diff --git a/README.md b/README.md index 2d5b583..7b62cbc 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,45 @@ -# io.Connect Desktop Tutorials - -Source code for the JavaScript tutorial for developing an **io.Connect Desktop** project. - -For a guide on using the tutorial code, see the [Tutorials](https://docs.interop.io/desktop/tutorials/javascript/index.html) section of the official **io.Connect Desktop** documentation. - +# io.Connect Desktop Tutorials + +Source code for the JavaScript and TypeScript tutorials for developing an **io.Connect Desktop** project. + +For a guide on using the tutorial code, see the [Tutorials](https://docs.interop.io/desktop/tutorials/javascript/index.html) section of the official **io.Connect Desktop** documentation. + +## JavaScript Version + +The JavaScript tutorial is located in the `javascript` directory. It contains both starter code and the complete solution. + +## TypeScript Version + +The TypeScript tutorial is located in the `typescript` directory. It mirrors the JavaScript version but with TypeScript support. Both starter code and solution are provided. + +### Building TypeScript Projects + +1. Navigate to either the `typescript/solution` or `typescript/start` directory: + +```bash +cd typescript/solution +# or +cd typescript/start +``` + +2. Install dependencies: + +```bash +npm install +``` + +3. Build all applications: + +```bash +npm run build +``` + +4. Start the applications: + +```bash +npm start +``` + +You can also build and start individual applications using the specific build and start scripts. See the package.json for available commands. + > ⚠️ *Note that this tutorial is for a licensed product.* \ No newline at end of file diff --git a/typescript/package.json b/typescript/package.json new file mode 100644 index 0000000..31b9e14 --- /dev/null +++ b/typescript/package.json @@ -0,0 +1,14 @@ +{ + "name": "ts-tutorial", + "version": "1.0.0", + "description": "io.Connect Desktop TypeScript Tutorial", + "scripts": { + "install:all": "cd solution && npm install && cd ../start && npm install", + "build:solution": "cd solution && npm run build", + "build:start": "cd start && npm run build", + "build": "npm run build:solution && npm run build:start" + }, + "devDependencies": { + "typescript": "^5.3.3" + } +} \ No newline at end of file diff --git a/typescript/solution/app-definitions/client-details.json b/typescript/solution/app-definitions/client-details.json new file mode 100644 index 0000000..d27d5ee --- /dev/null +++ b/typescript/solution/app-definitions/client-details.json @@ -0,0 +1,12 @@ +{ + "name": "client-details", + "title": "Client Details", + "type": "window", + "details": { + "url": "http://localhost:9200/" + }, + "customProperties": { + "folder": "Asset Management", + "includeInWorkspaces": true + } +} \ No newline at end of file diff --git a/typescript/solution/app-definitions/clients.json b/typescript/solution/app-definitions/clients.json new file mode 100644 index 0000000..eeb39e0 --- /dev/null +++ b/typescript/solution/app-definitions/clients.json @@ -0,0 +1,17 @@ +{ + "name": "clients", + "title": "Clients", + "type": "window", + "details": { + "url": "http://localhost:9000/", + "minWidth": 400, + "minHeight": 400, + "channelSelector": { + "enabled": false + } + }, + "customProperties": { + "folder": "Asset Management", + "includeInWorkspaces": true + } +} \ No newline at end of file diff --git a/typescript/solution/app-definitions/portfolio-downloader.json b/typescript/solution/app-definitions/portfolio-downloader.json new file mode 100644 index 0000000..3f83352 --- /dev/null +++ b/typescript/solution/app-definitions/portfolio-downloader.json @@ -0,0 +1,20 @@ +{ + "name": "portfolio-downloader", + "title": "Portfolio Downloader", + "type": "window", + "details": { + "url": "http://localhost:9300/" + }, + "intents": [ + { + "name": "ExportPortfolio", + "displayName": "Download Portfolio", + "contexts": [ + "ClientPortfolio" + ] + } + ], + "customProperties": { + "folder": "Asset Management" + } +} \ No newline at end of file diff --git a/typescript/solution/app-definitions/stocks.json b/typescript/solution/app-definitions/stocks.json new file mode 100644 index 0000000..7d9ff6f --- /dev/null +++ b/typescript/solution/app-definitions/stocks.json @@ -0,0 +1,33 @@ +[ + { + "name": "stocks", + "title": "Stocks", + "type": "window", + "ignoreSavedLayout": true, + "details": { + "url": "http://localhost:9100/", + "width": 500, + "height": 450, + "minWidth": 450, + "minHeight": 400, + "channelSelector": { + "enabled": false + } + }, + "customProperties": { + "folder": "Asset Management", + "includeInWorkspaces": true + } + }, + { + "name": "stock-details", + "title": "Stock Details", + "type": "window", + "details": { + "url": "http://localhost:9100/details" + }, + "customProperties": { + "folder": "Asset Management" + } + } +] \ No newline at end of file diff --git a/typescript/solution/client-details/esbuild.js b/typescript/solution/client-details/esbuild.js new file mode 100644 index 0000000..27c80dc --- /dev/null +++ b/typescript/solution/client-details/esbuild.js @@ -0,0 +1,48 @@ +const fs = require('fs'); +const path = require('path'); +const { build } = require('esbuild'); + +// Directory paths +const srcDir = path.join(__dirname, 'src'); +const distDir = path.join(__dirname, 'dist'); + +// Ensure dist directory exists +if (!fs.existsSync(distDir)) { + fs.mkdirSync(distDir, { recursive: true }); +} + +// Copy HTML file +fs.copyFileSync( + path.join(srcDir, 'index.html'), + path.join(distDir, 'index.html') +); + +// Copy lib directory +const libSrcDir = path.join(srcDir, 'lib'); +const libDistDir = path.join(distDir, 'lib'); + +if (!fs.existsSync(libDistDir)) { + fs.mkdirSync(libDistDir, { recursive: true }); +} + +fs.readdirSync(libSrcDir).forEach(file => { + fs.copyFileSync( + path.join(libSrcDir, file), + path.join(libDistDir, file) + ); +}); + +// Build with esbuild +build({ + entryPoints: [path.join(srcDir, 'index.ts')], + bundle: true, + outfile: path.join(distDir, 'index.js'), + platform: 'browser', + format: 'iife', + sourcemap: true, + target: ['es2020'], + tsconfig: path.join(__dirname, 'tsconfig.json'), +}).catch((error) => { + console.error(error); + process.exit(1); +}); \ No newline at end of file diff --git a/typescript/solution/client-details/src/index.html b/typescript/solution/client-details/src/index.html new file mode 100644 index 0000000..c917d85 --- /dev/null +++ b/typescript/solution/client-details/src/index.html @@ -0,0 +1,72 @@ + + + + + + + + + + + + Client Details + + + + + + + + + + + + + +
+
+
+
+ io.Connect is unavailable +
+
+
+

Client Details

+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DetailValue
Full Name
Address
Phone Number
Email
Account Manager
+
+
+ + + \ No newline at end of file diff --git a/typescript/solution/client-details/src/index.ts b/typescript/solution/client-details/src/index.ts new file mode 100644 index 0000000..8a194fd --- /dev/null +++ b/typescript/solution/client-details/src/index.ts @@ -0,0 +1,74 @@ +const setFields = (client: Client): void => { + const elementName = document.querySelectorAll("[data-name]")[0] as HTMLElement; + if (elementName) elementName.innerText = client.name; + + const elementAddress = document.querySelectorAll("[data-address]")[0] as HTMLElement; + if (elementAddress) elementAddress.innerText = client.address || ''; + + const elementPhone = document.querySelectorAll("[data-phone]")[0] as HTMLElement; + if (elementPhone) elementPhone.innerText = client.contactNumbers || ''; + + const elementOccupation = document.querySelectorAll("[data-email]")[0] as HTMLElement; + if (elementOccupation) elementOccupation.innerText = client.email || ''; + + const elementManager = document.querySelectorAll("[data-manager]")[0] as HTMLElement; + if (elementManager) elementManager.innerText = client.accountManager || ''; +}; + +// TODO: Chapter 3 +const toggleIOAvailable = (): void => { + const span = document.getElementById("ioConnectSpan"); + if (!span) return; + + span.classList.remove("bg-danger"); + span.classList.add("bg-success"); + span.textContent = "io.Connect is available"; +}; + +const start = async (): Promise => { + const html = document.documentElement; + const initialTheme = iodesktop.theme; + + html.className = initialTheme; + + // TODO: Chapter 3 + const config = { + libraries: [IOWorkspaces] + }; + + const io = await IODesktop(config); + + window.io = io; + + toggleIOAvailable(); + + // TODO: Chapter 12.1 + const themeHandler = (newTheme: Theme): void => { + html.className = newTheme.name; + }; + + io.themes.onChanged(themeHandler); + + // TODO: Chapter 9.4 + const myWorkspace = await io.workspaces.getMyWorkspace(); + + if (myWorkspace) { + const updateHandler = (context: any): void => { + if (context.client) { + setFields(context.client); + myWorkspace.setTitle(context.client.name); + } + }; + + myWorkspace.onContextUpdated(updateHandler); + } +}; + +// Add io property to window object +declare global { + interface Window { + io: IODesktopAPI; + } +} + +start().catch(console.error); \ No newline at end of file diff --git a/typescript/solution/client-details/src/lib/desktop.umd.js b/typescript/solution/client-details/src/lib/desktop.umd.js new file mode 100644 index 0000000..6cea2c9 --- /dev/null +++ b/typescript/solution/client-details/src/lib/desktop.umd.js @@ -0,0 +1,23144 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define(factory) : + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.desktop = factory()); +})(this, (function () { 'use strict'; + + var MetricTypes = { + STRING: 1, + NUMBER: 2, + TIMESTAMP: 3, + OBJECT: 4 + }; + + function getMetricTypeByValue(metric) { + if (metric.type === MetricTypes.TIMESTAMP) { + return "timestamp"; + } + else if (metric.type === MetricTypes.NUMBER) { + return "number"; + } + else if (metric.type === MetricTypes.STRING) { + return "string"; + } + else if (metric.type === MetricTypes.OBJECT) { + return "object"; + } + return "unknown"; + } + function getTypeByValue(value) { + if (value.constructor === Date) { + return "timestamp"; + } + else if (typeof value === "number") { + return "number"; + } + else if (typeof value === "string") { + return "string"; + } + else if (typeof value === "object") { + return "object"; + } + else { + return "string"; + } + } + function serializeMetric(metric) { + const serializedMetrics = {}; + const type = getMetricTypeByValue(metric); + if (type === "object") { + const values = Object.keys(metric.value).reduce((memo, key) => { + const innerType = getTypeByValue(metric.value[key]); + if (innerType === "object") { + const composite = defineNestedComposite(metric.value[key]); + memo[key] = { + type: "object", + description: "", + context: {}, + composite, + }; + } + else { + memo[key] = { + type: innerType, + description: "", + context: {}, + }; + } + return memo; + }, {}); + serializedMetrics.composite = values; + } + serializedMetrics.name = normalizeMetricName(metric.path.join("/") + "/" + metric.name); + serializedMetrics.type = type; + serializedMetrics.description = metric.description; + serializedMetrics.context = {}; + return serializedMetrics; + } + function defineNestedComposite(values) { + return Object.keys(values).reduce((memo, key) => { + const type = getTypeByValue(values[key]); + if (type === "object") { + memo[key] = { + type: "object", + description: "", + context: {}, + composite: defineNestedComposite(values[key]), + }; + } + else { + memo[key] = { + type, + description: "", + context: {}, + }; + } + return memo; + }, {}); + } + function normalizeMetricName(name) { + if (typeof name !== "undefined" && name.length > 0 && name[0] !== "/") { + return "/" + name; + } + else { + return name; + } + } + function getMetricValueByType(metric) { + const type = getMetricTypeByValue(metric); + if (type === "timestamp") { + return Date.now(); + } + else { + return publishNestedComposite(metric.value); + } + } + function publishNestedComposite(values) { + if (typeof values !== "object") { + return values; + } + return Object.keys(values).reduce((memo, key) => { + const value = values[key]; + if (typeof value === "object" && value.constructor !== Date) { + memo[key] = publishNestedComposite(value); + } + else if (value.constructor === Date) { + memo[key] = new Date(value).getTime(); + } + else if (value.constructor === Boolean) { + memo[key] = value.toString(); + } + else { + memo[key] = value; + } + return memo; + }, {}); + } + function flatten(arr) { + return arr.reduce((flat, toFlatten) => { + return flat.concat(Array.isArray(toFlatten) ? flatten(toFlatten) : toFlatten); + }, []); + } + function getHighestState(arr) { + return arr.sort((a, b) => { + if (!a.state) { + return 1; + } + if (!b.state) { + return -1; + } + return b.state - a.state; + })[0]; + } + function aggregateDescription(arr) { + let msg = ""; + arr.forEach((m, idx, a) => { + const path = m.path.join("."); + if (idx === a.length - 1) { + msg += path + "." + m.name + ": " + m.description; + } + else { + msg += path + "." + m.name + ": " + m.description + ","; + } + }); + if (msg.length > 100) { + return msg.slice(0, 100) + "..."; + } + else { + return msg; + } + } + function composeMsgForRootStateMetric(system) { + const aggregatedState = system.root.getAggregateState(); + const merged = flatten(aggregatedState); + const highestState = getHighestState(merged); + const aggregateDesc = aggregateDescription(merged); + return { + description: aggregateDesc, + value: highestState.state, + }; + } + + function gw3 (connection, config) { + if (!connection || typeof connection !== "object") { + throw new Error("Connection is required parameter"); + } + let joinPromise; + let session; + const init = (repo) => { + let resolveReadyPromise; + joinPromise = new Promise((resolve) => { + resolveReadyPromise = resolve; + }); + session = connection.domain("metrics"); + session.onJoined((reconnect) => { + if (!reconnect && resolveReadyPromise) { + resolveReadyPromise(); + resolveReadyPromise = undefined; + } + const rootStateMetric = { + name: "/State", + type: "object", + composite: { + Description: { + type: "string", + description: "", + }, + Value: { + type: "number", + description: "", + }, + }, + description: "System state", + context: {}, + }; + const defineRootMetricsMsg = { + type: "define", + metrics: [rootStateMetric], + }; + session.send(defineRootMetricsMsg); + if (reconnect) { + replayRepo(repo); + } + }); + session.join({ + system: config.system, + service: config.service, + instance: config.instance + }); + }; + const replayRepo = (repo) => { + replaySystem(repo.root); + }; + const replaySystem = (system) => { + createSystem(system); + system.metrics.forEach((m) => { + createMetric(m); + }); + system.subSystems.forEach((ss) => { + replaySystem(ss); + }); + }; + const createSystem = async (system) => { + if (system.parent === undefined) { + return; + } + await joinPromise; + const metric = { + name: normalizeMetricName(system.path.join("/") + "/" + system.name + "/State"), + type: "object", + composite: { + Description: { + type: "string", + description: "", + }, + Value: { + type: "number", + description: "", + }, + }, + description: "System state", + context: {}, + }; + const createMetricsMsg = { + type: "define", + metrics: [metric], + }; + session.send(createMetricsMsg); + }; + const updateSystem = async (system, state) => { + await joinPromise; + const shadowedUpdateMetric = { + type: "publish", + values: [{ + name: normalizeMetricName(system.path.join("/") + "/" + system.name + "/State"), + value: { + Description: state.description, + Value: state.state, + }, + timestamp: Date.now(), + }], + }; + session.send(shadowedUpdateMetric); + const stateObj = composeMsgForRootStateMetric(system); + const rootMetric = { + type: "publish", + peer_id: connection.peerId, + values: [{ + name: "/State", + value: { + Description: stateObj.description, + Value: stateObj.value, + }, + timestamp: Date.now(), + }], + }; + session.send(rootMetric); + }; + const createMetric = async (metric) => { + const metricClone = cloneMetric(metric); + await joinPromise; + const m = serializeMetric(metricClone); + const createMetricsMsg = { + type: "define", + metrics: [m], + }; + session.send(createMetricsMsg); + if (typeof metricClone.value !== "undefined") { + updateMetricCore(metricClone); + } + }; + const updateMetric = async (metric) => { + const metricClone = cloneMetric(metric); + await joinPromise; + updateMetricCore(metricClone); + }; + const updateMetricCore = (metric) => { + if (canUpdate()) { + const value = getMetricValueByType(metric); + const publishMetricsMsg = { + type: "publish", + values: [{ + name: normalizeMetricName(metric.path.join("/") + "/" + metric.name), + value, + timestamp: Date.now(), + }], + }; + return session.sendFireAndForget(publishMetricsMsg); + } + return Promise.resolve(); + }; + const cloneMetric = (metric) => { + const metricClone = { ...metric }; + if (typeof metric.value === "object" && metric.value !== null) { + metricClone.value = { ...metric.value }; + } + return metricClone; + }; + const canUpdate = () => { + try { + const func = config.canUpdateMetric ?? (() => true); + return func(); + } + catch { + return true; + } + }; + return { + init, + createSystem, + updateSystem, + createMetric, + updateMetric, + }; + } + + var Helpers = { + validate: (definition, parent, transport) => { + if (definition === null || typeof definition !== "object") { + throw new Error("Missing definition"); + } + if (parent === null || typeof parent !== "object") { + throw new Error("Missing parent"); + } + if (transport === null || typeof transport !== "object") { + throw new Error("Missing transport"); + } + }, + }; + + class BaseMetric { + definition; + system; + transport; + value; + type; + path = []; + name; + description; + get repo() { + return this.system?.repo; + } + get id() { return `${this.system.path}/${name}`; } + constructor(definition, system, transport, value, type) { + this.definition = definition; + this.system = system; + this.transport = transport; + this.value = value; + this.type = type; + Helpers.validate(definition, system, transport); + this.path = system.path.slice(0); + this.path.push(system.name); + this.name = definition.name; + this.description = definition.description; + transport.createMetric(this); + } + update(newValue) { + this.value = newValue; + return this.transport.updateMetric(this); + } + } + + class NumberMetric extends BaseMetric { + constructor(definition, system, transport, value) { + super(definition, system, transport, value, MetricTypes.NUMBER); + } + incrementBy(num) { + this.update(this.value + num); + } + increment() { + this.incrementBy(1); + } + decrement() { + this.incrementBy(-1); + } + decrementBy(num) { + this.incrementBy(num * -1); + } + } + + class ObjectMetric extends BaseMetric { + constructor(definition, system, transport, value) { + super(definition, system, transport, value, MetricTypes.OBJECT); + } + update(newValue) { + this.mergeValues(newValue); + return this.transport.updateMetric(this); + } + mergeValues(values) { + return Object.keys(this.value).forEach((k) => { + if (typeof values[k] !== "undefined") { + this.value[k] = values[k]; + } + }); + } + } + + class StringMetric extends BaseMetric { + constructor(definition, system, transport, value) { + super(definition, system, transport, value, MetricTypes.STRING); + } + } + + class TimestampMetric extends BaseMetric { + constructor(definition, system, transport, value) { + super(definition, system, transport, value, MetricTypes.TIMESTAMP); + } + now() { + this.update(new Date()); + } + } + + function system$1(name, repo, protocol, parent, description) { + if (!repo) { + throw new Error("Repository is required"); + } + if (!protocol) { + throw new Error("Transport is required"); + } + const _transport = protocol; + const _name = name; + const _description = description || ""; + const _repo = repo; + const _parent = parent; + const _path = _buildPath(parent); + let _state = {}; + const id = _arrayToString(_path, "/") + name; + const root = repo.root; + const _subSystems = []; + const _metrics = []; + function subSystem(nameSystem, descriptionSystem) { + if (!nameSystem || nameSystem.length === 0) { + throw new Error("name is required"); + } + const match = _subSystems.filter((s) => s.name === nameSystem); + if (match.length > 0) { + return match[0]; + } + const _system = system$1(nameSystem, _repo, _transport, me, descriptionSystem); + _subSystems.push(_system); + return _system; + } + function setState(state, stateDescription) { + _state = { state, description: stateDescription }; + _transport.updateSystem(me, _state); + } + function stringMetric(definition, value) { + return _getOrCreateMetric(definition, MetricTypes.STRING, value, (metricDef) => new StringMetric(metricDef, me, _transport, value)); + } + function numberMetric(definition, value) { + return _getOrCreateMetric(definition, MetricTypes.NUMBER, value, (metricDef) => new NumberMetric(metricDef, me, _transport, value)); + } + function objectMetric(definition, value) { + return _getOrCreateMetric(definition, MetricTypes.OBJECT, value, (metricDef) => new ObjectMetric(metricDef, me, _transport, value)); + } + function timestampMetric(definition, value) { + return _getOrCreateMetric(definition, MetricTypes.TIMESTAMP, value, (metricDef) => new TimestampMetric(metricDef, me, _transport, value)); + } + function _getOrCreateMetric(metricObject, expectedType, value, createMetric) { + let metricDef = { name: "" }; + if (typeof metricObject === "string") { + metricDef = { name: metricObject }; + } + else { + metricDef = metricObject; + } + const matching = _metrics.filter((shadowedMetric) => shadowedMetric.name === metricDef.name); + if (matching.length > 0) { + const existing = matching[0]; + if (existing.type !== expectedType) { + throw new Error(`A metric named ${metricDef.name} is already defined with different type.`); + } + if (typeof value !== "undefined") { + existing + .update(value) + .catch(() => { }); + } + return existing; + } + const metric = createMetric(metricDef); + _metrics.push(metric); + return metric; + } + function _buildPath(shadowedSystem) { + if (!shadowedSystem || !shadowedSystem.parent) { + return []; + } + const path = _buildPath(shadowedSystem.parent); + path.push(shadowedSystem.name); + return path; + } + function _arrayToString(path, separator) { + return ((path && path.length > 0) ? path.join(separator) : ""); + } + function getAggregateState() { + const aggState = []; + if (Object.keys(_state).length > 0) { + aggState.push({ + name: _name, + path: _path, + state: _state.state, + description: _state.description, + }); + } + _subSystems.forEach((shadowedSubSystem) => { + const result = shadowedSubSystem.getAggregateState(); + if (result.length > 0) { + aggState.push(...result); + } + }); + return aggState; + } + const me = { + get name() { + return _name; + }, + get description() { + return _description; + }, + get repo() { + return _repo; + }, + get parent() { + return _parent; + }, + path: _path, + id, + root, + get subSystems() { + return _subSystems; + }, + get metrics() { + return _metrics; + }, + subSystem, + getState: () => { + return _state; + }, + setState, + stringMetric, + timestampMetric, + objectMetric, + numberMetric, + getAggregateState, + }; + _transport.createSystem(me); + return me; + } + + class Repository { + root; + constructor(options, protocol) { + protocol.init(this); + this.root = system$1("", this, protocol); + this.addSystemMetrics(this.root, options.clickStream || options.clickStream === undefined); + } + addSystemMetrics(rootSystem, useClickStream) { + if (typeof navigator !== "undefined") { + rootSystem.stringMetric("UserAgent", navigator.userAgent); + } + if (useClickStream && typeof document !== "undefined") { + const clickStream = rootSystem.subSystem("ClickStream"); + const documentClickHandler = (e) => { + if (!e.target) { + return; + } + const target = e.target; + const className = target ? target.getAttribute("class") ?? "" : ""; + clickStream.objectMetric("LastBrowserEvent", { + type: "click", + timestamp: new Date(), + target: { + className, + id: target.id, + type: "<" + target.tagName.toLowerCase() + ">", + href: target.href || "", + }, + }); + }; + clickStream.objectMetric("Page", { + title: document.title, + page: window.location.href, + }); + if (document.addEventListener) { + document.addEventListener("click", documentClickHandler); + } + else { + document.attachEvent("onclick", documentClickHandler); + } + } + rootSystem.stringMetric("StartTime", (new Date()).toString()); + const urlMetric = rootSystem.stringMetric("StartURL", ""); + const appNameMetric = rootSystem.stringMetric("AppName", ""); + if (typeof window !== "undefined") { + if (typeof window.location !== "undefined") { + const startUrl = window.location.href; + urlMetric.update(startUrl); + } + if (typeof window.glue42gd !== "undefined") { + appNameMetric.update(window.glue42gd.appName); + } + } + } + } + + class NullProtocol { + init(repo) { + } + createSystem(system) { + return Promise.resolve(); + } + updateSystem(metric, state) { + return Promise.resolve(); + } + createMetric(metric) { + return Promise.resolve(); + } + updateMetric(metric) { + return Promise.resolve(); + } + } + + class PerfTracker { + api; + lastCount = 0; + initialPublishTimeout = 10 * 1000; + publishInterval = 60 * 1000; + system; + constructor(api, initialPublishTimeout, publishInterval) { + this.api = api; + this.initialPublishTimeout = initialPublishTimeout ?? this.initialPublishTimeout; + this.publishInterval = publishInterval ?? this.publishInterval; + this.scheduleCollection(); + this.system = this.api.subSystem("performance", "Performance data published by the web application"); + } + scheduleCollection() { + setTimeout(() => { + this.collect(); + setInterval(() => { + this.collect(); + }, this.publishInterval); + }, this.initialPublishTimeout); + } + collect() { + try { + this.collectMemory(); + this.collectEntries(); + } + catch { + } + } + collectMemory() { + const memory = window.performance.memory; + this.system.stringMetric("memory", JSON.stringify({ + totalJSHeapSize: memory.totalJSHeapSize, + usedJSHeapSize: memory.usedJSHeapSize + })); + } + collectEntries() { + const allEntries = window.performance.getEntries(); + if (allEntries.length <= this.lastCount) { + return; + } + this.lastCount = allEntries.length; + const jsonfiedEntries = allEntries.map((i) => i.toJSON()); + this.system.stringMetric("entries", JSON.stringify(jsonfiedEntries)); + } + } + + var metrics = (options) => { + let protocol; + if (!options.connection || typeof options.connection !== "object") { + protocol = new NullProtocol(); + } + else { + protocol = gw3(options.connection, options); + } + const repo = new Repository(options, protocol); + let rootSystem = repo.root; + if (!options.disableAutoAppSystem) { + rootSystem = rootSystem.subSystem("App"); + } + const api = addFAVSupport(rootSystem); + initPerf(api, options.pagePerformanceMetrics); + return api; + }; + function initPerf(api, config) { + if (typeof window === "undefined") { + return; + } + const perfConfig = window?.glue42gd?.metrics?.pagePerformanceMetrics; + if (perfConfig) { + config = perfConfig; + } + if (config?.enabled) { + new PerfTracker(api, config.initialPublishTimeout, config.publishInterval); + } + } + function addFAVSupport(system) { + const reportingSystem = system.subSystem("reporting"); + const def = { + name: "features" + }; + let featureMetric; + const featureMetricFunc = (name, action, payload) => { + if (typeof name === "undefined" || name === "") { + throw new Error("name is mandatory"); + } + else if (typeof action === "undefined" || action === "") { + throw new Error("action is mandatory"); + } + else if (typeof payload === "undefined" || payload === "") { + throw new Error("payload is mandatory"); + } + if (!featureMetric) { + featureMetric = reportingSystem.objectMetric(def, { name, action, payload }); + } + else { + featureMetric.update({ + name, + action, + payload + }); + } + }; + system.featureMetric = featureMetricFunc; + return system; + } + + var commonjsGlobal$1 = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; + + function getDefaultExportFromCjs$1 (x) { + return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; + } + + function createRegistry$1(options) { + if (options && options.errorHandling + && typeof options.errorHandling !== "function" + && options.errorHandling !== "log" + && options.errorHandling !== "silent" + && options.errorHandling !== "throw") { + throw new Error("Invalid options passed to createRegistry. Prop errorHandling should be [\"log\" | \"silent\" | \"throw\" | (err) => void], but " + typeof options.errorHandling + " was passed"); + } + var _userErrorHandler = options && typeof options.errorHandling === "function" && options.errorHandling; + var callbacks = {}; + function add(key, callback, replayArgumentsArr) { + var callbacksForKey = callbacks[key]; + if (!callbacksForKey) { + callbacksForKey = []; + callbacks[key] = callbacksForKey; + } + callbacksForKey.push(callback); + if (replayArgumentsArr) { + setTimeout(function () { + replayArgumentsArr.forEach(function (replayArgument) { + var _a; + if ((_a = callbacks[key]) === null || _a === void 0 ? void 0 : _a.includes(callback)) { + try { + if (Array.isArray(replayArgument)) { + callback.apply(undefined, replayArgument); + } + else { + callback.apply(undefined, [replayArgument]); + } + } + catch (err) { + _handleError(err, key); + } + } + }); + }, 0); + } + return function () { + var allForKey = callbacks[key]; + if (!allForKey) { + return; + } + allForKey = allForKey.reduce(function (acc, element, index) { + if (!(element === callback && acc.length === index)) { + acc.push(element); + } + return acc; + }, []); + if (allForKey.length === 0) { + delete callbacks[key]; + } + else { + callbacks[key] = allForKey; + } + }; + } + function execute(key) { + var argumentsArr = []; + for (var _i = 1; _i < arguments.length; _i++) { + argumentsArr[_i - 1] = arguments[_i]; + } + var callbacksForKey = callbacks[key]; + if (!callbacksForKey || callbacksForKey.length === 0) { + return []; + } + var results = []; + callbacksForKey.forEach(function (callback) { + try { + var result = callback.apply(undefined, argumentsArr); + results.push(result); + } + catch (err) { + results.push(undefined); + _handleError(err, key); + } + }); + return results; + } + function _handleError(exceptionArtifact, key) { + var errParam = exceptionArtifact instanceof Error ? exceptionArtifact : new Error(exceptionArtifact); + if (_userErrorHandler) { + _userErrorHandler(errParam); + return; + } + var msg = "[ERROR] callback-registry: User callback for key \"" + key + "\" failed: " + errParam.stack; + if (options) { + switch (options.errorHandling) { + case "log": + return console.error(msg); + case "silent": + return; + case "throw": + throw new Error(msg); + } + } + console.error(msg); + } + function clear() { + callbacks = {}; + } + function clearKey(key) { + var callbacksForKey = callbacks[key]; + if (!callbacksForKey) { + return; + } + delete callbacks[key]; + } + return { + add: add, + execute: execute, + clear: clear, + clearKey: clearKey + }; + } + createRegistry$1.default = createRegistry$1; + var lib$1 = createRegistry$1; + + + var CallbackRegistryFactory$1 = /*@__PURE__*/getDefaultExportFromCjs$1(lib$1); + + class InProcTransport { + gw; + registry = CallbackRegistryFactory$1(); + client; + constructor(settings, logger) { + this.gw = settings.facade; + this.gw.connect((_client, message) => { + this.messageHandler(message); + }).then((client) => { + this.client = client; + }); + } + get isObjectBasedTransport() { + return true; + } + sendObject(msg) { + if (this.client) { + this.client.send(msg); + return Promise.resolve(undefined); + } + else { + return Promise.reject(`not connected`); + } + } + send(_msg) { + return Promise.reject("not supported"); + } + onMessage(callback) { + return this.registry.add("onMessage", callback); + } + onConnectedChanged(callback) { + callback(true); + return () => { }; + } + close() { + return Promise.resolve(); + } + open() { + return Promise.resolve(); + } + name() { + return "in-memory"; + } + reconnect() { + return Promise.resolve(); + } + messageHandler(msg) { + this.registry.execute("onMessage", msg); + } + } + + class SharedWorkerTransport { + logger; + worker; + registry = CallbackRegistryFactory$1(); + constructor(workerFile, logger) { + this.logger = logger; + this.worker = new SharedWorker(workerFile); + this.worker.port.onmessage = (e) => { + this.messageHandler(e.data); + }; + } + get isObjectBasedTransport() { + return true; + } + sendObject(msg) { + this.worker.port.postMessage(msg); + return Promise.resolve(); + } + send(_msg) { + return Promise.reject("not supported"); + } + onMessage(callback) { + return this.registry.add("onMessage", callback); + } + onConnectedChanged(callback) { + callback(true); + return () => { }; + } + close() { + return Promise.resolve(); + } + open() { + return Promise.resolve(); + } + name() { + return "shared-worker"; + } + reconnect() { + return Promise.resolve(); + } + messageHandler(msg) { + this.registry.execute("onMessage", msg); + } + } + + let Utils$1 = class Utils { + static isNode() { + if (typeof Utils._isNode !== "undefined") { + return Utils._isNode; + } + if (typeof window !== "undefined") { + Utils._isNode = false; + return false; + } + try { + Utils._isNode = Object.prototype.toString.call(global.process) === "[object process]"; + } + catch (e) { + Utils._isNode = false; + } + return Utils._isNode; + } + static _isNode; + }; + + let PromiseWrapper$1 = class PromiseWrapper { + static delay(time) { + return new Promise((resolve) => setTimeout(resolve, time)); + } + resolve; + reject; + promise; + rejected = false; + resolved = false; + get ended() { + return this.rejected || this.resolved; + } + constructor() { + this.promise = new Promise((resolve, reject) => { + this.resolve = (t) => { + this.resolved = true; + resolve(t); + }; + this.reject = (err) => { + this.rejected = true; + reject(err); + }; + }); + } + }; + + const timers = {}; + function getAllTimers() { + return timers; + } + function timer (timerName) { + const existing = timers[timerName]; + if (existing) { + return existing; + } + const marks = []; + function now() { + return new Date().getTime(); + } + const startTime = now(); + mark("start", startTime); + let endTime; + let period; + function stop() { + endTime = now(); + mark("end", endTime); + period = endTime - startTime; + return period; + } + function mark(name, time) { + const currentTime = time ?? now(); + let diff = 0; + if (marks.length > 0) { + diff = currentTime - marks[marks.length - 1].time; + } + marks.push({ name, time: currentTime, diff }); + } + const timerObj = { + get startTime() { + return startTime; + }, + get endTime() { + return endTime; + }, + get period() { + return period; + }, + stop, + mark, + marks + }; + timers[timerName] = timerObj; + return timerObj; + } + + const WebSocketConstructor = Utils$1.isNode() ? require("ws") : window.WebSocket; + class WS { + ws; + logger; + settings; + startupTimer = timer("connection"); + _running = true; + _registry = CallbackRegistryFactory$1(); + wsRequests = []; + constructor(settings, logger) { + this.settings = settings; + this.logger = logger; + if (!this.settings.ws) { + throw new Error("ws is missing"); + } + } + onMessage(callback) { + return this._registry.add("onMessage", callback); + } + send(msg, options) { + return new Promise((resolve, reject) => { + this.waitForSocketConnection(() => { + try { + this.ws?.send(msg); + resolve(); + } + catch (e) { + reject(e); + } + }, reject); + }); + } + open() { + this.logger.info("opening ws..."); + this._running = true; + return new Promise((resolve, reject) => { + this.waitForSocketConnection(resolve, reject); + }); + } + close() { + this._running = false; + if (this.ws) { + this.ws.close(); + } + return Promise.resolve(); + } + onConnectedChanged(callback) { + return this._registry.add("onConnectedChanged", callback); + } + name() { + return this.settings.ws; + } + reconnect() { + this.ws?.close(); + const pw = new PromiseWrapper$1(); + this.waitForSocketConnection(() => { + pw.resolve(); + }); + return pw.promise; + } + waitForSocketConnection(callback, failed) { + failed = failed ?? (() => { }); + if (!this._running) { + failed(`wait for socket on ${this.settings.ws} failed - socket closed by user`); + return; + } + if (this.ws?.readyState === 1) { + callback(); + return; + } + this.wsRequests.push({ callback, failed }); + if (this.wsRequests.length > 1) { + return; + } + this.openSocket(); + } + async openSocket(retryInterval, retriesLeft) { + this.logger.info(`opening ws to ${this.settings.ws}, retryInterval: ${retryInterval}, retriesLeft: ${retriesLeft}...`); + this.startupTimer.mark("opening-socket"); + if (retryInterval === undefined) { + retryInterval = this.settings.reconnectInterval; + } + if (typeof retriesLeft === "undefined") { + retriesLeft = this.settings.reconnectAttempts; + } + if (retriesLeft !== undefined) { + if (retriesLeft === 0) { + this.notifyForSocketState(`wait for socket on ${this.settings.ws} failed - no more retries left`); + return; + } + this.logger.debug(`will retry ${retriesLeft} more times (every ${retryInterval} ms)`); + } + try { + await this.initiateSocket(); + this.startupTimer.mark("socket-initiated"); + this.notifyForSocketState(); + } + catch { + setTimeout(() => { + const retries = retriesLeft === undefined ? undefined : retriesLeft - 1; + this.openSocket(retryInterval, retries); + }, retryInterval); + } + } + initiateSocket() { + const pw = new PromiseWrapper$1(); + this.logger.debug(`initiating ws to ${this.settings.ws}...`); + this.ws = new WebSocketConstructor(this.settings.ws ?? ""); + this.ws.onerror = (err) => { + let reason = ""; + try { + reason = JSON.stringify(err); + } + catch (error) { + const seen = new WeakSet(); + const replacer = (key, value) => { + if (typeof value === "object" && value !== null) { + if (seen.has(value)) { + return; + } + seen.add(value); + } + return value; + }; + reason = JSON.stringify(err, replacer); + } + this.logger.info(`ws error - reason: ${reason}`); + pw.reject("error"); + this.notifyStatusChanged(false, reason); + }; + this.ws.onclose = (err) => { + this.logger.info(`ws closed - code: ${err?.code} reason: ${err?.reason}`); + pw.reject("closed"); + this.notifyStatusChanged(false); + }; + this.ws.onopen = () => { + this.startupTimer.mark("ws-opened"); + this.logger.info(`ws opened ${this.settings.identity?.application}`); + pw.resolve(); + this.notifyStatusChanged(true); + }; + this.ws.onmessage = (message) => { + this._registry.execute("onMessage", message.data); + }; + return pw.promise; + } + notifyForSocketState(error) { + this.wsRequests.forEach((wsRequest) => { + if (error) { + if (wsRequest.failed) { + wsRequest.failed(error); + } + } + else { + wsRequest.callback(); + } + }); + this.wsRequests = []; + } + notifyStatusChanged(status, reason) { + this._registry.execute("onConnectedChanged", status, reason); + } + } + + class MessageReplayerImpl { + specs; + specsNames = []; + messages = {}; + isDone; + subs = {}; + subsRefCount = {}; + connection; + constructor(specs) { + this.specs = {}; + for (const spec of specs) { + this.specs[spec.name] = spec; + this.specsNames.push(spec.name); + } + } + init(connection) { + this.connection = connection; + for (const name of this.specsNames) { + for (const type of this.specs[name].types) { + let refCount = this.subsRefCount[type]; + if (!refCount) { + refCount = 0; + } + refCount += 1; + this.subsRefCount[type] = refCount; + if (refCount > 1) { + continue; + } + const sub = connection.on(type, (msg) => this.processMessage(type, msg)); + this.subs[type] = sub; + } + } + } + processMessage(type, msg) { + if (this.isDone || !msg) { + return; + } + for (const name of this.specsNames) { + if (this.specs[name].types.indexOf(type) !== -1) { + const messages = this.messages[name] || []; + this.messages[name] = messages; + messages.push(msg); + } + } + } + drain(name, callback) { + if (callback) { + (this.messages[name] || []).forEach(callback); + } + delete this.messages[name]; + for (const type of this.specs[name].types) { + this.subsRefCount[type] -= 1; + if (this.subsRefCount[type] <= 0) { + this.connection?.off(this.subs[type]); + delete this.subs[type]; + delete this.subsRefCount[type]; + } + } + delete this.specs[name]; + if (!this.specs.length) { + this.isDone = true; + } + } + } + + let urlAlphabet$1 = + 'useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict'; + let nanoid$1 = (size = 21) => { + let id = ''; + let i = size; + while (i--) { + id += urlAlphabet$1[(Math.random() * 64) | 0]; + } + return id + }; + + const PromisePlus$1 = (executor, timeoutMilliseconds, timeoutMessage) => { + return new Promise((resolve, reject) => { + const timeout = setTimeout(() => { + const message = timeoutMessage || `Promise timeout hit: ${timeoutMilliseconds}`; + reject(message); + }, timeoutMilliseconds); + const providedPromise = new Promise(executor); + providedPromise + .then((result) => { + clearTimeout(timeout); + resolve(result); + }) + .catch((error) => { + clearTimeout(timeout); + reject(error); + }); + }); + }; + + class WebPlatformTransport { + settings; + logger; + identity; + isPreferredActivated; + _communicationId; + publicWindowId; + selfAssignedWindowId; + iAmConnected = false; + parentReady = false; + rejected = false; + parentPingResolve; + parentPingInterval; + connectionResolve; + extConnectionResolve; + extConnectionReject; + connectionReject; + port; + myClientId; + children = []; + extContentAvailable = false; + extContentConnecting = false; + extContentConnected = false; + parentWindowId; + parentInExtMode = false; + webNamespace = "g42_core_web"; + parent; + parentType; + parentPingTimeout = 5000; + connectionRequestTimeout = 7000; + defaultTargetString = "*"; + registry = CallbackRegistryFactory$1(); + messages = { + connectionAccepted: { name: "connectionAccepted", handle: this.handleConnectionAccepted.bind(this) }, + connectionRejected: { name: "connectionRejected", handle: this.handleConnectionRejected.bind(this) }, + connectionRequest: { name: "connectionRequest", handle: this.handleConnectionRequest.bind(this) }, + parentReady: { + name: "parentReady", handle: () => { + } + }, + parentPing: { name: "parentPing", handle: this.handleParentPing.bind(this) }, + platformPing: { name: "platformPing", handle: this.handlePlatformPing.bind(this) }, + platformReady: { name: "platformReady", handle: this.handlePlatformReady.bind(this) }, + clientUnload: { name: "clientUnload", handle: this.handleClientUnload.bind(this) }, + manualUnload: { name: "manualUnload", handle: this.handleManualUnload.bind(this) }, + extConnectionResponse: { name: "extConnectionResponse", handle: this.handleExtConnectionResponse.bind(this) }, + extSetupRequest: { name: "extSetupRequest", handle: this.handleExtSetupRequest.bind(this) }, + gatewayDisconnect: { name: "gatewayDisconnect", handle: this.handleGatewayDisconnect.bind(this) }, + gatewayInternalConnect: { name: "gatewayInternalConnect", handle: this.handleGatewayInternalConnect.bind(this) } + }; + constructor(settings, logger, identity) { + this.settings = settings; + this.logger = logger; + this.identity = identity; + this.extContentAvailable = !!window.glue42ext; + this.setUpMessageListener(); + this.setUpUnload(); + this.setupPlatformUnloadListener(); + this.parentType = window.name.includes("#wsp") ? "workspace" : undefined; + } + manualSetReadyState() { + this.iAmConnected = true; + this.parentReady = true; + } + get transportWindowId() { + return this.publicWindowId; + } + get communicationId() { + return this._communicationId; + } + async sendObject(msg) { + if (this.extContentConnected) { + return window.postMessage({ glue42ExtOut: msg }, this.defaultTargetString); + } + if (!this.port) { + throw new Error("Cannot send message, because the port was not opened yet"); + } + this.port.postMessage(msg); + } + get isObjectBasedTransport() { + return true; + } + onMessage(callback) { + return this.registry.add("onMessage", callback); + } + send() { + return Promise.reject("not supported"); + } + onConnectedChanged(callback) { + return this.registry.add("onConnectedChanged", callback); + } + async open() { + this.logger.debug("opening a connection to the web platform gateway."); + await this.connect(); + this.notifyStatusChanged(true); + } + close() { + const message = { + glue42core: { + type: this.messages.gatewayDisconnect.name, + data: { + clientId: this.myClientId, + ownWindowId: this.identity?.windowId + } + } + }; + this.port?.postMessage(message); + this.parentReady = false; + this.notifyStatusChanged(false, "manual reconnection"); + return Promise.resolve(); + } + name() { + return "web-platform"; + } + async reconnect() { + await this.close(); + return Promise.resolve(); + } + initiateInternalConnection() { + return new Promise((resolve, reject) => { + this.logger.debug("opening an internal web platform connection"); + this.port = this.settings.port; + if (this.iAmConnected) { + this.logger.warn("cannot open a new connection, because this client is currently connected"); + return; + } + this.port.onmessage = (event) => { + if (this.iAmConnected && !event.data?.glue42core) { + this.registry.execute("onMessage", event.data); + return; + } + const data = event.data?.glue42core; + if (!data) { + return; + } + if (data.type === this.messages.gatewayInternalConnect.name && data.success) { + this.publicWindowId = this.settings.windowId; + if (this.identity && this.publicWindowId) { + this.identity.windowId = this.publicWindowId; + this.identity.instance = this.publicWindowId; + } + resolve(); + } + if (data.type === this.messages.gatewayInternalConnect.name && data.error) { + reject(data.error); + } + }; + this.port.postMessage({ + glue42core: { + type: this.messages.gatewayInternalConnect.name + } + }); + }); + } + initiateRemoteConnection(target) { + return PromisePlus$1((resolve, reject) => { + this.connectionResolve = resolve; + this.connectionReject = reject; + this.myClientId = this.myClientId ?? nanoid$1(10); + const bridgeInstanceId = this.getMyWindowId() || nanoid$1(10); + const request = { + glue42core: { + type: this.messages.connectionRequest.name, + clientId: this.myClientId, + clientType: "child", + bridgeInstanceId, + selfAssignedWindowId: this.selfAssignedWindowId + } + }; + this.logger.debug("sending connection request"); + if (this.extContentConnecting) { + request.glue42core.clientType = "child"; + request.glue42core.bridgeInstanceId = this.myClientId; + request.glue42core.parentWindowId = this.parentWindowId; + return window.postMessage(request, this.defaultTargetString); + } + if (!target) { + throw new Error("Cannot send a connection request, because no glue target was specified!"); + } + target.postMessage(request, this.defaultTargetString); + }, this.connectionRequestTimeout, "The connection to the target glue window timed out"); + } + async isParentCheckSuccess(parentCheck) { + try { + await parentCheck; + return { success: true }; + } + catch (error) { + return { success: false }; + } + } + setUpMessageListener() { + if (this.settings.port) { + this.logger.debug("skipping generic message listener, because this is an internal client"); + return; + } + window.addEventListener("message", (event) => { + const data = event.data?.glue42core; + if (!data || this.rejected) { + return; + } + const allowedOrigins = this.settings.allowedOrigins || []; + if (allowedOrigins.length && !allowedOrigins.includes(event.origin)) { + this.logger.warn(`received a message from an origin which is not in the allowed list: ${event.origin}`); + return; + } + if (!this.checkMessageTypeValid(data.type)) { + this.logger.error(`cannot handle the incoming glue42 core message, because the type is invalid: ${data.type}`); + return; + } + const messageType = data.type; + this.logger.debug(`received valid glue42core message of type: ${messageType}`); + this.messages[messageType].handle(event); + }); + } + setUpUnload() { + if (this.settings.port) { + this.logger.debug("skipping unload event listener, because this is an internal client"); + return; + } + window.addEventListener("beforeunload", () => { + if (this.extContentConnected) { + return; + } + const message = { + glue42core: { + type: this.messages.clientUnload.name, + data: { + clientId: this.myClientId, + ownWindowId: this.identity?.windowId + } + } + }; + if (this.parent) { + this.parent.postMessage(message, this.defaultTargetString); + } + this.port?.postMessage(message); + }); + } + handlePlatformReady(event) { + this.logger.debug("the web platform gave the ready signal"); + this.parentReady = true; + if (this.parentPingResolve) { + this.parentPingResolve(); + delete this.parentPingResolve; + } + if (this.parentPingInterval) { + clearInterval(this.parentPingInterval); + delete this.parentPingInterval; + } + this.parent = event.source; + this.parentType = window.name.includes("#wsp") ? "workspace" : "window"; + } + handleConnectionAccepted(event) { + const data = event.data?.glue42core; + if (this.myClientId === data.clientId) { + return this.handleAcceptanceOfMyRequest(data); + } + return this.handleAcceptanceOfGrandChildRequest(data, event); + } + handleAcceptanceOfMyRequest(data) { + this.logger.debug("handling a connection accepted signal targeted at me."); + this.isPreferredActivated = data.isPreferredActivated; + if (this.extContentConnecting) { + return this.processExtContentConnection(data); + } + if (!data.port) { + this.logger.error("cannot set up my connection, because I was not provided with a port"); + return; + } + this.publicWindowId = this.getMyWindowId(); + if (this.identity) { + this.identity.windowId = this.publicWindowId; + this.identity.instance = this.identity.instance ? this.identity.instance : this.publicWindowId || nanoid$1(10); + } + if (this.identity && data.appName) { + this.identity.application = data.appName; + this.identity.applicationName = data.appName; + } + this._communicationId = data.communicationId; + this.port = data.port; + this.port.onmessage = (e) => this.registry.execute("onMessage", e.data); + if (this.connectionResolve) { + this.logger.debug("my connection is set up, calling the connection resolve."); + this.connectionResolve(); + delete this.connectionResolve; + return; + } + this.logger.error("unable to call the connection resolve, because no connection promise was found"); + } + processExtContentConnection(data) { + this.logger.debug("handling a connection accepted signal targeted at me for extension content connection."); + this.extContentConnecting = false; + this.extContentConnected = true; + this.publicWindowId = this.parentWindowId || this.myClientId; + if (this.extContentConnecting && this.identity) { + this.identity.windowId = this.publicWindowId; + } + if (this.identity && data.appName) { + this.identity.application = data.appName; + this.identity.applicationName = data.appName; + } + window.addEventListener("message", (event) => { + const extData = event.data?.glue42ExtInc; + if (!extData) { + return; + } + const allowedOrigins = this.settings.allowedOrigins || []; + if (allowedOrigins.length && !allowedOrigins.includes(event.origin)) { + this.logger.warn(`received a message from an origin which is not in the allowed list: ${event.origin}`); + return; + } + this.registry.execute("onMessage", extData); + }); + if (this.connectionResolve) { + this.logger.debug("my connection is set up, calling the connection resolve."); + this.connectionResolve(); + delete this.connectionResolve; + return; + } + } + handleAcceptanceOfGrandChildRequest(data, event) { + if (this.extContentConnecting || this.extContentConnected) { + this.logger.debug("cannot process acceptance of a grandchild, because I am connected to a content script"); + return; + } + this.logger.debug(`handling a connection accepted signal targeted at a grandchild: ${data.clientId}`); + const child = this.children.find((c) => c.grandChildId === data.clientId); + if (!child) { + this.logger.error(`cannot handle connection accepted for grandchild: ${data.clientId}, because there is no grandchild with this id`); + return; + } + child.connected = true; + this.logger.debug(`the grandchild connection for ${data.clientId} is set up, forwarding the success message and the gateway port`); + data.parentWindowId = this.publicWindowId; + child.source.postMessage(event.data, child.origin, [data.port]); + return; + } + handleConnectionRejected(event) { + this.logger.debug("handling a connection rejection. Most likely the reason is that this window was not created by a glue API call"); + if (!this.connectionReject) { + return; + } + const errorMsg = typeof event.data.glue42core?.error === "string" + ? `Connection was rejected. ${event.data.glue42core?.error}` + : "The platform connection was rejected. Most likely because this window was not created by a glue API call"; + this.connectionReject(errorMsg); + delete this.connectionReject; + } + handleConnectionRequest(event) { + if (this.extContentConnecting) { + this.logger.debug("This connection request event is targeted at the extension content"); + return; + } + const source = event.source; + const data = event.data.glue42core; + if (!data.clientType || data.clientType !== "grandChild") { + return this.rejectConnectionRequest(source, event.origin, "rejecting a connection request, because the source was not opened by a glue API call"); + } + if (!data.clientId) { + return this.rejectConnectionRequest(source, event.origin, "rejecting a connection request, because the source did not provide a valid id"); + } + if (!this.parent) { + return this.rejectConnectionRequest(source, event.origin, "Cannot forward the connection request, because no direct connection to the platform was found"); + } + this.logger.debug(`handling a connection request for a grandchild: ${data.clientId}`); + this.children.push({ grandChildId: data.clientId, source, connected: false, origin: event.origin }); + this.logger.debug(`grandchild: ${data.clientId} is prepared, forwarding connection request to the platform`); + this.parent.postMessage(event.data, this.defaultTargetString); + } + handleParentPing(event) { + if (!this.parentReady) { + this.logger.debug("my parent is not ready, I am ignoring the parent ping"); + return; + } + if (!this.iAmConnected) { + this.logger.debug("i am not fully connected yet, I am ignoring the parent ping"); + return; + } + const message = { + glue42core: { + type: this.messages.parentReady.name + } + }; + if (this.extContentConnected) { + message.glue42core.extMode = { windowId: this.myClientId }; + } + const source = event.source; + this.logger.debug("responding to a parent ping with a ready message"); + source.postMessage(message, event.origin); + } + setupPlatformUnloadListener() { + this.onMessage((msg) => { + if (msg.type === "platformUnload") { + this.logger.debug("detected a web platform unload"); + this.parentReady = false; + this.notifyStatusChanged(false, "Gateway unloaded"); + } + }); + } + handleManualUnload() { + const message = { + glue42core: { + type: this.messages.clientUnload.name, + data: { + clientId: this.myClientId, + ownWindowId: this.identity?.windowId + } + } + }; + if (this.extContentConnected) { + return window.postMessage({ glue42ExtOut: message }, this.defaultTargetString); + } + this.port?.postMessage(message); + } + handleClientUnload(event) { + const data = event.data.glue42core; + const clientId = data?.data.clientId; + if (!clientId) { + this.logger.warn("cannot process grand child unload, because the provided id was not valid"); + return; + } + const foundChild = this.children.find((child) => child.grandChildId === clientId); + if (!foundChild) { + this.logger.warn("cannot process grand child unload, because this client is unaware of this grandchild"); + return; + } + this.logger.debug(`handling grandchild unload for id: ${clientId}`); + this.children = this.children.filter((child) => child.grandChildId !== clientId); + } + handlePlatformPing() { + return; + } + notifyStatusChanged(status, reason) { + this.iAmConnected = status; + this.registry.execute("onConnectedChanged", status, reason); + } + checkMessageTypeValid(typeToValidate) { + return typeof typeToValidate === "string" && !!this.messages[typeToValidate]; + } + rejectConnectionRequest(source, origin, reason) { + this.rejected = true; + this.logger.error(reason); + const rejection = { + glue42core: { + type: this.messages.connectionRejected.name + } + }; + source.postMessage(rejection, origin); + } + requestConnectionPermissionFromExt() { + return this.waitForContentScript() + .then(() => PromisePlus$1((resolve, reject) => { + this.extConnectionResolve = resolve; + this.extConnectionReject = reject; + const message = { + glue42core: { + type: "extSetupRequest" + } + }; + this.logger.debug("permission request to the extension content script was sent"); + window.postMessage(message, this.defaultTargetString); + }, this.parentPingTimeout, "Cannot initialize glue, because this app was not opened or created by a Glue Client and the request for extension connection timed out")); + } + handleExtConnectionResponse(event) { + const data = event.data?.glue42core; + if (!data.approved) { + return this.extConnectionReject ? this.extConnectionReject("Cannot initialize glue, because this app was not opened or created by a Glue Client and the request for extension connection was rejected") : undefined; + } + if (this.extConnectionResolve) { + this.extConnectionResolve(); + delete this.extConnectionResolve; + } + this.extContentConnecting = true; + this.parentType = "extension"; + this.logger.debug("The extension connection was approved, proceeding."); + } + handleExtSetupRequest() { + return; + } + handleGatewayDisconnect() { + return; + } + handleGatewayInternalConnect() { + return; + } + waitForContentScript() { + const contentReady = !!window.glue42ext?.content; + if (contentReady) { + return Promise.resolve(); + } + return PromisePlus$1((resolve) => { + window.addEventListener("Glue42EXTReady", () => { + resolve(); + }); + }, this.connectionRequestTimeout, "The content script was available, but was never heard to be ready"); + } + async connect() { + if (this.settings.port) { + await this.initiateInternalConnection(); + this.logger.debug("internal web platform connection completed"); + return; + } + this.logger.debug("opening a client web platform connection"); + await this.findParent(); + await this.initiateRemoteConnection(this.parent); + this.logger.debug("the client is connected"); + } + async findParent() { + const connectionNotPossibleMsg = "Cannot initiate glue, because this window was not opened or created by a glue client"; + const myInsideParents = this.getPossibleParentsInWindow(window); + const myOutsideParents = this.getPossibleParentsOutsideWindow(window.top?.opener, window.top); + const uniqueParents = new Set([...myInsideParents, ...myOutsideParents]); + if (!uniqueParents.size && !this.extContentAvailable) { + throw new Error(connectionNotPossibleMsg); + } + if (!uniqueParents.size && this.extContentAvailable) { + await this.requestConnectionPermissionFromExt(); + return; + } + const defaultParentCheck = await this.isParentCheckSuccess(this.confirmParent(Array.from(uniqueParents))); + if (defaultParentCheck.success) { + this.logger.debug("The default parent was found!"); + return; + } + if (!this.extContentAvailable) { + throw new Error(connectionNotPossibleMsg); + } + await this.requestConnectionPermissionFromExt(); + } + getPossibleParentsInWindow(currentWindow) { + return (!currentWindow?.parent || currentWindow === currentWindow.parent) ? [] : [currentWindow.parent, ...this.getPossibleParentsInWindow(currentWindow.parent)]; + } + getPossibleParentsOutsideWindow(opener, current) { + return (!opener || !current || opener === current) ? [] : [opener, ...this.getPossibleParentsInWindow(opener), ...this.getPossibleParentsOutsideWindow(opener.opener, opener)]; + } + confirmParent(targets) { + const connectionNotPossibleMsg = "Cannot initiate glue, because this window was not opened or created by a glue client"; + const parentCheck = PromisePlus$1((resolve) => { + this.parentPingResolve = resolve; + const message = { + glue42core: { + type: this.messages.platformPing.name + } + }; + this.parentPingInterval = setInterval(() => { + targets.forEach((target) => { + target.postMessage(message, this.defaultTargetString); + }); + }, 1000); + }, this.parentPingTimeout, connectionNotPossibleMsg); + parentCheck.catch(() => { + if (this.parentPingInterval) { + clearInterval(this.parentPingInterval); + delete this.parentPingInterval; + } + }); + return parentCheck; + } + getMyWindowId() { + if (this.parentType === "workspace") { + return window.name.substring(0, window.name.indexOf("#wsp")); + } + if (window !== window.top) { + return; + } + if (window.name?.includes("g42")) { + return window.name; + } + this.selfAssignedWindowId = this.selfAssignedWindowId || `g42-${nanoid$1(10)}`; + return this.selfAssignedWindowId; + } + } + + const waitForInvocations = (invocations, callback) => { + let left = invocations; + return () => { + left--; + if (left === 0) { + callback(); + } + }; + }; + + class AsyncSequelizer { + minSequenceInterval; + queue = []; + isExecutingQueue = false; + constructor(minSequenceInterval = 0) { + this.minSequenceInterval = minSequenceInterval; + } + enqueue(action) { + return new Promise((resolve, reject) => { + this.queue.push({ action, resolve, reject }); + this.executeQueue(); + }); + } + async executeQueue() { + if (this.isExecutingQueue) { + return; + } + this.isExecutingQueue = true; + while (this.queue.length) { + const operation = this.queue.shift(); + if (!operation) { + this.isExecutingQueue = false; + return; + } + try { + const actionResult = await operation.action(); + operation.resolve(actionResult); + } + catch (error) { + operation.reject(error); + } + await this.intervalBreak(); + } + this.isExecutingQueue = false; + } + intervalBreak() { + return new Promise((res) => setTimeout(res, this.minSequenceInterval)); + } + } + + function domainSession (domain, connection, logger, successMessages, errorMessages) { + if (domain == null) { + domain = "global"; + } + successMessages = successMessages ?? ["success"]; + errorMessages = errorMessages ?? ["error"]; + let isJoined = domain === "global"; + let tryReconnecting = false; + let _latestOptions; + let _connectionOn = false; + const callbacks = CallbackRegistryFactory$1(); + connection.disconnected(handleConnectionDisconnected); + connection.loggedIn(handleConnectionLoggedIn); + connection.on("success", (msg) => handleSuccessMessage(msg)); + connection.on("error", (msg) => handleErrorMessage(msg)); + connection.on("result", (msg) => handleSuccessMessage(msg)); + if (successMessages) { + successMessages.forEach((sm) => { + connection.on(sm, (msg) => handleSuccessMessage(msg)); + }); + } + if (errorMessages) { + errorMessages.forEach((sm) => { + connection.on(sm, (msg) => handleErrorMessage(msg)); + }); + } + const requestsMap = {}; + function join(options) { + _latestOptions = options; + return new Promise((resolve, reject) => { + if (isJoined) { + resolve({}); + return; + } + let joinPromise; + if (domain === "global") { + joinPromise = _connectionOn ? Promise.resolve({}) : Promise.reject("not connected to gateway"); + } + else { + logger.debug(`joining domain ${domain}`); + const joinMsg = { + type: "join", + destination: domain, + domain: "global", + options, + }; + joinPromise = send(joinMsg); + } + joinPromise + .then(() => { + handleJoined(); + resolve({}); + }) + .catch((err) => { + logger.debug("error joining " + domain + " domain: " + JSON.stringify(err)); + reject(err); + }); + }); + } + function leave() { + if (domain === "global") { + return Promise.resolve(); + } + logger.debug("stopping session " + domain + "..."); + const leaveMsg = { + type: "leave", + destination: domain, + domain: "global", + }; + tryReconnecting = false; + return send(leaveMsg) + .then(() => { + isJoined = false; + callbacks.execute("onLeft"); + }) + .catch(() => { + isJoined = false; + callbacks.execute("onLeft"); + }); + } + function handleJoined() { + logger.debug("did join " + domain); + isJoined = true; + const wasReconnect = tryReconnecting; + tryReconnecting = false; + callbacks.execute("onJoined", wasReconnect); + } + function handleConnectionDisconnected() { + _connectionOn = false; + logger.debug("connection is down"); + isJoined = false; + tryReconnecting = true; + callbacks.execute("onLeft", { disconnected: true }); + } + function handleConnectionLoggedIn() { + _connectionOn = true; + if (tryReconnecting) { + logger.debug("connection is now up - trying to reconnect..."); + join(_latestOptions); + } + } + function onJoined(callback) { + if (isJoined) { + callback(false); + } + return callbacks.add("onJoined", callback); + } + function onLeft(callback) { + if (!isJoined) { + callback(); + } + return callbacks.add("onLeft", callback); + } + function handleErrorMessage(msg) { + if (domain !== msg.domain) { + return; + } + const requestId = msg.request_id; + if (!requestId) { + return; + } + const entry = requestsMap[requestId]; + if (!entry) { + return; + } + entry.error(msg); + } + function handleSuccessMessage(msg) { + if (msg.domain !== domain) { + return; + } + const requestId = msg.request_id; + if (!requestId) { + return; + } + const entry = requestsMap[requestId]; + if (!entry) { + return; + } + entry.success(msg); + } + function getNextRequestId() { + return nanoid$1(10); + } + let queuedCalls = []; + function send(msg, tag, options) { + const ignore = ["hello", "join"]; + if (msg.type && ignore.indexOf(msg.type) === -1) { + if (!isJoined) { + console.warn(`trying to send a message (${msg.domain} ${msg.type}) but not connected, will queue`); + const pw = new PromiseWrapper$1(); + queuedCalls.push({ msg, tag, options, pw }); + if (queuedCalls.length === 1) { + const unsubscribe = onJoined(() => { + logger.info(`joined - will now send queued messages (${queuedCalls.length} -> [${queuedCalls.map((m) => m.msg.type)}])`); + queuedCalls.forEach((qm) => { + send(qm.msg, qm.tag, qm.options) + .then((t) => qm.pw.resolve(t)) + .catch((e) => qm.pw.reject(e)); + }); + queuedCalls = []; + unsubscribe(); + }); + } + return pw.promise; + } + } + options = options ?? {}; + msg.request_id = msg.request_id ?? getNextRequestId(); + msg.domain = msg.domain ?? domain; + if (!options.skipPeerId) { + msg.peer_id = connection.peerId; + } + const requestId = msg.request_id; + return new Promise((resolve, reject) => { + requestsMap[requestId] = { + success: (successMsg) => { + delete requestsMap[requestId]; + successMsg._tag = tag; + resolve(successMsg); + }, + error: (errorMsg) => { + logger.warn(`Gateway error - ${JSON.stringify(errorMsg)}`); + delete requestsMap[requestId]; + errorMsg._tag = tag; + reject(errorMsg); + }, + }; + connection + .send(msg, options) + .catch((err) => { + requestsMap[requestId].error({ err }); + }); + }); + } + function sendFireAndForget(msg) { + msg.request_id = msg.request_id ? msg.request_id : getNextRequestId(); + msg.domain = msg.domain ?? domain; + msg.peer_id = connection.peerId; + return connection.send(msg); + } + return { + join, + leave, + onJoined, + onLeft, + send, + sendFireAndForget, + on: (type, callback) => { + connection.on(type, (msg) => { + if (msg.domain !== domain) { + return; + } + try { + callback(msg); + } + catch (e) { + logger.error(`Callback failed: ${e} \n ${e.stack} \n msg was: ${JSON.stringify(msg)}`, e); + } + }); + }, + loggedIn: (callback) => connection.loggedIn(callback), + connected: (callback) => connection.connected(callback), + disconnected: (callback) => connection.disconnected(callback), + get peerId() { + return connection.peerId; + }, + get domain() { + return domain; + }, + }; + } + + class Connection { + settings; + logger; + protocolVersion = 3; + peerId; + token; + info; + resolvedIdentity; + availableDomains; + gatewayToken; + replayer; + messageHandlers = {}; + ids = 1; + registry = CallbackRegistryFactory$1(); + _connected = false; + isTrace = false; + transport; + _defaultTransport; + _defaultAuth; + _targetTransport; + _targetAuth; + _swapTransport = false; + _switchInProgress = false; + _transportSubscriptions = []; + datePrefix = "#T42_DATE#"; + datePrefixLen = this.datePrefix.length; + dateMinLen = this.datePrefixLen + 1; + datePrefixFirstChar = this.datePrefix[0]; + _sequelizer = new AsyncSequelizer(); + _isLoggedIn = false; + shouldTryLogin = true; + pingTimer; + sessions = []; + globalDomain; + initialLogin = true; + initialLoginAttempts = 3; + loginConfig; + constructor(settings, logger) { + this.settings = settings; + this.logger = logger; + settings = settings || {}; + settings.reconnectAttempts = settings.reconnectAttempts ?? 10; + settings.reconnectInterval = settings.reconnectInterval ?? 1000; + if (settings.inproc) { + this.transport = new InProcTransport(settings.inproc, logger.subLogger("inMemory")); + } + else if (settings.sharedWorker) { + this.transport = new SharedWorkerTransport(settings.sharedWorker, logger.subLogger("shared-worker")); + } + else if (settings.webPlatform) { + this.transport = new WebPlatformTransport(settings.webPlatform, logger.subLogger("web-platform"), settings.identity); + } + else if (settings.ws !== undefined) { + this.transport = new WS(settings, logger.subLogger("ws")); + } + else { + throw new Error("No connection information specified"); + } + this.isTrace = logger.canPublish("trace"); + logger.debug(`starting with ${this.transport.name()} transport`); + const unsubConnectionChanged = this.transport.onConnectedChanged(this.handleConnectionChanged.bind(this)); + const unsubOnMessage = this.transport.onMessage(this.handleTransportMessage.bind(this)); + this._transportSubscriptions.push(unsubConnectionChanged); + this._transportSubscriptions.push(unsubOnMessage); + this._defaultTransport = this.transport; + this.ping(); + } + async switchTransport(settings) { + return this._sequelizer.enqueue(async () => { + if (!settings || typeof settings !== "object") { + throw new Error("Cannot switch transports, because the settings are missing or invalid."); + } + if (typeof settings.type === "undefined") { + throw new Error("Cannot switch the transport, because the type is not defined"); + } + this.logger.trace(`Starting transport switch with settings: ${JSON.stringify(settings)}`); + const switchTargetTransport = settings.type === "secondary" ? this.getNewSecondaryTransport(settings) : this._defaultTransport; + this._targetTransport = switchTargetTransport; + this._targetAuth = settings.type === "secondary" ? this.getNewSecondaryAuth(settings) : this._defaultAuth; + const verifyPromise = this.verifyConnection(); + this._swapTransport = true; + this._switchInProgress = true; + this.logger.trace("The new transport has been set, closing the current transport"); + await this.transport.close(); + try { + await verifyPromise; + const isSwitchSuccess = this.transport === switchTargetTransport; + this.logger.info(`The reconnection after the switch was completed. Was the switch a success: ${isSwitchSuccess}`); + this._switchInProgress = false; + return { success: isSwitchSuccess }; + } + catch (error) { + this.logger.info("The reconnection after the switch timed out, reverting back to the default transport."); + this.switchTransport({ type: "default" }); + this._switchInProgress = false; + return { success: false }; + } + }); + } + onLibReAnnounced(callback) { + return this.registry.add("libReAnnounced", callback); + } + setLibReAnnounced(lib) { + this.registry.execute("libReAnnounced", lib); + } + send(message, options) { + if (this.transport.sendObject && + this.transport.isObjectBasedTransport) { + const msg = this.createObjectMessage(message); + if (this.isTrace) { + this.logger.trace(`>> ${JSON.stringify(msg)}`); + } + return this.transport.sendObject(msg, options); + } + else { + const strMessage = this.createStringMessage(message); + if (this.isTrace) { + this.logger.trace(`>> ${strMessage}`); + } + return this.transport.send(strMessage, options); + } + } + on(type, messageHandler) { + type = type.toLowerCase(); + if (this.messageHandlers[type] === undefined) { + this.messageHandlers[type] = {}; + } + const id = this.ids++; + this.messageHandlers[type][id] = messageHandler; + return { + type, + id, + }; + } + off(info) { + delete this.messageHandlers[info.type.toLowerCase()][info.id]; + } + get isConnected() { + return this._isLoggedIn; + } + connected(callback) { + return this.loggedIn(() => { + const currentServer = this.transport.name(); + callback(currentServer); + }); + } + disconnected(callback) { + return this.registry.add("disconnected", callback); + } + async login(authRequest, reconnect) { + if (!this._defaultAuth) { + this._defaultAuth = authRequest; + } + if (this._swapTransport) { + this.logger.trace("Detected a transport swap, swapping transports"); + const newAuth = this.transportSwap(); + authRequest = newAuth ?? authRequest; + } + this.logger.trace(`Starting login for transport: ${this.transport.name()} and auth ${JSON.stringify(authRequest)}`); + try { + await this.transport.open(); + this.logger.trace(`Transport: ${this.transport.name()} opened, logging in`); + timer("connection").mark("transport-opened"); + const identity = await this.loginCore(authRequest, reconnect); + this.logger.trace(`Logged in with identity: ${JSON.stringify(identity)}`); + timer("connection").mark("protocol-logged-in"); + return identity; + } + catch (error) { + if (this._switchInProgress) { + this.logger.trace("An error while logging in after a transport swap, preparing a default swap."); + this.prepareDefaultSwap(); + } + throw new Error(error); + } + } + async logout() { + await this.logoutCore(); + await this.transport.close(); + } + loggedIn(callback) { + if (this._isLoggedIn) { + callback(); + } + return this.registry.add("onLoggedIn", callback); + } + domain(domain, successMessages, errorMessages) { + let session = this.sessions.find((s) => s.domain === domain); + if (!session) { + session = domainSession(domain, this, this.logger.subLogger(`domain=${domain}`), successMessages, errorMessages); + this.sessions.push(session); + } + return session; + } + authToken() { + const createTokenReq = { + domain: "global", + type: "create-token" + }; + if (!this.globalDomain) { + return Promise.reject(new Error("no global domain session")); + } + return this.globalDomain.send(createTokenReq) + .then((res) => { + return res.token; + }); + } + reconnect() { + return this.transport.reconnect(); + } + setLoggedIn(value) { + this._isLoggedIn = value; + if (this._isLoggedIn) { + this.registry.execute("onLoggedIn"); + } + } + distributeMessage(message, type) { + const handlers = this.messageHandlers[type.toLowerCase()]; + if (handlers !== undefined) { + Object.keys(handlers).forEach((handlerId) => { + const handler = handlers[handlerId]; + if (handler !== undefined) { + try { + handler(message); + } + catch (error) { + try { + this.logger.error(`Message handler failed with ${error.stack}`, error); + } + catch (loggerError) { + console.log("Message handler failed", error); + } + } + } + }); + } + } + handleConnectionChanged(connected) { + if (this._connected === connected) { + return; + } + this._connected = connected; + if (connected) { + if (this.settings?.replaySpecs?.length) { + this.replayer = new MessageReplayerImpl(this.settings.replaySpecs); + this.replayer.init(this); + } + this.registry.execute("connected"); + } + else { + this.handleDisconnected(); + this.registry.execute("disconnected"); + } + } + handleDisconnected() { + this.setLoggedIn(false); + const tryToLogin = this.shouldTryLogin; + if (tryToLogin && this.initialLogin) { + if (this.initialLoginAttempts <= 0) { + return; + } + this.initialLoginAttempts--; + } + this.logger.debug("disconnected - will try new login?" + this.shouldTryLogin); + if (this.shouldTryLogin) { + if (!this.loginConfig) { + throw new Error("no login info"); + } + this.login(this.loginConfig, true) + .catch(() => { + setTimeout(this.handleDisconnected.bind(this), this.settings.reconnectInterval || 1000); + }); + } + } + handleTransportMessage(msg) { + let msgObj; + if (typeof msg === "string") { + msgObj = this.processStringMessage(msg); + } + else { + msgObj = this.processObjectMessage(msg); + } + if (this.isTrace) { + this.logger.trace(`<< ${JSON.stringify(msgObj)}`); + } + this.distributeMessage(msgObj.msg, msgObj.msgType); + } + verifyConnection() { + return PromisePlus$1((resolve) => { + let unsub; + const ready = waitForInvocations(2, () => { + if (unsub) { + unsub(); + } + resolve(); + }); + unsub = this.onLibReAnnounced((lib) => { + if (lib.name === "interop") { + return ready(); + } + if (lib.name === "contexts") { + return ready(); + } + }); + }, 10000, "Transport switch timed out waiting for all libraries to be re-announced"); + } + getNewSecondaryTransport(settings) { + if (!settings.transportConfig?.url) { + throw new Error("Missing secondary transport URL."); + } + return new WS(Object.assign({}, this.settings, { ws: settings.transportConfig.url, reconnectAttempts: 1 }), this.logger.subLogger("ws-secondary")); + } + getNewSecondaryAuth(settings) { + if (!settings.transportConfig?.auth) { + throw new Error("Missing secondary transport auth information."); + } + return settings.transportConfig.auth; + } + transportSwap() { + this._swapTransport = false; + if (!this._targetTransport || !this._targetAuth) { + this.logger.warn(`Error while switching transports - either the target transport or auth is not defined: transport defined -> ${!!this._defaultTransport}, auth defined -> ${!!this._targetAuth}. Staying on the current one.`); + return; + } + this._transportSubscriptions.forEach((unsub) => unsub()); + this._transportSubscriptions = []; + this.transport = this._targetTransport; + const unsubConnectionChanged = this.transport.onConnectedChanged(this.handleConnectionChanged.bind(this)); + const unsubOnMessage = this.transport.onMessage(this.handleTransportMessage.bind(this)); + this._transportSubscriptions.push(unsubConnectionChanged); + this._transportSubscriptions.push(unsubOnMessage); + return this._targetAuth; + } + prepareDefaultSwap() { + this._transportSubscriptions.forEach((unsub) => unsub()); + this._transportSubscriptions = []; + this.transport.close().catch((error) => this.logger.warn(`Error closing the ${this.transport.name()} transport after a failed connection attempt: ${JSON.stringify(error)}`)); + this._targetTransport = this._defaultTransport; + this._targetAuth = this._defaultAuth; + this._swapTransport = true; + } + processStringMessage(message) { + const msg = JSON.parse(message, (key, value) => { + if (typeof value !== "string") { + return value; + } + if (value.length < this.dateMinLen) { + return value; + } + if (!value.startsWith(this.datePrefixFirstChar)) { + return value; + } + if (value.substring(0, this.datePrefixLen) !== this.datePrefix) { + return value; + } + try { + const milliseconds = parseInt(value.substring(this.datePrefixLen, value.length), 10); + if (isNaN(milliseconds)) { + return value; + } + return new Date(milliseconds); + } + catch (ex) { + return value; + } + }); + return { + msg, + msgType: msg.type, + }; + } + createStringMessage(message) { + const oldToJson = Date.prototype.toJSON; + try { + const datePrefix = this.datePrefix; + Date.prototype.toJSON = function () { + return datePrefix + this.getTime(); + }; + const result = JSON.stringify(message); + return result; + } + finally { + Date.prototype.toJSON = oldToJson; + } + } + processObjectMessage(message) { + if (!message.type) { + throw new Error("Object should have type property"); + } + return { + msg: message, + msgType: message.type, + }; + } + createObjectMessage(message) { + return message; + } + async loginCore(config, reconnect) { + this.logger.info("logging in..."); + this.loginConfig = config; + if (!this.loginConfig) { + this.loginConfig = { username: "", password: "" }; + } + this.shouldTryLogin = true; + const authentication = await this.setupAuthConfig(config, reconnect); + const helloMsg = { + type: "hello", + identity: this.settings.identity, + authentication + }; + if (config.sessionId) { + helloMsg.request_id = config.sessionId; + } + this.globalDomain = domainSession("global", this, this.logger.subLogger("global-domain"), [ + "welcome", + "token", + "authentication-request" + ]); + const sendOptions = { skipPeerId: true }; + if (this.initialLogin) { + sendOptions.retryInterval = this.settings.reconnectInterval; + sendOptions.maxRetries = this.settings.reconnectAttempts; + } + try { + const welcomeMsg = await this.tryAuthenticate(this.globalDomain, helloMsg, sendOptions, config); + this.initialLogin = false; + this.logger.info("login successful with peerId " + welcomeMsg.peer_id); + this.peerId = welcomeMsg.peer_id; + this.resolvedIdentity = welcomeMsg.resolved_identity; + this.availableDomains = welcomeMsg.available_domains; + if (welcomeMsg.options) { + this.token = welcomeMsg.options.access_token; + this.info = welcomeMsg.options.info; + } + this.setLoggedIn(true); + return welcomeMsg.resolved_identity; + } + catch (err) { + this.logger.error("error sending hello message - " + (err.message || err.msg || err.reason || err), err); + throw err; + } + finally { + if (config?.flowCallback && config.sessionId) { + config.flowCallback(config.sessionId, null); + } + } + } + async tryAuthenticate(globalDomain, helloMsg, sendOptions, config) { + let welcomeMsg; + while (true) { + const msg = await globalDomain.send(helloMsg, undefined, sendOptions); + if (msg.type === "authentication-request") { + const token = Buffer.from(msg.authentication.token, "base64"); + if (config.flowCallback && config.sessionId) { + helloMsg.authentication.token = + (await config.flowCallback(config.sessionId, token)) + .data + .toString("base64"); + } + helloMsg.request_id = config.sessionId; + } + else if (msg.type === "welcome") { + welcomeMsg = msg; + break; + } + else if (msg.type === "error") { + throw new Error("Authentication failed: " + msg.reason); + } + else { + throw new Error("Unexpected message type during authentication: " + msg.type); + } + } + return welcomeMsg; + } + async setupAuthConfig(config, reconnect) { + const authentication = {}; + this.gatewayToken = config.gatewayToken; + if (config.gatewayToken) { + if (reconnect) { + try { + config.gatewayToken = await this.getNewGWToken(); + } + catch (e) { + this.logger.warn(`failed to get GW token when reconnecting ${e?.message || e}`); + } + } + authentication.method = "gateway-token"; + authentication.token = config.gatewayToken; + this.gatewayToken = config.gatewayToken; + } + else if (config.flowName === "sspi") { + authentication.provider = "win"; + authentication.method = "access-token"; + if (config.flowCallback && config.sessionId) { + authentication.token = + (await config.flowCallback(config.sessionId, null)) + .data + .toString("base64"); + } + else { + throw new Error("Invalid SSPI config"); + } + } + else if (config.token) { + authentication.method = "access-token"; + authentication.token = config.token; + } + else if (config.username) { + authentication.method = "secret"; + authentication.login = config.username; + authentication.secret = config.password; + } + else if (config.provider) { + authentication.provider = config.provider; + authentication.providerContext = config.providerContext; + } + else { + throw new Error("invalid auth message" + JSON.stringify(config)); + } + return authentication; + } + async logoutCore() { + this.logger.debug("logging out..."); + this.shouldTryLogin = false; + if (this.pingTimer) { + clearTimeout(this.pingTimer); + } + const promises = this.sessions.map((session) => { + session.leave(); + }); + await Promise.all(promises); + } + getNewGWToken() { + if (typeof window !== "undefined") { + const glue42gd = window.glue42gd; + if (glue42gd) { + return glue42gd.getGWToken(); + } + } + return Promise.reject(new Error("not running in GD")); + } + ping() { + if (!this.shouldTryLogin) { + return; + } + if (this._isLoggedIn) { + this.send({ type: "ping" }); + } + this.pingTimer = setTimeout(() => { + this.ping(); + }, 30 * 1000); + } + } + + const order = ["trace", "debug", "info", "warn", "error", "off"]; + let Logger$1 = class Logger { + name; + parent; + static Interop; + static InteropMethodName = "T42.AppLogger.Log"; + static Instance; + path; + subLoggers = []; + _consoleLevel; + _publishLevel; + loggerFullName; + includeTimeAndLevel; + logFn = console; + customLogFn = false; + constructor(name, parent, logFn) { + this.name = name; + this.parent = parent; + this.name = name; + if (parent) { + this.path = `${parent.path}.${name}`; + } + else { + this.path = name; + } + this.loggerFullName = `[${this.path}]`; + this.includeTimeAndLevel = !logFn; + if (logFn) { + this.logFn = logFn; + this.customLogFn = true; + } + } + subLogger(name) { + const existingSub = this.subLoggers.filter((subLogger) => { + return subLogger.name === name; + })[0]; + if (existingSub !== undefined) { + return existingSub; + } + Object.keys(this).forEach((key) => { + if (key === name) { + throw new Error("This sub logger name is not allowed."); + } + }); + const sub = new Logger(name, this, this.customLogFn ? this.logFn : undefined); + this.subLoggers.push(sub); + return sub; + } + publishLevel(level) { + if (level) { + this._publishLevel = level; + } + return this._publishLevel || this.parent?.publishLevel(); + } + consoleLevel(level) { + if (level) { + this._consoleLevel = level; + } + return this._consoleLevel || this.parent?.consoleLevel(); + } + log(message, level, error) { + this.publishMessage(level || "info", message, error); + } + trace(message) { + this.log(message, "trace"); + } + debug(message) { + this.log(message, "debug"); + } + info(message) { + this.log(message, "info"); + } + warn(message) { + this.log(message, "warn"); + } + error(message, err) { + this.log(message, "error", err); + } + canPublish(level, compareWith) { + const levelIdx = order.indexOf(level); + const restrictionIdx = order.indexOf(compareWith || this.consoleLevel() || "trace"); + return levelIdx >= restrictionIdx; + } + publishMessage(level, message, error) { + const loggerName = this.loggerFullName; + if (level === "error" && !error) { + const e = new Error(); + if (e.stack) { + message = + message + + "\n" + + e.stack + .split("\n") + .slice(4) + .join("\n"); + } + } + if (this.canPublish(level, this.publishLevel())) { + const interop = Logger.Interop; + if (interop) { + try { + if (interop.methods({ name: Logger.InteropMethodName }).length > 0) { + const args = { + msg: message, + logger: loggerName, + level + }; + if (error && error instanceof Error) { + args.error = { + message: error.message, + stack: error.stack ?? "" + }; + } + interop.invoke(Logger.InteropMethodName, args); + } + } + catch { + } + } + } + if (this.canPublish(level)) { + let prefix = ""; + if (this.includeTimeAndLevel) { + const date = new Date(); + const time = `${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}:${date.getMilliseconds()}`; + prefix = `[${time}] [${level}] `; + } + const toPrint = `${prefix}${loggerName}: ${message}`; + switch (level) { + case "trace": + this.logFn.debug(toPrint); + break; + case "debug": + if (this.logFn.debug) { + this.logFn.debug(toPrint); + } + else { + this.logFn.log(toPrint); + } + break; + case "info": + this.logFn.info(toPrint); + break; + case "warn": + this.logFn.warn(toPrint); + break; + case "error": + this.logFn.error(toPrint, error); + break; + } + } + } + }; + + const GW_MESSAGE_CREATE_CONTEXT = "create-context"; + const GW_MESSAGE_ACTIVITY_CREATED = "created"; + const GW_MESSAGE_ACTIVITY_DESTROYED = "destroyed"; + const GW_MESSAGE_CONTEXT_CREATED = "context-created"; + const GW_MESSAGE_CONTEXT_ADDED = "context-added"; + const GW_MESSAGE_SUBSCRIBE_CONTEXT = "subscribe-context"; + const GW_MESSAGE_SUBSCRIBED_CONTEXT = "subscribed-context"; + const GW_MESSAGE_UNSUBSCRIBE_CONTEXT = "unsubscribe-context"; + const GW_MESSAGE_DESTROY_CONTEXT = "destroy-context"; + const GW_MESSAGE_CONTEXT_DESTROYED = "context-destroyed"; + const GW_MESSAGE_UPDATE_CONTEXT = "update-context"; + const GW_MESSAGE_CONTEXT_UPDATED = "context-updated"; + const GW_MESSAGE_JOINED_ACTIVITY = "joined"; + + const ContextMessageReplaySpec = { + get name() { + return "context"; + }, + get types() { + return [ + GW_MESSAGE_CREATE_CONTEXT, + GW_MESSAGE_ACTIVITY_CREATED, + GW_MESSAGE_ACTIVITY_DESTROYED, + GW_MESSAGE_CONTEXT_CREATED, + GW_MESSAGE_CONTEXT_ADDED, + GW_MESSAGE_SUBSCRIBE_CONTEXT, + GW_MESSAGE_SUBSCRIBED_CONTEXT, + GW_MESSAGE_UNSUBSCRIBE_CONTEXT, + GW_MESSAGE_DESTROY_CONTEXT, + GW_MESSAGE_CONTEXT_DESTROYED, + GW_MESSAGE_UPDATE_CONTEXT, + GW_MESSAGE_CONTEXT_UPDATED, + GW_MESSAGE_JOINED_ACTIVITY + ]; + } + }; + + var version$1 = "6.5.2-fmr-beta"; + + function prepareConfig$1 (configuration, ext, glue42gd) { + let nodeStartingContext; + if (Utils$1.isNode()) { + const startingContextString = process.env._GD_STARTING_CONTEXT_; + if (startingContextString) { + try { + nodeStartingContext = JSON.parse(startingContextString); + } + catch { + } + } + } + function getConnection() { + const gwConfig = configuration.gateway; + const protocolVersion = gwConfig?.protocolVersion ?? 3; + const reconnectInterval = gwConfig?.reconnectInterval; + const reconnectAttempts = gwConfig?.reconnectAttempts; + const defaultWs = "ws://localhost:8385"; + let ws = gwConfig?.ws; + const sharedWorker = gwConfig?.sharedWorker; + const inproc = gwConfig?.inproc; + const webPlatform = gwConfig?.webPlatform ?? undefined; + if (glue42gd) { + ws = glue42gd.gwURL; + } + if (Utils$1.isNode() && nodeStartingContext && nodeStartingContext.gwURL) { + ws = nodeStartingContext.gwURL; + } + if (!ws && !sharedWorker && !inproc) { + ws = defaultWs; + } + let instanceId; + let windowId; + let pid; + let environment; + let region; + const appName = getApplication(); + let uniqueAppName = appName; + if (typeof glue42gd !== "undefined") { + windowId = glue42gd.windowId; + pid = glue42gd.pid; + if (glue42gd.env) { + environment = glue42gd.env.env; + region = glue42gd.env.region; + } + uniqueAppName = glue42gd.application ?? "glue-app"; + instanceId = glue42gd.appInstanceId; + } + else if (Utils$1.isNode()) { + pid = process.pid; + if (nodeStartingContext) { + environment = nodeStartingContext.env; + region = nodeStartingContext.region; + instanceId = nodeStartingContext.instanceId; + } + } + else if (typeof window?.glue42electron !== "undefined") { + windowId = window?.glue42electron.instanceId; + pid = window?.glue42electron.pid; + environment = window?.glue42electron.env; + region = window?.glue42electron.region; + uniqueAppName = window?.glue42electron.application ?? "glue-app"; + instanceId = window?.glue42electron.instanceId; + } + else ; + const replaySpecs = configuration.gateway?.replaySpecs ?? []; + replaySpecs.push(ContextMessageReplaySpec); + let identity = { + application: uniqueAppName, + applicationName: appName, + windowId, + instance: instanceId, + process: pid, + region, + environment, + api: ext.version || version$1 + }; + if (configuration.identity) { + identity = Object.assign(identity, configuration.identity); + } + return { + identity, + reconnectInterval, + ws, + sharedWorker, + webPlatform, + inproc, + protocolVersion, + reconnectAttempts, + replaySpecs, + }; + } + function getContexts() { + if (typeof configuration.contexts === "undefined") { + return { reAnnounceKnownContexts: true }; + } + if (typeof configuration.contexts === "boolean" && configuration.contexts) { + return { reAnnounceKnownContexts: true }; + } + if (typeof configuration.contexts === "object") { + return Object.assign({}, { reAnnounceKnownContexts: true }, configuration.contexts); + } + return false; + } + function getApplication() { + if (configuration.application) { + return configuration.application; + } + if (glue42gd) { + return glue42gd.applicationName; + } + if (typeof window !== "undefined" && typeof window.glue42electron !== "undefined") { + return window.glue42electron.application; + } + const uid = nanoid$1(10); + if (Utils$1.isNode()) { + if (nodeStartingContext) { + return nodeStartingContext.applicationConfig.name; + } + return "NodeJS" + uid; + } + if (typeof window !== "undefined" && typeof document !== "undefined") { + return document.title + ` (${uid})`; + } + return uid; + } + function getAuth() { + if (typeof configuration.auth === "string") { + return { + token: configuration.auth + }; + } + if (configuration.auth) { + return configuration.auth; + } + if (Utils$1.isNode() && nodeStartingContext && nodeStartingContext.gwToken) { + return { + gatewayToken: nodeStartingContext.gwToken + }; + } + if (configuration.gateway?.webPlatform || configuration.gateway?.inproc || configuration.gateway?.sharedWorker) { + return { + username: "glue42", password: "glue42" + }; + } + } + function getLogger() { + let config = configuration.logger; + const defaultLevel = "warn"; + if (!config) { + config = defaultLevel; + } + let gdConsoleLevel; + if (glue42gd) { + gdConsoleLevel = glue42gd.consoleLogLevel; + } + if (typeof config === "string") { + return { console: gdConsoleLevel ?? config, publish: defaultLevel }; + } + return { + console: gdConsoleLevel ?? config.console ?? defaultLevel, + publish: config.publish ?? defaultLevel + }; + } + const connection = getConnection(); + let application = getApplication(); + if (typeof window !== "undefined") { + const windowAsAny = window; + const containerApplication = windowAsAny.htmlContainer ? + `${windowAsAny.htmlContainer.containerName}.${windowAsAny.htmlContainer.application}` : + windowAsAny?.glue42gd?.application; + if (containerApplication) { + application = containerApplication; + } + } + return { + bus: configuration.bus ?? false, + application, + auth: getAuth(), + logger: getLogger(), + connection, + metrics: configuration.metrics ?? true, + contexts: getContexts(), + version: ext.version || version$1, + libs: ext.libs ?? [], + customLogger: configuration.customLogger + }; + } + + class GW3ContextData { + name; + contextId; + context; + isAnnounced; + joinedActivity; + updateCallbacks = {}; + activityId; + sentExplicitSubscription; + hasReceivedSnapshot; + constructor(contextId, name, isAnnounced, activityId) { + this.contextId = contextId; + this.name = name; + this.isAnnounced = isAnnounced; + this.activityId = activityId; + this.context = {}; + } + hasCallbacks() { + return Object.keys(this.updateCallbacks).length > 0; + } + getState() { + if (this.isAnnounced && this.hasCallbacks()) { + return 3; + } + if (this.isAnnounced) { + return 2; + } + if (this.hasCallbacks()) { + return 1; + } + return 0; + } + } + + var lodash_clonedeep = {exports: {}}; + + /** + * lodash (Custom Build) + * Build: `lodash modularize exports="npm" -o ./` + * Copyright jQuery Foundation and other contributors + * Released under MIT license + * Based on Underscore.js 1.8.3 + * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + */ + lodash_clonedeep.exports; + + (function (module, exports) { + /** Used as the size to enable large array optimizations. */ + var LARGE_ARRAY_SIZE = 200; + + /** Used to stand-in for `undefined` hash values. */ + var HASH_UNDEFINED = '__lodash_hash_undefined__'; + + /** Used as references for various `Number` constants. */ + var MAX_SAFE_INTEGER = 9007199254740991; + + /** `Object#toString` result references. */ + var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + boolTag = '[object Boolean]', + dateTag = '[object Date]', + errorTag = '[object Error]', + funcTag = '[object Function]', + genTag = '[object GeneratorFunction]', + mapTag = '[object Map]', + numberTag = '[object Number]', + objectTag = '[object Object]', + promiseTag = '[object Promise]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + symbolTag = '[object Symbol]', + weakMapTag = '[object WeakMap]'; + + var arrayBufferTag = '[object ArrayBuffer]', + dataViewTag = '[object DataView]', + float32Tag = '[object Float32Array]', + float64Tag = '[object Float64Array]', + int8Tag = '[object Int8Array]', + int16Tag = '[object Int16Array]', + int32Tag = '[object Int32Array]', + uint8Tag = '[object Uint8Array]', + uint8ClampedTag = '[object Uint8ClampedArray]', + uint16Tag = '[object Uint16Array]', + uint32Tag = '[object Uint32Array]'; + + /** + * Used to match `RegExp` + * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns). + */ + var reRegExpChar = /[\\^$.*+?()[\]{}|]/g; + + /** Used to match `RegExp` flags from their coerced string values. */ + var reFlags = /\w*$/; + + /** Used to detect host constructors (Safari). */ + var reIsHostCtor = /^\[object .+?Constructor\]$/; + + /** Used to detect unsigned integer values. */ + var reIsUint = /^(?:0|[1-9]\d*)$/; + + /** Used to identify `toStringTag` values supported by `_.clone`. */ + var cloneableTags = {}; + cloneableTags[argsTag] = cloneableTags[arrayTag] = + cloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] = + cloneableTags[boolTag] = cloneableTags[dateTag] = + cloneableTags[float32Tag] = cloneableTags[float64Tag] = + cloneableTags[int8Tag] = cloneableTags[int16Tag] = + cloneableTags[int32Tag] = cloneableTags[mapTag] = + cloneableTags[numberTag] = cloneableTags[objectTag] = + cloneableTags[regexpTag] = cloneableTags[setTag] = + cloneableTags[stringTag] = cloneableTags[symbolTag] = + cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] = + cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true; + cloneableTags[errorTag] = cloneableTags[funcTag] = + cloneableTags[weakMapTag] = false; + + /** Detect free variable `global` from Node.js. */ + var freeGlobal = typeof commonjsGlobal$1 == 'object' && commonjsGlobal$1 && commonjsGlobal$1.Object === Object && commonjsGlobal$1; + + /** Detect free variable `self`. */ + var freeSelf = typeof self == 'object' && self && self.Object === Object && self; + + /** Used as a reference to the global object. */ + var root = freeGlobal || freeSelf || Function('return this')(); + + /** Detect free variable `exports`. */ + var freeExports = exports && !exports.nodeType && exports; + + /** Detect free variable `module`. */ + var freeModule = freeExports && 'object' == 'object' && module && !module.nodeType && module; + + /** Detect the popular CommonJS extension `module.exports`. */ + var moduleExports = freeModule && freeModule.exports === freeExports; + + /** + * Adds the key-value `pair` to `map`. + * + * @private + * @param {Object} map The map to modify. + * @param {Array} pair The key-value pair to add. + * @returns {Object} Returns `map`. + */ + function addMapEntry(map, pair) { + // Don't return `map.set` because it's not chainable in IE 11. + map.set(pair[0], pair[1]); + return map; + } + + /** + * Adds `value` to `set`. + * + * @private + * @param {Object} set The set to modify. + * @param {*} value The value to add. + * @returns {Object} Returns `set`. + */ + function addSetEntry(set, value) { + // Don't return `set.add` because it's not chainable in IE 11. + set.add(value); + return set; + } + + /** + * A specialized version of `_.forEach` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns `array`. + */ + function arrayEach(array, iteratee) { + var index = -1, + length = array ? array.length : 0; + + while (++index < length) { + if (iteratee(array[index], index, array) === false) { + break; + } + } + return array; + } + + /** + * Appends the elements of `values` to `array`. + * + * @private + * @param {Array} array The array to modify. + * @param {Array} values The values to append. + * @returns {Array} Returns `array`. + */ + function arrayPush(array, values) { + var index = -1, + length = values.length, + offset = array.length; + + while (++index < length) { + array[offset + index] = values[index]; + } + return array; + } + + /** + * A specialized version of `_.reduce` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {boolean} [initAccum] Specify using the first element of `array` as + * the initial value. + * @returns {*} Returns the accumulated value. + */ + function arrayReduce(array, iteratee, accumulator, initAccum) { + var index = -1, + length = array ? array.length : 0; + while (++index < length) { + accumulator = iteratee(accumulator, array[index], index, array); + } + return accumulator; + } + + /** + * The base implementation of `_.times` without support for iteratee shorthands + * or max array length checks. + * + * @private + * @param {number} n The number of times to invoke `iteratee`. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the array of results. + */ + function baseTimes(n, iteratee) { + var index = -1, + result = Array(n); + + while (++index < n) { + result[index] = iteratee(index); + } + return result; + } + + /** + * Gets the value at `key` of `object`. + * + * @private + * @param {Object} [object] The object to query. + * @param {string} key The key of the property to get. + * @returns {*} Returns the property value. + */ + function getValue(object, key) { + return object == null ? undefined : object[key]; + } + + /** + * Checks if `value` is a host object in IE < 9. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a host object, else `false`. + */ + function isHostObject(value) { + // Many host objects are `Object` objects that can coerce to strings + // despite having improperly defined `toString` methods. + var result = false; + if (value != null && typeof value.toString != 'function') { + try { + result = !!(value + ''); + } catch (e) {} + } + return result; + } + + /** + * Converts `map` to its key-value pairs. + * + * @private + * @param {Object} map The map to convert. + * @returns {Array} Returns the key-value pairs. + */ + function mapToArray(map) { + var index = -1, + result = Array(map.size); + + map.forEach(function(value, key) { + result[++index] = [key, value]; + }); + return result; + } + + /** + * Creates a unary function that invokes `func` with its argument transformed. + * + * @private + * @param {Function} func The function to wrap. + * @param {Function} transform The argument transform. + * @returns {Function} Returns the new function. + */ + function overArg(func, transform) { + return function(arg) { + return func(transform(arg)); + }; + } + + /** + * Converts `set` to an array of its values. + * + * @private + * @param {Object} set The set to convert. + * @returns {Array} Returns the values. + */ + function setToArray(set) { + var index = -1, + result = Array(set.size); + + set.forEach(function(value) { + result[++index] = value; + }); + return result; + } + + /** Used for built-in method references. */ + var arrayProto = Array.prototype, + funcProto = Function.prototype, + objectProto = Object.prototype; + + /** Used to detect overreaching core-js shims. */ + var coreJsData = root['__core-js_shared__']; + + /** Used to detect methods masquerading as native. */ + var maskSrcKey = (function() { + var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || ''); + return uid ? ('Symbol(src)_1.' + uid) : ''; + }()); + + /** Used to resolve the decompiled source of functions. */ + var funcToString = funcProto.toString; + + /** Used to check objects for own properties. */ + var hasOwnProperty = objectProto.hasOwnProperty; + + /** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ + var objectToString = objectProto.toString; + + /** Used to detect if a method is native. */ + var reIsNative = RegExp('^' + + funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&') + .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' + ); + + /** Built-in value references. */ + var Buffer = moduleExports ? root.Buffer : undefined, + Symbol = root.Symbol, + Uint8Array = root.Uint8Array, + getPrototype = overArg(Object.getPrototypeOf, Object), + objectCreate = Object.create, + propertyIsEnumerable = objectProto.propertyIsEnumerable, + splice = arrayProto.splice; + + /* Built-in method references for those with the same name as other `lodash` methods. */ + var nativeGetSymbols = Object.getOwnPropertySymbols, + nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined, + nativeKeys = overArg(Object.keys, Object); + + /* Built-in method references that are verified to be native. */ + var DataView = getNative(root, 'DataView'), + Map = getNative(root, 'Map'), + Promise = getNative(root, 'Promise'), + Set = getNative(root, 'Set'), + WeakMap = getNative(root, 'WeakMap'), + nativeCreate = getNative(Object, 'create'); + + /** Used to detect maps, sets, and weakmaps. */ + var dataViewCtorString = toSource(DataView), + mapCtorString = toSource(Map), + promiseCtorString = toSource(Promise), + setCtorString = toSource(Set), + weakMapCtorString = toSource(WeakMap); + + /** Used to convert symbols to primitives and strings. */ + var symbolProto = Symbol ? Symbol.prototype : undefined, + symbolValueOf = symbolProto ? symbolProto.valueOf : undefined; + + /** + * Creates a hash object. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + function Hash(entries) { + var index = -1, + length = entries ? entries.length : 0; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } + } + + /** + * Removes all key-value entries from the hash. + * + * @private + * @name clear + * @memberOf Hash + */ + function hashClear() { + this.__data__ = nativeCreate ? nativeCreate(null) : {}; + } + + /** + * Removes `key` and its value from the hash. + * + * @private + * @name delete + * @memberOf Hash + * @param {Object} hash The hash to modify. + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function hashDelete(key) { + return this.has(key) && delete this.__data__[key]; + } + + /** + * Gets the hash value for `key`. + * + * @private + * @name get + * @memberOf Hash + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function hashGet(key) { + var data = this.__data__; + if (nativeCreate) { + var result = data[key]; + return result === HASH_UNDEFINED ? undefined : result; + } + return hasOwnProperty.call(data, key) ? data[key] : undefined; + } + + /** + * Checks if a hash value for `key` exists. + * + * @private + * @name has + * @memberOf Hash + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function hashHas(key) { + var data = this.__data__; + return nativeCreate ? data[key] !== undefined : hasOwnProperty.call(data, key); + } + + /** + * Sets the hash `key` to `value`. + * + * @private + * @name set + * @memberOf Hash + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the hash instance. + */ + function hashSet(key, value) { + var data = this.__data__; + data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value; + return this; + } + + // Add methods to `Hash`. + Hash.prototype.clear = hashClear; + Hash.prototype['delete'] = hashDelete; + Hash.prototype.get = hashGet; + Hash.prototype.has = hashHas; + Hash.prototype.set = hashSet; + + /** + * Creates an list cache object. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + function ListCache(entries) { + var index = -1, + length = entries ? entries.length : 0; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } + } + + /** + * Removes all key-value entries from the list cache. + * + * @private + * @name clear + * @memberOf ListCache + */ + function listCacheClear() { + this.__data__ = []; + } + + /** + * Removes `key` and its value from the list cache. + * + * @private + * @name delete + * @memberOf ListCache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function listCacheDelete(key) { + var data = this.__data__, + index = assocIndexOf(data, key); + + if (index < 0) { + return false; + } + var lastIndex = data.length - 1; + if (index == lastIndex) { + data.pop(); + } else { + splice.call(data, index, 1); + } + return true; + } + + /** + * Gets the list cache value for `key`. + * + * @private + * @name get + * @memberOf ListCache + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function listCacheGet(key) { + var data = this.__data__, + index = assocIndexOf(data, key); + + return index < 0 ? undefined : data[index][1]; + } + + /** + * Checks if a list cache value for `key` exists. + * + * @private + * @name has + * @memberOf ListCache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function listCacheHas(key) { + return assocIndexOf(this.__data__, key) > -1; + } + + /** + * Sets the list cache `key` to `value`. + * + * @private + * @name set + * @memberOf ListCache + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the list cache instance. + */ + function listCacheSet(key, value) { + var data = this.__data__, + index = assocIndexOf(data, key); + + if (index < 0) { + data.push([key, value]); + } else { + data[index][1] = value; + } + return this; + } + + // Add methods to `ListCache`. + ListCache.prototype.clear = listCacheClear; + ListCache.prototype['delete'] = listCacheDelete; + ListCache.prototype.get = listCacheGet; + ListCache.prototype.has = listCacheHas; + ListCache.prototype.set = listCacheSet; + + /** + * Creates a map cache object to store key-value pairs. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + function MapCache(entries) { + var index = -1, + length = entries ? entries.length : 0; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } + } + + /** + * Removes all key-value entries from the map. + * + * @private + * @name clear + * @memberOf MapCache + */ + function mapCacheClear() { + this.__data__ = { + 'hash': new Hash, + 'map': new (Map || ListCache), + 'string': new Hash + }; + } + + /** + * Removes `key` and its value from the map. + * + * @private + * @name delete + * @memberOf MapCache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function mapCacheDelete(key) { + return getMapData(this, key)['delete'](key); + } + + /** + * Gets the map value for `key`. + * + * @private + * @name get + * @memberOf MapCache + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function mapCacheGet(key) { + return getMapData(this, key).get(key); + } + + /** + * Checks if a map value for `key` exists. + * + * @private + * @name has + * @memberOf MapCache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function mapCacheHas(key) { + return getMapData(this, key).has(key); + } + + /** + * Sets the map `key` to `value`. + * + * @private + * @name set + * @memberOf MapCache + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the map cache instance. + */ + function mapCacheSet(key, value) { + getMapData(this, key).set(key, value); + return this; + } + + // Add methods to `MapCache`. + MapCache.prototype.clear = mapCacheClear; + MapCache.prototype['delete'] = mapCacheDelete; + MapCache.prototype.get = mapCacheGet; + MapCache.prototype.has = mapCacheHas; + MapCache.prototype.set = mapCacheSet; + + /** + * Creates a stack cache object to store key-value pairs. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + function Stack(entries) { + this.__data__ = new ListCache(entries); + } + + /** + * Removes all key-value entries from the stack. + * + * @private + * @name clear + * @memberOf Stack + */ + function stackClear() { + this.__data__ = new ListCache; + } + + /** + * Removes `key` and its value from the stack. + * + * @private + * @name delete + * @memberOf Stack + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function stackDelete(key) { + return this.__data__['delete'](key); + } + + /** + * Gets the stack value for `key`. + * + * @private + * @name get + * @memberOf Stack + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function stackGet(key) { + return this.__data__.get(key); + } + + /** + * Checks if a stack value for `key` exists. + * + * @private + * @name has + * @memberOf Stack + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function stackHas(key) { + return this.__data__.has(key); + } + + /** + * Sets the stack `key` to `value`. + * + * @private + * @name set + * @memberOf Stack + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the stack cache instance. + */ + function stackSet(key, value) { + var cache = this.__data__; + if (cache instanceof ListCache) { + var pairs = cache.__data__; + if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) { + pairs.push([key, value]); + return this; + } + cache = this.__data__ = new MapCache(pairs); + } + cache.set(key, value); + return this; + } + + // Add methods to `Stack`. + Stack.prototype.clear = stackClear; + Stack.prototype['delete'] = stackDelete; + Stack.prototype.get = stackGet; + Stack.prototype.has = stackHas; + Stack.prototype.set = stackSet; + + /** + * Creates an array of the enumerable property names of the array-like `value`. + * + * @private + * @param {*} value The value to query. + * @param {boolean} inherited Specify returning inherited property names. + * @returns {Array} Returns the array of property names. + */ + function arrayLikeKeys(value, inherited) { + // Safari 8.1 makes `arguments.callee` enumerable in strict mode. + // Safari 9 makes `arguments.length` enumerable in strict mode. + var result = (isArray(value) || isArguments(value)) + ? baseTimes(value.length, String) + : []; + + var length = result.length, + skipIndexes = !!length; + + for (var key in value) { + if ((hasOwnProperty.call(value, key)) && + !(skipIndexes && (key == 'length' || isIndex(key, length)))) { + result.push(key); + } + } + return result; + } + + /** + * Assigns `value` to `key` of `object` if the existing value is not equivalent + * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. + * + * @private + * @param {Object} object The object to modify. + * @param {string} key The key of the property to assign. + * @param {*} value The value to assign. + */ + function assignValue(object, key, value) { + var objValue = object[key]; + if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) || + (value === undefined && !(key in object))) { + object[key] = value; + } + } + + /** + * Gets the index at which the `key` is found in `array` of key-value pairs. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} key The key to search for. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function assocIndexOf(array, key) { + var length = array.length; + while (length--) { + if (eq(array[length][0], key)) { + return length; + } + } + return -1; + } + + /** + * The base implementation of `_.assign` without support for multiple sources + * or `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @returns {Object} Returns `object`. + */ + function baseAssign(object, source) { + return object && copyObject(source, keys(source), object); + } + + /** + * The base implementation of `_.clone` and `_.cloneDeep` which tracks + * traversed objects. + * + * @private + * @param {*} value The value to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @param {boolean} [isFull] Specify a clone including symbols. + * @param {Function} [customizer] The function to customize cloning. + * @param {string} [key] The key of `value`. + * @param {Object} [object] The parent object of `value`. + * @param {Object} [stack] Tracks traversed objects and their clone counterparts. + * @returns {*} Returns the cloned value. + */ + function baseClone(value, isDeep, isFull, customizer, key, object, stack) { + var result; + if (customizer) { + result = object ? customizer(value, key, object, stack) : customizer(value); + } + if (result !== undefined) { + return result; + } + if (!isObject(value)) { + return value; + } + var isArr = isArray(value); + if (isArr) { + result = initCloneArray(value); + if (!isDeep) { + return copyArray(value, result); + } + } else { + var tag = getTag(value), + isFunc = tag == funcTag || tag == genTag; + + if (isBuffer(value)) { + return cloneBuffer(value, isDeep); + } + if (tag == objectTag || tag == argsTag || (isFunc && !object)) { + if (isHostObject(value)) { + return object ? value : {}; + } + result = initCloneObject(isFunc ? {} : value); + if (!isDeep) { + return copySymbols(value, baseAssign(result, value)); + } + } else { + if (!cloneableTags[tag]) { + return object ? value : {}; + } + result = initCloneByTag(value, tag, baseClone, isDeep); + } + } + // Check for circular references and return its corresponding clone. + stack || (stack = new Stack); + var stacked = stack.get(value); + if (stacked) { + return stacked; + } + stack.set(value, result); + + if (!isArr) { + var props = isFull ? getAllKeys(value) : keys(value); + } + arrayEach(props || value, function(subValue, key) { + if (props) { + key = subValue; + subValue = value[key]; + } + // Recursively populate clone (susceptible to call stack limits). + assignValue(result, key, baseClone(subValue, isDeep, isFull, customizer, key, value, stack)); + }); + return result; + } + + /** + * The base implementation of `_.create` without support for assigning + * properties to the created object. + * + * @private + * @param {Object} prototype The object to inherit from. + * @returns {Object} Returns the new object. + */ + function baseCreate(proto) { + return isObject(proto) ? objectCreate(proto) : {}; + } + + /** + * The base implementation of `getAllKeys` and `getAllKeysIn` which uses + * `keysFunc` and `symbolsFunc` to get the enumerable property names and + * symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Function} keysFunc The function to get the keys of `object`. + * @param {Function} symbolsFunc The function to get the symbols of `object`. + * @returns {Array} Returns the array of property names and symbols. + */ + function baseGetAllKeys(object, keysFunc, symbolsFunc) { + var result = keysFunc(object); + return isArray(object) ? result : arrayPush(result, symbolsFunc(object)); + } + + /** + * The base implementation of `getTag`. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the `toStringTag`. + */ + function baseGetTag(value) { + return objectToString.call(value); + } + + /** + * The base implementation of `_.isNative` without bad shim checks. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a native function, + * else `false`. + */ + function baseIsNative(value) { + if (!isObject(value) || isMasked(value)) { + return false; + } + var pattern = (isFunction(value) || isHostObject(value)) ? reIsNative : reIsHostCtor; + return pattern.test(toSource(value)); + } + + /** + * The base implementation of `_.keys` which doesn't treat sparse arrays as dense. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ + function baseKeys(object) { + if (!isPrototype(object)) { + return nativeKeys(object); + } + var result = []; + for (var key in Object(object)) { + if (hasOwnProperty.call(object, key) && key != 'constructor') { + result.push(key); + } + } + return result; + } + + /** + * Creates a clone of `buffer`. + * + * @private + * @param {Buffer} buffer The buffer to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Buffer} Returns the cloned buffer. + */ + function cloneBuffer(buffer, isDeep) { + if (isDeep) { + return buffer.slice(); + } + var result = new buffer.constructor(buffer.length); + buffer.copy(result); + return result; + } + + /** + * Creates a clone of `arrayBuffer`. + * + * @private + * @param {ArrayBuffer} arrayBuffer The array buffer to clone. + * @returns {ArrayBuffer} Returns the cloned array buffer. + */ + function cloneArrayBuffer(arrayBuffer) { + var result = new arrayBuffer.constructor(arrayBuffer.byteLength); + new Uint8Array(result).set(new Uint8Array(arrayBuffer)); + return result; + } + + /** + * Creates a clone of `dataView`. + * + * @private + * @param {Object} dataView The data view to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned data view. + */ + function cloneDataView(dataView, isDeep) { + var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer; + return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength); + } + + /** + * Creates a clone of `map`. + * + * @private + * @param {Object} map The map to clone. + * @param {Function} cloneFunc The function to clone values. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned map. + */ + function cloneMap(map, isDeep, cloneFunc) { + var array = isDeep ? cloneFunc(mapToArray(map), true) : mapToArray(map); + return arrayReduce(array, addMapEntry, new map.constructor); + } + + /** + * Creates a clone of `regexp`. + * + * @private + * @param {Object} regexp The regexp to clone. + * @returns {Object} Returns the cloned regexp. + */ + function cloneRegExp(regexp) { + var result = new regexp.constructor(regexp.source, reFlags.exec(regexp)); + result.lastIndex = regexp.lastIndex; + return result; + } + + /** + * Creates a clone of `set`. + * + * @private + * @param {Object} set The set to clone. + * @param {Function} cloneFunc The function to clone values. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned set. + */ + function cloneSet(set, isDeep, cloneFunc) { + var array = isDeep ? cloneFunc(setToArray(set), true) : setToArray(set); + return arrayReduce(array, addSetEntry, new set.constructor); + } + + /** + * Creates a clone of the `symbol` object. + * + * @private + * @param {Object} symbol The symbol object to clone. + * @returns {Object} Returns the cloned symbol object. + */ + function cloneSymbol(symbol) { + return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {}; + } + + /** + * Creates a clone of `typedArray`. + * + * @private + * @param {Object} typedArray The typed array to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned typed array. + */ + function cloneTypedArray(typedArray, isDeep) { + var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer; + return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length); + } + + /** + * Copies the values of `source` to `array`. + * + * @private + * @param {Array} source The array to copy values from. + * @param {Array} [array=[]] The array to copy values to. + * @returns {Array} Returns `array`. + */ + function copyArray(source, array) { + var index = -1, + length = source.length; + + array || (array = Array(length)); + while (++index < length) { + array[index] = source[index]; + } + return array; + } + + /** + * Copies properties of `source` to `object`. + * + * @private + * @param {Object} source The object to copy properties from. + * @param {Array} props The property identifiers to copy. + * @param {Object} [object={}] The object to copy properties to. + * @param {Function} [customizer] The function to customize copied values. + * @returns {Object} Returns `object`. + */ + function copyObject(source, props, object, customizer) { + object || (object = {}); + + var index = -1, + length = props.length; + + while (++index < length) { + var key = props[index]; + + var newValue = undefined; + + assignValue(object, key, newValue === undefined ? source[key] : newValue); + } + return object; + } + + /** + * Copies own symbol properties of `source` to `object`. + * + * @private + * @param {Object} source The object to copy symbols from. + * @param {Object} [object={}] The object to copy symbols to. + * @returns {Object} Returns `object`. + */ + function copySymbols(source, object) { + return copyObject(source, getSymbols(source), object); + } + + /** + * Creates an array of own enumerable property names and symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names and symbols. + */ + function getAllKeys(object) { + return baseGetAllKeys(object, keys, getSymbols); + } + + /** + * Gets the data for `map`. + * + * @private + * @param {Object} map The map to query. + * @param {string} key The reference key. + * @returns {*} Returns the map data. + */ + function getMapData(map, key) { + var data = map.__data__; + return isKeyable(key) + ? data[typeof key == 'string' ? 'string' : 'hash'] + : data.map; + } + + /** + * Gets the native function at `key` of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {string} key The key of the method to get. + * @returns {*} Returns the function if it's native, else `undefined`. + */ + function getNative(object, key) { + var value = getValue(object, key); + return baseIsNative(value) ? value : undefined; + } + + /** + * Creates an array of the own enumerable symbol properties of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. + */ + var getSymbols = nativeGetSymbols ? overArg(nativeGetSymbols, Object) : stubArray; + + /** + * Gets the `toStringTag` of `value`. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the `toStringTag`. + */ + var getTag = baseGetTag; + + // Fallback for data views, maps, sets, and weak maps in IE 11, + // for data views in Edge < 14, and promises in Node.js. + if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) || + (Map && getTag(new Map) != mapTag) || + (Promise && getTag(Promise.resolve()) != promiseTag) || + (Set && getTag(new Set) != setTag) || + (WeakMap && getTag(new WeakMap) != weakMapTag)) { + getTag = function(value) { + var result = objectToString.call(value), + Ctor = result == objectTag ? value.constructor : undefined, + ctorString = Ctor ? toSource(Ctor) : undefined; + + if (ctorString) { + switch (ctorString) { + case dataViewCtorString: return dataViewTag; + case mapCtorString: return mapTag; + case promiseCtorString: return promiseTag; + case setCtorString: return setTag; + case weakMapCtorString: return weakMapTag; + } + } + return result; + }; + } + + /** + * Initializes an array clone. + * + * @private + * @param {Array} array The array to clone. + * @returns {Array} Returns the initialized clone. + */ + function initCloneArray(array) { + var length = array.length, + result = array.constructor(length); + + // Add properties assigned by `RegExp#exec`. + if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) { + result.index = array.index; + result.input = array.input; + } + return result; + } + + /** + * Initializes an object clone. + * + * @private + * @param {Object} object The object to clone. + * @returns {Object} Returns the initialized clone. + */ + function initCloneObject(object) { + return (typeof object.constructor == 'function' && !isPrototype(object)) + ? baseCreate(getPrototype(object)) + : {}; + } + + /** + * Initializes an object clone based on its `toStringTag`. + * + * **Note:** This function only supports cloning values with tags of + * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. + * + * @private + * @param {Object} object The object to clone. + * @param {string} tag The `toStringTag` of the object to clone. + * @param {Function} cloneFunc The function to clone values. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the initialized clone. + */ + function initCloneByTag(object, tag, cloneFunc, isDeep) { + var Ctor = object.constructor; + switch (tag) { + case arrayBufferTag: + return cloneArrayBuffer(object); + + case boolTag: + case dateTag: + return new Ctor(+object); + + case dataViewTag: + return cloneDataView(object, isDeep); + + case float32Tag: case float64Tag: + case int8Tag: case int16Tag: case int32Tag: + case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag: + return cloneTypedArray(object, isDeep); + + case mapTag: + return cloneMap(object, isDeep, cloneFunc); + + case numberTag: + case stringTag: + return new Ctor(object); + + case regexpTag: + return cloneRegExp(object); + + case setTag: + return cloneSet(object, isDeep, cloneFunc); + + case symbolTag: + return cloneSymbol(object); + } + } + + /** + * Checks if `value` is a valid array-like index. + * + * @private + * @param {*} value The value to check. + * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. + * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. + */ + function isIndex(value, length) { + length = length == null ? MAX_SAFE_INTEGER : length; + return !!length && + (typeof value == 'number' || reIsUint.test(value)) && + (value > -1 && value % 1 == 0 && value < length); + } + + /** + * Checks if `value` is suitable for use as unique object key. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is suitable, else `false`. + */ + function isKeyable(value) { + var type = typeof value; + return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean') + ? (value !== '__proto__') + : (value === null); + } + + /** + * Checks if `func` has its source masked. + * + * @private + * @param {Function} func The function to check. + * @returns {boolean} Returns `true` if `func` is masked, else `false`. + */ + function isMasked(func) { + return !!maskSrcKey && (maskSrcKey in func); + } + + /** + * Checks if `value` is likely a prototype object. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a prototype, else `false`. + */ + function isPrototype(value) { + var Ctor = value && value.constructor, + proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto; + + return value === proto; + } + + /** + * Converts `func` to its source code. + * + * @private + * @param {Function} func The function to process. + * @returns {string} Returns the source code. + */ + function toSource(func) { + if (func != null) { + try { + return funcToString.call(func); + } catch (e) {} + try { + return (func + ''); + } catch (e) {} + } + return ''; + } + + /** + * This method is like `_.clone` except that it recursively clones `value`. + * + * @static + * @memberOf _ + * @since 1.0.0 + * @category Lang + * @param {*} value The value to recursively clone. + * @returns {*} Returns the deep cloned value. + * @see _.clone + * @example + * + * var objects = [{ 'a': 1 }, { 'b': 2 }]; + * + * var deep = _.cloneDeep(objects); + * console.log(deep[0] === objects[0]); + * // => false + */ + function cloneDeep(value) { + return baseClone(value, true, true); + } + + /** + * Performs a + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * comparison between two values to determine if they are equivalent. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'a': 1 }; + * var other = { 'a': 1 }; + * + * _.eq(object, object); + * // => true + * + * _.eq(object, other); + * // => false + * + * _.eq('a', 'a'); + * // => true + * + * _.eq('a', Object('a')); + * // => false + * + * _.eq(NaN, NaN); + * // => true + */ + function eq(value, other) { + return value === other || (value !== value && other !== other); + } + + /** + * Checks if `value` is likely an `arguments` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an `arguments` object, + * else `false`. + * @example + * + * _.isArguments(function() { return arguments; }()); + * // => true + * + * _.isArguments([1, 2, 3]); + * // => false + */ + function isArguments(value) { + // Safari 8.1 makes `arguments.callee` enumerable in strict mode. + return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') && + (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag); + } + + /** + * Checks if `value` is classified as an `Array` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array, else `false`. + * @example + * + * _.isArray([1, 2, 3]); + * // => true + * + * _.isArray(document.body.children); + * // => false + * + * _.isArray('abc'); + * // => false + * + * _.isArray(_.noop); + * // => false + */ + var isArray = Array.isArray; + + /** + * Checks if `value` is array-like. A value is considered array-like if it's + * not a function and has a `value.length` that's an integer greater than or + * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is array-like, else `false`. + * @example + * + * _.isArrayLike([1, 2, 3]); + * // => true + * + * _.isArrayLike(document.body.children); + * // => true + * + * _.isArrayLike('abc'); + * // => true + * + * _.isArrayLike(_.noop); + * // => false + */ + function isArrayLike(value) { + return value != null && isLength(value.length) && !isFunction(value); + } + + /** + * This method is like `_.isArrayLike` except that it also checks if `value` + * is an object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array-like object, + * else `false`. + * @example + * + * _.isArrayLikeObject([1, 2, 3]); + * // => true + * + * _.isArrayLikeObject(document.body.children); + * // => true + * + * _.isArrayLikeObject('abc'); + * // => false + * + * _.isArrayLikeObject(_.noop); + * // => false + */ + function isArrayLikeObject(value) { + return isObjectLike(value) && isArrayLike(value); + } + + /** + * Checks if `value` is a buffer. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a buffer, else `false`. + * @example + * + * _.isBuffer(new Buffer(2)); + * // => true + * + * _.isBuffer(new Uint8Array(2)); + * // => false + */ + var isBuffer = nativeIsBuffer || stubFalse; + + /** + * Checks if `value` is classified as a `Function` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a function, else `false`. + * @example + * + * _.isFunction(_); + * // => true + * + * _.isFunction(/abc/); + * // => false + */ + function isFunction(value) { + // The use of `Object#toString` avoids issues with the `typeof` operator + // in Safari 8-9 which returns 'object' for typed array and other constructors. + var tag = isObject(value) ? objectToString.call(value) : ''; + return tag == funcTag || tag == genTag; + } + + /** + * Checks if `value` is a valid array-like length. + * + * **Note:** This method is loosely based on + * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. + * @example + * + * _.isLength(3); + * // => true + * + * _.isLength(Number.MIN_VALUE); + * // => false + * + * _.isLength(Infinity); + * // => false + * + * _.isLength('3'); + * // => false + */ + function isLength(value) { + return typeof value == 'number' && + value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; + } + + /** + * Checks if `value` is the + * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) + * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(_.noop); + * // => true + * + * _.isObject(null); + * // => false + */ + function isObject(value) { + var type = typeof value; + return !!value && (type == 'object' || type == 'function'); + } + + /** + * Checks if `value` is object-like. A value is object-like if it's not `null` + * and has a `typeof` result of "object". + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @example + * + * _.isObjectLike({}); + * // => true + * + * _.isObjectLike([1, 2, 3]); + * // => true + * + * _.isObjectLike(_.noop); + * // => false + * + * _.isObjectLike(null); + * // => false + */ + function isObjectLike(value) { + return !!value && typeof value == 'object'; + } + + /** + * Creates an array of the own enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. See the + * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) + * for more details. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keys(new Foo); + * // => ['a', 'b'] (iteration order is not guaranteed) + * + * _.keys('hi'); + * // => ['0', '1'] + */ + function keys(object) { + return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object); + } + + /** + * This method returns a new empty array. + * + * @static + * @memberOf _ + * @since 4.13.0 + * @category Util + * @returns {Array} Returns the new empty array. + * @example + * + * var arrays = _.times(2, _.stubArray); + * + * console.log(arrays); + * // => [[], []] + * + * console.log(arrays[0] === arrays[1]); + * // => false + */ + function stubArray() { + return []; + } + + /** + * This method returns `false`. + * + * @static + * @memberOf _ + * @since 4.13.0 + * @category Util + * @returns {boolean} Returns `false`. + * @example + * + * _.times(2, _.stubFalse); + * // => [false, false] + */ + function stubFalse() { + return false; + } + + module.exports = cloneDeep; + } (lodash_clonedeep, lodash_clonedeep.exports)); + + var lodash_clonedeepExports = lodash_clonedeep.exports; + var cloneDeep = /*@__PURE__*/getDefaultExportFromCjs$1(lodash_clonedeepExports); + + function applyContextDelta(context, delta, logger) { + try { + if (logger?.canPublish("trace")) { + logger?.trace(`applying context delta ${JSON.stringify(delta)} on context ${JSON.stringify(context)}`); + } + if (!delta) { + return context; + } + if (delta.reset) { + context = { ...delta.reset }; + return context; + } + context = deepClone(context, undefined); + if (delta.commands) { + for (const command of delta.commands) { + if (command.type === "remove") { + deletePath(context, command.path); + } + else if (command.type === "set") { + setValueToPath(context, command.value, command.path); + } + } + return context; + } + const added = delta.added; + const updated = delta.updated; + const removed = delta.removed; + if (added) { + Object.keys(added).forEach((key) => { + context[key] = added[key]; + }); + } + if (updated) { + Object.keys(updated).forEach((key) => { + mergeObjectsProperties(key, context, updated); + }); + } + if (removed) { + removed.forEach((key) => { + delete context[key]; + }); + } + return context; + } + catch (e) { + logger?.error(`error applying context delta ${JSON.stringify(delta)} on context ${JSON.stringify(context)}`, e); + return context; + } + } + function deepClone(obj, hash) { + return cloneDeep(obj); + } + const mergeObjectsProperties = (key, what, withWhat) => { + const right = withWhat[key]; + if (right === undefined) { + return what; + } + const left = what[key]; + if (!left || !right) { + what[key] = right; + return what; + } + if (typeof left === "string" || + typeof left === "number" || + typeof left === "boolean" || + typeof right === "string" || + typeof right === "number" || + typeof right === "boolean" || + Array.isArray(left) || + Array.isArray(right)) { + what[key] = right; + return what; + } + what[key] = Object.assign({}, left, right); + return what; + }; + function deepEqual(x, y) { + if (x === y) { + return true; + } + if (!(x instanceof Object) || !(y instanceof Object)) { + return false; + } + if (x.constructor !== y.constructor) { + return false; + } + for (const p in x) { + if (!x.hasOwnProperty(p)) { + continue; + } + if (!y.hasOwnProperty(p)) { + return false; + } + if (x[p] === y[p]) { + continue; + } + if (typeof (x[p]) !== "object") { + return false; + } + if (!deepEqual(x[p], y[p])) { + return false; + } + } + for (const p in y) { + if (y.hasOwnProperty(p) && !x.hasOwnProperty(p)) { + return false; + } + } + return true; + } + function setValueToPath(obj, value, path) { + const pathArr = path.split("."); + let i; + for (i = 0; i < pathArr.length - 1; i++) { + if (!obj[pathArr[i]]) { + obj[pathArr[i]] = {}; + } + if (typeof obj[pathArr[i]] !== "object") { + obj[pathArr[i]] = {}; + } + obj = obj[pathArr[i]]; + } + obj[pathArr[i]] = value; + } + function isSubset(superObj, subObj) { + return Object.keys(subObj).every((ele) => { + if (typeof subObj[ele] === "object") { + return isSubset(superObj?.[ele] || {}, subObj[ele] || {}); + } + return subObj[ele] === superObj?.[ele]; + }); + } + function deletePath(obj, path) { + const pathArr = path.split("."); + let i; + for (i = 0; i < pathArr.length - 1; i++) { + if (!obj[pathArr[i]]) { + return; + } + obj = obj[pathArr[i]]; + } + delete obj[pathArr[i]]; + } + + let GW3Bridge$1 = class GW3Bridge { + _logger; + _connection; + _trackAllContexts; + _reAnnounceKnownContexts; + _gw3Session; + _contextNameToData = {}; + _gw3Subscriptions = []; + _nextCallbackSubscriptionNumber = 0; + _creationPromises = {}; + _contextNameToId = {}; + _contextIdToName = {}; + _protocolVersion = undefined; + _contextsTempCache = {}; + _contextsSubscriptionsCache = []; + _systemContextsSubKey; + get protocolVersion() { + if (!this._protocolVersion) { + const contextsDomainInfo = this._connection.availableDomains.find((d) => d.uri === "context"); + this._protocolVersion = contextsDomainInfo?.version ?? 1; + } + return this._protocolVersion; + } + get setPathSupported() { + return this.protocolVersion >= 2; + } + constructor(config) { + this._connection = config.connection; + this._logger = config.logger; + this._trackAllContexts = config.trackAllContexts; + this._reAnnounceKnownContexts = config.reAnnounceKnownContexts; + this._gw3Session = this._connection.domain("global", [ + GW_MESSAGE_CONTEXT_CREATED, + GW_MESSAGE_SUBSCRIBED_CONTEXT, + GW_MESSAGE_CONTEXT_DESTROYED, + GW_MESSAGE_CONTEXT_UPDATED, + ]); + this._gw3Session.disconnected(this.resetState.bind(this)); + this._gw3Session.onJoined((wasReconnect) => { + if (!wasReconnect) { + return; + } + if (!this._reAnnounceKnownContexts) { + return this._connection.setLibReAnnounced({ name: "contexts" }); + } + this.reInitiateState().then(() => this._connection.setLibReAnnounced({ name: "contexts" })); + }); + this.subscribeToContextCreatedMessages(); + this.subscribeToContextUpdatedMessages(); + this.subscribeToContextDestroyedMessages(); + this._connection.replayer?.drain(ContextMessageReplaySpec.name, (message) => { + const type = message.type; + if (!type) { + return; + } + if (type === GW_MESSAGE_CONTEXT_CREATED || + type === GW_MESSAGE_CONTEXT_ADDED || + type === GW_MESSAGE_ACTIVITY_CREATED) { + this.handleContextCreatedMessage(message); + } + else if (type === GW_MESSAGE_SUBSCRIBED_CONTEXT || + type === GW_MESSAGE_CONTEXT_UPDATED || + type === GW_MESSAGE_JOINED_ACTIVITY) { + this.handleContextUpdatedMessage(message); + } + else if (type === GW_MESSAGE_CONTEXT_DESTROYED || + type === GW_MESSAGE_ACTIVITY_DESTROYED) { + this.handleContextDestroyedMessage(message); + } + }); + } + dispose() { + for (const sub of this._gw3Subscriptions) { + this._connection.off(sub); + } + this._gw3Subscriptions.length = 0; + for (const contextName in this._contextNameToData) { + if (this._contextNameToId.hasOwnProperty(contextName)) { + delete this._contextNameToData[contextName]; + } + } + } + createContext(name, data) { + if (name in this._creationPromises) { + return this._creationPromises[name]; + } + this._creationPromises[name] = + this._gw3Session + .send({ + type: GW_MESSAGE_CREATE_CONTEXT, + domain: "global", + name, + data, + lifetime: "retained", + }) + .then((createContextMsg) => { + this._contextNameToId[name] = createContextMsg.context_id; + this._contextIdToName[createContextMsg.context_id] = name; + const contextData = this._contextNameToData[name] || new GW3ContextData(createContextMsg.context_id, name, true, undefined); + contextData.isAnnounced = true; + contextData.name = name; + contextData.contextId = createContextMsg.context_id; + contextData.context = createContextMsg.data || deepClone(data); + contextData.hasReceivedSnapshot = true; + this._contextNameToData[name] = contextData; + delete this._creationPromises[name]; + return createContextMsg.context_id; + }); + return this._creationPromises[name]; + } + all() { + return Object.keys(this._contextNameToData) + .filter((name) => this._contextNameToData[name].isAnnounced); + } + async update(name, delta) { + if (delta) { + delta = deepClone(delta); + } + if (name in this._creationPromises) { + await this._creationPromises[name]; + } + const contextData = this._contextNameToData[name]; + if (!contextData || !contextData.isAnnounced) { + return this.createContext(name, delta); + } + let currentContext = contextData.context; + if (!contextData.hasCallbacks()) { + currentContext = await this.get(contextData.name); + } + const calculatedDelta = this.setPathSupported ? + this.calculateContextDeltaV2(currentContext, delta) : + this.calculateContextDeltaV1(currentContext, delta); + if (!Object.keys(calculatedDelta.added).length + && !Object.keys(calculatedDelta.updated).length + && !calculatedDelta.removed.length + && !calculatedDelta.commands?.length) { + return Promise.resolve(); + } + return this._gw3Session + .send({ + type: GW_MESSAGE_UPDATE_CONTEXT, + domain: "global", + context_id: contextData.contextId, + delta: calculatedDelta, + }, {}, { skipPeerId: false }) + .then((gwResponse) => { + this.handleUpdated(contextData, calculatedDelta, { + updaterId: gwResponse.peer_id + }); + }); + } + async set(name, data) { + if (data) { + data = deepClone(data); + } + if (name in this._creationPromises) { + await this._creationPromises[name]; + } + const contextData = this._contextNameToData[name]; + if (!contextData || !contextData.isAnnounced) { + return this.createContext(name, data); + } + return this._gw3Session + .send({ + type: GW_MESSAGE_UPDATE_CONTEXT, + domain: "global", + context_id: contextData.contextId, + delta: { reset: data }, + }, {}, { skipPeerId: false }) + .then((gwResponse) => { + this.handleUpdated(contextData, { + reset: data, + added: {}, + removed: [], + updated: {} + }, { + updaterId: gwResponse.peer_id + }); + }); + } + setPath(name, path, value) { + if (!this.setPathSupported) { + return Promise.reject("glue.contexts.setPath operation is not supported, use Glue42 3.10 or later"); + } + return this.setPaths(name, [{ path, value }]); + } + async setPaths(name, pathValues) { + if (!this.setPathSupported) { + return Promise.reject("glue.contexts.setPaths operation is not supported, use Glue42 3.10 or later"); + } + if (pathValues) { + pathValues = deepClone(pathValues); + } + if (name in this._creationPromises) { + await this._creationPromises[name]; + } + const contextData = this._contextNameToData[name]; + if (!contextData || !contextData.isAnnounced) { + const obj = {}; + for (const pathValue of pathValues) { + setValueToPath(obj, pathValue.value, pathValue.path); + } + return this.createContext(name, obj); + } + const commands = []; + for (const pathValue of pathValues) { + if (pathValue.value === null) { + commands.push({ type: "remove", path: pathValue.path }); + } + else { + commands.push({ type: "set", path: pathValue.path, value: pathValue.value }); + } + } + return this._gw3Session + .send({ + type: GW_MESSAGE_UPDATE_CONTEXT, + domain: "global", + context_id: contextData.contextId, + delta: { commands } + }, {}, { skipPeerId: false }) + .then((gwResponse) => { + this.handleUpdated(contextData, { + added: {}, + removed: [], + updated: {}, + commands + }, { + updaterId: gwResponse.peer_id + }); + }); + } + async get(name) { + if (name in this._creationPromises) { + await this._creationPromises[name]; + } + const contextData = this._contextNameToData[name]; + if (!contextData || !contextData.isAnnounced) { + return Promise.resolve({}); + } + if (contextData && (!contextData.hasCallbacks() || !contextData.hasReceivedSnapshot)) { + return new Promise((resolve) => { + this.subscribe(name, (data, _d, _r, un) => { + this.unsubscribe(un); + resolve(data); + }); + }); + } + const context = contextData?.context ?? {}; + return Promise.resolve(deepClone(context)); + } + async subscribe(name, callback, subscriptionKey) { + if (name in this._creationPromises) { + await this._creationPromises[name]; + } + const thisCallbackSubscriptionNumber = typeof subscriptionKey === "undefined" ? this._nextCallbackSubscriptionNumber : subscriptionKey; + if (typeof subscriptionKey === "undefined") { + this._nextCallbackSubscriptionNumber += 1; + } + if (this._contextsSubscriptionsCache.every((subscription) => subscription.subKey !== this._nextCallbackSubscriptionNumber)) { + this._contextsSubscriptionsCache.push({ contextName: name, subKey: thisCallbackSubscriptionNumber, callback }); + } + let contextData = this._contextNameToData[name]; + if (!contextData || + !contextData.isAnnounced) { + contextData = contextData || new GW3ContextData(undefined, name, false, undefined); + this._contextNameToData[name] = contextData; + contextData.updateCallbacks[thisCallbackSubscriptionNumber] = callback; + return Promise.resolve(thisCallbackSubscriptionNumber); + } + const hadCallbacks = contextData.hasCallbacks(); + contextData.updateCallbacks[thisCallbackSubscriptionNumber] = callback; + if (!hadCallbacks) { + if (!contextData.joinedActivity) { + if (contextData.context && contextData.sentExplicitSubscription) { + if (contextData.hasReceivedSnapshot) { + const clone = deepClone(contextData.context); + callback(clone, clone, [], thisCallbackSubscriptionNumber); + } + return Promise.resolve(thisCallbackSubscriptionNumber); + } + return this.sendSubscribe(contextData) + .then(() => thisCallbackSubscriptionNumber); + } + else { + if (contextData.hasReceivedSnapshot) { + const clone = deepClone(contextData.context); + callback(clone, clone, [], thisCallbackSubscriptionNumber); + } + return Promise.resolve(thisCallbackSubscriptionNumber); + } + } + else { + if (contextData.hasReceivedSnapshot) { + const clone = deepClone(contextData.context); + callback(clone, clone, [], thisCallbackSubscriptionNumber); + } + return Promise.resolve(thisCallbackSubscriptionNumber); + } + } + unsubscribe(subscriptionKey) { + this._contextsSubscriptionsCache = this._contextsSubscriptionsCache.filter((subscription) => subscription.subKey !== subscriptionKey); + for (const name of Object.keys(this._contextNameToData)) { + const contextData = this._contextNameToData[name]; + if (!contextData) { + return; + } + const hadCallbacks = contextData.hasCallbacks(); + delete contextData.updateCallbacks[subscriptionKey]; + if (contextData.isAnnounced && + hadCallbacks && + !contextData.hasCallbacks() && + contextData.sentExplicitSubscription) { + this.sendUnsubscribe(contextData).catch(() => { }); + } + if (!contextData.isAnnounced && + !contextData.hasCallbacks()) { + delete this._contextNameToData[name]; + } + } + } + async destroy(name) { + if (name in this._creationPromises) { + await this._creationPromises[name]; + } + const contextData = this._contextNameToData[name]; + if (!contextData) { + return Promise.reject(`context with ${name} does not exist`); + } + return this._gw3Session + .send({ + type: GW_MESSAGE_DESTROY_CONTEXT, + domain: "global", + context_id: contextData.contextId, + }).then((_) => undefined); + } + handleUpdated(contextData, delta, extraData) { + const oldContext = contextData.context; + contextData.context = applyContextDelta(contextData.context, delta, this._logger); + contextData.hasReceivedSnapshot = true; + if (this._contextNameToData[contextData.name] === contextData && + !deepEqual(oldContext, contextData.context)) { + this.invokeUpdateCallbacks(contextData, delta, extraData); + } + } + subscribeToContextCreatedMessages() { + const createdMessageTypes = [ + GW_MESSAGE_CONTEXT_ADDED, + GW_MESSAGE_CONTEXT_CREATED, + GW_MESSAGE_ACTIVITY_CREATED, + ]; + for (const createdMessageType of createdMessageTypes) { + const sub = this._connection.on(createdMessageType, this.handleContextCreatedMessage.bind(this)); + this._gw3Subscriptions.push(sub); + } + } + handleContextCreatedMessage(contextCreatedMsg) { + const createdMessageType = contextCreatedMsg.type; + if (createdMessageType === GW_MESSAGE_ACTIVITY_CREATED) { + this._contextNameToId[contextCreatedMsg.activity_id] = contextCreatedMsg.context_id; + this._contextIdToName[contextCreatedMsg.context_id] = contextCreatedMsg.activity_id; + } + else if (createdMessageType === GW_MESSAGE_CONTEXT_ADDED) { + this._contextNameToId[contextCreatedMsg.name] = contextCreatedMsg.context_id; + this._contextIdToName[contextCreatedMsg.context_id] = contextCreatedMsg.name; + } + else ; + const name = this._contextIdToName[contextCreatedMsg.context_id]; + if (!name) { + throw new Error("Received created event for context with unknown name: " + contextCreatedMsg.context_id); + } + if (!this._contextNameToId[name]) { + throw new Error("Received created event for context with unknown id: " + contextCreatedMsg.context_id); + } + let contextData = this._contextNameToData[name]; + if (contextData) { + if (contextData.isAnnounced) { + return; + } + else { + if (!contextData.hasCallbacks()) { + throw new Error("Assertion failure: contextData.hasCallbacks()"); + } + contextData.isAnnounced = true; + contextData.contextId = contextCreatedMsg.context_id; + contextData.activityId = contextCreatedMsg.activity_id; + if (!contextData.sentExplicitSubscription) { + this.sendSubscribe(contextData); + } + } + } + else { + this._contextNameToData[name] = contextData = + new GW3ContextData(contextCreatedMsg.context_id, name, true, contextCreatedMsg.activity_id); + if (this._trackAllContexts) { + this.subscribe(name, () => { }).then((subKey) => this._systemContextsSubKey = subKey); + } + } + } + subscribeToContextUpdatedMessages() { + const updatedMessageTypes = [ + GW_MESSAGE_CONTEXT_UPDATED, + GW_MESSAGE_SUBSCRIBED_CONTEXT, + GW_MESSAGE_JOINED_ACTIVITY, + ]; + for (const updatedMessageType of updatedMessageTypes) { + const sub = this._connection.on(updatedMessageType, this.handleContextUpdatedMessage.bind(this)); + this._gw3Subscriptions.push(sub); + } + } + handleContextUpdatedMessage(contextUpdatedMsg) { + const updatedMessageType = contextUpdatedMsg.type; + const contextId = contextUpdatedMsg.context_id; + let contextData = this._contextNameToData[this._contextIdToName[contextId]]; + const justSeen = !contextData || !contextData.isAnnounced; + if (updatedMessageType === GW_MESSAGE_JOINED_ACTIVITY) { + if (!contextData) { + contextData = + this._contextNameToData[contextUpdatedMsg.activity_id] || + new GW3ContextData(contextId, contextUpdatedMsg.activity_id, true, contextUpdatedMsg.activity_id); + } + this._contextNameToData[contextUpdatedMsg.activity_id] = contextData; + this._contextIdToName[contextId] = contextUpdatedMsg.activity_id; + this._contextNameToId[contextUpdatedMsg.activity_id] = contextId; + contextData.contextId = contextId; + contextData.isAnnounced = true; + contextData.activityId = contextUpdatedMsg.activity_id; + contextData.joinedActivity = true; + } + else { + if (!contextData || !contextData.isAnnounced) { + if (updatedMessageType === GW_MESSAGE_SUBSCRIBED_CONTEXT) { + contextData = contextData || new GW3ContextData(contextId, contextUpdatedMsg.name, true, undefined); + contextData.sentExplicitSubscription = true; + this._contextNameToData[contextUpdatedMsg.name] = contextData; + this._contextIdToName[contextId] = contextUpdatedMsg.name; + this._contextNameToId[contextUpdatedMsg.name] = contextId; + } + else { + this._logger.error(`Received 'update' for unknown context: ${contextId}`); + } + return; + } + } + const oldContext = contextData.context; + contextData.hasReceivedSnapshot = true; + if (updatedMessageType === GW_MESSAGE_SUBSCRIBED_CONTEXT) { + contextData.context = contextUpdatedMsg.data || {}; + } + else if (updatedMessageType === GW_MESSAGE_JOINED_ACTIVITY) { + contextData.context = contextUpdatedMsg.context_snapshot || {}; + } + else if (updatedMessageType === GW_MESSAGE_CONTEXT_UPDATED) { + contextData.context = applyContextDelta(contextData.context, contextUpdatedMsg.delta, this._logger); + } + else { + throw new Error("Unrecognized context update message " + updatedMessageType); + } + if (justSeen || + !deepEqual(contextData.context, oldContext) || + updatedMessageType === GW_MESSAGE_SUBSCRIBED_CONTEXT) { + this.invokeUpdateCallbacks(contextData, contextUpdatedMsg.delta, { updaterId: contextUpdatedMsg.updater_id }); + } + } + invokeUpdateCallbacks(contextData, delta, extraData) { + delta = delta || { added: {}, updated: {}, reset: {}, removed: [] }; + if (delta.commands) { + delta.added = delta.updated = delta.reset = {}; + delta.removed = []; + for (const command of delta.commands) { + if (command.type === "remove") { + if (command.path.indexOf(".") === -1) { + delta.removed.push(command.path); + } + setValueToPath(delta.updated, null, command.path); + } + else if (command.type === "set") { + setValueToPath(delta.updated, command.value, command.path); + } + } + } + for (const updateCallbackIndex in contextData.updateCallbacks) { + if (contextData.updateCallbacks.hasOwnProperty(updateCallbackIndex)) { + try { + const updateCallback = contextData.updateCallbacks[updateCallbackIndex]; + updateCallback(deepClone(contextData.context), deepClone(Object.assign({}, delta.added || {}, delta.updated || {}, delta.reset || {})), delta.removed, parseInt(updateCallbackIndex, 10), extraData); + } + catch (err) { + this._logger.debug("callback error: " + JSON.stringify(err)); + } + } + } + } + subscribeToContextDestroyedMessages() { + const destroyedMessageTypes = [ + GW_MESSAGE_CONTEXT_DESTROYED, + GW_MESSAGE_ACTIVITY_DESTROYED, + ]; + for (const destroyedMessageType of destroyedMessageTypes) { + const sub = this._connection.on(destroyedMessageType, this.handleContextDestroyedMessage.bind(this)); + this._gw3Subscriptions.push(sub); + } + } + handleContextDestroyedMessage(destroyedMsg) { + const destroyedMessageType = destroyedMsg.type; + let contextId; + let name; + if (destroyedMessageType === GW_MESSAGE_ACTIVITY_DESTROYED) { + name = destroyedMsg.activity_id; + contextId = this._contextNameToId[name]; + if (!contextId) { + this._logger.error(`Received 'destroyed' for unknown activity: ${destroyedMsg.activity_id}`); + return; + } + } + else { + contextId = destroyedMsg.context_id; + name = this._contextIdToName[contextId]; + if (!name) { + this._logger.error(`Received 'destroyed' for unknown context: ${destroyedMsg.context_id}`); + return; + } + } + delete this._contextIdToName[contextId]; + delete this._contextNameToId[name]; + const contextData = this._contextNameToData[name]; + delete this._contextNameToData[name]; + if (!contextData || !contextData.isAnnounced) { + this._logger.error(`Received 'destroyed' for unknown context: ${contextId}`); + return; + } + } + sendSubscribe(contextData) { + contextData.sentExplicitSubscription = true; + return this._gw3Session + .send({ + type: GW_MESSAGE_SUBSCRIBE_CONTEXT, + domain: "global", + context_id: contextData.contextId, + }).then((_) => undefined); + } + sendUnsubscribe(contextData) { + contextData.sentExplicitSubscription = false; + return this._gw3Session + .send({ + type: GW_MESSAGE_UNSUBSCRIBE_CONTEXT, + domain: "global", + context_id: contextData.contextId, + }).then((_) => undefined); + } + calculateContextDeltaV1(from, to) { + const delta = { added: {}, updated: {}, removed: [], reset: undefined }; + if (from) { + for (const x of Object.keys(from)) { + if (Object.keys(to).indexOf(x) !== -1 + && to[x] !== null + && !deepEqual(from[x], to[x])) { + delta.updated[x] = to[x]; + } + } + } + for (const x of Object.keys(to)) { + if (!from || (Object.keys(from).indexOf(x) === -1)) { + if (to[x] !== null) { + delta.added[x] = to[x]; + } + } + else if (to[x] === null) { + delta.removed.push(x); + } + } + return delta; + } + calculateContextDeltaV2(from, to) { + const delta = { added: {}, updated: {}, removed: [], reset: undefined, commands: [] }; + for (const x of Object.keys(to)) { + if (to[x] !== null) { + const fromX = from ? from[x] : null; + if (!deepEqual(fromX, to[x])) { + delta.commands?.push({ type: "set", path: x, value: to[x] }); + } + } + else { + delta.commands?.push({ type: "remove", path: x }); + } + } + return delta; + } + resetState() { + for (const sub of this._gw3Subscriptions) { + this._connection.off(sub); + } + if (this._systemContextsSubKey) { + this.unsubscribe(this._systemContextsSubKey); + delete this._systemContextsSubKey; + } + this._gw3Subscriptions = []; + this._contextNameToId = {}; + this._contextIdToName = {}; + delete this._protocolVersion; + this._contextsTempCache = Object.keys(this._contextNameToData).reduce((cacheSoFar, ctxName) => { + const contextData = this._contextNameToData[ctxName]; + if (contextData.isAnnounced && (contextData.activityId || contextData.sentExplicitSubscription)) { + cacheSoFar[ctxName] = this._contextNameToData[ctxName].context; + } + return cacheSoFar; + }, {}); + this._contextNameToData = {}; + } + async reInitiateState() { + this.subscribeToContextCreatedMessages(); + this.subscribeToContextUpdatedMessages(); + this.subscribeToContextDestroyedMessages(); + this._connection.replayer?.drain(ContextMessageReplaySpec.name, (message) => { + const type = message.type; + if (!type) { + return; + } + if (type === GW_MESSAGE_CONTEXT_CREATED || + type === GW_MESSAGE_CONTEXT_ADDED || + type === GW_MESSAGE_ACTIVITY_CREATED) { + this.handleContextCreatedMessage(message); + } + else if (type === GW_MESSAGE_SUBSCRIBED_CONTEXT || + type === GW_MESSAGE_CONTEXT_UPDATED || + type === GW_MESSAGE_JOINED_ACTIVITY) { + this.handleContextUpdatedMessage(message); + } + else if (type === GW_MESSAGE_CONTEXT_DESTROYED || + type === GW_MESSAGE_ACTIVITY_DESTROYED) { + this.handleContextDestroyedMessage(message); + } + }); + await Promise.all(this._contextsSubscriptionsCache.map((subscription) => this.subscribe(subscription.contextName, subscription.callback, subscription.subKey))); + await this.flushQueue(); + for (const ctxName in this._contextsTempCache) { + if (typeof this._contextsTempCache[ctxName] !== "object" || Object.keys(this._contextsTempCache[ctxName]).length === 0) { + continue; + } + const lastKnownData = this._contextsTempCache[ctxName]; + this._logger.info(`Re-announcing known context: ${ctxName}`); + await this.flushQueue(); + await this.update(ctxName, lastKnownData); + } + this._contextsTempCache = {}; + this._logger.info("Contexts are re-announced"); + } + flushQueue() { + return new Promise((resolve) => setTimeout(() => resolve(), 0)); + } + }; + + class ContextsModule { + initTime; + initStartTime; + initEndTime; + _bridge; + constructor(config) { + this._bridge = new GW3Bridge$1(config); + } + all() { + return this._bridge.all(); + } + update(name, data) { + this.checkName(name); + this.checkData(data); + return this._bridge.update(name, data); + } + set(name, data) { + this.checkName(name); + this.checkData(data); + return this._bridge.set(name, data); + } + setPath(name, path, data) { + this.checkName(name); + this.checkPath(path); + const isTopLevelPath = path === ""; + if (isTopLevelPath) { + this.checkData(data); + return this.set(name, data); + } + return this._bridge.setPath(name, path, data); + } + setPaths(name, paths) { + this.checkName(name); + if (!Array.isArray(paths)) { + throw new Error("Please provide the paths as an array of PathValues!"); + } + for (const { path, value } of paths) { + this.checkPath(path); + const isTopLevelPath = path === ""; + if (isTopLevelPath) { + this.checkData(value); + } + } + return this._bridge.setPaths(name, paths); + } + subscribe(name, callback) { + this.checkName(name); + if (typeof callback !== "function") { + throw new Error("Please provide the callback as a function!"); + } + return this._bridge + .subscribe(name, (data, delta, removed, key, extraData) => callback(data, delta, removed, () => this._bridge.unsubscribe(key), extraData)) + .then((key) => () => { + this._bridge.unsubscribe(key); + }); + } + get(name) { + this.checkName(name); + return this._bridge.get(name); + } + ready() { + return Promise.resolve(this); + } + destroy(name) { + this.checkName(name); + return this._bridge.destroy(name); + } + get setPathSupported() { + return this._bridge.setPathSupported; + } + checkName(name) { + if (typeof name !== "string" || name === "") { + throw new Error("Please provide the name as a non-empty string!"); + } + } + checkPath(path) { + if (typeof path !== "string") { + throw new Error("Please provide the path as a dot delimited string!"); + } + } + checkData(data) { + if (typeof data !== "object") { + throw new Error("Please provide the data as an object!"); + } + } + } + + function promisify$2 (promise, successCallback, errorCallback) { + if (typeof successCallback !== "function" && typeof errorCallback !== "function") { + return promise; + } + if (typeof successCallback !== "function") { + successCallback = () => { }; + } + else if (typeof errorCallback !== "function") { + errorCallback = () => { }; + } + return promise.then(successCallback, errorCallback); + } + + function rejectAfter(ms = 0, promise, error) { + let timeout; + const clearTimeoutIfThere = () => { + if (timeout) { + clearTimeout(timeout); + } + }; + promise + .then(() => { + clearTimeoutIfThere(); + }) + .catch(() => { + clearTimeoutIfThere(); + }); + return new Promise((resolve, reject) => { + timeout = setTimeout(() => reject(error), ms); + }); + } + + var InvokeStatus; + (function (InvokeStatus) { + InvokeStatus[InvokeStatus["Success"] = 0] = "Success"; + InvokeStatus[InvokeStatus["Error"] = 1] = "Error"; + })(InvokeStatus || (InvokeStatus = {})); + class Client { + protocol; + repo; + instance; + configuration; + constructor(protocol, repo, instance, configuration) { + this.protocol = protocol; + this.repo = repo; + this.instance = instance; + this.configuration = configuration; + } + subscribe(method, options, successCallback, errorCallback, existingSub) { + const callProtocolSubscribe = (targetServers, stream, successProxy, errorProxy) => { + options.methodResponseTimeout = options.methodResponseTimeout ?? options.waitTimeoutMs; + this.protocol.client.subscribe(stream, options, targetServers, successProxy, errorProxy, existingSub); + }; + const promise = new Promise((resolve, reject) => { + const successProxy = (sub) => { + resolve(sub); + }; + const errorProxy = (err) => { + reject(err); + }; + if (!method) { + reject(`Method definition is required. Please, provide either a unique string for a method name or a “methodDefinition” object with a required “name” property.`); + return; + } + let methodDef; + if (typeof method === "string") { + methodDef = { name: method }; + } + else { + methodDef = method; + } + if (!methodDef.name) { + reject(`Method definition is required. Please, provide either a unique string for a method name or a “methodDefinition” object with a required “name” property.`); + return; + } + if (options === undefined) { + options = {}; + } + let target = options.target; + if (target === undefined) { + target = "best"; + } + if (typeof target === "string" && target !== "all" && target !== "best") { + reject(new Error(`"${target}" is not a valid target. Valid targets are "all", "best", or an instance.`)); + return; + } + if (options.methodResponseTimeout === undefined) { + options.methodResponseTimeout = options.method_response_timeout; + if (options.methodResponseTimeout === undefined) { + options.methodResponseTimeout = this.configuration.methodResponseTimeout; + } + } + if (options.waitTimeoutMs === undefined) { + options.waitTimeoutMs = options.wait_for_method_timeout; + if (options.waitTimeoutMs === undefined) { + options.waitTimeoutMs = this.configuration.waitTimeoutMs; + } + } + const delayStep = 500; + let delayTillNow = 0; + let currentServers = this.getServerMethodsByFilterAndTarget(methodDef, target); + if (currentServers.length > 0) { + callProtocolSubscribe(currentServers, currentServers[0].methods[0], successProxy, errorProxy); + } + else { + const retry = () => { + if (!target || !(options.waitTimeoutMs)) { + return; + } + delayTillNow += delayStep; + currentServers = this.getServerMethodsByFilterAndTarget(methodDef, target); + if (currentServers.length > 0) { + const streamInfo = currentServers[0].methods[0]; + callProtocolSubscribe(currentServers, streamInfo, successProxy, errorProxy); + } + else if (delayTillNow >= options.waitTimeoutMs) { + const def = typeof method === "string" ? { name: method } : method; + callProtocolSubscribe(currentServers, def, successProxy, errorProxy); + } + else { + setTimeout(retry, delayStep); + } + }; + setTimeout(retry, delayStep); + } + }); + return promisify$2(promise, successCallback, errorCallback); + } + servers(methodFilter) { + const filterCopy = methodFilter === undefined + ? undefined + : { ...methodFilter }; + return this.getServers(filterCopy).map((serverMethodMap) => { + return serverMethodMap.server.instance; + }); + } + methods(methodFilter) { + if (typeof methodFilter === "string") { + methodFilter = { name: methodFilter }; + } + else { + methodFilter = { ...methodFilter }; + } + return this.getMethods(methodFilter); + } + methodsForInstance(instance) { + return this.getMethodsForInstance(instance); + } + methodAdded(callback) { + return this.repo.onMethodAdded(callback); + } + methodRemoved(callback) { + return this.repo.onMethodRemoved(callback); + } + serverAdded(callback) { + return this.repo.onServerAdded(callback); + } + serverRemoved(callback) { + return this.repo.onServerRemoved((server, reason) => { + callback(server, reason); + }); + } + serverMethodAdded(callback) { + return this.repo.onServerMethodAdded((server, method) => { + callback({ server, method }); + }); + } + serverMethodRemoved(callback) { + return this.repo.onServerMethodRemoved((server, method) => { + callback({ server, method }); + }); + } + async invoke(methodFilter, argumentObj, target, additionalOptions, success, error) { + const getInvokePromise = async () => { + let methodDefinition; + if (typeof methodFilter === "string") { + methodDefinition = { name: methodFilter }; + } + else { + methodDefinition = { ...methodFilter }; + } + if (!methodDefinition.name) { + return Promise.reject(`Method definition is required. Please, provide either a unique string for a method name or a “methodDefinition” object with a required “name” property.`); + } + if (!argumentObj) { + argumentObj = {}; + } + if (!target) { + target = "best"; + } + if (typeof target === "string" && target !== "all" && target !== "best" && target !== "skipMine") { + return Promise.reject(new Error(`"${target}" is not a valid target. Valid targets are "all" and "best".`)); + } + if (!additionalOptions) { + additionalOptions = {}; + } + if (additionalOptions.methodResponseTimeoutMs === undefined) { + additionalOptions.methodResponseTimeoutMs = additionalOptions.method_response_timeout; + if (additionalOptions.methodResponseTimeoutMs === undefined) { + additionalOptions.methodResponseTimeoutMs = this.configuration.methodResponseTimeout; + } + } + if (additionalOptions.waitTimeoutMs === undefined) { + additionalOptions.waitTimeoutMs = additionalOptions.wait_for_method_timeout; + if (additionalOptions.waitTimeoutMs === undefined) { + additionalOptions.waitTimeoutMs = this.configuration.waitTimeoutMs; + } + } + if (additionalOptions.waitTimeoutMs !== undefined && typeof additionalOptions.waitTimeoutMs !== "number") { + return Promise.reject(new Error(`"${additionalOptions.waitTimeoutMs}" is not a valid number for "waitTimeoutMs" `)); + } + if (typeof argumentObj !== "object") { + return Promise.reject(new Error(`The method arguments must be an object. method: ${methodDefinition.name}`)); + } + let serversMethodMap = this.getServerMethodsByFilterAndTarget(methodDefinition, target); + if (serversMethodMap.length === 0) { + try { + serversMethodMap = await this.tryToAwaitForMethods(methodDefinition, target, additionalOptions); + } + catch (err) { + const method = { + ...methodDefinition, + getServers: () => [], + supportsStreaming: false, + objectTypes: methodDefinition.objectTypes ?? [], + flags: methodDefinition.flags?.metadata ?? {} + }; + const errorObj = { + method, + called_with: argumentObj, + message: `Can not find a method matching ${JSON.stringify(methodFilter)} with server filter ${JSON.stringify(target)}`, + executed_by: undefined, + returned: undefined, + status: undefined, + }; + return Promise.reject(errorObj); + } + } + const timeout = additionalOptions.methodResponseTimeoutMs; + const additionalOptionsCopy = additionalOptions; + const invokePromises = serversMethodMap.map((serversMethodPair) => { + const invId = nanoid$1(10); + const method = serversMethodPair.methods[0]; + const server = serversMethodPair.server; + const invokePromise = this.protocol.client.invoke(invId, method, argumentObj, server, additionalOptionsCopy); + return Promise.race([ + invokePromise, + rejectAfter(timeout, invokePromise, { + invocationId: invId, + message: `Invocation timeout (${timeout} ms) reached for method name: ${method?.name}, target instance: ${JSON.stringify(server.instance)}, options: ${JSON.stringify(additionalOptionsCopy)}`, + status: InvokeStatus.Error, + }) + ]); + }); + const invocationMessages = await Promise.all(invokePromises); + const results = this.getInvocationResultObj(invocationMessages, methodDefinition, argumentObj); + const allRejected = invocationMessages.every((result) => result.status === InvokeStatus.Error); + if (allRejected) { + return Promise.reject(results); + } + return results; + }; + return promisify$2(getInvokePromise(), success, error); + } + getInvocationResultObj(invocationResults, method, calledWith) { + const all_return_values = invocationResults + .filter((invokeMessage) => invokeMessage.status === InvokeStatus.Success) + .reduce((allValues, currentValue) => { + allValues = [ + ...allValues, + { + executed_by: currentValue.instance, + returned: currentValue.result, + called_with: calledWith, + method, + message: currentValue.message, + status: currentValue.status, + } + ]; + return allValues; + }, []); + const all_errors = invocationResults + .filter((invokeMessage) => invokeMessage.status === InvokeStatus.Error) + .reduce((allErrors, currError) => { + allErrors = [ + ...allErrors, + { + executed_by: currError.instance, + called_with: calledWith, + name: method.name, + message: currError.message, + } + ]; + return allErrors; + }, []); + const invResult = invocationResults[0]; + const result = { + method, + called_with: calledWith, + returned: invResult.result, + executed_by: invResult.instance, + all_return_values, + all_errors, + message: invResult.message, + status: invResult.status + }; + return result; + } + tryToAwaitForMethods(methodDefinition, target, additionalOptions) { + return new Promise((resolve, reject) => { + if (additionalOptions.waitTimeoutMs === 0) { + reject(); + return; + } + const delayStep = 500; + let delayTillNow = 0; + const retry = () => { + delayTillNow += delayStep; + const serversMethodMap = this.getServerMethodsByFilterAndTarget(methodDefinition, target); + if (serversMethodMap.length > 0) { + clearInterval(interval); + resolve(serversMethodMap); + } + else if (delayTillNow >= (additionalOptions.waitTimeoutMs || 10000)) { + clearInterval(interval); + reject(); + return; + } + }; + const interval = setInterval(retry, delayStep); + }); + } + filterByTarget(target, serverMethodMap) { + if (typeof target === "string") { + if (target === "all") { + return [...serverMethodMap]; + } + else if (target === "best") { + const localMachine = serverMethodMap + .find((s) => s.server.instance.isLocal); + if (localMachine) { + return [localMachine]; + } + if (serverMethodMap[0] !== undefined) { + return [serverMethodMap[0]]; + } + } + else if (target === "skipMine") { + return serverMethodMap.filter(({ server }) => server.instance.peerId !== this.instance.peerId); + } + } + else { + let targetArray; + if (!Array.isArray(target)) { + targetArray = [target]; + } + else { + targetArray = target; + } + const allServersMatching = targetArray.reduce((matches, filter) => { + const myMatches = serverMethodMap.filter((serverMethodPair) => { + return this.instanceMatch(filter, serverMethodPair.server.instance); + }); + return matches.concat(myMatches); + }, []); + return allServersMatching; + } + return []; + } + instanceMatch(instanceFilter, instanceDefinition) { + if (instanceFilter?.peerId && instanceFilter?.instance) { + instanceFilter = { ...instanceFilter }; + delete instanceFilter.peerId; + } + return this.containsProps(instanceFilter, instanceDefinition); + } + methodMatch(methodFilter, methodDefinition) { + return this.containsProps(methodFilter, methodDefinition); + } + containsProps(filter, repoMethod) { + const filterProps = Object.keys(filter) + .filter((prop) => { + return filter[prop] !== undefined + && filter[prop] !== null + && typeof filter[prop] !== "function" + && prop !== "object_types" + && prop !== "display_name" + && prop !== "id" + && prop !== "gatewayId" + && prop !== "identifier" + && prop[0] !== "_"; + }); + return filterProps.every((prop) => { + let isMatch; + const filterValue = filter[prop]; + const repoMethodValue = repoMethod[prop]; + switch (prop) { + case "objectTypes": + isMatch = (filterValue || []).every((filterValueEl) => { + return (repoMethodValue || []).includes(filterValueEl); + }); + break; + case "flags": + isMatch = isSubset(repoMethodValue || {}, filterValue || {}); + break; + default: + isMatch = String(filterValue).toLowerCase() === String(repoMethodValue).toLowerCase(); + } + return isMatch; + }); + } + getMethods(methodFilter) { + if (methodFilter === undefined) { + return this.repo.getMethods(); + } + const methods = this.repo.getMethods().filter((method) => { + return this.methodMatch(methodFilter, method); + }); + return methods; + } + getMethodsForInstance(instanceFilter) { + const allServers = this.repo.getServers(); + const matchingServers = allServers.filter((server) => { + return this.instanceMatch(instanceFilter, server.instance); + }); + if (matchingServers.length === 0) { + return []; + } + let resultMethodsObject = {}; + if (matchingServers.length === 1) { + resultMethodsObject = matchingServers[0].methods; + } + else { + matchingServers.forEach((server) => { + Object.keys(server.methods).forEach((methodKey) => { + const method = server.methods[methodKey]; + resultMethodsObject[method.identifier] = method; + }); + }); + } + return Object.keys(resultMethodsObject) + .map((key) => { + return resultMethodsObject[key]; + }); + } + getServers(methodFilter) { + const servers = this.repo.getServers(); + if (methodFilter === undefined) { + return servers.map((server) => { + return { server, methods: [] }; + }); + } + return servers.reduce((prev, current) => { + const methodsForServer = Object.values(current.methods); + const matchingMethods = methodsForServer.filter((method) => { + return this.methodMatch(methodFilter, method); + }); + if (matchingMethods.length > 0) { + prev.push({ server: current, methods: matchingMethods }); + } + return prev; + }, []); + } + getServerMethodsByFilterAndTarget(methodFilter, target) { + const serversMethodMap = this.getServers(methodFilter); + return this.filterByTarget(target, serversMethodMap); + } + } + + class ServerSubscription { + protocol; + repoMethod; + subscription; + constructor(protocol, repoMethod, subscription) { + this.protocol = protocol; + this.repoMethod = repoMethod; + this.subscription = subscription; + } + get stream() { + if (!this.repoMethod.stream) { + throw new Error("no stream"); + } + return this.repoMethod.stream; + } + get arguments() { return this.subscription.arguments || {}; } + get branchKey() { return this.subscription.branchKey; } + get instance() { + if (!this.subscription.instance) { + throw new Error("no instance"); + } + return this.subscription.instance; + } + close() { + this.protocol.server.closeSingleSubscription(this.repoMethod, this.subscription); + } + push(data) { + this.protocol.server.pushDataToSingle(this.repoMethod, this.subscription, data); + } + } + + class Request { + protocol; + repoMethod; + requestContext; + arguments; + instance; + constructor(protocol, repoMethod, requestContext) { + this.protocol = protocol; + this.repoMethod = repoMethod; + this.requestContext = requestContext; + this.arguments = requestContext.arguments; + this.instance = requestContext.instance; + } + accept() { + this.protocol.server.acceptRequestOnBranch(this.requestContext, this.repoMethod, ""); + } + acceptOnBranch(branch) { + this.protocol.server.acceptRequestOnBranch(this.requestContext, this.repoMethod, branch); + } + reject(reason) { + this.protocol.server.rejectRequest(this.requestContext, this.repoMethod, reason); + } + } + + let ServerStreaming$1 = class ServerStreaming { + protocol; + server; + constructor(protocol, server) { + this.protocol = protocol; + this.server = server; + protocol.server.onSubRequest((rc, rm) => this.handleSubRequest(rc, rm)); + protocol.server.onSubAdded((sub, rm) => this.handleSubAdded(sub, rm)); + protocol.server.onSubRemoved((sub, rm) => this.handleSubRemoved(sub, rm)); + } + handleSubRequest(requestContext, repoMethod) { + if (!(repoMethod && + repoMethod.streamCallbacks && + typeof repoMethod.streamCallbacks.subscriptionRequestHandler === "function")) { + return; + } + const request = new Request(this.protocol, repoMethod, requestContext); + repoMethod.streamCallbacks.subscriptionRequestHandler(request); + } + handleSubAdded(subscription, repoMethod) { + if (!(repoMethod && + repoMethod.streamCallbacks && + typeof repoMethod.streamCallbacks.subscriptionAddedHandler === "function")) { + return; + } + const sub = new ServerSubscription(this.protocol, repoMethod, subscription); + repoMethod.streamCallbacks.subscriptionAddedHandler(sub); + } + handleSubRemoved(subscription, repoMethod) { + if (!(repoMethod && + repoMethod.streamCallbacks && + typeof repoMethod.streamCallbacks.subscriptionRemovedHandler === "function")) { + return; + } + const sub = new ServerSubscription(this.protocol, repoMethod, subscription); + repoMethod.streamCallbacks.subscriptionRemovedHandler(sub); + } + }; + + class ServerBranch { + key; + protocol; + repoMethod; + constructor(key, protocol, repoMethod) { + this.key = key; + this.protocol = protocol; + this.repoMethod = repoMethod; + } + subscriptions() { + const subList = this.protocol.server.getSubscriptionList(this.repoMethod, this.key); + return subList.map((sub) => { + return new ServerSubscription(this.protocol, this.repoMethod, sub); + }); + } + close() { + this.protocol.server.closeAllSubscriptions(this.repoMethod, this.key); + } + push(data) { + this.protocol.server.pushData(this.repoMethod, data, [this.key]); + } + } + + class ServerStream { + _protocol; + _repoMethod; + _server; + name; + constructor(_protocol, _repoMethod, _server) { + this._protocol = _protocol; + this._repoMethod = _repoMethod; + this._server = _server; + this.name = this._repoMethod.definition.name; + } + branches(key) { + const bList = this._protocol.server.getBranchList(this._repoMethod); + if (key) { + if (bList.indexOf(key) > -1) { + return new ServerBranch(key, this._protocol, this._repoMethod); + } + return undefined; + } + else { + return bList.map((branchKey) => { + return new ServerBranch(branchKey, this._protocol, this._repoMethod); + }); + } + } + branch(key) { + return this.branches(key); + } + subscriptions() { + const subList = this._protocol.server.getSubscriptionList(this._repoMethod); + return subList.map((sub) => { + return new ServerSubscription(this._protocol, this._repoMethod, sub); + }); + } + get definition() { + const def2 = this._repoMethod.definition; + return { + accepts: def2.accepts, + description: def2.description, + displayName: def2.displayName, + name: def2.name, + objectTypes: def2.objectTypes, + returns: def2.returns, + supportsStreaming: def2.supportsStreaming, + flags: def2.flags?.metadata, + }; + } + close() { + this._protocol.server.closeAllSubscriptions(this._repoMethod); + this._server.unregister(this._repoMethod.definition, true); + } + push(data, branches) { + if (typeof branches !== "string" && !Array.isArray(branches) && branches !== undefined) { + throw new Error("invalid branches should be string or string array"); + } + if (typeof data !== "object") { + throw new Error("Invalid arguments. Data must be an object."); + } + this._protocol.server.pushData(this._repoMethod, data, branches); + } + updateRepoMethod(repoMethod) { + this._repoMethod = repoMethod; + } + } + + class Server { + protocol; + serverRepository; + streaming; + invocations = 0; + currentlyUnregistering = {}; + constructor(protocol, serverRepository) { + this.protocol = protocol; + this.serverRepository = serverRepository; + this.streaming = new ServerStreaming$1(protocol, this); + this.protocol.server.onInvoked(this.onMethodInvoked.bind(this)); + } + createStream(streamDef, callbacks, successCallback, errorCallback, existingStream) { + const promise = new Promise((resolve, reject) => { + if (!streamDef) { + reject("The stream name must be unique! Please, provide either a unique string for a stream name to “glue.interop.createStream()” or a “methodDefinition” object with a unique “name” property for the stream."); + return; + } + let streamMethodDefinition; + if (typeof streamDef === "string") { + streamMethodDefinition = { name: "" + streamDef }; + } + else { + streamMethodDefinition = { ...streamDef }; + } + if (!streamMethodDefinition.name) { + return reject(`The “name” property is required for the “streamDefinition” object and must be unique. Stream definition: ${JSON.stringify(streamMethodDefinition)}`); + } + const nameAlreadyExists = this.serverRepository.getList() + .some((serverMethod) => serverMethod.definition.name === streamMethodDefinition.name); + if (nameAlreadyExists) { + return reject(`A stream with the name "${streamMethodDefinition.name}" already exists! Please, provide a unique name for the stream.`); + } + streamMethodDefinition.supportsStreaming = true; + if (!callbacks) { + callbacks = {}; + } + if (typeof callbacks.subscriptionRequestHandler !== "function") { + callbacks.subscriptionRequestHandler = (request) => { + request.accept(); + }; + } + const repoMethod = this.serverRepository.add({ + definition: streamMethodDefinition, + streamCallbacks: callbacks, + protocolState: {}, + }); + this.protocol.server.createStream(repoMethod) + .then(() => { + let streamUserObject; + if (existingStream) { + streamUserObject = existingStream; + existingStream.updateRepoMethod(repoMethod); + } + else { + streamUserObject = new ServerStream(this.protocol, repoMethod, this); + } + repoMethod.stream = streamUserObject; + resolve(streamUserObject); + }) + .catch((err) => { + if (repoMethod.repoId) { + this.serverRepository.remove(repoMethod.repoId); + } + reject(err); + }); + }); + return promisify$2(promise, successCallback, errorCallback); + } + register(methodDefinition, callback) { + if (!methodDefinition) { + return Promise.reject("Method definition is required. Please, provide either a unique string for a method name or a “methodDefinition” object with a required “name” property."); + } + if (typeof callback !== "function") { + return Promise.reject(`The second parameter must be a callback function. Method: ${typeof methodDefinition === "string" ? methodDefinition : methodDefinition.name}`); + } + const wrappedCallbackFunction = async (context, resultCallback) => { + try { + const result = callback(context.args, context.instance); + if (result && typeof result.then === "function") { + const resultValue = await result; + resultCallback(undefined, resultValue); + } + else { + resultCallback(undefined, result); + } + } + catch (e) { + resultCallback(e ?? "", e ?? ""); + } + }; + wrappedCallbackFunction.userCallback = callback; + return this.registerCore(methodDefinition, wrappedCallbackFunction); + } + registerAsync(methodDefinition, callback) { + if (!methodDefinition) { + return Promise.reject("Method definition is required. Please, provide either a unique string for a method name or a “methodDefinition” object with a required “name” property."); + } + if (typeof callback !== "function") { + return Promise.reject(`The second parameter must be a callback function. Method: ${typeof methodDefinition === "string" ? methodDefinition : methodDefinition.name}`); + } + const wrappedCallback = async (context, resultCallback) => { + try { + let resultCalled = false; + const success = (result) => { + if (!resultCalled) { + resultCallback(undefined, result); + } + resultCalled = true; + }; + const error = (e) => { + if (!resultCalled) { + if (!e) { + e = ""; + } + resultCallback(e, e); + } + resultCalled = true; + }; + const methodResult = callback(context.args, context.instance, success, error); + if (methodResult && typeof methodResult.then === "function") { + methodResult + .then(success) + .catch(error); + } + } + catch (e) { + resultCallback(e, undefined); + } + }; + wrappedCallback.userCallbackAsync = callback; + return this.registerCore(methodDefinition, wrappedCallback); + } + async unregister(methodFilter, forStream = false) { + if (methodFilter === undefined) { + return Promise.reject("Please, provide either a unique string for a name or an object containing a “name” property."); + } + if (typeof methodFilter === "function") { + await this.unregisterWithPredicate(methodFilter, forStream); + return; + } + let methodDefinition; + if (typeof methodFilter === "string") { + methodDefinition = { name: methodFilter }; + } + else { + methodDefinition = methodFilter; + } + if (methodDefinition.name === undefined) { + return Promise.reject("Method name is required. Cannot find a method if the method name is undefined!"); + } + const methodToBeRemoved = this.serverRepository.getList().find((serverMethod) => { + return serverMethod.definition.name === methodDefinition.name + && (serverMethod.definition.supportsStreaming || false) === forStream; + }); + if (!methodToBeRemoved) { + return Promise.reject(`Method with a name "${methodDefinition.name}" does not exist or is not registered by your application!`); + } + await this.removeMethodsOrStreams([methodToBeRemoved]); + } + async unregisterWithPredicate(filterPredicate, forStream) { + const methodsOrStreamsToRemove = this.serverRepository.getList() + .filter((sm) => filterPredicate(sm.definition)) + .filter((serverMethod) => (serverMethod.definition.supportsStreaming || false) === forStream); + if (!methodsOrStreamsToRemove || methodsOrStreamsToRemove.length === 0) { + return Promise.reject(`Could not find a ${forStream ? "stream" : "method"} matching the specified condition!`); + } + await this.removeMethodsOrStreams(methodsOrStreamsToRemove); + } + removeMethodsOrStreams(methodsToRemove) { + const methodUnregPromises = []; + methodsToRemove.forEach((method) => { + const promise = this.protocol.server.unregister(method) + .then(() => { + if (method.repoId) { + this.serverRepository.remove(method.repoId); + } + }); + methodUnregPromises.push(promise); + this.addAsCurrentlyUnregistering(method.definition.name, promise); + }); + return Promise.all(methodUnregPromises); + } + async addAsCurrentlyUnregistering(methodName, promise) { + const timeout = new Promise((resolve) => setTimeout(resolve, 5000)); + this.currentlyUnregistering[methodName] = Promise.race([promise, timeout]).then(() => { + delete this.currentlyUnregistering[methodName]; + }); + } + async registerCore(method, theFunction) { + let methodDefinition; + if (typeof method === "string") { + methodDefinition = { name: "" + method }; + } + else { + methodDefinition = { ...method }; + } + if (!methodDefinition.name) { + return Promise.reject(`Please, provide a (unique) string value for the “name” property in the “methodDefinition” object: ${JSON.stringify(method)}`); + } + const unregisterInProgress = this.currentlyUnregistering[methodDefinition.name]; + if (typeof unregisterInProgress !== "undefined") { + await unregisterInProgress; + } + const nameAlreadyExists = this.serverRepository.getList() + .some((serverMethod) => serverMethod.definition.name === methodDefinition.name); + if (nameAlreadyExists) { + return Promise.reject(`A method with the name "${methodDefinition.name}" already exists! Please, provide a unique name for the method.`); + } + if (methodDefinition.supportsStreaming) { + return Promise.reject(`When you create methods with “glue.interop.register()” or “glue.interop.registerAsync()” the property “supportsStreaming” cannot be “true”. If you want “${methodDefinition.name}” to be a stream, please use the “glue.interop.createStream()” method.`); + } + const repoMethod = this.serverRepository.add({ + definition: methodDefinition, + theFunction, + protocolState: {}, + }); + return this.protocol.server.register(repoMethod) + .catch((err) => { + if (repoMethod?.repoId) { + this.serverRepository.remove(repoMethod.repoId); + } + throw err; + }); + } + onMethodInvoked(methodToExecute, invocationId, invocationArgs) { + if (!methodToExecute || !methodToExecute.theFunction) { + return; + } + methodToExecute.theFunction(invocationArgs, (err, result) => { + if (err !== undefined && err !== null) { + if (err.message && typeof err.message === "string") { + err = err.message; + } + else if (typeof err !== "string") { + try { + err = JSON.stringify(err); + } + catch (unStrException) { + err = `un-stringifyable error in onMethodInvoked! Top level prop names: ${Object.keys(err)}`; + } + } + } + if (!result) { + result = {}; + } + else if (typeof result !== "object" || Array.isArray(result)) { + result = { _value: result }; + } + this.protocol.server.methodInvocationResult(methodToExecute, invocationId, err, result); + }); + } + } + + class InstanceWrapper { + wrapped = {}; + constructor(API, instance, connection) { + this.wrapped.getMethods = function () { + return API.methodsForInstance(this); + }; + this.wrapped.getStreams = function () { + return API.methodsForInstance(this).filter((m) => m.supportsStreaming); + }; + if (instance) { + this.refreshWrappedObject(instance); + } + if (connection) { + connection.loggedIn(() => { + this.refresh(connection); + }); + this.refresh(connection); + } + } + unwrap() { + return this.wrapped; + } + refresh(connection) { + if (!connection) { + return; + } + const resolvedIdentity = connection?.resolvedIdentity; + const instance = Object.assign({}, resolvedIdentity ?? {}, { peerId: connection?.peerId }); + this.refreshWrappedObject(instance); + } + refreshWrappedObject(resolvedIdentity) { + Object.keys(resolvedIdentity).forEach((key) => { + this.wrapped[key] = resolvedIdentity[key]; + }); + this.wrapped.user = resolvedIdentity.user; + this.wrapped.instance = resolvedIdentity.instance; + this.wrapped.application = resolvedIdentity.application ?? nanoid$1(10); + this.wrapped.applicationName = resolvedIdentity.applicationName; + this.wrapped.pid = resolvedIdentity.pid ?? resolvedIdentity.process ?? Math.floor(Math.random() * 10000000000); + this.wrapped.machine = resolvedIdentity.machine; + this.wrapped.environment = resolvedIdentity.environment; + this.wrapped.region = resolvedIdentity.region; + this.wrapped.windowId = resolvedIdentity.windowId; + this.wrapped.isLocal = resolvedIdentity.isLocal ?? true; + this.wrapped.api = resolvedIdentity.api; + this.wrapped.service = resolvedIdentity.service; + this.wrapped.peerId = resolvedIdentity.peerId; + } + } + + const hideMethodSystemFlags = (method) => { + return { + ...method, + flags: method.flags.metadata || {} + }; + }; + class ClientRepository { + logger; + API; + servers = {}; + myServer; + methodsCount = {}; + callbacks = CallbackRegistryFactory$1(); + constructor(logger, API) { + this.logger = logger; + this.API = API; + const peerId = this.API.instance.peerId; + this.myServer = { + id: peerId, + methods: {}, + instance: this.API.instance, + wrapper: this.API.unwrappedInstance, + }; + this.servers[peerId] = this.myServer; + } + addServer(info, serverId) { + this.logger.debug(`adding server ${serverId}`); + const current = this.servers[serverId]; + if (current) { + return current.id; + } + const wrapper = new InstanceWrapper(this.API, info); + const serverEntry = { + id: serverId, + methods: {}, + instance: wrapper.unwrap(), + wrapper, + }; + this.servers[serverId] = serverEntry; + this.callbacks.execute("onServerAdded", serverEntry.instance); + return serverId; + } + removeServerById(id, reason) { + const server = this.servers[id]; + if (!server) { + this.logger.warn(`not aware of server ${id}, my state ${JSON.stringify(Object.keys(this.servers))}`); + return; + } + else { + this.logger.debug(`removing server ${id}`); + } + Object.keys(server.methods).forEach((methodId) => { + this.removeServerMethod(id, methodId); + }); + delete this.servers[id]; + this.callbacks.execute("onServerRemoved", server.instance, reason); + } + addServerMethod(serverId, method) { + const server = this.servers[serverId]; + if (!server) { + throw new Error("server does not exists"); + } + if (server.methods[method.id]) { + return; + } + const identifier = this.createMethodIdentifier(method); + const that = this; + const methodDefinition = { + identifier, + gatewayId: method.id, + name: method.name, + displayName: method.display_name, + description: method.description, + version: method.version, + objectTypes: method.object_types || [], + accepts: method.input_signature, + returns: method.result_signature, + supportsStreaming: typeof method.flags !== "undefined" ? method.flags.streaming : false, + flags: method.flags ?? {}, + getServers: () => { + return that.getServersByMethod(identifier); + } + }; + methodDefinition.object_types = methodDefinition.objectTypes; + methodDefinition.display_name = methodDefinition.displayName; + methodDefinition.version = methodDefinition.version; + server.methods[method.id] = methodDefinition; + const clientMethodDefinition = hideMethodSystemFlags(methodDefinition); + if (!this.methodsCount[identifier]) { + this.methodsCount[identifier] = 0; + this.callbacks.execute("onMethodAdded", clientMethodDefinition); + } + this.methodsCount[identifier] = this.methodsCount[identifier] + 1; + this.callbacks.execute("onServerMethodAdded", server.instance, clientMethodDefinition); + return methodDefinition; + } + removeServerMethod(serverId, methodId) { + const server = this.servers[serverId]; + if (!server) { + throw new Error("server does not exists"); + } + const method = server.methods[methodId]; + delete server.methods[methodId]; + const clientMethodDefinition = hideMethodSystemFlags(method); + this.methodsCount[method.identifier] = this.methodsCount[method.identifier] - 1; + if (this.methodsCount[method.identifier] === 0) { + this.callbacks.execute("onMethodRemoved", clientMethodDefinition); + } + this.callbacks.execute("onServerMethodRemoved", server.instance, clientMethodDefinition); + } + getMethods() { + return this.extractMethodsFromServers(Object.values(this.servers)).map(hideMethodSystemFlags); + } + getServers() { + return Object.values(this.servers).map(this.hideServerMethodSystemFlags); + } + onServerAdded(callback) { + const unsubscribeFunc = this.callbacks.add("onServerAdded", callback); + const serversWithMethodsToReplay = this.getServers().map((s) => s.instance); + return this.returnUnsubWithDelayedReplay(unsubscribeFunc, serversWithMethodsToReplay, callback); + } + onMethodAdded(callback) { + const unsubscribeFunc = this.callbacks.add("onMethodAdded", callback); + const methodsToReplay = this.getMethods(); + return this.returnUnsubWithDelayedReplay(unsubscribeFunc, methodsToReplay, callback); + } + onServerMethodAdded(callback) { + const unsubscribeFunc = this.callbacks.add("onServerMethodAdded", callback); + let unsubCalled = false; + const servers = this.getServers(); + setTimeout(() => { + servers.forEach((server) => { + const methods = server.methods; + Object.keys(methods).forEach((methodId) => { + if (!unsubCalled) { + callback(server.instance, methods[methodId]); + } + }); + }); + }, 0); + return () => { + unsubCalled = true; + unsubscribeFunc(); + }; + } + onMethodRemoved(callback) { + const unsubscribeFunc = this.callbacks.add("onMethodRemoved", callback); + return unsubscribeFunc; + } + onServerRemoved(callback) { + const unsubscribeFunc = this.callbacks.add("onServerRemoved", callback); + return unsubscribeFunc; + } + onServerMethodRemoved(callback) { + const unsubscribeFunc = this.callbacks.add("onServerMethodRemoved", callback); + return unsubscribeFunc; + } + getServerById(id) { + const server = this.servers[id]; + if (!server) { + return undefined; + } + return this.hideServerMethodSystemFlags(this.servers[id]); + } + reset() { + Object.keys(this.servers).forEach((key) => { + this.removeServerById(key, "reset"); + }); + this.servers = { + [this.myServer.id]: this.myServer + }; + this.methodsCount = {}; + } + createMethodIdentifier(methodInfo) { + const accepts = methodInfo.input_signature ?? ""; + const returns = methodInfo.result_signature ?? ""; + return (methodInfo.name + accepts + returns).toLowerCase(); + } + getServersByMethod(identifier) { + const allServers = []; + Object.values(this.servers).forEach((server) => { + Object.values(server.methods).forEach((method) => { + if (method.identifier === identifier) { + allServers.push(server.instance); + } + }); + }); + return allServers; + } + returnUnsubWithDelayedReplay(unsubscribeFunc, collectionToReplay, callback) { + let unsubCalled = false; + setTimeout(() => { + collectionToReplay.forEach((item) => { + if (!unsubCalled) { + callback(item); + } + }); + }, 0); + return () => { + unsubCalled = true; + unsubscribeFunc(); + }; + } + hideServerMethodSystemFlags(server) { + const clientMethods = {}; + Object.entries(server.methods).forEach(([name, method]) => { + clientMethods[name] = hideMethodSystemFlags(method); + }); + return { + ...server, + methods: clientMethods + }; + } + extractMethodsFromServers(servers) { + const methods = Object.values(servers).reduce((clientMethods, server) => { + return [...clientMethods, ...Object.values(server.methods)]; + }, []); + return methods; + } + } + + class ServerRepository { + nextId = 0; + methods = []; + add(method) { + method.repoId = String(this.nextId); + this.nextId += 1; + this.methods.push(method); + return method; + } + remove(repoId) { + if (typeof repoId !== "string") { + return new TypeError("Expecting a string"); + } + this.methods = this.methods.filter((m) => { + return m.repoId !== repoId; + }); + } + getById(id) { + if (typeof id !== "string") { + return undefined; + } + return this.methods.find((m) => { + return m.repoId === id; + }); + } + getList() { + return this.methods.map((m) => m); + } + length() { + return this.methods.length; + } + reset() { + this.methods = []; + } + } + + const SUBSCRIPTION_REQUEST = "onSubscriptionRequest"; + const SUBSCRIPTION_ADDED = "onSubscriptionAdded"; + const SUBSCRIPTION_REMOVED = "onSubscriptionRemoved"; + class ServerStreaming { + session; + repository; + serverRepository; + ERR_URI_SUBSCRIPTION_FAILED = "com.tick42.agm.errors.subscription.failure"; + callbacks = CallbackRegistryFactory$1(); + nextStreamId = 0; + constructor(session, repository, serverRepository) { + this.session = session; + this.repository = repository; + this.serverRepository = serverRepository; + session.on("add-interest", (msg) => { + this.handleAddInterest(msg); + }); + session.on("remove-interest", (msg) => { + this.handleRemoveInterest(msg); + }); + } + acceptRequestOnBranch(requestContext, streamingMethod, branch) { + if (typeof branch !== "string") { + branch = ""; + } + if (typeof streamingMethod.protocolState.subscriptionsMap !== "object") { + throw new TypeError("The streaming method is missing its subscriptions."); + } + if (!Array.isArray(streamingMethod.protocolState.branchKeyToStreamIdMap)) { + throw new TypeError("The streaming method is missing its branches."); + } + const streamId = this.getStreamId(streamingMethod, branch); + const key = requestContext.msg.subscription_id; + const subscription = { + id: key, + arguments: requestContext.arguments, + instance: requestContext.instance, + branchKey: branch, + streamId, + subscribeMsg: requestContext.msg, + }; + streamingMethod.protocolState.subscriptionsMap[key] = subscription; + this.session.sendFireAndForget({ + type: "accepted", + subscription_id: key, + stream_id: streamId, + }); + this.callbacks.execute(SUBSCRIPTION_ADDED, subscription, streamingMethod); + } + rejectRequest(requestContext, streamingMethod, reason) { + if (typeof reason !== "string") { + reason = ""; + } + this.sendSubscriptionFailed("Subscription rejected by user. " + reason, requestContext.msg.subscription_id); + } + pushData(streamingMethod, data, branches) { + if (typeof streamingMethod !== "object" || !Array.isArray(streamingMethod.protocolState.branchKeyToStreamIdMap)) { + return; + } + if (typeof data !== "object") { + throw new Error("Invalid arguments. Data must be an object."); + } + if (typeof branches === "string") { + branches = [branches]; + } + else if (!Array.isArray(branches) || branches.length <= 0) { + branches = []; + } + const streamIdList = streamingMethod.protocolState.branchKeyToStreamIdMap + .filter((br) => { + if (!branches || branches.length === 0) { + return true; + } + return branches.indexOf(br.key) >= 0; + }).map((br) => { + return br.streamId; + }); + streamIdList.forEach((streamId) => { + const publishMessage = { + type: "publish", + stream_id: streamId, + data, + }; + this.session.sendFireAndForget(publishMessage); + }); + } + pushDataToSingle(method, subscription, data) { + if (typeof data !== "object") { + throw new Error("Invalid arguments. Data must be an object."); + } + const postMessage = { + type: "post", + subscription_id: subscription.id, + data, + }; + this.session.sendFireAndForget(postMessage); + } + closeSingleSubscription(streamingMethod, subscription) { + if (streamingMethod.protocolState.subscriptionsMap) { + delete streamingMethod.protocolState.subscriptionsMap[subscription.id]; + } + const dropSubscriptionMessage = { + type: "drop-subscription", + subscription_id: subscription.id, + reason: "Server dropping a single subscription", + }; + this.session.sendFireAndForget(dropSubscriptionMessage); + subscription.instance; + this.callbacks.execute(SUBSCRIPTION_REMOVED, subscription, streamingMethod); + } + closeMultipleSubscriptions(streamingMethod, branchKey) { + if (typeof streamingMethod !== "object" || typeof streamingMethod.protocolState.subscriptionsMap !== "object") { + return; + } + if (!streamingMethod.protocolState.subscriptionsMap) { + return; + } + const subscriptionsMap = streamingMethod.protocolState.subscriptionsMap; + let subscriptionsToClose = Object.keys(subscriptionsMap) + .map((key) => { + return subscriptionsMap[key]; + }); + if (typeof branchKey === "string") { + subscriptionsToClose = subscriptionsToClose.filter((sub) => { + return sub.branchKey === branchKey; + }); + } + subscriptionsToClose.forEach((subscription) => { + delete subscriptionsMap[subscription.id]; + const drop = { + type: "drop-subscription", + subscription_id: subscription.id, + reason: "Server dropping all subscriptions on stream_id: " + subscription.streamId, + }; + this.session.sendFireAndForget(drop); + }); + } + getSubscriptionList(streamingMethod, branchKey) { + if (typeof streamingMethod !== "object") { + return []; + } + let subscriptions = []; + if (!streamingMethod.protocolState.subscriptionsMap) { + return []; + } + const subscriptionsMap = streamingMethod.protocolState.subscriptionsMap; + const allSubscriptions = Object.keys(subscriptionsMap) + .map((key) => { + return subscriptionsMap[key]; + }); + if (typeof branchKey !== "string") { + subscriptions = allSubscriptions; + } + else { + subscriptions = allSubscriptions.filter((sub) => { + return sub.branchKey === branchKey; + }); + } + return subscriptions; + } + getBranchList(streamingMethod) { + if (typeof streamingMethod !== "object") { + return []; + } + if (!streamingMethod.protocolState.subscriptionsMap) { + return []; + } + const subscriptionsMap = streamingMethod.protocolState.subscriptionsMap; + const allSubscriptions = Object.keys(subscriptionsMap) + .map((key) => { + return subscriptionsMap[key]; + }); + const result = []; + allSubscriptions.forEach((sub) => { + let branch = ""; + if (typeof sub === "object" && typeof sub.branchKey === "string") { + branch = sub.branchKey; + } + if (result.indexOf(branch) === -1) { + result.push(branch); + } + }); + return result; + } + onSubAdded(callback) { + this.onSubscriptionLifetimeEvent(SUBSCRIPTION_ADDED, callback); + } + onSubRequest(callback) { + this.onSubscriptionLifetimeEvent(SUBSCRIPTION_REQUEST, callback); + } + onSubRemoved(callback) { + this.onSubscriptionLifetimeEvent(SUBSCRIPTION_REMOVED, callback); + } + handleRemoveInterest(msg) { + const streamingMethod = this.serverRepository.getById(msg.method_id); + if (typeof msg.subscription_id !== "string" || + typeof streamingMethod !== "object") { + return; + } + if (!streamingMethod.protocolState.subscriptionsMap) { + return; + } + if (typeof streamingMethod.protocolState.subscriptionsMap[msg.subscription_id] !== "object") { + return; + } + const subscription = streamingMethod.protocolState.subscriptionsMap[msg.subscription_id]; + delete streamingMethod.protocolState.subscriptionsMap[msg.subscription_id]; + this.callbacks.execute(SUBSCRIPTION_REMOVED, subscription, streamingMethod); + } + onSubscriptionLifetimeEvent(eventName, handlerFunc) { + this.callbacks.add(eventName, handlerFunc); + } + getNextStreamId() { + return this.nextStreamId++ + ""; + } + handleAddInterest(msg) { + const caller = this.repository.getServerById(msg.caller_id); + const instance = caller?.instance ?? {}; + const requestContext = { + msg, + arguments: msg.arguments_kv || {}, + instance, + }; + const streamingMethod = this.serverRepository.getById(msg.method_id); + if (streamingMethod === undefined) { + const errorMsg = "No method with id " + msg.method_id + " on this server."; + this.sendSubscriptionFailed(errorMsg, msg.subscription_id); + return; + } + if (streamingMethod.protocolState.subscriptionsMap && + streamingMethod.protocolState.subscriptionsMap[msg.subscription_id]) { + this.sendSubscriptionFailed("A subscription with id " + msg.subscription_id + " already exists.", msg.subscription_id); + return; + } + this.callbacks.execute(SUBSCRIPTION_REQUEST, requestContext, streamingMethod); + } + sendSubscriptionFailed(reason, subscriptionId) { + const errorMessage = { + type: "error", + reason_uri: this.ERR_URI_SUBSCRIPTION_FAILED, + reason, + request_id: subscriptionId, + }; + this.session.sendFireAndForget(errorMessage); + } + getStreamId(streamingMethod, branchKey) { + if (typeof branchKey !== "string") { + branchKey = ""; + } + if (!streamingMethod.protocolState.branchKeyToStreamIdMap) { + throw new Error(`streaming ${streamingMethod.definition.name} method without protocol state`); + } + const needleBranch = streamingMethod.protocolState.branchKeyToStreamIdMap.filter((branch) => { + return branch.key === branchKey; + })[0]; + let streamId = (needleBranch ? needleBranch.streamId : undefined); + if (typeof streamId !== "string" || streamId === "") { + streamId = this.getNextStreamId(); + streamingMethod.protocolState.branchKeyToStreamIdMap.push({ key: branchKey, streamId }); + } + return streamId; + } + } + + class ServerProtocol { + session; + clientRepository; + serverRepository; + logger; + callbacks = CallbackRegistryFactory$1(); + streaming; + constructor(session, clientRepository, serverRepository, logger) { + this.session = session; + this.clientRepository = clientRepository; + this.serverRepository = serverRepository; + this.logger = logger; + this.streaming = new ServerStreaming(session, clientRepository, serverRepository); + this.session.on("invoke", (msg) => this.handleInvokeMessage(msg)); + } + createStream(repoMethod) { + repoMethod.protocolState.subscriptionsMap = {}; + repoMethod.protocolState.branchKeyToStreamIdMap = []; + return this.register(repoMethod, true); + } + register(repoMethod, isStreaming) { + const methodDef = repoMethod.definition; + const flags = Object.assign({}, { metadata: methodDef.flags ?? {} }, { streaming: isStreaming || false }); + const registerMsg = { + type: "register", + methods: [{ + id: repoMethod.repoId, + name: methodDef.name, + display_name: methodDef.displayName, + description: methodDef.description, + version: methodDef.version, + flags, + object_types: methodDef.objectTypes || methodDef.object_types, + input_signature: methodDef.accepts, + result_signature: methodDef.returns, + restrictions: undefined, + }], + }; + return this.session.send(registerMsg, { methodId: repoMethod.repoId }) + .then(() => { + this.logger.debug("registered method " + repoMethod.definition.name + " with id " + repoMethod.repoId); + }) + .catch((msg) => { + this.logger.warn(`failed to register method ${repoMethod.definition.name} with id ${repoMethod.repoId} - ${JSON.stringify(msg)}`); + throw msg; + }); + } + onInvoked(callback) { + this.callbacks.add("onInvoked", callback); + } + methodInvocationResult(method, invocationId, err, result) { + let msg; + if (err || err === "") { + msg = { + type: "error", + request_id: invocationId, + reason_uri: "agm.errors.client_error", + reason: err, + context: result, + peer_id: undefined, + }; + } + else { + msg = { + type: "yield", + invocation_id: invocationId, + peer_id: this.session.peerId, + result, + request_id: undefined, + }; + } + this.session.sendFireAndForget(msg); + } + async unregister(method) { + const msg = { + type: "unregister", + methods: [method.repoId], + }; + await this.session.send(msg); + } + getBranchList(method) { + return this.streaming.getBranchList(method); + } + getSubscriptionList(method, branchKey) { + return this.streaming.getSubscriptionList(method, branchKey); + } + closeAllSubscriptions(method, branchKey) { + this.streaming.closeMultipleSubscriptions(method, branchKey); + } + pushData(method, data, branches) { + this.streaming.pushData(method, data, branches); + } + pushDataToSingle(method, subscription, data) { + this.streaming.pushDataToSingle(method, subscription, data); + } + closeSingleSubscription(method, subscription) { + this.streaming.closeSingleSubscription(method, subscription); + } + acceptRequestOnBranch(requestContext, method, branch) { + this.streaming.acceptRequestOnBranch(requestContext, method, branch); + } + rejectRequest(requestContext, method, reason) { + this.streaming.rejectRequest(requestContext, method, reason); + } + onSubRequest(callback) { + this.streaming.onSubRequest(callback); + } + onSubAdded(callback) { + this.streaming.onSubAdded(callback); + } + onSubRemoved(callback) { + this.streaming.onSubRemoved(callback); + } + handleInvokeMessage(msg) { + const invocationId = msg.invocation_id; + const callerId = msg.caller_id; + const methodId = msg.method_id; + const args = msg.arguments_kv; + const methodList = this.serverRepository.getList(); + const method = methodList.filter((m) => { + return m.repoId === methodId; + })[0]; + if (method === undefined) { + return; + } + const client = this.clientRepository.getServerById(callerId)?.instance; + const invocationArgs = { args, instance: client }; + this.callbacks.execute("onInvoked", method, invocationId, invocationArgs); + } + } + + class UserSubscription { + repository; + subscriptionData; + get requestArguments() { + return this.subscriptionData.params.arguments || {}; + } + get servers() { + return this.subscriptionData.trackedServers.reduce((servers, pair) => { + if (pair.subscriptionId) { + const server = this.repository.getServerById(pair.serverId)?.instance; + if (server) { + servers.push(server); + } + } + return servers; + }, []); + } + get serverInstance() { + return this.servers[0]; + } + get stream() { + return this.subscriptionData.method; + } + constructor(repository, subscriptionData) { + this.repository = repository; + this.subscriptionData = subscriptionData; + } + onData(dataCallback) { + if (typeof dataCallback !== "function") { + throw new TypeError("The data callback must be a function."); + } + this.subscriptionData.handlers.onData.push(dataCallback); + if (this.subscriptionData.handlers.onData.length === 1 && this.subscriptionData.queued.data.length > 0) { + this.subscriptionData.queued.data.forEach((dataItem) => { + dataCallback(dataItem); + }); + } + } + onClosed(closedCallback) { + if (typeof closedCallback !== "function") { + throw new TypeError("The callback must be a function."); + } + this.subscriptionData.handlers.onClosed.push(closedCallback); + } + onFailed(callback) { + } + onConnected(callback) { + if (typeof callback !== "function") { + throw new TypeError("The callback must be a function."); + } + this.subscriptionData.handlers.onConnected.push(callback); + } + close() { + this.subscriptionData.close(); + } + setNewSubscription(newSub) { + this.subscriptionData = newSub; + } + } + + class TimedCache { + config; + cache = []; + timeoutIds = []; + constructor(config) { + this.config = config; + } + add(element) { + const id = nanoid$1(10); + this.cache.push({ id, element }); + const timeoutId = setTimeout(() => { + const elementIdx = this.cache.findIndex((entry) => entry.id === id); + if (elementIdx < 0) { + return; + } + this.cache.splice(elementIdx, 1); + }, this.config.ELEMENT_TTL_MS); + this.timeoutIds.push(timeoutId); + } + flush() { + const elements = this.cache.map((entry) => entry.element); + this.timeoutIds.forEach((id) => clearInterval(id)); + this.cache = []; + this.timeoutIds = []; + return elements; + } + } + + const STATUS_AWAITING_ACCEPT = "awaitingAccept"; + const STATUS_SUBSCRIBED = "subscribed"; + const ERR_MSG_SUB_FAILED = "Subscription failed."; + const ERR_MSG_SUB_REJECTED = "Subscription rejected."; + const ON_CLOSE_MSG_SERVER_INIT = "ServerInitiated"; + const ON_CLOSE_MSG_CLIENT_INIT = "ClientInitiated"; + class ClientStreaming { + session; + repository; + logger; + subscriptionsList = {}; + timedCache = new TimedCache({ ELEMENT_TTL_MS: 10000 }); + subscriptionIdToLocalKeyMap = {}; + nextSubLocalKey = 0; + constructor(session, repository, logger) { + this.session = session; + this.repository = repository; + this.logger = logger; + session.on("subscribed", this.handleSubscribed); + session.on("event", this.handleEventData); + session.on("subscription-cancelled", this.handleSubscriptionCancelled); + } + subscribe(streamingMethod, params, targetServers, success, error, existingSub) { + if (targetServers.length === 0) { + error({ + method: streamingMethod, + called_with: params.arguments, + message: ERR_MSG_SUB_FAILED + " No available servers matched the target params.", + }); + return; + } + const subLocalKey = this.getNextSubscriptionLocalKey(); + const pendingSub = this.registerSubscription(subLocalKey, streamingMethod, params, success, error, params.methodResponseTimeout || 10000, existingSub); + if (typeof pendingSub !== "object") { + error({ + method: streamingMethod, + called_with: params.arguments, + message: ERR_MSG_SUB_FAILED + " Unable to register the user callbacks.", + }); + return; + } + targetServers.forEach((target) => { + const serverId = target.server.id; + const method = target.methods.find((m) => m.name === streamingMethod.name); + if (!method) { + this.logger.error(`can not find method ${streamingMethod.name} for target ${target.server.id}`); + return; + } + pendingSub.trackedServers.push({ + serverId, + subscriptionId: undefined, + }); + const msg = { + type: "subscribe", + server_id: serverId, + method_id: method.gatewayId, + arguments_kv: params.arguments, + }; + this.session.send(msg, { serverId, subLocalKey }) + .then((m) => this.handleSubscribed(m)) + .catch((err) => this.handleErrorSubscribing(err)); + }); + } + drainSubscriptions() { + const existing = Object.values(this.subscriptionsList); + this.subscriptionsList = {}; + this.subscriptionIdToLocalKeyMap = {}; + return existing; + } + drainSubscriptionsCache() { + return this.timedCache.flush(); + } + getNextSubscriptionLocalKey() { + const current = this.nextSubLocalKey; + this.nextSubLocalKey += 1; + return current; + } + registerSubscription(subLocalKey, method, params, success, error, timeout, existingSub) { + const subsInfo = { + localKey: subLocalKey, + status: STATUS_AWAITING_ACCEPT, + method, + params, + success, + error, + trackedServers: [], + handlers: { + onData: existingSub?.handlers.onData || [], + onClosed: existingSub?.handlers.onClosed || [], + onConnected: existingSub?.handlers.onConnected || [], + }, + queued: { + data: [], + closers: [], + }, + timeoutId: undefined, + close: () => this.closeSubscription(subLocalKey), + subscription: existingSub?.subscription + }; + if (!existingSub) { + if (params.onData) { + subsInfo.handlers.onData.push(params.onData); + } + if (params.onClosed) { + subsInfo.handlers.onClosed.push(params.onClosed); + } + if (params.onConnected) { + subsInfo.handlers.onConnected.push(params.onConnected); + } + } + this.subscriptionsList[subLocalKey] = subsInfo; + subsInfo.timeoutId = setTimeout(() => { + if (this.subscriptionsList[subLocalKey] === undefined) { + return; + } + const pendingSub = this.subscriptionsList[subLocalKey]; + if (pendingSub.status === STATUS_AWAITING_ACCEPT) { + error({ + method, + called_with: params.arguments, + message: ERR_MSG_SUB_FAILED + " Subscription attempt timed out after " + timeout + " ms.", + }); + delete this.subscriptionsList[subLocalKey]; + } + else if (pendingSub.status === STATUS_SUBSCRIBED && pendingSub.trackedServers.length > 0) { + pendingSub.trackedServers = pendingSub.trackedServers.filter((server) => { + return (typeof server.subscriptionId !== "undefined"); + }); + delete pendingSub.timeoutId; + if (pendingSub.trackedServers.length <= 0) { + this.callOnClosedHandlers(pendingSub); + delete this.subscriptionsList[subLocalKey]; + } + } + }, timeout); + return subsInfo; + } + handleErrorSubscribing = (errorResponse) => { + const tag = errorResponse._tag; + const subLocalKey = tag.subLocalKey; + const pendingSub = this.subscriptionsList[subLocalKey]; + if (typeof pendingSub !== "object") { + return; + } + pendingSub.trackedServers = pendingSub.trackedServers.filter((server) => { + return server.serverId !== tag.serverId; + }); + if (pendingSub.trackedServers.length <= 0) { + clearTimeout(pendingSub.timeoutId); + if (pendingSub.status === STATUS_AWAITING_ACCEPT) { + const reason = (typeof errorResponse.reason === "string" && errorResponse.reason !== "") ? + ' Publisher said "' + errorResponse.reason + '".' : + " No reason given."; + const callArgs = typeof pendingSub.params.arguments === "object" ? + JSON.stringify(pendingSub.params.arguments) : + "{}"; + pendingSub.error({ + message: ERR_MSG_SUB_REJECTED + reason + " Called with:" + callArgs, + called_with: pendingSub.params.arguments, + method: pendingSub.method, + }); + } + else if (pendingSub.status === STATUS_SUBSCRIBED) { + this.callOnClosedHandlers(pendingSub); + } + delete this.subscriptionsList[subLocalKey]; + } + }; + handleSubscribed = (msg) => { + const subLocalKey = msg._tag.subLocalKey; + const pendingSub = this.subscriptionsList[subLocalKey]; + if (typeof pendingSub !== "object") { + return; + } + const serverId = msg._tag.serverId; + const acceptingServer = pendingSub.trackedServers + .filter((server) => { + return server.serverId === serverId; + })[0]; + if (typeof acceptingServer !== "object") { + return; + } + acceptingServer.subscriptionId = msg.subscription_id; + this.subscriptionIdToLocalKeyMap[msg.subscription_id] = subLocalKey; + const isFirstResponse = (pendingSub.status === STATUS_AWAITING_ACCEPT); + pendingSub.status = STATUS_SUBSCRIBED; + if (isFirstResponse) { + let reconnect = false; + let sub = pendingSub.subscription; + if (sub) { + sub.setNewSubscription(pendingSub); + pendingSub.success(sub); + reconnect = true; + } + else { + sub = new UserSubscription(this.repository, pendingSub); + pendingSub.subscription = sub; + pendingSub.success(sub); + } + for (const handler of pendingSub.handlers.onConnected) { + try { + handler(sub.serverInstance, reconnect); + } + catch (e) { + } + } + } + }; + handleEventData = (msg) => { + const subLocalKey = this.subscriptionIdToLocalKeyMap[msg.subscription_id]; + if (typeof subLocalKey === "undefined") { + return; + } + const subscription = this.subscriptionsList[subLocalKey]; + if (typeof subscription !== "object") { + return; + } + const trackedServersFound = subscription.trackedServers.filter((s) => { + return s.subscriptionId === msg.subscription_id; + }); + if (trackedServersFound.length !== 1) { + return; + } + const isPrivateData = msg.oob; + const sendingServerId = trackedServersFound[0].serverId; + const server = this.repository.getServerById(sendingServerId); + const receivedStreamData = () => { + return { + data: msg.data, + server: server?.instance ?? {}, + requestArguments: subscription.params.arguments, + message: undefined, + private: isPrivateData, + }; + }; + const onDataHandlers = subscription.handlers.onData; + const queuedData = subscription.queued.data; + if (onDataHandlers.length > 0) { + onDataHandlers.forEach((callback) => { + if (typeof callback === "function") { + callback(receivedStreamData()); + } + }); + } + else { + queuedData.push(receivedStreamData()); + } + }; + handleSubscriptionCancelled = (msg) => { + const subLocalKey = this.subscriptionIdToLocalKeyMap[msg.subscription_id]; + if (typeof subLocalKey === "undefined") { + return; + } + const subscription = this.subscriptionsList[subLocalKey]; + if (typeof subscription !== "object") { + return; + } + const expectedNewLength = subscription.trackedServers.length - 1; + subscription.trackedServers = subscription.trackedServers.filter((server) => { + if (server.subscriptionId === msg.subscription_id) { + subscription.queued.closers.push(server.serverId); + return false; + } + else { + return true; + } + }); + if (subscription.trackedServers.length !== expectedNewLength) { + return; + } + if (subscription.trackedServers.length <= 0) { + this.timedCache.add(subscription); + clearTimeout(subscription.timeoutId); + this.callOnClosedHandlers(subscription); + delete this.subscriptionsList[subLocalKey]; + } + delete this.subscriptionIdToLocalKeyMap[msg.subscription_id]; + }; + callOnClosedHandlers(subscription, reason) { + const closersCount = subscription.queued.closers.length; + const closingServerId = (closersCount > 0) ? subscription.queued.closers[closersCount - 1] : null; + let closingServer; + if (closingServerId !== undefined && typeof closingServerId === "string") { + closingServer = this.repository.getServerById(closingServerId)?.instance ?? {}; + } + subscription.handlers.onClosed.forEach((callback) => { + if (typeof callback !== "function") { + return; + } + callback({ + message: reason || ON_CLOSE_MSG_SERVER_INIT, + requestArguments: subscription.params.arguments || {}, + server: closingServer, + stream: subscription.method, + }); + }); + } + closeSubscription(subLocalKey) { + const subscription = this.subscriptionsList[subLocalKey]; + if (typeof subscription !== "object") { + return; + } + subscription.trackedServers.forEach((server) => { + if (typeof server.subscriptionId === "undefined") { + return; + } + subscription.queued.closers.push(server.serverId); + this.session.sendFireAndForget({ + type: "unsubscribe", + subscription_id: server.subscriptionId, + reason_uri: "", + reason: ON_CLOSE_MSG_CLIENT_INIT, + }); + delete this.subscriptionIdToLocalKeyMap[server.subscriptionId]; + }); + subscription.trackedServers = []; + this.callOnClosedHandlers(subscription, ON_CLOSE_MSG_CLIENT_INIT); + delete this.subscriptionsList[subLocalKey]; + } + } + + class ClientProtocol { + session; + repository; + logger; + streaming; + constructor(session, repository, logger) { + this.session = session; + this.repository = repository; + this.logger = logger; + session.on("peer-added", (msg) => this.handlePeerAdded(msg)); + session.on("peer-removed", (msg) => this.handlePeerRemoved(msg)); + session.on("methods-added", (msg) => this.handleMethodsAddedMessage(msg)); + session.on("methods-removed", (msg) => this.handleMethodsRemovedMessage(msg)); + this.streaming = new ClientStreaming(session, repository, logger); + } + subscribe(stream, options, targetServers, success, error, existingSub) { + this.streaming.subscribe(stream, options, targetServers, success, error, existingSub); + } + invoke(id, method, args, target) { + const serverId = target.id; + const methodId = method.gatewayId; + const msg = { + type: "call", + server_id: serverId, + method_id: methodId, + arguments_kv: args, + }; + return this.session.send(msg, { invocationId: id, serverId }) + .then((m) => this.handleResultMessage(m)) + .catch((err) => this.handleInvocationError(err)); + } + drainSubscriptions() { + return this.streaming.drainSubscriptions(); + } + drainSubscriptionsCache() { + return this.streaming.drainSubscriptionsCache(); + } + handlePeerAdded(msg) { + const newPeerId = msg.new_peer_id; + const remoteId = msg.identity; + const isLocal = msg.meta ? msg.meta.local : true; + const pid = Number(remoteId.process); + const serverInfo = { + machine: remoteId.machine, + pid: isNaN(pid) ? remoteId.process : pid, + instance: remoteId.instance, + application: remoteId.application, + applicationName: remoteId.applicationName, + environment: remoteId.environment, + region: remoteId.region, + user: remoteId.user, + windowId: remoteId.windowId, + peerId: newPeerId, + api: remoteId.api, + isLocal + }; + this.repository.addServer(serverInfo, newPeerId); + } + handlePeerRemoved(msg) { + const removedPeerId = msg.removed_id; + const reason = msg.reason; + this.repository.removeServerById(removedPeerId, reason); + } + handleMethodsAddedMessage(msg) { + const serverId = msg.server_id; + const methods = msg.methods; + methods.forEach((method) => { + this.repository.addServerMethod(serverId, method); + }); + } + handleMethodsRemovedMessage(msg) { + const serverId = msg.server_id; + const methodIdList = msg.methods; + const server = this.repository.getServerById(serverId); + if (server) { + const serverMethodKeys = Object.keys(server.methods); + serverMethodKeys.forEach((methodKey) => { + const method = server.methods[methodKey]; + if (methodIdList.indexOf(method.gatewayId) > -1) { + this.repository.removeServerMethod(serverId, methodKey); + } + }); + } + } + handleResultMessage(msg) { + const invocationId = msg._tag.invocationId; + const result = msg.result; + const serverId = msg._tag.serverId; + const server = this.repository.getServerById(serverId); + return { + invocationId, + result, + instance: server?.instance, + status: InvokeStatus.Success, + message: "" + }; + } + handleInvocationError(msg) { + this.logger.debug(`handle invocation error ${JSON.stringify(msg)}`); + if ("_tag" in msg) { + const invocationId = msg._tag.invocationId; + const serverId = msg._tag.serverId; + const server = this.repository.getServerById(serverId); + const message = msg.reason; + const context = msg.context; + return { + invocationId, + result: context, + instance: server?.instance, + status: InvokeStatus.Error, + message + }; + } + else { + return { + invocationId: "", + message: msg.message, + status: InvokeStatus.Error, + error: msg + }; + } + } + } + + function gW3ProtocolFactory (instance, connection, clientRepository, serverRepository, libConfig, interop) { + const logger = libConfig.logger.subLogger("gw3-protocol"); + let resolveReadyPromise; + const readyPromise = new Promise((resolve) => { + resolveReadyPromise = resolve; + }); + const session = connection.domain("agm", ["subscribed"]); + const server = new ServerProtocol(session, clientRepository, serverRepository, logger.subLogger("server")); + const client = new ClientProtocol(session, clientRepository, logger.subLogger("client")); + async function handleReconnect() { + logger.info("reconnected - will replay registered methods and subscriptions"); + client.drainSubscriptionsCache().forEach((sub) => { + const methodInfo = sub.method; + const params = Object.assign({}, sub.params); + logger.info(`trying to soft-re-subscribe to method ${methodInfo.name}, with params: ${JSON.stringify(params)}`); + interop.client.subscribe(methodInfo, params, undefined, undefined, sub).then(() => logger.info(`soft-subscribing to method ${methodInfo.name} DONE`)).catch((error) => logger.warn(`subscribing to method ${methodInfo.name} failed: ${JSON.stringify(error)}}`)); + }); + const reconnectionPromises = []; + const existingSubscriptions = client.drainSubscriptions(); + for (const sub of existingSubscriptions) { + const methodInfo = sub.method; + const params = Object.assign({}, sub.params); + logger.info(`trying to re-subscribe to method ${methodInfo.name}, with params: ${JSON.stringify(params)}`); + reconnectionPromises.push(interop.client.subscribe(methodInfo, params, undefined, undefined, sub).then(() => logger.info(`subscribing to method ${methodInfo.name} DONE`))); + } + const registeredMethods = serverRepository.getList(); + serverRepository.reset(); + for (const method of registeredMethods) { + const def = method.definition; + if (method.stream) { + reconnectionPromises.push(interop.server.createStream(def, method.streamCallbacks, undefined, undefined, method.stream) + .then(() => logger.info(`subscribing to method ${def.name} DONE`)) + .catch(() => logger.warn(`subscribing to method ${def.name} FAILED`))); + } + else if (method?.theFunction?.userCallback) { + reconnectionPromises.push(interop.register(def, method.theFunction.userCallback) + .then(() => logger.info(`registering method ${def.name} DONE`)) + .catch(() => logger.warn(`registering method ${def.name} FAILED`))); + } + else if (method?.theFunction?.userCallbackAsync) { + reconnectionPromises.push(interop.registerAsync(def, method.theFunction.userCallbackAsync) + .then(() => logger.info(`registering method ${def.name} DONE`)) + .catch(() => logger.warn(`registering method ${def.name} FAILED`))); + } + } + await Promise.all(reconnectionPromises); + logger.info("Interop is re-announced"); + } + function handleInitialJoin() { + if (resolveReadyPromise) { + resolveReadyPromise({ + client, + server, + }); + resolveReadyPromise = undefined; + } + } + session.onJoined((reconnect) => { + clientRepository.addServer(instance, connection.peerId); + if (reconnect) { + handleReconnect().then(() => connection.setLibReAnnounced({ name: "interop" })).catch((error) => logger.warn(`Error while re-announcing interop: ${JSON.stringify(error)}`)); + } + else { + handleInitialJoin(); + } + }); + session.onLeft(() => { + clientRepository.reset(); + }); + session.join(); + return readyPromise; + } + + class Interop { + instance; + readyPromise; + client; + server; + unwrappedInstance; + protocol; + clientRepository; + serverRepository; + constructor(configuration) { + if (typeof configuration === "undefined") { + throw new Error("configuration is required"); + } + if (typeof configuration.connection === "undefined") { + throw new Error("configuration.connections is required"); + } + const connection = configuration.connection; + if (typeof configuration.methodResponseTimeout !== "number") { + configuration.methodResponseTimeout = 30 * 1000; + } + if (typeof configuration.waitTimeoutMs !== "number") { + configuration.waitTimeoutMs = 30 * 1000; + } + this.unwrappedInstance = new InstanceWrapper(this, undefined, connection); + this.instance = this.unwrappedInstance.unwrap(); + this.clientRepository = new ClientRepository(configuration.logger.subLogger("cRep"), this); + this.serverRepository = new ServerRepository(); + let protocolPromise; + if (connection.protocolVersion === 3) { + protocolPromise = gW3ProtocolFactory(this.instance, connection, this.clientRepository, this.serverRepository, configuration, this); + } + else { + throw new Error(`protocol ${connection.protocolVersion} not supported`); + } + this.readyPromise = protocolPromise.then((protocol) => { + this.protocol = protocol; + this.client = new Client(this.protocol, this.clientRepository, this.instance, configuration); + this.server = new Server(this.protocol, this.serverRepository); + return this; + }); + } + ready() { + return this.readyPromise; + } + serverRemoved(callback) { + return this.client.serverRemoved(callback); + } + serverAdded(callback) { + return this.client.serverAdded(callback); + } + serverMethodRemoved(callback) { + return this.client.serverMethodRemoved(callback); + } + serverMethodAdded(callback) { + return this.client.serverMethodAdded(callback); + } + methodRemoved(callback) { + return this.client.methodRemoved(callback); + } + methodAdded(callback) { + return this.client.methodAdded(callback); + } + methodsForInstance(instance) { + return this.client.methodsForInstance(instance); + } + methods(methodFilter) { + return this.client.methods(methodFilter); + } + servers(methodFilter) { + return this.client.servers(methodFilter); + } + subscribe(method, options, successCallback, errorCallback) { + return this.client.subscribe(method, options, successCallback, errorCallback); + } + createStream(streamDef, callbacks, successCallback, errorCallback) { + return this.server.createStream(streamDef, callbacks, successCallback, errorCallback); + } + unregister(methodFilter) { + return this.server.unregister(methodFilter); + } + registerAsync(methodDefinition, callback) { + return this.server.registerAsync(methodDefinition, callback); + } + register(methodDefinition, callback) { + return this.server.register(methodDefinition, callback); + } + invoke(methodFilter, argumentObj, target, additionalOptions, success, error) { + return this.client.invoke(methodFilter, argumentObj, target, additionalOptions, success, error); + } + waitForMethod(name) { + const pw = new PromiseWrapper$1(); + const unsubscribe = this.client.methodAdded((m) => { + if (m.name === name) { + unsubscribe(); + pw.resolve(m); + } + }); + return pw.promise; + } + } + + const successMessages = ["subscribed", "success"]; + class MessageBus { + connection; + logger; + peerId; + session; + subscriptions; + readyPromise; + constructor(connection, logger) { + this.connection = connection; + this.logger = logger; + this.peerId = connection.peerId; + this.subscriptions = []; + this.session = connection.domain("bus", successMessages); + this.readyPromise = this.session.join(); + this.readyPromise.then(() => { + this.watchOnEvent(); + }); + } + ready() { + return this.readyPromise; + } + publish = (topic, data, options) => { + const { routingKey, target } = options || {}; + const args = this.removeEmptyValues({ + type: "publish", + topic, + data, + peer_id: this.peerId, + routing_key: routingKey, + target_identity: target + }); + this.session.send(args); + }; + subscribe = (topic, callback, options) => { + return new Promise((resolve, reject) => { + const { routingKey, target } = options || {}; + const args = this.removeEmptyValues({ + type: "subscribe", + topic, + peer_id: this.peerId, + routing_key: routingKey, + source: target + }); + this.session.send(args) + .then((response) => { + const { subscription_id } = response; + this.subscriptions.push({ subscription_id, topic, callback, source: target }); + resolve({ + unsubscribe: () => { + this.session.send({ type: "unsubscribe", subscription_id, peer_id: this.peerId }); + this.subscriptions = this.subscriptions.filter((s) => s.subscription_id !== subscription_id); + return Promise.resolve(); + } + }); + }) + .catch((error) => reject(error)); + }); + }; + watchOnEvent = () => { + this.session.on("event", (args) => { + const { data, subscription_id } = args; + const source = args["publisher-identity"]; + const subscription = this.subscriptions.find((s) => s.subscription_id === subscription_id); + if (subscription) { + if (!subscription.source) { + subscription.callback(data, subscription.topic, source); + } + else { + if (this.keysMatch(subscription.source, source)) { + subscription.callback(data, subscription.topic, source); + } + } + } + }); + }; + removeEmptyValues(obj) { + const cleaned = {}; + Object.keys(obj).forEach((key) => { + if (obj[key] !== undefined && obj[key] !== null) { + cleaned[key] = obj[key]; + } + }); + return cleaned; + } + keysMatch(obj1, obj2) { + const keysObj1 = Object.keys(obj1); + let allMatch = true; + keysObj1.forEach((key) => { + if (obj1[key] !== obj2[key]) { + allMatch = false; + } + }); + return allMatch; + } + } + + const IOConnectCoreFactory = (userConfig, ext) => { + const iodesktop = typeof window === "object" ? (window.iodesktop ?? window.glue42gd) : undefined; + const preloadPromise = typeof window === "object" ? (window.gdPreloadPromise ?? Promise.resolve()) : Promise.resolve(); + const glueInitTimer = timer("glue"); + userConfig = userConfig || {}; + ext = ext || {}; + const internalConfig = prepareConfig$1(userConfig, ext, iodesktop); + let _connection; + let _interop; + let _logger; + let _metrics; + let _contexts; + let _bus; + let _allowTrace; + const libs = {}; + function registerLib(name, inner, t) { + _allowTrace = _logger.canPublish("trace"); + if (_allowTrace) { + _logger.trace(`registering ${name} module`); + } + const done = (e) => { + inner.initTime = t.stop(); + inner.initEndTime = t.endTime; + inner.marks = t.marks; + if (!_allowTrace) { + return; + } + const traceMessage = e ? + `${name} failed - ${e.message}` : + `${name} is ready - ${t.endTime - t.startTime}`; + _logger.trace(traceMessage); + }; + inner.initStartTime = t.startTime; + if (inner.ready) { + inner.ready() + .then(() => { + done(); + }) + .catch((e) => { + const error = typeof e === "string" ? new Error(e) : e; + done(error); + }); + } + else { + done(); + } + if (!Array.isArray(name)) { + name = [name]; + } + name.forEach((n) => { + libs[n] = inner; + IOConnectCoreFactory[n] = inner; + }); + } + function setupConnection() { + const initTimer = timer("connection"); + _connection = new Connection(internalConfig.connection, _logger.subLogger("connection")); + let authPromise = Promise.resolve(internalConfig.auth); + if (internalConfig.connection && !internalConfig.auth) { + if (iodesktop) { + authPromise = iodesktop.getGWToken() + .then((token) => { + return { + gatewayToken: token + }; + }); + } + else if (typeof window !== "undefined" && window?.glue42electron) { + if (typeof window.glue42electron.gwToken === "string") { + authPromise = Promise.resolve({ + gatewayToken: window.glue42electron.gwToken + }); + } + } + else { + authPromise = Promise.reject("You need to provide auth information"); + } + } + return authPromise + .then((authConfig) => { + initTimer.mark("auth-promise-resolved"); + let authRequest; + if (Object.prototype.toString.call(authConfig) === "[object Object]") { + authRequest = authConfig; + } + else { + throw new Error("Invalid auth object - " + JSON.stringify(authConfig)); + } + return _connection.login(authRequest); + }) + .then(() => { + registerLib("connection", _connection, initTimer); + return internalConfig; + }) + .catch((e) => { + if (_connection) { + _connection.logout(); + } + throw e; + }); + } + function setupLogger() { + const initTimer = timer("logger"); + _logger = new Logger$1(`${internalConfig.connection.identity?.application}`, undefined, internalConfig.customLogger); + _logger.consoleLevel(internalConfig.logger.console); + _logger.publishLevel(internalConfig.logger.publish); + if (_logger.canPublish("debug")) { + _logger.debug("initializing glue..."); + } + registerLib("logger", _logger, initTimer); + return Promise.resolve(undefined); + } + function setupMetrics() { + const initTimer = timer("metrics"); + const config = internalConfig.metrics; + const metricsPublishingEnabledFunc = iodesktop?.getMetricsPublishingEnabled; + const identity = internalConfig.connection.identity; + const canUpdateMetric = metricsPublishingEnabledFunc ? metricsPublishingEnabledFunc : () => true; + const disableAutoAppSystem = (typeof config !== "boolean" && config.disableAutoAppSystem) ?? false; + _metrics = metrics({ + connection: config ? _connection : undefined, + logger: _logger.subLogger("metrics"), + canUpdateMetric, + system: "Glue42", + service: identity?.service ?? iodesktop?.applicationName ?? internalConfig.application, + instance: identity?.instance ?? identity?.windowId ?? nanoid$1(10), + disableAutoAppSystem, + pagePerformanceMetrics: typeof config !== "boolean" ? config?.pagePerformanceMetrics : undefined + }); + registerLib("metrics", _metrics, initTimer); + return Promise.resolve(); + } + function setupInterop() { + const initTimer = timer("interop"); + const agmConfig = { + connection: _connection, + logger: _logger.subLogger("interop"), + }; + _interop = new Interop(agmConfig); + Logger$1.Interop = _interop; + registerLib(["interop", "agm"], _interop, initTimer); + return Promise.resolve(); + } + function setupContexts() { + const hasActivities = (internalConfig.activities && _connection.protocolVersion === 3); + const needsContexts = internalConfig.contexts || hasActivities; + if (needsContexts) { + const initTimer = timer("contexts"); + _contexts = new ContextsModule({ + connection: _connection, + logger: _logger.subLogger("contexts"), + trackAllContexts: typeof internalConfig.contexts === "object" ? internalConfig.contexts.trackAllContexts : false, + reAnnounceKnownContexts: typeof internalConfig.contexts === "object" ? internalConfig.contexts.reAnnounceKnownContexts : false + }); + registerLib("contexts", _contexts, initTimer); + return _contexts; + } + else { + const replayer = _connection.replayer; + if (replayer) { + replayer.drain(ContextMessageReplaySpec.name); + } + } + } + async function setupBus() { + if (!internalConfig.bus) { + return Promise.resolve(); + } + const initTimer = timer("bus"); + _bus = new MessageBus(_connection, _logger.subLogger("bus")); + registerLib("bus", _bus, initTimer); + return Promise.resolve(); + } + function setupExternalLibs(externalLibs) { + try { + externalLibs.forEach((lib) => { + setupExternalLib(lib.name, lib.create); + }); + return Promise.resolve(); + } + catch (e) { + return Promise.reject(e); + } + } + function setupExternalLib(name, createCallback) { + const initTimer = timer(name); + const lib = createCallback(libs); + if (lib) { + registerLib(name, lib, initTimer); + } + } + function waitForLibs() { + const libsReadyPromises = Object.keys(libs).map((key) => { + const lib = libs[key]; + return lib.ready ? + lib.ready() : Promise.resolve(); + }); + return Promise.all(libsReadyPromises); + } + function constructGlueObject() { + const feedbackFunc = (feedbackInfo) => { + if (!_interop) { + return; + } + _interop.invoke("T42.ACS.Feedback", feedbackInfo, "best"); + }; + const info = { + coreVersion: version$1, + version: internalConfig.version + }; + glueInitTimer.stop(); + const glue = { + feedback: feedbackFunc, + info, + logger: _logger, + interop: _interop, + agm: _interop, + connection: _connection, + metrics: _metrics, + contexts: _contexts, + bus: _bus, + version: internalConfig.version, + userConfig, + done: () => { + _logger?.info("done called by user..."); + return _connection.logout(); + } + }; + glue.performance = { + get glueVer() { + return internalConfig.version; + }, + get glueConfig() { + return JSON.stringify(userConfig); + }, + get browser() { + return window.performance.timing.toJSON(); + }, + get memory() { + return window.performance.memory; + }, + get initTimes() { + const all = getAllTimers(); + return Object.keys(all).map((key) => { + const t = all[key]; + return { + name: key, + duration: t.endTime - t.startTime, + marks: t.marks, + startTime: t.startTime, + endTime: t.endTime + }; + }); + } + }; + Object.keys(libs).forEach((key) => { + const lib = libs[key]; + glue[key] = lib; + }); + glue.config = {}; + Object.keys(internalConfig).forEach((k) => { + glue.config[k] = internalConfig[k]; + }); + if (ext && ext.extOptions) { + Object.keys(ext.extOptions).forEach((k) => { + glue.config[k] = ext?.extOptions[k]; + }); + } + if (ext?.enrichGlue) { + ext.enrichGlue(glue); + } + if (iodesktop && iodesktop.updatePerfData) { + iodesktop.updatePerfData(glue.performance); + } + if (glue.agm) { + const deprecatedDecorator = (fn, wrong, proper) => { + return function () { + glue.logger.warn(`glue.js - 'glue.agm.${wrong}' method is deprecated, use 'glue.interop.${proper}' instead.`); + return fn.apply(glue.agm, arguments); + }; + }; + const agmAny = glue.agm; + agmAny.method_added = deprecatedDecorator(glue.agm.methodAdded, "method_added", "methodAdded"); + agmAny.method_removed = deprecatedDecorator(glue.agm.methodRemoved, "method_removed", "methodRemoved"); + agmAny.server_added = deprecatedDecorator(glue.agm.serverAdded, "server_added", "serverAdded"); + agmAny.server_method_aded = deprecatedDecorator(glue.agm.serverMethodAdded, "server_method_aded", "serverMethodAdded"); + agmAny.server_method_removed = deprecatedDecorator(glue.agm.serverMethodRemoved, "server_method_removed", "serverMethodRemoved"); + } + return glue; + } + async function registerInstanceIfNeeded() { + const RegisterInstanceMethodName = "T42.ACS.RegisterInstance"; + if (Utils$1.isNode() && typeof process.env._GD_STARTING_CONTEXT_ === "undefined" && typeof userConfig?.application !== "undefined") { + const isMethodAvailable = _interop.methods({ name: RegisterInstanceMethodName }).length > 0; + if (isMethodAvailable) { + try { + await _interop.invoke(RegisterInstanceMethodName, { appName: userConfig?.application, pid: process.pid }); + } + catch (error) { + const typedError = error; + _logger.error(`Cannot register as an instance: ${JSON.stringify(typedError.message)}`); + } + } + } + } + return preloadPromise + .then(setupLogger) + .then(setupConnection) + .then(() => Promise.all([setupMetrics(), setupInterop(), setupContexts(), setupBus()])) + .then(() => _interop.readyPromise) + .then(() => registerInstanceIfNeeded()) + .then(() => { + return setupExternalLibs(internalConfig.libs || []); + }) + .then(waitForLibs) + .then(constructGlueObject) + .catch((err) => { + return Promise.reject({ + err, + libs + }); + }); + }; + if (typeof window !== "undefined") { + window.IOConnectCore = IOConnectCoreFactory; + } + IOConnectCoreFactory.version = version$1; + IOConnectCoreFactory.default = IOConnectCoreFactory; + + class ActivityEntity { + constructor(id) { + this._id = id; + } + get id() { + return this._id; + } + _update(other) { + if (other._id !== this._id) { + throw Error("Can not update from entity with different id."); + } + this._updateCore(other); + } + _updateCore(other) { + return; + } + _beforeDelete(other) { + return; + } + } + + function isNumber(arg) { + return typeof arg === "number"; + } + function isString(arg) { + return typeof arg === "string"; + } + function isObject(arg) { + return typeof arg === "object" && !Array.isArray(arg) && arg !== null; + } + function isArray(arg) { + if (Array.isArray) { + return Array.isArray(arg); + } + return toString.call(arg) === "[object Array]"; + } + function isUndefined(arg) { + return typeof arg === "undefined"; + } + function isUndefinedOrNull(arg) { + return arg === null || typeof arg === "undefined"; + } + function isNullOrWhiteSpace(str) { + return (typeof str !== "string" || !str || str.length === 0 || /^\s*$/.test(str)); + } + function isBoolean(obj) { + return obj === true || obj === false || toString.call(obj) === "[object Boolean]"; + } + function isFunction(arg) { + return !!(arg && arg.constructor && arg.call && arg.apply); + } + function some(array, predicate) { + for (let index = 0; index < array.length; index++) { + if (predicate(array[index], index)) { + return true; + } + } + return false; + } + function ifNotUndefined(what, doWithIt) { + if (typeof what !== "undefined") { + doWithIt(what); + } + } + function promisify$1(promise, successCallback, errorCallback) { + if (typeof successCallback !== "function" && typeof errorCallback !== "function") { + return promise; + } + if (typeof successCallback !== "function") { + successCallback = () => { return; }; + } + else if (typeof errorCallback !== "function") { + errorCallback = () => { return; }; + } + promise.then(successCallback, errorCallback); + } + + class ActivityType extends ActivityEntity { + constructor(name, ownerWindow, helperWindows, description) { + super(name); + this._name = name; + this._description = description; + this._ownerWindow = ownerWindow; + this._helperWindows = helperWindows || []; + } + get name() { + return this._name; + } + get description() { + return this._description; + } + get helperWindows() { + return this._helperWindows.map((hw) => this.covertToWindowDef(hw)); + } + get ownerWindow() { + return this.covertToWindowDef(this._ownerWindow); + } + initiate(context, callback, configuration) { + return this._manager.initiate(this._name, context, callback, configuration); + } + _updateCore(other) { + super._updateCore(other); + ifNotUndefined(other._description, (x) => this._description = x); + ifNotUndefined(other._ownerWindow, (x) => this._ownerWindow = x); + ifNotUndefined(other._helperWindows, (x) => this._helperWindows = x); + } + covertToWindowDef(windowType) { + var _a, _b; + return { + type: (_a = windowType === null || windowType === void 0 ? void 0 : windowType.id) === null || _a === void 0 ? void 0 : _a.type, + name: (_b = windowType === null || windowType === void 0 ? void 0 : windowType.id) === null || _b === void 0 ? void 0 : _b.name + }; + } + } + + class WindowType extends ActivityEntity { + constructor(name, appByWindowTypeGetter) { + super(name); + this._name = name; + this._appByWindowTypeGetter = appByWindowTypeGetter; + } + get name() { + return this._name; + } + get config() { + return this._appByWindowTypeGetter(this._name); + } + get windows() { + return this._manager.getWindows({ type: this._name }); + } + create(activity, configuration) { + const definition = Object.assign({ type: this.name, name: this.name, isIndependent: false }, configuration); + return this._manager.createWindow(activity, definition); + } + } + + class EntityEvent { + constructor(entitiy, context) { + this.entity = entitiy; + this.context = context; + } + } + class EntityEventContext { + constructor(eventType) { + this.type = eventType; + } + } + class ActivityStatusChangeEventContext extends EntityEventContext { + constructor(newStatus, oldStatus) { + super(EntityEventType.StatusChange); + this.newStatus = newStatus; + this.oldStatus = oldStatus; + } + } + class ActivityContextChangedEventContext extends EntityEventContext { + constructor(context, updated, removed) { + super(EntityEventType.ActivityContextChange); + this.context = typeof context === "string" ? JSON.parse(context) : context; + this.updated = updated; + this.removed = removed; + } + } + class EntityEventType { + } + EntityEventType.Added = "added"; + EntityEventType.Removed = "removed"; + EntityEventType.Updated = "updated"; + EntityEventType.Closed = "closed"; + EntityEventType.StatusChange = "statusChange"; + EntityEventType.ActivityContextChange = "activityContextUpdate"; + EntityEventType.ActivityWindowEvent = "activityWindowEvent"; + EntityEventType.ActivityWindowJoinedActivity = "joined"; + EntityEventType.ActivityWindowLeftActivity = "left"; + class ActivityState { + } + ActivityState.Created = "created"; + ActivityState.Started = "started"; + ActivityState.Destroyed = "destroyed"; + + class ActivityAGM { + constructor(activity) { + this._activity = activity; + } + register(definition, handler) { + this._ensureHasAgm(); + ActivityAGM.AGM.register(definition, handler); + } + servers() { + this._ensureHasAgm(); + if (isUndefinedOrNull(this._activity)) { + return []; + } + return this._activity.windows.map((w) => { + return w.instance; + }); + } + methods() { + this._ensureHasAgm(); + if (isUndefinedOrNull(this._activity)) { + return []; + } + const windows = this._activity.windows; + const methodNames = []; + const methods = []; + windows.forEach((window) => { + const windowMethods = this.methodsForWindow(window); + windowMethods.forEach((currentWindowMethod) => { + if (methodNames.indexOf(currentWindowMethod.name) === -1) { + methodNames.push(currentWindowMethod.name); + methods.push(currentWindowMethod); + } + }); + }); + return methods; + } + methodsForWindow(window) { + this._ensureHasAgm(); + if (!window.instance) { + return []; + } + return ActivityAGM.AGM.methodsForInstance(window.instance); + } + invoke(methodName, arg, target, options, success, error) { + this._ensureHasAgm(); + const activityServers = this.servers(); + if (isUndefinedOrNull(target)) { + target = "activity.all"; + } + if (isString(target)) { + if (target === "activity.all") ; + else if (target === "activity.best") { + const potentialTargets = activityServers.filter((server) => { + const methods = ActivityAGM.AGM.methodsForInstance(server); + return methods.filter((m) => { + return m.name === methodName; + }).length > 0; + }); + if (potentialTargets.length > 0) { + [potentialTargets[0]]; + } + } + else if (target === "all" || target === "best") { + return promisify$1(ActivityAGM.AGM.invoke(methodName, arg, target, options), success, error); + } + else { + throw new Error("Invalid invoke target " + target); + } + } + else if (isArray(target)) { + if (target.length >= 0) { + const firstElem = target[0]; + if (this._isInstance(firstElem)) { + target.map((instance) => instance); + } + else if (this._isActivityWindow(firstElem)) { + target.map((win) => win.instance); + } + else { + throw new Error("Unknown target object"); + } + } + } + else { + if (this._isInstance(target)) ; + else if (this._isActivityWindow(target)) { + [target.instance]; + } + else { + throw new Error("Unknown target object"); + } + } + throw new Error("Not implemented"); + } + unregister(definition) { + this._ensureHasAgm(); + return ActivityAGM.AGM.unregister(definition); + } + createStream(methodDefinition, subscriptionAddedHandler, subscriptionRemovedHandler) { + this._ensureHasAgm(); + ActivityAGM.AGM.createStream(methodDefinition, { + subscriptionAddedHandler, + subscriptionRemovedHandler, + subscriptionRequestHandler: undefined + }); + } + subscribe(methodDefinition, parameters, target) { + this._ensureHasAgm(); + return ActivityAGM.AGM.subscribe(methodDefinition, parameters); + } + _ensureHasAgm() { + if (isUndefinedOrNull(ActivityAGM.AGM)) { + throw new Error("Agm should be configured to be used in activity"); + } + } + _isInstance(obj) { + return obj.application !== undefined; + } + _isActivityWindow(obj) { + return obj.instance !== undefined; + } + } + + class AttachedActivityDescriptor { + constructor(manager, ownerActivityId, state) { + this._manager = manager; + this._ownerActivityId = ownerActivityId; + this._state = state; + } + get ownerId() { + return this._state.ownerId; + } + get windowIds() { + return this._state.windowIds; + } + get frameColor() { + return this._state.frameColor; + } + get context() { + return this._state.context; + } + get tag() { + return this._state.tag; + } + detach(descriptor) { + descriptor = descriptor || {}; + const merged = {}; + Object.keys(this._state).forEach((prop) => { + merged[prop] = this._state[prop]; + }); + merged.context = descriptor.context || merged.context; + merged.frameColor = descriptor.frameColor || merged.frameColor; + return this._manager.detachActivities(this._ownerActivityId, merged); + } + } + + const nextTick = (cb) => { + setTimeout(cb, 0); + }; + function nodeify(promise, callback) { + if (!isFunction(callback)) { + return promise; + } + promise.then((resp) => { + nextTick(() => { + callback(null, resp); + }); + }, (err) => { + nextTick(() => { + callback(err, null); + }); + }); + } + + class Activity extends ActivityEntity { + constructor(id, actType, status, context, ownerId) { + super(id); + this._id = id; + this._actType = actType; + this._status = status; + this._context = context; + this._ownerId = ownerId; + this._agm = new ActivityAGM(this); + } + get type() { + if (this._manager) { + return this._manager.getActivityType(this._actType); + } + return undefined; + } + get context() { + return this._context; + } + get status() { + return this._status; + } + get owner() { + if (!this._ownerId) { + return null; + } + return this._manager.getWindows({ id: this._ownerId })[0]; + } + get windows() { + return this._manager.getWindows({ activityId: this._id }); + } + get agm() { + return this._agm; + } + addWindow(window, callback) { + return this._manager.addWindowToActivity(this, window, callback); + } + createWindow(windowType, callback) { + return this._manager.createWindow(this, windowType, callback); + } + createStackedWindows(windowTypes, timeout, callback) { + return this._manager.createStackedWindows(this, windowTypes, timeout, callback); + } + leave(window, callback) { + return this._manager.leaveWindowFromActivity(this, window, callback); + } + getWindowsByType(windowType) { + const filter = { activityId: this._id, type: windowType }; + return this._manager.getWindows(filter); + } + setContext(context, callback) { + return this._manager.setActivityContext(this, context, callback); + } + updateContext(context, callback) { + return this._manager.updateActivityContext(this, context, callback); + } + onStatusChange(handler) { + return this._manager.subscribeActivityEvents((a, ns, os) => { + if (a.id === this.id) { + handler(a, ns, os); + } + }); + } + onWindowEvent(handler) { + return this._manager.subscribeWindowEvents((a, w, e) => { + if (a.id === this.id) { + handler(a, w, e); + } + }); + } + onContextChanged(handler) { + this._manager.subscribeActivityContextChanged((act, context, updated, removed) => { + if (act.id === this.id) { + handler(context, updated, removed, act); + } + }); + try { + handler(this.context, this.context, [], this); + } + catch (e) { + return; + } + } + stop() { + this._manager.stopActivity(this); + } + clone(options) { + return this._manager.clone(this, options); + } + attach(activity, tag) { + let activityId; + if (typeof activity === "string") { + activityId = activity; + } + else { + activityId = activity.id; + } + return this._manager.attachActivities(activityId, this.id, tag); + } + onActivityAttached(callback) { + this._manager.subscribeActivitiesAttached((newActId, oldActId, descriptor) => { + if (newActId !== this._id) { + return; + } + callback(descriptor); + }); + } + onDetached(callback) { + this._manager.subscribeActivitiesDetached((newAct, originalActivity, state) => { + if (originalActivity.id !== this._id) { + return; + } + callback(newAct, state); + }); + } + _updateCore(other) { + super._updateCore(other); + ifNotUndefined(other._actType, (x) => this._actType = x); + ifNotUndefined(other._context, (x) => this._context = x); + ifNotUndefined(other._ownerId, (x) => this._ownerId = x); + if (other._status && (!this._status || (this._status.state !== other._status.state))) { + this._status = other._status; + } + } + _updateDescriptors(allStates) { + this._attached = allStates.map((s) => { + return new AttachedActivityDescriptor(this._manager, this._id, s); + }); + } + get attached() { + return this._attached; + } + setFrameColor(color, callback) { + const promise = new Promise((resolve, reject) => { + let callbacksToWait = this.windows.length; + if (callbacksToWait === 0) { + resolve(this); + } + this.windows.forEach((w) => { + w.underlyingWindow.setFrameColor(color, () => { + callbacksToWait--; + if (callbacksToWait <= 0) { + resolve(this); + } + }); + }); + setTimeout(() => { + if (callbacksToWait > 0) { + reject(this.id + " - timed out waiting for setFrameColor with" + color); + } + }, 5000); + }); + return nodeify(promise, callback); + } + getFrameColor() { + if (!this.windows || this.windows.length === 0) { + return ""; + } + return this.windows[0].underlyingWindow.frameColor; + } + } + + class LogLevel { + } + LogLevel.Trace = "trace"; + LogLevel.Debug = "debug"; + LogLevel.Info = "info"; + LogLevel.Warn = "warn"; + LogLevel.Error = "error"; + class Logger { + static GetNamed(name) { + return new Logger(name); + } + static Get(owner) { + return new Logger(Logger.GetTypeName(owner)); + } + constructor(name) { + this._name = name; + if (!isUndefinedOrNull(Logger.GlueLogger)) { + this._glueLogger = Logger.GlueLogger.subLogger(name); + } + } + trace(message) { + if (!isUndefinedOrNull(this._glueLogger)) { + this._glueLogger.trace(message); + } + else { + if (Logger.Level === LogLevel.Trace) { + console.info(this._getMessage(message, LogLevel.Trace)); + } + } + } + debug(message) { + if (!isUndefinedOrNull(this._glueLogger)) { + this._glueLogger.debug(message); + } + else { + if (Logger.Level === LogLevel.Debug || + Logger.Level === LogLevel.Trace) { + console.info(this._getMessage(message, LogLevel.Debug)); + } + } + } + info(message) { + if (!isUndefinedOrNull(this._glueLogger)) { + this._glueLogger.info(message); + } + else { + if (Logger.Level === LogLevel.Debug || + Logger.Level === LogLevel.Trace || + Logger.Level === LogLevel.Info) { + console.info(this._getMessage(message, LogLevel.Info)); + } + } + } + warn(message) { + if (!isUndefinedOrNull(this._glueLogger)) { + this._glueLogger.warn(message); + } + else { + if (Logger.Level === LogLevel.Debug || + Logger.Level === LogLevel.Trace || + Logger.Level === LogLevel.Info || + Logger.Level === LogLevel.Warn) { + console.info(this._getMessage(message, LogLevel.Info)); + } + } + } + error(message) { + if (!isUndefinedOrNull(this._glueLogger)) { + this._glueLogger.error(message); + } + else { + console.error(this._getMessage(message, LogLevel.Error)); + console.trace(); + } + } + _getMessage(message, level) { + return "[" + level + "] " + this._name + " - " + message; + } + static GetTypeName(object) { + const funcNameRegex = /function (.{1,})\(/; + const results = (funcNameRegex).exec(object.constructor.toString()); + return (results && results.length > 1) ? results[1] : ""; + } + } + Logger.Level = LogLevel.Info; + + class ActivityWindow extends ActivityEntity { + constructor(id, name, type, activityId, instance, isIndependent, windowGetter, hcWindowId) { + super(id); + this._logger = Logger.Get("window"); + this._type = type; + this._activityId = activityId; + this._name = name; + this._instance = instance; + this._isIndependent = isIndependent; + this._windowGetter = windowGetter; + this._hcWindowId = hcWindowId; + } + getBounds() { + return this._manager.getWindowBounds(this.id); + } + get name() { + return this._name; + } + get isIndependent() { + return this._isIndependent; + } + get type() { + if (this._manager) { + return this._manager.getWindowType(this._type); + } + return undefined; + } + get activity() { + if (isUndefined(this._activityId)) { + return undefined; + } + return this._manager.getActivityById(this._activityId); + } + get isOwner() { + const act = this.activity; + if (isUndefined(act)) { + return false; + } + return act.owner.id === this.id; + } + setVisible(isVisible, callback) { + return this._manager.setWindowVisibility(this.id, isVisible); + } + activate(focus) { + return this._manager.activateWindow(this.id, focus); + } + setBounds(bounds, callback) { + return this._manager.setWindowBounds(this.id, bounds, callback); + } + close() { + return this._manager.closeWindow(this.id); + } + get instance() { + return this._instance; + } + get underlyingWindow() { + const window = this._windowGetter(); + if (!window) { + return { + id: this._hcWindowId + }; + } + return window; + } + onActivityJoined(callback) { + this._subscribeForActivityWindowEvent(EntityEventType.ActivityWindowJoinedActivity, callback); + } + onActivityRemoved(callback) { + this._subscribeForActivityWindowEvent(EntityEventType.ActivityWindowLeftActivity, callback); + } + _updateCore(other) { + ifNotUndefined(other._activityId, (x) => this._activityId = x); + ifNotUndefined(other._isIndependent, (x) => this._isIndependent = x); + ifNotUndefined(other._hcWindowId, (x) => this._hcWindowId = x); + ifNotUndefined(other._type, (x) => this._type = x); + ifNotUndefined(other._name, (x) => this._name = x); + if (!isUndefinedOrNull(other._instance)) { + this._instance = other._instance; + } + } + _subscribeForActivityWindowEvent(eventName, callback) { + this._manager.subscribeWindowEvents((activity, window, event) => { + if (window.id !== this.id) { + return; + } + if (event === eventName) { + callback(activity); + } + }); + } + _beforeDelete(other) { + this._hcWindowId = other._hcWindowId; + } + } + + class ActivityStatus { + constructor(state, message, time) { + this.state = state; + this.message = message; + this.time = time; + } + getState() { + return this.state; + } + getMessage() { + return this.message; + } + getTime() { + return this.time; + } + } + + const gwMmessageError = "error"; + const gwMessageAddActivityTypes = "add-types"; + const gwMmessageActivityTypesAdded = "types-added"; + const gwMessageRemoveActivityTypes = "remove-types"; + const gwMessageActivityTypesRemoved = "types-removed"; + const gwMessageActivityCreated = "created"; + const gwMessageActivityDestroyed = "destroyed"; + const gwMessageActivityInitiated = "initiated"; + const gwMmessageJoinActivity = "join-activity"; + const gwMessageJoinedActivity = "joined"; + const gwMessageActivityJoined = "activity-joined"; + const gwMessageLeaveActivity = "leave-activity"; + const gwMessageActivityLeft = "left"; + const gwNmessageMergeActivities = "merge"; + const gwMessageSplitActivities = "split"; + const gwMessageOwnerChanged = "owner-changed"; + const gwMessageAddPeerFactories = "add-peer-factories"; + const gwMessagePeerFactoriesAdded = "peer-factories-added"; + const gwMessageRemovePeerFactories = "remove-peer-factories"; + const gwMessagePeerFactoriesRemoved = "peer-factories-removed"; + const gwMessageCreateActivity = "create"; + const gwMessageCreatePeer = "create-peer"; + const gwMessagePeerRequested = "peer-requested"; + const gwMessageReady = "ready"; + const gwMessagePeerCreated = "peer-created"; + const gwMessageDestroyActivity = "destroy"; + const gwMessageDisposePeer = "dispose-peer"; + const gwMessageDestroyPeer = "destroy-peer"; + class GW3Bridge { + static activityTypeGwMessageEntityToActivityType(entity, description) { + const nameToWindowType = (windowName) => new WindowType(windowName, undefined); + return new ActivityType(entity.name, entity.owner_type && nameToWindowType(entity.owner_type), entity.helper_types && entity.helper_types.map(nameToWindowType), description); + } + static peerFactoryGwMessageEntityToWindowType(entity) { + return new WindowType(entity.peer_type, (_) => undefined); + } + static activityGwMessageToActivity(msg, status) { + const ownerId = msg.owner !== undefined ? msg.owner.peer_id : msg.owner_id; + return new Activity(msg.activity_id, msg.activity_type, status, msg.context_snapshot, ownerId); + } + static activityToActivityStatusChangeEvent(act) { + return new EntityEvent(act, new ActivityStatusChangeEventContext(act.status, undefined)); + } + constructor(config) { + this._activityChangeCallbacks = []; + this._activityTypeStatusChangeCallbacks = []; + this._activityWindowChangeCallbacks = []; + this._windowTypeStatusChangeCallbacks = []; + this._peerIdAndFactoryIdToPeerType = {}; + this._peerFactoriesRegisteredByUs = {}; + this._gw3Subscriptions = []; + this._contextSubscriptions = {}; + this._activityTypesInitiatedFromMe = {}; + this._config = config; + this._connection = config.connection; + this._logger = config.logger; + this._contexts = config.contexts; + this._windows = config.windows; + this._sessionJoinedPromise = new Promise((resolve) => { + this._sessionJoinedPromiseResolve = resolve; + }); + this._activityJoinedPromise = new Promise((resolve) => { + this._activityJoinedPromiseResolve = resolve; + }); + if (!this._config.activityId) { + this._activityJoinedPromiseResolve({}); + } + this._gw3Session = this._connection.domain("activity", ["joined", "initiated", "peer-created", "token"]); + if (typeof window !== "undefined") { + const glue42gd = (window).glue42gd; + if (glue42gd && glue42gd.activityInfo) { + if (typeof glue42gd.addRefreshHandler === "function") { + glue42gd.addRefreshHandler((success, error) => { + this._gw3Session + .send({ + type: "reload" + }) + .then((msg) => { + if (!msg.token) { + error("Expected gateway token for refreshing."); + return; + } + try { + glue42gd.setGWToken(msg.token); + } + catch (e) { + error(e.message || e); + return; + } + success(); + }, error); + }); + } + if (glue42gd && typeof glue42gd.addWillNavigateHandler === "function") { + glue42gd.addWillNavigateHandler((success, error) => { + this._gw3Session + .send({ + type: "reload" + }) + .then((msg) => { + if (!msg.token) { + error("Expected gateway token for refreshing."); + return; + } + try { + glue42gd.setGWToken(msg.token); + } + catch (e) { + error(e.message || e); + return; + } + success(); + }, error); + }); + } + } + } + } + get bridgeType() { + return "GW3"; + } + init() { + this.forwardActivityTypeMessagesToStatusEventHandlers(); + this.subscribe(gwMessageActivityCreated, this.handleActivityCreatedMessage); + this.subscribe(gwMessageActivityDestroyed, this.handleActivityDestroyedMessage); + this.forwardActivityMessagesToStatusEventHandlers(); + this.forwardActivityCreatedAndJoinedActivityToActivityWindowEventHandlers(); + this.forwardPeerFactoryMessagesToStatusEventHandlers(); + this.forwardPeerFactoryMessagesToPeerFactoryRequests(); + this.subscribe(gwMessagePeerFactoriesAdded, this.handlePeerFactoriesAdded); + this.subscribe(gwMessagePeerFactoriesRemoved, this.handlePeerFactoriesRemoved); + this.forwardActivityWindowMessagesToEventHandlers(); + this.subscribe(gwMessageDisposePeer, () => { + if (this._config.disposeRequestHandling === "dispose") { + this.dispose(); + return; + } + if (this._config.disposeRequestHandling === "exit") { + if (this._windows && typeof this._windows.my() !== "undefined") { + this._windows.my().close(); + return; + } + if (typeof window !== "undefined" && typeof (window).close === "function") { + window.close(); + return; + } + if (typeof process !== "undefined" && typeof (process).exit === "function") { + process.exit(); + return; + } + } + }); + this._gw3Session.onJoined(() => { + if (this._config.mode === "trackMyOnly" || + this._config.mode === "trackMyTypeAndInitiatedFromMe") { + this._sessionJoinedPromiseResolve(this); + } + else { + this._gw3Session + .send({ + type: "subscribe", + activity_types: (this._config.mode === "trackAll" ? [] : + this._config.mode === "trackTypes" ? this._config.typesToTrack : []) + }) + .then(() => { + this._sessionJoinedPromiseResolve(this); + }); + } + }); + this._gw3Session.join(); + } + dispose() { + this._gw3Subscriptions.forEach((sub) => sub && this._connection.off(sub)); + this._gw3Subscriptions.length = 0; + } + ready() { + return Promise.all([this._sessionJoinedPromise, this._activityJoinedPromise]); + } + initReady() { + return this._sessionJoinedPromise; + } + onActivityTypeStatusChange(callback) { + this._activityTypeStatusChangeCallbacks.push(callback); + } + registerActivityType(activityTypeName, ownerWindow, helperWindows, config, description) { + const entity = {}; + entity.name = activityTypeName; + const toActivityPeerConfig = (windowDefinition) => ({ type: windowDefinition.type, name: windowDefinition.name, configuration: windowDefinition }); + entity.owner_type = toActivityPeerConfig(ownerWindow); + entity.helper_types = helperWindows.map(toActivityPeerConfig); + return this._gw3Session + .send({ + type: gwMessageAddActivityTypes, + types: [entity] + }) + .then(() => { + const activityType = GW3Bridge.activityTypeGwMessageEntityToActivityType(entity, description); + this.invokeCallbacks(this._activityTypeStatusChangeCallbacks, new EntityEvent(activityType, new EntityEventContext(EntityEventType.Added)), gwMessageAddActivityTypes); + return activityType; + }); + } + unregisterActivityType(activityTypeName) { + return this._gw3Session + .send({ + type: gwMessageRemoveActivityTypes, + types: [activityTypeName] + }) + .then(() => { + const activityType = new ActivityType(activityTypeName, undefined, undefined, undefined); + this.invokeCallbacks(this._activityTypeStatusChangeCallbacks, new EntityEvent(activityType, new EntityEventContext(EntityEventType.Removed)), gwMessageAddActivityTypes); + }); + } + onWindowTypeStatusChange(callback) { + this._windowTypeStatusChangeCallbacks.push(callback); + } + registerWindowFactory(windowType, factory, parameters) { + if (this._peerFactoriesRegisteredByUs[windowType]) { + return Promise.reject(new Error(`Factory for windowType ${windowType} already registered.`)); + } + this._peerFactoriesRegisteredByUs[windowType] = factory; + const entity = { + id: windowType, + peer_type: windowType, + configuration: parameters + }; + return this._gw3Session.send({ + type: gwMessageAddPeerFactories, + factories: [entity] + }) + .then(() => { + this.invokeCallbacks(this._windowTypeStatusChangeCallbacks, new EntityEvent(GW3Bridge.peerFactoryGwMessageEntityToWindowType(entity), new EntityEventContext(EntityEventType.Added)), gwMessageAddPeerFactories); + }) + .catch(() => { + delete this._peerFactoriesRegisteredByUs[windowType]; + }); + } + unregisterWindowFactory(windowType) { + const factory = this._peerFactoriesRegisteredByUs[windowType]; + if (!factory) { + return Promise.reject(new Error(`Factory for windowType ${windowType} not registered.`)); + } + delete this._peerFactoriesRegisteredByUs[windowType]; + return this._gw3Session.send({ + type: gwMessageRemovePeerFactories, + factory_ids: [windowType] + }).then(() => { + this.invokeCallbacks(this._windowTypeStatusChangeCallbacks, new EntityEvent(new WindowType(windowType, undefined), new EntityEventContext(EntityEventType.Removed)), gwMessageAddPeerFactories); + }); + } + onActivityStatusChange(callback) { + this._activityChangeCallbacks.push(callback); + } + initiateActivity(activityType, context, configuration) { + const initiateMsg = { + type: gwMessageCreateActivity, + activity_type: activityType, + initial_context: context, + }; + if (this.isOverrideTypeDefinition(configuration)) { + initiateMsg.types_override = { + owner_type: { type: configuration.owner.type, name: configuration.owner.name, configuration: configuration.owner }, + helper_types: configuration.helpers && configuration.helpers.map((wd) => ({ type: wd.type, name: wd.name, configuration: wd })) + }; + } + else { + initiateMsg.configuration = configuration && configuration.map((wd) => ({ type: wd.type, name: wd.name, configuration: wd })); + } + return this.sendCreateAndMapResultingMessagesToPromise(initiateMsg, gwMessageActivityInitiated, (msg, requestId) => msg.request_id === requestId, gwMessageActivityCreated, (msg, requestId, initMsg) => msg.activity_id === initMsg.activity_id, gwMessageActivityDestroyed, (msg, requestId, initMsg) => msg.activity_id === initMsg.activity_id, (msg) => msg.activity_id, null).then((id) => { + if (this._config.mode === "trackMyTypeAndInitiatedFromMe") { + if (!this._activityTypesInitiatedFromMe[activityType]) { + this._activityTypesInitiatedFromMe[activityType] = true; + return this._gw3Session + .send({ + type: "subscribe", + activity_types: [activityType] + }) + .then(() => { + return id; + }); + } + } + return id; + }); + } + stopActivity(activity) { + return this._gw3Session.send({ + type: gwMessageDestroyActivity, + activity_id: activity.id, + reason_uri: "com.tick42.glue.activity.constants.destroyReason.general", + reason: "Destroying activity" + }).then((_) => true); + } + updateActivityContext(activity, context, fullReplace, removedKeys) { + if (fullReplace) { + return this._contexts.set(activity.id, context); + } + else { + removedKeys = removedKeys || []; + for (const x of removedKeys) { + context[x] = null; + } + return this._contexts.update(activity.id, context); + } + } + announceWindow(windowType, activityWindowId) { + throw new Error("Invalid operation 'announceWindow' for GW3 protocol"); + } + registerWindow(type, name, independent) { + let shouldSendReady = typeof this._connection.gatewayToken !== "undefined"; + const peerId = this._connection.peerId; + if (typeof window !== "undefined") { + const glue42gd = window.glue42gd; + if (glue42gd) { + shouldSendReady = typeof glue42gd.activityInfo !== "undefined"; + } + } + if (shouldSendReady) { + this._gw3Session.send({ + type: gwMessageReady, + }); + } + this.invokeCallbacks(this._activityWindowChangeCallbacks, new EntityEvent(new ActivityWindow(peerId, name, type, undefined, this.getAgmInstance(peerId), independent, this.generateWindowGetter(peerId), undefined), new EntityEventContext(EntityEventType.Added)), "register window"); + return Promise.resolve(peerId); + } + onActivityWindowChange(callback) { + this._activityWindowChangeCallbacks.push(callback); + } + createWindow(activityId, windowDefinition) { + if (!windowDefinition.layout) { + if (windowDefinition.left || windowDefinition.width || windowDefinition.height || windowDefinition.top) { + windowDefinition.layout = { + mode: "pixels", + cellSize: 1, + }; + } + } + const joinPeer = (id) => { + if (!activityId) { + return; + } + return this.joinActivity(activityId, id, windowDefinition.name) + .then(() => { + return id; + }); + }; + return this.sendCreateAndMapResultingMessagesToPromise({ + type: gwMessageCreatePeer, + peer_type: windowDefinition.type, + peer_name: windowDefinition.name || windowDefinition.type, + configuration: windowDefinition, + activity_id: activityId, + }, undefined, undefined, gwMessagePeerCreated, (msg, requestId) => msg.request_id === requestId, undefined, undefined, (msg) => msg.created_id, joinPeer) + .then(joinPeer); + } + async closeWindow(id) { + await this._gw3Session.send({ + type: gwMessageDestroyPeer, + destroy_peer_id: id + }); + } + getAnnouncementInfo() { + let activityId = this._config.activityId || (this._config.announcementInfo && this._config.announcementInfo.activityId); + let activityWindowType = (this._config.announcementInfo && this._config.announcementInfo.activityWindowType); + let activityWindowIndependent = (this._config.announcementInfo && this._config.announcementInfo.activityWindowIndependent); + let activityWindowName = (this._config.announcementInfo && this._config.announcementInfo.activityWindowName); + if (typeof window !== "undefined" && + typeof window.location !== "undefined" && + window.location.search && + typeof URLSearchParams === "function") { + const searchParams = new URLSearchParams(location.search.slice(1)); + activityWindowType = activityWindowType || searchParams.get("t42PeerType"); + activityWindowType = activityWindowType || searchParams.get("t42ActivityWindowType"); + if (typeof activityWindowIndependent === "undefined") { + activityWindowIndependent = searchParams.get("t42ActivityWindowIndependent"); + } + activityWindowName = activityWindowName || searchParams.get("t42ActivityWindowName"); + activityId = activityId || searchParams.get("t42ActivityId"); + } + activityWindowType = activityWindowType || "unknown"; + activityWindowIndependent = activityWindowIndependent || false; + activityWindowName = activityWindowName || this._connection.peerId; + return { + activityWindowId: undefined, + activityId, + activityWindowType, + activityWindowIndependent, + activityWindowName, + }; + } + joinActivity(activityId, windowId, name) { + const maybeName = (name && { name }) || {}; + return this._gw3Session.send({ + type: gwMmessageJoinActivity, + target_id: windowId, + activity_id: activityId, + ...maybeName + }).then(() => { + this.invokeCallbacks(this._activityWindowChangeCallbacks, new EntityEvent(new ActivityWindow(windowId, undefined, undefined, activityId, this.getAgmInstance(windowId), undefined, this.generateWindowGetter(windowId), undefined), new EntityEventContext(EntityEventType.ActivityWindowJoinedActivity)), "activity joined - ActivityWindow"); + this.invokeCallbacks(this._activityChangeCallbacks, new EntityEvent(new Activity(activityId, undefined, new ActivityStatus("created", undefined, undefined), undefined, undefined), new EntityEventContext(EntityEventType.Updated)), "activity joined - Activity"); + }); + } + leaveActivity(activityId, windowId) { + return this._gw3Session.send({ + type: gwMessageLeaveActivity, + target_id: windowId, + activity_id: activityId + }).then(() => { + this.invokeCallbacks(this._activityWindowChangeCallbacks, new EntityEvent(new ActivityWindow(windowId, undefined, undefined, null, this.getAgmInstance(windowId), undefined, this.generateWindowGetter(windowId), undefined), new EntityEventContext(EntityEventType.ActivityWindowLeftActivity)), "activity left - ActivityWindow"); + this.invokeCallbacks(this._activityChangeCallbacks, new EntityEvent(new Activity(activityId, undefined, new ActivityStatus("created", undefined, undefined), undefined, undefined), new EntityEventContext(EntityEventType.Updated)), "activity left - Activity"); + }); + } + getActivityTypes() { + return Promise.resolve([]); + } + getWindowTypes() { + return Promise.resolve([]); + } + getActivities() { + return Promise.resolve([]); + } + getActivityWindows() { + return Promise.resolve([]); + } + createStackedWindows(id, windowDefinitions, timeout) { + return undefined; + } + getWindowBounds(id) { + return undefined; + } + setWindowBounds(id, bounds) { + return undefined; + } + activateWindow(id, focus) { + return undefined; + } + setWindowVisibility(id, visible) { + return undefined; + } + cloneActivity(id, cloneOptions) { + return undefined; + } + attachActivities(from, to, tag) { + return this._gw3Session.send({ + type: gwNmessageMergeActivities, + into: to, + merge: from + }); + } + detachActivities(activityId, newActivityInfo) { + return this._gw3Session.send({ + type: gwMessageSplitActivities, + from: activityId, + }).then(() => ""); + } + onActivitiesAttached(callback) { + } + onActivitiesDetached(callback) { + } + onActivityAttachedDescriptorsRefreshed(callback) { + } + getAttachedDescriptors() { + return Promise.resolve([]); + } + getRandomRequestId() { + return this._connection.peerId + ":" + Math.floor(Math.random() * 1e9) + ""; + } + forwardAddedAndRemovedMessagesToEventHandler(addedMessageType, removedMessageType, mapper, handlers) { + const getGetEntityEvent = (isAdded) => (entity) => new EntityEvent(entity, new EntityEventContext(isAdded ? + EntityEventType.Added : + EntityEventType.Removed)); + const sub1 = addedMessageType && this.forwardMessageToEventHandler(addedMessageType, (msg) => mapper(msg, true), getGetEntityEvent(true), handlers); + const sub2 = removedMessageType && this.forwardMessageToEventHandler(removedMessageType, (msg) => mapper(msg, false), getGetEntityEvent(false), handlers); + return [sub1, sub2].filter((x) => x); + } + forwardMessageToEventHandler(messageType, mapper, getEntityEvent, handler) { + return this.subscribe(messageType, (msg) => { + mapper(msg) + .forEach((ent) => handler.forEach((h) => h(getEntityEvent(ent, msg)))); + }); + } + sendCreateAndMapResultingMessagesToPromise(msg, initiatedMessageType, initiatedMessageFilter, createdMessageType, createdMessageFilter, cancelledMessageType, cancelledMessageFilter, createdMessageToPromiseResolution, listenForRecreates) { + const reqId = this.getRandomRequestId(); + let resolveCreatedPromise; + let rejectCreatedPromise; + const createdPromise = new Promise((resolve, reject) => { + resolveCreatedPromise = resolve; + rejectCreatedPromise = reject; + }); + let initiatedMessageAck = null; + let initiatedSubscription; + let createdSubscription; + let cancelledSubscription; + let errorSubscription; + const dropSubscriptions = () => { + this.dropSubscription(initiatedSubscription); + if (!listenForRecreates) { + this.dropSubscription(createdSubscription); + } + this.dropSubscription(cancelledSubscription); + this.dropSubscription(errorSubscription); + }; + initiatedSubscription = initiatedMessageType && + this.subscribe(initiatedMessageType, (msg4) => { + if (!initiatedMessageFilter(msg4, reqId)) { + return; + } + initiatedMessageAck = msg4; + this.dropSubscription(initiatedSubscription); + }); + let recreated = false; + createdSubscription = + this.subscribe(createdMessageType, (msg1) => { + if (!createdMessageFilter(msg1, reqId, initiatedMessageAck)) { + return; + } + if (recreated) { + if (listenForRecreates) { + listenForRecreates(createdMessageToPromiseResolution(msg1)); + } + } + else { + recreated = true; + resolveCreatedPromise(createdMessageToPromiseResolution(msg1)); + } + }); + cancelledSubscription = cancelledMessageType && + this.subscribe(cancelledMessageType, (msg2) => { + if (!cancelledMessageFilter(msg2, reqId, initiatedMessageAck)) { + return; + } + rejectCreatedPromise(msg2); + }); + errorSubscription = cancelledMessageType && + this.subscribe(gwMmessageError, (msg3) => { + if (msg3.request_id !== reqId) { + return; + } + rejectCreatedPromise(msg3); + }); + msg.request_id = reqId; + const toReturn = this._gw3Session + .send(msg) + .then(() => { + return createdPromise; + }); + toReturn.then(dropSubscriptions, dropSubscriptions); + return toReturn; + } + peerFactoryIdAndOwnerIdToWindowType(factoryId, ownerId) { + const peerType = this._peerIdAndFactoryIdToPeerType[ownerId + ":" + factoryId]; + if (!peerType) { + return null; + } + else { + return new WindowType(peerType, undefined); + } + } + subscribe(messageType, handler) { + const sub = this._connection.on(messageType, (msg) => handler.bind(this)(msg)); + this._gw3Subscriptions.push(sub); + return sub; + } + dropSubscription(subscription) { + if (subscription) { + this._connection.off(subscription); + delete this._gw3Subscriptions[this._gw3Subscriptions.indexOf(subscription)]; + } + } + invokeCallbacks(callbacks, event, description) { + callbacks.forEach((cb) => { + try { + cb(event); + } + catch (err) { + this._logger.error(`Error in ${description || event.context.type} callback: ` + JSON.stringify(err)); + } + }); + } + handleActivityCreatedMessage(msg) { + if (!msg.context_id) { + this._logger.error("Activity created with unknown context_id: " + msg.activity_id); + } + else { + if (!this._contextSubscriptions[msg.activity_id]) { + this.subscribeToContext(msg); + } + } + } + async subscribeToContext(msg) { + const activityId = msg.activity_id; + this._contextSubscriptions[activityId] = + await this._contexts.subscribe(activityId, (data, updated, removed) => { + const event = new EntityEvent(new Activity(activityId, undefined, undefined, data, undefined), new ActivityContextChangedEventContext(data, updated, removed)); + this.invokeCallbacks(this._activityChangeCallbacks, event, "context updated"); + }); + } + handleActivityDestroyedMessage(msg) { + const unsubscribeContext = this._contextSubscriptions[msg.activity_id]; + if (typeof unsubscribeContext === "function") { + unsubscribeContext(); + } + delete this._contextSubscriptions[msg.activity_id]; + } + handlePeerFactoriesAdded(msg) { + msg.factories.forEach((entity) => { + this._peerIdAndFactoryIdToPeerType[msg.owner_id + ":" + entity.id] = entity.peer_type; + }); + } + handlePeerFactoriesRemoved(msg) { + msg.factory_ids.forEach((factoryId) => { + delete this._peerIdAndFactoryIdToPeerType[msg.owner_id + ":" + factoryId]; + }); + } + forwardActivityTypeMessagesToStatusEventHandlers() { + this.forwardAddedAndRemovedMessagesToEventHandler(gwMmessageActivityTypesAdded, gwMessageActivityTypesRemoved, (msg, isAdded) => isAdded + ? msg.types.map((t) => GW3Bridge.activityTypeGwMessageEntityToActivityType(t, undefined)) + : msg.types.map((t) => new ActivityType(t.name, undefined, undefined, undefined)), this._activityTypeStatusChangeCallbacks); + } + forwardActivityCreatedAndJoinedActivityToActivityWindowEventHandlers() { + for (const activityCreatedMessage of [gwMessageActivityCreated, gwMessageJoinedActivity, gwMessageOwnerChanged]) { + this.forwardMessageToEventHandler(activityCreatedMessage, (msg) => ([msg.owner || { ...msg, type: msg.peer_type, name: msg.peer_name, peer_id: msg.owner_id }]) + .concat(msg.participants || []) + .map((info) => new ActivityWindow(info.peer_id, info.name, info.type, msg.activity_id, this.getAgmInstance(info.peer_id), undefined, this.generateWindowGetter(info.peer_id), undefined)), (ent, msg) => new EntityEvent(ent, new EntityEventContext(EntityEventType.ActivityWindowJoinedActivity)), this._activityWindowChangeCallbacks); + } + } + forwardActivityMessagesToStatusEventHandlers() { + for (const createdMessage of [gwMessageActivityCreated, gwMessageJoinedActivity]) { + this.forwardMessageToEventHandler(createdMessage, (msg) => [GW3Bridge.activityGwMessageToActivity(msg, new ActivityStatus("started", "", new Date()))], (ent, msg) => GW3Bridge.activityToActivityStatusChangeEvent(ent), this._activityChangeCallbacks); + } + this.forwardMessageToEventHandler(gwMessageActivityDestroyed, (msg) => [GW3Bridge.activityGwMessageToActivity(msg, new ActivityStatus("destroyed", msg.reason, new Date()))], (ent, msg) => GW3Bridge.activityToActivityStatusChangeEvent(ent), this._activityChangeCallbacks); + this.forwardMessageToEventHandler(gwMessageActivityInitiated, (msg) => [GW3Bridge.activityGwMessageToActivity(msg, new ActivityStatus("created", "", new Date()))], (ent, msg) => GW3Bridge.activityToActivityStatusChangeEvent(ent), this._activityChangeCallbacks); + this.forwardMessageToEventHandler(gwMessageOwnerChanged, (msg) => [GW3Bridge.activityGwMessageToActivity(msg, new ActivityStatus("created", "", new Date()))], (ent, msg) => GW3Bridge.activityToActivityStatusChangeEvent(ent), this._activityChangeCallbacks); + } + forwardPeerFactoryMessagesToStatusEventHandlers() { + this.forwardAddedAndRemovedMessagesToEventHandler(gwMessagePeerFactoriesAdded, gwMessagePeerFactoriesRemoved, (msg, isAdded) => isAdded + ? msg.factories.map(GW3Bridge.peerFactoryGwMessageEntityToWindowType) + : msg.factory_ids.map((id) => this.peerFactoryIdAndOwnerIdToWindowType(id, msg.owner_id)).filter((x) => x != null), this._windowTypeStatusChangeCallbacks); + } + forwardPeerFactoryMessagesToPeerFactoryRequests() { + this.subscribe(gwMessagePeerRequested, (msg) => { + const factory = this._peerFactoriesRegisteredByUs[msg.peer_factory]; + if (!factory) { + this._gw3Session.send({ + type: gwMmessageError, + request_id: msg.request_id, + reason: `Unknown peer factory ${msg.peer_factory}` + }); + return; + } + try { + const configuration = msg.configuration || {}; + configuration.gateway_token = configuration.gateway_token || msg.gateway_token; + configuration.peer_factory = configuration.peer_factory || msg.peer_factory; + const promise = factory({ + activityId: msg.activity && msg.activity.id, + activityType: msg.activity && msg.activity.type, + type: msg.configuration && msg.configuration.type, + gwToken: configuration.gateway_token, + configuration + }); + if (promise && promise.then && promise.catch) { + promise.catch((err) => this._gw3Session.send({ + type: gwMmessageError, + request_id: msg.request_id, + reason: err && (err.message || JSON.stringify(err)) + })); + } + } + catch (err) { + this._gw3Session.send({ + type: gwMmessageError, + request_id: msg.request_id, + reason: err && (err.message || JSON.stringify(err)) + }); + } + }); + } + forwardActivityWindowMessagesToEventHandlers() { + for (const joinedMessage of [gwMessageActivityJoined, gwMessageJoinedActivity]) { + this.subscribe(joinedMessage, (msg) => { + const joinedId = (joinedMessage === gwMessageActivityJoined) ? msg.joined_id : msg.peer_id; + const joinedType = (joinedMessage === gwMessageActivityJoined) ? msg.joined_type : msg.peer_type; + const joinedName = (joinedMessage === gwMessageActivityJoined) ? msg.joined_name : msg.peer_name; + const entity = new ActivityWindow(joinedId, joinedName, joinedType, msg.activity_id, this.getAgmInstance(joinedId), undefined, this.generateWindowGetter(joinedId), undefined); + if (!this._contextSubscriptions[msg.activity_id]) { + this.subscribeToContext(msg).then(() => { + if (joinedMessage === gwMessageJoinedActivity) { + this._activityJoinedPromiseResolve({}); + } + }); + } + else if (joinedMessage === gwMessageJoinedActivity) { + this._activityJoinedPromiseResolve({}); + } + this.invokeCallbacks(this._activityWindowChangeCallbacks, new EntityEvent(entity, new EntityEventContext(EntityEventType.ActivityWindowJoinedActivity)), joinedMessage); + }); + } + this.subscribe(gwMessageActivityLeft, (msg) => { + const entity = new ActivityWindow(msg.left_id, undefined, undefined, null, this.getAgmInstance(msg.left_id), undefined, this.generateWindowGetter(msg.left_id), undefined); + this.invokeCallbacks(this._activityWindowChangeCallbacks, new EntityEvent(entity, new EntityEventContext(EntityEventType.ActivityWindowLeftActivity)), gwMessageActivityLeft); + }); + this.forwardAddedAndRemovedMessagesToEventHandler(gwMessagePeerCreated, undefined, (msg) => [ + new ActivityWindow(msg.created_id, undefined, undefined, undefined, undefined, undefined, this.generateWindowGetter(msg.created_id), undefined) + ], this._activityWindowChangeCallbacks); + } + getAgmInstance(id) { + return this._config.agm.servers().find((s) => s.peerId === id || s.windowId === id); + } + generateWindowGetter(peerId) { + return () => { + const server = this.getAgmInstance(peerId); + if (!server) { + return; + } + const windowId = server.windowId; + return this._config.windows.list().filter((w) => w.id === windowId)[0]; + }; + } + isOverrideTypeDefinition(value) { + if (typeof value === "undefined") { + return false; + } + if (value.owner) { + return true; + } + return false; + } + } + + class ActivityMy { + constructor(manager, windows) { + this._myAttached = []; + this._myDetached = []; + this._myAttachedTo = []; + this._myDetachedFrom = []; + this._myActivityFrameColorChanged = []; + this._myActivityJoinedCallbacks = []; + this._myActivityRemovedCallbacks = []; + this._myContextUpdateCallbacks = []; + this._logger = Logger.Get(this); + this._m = manager; + manager.ready() + .then((am) => { + am.subscribeActivityContextChanged(this._subscribeMyContextChanged.bind(this)); + am.subscribeWindowEvents(this._subscribeMyWindowEvent.bind(this)); + am.subscribeActivitiesAttached(this._subscribeActivitiesAttached.bind(this)); + am.subscribeActivitiesDetached(this._subscribeActivitiesDetached.bind(this)); + if (windows) { + windows.onWindowFrameColorChanged(this._subscribeWindowFrameColorChanged.bind(this)); + } + }); + } + get window() { + if (isUndefinedOrNull(this._w)) { + const announcedWindows = this._m.announcedWindows; + if (announcedWindows.length > 0) { + this._w = announcedWindows[0]; + } + } + return this._w; + } + get activity() { + const myWin = this.window; + if (isUndefinedOrNull(myWin)) { + return undefined; + } + return myWin.activity; + } + createWindow(windowType) { + return this._m.createWindow(this.activity, windowType); + } + createStackedWindows(windowTypes, timeout) { + return this._m.createStackedWindows(this.activity, windowTypes, timeout); + } + get context() { + const activity = this.activity; + if (isUndefined(activity)) { + return {}; + } + return activity.context; + } + updateContext(context, callback) { + const activity = this.activity; + if (isUndefined(activity)) { + return new Promise((resolve, reject) => { + reject("Not in activity"); + }); + } + return activity.updateContext(context, callback); + } + setContext(context, callback) { + const activity = this.activity; + if (isUndefined(activity)) { + return new Promise((resolve, reject) => { + reject("Not in activity"); + }); + } + return activity.setContext(context, callback); + } + onActivityJoined(callback) { + this._myActivityJoinedCallbacks.push(callback); + const myWin = this.window; + if (!isUndefinedOrNull(myWin) && !isUndefinedOrNull(myWin.activity)) { + callback(myWin.activity); + } + } + onActivityLeft(callback) { + this._myActivityRemovedCallbacks.push(callback); + } + onContextChanged(callback) { + this._myContextUpdateCallbacks.push(callback); + const myWin = this.window; + if (isUndefinedOrNull(myWin)) { + return; + } + const activity = myWin.activity; + if (isUndefinedOrNull(activity)) { + return; + } + callback(activity.context, activity.context, [], activity); + } + clone(options, callback) { + const act = this.activity; + return this._m.clone(act, options, callback); + } + attach(activity, tag) { + let activityId; + if (typeof activity === "string") { + activityId = activity; + } + else { + activityId = activity.id; + } + return this._m.attachActivities(activityId, this.activity.id, tag); + } + onActivityAttached(callback) { + this._myAttached.push(callback); + } + onActivityDetached(callback) { + this._myDetached.push(callback); + } + onAttachedToActivity(callback) { + this._myAttachedTo.push(callback); + } + onDetachedFromActivity(callback) { + this._myDetachedFrom.push(callback); + } + get attached() { + if (!this.activity) { + return []; + } + return this.activity.attached; + } + setFrameColor(color, callback) { + if (this.activity) { + return this.activity.setFrameColor(color, callback); + } + else { + return Promise.resolve(null); + } + } + getFrameColor() { + if (this.activity) { + return this.activity.getFrameColor(); + } + return ""; + } + onFrameColorChanged(callback) { + this._myActivityFrameColorChanged.push(callback); + } + _subscribeMyContextChanged(activity, context, delta, removed) { + const myWin = this.window; + if (isUndefinedOrNull(myWin)) { + return; + } + const myActivity = myWin.activity; + if (isUndefinedOrNull(myActivity)) { + return; + } + if (activity.id !== myActivity.id) { + return; + } + this._notifyMyContextChanged(activity, context, delta, removed); + } + _subscribeMyWindowEvent(activity, window, event) { + if (isUndefinedOrNull(this.window)) { + return; + } + if (this.window.id !== window.id) { + return; + } + if (event === EntityEventType.ActivityWindowJoinedActivity) { + this._notifyMyWindowEvent(activity, this._myActivityJoinedCallbacks); + this._notifyMyContextChanged(activity, activity.context, null, null); + } + else if (event === EntityEventType.ActivityWindowLeftActivity) { + this._notifyMyWindowEvent(activity, this._myActivityRemovedCallbacks); + } + } + _notifyMyWindowEvent(activity, callbackStore) { + callbackStore.forEach((element) => { + try { + element(activity, event); + } + catch (e) { + this._logger.warn("error in user callback " + e); + } + }); + } + _notifyMyContextChanged(activity, context, delta, removed) { + delta = delta || {}; + removed = removed || []; + this._myContextUpdateCallbacks.forEach((element) => { + try { + element(context, delta, removed, activity); + } + catch (e) { + this._logger.warn("error in user callback " + e); + } + }); + } + _notifyAttached(state) { + this._myAttached.forEach((cb) => { + try { + cb(state); + } + catch (e) { + this._logger.warn("error in user callback " + e); + } + }); + } + _notifyDetached(state) { + this._myDetached.forEach((cb) => { + try { + cb(state); + } + catch (e) { + this._logger.warn("error in user callback " + e); + } + }); + } + _notifyAttachedTo(state) { + this._myAttachedTo.forEach((cb) => { + try { + cb(this.activity, state); + } + catch (e) { + this._logger.warn("error in user callback " + e); + } + }); + } + _notifyDetachedFrom(detached, existing, state) { + this._myDetachedFrom.forEach((cb) => { + try { + cb(detached, existing, state); + } + catch (e) { + this._logger.warn("error in user callback " + e); + } + }); + } + _subscribeActivitiesAttached(newAct, state) { + const myWin = this.window; + if (isUndefinedOrNull(myWin)) { + return; + } + const myActivity = myWin.activity; + if (isUndefinedOrNull(myActivity)) { + return; + } + if (newAct.id !== myActivity.id) { + return; + } + if (state.windowIds.indexOf(myWin.id) >= 0) { + this._notifyAttachedTo(state); + return; + } + this._notifyAttached(state); + } + _subscribeActivitiesDetached(newAct, oldAct, state) { + const myWin = this.window; + if (isUndefinedOrNull(myWin)) { + return; + } + const myActivity = myWin.activity; + if (isUndefinedOrNull(myActivity)) { + return; + } + if (oldAct.id === myActivity.id) { + this._notifyDetached(state); + } + if (newAct.id === myActivity.id) { + this._notifyDetachedFrom(newAct, oldAct, state); + } + } + _subscribeWindowFrameColorChanged(window) { + const act = this.activity; + if (!act) { + return; + } + if (!act.owner) { + return; + } + if (act.owner.underlyingWindow.id === window.id) { + this._myActivityFrameColorChanged.forEach((callback) => { + callback(window.frameColor); + }); + } + } + } + + class ReadyMarker { + constructor(name, signalsToWait) { + this._logger = Logger.Get("ReadyMarker [" + name + "]"); + this._logger.debug("Initializing ready marker for '" + name + "' with " + signalsToWait + " signals to wait"); + if (signalsToWait <= 0) { + throw new Error("Invalid signal number. Should be > 0"); + } + this._signals = signalsToWait; + this._callbacks = []; + this._name = name; + } + setCallback(callback) { + if (this.isSet()) { + callback(undefined); + return; + } + else if (this.isError()) { + callback(this._error); + return; + } + this._callbacks.push(callback); + } + signal(message) { + this._logger.debug("Signaled - " + message + " - signals left " + (this._signals - 1)); + this._signals--; + if (this._signals < 0) { + throw new Error("Error in ready marker '" + this._name + " - signals are " + this._signals); + } + if (this.isSet()) { + this._callbacks.forEach((callback) => { + callback(undefined); + }); + } + } + error(error) { + this._error = error; + this._callbacks.forEach((errorCallback) => { + errorCallback(error); + }); + } + isSet() { + if (this.isError()) { + return false; + } + return this._signals === 0; + } + isError() { + return !isUndefined(this._error); + } + getError() { + return this._error; + } + } + + class EntityObservableCollection { + constructor(processNew) { + this._items = {}; + this._listeners = []; + this._processNew = processNew; + } + addOne(item) { + this.add([item]); + } + add(items) { + items.forEach((element) => { + this.process(new EntityEvent(element, new EntityEventContext(EntityEventType.Added))); + }); + } + process(event) { + const context = event.context; + const type = context.type; + const entity = event.entity; + if (type === EntityEventType.StatusChange && + !context.oldStatus) { + const act = this._items[entity.id]; + if (act) { + context.oldStatus = act.status; + } + } + if (type === EntityEventType.StatusChange && + context.oldStatus && + context.newStatus && + context.oldStatus.state === + context.newStatus.state) { + context.type = EntityEventType.Updated; + } + if (typeof htmlContainer === "undefined") { + if (type === EntityEventType.ActivityWindowJoinedActivity && + this._items[entity.id] && + this._items[entity.id].activity) { + context.type = EntityEventType.Updated; + } + if (type === EntityEventType.ActivityWindowLeftActivity && + this._items[entity.id] && + !this._items[entity.id].activity) { + context.type = EntityEventType.Updated; + } + } + const internalEntity = this._updateInternalCollections(entity, type, context); + this._notifyListeners(internalEntity, context); + return internalEntity; + } + get() { + const result = []; + for (const key in this._items) { + if (this._items.hasOwnProperty(key)) { + const element = this._items[key]; + result.push(element); + } + } + return result; + } + getByName(name) { + for (const key in this._items) { + if (key === name) { + return this._items[key]; + } + } + return undefined; + } + getOrWait(name) { + return new Promise((resolve) => { + const entityAddedHandler = (entity) => { + if (entity.id !== name) { + return; + } + resolve(entity); + this.unsubscribe(entityAddedHandler); + }; + this.subscribe(entityAddedHandler); + const window = this.getByName(name); + if (window) { + this.unsubscribe(entityAddedHandler); + resolve(window); + return; + } + }); + } + subscribe(handler) { + this._listeners.push(handler); + Object.keys(this._items).forEach((key) => { + const element = this._items[key]; + handler(element, new EntityEventContext(EntityEventType.Added.toString())); + }); + return () => { + this.unsubscribe(handler); + }; + } + unsubscribe(handler) { + const index = this._listeners.indexOf(handler); + if (index !== -1) { + this._listeners.splice(index, 1); + } + } + _notifyListeners(entity, context) { + this._listeners.forEach((listener) => { + try { + listener(entity, context); + } + catch (e) { + return; + } + }); + } + _updateInternalCollections(entity, type, context) { + const entityAsAny = entity; + const isActivityDestroy = (type === EntityEventType.StatusChange && + entityAsAny.status && + entityAsAny.status.state === ActivityState.Destroyed) || + (type === EntityEventType.StatusChange && + context && + context.newStatus && + context.newStatus.state === ActivityState.Destroyed); + const isWindowClose = type === EntityEventType.Closed; + const isTypeRemove = type === EntityEventType.Removed && typeof entityAsAny.isIndependent === "undefined"; + if (isTypeRemove || isWindowClose || isActivityDestroy) { + const oldEntity = this._items[entity.id]; + delete this._items[entity.id]; + this._processNew(entity); + if (oldEntity) { + entity._beforeDelete(oldEntity); + } + return entity; + } + else { + const key = entity.id; + if (!this._items.hasOwnProperty(key)) { + this._processNew(entity); + this._items[entity.id] = entity; + } + else { + this._items[entity.id]._update(entity); + } + } + return this._items[entity.id]; + } + } + + class ActivityManager { + get usingHc() { + return this._bridge.bridgeType === "HC"; + } + get announcedWindows() { + return this._announcedWindows; + } + set announcedWindows(v) { + throw new Error("not allowed"); + } + constructor(bridge, autoAnnounce, windows) { + this._logger = Logger.Get("activityManager"); + this._announcedWindows = []; + this._attachedCallbacks = []; + this._detachedCallbacks = []; + this._frameColorChangesCallbacks = []; + this._windowHandlers = []; + this._bridge = bridge; + this._activityTypes = new EntityObservableCollection((e) => this._grabEntity(e)); + this._windowTypes = new EntityObservableCollection((e) => this._grabEntity(e)); + this._activities = new EntityObservableCollection((e) => this._grabEntity(e)); + this._windows = new EntityObservableCollection((e) => this._grabEntity(e)); + this._dataReadyMarker = new ReadyMarker("Activity Manager Data", ["GetActivityTypes", "GetWindowTypes", "GetActivities", "GetWindows"].length); + this._descriptorsMarker = new ReadyMarker("Attached Activities Descriptors", ["GetDescriptors"].length); + if (autoAnnounce) { + this._readyMarker = new ReadyMarker("Activity Manager Announce", ["Announcement"].length); + this._dataReadyMarker.setCallback((dataErr) => { + if (dataErr) { + this._readyMarker.error(dataErr); + } + this._descriptorsMarker.setCallback((err) => { + if (err) { + this._readyMarker.error(err); + } + this._logger.debug("Auto announcing window"); + this.announceWindow() + .then((w) => { + this._announcedWindows.push(w); + this._readyMarker.signal("Successfully announced window with id '" + w.id + "'"); + }) + .catch((errCatch) => { + this._logger.debug("Will not announce window - " + errCatch); + this._readyMarker.signal(); + }); + }); + this.refreshDescriptors(); + }); + } + else { + this._readyMarker = this._dataReadyMarker; + } + this._bridge.onActivitiesAttached((e) => { + this._handleActivitiesAttached(e); + }); + this._bridge.onActivitiesDetached((e) => { + this._handleActivitiesDetached(e); + }); + this._bridge.onActivityAttachedDescriptorsRefreshed((e) => { + this._handleActivityDescriptorsRefreshed(e); + }); + if (windows) { + windows.onWindowFrameColorChanged(this._handleWindowFrameColorChanged.bind(this)); + } + this._bridge.init(); + this._subscribeForData(); + this._bridge + .initReady() + .then((aw) => { + this._getInitialData(); + }) + .catch((error) => { + console.log(error); + }); + } + ready(callback) { + const promise = new Promise((resolve, reject) => { + this._readyMarker.setCallback((err) => { + if (!err) { + resolve(this); + } + else { + reject(this._readyMarker.getError()); + } + }); + }); + return nodeify(Promise.all([this._bridge.ready(), promise]).then(() => this), callback); + } + getActivityTypes() { + return this._activityTypes.get(); + } + getActivityType(name) { + return this._activityTypes.getByName(name); + } + registerActivityType(activityTypeName, ownerWindowType, helperWindowTypes, config, description, callback) { + const promise = new Promise((resolve, reject) => { + if (isUndefinedOrNull(activityTypeName)) { + reject("activityTypeName argument can not be undefined"); + return; + } + if (!isString(activityTypeName)) { + reject("activityTypeName should be string"); + return; + } + const actType = this.getActivityType(activityTypeName); + if (!isUndefinedOrNull(actType)) { + reject("Activity type '" + activityTypeName + "' already exists"); + return; + } + let ownerDefinition; + if (isUndefined(ownerWindowType)) { + reject("Owner window type can not be undefined"); + return; + } + if (isString(ownerWindowType)) { + ownerDefinition = { type: (ownerWindowType), name: "", isIndependent: false, arguments: {} }; + } + else { + ownerDefinition = (ownerWindowType); + } + const helperDefinitions = []; + if (!isUndefined(helperWindowTypes) && isArray(helperWindowTypes)) { + for (const index in helperWindowTypes) { + const item = helperWindowTypes[index]; + if (isString(item)) { + const definition = { + type: (item), + name: "", + isIndependent: false, + arguments: {}, + relativeTo: "", + relativeDirection: "", + windowStyleAttributes: {} + }; + helperDefinitions.push(definition); + } + else { + helperDefinitions.push(item); + } + } + } + this._bridge + .registerActivityType(activityTypeName, ownerDefinition, helperDefinitions, config, description) + .then((activityType) => { + this._grabEntity(activityType); + resolve(activityType); + }) + .catch((error) => { + reject(error); + }); + }); + return nodeify(promise, callback); + } + unregisterActivityType(type, callback) { + const promise = new Promise((resolve, reject) => { + const actType = this.getActivityType(type); + if (isUndefined(actType)) { + reject("Activity type '" + type + "' does not exists"); + return; + } + this._bridge.unregisterActivityType(type).then(() => resolve(actType), reject); + }); + return nodeify(promise, callback); + } + initiate(activityType, context, callback, configuration) { + const promise = new Promise((resolve, reject) => { + const actType = this.getActivityType(activityType); + if (isUndefined(actType)) { + reject("Activity type '" + activityType + "' does not exists"); + return; + } + this._bridge + .initiateActivity(activityType, context, configuration) + .then((actId) => { + this._activities + .getOrWait(actId) + .then((act) => { + resolve(act); + }) + .catch((err) => reject(err)); + }) + .catch((err) => { + reject(err); + }); + }); + return nodeify(promise, callback); + } + subscribeActivityTypeEvents(handler) { + this._activityTypes.subscribe((at, context) => { + handler(at, context.type); + }); + } + getWindowTypes() { + return this._windowTypes.get(); + } + getWindowType(name) { + return this._windowTypes.getByName(name); + } + registerWindowFactory(windowType, factoryMethod, callback) { + const promise = new Promise((resolve, reject) => { + if (isUndefinedOrNull(windowType)) { + reject("no windowType specified"); + return; + } + if (isObject(windowType)) { + windowType = windowType.getName(); + } + else if (!isString(windowType)) { + reject("windowType should be string or object that has getName method"); + return; + } + this._bridge + .registerWindowFactory(windowType, factoryMethod) + .then((v) => { + resolve(v); + }) + .catch((err) => { + reject(err); + }); + }); + return nodeify(promise, callback); + } + unregisterWindowFactory(windowType, callback) { + const promise = new Promise((resolve, reject) => { + if (isUndefinedOrNull(windowType)) { + reject("no windowType specified"); + return; + } + if (!isString(windowType)) { + reject("windowType should be a string"); + return; + } + this._bridge + .unregisterWindowFactory(windowType) + .then((v) => { + resolve(v); + }) + .catch((err) => { + reject(err); + }); + }); + return nodeify(promise, callback); + } + getActivities(activityType) { + let act = this._activities.get(); + act = act.filter((a) => a._ownerId); + if (!activityType) { + return act; + } + let types = activityType; + if (isString(activityType)) { + types = [activityType]; + } + else if (activityType instanceof ActivityType) { + types = [activityType.name]; + } + else if (activityType instanceof Array) ; + else { + throw new Error("Invalid input argument 'activityType' = " + activityType); + } + return act.filter((at) => { + const type = at.type; + return some(types, (t) => { + return type.id === t.id; + }); + }); + } + getActivityById(id) { + return this._activities.getByName(id); + } + announceWindow(activityWindowId, windowType) { + const promise = new Promise((resolve, reject) => { + const announcementInfo = this._bridge.getAnnouncementInfo(); + if (isUndefined(activityWindowId)) { + activityWindowId = announcementInfo.activityWindowId; + } + if (isUndefined(windowType)) { + windowType = announcementInfo.activityWindowType; + } + if (isUndefinedOrNull(windowType)) { + throw new Error("Can not announce - unknown windowType"); + } + const activityId = announcementInfo && announcementInfo.activityId; + if (isUndefinedOrNull(activityWindowId)) { + this._logger.debug("Registering window with type:'" + windowType + "', name:'" + announcementInfo.activityWindowName + "', ind.:'" + announcementInfo.activityWindowIndependent + "'"); + this._bridge.registerWindow(windowType, announcementInfo.activityWindowName, announcementInfo.activityWindowIndependent) + .then(this._windows.getOrWait.bind(this._windows)) + .then((w) => { + if (activityId) { + return this._activities.getOrWait(activityId).then((_) => w); + } + else { + return w; + } + }) + .then((w) => { + resolve(w); + }) + .catch((err) => { + this._logger.error(err); + }); + } + else { + this._logger.debug("Announcing window with id '" + activityWindowId + "' and type '" + windowType + "'"); + const currentWindow = this._windows.getByName(activityWindowId); + if (!isUndefinedOrNull(currentWindow)) { + this._logger.debug("Window with id '" + activityWindowId + "' already announced - reusing the window"); + resolve(currentWindow); + return; + } + const windowEventHandler = (a, w, e) => { + if (activityWindowId === w.id) { + if (e === EntityEventType.ActivityWindowJoinedActivity) { + const activity = w.activity; + if (isUndefined(activity)) { + reject("UNDEFINED ACTIVITY"); + } + this._logger.trace("Got joined event for id '" + activityWindowId + "'"); + resolve(w); + this.unsubscribeWindowEvents(windowEventHandler); + } + } + }; + this.subscribeWindowEvents(windowEventHandler); + this._logger.trace("Waiting for joined event for id '" + activityWindowId + "'"); + this._bridge.announceWindow(windowType, activityWindowId); + } + }); + return promise; + } + subscribeWindowTypeEvents(handler) { + this._windowTypes.subscribe((wt, context) => { + handler(wt, context.type); + }); + } + subscribeActivityEvents(handler) { + return this._activities.subscribe((act, context) => { + if (context.type === EntityEventType.StatusChange) { + const p = context; + handler(act, p.newStatus, p.oldStatus); + } + if (context.type === EntityEventType.Removed || + (context.type === EntityEventType.StatusChange && + context.newStatus.getState() === ActivityState.Destroyed)) { + for (const window of this._windows.get()) { + if (window.activity && window.activity.id === act.id) { + this._windows.process(new EntityEvent(window, new EntityEventContext(EntityEventType.ActivityWindowLeftActivity))); + } + } + } + }); + } + subscribeWindowEvents(handler) { + const wrappingHandler = (window, context) => { + let eventType = context.type; + if (eventType === EntityEventType.Added) { + eventType = "opened"; + } + handler(window.activity, window, eventType); + }; + this._windowHandlers.push([handler, wrappingHandler]); + return this._windows.subscribe(wrappingHandler); + } + unsubscribeWindowEvents(handler) { + const found = this._windowHandlers.find((pair) => pair[0] === handler); + if (found) { + this._windowHandlers.splice(this._windowHandlers.indexOf(found), 1); + this._windows.unsubscribe(found[1]); + } + } + createWindow(activity, windowTypeOrConfiguration, callback) { + const promise = new Promise((resolve, reject) => { + if (isUndefinedOrNull(windowTypeOrConfiguration)) { + reject("windowType is undefined"); + } + let windowDefinition; + if (isString(windowTypeOrConfiguration)) { + windowDefinition = { type: (windowTypeOrConfiguration), name: "", isIndependent: false, arguments: {} }; + } + else if (windowTypeOrConfiguration instanceof WindowType) { + windowDefinition = { + type: windowTypeOrConfiguration.type || windowTypeOrConfiguration.id, + name: windowTypeOrConfiguration.name || windowTypeOrConfiguration.type || windowTypeOrConfiguration.id, + isIndependent: false + }; + } + else { + const invalidKeys = ["url"]; + const filteredWindowTypeOrConfiguration = {}; + Object.keys(windowTypeOrConfiguration).forEach((key) => { + if (invalidKeys.indexOf(key) === -1) { + filteredWindowTypeOrConfiguration[key] = windowTypeOrConfiguration[key]; + } + }); + windowDefinition = filteredWindowTypeOrConfiguration; + } + let relativeToWindow; + if (!isUndefinedOrNull(windowDefinition.relativeTo)) { + relativeToWindow = windowDefinition.relativeTo; + if (typeof relativeToWindow === "string") { + const windows = this.getWindows({ type: relativeToWindow }); + if (!isUndefinedOrNull(windows) && windows.length > 0) { + windowDefinition.relativeTo = windows[0].id; + } + } + else if (!isUndefinedOrNull(relativeToWindow.type)) { + const windows = this.getWindows({ type: relativeToWindow.type }); + if (!isUndefinedOrNull(windows) && windows.length > 0) { + windowDefinition.relativeTo = windows[0].id; + } + } + else if (!isUndefinedOrNull(relativeToWindow.windowId)) { + windowDefinition.relativeTo = relativeToWindow.windowId; + } + } + this._bridge.createWindow(activity && activity.id, windowDefinition) + .then((wid) => { + this._logger.debug("Window created, waiting for window entity with id " + wid); + const handler = (window, context) => { + if (window.id === wid && (!activity || window.activity)) { + this._logger.debug("Got entity window with id " + wid); + resolve(window); + this._windows.unsubscribe(handler); + } + }; + this._windows.subscribe(handler); + }) + .catch((err) => { + reject(err); + }); + }); + return nodeify(promise, callback); + } + createStackedWindows(activity, relativeWindowTypes, timeout, callback) { + const promise = new Promise((resolve, reject) => { + if (isUndefinedOrNull(activity)) { + reject("activity is undefined"); + } + if (isUndefinedOrNull(relativeWindowTypes)) { + reject("relativeWindowTypes is undefined"); + } + if (!Array.isArray(relativeWindowTypes)) { + reject("relativeWindowTypes has to be an array"); + } + if (isUndefinedOrNull(timeout)) { + timeout = 20000; + } + const windowDefinitions = []; + relativeWindowTypes.forEach((element) => { + let windowDefinition; + if (isString(element)) { + windowDefinition = { type: (element), name: "", isIndependent: false, arguments: {} }; + } + else { + windowDefinition = (element); + } + windowDefinition.stackedWindow = true; + windowDefinition.timeout = timeout; + let relativeToWindow; + if (!isUndefinedOrNull(windowDefinition.relativeTo)) { + relativeToWindow = windowDefinition.relativeTo; + if (!isUndefinedOrNull(relativeToWindow.type)) { + windowDefinition.relativeTo = relativeToWindow.type; + } + else if (!isUndefinedOrNull(relativeToWindow.windowId)) { + const windows = this.getWindows({ id: relativeToWindow.windowId }); + if (!isUndefinedOrNull(windows) && windows.length > 0) { + windowDefinition.relativeTo = windows[0].type.name; + } + } + } + windowDefinitions.push(windowDefinition); + }); + const tasks = []; + windowDefinitions.forEach((wd) => tasks.push(this.createWindow(activity, wd))); + Promise.all(tasks).then(resolve).catch(reject); + }); + return nodeify(promise, callback); + } + addWindowToActivity(activity, window, callback) { + const toReturn = this._bridge.joinActivity(activity.id, window.id) + .then(() => window); + nodeify(toReturn, callback); + return toReturn; + } + leaveWindowFromActivity(activity, window, callback) { + const toReturn = this._bridge.leaveActivity(activity.id, window.id) + .then(() => window); + nodeify(toReturn, callback); + return toReturn; + } + setActivityContext(activity, context, callback) { + const promise = new Promise((resolve, reject) => { + if (isUndefinedOrNull(activity)) { + reject("activity can not be null"); + } + this._bridge + .updateActivityContext(activity, context, true) + .then((_) => { + resolve(activity); + }) + .catch((err) => { + reject(err); + }); + }); + return nodeify(promise, callback); + } + updateActivityContext(activity, context, callback) { + const promise = new Promise((resolve, reject) => { + if (isUndefinedOrNull(activity)) { + reject("activity can not be null"); + } + const removedKeys = []; + for (const key in context) { + if (context.hasOwnProperty(key) && context[key] === null) { + removedKeys.push(key); + } + } + for (const removedKey of removedKeys) { + delete context[removedKey]; + } + this._bridge + .updateActivityContext(activity, context, false, removedKeys) + .then((_) => { + resolve(activity); + }) + .catch((err) => { + reject(err); + }); + }); + return nodeify(promise, callback); + } + subscribeActivityContextChanged(handler) { + this._activities.subscribe((act, context) => { + if (context.type === EntityEventType.ActivityContextChange) { + const updateContext = context; + handler(act, updateContext.context, updateContext.updated, updateContext.removed); + } + }); + } + stopActivity(activity, callback) { + const promise = this._bridge.stopActivity(activity); + return nodeify(promise, callback); + } + getWindows(filter) { + if (isUndefined(filter)) { + return this._windows.get(); + } + if (!isUndefined(filter.id)) { + return [this._windows.getByName(filter.id)]; + } + const allWindows = this._windows.get(); + return allWindows.filter((w) => { + if (!isUndefined(filter.type) && w.type.id !== filter.type) { + return false; + } + if (!isUndefined(filter.name) && w.name !== filter.name) { + return false; + } + if (!isUndefined(filter.activityId)) { + if (isUndefinedOrNull(w.activity)) { + return false; + } + if (w.activity.id !== filter.activityId) { + return false; + } + } + return true; + }); + } + getWindowBounds(id) { + return this._bridge.getWindowBounds(id); + } + setWindowBounds(id, bounds, callback) { + const promise = new Promise((resolve, reject) => { + this._bridge.setWindowBounds(id, bounds) + .then(() => resolve()) + .catch((err) => reject(err)); + }); + return nodeify(promise, callback); + } + closeWindow(id) { + return this._bridge.closeWindow(id); + } + activateWindow(id, focus) { + return this._bridge.activateWindow(id, focus); + } + setWindowVisibility(id, visible) { + return this._bridge.setWindowVisibility(id, visible); + } + clone(activity, cloneOptions, callback) { + const promise = new Promise((resolve, reject) => { + if (!activity) { + reject("activity can not be null"); + } + this._bridge.cloneActivity(activity.id, cloneOptions) + .then((activityId) => { + this._activities + .getOrWait(activityId) + .then((act) => { + resolve(act); + }) + .catch((err) => reject(err)); + }) + .catch((err) => reject(err)); + }); + return nodeify(promise, callback); + } + attachActivities(from, to, tag, callback) { + tag = tag || {}; + const promise = new Promise((resolve, reject) => { + const fromActivity = this._activities.getByName(from); + if (!fromActivity) { + reject("can not find activity with id " + from); + return; + } + const toActivity = this._activities.getByName(to); + if (!toActivity) { + reject("can not find activity with id " + to); + return; + } + return this._bridge.attachActivities(from, to, tag) + .then((data) => { + const newActId = data.to; + const state = data.descriptor; + const allStates = data.descriptors; + this._activities.getOrWait(newActId).then((act) => { + act._updateDescriptors(allStates); + const stateWrapped = act.attached.filter((u) => u.ownerId === state.ownerId)[0]; + resolve(stateWrapped); + }); + }) + .catch((err) => { + reject(err); + }); + }); + return nodeify(promise, callback); + } + detachActivities(activityId, descriptor, callback) { + const promise = new Promise((resolve, reject) => { + return this._bridge.detachActivities(activityId, descriptor) + .then(() => { + const oldActId = undefined; + const newActId = undefined; + const descriptors = undefined; + this._activities + .getOrWait(oldActId) + .then((oldAct) => { + oldAct._updateDescriptors(descriptors); + this._activities + .getOrWait(newActId) + .then((newAct) => { + resolve(newAct); + }); + }) + .catch((err) => reject(err)); + }) + .catch((err) => { + reject(err); + }); + }); + return nodeify(promise, callback); + } + subscribeActivitiesAttached(callback) { + this._attachedCallbacks.push(callback); + } + subscribeActivitiesDetached(callback) { + this._detachedCallbacks.push(callback); + } + subscribeActivityFrameColorChanged(callback) { + this._frameColorChangesCallbacks.push(callback); + } + _grabEntity(entity) { + entity._manager = this; + } + _getInitialData() { + this._logger.debug("Request initial data..."); + this._bridge.getActivityTypes() + .then((at) => { + this._activityTypes.add(at); + this._dataReadyMarker.signal("Got act types"); + }) + .catch((error) => { + this._logger.error(error); + this._dataReadyMarker.error("Can not initialize ActivityManager - error getting activity types -" + error); + }); + this._bridge.getWindowTypes() + .then((wt) => { + this._windowTypes.add(wt); + this._dataReadyMarker.signal("Got window types"); + }) + .catch((error) => { + this._logger.error(error); + this._dataReadyMarker.error("Can not initialize ActivityManager - error getting window types " + error); + }); + this._bridge.getActivities() + .then((ac) => { + this._activities.add(ac); + this._dataReadyMarker.signal("Got activities"); + }) + .catch((error) => { + this._logger.error(error); + this._dataReadyMarker.error("Can not initialize ActivityManager - error getting activity instances -" + error); + }); + this._bridge.getActivityWindows() + .then((aw) => { + this._windows.add(aw); + this._dataReadyMarker.signal("Got windows"); + }) + .catch((error) => { + this._logger.error(error); + this._dataReadyMarker.error("Can not initialize ActivityManager - error getting activity windows -" + error); + }); + } + _subscribeForData() { + this._logger.debug("Subscribe for data..."); + this._bridge.onActivityTypeStatusChange((event) => { + this._activityTypes.process(event); + }); + this._bridge.onWindowTypeStatusChange((event) => { + this._windowTypes.process(event); + }); + this._bridge.onActivityWindowChange((event) => { + this._windows.process(event); + }); + this._bridge.onActivityStatusChange((event) => { + this._activities.process(event); + }); + } + _handleActivitiesAttached(data) { + const newActId = data.to; + const descriptor = data.descriptor; + const descriptors = data.descriptors; + this._activities.getOrWait(newActId).then((act) => { + act._updateDescriptors(descriptors); + const descriptorAsObjectFromAPI = act.attached.filter((u) => u.ownerId === descriptor.ownerId)[0]; + this._attachedCallbacks.forEach((callback) => { + try { + callback(act, descriptorAsObjectFromAPI); + } + catch (err) { + return; + } + }); + }); + } + _handleActivitiesDetached(data) { + const oldActId = data.oldActivityId; + const newActId = data.newActivityId; + const descriptors = data.descriptors; + const descriptor = data.descriptor; + this._activities.getOrWait(oldActId).then((oldAct) => { + oldAct._updateDescriptors(descriptors); + this._activities.getOrWait(newActId).then((newAct) => { + this._detachedCallbacks.forEach((callback) => { + try { + callback(newAct, oldAct, descriptor); + } + catch (err) { + return; + } + }); + }); + }); + } + _handleActivityDescriptorsRefreshed(data) { + const id = data.id; + const descriptors = data.descriptors; + const act = this._activities.getByName(id); + if (act) { + act._updateDescriptors(descriptors); + } + } + refreshDescriptors() { + this._bridge.getAttachedDescriptors() + .then((map) => { + if (map) { + Object.keys(map).forEach((key) => { + const actId = key; + const descriptors = map[key]; + const act = this._activities.getByName(actId); + if (act) { + act._updateDescriptors(descriptors); + } + }); + } + this._descriptorsMarker.signal("Successfully got descriptors"); + }) + .catch((err) => { + this._descriptorsMarker.error("failed to get descriptors - " + err); + }); + } + _handleWindowFrameColorChanged(win) { + if (!win.activityId) { + return; + } + const act = this._activities.getByName(win.activityId); + if (!act) { + return; + } + if (!act.owner) { + return; + } + if (act.owner.underlyingWindow.id !== win.id) { + return; + } + this._frameColorChangesCallbacks.forEach((callback) => { + try { + callback(act, win.frameColor); + } + catch (e) { + return; + } + }); + } + } + + class ActivityManagementAPI { + constructor(manager, my) { + this._m = manager; + this._my = my; + this.activityTypes = { + get: this._getActivityTypesWrapper.bind(this), + register: this._m.registerActivityType.bind(this._m), + unregister: this._m.unregisterActivityType.bind(this._m), + subscribe: this._m.subscribeActivityTypeEvents.bind(this._m), + unsubscribe: undefined, + initiate: this._m.initiate.bind(this._m) + }; + this.windowTypes = { + get: this._getWindowTypesWrapper.bind(this), + registerFactory: this._m.registerWindowFactory.bind(this._m), + unregisterFactory: this._m.unregisterWindowFactory.bind(this._m), + subscribe: this._m.subscribeWindowTypeEvents.bind(this._m), + unsubscribe: undefined + }; + this.windows = { + get: this._m.getWindows.bind(this._m), + subscribe: this._m.subscribeWindowEvents.bind(this._m), + announce: this._m.announceWindow.bind(this._m), + unsubscribe: undefined, + create: this._m.createWindow.bind(this._m) + }; + this.instances = { + get: this._m.getActivities.bind(this._m), + subscribe: this._m.subscribeActivityEvents.bind(this._m), + unsubscribe: undefined + }; + } + onAttached(callback) { + this._m.subscribeActivitiesAttached(callback); + } + onDetached(callback) { + this._m.subscribeActivitiesDetached(callback); + } + onActivityFrameColorChanged(callback) { + this._m.subscribeActivityFrameColorChanged(callback); + } + _getActivityTypesWrapper(name) { + if (isUndefined(name)) { + return this._m.getActivityTypes(); + } + return this._m.getActivityType(name); + } + _getWindowTypesWrapper(name) { + if (isUndefined(name)) { + return this._m.getWindowTypes(); + } + return this._m.getWindowType(name); + } + } + + class ActivityAPI { + constructor(manager, my) { + this._mgr = manager; + this._my = my; + this.all = new ActivityManagementAPI(manager, my); + } + ready(callback) { + const promise = new Promise((resolve, reject) => { + this._mgr.ready() + .then(() => { + resolve(this); + }) + .catch((err) => { + reject(err); + }); + }); + return nodeify(promise, callback); + } + get my() { + return this._my; + } + get aware() { + return this._my.window !== undefined; + } + get inActivity() { + return this.aware && this._my.activity !== undefined; + } + get agm() { + if (!this.aware) { + return undefined; + } + if (!this.inActivity) { + return new ActivityAGM(null); + } + return this._my.activity.agm; + } + getAvailableFrameColors() { + return []; + } + } + + class ActivityModule { + static checkIsUsingGW3Implementation(connection) { + return connection.protocolVersion === 3; + } + get api() { + return this._api; + } + set api(value) { + this._api = value; + } + constructor(config) { + if (!config) { + throw new Error("config can not be null"); + } + if (!isUndefined(config.logLevel)) { + Logger.Level = config.logLevel; + } + if (!isUndefinedOrNull(config.logger)) { + Logger.GlueLogger = config.logger; + } + let bridge; + this._isUsingHCImplementation = config.gdMajorVersion === 2; + this._isUsingGW3Implementation = ActivityModule.checkIsUsingGW3Implementation(config.connection); + if (this._isUsingHCImplementation) { + throw new Error("GD2 not supported"); + } + else if (this._isUsingGW3Implementation) { + bridge = new GW3Bridge(config); + } + else { + throw new Error("Unable to instantiate activity bridge implementation"); + } + if (!bridge) { + throw new Error("A bridge to native activity is needed to create activity lib."); + } + ActivityAGM.AGM = config.agm; + const activityManager = new ActivityManager(bridge, !config.disableAutoAnnounce, config.windows); + const my = new ActivityMy(activityManager, config.windows); + this._api = new ActivityAPI(activityManager, my); + this._readyPromise = activityManager.ready().then((_) => this); + } + get isUsingHCImplementation() { + return this._isUsingHCImplementation; + } + get isUsingGW3Implementation() { + return this._isUsingGW3Implementation; + } + ready(callback) { + return nodeify(this._readyPromise, callback); + } + } + + const ShutdownMethodName = "T42.ACS.Shutdown"; + const OnGDShutdownMethodName = "T42.ACS.OnGDShutdown"; + const RestartMethodName = "T42.ACS.Restart"; + const GetConfigurationRegionMethodName = "T42.ACS.GetConfigurationRegion"; + const SetConfigurationRegionMethodName = "T42.ACS.SetConfigurationRegion"; + const GetUserMethodName = "T42.ACS.GetUser"; + const GetBranchesMethodName = "T42.ACS.GetBranches"; + const GetCurrentBranchMethodName = "T42.ACS.GetCurrentBranch"; + const SetCurrentBranchMethodName = "T42.ACS.SetCurrentBranch"; + const GetFunctionalEntitlementMethodName = "T42.ACS.GetFunctionalEntitlement"; + const CanIMethodName = "T42.ACS.CanI"; + const StartApplicationMethodName = "T42.ACS.StartApplication"; + const StopApplicationMethodName = "T42.ACS.StopApplication"; + const ActivateApplicationMethodName = "T42.ACS.ActivateApplication"; + const ACSExecute = "T42.ACS.Execute"; + const OnEventMethodName = "T42.ACS.OnEvent"; + const GetApplicationsMethodName = "T42.ACS.GetApplications"; + + var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; + + function getDefaultExportFromCjs (x) { + return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; + } + + function createRegistry(options) { + if (options && options.errorHandling + && typeof options.errorHandling !== "function" + && options.errorHandling !== "log" + && options.errorHandling !== "silent" + && options.errorHandling !== "throw") { + throw new Error("Invalid options passed to createRegistry. Prop errorHandling should be [\"log\" | \"silent\" | \"throw\" | (err) => void], but " + typeof options.errorHandling + " was passed"); + } + var _userErrorHandler = options && typeof options.errorHandling === "function" && options.errorHandling; + var callbacks = {}; + function add(key, callback, replayArgumentsArr) { + var callbacksForKey = callbacks[key]; + if (!callbacksForKey) { + callbacksForKey = []; + callbacks[key] = callbacksForKey; + } + callbacksForKey.push(callback); + if (replayArgumentsArr) { + setTimeout(function () { + replayArgumentsArr.forEach(function (replayArgument) { + var _a; + if ((_a = callbacks[key]) === null || _a === void 0 ? void 0 : _a.includes(callback)) { + try { + if (Array.isArray(replayArgument)) { + callback.apply(undefined, replayArgument); + } + else { + callback.apply(undefined, [replayArgument]); + } + } + catch (err) { + _handleError(err, key); + } + } + }); + }, 0); + } + return function () { + var allForKey = callbacks[key]; + if (!allForKey) { + return; + } + allForKey = allForKey.reduce(function (acc, element, index) { + if (!(element === callback && acc.length === index)) { + acc.push(element); + } + return acc; + }, []); + if (allForKey.length === 0) { + delete callbacks[key]; + } + else { + callbacks[key] = allForKey; + } + }; + } + function execute(key) { + var argumentsArr = []; + for (var _i = 1; _i < arguments.length; _i++) { + argumentsArr[_i - 1] = arguments[_i]; + } + var callbacksForKey = callbacks[key]; + if (!callbacksForKey || callbacksForKey.length === 0) { + return []; + } + var results = []; + callbacksForKey.forEach(function (callback) { + try { + var result = callback.apply(undefined, argumentsArr); + results.push(result); + } + catch (err) { + results.push(undefined); + _handleError(err, key); + } + }); + return results; + } + function _handleError(exceptionArtifact, key) { + var errParam = exceptionArtifact instanceof Error ? exceptionArtifact : new Error(exceptionArtifact); + if (_userErrorHandler) { + _userErrorHandler(errParam); + return; + } + var msg = "[ERROR] callback-registry: User callback for key \"" + key + "\" failed: " + errParam.stack; + if (options) { + switch (options.errorHandling) { + case "log": + return console.error(msg); + case "silent": + return; + case "throw": + throw new Error(msg); + } + } + console.error(msg); + } + function clear() { + callbacks = {}; + } + function clearKey(key) { + var callbacksForKey = callbacks[key]; + if (!callbacksForKey) { + return; + } + delete callbacks[key]; + } + return { + add: add, + execute: execute, + clear: clear, + clearKey: clearKey + }; + } + createRegistry.default = createRegistry; + var lib = createRegistry; + + + var CallbackRegistryFactory = /*@__PURE__*/getDefaultExportFromCjs(lib); + + function objectValues(source) { + if (!source) { + return []; + } + return Object.keys(source).map((key) => source[key]); + } + function objectClone(obj) { + let result; + try { + result = JSON.parse(JSON.stringify(obj || {})); + } + catch (error) { + result = {}; + } + return result; + } + function validate(callback, configuration) { + if (configuration.throwErrors) { + if (typeof callback !== "function") { + throw new Error("Please provide the callback as a function!"); + } + } + } + + const INTEROP_METHOD_RESPONSE_TIMEOUT_MS = 90000; + const INTEROP_METHOD_WAIT_TIMEOUT_MS = 90000; + + let urlAlphabet = + 'useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict'; + let nanoid = (size = 21) => { + let id = ''; + let i = size | 0; + while (i--) { + id += urlAlphabet[(Math.random() * 64) | 0]; + } + return id + }; + + class Utils { + static getGDMajorVersion() { + if (typeof window === "undefined") { + return -1; + } + if (!window.glueDesktop) { + return -1; + } + if (!window.glueDesktop.version) { + return -1; + } + const parsed = window.glueDesktop.version.split("."); + const major = Number(parsed[0]); + return isNaN(major) ? -1 : major; + } + static typedError(error) { + let err; + if (error instanceof Error) { + err = error; + } + else if (typeof error === "string") { + err = new Error(error); + } + else if ("message" in error && typeof error.message === "string" && error.message.length > 0) { + err = new Error(error.message); + } + else if ("returned" in error + && typeof error.returned === "object" + && "errorMsg" in error.returned + && typeof error.returned.errorMsg === "string" + && error.returned.errorMsg.length > 0) { + err = new Error(error.returned.errorMsg); + } + else { + err = new Error("Unknown error"); + } + return err; + } + static async callbackifyPromise(action, successCallback, errorCallback) { + const success = (result) => { + if (typeof successCallback === "function") { + successCallback(result); + } + return Promise.resolve(result); + }; + const fail = (error) => { + const err = Utils.typedError(error); + if (typeof errorCallback === "function") { + errorCallback(err.message); + return; + } + return Promise.reject(err); + }; + try { + const result = await action(); + return success(result); + } + catch (error) { + return fail(error); + } + } + static getMonitor(bounds, displays) { + const monitorsSortedByOverlap = displays.map((m) => { + const { left, top, workingAreaWidth: width, workingAreaHeight: height } = m; + const overlap = this.calculateTotalOverlap({ left, top, width, height }, bounds); + return { + monitor: m, + totalOverlap: overlap + }; + }).sort((a, b) => b.totalOverlap - a.totalOverlap); + return monitorsSortedByOverlap[0].monitor; + } + static getDisplayCenterOfScreen(a, currentDisplay, primaryDisplay) { + const physicalWidth = a.width / currentDisplay.scaleFactor; + const physicalHeight = a.height / currentDisplay.scaleFactor; + const physicalDisplayLeft = currentDisplay.workArea.left / primaryDisplay.scaleFactor; + const physicalDisplayTop = currentDisplay.workArea.top / primaryDisplay.scaleFactor; + const physicalDisplayWidth = currentDisplay.workArea.width / currentDisplay.scaleFactor; + const physicalDisplayHeight = currentDisplay.workArea.height / currentDisplay.scaleFactor; + const physicalHOffset = Math.max((physicalDisplayWidth - physicalWidth) / 2, 0); + const physicalVOffset = Math.max((physicalDisplayHeight - physicalHeight) / 2, 0); + const centeredPhysicalLeft = Math.floor(physicalDisplayLeft + physicalHOffset); + const centeredPhysicalTop = Math.floor(physicalDisplayTop + physicalVOffset); + const left = centeredPhysicalLeft * primaryDisplay.scaleFactor; + const top = centeredPhysicalTop * primaryDisplay.scaleFactor; + return { + left, + top, + width: a.width, + height: a.height + }; + } + static isNode() { + if (typeof Utils._isNode !== "undefined") { + return Utils._isNode; + } + if (typeof window !== "undefined") { + Utils._isNode = false; + return false; + } + try { + Utils._isNode = Object.prototype.toString.call(global.process) === "[object process]"; + } + catch (e) { + Utils._isNode = false; + } + return Utils._isNode; + } + static generateId() { + return nanoid(10); + } + static isPromise(value) { + return Boolean(value && typeof value.then === 'function'); + } + static isAsyncFunction(value) { + return value && {}.toString.call(value) === '[object AsyncFunction]'; + } + static isNullOrUndefined(value) { + return value === null || value === undefined; + } + static calculateTotalOverlap(r1, r2) { + const r1x = r1.left; + const r1y = r1.top; + const r1xMax = r1x + r1.width; + const r1yMax = r1y + r1.height; + const r2x = r2.left; + const r2y = r2.top; + const r2xMax = r2x + r2.width; + const r2yMax = r2y + r2.height; + const xOverlap = Math.max(0, Math.min(r1xMax, r2xMax) - Math.max(r1x, r2x)); + const yOverlap = Math.max(0, Math.min(r1yMax, r2yMax) - Math.max(r1y, r2y)); + return xOverlap * yOverlap; + } + } + + class ApplicationImpl { + constructor(_appManager, _name, _agm, _logger, _configuration) { + this._appManager = _appManager; + this._name = _name; + this._agm = _agm; + this._logger = _logger; + this._configuration = _configuration; + this._registry = CallbackRegistryFactory(); + _appManager.onInstanceStarted((instance) => { + if (instance.application && instance.application.name !== this._name) { + return; + } + this._registry.execute("instanceStarted", instance); + }); + _appManager.onInstanceStopped((instance) => { + if (instance.application && instance.application.name !== this._name) { + return; + } + this._registry.execute("instanceStopped", instance); + }); + _appManager.onAppRemoved((app) => { + if (app.name !== this._name) { + return; + } + this._registry.execute("appRemoved", app); + }); + _appManager.onAppChanged((app) => { + if (app.name !== this._name) { + return; + } + this._registry.execute("appChanged", app); + }); + _appManager.onAppAvailable((app) => { + if (app.name !== this._name) { + return; + } + this._props.IsReady = true; + this._registry.execute("appAvailable", app); + }); + _appManager.onAppUnavailable((app) => { + if (app.name !== this._name) { + return; + } + this._props.IsReady = false; + this._registry.execute("appUnavailable", app); + }); + } + get name() { return this._name; } + get title() { return this._props.Title; } + get version() { return this._props.Version; } + get autoStart() { return this._props.AutoStart; } + get isShell() { return this._props.IsShell; } + get caption() { return this._props.Caption; } + get hidden() { return this._props.IsHidden; } + get container() { return this._props.ApplicationName; } + get activityType() { return this._props.ActivityType; } + get activityWindowType() { return this._props.ActivityWindowType; } + get windowSettings() { + if (!this._props.Arguments) { + return {}; + } + return objectClone(this._props.Arguments); + } + get allowMultiple() { return this._props.AllowMultiple; } + get available() { return this._props.IsReady || true; } + get icon() { return this._props.Icon; } + get iconURL() { return this._props.IconUrl; } + get sortOrder() { return this._props.SortOrder; } + get userProperties() { + if (!this._props.UserProperties) { + return {}; + } + return objectClone(this._props.UserProperties); + } + get keywords() { + if (!this._props.Keywords) { + return []; + } + return this._props.Keywords; + } + get isActivity() { + return this._props.ActivityType !== undefined && this._props.ActivityType !== ""; + } + get configuration() { + return { + autoStart: this._props.AutoStart, + caption: this._props.Caption, + hidden: this._props.IsHidden, + container: this._props.ApplicationName, + activityType: this._props.ActivityType, + allowMultiple: this._props.AllowMultiple + }; + } + get instances() { + return this._appManager.instances().filter((instance) => instance.application.name === this._name); + } + get type() { + return this._props.Type; + } + get mode() { + if (!this._props) { + return "unknown"; + } + if (this._props.Mode && typeof this._props.Mode === "string") { + return this._props.Mode.toLowerCase(); + } + if (this.isActivity) { + return "unknown"; + } + if (this._props.Arguments && this._props.Arguments.mode && typeof this._props.Arguments.mode === "string") { + return this._props.Arguments.mode.toLowerCase(); + } + let styleAttributes = this._props.WindowStyleAttributes; + if (styleAttributes) { + styleAttributes = styleAttributes.split(" ").join(""); + const searchFor = "mode:\""; + const modeIndex = styleAttributes.indexOf(searchFor); + if (modeIndex !== -1) { + const startModeIndex = modeIndex + searchFor.length; + const stopModeIndex = styleAttributes.indexOf("\"", startModeIndex); + const style = styleAttributes.substr(startModeIndex, stopModeIndex - startModeIndex); + if (style && typeof style === "string") { + return style.toLowerCase(); + } + } + } + return "flat"; + } + async getConfiguration() { + const result = await this._agm.invoke(GetApplicationsMethodName, { v2: { apps: [this._name] } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + const config = result.returned.applications[0]; + return config; + } + updateFromProps(props) { + if (!this._props) { + this._props = { Name: props.Name }; + } + Object.keys(props).forEach((key) => { + this._props[key] = props[key]; + }); + } + start(context, options) { + return new Promise(async (resolve, reject) => { + var _a, _b, _c, _d; + if (isUndefinedOrNull(context)) { + context = {}; + } + else if (((_a = this._configuration()) === null || _a === void 0 ? void 0 : _a.throwErrors) && typeof context !== "object" || Array.isArray(context)) { + return reject(new Error(`Invalid "context" parameter - must be an object.`)); + } + if (isUndefinedOrNull(options)) { + options = {}; + } + else if (((_b = this._configuration()) === null || _b === void 0 ? void 0 : _b.throwErrors) && typeof options !== "object") { + return reject(new Error(`Invalid "options" parameter - must be an object.`)); + } + const name = this._name; + let waitForAGMInstance = (_d = ((_c = options.awaitInterop) !== null && _c !== void 0 ? _c : options.waitForAGMReady)) !== null && _d !== void 0 ? _d : true; + let startTimeout = 60000; + if (typeof options.timeout === "number") { + startTimeout = options.timeout * 1000; + } + if (options.relativeTo !== undefined && typeof options.relativeTo !== "string") { + options.relativeTo = options.relativeTo.id || ""; + } + const waitForApplicationInstance = (id) => { + let unsub; + const timeout = setTimeout(() => { + if (unsub) { + unsub(); + } + const errMsg = `timed out while waiting for instance id ${id} for app ${this.name}`; + this._logger.error(errMsg); + reject(new Error(errMsg)); + }, startTimeout); + const waitFunc = (i) => { + if (i.id !== id) { + return; + } + if (unsub) { + unsub(); + unsub = undefined; + } + clearTimeout(timeout); + resolve(i); + }; + if (waitForAGMInstance) { + const instance = this._appManager.instances().find((i) => i.id === id); + if (instance) { + unsub = instance.onAgmReady(waitFunc); + } + else { + unsub = this._appManager.onInstanceAgmServerReady(waitFunc); + } + } + else { + unsub = this._appManager.onInstanceStarted(waitFunc); + } + }; + try { + this._logger.trace(`starting application ${name} with options: ${JSON.stringify(options)}`); + const result = await this._agm.invoke(StartApplicationMethodName, { + Name: name, + Context: context, + Options: options + }, "best", { + methodResponseTimeoutMs: startTimeout, + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + const acsResult = result.returned; + if (typeof acsResult.timeout !== "undefined" && typeof options.timeout === "undefined") { + startTimeout = acsResult.timeout * 1000; + } + if (typeof acsResult.waitForInterop !== "undefined" && (typeof options.waitForAGMReady === "undefined" && typeof options.awaitInterop === "undefined")) { + waitForAGMInstance = acsResult.waitForInterop; + } + if (acsResult && acsResult.Id) { + if (this._appManager.mode === "startOnly") { + const instance = this._appManager.handleInstanceStarted({ + ActivityId: undefined, + IsActivityOwner: undefined, + Context: undefined, + Title: undefined, + AgmServers: undefined, + Id: acsResult.Id, + Name: acsResult.Name, + }); + resolve(instance); + } + else { + waitForApplicationInstance(acsResult.Id); + } + } + else { + resolve(undefined); + } + } + catch (error) { + const err = Utils.typedError(error); + reject(err); + } + }); + } + onInstanceStarted(callback) { + validate(callback, this._configuration()); + return this._registry.add("instanceStarted", callback); + } + onInstanceStopped(callback) { + validate(callback, this._configuration()); + return this._registry.add("instanceStopped", callback); + } + onAvailable(callback) { + validate(callback, this._configuration()); + if (this._props.IsReady) { + setTimeout(() => { + this._registry.execute("appAvailable", this); + }, 0); + } + return this._registry.add("appAvailable", callback); + } + onUnavailable(callback) { + validate(callback, this._configuration()); + if (this._props.IsReady === false) { + setTimeout(() => { + this._registry.execute("appUnavailable", this); + }, 0); + } + return this._registry.add("appUnavailable", callback); + } + onChanged(callback) { + validate(callback, this._configuration()); + this._registry.add("appChanged", callback); + } + onRemoved(callback) { + validate(callback, this._configuration()); + this._registry.add("appRemoved", callback); + } + } + + class InstanceImpl { + constructor(_id, _appName, _appManager, _agm, _activities, _windows, _logger, startFailed, _configuration) { + this._id = _id; + this._appName = _appName; + this._appManager = _appManager; + this._agm = _agm; + this._activities = _activities; + this._windows = _windows; + this._logger = _logger; + this._configuration = _configuration; + this._registry = CallbackRegistryFactory(); + if (startFailed) { + return; + } + this._unsubscribeInstanceStopped = this._appManager.onInstanceStopped((instance) => { + if (instance.id !== this._id) { + return; + } + this._registry.execute("stopped", instance); + }); + this._unsubscribeInstanceAgmServerReady = this._appManager.onInstanceAgmServerReady((instance) => { + if (instance.id !== this._id) { + return; + } + this._registry.execute("agmReady", instance); + }); + } + get id() { return this._id; } + get application() { return this._appManager.application(this._appName); } + get activity() { + if (!this._activities) { + throw new Error("This method requires glue.activities library to be enabled."); + } + return this._activities.all.instances.get() + .filter((activityInstance) => activityInstance.id === this._activityId)[0]; + } + get isActivityOwner() { return this._isActivityOwner; } + get activityInstances() { + return this._appManager.instances().filter((i) => i.application.type !== "activity" && + i.activityId && + i.activityId === this._activityId); + } + get activityOwnerInstance() { + if (!this._activityId) { + return undefined; + } + return this.activityInstances.filter((inst) => inst === null || inst === void 0 ? void 0 : inst.isActivityOwner)[0]; + } + get window() { + if (!this._windows) { + throw new Error("This method requires glue.windows library to be enabled."); + } + let win = this._windows.list().find((w) => w.id === this._id); + if (!win && this._activities && this.activity && this.activityOwnerInstance) { + win = this.activityOwnerInstance.window; + } + return win; + } + get context() { + var _a, _b, _c; + return (_c = (_a = this._startUpContext) !== null && _a !== void 0 ? _a : (_b = this.window) === null || _b === void 0 ? void 0 : _b.context) !== null && _c !== void 0 ? _c : {}; + } + get title() { return this._title; } + get isActivityInstance() { return this._isActivityInstance; } + get activityId() { return this._activityId; } + get inActivity() { return this._inActivity; } + get isSingleWindowApp() { return !this._inActivity; } + get agm() { + return this._agmInstance; + } + get interopInstance() { + return this._agmInstance; + } + onInteropReady(callback) { + validate(callback, this._configuration()); + if (this._agmInstance) { + setTimeout(() => { + this._registry.execute("agmReady", this); + }, 0); + } + return this._registry.add("agmReady", callback); + } + onAgmReady(callback) { + return this.onInteropReady(callback); + } + onStopped(callback) { + validate(callback, this._configuration()); + return this._registry.add("stopped", callback); + } + getWindow() { + return new Promise((resolve, reject) => { + const result = this.window; + if (result) { + resolve(result); + return; + } + const done = (error, window) => { + if (error) { + reject(error); + } + if (window) { + resolve(window); + } + setTimeout(() => { + clearTimeout(timeout); + unsub(); + }, 0); + }; + this._logger.trace(`waiting for window with id ${this._id} to appear`); + const timeoutInSeconds = 60; + const timeout = setTimeout(() => { + this._logger.trace(`window with id ${this._id} did not appear in ${timeoutInSeconds} sec`); + done(new Error(`can not find a window with id ${this._id}`)); + }, timeoutInSeconds * 1000); + const unsub = this._windows.onWindowAdded((w) => { + if (w.id === this._id) { + this._logger.trace(`window with id ${this._id} appeared`); + done(undefined, w); + } + }); + }); + } + updateFromProps(props) { + this._startUpContext = props.Context; + this._title = props.Title; + this._isActivityInstance = false; + if (props.ActivityId && props.ActivityId !== "") { + this._activityId = props.ActivityId; + this._isActivityInstance = true; + } + this._isActivityOwner = props.IsActivityOwner; + if (!this._activityId && this._startUpContext && this._startUpContext.activityId) { + this._activityId = this._startUpContext.activityId; + } + this._inActivity = Boolean(this._activityId); + this.updateAgmInstanceFromProps(props); + } + updateAgmInstanceFromProps(props) { + if (!props.AgmServers) { + return; + } + const agmInstances = props.AgmServers; + if (agmInstances && agmInstances.length > 0 && !isUndefinedOrNull(agmInstances[0])) { + this._agmInstance = agmInstances[0]; + } + } + stop() { + return new Promise((resolve, reject) => { + let idToResolve = this._id; + if (this.isActivityOwner) { + idToResolve = this.activityId; + } + const unsubscribe = this._appManager.onInstanceStopped((instance) => { + if (instance.id === idToResolve) { + this._logger.trace(`instance with id ${idToResolve} stopped`); + unsubscribe(); + resolve(); + } + }); + this._logger.trace(`stopping instance with id ${this._id}`); + this._agm.invoke(StopApplicationMethodName, { + Name: this._appName, + Id: this._id + }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }) + .then(() => { + if (this._appManager.mode === "startOnly") { + this._appManager.handleInstanceStopped({ + Name: this._appName, + Id: this.id + }); + resolve(); + } + }) + .catch((err) => reject(err)); + }); + } + activate() { + return this._agm.invoke(ActivateApplicationMethodName, { Name: this._appName, Id: this._id }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + done() { + this._registry.clear(); + this._unsubscribeInstanceAgmServerReady(); + this._unsubscribeInstanceStopped(); + } + getContext() { + return Promise.resolve(this.context); + } + async startedBy() { + const result = await this._agm.invoke(ACSExecute, { command: "getStartedBy", Name: this._appName, Id: this._id }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return result.returned; + } + } + + class AppManagerImpl { + constructor(mode, _agm, _activities, _windows, _logger, _gdMajorVersion, _configuration) { + this.mode = mode; + this._agm = _agm; + this._activities = _activities; + this._windows = _windows; + this._logger = _logger; + this._gdMajorVersion = _gdMajorVersion; + this._configuration = _configuration; + this._apps = {}; + this._instances = []; + this._registry = CallbackRegistryFactory(); + this.getConfigurations = async (apps) => { + const args = { + v2: { + apps: undefined + } + }; + if (Array.isArray(apps)) { + args.v2 = { + apps + }; + } + const result = await this._agm.invoke(GetApplicationsMethodName, args, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return result.returned.applications; + }; + this.application = (name) => { + var _a; + if (((_a = this._configuration()) === null || _a === void 0 ? void 0 : _a.throwErrors) && typeof name !== "string" || isNullOrWhiteSpace(name)) { + throw new Error(`"name" must be string`); + } + return this._apps[name]; + }; + this.applications = () => { + return Object.keys(this._apps).map((k) => this._apps[k]); + }; + this.instances = () => { + return this._instances.map((i) => i); + }; + this.getMyInstance = () => { + const glue42gd = typeof window !== "undefined" && window.glue42gd; + if (glue42gd) { + if (this._gdMajorVersion >= 3) { + const instanceId = glue42gd.appInstanceId; + return this._instances.find((i) => i.id === instanceId); + } + } + else { + const instanceId = this._agm.instance.instance; + return this._instances.find((i) => i.id === instanceId); + } + return undefined; + }; + this.getMyApplication = () => { + var _a; + if (this._agm.instance) { + return (_a = this.application(this._agm.instance.applicationName)) !== null && _a !== void 0 ? _a : this.application(this._agm.instance.application); + } + }; + this.handleSnapshotAppsAdded = (newApps) => { + const currentApps = this.applications(); + if (currentApps.length > 0) { + currentApps.forEach((item) => { + const name = item.name; + const alreadyExists = newApps.find((i) => i.Name === item.name); + if (!alreadyExists) { + this.handleAppRemoved({ Name: name }); + } + }); + } + newApps.forEach((item) => { + const alreadyExists = currentApps.find((i) => i.name === item.Name); + if (!alreadyExists) { + this.handleAppAdded(item); + } + }); + }; + this.handleSnapshotInstanceStarted = (newInstances) => { + const currentInstances = this.instances(); + if (currentInstances.length > 0) { + currentInstances.forEach((item) => { + const id = item.id; + const alreadyExists = newInstances.find((i) => i.Id === id); + if (!alreadyExists) { + this.handleInstanceStopped({ Name: item.application.name, Id: id }); + } + }); + } + newInstances.forEach((item) => { + const alreadyExists = currentInstances.find((i) => i.id === item.Id); + if (!alreadyExists) { + this.handleInstanceStarted(item); + } + }); + }; + this.handleAppAdded = (props) => { + const id = this._getAppId(props); + this._logger.trace(`adding app ${id}`); + this._apps[id] = new ApplicationImpl(this, id, this._agm, this._logger, this._configuration); + const app = this._updateAppFromProps(props); + this._registry.execute("appAdded", app); + this._registry.execute("appAvailable", app); + }; + this.handleAppUpdated = (props) => { + const app = this._updateAppFromProps(props); + this._registry.execute("appChanged", app); + }; + this.handleAppRemoved = (props) => { + const id = this._getAppId(props); + this._logger.trace(`removing app ${id}`); + const app = this.application(id); + this._instances = this._instances.filter((i) => i.application.name !== app.name); + delete this._apps[id]; + this._registry.execute("appRemoved", app); + }; + this.handleAppReady = (props) => { + const id = this._getAppId(props); + const app = this._getAppOrThrow(id); + app.updateFromProps(props); + if (app.available) { + this._registry.execute("appAvailable", app); + } + else { + this._registry.execute("appUnavailable", app); + } + }; + this.handleInstanceStarted = (props) => { + this._logger.trace(`started app ${props.Name} ${props.Id}`); + const id = this._getInstanceId(props); + const appName = this._getInstanceAppName(props); + const instance = new InstanceImpl(id, appName, this, this._agm, this._activities, this._windows, this._logger, false, this._configuration); + this._updateInstanceFromProps(instance, props); + this._instances.push(instance); + this._registry.execute("instanceStarted", instance); + return instance; + }; + this.handleInstanceStopped = (props) => { + this._logger.trace(`instance stopped ${props.Name} ${props.Id}`); + const id = this._getInstanceId(props); + const appName = this._getInstanceAppName(props); + const instance = this._getInstanceOrThrow(id, appName); + this._instances = this._instances.filter((i) => !this._matchInstance(i, id, appName)); + this._registry.execute("instanceStopped", instance); + instance.done(); + }; + this.handleInstanceAgmServerReady = (props) => { + this._logger.trace(`instance interop server ready ${props.Name} ${props.Id}`); + const id = this._getInstanceId(props); + const appName = this._getInstanceAppName(props); + const instance = this._getInstanceOrThrow(id, appName); + instance.updateAgmInstanceFromProps(props); + this._registry.execute("instanceAgmServerReady", instance); + }; + this.handleInstanceStartFailed = (props) => { + const id = this._getInstanceId(props); + const appName = this._getInstanceAppName(props); + const startFailed = true; + const instance = new InstanceImpl(id, appName, undefined, undefined, undefined, undefined, this._logger, startFailed, this._configuration); + this._updateInstanceFromProps(instance, props); + this._registry.execute("instanceStartFailed", instance); + }; + this.handleInstanceUpdated = (props) => { + const id = this._getInstanceId(props); + const app = this._getInstanceAppName(props); + const instance = this._getInstanceOrThrow(id, app); + this._updateInstanceFromProps(instance, props); + }; + this.onInstanceStarted = (callback) => { + validate(callback, this._configuration()); + return this._registry.add("instanceStarted", callback, this._instances); + }; + this.onInstanceStartFailed = (callback) => { + validate(callback, this._configuration()); + return this._registry.add("instanceStartFailed", callback); + }; + this.onInstanceStopped = (callback) => { + validate(callback, this._configuration()); + return this._registry.add("instanceStopped", callback); + }; + this.onInstanceUpdated = (callback) => { + validate(callback, this._configuration()); + return this._registry.add("instanceChanged", callback); + }; + this.onInstanceAgmServerReady = (callback) => { + validate(callback, this._configuration()); + return this._registry.add("instanceAgmServerReady", callback); + }; + this.onAppAdded = (callback) => { + validate(callback, this._configuration()); + return this._registry.add("appAdded", callback, Object.values(this._apps)); + }; + this.onAppRemoved = (callback) => { + validate(callback, this._configuration()); + return this._registry.add("appRemoved", callback); + }; + this.onAppAvailable = (callback) => { + validate(callback, this._configuration()); + return this._registry.add("appAvailable", callback); + }; + this.onAppUnavailable = (callback) => { + validate(callback, this._configuration()); + return this._registry.add("appUnavailable", callback); + }; + this.onAppChanged = (callback) => { + validate(callback, this._configuration()); + return this._registry.add("appChanged", callback); + }; + } + _getAppOrThrow(id) { + const result = this.application(id); + if (!result) { + throw Error(`app with id ${id} not found`); + } + return result; + } + _getAppId(props) { + return props.Name; + } + _matchInstance(instance, id, appName) { + return instance.id === id && instance.application.name === appName; + } + _getInstanceByIdAndName(id, appName) { + return this._instances.filter((i) => this._matchInstance(i, id, appName))[0]; + } + _getInstanceOrThrow(id, appName) { + const result = this._getInstanceByIdAndName(id, appName); + if (!result) { + throw Error(`instance with id ${id} not found`); + } + return result; + } + _getInstanceId(props) { + return props.Id; + } + _getInstanceAppName(props) { + return props.Name; + } + _updateAppFromProps(props) { + const id = this._getAppId(props); + this._logger.trace(`updating app with + ${id}, ${JSON.stringify(props)}`); + const app = this._getAppOrThrow(id); + app.updateFromProps(props); + return app; + } + _updateInstanceFromProps(instance, props) { + this._logger.trace("updating instance with " + this._getInstanceId(props) + " for app " + this._getInstanceAppName(props)); + instance.updateFromProps(props); + } + } + + function promisify(promise, successCallback, errorCallback) { + const isFunction = (arg) => { + return !!(arg && arg.constructor && arg.call && arg.apply); + }; + if (!isFunction(successCallback) && !isFunction(errorCallback)) { + return promise; + } + if (!isFunction(successCallback)) { + successCallback = () => { + }; + } + else if (!isFunction(errorCallback)) { + errorCallback = () => { + }; + } + return promise.then(successCallback, errorCallback); + } + class EntitlementsImpl { + constructor(_agm) { + this._agm = _agm; + this._registry = CallbackRegistryFactory(); + this._isMethodRegistered = false; + this.handleBranchModified = (branch) => { + this._registry.execute("branchChanged", branch); + }; + this.handleBranchesModified = (branches) => { + this._registry.execute("branchesChanged", branches); + }; + this.getRegion = (success, error) => { + return promisify(this._agmInvoke(GetConfigurationRegionMethodName, (e) => e.returned.Region), success, error); + }; + this.getBranches = (success, error) => { + const promise = this._agmInvoke(GetBranchesMethodName, (e) => { + const obj = e.returned.Branches; + return Object.keys(obj).map((key) => obj[key]); + }); + return promisify(promise, success, error); + }; + this.getCurrentBranch = (success, error) => { + const promise = this._agmInvoke(GetCurrentBranchMethodName, (e) => e.returned.Branch, undefined); + return promisify(promise, success, error); + }; + this.setRegion = (region, success, error) => { + const promise = this._agmInvoke(SetConfigurationRegionMethodName, (e) => e.returned.ResultMessage, { Region: region }); + return promisify(promise, success, error); + }; + this.setCurrentBranch = (branch, success, error) => { + const promise = this._agmInvoke(SetCurrentBranchMethodName, (e) => e.returned.ResultMessage, { Branch: branch }); + return promisify(promise, success, error); + }; + this.currentUser = (success, error) => { + const promise = this._agmInvoke(GetUserMethodName); + return promisify(promise, success, error); + }; + this.getFunctionalEntitlement = (funct, success, error) => { + const promise = this._agmInvoke(GetFunctionalEntitlementMethodName, (e) => e.returned.Entitlement, { Function: funct }); + return promisify(promise, success, error); + }; + this.getFunctionalEntitlementBranch = (funct, branch, success, error) => { + const promise = this._agmInvoke(GetFunctionalEntitlementMethodName, (e) => e.returned.Entitlement, { Function: funct, Branch: branch }); + return promisify(promise, success, error); + }; + this.canI = (func, success, error) => { + const promise = this._agmInvoke(CanIMethodName, (e) => e.returned.Result, { Function: func }); + return promisify(promise, success, error); + }; + this.canIBranch = (func, branch, success, error) => { + const promise = this._agmInvoke(CanIMethodName, (e) => e.returned.Result, { Function: func, Branch: branch }); + return promisify(promise, success, error); + }; + this.onBranchesChanged = (callback) => { + return this._registry.add("branchesChanged", callback); + }; + this.onBranchChanged = (callback) => { + return this._registry.add("branchChanged", callback); + }; + this.exit = (options) => { + return this._agmInvoke(ShutdownMethodName, null, options); + }; + this.onShuttingDown = (callback) => { + this.registerMethod(); + return this._registry.add("onShuttingDown", callback); + }; + this.restart = (options) => { + return this._agmInvoke(RestartMethodName, null, options); + }; + this._agmInvoke = (method, transformFunction, args) => { + args = args || {}; + return new Promise((resolve, reject) => { + const errHandler = (error) => reject(error); + this._agm.invoke(method, args, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }) + .then((result) => { + if (!transformFunction) { + transformFunction = (d) => d.returned; + } + resolve(transformFunction(result)); + }) + .catch(errHandler); + }); + }; + } + registerMethod() { + if (!this._isMethodRegistered) { + this._agm.register(OnGDShutdownMethodName, async (args) => { + try { + const results = await Promise.all(this._registry.execute("onShuttingDown", args)); + const prevent = results.some((r) => r.prevent); + return { prevent }; + } + catch (error) { + } + }); + this._isMethodRegistered = true; + } + } + } + + function snapshot(interop, appManager) { + return new Promise((resolve, reject) => { + interop.invoke(GetApplicationsMethodName, { skipIcon: true }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }) + .then((response) => { + var _a; + const data = response.returned; + const configuration = (_a = response.returned.configuration) !== null && _a !== void 0 ? _a : {}; + if (!data) { + resolve(configuration); + } + const applications = data.applications; + if (!applications) { + resolve(configuration); + } + objectValues(applications).map((item) => appManager.handleAppAdded(item)); + resolve(configuration); + }) + .catch((err) => reject(new Error(`Error getting application snapshot: ${err.message}`))); + }); + } + + const OnBranchChangedEvent = "OnBranchChanged"; + const OnBranchesModifiedEvent = "OnBranchesModified"; + const OnApplicationAddedEvent = "OnApplicationAdded"; + const OnApplicationRemovedEvent = "OnApplicationRemoved"; + const OnApplicationChangedEvent = "OnApplicationChanged"; + const OnApplicationReadyEvent = "OnApplicationReady"; + const OnApplicationStartedEvent = "OnApplicationStarted"; + const OnApplicationAgmServerReadyEvent = "OnApplicationAgmServerReady"; + const OnApplicationUpdatedEvent = "OnApplicationUpdated"; + const OnApplicationStoppedEvent = "OnApplicationStopped"; + const OnApplicationStartFailedEvent = "OnApplicationStartFailed"; + + function createDataSubscription(agm, applications, entitlements, skipIcons) { + let subscription; + let initiated = false; + const start = () => { + let resolveFunc; + let rejectFunc; + const resultPromise = new Promise((resolve, reject) => { + resolveFunc = resolve; + rejectFunc = reject; + }); + agm.subscribe(OnEventMethodName, { arguments: { skipIcon: skipIcons }, waitTimeoutMs: 10000 }) + .then((s) => { + subscription = s; + subscription.onData((streamData) => { + var _a; + const events = streamData.data; + const configuration = (_a = events.configuration) !== null && _a !== void 0 ? _a : {}; + const onApplicationAddedEventArgs = objectValues(events[OnApplicationAddedEvent]); + if (streamData.data.isSnapshot) { + applications.handleSnapshotAppsAdded(onApplicationAddedEventArgs); + } + else { + onApplicationAddedEventArgs.forEach((item) => applications.handleAppAdded(item)); + } + objectValues(events[OnApplicationChangedEvent]) + .forEach((item) => applications.handleAppUpdated(item)); + objectValues(events[OnApplicationRemovedEvent]) + .forEach((item) => applications.handleAppRemoved(item)); + objectValues(events[OnApplicationReadyEvent]) + .forEach((item) => applications.handleAppReady(item)); + const onApplicationStartedEventArgs = objectValues(events[OnApplicationStartedEvent]); + if (streamData.data.isSnapshot) { + applications.handleSnapshotInstanceStarted(onApplicationStartedEventArgs); + } + else { + onApplicationStartedEventArgs.forEach((item) => applications.handleInstanceStarted(item)); + } + objectValues(events[OnApplicationStartFailedEvent]) + .forEach((item) => applications.handleInstanceStartFailed(item)); + objectValues(events[OnApplicationStoppedEvent]) + .forEach((item) => applications.handleInstanceStopped(item)); + objectValues(events[OnApplicationUpdatedEvent]) + .forEach((item) => applications.handleInstanceUpdated(item)); + objectValues(events[OnApplicationAgmServerReadyEvent]) + .forEach((item) => applications.handleInstanceAgmServerReady(item)); + objectValues(events[OnBranchChangedEvent]) + .forEach((item) => entitlements.handleBranchModified(item)); + objectValues(events[OnBranchesModifiedEvent]) + .forEach((item) => entitlements.handleBranchesModified(item)); + if (!initiated) { + initiated = true; + const hasMyAppInSnapShot = onApplicationAddedEventArgs.some((a) => a.Name === agm.instance.application); + const hasMyInstanceInSnapShot = onApplicationStartedEventArgs.some((i) => i.Id === agm.instance.instance); + if (hasMyAppInSnapShot) { + if (hasMyInstanceInSnapShot) { + resolveFunc(configuration); + } + else { + const un = applications.onInstanceStarted((i) => { + if (i.id === agm.instance.instance) { + un(); + resolveFunc(configuration); + } + }); + } + } + else { + resolveFunc(configuration); + } + } + }); + subscription.onFailed((err) => rejectFunc(err)); + }) + .catch((err) => { var _a; return rejectFunc(`Error subscribing for ${OnEventMethodName} stream. Err: ${(_a = err.message) !== null && _a !== void 0 ? _a : JSON.stringify(err)}`); }); + return resultPromise; + }; + const stop = () => { + if (subscription) { + subscription.close(); + } + }; + return { + start, + stop + }; + } + + const InMemoryStoreCommandMethodName = "T42.ACS.InMemoryStoreCommand"; + class InMemoryStore { + constructor(interop) { + this.interop = interop; + } + import(apps, mode) { + if (!apps || !Array.isArray(apps)) { + return Promise.reject(new Error("invalid apps argument - should be an array of application definitions")); + } + if (mode && mode !== "replace" && mode !== "merge") { + return Promise.reject(new Error("invalid mode argument - should be 'replace' or 'merge'")); + } + mode = mode !== null && mode !== void 0 ? mode : "replace"; + const command = { + command: "import", + args: { + apps, + mode + } + }; + return this.interop.invoke(InMemoryStoreCommandMethodName, command, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }) + .then((r) => r.returned); + } + export() { + return this.interop.invoke(InMemoryStoreCommandMethodName, { command: "export" }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }) + .then((r) => r.returned.apps); + } + remove(app) { + if (!app || typeof app !== "string") { + return Promise.reject(new Error("invalid app name, should be a string value")); + } + const command = { + command: "remove", + args: { + apps: [app] + } + }; + return this.interop.invoke(InMemoryStoreCommandMethodName, command, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }).then((r) => r.returned); + } + clear() { + const command = { + command: "clear" + }; + return this.interop.invoke(InMemoryStoreCommandMethodName, command, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }).then((r) => r.returned); + } + createAppDef(name, url) { + if (!url) { + url = "https://google.com"; + } + return { + name, + type: "window", + title: name, + details: { + url + } + }; + } + } + + var AppManagerFactory = (config) => { + if (!config) { + throw Error("config not set"); + } + if (!config.agm) { + throw Error("config.agm is missing"); + } + const START_ONLY = "startOnly"; + const SKIP_ICONS = "skipIcons"; + const FULL = "full"; + const mode = config.mode || START_ONLY; + if (mode !== START_ONLY && mode !== SKIP_ICONS && mode !== FULL) { + throw new Error(`Invalid mode for appManager lib - ${mode} is not supported`); + } + const activities = config.activities; + const agm = config.agm; + const logger = config.logger; + const windows = config.windows; + let configuration = {}; + const appManager = new AppManagerImpl(mode, agm, activities, windows, logger.subLogger("applications"), config.gdMajorVersion, () => configuration); + const entitlements = new EntitlementsImpl(agm); + let readyPromise; + if (mode === START_ONLY) { + readyPromise = snapshot(agm, appManager); + } + else { + const subscription = createDataSubscription(agm, appManager, entitlements, mode === SKIP_ICONS); + readyPromise = subscription.start(); + } + const api = { + ready: () => readyPromise.then((c) => { configuration = c; }), + applications: appManager.applications, + application: appManager.application, + getConfigurations: appManager.getConfigurations, + onAppAdded: appManager.onAppAdded, + onAppRemoved: appManager.onAppRemoved, + onAppChanged: appManager.onAppChanged, + onAppAvailable: appManager.onAppAvailable, + onAppUnavailable: appManager.onAppUnavailable, + instances: appManager.instances, + get myInstance() { + return appManager.getMyInstance(); + }, + get myApplication() { + return appManager.getMyApplication(); + }, + onInstanceStarted: appManager.onInstanceStarted, + onInstanceStopped: appManager.onInstanceStopped, + onInstanceUpdated: appManager.onInstanceUpdated, + onInstanceStartFailed: appManager.onInstanceStartFailed, + getRegion: entitlements.getRegion, + getBranches: entitlements.getBranches, + getCurrentBranch: entitlements.getCurrentBranch, + getFunctionalEntitlement: entitlements.getFunctionalEntitlement, + getFunctionalEntitlementBranch: entitlements.getFunctionalEntitlementBranch, + setCurrentBranch: entitlements.setCurrentBranch, + setRegion: entitlements.setRegion, + currentUser: entitlements.currentUser, + canI: entitlements.canI, + canIBranch: entitlements.canIBranch, + onBranchesChanged: entitlements.onBranchesChanged, + exit: entitlements.exit, + restart: entitlements.restart, + onShuttingDown: entitlements.onShuttingDown, + inMemory: new InMemoryStore(agm) + }; + return api; + }; + + const T42JumpListAction = "T42.JumpList.Action"; + class JumpListManager { + constructor() { + this._groupActionCallbacks = new Map(); + this._registered = false; + } + init(executor, agm, logger) { + this._executor = executor; + this._agm = agm; + this._logger = logger; + this.registerCallbackMethod(); + } + setEnabled(windowId, enabled) { + const settings = { + enabled + }; + return this._executor.updateJumpList(windowId, settings); + } + createCategory(windowId, title, actions) { + this.validateActions(title, actions); + const settings = { + category: { + title, + operation: "create", + actions: this.toUpdateActions(windowId, "create", title, actions) + } + }; + return this._executor.updateJumpList(windowId, settings); + } + removeCategory(windowId, title) { + const settings = { + category: { + title, + operation: "remove", + actions: [] + } + }; + this.manageActionCallback(windowId, settings.category.operation, title); + return this._executor.updateJumpList(windowId, settings); + } + createActions(windowId, categoryTitle, actions) { + this.validateActions(categoryTitle, actions); + const settings = { + category: { + title: categoryTitle, + operation: "update", + actions: this.toUpdateActions(windowId, "create", categoryTitle, actions) + } + }; + return this._executor.updateJumpList(windowId, settings); + } + removeActions(windowId, categoryTitle, actions) { + const settings = { + category: { + title: categoryTitle, + operation: "update", + actions: this.toUpdateActions(windowId, "remove", categoryTitle, actions) + } + }; + return this._executor.updateJumpList(windowId, settings); + } + async getActions(windowId, catgoryTitle) { + const actions = []; + const configuration = await this.getJumpListSettings(windowId); + const currentCategory = configuration.categories.find((category) => category.title === catgoryTitle); + if (currentCategory) { + currentCategory.actions.forEach((action) => { + const actionCallback = this.getActionCallback(action.callbackId); + if (actionCallback) { + action.callback = actionCallback.callback; + } + actions.push({ + icon: action.icon, + callback: action.callback, + singleInstanceTitle: action.singleInstanceTitle, + multiInstanceTitle: action.multiInstanceTitle + }); + }); + } + return Promise.resolve(actions); + } + getJumpListSettings(windowId) { + return this._executor.getJumpList(windowId); + } + toUpdateActions(windowId, operation, categoryTitle, actions) { + return actions.map((action) => { + const updateAction = { + icon: action.icon, + callback: action.callback, + callbackId: Utils.generateId(), + singleInstanceTitle: action.singleInstanceTitle, + multiInstanceTitle: action.multiInstanceTitle, + operation + }; + this.manageActionCallback(windowId, operation, categoryTitle, updateAction); + return updateAction; + }); + } + manageActionCallback(windowId, operation, categoryTitle, updateAction) { + var _a; + const groupCallbacksKey = `${categoryTitle}-${windowId}`; + if (operation === "create") { + if (!this._groupActionCallbacks.has(groupCallbacksKey)) { + this._groupActionCallbacks.set(groupCallbacksKey, []); + } + const categoryActionCallbacks = this._groupActionCallbacks.get(groupCallbacksKey); + categoryActionCallbacks.push({ + callbackId: updateAction.callbackId, + callback: updateAction.callback + }); + } + else if (operation === "remove") { + if (updateAction) { + let categoryActionCallbacks = (_a = this._groupActionCallbacks.get(groupCallbacksKey)) !== null && _a !== void 0 ? _a : []; + categoryActionCallbacks = categoryActionCallbacks.filter((accCal) => accCal.callbackId !== updateAction.callbackId); + if (categoryActionCallbacks.length === 0) { + this._groupActionCallbacks.delete(groupCallbacksKey); + } + else { + this._groupActionCallbacks.set(groupCallbacksKey, categoryActionCallbacks); + } + } + else { + this._groupActionCallbacks.delete(groupCallbacksKey); + } + } + } + registerCallbackMethod() { + if (this._registered) { + return; + } + this._registered = true; + try { + this._agm.register(T42JumpListAction, (args, caller) => { + const actionCallback = this.getActionCallback(args.callbackId); + if (actionCallback) { + try { + actionCallback.callback(); + } + catch (e) { + this._logger.error("Unable to execute user callback for jump list action!", e); + } + } + }); + } + catch (e) { + this._logger.error(`Unable to register method ${T42JumpListAction} for invoking jump list action callbacks!`, e); + return Promise.reject(e); + } + } + getActionCallback(callbackId) { + let callbackAction; + [...this._groupActionCallbacks.values()].forEach((callbacks) => { + const callback = callbacks.find((cal) => cal.callbackId === callbackId); + if (callback) { + callbackAction = callback; + } + }); + return callbackAction; + } + validateActions(category, actions) { + if (!(actions && actions.length > 0)) { + throw new Error(`Category '${category}' doesn't contain any actions!`); + } + actions.forEach((action) => { + if (!action.singleInstanceTitle) { + throw new Error(`Category '${category}' contains an action with undefined singleInstanceTitle!`); + } + if (!action.multiInstanceTitle) { + throw new Error(`Category '${category}' contains an action with undefined multiInstanceTitle!`); + } + if (!action.callback) { + throw new Error(`Category '${category}' contains an action with undefined callback function!`); + } + }); + } + } + var jumpListManager = new JumpListManager(); + + class WindowStore { + constructor() { + this.waitForTimeoutInMilliseconds = 60000; + this._windows = {}; + this._pendingWindows = {}; + this._pendingWindowsStates = {}; + this._registry = CallbackRegistryFactory(); + } + init(logger) { + this._logger = logger; + } + get(id) { + return this._windows[id] || this._pendingWindows[id]; + } + getIfReady(id) { + return this._windows[id]; + } + get list() { + return this._windows; + } + add(window, state) { + const isExist = typeof this._pendingWindows[window.API.id] !== "undefined"; + if (isExist) { + this._logger.error(`trying to add window with id ${window.API.id} from windowStore, which already exists`); + return; + } + this._pendingWindows[window.API.id] = window; + this._pendingWindowsStates[window.API.id] = state; + this._registry.execute("on-added", window); + if (this.shouldMarkReadyToShow(state)) { + this.markReadyToShow(window.API.id); + } + } + remove(window) { + delete this._windows[window.API.id]; + delete this._pendingWindows[window.API.id]; + delete this._pendingWindowsStates[window.API.id]; + this._registry.execute("on-removed", window); + } + setUrlChangedState(windowId) { + const targetWindowState = this._pendingWindowsStates[windowId]; + if (typeof targetWindowState === "undefined") { + return; + } + targetWindowState.urlChanged = true; + if (this.shouldMarkReadyToShow(targetWindowState)) { + this.markReadyToShow(windowId); + } + } + setCompositionChangedState(wrapper) { + const windowId = wrapper.API.id; + const targetWindowState = this._pendingWindowsStates[windowId]; + if (typeof targetWindowState === "undefined") { + return; + } + targetWindowState.compositionChanged = true; + if (this.shouldMarkReadyToShow(targetWindowState)) { + this.markReadyToShow(windowId); + } + } + waitFor(id) { + return new Promise((resolve, reject) => { + let unReady; + let unRemoved; + const timeout = setTimeout(() => { + unReady(); + unRemoved(); + reject(new Error(`Window with id "${id}" was not ready within ${this.waitForTimeoutInMilliseconds} milliseconds.`)); + }, this.waitForTimeoutInMilliseconds); + const win = this._windows[id]; + if (win) { + clearTimeout(timeout); + resolve(win); + } + else { + const cleanup = () => { + clearTimeout(timeout); + unReady(); + unRemoved(); + }; + unReady = this.onReadyWindow((w) => { + if (w.API.id !== id) { + return; + } + cleanup(); + resolve(w); + }); + unRemoved = this.onRemoved((w) => { + if (w.API.id !== id) { + return; + } + cleanup(); + reject(new Error(`Window with id "${id}" was closed before it became ready.`)); + }); + } + }); + } + onReadyWindow(callback) { + return this._registry.add("on-ready", callback); + } + onAdded(callback) { + return this._registry.add("on-added", callback); + } + onRemoved(callback) { + return this._registry.add("on-removed", callback); + } + markReadyToShow(windowId) { + if (this._pendingWindows[windowId]) { + this._windows[windowId] = this._pendingWindows[windowId]; + delete this._pendingWindows[windowId]; + delete this._pendingWindowsStates[windowId]; + } + this._registry.execute("on-ready", this._windows[windowId]); + } + shouldMarkReadyToShow(targetWindowState) { + return targetWindowState && targetWindowState.urlChanged && targetWindowState.ready && targetWindowState.compositionChanged; + } + } + var windowStore = new WindowStore(); + + class JumpListActions { + constructor(windowId, configuration) { + this.windowId = windowId; + this._categoryTitle = configuration.title; + } + list() { + return jumpListManager.getActions(this.windowId, this._categoryTitle); + } + create(actions) { + return jumpListManager.createActions(this.windowId, this._categoryTitle, actions); + } + remove(actions) { + return jumpListManager.removeActions(this.windowId, this._categoryTitle, actions); + } + } + + class JumpListCategories { + constructor(windowId) { + this.windowId = windowId; + } + list() { + return this.getCategories(); + } + create(title, actions) { + return jumpListManager.createCategory(this.windowId, title, actions); + } + remove(title) { + return jumpListManager.removeCategory(this.windowId, title); + } + async find(title) { + const categories = await this.getCategories(); + return categories.find((cat) => cat.title === title); + } + async getCategories() { + const result = []; + const configuration = await jumpListManager.getJumpListSettings(this.windowId); + configuration.categories.forEach((category) => { + result.push({ + title: category.title, + actions: new JumpListActions(this.windowId, category) + }); + }); + return result; + } + } + + class JumpList { + constructor(windowId) { + this.windowId = windowId; + this._categories = new JumpListCategories(windowId); + } + get categories() { + return this._categories; + } + async isEnabled() { + const configuration = await jumpListManager.getJumpListSettings(this.windowId); + return configuration.enabled; + } + setEnabled(enabled) { + return jumpListManager.setEnabled(this.windowId, enabled); + } + } + + var windowFactory = (id, options, executor, logger, appManagerGetter, displayAPIGetter, channelsAPIGetter, agm) => { + var _a, _b, _c, _d; + const _registry = CallbackRegistryFactory(); + const getChannels = () => { + const channels = channelsAPIGetter(); + if (!channels) { + throw new Error(`To use this method you need to enable channels API - set the channels property to true when initializing the Glue42 library`); + } + return channels; + }; + const _id = id; + const _name = options.name; + const _mode = options.mode; + let _bounds = options.bounds; + let _url = options.url; + let _title = options.title; + let _context = (_a = options.context) !== null && _a !== void 0 ? _a : {}; + let _frameColor = options.frameColor; + let _focus = options.focus; + let _neighbours = (_b = options.neighbours) !== null && _b !== void 0 ? _b : {}; + let _groupId = options.groupId; + let _isGroupHeaderVisible = options.isGroupHeaderVisible; + let _isTabHeaderVisible = options.isTabHeaderVisible; + let _isGroupHibernated = options.isGroupHibernated; + let _isGroupVisible = options.isGroupVisible; + let _isTabSelected = (_c = options.isTabSelected) !== null && _c !== void 0 ? _c : false; + let _settings = options.settings; + const _applicationName = options.applicationName; + let _isVisible = options.isVisible; + let _isSticky = options.isSticky; + let _isCollapsed = options.isCollapsed; + let _windowState = options.state; + let _tabGroupId = options.tabGroupId; + let _tabIndex = options.tabIndex; + let _frameId = options.frameId; + let _isLocked = options.isLocked; + let _allowWorkspaceDrop = options.allowWorkspaceDrop; + let _isPinned = options.isPinned; + let _group; + let _frameButtons = (_d = options.frameButtons) !== null && _d !== void 0 ? _d : []; + let _zoomFactor = options.zoomFactor; + let _placementSettings = options.placementSettings; + const _jumpList = new JumpList(id); + function close(cbOrOptions, error) { + if (typeof cbOrOptions === "undefined" || typeof cbOrOptions === "function") { + return Utils.callbackifyPromise(() => { + if (!id) { + throw new Error("The window is already closed."); + } + return executor.close(resultWindow); + }, cbOrOptions, error); + } + else { + return executor.close(resultWindow, cbOrOptions); + } + } + function navigate(newUrl, optionsOrCallback, error) { + if (typeof optionsOrCallback === "function") { + return Utils.callbackifyPromise(() => { + if (isNullOrWhiteSpace(newUrl)) { + throw new Error("The new URL must be a non-empty string."); + } + return executor.navigate(resultWindow, newUrl); + }, optionsOrCallback, error); + } + if (isNullOrWhiteSpace(newUrl)) { + throw new Error("The new URL must be a non-empty string."); + } + if ((optionsOrCallback === null || optionsOrCallback === void 0 ? void 0 : optionsOrCallback.timeout) && typeof optionsOrCallback.timeout !== "number") { + throw new Error("Timeout argument must be a valid number"); + } + return executor.navigate(resultWindow, newUrl, optionsOrCallback); + } + function setStyle(style, success, error) { + return Utils.callbackifyPromise(() => { + if (!style || Object.keys(style).length === 0 || Object.keys(style).every((key) => !key)) { + throw new Error("Invalid style arguments: " + JSON.stringify(style)); + } + if (style && style.focus !== undefined) { + if (typeof style.focus !== "boolean") { + throw new Error("Focus must be a boolean value. Currently, only `focus: true` is supported."); + } + else if (style.focus === false) { + console.warn("`focus: false` is not supported!"); + } + } + if (style && style.hidden !== undefined && typeof style.hidden !== "boolean") { + throw new Error("The `hidden` property must hold a boolean value."); + } + for (const prop of ["minHeight", "maxHeight", "minWidth", "maxWidth"]) { + const styleAsAny = style; + const value = styleAsAny[prop]; + if (prop in style) { + if (isUndefinedOrNull(value)) { + delete styleAsAny[prop]; + continue; + } + if (!isNumber(styleAsAny[prop])) { + throw new Error(`"${prop}" must be a number`); + } + } + } + return executor.setStyle(resultWindow, style); + }, success, error); + } + function resetButtons(buttons, success, error) { + return Utils.callbackifyPromise(() => executor.resetButtons(resultWindow, buttons), success, error); + } + function getButtons() { + return executor.getButtons(resultWindow); + } + function setOnTop(onTop, success, error) { + return Utils.callbackifyPromise(() => { + if (typeof onTop === "string") { + if (onTop !== "always") { + throw new Error("`onTop` must hold a `always` value."); + } + } + else if (typeof onTop !== "boolean") { + throw new Error("`onTop` must hold a boolean or `always` value."); + } + return executor.setOnTop(resultWindow, onTop); + }, success, error); + } + function setSizeConstraints(constraints, success, error) { + return Utils.callbackifyPromise(() => { + if (!constraints || Object.keys(constraints).every((value) => value === undefined)) { + throw new Error("The properties of `constraints` cannot be null or undefined."); + } + return executor.setSizeConstraints(resultWindow, constraints); + }, success, error); + } + function getSizeConstraints() { + return executor.getSizeConstraints(resultWindow); + } + function setTitle(newTitle, success, error) { + return Utils.callbackifyPromise(() => { + if (isUndefinedOrNull(newTitle)) { + throw new Error("`newTitle` must not be null or undefined."); + } + if (newTitle === _title) { + return Promise.resolve(resultWindow); + } + return executor.setTitle(resultWindow, newTitle); + }, success, error); + } + function setSticky(isSticky, success, error) { + return Utils.callbackifyPromise(() => { + if (typeof isSticky !== "boolean") { + throw new Error("`isSticky` must hold a boolean value."); + } + return executor.setSticky(resultWindow, isSticky); + }, success, error); + } + function setAllowWorkspaceDrop(allowWorkspaceDrop) { + if (typeof allowWorkspaceDrop !== "boolean") { + throw new Error("`allowWorkspaceDrop` must hold a boolean value."); + } + return executor.setAllowWorkspaceDrop(resultWindow, allowWorkspaceDrop); + } + function pin() { + return executor.pin(resultWindow); + } + function unpin() { + return executor.unpin(resultWindow); + } + function moveResize(bounds, success, error) { + return Utils.callbackifyPromise(() => { + if (isUndefinedOrNull(bounds)) { + throw new Error("The properties of `bounds` cannot be null or undefined."); + } + return executor.moveResize(resultWindow, bounds); + }, success, error); + } + function addFrameButton(buttonInfo, success, error) { + return Utils.callbackifyPromise(() => { + if (typeof buttonInfo === "undefined" || Object.keys(buttonInfo).length === 0) { + throw new Error("Button info is not available."); + } + if (isNullOrWhiteSpace(buttonInfo.buttonId)) { + throw new Error("`buttonId` must not be null or undefined."); + } + if (isNullOrWhiteSpace(buttonInfo.imageBase64)) { + throw new Error("`imageBase64` must not be null or undefined."); + } + return executor.addFrameButton(resultWindow, buttonInfo); + }, success, error); + } + function removeFrameButton(buttonId, success, error) { + return Utils.callbackifyPromise(() => { + if (isNullOrWhiteSpace(buttonId)) { + throw new Error("`buttonId` must not be null or undefined."); + } + return executor.removeFrameButton(resultWindow, buttonId); + }, success, error); + } + function activate(success, error) { + return Utils.callbackifyPromise(() => { + if (_focus) { + return Promise.resolve(resultWindow); + } + return executor.activate(resultWindow); + }, success, error); + } + function focus(success, error) { + return Utils.callbackifyPromise(() => { + if (_focus) { + return Promise.resolve(resultWindow); + } + return executor.focus(resultWindow); + }, success, error); + } + function maximizeRestore(success, error) { + return Utils.callbackifyPromise(() => { + return executor.maximizeRestore(resultWindow); + }, success, error); + } + function maximize(success, error) { + return Utils.callbackifyPromise(() => { + if (_windowState === "maximized") { + return Promise.resolve(resultWindow); + } + return executor.maximize(resultWindow); + }, success, error); + } + function restore(success, error) { + return Utils.callbackifyPromise(() => { + if (_windowState === "normal") { + return Promise.resolve(resultWindow); + } + return executor.restore(resultWindow); + }, success, error); + } + function minimize(success, error) { + return Utils.callbackifyPromise(() => { + if (_windowState === "minimized") { + return Promise.resolve(resultWindow); + } + return executor.minimize(resultWindow); + }, success, error); + } + function collapse(success, error) { + return Utils.callbackifyPromise(() => { + if (_isCollapsed) { + return Promise.resolve(resultWindow); + } + return executor.collapse(resultWindow); + }, success, error); + } + function expand(success, error) { + return Utils.callbackifyPromise(() => { + if (!_isCollapsed) { + return Promise.resolve(resultWindow); + } + return executor.expand(resultWindow); + }, success, error); + } + function toggleCollapse(success, error) { + return Utils.callbackifyPromise(() => { + return executor.toggleCollapse(resultWindow); + }, success, error); + } + function snap(target, direction, success, error) { + return Utils.callbackifyPromise(() => { + if (isUndefinedOrNull(target)) { + throw new Error(`A target window is not specified - ${typeof target === "string" ? target : JSON.stringify(target)}`); + } + if (typeof target === "string") { + const win = windowStore.get(target); + if (!win) { + throw new Error(`Invalid "target" parameter or no such window. Invoked with: ${target}`); + } + target = win.API; + } + if (typeof direction === "string") { + direction = { + direction, + autoAlign: true + }; + } + return executor.snap(resultWindow, target, direction); + }, success, error); + } + function attachTab(tab, opt, success, error) { + return Utils.callbackifyPromise(() => { + var _a; + const errorMessage = `Invalid "tab" parameter - must be an object with an "id" property or a string. Invoked for source window with ID:`; + if (isUndefinedOrNull(tab)) { + const errMsg = `${errorMessage} ${typeof tab === "string" ? tab : JSON.stringify(tab)}`; + throw new Error(errMsg); + } + let sourceWindow; + if (typeof tab === "string") { + sourceWindow = (_a = windowStore.get(tab)) === null || _a === void 0 ? void 0 : _a.API; + if (isUndefinedOrNull(sourceWindow)) { + const errMsg = `${errorMessage} ${typeof sourceWindow === "string" ? sourceWindow : JSON.stringify(sourceWindow)}`; + throw new Error(errMsg); + } + } + else if (!isUndefinedOrNull(tab.id)) { + sourceWindow = tab; + } + else { + throw new Error(errorMessage); + } + const attachOptions = {}; + if (!isUndefinedOrNull(opt)) { + if (typeof opt === "number") { + attachOptions.index = opt; + } + else { + attachOptions.selected = opt.selected; + attachOptions.index = opt.index; + } + } + return executor.attachTab(resultWindow, sourceWindow, attachOptions); + }, success, error); + } + function detachTab(opt = {}, success, error) { + return Utils.callbackifyPromise(() => { + const argsForSend = {}; + function isDetachRelative(o) { + return o.relativeTo !== undefined; + } + if (isDetachRelative(opt)) { + if (typeof opt.relativeTo === "string") { + argsForSend.relativeTo = opt.relativeTo; + } + else if (!isUndefinedOrNull(opt.relativeTo.id)) { + argsForSend.relativeTo = opt.relativeTo.id; + } + if (!isUndefinedOrNull(opt.relativeDirection)) { + argsForSend.relativeDirection = opt.relativeDirection; + } + if (!isUndefinedOrNull(opt.width)) { + argsForSend.width = opt.width; + } + if (!isUndefinedOrNull(opt.height)) { + argsForSend.height = opt.height; + } + } + else { + if (!isUndefinedOrNull(opt.bounds)) { + argsForSend.bounds = opt.bounds; + } + } + if (!isUndefinedOrNull(opt.hideTabHeader)) { + argsForSend.hideTabHeader = opt.hideTabHeader; + } + return executor.detachTab(resultWindow, argsForSend); + }, success, error); + } + function setVisible(toBeVisible, success, error) { + return Utils.callbackifyPromise(() => { + return executor.setVisible(resultWindow, toBeVisible); + }, success, error); + } + async function center(display) { + if (display) { + validateCenterArguments(display); + } + return executor.center(resultWindow, display); + } + function validateCenterArguments(display) { + if (typeof display !== "object") { + throw Error("display argument must be a valid display object"); + } + if (!display.workArea || !display.scaleFactor) { + throw Error("display argument is not a valid display object"); + } + } + function showLoader(loader) { + return executor.showLoader(resultWindow, loader); + } + function hideLoader() { + return executor.hideLoader(resultWindow); + } + function updateContext(context, success, error) { + return Utils.callbackifyPromise(() => { + if (!isObject(context)) { + throw new Error(`"context" must not be null or undefined.`); + } + return executor.updateContext(resultWindow, context, false); + }, success, error); + } + function lock(success, error) { + return Utils.callbackifyPromise(() => { + return executor.lock(resultWindow); + }, success, error); + } + function unlock(success, error) { + return Utils.callbackifyPromise(() => { + return executor.unlock(resultWindow); + }, success, error); + } + function getIcon(success, error) { + return Utils.callbackifyPromise(() => { + return executor.getIcon(resultWindow); + }, success, error); + } + function setIcon(base64Image, success, error) { + return Utils.callbackifyPromise(() => { + if (isNullOrWhiteSpace(base64Image)) { + throw new Error(`"base64Image" must be a non-empty string.`); + } + return executor.setIcon(resultWindow, base64Image); + }, success, error); + } + function setFrameColor(frameColor, success, error) { + return Utils.callbackifyPromise(() => { + if (isNullOrWhiteSpace(frameColor)) { + throw new Error(`"frameColor" must be a non-empty string`); + } + return executor.setFrameColor(resultWindow, frameColor); + }, success, error); + } + function setTabHeaderVisible(toBeTabHeaderVisible, success, error) { + return Utils.callbackifyPromise(() => { + if (typeof toBeTabHeaderVisible !== "boolean") { + throw new Error(`"toBeTabHeaderVisible" must hold a boolean value.`); + } + return executor.setTabHeaderVisible(resultWindow, toBeTabHeaderVisible); + }, success, error); + } + async function setTabTooltip(tooltip) { + if (isNullOrWhiteSpace(tooltip)) { + throw new Error(`"${tooltip}" must not be null or undefined`); + } + return executor.setTabTooltip(resultWindow, tooltip); + } + async function getTabTooltip() { + return executor.getTabTooltip(resultWindow); + } + function showPopup(config) { + return executor.showPopup(resultWindow, config); + } + function createFlydown(config) { + return executor.createFlydown(resultWindow.id, config); + } + function setModalState(isModal) { + return executor.setModalState(resultWindow.id, isModal || false); + } + function zoomIn(success, error) { + return Utils.callbackifyPromise(() => { + return executor.zoomIn(resultWindow); + }, success, error); + } + function zoomOut(success, error) { + return Utils.callbackifyPromise(() => { + return executor.zoomOut(resultWindow); + }, success, error); + } + function setZoomFactor(zoomFactor, success, error) { + return Utils.callbackifyPromise(() => { + if (isNaN(zoomFactor)) { + throw new Error(`zoomFactor is not a number`); + } + return executor.setZoomFactor(resultWindow, zoomFactor); + }, success, error); + } + function showDevTools() { + return executor.showDevTools(resultWindow); + } + function capture(captureOptions) { + return executor.capture(resultWindow, captureOptions); + } + function flash(suppliedOptions, mode) { + const flashOptions = { + shouldFlash: true, + mode: "auto" + }; + if (typeof suppliedOptions === "boolean") { + flashOptions.shouldFlash = suppliedOptions; + } + if (typeof mode !== "undefined") { + flashOptions.mode = mode; + } + return executor.flash(resultWindow, flashOptions); + } + function flashTab(suppliedOptions) { + const flashOptions = { + shouldFlash: true, + }; + if (typeof suppliedOptions === "boolean") { + flashOptions.shouldFlash = suppliedOptions; + } + return executor.flashTab(resultWindow, flashOptions); + } + function print(printOptions) { + return executor.print(resultWindow, printOptions); + } + function printToPDF(printToPDFOptions) { + return executor.printToPDF(resultWindow, printToPDFOptions); + } + function ungroup(ungroupOptions) { + return new Promise((resolve, reject) => { + const unGroupChanged = onGroupChanged((win, newGroup, oldGroup) => { + if (id === win.id) { + unGroupChanged(); + resolve(resultWindow); + } + }); + executor.ungroup(resultWindow, ungroupOptions) + .catch((e) => { + unGroupChanged(); + reject(e); + }); + }); + } + function place(placementSettings) { + return executor.place(resultWindow, placementSettings); + } + function refresh(ignoreCache) { + return executor.refresh(resultWindow, ignoreCache); + } + function download(url, opts) { + return executor.download(resultWindow, url, opts); + } + function configure(settings) { + return executor.configureWindow(resultWindow, settings); + } + function getConfiguration() { + return executor.getWindowConfiguration(resultWindow); + } + function getDockingPlacement() { + return executor.getDockingPlacement(resultWindow); + } + function dock(opts) { + return executor.dock(resultWindow, opts); + } + async function clone(cloneOptions) { + return executor.clone(resultWindow, cloneOptions); + } + async function executeCode(code) { + if (!code) { + throw new Error("Code argument is missing"); + } + if (typeof code !== "string") { + throw new Error("Code argument must be a valid string"); + } + const response = await executor.executeCode(resultWindow, code); + return response.result; + } + function onTitleChanged(callback) { + if (!isFunction(callback)) { + throw new Error("callback should be a function"); + } + callback(resultWindow.title, resultWindow); + return onEventCore("onTitleChanged", callback); + } + function onClose(callback) { + if (!isFunction(callback)) { + throw new Error("callback should be a function"); + } + if (id === undefined) { + callback(resultWindow); + } + return _registry.add("onClose", callback); + } + function onUrlChanged(callback) { + return onEventCore("onUrlChanged", callback); + } + function onFrameButtonAdded(callback) { + return onEventCore("onFrameButtonAdded", callback); + } + function onFrameButtonRemoved(callback) { + return onEventCore("onFrameButtonRemoved", callback); + } + function onFrameButtonClicked(callback) { + return onEventCore("onFrameButtonClicked", callback); + } + function onCollapsed(callback) { + if (!isFunction(callback)) { + throw new Error("callback should be a function"); + } + if (_isCollapsed) { + callback(resultWindow); + } + return _registry.add("collapsed", callback); + } + function onExpanded(callback) { + if (!isFunction(callback)) { + throw new Error("callback should be a function"); + } + if (!_isCollapsed) { + callback(resultWindow); + } + return _registry.add("expanded", callback); + } + function onMaximized(callback) { + if (_windowState === "maximized") { + return onEventCore("maximized", callback, [resultWindow]); + } + else { + return onEventCore("maximized", callback); + } + } + function onMinimized(callback) { + if (_windowState === "minimized") { + return onEventCore("minimized", callback, [resultWindow]); + } + else { + return onEventCore("minimized", callback); + } + } + function onNormal(callback) { + if (_windowState === "normal") { + return onEventCore("normal", callback, [resultWindow]); + } + else { + return onEventCore("normal", callback); + } + } + function onAttached(callback) { + return onEventCore("attached", callback); + } + function onDetached(callback) { + return onEventCore("detached", callback); + } + function onVisibilityChanged(callback) { + return onEventCore("visibility-changed", callback); + } + function onContextUpdated(callback) { + return onEventCore("context-updated", callback); + } + function onLockingChanged(callback) { + return onEventCore("lock-changed", callback); + } + function onBoundsChanged(callback) { + return onEventCore("bounds-changed", callback); + } + function onFocusChanged(callback) { + return onEventCore("focus-changed", callback); + } + function onStickyChanged(callback) { + return onEventCore("sticky-changed", callback); + } + function onFrameColorChanged(callback) { + return onEventCore("frame-color-changed", callback); + } + function onTabHeaderVisibilityChanged(callback) { + return onEventCore("tab-header-visibility-changed", callback); + } + function onWindowAttached(callback) { + return onEventCore("window-attached", callback); + } + function onWindowDetached(callback) { + return onEventCore("window-detached", callback); + } + function onGroupChanged(callback) { + return onEventCore("group-changed", callback); + } + function onTabSelectionChanged(callback) { + return onEventCore("tab-selection-changed", callback); + } + function onChannelRestrictionsChanged(callback) { + if (!isFunction(callback)) { + throw new Error("callback must be a function"); + } + return onEventCore("channel-restrictions-changed", callback); + } + function onClosing(callback) { + if (!isFunction(callback)) { + throw new Error("callback must be a function"); + } + const callbackWrap = (success, error, prevent) => { + const promise = callback(prevent); + if (promise === null || promise === void 0 ? void 0 : promise.then) { + promise.then(success).catch(error); + } + else { + success(); + } + }; + return executor.onClosing(callbackWrap, resultWindow); + } + function onRefreshing(callback) { + if (!isFunction(callback)) { + throw new Error("callback must be a function"); + } + const callbackWrap = (success, error, prevent) => { + const promise = callback(prevent); + if (promise === null || promise === void 0 ? void 0 : promise.then) { + promise.then(success).catch(error); + } + else { + success(); + } + }; + return executor.onRefreshing(callbackWrap, resultWindow); + } + function onNavigating(callback) { + if (!isFunction(callback)) { + throw new Error("callback must be a function"); + } + const callbackWrap = (success, error, prevent, args) => { + const promise = callback(args); + if (promise === null || promise === void 0 ? void 0 : promise.then) { + promise.then(success).catch(error); + } + else { + success(); + } + }; + return executor.onNavigating(callbackWrap, resultWindow); + } + function onZoomFactorChanged(callback) { + return onEventCore("zoom-factor-changed", callback); + } + function onPlacementSettingsChanged(callback) { + return onEventCore("placementSettingsChanged", callback); + } + function onNeighboursChanged(callback) { + return onEventCore("neighbours-changed", callback); + } + function onDockingChanged(callback) { + return onEventCore("docking-changed", callback); + } + function onEventCore(key, callback, replayArguments) { + if (!isFunction(callback)) { + throw new Error("callback must be a function"); + } + return _registry.add(key, callback, replayArguments); + } + function goBack() { + return executor.goBack(resultWindow); + } + function goForward() { + return executor.goForward(resultWindow); + } + function startDrag(option) { + return executor.startDrag(resultWindow, option); + } + function showDialog(dialogOptions) { + if ((dialogOptions === null || dialogOptions === void 0 ? void 0 : dialogOptions.timerDuration) && isNaN(dialogOptions === null || dialogOptions === void 0 ? void 0 : dialogOptions.timerDuration)) { + throw new Error("timerDuration must be a number"); + } + if ((dialogOptions === null || dialogOptions === void 0 ? void 0 : dialogOptions.showTimer) && typeof (dialogOptions === null || dialogOptions === void 0 ? void 0 : dialogOptions.showTimer) !== "boolean") { + throw new Error("showTimer must be a boolean"); + } + return executor.showDialog(resultWindow, dialogOptions); + } + function handleUpdate(updated) { + _url = updated.url; + _title = updated.title; + _context = updated.context || {}; + _bounds = updated.bounds; + _frameColor = updated.frameColor; + _focus = updated.focus; + _neighbours = updated.neighbours || {}; + _groupId = updated.groupId; + _isGroupHeaderVisible = updated.isGroupHeaderVisible; + _isTabHeaderVisible = updated.isTabHeaderVisible; + _isGroupHibernated = updated.isGroupHibernated; + _isGroupVisible = updated.isGroupVisible; + _isTabSelected = updated.isTabSelected; + _settings = updated.settings; + _isVisible = updated.isVisible; + _isSticky = updated.isSticky; + _isCollapsed = updated.isCollapsed; + _windowState = updated.state; + _tabGroupId = updated.tabGroupId; + _frameId = updated.frameId; + _isLocked = updated.isLocked; + _allowWorkspaceDrop = updated.allowWorkspaceDrop; + _isPinned = updated.isPinned; + _zoomFactor = updated.zoomFactor; + _placementSettings = updated.placementSettings; + } + function handleTitleChanged(newTitle) { + _title = newTitle; + executor.finished + .finally(() => { + _registry.execute("onTitleChanged", newTitle, resultWindow); + }); + } + function handleUrlChanged(newUrl) { + _url = newUrl; + _registry.execute("onUrlChanged", newUrl, resultWindow); + } + function handleVisibilityChanged(isVisible) { + if (isVisible === _isVisible) { + return; + } + _isVisible = isVisible; + _registry.execute("visibility-changed", resultWindow); + } + function handleWindowSettingsChanged(settings) { + _settings = settings; + _registry.execute("settings-changed", resultWindow); + } + function handleContextUpdated(context) { + _context = context; + _registry.execute("context-updated", _context, resultWindow); + } + function handleWindowClose() { + if (id === undefined) { + return; + } + _registry.execute("onClose", resultWindow); + id = undefined; + } + function handleFrameButtonAdded(frameButton) { + const buttonObj = ["buttonId", "imageBase64", "order", "tooltip"].reduce((memo, k) => { + memo[k] = frameButton[k]; + return memo; + }, {}); + const frameButtonsIds = _frameButtons.map((btn) => { + return btn.buttonId; + }); + if (frameButtonsIds.indexOf(frameButton.buttonId) === -1) { + _frameButtons.push(buttonObj); + } + _registry.execute("onFrameButtonAdded", buttonObj, resultWindow); + } + function handleFrameButtonRemoved(frameButtonId) { + let button; + _frameButtons = _frameButtons.reduce((memo, btn) => { + if (btn.buttonId === frameButtonId) { + button = btn; + } + else { + memo.push(btn); + } + return memo; + }, []); + if (button !== undefined) { + _registry.execute("onFrameButtonRemoved", button, resultWindow); + } + } + function handleFrameButtonClicked(frameButton) { + const button = _frameButtons.filter((btn) => { + return btn.buttonId === frameButton.buttonId; + }); + if (button.length > 0) { + _registry.execute("onFrameButtonClicked", button[0], resultWindow); + } + } + async function handleWindowChangeState(state) { + if (state === "collapsed") { + _isCollapsed = true; + } + else if (state === "expanded") { + _isCollapsed = false; + } + else { + _windowState = state; + } + await executor.finished; + _registry.execute(state, resultWindow); + } + function handleFrameIsLockedChanged(isLocked) { + _isLocked = isLocked; + _registry.execute("lock-changed", resultWindow); + } + function handleBoundsChanged(bounds) { + if (_bounds.top === bounds.top && _bounds.left === bounds.left && _bounds.width === bounds.width && _bounds.height === bounds.height) { + return; + } + _bounds = bounds; + _registry.execute("bounds-changed", resultWindow); + } + function handleFocusChanged(isFocused) { + _focus = isFocused; + _registry.execute("focus-changed", resultWindow); + } + function handleIsStickyChanged(isSticky) { + _isSticky = isSticky; + _registry.execute("sticky-changed", isSticky, resultWindow); + } + function handleFrameColorChanged(frameColor) { + _frameColor = frameColor; + _registry.execute("frame-color-changed", resultWindow); + } + function handleFrameAttached(tabGroupId, frameId, isTabHeaderVisible) { + _tabGroupId = tabGroupId; + _frameId = frameId; + _isTabHeaderVisible = isTabHeaderVisible; + _registry.execute("frame-attached", resultWindow); + } + function handleCompositionChanged(state) { + _neighbours = state.neighbors || {}; + _tabIndex = state.index; + _registry.execute("neighbours-changed", _neighbours, resultWindow); + } + function handleAllowWorkspaceDropChanged(allowWorkspaceDrop) { + _allowWorkspaceDrop = allowWorkspaceDrop; + _registry.execute("allow-workspace-drop-changed", resultWindow); + } + function handleIsPinnedChanged(isPinned) { + _isPinned = isPinned; + _registry.execute("is-pinned-changed", resultWindow); + } + function handleGroupHeaderVisibilityChanged(isGroupHeaderVisible) { + _isGroupHeaderVisible = isGroupHeaderVisible; + } + function handleTabHeaderVisibilityChanged(isTabHeaderVisible) { + if (_isTabHeaderVisible !== isTabHeaderVisible) { + _isTabHeaderVisible = isTabHeaderVisible; + _registry.execute("tab-header-visibility-changed", resultWindow); + } + } + async function handleFrameSelectionChanged(newWindow, prevWindow) { + let selectedWindow; + if (newWindow === id) { + _isTabSelected = true; + selectedWindow = resultWindow; + } + else { + _isTabSelected = false; + selectedWindow = windowStore.get(newWindow) ? windowStore.get(newWindow).API : undefined; + } + const previousWindow = windowStore.get(prevWindow) ? windowStore.get(prevWindow).API : undefined; + await executor.finished; + _registry.execute("tab-selection-changed", selectedWindow, previousWindow, resultWindow); + } + async function handleAttached(newTabGroupId, newFrameId, tabHeaderVisible, isLocked, winsToBeNotified) { + _tabGroupId = newTabGroupId; + _isTabHeaderVisible = tabHeaderVisible; + _frameId = newFrameId; + if (typeof isLocked !== "undefined") { + _isLocked = isLocked; + } + await executor.finished; + winsToBeNotified.forEach((w) => { + w.Events.handleWindowAttached(resultWindow); + }); + _registry.execute("attached", resultWindow); + } + function handleWindowAttached(win) { + _registry.execute("window-attached", win); + } + async function handleDetached(isLocked, winsToBeNotified) { + _tabGroupId = undefined; + _isTabSelected = false; + if (typeof isLocked !== "undefined") { + _isLocked = isLocked; + } + await executor.finished; + winsToBeNotified.forEach((w) => { + w.Events.handleWindowDetached(resultWindow); + }); + _registry.execute("detached", resultWindow); + } + function handleWindowDetached(win) { + _registry.execute("window-detached", win); + } + function handleZoomFactorChanged(zoomFactor) { + _zoomFactor = zoomFactor; + _registry.execute("zoom-factor-changed", resultWindow); + } + function handlePlacementSettingsChanged(placementSettings) { + let promise; + const copy = placementSettings; + if (!copy.display) { + promise = Promise.resolve(undefined); + } + else { + const displayAPI = displayAPIGetter(); + if (!displayAPI) { + promise = Promise.resolve(undefined); + } + else { + const index = copy.display - 1; + promise = new Promise((resolve, reject) => { + displayAPI.all().then((displays) => { + const display = displays.find((d) => d.index === index); + resolve(display); + }).catch(reject); + }); + } + } + void promise.then((d) => { + copy.display = d; + _placementSettings = copy; + _registry.execute("placementSettingsChanged", resultWindow); + }); + } + function handleDockingChanged(data) { + _registry.execute("docking-changed", resultWindow, { + docked: data.docked, + position: data.position, + claimScreenArea: data.claimScreenArea + }); + } + function handleChannelRestrictionsChanged(data) { + _registry.execute("channel-restrictions-changed", data); + } + function handleGroupChanged(newGroup, oldGroup) { + _group = newGroup; + _groupId = newGroup === null || newGroup === void 0 ? void 0 : newGroup.id; + if (!isUndefinedOrNull(newGroup) && !isUndefinedOrNull(oldGroup)) { + _registry.execute("group-changed", resultWindow, newGroup, oldGroup); + } + } + function getAllTabs() { + const allWindows = windowStore.list; + if (_mode.toLowerCase() !== "tab") { + return []; + } + const tabs = Object.keys(allWindows).reduce((memo, win) => { + const window = allWindows[win]; + if (window + && window.API.tabGroupId + && typeof window.API.tabGroupId !== "undefined" + && typeof resultWindow.tabGroupId !== "undefined" + && window.API.tabGroupId === resultWindow.tabGroupId) { + memo.push(window.API); + } + return memo; + }, []); + return tabs.sort((w1, w2) => { + if (w1.tabIndex !== w2.tabIndex) { + if (w1.tabIndex === -1) { + return Number.MAX_SAFE_INTEGER; + } + if (w2.tabIndex === -1) { + return Number.MIN_SAFE_INTEGER; + } + } + return w1.tabIndex - w2.tabIndex; + }); + } + function mapWindowIdsToWindowObjects(windowIdArr) { + return windowIdArr.reduce((memo, winId) => { + const window = windowStore.get(winId); + if (window) { + memo.push(window.API); + } + return memo; + }, []); + } + function getNeighboursByDirection(direction) { + const windowIds = _neighbours[direction]; + if (typeof windowIds !== "undefined") { + return mapWindowIdsToWindowObjects(windowIds); + } + } + function getApplicationName() { + var _a; + if (_applicationName) { + return _applicationName; + } + if (_context._APPLICATION_NAME) { + return _context._APPLICATION_NAME; + } + if (_context && _context._t42 && _context._t42.application) { + return _context._t42.application; + } + const info = getWindowInfo(); + if (info && info.applicationName) { + return info.applicationName; + } + const appManager = appManagerGetter(); + if (appManager) { + const instance = appManager.instances().find((i) => id === i.id); + if (instance) { + return (_a = instance.application) === null || _a === void 0 ? void 0 : _a.name; + } + } + return undefined; + } + function getWindowInfo() { + if (typeof window !== "undefined" && window.glue42gd && window.glue42gd.getWindowInfo) { + const info = window.glue42gd.getWindowInfo(id); + if (!info) { + return undefined; + } + else { + return info; + } + } + } + const resultWindow = { + get id() { + return _id; + }, + get name() { + return _name; + }, + get application() { + const appManager = appManagerGetter(); + const appName = getApplicationName(); + if (appName && appManager) { + return appManager.application(appName); + } + }, + get hostInstance() { + return executor.hostInstance; + }, + get interopInstance() { + const instance = agm.servers().find((s) => s.windowId === this.id); + if (instance) { + return instance; + } + else { + const appName = getApplicationName(); + if (appName) { + return { application: appName }; + } + } + }, + get agmInstance() { + return resultWindow.interopInstance; + }, + get url() { + return _url; + }, + get title() { + return _title; + }, + get windowStyleAttributes() { + return _settings; + }, + get settings() { + return _settings; + }, + get tabGroupId() { + return _mode.toLowerCase() === "tab" ? _tabGroupId : undefined; + }, + get tabIndex() { + return _mode.toLowerCase() === "tab" ? _tabIndex : undefined; + }, + get frameId() { + return _frameId; + }, + get frameButtons() { + return _frameButtons.sort((b1, b2) => b1.order - b2.order); + }, + get mode() { + return _mode; + }, + get state() { + return _windowState; + }, + get isCollapsed() { + return _isCollapsed; + }, + get isVisible() { + return _isVisible; + }, + get isLocked() { + return _isLocked; + }, + get context() { + return _context; + }, + get bounds() { + return _bounds; + }, + get minHeight() { + return _settings.minHeight; + }, + get maxHeight() { + return _settings.maxHeight; + }, + get minWidth() { + return _settings.minWidth; + }, + get maxWidth() { + return _settings.maxWidth; + }, + get isFocused() { + return _focus; + }, + get frameColor() { + return _frameColor; + }, + get opened() { + return resultWindow.id !== undefined; + }, + get group() { + return _group; + }, + get groupId() { + return _groupId; + }, + get isSticky() { + return _isSticky; + }, + get topNeighbours() { + return getNeighboursByDirection("top"); + }, + get leftNeighbours() { + return getNeighboursByDirection("left"); + }, + get rightNeighbours() { + return getNeighboursByDirection("right"); + }, + get bottomNeighbours() { + return getNeighboursByDirection("bottom"); + }, + get isGroupHeaderVisible() { + return _isGroupHeaderVisible; + }, + get activityId() { + if (_context._t42) { + return _context._t42.activityId; + } + const info = getWindowInfo(); + if (!info) { + return undefined; + } + return info.activityId; + }, + get activityWindowId() { + if (_context._t42) { + return _context._t42.activityWindowId; + } + const info = getWindowInfo(); + if (!info) { + return undefined; + } + return info.activityWindowId; + }, + get windowType() { + return options.windowType || "electron"; + }, + get zoomFactor() { + return _zoomFactor; + }, + get screen() { + if (typeof window !== "undefined" && window.glue42gd) { + return Utils.getMonitor(resultWindow.bounds, window.glue42gd.monitors); + } + return undefined; + }, + get placementSettings() { + return Object.assign({}, _placementSettings); + }, + get jumpList() { + return _jumpList; + }, + get allowWorkspaceDrop() { + return _allowWorkspaceDrop; + }, + get isPinned() { + return _isPinned; + }, + maximize, + restore, + minimize, + maximizeRestore, + collapse, + expand, + toggleCollapse, + focus, + activate, + moveResize, + setTitle, + setStyle, + setOnTop, + resetButtons, + getButtons, + setSizeConstraints, + getSizeConstraints, + navigate, + addFrameButton, + removeFrameButton, + setVisible, + show: () => setVisible(true), + hide: () => setVisible(false), + center, + close, + snap, + showLoader, + hideLoader, + updateContext, + lock, + unlock, + getIcon, + setIcon, + setFrameColor, + setTabTooltip, + getTabTooltip, + attachTab, + detachTab, + setTabHeaderVisible, + showPopup, + createFlydown, + setModalState, + setZoomFactor, + zoomIn, + zoomOut, + showDevTools, + capture, + flash, + flashTab, + setSticky, + setAllowWorkspaceDrop, + pin, + unpin, + print, + printToPDF, + place, + ungroup, + refresh, + goBack, + goForward, + download, + configure, + getConfiguration, + getDockingPlacement, + dock, + clone, + executeCode, + getChannel: async () => { + var _a; + const wins = await getChannels().getWindowsWithChannels({ windowIds: [_id] }); + return (_a = wins[0]) === null || _a === void 0 ? void 0 : _a.channel; + }, + startDrag, + showDialog, + onClose, + onUrlChanged, + onTitleChanged, + onFrameButtonAdded, + onFrameButtonRemoved, + onFrameButtonClicked, + onCollapsed, + onExpanded, + onMinimized, + onMaximized, + onNormal, + onAttached, + onDetached, + onVisibilityChanged, + onContextUpdated, + onLockingChanged, + onBoundsChanged, + onFrameColorChanged, + onFocusChanged, + onStickyChanged, + onGroupChanged, + onWindowAttached, + onWindowDetached, + onTabSelectionChanged, + onTabHeaderVisibilityChanged, + onClosing, + onRefreshing, + onZoomFactorChanged, + onPlacementSettingsChanged, + onNeighboursChanged, + onDockingChanged, + onNavigating, + onChannelRestrictionsChanged, + get tabs() { + return getAllTabs(); + }, + get isTabHeaderVisible() { + return _isTabHeaderVisible; + }, + get isTabSelected() { + return _isTabSelected; + }, + getURL() { + return Promise.resolve(_url); + }, + getTitle() { + return Promise.resolve(_title); + }, + getBounds() { + return Promise.resolve(_bounds); + }, + getContext() { + return Promise.resolve(_context); + }, + setContext(context) { + if (!isObject(context)) { + throw new Error(`"context" must not be null or undefined, set to empty object if you want to clear it out.`); + } + return executor.updateContext(resultWindow, context, true); + }, + getDisplay() { + const displayAPI = displayAPIGetter(); + return displayAPI.getByWindowId(id); + }, + resizeTo(width, height) { + return moveResize({ width, height }); + }, + moveTo(top, left) { + return moveResize({ top, left }); + }, + async getParentWindow() { + var _a; + const myParentId = _settings.parentInstanceId; + if (!myParentId) { + return undefined; + } + return (_a = windowStore.list[myParentId]) === null || _a === void 0 ? void 0 : _a.API; + }, + async getChildWindows() { + return Object.keys(windowStore.list) + .map((key) => windowStore.list[key].API) + .filter((w) => { + const parentId = w.settings.parentInstanceId; + return parentId === id; + }); + }, + joinChannel: (name) => { + return getChannels().join(name, id); + }, + leaveChannel: () => { + return getChannels().leave(id); + } + }; + const events = { + handleUpdate, + handleWindowClose, + handleWindowChangeState, + handleTitleChanged, + handleVisibilityChanged, + handleUrlChanged, + handleWindowSettingsChanged, + handleContextUpdated, + handleFrameIsLockedChanged, + handleBoundsChanged, + handleFocusChanged, + handleFrameButtonAdded, + handleFrameButtonRemoved, + handleFrameButtonClicked, + handleFrameColorChanged, + handleFrameAttached, + handleFrameSelectionChanged, + handleCompositionChanged, + handleAllowWorkspaceDropChanged, + handleIsPinnedChanged, + handleGroupHeaderVisibilityChanged, + handleTabHeaderVisibilityChanged, + handleGroupChanged, + handleAttached, + handleDetached, + handleWindowAttached, + handleWindowDetached, + handleZoomFactorChanged, + handleIsStickyChanged, + handlePlacementSettingsChanged, + handleDockingChanged, + handleChannelRestrictionsChanged + }; + const groupArgs = { + get isGroupHibernated() { + return _isGroupHibernated; + }, + get isGroupVisible() { + return _isGroupVisible; + }, + }; + return { + API: resultWindow, + Events: events, + GroupCreationArgs: groupArgs + }; + }; + + function getWindowsByTabGroupId(windowId, tabGroupId) { + const windows = windowStore.list; + return Object.keys(windows).reduce((memo, id) => { + const win = windows[id]; + if (win.API.tabGroupId === tabGroupId && win.API.id !== windowId) { + memo.push(win); + } + return memo; + }, []); + } + function isEmpty(object) { + if (!object || Object.keys(object).every((value) => object[value] === undefined)) { + return true; + } + return false; + } + + class GDExecutor { + constructor() { + this.GroupMethodName = "T42.Group.Execute"; + this.WndMethodName = "T42.Wnd.Execute"; + this._registry = CallbackRegistryFactory(); + this._finished = Promise.resolve(); + this._configuration = { + windowAvailableOnURLChanged: true + }; + this.unsubCallbacks = {}; + } + get hostInstance() { + return this.agmTarget; + } + get finished() { + return this._finished; + } + get configuration() { + return this._configuration; + } + init(agm, instance) { + this.agm = agm; + this.agmTarget = instance; + this._registry.add("event", (data) => { + if (data.type === "Closed") { + const keys = Object.keys(this.unsubCallbacks); + keys.forEach((key) => { + const isSameWindow = key.startsWith(data.windowId); + if (isSameWindow) { + delete this.unsubCallbacks[key]; + } + }); + } + }); + } + setConfiguration(config) { + this._configuration = { ...this._configuration, ...config }; + } + handleEvent(data) { + this._registry.execute("event", data); + } + async open(options) { + let finishedResolve; + this._finished = new Promise((resolve) => { + finishedResolve = resolve; + }); + try { + const result = await this.agm.invoke("T42.Wnd.Create", options, this.agmTarget, { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_RESPONSE_TIMEOUT_MS + }); + if (result.returned === undefined) { + throw new Error("failed to execute T42.Wnd.Create - unknown reason"); + } + const id = result.returned.id; + const win = await windowStore.waitFor(id); + if (!this.configuration || this.configuration.windowAvailableOnURLChanged) { + setTimeout(() => { + if (win.API.windowType === "electron") { + win.Events.handleUrlChanged(win.API.url); + } + }, 0); + } + return win.API; + } + finally { + finishedResolve(); + } + } + async close(w, options) { + const result = await this.execute("close", { windowId: w.id, options }, `Closed`); + if (options) { + return result.closed; + } + return w; + } + async navigate(w, newUrl, urlLoadOptions) { + let methodResponseTimeoutMs = 120000; + if (typeof urlLoadOptions === "object" && typeof urlLoadOptions.timeout === "number") { + methodResponseTimeoutMs = urlLoadOptions.timeout * 1000; + delete urlLoadOptions.timeout; + } + await this.execute("navigate", { windowId: w.id, options: { url: newUrl, urlLoadOptions }, invocationOptions: { methodResponseTimeoutMs } }, "UrlChanged"); + return w; + } + async setStyle(w, style) { + var _a; + const stylePromises = []; + const wait = (promise) => stylePromises.push(promise); + if (!isUndefinedOrNull(style.focus) && !w.isFocused) { + wait(w.focus()); + } + if (!isUndefinedOrNull(style.hidden)) { + const toBeVisible = !style.hidden; + wait(w.setVisible(toBeVisible)); + } + if (!isUndefinedOrNull(style.onTop)) { + wait(w.setOnTop(style.onTop)); + } + if (!isNullOrWhiteSpace(style.tabTooltip) || !isNullOrWhiteSpace(style.tabToolTip)) { + const toolTip = (_a = style.tabTooltip) !== null && _a !== void 0 ? _a : style.tabToolTip; + wait(w.setTabTooltip(toolTip)); + } + if (!isNullOrWhiteSpace(style.tabTitle)) { + wait(this.execute("setTabTitle", { windowId: w.id, options: { tabTitle: style.tabTitle } })); + } + const constraints = { + minHeight: style.minHeight, + minWidth: style.minWidth, + maxHeight: style.maxHeight, + maxWidth: style.maxWidth, + }; + const hasConstraints = !isEmpty(constraints); + if (hasConstraints) { + wait(w.setSizeConstraints(constraints)); + } + const buttons = { + allowClose: style.allowClose, + allowCollapse: style.allowCollapse, + allowLockUnlock: style.allowLockUnlock, + allowMaximize: style.allowMaximize, + allowMinimize: style.allowMinimize + }; + const hasButtons = !isEmpty(buttons); + if (hasButtons) { + wait(w.resetButtons(buttons)); + } + await Promise.all(stylePromises); + return w; + } + async setSizeConstraints(w, constraints) { + await this.execute("setSizeConstraints", { windowId: w.id, options: constraints }); + return w; + } + async getSizeConstraints(w) { + const sizeConstraint = await this.execute("getSizeConstraints", { windowId: w.id }); + return sizeConstraint; + } + async setTabTooltip(w, tabTooltip) { + await this.execute("setTabTooltip", { windowId: w.id, options: { tabTooltip } }); + return w; + } + async getTabTooltip(w) { + const result = await this.execute("getTabTooltip", { windowId: w.id }); + return result.tabTooltip; + } + async resetButtons(w, buttonsConfig) { + await this.execute("resetButtons", { windowId: w.id, options: buttonsConfig }); + return w; + } + async getButtons(w) { + const buttons = await this.execute("getButtons", { windowId: w.id }); + return buttons; + } + async setOnTop(w, onTop) { + await this.execute("setOnTop", { windowId: w.id, options: { onTop } }); + return w; + } + async setTitle(w, newTitle) { + const options = { + windowId: w.id, + options: { + title: newTitle + } + }; + await this.execute("setTitle", options, "TitleChanged"); + return w; + } + async setSticky(w, isSticky) { + const options = { + windowId: w.id, + options: { + isSticky + } + }; + await this.execute("setSticky", options); + return w; + } + async setAllowWorkspaceDrop(w, allowWorkspaceDrop) { + const options = { + windowId: w.id, + options: { + allowWorkspaceDrop + } + }; + await this.execute("setAllowWorkspaceDrop", options); + return w; + } + async pin(windowToPin) { + const options = { + windowId: windowToPin.id + }; + await this.execute("pinTab", options); + return windowToPin; + } + async unpin(pinnedWindow) { + const options = { + windowId: pinnedWindow.id + }; + await this.execute("unpinTab", options); + return pinnedWindow; + } + async moveResize(w, bounds) { + if (typeof window !== "undefined" && window.glueDesktop.versionNum < 31200) { + return new Promise(async (res, rej) => { + const resolveImmediately = this.areBoundsEqual(bounds, w); + let isDone = false; + const done = () => { + if (isDone) { + return; + } + isDone = true; + if (unsubscribeBoundsChanged) { + unsubscribeBoundsChanged(); + unsubscribeBoundsChanged = undefined; + } + res(w); + if (resolveTimeout) { + clearTimeout(resolveTimeout); + resolveTimeout = undefined; + } + }; + let resolveTimeout; + let unsubscribeBoundsChanged; + if (!resolveImmediately) { + unsubscribeBoundsChanged = w.onBoundsChanged((win) => { + if (!this.areBoundsEqual(bounds, win)) { + return; + } + done(); + }); + } + try { + await this.execute("moveResize", { windowId: w.id, options: { bounds } }); + } + catch (error) { + rej(error); + return; + } + if (resolveImmediately) { + done(); + return; + } + resolveTimeout = setTimeout(() => { + done(); + }, 1000); + }); + } + else { + await this.execute("moveResize", { windowId: w.id, options: { bounds } }); + } + return w; + } + async addFrameButton(w, buttonInfo) { + await this.execute("addButton", { windowId: w.id, options: buttonInfo }, "ButtonAdded"); + return w; + } + async removeFrameButton(w, buttonId) { + await this.execute("removeButton", { windowId: w.id, options: buttonId }, "ButtonRemoved"); + return w; + } + async activate(w) { + await this.execute("activate", { windowId: w.id }); + return w; + } + async focus(w) { + await this.execute("focus", { windowId: w.id }); + return w; + } + async maximizeRestore(w) { + await this.execute("maximizeRestore", { windowId: w.id }, "StateChanged"); + return w; + } + async maximize(w) { + await this.execute("maximize", { windowId: w.id }, "StateChanged"); + return w; + } + async restore(w) { + await this.execute("restore", { windowId: w.id }, "StateChanged"); + return w; + } + async minimize(w) { + await this.execute("minimize", { windowId: w.id }, "StateChanged"); + return w; + } + async collapse(w) { + await this.execute("collapse", { windowId: w.id }, "StateChanged"); + return w; + } + async expand(w) { + await this.execute("expand", { windowId: w.id }, "StateChanged"); + return w; + } + async toggleCollapse(w) { + await this.execute("toggleCollapse", { windowId: w.id }, "StateChanged"); + return w; + } + async snap(w, targetWindow, options) { + const args = { + targetWindowId: targetWindow.id + }; + args.snappingEdge = options.direction; + args.autoAlign = options.autoAlign; + await this.execute("snap", { windowId: w.id, options: args }, "CompositionChanged", `CompositionChanged-${targetWindow.id}`); + return w; + } + async attachTab(w, sourceWindow, options) { + await this.execute("attachTab", { + windowId: w.id, + options: { + index: options, + sourceWindowId: sourceWindow.id, + targetWindowId: w.id, + } + }, `WindowFrameAdded-${sourceWindow.id}`, `WindowFrameRemoved-${sourceWindow.id}`); + return w; + } + async detachTab(w, options) { + const eventKeys = ["WindowFrameRemoved", `WindowFrameAdded`]; + if (!isUndefinedOrNull(options === null || options === void 0 ? void 0 : options.relativeTo)) { + eventKeys.push(`CompositionChanged`); + eventKeys.push(`CompositionChanged-${options.relativeTo}`); + } + else { + eventKeys.push("BoundsChanged"); + } + await this.execute("detachTab", { windowId: w.id, options }, ...eventKeys); + return w; + } + async setVisible(w, toBeVisible = true) { + let command; + if (toBeVisible) { + command = "show"; + } + else { + command = "hide"; + } + await this.execute(command, { windowId: w.id }, "VisibilityChanged"); + return w; + } + async center(w, display) { + await this.execute("center", { windowId: w.id, options: display }); + return w; + } + async showLoader(w, loader) { + await this.execute("showLoadingAnimation", { windowId: w.id, options: loader }); + return w; + } + async hideLoader(w) { + await this.execute("hideLoadingAnimation", { windowId: w.id }); + return w; + } + async updateContext(w, context, replace) { + let un; + try { + const contextWithoutUndefinedValues = this.swapUndefinedToNull(context); + const done = new Promise((resolve, reject) => { + un = w.onContextUpdated(() => { + resolve(); + }); + }); + await Promise.all([this.execute("updateContext", { + windowId: w.id, context: contextWithoutUndefinedValues, replace + }), done]); + return w; + } + finally { + if (un) { + un(); + } + } + } + async lock(w) { + await this.execute("lockUnlock", { windowId: w.id, options: { lock: true } }, "FrameIsLockedChanged"); + return w; + } + async unlock(w) { + await this.execute("lockUnlock", { windowId: w.id, options: { lock: false } }, "FrameIsLockedChanged"); + return w; + } + async getIcon(w) { + const result = await this.execute("getIcon", { + windowId: w.id, + options: {} + }); + return result.icon; + } + async setIcon(w, base64Image) { + await this.execute("setIcon", { + windowId: w.id, + options: { + dataURL: base64Image + } + }); + return w; + } + async setFrameColor(w, frameColor) { + await this.execute("setFrameColor", { windowId: w.id, options: { frameColor } }, "FrameColorChanged"); + return w; + } + async setTabHeaderVisible(w, toBeTabHeaderVisible) { + await this.execute("setTabHeaderVisible", { + windowId: w.id, + options: { + toShow: toBeTabHeaderVisible + } + }, "TabHeaderVisibilityChanged"); + return w; + } + async showGroupPopup(id, options) { + const reformatedOptions = this.showPopupCore(id, options); + await this.executeGroup("showGroupPopup", { + groupId: id, + options: reformatedOptions + }); + } + async showPopup(targetWindow, options) { + const reformatedOptions = this.showPopupCore(targetWindow.id, options); + await this.execute("showPopupWindow", { + windowId: targetWindow.id, + options: reformatedOptions + }); + return targetWindow; + } + async createFlydown(windowId, options) { + if (!options) { + throw new Error("The options object is not valid!"); + } + const optionsCopy = { ...options }; + if (!optionsCopy.horizontalOffset) { + optionsCopy.horizontalOffset = 0; + } + if (!optionsCopy.verticalOffset) { + optionsCopy.verticalOffset = 0; + } + const fullOptions = this.reformatFlydownOptions(windowId, optionsCopy); + return this.execute("setFlydownArea", { windowId, options: fullOptions }).then(() => { + const zoneIds = fullOptions.zones.map((z) => z.id); + fullOptions.zones.forEach((z) => { + let callback = typeof (z.flydownSize) === "function" ? + z.flydownSize : () => z.flydownSize; + if (options.size instanceof Function && z.flydownSize) { + callback = async (data, cancel) => { + let result; + if (options.size instanceof Function) { + result = await options.size(data, cancel); + } + if (z.flydownSize instanceof Function && z.flydownSize !== options.size) { + return await z.flydownSize(data, cancel) || result; + } + return result || z.flydownSize; + }; + } + this._registry.clearKey(`${fullOptions.targetId}_${z.id}`); + this._registry.add(`${fullOptions.targetId}_${z.id}`, callback); + }); + return { + destroy: () => this.clearFlydownArea(fullOptions.targetId, zoneIds), + options: optionsCopy + }; + }); + } + async setModalState(windowId, isModal) { + return this.execute("setModalState", { windowId, options: { isModal } }); + } + async autoArrange(displayId) { + return this.execute("autoArrange", { options: { displayId } }); + } + async handleFlydownBoundsRequested(targetId, data) { + const cancelCallback = () => data.cancel = true; + const callbackData = { + zoneId: data.flydownId, + flydownWindowBounds: data.flydownWindowBounds, + flydownWindowId: data.flydownWindowId, + }; + const responses = await Promise.all(this._registry.execute(`${targetId}_${data.flydownId}`, callbackData, cancelCallback)); + if (responses.length === 1) { + const defaultResponse = { height: 0, width: 0, top: 0, left: 0 }; + const response = typeof (responses[0]) === "object" && !Array.isArray(responses[0]) ? responses[0] : defaultResponse; + const responseOptions = { ...data, flydownWindowBounds: response }; + return responseOptions; + } + } + async handleOnEventRequested(callbackId, args) { + var _a; + const callbacks = (_a = this.unsubCallbacks[callbackId]) !== null && _a !== void 0 ? _a : []; + let prevented = false; + const preventArgs = []; + await Promise.all(callbacks.map((cb) => { + return new Promise((resolve, reject) => { + cb(() => { + resolve(); + }, () => { + reject(); + }, (pArgs) => { + prevented = true; + preventArgs.push(pArgs); + }, args); + }); + })); + return { prevented, preventArgs }; + } + async zoomIn(window) { + await this.execute("zoomIn", { + windowId: window.id, + }); + return window; + } + async zoomOut(window) { + await this.execute("zoomOut", { + windowId: window.id, + }); + return window; + } + async setZoomFactor(window, zoomFactor) { + await this.execute("setZoomFactor", { + windowId: window.id, + options: { + zoomFactor + } + }); + return window; + } + async showDevTools(window) { + await this.execute("showDevTools", { + windowId: window.id, + }); + return window; + } + async capture(window, options) { + const base64screenshot = (await this.execute("captureScreenshot", { windowId: window.id, options: { ...options } })).data; + return base64screenshot; + } + async captureGroup(windowIds, options) { + const base64screenshot = (await this.execute("captureGroupScreenshot", { windowId: windowIds[0], options: { groupWindowIds: windowIds, ...options } })).data; + return base64screenshot; + } + async flash(resultWindow, options) { + await this.execute("flash", { windowId: resultWindow.id, options: { ...options } }); + return resultWindow; + } + async flashTab(resultWindow, options) { + await this.execute("flashTab", { windowId: resultWindow.id, options: { ...options } }); + return resultWindow; + } + async configure(windowId, options) { + return this.execute("configure", { windowId, options: { ...options } }); + } + async print(resultWindow, options) { + await this.execute("print", { windowId: resultWindow.id, options: { ...options } }); + return resultWindow; + } + async printToPDF(resultWindow, options) { + const filePath = (await this.execute("printToPDF", { windowId: resultWindow.id, options: { ...options } })).filePath; + return filePath; + } + async place(window, options) { + const copy = { ...options }; + if (!options.display || options.display === "current") { + copy.display = await window.getDisplay(); + } + if (copy.display && typeof copy.display !== "string" && typeof copy.display !== "number") { + copy.display = copy.display.index + 1; + } + return this.execute("place", { windowId: window.id, options: { ...copy } }); + } + async refresh(resultWindow, ignoreCache) { + await this.execute("refresh", { windowId: resultWindow.id, options: { ignoreCache } }); + return resultWindow; + } + async download(resultWindow, url, options = {}) { + options.enableDownloadBar = !options.silent; + const result = await this.execute("downloadURL", { windowId: resultWindow.id, options: { url, options } }); + return { + url, + path: result.fullPath, + size: result.fileSize, + }; + } + async configureWindow(resultWindow, options) { + await this.execute("configureWindow", { windowId: resultWindow.id, options }); + return resultWindow; + } + async getWindowConfiguration(resultWindow) { + const config = await this.execute("getWindowConfiguration", { windowId: resultWindow.id }); + return config; + } + async startDrag(resultWindow, options) { + await this.execute("startDrag", { windowId: resultWindow.id, options }); + return resultWindow; + } + showDialog(resultWindow, options) { + return new Promise((res, rej) => { + const token = Utils.generateId(); + const un = this._registry.add("event", (args) => { + if (args.type === "DialogResult" && args.windowId === resultWindow.id && args.data.token === token) { + un(); + const data = args.data; + if ("status" in data) { + if (data.status === "failed") { + rej(new Error(data.message)); + } + else if (data.status === "successful") { + res(data.result); + } + } + } + }); + this.execute("showDialog", { windowId: resultWindow.id, options: Object.assign({}, { ...options }, { token }) }); + }); + } + async execute(command, options, ...eventKeys) { + return this.executeCore(this.WndMethodName, command, options, ...eventKeys); + } + async executeGroup(command, options, ...eventKeys) { + return this.executeCore(this.GroupMethodName, command, options, ...eventKeys); + } + async ungroup(w, options) { + const args = { + windowId: w.id, + options + }; + await this.execute("ungroup", args); + return w; + } + async updateJumpList(windowId, options) { + const args = { + windowId, + options + }; + await this.execute("updateJumplist", args); + } + async getJumpList(windowId) { + const args = { + windowId, + }; + const result = await this.execute("getJumplist", args); + return result; + } + onClosing(callback, gdWindow) { + const glue42gd = typeof window !== "undefined" && window.glue42gd; + if (glue42gd && gdWindow.windowType === "electron") { + return glue42gd.addCloseHandler(callback, gdWindow.id); + } + else { + return this.nonWindowHandlers(callback, gdWindow.id, "OnClosing"); + } + } + onGroupClosing(callback, group) { + return this.nonWindowHandlersCore(group.id, "OnClosing", true, callback); + } + onRefreshing(callback, gdWindow) { + const glue42gd = typeof window !== "undefined" && window.glue42gd; + if (glue42gd && gdWindow.windowType === "electron") { + return glue42gd.addRefreshHandler(callback, gdWindow.id); + } + else { + return this.nonWindowHandlers(callback, gdWindow.id, "OnRefreshing"); + } + } + onNavigating(callback, gdWindow) { + const glue42gd = typeof window !== "undefined" && window.glue42gd; + if (glue42gd && gdWindow.windowType === "electron") { + return glue42gd.addWillNavigateHandler(callback, gdWindow.id); + } + else { + return this.nonWindowHandlers(callback, gdWindow.id, "OnNavigating"); + } + } + async clone(window, cloneOptions) { + const args = { + windowId: window.id, + options: cloneOptions + }; + const result = await this.execute("clone", args); + const win = await windowStore.waitFor(result.id); + return win.API; + } + async executeCode(targetWindow, code) { + const args = { + windowId: targetWindow.id, + options: { + code + } + }; + return this.execute("executeCode", args); + } + async goBack(resultWindow) { + await this.execute("goBack", { windowId: resultWindow.id }); + } + async goForward(resultWindow) { + await this.execute("goForward", { windowId: resultWindow.id }); + } + async getDockingPlacement(window) { + return this.execute("getDockingPlacement", { windowId: window.id }); + } + dock(window, options) { + return this.execute("dock", { windowId: window.id, options }); + } + clearCallbacks(id) { + const keys = Object.keys(this.unsubCallbacks); + keys.forEach((key) => { + if (key.startsWith(id)) { + delete this.unsubCallbacks[key]; + } + }); + } + nonWindowHandlers(callback, targetId, type) { + return this.nonWindowHandlersCore(targetId, type, false, callback); + } + nonWindowHandlersCore(targetId, type, isGroup, callback) { + const id = `${targetId}-${type}`; + const unsub = () => { + var _a; + if (this.unsubCallbacks[id]) { + const callbacks = this.unsubCallbacks[id]; + this.unsubCallbacks[id] = callbacks.filter((cb) => cb !== callback); + if (this.unsubCallbacks[id].length === 0) { + delete this.unsubCallbacks[id]; + } + } + const cbs = (_a = this.unsubCallbacks[id]) !== null && _a !== void 0 ? _a : []; + if (cbs.length === 0) { + const options = { + unsubscribe: true + }; + if (isGroup) { + this.executeGroup(type, { + groupId: targetId, + options + }); + } + else { + this.execute(type, { + windowId: targetId, + options + }); + } + } + }; + if (this.unsubCallbacks[id]) { + this.unsubCallbacks[id].push(callback); + return unsub; + } + else { + this.unsubCallbacks[id] = [callback]; + } + if (isGroup) { + this.executeGroup(type, { groupId: targetId }); + } + else { + this.execute(type, { windowId: targetId }); + } + return unsub; + } + reformatFlydownOptions(windowId, options) { + const assignGeneralIfUnassigned = (zone, prop) => { + if (options[prop] && (zone[prop] === undefined || zone[prop] === null)) { + const valueFromOptions = options[prop]; + zone[prop] = valueFromOptions; + } + }; + const zones = options.zones.map((z) => { + assignGeneralIfUnassigned(z, "windowId"); + assignGeneralIfUnassigned(z, "targetLocation"); + if (options.size && (z.flydownSize === undefined || z.flydownSize === null)) { + z.flydownSize = options.size; + } + z.flydownBounds = z.flydownSize; + z.flydownId = z.windowId; + if (!z.targetLocation) { + z.targetLocation = "bottom"; + } + return z; + }); + return { + ...options, + zones, + targetId: windowId, + flydownBounds: options.size, + flydownActiveArea: options.activeArea + }; + } + clearFlydownArea(windowId, areaIds) { + return this.execute("clearFlydownWindowArea", { + windowId, + options: {} + }).then(() => { + areaIds.forEach((id) => { + this._registry.clearKey(`${windowId}_${id}`); + }); + }); + } + executeWithoutToken(params, ...eventKeys) { + const uns = []; + const executed = eventKeys === null || eventKeys === void 0 ? void 0 : eventKeys.filter((k) => !isUndefinedOrNull(k)).map((key) => { + return new Promise((r) => { + const [type, windowId = params.windowId] = key.split("-"); + uns.push(this._registry.add("event", (data) => { + if (data.type === type && data.windowId === windowId) { + r(); + } + })); + }); + }); + const action = new Promise((resolve, reject) => { + this.agm.invoke("T42.Wnd.Execute", params, this.agmTarget, { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_RESPONSE_TIMEOUT_MS + }) + .then((i) => { + if (i.returned && i.returned.errorMsg) { + reject(i); + } + else { + resolve(i.returned); + } + }) + .catch((e) => reject(e)); + }); + return Promise.all([action, ...executed]) + .then((r) => { + return r[0]; + }) + .finally(() => { + uns.forEach((un) => un()); + }); + } + async executeCore(methodName, command, options, ...eventKeys) { + const { invocationOptions, ...invocationArgs } = options; + const params = { + ...invocationArgs, + command, + }; + let finishedResolve; + this._finished = new Promise((resolve) => { + finishedResolve = resolve; + }); + try { + if (typeof window !== "undefined" && window.glueDesktop.versionNum < 31200) { + return await this.executeWithoutToken(params, ...eventKeys); + } + else { + return await this.executeWithToken(methodName, params, invocationOptions); + } + } + finally { + finishedResolve(); + } + } + async executeWithToken(methodName, options, invocationOptions) { + let un; + try { + const token = Utils.generateId(); + const event = new Promise((r) => { + un = this._registry.add("event", (data) => { + if (data.token === token) { + r(); + } + }); + }); + const execute = new Promise((resolve, reject) => { + options.token = token; + if (!invocationOptions) { + invocationOptions = { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_RESPONSE_TIMEOUT_MS + }; + } + else if (!invocationOptions.methodResponseTimeoutMs) { + invocationOptions.methodResponseTimeoutMs = INTEROP_METHOD_RESPONSE_TIMEOUT_MS; + } + else if (!invocationOptions.waitTimeoutMs) { + invocationOptions.waitTimeoutMs = INTEROP_METHOD_WAIT_TIMEOUT_MS; + } + this.agm.invoke(methodName, options, this.agmTarget, invocationOptions) + .then((i) => { + if (i.returned && i.returned.errorMsg) { + reject(new Error(i.returned.errorMsg)); + } + else { + resolve(i.returned); + } + }) + .catch((e) => { + const error = Utils.typedError(e); + reject(error); + }); + }); + const result = await Promise.all([execute, event]); + return result[0]; + } + finally { + if (un) { + un(); + } + } + } + areBoundsEqual(requested, w) { + const current = w.bounds; + const settings = w.settings; + let height = requested.height; + let width = requested.width; + if (requested.height < settings.minHeight) { + height = settings.minHeight; + } + if (requested.height > settings.maxHeight) { + height = settings.maxHeight; + } + if (requested.width < settings.minWidth) { + width = settings.minWidth; + } + if (requested.width > settings.maxWidth) { + width = settings.maxWidth; + } + const areHeightsEqual = height ? current.height === height : true; + const areWidthsEqual = width ? current.width === width : true; + const areLeftsEqual = requested.left ? current.left === requested.left : true; + const areTopsEqual = requested.top ? current.top === requested.top : true; + return areHeightsEqual && areWidthsEqual && areLeftsEqual && areTopsEqual; + } + swapUndefinedToNull(context) { + try { + const copy = {}; + for (const key of Object.keys(context)) { + let value = context[key]; + if (typeof value === "undefined") { + value = null; + } + copy[key] = value; + } + return copy; + } + catch { + return context; + } + } + showPopupCore(id, options) { + if (!options) { + throw new Error("The options object is not valid!"); + } + const optionsCopy = { ...options }; + if (!optionsCopy.targetLocation) { + optionsCopy.targetLocation = "bottom"; + } + const reformatedOptions = { + ...optionsCopy, + popupBounds: optionsCopy.size, + targetId: id, + popupId: optionsCopy.windowId + }; + return reformatedOptions; + } + } + var executor = new GDExecutor(); + + class GDEnvironment { + constructor(agm, logger, appManagerGetter, displayAPIGetter, channelsAPIGetter, wndId, groupId) { + this._registry = CallbackRegistryFactory(); + this._agm = agm; + this._logger = logger.subLogger("gd-env"); + this._windowId = wndId; + this._groupId = groupId; + this._appManagerGetter = appManagerGetter; + this._displayAPIGetter = displayAPIGetter; + this._channelsAPIGetter = channelsAPIGetter; + } + init() { + return new Promise((resolve, reject) => { + this._agm.register("T42.Wnd.OnEventWithResponse", (args, caller) => { + return this.respondToEvent(args); + }); + new Promise((streamResolve, streamReject) => { + this._agm.subscribe("T42.Wnd.OnEvent", { + target: "best", + arguments: { + withConfig: true + }, + onData: (streamData) => { + if (streamData.data.type === "Configuration") { + this._configuration = streamData.data; + executor.setConfiguration(this._configuration); + return; + } + this.updateWindow(streamData.data, resolve); + executor.handleEvent(streamData.data); + }, + onConnected: (instance) => { + this._agmInstance = instance; + executor.init(this._agm, this._agmInstance); + } + }).catch((error) => { + var _a; + const message = `${(_a = error === null || error === void 0 ? void 0 : error.method) === null || _a === void 0 ? void 0 : _a.name} - ${JSON.stringify(error === null || error === void 0 ? void 0 : error.called_with)} - ${error === null || error === void 0 ? void 0 : error.message}`; + reject(new Error(message)); + }); + }); + }); + } + get executor() { + return executor; + } + open(name, url, options) { + options = options || {}; + const copyOptions = { ...options }; + if (copyOptions.relativeTo !== undefined && typeof copyOptions.relativeTo !== "string") { + copyOptions.relativeTo = copyOptions.relativeTo.id || ""; + } + copyOptions.name = name; + copyOptions.url = url; + copyOptions.windowState = options.windowState || options.state; + delete copyOptions.state; + return this.executor.open(copyOptions); + } + createFlydown(windowId, options) { + return this.executor.createFlydown(windowId, options); + } + async showPopup(windowId, options) { + const window = windowStore.get(windowId); + await this.executor.showPopup(window.API, options); + } + tabAttached(callback) { + return this._registry.add("tab-attached", callback); + } + tabDetached(callback) { + return this._registry.add("tab-detached", callback); + } + onWindowFrameColorChanged(callback) { + return this._registry.add("frame-color-changed", callback); + } + onEvent(callback) { + return this._registry.add("window-event", callback); + } + my() { + return this._windowId; + } + myGroup() { + return this._groupId; + } + onCompositionChanged(callback) { + return this._registry.add("composition-changed", callback); + } + onGroupHeaderVisibilityChanged(callback) { + return this._registry.add("group-header-changed", callback); + } + onGroupVisibilityChanged(callback) { + return this._registry.add("group-visibility-changed", callback); + } + onGroupStateChanged(callback) { + return this._registry.add("group-state-changed", callback); + } + onWindowGotFocus(callback) { + return this._registry.add("got-focus", callback); + } + onWindowLostFocus(callback) { + return this._registry.add("lost-focus", callback); + } + onWindowsAutoArrangeChanged(callback) { + return this._registry.add("windows-auto-arranged-changed", callback); + } + respondToEvent(args) { + if (args.type === "ShowFlydownBoundsRequested") { + return this.executor.handleFlydownBoundsRequested(args.data.windowId, args.data); + } + else if (args.type === "OnClosing" || args.type === "OnRefreshing" || args.type === "OnNavigating") { + return this.executor.handleOnEventRequested(args.data.callbackId, args.data.args); + } + return Promise.reject(`There isn't a handler for ${args.type}`); + } + updateWindow(windowInfo, readyResolve) { + const extendedStreamEvent = this.getExtendedStreamEvent(windowInfo); + if (windowInfo.type === "Snapshot") { + const windowInfoFullInfoEvent = windowInfo; + windowInfoFullInfoEvent.windows.forEach((w) => { + const existingWindow = windowStore.get(w.id); + if (existingWindow) { + existingWindow.Events.handleUpdate(this.mapToWindowConstructorOptions(w)); + existingWindow.GroupCreationArgs = this.mapToGroupCreationArgs(w); + } + else { + this.createWindowFromSnapshot(w.id, w); + } + this._registry.execute("window-event", extendedStreamEvent); + }); + readyResolve(this); + return; + } + if (windowInfo.type === "CommandExecuted") { + this._registry.execute("window-event", extendedStreamEvent); + return; + } + if (windowInfo.type === "Created") { + const windowInfoCreatedEvent = (windowInfo); + this.createWindowFromStream(windowInfoCreatedEvent.windowId, windowInfoCreatedEvent.data || {}); + this._registry.execute("window-event", extendedStreamEvent); + return; + } + if (windowInfo.type === "OnGroupVisibilityChanged") { + const info = windowInfo; + this._registry.execute("group-visibility-changed", info.data); + this._registry.execute("window-event", windowInfo); + return; + } + if (windowInfo.type === "OnGroupStateChanged") { + const info = windowInfo; + this._registry.execute("group-state-changed", info.data); + this._registry.execute("window-event", windowInfo); + return; + } + if (windowInfo.type === "OnWindowsAutoArrangeChanged") { + const info = windowInfo; + this._registry.execute("windows-auto-arranged-changed", info.data); + this._registry.execute("window-event", windowInfo); + return; + } + const windowObjectAndEvents = windowStore.get((windowInfo).windowId); + if (!windowObjectAndEvents) { + this._logger.error(`received update for unknown window. Stream:', ${JSON.stringify(windowInfo, null, 4)}`); + return; + } + const theWindow = windowObjectAndEvents.API; + const theWindowEvents = windowObjectAndEvents.Events; + if (windowInfo.type === "BoundsChanged") { + const windowInfoBoundsChangedEvent = windowInfo; + theWindowEvents.handleBoundsChanged(windowInfoBoundsChangedEvent.data); + } + if (windowInfo.type === "UrlChanged") { + const windowInfoUrlChangedEvent = windowInfo; + windowStore.setUrlChangedState(windowInfoUrlChangedEvent.windowId); + theWindowEvents.handleUrlChanged(windowInfoUrlChangedEvent.data); + } + if (windowInfo.type === "TitleChanged") { + const windowInfoTitleChanged = windowInfo; + theWindowEvents.handleTitleChanged(windowInfoTitleChanged.data); + } + if (windowInfo.type === "IsStickyChanged") { + const windowInfoIsStickyChangedChanged = windowInfo; + theWindowEvents.handleIsStickyChanged(windowInfoIsStickyChangedChanged.data); + } + if (windowInfo.type === "VisibilityChanged") { + theWindowEvents.handleVisibilityChanged(windowInfo.data); + } + if (windowInfo.type === "ContextChanged") { + theWindowEvents.handleContextUpdated(windowInfo.data); + } + if (windowInfo.type === "StateChanged") { + theWindowEvents.handleWindowChangeState(windowInfo.data); + } + if (windowInfo.type === "FrameColorChanged") { + theWindowEvents.handleFrameColorChanged(windowInfo.data); + this._registry.execute("frame-color-changed", theWindow); + } + if (windowInfo.type === "CompositionChanged") { + const windowInfoCompositionChanged = windowInfo; + theWindowEvents.handleCompositionChanged(windowInfoCompositionChanged.data); + windowStore.setCompositionChangedState(windowObjectAndEvents); + this._registry.execute("composition-changed", windowInfoCompositionChanged.data); + } + if (windowInfo.type === "GroupHeaderVisibilityChanged") { + const info = windowInfo; + theWindowEvents.handleGroupHeaderVisibilityChanged(info.data.groupHeaderVisible); + this._registry.execute("group-header-changed", info.data); + } + if (windowInfo.type === "FocusChanged") { + const windowInfoFocusChanged = windowInfo; + this.focusChanged(theWindowEvents, theWindow, windowInfoFocusChanged.data); + } + if (windowInfo.type === "WindowFrameChanged") { + theWindowEvents.handleFrameAttached(windowInfo.data.frameId, windowInfo.data.frameId, windowInfo.data.isTabHeaderVisible); + this._registry.execute("frame-changed"); + } + if (windowInfo.type === "WindowFrameAdded") { + const winsToBeNotified = getWindowsByTabGroupId(theWindow.id, windowInfo.data.frameId); + const data = windowInfo.data; + theWindowEvents.handleAttached(data.frameId, data.frameId, data.isTabHeaderVisible, data.isLocked, winsToBeNotified) + .then(async () => { + if (winsToBeNotified.length > 0) { + await executor.finished; + this._registry.execute("tab-attached", theWindow, windowInfo.data.frameId, windowInfo.data.isTabHeaderVisible); + } + }); + } + if (windowInfo.type === "WindowFrameRemoved") { + const oldTabGroupId = theWindow.tabGroupId; + const winsToBeNotified = getWindowsByTabGroupId(theWindow.id, oldTabGroupId); + theWindowEvents.handleDetached(windowInfo.data.isLocked, winsToBeNotified) + .then(async () => { + if (winsToBeNotified.length > 0) { + await executor.finished; + this._registry.execute("tab-detached", theWindow, windowInfo.data.frameId, theWindow.tabGroupId); + } + }); + } + if (windowInfo.type === "TabHeaderVisibilityChanged") { + theWindowEvents.handleTabHeaderVisibilityChanged(windowInfo.data.isTabHeaderVisible); + } + if (windowInfo.type === "FrameSelectionChanged") { + theWindowEvents.handleFrameSelectionChanged(windowInfo.data.newWindowId, windowInfo.data.prevWindowId); + } + if (windowInfo.type === "ButtonClicked") { + theWindowEvents.handleFrameButtonClicked(windowInfo.data); + } + if (windowInfo.type === "ButtonAdded") { + theWindowEvents.handleFrameButtonAdded(windowInfo.data); + } + if (windowInfo.type === "ButtonRemoved") { + theWindowEvents.handleFrameButtonRemoved(windowInfo.data); + } + if (windowInfo.type === "WindowZoomFactorChanged") { + theWindowEvents.handleZoomFactorChanged(windowInfo.data); + } + if (windowInfo.type === "Closed") { + windowStore.remove(windowObjectAndEvents); + theWindowEvents.handleWindowClose(); + } + if (windowInfo.type === "FrameIsLockedChanged") { + theWindowEvents.handleFrameIsLockedChanged(windowInfo.data); + } + if (windowInfo.type === "PlacementSettingsChanged") { + theWindowEvents.handlePlacementSettingsChanged(windowInfo.data); + } + if (windowInfo.type === "DockingChanged") { + theWindowEvents.handleDockingChanged(windowInfo.data); + } + if (windowInfo.type === "AllowWorkspaceDropChanged") { + theWindowEvents.handleAllowWorkspaceDropChanged(windowInfo.data); + } + if (windowInfo.type === "IsPinnedChanged") { + theWindowEvents.handleIsPinnedChanged(windowInfo.data); + } + if (windowInfo.type === "WindowChannelRestrictionsChanged") { + theWindowEvents.handleChannelRestrictionsChanged(windowInfo.data); + } + this._registry.execute("window-event", extendedStreamEvent); + } + createWindowFromSnapshot(windowId, options) { + const windowObjAndEvents = this.createWindowCore(windowId, options); + windowStore.add(windowObjAndEvents, { + ready: true, + urlChanged: true, + compositionChanged: true + }); + } + createWindowFromStream(windowId, options) { + var _a; + const windowObjAndEvents = this.createWindowCore(windowId, options); + const isRemote = windowObjAndEvents.API.windowType === "remote"; + const isFrameless = windowObjAndEvents.API.windowType === "electron" && windowObjAndEvents.API.mode === "frameless"; + const isHidden = windowObjAndEvents.API.isVisible === false; + let urlChanged = false; + let compositionChanged = false; + if (isRemote) { + urlChanged = true; + } + if (isFrameless || isHidden) { + compositionChanged = true; + } + if (!isRemote) { + urlChanged = !((_a = this._configuration) === null || _a === void 0 ? void 0 : _a.windowAvailableOnURLChanged); + } + windowStore.add(windowObjAndEvents, { + ready: true, + urlChanged, + compositionChanged + }); + } + createWindowCore(windowId, options) { + const windowObjAndEvents = windowFactory(windowId, this.mapToWindowConstructorOptions(options), executor, this._logger, this._appManagerGetter, this._displayAPIGetter, this._channelsAPIGetter, this._agm); + windowObjAndEvents.GroupCreationArgs = this.mapToGroupCreationArgs(options); + return windowObjAndEvents; + } + async focusChanged(theWindowEvents, theWindow, focus) { + theWindowEvents.handleFocusChanged(focus); + try { + if (!this._configuration.windowAvailableOnURLChanged) { + await windowStore.waitFor(theWindow.id); + } + } + catch (error) { + return; + } + if (focus) { + this._registry.execute("got-focus", theWindow); + } + else { + this._registry.execute("lost-focus", theWindow); + } + } + mapToWindowConstructorOptions(args) { + return { + name: args.name, + context: args.context, + bounds: args.bounds, + url: args.url, + title: args.title, + isVisible: args.isVisible, + focus: args.isFocused, + state: args.state, + frameColor: args.frameColor, + groupId: args.groupId, + neighbours: args.neighbors, + isFocused: args.isFocused, + isGroupHeaderVisible: args.groupHeaderVisible, + isCollapsed: args.isCollapsed, + tabGroupId: args.frameId, + frameId: args.frameId, + mode: args.mode, + isTabHeaderVisible: args.isTabHeaderVisible, + isTabSelected: args.isActiveTab, + settings: args.settings, + windowType: args.windowType, + zoomFactor: args.zoomFactor, + isLocked: args.isLocked, + placementSettings: args.placementSettings, + isSticky: args.isSticky, + tabIndex: args.tabIndex, + frameButtons: args.frameButtons, + jumpListOptions: args.jumpList, + applicationName: args.applicationName, + allowWorkspaceDrop: args.allowWorkspaceDrop, + isPinned: args.isPinned + }; + } + mapToGroupCreationArgs(args) { + return { + isGroupHibernated: args.isGroupHibernated, + isGroupVisible: args.isGroupVisible + }; + } + getExtendedStreamEvent(streamEvent) { + try { + if (!streamEvent.windowId) { + return streamEvent; + } + const window = windowStore.get(streamEvent.windowId); + if (!window) { + return streamEvent; + } + const result = { + state: streamEvent.type, + windowName: window.API.name, + ...streamEvent + }; + if (result.state === "WindowFrameAdded") { + result.state = "TabAttached"; + } + if (result.state === "StateChanged") { + result.state = result.data.charAt(0).toUpperCase() + result.data.slice(1); + } + if (result.state === "ButtonAdded") { + result.state = "FrameButtonAdded"; + } + if (result.state === "ButtonRemoved") { + result.state = "FrameButtonRemoved"; + } + return result; + } + catch (error) { + return streamEvent; + } + } + } + + var envDetector = (agm, logger, appManagerGetter, displayAPIGetter, channelsAPIGetter, gdMajorVersion) => { + var _a; + const _logger = logger; + if (gdMajorVersion === 2) { + _logger.trace("running in HC"); + throw new Error("GD2 not supported"); + } + else if (gdMajorVersion >= 3) { + _logger.trace("running in GD 3"); + return new GDEnvironment(agm, _logger, appManagerGetter, displayAPIGetter, channelsAPIGetter, window.glue42gd.windowId, (_a = window.webGroupsManager) === null || _a === void 0 ? void 0 : _a.id).init(); + } + else { + _logger.trace("running in Browser or Node"); + return new GDEnvironment(agm, _logger, appManagerGetter, displayAPIGetter, channelsAPIGetter).init(); + } + }; + + var groupFactory = (id, executor) => { + const _registry = CallbackRegistryFactory(); + const _windowsId = []; + let _isHibernatedFlag; + let _isVisible; + async function addWindow(winId) { + var _a, _b, _c, _d; + if (_windowsId.indexOf(winId) === -1) { + _windowsId.push(winId); + const win = windowStore.get(winId); + win.Events.handleGroupChanged(groupObject, undefined); + _isHibernatedFlag = (_b = (_a = win.GroupCreationArgs.isGroupHibernated) !== null && _a !== void 0 ? _a : _isHibernatedFlag) !== null && _b !== void 0 ? _b : false; + _isVisible = (_d = (_c = win.GroupCreationArgs.isGroupVisible) !== null && _c !== void 0 ? _c : _isVisible) !== null && _d !== void 0 ? _d : true; + await executor.finished; + _registry.execute("window-added", groupObject, win.API); + } + } + async function removeWindow(win) { + const index = _windowsId.indexOf(win.API.id); + if (index !== -1) { + _windowsId.splice(index, 1); + win.Events.handleGroupChanged(undefined, groupObject); + await executor.finished; + _registry.execute("window-removed", groupObject, win.API); + } + } + function find(window, success, error) { + let winId; + if (typeof window === "string") { + winId = window; + } + else if (!isUndefinedOrNull(window)) { + winId = window.id; + } + const win = _mapToWindowObject(winId); + if (win) { + if (typeof success === "function") { + success(win); + } + return win; + } + else { + if (typeof error === "function") { + error(`No window with ID: ${winId}`); + } + } + } + function windows(success) { + const mappedWindows = _mapToWindowObjects(); + return mappedWindows; + } + async function execute(command, options, ...keys) { + await executor.execute(command, options, ...keys); + return groupObject; + } + function handleGroupHeaderVisibilityChanged(windowInfo) { + _registry.execute("header-visibility-changed", groupObject); + } + function handleGroupVisibilityChanged(visibile) { + _isVisible = visibile; + _registry.execute("group-visibility-changed", groupObject); + } + function handleGroupHibernateChanged(isHibernatedFlag) { + _isHibernatedFlag = isHibernatedFlag; + } + function _mapToWindowObjects() { + const winObjects = []; + _windowsId.forEach((winId) => { + const windowObject = _mapToWindowObject(winId); + if (typeof windowObject !== "undefined") { + winObjects.push(windowObject); + } + }); + return winObjects; + } + function _mapToWindowObject(windowId) { + return windowStore.get(windowId) ? windowStore.get(windowId).API : undefined; + } + function _getGroupHeaderVisibility() { + const windowWithHiddenHeader = _mapToWindowObjects().find((w) => !w.isGroupHeaderVisible); + const _isGroupHeaderVisible = windowWithHiddenHeader === undefined; + return _isGroupHeaderVisible; + } + function isHibernated() { + return _isHibernatedFlag; + } + function onHeaderVisibilityChanged(callback) { + return _registry.add("header-visibility-changed", callback); + } + function onWindowAdded(callback) { + return _registry.add("window-added", callback); + } + function onWindowRemoved(callback) { + return _registry.add("window-removed", callback); + } + function onVisibilityChanged(callback) { + if (!callback) { + throw new Error("Callback argument is required"); + } + if (callback && typeof callback !== "function") { + throw new Error("Callback argument must be a function"); + } + return _registry.add("group-visibility-changed", callback); + } + function onClosing(callback) { + if (typeof callback !== "function") { + throw new Error("callback must be a function"); + } + const callbackWrap = (success, error, prevent) => { + const promise = callback(prevent); + if (promise === null || promise === void 0 ? void 0 : promise.then) { + promise.then(success).catch(error); + } + else { + success(); + } + }; + return executor.onGroupClosing(callbackWrap, groupObject); + } + const groupObject = { + id, + get windows() { + return windows(); + }, + find, + get isHeaderVisible() { + return _getGroupHeaderVisibility(); + }, + get isHibernated() { + return isHibernated(); + }, + get isVisible() { + return _isVisible; + }, + showHeader: (success, error) => { + return Utils.callbackifyPromise(() => { + return execute("setGroupHeaderVisibility", { windowId: _windowsId[0], options: { toShow: true } }, ..._windowsId.map((w) => `GroupHeaderVisibilityChanged-${w}`)); + }, success, error); + }, + hideHeader: (success, error) => { + return Utils.callbackifyPromise(() => { + return execute("setGroupHeaderVisibility", { windowId: _windowsId[0], options: { toShow: false } }, ..._windowsId.map((w) => `GroupHeaderVisibilityChanged-${w}`)); + }, success, error); + }, + getTitle: async () => { + const r = await executor.execute("getGroupTitle", { windowId: _windowsId[0] }); + return r.title; + }, + setTitle: async (title) => { + if (isNullOrWhiteSpace(title)) { + throw new Error("`title` must not be null or undefined."); + } + return execute("setGroupTitle", { windowId: _windowsId[0], options: { title } }); + }, + capture: (captureOptions) => { + return executor.captureGroup(_windowsId, captureOptions); + }, + maximize: (success, error) => { + return Utils.callbackifyPromise(() => { + return execute("maximizeGroup", { windowId: _windowsId[0] }, ..._windowsId.map((w) => `StateChanged-${w}`)); + }, success, error); + }, + restore: (success, error) => { + return Utils.callbackifyPromise(() => { + return execute("restoreGroup", { windowId: _windowsId[0] }, ..._windowsId.map((w) => `StateChanged-${w}`)); + }, success, error); + }, + show: (activate) => { + if (!isUndefinedOrNull(activate) && !isBoolean(activate)) { + throw new Error("Activate flag must be a boolean!"); + } + activate = !isUndefinedOrNull(activate) ? activate : true; + return executor.executeGroup("showGroup", { + groupId: id, + options: { activate } + }); + }, + hide: () => { + return executor.executeGroup("hideGroup", { + groupId: id + }); + }, + close: () => { + return executor.executeGroup("closeGroup", { + groupId: id + }); + }, + showPopup: (options) => { + return executor.showGroupPopup(id, options); + }, + onHeaderVisibilityChanged, + onWindowAdded, + onWindowRemoved, + onVisibilityChanged, + onClosing, + }; + const internal = { + get windows() { + return _windowsId; + }, + addWindow, + removeWindow, + handleGroupHeaderVisibilityChanged, + handleGroupVisibilityChanged, + handleGroupHibernateChanged + }; + return { + groupAPI: groupObject, + groupInternal: internal, + }; + }; + + var groupsFactory = (environment, logger) => { + const _registry = CallbackRegistryFactory(); + const _groups = {}; + let heardForWindowsCounter = -1; + const windows = windowStore.list; + Object.keys(windows).forEach((k) => { + const win = windows[k]; + const groupId = win.API.groupId; + const winId = win.API.id; + if (!isNullOrWhiteSpace(groupId)) { + addWindow(groupId, winId); + } + }); + windowStore.onRemoved((w) => { + const group = findGroupWrapperByWindow(w.API); + removeWindow(group, w); + }); + environment.onCompositionChanged((windowInfo) => { + handleCompositionChanged(windowInfo); + }); + environment.onGroupHeaderVisibilityChanged((windowInfo) => { + const windowId = windowInfo.windowId; + const group = findGroupByWindow(windowId); + if (typeof group !== "undefined") { + const groupEvents = _groups[group.id]; + if (heardForWindowsCounter === -1) { + heardForWindowsCounter = group.windows.length; + } + heardForWindowsCounter--; + if (heardForWindowsCounter === 0) { + heardForWindowsCounter = -1; + groupEvents.groupInternal.handleGroupHeaderVisibilityChanged(windowInfo); + } + } + }); + environment.onGroupVisibilityChanged((data) => { + const groupEvents = _groups[data.groupId]; + if (groupEvents) { + groupEvents.groupInternal.handleGroupVisibilityChanged(data.visible); + } + }); + environment.onGroupStateChanged((data) => { + const groupWrapper = _groups[data.groupId]; + if (data.state === "hibernated") { + if (groupWrapper === null || groupWrapper === void 0 ? void 0 : groupWrapper.groupAPI) { + groupWrapper.groupInternal.handleGroupHibernateChanged(true); + } + _registry.execute("group-hibernated", data.groupId); + } + else if (data.state === "resumed") { + if (groupWrapper === null || groupWrapper === void 0 ? void 0 : groupWrapper.groupAPI) { + groupWrapper.groupInternal.handleGroupHibernateChanged(false); + } + _registry.execute("group-resumed", groupWrapper.groupAPI); + } + }); + function my() { + var _a; + return findGroupByWindow((_a = environment.myGroup()) !== null && _a !== void 0 ? _a : environment.my()); + } + async function create(options) { + if (isUndefinedOrNull(options)) { + throw new Error(`options must be defined`); + } + if (isUndefinedOrNull(options.groups) || !Array.isArray(options.groups) || options.groups.length === 0) { + throw new Error(`options.groups must be defined`); + } + const { groupIds } = await executor.executeGroup("createGroups", { + options + }); + const groups = groupIds.map((groupId) => { + return waitForGroup(groupId); + }); + return Promise.all(groups); + } + async function close(idOrGroup, options) { + if (isUndefinedOrNull(idOrGroup)) { + throw new Error(`group must be defined`); + } + let groupId = ""; + if (typeof idOrGroup === "string") { + groupId = idOrGroup; + } + else { + groupId = idOrGroup.id; + } + if (isUndefinedOrNull(options)) { + throw new Error(`options must be defined`); + } + await executor.executeGroup("closeGroup", { + groupId, + options + }); + } + function list(success) { + const result = Object.keys(_groups).map((groupId) => { + if (_groups[groupId]) { + return _groups[groupId].groupAPI; + } + }); + if (typeof success === "function") { + success(result); + } + return result; + } + function findGroupByWindow(winId, success, error) { + let windowId; + if (typeof winId === "string") { + windowId = winId; + } + else if (!isUndefinedOrNull(winId)) { + windowId = winId.id; + } + const result = Object.values(_groups).find((groupObj) => { + const group = groupObj.groupAPI; + const wins = group.windows.filter((w) => w.id === windowId); + return wins.length; + }); + if (result) { + if (typeof success === "function") { + success(result.groupAPI); + } + return result.groupAPI; + } + else if (typeof error === "function") { + error(`Cannot find the group of the window.`); + } + } + function waitForGroup(groupId) { + if (!groupId) { + return Promise.reject(new Error(`groupId must be defined`)); + } + return new Promise((res, rej) => { + const groupWrapper = _groups[groupId]; + if (groupWrapper) { + res(groupWrapper.groupAPI); + } + else { + const un = onGroupAdded((group) => { + if (group.id === groupId) { + un(); + res(group); + } + }); + } + }); + } + function getMyGroup() { + var _a; + return waitForGroup((_a = environment.myGroup()) !== null && _a !== void 0 ? _a : environment.my()); + } + async function resume(groupId, activate) { + validateGroupIdArg(groupId); + if (!isUndefinedOrNull(activate) && !isBoolean(activate)) { + throw new Error("Activate flag must be a boolean!"); + } + activate = !isUndefinedOrNull(activate) ? activate : true; + await executor.executeGroup("resumeGroup", { + groupId, + options: { activate } + }); + } + async function hibernate(groupId) { + validateGroupIdArg(groupId); + await executor.executeGroup("hibernateGroup", { + groupId + }); + return groupId; + } + function onGroupAdded(callback) { + return _registry.add("group-added", callback); + } + function onGroupRemoved(callback) { + return _registry.add("group-removed", callback); + } + function onWindowMoved(callback) { + return _registry.add("window-moved", callback); + } + function onHibernated(callback) { + if (!callback) { + throw new Error("Callback argument is required"); + } + if (callback && typeof callback !== "function") { + throw new Error("Callback argument must be a function"); + } + return _registry.add("group-hibernated", callback); + } + function onResumed(callback) { + if (!callback) { + throw new Error("Callback argument is required"); + } + if (callback && typeof callback !== "function") { + throw new Error("Callback argument must be a function"); + } + return _registry.add("group-resumed", callback); + } + function createOrGet(groupId) { + if (!_groups.hasOwnProperty(groupId)) { + const createdGroupWrapper = groupFactory(groupId, environment.executor); + _groups[groupId] = createdGroupWrapper; + const group = createdGroupWrapper.groupAPI; + _registry.execute("group-added", group); + return createdGroupWrapper; + } + else { + return _groups[groupId]; + } + } + function deleteIfEmpty(groupWrapper) { + const group = groupWrapper.groupAPI; + if (group.windows.length === 0) { + delete _groups[group.id]; + executor.clearCallbacks(group.id); + _registry.execute("group-removed", group); + } + } + function addWindow(groupId, winId) { + const group = createOrGet(groupId); + group.groupInternal.addWindow(winId); + return group; + } + function removeWindow(group, win) { + if (!group) { + return; + } + group.groupInternal.removeWindow(win); + deleteIfEmpty(group); + } + function handleCompositionChanged(state) { + const groupId = state.groupId; + const windowId = state.windowId; + const win = windowStore.get(windowId); + if (!win) { + return; + } + const currentGroup = findGroupWrapperByWindow(win.API); + if (isUndefinedOrNull(groupId)) { + removeWindow(currentGroup, win); + return; + } + if (isUndefinedOrNull(currentGroup) && !isUndefinedOrNull(groupId)) { + addWindow(groupId, win.API.id); + return; + } + if (currentGroup.groupAPI.id !== groupId) { + moveWindow(win, currentGroup.groupAPI.id, groupId); + } + } + function moveWindow(win, from, to) { + const winId = win.API.id; + const fromGroup = _groups[from]; + removeWindow(fromGroup, win); + const toGroup = addWindow(to, winId); + win.Events.handleGroupChanged(toGroup.groupAPI, fromGroup.groupAPI); + _registry.execute("window-moved", winId, from, to); + } + function findGroupWrapperByWindow(winId) { + let windowId; + if (typeof winId === "string") { + windowId = winId; + } + else if (!isUndefinedOrNull(winId)) { + windowId = winId.id; + } + return Object.values(_groups).find((groupObj) => { + const groupInternal = groupObj.groupInternal; + const wins = groupInternal.windows.filter((id) => id === windowId); + return wins.length; + }); + } + function validateGroupIdArg(groupId) { + if (!groupId || typeof groupId !== "string") { + throw new Error("Please provide a valid Group ID as a non-empty string!"); + } + } + const groups = { + get my() { + return my(); + }, + create, + close, + list, + findGroupByWindow, + waitForGroup, + getMyGroup, + onGroupAdded, + onGroupRemoved, + hibernate, + resume, + onHibernated, + onResumed + }; + const events = { onWindowMoved }; + return { + groupsAPI: groups, + groupsEvents: events, + }; + }; + + var WindowsFactory = (agm, logger, appManagerGetter, displayAPIGetter, channelsGetter, gdMajorVersion) => { + const _registry = CallbackRegistryFactory(); + const _logger = logger; + let groups; + let environment; + windowStore.init(_logger); + const isReady = new Promise((resolve, reject) => { + envDetector(agm, _logger, appManagerGetter, displayAPIGetter, channelsGetter, gdMajorVersion) + .then((env) => { + environment = env; + groups = groupsFactory(env); + jumpListManager.init(env.executor, agm, _logger); + resolve(); + }) + .catch((e) => { + const err = `Timed out waiting for connection to Glue42 Enterprise: Error: ${e.message}`; + _logger.error(err, e); + reject(new Error(err)); + }); + }); + function ready() { + return isReady; + } + function my() { + const myWindow = windowStore.getIfReady(environment.my()); + return myWindow ? myWindow.API : undefined; + } + function open(name, url, options, success, error) { + return Utils.callbackifyPromise(() => { + if (isNullOrWhiteSpace(name)) { + throw new Error("The window name is missing."); + } + if (isNullOrWhiteSpace(url)) { + throw new Error("The window URL is missing."); + } + if (!isUndefinedOrNull(options)) { + const optionsAsAny = options; + for (const prop of ["minHeight", "maxHeight", "minWidth", "maxWidth", "width", "height", "top", "left"]) { + if (prop in optionsAsAny) { + const value = optionsAsAny[prop]; + if (isUndefinedOrNull(value)) { + delete optionsAsAny[prop]; + continue; + } + if (!isNumber(value)) { + const errMessage = `${prop} must be a number`; + throw new Error(errMessage); + } + if (optionsAsAny[prop] === "width" || optionsAsAny[prop] === "height") { + if (value <= 0) { + const errMessage = `${prop} must be a positive number`; + throw new Error(errMessage); + } + } + } + } + } + return environment.open(name, url, options); + }, success, error); + } + function find(name, success, error) { + const windows = windowStore.list; + const windowsForListing = Object.keys(windows).reduce((memo, winId) => { + var _a; + const window = windows[winId]; + if (((_a = window === null || window === void 0 ? void 0 : window.API) === null || _a === void 0 ? void 0 : _a.name) === name) { + memo.push(window.API); + } + return memo; + }, []); + const win = windowsForListing[0]; + if (win) { + if (typeof success === "function") { + success(windowsForListing[0]); + } + return windowsForListing[0]; + } + else { + if (typeof error === "function") { + error("There is no window with name:" + name); + } + } + } + function findById(id, success, error) { + const windows = windowStore.list; + const windowsForListing = Object.keys(windows).reduce((memo, winId) => { + const window = windows[winId]; + if (typeof window !== "undefined" && window.API.id === id) { + memo.push(window.API); + } + return memo; + }, []); + const win = windowsForListing[0]; + if (win) { + if (typeof success === "function") { + success(windowsForListing[0]); + } + return windowsForListing[0]; + } + else { + if (typeof error === "function") { + error("There is no window with such id:" + id); + } + } + } + function list(success) { + const windows = windowStore.list; + const windowsForListing = Object.keys(windows) + .map((k) => { + return windows[k].API; + }); + if (typeof success !== "function") { + return windowsForListing; + } + success(windowsForListing); + } + function configure(options) { + const win = my(); + const winId = win ? win.id : ""; + return executor.configure(winId, options); + } + function autoArrange(displayId) { + return executor.autoArrange(displayId); + } + function windowAdded(callback) { + return _registry.add("window-added", callback); + } + function windowRemoved(callback) { + return _registry.add("window-removed", callback); + } + function tabAttached(callback) { + let unsubFunc; + let unsubscribed = false; + isReady.then(() => { + if (unsubscribed) { + return; + } + unsubFunc = environment.tabAttached(callback); + }); + return () => { + unsubscribed = true; + if (unsubFunc) { + unsubFunc(); + } + }; + } + function tabDetached(callback) { + let unsubFunc; + let unsubscribed = false; + isReady.then(() => { + if (unsubscribed) { + return; + } + unsubFunc = environment.tabDetached(callback); + }); + return () => { + unsubscribed = true; + if (unsubFunc) { + unsubFunc(); + } + }; + } + function onWindowFrameColorChanged(callback) { + let unsubFunc; + let unsubscribed = false; + isReady.then(() => { + if (unsubscribed) { + return; + } + unsubFunc = environment.onWindowFrameColorChanged(callback); + }); + return () => { + unsubscribed = true; + if (unsubFunc) { + unsubFunc(); + } + }; + } + function onWindowGotFocus(callback) { + let unsubFunc; + let unsubscribed = false; + isReady.then(() => { + if (unsubscribed) { + return; + } + unsubFunc = environment.onWindowGotFocus(callback); + }); + return () => { + unsubscribed = true; + if (unsubFunc) { + unsubFunc(); + } + }; + } + function onWindowLostFocus(callback) { + let unsubFunc; + let unsubscribed = false; + isReady.then(() => { + if (unsubscribed) { + return; + } + unsubFunc = environment.onWindowLostFocus(callback); + }); + return () => { + unsubscribed = true; + if (unsubFunc) { + unsubFunc(); + } + }; + } + function onArrangementChanged(callback) { + return environment.onWindowsAutoArrangeChanged(callback); + } + function onEvent(callback) { + let unsubFunc; + let unsubscribed = false; + isReady.then(() => { + if (unsubscribed) { + return; + } + unsubFunc = environment.onEvent(callback); + }); + return () => { + unsubscribed = true; + if (unsubFunc) { + unsubFunc(); + } + }; + } + function createFlydown(targetId, config) { + return environment.createFlydown(targetId, config); + } + function showPopup(targetId, config) { + return environment.showPopup(targetId, config); + } + function handleWindowAdded(w) { + _registry.execute("window-added", w.API); + } + function handleWindowRemoved(w) { + _registry.execute("window-removed", w.API); + } + windowStore.onReadyWindow(handleWindowAdded); + windowStore.onRemoved(handleWindowRemoved); + return { + my, + open, + find, + findById, + list, + ready, + onWindowAdded: windowAdded, + windowAdded, + onWindowRemoved: windowRemoved, + windowRemoved, + onTabAttached: tabAttached, + onTabDetached: tabDetached, + onWindowFrameColorChanged, + onArrangementChanged, + get groups() { + return groups.groupsAPI; + }, + onWindowGotFocus, + onWindowLostFocus, + onEvent, + createFlydown, + showPopup, + configure, + autoArrange + }; + }; + + class LayoutStore { + constructor() { + this.layouts = []; + } + removeWhere(condition) { + this.layouts = this.layouts.filter(condition); + } + removeAll() { + this.layouts = []; + } + add(item) { + this.layouts.push(item); + } + get all() { + return this.layouts; + } + where(condition) { + return this.layouts.filter(condition); + } + first(condition) { + return this.where(condition)[0]; + } + } + var store = new LayoutStore(); + + const SaveContextMethodName = "T42.HC.GetSaveContext"; + class ContextProvider { + constructor(config, activitiesGetter, callbacks, logger) { + this.config = config; + this.activitiesGetter = activitiesGetter; + this.callbacks = callbacks; + this.logger = logger; + this.interop = config.agm; + this.registerRequestMethods(); + } + onSaveRequested(callback) { + return this.callbacks.add("saveRequested", callback); + } + isActivityOwner() { + if (typeof htmlContainer !== "undefined") { + const context = htmlContainer.getContext(); + return context && context._t42 && context._t42.activityIsOwner; + } + const activities = this.activitiesGetter(); + if (!activities) { + return false; + } + if (!activities.inActivity) { + return false; + } + const myWindow = activities.my.window; + const myActivity = activities.my.activity; + if (!myActivity && !myWindow) { + return false; + } + return myActivity.owner.id === myWindow.id; + } + registerRequestMethods() { + this.interop.register(SaveContextMethodName, (args) => { + const usersCbs = this.callbacks.execute("saveRequested", args); + if ((usersCbs === null || usersCbs === void 0 ? void 0 : usersCbs.length) > 1) { + this.logger.warn(`Multiple subscriptions for "glue.layouts.onSaveRequested" - only the first one will be used`); + } + const requestResult = usersCbs[0]; + const autoSaveWindowContext = this.config.autoSaveWindowContext; + if (typeof autoSaveWindowContext === "boolean" && autoSaveWindowContext) { + return { autoSaveWindowContext }; + } + else if (Array.isArray(autoSaveWindowContext) && autoSaveWindowContext.length > 0) { + return { autoSaveWindowContext }; + } + const result = { windowContext: requestResult === null || requestResult === void 0 ? void 0 : requestResult.windowContext, activityContext: undefined }; + if (this.isActivityOwner()) { + result.activityContext = requestResult === null || requestResult === void 0 ? void 0 : requestResult.activityContext; + } + return result; + }); + } + } + + function transformACSLayout(something) { + if (!something) { + return something; + } + if (Array.isArray(something)) { + return something.map((item) => { + return transformACSLayout(item); + }); + } + if (typeof something === "string" || typeof something === "number" || typeof something === "boolean") { + return something; + } + const initial = {}; + return Object.keys(something).reduce((accumulator, current) => { + var _a; + const value = something[current]; + const convertedValue = transformACSLayout(value); + let key = current; + if (((_a = current[0]) === null || _a === void 0 ? void 0 : _a.toLowerCase()) !== current[0]) { + key = current[0].toLowerCase() + current.substr(1); + } + accumulator[key] = convertedValue; + return accumulator; + }, initial); + } + + class LayoutImpl { + constructor(data) { + this.name = data.name; + this.type = data.type; + this.components = data.components; + this.context = data.context; + this.metadata = data.metadata; + this.version = data.version; + this.displays = data.displays; + } + } + + var main = {}; + + var application = {}; + + /** + * This file was automatically generated by json-schema-to-typescript. + * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file, + * and run json-schema-to-typescript to regenerate this file. + */ + Object.defineProperty(application, "__esModule", { value: true }); + + var system = {}; + + /** + * This file was automatically generated by json-schema-to-typescript. + * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file, + * and run json-schema-to-typescript to regenerate this file. + */ + Object.defineProperty(system, "__esModule", { value: true }); + + var layout = {}; + + Object.defineProperty(layout, "__esModule", { value: true }); + layout.SwimlaneItemType = layout.LayoutType = void 0; + var LayoutType; + (function (LayoutType) { + LayoutType["Global"] = "Global"; + LayoutType["Activity"] = "Activity"; + LayoutType["ApplicationDefault"] = "ApplicationDefault"; + LayoutType["Swimlane"] = "Swimlane"; + LayoutType["Workspaces"] = "Workspace"; + })(LayoutType || (layout.LayoutType = LayoutType = {})); + var SwimlaneItemType; + (function (SwimlaneItemType) { + SwimlaneItemType["Tab"] = "tab"; + SwimlaneItemType["Window"] = "window"; + SwimlaneItemType["Canvas"] = "canvas"; + })(SwimlaneItemType || (layout.SwimlaneItemType = SwimlaneItemType = {})); + + var swTheme = {}; + + /** + * This file was automatically generated by json-schema-to-typescript. + * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file, + * and run json-schema-to-typescript to regenerate this file. + */ + Object.defineProperty(swTheme, "__esModule", { value: true }); + + var swConfiguration = {}; + + /** + * This file was automatically generated by json-schema-to-typescript. + * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file, + * and run json-schema-to-typescript to regenerate this file. + */ + Object.defineProperty(swConfiguration, "__esModule", { value: true }); + + (function (exports) { + var __createBinding = (commonjsGlobal && commonjsGlobal.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; + })); + var __exportStar = (commonjsGlobal && commonjsGlobal.__exportStar) || function(m, exports) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); + }; + Object.defineProperty(exports, "__esModule", { value: true }); + // export { SchemaValidator } from "./validator"; + // export { FileProvider } from "./fileProvider"; + // export { SchemaProvider } from "./provider"; + __exportStar(application, exports); + __exportStar(system, exports); + __exportStar(layout, exports); + __exportStar(swTheme, exports); + __exportStar(swConfiguration, exports); + + } (main)); + + const LayoutsCommandMethod = "T42.ACS.Command"; + class LayoutsAPIImpl { + constructor(config, stream, callbacks, logger) { + this.config = config; + this.stream = stream; + this.callbacks = callbacks; + this.isRegisterMethodForLayoutModified = false; + this.appManager = config.appManager; + this.provider = new ContextProvider(config, config.activityGetter, callbacks, logger); + stream.subscribe(); + } + async setDefaultGlobal(name) { + const methodName = "SelectDefaultLayout"; + await this.invokeMethodCore(methodName, { name }); + return; + } + async clearDefaultGlobal() { + const methodName = "DeselectDefaultLayout"; + await this.invokeMethodCore(methodName); + return; + } + async getDefaultGlobal() { + const methodName = "GetDefaultLayout"; + const result = await this.invokeMethodCore(methodName); + const layout = result.returned; + if (layout === null || layout === undefined || (typeof layout === 'object' && Object.keys(layout).length === 0)) { + return undefined; + } + return objectClone(this.isSlimMode() ? layout : this.list().find((l) => l.name === layout.name && l.type === layout.type)); + } + ready() { + if (this.config.mode === "fullWaitSnapshot") { + return this.stream.gotSnapshot; + } + return this.stream.ready; + } + save(layout) { + return new Promise((resolve, reject) => { + var _a, _b; + this.verifyNotSlimMode(); + if (isUndefinedOrNull(layout)) { + return reject(new Error("layout is required")); + } + if (isNullOrWhiteSpace(layout.name)) { + return reject(new Error("layout.name argument is required")); + } + if (isNullOrWhiteSpace(layout.type)) { + layout.type = "Global"; + } + if (!isNullOrWhiteSpace(layout.activityId)) { + layout.type = "Activity"; + } + const layoutObject = { + name: layout.name, + type: layout.type, + context: (_a = layout.context) !== null && _a !== void 0 ? _a : {}, + metadata: (_b = layout.metadata) !== null && _b !== void 0 ? _b : {}, + options: {}, + }; + if (layout.type === "Activity") { + let actId = layout.activityId; + if (!actId) { + if (!this.appManager.myInstance.inActivity) { + return reject(new Error("Current application is not in activity. Cannot save activity layout for it.")); + } + actId = this.appManager.myInstance.activityId; + } + layoutObject.activityId = actId; + } + else if (layout.type === "Global") { + if (Array.isArray(layout.ignoreInstances)) { + layoutObject.options.ignoreInstances = layout.ignoreInstances; + } + if (Array.isArray(layout.instances)) { + layoutObject.options.instances = layout.instances; + } + if (typeof layout.setAsCurrent === "boolean") { + layoutObject.options.setAsCurrent = layout.setAsCurrent; + } + } + else { + return reject(new Error(`layout type ${layout.type} is not supported`)); + } + this.invokeMethodAndTrack("SaveLayout", layoutObject, resolve, reject); + }); + } + restore(options) { + return new Promise((resolve, reject) => { + var _a, _b, _c; + this.verifyNotSlimMode(); + if (isUndefinedOrNull(options)) { + return reject(new Error("options argument is required")); + } + if (isNullOrWhiteSpace(options.name)) { + return reject(new Error("options.name argument is required")); + } + if (isNullOrWhiteSpace(options.type)) { + options.type = "Global"; + } + if (!isNullOrWhiteSpace(options.activityIdToJoin)) { + options.type = "Activity"; + } + if (options.type === "Activity") { + if (isUndefinedOrNull(options.setActivityContext)) { + options.setActivityContext = true; + } + if (typeof options.setActivityContext !== "boolean") { + return reject(new Error("`setActivityContext` must hold a boolean value.")); + } + options.activityIdToJoin = (_a = options.activityIdToJoin) !== null && _a !== void 0 ? _a : this.appManager.myInstance.activityId; + } + if (!isUndefinedOrNull(options.closeRunningInstance)) { + options.closeRunningInstances = options.closeRunningInstance; + } + if (isUndefinedOrNull(options.closeRunningInstances)) { + options.closeRunningInstances = true; + } + if (!isBoolean(options.closeRunningInstances)) { + return reject(new Error("`closeRunningInstances` must hold a boolean value.")); + } + if (isUndefinedOrNull(options.closeMe)) { + options.closeMe = options.closeRunningInstances; + } + if (!isBoolean(options.closeMe)) { + return reject(new Error("`closeMe` must hold a boolean value.")); + } + if (!isUndefinedOrNull(options.context) && !isObject(options.context)) { + return reject(new Error("`context` must hold an object value.")); + } + if (!isUndefinedOrNull(options.timeout) && typeof options.timeout !== "number") { + return reject(new Error("`timeout` must hold an number value.")); + } + options.context = (_b = options.context) !== null && _b !== void 0 ? _b : {}; + const restoreOptions = { + activityToJoin: options.activityIdToJoin, + setActivityContext: options.setActivityContext, + ignoreActivityWindowTypes: options.ignoreActivityWindowTypes, + reuseExistingWindows: options.reuseWindows, + closeRunningInstances: options.closeRunningInstances, + excludeFromClosing: options.closeMe ? [] : [(_c = this.appManager.myInstance) === null || _c === void 0 ? void 0 : _c.id] + }; + const arg = { + type: options.type, + name: options.name, + context: options.context, + options: restoreOptions + }; + if (options.timeout) { + arg.timeout = options.timeout; + } + this.invokeMethodAndTrack("RestoreLayout", arg, resolve, reject, true); + }); + } + reset(options) { + return new Promise((resolve, reject) => { + this.verifyNotSlimMode(); + if (typeof options !== "object") { + return reject(new Error("options argument is required")); + } + if (isNullOrWhiteSpace(options.layoutId)) { + return reject(new Error("options.layoutId argument is required")); + } + const msg = { + ...options + }; + this.invokeMethodAndTrack("ResetLayout", msg, resolve, reject, true); + }); + } + remove(type, name) { + return new Promise((resolve, reject) => { + this.verifyNotSlimMode(); + if (!name) { + return reject(new Error("name argument is required")); + } + if (!type) { + return reject(new Error("type argument is required")); + } + const msg = { + type, + name, + }; + this.invokeMethodAndTrack("RemoveLayout", msg, resolve, reject); + }); + } + list() { + this.verifyNotSlimMode(); + return objectClone(store.all); + } + import(layouts, mode) { + return new Promise((resolve, reject) => { + this.verifyNotSlimMode(); + if (!isUndefinedOrNull(mode)) { + if (mode !== "merge" && mode !== "replace") { + return reject(new Error(`${mode} is not supported - only "merge" and "replace"`)); + } + } + if (!Array.isArray(layouts)) { + return reject(new Error("layouts arguments is not an array")); + } + const msg = { + mode: mode || "replace", + layouts + }; + this.invokeMethodAndTrack("ImportLayouts", msg, resolve, reject, true); + }); + } + export(layoutType) { + return new Promise((resolve, reject) => { + var _a; + if (!isUndefinedOrNull(layoutType) && !((_a = Object.values(main.LayoutType)) === null || _a === void 0 ? void 0 : _a.includes(layoutType))) { + return reject(new Error(`${layoutType} is not a supported Layout Type`)); + } + const handleResult = (result) => { + let layouts = this.getObjectValues(result.Layouts).map((t) => new LayoutImpl(transformACSLayout(t))); + if (layoutType) { + layouts = layouts.filter((l) => l.type === layoutType); + } + resolve(layouts); + }; + this.invokeMethodAndTrack("ExportLayouts", {}, handleResult, reject, true); + }); + } + rename(layout, newName) { + return new Promise((resolve, reject) => { + this.verifyNotSlimMode(); + if (!layout) { + return reject(new Error("layout argument is required")); + } + if (!layout.name) { + return reject(new Error("name argument is required")); + } + if (!layout.type) { + return reject(new Error("type argument is required")); + } + const msg = { type: layout.type, oldName: layout.name, newName }; + this.invokeMethodAndTrack("RenameLayout", msg, resolve, reject); + }); + } + updateMetadata(layout) { + return new Promise((resolve, reject) => { + if (!layout) { + return reject(new Error("layout argument is required")); + } + if (!layout.name) { + return reject(new Error("name argument is required")); + } + if (!layout.type) { + return reject(new Error("type argument is required")); + } + if (!layout.metadata) { + return reject(new Error("metadata argument is required")); + } + const layoutObject = { + name: layout.name, + type: layout.type, + metadata: layout.metadata + }; + this.invokeMethodAndTrack("UpdateMetadata", layoutObject, resolve, reject, true); + }); + } + hibernate(name, options) { + return new Promise((resolve, reject) => { + if (!name) { + return reject(new Error("name cannot be empty")); + } + options = options || {}; + const request = { + name, + type: "Global", + context: options.context || {}, + metadata: options.metadata || {}, + }; + this.invokeMethodAndTrack("HibernateLayout", request, resolve, reject, true); + }); + } + resume(name, context, options) { + return new Promise((resolve, reject) => { + if (!name) { + return reject(new Error("name cannot be empty")); + } + const request = { + name, + type: "Global", + context, + ...options + }; + this.invokeMethodAndTrack("ResumeLayout", request, resolve, reject, true); + }); + } + async getCurrentLayout() { + const methodName = "GetCurrentLayout"; + const result = await this.invokeMethodCore(methodName); + let layout = result.returned.layout; + if (!layout) { + return undefined; + } + if (!this.isSlimMode()) { + layout = this.list().find((l) => l.name === layout.name && l.type === layout.type); + } + return objectClone(layout); + } + getRestoredLayoutsInfo() { + return new Promise((resolve, reject) => { + const methodName = "GetRestoredLayoutsInfo"; + this.invokeMethodCore(methodName) + .then((result) => { + const restoredLayouts = result.returned; + resolve(restoredLayouts); + }) + .catch(reject); + }); + } + onAdded(callback) { + const result = this.callbacks.add("added", callback); + if (store.all.length > 0) { + store.all.forEach((layout) => { + try { + callback(layout); + } + catch (err) { } + }); + } + return result; + } + onRemoved(callback) { + return this.callbacks.add("removed", callback); + } + onChanged(callback) { + return this.callbacks.add("changed", callback); + } + onRestored(callback) { + return this.callbacks.add("restored", callback); + } + onRenamed(callback) { + return this.callbacks.add("renamed", callback); + } + onEvent(callback) { + return this.stream.onEvent(callback); + } + onSaveRequested(callback) { + return this.provider.onSaveRequested(callback); + } + onLayoutModified(callback) { + if (this.isRegisterMethodForLayoutModified === false) { + this.isRegisterMethodForLayoutModified = true; + this.registerMethodForLayoutModified(); + } + return this.callbacks.add("layout-modified", callback); + } + updateAppContextInCurrent(context) { + return new Promise((resolve, reject) => { + if (context && typeof context !== "object") { + return reject(new Error("Context must be an object")); + } + context = context !== null && context !== void 0 ? context : {}; + const request = { + context + }; + this.invokeMethodAndTrack("UpdateLayoutComponentContext", request, resolve, reject, true); + }); + } + updateDefaultContext(context) { + return new Promise((resolve, reject) => { + if (context && typeof context !== "object") { + return reject(new Error("Context must be an object")); + } + context = context !== null && context !== void 0 ? context : {}; + const request = { + context + }; + this.invokeMethodAndTrack("UpdateDefaultContext", request, resolve, reject, true); + }); + } + async get(name, type) { + const matching = this.list().find((l) => l.name === name && l.type === type); + if (!matching) { + throw new Error(`cannot find layout with name=${name} and type=${type}`); + } + return objectClone(matching); + } + async getAll(type) { + var _a; + if (!isUndefinedOrNull(type) && !((_a = Object.values(main.LayoutType)) === null || _a === void 0 ? void 0 : _a.includes(type))) { + throw new Error((`${type} is not a supported Layout Type`)); + } + const matching = this.list().filter((l) => type === l.type); + return objectClone(matching); + } + async forceRefresh() { + const methodName = "RefreshLayouts"; + await this.invokeMethodCore(methodName); + } + isSlimMode() { + return this.config.mode === "slim"; + } + verifyNotSlimMode() { + if (this.isSlimMode()) { + throw Error("Operation not allowed in slim mode. Run in full mode."); + } + } + async registerMethodForLayoutModified() { + await this.config.agm.register("T42.ACS.LayoutModified", (args, caller) => { + this.callbacks.execute("layout-modified", args); + }); + } + invokeMethodAndTrack(methodName, args, resolve, reject, skipStreamEvent) { + let streamEventReceived = skipStreamEvent; + let agmResult; + const token = Utils.generateId(); + args.token = token; + const handleResult = () => { + if (streamEventReceived && agmResult) { + resolve(agmResult); + } + }; + const methodResponseTimeoutMs = 120 * 1000; + if (!skipStreamEvent) { + this.stream.waitFor(token, methodResponseTimeoutMs) + .then(() => { + streamEventReceived = true; + handleResult(); + }) + .catch((err) => { + reject(err); + }); + } + const responseHandler = (result) => { + if (!result.returned) { + return reject(new Error("No result from method " + methodName)); + } + if (result.returned.status && (result.returned.status !== "Success" && result.returned.status !== "PartialSuccess")) { + if (typeof (result.returned) === "string") { + return reject(new Error(result.returned)); + } + else if (typeof (result.returned) === "object") { + if (result.returned.status && result.returned.failed) { + return reject(new Error(`${result.returned.status}: ${JSON.stringify(result.returned.failed)}`)); + } + else { + return reject(new Error(result.returned)); + } + } + } + agmResult = result.returned; + handleResult(); + }; + this.invokeMethodCore(methodName, args, "best", { methodResponseTimeoutMs }) + .then(responseHandler) + .catch((err) => reject(err)); + } + async invokeMethodCore(methodName, args, target, options) { + options = options !== null && options !== void 0 ? options : {}; + if (typeof options.methodResponseTimeoutMs === "undefined") { + options.methodResponseTimeoutMs = INTEROP_METHOD_WAIT_TIMEOUT_MS; + } + if (typeof options.waitTimeoutMs === "undefined") { + options.waitTimeoutMs = INTEROP_METHOD_WAIT_TIMEOUT_MS; + } + if (this.isCommandMethodPresent()) { + return await this.config.agm.invoke(LayoutsCommandMethod, { command: methodName, data: args }, target, options); + } + else { + return await this.config.agm.invoke(`T42.ACS.${methodName}`, args, target, options); + } + } + getObjectValues(obj) { + if (!obj) { + return []; + } + return Object.keys(obj).map((k) => obj[k]); + } + isCommandMethodPresent() { + return this.config.agm.methods().some((method) => method.name === LayoutsCommandMethod); + } + } + + class ACSStream { + constructor(agm, callbacks) { + this.agm = agm; + this.callbacks = callbacks; + this.StreamName = "T42.ACS.OnLayoutEvent"; + this.ready = new Promise((resolve, reject) => { + this.resolveReady = resolve; + this.rejectReady = reject; + }); + this.gotSnapshot = new Promise((resolve, reject) => { + this.resolveGotSnapshot = resolve; + this.rejectGotSnapshot = reject; + }); + } + subscribe(noRetry) { + const transform = (obj) => { + return this.getObjectValues(obj).map((t) => transformACSLayout(t)); + }; + if (!this.checkForLayoutEventMethod()) { + if (noRetry) { + this.resolveReady(); + } + setTimeout(() => { + this.subscribe(true); + }, 500); + } + else { + this.agm.subscribe(this.StreamName, { waitTimeoutMs: 10000 }) + .then((subs) => { + subs.onData((args) => { + const data = args.data; + if (data.IsSnapshot) { + this.resolveGotSnapshot(); + } + this.addLayouts(transform(data.OnLayoutAdded), data.IsSnapshot); + this.removeLayouts(transform(data.OnLayoutRemoved)); + this.changeLayouts(transform(data.OnLayoutChanged)); + this.renameLayouts(transform(data.OnLayoutRenamed)); + this.restoredLayout(transform(data.OnLayoutRestored)); + this.callbacks.execute("streamEvent", data); + }); + subs.onFailed((err) => { + const msg = `Can not subscribe to "${this.StreamName}" stream - ${JSON.stringify(err)}`; + this.rejectReady(msg); + this.rejectGotSnapshot(msg); + }); + this.resolveReady(); + }) + .catch((err) => { + const msg = `Error subscribing to "${this.StreamName}" stream - ${JSON.stringify(err)}`; + this.rejectReady(msg); + this.rejectGotSnapshot(msg); + }); + } + } + onEvent(callback) { + return this.callbacks.add("streamEvent", callback); + } + waitFor(token, timeout) { + if (!timeout) { + timeout = 30000; + } + return new Promise((resolve, reject) => { + let done = false; + const unsubscribe = this.onEvent((streamEvent) => { + if (streamEvent.Token === token) { + done = true; + unsubscribe(); + resolve(); + } + }); + setTimeout(() => { + if (!done) { + reject("timed out"); + } + }, timeout); + }); + } + checkForLayoutEventMethod() { + try { + return this.agm + .methods() + .map((m) => m.name) + .indexOf(this.StreamName) !== -1; + } + catch (e) { + return false; + } + } + addLayouts(layoutsData, isSnapshot) { + if (!layoutsData) { + return; + } + const createAndNotifyLayout = (layoutData) => { + const layout = new LayoutImpl(layoutData); + store.add(layout); + this.callbacks.execute("added", layout); + }; + layoutsData.forEach((layoutData) => { + if (isSnapshot) { + const found = store.first((existingLayout) => this.compareLayouts(existingLayout, layoutData)); + if (!found) { + createAndNotifyLayout(layoutData); + } + } + else { + createAndNotifyLayout(layoutData); + } + }); + } + removeLayouts(removedLayouts) { + if (!removedLayouts) { + return; + } + removedLayouts.forEach((removedLayout) => { + store.removeWhere((existingLayout) => !this.compareLayouts(existingLayout, removedLayout)); + this.callbacks.execute("removed", removedLayout); + }); + } + changeLayouts(changedLayouts) { + if (!changedLayouts) { + return; + } + changedLayouts.forEach((changedLayout) => { + store.removeWhere((existingLayout) => !this.compareLayouts(existingLayout, changedLayout)); + store.add(new LayoutImpl(changedLayout)); + this.callbacks.execute("changed", changedLayout); + }); + } + renameLayouts(renamedLayouts) { + if (!renamedLayouts) { + return; + } + renamedLayouts.forEach((renamedLayout) => { + const existingLayout = store.first((current) => this.compareLayouts(current, { type: renamedLayout.type, name: renamedLayout.oldName })); + if (!existingLayout) { + throw Error(`received rename event for unknown layout with type ${renamedLayout.type} and name ${renamedLayout.oldName}`); + } + existingLayout.name = renamedLayout.newName; + this.callbacks.execute("renamed", existingLayout); + }); + } + compareLayouts(layout1, layout2) { + return layout1.name === layout2.name && layout1.type === layout2.type; + } + getObjectValues(obj) { + if (!obj) { + return []; + } + return Object.keys(obj).map((k) => obj[k]); + } + restoredLayout(restoredLayouts) { + if (!restoredLayouts) { + return; + } + restoredLayouts.forEach((restoredLayout) => { + const existingLayout = store.first((current) => this.compareLayouts(current, { type: restoredLayout.type, name: restoredLayout.name })); + this.callbacks.execute("restored", existingLayout); + }); + } + } + + function LayoutsFactory (config) { + if (!config.agm) { + throw Error("config.agm is required"); + } + if (!config.logger) { + throw Error("config.logger is required"); + } + config.mode = config.mode || "slim"; + const logger = config.logger; + const callbacks = CallbackRegistryFactory(); + let acsStream; + if (config.mode === "full" || "fullWaitSnapshot") { + acsStream = new ACSStream(config.agm, callbacks); + } + return new LayoutsAPIImpl(config, acsStream, callbacks, logger); + } + + const T42DisplayCommand = "T42.Displays.Command"; + const T42DisplayOnEvent = "T42.Displays.OnEvent"; + class DisplayManager { + constructor(_agm, _logger) { + this._agm = _agm; + this._logger = _logger; + this._registry = CallbackRegistryFactory(); + this._registered = false; + this.all = async () => { + const displays = await this.callGD(DisplayCommand.GetAll, {}); + return displays.map(this.decorateDisplay); + }; + this.get = async (id) => { + const display = await this.callGD(DisplayCommand.Get, { id }); + return this.decorateDisplay(display); + }; + this.getPrimary = async () => { + const primary = (await this.all()).find((d) => d.isPrimary); + return primary; + }; + this.capture = async (options) => { + const screenshot = await this.callGD(DisplayCommand.Capture, { ...options }); + return screenshot; + }; + this.captureAll = async (options) => { + const screenshots = await this.callGD(DisplayCommand.CaptureAll, { ...options }); + return screenshots; + }; + this.getMousePosition = async () => { + const point = await this.callGD(DisplayCommand.GetMousePosition); + return point; + }; + this.callGD = async (command, options) => { + const invocationResult = await this._agm.invoke(T42DisplayCommand, { options: { ...options }, command }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return invocationResult.returned.data; + }; + this.decorateDisplay = (original) => { + const decoratedDisplay = { + ...original, + capture: (size) => this.capture({ id: original.id, size }) + }; + const workAreaAsAny = decoratedDisplay.workArea; + workAreaAsAny.x = workAreaAsAny.left; + workAreaAsAny.y = decoratedDisplay.workArea.top; + return decoratedDisplay; + }; + } + getByWindowId(id) { + const current = this.callGD(DisplayCommand.GetByWindowId, { id }); + return current; + } + onDisplayChanged(cb) { + this.register(); + return this._registry.add("on-display-changed", cb); + } + register() { + if (this._registered) { + return; + } + this._registered = true; + this._agm.register(T42DisplayOnEvent, (args, caller) => { + const event = args.event; + const data = args.data; + switch (event) { + case "display-changed": + this._registry.execute("on-display-changed", data.displays.map(this.decorateDisplay)); + break; + default: + this._logger.warn(`unknown event - ${event}`); + break; + } + }); + } + } + var DisplayCommand; + (function (DisplayCommand) { + DisplayCommand["Capture"] = "capture"; + DisplayCommand["CaptureAll"] = "captureAll"; + DisplayCommand["GetAll"] = "getAll"; + DisplayCommand["Get"] = "get"; + DisplayCommand["GetByWindowId"] = "getByWindowId"; + DisplayCommand["GetMousePosition"] = "getMousePosition"; + })(DisplayCommand || (DisplayCommand = {})); + + class SingleChannelID { + constructor(channel) { + this.channel = channel; + } + get isJoinedToAnyChannel() { + return !!this.channel; + } + isOnChannel(channel) { + return this.channel === channel; + } + leaveChannel(channel) { + if (channel === undefined || this.channel === channel) { + this.channel = undefined; + } + } + joinChannel(channel) { + this.channel = channel; + } + all() { + if (this.channel) { + return [this.channel]; + } + return []; + } + toString() { + return this.channel; + } + equals(other) { + if (other instanceof SingleChannelID) { + return this.channel === other.channel; + } + return false; + } + } + class MultiChannelId { + constructor(channels) { + this.ChannelDelimiter = "+++"; + if (!channels) { + this.channels = []; + } + else if (typeof channels === "string") { + this.channels = channels === null || channels === void 0 ? void 0 : channels.split(this.ChannelDelimiter).filter(Boolean); + } + else { + this.channels = (channels !== null && channels !== void 0 ? channels : []).filter(Boolean); + } + } + get isJoinedToAnyChannel() { + return this.channels.length > 0; + } + isOnChannel(channel) { + return this.channels.includes(channel); + } + joinChannel(channel) { + const newChannels = new MultiChannelId(channel); + newChannels.all().forEach((newChannel) => { + if (!this.channels.includes(newChannel)) { + this.channels.push(newChannel); + } + }); + } + leaveChannel(channel) { + const channelsToLeave = new MultiChannelId(channel !== null && channel !== void 0 ? channel : this.channels); + channelsToLeave.all().forEach((c) => { + this.channels = this.channels.filter((ch) => ch !== c); + }); + } + all() { + return this.channels; + } + toString() { + if (this.channels.length === 0) { + return undefined; + } + return this.channels.join(this.ChannelDelimiter); + } + equals(other) { + if (other instanceof MultiChannelId) { + return this.channels.length === other.channels.length && + this.channels.every((c, i) => c === other.channels[i]); + } + return false; + } + } + + let interop; + let myInstanceId; + let logger; + const T42_ANNOUNCE_METHOD_NAME = "T42.Channels.Announce"; + const T42_COMMAND_METHOD_NAME = "T42.Channels.Command"; + async function setupInterop(interopLib, channels, loggerAPI) { + var _a, _b; + logger = loggerAPI; + interop = interopLib; + if (typeof window !== "undefined") { + if (window.glue42gd) { + myInstanceId = window.glue42gd.windowId; + } + } + if (!myInstanceId) { + myInstanceId = interopLib.instance.instance; + } + await interop.register(T42_COMMAND_METHOD_NAME, (args) => { + const command = args.command; + if (!command) { + throw new Error("missing command argument"); + } + logger.trace(`received command "${command}" with ${JSON.stringify(args)}`); + if (command === "join") { + const id = args.channel; + if (!id) { + throw new Error("missing argument id"); + } + return channels.joinNoSelectorSwitch(id); + } + if (command === "leave") { + return channels.leaveNoSelectorSwitch(); + } + if (command === "get") { + const id = channels.current(); + return { id }; + } + if (command === "restrictions-changed") { + const restrictions = args.restrictions; + const targetWindowId = args.swId; + channels.handleRestrictionsChanged(restrictions, targetWindowId); + return; + } + if (command === "isFdc3DataWrappingSupported") { + return { isSupported: true }; + } + if (command === "join-multi") { + const channelsToJoin = args.channelsToJoin; + if (!channelsToJoin) { + throw new Error("missing argument channelsToJoin"); + } + return channels.joinNoSelectorSwitch(new MultiChannelId(channelsToJoin).toString()); + } + if (command === "leave-multi") { + const channelsToLeave = args.channelsToLeave; + return channels.leaveNoSelectorSwitch(new MultiChannelId(channelsToLeave).toString()); + } + throw new Error(`unknown command ${command}`); + }); + const result = await interop.invoke(T42_ANNOUNCE_METHOD_NAME, { swId: myInstanceId, instance: interop.instance.instance }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_RESPONSE_TIMEOUT_MS + }); + if ((_a = result.returned) === null || _a === void 0 ? void 0 : _a.restrictions) { + channels.handleRestrictionsChanged((_b = result.returned) === null || _b === void 0 ? void 0 : _b.restrictions, myInstanceId); + } + return result.returned; + } + async function sendLeaveChannel(channel, winId) { + var _a; + await invoke("leaveChannel", { channel }, (_a = winId !== null && winId !== void 0 ? winId : winId) !== null && _a !== void 0 ? _a : myInstanceId); + } + async function sendSwitchChannelUI(channel, winId) { + await invoke("switchChannel", { newChannel: channel }, winId !== null && winId !== void 0 ? winId : myInstanceId); + } + async function setRestrictions(restrictions) { + var _a; + await invoke("restrict", restrictions, (_a = restrictions.windowId) !== null && _a !== void 0 ? _a : myInstanceId); + } + async function getRestrictionsByWindow(id) { + try { + const result = await invoke("getRestrictions", {}, id !== null && id !== void 0 ? id : myInstanceId); + return result.returned; + } + catch (e) { + } + } + async function setRestrictionsForAllChannels(restrictions) { + var _a; + await invoke("restrictAll", restrictions, (_a = restrictions.windowId) !== null && _a !== void 0 ? _a : myInstanceId); + } + async function getChannelsInfo(filter) { + const result = await invoke("getChannelsInfo", { filter }); + return result.returned; + } + async function addOrRemoveChannel(command, id, color, label) { + await invoke(command, { id, color, label }); + } + async function getChannelInitInfo(config, i) { + if (typeof config.operationMode !== "boolean" && typeof config.operationMode === "string") { + validateMode(config.operationMode); + return { mode: config.operationMode, initialChannel: undefined }; + } + try { + const result = await i.invoke(T42_ANNOUNCE_METHOD_NAME, { command: "getChannelsMode" }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_RESPONSE_TIMEOUT_MS, + }); + const initialChannel = result.returned.initialChannel; + if (result.returned.mode === "single") { + return { + mode: "single", + initialChannel + }; + } + else if (result.returned.mode === "multi") { + return { + mode: "multi", + initialChannel + }; + } + else { + return { + mode: "single", + initialChannel + }; + } + } + catch (e) { + return { mode: "single", initialChannel: undefined }; + } + } + function invoke(command, data, swId) { + const args = { command, data }; + if (swId) { + args.swId = swId; + } + return interop.invoke(T42_ANNOUNCE_METHOD_NAME, args, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_RESPONSE_TIMEOUT_MS, + }); + } + function validateMode(mode) { + if (mode !== "single" && mode !== "multi") { + throw new Error(`Invalid mode: ${mode}`); + } + } + + const CONTEXT_PREFIX = "___channel___"; + const LATEST_FDC3_TYPE = "latest_fdc3_type"; + class BaseSharedContextSubscriber { + constructor(contexts) { + this.contexts = contexts; + } + subscribe(callback) { + this.callback = callback; + } + subscribeFor(name, callback) { + if (!this.isChannel(name)) { + return Promise.reject(new Error(`Channel with name: ${name} doesn't exist!`)); + } + const contextName = this.createContextName(name); + return this.contexts.subscribe(contextName, (data, _, __, ___, extraData) => { + callback(data.data, data, extraData === null || extraData === void 0 ? void 0 : extraData.updaterId); + }); + } + all() { + const contextNames = this.contexts.all(); + const channelContextNames = contextNames.filter((contextName) => contextName.startsWith(CONTEXT_PREFIX)); + const channelNames = channelContextNames.map((channelContextName) => channelContextName.substr(CONTEXT_PREFIX.length)); + return channelNames; + } + async getContextData(name) { + if (!this.isChannel(name)) { + throw new Error(`A channel with name: ${name} doesn't exist!`); + } + const contextName = this.createContextName(name); + const contextData = await this.contexts.get(contextName); + if (contextData[LATEST_FDC3_TYPE]) { + return this.getContextWithFdc3Data(contextData); + } + else { + delete contextData[LATEST_FDC3_TYPE]; + } + return contextData; + } + updateChannel(name, data) { + const contextName = this.createContextName(name); + return this.contexts.update(contextName, data); + } + updateData(name, data) { + const contextName = this.createContextName(name); + const fdc3Type = this.getFDC3Type(data); + if (this.contexts.setPathSupported) { + const pathValues = Object.keys(data).map((key) => { + return { + path: `data.` + key, + value: data[key] + }; + }); + if (fdc3Type) { + pathValues.push({ path: LATEST_FDC3_TYPE, value: fdc3Type }); + } + return this.contexts.setPaths(contextName, pathValues); + } + else { + if (fdc3Type) { + data[LATEST_FDC3_TYPE] = fdc3Type; + } + return this.contexts.update(contextName, { data }); + } + } + setPaths(name, paths) { + const contextName = this.createContextName(name); + if (this.contexts.setPathSupported) { + const pathValues = paths.map((p) => { + return { + path: `data.` + p.path, + value: p.value + }; + }); + pathValues.map((p) => { + const fdc3Type = this.getFDC3Type(p.value); + if (fdc3Type) { + pathValues.push({ path: LATEST_FDC3_TYPE, value: fdc3Type }); + } + }); + return this.contexts.setPaths(contextName, pathValues); + } + else { + throw new Error("setPaths is not supported!"); + } + } + clearContextData(name) { + const contextName = this.createContextName(name); + return this.contexts.update(contextName, { data: {}, [LATEST_FDC3_TYPE]: undefined }); + } + isChannel(name) { + return this.all().some((channelName) => channelName === name); + } + async remove(name) { + if (!this.isChannel(name)) { + throw new Error(`A channel with name: ${name} doesn't exist!`); + } + const contextName = this.createContextName(name); + await this.contexts.destroy(contextName); + } + createContextName(name) { + return CONTEXT_PREFIX + name; + } + getFDC3Type(data) { + const fdc3PropsArr = Object.keys(data).filter((key) => key.indexOf("fdc3_") === 0); + if (fdc3PropsArr.length === 0) { + return; + } + if (fdc3PropsArr.length > 1) { + throw new Error("FDC3 does not support updating of multiple context keys"); + } + return fdc3PropsArr[0].split("_").slice(1).join("_"); + } + getContextWithFdc3Data(channelContext) { + const { latest_fdc3_type, ...rest } = channelContext; + const parsedType = latest_fdc3_type.split("&").join("."); + const fdc3Context = { type: parsedType, ...rest.data[`fdc3_${latest_fdc3_type}`] }; + delete rest.data[`fdc3_${latest_fdc3_type}`]; + const context = { + name: channelContext.name, + meta: channelContext.meta, + data: { + ...rest.data, + fdc3: fdc3Context + } + }; + return context; + } + } + class MultiSharedContextSubscriber extends BaseSharedContextSubscriber { + constructor() { + super(...arguments); + this.currentlySubscribedChannels = []; + this.unsubscribeMap = {}; + } + async switchChannel(id) { + const newChannels = new MultiChannelId(id).all(); + for (const newChannel of newChannels) { + if (!this.currentlySubscribedChannels.includes(newChannel)) { + await this.subscribeToChannel(newChannel); + } + } + } + async leave(id) { + const channelsToLeave = new MultiChannelId(id).all(); + for (const newChannel of channelsToLeave) { + if (this.currentlySubscribedChannels.includes(newChannel)) { + this.unsubscribeFromChannel(newChannel); + } + } + } + async updateData(id, data) { + const channels = new MultiChannelId(id).all(); + for (const channel of channels) { + await super.updateData(channel, data); + } + } + async setPaths(id, paths) { + const channels = new MultiChannelId(id).all(); + for (const channel of channels) { + await super.setPaths(channel, paths); + } + } + isChannel(name) { + const channels = new MultiChannelId(name).all(); + return channels.every((channel) => super.isChannel(channel)); + } + async subscribeToChannel(name) { + const contextName = this.createContextName(name); + const usub = await this.contexts.subscribe(contextName, (data, _, __, ___, extraData) => { + if (this.callback) { + this.callback(data.data, data, extraData === null || extraData === void 0 ? void 0 : extraData.updaterId); + } + }); + this.currentlySubscribedChannels.push(name); + this.unsubscribeMap[contextName] = usub; + } + async unsubscribeFromChannel(name) { + const contextName = this.createContextName(name); + const unsub = this.unsubscribeMap[contextName]; + if (unsub) { + unsub(); + delete this.unsubscribeMap[contextName]; + } + this.currentlySubscribedChannels = this.currentlySubscribedChannels.filter((channel) => channel !== name); + } + } + class SharedContextSubscriber extends BaseSharedContextSubscriber { + async switchChannel(name) { + this.unsubscribe(); + const contextName = this.createContextName(name); + this.unsubscribeFunc = await this.contexts.subscribe(contextName, (data, _, __, ___, extraData) => { + if (this.callback) { + this.callback(data.data, data, extraData === null || extraData === void 0 ? void 0 : extraData.updaterId); + } + }); + } + async leave() { + if (this.callback) { + this.callback({}, undefined); + } + this.unsubscribe(); + } + unsubscribe() { + if (this.unsubscribeFunc) { + this.unsubscribeFunc(); + this.unsubscribeFunc = undefined; + } + } + } + + const validateFdc3Options = (options) => { + if (typeof options !== "object" || Array.isArray(options)) { + throw new Error(`Provide options as an object`); + } + if (options.contextType && (typeof options.contextType !== "string" || !options.contextType.length)) { + throw new Error(`Provide options.contextType as a non-empty string`); + } + }; + + class ChannelsImpl { + constructor(interop, getWindowsAPI, getAppManagerAPI, logger) { + this.interop = interop; + this.getWindowsAPI = getWindowsAPI; + this.getAppManagerAPI = getAppManagerAPI; + this.logger = logger; + this.subsKey = "subs"; + this.changedKey = "changed"; + this.channelsChangedKey = "channelsChanged"; + this.isInitialJoin = true; + this.registry = CallbackRegistryFactory(); + this.pendingReplays = {}; + this.pendingRestrictionCallbacks = new Map(); + } + async getMyChannels(options) { + if (!this.currentChannelID) { + return Promise.resolve([]); + } + if (this.currentChannelID.all().length === 0) { + return Promise.resolve([]); + } + const result = []; + for (const channel of this.currentChannelID.all()) { + result.push(await this.get(channel, options)); + } + return result; + } + async init(shared, mode, initial) { + this.mode = mode; + this.shared = shared; + this.shared.subscribe(this.handler.bind(this)); + this.subscribeForChannelRestrictionsChange(); + let initialChannel = initial; + if (typeof window !== "undefined" && typeof window.glue42gd !== "undefined") { + initialChannel = window.glue42gd.initialChannel; + } + this.currentChannelID = this.getID(initialChannel); + this.logger.trace(`initialized with mode: "${mode}" and initial channel: "${initialChannel}"`); + if (this.currentChannelID.isJoinedToAnyChannel) { + this.logger.trace(`joining initial channel: "${this.currentChannelID.toString()}"`); + await this.joinNoSelectorSwitch(this.currentChannelID.toString()); + } + } + subscribe(callback, options) { + if (typeof callback !== "function") { + throw new Error("Please provide the callback as a function!"); + } + const id = Utils.generateId(); + this.pendingReplays[id] = true; + const wrappedCallback = (options === null || options === void 0 ? void 0 : options.contextType) + ? this.getWrappedSubscribeCallbackWithFdc3Type(callback, id, options.contextType) + : this.getWrappedSubscribeCallback(callback, id); + if (this.lastUpdate) { + let lastUpdate = Object.assign({}, this.lastUpdate); + setTimeout(async () => { + if (this.pendingReplays[id]) { + if (this.lastUpdate) { + lastUpdate = this.lastUpdate; + } + wrappedCallback(lastUpdate.context.data, lastUpdate.context, lastUpdate.updaterId); + } + delete this.pendingReplays[id]; + }, 0); + } + const unsub = this.registry.add(this.subsKey, wrappedCallback); + return () => { + this.pendingReplays[id] = false; + this.pendingRestrictionCallbacks.delete(id); + unsub(); + }; + } + async subscribeFor(name, callback, options) { + if (typeof name !== "string") { + throw new Error("Please provide the name as a string!"); + } + if (typeof callback !== "function") { + throw new Error("Please provide the callback as a function!"); + } + const id = Utils.generateId(); + const wrappedCallback = (options === null || options === void 0 ? void 0 : options.contextType) + ? this.getWrappedSubscribeCallbackWithFdc3Type(callback, id, options.contextType) + : this.getWrappedSubscribeCallback(callback, id); + const unsub = await this.shared.subscribeFor(name, wrappedCallback); + return () => { + this.pendingRestrictionCallbacks.delete(id); + unsub(); + }; + } + async publish(data, options) { + if (typeof data !== "object") { + throw new Error("Please provide the data as an object!"); + } + if (options) { + this.validatePublishOptions(options); + } + if (typeof options === "object") { + return this.publishWithOptions(data, options); + } + const channelName = typeof options === "string" ? options : this.currentChannelID.toString(); + if (!channelName) { + throw new Error("Not joined to any channel!"); + } + if (!this.shared.isChannel(channelName)) { + return Promise.reject(new Error(`A channel with name: ${channelName} doesn't exist!`)); + } + if (this.mode === "multi") { + const channelsToPublish = new MultiChannelId(channelName).all(); + const restrictedChannels = []; + for (const cn of channelsToPublish) { + const canPublish = (await this.getRestrictionsByChannel(cn)).write; + if (!canPublish) { + restrictedChannels.push(cn); + continue; + } + await this.shared.updateData(cn, data); + } + if (restrictedChannels.length > 0) { + const restrictedChannelsErr = `Unable to publish due to restrictions to the following channels: ${restrictedChannels.join(", ")}`; + if (restrictedChannels.length === channelsToPublish.length) { + throw new Error(restrictedChannelsErr); + } + else { + this.logger.warn(restrictedChannelsErr); + } + } + } + else { + const canPublish = (await this.getRestrictionsByChannel(channelName)).write; + if (!canPublish) { + throw new Error(`Window does not have permission to write to channel ${channelName}`); + } + return this.shared.updateData(channelName, data); + } + } + async setPaths(paths, name) { + if (name) { + if (typeof name !== "string") { + throw new Error("Please provide the name as a string!"); + } + if (!this.shared.isChannel(name)) { + return Promise.reject(new Error(`A channel with name: ${name} doesn't exist!`)); + } + if (!(await this.getRestrictionsByChannel(name)).write) { + throw new Error(`Window does not have permission to write to channel ${name}`); + } + return this.shared.setPaths(name, paths); + } + if (!this.currentChannelID) { + throw new Error("Not joined to any channel!"); + } + if (!(await this.getRestrictionsByChannel(this.currentChannelID.toString())).write) { + throw new Error(`Window does not have permission to write to channel ${this.currentChannelID.toString()}`); + } + if (!Array.isArray(paths)) { + throw new Error("Path Values argument is not a valid array"); + } + paths.forEach((path) => { + this.validatePathArgs(path); + }); + return this.shared.setPaths(this.currentChannelID.toString(), paths); + } + async setPath(path, name) { + if (name) { + if (typeof name !== "string") { + throw new Error("Please provide the name as a string!"); + } + if (!this.shared.isChannel(name)) { + return Promise.reject(new Error(`A channel with name: ${name} doesn't exist!`)); + } + if (!(await this.getRestrictionsByChannel(name)).write) { + throw new Error(`Window does not have permission to write to channel ${name}`); + } + return this.shared.setPaths(name, [path]); + } + if (!this.currentChannelID) { + throw new Error("Not joined to any channel!"); + } + if (!(await this.getRestrictionsByChannel(this.currentChannelID.toString())).write) { + throw new Error(`Window does not have permission to write to channel ${this.currentChannelID.toString()}`); + } + this.validatePathArgs(path); + return this.shared.setPaths(this.currentChannelID.toString(), [path]); + } + all() { + const channelNames = this.shared.all(); + return Promise.resolve(channelNames); + } + async list() { + const channelNames = await this.all(); + const channelContexts = await Promise.all(channelNames.map((channelName) => this.get(channelName))); + return channelContexts; + } + async get(name, options) { + if (typeof name !== "string") { + return Promise.reject(new Error("Please provide the channel name as a string!")); + } + if (!(options === null || options === void 0 ? void 0 : options.contextType)) { + return this.shared.getContextData(name); + } + validateFdc3Options(options); + const context = await this.shared.getContextData(name); + return this.getContextWithFdc3Type(context, options.contextType); + } + getMy(options) { + if (!this.currentChannelID) { + return Promise.resolve(undefined); + } + if (this.currentChannelID.all().length === 0) { + return Promise.resolve(undefined); + } + return this.get(this.currentChannelID.all()[0], options); + } + async join(name, windowId) { + if (windowId !== undefined && windowId !== null) { + this.validateWindowIdArg(windowId); + this.logger.trace(`joining channel ${name} for window: ${windowId}`); + return sendSwitchChannelUI(name, windowId); + } + return this.joinCore(name); + } + async joinNoSelectorSwitch(channelName) { + this.logger.trace(`joining channel "${channelName}" from command`); + return this.joinCore(channelName, false); + } + leave(options) { + this.logger.trace(`leaving channel with options: ${JSON.stringify(options)}`); + let windowId; + let channelName; + if (typeof options === "string") { + windowId = options; + } + else if (typeof options === "object" && !Array.isArray(options) && options !== null && options !== undefined) { + if (options.windowId) { + windowId = options.windowId; + } + if (options.channel) { + channelName = options.channel; + } + } + if (this.mode === "multi") { + return this.leaveWhenMulti(channelName, windowId); + } + else { + return this.leaveWhenSingle(channelName, windowId); + } + } + leaveNoSelectorSwitch(channelName) { + this.logger.trace(`leaving channel "${channelName}" from command`); + return this.leaveCore(false, channelName); + } + current() { + return this.currentChannelID.toString(); + } + my() { + return this.current(); + } + myChannels() { + var _a; + return (_a = this.currentChannelID.all()) !== null && _a !== void 0 ? _a : []; + } + onChannelsChanged(callback) { + if (typeof callback !== "function") { + throw new Error("Please provide the callback as a function!"); + } + let timeoutId; + const current = this.current(); + if (current) { + timeoutId = setTimeout(() => { + callback(this.myChannels()); + }, 0); + } + const un = this.registry.add(this.channelsChangedKey, callback); + return () => { + un(); + clearTimeout(timeoutId); + }; + } + changed(callback) { + if (typeof callback !== "function") { + throw new Error("Please provide the callback as a function!"); + } + const current = this.current(); + if (current) { + setTimeout(() => { + callback(this.current()); + }, 0); + } + return this.registry.add(this.changedKey, () => { + callback(this.current()); + }); + } + onChanged(callback) { + return this.changed(callback); + } + async add(info) { + var _a; + if (typeof info !== "object") { + throw new Error("Please provide the info as an object!"); + } + if (typeof info.name === "undefined") { + throw new Error("info.name is missing!"); + } + if (typeof info.name !== "string") { + throw new Error("Please provide the info.name as a string!"); + } + if (typeof info.meta === "undefined") { + throw new Error("info.meta is missing!"); + } + if (typeof info.meta !== "object") { + throw new Error("Please provide the info.meta as an object!"); + } + if (typeof info.meta.color === "undefined") { + throw new Error("info.meta.color is missing!"); + } + if (typeof info.meta.color !== "string") { + throw new Error("Please provide the info.meta.color as a string!"); + } + const context = { + name: info.name, + meta: info.meta || {}, + data: info.data || {} + }; + this.logger.trace(`adding channel: ${info.name}`); + await addOrRemoveChannel("addChannel", info.name, info.meta.color, (_a = info.meta) === null || _a === void 0 ? void 0 : _a.label); + await this.shared.updateChannel(info.name, context); + return context; + } + async remove(channel) { + if (typeof channel !== "string") { + throw new Error("Please provide the channel name as a string!"); + } + this.logger.trace(`removing channel: ${channel}`); + await this.shared.remove(channel); + await addOrRemoveChannel("removeChannel", channel); + } + async getWindowsOnChannel(channel) { + this.validateChannelArg(channel); + const windowInfos = await this.getWindowsWithChannels({ channels: [channel] }); + return windowInfos.map((w) => w.window); + } + async getWindowsWithChannels(filter) { + this.validateWindowsWithChannelsFilter(filter); + try { + const info = await getChannelsInfo(filter); + const windowsAPI = this.getWindowsAPI(); + if (info === null || info === void 0 ? void 0 : info.windows) { + return info.windows.reduce((memo, windowInfo) => { + const window = windowsAPI.findById(windowInfo.windowId); + memo.push({ + window, + channel: windowInfo.channel, + application: windowInfo.application + }); + return memo; + }, []); + } + } + catch (er) { + this.logger.error(`Error getting all channel enabled windows. This method is available since Glue42 3.12`, er); + } + return []; + } + async restrict(restriction) { + this.validateRestrictionConfig(restriction); + return setRestrictions(restriction); + } + async getRestrictions(windowId) { + if (windowId) { + this.validateWindowIdArg(windowId); + } + return getRestrictionsByWindow(windowId); + } + async restrictAll(restriction) { + this.validateRestrictionConfig(restriction); + return setRestrictionsForAllChannels(restriction); + } + handleRestrictionsChanged(restrictions, windowId) { + this.registry.execute("restrictions-changed", { + restrictions, + windowId + }); + } + async clearChannelData(channel) { + const channelName = typeof channel === "string" ? channel : this.currentChannelID.toString(); + if (!channelName) { + return; + } + if (!this.shared.isChannel(channelName)) { + return; + } + const canPublish = (await this.getRestrictionsByChannel(channelName)).write; + if (!canPublish) { + return; + } + return this.shared.clearContextData(channelName); + } + handler(data, context, updaterId) { + if (!context && !updaterId) { + this.lastUpdate = undefined; + return; + } + this.lastUpdate = { context, updaterId }; + this.pendingReplays = {}; + this.registry.execute(this.subsKey, data, context, updaterId); + } + async joinCore(name, changeSelector = true) { + this.logger.trace(`joining channel "${name}" ${changeSelector ? "" : "from command"}`); + if (typeof name !== "string") { + throw new Error("Please provide the channel name as a string!"); + } + const newId = this.getID(name); + if (!this.isInitialJoin && this.currentChannelID.isOnChannel(newId.toString())) { + this.logger.trace(`already on channel: "${name}" ${changeSelector ? "" : "from command"}`); + return; + } + this.isInitialJoin = false; + await Promise.all(newId.all().map((n) => this.verifyChannelExists(n))); + this.currentChannelID.joinChannel(name); + this.lastUpdate = undefined; + this.logger.trace(`switching channel context to: "${name}" ${changeSelector ? "" : "from command"}`); + await this.shared.switchChannel(this.currentChannelID.toString()); + if (changeSelector) { + this.logger.trace(`switching UI channel to: "${name}" ${changeSelector ? "" : "from command"}`); + await sendSwitchChannelUI(name); + this.logger.trace(`switched UI channel to: "${name}" ${changeSelector ? "" : "from command"}`); + } + this.raiseChannelsChangedEvents(); + this.logger.trace(`joined channel: ${name} ${changeSelector ? "" : "from command"} - current channel/s: ${this.currentChannelID.toString()}`); + } + async verifyChannelExists(name) { + const doesChannelExist = (channelName) => { + const channelNames = this.shared.all(); + return channelNames.includes(channelName); + }; + if (!doesChannelExist(name)) { + const channelExistsPromise = new Promise((resolve, reject) => { + const intervalId = setInterval(() => { + if (doesChannelExist(name)) { + clearTimeout(timeoutId); + clearInterval(intervalId); + resolve(); + } + }, 100); + const timeoutId = setTimeout(() => { + clearInterval(intervalId); + return reject(new Error(`A channel with name: ${name} doesn't exist!`)); + }, 3000); + }); + await channelExistsPromise; + } + } + async leaveCore(changeSelector = true, channelID) { + if (!this.currentChannelID.isJoinedToAnyChannel) { + this.logger.trace(`leave called ${changeSelector ? "" : "from command"} when not joined to any channel change selector`); + return; + } + if (channelID && !this.currentChannelID.isOnChannel(channelID)) { + this.logger.trace(`leave called ${changeSelector ? "" : "from command"} when not joined to channel: "${channelID}"`); + return; + } + this.logger.trace(`leaving context channel: "${channelID}" ${changeSelector ? "" : "from command"}`); + this.currentChannelID.leaveChannel(channelID); + await this.shared.leave(channelID); + this.lastUpdate = undefined; + this.raiseChannelsChangedEvents(); + if (changeSelector) { + this.logger.trace(`switching UI channel to: "${channelID}" ${changeSelector ? "" : "from command"}`); + await sendSwitchChannelUI(this.currentChannelID.toString()); + this.logger.trace(`switched UI channel to: "${channelID}" ${changeSelector ? "" : "from command"}`); + } + this.logger.trace(`left single channel: "${channelID}" ${changeSelector ? "" : "from command"} - current channel/s: "${this.currentChannelID.toString()}"`); + return Promise.resolve(); + } + async leaveCoreMulti(changeSelector = true, channelID) { + this.logger.trace(`leaving multi channel: "${channelID.toString()}" ${changeSelector ? "" : "from command"}`); + const currentChannels = this.currentChannelID.all(); + const isJoinedToChannel = currentChannels.some((c) => channelID.isOnChannel(c)); + if (!isJoinedToChannel || !this.currentChannelID.isJoinedToAnyChannel) { + this.logger.trace(`leave called ${changeSelector ? "" : "from command"} when not joined to any channel`); + return; + } + const channelName = channelID.toString(); + this.currentChannelID.leaveChannel(channelName); + await this.shared.leave(channelName); + this.lastUpdate = undefined; + this.raiseChannelsChangedEvents(); + if (changeSelector) { + this.logger.trace(`switching UI channel to: "${channelName}" ${changeSelector ? "" : "from command"}`); + await sendLeaveChannel(channelName); + this.logger.trace(`switched UI channel to: "${channelName}" ${changeSelector ? "" : "from command"}`); + } + this.logger.trace(`left multi channel: "${channelName}" ${changeSelector ? "" : "from command"} - current channel/s: ${this.currentChannelID.toString()}`); + return Promise.resolve(); + } + raiseChannelsChangedEvents() { + this.registry.execute(this.changedKey, this.currentChannelID.toString()); + this.registry.execute(this.channelsChangedKey, this.currentChannelID.all()); + } + async getRestrictionsByChannel(channelName) { + var _a; + const restrictions = (_a = this.channelRestrictions) !== null && _a !== void 0 ? _a : await getRestrictionsByWindow(); + if (!restrictions || !Array.isArray(restrictions.channels) || !restrictions.channels.find(c => c.name === channelName)) { + return { + read: true, + write: true + }; + } + const byChannel = restrictions.channels.find(c => c.name === channelName); + return byChannel; + } + onRestrictionsChanged(callback, callbackId, currentChannelName) { + this.pendingRestrictionCallbacks.set(callbackId, { + cb: callback, + channelName: currentChannelName + }); + if (this.onRestrictionsChangedSub) { + return; + } + this.onRestrictionsChangedSub = this.registry.add("restrictions-changed", ({ restrictions }) => { + this.logger.trace(`restrictions changed - ${JSON.stringify(restrictions)}`); + this.pendingRestrictionCallbacks.forEach(({ cb, channelName }, id) => { + const currentChannel = restrictions.channels.find((c) => c.name === channelName); + if (!currentChannel) { + this.logger.trace(`channel "${channelName}" not found in restrictions`); + return; + } + if (currentChannel.read) { + this.pendingRestrictionCallbacks.delete(id); + if (this.pendingRestrictionCallbacks.values.length === 0 && this.onRestrictionsChangedSub) { + this.onRestrictionsChangedSub(); + this.onRestrictionsChangedSub = null; + } + cb(); + } + }); + }); + } + subscribeForChannelRestrictionsChange() { + this.registry.add("restrictions-changed", (r) => { + this.logger.trace(`channel restrictions changed - ${JSON.stringify(r.restrictions)}`); + this.channelRestrictions = r.restrictions; + }); + } + validatePathArgs(path) { + if (!path) { + throw new Error("Please provide a valid path value argument"); + } + if (typeof path !== "object") { + throw new Error(`Path Value argument is not a valid object: ${JSON.stringify(path)}`); + } + if (!path.path) { + throw new Error(`path property is missing from Path Value argument: ${JSON.stringify(path)}`); + } + if (!path.value) { + throw new Error(`value property is missing from Path Value argument: ${JSON.stringify(path)}`); + } + if (typeof path.path !== "string") { + throw new Error(`path property is not a valid string from the Path Value argument: ${JSON.stringify(path)}`); + } + } + validatePublishOptions(options) { + if ((typeof options !== "string" && typeof options !== "object") || Array.isArray(options)) { + throw new Error("Provide options as a string or an object"); + } + if (typeof options === "object") { + this.validatePublishOptionsObject(options); + return; + } + if (options === "string" && !options.length) { + throw new Error("Provide options as a non-empty string"); + } + } + validatePublishOptionsObject(options) { + if (typeof options !== "object" || Array.isArray(options)) { + throw new Error("Provide options as an object"); + } + if (options.name && (typeof options.name !== "string" || !options.name.length)) { + throw new Error("Provide options.name as a non-empty string"); + } + if (Object.keys(options).includes("fdc3") && typeof options.fdc3 !== "boolean") { + throw new Error("Provide options.fdc3 as a boolean"); + } + } + async publishWithOptions(data, options) { + const channelName = options.name || this.currentChannelID.toString(); + if (!this.shared.isChannel(channelName)) { + throw new Error(`A channel with name: ${options.name} doesn't exist!`); + } + if (!channelName) { + throw new Error("Cannot publish to channel, because not joined to a channel!"); + } + const canPublish = (await this.getRestrictionsByChannel(channelName)).write; + if (!canPublish) { + throw new Error(`Window does not have permission to write to channel ${this.currentChannelID.toString()}`); + } + if (!options.fdc3) { + return this.shared.updateData(channelName, data); + } + return this.publishFdc3Data(channelName, data); + } + async publishFdc3Data(channelName, data) { + var _a; + if (typeof data.type !== "string" || !((_a = data.type) === null || _a === void 0 ? void 0 : _a.length)) { + throw new Error("Expected a valid FDC3 Context with compulsory 'type' field"); + } + const { type, ...rest } = data; + const parsedType = type.split(".").join("&"); + const fdc3DataToPublish = { [`fdc3_${parsedType}`]: rest }; + return this.shared.updateData(channelName, fdc3DataToPublish); + } + getWrappedSubscribeCallback(callback, id) { + const wrappedCallback = async (_, context, updaterId) => { + const restrictionByChannel = await this.getRestrictionsByChannel(context.name); + const channelData = this.getDataWithFdc3Encoding(context); + if (restrictionByChannel.read) { + callback(channelData, context, updaterId); + } + else { + this.onRestrictionsChanged(() => { + callback(channelData, context, updaterId); + }, id, context.name); + } + }; + return wrappedCallback; + } + getWrappedSubscribeCallbackWithFdc3Type(callback, id, fdc3Type) { + const didReplay = { replayed: false }; + const wrappedCallback = async (_, context, updaterId) => { + const restrictionByChannel = await this.getRestrictionsByChannel(context.name); + const callbackWithTypesChecks = () => { + const { data, latest_fdc3_type } = context; + const searchedType = `fdc3_${fdc3Type.split(".").join("&")}`; + if (!data[searchedType]) { + return; + } + if (didReplay.replayed) { + return this.parseDataAndInvokeSubscribeCallback({ latestFdc3TypeEncoded: latest_fdc3_type, searchedType: fdc3Type, callback, context, updaterId }); + } + const fdc3Data = { type: fdc3Type, ...data[searchedType] }; + callback({ fdc3: fdc3Data }, context, updaterId); + didReplay.replayed = true; + }; + if (restrictionByChannel.read) { + callbackWithTypesChecks(); + return; + } + this.onRestrictionsChanged(callbackWithTypesChecks, id, context.name); + }; + return wrappedCallback; + } + parseDataAndInvokeSubscribeCallback(args) { + const { latestFdc3TypeEncoded, searchedType, callback, context, updaterId } = args; + const latestPublishedType = latestFdc3TypeEncoded.split("&").join("."); + if (latestPublishedType !== searchedType) { + return; + } + const fdc3Data = { type: searchedType, ...context.data[`fdc3_${latestFdc3TypeEncoded}`] }; + callback({ fdc3: fdc3Data }, context, updaterId); + } + getContextWithFdc3Type(context, searchedType) { + var _a, _b; + if (((_b = (_a = context.data) === null || _a === void 0 ? void 0 : _a.fdc3) === null || _b === void 0 ? void 0 : _b.type) === searchedType) { + return { + name: context.name, + meta: context.meta, + data: { fdc3: context.data.fdc3 } + }; + } + const encodedType = `fdc3_${searchedType.split(".").join("&")}`; + if (!context.data[encodedType]) { + return { + name: context.name, + meta: context.meta, + data: {} + }; + } + const fdc3Context = { type: searchedType, ...context.data[encodedType] }; + return { + name: context.name, + meta: context.meta, + data: { fdc3: fdc3Context } + }; + } + getDataWithFdc3Encoding(context) { + const { data, latest_fdc3_type } = context; + if (!latest_fdc3_type) { + return data; + } + const parsedType = latest_fdc3_type.split("&").join("."); + const latestTypePropName = `fdc3_${latest_fdc3_type}`; + const fdc3Data = { type: parsedType, ...data[latestTypePropName] }; + const { [latestTypePropName]: latestFDC3Type, ...rest } = data; + return { ...rest, fdc3: fdc3Data }; + } + getID(id) { + if (this.mode === "multi") { + return new MultiChannelId(id); + } + else { + return new SingleChannelID(id); + } + } + leaveWhenSingle(channelName, windowId) { + if (windowId) { + this.logger.trace(`leaving single channel "${channelName}" for window: "${windowId}"`); + return sendSwitchChannelUI(undefined, windowId); + } + this.logger.trace(`leaving single channel "${channelName}" for our window`); + return this.leaveCore(true, channelName); + } + async leaveWhenMulti(channelName, windowId) { + if (windowId) { + this.logger.trace(`leaving multi channel "${channelName}" for window: "${windowId}"`); + return sendLeaveChannel(channelName, windowId); + } + else { + const channelId = channelName ? new MultiChannelId(channelName) : this.currentChannelID; + this.logger.trace(`leaving multi channel "${channelId.toString()}" for our window`); + return this.leaveCoreMulti(true, channelId); + } + } + validateWindowIdArg(windowId) { + if (typeof windowId !== "string") { + throw new Error("The window ID must be a non-empty string!"); + } + const windows = this.getWindowsAPI(); + if (!windows.findById(windowId)) { + throw new Error(`Window with ID "${windowId}" doesn't exist!`); + } + } + validateChannelArg(channel) { + if (!channel) { + throw new Error("Please provide a valid Channel name as a non-empty string!"); + } + if (typeof channel !== "string") { + throw new Error("The Channel name must be a non-empty string!"); + } + const channelNames = this.shared.all(); + if (channelNames.every((name) => name !== channel)) { + throw new Error(`Channel "${channel}" does not exist!"`); + } + } + validateWindowsWithChannelsFilter(filter) { + if (filter === undefined) { + return; + } + if (filter === null || Array.isArray(filter) || typeof filter !== "object") { + throw new Error("The `filter` argument must be a valid object!"); + } + } + isRestrictions(restriction) { + return 'name' in restriction; + } + validateRestrictionConfig(restriction) { + if (restriction === null || restriction === undefined || Array.isArray(restriction) || typeof restriction !== "object") { + throw new Error("The `restrictions` argument must be a valid object with Channel restrictions!"); + } + if (this.isRestrictions(restriction) && typeof restriction.name !== "string") { + throw new Error("The `name` restriction property must be a non-empty string!"); + } + if (restriction.read !== null && restriction.read !== undefined && typeof restriction.read !== "boolean") { + throw new Error("The `read` restriction property must be a boolean value!"); + } + if (restriction.write !== null && restriction.write !== undefined && typeof restriction.write !== "boolean") { + throw new Error("The `write` restriction property must be a boolean value!"); + } + if ((restriction.read === null || restriction.read === undefined) && (restriction.write === null || restriction.write === undefined)) { + throw new Error("It's required to set either the `read` or the `write` property of the Channel restriction object!"); + } + if (restriction.windowId !== null && restriction.windowId !== undefined) { + this.validateWindowIdArg(restriction.windowId); + } + } + } + + function factory$4(config, contexts, agm, getWindowsAPI, getAppManagerAPI, logger) { + const channelsReadyPromise = getChannelInitInfo(config, agm) + .then(async ({ mode, initialChannel }) => { + const sharedContexts = mode === "single" ? new SharedContextSubscriber(contexts) : new MultiSharedContextSubscriber(contexts); + if (mode === "multi") { + logger.info(`multi-channel mode enabled`); + } + await channels.init(sharedContexts, mode, initialChannel); + await setupInterop(agm, channels, logger); + return true; + }); + const channels = new ChannelsImpl(agm, getWindowsAPI, getAppManagerAPI, logger); + return { + subscribe: channels.subscribe.bind(channels), + subscribeFor: channels.subscribeFor.bind(channels), + publish: channels.publish.bind(channels), + setPath: channels.setPath.bind(channels), + setPaths: channels.setPaths.bind(channels), + all: channels.all.bind(channels), + list: channels.list.bind(channels), + get: channels.get.bind(channels), + join: channels.join.bind(channels), + leave: channels.leave.bind(channels), + restrict: channels.restrict.bind(channels), + getRestrictions: channels.getRestrictions.bind(channels), + clearChannelData: channels.clearChannelData.bind(channels), + restrictAll: channels.restrictAll.bind(channels), + current: channels.current.bind(channels), + my: channels.my.bind(channels), + changed: channels.changed.bind(channels), + onChanged: channels.onChanged.bind(channels), + add: channels.add.bind(channels), + remove: channels.remove.bind(channels), + getWindowsOnChannel: channels.getWindowsOnChannel.bind(channels), + getWindowsWithChannels: channels.getWindowsWithChannels.bind(channels), + getMy: channels.getMy.bind(channels), + ready: async () => { + await Promise.all([contexts.ready(), channelsReadyPromise]); + }, + get mode() { return channels.mode; }, + getMyChannels: channels.getMyChannels.bind(channels), + myChannels: channels.myChannels.bind(channels), + onChannelsChanged: channels.onChannelsChanged.bind(channels), + }; + } + + const CommandMethod = "T42.Hotkeys.Command"; + const InvokeMethod = "T42.Hotkeys.Invoke"; + const RegisterCommand = "register"; + const UnregisterCommand = "unregister"; + const UnregisterAllCommand = "unregisterAll"; + class HotkeysImpl { + constructor(agm) { + this.agm = agm; + this.registry = CallbackRegistryFactory(); + this.firstHotkey = true; + this.hotkeys = new Map(); + } + async register(info, callback) { + if (typeof info === "undefined") { + throw new Error("Hotkey parameter missing"); + } + if (typeof info === "string") { + info = { + hotkey: info + }; + } + else { + if (!info.hotkey) { + throw new Error("Info's hotkey parameter missing"); + } + info = { + hotkey: info.hotkey, + description: info.description + }; + } + const hkToLower = this.formatHotkey(info.hotkey); + if (this.hotkeys.has(hkToLower)) { + throw new Error(`Shortcut for ${hkToLower} already registered`); + } + if (this.firstHotkey) { + this.firstHotkey = false; + await this.registerInvokeAGMMethod(); + } + this.registry.add(hkToLower, callback); + await this.agm.invoke(CommandMethod, { command: RegisterCommand, hotkey: hkToLower, description: info.description }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + this.hotkeys.set(hkToLower, info); + } + async unregister(hotkey) { + if (typeof hotkey === "undefined") { + throw new Error("hotkey parameter missing"); + } + if (typeof hotkey !== "string") { + throw new Error("hotkey parameter must be string"); + } + const hkToLower = this.formatHotkey(hotkey); + await this.agm.invoke(CommandMethod, { command: UnregisterCommand, hotkey: hkToLower }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + this.hotkeys.delete(hkToLower); + this.registry.clearKey(hkToLower); + } + async unregisterAll() { + await this.agm.invoke(CommandMethod, { command: UnregisterAllCommand }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + this.hotkeys.clear(); + this.registry.clear(); + } + isRegistered(hotkey) { + const hkToLower = this.formatHotkey(hotkey); + return this.hotkeys.has(hkToLower); + } + registerInvokeAGMMethod() { + return this.agm.register(InvokeMethod, (args) => { + const hkToLower = args.key.toLowerCase(); + const info = this.hotkeys.get(hkToLower); + this.registry.execute(hkToLower, info); + }); + } + formatHotkey(hotkey) { + if (hotkey) { + return hotkey.replace(/\s/g, "").toLowerCase(); + } + } + } + + function factory$3(agm) { + const hotkeys = new HotkeysImpl(agm); + return { + register: hotkeys.register.bind(hotkeys), + unregister: hotkeys.unregister.bind(hotkeys), + unregisterAll: hotkeys.unregisterAll.bind(hotkeys), + isRegistered: hotkeys.isRegistered.bind(hotkeys), + ready: () => Promise.resolve() + }; + } + + var version = "6.12.0"; + + var prepareConfig = (options) => { + function getLibConfig(value, defaultMode, trueMode) { + if (typeof value === "boolean" && !value) { + return undefined; + } + const mode = getModeAsString(value, defaultMode, trueMode); + if (typeof mode === "undefined") { + return undefined; + } + if (typeof value === "object") { + value.mode = mode; + return value; + } + return { + mode, + }; + } + function getModeAsString(value, defaultMode, trueMode) { + if (typeof value === "object") { + return getModeAsString(value.mode, defaultMode, trueMode).toString(); + } + else if (typeof value === "undefined") { + if (typeof defaultMode === "boolean" && !defaultMode) { + return undefined; + } + else if (typeof defaultMode === "boolean" && defaultMode) { + return typeof trueMode === "undefined" ? defaultMode : trueMode; + } + else if (typeof defaultMode === "undefined") { + return undefined; + } + else { + return defaultMode; + } + } + else if (typeof value === "boolean") { + if (value) { + return (typeof trueMode === "undefined") ? defaultMode : trueMode; + } + else { + return undefined; + } + } + return value; + } + const appDefaultMode = true; + const appDefaultTrueMode = "startOnly"; + const activitiesDefaultMode = Utils.isNode() ? false : "trackMyTypeAndInitiatedFromMe"; + const activitiesTrueMode = "trackMyTypeAndInitiatedFromMe"; + const layoutsDefaultMode = "slim"; + const layoutsTrueMode = layoutsDefaultMode; + const channelsConfig = () => { + if (typeof options.channels === "boolean") { + return options.channels; + } + else if (typeof options.channels === "object" && typeof options.channels.enabled === "boolean" && options.channels.enabled) { + return { mode: true, ...options.channels }; + } + else { + return false; + } + }; + const exposeAPI = typeof options.exposeAPI === "boolean" || typeof options.exposeGlue === "boolean"; + return { + layouts: getLibConfig(options.layouts, layoutsDefaultMode, layoutsTrueMode), + activities: getLibConfig(options.activities, activitiesDefaultMode, activitiesTrueMode), + appManager: getLibConfig(options.appManager, appDefaultMode, appDefaultTrueMode), + windows: getLibConfig(options.windows, true, true), + channels: getLibConfig(channelsConfig(), false, true), + displays: getLibConfig(options.displays, true, true), + exposeAPI: exposeAPI ? exposeAPI : true + }; + }; + + class Glue42Notification { + constructor(options) { + this.options = options; + this.callbacks = CallbackRegistryFactory(); + this.actions = options.actions; + this.body = options.body; + this.badge = options.badge; + this.data = options.data; + this.dir = options.dir; + this.icon = options.icon; + this.image = options.image; + this.lang = options.lang; + this.renotify = options.renotify; + this.requireInteraction = options.requireInteraction; + this.silent = options.silent; + this.tag = options.tag; + this.timestamp = options.timestamp; + this.title = options.title; + } + close() { + throw new Error("Method not implemented."); + } + addEventListener(type, listener, options) { + this.callbacks.add(type, listener); + } + removeEventListener(type, listener, options) { + } + dispatchEvent(event) { + this.callbacks.execute(event.type, event); + return true; + } + } + + class PanelAPI { + constructor(interop, onStreamEvent) { + this.interop = interop; + this.onStreamEvent = onStreamEvent; + } + onVisibilityChanged(callback) { + return this.onStreamEvent("on-panel-visibility-changed", callback); + } + toggle() { + return this.interop.invoke("T42.Notifications.Show", undefined, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + show() { + return this.interop.invoke("T42.Notifications.Show", { show: true }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + hide() { + return this.interop.invoke("T42.Notifications.Hide"); + } + async isVisible() { + const interopResult = await this.interop.invoke("T42.Notifications.Execute", { command: "isPanelVisible" }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return interopResult.returned.panelVisible; + } + toAPI() { + return { + onVisibilityChanged: this.onVisibilityChanged.bind(this), + toggle: this.toggle.bind(this), + show: this.show.bind(this), + hide: this.hide.bind(this), + isVisible: this.isVisible.bind(this) + }; + } + } + + const STARTING_INDEX = 0; + class Notifications { + constructor(interop, logger) { + this.interop = interop; + this.NotificationsSubscribeStream = "T42.GNS.Subscribe.Notifications"; + this.NotificationsCounterStream = "T42.Notifications.Counter"; + this.RaiseNotificationMethodName = "T42.GNS.Publish.RaiseNotification"; + this.NotificationsExecuteMethod = "T42.Notifications.Execute"; + this.NotificationFilterMethodName = "T42.Notifications.Filter"; + this.methodsRegistered = false; + this.NOTIFICATIONS_CONFIGURE_METHOD_NAME = "T42.Notifications.Configure"; + this.methodNameRoot = "T42.Notifications.Handler-" + Utils.generateId(); + this.nextId = 0; + this.notifications = {}; + this.registry = CallbackRegistryFactory(); + this.subscribedForNotifications = false; + this.subscribedCounterStream = false; + this.subscriptionsCountForNotifications = 0; + this.subscriptionsCountForCounter = 0; + this.logger = logger.subLogger("notifications"); + this._panel = new PanelAPI(interop, this.onStreamEventCore.bind(this)); + this._panelAPI = this._panel.toAPI(); + this.subscribeInternalEvents(); + } + get maxActions() { + return 10; + } + get panel() { + return this._panelAPI; + } + async raise(options) { + var _a; + const notification = await this.createNotification(options); + const g42notification = new Glue42Notification(options); + this.notifications[notification.id] = g42notification; + try { + const invocationResult = await this.interop.invoke(this.RaiseNotificationMethodName, { notification }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + g42notification.id = (_a = invocationResult.returned) === null || _a === void 0 ? void 0 : _a.id; + } + catch (err) { + const errorMessage = err.message; + setTimeout(() => { + this.handleNotificationErrorEvent(g42notification, errorMessage); + }, 1); + } + return g42notification; + } + async setFilter(filter) { + const result = await this.interop.invoke(this.NotificationFilterMethodName, filter, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return result.returned; + } + async getFilter() { + const result = await this.interop.invoke(this.NotificationFilterMethodName, undefined, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return result.returned; + } + async configure(options) { + var _a, _b, _c, _d, _e, _f, _g, _h; + if (!options || Array.isArray(options)) { + throw new Error("Invalid options - should be an object."); + } + if (Object.values(options).length === 0) { + throw new Error("The argument must be a non-empty object."); + } + if (typeof options.enable !== "undefined" && typeof options.enable !== "boolean") { + throw new Error("Expected type of enabled - boolean."); + } + if (typeof options.enableToasts !== "undefined" && typeof options.enableToasts !== "boolean") { + throw new Error("Expected type of enableToasts - boolean."); + } + if (typeof options.toastExpiry !== "undefined" && typeof options.toastExpiry !== "number") { + throw new Error("Expected type of toastExpiry - number."); + } + if (options.sourceFilter && typeof options.sourceFilter !== "object") { + throw new Error("Expected type of sourceFilter - object."); + } + if (((_a = options.sourceFilter) === null || _a === void 0 ? void 0 : _a.allowed) && !Array.isArray((_b = options.sourceFilter) === null || _b === void 0 ? void 0 : _b.allowed)) { + throw new Error("Expected type of sourceFilter.allowed - array."); + } + if (((_c = options.sourceFilter) === null || _c === void 0 ? void 0 : _c.blocked) && !Array.isArray((_d = options.sourceFilter) === null || _d === void 0 ? void 0 : _d.blocked)) { + throw new Error("Expected type of sourceFilter.blocked - array."); + } + if (options.toasts && typeof options.toasts !== "object") { + throw new Error("Expected type of (options.toasts - object."); + } + if (((_e = options.toasts) === null || _e === void 0 ? void 0 : _e.mode) && typeof options.toasts.mode !== "string") { + throw new Error("Expected type of (options.toasts.mode - string."); + } + if (((_f = options.toasts) === null || _f === void 0 ? void 0 : _f.stackBy) && typeof options.toasts.stackBy !== "string") { + throw new Error("Expected type of (options.toasts.stackBy - string."); + } + if (options.placement && typeof options.placement !== "object") { + throw new Error("Expected type of (options.placement - object."); + } + if (((_g = options.placement) === null || _g === void 0 ? void 0 : _g.toasts) && typeof options.placement.toasts !== "string") { + throw new Error("Expected type of (options.placement.toasts - string."); + } + if (((_h = options.placement) === null || _h === void 0 ? void 0 : _h.panel) && typeof options.placement.panel !== "string") { + throw new Error("Expected type of (options.placement.panel - string."); + } + if (typeof options.closeNotificationOnClick !== "undefined" && typeof options.closeNotificationOnClick !== "boolean") { + throw new Error("Expected type of closeNotificationOnClick - boolean."); + } + const result = await this.interop.invoke(this.NOTIFICATIONS_CONFIGURE_METHOD_NAME, options, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return result.returned; + } + async getConfiguration() { + const result = await this.interop.invoke(this.NotificationsExecuteMethod, { command: "getConfiguration" }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return result.returned; + } + async list() { + const interopResult = await this.interop.invoke(this.NotificationsExecuteMethod, { + command: "list", + data: { statesVersion2: true } + }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return interopResult.returned.notifications; + } + async updateData(id, data) { + const replacer = (key, value) => typeof value === "undefined" ? null : value; + const attribute = { + key: "data", + value: { + stringValue: JSON.stringify(data, replacer) + } + }; + const interopResult = await this.interop.invoke(this.NotificationsExecuteMethod, { command: "create-or-update-attribute", data: { id, attribute } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return interopResult.returned; + } + onRaised(callback) { + return this.onStreamEventCore("on-notification-raised", callback); + } + onStateChanged(callback) { + return this.onStreamEventCore("on-state-changed", callback); + } + onClosed(callback) { + return this.onStreamEventCore("on-notification-closed", callback); + } + onConfigurationChanged(callback) { + if (typeof callback !== "function") { + throw new Error("Please provide the callback as a function!"); + } + this.subscribe(); + const un = this.registry.add("on-configuration-changed", callback); + return () => { + un(); + this.closeStreamSubscriptionIfNoNeeded(); + }; + } + onCounterChanged(callback) { + if (typeof callback !== "function") { + throw new Error("Please provide the callback as a function!"); + } + this.subscribeForCounterStream(); + const un = this.registry.add("on-counter-changed", callback); + return () => { + un(); + this.closeStreamCounterSubscriptionIfNoNeeded(); + }; + } + onDataChanged(callback) { + if (typeof callback !== "function") { + throw new Error("Please provide the callback as a function!"); + } + this.subscribe(); + const un = this.registry.add("on-notification-data-changed", callback); + return () => { + un(); + this.closeStreamSubscriptionIfNoNeeded(); + }; + } + async clearAll() { + await this.interop.invoke(this.NotificationsExecuteMethod, { command: "clearAll" }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async clearOld() { + await this.interop.invoke(this.NotificationsExecuteMethod, { command: "clearAllOld", data: { statesVersion2: true } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async clear(id) { + if (!id) { + throw new Error("The 'id' argument cannot be null or undefined"); + } + if (typeof (id) !== "string") { + throw new Error("The 'id' argument must be a string"); + } + await this.interop.invoke(this.NotificationsExecuteMethod, { command: "clear", data: { id } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async clearMany(notifications) { + this.validateNotificationsArr(notifications); + await this.interop.invoke(this.NotificationsExecuteMethod, { command: "clearMany", data: { notifications } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async click(id, action, options) { + await this.interop.invoke(this.NotificationsExecuteMethod, { command: "click", data: { id, action, options } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async snooze(id, duration) { + await this.interop.invoke(this.NotificationsExecuteMethod, { command: "snooze", data: { id, duration } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async snoozeMany(notifications, duration) { + if (!duration) { + throw new Error("The 'duration' argument cannot be null or undefined"); + } + if (typeof duration !== "number") { + throw new Error("The 'duration' argument must be a valid number"); + } + this.validateNotificationsArr(notifications); + await this.interop.invoke(this.NotificationsExecuteMethod, { command: "snoozeMany", data: { notifications, duration } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async setState(id, state) { + if (!id) { + throw new Error("The 'id' argument cannot be null or undefined"); + } + if (typeof (id) !== "string") { + throw new Error("The 'id' argument must be a string"); + } + if (!state) { + throw new Error("The 'state' argument cannot be null or undefined"); + } + this.validateState(state); + await this.interop.invoke(this.NotificationsExecuteMethod, { command: "updateState", data: { id, state } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async setStates(notifications, state) { + if (!state) { + throw new Error("The 'state' argument cannot be null or undefined"); + } + if (typeof state !== "string") { + throw new Error("The 'state' argument must be a valid string"); + } + this.validateNotificationsArr(notifications); + await this.interop.invoke(this.NotificationsExecuteMethod, { command: "updateStates", data: { notifications, state } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + toAPI() { + return { + maxActions: this.maxActions, + panel: this._panel.toAPI(), + raise: this.raise.bind(this), + setFilter: this.setFilter.bind(this), + getFilter: this.getFilter.bind(this), + configure: this.configure.bind(this), + getConfiguration: this.getConfiguration.bind(this), + list: this.list.bind(this), + onRaised: this.onRaised.bind(this), + onStateChanged: this.onStateChanged.bind(this), + onClosed: this.onClosed.bind(this), + onConfigurationChanged: this.onConfigurationChanged.bind(this), + onCounterChanged: this.onCounterChanged.bind(this), + onDataChanged: this.onDataChanged.bind(this), + clearAll: this.clearAll.bind(this), + clearOld: this.clearOld.bind(this), + clear: this.clear.bind(this), + click: this.click.bind(this), + setState: this.setState.bind(this), + updateData: this.updateData.bind(this), + snooze: this.snooze.bind(this), + snoozeMany: this.snoozeMany.bind(this), + clearMany: this.clearMany.bind(this), + setStates: this.setStates.bind(this), + import: this.importNotifications.bind(this) + }; + } + async importNotifications(notifications) { + if (!notifications || !Array.isArray(notifications) || notifications.length === 0) { + throw new Error("Notifications argument must be a valid array with notification options"); + } + const notificationsToImport = await Promise.all(notifications.map((notificationOptions) => this.createNotification(notificationOptions, true))); + const invocationResult = await this.interop.invoke(this.NotificationsExecuteMethod, { command: "importNotifications", data: { notificationSettings: notificationsToImport } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return invocationResult.returned.notifications; + } + async createNotification(options, imported) { + var _a, _b, _c, _d; + this.validate(options, imported); + if (!this.methodsRegistered) { + const bunchOfPromises = []; + for (let index = STARTING_INDEX; index < this.maxActions; index++) { + bunchOfPromises.push(this.interop.register(`${this.methodNameRoot}_${index}`, this.handleNotificationEvent.bind(this))); + } + this.methodsRegistered = true; + await Promise.all(bunchOfPromises); + } + const id = (_a = options.id) !== null && _a !== void 0 ? _a : Utils.generateId(); + const type = (_b = options.type) !== null && _b !== void 0 ? _b : "Notification"; + const notification = { + id, + state: (_c = options.state) !== null && _c !== void 0 ? _c : "Active", + title: options.title, + type, + severity: (_d = options.severity) !== null && _d !== void 0 ? _d : "None", + description: options.body, + glueRoutingDetailMethodName: `${this.methodNameRoot}_${STARTING_INDEX}`, + actions: [], + sourceId: id, + source: options.source, + publishExtraEvents: true, + clickInterop: options.clickInterop + }; + if (options.actions) { + this.handleActions(options, id, notification); + } + this.handleOptions(options, notification); + return notification; + } + onStreamEventCore(key, callback) { + if (typeof callback !== "function") { + throw new Error("Please provide the callback as a function!"); + } + this.subscribe(); + const un = this.registry.add(key, callback); + return () => { + un(); + this.closeStreamSubscriptionIfNoNeeded(); + }; + } + handleOptions(options, notification) { + if (options.icon) { + notification.attributes = notification.attributes || []; + notification.attributes.push({ key: "icon", value: { stringValue: options.icon } }); + } + if (options.data) { + notification.attributes = notification.attributes || []; + const dataAsString = JSON.stringify(options.data); + notification.attributes.push({ key: "data", value: { stringValue: dataAsString } }); + } + if (typeof options.panelExpiry === "number") { + notification.attributes = notification.attributes || []; + notification.attributes.push({ key: "panelExpiry", value: { stringValue: options.panelExpiry.toString() } }); + } + if (typeof options.toastExpiry === "number") { + notification.attributes = notification.attributes || []; + notification.attributes.push({ key: "toastExpiry", value: { stringValue: options.toastExpiry.toString() } }); + } + } + handleActions(options, id, notification) { + var _a, _b, _c; + const validActions = options.actions.slice(0, this.maxActions); + let index = STARTING_INDEX; + for (const action of validActions) { + const args = { + g42notificationId: id, + g42action: action.action, + g42interopMethod: (_a = action.interop) === null || _a === void 0 ? void 0 : _a.method, + g42interopTarget: (_b = action.interop) === null || _b === void 0 ? void 0 : _b.target, + g42interopArguments: JSON.stringify((_c = action.interop) === null || _c === void 0 ? void 0 : _c.arguments) + }; + const parameters = Object.keys(args).map((key) => { + const value = args[key]; + return { + name: key, + value: { + stringValue: value + } + }; + }); + const glueAction = { + name: `${this.methodNameRoot}_${index}`, + description: action.title, + displayName: action.title, + displayPath: action.displayPath, + displayId: action.displayId, + parameters + }; + notification.actions.push(glueAction); + index++; + } + } + validate(options, imported) { + if (!options) { + throw new Error("invalid options - should be an object"); + } + if (typeof options !== "object") { + throw new Error("invalid options - should be an object"); + } + if (!options.title) { + throw new Error("invalid options - should have a title"); + } + if (typeof options.title !== "string") { + throw new Error("invalid options - title should be a string"); + } + if (options.severity && typeof options.severity !== "string") { + throw new Error("invalid options - severity should be a string"); + } + if (options.panelExpiry && typeof options.panelExpiry !== "number") { + throw new Error("invalid options - panelExpiry should be a number"); + } + if (options.toastExpiry && typeof options.toastExpiry !== "number") { + throw new Error("invalid options - toastExpiry should be a number"); + } + if (options.state) { + this.validateState(options.state, imported); + } + } + validateState(state, imported) { + if (typeof (state) !== "string") { + throw new Error("The 'state' argument must be a string"); + } + const validStates = [ + "Active", + "Acknowledged", + "Stale" + ]; + if (imported) { + validStates.push("Seen", "Snoozed", "Processing", "Closed"); + } + if (!validStates.includes(state)) { + throw new Error(`The state argument: ${state} is not valid!`); + } + } + subscribe() { + this.subscriptionsCountForNotifications++; + if (!this.subscribedForNotifications) { + this.subscribedForNotifications = true; + this.logger.info(`Attempting to subscribe to "${this.NotificationsSubscribeStream}".`); + this.interop + .subscribe(this.NotificationsSubscribeStream, { + arguments: { + sendDeltaOnly: true, + statesVersion2: true + } + }) + .then((sub) => { + this.subscriptionForNotifications = sub; + this.logger.info(`Successfully subscribed to "${this.NotificationsSubscribeStream}".`); + sub.onData(({ data }) => { + this.handleData(data); + }); + sub.onClosed((...args) => { + this.subscribedForNotifications = false; + this.logger.info(`Stream subscription Closed - ${JSON.stringify(args)}`); + }); + sub.onFailed((...args) => { + this.subscribedForNotifications = false; + this.logger.warn(`Stream subscription Failed - ${JSON.stringify(args)}`); + }); + }) + .catch((e) => { + this.subscribedForNotifications = false; + this.logger.error(`Unable to subscribe to "${this.NotificationsSubscribeStream}"`, e); + }); + } + } + subscribeForCounterStream() { + this.subscriptionsCountForCounter++; + if (!this.subscribedCounterStream) { + this.subscribedCounterStream = true; + this.logger.info(`Attempting to subscribe to "${this.NotificationsCounterStream}".`); + this.interop + .subscribe(this.NotificationsCounterStream, { + arguments: { + sendDeltaOnly: true + } + }) + .then((sub) => { + this.subscriptionForCounter = sub; + this.logger.info(`Successfully subscribed to "${this.NotificationsCounterStream}".`); + sub.onData(({ data }) => { + this.registry.execute("on-counter-changed", { count: data.count }); + }); + sub.onClosed((...args) => { + this.subscribedCounterStream = false; + this.logger.info(`Stream subscription Closed - ${JSON.stringify(args)}`); + }); + sub.onFailed((...args) => { + this.subscribedCounterStream = false; + this.logger.warn(`Stream subscription Failed - ${JSON.stringify(args)}`); + }); + }) + .catch((e) => { + this.subscribedCounterStream = false; + this.logger.error(`Unable to subscribe to "${this.NotificationsCounterStream}"`, e); + }); + } + } + subscribeInternalEvents() { + this.registry.add("on-notification-closed", (id) => { + this.handleOnClosed(id); + }); + this.registry.add("on-notification-raised", (notification) => { + this.handleOnShow(notification.id); + }); + } + handleData(message) { + var _a; + try { + if ("items" in message && Array.isArray(message.items)) { + this.handleItemsData(message); + } + else if ("deltas" in message && Array.isArray(message.deltas)) { + this.handleDeltas(message); + } + if ("configuration" in message && typeof message.configuration === "object") { + this.logger.info(`Received configuration ${JSON.stringify(message.configuration)} from the stream`); + this.registry.execute("on-configuration-changed", message.configuration, message.configuration.allApplications); + } + if ("command" in message && typeof message.command === "string") { + this.logger.info(`Received command "${(_a = message.command) !== null && _a !== void 0 ? _a : JSON.stringify(message)}" from the stream`); + if (message.command === "showPanel" || message.command === "hidePanel") { + this.registry.execute("on-panel-visibility-changed", message.command === "showPanel"); + } + } + } + catch (e) { + this.logger.error(`Failed to parse data from the stream`, e); + } + } + handleItemsData(message) { + const items = message.items; + this.logger.info(`Received ${items.length} notifications from the stream`); + const notifications = items; + if (message.isSnapshot) { + notifications.forEach((n) => { + this.registry.execute("on-notification-raised", n); + }); + } + else { + const notification = notifications[0]; + if (notification.state === "Closed") { + this.registry.execute("on-notification-closed", { id: notification.id }); + } + else { + this.registry.execute("on-notification-raised", notification); + } + } + } + handleDeltas(message) { + const deltas = message.deltas; + deltas.forEach((info) => { + var _a; + const id = info.id; + const delta = (_a = info.delta) !== null && _a !== void 0 ? _a : {}; + if (delta.state === "Closed") { + this.registry.execute("on-notification-closed", { id, ...delta }); + } + else if (delta.state) { + this.registry.execute("on-state-changed", { id }, delta.state); + } + else if (delta.attributes) { + const attributes = delta.attributes; + const dataAttribute = attributes.find((a) => a.key === "data"); + if (dataAttribute) { + this.registry.execute("on-notification-data-changed", { id }, JSON.parse(dataAttribute.value.stringValue)); + } + } + }); + } + handleOnClosed(id) { + const { notification, key } = this.getNotification(id); + if (notification) { + this.handleEvent(notification, "close"); + delete this.notifications[key]; + } + } + handleOnShow(id) { + const { notification } = this.getNotification(id); + if (notification) { + this.handleEvent(notification, "show"); + } + } + getNotification(id) { + let notification; + let key; + for (const k in this.notifications) { + if (this.notifications[k].id === id) { + notification = this.notifications[k]; + key = k; + break; + } + } + return { notification, key }; + } + handleNotificationEvent(args) { + const gnsNotificationArgs = this.getGnsNotificationArgs(args); + if (gnsNotificationArgs.event === "unknown") { + return; + } + const notification = this.notifications[gnsNotificationArgs.notificationId]; + if (!notification) { + return; + } + this.handleNotificationEventCore(notification, gnsNotificationArgs); + } + handleNotificationEventCore(notification, args) { + switch (args.event) { + case "action": { + return this.handleNotificationActionEvent(notification, args.notificationActionPayload); + } + case "click": { + return this.handleNotificationClickEvent(notification); + } + case "close": { + return this.handleEvent(notification, "close"); + } + case "error": { + return this.handleNotificationErrorEvent(notification, args.error); + } + case "show": { + return this.handleEvent(notification, "show"); + } + } + } + handleNotificationActionEvent(notification, payload) { + const event = { + type: "onaction", + action: payload.g42action + }; + if (notification.onaction) { + notification.onaction(event); + } + notification.dispatchEvent(event); + } + handleNotificationClickEvent(notification) { + const event = { type: "onclick" }; + if (notification.onclick) { + notification.onclick(event); + } + notification.dispatchEvent(event); + } + handleEvent(notification, eventType) { + var _a; + const event = { type: eventType }; + const eventName = `on${eventType}`; + (_a = notification[eventName]) === null || _a === void 0 ? void 0 : _a.call(notification, event); + notification.dispatchEvent(event); + } + handleNotificationErrorEvent(notification, error) { + const event = { type: "onerror", error }; + if (notification.onerror) { + notification.onerror(event); + } + notification.dispatchEvent(event); + } + getGnsNotificationArgs(args) { + var _a; + let result; + const event = (_a = args.notification) === null || _a === void 0 ? void 0 : _a.event; + if (!event) { + result = this.getBackwardGnsNotificationArgs(args); + } + else { + result = { + event, + notificationId: args.notification.sourceNotificationId, + notificationActionPayload: args + }; + } + return result; + } + getBackwardGnsNotificationArgs(args) { + var _a; + let result; + if (args.g42notificationId) { + result = { + event: "action", + notificationId: args.g42notificationId, + notificationActionPayload: args + }; + } + else if ((_a = args.notification) === null || _a === void 0 ? void 0 : _a.sourceNotificationId) { + result = { + event: "click", + notificationId: args.notification.sourceNotificationId, + notificationActionPayload: args + }; + } + else { + result = { + event: "unknown", + notificationId: undefined, + notificationActionPayload: args + }; + } + return result; + } + closeStreamSubscriptionIfNoNeeded() { + this.subscriptionsCountForNotifications--; + if (this.subscriptionForNotifications && this.subscriptionsCountForNotifications === 0) { + this.subscriptionForNotifications.close(); + this.subscriptionForNotifications = undefined; + } + } + closeStreamCounterSubscriptionIfNoNeeded() { + this.subscriptionsCountForCounter--; + if (this.subscriptionForCounter && this.subscriptionsCountForCounter === 0) { + this.subscriptionForCounter.close(); + this.subscriptionForCounter = undefined; + } + } + validateNotificationsArr(notifications) { + if (!Array.isArray(notifications)) { + throw new Error("The 'notifications' argument must be an array with valid notification IDs"); + } + if (notifications.some((n) => typeof n !== "string")) { + throw new Error("The 'notifications' argument must contain only valid string notification IDs"); + } + } + } + + const ThemesConfigurationMethodName = "T42.Themes.Configuration"; + class ThemesImpl { + constructor(contexts, interop) { + this.contexts = contexts; + this.interop = interop; + this.registry = CallbackRegistryFactory(); + this.isSubscribed = false; + this.getConfiguration(); + } + async list() { + await this.getConfiguration(); + if (!this.getMethodName) { + throw new Error("not supported"); + } + return (await this.getAll()).returned.all; + } + async getCurrent() { + await this.getConfiguration(); + if (!this.getMethodName) { + throw new Error("not supported"); + } + const all = await this.getAll(); + return all.returned.all.find((t) => t.name === all.returned.selected); + } + async select(theme) { + await this.getConfiguration(); + if (!this.setMethodName) { + throw new Error("not supported"); + } + await this.interop.invoke(this.setMethodName, { theme }); + } + onChanged(callback) { + if (!callback) { + throw new Error("Callback argument is required"); + } + if (callback && typeof callback !== "function") { + throw new Error("Callback argument must be a function"); + } + this.subscribe(); + return this.registry.add("changed", callback); + } + async getConfiguration() { + try { + if (this.sharedContextName) { + return; + } + const config = await this.interop.invoke(ThemesConfigurationMethodName); + this.sharedContextName = config.returned.sharedContextName; + this.getMethodName = config.returned.getThemesMethodName; + this.setMethodName = config.returned.setThemesMethodName; + } + catch (error) { + return; + } + } + async getAll() { + await this.getConfiguration(); + return await this.interop.invoke(this.getMethodName); + } + async subscribe() { + await this.getConfiguration(); + if (this.isSubscribed) { + return; + } + this.isSubscribed = true; + this.contexts.subscribe(this.sharedContextName, (data) => { + if (data && data.all && data.selected) { + this.registry.execute("changed", data.all.find((t) => t.name === data.selected)); + } + }); + } + } + + function factory$2(contexts, interop) { + const themes = new ThemesImpl(contexts, interop); + return { + list: themes.list.bind(themes), + getCurrent: themes.getCurrent.bind(themes), + select: themes.select.bind(themes), + onChanged: themes.onChanged.bind(themes), + ready: () => Promise.resolve(), + }; + } + + const connectBrowserAppProps = ["name", "title", "version", "customProperties", "icon", "caption", "type"]; + const fdc3v2AppProps = ["appId", "name", "type", "details", "version", "title", "tooltip", "lang", "description", "categories", "icons", "screenshots", "contactEmail", "moreInfo", "publisher", "customConfig", "hostManifests", "interop", "localizedVersions"]; + + /** + * Wraps values in an `Ok` type. + * + * Example: `ok(5) // => {ok: true, result: 5}` + */ + var ok = function (result) { return ({ ok: true, result: result }); }; + /** + * Wraps errors in an `Err` type. + * + * Example: `err('on fire') // => {ok: false, error: 'on fire'}` + */ + var err = function (error) { return ({ ok: false, error: error }); }; + /** + * Create a `Promise` that either resolves with the result of `Ok` or rejects + * with the error of `Err`. + */ + var asPromise = function (r) { + return r.ok === true ? Promise.resolve(r.result) : Promise.reject(r.error); + }; + /** + * Unwraps a `Result` and returns either the result of an `Ok`, or + * `defaultValue`. + * + * Example: + * ``` + * Result.withDefault(5, number().run(json)) + * ``` + * + * It would be nice if `Decoder` had an instance method that mirrored this + * function. Such a method would look something like this: + * ``` + * class Decoder { + * runWithDefault = (defaultValue: A, json: any): A => + * Result.withDefault(defaultValue, this.run(json)); + * } + * + * number().runWithDefault(5, json) + * ``` + * Unfortunately, the type of `defaultValue: A` on the method causes issues + * with type inference on the `object` decoder in some situations. While these + * inference issues can be solved by providing the optional type argument for + * `object`s, the extra trouble and confusion doesn't seem worth it. + */ + var withDefault = function (defaultValue, r) { + return r.ok === true ? r.result : defaultValue; + }; + /** + * Return the successful result, or throw an error. + */ + var withException = function (r) { + if (r.ok === true) { + return r.result; + } + else { + throw r.error; + } + }; + /** + * Apply `f` to the result of an `Ok`, or pass the error through. + */ + var map = function (f, r) { + return r.ok === true ? ok(f(r.result)) : r; + }; + /** + * Apply `f` to the result of two `Ok`s, or pass an error through. If both + * `Result`s are errors then the first one is returned. + */ + var map2 = function (f, ar, br) { + return ar.ok === false ? ar : + br.ok === false ? br : + ok(f(ar.result, br.result)); + }; + /** + * Apply `f` to the error of an `Err`, or pass the success through. + */ + var mapError = function (f, r) { + return r.ok === true ? r : err(f(r.error)); + }; + /** + * Chain together a sequence of computations that may fail, similar to a + * `Promise`. If the first computation fails then the error will propagate + * through. If it succeeds, then `f` will be applied to the value, returning a + * new `Result`. + */ + var andThen = function (f, r) { + return r.ok === true ? f(r.result) : r; + }; + + /*! ***************************************************************************** + Copyright (c) Microsoft Corporation. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THIS SOFTWARE. + ***************************************************************************** */ + /* global Reflect, Promise */ + + + + var __assign = function() { + __assign = Object.assign || function __assign(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; + } + return t; + }; + return __assign.apply(this, arguments); + }; + + function __rest(s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { + if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) + t[p[i]] = s[p[i]]; + } + return t; + } + + function isEqual(a, b) { + if (a === b) { + return true; + } + if (a === null && b === null) { + return true; + } + if (typeof (a) !== typeof (b)) { + return false; + } + if (typeof (a) === 'object') { + // Array + if (Array.isArray(a)) { + if (!Array.isArray(b)) { + return false; + } + if (a.length !== b.length) { + return false; + } + for (var i = 0; i < a.length; i++) { + if (!isEqual(a[i], b[i])) { + return false; + } + } + return true; + } + // Hash table + var keys = Object.keys(a); + if (keys.length !== Object.keys(b).length) { + return false; + } + for (var i = 0; i < keys.length; i++) { + if (!b.hasOwnProperty(keys[i])) { + return false; + } + if (!isEqual(a[keys[i]], b[keys[i]])) { + return false; + } + } + return true; + } + } + /* + * Helpers + */ + var isJsonArray = function (json) { return Array.isArray(json); }; + var isJsonObject = function (json) { + return typeof json === 'object' && json !== null && !isJsonArray(json); + }; + var typeString = function (json) { + switch (typeof json) { + case 'string': + return 'a string'; + case 'number': + return 'a number'; + case 'boolean': + return 'a boolean'; + case 'undefined': + return 'undefined'; + case 'object': + if (json instanceof Array) { + return 'an array'; + } + else if (json === null) { + return 'null'; + } + else { + return 'an object'; + } + default: + return JSON.stringify(json); + } + }; + var expectedGot = function (expected, got) { + return "expected " + expected + ", got " + typeString(got); + }; + var printPath = function (paths) { + return paths.map(function (path) { return (typeof path === 'string' ? "." + path : "[" + path + "]"); }).join(''); + }; + var prependAt = function (newAt, _a) { + var at = _a.at, rest = __rest(_a, ["at"]); + return (__assign({ at: newAt + (at || '') }, rest)); + }; + /** + * Decoders transform json objects with unknown structure into known and + * verified forms. You can create objects of type `Decoder` with either the + * primitive decoder functions, such as `boolean()` and `string()`, or by + * applying higher-order decoders to the primitives, such as `array(boolean())` + * or `dict(string())`. + * + * Each of the decoder functions are available both as a static method on + * `Decoder` and as a function alias -- for example the string decoder is + * defined at `Decoder.string()`, but is also aliased to `string()`. Using the + * function aliases exported with the library is recommended. + * + * `Decoder` exposes a number of 'run' methods, which all decode json in the + * same way, but communicate success and failure in different ways. The `map` + * and `andThen` methods modify decoders without having to call a 'run' method. + * + * Alternatively, the main decoder `run()` method returns an object of type + * `Result`. This library provides a number of helper + * functions for dealing with the `Result` type, so you can do all the same + * things with a `Result` as with the decoder methods. + */ + var Decoder = /** @class */ (function () { + /** + * The Decoder class constructor is kept private to separate the internal + * `decode` function from the external `run` function. The distinction + * between the two functions is that `decode` returns a + * `Partial` on failure, which contains an unfinished error + * report. When `run` is called on a decoder, the relevant series of `decode` + * calls is made, and then on failure the resulting `Partial` + * is turned into a `DecoderError` by filling in the missing information. + * + * While hiding the constructor may seem restrictive, leveraging the + * provided decoder combinators and helper functions such as + * `andThen` and `map` should be enough to build specialized decoders as + * needed. + */ + function Decoder(decode) { + var _this = this; + this.decode = decode; + /** + * Run the decoder and return a `Result` with either the decoded value or a + * `DecoderError` containing the json input, the location of the error, and + * the error message. + * + * Examples: + * ``` + * number().run(12) + * // => {ok: true, result: 12} + * + * string().run(9001) + * // => + * // { + * // ok: false, + * // error: { + * // kind: 'DecoderError', + * // input: 9001, + * // at: 'input', + * // message: 'expected a string, got 9001' + * // } + * // } + * ``` + */ + this.run = function (json) { + return mapError(function (error) { return ({ + kind: 'DecoderError', + input: json, + at: 'input' + (error.at || ''), + message: error.message || '' + }); }, _this.decode(json)); + }; + /** + * Run the decoder as a `Promise`. + */ + this.runPromise = function (json) { return asPromise(_this.run(json)); }; + /** + * Run the decoder and return the value on success, or throw an exception + * with a formatted error string. + */ + this.runWithException = function (json) { return withException(_this.run(json)); }; + /** + * Construct a new decoder that applies a transformation to the decoded + * result. If the decoder succeeds then `f` will be applied to the value. If + * it fails the error will propagated through. + * + * Example: + * ``` + * number().map(x => x * 5).run(10) + * // => {ok: true, result: 50} + * ``` + */ + this.map = function (f) { + return new Decoder(function (json) { return map(f, _this.decode(json)); }); + }; + /** + * Chain together a sequence of decoders. The first decoder will run, and + * then the function will determine what decoder to run second. If the result + * of the first decoder succeeds then `f` will be applied to the decoded + * value. If it fails the error will propagate through. + * + * This is a very powerful method -- it can act as both the `map` and `where` + * methods, can improve error messages for edge cases, and can be used to + * make a decoder for custom types. + * + * Example of adding an error message: + * ``` + * const versionDecoder = valueAt(['version'], number()); + * const infoDecoder3 = object({a: boolean()}); + * + * const decoder = versionDecoder.andThen(version => { + * switch (version) { + * case 3: + * return infoDecoder3; + * default: + * return fail(`Unable to decode info, version ${version} is not supported.`); + * } + * }); + * + * decoder.run({version: 3, a: true}) + * // => {ok: true, result: {a: true}} + * + * decoder.run({version: 5, x: 'abc'}) + * // => + * // { + * // ok: false, + * // error: {... message: 'Unable to decode info, version 5 is not supported.'} + * // } + * ``` + * + * Example of decoding a custom type: + * ``` + * // nominal type for arrays with a length of at least one + * type NonEmptyArray = T[] & { __nonEmptyArrayBrand__: void }; + * + * const nonEmptyArrayDecoder = (values: Decoder): Decoder> => + * array(values).andThen(arr => + * arr.length > 0 + * ? succeed(createNonEmptyArray(arr)) + * : fail(`expected a non-empty array, got an empty array`) + * ); + * ``` + */ + this.andThen = function (f) { + return new Decoder(function (json) { + return andThen(function (value) { return f(value).decode(json); }, _this.decode(json)); + }); + }; + /** + * Add constraints to a decoder _without_ changing the resulting type. The + * `test` argument is a predicate function which returns true for valid + * inputs. When `test` fails on an input, the decoder fails with the given + * `errorMessage`. + * + * ``` + * const chars = (length: number): Decoder => + * string().where( + * (s: string) => s.length === length, + * `expected a string of length ${length}` + * ); + * + * chars(5).run('12345') + * // => {ok: true, result: '12345'} + * + * chars(2).run('HELLO') + * // => {ok: false, error: {... message: 'expected a string of length 2'}} + * + * chars(12).run(true) + * // => {ok: false, error: {... message: 'expected a string, got a boolean'}} + * ``` + */ + this.where = function (test, errorMessage) { + return _this.andThen(function (value) { return (test(value) ? Decoder.succeed(value) : Decoder.fail(errorMessage)); }); + }; + } + /** + * Decoder primitive that validates strings, and fails on all other input. + */ + Decoder.string = function () { + return new Decoder(function (json) { + return typeof json === 'string' + ? ok(json) + : err({ message: expectedGot('a string', json) }); + }); + }; + /** + * Decoder primitive that validates numbers, and fails on all other input. + */ + Decoder.number = function () { + return new Decoder(function (json) { + return typeof json === 'number' + ? ok(json) + : err({ message: expectedGot('a number', json) }); + }); + }; + /** + * Decoder primitive that validates booleans, and fails on all other input. + */ + Decoder.boolean = function () { + return new Decoder(function (json) { + return typeof json === 'boolean' + ? ok(json) + : err({ message: expectedGot('a boolean', json) }); + }); + }; + Decoder.constant = function (value) { + return new Decoder(function (json) { + return isEqual(json, value) + ? ok(value) + : err({ message: "expected " + JSON.stringify(value) + ", got " + JSON.stringify(json) }); + }); + }; + Decoder.object = function (decoders) { + return new Decoder(function (json) { + if (isJsonObject(json) && decoders) { + var obj = {}; + for (var key in decoders) { + if (decoders.hasOwnProperty(key)) { + var r = decoders[key].decode(json[key]); + if (r.ok === true) { + // tslint:disable-next-line:strict-type-predicates + if (r.result !== undefined) { + obj[key] = r.result; + } + } + else if (json[key] === undefined) { + return err({ message: "the key '" + key + "' is required but was not present" }); + } + else { + return err(prependAt("." + key, r.error)); + } + } + } + return ok(obj); + } + else if (isJsonObject(json)) { + return ok(json); + } + else { + return err({ message: expectedGot('an object', json) }); + } + }); + }; + Decoder.array = function (decoder) { + return new Decoder(function (json) { + if (isJsonArray(json) && decoder) { + var decodeValue_1 = function (v, i) { + return mapError(function (err$$1) { return prependAt("[" + i + "]", err$$1); }, decoder.decode(v)); + }; + return json.reduce(function (acc, v, i) { + return map2(function (arr, result) { return arr.concat([result]); }, acc, decodeValue_1(v, i)); + }, ok([])); + } + else if (isJsonArray(json)) { + return ok(json); + } + else { + return err({ message: expectedGot('an array', json) }); + } + }); + }; + Decoder.tuple = function (decoders) { + return new Decoder(function (json) { + if (isJsonArray(json)) { + if (json.length !== decoders.length) { + return err({ + message: "expected a tuple of length " + decoders.length + ", got one of length " + json.length + }); + } + var result = []; + for (var i = 0; i < decoders.length; i++) { + var nth = decoders[i].decode(json[i]); + if (nth.ok) { + result[i] = nth.result; + } + else { + return err(prependAt("[" + i + "]", nth.error)); + } + } + return ok(result); + } + else { + return err({ message: expectedGot("a tuple of length " + decoders.length, json) }); + } + }); + }; + Decoder.union = function (ad, bd) { + var decoders = []; + for (var _i = 2; _i < arguments.length; _i++) { + decoders[_i - 2] = arguments[_i]; + } + return Decoder.oneOf.apply(Decoder, [ad, bd].concat(decoders)); + }; + Decoder.intersection = function (ad, bd) { + var ds = []; + for (var _i = 2; _i < arguments.length; _i++) { + ds[_i - 2] = arguments[_i]; + } + return new Decoder(function (json) { + return [ad, bd].concat(ds).reduce(function (acc, decoder) { return map2(Object.assign, acc, decoder.decode(json)); }, ok({})); + }); + }; + /** + * Escape hatch to bypass validation. Always succeeds and types the result as + * `any`. Useful for defining decoders incrementally, particularly for + * complex objects. + * + * Example: + * ``` + * interface User { + * name: string; + * complexUserData: ComplexType; + * } + * + * const userDecoder: Decoder = object({ + * name: string(), + * complexUserData: anyJson() + * }); + * ``` + */ + Decoder.anyJson = function () { return new Decoder(function (json) { return ok(json); }); }; + /** + * Decoder identity function which always succeeds and types the result as + * `unknown`. + */ + Decoder.unknownJson = function () { + return new Decoder(function (json) { return ok(json); }); + }; + /** + * Decoder for json objects where the keys are unknown strings, but the values + * should all be of the same type. + * + * Example: + * ``` + * dict(number()).run({chocolate: 12, vanilla: 10, mint: 37}); + * // => {ok: true, result: {chocolate: 12, vanilla: 10, mint: 37}} + * ``` + */ + Decoder.dict = function (decoder) { + return new Decoder(function (json) { + if (isJsonObject(json)) { + var obj = {}; + for (var key in json) { + if (json.hasOwnProperty(key)) { + var r = decoder.decode(json[key]); + if (r.ok === true) { + obj[key] = r.result; + } + else { + return err(prependAt("." + key, r.error)); + } + } + } + return ok(obj); + } + else { + return err({ message: expectedGot('an object', json) }); + } + }); + }; + /** + * Decoder for values that may be `undefined`. This is primarily helpful for + * decoding interfaces with optional fields. + * + * Example: + * ``` + * interface User { + * id: number; + * isOwner?: boolean; + * } + * + * const decoder: Decoder = object({ + * id: number(), + * isOwner: optional(boolean()) + * }); + * ``` + */ + Decoder.optional = function (decoder) { + return new Decoder(function (json) { return (json === undefined || json === null ? ok(undefined) : decoder.decode(json)); }); + }; + /** + * Decoder that attempts to run each decoder in `decoders` and either succeeds + * with the first successful decoder, or fails after all decoders have failed. + * + * Note that `oneOf` expects the decoders to all have the same return type, + * while `union` creates a decoder for the union type of all the input + * decoders. + * + * Examples: + * ``` + * oneOf(string(), number().map(String)) + * oneOf(constant('start'), constant('stop'), succeed('unknown')) + * ``` + */ + Decoder.oneOf = function () { + var decoders = []; + for (var _i = 0; _i < arguments.length; _i++) { + decoders[_i] = arguments[_i]; + } + return new Decoder(function (json) { + var errors = []; + for (var i = 0; i < decoders.length; i++) { + var r = decoders[i].decode(json); + if (r.ok === true) { + return r; + } + else { + errors[i] = r.error; + } + } + var errorsList = errors + .map(function (error) { return "at error" + (error.at || '') + ": " + error.message; }) + .join('", "'); + return err({ + message: "expected a value matching one of the decoders, got the errors [\"" + errorsList + "\"]" + }); + }); + }; + /** + * Decoder that always succeeds with either the decoded value, or a fallback + * default value. + */ + Decoder.withDefault = function (defaultValue, decoder) { + return new Decoder(function (json) { + return ok(withDefault(defaultValue, decoder.decode(json))); + }); + }; + /** + * Decoder that pulls a specific field out of a json structure, instead of + * decoding and returning the full structure. The `paths` array describes the + * object keys and array indices to traverse, so that values can be pulled out + * of a nested structure. + * + * Example: + * ``` + * const decoder = valueAt(['a', 'b', 0], string()); + * + * decoder.run({a: {b: ['surprise!']}}) + * // => {ok: true, result: 'surprise!'} + * + * decoder.run({a: {x: 'cats'}}) + * // => {ok: false, error: {... at: 'input.a.b[0]' message: 'path does not exist'}} + * ``` + * + * Note that the `decoder` is ran on the value found at the last key in the + * path, even if the last key is not found. This allows the `optional` + * decoder to succeed when appropriate. + * ``` + * const optionalDecoder = valueAt(['a', 'b', 'c'], optional(string())); + * + * optionalDecoder.run({a: {b: {c: 'surprise!'}}}) + * // => {ok: true, result: 'surprise!'} + * + * optionalDecoder.run({a: {b: 'cats'}}) + * // => {ok: false, error: {... at: 'input.a.b.c' message: 'expected an object, got "cats"'} + * + * optionalDecoder.run({a: {b: {z: 1}}}) + * // => {ok: true, result: undefined} + * ``` + */ + Decoder.valueAt = function (paths, decoder) { + return new Decoder(function (json) { + var jsonAtPath = json; + for (var i = 0; i < paths.length; i++) { + if (jsonAtPath === undefined) { + return err({ + at: printPath(paths.slice(0, i + 1)), + message: 'path does not exist' + }); + } + else if (typeof paths[i] === 'string' && !isJsonObject(jsonAtPath)) { + return err({ + at: printPath(paths.slice(0, i + 1)), + message: expectedGot('an object', jsonAtPath) + }); + } + else if (typeof paths[i] === 'number' && !isJsonArray(jsonAtPath)) { + return err({ + at: printPath(paths.slice(0, i + 1)), + message: expectedGot('an array', jsonAtPath) + }); + } + else { + jsonAtPath = jsonAtPath[paths[i]]; + } + } + return mapError(function (error) { + return jsonAtPath === undefined + ? { at: printPath(paths), message: 'path does not exist' } + : prependAt(printPath(paths), error); + }, decoder.decode(jsonAtPath)); + }); + }; + /** + * Decoder that ignores the input json and always succeeds with `fixedValue`. + */ + Decoder.succeed = function (fixedValue) { + return new Decoder(function (json) { return ok(fixedValue); }); + }; + /** + * Decoder that ignores the input json and always fails with `errorMessage`. + */ + Decoder.fail = function (errorMessage) { + return new Decoder(function (json) { return err({ message: errorMessage }); }); + }; + /** + * Decoder that allows for validating recursive data structures. Unlike with + * functions, decoders assigned to variables can't reference themselves + * before they are fully defined. We can avoid prematurely referencing the + * decoder by wrapping it in a function that won't be called until use, at + * which point the decoder has been defined. + * + * Example: + * ``` + * interface Comment { + * msg: string; + * replies: Comment[]; + * } + * + * const decoder: Decoder = object({ + * msg: string(), + * replies: lazy(() => array(decoder)) + * }); + * ``` + */ + Decoder.lazy = function (mkDecoder) { + return new Decoder(function (json) { return mkDecoder().decode(json); }); + }; + return Decoder; + }()); + + /* tslint:disable:variable-name */ + /** See `Decoder.string` */ + var string = Decoder.string; + /** See `Decoder.number` */ + var number = Decoder.number; + /** See `Decoder.boolean` */ + var boolean = Decoder.boolean; + /** See `Decoder.anyJson` */ + var anyJson = Decoder.anyJson; + /** See `Decoder.unknownJson` */ + Decoder.unknownJson; + /** See `Decoder.constant` */ + var constant = Decoder.constant; + /** See `Decoder.object` */ + var object = Decoder.object; + /** See `Decoder.array` */ + var array = Decoder.array; + /** See `Decoder.tuple` */ + Decoder.tuple; + /** See `Decoder.dict` */ + var dict = Decoder.dict; + /** See `Decoder.optional` */ + var optional = Decoder.optional; + /** See `Decoder.oneOf` */ + var oneOf = Decoder.oneOf; + /** See `Decoder.union` */ + Decoder.union; + /** See `Decoder.intersection` */ + Decoder.intersection; + /** See `Decoder.withDefault` */ + Decoder.withDefault; + /** See `Decoder.valueAt` */ + Decoder.valueAt; + /** See `Decoder.succeed` */ + Decoder.succeed; + /** See `Decoder.fail` */ + Decoder.fail; + /** See `Decoder.lazy` */ + Decoder.lazy; + + const nonEmptyStringDecoder = string().where((s) => s.length > 0, "Expected a non-empty string"); + const nonNegativeNumberDecoder = number().where((num) => num >= 0, "Expected a non-negative number"); + + const intentDefinitionDecoder = object({ + name: nonEmptyStringDecoder, + displayName: optional(string()), + contexts: optional(array(string())), + customConfig: optional(object()) + }); + const v2TypeDecoder = oneOf(constant("web"), constant("native"), constant("citrix"), constant("onlineNative"), constant("other")); + const v2DetailsDecoder = object({ + url: nonEmptyStringDecoder + }); + const v2IconDecoder = object({ + src: nonEmptyStringDecoder, + size: optional(nonEmptyStringDecoder), + type: optional(nonEmptyStringDecoder) + }); + const v2ScreenshotDecoder = object({ + src: nonEmptyStringDecoder, + size: optional(nonEmptyStringDecoder), + type: optional(nonEmptyStringDecoder), + label: optional(nonEmptyStringDecoder) + }); + const v2ListensForIntentDecoder = object({ + contexts: array(nonEmptyStringDecoder), + displayName: optional(nonEmptyStringDecoder), + resultType: optional(nonEmptyStringDecoder), + customConfig: optional(anyJson()) + }); + const v2IntentsDecoder = object({ + listensFor: optional(dict(v2ListensForIntentDecoder)), + raises: optional(dict(array(nonEmptyStringDecoder))) + }); + const v2UserChannelDecoder = object({ + broadcasts: optional(array(nonEmptyStringDecoder)), + listensFor: optional(array(nonEmptyStringDecoder)) + }); + const v2AppChannelDecoder = object({ + name: nonEmptyStringDecoder, + description: optional(nonEmptyStringDecoder), + broadcasts: optional(array(nonEmptyStringDecoder)), + listensFor: optional(array(nonEmptyStringDecoder)) + }); + const v2InteropDecoder = object({ + intents: optional(v2IntentsDecoder), + userChannels: optional(v2UserChannelDecoder), + appChannels: optional(array(v2AppChannelDecoder)) + }); + const glue42ApplicationDetailsDecoder = object({ + url: optional(nonEmptyStringDecoder), + top: optional(number()), + left: optional(number()), + width: optional(nonNegativeNumberDecoder), + height: optional(nonNegativeNumberDecoder) + }); + const glue42HostManifestsBrowserDecoder = object({ + name: optional(nonEmptyStringDecoder), + type: optional(nonEmptyStringDecoder.where((s) => s === "window", "Expected a value of window")), + title: optional(nonEmptyStringDecoder), + version: optional(nonEmptyStringDecoder), + customProperties: optional(anyJson()), + icon: optional(string()), + caption: optional(string()), + details: optional(glue42ApplicationDetailsDecoder), + intents: optional(array(intentDefinitionDecoder)), + hidden: optional(boolean()) + }); + const v1DefinitionDecoder = object({ + name: nonEmptyStringDecoder, + appId: nonEmptyStringDecoder, + title: optional(nonEmptyStringDecoder), + version: optional(nonEmptyStringDecoder), + manifest: nonEmptyStringDecoder, + manifestType: nonEmptyStringDecoder, + tooltip: optional(nonEmptyStringDecoder), + description: optional(nonEmptyStringDecoder), + contactEmail: optional(nonEmptyStringDecoder), + supportEmail: optional(nonEmptyStringDecoder), + publisher: optional(nonEmptyStringDecoder), + images: optional(array(object({ url: optional(nonEmptyStringDecoder) }))), + icons: optional(array(object({ icon: optional(nonEmptyStringDecoder) }))), + customConfig: anyJson(), + intents: optional(array(intentDefinitionDecoder)) + }); + const v2LocalizedDefinitionDecoder = object({ + appId: optional(nonEmptyStringDecoder), + name: optional(nonEmptyStringDecoder), + details: optional(v2DetailsDecoder), + version: optional(nonEmptyStringDecoder), + title: optional(nonEmptyStringDecoder), + tooltip: optional(nonEmptyStringDecoder), + lang: optional(nonEmptyStringDecoder), + description: optional(nonEmptyStringDecoder), + categories: optional(array(nonEmptyStringDecoder)), + icons: optional(array(v2IconDecoder)), + screenshots: optional(array(v2ScreenshotDecoder)), + contactEmail: optional(nonEmptyStringDecoder), + supportEmail: optional(nonEmptyStringDecoder), + moreInfo: optional(nonEmptyStringDecoder), + publisher: optional(nonEmptyStringDecoder), + customConfig: optional(array(anyJson())), + hostManifests: optional(anyJson()), + interop: optional(v2InteropDecoder) + }); + const v2DefinitionDecoder = object({ + appId: nonEmptyStringDecoder, + name: nonEmptyStringDecoder, + type: v2TypeDecoder, + details: v2DetailsDecoder, + version: optional(nonEmptyStringDecoder), + title: optional(nonEmptyStringDecoder), + tooltip: optional(nonEmptyStringDecoder), + lang: optional(nonEmptyStringDecoder), + description: optional(nonEmptyStringDecoder), + categories: optional(array(nonEmptyStringDecoder)), + icons: optional(array(v2IconDecoder)), + screenshots: optional(array(v2ScreenshotDecoder)), + contactEmail: optional(nonEmptyStringDecoder), + supportEmail: optional(nonEmptyStringDecoder), + moreInfo: optional(nonEmptyStringDecoder), + publisher: optional(nonEmptyStringDecoder), + customConfig: optional(array(anyJson())), + hostManifests: optional(anyJson()), + interop: optional(v2InteropDecoder), + localizedVersions: optional(dict(v2LocalizedDefinitionDecoder)) + }); + const allDefinitionsDecoder = oneOf(v1DefinitionDecoder, v2DefinitionDecoder); + + const parseDecoderErrorToStringMessage = (error) => { + return `${error.kind} at ${error.at}: ${JSON.stringify(error.input)}. Reason - ${error.message}`; + }; + + class FDC3Service { + fdc3ToDesktopDefinitionType = { + web: "window", + native: "exe", + citrix: "citrix", + onlineNative: "clickonce", + other: "window" + }; + toApi() { + return { + isFdc3Definition: this.isFdc3Definition.bind(this), + parseToBrowserBaseAppData: this.parseToBrowserBaseAppData.bind(this), + parseToDesktopAppConfig: this.parseToDesktopAppConfig.bind(this) + }; + } + isFdc3Definition(definition) { + const decodeRes = allDefinitionsDecoder.run(definition); + if (!decodeRes.ok) { + return { isFdc3: false, reason: parseDecoderErrorToStringMessage(decodeRes.error) }; + } + if (definition.appId && definition.details) { + return { isFdc3: true, version: "2.0" }; + } + if (definition.manifest) { + return { isFdc3: true, version: "1.2" }; + } + return { isFdc3: false, reason: "The passed definition is not FDC3" }; + } + parseToBrowserBaseAppData(definition) { + const { isFdc3, version } = this.isFdc3Definition(definition); + if (!isFdc3) { + throw new Error("The passed definition is not FDC3"); + } + const decodeRes = allDefinitionsDecoder.run(definition); + if (!decodeRes.ok) { + throw new Error(`Invalid FDC3 ${version} definition. Error: ${parseDecoderErrorToStringMessage(decodeRes.error)}`); + } + const userProperties = this.getUserPropertiesFromDefinition(definition, version); + const createOptions = { url: this.getUrl(definition, version) }; + const baseApplicationData = { + name: definition.appId, + type: "window", + createOptions, + userProperties: { + ...userProperties, + intents: version === "1.2" + ? userProperties.intents + : this.getIntentsFromV2AppDefinition(definition), + details: createOptions + }, + title: definition.title, + version: definition.version, + icon: this.getIconFromDefinition(definition, version), + caption: definition.description, + fdc3: version === "2.0" ? { ...definition, definitionVersion: "2.0" } : undefined, + }; + const ioConnectDefinition = definition.hostManifests?.ioConnect || definition.hostManifests?.["Glue42"]; + if (!ioConnectDefinition) { + return baseApplicationData; + } + const ioDefinitionDecodeRes = glue42HostManifestsBrowserDecoder.run(ioConnectDefinition); + if (!ioDefinitionDecodeRes.ok) { + throw new Error(`Invalid FDC3 ${version} definition. Error: ${parseDecoderErrorToStringMessage(ioDefinitionDecodeRes.error)}`); + } + if (!Object.keys(ioDefinitionDecodeRes.result).length) { + return baseApplicationData; + } + return this.mergeBaseAppDataWithGlueManifest(baseApplicationData, ioDefinitionDecodeRes.result); + } + parseToDesktopAppConfig(definition) { + const { isFdc3, version } = this.isFdc3Definition(definition); + if (!isFdc3) { + throw new Error("The passed definition is not FDC3"); + } + const decodeRes = allDefinitionsDecoder.run(definition); + if (!decodeRes.ok) { + throw new Error(`Invalid FDC3 ${version} definition. Error: ${parseDecoderErrorToStringMessage(decodeRes.error)}`); + } + if (version === "1.2") { + const fdc3v1Definition = definition; + return { + name: fdc3v1Definition.appId, + type: "window", + details: { + url: this.getUrl(definition, version) + }, + version: fdc3v1Definition.version, + title: fdc3v1Definition.title, + tooltip: fdc3v1Definition.tooltip, + caption: fdc3v1Definition.description, + icon: fdc3v1Definition.icons?.[0].icon, + intents: fdc3v1Definition.intents, + customProperties: { + manifestType: fdc3v1Definition.manifestType, + images: fdc3v1Definition.images, + contactEmail: fdc3v1Definition.contactEmail, + supportEmail: fdc3v1Definition.supportEmail, + publisher: fdc3v1Definition.publisher, + icons: fdc3v1Definition.icons, + customConfig: fdc3v1Definition.customConfig + } + }; + } + const fdc3v2Definition = definition; + const desktopDefinition = { + name: fdc3v2Definition.appId, + type: this.fdc3ToDesktopDefinitionType[fdc3v2Definition.type], + details: fdc3v2Definition.details, + version: fdc3v2Definition.version, + title: fdc3v2Definition.title, + tooltip: fdc3v2Definition.tooltip, + caption: fdc3v2Definition.description, + icon: this.getIconFromDefinition(fdc3v2Definition, "2.0"), + intents: this.getIntentsFromV2AppDefinition(fdc3v2Definition), + fdc3: { ...fdc3v2Definition, definitionVersion: "2.0" } + }; + const ioConnectDefinition = definition.hostManifests?.ioConnect || definition.hostManifests?.["Glue42"]; + if (!ioConnectDefinition) { + return desktopDefinition; + } + if (typeof ioConnectDefinition !== "object" || Array.isArray(ioConnectDefinition)) { + throw new Error(`Invalid '${definition.hostManifests.ioConnect ? "hostManifests.ioConnect" : "hostManifests['Glue42']"}' key`); + } + return this.mergeDesktopConfigWithGlueManifest(desktopDefinition, ioConnectDefinition); + } + getUserPropertiesFromDefinition(definition, version) { + if (version === "1.2") { + return Object.fromEntries(Object.entries(definition).filter(([key]) => !connectBrowserAppProps.includes(key))); + } + return Object.fromEntries(Object.entries(definition).filter(([key]) => !connectBrowserAppProps.includes(key) && !fdc3v2AppProps.includes(key))); + } + getUrl(definition, version) { + let url; + if (version === "1.2") { + const parsedManifest = JSON.parse(definition.manifest); + url = parsedManifest.details?.url || parsedManifest.url; + } + else { + url = definition.details?.url; + } + if (!url || typeof url !== "string") { + throw new Error(`Invalid FDC3 ${version} definition. Provide valid 'url' under '${version === "1.2" ? "manifest" : "details"}' key`); + } + return url; + } + getIntentsFromV2AppDefinition(definition) { + const fdc3Intents = definition.interop?.intents?.listensFor; + if (!fdc3Intents) { + return; + } + const intents = Object.entries(fdc3Intents).map((fdc3Intent) => { + const [intentName, intentData] = fdc3Intent; + return { + name: intentName, + ...intentData + }; + }); + return intents; + } + getIconFromDefinition(definition, version) { + if (version === "1.2") { + return definition.icons?.find((iconDef) => iconDef.icon)?.icon || undefined; + } + return definition.icons?.find((iconDef) => iconDef.src)?.src || undefined; + } + mergeBaseAppDataWithGlueManifest(baseAppData, hostManifestDefinition) { + let baseApplicationDefinition = baseAppData; + if (hostManifestDefinition.details) { + const details = { ...baseAppData.createOptions, ...hostManifestDefinition.details }; + baseApplicationDefinition.createOptions = details; + baseApplicationDefinition.userProperties.details = details; + } + if (Array.isArray(hostManifestDefinition.intents)) { + baseApplicationDefinition.userProperties.intents = (baseApplicationDefinition.userProperties.intents || []).concat(hostManifestDefinition.intents); + } + baseApplicationDefinition = { ...baseApplicationDefinition, ...hostManifestDefinition }; + delete baseApplicationDefinition.details; + delete baseApplicationDefinition.intents; + return baseApplicationDefinition; + } + mergeDesktopConfigWithGlueManifest(config, desktopDefinition) { + const appConfig = Object.assign({}, config, desktopDefinition, { details: { ...config.details, ...desktopDefinition.details } }); + if (Array.isArray(desktopDefinition.intents)) { + appConfig.intents = (config.intents || []).concat(desktopDefinition.intents); + } + return appConfig; + } + } + + const decoders$1 = { + common: { + nonEmptyStringDecoder, + nonNegativeNumberDecoder + }, + fdc3: { + allDefinitionsDecoder, + v1DefinitionDecoder, + v2DefinitionDecoder + } + }; + + var INTENTS_ERRORS; + (function (INTENTS_ERRORS) { + INTENTS_ERRORS["USER_CANCELLED"] = "User Closed Intents Resolver UI without choosing a handler"; + INTENTS_ERRORS["CALLER_NOT_DEFINED"] = "Caller Id is not defined"; + INTENTS_ERRORS["TIMEOUT_HIT"] = "Timeout hit"; + INTENTS_ERRORS["INTENT_NOT_FOUND"] = "Cannot find Intent"; + INTENTS_ERRORS["HANDLER_NOT_FOUND"] = "Cannot find Intent Handler"; + INTENTS_ERRORS["TARGET_INSTANCE_UNAVAILABLE"] = "Cannot start Target Instance"; + INTENTS_ERRORS["INTENT_DELIVERY_FAILED"] = "Target Instance did not add a listener"; + INTENTS_ERRORS["RESOLVER_UNAVAILABLE"] = "Intents Resolver UI unavailable"; + INTENTS_ERRORS["RESOLVER_TIMEOUT"] = "User did not choose a handler"; + INTENTS_ERRORS["INVALID_RESOLVER_RESPONSE"] = "Intents Resolver UI returned invalid response"; + INTENTS_ERRORS["INTENT_HANDLER_REJECTION"] = "Intent Handler function processing the raised intent threw an error or rejected the promise it returned"; + })(INTENTS_ERRORS || (INTENTS_ERRORS = {})); + + class IoC { + _fdc3; + _decoders = decoders$1; + _errors = { + intents: INTENTS_ERRORS + }; + get fdc3() { + if (!this._fdc3) { + this._fdc3 = new FDC3Service().toApi(); + } + return this._fdc3; + } + get decoders() { + return this._decoders; + } + get errors() { + return this._errors; + } + } + + const ioc = new IoC(); + ioc.fdc3; + ioc.decoders; + const errors = ioc.errors; + + const GLUE42_FDC3_INTENTS_METHOD_PREFIX = "Tick42.FDC3.Intents."; + const INTENTS_RESOLVER_INTEROP_PREFIX = "T42.Intents.Resolver.Control"; + const INTENTS_RESOLVER_WIDTH = 400; + const INTENTS_RESOLVER_HEIGHT = 440; + const DEFAULT_RESOLVER_RESPONSE_TIMEOUT = 60 * 1000; + const INTENT_HANDLER_DEFAULT_PROPS = ["applicationName", "type"]; + const INTENTS_RESOLVER_APP_NAME = "intentsResolver"; + const MAX_SET_TIMEOUT_DELAY = 2147483647; + const DEFAULT_METHOD_RESPONSE_TIMEOUT_MS = 60 * 1000; + const DEFAULT_RAISE_TIMEOUT_MS = 90 * 1000; + const DEFAULT_PICK_HANDLER_BY_TIMEOUT_MS = 90 * 1000; + const ERRORS = errors.intents; + + const PromisePlus = (executor, timeoutMilliseconds, timeoutMessage) => { + return new Promise((resolve, reject) => { + const timeout = setTimeout(() => { + const message = timeoutMessage || `Promise timeout hit: ${timeoutMilliseconds}`; + reject(message); + }, timeoutMilliseconds); + const providedPromise = new Promise(executor); + providedPromise + .then((result) => { + clearTimeout(timeout); + resolve(result); + }) + .catch((error) => { + clearTimeout(timeout); + reject(error); + }); + }); + }; + const PromiseWrap = (promise, timeoutMilliseconds, timeoutMessage) => { + return new Promise((resolve, reject) => { + let promiseActive = true; + const timeout = setTimeout(() => { + if (!promiseActive) { + return; + } + promiseActive = false; + const message = timeoutMessage || `Promise timeout hit: ${timeoutMilliseconds}`; + reject(message); + }, timeoutMilliseconds); + promise() + .then((result) => { + if (!promiseActive) { + return; + } + promiseActive = false; + clearTimeout(timeout); + resolve(result); + }) + .catch((error) => { + if (!promiseActive) { + return; + } + promiseActive = false; + clearTimeout(timeout); + reject(error); + }); + }); + }; + + const validateIntentHandlerAsResponse = (handler) => { + if (typeof handler !== "object") { + return { isValid: false, error: `Response object has invalid 'handler' key. Expected an object, got ${typeof handler}` }; + } + const compulsoryKeysExist = INTENT_HANDLER_DEFAULT_PROPS.filter((key) => !(key in handler)); + if (compulsoryKeysExist.length) { + return { isValid: false, error: `Handler in Response object does not provide compulsory keys: ${compulsoryKeysExist.join(", ")}` }; + } + return { isValid: true, ok: handler }; + }; + const validateIntentRequestTarget = (target) => { + if (!target) { + return; + } + if (typeof target !== "string" && typeof target !== "object") { + throw new Error(`Please provide the intent target as one of the valid values: "reuse", "startNew", { app: string }, { instance: string } `); + } + }; + const validateIntentRequestContext = (context) => { + if (!context) { + return; + } + if (typeof context !== "object") { + throw new Error(`Please provide the intent context as an object`); + } + if (context.type && typeof context.type !== "string") { + throw new Error(`Please provide the intent context as an object with 'type' property as string`); + } + if (context.data && typeof context.data !== "object") { + throw new Error(`Please provide the intent context as an object with 'data' property as object`); + } + }; + const validateIntentRequestHandler = (handler) => { + if (!handler.applicationName) { + throw new Error(`Please provide applicationName for handler ${JSON.stringify(handler)}`); + } + if (!handler.type) { + throw new Error(`Please provide type for handler ${JSON.stringify(handler)}`); + } + if (handler.type === "instance" && !handler.instanceId) { + throw new Error(`Please provide instanceId for handler ${JSON.stringify(handler)}`); + } + }; + const validateIntentRequestTimeout = (timeout) => { + if (!timeout) { + return; + } + if (typeof timeout !== "number") { + throw new Error(`Please provide the timeout as a number`); + } + if (timeout <= 0) { + throw new Error(`Please provide the timeout as a positive number`); + } + }; + const validateWaitUserResponseIndefinitely = (waitUserResponseIndefinitely) => { + if (!waitUserResponseIndefinitely) { + return; + } + if (typeof waitUserResponseIndefinitely !== "boolean") { + throw new Error("Please provide waitUserResponseIndefinitely as a boolean"); + } + }; + const validateHandlerFilter = (handlerFilter) => { + if (!handlerFilter) { + throw new Error(`Provide 'handlerFilter' with at least one filter criteria of the following: 'intent' | 'contextTypes' | 'resultType' | 'applicationNames'`); + } + const { title, openResolver, timeout, intent, contextTypes, resultType, applicationNames } = handlerFilter; + if (typeof title !== "undefined" && (typeof title !== "string" || !title.length)) { + throw new Error(`Provide 'title' as a non empty string`); + } + if (typeof openResolver !== "undefined" && typeof openResolver !== "boolean") { + throw new Error(`Provide 'openResolver' prop as a boolean`); + } + if (typeof timeout !== "undefined" && (typeof timeout !== "number" || timeout <= 0)) { + throw new Error(`Provide 'timeout' prop as a positive number`); + } + if (typeof intent !== "undefined" && (typeof intent !== "string" || !intent.length)) { + throw new Error(`Provide 'intent' as a non empty string`); + } + if (typeof contextTypes !== "undefined" && (!Array.isArray(contextTypes) || contextTypes.some(ctx => typeof ctx !== "string"))) { + throw new Error(`Provide 'contextTypes' as an array of non empty strings`); + } + if (typeof resultType !== "undefined" && (typeof resultType !== "string" || !resultType.length)) { + throw new Error(`Provide 'resultType' as a non empty string`); + } + if (typeof applicationNames !== "undefined" && (!Array.isArray(applicationNames) || applicationNames.some(appName => typeof appName !== "string"))) { + throw new Error(`Provide 'applicationNames' as an array of non empty strings`); + } + const errorMsg = "Provide at least one filter criteria of the following: 'intent' | 'contextTypes' | 'resultType' | 'applicationNames'"; + if (!Object.keys(handlerFilter).length) { + throw new Error(errorMsg); + } + if (!intent && !resultType && (!contextTypes || !contextTypes.length) && (!applicationNames || !applicationNames.length)) { + throw new Error(errorMsg); + } + }; + const validateResolverResponse = (responseObj) => { + var _a, _b; + if (typeof responseObj.intent !== "string") { + return { isValid: false, error: `Response object has invalid 'intent' key. Expected a string, got ${typeof responseObj.intent}` }; + } + if (((_a = responseObj.userSettings) === null || _a === void 0 ? void 0 : _a.preserveChoice) && typeof ((_b = responseObj.userSettings) === null || _b === void 0 ? void 0 : _b.preserveChoice) !== "boolean") { + return { isValid: false, error: `Response object has invalid 'userSettings.preserveChoice' key. Expected a boolean, got ${typeof responseObj.userSettings.preserveChoice}` }; + } + const { isValid, error } = validateIntentHandlerAsResponse(responseObj.handler); + return isValid + ? { isValid: true, ok: responseObj } + : { isValid, error }; + }; + const validateIntentRequest = (request) => { + validateIntentRequestContext(request.context); + validateIntentRequestTarget(request.target); + validateIntentRequestTimeout(request.timeout); + validateWaitUserResponseIndefinitely(request.waitUserResponseIndefinitely); + if (typeof request.clearSavedHandler !== "undefined" && typeof request.clearSavedHandler !== "boolean") { + throw new Error("Please provide 'clearSavedHandler' as a boolean"); + } + if (request.handlers) { + request.handlers.forEach((handler) => validateIntentRequestHandler(handler)); + } + }; + const validateIntentHandler = (handler) => { + if (typeof handler !== "object") { + throw new Error("IntentHandler must be an object"); + } + if (typeof handler.applicationName !== "string" || !handler.applicationName.length) { + throw new Error(`Please provide 'applicationName' as a non-empty string`); + } + if (typeof handler.type !== "string" || !["app", "instance"].includes(handler.type)) { + throw new Error(`Invalid 'type' property. Expected 'app' | 'instance' got ${handler.type}`); + } + if (typeof handler.applicationTitle !== "undefined" && typeof handler.applicationTitle !== "string") { + throw new Error(`Provide 'applicationTitle' as a string`); + } + if (typeof handler.applicationDescription !== "undefined" && typeof handler.applicationDescription !== "string") { + throw new Error(`Provide 'applicationDescription' as a string`); + } + if (typeof handler.applicationIcon !== "undefined" && typeof handler.applicationIcon !== "string") { + throw new Error(`Provide 'applicationIcon' as a string`); + } + if (typeof handler.displayName !== "undefined" && typeof handler.displayName !== "string") { + throw new Error(`Provide 'displayName' as a string`); + } + if (typeof handler.contextTypes !== "undefined" && (!Array.isArray(handler.contextTypes) || handler.contextTypes.some(ctx => typeof ctx !== "string"))) { + throw new Error(`Provide 'contextTypes' as an array of non empty strings`); + } + if (typeof handler.instanceId !== "undefined" && typeof handler.instanceId !== "string") { + throw new Error(`Provide 'instanceId' as a string`); + } + if (typeof handler.instanceTitle !== "undefined" && typeof handler.instanceTitle !== "string") { + throw new Error(`Provide 'instanceTitle' as a string`); + } + if (typeof handler.resultType !== "undefined" && typeof handler.resultType !== "string") { + throw new Error(`Provide 'resultType' as a string`); + } + }; + const clearNullUndefined = (obj) => { + Object.keys(obj).forEach(key => { + if (obj[key] === null || obj[key] === undefined) { + delete obj[key]; + } + }); + }; + + class Intents { + constructor(interop, windows, logger, options, prefsController, appManager) { + this.interop = interop; + this.windows = windows; + this.logger = logger; + this.prefsController = prefsController; + this.appManager = appManager; + this.myIntents = new Set(); + this.intentsResolverResponsePromises = {}; + this.useIntentsResolverUI = true; + this.unregisterIntentPromises = []; + this.addedHandlerInfoPerApp = {}; + this.checkIfIntentsResolverIsEnabled(options, appManager); + } + async find(intentFilter) { + await Promise.all(this.unregisterIntentPromises); + let intents = await this.all(); + if (typeof intentFilter === "undefined") { + return intents; + } + if (typeof intentFilter === "string") { + return intents.filter((intent) => intent.name === intentFilter); + } + if (typeof intentFilter !== "object") { + throw new Error("Please provide the intentFilter as a string or an object!"); + } + if (intentFilter.contextType) { + const ctToLower = intentFilter.contextType.toLowerCase(); + intents = intents.filter((intent) => intent.handlers.some((handler) => { var _a; return (_a = handler.contextTypes) === null || _a === void 0 ? void 0 : _a.some((ct) => ct.toLowerCase() === ctToLower); })); + } + if (intentFilter.resultType) { + const resultTypeToLower = intentFilter.resultType.toLowerCase(); + intents = intents.filter((intent) => intent.handlers.some((handler) => { var _a; return ((_a = handler.resultType) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === resultTypeToLower; })); + } + if (intentFilter.name) { + intents = intents.filter((intent) => intent.name === intentFilter.name); + } + return intents; + } + async raise(intentRequest) { + if ((typeof intentRequest !== "string" && typeof intentRequest !== "object") || (typeof intentRequest === "object" && typeof intentRequest.intent !== "string")) { + throw new Error("Please provide the intent as a string or an object with an intent property!"); + } + if (typeof intentRequest === "string") { + intentRequest = { intent: intentRequest }; + } + validateIntentRequest(intentRequest); + await Promise.all(this.unregisterIntentPromises); + if (intentRequest.clearSavedHandler) { + this.logger.trace(`User removes saved handler for intent ${intentRequest.intent}`); + await this.removeRememberedHandler(intentRequest.intent); + } + const resolverInstance = {}; + const timeout = intentRequest.waitUserResponseIndefinitely ? MAX_SET_TIMEOUT_DELAY : intentRequest.timeout || DEFAULT_RAISE_TIMEOUT_MS; + const resultFromRememberedHandler = await this.checkHandleRaiseWithRememberedHandler(intentRequest, resolverInstance, timeout); + if (resultFromRememberedHandler) { + return resultFromRememberedHandler; + } + const coreRaiseIntentFn = this.coreRaiseIntent.bind(this, { request: intentRequest, resolverInstance, timeout }); + if (intentRequest.waitUserResponseIndefinitely) { + return coreRaiseIntentFn(); + } + const resultPromise = PromiseWrap(coreRaiseIntentFn, timeout, `${ERRORS.TIMEOUT_HIT} hit for intent request ${JSON.stringify(intentRequest)}`); + resultPromise.catch(() => this.handleRaiseOnError(resolverInstance.instanceId)); + return resultPromise; + } + async all() { + await Promise.all(this.unregisterIntentPromises); + let apps; + try { + const result = await this.interop.invoke("T42.ACS.GetApplications", { withIntentsInfo: true }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + apps = result.returned.applications; + } + catch (e) { + this.logger.error(`Failed to get the applications!`, e); + return []; + } + const intents = {}; + const appsWithIntents = apps.filter((app) => app.intents && app.intents.length > 0); + for (const app of appsWithIntents) { + for (const intentDef of app.intents) { + let intent = intents[intentDef.name]; + if (!intent) { + intent = { + name: intentDef.name, + handlers: [], + }; + intents[intentDef.name] = intent; + } + const handler = { + applicationName: app.name, + applicationTitle: app.title || "", + applicationDescription: app.caption, + displayName: intentDef.displayName, + contextTypes: intentDef.contexts, + applicationIcon: app.icon, + type: "app", + resultType: intentDef.resultType + }; + intent.handlers.push(handler); + } + } + const servers = this.interop.servers(); + const serverWindowIds = servers.map((server) => server.windowId).filter((serverWindowId) => typeof serverWindowId !== "undefined"); + const T42WndGetInfo = "T42.Wnd.GetInfo"; + const isT42WndGetInfoMethodRegistered = this.interop.methods().some((method) => method.name === T42WndGetInfo); + let windowsInfos; + if (isT42WndGetInfoMethodRegistered) { + try { + const result = await this.interop.invoke(T42WndGetInfo, { ids: serverWindowIds }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + windowsInfos = result.returned.windows; + } + catch (e) { + } + } + for (const server of servers) { + await Promise.all(server.getMethods() + .filter((method) => method.name.startsWith(GLUE42_FDC3_INTENTS_METHOD_PREFIX)) + .map(async (method) => { + const intentName = method.name.replace(GLUE42_FDC3_INTENTS_METHOD_PREFIX, ""); + let intent = intents[intentName]; + if (!intent) { + intent = { + name: intentName, + handlers: [], + }; + intents[intentName] = intent; + } + const title = await this.windowsIdToTitle(server.windowId, windowsInfos); + const handler = this.constructIntentHandler({ method, apps, server, intentName, title }); + intent.handlers.push(handler); + })); + } + return Object.values(intents); + } + addIntentListener(intent, handler) { + if ((typeof intent !== "string" && typeof intent !== "object") || (typeof intent === "object" && typeof intent.intent !== "string")) { + throw new Error("Please provide the intent as a string or an object with an intent property!"); + } + if (typeof handler !== "function") { + throw new Error("Please provide the handler as a function!"); + } + const intentName = typeof intent === "string" ? intent : intent.intent; + const methodName = `${GLUE42_FDC3_INTENTS_METHOD_PREFIX}${intentName}`; + let intentFlag = {}; + let registerPromise; + const alreadyRegistered = this.myIntents.has(intentName); + if (alreadyRegistered) { + throw new Error(`Intent listener for intent ${intentName} already registered!`); + } + this.myIntents.add(intentName); + const result = { + unsubscribe: () => { + this.myIntents.delete(intentName); + registerPromise + .then(() => this.interop.unregister(methodName)) + .catch((err) => this.logger.trace(`Unregistration of a method with name ${methodName} failed with reason: ${JSON.stringify(err)}`)); + } + }; + if (typeof intent === "object") { + const { intent: removed, ...rest } = intent; + intentFlag = rest; + } + registerPromise = this.interop.register({ name: methodName, flags: { intent: intentFlag } }, (args) => { + if (this.myIntents.has(intentName)) { + return handler(args); + } + }); + registerPromise.catch((err) => { + this.myIntents.delete(intentName); + this.logger.warn(`Registration of a method with name ${methodName} failed with reason: ${JSON.stringify(err)}`); + }); + return result; + } + async register(intent, handler) { + if ((typeof intent !== "string" && typeof intent !== "object") || (typeof intent === "object" && typeof intent.intent !== "string")) { + throw new Error("Please provide the intent as a string or an object with an intent property!"); + } + if (typeof handler !== "function") { + throw new Error("Please provide the handler as a function!"); + } + await Promise.all(this.unregisterIntentPromises); + const intentName = typeof intent === "string" ? intent : intent.intent; + const methodName = this.buildInteropMethodName(intentName); + let intentFlag = {}; + const alreadyRegistered = this.myIntents.has(intentName); + if (alreadyRegistered) { + throw new Error(`Intent listener for intent ${intentName} already registered!`); + } + this.myIntents.add(intentName); + if (typeof intent === "object") { + const { intent: removed, ...rest } = intent; + intentFlag = rest; + } + try { + await this.interop.register({ name: methodName, flags: { intent: intentFlag } }, (args, caller) => { + if (this.myIntents.has(intentName)) { + return handler(args, caller); + } + }); + } + catch (err) { + this.myIntents.delete(intentName); + throw new Error(`Registration of a method with name ${methodName} failed with reason: ${JSON.stringify(err)}`); + } + return { + unsubscribe: () => this.unsubscribeIntent(intentName) + }; + } + async filterHandlers(handlerFilter) { + var _a, _b; + validateHandlerFilter(handlerFilter); + if (handlerFilter.openResolver && !this.useIntentsResolverUI) { + throw new Error("Cannot resolve 'filterHandlers' request using Intents Resolver UI because it's globally disabled"); + } + (_a = this.logger) === null || _a === void 0 ? void 0 : _a.trace(`Received 'filterHandlers' command with request: ${JSON.stringify(handlerFilter)}`); + const filteredHandlers = this.filterHandlersBy(await this.all(), handlerFilter); + if (!filteredHandlers || !filteredHandlers.length) { + return { handlers: [] }; + } + const { open, reason } = this.checkIfResolverShouldBeOpenedForFilterHandlers(filteredHandlers, handlerFilter); + if (!open) { + (_b = this.logger) === null || _b === void 0 ? void 0 : _b.trace(`Intent Resolver UI won't be used. Reason: ${reason}`); + return { handlers: filteredHandlers }; + } + const resolverInstance = { instanceId: undefined }; + const timeout = handlerFilter.timeout || DEFAULT_PICK_HANDLER_BY_TIMEOUT_MS; + const handler = await PromiseWrap(() => this.startResolverApp({ request: handlerFilter, resolverInstance, method: 'filterHandlers' }), timeout, `Timeout of ${timeout}ms hit for 'filterHandlers' request with filter: ${JSON.stringify(handlerFilter)}`); + return { handlers: [handler] }; + } + async getIntents(handler) { + var _a; + this.logger.trace(`Received 'getIntents' command with handler ${JSON.stringify(handler)}`); + validateIntentHandler(handler); + const intents = await this.all(); + clearNullUndefined(handler); + (_a = this.logger) === null || _a === void 0 ? void 0 : _a.trace(`Extracting valid intents for the passed handler`); + const intentsWithInfo = this.extractIntentsWithInfoByHandler(intents, handler); + this.logger.trace(`Returning intents for handler ${JSON.stringify(handler)}`); + return { intents: intentsWithInfo }; + } + async clearSavedHandlers() { + this.logger.trace("Removing all saved handlers from prefs storage for current app"); + await this.prefsController.update({ intents: undefined }); + } + onHandlerAdded(callback) { + var _a; + const unAppAdded = (_a = this.appManager) === null || _a === void 0 ? void 0 : _a.onAppAdded(async (app) => { + var _a; + const appName = app.name; + const appDef = await app.getConfiguration(); + const isIntentHandler = (_a = appDef === null || appDef === void 0 ? void 0 : appDef.intents) === null || _a === void 0 ? void 0 : _a.length; + if (!isIntentHandler) { + return; + } + appDef.intents.forEach((intent) => { + const handler = this.constructIntentHandlerFromApp(appDef, intent); + if (!this.addedHandlerInfoPerApp[appName]) { + this.addedHandlerInfoPerApp[appName] = []; + } + const appHandlers = this.addedHandlerInfoPerApp[appName]; + appHandlers.push({ handler, name: intent.name }); + callback(handler, intent.name); + }); + }); + const unServerMethodAdded = this.interop.serverMethodAdded(({ method, server }) => { + if (!method.name.startsWith(GLUE42_FDC3_INTENTS_METHOD_PREFIX)) { + return; + } + const intentName = method.name.replace(GLUE42_FDC3_INTENTS_METHOD_PREFIX, ""); + const intentsInfo = this.constructIntentHandler({ method, apps: [], server, intentName, title: "" }); + callback(intentsInfo, intentName); + }); + return () => { + if (typeof unServerMethodAdded === "function") { + unServerMethodAdded(); + } + if (typeof unAppAdded === "function") { + unAppAdded(); + } + }; + } + onHandlerRemoved(callback) { + var _a; + const unAppRemoved = (_a = this.appManager) === null || _a === void 0 ? void 0 : _a.onAppRemoved(async (app) => { + const appName = app.name; + const handlers = this.addedHandlerInfoPerApp[appName]; + const isIntentHandler = handlers === null || handlers === void 0 ? void 0 : handlers.length; + if (!isIntentHandler) { + return; + } + delete this.addedHandlerInfoPerApp[appName]; + handlers.forEach((addedHandlerInfo) => { + callback(addedHandlerInfo.handler, addedHandlerInfo.name); + }); + }); + const unServerMethodAdded = this.interop.serverMethodRemoved(({ method, server }) => { + if (!method.name.startsWith(GLUE42_FDC3_INTENTS_METHOD_PREFIX)) { + return; + } + const intentName = method.name.replace(GLUE42_FDC3_INTENTS_METHOD_PREFIX, ""); + const intentsInfo = this.constructIntentHandler({ method, apps: [], server, intentName, title: "" }); + callback(intentsInfo, intentName); + }); + return () => { + if (typeof unServerMethodAdded === "function") { + unServerMethodAdded(); + } + if (typeof unAppRemoved === "function") { + unAppRemoved(); + } + }; + } + toAPI() { + return { + all: this.all.bind(this), + find: this.find.bind(this), + raise: this.raise.bind(this), + addIntentListener: this.addIntentListener.bind(this), + register: this.register.bind(this), + filterHandlers: this.filterHandlers.bind(this), + getIntents: this.getIntents.bind(this), + clearSavedHandlers: this.clearSavedHandlers.bind(this), + onHandlerAdded: this.onHandlerAdded.bind(this), + onHandlerRemoved: this.onHandlerRemoved.bind(this) + }; + } + filterHandlersBy(intents, filter) { + const filteredIntentsWithHandlers = intents.filter((intent) => { + if (filter.intent && filter.intent !== intent.name) { + return; + } + if (filter.resultType) { + const filteredHandlers = intent.handlers.filter((handler) => handler.resultType && handler.resultType === filter.resultType); + if (!filteredHandlers.length) + return; + intent.handlers = filteredHandlers; + } + if (filter.contextTypes) { + const filteredHandlers = intent.handlers.filter((handler) => { var _a; return (_a = filter.contextTypes) === null || _a === void 0 ? void 0 : _a.every((contextType) => { var _a; return (_a = handler.contextTypes) === null || _a === void 0 ? void 0 : _a.includes(contextType); }); }); + if (!filteredHandlers.length) + return; + intent.handlers = filteredHandlers; + } + if (filter.applicationNames) { + const filteredHandlers = intent.handlers.filter((handler) => { var _a; return (_a = filter.applicationNames) === null || _a === void 0 ? void 0 : _a.includes(handler.applicationName); }); + if (!filteredHandlers.length) + return; + intent.handlers = filteredHandlers; + } + return intent; + }); + return filteredIntentsWithHandlers.map((intent) => intent.handlers).flat(1); + } + async coreRaiseIntent({ request, resolverInstance, timeout }) { + var _a, _b; + const intentDef = await this.get(request.intent); + if (typeof intentDef === "undefined") { + throw new Error(`${ERRORS.INTENT_NOT_FOUND} with name ${request.intent}`); + } + const { open, reason } = await this.checkIfResolverShouldBeOpenedForRaise(intentDef, request); + if (!open) { + this.logger.trace(`Intent Resolver UI won't be used. Reason: ${reason}`); + return request.waitUserResponseIndefinitely + ? PromiseWrap(() => this.raiseIntent(request, timeout), timeout, `${ERRORS.TIMEOUT_HIT} - waited ${timeout}ms for 'raise' to resolve`) + : this.raiseIntent(request, timeout); + } + const resolverHandler = await this.startResolverApp({ request, method: "raise", resolverInstance }); + (_a = this.logger) === null || _a === void 0 ? void 0 : _a.trace(`Raising intent to target handler: ${JSON.stringify(resolverHandler)} with timeout of ${timeout}`); + if (request.waitUserResponseIndefinitely) { + return PromiseWrap(() => this.raiseIntentToTargetHandler(request, resolverHandler, timeout), timeout, `${ERRORS.TIMEOUT_HIT} - waited ${timeout}ms for 'raise' to resolve`); + } + const result = await this.raiseIntentToTargetHandler(request, resolverHandler, timeout); + (_b = this.logger) === null || _b === void 0 ? void 0 : _b.trace(`Result from raise() method for intent ${JSON.stringify(request.intent)}: ${JSON.stringify(result)}`); + return result; + } + async get(intent) { + return (await this.all()).find((registeredIntent) => registeredIntent.name === intent); + } + async raiseIntent(intentRequest, timeout) { + const intentName = intentRequest.intent; + const intentDef = await this.get(intentName); + if (typeof intentDef === "undefined") { + throw new Error(`${ERRORS.INTENT_NOT_FOUND} with name ${intentRequest.intent}`); + } + const firstFoundAppHandler = intentRequest.handlers ? this.findHandlerByFilter(intentRequest.handlers, { type: "app" }) : this.findHandlerByFilter(intentDef.handlers, { type: "app" }); + const firstFoundInstanceHandler = intentRequest.handlers ? this.findHandlerByFilter(intentRequest.handlers, { type: "instance" }) : this.findHandlerByFilter(intentDef.handlers, { type: "instance" }); + let handler; + if (!intentRequest.target || intentRequest.target === "reuse") { + handler = firstFoundInstanceHandler || firstFoundAppHandler; + } + if (intentRequest.target === "startNew") { + handler = firstFoundAppHandler; + } + if (typeof intentRequest.target === "object" && intentRequest.target.app) { + handler = this.findHandlerByFilter(intentDef.handlers, { app: intentRequest.target.app }); + } + if (typeof intentRequest.target === "object" && intentRequest.target.instance) { + handler = this.findHandlerByFilter(intentDef.handlers, { instance: intentRequest.target.instance, app: intentRequest.target.app }); + } + if (!handler) { + throw new Error(`Can not raise intent for request ${JSON.stringify(intentRequest)} - can not find intent handler!`); + } + const result = await this.raiseIntentToTargetHandler(intentRequest, handler, timeout); + return result; + } + async raiseIntentToTargetHandler(intentRequest, handler, timeout) { + var _a, _b; + (_a = this.logger) === null || _a === void 0 ? void 0 : _a.trace(`Raising intent to target handler:${JSON.stringify(handler)}`); + if (!handler.instanceId) { + const instanceIdPromise = this.invokeStartApp(handler.applicationName, intentRequest.context, intentRequest.options).catch((err) => { + const reasonMsg = typeof err === "string" ? err : JSON.stringify(err); + throw new Error(`${ERRORS.TARGET_INSTANCE_UNAVAILABLE}. Reason: ${reasonMsg}`); + }); + handler.instanceId = await instanceIdPromise; + } + const methodName = `${GLUE42_FDC3_INTENTS_METHOD_PREFIX}${intentRequest.intent}`; + const invokeOptions = { + methodResponseTimeoutMs: timeout ? timeout + 1000 : DEFAULT_METHOD_RESPONSE_TIMEOUT_MS, + waitTimeoutMs: timeout ? timeout + 1000 : DEFAULT_METHOD_RESPONSE_TIMEOUT_MS + }; + const resultPromise = this.interop.invoke(methodName, intentRequest.context, { instance: handler.instanceId }, invokeOptions) + .catch((err) => { + const reasonMsg = typeof err === "string" ? err : JSON.stringify(err); + throw new Error(`${ERRORS.INTENT_HANDLER_REJECTION}. Reason: ${reasonMsg}`); + }); + const result = await resultPromise; + (_b = this.logger) === null || _b === void 0 ? void 0 : _b.trace(`raiseIntent command completed. Returning result: ${JSON.stringify(result)}`); + return { + request: intentRequest, + handler: { ...handler, type: "instance" }, + result: result.returned + }; + } + async startResolverApp({ request, method, resolverInstance }) { + var _a, _b, _c, _d; + (_a = this.logger) === null || _a === void 0 ? void 0 : _a.trace(`Intents Resolver UI with app name ${this.intentsResolverAppName} will be used for request: ${JSON.stringify(request)}`); + const responseMethodName = await this.registerIntentResolverMethod(); + (_b = this.logger) === null || _b === void 0 ? void 0 : _b.trace(`Registered interop method ${responseMethodName}`); + const startContext = this.buildStartContext(method, request, responseMethodName); + const startOptions = await this.buildStartOptions(); + (_c = this.logger) === null || _c === void 0 ? void 0 : _c.trace(`Starting Intents Resolver UI with context: ${JSON.stringify(startContext)} and options: ${JSON.stringify(startOptions)}`); + const instance = await this.appManager.application(this.intentsResolverAppName).start(startContext, startOptions); + resolverInstance.instanceId = instance.id; + (_d = this.logger) === null || _d === void 0 ? void 0 : _d.trace(`Intents Resolver instance with id ${instance.id} opened`); + this.subscribeOnInstanceStopped(instance, method); + const timeout = request.timeout || method === "raise" ? DEFAULT_RAISE_TIMEOUT_MS : DEFAULT_PICK_HANDLER_BY_TIMEOUT_MS; + this.createResponsePromise({ + intent: method === "raise" ? request.intent : undefined, + instanceId: instance.id, + responseMethodName, + timeout, + errorMsg: `Timeout of ${timeout}ms hit waiting for the user to choose a handler ${method === "raise" + ? `for intent ${request.intent}` + : `for '${method}' method with filter ${JSON.stringify(request)}`}` + }); + const handler = await this.handleInstanceResponse({ instanceId: instance.id, caller: startContext.initialCaller, method, request }); + return handler; + } + async windowsIdToTitle(id, windowsInfos) { + var _a, _b; + if (typeof windowsInfos !== "undefined") { + return (_a = windowsInfos.find((windowsInfo) => windowsInfo.id === id)) === null || _a === void 0 ? void 0 : _a.title; + } + const window = (_b = this.windows) === null || _b === void 0 ? void 0 : _b.findById(id); + const title = await (window === null || window === void 0 ? void 0 : window.getTitle()); + return title; + } + async handleInstanceResponse({ instanceId, method, request, caller }) { + var _a, _b, _c; + try { + const response = await this.intentsResolverResponsePromises[instanceId].promise; + const subMessage = method === "raise" ? `for intent ${response.intent} ` : ""; + (_a = this.logger) === null || _a === void 0 ? void 0 : _a.trace(`Intent handler chosen ${subMessage}: ${JSON.stringify(response.handler)}. Stopping resolver instance with id ${instanceId}`); + this.stopResolverInstance(instanceId); + (_b = this.logger) === null || _b === void 0 ? void 0 : _b.trace(`Instance with id ${instanceId} successfully stopped`); + if ((_c = response.userSettings) === null || _c === void 0 ? void 0 : _c.preserveChoice) { + await this.saveUserChoice({ + intent: response.intent, + handler: response.handler, + filter: method === "filterHandlers" + ? { applicationNames: request.applicationNames, contextTypes: request.contextTypes, resultType: request.resultType } + : undefined, + caller + }); + } + return response.handler; + } + catch (error) { + this.stopResolverInstance(instanceId); + throw new Error(error); + } + } + async registerIntentResolverMethod() { + const methodName = INTENTS_RESOLVER_INTEROP_PREFIX + Utils.generateId(); + await this.interop.register(methodName, (args, callerId) => this.resolverResponseHandler(args, callerId)); + return methodName; + } + resolverResponseHandler(args, callerId) { + const { instance } = callerId; + const isValid = validateResolverResponse(args); + if (!isValid) { + this.logger.trace(`Intent Resolver instance with id ${callerId.instance} sent invalid response. Error: ${isValid.error}`); + this.intentsResolverResponsePromises[instance].reject(isValid.error); + this.stopResolverInstance(instance); + return; + } + const validResponse = isValid.ok; + this.intentsResolverResponsePromises[instance].resolve(validResponse); + this.cleanUpIntentResolverPromise(instance); + } + buildStartContext(method, request, methodName) { + var _a; + const myAppName = this.interop.instance.application || this.interop.instance.applicationName; + const myAppTitle = ((_a = this.appManager.application(myAppName)) === null || _a === void 0 ? void 0 : _a.title) || ""; + const baseStartContext = { + callerId: this.interop.instance.instance, + methodName, + initialCaller: { id: this.interop.instance.instance, applicationName: myAppName, applicationTitle: myAppTitle }, + resolverApi: "1.0" + }; + return method === "raise" + ? { ...baseStartContext, intent: request } + : { ...baseStartContext, handlerFilter: request }; + } + async buildStartOptions() { + const win = this.windows.my(); + if (!win) { + return; + } + const bounds = await win.getBounds(); + return { + top: await this.getResolverStartupTopBound(bounds), + left: (bounds.width - INTENTS_RESOLVER_WIDTH) / 2 + bounds.left, + width: INTENTS_RESOLVER_WIDTH, + height: INTENTS_RESOLVER_HEIGHT + }; + } + async getResolverStartupTopBound(bounds) { + const myDisplay = await this.windows.my().getDisplay(); + const minWorkareaHeight = myDisplay.workArea.height; + const top = (bounds.height - INTENTS_RESOLVER_HEIGHT) / 2 + bounds.top; + if (top < 0) { + return 0; + } + if (top + INTENTS_RESOLVER_HEIGHT > minWorkareaHeight) { + return minWorkareaHeight / 2; + } + return top; + } + createResponsePromise({ instanceId, intent, responseMethodName, timeout, errorMsg }) { + let resolve = () => { }; + let reject = () => { }; + const promise = PromisePlus((res, rej) => { + resolve = res; + reject = rej; + }, timeout, errorMsg); + this.intentsResolverResponsePromises[instanceId] = { intent, resolve, reject, promise, methodName: responseMethodName }; + } + async invokeStartApp(application, context, options) { + const result = await this.interop.invoke("T42.ACS.StartApplication", { Name: application, options: { ...options, startedByIntentAPI: true } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return result.returned.Id; + } + subscribeOnInstanceStopped(instance, method) { + const { application } = instance; + const unsub = application.onInstanceStopped((inst) => { + if (inst.id !== instance.id) { + return; + } + const intentPromise = this.intentsResolverResponsePromises[inst.id]; + if (!intentPromise) { + return unsub(); + } + const errorMsg = `Cannot resolve ${method === "raise" ? `raised intent ${intentPromise.intent}` : `'${method}' method`} - User closed ${instance.application.name} app without choosing a handler`; + intentPromise.reject(errorMsg); + this.cleanUpIntentResolverPromise(inst.id); + unsub(); + }); + } + async cleanUpIntentResolverPromise(instanceId) { + const intentPromise = this.intentsResolverResponsePromises[instanceId]; + if (!intentPromise) { + return; + } + const unregisterPromise = this.interop.unregister(intentPromise.methodName); + unregisterPromise.catch((error) => this.logger.warn(error)); + delete this.intentsResolverResponsePromises[instanceId]; + } + handleRaiseOnError(instanceId) { + if (!instanceId) { + return; + } + this.stopResolverInstance(instanceId); + } + stopResolverInstance(instanceId) { + const gdWin = this.windows.findById(instanceId); + gdWin === null || gdWin === void 0 ? void 0 : gdWin.close().catch((err) => this.logger.error(err)); + } + checkIfIntentsResolverIsEnabled(options, appManager) { + var _a, _b, _c, _d, _e; + if (!appManager) { + this.useIntentsResolverUI = false; + return; + } + this.useIntentsResolverUI = typeof ((_a = options.intents) === null || _a === void 0 ? void 0 : _a.enableIntentsResolverUI) === "boolean" + ? options.intents.enableIntentsResolverUI + : true; + this.intentsResolverAppName = (_c = (_b = options.intents) === null || _b === void 0 ? void 0 : _b.intentsResolverAppName) !== null && _c !== void 0 ? _c : INTENTS_RESOLVER_APP_NAME; + this.intentsResolverResponseTimeout = (_e = (_d = options.intents) === null || _d === void 0 ? void 0 : _d.methodResponseTimeoutMs) !== null && _e !== void 0 ? _e : DEFAULT_RESOLVER_RESPONSE_TIMEOUT; + } + async checkIfResolverShouldBeOpenedForRaise(intent, request) { + const checkOpen = this.checkIfIntentsResolverShouldBeOpened(); + if (!checkOpen.open) { + return checkOpen; + } + const hasMoreThanOneHandler = await this.checkIfIntentHasMoreThanOneHandler(intent, request); + if (!hasMoreThanOneHandler) { + return { open: false, reason: `Raised intent ${intent.name} has only one handler` }; + } + return { open: true }; + } + checkIfResolverShouldBeOpenedForFilterHandlers(handlers, filter) { + if (handlers.length === 1) { + return { open: false, reason: `There's only one valid intent handler for filter ${JSON.stringify(filter)}` }; + } + if (typeof (filter === null || filter === void 0 ? void 0 : filter.openResolver) === "boolean" && !filter.openResolver) { + return { open: false, reason: "Intents resolver is disabled by IntentHandler filter" }; + } + return this.checkIfIntentsResolverShouldBeOpened(); + } + checkIfIntentsResolverShouldBeOpened() { + if (!this.useIntentsResolverUI) { + return { open: false, reason: `Intent Resolver is disabled. Resolving to first found handler` }; + } + const intentsResolverApp = this.appManager.application(this.intentsResolverAppName); + if (!intentsResolverApp) { + return { open: false, reason: `Intent Resolver Application with name ${this.intentsResolverAppName} not found.` }; + } + return { open: true }; + } + async checkIfIntentHasMoreThanOneHandler(intent, request) { + const handlers = await this.removeSingletons(request.handlers || intent.handlers); + if (!request.target) { + return handlers.length > 1; + } + if (request.target === "reuse") { + return handlers.filter(handler => handler.type === "instance" && handler.instanceId).length > 1 || intent.handlers.filter(handler => handler.type === "app").length > 1; + } + if (request.target === "startNew") { + return handlers.filter(handler => handler.type === "app").length > 1; + } + if (request.target.instance) { + return false; + } + if (request.target.app) { + const searchedAppName = request.target.app; + const instanceHandlersByAppName = handlers.filter((handler) => handler.applicationName === searchedAppName && handler.instanceId); + return instanceHandlersByAppName.length > 1; + } + return false; + } + async removeSingletons(handlers) { + const handlersWithSingletonProp = await Promise.all(handlers.map(async (handler) => { + if (handler.type === "instance") { + return handler; + } + const appConfig = await this.appManager.application(handler.applicationName).getConfiguration(); + const isSingleton = appConfig.allowMultiple === false; + return { ...handler, isSingleton }; + })); + const filteredSingletonsWithOpenedInstances = handlersWithSingletonProp.filter((handler, _, currentHandlers) => { + if (handler.instanceId || !handler.isSingleton) { + return handler; + } + const openedInstance = currentHandlers.find((h) => h.instanceId && h.applicationName === handler.applicationName); + if (openedInstance) { + return; + } + return handler; + }); + return filteredSingletonsWithOpenedInstances; + } + buildInteropMethodName(intentName) { + return `${GLUE42_FDC3_INTENTS_METHOD_PREFIX}${intentName}`; + } + clearUnregistrationPromise(promiseToRemove) { + this.unregisterIntentPromises = this.unregisterIntentPromises.filter((promise) => promise !== promiseToRemove); + } + unsubscribeIntent(intentName) { + this.myIntents.delete(intentName); + const methodName = this.buildInteropMethodName(intentName); + const unregisterPromise = this.interop.unregister(methodName); + this.unregisterIntentPromises.push(unregisterPromise); + unregisterPromise + .then(() => { + this.clearUnregistrationPromise(unregisterPromise); + }) + .catch((err) => { + this.logger.error(`Unregistration of a method with name ${methodName} failed with reason: `, err); + this.clearUnregistrationPromise(unregisterPromise); + }); + } + findHandlerByFilter(handlers, filter) { + if (filter.type) { + return handlers.find((handler) => handler.type === filter.type); + } + if (filter.instance) { + return handlers.find((handler) => filter.app + ? handler.applicationName === filter.app && handler.instanceId === filter.instance + : handler.instanceId === filter.instance); + } + if (filter.app) { + return handlers.find((handler) => handler.applicationName === filter.app); + } + } + extractIntentsWithInfoByHandler(intents, handler) { + const intentsWithInfo = intents.reduce((validIntentsWithInfo, intent) => { + intent.handlers.forEach((currentHandler) => { + const isValid = Object.keys(handler).every((key) => { + var _a; + return key === "contextTypes" + ? (_a = handler.contextTypes) === null || _a === void 0 ? void 0 : _a.every((contextType) => { var _a; return (_a = currentHandler.contextTypes) === null || _a === void 0 ? void 0 : _a.includes(contextType); }) + : currentHandler[key] === handler[key]; + }); + if (!isValid) { + return; + } + const intentWithInfo = { + intent: intent.name, + contextTypes: currentHandler.contextTypes, + description: currentHandler.applicationDescription, + displayName: currentHandler.displayName, + icon: currentHandler.applicationIcon, + resultType: currentHandler.resultType + }; + validIntentsWithInfo.push(intentWithInfo); + }); + return validIntentsWithInfo; + }, []); + return intentsWithInfo; + } + async removeRememberedHandler(intentName) { + var _a; + this.logger.trace(`Removing saved handler from prefs storage for intent ${intentName}`); + let prefs; + try { + prefs = await this.prefsController.get(); + } + catch (error) { + this.logger.warn(`prefs.get() threw the following error: ${typeof error === "string" ? error : JSON.stringify(error)}`); + return; + } + const intentPrefs = (_a = prefs.data) === null || _a === void 0 ? void 0 : _a.intents; + if (!intentPrefs) { + this.logger.trace("No app prefs found for current app"); + return; + } + delete intentPrefs[intentName]; + const updatedPrefs = { + ...prefs.data, + intents: intentPrefs + }; + try { + await this.prefsController.update(updatedPrefs); + } + catch (error) { + this.logger.warn(`prefs.update() threw the following error: ${typeof error === "string" ? error : JSON.stringify(error)}`); + return; + } + this.logger.trace(`Handler saved choice for intent ${intentName} removed successfully`); + } + async checkForRememberedHandler(intentRequest) { + var _a, _b; + let prefs; + try { + prefs = await this.prefsController.get(); + } + catch (error) { + this.logger.warn(`prefs.get() threw the following error: ${typeof error === "string" ? error : JSON.stringify(error)}`); + return; + } + const prefsForIntent = (_b = (_a = prefs.data) === null || _a === void 0 ? void 0 : _a.intents) === null || _b === void 0 ? void 0 : _b[intentRequest.intent]; + return prefsForIntent === null || prefsForIntent === void 0 ? void 0 : prefsForIntent.handler; + } + async checkHandleRaiseWithRememberedHandler(intentRequest, resolverInstance, timeout) { + if (intentRequest.target) { + return; + } + const rememberedHandler = await this.checkForRememberedHandler(intentRequest); + if (!rememberedHandler) { + return; + } + const request = { + ...intentRequest, + target: { + app: rememberedHandler.applicationName, + instance: rememberedHandler.instanceId + } + }; + try { + const response = await this.coreRaiseIntent({ request, resolverInstance, timeout }); + return response; + } + catch (error) { + this.logger.trace("Could not raise intent to remembered handler. Removing it from Prefs store"); + await this.removeRememberedHandler(intentRequest.intent); + } + } + async saveUserChoice({ intent, handler, filter, caller }) { + var _a, _b; + const prevPrefs = await this.prefsController.get(caller.applicationName); + const prevIntentsPrefs = ((_a = prevPrefs === null || prevPrefs === void 0 ? void 0 : prevPrefs.data) === null || _a === void 0 ? void 0 : _a.intents) || {}; + const prefsToUpdate = { + ...prevPrefs.data, + intents: { + ...prevIntentsPrefs, + [intent]: { handler, filter } + } + }; + await this.prefsController.update(prefsToUpdate, { app: caller.applicationName }); + (_b = this.logger) === null || _b === void 0 ? void 0 : _b.info(`Saved user's choice of handler for '${caller.applicationName}' app`); + } + constructIntentHandler({ apps, intentName, method, server, title }) { + const info = method.flags.intent; + const app = apps.find((appWithIntents) => appWithIntents.name === server.application); + let appIntent; + if (app === null || app === void 0 ? void 0 : app.intents) { + appIntent = app.intents.find((appDefIntent) => appDefIntent.name === intentName); + } + const handler = { + instanceId: server.instance, + applicationName: server.application, + applicationIcon: info.icon || (app === null || app === void 0 ? void 0 : app.icon), + applicationTitle: (app === null || app === void 0 ? void 0 : app.title) || "", + applicationDescription: info.description || (app === null || app === void 0 ? void 0 : app.caption), + displayName: info.displayName || (appIntent === null || appIntent === void 0 ? void 0 : appIntent.displayName), + contextTypes: info.contextTypes || (appIntent === null || appIntent === void 0 ? void 0 : appIntent.contexts), + instanceTitle: title, + type: "instance", + resultType: (appIntent === null || appIntent === void 0 ? void 0 : appIntent.resultType) || info.resultType + }; + return handler; + } + constructIntentHandlerFromApp(app, intent) { + return { + applicationName: app.name, + applicationTitle: app.title || "", + applicationDescription: app.caption, + displayName: intent.displayName, + contextTypes: intent.contexts, + applicationIcon: app.icon, + type: "app", + resultType: intent.resultType + }; + } + } + + class FactoryCallInfo { + constructor() { + this.initialized = false; + this.details = []; + this.reject = () => { }; + this.resolve = () => { }; + } + init(config) { + this.initialized = true; + this.addCall(config); + this.promise = new Promise((resolve, reject) => { + this.resolve = resolve; + this.reject = reject; + }); + } + addCall(config) { + this.details.push({ date: new Date(), config }); + } + done(g) { + this.resolve(g); + } + error(e) { + this.reject(e); + } + } + + class Prefs { + constructor(appName, interop) { + this.appName = appName; + this.interop = interop; + this.registry = CallbackRegistryFactory(); + this.interopMethodRegistered = false; + } + async get(app) { + const data = (await this.interop.invoke(Prefs.T42GetPrefsMethodName, { app: app !== null && app !== void 0 ? app : this.appName }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + })); + return data.returned; + } + async set(data, options) { + var _a; + this.verifyDataObject(data); + await this.interop.invoke(Prefs.T42SetPrefsMethodName, { app: (_a = options === null || options === void 0 ? void 0 : options.app) !== null && _a !== void 0 ? _a : this.appName, data, merge: false }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async setFor(app, data) { + this.verifyApp(app); + this.verifyDataObject(data); + return this.set(data, { app }); + } + async update(data, options) { + var _a; + this.verifyDataObject(data); + await this.interop.invoke(Prefs.T42SetPrefsMethodName, { app: (_a = options === null || options === void 0 ? void 0 : options.app) !== null && _a !== void 0 ? _a : this.appName, data, merge: true }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async updateFor(app, data) { + this.verifyApp(app); + this.verifyDataObject(data); + return this.update(data, { app }); + } + async clear(app) { + await this.interop.invoke(Prefs.T42SetPrefsMethodName, { app: app !== null && app !== void 0 ? app : this.appName, clear: true }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async clearFor(app) { + this.verifyApp(app); + await this.interop.invoke(Prefs.T42SetPrefsMethodName, { app, clear: true }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async getAll() { + const data = (await this.interop.invoke(Prefs.T42GetPrefsMethodName, undefined, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + })); + return data.returned; + } + async clearAll() { + await this.interop.invoke(Prefs.T42SetPrefsMethodName, { clear: true }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + subscribe(callback) { + this.verifyCallback(callback); + return this.subscribeFor(this.appName, callback); + } + subscribeFor(app, callback) { + this.verifyApp(app); + this.verifyCallback(callback); + const unsubscribeFn = this.registry.add(app, callback); + this.registerInteropIfNeeded() + .then(() => { + this.interop.invoke(Prefs.T42GetPrefsMethodName, { app, subscribe: true }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + }); + return () => { + unsubscribeFn(); + }; + } + async registerInteropIfNeeded() { + if (this.interopMethodRegistered) { + return; + } + this.interopMethodRegistered = true; + await this.interop.register(Prefs.T42UpdatePrefsMethodName, (args) => { + this.registry.execute(args.app, args); + }); + } + verifyApp(app) { + if (!app) { + throw new Error(`app should be defined`); + } + if (!isString(app)) { + throw new Error(`app should be a string`); + } + } + verifyDataObject(data) { + if (!data) { + throw new Error(`data should be defined`); + } + if (!isObject(data)) { + throw new Error(`data should be an object`); + } + } + verifyCallback(callback) { + if (!isFunction(callback)) { + throw new Error(`callback should be defined`); + } + } + } + Prefs.T42UpdatePrefsMethodName = "T42.Prefs.Update"; + Prefs.T42GetPrefsMethodName = "T42.Prefs.Get"; + Prefs.T42SetPrefsMethodName = "T42.Prefs.Set"; + + class Cookies { + constructor(methodName, interop) { + this.methodName = methodName; + this.interop = interop; + } + async get(filter) { + const result = await this.invoke("get-cookies", { filter }); + return result.returned.cookies; + } + async set(cookie) { + this.verifyCookieObject(cookie); + await this.invoke("set-cookie", cookie); + } + async remove(url, name) { + if (!isString(url)) { + throw new Error(`url should be a string`); + } + if (!isString(name)) { + throw new Error(`name should be a string`); + } + await this.invoke("remove-cookie", { url, name }); + } + invoke(command, data) { + return this.interop.invoke(this.methodName, { command, args: data }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_RESPONSE_TIMEOUT_MS, + }); + } + verifyCookieObject(cookie) { + if (!cookie) { + throw new Error(`cookie should be defined`); + } + if (!isObject(cookie)) { + throw new Error(`cookie should be an object`); + } + if (Utils.isNullOrUndefined(cookie.url) || !isString(cookie.url)) { + throw new Error(`cookie.url should be a string`); + } + if (Utils.isNullOrUndefined(cookie.name) || !isString(cookie.name)) { + throw new Error(`cookie.name should be a string`); + } + if (!Utils.isNullOrUndefined(cookie.value) && !isString(cookie.value)) { + throw new Error(`cookie.value should be a string`); + } + if (!Utils.isNullOrUndefined(cookie.domain) && !isString(cookie.domain)) { + throw new Error(`cookie.domain should be a string`); + } + if (!Utils.isNullOrUndefined(cookie.path) && !isString(cookie.path)) { + throw new Error(`cookie.path should be a string`); + } + if (!Utils.isNullOrUndefined(cookie.secure) && typeof cookie.secure !== "boolean") { + throw new Error(`cookie.secure should be a boolean`); + } + if (!Utils.isNullOrUndefined(cookie.httpOnly) && typeof cookie.httpOnly !== "boolean") { + throw new Error(`cookie.httpOnly should be a boolean`); + } + if (!Utils.isNullOrUndefined(cookie.expirationDate) && typeof cookie.expirationDate !== "number") { + throw new Error(`cookie.expirationDate should be a number`); + } + } + } + + function factory$1(agm, methodName) { + const cookies = new Cookies(methodName, agm); + return { + get: cookies.get.bind(cookies), + remove: cookies.remove.bind(cookies), + set: cookies.set.bind(cookies), + ready: () => Promise.resolve() + }; + } + + class EventsDispatcher { + constructor(config) { + this.config = config; + this.glue42EventName = "Glue42"; + this.events = { + notifyStarted: { name: "notifyStarted", handle: this.handleNotifyStarted.bind(this) }, + requestGlue: { name: "requestGlue", handle: this.handleRequestGlue.bind(this) } + }; + } + start(glue) { + if (Utils.isNode()) { + return; + } + this.glue = glue; + this.wireCustomEventListener(); + this.announceStarted(); + } + wireCustomEventListener() { + window.addEventListener(this.glue42EventName, (event) => { + const data = event.detail; + if (!data || !data.glue42) { + return; + } + const glue42Event = data.glue42.event; + const foundHandler = this.events[glue42Event]; + if (!foundHandler) { + return; + } + foundHandler.handle(data.glue42.message); + }); + } + announceStarted() { + this.send("start"); + } + handleRequestGlue() { + if (!this.config.exposeAPI) { + this.send("requestGlueResponse", { error: "Will not give access to the underlying Glue API, because it was explicitly denied upon initialization." }); + return; + } + this.send("requestGlueResponse", { glue: this.glue }); + } + handleNotifyStarted() { + this.announceStarted(); + } + send(eventName, message) { + const payload = { glue42: { event: eventName, message } }; + const event = new CustomEvent(this.glue42EventName, { detail: payload }); + window.dispatchEvent(event); + } + } + + class PromiseWrapper { + static delay(time) { + return new Promise((resolve) => setTimeout(resolve, time)); + } + static async delayForever() { + const biggestPossibleDelay = 2147483647; + while (true) { + await this.delay(biggestPossibleDelay); + } + } + get ended() { + return this.rejected || this.resolved; + } + constructor() { + this.promise = new Promise((resolve, reject) => { + this.resolve = (t) => { + this.resolved = true; + resolve(t); + }; + this.reject = (err) => { + this.rejected = true; + reject(err); + }; + }); + } + } + + class Interception { + constructor() { + this.InterceptorMethodName = "T42.GD.Interception.Execute"; + this.InterceptorHandlerMethodName = "T42.GD.Interception.Handler"; + this.interceptions = []; + } + init(interop) { + this.interop = interop; + } + async register(request) { + if (!request || typeof request !== "object" || Array.isArray(request)) { + throw new Error(`Please provide a valid object.`); + } + const handler = request.handler; + if (typeof handler !== "function") { + throw new Error("Please provide a valid handler function."); + } + const interceptions = request.interceptions; + this.validateInterceptions(interceptions); + this.interceptions.push(request); + try { + await this.interop.invoke(this.InterceptorMethodName, { + command: "register", + interceptions + }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + await this.registerMethodIfNotRegistered(); + } + catch (error) { + this.interceptions = this.interceptions.filter((i) => i !== request); + const message = error.message || "Unknown error"; + const newError = new Error(`Failed to register interception: ${message}`); + throw newError; + } + } + async unregister(request) { + if (!request || typeof request !== "object" || Array.isArray(request)) { + throw new Error(`Please provide a valid object.`); + } + const interceptions = request.interceptions; + this.validateInterceptions(interceptions); + try { + await this.interop.invoke(this.InterceptorMethodName, { + command: "unregister", + interceptions + }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + this.interceptions = this.interceptions.filter((config) => { + return !interceptions.some((interception) => { + return config.interceptions.some((i) => { + return i.domain === interception.domain && i.operation === interception.operation; + }); + }); + }); + } + catch (error) { + const message = error.message || "Unknown error"; + const newError = new Error(`Failed to unregister interception: ${message}`); + throw newError; + } + } + async handleInterception(domain, operation, operationArgs, phase) { + if (this.interop.methods(this.InterceptorMethodName).length === 0) { + return {}; + } + const result = await this.interop.invoke(this.InterceptorMethodName, { + command: "raiseInterception", + interceptions: [{ + operationArgs, + domain, + operation, + phase + }] + }, 'best', { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return result.returned; + } + static createProxyObject(apiToIntercept, domain, interception) { + const methods = Interception.OperationsPerDomain[domain] || []; + const handler = { + get(target, propertyKey, receiver) { + const property = Reflect.get(target, propertyKey, receiver); + try { + if (typeof property !== "function") { + return property; + } + const shouldIntercept = methods.includes(propertyKey); + const isAwaitable = Utils.isPromise(property) || Utils.isAsyncFunction(property); + if (!shouldIntercept || !isAwaitable) { + return property; + } + return Interception.interceptMethod(property, propertyKey, target, domain, interception); + } + catch (error) { + return property; + } + } + }; + const proxyAPI = new Proxy(apiToIntercept, handler); + return proxyAPI; + } + static interceptMethod(originalMethod, propertyKey, target, domain, interception) { + return async function (...args) { + const beforeInterceptionResult = await interception.handleInterception(domain, propertyKey, args, "before"); + if (!Utils.isNullOrUndefined(beforeInterceptionResult.operationResult)) { + return beforeInterceptionResult.operationResult; + } + if (!Utils.isNullOrUndefined(beforeInterceptionResult.operationArgs)) { + args = beforeInterceptionResult.operationArgs; + } + const methodResult = await originalMethod.apply(target, args); + const afterInterceptionResult = await interception.handleInterception(domain, propertyKey, [methodResult], "after"); + if (!Utils.isNullOrUndefined(afterInterceptionResult.operationResult)) { + return afterInterceptionResult.operationResult; + } + return methodResult; + }; + } + toAPI() { + return { + register: this.register.bind(this), + unregister: this.unregister.bind(this), + }; + } + async registerMethodIfNotRegistered() { + var _a; + if ((_a = this.whenRegisteredPromise) === null || _a === void 0 ? void 0 : _a.ended) { + return; + } + this.whenRegisteredPromise = new PromiseWrapper(); + this.registerMethod(); + } + async registerMethod() { + await this.interop.register(this.InterceptorHandlerMethodName, async (data) => { + const command = data.command; + if (command === "raiseInterception") { + const raisedInterception = data.interception; + const interceptor = this.interceptions.find((config) => { + return config.interceptions.some((interception) => { + return interception.domain === raisedInterception.domain && interception.operation === raisedInterception.operation; + }); + }); + const result = await interceptor.handler(raisedInterception); + return result; + } + }); + this.whenRegisteredPromise.resolve(); + } + validateInterceptions(interceptions) { + if (!Array.isArray(interceptions)) { + throw new Error("Please provide a valid array of interceptions."); + } + if (interceptions.length === 0) { + throw new Error("Please provide at least one interception."); + } + for (const interception of interceptions) { + if (typeof interception === "undefined" || interception === null || typeof interception !== "object" || Array.isArray(interception)) { + throw new Error("Please provide a valid interception object."); + } + if (typeof interception.domain !== "string" || !interception.domain) { + throw new Error("Please provide a valid domain string."); + } + if (typeof interception.operation !== "string" || !interception.operation) { + throw new Error("Please provide a valid operation string."); + } + this.validateTypeString(interception); + } + } + validateTypeString(interception) { + if (!isUndefinedOrNull(interception.phase)) { + const isValidType = ["all", "before", "after"].includes(interception.phase); + if (typeof interception.phase !== "string" || !isValidType) { + throw new Error("Please provide a valid phase string."); + } + } + } + } + Interception.OperationsPerDomain = { + "intents": ["raise"] + }; + + const callInfo = new FactoryCallInfo(); + const factory = async (options) => { + let firstRun = false; + if (!callInfo.initialized) { + firstRun = true; + callInfo.init(options); + } + const glue42gd = typeof window !== "undefined" && window.glue42gd; + if (glue42gd) { + if (!firstRun) { + callInfo.addCall(options); + return callInfo.promise; + } + } + const g = await factoryCore(options, glue42gd); + callInfo.resolve(g); + return g; + }; + const factoryCore = async (options, glue42gd) => { + const T42GDExecuteMethod = "T42.GD.Execute"; + const gdMajorVersion = Utils.getGDMajorVersion(); + options = options || {}; + const glueConfig = prepareConfig(options); + options.gateway = options.gateway || {}; + let _appManager; + let _activity; + let _windows; + let _displays; + let _channels; + let _prefs; + const _interceptors = new Interception(); + const _browserEventsDispatcher = new EventsDispatcher(glueConfig); + function createWindows(core) { + if (glueConfig.windows) { + const windowsLogger = getLibLogger("windows", core.logger, glueConfig.windows); + _windows = WindowsFactory(core.agm, windowsLogger, () => { + return _appManager; + }, () => { + return _displays; + }, () => { + return _channels; + }, gdMajorVersion); + debugLog(_windows); + return _windows; + } + } + function createActivities(core) { + var _a; + if (glueConfig.activities) { + if (ActivityModule.checkIsUsingGW3Implementation && ActivityModule.checkIsUsingGW3Implementation(core.connection)) { + const activityLogger = getLibLogger("activity", core.logger, glueConfig.activities); + _activity = new ActivityModule({ + connection: core.connection, + contexts: core.contexts, + agm: core.agm, + logger: activityLogger, + logLevel: "info", + disableAutoAnnounce: false, + disposeRequestHandling: "exit", + announcementInfo: null, + windows: _windows, + appManagerGetter: () => { + return _appManager; + }, + mode: glueConfig.activities.mode, + typesToTrack: glueConfig.activities.typesToTrack, + activityId: (_a = glue42gd === null || glue42gd === void 0 ? void 0 : glue42gd.activityInfo) === null || _a === void 0 ? void 0 : _a.activityId, + gdMajorVersion + }).api; + debugLog(_activity); + return _activity; + } + } + } + function createAppManager(core) { + if (!glueConfig.appManager) { + return; + } + const logger = getLibLogger("appManager", core.logger, glueConfig.appManager); + _appManager = AppManagerFactory({ + agm: core.agm, + windows: _windows, + logger, + activities: _activity, + mode: glueConfig.appManager.mode, + gdMajorVersion + }); + debugLog(_appManager); + return _appManager; + } + function createLayouts(core) { + var _a; + if (!glueConfig.layouts) { + return; + } + const logger = getLibLogger("layouts", core.logger, glueConfig.layouts); + const layoutsConfig = glueConfig.layouts; + const lay = LayoutsFactory({ + agm: core.agm, + appManager: _appManager, + activityGetter: () => _activity, + logger, + mode: layoutsConfig.mode, + autoSaveWindowContext: (_a = layoutsConfig.autoSaveWindowContext) !== null && _a !== void 0 ? _a : false, + gdMajorVersion + }); + debugLog(lay); + return lay; + } + function createChannels(core) { + if (!glueConfig.channels) { + return; + } + const logger = getLibLogger("channels", core.logger, glueConfig.channels); + if (!core.contexts) { + logger.error("Channels library requires Contexts library to be initialized."); + return; + } + _channels = factory$4({ operationMode: glueConfig.channels.operationMode }, core.contexts, core.agm, () => _windows, () => _appManager, logger); + debugLog(_channels); + return _channels; + } + function createHotkeys(core) { + const hotkeysAPI = factory$3(core.agm); + debugLog(hotkeysAPI); + return hotkeysAPI; + } + function createIntents(core) { + const domain = "intents"; + const intents = new Intents(core.agm, _windows, core.logger.subLogger(domain), options, _prefs, _appManager); + const intentsAPI = intents.toAPI(); + const proxyIntentsAPI = Interception.createProxyObject(intentsAPI, domain, _interceptors); + debugLog(proxyIntentsAPI); + return proxyIntentsAPI; + } + function createNotifications(core) { + const notificationsAPI = new Notifications(core.interop, core.logger).toAPI(); + debugLog(notificationsAPI); + return notificationsAPI; + } + function createDisplaysApi(core) { + if (glueConfig.displays) { + const displaysLogger = getLibLogger("displays", core.logger, glueConfig.displays); + _displays = new DisplayManager(core.agm, displaysLogger); + debugLog(_displays); + return _displays; + } + } + function createThemes(core) { + if (!core.contexts) { + return; + } + const themesAPI = factory$2(core.contexts, core.interop); + debugLog(themesAPI); + return themesAPI; + } + function createPrefs(core) { + var _a, _b; + const appName = (_b = (_a = options.application) !== null && _a !== void 0 ? _a : glue42gd === null || glue42gd === void 0 ? void 0 : glue42gd.applicationName) !== null && _b !== void 0 ? _b : core.interop.instance.application; + _prefs = new Prefs(appName, core.interop); + debugLog(_prefs); + return _prefs; + } + function createCookies(core) { + const api = factory$1(core.interop, T42GDExecuteMethod); + debugLog(api); + return api; + } + function createInterception(core) { + _interceptors.init(core.interop); + debugLog(_interceptors); + return _interceptors.toAPI(); + } + function getLibLogger(loggerName, logger, config) { + const newLogger = logger.subLogger(loggerName); + if (config && config.logger) { + const loggerConfig = config.logger; + if (loggerConfig.console) { + newLogger.consoleLevel(loggerConfig.console); + } + if (loggerConfig.publish) { + newLogger.publishLevel(loggerConfig.publish); + } + } + return newLogger; + } + const ext = { + libs: [ + { name: "windows", create: createWindows }, + { name: "activities", create: createActivities }, + { name: "appManager", create: createAppManager }, + { name: "layouts", create: createLayouts }, + { name: "channels", create: createChannels }, + { name: "hotkeys", create: createHotkeys }, + { name: "displays", create: createDisplaysApi }, + { name: "prefs", create: createPrefs }, + { name: "intents", create: createIntents }, + { name: "notifications", create: createNotifications }, + { name: "themes", create: createThemes }, + { name: "cookies", create: createCookies }, + { name: "interception", create: createInterception } + ], + version, + enrichGlue: (glue) => { + glue.config.activities = glueConfig.activities; + glue.config.windows = glueConfig.windows; + glue.config.appManager = glueConfig.appManager; + glue.config.layouts = glueConfig.layouts; + glue.config.channels = glueConfig.channels; + glue.config.displays = glueConfig.displays; + }, + }; + const currentLog = []; + if (typeof window !== "undefined") { + if (!window.glueFactoryLog) { + window.glueFactoryLog = []; + } + window.glueFactoryLog.push(currentLog); + } + function debugLog(entry) { + currentLog.push(entry); + } + const glueApi = (await IOConnectCoreFactory(options, ext)); + if (Array.isArray(options === null || options === void 0 ? void 0 : options.libraries) && options.libraries.length) { + await Promise.all(options.libraries.map((lib) => lib(glueApi, options))); + } + _browserEventsDispatcher.start(glueApi); + return glueApi; + }; + factory.coreVersion = IOConnectCoreFactory.version; + factory.version = version; + factory.calls = callInfo; + + var _a, _b; + let whatToExpose = factory; + let shouldSetToWindow = true; + if (typeof window !== "undefined") { + const windowAsAny = window; + const iodesktop = (_a = windowAsAny.iodesktop) !== null && _a !== void 0 ? _a : windowAsAny.glue42gd; + if (iodesktop && iodesktop.autoInjected) { + whatToExpose = (_b = windowAsAny.IODesktop) !== null && _b !== void 0 ? _b : windowAsAny.Glue; + shouldSetToWindow = false; + } + if (shouldSetToWindow) { + windowAsAny.Glue = whatToExpose; + windowAsAny.IODesktop = whatToExpose; + } + delete windowAsAny.IOBrowser; + delete windowAsAny.GlueCore; + } + whatToExpose.default = whatToExpose; + var whatToExpose$1 = whatToExpose; + + return whatToExpose$1; + +})); +//# sourceMappingURL=desktop.umd.js.map diff --git a/typescript/solution/client-details/src/lib/io.applications.css b/typescript/solution/client-details/src/lib/io.applications.css new file mode 100644 index 0000000..98e5910 --- /dev/null +++ b/typescript/solution/client-details/src/lib/io.applications.css @@ -0,0 +1,12 @@ +:root{--bs-blue: #007be5;--bs-indigo: #6610f2;--bs-purple: #6f42c1;--bs-pink: #fd397a;--bs-red: #ff511f;--bs-orange: #fd7e14;--bs-yellow: #f9a825;--bs-green: #43a047;--bs-teal: #616161;--bs-cyan: #469eb9;--bs-white: #fff;--bs-gray: #6c757d;--bs-gray-dark: #343a40;--bs-gray-100: #f8f9fa;--bs-gray-200: #e9ecef;--bs-gray-300: #dee2e6;--bs-gray-400: #ced4da;--bs-gray-500: #adb5bd;--bs-gray-600: #6c757d;--bs-gray-700: #495057;--bs-gray-800: #343a40;--bs-gray-900: #212529;--bs-primary: #007be5;--bs-secondary: #616161;--bs-success: #43a047;--bs-info: #469eb9;--bs-warning: #f9a825;--bs-danger: #ff511f;--bs-light: #616161;--bs-dark: #616161;--bs-primary-rgb: 0,123,229;--bs-secondary-rgb: 97,97,97;--bs-success-rgb: 67,160,71;--bs-info-rgb: 70,158,185;--bs-warning-rgb: 249,168,37;--bs-danger-rgb: 255,81,31;--bs-light-rgb: 97,97,97;--bs-dark-rgb: 97,97,97;--bs-white-rgb: 255,255,255;--bs-black-rgb: 0,0,0;--bs-body-color-rgb: 33,37,41;--bs-body-bg-rgb: 255,255,255;--bs-font-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--bs-gradient: linear-gradient(180deg, rgba(255,255,255,0.15), rgba(255,255,255,0));--bs-body-font-family: Montserrat,Helvetica Neue,Arial,sans-serif;--bs-body-font-size: .75rem;--bs-body-font-weight: 400;--bs-body-line-height: 1.5;--bs-body-color: #212529;--bs-body-bg: #fff}:root{--t42-font-family: "Montserrat", "Helvetica Neue", Arial, sans-serif;--t42-font-size: 0.75rem;--bs-gutter-x: 0.938rem;--primary: #007be5;--secondary: #616161;--success: #43a047;--info: #616161;--warning: #f9a825;--danger: #ff511f;--light: #616161;--dark: #616161;--white: #ffffff}.dark{--t42-bg-light-base: 0, 0%;--t42-bg-light-l: 18%;--t42-bg-light: 45, 45, 45;--t42-bg-mid: 37, 37, 37;--t42-bg-dark: 30, 30, 30;--t42-content-color-base: 0, 0%;--t42-content-color: #bababa;--t42-content-color-l: 73%;--t42-content-color-muted: hsl(var(--t42-content-color-base), 63%);--t42-content-color-disabled: hsl(var(--t42-content-color-base), 43%);--t42-color-opacity-025: hsla(var(--t42-content-color-base), 100%, 0.025);--t42-color-opacity-05: hsla(var(--t42-content-color-base), 100%, 0.05);--t42-color-opacity-10: hsla(var(--t42-content-color-base), 100%, 0.1);--t42-color-opacity-20: hsla(var(--t42-content-color-base), 100%, 0.2);--t42-color-opacity-30: hsla(var(--t42-content-color-base), 100%, 0.3);--t42-link-color: hsl(var(--t42-content-color-base), 100%);--t42-shadow: 0 0 12px 0 hsla(var(--t42-content-color-base), 0%, 0.15);--t42-border: 0.0625rem solid var(--t42-color-opacity-10);--t42-logo-icon: url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 xmlns:xlink=%27http://www.w3.org/1999/xlink%27 x=%270px%27 y=%270px%27 viewBox=%270 0 100.2 121%27 style=%27enable-background:new 0 0 100.2 121;%27%3E%3Cpath fill=%27%233A77BC%27 d=%27M59.4,10.6l-8.3,8.3c-0.5,0.5-1.4,0.5-1.9,0l-8.3-8.3c-0.5-0.5-0.5-1.4,0-1.9l8.3-8.3c0.5-0.5,1.4-0.5,1.9,0 l8.3,8.3C59.9,9.2,59.9,10.1,59.4,10.6z M59.3,110.4l-8.3-8.3c-0.5-0.5-1.4-0.5-1.9,0l-8.3,8.3c-0.5,0.5-0.5,1.4,0,1.9l8.3,8.3 c0.5,0.5,1.4,0.5,1.9,0l8.3-8.3C59.9,111.8,59.9,110.9,59.3,110.4z%27/%3E%3Cpath fill=%27%23FFFFFF%27 d=%27M100.1,60.1c0.3,7.3-2.9,14.3-9.3,20.6l-24.7,24.7c-0.6,0.6-1.5,0.6-2.1,0l-8.1-8.1c-0.6-0.6-0.6-1.5,0-2.1 l24.7-24.7c0.1-0.1,0.2-0.2,0.3-0.3c3.2-3.3,4.7-6.7,4.4-10.2c0-0.4-0.1-0.8-0.2-1.3c-0.6-3.3-2.8-7-6.8-11l-9.9-9.9 c-0.3-0.3-0.7-0.5-1.1-0.5c-0.4,0-0.8,0.2-1.3,0.6L34.5,69.6c-0.6,0.6-1.5,0.6-2.1,0L27.7,65c-3.3-3.3-3.8-5.1-1.3-7.6 c11.1-11.2,22-22.1,33.2-33.2c2.7-2.7,5.1-4.2,7.5-4.3c2.5-0.1,4.7,1.2,6.9,3.5l14.3,14.3C95.9,45.3,99.8,52.8,100.1,60.1 L100.1,60.1z M0,60.9c0.3,7.3,3.7,14.3,11.2,21.9l14.8,14.8c2.3,2.3,4.5,3.6,6.9,3.5c2.4-0.1,4.8-1.6,7.5-4.3 c11.1-11.1,22.1-22,33.2-33.2c2.5-2.5,2-4.3-1.3-7.6l-4.7-4.7c-0.6-0.6-1.5-0.6-2.1,0L34,83c-0.5,0.5-0.9,0.6-1.3,0.6 c-0.4,0-0.7-0.1-1.1-0.5L21.3,72.7c-4-4-5.7-7.2-6.3-10.5c-0.1-0.4-0.1-0.8-0.2-1.3c-0.3-3.5,1.2-6.9,4.4-10.2 c0.1-0.1,0.2-0.2,0.3-0.3l24.7-24.7c0.6-0.6,0.6-1.5,0-2.1l-8.1-8.1c-0.6-0.6-1.5-0.6-2.1,0L9.3,40.3C2.9,46.6-0.3,53.5,0,60.9 L0,60.9z%27/%3E%3C/svg%3E%0A");--t42-icon-color: var(--t42-link-color);--t42-list-group-hover-bg-special: hsla(var(--t42-content-color-base), 100%, 0.065);--backdrop-filter: blur(5px) saturate(200%);--accordion-filter: invert(1) brightness(1);--filter-close: invert(1);--t42-body: rgb(var(--t42-bg-dark));--pink: rgb(0 170 200);--t42-link-hover-color: hsl(var(--t42-bg-light-base), 100%);--t42-link-hover-bg: var(--t42-color-opacity-05);--t42-link-active-bg: var(--t42-color-opacity-10);--t42-input-bg: rgb(var(--t42-bg-dark));--t42-input-disabled-bg: Hsla(var(--t42-content-color-base), 100%, 0.075);--t42-tooltip-bg: rgba(var(--t42-bg-dark), 0.85);--t42-modal-bg: rgba(var(--t42-bg-light), 0.75);--t42-table-active-bg: rgba(255, 255, 255, 0.1);--t42-select-indicator: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9IiNFRUVFRUUiIHZpZXdCb3g9IjAgMCAxNiAxNiI+PHBhdGggZD0iTTIuNSA1LjVjLjQtLjQgMS0uNSAxLjYgMGwzLjkgMy43bDMuOS0zLjdjLjUtLjUgMS4xLS40IDEuNiAwYy40LjQuNCAxLjIgMCAxLjZjLS40LjQtNC43IDQuNS00LjcgNC41Yy0uMi4yLS41LjMtLjguM3MtLjYtLjEtLjgtLjNjMCAwLTQuMy00LjEtNC43LTQuNXMtLjQtMS4yIDAtMS42eiI+PC9wYXRoPjwvc3ZnPg==)}.light{--t42-bg-light-base: 0, 0%;--t42-bg-light-l: 100%;--t42-bg-light: 255, 255, 255;--t42-bg-mid: 250, 250, 250;--t42-bg-dark: 245, 245, 245;--t42-content-color-base: 0, 0%;--t42-content-color: #757575;--t42-content-color-l: 46%;--t42-content-color-muted: hsl(var(--t42-content-color-base), 66%);--t42-color-opacity-025: hsla(var(--t42-content-color-base), 0%, 0.025);--t42-color-opacity-05: hsla(var(--t42-content-color-base), 0%, 0.05);--t42-color-opacity-10: hsla(var(--t42-content-color-base), 0%, 0.075);--t42-color-opacity-30: hsla(var(--t42-content-color-base), 0%, 0.1);--t42-color-opacity-20: hsla(var(--t42-content-color-base), 0%, 0.2);--t42-link-color: hsl(var(--t42-content-color-base), 5%);--t42-shadow: 0 0 12px 0 hsla(var(--t42-content-color-base), 0%, 0.05);--t42-border: 0.0625rem solid var(--t42-color-opacity-10);--t42-logo-icon: url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 xmlns:xlink=%27http://www.w3.org/1999/xlink%27 x=%270px%27 y=%270px%27 viewBox=%270 0 100.2 121%27 style=%27enable-background:new 0 0 100.2 121;%27%3E%3Cpath fill=%27%233A77BC%27 d=%27M59.4,10.6l-8.3,8.3c-0.5,0.5-1.4,0.5-1.9,0l-8.3-8.3c-0.5-0.5-0.5-1.4,0-1.9l8.3-8.3c0.5-0.5,1.4-0.5,1.9,0 l8.3,8.3C59.9,9.2,59.9,10.1,59.4,10.6z M59.3,110.4l-8.3-8.3c-0.5-0.5-1.4-0.5-1.9,0l-8.3,8.3c-0.5,0.5-0.5,1.4,0,1.9l8.3,8.3 c0.5,0.5,1.4,0.5,1.9,0l8.3-8.3C59.9,111.8,59.9,110.9,59.3,110.4z%27/%3E%3Cpath fill=%27%23083044%27 d=%27M100.1,60.1c0.3,7.3-2.9,14.3-9.3,20.6l-24.7,24.7c-0.6,0.6-1.5,0.6-2.1,0l-8.1-8.1c-0.6-0.6-0.6-1.5,0-2.1 l24.7-24.7c0.1-0.1,0.2-0.2,0.3-0.3c3.2-3.3,4.7-6.7,4.4-10.2c0-0.4-0.1-0.8-0.2-1.3c-0.6-3.3-2.8-7-6.8-11l-9.9-9.9 c-0.3-0.3-0.7-0.5-1.1-0.5c-0.4,0-0.8,0.2-1.3,0.6L34.5,69.6c-0.6,0.6-1.5,0.6-2.1,0L27.7,65c-3.3-3.3-3.8-5.1-1.3-7.6 c11.1-11.2,22-22.1,33.2-33.2c2.7-2.7,5.1-4.2,7.5-4.3c2.5-0.1,4.7,1.2,6.9,3.5l14.3,14.3C95.9,45.3,99.8,52.8,100.1,60.1 L100.1,60.1z M0,60.9c0.3,7.3,3.7,14.3,11.2,21.9l14.8,14.8c2.3,2.3,4.5,3.6,6.9,3.5c2.4-0.1,4.8-1.6,7.5-4.3 c11.1-11.1,22.1-22,33.2-33.2c2.5-2.5,2-4.3-1.3-7.6l-4.7-4.7c-0.6-0.6-1.5-0.6-2.1,0L34,83c-0.5,0.5-0.9,0.6-1.3,0.6 c-0.4,0-0.7-0.1-1.1-0.5L21.3,72.7c-4-4-5.7-7.2-6.3-10.5c-0.1-0.4-0.1-0.8-0.2-1.3c-0.3-3.5,1.2-6.9,4.4-10.2 c0.1-0.1,0.2-0.2,0.3-0.3l24.7-24.7c0.6-0.6,0.6-1.5,0-2.1l-8.1-8.1c-0.6-0.6-1.5-0.6-2.1,0L9.3,40.3C2.9,46.6-0.3,53.5,0,60.9 L0,60.9z%27/%3E%3C/svg%3E%0A");--t42-icon-color: Hsl(var(--t42-content-color-base), 38%);--t42-list-group-hover-bg-special: hsla(var(--t42-content-color-base), 95%, 0.065);--backdrop-filter: blur(5px) saturate(200%);--accordion-filter: brightness(0%);--filter-close: invert(0);--t42-body: rgb(var(--t42-bg-mid));--t42-link-hover-color: hsl(var(--t42-bg-light-base), 0%);--t42-link-hover-bg: hsl(var(--t42-content-color-base), 95%);--t42-link-active-bg: hsl(var(--t42-content-color-base), 90%);--t42-input-bg: rgb(var(--t42-bg-light));--t42-input-disabled-bg: var(--t42-color-opacity-10);--t42-tooltip-bg: rgba(var(--t42-bg-light), 0.95);--t42-modal-bg: rgba(var(--t42-bg-light), 0.95);--t42-table-active-bg: rgba(0, 0, 0, 0.025);--t42-select-indicator: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9IiM2MTYxNjEiIHZpZXdCb3g9IjAgMCAxNiAxNiI+PHBhdGggZD0iTTIuNSA1LjVjLjQtLjQgMS0uNSAxLjYgMGwzLjkgMy43bDMuOS0zLjdjLjUtLjUgMS4xLS40IDEuNiAwYy40LjQuNCAxLjIgMCAxLjZjLS40LjQtNC43IDQuNS00LjcgNC41Yy0uMi4yLS41LjMtLjguM3MtLjYtLjEtLjgtLjNjMCAwLTQuMy00LjEtNC43LTQuNXMtLjQtMS4yIDAtMS42eiI+PC9wYXRoPjwvc3ZnPg==)}*,*::before,*::after{box-sizing:border-box}@media (prefers-reduced-motion: no-preference){:root{scroll-behavior:smooth}}body{margin:0;font-family:var(--bs-body-font-family);font-size:var(--bs-body-font-size);font-weight:var(--bs-body-font-weight);line-height:var(--bs-body-line-height);color:var(--bs-body-color);text-align:var(--bs-body-text-align);background-color:var(--bs-body-bg);-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:rgba(0,0,0,0)}hr{margin:1rem 0;color:inherit;background-color:currentColor;border:0;opacity:.25}hr:not([size]){height:1px}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem;font-weight:500;line-height:1.2;color:var(--t42-link-color)}h1{font-size:calc(1.26563rem + .1875vw)}@media (min-width: 1200px){h1{font-size:1.40625rem}}h2{font-size:1.125rem}h3{font-size:.98475rem}h4{font-size:.84375rem}h5{font-size:.75rem}h6{font-size:.7035rem}p{margin-top:0;margin-bottom:1rem}abbr[title],abbr[data-bs-original-title]{text-decoration:underline dotted;cursor:help;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}ol,ul{padding-left:2rem}ol,ul,dl{margin-top:0;margin-bottom:1rem}ol ol,ul ul,ol ul,ul ol{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:.875em}mark{padding:0.2rem 0.2rem 0;background-color:#007be5}sub,sup{position:relative;font-size:.75em;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:var(--t42-link-color);text-decoration:underline}a:hover{color:var(--t42-link-hover-color)}a:not([href]):not([class]),a:not([href]):not([class]):hover{color:inherit;text-decoration:none}pre,code,kbd,samp{font-family:var(--bs-font-monospace);font-size:1em;direction:ltr /* rtl:ignore */;unicode-bidi:bidi-override}pre{display:block;margin-top:0;margin-bottom:1rem;overflow:auto;font-size:inherit;color:var(--t42-content-color)}pre code{font-size:inherit;color:inherit;word-break:normal}code{font-size:inherit;color:#469eb9;word-wrap:break-word}a>code{color:inherit}kbd{padding:.2rem .4rem;font-size:inherit;color:#fff;background-color:#212529;border-radius:.25rem}kbd kbd{padding:0;font-size:1em;font-weight:700}figure{margin:0 0 1rem}img,svg{vertical-align:middle}table{caption-side:bottom;border-collapse:collapse}caption{padding-top:.25rem;padding-bottom:.25rem;color:var(--t42-content-color-muted);text-align:left}th{text-align:inherit;text-align:-webkit-match-parent}thead,tbody,tfoot,tr,td,th{border-color:inherit;border-style:solid;border-width:0}label{display:inline-block}button{border-radius:0}button:focus:not(:focus-visible){outline:0}input,button,select,optgroup,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,select{text-transform:none}[role="button"]{cursor:pointer}select{word-wrap:normal}select:disabled{opacity:1}[list]::-webkit-calendar-picker-indicator{display:none}button,[type="button"],[type="reset"],[type="submit"]{-webkit-appearance:button}button:not(:disabled),[type="button"]:not(:disabled),[type="reset"]:not(:disabled),[type="submit"]:not(:disabled){cursor:pointer}::-moz-focus-inner{padding:0;border-style:none}textarea{resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{float:left;width:100%;padding:0;margin-bottom:.5rem;font-size:calc(1.275rem + .3vw);line-height:inherit}@media (min-width: 1200px){legend{font-size:1.5rem}}legend+*{clear:left}::-webkit-datetime-edit-fields-wrapper,::-webkit-datetime-edit-text,::-webkit-datetime-edit-minute,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-year-field{padding:0}::-webkit-inner-spin-button{height:auto}[type="search"]{outline-offset:-2px;-webkit-appearance:textfield}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-color-swatch-wrapper{padding:0}::file-selector-button{font:inherit}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}iframe{border:0}summary{display:list-item;cursor:pointer}progress{vertical-align:baseline}[hidden]{display:none !important}body{color:var(--t42-content-color);font-family:var(--t42-font-family);background-color:var(--t42-body)}a:focus,button:focus,div:focus,span:focus{outline:0}a{text-decoration:none}dt{font-weight:normal}::selection{color:var(--white);background-color:var(--primary)}::-webkit-scrollbar{width:4px;height:4px}::-webkit-scrollbar-track{border-radius:.25rem;background:transparent}::-webkit-scrollbar-thumb{border-radius:.25rem;background:var(--t42-color-opacity-10)}::-webkit-resizer{background:transparent}::-webkit-scrollbar-corner{background:transparent}::-webkit-scrollbar-thumb:window-inactive{background:transparent}::-webkit-scrollbar-thumb:hover,::-webkit-scrollbar-thumb:active{background:Hsla(var(--t42-content-color-base), 100%, 0.05)}.accordion-button{position:relative;display:flex;align-items:center;width:100%;padding:1rem 1.25rem;font-size:.75rem;color:var(--t42-link-color);text-align:left;background-color:Rgb(var(--t42-bg-mid));border:0;border-radius:0;overflow-anchor:none;transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out,border-radius 0.15s ease}@media (prefers-reduced-motion: reduce){.accordion-button{transition:none}}.accordion-button:not(.collapsed){color:var(--t42-link-color);background-color:Rgb(var(--t42-bg-mid));box-shadow:inset 0 -1px 0 var(--t42-color-opacity-10)}.accordion-button:not(.collapsed)::after{background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 16 16%27 fill=%27var%28--t42-link-color%29%27%3e%3cpath fill-rule=%27evenodd%27 d=%27M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z%27/%3e%3c/svg%3e");transform:rotate(-180deg)}.accordion-button::after{flex-shrink:0;width:1.25rem;height:1.25rem;margin-left:auto;content:"";background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 16 16%27 fill=%27var%28--t42-link-color%29%27%3e%3cpath fill-rule=%27evenodd%27 d=%27M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z%27/%3e%3c/svg%3e");background-repeat:no-repeat;background-size:1.25rem;transition:transform 0.2s ease-in-out}@media (prefers-reduced-motion: reduce){.accordion-button::after{transition:none}}.accordion-button:hover{z-index:2}.accordion-button:focus{z-index:3;border-color:#007be5;outline:0;box-shadow:0 0 0 0 rgba(0,123,229,0.25)}.accordion-header{margin-bottom:0}.accordion-item{background-color:Rgb(var(--t42-bg-mid));border:1px solid var(--t42-color-opacity-10)}.accordion-item:first-of-type{border-top-left-radius:0;border-top-right-radius:0}.accordion-item:first-of-type .accordion-button{border-top-left-radius:0;border-top-right-radius:0}.accordion-item:not(:first-of-type){border-top:0}.accordion-item:last-of-type{border-bottom-right-radius:0;border-bottom-left-radius:0}.accordion-item:last-of-type .accordion-button.collapsed{border-bottom-right-radius:0;border-bottom-left-radius:0}.accordion-item:last-of-type .accordion-collapse{border-bottom-right-radius:0;border-bottom-left-radius:0}.accordion-body{padding:1rem 1.25rem}.accordion-flush .accordion-collapse{border-width:0}.accordion-flush .accordion-item{border-right:0;border-left:0;border-radius:0}.accordion-flush .accordion-item:first-child{border-top:0}.accordion-flush .accordion-item:last-child{border-bottom:0}.accordion-flush .accordion-item .accordion-button{border-radius:0}.accordion-button::after,.accordion-button:not(.collapsed)::after{filter:var(--accordion-filter)}.accordion-button:disabled,.accordion-button.disabled{color:var(--t42-content-color-disabled)}.accordion-button:disabled::after,.accordion-button.disabled::after{opacity:0.25}.alert{position:relative;padding:.75rem .875rem;margin-bottom:.5rem;border:1px solid transparent;border-radius:0}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-right:2.625rem}.alert-dismissible .btn-close{position:absolute;top:0;right:0;z-index:2;padding:.9375rem .875rem}.alert-primary{color:#004a89;background-color:#cce5fa;border-color:#b3d7f7}.alert-primary .alert-link{color:#003b6e}.alert-secondary{color:#3a3a3a;background-color:#dfdfdf;border-color:#d0d0d0}.alert-secondary .alert-link{color:#2e2e2e}.alert-success{color:#28602b;background-color:#d9ecda;border-color:#c7e3c8}.alert-success .alert-link{color:#204d22}.alert-info{color:#2a5f6f;background-color:#daecf1;border-color:#c8e2ea}.alert-info .alert-link{color:#224c59}.alert-warning{color:#64430f;background-color:#feeed3;border-color:#fde5be}.alert-warning .alert-link{color:#50360c}.alert-danger{color:#993113;background-color:#ffdcd2;border-color:#ffcbbc}.alert-danger .alert-link{color:#7a270f}.alert-light{color:#3a3a3a;background-color:#dfdfdf;border-color:#d0d0d0}.alert-light .alert-link{color:#2e2e2e}.alert-dark{color:#3a3a3a;background-color:#dfdfdf;border-color:#d0d0d0}.alert-dark .alert-link{color:#2e2e2e}.alert{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border-color;position:relative;z-index:10000;display:flex;align-items:center;border:0.0625rem solid var(--t42-color-opacity-10);overflow:hidden;color:var(--t42-content-color);background-color:Rgba(var(--t42-bg-light), 0.75);background-repeat:no-repeat;background-size:100%;backdrop-filter:var(--backdrop-filter)}.alert h5{margin-bottom:0;color:var(--t42-content-color)}.alert p{margin-bottom:0}.alert-link{color:var(--t42-link-color);font-weight:normal}.alert-dismissible .close{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border-color;position:absolute;top:50%;right:0.75rem;width:1.5rem;height:1.5rem;padding:0;border:0;border-radius:50%;color:var(--t42-content-color);font-weight:700;font-size:1rem;line-height:1;background-color:var(--t42-color-opacity-05);transform:translateY(-50%);opacity:0.5}.alert-dismissible .close::before{position:relative;top:-1px}.alert-dismissible .close:hover{opacity:1}.alert::before{z-index:1;width:1.25rem;height:1.25rem;margin-right:0.875rem;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-position:center;mask-position:center;background-color:var(--t42-icon-color);content:""}.alert::after{position:absolute;top:0;left:0;z-index:-1;width:1px;height:1px;border-radius:50%;opacity:1;animation:color-pulse 3s infinite;content:""}.alert-primary:hover,.alert-secondary:hover,.alert-info:hover,.alert-light:hover,.alert-dark:hover{border-color:#616161}.alert-primary::after,.alert-secondary::after,.alert-info::after,.alert-light::after,.alert-dark::after{background:#616161;background:radial-gradient(circle, rgba(255,255,255,0.35) 0%, rgba(97,97,97,0.75) 60%, #616161 75%, #616161 100%)}.alert-primary::before,.alert-secondary::before,.alert-info::before,.alert-light::before,.alert-dark::before{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M260.6 484.4q0-4.1-4.6-4.1q-16.9 0-29.2-12.3t-11.8-29.2q0-4.6-4.6-4.6t-4.6 4.6q0 21 14.8 35.8t35.3 14.3q4.6 0 4.6-4.6zM493.6 402.4q0 14.8-10.8 25.6t-25.6 10.8h-128q0 30.2-21.5 51.7t-51.7 21.5t-51.7-21.5t-21.5-51.7h-128q-14.8 0-25.6-10.8t-10.8-25.6q14.3-12.3 26.1-25.1t24.1-34.3t21.5-45.6t13.8-58.9t5.6-74.2q0-43 33.8-80.4t87.6-45.6q-2.6-5.1-2.6-10.8q0-11.8 8.2-19.5t19.5-8.2t19.5 8.2t8.2 19.5q0 5.6-2.6 10.8q54.3 8.2 87.6 45.6t33.8 80.4q0 39.9 5.6 74.2t14.3 58.9t21 45.6t24.6 34.3t25.6 25.1z%27%3E%3C/path%3E%3C/svg%3E")}.alert-success:hover{border-color:#43a047}.alert-success::after{background:#43a047;background:radial-gradient(circle, rgba(255,255,255,0.35) 0%, rgba(67,160,71,0.75) 60%, #43a047 75%, #43a047 100%)}.alert-success::before{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M477.4 152.8q0 11.3-8.2 19.5l-245.8 245.8q-8.2 7.7-19.5 7.7t-19.5-7.7l-142.3-142.3q-7.7-8.2-7.7-19.5t7.7-19.5l38.9-38.9q8.2-8.2 19.5-8.2t19.5 8.2l84 84.5l187.4-187.9q8.2-8.2 19.5-8.2t19.5 8.2l38.9 38.9q8.2 7.7 8.2 19.5z%27%3E%3C/path%3E%3C/svg%3E")}.alert-warning:hover{border-color:#f9a825}.alert-warning::after{background:#f9a825;background:radial-gradient(circle, rgba(255,255,255,0.35) 0%, rgba(249,168,37,0.75) 60%, #f9a825 75%, #f9a825 100%)}.alert-warning::before{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M292.4 410.9v-54.3q0-4.1-2.6-6.7t-6.1-2.6h-55.3q-3.6 0-6.1 2.6t-2.6 6.7v54.3q0 4.1 2.6 6.7t6.1 3.1h55.3q3.6 0 6.1-3.1t2.6-6.7zM291.8 304.4l5.1-131.6q0-3.1-2.6-5.1q-3.6-3.1-7.2-3.1h-62.5q-3.1 0-7.2 3.1q-2.6 2-2.6 6.1l4.6 130.6q0 2.6 3.1 4.6t6.7 1.5h52.7q4.1 0 7.2-1.5t2.6-4.6zM288.3 37.1l219.1 402.4q10.2 17.9-.5 35.8q-4.6 8.7-13.3 13.3t-17.9 5.1h-439.3q-9.2 0-17.9-5.1t-13.3-13.3q-10.8-17.9-.5-35.8l219.6-402.4q4.6-8.7 13.3-13.8t18.4-5.1t18.4 5.1t13.8 13.8z%27%3E%3C/path%3E%3C/svg%3E%0A")}.alert-danger:hover{border-color:#ff511f}.alert-danger::after{background:#ff511f;background:radial-gradient(circle, rgba(255,255,255,0.35) 0%, rgba(255,81,31,0.75) 60%, #ff511f 75%, #ff511f 100%)}.alert-danger::before{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 402 512%27%3E%3Cpath d=%27M370.728 359.68q0 11.264-7.68 19.456l-38.912 38.912q-8.192 7.68-19.456 7.68t-19.456-7.68l-83.968-84.48-83.968 84.48q-8.192 7.68-19.456 7.68t-19.456-7.68l-38.912-38.912q-8.192-8.192-8.192-19.456t8.192-19.456l83.968-83.968-83.968-83.968q-8.192-8.192-8.192-19.456t8.192-19.456l38.912-38.912q8.192-8.192 19.456-8.192t19.456 8.192l83.968 83.968 83.968-83.968q8.192-8.192 19.456-8.192t19.456 8.192l38.912 38.912q7.68 7.68 7.68 19.456t-7.68 19.456l-83.968 83.968 83.968 83.968q7.68 7.68 7.68 19.456z%27%3E%3C/path%3E%3C/svg%3E")}@keyframes color-pulse{0%{transform:scale(1);opacity:1}50%{transform:scale(250);opacity:0}100%{opacity:0}}.badge{display:inline-block;padding:.2rem .5rem;font-size:.75em;font-weight:300;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:1rem}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.badge{border:var(--t42-border);color:var(--t42-link-color);backdrop-filter:var(--backdrop-filter)}.badge.bg-primary{border:0.0625rem solid #007be5;background-color:rgba(0,123,229,0.15) !important}.badge.bg-secondary{border:0.0625rem solid #616161;background-color:rgba(97,97,97,0.15) !important}.badge.bg-success{border:0.0625rem solid #43a047;background-color:rgba(67,160,71,0.15) !important}.badge.bg-info{border:0.0625rem solid #469eb9;background-color:rgba(70,158,185,0.15) !important}.badge.bg-warning{border:0.0625rem solid #f9a825;background-color:rgba(249,168,37,0.15) !important}.badge.bg-danger{border:0.0625rem solid #ff511f;background-color:rgba(255,81,31,0.15) !important}.badge.bg-light{border:0.0625rem solid #616161;background-color:rgba(97,97,97,0.15) !important}.badge.bg-dark{border:0.0625rem solid #616161;background-color:rgba(97,97,97,0.15) !important}button .badge{border:0.0625rem solid var(--t42-color-opacity-30)}button:hover .badge{color:var(--white)}.btn-close{box-sizing:content-box;width:1em;height:1em;padding:0 0;color:var(--t42-content-color);background:transparent url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 16 16%27 fill=%27var%28--t42-content-color%29%27%3e%3cpath d=%27M.293.293a1 1 0 011.414 0L8 6.586 14.293.293a1 1 0 111.414 1.414L9.414 8l6.293 6.293a1 1 0 01-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 01-1.414-1.414L6.586 8 .293 1.707a1 1 0 010-1.414z%27/%3e%3c/svg%3e") center/1em auto no-repeat;border:0;border-radius:.25rem;opacity:.5}.btn-close:hover{color:var(--t42-content-color);text-decoration:none;opacity:.75}.btn-close:focus{outline:0;box-shadow:0 0 0 0 rgba(0,123,229,0.25);opacity:1}.btn-close:disabled,.btn-close.disabled{pointer-events:none;user-select:none;opacity:.25}.btn-close-white{filter:invert(1) grayscale(100%) brightness(200%)}.btn{display:inline-block;font-weight:400;line-height:1.875rem;color:#212529;text-align:center;text-decoration:none;vertical-align:middle;cursor:pointer;user-select:none;background-color:transparent;border:1px solid transparent;padding:0 .875rem;font-size:.75rem;border-radius:0;transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.btn{transition:none}}.btn:hover{color:#212529}.btn-check:focus+.btn,.btn:focus{outline:0;box-shadow:0 0 0 0 rgba(0,123,229,0.25)}.btn:disabled,.btn.disabled,fieldset:disabled .btn{pointer-events:none;opacity:.35}.btn-primary{color:#000;background-color:#007be5;border-color:#007be5}.btn-primary:hover{color:#000;background-color:#268fe9;border-color:#1a88e8}.btn-check:focus+.btn-primary,.btn-primary:focus{color:#000;background-color:#268fe9;border-color:#1a88e8;box-shadow:0 0 0 0 rgba(0,105,195,0.5)}.btn-check:checked+.btn-primary,.btn-check:active+.btn-primary,.btn-primary:active,.btn-primary.active,.show>.btn-primary.dropdown-toggle{color:#000;background-color:#3395ea;border-color:#1a88e8}.btn-check:checked+.btn-primary:focus,.btn-check:active+.btn-primary:focus,.btn-primary:active:focus,.btn-primary.active:focus,.show>.btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(0,105,195,0.5)}.btn-primary:disabled,.btn-primary.disabled{color:#000;background-color:#007be5;border-color:#007be5}.btn-secondary{color:#fff;background-color:#616161;border-color:#616161}.btn-secondary:hover{color:#fff;background-color:#525252;border-color:#4e4e4e}.btn-check:focus+.btn-secondary,.btn-secondary:focus{color:#fff;background-color:#525252;border-color:#4e4e4e;box-shadow:0 0 0 0 rgba(121,121,121,0.5)}.btn-check:checked+.btn-secondary,.btn-check:active+.btn-secondary,.btn-secondary:active,.btn-secondary.active,.show>.btn-secondary.dropdown-toggle{color:#fff;background-color:#4e4e4e;border-color:#494949}.btn-check:checked+.btn-secondary:focus,.btn-check:active+.btn-secondary:focus,.btn-secondary:active:focus,.btn-secondary.active:focus,.show>.btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(121,121,121,0.5)}.btn-secondary:disabled,.btn-secondary.disabled{color:#fff;background-color:#616161;border-color:#616161}.btn-success{color:#000;background-color:#43a047;border-color:#43a047}.btn-success:hover{color:#000;background-color:#5fae63;border-color:#56aa59}.btn-check:focus+.btn-success,.btn-success:focus{color:#000;background-color:#5fae63;border-color:#56aa59;box-shadow:0 0 0 0 rgba(57,136,60,0.5)}.btn-check:checked+.btn-success,.btn-check:active+.btn-success,.btn-success:active,.btn-success.active,.show>.btn-success.dropdown-toggle{color:#000;background-color:#69b36c;border-color:#56aa59}.btn-check:checked+.btn-success:focus,.btn-check:active+.btn-success:focus,.btn-success:active:focus,.btn-success.active:focus,.show>.btn-success.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(57,136,60,0.5)}.btn-success:disabled,.btn-success.disabled{color:#000;background-color:#43a047;border-color:#43a047}.btn-info{color:#000;background-color:#469eb9;border-color:#469eb9}.btn-info:hover{color:#000;background-color:#62adc4;border-color:#59a8c0}.btn-check:focus+.btn-info,.btn-info:focus{color:#000;background-color:#62adc4;border-color:#59a8c0;box-shadow:0 0 0 0 rgba(60,134,157,0.5)}.btn-check:checked+.btn-info,.btn-check:active+.btn-info,.btn-info:active,.btn-info.active,.show>.btn-info.dropdown-toggle{color:#000;background-color:#6bb1c7;border-color:#59a8c0}.btn-check:checked+.btn-info:focus,.btn-check:active+.btn-info:focus,.btn-info:active:focus,.btn-info.active:focus,.show>.btn-info.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(60,134,157,0.5)}.btn-info:disabled,.btn-info.disabled{color:#000;background-color:#469eb9;border-color:#469eb9}.btn-warning{color:#000;background-color:#f9a825;border-color:#f9a825}.btn-warning:hover{color:#000;background-color:#fab546;border-color:#fab13b}.btn-check:focus+.btn-warning,.btn-warning:focus{color:#000;background-color:#fab546;border-color:#fab13b;box-shadow:0 0 0 0 rgba(212,143,31,0.5)}.btn-check:checked+.btn-warning,.btn-check:active+.btn-warning,.btn-warning:active,.btn-warning.active,.show>.btn-warning.dropdown-toggle{color:#000;background-color:#fab951;border-color:#fab13b}.btn-check:checked+.btn-warning:focus,.btn-check:active+.btn-warning:focus,.btn-warning:active:focus,.btn-warning.active:focus,.show>.btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(212,143,31,0.5)}.btn-warning:disabled,.btn-warning.disabled{color:#000;background-color:#f9a825;border-color:#f9a825}.btn-danger{color:#000;background-color:#ff511f;border-color:#ff511f}.btn-danger:hover{color:#000;background-color:#ff6b41;border-color:#ff6235}.btn-check:focus+.btn-danger,.btn-danger:focus{color:#000;background-color:#ff6b41;border-color:#ff6235;box-shadow:0 0 0 0 rgba(217,69,26,0.5)}.btn-check:checked+.btn-danger,.btn-check:active+.btn-danger,.btn-danger:active,.btn-danger.active,.show>.btn-danger.dropdown-toggle{color:#000;background-color:#ff744c;border-color:#ff6235}.btn-check:checked+.btn-danger:focus,.btn-check:active+.btn-danger:focus,.btn-danger:active:focus,.btn-danger.active:focus,.show>.btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(217,69,26,0.5)}.btn-danger:disabled,.btn-danger.disabled{color:#000;background-color:#ff511f;border-color:#ff511f}.btn-light{color:#fff;background-color:#616161;border-color:#616161}.btn-light:hover{color:#fff;background-color:#525252;border-color:#4e4e4e}.btn-check:focus+.btn-light,.btn-light:focus{color:#fff;background-color:#525252;border-color:#4e4e4e;box-shadow:0 0 0 0 rgba(121,121,121,0.5)}.btn-check:checked+.btn-light,.btn-check:active+.btn-light,.btn-light:active,.btn-light.active,.show>.btn-light.dropdown-toggle{color:#fff;background-color:#4e4e4e;border-color:#494949}.btn-check:checked+.btn-light:focus,.btn-check:active+.btn-light:focus,.btn-light:active:focus,.btn-light.active:focus,.show>.btn-light.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(121,121,121,0.5)}.btn-light:disabled,.btn-light.disabled{color:#fff;background-color:#616161;border-color:#616161}.btn-dark{color:#fff;background-color:#616161;border-color:#616161}.btn-dark:hover{color:#fff;background-color:#525252;border-color:#4e4e4e}.btn-check:focus+.btn-dark,.btn-dark:focus{color:#fff;background-color:#525252;border-color:#4e4e4e;box-shadow:0 0 0 0 rgba(121,121,121,0.5)}.btn-check:checked+.btn-dark,.btn-check:active+.btn-dark,.btn-dark:active,.btn-dark.active,.show>.btn-dark.dropdown-toggle{color:#fff;background-color:#4e4e4e;border-color:#494949}.btn-check:checked+.btn-dark:focus,.btn-check:active+.btn-dark:focus,.btn-dark:active:focus,.btn-dark.active:focus,.show>.btn-dark.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(121,121,121,0.5)}.btn-dark:disabled,.btn-dark.disabled{color:#fff;background-color:#616161;border-color:#616161}.btn-outline-primary{color:#007be5;border-color:#007be5}.btn-outline-primary:hover{color:#000;background-color:#007be5;border-color:#007be5}.btn-check:focus+.btn-outline-primary,.btn-outline-primary:focus{box-shadow:0 0 0 0 rgba(0,123,229,0.5)}.btn-check:checked+.btn-outline-primary,.btn-check:active+.btn-outline-primary,.btn-outline-primary:active,.btn-outline-primary.active,.btn-outline-primary.dropdown-toggle.show{color:#000;background-color:#007be5;border-color:#007be5}.btn-check:checked+.btn-outline-primary:focus,.btn-check:active+.btn-outline-primary:focus,.btn-outline-primary:active:focus,.btn-outline-primary.active:focus,.btn-outline-primary.dropdown-toggle.show:focus{box-shadow:0 0 0 0 rgba(0,123,229,0.5)}.btn-outline-primary:disabled,.btn-outline-primary.disabled{color:#007be5;background-color:transparent}.btn-outline-secondary{color:#616161;border-color:#616161}.btn-outline-secondary:hover{color:#fff;background-color:#616161;border-color:#616161}.btn-check:focus+.btn-outline-secondary,.btn-outline-secondary:focus{box-shadow:0 0 0 0 rgba(97,97,97,0.5)}.btn-check:checked+.btn-outline-secondary,.btn-check:active+.btn-outline-secondary,.btn-outline-secondary:active,.btn-outline-secondary.active,.btn-outline-secondary.dropdown-toggle.show{color:#fff;background-color:#616161;border-color:#616161}.btn-check:checked+.btn-outline-secondary:focus,.btn-check:active+.btn-outline-secondary:focus,.btn-outline-secondary:active:focus,.btn-outline-secondary.active:focus,.btn-outline-secondary.dropdown-toggle.show:focus{box-shadow:0 0 0 0 rgba(97,97,97,0.5)}.btn-outline-secondary:disabled,.btn-outline-secondary.disabled{color:#616161;background-color:transparent}.btn-outline-success{color:#43a047;border-color:#43a047}.btn-outline-success:hover{color:#000;background-color:#43a047;border-color:#43a047}.btn-check:focus+.btn-outline-success,.btn-outline-success:focus{box-shadow:0 0 0 0 rgba(67,160,71,0.5)}.btn-check:checked+.btn-outline-success,.btn-check:active+.btn-outline-success,.btn-outline-success:active,.btn-outline-success.active,.btn-outline-success.dropdown-toggle.show{color:#000;background-color:#43a047;border-color:#43a047}.btn-check:checked+.btn-outline-success:focus,.btn-check:active+.btn-outline-success:focus,.btn-outline-success:active:focus,.btn-outline-success.active:focus,.btn-outline-success.dropdown-toggle.show:focus{box-shadow:0 0 0 0 rgba(67,160,71,0.5)}.btn-outline-success:disabled,.btn-outline-success.disabled{color:#43a047;background-color:transparent}.btn-outline-info{color:#469eb9;border-color:#469eb9}.btn-outline-info:hover{color:#000;background-color:#469eb9;border-color:#469eb9}.btn-check:focus+.btn-outline-info,.btn-outline-info:focus{box-shadow:0 0 0 0 rgba(70,158,185,0.5)}.btn-check:checked+.btn-outline-info,.btn-check:active+.btn-outline-info,.btn-outline-info:active,.btn-outline-info.active,.btn-outline-info.dropdown-toggle.show{color:#000;background-color:#469eb9;border-color:#469eb9}.btn-check:checked+.btn-outline-info:focus,.btn-check:active+.btn-outline-info:focus,.btn-outline-info:active:focus,.btn-outline-info.active:focus,.btn-outline-info.dropdown-toggle.show:focus{box-shadow:0 0 0 0 rgba(70,158,185,0.5)}.btn-outline-info:disabled,.btn-outline-info.disabled{color:#469eb9;background-color:transparent}.btn-outline-warning{color:#f9a825;border-color:#f9a825}.btn-outline-warning:hover{color:#000;background-color:#f9a825;border-color:#f9a825}.btn-check:focus+.btn-outline-warning,.btn-outline-warning:focus{box-shadow:0 0 0 0 rgba(249,168,37,0.5)}.btn-check:checked+.btn-outline-warning,.btn-check:active+.btn-outline-warning,.btn-outline-warning:active,.btn-outline-warning.active,.btn-outline-warning.dropdown-toggle.show{color:#000;background-color:#f9a825;border-color:#f9a825}.btn-check:checked+.btn-outline-warning:focus,.btn-check:active+.btn-outline-warning:focus,.btn-outline-warning:active:focus,.btn-outline-warning.active:focus,.btn-outline-warning.dropdown-toggle.show:focus{box-shadow:0 0 0 0 rgba(249,168,37,0.5)}.btn-outline-warning:disabled,.btn-outline-warning.disabled{color:#f9a825;background-color:transparent}.btn-outline-danger{color:#ff511f;border-color:#ff511f}.btn-outline-danger:hover{color:#000;background-color:#ff511f;border-color:#ff511f}.btn-check:focus+.btn-outline-danger,.btn-outline-danger:focus{box-shadow:0 0 0 0 rgba(255,81,31,0.5)}.btn-check:checked+.btn-outline-danger,.btn-check:active+.btn-outline-danger,.btn-outline-danger:active,.btn-outline-danger.active,.btn-outline-danger.dropdown-toggle.show{color:#000;background-color:#ff511f;border-color:#ff511f}.btn-check:checked+.btn-outline-danger:focus,.btn-check:active+.btn-outline-danger:focus,.btn-outline-danger:active:focus,.btn-outline-danger.active:focus,.btn-outline-danger.dropdown-toggle.show:focus{box-shadow:0 0 0 0 rgba(255,81,31,0.5)}.btn-outline-danger:disabled,.btn-outline-danger.disabled{color:#ff511f;background-color:transparent}.btn-outline-light{color:#616161;border-color:#616161}.btn-outline-light:hover{color:#fff;background-color:#616161;border-color:#616161}.btn-check:focus+.btn-outline-light,.btn-outline-light:focus{box-shadow:0 0 0 0 rgba(97,97,97,0.5)}.btn-check:checked+.btn-outline-light,.btn-check:active+.btn-outline-light,.btn-outline-light:active,.btn-outline-light.active,.btn-outline-light.dropdown-toggle.show{color:#fff;background-color:#616161;border-color:#616161}.btn-check:checked+.btn-outline-light:focus,.btn-check:active+.btn-outline-light:focus,.btn-outline-light:active:focus,.btn-outline-light.active:focus,.btn-outline-light.dropdown-toggle.show:focus{box-shadow:0 0 0 0 rgba(97,97,97,0.5)}.btn-outline-light:disabled,.btn-outline-light.disabled{color:#616161;background-color:transparent}.btn-outline-dark{color:#616161;border-color:#616161}.btn-outline-dark:hover{color:#fff;background-color:#616161;border-color:#616161}.btn-check:focus+.btn-outline-dark,.btn-outline-dark:focus{box-shadow:0 0 0 0 rgba(97,97,97,0.5)}.btn-check:checked+.btn-outline-dark,.btn-check:active+.btn-outline-dark,.btn-outline-dark:active,.btn-outline-dark.active,.btn-outline-dark.dropdown-toggle.show{color:#fff;background-color:#616161;border-color:#616161}.btn-check:checked+.btn-outline-dark:focus,.btn-check:active+.btn-outline-dark:focus,.btn-outline-dark:active:focus,.btn-outline-dark.active:focus,.btn-outline-dark.dropdown-toggle.show:focus{box-shadow:0 0 0 0 rgba(97,97,97,0.5)}.btn-outline-dark:disabled,.btn-outline-dark.disabled{color:#616161;background-color:transparent}.btn-link{font-weight:400;color:var(--t42-link-color);text-decoration:underline}.btn-link:hover{color:var(--t42-link-hover-color)}.btn-link:disabled,.btn-link.disabled{color:#6c757d}.btn-lg,.btn-group-lg>.btn{padding:0 .875rem;font-size:.75rem;border-radius:0}.btn-sm,.btn-group-sm>.btn{padding:0 .875rem;font-size:.75rem;border-radius:0}.btn-group,.btn-group-vertical{position:relative;display:inline-flex;vertical-align:middle}.btn-group>.btn,.btn-group-vertical>.btn{position:relative;flex:1 1 auto}.btn-group>.btn-check:checked+.btn,.btn-group>.btn-check:focus+.btn,.btn-group>.btn:hover,.btn-group>.btn:focus,.btn-group>.btn:active,.btn-group>.btn.active,.btn-group-vertical>.btn-check:checked+.btn,.btn-group-vertical>.btn-check:focus+.btn,.btn-group-vertical>.btn:hover,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn.active{z-index:1}.btn-toolbar{display:flex;flex-wrap:wrap;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group>.btn:not(:first-child),.btn-group>.btn-group:not(:first-child){margin-left:-1px}.btn-group>.btn:not(:last-child):not(.dropdown-toggle),.btn-group>.btn-group:not(:last-child)>.btn{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:nth-child(n+3),.btn-group>:not(.btn-check)+.btn,.btn-group>.btn-group:not(:first-child)>.btn{border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.65625rem;padding-left:.65625rem}.dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after,.dropend .dropdown-toggle-split::after{margin-left:0}.dropstart .dropdown-toggle-split::before{margin-right:0}.btn-sm+.dropdown-toggle-split,.btn-group-sm>.btn+.dropdown-toggle-split{padding-right:.65625rem;padding-left:.65625rem}.btn-lg+.dropdown-toggle-split,.btn-group-lg>.btn+.dropdown-toggle-split{padding-right:.65625rem;padding-left:.65625rem}.btn-group-vertical{flex-direction:column;align-items:flex-start;justify-content:center}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn:not(:first-child),.btn-group-vertical>.btn-group:not(:first-child){margin-top:-1px}.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle),.btn-group-vertical>.btn-group:not(:last-child)>.btn{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn ~ .btn,.btn-group-vertical>.btn-group:not(:first-child)>.btn{border-top-left-radius:0;border-top-right-radius:0}button,button:focus{outline:none}.btn{color:var(--t42-link-color);transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, border-color;cursor:default}.btn.disabled,.btn:disabled{color:var(--t42-link-color);cursor:default}.btn:not(.disabled):not(:disabled).active,.btn:not(.disabled):not(:disabled):hover{border-color:var(--t42-color-opacity-30);color:var(--white);backdrop-filter:var(--backdrop-filter)}.btn:focus,.btn:active{color:var(--white)}.btn-primary{background-color:rgba(0,123,229,0.05)}.btn-primary.disabled,.btn-primary:disabled{background-color:rgba(0,123,229,0.05)}.btn-primary:not(.disabled):not(:disabled).active,.btn-primary:not(.disabled):not(:disabled):hover{background-color:#007be5}.btn-primary:not(.disabled):not(:disabled).btn-icon.active,.btn-primary:not(.disabled):not(:disabled).btn-icon:focus,.btn-primary:not(.disabled):not(:disabled).btn-icon:hover{color:var(--white)}.btn-primary.dropdown-toggle.active,.btn-primary.dropdown-toggle:active,.btn-primary.dropdown-toggle:focus{border-color:var(--t42-color-opacity-30);background-color:#007be5}.btn-secondary{background-color:rgba(97,97,97,0.05)}.btn-secondary.disabled,.btn-secondary:disabled{background-color:rgba(97,97,97,0.05)}.btn-secondary:not(.disabled):not(:disabled).active,.btn-secondary:not(.disabled):not(:disabled):hover{background-color:#616161}.btn-secondary:not(.disabled):not(:disabled).btn-icon.active,.btn-secondary:not(.disabled):not(:disabled).btn-icon:focus,.btn-secondary:not(.disabled):not(:disabled).btn-icon:hover{color:var(--white)}.btn-secondary.dropdown-toggle.active,.btn-secondary.dropdown-toggle:active,.btn-secondary.dropdown-toggle:focus{border-color:var(--t42-color-opacity-30);background-color:#616161}.btn-success{background-color:rgba(67,160,71,0.05)}.btn-success.disabled,.btn-success:disabled{background-color:rgba(67,160,71,0.05)}.btn-success:not(.disabled):not(:disabled).active,.btn-success:not(.disabled):not(:disabled):hover{background-color:#43a047}.btn-success:not(.disabled):not(:disabled).btn-icon.active,.btn-success:not(.disabled):not(:disabled).btn-icon:focus,.btn-success:not(.disabled):not(:disabled).btn-icon:hover{color:var(--white)}.btn-success.dropdown-toggle.active,.btn-success.dropdown-toggle:active,.btn-success.dropdown-toggle:focus{border-color:var(--t42-color-opacity-30);background-color:#43a047}.btn-info{background-color:rgba(70,158,185,0.05)}.btn-info.disabled,.btn-info:disabled{background-color:rgba(70,158,185,0.05)}.btn-info:not(.disabled):not(:disabled).active,.btn-info:not(.disabled):not(:disabled):hover{background-color:#469eb9}.btn-info:not(.disabled):not(:disabled).btn-icon.active,.btn-info:not(.disabled):not(:disabled).btn-icon:focus,.btn-info:not(.disabled):not(:disabled).btn-icon:hover{color:var(--white)}.btn-info.dropdown-toggle.active,.btn-info.dropdown-toggle:active,.btn-info.dropdown-toggle:focus{border-color:var(--t42-color-opacity-30);background-color:#469eb9}.btn-warning{background-color:rgba(249,168,37,0.05)}.btn-warning.disabled,.btn-warning:disabled{background-color:rgba(249,168,37,0.05)}.btn-warning:not(.disabled):not(:disabled).active,.btn-warning:not(.disabled):not(:disabled):hover{background-color:#f9a825}.btn-warning:not(.disabled):not(:disabled).btn-icon.active,.btn-warning:not(.disabled):not(:disabled).btn-icon:focus,.btn-warning:not(.disabled):not(:disabled).btn-icon:hover{color:var(--white)}.btn-warning.dropdown-toggle.active,.btn-warning.dropdown-toggle:active,.btn-warning.dropdown-toggle:focus{border-color:var(--t42-color-opacity-30);background-color:#f9a825}.btn-danger{background-color:rgba(255,81,31,0.05)}.btn-danger.disabled,.btn-danger:disabled{background-color:rgba(255,81,31,0.05)}.btn-danger:not(.disabled):not(:disabled).active,.btn-danger:not(.disabled):not(:disabled):hover{background-color:#ff511f}.btn-danger:not(.disabled):not(:disabled).btn-icon.active,.btn-danger:not(.disabled):not(:disabled).btn-icon:focus,.btn-danger:not(.disabled):not(:disabled).btn-icon:hover{color:var(--white)}.btn-danger.dropdown-toggle.active,.btn-danger.dropdown-toggle:active,.btn-danger.dropdown-toggle:focus{border-color:var(--t42-color-opacity-30);background-color:#ff511f}.btn-light{background-color:rgba(97,97,97,0.05)}.btn-light.disabled,.btn-light:disabled{background-color:rgba(97,97,97,0.05)}.btn-light:not(.disabled):not(:disabled).active,.btn-light:not(.disabled):not(:disabled):hover{background-color:#616161}.btn-light:not(.disabled):not(:disabled).btn-icon.active,.btn-light:not(.disabled):not(:disabled).btn-icon:focus,.btn-light:not(.disabled):not(:disabled).btn-icon:hover{color:var(--white)}.btn-light.dropdown-toggle.active,.btn-light.dropdown-toggle:active,.btn-light.dropdown-toggle:focus{border-color:var(--t42-color-opacity-30);background-color:#616161}.btn-dark{background-color:rgba(97,97,97,0.05)}.btn-dark.disabled,.btn-dark:disabled{background-color:rgba(97,97,97,0.05)}.btn-dark:not(.disabled):not(:disabled).active,.btn-dark:not(.disabled):not(:disabled):hover{background-color:#616161}.btn-dark:not(.disabled):not(:disabled).btn-icon.active,.btn-dark:not(.disabled):not(:disabled).btn-icon:focus,.btn-dark:not(.disabled):not(:disabled).btn-icon:hover{color:var(--white)}.btn-dark.dropdown-toggle.active,.btn-dark.dropdown-toggle:active,.btn-dark.dropdown-toggle:focus{border-color:var(--t42-color-opacity-30);background-color:#616161}.btn-link{text-decoration:none;backdrop-filter:none}.btn-link:not(.disabled):not(:disabled).active,.btn-link:not(.disabled):not(:disabled):focus,.btn-link:not(.disabled):not(:disabled):hover{border-color:transparent;color:var(--t42-link-color);text-decoration:underline}.btn-icon:not(.disabled):not(:disabled).active,.btn-icon:not(.disabled):not(:disabled):focus,.btn-icon:not(.disabled):not(:disabled):hover{color:var(--t42-link-color)}.btn-icon-action{display:flex;justify-content:center;width:1rem;height:1rem;padding:0;border-radius:50%;font-size:0.75rem;transition:all .2s ease-in-out}@media (prefers-reduced-motion: reduce){.btn-icon-action{transition:none}}.btn-icon-action:not(.disabled):not(:disabled).active,.btn-icon-action:not(.disabled):not(:disabled):hover,.btn-icon-action:not(.disabled):not(:disabled):focus{border-color:transparent;background-color:Rgb(var(--t42-bg-light));box-shadow:var(--t42-shadow)}.btn-icon-action-right{position:absolute;right:0.25rem}.btn-icon-action-show-hover{transition:all .2s ease-in-out}@media (prefers-reduced-motion: reduce){.btn-icon-action-show-hover{transition:none}}.btn-icon-action-show-hover .btn-icon-action{opacity:0}.btn-icon-action-show-hover:not(.disabled):not(:disabled):hover .btn-icon-action{opacity:1}.btn-close{width:1rem;height:1rem;filter:var(--filter-close)}.breadcrumb{display:flex;flex-wrap:wrap;padding:0 0;margin-bottom:.5rem;list-style:none;background-color:rgba(0,0,0,0)}.breadcrumb-item+.breadcrumb-item{padding-left:.5rem}.breadcrumb-item+.breadcrumb-item::before{float:left;padding-right:.5rem;color:#6c757d;content:var(--bs-breadcrumb-divider, "/") /* rtl: var(--bs-breadcrumb-divider, "/") */}.breadcrumb-item.active{color:var(--t42-link-color)}.breadcrumb-item{font-size:83.3%}.breadcrumb-item.active{text-decoration:underline}.breadcrumb-item+.breadcrumb-item{padding-left:0}.breadcrumb-item+.breadcrumb-item::before{position:relative;top:0.063rem;left:0.063rem;width:0.75rem;height:0.75rem;background-color:var(--t42-content-color);content:"";-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M339.2,256.3c0,2.4-0.9,4.4-2.6,6.1L203,396c-1.7,1.7-3.8,2.6-6.1,2.6c-2.4,0-4.6-0.9-6.7-2.6l-14.3-14.3 c-2-2-3.1-4.3-3.1-6.7s1-4.6,3.1-6.7L288,256.3L175.9,143.6c-2-1.7-3.1-3.8-3.1-6.1s1-4.6,3.1-6.7l14.3-14.3c1.7-2,3.9-3.1,6.7-3.1 s4.8,1,6.1,3.1l133.6,133.1C338.3,251.3,339.2,253.5,339.2,256.3L339.2,256.3z%27/%3E%3C/svg%3E")}mark,.mark{color:var(--white)}pre{background-color:var(--t42-bg-dark)}blockquote,.blockquote{padding:1rem 1rem 0.01rem;border-left:0.25rem solid var(--secondary);background-color:Rgb(var(--t42-bg-dark))}.blockquote-footer{margin-top:-2rem;margin-left:1.25rem;color:var(--t42-content-color-muted);font-size:0.875em}pre{border:0.0625rem solid var(--t42-color-opacity-10)}.card{position:relative;display:flex;flex-direction:column;min-width:0;word-wrap:break-word;background-color:Rgba(var(--t42-bg-light), 0.75);background-clip:border-box;border:1px solid var(--t42-color-opacity-10);border-radius:0}.card>hr{margin-right:0;margin-left:0}.card>.list-group{border-top:inherit;border-bottom:inherit}.card>.list-group:first-child{border-top-width:0;border-top-left-radius:0;border-top-right-radius:0}.card>.list-group:last-child{border-bottom-width:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.card>.card-header+.list-group,.card>.list-group+.card-footer{border-top:0}.card-body{flex:1 1 auto;padding:1.25rem 1.25rem}.card-title{margin-bottom:.5rem}.card-subtitle{margin-top:-.25rem;margin-bottom:0}.card-text:last-child{margin-bottom:0}.card-link+.card-link{margin-left:1.25rem}.card-header{padding:.625rem 1.25rem;margin-bottom:0;color:var(--t42-link-color);background-color:rgba(0,0,0,0);border-bottom:1px solid var(--t42-color-opacity-10)}.card-header:first-child{border-radius:0 0 0 0}.card-footer{padding:.625rem 1.25rem;color:var(--t42-link-color);background-color:rgba(0,0,0,0);border-top:1px solid var(--t42-color-opacity-10)}.card-footer:last-child{border-radius:0 0 0 0}.card-header-tabs{margin-right:-.625rem;margin-bottom:-.625rem;margin-left:-.625rem;border-bottom:0}.card-header-tabs .nav-link.active{background-color:Rgba(var(--t42-bg-light), 0.75);border-bottom-color:Rgba(var(--t42-bg-light), 0.75)}.card-header-pills{margin-right:-.625rem;margin-left:-.625rem}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1rem;border-radius:0}.card-img,.card-img-top,.card-img-bottom{width:100%}.card-img,.card-img-top{border-top-left-radius:0;border-top-right-radius:0}.card-img,.card-img-bottom{border-bottom-right-radius:0;border-bottom-left-radius:0}.card-group>.card{margin-bottom:.75rem}@media (min-width: 576px){.card-group{display:flex;flex-flow:row wrap}.card-group>.card{flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:not(:last-child) .card-img-top,.card-group>.card:not(:last-child) .card-header{border-top-right-radius:0}.card-group>.card:not(:last-child) .card-img-bottom,.card-group>.card:not(:last-child) .card-footer{border-bottom-right-radius:0}.card-group>.card:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:not(:first-child) .card-img-top,.card-group>.card:not(:first-child) .card-header{border-top-left-radius:0}.card-group>.card:not(:first-child) .card-img-bottom,.card-group>.card:not(:first-child) .card-footer{border-bottom-left-radius:0}}.card{box-shadow:var(--t42-shadow);backdrop-filter:var(--backdrop-filter)}.card .card-header{border-bottom-width:0}.card .card-subtitle{margin-bottom:0.5rem;font-size:83.3%}.card.bg-primary{background-color:transparent !important}.card.bg-primary .card-header{background-color:Rgba(var(--t42-bg-mid), 0.75)}.card.bg-primary .card-body{background-color:Rgba(var(--t42-bg-light), 0.75)}.card.bg-secondary{background-color:transparent !important}.card.bg-secondary .card-header{background-color:Rgba(var(--t42-bg-light), 0.75)}.card.bg-secondary .card-body{background-color:Rgba(var(--t42-bg-mid), 0.75)}.card:not(.bg-primary):not(.bg-secondary) .card-header+.card-body{padding-top:0}.card-header-tabs{margin-bottom:0}.accordion .card:first-of-type,.accordion .card:not(:first-of-type):not(:last-of-type){margin-bottom:0.5rem;border-bottom:var(--t42-border)}.accordion .card-header{position:relative;padding:0}.accordion .card-header .btn-link{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;width:100%;padding:0.75rem 2rem;line-height:1.4;text-align:left}.accordion .card-header .btn-link::before{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:transform;position:absolute;display:inline-block;width:0.75rem;height:0.75rem;background-color:var(--t42-content-color);transform:translateX(-1rem) translateY(0.063rem) rotate(-90deg);content:"";-webkit-mask-image:var(--t42-select-indicator)}.accordion .card-header .btn-link:hover{backdrop-filter:none}.accordion .card-header .btn-link.collapsed::before{transform:translateX(-1rem) translateY(0.063rem)}.accordion .card-header .btn-link.disabled::before,.accordion .card-header .btn-link:disabled::before{opacity:.35}.accordion .card-body{padding:0 1.25rem 1.25rem}.accordion .bg-primary .card-body,.accordion .bg-secondary .card-body{padding:1.25rem}.dropup,.dropend,.dropdown,.dropstart{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:0;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{position:absolute;z-index:1000;display:none;min-width:10rem;padding:0 0;margin:0;font-size:.75rem;color:var(--t42-content-color);text-align:left;list-style:none;background-color:Rgba(var(--t42-bg-light), 0.75);background-clip:padding-box;border:1px solid var(--t42-color-opacity-10);border-radius:0}.dropdown-menu[data-bs-popper]{top:100%;left:0;margin-top:.125rem}.dropdown-menu-start{--bs-position: start}.dropdown-menu-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-end{--bs-position: end}.dropdown-menu-end[data-bs-popper]{right:0;left:auto}@media (min-width: 576px){.dropdown-menu-sm-start{--bs-position: start}.dropdown-menu-sm-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-sm-end{--bs-position: end}.dropdown-menu-sm-end[data-bs-popper]{right:0;left:auto}}@media (min-width: 768px){.dropdown-menu-md-start{--bs-position: start}.dropdown-menu-md-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-md-end{--bs-position: end}.dropdown-menu-md-end[data-bs-popper]{right:0;left:auto}}@media (min-width: 992px){.dropdown-menu-lg-start{--bs-position: start}.dropdown-menu-lg-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-lg-end{--bs-position: end}.dropdown-menu-lg-end[data-bs-popper]{right:0;left:auto}}@media (min-width: 1200px){.dropdown-menu-xl-start{--bs-position: start}.dropdown-menu-xl-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-xl-end{--bs-position: end}.dropdown-menu-xl-end[data-bs-popper]{right:0;left:auto}}@media (min-width: 1400px){.dropdown-menu-xxl-start{--bs-position: start}.dropdown-menu-xxl-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-xxl-end{--bs-position: end}.dropdown-menu-xxl-end[data-bs-popper]{right:0;left:auto}}.dropup .dropdown-menu[data-bs-popper]{top:auto;bottom:100%;margin-top:0;margin-bottom:.125rem}.dropup .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:0;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropend .dropdown-menu[data-bs-popper]{top:0;right:auto;left:100%;margin-top:0;margin-left:.125rem}.dropend .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:0;content:"";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid}.dropend .dropdown-toggle:empty::after{margin-left:0}.dropend .dropdown-toggle::after{vertical-align:0}.dropstart .dropdown-menu[data-bs-popper]{top:0;right:100%;left:auto;margin-top:0;margin-right:.125rem}.dropstart .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:0;content:""}.dropstart .dropdown-toggle::after{display:none}.dropstart .dropdown-toggle::before{display:inline-block;margin-right:.255em;vertical-align:0;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropstart .dropdown-toggle:empty::after{margin-left:0}.dropstart .dropdown-toggle::before{vertical-align:0}.dropdown-divider{height:0;margin:0 0;overflow:hidden;border-top:1px solid var(--t42-color-opacity-10)}.dropdown-item{display:block;width:100%;padding:.375rem 1rem;clear:both;font-weight:400;color:var(--t42-content-color);text-align:inherit;text-decoration:none;white-space:nowrap;background-color:transparent;border:0}.dropdown-item:first-child{border-top-left-radius:0;border-top-right-radius:0}.dropdown-item:last-child{border-bottom-right-radius:0;border-bottom-left-radius:0}.dropdown-item:hover,.dropdown-item:focus{color:var(--t42-link-hover-color);background-color:var(--t42-link-hover-bg)}.dropdown-item.active,.dropdown-item:active{color:var(--t42-link-hover-color);text-decoration:none;background-color:var(--t42-link-active-bg)}.dropdown-item.disabled,.dropdown-item:disabled{color:#adb5bd;pointer-events:none;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:0 1rem;margin-bottom:0;font-size:.65625rem;color:shade-color(#616161, 10%);white-space:nowrap}.dropdown-item-text{display:block;padding:.375rem 1rem;color:var(--t42-content-color)}.dropdown-menu-dark{color:#dee2e6;background-color:#343a40;border-color:var(--t42-color-opacity-10)}.dropdown-menu-dark .dropdown-item{color:#dee2e6}.dropdown-menu-dark .dropdown-item:hover,.dropdown-menu-dark .dropdown-item:focus{color:#fff;background-color:rgba(255,255,255,0.15)}.dropdown-menu-dark .dropdown-item.active,.dropdown-menu-dark .dropdown-item:active{color:var(--t42-link-hover-color);background-color:var(--t42-link-active-bg)}.dropdown-menu-dark .dropdown-item.disabled,.dropdown-menu-dark .dropdown-item:disabled{color:#adb5bd}.dropdown-menu-dark .dropdown-divider{border-color:var(--t42-color-opacity-10)}.dropdown-menu-dark .dropdown-item-text{color:#dee2e6}.dropdown-menu-dark .dropdown-header{color:#adb5bd}.dropdown-menu{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:opacity, visability;display:block;visibility:hidden;opacity:0;backdrop-filter:var(--backdrop-filter)}.dropdown-menu.show{visibility:visible;opacity:1}.dropdown-toggle::after{position:relative;width:0.5rem;height:0.5rem;border:0;background-color:var(--t42-link-color);content:"";-webkit-mask-image:url("data:image/svg+xml,%3Csvg version=%271.1%27 xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M480.768 186.88l-211.968 211.456q-5.12 5.632-12.8 5.632t-12.8-5.632l-211.968-211.456q-5.632-5.632-5.632-13.312t5.632-12.8l47.616-47.104q5.12-5.632 12.8-5.632t12.8 5.632l151.552 151.552 151.552-151.552q5.632-5.632 12.8-5.632t13.312 5.632l47.104 47.104q5.632 5.632 5.632 12.8t-5.632 13.312z%27%3E%3C/path%3E%3C/svg%3E")}.dropdown-toggle.show::after{color:var(--white)}.dropup .dropdown-toggle::after{position:relative;top:0.188rem;width:0.5rem;height:0.5rem;border:0;background-color:var(--t42-link-color);content:"";-webkit-mask-image:url("data:image/svg+xml,%3Csvg version=%271.1%27 xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M480.768 351.488l-47.104 47.104q-5.632 5.12-13.312 5.12t-12.8-5.12l-151.552-152.064-151.552 152.064q-5.632 5.12-12.8 5.12t-12.8-5.12l-47.616-47.104q-5.632-5.632-5.632-13.312t5.632-12.8l211.968-211.968q5.632-5.12 12.8-5.12t12.8 5.12l211.968 211.968q5.632 5.632 5.632 12.8t-5.632 13.312z%27%3E%3C/path%3E%3C/svg%3E%0A")}.form-label{margin-bottom:.5rem}.col-form-label{padding-top:1px;padding-bottom:1px;margin-bottom:0;font-size:inherit;line-height:1.875rem}.col-form-label-lg{padding-top:1px;padding-bottom:1px;font-size:.75rem}.col-form-label-sm{padding-top:1px;padding-bottom:1px;font-size:.75rem}.form-text{margin-top:.25rem;font-size:.875em;color:var(--t42-content-color-muted)}.form-control{display:block;width:100%;padding:0 .875rem;font-size:.75rem;font-weight:400;line-height:1.875rem;color:var(--t42-link-color);background-color:var(--t42-input-bg);background-clip:padding-box;border:1px solid var(--t42-color-opacity-10);appearance:none;border-radius:0;transition:border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.form-control{transition:none}}.form-control[type="file"]{overflow:hidden}.form-control[type="file"]:not(:disabled):not([readonly]){cursor:pointer}.form-control:focus{color:var(--t42-link-color);background-color:var(--t42-input-bg);border-color:#007be5;outline:0;box-shadow:0 0 0 0 rgba(0,123,229,0.25)}.form-control::-webkit-date-and-time-value{height:1.875rem}.form-control::placeholder{color:var(--t42-content-color-muted);opacity:1}.form-control:disabled,.form-control[readonly]{background-color:var(--t42-input-disabled-bg);opacity:1}.form-control::file-selector-button{padding:0 .875rem;margin:0 -.875rem;margin-inline-end:.875rem;color:var(--t42-link-color);background-color:#e9ecef;pointer-events:none;border-color:inherit;border-style:solid;border-width:0;border-inline-end-width:1px;border-radius:0;transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.form-control::file-selector-button{transition:none}}.form-control:hover:not(:disabled):not([readonly])::file-selector-button{background-color:#dde0e3}.form-control::-webkit-file-upload-button{padding:0 .875rem;margin:0 -.875rem;margin-inline-end:.875rem;color:var(--t42-link-color);background-color:#e9ecef;pointer-events:none;border-color:inherit;border-style:solid;border-width:0;border-inline-end-width:1px;border-radius:0;transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.form-control::-webkit-file-upload-button{transition:none}}.form-control:hover:not(:disabled):not([readonly])::-webkit-file-upload-button{background-color:#dde0e3}.form-control-plaintext{display:block;width:100%;padding:0 0;margin-bottom:0;line-height:1.875rem;color:var(--t42-content-color);background-color:transparent;border:solid transparent;border-width:1px 0}.form-control-plaintext.form-control-sm,.form-control-plaintext.form-control-lg{padding-right:0;padding-left:0}.form-control-sm{min-height:2rem;padding:0 .875rem;font-size:.75rem;border-radius:0}.form-control-sm::file-selector-button{padding:0 .875rem;margin:0 -.875rem;margin-inline-end:.875rem}.form-control-sm::-webkit-file-upload-button{padding:0 .875rem;margin:0 -.875rem;margin-inline-end:.875rem}.form-control-lg{min-height:2rem;padding:0 .875rem;font-size:.75rem;border-radius:0}.form-control-lg::file-selector-button{padding:0 .875rem;margin:0 -.875rem;margin-inline-end:.875rem}.form-control-lg::-webkit-file-upload-button{padding:0 .875rem;margin:0 -.875rem;margin-inline-end:.875rem}textarea.form-control{min-height:2rem}textarea.form-control-sm{min-height:2rem}textarea.form-control-lg{min-height:2rem}.form-control-color{width:3rem;height:auto;padding:0}.form-control-color:not(:disabled):not([readonly]){cursor:pointer}.form-control-color::-moz-color-swatch{height:1.875rem;border-radius:0}.form-control-color::-webkit-color-swatch{height:1.875rem;border-radius:0}.form-select{display:block;width:100%;padding:0 2.625rem 0 .875rem;-moz-padding-start:calc(.875rem - 3px);font-size:.75rem;font-weight:400;line-height:1.875rem;color:var(--t42-link-color);background-color:var(--t42-input-bg);background-image:var(--t42-select-indicator);background-repeat:no-repeat;background-position:right 0.5rem center;background-size:1rem;border:1px solid var(--t42-color-opacity-10);border-radius:0;transition:border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out;appearance:none}@media (prefers-reduced-motion: reduce){.form-select{transition:none}}.form-select:focus{border-color:#007be5;outline:0;box-shadow:0 0 0 0 rgba(0,123,229,0.25)}.form-select[multiple],.form-select[size]:not([size="1"]){padding-right:.875rem;background-image:none}.form-select:disabled{background-color:#e9ecef}.form-select:-moz-focusring{color:transparent;text-shadow:0 0 0 var(--t42-link-color)}.form-select-sm{padding-top:0;padding-bottom:0;padding-left:.875rem;font-size:.75rem;border-radius:0}.form-select-lg{padding-top:0;padding-bottom:0;padding-left:.875rem;font-size:.75rem;border-radius:0}.form-check{display:block;min-height:1.125rem;padding-left:1.25rem;margin-bottom:0}.form-check .form-check-input{float:left;margin-left:-1.25rem}.form-check-input{width:1em;height:1em;margin-top:.25em;vertical-align:top;background-color:var(--t42-input-bg);background-repeat:no-repeat;background-position:center;background-size:contain;border:1px solid rgba(0,0,0,0.25);appearance:none;color-adjust:exact}.form-check-input[type="checkbox"]{border-radius:.25em}.form-check-input[type="radio"]{border-radius:50%}.form-check-input:active{filter:brightness(90%)}.form-check-input:focus{border-color:#007be5;outline:0;box-shadow:0 0 0 0 rgba(0,123,229,0.25)}.form-check-input:checked{background-color:#007be5;border-color:#007be5}.form-check-input:checked[type="checkbox"]{background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 20 20%27%3e%3cpath fill=%27none%27 stroke=%27%23fff%27 stroke-linecap=%27round%27 stroke-linejoin=%27round%27 stroke-width=%273%27 d=%27M6 10l3 3l6-6%27/%3e%3c/svg%3e")}.form-check-input:checked[type="radio"]{background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%27-4 -4 8 8%27%3e%3ccircle r=%272%27 fill=%27%23fff%27/%3e%3c/svg%3e")}.form-check-input[type="checkbox"]:indeterminate{background-color:#007be5;border-color:#007be5;background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 20 20%27%3e%3cpath fill=%27none%27 stroke=%27%23fff%27 stroke-linecap=%27round%27 stroke-linejoin=%27round%27 stroke-width=%273%27 d=%27M6 10h8%27/%3e%3c/svg%3e")}.form-check-input:disabled{pointer-events:none;filter:none;opacity:.5}.form-check-input[disabled] ~ .form-check-label,.form-check-input:disabled ~ .form-check-label{opacity:.5}.form-switch{padding-left:2.5em}.form-switch .form-check-input{width:2em;margin-left:-2.5em;background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%27-4 -4 8 8%27%3e%3ccircle r=%273%27 fill=%27rgba%280,0,0,0.25%29%27/%3e%3c/svg%3e");background-position:left center;border-radius:2em;transition:background-position 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.form-switch .form-check-input{transition:none}}.form-switch .form-check-input:focus{background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%27-4 -4 8 8%27%3e%3ccircle r=%273%27 fill=%27%23007be5%27/%3e%3c/svg%3e")}.form-switch .form-check-input:checked{background-position:right center;background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%27-4 -4 8 8%27%3e%3ccircle r=%273%27 fill=%27%23fff%27/%3e%3c/svg%3e")}.form-check-inline{display:inline-block;margin-right:1rem}.btn-check{position:absolute;clip:rect(0, 0, 0, 0);pointer-events:none}.btn-check[disabled]+.btn,.btn-check:disabled+.btn{pointer-events:none;filter:none;opacity:.35}.form-range{width:100%;height:1rem;padding:0;background-color:transparent;appearance:none}.form-range:focus{outline:0}.form-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 0 rgba(0,123,229,0.25)}.form-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 0 rgba(0,123,229,0.25)}.form-range::-moz-focus-outer{border:0}.form-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-.25rem;background-color:#007be5;border:0;border-radius:1rem;transition:background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out;appearance:none}@media (prefers-reduced-motion: reduce){.form-range::-webkit-slider-thumb{transition:none}}.form-range::-webkit-slider-thumb:active{background-color:#b3d7f7}.form-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.form-range::-moz-range-thumb{width:1rem;height:1rem;background-color:#007be5;border:0;border-radius:1rem;transition:background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out;appearance:none}@media (prefers-reduced-motion: reduce){.form-range::-moz-range-thumb{transition:none}}.form-range::-moz-range-thumb:active{background-color:#b3d7f7}.form-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.form-range:disabled{pointer-events:none}.form-range:disabled::-webkit-slider-thumb{background-color:#adb5bd}.form-range:disabled::-moz-range-thumb{background-color:#adb5bd}.form-floating{position:relative}.form-floating>.form-control,.form-floating>.form-select{height:calc(3.5rem + 2px);line-height:1.25}.form-floating>label{position:absolute;top:0;left:0;height:100%;padding:1rem .875rem;pointer-events:none;border:1px solid transparent;transform-origin:0 0;transition:opacity 0.1s ease-in-out,transform 0.1s ease-in-out}@media (prefers-reduced-motion: reduce){.form-floating>label{transition:none}}.form-floating>.form-control{padding:1rem .875rem}.form-floating>.form-control::placeholder{color:transparent}.form-floating>.form-control:focus,.form-floating>.form-control:not(:placeholder-shown){padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control:-webkit-autofill{padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-select{padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control:focus ~ label,.form-floating>.form-control:not(:placeholder-shown) ~ label,.form-floating>.form-select ~ label{opacity:.65;transform:scale(0.85) translateY(-0.5rem) translateX(0.15rem)}.form-floating>.form-control:-webkit-autofill ~ label{opacity:.65;transform:scale(0.85) translateY(-0.5rem) translateX(0.15rem)}.input-group{position:relative;display:flex;flex-wrap:wrap;align-items:stretch;width:100%}.input-group>.form-control,.input-group>.form-select{position:relative;flex:1 1 auto;width:1%;min-width:0}.input-group>.form-control:focus,.input-group>.form-select:focus{z-index:3}.input-group .btn{position:relative;z-index:2}.input-group .btn:focus{z-index:3}.input-group-text{display:flex;align-items:center;padding:0 .875rem;font-size:.75rem;font-weight:400;line-height:1.875rem;color:var(--t42-content-color);text-align:center;white-space:nowrap;background-color:#e9ecef;border:1px solid var(--t42-color-opacity-10);border-radius:0}.input-group-lg>.form-control,.input-group-lg>.form-select,.input-group-lg>.input-group-text,.input-group-lg>.btn{padding:0 .875rem;font-size:.75rem;border-radius:0}.input-group-sm>.form-control,.input-group-sm>.form-select,.input-group-sm>.input-group-text,.input-group-sm>.btn{padding:0 .875rem;font-size:.75rem;border-radius:0}.input-group-lg>.form-select,.input-group-sm>.form-select{padding-right:3.5rem}.input-group:not(.has-validation)>:not(:last-child):not(.dropdown-toggle):not(.dropdown-menu),.input-group:not(.has-validation)>.dropdown-toggle:nth-last-child(n+3){border-top-right-radius:0;border-bottom-right-radius:0}.input-group.has-validation>:nth-last-child(n+3):not(.dropdown-toggle):not(.dropdown-menu),.input-group.has-validation>.dropdown-toggle:nth-last-child(n+4){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>:not(:first-child):not(.dropdown-menu):not(.valid-tooltip):not(.valid-feedback):not(.invalid-tooltip):not(.invalid-feedback){margin-left:-1px;border-top-left-radius:0;border-bottom-left-radius:0}.valid-feedback{display:none;width:100%;margin-top:.5rem;font-size:.7rem;color:#43a047}.valid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem 1rem;margin-top:.1rem;font-size:.65625rem;color:#000;background-color:#43a047;border-radius:0}.was-validated :valid ~ .valid-feedback,.was-validated :valid ~ .valid-tooltip,.is-valid ~ .valid-feedback,.is-valid ~ .valid-tooltip{display:block}.was-validated .form-control:valid,.form-control.is-valid{border-color:#43a047;padding-right:2rem;background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 8 8%27%3e%3cpath fill=%27%2343a047%27 d=%27M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z%27/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right .5rem center;background-size:1rem 1rem}.was-validated .form-control:valid:focus,.form-control.is-valid:focus{border-color:#43a047;box-shadow:0 0 0 0 rgba(67,160,71,0.25)}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{padding-right:2rem;background-position:top .5rem right .5rem}.was-validated .form-select:valid,.form-select.is-valid{border-color:#43a047}.was-validated .form-select:valid:not([multiple]):not([size]),.was-validated .form-select:valid:not([multiple])[size="1"],.form-select.is-valid:not([multiple]):not([size]),.form-select.is-valid:not([multiple])[size="1"]{padding-right:3.5rem;background-image:var(--t42-select-indicator),url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 8 8%27%3e%3cpath fill=%27%2343a047%27 d=%27M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z%27/%3e%3c/svg%3e");background-position:right 0.5rem center,right 1.75rem center;background-size:1rem,1rem}.was-validated .form-select:valid:focus,.form-select.is-valid:focus{border-color:#43a047;box-shadow:0 0 0 0 rgba(67,160,71,0.25)}.was-validated .form-check-input:valid,.form-check-input.is-valid{border-color:#43a047}.was-validated .form-check-input:valid:checked,.form-check-input.is-valid:checked{background-color:#43a047}.was-validated .form-check-input:valid:focus,.form-check-input.is-valid:focus{box-shadow:0 0 0 0 rgba(67,160,71,0.25)}.was-validated .form-check-input:valid ~ .form-check-label,.form-check-input.is-valid ~ .form-check-label{color:#43a047}.form-check-inline .form-check-input ~ .valid-feedback{margin-left:.5em}.was-validated .input-group .form-control:valid,.input-group .form-control.is-valid,.was-validated .input-group .form-select:valid,.input-group .form-select.is-valid{z-index:1}.was-validated .input-group .form-control:valid:focus,.input-group .form-control.is-valid:focus,.was-validated .input-group .form-select:valid:focus,.input-group .form-select.is-valid:focus{z-index:3}.invalid-feedback{display:none;width:100%;margin-top:.5rem;font-size:.7rem;color:#ff511f}.invalid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem 1rem;margin-top:.1rem;font-size:.65625rem;color:#000;background-color:#ff511f;border-radius:0}.was-validated :invalid ~ .invalid-feedback,.was-validated :invalid ~ .invalid-tooltip,.is-invalid ~ .invalid-feedback,.is-invalid ~ .invalid-tooltip{display:block}.was-validated .form-control:invalid,.form-control.is-invalid{border-color:#ff511f;padding-right:2rem;background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 12 12%27 width=%2712%27 height=%2712%27 fill=%27none%27 stroke=%27%23ff511f%27%3e%3ccircle cx=%276%27 cy=%276%27 r=%274.5%27/%3e%3cpath stroke-linejoin=%27round%27 d=%27M5.8 3.6h.4L6 6.5z%27/%3e%3ccircle cx=%276%27 cy=%278.2%27 r=%27.6%27 fill=%27%23ff511f%27 stroke=%27none%27/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right .5rem center;background-size:1rem 1rem}.was-validated .form-control:invalid:focus,.form-control.is-invalid:focus{border-color:#ff511f;box-shadow:0 0 0 0 rgba(255,81,31,0.25)}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{padding-right:2rem;background-position:top .5rem right .5rem}.was-validated .form-select:invalid,.form-select.is-invalid{border-color:#ff511f}.was-validated .form-select:invalid:not([multiple]):not([size]),.was-validated .form-select:invalid:not([multiple])[size="1"],.form-select.is-invalid:not([multiple]):not([size]),.form-select.is-invalid:not([multiple])[size="1"]{padding-right:3.5rem;background-image:var(--t42-select-indicator),url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 12 12%27 width=%2712%27 height=%2712%27 fill=%27none%27 stroke=%27%23ff511f%27%3e%3ccircle cx=%276%27 cy=%276%27 r=%274.5%27/%3e%3cpath stroke-linejoin=%27round%27 d=%27M5.8 3.6h.4L6 6.5z%27/%3e%3ccircle cx=%276%27 cy=%278.2%27 r=%27.6%27 fill=%27%23ff511f%27 stroke=%27none%27/%3e%3c/svg%3e");background-position:right 0.5rem center,right 1.75rem center;background-size:1rem,1rem}.was-validated .form-select:invalid:focus,.form-select.is-invalid:focus{border-color:#ff511f;box-shadow:0 0 0 0 rgba(255,81,31,0.25)}.was-validated .form-check-input:invalid,.form-check-input.is-invalid{border-color:#ff511f}.was-validated .form-check-input:invalid:checked,.form-check-input.is-invalid:checked{background-color:#ff511f}.was-validated .form-check-input:invalid:focus,.form-check-input.is-invalid:focus{box-shadow:0 0 0 0 rgba(255,81,31,0.25)}.was-validated .form-check-input:invalid ~ .form-check-label,.form-check-input.is-invalid ~ .form-check-label{color:#ff511f}.form-check-inline .form-check-input ~ .invalid-feedback{margin-left:.5em}.was-validated .input-group .form-control:invalid,.input-group .form-control.is-invalid,.was-validated .input-group .form-select:invalid,.input-group .form-select.is-invalid{z-index:2}.was-validated .input-group .form-control:invalid:focus,.input-group .form-control.is-invalid:focus,.was-validated .input-group .form-select:invalid:focus,.input-group .form-select.is-invalid:focus{z-index:3}input{background-color:var(--t42-input-bg)}input[type="number"]::-webkit-calendar-picker-indicator,input[type="datetime-local"]::-webkit-calendar-picker-indicator,input[type="month"]::-webkit-calendar-picker-indicator,input[type="week"]::-webkit-calendar-picker-indicator,input[type="time"]::-webkit-calendar-picker-indicator,input[type="date"]::-webkit-calendar-picker-indicator{background:transparent}input[type="number"]::-webkit-inner-spin-button,input[type="datetime-local"]::-webkit-inner-spin-button,input[type="month"]::-webkit-inner-spin-button,input[type="week"]::-webkit-inner-spin-button,input[type="time"]::-webkit-inner-spin-button,input[type="date"]::-webkit-inner-spin-button{appearance:none}input[type="color"],input[type="range"]{padding:0;border:0}form div[class^="col"]{position:relative}.form-check-label input[type="checkbox"],.form-check-label input[type="radio"]{margin-top:0.125rem;margin-left:-1.2rem;opacity:1}.form-check .form-check-input:disabled{opacity:0}.form-check-label{margin-bottom:0}.form-check-inline .form-check-label{padding-left:0.25rem}.form-check-inline input[type="radio"]:checked+label::after{left:-1rem}.form-control{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border;background-color:transparent}.form-control:disabled,.form-control.disabled,.form-control[readonly]{cursor:default;opacity:0.65}.form-control.is-valid,.form-control.is-invalid{border-color:var(--t42-color-opacity-10)}.form-control.is-valid:focus,.form-control.is-invalid:focus{border-color:var(--primary);box-shadow:none}.form-control[type="file"]{opacity:0}.form-text{color:var(--secondary)}.form-control-plaintext:focus{outline:0}select{background-image:var(--t42-select-indicator);background-repeat:no-repeat;background-position:right 0.5rem center;background-size:1rem;cursor:pointer;appearance:none}select[multiple]{padding:0;background-image:none}select[multiple] option{padding:0 0.875rem}select[multiple] option:checked{background-color:var(--primary)}select:disabled{border-color:transparent;cursor:default;opacity:0.65}textarea,textarea.form-control{min-height:90px;max-height:180px;padding-top:5px;padding-bottom:5px}textarea:disabled,textarea.form-control:disabled{border-color:transparent}input[type="range"]{width:100%;appearance:none}input[type="range"]:focus{background-color:transparent;outline:none}input[type="range"]:focus::-ms-fill-lower,input[type="range"]:focus::-ms-fill-upper{background:var(--primary)}input[type="range"]::-webkit-slider-runnable-track{width:100%;height:0.0625rem;border:0;border-radius:0;background:var(--t42-color-opacity-10);box-shadow:none;cursor:pointer}input[type="range"]::-webkit-slider-thumb{width:12px;height:12px;margin-top:-5px;border:0;border-radius:50%;background:var(--primary);box-shadow:none;cursor:pointer;appearance:none}input[type="range"]:focus::-webkit-slider-runnable-track{background:var(--t42-color-opacity-10)}input[type="range"]::-moz-range-track{width:100%;height:2px;border:0;border-radius:0;background:var(--t42-color-opacity-10);box-shadow:none;cursor:pointer}input[type="range"]::-moz-range-thumb{width:12px;height:12px;border:0;border-radius:50px;background:var(--primary);box-shadow:none;cursor:pointer}input[type="range"]::-ms-track{width:100%;height:2px;border-color:transparent;color:transparent;background:transparent;cursor:pointer}input[type="range"]::-ms-fill-lower,input[type="range"]::-ms-fill-upper{border:0;border-radius:0;background:var(--primary);box-shadow:none}input[type="range"]::-ms-thumb{width:12px;height:12px;border:0;border-radius:50px;background:var(--primary);box-shadow:none;cursor:pointer}input[type="checkbox"]{opacity:0}input[type="checkbox"]+label{position:relative;color:var(--t42-content-color-muted);cursor:pointer;user-select:none}input[type="checkbox"]+label::before{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, border-color;position:absolute;top:0.0625rem;left:-1.25rem;display:block;width:0.875rem;height:0.875rem;border:0.0625rem solid var(--t42-content-color-muted);border-radius:0;cursor:pointer;content:"";pointer-events:all}input[type="checkbox"]+label::after{position:absolute;top:0.125rem;left:-1.188rem;display:block;width:0.875rem;height:0.875rem;background-image:none;content:"";-webkit-mask-size:0.75rem;-webkit-mask-repeat:no-repeat;content:""}input[type="checkbox"].indeterminate+label::before,input[type="checkbox"]:indeterminate+label::before{border-color:var(--t42-color-opacity-30);background-color:var(--primary)}input[type="checkbox"].indeterminate+label::after,input[type="checkbox"]:indeterminate+label::after{top:0.375rem;left:-1.063rem;width:0.5rem;height:0.188rem;background-color:var(--white)}input[type="checkbox"]:disabled+label,input[type="checkbox"]:disabled+.form-check-label{color:var(--t42-content-color-disabled)}input[type="checkbox"]:checked.disabled+label,input[type="checkbox"]:checked:disabled+label,input[type="checkbox"]:indeterminate.disabled+label,input[type="checkbox"]:indeterminate:disabled+label,input[type="checkbox"].disabled+label,input[type="checkbox"]:disabled+label{color:var(--t42-content-color-disabled)}input[type="checkbox"]:checked.disabled+label::before,input[type="checkbox"]:checked:disabled+label::before,input[type="checkbox"]:indeterminate.disabled+label::before,input[type="checkbox"]:indeterminate:disabled+label::before,input[type="checkbox"].disabled+label::before,input[type="checkbox"]:disabled+label::before{border-color:transparent;background-color:var(--t42-color-opacity-10)}input[type="checkbox"]:checked+label::before{border-color:var(--t42-color-opacity-30);background-color:var(--primary)}input[type="checkbox"]:checked+label::after{background-color:var(--t42-link-color);-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M212.48599,435.14899c-11.60532,0.00003-21.16266-4.77866-28.672-14.336l-92.16-120.832 c-5.46133-8.19202-7.50933-17.06665-6.144-26.62399s5.80267-17.408,13.312-23.552s16.21333-8.53334,26.112-7.168 c9.89867,1.36533,17.92,6.14401,24.064,14.336l60.416,78.84799L360.966,93.13298c5.46133-8.192,12.79999-13.312,22.01599-15.36 s18.26132-0.68267,27.13599,4.096c8.19199,5.46133,13.31198,12.8,15.35999,22.016s0.68265,18.26133-4.09601,27.136l-179.2,286.71997 c-6.82668,10.9227-16.384,16.384-28.672,16.384L212.48599,435.14899z%27/%3E%3C/svg%3E")}input[type="radio"]{opacity:0}input[type="radio"]+label{position:relative;color:var(--t42-content-color-muted);cursor:pointer;user-select:none}input[type="radio"]+label::before{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, border;position:absolute;top:0.0625rem;left:-1.25rem;display:block;width:0.875rem;height:0.875rem;border:0.0625rem solid var(--t42-content-color-muted);border-radius:50%;cursor:pointer;content:"";pointer-events:all}input[type="radio"]+label::after{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, border;position:absolute;top:0.313rem;left:-1rem;display:block;width:0.375rem;height:0.375rem;border-radius:50%;color:var(--white);background-image:none;transform:scale(0);opacity:0;content:""}input[type="radio"]+label:focus{border-color:var(--primary)}input[type="radio"]:disabled+label,input[type="radio"]:disabled+.form-check-label{color:var(--t42-content-color-disabled)}input[type="radio"]:checked.disabled+label,input[type="radio"]:checked:disabled+label,input[type="radio"].disabled+label,input[type="radio"]:disabled+label{color:var(--t42-content-color-disabled)}input[type="radio"]:checked.disabled+label::before,input[type="radio"]:checked:disabled+label::before,input[type="radio"].disabled+label::before,input[type="radio"]:disabled+label::before{border-color:transparent;background-color:var(--t42-color-opacity-10)}input[type="radio"]:checked+label::before{border-color:var(--t42-color-opacity-30);background-color:var(--primary)}input[type="radio"]:checked+label::after{background-color:var(--white);transform:scale(1);opacity:1}.custom-control{padding-left:1.25rem}.custom-control .custom-control-input:checked ~ .custom-control-label::before{border-color:var(--t42-color-opacity-30)}.custom-select,.form-select{max-height:2rem;background-color:transparent;background-image:var(--t42-select-indicator);background-repeat:no-repeat;background-position:right 0.5rem center;background-size:1rem}.custom-select:focus,.custom-select option,.form-select:focus,.form-select option{background-color:var(--t42-input-bg)}.custom-select:disabled option,.form-select:disabled option{background-color:transparent}.custom-radio .custom-control-label{color:var(--t42-content-color-muted);user-select:none}.custom-radio .custom-control-label::after{background:none}.custom-radio .custom-control-input:checked ~ .custom-control-label::after{background-image:none}.custom-checkbox .custom-control-label{color:var(--t42-content-color-muted);user-select:none}.custom-checkbox .custom-control-label::after{background:none}.custom-checkbox .custom-control-input:checked ~ .custom-control-label::after{background-image:none}.custom-checkbox .custom-control-input:disabled .custom-control-label::after,.custom-checkbox .custom-control-input:disabled:checked ~ .custom-control-label::after,.custom-checkbox .custom-control-input:disabled:indeterminate ~ .custom-control-label::after{opacity:0.4}.custom-checkbox .custom-control-input:disabled ~ .custom-control-label::before{border-color:transparent}.switch{position:relative;display:inline-block;align-items:center;height:0.875rem;margin-bottom:0;padding-left:2rem;cursor:pointer}.switch.disabled{color:var(--t42-content-color-disabled)}.switch .slider{position:absolute;top:0;right:0;bottom:0;left:0;width:1.75rem;border:1px solid var(--t42-content-color-muted);cursor:pointer;transition:0.4s}.switch .slider::before{position:absolute;bottom:0.125rem;left:0.125rem;width:0.5rem;height:0.5rem;background-color:var(--t42-content-color-muted);transition:0.4s;content:""}.switch input{width:0;height:0;opacity:0}.switch input:checked+.slider{border:var(--t42-border);background-color:var(--primary)}.switch input:checked+.slider::before{background-color:var(--white);transform:translateX(0.875rem)}.switch input:focus+.slider{box-shadow:0 0 1px #2196f3}.switch input:disabled+.slider{border:var(--t42-border);background-color:var(--t42-color-opacity-10)}.switch input:disabled+.slider::before{background-color:var(--t42-color-opacity-20)}.input-group-prepend .input-group-text{justify-content:center;border-right:0}.input-group-append .input-group-text{justify-content:center;border-left:0}.input-group-append .custom-control,.input-group-prepend .custom-control{margin-bottom:0;padding-left:0.875rem}.input-group-append .custom-control-label,.input-group-prepend .custom-control-label{position:absolute;left:0;min-width:0.875rem;min-height:0.875rem}.input-group-append .custom-control-label::before,.input-group-prepend .custom-control-label::before{left:0}.input-group-append .custom-control-label::after,.input-group-prepend .custom-control-label::after{left:0.25rem}.input-group-append .custom-checkbox .custom-control-label::after,.input-group-prepend .custom-checkbox .custom-control-label::after{left:0.125rem}.custom-file{margin-bottom:1rem}.custom-file-input,.form-control[type="file"]{z-index:1}.custom-file-input:focus ~ .custom-file-label,.form-control[type="file"]:focus ~ .custom-file-label{background-color:var(--t42-input-bg)}.custom-file-label,.input-group-text{background-color:transparent}.custom-file-label::after,.input-group-text::after{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color;background-color:Rgba(--secondary, 0.05);cursor:pointer}.custom-file-label:hover::after,.input-group-text:hover::after{color:var(--white);background-color:var(--secondary)}.form-control[type="file"]+.input-group-text{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color,color;position:absolute;top:0;right:0;left:0;z-index:1;height:2rem;padding:0.375rem 0.875rem;border:var(--t42-border);color:var(--t42-content-color-muted)}.form-control[type="file"]+.input-group-text::after{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color,color;position:absolute;top:0;right:0;bottom:0;z-index:3;display:block;height:100%;padding:0.375rem 0.875rem;border-left:inherit;color:var(--t42-link-color);line-height:1.5;cursor:pointer;content:"Browse"}.form-control[type="file"]+.input-group-text:hover{background-color:var(--t42-input-bg)}.form-control[type="file"]+.input-group-text:hover::after{color:var(--white);background-color:var(--secondary)}.custom-switch{padding-left:2rem}.custom-switch .custom-control-label::before{left:-2rem}.custom-switch .custom-control-label::after{top:0.25rem;left:-1.813rem;width:0.5rem;height:0.5rem}.custom-switch .custom-control-input:checked ~ .custom-control-label::after{background-color:var(--white);content:""}.custom-switch .custom-control-input:not(:disabled):active ~ .custom-control-label::before{border-color:var(--t42-color-opacity-30);background-color:var(--primary)}.valid-feedback,.valid-tooltip,.invalid-feedback,.invalid-tooltip,.warning-feedback,.warning-tooltip{position:absolute;bottom:-1rem;width:calc(100% - 1.875rem);margin-top:0;overflow:hidden;color:var(--t42-content-color);font-size:.7rem;white-space:nowrap;text-overflow:ellipsis}.valid-tooltip,.invalid-tooltip,.warning-tooltip{color:var(--t42-content-color-muted)}.custom-radio label+div,.custom-checkbox label+div,.form-check label+div{width:calc(100% + 1.25rem);transform:translateX(-1.25rem)}.form-group{margin-bottom:1rem}label{margin-bottom:0.5rem}.form-row{display:flex;flex-wrap:wrap;margin-right:-0.5rem;margin-left:-0.5rem}.form-row>.col,.form-row>[class*="col-"]{padding-right:0.5rem;padding-left:0.5rem}.form-inline{display:flex;flex-flow:row wrap;align-items:center}.form-inline .form-check{width:100%}@media (min-width: 576px){.form-inline label{display:flex;align-items:center;justify-content:center;margin-bottom:0}.form-inline .form-group{display:flex;flex:0 0 auto;flex-flow:row wrap;align-items:center;margin-bottom:0}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-plaintext{display:inline-block}.form-inline .input-group,.form-inline .custom-select,.form-inline .form-select{width:auto}.form-inline .form-check{display:flex;align-items:center;justify-content:center;width:auto;padding-left:0}.form-inline .form-check-input{position:relative;flex-shrink:0;margin-top:0;margin-left:0}.form-inline .custom-control{align-items:center;justify-content:center}.form-inline .custom-control-label{margin-bottom:0}}/*! + * Bootstrap Grid v5.1.3 (https://getbootstrap.com/) + * Copyright 2011-2021 The Bootstrap Authors + * Copyright 2011-2021 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) + */:root{--bs-blue: #007be5;--bs-indigo: #6610f2;--bs-purple: #6f42c1;--bs-pink: #fd397a;--bs-red: #ff511f;--bs-orange: #fd7e14;--bs-yellow: #f9a825;--bs-green: #43a047;--bs-teal: #616161;--bs-cyan: #469eb9;--bs-white: #fff;--bs-gray: #6c757d;--bs-gray-dark: #343a40;--bs-gray-100: #f8f9fa;--bs-gray-200: #e9ecef;--bs-gray-300: #dee2e6;--bs-gray-400: #ced4da;--bs-gray-500: #adb5bd;--bs-gray-600: #6c757d;--bs-gray-700: #495057;--bs-gray-800: #343a40;--bs-gray-900: #212529;--bs-primary: #007be5;--bs-secondary: #616161;--bs-success: #43a047;--bs-info: #469eb9;--bs-warning: #f9a825;--bs-danger: #ff511f;--bs-light: #616161;--bs-dark: #616161;--bs-primary-rgb: 0,123,229;--bs-secondary-rgb: 97,97,97;--bs-success-rgb: 67,160,71;--bs-info-rgb: 70,158,185;--bs-warning-rgb: 249,168,37;--bs-danger-rgb: 255,81,31;--bs-light-rgb: 97,97,97;--bs-dark-rgb: 97,97,97;--bs-white-rgb: 255,255,255;--bs-black-rgb: 0,0,0;--bs-body-color-rgb: 33,37,41;--bs-body-bg-rgb: 255,255,255;--bs-font-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--bs-gradient: linear-gradient(180deg, rgba(255,255,255,0.15), rgba(255,255,255,0));--bs-body-font-family: Montserrat,Helvetica Neue,Arial,sans-serif;--bs-body-font-size: .75rem;--bs-body-font-weight: 400;--bs-body-line-height: 1.5;--bs-body-color: #212529;--bs-body-bg: #fff}.container,.container-fluid,.container-sm,.container-md,.container-lg,.container-xl,.container-xxl{width:100%;padding-right:var(--bs-gutter-x, .75rem);padding-left:var(--bs-gutter-x, .75rem);margin-right:auto;margin-left:auto}@media (min-width: 576px){.container,.container-sm{max-width:540px}}@media (min-width: 768px){.container,.container-sm,.container-md{max-width:720px}}@media (min-width: 992px){.container,.container-sm,.container-md,.container-lg{max-width:960px}}@media (min-width: 1200px){.container,.container-sm,.container-md,.container-lg,.container-xl{max-width:1140px}}@media (min-width: 1400px){.container,.container-sm,.container-md,.container-lg,.container-xl,.container-xxl{max-width:1320px}}.row{--bs-gutter-x: 1.5rem;--bs-gutter-y: 0;display:flex;flex-wrap:wrap;margin-top:calc(-1 * var(--bs-gutter-y));margin-right:calc(-.5 * var(--bs-gutter-x));margin-left:calc(-.5 * var(--bs-gutter-x))}.row>*{box-sizing:border-box;flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--bs-gutter-x) * .5);padding-left:calc(var(--bs-gutter-x) * .5);margin-top:var(--bs-gutter-y)}.col{flex:1 0 0%}.row-cols-auto>*{flex:0 0 auto;width:auto}.row-cols-1>*{flex:0 0 auto;width:100%}.row-cols-2>*{flex:0 0 auto;width:50%}.row-cols-3>*{flex:0 0 auto;width:33.33333%}.row-cols-4>*{flex:0 0 auto;width:25%}.row-cols-5>*{flex:0 0 auto;width:20%}.row-cols-6>*{flex:0 0 auto;width:16.66667%}.col-auto{flex:0 0 auto;width:auto}.col-1{flex:0 0 auto;width:8.33333%}.col-2{flex:0 0 auto;width:16.66667%}.col-3{flex:0 0 auto;width:25%}.col-4{flex:0 0 auto;width:33.33333%}.col-5{flex:0 0 auto;width:41.66667%}.col-6{flex:0 0 auto;width:50%}.col-7{flex:0 0 auto;width:58.33333%}.col-8{flex:0 0 auto;width:66.66667%}.col-9{flex:0 0 auto;width:75%}.col-10{flex:0 0 auto;width:83.33333%}.col-11{flex:0 0 auto;width:91.66667%}.col-12{flex:0 0 auto;width:100%}.offset-1{margin-left:8.33333%}.offset-2{margin-left:16.66667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.33333%}.offset-5{margin-left:41.66667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.33333%}.offset-8{margin-left:66.66667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.33333%}.offset-11{margin-left:91.66667%}.g-0,.gx-0{--bs-gutter-x: 0}.g-0,.gy-0{--bs-gutter-y: 0}.g-1,.gx-1{--bs-gutter-x: .25rem}.g-1,.gy-1{--bs-gutter-y: .25rem}.g-2,.gx-2{--bs-gutter-x: .5rem}.g-2,.gy-2{--bs-gutter-y: .5rem}.g-3,.gx-3{--bs-gutter-x: 1rem}.g-3,.gy-3{--bs-gutter-y: 1rem}.g-4,.gx-4{--bs-gutter-x: 1.5rem}.g-4,.gy-4{--bs-gutter-y: 1.5rem}.g-5,.gx-5{--bs-gutter-x: 3rem}.g-5,.gy-5{--bs-gutter-y: 3rem}@media (min-width: 576px){.col-sm{flex:1 0 0%}.row-cols-sm-auto>*{flex:0 0 auto;width:auto}.row-cols-sm-1>*{flex:0 0 auto;width:100%}.row-cols-sm-2>*{flex:0 0 auto;width:50%}.row-cols-sm-3>*{flex:0 0 auto;width:33.33333%}.row-cols-sm-4>*{flex:0 0 auto;width:25%}.row-cols-sm-5>*{flex:0 0 auto;width:20%}.row-cols-sm-6>*{flex:0 0 auto;width:16.66667%}.col-sm-auto{flex:0 0 auto;width:auto}.col-sm-1{flex:0 0 auto;width:8.33333%}.col-sm-2{flex:0 0 auto;width:16.66667%}.col-sm-3{flex:0 0 auto;width:25%}.col-sm-4{flex:0 0 auto;width:33.33333%}.col-sm-5{flex:0 0 auto;width:41.66667%}.col-sm-6{flex:0 0 auto;width:50%}.col-sm-7{flex:0 0 auto;width:58.33333%}.col-sm-8{flex:0 0 auto;width:66.66667%}.col-sm-9{flex:0 0 auto;width:75%}.col-sm-10{flex:0 0 auto;width:83.33333%}.col-sm-11{flex:0 0 auto;width:91.66667%}.col-sm-12{flex:0 0 auto;width:100%}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.33333%}.offset-sm-2{margin-left:16.66667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.33333%}.offset-sm-5{margin-left:41.66667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.33333%}.offset-sm-8{margin-left:66.66667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.33333%}.offset-sm-11{margin-left:91.66667%}.g-sm-0,.gx-sm-0{--bs-gutter-x: 0}.g-sm-0,.gy-sm-0{--bs-gutter-y: 0}.g-sm-1,.gx-sm-1{--bs-gutter-x: .25rem}.g-sm-1,.gy-sm-1{--bs-gutter-y: .25rem}.g-sm-2,.gx-sm-2{--bs-gutter-x: .5rem}.g-sm-2,.gy-sm-2{--bs-gutter-y: .5rem}.g-sm-3,.gx-sm-3{--bs-gutter-x: 1rem}.g-sm-3,.gy-sm-3{--bs-gutter-y: 1rem}.g-sm-4,.gx-sm-4{--bs-gutter-x: 1.5rem}.g-sm-4,.gy-sm-4{--bs-gutter-y: 1.5rem}.g-sm-5,.gx-sm-5{--bs-gutter-x: 3rem}.g-sm-5,.gy-sm-5{--bs-gutter-y: 3rem}}@media (min-width: 768px){.col-md{flex:1 0 0%}.row-cols-md-auto>*{flex:0 0 auto;width:auto}.row-cols-md-1>*{flex:0 0 auto;width:100%}.row-cols-md-2>*{flex:0 0 auto;width:50%}.row-cols-md-3>*{flex:0 0 auto;width:33.33333%}.row-cols-md-4>*{flex:0 0 auto;width:25%}.row-cols-md-5>*{flex:0 0 auto;width:20%}.row-cols-md-6>*{flex:0 0 auto;width:16.66667%}.col-md-auto{flex:0 0 auto;width:auto}.col-md-1{flex:0 0 auto;width:8.33333%}.col-md-2{flex:0 0 auto;width:16.66667%}.col-md-3{flex:0 0 auto;width:25%}.col-md-4{flex:0 0 auto;width:33.33333%}.col-md-5{flex:0 0 auto;width:41.66667%}.col-md-6{flex:0 0 auto;width:50%}.col-md-7{flex:0 0 auto;width:58.33333%}.col-md-8{flex:0 0 auto;width:66.66667%}.col-md-9{flex:0 0 auto;width:75%}.col-md-10{flex:0 0 auto;width:83.33333%}.col-md-11{flex:0 0 auto;width:91.66667%}.col-md-12{flex:0 0 auto;width:100%}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.33333%}.offset-md-2{margin-left:16.66667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.33333%}.offset-md-5{margin-left:41.66667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.33333%}.offset-md-8{margin-left:66.66667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.33333%}.offset-md-11{margin-left:91.66667%}.g-md-0,.gx-md-0{--bs-gutter-x: 0}.g-md-0,.gy-md-0{--bs-gutter-y: 0}.g-md-1,.gx-md-1{--bs-gutter-x: .25rem}.g-md-1,.gy-md-1{--bs-gutter-y: .25rem}.g-md-2,.gx-md-2{--bs-gutter-x: .5rem}.g-md-2,.gy-md-2{--bs-gutter-y: .5rem}.g-md-3,.gx-md-3{--bs-gutter-x: 1rem}.g-md-3,.gy-md-3{--bs-gutter-y: 1rem}.g-md-4,.gx-md-4{--bs-gutter-x: 1.5rem}.g-md-4,.gy-md-4{--bs-gutter-y: 1.5rem}.g-md-5,.gx-md-5{--bs-gutter-x: 3rem}.g-md-5,.gy-md-5{--bs-gutter-y: 3rem}}@media (min-width: 992px){.col-lg{flex:1 0 0%}.row-cols-lg-auto>*{flex:0 0 auto;width:auto}.row-cols-lg-1>*{flex:0 0 auto;width:100%}.row-cols-lg-2>*{flex:0 0 auto;width:50%}.row-cols-lg-3>*{flex:0 0 auto;width:33.33333%}.row-cols-lg-4>*{flex:0 0 auto;width:25%}.row-cols-lg-5>*{flex:0 0 auto;width:20%}.row-cols-lg-6>*{flex:0 0 auto;width:16.66667%}.col-lg-auto{flex:0 0 auto;width:auto}.col-lg-1{flex:0 0 auto;width:8.33333%}.col-lg-2{flex:0 0 auto;width:16.66667%}.col-lg-3{flex:0 0 auto;width:25%}.col-lg-4{flex:0 0 auto;width:33.33333%}.col-lg-5{flex:0 0 auto;width:41.66667%}.col-lg-6{flex:0 0 auto;width:50%}.col-lg-7{flex:0 0 auto;width:58.33333%}.col-lg-8{flex:0 0 auto;width:66.66667%}.col-lg-9{flex:0 0 auto;width:75%}.col-lg-10{flex:0 0 auto;width:83.33333%}.col-lg-11{flex:0 0 auto;width:91.66667%}.col-lg-12{flex:0 0 auto;width:100%}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.33333%}.offset-lg-2{margin-left:16.66667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.33333%}.offset-lg-5{margin-left:41.66667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.33333%}.offset-lg-8{margin-left:66.66667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.33333%}.offset-lg-11{margin-left:91.66667%}.g-lg-0,.gx-lg-0{--bs-gutter-x: 0}.g-lg-0,.gy-lg-0{--bs-gutter-y: 0}.g-lg-1,.gx-lg-1{--bs-gutter-x: .25rem}.g-lg-1,.gy-lg-1{--bs-gutter-y: .25rem}.g-lg-2,.gx-lg-2{--bs-gutter-x: .5rem}.g-lg-2,.gy-lg-2{--bs-gutter-y: .5rem}.g-lg-3,.gx-lg-3{--bs-gutter-x: 1rem}.g-lg-3,.gy-lg-3{--bs-gutter-y: 1rem}.g-lg-4,.gx-lg-4{--bs-gutter-x: 1.5rem}.g-lg-4,.gy-lg-4{--bs-gutter-y: 1.5rem}.g-lg-5,.gx-lg-5{--bs-gutter-x: 3rem}.g-lg-5,.gy-lg-5{--bs-gutter-y: 3rem}}@media (min-width: 1200px){.col-xl{flex:1 0 0%}.row-cols-xl-auto>*{flex:0 0 auto;width:auto}.row-cols-xl-1>*{flex:0 0 auto;width:100%}.row-cols-xl-2>*{flex:0 0 auto;width:50%}.row-cols-xl-3>*{flex:0 0 auto;width:33.33333%}.row-cols-xl-4>*{flex:0 0 auto;width:25%}.row-cols-xl-5>*{flex:0 0 auto;width:20%}.row-cols-xl-6>*{flex:0 0 auto;width:16.66667%}.col-xl-auto{flex:0 0 auto;width:auto}.col-xl-1{flex:0 0 auto;width:8.33333%}.col-xl-2{flex:0 0 auto;width:16.66667%}.col-xl-3{flex:0 0 auto;width:25%}.col-xl-4{flex:0 0 auto;width:33.33333%}.col-xl-5{flex:0 0 auto;width:41.66667%}.col-xl-6{flex:0 0 auto;width:50%}.col-xl-7{flex:0 0 auto;width:58.33333%}.col-xl-8{flex:0 0 auto;width:66.66667%}.col-xl-9{flex:0 0 auto;width:75%}.col-xl-10{flex:0 0 auto;width:83.33333%}.col-xl-11{flex:0 0 auto;width:91.66667%}.col-xl-12{flex:0 0 auto;width:100%}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.33333%}.offset-xl-2{margin-left:16.66667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.33333%}.offset-xl-5{margin-left:41.66667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.33333%}.offset-xl-8{margin-left:66.66667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.33333%}.offset-xl-11{margin-left:91.66667%}.g-xl-0,.gx-xl-0{--bs-gutter-x: 0}.g-xl-0,.gy-xl-0{--bs-gutter-y: 0}.g-xl-1,.gx-xl-1{--bs-gutter-x: .25rem}.g-xl-1,.gy-xl-1{--bs-gutter-y: .25rem}.g-xl-2,.gx-xl-2{--bs-gutter-x: .5rem}.g-xl-2,.gy-xl-2{--bs-gutter-y: .5rem}.g-xl-3,.gx-xl-3{--bs-gutter-x: 1rem}.g-xl-3,.gy-xl-3{--bs-gutter-y: 1rem}.g-xl-4,.gx-xl-4{--bs-gutter-x: 1.5rem}.g-xl-4,.gy-xl-4{--bs-gutter-y: 1.5rem}.g-xl-5,.gx-xl-5{--bs-gutter-x: 3rem}.g-xl-5,.gy-xl-5{--bs-gutter-y: 3rem}}@media (min-width: 1400px){.col-xxl{flex:1 0 0%}.row-cols-xxl-auto>*{flex:0 0 auto;width:auto}.row-cols-xxl-1>*{flex:0 0 auto;width:100%}.row-cols-xxl-2>*{flex:0 0 auto;width:50%}.row-cols-xxl-3>*{flex:0 0 auto;width:33.33333%}.row-cols-xxl-4>*{flex:0 0 auto;width:25%}.row-cols-xxl-5>*{flex:0 0 auto;width:20%}.row-cols-xxl-6>*{flex:0 0 auto;width:16.66667%}.col-xxl-auto{flex:0 0 auto;width:auto}.col-xxl-1{flex:0 0 auto;width:8.33333%}.col-xxl-2{flex:0 0 auto;width:16.66667%}.col-xxl-3{flex:0 0 auto;width:25%}.col-xxl-4{flex:0 0 auto;width:33.33333%}.col-xxl-5{flex:0 0 auto;width:41.66667%}.col-xxl-6{flex:0 0 auto;width:50%}.col-xxl-7{flex:0 0 auto;width:58.33333%}.col-xxl-8{flex:0 0 auto;width:66.66667%}.col-xxl-9{flex:0 0 auto;width:75%}.col-xxl-10{flex:0 0 auto;width:83.33333%}.col-xxl-11{flex:0 0 auto;width:91.66667%}.col-xxl-12{flex:0 0 auto;width:100%}.offset-xxl-0{margin-left:0}.offset-xxl-1{margin-left:8.33333%}.offset-xxl-2{margin-left:16.66667%}.offset-xxl-3{margin-left:25%}.offset-xxl-4{margin-left:33.33333%}.offset-xxl-5{margin-left:41.66667%}.offset-xxl-6{margin-left:50%}.offset-xxl-7{margin-left:58.33333%}.offset-xxl-8{margin-left:66.66667%}.offset-xxl-9{margin-left:75%}.offset-xxl-10{margin-left:83.33333%}.offset-xxl-11{margin-left:91.66667%}.g-xxl-0,.gx-xxl-0{--bs-gutter-x: 0}.g-xxl-0,.gy-xxl-0{--bs-gutter-y: 0}.g-xxl-1,.gx-xxl-1{--bs-gutter-x: .25rem}.g-xxl-1,.gy-xxl-1{--bs-gutter-y: .25rem}.g-xxl-2,.gx-xxl-2{--bs-gutter-x: .5rem}.g-xxl-2,.gy-xxl-2{--bs-gutter-y: .5rem}.g-xxl-3,.gx-xxl-3{--bs-gutter-x: 1rem}.g-xxl-3,.gy-xxl-3{--bs-gutter-y: 1rem}.g-xxl-4,.gx-xxl-4{--bs-gutter-x: 1.5rem}.g-xxl-4,.gy-xxl-4{--bs-gutter-y: 1.5rem}.g-xxl-5,.gx-xxl-5{--bs-gutter-x: 3rem}.g-xxl-5,.gy-xxl-5{--bs-gutter-y: 3rem}}.d-inline{display:inline !important}.d-inline-block{display:inline-block !important}.d-block{display:block !important}.d-grid{display:grid !important}.d-table{display:table !important}.d-table-row{display:table-row !important}.d-table-cell{display:table-cell !important}.d-flex{display:flex !important}.d-inline-flex{display:inline-flex !important}.d-none{display:none !important}.flex-fill{flex:1 1 auto !important}.flex-row{flex-direction:row !important}.flex-column{flex-direction:column !important}.flex-row-reverse{flex-direction:row-reverse !important}.flex-column-reverse{flex-direction:column-reverse !important}.flex-grow-0{flex-grow:0 !important}.flex-grow-1{flex-grow:1 !important}.flex-shrink-0{flex-shrink:0 !important}.flex-shrink-1{flex-shrink:1 !important}.flex-wrap{flex-wrap:wrap !important}.flex-nowrap{flex-wrap:nowrap !important}.flex-wrap-reverse{flex-wrap:wrap-reverse !important}.justify-content-start{justify-content:flex-start !important}.justify-content-end{justify-content:flex-end !important}.justify-content-center{justify-content:center !important}.justify-content-between{justify-content:space-between !important}.justify-content-around{justify-content:space-around !important}.justify-content-evenly{justify-content:space-evenly !important}.align-items-start{align-items:flex-start !important}.align-items-end{align-items:flex-end !important}.align-items-center{align-items:center !important}.align-items-baseline{align-items:baseline !important}.align-items-stretch{align-items:stretch !important}.align-content-start{align-content:flex-start !important}.align-content-end{align-content:flex-end !important}.align-content-center{align-content:center !important}.align-content-between{align-content:space-between !important}.align-content-around{align-content:space-around !important}.align-content-stretch{align-content:stretch !important}.align-self-auto{align-self:auto !important}.align-self-start{align-self:flex-start !important}.align-self-end{align-self:flex-end !important}.align-self-center{align-self:center !important}.align-self-baseline{align-self:baseline !important}.align-self-stretch{align-self:stretch !important}.order-first{order:-1 !important}.order-0{order:0 !important}.order-1{order:1 !important}.order-2{order:2 !important}.order-3{order:3 !important}.order-4{order:4 !important}.order-5{order:5 !important}.order-last{order:6 !important}.m-0{margin:0 !important}.m-1{margin:.25rem !important}.m-2{margin:.5rem !important}.m-3{margin:1rem !important}.m-4{margin:1.5rem !important}.m-5{margin:3rem !important}.m-auto{margin:auto !important}.mx-0{margin-right:0 !important;margin-left:0 !important}.mx-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-3{margin-right:1rem !important;margin-left:1rem !important}.mx-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-5{margin-right:3rem !important;margin-left:3rem !important}.mx-auto{margin-right:auto !important;margin-left:auto !important}.my-0{margin-top:0 !important;margin-bottom:0 !important}.my-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-0{margin-top:0 !important}.mt-1{margin-top:.25rem !important}.mt-2{margin-top:.5rem !important}.mt-3{margin-top:1rem !important}.mt-4{margin-top:1.5rem !important}.mt-5{margin-top:3rem !important}.mt-auto{margin-top:auto !important}.me-0{margin-right:0 !important}.me-1{margin-right:.25rem !important}.me-2{margin-right:.5rem !important}.me-3{margin-right:1rem !important}.me-4{margin-right:1.5rem !important}.me-5{margin-right:3rem !important}.me-auto{margin-right:auto !important}.mb-0{margin-bottom:0 !important}.mb-1{margin-bottom:.25rem !important}.mb-2{margin-bottom:.5rem !important}.mb-3{margin-bottom:1rem !important}.mb-4{margin-bottom:1.5rem !important}.mb-5{margin-bottom:3rem !important}.mb-auto{margin-bottom:auto !important}.ms-0{margin-left:0 !important}.ms-1{margin-left:.25rem !important}.ms-2{margin-left:.5rem !important}.ms-3{margin-left:1rem !important}.ms-4{margin-left:1.5rem !important}.ms-5{margin-left:3rem !important}.ms-auto{margin-left:auto !important}.p-0{padding:0 !important}.p-1{padding:.25rem !important}.p-2{padding:.5rem !important}.p-3{padding:1rem !important}.p-4{padding:1.5rem !important}.p-5{padding:3rem !important}.px-0{padding-right:0 !important;padding-left:0 !important}.px-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-3{padding-right:1rem !important;padding-left:1rem !important}.px-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-5{padding-right:3rem !important;padding-left:3rem !important}.py-0{padding-top:0 !important;padding-bottom:0 !important}.py-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-0{padding-top:0 !important}.pt-1{padding-top:.25rem !important}.pt-2{padding-top:.5rem !important}.pt-3{padding-top:1rem !important}.pt-4{padding-top:1.5rem !important}.pt-5{padding-top:3rem !important}.pe-0{padding-right:0 !important}.pe-1{padding-right:.25rem !important}.pe-2{padding-right:.5rem !important}.pe-3{padding-right:1rem !important}.pe-4{padding-right:1.5rem !important}.pe-5{padding-right:3rem !important}.pb-0{padding-bottom:0 !important}.pb-1{padding-bottom:.25rem !important}.pb-2{padding-bottom:.5rem !important}.pb-3{padding-bottom:1rem !important}.pb-4{padding-bottom:1.5rem !important}.pb-5{padding-bottom:3rem !important}.ps-0{padding-left:0 !important}.ps-1{padding-left:.25rem !important}.ps-2{padding-left:.5rem !important}.ps-3{padding-left:1rem !important}.ps-4{padding-left:1.5rem !important}.ps-5{padding-left:3rem !important}@media (min-width: 576px){.d-sm-inline{display:inline !important}.d-sm-inline-block{display:inline-block !important}.d-sm-block{display:block !important}.d-sm-grid{display:grid !important}.d-sm-table{display:table !important}.d-sm-table-row{display:table-row !important}.d-sm-table-cell{display:table-cell !important}.d-sm-flex{display:flex !important}.d-sm-inline-flex{display:inline-flex !important}.d-sm-none{display:none !important}.flex-sm-fill{flex:1 1 auto !important}.flex-sm-row{flex-direction:row !important}.flex-sm-column{flex-direction:column !important}.flex-sm-row-reverse{flex-direction:row-reverse !important}.flex-sm-column-reverse{flex-direction:column-reverse !important}.flex-sm-grow-0{flex-grow:0 !important}.flex-sm-grow-1{flex-grow:1 !important}.flex-sm-shrink-0{flex-shrink:0 !important}.flex-sm-shrink-1{flex-shrink:1 !important}.flex-sm-wrap{flex-wrap:wrap !important}.flex-sm-nowrap{flex-wrap:nowrap !important}.flex-sm-wrap-reverse{flex-wrap:wrap-reverse !important}.justify-content-sm-start{justify-content:flex-start !important}.justify-content-sm-end{justify-content:flex-end !important}.justify-content-sm-center{justify-content:center !important}.justify-content-sm-between{justify-content:space-between !important}.justify-content-sm-around{justify-content:space-around !important}.justify-content-sm-evenly{justify-content:space-evenly !important}.align-items-sm-start{align-items:flex-start !important}.align-items-sm-end{align-items:flex-end !important}.align-items-sm-center{align-items:center !important}.align-items-sm-baseline{align-items:baseline !important}.align-items-sm-stretch{align-items:stretch !important}.align-content-sm-start{align-content:flex-start !important}.align-content-sm-end{align-content:flex-end !important}.align-content-sm-center{align-content:center !important}.align-content-sm-between{align-content:space-between !important}.align-content-sm-around{align-content:space-around !important}.align-content-sm-stretch{align-content:stretch !important}.align-self-sm-auto{align-self:auto !important}.align-self-sm-start{align-self:flex-start !important}.align-self-sm-end{align-self:flex-end !important}.align-self-sm-center{align-self:center !important}.align-self-sm-baseline{align-self:baseline !important}.align-self-sm-stretch{align-self:stretch !important}.order-sm-first{order:-1 !important}.order-sm-0{order:0 !important}.order-sm-1{order:1 !important}.order-sm-2{order:2 !important}.order-sm-3{order:3 !important}.order-sm-4{order:4 !important}.order-sm-5{order:5 !important}.order-sm-last{order:6 !important}.m-sm-0{margin:0 !important}.m-sm-1{margin:.25rem !important}.m-sm-2{margin:.5rem !important}.m-sm-3{margin:1rem !important}.m-sm-4{margin:1.5rem !important}.m-sm-5{margin:3rem !important}.m-sm-auto{margin:auto !important}.mx-sm-0{margin-right:0 !important;margin-left:0 !important}.mx-sm-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-sm-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-sm-3{margin-right:1rem !important;margin-left:1rem !important}.mx-sm-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-sm-5{margin-right:3rem !important;margin-left:3rem !important}.mx-sm-auto{margin-right:auto !important;margin-left:auto !important}.my-sm-0{margin-top:0 !important;margin-bottom:0 !important}.my-sm-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-sm-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-sm-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-sm-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-sm-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-sm-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-sm-0{margin-top:0 !important}.mt-sm-1{margin-top:.25rem !important}.mt-sm-2{margin-top:.5rem !important}.mt-sm-3{margin-top:1rem !important}.mt-sm-4{margin-top:1.5rem !important}.mt-sm-5{margin-top:3rem !important}.mt-sm-auto{margin-top:auto !important}.me-sm-0{margin-right:0 !important}.me-sm-1{margin-right:.25rem !important}.me-sm-2{margin-right:.5rem !important}.me-sm-3{margin-right:1rem !important}.me-sm-4{margin-right:1.5rem !important}.me-sm-5{margin-right:3rem !important}.me-sm-auto{margin-right:auto !important}.mb-sm-0{margin-bottom:0 !important}.mb-sm-1{margin-bottom:.25rem !important}.mb-sm-2{margin-bottom:.5rem !important}.mb-sm-3{margin-bottom:1rem !important}.mb-sm-4{margin-bottom:1.5rem !important}.mb-sm-5{margin-bottom:3rem !important}.mb-sm-auto{margin-bottom:auto !important}.ms-sm-0{margin-left:0 !important}.ms-sm-1{margin-left:.25rem !important}.ms-sm-2{margin-left:.5rem !important}.ms-sm-3{margin-left:1rem !important}.ms-sm-4{margin-left:1.5rem !important}.ms-sm-5{margin-left:3rem !important}.ms-sm-auto{margin-left:auto !important}.p-sm-0{padding:0 !important}.p-sm-1{padding:.25rem !important}.p-sm-2{padding:.5rem !important}.p-sm-3{padding:1rem !important}.p-sm-4{padding:1.5rem !important}.p-sm-5{padding:3rem !important}.px-sm-0{padding-right:0 !important;padding-left:0 !important}.px-sm-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-sm-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-sm-3{padding-right:1rem !important;padding-left:1rem !important}.px-sm-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-sm-5{padding-right:3rem !important;padding-left:3rem !important}.py-sm-0{padding-top:0 !important;padding-bottom:0 !important}.py-sm-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-sm-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-sm-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-sm-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-sm-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-sm-0{padding-top:0 !important}.pt-sm-1{padding-top:.25rem !important}.pt-sm-2{padding-top:.5rem !important}.pt-sm-3{padding-top:1rem !important}.pt-sm-4{padding-top:1.5rem !important}.pt-sm-5{padding-top:3rem !important}.pe-sm-0{padding-right:0 !important}.pe-sm-1{padding-right:.25rem !important}.pe-sm-2{padding-right:.5rem !important}.pe-sm-3{padding-right:1rem !important}.pe-sm-4{padding-right:1.5rem !important}.pe-sm-5{padding-right:3rem !important}.pb-sm-0{padding-bottom:0 !important}.pb-sm-1{padding-bottom:.25rem !important}.pb-sm-2{padding-bottom:.5rem !important}.pb-sm-3{padding-bottom:1rem !important}.pb-sm-4{padding-bottom:1.5rem !important}.pb-sm-5{padding-bottom:3rem !important}.ps-sm-0{padding-left:0 !important}.ps-sm-1{padding-left:.25rem !important}.ps-sm-2{padding-left:.5rem !important}.ps-sm-3{padding-left:1rem !important}.ps-sm-4{padding-left:1.5rem !important}.ps-sm-5{padding-left:3rem !important}}@media (min-width: 768px){.d-md-inline{display:inline !important}.d-md-inline-block{display:inline-block !important}.d-md-block{display:block !important}.d-md-grid{display:grid !important}.d-md-table{display:table !important}.d-md-table-row{display:table-row !important}.d-md-table-cell{display:table-cell !important}.d-md-flex{display:flex !important}.d-md-inline-flex{display:inline-flex !important}.d-md-none{display:none !important}.flex-md-fill{flex:1 1 auto !important}.flex-md-row{flex-direction:row !important}.flex-md-column{flex-direction:column !important}.flex-md-row-reverse{flex-direction:row-reverse !important}.flex-md-column-reverse{flex-direction:column-reverse !important}.flex-md-grow-0{flex-grow:0 !important}.flex-md-grow-1{flex-grow:1 !important}.flex-md-shrink-0{flex-shrink:0 !important}.flex-md-shrink-1{flex-shrink:1 !important}.flex-md-wrap{flex-wrap:wrap !important}.flex-md-nowrap{flex-wrap:nowrap !important}.flex-md-wrap-reverse{flex-wrap:wrap-reverse !important}.justify-content-md-start{justify-content:flex-start !important}.justify-content-md-end{justify-content:flex-end !important}.justify-content-md-center{justify-content:center !important}.justify-content-md-between{justify-content:space-between !important}.justify-content-md-around{justify-content:space-around !important}.justify-content-md-evenly{justify-content:space-evenly !important}.align-items-md-start{align-items:flex-start !important}.align-items-md-end{align-items:flex-end !important}.align-items-md-center{align-items:center !important}.align-items-md-baseline{align-items:baseline !important}.align-items-md-stretch{align-items:stretch !important}.align-content-md-start{align-content:flex-start !important}.align-content-md-end{align-content:flex-end !important}.align-content-md-center{align-content:center !important}.align-content-md-between{align-content:space-between !important}.align-content-md-around{align-content:space-around !important}.align-content-md-stretch{align-content:stretch !important}.align-self-md-auto{align-self:auto !important}.align-self-md-start{align-self:flex-start !important}.align-self-md-end{align-self:flex-end !important}.align-self-md-center{align-self:center !important}.align-self-md-baseline{align-self:baseline !important}.align-self-md-stretch{align-self:stretch !important}.order-md-first{order:-1 !important}.order-md-0{order:0 !important}.order-md-1{order:1 !important}.order-md-2{order:2 !important}.order-md-3{order:3 !important}.order-md-4{order:4 !important}.order-md-5{order:5 !important}.order-md-last{order:6 !important}.m-md-0{margin:0 !important}.m-md-1{margin:.25rem !important}.m-md-2{margin:.5rem !important}.m-md-3{margin:1rem !important}.m-md-4{margin:1.5rem !important}.m-md-5{margin:3rem !important}.m-md-auto{margin:auto !important}.mx-md-0{margin-right:0 !important;margin-left:0 !important}.mx-md-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-md-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-md-3{margin-right:1rem !important;margin-left:1rem !important}.mx-md-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-md-5{margin-right:3rem !important;margin-left:3rem !important}.mx-md-auto{margin-right:auto !important;margin-left:auto !important}.my-md-0{margin-top:0 !important;margin-bottom:0 !important}.my-md-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-md-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-md-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-md-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-md-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-md-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-md-0{margin-top:0 !important}.mt-md-1{margin-top:.25rem !important}.mt-md-2{margin-top:.5rem !important}.mt-md-3{margin-top:1rem !important}.mt-md-4{margin-top:1.5rem !important}.mt-md-5{margin-top:3rem !important}.mt-md-auto{margin-top:auto !important}.me-md-0{margin-right:0 !important}.me-md-1{margin-right:.25rem !important}.me-md-2{margin-right:.5rem !important}.me-md-3{margin-right:1rem !important}.me-md-4{margin-right:1.5rem !important}.me-md-5{margin-right:3rem !important}.me-md-auto{margin-right:auto !important}.mb-md-0{margin-bottom:0 !important}.mb-md-1{margin-bottom:.25rem !important}.mb-md-2{margin-bottom:.5rem !important}.mb-md-3{margin-bottom:1rem !important}.mb-md-4{margin-bottom:1.5rem !important}.mb-md-5{margin-bottom:3rem !important}.mb-md-auto{margin-bottom:auto !important}.ms-md-0{margin-left:0 !important}.ms-md-1{margin-left:.25rem !important}.ms-md-2{margin-left:.5rem !important}.ms-md-3{margin-left:1rem !important}.ms-md-4{margin-left:1.5rem !important}.ms-md-5{margin-left:3rem !important}.ms-md-auto{margin-left:auto !important}.p-md-0{padding:0 !important}.p-md-1{padding:.25rem !important}.p-md-2{padding:.5rem !important}.p-md-3{padding:1rem !important}.p-md-4{padding:1.5rem !important}.p-md-5{padding:3rem !important}.px-md-0{padding-right:0 !important;padding-left:0 !important}.px-md-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-md-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-md-3{padding-right:1rem !important;padding-left:1rem !important}.px-md-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-md-5{padding-right:3rem !important;padding-left:3rem !important}.py-md-0{padding-top:0 !important;padding-bottom:0 !important}.py-md-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-md-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-md-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-md-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-md-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-md-0{padding-top:0 !important}.pt-md-1{padding-top:.25rem !important}.pt-md-2{padding-top:.5rem !important}.pt-md-3{padding-top:1rem !important}.pt-md-4{padding-top:1.5rem !important}.pt-md-5{padding-top:3rem !important}.pe-md-0{padding-right:0 !important}.pe-md-1{padding-right:.25rem !important}.pe-md-2{padding-right:.5rem !important}.pe-md-3{padding-right:1rem !important}.pe-md-4{padding-right:1.5rem !important}.pe-md-5{padding-right:3rem !important}.pb-md-0{padding-bottom:0 !important}.pb-md-1{padding-bottom:.25rem !important}.pb-md-2{padding-bottom:.5rem !important}.pb-md-3{padding-bottom:1rem !important}.pb-md-4{padding-bottom:1.5rem !important}.pb-md-5{padding-bottom:3rem !important}.ps-md-0{padding-left:0 !important}.ps-md-1{padding-left:.25rem !important}.ps-md-2{padding-left:.5rem !important}.ps-md-3{padding-left:1rem !important}.ps-md-4{padding-left:1.5rem !important}.ps-md-5{padding-left:3rem !important}}@media (min-width: 992px){.d-lg-inline{display:inline !important}.d-lg-inline-block{display:inline-block !important}.d-lg-block{display:block !important}.d-lg-grid{display:grid !important}.d-lg-table{display:table !important}.d-lg-table-row{display:table-row !important}.d-lg-table-cell{display:table-cell !important}.d-lg-flex{display:flex !important}.d-lg-inline-flex{display:inline-flex !important}.d-lg-none{display:none !important}.flex-lg-fill{flex:1 1 auto !important}.flex-lg-row{flex-direction:row !important}.flex-lg-column{flex-direction:column !important}.flex-lg-row-reverse{flex-direction:row-reverse !important}.flex-lg-column-reverse{flex-direction:column-reverse !important}.flex-lg-grow-0{flex-grow:0 !important}.flex-lg-grow-1{flex-grow:1 !important}.flex-lg-shrink-0{flex-shrink:0 !important}.flex-lg-shrink-1{flex-shrink:1 !important}.flex-lg-wrap{flex-wrap:wrap !important}.flex-lg-nowrap{flex-wrap:nowrap !important}.flex-lg-wrap-reverse{flex-wrap:wrap-reverse !important}.justify-content-lg-start{justify-content:flex-start !important}.justify-content-lg-end{justify-content:flex-end !important}.justify-content-lg-center{justify-content:center !important}.justify-content-lg-between{justify-content:space-between !important}.justify-content-lg-around{justify-content:space-around !important}.justify-content-lg-evenly{justify-content:space-evenly !important}.align-items-lg-start{align-items:flex-start !important}.align-items-lg-end{align-items:flex-end !important}.align-items-lg-center{align-items:center !important}.align-items-lg-baseline{align-items:baseline !important}.align-items-lg-stretch{align-items:stretch !important}.align-content-lg-start{align-content:flex-start !important}.align-content-lg-end{align-content:flex-end !important}.align-content-lg-center{align-content:center !important}.align-content-lg-between{align-content:space-between !important}.align-content-lg-around{align-content:space-around !important}.align-content-lg-stretch{align-content:stretch !important}.align-self-lg-auto{align-self:auto !important}.align-self-lg-start{align-self:flex-start !important}.align-self-lg-end{align-self:flex-end !important}.align-self-lg-center{align-self:center !important}.align-self-lg-baseline{align-self:baseline !important}.align-self-lg-stretch{align-self:stretch !important}.order-lg-first{order:-1 !important}.order-lg-0{order:0 !important}.order-lg-1{order:1 !important}.order-lg-2{order:2 !important}.order-lg-3{order:3 !important}.order-lg-4{order:4 !important}.order-lg-5{order:5 !important}.order-lg-last{order:6 !important}.m-lg-0{margin:0 !important}.m-lg-1{margin:.25rem !important}.m-lg-2{margin:.5rem !important}.m-lg-3{margin:1rem !important}.m-lg-4{margin:1.5rem !important}.m-lg-5{margin:3rem !important}.m-lg-auto{margin:auto !important}.mx-lg-0{margin-right:0 !important;margin-left:0 !important}.mx-lg-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-lg-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-lg-3{margin-right:1rem !important;margin-left:1rem !important}.mx-lg-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-lg-5{margin-right:3rem !important;margin-left:3rem !important}.mx-lg-auto{margin-right:auto !important;margin-left:auto !important}.my-lg-0{margin-top:0 !important;margin-bottom:0 !important}.my-lg-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-lg-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-lg-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-lg-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-lg-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-lg-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-lg-0{margin-top:0 !important}.mt-lg-1{margin-top:.25rem !important}.mt-lg-2{margin-top:.5rem !important}.mt-lg-3{margin-top:1rem !important}.mt-lg-4{margin-top:1.5rem !important}.mt-lg-5{margin-top:3rem !important}.mt-lg-auto{margin-top:auto !important}.me-lg-0{margin-right:0 !important}.me-lg-1{margin-right:.25rem !important}.me-lg-2{margin-right:.5rem !important}.me-lg-3{margin-right:1rem !important}.me-lg-4{margin-right:1.5rem !important}.me-lg-5{margin-right:3rem !important}.me-lg-auto{margin-right:auto !important}.mb-lg-0{margin-bottom:0 !important}.mb-lg-1{margin-bottom:.25rem !important}.mb-lg-2{margin-bottom:.5rem !important}.mb-lg-3{margin-bottom:1rem !important}.mb-lg-4{margin-bottom:1.5rem !important}.mb-lg-5{margin-bottom:3rem !important}.mb-lg-auto{margin-bottom:auto !important}.ms-lg-0{margin-left:0 !important}.ms-lg-1{margin-left:.25rem !important}.ms-lg-2{margin-left:.5rem !important}.ms-lg-3{margin-left:1rem !important}.ms-lg-4{margin-left:1.5rem !important}.ms-lg-5{margin-left:3rem !important}.ms-lg-auto{margin-left:auto !important}.p-lg-0{padding:0 !important}.p-lg-1{padding:.25rem !important}.p-lg-2{padding:.5rem !important}.p-lg-3{padding:1rem !important}.p-lg-4{padding:1.5rem !important}.p-lg-5{padding:3rem !important}.px-lg-0{padding-right:0 !important;padding-left:0 !important}.px-lg-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-lg-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-lg-3{padding-right:1rem !important;padding-left:1rem !important}.px-lg-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-lg-5{padding-right:3rem !important;padding-left:3rem !important}.py-lg-0{padding-top:0 !important;padding-bottom:0 !important}.py-lg-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-lg-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-lg-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-lg-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-lg-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-lg-0{padding-top:0 !important}.pt-lg-1{padding-top:.25rem !important}.pt-lg-2{padding-top:.5rem !important}.pt-lg-3{padding-top:1rem !important}.pt-lg-4{padding-top:1.5rem !important}.pt-lg-5{padding-top:3rem !important}.pe-lg-0{padding-right:0 !important}.pe-lg-1{padding-right:.25rem !important}.pe-lg-2{padding-right:.5rem !important}.pe-lg-3{padding-right:1rem !important}.pe-lg-4{padding-right:1.5rem !important}.pe-lg-5{padding-right:3rem !important}.pb-lg-0{padding-bottom:0 !important}.pb-lg-1{padding-bottom:.25rem !important}.pb-lg-2{padding-bottom:.5rem !important}.pb-lg-3{padding-bottom:1rem !important}.pb-lg-4{padding-bottom:1.5rem !important}.pb-lg-5{padding-bottom:3rem !important}.ps-lg-0{padding-left:0 !important}.ps-lg-1{padding-left:.25rem !important}.ps-lg-2{padding-left:.5rem !important}.ps-lg-3{padding-left:1rem !important}.ps-lg-4{padding-left:1.5rem !important}.ps-lg-5{padding-left:3rem !important}}@media (min-width: 1200px){.d-xl-inline{display:inline !important}.d-xl-inline-block{display:inline-block !important}.d-xl-block{display:block !important}.d-xl-grid{display:grid !important}.d-xl-table{display:table !important}.d-xl-table-row{display:table-row !important}.d-xl-table-cell{display:table-cell !important}.d-xl-flex{display:flex !important}.d-xl-inline-flex{display:inline-flex !important}.d-xl-none{display:none !important}.flex-xl-fill{flex:1 1 auto !important}.flex-xl-row{flex-direction:row !important}.flex-xl-column{flex-direction:column !important}.flex-xl-row-reverse{flex-direction:row-reverse !important}.flex-xl-column-reverse{flex-direction:column-reverse !important}.flex-xl-grow-0{flex-grow:0 !important}.flex-xl-grow-1{flex-grow:1 !important}.flex-xl-shrink-0{flex-shrink:0 !important}.flex-xl-shrink-1{flex-shrink:1 !important}.flex-xl-wrap{flex-wrap:wrap !important}.flex-xl-nowrap{flex-wrap:nowrap !important}.flex-xl-wrap-reverse{flex-wrap:wrap-reverse !important}.justify-content-xl-start{justify-content:flex-start !important}.justify-content-xl-end{justify-content:flex-end !important}.justify-content-xl-center{justify-content:center !important}.justify-content-xl-between{justify-content:space-between !important}.justify-content-xl-around{justify-content:space-around !important}.justify-content-xl-evenly{justify-content:space-evenly !important}.align-items-xl-start{align-items:flex-start !important}.align-items-xl-end{align-items:flex-end !important}.align-items-xl-center{align-items:center !important}.align-items-xl-baseline{align-items:baseline !important}.align-items-xl-stretch{align-items:stretch !important}.align-content-xl-start{align-content:flex-start !important}.align-content-xl-end{align-content:flex-end !important}.align-content-xl-center{align-content:center !important}.align-content-xl-between{align-content:space-between !important}.align-content-xl-around{align-content:space-around !important}.align-content-xl-stretch{align-content:stretch !important}.align-self-xl-auto{align-self:auto !important}.align-self-xl-start{align-self:flex-start !important}.align-self-xl-end{align-self:flex-end !important}.align-self-xl-center{align-self:center !important}.align-self-xl-baseline{align-self:baseline !important}.align-self-xl-stretch{align-self:stretch !important}.order-xl-first{order:-1 !important}.order-xl-0{order:0 !important}.order-xl-1{order:1 !important}.order-xl-2{order:2 !important}.order-xl-3{order:3 !important}.order-xl-4{order:4 !important}.order-xl-5{order:5 !important}.order-xl-last{order:6 !important}.m-xl-0{margin:0 !important}.m-xl-1{margin:.25rem !important}.m-xl-2{margin:.5rem !important}.m-xl-3{margin:1rem !important}.m-xl-4{margin:1.5rem !important}.m-xl-5{margin:3rem !important}.m-xl-auto{margin:auto !important}.mx-xl-0{margin-right:0 !important;margin-left:0 !important}.mx-xl-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-xl-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-xl-3{margin-right:1rem !important;margin-left:1rem !important}.mx-xl-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-xl-5{margin-right:3rem !important;margin-left:3rem !important}.mx-xl-auto{margin-right:auto !important;margin-left:auto !important}.my-xl-0{margin-top:0 !important;margin-bottom:0 !important}.my-xl-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-xl-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-xl-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-xl-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-xl-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-xl-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-xl-0{margin-top:0 !important}.mt-xl-1{margin-top:.25rem !important}.mt-xl-2{margin-top:.5rem !important}.mt-xl-3{margin-top:1rem !important}.mt-xl-4{margin-top:1.5rem !important}.mt-xl-5{margin-top:3rem !important}.mt-xl-auto{margin-top:auto !important}.me-xl-0{margin-right:0 !important}.me-xl-1{margin-right:.25rem !important}.me-xl-2{margin-right:.5rem !important}.me-xl-3{margin-right:1rem !important}.me-xl-4{margin-right:1.5rem !important}.me-xl-5{margin-right:3rem !important}.me-xl-auto{margin-right:auto !important}.mb-xl-0{margin-bottom:0 !important}.mb-xl-1{margin-bottom:.25rem !important}.mb-xl-2{margin-bottom:.5rem !important}.mb-xl-3{margin-bottom:1rem !important}.mb-xl-4{margin-bottom:1.5rem !important}.mb-xl-5{margin-bottom:3rem !important}.mb-xl-auto{margin-bottom:auto !important}.ms-xl-0{margin-left:0 !important}.ms-xl-1{margin-left:.25rem !important}.ms-xl-2{margin-left:.5rem !important}.ms-xl-3{margin-left:1rem !important}.ms-xl-4{margin-left:1.5rem !important}.ms-xl-5{margin-left:3rem !important}.ms-xl-auto{margin-left:auto !important}.p-xl-0{padding:0 !important}.p-xl-1{padding:.25rem !important}.p-xl-2{padding:.5rem !important}.p-xl-3{padding:1rem !important}.p-xl-4{padding:1.5rem !important}.p-xl-5{padding:3rem !important}.px-xl-0{padding-right:0 !important;padding-left:0 !important}.px-xl-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-xl-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-xl-3{padding-right:1rem !important;padding-left:1rem !important}.px-xl-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-xl-5{padding-right:3rem !important;padding-left:3rem !important}.py-xl-0{padding-top:0 !important;padding-bottom:0 !important}.py-xl-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-xl-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-xl-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-xl-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-xl-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-xl-0{padding-top:0 !important}.pt-xl-1{padding-top:.25rem !important}.pt-xl-2{padding-top:.5rem !important}.pt-xl-3{padding-top:1rem !important}.pt-xl-4{padding-top:1.5rem !important}.pt-xl-5{padding-top:3rem !important}.pe-xl-0{padding-right:0 !important}.pe-xl-1{padding-right:.25rem !important}.pe-xl-2{padding-right:.5rem !important}.pe-xl-3{padding-right:1rem !important}.pe-xl-4{padding-right:1.5rem !important}.pe-xl-5{padding-right:3rem !important}.pb-xl-0{padding-bottom:0 !important}.pb-xl-1{padding-bottom:.25rem !important}.pb-xl-2{padding-bottom:.5rem !important}.pb-xl-3{padding-bottom:1rem !important}.pb-xl-4{padding-bottom:1.5rem !important}.pb-xl-5{padding-bottom:3rem !important}.ps-xl-0{padding-left:0 !important}.ps-xl-1{padding-left:.25rem !important}.ps-xl-2{padding-left:.5rem !important}.ps-xl-3{padding-left:1rem !important}.ps-xl-4{padding-left:1.5rem !important}.ps-xl-5{padding-left:3rem !important}}@media (min-width: 1400px){.d-xxl-inline{display:inline !important}.d-xxl-inline-block{display:inline-block !important}.d-xxl-block{display:block !important}.d-xxl-grid{display:grid !important}.d-xxl-table{display:table !important}.d-xxl-table-row{display:table-row !important}.d-xxl-table-cell{display:table-cell !important}.d-xxl-flex{display:flex !important}.d-xxl-inline-flex{display:inline-flex !important}.d-xxl-none{display:none !important}.flex-xxl-fill{flex:1 1 auto !important}.flex-xxl-row{flex-direction:row !important}.flex-xxl-column{flex-direction:column !important}.flex-xxl-row-reverse{flex-direction:row-reverse !important}.flex-xxl-column-reverse{flex-direction:column-reverse !important}.flex-xxl-grow-0{flex-grow:0 !important}.flex-xxl-grow-1{flex-grow:1 !important}.flex-xxl-shrink-0{flex-shrink:0 !important}.flex-xxl-shrink-1{flex-shrink:1 !important}.flex-xxl-wrap{flex-wrap:wrap !important}.flex-xxl-nowrap{flex-wrap:nowrap !important}.flex-xxl-wrap-reverse{flex-wrap:wrap-reverse !important}.justify-content-xxl-start{justify-content:flex-start !important}.justify-content-xxl-end{justify-content:flex-end !important}.justify-content-xxl-center{justify-content:center !important}.justify-content-xxl-between{justify-content:space-between !important}.justify-content-xxl-around{justify-content:space-around !important}.justify-content-xxl-evenly{justify-content:space-evenly !important}.align-items-xxl-start{align-items:flex-start !important}.align-items-xxl-end{align-items:flex-end !important}.align-items-xxl-center{align-items:center !important}.align-items-xxl-baseline{align-items:baseline !important}.align-items-xxl-stretch{align-items:stretch !important}.align-content-xxl-start{align-content:flex-start !important}.align-content-xxl-end{align-content:flex-end !important}.align-content-xxl-center{align-content:center !important}.align-content-xxl-between{align-content:space-between !important}.align-content-xxl-around{align-content:space-around !important}.align-content-xxl-stretch{align-content:stretch !important}.align-self-xxl-auto{align-self:auto !important}.align-self-xxl-start{align-self:flex-start !important}.align-self-xxl-end{align-self:flex-end !important}.align-self-xxl-center{align-self:center !important}.align-self-xxl-baseline{align-self:baseline !important}.align-self-xxl-stretch{align-self:stretch !important}.order-xxl-first{order:-1 !important}.order-xxl-0{order:0 !important}.order-xxl-1{order:1 !important}.order-xxl-2{order:2 !important}.order-xxl-3{order:3 !important}.order-xxl-4{order:4 !important}.order-xxl-5{order:5 !important}.order-xxl-last{order:6 !important}.m-xxl-0{margin:0 !important}.m-xxl-1{margin:.25rem !important}.m-xxl-2{margin:.5rem !important}.m-xxl-3{margin:1rem !important}.m-xxl-4{margin:1.5rem !important}.m-xxl-5{margin:3rem !important}.m-xxl-auto{margin:auto !important}.mx-xxl-0{margin-right:0 !important;margin-left:0 !important}.mx-xxl-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-xxl-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-xxl-3{margin-right:1rem !important;margin-left:1rem !important}.mx-xxl-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-xxl-5{margin-right:3rem !important;margin-left:3rem !important}.mx-xxl-auto{margin-right:auto !important;margin-left:auto !important}.my-xxl-0{margin-top:0 !important;margin-bottom:0 !important}.my-xxl-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-xxl-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-xxl-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-xxl-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-xxl-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-xxl-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-xxl-0{margin-top:0 !important}.mt-xxl-1{margin-top:.25rem !important}.mt-xxl-2{margin-top:.5rem !important}.mt-xxl-3{margin-top:1rem !important}.mt-xxl-4{margin-top:1.5rem !important}.mt-xxl-5{margin-top:3rem !important}.mt-xxl-auto{margin-top:auto !important}.me-xxl-0{margin-right:0 !important}.me-xxl-1{margin-right:.25rem !important}.me-xxl-2{margin-right:.5rem !important}.me-xxl-3{margin-right:1rem !important}.me-xxl-4{margin-right:1.5rem !important}.me-xxl-5{margin-right:3rem !important}.me-xxl-auto{margin-right:auto !important}.mb-xxl-0{margin-bottom:0 !important}.mb-xxl-1{margin-bottom:.25rem !important}.mb-xxl-2{margin-bottom:.5rem !important}.mb-xxl-3{margin-bottom:1rem !important}.mb-xxl-4{margin-bottom:1.5rem !important}.mb-xxl-5{margin-bottom:3rem !important}.mb-xxl-auto{margin-bottom:auto !important}.ms-xxl-0{margin-left:0 !important}.ms-xxl-1{margin-left:.25rem !important}.ms-xxl-2{margin-left:.5rem !important}.ms-xxl-3{margin-left:1rem !important}.ms-xxl-4{margin-left:1.5rem !important}.ms-xxl-5{margin-left:3rem !important}.ms-xxl-auto{margin-left:auto !important}.p-xxl-0{padding:0 !important}.p-xxl-1{padding:.25rem !important}.p-xxl-2{padding:.5rem !important}.p-xxl-3{padding:1rem !important}.p-xxl-4{padding:1.5rem !important}.p-xxl-5{padding:3rem !important}.px-xxl-0{padding-right:0 !important;padding-left:0 !important}.px-xxl-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-xxl-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-xxl-3{padding-right:1rem !important;padding-left:1rem !important}.px-xxl-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-xxl-5{padding-right:3rem !important;padding-left:3rem !important}.py-xxl-0{padding-top:0 !important;padding-bottom:0 !important}.py-xxl-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-xxl-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-xxl-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-xxl-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-xxl-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-xxl-0{padding-top:0 !important}.pt-xxl-1{padding-top:.25rem !important}.pt-xxl-2{padding-top:.5rem !important}.pt-xxl-3{padding-top:1rem !important}.pt-xxl-4{padding-top:1.5rem !important}.pt-xxl-5{padding-top:3rem !important}.pe-xxl-0{padding-right:0 !important}.pe-xxl-1{padding-right:.25rem !important}.pe-xxl-2{padding-right:.5rem !important}.pe-xxl-3{padding-right:1rem !important}.pe-xxl-4{padding-right:1.5rem !important}.pe-xxl-5{padding-right:3rem !important}.pb-xxl-0{padding-bottom:0 !important}.pb-xxl-1{padding-bottom:.25rem !important}.pb-xxl-2{padding-bottom:.5rem !important}.pb-xxl-3{padding-bottom:1rem !important}.pb-xxl-4{padding-bottom:1.5rem !important}.pb-xxl-5{padding-bottom:3rem !important}.ps-xxl-0{padding-left:0 !important}.ps-xxl-1{padding-left:.25rem !important}.ps-xxl-2{padding-left:.5rem !important}.ps-xxl-3{padding-left:1rem !important}.ps-xxl-4{padding-left:1.5rem !important}.ps-xxl-5{padding-left:3rem !important}}@media print{.d-print-inline{display:inline !important}.d-print-inline-block{display:inline-block !important}.d-print-block{display:block !important}.d-print-grid{display:grid !important}.d-print-table{display:table !important}.d-print-table-row{display:table-row !important}.d-print-table-cell{display:table-cell !important}.d-print-flex{display:flex !important}.d-print-inline-flex{display:inline-flex !important}.d-print-none{display:none !important}}.row{--bs-gutter-x: 1.875rem}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:#fff;border:1px solid #dee2e6;border-radius:.25rem;max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:.875em;color:#6c757d}.list-group{display:flex;flex-direction:column;padding-left:0;margin-bottom:0;border-radius:0}.list-group-numbered{list-style-type:none;counter-reset:section}.list-group-numbered>li::before{content:counters(section, ".") ". ";counter-increment:section}.list-group-item-action{width:100%;color:var(--t42-content-color);text-align:inherit}.list-group-item-action:hover,.list-group-item-action:focus{z-index:1;color:var(--t42-link-hover-color);text-decoration:none;background-color:var(--t42-link-hover-bg)}.list-group-item-action:active{color:var(--t42-link-hover-color);background-color:var(--t42-link-active-bg)}.list-group-item{position:relative;display:block;padding:.75rem 1.25rem;color:inherit;text-decoration:none;background-color:Rgb(var(--t42-bg-mid));border:1px solid rgba(0,0,0,0)}.list-group-item:first-child{border-top-left-radius:inherit;border-top-right-radius:inherit}.list-group-item:last-child{border-bottom-right-radius:inherit;border-bottom-left-radius:inherit}.list-group-item.disabled,.list-group-item:disabled{color:var(--t42-content-color-disabled);pointer-events:none;background-color:rgba(0,0,0,0)}.list-group-item.active{z-index:2;color:var(--t42-link-hover-color);background-color:var(--t42-link-active-bg);border-color:rgba(0,0,0,0)}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{margin-top:-1px;border-top-width:1px}.list-group-horizontal{flex-direction:row}.list-group-horizontal>.list-group-item:first-child{border-bottom-left-radius:0;border-top-right-radius:0}.list-group-horizontal>.list-group-item:last-child{border-top-right-radius:0;border-bottom-left-radius:0}.list-group-horizontal>.list-group-item.active{margin-top:0}.list-group-horizontal>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}@media (min-width: 576px){.list-group-horizontal-sm{flex-direction:row}.list-group-horizontal-sm>.list-group-item:first-child{border-bottom-left-radius:0;border-top-right-radius:0}.list-group-horizontal-sm>.list-group-item:last-child{border-top-right-radius:0;border-bottom-left-radius:0}.list-group-horizontal-sm>.list-group-item.active{margin-top:0}.list-group-horizontal-sm>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-sm>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width: 768px){.list-group-horizontal-md{flex-direction:row}.list-group-horizontal-md>.list-group-item:first-child{border-bottom-left-radius:0;border-top-right-radius:0}.list-group-horizontal-md>.list-group-item:last-child{border-top-right-radius:0;border-bottom-left-radius:0}.list-group-horizontal-md>.list-group-item.active{margin-top:0}.list-group-horizontal-md>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-md>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width: 992px){.list-group-horizontal-lg{flex-direction:row}.list-group-horizontal-lg>.list-group-item:first-child{border-bottom-left-radius:0;border-top-right-radius:0}.list-group-horizontal-lg>.list-group-item:last-child{border-top-right-radius:0;border-bottom-left-radius:0}.list-group-horizontal-lg>.list-group-item.active{margin-top:0}.list-group-horizontal-lg>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-lg>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width: 1200px){.list-group-horizontal-xl{flex-direction:row}.list-group-horizontal-xl>.list-group-item:first-child{border-bottom-left-radius:0;border-top-right-radius:0}.list-group-horizontal-xl>.list-group-item:last-child{border-top-right-radius:0;border-bottom-left-radius:0}.list-group-horizontal-xl>.list-group-item.active{margin-top:0}.list-group-horizontal-xl>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-xl>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width: 1400px){.list-group-horizontal-xxl{flex-direction:row}.list-group-horizontal-xxl>.list-group-item:first-child{border-bottom-left-radius:0;border-top-right-radius:0}.list-group-horizontal-xxl>.list-group-item:last-child{border-top-right-radius:0;border-bottom-left-radius:0}.list-group-horizontal-xxl>.list-group-item.active{margin-top:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}.list-group-flush{border-radius:0}.list-group-flush>.list-group-item{border-width:0 0 1px}.list-group-flush>.list-group-item:last-child{border-bottom-width:0}.list-group-item-primary{color:#004a89;background-color:#cce5fa}.list-group-item-primary.list-group-item-action:hover,.list-group-item-primary.list-group-item-action:focus{color:#004a89;background-color:#b8cee1}.list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#004a89;border-color:#004a89}.list-group-item-secondary{color:#3a3a3a;background-color:#dfdfdf}.list-group-item-secondary.list-group-item-action:hover,.list-group-item-secondary.list-group-item-action:focus{color:#3a3a3a;background-color:#c9c9c9}.list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#3a3a3a;border-color:#3a3a3a}.list-group-item-success{color:#28602b;background-color:#d9ecda}.list-group-item-success.list-group-item-action:hover,.list-group-item-success.list-group-item-action:focus{color:#28602b;background-color:#c3d4c4}.list-group-item-success.list-group-item-action.active{color:#fff;background-color:#28602b;border-color:#28602b}.list-group-item-info{color:#2a5f6f;background-color:#daecf1}.list-group-item-info.list-group-item-action:hover,.list-group-item-info.list-group-item-action:focus{color:#2a5f6f;background-color:#c4d4d9}.list-group-item-info.list-group-item-action.active{color:#fff;background-color:#2a5f6f;border-color:#2a5f6f}.list-group-item-warning{color:#64430f;background-color:#feeed3}.list-group-item-warning.list-group-item-action:hover,.list-group-item-warning.list-group-item-action:focus{color:#64430f;background-color:#e5d6be}.list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#64430f;border-color:#64430f}.list-group-item-danger{color:#993113;background-color:#ffdcd2}.list-group-item-danger.list-group-item-action:hover,.list-group-item-danger.list-group-item-action:focus{color:#993113;background-color:#e6c6bd}.list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#993113;border-color:#993113}.list-group-item-light{color:#3a3a3a;background-color:#dfdfdf}.list-group-item-light.list-group-item-action:hover,.list-group-item-light.list-group-item-action:focus{color:#3a3a3a;background-color:#c9c9c9}.list-group-item-light.list-group-item-action.active{color:#fff;background-color:#3a3a3a;border-color:#3a3a3a}.list-group-item-dark{color:#3a3a3a;background-color:#dfdfdf}.list-group-item-dark.list-group-item-action:hover,.list-group-item-dark.list-group-item-action:focus{color:#3a3a3a;background-color:#c9c9c9}.list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#3a3a3a;border-color:#3a3a3a}.list-unstyled{padding-left:0;list-style:none}.list-group{box-shadow:var(--t42-shadow)}.list-group-item{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:color;margin-bottom:0;border:0;border-bottom:var(--t42-border);backdrop-filter:var(--backdrop-filter)}.list-group-item:last-child{border-bottom:transparent}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{margin-top:0;border-top-width:0}.list-group-item-action{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background,color;transition-duration:0.25s}.list-group-item-action:hover,.list-group-item-action:focus{background-color:var(--t42-list-group-hover-bg-special)}.list-group-item-action.active:hover{background-color:var(--t42-color-opacity-05)}.modal{position:fixed;top:0;left:0;z-index:1055;display:none;width:100%;height:100%;overflow-x:hidden;overflow-y:auto;outline:0}.modal-dialog{position:relative;width:auto;margin:.5rem;pointer-events:none}.modal.fade .modal-dialog{transition:transform 0.3s ease-out;transform:translate(0, -50px)}@media (prefers-reduced-motion: reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{transform:none}.modal.modal-static .modal-dialog{transform:scale(1.02)}.modal-dialog-scrollable{height:calc(100% - 1rem)}.modal-dialog-scrollable .modal-content{max-height:100%;overflow:hidden}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{display:flex;align-items:center;min-height:calc(100% - 1rem)}.modal-content{position:relative;display:flex;flex-direction:column;width:100%;pointer-events:auto;background-color:var(--t42-modal-bg);background-clip:padding-box;border:.0625rem solid var(--t42-color-opacity-10);border-radius:0;outline:0}.modal-backdrop{position:fixed;top:0;left:0;z-index:1050;width:100vw;height:100vh;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:.5}.modal-header{display:flex;flex-shrink:0;align-items:center;justify-content:space-between;padding:1rem 1rem;border-bottom:.0625rem solid rgba(0,0,0,0);border-top-left-radius:0;border-top-right-radius:0}.modal-header .btn-close{padding:.5rem .5rem;margin:-.5rem -.5rem -.5rem auto}.modal-title{margin-bottom:0;line-height:1.5}.modal-body{position:relative;flex:1 1 auto;padding:1rem}.modal-footer{display:flex;flex-wrap:wrap;flex-shrink:0;align-items:center;justify-content:flex-end;padding:.75rem;border-top:.0625rem solid rgba(0,0,0,0);border-bottom-right-radius:0;border-bottom-left-radius:0}.modal-footer>*{margin:.25rem}@media (min-width: 576px){.modal-dialog{max-width:500px;margin:1.75rem auto}.modal-dialog-scrollable{height:calc(100% - 3.5rem)}.modal-dialog-centered{min-height:calc(100% - 3.5rem)}.modal-sm{max-width:300px}}@media (min-width: 992px){.modal-lg,.modal-xl{max-width:800px}}@media (min-width: 1200px){.modal-xl{max-width:1140px}}.modal-fullscreen{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen .modal-header{border-radius:0}.modal-fullscreen .modal-body{overflow-y:auto}.modal-fullscreen .modal-footer{border-radius:0}@media (max-width: 575.98px){.modal-fullscreen-sm-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-sm-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-sm-down .modal-header{border-radius:0}.modal-fullscreen-sm-down .modal-body{overflow-y:auto}.modal-fullscreen-sm-down .modal-footer{border-radius:0}}@media (max-width: 767.98px){.modal-fullscreen-md-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-md-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-md-down .modal-header{border-radius:0}.modal-fullscreen-md-down .modal-body{overflow-y:auto}.modal-fullscreen-md-down .modal-footer{border-radius:0}}@media (max-width: 991.98px){.modal-fullscreen-lg-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-lg-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-lg-down .modal-header{border-radius:0}.modal-fullscreen-lg-down .modal-body{overflow-y:auto}.modal-fullscreen-lg-down .modal-footer{border-radius:0}}@media (max-width: 1199.98px){.modal-fullscreen-xl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xl-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-xl-down .modal-header{border-radius:0}.modal-fullscreen-xl-down .modal-body{overflow-y:auto}.modal-fullscreen-xl-down .modal-footer{border-radius:0}}@media (max-width: 1399.98px){.modal-fullscreen-xxl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xxl-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-xxl-down .modal-header{border-radius:0}.modal-fullscreen-xxl-down .modal-body{overflow-y:auto}.modal-fullscreen-xxl-down .modal-footer{border-radius:0}}.modal{backdrop-filter:var(--backdrop-filter)}.modal .btn-close{font-size:1.25rem;background-size:0.75rem;filter:var(--filter-close)}.modal-content{border-top:0;background:linear-gradient(to bottom right, Rgba(var(--t42-bg-light), 0.75) 0%, Rgba(var(--t42-bg-dark), 0.75) 100%);box-shadow:var(--t42-shadow)}.modal-content::before{display:block;height:0.0625rem;background:linear-gradient(90deg, #007be5 0%, rgba(0,123,229,0.5) 100%);content:""}.modal-body{padding:0 1rem}.modal-body p:last-child{margin-bottom:0}.modal-sm .modal-footer{flex-direction:column}.modal-sm .modal-footer .btn{width:100%}.modal-sm .modal-footer .btn:not(:last-of-type){margin-bottom:0.5rem}.modal-fill-in{background-color:Rgba(var(--t42-bg-light), 0.75)}.modal-fill-in.modal-dialog{display:flex;flex-flow:column nowrap;align-content:center;align-items:center;justify-content:center;width:auto;max-width:100%;height:100%;margin:0 auto}.modal-fill-in .modal-content{display:flex;max-width:600px;border-color:transparent;background:transparent;background-color:transparent;box-shadow:none;backdrop-filter:none;pointer-events:auto}.modal-fill-in .modal-content::before{display:none}.modal-fill-in::before{position:fixed;top:0;right:0;left:0;display:block;height:0.0625rem;background:linear-gradient(90deg, #007be5 0%, rgba(0,123,229,0.5) 100%);content:""}.modal-fill-in.modal-lg .modal-content{max-width:800px}.modal-fill-in.modal-sm .modal-content{max-width:300px}.nav{display:flex;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:.45rem 1rem;color:var(--t42-link-color);text-decoration:none;transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.nav-link{transition:none}}.nav-link:hover,.nav-link:focus{color:var(--t42-link-hover-color)}.nav-link.disabled{color:var(--t42-content-color-disabled);pointer-events:none;cursor:default}.nav-tabs{border-bottom:.0625rem solid var(--t42-color-opacity-10)}.nav-tabs .nav-link{margin-bottom:-.0625rem;background:none;border:.0625rem solid transparent;border-top-left-radius:0;border-top-right-radius:0}.nav-tabs .nav-link:hover,.nav-tabs .nav-link:focus{border-color:transparent transparent var(--t42-color-opacity-10);isolation:isolate}.nav-tabs .nav-link.disabled{color:var(--t42-content-color-disabled);background-color:transparent;border-color:transparent}.nav-tabs .nav-link.active,.nav-tabs .nav-item.show .nav-link{color:var(--t42-link-hover-color);background-color:var(--t42-link-active-bg);border-color:transparent transparent #007be5}.nav-tabs .dropdown-menu{margin-top:-.0625rem;border-top-left-radius:0;border-top-right-radius:0}.nav-pills .nav-link{background:none;border:0;border-radius:.25rem}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:var(--t42-link-hover-color);background-color:var(--t42-link-active-bg)}.nav-fill>.nav-link,.nav-fill .nav-item{flex:1 1 auto;text-align:center}.nav-justified>.nav-link,.nav-justified .nav-item{flex-basis:0;flex-grow:1;text-align:center}.nav-fill .nav-item .nav-link,.nav-justified .nav-item .nav-link{width:100%}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-link{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, border-color, color;margin-right:3px;border:.0625rem solid transparent}.nav-link:not(.disabled):not(:disabled):focus,.nav-link:not(.disabled):not(:disabled):active,.nav-link:not(.disabled):not(:disabled).active,.nav-link:not(.disabled):not(:disabled):hover{border-color:var(--t42-color-opacity-10);color:var(--t42-link-color);background-color:var(--t42-link-hover-bg)}.nav-link.dropdown-toggle::after{right:-0.125rem}.navbar-nav .nav-item{bottom:-1px}.navbar-nav .nav-item .nav-link{border-bottom:0}.navbar-nav .nav-item:not(.disabled):not(:disabled):focus .nav-link,.navbar-nav .nav-item:not(.disabled):not(:disabled):active .nav-link,.navbar-nav .nav-item:not(.disabled):not(:disabled).active .nav-link,.navbar-nav .nav-item:not(.disabled):not(:disabled):hover .nav-link{border-color:var(--t42-color-opacity-10)}.nav.flex-column .nav-link{margin-bottom:3px}.nav-tabs .nav-link{position:relative;display:flex;align-items:center;height:2rem}.nav-tabs .nav-link::before{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:height;position:absolute;bottom:-2px;left:-1px;width:calc(100% + 2px);height:0;background-color:var(--primary);content:""}.nav-tabs .nav-link.active::before{height:3px}.nav-tabs .nav-link.active:hover::before{height:0}.nav-tabs .nav-link .btn-close{width:0.5rem;height:0.5rem}.nav-tabs .nav-item{margin-right:0}.nav-tabs .dropdown.show .dropdown-toggle{border-color:transparent}.nav-tabs.flex-column .nav-link.active:hover::before{width:0}.nav-tabs.flex-column .nav-link::before{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:width;top:-1px;width:0;height:100%;margin-left:0;background-color:var(--primary);content:""}.nav-tabs.flex-column .nav-link.active::before{width:3px;height:calc(100% + 2px)}.nav-pills .nav-link{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;width:100%;padding:0.25rem 1rem;border:1px solid transparent;border-radius:1rem}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{position:relative;border-color:transparent}.nav-pills .nav-item{margin-right:3px}.nav-pills .nav-item:last-child{margin-right:0}.nav-pills .nav-link.active:not(.dropdown-toggle),.nav-pills .show>.nav-link:not(.dropdown-toggle){padding:0.25rem 1.75rem 0.25rem 1rem}.nav-pills .nav-link.active:not(.dropdown-toggle)::before,.nav-pills .show>.nav-link:not(.dropdown-toggle)::before{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:right;position:absolute;top:50%;right:10px;width:8px;height:8px;border-radius:50%;background-color:var(--primary);transform:translateY(-50%);content:""}.nav-pills .nav-link.active:not(.dropdown-toggle):hover::before,.nav-pills .show>.nav-link:not(.dropdown-toggle):hover::before{right:-10px}.nav-justified .nav-item .nav-link::before{right:1px;left:-1px;margin-left:0}.tab-content{padding-top:0.5rem}.nav-action-buttons .nav-link{position:relative;padding:0.45rem 1.5rem 0.45rem 1rem}.nav-action-buttons .icon-cancel::before{display:block;width:1rem;height:1rem;background-color:var(--t42-content-color);content:"";-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M366.854,336.384c6.14398,6.14398,9.216,13.48267,9.216,22.01599s-3.07202,15.87198-9.216,22.01599 c-6.14398,5.46133-13.48267,8.19202-22.01599,8.19199c-8.53333,0.00003-15.87201-2.73065-22.01602-8.19199l-67.584-77.82401 l-67.584,77.82401c-6.144,5.46133-13.48267,8.19202-22.01601,8.19199c-8.53333,0.00003-15.87199-2.73065-22.01599-8.19199 c-5.46133-6.14401-8.192-13.48267-8.192-22.01599s2.73067-15.87201,8.192-22.01599l70.65599-79.87201l-70.65601-80.896 c-5.46132-6.144-8.19199-13.48268-8.19199-22.01601c0-8.53334,2.73067-15.87201,8.19199-22.01601 c6.14401-5.46133,13.48267-8.19199,22.01601-8.192c8.53334,0.00001,15.87201,2.73067,22.01601,8.192l67.584,77.82401 l67.584-77.82401c6.14401-5.46133,13.4827-8.19199,22.01602-8.192c8.53333,0.00001,15.87201,2.73067,22.01599,8.192 c6.14398,6.144,9.216,13.48267,9.216,22.01601c0,8.53333-3.07202,15.87201-9.216,22.01601l-70.65601,80.896L366.854,336.384z%27/%3E%3C/svg%3E")}.navbar{position:relative;display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;padding-top:0;padding-right:.875rem;padding-bottom:0;padding-left:.875rem}.navbar>.container,.navbar>.container-fluid,.navbar>.container-sm,.navbar>.container-md,.navbar>.container-lg,.navbar>.container-xl,.navbar>.container-xxl{display:flex;flex-wrap:inherit;align-items:center;justify-content:space-between}.navbar-brand{padding-top:.075rem;padding-bottom:.075rem;margin-right:1rem;font-size:1.25rem;text-decoration:none;white-space:nowrap}.navbar-nav{display:flex;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-nav .dropdown-menu{position:static}.navbar-text{padding-top:.45rem;padding-bottom:.45rem}.navbar-collapse{flex-basis:100%;flex-grow:1;align-items:center}.navbar-toggler{padding:0 0;font-size:.9375rem;line-height:1;background-color:transparent;border:1px solid transparent;border-radius:0;transition:box-shadow 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.navbar-toggler{transition:none}}.navbar-toggler:hover{text-decoration:none}.navbar-toggler:focus{text-decoration:none;outline:0;box-shadow:0 0 0 0}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;background-repeat:no-repeat;background-position:center;background-size:100%}.navbar-nav-scroll{max-height:var(--bs-scroll-height, 75vh);overflow-y:auto}@media (min-width: 576px){.navbar-expand-sm{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-sm .navbar-nav{flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm .navbar-nav-scroll{overflow:visible}.navbar-expand-sm .navbar-collapse{display:flex !important;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}.navbar-expand-sm .offcanvas-header{display:none}.navbar-expand-sm .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;visibility:visible !important;background-color:transparent;border-right:0;border-left:0;transition:none;transform:none}.navbar-expand-sm .offcanvas-top,.navbar-expand-sm .offcanvas-bottom{height:auto;border-top:0;border-bottom:0}.navbar-expand-sm .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width: 768px){.navbar-expand-md{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-md .navbar-nav{flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-md .navbar-nav-scroll{overflow:visible}.navbar-expand-md .navbar-collapse{display:flex !important;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}.navbar-expand-md .offcanvas-header{display:none}.navbar-expand-md .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;visibility:visible !important;background-color:transparent;border-right:0;border-left:0;transition:none;transform:none}.navbar-expand-md .offcanvas-top,.navbar-expand-md .offcanvas-bottom{height:auto;border-top:0;border-bottom:0}.navbar-expand-md .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width: 992px){.navbar-expand-lg{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-lg .navbar-nav{flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-lg .navbar-nav-scroll{overflow:visible}.navbar-expand-lg .navbar-collapse{display:flex !important;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}.navbar-expand-lg .offcanvas-header{display:none}.navbar-expand-lg .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;visibility:visible !important;background-color:transparent;border-right:0;border-left:0;transition:none;transform:none}.navbar-expand-lg .offcanvas-top,.navbar-expand-lg .offcanvas-bottom{height:auto;border-top:0;border-bottom:0}.navbar-expand-lg .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width: 1200px){.navbar-expand-xl{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-xl .navbar-nav{flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xl .navbar-nav-scroll{overflow:visible}.navbar-expand-xl .navbar-collapse{display:flex !important;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}.navbar-expand-xl .offcanvas-header{display:none}.navbar-expand-xl .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;visibility:visible !important;background-color:transparent;border-right:0;border-left:0;transition:none;transform:none}.navbar-expand-xl .offcanvas-top,.navbar-expand-xl .offcanvas-bottom{height:auto;border-top:0;border-bottom:0}.navbar-expand-xl .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width: 1400px){.navbar-expand-xxl{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-xxl .navbar-nav{flex-direction:row}.navbar-expand-xxl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xxl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xxl .navbar-nav-scroll{overflow:visible}.navbar-expand-xxl .navbar-collapse{display:flex !important;flex-basis:auto}.navbar-expand-xxl .navbar-toggler{display:none}.navbar-expand-xxl .offcanvas-header{display:none}.navbar-expand-xxl .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;visibility:visible !important;background-color:transparent;border-right:0;border-left:0;transition:none;transform:none}.navbar-expand-xxl .offcanvas-top,.navbar-expand-xxl .offcanvas-bottom{height:auto;border-top:0;border-bottom:0}.navbar-expand-xxl .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}.navbar-expand{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand .navbar-nav{flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand .navbar-nav-scroll{overflow:visible}.navbar-expand .navbar-collapse{display:flex !important;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-expand .offcanvas-header{display:none}.navbar-expand .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;visibility:visible !important;background-color:transparent;border-right:0;border-left:0;transition:none;transform:none}.navbar-expand .offcanvas-top,.navbar-expand .offcanvas-bottom{height:auto;border-top:0;border-bottom:0}.navbar-expand .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}.navbar-light .navbar-brand{color:var(--t42-link-color)}.navbar-light .navbar-brand:hover,.navbar-light .navbar-brand:focus{color:var(--t42-link-hover-color)}.navbar-light .navbar-nav .nav-link{color:var(--t42-link-color)}.navbar-light .navbar-nav .nav-link:hover,.navbar-light .navbar-nav .nav-link:focus{color:var(--t42-link-hover-color)}.navbar-light .navbar-nav .nav-link.disabled{color:var(--t42-content-color-disabled)}.navbar-light .navbar-nav .show>.nav-link,.navbar-light .navbar-nav .nav-link.active{color:var(--t42-link-hover-color)}.navbar-light .navbar-toggler{color:var(--t42-link-color);border-color:rgba(0,0,0,0.1)}.navbar-light .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 30 30%27%3e%3cpath stroke=%27var%28--t42-link-color%29%27 stroke-linecap=%27round%27 stroke-miterlimit=%2710%27 stroke-width=%272%27 d=%27M4 7h22M4 15h22M4 23h22%27/%3e%3c/svg%3e")}.navbar-light .navbar-text{color:var(--t42-link-color)}.navbar-light .navbar-text a,.navbar-light .navbar-text a:hover,.navbar-light .navbar-text a:focus{color:var(--t42-link-hover-color)}.navbar-dark .navbar-brand{color:var(--t42-link-color)}.navbar-dark .navbar-brand:hover,.navbar-dark .navbar-brand:focus{color:var(--t42-link-hover-color)}.navbar-dark .navbar-nav .nav-link{color:var(--t42-link-color)}.navbar-dark .navbar-nav .nav-link:hover,.navbar-dark .navbar-nav .nav-link:focus{color:var(--t42-link-hover-color)}.navbar-dark .navbar-nav .nav-link.disabled{color:var(--t42-content-color-disabled)}.navbar-dark .navbar-nav .show>.nav-link,.navbar-dark .navbar-nav .nav-link.active{color:var(--t42-link-hover-color)}.navbar-dark .navbar-toggler{color:var(--t42-link-color);border-color:rgba(255,255,255,0.1)}.navbar-dark .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 30 30%27%3e%3cpath stroke=%27var%28--t42-link-color%29%27 stroke-linecap=%27round%27 stroke-miterlimit=%2710%27 stroke-width=%272%27 d=%27M4 7h22M4 15h22M4 23h22%27/%3e%3c/svg%3e")}.navbar-dark .navbar-text{color:var(--t42-link-color)}.navbar-dark .navbar-text a,.navbar-dark .navbar-text a:hover,.navbar-dark .navbar-text a:focus{color:var(--t42-link-hover-color)}.navbar{border-bottom:var(--t42-border);background-color:Rgba(var(--t42-bg-mid), 0.75);backdrop-filter:var(--backdrop-filter)}.navbar-dark{background-color:Rgba(var(--t42-bg-dark), 0.75)}.navbar-light{background-color:Rgba(var(--t42-bg-light), 0.75)}.navbar .nav-item{position:relative}.navbar .nav-item.show:focus .nav-link:not(.disabled):not(:disabled),.navbar .nav-item.show:active .nav-link:not(.disabled):not(:disabled),.navbar .nav-item.show.active .nav-link:not(.disabled):not(:disabled),.navbar .nav-item:not(.disabled):not(:disabled):focus .nav-link:not(.disabled):not(:disabled),.navbar .nav-item:not(.disabled):not(:disabled):active .nav-link:not(.disabled):not(:disabled),.navbar .nav-item:not(.disabled):not(:disabled).active .nav-link:not(.disabled):not(:disabled){color:var(--t42-link-color);background-color:var(--t42-color-opacity-10)}.navbar .nav-item.show:hover .nav-link:not(.disabled):not(:disabled),.navbar .nav-item:not(.disabled):not(:disabled):hover .nav-link:not(.disabled):not(:disabled){color:var(--t42-link-color);background-color:var(--t42-color-opacity-05)}.navbar .nav-link{padding-right:.875rem;padding-left:.875rem}.navbar .btn-group{height:100%;padding-left:.875rem;border-left:var(--t42-border)}.pagination{display:flex;padding-left:0;list-style:none}.page-link{position:relative;display:block;color:var(--t42-content-color);text-decoration:none;background-color:rgba(0,0,0,0);border:0 solid rgba(0,0,0,0);transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.page-link{transition:none}}.page-link:hover{z-index:2;color:var(--t42-link-hover-color);background-color:var(--t42-link-hover-bg);border-color:#dee2e6}.page-link:focus{z-index:3;color:var(--t42-link-hover-color);background-color:rgba(0,0,0,0);outline:0;box-shadow:0 0 0 0 rgba(0,123,229,0.25)}.page-item:not(:first-child) .page-link{margin-left:0}.page-item.active .page-link{z-index:3;color:var(--white);background-color:var(--primary);border-color:var(--primary)}.page-item.disabled .page-link{color:var(--t42-content-color-disabled);pointer-events:none;background-color:rgba(0,0,0,0);border-color:#dee2e6}.page-link{padding:.125rem .5rem}.page-item:first-child .page-link{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.page-item:last-child .page-link{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.pagination-lg .page-link{padding:.75rem 1.5rem;font-size:.9375rem}.pagination-lg .page-item:first-child .page-link{border-top-left-radius:1rem;border-bottom-left-radius:1rem}.pagination-lg .page-item:last-child .page-link{border-top-right-radius:1rem;border-bottom-right-radius:1rem}.pagination-sm .page-link{padding:.25rem .5rem;font-size:.65625rem}.pagination-sm .page-item:first-child .page-link{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.pagination-sm .page-item:last-child .page-link{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.page-link{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, color;display:flex;align-items:center;justify-content:center;min-width:1.5rem;min-height:1.5rem;border-radius:0.25rem;overflow:hidden}.page-link[aria-label="Next"],.page-link[aria-label="Previous"]{padding:0}.page-link[aria-label="Next"] span{background:var(--t42-select-indicator) center center/1rem 1rem no-repeat;transform:rotate(-90deg)}.page-link[aria-label="Previous"] span{background:var(--t42-select-indicator) center center/1rem 1rem no-repeat;transform:rotate(90deg)}.page-link>span{width:100%;height:100%;min-height:1rem;font-size:0;clip:initial}.pagination-lg .page-link[aria-label="Next"],.pagination-lg .page-link[aria-label="Previous"]{padding:0.75rem 1.5rem}.page-item{margin-right:8px}.page-item:first-child .page-link>span:not(.sr-only)::before,.page-item:last-child .page-link>span:not(.sr-only)::before{top:-0.125rem}.page-item.active .page-link:hover,.page-item:active .page-link:hover{background-color:var(--t42-color-opacity-05)}.page-item.active.disabled .page-link{background-color:var(--t42-color-opacity-10)}.popover{position:absolute;top:0;left:0 /* rtl:ignore */;z-index:1070;display:block;max-width:276px;font-family:"Montserrat","Helvetica Neue",Arial,sans-serif;font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.65625rem;word-wrap:break-word;background-color:Rgba(var(--t42-bg-dark), 0.75);background-clip:padding-box;border:1px solid var(--t42-color-opacity-10);border-radius:0}.popover .popover-arrow{position:absolute;display:block;width:1rem;height:.5rem}.popover .popover-arrow::before,.popover .popover-arrow::after{position:absolute;display:block;content:"";border-color:transparent;border-style:solid}.bs-popover-top>.popover-arrow,.bs-popover-auto[data-popper-placement^="top"]>.popover-arrow{bottom:calc(-.5rem - 1px)}.bs-popover-top>.popover-arrow::before,.bs-popover-auto[data-popper-placement^="top"]>.popover-arrow::before{bottom:0;border-width:.5rem .5rem 0;border-top-color:var(--t42-color-opacity-10)}.bs-popover-top>.popover-arrow::after,.bs-popover-auto[data-popper-placement^="top"]>.popover-arrow::after{bottom:1px;border-width:.5rem .5rem 0;border-top-color:var(--t42-color-opacity-10)}.bs-popover-end>.popover-arrow,.bs-popover-auto[data-popper-placement^="right"]>.popover-arrow{left:calc(-.5rem - 1px);width:.5rem;height:1rem}.bs-popover-end>.popover-arrow::before,.bs-popover-auto[data-popper-placement^="right"]>.popover-arrow::before{left:0;border-width:.5rem .5rem .5rem 0;border-right-color:var(--t42-color-opacity-10)}.bs-popover-end>.popover-arrow::after,.bs-popover-auto[data-popper-placement^="right"]>.popover-arrow::after{left:1px;border-width:.5rem .5rem .5rem 0;border-right-color:var(--t42-color-opacity-10)}.bs-popover-bottom>.popover-arrow,.bs-popover-auto[data-popper-placement^="bottom"]>.popover-arrow{top:calc(-.5rem - 1px)}.bs-popover-bottom>.popover-arrow::before,.bs-popover-auto[data-popper-placement^="bottom"]>.popover-arrow::before{top:0;border-width:0 .5rem .5rem .5rem;border-bottom-color:var(--t42-color-opacity-10)}.bs-popover-bottom>.popover-arrow::after,.bs-popover-auto[data-popper-placement^="bottom"]>.popover-arrow::after{top:1px;border-width:0 .5rem .5rem .5rem;border-bottom-color:var(--t42-color-opacity-10)}.bs-popover-bottom .popover-header::before,.bs-popover-auto[data-popper-placement^="bottom"] .popover-header::before{position:absolute;top:0;left:50%;display:block;width:1rem;margin-left:-.5rem;content:"";border-bottom:1px solid Rgba(var(--t42-bg-mid), 0.75)}.bs-popover-start>.popover-arrow,.bs-popover-auto[data-popper-placement^="left"]>.popover-arrow{right:calc(-.5rem - 1px);width:.5rem;height:1rem}.bs-popover-start>.popover-arrow::before,.bs-popover-auto[data-popper-placement^="left"]>.popover-arrow::before{right:0;border-width:.5rem 0 .5rem .5rem;border-left-color:var(--t42-color-opacity-10)}.bs-popover-start>.popover-arrow::after,.bs-popover-auto[data-popper-placement^="left"]>.popover-arrow::after{right:1px;border-width:.5rem 0 .5rem .5rem;border-left-color:var(--t42-color-opacity-10)}.popover-header{padding:.55rem 1rem;margin-bottom:0;font-size:.75rem;color:var(--t42-link-color);background-color:Rgba(var(--t42-bg-mid), 0.75);border-bottom:1px solid var(--t42-color-opacity-10);border-top-left-radius:0;border-top-right-radius:0}.popover-header:empty{display:none}.popover-body{padding:1rem 1rem;color:var(--t42-content-color)}.popover{backdrop-filter:var(--backdrop-filter)}@keyframes progress-bar-stripes{0%{background-position-x:1.063rem}}.progress{display:flex;height:1.063rem;overflow:hidden;font-size:.6rem;background-color:Rgb(var(--t42-bg-mid));border-radius:0}.progress-bar{display:flex;flex-direction:column;justify-content:center;overflow:hidden;color:#fff;text-align:center;white-space:nowrap;background-color:#007be5;transition:width 0.6s ease}@media (prefers-reduced-motion: reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-size:1.063rem 1.063rem}.progress-bar-animated{animation:1s linear infinite progress-bar-stripes}@media (prefers-reduced-motion: reduce){.progress-bar-animated{animation:none}}.progress{border:var(--t42-border)}.table{--bs-table-bg: rgba(0,0,0,0);--bs-table-accent-bg: rgba(0,0,0,0);--bs-table-striped-color: var(--t42-content-color);--bs-table-striped-bg: rgba(0,0,0,0.05);--bs-table-active-color: var(--t42-content-color);--bs-table-active-bg: rgba(0,0,0,0.1);--bs-table-hover-color: var(--t42-link-color);--bs-table-hover-bg: rgba(0,0,0,0.075);width:100%;margin-bottom:1rem;color:var(--t42-content-color);vertical-align:top;border-color:var(--t42-color-opacity-10)}.table>:not(caption)>*>*{padding:.25rem .313rem;background-color:var(--bs-table-bg);border-bottom-width:1px;box-shadow:inset 0 0 0 9999px var(--bs-table-accent-bg)}.table>tbody{vertical-align:inherit}.table>thead{vertical-align:bottom}.table>:not(:first-child){border-top:2px solid currentColor}.caption-top{caption-side:top}.table-sm>:not(caption)>*>*{padding:.25rem .25rem}.table-bordered>:not(caption)>*{border-width:1px 0}.table-bordered>:not(caption)>*>*{border-width:0 1px}.table-borderless>:not(caption)>*>*{border-bottom-width:0}.table-borderless>:not(:first-child){border-top-width:0}.table-striped>tbody>tr:nth-of-type(odd)>*{--bs-table-accent-bg: var(--bs-table-striped-bg);color:var(--bs-table-striped-color)}.table-active{--bs-table-accent-bg: var(--bs-table-active-bg);color:var(--bs-table-active-color)}.table-hover>tbody>tr:hover>*{--bs-table-accent-bg: var(--bs-table-hover-bg);color:var(--bs-table-hover-color)}.table-primary{--bs-table-bg: #cce5fa;--bs-table-striped-bg: #c2daee;--bs-table-striped-color: #000;--bs-table-active-bg: #b8cee1;--bs-table-active-color: #000;--bs-table-hover-bg: #bdd4e7;--bs-table-hover-color: #000;color:#000;border-color:#b8cee1}.table-secondary{--bs-table-bg: #dfdfdf;--bs-table-striped-bg: #d4d4d4;--bs-table-striped-color: #000;--bs-table-active-bg: #c9c9c9;--bs-table-active-color: #000;--bs-table-hover-bg: #cecece;--bs-table-hover-color: #000;color:#000;border-color:#c9c9c9}.table-success{--bs-table-bg: #d9ecda;--bs-table-striped-bg: #cee0cf;--bs-table-striped-color: #000;--bs-table-active-bg: #c3d4c4;--bs-table-active-color: #000;--bs-table-hover-bg: #c9daca;--bs-table-hover-color: #000;color:#000;border-color:#c3d4c4}.table-info{--bs-table-bg: #daecf1;--bs-table-striped-bg: #cfe0e5;--bs-table-striped-color: #000;--bs-table-active-bg: #c4d4d9;--bs-table-active-color: #000;--bs-table-hover-bg: #cadadf;--bs-table-hover-color: #000;color:#000;border-color:#c4d4d9}.table-warning{--bs-table-bg: #feeed3;--bs-table-striped-bg: #f1e2c8;--bs-table-striped-color: #000;--bs-table-active-bg: #e5d6be;--bs-table-active-color: #000;--bs-table-hover-bg: #ebdcc3;--bs-table-hover-color: #000;color:#000;border-color:#e5d6be}.table-danger{--bs-table-bg: #ffdcd2;--bs-table-striped-bg: #f2d1c8;--bs-table-striped-color: #000;--bs-table-active-bg: #e6c6bd;--bs-table-active-color: #000;--bs-table-hover-bg: #ecccc2;--bs-table-hover-color: #000;color:#000;border-color:#e6c6bd}.table-light{--bs-table-bg: #616161;--bs-table-striped-bg: dimgray;--bs-table-striped-color: #fff;--bs-table-active-bg: #717171;--bs-table-active-color: #fff;--bs-table-hover-bg: #6d6d6d;--bs-table-hover-color: #fff;color:#fff;border-color:#717171}.table-dark{--bs-table-bg: #616161;--bs-table-striped-bg: dimgray;--bs-table-striped-color: #fff;--bs-table-active-bg: #717171;--bs-table-active-color: #fff;--bs-table-hover-bg: #6d6d6d;--bs-table-hover-color: #fff;color:#fff;border-color:#717171}.table-responsive{overflow-x:auto;-webkit-overflow-scrolling:touch}@media (max-width: 575.98px){.table-responsive-sm{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width: 767.98px){.table-responsive-md{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width: 991.98px){.table-responsive-lg{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width: 1199.98px){.table-responsive-xl{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width: 1399.98px){.table-responsive-xxl{overflow-x:auto;-webkit-overflow-scrolling:touch}}.table>:not(:first-child){border-width:0}.table td,.table th{white-space:nowrap;vertical-align:middle}.table a{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border;border-bottom:0.063rem dashed var(--dark);color:var(--t42-content-color)}.table a:hover{border-bottom-color:var(--t42-content-color);border-bottom-style:solid;color:var(--t42-link-color);text-decoration:none}.table thead th{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;border-width:1px 0;color:Hsl(var(--t42-content-color-base), calc(var(--t42-content-color-l) - 20%));font-weight:normal;font-size:83.3%;text-transform:uppercase}.table td{position:relative}.table td .btn,.table td .btn-sm,.table td .btn-group-sm>.btn,.table td .btn-lg,.table td .btn-group-lg>.btn{line-height:1.25rem}.table td .btn-icon i{position:relative;top:0.0625rem}.table tr th:first-child,.table tr td:first-child{padding-left:0.5rem}.table tr th:last-child,.table tr td:last-child{padding-right:0.5rem}.table-hover tbody tr:hover{background-color:var(--t42-table-active-bg)}.table-hover tbody tr:hover a{border-bottom-color:var(--t42-content-color);color:var(--t42-link-color)}.table-responsive{border:0}.tooltip{position:absolute;z-index:1080;display:block;margin:0;font-family:"Montserrat","Helvetica Neue",Arial,sans-serif;font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.65625rem;word-wrap:break-word;opacity:0}.tooltip.show{opacity:1}.tooltip .tooltip-arrow{position:absolute;display:block;width:.8rem;height:.4rem}.tooltip .tooltip-arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-top,.bs-tooltip-auto[data-popper-placement^="top"]{padding:.4rem 0}.bs-tooltip-top .tooltip-arrow,.bs-tooltip-auto[data-popper-placement^="top"] .tooltip-arrow{bottom:0}.bs-tooltip-top .tooltip-arrow::before,.bs-tooltip-auto[data-popper-placement^="top"] .tooltip-arrow::before{top:-1px;border-width:.4rem .4rem 0;border-top-color:var(--t42-tooltip-bg)}.bs-tooltip-end,.bs-tooltip-auto[data-popper-placement^="right"]{padding:0 .4rem}.bs-tooltip-end .tooltip-arrow,.bs-tooltip-auto[data-popper-placement^="right"] .tooltip-arrow{left:0;width:.4rem;height:.8rem}.bs-tooltip-end .tooltip-arrow::before,.bs-tooltip-auto[data-popper-placement^="right"] .tooltip-arrow::before{right:-1px;border-width:.4rem .4rem .4rem 0;border-right-color:var(--t42-tooltip-bg)}.bs-tooltip-bottom,.bs-tooltip-auto[data-popper-placement^="bottom"]{padding:.4rem 0}.bs-tooltip-bottom .tooltip-arrow,.bs-tooltip-auto[data-popper-placement^="bottom"] .tooltip-arrow{top:0}.bs-tooltip-bottom .tooltip-arrow::before,.bs-tooltip-auto[data-popper-placement^="bottom"] .tooltip-arrow::before{bottom:-1px;border-width:0 .4rem .4rem;border-bottom-color:var(--t42-tooltip-bg)}.bs-tooltip-start,.bs-tooltip-auto[data-popper-placement^="left"]{padding:0 .4rem}.bs-tooltip-start .tooltip-arrow,.bs-tooltip-auto[data-popper-placement^="left"] .tooltip-arrow{right:0;width:.4rem;height:.8rem}.bs-tooltip-start .tooltip-arrow::before,.bs-tooltip-auto[data-popper-placement^="left"] .tooltip-arrow::before{left:-1px;border-width:.4rem 0 .4rem .4rem;border-left-color:var(--t42-tooltip-bg)}.tooltip-inner{max-width:200px;padding:.25rem 1rem;color:var(--t42-content-color);text-align:center;background-color:var(--t42-tooltip-bg);border-radius:0}.tooltip .tooltip-inner{border:var(--t42-border);box-shadow:var(--t42-shadow)}.bs-tooltip-top .arrow,.bs-tooltip-auto[data-popper-placement^="top"] .arrow{bottom:1px}.bs-tooltip-top .arrow::before,.bs-tooltip-auto[data-popper-placement^="top"] .arrow::before{border-top-color:var(--t42-color-opacity-10)}.bs-tooltip-bottom .arrow,.bs-tooltip-auto[data-popper-placement^="bottom"] .arrow{top:1px}.bs-tooltip-bottom .arrow::before,.bs-tooltip-auto[data-popper-placement^="bottom"] .arrow::before{border-bottom-color:var(--t42-color-opacity-10)}.bs-tooltip-right .arrow{left:1px}.bs-tooltip-right .arrow::before{border-right-color:var(--t42-color-opacity-10)}.bs-tooltip-left .arrow{right:1px}.bs-tooltip-left .arrow::before{border-left-color:var(--t42-color-opacity-10)}.fade{transition:opacity 0.15s linear}@media (prefers-reduced-motion: reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{height:0;overflow:hidden;transition:height 0.35s ease}@media (prefers-reduced-motion: reduce){.collapsing{transition:none}}.collapsing.collapse-horizontal{width:0;height:auto;transition:width 0.35s ease}@media (prefers-reduced-motion: reduce){.collapsing.collapse-horizontal{transition:none}}mark,.mark{color:var(--white)}pre{background-color:var(--t42-bg-dark)}blockquote,.blockquote{padding:1rem 1rem 0.01rem;border-left:0.25rem solid var(--secondary);background-color:Rgb(var(--t42-bg-dark))}.blockquote-footer{margin-top:-2rem;margin-left:1.25rem;color:var(--t42-content-color-muted);font-size:0.875em}.clearfix::after{display:block;clear:both;content:""}.link-primary{color:#007be5}.link-primary:hover,.link-primary:focus{color:#3395ea}.link-secondary{color:#616161}.link-secondary:hover,.link-secondary:focus{color:#4e4e4e}.link-success{color:#43a047}.link-success:hover,.link-success:focus{color:#69b36c}.link-info{color:#469eb9}.link-info:hover,.link-info:focus{color:#6bb1c7}.link-warning{color:#f9a825}.link-warning:hover,.link-warning:focus{color:#fab951}.link-danger{color:#ff511f}.link-danger:hover,.link-danger:focus{color:#ff744c}.link-light{color:#616161}.link-light:hover,.link-light:focus{color:#4e4e4e}.link-dark{color:#616161}.link-dark:hover,.link-dark:focus{color:#4e4e4e}.ratio{position:relative;width:100%}.ratio::before{display:block;padding-top:var(--bs-aspect-ratio);content:""}.ratio>*{position:absolute;top:0;left:0;width:100%;height:100%}.ratio-1x1{--bs-aspect-ratio: 100%}.ratio-4x3{--bs-aspect-ratio: calc(3 / 4 * 100%)}.ratio-16x9{--bs-aspect-ratio: calc(9 / 16 * 100%)}.ratio-21x9{--bs-aspect-ratio: calc(9 / 21 * 100%)}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}.sticky-top{position:sticky;top:0;z-index:1020}@media (min-width: 576px){.sticky-sm-top{position:sticky;top:0;z-index:1020}}@media (min-width: 768px){.sticky-md-top{position:sticky;top:0;z-index:1020}}@media (min-width: 992px){.sticky-lg-top{position:sticky;top:0;z-index:1020}}@media (min-width: 1200px){.sticky-xl-top{position:sticky;top:0;z-index:1020}}@media (min-width: 1400px){.sticky-xxl-top{position:sticky;top:0;z-index:1020}}.hstack{display:flex;flex-direction:row;align-items:center;align-self:stretch}.vstack{display:flex;flex:1 1 auto;flex-direction:column;align-self:stretch}.visually-hidden,.visually-hidden-focusable:not(:focus):not(:focus-within){position:absolute !important;width:1px !important;height:1px !important;padding:0 !important;margin:-1px !important;overflow:hidden !important;clip:rect(0, 0, 0, 0) !important;white-space:nowrap !important;border:0 !important}.stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.vr{display:inline-block;align-self:stretch;width:1px;min-height:1em;background-color:currentColor;opacity:.25}.align-baseline{vertical-align:baseline !important}.align-top{vertical-align:top !important}.align-middle{vertical-align:middle !important}.align-bottom{vertical-align:bottom !important}.align-text-bottom{vertical-align:text-bottom !important}.align-text-top{vertical-align:text-top !important}.float-start{float:left !important}.float-end{float:right !important}.float-none{float:none !important}.opacity-0{opacity:0 !important}.opacity-25{opacity:.25 !important}.opacity-50{opacity:.5 !important}.opacity-75{opacity:.75 !important}.opacity-100{opacity:1 !important}.overflow-auto{overflow:auto !important}.overflow-hidden{overflow:hidden !important}.overflow-visible{overflow:visible !important}.overflow-scroll{overflow:scroll !important}.d-inline{display:inline !important}.d-inline-block{display:inline-block !important}.d-block{display:block !important}.d-grid{display:grid !important}.d-table{display:table !important}.d-table-row{display:table-row !important}.d-table-cell{display:table-cell !important}.d-flex{display:flex !important}.d-inline-flex{display:inline-flex !important}.d-none{display:none !important}.shadow{box-shadow:0 0.5rem 1rem rgba(0,0,0,0.15) !important}.shadow-sm{box-shadow:0 0.125rem 0.25rem rgba(0,0,0,0.075) !important}.shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,0.175) !important}.shadow-none{box-shadow:none !important}.position-static{position:static !important}.position-relative{position:relative !important}.position-absolute{position:absolute !important}.position-fixed{position:fixed !important}.position-sticky{position:sticky !important}.top-0{top:0 !important}.top-50{top:50% !important}.top-100{top:100% !important}.bottom-0{bottom:0 !important}.bottom-50{bottom:50% !important}.bottom-100{bottom:100% !important}.start-0{left:0 !important}.start-50{left:50% !important}.start-100{left:100% !important}.end-0{right:0 !important}.end-50{right:50% !important}.end-100{right:100% !important}.translate-middle{transform:translate(-50%, -50%) !important}.translate-middle-x{transform:translateX(-50%) !important}.translate-middle-y{transform:translateY(-50%) !important}.border{border:1px solid #dee2e6 !important}.border-0{border:0 !important}.border-top{border-top:1px solid #dee2e6 !important}.border-top-0{border-top:0 !important}.border-end{border-right:1px solid #dee2e6 !important}.border-end-0{border-right:0 !important}.border-bottom{border-bottom:1px solid #dee2e6 !important}.border-bottom-0{border-bottom:0 !important}.border-start{border-left:1px solid #dee2e6 !important}.border-start-0{border-left:0 !important}.border-primary{border-color:#007be5 !important}.border-secondary{border-color:#616161 !important}.border-success{border-color:#43a047 !important}.border-info{border-color:#469eb9 !important}.border-warning{border-color:#f9a825 !important}.border-danger{border-color:#ff511f !important}.border-light{border-color:#616161 !important}.border-dark{border-color:#616161 !important}.border-white{border-color:#fff !important}.border-1{border-width:1px !important}.border-2{border-width:2px !important}.border-3{border-width:3px !important}.border-4{border-width:4px !important}.border-5{border-width:5px !important}.w-25{width:25% !important}.w-50{width:50% !important}.w-75{width:75% !important}.w-100{width:100% !important}.w-auto{width:auto !important}.mw-100{max-width:100% !important}.vw-100{width:100vw !important}.min-vw-100{min-width:100vw !important}.h-25{height:25% !important}.h-50{height:50% !important}.h-75{height:75% !important}.h-100{height:100% !important}.h-auto{height:auto !important}.mh-100{max-height:100% !important}.vh-100{height:100vh !important}.min-vh-100{min-height:100vh !important}.flex-fill{flex:1 1 auto !important}.flex-row{flex-direction:row !important}.flex-column{flex-direction:column !important}.flex-row-reverse{flex-direction:row-reverse !important}.flex-column-reverse{flex-direction:column-reverse !important}.flex-grow-0{flex-grow:0 !important}.flex-grow-1{flex-grow:1 !important}.flex-shrink-0{flex-shrink:0 !important}.flex-shrink-1{flex-shrink:1 !important}.flex-wrap{flex-wrap:wrap !important}.flex-nowrap{flex-wrap:nowrap !important}.flex-wrap-reverse{flex-wrap:wrap-reverse !important}.gap-0{gap:0 !important}.gap-1{gap:.25rem !important}.gap-2{gap:.5rem !important}.gap-3{gap:1rem !important}.gap-4{gap:1.5rem !important}.gap-5{gap:3rem !important}.justify-content-start{justify-content:flex-start !important}.justify-content-end{justify-content:flex-end !important}.justify-content-center{justify-content:center !important}.justify-content-between{justify-content:space-between !important}.justify-content-around{justify-content:space-around !important}.justify-content-evenly{justify-content:space-evenly !important}.align-items-start{align-items:flex-start !important}.align-items-end{align-items:flex-end !important}.align-items-center{align-items:center !important}.align-items-baseline{align-items:baseline !important}.align-items-stretch{align-items:stretch !important}.align-content-start{align-content:flex-start !important}.align-content-end{align-content:flex-end !important}.align-content-center{align-content:center !important}.align-content-between{align-content:space-between !important}.align-content-around{align-content:space-around !important}.align-content-stretch{align-content:stretch !important}.align-self-auto{align-self:auto !important}.align-self-start{align-self:flex-start !important}.align-self-end{align-self:flex-end !important}.align-self-center{align-self:center !important}.align-self-baseline{align-self:baseline !important}.align-self-stretch{align-self:stretch !important}.order-first{order:-1 !important}.order-0{order:0 !important}.order-1{order:1 !important}.order-2{order:2 !important}.order-3{order:3 !important}.order-4{order:4 !important}.order-5{order:5 !important}.order-last{order:6 !important}.m-0{margin:0 !important}.m-1{margin:.25rem !important}.m-2{margin:.5rem !important}.m-3{margin:1rem !important}.m-4{margin:1.5rem !important}.m-5{margin:3rem !important}.m-auto{margin:auto !important}.mx-0{margin-right:0 !important;margin-left:0 !important}.mx-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-3{margin-right:1rem !important;margin-left:1rem !important}.mx-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-5{margin-right:3rem !important;margin-left:3rem !important}.mx-auto{margin-right:auto !important;margin-left:auto !important}.my-0{margin-top:0 !important;margin-bottom:0 !important}.my-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-0{margin-top:0 !important}.mt-1{margin-top:.25rem !important}.mt-2{margin-top:.5rem !important}.mt-3{margin-top:1rem !important}.mt-4{margin-top:1.5rem !important}.mt-5{margin-top:3rem !important}.mt-auto{margin-top:auto !important}.me-0{margin-right:0 !important}.me-1{margin-right:.25rem !important}.me-2{margin-right:.5rem !important}.me-3{margin-right:1rem !important}.me-4{margin-right:1.5rem !important}.me-5{margin-right:3rem !important}.me-auto{margin-right:auto !important}.mb-0{margin-bottom:0 !important}.mb-1{margin-bottom:.25rem !important}.mb-2{margin-bottom:.5rem !important}.mb-3{margin-bottom:1rem !important}.mb-4{margin-bottom:1.5rem !important}.mb-5{margin-bottom:3rem !important}.mb-auto{margin-bottom:auto !important}.ms-0{margin-left:0 !important}.ms-1{margin-left:.25rem !important}.ms-2{margin-left:.5rem !important}.ms-3{margin-left:1rem !important}.ms-4{margin-left:1.5rem !important}.ms-5{margin-left:3rem !important}.ms-auto{margin-left:auto !important}.p-0{padding:0 !important}.p-1{padding:.25rem !important}.p-2{padding:.5rem !important}.p-3{padding:1rem !important}.p-4{padding:1.5rem !important}.p-5{padding:3rem !important}.px-0{padding-right:0 !important;padding-left:0 !important}.px-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-3{padding-right:1rem !important;padding-left:1rem !important}.px-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-5{padding-right:3rem !important;padding-left:3rem !important}.py-0{padding-top:0 !important;padding-bottom:0 !important}.py-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-0{padding-top:0 !important}.pt-1{padding-top:.25rem !important}.pt-2{padding-top:.5rem !important}.pt-3{padding-top:1rem !important}.pt-4{padding-top:1.5rem !important}.pt-5{padding-top:3rem !important}.pe-0{padding-right:0 !important}.pe-1{padding-right:.25rem !important}.pe-2{padding-right:.5rem !important}.pe-3{padding-right:1rem !important}.pe-4{padding-right:1.5rem !important}.pe-5{padding-right:3rem !important}.pb-0{padding-bottom:0 !important}.pb-1{padding-bottom:.25rem !important}.pb-2{padding-bottom:.5rem !important}.pb-3{padding-bottom:1rem !important}.pb-4{padding-bottom:1.5rem !important}.pb-5{padding-bottom:3rem !important}.ps-0{padding-left:0 !important}.ps-1{padding-left:.25rem !important}.ps-2{padding-left:.5rem !important}.ps-3{padding-left:1rem !important}.ps-4{padding-left:1.5rem !important}.ps-5{padding-left:3rem !important}.font-monospace{font-family:var(--bs-font-monospace) !important}.fs-1{font-size:calc(1.26563rem + .1875vw) !important}.fs-2{font-size:1.125rem !important}.fs-3{font-size:.98475rem !important}.fs-4{font-size:.84375rem !important}.fs-5{font-size:.75rem !important}.fs-6{font-size:.7035rem !important}.fst-italic{font-style:italic !important}.fst-normal{font-style:normal !important}.fw-light{font-weight:300 !important}.fw-lighter{font-weight:lighter !important}.fw-normal{font-weight:400 !important}.fw-bold{font-weight:700 !important}.fw-bolder{font-weight:bolder !important}.lh-1{line-height:1 !important}.lh-sm{line-height:1.25 !important}.lh-base{line-height:1.5 !important}.lh-lg{line-height:2 !important}.text-start{text-align:left !important}.text-end{text-align:right !important}.text-center{text-align:center !important}.text-decoration-none{text-decoration:none !important}.text-decoration-underline{text-decoration:underline !important}.text-decoration-line-through{text-decoration:line-through !important}.text-lowercase{text-transform:lowercase !important}.text-uppercase{text-transform:uppercase !important}.text-capitalize{text-transform:capitalize !important}.text-wrap{white-space:normal !important}.text-nowrap{white-space:nowrap !important}.text-break{word-wrap:break-word !important;word-break:break-word !important}.text-primary{--bs-text-opacity: 1;color:rgba(var(--bs-primary-rgb), var(--bs-text-opacity)) !important}.text-secondary{--bs-text-opacity: 1;color:rgba(var(--bs-secondary-rgb), var(--bs-text-opacity)) !important}.text-success{--bs-text-opacity: 1;color:rgba(var(--bs-success-rgb), var(--bs-text-opacity)) !important}.text-info{--bs-text-opacity: 1;color:rgba(var(--bs-info-rgb), var(--bs-text-opacity)) !important}.text-warning{--bs-text-opacity: 1;color:rgba(var(--bs-warning-rgb), var(--bs-text-opacity)) !important}.text-danger{--bs-text-opacity: 1;color:rgba(var(--bs-danger-rgb), var(--bs-text-opacity)) !important}.text-light{--bs-text-opacity: 1;color:rgba(var(--bs-light-rgb), var(--bs-text-opacity)) !important}.text-dark{--bs-text-opacity: 1;color:rgba(var(--bs-dark-rgb), var(--bs-text-opacity)) !important}.text-black{--bs-text-opacity: 1;color:rgba(var(--bs-black-rgb), var(--bs-text-opacity)) !important}.text-white{--bs-text-opacity: 1;color:rgba(var(--bs-white-rgb), var(--bs-text-opacity)) !important}.text-body{--bs-text-opacity: 1;color:rgba(var(--bs-body-color-rgb), var(--bs-text-opacity)) !important}.text-muted{--bs-text-opacity: 1;color:var(--t42-content-color-muted) !important}.text-black-50{--bs-text-opacity: 1;color:rgba(0,0,0,0.5) !important}.text-white-50{--bs-text-opacity: 1;color:rgba(255,255,255,0.5) !important}.text-reset{--bs-text-opacity: 1;color:inherit !important}.text-opacity-25{--bs-text-opacity: .25}.text-opacity-50{--bs-text-opacity: .5}.text-opacity-75{--bs-text-opacity: .75}.text-opacity-100{--bs-text-opacity: 1}.bg-primary{--bs-bg-opacity: 1;background-color:rgba(var(--bs-primary-rgb), var(--bs-bg-opacity)) !important}.bg-secondary{--bs-bg-opacity: 1;background-color:rgba(var(--bs-secondary-rgb), var(--bs-bg-opacity)) !important}.bg-success{--bs-bg-opacity: 1;background-color:rgba(var(--bs-success-rgb), var(--bs-bg-opacity)) !important}.bg-info{--bs-bg-opacity: 1;background-color:rgba(var(--bs-info-rgb), var(--bs-bg-opacity)) !important}.bg-warning{--bs-bg-opacity: 1;background-color:rgba(var(--bs-warning-rgb), var(--bs-bg-opacity)) !important}.bg-danger{--bs-bg-opacity: 1;background-color:rgba(var(--bs-danger-rgb), var(--bs-bg-opacity)) !important}.bg-light{--bs-bg-opacity: 1;background-color:rgba(var(--bs-light-rgb), var(--bs-bg-opacity)) !important}.bg-dark{--bs-bg-opacity: 1;background-color:rgba(var(--bs-dark-rgb), var(--bs-bg-opacity)) !important}.bg-black{--bs-bg-opacity: 1;background-color:rgba(var(--bs-black-rgb), var(--bs-bg-opacity)) !important}.bg-white{--bs-bg-opacity: 1;background-color:rgba(var(--bs-white-rgb), var(--bs-bg-opacity)) !important}.bg-body{--bs-bg-opacity: 1;background-color:rgba(var(--bs-body-bg-rgb), var(--bs-bg-opacity)) !important}.bg-transparent{--bs-bg-opacity: 1;background-color:rgba(0,0,0,0) !important}.bg-opacity-10{--bs-bg-opacity: .1}.bg-opacity-25{--bs-bg-opacity: .25}.bg-opacity-50{--bs-bg-opacity: .5}.bg-opacity-75{--bs-bg-opacity: .75}.bg-opacity-100{--bs-bg-opacity: 1}.bg-gradient{background-image:var(--bs-gradient) !important}.user-select-all{user-select:all !important}.user-select-auto{user-select:auto !important}.user-select-none{user-select:none !important}.pe-none{pointer-events:none !important}.pe-auto{pointer-events:auto !important}.rounded{border-radius:.25rem !important}.rounded-0{border-radius:0 !important}.rounded-1{border-radius:.25rem !important}.rounded-2{border-radius:.25rem !important}.rounded-3{border-radius:1rem !important}.rounded-circle{border-radius:50% !important}.rounded-pill{border-radius:50rem !important}.rounded-top{border-top-left-radius:.25rem !important;border-top-right-radius:.25rem !important}.rounded-end{border-top-right-radius:.25rem !important;border-bottom-right-radius:.25rem !important}.rounded-bottom{border-bottom-right-radius:.25rem !important;border-bottom-left-radius:.25rem !important}.rounded-start{border-bottom-left-radius:.25rem !important;border-top-left-radius:.25rem !important}.visible{visibility:visible !important}.invisible{visibility:hidden !important}@media (min-width: 576px){.float-sm-start{float:left !important}.float-sm-end{float:right !important}.float-sm-none{float:none !important}.d-sm-inline{display:inline !important}.d-sm-inline-block{display:inline-block !important}.d-sm-block{display:block !important}.d-sm-grid{display:grid !important}.d-sm-table{display:table !important}.d-sm-table-row{display:table-row !important}.d-sm-table-cell{display:table-cell !important}.d-sm-flex{display:flex !important}.d-sm-inline-flex{display:inline-flex !important}.d-sm-none{display:none !important}.flex-sm-fill{flex:1 1 auto !important}.flex-sm-row{flex-direction:row !important}.flex-sm-column{flex-direction:column !important}.flex-sm-row-reverse{flex-direction:row-reverse !important}.flex-sm-column-reverse{flex-direction:column-reverse !important}.flex-sm-grow-0{flex-grow:0 !important}.flex-sm-grow-1{flex-grow:1 !important}.flex-sm-shrink-0{flex-shrink:0 !important}.flex-sm-shrink-1{flex-shrink:1 !important}.flex-sm-wrap{flex-wrap:wrap !important}.flex-sm-nowrap{flex-wrap:nowrap !important}.flex-sm-wrap-reverse{flex-wrap:wrap-reverse !important}.gap-sm-0{gap:0 !important}.gap-sm-1{gap:.25rem !important}.gap-sm-2{gap:.5rem !important}.gap-sm-3{gap:1rem !important}.gap-sm-4{gap:1.5rem !important}.gap-sm-5{gap:3rem !important}.justify-content-sm-start{justify-content:flex-start !important}.justify-content-sm-end{justify-content:flex-end !important}.justify-content-sm-center{justify-content:center !important}.justify-content-sm-between{justify-content:space-between !important}.justify-content-sm-around{justify-content:space-around !important}.justify-content-sm-evenly{justify-content:space-evenly !important}.align-items-sm-start{align-items:flex-start !important}.align-items-sm-end{align-items:flex-end !important}.align-items-sm-center{align-items:center !important}.align-items-sm-baseline{align-items:baseline !important}.align-items-sm-stretch{align-items:stretch !important}.align-content-sm-start{align-content:flex-start !important}.align-content-sm-end{align-content:flex-end !important}.align-content-sm-center{align-content:center !important}.align-content-sm-between{align-content:space-between !important}.align-content-sm-around{align-content:space-around !important}.align-content-sm-stretch{align-content:stretch !important}.align-self-sm-auto{align-self:auto !important}.align-self-sm-start{align-self:flex-start !important}.align-self-sm-end{align-self:flex-end !important}.align-self-sm-center{align-self:center !important}.align-self-sm-baseline{align-self:baseline !important}.align-self-sm-stretch{align-self:stretch !important}.order-sm-first{order:-1 !important}.order-sm-0{order:0 !important}.order-sm-1{order:1 !important}.order-sm-2{order:2 !important}.order-sm-3{order:3 !important}.order-sm-4{order:4 !important}.order-sm-5{order:5 !important}.order-sm-last{order:6 !important}.m-sm-0{margin:0 !important}.m-sm-1{margin:.25rem !important}.m-sm-2{margin:.5rem !important}.m-sm-3{margin:1rem !important}.m-sm-4{margin:1.5rem !important}.m-sm-5{margin:3rem !important}.m-sm-auto{margin:auto !important}.mx-sm-0{margin-right:0 !important;margin-left:0 !important}.mx-sm-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-sm-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-sm-3{margin-right:1rem !important;margin-left:1rem !important}.mx-sm-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-sm-5{margin-right:3rem !important;margin-left:3rem !important}.mx-sm-auto{margin-right:auto !important;margin-left:auto !important}.my-sm-0{margin-top:0 !important;margin-bottom:0 !important}.my-sm-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-sm-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-sm-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-sm-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-sm-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-sm-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-sm-0{margin-top:0 !important}.mt-sm-1{margin-top:.25rem !important}.mt-sm-2{margin-top:.5rem !important}.mt-sm-3{margin-top:1rem !important}.mt-sm-4{margin-top:1.5rem !important}.mt-sm-5{margin-top:3rem !important}.mt-sm-auto{margin-top:auto !important}.me-sm-0{margin-right:0 !important}.me-sm-1{margin-right:.25rem !important}.me-sm-2{margin-right:.5rem !important}.me-sm-3{margin-right:1rem !important}.me-sm-4{margin-right:1.5rem !important}.me-sm-5{margin-right:3rem !important}.me-sm-auto{margin-right:auto !important}.mb-sm-0{margin-bottom:0 !important}.mb-sm-1{margin-bottom:.25rem !important}.mb-sm-2{margin-bottom:.5rem !important}.mb-sm-3{margin-bottom:1rem !important}.mb-sm-4{margin-bottom:1.5rem !important}.mb-sm-5{margin-bottom:3rem !important}.mb-sm-auto{margin-bottom:auto !important}.ms-sm-0{margin-left:0 !important}.ms-sm-1{margin-left:.25rem !important}.ms-sm-2{margin-left:.5rem !important}.ms-sm-3{margin-left:1rem !important}.ms-sm-4{margin-left:1.5rem !important}.ms-sm-5{margin-left:3rem !important}.ms-sm-auto{margin-left:auto !important}.p-sm-0{padding:0 !important}.p-sm-1{padding:.25rem !important}.p-sm-2{padding:.5rem !important}.p-sm-3{padding:1rem !important}.p-sm-4{padding:1.5rem !important}.p-sm-5{padding:3rem !important}.px-sm-0{padding-right:0 !important;padding-left:0 !important}.px-sm-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-sm-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-sm-3{padding-right:1rem !important;padding-left:1rem !important}.px-sm-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-sm-5{padding-right:3rem !important;padding-left:3rem !important}.py-sm-0{padding-top:0 !important;padding-bottom:0 !important}.py-sm-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-sm-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-sm-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-sm-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-sm-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-sm-0{padding-top:0 !important}.pt-sm-1{padding-top:.25rem !important}.pt-sm-2{padding-top:.5rem !important}.pt-sm-3{padding-top:1rem !important}.pt-sm-4{padding-top:1.5rem !important}.pt-sm-5{padding-top:3rem !important}.pe-sm-0{padding-right:0 !important}.pe-sm-1{padding-right:.25rem !important}.pe-sm-2{padding-right:.5rem !important}.pe-sm-3{padding-right:1rem !important}.pe-sm-4{padding-right:1.5rem !important}.pe-sm-5{padding-right:3rem !important}.pb-sm-0{padding-bottom:0 !important}.pb-sm-1{padding-bottom:.25rem !important}.pb-sm-2{padding-bottom:.5rem !important}.pb-sm-3{padding-bottom:1rem !important}.pb-sm-4{padding-bottom:1.5rem !important}.pb-sm-5{padding-bottom:3rem !important}.ps-sm-0{padding-left:0 !important}.ps-sm-1{padding-left:.25rem !important}.ps-sm-2{padding-left:.5rem !important}.ps-sm-3{padding-left:1rem !important}.ps-sm-4{padding-left:1.5rem !important}.ps-sm-5{padding-left:3rem !important}.text-sm-start{text-align:left !important}.text-sm-end{text-align:right !important}.text-sm-center{text-align:center !important}}@media (min-width: 768px){.float-md-start{float:left !important}.float-md-end{float:right !important}.float-md-none{float:none !important}.d-md-inline{display:inline !important}.d-md-inline-block{display:inline-block !important}.d-md-block{display:block !important}.d-md-grid{display:grid !important}.d-md-table{display:table !important}.d-md-table-row{display:table-row !important}.d-md-table-cell{display:table-cell !important}.d-md-flex{display:flex !important}.d-md-inline-flex{display:inline-flex !important}.d-md-none{display:none !important}.flex-md-fill{flex:1 1 auto !important}.flex-md-row{flex-direction:row !important}.flex-md-column{flex-direction:column !important}.flex-md-row-reverse{flex-direction:row-reverse !important}.flex-md-column-reverse{flex-direction:column-reverse !important}.flex-md-grow-0{flex-grow:0 !important}.flex-md-grow-1{flex-grow:1 !important}.flex-md-shrink-0{flex-shrink:0 !important}.flex-md-shrink-1{flex-shrink:1 !important}.flex-md-wrap{flex-wrap:wrap !important}.flex-md-nowrap{flex-wrap:nowrap !important}.flex-md-wrap-reverse{flex-wrap:wrap-reverse !important}.gap-md-0{gap:0 !important}.gap-md-1{gap:.25rem !important}.gap-md-2{gap:.5rem !important}.gap-md-3{gap:1rem !important}.gap-md-4{gap:1.5rem !important}.gap-md-5{gap:3rem !important}.justify-content-md-start{justify-content:flex-start !important}.justify-content-md-end{justify-content:flex-end !important}.justify-content-md-center{justify-content:center !important}.justify-content-md-between{justify-content:space-between !important}.justify-content-md-around{justify-content:space-around !important}.justify-content-md-evenly{justify-content:space-evenly !important}.align-items-md-start{align-items:flex-start !important}.align-items-md-end{align-items:flex-end !important}.align-items-md-center{align-items:center !important}.align-items-md-baseline{align-items:baseline !important}.align-items-md-stretch{align-items:stretch !important}.align-content-md-start{align-content:flex-start !important}.align-content-md-end{align-content:flex-end !important}.align-content-md-center{align-content:center !important}.align-content-md-between{align-content:space-between !important}.align-content-md-around{align-content:space-around !important}.align-content-md-stretch{align-content:stretch !important}.align-self-md-auto{align-self:auto !important}.align-self-md-start{align-self:flex-start !important}.align-self-md-end{align-self:flex-end !important}.align-self-md-center{align-self:center !important}.align-self-md-baseline{align-self:baseline !important}.align-self-md-stretch{align-self:stretch !important}.order-md-first{order:-1 !important}.order-md-0{order:0 !important}.order-md-1{order:1 !important}.order-md-2{order:2 !important}.order-md-3{order:3 !important}.order-md-4{order:4 !important}.order-md-5{order:5 !important}.order-md-last{order:6 !important}.m-md-0{margin:0 !important}.m-md-1{margin:.25rem !important}.m-md-2{margin:.5rem !important}.m-md-3{margin:1rem !important}.m-md-4{margin:1.5rem !important}.m-md-5{margin:3rem !important}.m-md-auto{margin:auto !important}.mx-md-0{margin-right:0 !important;margin-left:0 !important}.mx-md-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-md-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-md-3{margin-right:1rem !important;margin-left:1rem !important}.mx-md-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-md-5{margin-right:3rem !important;margin-left:3rem !important}.mx-md-auto{margin-right:auto !important;margin-left:auto !important}.my-md-0{margin-top:0 !important;margin-bottom:0 !important}.my-md-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-md-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-md-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-md-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-md-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-md-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-md-0{margin-top:0 !important}.mt-md-1{margin-top:.25rem !important}.mt-md-2{margin-top:.5rem !important}.mt-md-3{margin-top:1rem !important}.mt-md-4{margin-top:1.5rem !important}.mt-md-5{margin-top:3rem !important}.mt-md-auto{margin-top:auto !important}.me-md-0{margin-right:0 !important}.me-md-1{margin-right:.25rem !important}.me-md-2{margin-right:.5rem !important}.me-md-3{margin-right:1rem !important}.me-md-4{margin-right:1.5rem !important}.me-md-5{margin-right:3rem !important}.me-md-auto{margin-right:auto !important}.mb-md-0{margin-bottom:0 !important}.mb-md-1{margin-bottom:.25rem !important}.mb-md-2{margin-bottom:.5rem !important}.mb-md-3{margin-bottom:1rem !important}.mb-md-4{margin-bottom:1.5rem !important}.mb-md-5{margin-bottom:3rem !important}.mb-md-auto{margin-bottom:auto !important}.ms-md-0{margin-left:0 !important}.ms-md-1{margin-left:.25rem !important}.ms-md-2{margin-left:.5rem !important}.ms-md-3{margin-left:1rem !important}.ms-md-4{margin-left:1.5rem !important}.ms-md-5{margin-left:3rem !important}.ms-md-auto{margin-left:auto !important}.p-md-0{padding:0 !important}.p-md-1{padding:.25rem !important}.p-md-2{padding:.5rem !important}.p-md-3{padding:1rem !important}.p-md-4{padding:1.5rem !important}.p-md-5{padding:3rem !important}.px-md-0{padding-right:0 !important;padding-left:0 !important}.px-md-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-md-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-md-3{padding-right:1rem !important;padding-left:1rem !important}.px-md-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-md-5{padding-right:3rem !important;padding-left:3rem !important}.py-md-0{padding-top:0 !important;padding-bottom:0 !important}.py-md-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-md-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-md-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-md-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-md-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-md-0{padding-top:0 !important}.pt-md-1{padding-top:.25rem !important}.pt-md-2{padding-top:.5rem !important}.pt-md-3{padding-top:1rem !important}.pt-md-4{padding-top:1.5rem !important}.pt-md-5{padding-top:3rem !important}.pe-md-0{padding-right:0 !important}.pe-md-1{padding-right:.25rem !important}.pe-md-2{padding-right:.5rem !important}.pe-md-3{padding-right:1rem !important}.pe-md-4{padding-right:1.5rem !important}.pe-md-5{padding-right:3rem !important}.pb-md-0{padding-bottom:0 !important}.pb-md-1{padding-bottom:.25rem !important}.pb-md-2{padding-bottom:.5rem !important}.pb-md-3{padding-bottom:1rem !important}.pb-md-4{padding-bottom:1.5rem !important}.pb-md-5{padding-bottom:3rem !important}.ps-md-0{padding-left:0 !important}.ps-md-1{padding-left:.25rem !important}.ps-md-2{padding-left:.5rem !important}.ps-md-3{padding-left:1rem !important}.ps-md-4{padding-left:1.5rem !important}.ps-md-5{padding-left:3rem !important}.text-md-start{text-align:left !important}.text-md-end{text-align:right !important}.text-md-center{text-align:center !important}}@media (min-width: 992px){.float-lg-start{float:left !important}.float-lg-end{float:right !important}.float-lg-none{float:none !important}.d-lg-inline{display:inline !important}.d-lg-inline-block{display:inline-block !important}.d-lg-block{display:block !important}.d-lg-grid{display:grid !important}.d-lg-table{display:table !important}.d-lg-table-row{display:table-row !important}.d-lg-table-cell{display:table-cell !important}.d-lg-flex{display:flex !important}.d-lg-inline-flex{display:inline-flex !important}.d-lg-none{display:none !important}.flex-lg-fill{flex:1 1 auto !important}.flex-lg-row{flex-direction:row !important}.flex-lg-column{flex-direction:column !important}.flex-lg-row-reverse{flex-direction:row-reverse !important}.flex-lg-column-reverse{flex-direction:column-reverse !important}.flex-lg-grow-0{flex-grow:0 !important}.flex-lg-grow-1{flex-grow:1 !important}.flex-lg-shrink-0{flex-shrink:0 !important}.flex-lg-shrink-1{flex-shrink:1 !important}.flex-lg-wrap{flex-wrap:wrap !important}.flex-lg-nowrap{flex-wrap:nowrap !important}.flex-lg-wrap-reverse{flex-wrap:wrap-reverse !important}.gap-lg-0{gap:0 !important}.gap-lg-1{gap:.25rem !important}.gap-lg-2{gap:.5rem !important}.gap-lg-3{gap:1rem !important}.gap-lg-4{gap:1.5rem !important}.gap-lg-5{gap:3rem !important}.justify-content-lg-start{justify-content:flex-start !important}.justify-content-lg-end{justify-content:flex-end !important}.justify-content-lg-center{justify-content:center !important}.justify-content-lg-between{justify-content:space-between !important}.justify-content-lg-around{justify-content:space-around !important}.justify-content-lg-evenly{justify-content:space-evenly !important}.align-items-lg-start{align-items:flex-start !important}.align-items-lg-end{align-items:flex-end !important}.align-items-lg-center{align-items:center !important}.align-items-lg-baseline{align-items:baseline !important}.align-items-lg-stretch{align-items:stretch !important}.align-content-lg-start{align-content:flex-start !important}.align-content-lg-end{align-content:flex-end !important}.align-content-lg-center{align-content:center !important}.align-content-lg-between{align-content:space-between !important}.align-content-lg-around{align-content:space-around !important}.align-content-lg-stretch{align-content:stretch !important}.align-self-lg-auto{align-self:auto !important}.align-self-lg-start{align-self:flex-start !important}.align-self-lg-end{align-self:flex-end !important}.align-self-lg-center{align-self:center !important}.align-self-lg-baseline{align-self:baseline !important}.align-self-lg-stretch{align-self:stretch !important}.order-lg-first{order:-1 !important}.order-lg-0{order:0 !important}.order-lg-1{order:1 !important}.order-lg-2{order:2 !important}.order-lg-3{order:3 !important}.order-lg-4{order:4 !important}.order-lg-5{order:5 !important}.order-lg-last{order:6 !important}.m-lg-0{margin:0 !important}.m-lg-1{margin:.25rem !important}.m-lg-2{margin:.5rem !important}.m-lg-3{margin:1rem !important}.m-lg-4{margin:1.5rem !important}.m-lg-5{margin:3rem !important}.m-lg-auto{margin:auto !important}.mx-lg-0{margin-right:0 !important;margin-left:0 !important}.mx-lg-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-lg-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-lg-3{margin-right:1rem !important;margin-left:1rem !important}.mx-lg-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-lg-5{margin-right:3rem !important;margin-left:3rem !important}.mx-lg-auto{margin-right:auto !important;margin-left:auto !important}.my-lg-0{margin-top:0 !important;margin-bottom:0 !important}.my-lg-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-lg-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-lg-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-lg-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-lg-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-lg-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-lg-0{margin-top:0 !important}.mt-lg-1{margin-top:.25rem !important}.mt-lg-2{margin-top:.5rem !important}.mt-lg-3{margin-top:1rem !important}.mt-lg-4{margin-top:1.5rem !important}.mt-lg-5{margin-top:3rem !important}.mt-lg-auto{margin-top:auto !important}.me-lg-0{margin-right:0 !important}.me-lg-1{margin-right:.25rem !important}.me-lg-2{margin-right:.5rem !important}.me-lg-3{margin-right:1rem !important}.me-lg-4{margin-right:1.5rem !important}.me-lg-5{margin-right:3rem !important}.me-lg-auto{margin-right:auto !important}.mb-lg-0{margin-bottom:0 !important}.mb-lg-1{margin-bottom:.25rem !important}.mb-lg-2{margin-bottom:.5rem !important}.mb-lg-3{margin-bottom:1rem !important}.mb-lg-4{margin-bottom:1.5rem !important}.mb-lg-5{margin-bottom:3rem !important}.mb-lg-auto{margin-bottom:auto !important}.ms-lg-0{margin-left:0 !important}.ms-lg-1{margin-left:.25rem !important}.ms-lg-2{margin-left:.5rem !important}.ms-lg-3{margin-left:1rem !important}.ms-lg-4{margin-left:1.5rem !important}.ms-lg-5{margin-left:3rem !important}.ms-lg-auto{margin-left:auto !important}.p-lg-0{padding:0 !important}.p-lg-1{padding:.25rem !important}.p-lg-2{padding:.5rem !important}.p-lg-3{padding:1rem !important}.p-lg-4{padding:1.5rem !important}.p-lg-5{padding:3rem !important}.px-lg-0{padding-right:0 !important;padding-left:0 !important}.px-lg-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-lg-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-lg-3{padding-right:1rem !important;padding-left:1rem !important}.px-lg-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-lg-5{padding-right:3rem !important;padding-left:3rem !important}.py-lg-0{padding-top:0 !important;padding-bottom:0 !important}.py-lg-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-lg-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-lg-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-lg-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-lg-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-lg-0{padding-top:0 !important}.pt-lg-1{padding-top:.25rem !important}.pt-lg-2{padding-top:.5rem !important}.pt-lg-3{padding-top:1rem !important}.pt-lg-4{padding-top:1.5rem !important}.pt-lg-5{padding-top:3rem !important}.pe-lg-0{padding-right:0 !important}.pe-lg-1{padding-right:.25rem !important}.pe-lg-2{padding-right:.5rem !important}.pe-lg-3{padding-right:1rem !important}.pe-lg-4{padding-right:1.5rem !important}.pe-lg-5{padding-right:3rem !important}.pb-lg-0{padding-bottom:0 !important}.pb-lg-1{padding-bottom:.25rem !important}.pb-lg-2{padding-bottom:.5rem !important}.pb-lg-3{padding-bottom:1rem !important}.pb-lg-4{padding-bottom:1.5rem !important}.pb-lg-5{padding-bottom:3rem !important}.ps-lg-0{padding-left:0 !important}.ps-lg-1{padding-left:.25rem !important}.ps-lg-2{padding-left:.5rem !important}.ps-lg-3{padding-left:1rem !important}.ps-lg-4{padding-left:1.5rem !important}.ps-lg-5{padding-left:3rem !important}.text-lg-start{text-align:left !important}.text-lg-end{text-align:right !important}.text-lg-center{text-align:center !important}}@media (min-width: 1200px){.float-xl-start{float:left !important}.float-xl-end{float:right !important}.float-xl-none{float:none !important}.d-xl-inline{display:inline !important}.d-xl-inline-block{display:inline-block !important}.d-xl-block{display:block !important}.d-xl-grid{display:grid !important}.d-xl-table{display:table !important}.d-xl-table-row{display:table-row !important}.d-xl-table-cell{display:table-cell !important}.d-xl-flex{display:flex !important}.d-xl-inline-flex{display:inline-flex !important}.d-xl-none{display:none !important}.flex-xl-fill{flex:1 1 auto !important}.flex-xl-row{flex-direction:row !important}.flex-xl-column{flex-direction:column !important}.flex-xl-row-reverse{flex-direction:row-reverse !important}.flex-xl-column-reverse{flex-direction:column-reverse !important}.flex-xl-grow-0{flex-grow:0 !important}.flex-xl-grow-1{flex-grow:1 !important}.flex-xl-shrink-0{flex-shrink:0 !important}.flex-xl-shrink-1{flex-shrink:1 !important}.flex-xl-wrap{flex-wrap:wrap !important}.flex-xl-nowrap{flex-wrap:nowrap !important}.flex-xl-wrap-reverse{flex-wrap:wrap-reverse !important}.gap-xl-0{gap:0 !important}.gap-xl-1{gap:.25rem !important}.gap-xl-2{gap:.5rem !important}.gap-xl-3{gap:1rem !important}.gap-xl-4{gap:1.5rem !important}.gap-xl-5{gap:3rem !important}.justify-content-xl-start{justify-content:flex-start !important}.justify-content-xl-end{justify-content:flex-end !important}.justify-content-xl-center{justify-content:center !important}.justify-content-xl-between{justify-content:space-between !important}.justify-content-xl-around{justify-content:space-around !important}.justify-content-xl-evenly{justify-content:space-evenly !important}.align-items-xl-start{align-items:flex-start !important}.align-items-xl-end{align-items:flex-end !important}.align-items-xl-center{align-items:center !important}.align-items-xl-baseline{align-items:baseline !important}.align-items-xl-stretch{align-items:stretch !important}.align-content-xl-start{align-content:flex-start !important}.align-content-xl-end{align-content:flex-end !important}.align-content-xl-center{align-content:center !important}.align-content-xl-between{align-content:space-between !important}.align-content-xl-around{align-content:space-around !important}.align-content-xl-stretch{align-content:stretch !important}.align-self-xl-auto{align-self:auto !important}.align-self-xl-start{align-self:flex-start !important}.align-self-xl-end{align-self:flex-end !important}.align-self-xl-center{align-self:center !important}.align-self-xl-baseline{align-self:baseline !important}.align-self-xl-stretch{align-self:stretch !important}.order-xl-first{order:-1 !important}.order-xl-0{order:0 !important}.order-xl-1{order:1 !important}.order-xl-2{order:2 !important}.order-xl-3{order:3 !important}.order-xl-4{order:4 !important}.order-xl-5{order:5 !important}.order-xl-last{order:6 !important}.m-xl-0{margin:0 !important}.m-xl-1{margin:.25rem !important}.m-xl-2{margin:.5rem !important}.m-xl-3{margin:1rem !important}.m-xl-4{margin:1.5rem !important}.m-xl-5{margin:3rem !important}.m-xl-auto{margin:auto !important}.mx-xl-0{margin-right:0 !important;margin-left:0 !important}.mx-xl-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-xl-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-xl-3{margin-right:1rem !important;margin-left:1rem !important}.mx-xl-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-xl-5{margin-right:3rem !important;margin-left:3rem !important}.mx-xl-auto{margin-right:auto !important;margin-left:auto !important}.my-xl-0{margin-top:0 !important;margin-bottom:0 !important}.my-xl-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-xl-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-xl-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-xl-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-xl-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-xl-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-xl-0{margin-top:0 !important}.mt-xl-1{margin-top:.25rem !important}.mt-xl-2{margin-top:.5rem !important}.mt-xl-3{margin-top:1rem !important}.mt-xl-4{margin-top:1.5rem !important}.mt-xl-5{margin-top:3rem !important}.mt-xl-auto{margin-top:auto !important}.me-xl-0{margin-right:0 !important}.me-xl-1{margin-right:.25rem !important}.me-xl-2{margin-right:.5rem !important}.me-xl-3{margin-right:1rem !important}.me-xl-4{margin-right:1.5rem !important}.me-xl-5{margin-right:3rem !important}.me-xl-auto{margin-right:auto !important}.mb-xl-0{margin-bottom:0 !important}.mb-xl-1{margin-bottom:.25rem !important}.mb-xl-2{margin-bottom:.5rem !important}.mb-xl-3{margin-bottom:1rem !important}.mb-xl-4{margin-bottom:1.5rem !important}.mb-xl-5{margin-bottom:3rem !important}.mb-xl-auto{margin-bottom:auto !important}.ms-xl-0{margin-left:0 !important}.ms-xl-1{margin-left:.25rem !important}.ms-xl-2{margin-left:.5rem !important}.ms-xl-3{margin-left:1rem !important}.ms-xl-4{margin-left:1.5rem !important}.ms-xl-5{margin-left:3rem !important}.ms-xl-auto{margin-left:auto !important}.p-xl-0{padding:0 !important}.p-xl-1{padding:.25rem !important}.p-xl-2{padding:.5rem !important}.p-xl-3{padding:1rem !important}.p-xl-4{padding:1.5rem !important}.p-xl-5{padding:3rem !important}.px-xl-0{padding-right:0 !important;padding-left:0 !important}.px-xl-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-xl-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-xl-3{padding-right:1rem !important;padding-left:1rem !important}.px-xl-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-xl-5{padding-right:3rem !important;padding-left:3rem !important}.py-xl-0{padding-top:0 !important;padding-bottom:0 !important}.py-xl-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-xl-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-xl-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-xl-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-xl-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-xl-0{padding-top:0 !important}.pt-xl-1{padding-top:.25rem !important}.pt-xl-2{padding-top:.5rem !important}.pt-xl-3{padding-top:1rem !important}.pt-xl-4{padding-top:1.5rem !important}.pt-xl-5{padding-top:3rem !important}.pe-xl-0{padding-right:0 !important}.pe-xl-1{padding-right:.25rem !important}.pe-xl-2{padding-right:.5rem !important}.pe-xl-3{padding-right:1rem !important}.pe-xl-4{padding-right:1.5rem !important}.pe-xl-5{padding-right:3rem !important}.pb-xl-0{padding-bottom:0 !important}.pb-xl-1{padding-bottom:.25rem !important}.pb-xl-2{padding-bottom:.5rem !important}.pb-xl-3{padding-bottom:1rem !important}.pb-xl-4{padding-bottom:1.5rem !important}.pb-xl-5{padding-bottom:3rem !important}.ps-xl-0{padding-left:0 !important}.ps-xl-1{padding-left:.25rem !important}.ps-xl-2{padding-left:.5rem !important}.ps-xl-3{padding-left:1rem !important}.ps-xl-4{padding-left:1.5rem !important}.ps-xl-5{padding-left:3rem !important}.text-xl-start{text-align:left !important}.text-xl-end{text-align:right !important}.text-xl-center{text-align:center !important}}@media (min-width: 1400px){.float-xxl-start{float:left !important}.float-xxl-end{float:right !important}.float-xxl-none{float:none !important}.d-xxl-inline{display:inline !important}.d-xxl-inline-block{display:inline-block !important}.d-xxl-block{display:block !important}.d-xxl-grid{display:grid !important}.d-xxl-table{display:table !important}.d-xxl-table-row{display:table-row !important}.d-xxl-table-cell{display:table-cell !important}.d-xxl-flex{display:flex !important}.d-xxl-inline-flex{display:inline-flex !important}.d-xxl-none{display:none !important}.flex-xxl-fill{flex:1 1 auto !important}.flex-xxl-row{flex-direction:row !important}.flex-xxl-column{flex-direction:column !important}.flex-xxl-row-reverse{flex-direction:row-reverse !important}.flex-xxl-column-reverse{flex-direction:column-reverse !important}.flex-xxl-grow-0{flex-grow:0 !important}.flex-xxl-grow-1{flex-grow:1 !important}.flex-xxl-shrink-0{flex-shrink:0 !important}.flex-xxl-shrink-1{flex-shrink:1 !important}.flex-xxl-wrap{flex-wrap:wrap !important}.flex-xxl-nowrap{flex-wrap:nowrap !important}.flex-xxl-wrap-reverse{flex-wrap:wrap-reverse !important}.gap-xxl-0{gap:0 !important}.gap-xxl-1{gap:.25rem !important}.gap-xxl-2{gap:.5rem !important}.gap-xxl-3{gap:1rem !important}.gap-xxl-4{gap:1.5rem !important}.gap-xxl-5{gap:3rem !important}.justify-content-xxl-start{justify-content:flex-start !important}.justify-content-xxl-end{justify-content:flex-end !important}.justify-content-xxl-center{justify-content:center !important}.justify-content-xxl-between{justify-content:space-between !important}.justify-content-xxl-around{justify-content:space-around !important}.justify-content-xxl-evenly{justify-content:space-evenly !important}.align-items-xxl-start{align-items:flex-start !important}.align-items-xxl-end{align-items:flex-end !important}.align-items-xxl-center{align-items:center !important}.align-items-xxl-baseline{align-items:baseline !important}.align-items-xxl-stretch{align-items:stretch !important}.align-content-xxl-start{align-content:flex-start !important}.align-content-xxl-end{align-content:flex-end !important}.align-content-xxl-center{align-content:center !important}.align-content-xxl-between{align-content:space-between !important}.align-content-xxl-around{align-content:space-around !important}.align-content-xxl-stretch{align-content:stretch !important}.align-self-xxl-auto{align-self:auto !important}.align-self-xxl-start{align-self:flex-start !important}.align-self-xxl-end{align-self:flex-end !important}.align-self-xxl-center{align-self:center !important}.align-self-xxl-baseline{align-self:baseline !important}.align-self-xxl-stretch{align-self:stretch !important}.order-xxl-first{order:-1 !important}.order-xxl-0{order:0 !important}.order-xxl-1{order:1 !important}.order-xxl-2{order:2 !important}.order-xxl-3{order:3 !important}.order-xxl-4{order:4 !important}.order-xxl-5{order:5 !important}.order-xxl-last{order:6 !important}.m-xxl-0{margin:0 !important}.m-xxl-1{margin:.25rem !important}.m-xxl-2{margin:.5rem !important}.m-xxl-3{margin:1rem !important}.m-xxl-4{margin:1.5rem !important}.m-xxl-5{margin:3rem !important}.m-xxl-auto{margin:auto !important}.mx-xxl-0{margin-right:0 !important;margin-left:0 !important}.mx-xxl-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-xxl-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-xxl-3{margin-right:1rem !important;margin-left:1rem !important}.mx-xxl-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-xxl-5{margin-right:3rem !important;margin-left:3rem !important}.mx-xxl-auto{margin-right:auto !important;margin-left:auto !important}.my-xxl-0{margin-top:0 !important;margin-bottom:0 !important}.my-xxl-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-xxl-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-xxl-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-xxl-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-xxl-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-xxl-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-xxl-0{margin-top:0 !important}.mt-xxl-1{margin-top:.25rem !important}.mt-xxl-2{margin-top:.5rem !important}.mt-xxl-3{margin-top:1rem !important}.mt-xxl-4{margin-top:1.5rem !important}.mt-xxl-5{margin-top:3rem !important}.mt-xxl-auto{margin-top:auto !important}.me-xxl-0{margin-right:0 !important}.me-xxl-1{margin-right:.25rem !important}.me-xxl-2{margin-right:.5rem !important}.me-xxl-3{margin-right:1rem !important}.me-xxl-4{margin-right:1.5rem !important}.me-xxl-5{margin-right:3rem !important}.me-xxl-auto{margin-right:auto !important}.mb-xxl-0{margin-bottom:0 !important}.mb-xxl-1{margin-bottom:.25rem !important}.mb-xxl-2{margin-bottom:.5rem !important}.mb-xxl-3{margin-bottom:1rem !important}.mb-xxl-4{margin-bottom:1.5rem !important}.mb-xxl-5{margin-bottom:3rem !important}.mb-xxl-auto{margin-bottom:auto !important}.ms-xxl-0{margin-left:0 !important}.ms-xxl-1{margin-left:.25rem !important}.ms-xxl-2{margin-left:.5rem !important}.ms-xxl-3{margin-left:1rem !important}.ms-xxl-4{margin-left:1.5rem !important}.ms-xxl-5{margin-left:3rem !important}.ms-xxl-auto{margin-left:auto !important}.p-xxl-0{padding:0 !important}.p-xxl-1{padding:.25rem !important}.p-xxl-2{padding:.5rem !important}.p-xxl-3{padding:1rem !important}.p-xxl-4{padding:1.5rem !important}.p-xxl-5{padding:3rem !important}.px-xxl-0{padding-right:0 !important;padding-left:0 !important}.px-xxl-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-xxl-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-xxl-3{padding-right:1rem !important;padding-left:1rem !important}.px-xxl-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-xxl-5{padding-right:3rem !important;padding-left:3rem !important}.py-xxl-0{padding-top:0 !important;padding-bottom:0 !important}.py-xxl-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-xxl-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-xxl-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-xxl-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-xxl-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-xxl-0{padding-top:0 !important}.pt-xxl-1{padding-top:.25rem !important}.pt-xxl-2{padding-top:.5rem !important}.pt-xxl-3{padding-top:1rem !important}.pt-xxl-4{padding-top:1.5rem !important}.pt-xxl-5{padding-top:3rem !important}.pe-xxl-0{padding-right:0 !important}.pe-xxl-1{padding-right:.25rem !important}.pe-xxl-2{padding-right:.5rem !important}.pe-xxl-3{padding-right:1rem !important}.pe-xxl-4{padding-right:1.5rem !important}.pe-xxl-5{padding-right:3rem !important}.pb-xxl-0{padding-bottom:0 !important}.pb-xxl-1{padding-bottom:.25rem !important}.pb-xxl-2{padding-bottom:.5rem !important}.pb-xxl-3{padding-bottom:1rem !important}.pb-xxl-4{padding-bottom:1.5rem !important}.pb-xxl-5{padding-bottom:3rem !important}.ps-xxl-0{padding-left:0 !important}.ps-xxl-1{padding-left:.25rem !important}.ps-xxl-2{padding-left:.5rem !important}.ps-xxl-3{padding-left:1rem !important}.ps-xxl-4{padding-left:1.5rem !important}.ps-xxl-5{padding-left:3rem !important}.text-xxl-start{text-align:left !important}.text-xxl-end{text-align:right !important}.text-xxl-center{text-align:center !important}}@media (min-width: 1200px){.fs-1{font-size:1.40625rem !important}}@media print{.d-print-inline{display:inline !important}.d-print-inline-block{display:inline-block !important}.d-print-block{display:block !important}.d-print-grid{display:grid !important}.d-print-table{display:table !important}.d-print-table-row{display:table-row !important}.d-print-table-cell{display:table-cell !important}.d-print-flex{display:flex !important}.d-print-inline-flex{display:inline-flex !important}.d-print-none{display:none !important}}body{background-size:cover}.bg-light{background-color:Rgb(var(--t42-bg-light)) !important}.bg-dark{background-color:Rgb(var(--t42-bg-dark)) !important}.bg-base{background-color:Rgb(var(--t42-bg-mid)) !important}.border{border:0.0625rem solid var(--t42-color-opacity-10) !important}.border-primary{border-color:#007be5 !important}.border-secondary,.border-info,.border-light,.border-dark,.border-white{border-color:var(--t42-color-opacity-10) !important}.border-success{border-color:#43a047 !important}.border-danger{border-color:#ff511f !important}.border-warning{border-color:#f9a825 !important}.pl-0{padding-left:0}.pl-1{padding-left:0.25rem}.pl-2{padding-left:0.5rem}.pl-3{padding-left:1rem}.pl-4{padding-left:1.5rem}.pl-5{padding-left:3rem}.pl-auto{padding-left:auto}.pr-0{padding-right:0}.pr-1{padding-right:0.25rem}.pr-2{padding-right:0.5rem}.pr-3{padding-right:1rem}.pr-4{padding-right:1.5rem}.pr-5{padding-right:3rem}.pr-auto{padding-right:auto}.ml-0{margin-left:0}.ml-1{margin-left:0.25rem}.ml-2{margin-left:0.5rem}.ml-3{margin-left:1rem}.ml-4{margin-left:1.5rem}.ml-5{margin-left:3rem}.ml-auto{margin-left:auto}.mr-0{margin-right:0}.mr-1{margin-right:0.25rem}.mr-2{margin-right:0.5rem}.mr-3{margin-right:1rem}.mr-4{margin-right:1.5rem}.mr-5{margin-right:3rem}.mr-auto{margin-right:auto}@keyframes spinner-border{to{transform:rotate(360deg) /* rtl:ignore */}}.spinner-border{display:inline-block;width:2rem;height:2rem;vertical-align:-.125em;border:.25em solid currentColor;border-right-color:transparent;border-radius:50%;animation:.75s linear infinite spinner-border}.spinner-border-sm{width:1rem;height:1rem;border-width:.2em}@keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1;transform:none}}.spinner-grow{display:inline-block;width:2rem;height:2rem;vertical-align:-.125em;background-color:currentColor;border-radius:50%;opacity:0;animation:.75s linear infinite spinner-grow}.spinner-grow-sm{width:1rem;height:1rem}@media (prefers-reduced-motion: reduce){.spinner-border,.spinner-grow{animation-duration:1.5s}}.loader-wrapper{display:flex;flex-direction:column;flex-grow:1;gap:1rem;align-items:center;justify-content:center}.loader-wrapper .loader{width:2rem;height:2rem;border-radius:50%;background:radial-gradient(farthest-side, #999d9e 94%, rgba(0,0,0,0)) center top/4px 4px no-repeat,conic-gradient(rgba(0,0,0,0) 15%, #999d9e);-webkit-mask:radial-gradient(farthest-side, rgba(0,0,0,0) calc(100% - 4px), #000 0)}.loader-wrapper.active .loader{animation:s3 1.5s infinite linear}@keyframes s3{to{transform:rotate(1turn)}}.loader-wrapper .loader-text{margin:0 auto;padding:0 0.833rem;overflow:hidden;color:var(--t42-content-color-muted);text-align:center;text-overflow:ellipsis}@keyframes clipMe{0%,100%{clip:rect(0, 220px, 2px, 0)}25%{clip:rect(0, 2px, 220px, 0)}50%{clip:rect(218px, 220px, 220px, 0)}75%{clip:rect(0, 220px, 220px, 218px)}}@keyframes spin{from{transform:rotate(0deg)}to{transform:rotate(360deg)}}.spinner{display:inline-block;animation-name:spin;animation-duration:3000ms;animation-timing-function:linear;animation-iteration-count:infinite}@font-face{font-weight:400;font-family:"Montserrat";font-style:normal;src:url(data:font/ttf;base64,AAEAAAARAQAABAAQR0RFRrFss1wAAmssAAACfkdQT1N2Wb7+AAJtrAABFy5HU1VCjJZZRgADhNwAAC8mT1MvMlYMpE4AAfmwAAAAYGNtYXBfILVpAAH6EAAACuRjdnQgMKUWggACEzwAAADkZnBnbU0kjnwAAgT0AAANbWdhc3AAAAAQAAJrJAAAAAhnbHlmzhsdpQAAARwAAct0aGVhZA5QtXgAAduUAAAANmhoZWEG0AwiAAH5jAAAACRobXR4v8HBsgAB28wAAB3AbG9jYfsbiDIAAcywAAAO4m1heHAIxQ5XAAHMkAAAACBuYW1lKqFFSQACFCAAAAHucG9zdFa6PIcAAhYQAABVE3ByZXDNS6zAAAISZAAAANUAAgAoAAACIwK8AAMABwApQCYAAAACAwACZQQBAwEBA1UEAQMDAV0AAQMBTQQEBAcEBxIREAUNFysTIREhJREhESgB+/4FAav+pQK8/URGAjD90AAAAv//AAAC3QK8AAcACgArQCgJAQQCAUoFAQQAAAEEAGYAAgJCSwMBAQFDAUwICAgKCAoREREQBgoYKyUhByMBMwEjJwMDAif+jE1nAT1jAT5pcJeXr68CvP1E/wFX/qn/////AAAC3QN3ACIABAAAAAMHEgKaAAD/////AAAC3QN3ACIABAAAAAMHGQKaAAD/////AAAC3QPhACIABAAAACcHMQKaAJYBBwcuApoBEQARsQIBsJawMyuxAwG4ARGwMysA//////88At0DdwAiAAQAAAAjBv8CmgAAAAMHGQKaAAD/////AAAC3QPhACIABAAAACcHMQKaAJYBBwctApoBEQARsQIBsJawMyuxAwG4ARGwMysA/////wAAAt0D7QAiAAQAAAAnBzECmgCWAQcHNAKaAP4AELECAbCWsDMrsQMBsP6wMyv/////AAAC3QPgACIABAAAACcHMQKaAJYBBwcyApoBEQARsQIBsJawMyuxAwG4ARGwMysA/////wAAAt0DdwAiAAQAAAADBxcCmgAA/////wAAAt0DdwAiAAQAAAADBxYCmgAA/////wAAAt0DvgAiAAQAAAAnBy8CmgCWAQcHLgNCAO4AELECAbCWsDMrsQMBsO6wMyv//////zwC3QN3ACIABAAAACMG/wKaAAAAAwcWApoAAP////8AAALdA74AIgAEAAAAJwcvApoAlgEHBy0DQgDuABCxAgGwlrAzK7EDAbDusDMr/////wAAAt0D0wAiAAQAAAAnBy8CmgCWAQcHNAMcAOQAELECAbCWsDMrsQMBsOSwMyv/////AAAC3QPmACIABAAAACcHLwKaAJYBBwcyApoBFwARsQIBsJawMyuxAwG4ARewMysA/////wAAAt0DdwAiAAQAAAADByMCmgAA/////wAAAt0DbQAiAAQAAAADBwoCmgAA//////88At0CvAAiAAQAAAADBv8CmgAA/////wAAAt0DdwAiAAQAAAADBxACmgAA/////wAAAt0DuwAiAAQAAAADByICmgAA/////wAAAt0DfQAiAAQAAAADByQCmgAA/////wAAAt0DVAAiAAQAAAADBx4CmgAA//////8gAvMCvAAiAAQAAAADBwMECAAA/////wAAAt0D1gAiAAQAAAEHBvACmgCqAAixAgKwqrAzK/////8AAALdBB0AIgAEAAABBwbxApoAqgAIsQICsKqwMyv/////AAAC3QN3ACIABAAAAAMHGgKaAAAAAv//AAAD3wK8AA8AEwBEQEEABQAGCQUGZQsBCQABBwkBZQgBBAQDXQADA0JLCgEHBwBdAgEAAEMATBAQAAAQExATEhEADwAPEREREREREQwKGyslFSE1IQcjASEVIRUhFSEVJxEjAwPf/gT+6mdnAaECMf51AV/+oWMU01dXr68CvFfXVeKoAWb+mv////8AAAPfA3cAIgAeAAAAAwcSA0AAAAADAGkAAALDArwADgAXAB8APEA5DgEEAgFKAAIABAUCBGUGAQMDAV0AAQFCSwcBBQUAXQAAAEMATBgYDw8YHxgeHRsPFw8WJyEkCAoXKwAWFRQGIyERITIWFRQGBwEVMzI2NTQmIxI2NTQjIxUzAn1GiYP+sgE6eIMzK/6NzU1TU01uVqvm5gFaWURbYgK8YFU3UBUBAOA5Nzc5/eY4PHXpAAABADD/+AKtAsQAGwAuQCsYFwsKBAIBAUoAAQEAXwAAAEhLAAICA18EAQMDSQNMAAAAGwAaJiQmBQoXKwQmJjU0NjYzMhYXByYjIgYGFRQWFjMyNxcGBiMBOalgYKppUogwQU92Tn5HR35OdVBBMIlSCF2jZmajXTc2P1NGe0xMe0ZUPzY4//8AMP/4Aq0DdwAiACEAAAADBxICxwAA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BwcDUQBzAAixAQGwc7AzK///AGn/LwLDArwAIgBSAAAAAwcEAsEAAP//AGkAAALDA3cAIgBSAAAAAwcXAsEAAP//AGkAAALDA3cAIgBSAAAAAwcWAsEAAP//AGn/PALDArwAIgBSAAAAAwb/AsEAAAABAGkAAADNArwAAwATQBAAAABCSwABAUMBTBEQAgoWKxMzESNpZGQCvP1EAAIAV//4Am0CvAAPABMAM0AwAwEABAIBAgACSgAEBAFdAwEBAUJLAAAAAl8FAQICSQJMAAATEhEQAA8ADhMlBgoWKwQmJzcWFjMyNjURMxEUBiMDMxEjAQN8MCcsaDdeYmSeiORkZAgmIVAeIG5vAY7+d5miAsT+eQD//wBQAAABUgN3ACIAWAAAAAMHEgHHAAD////5AAABPQN3ACIAWAAAAAMHGQHHAAD////oAAABTgN3ACIAWAAAAAMHFgHHAAD///+uAAABGwN3ACIAWAAAAAMHIwHHAAD//wALAAABKwNtACIAWAAAAAMHCgHHAAD//wAPAAABOQP0ACIAWAAAACcHKwHHAJYBBwcuAccBJAARsQECsJawMyuxAwG4ASSwMysA//8AYAAAANYDfQAiAFgAAAADBw4BxwAA//8AaP88AM4CvAAiAFgAAAADBv8BxwAA////5AAAAOYDdwAiAFgAAAADBxABxwAA//8APwAAAQADuwAiAFgAAAADByIBxwAA////+QAAAT0DfQAiAFgAAAADByQBxwAA//8AFgAAASADVAAiAFgAAAADBygBxwAA//8ATv8gAPECvAAiAFgAAAADByoB+AAA////8wAAAUMDdwAiAFgAAAADBxoBxwAAAAH/9//4AZ4CvAAQACxAKQMCAgABAUoAAQECXQACAkJLAAAAA18EAQMDSQNMAAAAEAAPERMkBQoXKxYmJzcWMzI2NREjNSERFAYjhGwhOjpYOz39AWBvbAg1MERTSEYBiVf+JXR1////9//4AaIDdwAiAGgAAAADBxYCGwAAAAEAaQAAAs4CvAALAB9AHAkGAQMAAQFKAgEBAUJLAwEAAEMATBISERIEChgrAQcVIxEzEQEzAQEjAU2AZGQBfHL+1QE+dQE3grUCvP55AYf+xf5///8AaQAAAs4DdwAiAGoAAAADBxcCowAA//8Aaf75As4CvAAiAGoAAAADBwECowAA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KAcKGSsBERQGBwYVFBYzMjY3FwYjIiY1NDcmJjURMxEUMzI2NRECs15XkCIcECEMEygyOEBFf41kxWBmArz+cnaSHjNJGBwJCDEYNy5DMQifjgGO/nbhb3IBigD//wBj//gCswPWACIAxwAAAQcG8AK4AKoACLEBArCqsDMr//8AY//4ArMDdwAiAMcAAAADBxoCuAAA//8AY//4ArMD9AAiAMcAAAAnBzICuACWAQcHLgK4ASQAEbEBAbCWsDMrsQIBuAEksDMrAAAB//8AAALJArwABgAhQB4FAQABAUoDAgIBAUJLAAAAQwBMAAAABgAGEREEChYrAQEjATMTEwLJ/s1j/sxs/P4CvP1EArz9wQI/AAEAIAAABEYCvAAMACdAJAsIAwMAAgFKBQQDAwICQksBAQAAQwBMAAAADAAMEhESEQYKGCsBAyMDAyMDMxMTMxMTBEbqab+/a+pnvcVcwcECvP1EAi/90QK8/ccCOf3EAjz//wAgAAAERgN3ACIA4AAAAAMHEgNgAAD//wAgAAAERgN3ACIA4AAAAAMHFgNgAAD//wAgAAAERgNtACIA4AAAAAMHCgNgAAD//wAgAAAERgN3ACIA4AAAAAMHEANgAAAAAQANAAAClAK8AAsAJkAjCgcEAQQAAQFKAgEBAUJLBAMCAABDAEwAAAALAAsSEhIFChcrIQMDIwEDMxMTMwMBAiHSz3MBB/dyxMJt9wEJASH+3wFnAVX+8wEN/q7+lgAAAf/8AAACiwK8AAgAHUAaBgMAAwABAUoCAQEBQksAAABDAEwSEhEDChcrJRUjNQEzExMzAXVj/upr4OFj8vL0Acj+jwFx/////AAAAosDdwAiAOYAAAADBxICcAAA/////AAAAosDdwAiAOYAAAADBxYCcAAA/////AAAAosDbQAiAOYAAAADBwoCcAAA/////AAAAosDfQAiAOYAAAADBw4CcAAA/////P88AosCvAAiAOYAAAADBv8CcAAA/////AAAAosDdwAiAOYAAAADBxACcAAA/////AAAAosDuwAiAOYAAAADByICcAAA/////AAAAosDVAAiAOYAAAADBx4CcAAA/////AAAAosDdwAiAOYAAAADBxoCcAAAAAEAKwAAAnQCvAAJAC9ALAgBAQIDAQADAkoAAQECXQACAkJLBAEDAwBdAAAAQwBM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AfIAxAAIsQEBsMSwMyv//wBb/y8CUgLmACIB2AAAAAMHBAKDAAD////YAAACUgO1ACIB2AAAAQcG7QG3ANQACLEBAbDUsDMr////2AAAAlIDoQAiAdgAAAEHBxYBtwAqAAixAQGwKrAzK///AFv/PAJSAuYAIgHYAAAAAwb/AoMAAP//AEoAAADMAvUAIgHfAAAAAwcpAbcAAAABAFsAAAC7AhIAAwATQBAAAABFSwABAUMBTBEQAgoWKxMzESNbYGACEv3u//8AQAAAAUIC4QAiAd8AAAADBucBtwAA//8AAgAAARQC4QAiAd8AAAADBzcBtwAA////8QAAASUC4QAiAd8AAAADBzYBtwAA////ngAAAQsC4QAiAd8AAAADBvsBtwAA//8AEgAAAQQC1gAiAd8AAAADBzUBtwAA/////wAAASkDXgAiAd8AAAAjBysBtwAAAQcHLgG3AI4ACLEDAbCOsDMr//8AUAAAAMYC5wAiAd8AAAADBuMBtwAA//8ASv88AMwC9QAiAd8AAAAjBykBtwAAAAMG/wG3AAD////UAAAA1gLhACIB3wAAAAMG5QG3AAD//wAvAAAA8AMlACIB3wAAAAMG+gG3AAD//wACAAABFALnACIB3wAAAAMHOgG3AAD//wBK/zgB6AL1ACIB3wAAACMHKQG3AAAAIwHwARcAAAADBykC0wAA//8ABgAAARACvgAiAd8AAAADBzkBtwAA//8APP8gAN8C9QAiAd8AAAAjBykBtwAAAAMHKgHmAAD////8AAABGgLhACIB3wAAAAMHOAG3AAD///+k/zgA0QL1ACIB8AAAAAMHKQG8AAAAAf+k/zgAwAISAA4AKUAmAwEAAQIBAgACSgABAUVLAAAAAmADAQICTQJMAAAADgANEyQEChYrBiYnNxYzMjY1ETMRFAYjDDwUHx4wJilgWFHIEBBKGS8uAiz91lJe////pP84ASoC4QAiAfAAAAADBzYBvAAAAAEAWwAAAmYC5gALACNAIAkGAQMAAgFKAAEBREsAAgJFSwMBAABDAEwSEhESBAoYKyUHFSMRMxEBMwcTIwEpbmBgASF03/V292aRAub+JAEI2/7J////2AAAAmYDtQAiAfIAAAEHBu0BtwDUAAixAQGw1LAzK///AFv++QJmAuYAIgHyAAAAAwcBAmUAAAABAFsAAAJm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yNQBDP70/////wAAAmgDBwAiAt8AAAEHBucCXwAmAAixAgGwJrAzK/////8AAAJoAwcAIgLfAAABBwbvAl8AJgAIsQIBsCawMyv/////AAACaANxACIC3wAAACcHMQJfACYBBwcuAl8AoQAQsQIBsCawMyuxAwGwobAzK///////PAJoAwcAIgLfAAAAIwb/Al8AAAEHBu8CXwAmAAixAwGwJrAzK/////8AAAJoA3EAIgLfAAAAJwcxAl8AJgEHBy0CXwChABCxAgGwJrAzK7EDAbChsDMr/////wAAAmgDfQAiAt8AAAAnBzECXwAmAQcHNAJfAI4AELECAbAmsDMrsQMBsI6wMyv/////AAACaANwACIC3wAAACcHMQJfACYBBwcyAl8AoQAQsQIBsCawMyuxAwGwobAzK/////8AAAJoAwcAIgLfAAABBwbtAl8AJgAIsQIBsCawMyv/////AAACaAMHACIC3wAAAQcG7AJfACYACLECAbAmsDMr/////wAAAnkDTgAiAt8AAAAnBy8CXwAmAQcHLgMHAH4AELECAbAmsDMrsQMBsH6wMyv//////zwCaAMHACIC3wAAACMG/wJfAAABBwbsAl8AJgAIsQMBsCawMyv/////AAACaANOACIC3wAAACcHLwJfACYBBwctAwcAfgAQsQIBsCawMyuxAwGwfrAzK/////8AAAJoA2MAIgLfAAAAJwcvAl8AJgEHBzQC4QB0ABCxAgGwJrAzK7EDAbB0sDMr/////wAAAmgDdgAiAt8AAAAnBy8CXwAmAQcHMgJfAKcAELECAbAmsDMrsQMBsKewMyv/////AAACaAMHACIC3wAAAQcG+wJfACYACLECArAmsDMr/////wAAAmgC/QAiAt8AAAEHBt8CXwAmAAixAgKwJrAzK///////PAJoAjgAIgLfAAAAAwb/Al8AAP////8AAAJoAwcAIgLfAAABBwblAl8AJgAIsQIBsCawMyv/////AAACaANLACIC3wAAAQcG+gJfACYACLECAbAmsDMr/////wAAAmgDDQAiAt8AAAEHBvwCXwAmAAixAgGwJrAzK/////8AAAJoAuQAIgLfAAABBwb2Al8AJgAIsQIBsCawMyv//////yACfgI4ACIC3wAAAAMHAwOTAAD/////AAACaANSACIC3wAAAQcG8AJf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VAD////w/zgCNgISAAICbwYA////8P84AjYC4QAiAm8GAAADB1gB8AAAAAMAK/8+AvoC5gARABgAHgA3QDQeAQAGAUoABAMEgwgBBwcDXwUBAwMiSwAGBgBfAgEAACFLAAEBJAFMFhEUEREUERERCQcdKyQGBxUjNSYmNTQ2NzUzFRYWFQQWFxEGBhUENTQmJxEC+qSVXpWjopZelaT9kG1sbWwCEW5sj44Iu7sIjXx7igjPzwiLelVgBwF0B15TrKxUXQf+iwD//wAJAAACFQISAAICbvsAAAEAKgAAAgQCEgARAC9ALBABAwIDAQEDAkoAAwABAAMBZwUEAgICIksAAAAhAEwAAAARABEjEyIRBgcYKwERIzUGIyImNTUzFRQWMzI3NQIEYFZVY2xgRT5GUQIS/e7WKFxcrKY3OCPyAAABAF3/gQKTAhIACwApQCYAAAMAUgQBAgIiSwYFAgMDAV4AAQEhAUwAAAALAAsREREREQcHGSslFSM1IREzESERMxECk1v+JWABImBU038CEv5CAb7+QgAAAQBdAAADUAISAAsAJUAiBgUDAwEBIksEAQICAF4AAAAhAEwAAAALAAsREREREQcHGSsBESERMxEzETMRMxEDUP0NYOpg6QIS/e4CEv5CAb7+QgG+AP//AF3/jwOfAhIAIgUmAAAAAwdaArIAAAABAF3/gQIoAhIACwBGS7AKUFhAGAABAAABbwUBAwMiSwAEBABeAgEAACEATBtAFwABAAGEBQEDAyJLAAQEAF4CAQAAIQBMWUAJEREREREQBgcaKyEjFSM1IxEzESERMwIot1u5YAELYH9/AhL+QgG+AAACAF3//gIhAhIACgATADBALQUBAgADBAIDZQABASJLBgEEBABeAAAAIQBMCwsAAAsTCxIRDwAKAAkRJAcHFisAFhUUBicnETMVFxI2NTQmJycVFwG3anNr5mCVKkNBQ35+AV1aUlZdAQECErMB/uk2NTQwAQLQAQACAAQAAAJhAhIADAAVADZAMwYBAwAEBQMEZQABAQJdAAICIksHAQUFAF0AAAAhAEwNDQAADRUNFBMRAAwACxERJAgHFysAFhUUBiMjESM1IRUzEjY1NCYjIxUzAfhpc2nfogECkCpAPz98fAFfW1JVXQG+VLP+6jY1MzHPAAADAF3//gLJAhIACgAOABcANkAz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hAMBAgIBXQABASEBTAAAAAUABRERBAcWKzcVIzUjNfpccVfwmVcAAQA6/2cA2wBXAAUAH0AcAAABAIQDAQICAV0AAQEhAUwAAAAFAAUREQQHFis3FSM1IzXbXURX8JlXAAEAQP+PANoAUgAFADxLsApQWEASAAABAQBvAwECAgFdAAEBIQFMG0ARAAABAIQDAQICAV0AAQEhAUxZQAsAAAAFAAUREQQHFis3FSM1IzXaV0NSw3FSAP///jICWf92A0sAIgcxAAABBgcuAHsACLEBAbB7sDMr///+MgJZ/3YDSwAiBzEAAAEGBy0AewAIsQEBsHuwMyv///4yAln/dgNXACIHMQAAAQYHNABoAAixAQGwaLAzK////i8CWf95A0oAIgcxAAABBgcyAHsACLEBAbB7sDMr///+IQJfABoDKAAiBy8AAAEHBy4AqABYAAixAQGwWLAzK////iECX//BAygAIgcvAAABBwctAKgAWAAIsQEBsFiwMyv///4hAl//pAM9ACIHLwAAAQcHNACCAE4ACLEBAbBOsDMr///+IQJf/4cDUAAiBy8AAAEHBzIAAACBAAixAQGwgbAzK////jIC7/92A+EAJwcxAAAAlgEHBy4AAAERABGxAAGwlrAzK7EBAbgBEbAzKwD///4yAu//dgPhACcHMQAAAJYBBwctAAABEQARsQABsJawMyuxAQG4ARGwMysA///+MgLv/3YD7QAnBzEAAACWAQcHNAAAAP4AELEAAbCWsDMrsQEBsP6wMyv///4vAu//eQPgACcHMQAAAJYBBwcyAAABEQARsQABsJawMyuxAQG4ARGwMysA///+IQL1ABoDvgAnBy8AAACWAQcHLgCoAO4AELEAAbCWsDMrsQEBsO6wMyv///4hAvX/wQO+ACcHLwAAAJYBBwctAKgA7gAQsQABsJawMyuxAQGw7rAzK////iEC9f+kA9MAJwcvAAAAlgEHBzQAggDkABCxAAGwlrAzK7EBAbDksDMr///+IQL1/4cD5gAnBy8AAACWAQcHMgAAARcAEbEAAbCWsDMrsQEBuAEXsDMrAAABAF//ZwC8ABcAAwAYQBUAAQAAAVUAAQEAXQAAAQBNERACBxYrFyM1M7xdXZmwAAABAF7/jwC5ABUAAwAYQBUAAQAAAVUAAQEAXQAAAQBNERACBxYrFyM1M7lb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UXdRg1GUUaVRtlHHUdhR6VICUhtSgFKLUp9SsFLJUuJS+1NDU3xTuVQOVFFUYlRzVH9UkFScVK1UuVUPVSBVOVVBVVJVa1V3VYhVlFWlVbFVxlZEVmNWdFaFVpFWnVauVrpWxlb0VwVXFlcnVzhXSVdaV2ZXd1eIV5lXslfHV+BX+VgSWCNYNFhFWF5YrFi9WM5Y51kLWTxZTVleWW9ZgFmtWdBZ4VnyWgNaFFogWjFaQlpTWmRaklqjWrRaxVrRWw1bHlsvW0hbXVt2W49bqFu5W8pb41v4XBFcKlxDXFRcZVxxXIJck1ykXLVcwVzSXONc9F1ZXWpdf13WXedd+F4JXh5eL15IXl1edl6PXqheuV7KXtte5174XwlfGl8rX0RfXV/pX/pgSGCBYOJg82EEYRVhJmE3YUhhXGGGYY5hn2HtYf5iD2IgYjFiSmJWYmdieGKJYsVi1mLiYvNjKGM5Y0VjpmOyY/dkCGQZZCVkNmRCZKJkrmS6ZMtlFmVAZVFlYmVuZXpli2WXZaNl7WX+Zg9mIGYxZkJmU2ZfZnBmgWaSZqtmwGbZZvJnC2ccZy1nPmdXZ2NndGeFZ55n5mf3aAhoGWgqaHVohmiXaKhouWjKaNto7Gj9aQ5pSWlaaWtpfGmIad9qH2onamJqr2rNatlq+ms7a0NrT2tba5tr+WwfbCtsN2yNbLtsx20hbVVtXW1lbYltkW2Zbblt8m3+blBugG62buJvDm8ab0Fvem+4b8Rv0HAxcDlwSXCYcK5wunDCcQBxc3G1ciRybXK4csxzGXNJc5hzpHOwc7xz+nQ3dGt0d3SDdNZ04nWZdaV1sXW5dc112XYNdhl2XXaTdp93B3cTdxt3J3dud6x34XggeF54anh2eH54injheO14+XkFeVF5XXlpeXV5iXmhea15uXnFedF53Xnoefh6RnqQesh7I3txe3l7qnvzfEF8f3yLfMJ85n05fWN9b317fYd9j33Ufdx96H30ffx+CH6nfrN+6380fzx/RH9Qf5p/5IA1gKOBM4GugbaCDoIagiaCMoI6gkaCUoJegmqCdoKCgo6CloLvgveDXYOng8SD1oQHhEeET4RbhGeEo4T+hSSFMIU8hZKFvYXJhhiGS4ZxhnmGnYalhq2GzYbVhuGHMIc4h22HmYfEh9CICYhFiISIyYjViTKJOolKiZaJoomuibqKAYqKisiLJouKi9uL44wxjF+MrYy5jRaNIo1djZ6Nz43bjeeN845FjtOO347rjw6PIo8uj2KPbo+vj7eP95BZkGWQbZB5kL6ROJF6ka2R6pImkjKSPpJGklKSpJKwkrySyJMRkx2TKZM1k4eTk5Ofk6uTt5PDk8+T2pPmlDWUepSylQqVXJVklZWV35ZXlpmWpZcDl1qXYpell/6YBpgSmB6YT5hymHqYgpiKmL+Yy5ktmTmZgZnPmkaabpp6moaamJrymv6bBpsSmyabLps2mz6bSptWm16bapvom/ScRJxMnFScYJyonPadXp3GnkCemJ6knrCeuJ7EnxOfH58rnzefQ59Pn1ufZ5+/n+agMqB0oLCgwaDJoQqhKaFpobKh5aItoo+izaM4o5mj36P9pD2kiKS+pQelD6VSpVqlaKV3pYallaWkpbOlwqXRpeCl76X+pkCmaKaopvCnI6drp82oC6h2qNipHqlFqYWpzqoDqkyqVKqXqp+rA6sRqx+rLas7q0mrV6tlq3OrgauPq8mr76wtrHOso6zlrTytd63Xri+uPq5krqKu6K73rzqvSa+Fr5Svo6+yr8Gv0K/fr+6v/bAMsBuwKrA5sFGwYbBxsIGwkbChsLGwwbDRsOGxFrExsVaxe7GNsbqxyrH5siiylLK2swuzZLNws4ezmbOws8yz57QMtBm0PrRVtHq0vrUFtSW1SLVrtZG1nrWrtbi1xbXStd+1+LYRtiq2MrZLtlO2W7ZotnW2graOtpq2ubbbtue287b/tya3Ubd+t5O3qLe1t8K38bgiuC64OrhZuHu4nbjxuUi5VLlguWy5eLmfucq597oNuiq6Oro6ujq6Oro6ujq6OrqWuuG7c7vfvFG8371Jvbq98r5UvsO+/79Xv6C/28BIwFjA5cErwXzBwsHswizCuML4wwDDRcNNw3XDjsOrw/XEJ8SBxJfErsTYxQTFOsW+xjLGUMayxybHacdxx3nHnMfVyATIDMhvyR7J/sodyjXKW8p0ypPKq8rUyuzLHss8y1vLfsuly8vL3sv6zBTMKsxUzGbMdsyOzJ7MxMzczQLNGs3KzjjOY87iz2TP6tAx0HnQj9Cx0QbRK9Fi0cvSU9J60pHSsdK+03fT5dQk1DXURtRX1IHUktSs1L3U1tTn1PjVHtU11VrVf9WP1cHWA9ZI1rzWzdbe1u/XDdce1y/XQNd115vXydf22CLYS9iJ2LnY+dkx2WHZftmc2brZzNnm2iHaONpP2mbajNqj2rna0Nrl2vzbE9s121bbd9uO27zcLNxD3FrccdyL3KLcudzQ3QHdI91N3Wfded2P3andzN4L3lPehN6k3sTe5t8I3zLfld+53+rgMuBU4Hzg8uEJ4S/hU+Ft4Yrhl+Gj4cDh2eH24ibiVOJu4oripuKv4rjiweLK4tPi3OLl4u7i9+MA4wnjEuMb4zTjTeNk45LjwOPs5AnkJuRS5GLkcuSC5JLko+S05MXk1uTt5QTlGuUx5UflXeVz5YrlouW6AAAAAQAAAAczM3QVnhxfDzz1AAcD6AAAAADWC/5GAAAAANYeQAX8uP75Bk0EHQAAAAcAAgAAAAAAAAJLACgAAAAAAQ0AAAENAAAC3P//Atz//wLc//8C3P//Atz//wLc//8C3P//Atz//wLc//8C3P//Atz//wLc//8C3P//Atz//wLc//8C3P//Atz//wLc//8C3P//Atz//wLc//8C3P//Atz//wLc//8C3P//Atz//wQX//8EF///AvUAaQLTADAC0wAwAtMAMALTADAC0wAwAtMAMALTADADOgBpBa4AaQNCAAsDOgBpA0IACwM6AGkDOgBpBUMAaQKeAGkCngBpAp4AaQKeAGkCngBpAp4AaQKeAGkCngBpAp4AaQKeAGkCngBpAp4AaQKeAGkCngBpAp4AaQKeAGkCngBpAp4AaQKeAGkCngBpAp4AaQKeAGkCngBpAm8AHwJvAB8CewBpAwQAMAMEADADBAAwAwQAMAMEADADBAAwAwQAMAMnADADLABpAzwACQMsAGkDLABpAywAaQMsAGkBNgBpAtAAVwE2AFABNv/5ATb/6AE2/64BNgALATYADwE2AGABNgBoATb/5AE2AD8BNv/5ATYAFgE2AE4BNv/zAgH/9wIB//cCzwBpAs8AaQLPAGkCUgBpBFMAaQJSAFACUgBpAlIAaQJSAGkCUgBpA24AaQJSAGkCWgAJA7sAaQO7AGkDLABpBS0AaQMsAGkDLABpAywAaQMsAGkDLABpAywAaQRIAGkDLABpAywAaQNIADADSAAwA0gAMANIADADSAAwA0gAMANIADADSAAwA0gAMANIADADSAAwA0gAMANIADADSAAwA0gAMANIADADSAAwA0gAMANIADADSAAwA0gAMANIADADSAAwA0gAMANIADADSAAwA0gAMANIADADSAAwA0gAMANIADADSAAwA0gAMANIADAEZgAwAtIAaQLSAGkDSAAwAtcAaQLXAGkC1wBpAtcAaQLXAGkC1wBpAtcAaQLXAGkCbQApAm0AKQJtACkBAgBQAm0AKQJtACkCbQApAm0AKQJtACkCbQApAm0AKQJtACkC+wBjAzEAMAJLAAQCSwAEAksABAJLAAQCSwAEAksABAJLAAQDFwBjAxcAYwMXAGMDFwBjAxcAYwMXAGMDFwBjAxcAYwMXAGMDFwBjAx8AYwMfAGMDHwBjAx8AYwMfAGMDHwBjAxcAYwMXAGMDFwBjAxcAYwMXAGMDFwBjAxcAYwMXAGMCyP//BGYAIARmACAEZgAgBGYAIARmACACoQANAof//AKH//wCh//8Aof//AKH//wCh//8Aof//AKH//wCh//8Aof//AKRACsCkQArApEAKwKRACsCkQArAtAAVwMgAGMDIABjAyAAYwMgAGMDIABjAyAAYwMgAGMDIABjAyAAYwMgAGMDIABjAyAAYwMgAGMDIABjAyAAYwMgAGMDIABjAyAAYwMgAGMDIABjAyAAYwMgAGMDIABjAyAAYwMgAGMDIABjBDIAWgQyAFoFrgBpBU0AaQKEADMChAAzAoQAMwKEADMChAAzAoQAMwKEADMChAAzAoQAMwKEADMChAAzAoQAMwKEADMChAAzAoQAMwKEADMChAAzAoQAMwKEADMChAAzAoQAMwKEADMChAAzAl4AYwMEADADBAAwAwQAMAMEADADBAAwAwQAMAMEADADLAAwAcgAKwLQAFcByAArAtAAVwHIACsByAArAcj/+AHIACsByAArAcgAKwHIACsByAArAcgAKwHIACsByAArAcgAKwHIACsB///3Af//9wRvAGkEywBpBMsAaQMeAGkFHQBpAx4AaQMeAGkDHgBpAx4AaQMeAGkDHgBpBDoAaQMeAGkDHgBpA0gAMAMxAEUCVv/8Alb//AJW//wCVv/8Alb//AJW//wCVv/8AxoAYwMaAGMDGgBjAxoAYwMaAGMDGgBjAxoAYwMaAGMDGgBjAxoAYwMaAGMDGgBjAxoAYwMaAGMDGgBjAxoAYwMaAGMDGgBjAxoAYwMaAGMDGgBjAxoAYwMaAGMDGgBjBKYAYwSmAGMEpgBjBKYAYwSmAGMDEwBeAxMAXgMTAF4DEwBeAxMAXgMTAF4DEwBeAxMAXgMTAF4DEwBeApsAMAKbADACmwAwApsAMAKbADACVgAyAlYAMgJWADICVgAyAlYAMgJWADICVgAyAlYAMgJWADICVgAyAlYAMgJWADICVgAyAlYAMgJWADICVgAyAlYAMgJWADICVgAyAlYAMgJWADICVgAyAlYAMgJWADICVgAyAlYAMgPdADID3QAyAqoAWwI7ACoCOwAqAjsAKgI7ACoCOwAqAjsAKgI7ACoCqgAqAoAAKgKqACoCqgAqAqoAKgKqACoEuwAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAg//7AIP/+wBYQAPArIAKgKyACoCsgAqArIAKgKyACoCsgAqArIAKgK6ACoCqQBbAqkAAAKpAFsCqf/YAqn/2AKpAFsBFwBKARcAWwEXAEABFwACARf/8QEX/54BFwASARf//wEXAFABFwBKARf/1AEXAC8BFwACAjMASgEXAAYBFwA8ARf//AEc/6QBHP+kARz/pAJoAFsCaP/YAmgAWwJeAFsBFwBbARcAQAEXAFsBFwBYAVoAWwEXAFgCMwBbARf/6AEn//kEIQBbBCEAWwKpAFsCqQBbAwIANQKpAFsCqQBbAqkAWwKpAFsCqQBbA8UAWwKpAFsCqQBbAnsAKgJ7ACoCewAqAnsAKgJ7ACoCewAqAnsAKgJ7ACoCewAqAnsAKgJ7ACoCewAqAnsAKgJ7ACoCewAqAnsAKgJ7ACoCewAqAnsAKgJ7ACoCewAqAn8AKgJ7ACoCewAqAnsAKgJ7ACoCewAqAnsAKgJ7ACoCewAqAnsAKgJ7ACoCewAqAnsAKgQrACoCqgBbAqoAWwKqACoBmgBbAZoAWwGaADcBmgBYAZr//QGaAFgBmgBIAZr/6AH1ABgB9QAYAfUAGAD/AFAB9QAYAfUAGAH1ABgB9QAYAfUAGAH1ABgB9QAYAfUAGAKkAFsBMgAZAZ4ADwGoABQBngAPAZ4ADwGeAA8BngAJAZ4ADwGeAA8CpQBWAqUAVgKlAFYCpQBWAqUAVgKlAFYCpQBWAqUAVgKlAFYCpQBWAq0AVgKtAFYCrQBWAq0AVgKtAFYCrQBWAqUAVgKlAFYCpQBWAqUAVgKlAFYCpQBWAqUAVgKlAFYCL//+A4MABgODAAYDgwAGA4MABgODAAYCKAAOAi//6gIv/+oCL//qAi//6gIv/+oCL//qAi//6gIv/+oCL//qAi//6gIJACgCCQAoAgkAKAIJACgCCQAoAjIASAKqACoCqgAqAqoAKgKqACoCqgAqAqoAKgKqACoCqgAqAqoAKgKqACoCqgAqAqoAKgKqACoCqgAqAqoAKgKqACoCqgAqAqoAKgKqACoCqgAqAqoAKgKqACoCqgAqAqoAKgKqACoCqgAqA90AMgPdADIEvQAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAArAVMAWwFBAFsBQQBAAUEAWwFBAFsBbQBbAUEAWwI1AFsBQQApAUH/8QQ6ACoBiwBWAZUADAGLAFYBiwBWAYsAVgGL//YBiwBWAYsASAPZAFYD2QBWA9kAVgPZAFYD2QBWAqUAVAKlAFQCpQBUAqUAVAKlAFQCpQBUAqUAVAKlAFQCpQBUAhMALQITAC0CEwAtAhMALQITAC0EsQAEAsgADwJ4AA8CugBbAosADwJn//8CZ///Amf//wJn//8CZ///Amf//wJn//8CZ///Amf//wJn//8CZ///Amf//wJn//8CZ///Amf//wJn//8CZ///Amf//wJn//8CZ///Amf//wJn//8CZ///Amf//wJn//8CZ///A2z//wNs//8ChABhAmEALAJhACwCYQAsAmEALAJhACwCYQAsAmEALAK+AGEC0gAgAr4AYQLSACACvgBhAr4AYQTOAGECOgBhAjoAYQI6AGECOgBhAjoAYQI6AGECOgBhAjoAYQI6AGECOgBhAjoAYQI6AEMCOgBhAjoAYQI6AGECOgBhAjoAYQI6AGECOgBhAjoAYQI6AGECOgBhAjoAYQKcACwCMAAlAjAAJQIgAGECjgAsAo4ALAKOACwCjgAsAo4ALAKOACwCjgAsAq8ALAK7AGEC4wAiArsAYQK7AGECuwBhArsAYQEiAGEBIgBhASIARgJQAEEBIgAIASL/9wEi/6QBIgAYASIABQEiAFYBIgBeASL/2gEiADUBIgAIAm8ATAEiAAwBIgBDASIAAgHB//wBwf/8AmwAYQJsAGECbABhAmwAYQH7AGEB+wBHAfsAYQH7AGEB+wBhAfsAYQO8AGEB+wBhAfv/+AMyAGEDMgBhArsAYQK7AGECuwBhArsAYQK7AGECuwBhArsAYQR8AGECuwBhArsAYQLCACwCwgAsAsIALALCACwCwgAsAsIALALCACwCwgAsAsIALALCACwCwgAsAsIALALCACwCwgAsAsIALALCACwCwgAsAsIALALCACwCwgAsAsIALALCACwCwgAsAsIALALCACwCwgAsAsIALALCACwCwgAsAsIALALCACwCwgAsAsIALALCACwDqwAsAm8AYQJvAGECwgAsAnYAYQJ2AGECdgBhAnYAYQJ2AFQCdgBhAnYAYQJ2AGECEwAlAhMAJQITACUA/wBQAhMAJQITACUCEwAlAhMAJQITACUCEwAlAhMAJQITACUCigBbAe0ABAHtAAQB7QAEAe0ABAHtAAQB7QAEAe0ABAHtAAQCqABbAqgAWwKoAFsCqABbAqgAWwKoAFsCqABbAqgAWwKoAFsCqABbArAAWwKwAFsCsABbArAAWwKwAFsCsABbAqgAWwKoAFsCqABbAqgAWwKoAFsCqABbAqgAWwKoAFsCaQAIA70AIgO9ACIDvQAiA70AIgO9ACICPAAMAjkAAgI5AAICOQACAjkAAgI5AAICOQACAjkAAgI5AAICOQACAjkAAgIrACkCKwApAisAKQIrACkCKwApAq8AWwKvAFsCrwBbAq8AWwKvAFsCrwBbAq8AWwKvAFsCrwBbAq8AWwKvAFsCrwBbAq8AWwKvAFsCrwBbAq8AWwKvAFsCrwBbAq8AWwKvAFsCrwBbAq8AWwKvAFsCrwBbAq8AWwKvAFsDmQBVA5kAVQToAGECJwAqAicAKgInACoCJwAqAicAKgInACoCJwAqAicAKgInACoCJwAqAicAKgInACoCJwAqAicAKgInACoCJwAqAicAKgInACoCJwAqAicAKgInACoCJwAqAicAKgKcADkCCABbAo4ALAKOACwCjgAsAo4ALAKOACwCjgAsAo4ALAK0ACwBqgA5AaoAOQGqADkCbwBBAaoAOQGqADkBqv/pAaoAOQGqADkBqgA5AaoAHwGqADkBqgA5Am8ATAGqADkBqgA5AaoAOQHB//wBwf/8A7wAYQQAAGEEAABhAq4AYQKuAGECrgBhAq4AYQKuAGECrgBhAq4AYQRvAGECrgBhAq4AYQLCACwB9//8Aff//AH3//wB9//8Aff//AH3//wB9//8Aff//AKuAFsCrgBbAq4AWwKuAFsCrgBbAq4AWwKuAFsCrgBbAq4AWwKuAFsCtgBbArYAWwK2AFsCtgBbArYAWwK2AFsCrgBbAq4AWwKuAFsCrgBbAq4AWwKuAFsCrgBbAq4AWwP/AFsD/wBbA/8AWwP/AFsD/wBbAqMAVgKjAFYCowBWAqMAVgKjAFYCowBWAqMAVgKjAFYCowBWAqMAVgIrACkCKwApAisAKQIrACkCKwApAZQAJQGiACAC9gAMAtsAbQLrAG0CQgBtAkIAbQJFAG0DJAANApkAbQKZAG0CmQBtBAUAEwKCACADNwBtAzcAbQM3AG0DUwBtAscAbQLHAG0DFgANA8MAbQM0AG0DUAAzAzUAbQLKAG0CzgA0AlsADQKzABACswAQA54ALQKcABEC4AA2Az0AbQRHAG0EYABtAycAbQLJAG0DPAANA+EAbQSjAA0EnABtAnwAMQLEADUCwwAdAT0AbQE2AAsCHAASA0oADQRLAG0C2wA6A0EADgMrABMDhAASA1AAMwL5AA4CagAeAr8AbQQsABMCggAgAvMAbQLkAG0C3QAjAzsADQNPAG0EPwBtBKwAbQNQAG0DzgA5As4ANAJbAA0CmwAGAof//ALBABEDzgAOAvsANgLgADUC4ABtAyUAbQPdACAD3QAgAT4AbQQFABMCygBtAy8AbQNQAG0C3AAzA+gAbQL2AAwC9gAMBBYABwKZAG0DNwApAzcAKQQFABMCggAgAm8AHwM3AG0DNwBtA1AAMwNQADMDUAAzAsMAHQKzABACswAQArMAEALgADYCQgBtA+EAbQJrAB0CoAAOAqwAGgKCADkDFwAMA1YAMwQ9ABUC4wAfAt0AbQMw/7QDMQANAxkADgLlAA0DnQAxAk8AbQKCACACzgA0As4ANAMgAGMDRAAeAoQAMwKEADMChAAzAxoAYwMaAGMDGgBjAxoAYwMWACACzQBcAncADQMTAF4DEwBeA58AMgLMAF8DaAAOA+EAXwSfAAwEjABtAf//9wM7ABMCdwANAyAAYwMgAGMEMgBaAoQAMwMaAGMDGgBjAxMAXgMTAF4DEwBeA+EAXwNIADAC7wAaAk0AMAKWAD4CZgBdAegAXQHoAF0B0gBdApgACAJ0ACwCdAAsAnQALANRAA0CIAAcArYAXQK2AF0CtgBdAswAXQJWAF0CVgBdAoEABQMeAF0CqQBdAoEALAKlAF0CsABdAjsALAHtAAQCO//wAjv/8AMlACsCHQAJAmEAKgKyAF0DrQBdA60AXQKGAF0CPwBdAn8ABAMnAF0DpgAFA7gAXQIYACsCQQAsAj8AGAEbAEwBFwASARz/ogKi/9wDbABdAmQAMAKj//YCZQAAAsAADwKKACwCVAAFAgQAKwJZAF0DcgANAiAAHAJWAF0CZgBbAlUAAAKeAAQCvgBdA3YAXQKlAF0D0ABdAyYALwI7ACwB7QAEAj4ABgI+AAYCHQAJAwMABQJ6ACoCYQApAqIAXQK8AF0DAwAVAwMAFQEbAF0DUQANAlYAXQKXAAUCrwBdAr8AXQJeACcDPQBdAk0AMAJNADAD4wAwAnQALAJzADgCcwA4A1EADQIgABwCD//sArYAXQK2AF0CgQAsAooALAKKACwCPwAYAjv/8AI7//ACO//wAmEAKgHoAF0DJwBdAewADQIdAAsCOQAWAiAANQKBAAUCsAAuA6oACQJeABYCuwBeAqn/pQKWAAUCfgBMAiEALgKzACkDUQANAe7/9wKeAE0CngBNAp4ATQJVAF4CPAAFAqkAXQKiAF0EGwBdAmMALAK3AE0EGwBOBDQATgJAAFACnAAFA1cAXgH0AF0CIAAcAjsALAHoAF0CbgAnARcABgKzACcCpQBWBBsATgKqACoCswApAmQAKgJkACoCZAAqAp4ATQKeAE0CngBNAp4ATQKWAEYEGwBdAqUAVAKlAFQCSQBQAqUABQMoAFADrQAIA7IAXQJ6//wCqgAqAqoAKgPdADICZAAqAmQAKwJkACsCngBNAp4ATQKlAFQCpQBUAqUAVAMoAFACawARAtz//wOCAAkCqgBbAtT/+ALc//8CzwBpApsAMAFyAAgCPgAOAjwABQKdACYCPgARAmkAMAJWAB4ChAAsAmkAHAKsADIBcgAIAj4ABgI8AAYCnQAmAj4AEQJpADACVgAeAoQALAJpABwBrgAcAa4AUQGuABwBrgAbAa4AFgGuABsBrgAlAa4AJAGuABwBrgAgArwAPQK8AJACvAA8ArwAPgK8ADUCvABBArwASgK8AEkCvAA7ArwAQQK8ADwCvACQArwARwK8AD4CvAA1ArwAQQK8AEoCvABJArwAOwK8AEEBrgAcAa4AUQGuABwBrgAbAa4AFgGuABsBrgAlAa4AJAGuABwBrgAgAa4AHAGuAFEBrgAcAa4AGwGuABYBrgAbAa4AJQGuACQBrgAcAa4AIAGuABwBrgBRAa4AHAGuABsBrgAWAa4AGwGuACUBrgAkAa4AHAGuACABrgAcAa4AUQGuABwBrgAbAa4AFgGuABsBrgAlAa4AJAGuABwBrgAgAK7/QgQKAFEECgBRBAoAHAQKAFEECgAbBAoAUQQKABsECgAbBAoAJAGQABMBYP/aAQsAQgE6AEIA4wAuAOMAMAKzAC4BDABFAQwARQK/ABsA4wAuAj0ACQI9AEUBhwA/ANIAPwDjAC4BYP/kAfQAAAFg/9oBHwBMAU4ATAFYAH4BYP/kAIEALQFfADkBXwATAU0AaQFNABMBUQBfAVIAIAFzAEMBcwAdAWEAcwFhAB0BZQBpAWYAKgPoAAAB9AAAArwALwPoAAABfwA5AX8AOQF/ADkD6AAAAfQAAAGTAEMB+AAuAfgAIgE4AC4BOAAiAaAAMAGgAC4BoAAwAOMALgDjADAA4wAwAgwAOAIMACwBTAA4AUwALAEMAEUBDABFAdwALgHdACIBIgAuASMAIgDnADMCCgAIAgkARQGHAD8BnwAwAZ8ALgGfADAA4gAuAOIAMADjADAA0gA/AUkAJAFJACsCvAAAAGQAAADjAAABDQAAAIYAAAAAAAAC0wAwAjsAKgLTADACvAAfAm0AKQKqACoDJwAeAcH/pAKXAB4DBAAwAzgAVwKUAB4ChgAeAsgAHgOUAGkDcAAeBmoAaQNLAB4C7gAeAtAAHQKGAB4C0QBMAqoAMwSqAB4Cw//8AR8ATAIaAEwBYP/kAkYAQwJGAEMCRgBrAkYAQwJGAEMCRgBDAkYAQwJGAEMCRgBDAkYAQwJGAEMCRgA6AkYAOgJGAEMCRgAlA5sAKgGP/90DggAJAtz//wMsAGkCkQArAyMAQwKqAFsCvABIA0sAJQS6ACUCWABgAlgAeAJYAEMCWAB5AlgAagJYAG4CWABgAlgAbwLZADICWABfAlgAYAJYAEMCWABq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Bz4HPQdEB0MHTAdKB0cHQAdFB0EHRgdJB04HUwdSB1QHUAblBucG7AbyBvYG7wbjBt8G+gbwBuoG7QRuBG8ElwRqBI8EjgSRBJIEkwSMBI0ElAR3BHQEgQSIBGYEZwRoBGkEbARtBHAEcQRyBHMEdgSCBIMEhQSEBIYEhwSKBIsEiQSQBJUElgUGBQcFCAUJBQwFDQUQBREFEgUTBRYFIgUjBSUFJAUmBScFKgUrBSkFMAU1BTYFDgUPBTcFCgUvBS4FMQUyBTMFLAUtBTQFFwUUBSEFKASYBTgEmQU5BJoFOgSbBTsEdQUVBNgFeQTZBXoEawULBJwFPASdBT0EngU+BJ8FPwSgBUAEoQVBBKIFQgSjBUMEpAVEBKUFRQSmBUcEqAVIBKkFSQSqBUoEqwVLBKwFTAStBU0ErgVOBK8FTwSwBVAEsQVRBLMFUwS0BVQEtQS2BVYEtwVXBVgEuAVZBLkFWgS6BVsEuwVcBVUEvAVdBL0FXgS+BV8EvwVgBMAFYQTBBWIEwgVjBMMFZATEBWUExQVmBMYFZwTHBWgEyAVpBMkFagTKBWsEywVsBMwFbQTNBW4EzgVvBM8FcATQBXEE0QVyBNIFcwTTBXQE1AV1BNUFdgTWBXcE1wV4BKcFRgSyBVIE2gV7BNsFfAAlAasALQGyAC4BswBEAckAQwHIADQBuQBQAdYAVwHdAFQB2gBfAeUAcwH7AHUB/QB4AgAAfgIGAH8CBwCCAgoAowIrAKQCLACeAiYAnQIlAK8CNwCxAjkAuwJDALwCRAC0AjwAtwI/AL0CRQDFAk4AxgJPAN4CZwDaAmMA5AJtAOECagDjAmwA6gJzAPQCfQAVAZsAFwGdAA4BlAAQAZYAEQGXABIBmAAPAZUABwGNAAkBjwAKAZAACwGRAAgBjgA+AcMAQAHFAEYBywA2AbsAOAG9ADkBvgA6Ab8ANwG8AGMB6QBhAecAkQIZAJMCGwCIAhAAigISAIsCEwCMAhQAiQIRAJUCHQCXAh8AmAIgAJkCIQCWAh4AzgJXANACWQDSAlsA1AJdANUCXgDWAl8A0wJcAOwCdQDrAnQA7QJ2AO8CeAZzBnUGdwZ0BngGSgZJBkgGSwZXBlgGVgbVBtYGJwaBBoUGfgZ/BoQGjwaKBoIGgwZ5Bo4GjAaGBocGiwW/Bb4GtQavBrEGswa3BrgGtgaw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AREBEgETARQAYwEVAK4AkAEWACUAJgD9AP8AZAEXARgBGQAnARoA6QEbARwBHQEeAR8AKABlASABIQEiAMgBIwEkASUBJgEnASgAygEpASoAywErASwBLQEuAS8BMAExATIBMwApACoA+AE0ATUBNgE3ATgBOQArAToBOwE8AT0BPgAsAT8AzAFAAM0BQQDOAUIA+gFDAM8BRAFFAUYBRwFIAC0BSQAuAUoBSwAvAUwBTQFOAU8BUAFRAVIBUwDiADABVAAxAVUBVgFXAVgBWQFaAVsBXAFdAGYAMgDQAV4A0QFfAWABYQFiAWMBZABnAWUBZgFnANMBaAFpAWoBawFsAW0BbgFvAXABcQFyAXMBdACRAXUArwF2AXcBeACwADMA7QA0ADUBeQF6AXsBfAF9AX4BfwA2AYABgQGCAOQBgwD7AYQBhQGGAYcBiAGJAYoANwGLAYwBjQGOAY8BkAA4ANQBkQGSANUBkwBoAZQA1gGVAZYBlwGYAZkBmgGbAZwBnQGeAZ8BoAGhAaIBowA5ADoBpAGlAaYBpwA7ADwA6wGoALsBqQGqAasBrAGtAa4APQGvAOYBsAGxAbIBswG0AbUBtgG3AbgBuQG6AbsBvAG9Ab4BvwHAAcEBwgHDAcQBxQHGAccByAHJAcoBywHMAc0BzgHPAdAB0QHSAdMB1AHVAdYB1wHYAdkB2gHbAdwB3QHeAd8B4AHhAeIB4wHkAeUB5gHnAegB6QHqAesB7AHtAe4B7wHwAfEB8gHzAfQB9QH2AfcB+AH5AfoB+wH8Af0B/gH/AgACAQICAgMCBAIFAgYCBwIIAgkCCgILAgwCDQIOAg8CEAIRAhICEwIUAhUCFgIXAhgCGQIaAhsCHAIdAh4CHwIgAiECIgIjAiQCJQImAicCKAIpAioCKwIsAi0CLgIvAjACMQIyAjMCNAI1AjYCNwI4AjkCOgI7AjwCPQI+Aj8CQAJBAkICQwJEAkUCRgBEAGkCRwJIAkkCSgJLAkwCTQBrAk4CTwJQAlECUgJTAGwCVABqAlUCVgJXAlgAbgJZAG0AoAJaAEUARgD+AQAAbwJbAlwCXQBHAOoCXgEBAl8CYAJhAEgAcAJiAmMCZAByAmUCZgJnAmgCaQJqAHMCawJsAHECbQJuAm8CcAJxAnICcwJ0AnUCdgBJAEoA+QJ3AngCeQJ6AnsCfABLAn0CfgJ/AoACgQBMANcAdAKCAHYCgwB3AoQChQKGAHUChwKIAokCigKLAowATQKNAo4ATgKPApACkQBPApICkwKUApUClgKXApgA4wBQApkAUQKaApsCnAKdAp4CnwKgAqECogB4AFIAeQKjAHsCpAKlAqYCpwKoAqkAfAKqAqsCrAB6Aq0CrgKvArACsQKyArMCtAK1ArYCtwK4ArkAoQK6AH0CuwK8Ar0AsQBTAO4AVABVAr4CvwLAAsECwgLDAsQAVgLFAsYCxwDlAsgA/ALJAsoCywLMAs0AiQLOAFcCzwLQAtEC0gLTAtQC1QBYAH4C1gLXAIAC2ACBAtkAfwLaAtsC3ALdAt4C3wLgAuEC4gLjAuQC5QLmAucC6ABZAFoC6QLqAusC7ABbAFwA7ALtALoC7gLvAvAC8QLyAvMAXQL0AOcC9QL2AvcC+AL5AvoC+wL8Av0C/gL/AwADAQMCAwMDBAMFAwYDBwMIAwkDCgMLAwwDDQMOAw8DEAMRAxIDEwMUAxUDFgMXAxgDGQMaAxsDHAMdAx4DHwMgAyEDIgMjAyQDJQMmAycDKAMpAyoDKwMsAy0DLgMvAzADMQMyAzMDNAM1AzYDNwM4AzkDOgM7AzwDPQM+Az8DQANBA0IDQwNEA0UDRgNHA0gDSQNKA0sDTANNA04DTwNQA1EDUgNTAMAAwQNUA1UDVgNXA1gDWQNaA1sDXANdA14DXwNgA2EDYgNjA2QDZQNmA2cDaANpA2oDawNsA20DbgNvA3ADcQNyA3MDdAN1A3YDdwN4A3kDegN7A3wDfQN+A38DgAOBA4IDgwOEA4UDhgOHA4gDiQOKA4sDjAONA44DjwOQA5EDkgOTA5QDlQOWA5cDmAOZA5oDmwOcA50DngOfA6ADoQOiA6MDpAOlA6YDpwOoA6kDqgOrA6wDrQOuA68DsAOxA7IDswO0A7UDtgO3A7gDuQO6A7sDvAO9A74DvwPAA8EDwgPDA8QDxQPGA8cDyAPJA8oDywPMA80DzgPPA9AD0QPSA9MD1APVA9YD1wPYA9kD2gPbA9wD3QPeA98D4APhA+ID4wPkA+UD5gPnA+gD6QPqA+sD7APtA+4D7wPwA/ED8gPzA/QD9QP2A/cD+AP5A/oD+wP8A/0D/gP/BAAEAQQCBAMEBAQFBAYEBwQIBAkECgQLBAwEDQQOBA8EEAQRBBIEEwQUBBUEFgQXBBgEGQQaBBsEHAQdBB4EHwQgBCEEIgQjBCQEJQQmBCcEKAQpBCoEKwQsBC0ELgQvBDAEMQQyBDMENAQ1BDYENwQ4BDkEOgQ7BDwEPQQ+BD8EQARBBEIEQwREBEUERgRHBEgESQRKBEsETARNBE4ETwRQBFEEUgRTBFQEVQRWBFcEWARZBFoEWwRcBF0EXgRfBGAEYQRiBGMEZARlBGYEZwRoBGkEagRrBGwEbQRuBG8EcARxBHIEcwR0BHUEdgR3BHgEeQR6BHsEfAR9BH4EfwSABIEEggSDBIQEhQSGBIcEiASJBIoEiwSMBI0EjgSPBJAEkQSSBJMElASVBJYElwSYBJkEmgSbBJwEnQSeBJ8EoAShBKIEowSkBKUEpgSnBKgEqQSqBKsErAStBK4ErwSwBLEEsgSzBLQEtQS2BLcEuAS5BLoEuwS8BL0EvgS/BMAEwQTCBMMExATFBMYExwTIBMkEygTLBMwEzQTOBM8E0ATRBNIE0wTUBNUE1gTXBNgE2QTaAJ0AngTbBNwE3QTeBN8E4AThBOIE4wTkBOUE5gTnBOgE6QTqBOsE7ATtBO4E7wTwBPEE8gTzBPQE9QT2BPcE+AT5BPoE+wT8BP0E/gT/BQAFAQUCBQMFBAUFBQYFBwUIBQkFCgULBQwFDQUOBQ8FEAURBRIFEwUUBRUFFgUXBRgFGQUaBRsFHAUdBR4FHwUgBSEFIgUjBSQFJQUmBScFKAUpBSoFKwUsBS0FLgUvBTAFMQUyBTMFNAU1BTYFNwU4BTkFOgU7BTwFPQU+BT8FQAVBBUIFQwVEBUUFRgVHBUgFSQVKBUsFTAVNBU4FTwVQBVEFUgVTBVQFVQVWBVcFWAVZBVoFWwVcBV0FXgVfBWAFYQViBWMFZAVlBWYFZwVoBWkFagVrBWwFbQVuBW8FcAVxBXIFcwV0BXUFdgV3BXgFeQV6BXsFfAV9BX4FfwWABYEFggWDBYQFhQWGBYcFiAWJBYoFiwWMBY0FjgWPBZAFkQWSBZMFlAWVBZYFlwWYBZkFmgWbBZwFnQWeBZ8FoAWhBaIFowWkBaUFpgWnBagFqQWqBasFrAWtBa4FrwWwBbEFsgWzBbQFtQW2BbcFuAW5BboFuwW8Bb0FvgW/BcAFwQXCBcMFxAXFBcYFxwXIBckFygXLBcwFzQXOBc8F0AXRBdIF0wXUBdUF1gXXBdgF2QXaBdsF3AXdBd4F3wXgBeEF4gXjBeQF5QXmBecF6AXpBeoF6wXsBe0F7gXvBfAF8QXyBfMF9AX1BfYF9wX4BfkF+gX7BfwF/QX+Bf8GAAYBBgIGAwYEBgUGBgYHBggGCQYKBgsGDAYNBg4GDwYQBhEGEgYTBhQGFQYWBhcGGAYZBhoGGwYcBh0GHgYfBiAGIQYiBiMGJAYlBiYGJwYoBikGKgYrBiwGLQYuBi8GMAYxAJsGMgYzABMAFAAVABYAFwAYABkAGgAbABwGNAY1BjYGNwY4BjkGOgY7BjwGPQY+Bj8GQAZBBkIGQwZEBkUGRgZHBkgGSQZKBksGTAZNBk4GTwZQBlEGUgZTBlQGVQZWBlcGWAZZBloGWwZcBl0GXgZfBmAGYQZiBmMGZAZlBmYGZwZoBmkGagZrBmwGbQZuBm8GcAZxBnIGcwZ0BnUGdgZ3BngGeQZ6BnsGfAZ9Bn4GfwaABoEGggaDALwA9AaEBoUA9QD2BoYGhwaIBokADQA/AMMAhwAdAA8AqwAEAKMABgARACIAogAFAAoAHgASAEIGigaLBowGjQaOBo8AXgBgAD4AQAALAAwGkAaRBpIGkwaUBpUAswCyBpYGlwAQBpgGmQaaBpsGnACpAKoAvgC/AMUAtAC1ALYAtwDEBp0GngafBqAGoQaiBqMGpAalBqYGpwaoBqkGqgarBqwGrQauBq8GsAaxBrIGswa0BrUGtga3BrgGuQa6AIQGuwC9AAcGvAa9AKYA9wa+Br8GwAbBBsIGwwbEBsUGxgbHBsgAhQbJBsoGywCWBswGzQbOAA4A7wDwALgAIACPACEAHwCVAJQAkwCnAGEApAbPAJIAnAbQBtEAmgCZAKUG0gCYAAgAxgbTBtQG1QbWBtcG2AbZBtoG2wbcBt0G3gbfBuAG4QbiALkG4wbkBuUG5gbnBugG6QbqBusG7AAjAAkAiACGAIsAigCMAIMAXwDoBu0AggDCBu4G7wBBBvAG8QbyBvMG9Ab1BvYG9wb4BvkG+gb7BvwG/Qb+Bv8HAAcBBwIHAwcEBwUHBgcHBwgHCQcKBwsHDAcNBw4HDwcQBxEHEgcTBxQHFQcWBxcHGAcZBxoHGwccBx0HHgcfByAHIQciByMHJAclByYHJwcoBykHKgcrBywHLQcuBy8HMAcxBzIHMwc0BzUHNgc3BzgHOQc6BzsHPAc9Bz4HPwdAB0EHQgdDB0QHRQdGB0cHSAdJB0oHSwdMB00HTgdPB1AHUQdSB1MHVAdVB1YHVwdYB1kHWgdbB1wHXQCNANsA4QDeANgAjgDcAEMA3wDaAOAA3QDZB14HXwdgB2EHYgdjB2QHZQdmB2cHaAdpB2oHawdsB20HbgdvB3AHcQdyB3MHdAd1B3YHdwd4BE5VTEwGQWJyZXZlB3VuaTFFQUUHdW5pMUVCNgd1bmkxRUIwB3VuaTFFQjIHdW5pMUVCNAd1bmkwMUNEB3VuaTFFQTQHdW5pMUVBQwd1bmkxRUE2B3VuaTFFQTgHdW5pMUVBQQd1bmkwMjAwB3VuaTFFQTAHdW5pMUVBMgd1bmkwMjAyB0FtYWNyb24HQW9nb25lawpBcmluZ2FjdXRlB0FFYWN1dGUHdW5pMUUwOAtDY2lyY3VtZmxleApDZG90YWNjZW50B3VuaTAxQzQGRGNhcm9uBkRjcm9hdAd1bmkxRTBDB3VuaTFFMEUHdW5pMDFDNQZFYnJldmUGRWNhcm9uB3VuaTFFMUMHdW5pMUVCRQd1bmkxRUM2B3VuaTFFQzAHdW5pMUVDMgd1bmkxRUM0B3VuaTAyMDQKRWRvdGFjY2VudAd1bmkxRUI4B3VuaTFFQkEHdW5pMDIwNgdFbWFjcm9uB3VuaTFFMTYHdW5pMUUxNAdFb2dvbmVrB3VuaTFFQkMHdW5pMDFCNwd1bmkwMUVFBkdjYXJvbgtHY2lyY3VtZmxleAxHY29tbWFhY2NlbnQKR2RvdGFjY2VudAd1bmkxRTIwB3VuaTAxRTQESGJhcgd1bmkxRTJBB3VuaTAyMUULSGNpcmN1bWZsZXgHdW5pMUUyNAJJSgZJYnJldmUHdW5pMDIwOAd1bmkxRTJFB3VuaTFFQ0EHdW5pMUVDOAd1bmkwMjBBB0ltYWNyb24HSW9nb25lawZJdGlsZGULSmNpcmN1bWZsZXgHdW5pMDFFOAxLY29tbWFhY2NlbnQHdW5pMDFDNwZMYWN1dGUGTGNhcm9uDExjb21tYWFjY2VudARMZG90B3VuaTFFMzYHdW5pMDFDOAd1bmkxRTNBB3VuaTFFNDIHdW5pMDFDQQZOYWN1dGUGTmNhcm9uDE5jb21tYWFjY2VudAd1bmkxRTQ0B3VuaTFFNDYDRW5nB3VuaTAxQ0IHdW5pMUU0OAZPYnJldmUHdW5pMUVEMAd1bmkxRUQ4B3VuaTFFRDIHdW5pMUVENAd1bmkxRUQ2B3VuaTAyMEMHdW5pMDIyQQd1bmkwMjMwB3VuaTFFQ0MHdW5pMUVDRQVPaG9ybgd1bmkxRURBB3VuaTFFRTIHdW5pMUVEQwd1bmkxRURFB3VuaTFFRTANT2h1bmdhcnVtbGF1dAd1bmkwMjBFB09tYWNyb24HdW5pMUU1Mgd1bmkxRTUwB3VuaTAxRUELT3NsYXNoYWN1dGUHdW5pMUU0Qwd1bmkxRTRFB3VuaTAyMkMGUmFjdXRlBlJjYXJvbgxSY29tbWFhY2NlbnQHdW5pMDIxMAd1bmkxRTVBB3VuaTAyMTIHdW5pMUU1RQZTYWN1dGUHdW5pMUU2NAd1bmlBNzhCB3VuaTFFNjYLU2NpcmN1bWZsZXgMU2NvbW1hYWNjZW50B3VuaTFFNjAHdW5pMUU2Mgd1bmkxRTY4B3VuaTFFOUUHdW5pMDE4RgRUYmFyBlRjYXJvbgd1bmkwMTYyB3VuaTAyMUEHdW5pMUU2Qwd1bmkxRTZFBlVicmV2ZQd1bmkwMUQzB3VuaTAyMTQHdW5pMUVFNAd1bmkxRUU2BVVob3JuB3VuaTFFRTgHdW5pMUVGMAd1bmkxRUVBB3VuaTFFRUMHdW5pMUVFRQ1VaHVuZ2FydW1sYXV0B3VuaTAyMTYHVW1hY3Jvbgd1bmkxRTdBB1VvZ29uZWsFVXJpbmcGVXRpbGRlB3VuaTFFNzgGV2FjdXRlC1djaXJjdW1mbGV4CVdkaWVyZXNpcwZXZ3JhdmULWWNpcmN1bWZsZXgHdW5pMUU4RQd1bmkxRUY0BllncmF2ZQd1bmkxRUY2B3VuaTAyMzIHdW5pMUVGOAZaYWN1dGUKWmRvdGFjY2VudAd1bmkxRTkyEElhY3V0ZV9KLmxvY2xOTEQGQS5zczAxC0FhY3V0ZS5zczAxC0FicmV2ZS5zczAxDHVuaTFFQUUuc3MwMQx1bmkxRUI2LnNzMDEMdW5pMUVCMC5zczAxDHVuaTFFQjIuc3MwMQx1bmkxRUI0LnNzMDEMdW5pMDFDRC5zczAxEEFjaXJjdW1mbGV4LnNzMDEMdW5pMUVBNC5zczAxDHVuaTFFQUMuc3MwMQx1bmkxRUE2LnNzMDEMdW5pMUVBOC5zczAxDHVuaTFFQUEuc3MwMQx1bmkwMjAwLnNzMDEOQWRpZXJlc2lzLnNzMDEMdW5pMUVBMC5zczAxC0FncmF2ZS5zczAxDHVuaTFFQTIuc3MwMQx1bmkwMjAyLnNzMDEMQW1hY3Jvbi5zczAxDEFvZ29uZWsuc3MwMQpBcmluZy5zczAxD0FyaW5nYWN1dGUuc3MwMQtBdGlsZGUuc3MwMQdBRS5zczAxDEFFYWN1dGUuc3MwMQx1bmkwMUM0LnNzMDEMdW5pMDFDNS5zczAxBkUuc3MwMQtFYWN1dGUuc3MwMQtFYnJldmUuc3MwMQtFY2Fyb24uc3MwMQx1bmkxRTFDLnNzMDEQRWNpcmN1bWZsZXguc3MwMQx1bmkxRUJFLnNzMDEMdW5pMUVDNi5zczAxDHVuaTFFQzAuc3MwMQx1bmkxRUMyLnNzMDEMdW5pMUVDNC5zczAxDHVuaTAyMDQuc3MwMQ5FZGllcmVzaXMuc3MwMQ9FZG90YWNjZW50LnNzMDEMdW5pMUVCOC5zczAxC0VncmF2ZS5zczAxDHVuaTFFQkEuc3MwMQx1bmkwMjA2LnNzMDEMRW1hY3Jvbi5zczAxDHVuaTFFMTYuc3MwMQx1bmkxRTE0LnNzMDEMRW9nb25lay5zczAxDHVuaTFFQkMuc3MwMQZGLnNzMDEGRy5zczAxC0dicmV2ZS5zczAxC0djYXJvbi5zczAxEEdjaXJjdW1mbGV4LnNzMDERR2NvbW1hYWNjZW50LnNzMDEPR2RvdGFjY2VudC5zczAxDHVuaTFFMjAuc3MwMQx1bmkwMUU0LnNzMDEGSS5zczAxB0lKLnNzMDELSWFjdXRlLnNzMDEVSWFjdXRlX0oubG9jbE5MRC5zczAxC0licmV2ZS5zczAxEEljaXJjdW1mbGV4LnNzMDEMdW5pMDIwOC5zczAxDklkaWVyZXNpcy5zczAxDHVuaTFFMkUuc3MwMQ9JZG90YWNjZW50LnNzMDEMdW5pMUVDQS5zczAxC0lncmF2ZS5zczAxDHVuaTFFQzguc3MwMQx1bmkwMjBBLnNzMDEMSW1hY3Jvbi5zczAxDElvZ29uZWsuc3MwMQtJdGlsZGUuc3MwMQZKLnNzMDEQSmNpcmN1bWZsZXguc3MwMQx1bmkwMUM3LnNzMDEGTS5zczAxDHVuaTFFNDIuc3MwMQZOLnNzMDEMdW5pMDFDQS5zczAxC05hY3V0ZS5zczAxC05jYXJvbi5zczAxEU5jb21tYWFjY2VudC5zczAxDHVuaTFFNDQuc3MwMQx1bmkxRTQ2LnNzMDEIRW5nLnNzMDEMdW5pMDFDQi5zczAxDHVuaTFFNDguc3MwMQtOdGlsZGUuc3MwMQZRLnNzMDEMdW5pMDE4Ri5zczAxBlQuc3MwMQlUYmFyLnNzMDELVGNhcm9uLnNzMDEMdW5pMDE2Mi5zczAxDHVuaTAyMUEuc3MwMQx1bmkxRTZDLnNzMDEMdW5pMUU2RS5zczAxBlUuc3MwMQtVYWN1dGUuc3MwMQtVYnJldmUuc3MwMQx1bmkwMUQzLnNzMDEQVWNpcmN1bWZsZXguc3MwMQx1bmkwMjE0LnNzMDEOVWRpZXJlc2lzLnNzMDEMdW5pMUVFNC5zczAxC1VncmF2ZS5zczAxDHVuaTFFRTYuc3MwMQpVaG9ybi5zczAxDHVuaTFFRTguc3MwMQx1bmkxRUYwLnNzMDEMdW5pMUVFQS5zczAxDHVuaTFFRUMuc3MwMQx1bmkxRUVFLnNzMDESVWh1bmdhcnVtbGF1dC5zczAxDHVuaTAyMTYuc3MwMQxVbWFjcm9uLnNzMDEMdW5pMUU3QS5zczAxDFVvZ29uZWsuc3MwMQpVcmluZy5zczAxC1V0aWxkZS5zczAxDHVuaTFFNzguc3MwMQZXLnNzMDELV2FjdXRlLnNzMDEQV2NpcmN1bWZsZXguc3MwMQ5XZGllcmVzaXMuc3MwMQtXZ3JhdmUuc3MwMQZZLnNzMDELWWFjdXRlLnNzMDEQWWNpcmN1bWZsZXguc3MwMQ5ZZGllcmVzaXMuc3MwMQx1bmkxRThFLnNzMDEMdW5pMUVGNC5zczAxC1lncmF2ZS5zczAxDHVuaTFFRjYuc3MwMQx1bmkwMjMyLnNzMDEMdW5pMUVGOC5zczAxBlouc3MwMQtaYWN1dGUuc3MwMQtaY2Fyb24uc3MwMQ9aZG90YWNjZW50LnNzMDEMdW5pMUU5Mi5zczAxBmFicmV2ZQd1bmkxRUFGB3VuaTFFQjcHdW5pMUVCMQd1bmkxRUIzB3VuaTFFQjUHdW5pMDFDRQd1bmkxRUE1B3VuaTFFQUQHdW5pMUVBNwd1bmkxRUE5B3VuaTFFQUIHdW5pMDIwMQd1bmkxRUExB3VuaTFFQTMHdW5pMDIwMwdhbWFjcm9uB2FvZ29uZWsKYXJpbmdhY3V0ZQdhZWFjdXRlB3VuaTFFMDkLY2NpcmN1bWZsZXgKY2RvdGFjY2VudAZkY2Fyb24HdW5pMUUwRAd1bmkxRTBGB3VuaTAxQzYGZWJyZXZlBmVjYXJvbgd1bmkxRTFEB3VuaTFFQkYHdW5pMUVDNwd1bmkxRUMxB3VuaTFFQzMHdW5pMUVDNQd1bmkwMjA1CmVkb3RhY2NlbnQHdW5pMUVCOQd1bmkxRUJCB3VuaTAyMDcHZW1hY3Jvbgd1bmkxRTE3B3VuaTFFMTUHZW9nb25lawd1bmkxRUJEB3VuaTAyNTkHdW5pMDI5Mgd1bmkwMUVGBmdjYXJvbgtnY2lyY3VtZmxleAxnY29tbWFhY2NlbnQKZ2RvdGFjY2VudAd1bmkxRTIxB3VuaTAxRTUEaGJhcgd1bmkxRTJCB3VuaTAyMUYLaGNpcmN1bWZsZXgHdW5pMUUyNQZpYnJldmUHdW5pMDIwOQd1bmkxRTJGCWkubG9jbFRSSwd1bmkxRUNCB3VuaTFFQzkHdW5pMDIwQgJpagdpbWFjcm9uB2lvZ29uZWsGaXRpbGRlB3VuaTAyMzcLamNpcmN1bWZsZXgHdW5pMDFFOQxrY29tbWFhY2NlbnQMa2dyZWVubGFuZGljBmxhY3V0ZQZsY2Fyb24MbGNvbW1hYWNjZW50BGxkb3QHdW5pMUUzNwd1bmkwMUM5B3VuaTFFM0IHdW5pMUU0MwZuYWN1dGULbmFwb3N0cm9waGUGbmNhcm9uDG5jb21tYWFjY2VudAd1bmkxRTQ1B3VuaTFFNDcDZW5nB3VuaTAxQ0MHdW5pMUU0OQZvYnJldmUHdW5pMUVEMQd1bmkxRUQ5B3VuaTFFRDMHdW5pMUVENQd1bmkxRUQ3B3VuaTAyMEQHdW5pMDIyQgd1bmkwMjMxB3VuaTFFQ0QHdW5pMUVDRgVvaG9ybgd1bmkxRURCB3VuaTFFRTMHdW5pMUVERAd1bmkxRURGB3VuaTFFRTENb2h1bmdhcnVtbGF1dAd1bmkwMjBGB29tYWNyb24HdW5pMUU1Mwd1bmkxRTUxB3VuaTAxRUILb3NsYXNoYWN1dGUHdW5pMUU0RAd1bmkxRTRGB3VuaTAyMkQGcmFjdXRlBnJjYXJvbgxyY29tbWFhY2NlbnQHdW5pMDIxMQd1bmkxRTVCB3VuaTAyMTMHdW5pMUU1RgZzYWN1dGUHdW5pMUU2NQd1bmlBNzhDB3VuaTFFNjcLc2NpcmN1bWZsZXgMc2NvbW1hYWNjZW50B3VuaTFFNjEHdW5pMUU2Mwd1bmkxRTY5BWxvbmdzBHRiYXIGdGNhcm9uB3VuaTAxNjMHdW5pMDIxQgd1bmkxRTk3B3VuaTFFNkQHdW5pMUU2RgZ1YnJldmUHdW5pMDFENAd1bmkwMjE1B3VuaTFFRTUHdW5pMUVFNwV1aG9ybgd1bmkxRUU5B3VuaTFFRjEHdW5pMUVFQgd1bmkxRUVEB3VuaTFFRUYNdWh1bmdhcnVtbGF1dAd1bmkwMjE3B3VtYWNyb24HdW5pMUU3Qgd1b2dvbmVrBXVyaW5nBnV0aWxkZQd1bmkxRTc5BndhY3V0ZQt3Y2lyY3VtZmxleAl3ZGllcmVzaXMGd2dyYXZlC3ljaXJjdW1mbGV4B3VuaTFFOEYHdW5pMUVGNQZ5Z3JhdmUHdW5pMUVGNwd1bmkwMjMzB3VuaTFFRjkGemFjdXRlCnpkb3RhY2NlbnQHdW5pMUU5MxBpYWN1dGVfai5sb2NsTkxEBmEuc3MwMQthYWN1dGUuc3MwMQthYnJldmUuc3MwMQx1bmkxRUFGLnNzMDEMdW5pMUVCNy5zczAxDHVuaTFFQjEuc3MwMQx1bmkxRUIzLnNzMDEMdW5pMUVCNS5zczAxDHVuaTAxQ0Uuc3MwMRBhY2lyY3VtZmxleC5zczAxDHVuaTFFQTUuc3MwMQx1bmkxRUFELnNzMDEMdW5pMUVBNy5zczAxDHVuaTFFQTkuc3MwMQx1bmkxRUFCLnNzMDEMdW5pMDIwMS5zczAxDmFkaWVyZXNpcy5zczAxDHVuaTFFQTEuc3MwMQthZ3JhdmUuc3MwMQx1bmkxRUEzLnNzMDEMdW5pMDIwMy5zczAxDGFtYWNyb24uc3MwMQxhb2dvbmVrLnNzMDEKYXJpbmcuc3MwMQ9hcmluZ2FjdXRlLnNzMDELYXRpbGRlLnNzMDEHYWUuc3MwMQxhZWFjdXRlLnNzMDEMdW5pMDFDNi5zczAxBmUuc3MwMQtlYWN1dGUuc3MwMQtlYnJldmUuc3MwMQtlY2Fyb24uc3MwMQx1bmkxRTFELnNzMDEQZWNpcmN1bWZsZXguc3MwMQx1bmkxRUJGLnNzMDEMdW5pMUVDNy5zczAxDHVuaTFFQzEuc3MwMQx1bmkxRUMzLnNzMDEMdW5pMUVDNS5zczAxDHVuaTAyMDUuc3MwMQ5lZGllcmVzaXMuc3MwMQ9lZG90YWNjZW50LnNzMDEMdW5pMUVCOS5zczAxC2VncmF2ZS5zczAxDHVuaTFFQkIuc3MwMQx1bmkwMjA3LnNzMDEMZW1hY3Jvbi5zczAxDHVuaTFFMTcuc3MwMQx1bmkxRTE1LnNzMDEMZW9nb25lay5zczAxDHVuaTFFQkQuc3MwMQx1bmkwMjU5LnNzMDEGZi5zczAxBmwuc3MwMQtsYWN1dGUuc3MwMQtsY2Fyb24uc3MwMRFsY29tbWFhY2NlbnQuc3MwMQlsZG90LnNzMDEMdW5pMUUzNy5zczAxDHVuaTAxQzkuc3MwMQx1bmkxRTNCLnNzMDELbHNsYXNoLnNzMDEHb2Uuc3MwMQZ0LnNzMDEJdGJhci5zczAxC3RjYXJvbi5zczAxDHVuaTAxNjMuc3MwMQx1bmkwMjFCLnNzMDEMdW5pMUU5Ny5zczAxDHVuaTFFNkQuc3MwMQx1bmkxRTZGLnNzMDEGdy5zczAxC3dhY3V0ZS5zczAxEHdjaXJjdW1mbGV4LnNzMDEOd2RpZXJlc2lzLnNzMDELd2dyYXZlLnNzMDEGeS5zczAxC3lhY3V0ZS5zczAxEHljaXJjdW1mbGV4LnNzMDEOeWRpZXJlc2lzLnNzMDEMdW5pMUVGNS5zczAxC3lncmF2ZS5zczAxDHVuaTFFRjcuc3MwMQx1bmkwMjMzLnNzMDEMdW5pMUVGOS5zczAxBnouc3MwMQt6YWN1dGUuc3MwMQt6Y2Fyb24uc3MwMQ96ZG90YWNjZW50LnNzMDEMdW5pMUU5My5zczAxA1RfaAdmaS5zczAxB2ZsLnNzMDEEYS5zYwlhYWN1dGUuc2MJYWJyZXZlLnNjCnVuaTFFQUYuc2MKdW5pMUVCNy5zYwp1bmkxRUIxLnNjCnVuaTFFQjMuc2MKdW5pMUVCNS5zYwp1bmkwMUNFLnNjDmFjaXJjdW1mbGV4LnNjCnVuaTFFQTUuc2MKdW5pMUVBRC5zYwp1bmkxRUE3LnNjCnVuaTFFQTkuc2MKdW5pMUVBQi5zYwp1bmkwMjAxLnNjDGFkaWVyZXNpcy5zYwp1bmkxRUExLnNjCWFncmF2ZS5zYwp1bmkxRUEzLnNjCnVuaTAyMDMuc2MKYW1hY3Jvbi5zYwphb2dvbmVrLnNjCGFyaW5nLnNjDWFyaW5nYWN1dGUuc2MJYXRpbGRlLnNjBWFlLnNjCmFlYWN1dGUuc2MEYi5zYwRjLnNjCWNhY3V0ZS5zYwljY2Fyb24uc2MLY2NlZGlsbGEuc2MKdW5pMUUwOS5zYw5jY2lyY3VtZmxleC5zYw1jZG90YWNjZW50LnNjBGQuc2MGZXRoLnNjCWRjYXJvbi5zYwlkY3JvYXQuc2MKdW5pMUUwRC5zYwp1bmkxRTBGLnNjCnVuaTAxQzYuc2MEZS5zYwllYWN1dGUuc2MJZWJyZXZlLnNjCWVjYXJvbi5zYwp1bmkxRTFELnNjDmVjaXJjdW1mbGV4LnNjCnVuaTFFQkYuc2MKdW5pMUVDNy5zYwp1bmkxRUMxLnNjCnVuaTFFQzMuc2MKdW5pMUVDNS5zYwp1bmkwMjA1LnNjDGVkaWVyZXNpcy5zYw1lZG90YWNjZW50LnNjCnVuaTFFQjkuc2MJZWdyYXZlLnNjCnVuaTFFQkIuc2MKdW5pMDIwNy5zYwplbWFjcm9uLnNjCnVuaTFFMTcuc2MKdW5pMUUxNS5zYwplb2dvbmVrLnNjCnVuaTFFQkQuc2MKdW5pMDI1OS5zYwp1bmkwMjkyLnNjCnVuaTAxRUYuc2MEZi5zYwRnLnNjCWdicmV2ZS5zYwlnY2Fyb24uc2MOZ2NpcmN1bWZsZXguc2MPZ2NvbW1hYWNjZW50LnNjDWdkb3RhY2NlbnQuc2MKdW5pMUUyMS5zYwp1bmkwMUU1LnNjBGguc2MHaGJhci5zYwp1bmkxRTJCLnNjCnVuaTAyMUYuc2MOaGNpcmN1bWZsZXguc2MKdW5pMUUyNS5zYwRpLnNjC2RvdGxlc3NpLnNjCWlhY3V0ZS5zYxNpYWN1dGVfai5sb2NsTkxELnNjCWlicmV2ZS5zYw5pY2lyY3VtZmxleC5zYwp1bmkwMjA5LnNjDGlkaWVyZXNpcy5zYwp1bmkxRTJGLnNjDGkuc2MubG9jbFRSSwp1bmkxRUNCLnNjCWlncmF2ZS5zYwp1bmkxRUM5LnNjCnVuaTAyMEIuc2MFaWouc2MKaW1hY3Jvbi5zYwppb2dvbmVrLnNjCWl0aWxkZS5zYwRqLnNjDmpjaXJjdW1mbGV4LnNjBGsuc2MKdW5pMDFFOS5zYw9rY29tbWFhY2NlbnQuc2MPa2dyZWVubGFuZGljLnNjBGwuc2MJbGFjdXRlLnNjCWxjYXJvbi5zYw9sY29tbWFhY2NlbnQuc2MHbGRvdC5zYwp1bmkxRTM3LnNjCnVuaTAxQzkuc2MKdW5pMUUzQi5zYwlsc2xhc2guc2MEbS5zYwp1bmkxRTQzLnNjBG4uc2MJbmFjdXRlLnNjCW5jYXJvbi5zYw9uY29tbWFhY2NlbnQuc2MKdW5pMUU0NS5zYwp1bmkxRTQ3LnNjBmVuZy5zYwp1bmkwMUNDLnNjCnVuaTFFNDkuc2MJbnRpbGRlLnNjBG8uc2MJb2FjdXRlLnNjCW9icmV2ZS5zYw5vY2lyY3VtZmxleC5zYwp1bmkxRUQxLnNjCnVuaTFFRDkuc2MKdW5pMUVEMy5zYwp1bmkxRUQ1LnNjCnVuaTFFRDcuc2MKdW5pMDIwRC5zYwxvZGllcmVzaXMuc2MKdW5pMDIyQi5zYwp1bmkwMjMxLnNjCnVuaTFFQ0Quc2MJb2dyYXZlLnNjCnVuaTFFQ0Yuc2MIb2hvcm4uc2MKdW5pMUVEQi5zYwp1bmkxRUUzLnNjCnVuaTFFREQuc2MKdW5pMUVERi5zYwp1bmkxRUUxLnNjEG9odW5nYXJ1bWxhdXQuc2MKdW5pMDIwRi5zYwpvbWFjcm9uLnNjCnVuaTFFNTMuc2MKdW5pMUU1MS5zYwp1bmkwMUVCLnNjCW9zbGFzaC5zYw5vc2xhc2hhY3V0ZS5zYwlvdGlsZGUuc2MKdW5pMUU0RC5zYwp1bmkxRTRGLnNjCnVuaTAyMkQuc2MFb2Uuc2MEcC5zYwh0aG9ybi5zYwRxLnNjBHIuc2MJcmFjdXRlLnNjCXJjYXJvbi5zYw9yY29tbWFhY2NlbnQuc2MKdW5pMDIxMS5zYwp1bmkxRTVCLnNjCnVuaTAyMTMuc2MKdW5pMUU1Ri5zYwRzLnNjCXNhY3V0ZS5zYwp1bmkxRTY1LnNjCnVuaUE3OEMuc2MJc2Nhcm9uLnNjCnVuaTFFNjcuc2MLc2NlZGlsbGEuc2MOc2NpcmN1bWZsZXguc2MPc2NvbW1hYWNjZW50LnNjCnVuaTFFNjEuc2MKdW5pMUU2My5zYwp1bmkxRTY5LnNjDWdlcm1hbmRibHMuc2MEdC5zYwd0YmFyLnNjCXRjYXJvbi5zYwp1bmkwMTYzLnNjCnVuaTAyMUIuc2MKdW5pMUU5Ny5zYwp1bmkxRTZELnNjCnVuaTFFNkYuc2MEdS5zYwl1YWN1dGUuc2MJdWJyZXZlLnNjCnVuaTAxRDQuc2MOdWNpcmN1bWZsZXguc2MKdW5pMDIxNS5zYwx1ZGllcmVzaXMuc2MKdW5pMUVFNS5zYwl1Z3JhdmUuc2MKdW5pMUVFNy5zYwh1aG9ybi5zYwp1bmkxRUU5LnNjCnVuaTFFRjEuc2MKdW5pMUVFQi5zYwp1bmkxRUVELnNjCnVuaTFFRUYuc2MQdWh1bmdhcnVtbGF1dC5zYwp1bmkwMjE3LnNjCnVtYWNyb24uc2MKdW5pMUU3Qi5zYwp1b2dvbmVrLnNjCHVyaW5nLnNjCXV0aWxkZS5zYwp1bmkxRTc5LnNjBHYuc2MEdy5zYwl3YWN1dGUuc2MOd2NpcmN1bWZsZXguc2MMd2RpZXJlc2lzLnNjCXdncmF2ZS5zYwR4LnNjBHkuc2MJeWFjdXRlLnNjDnljaXJjdW1mbGV4LnNjDHlkaWVyZXNpcy5zYwp1bmkxRThGLnNjCnVuaTFFRjUuc2MJeWdyYXZlLnNjCnVuaTFFRjcuc2MKdW5pMDIzMy5zYwp1bmkxRUY5LnNjBHouc2MJemFjdXRlLnNjCXpjYXJvbi5zYw16ZG90YWNjZW50LnNjCnVuaTFFOTMuc2MJYS5zYy5zczAxDmFhY3V0ZS5zYy5zczAxDmFicmV2ZS5zYy5zczAxD3VuaTFFQUYuc2Muc3MwMQ91bmkxRUI3LnNjLnNzMDEPdW5pMUVCMS5zYy5zczAxD3VuaTFFQjMuc2Muc3MwMQ91bmkxRUI1LnNjLnNzMDEPdW5pMDFDRS5zYy5zczAxE2FjaXJjdW1mbGV4LnNjLnNzMDEPdW5pMUVBNS5zYy5zczAxD3VuaTFFQUQuc2Muc3MwMQ91bmkxRUE3LnNjLnNzMDEPdW5pMUVBOS5zYy5zczAxD3VuaTFFQUIuc2Muc3MwMQ91bmkwMjAxLnNjLnNzMDERYWRpZXJlc2lzLnNjLnNzMDEPdW5pMUVBMS5zYy5zczAxDmFncmF2ZS5zYy5zczAxD3VuaTFFQTMuc2Muc3MwMQ91bmkwMjAzLnNjLnNzMDEPYW1hY3Jvbi5zYy5zczAxD2FvZ29uZWsuc2Muc3MwMQ1hcmluZy5zYy5zczAxEmFyaW5nYWN1dGUuc2Muc3MwMQ5hdGlsZGUuc2Muc3MwMQphZS5zYy5zczAxD2FlYWN1dGUuc2Muc3MwMQ91bmkwMUM2LnNjLnNzMDEJZS5zYy5zczAxDmVhY3V0ZS5zYy5zczAxDmVicmV2ZS5zYy5zczAxDmVjYXJvbi5zYy5zczAxD3VuaTFFMUQuc2Muc3MwMRNlY2lyY3VtZmxleC5zYy5zczAxD3VuaTFFQkYuc2Muc3MwMQ91bmkxRUM3LnNjLnNzMDEPdW5pMUVDMS5zYy5zczAxD3VuaTFFQzMuc2Muc3MwMQ91bmkxRUM1LnNjLnNzMDEPdW5pMDIwNS5zYy5zczAxEWVkaWVyZXNpcy5zYy5zczAxEmVkb3RhY2NlbnQuc2Muc3MwMQ91bmkxRUI5LnNjLnNzMDEOZWdyYXZlLnNjLnNzMDEPdW5pMUVCQi5zYy5zczAxD3VuaTAyMDcuc2Muc3MwMQ9lbWFjcm9uLnNjLnNzMDEPdW5pMUUxNy5zYy5zczAxD3VuaTFFMTUuc2Muc3MwMQ9lb2dvbmVrLnNjLnNzMDEPdW5pMUVCRC5zYy5zczAxD3VuaTAyNTkuc2Muc3MwMQlmLnNjLnNzMDEJZy5zYy5zczAxDmdicmV2ZS5zYy5zczAxDmdjYXJvbi5zYy5zczAxE2djaXJjdW1mbGV4LnNjLnNzMDEUZ2NvbW1hYWNjZW50LnNjLnNzMDESZ2RvdGFjY2VudC5zYy5zczAxD3VuaTFFMjEuc2Muc3MwMQ91bmkwMUU1LnNjLnNzMDEJaS5zYy5zczAxEGRvdGxlc3NpLnNjLnNzMDEOaWFjdXRlLnNjLnNzMDEYaWFjdXRlX2oubG9jbE5MRC5zYy5zczAxDmlicmV2ZS5zYy5zczAxE2ljaXJjdW1mbGV4LnNjLnNzMDEPdW5pMDIwOS5zYy5zczAxEWlkaWVyZXNpcy5zYy5zczAxD3VuaTFFMkYuc2Muc3MwMQ91bmkxRUNCLnNjLnNzMDEOaWdyYXZlLnNjLnNzMDEPdW5pMUVDOS5zYy5zczAxD3VuaTAyMEIuc2Muc3MwMQppai5zYy5zczAxD2ltYWNyb24uc2Muc3MwMQ9pb2dvbmVrLnNjLnNzMDEOaXRpbGRlLnNjLnNzMDEJai5zYy5zczAxE2pjaXJjdW1mbGV4LnNjLnNzMDEPdW5pMDFDOS5zYy5zczAxCW0uc2Muc3MwMQ91bmkxRTQzLnNjLnNzMDEJbi5zYy5zczAxDm5hY3V0ZS5zYy5zczAxDm5jYXJvbi5zYy5zczAxFG5jb21tYWFjY2VudC5zYy5zczAxD3VuaTFFNDUuc2Muc3MwMQ91bmkxRTQ3LnNjLnNzMDELZW5nLnNjLnNzMDEPdW5pMDFDQy5zYy5zczAxD3VuaTFFNDkuc2Muc3MwMQ5udGlsZGUuc2Muc3MwMQlxLnNjLnNzMDEJdC5zYy5zczAxDHRiYXIuc2Muc3MwMQ50Y2Fyb24uc2Muc3MwMQ91bmkwMTYzLnNjLnNzMDEPdW5pMDIxQi5zYy5zczAxD3VuaTFFOTcuc2Muc3MwMQ91bmkxRTZELnNjLnNzMDEPdW5pMUU2Ri5zYy5zczAxCXUuc2Muc3MwMQ51YWN1dGUuc2Muc3MwMQ51YnJldmUuc2Muc3MwMQ91bmkwMUQ0LnNjLnNzMDETdWNpcmN1bWZsZXguc2Muc3MwMQ91bmkwMjE1LnNjLnNzMDERdWRpZXJlc2lzLnNjLnNzMDEPdW5pMUVFNS5zYy5zczAxDnVncmF2ZS5zYy5zczAxD3VuaTFFRTcuc2Muc3MwMQ11aG9ybi5zYy5zczAxD3VuaTFFRTkuc2Muc3MwMQ91bmkxRUYxLnNjLnNzMDEPdW5pMUVFQi5zYy5zczAxD3VuaTFFRUQuc2Muc3MwMQ91bmkxRUVGLnNjLnNzMDEVdWh1bmdhcnVtbGF1dC5zYy5zczAxD3VuaTAyMTcuc2Muc3MwMQ91bWFjcm9uLnNjLnNzMDEPdW5pMUU3Qi5zYy5zczAxD3VvZ29uZWsuc2Muc3MwMQ11cmluZy5zYy5zczAxDnV0aWxkZS5zYy5zczAxD3VuaTFFNzkuc2Muc3MwMQl3LnNjLnNzMDEOd2FjdXRlLnNjLnNzMDETd2NpcmN1bWZsZXguc2Muc3MwMRF3ZGllcmVzaXMuc2Muc3MwMQ53Z3JhdmUuc2Muc3MwMQl5LnNjLnNzMDEOeWFjdXRlLnNjLnNzMDETeWNpcmN1bWZsZXguc2Muc3MwMRF5ZGllcmVzaXMuc2Muc3MwMQ91bmkxRThGLnNjLnNzMDEPdW5pMUVGNS5zYy5zczAxDnlncmF2ZS5zYy5zczAxD3VuaTFFRjcuc2Muc3MwMQ91bmkwMjMzLnNjLnNzMDEPdW5pMUVGOS5zYy5zczAxCXouc2Muc3MwMQ56YWN1dGUuc2Muc3MwMQ56Y2Fyb24uc2Muc3MwMRJ6ZG90YWNjZW50LnNjLnNzMDEPdW5pMUU5My5zYy5zczAxB3VuaTA0MTAHdW5pMDQxMQd1bmkwNDEyB3VuaTA0MTMHdW5pMDQwMwd1bmkwNDkwB3VuaTA0MTQHdW5pMDQxNQd1bmkwNDAwB3VuaTA0MDEHdW5pMDQxNgd1bmkwNDE3B3VuaTA0MTgHdW5pMDQxOQd1bmkwNDBEB3VuaTA0OEEHdW5pMDQxQQd1bmkwNDBDB3VuaTA0MUIHdW5pMDQxQwd1bmkwNDFEB3VuaTA0MUUHdW5pMDQxRgd1bmkwNDIwB3VuaTA0MjEHdW5pMDQyMgd1bmkwNDIzB3VuaTA0MEUHdW5pMDQyNAd1bmkwNDI1B3VuaTA0MjcHdW5pMDQyNgd1bmkwNDI4B3VuaTA0MjkHdW5pMDQwRgd1bmkwNDJDB3VuaTA0MkEHdW5pMDQyQgd1bmkwNDA5B3VuaTA0MEEHdW5pMDQwNQd1bmkwNDA0B3VuaTA0MkQHdW5pMDQwNgd1bmkwNDA3B3VuaTA0MDgHdW5pMDQwQgd1bmkwNDJFB3VuaTA0MkYHdW5pMDQwMgd1bmkwNDYyB3VuaTA0NkEHdW5pMDQ3Mgd1bmkwNDc0B3VuaTA0OTIHdW5pMDQ5NAd1bmkwNDk2B3VuaTA0OTgHdW5pMDQ5QQd1bmkwNDlDB3VuaTA0OUUHdW5pMDRBMAd1bmkwNEEyB3VuaTA0QTQHdW5pMDRBNgd1bmkwNTI0B3VuaTA0QTgHdW5pMDRBQQd1bmkwNEFDB3VuaTA0QUUHdW5pMDRCMAd1bmkwNEIyB3VuaTA0QjQHdW5pMDRCNgd1bmkwNEI4B3VuaTA0QkEHdW5pMDUyNgd1bmkwNEJDB3VuaTA0QkUHdW5pMDRDMAd1bmkwNEMxB3VuaTA0QzMHdW5pMDRDNwd1bmkwNEM5B3VuaTA0Q0IHdW5pMDRDRAd1bmkwNEQwB3VuaTA0RDIHdW5pMDRENAd1bmkwNEQ2B3VuaTA0RDgHdW5pMDREQQd1bmkwNERDB3VuaTA0REUHdW5pMDRFMAd1bmkwNEUyB3VuaTA0RTQHdW5pMDRFNgd1bmkwNEU4B3VuaTA0RUEHdW5pMDRFQwd1bmkwNEVFB3VuaTA0RjAHdW5pMDRGMgd1bmkwNEY0B3VuaTA0RjYHdW5pMDRGOAd1bmkwNEZBB3VuaTA0RkMHdW5pMDRGRQd1bmkwNTEwB3VuaTA1MTIHdW5pMDUxQQd1bmkwNTFDB3VuaTA0OEMHdW5pMDQ4RQd1bmkwNTI4B3VuaTA1MkUPdW5pMDQxNC5sb2NsQkdSD3VuaTA0MUIubG9jbEJHUg91bmkwNDI0LmxvY2xCR1IPdW5pMDQ5Mi5sb2NsQlNID3VuaTA0OTgubG9jbEJTSA91bmkwNEFBLmxvY2xCU0gPdW5pMDRBQS5sb2NsQ0hVDHVuaTA0MTAuc3MwMQx1bmkwNDE0LnNzMDEMdW5pMDQxNS5zczAxDHVuaTA0MDAuc3MwMQx1bmkwNDAxLnNzMDEMdW5pMDQxOC5zczAxDHVuaTA0MTkuc3MwMQx1bmkwNDhBLnNzMDEMdW5pMDQwRC5zczAxDHVuaTA0MUIuc3MwMQx1bmkwNDIwLnNzMDEMdW5pMDQyMi5zczAxDHVuaTA0MjMuc3MwMQx1bmkwNDBFLnNzMDEMdW5pMDQyNC5zczAxDHVuaTA0MkMuc3MwMQx1bmkwNDJBLnNzMDEMdW5pMDQyQi5zczAxDHVuaTA0MDkuc3MwMQx1bmkwNDBBLnNzMDEMdW5pMDQwOC5zczAxDHVuaTA0NjIuc3MwMQx1bmkwNEFDLnNzMDEMdW5pMDREMC5zczAxDHVuaTA0RDIuc3MwMQx1bmkwNEQ0LnNzMDEMdW5pMDRENi5zczAxDHVuaTA0RTIuc3MwMQx1bmkwNEU0LnNzMDEMdW5pMDRFRS5zczAxDHVuaTA0RjAuc3MwMQx1bmkwNEYyLnNzMDEMdW5pMDRGOC5zczAxDHVuaTA1MUEuc3MwMQx1bmkwNDhDLnNzMDEHdW5pMDQzMAd1bmkwNDMxB3VuaTA0MzIHdW5pMDQzMwd1bmkwNDUzB3VuaTA0OTEHdW5pMDQzNAd1bmkwNDM1B3VuaTA0NTAHdW5pMDQ1MQd1bmkwNDM2B3VuaTA0MzcHdW5pMDQzOAd1bmkwNDM5B3VuaTA0NUQHdW5pMDQ4Qgd1bmkwNDNBB3VuaTA0NUMHdW5pMDQzQgd1bmkwNDNDB3VuaTA0M0QHdW5pMDQzRQd1bmkwNDNGB3VuaTA0NDAHdW5pMDQ0MQd1bmkwNDQyB3VuaTA0NDMHdW5pMDQ1RQd1bmkwNDQ0B3VuaTA0NDUHdW5pMDQ0Nwd1bmkwNDQ2B3VuaTA0NDgHdW5pMDQ0OQd1bmkwNDVGB3VuaTA0NEMHdW5pMDQ0QQd1bmkwNDRCB3VuaTA0NTkHdW5pMDQ1QQd1bmkwNDU1B3VuaTA0NTQHdW5pMDQ0RAd1bmkwNDU2B3VuaTA0NTcHdW5pMDQ1OAd1bmkwNDVCB3VuaTA0NEUHdW5pMDQ0Rgd1bmkwNDUyB3VuaTA0NjMHdW5pMDQ2Qgd1bmkwNDczB3VuaTA0NzUHdW5pMDQ5Mwd1bmkwNDk1B3VuaTA0OTcHdW5pMDQ5OQd1bmkwNDlCB3VuaTA0OUQHdW5pMDQ5Rgd1bmkwNEExB3VuaTA0QTMHdW5pMDRBNQd1bmkwNTI1B3VuaTA0QTcHdW5pMDRBOQd1bmkwNEFCB3VuaTA0QUQHdW5pMDRBRgd1bmkwNEIxB3VuaTA0QjMHdW5pMDRCNQd1bmkwNEI3B3VuaTA0QjkHdW5pMDRCQgd1bmkwNTI3B3VuaTA0QkQHdW5pMDRCRgd1bmkwNENGB3VuaTA0QzIHdW5pMDRDNAd1bmkwNEM2B3VuaTA0QzgHdW5pMDRDQQd1bmkwNENDB3VuaTA0Q0UHdW5pMDREMQd1bmkwNEQzB3VuaTA0RDUHdW5pMDRENwd1bmkwNEQ5B3VuaTA0REIHdW5pMDRERAd1bmkwNERGB3VuaTA0RTEHdW5pMDRFMwd1bmkwNEU1B3VuaTA0RTcHdW5pMDRFOQd1bmkwNEVCB3VuaTA0RUQHdW5pMDRFRgd1bmkwNEYxB3VuaTA0RjMHdW5pMDRGNQd1bmkwNEY3B3VuaTA0RjkHdW5pMDRGQgd1bmkwNEZEB3VuaTA0RkYHdW5pMDUxMQd1bmkwNTEzB3VuaTA1MUIHdW5pMDUxRAd1bmkwNDhEB3VuaTA0OEYHdW5pMDUyOQd1bmkwNTJGD3VuaTA0MzIubG9jbEJHUg91bmkwNDMzLmxvY2xCR1IPdW5pMDQzNC5sb2NsQkdSD3VuaTA0MzYubG9jbEJHUg91bmkwNDM3LmxvY2xCR1IPdW5pMDQzOC5sb2NsQkdSD3VuaTA0MzkubG9jbEJHUg91bmkwNDVELmxvY2xCR1IPdW5pMDQzQS5sb2NsQkdSD3VuaTA0M0IubG9jbEJHUg91bmkwNDNELmxvY2xCR1IPdW5pMDQzRi5sb2NsQkdSD3VuaTA0NDIubG9jbEJHUg91bmkwNDQ3LmxvY2xCR1IPdW5pMDQ0Ni5sb2NsQkdSD3VuaTA0NDgubG9jbEJHUg91bmkwNDQ5LmxvY2xCR1IPdW5pMDQ0Qy5sb2NsQkdSD3VuaTA0NEEubG9jbEJHUg91bmkwNDRFLmxvY2xCR1IPdW5pMDQ5My5sb2NsQlNID3VuaTA0OTkubG9jbEJTSA91bmkwNEFCLmxvY2xDSFUPdW5pMDQ1My5sb2NsTUtED3VuaTA0MzEubG9jbFNSQg91bmkwNDMzLmxvY2xTUkIPdW5pMDQzNC5sb2NsU1JCD3VuaTA0M0YubG9jbFNSQg91bmkwNDQyLmxvY2xTUkIMdW5pMDQzMC5zczAxDHVuaTA0MzQuc3MwMQx1bmkwNDM1LnNzMDEMdW5pMDQ1MC5zczAxDHVuaTA0NTEuc3MwMQx1bmkwNDM4LnNzMDEMdW5pMDQzOS5zczAxDHVuaTA0OEIuc3MwMQx1bmkwNDVELnNzMDEMdW5pMDQ0MC5zczAxDHVuaTA0NDIuc3MwMQx1bmkwNDQzLnNzMDEMdW5pMDQ1RS5zczAxDHVuaTA0NEMuc3MwMQx1bmkwNDRBLnNzMDEMdW5pMDQ0Qi5zczAxDHVuaTA0NTkuc3MwMQx1bmkwNDVBLnNzMDEMdW5pMDQ2My5zczAxDHVuaTA0RDEuc3MwMQx1bmkwNEQzLnNzMDEMdW5pMDRENS5zczAxDHVuaTA0RDcuc3MwMQx1bmkwNEQ5LnNzMDEMdW5pMDREQi5zczAxDHVuaTA0RTMuc3MwMQx1bmkwNEU1LnNzMDEMdW5pMDRFRi5zczAxDHVuaTA0RjEuc3MwMQx1bmkwNEYzLnNzMDEMdW5pMDRGOS5zczAxDHVuaTA0OEQuc3MwMQd1bmkwMzk0B3VuaTAzQTkHdW5pMDNCQwd1bmkyMTJCB3VuaTIxMkEIemVyby5vc2YHb25lLm9zZgd0d28ub3NmCXRocmVlLm9zZghmb3VyLm9zZghmaXZlLm9zZgdzaXgub3NmCXNldmVuLm9zZgllaWdodC5vc2YIbmluZS5vc2YJemVyby5zaW5mCG9uZS5zaW5mCHR3by5zaW5mCnRocmVlLnNpbmYJZm91ci5zaW5mCWZpdmUuc2luZghzaXguc2luZgpzZXZlbi5zaW5mCmVpZ2h0LnNpbmYJbmluZS5zaW5mB3plcm8udGYGb25lLnRmBnR3by50Zgh0aHJlZS50Zgdmb3VyLnRmB2ZpdmUudGYGc2l4LnRmCHNldmVuLnRmCGVpZ2h0LnRmB25pbmUudGYJemVyby50b3NmCG9uZS50b3NmCHR3by50b3NmCnRocmVlLnRvc2YJZm91ci50b3NmCWZpdmUudG9zZghzaXgudG9zZgpzZXZlbi50b3NmCmVpZ2h0LnRvc2YJbmluZS50b3NmB3VuaTIwODAHdW5pMjA4MQd1bmkyMDgyB3VuaTIwODMHdW5pMjA4NAd1bmkyMDg1B3VuaTIwODYHdW5pMjA4Nwd1bmkyMDg4B3VuaTIwODkJemVyby5kbm9tCG9uZS5kbm9tCHR3by5kbm9tCnRocmVlLmRub20JZm91ci5kbm9tCWZpdmUuZG5vbQhzaXguZG5vbQpzZXZlbi5kbm9tCmVpZ2h0LmRub20JbmluZS5kbm9tCXplcm8ubnVtcghvbmUubnVtcgh0d28ubnVtcgp0aHJlZS5udW1yCWZvdXIubnVtcglmaXZlLm51bXIIc2l4Lm51bXIKc2V2ZW4ubnVtcgplaWdodC5udW1yCW5pbmUubnVtcgd1bmkyMDcwB3VuaTAwQjkHdW5pMDBCMgd1bmkwMEIzB3VuaTIwNzQHdW5pMjA3NQd1bmkyMDc2B3VuaTIwNzcHdW5pMjA3OAd1bmkyMDc5B3VuaTIxNTMHdW5pMjE1NAlvbmVlaWdodGgMdGhyZWVlaWdodGhzC2ZpdmVlaWdodGhzDHNldmVuZWlnaHRocw5iYWNrc2xhc2guY2FzZRNwZXJpb2RjZW50ZXJlZC5jYXNlC2J1bGxldC5jYXNlG3BlcmlvZGNlbnRlcmVkLmxvY2xDQVQuY2FzZQpzbGFzaC5jYXNlFnBlcmlvZGNlbnRlcmVkLmxvY2xDQVQOYnJhY2VsZWZ0LmNhc2UPYnJhY2VyaWdodC5jYXNlEGJyYWNrZXRsZWZ0LmNhc2URYnJhY2tldHJpZ2h0LmNhc2UOcGFyZW5sZWZ0LmNhc2UPcGFyZW5yaWdodC5jYXNlCmZpZ3VyZWRhc2gHdW5pMjAxNQd1bmkyMDEwB3VuaTAwQUQLZW1kYXNoLmNhc2ULZW5kYXNoLmNhc2ULaHlwaGVuLmNhc2USZ3VpbGxlbW90bGVmdC5jYXNlE2d1aWxsZW1vdHJpZ2h0LmNhc2USZ3VpbHNpbmdsbGVmdC5jYXNlE2d1aWxzaW5nbHJpZ2h0LmNhc2UJZXhjbGFtLnNjDWV4Y2xhbWRvd24uc2MQZ3VpbGxlbW90bGVmdC5zYxFndWlsbGVtb3RyaWdodC5zYxBndWlsc2luZ2xsZWZ0LnNjEWd1aWxzaW5nbHJpZ2h0LnNjCXBlcmlvZC5zYwtxdWVzdGlvbi5zYw9xdWVzdGlvbmRvd24uc2MLcXVvdGVkYmwuc2MPcXVvdGVkYmxiYXNlLnNjD3F1b3RlZGJsbGVmdC5zYxBxdW90ZWRibHJpZ2h0LnNjDHF1b3RlbGVmdC5zYw1xdW90ZXJpZ2h0LnNjEXF1b3Rlc2luZ2xiYXNlLnNjDnF1b3Rlc2luZ2xlLnNjB3VuaTI3RTgHdW5pMjdFOQd1bmkyMDA3B3VuaTIwMEEHdW5pMjAwOAd1bmkwMEEwB3VuaTIwMDkHdW5pMjAwQgd1bmkyMEI1DWNvbG9ubW9uZXRhcnkEZG9uZwRFdXJvB3VuaTIwQjIHdW5pMjBCNAd1bmkyMEFEBGxpcmEHdW5pMjBCQQd1bmkyMEJDB3VuaTIwQTYGcGVzZXRhB3VuaTIwQjEHdW5pMjBCRAd1bmkyMEI5B3VuaTIwQjgHdW5pMjBBRQd1bmkyMEE5B3VuaTIyMTkHdW5pMjA1Mgd1bmkyMjE1CGVtcHR5c2V0B3VuaTIxMjYHdW5pMjIwNgd1bmkwMEI1B2Fycm93dXAHdW5pMjE5NwphcnJvd3JpZ2h0B3VuaTIxOTgJYXJyb3dkb3duB3VuaTIxOTkJYXJyb3dsZWZ0B3VuaTIxOTYJYXJyb3dib3RoCWFycm93dXBkbgxhcnJvd3VwLmNhc2UPYXJyb3dyaWdodC5jYXNlDmFycm93ZG93bi5jYXNlDmFycm93bGVmdC5jYXNlB3VuaTI1QzYHdW5pMjVDNwlmaWxsZWRib3gHdW5pMjVBMQd0cmlhZ3VwB3VuaTI1QjYHdHJpYWdkbgd1bmkyNUMwB3VuaTI1QjMHdW5pMjVCNwd1bmkyNUJEB3VuaTI1QzEHdW5pMjExMwllc3RpbWF0ZWQHdW5pMjExNgZtaW51dGUGc2Vjb25kB2F0LmNhc2UMdW5pMjExNi5zczAxDGFtcGVyc2FuZC5zYwd1bmkwMzA4C3VuaTAzMDgwMzAwC3VuaTAzMDgwMzAxC3VuaTAzMDgwMzA0B3VuaTAzMDcLdW5pMDMwNzAzMDQJZ3JhdmVjb21iC3VuaTAzMDAwMzA0CWFjdXRlY29tYgt1bmkwMzAxMDMwNwt1bmkwMzAxMDMwNAd1bmkwMzBCDWNhcm9uY29tYi5hbHQHdW5pMDMwMgd1bmkwMzBDC3VuaTAzMEMwMzA3B3VuaTAzMDYHdW5pMDMwQQt1bmkwMzBBMDMwMQl0aWxkZWNvbWILdW5pMDMwMzAzMDgTdGlsZGVjb21iX2FjdXRlY29tYgt1bmkwMzAzMDMwNAd1bmkwMzA0C3VuaTAzMDQwMzA4C3VuaTAzMDQwMzAwC3VuaTAzMDQwMzAxDWhvb2thYm92ZWNvbWIHdW5pMDMwRgd1bmkwMzExB3VuaTAzMTIHdW5pMDMxQgxkb3RiZWxvd2NvbWIHdW5pMDMyNAd1bmkwMzI2B3VuaTAzMjcHdW5pMDMyOAd1bmkwMzJFB3VuaTAzMzEHdW5pMDMzNQd1bmkwMzM2B3VuaTAzMzcHdW5pMDMzOAx1bmkwMzA4LmNhc2UQdW5pMDMwODAzMDAuY2FzZRB1bmkwMzA4MDMwMS5jYXNlEHVuaTAzMDgwMzA0LmNhc2UMdW5pMDMwNy5jYXNlEHVuaTAzMDcwMzA0LmNhc2UOZ3JhdmVjb21iLmNhc2UQdW5pMDMwMDAzMDQuY2FzZQ5hY3V0ZWNvbWIuY2FzZRB1bmkwMzAxMDMwNy5jYXNlEHVuaTAzMDEwMzA0LmNhc2UMdW5pMDMwQi5jYXNlDHVuaTAzMDIuY2FzZQx1bmkwMzBDLmNhc2UQdW5pMDMwQzAzMDcuY2FzZQx1bmkwMzA2LmNhc2UOdGlsZGVjb21iLmNhc2UQdW5pMDMwMzAzMDguY2FzZRh0aWxkZWNvbWJfYWN1dGVjb21iLmNhc2UQdW5pMDMwMzAzMDQuY2FzZQx1bmkwMzA0LmNhc2UQdW5pMDMwNDAzMDguY2FzZRB1bmkwMzA0MDMwMC5jYXNlEHVuaTAzMDQwMzAxLmNhc2USaG9va2Fib3ZlY29tYi5jYXNlDHVuaTAzMEYuY2FzZQx1bmkwMzExLmNhc2UMdW5pMDMzNS5jYXNlDHVuaTAzMzcuY2FzZQx1bmkwMzM4LmNhc2UTdW5pMDMwNC5uYXJyb3cuY2FzZQl1bmkwMzA3LmkJdW5pMDMyOC5pEHVuaTAzMDgubG9jbFZJRVQQdW5pMDMwNy5sb2NsVklFVBJncmF2ZWNvbWIubG9jbFZJRVQSYWN1dGVjb21iLmxvY2xWSUVUEHVuaTAzMDIubG9jbFZJRVQQdW5pMDMwQy5sb2NsVklFVBB1bmkwMzA2LmxvY2xWSUVUEnRpbGRlY29tYi5sb2NsVklFVBB1bmkwMzA0LmxvY2xWSUVUFmhvb2thYm92ZWNvbWIubG9jbFZJRVQOdW5pMDMwOC5uYXJyb3cOdW5pMDMwMi5uYXJyb3cOdW5pMDMwNi5uYXJyb3cQdGlsZGVjb21iLm5hcnJvdw51bmkwMzA0Lm5hcnJvdw51bmkwMzExLm5hcnJvdxNjYXJvbmNvbWIuYWx0LnNob3J0CXVuaTAzMzUudAd1bmkwMkJDB3VuaTAyQkIHdW5pMDJCQQd1bmkwMkM5B3VuaTAyQ0IHdW5pMDJCOQd1bmkwMkJGB3VuaTAyQkUHdW5pMDJDQQd1bmkwMkNDB3VuaTAyQzgKdW5pMDMzNS5zYwp1bmkwMzM2LnNjCnVuaTAzMzguc2MLYnJldmVjb21iY3kQYnJldmVjb21iY3kuY2FzZQtkZXNjZW5kZXJjeRBkZXNjZW5kZXJjeS5jYXNlFmRlc2NlbmRlcmN5LmNhc2Uuc2hvcnQRZGVzY2VuZGVyY3kuc2hvcnQLdW5pMDMwNjAzMDELdW5pMDMwNjAzMDALdW5pMDMwNjAzMDkLdW5pMDMwNjAzMDMLdW5pMDMwMjAzMDELdW5pMDMwMjAzMDALdW5pMDMwMjAzMDkLdW5pMDMwMjAzMDMQdW5pMDMwNjAzMDEuY2FzZRB1bmkwMzA2MDMwMC5jYXNlEHVuaTAzMDYwMzA5LmNhc2UQdW5pMDMwNjAzMDMuY2FzZRB1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AAMAAAAAAAMAAwADAAMACAADAAAAAAAAAAAAGwAAAAD/9gAAAAAACAAAAAAAAAAA/+wAAAAAAAAAAAAAAAAAAAAAAAAAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/+QAAAAAAAAAAAAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/2AAAAAAAHAAAAAP/2AAD/9AAAAAAAAAAAAAAAAAAAAAAAAAAA/8cAAAAAAAAAAAAAAAAAAAAHAAAABwAAAAAAAAAAAAD//QAAAAAAAAAAAAP/9gAIAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkAAP/2AAAAAAAKAAoAAAAA//YAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/7QAAAAAAAwAAAAoAAAAKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//bAAoAAAAAAAMAAwADAAMAAwADAAAAAAAAAAAAEwAAAAD/9gAAAAAAAAAAAAD/9gAA/+wAAAAAAAAAAAAAAAAAAAAAAAAAAP+/AAAAAAAAAAAAAAAAAAAAAAAAAAcAAP/2//YAAAAN/+7/qQAAAAD/2//5/9j/3gAA//kAAAADAAAAAwAAAAMAAAAK//YACAAA/+z/9v/s//P//QAAAAcAAAADAAD/6QAAAAf/9gAHAAAAAAAAAAAAAAAA/9YAAAAAAAAAAAAAAAAAAAAAAAcAAP/2AAAAAAAAAAD/8QAAAAAAAAAA//H/2AAA/+b/9AAAAAAAAAAAAAAAAAAAAAD//QAAAAD/5wAAAAD/4gAAAAAAAAAAAAAAAAAAAAAAAP/5AAcAAAAAAAAAAAAAAAAAJgAIAAgAAAAAAAAAAAAAAAAAAP/s/+8AAAAAAAAAAAAKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIQAAAAAAHAAAAAAAAwAAAAAAAAAAAA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAsAAAAAAAAAAAAAAADAAAAAAAA/+//9wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAmAAAAAAAAAAAAAAAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/58AAAAAAAD/wQADAAMAAwAAAAD/9wABAAMAA//xAAD/8/9/AAAAAP/BAAD/y//YAAr/7f/u/+//7v/v/8n/7P/2AAD/8//bAGMACgAD/9gACgAHAAr/9AAD//n/9v/iAAD/9gAD//MACgAAAAAAAAAA/+0AAAAAAAAAAAAKAAD/+QAAAAAAAP/O/84ACgAAAAAACgAAAAAAAAAAAAD/zv/lAAD/lQAAABcAAAAXAAAAAAAAAAAAAAAAAAr/4v/xAAAAAAAAAAD/7QAA//kAAAAU//EAAAAAAAP//f/2//AACgAAAAD/4v/lAAD//QAA//kAAAAAAAAAAAAAAAAAAAAAABMAAAAAAAAAAAAAAAAAAP/YAAD/5QAA/6QADAAAAAwAAAAAAAoAAAAAAAAAAP/iAAAAAAAAAAAAAP/vAAAAAP/zAAD/7AAAAAAAAAAAAAAAAAAA//kAAP/v/6IACAAI//3/xgAAAAAAAAAAAAP/1QAA//b/2//yAAD/1f+oAAAAAP/EAAP/ewAA/+YAAP/pAAD/7AAA/94AAP/sAAP/1f/pACgAAAAU/9oAAAAAADL/0P/9/9j/4v/OAAj/7f/z/9//1QAAAAAAAAAAAAr/xwAAAAAAA//iAAAAAAAAAAAAAAAAAAAAAAAK//QAAAAA/9gAAAAA/8QAKgAA/6QAAAAA/+L/6v/i/+r/2//lAAAAAAAAAAAAFAAAAAD/zgAAAAAAIAAAAAD/4AAA/+wAAAAAAAAAAAAAAAAAAAAAAAD/9AA0AAAAAAAAAAAAAwADAAMAAP/7/9v/2wAAAAMAAAAlACUAJQAAAAAAKP/uACUAHv/i/+AAHAAAABwAAAAAAAAADAAKACoAJ//MABMAFAATAAwAJQAAAAAAAwAAAD4AAAAAAAAAAP/5//sAAAAgAAAAAAAAABsAAAAAAAAAAAADAAAAAwAAAAAAAAAAAAAAAwAAAAAAAAAaAAAAAAAA/+wAAAATAAD/4wAAAAAAAAAAAAAAAAAAAAAAAAAA//kAAAAAAAAAAAAAAAAAAAAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//QANAAAAAAAAAAAAAMAAwADAAAAAP/H/9EAAAADAAAAAAAvACUAAAAAACj/7gAlAB7/4v/gABwAAAAcAAAAAAAAAAAACgAbABT/zAARAAoAIQAUAAoAAAAAAAMAAAAvAAgAAAAAAAD/9gAAAAAACgAAAAAAAAAbAAAAAAAAAAAAAwAAAAMAAAAAAAAAAAAAAAMAAAAAAAAAGgAAAAAAAP/sAAAAHgAA/+MAAAAAAAAAAAAAAAAAAAAAAAAAAP/lAAAAAAAAAAAAAAAAAAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/qADwACAADAAoAFAAIAAAACAAH//3/2P/vAAAAAwAAABYALwAuAAAAAAAb/8kAIAAq/9X/3gAAAAAAAAAAAC0AAAAaAAAAMQAl/8QAEQAeACUAFgA0//kABwADAAAATQAUAAD/7AAA//kAAwAAACoAAAAAAAAAHgAAAAAAAAAAAAMAAAADAAAAAAAAAAAAAAADAAAAAAAAABoAAAAAAAD/7AAAAB4AAP/gAAAAAAAAAAAAAAAeAAAAAAAAAAD/7AAAAAAAAAAAAAAAAAAAAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/2wAaAB4AJv/xAC//7f+//+0AAP/i/73/sP/P/+3/7P/iAB4AAAAhACYAAP+fAAD/7f+1/8cAMQAHADQAGwA8AB4ADP/sAAwAAP+8AAD/4gAvAAD/6f+G/+wAAP+8AAAAKP/2AAD/+f/Y/+kAAAAA/98AAAAA/34AHAAcAAoAAAAAAAsACAAKAC//5QAIAAoAAAAAAA3/+P+5AAMADv/lAAr/8//sAAAAAAAAAAAAAAAA//kAAAAAABsAAP/+AIEAGwA8/84AIAAbAAD/7AAAAAD//f/2ABH/+QAH//YAAAAAAAoAAAACABAGJQYsAAAGLgY4AAgGOgY6ABMGPAY8ABQGPgY+ABUGQAZAABYGQgZCABcGRAZEABgGRgZGABkGTAZOABoGUQZwAB0GlAaWAD0GmAaYAEAGoQahAEEG2gbbAEIHPgc+AEQAAgA7BiYGJwALBigGKAADBikGKgAPBisGKwAEBiwGLAAGBi4GLgAPBi8GLwAQBjAGMAASBjEGMgAYBjMGMwADBjQGNAAaBjUGNQAbBjcGOAAMBjoGOgAaBjwGPAABBj4GPgABBkAGQAANBkIGQgACBkQGRAACBkYGRgAOBkwGTgALBlEGUQAMBlIGUgAJBlMGUwALBlQGVAAJBlUGVQALBlYGVgAPBlcGVwAUBlgGWAAWBlkGWQAUBloGWgAWBlsGWwAPBlwGXAAIBl0GXQAMBl4GXgAIBl8GXwAMBmAGYAAFBmEGYQAHBmIGYgAKBmMGYwALBmQGZAAKBmUGZQALBmYGZgAPBmcGZwARBmgGaAATBmkGaQAZBmoGagAPBmsGawAVBmwGbAAXBm0GbQAVBm4GbgAXBm8GbwAPBnAGcAAZBpQGlAAaBpUGlgALBpgGmAALBqEGoQALBtoG2wAYBz4HPgAUAAIAZgXABcAALQXBBcEAEgXCBcIAKgXDBcMAJwXEBcQADAXFBcUACgXGBcYALQXHBccAJAXIBcgANgXJBckAOAXKBcoANQXLBcsAMAXMBcwAKwXNBc0AKAXOBc4ADQXPBc8ACwXQBdAALQXRBdEAJQXSBdIANgXTBdMAEQYlBiUAAgYmBicALwYoBigABQYpBioAFwYrBisALgYsBiwACAYuBi4AFwYvBi8AGAYwBjAAGgYxBjIAIAYzBjMABQY0BjQAJgY1BjUALAY2BjYAAgY3BjgAEAY6BjoAJgY9Bj0AAwY+Bj4ANwY/Bj8AAwZBBkEAFAZDBkMABAZFBkUABAZHBkcAFQZMBk4ALwZRBlEAEAZSBlIALwZTBlMADgZUBlQALwZVBlUADgZWBlYAFwZXBlcAHAZYBlgAHgZZBlkAHAZaBloAHgZbBlsAFwZcBlwAEAZdBl0ANAZeBl4AEAZfBl8ANAZgBmAABwZhBmEACQZiBmIALwZjBmMADwZkBmQALwZlBmUADwZmBmYAFwZnBmcAGQZoBmgAGwZpBmkAIQZqBmoAFwZrBmsAHQZsBmwAHwZtBm0AHQZuBm4AHwZvBm8AFwZwBnAAIQZ8BnwAMwZ/Bn8AMwaBBoEAMwaEBoQAMwaFBoUAMgaGBoYAMwaIBogAMwaKBosAMwaMBowAIgaNBo0AMgaQBpAAMwaRBpEAMQaUBpQAJgaVBpYALwaYBpgALwahBqIALwaqBqoALwatBq4AFgbLBssAAQbMBswAEwbNBs0AIwbQBtAAKQbRBtEABgbaBtsAIAbeBt4AOQc+Bz4AHAACDHAABAAADHoMqgASAFgAAP/7//3//f/b//b/+//v/+r/6v/9AAf/4v/4//P/9gAK//b/7P/7AAP/+QAKAAcABAAD//r/9v/9AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/2/9X/9gAA//n/9P/4AAD/9v/2AAD/8//2AAAAAAAAAAAAAAAAAAAAAP/4AAD/+AAA//3////0//sAB//z//v/+//9AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAA8AAP/5AAD/8wAA//EAAAAA/9sAFAAAAAAACgAAAAAAAAAAAAAAAAAAAAAAAwAA//YAAAAHAAAAAAAAAAAAAAAAABT/+f/9AA8ACv/9/+8AKP/2AAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//5/8z/zP/L//j/qf/5/+z/zgAA/+//4gAU/8sACv/p/+IAAAAV//3/7gAI//P/9gAIABT/4v/9AAr/0f/0//3//gAK//kAHAAUAAAAAAAbAAAAFAAU//YAFAAHAAoACgAKAAoACv/5AA3/5//u//YAAv/s//4ABwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABUAAAAmAAj/4P/J/8f/+f+/AA3/7P/HABIAC//iABv/yQAA/+n/2wAAAAD/8//p//wACv/sABQAHv/YAAAABwAAAAAAAAAr//b//AAbADz/+f/MACj/9wAVAAD/9AAKAAsAFAAHAAAAAwAKAAAAAwAA/+X/4gAA/+X/9AAM//0ACwAU//0AAwAK//EACgAFAAr//QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAAAAL/7P/s/+//6f/5/+IAAAAA/9sAAP/4//YACv/iAAD/+QAAAAAAAAAAAAD/+AAA//0AAAAC/+wAAAAAAAAAAAAAAAAAAAAAAAcAAAAAAAAAFAAAAAAAAP/2AAAAAAAHAAAAAAAKAAAAAAAAAAD//QAAAAoAAP/4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/0//QAAP/2AAD/9gAAAAD/+QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/8AAAP/l/+8AAAAKAAX//QAI//kAGwAK/+v/7wAD/8wAD//CAAoAHgAA//YADf/+AAr/7QANAAP/1QAG/+7/7AAA//gAAP/v/+7/+f/a/+wAAAAA/9YAAP/i//0AAP/g/+z/7AAA/+7/zv/zAAD/zgAKABsAFP/0ACgAEgAAAAAAAP/lAAAAAP/vAAD/4gAA/+X/7P/u//YAAQAB/7//7//i/+j/9P/5/+X//QAAAAD/1QAA/+r/4AALAAoAAP/x//n/9AAo/+X/+AAAAAr/2wAK/9sAFAAUAAAAAAAXABQAC//9//kAA//bABwAAP/5AAAAAAAAAAAAAAAA//P/9AAA//n/7P/3/+8AAP/5/+MAAQAAAAAAAP/sAAAAAP/uAAAAFAAKAB4AHgAOAAcAAAAAAAD/9v+4//kACv/9AAD/+QAAAAD/+QAA//QAAAAAAAD//f/3AAAAAP/5//EAAAAHAAAAAP/n//b/9P/2//n/9AAA//QAAP/4/+z/7AAKAAAAAP/2//kAAAAU//3/9f/v//EAAP/9AAr/7QAAAAD/+QAAAAD/+QAAAAAAAAAAAAD/+QAK//kAAAAA//kACgAAAAoAAAAAAAUAAAAAAAgAAAAAAAAAAAAA//0AAAAAAAAAAAAAAAAAAP/9AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAA/+X/+QAA//b/9v/2AAAAAAAA//r/7P/2AAAAAAAAAAD/9gAAAAAAB//5AAz/8wAAAAD//f/x//YAAP/0//v/+wACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAAAA0AAP/5AAD/+QAA//EAAAAA/+UAAAAHAAAACv/sAAAAAAAAAAAAAAAAAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABH/+QAAABEACgAA//YACv/7AAoAAAAAAAAAAAAHAAAAAAAAAAAAAAAAAAAAAP/2AAAAAAAAAAAAAAAAAAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAADQAD//kAAP/0AAD/7wAAAAD/+QAAAA0ACgAKAAAAAAAAAAAAAAAAABQAAwAH//kAAAAAAAMAAAAAAAD//QAAAAAACAAAAAAAAAAAAAAAAAAKAAAAHgAAAAD/+QAAAAAAAAAA//kAAAAA//YAAAAAAAAAAAAAAAoAAwAAAAAAAAAAAAAAAAAAAAAAAP/5//0AAAAAAAAAAP/tAAAAAAAAAAAAAP/9AAAAAAAA//4AAAAIAAP/9v/z/+z/+f/x//kAAP/gAAAACP/9AAP/7AAA//kAAAAAAAAAAAAAAAD/+f/5AAMACP/5AAAAAAAAAAAAAAALAAAAAAAHAAMAAP/9ABT/+QAXAAAAAP/3AAIACgAAAAAAAAAKAAAAAAAAAAD/9gAKAAD//QAAAAAAAAAAAAD/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/+P/2/+n/zv/s//H/5//f/9//7QAH/+z/+P/iAAD/9P/s/+IAAAAHAAAAAAABAAf//f/2//T/8//0AAMAAAAA//n/9v/9//QAAAAAAAAAAAAAAAD/7AAA/+wAAAAAAAAAAAAAAAAAAAAHAAAAAAAA//0AAAAAAAoAAP/2//0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAAAAKAAoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAeAAAAAAAAAAAAAAAAAAAAAAAA//sAAP/x/9P/4v/d/9r/5P/V//T/9v/R//j/6f/s//P/2P/2//n/+f/5AAAAAP/+//b/+f/i//P/+f/vAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/9AAD/8f/2AAD/9gAAAAAAAAAAAAAABwAKAAAAAAAA//b/9gAA/+L/8//5AAAAAAAA//7/9gAAAAAAAP/9//kAAAAAAAAAAAAAAAAAAAAHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/9AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgABBcAF1AAAAAEFwAAVAA4AEQAMAAoAAwABAAkABwAAAA4AEAAGAA0ACwAEAAIACQAIAAAABQAPAAIBOAAEAB8AAQAhACcAJQBKAFEAJQBoAGkAAwCEAKYAJQCpAKkAJQCyALQAJgC2AL0AJgC/AL8AJQDAAMYABQDHAN4AQADfAOQABwDlAOUACADmAO8ACQDwAPQACgD2AQ8ASwEQAREAAQEUASoALgErASsASwEsATMAJQE0ATQAAgE2AUQAAgFFAUYABAFVAVYAJQFXAV0ABgFeAXoAQAF7AYQALwGFAYkACgGKAaUAJwGnAcwAOAHQAdcAOAHeAe4AUgHvAfEADQH1AfUAUgH/AgsAUgIMAi4AOAIvAi8AUgIxAjEAOAIyAjkAUgI6AjwARwI+AkUARwJIAk8APAJQAmcAVQJoAm0AGAJuAm4AGgJvAngAGAJ5An0ASQJ/ApgAOAKZApoAJwKbArMAOAK+Ar4AOALHAtQAVQLVAtkASQLaAtoABQLbAtwAPALeAt4APALfAvoAHQL8AwIAIAMhAyEAIAMlAywAIANFA0YAJANgA4IAIAOFA4UAIAOOA5AAVAOSA5kAVAObA6IAFwO7A8AAGQPBA8EAHAPCA8sAPgPMA9AAPwPRA+oATAPuBAQAMwQFBAUAIAQGBAYAVgQHBA4AIAQgBCEADgQvBC8AIAQwBDcAFwRfBGMAPwRkBGUACwRmBGYAAQRwBHAACAR7BHsAJQR+BH4AJQR/BH8ABQSABIEACASCBIIAJQSDBIMACASKBIoABQSOBI4AJgSPBI8AJQSTBJMAAwSUBJQABQSWBJYACASXBJgABQSZBJkACASaBJoAJQSbBJsABwSeBJ4ACASjBKMABQSoBKkAJQSqBKoABQSrBKwACQStBK0ACASuBK4ABQS2BLYACAS8BL4AAQTABMEAJQTCBMIACATHBMkAJQTLBM0ACATSBNMACATUBNQALgTWBNYAJQTXBNcABwTdBN0AAQTeBN4AJQThBOIAJQTjBOMASwTlBOcALgTtBO0ASwTuBO4ABgTvBPAALwTxBPEAJQTyBPIAQATzBPMABQT0BPQAQAT3BPcABAT5BPkABgT6BPsASwT8BPwAAQT9BP0ALgUABQIALwUEBQQAJQUFBQUAQAUGBQYAJwUHBQcAJQUIBQsAUgUNBQ8AOAUQBRAAGgUSBRcAUgUZBRoAUgUbBRsAOAUcBR0AUgUeBR4AOAUgBSEAGAUiBSIAOAUjBSMAGgUkBSQAVQUlBSkAUgUrBSsAUgUtBS0AUgUuBS4ARwUvBS8AOAUxBTIAUgUzBTMADQU1BTUAUgU2BTYAGgU5BTkAGgU6BToAOAU7BTsAGAU9BT0AUgU+BT4AGgVABUEAUgVEBUcAUgVIBUkAOAVLBUwAGAVNBU0AGgVPBVAAVQVWBVYAGgVXBVcAUgVZBVoAUgVbBVsAVQVcBVwAUgVdBV8AJwVgBWIAOAVjBWMAGgVmBWcAUgVoBWoAOAVsBW4AGAVvBW8AVQVwBXIAUgVzBXQAGgV3BXcAOAV4BXgAGAV6BXoAUgV7BXsADQV9BX0AOAV+BX4ARwV/BX8AOAWABYAAGgWCBYQAVQWHBYkAUgWKBY4AVQWRBZEAUgWTBZMAOAWUBZQAUgWWBZYAUgWXBZcAOAWYBZkAVQWaBZ4AOAWfBaIAVQWlBacAVQWpBakAVQWrBasAUgWtBa4AOAWvBa8AJwWwBbEAOAWzBbgAVQW6BboAAQW+Bb4AAQXABcAASgXBBcEAOQXCBcIAIwXDBcMAIgXEBcQATwXFBcUAHwXGBcYASgXHBccAIQXIBcgANAXJBckANwXKBcoAVwXLBcsARgXMBcwASAXNBc0ALAXOBc4ARAXPBc8AQwXQBdAASgXRBdEAKgXSBdIANAXTBdMAKQYkBiQACwYlBiUADAYmBicANQYoBigAMQYpBioAEAYrBisAQQYsBiwAQgYuBi4AEAYvBi8AEQYwBjAAEgYxBjIAFAYzBjMAMQY0BjQAKwY1BjUALQY2BjYADAY3BjgAUQY6BjoAKwY9Bj0ATQY/Bj8ATQZDBkMATgZFBkUATgZHBkcAUwZMBk4ANQZRBlEAUQZSBlIANQZTBlMARQZUBlQANQZVBlUARQZWBlYAEAZXBlcAEwZYBlgAOwZZBlkAEwZaBloAOwZbBlsAEAZcBlwAUQZdBl0AUAZeBl4AUQZfBl8AUAZiBmIANQZkBmQANQZmBmYAEAZqBmoAEAZvBm8AEAZ5BnkAJQZ6BnoAOAZ7BnsAJQZ8BnwAMgZ9Bn0AJgZ+Bn4AOAZ/Bn8AMgaABoAAKAaBBoEAMgaCBoIAJQaEBoQAMgaFBoUANgaGBoYAMgaIBogAMgaKBosAMgaMBowAFQaNBo0ANgaQBpAAMgaRBpEAGwaUBpQAKwaVBpYANQaYBpgANQahBqIANQanBqcAAQaqBqoANQarBqsAUgatBq4ADwbKBsoAJQbLBssAMAbMBswAOgbNBs0AFgbOBs8AJQbQBtAAPQbRBtEAHgbXBtcAJQbaBtsAFAbcBtwAJQc+Bz4AEwACAAgACgAaBJgFCjDQQfBOrlTMbU6FfI8WAAEAsgAEAAAAVAQKAV4BaAGGAYYBhgGGAYYBhgGGAbQBtAG0AbQBtAG0Af4B/gH+Af4B/gH+Af4B/gH+Af4ENAIoAigCKAIoAigCKAIoA44ClgJCA6oCjAJQAmICcAJ+AowClgKgAs4C3AOOA5wDqgPcBF4EXgReBFgEWAPuBE4D9AROA/4D/gQEBFgEWARYBFgEWARwBHAEWARYBAoENAQ0BE4EWARYBFgEWAReBF4EcAABAFQASQCUAKkAwADBAMIAwwDEAMUAxgDfAOAA4QDiAOMA5ADmAOcA6ADpAOoA6wDsAO0A7gDvASsBVwFYAVkBWgFbAVwBXQGgAbABygHPAd4B4gHjAeoB7QHvAfgB/gIxAkoCTAJkArQDhQRkBGUGJAYmBicGMAY0BjUGOgY8Bj4GQAZMBk0GTgZTBlUGVwZZBmMGZQaBBoUGjQaUBpUGlgaYBqEG2AbdBz4AAgYlAAYGNgAGAAcGNAApBjUAKAY6ACkGPQAIBj8ACAZHAAMGlAApAAsB4QAZ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//YAAAAAAAAAAAAAAAAAAAAAAAD/7wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAAAAAAoAAAAA//YAAAAAAAAAAAAAAAAAAAAA//YAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/s//cAAAAAAAAAAAAAAAD/+QAAAAAAAAAAAAD/9QAA//cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//kAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//0AAP/2AAAAAAAAAAAAAAAA//sAAAAA//0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//kAAAAAAAAAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/j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ACMCmQKaAE0CmwKzACMCtAK9AG8CvgK+ACMCvwLGAG8CxwLUADoC1QLZAEMC2gLaAAYC2wLcADMC3gLeADMC3wL6AE4C+wL7AFUC/AMCACQDAwMgAFUDIQMhACQDJAMkAFUDJQMsACQDLQNEAFUDRQNGAB8DRwNfAFUDYAOCACQDgwOEAFUDhQOFACQDhgONAFUDjgOQAFcDkgOZAFcDmwOiADQDowO6ADsDuwPAAD4DwQPBAEADwgPLAEEDzAPQAFoD0QPqAE8D7QPtAFUD7gQEABQEBQQFACQEBgQGAFIEBwQOACQEDwQRAFsEEgQSAFUEEwQbAFsEHAQcAFUEHQQfAFsEIAQhACAEIgQuAFUELwQvACQEMAQ3ADQEOARUADsEVQReAEIEXwRjAFoEZARlAA0EZgRmAEYEZwRrAGsEbARsAEcEbQRvAGsEcARwAAoEcQRxAEsEcgR3AGsEeAR4AEcEeQR6AGsEewR7AAUEfAR9AGsEfgR+AAUEfwR/AAYEgASBAAoEggSCAAUEgwSDAAoEhASEAAEEhQSJAGsEigSKAAYEiwSLAGsEjASMAEcEjQSNAGsEjgSOAEwEjwSPAAUEkASQAEsEkQSSAGsEkwSTAAMElASUAAYElQSVAGsElgSWAAoElwSYAAYEmQSZAAoEmgSaAAUEmwSbAAkEnQSdAGsEngSeAAoEnwSfAEsEoASiAGsEowSjAAYEpASnAGsEqASpAAUEqgSqAAYEqwSsAAsErQStAAoErgSuAAYErwSwAAEEsQSyAGsEswS0AAIEtQS1AGsEtgS2AAoEtwS5AGsEugS6AAEEuwS7AGsEvAS+AEYEvwS/AGsEwATBAAUEwgTCAAoEwwTEAEsExQTGAGsExwTJAAUEygTKAEsEywTNAAoEzgTOAAEEzwTRAGsE0gTTAAoE1ATUAEoE1QTVAEcE1gTWAAUE1wTXAAkE2ATaAGsE2wTcAEcE3QTdAEYE3gTeAAUE3wTfAGsE4QTiAAUE4wTjAFwE5ATkAF4E5QTnAEoE6ATrAGsE7ATsAEkE7QTtAFwE7gTuAAcE7wTwAAwE8QTxAAUE8gTyAAgE8wTzAAYE9AT0AAgE9QT1AEcE9gT2AGsE9wT3AAQE+QT5AAcE+gT7AFwE/AT8AEYE/QT9AEoE/gT/AGsFAAUCAAwFBAUEAAUFBQUFAAgFBgUGAE0FBwUHAAUFCAULAGUFDAUMAEgFDQUPACMFEAUQAD8FEQURAFEFEgUXAGUFGAUYAEgFGQUaAGUFGwUbACMFHAUdAGUFHgUeACMFHwUfADUFIAUhAD0FIgUiACMFIwUjAD8FJAUkADoFJQUpAGUFKgUqADUFKwUrAGUFLAUsAEgFLQUtAGUFLgUuAC4FLwUvACMFMAUwAFEFMQUyAGUFMwUzAGQFNAU0AG0FNQU1AGUFNgU2AD8FNwU3AG8FOAU4ADUFOQU5AD8FOgU6ACMFOwU7AD0FPAU8ABkFPQU9AGUFPgU+AD8FPwU/AFEFQAVBAGUFQgVCAG8FQwVDADUFRAVHAGUFSAVJACMFSgVKADUFSwVMAD0FTQVNAD8FTgVOADUFTwVQADoFUQVSAG8FUwVUABEFVQVVAG8FVgVWAD8FVwVXAGUFWAVYAEgFWQVaAGUFWwVbADoFXAVcAGUFXQVfAE0FYAViACMFYwVjAD8FZAVlAFEFZgVnAGUFaAVqACMFawVrAFEFbAVuAD0FbwVvADoFcAVyAGUFcwV0AD8FdQV1AFYFdgV2AEgFdwV3ACMFeAV4AD0FeQV5AC8FegV6AGUFewV7AGQFfAV8AEgFfQV9ACMFfgV+AC4FfwV/ACMFgAWAAD8FgQWBAFEFggWEADoFhQWFAG8FhgWGAEgFhwWJAGUFigWOADoFjwWPADUFkAWQAG8FkQWRAGUFkgWSAFEFkwWTACMFlAWUAGUFlQWVAA8FlgWWAGUFlwWXACMFmAWZADoFmgWeACMFnwWiADoFowWjAG4FpQWnADoFqAWoABwFqQWpADoFqgWqAEgFqwWrAGUFrQWuACMFrwWvAE0FsAWxACMFswW4ADoFuQW5AC8FugW6AEYFvgW+AEYFvwW/AGsFwAXAAEQFwQXBACUFwgXCAFkFwwXDADYFxAXEABcFxQXFAFMFxgXGAEQFxwXHADAFyAXIABUFyQXJACEFygXKAEUFywXLACYFzAXMADkFzQXNADcFzgXOABgFzwXPAFQF0AXQAEQF0QXRADEF0gXSABUF0wXTACIGJAYkAA0GJQYlAA4GJgYnAB0GKAYoABIGKQYqACgGKwYrAGAGLAYsABYGLgYuACgGLwYvACkGMAYwACoGMQYyAC0GMwYzABIGNAY0ADIGNQY1ADwGNgY2AA4GNwY4AB4GOgY6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BSMAEwUkBSQAQAUlBSkAPwUrBSsAPwUtBS0APwUuBS4AGwUvBS8AGQUxBTIAPwUzBTMAPQU1BTUAPwU2BTYAEwU3BTcAPgU5BTkAEwU6BToAGQU7BTsAEQU9BT0APwU+BT4AEwVABUEAPwVCBUIAPgVEBUcAPwVIBUkAGQVLBUwAEQVNBU0AEwVPBVAAQAVRBVIAPgVVBVUAPgVWBVYAEwVXBVcAPwVZBVoAPwVbBVsAQAVcBVwAPwVdBV8ACgVgBWIAGQVjBWMAEwVmBWcAPwVoBWoAGQVsBW4AEQVvBW8AQAVwBXIAPwVzBXQAEwV3BXcAGQV4BXgAEQV6BXoAPwV7BXsAPQV9BX0AGQV+BX4AGwV/BX8AGQWABYAAEwWCBYQAQAWFBYUAPgWHBYkAPwWKBY4AQAWQBZAAPgWRBZEAPwWTBZMAGQWUBZQAPwWWBZYAPwWXBZcAGQWYBZkAQAWaBZ4AGQWfBaIAQAWlBacAQAWpBakAQAWrBasAPwWtBa4AGQWvBa8ACgWwBbEAGQWzBbgAQAW6BboAAQW+Bb4AAQXBBcEAKwXCBcIAOQXDBcMAOAXEBcQAJwXHBccANQXKBcoAPAXLBcsALAXMBcwAOgXOBc4AKAXPBc8AJgXRBdEANgYkBiQADAYlBiUAHwYmBicAKgYoBigAIgYpBioALwYrBisAIwYuBi4ALwYvBi8AMAYwBjAAMQYxBjIANAYzBjMAIgY0BjQANwY1BjUAOwY2BjYAHwY6BjoANwY9Bj0AIAY/Bj8AIAZBBkEALQZDBkMAIQZFBkUAIQZHBkcALgZMBk4AKgZSBlIAKgZUBlQAKgZWBlYALwZYBlgAMwZaBloAMwZbBlsALwZgBmAAJAZhBmEAJQZiBmIAKgZjBmMAKQZkBmQAKgZlBmUAKQZmBmYALwZoBmgAMgZqBmoALwZvBm8ALwZ5BnkAFQZ6BnoAGQZ7BnsAFQZ9Bn0AFgZ+Bn4AGQaCBoIAFQaUBpQANwaVBpYAKgaYBpgAKgahBqIAKganBqcAAQaqBqoAKgarBqsAPwbKBsoAFQbOBs8AFQbXBtcAFQbaBtsANAbcBtwAFQACAJ4ABAAAAKwAsAABAEcAAP+j//n/9AAKAB4AKAAh//YAFAAK/6j/9v/2ABQAAwAHAB4ABwAUABH/7P/5//P/2QARAA0AEf/2//0AUAAg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AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9AAA//D/8AAAAAD/7f/3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/8f/q//f/9AAA/+0AAP/s//P/9//w//cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKACUABwAA//b/9gAA/+n/+f/bAAAAAAAAAAAAHgAAAAAAFAAAAAcAAP/9//kAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwAAAAAACP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABf/9AAAABQAFAAAAAoAAAAUAAoABwAAAAAADf/2AAAAFAAAAAAAAwAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAACP/2AAAACAAAAAAAAwAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKAAoAFAAA/+z/7AAA/+L/9v/YAAoAAABkAEQAFAAKAAAACAAAAAD/9gAA//YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAEQAAAAAACAADAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/zAAD/6QAA//T/7wAA/9//1v/WAAAAEf/0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA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ABIFhQWFAAQFhwWJAAgFkAWQAAkFkgWSABIFlAWUAAsFlQWVAAkFnAWeAAEFowWjAAkFrwWwAAEFsQWxAAkGiQaJAAwAAgFrAAQAHwBMACAAIABNACEAJwAwACgARgBNAEcASABIAEkASQBNAEoAUQAwAFIAZwBNAGoAgwBNAIQApgAwAKcAqABNAKkAqQAwAKoAsQBNALIAtABOALYAvQBOAL8AvwAwAMAAxgACAMcA3gAxAN8A5AAyAOUA5QA2AOYA7wAzAPUA9QBNAPYBDwABARABEQBMARIBEwBNASsBKwABASwBMwAwATUBNQBNAUUBRgBJAUcBSABNAUoBVABNAVUBVgAwAVcBXQBKAV4BegAxAYoBpQA3AaYBpgATAacBzAAWAc4BzgAPAdAB1wAWAdgB3QATAd4B7gBCAe8B8QBBAfIB9AATAfUB9QBCAfYB/gATAf8CCwBCAgwCLgAWAi8CLwBCAjACMAATAjECMQAWAjICOQBCAjoCPABFAj4CRQBFAkYCRgATAkgCTwAjAlACZwBGAmgCbQApAm4CbgAqAm8CeAApAnkCfQArAn8CmAAWApkCmgA3ApsCswAWArQCvQATAr4CvgAWAr8CxgATAscC1ABGAtUC2QArAtoC2gACAtsC3AAjAt4C3gAjBGQEZQAEBGYEZgBMBGcEawBNBGwEbAA1BG0EbwBNBHAEcAA2BHEEcQBIBHIEdwBNBHgEeAA1BHkEegBNBHsEewAwBHwEfQBNBH4EfgAwBH8EfwACBIAEgQA2BIIEggAwBIMEgwA2BIQEhAAuBIUEiQBNBIoEigACBIsEiwBNBIwEjAA1BI0EjQBNBI4EjgBOBI8EjwAwBJAEkABIBJEEkgBNBJQElAACBJUElQBNBJYElgA2BJcEmAACBJkEmQA2BJoEmgAwBJsEmwAyBJ0EnQBNBJ4EngA2BJ8EnwBIBKAEogBNBKMEowACBKQEpwBNBKgEqQAwBKoEqgACBKsErAAzBK0ErQA2BK4ErgACBK8EsAAuBLEEsgBNBLMEtAAvBLUEtQBNBLYEtgA2BLcEuQBNBLoEugAuBLsEuwBNBLwEvgBMBL8EvwBNBMAEwQAwBMIEwgA2BMMExABIBMUExgBNBMcEyQAwBMoEygBIBMsEzQA2BM4EzgAuBM8E0QBNBNIE0wA2BNUE1QA1BNYE1gAwBNcE1wAyBNgE2gBNBNsE3AA1BN0E3QBMBN4E3gAwBN8E3wBNBOEE4gAwBOME4wABBOQE5ABHBOgE6wBNBO0E7QABBO4E7gBKBPEE8QAwBPIE8gAxBPME8wACBPQE9AAxBPUE9QA1BPYE9gBNBPcE9wBJBPkE+QBKBPoE+wABBPwE/ABMBP4E/wBNBQQFBAAwBQUFBQAxBQYFBgA3BQcFBwAwBQgFCwBCBQwFDAAOBQ0FDwAWBRAFEAAqBREFEQAPBRIFFwBCBRgFGAAOBRkFGgBCBRsFGwAWBRwFHQBCBR4FHgAWBR8FHwAkBSAFIQApBSIFIgAWBSMFIwAqBSQFJABGBSUFKQBCBSoFKgAkBSsFKwBCBSwFLAAOBS0FLQBCBS4FLgBFBS8FLwAWBTAFMAAPBTEFMgBCBTMFMwBBBTUFNQBCBTYFNgAqBTcFNwATBTgFOAAkBTkFOQAqBToFOgAWBTsFOwApBT0FPQBCBT4FPgAqBT8FPwAPBUAFQQBCBUIFQgATBUMFQwAkBUQFRwBCBUgFSQAWBUoFSgAkBUsFTAApBU0FTQAqBU4FTgAkBU8FUABGBVEFUgATBVMFVAAJBVUFVQATBVYFVgAqBVcFVwBCBVgFWAAOBVkFWgBCBVsFWwBGBVwFXABCBV0FXwA3BWAFYgAWBWMFYwAqBWQFZQAPBWYFZwBCBWgFagAWBWsFawAPBWwFbgApBW8FbwBGBXAFcgBCBXMFdAAqBXUFdQBEBXYFdgAOBXcFdwAWBXgFeAApBXkFeQAgBXoFegBCBXsFewBBBXwFfAAOBX0FfQAWBX4FfgBFBX8FfwAWBYAFgAAqBYEFgQAPBYIFhABGBYUFhQATBYYFhgAOBYcFiQBCBYoFjgBGBY8FjwAkBZAFkAATBZEFkQBCBZIFkgAPBZMFkwAWBZQFlABCBZUFlQAGBZYFlgBCBZcFlwAWBZgFmQBGBZoFngAWBZ8FogBGBaUFpwBGBagFqABLBakFqQBGBaoFqgAOBasFqwBCBa0FrgAWBa8FrwA3BbAFsQAWBbMFuABGBbkFuQAgBboFugBMBb4FvgBMBb8FvwBNBcAFwAAsBcEFwQAXBcIFwgAoBcMFwwAlBcQFxAAQBcUFxQA/BcYFxgAsBccFxwAhBcgFyAANBckFyQAUBcoFygAtBcsFywAYBcwFzAA7Bc0FzQAm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D4oPig+KCrAPig+KD4oPig+KD4oPig+KD4oKqg+KD4oPig+KD4oPig+KD4oPig+KD4oPig+KD4oPigugD4oLjguUCg4LoA+KD4oPig+KChQPigoaD4oLuA+KD4oKIA+KD4oPig+KD4oPigomD4oPigrCCiwKzg+KD4oKMgo4Cj4Pig+KD4oPigpED4oPig+KD4oPigv0D4oLUgtYC6wLZAtqD4oPigsoD4oPig+KD4oK1A+KD4oOOg+KC74Pig+KD4oPigpKD4oPig+KD4oKUA+KD4oKVg+KClwPig+KCtoPigrgCuYPigraD4oKYgrmD4oPig+KD4oPig+KD4oPig+KD4oPigvED4oLyg+KD4oOOg+KCmgKbg+KCnQPigp6CoAPigqGD4oKjAqSD4oPig+KD4oPig+KCpgPigqeCqQPig+KD4oKqg+KD4oPig+KCrAPig+KD4oPig+KD4oPig+KD4oPig+KD4oKtg+KCrwPig+KCrYPigq8D4oPigrCCsgKzg+KD4oPig+KCtQPig+KCtoPigrgCuYPigrsD4oK8g+KD4oK/gsECvgPig+KCv4LBAsKD4oPigsQD4oLFg+KD4oLHAsiCygPig+KD4oPigsuD4oPig+KD4oLNA+KD4oPig+KCzoPig+KDjoPigtAD4oPig+KD4oLRg+KD4oPig+KC0wPig+KC1ILWAteC2QLagtSC1gLrAtkC2oLUgtYC14LZAtqD4oPigtwD4oPig+KD4oLdg+KD4oPig+KC3wPig+KD4oPiguCD4oPig+KD4oLiA+KD4oPig+KC7gPig+KC44LlAuaC6APig+KD4oLpg+KD4oPig+KC6wPig+KD4oPig+KC7IPig+KD4oPig+KD4oPig+KC7gPig+KDjoPigu+D4oPigvED4oLyg+KD4oLxA+KC8oPig+KDXoMEgwMD4oPigweDCQMKg+KD4oMHgwkC9APig+KDB4MJAvWD4oPigw2DDwMDA+KDEgMNgw8DAwPigxIDDYMPAwMD4oMSAw2DDwL3A+KDEgPig+KD4oPig+KC/oPigwADAYPigxaD4oL4g+KD4oMWg+KC+IPig+KD4oPigvoD4oPig+KD4oL7g+KD4oPig+KD4oL9A+KC/oPigwADAYPig16DBIMDA+KD4oNegwSDEIPig+KDvQPigwYD4oPigweDCQMKg+KD4oMNgw8DDAPigxIDDYMPAxCD4oMSAxaD4oMTg+KD4oMWg+KDFQPig+KDFoPigxgD4oPig+KD4oMZg+KD4oPig+KD4oMbA+KDYwNkg2GD4oPigxyD4oMeA+KD4oPig+KDigPig+KD4oPig6UD4oPig2qDbANtg+KD4oNqg2wDH4Pig+KDaoNsAyED4oPig+KD4oNdA+KD4oOfA+KDoIPig+KD4oPigyKD4oPig+KD4oMig+KD4oPig+KDJAPig+KD4oPigyWD4oPig+KD4oPNg+KD4oPig+KDJwPig+KD4oPig+KD4oPig16D4oNgA+KD4oOWA+KDl4OZA+KDdoN4A28DewN8g+KD4oPig+KD4oMog+KDKgPig+KDogPig6OD4oPig0gD4oNJg0sD4oOFg+KDK4Pig+KDhYPigyuD4oPig+KD4oPig+KD4oPig+KDTgPig+KD4oPig+KD4oPig+KD4oPig+KD4oPig+KD4oONA+KD4oPigy0DjQPig+KD4oPigy6D4oMwA+KDMYPig+KDMwPig+KD4oPig+KD4oOgg+KD4oNXAzSDNgPig+KDpoOoAzeD4oPig+KD4oM5A+KD4oM6g+KDPAM9g6CD4oPig34D4oPig+KD4oM/A+KD4oPig+KDXQPig+KDnwPig6CD4oPig+KD4oPNg+KD4oNAg+KDQgPig+KDQ4Pig0UD4oPig5YD4oOXg5kD4oOWA+KDRoOZA+KD4oPig+KD4oPig6ID4oOjg+KD4oNIA+KDSYNLA+KD4oPig+KDTIPig+KD4oPig0yD4oPig+KD4oPig+KD4oPig04D4oPig+KD4oNPg+KD4oOag+KDWINRA1KDVAPig1WD4oPig1QD4oNVg+KD4oNXA+KDWINaA1uD4oPig10D4oPig+KD4oPig+KD4oOWA+KDl4OZA+KDXoPig2AD4oPig2MDZINhg+KD4oNjA2SDZgPig+KDZ4Pig2kD4oPig2qDbANtg+KD4oN2g3CDbwPig+KDdoNwg3mD4oPig+KD4oNyA+KD4oOfA+KDgQPig+KD4oPig3OD4oPig+KD4oN1A+KD4oN2g3gDeYN7A3yD4oPig34D4oPig+KD4oN/g+KD4oPig+KDgQPig+KDhYPig4KD4oPig4WD4oOEA+KD4oOFg+KDhwPig+KD4oPig4iD4oPig+KD4oOKA+KD4oPig+KDi4ONA+KD4oPig+KD4oPig46D4oOQA+KD4oORg+KDkwPig+KD4oPig+KD4oPig+KD4oOxA+KD4oPVA9aDtYPig9mD1QPWg7WD4oPZg9UD1oO4g+KD2YPig+KDlIPig+KDlgPig5eDmQPig5qD4oOcA+KD4oO9A+KD4oPig+KD4oPig+KD4oPig9UD1oO1g+KD2YPig+KDnYPig+KD4oPig52D4oPig58D4oOgg+KD4oOiA+KDo4Pig+KD4oPig6UD4oPig6aDqAOpg+KD4oPig+KDtYPig+KDqwOsg9sD4oOuA+KD4oOvg+KD4oPDA8SDwYPig+KD4oPig7ED4oPig8kDyoPMA+KD4oPJA8qDsoPig+KDyQPKg7QD4oPig9UD1oO1g+KD2YPVA9aDtYPig9mD1QPWg7cD4oPZg9UD1oO4g+KD2YO6A+KDu4Pig+KDvQPig+KD4oPig94D4oO+g+KD4oPeA+KDvoPig+KD4oPig8AD4oPig8MDxIPBg+KD4oPDA8SDxgPig+KD4oPig8eD4oPig8kDyoPMA+KD4oPPA9CDzYPig+KDzwPQg9ID4oPig9UD1oPTg+KD2YPVA9aD2APig9mD3gPig9sD4oPig94D4oPcg+KD4oPeA+KD34Pig+KD4oPig+ED4oPigABAX0AAAABAUoDUwABAWUDUwABAWUDOQABAZoDUwABAZoCvAABAWcDUwABAfICvAABAogCSgABAUoAAAABAYMAAAABAUACvAABANAAAAABAJsAAAABAM0AAAABAJsDOQABAQoCvAABAWcCvAABAX0CvAABAfAAAAABAfACvQABA0QCvAABAS8CvAABAS8BUwABAU4AAAABAU4CvAABAUsA+QABAUQAAAABAUQCvAABAUEA+QABAS4AAAABAS4CvAABAS4BUwABAVUCvAABAVQCvAABAlUAAAABAk8CvwABAJ8AAAABANEAAAABAJ8CvAABAgQCvAABAZkAAAABAZkCvAABAZkCKQABAeEAAAABAeECvAABAXsCvAABAXsAAAABAuoAAAABAXsDOQABAhwAAAABAhwCvAABAW8AAAABAmkAAAABAWUCvAABAZ0CvAABAZ0DOQABAgQDOQABAT8DOQABAZoDNQABAZoDOQABAagAAAABAfUAAAABAagDOQABAagBXgABAoECvAABAUADOQABAVQDNQABAVQDOQABAVQDUwABAVUDOQABA0MAAAABA3QAAAABAfIDOQABAK4CSgABAWYCvAABAagCvAABAMcCSgABAUoCvAABAT8CvAABAZYAAAABAZ8CvAABAV4DUwABAV4DOQABAY8DUwABAYoCvAABAfECvAABAOwCvAABAQ4CSgABATwAAAABAT4CvAABATsBSgABAY8CvAABAr0AAAABAhQCvAABAV4AAAABAlEAAAABAV4CvAABAY8DNQABAYgAAAABArEAAAABAY8DOQABAo4CvAABAYoDNQABAYoDOQABApcAAAABAYoDUwABAfEDOQABAMMCSgABATgAAAABATgCEwABATUCvQABATUCowABAVUCEgABAVUCvQABAVUCswABATQCvQABAYIAAAABAW4CEgABARACEgABAaACEgABAgEBugABAQsAAAABAQsCEgABATkAAAABAL0AAAABAI0CxQABAIsCowABAI4CxQABAVsAAAABAJAC5gABAMMCeQABATMCEAABAUEAAAABAUECEgABAYoAAAABAYoCEgABArECEAABAPgAAAABAPgCEgABAPgA/AABAR4ABQABARQCEgABARMCEgABAMgCegABAQQCEgABAdAAAAABAcoCEAABAI0AAAABAI0C5gABAI0BZgABARYC5gABAagCEgABAY8AAAABAY8CEgABASECEgABAR8AAAABAf0AAAABASECowABAdkAAAABAc0CEgABATUAAAABAgkAAAABATUCEgABAT8CEgABAGsCEgABAagCowABAVUCnwABAVUCowABAT8AAAABAaIAAAABAT8CowABAT8BCQABAcgCEgABAUUCEgABAUUCowABAQcCowABARACnwABARACowABAaAAAAABARACvQABARQCowABASMCEAABAaACowABAJoBugABAS8AAAABAUICEgABAdQAAAABAdQCEgABATECEgABAVIAAAABAVICEgABAVIBpgABAVkAAAABAVkCEgABAgYCEAABAPsAAAABAQcCEgABAToAAAABAS4CEgABASMCuwABAIsAAAABALsAAAABAIsCnwABAVAAAAABAkkAAAABAhoCEgABAgYCnQABAUgCEgABATACvQABATACowABAUYCEgABAUYCswABAUYCvQABAWkAAAABAVYCEgABAhQAAAABAVACEgABAZUCEgABAU8CEgABAU8AAAABAk8AAAABAU8CowABAeUCEgABATAAAAABAb0AAAABATACEgABATQCEgABATQAAAABAKcCEgABATQCowABAUYCnwABAUcAAAABAkAAAAABAUYCowABAhECEgABAVACnwABAVACowABApUAAAABAVACvQABAZUCowABAAAAAAAJAAAAAQAIAAEABAAAA7wABgEAAAEACAABAAwAHAABACoASgABAAYG/wcABwEHAgcEBwUAAQAFBv8HAAcBBwQHBQAGAAAAGgAAABoAAAAaAAAAGgAAABoAAAAaAAH+1AAAAAUAEgAMABIAGAAeAAH+1P9qAAH+1P9vAAH+1P9jAAH+1P9yAAYCAAABAAgAAQF6AAwAAQGgAEAAAgAIBt8G6gAABuwG/QAMBwoHJAAeB0AHQQA5B0UHRQA7B0gHSgA8B0wHUQA/B1MHVABFAEcAkACuAK4ArgKSAJYAugCuALoAnACuALoAwADAAsAAwACiAKIAwACuAK4ArgCoAK4ArgCuALQAugDAAMYAzADqAOoA6gDSANgA9gDqAPYA3gDqAPYA/AD8At4A/AD8AOoA6gDqAOQA6gDqAOoA8AD2APwBFAEOAQ4BDgEgASABIAECAQgBDgEOARQBGgEgAAH+1AKjAAH+1AMwAAH+1AMxAAH+1AL9AAH+1AKfAAH+1AMtAAH+1AMDAAH+1AK9AAH+1AKzAAH+1ALfAAH+1AM5AAH+1ANSAAH+1APGAAH+1APHAAH+1AM1AAH+1APDAAH+1AOZAAH+1ANTAAH+1ANJAAEBLAKjAAEBLAK8AAEBLAK9AAEBLAKfAAEBLAL9AAEBLAKzAAYCAAABAAgAAQAMACgAAQAyAWoAAgAEBt8G6gAABuwG/QAMBwoHJAAeB14HbQA5AAIAAQdeB20AAABJAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABMgAAATIAAAEyAAABMgAAATIAAAEyAAABMgAAATIAAAEyAAABMgAAATIAAAEyAAABMgAAATIAAAEyAAABMgAAATIAAAEyAAABMgAAATIAAAEyAAABJgAAATIAAAEyAAABMgAAATIAAAEyAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEyAAABMgAAATIAAAEyAAABMgAAATIAAAEyAAABMgAB/tQCuwAB/tQCEgAB/tQCvAAQACgAKAAiACgALgAuADQAOgBGAEYAQABGAEwATABSAFgAAf7UAyUAAf7UAxoAAf98AvcAAf9WAwsAAf7UAyAAAf7UA7sAAf7UA7AAAf98A40AAf9WA6EAAf7UA7YAAQAMACIABQEKAq4AAgADBt8G6gAABuwHJwAMB14HbQBIAAIAJgAEAEgAAABKAH8ARQCBAKYAewCpALQAoQC2AL0ArQC/ANoAtQDcAN4A0QDgAOQA1ADmAPQA2QD2ASoA6AEsATYBHQE4AVABKAFSAVQBQQFWAaUBRAGnAa4BlAGwAc4BnAHQAdYBuwHYAgcBwgIJAjwB8gI+AkUCJgJIAm0CLgJvAn0CVAJ/ArMCYwK1AtkCmALfAyMCvQMlAzUDAgM3A1sDEwNdA4IDOAOFA5ADXgOSA5kDagObA7YDcgO4A7oDjgO8A8ADkQPCBAUDlgQHBBED2gQTBCoD5QQsBC4D/QQwBGMEAABYAAIBmAACAZgAAgGYAAIBmAACAZgAAgGYAAIBmAACAZgAAgGYAAIBmAACAZgAAgGYAAIBmAACAZgAAgGYAAIBmAACAZgAAgGYAAIBmAACAZgAAgGYAAIBmAACAZgAAgGYAAIBmAACAZgAAgGYAAIBmAACAZgAAgGYAAQBmAAAAWgAAAFoAAABaAAAAWgAAQFiAAABaAAAAWgAAwFuAAMBdAADAYwAAwF6AAIBngACAZ4AAgGeAAIBngACAZ4AAgGeAAIBngACAZ4AAgGeAAIBngACAZ4AAgGeAAIBngACAZ4AAgGeAAIBngACAZ4AAgGeAAIBngACAZ4AAgGeAAIBgAACAZ4AAgGeAAIBngACAZ4AAgGeAAMBhgADAYwAAwGSAAIBmAACAZgAAgGYAAIBmAACAZgAAgGYAAIBmAACAZgAAgGeAAIBngACAZ4AAgGeAAIBngACAZ4AAgGeAAIBngAB/tUAAAAB/tQAAAAB/tQBtgAB/kwBtgAB/soBCgAB/tQCuwAB/tQBZAAB/ycBggAB/mMBXgAB/tQCEgAB/tQCvAQ0KlIqWCpGPJQ8lCpSKlgqNDyUPJQqUipYKl48lDyUKlIqWCoQPJQ8lCouKlgqXjyUPJQqUipYKhA8lDyUKlIqWCoKPJQ8lCpSKlgqEDyUPJQqUipYKl48lDyUKlIqWCpePJQ8lCpSKlgqFjyUPJQqLipYKl48lDyUKlIqWCoWPJQ8lCpSKlgqHDyUPJQqUipYKiI8lDyUKlIqWCo0PJQ8lCpSKlgqKDyUPJQqLipYKkY8lDyUKlIqWCo0PJQ8lCpSKlgqOjyUPJQqUipYKl48lDyUKlIqWCpAPJQ8lCpSKlgqRjyUPJQqUipYKkw8lDyUKlIqWCpMPJQ8lCpSKlgqXjyUPJQuWjyULlQ8lDyULlo8lC5gPJQ8lCpkPJQqajyUPJQqgjyUKnA8lDyUKoI8lCp2PJQ8lCqCPJQqfDyUPJQqgjyUKnA8lDyUKoI8lCp2PJQ8lCqCPJQqfDyUPJQqgjyUKog8lDyUM0w8lCrQLn48lCqOPJQqlC5+PJQqmjyUKqAqpjyUM0w8lCqsLn48lCqyPJQquCq+PJQqxDyUKtAufjyUKso8lCrQLn48lCrWPJQq3C5+PJQrHiskKxg8lDyUKx4rJDjaPJQ8lCseKyQrKjyUPJQrHiskKyo8lDyUKx4rJCsqPJQ8lCseKyQrKjyUPJQrHiskKuI8lDyUKwArJCsqPJQ8lCseKyQq4jyUPJQrHiskKug8lDyUKx4rJCruPJQ8lCseKyQ42jyUPJQrHiskKvQ8lDyUKx4rJCr6PJQ8lCsAKyQrGDyUPJQrHiskONo8lDyUKx4rJCsGPJQ8lCseKyQrKjyUPJQrHiskKww8lDyUKx4rJCsSPJQ8lCseKyQrEjyUPJQrHiskKxg8lDyUKx4rJCsqPJQ8lCs2PJQrMDyUPJQrNjyUKzw8lDyULDg8lC72PJQ8lCw4PJQu2DyUPJQsODyULtg8lDyULDg8lC7YPJQ8lCwgPJQu9jyUPJQsODyULuQ8lDyULDg8lC7qPJQ8lCw4PJQu9jyUPJQsODyULDIrWjyUK0I8lCtIK048lCtUPJQsMitaPJQsODyULD4rWjyULDg8lCw+K1o8lCwgPJQsMitaPJQriiuQK948lDyUPJQ8lCtgPJQ8lCuKK5ArxjyUPJQriiuQK5Y8lDyUK4orkCuWPJQ8lCuKK5ArxjyUPJQriiuQK2Y8lDyUK4orkCtsPJQ8lCuKK5ArcjyUPJQreCuQK948lDyUK4orkCvGPJQ8lCuKK5ArfjyUPJQriiuQK5Y8lDyUK4orkCuEPJQ8lCuKK5Ar3jyUPJQriiuQK5Y8lDyUPJQ8lCucPJQ8lDyUPJQrojyUPJQrqDyUK7o8lDyUK6g8lCuuPJQ8lCu0PJQrujyUPJQvUDyUK94vXC9iL1A8lCvAL1wvYi9QPJQrxi9cL2IvUDyUK94vXC9iK8w8lCveL1wvYi9QPJQr3i9cL2IrzDyUK94vXC9iL1A8lCvSL1wvYivYPJQr3i9cL2Ir5DyUK+or8Cv2K/w8lCwIPJQ8lCwCPJQsCDyUPJQsODyULDI8lDyULDg8lCwOPJQ8lCw4PJQsFDyUPJQsODyULD48lDyULCA8lCwyPJQ8lCw4PJQsGjyUPJQsIDyULDI8lDyULDg8lCwmPJQ8lCwsPJQsMjyUPJQsODyULD48lDyULIAshiyqLJIsmCyALIYsdCySLJgsgCyGLHoskiyYLIAshix6LJIsmCyALIYsRCySLJgsYiyGLHoskiyYLIAshixELJIsmCyALIYsSiySLJgsgCyGLFAskiyYLIAshix0LJIsmCyALIYsViySLJgsgCyGLIwskiyYLIAshixcLJIsmCxiLIYsqiySLJgsgCyGLHQskiyYLIAshixoLJIsmCyAPJQsqjyUPJQsgDyULHQ8lDyULGI8lCyqPJQ8lCyAPJQsdDyUPJQsgDyULGg8lDyULIA8lCx6PJQ8lCyALIYsdCySLJgsgCyGLHoskiyYLIAshixuLJIsmCyALIYsjCySLJgsgCyGLIwskiyYPJQ8lCyqPJQ8lCyALIYsqiySLJgsgCyGLHQskiyYLIAshix6LJIsmCyALIYsjCySLJgsgCyGLIwskiyYLIAshiyMLJIsmCyePJQspDyUPJQ8lDyULKo8lDyULLw8lCzOPJQ8lCy8PJQssDyUPJQsvDyULMI8lDyULLY8lCzOPJQ8lCy8PJQssDyUPJQstjyULM48lDyULLw8lCzCPJQ8lCzIPJQszjyUPJQs7DyULPI8lDyULOw8lCzUPJQ8lCzsPJQs2jyUPJQs7DyULOY8lDyULOw8lCzgPJQ8lCzsPJQs8jyUPJQs7DyULOY8lDyULPg8lCzyPJQ8lCzsPJQs/jyUPJQs+DyULPI8lDyULPg8lCz+PJQ8lDhEPJQtBDyUPJQtEDyULSItKDyULRA8lC0iLSg8lC0QPJQtCi0oPJQtEDyULSItKDyULRY8lC0iLSg8lC0WPJQtIi0oPJQtHDyULSItKDyULWQtai06PJQtdi1kLWotRjyULXYtZC1qLV48lC12LWQtai1ePJQtdi1kLWotXjyULXYtZC1qLUY8lC12LWQtai0uPJQtdi00LWotOjyULXYtZC1qLUY8lC12LWQtai1APJQtdi1kLWotOjyULXYtZC1qLUY8lC12LTQtai06PJQtdi1kLWotRjyULXYtZC1qLUA8lC12LWQtai1ePJQtdi1kLWotRjyULXYtZC1qLV48lC12LWQtai1MPJQtdi1kLWotUjyULXYtZC1qLVg8lC12LWQtai1ePJQtdi1kLWotcDyULXYtjjyULXw8lDyULY48lC2UPJQ8lC2OPJQtgjyUPJQtjjyULYg8lDyULY48lC2UPJQ8lC3EPJQtrC3QPJQtxDyULbIt0DyULcQ8lC3KLdA8lC3EPJQtmi3QPJQtxDyULaAt0DyULaY8lC2sLdA8lC3EPJQtsi3QPJQtxDyULbgt0DyULcQ8lC2+LdA8lC3EPJQtyi3QPJQt4jyULfQ8lDyULeI8lC3WPJQ8lC3iPJQt3DyUPJQt4jyULeg8lDyULe48lC30PJQ8lC5CLkguNjyUPJQuQi5ILiQ8lDyULkIuSC5OPJQ8lC5CLkguADyUPJQuHi5ILk48lDyULkIuSC4APJQ8lC5CLkgt+jyUPJQuQi5ILgA8lDyULkIuSC5OPJQ8lC5CLkguTjyUPJQuQi5ILgY8lDyULh4uSC5OPJQ8lC5CLkguBjyUPJQuQi5ILgw8lDyULkIuSC4SPJQ8lC5CLkguJDyUPJQuQi5ILhg8lDyULh4uSC42PJQ8lC5CLkguJDyUPJQuQi5ILio8lDyULkIuSC5OPJQ8lC5CLkguMDyUPJQuQi5ILjY8lDyULkIuSC48PJQ8lC5CLkguPDyUPJQuQi5ILk48lDyULlo8lC5UPJQ8lC5aPJQuYDyUPJQuZjyULmwufjyULnI8lC54Ln48lC7GLswuwDyUPJQuxi7MLqg8lDyULsYuzC7SPJQ8lC7GLswu0jyUPJQuxi7MLtI8lDyULsYuzC7SPJQ8lC7GLswuhDyUPJQuoi7MLtI8lDyULsYuzC6EPJQ8lC7GLswuijyUPJQuxi7MLpA8lDyULsYuzC6oPJQ8lC7GLswuljyUPJQuxi7MLpw8lDyULqIuzC7APJQ8lC7GLswuqDyUPJQuxi7MLq48lDyULsYuzC7SPJQ8lC7GLswutDyUPJQuxi7MLro8lDyULsYuzC66PJQ8lC7GPJQuwDyUPJQuxi7MLtI8lDyULvA8lC72PJQ8lC7wPJQu2DyUPJQu8DyULtg8lDyULvA8lC7YPJQ8lC7ePJQu9jyUPJQu8DyULuQ8lDyULvA8lC7qPJQ8lC7wPJQu9jyUPJQvMi84Lyw8lDyUPJQ8lC78PJQ8lC8yLzgvGjyUPJQvMi84Lz48lDyULzIvOC8+PJQ8lC8yLzgvGjyUPJQvMi84LwI8lDyULzIvOC8IPJQ8lC8yLzgvDjyUPJQvFC84Lyw8lDyULzIvOC8aPJQ8lC8yLzgvIDyUPJQvMi84Lz48lDyULzIvOC8mPJQ8lC8yLzgvLDyUPJQvMi84Lz48lDyUPJQ8lC9EPJQ8lDyUPJQvSjyUPJQvUDyUL1YvXC9iL2g8lC90PJQ8lC9uPJQvdDyUPJQvpDyUL548lDyUL6Q8lC96PJQ8lC+kPJQvgDyUPJQvpDyUL6o8lDyUL4w8lC+ePJQ8lC+kPJQvhjyUPJQvjDyUL548lDyUL6Q8lC+SPJQ8lC+YPJQvnjyUPJQvpDyUL6o8lDyUL7A8lC+2PJQ8lDNYPJQvzi/UPJQzWDyUL84v1DyUM1g8lC+8L9Q8lDNYPJQvzi/UPJQvwjyUL84v1DyUL8I8lC/OL9Q8lC/IPJQvzi/UPJQwEDAWL/48lDAiMBAwFi/sPJQwIjAQMBYwCjyUMCIwEDAWMAo8lDAiMBAwFjAKPJQwIjAQMBYv7DyUMCIwEDAWL9o8lDAiL+AwFi/+PJQwIjAQMBYv7DyUMCIwEDAWL+Y8lDAiMBAwFi/+PJQwIjAQMBYv7DyUMCIv4DAWL/48lDAiMBAwFi/sPJQwIjAQMBYv5jyUMCIwEDAWMAo8lDAiMBAwFi/sPJQwIjAQMBYwCjyUMCIwEDAWL/I8lDAiMBAwFi/4PJQwIjAQMBYv/jyUMCIwEDAWMAQ8lDAiMBAwFjAKPJQwIjAQMBYwHDyUMCIwOjyUMCg8lDyUMDo8lDBAPJQ8lDA6PJQwLjyUPJQwOjyUMDQ8lDyUMDo8lDBAPJQ8lDBwPJQwWDyUPJQwcDyUMF48lDyUMHA8lDB2PJQ8lDBwPJQwRjyUPJQwcDyUMEw8lDyUMFI8lDBYPJQ8lDBwPJQwXjyUPJQwcDyUMGQ8lDyUMHA8lDBqPJQ8lDBwPJQwdjyUPJQ6SDyUMI48lDyUOkg8lDB8PJQ8lDpIPJQwgjyUPJQ6SDyUMIg8lDyUOiQ8lDCOPJQ8lDnoMNYwyjyUPJQ56DDWMLg8lDyUOegw1jDcPJQ8lDnoMNYwmjyUPJQ59DDWMNw8lDyUOegw1jCaPJQ8lDnoMNYwlDyUPJQ56DDWMJo8lDyUOegw1jDcPJQ8lDnoMNYw3DyUPJQ56DDWMKA8lDyUOfQw1jDcPJQ8lDnoMNYwoDyUPJQ56DDWMKY8lDyUOegw1jCsPJQ8lDnoMNYwuDyUPJQ56DDWMLI8lDyUOfQw1jDKPJQ8lDnoMNYwuDyUPJQ56DDWML48lDyUOegw1jDcPJQ8lDnoMNYwxDyUPJQ56DDWMMo8lDyUOegw1jDQPJQ8lDnoMNYw0DyUPJQ56DDWMNw8lDyUMOg8lDDiPJQ8lDDoPJQw7jyUPJQxBjyUMPQ8lDyUMQY8lDD6PJQ8lDEGPJQxADyUPJQxBjyUMPQ8lDyUMQY8lDD6PJQ8lDEGPJQxADyUPJQxBjyUMQw8lDyUMRI8lDyUNQ41FDESPJQ8lDUONRQxEjyUPJQ1DjUUMRg8lDyUNQ41FDEePJQ8lDUONRQxJDyUMSo1DjUUO1AxeDFOPJQ8lDtQMXgxVDyUPJQ7UDF4MX48lDyUO1AxeDF+PJQ8lDtQMXgxfjyUPJQ7UDF4MX48lDyUO1AxeDEwPJQ8lDgUMXgxfjyUPJQ7UDF4MTA8lDyUO1AxeDE2PJQ8lDtQMXgxPDyUPJQ7UDF4MVQ8lDyUO1AxeDFCPJQ8lDtQMXgxSDyUPJQ4FDF4MU48lDyUO1AxeDFUPJQ8lDtQMXgxWjyUPJQ7UDF4MX48lDyUO1AxeDFgPJQ8lDtQMXgxZjyUPJQ7UDF4MWY8lDyUMWw8lDFyPJQ8lDtQMXgxfjyUPJQxhDGKMZA8lDyUMZw8lDGWPJQ8lDGcPJQxojyUPJQ8lDyUMag8lDyUPJQ8lDGuPJQ8lDyUPJQxrjyUPJQ8lDyUMa48lDyUPJQ8lDG0PJQ8lDyUPJQxujyUPJQ8lDyUMcA8lDyUOkg8lDWkMdIx2DpIPJQ1pDHSMdgxxjyUNaQx0jHYOkg8lDIyMdIx2DpIPJQxzDHSMdg6JDyUNaQx0jHYM3AyDjIIPJQ8lDNwMg4x3jyUPJQzcDIOMfY8lDyUM3AyDjIUPJQ8lDNwMg4yFDyUPJQzcDIOMfY8lDyUM3AyDjHkPJQ8lDNwMg4x6jyUPJQzcDIOMfA8lDyUM2oyDjIIPJQ8lDNwMg4x9jyUPJQzcDIOMfw8lDyUM3AyDjIUPJQ8lDNwMg4ySjyUPJQzcDIOMgI8lDyUM3AyDjIIPJQ8lDNwMg4yFDyUPJQ8lDyUMho8lDyUPJQ8lDIgPJQ8lDyUPJQyJjyUPJQyLDyUNaQ8lDI+Miw8lDIyPJQyPjI4PJQ1pDyUMj44LDyUMkQ8lDyUM3A8lDWkNaoyUDNwPJQ1hjWqMlAzcDyUNaQ1qjJQM2o8lDWkNaoyUDNwPJQ1pDWqMlAzajyUNaQ1qjJQM3A8lDJKNaoyUDN8PJQ1pDWqMlAyVjyUMlwyYjJoMm48lDyUPJQ8lDJ0PJQ8lDyUPJQ6SDyUMp48lDyUOkg8lDJ6PJQ8lDKAPJQyhjyUPJQ6SDyUMqQ8lDyUOiQ8lDKePJQ8lDpIPJQyjDyUPJQ6JDyUMp48lDyUOkg8lDKSPJQ8lDKYPJQynjyUPJQ6SDyUMqQ8lDyUMxYzHDL4MygzLjMWMxwy7DMoMy4zFjMcMxAzKDMuMxYzHDMQMygzLjMWMxwyqjMoMy4yyDMcMxAzKDMuMxYzHDKqMygzLjMWMxwysDMoMy4zFjMcMrYzKDMuMxYzHDLsMygzLjMWMxwyvDMoMy4zFjMcMyIzKDMuMxYzHDLCMygzLjLIMxwy+DMoMy4zFjMcMuwzKDMuMxYzHDLOMygzLjLmPJQzXjyUPJQy5jyUMto8lDyUMtQ8lDNePJQ8lDLmPJQy2jyUPJQy5jyUMuA8lDyUMuY8lDMQPJQ8lDMWMxwy7DMoMy4zFjMcMxAzKDMuMxYzHDLyMygzLjMWMxwzIjMoMy4zFjMcMyIzKDMuMxY8lDL4Mygy/jMWMxwzBDMoMy4zFjMcMwozKDMuMxYzHDMQMygzLjMWMxwzIjMoMy4zFjMcMyIzKDMuMxYzHDMiMygzLjM0PJQzOjyUPJQzQDyUM0Y8lDyUM0w8lDNSPJQ8lDNYPJQzXjyUPJQzcDyUM4I8lDyUM3A8lDNkPJQ8lDNwPJQzdjyUPJQzajyUM4I8lDyUM3A8lDNkPJQ8lDNqPJQzgjyUPJQzcDyUM3Y8lDyUM3w8lDOCPJQ8lDOgPJQzpjyUPJQzoDyUM4g8lDyUM6A8lDOOPJQ8lDOgPJQzmjyUPJQzoDyUM5Q8lDyUM6A8lDOmPJQ8lDOgPJQzmjyUPJQzrDyUM6Y8lDyUM6A8lDOyPJQ8lDOsPJQzpjyUPJQzrDyUM7I8lDyUM9A8lDPoM+4z9DO4PJQzvjPEM8oz0DyUM+gz7jP0M9A8lDPoM+4z9DPcPJQz6DPuM/Qz0DyUM9Yz7jP0M9w8lDPoM+4z9DPiPJQz6DPuM/Q23DQGNig8lDQSNtw0BjYuPJQ0EjbcNAY2RjyUNBI23DQGNkY8lDQSNtw0BjZGPJQ0EjbcNAY2LjyUNBI23DQGNhw8lDQSM/o0BjYoPJQ0EjbcNAY2LjyUNBI23DQGNjQ8lDQSNtw0BjYoPJQ0EjbcNAY2LjyUNBIz+jQGNig8lDQSNtw0BjYuPJQ0EjbcNAY2NDyUNBI23DQGNkY8lDQSNtw0BjYuPJQ0EjbcNAY2RjyUNBI23DQGNjo8lDQSNtw0BjQMPJQ0EjbcNAY2KDyUNBI23DQGNAA8lDQSNtw0BjZGPJQ0EjbcNAY0DDyUNBI0GDyUNB48lDyUNDY8lDQkPJQ8lDQ2PJQ0PDyUPJQ0NjyUNCo8lDyUNDY8lDQwPJQ8lDQ2PJQ0PDyUPJQ0bDyUNFQ8lDyUNGw8lDRaPJQ8lDRsPJQ0cjyUPJQ0bDyUNEI8lDyUNGw8lDRIPJQ8lDROPJQ0VDyUPJQ0bDyUNFo8lDyUNGw8lDRgPJQ8lDRsPJQ0ZjyUPJQ0bDyUNHI8lDyUNIQ8lDSWPJQ8lDSEPJQ0eDyUPJQ0hDyUNH48lDyUNIQ8lDSKPJQ8lDSQPJQ0ljyUPJQ05DTqNNg8lDyUNOQ06jTGPJQ8lDTkNOo08DyUPJQ05DTqNKI8lDyUNMA06jTwPJQ8lDTkNOo0ojyUPJQ05DTqNJw8lDyUNOQ06jSiPJQ8lDTkNOo08DyUPJQ05DTqNPA8lDyUNOQ06jSoPJQ8lDTANOo08DyUPJQ05DTqNKg8lDyUNOQ06jSuPJQ8lDTkNOo0tDyUPJQ05DTqNMY8lDyUNOQ06jS6PJQ8lDTANOo02DyUPJQ05DTqNMY8lDyUNOQ06jTMPJQ8lDTkNOo08DyUPJQ05DTqNNI8lDyUNOQ06jTYPJQ8lDTkNOo03jyUPJQ05DTqNN48lDyUNOQ06jTwPJQ8lDyUPJQ09jyUPJQ8lDyUNPw8lDyUNQI8lDUINQ41FDViNWg1PjyUPJQ1YjVoNUQ8lDyUNWI1aDVuPJQ8lDViNWg1bjyUPJQ1YjVoNW48lDyUNWI1aDVuPJQ8lDViNWg1GjyUPJQ1ODVoNW48lDyUNWI1aDUaPJQ8lDViNWg1IDyUPJQ1YjVoNSY8lDyUNWI1aDVEPJQ8lDViNWg1LDyUPJQ1YjVoNTI8lDyUNTg1aDU+PJQ8lDViNWg1RDyUPJQ1YjVoNUo8lDyUNWI1aDVuPJQ8lDViNWg1UDyUPJQ1YjVoNVY8lDyUNWI1aDVWPJQ8lDdmPJQ1XDyUPJQ1YjVoNW48lDyUNXQ1ejWAPJQ8lDWePJQ1pDWqNc41njyUNYY1qjXONZ48lDWkNao1zjWMPJQ1pDWqNc41njyUNaQ1qjXONYw8lDWkNao1zjWePJQ1kjWqNc41mDyUNaQ1qjXONZ48lDWkNao1zjWwPJQ1tjyUPJQ11DyUNew18jX4Nbw8lDXCNcg1zjXUPJQ17DXyNfg11DyUNew18jX4NeA8lDXsNfI1+DXUPJQ12jXyNfg14DyUNew18jX4NeY8lDXsNfI1+DYQPJQ1/jyUPJQ2EDyUNhY8lDyUNhA8lDYEPJQ8lDYQPJQ2CjyUPJQ2EDyUNhY8lDyUNkA8lDYoPJQ8lDZAPJQ2LjyUPJQ2QDyUNkY8lDyUNkA8lDYcPJQ8lDYiPJQ2KDyUPJQ2QDyUNi48lDyUNkA8lDY0PJQ8lDZAPJQ2OjyUPJQ2QDyUNkY8lDyUNlg8lDZqPJQ8lDZYPJQ2TDyUPJQ2WDyUNlI8lDyUNlg8lDZePJQ8lDZkPJQ2ajyUPJQ7UDayNqY8lDyUO1A2sjaUPJQ8lDtQNrI2uDyUPJQ7UDayNnY8lDyUOBQ2sja4PJQ8lDtQNrI2djyUPJQ7UDayNnA8lDyUO1A2sjZ2PJQ8lDtQNrI2uDyUPJQ7UDayNrg8lDyUO1A2sjZ8PJQ8lDgUNrI2uDyUPJQ7UDayNnw8lDyUO1A2sjaCPJQ8lDtQNrI2iDyUPJQ7UDayNpQ8lDyUO1A2sjaOPJQ8lDgUNrI2pjyUPJQ7UDayNpQ8lDyUO1A2sjaaPJQ8lDtQNrI2uDyUPJQ7UDayNqA8lDyUO1A2sjamPJQ8lDtQNrI2rDyUPJQ7UDayNqw8lDyUO1A2sja4PJQ8lDbEPJQ2vjyUPJQ2xDyUNso8lDyUNvQ8lDbQPJQ8lDbcPJQ6/DyUPJQ23DyUNtY8lDyUNtw8lDrePJQ8lDbcPJQ6/DyUPJQ23DyUNtY8lDyUNtw8lDrePJQ8lDbcPJQ66jyUPJQ29DyUOAg6eDyUNuI8lDboNu48lDb0PJQ39jp4PJQ2+jyUNwA3BjyUNww8lDgIOng8lDcSPJQ4CDp4PJQ3GDyUNx46eDyUN2Y3bDdgPJQ8lDdmN2w3SDyUPJQ3ZjdsN3I8lDyUN2Y3bDdyPJQ8lDdmN2w3cjyUPJQ3ZjdsN3I8lDyUN2Y3bDckPJQ8lDdCN2w3cjyUPJQ3ZjdsNyQ8lDyUN2Y3bDcqPJQ8lDdmN2w3MDyUPJQ3ZjdsN0g8lDyUN2Y3bDc2PJQ8lDdmN2w3PDyUPJQ3QjdsN2A8lDyUN2Y3bDdIPJQ8lDdmN2w3TjyUPJQ3ZjdsN3I8lDyUN2Y3bDdUPJQ8lDdmN2w3WjyUPJQ3ZjdsN1o8lDyUN2Y3bDdgPJQ8lDdmN2w3cjyUPJQ60jyUOtg8lDyUN348lDd4PJQ8lDd+PJQ3hDyUPJQ8BDyUOvw8lDyUPAQ8lDrePJQ8lDwEPJQ63jyUPJQ8BDyUOt48lDyUO9o8lDr8PJQ8lDwEPJQ66jyUPJQ8BDyUOvA8lDyUPAQ8lDr8PJQ8lDh6PJQ4dDeiPJQ3ijyUN5A3ljyUN5w8lDh0N6I8lDh6PJQ4gDeiPJQ4ejyUOIA3ojyUOGI8lDh0N6I8lDfYN9430jyUPJQ32DfeN9I8lDyUN9g33jfAPJQ8lDfYN9435DyUPJQ32DfeN+Q8lDyUN9g33jfAPJQ8lDfYN943qDyUPJQ32DfeN648lDyUN9g33je0PJQ8lDe6N9430jyUPJQ32DfeN8A8lDyUN9g33jfGPJQ8lDfYN9435DyUPJQ8lDyUOyA8lDyUN9g33jfMPJQ8lDfYN9430jyUPJQ32DfeN+Q8lDyUPJQ8lDfqPJQ8lDyUPJQ38DyUPJQ4AjyUOAg8lDyUOAI8lDf2PJQ8lDf8PJQ4CDyUPJQ4AjyUOAg8lDyUO1A8lDgmO1w7YjtQPJQ4DjtcO2I7UDyUOCY7XDtiOBQ8lDgmO1w7YjtQPJQ4JjtcO2I4FDyUOCY7XDtiO1A8lDgaO1w7YjggPJQ4JjtcO2I4LDyUODI4ODg+OEQ8lDhQPJQ8lDhKPJQ4UDyUPJQ4ejyUOHQ8lDyUOHo8lDhWPJQ8lDh6PJQ4gDyUPJQ4YjyUOHQ8lDyUOHo8lDhcPJQ8lDhiPJQ4dDyUPJQ4ejyUOGg8lDyUOG48lDh0PJQ8lDh6PJQ4gDyUPJQ4zjjUOLw44DjmOM441DiwOOA45jjOONQ4yDjgOOY4zjjUOMg44DjmOM441DiGOOA45jikONQ4yDjgOOY4zjjUOIY44DjmOM441DiMOOA45jjOONQ4kjjgOOY4zjjUOLA44DjmOM441DiYOOA45jjOONQ42jjgOOY4zjjUOJ444DjmOKQ41Di8OOA45jjOONQ4sDjgOOY4zjjUOKo44DjmOM48lDi8PJQ8lDjOPJQ4sDyUPJQ4pDyUOLw8lDyUOM48lDiwPJQ8lDjOPJQ4qjyUPJQ4zjyUOMg8lDyUOM441DiwOOA45jjOONQ4yDjgOOY4zjjUOLY44DjmOM441DjaOOA45jjOONQ42jjgOOY8lDyUOLw8lDyUOMI41DuYOOA45jjCONQ7ejjgOOY4zjjUOMg44DjmOM441DjaOOA45jjOONQ42jjgOOY4zjjUONo44DjmOOw8lDjyPJQ8lDyUPJQ4+DyUPJQ5CjyUORw8lDyUOQo8lDj+PJQ8lDkKPJQ5EDyUPJQ5BDyUORw8lDyUOQo8lDj+PJQ8lDkEPJQ5HDyUPJQ5CjyUORA8lDyUORY8lDkcPJQ8lDk6PJQ5QDyUPJQ5OjyUOSI8lDyUOTo8lDkoPJQ8lDk6PJQ5NDyUPJQ5OjyUOS48lDyUOTo8lDlAPJQ8lDk6PJQ5NDyUPJQ5RjyUOUA8lDyUOTo8lDlMPJQ8lDlGPJQ5QDyUPJQ5RjyUOUw8lDyUOVg8lDlwOXY8lDlYPJQ5cDl2PJQ5WDyUOVI5djyUOVg8lDlwOXY8lDlkPJQ5cDl2PJQ5WDyUOV45djyUOWQ8lDlwOXY8lDlqPJQ5cDl2PJQ8BDl8O/I8lDmCPAQ5fDvmPJQ5gjwEOXw7/jyUOYI8BDl8O/48lDmCPAQ5fDv+PJQ5gjwEOXw75jyUOYI8BDl8O9Q8lDmCO9o5fDvyPJQ5gjwEOXw75jyUOYI8BDl8O+A8lDmCPAQ5fDvyPJQ5gjwEOXw75jyUOYI72jl8O/I8lDmCPAQ5fDvmPJQ5gjwEOXw74DyUOYI8BDl8O/48lDmCPAQ5fDvmPJQ5gjwEOXw7/jyUOYI8BDl8O+w8lDmCPAQ5fDwQPJQ5gjwEOXw7+DyUOYI8BDl8O/48lDmCPAQ5fDwQPJQ5gjmaPJQ5iDyUPJQ5mjyUOaA8lDyUOZo8lDmOPJQ8lDmaPJQ5lDyUPJQ5mjyUOaA8lDyUOdA8lDm4PJQ8lDnQPJQ5vjyUPJQ50DyUOdY8lDyUOdA8lDmmPJQ8lDnQPJQ5rDyUPJQ5sjyUObg8lDyUOdA8lDm+PJQ8lDnQPJQ5xDyUPJQ50DyUOco8lDyUOdA8lDnWPJQ8lDnoPJQ5+jyUPJQ56DyUOdw8lDyUOeg8lDniPJQ8lDnoPJQ57jyUPJQ59DyUOfo8lDyUOkg6Tjo8PJQ8lDpIOk46KjyUPJQ6SDpOOlQ8lDyUOkg6TjoGPJQ8lDokOk46VDyUPJQ6SDpOOgY8lDyUOkg6TjoAPJQ8lDpIOk46BjyUPJQ6SDpOOlQ8lDyUOkg6TjpUPJQ8lDpIOk46DDyUPJQ6JDpOOlQ8lDyUOkg6TjoMPJQ8lDpIOk46EjyUPJQ6SDpOOhg8lDyUOkg6TjoqPJQ8lDpIOk46HjyUPJQ6JDpOOjw8lDyUOkg6TjoqPJQ8lDpIOk46MDyUPJQ6SDpOOlQ8lDyUOkg6Tjo2PJQ8lDpIOk46PDyUPJQ6SDpOOkI8lDyUOkg6TjpCPJQ8lDpIOk46VDyUPJQ6YDyUOlo8lDyUOmA8lDpmPJQ8lDpsPJQ6cjp4PJQ6wDrGOro8lDyUOsA6xjqiPJQ8lDrAOsY6zDyUPJQ6wDrGOsw8lDyUOsA6xjrMPJQ8lDrAOsY6zDyUPJQ6wDrGOn48lDyUOpw6xjrMPJQ8lDrAOsY6fjyUPJQ6wDrGOoQ8lDyUOsA6xjqKPJQ8lDrAOsY6ojyUPJQ6wDrGOpA8lDyUOsA6xjqWPJQ8lDqcOsY6ujyUPJQ6wDrGOqI8lDyUOsA6xjqoPJQ8lDrAOsY6zDyUPJQ6wDrGOq48lDyUOsA6xjq0PJQ8lDrAOsY6tDyUPJQ8lDyUOro8lDyUOsA6xjrMPJQ8lDrSPJQ62DyUPJQ69jyUOvw8lDyUOvY8lDrePJQ8lDr2PJQ63jyUPJQ69jyUOt48lDyUOuQ8lDr8PJQ8lDr2PJQ66jyUPJQ69jyUOvA8lDyUOvY8lDr8PJQ8lDsyOzg7LDyUPJQ7Mjs4Oyw8lDyUOzI7ODsUPJQ8lDsyOzg7PjyUPJQ7Mjs4Oz48lDyUOzI7ODsUPJQ8lDsyOzg7AjyUPJQ7Mjs4Owg8lDyUOw47ODssPJQ8lDsyOzg7FDyUPJQ7Mjs4Oxo8lDyUOzI7ODs+PJQ8lDyUPJQ7IDyUPJQ7Mjs4OyY8lDyUOzI7ODssPJQ8lDsyOzg7PjyUPJQ8lDyUO0Q8lDyUPJQ8lDtKPJQ8lDtQPJQ7VjtcO2I7aDyUO3Q8lDyUO248lDt0PJQ8lDuePJQ7mDyUPJQ7njyUO3o8lDyUO548lDukPJQ8lDuGPJQ7mDyUPJQ7njyUO4A8lDyUO4Y8lDuYPJQ8lDuePJQ7jDyUPJQ7kjyUO5g8lDyUO548lDukPJQ8lDuwPJQ7yDvOPJQ7sDyUO8g7zjyUO7A8lDuqO848lDuwPJQ7yDvOPJQ7vDyUO8g7zjyUO7A8lDu2O848lDu8PJQ7yDvOPJQ7wjyUO8g7zjyUPAQ8CjvyPJQ8FjwEPAo75jyUPBY8BDwKO/48lDwWPAQ8Cjv+PJQ8FjwEPAo7/jyUPBY8BDwKO+Y8lDwWPAQ8CjvUPJQ8FjvaPAo78jyUPBY8BDwKO+Y8lDwWPAQ8CjvgPJQ8FjwEPAo78jyUPBY8BDwKO+Y8lDwWO9o8CjvyPJQ8FjwEPAo75jyUPBY8BDwKO+A8lDwWPAQ8Cjv+PJQ8FjwEPAo75jyUPBY8BDwKO/48lDwWPAQ8CjvsPJQ8FjwEPAo8EDyUPBY8BDwKO/I8lDwWPAQ8Cjv4PJQ8FjwEPAo7/jyUPBY8BDwKPBA8lDwWPC48lDwcPJQ8lDwuPJQ8NDyUPJQ8LjyUPCI8lDyUPC48lDwoPJQ8lDwuPJQ8NDyUPJQ8ZDyUPEw8lDyUPGQ8lDxSPJQ8lDxkPJQ8ajyUPJQ8ZDyUPDo8lDyUPGQ8lDxAPJQ8lDxGPJQ8TDyUPJQ8ZDyUPFI8lDyUPGQ8lDxYPJQ8lDxkPJQ8XjyUPJQ8ZDyUPGo8lDyUPHw8lDyOPJQ8lDx8PJQ8cDyUPJQ8fDyUPHY8lDyUPHw8lDyCPJQ8lDyIPJQ8jjyUPJQAAQFuA7sAAQFuA7AAAQIWA40AAQHwA6EAAQFuA7YAAQFu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AFYAZQB0AIMAkQCgAK8AvgDNANwA6wD6AQkBGAEnATYAAP//ABUADAAbACoAOQBIAFcAZgB1AIQAkgChALAAvwDOAN0A7AD7AQoBGQEoATcAAP//ABUADQAcACsAOgBJAFgAZwB2AIUAkwCiALEAwADPAN4A7QD8AQsBGgEpATgAAP//ABUADgAdACwAOwBKAFkAaAB3AIYAlACjALIAwQDQAN8A7gD9AQwBGwEqATkBOmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNjbXAHgmNjbXAHgmNjbXAHgmNjbXAHgmNjbXAHgmNjbXAHcmNjbXAHgmNjbXAHgmNjbXAHgmNjbXAHgmNjbXAHgmNjbXAHgmNjbXAHgmNjbXAHgmNjbXAHgmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxvY2wHsGxvY2wHtmxvY2wHvGxvY2wHwmxvY2wHyGxvY2wHzmxvY2wH1GxvY2wH2mxvY2wH4GxvY2wH5mxvY2wH7GxvY2wH8mxvY2wH+GxvY2wH/m51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQgAAAAIAAAABAAAAAQAkAAAAAQAmAAAABgACAAMABAAFAAYABwAAAAQAAgADAAQABQAAAAEAJwAAAAEAGgAAAAMAGwAcAB0AAAABACgAAAABACAAAAABABEAAAABABUAAAABABQAAAABABIAAAABABMAAAABABAAAAABAAkAAAABAA8AAAABAAwAAAABAAsAAAABAAgAAAABAAoAAAABAA0AAAABAA4AAAABABkAAAABACMAAAACAB4AHwAAAAEAIQAAAAEAKQAAAAEAFwAAAAEAJQAAAAEAKgAAAAEAFgAAAAEAGAAAAAEAIgAtAFwG3hGaEkgSrhKuFAIUAhSsFNoVHhUeFUAVQBVAFUAVQBVUFcIV1hX8FhYWPBZKFlgWiBZmFnQWiBaWFt4XJhdIF2AXeBeQF64Z+BxUHUYdZh2OHY4iniM4AAEAAAABAAgAAgRCAh4C+wL8Av0C/gL/AwADAQMCAwMDBAMFAwYDBwMIAyIDIwMtAy4DLwMwAzEDMgNHA0gDSQNLA0wDTQNOA08DUANRA1IDUwNhA2IDYwNkA2UDZgNnA2gDaQNqA2sDbANtA24DbwNwA3EDcgNzA3QDdQN2A3cDeAN5A3oDewN8A30DfgN/A4ADgQOCA4MDhAOGA4cDiAOJA4oDiwOMA40DjgOPA5ADkQOSA5MDlQOWA5cDmAOZA5oDuwPBAvsC/AL9Av4C/wMAAwEDAgMDAwQDBQMGAwcDCAMiAyMDJQMmAycDKAMpAyoDKwMsAy0DLgMvAzADMQMyAzQDNQM3AzgDOQM6AzsDPAM9Az4DPwNAA0EDQgNDA0QDRgNHA0gDSQNKA1QDVQNWA1cDWANZA1oDWwNcA10DXgNfA2EDYgNjA2QDZQNmA2cDaANpA2oDawNsA20DbgNvA3ADcQNyA3MDdAN1A3YDdwN4A3kDegN7A3wDfQN+A38DgAOBA4MDhAOFA4YDhwOIA4kDigOLA4wDjQOOA48DkAORA5IDkwOVA5YDlwOYA5kDmgOjA6QDpQOmA6cDqAOpA6oDqwOsA60DrgOvA7ADsQOyA7MDtAO1A7YDtwO4A7kDugO7A8EDxgM2At0C3gPRA9ID0wPUA9UD1gPXA9gD2QPaA9sD3APdA94D3wPgA+ED4gPjA+QD5QPmA+cD6APpA+oD6wPsA+0D7gPvA/AD8QPyA/MD9AP1A/YD9wP4A/kD+gP7A/wD/QP+A/8EAAQBBAIEAwQEBAUEBgQHBAgECQQKBAsEDAQNBA4EDwQQBBEEEgQTBBQEFQQWBBcEGAQZBBoEGwQcBB0EHgQfBCAEIQQiBCMEJAQlBCYEJwQoBCkEKgQrBCwELQQuBC8EMAQxBDIEMwQ0BDUENgQ3BDgEOQQ6BDsEPAQ9BD4EPwRABEEEQgRDBEQERQRGBEcESARJBEoESwRMBE0ETgRPBFAEUQRSBFMEVARVBFYEVwRYBFkEWgRbBFwEXQReBF8EYARhBGIEYwTjBOUE5gTnBOgE6QTrBOoE7QTuBO8E8ATyBPME9AT1BPYE9wT4BN8E4AT5BPoE+wT8BP0E/gT/BQAFAQUCBQMFBAUFBZoFlQV9BZQFnAWdBZ4FgAWBBaEFhQWGBYcFowWlBaYFigWLBYwFjQWpBaoFqwWQBawFkQWSBZMFrQWuBa8FsAWxBbIFswW0BbUFtgW3BbgFuQX8Bf0F/gX/BgAGAQYCBgMGBAYFBjYGOAZgBmEGZgZnBmgGaQZwBjkGQgZDBkQGRQZGBkcGTwZQBlEGagZrBmwGbQZuBm8GuQa6BrsGvAbcBt4G3QcKBwsHDAcNBw4HDwcQBxEHEgcTBxQHFQcWBxcHGAcZBxoHGwccBx0HHgcfByAHIQciByMHJAdWByYHZgdnB2gHaQdqB2sHbAdtAAIAXgAgACgAAAAqAC4ACQBHAEgADgBSAFcAEABqAG0AFgBvAHYAGgCFAKgAIgCqALcARgC5AL4AVADfAN8AWgDlAOUAWwGmAbMAXAHNAc4AagHQAd0AbAHfAe4AegHxAfUAigH/AgIAjwIEAgsAkwINAi0AmwIvAj8AvAJBAkYAzQJQAmgA0wJuAm4A7AJzAnMA7QJ+An4A7gLbAtwA7wLfAvoA8QMJAyEBDQMkAywBJgMzAzsBLwM9A0YBOANRA1EBQgNUA18BQwOFA4UBTwObA7oBUAO8A8ABcAPCA9ABdQRmBGYBhARtBG8BhQRyBHUBiAR9BH0BjAR/BIEBjQSJBI0BkASTBJMBlQSYBJgBlgScBJwBlwSfBJ8BmASqBKoBmQS8BL8BmgTFBMYBngTLBM0BoATQBNABowTWBNYBpATYBNgBpQUGBQgBpgUKBQoBqQUNBREBqgUVBRYBrwUYBRgBsQUaBRoBsgUdBR0BswUgBSEBtAUkBScBtgUrBS0BugU1BTUBvQU4BTgBvgU8BTwBvwU/BT8BwAVJBUkBwQVdBWIBwgVmBWcByAVsBW4BygVxBXEBzQV5BXkBzgYGBg8BzwYlBiUB2QYnBicB2gYrBiwB2wYuBjIB3QY7BkEB4gZIBkkB6QZMBkwB6wZWBlsB7AavBq8B8gaxBrEB8wazBrMB9Aa1BrUB9QbKBssB9gbYBtgB+AbfBuoB+QbsBu8CBQbyBvwCCQcHBwgCFAdeB2UCFgADAAAAAQAIAAEJtAEyAmoCcgJ4An4ChAKKApAClgKcAqICqAKuArQCugLAAsYCzALSAtgC3gLkAuoC8AL2AvwDAgMIAw4DFAMaAyADJgMsAzIDOAM+A0QDSgNQA1YDXANiA2gDbgN0A3oDgAOGA4wDkgOYA54DpAOqA7ADtgO8A8IDyAPOA9QD2gPgA+YD7APyA/gD/gQEBAoEEAQWBBwEIgQoBC4ENAQ6BEAERgRMBFIEWAReBGQEagRwBHYEfASCBIgEjgSUBJoHdgSgBKYErASyBLgEvgTEBMwE0gTYBN4E5ATqBPAE9gT8BQIFCAUOBRQFGgUgBSYFLAUyBTgFPgVEBUoFUAVWBVwFYgVoBW4FdAV6BYAFhgWMBZIFmAWeBaQFqgWwBbYFvAXCBcgFzgXUBdoF4AXmBewF9AX6BgAGBgYMBhIGGAYeBiQGKgYwBjYGPAZCBkgGTgZUBloGYAZmBmwGcgZ4Bn4GhAaKBpAGlgacBqIGqAauBrQGugbABsYGzAbSBtgG3gbkBuoG8Ab2BvwHAgcIBw4HFAcaByAHJgcsBzIHOgdAB0YHTAdSB1gHXgdkB2oHcAd2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AQIBAwEEAQUBBgEHAQgBCQEKAQsBDAENAQ4BDwEQAREBEgETARQBFQEWARcBGAEZARoBGwEcAR0BHgEfASABIQEiASMBJAElASYBJwEoASkBKgErASwBLQEuAS8BMAExATIBMwE0ATUBNgE4ATkBOgE7ATwBPQE+AT8BQAFBAUIBQwFEAUUBRgFHAUgBSQFKAUsBTAFNAU4BTwFQAVEBUgFTAVQBVQFWAVcBWAFZAVoBWwFcAV0BXgFfAWABYQFiAWMBZAFlAWYBZwFoAWkBagFrAWwBbQFuAW8BcAFxAXIBcwF0AXUBdgF3AXgBeQF6AXsBfAF9AX4BfwGAAYEBggGDAYQBhQGGAYcBiAGJATcCfwKAAoECggKDAoQChQKGAocCiAKJAooCiwKMAo0CjgKPApACkQKSApMClAKVApYClwKYApkCmgKbApwCnQKeAp8CoAKhAqICowKkAqUCpgKnAqgCqQKqAqsCrAKtAq4CrwKwArECsgKzArQCtQK2ArcCuAK5AroCuwK8Ar0CvgK/AsACwQLCAsMCxALFAsYCxwLIAskCygLLAswCzQLOAs8C0ALRAtIC0wLUAtUC1gLXAtgC2QLdAt4D0QPSA9MD1APVA9YD1wPYA9kD2gPbA9wD3QPeA98D4APhA+ID4wPkA+UD5gPnA+gD6QPqA+sD7APtA+4D7wPwA/ED8gPzA/QD9QP2A/cD+AP5A/oD+wP8A/0D/gP/BAAEAQQCBAMEBAQFBAYEBwQIBAkECgQLBAwEDQQOBA8EEAQRBBIEEwQUBBUEFgQXBBgEGQQaBBsEHAQdBB4EHwQgBCEEIgQjBCQEJQQmBCcEKAQpBCoEKwQsBC0ELgQvBDAEMQQyBDMENAQ1BDYENwQ4BDkEOgQ7BDwEPQQ+BD8EQARBBEIEQwREBEUERgRHBEgESQRKBEsETARNBE4ETwRQBFEEUgRTBFQEVQRWBFcEWARZBFoEWwRcBF0EXgRfBGAEYQRiBGME4wTkBOUE5gTnBOgE6QTrBOoE7ATtBO4E7wTwBPEE8gTzBPQE9QT2BPcE+AT5BPoE+wT8BP0E/gT/BQAFAQUCBQMFBAUFBZoFmwWcBZ0FngWfBaAFogWhBaMFpAWlBaYFpwWoBakFqgWrBawFrQWuBa8FsAWxBbIFswW0BbUFtgW3BbgFuQbdAAIAPQAEAB8AAAApACkAHAAvAEYAHQBJAFEANQBYAGkAPgBuAG4AUAB3AIMAUQCpAKkAXgC/AN4AXwDgAOQAfwDmAPUAhAGKAaUAlAG0AcwAsAHPAc8AyQH2Af4AygIuAi4A0wJIAk8A1AJpAm0A3AJvAnIA4QJ0An0A5QLbAtwA7wLfAvoA8QMJAyEBDQMkAywBJgMzAzsBLwM9A0YBOANRA1EBQgNUA18BQwOFA4UBTwObA7oBUAO8A8ABcAPCA9ABdQRmBGYBhARsBG8BhQRyBHUBiQR4BHgBjQR9BH0BjgR/BIIBjwSJBI0BkwSTBJMBmASYBJgBmQSqBKoBmgS8BL8BmwTFBMYBnwTLBM0BoQTQBNABpATWBNYBpQTYBNgBpgUGBQYBpwUMBQ8BqAUSBRUBrAUdBR0BsAUfBSEBsQUpBS0BtAU4BTgBuQVdBWIBugVmBWcBwAVsBW4BwgVxBXEBxQV5BXkBxgbYBtgBxwABAAAAAQAIAAIAWAApAd8B8AY7BwoHCwcMBw0HDgcPBxAHEQcSBxMHFAcVBxYHFwcYBxkHGgcbBxwHHQceBx8HIAchByIHIwckByUHJgcnB2YHZwdoB2kHagdrB2wHbQACAAkB3gHeAAAB7wHvAAEGJgYmAAIG3wbqAAMG7AbvAA8G8gb8ABMHBgcGAB4HCAcJAB8HXgdlACEAAQAAAAEACAACACQADwRkBGUEZARlBfwF/QX+Bf8GAAYBBgIGAwYEBgUGOQABAA8ABACEAYoCDAYGBgcGCAYJBgoGCwYMBg0GDgYPBiYAAA==) format("truetype")}@font-face{font-weight:normal;font-family:"tick42-icons";font-style:normal;src:url(data:font/ttf;base64,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YGAGCAcGqgJK/bYCgP1KJhsaARscJQK2JhsaARscJQAAAQAAAAEAAH2fuHdfDzz1AAsEAAAAAADhVnMIAAAAAOFWcwj//f+9BQADwwAAAAgAAgAAAAAAAAABAAADwP/AAAAFJP/9//0FAAABAAAAAAAAAAAAAAAAAAAA9wQAAAAAAAAAAAAAAAIAAAAEAAAABAAAAAO2//8ESQAAA24AAANuAAACkf//A24AAAO2//8CSQAABAAAAAO2//8CAAAAAmYAAALNAAACHwAAAmYAAAJmAAACqwAAAeEAAAOFAAADhQAAA24AAAQAAAAEkf//AyQAAANWAAACZgAAAOEAAAJIAAADrgAAAysAAAOaAAAEAAAAA24AAAQAAAAEAAAABAAAAAQAAAAEAP/9A24AAAQAAAADWAAAAyQAAANuAAADbgAAA24AAAQAAAADtgAAAbYAAAQAAAAEAAAAA24AAANuAAADbgAAA24AAAQAAAAEAAAABAAAAAQAAAAEAQAABAAAAAQAAAAEAAAAApH//wQA//0EAAAABAD//QQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAAA24AAAO2AAAEAAAAA7b//wMkAAADJAAAAyQAAAQAAAAEAAAAA24AAANuAAADtgAAA7YAAAMkAAADtv//BAAAAAQAAAADbgAABEkAAALbAAADtv//A7b//wQAAAACSQAAAkkAAAFuAAABbgAAAtsAAAQAAAAC2wAABAAAAAO2AAADbgAAA24AAAO2AAADtgAAA7YAAANHAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAADJAAAAtsAAAMkAAADbgAABAAAAANuAAADtv//A7b//wJJAAACSQAAAkkAAAQAAAAEAAAABAAAAAQAAAAESQAABEkAAAQAAAAEAAAAA24AAANuAAACSQAAAkkAAAKRAAACkQAAAW4AAAFuAAACkQAAApEAAARJAAADbgAAA7b//wO2//8EAAAAA24AAAQAAAADtv//BEkAAAO2AAAESQAABAAAAAMkAAACSQAAA7b//wJJAAABbgAAAW4AAAKR//8DJAAAA7b//wKR//8DJAAAANsAAANuAAADbgAAA24AAANuAAACSQAAAkkAAANuAAADtgAAA7YAAAQAAAAEAAAAA24AAANuAAABtgAAAbYAAAQAAAAEAAAABAAAAAUkAAADbgAAA24AAANuAAADbgAAA24AAANuAAADbgAAA24AAANuAAADbgAAA24AAANuAAADbgAABJEAAASRAAAEkQAAA24AAASR//8Ekf//BJH//wSR//8Ekf//BJEAAAQAAAADbgAAA24AAANuAAADbgAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAO2//8DbgAABAAAAAQAAAAEkf//BAAAAAQAAAAAAAAAAAoAFAAeAQgBbAHkAk4DIgP+BEIIOAj2CTQJjAosCkoKZAqCCqQK0Ar8CyoLZguaC9IMNAzEDPINnA4gDl4OfA6wDvoPGg84D2wP0hAGEFQQhBD0EfgSOBJ8Ep4TVhO4FBoUYBXAFioWbBaqFzAXdBfiGFAY1hmWGpYcAhx2HQIdih64IAQgZiFGIhQjcCRuJKwk3iU4JbwmBCYeJjgmuCc6J9IoKihsKJAo0ikCKbIqQiq2KxYr0Cw+LIws+i2gLeguWi6SLxgvoC/8MCAwRjBqMI4wvjDuMRwxTDGIMcQyADI8MqIzGjNgM8o0HjR6NMg1fjbONx43Xjd8OFg4zjlcOdQ6SjrEOwY7SDtyO+Q8VDywPcA+Aj5EPmg+jD8GP5A/+kBUQLRBFEFcQcxCZELCQxRDZkO4RApEOERmRJREwkUkRXJF8EZuRzJHXEe4SAxIiEjQSURJrkniSppLiEv+TFRMlE0ITZpOFk5gTrhPEE9QT5xP7FBEUPZRyFH+UnxS/FOWVDBUyFViVY5VulXoVhZWXFbcV2pYSljeWWxZ4FpIWuJbjlwGXLZdEF2SXeBejF8OX7JgXGB6YLphSmG2YlJi7GNaY/xkdmTkZXRmKGbCZ3poHmiSaWBqSGsga6Zr1Gv4bERspm0SAAEAAAD3As4ADwAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAOAK4AAQAAAAAAAQAMAAAAAQAAAAAAAgAHAI0AAQAAAAAAAwAMAEUAAQAAAAAABAAMAKIAAQAAAAAABQALACQAAQAAAAAABgAMAGkAAQAAAAAACgAaAMYAAwABBAkAAQAYAAwAAwABBAkAAgAOAJQAAwABBAkAAwAYAFEAAwABBAkABAAYAK4AAwABBAkABQAWAC8AAwABBAkABgAYAHUAAwABBAkACgA0AOB0aWNrNDItaWNvbnMAdABpAGMAawA0ADIALQBpAGMAbwBuAHNWZXJzaW9uIDEuMABWAGUAcgBzAGkAbwBuACAAMQAuADB0aWNrNDItaWNvbnMAdABpAGMAawA0ADIALQBpAGMAbwBuAHN0aWNrNDItaWNvbnMAdABpAGMAawA0ADIALQBpAGMAbwBuAHNSZWd1bGFyAFIAZQBnAHUAbABhAHJ0aWNrNDItaWNvbnMAdABpAGMAawA0ADIALQBpAGMAbwBuAHNGb250IGdlbmVyYXRlZCBieSBJY29Nb29uLgBGAG8AbgB0ACAAZwBlAG4AZQByAGEAdABlAGQAIABiAHkAIABJAGMAbwBNAG8AbwBuAC4AAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA) format("truetype")}[class^="icon-"],[class*=" icon-"]{font-weight:normal;font-family:"tick42-icons";font-style:normal;font-variant:normal;line-height:1;text-transform:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.tick42-custom-icon i{color:var(--t42-link-color)}.tick42-custom-icon img{display:block}.tick42-custom-icon.disabled i,.tick42-custom-icon:disabled i{color:var(--t42-content-color-disabled)}i.disabled,.disabled i{color:var(--t42-content-color-disabled)}.icon-size-12 i{font-size:0.75rem}.icon-size-12 i,.icon-size-12 img{width:0.75rem;height:0.75rem}.icon-size-14 i{font-size:0.875rem}.icon-size-14 i,.icon-size-14 img{width:0.875rem;height:0.875rem}.icon-size-24 i{font-size:1.5rem}.icon-size-24 i,.icon-size-24 img{width:1.5rem;height:1.5rem}.icon-size-16 i,.icon-size-16 img{width:1rem;height:1rem}.icon-size-16 i{font-size:1rem}.icon-size-32 i,.icon-size-32 img{width:2rem;height:2rem}.icon-size-32 i{font-size:2rem}.icon-size-48 i,.icon-size-48 img{width:3rem;height:3rem}.icon-size-48 i{font-size:3rem}.icon-size-64 i,.icon-size-64 img{width:4rem;height:4rem}.icon-size-64 i{font-size:4rem}.icon-size-80 i,.icon-size-80 img{width:5rem;height:5rem}.icon-size-80 i{font-size:5rem}.icon-size-96 i,.icon-size-96 img{width:6rem;height:6rem}.icon-size-96 i{font-size:6rem}.icon-size-112 i,.icon-size-112 img{width:7rem;height:7rem}.icon-size-112 i{font-size:7rem}.icon-size-128 i,.icon-size-128 img{width:8rem;height:8rem}.icon-size-128 i{font-size:8rem}.icon-primary i::before{color:#007be5}.icon-secondary i::before{color:#616161}.icon-success i::before{color:#43a047}.icon-info i::before{color:#469eb9}.icon-warning i::before{color:#f9a825}.icon-danger i::before{color:#ff511f}.icon-light i::before{color:#616161}.icon-dark i::before{color:#616161}.icon-dev-tools::before{content:"\e901"}.icon-interop::before{content:"\e900"}.icon-mail::before{content:"\e800"}.icon-attention::before{content:"\e801"}.icon-print::before{content:"\e802"}.icon-picture::before{content:"\e803"}.icon-thumbs-up::before{content:"\e804"}.icon-thumbs-down::before{content:"\e805"}.icon-lock::before{content:"\e806"}.icon-globe::before{content:"\e807"}.icon-calendar::before{content:"\e808"}.icon-location::before{content:"\e809"}.icon-briefcase::before{content:"\e80a"}.icon-export::before{content:"\e80b"}.icon-play::before{content:"\e80c"}.icon-stop::before{content:"\e80d"}.icon-record::before{content:"\e80e"}.icon-pause::before{content:"\e80f"}.icon-to-end::before{content:"\e810"}.icon-to-start::before{content:"\e811"}.icon-check::before{content:"\e812"}.icon-cancel::before{content:"\e813"}.icon-fast-forward::before{content:"\e814"}.icon-fast-backward::before{content:"\e815"}.icon-attention-circled::before{content:"\e816"}.icon-bell::before{content:"\e817"}.icon-chart-bar::before{content:"\e818"}.icon-phone::before{content:"\e819"}.icon-doc-add::before{content:"\e81a"}.icon-layout::before{content:"\e81b"}.icon-dot::before{content:"\e81c"}.icon-dot-2::before{content:"\e81d"}.icon-dot-3::before{content:"\e81e"}.icon-resize-full-1::before{content:"\e81f"}.icon-resize-small-1::before{content:"\e820"}.icon-checkbox::before{content:"\e821"}.icon-cancel-circled::before{content:"\e822"}.icon-03-context-viewer::before{content:"\e823"}.icon-volume-off-1::before{content:"\e824"}.icon-volume::before{content:"\e825"}.icon-headphones-1::before{content:"\e826"}.icon-performance-report::before{content:"\e827"}.icon-pause-1::before{content:"\e828"}.icon-volume-up-1::before{content:"\e829"}.icon-volume-down-1::before{content:"\e82a"}.icon-trash-empty::before{content:"\e839"}.icon-resize-small::before{content:"\e83b"}.icon-resize-full::before{content:"\e83c"}.icon-doc::before{content:"\e83d"}.icon-cog::before{content:"\e83e"}.icon-wrench::before{content:"\e83f"}.icon-resize-vertical::before{content:"\e840"}.icon-resize-horizontal::before{content:"\e841"}.icon-edit::before{content:"\e842"}.icon-pencil-1::before{content:"\e843"}.icon-cw-2::before{content:"\e844"}.icon-ccw-1::before{content:"\e845"}.icon-arrows-cw-1::before{content:"\e847"}.icon-th-large::before{content:"\e848"}.icon-th::before{content:"\e849"}.icon-spin5::before{content:"\e84a"}.icon-spin6::before{content:"\e84b"}.icon-spin4::before{content:"\e84c"}.icon-spin3::before{content:"\e84d"}.icon-spin2::before{content:"\e84e"}.icon-spin1::before{content:"\e84f"}.icon-pin::before{content:"\e850"}.icon-trading-controls::before{content:"\e856"}.icon-icon-coverage::before{content:"\e857"}.icon-taxes::before{content:"\e858"}.icon-credit::before{content:"\e859"}.icon-checkbox-checked::before{content:"\e85a"}.icon-checkbox-indeterminate::before{content:"\e85b"}.icon-radio::before{content:"\e85c"}.icon-radio-choose::before{content:"\e85d"}.icon-arrow-up-down::before{content:"\e85e"}.icon-arrow-double-left::before{content:"\e85f"}.icon-arrow-double-right::before{content:"\e860"}.icon-floppy::before{content:"\e861"}.icon-logout::before{content:"\e862"}.icon-mail-1::before{content:"\e864"}.icon-search-1::before{content:"\e865"}.icon-plus-1::before{content:"\e866"}.icon-minus-1::before{content:"\e867"}.icon-cancel-1::before{content:"\e868"}.icon-ok::before{content:"\e869"}.icon-th-list::before{content:"\e86a"}.icon-help-circled::before{content:"\e86b"}.icon-info-circled::before{content:"\e86c"}.icon-home::before{content:"\e86d"}.icon-link-1::before{content:"\e86e"}.icon-attach-1::before{content:"\e86f"}.icon-lock-open-1::before{content:"\e870"}.icon-eye::before{content:"\e871"}.icon-eye-off::before{content:"\e872"}.icon-tag::before{content:"\e873"}.icon-tags::before{content:"\e874"}.icon-bookmark::before{content:"\e875"}.icon-download-1::before{content:"\e876"}.icon-upload-1::before{content:"\e877"}.icon-forward-1::before{content:"\e878"}.icon-down-dir::before{content:"\e879"}.icon-up-dir::before{content:"\e87a"}.icon-left-dir::before{content:"\e87b"}.icon-right-dir::before{content:"\e87c"}.icon-left-open-1::before{content:"\e87d"}.icon-down-open-1::before{content:"\e87e"}.icon-right-open-1::before{content:"\e87f"}.icon-up-open-1::before{content:"\e880"}.icon-down-big::before{content:"\e881"}.icon-left-big::before{content:"\e882"}.icon-right-big::before{content:"\e883"}.icon-up-big::before{content:"\e884"}.icon-asterisk::before{content:"\e885"}.icon-check-1::before{content:"\e886"}.icon-tick42-icon-monochrome::before{content:"\e887"}.icon-task-manager::before{content:"\e888"}.icon-context-viewer::before{content:"\e889"}.icon-help-2::before{content:"\e88a"}.icon-star-empty-1::before{content:"\e88b"}.icon-star-full::before{content:"\e902"}.icon-move::before{content:"\f047"}.icon-link-ext::before{content:"\f08e"}.icon-check-empty::before{content:"\f096"}.icon-bookmark-empty::before{content:"\f097"}.icon-filter::before{content:"\f0b0"}.icon-resize-full-alt::before{content:"\f0b2"}.icon-docs::before{content:"\f0c5"}.icon-menu-1::before{content:"\f0c9"}.icon-table::before{content:"\f0ce"}.icon-columns::before{content:"\f0db"}.icon-sort::before{content:"\f0dc"}.icon-sort-down::before{content:"\f0dd"}.icon-sort-up::before{content:"\f0de"}.icon-mail-alt::before{content:"\f0e0"}.icon-sitemap::before{content:"\f0e8"}.icon-paste::before{content:"\f0ea"}.icon-exchange::before{content:"\f0ec"}.icon-download-cloud::before{content:"\f0ed"}.icon-upload-cloud::before{content:"\f0ee"}.icon-suitcase-1::before{content:"\f0f2"}.icon-bell-alt::before{content:"\f0f3"}.icon-doc-text-1::before{content:"\f0f6"}.icon-plus-squared::before{content:"\f0fe"}.icon-angle-double-left::before{content:"\f100"}.icon-angle-double-right::before{content:"\f101"}.icon-angle-double-up::before{content:"\f102"}.icon-angle-double-down::before{content:"\f103"}.icon-angle-left::before{content:"\f104"}.icon-angle-right::before{content:"\f105"}.icon-angle-up::before{content:"\f106"}.icon-angle-down::before{content:"\f107"}.icon-laptop::before{content:"\f109"}.icon-circle-empty::before{content:"\f10c"}.icon-quote-left::before{content:"\f10d"}.icon-quote-right::before{content:"\f10e"}.icon-spinner::before{content:"\f110"}.icon-circle::before{content:"\f111"}.icon-reply-1::before{content:"\f112"}.icon-folder-empty::before{content:"\f114"}.icon-folder-open-empty::before{content:"\f115"}.icon-terminal::before{content:"\f120"}.icon-code::before{content:"\f121"}.icon-reply-all-1::before{content:"\f122"}.icon-direction::before{content:"\f124"}.icon-fork::before{content:"\f126"}.icon-unlink::before{content:"\f127"}.icon-help::before{content:"\f128"}.icon-info::before{content:"\f129"}.icon-attention-alt::before{content:"\f12a"}.icon-mic::before{content:"\f130"}.icon-mute::before{content:"\f131"}.icon-calendar-empty::before{content:"\f133"}.icon-lock-open-alt::before{content:"\f13e"}.icon-ellipsis::before{content:"\f141"}.icon-ellipsis-vert::before{content:"\f142"}.icon-minus-squared::before{content:"\f146"}.icon-ok-squared::before{content:"\f14a"}.icon-link-ext-alt::before{content:"\f14c"}.icon-expand-right::before{content:"\f152"}.icon-euro::before{content:"\f153"}.icon-dollar::before{content:"\f155"}.icon-doc-inv::before{content:"\f15b"}.icon-sort-name-up::before{content:"\f15d"}.icon-sort-name-down::before{content:"\f15e"}.icon-sort-alt-up::before{content:"\f160"}.icon-sort-alt-down::before{content:"\f161"}.icon-sort-number-up::before{content:"\f162"}.icon-sort-number-down::before{content:"\f163"}.icon-down::before{content:"\f175"}.icon-up::before{content:"\f176"}.icon-left::before{content:"\f177"}.icon-right::before{content:"\f178"}.icon-cube::before{content:"\f1b2"}.icon-cubes::before{content:"\f1b3"}.icon-database::before{content:"\f1c0"}.icon-file-pdf::before{content:"\f1c1"}.icon-file-word::before{content:"\f1c2"}.icon-file-excel::before{content:"\f1c3"}.icon-file-powerpoint::before{content:"\f1c4"}.icon-file-image::before{content:"\f1c5"}.icon-file-archive::before{content:"\f1c6"}.icon-file-audio::before{content:"\f1c7"}.icon-file-video::before{content:"\f1c8"}.icon-file-code::before{content:"\f1c9"}.icon-circle-thin::before{content:"\f1db"}.icon-sliders::before{content:"\f1de"}.icon-share::before{content:"\f1e0"}.icon-wifi::before{content:"\f1eb"}.icon-bell-off::before{content:"\f1f6"}.icon-bell-off-empty::before{content:"\f1f7"}.icon-copyright::before{content:"\f1f9"}.icon-chart-area::before{content:"\f1fe"}.icon-chart-line::before{content:"\f201"}.icon-toggle-off::before{content:"\f204"}.icon-toggle-on::before{content:"\f205"}.icon-user-plus::before{content:"\f234"}.icon-user-times::before{content:"\f235"}.icon-clone::before{content:"\f24d"}.icon-hourglass-o::before{content:"\f250"}.icon-hourglass-1::before{content:"\f251"}.icon-hourglass-2::before{content:"\f252"}.icon-hourglass-3::before{content:"\f253"}.icon-calendar-plus-o::before{content:"\f271"}.icon-calendar-minus-o::before{content:"\f272"}.icon-calendar-times-o::before{content:"\f273"}.icon-calendar-check-o::before{content:"\f274"}.icon-hashtag::before{content:"\f292"}.icon-low-vision::before{content:"\f2a8"}.icon-envelope-open-o::before{content:"\f2b7"}.icon-address-book-o::before{content:"\f2ba"}.icon-user-o::before{content:"\f2c0"}.icon-window-maximize::before{content:"\f2d0"}.icon-window-minimize::before{content:"\f2d1"}.icon-window-restore::before{content:"\f2d2"}.icon-window-close::before{content:"\f2d3"}.icon-window-close-o::before{content:"\f2d4"}.icon-app::before{content:"\e903"}.icon-download-arrow::before{content:"\e904"}.icon-logo::before{content:"\e905"}.icon-feedback::before{content:"\e906"}.icon-action::before{content:"\e907"}.icon-swimlane::before{content:"\e908"}div.ag-dnd-ghost{border-color:transparent;border-radius:0.25rem;color:var(--white);font-size:0.75rem;font-family:inherit;line-height:inherit;background-color:var(--primary);cursor:default}div .ag-dnd-ghost-icon{display:flex;float:none;padding:0 0.25rem 0 0}div .ag-dnd-ghost-icon .ag-icon{background-color:var(--white)}.ag-tick42{padding-top:0}.ag-tick42 a{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border;border-bottom:0.063rem dashed var(--dark);color:var(--t42-content-color)}.ag-tick42 a:hover{text-decoration:none}.ag-tick42 .ag-filter-body{margin:0}.ag-tick42 input{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border;padding:0 0.5rem;border:var(--t42-border);color:var(--t42-content-color);line-height:2rem;background-color:var(--t42-input-bg)}.ag-tick42 input:focus{border-color:var(--primary);outline:0}.ag-tick42 input.ag-column-name-filter{margin-left:0.5rem}.ag-tick42 .ag-input-wrapper{padding:0.25rem}.ag-tick42 .ag-input-wrapper.ag-checkbox-input-wrapper{padding:0}.ag-tick42 .ag-cell-wrapper.ag-row-group{align-items:center}.ag-tick42 .ag-cell{padding:0 0.25rem;border-bottom:var(--t42-border);line-height:1.875rem;white-space:nowrap;text-overflow:ellipsis}.ag-tick42 .ag-cell .btn,.ag-tick42 .ag-cell .btn-sm,.ag-tick42 .ag-cell .btn-group-sm>.btn,.ag-tick42 .ag-cell .btn-lg,.ag-tick42 .ag-cell .btn-group-lg>.btn{line-height:1.25rem}.ag-tick42 .ag-cell .btn-icon i{position:relative;top:0.0625rem}.ag-tick42 .ag-cell:focus{outline:1px solid var(--primary)}.ag-tick42 .ag-cell .dropdown-toggle{width:20px;height:20px;margin-top:-3px;padding:0;border:0;line-height:22px}.ag-tick42 .ag-cell .dropdown-toggle::after{background-color:transparent;content:""}.ag-tick42 .ag-row::before{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:width;position:absolute;top:0;bottom:0;left:0;z-index:1;width:0;background-color:var(--primary);content:""}.ag-tick42 .ag-row.ag-row-selected{color:var(--t42-link-color);background-color:var(--t42-color-opacity-10)}.ag-tick42 .ag-row.ag-row-selected .ag-icon{color:var(--t42-link-color)}.ag-tick42 .ag-pinned-left-header,.ag-tick42 .ag-pinned-left-cols-container,.ag-tick42 .ag-pinned-right-header,.ag-tick42 .ag-pinned-right-cols-container{background-color:Rgb(var(--t42-bg-mid))}.ag-tick42 .ag-pinned-left-cols-container .ag-row-selected::before,.ag-tick42 .ag-pinned-left-cols-container.ag-hidden+.ag-center-cols-clipper .ag-row-selected::before{width:2px}.ag-tick42 .ag-row-hover{background-color:var(--t42-color-opacity-10)}.ag-tick42 .ag-row-hover .ag-cell{color:var(--t42-link-color)}.ag-tick42 .ag-row-hover .ag-loading .ag-icon-loading::after{background:Rgb(var(--t42-bg-light))}.ag-tick42 .ag-row-hover a{border-bottom-color:var(--t42-content-color);color:var(--t42-link-color)}.ag-tick42 .ag-row-hover a:hover{border-bottom-style:solid}.ag-tick42 .ag-header-row:last-of-type{border-bottom:var(--t42-border)}.ag-tick42 .ag-header-cell,.ag-tick42 .ag-header-group-cell{padding:0 0.25rem;border-top:var(--t42-border);border-left:var(--t42-border);color:Hsl(var(--t42-content-color-base), calc(var(--t42-content-color-l) - 20%))}.ag-tick42 .ag-header-cell:first-of-type,.ag-tick42 .ag-header-group-cell:first-of-type{border-left:0}.ag-tick42 .ag-header-cell .ag-header-cell-label,.ag-tick42 .ag-header-cell .ag-header-group-cell-label,.ag-tick42 .ag-header-group-cell .ag-header-cell-label,.ag-tick42 .ag-header-group-cell .ag-header-group-cell-label{font-weight:normal;font-size:83.3%;line-height:1.875rem;text-transform:uppercase}.ag-tick42 .ag-header-cell .ag-header-select-all,.ag-tick42 .ag-header-group-cell .ag-header-select-all{margin-right:0.5rem}.ag-tick42 .ag-header-cell-moving{background-color:Hsl(var(--t42-bg-light-base), calc(var(--t42-bg-light-l) + 5%))}.ag-tick42 .ag-cell-inline-editing{padding-top:0}.ag-tick42 .ag-cell-edit-input{border-top:0;border-bottom:0;border-radius:0}.ag-tick42 .ag-icon{font-family:inherit}.ag-tick42 .ag-icon::before{content:""}.ag-tick42 .ag-react-container .btn-icon{margin-bottom:0.125rem;padding:0 0.5rem}.ag-tick42 .ag-tabs-header{display:flex;height:1.875rem;border-bottom:var(--t42-border);border-bottom-width:0.063rem}.ag-tick42 .ag-tabs-header .ag-tab{display:flex;align-items:center;justify-content:center;width:1.875rem;height:1.875rem;color:var(--primary);cursor:pointer}.ag-tick42 .ag-tabs-header .ag-tab.ag-tab-selected{background-color:var(--primary)}.ag-tick42 .ag-tabs-header .ag-tab.ag-tab-selected .ag-icon{background-color:var(--white)}.ag-tick42 .ag-tabs-body{max-height:280px;overflow:auto}.ag-tick42 .ag-menu,.ag-tick42 .ag-tool-panel{z-index:1040;border:var(--t42-border);border-radius:0;overflow:initial;background-color:rgba(var(--t42-bg-light), 0.75);box-shadow:var(--t42-shadow);backdrop-filter:var(--backdrop-filter)}.ag-tick42 .ag-menu .ag-column-select-column,.ag-tick42 .ag-menu .ag-column-select-column-group,.ag-tick42 .ag-tool-panel .ag-column-select-column,.ag-tick42 .ag-tool-panel .ag-column-select-column-group{display:flex;align-items:center;margin-left:0;line-height:2rem;cursor:pointer}.ag-tick42 .ag-menu .ag-column-select-column .ag-column-select-checkbox:hover,.ag-tick42 .ag-menu .ag-column-select-column-group .ag-column-select-checkbox:hover,.ag-tick42 .ag-tool-panel .ag-column-select-column .ag-column-select-checkbox:hover,.ag-tick42 .ag-tool-panel .ag-column-select-column-group .ag-column-select-checkbox:hover{color:var(--t42-link-color)}.ag-tick42 .ag-menu .ag-column-select-column:hover,.ag-tick42 .ag-menu .ag-column-select-column-group:hover,.ag-tick42 .ag-tool-panel .ag-column-select-column:hover,.ag-tick42 .ag-tool-panel .ag-column-select-column-group:hover{color:Hsl(var(--t42-content--base), 100%);background-color:var(--t42-color-opacity-10)}.ag-tick42 .ag-menu .ag-column-select-header,.ag-tick42 .ag-tool-panel .ag-column-select-header{padding:0.5rem}.ag-tick42 .ag-menu .ag-column-select-column-label,.ag-tick42 .ag-tool-panel .ag-column-select-column-label{margin-left:0.25rem}.ag-tick42 .ag-tab-body{max-height:220px;overflow:auto}.ag-tick42 .ag-tab-body .ag-set-filter-list{height:9rem}.ag-tick42 .ag-tab-body input{border:var(--t42-border)}.ag-tick42 .ag-tab-body input:focus{border-color:var(--primary)}.ag-tick42 .ag-menu-option{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:color;line-height:2rem;cursor:pointer}.ag-tick42 .ag-menu-option .ag-menu-option-icon{color:var(--t42-content-color)}.ag-tick42 .ag-menu-option .ag-menu-option-icon,.ag-tick42 .ag-menu-option .ag-menu-option-popup-pointer{width:2rem;color:var(--t42-content-color);text-align:center}.ag-tick42 .ag-menu-option .ag-menu-option-icon.ag-menu-option-popup-pointer,.ag-tick42 .ag-menu-option .ag-menu-option-icon:hover,.ag-tick42 .ag-menu-option .ag-menu-option-popup-pointer.ag-menu-option-popup-pointer,.ag-tick42 .ag-menu-option .ag-menu-option-popup-pointer:hover{color:var(--t42-content-color)}.ag-tick42 .ag-menu-option .ag-menu-option-icon.ag-menu-option-popup-pointer .ag-icon,.ag-tick42 .ag-menu-option .ag-menu-option-icon:hover .ag-icon,.ag-tick42 .ag-menu-option .ag-menu-option-popup-pointer.ag-menu-option-popup-pointer .ag-icon,.ag-tick42 .ag-menu-option .ag-menu-option-popup-pointer:hover .ag-icon{color:var(--t42-content-color)}.ag-tick42 .ag-menu-option.ag-menu-option-active{color:var(--t42-link-color);background-color:var(--t42-color-opacity-10)}.ag-tick42 .ag-menu-option.ag-menu-option-active .ag-icon{color:var(--t42-content-color)}.ag-tick42 .ag-menu-separator{border-bottom:var(--t42-border);border-bottom-color:var(--t42-color-opacity-10)}.ag-tick42 .ag-menu-column-select-wrapper,.ag-tick42 .ag-primary-cols-list-panel{height:auto}.ag-tick42 .ag-tool-panel .ag-pivot-mode{padding-top:0.5rem}.ag-tick42 .ag-column-tool-panel-column{padding:0 0.25rem}.ag-tick42 .ag-column-tool-panel-column .ag-icon{margin:0 0.25rem}.ag-tick42 .ag-column-tool-panel-column-label,.ag-tick42 span.ag-column-tool-panel-column-group{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;padding-left:0.25rem}.ag-tick42 .ag-column-tool-panel-column-group .ag-icon{margin:0 0.25rem 0 0}.ag-tick42 .ag-root+.ag-tool-panel{box-shadow:none}.ag-tick42 .ag-row-group-leaf-indent{margin-left:24px}.ag-tick42 .ag-group-expanded,.ag-tick42 .ag-group-contracted{display:flex;align-items:center;min-width:0.75rem;height:100%;margin-right:0.5rem}.ag-tick42 .ag-group-value .ag-react-container{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;display:inline;font-size:87.5%}.ag-tick42 .ag-popup-editor{box-shadow:var(--t42-shadow)}.ag-tick42 .ag-rich-select{border:var(--t42-border);border-radius:0;overflow-y:auto;background-color:Rgb(var(--t42-bg-light), 1)}.ag-tick42 .ag-rich-select-row{padding-left:0.75rem}.ag-tick42 .ag-rich-select-row-selected{background:var(--t42-color-opacity-10)}.ag-tick42 .ag-rich-select-value{position:relative;height:2rem;padding-left:0.75rem;border-bottom:var(--t42-border);line-height:2rem}.ag-tick42 .ag-rich-select-value::before{position:absolute;top:0;bottom:0;left:0;width:3px;background-color:var(--primary);content:""}.ag-tick42 .icon-window-maximize::before,.ag-tick42 .icon-window-minimize::before,.ag-tick42 .icon-window-ok::before{font-size:0.813rem}.ag-tick42 .ag-column-drop{border-top:var(--t42-border)}.ag-tick42 .ag-column-drop.ag-column-drop-horizontal{display:flex;height:1.875rem}.ag-tick42 .ag-column-drop.ag-column-drop-horizontal div{display:flex;align-items:center}.ag-tick42 .ag-column-drop.ag-column-drop-horizontal div:first-of-type{margin-right:0.25rem}.ag-tick42 .ag-column-drop .ag-column-drop-empty-message{align-self:center}.ag-tick42 .ag-column-drop .ag-column-drop-cell{display:flex;height:1.125rem;margin:0.125rem 0.25rem;padding:0 0.125rem 0 0.25rem;border-radius:0.25rem;background-color:Rgb(var(--t42-bg-light))}.ag-tick42 .ag-column-drop .ag-column-drop-cell .ag-column-drop-cell-text{padding:0 0.25rem;line-height:1.125rem}.ag-tick42 .ag-column-drop.ag-column-drop-vertical div{justify-content:start}.ag-tick42 .ag-column-drop.ag-column-drop-vertical .ag-icon-group{margin:0 0.25rem}.ag-tick42 .ag-right-arrow{width:1.5rem;padding:0 0.25rem;overflow:hidden;text-indent:-999px;background-color:var(--t42-content-color);transform:rotate(-90deg);-webkit-mask-image:var(--t42-select-indicator)}.ag-tick42 .ag-right-arrow::before{position:absolute;text-indent:999px}.ag-tick42 .ag-group-checkbox{display:flex;align-items:center;width:1rem;height:100%;margin-right:0.5rem}.ag-tick42 .ag-group-checkbox .ag-icon{width:0.875rem;height:0.875rem}.ag-tick42 .ag-group-checkbox:empty{width:initial}.ag-tick42 .ag-ltr .ag-toolpanel-indent-1{padding-left:1rem}.ag-tick42 .ag-ltr .ag-toolpanel-indent-2{padding-left:2rem}.ag-tick42 .ag-ltr .ag-toolpanel-indent-3{padding-left:3rem}.ag-tick42 .ag-ltr .ag-row-group-indent-1{padding-left:calc(1 * 1.45rem)}.ag-tick42 .ag-ltr .ag-row-group-indent-2{padding-left:calc(2 * 1.45rem)}.ag-tick42 .ag-ltr .ag-row-group-indent-3{padding-left:calc(3 * 1.45rem)}.ag-menu .ag-filter-checkbox{min-width:2rem}.ag-menu .ag-icon-checkbox-checked::after{width:0.625rem;height:0.625rem}.ag-menu .ag-column-group-icons{width:1.5rem}.ag-menu .ag-labeled.ag-label-align-right>div{margin-left:0.25rem}.ag-filter-panel{width:100%}.loading-filter{background-color:rgba(var(--t42-bg-light), 0.75);backdrop-filter:var(--backdrop-filter)}#selectAllContainer,.ag-set-filter-item{display:flex;align-items:center;cursor:pointer}#selectAllContainer .ag-filter-value,#selectAllContainer .ag-set-filter-item-value,.ag-set-filter-item .ag-filter-value,.ag-set-filter-item .ag-set-filter-item-value{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}#selectAllContainer .ag-set-filter-item-value,.ag-set-filter-item .ag-set-filter-item-value{margin-left:0.25rem}.ag-filter-checkbox{justify-content:center;min-width:2rem;color:var(--primary)}.ag-set-filter-item:hover,.ag-filter-header-container:hover label{color:var(--t42-link-color);background-color:var(--t42-color-opacity-10)}.ag-set-filter-item:hover .ag-icon,.ag-filter-header-container:hover label .ag-icon{color:var(--t42-link-color)}.ag-input-text-wrapper{padding:0.25rem 0.25rem 0}.ag-primary-cols-header-panel{align-items:center;padding:0.25rem 0.25rem 0.25rem 0}.ag-primary-cols-header-panel div:nth-child(1){width:1.25rem}.ag-primary-cols-header-panel div:nth-child(2){width:1rem;margin-right:0.25rem}.ag-filter-toolpanel-header{display:flex}.ag-filter-toolpanel-header .ag-header-cell-text{padding:0 0.25rem}.ag-filter-condition{justify-content:space-evenly;padding:0.5rem 0}.ag-filter-condition .ag-labeled.ag-label-align-right div{margin-left:0}.ag-radio-button-label{position:relative;color:var(--t42-content-color-muted);cursor:pointer;user-select:none}.ag-radio-button-input-wrapper::before{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, border;position:absolute;left:-1.125rem;display:block;width:0.875rem;height:0.875rem;border:0.0625rem solid var(--t42-content-color-muted);border-radius:50%;cursor:pointer;content:"";pointer-events:all}.ag-radio-button-input-wrapper::after{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, border;position:absolute;left:-0.875rem;display:block;width:0.375rem;height:0.375rem;border-radius:50%;color:var(--white);background-image:none;transform:scale(0);opacity:0;content:""}.ag-radio-button-input-wrapper:focus{border-color:var(--primary)}.ag-radio-button-input-wrapper.ag-checked::before{border-color:var(--t42-color-opacity-30);background-color:var(--primary)}.ag-radio-button-input-wrapper.ag-checked::after{background-color:var(--white);transform:scale(1);opacity:1}.ag-list{z-index:1100;background-color:rgba(var(--t42-bg-mid), 0.7);backdrop-filter:var(--backdrop-filter)}.ag-list .ag-list-item{padding:0 0.5rem;line-height:2rem;cursor:pointer}.ag-list .ag-list-item:hover{background-color:Rgb(var(--t42-bg-light))}.ag-picker-field-wrapper{height:2rem;padding:0 0.5rem;line-height:2rem;cursor:pointer}.ag-column-select-header-icon{display:flex;align-items:center}.ag-column-select-header .ag-text-field-input{height:1.875rem;line-height:1.875rem}.ag-filter-list-panel .ag-filter-toolpanel-expand{margin:0 0.25rem}.ag-filter-list-panel .ag-filter-toolpanel-group-container,.ag-filter-list-panel .ag-filter-toolpanel-instance-filter{padding-left:0.25rem}.ag-side-bar{position:relative}.ag-side-bar .ag-side-bar-right .ag-tool-panel-horizontal-resize{left:-0.375rem}.ag-side-bar>div:first-child{border:var(--t42-border);background-color:var(--t42-color-opacity-10)}.ag-side-bar .ag-pivot-mode-select{display:flex;padding:0.25rem;border-bottom:var(--t42-border)}.ag-side-bar .ag-pivot-mode-select label{margin:0 0 0 0.5rem}.ag-side-bar .ag-pivot-mode-select .ag-checkbox-label{padding-left:0.25rem}.ag-side-bar .ag-side-buttons div.ag-side-button button{width:1rem;height:1rem;padding:0;border:0.0625rem solid transparent;color:Hsl(var(--t42-content-color-base), 100%);background-color:transparent}.ag-side-bar .ag-side-buttons div.ag-side-button button:hover{color:Hsl(var(--t42-content-color-base), 100%);background-color:Rgb(var(--t42-bg-dark))}.ag-side-bar .ag-side-buttons div.ag-side-button button>span{display:none}.ag-side-bar .ag-side-buttons div.ag-side-button.ag-selected button{border-color:var(--t42-color-opacity-30);background-color:var(--primary)}.ag-side-bar .ag-side-buttons div.ag-side-button.ag-selected button [class*="ag-icon-"]{background-color:var(--white)}.ag-side-bar .ag-icon-checkbox-checked::after{width:0.625rem;height:0.625rem}.ag-side-bar .ag-column-panel,.ag-side-bar .ag-filter-panel{padding-left:0.25rem}.ag-side-bar .ag-filter-checkbox{margin-right:0.25rem}.ag-tool-panel-wrapper{border-top:var(--t42-border);border-bottom:var(--t42-border)}.ag-tool-panel-wrapper .ag-set-filter-list{width:100%;height:auto}.ag-tool-panel-wrapper .ag-column-select-checkbox,.ag-tool-panel-wrapper .ag-column-select-header-checkbox{margin:0 0.25rem}.ag-tool-panel-horizontal-resize{top:initial;width:0.188rem;background-color:var(--t42-color-opacity-10)}.ag-column-panel,.ag-column-select-panel,.ag-column-drop-vertical,.ag-column-drop-list{display:block;min-height:initial;max-height:initial;overflow:visible}.ag-column-panel input,.ag-column-select-panel input,.ag-column-drop-vertical input,.ag-column-drop-list input{border:var(--t42-border)}.ag-column-panel input:focus,.ag-column-select-panel input:focus,.ag-column-drop-vertical input:focus,.ag-column-drop-list input:focus{border-color:var(--primary)}[class*="ag-icon-"],.icon-check-1,.icon-check-empty,.icon-resize-horizontal{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:color, transform;display:block;width:0.75rem;height:0.75rem;margin:0 auto;background-color:var(--t42-content-color);background-image:none;mask-repeat:no-repeat;mask-position:center;cursor:pointer}[class*="ag-icon-"]:hover,.icon-check-1:hover,.icon-check-empty:hover,.icon-resize-horizontal:hover{background-color:var(--t42-link-color)}.ag-menu-option-disabled{color:var(--t42-content-color-disabled)}.ag-menu-option-disabled .ag-icon{background-color:var(--t42-content-color-disabled)}.ag-icon-menu{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M475.4,384v36.4c0,5.1-1.7,9.4-5.1,12.8s-7.9,5.3-13.3,5.6H55c-5.1,0-9.4-1.9-12.8-5.6c-3.4-3.8-5.3-8-5.6-12.8V384 c0-5.1,1.9-9.4,5.6-12.8c3.8-3.4,8-5.3,12.8-5.6h401.9c5.1,0,9.6,1.9,13.3,5.6C474,375,475.7,379.2,475.4,384z M475.4,237.6v36.9 c0,4.8-1.7,9-5.1,12.8s-7.9,5.5-13.3,5.1H55c-5.1,0-9.4-1.7-12.8-5.1s-5.3-7.7-5.6-12.8v-36.9c0-4.8,1.9-9,5.6-12.8 c3.8-3.8,8-5.5,12.8-5.1h401.9c5.1,0,9.6,1.7,13.3,5.1S475.7,232.5,475.4,237.6z M475.4,91.7V128c0,4.8-1.7,9-5.1,12.8 s-7.9,5.6-13.3,5.6H55c-5.1,0-9.4-1.9-12.8-5.6s-5.3-8-5.6-12.8V91.7c0-5.1,1.9-9.6,5.6-13.3c3.8-3.8,8-5.5,12.8-5.1h401.9 c5.1,0,9.6,1.7,13.3,5.1S475.7,86.2,475.4,91.7z%27/%3E%3C/svg%3E%0A")}.ag-header-icon{margin-left:0.125rem}.ag-header-icon .ag-icon-menu{line-height:1.875rem}.ag-icon-asc{-webkit-mask-image:var(--t42-select-indicator);transform:rotate(180deg)}.ag-icon-desc{-webkit-mask-image:var(--t42-select-indicator);margin-bottom:2px}.ag-icon-filter{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 16 16%27%3E%3Cpath d=%27M14.9,1.4c0.1,0.3,0.1,0.5-0.1,0.7L9.9,7v7.4c0,0.3-0.1,0.5-0.4,0.6C9.4,15,9.4,15,9.3,15c-0.2,0-0.3-0.1-0.4-0.2l-2.5-2.5 c-0.1-0.1-0.2-0.3-0.2-0.4V7L1.2,2.1C1,1.9,0.9,1.7,1.1,1.4C1.2,1.1,1.4,1,1.7,1h12.7C14.6,1,14.8,1.1,14.9,1.4L14.9,1.4z%27/%3E%3C/svg%3E")}.ag-icon-none{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 16 16%27%3E%3Cpath d=%27M1 6L5 2Q6 1 7 2L11 6Q11 7 10 7L2 7Q1 7 1 6M2 8Q1 8 1 9L5 13Q6 14 7 13L11 9Q11 8 10 8L2 8%27/%3E%3C/svg%3E%0A")}.ag-icon-indeterminate,.ag-icon-checkbox-indeterminate,.ag-icon-checkbox-indeterminate-readonly,.ag-icon-checkbox-unchecked,.ag-icon-checkbox-unchecked-readonly,.ag-icon-checkbox-checked-readonly,.ag-icon-checkbox-checked,.icon-check-1,.icon-check-empty,.ag-checkbox-input-wrapper,.ag-toggle-button-input-wrapper{position:relative;padding:0;color:var(--t42-content-color-muted);background-color:transparent;cursor:pointer;user-select:none}.ag-icon-indeterminate::before,.ag-icon-checkbox-indeterminate::before,.ag-icon-checkbox-indeterminate-readonly::before,.ag-icon-checkbox-unchecked::before,.ag-icon-checkbox-unchecked-readonly::before,.ag-icon-checkbox-checked-readonly::before,.ag-icon-checkbox-checked::before,.icon-check-1::before,.icon-check-empty::before,.ag-checkbox-input-wrapper::before,.ag-toggle-button-input-wrapper::before{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, border-color;display:block;width:100%;height:100%;border:var(--t42-border);border-color:var(--t42-content-color);cursor:pointer;content:"";pointer-events:all}.ag-icon-indeterminate:focus,.ag-icon-checkbox-indeterminate:focus,.ag-icon-checkbox-indeterminate-readonly:focus,.ag-icon-checkbox-unchecked:focus,.ag-icon-checkbox-unchecked-readonly:focus,.ag-icon-checkbox-checked-readonly:focus,.ag-icon-checkbox-checked:focus,.icon-check-1:focus,.icon-check-empty:focus,.ag-checkbox-input-wrapper:focus,.ag-toggle-button-input-wrapper:focus{border-color:var(--primary)}.ag-icon-indeterminate:hover,.ag-icon-checkbox-indeterminate:hover,.ag-icon-checkbox-indeterminate-readonly:hover,.ag-icon-checkbox-unchecked:hover,.ag-icon-checkbox-unchecked-readonly:hover,.ag-icon-checkbox-checked-readonly:hover,.ag-icon-checkbox-checked:hover,.icon-check-1:hover,.icon-check-empty:hover,.ag-checkbox-input-wrapper:hover,.ag-toggle-button-input-wrapper:hover{background-color:transparent}.ag-icon-checkbox-indeterminate,.ag-icon-checkbox-indeterminate-readonly,.ag-icon-checkbox-checked,.ag-icon-checkbox-checked-readonly,.icon-check-empty,.ag-checkbox-input-wrapper.ag-indeterminate,.ag-checkbox-input-wrapper.ag-checked,.ag-toggle-button-input-wrapper.ag-checked{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background, color}.ag-icon-checkbox-indeterminate::before,.ag-icon-checkbox-indeterminate-readonly::before,.ag-icon-checkbox-checked::before,.ag-icon-checkbox-checked-readonly::before,.icon-check-empty::before,.ag-checkbox-input-wrapper.ag-indeterminate::before,.ag-checkbox-input-wrapper.ag-checked::before,.ag-toggle-button-input-wrapper.ag-checked::before{border:0.0625rem solid var(--t42-color-opacity-30);background:var(--primary)}.ag-icon-checkbox-indeterminate::after,.ag-icon-checkbox-indeterminate-readonly::after,.ag-icon-checkbox-checked::after,.ag-icon-checkbox-checked-readonly::after,.icon-check-empty::after,.ag-checkbox-input-wrapper.ag-indeterminate::after,.ag-checkbox-input-wrapper.ag-checked::after,.ag-toggle-button-input-wrapper.ag-checked::after{position:absolute;top:0.063rem;left:0.063rem;display:block;width:0.75rem;height:0.75rem;background:var(--white);content:""}.ag-icon-checkbox-checked::after,.ag-icon-checkbox-checked-readonly::after,.icon-check-empty::after,.ag-checkbox-input-wrapper.ag-checked::after,.ag-toggle-button-input-wrapper.ag-checked::after{-webkit-mask-image:url("data:image/svg+xml,%3Csvg version=%271.1%27 xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M477.44 152.832q0 11.264-8.192 19.456l-245.76 245.76q-8.192 7.68-19.456 7.68t-19.456-7.68l-142.336-142.336q-7.68-8.192-7.68-19.456t7.68-19.456l38.912-38.912q8.192-8.192 19.456-8.192t19.456 8.192l83.968 84.48 187.392-187.904q8.192-8.192 19.456-8.192t19.456 8.192l38.912 38.912q8.192 7.68 8.192 19.456z%27%3E%3C/path%3E%3C/svg%3E%0A")}.ag-icon-checkbox-indeterminate::after,.ag-icon-checkbox-indeterminate-readonly::after,.ag-checkbox-input-wrapper.ag-indeterminate::after{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 -1 5 6%27%3E%3Cpath d=%27M 1 1 A 1 1 0 0 0 1 2 L 4 2 A 1 1 0 0 0 4 1 L 1 1%27/%3E%3C/svg%3E%0A")}.ag-checkbox-input-wrapper.ag-indeterminate::after{top:0.125rem;left:0.125rem}.ag-checkbox-input-wrapper::before,.ag-toggle-button-input-wrapper::before{width:0.875rem;height:0.875rem}.ag-checkbox-input-wrapper .ag-checkbox-input,.ag-checkbox-input-wrapper .ag-toggle-button-input,.ag-toggle-button-input-wrapper .ag-checkbox-input,.ag-toggle-button-input-wrapper .ag-toggle-button-input{position:absolute;z-index:2;width:0.875rem;height:0.875rem}.ag-icon-columns{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M146.432 374.784v55.296q0 11.264-8.192 18.944t-19.456 8.192h-91.136q-11.776 0-19.456-8.192t-8.192-18.944v-55.296q0-11.264 8.192-19.456t19.456-7.68h91.136q11.776 0 19.456 7.68t8.192 19.456zM146.432 228.864v54.784q0 11.264-8.192 19.456t-19.456 7.68h-91.136q-11.776 0-19.456-7.68t-8.192-19.456v-54.784q0-11.776 8.192-19.456t19.456-8.192h91.136q11.776 0 19.456 8.192t8.192 19.456zM329.216 374.784v55.296q0 11.264-8.192 18.944t-19.456 8.192h-91.136q-11.776 0-19.456-8.192t-8.192-18.944v-55.296q0-11.264 8.192-19.456t19.456-7.68h91.136q11.776 0 19.456 7.68t8.192 19.456zM146.432 82.432v54.784q0 11.264-8.192 19.456t-19.456 8.192h-91.136q-11.776 0-19.456-8.192t-8.192-19.456v-54.784q0-11.264 8.192-19.456t19.456-8.192h91.136q11.776 0 19.456 8.192t8.192 19.456zM329.216 228.864v54.784q0 11.264-8.192 19.456t-19.456 7.68h-91.136q-11.776 0-19.456-7.68t-8.192-19.456v-54.784q0-11.776 8.192-19.456t19.456-8.192h91.136q11.776 0 19.456 8.192t8.192 19.456zM512 374.784v55.296q0 11.264-8.192 18.944t-19.456 8.192h-91.136q-11.264 0-19.456-8.192t-8.192-18.944v-55.296q0-11.264 8.192-19.456t19.456-7.68h91.136q11.776 0 19.456 7.68t8.192 19.456zM329.216 82.432v54.784q0 11.264-8.192 19.456t-19.456 8.192h-91.136q-11.776 0-19.456-8.192t-8.192-19.456v-54.784q0-11.264 8.192-19.456t19.456-8.192h91.136q11.776 0 19.456 8.192t8.192 19.456zM512 228.864v54.784q0 11.264-8.192 19.456t-19.456 7.68h-91.136q-11.264 0-19.456-7.68t-8.192-19.456v-54.784q0-11.776 8.192-19.456t19.456-8.192h91.136q11.776 0 19.456 8.192t8.192 19.456zM512 82.432v54.784q0 11.264-8.192 19.456t-19.456 8.192h-91.136q-11.264 0-19.456-8.192t-8.192-19.456v-54.784q0-11.264 8.192-19.456t19.456-8.192h91.136q11.776 0 19.456 8.192t8.192 19.456z%27%3E%3C/path%3E%3C/svg%3E")}.ag-icon-pin{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M228.4,228.6v-128c0-2.7-0.9-4.9-2.6-6.7s-3.9-2.6-6.7-2.6c-2.7,0-4.9,0.9-6.7,2.6c-1.7,1.7-2.6,3.9-2.6,6.7v128 c0,2.7,0.9,4.9,2.6,6.7c1.7,1.7,3.9,2.6,6.7,2.6c2.7,0,4.9-0.9,6.7-2.6S228.4,231.3,228.4,228.6z M420.4,329.5c0,4.8-1.9,9-5.6,12.8 c-3.8,3.8-8,5.5-12.8,5.1H279.6l-14.8,138.2c-0.3,2.4-1.4,4.3-3.1,5.6c-1.7,1.4-3.6,2.2-5.6,2.6h-0.5c-5.1,0-8-2.6-8.7-7.7 l-22-138.8H109.6c-5.1,0-9.4-1.7-12.8-5.1c-3.4-3.4-5.3-7.7-5.6-12.8c0-23.6,7.5-44.7,22.5-63.5s31.9-28.2,50.7-28.2V91.4 c-9.9,0-18.4-3.6-25.6-10.8c-7.2-7.2-10.9-15.7-11.3-25.6s3.4-18.4,11.3-25.6c7.9-7.2,16.4-10.9,25.6-11.3h182.8 c9.9,0,18.4,3.8,25.6,11.3s10.8,16,10.8,25.6s-3.6,18.1-10.8,25.6S357,91.7,347.1,91.4v146.4c18.8,0,35.7,9.4,50.7,28.2 C412.8,284.8,420.4,305.9,420.4,329.5L420.4,329.5z%27/%3E%3C/svg%3E")}.ag-icon-small-right,.ag-icon-small-down{width:0.65rem;height:0.65rem;-webkit-mask-image:var(--t42-select-indicator);transform:rotate(-90deg)}.ag-icon-small-down{transform:rotate(0)}.ag-icon-tick{-webkit-mask-image:url("data:image/svg+xml,%3Csvg version=%271.1%27 xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M477.44 152.832q0 11.264-8.192 19.456l-245.76 245.76q-8.192 7.68-19.456 7.68t-19.456-7.68l-142.336-142.336q-7.68-8.192-7.68-19.456t7.68-19.456l38.912-38.912q8.192-8.192 19.456-8.192t19.456 8.192l83.968 84.48 187.392-187.904q8.192-8.192 19.456-8.192t19.456 8.192l38.912 38.912q8.192 7.68 8.192 19.456z%27%3E%3C/path%3E%3C/svg%3E%0A")}.ag-icon-copy{-webkit-mask-image:url("data:image/svg+xml,")}.ag-icon-csv,.ag-icon-excel{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M0 0zq0-7.7-5.1-12.8zM475.3 356.6v91.6q0 11.3-8.2 18.9t-19.5 8.2h-420.4q-11.8 0-19.5-8.2t-8.2-18.9v-91.6q0-11.3 8.2-19.5t19.5-8.2h132.6l38.4 38.9q16.9 16.4 38.9 16.4t38.9-16.4l38.9-38.9h132.6q11.3 0 19.5 8.2t8.2 19.5zM382.1 193.8q5.1 11.8-4.1 20l-128 128q-5.1 5.6-12.8 5.6t-12.8-5.6l-128-128q-8.7-8.2-4.1-20q5.1-10.8 16.9-10.8h73.2v-128q0-7.7 5.6-12.8t12.8-5.6h73.2q7.2 0 12.8 5.6t5.1 12.8v128h73.2q12.3 0 16.9 10.8M347 439A1 1 0 00347 402A1 1 0 00347 439M420 439A1 1 0 00420 402A1 1 0 00420 439zz%27/%3E%3C/svg%3E%0A")}.ag-icon-expanded{-webkit-mask-image:var(--t42-select-indicator);transform:rotate(-90deg)}.ag-icon-contracted{-webkit-mask-image:var(--t42-select-indicator);transform:rotate(90deg)}.ag-header-expand-icon-collapsed .ag-icon-contracted{margin-bottom:1px;transform:rotate(90deg);-webkit-mask-image:var(--t42-select-indicator)}.ag-icon-paste{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M219.648 475.648h256v-183.296h-119.296q-11.264 0-18.944-7.68t-8.192-19.456v-118.784h-109.568v329.216zM292.352 64v-18.432q0-3.584-2.56-6.144t-6.144-3.072h-201.216q-3.584 0-6.656 3.072t-2.56 6.144v18.432q0 3.584 2.56 6.656t6.656 2.56h201.216q3.584 0 6.144-2.56t2.56-6.656zM365.568 256h85.504l-85.504-85.504v85.504zM512 292.352v192q0 11.776-8.192 19.456t-19.456 8.192h-273.92q-11.776 0-19.456-8.192t-8.192-19.456v-45.568h-155.136q-11.776 0-19.456-8.192t-8.192-18.944v-384q0-11.776 8.192-19.456t19.456-8.192h310.784q11.264 0 19.456 8.192t7.68 19.456v93.696q6.144 3.584 10.24 7.68l116.736 116.736q8.192 7.68 13.824 21.504t5.632 25.088z%27%3E%3C/path%3E%3C/svg%3E%0A")}.ag-icon-arrows{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M512 256q0 7.168-5.632 12.8l-72.704 73.216q-5.632 5.632-13.312 5.632t-12.8-5.632-5.12-12.8v-36.864h-110.080v110.080h36.864q7.168 0 12.8 5.12t5.632 12.8-5.632 12.8l-73.216 73.216q-5.12 5.632-12.8 5.632t-12.8-5.632l-73.216-73.216q-5.632-5.12-5.632-12.8t5.632-12.8 12.8-5.12h36.864v-110.080h-110.080v36.864q0 7.168-5.12 12.8t-12.8 5.632-12.8-5.632l-73.216-73.216q-5.632-5.632-5.632-12.8t5.632-12.8l73.216-73.216q5.12-5.632 12.8-5.632t12.8 5.632 5.12 12.8v36.864h110.080v-110.080h-36.864q-7.168 0-12.8-5.12t-5.632-12.8 5.632-13.312l73.216-72.704q5.632-5.632 12.8-5.632t12.8 5.632l73.216 72.704q5.632 5.632 5.632 13.312t-5.632 12.8-12.8 5.12h-36.864v110.080h110.080v-36.864q0-7.168 5.12-12.8t12.8-5.632 13.312 5.632l72.704 73.216q5.632 5.12 5.632 12.8z%27%3E%3C/path%3E%3C/svg%3E%0A")}.ag-icon-not-allowed{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27m 182.8 238.1 h 145.9 v -55.3 c 0 -20.1 -7.2 -37.4 -21.5 -51.7 s -31.6 -21.3 -51.7 -21 c -20.1 0.3 -37.4 7.3 -51.7 21 s -21.3 30.9 -21 51.7 l -0 55.3 l 0 0 z m 237.6 27.1 v 164.9 c 0 7.5 -2.7 13.8 -8.2 18.9 s -11.9 7.9 -19.5 8.2 h -273.9 c -7.9 0 -14.3 -2.7 -19.5 -8.2 c -5.1 -5.5 -7.9 -11.8 -8.2 -18.9 v -164.9 c 0 -7.5 2.7 -14 8.2 -19.5 s 11.9 -8 19.5 -7.7 h 8.7 v -55.3 c 0 -34.8 12.6 -64.9 37.9 -90.1 s 55.3 -37.9 90.1 -37.9 s 65 12.6 90.6 37.9 s 38.1 55.3 37.4 90.1 v 55.3 h 9.2 c 7.9 0 14.3 2.6 19.5 7.7 s 7.8 11.7 8.2 19.5 z%27/%3E%3C/svg%3E")}.ag-icon-eye-slash{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M 475.6 256.3 q -43.5 -67.6 -109.1 -100.9 q 17.4 29.7 17.4 64 q 0 52.7 -37.4 90.6 t -90.6 37.4 t -90.6 -37.4 t -37.4 -90.6 q 0 -34.3 17.4 -64 q -65.5 33.3 -109.1 100.9 q 38.4 58.4 95.7 93.2 t 123.9 34.8 t 124.4 -34.8 t 95.2 -93.2 z M 269.8 146.2 q 0 -5.6 -4.1 -9.7 t -9.7 -3.6 q -35.8 0 -61.4 25.6 t -25.6 60.9 q 0 5.6 4.1 9.7 t 9.7 4.1 t 9.7 -4.1 t 4.1 -9.7 q 0 -24.6 17.4 -42 t 42 -17.4 q 5.6 0 9.7 -4.1 t 4.1 -9.7 z M 512 256.3 q 0 9.7 -5.6 19.5 q -39.9 66 -107.5 105.5 t -142.8 39.4 t -142.8 -39.4 t -107.5 -105.5 q -5.6 -9.7 -5.6 -19.5 t 5.6 -20 q 39.9 -65.5 107.5 -105 t 142.8 -39.9 t 142.8 39.9 t 107.5 105 q 5.6 10.2 5.6 20 z%27%3E%3C/path%3E%3C/svg%3E%0A")}.ag-icon-group{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M146.4 374.8v55.3q0 11.3-8.2 18.9t-19.5 8.2h-91.1q-11.8 0-19.5-8.2t-8.2-18.9v-55.3q0-11.3 8.2-19.5t19.5-7.7h91.1q11.8 0 19.5 7.7t8.2 19.5zM146.4 228.9v54.8q0 11.3-8.2 19.5t-19.5 7.7h-91.1q-11.8 0-19.5-7.7t-8.2-19.5v-54.8q0-11.8 8.2-19.5t19.5-8.2h91.1q11.8 0 19.5 8.2t8.2 19.5zM512 374.8v55.3q0 11.3-8.2 18.9t-19.5 8.2h-273.9q-11.8 0-19.5-8.2t-8.2-18.9v-55.3q0-11.3 8.2-19.5t19.5-7.7h273.9q11.8 0 19.5 7.7t8.2 19.5zM146.4 82.4v54.8q0 11.3-8.2 19.5t-19.5 8.2h-91.1q-11.8 0-19.5-8.2t-8.2-19.5v-54.8q0-11.3 8.2-19.5t19.5-8.2h91.1q11.8 0 19.5 8.2t8.2 19.5zM512 228.9v54.8q0 11.3-8.2 19.5t-19.5 7.7h-273.9q-11.8 0-19.5-7.7t-8.2-19.5v-54.8q0-11.8 8.2-19.5t19.5-8.2h273.9q11.8 0 19.5 8.2t8.2 19.5zM512 82.4v54.8q0 11.3-8.2 19.5t-19.5 8.2h-273.9q-11.8 0-19.5-8.2t-8.2-19.5v-54.8q0-11.3 8.2-19.5t19.5-8.2h273.9q11.8 0 19.5 8.2t8.2 19.5z%27%3E%3C/path%3E%3C/svg%3E%0A")}.ag-icon-grip{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 16 16%27%3E%3Cpath d=%27M4 3L6 3L6 5L4 5L4 3M4 7L6 7L6 9L4 9L4 7M4 11L6 11L6 13L4 13L4 11M8 3L10 3L10 5L8 5L8 3M8 7L10 7L10 9L8 9L8 7M8 11L10 11L10 13L8 13L8 11%27/%3E%3C/svg%3E%0A");margin:0}.ag-icon-tree-open{-webkit-mask-image:var(--t42-select-indicator);transform:rotate(180deg)}.ag-icon-tree-closed{-webkit-mask-image:var(--t42-select-indicator);transform:rotate(270deg)}.ag-icon-tree-indeterminate{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 -1 5 6%27%3E%3Cpath d=%27M 1 1 A 1 1 0 0 0 1 2 L 4 2 A 1 1 0 0 0 4 1 L 1 1%27/%3E%3C/svg%3E%0A")}.ag-icon-save{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M 420.6 319.2 V 393 c 0 22.9 -8 42.3 -24.1 58.4 s -35.5 24.1 -58.4 24.1 H 100.6 c -22.9 0 -42.3 -8 -58.4 -24.1 S 18.2 415.8 18.2 393 V 155.4 c 0 -22.5 8 -41.8 24.1 -57.9 S 77.7 73.3 100.6 73 h 72.7 c 2.4 0 4.6 1 6.7 3.1 c 2 2 2.9 4.1 2.6 6.1 c 0 5.1 -2.6 8.2 -7.7 9.2 c -14.7 5.1 -27.3 10.9 -37.9 17.4 c -1.7 0.7 -3.2 1 -4.6 1 h -31.7 c -12.6 0 -23.4 4.4 -32.3 13.3 s -13.5 19.6 -13.8 32.3 V 393 c 0 12.6 4.6 23.4 13.8 32.3 c 9.2 8.9 20 13.5 32.3 13.8 h 237.6 c 12.6 0 23.4 -4.6 32.3 -13.8 c 8.9 -9.2 13.3 -20 13.3 -32.3 V 332 c 0 -3.8 1.7 -6.5 5.1 -8.2 c 5.5 -2.4 10.8 -6 15.9 -10.8 c 2.7 -3.1 6 -3.8 9.7 -2 C 418.6 312.7 420.6 315.5 420.6 319.2 L 420.6 319.2 z M 488.2 177.4 L 378.6 287 c -3.4 3.8 -7.7 5.6 -12.8 5.6 c -2.4 0 -4.8 -0.5 -7.2 -1.5 c -7.5 -3.1 -11.3 -8.7 -11.3 -16.9 v -54.8 h -45.6 c -61.8 0 -103.6 12.5 -125.4 37.4 c -22.5 26.3 -29.5 71.3 -21 135.2 c 0.7 4.4 -1.2 7.7 -5.6 9.7 c -1.7 0.3 -2.9 0.5 -3.6 0.5 c -3.1 0 -5.5 -1.2 -7.2 -3.6 c -2 -2.7 -4.1 -5.6 -6.1 -8.7 c -2 -3.1 -5.8 -9.7 -11.3 -20 c -5.5 -10.2 -10.2 -19.6 -14.3 -28.2 c -4.1 -8.5 -7.7 -19.5 -10.8 -32.8 c -3.1 -13.3 -4.8 -24.9 -5.1 -34.8 c 0 -9.2 0.3 -17.9 1 -26.1 c 0.7 -8.2 2 -16.7 4.1 -25.6 c 2 -8.9 4.6 -17.2 7.7 -25.1 c 3.1 -7.9 7.7 -15.5 13.8 -23 c 6.1 -7.5 12.6 -14.7 19.5 -21.5 s 15.7 -12.6 26.6 -17.4 c 10.9 -4.8 22.9 -9.4 35.8 -13.8 c 13 -4.4 28.2 -7.3 45.6 -8.7 s 36.2 -2.4 56.3 -3.1 h 45.6 V 55 c 0 -8.2 3.8 -13.8 11.3 -16.9 c 2.4 -1 4.8 -1.5 7.2 -1.5 c 4.8 0 9 1.9 12.8 5.6 l 109.6 109.6 c 3.8 3.4 5.6 7.7 5.6 12.8 S 491.9 174 488.2 177.4 L 488.2 177.4 z%27/%3E%3C/svg%3E")}.ag-tooltip{padding:0.125rem 0.5rem;border:0.0625rem solid var(--t42-color-opacity-10);border-radius:0.25rem;background:Rgb(var(--t42-bg-light));box-shadow:var(--t42-shadow)}.ag-icon-cancel{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M366.9 336.4c6.1 6.1 9.2 13.5 9.2 22s-3.1 15.9-9.2 22c-6.1 5.5-13.5 8.2-22 8.2c-8.5 0-15.9-2.7-22-8.2l-67.6-77.8l-67.6 77.8c-6.1 5.5-13.5 8.2-22 8.2c-8.5 0-15.9-2.7-22-8.2c-5.5-6.1-8.2-13.5-8.2-22s2.7-15.9 8.2-22l70.7-79.9l-70.7-80.9c-5.5-6.1-8.2-13.5-8.2-22c0-8.5 2.7-15.9 8.2-22c6.1-5.5 13.5-8.2 22-8.2c8.5 0 15.9 2.7 22 8.2l67.6 77.8l67.6-77.8c6.1-5.5 13.5-8.2 22-8.2c8.5 0 15.9 2.7 22 8.2c6.1 6.1 9.2 13.5 9.2 22c0 8.5-3.1 15.9-9.2 22l-70.7 80.9L366.9 336.4z%27/%3E%3C/svg%3E")}.icon-check-empty::after{width:0.65rem;height:0.65rem}.icon-resize-horizontal{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M512 256q0 7.2-5.6 12.8l-72.7 73.2q-5.6 5.6-13.3 5.6t-12.8-5.6t-5.1-12.8v-36.9h-292.9v36.9q0 7.2-5.1 12.8t-12.8 5.6t-12.8-5.6l-73.2-73.2q-5.6-5.6-5.6-12.8t5.6-12.8l73.2-73.2q5.1-5.6 12.8-5.6t12.8 5.6t5.1 12.8v36.9h292.9v-36.9q0-7.2 5.1-12.8t12.8-5.6t13.3 5.6l72.7 73.2q5.6 5.1 5.6 12.8z%27%3E%3C/path%3E%3C/svg%3E%0A")}.ag-icon-aggregation{margin:0 0.25rem;-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 16 16%27%3E%3Cpath d=%27M3.6,1.7c-0.2,0.7-0.9,1.1-1.5,1C1.5,2.6,1,2,1,1.3C1,0.7,1.5,0.1,2.1,0c0.4-0.1,0.7,0,1,0.2C3.4,0.4,3.6,0.7,3.7,1 c0.3,0,0.5,0.1,0.8,0.3C4.7,1.5,5,1.8,5.2,2.1c0.2,0.3,0.4,0.7,0.6,1c0.1,0.2,0.3,0.5,0.5,0.7c0.2,0.2,0.5,0.5,0.8,0.6 c0.1,0.1,0.3,0.1,0.5,0.1c0.6,0,2.3,0,2.9,0c0.4,0,0.7,0,1.1,0c0,0,0,0,0.1,0c0,0,0,0,0-0.1c0-0.1,0-0.2,0-0.3c0,0,0-0.1,0-0.1 c0-0.1,0.1-0.1,0.2-0.1c0.1,0,0.1,0,0.1,0.1c0.1,0,0.1,0.1,0.2,0.2c0.2,0.2,0.3,0.3,0.5,0.5C12.8,4.8,13,5,13.1,5.1c0,0,0,0,0,0 c0,0,0,0-0.1,0c-1.5,0-4.1,0-5.7,0C7.2,5.2,7,5.1,6.8,5C6.6,4.9,6.3,4.8,6.1,4.6C5.7,4.3,5.5,4,5.2,3.5C5,3.2,4.8,2.8,4.6,2.4 C4.4,2.2,4.3,2.1,4.1,1.9C4,1.8,3.9,1.7,3.8,1.7C3.7,1.7,3.7,1.7,3.6,1.7z%27/%3E%3Cpath d=%27M3.6,7.7c1,0,10.6,0,11,0c0.1,0,0.1,0,0.1,0.1C14.8,7.8,14.9,7.9,15,8c-0.1,0.1-0.2,0.2-0.3,0.3c0,0,0,0-0.1,0 c0,0,0,0-0.1,0c-3.3,0-7.7,0-10.9,0C3.5,8.8,3.2,9.1,2.8,9.3C2.5,9.4,2.2,9.4,2,9.3C1.4,9.1,1,8.6,1,8c0-0.7,0.5-1.2,1.1-1.3 c0.3-0.1,0.7,0,1,0.2C3.4,7.1,3.6,7.3,3.6,7.7z%27/%3E%3Cpath d=%27M13.1,10.9C13.1,10.9,13.1,10.9,13.1,10.9c-0.3,0.3-0.6,0.6-0.8,0.8c-0.1,0.1-0.2,0.2-0.3,0.3c0,0-0.1,0.1-0.1,0.1 c0,0-0.1,0-0.1,0c-0.1,0-0.1,0-0.2-0.1c0,0,0-0.1,0-0.1c0-0.1,0-0.2,0-0.3c0,0,0,0,0-0.1c-1,0-3.1,0-4.1,0c-0.1,0-0.3,0-0.4,0.1 c-0.3,0.1-0.5,0.2-0.7,0.4c-0.2,0.2-0.4,0.5-0.6,0.8c-0.2,0.4-0.4,0.7-0.7,1.1c-0.2,0.2-0.4,0.4-0.6,0.6c-0.1,0.1-0.3,0.2-0.4,0.3 c-0.1,0.1-0.3,0.2-0.4,0.2c0,0-0.1,0-0.1,0c-0.1,0.4-0.3,0.7-0.7,0.9C2.7,16,2.4,16,2.1,16C1.5,15.9,1,15.3,1,14.7 c0-0.7,0.5-1.2,1-1.3c0.3-0.1,0.7,0,1,0.2c0.3,0.2,0.5,0.5,0.6,0.8c0.1,0,0.2,0,0.2,0C4,14.2,4.1,14.1,4.2,14 c0.2-0.2,0.3-0.4,0.5-0.6c0.2-0.3,0.4-0.6,0.6-1c0.2-0.3,0.4-0.6,0.6-0.9c0.3-0.2,0.5-0.5,0.9-0.6c0.2-0.1,0.4-0.1,0.6-0.1 c0,0,0.1,0,0.1,0c0.6,0,2.4,0,3,0c0.8,0,1.7,0,2.5,0C13.1,10.9,13.1,10.9,13.1,10.9C13.1,10.9,13.1,10.9,13.1,10.9z%27/%3E%3Cpath d=%27M3.6,11.7c-0.1,0.4-0.3,0.7-0.7,0.9c-0.3,0.2-0.6,0.2-0.9,0.1C1.5,12.6,1,12.1,1,11.4c0-0.7,0.5-1.2,1.1-1.3 c0.3-0.1,0.7,0,1,0.2c0.3,0.2,0.5,0.5,0.6,0.8c0.1,0,0.1,0,0.2,0c0.2,0,0.3-0.1,0.4-0.2c0.2-0.1,0.4-0.3,0.5-0.4 C4.9,10.3,5,10.2,5,10.2C5.3,9.9,5.6,9.7,6,9.6c0.3-0.1,0.6-0.2,0.8-0.2c0.1,0,0.1,0,0.2,0c1.1,0,3.4,0,4.5,0c0.9,0,1.8,0,2.6,0 c0,0,0,0,0.1,0c0,0,0,0,0,0C14,9.6,13.8,9.8,13.6,10c-1.8,0-4.8,0-6.6,0c-0.3,0-0.6,0.1-0.9,0.2c-0.2,0.1-0.5,0.3-0.6,0.5 c-0.3,0.3-0.5,0.5-0.8,0.7c-0.2,0.1-0.4,0.2-0.6,0.3C3.9,11.7,3.8,11.7,3.6,11.7C3.7,11.7,3.7,11.7,3.6,11.7z%27/%3E%3Cpath d=%27M3.6,4.9C3.5,5.3,3.3,5.6,2.9,5.8C2.6,5.9,2.3,6,2,5.9C1.4,5.7,1,5.2,1,4.5c0-0.6,0.5-1.2,1.1-1.3c0.7-0.1,1.4,0.3,1.5,1 c0,0,0.1,0,0.1,0c0.3,0,0.5,0.1,0.7,0.3C4.7,4.7,5,4.9,5.2,5c0.1,0.1,0.2,0.2,0.4,0.4c0.3,0.3,0.6,0.5,1,0.5C6.7,6,6.9,6,7,6 c1.8,0,4.8,0,6.6,0c0.1,0.1,0.3,0.3,0.6,0.6c0,0,0,0,0,0c0,0,0,0,0,0c0,0,0,0-0.1,0c-2,0-5.1,0-7.1,0c-0.3,0-0.5,0-0.8-0.1 C6,6.5,5.7,6.4,5.5,6.2C5.3,6.1,5.1,5.9,5,5.8C4.8,5.5,4.5,5.3,4.2,5.1C4.1,5,3.9,4.9,3.6,4.9z%27/%3E%3C/svg%3E%0A")}.ag-icon-loading{position:relative;width:1rem;height:1rem;border-radius:50%;background:linear-gradient(to right, var(--t42-icon-color), Rgba(var(--t42-bg-dark) 42%));transform:translateZ(0);animation:icon-loading 1.4s infinite linear}.ag-icon-loading::before{position:absolute;top:0;left:0;width:50%;height:50%;border-radius:100% 0 0;background:var(--t42-icon-color);content:""}.ag-icon-loading::after{position:absolute;top:0;right:0;bottom:0;left:0;width:75%;height:75%;margin:auto;border-radius:50%;background:Rgb(var(--t42-bg-dark));content:""}.ag-loading{display:flex;padding-left:0.5rem}@keyframes icon-loading{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.search{position:relative}.search i{position:absolute;top:0.625rem;right:0.75rem;width:.75rem;height:.75rem;background-color:var(--t42-content-color);-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M328.9 219.4q0-52.7-37.4-90.1t-90.6-37.9t-90.6 37.9t-37.4 90.1t37.4 90.6t90.6 37.4t90.6-37.4t37.4-90.6zM475.3 457.5q0 14.8-11.3 25.6t-25.6 10.8q-15.4 0-25.6-10.8l-97.8-97.8q-51.2 35.3-114.2 35.3q-41 0-78.3-15.9t-64-43t-43-64t-15.9-78.3t15.9-77.8t43-64.5t64-43t78.3-15.9t78.3 15.9t64 43t43 64.5t15.9 77.8q0 63-35.3 114.2l97.8 97.8q10.8 10.8 10.8 26.1z%27%3E%3C/path%3E%3C/svg%3E%0A")}.search-results{position:absolute;top:33px;max-height:215px;overflow-y:auto}.search-results .list-group-item{white-space:nowrap}.select{position:relative;z-index:12;display:flex;align-items:center;justify-content:center;width:100%;height:2rem;list-style:none;cursor:pointer}.select input[type="radio"]{opacity:1}.select_expand{position:absolute;top:0;right:0;width:0;height:2rem}.select_expand::after{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:transform;position:absolute;top:50%;right:0;z-index:2;width:1rem;height:1rem;background:var(--t42-select-indicator) center center/1rem 1rem no-repeat;transform:translate(-65%, -55%);content:"";pointer-events:none}.select_expand:checked+.select_close_label+.select_options .select_label:hover{color:var(--t42-link-hover-color);background-color:var(--t42-link-active-bg)}.select_expand:checked::after{transform:translate(-65%, -55%) rotate(-180deg)}.select_expand_label{position:absolute;top:0;left:0;display:block;width:100%;height:2rem;margin-bottom:0;cursor:pointer}.select_close{display:none}.select_close_label{position:fixed;top:0;left:0;display:none;margin-bottom:0}.select_items{position:absolute;top:0;left:0;width:100%;min-height:2rem;border-color:var(--t42-color-opacity-10);border-style:solid;border-width:1px}.select_items:hover{border-color:var(--primary)}.select_input{display:none}.select_label{display:block;height:0;margin-bottom:0;padding-left:0.875rem;overflow:hidden;line-height:2rem;cursor:pointer;transition:all 200ms cubic-bezier(0.4, 0.25, 0.3, 1)}.select_label-placeholder{position:absolute;top:0;left:0;height:2rem;vertical-align:middle;background-color:transparent}.select_expand:checked+.select_close_label{display:block}.select_expand:checked+.select_close_label::before,.select_expand:checked+.select_close_label::after{display:none}.select_expand:checked+.select_close_label+.select_options .select_label{height:2rem}.select_expand:checked+.select_close_label+.select_options+.select_expand_label{display:none}.select_input:checked+.select_label{height:2rem}.select_option label{color:var(--t42-content-color)}.select_options{max-height:10rem;padding-left:0;overflow:auto;list-style:none}.dark{--t42-json-icons: url("data:image/svg+xml,%3C%3Fxml version=%271.0%27 encoding=%27UTF-8%27 standalone=%27no%27%3F%3E%3Csvg xmlns:dc=%27http://purl.org/dc/elements/1.1/%27 xmlns:cc=%27http://creativecommons.org/ns%23%27 xmlns:rdf=%27http://www.w3.org/1999/02/22-rdf-syntax-ns%23%27 xmlns:svg=%27http://www.w3.org/2000/svg%27 xmlns=%27http://www.w3.org/2000/svg%27 xmlns:sodipodi=%27http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd%27 xmlns:inkscape=%27http://www.inkscape.org/namespaces/inkscape%27 width=%27240%27 height=%27144%27 id=%27svg4136%27 version=%271.1%27 inkscape:version=%270.91 r13725%27 sodipodi:docname=%27jsoneditor-icons.svg%27%3E%3Ctitle id=%27title6512%27%3EJSON Editor Icons%3C/title%3E%3Crect id=%27svg_1-7%27 height=%2716%27 width=%2716%27 y=%273.999995%27 x=%2728.000006%27 style=%27fill:%23ff511f;%27 /%3E%3Crect x=%277%27 y=%2711%27 width=%2710%27 height=%272%27 id=%27svg_1-1%27 style=%27fill:%23ffffff;%27 /%3E%3Crect x=%2711%27 y=%277%27 width=%272%27 height=%2710%27 id=%27svg_1-1-1%27 style=%27fill:%23ffffff;%27 /%3E%3Cg id=%27g4299-3%27 transform=%27matrix%280.70710678,-0.70710678,0.70710678,0.70710678,19.029435,12.000001%29%27 style=%27%27%3E%3Crect x=%277%27 y=%2711%27 width=%2710%27 height=%272%27 id=%27svg_1-1-0%27 style=%27fill:%23ffffff;%27 /%3E%3Crect x=%2711%27 y=%277%27 width=%272%27 height=%2710%27 id=%27svg_1-1-1-9%27 style=%27fill:%23ffffff;%27 /%3E%3C/g%3E%3Crect height=%277%27 width=%277%27 y=%277%27 x=%2755%27 style=%27fill:%23ffffff;stroke-width:1;stroke:%23ffffff%27 /%3E%3Crect id=%27svg_1-7-5-7%27 height=%277%27 width=%277%27 y=%2710%27 x=%2758%27 style=%27fill:%23ffffff;stroke-width:1;stroke:%231d1d1d%27 /%3E%3Cg id=%27g4378%27%3E%3Crect style=%27fill:%23ffffff;%27 x=%27198%27 y=%2711%27 width=%278%27 height=%272%27 id=%27svg_1-7-5-3%27 /%3E%3Crect id=%27rect4374%27 height=%272%27 width=%2712%27 y=%277%27 x=%27198%27 style=%27fill:%23ffffff;%27 /%3E%3Crect id=%27rect4376%27 height=%272%27 width=%274%27 y=%2715%27 x=%27198%27 style=%27fill:%23ffffff;%27 /%3E%3C/g%3E%3Cg transform=%27matrix%281,0,0,-1,-23.999995,23.999995%29%27 id=%27g4383%27%3E%3Crect id=%27rect4385%27 height=%272%27 width=%278%27 y=%2711%27 x=%27198%27 style=%27fill:%23ffffff;%27 /%3E%3Crect style=%27fill:%23ffffff;%27 x=%27198%27 y=%277%27 width=%2712%27 height=%272%27 id=%27rect4387%27 /%3E%3Crect style=%27fill:%23ffffff;%27 x=%27198%27 y=%2715%27 width=%274%27 height=%272%27 id=%27rect4389%27 /%3E%3C/g%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 85.10447,6.0157384 -0.0156,1.4063 c 3.02669,-0.2402 0.33008,3.6507996 2.48438,4.5780996 -2.18694,1.0938 0.49191,4.9069 -2.45313,4.5781 l -0.0156,1.4219 c 5.70828,0.559 1.03264,-5.1005 4.70313,-5.2656 l 0,-1.4063 c -3.61303,-0.027 1.11893,-5.7069996 -4.70313,-5.3124996 z%27 id=%27path4351%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 82.78125,5.9984384 0.0156,1.4063 c -3.02668,-0.2402 -0.33007,3.6506996 -2.48437,4.5780996 2.18694,1.0938 -0.49192,4.9069 2.45312,4.5781 l 0.0156,1.4219 c -5.70827,0.559 -1.03263,-5.1004 -4.70312,-5.2656 l 0,-1.4063 c 3.61303,-0.027 -1.11894,-5.7070996 4.70312,-5.3124996 z%27 id=%27path4351-9%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 103.719,5.6719384 0,12.7187996 3.03125,0 0,-1.5313 -1.34375,0 0,-9.6249996 1.375,0 0,-1.5625 z%27 id=%27path2987%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 112.2185,5.6721984 0,12.7187996 -3.03125,0 0,-1.5313 1.34375,0 0,-9.6249996 -1.375,0 0,-1.5625 z%27 id=%27path2987-1%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27M133,6.4h-1.9l-4.8,11.2h1.8l1.1-2.9h5.7l1.1,2.9h1.8L133,6.4z M129.7,13.5l2.3-5.5l2.3,5.5L129.7,13.5z%27 id=%27path3780%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 156.47655,5.8917384 0,2.1797 0.46093,2.3983996 1.82813,0 0.39844,-2.3983996 0,-2.1797 z%27 id=%27path5008-2%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 152.51561,5.8906384 0,2.1797 0.46094,2.3983996 1.82812,0 0.39844,-2.3983996 0,-2.1797 z%27 id=%27path5008-2-8%27 /%3E%3Crect id=%27svg_1-7-2%27 height=%272%27 width=%2712%27 y=%2764%27 x=%2754%27 style=%27fill:%236e6e6e;%27 /%3E%3Crect id=%27svg_1-7-2-2%27 height=%273%27 width=%273%27 y=%2752%27 x=%2780%27 style=%27fill:%236e6e6e;%27 /%3E%3Crect style=%27fill:%236e6e6e;%27 x=%2785%27 y=%2752%27 width=%273%27 height=%273%27 id=%27rect4561%27 /%3E%3Crect style=%27fill:%236e6e6e;%27 x=%2780%27 y=%2758%27 width=%273%27 height=%273%27 id=%27rect4563%27 /%3E%3Crect id=%27rect4565%27 height=%273%27 width=%273%27 y=%2758%27 x=%2785%27 style=%27fill:%236e6e6e;%27 /%3E%3Crect id=%27rect4567%27 height=%273%27 width=%273%27 y=%2764%27 x=%2780%27 style=%27fill:%236e6e6e;%27 /%3E%3Crect style=%27fill:%236e6e6e;%27 x=%2785%27 y=%2764%27 width=%273%27 height=%273%27 id=%27rect4569%27 /%3E%3Ccircle style=%27opacity:1;fill:none;stroke:%236e6e6e;stroke-width:2;%27 id=%27path4571%27 cx=%27110.06081%27 cy=%2757.939209%27 r=%274.7438836%27 /%3E%3Crect style=%27fill:%236e6e6e;%27 x=%27116.64566%27 y=%27-31.79752%27 width=%274.229713%27 height=%276.4053884%27 id=%27rect4563-2%27 transform=%27matrix%280.70710678,0.70710678,-0.70710678,0.70710678,0,0%29%27 /%3E%3Cpath style=%27fill:%236e6e6e;fill-rule:evenodd;%27 d=%27M 125,56 138.77027,56.095 132,64 Z%27 id=%27path4613%27 /%3E%3Cpath id=%27path4615%27 d=%27M 149,64 162.77027,63.905 156,56 Z%27 style=%27fill:%236e6e6e;fill-rule:evenodd;%27 /%3E%3Crect style=%27fill:%236e6e6e;%27 x=%2754%27 y=%2753%27 width=%2712%27 height=%272%27 id=%27rect4638%27 /%3E%3Crect id=%27svg_1-7-2-24%27 height=%272%27 width=%2713%27 y=%27-56%27 x=%2753%27 style=%27fill:%236e6e6e;%27 transform=%27matrix%280,1,-1,0,0,0%29%27 /%3E%3Crect transform=%27matrix%280,1,-1,0,0,0%29%27 style=%27fill:%236e6e6e;%27 x=%2753%27 y=%27-66%27 width=%2713%27 height=%272%27 id=%27rect4657%27 /%3E%3Crect id=%27rect4659%27 height=%271%27 width=%2712%27 y=%2757%27 x=%2754%27 style=%27fill:%236e6e6e;%27 /%3E%3Crect style=%27fill:%23ffffff;%27 x=%2754%27 y=%2788%27 width=%2712%27 height=%272%27 id=%27rect4661%27 /%3E%3Crect style=%27fill:%23ffffff;%27 x=%2780%27 y=%2776%27 width=%273%27 height=%273%27 id=%27rect4663%27 /%3E%3Crect id=%27rect4665%27 height=%273%27 width=%273%27 y=%2776%27 x=%2785%27 style=%27fill:%23ffffff;%27 /%3E%3Crect id=%27rect4667%27 height=%273%27 width=%273%27 y=%2782%27 x=%2780%27 style=%27fill:%23ffffff;%27 /%3E%3Crect style=%27fill:%23ffffff;%27 x=%2785%27 y=%2782%27 width=%273%27 height=%273%27 id=%27rect4669%27 /%3E%3Crect style=%27fill:%23ffffff;%27 x=%2780%27 y=%2788%27 width=%273%27 height=%273%27 id=%27rect4671%27 /%3E%3Crect id=%27rect4673%27 height=%273%27 width=%273%27 y=%2788%27 x=%2785%27 style=%27fill:%23ffffff;%27 /%3E%3Ccircle r=%274.7438836%27 cy=%2781.939331%27 cx=%27110.06081%27 id=%27circle4675%27 style=%27opacity:1;fill:none;stroke:%23ffffff;stroke-width:2;%27 /%3E%3Crect transform=%27matrix%280.70710678,0.70710678,-0.70710678,0.70710678,0,0%29%27 id=%27rect4677%27 height=%276.4053884%27 width=%274.229713%27 y=%27-14.826816%27 x=%27133.6163%27 style=%27fill:%23ffffff;%27 /%3E%3Cpath id=%27path4679%27 d=%27m 125,80.000005 13.77027,0.09499 L 132,87.999992 Z%27 style=%27fill:%23ffffff;%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27M 149,88.0002 162.77027,87.9052 156,80.0002 Z%27 id=%27path4681%27 /%3E%3Crect id=%27rect4683%27 height=%272%27 width=%2712%27 y=%2777%27 x=%2754%27 style=%27fill:%23ffffff;%27 /%3E%3Crect transform=%27matrix%280,1,-1,0,0,0%29%27 style=%27fill:%23ffffff;%27 x=%2777%27 y=%27-56%27 width=%2713%27 height=%272%27 id=%27rect4685%27 /%3E%3Crect id=%27rect4687%27 height=%272%27 width=%2713%27 y=%27-66%27 x=%2777%27 style=%27fill:%23ffffff;%27 transform=%27matrix%280,1,-1,0,0,0%29%27 /%3E%3Crect style=%27fill:%23ffffff;%27 x=%2754%27 y=%2781%27 width=%2712%27 height=%271%27 id=%27rect4689%27 /%3E%3Crect id=%27rect4761-1%27 height=%272%27 width=%2716%27 y=%27101%27 x=%2776%27 style=%27fill:%23ffffff;%27 /%3E%3Crect id=%27rect4761-0%27 height=%272%27 width=%2716%27 y=%27105%27 x=%2776%27 style=%27fill:%23ffffff;%27 /%3E%3Crect id=%27rect4761-7%27 height=%272%27 width=%279%27 y=%27109%27 x=%2776%27 style=%27fill:%23ffffff;%27 /%3E%3Crect id=%27rect4761-1-1%27 height=%272%27 width=%2712%27 y=%27125%27 x=%2776%27 style=%27fill:%23ffffff;%27 /%3E%3Crect id=%27rect4761-1-1-4%27 height=%272%27 width=%2710%27 y=%27137%27 x=%2776%27 style=%27fill:%23ffffff;%27 /%3E%3Crect id=%27rect4761-1-1-4-4%27 height=%272%27 width=%2710%27 y=%27129%27 x=%2782%27 style=%27fill:%23ffffff;%27 /%3E%3Crect id=%27rect4761-1-1-4-4-3%27 height=%272%27 width=%279%27 y=%27133%27 x=%2782%27 style=%27fill:%23ffffff;%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 36.398438,100.0254 c -0.423362,-0.013 -0.846847,0.01 -1.265626,0.062 -1.656562,0.2196 -3.244567,0.9739 -4.507812,2.2266 L 29,100.5991 l -2.324219,7.7129 7.826172,-1.9062 -1.804687,-1.9063 c 1.597702,-1.5308 4.048706,-1.8453 5.984375,-0.7207 1.971162,1.1452 2.881954,3.3975 2.308593,5.5508 -0.573361,2.1533 -2.533865,3.6953 -4.830078,3.6953 l 0,3.0742 c 3.550756,0 6.710442,-2.4113 7.650391,-5.9414 0.939949,-3.5301 -0.618463,-7.2736 -3.710938,-9.0703 -1.159678,-0.6738 -2.431087,-1.0231 -3.701171,-1.0625 z%27 id=%27path4138%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 59.722656,99.9629 c -1.270084,0.039 -2.541493,0.3887 -3.701172,1.0625 -3.092475,1.7967 -4.650886,5.5402 -3.710937,9.0703 0.939949,3.5301 4.09768,5.9414 7.648437,5.9414 l 0,-3.0742 c -2.296214,0 -4.256717,-1.542 -4.830078,-3.6953 -0.573361,-2.1533 0.337432,-4.4056 2.308594,-5.5508 1.935731,-1.1246 4.38863,-0.8102 5.986326,0.7207 l -1.806638,1.9063 7.828128,1.9062 -2.32422,-7.7129 -1.62696,1.7168 c -1.26338,-1.2531 -2.848917,-2.0088 -4.505855,-2.2285 -0.418778,-0.055 -0.842263,-0.076 -1.265625,-0.062 z%27 id=%27path4138-1%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 10.5,100 0,2 -2.4999996,0 L 12,107 l 4,-5 -2.5,0 0,-2 -3,0 z%27 id=%27path3055-0-77%27 /%3E%3Cpath style=%27fill:none;stroke:%23ffffff;%27 d=%27m 4.9850574,108.015 14.0298856,-0.03%27 id=%27path5244-5-0-5%27 /%3E%3Cpath style=%27fill:none;stroke:%23ffffff;%27 d=%27m 4.9849874,132.015 14.0298866,-0.03%27 id=%27path5244-5-0-5-8%27 /%3E%3Cpath style=%27color:%23000000;fill:%236e6e6e;%27 d=%27m 36.398438,123.9629 c -0.423362,-0.013 -0.846847,0.01 -1.265626,0.062 -1.656562,0.2196 -3.244567,0.9739 -4.507812,2.2266 L 29,124.5366 l -2.324219,7.7129 7.826172,-1.9062 -1.804687,-1.9063 c 1.597702,-1.5308 4.048706,-1.8453 5.984375,-0.7207 1.971162,1.1453 2.881954,3.3975 2.308593,5.5508 -0.573361,2.1533 -2.533864,3.6953 -4.830078,3.6953 l 0,3.0742 c 3.550757,0 6.710442,-2.4093 7.650391,-5.9394 0.939949,-3.5301 -0.618463,-7.2756 -3.710938,-9.0723 -1.159678,-0.6737 -2.431087,-1.0231 -3.701171,-1.0625 z%27 id=%27path4138-12%27 /%3E%3Cpath style=%27color:%23000000;fill:%236e6e6e;%27 d=%27m 59.722656,123.9629 c -1.270084,0.039 -2.541493,0.3888 -3.701172,1.0625 -3.092475,1.7967 -4.650886,5.5422 -3.710937,9.0723 0.939949,3.5301 4.09768,5.9394 7.648437,5.9394 l 0,-3.0742 c -2.296214,0 -4.256717,-1.542 -4.830078,-3.6953 -0.573361,-2.1533 0.337432,-4.4055 2.308594,-5.5508 1.935731,-1.1246 4.38863,-0.8102 5.986326,0.7207 l -1.806638,1.9063 7.828128,1.9062 -2.32422,-7.7129 -1.62696,1.7168 c -1.26338,-1.2531 -2.848917,-2.0088 -4.505855,-2.2285 -0.418778,-0.055 -0.842263,-0.076 -1.265625,-0.062 z%27 id=%27path4138-1-3%27 /%3E%3Cpath id=%27path6191%27 d=%27m 10.5,116 0,-2 -2.4999996,0 L 12,109 l 4,5 -2.5,0 0,2 -3,0 z%27 style=%27fill:%23ffffff;stroke-width:1.96599996;%27 /%3E%3Cpath style=%27fill:%23ffffff;stroke-width:1.96599996;%27 d=%27m 10.5,129 0,-2 -2.4999996,0 L 12,122 l 4,5 -2.5,0 0,2 -3,0 z%27 id=%27path6193%27 /%3E%3Cpath id=%27path6195%27 d=%27m 10.5,135 0,2 -2.4999996,0 L 12,142 l 4,-5 -2.5,0 0,-2 -3,0 z%27 style=%27fill:%23ffffff;stroke-width:1.96599996;%27 /%3E%3Cpath sodipodi:type=%27star%27 style=%27fill:%236e6e6e;%27 id=%27path4500%27 sodipodi:sides=%273%27 sodipodi:cx=%2711.55581%27 sodipodi:cy=%2760.073242%27 sodipodi:r1=%275.1116104%27 sodipodi:r2=%272.5558052%27 sodipodi:arg1=%270%27 sodipodi:arg2=%271.0471976%27 inkscape:flatsided=%27false%27 inkscape:rounded=%270%27 inkscape:randomized=%270%27 d=%27m 16.66742,60.073242 -3.833708,2.213392 -3.8337072,2.213393 0,-4.426785 0,-4.426784 3.8337082,2.213392 z%27 inkscape:transform-center-x=%27-1.2779026%27 /%3E%3Cpath inkscape:transform-center-x=%271.277902%27 d=%27m -31.500004,60.073242 -3.833708,2.213392 -3.833707,2.213393 0,-4.426785 0,-4.426784 3.833707,2.213392 z%27 inkscape:randomized=%270%27 inkscape:rounded=%270%27 inkscape:flatsided=%27false%27 sodipodi:arg2=%271.0471976%27 sodipodi:arg1=%270%27 sodipodi:r2=%272.5558052%27 sodipodi:r1=%275.1116104%27 sodipodi:cy=%2760.073242%27 sodipodi:cx=%27-36.611614%27 sodipodi:sides=%273%27 id=%27path4502%27 style=%27fill:%236e6e6e;%27 sodipodi:type=%27star%27 transform=%27scale%28-1,1%29%27 /%3E%3Cpath d=%27m 16.66742,60.073212 -3.833708,2.213392 -3.8337072,2.213392 0,-4.426784 0,-4.426785 3.8337082,2.213392 z%27 inkscape:randomized=%270%27 inkscape:rounded=%270%27 inkscape:flatsided=%27false%27 sodipodi:arg2=%271.0471976%27 sodipodi:arg1=%270%27 sodipodi:r2=%272.5558052%27 sodipodi:r1=%275.1116104%27 sodipodi:cy=%2760.073212%27 sodipodi:cx=%2711.55581%27 sodipodi:sides=%273%27 id=%27path4504%27 style=%27fill:%236e6e6e;%27 sodipodi:type=%27star%27 transform=%27matrix%280,1,-1,0,72.0074,71.7877%29%27 inkscape:transform-center-y=%271.2779029%27 /%3E%3Cpath inkscape:transform-center-y=%27-1.2779026%27 transform=%27matrix%280,-1,-1,0,96,96%29%27 sodipodi:type=%27star%27 style=%27fill:%236e6e6e;%27 id=%27path4506%27 sodipodi:sides=%273%27 sodipodi:cx=%2711.55581%27 sodipodi:cy=%2760.073212%27 sodipodi:r1=%275.1116104%27 sodipodi:r2=%272.5558052%27 sodipodi:arg1=%270%27 sodipodi:arg2=%271.0471976%27 inkscape:flatsided=%27false%27 inkscape:rounded=%270%27 inkscape:randomized=%270%27 d=%27m 16.66742,60.073212 -3.833708,2.213392 -3.8337072,2.213392 0,-4.426784 0,-4.426785 3.8337082,2.213392 z%27 /%3E%3Cpath id=%27path4615-5%27 d=%27m 171.82574,65.174193 16.34854,0 -8.17427,-13.348454 z%27 style=%27fill:%23f9a825;fill-rule:evenodd;stroke:%23f9a825;stroke-width:2;%27 /%3E%3Cpath style=%27opacity:1;fill:%23ffffff;%27 d=%27m 179,55 0,6 2,0 0,-6%27 id=%27path4300%27 /%3E%3Cpath style=%27opacity:1;fill:%23ffffff;%27 d=%27m 179,62 0,2 2,0 0,-2%27 id=%27path4300-6%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27M 99.994369,113.0221 102,114.98353 l 7,-6.9558 3,0.97227 2,-1 1,-2 0,-3 -3,3 -3,-3 3,-3 -3,0 -2,1 -1,2 0.99437,3.0221 z%27 id=%27path4268%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 234,6 0,2 -5,5 0,5 -2,0 0,-5 -5,-5 0,-2%27 id=%27path3546%27 /%3E%3Cg transform=%27matrix%281.3333328,0,0,-1.5999992,-139.9999,127.19999%29%27 id=%27g4383-6%27%3E%3Crect id=%27rect4385-2%27 height=%271%27 width=%276%27 y=%2712.625005%27 x=%27198%27 style=%27fill:%23ffffff;stroke:%23000000;stroke-width:0%27 /%3E%3Crect style=%27fill:%23ffffff;stroke:%23000000;stroke-width:0%27 x=%27198%27 y=%2715.125007%27 width=%278%27 height=%271%27 id=%27rect4387-9%27 /%3E%3Crect style=%27fill:%23ffffff;stroke:%23000000;stroke-width:0%27 x=%27198%27 y=%277.6250024%27 width=%273%27 height=%271%27 id=%27rect4389-1-0%27 /%3E%3Crect style=%27fill:%23ffffff;stroke:%23000000;stroke-width:0%27 x=%27198%27 y=%2710.125004%27 width=%274%27 height=%271%27 id=%27rect4389-1-9%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 207.00001,16.375004 0,-5.625005 -2.25,0 3,-3.1250014 3,3.1250014 -2.25,0 0,5.625005 -1.5,0%27 id=%27path4402%27 /%3E%3C/g%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 164,100 0,3 -6,6 0,7 -4,0 0,-7 -6,-6 0,-3%27 id=%27path3546-2-2%27 /%3E%3Cpath id=%27path4402-5-7%27 d=%27m 15,41 0,-7 -4,0 0,3 -5,-4 5,-4 0,3 6,0 0,9%27 style=%27fill:%23ffffff;%27 /%3E%3C/svg%3E%0A")}.light{--t42-json-icons: url("data:image/svg+xml,%3C%3Fxml version=%271.0%27 encoding=%27UTF-8%27 standalone=%27no%27%3F%3E%3Csvg xmlns:dc=%27http://purl.org/dc/elements/1.1/%27 xmlns:cc=%27http://creativecommons.org/ns%23%27 xmlns:rdf=%27http://www.w3.org/1999/02/22-rdf-syntax-ns%23%27 xmlns:svg=%27http://www.w3.org/2000/svg%27 xmlns=%27http://www.w3.org/2000/svg%27 xmlns:sodipodi=%27http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd%27 xmlns:inkscape=%27http://www.inkscape.org/namespaces/inkscape%27 width=%27240%27 height=%27144%27 id=%27svg4136%27 version=%271.1%27 inkscape:version=%270.91 r13725%27 sodipodi:docname=%27jsoneditor-icons.svg%27%3E%3Ctitle id=%27title6512%27%3EJSON Editor Icons%3C/title%3E%3Crect id=%27svg_1-7%27 height=%2716%27 width=%2716%27 y=%273.999995%27 x=%2728.000006%27 style=%27fill:%23ff511f;%27 /%3E%3Crect x=%277%27 y=%2711%27 width=%2710%27 height=%272%27 id=%27svg_1-1%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect x=%2711%27 y=%277%27 width=%272%27 height=%2710%27 id=%27svg_1-1-1%27 style=%27fill:%230d0d0d;%27 /%3E%3Cg id=%27g4299-3%27 transform=%27matrix%280.70710678,-0.70710678,0.70710678,0.70710678,19.029435,12.000001%29%27 style=%27%27%3E%3Crect x=%277%27 y=%2711%27 width=%2710%27 height=%272%27 id=%27svg_1-1-0%27 style=%27fill:%23ffffff;%27 /%3E%3Crect x=%2711%27 y=%277%27 width=%272%27 height=%2710%27 id=%27svg_1-1-1-9%27 style=%27fill:%23ffffff;%27 /%3E%3C/g%3E%3Crect height=%277%27 width=%277%27 y=%277%27 x=%2755%27 style=%27fill:%230d0d0d;stroke-width:1;stroke:%230d0d0d%27 /%3E%3Crect id=%27svg_1-7-5-7%27 height=%277%27 width=%277%27 y=%2710%27 x=%2758%27 style=%27fill:%230d0d0d;stroke-width:1;stroke:%23ffffff%27 /%3E%3Cg id=%27g4378%27%3E%3Crect style=%27fill:%230d0d0d;%27 x=%27198%27 y=%2711%27 width=%278%27 height=%272%27 id=%27svg_1-7-5-3%27 /%3E%3Crect id=%27rect4374%27 height=%272%27 width=%2712%27 y=%277%27 x=%27198%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect id=%27rect4376%27 height=%272%27 width=%274%27 y=%2715%27 x=%27198%27 style=%27fill:%230d0d0d;%27 /%3E%3C/g%3E%3Cg transform=%27matrix%281,0,0,-1,-23.999995,23.999995%29%27 id=%27g4383%27%3E%3Crect id=%27rect4385%27 height=%272%27 width=%278%27 y=%2711%27 x=%27198%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect style=%27fill:%230d0d0d;%27 x=%27198%27 y=%277%27 width=%2712%27 height=%272%27 id=%27rect4387%27 /%3E%3Crect style=%27fill:%230d0d0d;%27 x=%27198%27 y=%2715%27 width=%274%27 height=%272%27 id=%27rect4389%27 /%3E%3C/g%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 85.10447,6.0157384 -0.0156,1.4063 c 3.02669,-0.2402 0.33008,3.6507996 2.48438,4.5780996 -2.18694,1.0938 0.49191,4.9069 -2.45313,4.5781 l -0.0156,1.4219 c 5.70828,0.559 1.03264,-5.1005 4.70313,-5.2656 l 0,-1.4063 c -3.61303,-0.027 1.11893,-5.7069996 -4.70313,-5.3124996 z%27 id=%27path4351%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 82.78125,5.9984384 0.0156,1.4063 c -3.02668,-0.2402 -0.33007,3.6506996 -2.48437,4.5780996 2.18694,1.0938 -0.49192,4.9069 2.45312,4.5781 l 0.0156,1.4219 c -5.70827,0.559 -1.03263,-5.1004 -4.70312,-5.2656 l 0,-1.4063 c 3.61303,-0.027 -1.11894,-5.7070996 4.70312,-5.3124996 z%27 id=%27path4351-9%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 103.719,5.6719384 0,12.7187996 3.03125,0 0,-1.5313 -1.34375,0 0,-9.6249996 1.375,0 0,-1.5625 z%27 id=%27path2987%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 112.2185,5.6721984 0,12.7187996 -3.03125,0 0,-1.5313 1.34375,0 0,-9.6249996 -1.375,0 0,-1.5625 z%27 id=%27path2987-1%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27M133,6.4h-1.9l-4.8,11.2h1.8l1.1-2.9h5.7l1.1,2.9h1.8L133,6.4z M129.7,13.5l2.3-5.5l2.3,5.5L129.7,13.5z%27 id=%27path3780%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 156.47655,5.8917384 0,2.1797 0.46093,2.3983996 1.82813,0 0.39844,-2.3983996 0,-2.1797 z%27 id=%27path5008-2%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 152.51561,5.8906384 0,2.1797 0.46094,2.3983996 1.82812,0 0.39844,-2.3983996 0,-2.1797 z%27 id=%27path5008-2-8%27 /%3E%3Crect id=%27svg_1-7-2%27 height=%272%27 width=%2712%27 y=%2764%27 x=%2754%27 style=%27fill:%236e6e6e;%27 /%3E%3Crect id=%27svg_1-7-2-2%27 height=%273%27 width=%273%27 y=%2752%27 x=%2780%27 style=%27fill:%236e6e6e;%27 /%3E%3Crect style=%27fill:%236e6e6e;%27 x=%2785%27 y=%2752%27 width=%273%27 height=%273%27 id=%27rect4561%27 /%3E%3Crect style=%27fill:%236e6e6e;%27 x=%2780%27 y=%2758%27 width=%273%27 height=%273%27 id=%27rect4563%27 /%3E%3Crect id=%27rect4565%27 height=%273%27 width=%273%27 y=%2758%27 x=%2785%27 style=%27fill:%236e6e6e;%27 /%3E%3Crect id=%27rect4567%27 height=%273%27 width=%273%27 y=%2764%27 x=%2780%27 style=%27fill:%236e6e6e;%27 /%3E%3Crect style=%27fill:%236e6e6e;%27 x=%2785%27 y=%2764%27 width=%273%27 height=%273%27 id=%27rect4569%27 /%3E%3Ccircle style=%27opacity:1;fill:none;stroke:%236e6e6e;stroke-width:2;%27 id=%27path4571%27 cx=%27110.06081%27 cy=%2757.939209%27 r=%274.7438836%27 /%3E%3Crect style=%27fill:%236e6e6e;%27 x=%27116.64566%27 y=%27-31.79752%27 width=%274.229713%27 height=%276.4053884%27 id=%27rect4563-2%27 transform=%27matrix%280.70710678,0.70710678,-0.70710678,0.70710678,0,0%29%27 /%3E%3Cpath style=%27fill:%236e6e6e;fill-rule:evenodd;%27 d=%27M 125,56 138.77027,56.095 132,64 Z%27 id=%27path4613%27 /%3E%3Cpath id=%27path4615%27 d=%27M 149,64 162.77027,63.905 156,56 Z%27 style=%27fill:%236e6e6e;fill-rule:evenodd;%27 /%3E%3Crect style=%27fill:%236e6e6e;%27 x=%2754%27 y=%2753%27 width=%2712%27 height=%272%27 id=%27rect4638%27 /%3E%3Crect id=%27svg_1-7-2-24%27 height=%272%27 width=%2713%27 y=%27-56%27 x=%2753%27 style=%27fill:%236e6e6e;%27 transform=%27matrix%280,1,-1,0,0,0%29%27 /%3E%3Crect transform=%27matrix%280,1,-1,0,0,0%29%27 style=%27fill:%236e6e6e;%27 x=%2753%27 y=%27-66%27 width=%2713%27 height=%272%27 id=%27rect4657%27 /%3E%3Crect id=%27rect4659%27 height=%271%27 width=%2712%27 y=%2757%27 x=%2754%27 style=%27fill:%236e6e6e;%27 /%3E%3Crect style=%27fill:%230d0d0d;%27 x=%2754%27 y=%2788%27 width=%2712%27 height=%272%27 id=%27rect4661%27 /%3E%3Crect style=%27fill:%230d0d0d;%27 x=%2780%27 y=%2776%27 width=%273%27 height=%273%27 id=%27rect4663%27 /%3E%3Crect id=%27rect4665%27 height=%273%27 width=%273%27 y=%2776%27 x=%2785%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect id=%27rect4667%27 height=%273%27 width=%273%27 y=%2782%27 x=%2780%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect style=%27fill:%230d0d0d;%27 x=%2785%27 y=%2782%27 width=%273%27 height=%273%27 id=%27rect4669%27 /%3E%3Crect style=%27fill:%230d0d0d;%27 x=%2780%27 y=%2788%27 width=%273%27 height=%273%27 id=%27rect4671%27 /%3E%3Crect id=%27rect4673%27 height=%273%27 width=%273%27 y=%2788%27 x=%2785%27 style=%27fill:%230d0d0d;%27 /%3E%3Ccircle r=%274.7438836%27 cy=%2781.939331%27 cx=%27110.06081%27 id=%27circle4675%27 style=%27opacity:1;fill:none;stroke:%230d0d0d;stroke-width:2;%27 /%3E%3Crect transform=%27matrix%280.70710678,0.70710678,-0.70710678,0.70710678,0,0%29%27 id=%27rect4677%27 height=%276.4053884%27 width=%274.229713%27 y=%27-14.826816%27 x=%27133.6163%27 style=%27fill:%230d0d0d;%27 /%3E%3Cpath id=%27path4679%27 d=%27m 125,80.000005 13.77027,0.09499 L 132,87.999992 Z%27 style=%27fill:%230d0d0d;%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27M 149,88.0002 162.77027,87.9052 156,80.0002 Z%27 id=%27path4681%27 /%3E%3Crect id=%27rect4683%27 height=%272%27 width=%2712%27 y=%2777%27 x=%2754%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect transform=%27matrix%280,1,-1,0,0,0%29%27 style=%27fill:%230d0d0d;%27 x=%2777%27 y=%27-56%27 width=%2713%27 height=%272%27 id=%27rect4685%27 /%3E%3Crect id=%27rect4687%27 height=%272%27 width=%2713%27 y=%27-66%27 x=%2777%27 style=%27fill:%230d0d0d;%27 transform=%27matrix%280,1,-1,0,0,0%29%27 /%3E%3Crect style=%27fill:%230d0d0d;%27 x=%2754%27 y=%2781%27 width=%2712%27 height=%271%27 id=%27rect4689%27 /%3E%3Crect id=%27rect4761-1%27 height=%272%27 width=%2716%27 y=%27101%27 x=%2776%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect id=%27rect4761-0%27 height=%272%27 width=%2716%27 y=%27105%27 x=%2776%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect id=%27rect4761-7%27 height=%272%27 width=%279%27 y=%27109%27 x=%2776%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect id=%27rect4761-1-1%27 height=%272%27 width=%2712%27 y=%27125%27 x=%2776%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect id=%27rect4761-1-1-4%27 height=%272%27 width=%2710%27 y=%27137%27 x=%2776%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect id=%27rect4761-1-1-4-4%27 height=%272%27 width=%2710%27 y=%27129%27 x=%2782%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect id=%27rect4761-1-1-4-4-3%27 height=%272%27 width=%279%27 y=%27133%27 x=%2782%27 style=%27fill:%230d0d0d;%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 36.398438,100.0254 c -0.423362,-0.013 -0.846847,0.01 -1.265626,0.062 -1.656562,0.2196 -3.244567,0.9739 -4.507812,2.2266 L 29,100.5991 l -2.324219,7.7129 7.826172,-1.9062 -1.804687,-1.9063 c 1.597702,-1.5308 4.048706,-1.8453 5.984375,-0.7207 1.971162,1.1452 2.881954,3.3975 2.308593,5.5508 -0.573361,2.1533 -2.533865,3.6953 -4.830078,3.6953 l 0,3.0742 c 3.550756,0 6.710442,-2.4113 7.650391,-5.9414 0.939949,-3.5301 -0.618463,-7.2736 -3.710938,-9.0703 -1.159678,-0.6738 -2.431087,-1.0231 -3.701171,-1.0625 z%27 id=%27path4138%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 59.722656,99.9629 c -1.270084,0.039 -2.541493,0.3887 -3.701172,1.0625 -3.092475,1.7967 -4.650886,5.5402 -3.710937,9.0703 0.939949,3.5301 4.09768,5.9414 7.648437,5.9414 l 0,-3.0742 c -2.296214,0 -4.256717,-1.542 -4.830078,-3.6953 -0.573361,-2.1533 0.337432,-4.4056 2.308594,-5.5508 1.935731,-1.1246 4.38863,-0.8102 5.986326,0.7207 l -1.806638,1.9063 7.828128,1.9062 -2.32422,-7.7129 -1.62696,1.7168 c -1.26338,-1.2531 -2.848917,-2.0088 -4.505855,-2.2285 -0.418778,-0.055 -0.842263,-0.076 -1.265625,-0.062 z%27 id=%27path4138-1%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 10.5,100 0,2 -2.4999996,0 L 12,107 l 4,-5 -2.5,0 0,-2 -3,0 z%27 id=%27path3055-0-77%27 /%3E%3Cpath style=%27fill:none;stroke:%230d0d0d;%27 d=%27m 4.9850574,108.015 14.0298856,-0.03%27 id=%27path5244-5-0-5%27 /%3E%3Cpath style=%27fill:none;stroke:%230d0d0d;%27 d=%27m 4.9849874,132.015 14.0298866,-0.03%27 id=%27path5244-5-0-5-8%27 /%3E%3Cpath style=%27color:%23000000;fill:%236e6e6e;%27 d=%27m 36.398438,123.9629 c -0.423362,-0.013 -0.846847,0.01 -1.265626,0.062 -1.656562,0.2196 -3.244567,0.9739 -4.507812,2.2266 L 29,124.5366 l -2.324219,7.7129 7.826172,-1.9062 -1.804687,-1.9063 c 1.597702,-1.5308 4.048706,-1.8453 5.984375,-0.7207 1.971162,1.1453 2.881954,3.3975 2.308593,5.5508 -0.573361,2.1533 -2.533864,3.6953 -4.830078,3.6953 l 0,3.0742 c 3.550757,0 6.710442,-2.4093 7.650391,-5.9394 0.939949,-3.5301 -0.618463,-7.2756 -3.710938,-9.0723 -1.159678,-0.6737 -2.431087,-1.0231 -3.701171,-1.0625 z%27 id=%27path4138-12%27 /%3E%3Cpath style=%27color:%23000000;fill:%236e6e6e;%27 d=%27m 59.722656,123.9629 c -1.270084,0.039 -2.541493,0.3888 -3.701172,1.0625 -3.092475,1.7967 -4.650886,5.5422 -3.710937,9.0723 0.939949,3.5301 4.09768,5.9394 7.648437,5.9394 l 0,-3.0742 c -2.296214,0 -4.256717,-1.542 -4.830078,-3.6953 -0.573361,-2.1533 0.337432,-4.4055 2.308594,-5.5508 1.935731,-1.1246 4.38863,-0.8102 5.986326,0.7207 l -1.806638,1.9063 7.828128,1.9062 -2.32422,-7.7129 -1.62696,1.7168 c -1.26338,-1.2531 -2.848917,-2.0088 -4.505855,-2.2285 -0.418778,-0.055 -0.842263,-0.076 -1.265625,-0.062 z%27 id=%27path4138-1-3%27 /%3E%3Cpath id=%27path6191%27 d=%27m 10.5,116 0,-2 -2.4999996,0 L 12,109 l 4,5 -2.5,0 0,2 -3,0 z%27 style=%27fill:%230d0d0d;stroke-width:2;%27 /%3E%3Cpath style=%27fill:%230d0d0d;stroke-width:2;%27 d=%27m 10.5,129 0,-2 -2.4999996,0 L 12,122 l 4,5 -2.5,0 0,2 -3,0 z%27 id=%27path6193%27 /%3E%3Cpath id=%27path6195%27 d=%27m 10.5,135 0,2 -2.4999996,0 L 12,142 l 4,-5 -2.5,0 0,-2 -3,0 z%27 style=%27fill:%230d0d0d;stroke-width:2;%27 /%3E%3Cpath sodipodi:type=%27star%27 style=%27fill:%236e6e6e;%27 id=%27path4500%27 sodipodi:sides=%273%27 sodipodi:cx=%2711.55581%27 sodipodi:cy=%2760.073242%27 sodipodi:r1=%275.1116104%27 sodipodi:r2=%272.5558052%27 sodipodi:arg1=%270%27 sodipodi:arg2=%271.0471976%27 inkscape:flatsided=%27false%27 inkscape:rounded=%270%27 inkscape:randomized=%270%27 d=%27m 16.66742,60.073242 -3.833708,2.213392 -3.8337072,2.213393 0,-4.426785 0,-4.426784 3.8337082,2.213392 z%27 inkscape:transform-center-x=%27-1.2779026%27 /%3E%3Cpath inkscape:transform-center-x=%271.277902%27 d=%27m -31.500004,60.073242 -3.833708,2.213392 -3.833707,2.213393 0,-4.426785 0,-4.426784 3.833707,2.213392 z%27 inkscape:randomized=%270%27 inkscape:rounded=%270%27 inkscape:flatsided=%27false%27 sodipodi:arg2=%271.0471976%27 sodipodi:arg1=%270%27 sodipodi:r2=%272.5558052%27 sodipodi:r1=%275.1116104%27 sodipodi:cy=%2760.073242%27 sodipodi:cx=%27-36.611614%27 sodipodi:sides=%273%27 id=%27path4502%27 style=%27fill:%236e6e6e;%27 sodipodi:type=%27star%27 transform=%27scale%28-1,1%29%27 /%3E%3Cpath d=%27m 16.66742,60.073212 -3.833708,2.213392 -3.8337072,2.213392 0,-4.426784 0,-4.426785 3.8337082,2.213392 z%27 inkscape:randomized=%270%27 inkscape:rounded=%270%27 inkscape:flatsided=%27false%27 sodipodi:arg2=%271.0471976%27 sodipodi:arg1=%270%27 sodipodi:r2=%272.5558052%27 sodipodi:r1=%275.1116104%27 sodipodi:cy=%2760.073212%27 sodipodi:cx=%2711.55581%27 sodipodi:sides=%273%27 id=%27path4504%27 style=%27fill:%236e6e6e;%27 sodipodi:type=%27star%27 transform=%27matrix%280,1,-1,0,72.0074,71.7877%29%27 inkscape:transform-center-y=%271.2779029%27 /%3E%3Cpath inkscape:transform-center-y=%27-1.2779026%27 transform=%27matrix%280,-1,-1,0,96,96%29%27 sodipodi:type=%27star%27 style=%27fill:%236e6e6e;%27 id=%27path4506%27 sodipodi:sides=%273%27 sodipodi:cx=%2711.55581%27 sodipodi:cy=%2760.073212%27 sodipodi:r1=%275.1116104%27 sodipodi:r2=%272.5558052%27 sodipodi:arg1=%270%27 sodipodi:arg2=%271.0471976%27 inkscape:flatsided=%27false%27 inkscape:rounded=%270%27 inkscape:randomized=%270%27 d=%27m 16.66742,60.073212 -3.833708,2.213392 -3.8337072,2.213392 0,-4.426784 0,-4.426785 3.8337082,2.213392 z%27 /%3E%3Cpath id=%27path4615-5%27 d=%27m 171.82574,65.174193 16.34854,0 -8.17427,-13.348454 z%27 style=%27fill:%23f9a825;fill-rule:evenodd;stroke:%23f9a825;stroke-width:2;%27 /%3E%3Cpath style=%27opacity:1;fill:%23ffffff;%27 d=%27m 179,55 0,6 2,0 0,-6%27 id=%27path4300%27 /%3E%3Cpath style=%27opacity:1;fill:%23ffffff;%27 d=%27m 179,62 0,2 2,0 0,-2%27 id=%27path4300-6%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27M 99.994369,113.0221 102,114.98353 l 7,-6.9558 3,0.97227 2,-1 1,-2 0,-3 -3,3 -3,-3 3,-3 -3,0 -2,1 -1,2 0.99437,3.0221 z%27 id=%27path4268%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 234,6 0,2 -5,5 0,5 -2,0 0,-5 -5,-5 0,-2%27 id=%27path3546%27 /%3E%3Cg transform=%27matrix%281.3333328,0,0,-1.5999992,-139.9999,127.19999%29%27 id=%27g4383-6%27%3E%3Crect id=%27rect4385-2%27 height=%271%27 width=%276%27 y=%2712.625005%27 x=%27198%27 style=%27fill:%230d0d0d;stroke:%23000000;stroke-width:0%27 /%3E%3Crect style=%27fill:%230d0d0d;stroke:%23000000;stroke-width:0%27 x=%27198%27 y=%2715.125007%27 width=%278%27 height=%271%27 id=%27rect4387-9%27 /%3E%3Crect style=%27fill:%230d0d0d;stroke:%23000000;stroke-width:0%27 x=%27198%27 y=%277.6250024%27 width=%273%27 height=%271%27 id=%27rect4389-1-0%27 /%3E%3Crect style=%27fill:%230d0d0d;stroke:%23000000;stroke-width:0%27 x=%27198%27 y=%2710.125004%27 width=%274%27 height=%271%27 id=%27rect4389-1-9%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 207.00001,16.375004 0,-5.625005 -2.25,0 3,-3.1250014 3,3.1250014 -2.25,0 0,5.625005 -1.5,0%27 id=%27path4402%27 /%3E%3C/g%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 164,100 0,3 -6,6 0,7 -4,0 0,-7 -6,-6 0,-3%27 id=%27path3546-2-2%27 /%3E%3Cpath id=%27path4402-5-7%27 d=%27m 15,41 0,-7 -4,0 0,3 -5,-4 5,-4 0,3 6,0 0,9%27 style=%27fill:%230d0d0d;%27 /%3E%3C/svg%3E%0A")}body{/*! + * Selectr 2.4.13 + * http://mobius.ovh/docs/selectr + * + * Released under the MIT license + */}body .jsoneditor,body .jsoneditor-modal{-webkit-text-size-adjust:none;text-size-adjust:none}body .jsoneditor input,body .jsoneditor input:not([type]),body .jsoneditor input[type="text"],body .jsoneditor input[type="search"],body .jsoneditor-modal input,body .jsoneditor-modal input:not([type]),body .jsoneditor-modal input[type="text"],body .jsoneditor-modal input[type="search"]{height:auto;border:inherit;box-shadow:none;font-size:inherit;box-sizing:inherit;padding:inherit;font-family:inherit;transition:none;line-height:inherit}body .jsoneditor input:focus,body .jsoneditor input:not([type]):focus,body .jsoneditor input[type="text"]:focus,body .jsoneditor input[type="search"]:focus,body .jsoneditor-modal input:focus,body .jsoneditor-modal input:not([type]):focus,body .jsoneditor-modal input[type="text"]:focus,body .jsoneditor-modal input[type="search"]:focus{border:inherit;box-shadow:inherit}body .jsoneditor textarea,body .jsoneditor-modal textarea{height:inherit}body .jsoneditor select,body .jsoneditor-modal select{display:inherit;height:inherit}body .jsoneditor label,body .jsoneditor-modal label{font-size:inherit;font-weight:inherit;color:inherit}body .jsoneditor table,body .jsoneditor-modal table{border-collapse:collapse;width:auto}body .jsoneditor td,body .jsoneditor th,body .jsoneditor-modal td,body .jsoneditor-modal th{padding:0;display:table-cell;text-align:left;vertical-align:inherit;border-radius:inherit}body .jsoneditor .autocomplete.dropdown{position:absolute;background:var(--t42-content-color);box-shadow:var(--t42-shadow);border:1px solid var(--t42-color-opacity-10);overflow-x:hidden;overflow-y:auto;cursor:default;margin:0;padding:5px;text-align:left;outline:0;font-family:var(--bs-font-monospace);font-size:var(--t42-font-size)}body .jsoneditor .autocomplete.dropdown .item{color:var(--t42-content-color)}body .jsoneditor .autocomplete.dropdown .item.hover{background-color:Rgb(var(--t42-bg-mid))}body .jsoneditor .autocomplete.hint{color:var(--t42-content-color);top:4px;left:4px}body .jsoneditor-contextmenu-root{position:relative;width:0;height:0}body .jsoneditor-contextmenu{position:absolute;box-sizing:content-box;z-index:2}body .jsoneditor-contextmenu .jsoneditor-menu{position:relative;left:0;top:0;width:128px;height:auto;background:var(--t42-content-color);border:1px solid var(--t42-color-opacity-10);box-shadow:var(--t42-shadow);list-style:none;margin:0;padding:0}body .jsoneditor-contextmenu .jsoneditor-menu button{position:relative;padding:0 8px 0 0;margin:0;width:128px;height:auto;border:none;cursor:pointer;color:var(--t42-content-color);background:transparent;font-size:var(--t42-font-size);font-family:var(--t42-font-family);box-sizing:border-box;text-align:left}body .jsoneditor-contextmenu .jsoneditor-menu button::-moz-focus-inner{padding:0;border:0}body .jsoneditor-contextmenu .jsoneditor-menu button.jsoneditor-default{width:96px}body .jsoneditor-contextmenu .jsoneditor-menu button.jsoneditor-expand{float:right;width:32px;height:24px;border-left:1px solid var(--t42-color-opacity-10)}body .jsoneditor-contextmenu .jsoneditor-menu li{overflow:hidden}body .jsoneditor-contextmenu .jsoneditor-menu li ul{display:none;position:relative;left:-10px;top:0;border:none;box-shadow:inset var(--t42-shadow);padding:0 10px;-webkit-transition:all 0.3s ease-out;-moz-transition:all 0.3s ease-out;-o-transition:all 0.3s ease-out;transition:all 0.3s ease-out}body .jsoneditor-contextmenu .jsoneditor-menu li ul .jsoneditor-icon{margin-left:24px}body .jsoneditor-contextmenu .jsoneditor-menu li ul li button{padding-left:24px;animation:all ease-in-out 1s}body .jsoneditor-contextmenu .jsoneditor-menu li button .jsoneditor-expand{position:absolute;top:0;right:0;width:24px;height:24px;padding:0;margin:0 4px 0 0;background-image:"/";background-position:0 -72px}body .jsoneditor-contextmenu .jsoneditor-icon{position:absolute;top:0;left:0;width:24px;height:24px;border:none;padding:0;margin:0;background-image:"/"}body .jsoneditor-contextmenu .jsoneditor-text{padding:4px 0 4px 24px;word-wrap:break-word}body .jsoneditor-contextmenu .jsoneditor-text.jsoneditor-right-margin{padding-right:24px}body .jsoneditor-contextmenu .jsoneditor-separator{height:0;border-top:1px solid var(--t42-color-opacity-10);padding-top:5px;margin-top:5px}body .jsoneditor-contextmenu button.jsoneditor-remove .jsoneditor-icon{background-position:-24px 0}body .jsoneditor-contextmenu button.jsoneditor-append .jsoneditor-icon{background-position:0 0}body .jsoneditor-contextmenu button.jsoneditor-insert .jsoneditor-icon{background-position:0 0}body .jsoneditor-contextmenu button.jsoneditor-duplicate .jsoneditor-icon{background-position:-48px 0}body .jsoneditor-contextmenu button.jsoneditor-sort-asc .jsoneditor-icon{background-position:-168px 0}body .jsoneditor-contextmenu button.jsoneditor-sort-desc .jsoneditor-icon{background-position:-192px 0}body .jsoneditor-contextmenu button.jsoneditor-transform .jsoneditor-icon{background-position:-216px 0}body .jsoneditor-contextmenu button.jsoneditor-extract .jsoneditor-icon{background-position:0 -24px}body .jsoneditor-contextmenu button.jsoneditor-type-string .jsoneditor-icon{background-position:-144px 0}body .jsoneditor-contextmenu button.jsoneditor-type-auto .jsoneditor-icon{background-position:-120px 0}body .jsoneditor-contextmenu button.jsoneditor-type-object .jsoneditor-icon{background-position:-72px 0}body .jsoneditor-contextmenu button.jsoneditor-type-array .jsoneditor-icon{background-position:-96px 0}body .jsoneditor-contextmenu button.jsoneditor-type-modes .jsoneditor-icon{background-image:none;width:6px}body .jsoneditor-contextmenu ul,body .jsoneditor-contextmenu li{box-sizing:content-box;position:relative}body .jsoneditor-contextmenu .jsoneditor-menu button:hover,body .jsoneditor-contextmenu .jsoneditor-menu button:focus{color:var(--t42-content-color);background-color:var(--t42-color-opacity-10);outline:none}body .jsoneditor-contextmenu .jsoneditor-menu li button.jsoneditor-selected,body .jsoneditor-contextmenu .jsoneditor-menu li button.jsoneditor-selected:hover,body .jsoneditor-contextmenu .jsoneditor-menu li button.jsoneditor-selected:focus{color:var(--t42-content-color);background-color:var(--red)}body .jsoneditor-contextmenu .jsoneditor-menu li ul li button:hover,body .jsoneditor-contextmenu .jsoneditor-menu li ul li button:focus{background-color:var(--t42-color-opacity-10)}body .jsoneditor-modal{max-width:95%;border-radius:2px !important;padding:45px 15px 15px 15px !important;box-shadow:var(--t42-shadow);color:var(--t42-content-color);line-height:1.3em}body .jsoneditor-modal.jsoneditor-modal-transform{width:600px !important}body .jsoneditor-modal .pico-modal-header{position:absolute;box-sizing:border-box;top:0;left:0;width:100%;padding:0 10px;height:30px;line-height:30px;font-family:var(--t42-font-family);font-size:11pt;background:var(--primary);color:var(--t42-content-color)}body .jsoneditor-modal table{width:100%}body .jsoneditor-modal table td{padding:3px 0}body .jsoneditor-modal table td.jsoneditor-modal-input{text-align:right;padding-right:0;white-space:nowrap}body .jsoneditor-modal table td.jsoneditor-modal-actions{padding-top:15px}body .jsoneditor-modal table th{vertical-align:middle}body .jsoneditor-modal p:first-child{margin-top:0}body .jsoneditor-modal a{color:var(--primary)}body .jsoneditor-modal .jsoneditor-jmespath-block{margin-bottom:10px}body .jsoneditor-modal .pico-close{background:none !important;font-size:24px !important;top:7px !important;right:7px !important;color:var(--t42-content-color)}body .jsoneditor-modal input{padding:4px}body .jsoneditor-modal input[type="text"]{cursor:inherit}body .jsoneditor-modal input[disabled]{background:var(--t42-content-color-muted);color:var(--t42-content-color-muted)}body .jsoneditor-modal .jsoneditor-select-wrapper{position:relative;display:inline-block}body .jsoneditor-modal .jsoneditor-select-wrapper:after{content:"";width:0;height:0;border-left:5px solid transparent;border-right:5px solid transparent;border-top:6px solid #666;position:absolute;right:8px;top:14px;pointer-events:none}body .jsoneditor-modal select{padding:3px 24px 3px 10px;min-width:180px;max-width:350px;-webkit-appearance:none;-moz-appearance:none;appearance:none;text-indent:0;text-overflow:"";font-size:var(--t42-font-size);line-height:1.5em}body .jsoneditor-modal select::-ms-expand{display:none}body .jsoneditor-modal .jsoneditor-button-group input{padding:4px 10px;margin:0;border-radius:0;border-left-style:none}body .jsoneditor-modal .jsoneditor-button-group input.jsoneditor-button-first{border-top-left-radius:3px;border-bottom-left-radius:3px;border-left-style:solid}body .jsoneditor-modal .jsoneditor-button-group input.jsoneditor-button-last{border-top-right-radius:3px;border-bottom-right-radius:3px}body .jsoneditor-modal .jsoneditor-transform-preview{background:var(--t42-color-opacity-10);height:200px}body .jsoneditor-modal .jsoneditor-transform-preview.jsoneditor-error{color:var(--red)}body .jsoneditor-modal .jsoneditor-jmespath-wizard{line-height:1.2em;width:100%;padding:0;border-radius:3px}body .jsoneditor-modal .jsoneditor-jmespath-label{font-weight:bold;color:dodgerblue;margin-top:20px;margin-bottom:5px}body .jsoneditor-modal .jsoneditor-jmespath-wizard-table{width:100%;border-collapse:collapse}body .jsoneditor-modal .jsoneditor-jmespath-wizard-label{font-style:italic;margin:4px 0 2px 0}body .jsoneditor-modal .jsoneditor-inline{position:relative;display:inline-block;width:100%;padding-top:2px;padding-bottom:2px}body .jsoneditor-modal .jsoneditor-inline:not(:last-child){padding-right:2px}body .jsoneditor-modal .jsoneditor-jmespath-filter{display:flex;flex-wrap:wrap}body .jsoneditor-modal .jsoneditor-jmespath-filter-field{width:180px}body .jsoneditor-modal .jsoneditor-jmespath-filter-relation{width:100px}body .jsoneditor-modal .jsoneditor-jmespath-filter-value{min-width:180px;flex:1}body .jsoneditor-modal .jsoneditor-jmespath-sort-field{width:170px}body .jsoneditor-modal .jsoneditor-jmespath-sort-order{width:150px}body .jsoneditor-modal .jsoneditor-jmespath-select-fields{width:100%}body .jsoneditor-modal .selectr-selected{border-color:var(--t42-color-opacity-10);padding:4px 28px 4px 8px}body .jsoneditor-modal .selectr-selected .selectr-tag{background-color:var(--primary);border-radius:5px}body .jsoneditor-modal table th,body .jsoneditor-modal table td{text-align:left;vertical-align:middle;font-weight:normal;color:var(--t42-content-color);border-spacing:0;border-collapse:collapse}body .jsoneditor-modal select,body .jsoneditor-modal textarea,body .jsoneditor-modal input,body .jsoneditor-modal input[type="text"],body .jsoneditor-modal input[type="text"]:focus,body .jsoneditor-modal #query{background:#ffffff;border:1px solid var(--t42-color-opacity-10);color:var(--t42-content-color);border-radius:3px;padding:4px}body .jsoneditor-modal textarea,body .jsoneditor-modal #query{border-radius:unset}body .jsoneditor-modal,body .jsoneditor-modal table td,body .jsoneditor-modal table th,body .jsoneditor-modal select,body .jsoneditor-modal option,body .jsoneditor-modal textarea,body .jsoneditor-modal input,body .jsoneditor-modal input[type="text"],body .jsoneditor-modal #query{font-size:10.5pt;font-family:var(--t42-font-family)}body .jsoneditor-modal #query,body .jsoneditor-modal .jsoneditor-transform-preview{font-family:var(--bs-font-monospace);font-size:var(--t42-font-size);width:100%;box-sizing:border-box}body .jsoneditor-modal input[type="button"],body .jsoneditor-modal input[type="submit"]{background:var(--t42-color-opacity-10);padding:4px 20px}body .jsoneditor-modal select,body .jsoneditor-modal input{cursor:pointer}body .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-asc input.jsoneditor-button-asc,body .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-desc input.jsoneditor-button-desc{background:var(--primary);border-color:var(--primary);color:var(--t42-content-color)}body .jsoneditor{color:var(--t42-content-color);border:thin solid var(--primary);-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;width:100%;height:100%;position:relative;padding:0;line-height:100%}body div.jsoneditor-field,body div.jsoneditor-value,body a.jsoneditor-value,body div.jsoneditor-readonly,body div.jsoneditor-default{border:1px solid transparent;min-height:16px;min-width:32px;line-height:16px;padding:2px;margin:1px;word-wrap:break-word;word-break:break-word;overflow-wrap:break-word;float:left}body div.jsoneditor-field p,body div.jsoneditor-value p{margin:0}body div.jsoneditor-value.jsoneditor-empty::after{content:"value"}body div.jsoneditor-value.jsoneditor-string{color:var(--green)}body div.jsoneditor-value.jsoneditor-number{color:var(--red)}body div.jsoneditor-value.jsoneditor-boolean{color:var(--yellow)}body div.jsoneditor-value.jsoneditor-null{color:var(--primary)}body div.jsoneditor-value.jsoneditor-color-value{color:var(--t42-content-color)}body div.jsoneditor-value.jsoneditor-invalid{color:var(--white)}body div.jsoneditor-readonly{min-width:16px;color:var(--t42-content-color-muted)}body div.jsoneditor-empty{border-color:var(--t42-color-opacity-10);border-style:dashed;border-radius:2px}body div.jsoneditor-field.jsoneditor-empty::after{content:"field"}body div.jsoneditor td{vertical-align:top}body div.jsoneditor td.jsoneditor-separator{padding:3px 0;vertical-align:top;color:var(--t42-content-color-muted)}body div.jsoneditor td.jsoneditor-tree{vertical-align:top}body div.jsoneditor.busy pre.jsoneditor-preview{background:var(--t42-color-opacity-10);color:var(--t42-content-color-muted)}body div.jsoneditor.busy div.jsoneditor-busy{display:inherit}body div.jsoneditor code.jsoneditor-preview{background:none}body div.jsoneditor.jsoneditor-mode-preview pre.jsoneditor-preview{width:100%;height:100%;box-sizing:border-box;overflow:auto;padding:2px;margin:0;white-space:pre-wrap;word-break:break-all}body div.jsoneditor-default{color:var(--t42-content-color-muted);padding-left:10px}body div.jsoneditor-tree{width:100%;height:100%;position:relative;overflow:auto;background:var(--t42-content-color)}body div.jsoneditor-tree button.jsoneditor-button{width:24px;height:24px;padding:0;margin:0;border:none;cursor:pointer;background-color:transparent;background-image:"/"}body div.jsoneditor-tree button.jsoneditor-button:focus{background-color:var(--t42-color-opacity-10);outline:#e5e5e5 solid 1px}body div.jsoneditor-tree button.jsoneditor-collapsed{background-position:0 -48px}body div.jsoneditor-tree button.jsoneditor-expanded{background-position:0 -72px}body div.jsoneditor-tree button.jsoneditor-contextmenu-button{background-position:-48px -72px}body div.jsoneditor-tree button.jsoneditor-invisible{visibility:hidden;background:none}body div.jsoneditor-tree button.jsoneditor-dragarea{background-image:"/";background-position:-72px -72px;cursor:move}body div.jsoneditor-tree *:focus{outline:none}body div.jsoneditor-tree div.jsoneditor-show-more{display:inline-block;padding:3px 4px;margin:2px 0;background-color:var(--t42-color-opacity-10);border-radius:3px;color:var(--t42-content-color-muted);font-family:var(--t42-font-family);font-size:var(--t42-font-size)}body div.jsoneditor-tree div.jsoneditor-show-more a{display:inline-block;color:var(--t42-content-color-muted)}body div.jsoneditor-tree div.jsoneditor-color{display:inline-block;width:12px;height:12px;margin:4px;border:1px solid var(--t42-content-color-muted);cursor:pointer}body div.jsoneditor-tree div.jsoneditor-color.jsoneditor-color-readonly{cursor:inherit}body div.jsoneditor-tree div.jsoneditor-date{background:var(--t42-content-color);color:var(--t42-content-color);font-family:var(--t42-font-family);border-radius:3px;display:inline-block;padding:3px;margin:0 3px}body div.jsoneditor-tree table.jsoneditor-tree{border-collapse:collapse;border-spacing:0;width:100%}body div.jsoneditor-tree .jsoneditor-button{display:block}body div.jsoneditor-tree .jsoneditor-button.jsoneditor-schema-error{width:24px;height:24px;padding:0;margin:0 4px 0 0;background-image:"/";background-position:-168px -48px;background-color:transparent}body div.jsoneditor-outer{position:static;width:100%;height:100%;margin:0;padding:0;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}body div.jsoneditor-outer.has-nav-bar{margin-top:-26px;padding-top:26px}body div.jsoneditor-outer.has-nav-bar.has-main-menu-bar{margin-top:-61px;padding-top:61px}body div.jsoneditor-outer.has-status-bar{margin-bottom:-26px;padding-bottom:26px}body div.jsoneditor-outer.has-main-menu-bar{margin-top:-35px;padding-top:35px}body div.jsoneditor-busy{position:absolute;top:15%;left:0;box-sizing:border-box;width:100%;text-align:center;display:none}body div.jsoneditor-busy span{background-color:var(--t42-color-opacity-10);border:1px solid var(--t42-color-opacity-10);border-radius:3px;padding:5px 15px;box-shadow:var(--t42-shadow)}body div.jsoneditor-field.jsoneditor-empty::after,body div.jsoneditor-value.jsoneditor-empty::after{pointer-events:none;color:var(--t42-content-color-muted);font-size:8pt}body div.jsoneditor-value.jsoneditor-url,body a.jsoneditor-value.jsoneditor-url{color:var(--green);text-decoration:underline}body a.jsoneditor-value.jsoneditor-url{display:inline-block;padding:2px;margin:2px}body a.jsoneditor-value.jsoneditor-url:hover,body a.jsoneditor-value.jsoneditor-url:focus{color:var(--red)}body div.jsoneditor-field[contenteditable="true"]:focus,body div.jsoneditor-field[contenteditable="true"]:hover,body div.jsoneditor-value[contenteditable="true"]:focus,body div.jsoneditor-value[contenteditable="true"]:hover,body div.jsoneditor-field.jsoneditor-highlight,body div.jsoneditor-value.jsoneditor-highlight{background-color:var(--t42-color-opacity-10);border:1px solid var(--t42-color-opacity-10);border-radius:2px}body div.jsoneditor-field.jsoneditor-highlight-active,body div.jsoneditor-field.jsoneditor-highlight-active:focus,body div.jsoneditor-field.jsoneditor-highlight-active:hover,body div.jsoneditor-value.jsoneditor-highlight-active,body div.jsoneditor-value.jsoneditor-highlight-active:focus,body div.jsoneditor-value.jsoneditor-highlight-active:hover{background-color:#fe0;border:1px solid #ffc700;border-radius:2px}body div.jsoneditor-value.jsoneditor-object,body div.jsoneditor-value.jsoneditor-array{min-width:16px}body div.jsoneditor-tree button.jsoneditor-contextmenu-button:hover,body div.jsoneditor-tree button.jsoneditor-contextmenu-button:focus,body div.jsoneditor-tree button.jsoneditor-contextmenu-button.jsoneditor-selected,body tr.jsoneditor-selected.jsoneditor-first button.jsoneditor-contextmenu-button{background-position:-48px -48px}body div.jsoneditor-tree div.jsoneditor-show-more a:hover,body div.jsoneditor-tree div.jsoneditor-show-more a:focus{color:var(--red)}body textarea.jsoneditor-text,body .ace-jsoneditor{min-height:150px}body textarea.jsoneditor-text.ace_editor,body .ace-jsoneditor.ace_editor{font-family:var(--bs-font-monospace)}body textarea.jsoneditor-text{width:100%;height:100%;margin:0;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;outline-width:0;border:none;background-color:var(--t42-content-color);resize:none}body tr.jsoneditor-highlight,body tr.jsoneditor-selected{background-color:var(--t42-content-color-muted)}body tr.jsoneditor-selected button.jsoneditor-dragarea,body tr.jsoneditor-selected button.jsoneditor-contextmenu-button{visibility:hidden}body tr.jsoneditor-selected.jsoneditor-first button.jsoneditor-dragarea,body tr.jsoneditor-selected.jsoneditor-first button.jsoneditor-contextmenu-button{visibility:visible}body div.jsoneditor-tree button.jsoneditor-dragarea:hover,body div.jsoneditor-tree button.jsoneditor-dragarea:focus,body tr.jsoneditor-selected.jsoneditor-first button.jsoneditor-dragarea{background-position:-72px -48px}body div.jsoneditor tr,body div.jsoneditor th,body div.jsoneditor td{padding:0;margin:0}body div.jsoneditor-field,body div.jsoneditor-value,body div.jsoneditor td,body div.jsoneditor th,body div.jsoneditor textarea,body pre.jsoneditor-preview,body .jsoneditor-schema-error,body .jsoneditor-popover{font-family:var(--bs-font-monospace);font-size:var(--t42-font-size);color:var(--t42-content-color)}body .jsoneditor-schema-error{cursor:default;display:inline-block;height:24px;line-height:24px;position:relative;text-align:center;width:24px}body .jsoneditor-popover{background-color:Rgb(var(--t42-bg-light));border-radius:3px;box-shadow:var(--t42-shadow);color:var(--t42-content-color);padding:7px 10px;position:absolute;cursor:auto;width:200px}body .jsoneditor-popover.jsoneditor-above{bottom:32px;left:-98px}body .jsoneditor-popover.jsoneditor-above:before{border-top:7px solid Rgb(var(--t42-bg-light));bottom:-7px}body .jsoneditor-popover.jsoneditor-below{top:32px;left:-98px}body .jsoneditor-popover.jsoneditor-below:before{border-bottom:7px solid Rgb(var(--t42-bg-light));top:-7px}body .jsoneditor-popover.jsoneditor-left{top:-7px;right:32px}body .jsoneditor-popover.jsoneditor-left:before{border-left:7px solid Rgb(var(--t42-bg-light));border-top:7px solid transparent;border-bottom:7px solid transparent;content:"";top:19px;right:-14px;left:inherit;margin-left:inherit;margin-top:-7px;position:absolute}body .jsoneditor-popover.jsoneditor-right{top:-7px;left:32px}body .jsoneditor-popover.jsoneditor-right:before{border-right:7px solid Rgb(var(--t42-bg-light));border-top:7px solid transparent;border-bottom:7px solid transparent;content:"";top:19px;left:-14px;margin-left:inherit;margin-top:-7px;position:absolute}body .jsoneditor-popover:before{border-right:7px solid transparent;border-left:7px solid transparent;content:"";display:block;left:50%;margin-left:-7px;position:absolute}body .jsoneditor-text-errors tr.jump-to-line:hover{text-decoration:underline;cursor:pointer}body .jsoneditor-schema-error:hover .jsoneditor-popover,body .jsoneditor-schema-error:focus .jsoneditor-popover{display:block;animation:fade-in 0.3s linear 1, move-up 0.3s linear 1}@keyframes fade-in{from{opacity:0}to{opacity:1}}body .jsoneditor .jsoneditor-validation-errors-container{max-height:130px;overflow-y:auto}body .jsoneditor .jsoneditor-validation-errors{width:100%;overflow:hidden}body .jsoneditor .jsoneditor-additional-errors{position:absolute;margin:auto;bottom:31px;left:calc(50% - 92px);color:var(--t42-content-color-muted);background-color:Rgb(var(--t42-bg-mid));padding:7px 15px;border-radius:8px}body .jsoneditor .jsoneditor-additional-errors.visible{visibility:visible;opacity:1;transition:opacity 2s linear}body .jsoneditor .jsoneditor-additional-errors.hidden{visibility:hidden;opacity:0;transition:visibility 0s 2s, opacity 2s linear}body .jsoneditor .jsoneditor-text-errors{width:100%;border-collapse:collapse;border-top:1px solid #ffc700}body .jsoneditor .jsoneditor-text-errors td{padding:3px 6px;vertical-align:middle}body .jsoneditor .jsoneditor-text-errors td pre{margin:0;white-space:pre-wrap}body .jsoneditor .jsoneditor-text-errors tr{background-color:var(--t42-color-opacity-10)}body .jsoneditor .jsoneditor-text-errors tr.parse-error{background-color:var(--red)}body .jsoneditor-text-errors .jsoneditor-schema-error{border:none;width:24px;height:24px;padding:0;margin:0 4px 0 0;cursor:pointer}body .jsoneditor-text-errors tr .jsoneditor-schema-error{background-image:"/";background-position:-168px -48px;background-color:transparent}body .jsoneditor-text-errors tr.parse-error .jsoneditor-schema-error{background-image:"/";background-position:-25px 0px;background-color:transparent}body .jsoneditor-anchor{cursor:pointer}body .jsoneditor-anchor .picker_wrapper.popup.popup_bottom{top:28px;left:-10px}body .fadein{-webkit-animation:fadein 0.3s;animation:fadein 0.3s;-moz-animation:fadein 0.3s;-o-animation:fadein 0.3s}@keyframes fadein{0%{opacity:0}100%{opacity:1}}body .jsoneditor-modal input[type="search"].selectr-input{border:1px solid #d3d3d3;width:calc(100% - 4px);margin:2px;padding:4px;box-sizing:border-box}body .jsoneditor-modal button.selectr-input-clear{right:8px}body .jsoneditor-menu{width:100%;height:35px;padding:2px;margin:0;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;color:var(--t42-content-color);background-color:var(--primary);border-bottom:1px solid var(--primary)}body .jsoneditor-menu>button,body .jsoneditor-menu>.jsoneditor-modes>button{width:26px;height:26px;margin:2px;padding:0;border-radius:2px;border:1px solid transparent;background-color:transparent;background-image:"/";color:var(--t42-content-color);opacity:0.8;font-family:var(--t42-font-family);font-size:var(--t42-font-size);float:left}body .jsoneditor-menu>button:hover,body .jsoneditor-menu>.jsoneditor-modes>button:hover{background-color:rgba(255,255,255,0.2);border:1px solid rgba(255,255,255,0.4)}body .jsoneditor-menu>button:focus,body .jsoneditor-menu>button:active,body .jsoneditor-menu>.jsoneditor-modes>button:focus,body .jsoneditor-menu>.jsoneditor-modes>button:active{background-color:rgba(255,255,255,0.3)}body .jsoneditor-menu>button:disabled,body .jsoneditor-menu>.jsoneditor-modes>button:disabled{opacity:0.5;background-color:transparent;border:none}body .jsoneditor-menu>button.jsoneditor-collapse-all{background-position:0 -96px}body .jsoneditor-menu>button.jsoneditor-expand-all{background-position:0 -120px}body .jsoneditor-menu>button.jsoneditor-sort{background-position:-120px -96px}body .jsoneditor-menu>button.jsoneditor-transform{background-position:-144px -96px}body .jsoneditor.jsoneditor-mode-view>.jsoneditor-menu>button.jsoneditor-sort,body .jsoneditor.jsoneditor-mode-form>.jsoneditor-menu>button.jsoneditor-sort,body .jsoneditor.jsoneditor-mode-view>.jsoneditor-menu>button.jsoneditor-transform,body .jsoneditor.jsoneditor-mode-form>.jsoneditor-menu>button.jsoneditor-transform{display:none}body .jsoneditor-menu>button.jsoneditor-undo{background-position:-24px -96px}body .jsoneditor-menu>button.jsoneditor-undo:disabled{background-position:-24px -120px}body .jsoneditor-menu>button.jsoneditor-redo{background-position:-48px -96px}body .jsoneditor-menu>button.jsoneditor-redo:disabled{background-position:-48px -120px}body .jsoneditor-menu>button.jsoneditor-compact{background-position:-72px -96px}body .jsoneditor-menu>button.jsoneditor-format{background-position:-72px -120px}body .jsoneditor-menu>button.jsoneditor-repair{background-position:-96px -96px}body .jsoneditor-menu>.jsoneditor-modes{display:inline-block;float:left}body .jsoneditor-menu>.jsoneditor-modes>button{background-image:none;width:auto;padding-left:6px;padding-right:6px}body .jsoneditor-menu>button.jsoneditor-separator,body .jsoneditor-menu>.jsoneditor-modes>button.jsoneditor-separator{margin-left:10px}body .jsoneditor-menu a{font-family:var(--t42-font-family);font-size:var(--t42-font-size);color:var(--t42-content-color);opacity:0.8;vertical-align:middle}body .jsoneditor-menu a:hover{opacity:1}body .jsoneditor-menu a.jsoneditor-poweredBy{font-size:8pt;position:absolute;right:0;top:0;padding:10px}body .jsoneditor-navigation-bar{width:100%;height:26px;line-height:26px;padding:0;margin:0;border-bottom:1px solid var(--t42-color-opacity-10);-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;color:var(--t42-content-color-muted);background-color:Rgb(var(--t42-bg-mid));overflow:hidden;font-family:var(--t42-font-family);font-size:var(--t42-font-size)}body .jsoneditor-search{font-family:var(--t42-font-family);position:absolute;right:4px;top:4px;border-collapse:collapse;border-spacing:0;display:flex}body .jsoneditor-search input{color:var(--t42-content-color);width:120px;border:none;outline:none;margin:1px;line-height:20px;font-family:var(--t42-font-family)}body .jsoneditor-search button{width:16px;height:24px;padding:0;margin:0;border:none;background:"/";vertical-align:top}body .jsoneditor-search button:hover{background-color:transparent}body .jsoneditor-search button.jsoneditor-refresh{width:18px;background-position:-99px -73px}body .jsoneditor-search button.jsoneditor-next{cursor:pointer;background-position:-124px -73px}body .jsoneditor-search button.jsoneditor-next:hover{background-position:-124px -49px}body .jsoneditor-search button.jsoneditor-previous{cursor:pointer;background-position:-148px -73px;margin-right:2px}body .jsoneditor-search button.jsoneditor-previous:hover{background-position:-148px -49px}body .jsoneditor-results{font-family:var(--t42-font-family);color:var(--t42-content-color);padding-right:5px;line-height:26px}body .jsoneditor-frame{border:1px solid transparent;background-color:var(--t42-content-color);padding:0 2px;margin:0}body .jsoneditor-statusbar{line-height:26px;height:26px;color:var(--t42-content-color-muted);background-color:Rgb(var(--t42-bg-mid));border-top:1px solid var(--t42-color-opacity-10);-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;font-size:var(--t42-font-size)}body .jsoneditor-statusbar>.jsoneditor-curserinfo-val{margin-right:12px}body .jsoneditor-statusbar>.jsoneditor-curserinfo-count{margin-left:4px}body .jsoneditor-statusbar>.jsoneditor-validation-error-icon{float:right;width:24px;height:24px;padding:0;margin-top:1px;background-image:"/";background-position:-168px -48px;cursor:pointer}body .jsoneditor-statusbar>.jsoneditor-validation-error-count{float:right;margin:0 4px 0 0;cursor:pointer}body .jsoneditor-statusbar>.jsoneditor-parse-error-icon{float:right;width:24px;height:24px;padding:0;margin:1px;background-image:"/";background-position:-25px 0px}body .jsoneditor-statusbar .jsoneditor-array-info a{color:inherit}body div.jsoneditor-statusbar>.jsoneditor-curserinfo-label,body div.jsoneditor-statusbar>.jsoneditor-size-info{margin:0 4px}body .jsoneditor-treepath{padding:0 5px;overflow:hidden;white-space:nowrap;outline:none}body .jsoneditor-treepath.show-all{word-wrap:break-word;white-space:normal;position:absolute;background-color:Rgb(var(--t42-bg-mid));z-index:1;box-shadow:var(--t42-shadow)}body .jsoneditor-treepath.show-all span.jsoneditor-treepath-show-all-btn{display:none}body .jsoneditor-treepath div.jsoneditor-contextmenu-root{position:absolute;left:0}body .jsoneditor-treepath .jsoneditor-treepath-show-all-btn{position:absolute;background-color:Rgb(var(--t42-bg-mid));left:0;height:20px;padding:0 3px;cursor:pointer}body .jsoneditor-treepath .jsoneditor-treepath-element{margin:1px;font-family:var(--t42-font-family);font-size:var(--t42-font-size)}body .jsoneditor-treepath .jsoneditor-treepath-seperator{margin:2px;font-size:9pt;font-family:var(--t42-font-family)}body .jsoneditor-treepath span.jsoneditor-treepath-element:hover,body .jsoneditor-treepath span.jsoneditor-treepath-seperator:hover{cursor:pointer;text-decoration:underline}body .selectr-container{position:relative}body .selectr-container li{list-style:none}body .selectr-hidden{position:absolute;overflow:hidden;clip:rect(0px, 0px, 0px, 0px);width:1px;height:1px;margin:-1px;padding:0;border:0 none}body .selectr-visible{position:absolute;left:0;top:0;width:100%;height:100%;opacity:0;z-index:11}body .selectr-desktop.multiple .selectr-visible{display:none}body .selectr-desktop.multiple.native-open .selectr-visible{top:100%;min-height:200px !important;height:auto;opacity:1;display:block}body .selectr-container.multiple.selectr-mobile .selectr-selected{z-index:0}body .selectr-selected{position:relative;z-index:1;box-sizing:border-box;width:100%;padding:7px 28px 7px 14px;cursor:pointer;border:1px solid Rgb(var(--t42-bg-mid));border-radius:3px;background-color:var(--t42-content-color)}body .selectr-selected::before{position:absolute;top:50%;right:10px;width:0;height:0;content:'';-o-transform:rotate(0deg) translate3d(0px, -50%, 0px);-ms-transform:rotate(0deg) translate3d(0px, -50%, 0px);-moz-transform:rotate(0deg) translate3d(0px, -50%, 0px);-webkit-transform:rotate(0deg) translate3d(0px, -50%, 0px);transform:rotate(0deg) translate3d(0px, -50%, 0px);border-width:4px 4px 0 4px;border-style:solid;border-color:#6c7a86 transparent transparent}body .selectr-container.open .selectr-selected::before,body .selectr-container.native-open .selectr-selected::before{border-width:0 4px 4px 4px;border-style:solid;border-color:transparent transparent #6c7a86}body .selectr-label{display:none;overflow:hidden;width:100%;white-space:nowrap;text-overflow:ellipsis}body .selectr-placeholder{color:#6c7a86}body .selectr-tags{margin:0;padding:0;white-space:normal}body .has-selected .selectr-tags{margin:0 0 -2px}body .selectr-tag{list-style:none;position:relative;float:left;padding:2px 25px 2px 8px;margin:0 2px 2px 0;cursor:default;color:var(--t42-content-color);border:medium none;border-radius:10px;background:#acb7bf none repeat scroll 0 0}body .selectr-container.multiple.has-selected .selectr-selected{padding:5px 28px 5px 5px}body .selectr-options-container{position:absolute;z-index:10000;top:calc(100% - 1px);left:0;display:none;box-sizing:border-box;width:100%;border-width:0 1px 1px;border-style:solid;border-color:transparent Rgb(var(--t42-bg-mid)) Rgb(var(--t42-bg-mid));border-radius:0 0 3px 3px;background-color:var(--t42-content-color)}body .selectr-container.open .selectr-options-container{display:block}body .selectr-input-container{position:relative;display:none}body .selectr-clear,body .selectr-input-clear,body .selectr-tag-remove{position:absolute;top:50%;right:22px;width:20px;height:20px;padding:0;cursor:pointer;-o-transform:translate3d(0px, -50%, 0px);-ms-transform:translate3d(0px, -50%, 0px);-moz-transform:translate3d(0px, -50%, 0px);-webkit-transform:translate3d(0px, -50%, 0px);transform:translate3d(0px, -50%, 0px);border:medium none;background-color:transparent;z-index:11}body .selectr-clear,body .selectr-input-clear{display:none}body .selectr-container.has-selected .selectr-clear,body .selectr-input-container.active .selectr-input-clear{display:block}body .selectr-selected .selectr-tag-remove{right:2px}body .selectr-clear::before,body .selectr-clear::after,body .selectr-input-clear::before,body .selectr-input-clear::after,body .selectr-tag-remove::before,body .selectr-tag-remove::after{position:absolute;top:5px;left:9px;width:2px;height:10px;content:' ';background-color:#6c7a86}body .selectr-tag-remove::before,body .selectr-tag-remove::after{top:4px;width:3px;height:12px;background-color:var(--t42-content-color)}body .selectr-clear:before,body .selectr-input-clear::before,body .selectr-tag-remove::before{-o-transform:rotate(45deg);-ms-transform:rotate(45deg);-moz-transform:rotate(45deg);-webkit-transform:rotate(45deg);transform:rotate(45deg)}body .selectr-clear:after,body .selectr-input-clear::after,body .selectr-tag-remove::after{-o-transform:rotate(-45deg);-ms-transform:rotate(-45deg);-moz-transform:rotate(-45deg);-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}body .selectr-input-container.active,body .selectr-input-container.active .selectr-clear{display:block}body .selectr-input{top:5px;left:5px;box-sizing:border-box;width:calc(100% - 30px);margin:10px 15px;padding:7px 30px 7px 9px;border:1px solid Rgb(var(--t42-bg-mid));border-radius:3px}body .selectr-notice{display:none;box-sizing:border-box;width:100%;padding:8px 16px;border-top:1px solid Rgb(var(--t42-bg-mid));border-radius:0 0 3px 3px;background-color:var(--t42-content-color)}body .selectr-container.notice .selectr-notice{display:block}body .selectr-container.notice .selectr-selected{border-radius:3px 3px 0 0}body .selectr-options{position:relative;top:calc(100% + 2px);display:none;overflow-x:auto;overflow-y:scroll;max-height:200px;margin:0;padding:0}body .selectr-container.open .selectr-options,body .selectr-container.open .selectr-input-container,body .selectr-container.notice .selectr-options-container{display:block}body .selectr-option{position:relative;display:block;padding:5px 20px;list-style:outside none none;cursor:pointer;font-weight:normal}body .selectr-options.optgroups>.selectr-option{padding-left:25px}body .selectr-optgroup{font-weight:bold;padding:0}body .selectr-optgroup--label{font-weight:bold;margin-top:10px;padding:5px 15px}body .selectr-match{text-decoration:underline}body .selectr-option.selected{background-color:#ddd}body .selectr-option.active{color:var(--t42-content-color);background-color:#5897fb}body .selectr-option.disabled{opacity:0.4}body .selectr-option.excluded{display:none}body .selectr-container.open .selectr-selected{border-color:Rgb(var(--t42-bg-mid)) Rgb(var(--t42-bg-mid)) transparent Rgb(var(--t42-bg-mid));border-radius:3px 3px 0 0}body .selectr-container.open .selectr-selected::after{-o-transform:rotate(180deg) translate3d(0px, 50%, 0px);-ms-transform:rotate(180deg) translate3d(0px, 50%, 0px);-moz-transform:rotate(180deg) translate3d(0px, 50%, 0px);-webkit-transform:rotate(180deg) translate3d(0px, 50%, 0px);transform:rotate(180deg) translate3d(0px, 50%, 0px)}body .selectr-disabled{opacity:.6}body .selectr-empty,body .has-selected .selectr-placeholder{display:none}body .has-selected .selectr-label{display:block}body .taggable .selectr-selected{padding:4px 28px 4px 4px}body .taggable .selectr-selected::after{display:table;content:" ";clear:both}body .taggable .selectr-label{width:auto}body .taggable .selectr-tags{float:left;display:block}body .taggable .selectr-placeholder{display:none}body .input-tag{float:left;min-width:90px;width:auto}body .selectr-tag-input{border:medium none;padding:3px 10px;width:100%;font-family:inherit;font-weight:inherit;font-size:inherit}body .selectr-input-container.loading::after{position:absolute;top:50%;right:20px;width:20px;height:20px;content:'';-o-transform:translate3d(0px, -50%, 0px);-ms-transform:translate3d(0px, -50%, 0px);-moz-transform:translate3d(0px, -50%, 0px);-webkit-transform:translate3d(0px, -50%, 0px);transform:translate3d(0px, -50%, 0px);-o-transform-origin:50% 0 0;-ms-transform-origin:50% 0 0;-moz-transform-origin:50% 0 0;-webkit-transform-origin:50% 0 0;transform-origin:50% 0 0;-moz-animation:500ms linear 0s normal forwards infinite running selectr-spin;-webkit-animation:500ms linear 0s normal forwards infinite running selectr-spin;animation:500ms linear 0s normal forwards infinite running selectr-spin;border-width:3px;border-style:solid;border-color:#aaa #ddd #ddd;border-radius:50%}@-webkit-keyframes selectr-spin{0%{-webkit-transform:rotate(0deg) translate3d(0px, -50%, 0px);transform:rotate(0deg) translate3d(0px, -50%, 0px)}100%{-webkit-transform:rotate(360deg) translate3d(0px, -50%, 0px);transform:rotate(360deg) translate3d(0px, -50%, 0px)}}@keyframes selectr-spin{0%{-webkit-transform:rotate(0deg) translate3d(0px, -50%, 0px);transform:rotate(0deg) translate3d(0px, -50%, 0px)}100%{-webkit-transform:rotate(360deg) translate3d(0px, -50%, 0px);transform:rotate(360deg) translate3d(0px, -50%, 0px)}}body .selectr-container.open.inverted .selectr-selected{border-color:transparent Rgb(var(--t42-bg-mid)) Rgb(var(--t42-bg-mid));border-radius:0 0 3px 3px}body .selectr-container.inverted .selectr-options-container{border-width:1px 1px 0;border-color:Rgb(var(--t42-bg-mid)) Rgb(var(--t42-bg-mid)) transparent;border-radius:3px 3px 0 0;background-color:var(--t42-content-color)}body .selectr-container.inverted .selectr-options-container{top:auto;bottom:calc(100% - 1px)}body .selectr-container ::-webkit-input-placeholder{color:#6c7a86;opacity:1}body .selectr-container ::-moz-placeholder{color:#6c7a86;opacity:1}body .selectr-container :-ms-input-placeholder{color:#6c7a86;opacity:1}body .selectr-container ::placeholder{color:#6c7a86;opacity:1}body #jsoneditor{height:100%}body .jsoneditor{border-color:var(--t42-color-opacity-10)}body .jsoneditor textarea{line-height:1.5;background-color:Rgb(var(--t42-bg-dark));min-height:100%}body .jsoneditor input{outline:0}body .jsoneditor input:focus{outline:0}body .jsoneditor-button:focus{outline:none}body .jsoneditor-menu{border-bottom-color:var(--t42-color-opacity-10);background-color:Rgb(var(--t42-bg-light))}body .jsoneditor-menu button{background-image:var(--t42-json-icons);background-color:transparent}body .jsoneditor-menu button:hover,body .jsoneditor-menu button:focus{color:var(--t42-link-hover-color)}body .jsoneditor-menu>button,body .jsoneditor-menu>.jsoneditor-modes>button{border-radius:0;font-size:.75rem;backdrop-filter:var(--backdrop-filter);transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, color}body .jsoneditor-menu>button:hover:not(.disabled):not(:disabled),body .jsoneditor-menu>button:active,body .jsoneditor-menu>.jsoneditor-modes>button:hover:not(.disabled):not(:disabled),body .jsoneditor-menu>.jsoneditor-modes>button:active{border-color:transparent;color:var(--t42-link-hover-color);background-color:var(--t42-color-opacity-10)}body .jsoneditor-menu li button.jsoneditor-selected{background-color:var(--t42-color-opacity-10)}body .jsoneditor-menu .jsoneditor-poweredBy{display:none}body .jsoneditor-frame{padding:0 .875rem;border-color:var(--t42-color-opacity-10);background-color:transparent;display:flex;transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border-color}body .jsoneditor-frame:focus-within{border-color:var(--primary);background-color:var(--t42-input-bg);outline:0}body .jsoneditor-frame table td{vertical-align:middle}body .jsoneditor-search input[type="text"]{border:0}body .jsoneditor-search input[type="text"]:focus{border:0}body .jsoneditor-search input{background-color:transparent}body .jsoneditor-contextmenu{z-index:2}body .jsoneditor-contextmenu .jsoneditor-menu{border-color:var(--t42-color-opacity-10);background:linear-gradient(to bottom right, rgba(var(--t42-bg-light), 0.75) 0%, rgba(var(--t42-bg-dark), 0.75) 100%);box-shadow:var(--t42-shadow);backdrop-filter:var(--backdrop-filter)}body .jsoneditor-contextmenu .jsoneditor-menu button button .jsoneditor-expand,body .jsoneditor-contextmenu .jsoneditor-menu li button .jsoneditor-expand{background-image:var(--t42-json-icons);z-index:1}body .jsoneditor-contextmenu .jsoneditor-menu button button.jsoneditor-selected,body .jsoneditor-contextmenu .jsoneditor-menu li button.jsoneditor-selected{background-color:var(--t42-color-opacity-10);transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, color}body .jsoneditor-contextmenu .jsoneditor-menu button button.jsoneditor-selected:hover,body .jsoneditor-contextmenu .jsoneditor-menu button button.jsoneditor-selected:focus,body .jsoneditor-contextmenu .jsoneditor-menu li button.jsoneditor-selected:hover,body .jsoneditor-contextmenu .jsoneditor-menu li button.jsoneditor-selected:focus{color:var(--t42-link-hover-color);background-color:var(--t42-color-opacity-10)}body .jsoneditor-contextmenu .jsoneditor-menu button{display:flex;justify-content:start}body .jsoneditor-contextmenu .jsoneditor-menu button.jsoneditor-default{float:left;z-index:1}body .jsoneditor-contextmenu .jsoneditor-menu li ul{padding:0 !important;left:0}body .jsoneditor-contextmenu .jsoneditor-menu li ul li button{padding-left:1rem}body .jsoneditor-contextmenu .jsoneditor-menu li ul .jsoneditor-icon{position:relative;margin-left:0}body .jsoneditor-contextmenu .jsoneditor-menu .jsoneditor-text{padding:0;line-height:1.5rem}body .jsoneditor-contextmenu .jsoneditor-icon{position:relative;background-image:var(--t42-json-icons)}body .jsoneditor-contextmenu .jsoneditor-separator{margin-top:0;padding-top:0}body .jsoneditor-mode-preview pre.jsoneditor-preview{border:0;line-height:1.5}body .jsoneditor-modal{border-top:0;background:linear-gradient(to bottom right, rgba(var(--t42-bg-light), 0.75) 0%, rgba(var(--t42-bg-dark), 0.75) 100%) !important;box-shadow:var(--t42-shadow) !important;backdrop-filter:var(--backdrop-filter)}body .jsoneditor-modal::before{position:absolute;top:0;right:0;left:0;display:block;width:100%;height:0.0625rem;background:linear-gradient(90deg, #007be5 0%, rgba(0,123,229,0.5) 100%);content:""}body .jsoneditor-modal .pico-modal-header{padding:0.5rem 0.988rem;background:transparent;font-size:0.75rem}body .jsoneditor-modal .pico-close{top:1rem !important;right:1rem !important;color:var(--t42-content-color-muted);transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:color}body .jsoneditor-modal .pico-close:not(.disabled):not(:disabled).active,body .jsoneditor-modal .pico-close:not(.disabled):not(:disabled):focus,body .jsoneditor-modal .pico-close:not(.disabled):not(:disabled):hover{color:var(--t42-link-color)}body .jsoneditor-modal table td{font-size:0.75rem;padding:0 0.25rem}body .jsoneditor-modal table td.jsoneditor-modal-input{padding-top:0.25rem;padding-bottom:0.25rem;text-align:left}body .jsoneditor-modal table td.jsoneditor-modal-input.jsoneditor-modal-actions{text-align:right}body .jsoneditor-modal table th{font-size:0.75rem}body .jsoneditor-modal label,body .jsoneditor-modal p{font-size:0.75rem}body .jsoneditor-modal select{min-width:12.375rem}body .jsoneditor-modal .selectr-selected{padding:0 0.857rem}body .jsoneditor-modal select,body .jsoneditor-modal textarea,body .jsoneditor-modal input,body .jsoneditor-modal input[type="text"],body .jsoneditor-modal input[type="search"],body .jsoneditor-modal #query{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border;border-color:var(--t42-color-opacity-10);border-radius:0;font-size:0.75rem;background-color:var(--t42-input-bg)}body .jsoneditor-modal select:focus,body .jsoneditor-modal textarea:focus,body .jsoneditor-modal input:focus,body .jsoneditor-modal input[type="text"]:focus,body .jsoneditor-modal input[type="search"]:focus,body .jsoneditor-modal #query:focus{border-color:var(--primary);box-shadow:none;outline:0;padding:0 0 0 .875rem;border-radius:0}body .jsoneditor-modal select:disabled,body .jsoneditor-modal select.disabled,body .jsoneditor-modal select[readonly],body .jsoneditor-modal textarea:disabled,body .jsoneditor-modal textarea.disabled,body .jsoneditor-modal textarea[readonly],body .jsoneditor-modal input:disabled,body .jsoneditor-modal input.disabled,body .jsoneditor-modal input[readonly],body .jsoneditor-modal input[type="text"]:disabled,body .jsoneditor-modal input[type="text"].disabled,body .jsoneditor-modal input[type="text"][readonly],body .jsoneditor-modal input[type="search"]:disabled,body .jsoneditor-modal input[type="search"].disabled,body .jsoneditor-modal input[type="search"][readonly],body .jsoneditor-modal #query:disabled,body .jsoneditor-modal #query.disabled,body .jsoneditor-modal #query[readonly]{cursor:default;opacity:0.65}body .jsoneditor-modal input[type="search"].selectr-input{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border-color;border:var(--t42-border);background-color:var(--t42-input-bg);margin:0;line-height:1.5rem;width:100%;padding:0 0.5rem}body .jsoneditor-modal input[type="search"].selectr-input:hover{border-color:var(--primary)}body .jsoneditor-modal .jsoneditor-select-wrapper::after{border-top:var(--t42-color-opacity-10)}body .jsoneditor-modal input[type="button"],body .jsoneditor-modal input[type="submit"]{padding:0 .875rem;border-radius:0;color:var(--t42-link-color);line-height:1.875rem;background:transparent;transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, border-color}body .jsoneditor-modal input[type="button"]:not(.disabled):not(:disabled).active,body .jsoneditor-modal input[type="button"]:not(.disabled):not(:disabled):hover,body .jsoneditor-modal input[type="submit"]:not(.disabled):not(:disabled).active,body .jsoneditor-modal input[type="submit"]:not(.disabled):not(:disabled):hover{border-color:var(--t42-color-opacity-30);color:var(--white);background:var(--primary)}body .jsoneditor-modal .jsoneditor-button-group input.jsoneditor-button-first{border-left-style:solid;border-top-left-radius:0;border-bottom-left-radius:0}body .jsoneditor-modal .jsoneditor-button-group input.jsoneditor-button-last{border-top-right-radius:0;border-bottom-right-radius:0}body .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-asc input.jsoneditor-button-asc,body .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-desc input.jsoneditor-button-desc{color:var(--white);background:var(--primary)}body .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-asc input.jsoneditor-button-asc:hover,body .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-asc input.jsoneditor-button-asc:focus,body .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-asc input.jsoneditor-button-asc:active,body .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-desc input.jsoneditor-button-desc:hover,body .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-desc input.jsoneditor-button-desc:focus,body .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-desc input.jsoneditor-button-desc:active{border-color:var(--t42-color-opacity-30);color:var(--white)}body .jsoneditor-modal .jsoneditor-jmespath-label{color:var(--t42-content-color);font-weight:400}body .jsoneditor-modal .jsoneditor-jmespath-filter-value input{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border-color;line-height:1.875rem;padding:0 0 0 .875rem;font-size:0.75rem;background-color:var(--t42-input-bg)}body .jsoneditor-modal .jsoneditor-jmespath-filter-value input:focus,body .jsoneditor-modal .jsoneditor-jmespath-filter-value input:hover{background-color:var(--t42-input-bg);border-color:var(--primary)}body .jsoneditor-jmespath-block .jsoneditor-modal-actions{text-align:right}body div.jsoneditor td.jsoneditor-tree{vertical-align:middle}body div.jsoneditor td.jsoneditor-separator{vertical-align:middle}body div.jsoneditor-tree{background:transparent}body div.jsoneditor-tree button.jsoneditor-button{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, outline-color;background-image:var(--t42-json-icons)}body div.jsoneditor-tree button.jsoneditor-button:focus{background-color:transparent;outline-color:var(--t42-color-opacity-10)}body tr.jsoneditor-selected,body tr.jsoneditor-highlight{background-color:var(--t42-color-opacity-10)}body .selectr-selected{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border-color;height:2rem;font-size:0.75rem;font-weight:400;line-height:1.875rem;background-color:var(--t42-input-bg);border-radius:0}body .selectr-selected::before{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:transform;right:0.5rem;border:0;width:0.75rem;height:0.75rem;background:var(--t42-select-indicator) center center/1rem 1rem no-repeat;transform:translateY(-50%)}body .selectr-placeholder{color:var(--t42-content-color-muted)}body .selectr-container.open .selectr-selected{border-radius:0;border-color:var(--primary)}body .selectr-container.open .selectr-selected::before{border:0;transform:rotate(180deg) translateY(50%)}body .selectr-container.open .selectr-options-container{border-left-color:var(--primary);border-right-color:var(--primary);border-bottom-color:var(--primary)}body .selectr-options{overflow-y:auto}body .selectr-options-container{min-height:2rem;border-color:var(--t42-color-opacity-10);border-style:solid;border-width:1px;background-color:Rgb(var(--t42-bg-dark))}body .selectr-options .active{color:var(--t42-link-hover-color);background-color:var(--t42-color-opacity-10)}body .selectr-options .selected{color:var(--t42-link-hover-color);background-color:var(--primary)}body .selectr-option{padding:0 0 0 0.875rem;line-height:2rem;font-size:0.75rem}body .selectr-input{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border-color;border:var(--t42-border);background-color:var(--t42-input-bg)}body .selectr-input:hover{border-color:var(--primary)}body .selectr-input-container{padding:0.25rem}body .selectr-clear::before,body .selectr-clear::after{background-color:var(--t42-content-color)}body .jsoneditor .ace-jsoneditor .ace_text-input{min-height:auto}body .jsoneditor .ace-jsoneditor.ace_editor,body .jsoneditor .ace-jsoneditor .ace_scroller{background-color:Rgb(var(--t42-bg-dark))}body .jsoneditor .ace-jsoneditor .ace_gutter{color:var(--t42-content-color-muted);background-color:Rgb(var(--t42-bg-mid))}body .jsoneditor .ace-jsoneditor .ace_gutter-active-line{background-color:Rgb(var(--t42-bg-light))}body .jsoneditor .ace-jsoneditor .ace_cursor{border-color:Rgb(var(--t42-content-color))}body .jsoneditor .ace-jsoneditor .ace_marker-layer .ace_active-line{background-color:rgba(var(--secondary), 0.25)}body .jsoneditor .ace-jsoneditor .ace_marker-layer .ace_selection{background-color:var(--t42-color-opacity-10)}body .jsoneditor .ace-jsoneditor .ace_marker-layer .ace_selected-word{border-color:var(--t42-color-opacity-10);background-color:var(--t42-color-opacity-10)}body .jsoneditor .ace-jsoneditor .ace_marker-layer .ace_bracket{border:var(--t42-border)}body .jsoneditor .ace-jsoneditor .ace_variable{color:var(--t42-content-color)}body .jsoneditor .ace-jsoneditor .ace_constant.ace_numeric{color:#ff511f}body .jsoneditor .ace-jsoneditor .ace_constant.ace_language{color:#f9a825}body .jsoneditor .ace-jsoneditor .ace_string{color:#43a047}body .jsoneditor .ace-jsoneditor .ace_fold{border-color:var(--t42-color-opacity-10);background-color:Rgb(var(--t42-bg-light));transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-image}body .jsoneditor .ace-jsoneditor .ace_fold-widget:hover,body .jsoneditor .ace-jsoneditor .ace_fold-widget:active{border-color:var(--t42-color-opacity-30);background-color:var(--t42-color-opacity-10);box-shadow:none}body .pico-modal-contents{display:block} + diff --git a/typescript/solution/client-details/src/lib/workspaces.umd.js b/typescript/solution/client-details/src/lib/workspaces.umd.js new file mode 100644 index 0000000..53ca1d8 --- /dev/null +++ b/typescript/solution/client-details/src/lib/workspaces.umd.js @@ -0,0 +1,5302 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define(factory) : + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.workspaces = factory()); +})(this, (function () { 'use strict'; + + function getDefaultExportFromCjs (x) { + return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; + } + + function createRegistry(options) { + if (options && options.errorHandling + && typeof options.errorHandling !== "function" + && options.errorHandling !== "log" + && options.errorHandling !== "silent" + && options.errorHandling !== "throw") { + throw new Error("Invalid options passed to createRegistry. Prop errorHandling should be [\"log\" | \"silent\" | \"throw\" | (err) => void], but " + typeof options.errorHandling + " was passed"); + } + var _userErrorHandler = options && typeof options.errorHandling === "function" && options.errorHandling; + var callbacks = {}; + function add(key, callback, replayArgumentsArr) { + var callbacksForKey = callbacks[key]; + if (!callbacksForKey) { + callbacksForKey = []; + callbacks[key] = callbacksForKey; + } + callbacksForKey.push(callback); + if (replayArgumentsArr) { + setTimeout(function () { + replayArgumentsArr.forEach(function (replayArgument) { + var _a; + if ((_a = callbacks[key]) === null || _a === void 0 ? void 0 : _a.includes(callback)) { + try { + if (Array.isArray(replayArgument)) { + callback.apply(undefined, replayArgument); + } + else { + callback.apply(undefined, [replayArgument]); + } + } + catch (err) { + _handleError(err, key); + } + } + }); + }, 0); + } + return function () { + var allForKey = callbacks[key]; + if (!allForKey) { + return; + } + allForKey = allForKey.reduce(function (acc, element, index) { + if (!(element === callback && acc.length === index)) { + acc.push(element); + } + return acc; + }, []); + if (allForKey.length === 0) { + delete callbacks[key]; + } + else { + callbacks[key] = allForKey; + } + }; + } + function execute(key) { + var argumentsArr = []; + for (var _i = 1; _i < arguments.length; _i++) { + argumentsArr[_i - 1] = arguments[_i]; + } + var callbacksForKey = callbacks[key]; + if (!callbacksForKey || callbacksForKey.length === 0) { + return []; + } + var results = []; + callbacksForKey.forEach(function (callback) { + try { + var result = callback.apply(undefined, argumentsArr); + results.push(result); + } + catch (err) { + results.push(undefined); + _handleError(err, key); + } + }); + return results; + } + function _handleError(exceptionArtifact, key) { + var errParam = exceptionArtifact instanceof Error ? exceptionArtifact : new Error(exceptionArtifact); + if (_userErrorHandler) { + _userErrorHandler(errParam); + return; + } + var msg = "[ERROR] callback-registry: User callback for key \"" + key + "\" failed: " + errParam.stack; + if (options) { + switch (options.errorHandling) { + case "log": + return console.error(msg); + case "silent": + return; + case "throw": + throw new Error(msg); + } + } + console.error(msg); + } + function clear() { + callbacks = {}; + } + function clearKey(key) { + var callbacksForKey = callbacks[key]; + if (!callbacksForKey) { + return; + } + delete callbacks[key]; + } + return { + add: add, + execute: execute, + clear: clear, + clearKey: clearKey + }; + } + createRegistry.default = createRegistry; + var lib = createRegistry; + + + var CallbackFactory = /*@__PURE__*/getDefaultExportFromCjs(lib); + + /** + * Wraps values in an `Ok` type. + * + * Example: `ok(5) // => {ok: true, result: 5}` + */ + var ok = function (result) { return ({ ok: true, result: result }); }; + /** + * Wraps errors in an `Err` type. + * + * Example: `err('on fire') // => {ok: false, error: 'on fire'}` + */ + var err = function (error) { return ({ ok: false, error: error }); }; + /** + * Create a `Promise` that either resolves with the result of `Ok` or rejects + * with the error of `Err`. + */ + var asPromise = function (r) { + return r.ok === true ? Promise.resolve(r.result) : Promise.reject(r.error); + }; + /** + * Unwraps a `Result` and returns either the result of an `Ok`, or + * `defaultValue`. + * + * Example: + * ``` + * Result.withDefault(5, number().run(json)) + * ``` + * + * It would be nice if `Decoder` had an instance method that mirrored this + * function. Such a method would look something like this: + * ``` + * class Decoder { + * runWithDefault = (defaultValue: A, json: any): A => + * Result.withDefault(defaultValue, this.run(json)); + * } + * + * number().runWithDefault(5, json) + * ``` + * Unfortunately, the type of `defaultValue: A` on the method causes issues + * with type inference on the `object` decoder in some situations. While these + * inference issues can be solved by providing the optional type argument for + * `object`s, the extra trouble and confusion doesn't seem worth it. + */ + var withDefault = function (defaultValue, r) { + return r.ok === true ? r.result : defaultValue; + }; + /** + * Return the successful result, or throw an error. + */ + var withException = function (r) { + if (r.ok === true) { + return r.result; + } + else { + throw r.error; + } + }; + /** + * Apply `f` to the result of an `Ok`, or pass the error through. + */ + var map = function (f, r) { + return r.ok === true ? ok(f(r.result)) : r; + }; + /** + * Apply `f` to the result of two `Ok`s, or pass an error through. If both + * `Result`s are errors then the first one is returned. + */ + var map2 = function (f, ar, br) { + return ar.ok === false ? ar : + br.ok === false ? br : + ok(f(ar.result, br.result)); + }; + /** + * Apply `f` to the error of an `Err`, or pass the success through. + */ + var mapError = function (f, r) { + return r.ok === true ? r : err(f(r.error)); + }; + /** + * Chain together a sequence of computations that may fail, similar to a + * `Promise`. If the first computation fails then the error will propagate + * through. If it succeeds, then `f` will be applied to the value, returning a + * new `Result`. + */ + var andThen = function (f, r) { + return r.ok === true ? f(r.result) : r; + }; + + /*! ***************************************************************************** + Copyright (c) Microsoft Corporation. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THIS SOFTWARE. + ***************************************************************************** */ + /* global Reflect, Promise */ + + + + var __assign = function() { + __assign = Object.assign || function __assign(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; + } + return t; + }; + return __assign.apply(this, arguments); + }; + + function __rest(s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { + if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) + t[p[i]] = s[p[i]]; + } + return t; + } + + function isEqual(a, b) { + if (a === b) { + return true; + } + if (a === null && b === null) { + return true; + } + if (typeof (a) !== typeof (b)) { + return false; + } + if (typeof (a) === 'object') { + // Array + if (Array.isArray(a)) { + if (!Array.isArray(b)) { + return false; + } + if (a.length !== b.length) { + return false; + } + for (var i = 0; i < a.length; i++) { + if (!isEqual(a[i], b[i])) { + return false; + } + } + return true; + } + // Hash table + var keys = Object.keys(a); + if (keys.length !== Object.keys(b).length) { + return false; + } + for (var i = 0; i < keys.length; i++) { + if (!b.hasOwnProperty(keys[i])) { + return false; + } + if (!isEqual(a[keys[i]], b[keys[i]])) { + return false; + } + } + return true; + } + } + /* + * Helpers + */ + var isJsonArray = function (json) { return Array.isArray(json); }; + var isJsonObject = function (json) { + return typeof json === 'object' && json !== null && !isJsonArray(json); + }; + var typeString = function (json) { + switch (typeof json) { + case 'string': + return 'a string'; + case 'number': + return 'a number'; + case 'boolean': + return 'a boolean'; + case 'undefined': + return 'undefined'; + case 'object': + if (json instanceof Array) { + return 'an array'; + } + else if (json === null) { + return 'null'; + } + else { + return 'an object'; + } + default: + return JSON.stringify(json); + } + }; + var expectedGot = function (expected, got) { + return "expected " + expected + ", got " + typeString(got); + }; + var printPath = function (paths) { + return paths.map(function (path) { return (typeof path === 'string' ? "." + path : "[" + path + "]"); }).join(''); + }; + var prependAt = function (newAt, _a) { + var at = _a.at, rest = __rest(_a, ["at"]); + return (__assign({ at: newAt + (at || '') }, rest)); + }; + /** + * Decoders transform json objects with unknown structure into known and + * verified forms. You can create objects of type `Decoder` with either the + * primitive decoder functions, such as `boolean()` and `string()`, or by + * applying higher-order decoders to the primitives, such as `array(boolean())` + * or `dict(string())`. + * + * Each of the decoder functions are available both as a static method on + * `Decoder` and as a function alias -- for example the string decoder is + * defined at `Decoder.string()`, but is also aliased to `string()`. Using the + * function aliases exported with the library is recommended. + * + * `Decoder` exposes a number of 'run' methods, which all decode json in the + * same way, but communicate success and failure in different ways. The `map` + * and `andThen` methods modify decoders without having to call a 'run' method. + * + * Alternatively, the main decoder `run()` method returns an object of type + * `Result`. This library provides a number of helper + * functions for dealing with the `Result` type, so you can do all the same + * things with a `Result` as with the decoder methods. + */ + var Decoder = /** @class */ (function () { + /** + * The Decoder class constructor is kept private to separate the internal + * `decode` function from the external `run` function. The distinction + * between the two functions is that `decode` returns a + * `Partial` on failure, which contains an unfinished error + * report. When `run` is called on a decoder, the relevant series of `decode` + * calls is made, and then on failure the resulting `Partial` + * is turned into a `DecoderError` by filling in the missing information. + * + * While hiding the constructor may seem restrictive, leveraging the + * provided decoder combinators and helper functions such as + * `andThen` and `map` should be enough to build specialized decoders as + * needed. + */ + function Decoder(decode) { + var _this = this; + this.decode = decode; + /** + * Run the decoder and return a `Result` with either the decoded value or a + * `DecoderError` containing the json input, the location of the error, and + * the error message. + * + * Examples: + * ``` + * number().run(12) + * // => {ok: true, result: 12} + * + * string().run(9001) + * // => + * // { + * // ok: false, + * // error: { + * // kind: 'DecoderError', + * // input: 9001, + * // at: 'input', + * // message: 'expected a string, got 9001' + * // } + * // } + * ``` + */ + this.run = function (json) { + return mapError(function (error) { return ({ + kind: 'DecoderError', + input: json, + at: 'input' + (error.at || ''), + message: error.message || '' + }); }, _this.decode(json)); + }; + /** + * Run the decoder as a `Promise`. + */ + this.runPromise = function (json) { return asPromise(_this.run(json)); }; + /** + * Run the decoder and return the value on success, or throw an exception + * with a formatted error string. + */ + this.runWithException = function (json) { return withException(_this.run(json)); }; + /** + * Construct a new decoder that applies a transformation to the decoded + * result. If the decoder succeeds then `f` will be applied to the value. If + * it fails the error will propagated through. + * + * Example: + * ``` + * number().map(x => x * 5).run(10) + * // => {ok: true, result: 50} + * ``` + */ + this.map = function (f) { + return new Decoder(function (json) { return map(f, _this.decode(json)); }); + }; + /** + * Chain together a sequence of decoders. The first decoder will run, and + * then the function will determine what decoder to run second. If the result + * of the first decoder succeeds then `f` will be applied to the decoded + * value. If it fails the error will propagate through. + * + * This is a very powerful method -- it can act as both the `map` and `where` + * methods, can improve error messages for edge cases, and can be used to + * make a decoder for custom types. + * + * Example of adding an error message: + * ``` + * const versionDecoder = valueAt(['version'], number()); + * const infoDecoder3 = object({a: boolean()}); + * + * const decoder = versionDecoder.andThen(version => { + * switch (version) { + * case 3: + * return infoDecoder3; + * default: + * return fail(`Unable to decode info, version ${version} is not supported.`); + * } + * }); + * + * decoder.run({version: 3, a: true}) + * // => {ok: true, result: {a: true}} + * + * decoder.run({version: 5, x: 'abc'}) + * // => + * // { + * // ok: false, + * // error: {... message: 'Unable to decode info, version 5 is not supported.'} + * // } + * ``` + * + * Example of decoding a custom type: + * ``` + * // nominal type for arrays with a length of at least one + * type NonEmptyArray = T[] & { __nonEmptyArrayBrand__: void }; + * + * const nonEmptyArrayDecoder = (values: Decoder): Decoder> => + * array(values).andThen(arr => + * arr.length > 0 + * ? succeed(createNonEmptyArray(arr)) + * : fail(`expected a non-empty array, got an empty array`) + * ); + * ``` + */ + this.andThen = function (f) { + return new Decoder(function (json) { + return andThen(function (value) { return f(value).decode(json); }, _this.decode(json)); + }); + }; + /** + * Add constraints to a decoder _without_ changing the resulting type. The + * `test` argument is a predicate function which returns true for valid + * inputs. When `test` fails on an input, the decoder fails with the given + * `errorMessage`. + * + * ``` + * const chars = (length: number): Decoder => + * string().where( + * (s: string) => s.length === length, + * `expected a string of length ${length}` + * ); + * + * chars(5).run('12345') + * // => {ok: true, result: '12345'} + * + * chars(2).run('HELLO') + * // => {ok: false, error: {... message: 'expected a string of length 2'}} + * + * chars(12).run(true) + * // => {ok: false, error: {... message: 'expected a string, got a boolean'}} + * ``` + */ + this.where = function (test, errorMessage) { + return _this.andThen(function (value) { return (test(value) ? Decoder.succeed(value) : Decoder.fail(errorMessage)); }); + }; + } + /** + * Decoder primitive that validates strings, and fails on all other input. + */ + Decoder.string = function () { + return new Decoder(function (json) { + return typeof json === 'string' + ? ok(json) + : err({ message: expectedGot('a string', json) }); + }); + }; + /** + * Decoder primitive that validates numbers, and fails on all other input. + */ + Decoder.number = function () { + return new Decoder(function (json) { + return typeof json === 'number' + ? ok(json) + : err({ message: expectedGot('a number', json) }); + }); + }; + /** + * Decoder primitive that validates booleans, and fails on all other input. + */ + Decoder.boolean = function () { + return new Decoder(function (json) { + return typeof json === 'boolean' + ? ok(json) + : err({ message: expectedGot('a boolean', json) }); + }); + }; + Decoder.constant = function (value) { + return new Decoder(function (json) { + return isEqual(json, value) + ? ok(value) + : err({ message: "expected " + JSON.stringify(value) + ", got " + JSON.stringify(json) }); + }); + }; + Decoder.object = function (decoders) { + return new Decoder(function (json) { + if (isJsonObject(json) && decoders) { + var obj = {}; + for (var key in decoders) { + if (decoders.hasOwnProperty(key)) { + var r = decoders[key].decode(json[key]); + if (r.ok === true) { + // tslint:disable-next-line:strict-type-predicates + if (r.result !== undefined) { + obj[key] = r.result; + } + } + else if (json[key] === undefined) { + return err({ message: "the key '" + key + "' is required but was not present" }); + } + else { + return err(prependAt("." + key, r.error)); + } + } + } + return ok(obj); + } + else if (isJsonObject(json)) { + return ok(json); + } + else { + return err({ message: expectedGot('an object', json) }); + } + }); + }; + Decoder.array = function (decoder) { + return new Decoder(function (json) { + if (isJsonArray(json) && decoder) { + var decodeValue_1 = function (v, i) { + return mapError(function (err$$1) { return prependAt("[" + i + "]", err$$1); }, decoder.decode(v)); + }; + return json.reduce(function (acc, v, i) { + return map2(function (arr, result) { return arr.concat([result]); }, acc, decodeValue_1(v, i)); + }, ok([])); + } + else if (isJsonArray(json)) { + return ok(json); + } + else { + return err({ message: expectedGot('an array', json) }); + } + }); + }; + Decoder.tuple = function (decoders) { + return new Decoder(function (json) { + if (isJsonArray(json)) { + if (json.length !== decoders.length) { + return err({ + message: "expected a tuple of length " + decoders.length + ", got one of length " + json.length + }); + } + var result = []; + for (var i = 0; i < decoders.length; i++) { + var nth = decoders[i].decode(json[i]); + if (nth.ok) { + result[i] = nth.result; + } + else { + return err(prependAt("[" + i + "]", nth.error)); + } + } + return ok(result); + } + else { + return err({ message: expectedGot("a tuple of length " + decoders.length, json) }); + } + }); + }; + Decoder.union = function (ad, bd) { + var decoders = []; + for (var _i = 2; _i < arguments.length; _i++) { + decoders[_i - 2] = arguments[_i]; + } + return Decoder.oneOf.apply(Decoder, [ad, bd].concat(decoders)); + }; + Decoder.intersection = function (ad, bd) { + var ds = []; + for (var _i = 2; _i < arguments.length; _i++) { + ds[_i - 2] = arguments[_i]; + } + return new Decoder(function (json) { + return [ad, bd].concat(ds).reduce(function (acc, decoder) { return map2(Object.assign, acc, decoder.decode(json)); }, ok({})); + }); + }; + /** + * Escape hatch to bypass validation. Always succeeds and types the result as + * `any`. Useful for defining decoders incrementally, particularly for + * complex objects. + * + * Example: + * ``` + * interface User { + * name: string; + * complexUserData: ComplexType; + * } + * + * const userDecoder: Decoder = object({ + * name: string(), + * complexUserData: anyJson() + * }); + * ``` + */ + Decoder.anyJson = function () { return new Decoder(function (json) { return ok(json); }); }; + /** + * Decoder identity function which always succeeds and types the result as + * `unknown`. + */ + Decoder.unknownJson = function () { + return new Decoder(function (json) { return ok(json); }); + }; + /** + * Decoder for json objects where the keys are unknown strings, but the values + * should all be of the same type. + * + * Example: + * ``` + * dict(number()).run({chocolate: 12, vanilla: 10, mint: 37}); + * // => {ok: true, result: {chocolate: 12, vanilla: 10, mint: 37}} + * ``` + */ + Decoder.dict = function (decoder) { + return new Decoder(function (json) { + if (isJsonObject(json)) { + var obj = {}; + for (var key in json) { + if (json.hasOwnProperty(key)) { + var r = decoder.decode(json[key]); + if (r.ok === true) { + obj[key] = r.result; + } + else { + return err(prependAt("." + key, r.error)); + } + } + } + return ok(obj); + } + else { + return err({ message: expectedGot('an object', json) }); + } + }); + }; + /** + * Decoder for values that may be `undefined`. This is primarily helpful for + * decoding interfaces with optional fields. + * + * Example: + * ``` + * interface User { + * id: number; + * isOwner?: boolean; + * } + * + * const decoder: Decoder = object({ + * id: number(), + * isOwner: optional(boolean()) + * }); + * ``` + */ + Decoder.optional = function (decoder) { + return new Decoder(function (json) { return (json === undefined || json === null ? ok(undefined) : decoder.decode(json)); }); + }; + /** + * Decoder that attempts to run each decoder in `decoders` and either succeeds + * with the first successful decoder, or fails after all decoders have failed. + * + * Note that `oneOf` expects the decoders to all have the same return type, + * while `union` creates a decoder for the union type of all the input + * decoders. + * + * Examples: + * ``` + * oneOf(string(), number().map(String)) + * oneOf(constant('start'), constant('stop'), succeed('unknown')) + * ``` + */ + Decoder.oneOf = function () { + var decoders = []; + for (var _i = 0; _i < arguments.length; _i++) { + decoders[_i] = arguments[_i]; + } + return new Decoder(function (json) { + var errors = []; + for (var i = 0; i < decoders.length; i++) { + var r = decoders[i].decode(json); + if (r.ok === true) { + return r; + } + else { + errors[i] = r.error; + } + } + var errorsList = errors + .map(function (error) { return "at error" + (error.at || '') + ": " + error.message; }) + .join('", "'); + return err({ + message: "expected a value matching one of the decoders, got the errors [\"" + errorsList + "\"]" + }); + }); + }; + /** + * Decoder that always succeeds with either the decoded value, or a fallback + * default value. + */ + Decoder.withDefault = function (defaultValue, decoder) { + return new Decoder(function (json) { + return ok(withDefault(defaultValue, decoder.decode(json))); + }); + }; + /** + * Decoder that pulls a specific field out of a json structure, instead of + * decoding and returning the full structure. The `paths` array describes the + * object keys and array indices to traverse, so that values can be pulled out + * of a nested structure. + * + * Example: + * ``` + * const decoder = valueAt(['a', 'b', 0], string()); + * + * decoder.run({a: {b: ['surprise!']}}) + * // => {ok: true, result: 'surprise!'} + * + * decoder.run({a: {x: 'cats'}}) + * // => {ok: false, error: {... at: 'input.a.b[0]' message: 'path does not exist'}} + * ``` + * + * Note that the `decoder` is ran on the value found at the last key in the + * path, even if the last key is not found. This allows the `optional` + * decoder to succeed when appropriate. + * ``` + * const optionalDecoder = valueAt(['a', 'b', 'c'], optional(string())); + * + * optionalDecoder.run({a: {b: {c: 'surprise!'}}}) + * // => {ok: true, result: 'surprise!'} + * + * optionalDecoder.run({a: {b: 'cats'}}) + * // => {ok: false, error: {... at: 'input.a.b.c' message: 'expected an object, got "cats"'} + * + * optionalDecoder.run({a: {b: {z: 1}}}) + * // => {ok: true, result: undefined} + * ``` + */ + Decoder.valueAt = function (paths, decoder) { + return new Decoder(function (json) { + var jsonAtPath = json; + for (var i = 0; i < paths.length; i++) { + if (jsonAtPath === undefined) { + return err({ + at: printPath(paths.slice(0, i + 1)), + message: 'path does not exist' + }); + } + else if (typeof paths[i] === 'string' && !isJsonObject(jsonAtPath)) { + return err({ + at: printPath(paths.slice(0, i + 1)), + message: expectedGot('an object', jsonAtPath) + }); + } + else if (typeof paths[i] === 'number' && !isJsonArray(jsonAtPath)) { + return err({ + at: printPath(paths.slice(0, i + 1)), + message: expectedGot('an array', jsonAtPath) + }); + } + else { + jsonAtPath = jsonAtPath[paths[i]]; + } + } + return mapError(function (error) { + return jsonAtPath === undefined + ? { at: printPath(paths), message: 'path does not exist' } + : prependAt(printPath(paths), error); + }, decoder.decode(jsonAtPath)); + }); + }; + /** + * Decoder that ignores the input json and always succeeds with `fixedValue`. + */ + Decoder.succeed = function (fixedValue) { + return new Decoder(function (json) { return ok(fixedValue); }); + }; + /** + * Decoder that ignores the input json and always fails with `errorMessage`. + */ + Decoder.fail = function (errorMessage) { + return new Decoder(function (json) { return err({ message: errorMessage }); }); + }; + /** + * Decoder that allows for validating recursive data structures. Unlike with + * functions, decoders assigned to variables can't reference themselves + * before they are fully defined. We can avoid prematurely referencing the + * decoder by wrapping it in a function that won't be called until use, at + * which point the decoder has been defined. + * + * Example: + * ``` + * interface Comment { + * msg: string; + * replies: Comment[]; + * } + * + * const decoder: Decoder = object({ + * msg: string(), + * replies: lazy(() => array(decoder)) + * }); + * ``` + */ + Decoder.lazy = function (mkDecoder) { + return new Decoder(function (json) { return mkDecoder().decode(json); }); + }; + return Decoder; + }()); + + /* tslint:disable:variable-name */ + /** See `Decoder.string` */ + var string = Decoder.string; + /** See `Decoder.number` */ + var number = Decoder.number; + /** See `Decoder.boolean` */ + var boolean = Decoder.boolean; + /** See `Decoder.anyJson` */ + var anyJson = Decoder.anyJson; + /** See `Decoder.unknownJson` */ + Decoder.unknownJson; + /** See `Decoder.constant` */ + var constant = Decoder.constant; + /** See `Decoder.object` */ + var object = Decoder.object; + /** See `Decoder.array` */ + var array = Decoder.array; + /** See `Decoder.tuple` */ + Decoder.tuple; + /** See `Decoder.dict` */ + Decoder.dict; + /** See `Decoder.optional` */ + var optional = Decoder.optional; + /** See `Decoder.oneOf` */ + var oneOf = Decoder.oneOf; + /** See `Decoder.union` */ + Decoder.union; + /** See `Decoder.intersection` */ + var intersection = Decoder.intersection; + /** See `Decoder.withDefault` */ + Decoder.withDefault; + /** See `Decoder.valueAt` */ + Decoder.valueAt; + /** See `Decoder.succeed` */ + Decoder.succeed; + /** See `Decoder.fail` */ + Decoder.fail; + /** See `Decoder.lazy` */ + var lazy = Decoder.lazy; + + const nonEmptyStringDecoder = string().where((s) => s.length > 0, "Expected a non-empty string"); + const nonNegativeNumberDecoder = number().where((num) => num >= 0, "Expected a non-negative number"); + const positiveNumberDecoder = number().where((num) => num > 0, "Expected a positive number"); + const windowDragModeDecoder = oneOf(constant("keepInside"), constant("autoEject")); + const isWindowInSwimlaneResultDecoder = object({ + inWorkspace: boolean() + }); + const allParentDecoder = oneOf(constant("workspace"), constant("row"), constant("column"), constant("group")); + const subParentDecoder = oneOf(constant("row"), constant("column"), constant("group")); + const frameStateDecoder = oneOf(constant("maximized"), constant("minimized"), constant("normal")); + const loadingAnimationTypeDecoder = oneOf(constant("workspace")); + const checkThrowCallback = (callback, allowUndefined) => { + const argumentType = typeof callback; + if (allowUndefined && argumentType !== "function" && argumentType !== "undefined") { + throw new Error(`Provided argument must be either undefined or of type function, provided: ${argumentType}`); + } + if (!allowUndefined && argumentType !== "function") { + throw new Error(`Provided argument must be of type function, provided: ${argumentType}`); + } + }; + const workspaceBuilderCreateConfigDecoder = optional(object({ + saveLayout: optional(boolean()) + })); + const deleteLayoutConfigDecoder = object({ + name: nonEmptyStringDecoder + }); + const windowDefinitionConfigDecoder = object({ + minWidth: optional(number()), + maxWidth: optional(number()), + minHeight: optional(number()), + maxHeight: optional(number()), + allowExtract: optional(boolean()), + allowReorder: optional(boolean()), + showCloseButton: optional(boolean()) + }); + const groupDefinitionConfigDecoder = object({ + minWidth: optional(number()), + maxWidth: optional(number()), + minHeight: optional(number()), + maxHeight: optional(number()), + allowExtract: optional(boolean()), + allowReorder: optional(boolean()), + allowDrop: optional(boolean()), + allowDropHeader: optional(boolean()), + allowDropLeft: optional(boolean()), + allowDropRight: optional(boolean()), + allowDropTop: optional(boolean()), + allowDropBottom: optional(boolean()), + showMaximizeButton: optional(boolean()), + showEjectButton: optional(boolean()), + showAddWindowButton: optional(boolean()) + }); + const rowDefinitionConfigDecoder = object({ + minHeight: optional(number()), + maxHeight: optional(number()), + allowDrop: optional(boolean()), + allowSplitters: optional(boolean()), + isPinned: optional(boolean()), + maximizationBoundary: optional(boolean()) + }); + const columnDefinitionConfigDecoder = object({ + minWidth: optional(number()), + maxWidth: optional(number()), + allowDrop: optional(boolean()), + allowSplitters: optional(boolean()), + isPinned: optional(boolean()), + maximizationBoundary: optional(boolean()) + }); + const swimlaneWindowDefinitionDecoder = object({ + type: optional(constant("window")), + appName: optional(nonEmptyStringDecoder), + windowId: optional(nonEmptyStringDecoder), + context: optional(anyJson()), + config: optional(windowDefinitionConfigDecoder) + }); + const strictSwimlaneWindowDefinitionDecoder = object({ + type: constant("window"), + appName: optional(nonEmptyStringDecoder), + windowId: optional(nonEmptyStringDecoder), + context: optional(anyJson()), + config: optional(windowDefinitionConfigDecoder) + }); + const parentDefinitionDecoder = optional(object({ + type: optional(subParentDecoder), + children: optional(lazy(() => array(oneOf(swimlaneWindowDefinitionDecoder, parentDefinitionDecoder)))), + config: optional(anyJson()) + })); + const strictColumnDefinitionDecoder = object({ + type: constant("column"), + children: optional(lazy(() => array(oneOf(strictSwimlaneWindowDefinitionDecoder, strictParentDefinitionDecoder)))), + config: optional(columnDefinitionConfigDecoder) + }); + const strictRowDefinitionDecoder = object({ + type: constant("row"), + children: optional(lazy(() => array(oneOf(strictSwimlaneWindowDefinitionDecoder, strictParentDefinitionDecoder)))), + config: optional(rowDefinitionConfigDecoder) + }); + const strictGroupDefinitionDecoder = object({ + type: constant("group"), + children: optional(lazy(() => array(oneOf(strictSwimlaneWindowDefinitionDecoder, strictParentDefinitionDecoder)))), + config: optional(groupDefinitionConfigDecoder) + }); + const strictParentDefinitionDecoder = oneOf(strictGroupDefinitionDecoder, strictColumnDefinitionDecoder, strictRowDefinitionDecoder); + oneOf(string().where((s) => s.toLowerCase() === "maximized", "Expected a case insensitive variation of 'maximized'"), string().where((s) => s.toLowerCase() === "normal", "Expected a case insensitive variation of 'normal'")); + const newFrameConfigDecoder = object({ + bounds: optional(object({ + left: optional(number()), + top: optional(number()), + width: optional(nonNegativeNumberDecoder), + height: optional(nonNegativeNumberDecoder) + })), + frameId: optional(nonEmptyStringDecoder) + }); + const loadingStrategyDecoder = oneOf(constant("direct"), constant("delayed"), constant("lazy")); + const restoreWorkspaceConfigDecoder = optional(object({ + app: optional(nonEmptyStringDecoder), + context: optional(anyJson()), + loadingStrategy: optional(loadingStrategyDecoder), + title: optional(nonEmptyStringDecoder), + reuseWorkspaceId: optional(nonEmptyStringDecoder), + frameId: optional(nonEmptyStringDecoder), + applicationName: optional(nonEmptyStringDecoder), + lockdown: optional(boolean()), + activateFrame: optional(boolean()), + newFrame: optional(oneOf(newFrameConfigDecoder, boolean())), + noTabHeader: optional(boolean()), + inMemoryLayout: optional(boolean()), + icon: optional(nonEmptyStringDecoder), + isPinned: optional(boolean()), + isSelected: optional(boolean()), + positionIndex: optional(nonNegativeNumberDecoder), + allowSystemHibernation: optional(boolean()) + })); + const openWorkspaceConfigDecoder = object({ + name: nonEmptyStringDecoder, + restoreOptions: optional(restoreWorkspaceConfigDecoder) + }); + const workspaceDefinitionDecoder = object({ + children: optional(array(oneOf(swimlaneWindowDefinitionDecoder, strictParentDefinitionDecoder))), + context: optional(anyJson()), + config: optional(object({ + title: optional(nonEmptyStringDecoder), + position: optional(nonNegativeNumberDecoder), + isFocused: optional(boolean()), + noTabHeader: optional(boolean()), + reuseWorkspaceId: optional(nonEmptyStringDecoder), + loadingStrategy: optional(loadingStrategyDecoder), + allowDrop: optional(boolean()), + allowDropLeft: optional(boolean()), + allowDropTop: optional(boolean()), + allowDropRight: optional(boolean()), + allowDropBottom: optional(boolean()), + allowSystemHibernation: optional(boolean()), + allowExtract: optional(boolean()), + allowWindowReorder: optional(boolean()), + showSaveButton: optional(boolean()), + allowWorkspaceTabReorder: optional(boolean()), + allowWorkspaceTabExtract: optional(boolean()), + showCloseButton: optional(boolean()), + allowSplitters: optional(boolean()), + showWindowCloseButtons: optional(boolean()), + showEjectButtons: optional(boolean()), + showAddWindowButtons: optional(boolean()), + icon: optional(nonEmptyStringDecoder), + isPinned: optional(boolean()), + isSelected: optional(boolean()), + positionIndex: optional(nonNegativeNumberDecoder), + windowDragMode: optional(windowDragModeDecoder) + })), + frame: optional(object({ + activate: optional(boolean()), + reuseFrameId: optional(nonEmptyStringDecoder), + applicationName: optional(nonEmptyStringDecoder), + newFrame: optional(oneOf(boolean(), newFrameConfigDecoder)) + })) + }); + const workspaceSelectorDecoder = object({ + workspaceId: nonEmptyStringDecoder + }); + const restoreWorkspaceDefinitionDecoder = object({ + name: nonEmptyStringDecoder, + restoreOptions: optional(restoreWorkspaceConfigDecoder) + }); + const emptyFrameDefinitionDecoder = optional(object({ + applicationName: optional(string()), + frameConfig: optional(newFrameConfigDecoder), + context: optional(object()), + layoutComponentId: optional(nonEmptyStringDecoder) + })); + const frameInitConfigDecoder = object({ + workspaces: array(oneOf(optional(workspaceDefinitionDecoder), optional(restoreWorkspaceDefinitionDecoder))) + }); + const frameInitProtocolConfigDecoder = object({ + frameId: nonEmptyStringDecoder, + workspaces: array(oneOf(workspaceDefinitionDecoder, restoreWorkspaceDefinitionDecoder)) + }); + const builderConfigDecoder = object({ + type: allParentDecoder, + definition: optional(oneOf(workspaceDefinitionDecoder, parentDefinitionDecoder)) + }); + const workspaceCreateConfigDecoder = intersection(workspaceDefinitionDecoder, object({ + saveConfig: optional(object({ + saveLayout: optional(boolean()) + })) + })); + const getFrameSummaryConfigDecoder = object({ + itemId: nonEmptyStringDecoder + }); + const frameInitializationContextDecoder = object({ + context: optional(object()) + }); + const frameSummaryDecoder = object({ + id: nonEmptyStringDecoder, + isFocused: optional(boolean()), + isInitialized: optional(boolean()), + initializationContext: optional(frameInitializationContextDecoder) + }); + object({ + type: subParentDecoder, + id: nonEmptyStringDecoder, + frameId: nonEmptyStringDecoder, + workspaceId: nonEmptyStringDecoder, + positionIndex: number() + }); + const eventTypeDecoder = oneOf(constant("frame"), constant("workspace"), constant("container"), constant("window")); + const streamRequestArgumentsDecoder = object({ + type: eventTypeDecoder, + branch: nonEmptyStringDecoder + }); + const workspaceEventActionDecoder = oneOf(constant("opened"), constant("closing"), constant("closed"), constant("focus"), constant("added"), constant("loaded"), constant("removed"), constant("childrenUpdate"), constant("containerChange"), constant("maximized"), constant("restored"), constant("minimized"), constant("normal"), constant("selected"), constant("lock-configuration-changed"), constant("hibernated"), constant("resumed")); + const workspaceConfigResultDecoder = object({ + frameId: nonEmptyStringDecoder, + title: nonEmptyStringDecoder, + positionIndex: nonNegativeNumberDecoder, + name: nonEmptyStringDecoder, + layoutName: optional(nonEmptyStringDecoder), + isHibernated: optional(boolean()), + isSelected: optional(boolean()), + allowDrop: optional(boolean()), + allowSystemHibernation: optional(boolean()), + allowExtract: optional(boolean()), + allowWindowReorder: optional(boolean()), + allowSplitters: optional(boolean()), + showCloseButton: optional(boolean()), + showSaveButton: optional(boolean()), + allowWorkspaceTabReorder: optional(boolean()), + allowWorkspaceTabExtract: optional(boolean()), + allowDropLeft: optional(boolean()), + allowDropTop: optional(boolean()), + allowDropRight: optional(boolean()), + allowDropBottom: optional(boolean()), + minWidth: optional(number()), + maxWidth: optional(number()), + minHeight: optional(number()), + maxHeight: optional(number()), + showAddWindowButtons: optional(boolean()), + showEjectButtons: optional(boolean()), + showWindowCloseButtons: optional(boolean()), + widthInPx: optional(number()), + heightInPx: optional(number()), + isPinned: optional(boolean()), + windowDragMode: optional(windowDragModeDecoder), + loadingStrategy: optional(loadingStrategyDecoder) + }); + const baseChildSnapshotConfigDecoder = object({ + frameId: nonEmptyStringDecoder, + workspaceId: nonEmptyStringDecoder, + positionIndex: number(), + minWidth: optional(number()), + maxWidth: optional(number()), + minHeight: optional(number()), + maxHeight: optional(number()) + }); + const parentSnapshotConfigDecoder = anyJson(); + const swimlaneWindowSnapshotConfigDecoder = intersection(baseChildSnapshotConfigDecoder, object({ + windowId: optional(nonEmptyStringDecoder), + isMaximized: optional(boolean()), + isFocused: boolean(), + isSelected: optional(boolean()), + title: optional(string()), + appName: optional(nonEmptyStringDecoder), + allowExtract: optional(boolean()), + allowReorder: optional(boolean()), + showCloseButton: optional(boolean()), + minWidth: optional(number()), + minHeight: optional(number()), + maxWidth: optional(number()), + maxHeight: optional(number()), + widthInPx: optional(number()), + heightInPx: optional(number()), + context: optional(anyJson()) + })); + const customWorkspaceSubParentSnapshotDecoder = object({ + id: optional(nonEmptyStringDecoder), + config: parentSnapshotConfigDecoder, + children: optional(lazy(() => array(customWorkspaceChildSnapshotDecoder))), + type: oneOf(constant("row"), constant("column"), constant("group")) + }); + const customWorkspaceWindowSnapshotDecoder = object({ + id: optional(nonEmptyStringDecoder), + config: swimlaneWindowSnapshotConfigDecoder, + type: constant("window") + }); + const customWorkspaceChildSnapshotDecoder = oneOf(customWorkspaceWindowSnapshotDecoder, customWorkspaceSubParentSnapshotDecoder); + const childSnapshotResultDecoder = customWorkspaceChildSnapshotDecoder; + const workspaceSnapshotResultDecoder = object({ + id: nonEmptyStringDecoder, + config: workspaceConfigResultDecoder, + children: array(childSnapshotResultDecoder), + frameSummary: frameSummaryDecoder, + context: optional(anyJson()) + }); + const windowLayoutItemDecoder = object({ + type: constant("window"), + config: object({ + appName: nonEmptyStringDecoder, + windowId: optional(nonEmptyStringDecoder), + context: optional(anyJson()), + url: optional(nonEmptyStringDecoder), + title: optional(string()), + allowExtract: optional(boolean()), + allowReorder: optional(boolean()), + showCloseButton: optional(boolean()), + minWidth: optional(number()), + minHeight: optional(number()), + maxWidth: optional(number()), + maxHeight: optional(number()), + isMaximized: optional(boolean()) + }) + }); + const groupLayoutItemDecoder = object({ + type: constant("group"), + config: anyJson(), + children: array(oneOf(windowLayoutItemDecoder)) + }); + const columnLayoutItemDecoder = object({ + type: constant("column"), + config: anyJson(), + children: array(oneOf(groupLayoutItemDecoder, windowLayoutItemDecoder, lazy(() => columnLayoutItemDecoder), lazy(() => rowLayoutItemDecoder))) + }); + const rowLayoutItemDecoder = object({ + type: constant("row"), + config: anyJson(), + children: array(oneOf(columnLayoutItemDecoder, groupLayoutItemDecoder, windowLayoutItemDecoder, lazy(() => rowLayoutItemDecoder))) + }); + const workspaceLayoutDecoder = object({ + name: nonEmptyStringDecoder, + type: constant("Workspace"), + metadata: optional(anyJson()), + components: array(object({ + type: constant("Workspace"), + application: optional(string()), + state: object({ + config: anyJson(), + context: anyJson(), + children: array(oneOf(rowLayoutItemDecoder, columnLayoutItemDecoder, groupLayoutItemDecoder, windowLayoutItemDecoder)) + }) + })) + }); + const workspacesImportLayoutDecoder = object({ + layout: workspaceLayoutDecoder, + mode: oneOf(constant("replace"), constant("merge")) + }); + const workspacesImportLayoutsDecoder = object({ + layouts: array(workspaceLayoutDecoder), + mode: oneOf(constant("replace"), constant("merge")) + }); + const exportedLayoutsResultDecoder = object({ + layouts: array(workspaceLayoutDecoder) + }); + const frameSummaryResultDecoder = object({ + id: nonEmptyStringDecoder, + isFocused: optional(boolean()), + isInitialized: optional(boolean()), + initializationContext: optional(frameInitializationContextDecoder) + }); + const frameSummariesResultDecoder = object({ + summaries: array(frameSummaryResultDecoder) + }); + const workspaceSummaryResultDecoder = object({ + id: nonEmptyStringDecoder, + config: workspaceConfigResultDecoder + }); + const workspaceSummariesResultDecoder = object({ + summaries: array(workspaceSummaryResultDecoder) + }); + const frameSnapshotResultDecoder = object({ + id: nonEmptyStringDecoder, + config: anyJson(), + workspaces: array(workspaceSnapshotResultDecoder) + }); + const layoutSummaryDecoder = object({ + name: nonEmptyStringDecoder, + applicationName: optional(string()) + }); + const layoutSummariesDecoder = object({ + summaries: array(layoutSummaryDecoder) + }); + const simpleWindowOperationSuccessResultDecoder = object({ + windowId: nonEmptyStringDecoder + }); + const voidResultDecoder = anyJson(); + const frameStateResultDecoder = object({ + state: frameStateDecoder + }); + const frameBoundsDecoder = object({ + top: number(), + left: number(), + width: nonNegativeNumberDecoder, + height: nonNegativeNumberDecoder + }); + const frameBoundsResultDecoder = object({ + bounds: frameBoundsDecoder + }); + const getWorkspaceIconResultDecoder = object({ + icon: optional(nonEmptyStringDecoder) + }); + const getPlatformFrameIdResultDecoder = object({ + id: optional(nonEmptyStringDecoder) + }); + const operationCheckResultDecoder = object({ + isSupported: boolean() + }); + const resizeConfigDecoder = object({ + width: optional(positiveNumberDecoder), + height: optional(positiveNumberDecoder), + relative: optional(boolean()) + }); + const moveConfigDecoder = object({ + top: optional(number()), + left: optional(number()), + relative: optional(boolean()) + }); + const simpleItemConfigDecoder = object({ + itemId: nonEmptyStringDecoder + }); + const frameSnapshotConfigDecoder = object({ + itemId: nonEmptyStringDecoder, + excludeIds: optional(boolean()) + }); + const frameStateConfigDecoder = object({ + frameId: nonEmptyStringDecoder, + requestedState: frameStateDecoder + }); + const setItemTitleConfigDecoder = object({ + itemId: nonEmptyStringDecoder, + title: nonEmptyStringDecoder + }); + const moveWindowConfigDecoder = object({ + itemId: nonEmptyStringDecoder, + containerId: nonEmptyStringDecoder + }); + const resizeItemConfigDecoder = intersection(simpleItemConfigDecoder, resizeConfigDecoder); + const setMaximizationBoundaryConfigDecoder = object({ + itemId: nonEmptyStringDecoder, + enabled: boolean() + }); + const moveFrameConfigDecoder = intersection(simpleItemConfigDecoder, moveConfigDecoder); + object({ + id: nonEmptyStringDecoder, + type: subParentDecoder + }); + const addWindowConfigDecoder = object({ + definition: swimlaneWindowDefinitionDecoder, + parentId: nonEmptyStringDecoder, + parentType: allParentDecoder + }); + const addContainerConfigDecoder = object({ + definition: strictParentDefinitionDecoder, + parentId: nonEmptyStringDecoder, + parentType: allParentDecoder + }); + const addItemResultDecoder = object({ + itemId: nonEmptyStringDecoder, + windowId: optional(nonEmptyStringDecoder) + }); + const pingResultDecoder = object({ + live: boolean() + }); + const bundleWorkspaceConfigDecoder = object({ + type: oneOf(constant("row"), constant("column")), + workspaceId: nonEmptyStringDecoder + }); + const bundleItemConfigDecoder = object({ + type: oneOf(constant("row"), constant("column")), + itemId: nonEmptyStringDecoder + }); + const containerSummaryResultDecoder = object({ + itemId: nonEmptyStringDecoder, + config: parentSnapshotConfigDecoder + }); + const frameStreamDataDecoder = object({ + frameSummary: frameSummaryDecoder, + frameBounds: optional(frameBoundsDecoder) + }); + const workspaceStreamDataDecoder = object({ + workspaceSummary: workspaceSummaryResultDecoder, + frameSummary: frameSummaryDecoder, + workspaceSnapshot: optional(workspaceSnapshotResultDecoder), + frameBounds: optional(frameBoundsDecoder) + }); + const containerStreamDataDecoder = object({ + containerSummary: containerSummaryResultDecoder + }); + const windowStreamDataDecoder = object({ + windowSummary: object({ + itemId: nonEmptyStringDecoder, + parentId: nonEmptyStringDecoder, + config: swimlaneWindowSnapshotConfigDecoder + }) + }); + const workspaceLayoutSaveConfigDecoder = object({ + name: nonEmptyStringDecoder, + workspaceId: nonEmptyStringDecoder, + saveContext: optional(boolean()), + allowMultiple: optional(boolean()), + metadata: optional(object()) + }); + const workspaceLockConfigDecoder = object({ + allowDrop: optional(boolean()), + allowDropLeft: optional(boolean()), + allowDropTop: optional(boolean()), + allowDropRight: optional(boolean()), + allowDropBottom: optional(boolean()), + allowSystemHibernation: optional(boolean()), + allowExtract: optional(boolean()), + allowWindowReorder: optional(boolean()), + allowSplitters: optional(boolean()), + showCloseButton: optional(boolean()), + showSaveButton: optional(boolean()), + allowWorkspaceTabReorder: optional(boolean()), + allowWorkspaceTabExtract: optional(boolean()), + showWindowCloseButtons: optional(boolean()), + showAddWindowButtons: optional(boolean()), + showEjectButtons: optional(boolean()), + }); + const lockWorkspaceDecoder = object({ + workspaceId: nonEmptyStringDecoder, + config: optional(workspaceLockConfigDecoder) + }); + const windowLockConfigDecoder = object({ + allowExtract: optional(boolean()), + allowReorder: optional(boolean()), + showCloseButton: optional(boolean()) + }); + const elementResizeConfigDecoder = object({ + width: optional(nonNegativeNumberDecoder), + height: optional(nonNegativeNumberDecoder) + }); + const lockWindowDecoder = object({ + windowPlacementId: nonEmptyStringDecoder, + config: optional(windowLockConfigDecoder) + }); + const rowLockConfigDecoder = object({ + allowDrop: optional(boolean()), + allowSplitters: optional(boolean()), + }); + const columnLockConfigDecoder = object({ + allowDrop: optional(boolean()), + allowSplitters: optional(boolean()), + }); + const groupLockConfigDecoder = object({ + allowExtract: optional(boolean()), + allowReorder: optional(boolean()), + allowDrop: optional(boolean()), + allowDropLeft: optional(boolean()), + allowDropRight: optional(boolean()), + allowDropTop: optional(boolean()), + allowDropBottom: optional(boolean()), + allowDropHeader: optional(boolean()), + showMaximizeButton: optional(boolean()), + showEjectButton: optional(boolean()), + showAddWindowButton: optional(boolean()), + }); + const lockRowDecoder = object({ + itemId: nonEmptyStringDecoder, + type: constant("row"), + config: optional(rowLockConfigDecoder) + }); + const lockColumnDecoder = object({ + itemId: nonEmptyStringDecoder, + type: constant("column"), + config: optional(columnLockConfigDecoder) + }); + const lockGroupDecoder = object({ + itemId: nonEmptyStringDecoder, + type: constant("group"), + config: optional(groupLockConfigDecoder) + }); + const lockContainerDecoder = oneOf(lockRowDecoder, lockColumnDecoder, lockGroupDecoder); + const pinWorkspaceDecoder = object({ + workspaceId: nonEmptyStringDecoder, + icon: optional(nonEmptyStringDecoder) + }); + const setWorkspaceIconDecoder = object({ + workspaceId: nonEmptyStringDecoder, + icon: optional(nonEmptyStringDecoder) + }); + const workspacePinOptionsDecoder = optional(object({ + icon: optional(nonEmptyStringDecoder) + })); + const shortcutConfigDecoder = object({ + shortcut: nonEmptyStringDecoder, + frameId: nonEmptyStringDecoder + }); + const shortcutClickedDataDecoder = object({ + shortcut: nonEmptyStringDecoder, + frameId: nonEmptyStringDecoder + }); + const setMaximizationBoundaryAPIConfigDecoder = object({ + enabled: boolean() + }); + const loadingAnimationConfigDecoder = object({ + itemId: nonEmptyStringDecoder, + type: loadingAnimationTypeDecoder + }); + const operationCheckConfigDecoder = object({ + operation: nonEmptyStringDecoder + }); + const setWindowDragModeDecoder = object({ + itemId: nonEmptyStringDecoder, + dragMode: windowDragModeDecoder + }); + const setLoadingStrategyDecoder = object({ + itemId: nonEmptyStringDecoder, + strategy: loadingStrategyDecoder + }); + + const webPlatformMethodName = "T42.Web.Platform.Control"; + const webPlatformWspStreamName = "T42.Web.Platform.WSP.Stream"; + const OUTGOING_METHODS = { + control: { name: "T42.Workspaces.Control", isStream: false }, + frameStream: { name: "T42.Workspaces.Stream.Frame", isStream: true }, + workspaceStream: { name: "T42.Workspaces.Stream.Workspace", isStream: true }, + containerStream: { name: "T42.Workspaces.Stream.Container", isStream: true }, + windowStream: { name: "T42.Workspaces.Stream.Window", isStream: true } + }; + const INCOMING_METHODS = { + control: { name: "T42.Workspaces.Client.Control", isStream: false }, + }; + const STREAMS = { + frame: { name: "T42.Workspaces.Stream.Frame", payloadDecoder: frameStreamDataDecoder }, + workspace: { name: "T42.Workspaces.Stream.Workspace", payloadDecoder: workspaceStreamDataDecoder }, + container: { name: "T42.Workspaces.Stream.Container", payloadDecoder: containerStreamDataDecoder }, + window: { name: "T42.Workspaces.Stream.Window", payloadDecoder: windowStreamDataDecoder } + }; + const CLIENT_OPERATIONS = { + shortcutClicked: { name: "shortcutClicked", argsDecoder: shortcutClickedDataDecoder, resultDecoder: voidResultDecoder }, + }; + const OPERATIONS = { + ping: { name: "ping", resultDecoder: pingResultDecoder }, + isWindowInWorkspace: { name: "isWindowInWorkspace", argsDecoder: simpleItemConfigDecoder, resultDecoder: isWindowInSwimlaneResultDecoder }, + createWorkspace: { name: "createWorkspace", resultDecoder: workspaceSnapshotResultDecoder, argsDecoder: workspaceCreateConfigDecoder }, + createFrame: { name: "createFrame", resultDecoder: frameSummaryResultDecoder, argsDecoder: emptyFrameDefinitionDecoder }, + initFrame: { name: "initFrame", resultDecoder: voidResultDecoder, argsDecoder: frameInitProtocolConfigDecoder }, + getAllFramesSummaries: { name: "getAllFramesSummaries", resultDecoder: frameSummariesResultDecoder }, + getFrameSummary: { name: "getFrameSummary", resultDecoder: frameSummaryDecoder, argsDecoder: getFrameSummaryConfigDecoder }, + getAllWorkspacesSummaries: { name: "getAllWorkspacesSummaries", resultDecoder: workspaceSummariesResultDecoder }, + getWorkspaceSnapshot: { name: "getWorkspaceSnapshot", resultDecoder: workspaceSnapshotResultDecoder, argsDecoder: simpleItemConfigDecoder }, + getAllLayoutsSummaries: { name: "getAllLayoutsSummaries", resultDecoder: layoutSummariesDecoder }, + openWorkspace: { name: "openWorkspace", argsDecoder: openWorkspaceConfigDecoder, resultDecoder: workspaceSnapshotResultDecoder }, + deleteLayout: { name: "deleteLayout", resultDecoder: voidResultDecoder, argsDecoder: deleteLayoutConfigDecoder }, + saveLayout: { name: "saveLayout", resultDecoder: workspaceLayoutDecoder, argsDecoder: workspaceLayoutSaveConfigDecoder }, + importLayout: { name: "importLayout", resultDecoder: voidResultDecoder, argsDecoder: workspacesImportLayoutDecoder }, + importLayouts: { name: "importLayouts", resultDecoder: voidResultDecoder, argsDecoder: workspacesImportLayoutsDecoder }, + exportAllLayouts: { name: "exportAllLayouts", resultDecoder: exportedLayoutsResultDecoder }, + restoreItem: { name: "restoreItem", argsDecoder: simpleItemConfigDecoder, resultDecoder: voidResultDecoder }, + maximizeItem: { name: "maximizeItem", argsDecoder: simpleItemConfigDecoder, resultDecoder: voidResultDecoder }, + focusItem: { name: "focusItem", argsDecoder: simpleItemConfigDecoder, resultDecoder: voidResultDecoder }, + closeItem: { name: "closeItem", argsDecoder: simpleItemConfigDecoder, resultDecoder: voidResultDecoder }, + resizeItem: { name: "resizeItem", argsDecoder: resizeItemConfigDecoder, resultDecoder: voidResultDecoder }, + setMaximizationBoundary: { name: "setMaximizationBoundary", argsDecoder: setMaximizationBoundaryConfigDecoder, resultDecoder: voidResultDecoder }, + changeFrameState: { name: "changeFrameState", argsDecoder: frameStateConfigDecoder, resultDecoder: voidResultDecoder }, + getFrameState: { name: "getFrameState", argsDecoder: simpleItemConfigDecoder, resultDecoder: frameStateResultDecoder }, + getFrameBounds: { name: "getFrameBounds", argsDecoder: simpleItemConfigDecoder, resultDecoder: frameBoundsResultDecoder }, + moveFrame: { name: "moveFrame", argsDecoder: moveFrameConfigDecoder, resultDecoder: voidResultDecoder }, + getFrameSnapshot: { name: "getFrameSnapshot", argsDecoder: frameSnapshotConfigDecoder, resultDecoder: frameSnapshotResultDecoder }, + forceLoadWindow: { name: "forceLoadWindow", argsDecoder: simpleItemConfigDecoder, resultDecoder: simpleWindowOperationSuccessResultDecoder }, + ejectWindow: { name: "ejectWindow", argsDecoder: simpleItemConfigDecoder, resultDecoder: simpleWindowOperationSuccessResultDecoder }, + setItemTitle: { name: "setItemTitle", argsDecoder: setItemTitleConfigDecoder, resultDecoder: voidResultDecoder }, + moveWindowTo: { name: "moveWindowTo", argsDecoder: moveWindowConfigDecoder, resultDecoder: voidResultDecoder }, + addWindow: { name: "addWindow", argsDecoder: addWindowConfigDecoder, resultDecoder: addItemResultDecoder }, + addContainer: { name: "addContainer", argsDecoder: addContainerConfigDecoder, resultDecoder: addItemResultDecoder }, + bundleWorkspace: { name: "bundleWorkspace", argsDecoder: bundleWorkspaceConfigDecoder, resultDecoder: voidResultDecoder }, + bundleItem: { name: "bundleItem", argsDecoder: bundleItemConfigDecoder, resultDecoder: voidResultDecoder }, + hibernateWorkspace: { name: "hibernateWorkspace", argsDecoder: workspaceSelectorDecoder, resultDecoder: voidResultDecoder }, + resumeWorkspace: { name: "resumeWorkspace", argsDecoder: workspaceSelectorDecoder, resultDecoder: voidResultDecoder }, + lockWorkspace: { name: "lockWorkspace", argsDecoder: lockWorkspaceDecoder, resultDecoder: voidResultDecoder }, + lockWindow: { name: "lockWindow", argsDecoder: lockWindowDecoder, resultDecoder: voidResultDecoder }, + lockContainer: { name: "lockContainer", argsDecoder: lockContainerDecoder, resultDecoder: voidResultDecoder }, + pinWorkspace: { name: "pinWorkspace", argsDecoder: pinWorkspaceDecoder, resultDecoder: voidResultDecoder }, + unpinWorkspace: { name: "unpinWorkspace", argsDecoder: workspaceSelectorDecoder, resultDecoder: voidResultDecoder }, + getWorkspaceIcon: { name: "getWorkspaceIcon", argsDecoder: workspaceSelectorDecoder, resultDecoder: getWorkspaceIconResultDecoder }, + setWorkspaceIcon: { name: "setWorkspaceIcon", argsDecoder: setWorkspaceIconDecoder, resultDecoder: voidResultDecoder }, + registerShortcut: { name: "registerShortcut", argsDecoder: shortcutConfigDecoder, resultDecoder: voidResultDecoder }, + unregisterShortcut: { name: "unregisterShortcut", argsDecoder: shortcutConfigDecoder, resultDecoder: voidResultDecoder }, + showLoadingAnimation: { name: "showLoadingAnimation", argsDecoder: loadingAnimationConfigDecoder, resultDecoder: voidResultDecoder }, + hideLoadingAnimation: { name: "hideLoadingAnimation", argsDecoder: loadingAnimationConfigDecoder, resultDecoder: voidResultDecoder }, + getPlatformFrameId: { name: "getPlatformFrameId", resultDecoder: getPlatformFrameIdResultDecoder }, + operationCheck: { name: "operationCheck", argsDecoder: operationCheckConfigDecoder, resultDecoder: operationCheckResultDecoder }, + setWindowDragMode: { name: "setWindowDragMode", argsDecoder: setWindowDragModeDecoder, resultDecoder: voidResultDecoder }, + setLoadingStrategy: { name: "setLoadingStrategy", argsDecoder: setLoadingStrategyDecoder, resultDecoder: voidResultDecoder } + }; + + class PromiseWrapper { + resolve; + reject; + promise; + constructor() { + this.promise = new Promise((res, rej) => { + this.resolve = res; + this.reject = rej; + }); + } + } + + class Bridge { + transport; + registry; + activeSubscriptions = []; + pendingSubScriptions = []; + constructor(transport, registry) { + this.transport = transport; + this.registry = registry; + } + async createCoreEventSubscription() { + await this.transport.coreSubscriptionReady(this.handleCoreEvent.bind(this)); + } + handleCoreSubscription(config) { + const registryKey = `${config.eventType}-${config.action}`; + const scope = config.scope; + const scopeId = config.scopeId; + return this.registry.add(registryKey, (args) => { + const scopeConfig = { + type: scope, + id: scopeId + }; + const receivedIds = { + frame: args.frameSummary?.id || args.windowSummary?.config.frameId, + workspace: args.workspaceSummary?.id || args.windowSummary?.config.workspaceId, + container: args.containerSummary?.itemId, + window: args.windowSummary?.itemId + }; + const shouldInvokeCallback = this.checkScopeMatch(scopeConfig, receivedIds); + if (!shouldInvokeCallback) { + return; + } + config.callback(args); + }); + } + async send(operationName, operationArgs) { + const operationDefinition = Object.values(OPERATIONS).find((operation) => operation.name === operationName); + if (!operationDefinition) { + throw new Error(`Cannot find definition for operation name: ${operationName}`); + } + if (operationDefinition.argsDecoder) { + try { + operationDefinition.argsDecoder.runWithException(operationArgs); + } + catch (error) { + throw new Error(`Unexpected internal outgoing validation error: ${error.message}, for input: ${JSON.stringify(error.input)}, for operation ${operationName}`); + } + } + try { + const operationResult = await this.transport.transmitControl(operationDefinition.name, operationArgs); + operationDefinition.resultDecoder.runWithException(operationResult); + return operationResult; + } + catch (error) { + if (error.kind) { + throw new Error(`Unexpected internal incoming validation error: ${error.message}, for input: ${JSON.stringify(error.input)}, for operation ${operationName}`); + } + throw new Error(error.message); + } + } + async subscribe(config) { + const pendingSub = this.getPendingSubscription(config); + if (pendingSub) { + await pendingSub.promise; + } + let activeSub = this.getActiveSubscription(config); + const registryKey = this.getRegistryKey(config); + if (!activeSub) { + const pendingPromise = new PromiseWrapper(); + const pendingSubscription = { + streamType: config.eventType, + level: config.scope, + levelId: config.scopeId, + promise: pendingPromise.promise + }; + this.pendingSubScriptions.push(pendingSubscription); + try { + const stream = STREAMS[config.eventType]; + const gdSub = await this.transport.subscribe(stream.name, this.getBranchKey(config), config.eventType); + gdSub.onData((streamData) => { + const data = streamData.data; + const requestedArgumentsResult = streamRequestArgumentsDecoder.run(streamData.requestArguments); + const actionResult = workspaceEventActionDecoder.run(data.action); + if (!requestedArgumentsResult.ok || !actionResult.ok) { + return; + } + const streamType = requestedArgumentsResult.result.type; + const branch = requestedArgumentsResult.result.branch; + const keyToExecute = `${streamType}-${branch}-${actionResult.result}`; + const validatedPayload = STREAMS[streamType].payloadDecoder.run(data.payload); + if (!validatedPayload.ok) { + return; + } + this.registry.execute(keyToExecute, validatedPayload.result); + }); + activeSub = { + streamType: config.eventType, + level: config.scope, + levelId: config.scopeId, + callbacksCount: 0, + gdSub + }; + this.activeSubscriptions.push(activeSub); + pendingPromise.resolve(); + } + catch (error) { + pendingPromise.reject(error); + throw error; + } + finally { + this.removePendingSubscription(pendingSubscription); + } + } + const unsubscribe = this.registry.add(registryKey, config.callback); + ++activeSub.callbacksCount; + return () => { + unsubscribe(); + --activeSub.callbacksCount; + if (activeSub.callbacksCount === 0) { + activeSub.gdSub.close(); + this.activeSubscriptions.splice(this.activeSubscriptions.indexOf(activeSub), 1); + } + }; + } + onOperation(callback) { + const wrappedCallback = (payload, caller) => { + const operationName = payload.operation; + const operationArgs = payload.data; + const operationDefinition = Object.values(CLIENT_OPERATIONS).find((operation) => operation.name === operationName); + if (!operationDefinition) { + throw new Error(`Cannot find definition for operation name: ${operationName}`); + } + if (operationDefinition.argsDecoder) { + try { + operationDefinition.argsDecoder.runWithException(operationArgs); + } + catch (error) { + throw new Error(`Unexpected internal outgoing validation error: ${error.message}, for input: ${JSON.stringify(error.input)}, for operation ${operationName}`); + } + } + callback(payload, caller); + }; + return this.transport.onInternalMethodInvoked("control", wrappedCallback); + } + checkScopeMatch(scope, receivedIds) { + if (scope.type === "global") { + return true; + } + if (scope.type === "frame" && scope.id === receivedIds.frame) { + return true; + } + if (scope.type === "workspace" && scope.id === receivedIds.workspace) { + return true; + } + if (scope.type === "container" && scope.id === receivedIds.container) { + return true; + } + if (scope.type === "window" && scope.id === receivedIds.window) { + return true; + } + return false; + } + handleCoreEvent(args) { + const data = args.data; + try { + const verifiedAction = workspaceEventActionDecoder.runWithException(data.action); + const verifiedType = eventTypeDecoder.runWithException(data.type); + const verifiedPayload = STREAMS[verifiedType].payloadDecoder.runWithException(data.payload); + const registryKey = `${verifiedType}-${verifiedAction}`; + this.registry.execute(registryKey, verifiedPayload); + } + catch (error) { + console.warn(`Cannot handle event with data ${JSON.stringify(data)}, because of validation error: ${error.message}`); + } + } + getBranchKey(config) { + return config.scope === "global" ? config.scope : `${config.scope}_${config.scopeId}`; + } + getRegistryKey(config) { + return `${config.eventType}-${this.getBranchKey(config)}-${config.action}`; + } + getActiveSubscription(config) { + return this.activeSubscriptions + .find((activeSub) => activeSub.streamType === config.eventType && + activeSub.level === config.scope && + activeSub.levelId === config.scopeId); + } + getPendingSubscription(config) { + return this.pendingSubScriptions + .find((activeSub) => activeSub.streamType === config.eventType && + activeSub.level === config.scope && + activeSub.levelId === config.scopeId); + } + removePendingSubscription(pendingSubscription) { + const index = this.pendingSubScriptions.indexOf(pendingSubscription); + if (index >= 0) { + this.pendingSubScriptions.splice(index, 1); + } + } + } + + const promisePlus = (promise, timeoutMilliseconds, timeoutMessage) => { + return new Promise((resolve, reject) => { + let promiseActive = true; + const timeout = setTimeout(() => { + if (!promiseActive) { + return; + } + promiseActive = false; + const message = timeoutMessage; + reject(message); + }, timeoutMilliseconds); + promise() + .then((result) => { + if (!promiseActive) { + return; + } + promiseActive = false; + clearTimeout(timeout); + resolve(result); + }) + .catch((error) => { + if (!promiseActive) { + return; + } + promiseActive = false; + clearTimeout(timeout); + reject(error); + }); + }); + }; + + const isDesktop = () => { + return typeof window === "undefined" ? + true : + window.glue42gd || window.iodesktop; + }; + const browserGlobal = () => { + return typeof window === "undefined" ? null : + window.glue42core || window.iobrowser; + }; + + class InteropTransport { + agm; + registry; + defaultTransportTimeout = 120000; + coreEventMethodInitiated = false; + corePlatformSubPromise; + constructor(agm, registry) { + this.agm = agm; + this.registry = registry; + } + async initiate(actualWindowId) { + if (isDesktop()) { + await Promise.all(Object.values(OUTGOING_METHODS).map((method) => { + return this.verifyMethodLive(method.name); + })); + await Promise.all(Object.keys(INCOMING_METHODS).map((method) => { + return this.registerMethod(method); + })); + return; + } + const systemId = browserGlobal().communicationId; + await Promise.all([ + this.verifyMethodLive(webPlatformMethodName, systemId), + this.verifyMethodLive(webPlatformWspStreamName, systemId) + ]); + await this.transmitControl("frameHello", { windowId: actualWindowId }); + } + coreSubscriptionReady(eventCallback) { + if (!this.coreEventMethodInitiated) { + this.subscribePlatform(eventCallback); + } + return this.corePlatformSubPromise; + } + subscribePlatform(eventCallback) { + this.coreEventMethodInitiated = true; + const systemId = browserGlobal().communicationId; + this.corePlatformSubPromise = this.agm.subscribe(webPlatformWspStreamName, systemId ? { target: { instance: systemId } } : undefined); + this.corePlatformSubPromise + .then((sub) => { + sub.onData((data) => eventCallback(data.data)); + }); + } + async subscribe(streamName, streamBranch, streamType) { + const subscriptionArgs = { + branch: streamBranch, + type: streamType + }; + let subscription; + try { + subscription = await this.agm.subscribe(streamName, { arguments: subscriptionArgs }); + } + catch (error) { + const message = `Internal subscription error! Error details: stream - ${streamName}, branch: ${streamBranch}. Internal message: ${error.message}`; + throw new Error(message); + } + return subscription; + } + async transmitControl(operation, operationArguments) { + const invocationArguments = isDesktop() ? { operation, operationArguments } : { operation, domain: "workspaces", data: operationArguments }; + const methodName = isDesktop() ? OUTGOING_METHODS.control.name : webPlatformMethodName; + const platformTarget = isDesktop() ? undefined : browserGlobal().communicationId; + let invocationResult; + const baseErrorMessage = `Internal Workspaces Communication Error. Attempted operation: ${JSON.stringify(invocationArguments)}. `; + try { + invocationResult = await this.agm.invoke(methodName, invocationArguments, platformTarget ? { instance: platformTarget } : "best", { methodResponseTimeoutMs: this.defaultTransportTimeout }); + if (!invocationResult) { + throw new Error("Received unsupported result from GD - empty result"); + } + if (!Array.isArray(invocationResult.all_return_values) || invocationResult.all_return_values.length === 0) { + throw new Error("Received unsupported result from GD - empty values collection"); + } + } + catch (error) { + if (error && error.all_errors && error.all_errors.length) { + const invocationErrorMessage = error.all_errors[0].message; + throw new Error(`${baseErrorMessage} -> Inner message: ${invocationErrorMessage}`); + } + throw new Error(`${baseErrorMessage} -> Inner message: ${error.message}`); + } + return invocationResult.all_return_values[0].returned; + } + onInternalMethodInvoked(key, callback) { + return this.registry.add(key, callback); + } + verifyMethodLive(name, systemId) { + return promisePlus(() => { + return new Promise((resolve) => { + const hasMethod = this.agm.methods().some((method) => { + const nameMatch = method.name === name; + const serverMatch = systemId ? + method.getServers().some((server) => server.instance === systemId) : + true; + return nameMatch && serverMatch; + }); + if (hasMethod) { + resolve(); + return; + } + const unSub = this.agm.serverMethodAdded((data) => { + const method = data.method; + const server = data.server; + const serverMatch = systemId ? + server.instance === systemId : + true; + if (method.name === name && serverMatch) { + unSub(); + resolve(); + } + }); + }); + }, 15000, "Timeout waiting for the Workspaces communication channels"); + } + registerMethod(key) { + const method = INCOMING_METHODS[key]; + return this.agm.register(method.name, (args, caller) => { + this.registry.execute(key, args, caller); + }); + } + } + + const privateData$4 = new WeakMap(); + class ParentBuilder { + constructor(definition, base) { + const children = base.wrapChildren(definition.children); + delete definition.children; + privateData$4.set(this, { base, children, definition }); + } + get type() { + return privateData$4.get(this).definition.type; + } + addColumn(definition) { + const base = privateData$4.get(this).base; + return base.add("column", privateData$4.get(this).children, definition); + } + addRow(definition) { + const base = privateData$4.get(this).base; + return base.add("row", privateData$4.get(this).children, definition); + } + addGroup(definition) { + const base = privateData$4.get(this).base; + return base.add("group", privateData$4.get(this).children, definition); + } + addWindow(definition) { + const base = privateData$4.get(this).base; + base.addWindow(privateData$4.get(this).children, definition); + return this; + } + serialize() { + const definition = privateData$4.get(this).definition; + definition.children = privateData$4.get(this).base.serializeChildren(privateData$4.get(this).children); + return definition; + } + } + + class BaseBuilder { + getBuilder; + constructor(getBuilder) { + this.getBuilder = getBuilder; + } + wrapChildren(children) { + return children.map((child) => { + if (child.type === "window") { + return child; + } + return this.getBuilder({ type: child.type, definition: child }); + }); + } + add(type, children, definition) { + const validatedDefinition = parentDefinitionDecoder.runWithException(definition); + const childBuilder = this.getBuilder({ type, definition: validatedDefinition }); + children.push(childBuilder); + return childBuilder; + } + addWindow(children, definition) { + const validatedDefinition = swimlaneWindowDefinitionDecoder.runWithException(definition); + validatedDefinition.type = "window"; + children.push(validatedDefinition); + } + serializeChildren(children) { + return children.map((child) => { + if (child instanceof ParentBuilder) { + return child.serialize(); + } + else { + return child; + } + }); + } + } + + const privateData$3 = new WeakMap(); + class WorkspaceBuilder { + constructor(definition, base, controller) { + const children = base.wrapChildren(definition.children); + delete definition.children; + privateData$3.set(this, { base, children, definition, controller }); + } + addColumn(definition) { + const children = privateData$3.get(this).children; + const areAllColumns = children.every((child) => child instanceof ParentBuilder && child.type === "column"); + if (!areAllColumns) { + throw new Error("Cannot add a column to this workspace, because there are already children of another type"); + } + const base = privateData$3.get(this).base; + return base.add("column", children, definition); + } + addRow(definition) { + const children = privateData$3.get(this).children; + const areAllRows = children.every((child) => child instanceof ParentBuilder && child.type === "row"); + if (!areAllRows) { + throw new Error("Cannot add a row to this workspace, because there are already children of another type"); + } + const base = privateData$3.get(this).base; + return base.add("row", children, definition); + } + addGroup(definition) { + const children = privateData$3.get(this).children; + if (children.length !== 0) { + throw new Error("Cannot add a group to this workspace, because there are already defined children."); + } + const base = privateData$3.get(this).base; + return base.add("group", children, definition); + } + addWindow(definition) { + const children = privateData$3.get(this).children; + if (children.length !== 0) { + throw new Error("Cannot add a window to this workspace, because there are already defined children."); + } + const base = privateData$3.get(this).base; + base.addWindow(children, definition); + return this; + } + getChildAt(index) { + nonNegativeNumberDecoder.runWithException(index); + const data = privateData$3.get(this).children; + return data[index]; + } + async create(config) { + const saveConfig = workspaceBuilderCreateConfigDecoder.runWithException(config); + const definition = privateData$3.get(this).definition; + definition.children = privateData$3.get(this).base.serializeChildren(privateData$3.get(this).children); + const controller = privateData$3.get(this).controller; + return controller.createWorkspace(definition, saveConfig); + } + } + + const privateData$2 = new WeakMap(); + const getBase$2 = (model) => { + return privateData$2.get(model).base; + }; + class Row { + constructor(base) { + privateData$2.set(this, { base }); + } + get type() { + return "row"; + } + get id() { + return getBase$2(this).getId(this); + } + get frameId() { + return getBase$2(this).getFrameId(this); + } + get workspaceId() { + return getBase$2(this).getWorkspaceId(this); + } + get positionIndex() { + return getBase$2(this).getPositionIndex(this); + } + get children() { + return getBase$2(this).getAllChildren(this); + } + get parent() { + return getBase$2(this).getMyParent(this); + } + get frame() { + return getBase$2(this).getMyFrame(this); + } + get workspace() { + return getBase$2(this).getMyWorkspace(this); + } + get allowDrop() { + return getBase$2(this).getAllowDrop(this); + } + get allowSplitters() { + return getBase$2(this).getAllowSplitters(this); + } + get minWidth() { + return getBase$2(this).getMinWidth(this); + } + get minHeight() { + return getBase$2(this).getMinHeight(this); + } + get maxWidth() { + return getBase$2(this).getMaxWidth(this); + } + get maxHeight() { + return getBase$2(this).getMaxHeight(this); + } + get width() { + return getBase$2(this).getWidthInPx(this); + } + get height() { + return getBase$2(this).getHeightInPx(this); + } + get isPinned() { + return getBase$2(this).getIsPinned(this); + } + get isMaximized() { + return getBase$2(this).getIsMaximized(this); + } + get maximizationBoundary() { + return getBase$2(this).getMaximizationBoundary(this); + } + addWindow(definition) { + return getBase$2(this).addWindow(this, definition, "row"); + } + async addGroup(definition) { + if (definition?.type && definition.type !== "group") { + throw new Error(`Expected a group definition, but received ${definition.type}`); + } + return getBase$2(this).addParent(this, "group", "row", definition); + } + async addColumn(definition) { + if (definition?.type && definition.type !== "column") { + throw new Error(`Expected a column definition, but received ${definition.type}`); + } + return getBase$2(this).addParent(this, "column", "row", definition); + } + async addRow() { + throw new Error("Adding rows as row children is not supported"); + } + removeChild(predicate) { + return getBase$2(this).removeChild(this, predicate); + } + maximize() { + return getBase$2(this).maximize(this); + } + restore() { + return getBase$2(this).restore(this); + } + close() { + return getBase$2(this).close(this); + } + lock(config) { + let lockConfigResult = undefined; + if (typeof config === "function") { + const currentLockConfig = { + allowDrop: this.allowDrop, + allowSplitters: this.allowSplitters + }; + lockConfigResult = config(currentLockConfig); + } + else { + lockConfigResult = config; + } + const verifiedConfig = lockConfigResult === undefined ? undefined : rowLockConfigDecoder.runWithException(lockConfigResult); + return getBase$2(this).lockContainer(this, verifiedConfig); + } + async setHeight(height) { + nonNegativeNumberDecoder.runWithException(height); + return getBase$2(this).setHeight(this, height); + } + async onLockConfigurationChanged(callback) { + checkThrowCallback(callback); + const wrappedCallback = async () => { + await this.workspace.refreshReference(); + callback({ + allowDrop: this.allowDrop, + allowSplitters: this.allowSplitters + }); + }; + const config = { + callback: wrappedCallback, + action: "lock-configuration-changed", + eventType: "container", + scope: "container" + }; + const unsubscribe = await getBase$2(this).processLocalSubscription(this, config); + return unsubscribe; + } + async setMaximizationBoundary(config) { + const validatedConfig = setMaximizationBoundaryAPIConfigDecoder.runWithException(config); + return getBase$2(this).setMaximizationBoundary(this, validatedConfig); + } + } + + const privateData$1 = new WeakMap(); + const getBase$1 = (model) => { + return privateData$1.get(model).base; + }; + class Column { + constructor(base) { + privateData$1.set(this, { base }); + } + get type() { + return "column"; + } + get id() { + return getBase$1(this).getId(this); + } + get frameId() { + return getBase$1(this).getFrameId(this); + } + get workspaceId() { + return getBase$1(this).getWorkspaceId(this); + } + get positionIndex() { + return getBase$1(this).getPositionIndex(this); + } + get children() { + return getBase$1(this).getAllChildren(this); + } + get parent() { + return getBase$1(this).getMyParent(this); + } + get frame() { + return getBase$1(this).getMyFrame(this); + } + get workspace() { + return getBase$1(this).getMyWorkspace(this); + } + get allowDrop() { + return getBase$1(this).getAllowDrop(this); + } + get allowSplitters() { + return getBase$1(this).getAllowSplitters(this); + } + get minWidth() { + return getBase$1(this).getMinWidth(this); + } + get minHeight() { + return getBase$1(this).getMinHeight(this); + } + get maxWidth() { + return getBase$1(this).getMaxWidth(this); + } + get maxHeight() { + return getBase$1(this).getMaxHeight(this); + } + get width() { + return getBase$1(this).getWidthInPx(this); + } + get height() { + return getBase$1(this).getHeightInPx(this); + } + get isPinned() { + return getBase$1(this).getIsPinned(this); + } + get isMaximized() { + return getBase$1(this).getIsMaximized(this); + } + get maximizationBoundary() { + return getBase$1(this).getMaximizationBoundary(this); + } + addWindow(definition) { + return getBase$1(this).addWindow(this, definition, "column"); + } + async addGroup(definition) { + if (definition?.type && definition.type !== "group") { + throw new Error(`Expected a group definition, but received ${definition.type}`); + } + return getBase$1(this).addParent(this, "group", "column", definition); + } + async addColumn() { + throw new Error("Adding columns as column children is not supported"); + } + async addRow(definition) { + if (definition?.type && definition.type !== "row") { + throw new Error(`Expected a row definition, but received ${definition.type}`); + } + return getBase$1(this).addParent(this, "row", "column", definition); + } + removeChild(predicate) { + return getBase$1(this).removeChild(this, predicate); + } + maximize() { + return getBase$1(this).maximize(this); + } + restore() { + return getBase$1(this).restore(this); + } + close() { + return getBase$1(this).close(this); + } + lock(config) { + let lockConfigResult = undefined; + if (typeof config === "function") { + const currentLockConfig = { + allowDrop: this.allowDrop, + allowSplitters: this.allowSplitters + }; + lockConfigResult = config(currentLockConfig); + } + else { + lockConfigResult = config; + } + const verifiedConfig = lockConfigResult === undefined ? undefined : columnLockConfigDecoder.runWithException(lockConfigResult); + return getBase$1(this).lockContainer(this, verifiedConfig); + } + async setWidth(width) { + nonNegativeNumberDecoder.runWithException(width); + return getBase$1(this).setWidth(this, width); + } + async onLockConfigurationChanged(callback) { + checkThrowCallback(callback); + const wrappedCallback = async () => { + await this.workspace.refreshReference(); + callback({ + allowDrop: this.allowDrop, + allowSplitters: this.allowSplitters + }); + }; + const config = { + callback: wrappedCallback, + action: "lock-configuration-changed", + eventType: "container", + scope: "container" + }; + const unsubscribe = await getBase$1(this).processLocalSubscription(this, config); + return unsubscribe; + } + async setMaximizationBoundary(config) { + const validatedConfig = setMaximizationBoundaryAPIConfigDecoder.runWithException(config); + return getBase$1(this).setMaximizationBoundary(this, validatedConfig); + } + } + + const privateData = new WeakMap(); + const getBase = (model) => { + return privateData.get(model).base; + }; + class Group { + constructor(base) { + privateData.set(this, { base }); + } + get type() { + return "group"; + } + get id() { + return getBase(this).getId(this); + } + get frameId() { + return getBase(this).getFrameId(this); + } + get workspaceId() { + return getBase(this).getWorkspaceId(this); + } + get positionIndex() { + return getBase(this).getPositionIndex(this); + } + get children() { + return getBase(this).getAllChildren(this); + } + get parent() { + return getBase(this).getMyParent(this); + } + get frame() { + return getBase(this).getMyFrame(this); + } + get workspace() { + return getBase(this).getMyWorkspace(this); + } + get allowExtract() { + return getBase(this).getAllowExtract(this); + } + get allowReorder() { + return getBase(this).getAllowReorder(this); + } + get allowDropLeft() { + return getBase(this).getAllowDropLeft(this); + } + get allowDropRight() { + return getBase(this).getAllowDropRight(this); + } + get allowDropTop() { + return getBase(this).getAllowDropTop(this); + } + get allowDropBottom() { + return getBase(this).getAllowDropBottom(this); + } + get allowDropHeader() { + return getBase(this).getAllowDropHeader(this); + } + get allowDrop() { + return getBase(this).getAllowDrop(this); + } + get showMaximizeButton() { + return getBase(this).getShowMaximizeButton(this); + } + get showEjectButton() { + return getBase(this).getShowEjectButton(this); + } + get showAddWindowButton() { + return getBase(this).getShowAddWindowButton(this); + } + get minWidth() { + return getBase(this).getMinWidth(this); + } + get minHeight() { + return getBase(this).getMinHeight(this); + } + get maxWidth() { + return getBase(this).getMaxWidth(this); + } + get maxHeight() { + return getBase(this).getMaxHeight(this); + } + get width() { + return getBase(this).getWidthInPx(this); + } + get height() { + return getBase(this).getHeightInPx(this); + } + get isMaximized() { + return getBase(this).getIsMaximized(this); + } + addWindow(definition) { + return getBase(this).addWindow(this, definition, "group"); + } + async addGroup() { + throw new Error("Adding groups as group child is not supported"); + } + async addColumn() { + throw new Error("Adding columns as group child is not supported"); + } + async addRow() { + throw new Error("Adding rows as group child is not supported"); + } + removeChild(predicate) { + return getBase(this).removeChild(this, predicate); + } + maximize() { + return getBase(this).maximize(this); + } + restore() { + return getBase(this).restore(this); + } + close() { + return getBase(this).close(this); + } + lock(config) { + let lockConfigResult = undefined; + if (typeof config === "function") { + const currentLockConfig = { + allowDrop: this.allowDrop, + allowDropHeader: this.allowDropHeader, + allowDropLeft: this.allowDropLeft, + allowDropRight: this.allowDropRight, + allowDropTop: this.allowDropTop, + allowDropBottom: this.allowDropBottom, + allowExtract: this.allowExtract, + allowReorder: this.allowReorder, + showAddWindowButton: this.showAddWindowButton, + showEjectButton: this.showEjectButton, + showMaximizeButton: this.showMaximizeButton + }; + lockConfigResult = config(currentLockConfig); + } + else { + lockConfigResult = config; + } + const verifiedConfig = lockConfigResult === undefined ? undefined : groupLockConfigDecoder.runWithException(lockConfigResult); + return getBase(this).lockContainer(this, verifiedConfig); + } + async setSize(config) { + const verifiedConfig = elementResizeConfigDecoder.runWithException(config); + if (!verifiedConfig.width && !verifiedConfig.height) { + throw new Error("Expected either width or height to be passed."); + } + return getBase(this).setSize(this, config.width, config.height); + } + async bundleToRow() { + await getBase(this).bundleTo(this, "row"); + await this.workspace.refreshReference(); + } + async bundleToColumn() { + await getBase(this).bundleTo(this, "column"); + await this.workspace.refreshReference(); + } + async onLockConfigurationChanged(callback) { + checkThrowCallback(callback); + const wrappedCallback = async () => { + await this.workspace.refreshReference(); + callback({ + allowDrop: this.allowDrop, + allowDropHeader: this.allowDropHeader, + allowDropLeft: this.allowDropLeft, + allowDropTop: this.allowDropTop, + allowDropRight: this.allowDropRight, + allowDropBottom: this.allowDropBottom, + allowExtract: this.allowExtract, + allowReorder: this.allowReorder, + showAddWindowButton: this.showAddWindowButton, + showEjectButton: this.showEjectButton, + showMaximizeButton: this.showMaximizeButton + }); + }; + const config = { + callback: wrappedCallback, + action: "lock-configuration-changed", + eventType: "container", + scope: "container" + }; + const unsubscribe = await getBase(this).processLocalSubscription(this, config); + return unsubscribe; + } + } + + const DEFAULT_WINDOW_DRAG_MODE = "keepInside"; + + const data$3 = new WeakMap(); + const getData$3 = (model) => { + return data$3.get(model).manager.getWorkspaceData(model); + }; + const getDataManager = (model) => { + return data$3.get(model).manager; + }; + class Workspace { + constructor(dataManager) { + data$3.set(this, { manager: dataManager }); + } + get id() { + return getData$3(this).id; + } + get frameId() { + return getData$3(this).config.frameId; + } + get positionIndex() { + return getData$3(this).config.positionIndex; + } + get title() { + return getData$3(this).config.title; + } + get layoutName() { + return getData$3(this).config.layoutName; + } + get isHibernated() { + return getData$3(this).config.isHibernated; + } + get isSelected() { + return getData$3(this).config.isSelected; + } + get children() { + return getData$3(this).children; + } + get frame() { + return getData$3(this).frame; + } + get allowSplitters() { + return getData$3(this).config.allowSplitters; + } + get allowSystemHibernation() { + return getData$3(this).config.allowSystemHibernation; + } + get allowDrop() { + return getData$3(this).config.allowDrop; + } + get allowDropLeft() { + return getData$3(this).config.allowDropLeft; + } + get allowDropTop() { + return getData$3(this).config.allowDropTop; + } + get allowDropRight() { + return getData$3(this).config.allowDropRight; + } + get allowDropBottom() { + return getData$3(this).config.allowDropBottom; + } + get allowExtract() { + return getData$3(this).config.allowExtract; + } + get allowWindowReorder() { + return getData$3(this).config.allowWindowReorder; + } + get showCloseButton() { + return getData$3(this).config.showCloseButton; + } + get showSaveButton() { + return getData$3(this).config.showSaveButton; + } + get allowWorkspaceTabReorder() { + return getData$3(this).config.allowWorkspaceTabReorder; + } + get allowWorkspaceTabExtract() { + return getData$3(this).config.allowWorkspaceTabExtract; + } + get minWidth() { + return getData$3(this).config.minWidth; + } + get minHeight() { + return getData$3(this).config.minHeight; + } + get maxWidth() { + return getData$3(this).config.maxWidth; + } + get maxHeight() { + return getData$3(this).config.maxHeight; + } + get width() { + return getData$3(this).config.widthInPx; + } + get height() { + return getData$3(this).config.heightInPx; + } + get showWindowCloseButtons() { + return getData$3(this).config.showWindowCloseButtons; + } + get showEjectButtons() { + return getData$3(this).config.showEjectButtons; + } + get showAddWindowButtons() { + return getData$3(this).config.showAddWindowButtons; + } + get isPinned() { + return getData$3(this).config.isPinned; + } + get windowDragMode() { + const desktopGlobal = isDesktop(); + if (!desktopGlobal) { + return DEFAULT_WINDOW_DRAG_MODE; + } + return getData$3(this).config.windowDragMode; + } + get loadingStrategy() { + if (!isDesktop()) { + console.warn("The workspace.loadingStrategy property is not supported in IO Connect Browser"); + } + return getData$3(this).config.loadingStrategy; + } + async setLoadingStrategy(strategy) { + if (!isDesktop()) { + throw new Error("Not supported in IO Connect Browser"); + } + const controller = getData$3(this).controller; + await controller.setLoadingStrategy(this.id, strategy); + await this.refreshReference(); + } + async removeChild(predicate) { + checkThrowCallback(predicate); + const child = this.children.find(predicate); + if (!child) { + return; + } + await child.close(); + await this.refreshReference(); + } + async remove(predicate) { + checkThrowCallback(predicate); + const controller = getData$3(this).controller; + const child = controller.iterateFindChild(this.children, predicate); + await child.close(); + await this.refreshReference(); + } + async focus() { + await getData$3(this).controller.focusItem(this.id); + await this.refreshReference(); + } + async close() { + const controller = getData$3(this).controller; + const workspaces = await getData$3(this).frame.workspaces(); + const platformFrameId = (await controller.getPlatformFrameId()).id; + const shouldCloseFrame = workspaces.length === 1 && + workspaces.every((wsp) => wsp.id === this.id) && + platformFrameId !== this.frame.id; + if (shouldCloseFrame) { + return this.frame.close(); + } + await controller.closeItem(this.id); + } + snapshot() { + return getData$3(this).controller.getSnapshot(this.id, "workspace"); + } + async saveLayout(name, config) { + nonEmptyStringDecoder.runWithException(name); + await getData$3(this).controller.saveLayout({ name, workspaceId: this.id, saveContext: config?.saveContext, metadata: config?.metadata, allowMultiple: config?.allowMultiple }); + } + async setTitle(title) { + nonEmptyStringDecoder.runWithException(title); + const controller = getData$3(this).controller; + await controller.setItemTitle(this.id, title); + await this.refreshReference(); + } + getContext() { + const controller = getData$3(this).controller; + return controller.getWorkspaceContext(this.id); + } + setContext(data) { + const controller = getData$3(this).controller; + return controller.setWorkspaceContext(this.id, data); + } + updateContext(data) { + const controller = getData$3(this).controller; + return controller.updateWorkspaceContext(this.id, data); + } + onContextUpdated(callback) { + const controller = getData$3(this).controller; + return controller.subscribeWorkspaceContextUpdated(this.id, callback); + } + async refreshReference() { + const newSnapshot = (await getData$3(this).controller.getSnapshot(this.id, "workspace")); + const currentChildrenFlat = getData$3(this).controller.flatChildren(getData$3(this).children); + const newChildren = getData$3(this).controller.refreshChildren({ + existingChildren: currentChildrenFlat, + workspace: this, + parent: this, + children: newSnapshot.children + }); + const currentFrame = this.frame; + let actualFrame; + if (currentFrame.id === newSnapshot.config.frameId) { + getDataManager(this).remapFrame(currentFrame, newSnapshot.frameSummary); + actualFrame = currentFrame; + } + else { + const frameCreateConfig = { + summary: newSnapshot.frameSummary + }; + const newFrame = getData$3(this).ioc.getModel("frame", frameCreateConfig); + actualFrame = newFrame; + } + getDataManager(this).remapWorkspace(this, { + config: newSnapshot.config, + children: newChildren, + frame: actualFrame + }); + } + async getIcon() { + const controller = getData$3(this).controller; + return controller.getWorkspaceIcon(this.id); + } + async setIcon(icon) { + const controller = getData$3(this).controller; + return controller.setWorkspaceIcon(this.id, icon); + } + getBox(predicate) { + checkThrowCallback(predicate); + const children = getData$3(this).children; + const controller = getData$3(this).controller; + return controller.iterateFindChild(children, (child) => child.type !== "window" && predicate(child)); + } + getAllBoxes(predicate) { + checkThrowCallback(predicate, true); + const children = getData$3(this).children; + const controller = getData$3(this).controller; + const allParents = controller.iterateFilterChildren(children, (child) => child.type !== "window"); + if (!predicate) { + return allParents; + } + return allParents.filter(predicate); + } + getRow(predicate) { + checkThrowCallback(predicate); + return this.getBox((parent) => parent.type === "row" && predicate(parent)); + } + getAllRows(predicate) { + checkThrowCallback(predicate, true); + if (predicate) { + return this.getAllBoxes((parent) => parent.type === "row" && predicate(parent)); + } + return this.getAllBoxes((parent) => parent.type === "row"); + } + getColumn(predicate) { + checkThrowCallback(predicate); + return this.getBox((parent) => parent.type === "column" && predicate(parent)); + } + getAllColumns(predicate) { + checkThrowCallback(predicate, true); + if (predicate) { + return this.getAllBoxes((parent) => parent.type === "column" && predicate(parent)); + } + return this.getAllBoxes((parent) => parent.type === "column"); + } + getGroup(predicate) { + checkThrowCallback(predicate); + return this.getBox((parent) => parent.type === "group" && predicate(parent)); + } + getAllGroups(predicate) { + checkThrowCallback(predicate, true); + if (predicate) { + return this.getAllBoxes((parent) => parent.type === "group" && predicate(parent)); + } + return this.getAllBoxes((parent) => parent.type === "group"); + } + getWindow(predicate) { + checkThrowCallback(predicate); + const children = getData$3(this).children; + const controller = getData$3(this).controller; + return controller.iterateFindChild(children, (child) => child.type === "window" && predicate(child)); + } + getAllWindows(predicate) { + checkThrowCallback(predicate, true); + const children = getData$3(this).children; + const controller = getData$3(this).controller; + const allWindows = controller.iterateFilterChildren(children, (child) => child.type === "window"); + if (!predicate) { + return allWindows; + } + return allWindows.filter(predicate); + } + addRow(definition) { + return getData$3(this).base.addParent(this, "row", "workspace", definition); + } + addColumn(definition) { + return getData$3(this).base.addParent(this, "column", "workspace", definition); + } + addGroup(definition) { + return getData$3(this).base.addParent(this, "group", "workspace", definition); + } + addWindow(definition) { + return getData$3(this).base.addWindow(this, definition, "workspace"); + } + async bundleToRow() { + await getData$3(this).controller.bundleWorkspaceTo("row", this.id); + await this.refreshReference(); + } + async bundleToColumn() { + await getData$3(this).controller.bundleWorkspaceTo("column", this.id); + await this.refreshReference(); + } + async hibernate() { + await getData$3(this).controller.hibernateWorkspace(this.id); + await this.refreshReference(); + } + async resume() { + await getData$3(this).controller.resumeWorkspace(this.id); + await this.refreshReference(); + } + async lock(config) { + let lockConfigResult = undefined; + if (typeof config === "function") { + const currentLockConfig = { + allowDrop: this.allowDrop, + allowDropLeft: this.allowDropLeft, + allowDropTop: this.allowDropTop, + allowDropRight: this.allowDropRight, + allowDropBottom: this.allowDropBottom, + allowSystemHibernation: this.allowSystemHibernation, + allowExtract: this.allowExtract, + allowWindowReorder: this.allowWindowReorder, + allowSplitters: this.allowSplitters, + showCloseButton: this.showCloseButton, + showSaveButton: this.showSaveButton, + allowWorkspaceTabReorder: this.allowWorkspaceTabReorder, + allowWorkspaceTabExtract: this.allowWorkspaceTabExtract, + showAddWindowButtons: this.showAddWindowButtons, + showEjectButtons: this.showEjectButtons, + showWindowCloseButtons: this.showWindowCloseButtons + }; + lockConfigResult = config(currentLockConfig); + } + else { + lockConfigResult = config; + } + const verifiedConfig = lockConfigResult === undefined ? undefined : workspaceLockConfigDecoder.runWithException(lockConfigResult); + await getData$3(this).controller.lockWorkspace(this.id, verifiedConfig); + await this.refreshReference(); + } + async pin(options) { + workspacePinOptionsDecoder.runWithException(options); + await getData$3(this).controller.pinWorkspace(this.id, options?.icon); + await this.refreshReference(); + } + async unpin() { + await getData$3(this).controller.unpinWorkspace(this.id); + await this.refreshReference(); + } + async showLoadingAnimation() { + if (!isDesktop()) { + throw new Error("Not supported in IO Connect Browser"); + } + await getData$3(this).controller.showWorkspaceLoadingAnimation(this.id); + } + async hideLoadingAnimation() { + if (!isDesktop()) { + throw new Error("Not supported in IO Connect Browser"); + } + await getData$3(this).controller.hideWorkspaceLoadingAnimation(this.id); + } + async setWindowDragMode(mode) { + const desktopGlobal = isDesktop(); + if (!desktopGlobal) { + throw new Error("Not supported in IO Connect Browser"); + } + windowDragModeDecoder.runWithException(mode); + await getData$3(this).controller.setWindowDragMode(this.id, mode); + await this.refreshReference(); + } + async onClosed(callback) { + checkThrowCallback(callback); + const id = getData$3(this).id; + const wrappedCallback = async (payload) => { + callback({ frameId: payload.frameSummary.id, workspaceId: payload.workspaceSummary.id, frameBounds: payload.frameBounds }); + }; + const config = { + action: "closed", + eventType: "workspace", + scope: "workspace", + scopeId: id, + callback: wrappedCallback + }; + const unsubscribe = await getData$3(this).controller.processLocalSubscription(config, id); + return unsubscribe; + } + async onHibernated(callback) { + checkThrowCallback(callback); + const id = getData$3(this).id; + const wrappedCallback = async () => { + await this.refreshReference(); + callback(); + }; + const config = { + action: "hibernated", + eventType: "workspace", + scope: "workspace", + scopeId: id, + callback: wrappedCallback + }; + const unsubscribe = await getData$3(this).controller.processLocalSubscription(config, id); + return unsubscribe; + } + async onResumed(callback) { + checkThrowCallback(callback); + const id = getData$3(this).id; + const wrappedCallback = async () => { + await this.refreshReference(); + callback(); + }; + const config = { + action: "resumed", + eventType: "workspace", + scope: "workspace", + scopeId: id, + callback: wrappedCallback + }; + const unsubscribe = await getData$3(this).controller.processLocalSubscription(config, id); + return unsubscribe; + } + async onWindowAdded(callback) { + checkThrowCallback(callback); + const id = getData$3(this).id; + const wrappedCallback = async (payload) => { + await this.refreshReference(); + const windowParent = this.getBox((parent) => parent.id === payload.windowSummary.parentId); + const foundWindow = windowParent.children.find((child) => { + return child.type === "window" && child.elementId === payload.windowSummary.itemId; + }); + callback(foundWindow); + }; + const config = { + action: "added", + eventType: "window", + scope: "workspace", + scopeId: id, + callback: wrappedCallback + }; + const unsubscribe = await getData$3(this).controller.processLocalSubscription(config, id); + return unsubscribe; + } + async onWindowRemoved(callback) { + checkThrowCallback(callback); + const id = getData$3(this).id; + const wrappedCallback = async (payload) => { + await this.refreshReference(); + const { windowId, workspaceId, frameId } = payload.windowSummary.config; + callback({ windowId, workspaceId, frameId }); + }; + const config = { + action: "removed", + eventType: "window", + scope: "workspace", + scopeId: id, + callback: wrappedCallback + }; + const unsubscribe = await getData$3(this).controller.processLocalSubscription(config, id); + return unsubscribe; + } + async onWindowLoaded(callback) { + checkThrowCallback(callback); + const id = getData$3(this).id; + const wrappedCallback = async (payload) => { + await this.refreshReference(); + const foundWindow = this.getWindow((win) => { + return win.id && win.id === payload.windowSummary.config.windowId; + }); + callback(foundWindow); + }; + const config = { + action: "loaded", + eventType: "window", + scope: "workspace", + scopeId: id, + callback: wrappedCallback + }; + const unsubscribe = await getData$3(this).controller.processLocalSubscription(config, id); + return unsubscribe; + } + async onWindowMaximized(callback) { + checkThrowCallback(callback); + const id = getData$3(this).id; + const wrappedCallback = async (payload) => { + await this.refreshReference(); + const windowParent = this.getBox((parent) => parent.id === payload.windowSummary.parentId); + const foundWindow = windowParent.children.find((child) => { + return child.type === "window" && child.elementId === payload.windowSummary.itemId; + }); + callback(foundWindow); + }; + const config = { + action: "maximized", + eventType: "window", + scope: "workspace", + scopeId: id, + callback: wrappedCallback + }; + const unsubscribe = await getData$3(this).controller.processLocalSubscription(config, id); + return unsubscribe; + } + async onWindowRestored(callback) { + checkThrowCallback(callback); + const id = getData$3(this).id; + const wrappedCallback = async (payload) => { + await this.refreshReference(); + const windowParent = this.getBox((parent) => parent.id === payload.windowSummary.parentId); + const foundWindow = windowParent.children.find((child) => { + return child.type === "window" && child.elementId === payload.windowSummary.itemId; + }); + callback(foundWindow); + }; + const config = { + action: "restored", + eventType: "window", + scope: "workspace", + scopeId: id, + callback: wrappedCallback + }; + const unsubscribe = await getData$3(this).controller.processLocalSubscription(config, id); + return unsubscribe; + } + async onWindowSelected(callback) { + checkThrowCallback(callback); + const id = getData$3(this).id; + const wrappedCallback = async (payload) => { + await this.refreshReference(); + const windowParent = this.getBox((parent) => parent.id === payload.windowSummary.parentId); + const foundWindow = windowParent.children.find((child) => { + return child.type === "window" && child.elementId === payload.windowSummary.itemId; + }); + callback(foundWindow); + }; + const config = { + action: "selected", + eventType: "window", + scope: "workspace", + scopeId: id, + callback: wrappedCallback + }; + const unsubscribe = await getData$3(this).controller.processLocalSubscription(config, id); + return unsubscribe; + } + async onLockConfigurationChanged(callback) { + checkThrowCallback(callback); + const id = getData$3(this).id; + const wrappedCallback = async () => { + await this.refreshReference(); + callback({ + allowDrop: this.allowDrop, + allowDropLeft: this.allowDropLeft, + allowDropTop: this.allowDropTop, + allowDropRight: this.allowDropRight, + allowDropBottom: this.allowDropBottom, + allowSystemHibernation: this.allowSystemHibernation, + allowExtract: this.allowExtract, + allowSplitters: this.allowSplitters, + allowWindowReorder: this.allowWindowReorder, + allowWorkspaceTabExtract: this.allowWorkspaceTabExtract, + allowWorkspaceTabReorder: this.allowWorkspaceTabReorder, + showAddWindowButtons: this.showAddWindowButtons, + showCloseButton: this.showCloseButton, + showEjectButtons: this.showEjectButtons, + showSaveButton: this.showSaveButton, + showWindowCloseButtons: this.showWindowCloseButtons + }); + }; + const config = { + action: "lock-configuration-changed", + eventType: "workspace", + scope: "workspace", + scopeId: id, + callback: wrappedCallback + }; + const unsubscribe = await getData$3(this).controller.processLocalSubscription(config, id); + return unsubscribe; + } + } + + const data$2 = new WeakMap(); + const getData$2 = (model) => { + return data$2.get(model).manager.getWindowData(model); + }; + class Window { + constructor(dataManager) { + data$2.set(this, { manager: dataManager }); + } + get id() { + return getData$2(this).config.windowId; + } + get elementId() { + return getData$2(this).id; + } + get type() { + return "window"; + } + get frameId() { + return getData$2(this).frame.id; + } + get workspaceId() { + return getData$2(this).workspace.id; + } + get positionIndex() { + return getData$2(this).config.positionIndex; + } + get isMaximized() { + return getData$2(this).config.isMaximized; + } + get isLoaded() { + return getData$2(this).controller.checkIsWindowLoaded(this.id); + } + get isSelected() { + return getData$2(this).config.isSelected; + } + get focused() { + return this.getGdWindow().isFocused; + } + get title() { + return getData$2(this).config.title; + } + get allowExtract() { + return getData$2(this).config.allowExtract; + } + get allowReorder() { + return getData$2(this).config.allowReorder; + } + get showCloseButton() { + return getData$2(this).config.showCloseButton; + } + get width() { + return getData$2(this).config.widthInPx; + } + get height() { + return getData$2(this).config.heightInPx; + } + get minWidth() { + return getData$2(this).config.minWidth; + } + get minHeight() { + return getData$2(this).config.minHeight; + } + get maxWidth() { + return getData$2(this).config.maxWidth; + } + get maxHeight() { + return getData$2(this).config.maxHeight; + } + get workspace() { + return getData$2(this).workspace; + } + get frame() { + return getData$2(this).frame; + } + get parent() { + return getData$2(this).parent; + } + get appName() { + return getData$2(this).config.appName; + } + async forceLoad() { + if (this.isLoaded) { + return; + } + const controller = getData$2(this).controller; + const itemId = getData$2(this).id; + const windowId = await controller.forceLoadWindow(itemId); + getData$2(this).config.windowId = windowId; + await this.workspace.refreshReference(); + } + async focus() { + const id = getData$2(this).id; + const controller = getData$2(this).controller; + await controller.focusItem(id); + await this.workspace.refreshReference(); + } + async close() { + const id = getData$2(this).id; + const controller = getData$2(this).controller; + await controller.closeItem(id); + await getData$2(this) + .parent + .removeChild((child) => child.id === id); + await this.workspace.refreshReference(); + } + async setTitle(title) { + nonEmptyStringDecoder.runWithException(title); + const itemId = getData$2(this).id; + const controller = getData$2(this).controller; + await controller.setItemTitle(itemId, title); + await this.workspace.refreshReference(); + } + async maximize() { + const id = getData$2(this).id; + const controller = getData$2(this).controller; + await controller.maximizeItem(id); + await this.workspace.refreshReference(); + } + async restore() { + const id = getData$2(this).id; + const controller = getData$2(this).controller; + await controller.restoreItem(id); + await this.workspace.refreshReference(); + } + async eject() { + if (!this.isLoaded) { + throw new Error("Cannot eject this window, because it is not loaded yet"); + } + const itemId = getData$2(this).id; + const newWindowId = await getData$2(this).controller.ejectWindow(itemId); + getData$2(this).config.windowId = newWindowId; + await this.workspace.refreshReference(); + return this.getGdWindow(); + } + getGdWindow() { + if (!this.isLoaded) { + throw new Error("Cannot fetch this GD window, because the window is not yet loaded"); + } + const myId = getData$2(this).config.windowId; + const controller = getData$2(this).controller; + return controller.getGDWindow(myId); + } + async moveTo(parent) { + if (!(parent instanceof Row || parent instanceof Column || parent instanceof Group)) { + throw new Error("Cannot add to the provided parent, because the provided parent is not an instance of Row, Column or Group"); + } + const myId = getData$2(this).id; + const controller = getData$2(this).controller; + const foundParent = await controller.getParent((p) => p.id === parent.id); + if (!foundParent) { + throw new Error("Cannot move the window to the selected parent, because this parent does not exist."); + } + await controller.moveWindowTo(myId, parent.id); + await this.workspace.refreshReference(); + } + async lock(config) { + let lockConfigResult = undefined; + if (typeof config === "function") { + const currentLockConfig = { + allowExtract: this.allowExtract, + allowReorder: this.allowReorder, + showCloseButton: this.showCloseButton + }; + lockConfigResult = config(currentLockConfig); + } + else { + lockConfigResult = config; + } + const verifiedConfig = lockConfigResult === undefined ? undefined : windowLockConfigDecoder.runWithException(lockConfigResult); + const windowPlacementId = getData$2(this).id; + await getData$2(this).controller.lockWindow(windowPlacementId, verifiedConfig); + await this.workspace.refreshReference(); + } + async setSize(config) { + const verifiedConfig = elementResizeConfigDecoder.runWithException(config); + if (!verifiedConfig.width && !verifiedConfig.height) { + throw new Error("Expected either width or height to be passed."); + } + const myId = getData$2(this).id; + const controller = getData$2(this).controller; + await controller.resizeItem(myId, { + height: verifiedConfig.height, + width: verifiedConfig.width, + relative: false + }); + await this.workspace.refreshReference(); + } + async onRemoved(callback) { + checkThrowCallback(callback); + const id = getData$2(this).id; + const wrappedCallback = async () => { + await this.workspace.refreshReference(); + callback(); + }; + const config = { + callback: wrappedCallback, + action: "removed", + eventType: "window", + scope: "window" + }; + const unsubscribe = await getData$2(this).controller.processLocalSubscription(config, id); + return unsubscribe; + } + async onLockConfigurationChanged(callback) { + checkThrowCallback(callback); + const id = getData$2(this).id; + const wrappedCallback = async () => { + await this.workspace.refreshReference(); + callback({ + allowExtract: this.allowExtract, + allowReorder: this.allowReorder, + showCloseButton: this.showCloseButton + }); + }; + const config = { + callback: wrappedCallback, + action: "lock-configuration-changed", + eventType: "window", + scope: "window" + }; + const unsubscribe = await getData$2(this).controller.processLocalSubscription(config, id); + return unsubscribe; + } + } + + const data$1 = new WeakMap(); + const getData$1 = (model) => { + return data$1.get(model).manager.getFrameData(model); + }; + class Frame { + constructor(dataManager) { + data$1.set(this, { manager: dataManager }); + } + async registerShortcut(shortcut, callback) { + nonEmptyStringDecoder.runWithException(shortcut); + checkThrowCallback(callback); + const myId = getData$1(this).summary.id; + const unsubscribe = await getData$1(this).controller.registerShortcut(shortcut, myId, callback); + return unsubscribe; + } + get id() { + return getData$1(this).summary.id; + } + get isInitialized() { + return getData$1(this).summary.isInitialized; + } + getBounds() { + const myId = getData$1(this).summary.id; + return getData$1(this).controller.getFrameBounds(myId); + } + async resize(config) { + const validatedConfig = resizeConfigDecoder.runWithException(config); + const myId = getData$1(this).summary.id; + return getData$1(this).controller.resizeItem(myId, validatedConfig); + } + async move(config) { + const validatedConfig = moveConfigDecoder.runWithException(config); + const myId = getData$1(this).summary.id; + return getData$1(this).controller.moveFrame(myId, validatedConfig); + } + focus() { + const myId = getData$1(this).summary.id; + return getData$1(this).controller.focusItem(myId); + } + async state() { + if (!isDesktop()) { + throw new Error("State operations are not supported in IO Connect Browser"); + } + const myId = getData$1(this).summary.id; + return getData$1(this).controller.getFrameState(myId); + } + async minimize() { + if (!isDesktop()) { + throw new Error("State operations are not supported in IO Connect Browser"); + } + const myId = getData$1(this).summary.id; + return getData$1(this).controller.changeFrameState(myId, "minimized"); + } + async maximize() { + if (!isDesktop()) { + throw new Error("State operations are not supported in IO Connect Browser"); + } + const myId = getData$1(this).summary.id; + return getData$1(this).controller.changeFrameState(myId, "maximized"); + } + async restore() { + if (!isDesktop()) { + throw new Error("State operations are not supported in IO Connect Browser"); + } + const myId = getData$1(this).summary.id; + return getData$1(this).controller.changeFrameState(myId, "normal"); + } + close() { + const myId = getData$1(this).summary.id; + return getData$1(this).controller.closeItem(myId); + } + snapshot() { + const myId = getData$1(this).summary.id; + return getData$1(this).controller.getSnapshot(myId, "frame"); + } + async workspaces() { + const controller = getData$1(this).controller; + return controller.getWorkspacesByFrameId(this.id); + } + async getConstraints() { + const controller = getData$1(this).controller; + const myId = getData$1(this).summary.id; + return controller.getFrameConstraints(myId); + } + async restoreWorkspace(name, options) { + nonEmptyStringDecoder.runWithException(name); + const validatedOptions = restoreWorkspaceConfigDecoder.runWithException(options); + return getData$1(this).controller.restoreWorkspace(name, validatedOptions); + } + createWorkspace(definition, config) { + const validatedDefinition = workspaceDefinitionDecoder.runWithException(definition); + const validatedConfig = workspaceBuilderCreateConfigDecoder.runWithException(config); + return getData$1(this).controller.createWorkspace(validatedDefinition, validatedConfig); + } + async init(config) { + frameInitConfigDecoder.runWithException(config); + if (getData$1(this).summary.isInitialized) { + throw new Error("The frame has already been initialized"); + } + return getData$1(this).controller.initFrame(this.id, config); + } + async onClosed(callback) { + checkThrowCallback(callback); + const myId = getData$1(this).summary.id; + const wrappedCallback = (payload) => { + callback({ frameId: payload.frameSummary.id, frameBounds: payload.frameBounds }); + }; + const config = { + callback: wrappedCallback, + action: "closed", + eventType: "frame", + scope: "frame" + }; + const unsubscribe = await getData$1(this).controller.processLocalSubscription(config, myId); + return unsubscribe; + } + async onMaximized(callback) { + checkThrowCallback(callback); + const myId = getData$1(this).summary.id; + const wrappedCallback = () => { + callback(); + }; + const config = { + callback: wrappedCallback, + action: "maximized", + eventType: "frame", + scope: "frame" + }; + const unsubscribe = await getData$1(this).controller.processLocalSubscription(config, myId); + return unsubscribe; + } + async onMinimized(callback) { + checkThrowCallback(callback); + const myId = getData$1(this).summary.id; + const wrappedCallback = () => { + callback(); + }; + const config = { + callback: wrappedCallback, + action: "minimized", + eventType: "frame", + scope: "frame" + }; + const unsubscribe = await getData$1(this).controller.processLocalSubscription(config, myId); + return unsubscribe; + } + async onNormal(callback) { + checkThrowCallback(callback); + const myId = getData$1(this).summary.id; + const wrappedCallback = () => { + callback(); + }; + const config = { + callback: wrappedCallback, + action: "normal", + eventType: "frame", + scope: "frame" + }; + const unsubscribe = await getData$1(this).controller.processLocalSubscription(config, myId); + return unsubscribe; + } + async onWorkspaceOpened(callback) { + checkThrowCallback(callback); + const myId = getData$1(this).summary.id; + const wrappedCallback = async (payload) => { + const workspace = await getData$1(this).controller.transformStreamPayloadToWorkspace(payload); + callback(workspace); + }; + const config = { + callback: wrappedCallback, + action: "opened", + eventType: "workspace", + scope: "frame" + }; + const unsubscribe = await getData$1(this).controller.processLocalSubscription(config, myId); + return unsubscribe; + } + async onWorkspaceSelected(callback) { + checkThrowCallback(callback); + const myId = getData$1(this).summary.id; + const wrappedCallback = async (payload) => { + const workspace = await getData$1(this).controller.getWorkspaceById(payload.workspaceSummary.id); + callback(workspace); + }; + const config = { + callback: wrappedCallback, + action: "selected", + eventType: "workspace", + scope: "frame" + }; + const unsubscribe = await getData$1(this).controller.processLocalSubscription(config, myId); + return unsubscribe; + } + async onWorkspaceClosed(callback) { + checkThrowCallback(callback); + const myId = getData$1(this).summary.id; + const wrappedCallback = (payload) => { + callback({ frameId: payload.frameSummary.id, workspaceId: payload.workspaceSummary.id, frameBounds: payload.frameBounds }); + }; + const config = { + callback: wrappedCallback, + action: "closed", + eventType: "workspace", + scope: "frame" + }; + const unsubscribe = await getData$1(this).controller.processLocalSubscription(config, myId); + return unsubscribe; + } + async onWindowAdded(callback) { + checkThrowCallback(callback); + const myId = getData$1(this).summary.id; + const wrappedCallback = async (payload) => { + const foundParent = await getData$1(this).controller.getParent((parent) => parent.id === payload.windowSummary.parentId); + const foundWindow = foundParent.children.find((child) => child.type === "window" && child.positionIndex === payload.windowSummary.config.positionIndex); + callback(foundWindow); + }; + const config = { + callback: wrappedCallback, + action: "added", + eventType: "window", + scope: "frame" + }; + const unsubscribe = await getData$1(this).controller.processLocalSubscription(config, myId); + return unsubscribe; + } + async onWindowRemoved(callback) { + checkThrowCallback(callback); + const myId = getData$1(this).summary.id; + const wrappedCallback = (payload) => { + const { windowId, workspaceId, frameId } = payload.windowSummary.config; + callback({ windowId, workspaceId, frameId }); + }; + const config = { + callback: wrappedCallback, + action: "removed", + eventType: "window", + scope: "frame" + }; + const unsubscribe = await getData$1(this).controller.processLocalSubscription(config, myId); + return unsubscribe; + } + async onWindowLoaded(callback) { + checkThrowCallback(callback); + const myId = getData$1(this).summary.id; + const wrappedCallback = async (payload) => { + const foundParent = await getData$1(this).controller.getParent((parent) => { + return parent.id === payload.windowSummary.parentId; + }); + const foundWindow = foundParent.children.find((child) => child.type === "window" && child.positionIndex === payload.windowSummary.config.positionIndex); + callback(foundWindow); + }; + const config = { + callback: wrappedCallback, + action: "loaded", + eventType: "window", + scope: "frame" + }; + const unsubscribe = await getData$1(this).controller.processLocalSubscription(config, myId); + return unsubscribe; + } + async onInitializationRequested(callback) { + checkThrowCallback(callback); + if (!this.isInitialized) { + callback(getData$1(this).summary.initializationContext); + } + return () => { }; + } + async onFocusChanged(callback) { + checkThrowCallback(callback); + const myData = getData$1(this); + const { id } = myData.summary; + const wrappedCallback = (args) => { + callback({ isFocused: args.frameSummary.isFocused }); + }; + const config = { + callback: wrappedCallback, + action: "focus", + eventType: "frame", + scope: "frame" + }; + const unsubscribe = await myData.controller.processLocalSubscription(config, id); + return unsubscribe; + } + } + + class PrivateDataManager { + parentsData = new WeakMap(); + workspacesData = new WeakMap(); + windowsData = new WeakMap(); + framesData = new WeakMap(); + deleteData(model) { + if (model instanceof Window) { + this.windowsData.delete(model); + } + if (model instanceof Workspace) { + this.workspacesData.delete(model); + } + if (model instanceof Row || model instanceof Column || model instanceof Group) { + this.parentsData.delete(model); + } + if (model instanceof Frame) { + this.framesData.delete(model); + } + } + setWindowData(model, data) { + this.windowsData.set(model, data); + } + setWorkspaceData(model, data) { + this.workspacesData.set(model, data); + } + setParentData(model, data) { + this.parentsData.set(model, data); + } + setFrameData(model, data) { + this.framesData.set(model, data); + } + getWindowData(model) { + return this.windowsData.get(model); + } + getWorkspaceData(model) { + return this.workspacesData.get(model); + } + getParentData(model) { + return this.parentsData.get(model); + } + getFrameData(model) { + return this.framesData.get(model); + } + remapChild(model, newData) { + if (model instanceof Window) { + const data = this.windowsData.get(model); + data.parent = newData.parent || data.parent; + data.config = newData.config || data.config; + } + if (model instanceof Row || model instanceof Column || model instanceof Group) { + const data = this.parentsData.get(model); + data.parent = newData.parent || data.parent; + data.config = newData.config || data.config; + data.children = newData.children || data.children; + } + } + remapFrame(model, newData) { + const data = this.framesData.get(model); + data.summary = newData; + } + remapWorkspace(model, newData) { + const data = this.workspacesData.get(model); + data.frame = newData.frame || data.frame; + data.config = newData.config || data.config; + data.children = newData.children || data.children; + } + } + + const data = new WeakMap(); + const getData = (base, model) => { + const manager = data.get(base).manager; + if (model instanceof Workspace) { + return manager.getWorkspaceData(model); + } + return data.get(base).manager.getParentData(model); + }; + class Base { + frameId; + workspaceId; + positionIndex; + constructor(dataManager) { + data.set(this, { manager: dataManager }); + } + getId(model) { + return getData(this, model).id; + } + getPositionIndex(model) { + return getData(this, model).config.positionIndex; + } + getWorkspaceId(model) { + const privateData = getData(this, model); + return privateData.config.workspaceId || privateData.workspace.id; + } + getFrameId(model) { + return getData(this, model).frame.id; + } + getAllChildren(model, predicate) { + checkThrowCallback(predicate, true); + const children = getData(this, model).children; + if (typeof predicate === "undefined") { + return children; + } + return children.filter(predicate); + } + getMyParent(model) { + if (model instanceof Workspace) { + return model; + } + return getData(this, model).parent; + } + getMyFrame(model) { + return getData(this, model).frame; + } + getMyWorkspace(model) { + if (model instanceof Workspace) { + return model; + } + return getData(this, model).workspace; + } + async addWindow(model, definition, parentType) { + if (!definition.appName && !definition.windowId) { + throw new Error("The window definition should contain either an appName or a windowId"); + } + const validatedDefinition = swimlaneWindowDefinitionDecoder.runWithException(definition); + const controller = getData(this, model).controller; + const operationResult = await controller.add("window", getData(this, model).id, parentType, validatedDefinition); + if (model instanceof Workspace) { + await model.refreshReference(); + return model.getWindow(w => w.elementId === operationResult.itemId); + } + const myWorkspace = this.getMyWorkspace(model); + await myWorkspace.refreshReference(); + return myWorkspace.getWindow(w => w.elementId === operationResult.itemId); + } + async addParent(model, typeToAdd, parentType, definition) { + const parentDefinition = this.transformDefinition(typeToAdd, definition); + const controller = getData(this, model).controller; + const newParentId = (await controller.add("container", getData(this, model).id, parentType, parentDefinition)).itemId; + if (model instanceof Workspace) { + await model.refreshReference(); + return model.getBox((parent) => parent.id === newParentId); + } + const myWorkspace = this.getMyWorkspace(model); + await myWorkspace.refreshReference(); + return myWorkspace.getBox((parent) => parent.id === newParentId); + } + async removeChild(model, predicate) { + checkThrowCallback(predicate); + const child = this.getAllChildren(model).find(predicate); + if (!child) { + return; + } + await child.close(); + if (model instanceof Workspace) { + await model.refreshReference(); + return; + } + await this.getMyWorkspace(model).refreshReference(); + } + async maximize(model) { + const { controller, id } = getData(this, model); + await controller.maximizeItem(id); + await this.getMyWorkspace(model.parent).refreshReference(); + } + async restore(model) { + const { controller, id } = getData(this, model); + await controller.restoreItem(id); + await this.getMyWorkspace(model.parent).refreshReference(); + } + async close(model) { + const modelData = getData(this, model); + const controller = getData(this, model).controller; + await controller.closeItem(modelData.id); + await this.getMyWorkspace(modelData.parent).refreshReference(); + } + async lockContainer(model, config) { + const modelData = getData(this, model); + const controller = getData(this, model).controller; + await controller.lockContainer(modelData.id, model.type, config); + await this.getMyWorkspace(modelData.parent).refreshReference(); + } + getAllowDrop(model) { + return getData(this, model).config.allowDrop; + } + getAllowDropLeft(model) { + const privateData = getData(this, model); + if (privateData.type !== "group") { + throw new Error(`Property allowDropLeft is available only for groups and not on ${model.type} ${model.id}`); + } + return privateData.config.allowDropLeft; + } + getAllowDropRight(model) { + const privateData = getData(this, model); + if (privateData.type !== "group") { + throw new Error(`Property allowDropRight is available only for groups and not on ${model.type} ${model.id}`); + } + return privateData.config.allowDropRight; + } + getAllowDropTop(model) { + const privateData = getData(this, model); + if (privateData.type !== "group") { + throw new Error(`Property allowDropTop is available only for groups and not on ${model.type} ${model.id}`); + } + return privateData.config.allowDropTop; + } + getAllowDropBottom(model) { + const privateData = getData(this, model); + if (privateData.type !== "group") { + throw new Error(`Property allowDropBottom is available only for groups and not on ${model.type} ${model.id}`); + } + return privateData.config.allowDropBottom; + } + getAllowDropHeader(model) { + const privateData = getData(this, model); + if (privateData.type !== "group") { + throw new Error(`Property allowDropHeader is available only for groups and not on ${model.type} ${model.id}`); + } + return privateData.config.allowDropHeader; + } + getAllowSplitters(model) { + const privateData = getData(this, model); + if (privateData.type === "group") { + throw new Error(`Cannot get allow splitters from private data ${privateData.type}`); + } + return privateData.config.allowSplitters; + } + getAllowExtract(model) { + const privateData = getData(this, model); + if (privateData.type !== "group") { + throw new Error(`Cannot get allow extract from private data ${privateData.type} with config ${privateData.type !== "workspace" ? privateData.config.type : ""}`); + } + return privateData.config.allowExtract; + } + getAllowReorder(model) { + const privateData = getData(this, model); + if (privateData.type !== "group") { + throw new Error(`Cannot get allow extract from private data ${privateData.type} with config ${privateData.type !== "workspace" ? privateData.config.type : ""}`); + } + return privateData.config.allowReorder; + } + getShowMaximizeButton(model) { + const privateData = getData(this, model); + if (privateData.type !== "group") { + throw new Error(`Cannot get show maximize button from private data${privateData.type} with config ${privateData.type !== "workspace" ? privateData.config.type : ""}`); + } + return privateData.config.showMaximizeButton; + } + getShowEjectButton(model) { + const privateData = getData(this, model); + if (privateData.type !== "group") { + throw new Error(`Cannot get show eject button from private data${privateData.type} with config ${privateData.type !== "workspace" ? privateData.config.type : ""}`); + } + return privateData.config.showEjectButton; + } + getShowAddWindowButton(model) { + const privateData = getData(this, model); + if (privateData.type !== "group") { + throw new Error(`Cannot get add window button from private data${privateData.type} with config ${privateData.type !== "workspace" ? privateData.config.type : ""}`); + } + return privateData.config.showAddWindowButton; + } + getMinWidth(model) { + const privateData = getData(this, model); + return privateData.config.minWidth; + } + getMaxWidth(model) { + const privateData = getData(this, model); + return privateData.config.maxWidth; + } + getMinHeight(model) { + const privateData = getData(this, model); + return privateData.config.minHeight; + } + getMaxHeight(model) { + const privateData = getData(this, model); + return privateData.config.maxHeight; + } + getWidthInPx(model) { + const privateData = getData(this, model); + return privateData.config.widthInPx; + } + getHeightInPx(model) { + const privateData = getData(this, model); + return privateData.config.heightInPx; + } + getIsPinned(model) { + const privateData = getData(this, model); + return privateData.config.isPinned; + } + getIsMaximized(model) { + const privateData = getData(this, model); + return privateData.config.isMaximized; + } + getMaximizationBoundary(model) { + const privateData = getData(this, model); + return privateData.config.maximizationBoundary; + } + async setHeight(model, height) { + const modelData = getData(this, model); + const { controller, id } = modelData; + await controller.resizeItem(id, { + height + }); + await this.getMyWorkspace(modelData.parent).refreshReference(); + } + async setWidth(model, width) { + const modelData = getData(this, model); + const { controller, id } = modelData; + await controller.resizeItem(id, { + width + }); + await this.getMyWorkspace(modelData.parent).refreshReference(); + } + async setSize(model, width, height) { + const modelData = getData(this, model); + const { controller, id } = modelData; + await controller.resizeItem(id, { + width, + height + }); + await this.getMyWorkspace(modelData.parent).refreshReference(); + } + async setMaximizationBoundary(model, config) { + const modelData = getData(this, model); + const { controller, id } = modelData; + await controller.setMaximizationBoundary(id, config); + await this.getMyWorkspace(modelData.parent).refreshReference(); + } + async bundleTo(model, type) { + const modelData = getData(this, model); + const { controller, id } = modelData; + await controller.bundleItemTo(type, id); + } + async processLocalSubscription(model, subscriptionConfig) { + return getData(this, model).controller.processLocalSubscription(subscriptionConfig, this.getId(model)); + } + transformDefinition(type, definition) { + let parentDefinition; + if (typeof definition === "undefined") { + parentDefinition = { type, children: [] }; + } + else if (definition instanceof ParentBuilder) { + parentDefinition = definition.serialize(); + } + else { + if (typeof definition.type === "undefined") { + definition.type = type; + } + parentDefinition = strictParentDefinitionDecoder.runWithException(definition); + parentDefinition.children = parentDefinition.children || []; + } + return parentDefinition; + } + } + + class BaseController { + ioc; + windows; + contexts; + layouts; + constructor(ioc, windows, contexts, layouts) { + this.ioc = ioc; + this.windows = windows; + this.contexts = contexts; + this.layouts = layouts; + } + get bridge() { + return this.ioc.bridge; + } + get privateDataManager() { + return this.ioc.privateDataManager; + } + checkIsWindowLoaded(windowId) { + return (!!windowId) && this.windows.list().some((win) => win.id === windowId); + } + async createWorkspace(createConfig) { + const snapshot = await this.bridge.send(OPERATIONS.createWorkspace.name, createConfig); + const frameConfig = { + summary: snapshot.frameSummary + }; + const frame = this.ioc.getModel("frame", frameConfig); + const workspaceConfig = { frame, snapshot }; + return this.ioc.getModel("workspace", workspaceConfig); + } + async createEmptyFrame(definition) { + const frameSummary = await this.bridge.send(OPERATIONS.createFrame.name, definition); + const frameConfig = { + summary: frameSummary + }; + return this.ioc.getModel("frame", frameConfig); + } + async initFrame(frameId, config) { + await this.bridge.send(OPERATIONS.initFrame.name, { frameId, ...config }); + } + async restoreWorkspace(name, options) { + const snapshot = await this.bridge.send(OPERATIONS.openWorkspace.name, { name, restoreOptions: options }); + const frameSummary = await this.bridge.send(OPERATIONS.getFrameSummary.name, { itemId: snapshot.config.frameId }); + const frameConfig = { + summary: frameSummary + }; + const frame = this.ioc.getModel("frame", frameConfig); + const workspaceConfig = { frame, snapshot }; + return this.ioc.getModel("workspace", workspaceConfig); + } + async add(type, parentId, parentType, definition) { + let operationName; + const operationArgs = { definition, parentId, parentType }; + if (type === "window") { + operationName = OPERATIONS.addWindow.name; + } + else if (type === "container") { + operationName = OPERATIONS.addContainer.name; + } + else { + throw new Error(`Unrecognized add type: ${type}`); + } + return await this.bridge.send(operationName, operationArgs); + } + async getFrame(windowId) { + const frameSummary = await this.bridge.send(OPERATIONS.getFrameSummary.name, { itemId: windowId }); + const frameConfig = { + summary: frameSummary + }; + return this.ioc.getModel("frame", frameConfig); + } + getFrames(allFrameSummaries, predicate) { + return allFrameSummaries.reduce((frames, frameSummary) => { + const frameConfig = { + summary: frameSummary + }; + const frameToCheck = this.ioc.getModel("frame", frameConfig); + if (!predicate || predicate(frameToCheck)) { + frames.push(frameToCheck); + } + return frames; + }, []); + } + getAllWorkspaceSummaries(...bridgeResults) { + const allSummaries = bridgeResults.reduce((summaries, summaryResult) => { + summaries.push(...summaryResult.summaries); + return summaries; + }, []); + return allSummaries.map((summary) => { + return Object.assign({}, { id: summary.id, width: summary.config.widthInPx, height: summary.config.heightInPx }, summary.config); + }); + } + handleOnSaved(callback) { + const wrappedCallback = (layout) => { + if (layout.type !== "Workspace") { + return; + } + callback(layout); + }; + const addedUnSub = this.layouts.onAdded(wrappedCallback); + const changedUnSub = this.layouts.onChanged(wrappedCallback); + return () => { + addedUnSub(); + changedUnSub(); + }; + } + handleOnRemoved(callback) { + const wrappedCallback = (layout) => { + if (layout.type !== "Workspace") { + return; + } + callback(layout); + }; + return this.layouts.onRemoved(wrappedCallback); + } + async importLayouts(layouts, mode) { + await this.layouts.import(layouts, mode); + } + async transformStreamPayloadToWorkspace(payload) { + const frameConfig = { + summary: payload.frameSummary + }; + const frame = this.ioc.getModel("frame", frameConfig); + const snapshot = payload.workspaceSnapshot || (await this.bridge.send(OPERATIONS.getWorkspaceSnapshot.name, { itemId: payload.workspaceSummary.id })); + const workspaceConfig = { frame, snapshot }; + const workspace = this.ioc.getModel("workspace", workspaceConfig); + return workspace; + } + async fetchWorkspace(itemId) { + const snapshot = await this.bridge.send(OPERATIONS.getWorkspaceSnapshot.name, { itemId }); + const frameConfig = { + summary: snapshot.frameSummary + }; + const frame = this.ioc.getModel("frame", frameConfig); + const workspaceConfig = { frame, snapshot }; + return this.ioc.getModel("workspace", workspaceConfig); + } + async bundleWorkspaceTo(type, workspaceId) { + await this.bridge.send(OPERATIONS.bundleWorkspace.name, { type, workspaceId }); + } + async bundleItemTo(type, itemId) { + const isSupported = await this.isOperationSupported(OPERATIONS.bundleItem.name); + if (!isSupported) { + throw new Error(`Operation ${OPERATIONS.bundleItem.name} is not supported. Ensure that you are running the latest version of all packages`); + } + await this.bridge.send(OPERATIONS.bundleItem.name, { type, itemId }); + } + getWorkspaceContext(workspaceId) { + const contextName = `___workspace___${workspaceId}`; + return this.contexts.get(contextName); + } + setWorkspaceContext(workspaceId, data) { + const contextName = `___workspace___${workspaceId}`; + return this.contexts.set(contextName, data); + } + updateWorkspaceContext(workspaceId, data) { + const contextName = `___workspace___${workspaceId}`; + return this.contexts.update(contextName, data); + } + subscribeWorkspaceContextUpdated(workspaceId, callback) { + const contextName = `___workspace___${workspaceId}`; + return this.contexts.subscribe(contextName, callback); + } + async restoreItem(itemId) { + await this.bridge.send(OPERATIONS.restoreItem.name, { itemId }); + } + async maximizeItem(itemId) { + await this.bridge.send(OPERATIONS.maximizeItem.name, { itemId }); + } + async focusItem(itemId) { + await this.bridge.send(OPERATIONS.focusItem.name, { itemId }); + } + async closeItem(itemId) { + await this.bridge.send(OPERATIONS.closeItem.name, { itemId }); + } + async resizeItem(itemId, config) { + await this.bridge.send(OPERATIONS.resizeItem.name, Object.assign({}, { itemId }, config)); + } + async setMaximizationBoundary(itemId, config) { + await this.bridge.send(OPERATIONS.setMaximizationBoundary.name, Object.assign({}, { itemId }, config)); + } + async showWorkspaceLoadingAnimation(workspaceId) { + await this.bridge.send(OPERATIONS.showLoadingAnimation.name, { itemId: workspaceId, type: "workspace" }); + } + async hideWorkspaceLoadingAnimation(workspaceId) { + await this.bridge.send(OPERATIONS.hideLoadingAnimation.name, { itemId: workspaceId, type: "workspace" }); + } + async setWindowDragMode(workspaceId, dragMode) { + await this.bridge.send(OPERATIONS.setWindowDragMode.name, { itemId: workspaceId, dragMode }); + } + async moveFrame(itemId, config) { + await this.bridge.send(OPERATIONS.moveFrame.name, Object.assign({}, { itemId }, config)); + } + getGDWindow(itemId) { + return this.windows.list().find((gdWindow) => gdWindow.id === itemId); + } + async forceLoadWindow(itemId) { + const controlResult = await this.bridge.send(OPERATIONS.forceLoadWindow.name, { itemId }); + return controlResult.windowId; + } + async ejectWindow(itemId) { + return await this.bridge.send(OPERATIONS.ejectWindow.name, { itemId }); + } + async moveWindowTo(itemId, newParentId) { + await this.bridge.send(OPERATIONS.moveWindowTo.name, { itemId, containerId: newParentId }); + } + async getSnapshot(itemId, type) { + let result; + if (type === "workspace") { + result = await this.bridge.send(OPERATIONS.getWorkspaceSnapshot.name, { itemId }); + } + else if (type === "frame") { + result = await this.bridge.send(OPERATIONS.getFrameSnapshot.name, { itemId }); + } + return result; + } + async setItemTitle(itemId, title) { + await this.bridge.send(OPERATIONS.setItemTitle.name, { itemId, title }); + } + refreshChildren(config) { + const { parent, children, existingChildren, workspace } = config; + if (parent instanceof Window || parent.type === "window") { + return; + } + const newChildren = children.map((newChildSnapshot) => { + let childToAdd = existingChildren.find((child) => { + return child.type === "window" ? child.elementId === newChildSnapshot.id : child.id === newChildSnapshot.id; + }); + if (childToAdd) { + this.privateDataManager.remapChild(childToAdd, { + parent: parent, + children: [], + config: newChildSnapshot.config + }); + } + else { + let createConfig; + if (newChildSnapshot.type === "window") { + createConfig = { + id: newChildSnapshot.id, + parent: parent, + frame: workspace.frame, + workspace, + config: newChildSnapshot.config, + }; + } + else { + createConfig = { + id: newChildSnapshot.id, + parent: parent, + frame: workspace.frame, + workspace, + config: newChildSnapshot.config, + children: [] + }; + } + childToAdd = this.ioc.getModel(newChildSnapshot.type, createConfig); + } + if (newChildSnapshot.type !== "window") { + this.refreshChildren({ + workspace, existingChildren, + children: newChildSnapshot.children, + parent: childToAdd + }); + } + return childToAdd; + }); + if (parent instanceof Workspace) { + return newChildren; + } + else { + this.privateDataManager.remapChild(parent, { children: newChildren }); + return newChildren; + } + } + iterateFindChild(children, predicate) { + let foundChild = children.find((child) => predicate(child)); + if (foundChild) { + return foundChild; + } + children.some((child) => { + if (child instanceof Window) { + return false; + } + foundChild = this.iterateFindChild(child.children, predicate); + if (foundChild) { + return true; + } + }); + return foundChild; + } + iterateFilterChildren(children, predicate) { + const foundChildren = children.filter((child) => predicate(child)); + const grandChildren = children.reduce((innerFound, child) => { + if (child instanceof Window) { + return innerFound; + } + innerFound.push(...this.iterateFilterChildren(child.children, predicate)); + return innerFound; + }, []); + foundChildren.push(...grandChildren); + return foundChildren; + } + notifyWindowAdded(windowId) { + return new Promise((resolve) => { + const alreadyPresent = this.windows.list().some((win) => win.id === windowId); + if (alreadyPresent) { + return resolve(); + } + const unsubscribe = this.windows.onWindowAdded((win) => { + if (win.id !== windowId) { + return; + } + if (unsubscribe) { + unsubscribe(); + } + resolve(); + }); + }); + } + async hibernateWorkspace(workspaceId) { + await this.bridge.send(OPERATIONS.hibernateWorkspace.name, { workspaceId }); + } + async resumeWorkspace(workspaceId) { + await this.bridge.send(OPERATIONS.resumeWorkspace.name, { workspaceId }); + } + async lockWorkspace(workspaceId, config) { + await this.bridge.send(OPERATIONS.lockWorkspace.name, { workspaceId, config }); + } + async lockWindow(windowPlacementId, config) { + await this.bridge.send(OPERATIONS.lockWindow.name, { windowPlacementId, config }); + } + async lockContainer(itemId, type, config) { + await this.bridge.send(OPERATIONS.lockContainer.name, { itemId, type, config }); + } + async pinWorkspace(workspaceId, icon) { + await this.bridge.send(OPERATIONS.pinWorkspace.name, { workspaceId, icon }); + } + async unpinWorkspace(workspaceId) { + await this.bridge.send(OPERATIONS.unpinWorkspace.name, { workspaceId }); + } + async getWorkspaceIcon(workspaceId) { + const result = await this.bridge.send(OPERATIONS.getWorkspaceIcon.name, { workspaceId }); + return result.icon; + } + setWorkspaceIcon(workspaceId, icon) { + return this.bridge.send(OPERATIONS.setWorkspaceIcon.name, { workspaceId, icon }); + } + async getPlatformFrameId() { + try { + const result = await this.bridge.send(OPERATIONS.getPlatformFrameId.name, {}); + return result; + } + catch (error) { + return {}; + } + } + async setLoadingStrategy(workspaceId, strategy) { + await this.isOperationSupported(OPERATIONS.setLoadingStrategy.name); + return this.bridge.send(OPERATIONS.setLoadingStrategy.name, { itemId: workspaceId, strategy }); + } + async isOperationSupported(operation) { + if (isDesktop()) { + return { isSupported: true }; + } + return await this.bridge.send(OPERATIONS.operationCheck.name, { operation }); + } + } + + class MainController { + bridge; + base; + shortcutsController; + constructor(bridge, base, shortcutsController) { + this.bridge = bridge; + this.base = base; + this.shortcutsController = shortcutsController; + } + checkIsWindowLoaded(windowId) { + return this.base.checkIsWindowLoaded(windowId); + } + async checkIsInSwimlane(windowId) { + const controlResult = await this.bridge.send(OPERATIONS.isWindowInWorkspace.name, { itemId: windowId }); + return controlResult.inWorkspace; + } + async createWorkspace(definition, saveConfig) { + const createConfig = Object.assign({}, definition, { saveConfig }); + return await this.base.createWorkspace(createConfig); + } + async createEmptyFrame(definition) { + return await this.base.createEmptyFrame(definition); + } + async initFrame(frameId, config) { + return this.base.initFrame(frameId, config); + } + async restoreWorkspace(name, options) { + const allLayouts = await this.getLayoutSummaries(); + const layoutExists = allLayouts.some((summary) => summary.name === name); + if (!layoutExists) { + throw new Error(`This layout: ${name} cannot be restored, because it doesn't exist.`); + } + if (options?.frameId) { + const allFrameSummaries = await this.bridge.send(OPERATIONS.getAllFramesSummaries.name); + const foundMatchingFrame = allFrameSummaries.summaries.some((summary) => summary.id === options.frameId); + if (!foundMatchingFrame) { + throw new Error(`Cannot reuse the frame with id: ${options.frameId}, because there is no frame with that ID found`); + } + } + return await this.base.restoreWorkspace(name, options); + } + async add(type, parentId, parentType, definition) { + return await this.base.add(type, parentId, parentType, definition); + } + processLocalSubscription(config, levelId) { + return isDesktop() ? + this.handleEnterpriseLocalSubscription(config, levelId) : + this.handleCoreLocalSubscription(config, levelId); + } + processGlobalSubscription(callback, eventType, action) { + return isDesktop() ? + this.handleEnterpriseGlobalSubscription(callback, eventType, action) : + this.handleCoreGlobalSubscription(callback, eventType, action); + } + async getFrame(selector) { + if (selector.windowId) { + return await this.base.getFrame(selector.windowId); + } + if (selector.predicate) { + return (await this.getFrames(selector.predicate))[0]; + } + throw new Error(`The provided selector is not valid: ${JSON.stringify(selector)}`); + } + async getFrames(predicate) { + const allFrameSummaries = await this.bridge.send(OPERATIONS.getAllFramesSummaries.name); + return this.base.getFrames(allFrameSummaries.summaries, predicate); + } + getWorkspaceById(workspaceId) { + return this.base.fetchWorkspace(workspaceId); + } + async getWorkspaceByWindowId(itemId) { + if (!isDesktop()) { + return (await this.getWorkspaces((wsp) => !!wsp.getWindow((w) => w.id === itemId)))[0]; + } + return this.base.fetchWorkspace(itemId); + } + transformStreamPayloadToWorkspace(payload) { + return this.base.transformStreamPayloadToWorkspace(payload); + } + async getWorkspace(predicate) { + let foundWorkspace; + await this.iterateWorkspaces((wsp, end) => { + if (predicate(wsp)) { + foundWorkspace = wsp; + end(); + } + }); + return foundWorkspace; + } + async getWorkspaces(predicate) { + const matchingWorkspaces = []; + await this.iterateWorkspaces((wsp) => { + if (!predicate || predicate(wsp)) { + matchingWorkspaces.push(wsp); + } + }); + return matchingWorkspaces; + } + async getWorkspacesByFrameId(frameId) { + const workspaceSummaries = await this.getAllWorkspaceSummaries(); + const summariesForFrame = workspaceSummaries.filter((s) => s.frameId === frameId); + const workspacesForFrame = await Promise.all(summariesForFrame.map((summary) => { + return this.base.fetchWorkspace(summary.id); + })); + return workspacesForFrame; + } + async getAllWorkspaceSummaries() { + const allSummariesResult = await this.bridge.send(OPERATIONS.getAllWorkspacesSummaries.name, {}); + return this.base.getAllWorkspaceSummaries(allSummariesResult); + } + async getWindow(predicate) { + let resultWindow; + await this.iterateWorkspaces((wsp, end) => { + const foundWindow = wsp.getWindow(predicate); + if (foundWindow) { + resultWindow = foundWindow; + end(); + } + }); + return resultWindow; + } + async getParent(predicate) { + let resultParent; + await this.iterateWorkspaces((wsp, end) => { + const foundParent = wsp.getBox(predicate); + if (foundParent) { + resultParent = foundParent; + end(); + } + }); + return resultParent; + } + async getLayoutSummaries() { + const allLayouts = await this.bridge.send(OPERATIONS.getAllLayoutsSummaries.name); + return allLayouts.summaries; + } + async deleteLayout(name) { + await this.bridge.send(OPERATIONS.deleteLayout.name, { name }); + } + async exportLayout(predicate) { + const allLayoutsResult = await this.bridge.send(OPERATIONS.exportAllLayouts.name); + return allLayoutsResult.layouts.reduce((matchingLayouts, layout) => { + if (!predicate || predicate(layout)) { + matchingLayouts.push(layout); + } + return matchingLayouts; + }, []); + } + async saveLayout(config) { + return await this.bridge.send(OPERATIONS.saveLayout.name, config); + } + async importLayouts(layouts, mode) { + if (isDesktop()) { + try { + await this.bridge.send(OPERATIONS.importLayouts.name, { layouts, mode }); + } + catch (error) { + await Promise.all(layouts.map((layout) => this.bridge.send(OPERATIONS.importLayout.name, { layout, mode }))); + } + return; + } + await this.base.importLayouts(layouts, mode); + } + handleOnSaved(callback) { + return this.base.handleOnSaved(callback); + } + handleOnRemoved(callback) { + return this.base.handleOnRemoved(callback); + } + async bundleWorkspaceTo(type, workspaceId) { + return await this.base.bundleWorkspaceTo(type, workspaceId); + } + async bundleItemTo(type, id) { + return await this.base.bundleItemTo(type, id); + } + getWorkspaceContext(workspaceId) { + return this.base.getWorkspaceContext(workspaceId); + } + setWorkspaceContext(workspaceId, data) { + return this.base.setWorkspaceContext(workspaceId, data); + } + updateWorkspaceContext(workspaceId, data) { + return this.base.updateWorkspaceContext(workspaceId, data); + } + subscribeWorkspaceContextUpdated(workspaceId, callback) { + return this.base.subscribeWorkspaceContextUpdated(workspaceId, callback); + } + async restoreItem(itemId) { + return await this.base.restoreItem(itemId); + } + async maximizeItem(itemId) { + return await this.base.maximizeItem(itemId); + } + async focusItem(itemId) { + return await this.base.focusItem(itemId); + } + async changeFrameState(frameId, state) { + await this.bridge.send(OPERATIONS.changeFrameState.name, { frameId, requestedState: state }); + } + async getFrameBounds(frameId) { + const frameResult = await this.bridge.send(OPERATIONS.getFrameBounds.name, { itemId: frameId }); + return frameResult.bounds; + } + async getFrameState(frameId) { + const frameResult = await this.bridge.send(OPERATIONS.getFrameState.name, { itemId: frameId }); + return frameResult.state; + } + async closeItem(itemId) { + return await this.base.closeItem(itemId); + } + async resizeItem(itemId, config) { + return await this.base.resizeItem(itemId, config); + } + async setMaximizationBoundary(itemId, config) { + return await this.base.setMaximizationBoundary(itemId, config); + } + async showWorkspaceLoadingAnimation(workspaceId) { + return await this.base.showWorkspaceLoadingAnimation(workspaceId); + } + async hideWorkspaceLoadingAnimation(workspaceId) { + return await this.base.hideWorkspaceLoadingAnimation(workspaceId); + } + async setWindowDragMode(workspaceId, dragMode) { + return await this.base.setWindowDragMode(workspaceId, dragMode); + } + async moveFrame(itemId, config) { + return await this.base.moveFrame(itemId, config); + } + getGDWindow(itemId) { + return this.base.getGDWindow(itemId); + } + async forceLoadWindow(itemId) { + const windowId = await this.base.forceLoadWindow(itemId); + await this.base.notifyWindowAdded(windowId); + return windowId; + } + async ejectWindow(itemId) { + const windowId = (await this.base.ejectWindow(itemId)).windowId; + await this.base.notifyWindowAdded(windowId); + return windowId; + } + async moveWindowTo(itemId, newParentId) { + return await this.base.moveWindowTo(itemId, newParentId); + } + async getSnapshot(itemId, type) { + return await this.base.getSnapshot(itemId, type); + } + async setItemTitle(itemId, title) { + return await this.base.setItemTitle(itemId, title); + } + flatChildren(children) { + return children.reduce((soFar, child) => { + soFar.push(child); + if (child.type !== "window") { + soFar.push(...this.flatChildren(child.children)); + } + return soFar; + }, []); + } + refreshChildren(config) { + return this.base.refreshChildren(config); + } + iterateFindChild(children, predicate) { + return this.base.iterateFindChild(children, predicate); + } + iterateFilterChildren(children, predicate) { + return this.base.iterateFilterChildren(children, predicate); + } + hibernateWorkspace(workspaceId) { + return this.base.hibernateWorkspace(workspaceId); + } + resumeWorkspace(workspaceId) { + return this.base.resumeWorkspace(workspaceId); + } + lockWorkspace(workspaceId, config) { + return this.base.lockWorkspace(workspaceId, config); + } + lockWindow(windowPlacementId, config) { + return this.base.lockWindow(windowPlacementId, config); + } + lockContainer(itemId, type, config) { + return this.base.lockContainer(itemId, type, config); + } + pinWorkspace(workspaceId, icon) { + return this.base.pinWorkspace(workspaceId, icon); + } + unpinWorkspace(workspaceId) { + return this.base.unpinWorkspace(workspaceId); + } + getWorkspaceIcon(workspaceId) { + return this.base.getWorkspaceIcon(workspaceId); + } + setWorkspaceIcon(workspaceId, icon) { + return this.base.setWorkspaceIcon(workspaceId, icon); + } + async getFrameConstraints(frameId) { + const frameSnapshot = await this.getSnapshot(frameId, "frame"); + return { + minWidth: frameSnapshot.config.minWidth, + maxWidth: frameSnapshot.config.maxWidth, + minHeight: frameSnapshot.config.minHeight, + maxHeight: frameSnapshot.config.maxHeight, + }; + } + registerShortcut(shortcut, frameId, callback) { + return this.shortcutsController.registerShortcut(shortcut, frameId, callback); + } + getPlatformFrameId() { + return this.base.getPlatformFrameId(); + } + setLoadingStrategy(workspaceId, strategy) { + return this.base.setLoadingStrategy(workspaceId, strategy); + } + async handleCoreLocalSubscription(config, levelId) { + await this.bridge.createCoreEventSubscription(); + config.scopeId = config.scopeId || levelId; + if (config.eventType === "window" && config.action === "loaded") { + const originalCB = config.callback; + const wrappedCB = async (callbackData) => { + await this.base.notifyWindowAdded(callbackData.windowSummary.config.windowId); + originalCB(callbackData); + }; + config.callback = wrappedCB; + } + return this.bridge.handleCoreSubscription(config); + } + handleEnterpriseLocalSubscription(config, levelId) { + config.scopeId = config.scopeId || levelId; + if (config.eventType === "window" && config.action === "loaded") { + const originalCB = config.callback; + const wrappedCB = async (callbackData) => { + await this.base.notifyWindowAdded(callbackData.windowSummary.config.windowId); + originalCB(callbackData); + }; + config.callback = wrappedCB; + } + return this.bridge.subscribe(config); + } + async handleCoreGlobalSubscription(callback, eventType, action) { + await this.bridge.createCoreEventSubscription(); + const config = { + eventType, callback, action, + scope: "global", + }; + if (eventType === "window" && action === "loaded") { + const wrappedCB = async (callbackData) => { + await this.base.notifyWindowAdded(callbackData.windowSummary.config.windowId); + callback(callbackData); + }; + config.callback = wrappedCB; + } + return this.bridge.handleCoreSubscription(config); + } + handleEnterpriseGlobalSubscription(callback, eventType, action) { + const config = { + eventType, callback, action, + scope: "global", + }; + if (eventType === "window" && action === "loaded") { + const wrappedCB = async (callbackData) => { + await this.base.notifyWindowAdded(callbackData.windowSummary.config.windowId); + callback(callbackData); + }; + config.callback = wrappedCB; + } + return this.bridge.subscribe(config); + } + async iterateWorkspaces(callback) { + let ended = false; + const end = () => { ended = true; }; + const workspaceSummaries = await this.getAllWorkspaceSummaries(); + for (const summary of workspaceSummaries) { + if (ended) { + return; + } + const wsp = await this.base.fetchWorkspace(summary.id); + callback(wsp, end); + } + } + } + + class ShortcutsController { + bridge; + _shortcuts = CallbackFactory(); + constructor(bridge) { + this.bridge = bridge; + this.bridge.onOperation((payload, caller) => { + if (payload.operation === CLIENT_OPERATIONS.shortcutClicked.name) { + const data = payload.data; + this._shortcuts.execute(`${data.frameId}-${data.shortcut}`); + } + }); + } + async registerShortcut(shortcut, frameId, callback) { + await this.bridge.send(OPERATIONS.registerShortcut.name, { shortcut, frameId }); + const un = this._shortcuts.add(`${frameId}-${shortcut}`, callback); + return () => { + un(); + this.bridge.send(OPERATIONS.unregisterShortcut.name, { shortcut, frameId }); + }; + } + } + + class IoC { + agm; + windows; + layouts; + contexts; + _controllerInstance; + _bridgeInstance; + _transportInstance; + _privateDataManagerInstance; + _parentBaseInstance; + _baseController; + _shortcutsController; + constructor(agm, windows, layouts, contexts) { + this.agm = agm; + this.windows = windows; + this.layouts = layouts; + this.contexts = contexts; + } + get baseController() { + if (!this._baseController) { + this._baseController = new BaseController(this, this.windows, this.contexts, this.layouts); + } + return this._baseController; + } + get controller() { + if (!this._controllerInstance) { + this._controllerInstance = new MainController(this.bridge, this.baseController, this.shortcutsController); + } + return this._controllerInstance; + } + get shortcutsController() { + if (!this._shortcutsController) { + this._shortcutsController = new ShortcutsController(this.bridge); + } + return this._shortcutsController; + } + get bridge() { + if (!this._bridgeInstance) { + this._bridgeInstance = new Bridge(this.transport, CallbackFactory()); + } + return this._bridgeInstance; + } + get transport() { + if (!this._transportInstance) { + this._transportInstance = new InteropTransport(this.agm, CallbackFactory()); + } + return this._transportInstance; + } + get privateDataManager() { + if (!this._privateDataManagerInstance) { + this._privateDataManagerInstance = new PrivateDataManager(); + } + return this._privateDataManagerInstance; + } + get parentBase() { + if (!this._parentBaseInstance) { + this._parentBaseInstance = new Base(this.privateDataManager); + } + return this._parentBaseInstance; + } + async initiate(actualWindowId) { + await this.transport.initiate(actualWindowId); + } + getModel(type, createConfig) { + switch (type) { + case "frame": { + const newFrame = new Frame(this.privateDataManager); + const { summary } = createConfig; + const frameData = { summary, controller: this.controller }; + this.privateDataManager.setFrameData(newFrame, frameData); + return newFrame; + } + case "window": { + const { id, parent, frame, workspace, config } = createConfig; + const windowPrivateData = { + type: "window", + controller: this.controller, + config, id, parent, frame, workspace + }; + const newWindow = new Window(this.privateDataManager); + this.privateDataManager.setWindowData(newWindow, windowPrivateData); + return newWindow; + } + case "row": + case "column": + case "group": { + const { id, children, parent, frame, workspace, config } = createConfig; + const newParent = type === "column" ? new Column(this.parentBase) : + type === "row" ? new Row(this.parentBase) : new Group(this.parentBase); + const builtChildren = this.buildChildren(children, frame, workspace, newParent); + const parentPrivateData = { + id, parent, frame, workspace, + config, + type, + controller: this.controller, + children: builtChildren, + }; + this.privateDataManager.setParentData(newParent, parentPrivateData); + return newParent; + } + case "workspace": { + const { snapshot, frame } = createConfig; + const newWorkspace = new Workspace(this.privateDataManager); + const children = this.buildChildren(snapshot.children, frame, newWorkspace, newWorkspace); + const workspacePrivateData = { + id: snapshot.id, + type: "workspace", + config: snapshot.config, + base: this.parentBase, + controller: this.controller, + children, frame, ioc: this + }; + this.privateDataManager.setWorkspaceData(newWorkspace, workspacePrivateData); + return newWorkspace; + } + default: throw new Error(`Unrecognized type: ${type}`); + } + } + getBuilder(config) { + config.definition = config.definition || {}; + if (!Array.isArray(config.definition.children)) { + config.definition.children = []; + } + const baseBuilder = new BaseBuilder(this.getBuilder.bind(this)); + switch (config.type) { + case "workspace": { + return new WorkspaceBuilder(config.definition, baseBuilder, this.controller); + } + case "row": + case "column": + case "group": { + config.definition.type = config.type; + return new ParentBuilder(config.definition, baseBuilder); + } + default: throw new Error(`Unexpected Builder creation error, provided config: ${JSON.stringify(config)}`); + } + } + buildChildren(children, frame, workspace, parent) { + return children.map((child) => { + switch (child.type) { + case "window": return this.getModel("window", { + id: child.id, + config: child.config, + frame, workspace, parent + }); + case "column": return this.getModel(child.type, { + id: child.id, + config: child.config, + children: child.children, + frame, workspace, parent + }); + case "row": return this.getModel(child.type, { + id: child.id, + config: child.config, + children: child.children, + frame, workspace, parent + }); + case "group": return this.getModel(child.type, { + id: child.id, + config: child.config, + children: child.children, + frame, workspace, parent + }); + default: throw new Error(`Unsupported child type: ${child.type}`); + } + }); + } + } + + var version = "3.5.6"; + + const composeAPI = (glue, ioc) => { + const controller = ioc.controller; + const inWorkspace = () => { + const myId = glue.windows.my().id; + if (!myId) { + throw new Error("Cannot get my frame, because my id is undefined."); + } + return controller.checkIsInSwimlane(myId); + }; + const getBuilder = (config) => { + const validatedConfig = builderConfigDecoder.runWithException(config); + return ioc.getBuilder(validatedConfig); + }; + const getMyFrame = async () => { + const windowId = glue.windows.my().id; + if (!windowId) { + throw new Error("Cannot get my frame, because my id is undefined."); + } + const isInSwimlane = await controller.checkIsInSwimlane(windowId); + if (!isInSwimlane) { + throw new Error("Cannot fetch your frame, because this window is not in a workspace"); + } + return controller.getFrame({ windowId }); + }; + const getFrame = async (predicate) => { + checkThrowCallback(predicate); + return controller.getFrame({ predicate }); + }; + const getAllFrames = async (predicate) => { + checkThrowCallback(predicate, true); + return controller.getFrames(predicate); + }; + const getAllWorkspacesSummaries = () => { + return controller.getAllWorkspaceSummaries(); + }; + const getMyWorkspace = async () => { + const myId = glue.windows.my().id; + if (!myId) { + throw new Error("Cannot get my workspace, because my id is undefined."); + } + const isInSwimlane = await controller.checkIsInSwimlane(myId); + if (!isInSwimlane) { + throw new Error("Cannot fetch your workspace, because this window is not in a workspace"); + } + return await controller.getWorkspaceByWindowId(myId); + }; + const getWorkspace = async (predicate) => { + checkThrowCallback(predicate); + return (await controller.getWorkspaces(predicate))[0]; + }; + const getWorkspaceById = async (workspaceId) => { + nonEmptyStringDecoder.runWithException(workspaceId); + return controller.getWorkspaceById(workspaceId); + }; + const getAllWorkspaces = (predicate) => { + checkThrowCallback(predicate, true); + return controller.getWorkspaces(predicate); + }; + const getWindow = async (predicate) => { + checkThrowCallback(predicate); + return controller.getWindow(predicate); + }; + const getParent = async (predicate) => { + checkThrowCallback(predicate); + return controller.getParent(predicate); + }; + const restoreWorkspace = async (name, options) => { + nonEmptyStringDecoder.runWithException(name); + const validatedOptions = restoreWorkspaceConfigDecoder.runWithException(options); + return controller.restoreWorkspace(name, validatedOptions); + }; + const createWorkspace = async (definition, saveConfig) => { + const validatedDefinition = workspaceDefinitionDecoder.runWithException(definition); + const validatedConfig = workspaceBuilderCreateConfigDecoder.runWithException(saveConfig); + return controller.createWorkspace(validatedDefinition, validatedConfig); + }; + const createEmptyFrame = async (definition) => { + const validatedDefinition = emptyFrameDefinitionDecoder.runWithException(definition); + return controller.createEmptyFrame(validatedDefinition ?? {}); + }; + const layouts = { + getSummaries: () => { + return controller.getLayoutSummaries(); + }, + delete: async (name) => { + nonEmptyStringDecoder.runWithException(name); + return controller.deleteLayout(name); + }, + export: async (predicate) => { + checkThrowCallback(predicate, true); + return controller.exportLayout(predicate); + }, + import: async (layouts, mode = "replace") => { + if (!Array.isArray(layouts)) { + throw new Error(`The provided layouts argument is not an array: ${JSON.stringify(layouts)}`); + } + layouts.forEach((layout) => workspaceLayoutDecoder.runWithException(layout)); + return controller.importLayouts(layouts, mode); + }, + save: async (config) => { + const verifiedConfig = workspaceLayoutSaveConfigDecoder.runWithException(config); + return controller.saveLayout(verifiedConfig); + }, + onSaved: async (callback) => { + checkThrowCallback(callback); + return controller.handleOnSaved(callback); + }, + onRemoved: async (callback) => { + checkThrowCallback(callback); + return controller.handleOnRemoved(callback); + } + }; + const onFrameOpened = async (callback) => { + checkThrowCallback(callback); + const wrappedCallback = (payload) => { + const frameConfig = { + summary: payload.frameSummary + }; + const frame = ioc.getModel("frame", frameConfig); + callback(frame); + }; + const unsubscribe = await controller.processGlobalSubscription(wrappedCallback, "frame", "opened"); + return unsubscribe; + }; + const onFrameClosed = async (callback) => { + checkThrowCallback(callback); + const wrappedCallback = (payload) => { + callback({ frameId: payload.frameSummary.id, frameBounds: payload.frameBounds }); + }; + const unsubscribe = await controller.processGlobalSubscription(wrappedCallback, "frame", "closed"); + return unsubscribe; + }; + const onWorkspaceOpened = async (callback) => { + checkThrowCallback(callback); + const wrappedCallback = async (payload) => { + const workspace = await controller.transformStreamPayloadToWorkspace(payload); + callback(workspace); + }; + const unsubscribe = await controller.processGlobalSubscription(wrappedCallback, "workspace", "opened"); + return unsubscribe; + }; + const onWorkspaceClosed = async (callback) => { + checkThrowCallback(callback); + const wrappedCallback = (payload) => { + callback({ frameId: payload.frameSummary.id, workspaceId: payload.workspaceSummary.id, frameBounds: payload.frameBounds }); + }; + const unsubscribe = await controller.processGlobalSubscription(wrappedCallback, "workspace", "closed"); + return unsubscribe; + }; + const onWorkspaceHibernated = async (callback) => { + checkThrowCallback(callback); + const wrappedCallback = async (payload) => { + const workspace = await controller.transformStreamPayloadToWorkspace(payload); + callback(workspace); + }; + const unsubscribe = await controller.processGlobalSubscription(wrappedCallback, "workspace", "hibernated"); + return unsubscribe; + }; + const onWorkspaceResumed = async (callback) => { + checkThrowCallback(callback); + const wrappedCallback = async (payload) => { + const workspace = await controller.transformStreamPayloadToWorkspace(payload); + callback(workspace); + }; + const unsubscribe = await controller.processGlobalSubscription(wrappedCallback, "workspace", "resumed"); + return unsubscribe; + }; + const onWindowAdded = async (callback) => { + checkThrowCallback(callback); + const wrappedCallback = async (payload) => { + const snapshot = (await controller.getSnapshot(payload.windowSummary.config.workspaceId, "workspace")); + const frameConfig = { + summary: snapshot.frameSummary + }; + const frame = ioc.getModel("frame", frameConfig); + const workspaceConfig = { frame, snapshot }; + const workspace = ioc.getModel("workspace", workspaceConfig); + const windowParent = workspace.getBox((parent) => parent.id === payload.windowSummary.parentId); + const foundWindow = windowParent.children.find((child) => child.type === "window" && child.elementId === payload.windowSummary.itemId); + callback(foundWindow); + }; + const unsubscribe = await controller.processGlobalSubscription(wrappedCallback, "window", "added"); + return unsubscribe; + }; + const onWindowLoaded = async (callback) => { + checkThrowCallback(callback); + const wrappedCallback = async (payload) => { + const snapshot = (await controller.getSnapshot(payload.windowSummary.config.workspaceId, "workspace")); + const frameConfig = { + summary: snapshot.frameSummary + }; + const frame = ioc.getModel("frame", frameConfig); + const workspaceConfig = { frame, snapshot }; + const workspace = ioc.getModel("workspace", workspaceConfig); + const foundWindow = workspace.getWindow((win) => win.id && win.id === payload.windowSummary.config.windowId); + callback(foundWindow); + }; + const unsubscribe = await controller.processGlobalSubscription(wrappedCallback, "window", "loaded"); + return unsubscribe; + }; + const onWindowRemoved = async (callback) => { + checkThrowCallback(callback); + const wrappedCallback = (payload) => { + const { windowId, workspaceId, frameId } = payload.windowSummary.config; + callback({ windowId, workspaceId, frameId }); + }; + const unsubscribe = await controller.processGlobalSubscription(wrappedCallback, "window", "removed"); + return unsubscribe; + }; + const onWindowMaximized = async (callback) => { + checkThrowCallback(callback); + const wrappedCallback = async (payload) => { + const snapshot = (await controller.getSnapshot(payload.windowSummary.config.workspaceId, "workspace")); + const frameConfig = { + summary: snapshot.frameSummary + }; + const frame = ioc.getModel("frame", frameConfig); + const workspaceConfig = { frame, snapshot }; + const workspace = ioc.getModel("workspace", workspaceConfig); + const windowParent = workspace.getBox((parent) => parent.id === payload.windowSummary.parentId); + const foundWindow = windowParent.children.find((child) => child.type === "window" && child.elementId === payload.windowSummary.itemId); + callback(foundWindow); + }; + const unsubscribe = await controller.processGlobalSubscription(wrappedCallback, "window", "maximized"); + return unsubscribe; + }; + const onWindowRestored = async (callback) => { + checkThrowCallback(callback); + const wrappedCallback = async (payload) => { + const snapshot = (await controller.getSnapshot(payload.windowSummary.config.workspaceId, "workspace")); + const frameConfig = { + summary: snapshot.frameSummary + }; + const frame = ioc.getModel("frame", frameConfig); + const workspaceConfig = { frame, snapshot }; + const workspace = ioc.getModel("workspace", workspaceConfig); + const windowParent = workspace.getBox((parent) => parent.id === payload.windowSummary.parentId); + const foundWindow = windowParent.children.find((child) => child.type === "window" && child.elementId === payload.windowSummary.itemId); + callback(foundWindow); + }; + const unsubscribe = await controller.processGlobalSubscription(wrappedCallback, "window", "restored"); + return unsubscribe; + }; + const onWindowSelected = async (callback) => { + checkThrowCallback(callback); + const wrappedCallback = async (payload) => { + const snapshot = (await controller.getSnapshot(payload.windowSummary.config.workspaceId, "workspace")); + const frameConfig = { + summary: snapshot.frameSummary + }; + const frame = ioc.getModel("frame", frameConfig); + const workspaceConfig = { frame, snapshot }; + const workspace = ioc.getModel("workspace", workspaceConfig); + const windowParent = workspace.getBox((parent) => parent.id === payload.windowSummary.parentId); + const foundWindow = windowParent.children.find((child) => child.type === "window" && child.elementId === payload.windowSummary.itemId); + callback(foundWindow); + }; + const unsubscribe = await controller.processGlobalSubscription(wrappedCallback, "window", "selected"); + return unsubscribe; + }; + const waitForFrame = async (id) => { + nonEmptyStringDecoder.runWithException(id); + return new Promise((res, rej) => { + let unsub = () => { + }; + onFrameOpened((f) => { + if (f.id === id) { + res(f); + unsub(); + } + }).then((u) => { + unsub = u; + return getAllFrames(); + }).then((frames) => { + const myFrame = frames.find((f) => f.id === id); + if (myFrame) { + res(myFrame); + unsub(); + } + }).catch(rej); + }); + }; + return { + inWorkspace, + getBuilder, + getMyFrame, + getFrame, + getAllFrames, + getAllWorkspacesSummaries, + getMyWorkspace, + getWorkspace, + getWorkspaceById, + getAllWorkspaces, + getWindow, + getBox: getParent, + restoreWorkspace, + createWorkspace, + createEmptyFrame, + waitForFrame, + layouts, + onFrameOpened, + onFrameClosed, + onWorkspaceOpened, + onWorkspaceClosed, + onWorkspaceHibernated, + onWorkspaceResumed, + onWindowAdded, + onWindowLoaded, + onWindowRemoved, + onWindowMaximized, + onWindowRestored, + onWindowSelected, + version + }; + }; + + const factoryFunction = async (io) => { + const ioc = new IoC(io.agm, io.windows, io.layouts, io.contexts); + const actualWindowId = io.interop.instance.windowId; + await ioc.initiate(actualWindowId); + io.workspaces = composeAPI(io, ioc); + }; + if (typeof window !== "undefined") { + window.IOWorkspaces = factoryFunction; + } + + return factoryFunction; + +})); +//# sourceMappingURL=workspaces.umd.js.map diff --git a/typescript/solution/client-details/tsconfig.json b/typescript/solution/client-details/tsconfig.json new file mode 100644 index 0000000..11ec879 --- /dev/null +++ b/typescript/solution/client-details/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "./dist", + "rootDir": "./src" + }, + "include": ["./src", "../../types"] +} \ No newline at end of file diff --git a/typescript/solution/client-details/webpack.config.js b/typescript/solution/client-details/webpack.config.js new file mode 100644 index 0000000..cf31d79 --- /dev/null +++ b/typescript/solution/client-details/webpack.config.js @@ -0,0 +1,31 @@ +const path = require('path'); +const CopyWebpackPlugin = require('copy-webpack-plugin'); + +module.exports = { + mode: 'development', + entry: './src/index.ts', + module: { + rules: [ + { + test: /\.tsx?$/, + use: 'ts-loader', + exclude: /node_modules/, + }, + ], + }, + resolve: { + extensions: ['.tsx', '.ts', '.js'], + }, + output: { + filename: 'index.js', + path: path.resolve(__dirname, 'dist'), + }, + plugins: [ + new CopyWebpackPlugin({ + patterns: [ + { from: 'src/index.html', to: 'index.html' }, + { from: 'src/lib', to: 'lib' } + ], + }), + ], +}; \ No newline at end of file diff --git a/typescript/solution/clients/esbuild.js b/typescript/solution/clients/esbuild.js new file mode 100644 index 0000000..27c80dc --- /dev/null +++ b/typescript/solution/clients/esbuild.js @@ -0,0 +1,48 @@ +const fs = require('fs'); +const path = require('path'); +const { build } = require('esbuild'); + +// Directory paths +const srcDir = path.join(__dirname, 'src'); +const distDir = path.join(__dirname, 'dist'); + +// Ensure dist directory exists +if (!fs.existsSync(distDir)) { + fs.mkdirSync(distDir, { recursive: true }); +} + +// Copy HTML file +fs.copyFileSync( + path.join(srcDir, 'index.html'), + path.join(distDir, 'index.html') +); + +// Copy lib directory +const libSrcDir = path.join(srcDir, 'lib'); +const libDistDir = path.join(distDir, 'lib'); + +if (!fs.existsSync(libDistDir)) { + fs.mkdirSync(libDistDir, { recursive: true }); +} + +fs.readdirSync(libSrcDir).forEach(file => { + fs.copyFileSync( + path.join(libSrcDir, file), + path.join(libDistDir, file) + ); +}); + +// Build with esbuild +build({ + entryPoints: [path.join(srcDir, 'index.ts')], + bundle: true, + outfile: path.join(distDir, 'index.js'), + platform: 'browser', + format: 'iife', + sourcemap: true, + target: ['es2020'], + tsconfig: path.join(__dirname, 'tsconfig.json'), +}).catch((error) => { + console.error(error); + process.exit(1); +}); \ No newline at end of file diff --git a/typescript/solution/clients/src/index.html b/typescript/solution/clients/src/index.html new file mode 100644 index 0000000..a014c17 --- /dev/null +++ b/typescript/solution/clients/src/index.html @@ -0,0 +1,57 @@ + + + + + + + + + + + + Clients + + + + + + + + + + + + + +
+
+
+
+ io.Connect is unavailable +
+ +
+
+

Clients

+
+
+
+ + + + + + + + + + + +
Full NamePIDGIDAccount Manager
+
+
+ + + diff --git a/typescript/solution/clients/src/index.ts b/typescript/solution/clients/src/index.ts new file mode 100644 index 0000000..d633767 --- /dev/null +++ b/typescript/solution/clients/src/index.ts @@ -0,0 +1,162 @@ +const setupClients = (clients: Client[]): void => { + const table = document.getElementById("clientsTable")?.getElementsByTagName("tbody")[0]; + if (!table) return; + + const addRowCell = (row: HTMLTableRowElement, cellData: string, cssClass?: string): void => { + const cell = document.createElement("td"); + + cell.innerText = cellData; + + if (cssClass) { + cell.className = cssClass; + } + + row.appendChild(cell); + }; + + const addRow = (table: HTMLTableSectionElement, client: Client): void => { + const row = document.createElement("tr"); + + addRowCell(row, client.name || ""); + addRowCell(row, client.pId || ""); + addRowCell(row, client.gId || ""); + addRowCell(row, client.accountManager || ""); + + row.onclick = () => { + clientClickedHandler(client); + }; + + table.appendChild(row); + }; + + clients.forEach((client) => { + addRow(table, client); + }); +}; + +// TODO: Chapter 3 +const toggleIOAvailable = (): void => { + const span = document.getElementById("ioConnectSpan"); + if (!span) return; + + span.classList.remove("bg-danger"); + span.classList.add("bg-success"); + span.textContent = "io.Connect is available"; +}; + +const clientClickedHandler = async (client: Client): Promise => { + // TODO: Chapter 5.2 + // const selectClientStocks = io.interop.methods().find(method => method.name === "SelectClient"); + + // TODO: Chapter 5.3 + // if (selectClientStocks) { + // io.interop.invoke(selectClientStocks, { client }); + // }; + + // TODO: Chapter 6.1 + // io.contexts.update("SelectedClient", client).catch(console.error); + + // TODO: Chapter 7.2 + // const currentChannel = io.channels.my(); + + // if (currentChannel) { + // io.channels.publish(client).catch(console.error); + // }; + + // TODO: Chapter 9.3 + const restoreConfig = { + context: { client } + }; + + try { + const workspace = await window.io.workspaces.restoreWorkspace("Client Space", restoreConfig); + + await raiseNotificationOnWorkspaceOpen(client.name, workspace); + } catch (error) { + console.error((error as Error).message); + } +}; + +const raiseNotificationOnWorkspaceOpen = async (clientName: string, workspace: Workspace): Promise => { + // TODO: Chapter 11.1 + const options: NotificationOptions = { + title: "New Workspace", + body: `A new Workspace for ${clientName} was opened!`, + }; + + const notification = await window.io.notifications.raise(options); + + notification.onclick = () => { + workspace.frame.focus().catch(console.error); + workspace.focus().catch(console.error); + }; +}; + +const start = async (): Promise => { + const html = document.documentElement; + const initialTheme = iodesktop.theme; + + html.className = initialTheme; + + const clientsResponse = await fetch("http://localhost:8080/api/clients"); + const clients = await clientsResponse.json() as Client[]; + + setupClients(clients); + + // const stocksButton = document.getElementById("stocks-btn"); + + // stocksButton.onclick = stocksButtonHandler; + + // TODO: Chapter 3 + const config = { + // channels: true, + libraries: [IOWorkspaces] + }; + + const io = await IODesktop(config); + + window.io = io; + + toggleIOAvailable(); + + // TODO: Chapter 12.1 + const themeHandler = (newTheme: Theme): void => { + html.className = newTheme.name; + }; + + io.themes.onChanged(themeHandler); + + // TODO: Chapter 13 + const stocksAppHotkey: Hotkey = { + hotkey: "alt+shift+s", + description: "Starts the Stocks app." + }; + + const stocksAppHotkeyHandler = (): void => { + io.appManager.application("stocks").start().catch(console.error); + }; + + const themeHotkey: Hotkey = { + hotkey: "alt+shift+t", + description: "Toggles the platform theme." + }; + + const themeHotkeyHandler = async (): Promise => { + const currentTheme = await io.themes.getCurrent(); + const themeToSelect = currentTheme.name === "dark" ? "light" : "dark"; + + io.themes.select(themeToSelect); + }; + + io.hotkeys.register(stocksAppHotkey, stocksAppHotkeyHandler); + io.hotkeys.register(themeHotkey, themeHotkeyHandler); +}; + +// Add io property to window object +declare global { + interface Window { + io: IODesktopAPI; + } +} + +start().catch(console.error); \ No newline at end of file diff --git a/typescript/solution/clients/src/lib/desktop.umd.js b/typescript/solution/clients/src/lib/desktop.umd.js new file mode 100644 index 0000000..6cea2c9 --- /dev/null +++ b/typescript/solution/clients/src/lib/desktop.umd.js @@ -0,0 +1,23144 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define(factory) : + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.desktop = factory()); +})(this, (function () { 'use strict'; + + var MetricTypes = { + STRING: 1, + NUMBER: 2, + TIMESTAMP: 3, + OBJECT: 4 + }; + + function getMetricTypeByValue(metric) { + if (metric.type === MetricTypes.TIMESTAMP) { + return "timestamp"; + } + else if (metric.type === MetricTypes.NUMBER) { + return "number"; + } + else if (metric.type === MetricTypes.STRING) { + return "string"; + } + else if (metric.type === MetricTypes.OBJECT) { + return "object"; + } + return "unknown"; + } + function getTypeByValue(value) { + if (value.constructor === Date) { + return "timestamp"; + } + else if (typeof value === "number") { + return "number"; + } + else if (typeof value === "string") { + return "string"; + } + else if (typeof value === "object") { + return "object"; + } + else { + return "string"; + } + } + function serializeMetric(metric) { + const serializedMetrics = {}; + const type = getMetricTypeByValue(metric); + if (type === "object") { + const values = Object.keys(metric.value).reduce((memo, key) => { + const innerType = getTypeByValue(metric.value[key]); + if (innerType === "object") { + const composite = defineNestedComposite(metric.value[key]); + memo[key] = { + type: "object", + description: "", + context: {}, + composite, + }; + } + else { + memo[key] = { + type: innerType, + description: "", + context: {}, + }; + } + return memo; + }, {}); + serializedMetrics.composite = values; + } + serializedMetrics.name = normalizeMetricName(metric.path.join("/") + "/" + metric.name); + serializedMetrics.type = type; + serializedMetrics.description = metric.description; + serializedMetrics.context = {}; + return serializedMetrics; + } + function defineNestedComposite(values) { + return Object.keys(values).reduce((memo, key) => { + const type = getTypeByValue(values[key]); + if (type === "object") { + memo[key] = { + type: "object", + description: "", + context: {}, + composite: defineNestedComposite(values[key]), + }; + } + else { + memo[key] = { + type, + description: "", + context: {}, + }; + } + return memo; + }, {}); + } + function normalizeMetricName(name) { + if (typeof name !== "undefined" && name.length > 0 && name[0] !== "/") { + return "/" + name; + } + else { + return name; + } + } + function getMetricValueByType(metric) { + const type = getMetricTypeByValue(metric); + if (type === "timestamp") { + return Date.now(); + } + else { + return publishNestedComposite(metric.value); + } + } + function publishNestedComposite(values) { + if (typeof values !== "object") { + return values; + } + return Object.keys(values).reduce((memo, key) => { + const value = values[key]; + if (typeof value === "object" && value.constructor !== Date) { + memo[key] = publishNestedComposite(value); + } + else if (value.constructor === Date) { + memo[key] = new Date(value).getTime(); + } + else if (value.constructor === Boolean) { + memo[key] = value.toString(); + } + else { + memo[key] = value; + } + return memo; + }, {}); + } + function flatten(arr) { + return arr.reduce((flat, toFlatten) => { + return flat.concat(Array.isArray(toFlatten) ? flatten(toFlatten) : toFlatten); + }, []); + } + function getHighestState(arr) { + return arr.sort((a, b) => { + if (!a.state) { + return 1; + } + if (!b.state) { + return -1; + } + return b.state - a.state; + })[0]; + } + function aggregateDescription(arr) { + let msg = ""; + arr.forEach((m, idx, a) => { + const path = m.path.join("."); + if (idx === a.length - 1) { + msg += path + "." + m.name + ": " + m.description; + } + else { + msg += path + "." + m.name + ": " + m.description + ","; + } + }); + if (msg.length > 100) { + return msg.slice(0, 100) + "..."; + } + else { + return msg; + } + } + function composeMsgForRootStateMetric(system) { + const aggregatedState = system.root.getAggregateState(); + const merged = flatten(aggregatedState); + const highestState = getHighestState(merged); + const aggregateDesc = aggregateDescription(merged); + return { + description: aggregateDesc, + value: highestState.state, + }; + } + + function gw3 (connection, config) { + if (!connection || typeof connection !== "object") { + throw new Error("Connection is required parameter"); + } + let joinPromise; + let session; + const init = (repo) => { + let resolveReadyPromise; + joinPromise = new Promise((resolve) => { + resolveReadyPromise = resolve; + }); + session = connection.domain("metrics"); + session.onJoined((reconnect) => { + if (!reconnect && resolveReadyPromise) { + resolveReadyPromise(); + resolveReadyPromise = undefined; + } + const rootStateMetric = { + name: "/State", + type: "object", + composite: { + Description: { + type: "string", + description: "", + }, + Value: { + type: "number", + description: "", + }, + }, + description: "System state", + context: {}, + }; + const defineRootMetricsMsg = { + type: "define", + metrics: [rootStateMetric], + }; + session.send(defineRootMetricsMsg); + if (reconnect) { + replayRepo(repo); + } + }); + session.join({ + system: config.system, + service: config.service, + instance: config.instance + }); + }; + const replayRepo = (repo) => { + replaySystem(repo.root); + }; + const replaySystem = (system) => { + createSystem(system); + system.metrics.forEach((m) => { + createMetric(m); + }); + system.subSystems.forEach((ss) => { + replaySystem(ss); + }); + }; + const createSystem = async (system) => { + if (system.parent === undefined) { + return; + } + await joinPromise; + const metric = { + name: normalizeMetricName(system.path.join("/") + "/" + system.name + "/State"), + type: "object", + composite: { + Description: { + type: "string", + description: "", + }, + Value: { + type: "number", + description: "", + }, + }, + description: "System state", + context: {}, + }; + const createMetricsMsg = { + type: "define", + metrics: [metric], + }; + session.send(createMetricsMsg); + }; + const updateSystem = async (system, state) => { + await joinPromise; + const shadowedUpdateMetric = { + type: "publish", + values: [{ + name: normalizeMetricName(system.path.join("/") + "/" + system.name + "/State"), + value: { + Description: state.description, + Value: state.state, + }, + timestamp: Date.now(), + }], + }; + session.send(shadowedUpdateMetric); + const stateObj = composeMsgForRootStateMetric(system); + const rootMetric = { + type: "publish", + peer_id: connection.peerId, + values: [{ + name: "/State", + value: { + Description: stateObj.description, + Value: stateObj.value, + }, + timestamp: Date.now(), + }], + }; + session.send(rootMetric); + }; + const createMetric = async (metric) => { + const metricClone = cloneMetric(metric); + await joinPromise; + const m = serializeMetric(metricClone); + const createMetricsMsg = { + type: "define", + metrics: [m], + }; + session.send(createMetricsMsg); + if (typeof metricClone.value !== "undefined") { + updateMetricCore(metricClone); + } + }; + const updateMetric = async (metric) => { + const metricClone = cloneMetric(metric); + await joinPromise; + updateMetricCore(metricClone); + }; + const updateMetricCore = (metric) => { + if (canUpdate()) { + const value = getMetricValueByType(metric); + const publishMetricsMsg = { + type: "publish", + values: [{ + name: normalizeMetricName(metric.path.join("/") + "/" + metric.name), + value, + timestamp: Date.now(), + }], + }; + return session.sendFireAndForget(publishMetricsMsg); + } + return Promise.resolve(); + }; + const cloneMetric = (metric) => { + const metricClone = { ...metric }; + if (typeof metric.value === "object" && metric.value !== null) { + metricClone.value = { ...metric.value }; + } + return metricClone; + }; + const canUpdate = () => { + try { + const func = config.canUpdateMetric ?? (() => true); + return func(); + } + catch { + return true; + } + }; + return { + init, + createSystem, + updateSystem, + createMetric, + updateMetric, + }; + } + + var Helpers = { + validate: (definition, parent, transport) => { + if (definition === null || typeof definition !== "object") { + throw new Error("Missing definition"); + } + if (parent === null || typeof parent !== "object") { + throw new Error("Missing parent"); + } + if (transport === null || typeof transport !== "object") { + throw new Error("Missing transport"); + } + }, + }; + + class BaseMetric { + definition; + system; + transport; + value; + type; + path = []; + name; + description; + get repo() { + return this.system?.repo; + } + get id() { return `${this.system.path}/${name}`; } + constructor(definition, system, transport, value, type) { + this.definition = definition; + this.system = system; + this.transport = transport; + this.value = value; + this.type = type; + Helpers.validate(definition, system, transport); + this.path = system.path.slice(0); + this.path.push(system.name); + this.name = definition.name; + this.description = definition.description; + transport.createMetric(this); + } + update(newValue) { + this.value = newValue; + return this.transport.updateMetric(this); + } + } + + class NumberMetric extends BaseMetric { + constructor(definition, system, transport, value) { + super(definition, system, transport, value, MetricTypes.NUMBER); + } + incrementBy(num) { + this.update(this.value + num); + } + increment() { + this.incrementBy(1); + } + decrement() { + this.incrementBy(-1); + } + decrementBy(num) { + this.incrementBy(num * -1); + } + } + + class ObjectMetric extends BaseMetric { + constructor(definition, system, transport, value) { + super(definition, system, transport, value, MetricTypes.OBJECT); + } + update(newValue) { + this.mergeValues(newValue); + return this.transport.updateMetric(this); + } + mergeValues(values) { + return Object.keys(this.value).forEach((k) => { + if (typeof values[k] !== "undefined") { + this.value[k] = values[k]; + } + }); + } + } + + class StringMetric extends BaseMetric { + constructor(definition, system, transport, value) { + super(definition, system, transport, value, MetricTypes.STRING); + } + } + + class TimestampMetric extends BaseMetric { + constructor(definition, system, transport, value) { + super(definition, system, transport, value, MetricTypes.TIMESTAMP); + } + now() { + this.update(new Date()); + } + } + + function system$1(name, repo, protocol, parent, description) { + if (!repo) { + throw new Error("Repository is required"); + } + if (!protocol) { + throw new Error("Transport is required"); + } + const _transport = protocol; + const _name = name; + const _description = description || ""; + const _repo = repo; + const _parent = parent; + const _path = _buildPath(parent); + let _state = {}; + const id = _arrayToString(_path, "/") + name; + const root = repo.root; + const _subSystems = []; + const _metrics = []; + function subSystem(nameSystem, descriptionSystem) { + if (!nameSystem || nameSystem.length === 0) { + throw new Error("name is required"); + } + const match = _subSystems.filter((s) => s.name === nameSystem); + if (match.length > 0) { + return match[0]; + } + const _system = system$1(nameSystem, _repo, _transport, me, descriptionSystem); + _subSystems.push(_system); + return _system; + } + function setState(state, stateDescription) { + _state = { state, description: stateDescription }; + _transport.updateSystem(me, _state); + } + function stringMetric(definition, value) { + return _getOrCreateMetric(definition, MetricTypes.STRING, value, (metricDef) => new StringMetric(metricDef, me, _transport, value)); + } + function numberMetric(definition, value) { + return _getOrCreateMetric(definition, MetricTypes.NUMBER, value, (metricDef) => new NumberMetric(metricDef, me, _transport, value)); + } + function objectMetric(definition, value) { + return _getOrCreateMetric(definition, MetricTypes.OBJECT, value, (metricDef) => new ObjectMetric(metricDef, me, _transport, value)); + } + function timestampMetric(definition, value) { + return _getOrCreateMetric(definition, MetricTypes.TIMESTAMP, value, (metricDef) => new TimestampMetric(metricDef, me, _transport, value)); + } + function _getOrCreateMetric(metricObject, expectedType, value, createMetric) { + let metricDef = { name: "" }; + if (typeof metricObject === "string") { + metricDef = { name: metricObject }; + } + else { + metricDef = metricObject; + } + const matching = _metrics.filter((shadowedMetric) => shadowedMetric.name === metricDef.name); + if (matching.length > 0) { + const existing = matching[0]; + if (existing.type !== expectedType) { + throw new Error(`A metric named ${metricDef.name} is already defined with different type.`); + } + if (typeof value !== "undefined") { + existing + .update(value) + .catch(() => { }); + } + return existing; + } + const metric = createMetric(metricDef); + _metrics.push(metric); + return metric; + } + function _buildPath(shadowedSystem) { + if (!shadowedSystem || !shadowedSystem.parent) { + return []; + } + const path = _buildPath(shadowedSystem.parent); + path.push(shadowedSystem.name); + return path; + } + function _arrayToString(path, separator) { + return ((path && path.length > 0) ? path.join(separator) : ""); + } + function getAggregateState() { + const aggState = []; + if (Object.keys(_state).length > 0) { + aggState.push({ + name: _name, + path: _path, + state: _state.state, + description: _state.description, + }); + } + _subSystems.forEach((shadowedSubSystem) => { + const result = shadowedSubSystem.getAggregateState(); + if (result.length > 0) { + aggState.push(...result); + } + }); + return aggState; + } + const me = { + get name() { + return _name; + }, + get description() { + return _description; + }, + get repo() { + return _repo; + }, + get parent() { + return _parent; + }, + path: _path, + id, + root, + get subSystems() { + return _subSystems; + }, + get metrics() { + return _metrics; + }, + subSystem, + getState: () => { + return _state; + }, + setState, + stringMetric, + timestampMetric, + objectMetric, + numberMetric, + getAggregateState, + }; + _transport.createSystem(me); + return me; + } + + class Repository { + root; + constructor(options, protocol) { + protocol.init(this); + this.root = system$1("", this, protocol); + this.addSystemMetrics(this.root, options.clickStream || options.clickStream === undefined); + } + addSystemMetrics(rootSystem, useClickStream) { + if (typeof navigator !== "undefined") { + rootSystem.stringMetric("UserAgent", navigator.userAgent); + } + if (useClickStream && typeof document !== "undefined") { + const clickStream = rootSystem.subSystem("ClickStream"); + const documentClickHandler = (e) => { + if (!e.target) { + return; + } + const target = e.target; + const className = target ? target.getAttribute("class") ?? "" : ""; + clickStream.objectMetric("LastBrowserEvent", { + type: "click", + timestamp: new Date(), + target: { + className, + id: target.id, + type: "<" + target.tagName.toLowerCase() + ">", + href: target.href || "", + }, + }); + }; + clickStream.objectMetric("Page", { + title: document.title, + page: window.location.href, + }); + if (document.addEventListener) { + document.addEventListener("click", documentClickHandler); + } + else { + document.attachEvent("onclick", documentClickHandler); + } + } + rootSystem.stringMetric("StartTime", (new Date()).toString()); + const urlMetric = rootSystem.stringMetric("StartURL", ""); + const appNameMetric = rootSystem.stringMetric("AppName", ""); + if (typeof window !== "undefined") { + if (typeof window.location !== "undefined") { + const startUrl = window.location.href; + urlMetric.update(startUrl); + } + if (typeof window.glue42gd !== "undefined") { + appNameMetric.update(window.glue42gd.appName); + } + } + } + } + + class NullProtocol { + init(repo) { + } + createSystem(system) { + return Promise.resolve(); + } + updateSystem(metric, state) { + return Promise.resolve(); + } + createMetric(metric) { + return Promise.resolve(); + } + updateMetric(metric) { + return Promise.resolve(); + } + } + + class PerfTracker { + api; + lastCount = 0; + initialPublishTimeout = 10 * 1000; + publishInterval = 60 * 1000; + system; + constructor(api, initialPublishTimeout, publishInterval) { + this.api = api; + this.initialPublishTimeout = initialPublishTimeout ?? this.initialPublishTimeout; + this.publishInterval = publishInterval ?? this.publishInterval; + this.scheduleCollection(); + this.system = this.api.subSystem("performance", "Performance data published by the web application"); + } + scheduleCollection() { + setTimeout(() => { + this.collect(); + setInterval(() => { + this.collect(); + }, this.publishInterval); + }, this.initialPublishTimeout); + } + collect() { + try { + this.collectMemory(); + this.collectEntries(); + } + catch { + } + } + collectMemory() { + const memory = window.performance.memory; + this.system.stringMetric("memory", JSON.stringify({ + totalJSHeapSize: memory.totalJSHeapSize, + usedJSHeapSize: memory.usedJSHeapSize + })); + } + collectEntries() { + const allEntries = window.performance.getEntries(); + if (allEntries.length <= this.lastCount) { + return; + } + this.lastCount = allEntries.length; + const jsonfiedEntries = allEntries.map((i) => i.toJSON()); + this.system.stringMetric("entries", JSON.stringify(jsonfiedEntries)); + } + } + + var metrics = (options) => { + let protocol; + if (!options.connection || typeof options.connection !== "object") { + protocol = new NullProtocol(); + } + else { + protocol = gw3(options.connection, options); + } + const repo = new Repository(options, protocol); + let rootSystem = repo.root; + if (!options.disableAutoAppSystem) { + rootSystem = rootSystem.subSystem("App"); + } + const api = addFAVSupport(rootSystem); + initPerf(api, options.pagePerformanceMetrics); + return api; + }; + function initPerf(api, config) { + if (typeof window === "undefined") { + return; + } + const perfConfig = window?.glue42gd?.metrics?.pagePerformanceMetrics; + if (perfConfig) { + config = perfConfig; + } + if (config?.enabled) { + new PerfTracker(api, config.initialPublishTimeout, config.publishInterval); + } + } + function addFAVSupport(system) { + const reportingSystem = system.subSystem("reporting"); + const def = { + name: "features" + }; + let featureMetric; + const featureMetricFunc = (name, action, payload) => { + if (typeof name === "undefined" || name === "") { + throw new Error("name is mandatory"); + } + else if (typeof action === "undefined" || action === "") { + throw new Error("action is mandatory"); + } + else if (typeof payload === "undefined" || payload === "") { + throw new Error("payload is mandatory"); + } + if (!featureMetric) { + featureMetric = reportingSystem.objectMetric(def, { name, action, payload }); + } + else { + featureMetric.update({ + name, + action, + payload + }); + } + }; + system.featureMetric = featureMetricFunc; + return system; + } + + var commonjsGlobal$1 = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; + + function getDefaultExportFromCjs$1 (x) { + return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; + } + + function createRegistry$1(options) { + if (options && options.errorHandling + && typeof options.errorHandling !== "function" + && options.errorHandling !== "log" + && options.errorHandling !== "silent" + && options.errorHandling !== "throw") { + throw new Error("Invalid options passed to createRegistry. Prop errorHandling should be [\"log\" | \"silent\" | \"throw\" | (err) => void], but " + typeof options.errorHandling + " was passed"); + } + var _userErrorHandler = options && typeof options.errorHandling === "function" && options.errorHandling; + var callbacks = {}; + function add(key, callback, replayArgumentsArr) { + var callbacksForKey = callbacks[key]; + if (!callbacksForKey) { + callbacksForKey = []; + callbacks[key] = callbacksForKey; + } + callbacksForKey.push(callback); + if (replayArgumentsArr) { + setTimeout(function () { + replayArgumentsArr.forEach(function (replayArgument) { + var _a; + if ((_a = callbacks[key]) === null || _a === void 0 ? void 0 : _a.includes(callback)) { + try { + if (Array.isArray(replayArgument)) { + callback.apply(undefined, replayArgument); + } + else { + callback.apply(undefined, [replayArgument]); + } + } + catch (err) { + _handleError(err, key); + } + } + }); + }, 0); + } + return function () { + var allForKey = callbacks[key]; + if (!allForKey) { + return; + } + allForKey = allForKey.reduce(function (acc, element, index) { + if (!(element === callback && acc.length === index)) { + acc.push(element); + } + return acc; + }, []); + if (allForKey.length === 0) { + delete callbacks[key]; + } + else { + callbacks[key] = allForKey; + } + }; + } + function execute(key) { + var argumentsArr = []; + for (var _i = 1; _i < arguments.length; _i++) { + argumentsArr[_i - 1] = arguments[_i]; + } + var callbacksForKey = callbacks[key]; + if (!callbacksForKey || callbacksForKey.length === 0) { + return []; + } + var results = []; + callbacksForKey.forEach(function (callback) { + try { + var result = callback.apply(undefined, argumentsArr); + results.push(result); + } + catch (err) { + results.push(undefined); + _handleError(err, key); + } + }); + return results; + } + function _handleError(exceptionArtifact, key) { + var errParam = exceptionArtifact instanceof Error ? exceptionArtifact : new Error(exceptionArtifact); + if (_userErrorHandler) { + _userErrorHandler(errParam); + return; + } + var msg = "[ERROR] callback-registry: User callback for key \"" + key + "\" failed: " + errParam.stack; + if (options) { + switch (options.errorHandling) { + case "log": + return console.error(msg); + case "silent": + return; + case "throw": + throw new Error(msg); + } + } + console.error(msg); + } + function clear() { + callbacks = {}; + } + function clearKey(key) { + var callbacksForKey = callbacks[key]; + if (!callbacksForKey) { + return; + } + delete callbacks[key]; + } + return { + add: add, + execute: execute, + clear: clear, + clearKey: clearKey + }; + } + createRegistry$1.default = createRegistry$1; + var lib$1 = createRegistry$1; + + + var CallbackRegistryFactory$1 = /*@__PURE__*/getDefaultExportFromCjs$1(lib$1); + + class InProcTransport { + gw; + registry = CallbackRegistryFactory$1(); + client; + constructor(settings, logger) { + this.gw = settings.facade; + this.gw.connect((_client, message) => { + this.messageHandler(message); + }).then((client) => { + this.client = client; + }); + } + get isObjectBasedTransport() { + return true; + } + sendObject(msg) { + if (this.client) { + this.client.send(msg); + return Promise.resolve(undefined); + } + else { + return Promise.reject(`not connected`); + } + } + send(_msg) { + return Promise.reject("not supported"); + } + onMessage(callback) { + return this.registry.add("onMessage", callback); + } + onConnectedChanged(callback) { + callback(true); + return () => { }; + } + close() { + return Promise.resolve(); + } + open() { + return Promise.resolve(); + } + name() { + return "in-memory"; + } + reconnect() { + return Promise.resolve(); + } + messageHandler(msg) { + this.registry.execute("onMessage", msg); + } + } + + class SharedWorkerTransport { + logger; + worker; + registry = CallbackRegistryFactory$1(); + constructor(workerFile, logger) { + this.logger = logger; + this.worker = new SharedWorker(workerFile); + this.worker.port.onmessage = (e) => { + this.messageHandler(e.data); + }; + } + get isObjectBasedTransport() { + return true; + } + sendObject(msg) { + this.worker.port.postMessage(msg); + return Promise.resolve(); + } + send(_msg) { + return Promise.reject("not supported"); + } + onMessage(callback) { + return this.registry.add("onMessage", callback); + } + onConnectedChanged(callback) { + callback(true); + return () => { }; + } + close() { + return Promise.resolve(); + } + open() { + return Promise.resolve(); + } + name() { + return "shared-worker"; + } + reconnect() { + return Promise.resolve(); + } + messageHandler(msg) { + this.registry.execute("onMessage", msg); + } + } + + let Utils$1 = class Utils { + static isNode() { + if (typeof Utils._isNode !== "undefined") { + return Utils._isNode; + } + if (typeof window !== "undefined") { + Utils._isNode = false; + return false; + } + try { + Utils._isNode = Object.prototype.toString.call(global.process) === "[object process]"; + } + catch (e) { + Utils._isNode = false; + } + return Utils._isNode; + } + static _isNode; + }; + + let PromiseWrapper$1 = class PromiseWrapper { + static delay(time) { + return new Promise((resolve) => setTimeout(resolve, time)); + } + resolve; + reject; + promise; + rejected = false; + resolved = false; + get ended() { + return this.rejected || this.resolved; + } + constructor() { + this.promise = new Promise((resolve, reject) => { + this.resolve = (t) => { + this.resolved = true; + resolve(t); + }; + this.reject = (err) => { + this.rejected = true; + reject(err); + }; + }); + } + }; + + const timers = {}; + function getAllTimers() { + return timers; + } + function timer (timerName) { + const existing = timers[timerName]; + if (existing) { + return existing; + } + const marks = []; + function now() { + return new Date().getTime(); + } + const startTime = now(); + mark("start", startTime); + let endTime; + let period; + function stop() { + endTime = now(); + mark("end", endTime); + period = endTime - startTime; + return period; + } + function mark(name, time) { + const currentTime = time ?? now(); + let diff = 0; + if (marks.length > 0) { + diff = currentTime - marks[marks.length - 1].time; + } + marks.push({ name, time: currentTime, diff }); + } + const timerObj = { + get startTime() { + return startTime; + }, + get endTime() { + return endTime; + }, + get period() { + return period; + }, + stop, + mark, + marks + }; + timers[timerName] = timerObj; + return timerObj; + } + + const WebSocketConstructor = Utils$1.isNode() ? require("ws") : window.WebSocket; + class WS { + ws; + logger; + settings; + startupTimer = timer("connection"); + _running = true; + _registry = CallbackRegistryFactory$1(); + wsRequests = []; + constructor(settings, logger) { + this.settings = settings; + this.logger = logger; + if (!this.settings.ws) { + throw new Error("ws is missing"); + } + } + onMessage(callback) { + return this._registry.add("onMessage", callback); + } + send(msg, options) { + return new Promise((resolve, reject) => { + this.waitForSocketConnection(() => { + try { + this.ws?.send(msg); + resolve(); + } + catch (e) { + reject(e); + } + }, reject); + }); + } + open() { + this.logger.info("opening ws..."); + this._running = true; + return new Promise((resolve, reject) => { + this.waitForSocketConnection(resolve, reject); + }); + } + close() { + this._running = false; + if (this.ws) { + this.ws.close(); + } + return Promise.resolve(); + } + onConnectedChanged(callback) { + return this._registry.add("onConnectedChanged", callback); + } + name() { + return this.settings.ws; + } + reconnect() { + this.ws?.close(); + const pw = new PromiseWrapper$1(); + this.waitForSocketConnection(() => { + pw.resolve(); + }); + return pw.promise; + } + waitForSocketConnection(callback, failed) { + failed = failed ?? (() => { }); + if (!this._running) { + failed(`wait for socket on ${this.settings.ws} failed - socket closed by user`); + return; + } + if (this.ws?.readyState === 1) { + callback(); + return; + } + this.wsRequests.push({ callback, failed }); + if (this.wsRequests.length > 1) { + return; + } + this.openSocket(); + } + async openSocket(retryInterval, retriesLeft) { + this.logger.info(`opening ws to ${this.settings.ws}, retryInterval: ${retryInterval}, retriesLeft: ${retriesLeft}...`); + this.startupTimer.mark("opening-socket"); + if (retryInterval === undefined) { + retryInterval = this.settings.reconnectInterval; + } + if (typeof retriesLeft === "undefined") { + retriesLeft = this.settings.reconnectAttempts; + } + if (retriesLeft !== undefined) { + if (retriesLeft === 0) { + this.notifyForSocketState(`wait for socket on ${this.settings.ws} failed - no more retries left`); + return; + } + this.logger.debug(`will retry ${retriesLeft} more times (every ${retryInterval} ms)`); + } + try { + await this.initiateSocket(); + this.startupTimer.mark("socket-initiated"); + this.notifyForSocketState(); + } + catch { + setTimeout(() => { + const retries = retriesLeft === undefined ? undefined : retriesLeft - 1; + this.openSocket(retryInterval, retries); + }, retryInterval); + } + } + initiateSocket() { + const pw = new PromiseWrapper$1(); + this.logger.debug(`initiating ws to ${this.settings.ws}...`); + this.ws = new WebSocketConstructor(this.settings.ws ?? ""); + this.ws.onerror = (err) => { + let reason = ""; + try { + reason = JSON.stringify(err); + } + catch (error) { + const seen = new WeakSet(); + const replacer = (key, value) => { + if (typeof value === "object" && value !== null) { + if (seen.has(value)) { + return; + } + seen.add(value); + } + return value; + }; + reason = JSON.stringify(err, replacer); + } + this.logger.info(`ws error - reason: ${reason}`); + pw.reject("error"); + this.notifyStatusChanged(false, reason); + }; + this.ws.onclose = (err) => { + this.logger.info(`ws closed - code: ${err?.code} reason: ${err?.reason}`); + pw.reject("closed"); + this.notifyStatusChanged(false); + }; + this.ws.onopen = () => { + this.startupTimer.mark("ws-opened"); + this.logger.info(`ws opened ${this.settings.identity?.application}`); + pw.resolve(); + this.notifyStatusChanged(true); + }; + this.ws.onmessage = (message) => { + this._registry.execute("onMessage", message.data); + }; + return pw.promise; + } + notifyForSocketState(error) { + this.wsRequests.forEach((wsRequest) => { + if (error) { + if (wsRequest.failed) { + wsRequest.failed(error); + } + } + else { + wsRequest.callback(); + } + }); + this.wsRequests = []; + } + notifyStatusChanged(status, reason) { + this._registry.execute("onConnectedChanged", status, reason); + } + } + + class MessageReplayerImpl { + specs; + specsNames = []; + messages = {}; + isDone; + subs = {}; + subsRefCount = {}; + connection; + constructor(specs) { + this.specs = {}; + for (const spec of specs) { + this.specs[spec.name] = spec; + this.specsNames.push(spec.name); + } + } + init(connection) { + this.connection = connection; + for (const name of this.specsNames) { + for (const type of this.specs[name].types) { + let refCount = this.subsRefCount[type]; + if (!refCount) { + refCount = 0; + } + refCount += 1; + this.subsRefCount[type] = refCount; + if (refCount > 1) { + continue; + } + const sub = connection.on(type, (msg) => this.processMessage(type, msg)); + this.subs[type] = sub; + } + } + } + processMessage(type, msg) { + if (this.isDone || !msg) { + return; + } + for (const name of this.specsNames) { + if (this.specs[name].types.indexOf(type) !== -1) { + const messages = this.messages[name] || []; + this.messages[name] = messages; + messages.push(msg); + } + } + } + drain(name, callback) { + if (callback) { + (this.messages[name] || []).forEach(callback); + } + delete this.messages[name]; + for (const type of this.specs[name].types) { + this.subsRefCount[type] -= 1; + if (this.subsRefCount[type] <= 0) { + this.connection?.off(this.subs[type]); + delete this.subs[type]; + delete this.subsRefCount[type]; + } + } + delete this.specs[name]; + if (!this.specs.length) { + this.isDone = true; + } + } + } + + let urlAlphabet$1 = + 'useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict'; + let nanoid$1 = (size = 21) => { + let id = ''; + let i = size; + while (i--) { + id += urlAlphabet$1[(Math.random() * 64) | 0]; + } + return id + }; + + const PromisePlus$1 = (executor, timeoutMilliseconds, timeoutMessage) => { + return new Promise((resolve, reject) => { + const timeout = setTimeout(() => { + const message = timeoutMessage || `Promise timeout hit: ${timeoutMilliseconds}`; + reject(message); + }, timeoutMilliseconds); + const providedPromise = new Promise(executor); + providedPromise + .then((result) => { + clearTimeout(timeout); + resolve(result); + }) + .catch((error) => { + clearTimeout(timeout); + reject(error); + }); + }); + }; + + class WebPlatformTransport { + settings; + logger; + identity; + isPreferredActivated; + _communicationId; + publicWindowId; + selfAssignedWindowId; + iAmConnected = false; + parentReady = false; + rejected = false; + parentPingResolve; + parentPingInterval; + connectionResolve; + extConnectionResolve; + extConnectionReject; + connectionReject; + port; + myClientId; + children = []; + extContentAvailable = false; + extContentConnecting = false; + extContentConnected = false; + parentWindowId; + parentInExtMode = false; + webNamespace = "g42_core_web"; + parent; + parentType; + parentPingTimeout = 5000; + connectionRequestTimeout = 7000; + defaultTargetString = "*"; + registry = CallbackRegistryFactory$1(); + messages = { + connectionAccepted: { name: "connectionAccepted", handle: this.handleConnectionAccepted.bind(this) }, + connectionRejected: { name: "connectionRejected", handle: this.handleConnectionRejected.bind(this) }, + connectionRequest: { name: "connectionRequest", handle: this.handleConnectionRequest.bind(this) }, + parentReady: { + name: "parentReady", handle: () => { + } + }, + parentPing: { name: "parentPing", handle: this.handleParentPing.bind(this) }, + platformPing: { name: "platformPing", handle: this.handlePlatformPing.bind(this) }, + platformReady: { name: "platformReady", handle: this.handlePlatformReady.bind(this) }, + clientUnload: { name: "clientUnload", handle: this.handleClientUnload.bind(this) }, + manualUnload: { name: "manualUnload", handle: this.handleManualUnload.bind(this) }, + extConnectionResponse: { name: "extConnectionResponse", handle: this.handleExtConnectionResponse.bind(this) }, + extSetupRequest: { name: "extSetupRequest", handle: this.handleExtSetupRequest.bind(this) }, + gatewayDisconnect: { name: "gatewayDisconnect", handle: this.handleGatewayDisconnect.bind(this) }, + gatewayInternalConnect: { name: "gatewayInternalConnect", handle: this.handleGatewayInternalConnect.bind(this) } + }; + constructor(settings, logger, identity) { + this.settings = settings; + this.logger = logger; + this.identity = identity; + this.extContentAvailable = !!window.glue42ext; + this.setUpMessageListener(); + this.setUpUnload(); + this.setupPlatformUnloadListener(); + this.parentType = window.name.includes("#wsp") ? "workspace" : undefined; + } + manualSetReadyState() { + this.iAmConnected = true; + this.parentReady = true; + } + get transportWindowId() { + return this.publicWindowId; + } + get communicationId() { + return this._communicationId; + } + async sendObject(msg) { + if (this.extContentConnected) { + return window.postMessage({ glue42ExtOut: msg }, this.defaultTargetString); + } + if (!this.port) { + throw new Error("Cannot send message, because the port was not opened yet"); + } + this.port.postMessage(msg); + } + get isObjectBasedTransport() { + return true; + } + onMessage(callback) { + return this.registry.add("onMessage", callback); + } + send() { + return Promise.reject("not supported"); + } + onConnectedChanged(callback) { + return this.registry.add("onConnectedChanged", callback); + } + async open() { + this.logger.debug("opening a connection to the web platform gateway."); + await this.connect(); + this.notifyStatusChanged(true); + } + close() { + const message = { + glue42core: { + type: this.messages.gatewayDisconnect.name, + data: { + clientId: this.myClientId, + ownWindowId: this.identity?.windowId + } + } + }; + this.port?.postMessage(message); + this.parentReady = false; + this.notifyStatusChanged(false, "manual reconnection"); + return Promise.resolve(); + } + name() { + return "web-platform"; + } + async reconnect() { + await this.close(); + return Promise.resolve(); + } + initiateInternalConnection() { + return new Promise((resolve, reject) => { + this.logger.debug("opening an internal web platform connection"); + this.port = this.settings.port; + if (this.iAmConnected) { + this.logger.warn("cannot open a new connection, because this client is currently connected"); + return; + } + this.port.onmessage = (event) => { + if (this.iAmConnected && !event.data?.glue42core) { + this.registry.execute("onMessage", event.data); + return; + } + const data = event.data?.glue42core; + if (!data) { + return; + } + if (data.type === this.messages.gatewayInternalConnect.name && data.success) { + this.publicWindowId = this.settings.windowId; + if (this.identity && this.publicWindowId) { + this.identity.windowId = this.publicWindowId; + this.identity.instance = this.publicWindowId; + } + resolve(); + } + if (data.type === this.messages.gatewayInternalConnect.name && data.error) { + reject(data.error); + } + }; + this.port.postMessage({ + glue42core: { + type: this.messages.gatewayInternalConnect.name + } + }); + }); + } + initiateRemoteConnection(target) { + return PromisePlus$1((resolve, reject) => { + this.connectionResolve = resolve; + this.connectionReject = reject; + this.myClientId = this.myClientId ?? nanoid$1(10); + const bridgeInstanceId = this.getMyWindowId() || nanoid$1(10); + const request = { + glue42core: { + type: this.messages.connectionRequest.name, + clientId: this.myClientId, + clientType: "child", + bridgeInstanceId, + selfAssignedWindowId: this.selfAssignedWindowId + } + }; + this.logger.debug("sending connection request"); + if (this.extContentConnecting) { + request.glue42core.clientType = "child"; + request.glue42core.bridgeInstanceId = this.myClientId; + request.glue42core.parentWindowId = this.parentWindowId; + return window.postMessage(request, this.defaultTargetString); + } + if (!target) { + throw new Error("Cannot send a connection request, because no glue target was specified!"); + } + target.postMessage(request, this.defaultTargetString); + }, this.connectionRequestTimeout, "The connection to the target glue window timed out"); + } + async isParentCheckSuccess(parentCheck) { + try { + await parentCheck; + return { success: true }; + } + catch (error) { + return { success: false }; + } + } + setUpMessageListener() { + if (this.settings.port) { + this.logger.debug("skipping generic message listener, because this is an internal client"); + return; + } + window.addEventListener("message", (event) => { + const data = event.data?.glue42core; + if (!data || this.rejected) { + return; + } + const allowedOrigins = this.settings.allowedOrigins || []; + if (allowedOrigins.length && !allowedOrigins.includes(event.origin)) { + this.logger.warn(`received a message from an origin which is not in the allowed list: ${event.origin}`); + return; + } + if (!this.checkMessageTypeValid(data.type)) { + this.logger.error(`cannot handle the incoming glue42 core message, because the type is invalid: ${data.type}`); + return; + } + const messageType = data.type; + this.logger.debug(`received valid glue42core message of type: ${messageType}`); + this.messages[messageType].handle(event); + }); + } + setUpUnload() { + if (this.settings.port) { + this.logger.debug("skipping unload event listener, because this is an internal client"); + return; + } + window.addEventListener("beforeunload", () => { + if (this.extContentConnected) { + return; + } + const message = { + glue42core: { + type: this.messages.clientUnload.name, + data: { + clientId: this.myClientId, + ownWindowId: this.identity?.windowId + } + } + }; + if (this.parent) { + this.parent.postMessage(message, this.defaultTargetString); + } + this.port?.postMessage(message); + }); + } + handlePlatformReady(event) { + this.logger.debug("the web platform gave the ready signal"); + this.parentReady = true; + if (this.parentPingResolve) { + this.parentPingResolve(); + delete this.parentPingResolve; + } + if (this.parentPingInterval) { + clearInterval(this.parentPingInterval); + delete this.parentPingInterval; + } + this.parent = event.source; + this.parentType = window.name.includes("#wsp") ? "workspace" : "window"; + } + handleConnectionAccepted(event) { + const data = event.data?.glue42core; + if (this.myClientId === data.clientId) { + return this.handleAcceptanceOfMyRequest(data); + } + return this.handleAcceptanceOfGrandChildRequest(data, event); + } + handleAcceptanceOfMyRequest(data) { + this.logger.debug("handling a connection accepted signal targeted at me."); + this.isPreferredActivated = data.isPreferredActivated; + if (this.extContentConnecting) { + return this.processExtContentConnection(data); + } + if (!data.port) { + this.logger.error("cannot set up my connection, because I was not provided with a port"); + return; + } + this.publicWindowId = this.getMyWindowId(); + if (this.identity) { + this.identity.windowId = this.publicWindowId; + this.identity.instance = this.identity.instance ? this.identity.instance : this.publicWindowId || nanoid$1(10); + } + if (this.identity && data.appName) { + this.identity.application = data.appName; + this.identity.applicationName = data.appName; + } + this._communicationId = data.communicationId; + this.port = data.port; + this.port.onmessage = (e) => this.registry.execute("onMessage", e.data); + if (this.connectionResolve) { + this.logger.debug("my connection is set up, calling the connection resolve."); + this.connectionResolve(); + delete this.connectionResolve; + return; + } + this.logger.error("unable to call the connection resolve, because no connection promise was found"); + } + processExtContentConnection(data) { + this.logger.debug("handling a connection accepted signal targeted at me for extension content connection."); + this.extContentConnecting = false; + this.extContentConnected = true; + this.publicWindowId = this.parentWindowId || this.myClientId; + if (this.extContentConnecting && this.identity) { + this.identity.windowId = this.publicWindowId; + } + if (this.identity && data.appName) { + this.identity.application = data.appName; + this.identity.applicationName = data.appName; + } + window.addEventListener("message", (event) => { + const extData = event.data?.glue42ExtInc; + if (!extData) { + return; + } + const allowedOrigins = this.settings.allowedOrigins || []; + if (allowedOrigins.length && !allowedOrigins.includes(event.origin)) { + this.logger.warn(`received a message from an origin which is not in the allowed list: ${event.origin}`); + return; + } + this.registry.execute("onMessage", extData); + }); + if (this.connectionResolve) { + this.logger.debug("my connection is set up, calling the connection resolve."); + this.connectionResolve(); + delete this.connectionResolve; + return; + } + } + handleAcceptanceOfGrandChildRequest(data, event) { + if (this.extContentConnecting || this.extContentConnected) { + this.logger.debug("cannot process acceptance of a grandchild, because I am connected to a content script"); + return; + } + this.logger.debug(`handling a connection accepted signal targeted at a grandchild: ${data.clientId}`); + const child = this.children.find((c) => c.grandChildId === data.clientId); + if (!child) { + this.logger.error(`cannot handle connection accepted for grandchild: ${data.clientId}, because there is no grandchild with this id`); + return; + } + child.connected = true; + this.logger.debug(`the grandchild connection for ${data.clientId} is set up, forwarding the success message and the gateway port`); + data.parentWindowId = this.publicWindowId; + child.source.postMessage(event.data, child.origin, [data.port]); + return; + } + handleConnectionRejected(event) { + this.logger.debug("handling a connection rejection. Most likely the reason is that this window was not created by a glue API call"); + if (!this.connectionReject) { + return; + } + const errorMsg = typeof event.data.glue42core?.error === "string" + ? `Connection was rejected. ${event.data.glue42core?.error}` + : "The platform connection was rejected. Most likely because this window was not created by a glue API call"; + this.connectionReject(errorMsg); + delete this.connectionReject; + } + handleConnectionRequest(event) { + if (this.extContentConnecting) { + this.logger.debug("This connection request event is targeted at the extension content"); + return; + } + const source = event.source; + const data = event.data.glue42core; + if (!data.clientType || data.clientType !== "grandChild") { + return this.rejectConnectionRequest(source, event.origin, "rejecting a connection request, because the source was not opened by a glue API call"); + } + if (!data.clientId) { + return this.rejectConnectionRequest(source, event.origin, "rejecting a connection request, because the source did not provide a valid id"); + } + if (!this.parent) { + return this.rejectConnectionRequest(source, event.origin, "Cannot forward the connection request, because no direct connection to the platform was found"); + } + this.logger.debug(`handling a connection request for a grandchild: ${data.clientId}`); + this.children.push({ grandChildId: data.clientId, source, connected: false, origin: event.origin }); + this.logger.debug(`grandchild: ${data.clientId} is prepared, forwarding connection request to the platform`); + this.parent.postMessage(event.data, this.defaultTargetString); + } + handleParentPing(event) { + if (!this.parentReady) { + this.logger.debug("my parent is not ready, I am ignoring the parent ping"); + return; + } + if (!this.iAmConnected) { + this.logger.debug("i am not fully connected yet, I am ignoring the parent ping"); + return; + } + const message = { + glue42core: { + type: this.messages.parentReady.name + } + }; + if (this.extContentConnected) { + message.glue42core.extMode = { windowId: this.myClientId }; + } + const source = event.source; + this.logger.debug("responding to a parent ping with a ready message"); + source.postMessage(message, event.origin); + } + setupPlatformUnloadListener() { + this.onMessage((msg) => { + if (msg.type === "platformUnload") { + this.logger.debug("detected a web platform unload"); + this.parentReady = false; + this.notifyStatusChanged(false, "Gateway unloaded"); + } + }); + } + handleManualUnload() { + const message = { + glue42core: { + type: this.messages.clientUnload.name, + data: { + clientId: this.myClientId, + ownWindowId: this.identity?.windowId + } + } + }; + if (this.extContentConnected) { + return window.postMessage({ glue42ExtOut: message }, this.defaultTargetString); + } + this.port?.postMessage(message); + } + handleClientUnload(event) { + const data = event.data.glue42core; + const clientId = data?.data.clientId; + if (!clientId) { + this.logger.warn("cannot process grand child unload, because the provided id was not valid"); + return; + } + const foundChild = this.children.find((child) => child.grandChildId === clientId); + if (!foundChild) { + this.logger.warn("cannot process grand child unload, because this client is unaware of this grandchild"); + return; + } + this.logger.debug(`handling grandchild unload for id: ${clientId}`); + this.children = this.children.filter((child) => child.grandChildId !== clientId); + } + handlePlatformPing() { + return; + } + notifyStatusChanged(status, reason) { + this.iAmConnected = status; + this.registry.execute("onConnectedChanged", status, reason); + } + checkMessageTypeValid(typeToValidate) { + return typeof typeToValidate === "string" && !!this.messages[typeToValidate]; + } + rejectConnectionRequest(source, origin, reason) { + this.rejected = true; + this.logger.error(reason); + const rejection = { + glue42core: { + type: this.messages.connectionRejected.name + } + }; + source.postMessage(rejection, origin); + } + requestConnectionPermissionFromExt() { + return this.waitForContentScript() + .then(() => PromisePlus$1((resolve, reject) => { + this.extConnectionResolve = resolve; + this.extConnectionReject = reject; + const message = { + glue42core: { + type: "extSetupRequest" + } + }; + this.logger.debug("permission request to the extension content script was sent"); + window.postMessage(message, this.defaultTargetString); + }, this.parentPingTimeout, "Cannot initialize glue, because this app was not opened or created by a Glue Client and the request for extension connection timed out")); + } + handleExtConnectionResponse(event) { + const data = event.data?.glue42core; + if (!data.approved) { + return this.extConnectionReject ? this.extConnectionReject("Cannot initialize glue, because this app was not opened or created by a Glue Client and the request for extension connection was rejected") : undefined; + } + if (this.extConnectionResolve) { + this.extConnectionResolve(); + delete this.extConnectionResolve; + } + this.extContentConnecting = true; + this.parentType = "extension"; + this.logger.debug("The extension connection was approved, proceeding."); + } + handleExtSetupRequest() { + return; + } + handleGatewayDisconnect() { + return; + } + handleGatewayInternalConnect() { + return; + } + waitForContentScript() { + const contentReady = !!window.glue42ext?.content; + if (contentReady) { + return Promise.resolve(); + } + return PromisePlus$1((resolve) => { + window.addEventListener("Glue42EXTReady", () => { + resolve(); + }); + }, this.connectionRequestTimeout, "The content script was available, but was never heard to be ready"); + } + async connect() { + if (this.settings.port) { + await this.initiateInternalConnection(); + this.logger.debug("internal web platform connection completed"); + return; + } + this.logger.debug("opening a client web platform connection"); + await this.findParent(); + await this.initiateRemoteConnection(this.parent); + this.logger.debug("the client is connected"); + } + async findParent() { + const connectionNotPossibleMsg = "Cannot initiate glue, because this window was not opened or created by a glue client"; + const myInsideParents = this.getPossibleParentsInWindow(window); + const myOutsideParents = this.getPossibleParentsOutsideWindow(window.top?.opener, window.top); + const uniqueParents = new Set([...myInsideParents, ...myOutsideParents]); + if (!uniqueParents.size && !this.extContentAvailable) { + throw new Error(connectionNotPossibleMsg); + } + if (!uniqueParents.size && this.extContentAvailable) { + await this.requestConnectionPermissionFromExt(); + return; + } + const defaultParentCheck = await this.isParentCheckSuccess(this.confirmParent(Array.from(uniqueParents))); + if (defaultParentCheck.success) { + this.logger.debug("The default parent was found!"); + return; + } + if (!this.extContentAvailable) { + throw new Error(connectionNotPossibleMsg); + } + await this.requestConnectionPermissionFromExt(); + } + getPossibleParentsInWindow(currentWindow) { + return (!currentWindow?.parent || currentWindow === currentWindow.parent) ? [] : [currentWindow.parent, ...this.getPossibleParentsInWindow(currentWindow.parent)]; + } + getPossibleParentsOutsideWindow(opener, current) { + return (!opener || !current || opener === current) ? [] : [opener, ...this.getPossibleParentsInWindow(opener), ...this.getPossibleParentsOutsideWindow(opener.opener, opener)]; + } + confirmParent(targets) { + const connectionNotPossibleMsg = "Cannot initiate glue, because this window was not opened or created by a glue client"; + const parentCheck = PromisePlus$1((resolve) => { + this.parentPingResolve = resolve; + const message = { + glue42core: { + type: this.messages.platformPing.name + } + }; + this.parentPingInterval = setInterval(() => { + targets.forEach((target) => { + target.postMessage(message, this.defaultTargetString); + }); + }, 1000); + }, this.parentPingTimeout, connectionNotPossibleMsg); + parentCheck.catch(() => { + if (this.parentPingInterval) { + clearInterval(this.parentPingInterval); + delete this.parentPingInterval; + } + }); + return parentCheck; + } + getMyWindowId() { + if (this.parentType === "workspace") { + return window.name.substring(0, window.name.indexOf("#wsp")); + } + if (window !== window.top) { + return; + } + if (window.name?.includes("g42")) { + return window.name; + } + this.selfAssignedWindowId = this.selfAssignedWindowId || `g42-${nanoid$1(10)}`; + return this.selfAssignedWindowId; + } + } + + const waitForInvocations = (invocations, callback) => { + let left = invocations; + return () => { + left--; + if (left === 0) { + callback(); + } + }; + }; + + class AsyncSequelizer { + minSequenceInterval; + queue = []; + isExecutingQueue = false; + constructor(minSequenceInterval = 0) { + this.minSequenceInterval = minSequenceInterval; + } + enqueue(action) { + return new Promise((resolve, reject) => { + this.queue.push({ action, resolve, reject }); + this.executeQueue(); + }); + } + async executeQueue() { + if (this.isExecutingQueue) { + return; + } + this.isExecutingQueue = true; + while (this.queue.length) { + const operation = this.queue.shift(); + if (!operation) { + this.isExecutingQueue = false; + return; + } + try { + const actionResult = await operation.action(); + operation.resolve(actionResult); + } + catch (error) { + operation.reject(error); + } + await this.intervalBreak(); + } + this.isExecutingQueue = false; + } + intervalBreak() { + return new Promise((res) => setTimeout(res, this.minSequenceInterval)); + } + } + + function domainSession (domain, connection, logger, successMessages, errorMessages) { + if (domain == null) { + domain = "global"; + } + successMessages = successMessages ?? ["success"]; + errorMessages = errorMessages ?? ["error"]; + let isJoined = domain === "global"; + let tryReconnecting = false; + let _latestOptions; + let _connectionOn = false; + const callbacks = CallbackRegistryFactory$1(); + connection.disconnected(handleConnectionDisconnected); + connection.loggedIn(handleConnectionLoggedIn); + connection.on("success", (msg) => handleSuccessMessage(msg)); + connection.on("error", (msg) => handleErrorMessage(msg)); + connection.on("result", (msg) => handleSuccessMessage(msg)); + if (successMessages) { + successMessages.forEach((sm) => { + connection.on(sm, (msg) => handleSuccessMessage(msg)); + }); + } + if (errorMessages) { + errorMessages.forEach((sm) => { + connection.on(sm, (msg) => handleErrorMessage(msg)); + }); + } + const requestsMap = {}; + function join(options) { + _latestOptions = options; + return new Promise((resolve, reject) => { + if (isJoined) { + resolve({}); + return; + } + let joinPromise; + if (domain === "global") { + joinPromise = _connectionOn ? Promise.resolve({}) : Promise.reject("not connected to gateway"); + } + else { + logger.debug(`joining domain ${domain}`); + const joinMsg = { + type: "join", + destination: domain, + domain: "global", + options, + }; + joinPromise = send(joinMsg); + } + joinPromise + .then(() => { + handleJoined(); + resolve({}); + }) + .catch((err) => { + logger.debug("error joining " + domain + " domain: " + JSON.stringify(err)); + reject(err); + }); + }); + } + function leave() { + if (domain === "global") { + return Promise.resolve(); + } + logger.debug("stopping session " + domain + "..."); + const leaveMsg = { + type: "leave", + destination: domain, + domain: "global", + }; + tryReconnecting = false; + return send(leaveMsg) + .then(() => { + isJoined = false; + callbacks.execute("onLeft"); + }) + .catch(() => { + isJoined = false; + callbacks.execute("onLeft"); + }); + } + function handleJoined() { + logger.debug("did join " + domain); + isJoined = true; + const wasReconnect = tryReconnecting; + tryReconnecting = false; + callbacks.execute("onJoined", wasReconnect); + } + function handleConnectionDisconnected() { + _connectionOn = false; + logger.debug("connection is down"); + isJoined = false; + tryReconnecting = true; + callbacks.execute("onLeft", { disconnected: true }); + } + function handleConnectionLoggedIn() { + _connectionOn = true; + if (tryReconnecting) { + logger.debug("connection is now up - trying to reconnect..."); + join(_latestOptions); + } + } + function onJoined(callback) { + if (isJoined) { + callback(false); + } + return callbacks.add("onJoined", callback); + } + function onLeft(callback) { + if (!isJoined) { + callback(); + } + return callbacks.add("onLeft", callback); + } + function handleErrorMessage(msg) { + if (domain !== msg.domain) { + return; + } + const requestId = msg.request_id; + if (!requestId) { + return; + } + const entry = requestsMap[requestId]; + if (!entry) { + return; + } + entry.error(msg); + } + function handleSuccessMessage(msg) { + if (msg.domain !== domain) { + return; + } + const requestId = msg.request_id; + if (!requestId) { + return; + } + const entry = requestsMap[requestId]; + if (!entry) { + return; + } + entry.success(msg); + } + function getNextRequestId() { + return nanoid$1(10); + } + let queuedCalls = []; + function send(msg, tag, options) { + const ignore = ["hello", "join"]; + if (msg.type && ignore.indexOf(msg.type) === -1) { + if (!isJoined) { + console.warn(`trying to send a message (${msg.domain} ${msg.type}) but not connected, will queue`); + const pw = new PromiseWrapper$1(); + queuedCalls.push({ msg, tag, options, pw }); + if (queuedCalls.length === 1) { + const unsubscribe = onJoined(() => { + logger.info(`joined - will now send queued messages (${queuedCalls.length} -> [${queuedCalls.map((m) => m.msg.type)}])`); + queuedCalls.forEach((qm) => { + send(qm.msg, qm.tag, qm.options) + .then((t) => qm.pw.resolve(t)) + .catch((e) => qm.pw.reject(e)); + }); + queuedCalls = []; + unsubscribe(); + }); + } + return pw.promise; + } + } + options = options ?? {}; + msg.request_id = msg.request_id ?? getNextRequestId(); + msg.domain = msg.domain ?? domain; + if (!options.skipPeerId) { + msg.peer_id = connection.peerId; + } + const requestId = msg.request_id; + return new Promise((resolve, reject) => { + requestsMap[requestId] = { + success: (successMsg) => { + delete requestsMap[requestId]; + successMsg._tag = tag; + resolve(successMsg); + }, + error: (errorMsg) => { + logger.warn(`Gateway error - ${JSON.stringify(errorMsg)}`); + delete requestsMap[requestId]; + errorMsg._tag = tag; + reject(errorMsg); + }, + }; + connection + .send(msg, options) + .catch((err) => { + requestsMap[requestId].error({ err }); + }); + }); + } + function sendFireAndForget(msg) { + msg.request_id = msg.request_id ? msg.request_id : getNextRequestId(); + msg.domain = msg.domain ?? domain; + msg.peer_id = connection.peerId; + return connection.send(msg); + } + return { + join, + leave, + onJoined, + onLeft, + send, + sendFireAndForget, + on: (type, callback) => { + connection.on(type, (msg) => { + if (msg.domain !== domain) { + return; + } + try { + callback(msg); + } + catch (e) { + logger.error(`Callback failed: ${e} \n ${e.stack} \n msg was: ${JSON.stringify(msg)}`, e); + } + }); + }, + loggedIn: (callback) => connection.loggedIn(callback), + connected: (callback) => connection.connected(callback), + disconnected: (callback) => connection.disconnected(callback), + get peerId() { + return connection.peerId; + }, + get domain() { + return domain; + }, + }; + } + + class Connection { + settings; + logger; + protocolVersion = 3; + peerId; + token; + info; + resolvedIdentity; + availableDomains; + gatewayToken; + replayer; + messageHandlers = {}; + ids = 1; + registry = CallbackRegistryFactory$1(); + _connected = false; + isTrace = false; + transport; + _defaultTransport; + _defaultAuth; + _targetTransport; + _targetAuth; + _swapTransport = false; + _switchInProgress = false; + _transportSubscriptions = []; + datePrefix = "#T42_DATE#"; + datePrefixLen = this.datePrefix.length; + dateMinLen = this.datePrefixLen + 1; + datePrefixFirstChar = this.datePrefix[0]; + _sequelizer = new AsyncSequelizer(); + _isLoggedIn = false; + shouldTryLogin = true; + pingTimer; + sessions = []; + globalDomain; + initialLogin = true; + initialLoginAttempts = 3; + loginConfig; + constructor(settings, logger) { + this.settings = settings; + this.logger = logger; + settings = settings || {}; + settings.reconnectAttempts = settings.reconnectAttempts ?? 10; + settings.reconnectInterval = settings.reconnectInterval ?? 1000; + if (settings.inproc) { + this.transport = new InProcTransport(settings.inproc, logger.subLogger("inMemory")); + } + else if (settings.sharedWorker) { + this.transport = new SharedWorkerTransport(settings.sharedWorker, logger.subLogger("shared-worker")); + } + else if (settings.webPlatform) { + this.transport = new WebPlatformTransport(settings.webPlatform, logger.subLogger("web-platform"), settings.identity); + } + else if (settings.ws !== undefined) { + this.transport = new WS(settings, logger.subLogger("ws")); + } + else { + throw new Error("No connection information specified"); + } + this.isTrace = logger.canPublish("trace"); + logger.debug(`starting with ${this.transport.name()} transport`); + const unsubConnectionChanged = this.transport.onConnectedChanged(this.handleConnectionChanged.bind(this)); + const unsubOnMessage = this.transport.onMessage(this.handleTransportMessage.bind(this)); + this._transportSubscriptions.push(unsubConnectionChanged); + this._transportSubscriptions.push(unsubOnMessage); + this._defaultTransport = this.transport; + this.ping(); + } + async switchTransport(settings) { + return this._sequelizer.enqueue(async () => { + if (!settings || typeof settings !== "object") { + throw new Error("Cannot switch transports, because the settings are missing or invalid."); + } + if (typeof settings.type === "undefined") { + throw new Error("Cannot switch the transport, because the type is not defined"); + } + this.logger.trace(`Starting transport switch with settings: ${JSON.stringify(settings)}`); + const switchTargetTransport = settings.type === "secondary" ? this.getNewSecondaryTransport(settings) : this._defaultTransport; + this._targetTransport = switchTargetTransport; + this._targetAuth = settings.type === "secondary" ? this.getNewSecondaryAuth(settings) : this._defaultAuth; + const verifyPromise = this.verifyConnection(); + this._swapTransport = true; + this._switchInProgress = true; + this.logger.trace("The new transport has been set, closing the current transport"); + await this.transport.close(); + try { + await verifyPromise; + const isSwitchSuccess = this.transport === switchTargetTransport; + this.logger.info(`The reconnection after the switch was completed. Was the switch a success: ${isSwitchSuccess}`); + this._switchInProgress = false; + return { success: isSwitchSuccess }; + } + catch (error) { + this.logger.info("The reconnection after the switch timed out, reverting back to the default transport."); + this.switchTransport({ type: "default" }); + this._switchInProgress = false; + return { success: false }; + } + }); + } + onLibReAnnounced(callback) { + return this.registry.add("libReAnnounced", callback); + } + setLibReAnnounced(lib) { + this.registry.execute("libReAnnounced", lib); + } + send(message, options) { + if (this.transport.sendObject && + this.transport.isObjectBasedTransport) { + const msg = this.createObjectMessage(message); + if (this.isTrace) { + this.logger.trace(`>> ${JSON.stringify(msg)}`); + } + return this.transport.sendObject(msg, options); + } + else { + const strMessage = this.createStringMessage(message); + if (this.isTrace) { + this.logger.trace(`>> ${strMessage}`); + } + return this.transport.send(strMessage, options); + } + } + on(type, messageHandler) { + type = type.toLowerCase(); + if (this.messageHandlers[type] === undefined) { + this.messageHandlers[type] = {}; + } + const id = this.ids++; + this.messageHandlers[type][id] = messageHandler; + return { + type, + id, + }; + } + off(info) { + delete this.messageHandlers[info.type.toLowerCase()][info.id]; + } + get isConnected() { + return this._isLoggedIn; + } + connected(callback) { + return this.loggedIn(() => { + const currentServer = this.transport.name(); + callback(currentServer); + }); + } + disconnected(callback) { + return this.registry.add("disconnected", callback); + } + async login(authRequest, reconnect) { + if (!this._defaultAuth) { + this._defaultAuth = authRequest; + } + if (this._swapTransport) { + this.logger.trace("Detected a transport swap, swapping transports"); + const newAuth = this.transportSwap(); + authRequest = newAuth ?? authRequest; + } + this.logger.trace(`Starting login for transport: ${this.transport.name()} and auth ${JSON.stringify(authRequest)}`); + try { + await this.transport.open(); + this.logger.trace(`Transport: ${this.transport.name()} opened, logging in`); + timer("connection").mark("transport-opened"); + const identity = await this.loginCore(authRequest, reconnect); + this.logger.trace(`Logged in with identity: ${JSON.stringify(identity)}`); + timer("connection").mark("protocol-logged-in"); + return identity; + } + catch (error) { + if (this._switchInProgress) { + this.logger.trace("An error while logging in after a transport swap, preparing a default swap."); + this.prepareDefaultSwap(); + } + throw new Error(error); + } + } + async logout() { + await this.logoutCore(); + await this.transport.close(); + } + loggedIn(callback) { + if (this._isLoggedIn) { + callback(); + } + return this.registry.add("onLoggedIn", callback); + } + domain(domain, successMessages, errorMessages) { + let session = this.sessions.find((s) => s.domain === domain); + if (!session) { + session = domainSession(domain, this, this.logger.subLogger(`domain=${domain}`), successMessages, errorMessages); + this.sessions.push(session); + } + return session; + } + authToken() { + const createTokenReq = { + domain: "global", + type: "create-token" + }; + if (!this.globalDomain) { + return Promise.reject(new Error("no global domain session")); + } + return this.globalDomain.send(createTokenReq) + .then((res) => { + return res.token; + }); + } + reconnect() { + return this.transport.reconnect(); + } + setLoggedIn(value) { + this._isLoggedIn = value; + if (this._isLoggedIn) { + this.registry.execute("onLoggedIn"); + } + } + distributeMessage(message, type) { + const handlers = this.messageHandlers[type.toLowerCase()]; + if (handlers !== undefined) { + Object.keys(handlers).forEach((handlerId) => { + const handler = handlers[handlerId]; + if (handler !== undefined) { + try { + handler(message); + } + catch (error) { + try { + this.logger.error(`Message handler failed with ${error.stack}`, error); + } + catch (loggerError) { + console.log("Message handler failed", error); + } + } + } + }); + } + } + handleConnectionChanged(connected) { + if (this._connected === connected) { + return; + } + this._connected = connected; + if (connected) { + if (this.settings?.replaySpecs?.length) { + this.replayer = new MessageReplayerImpl(this.settings.replaySpecs); + this.replayer.init(this); + } + this.registry.execute("connected"); + } + else { + this.handleDisconnected(); + this.registry.execute("disconnected"); + } + } + handleDisconnected() { + this.setLoggedIn(false); + const tryToLogin = this.shouldTryLogin; + if (tryToLogin && this.initialLogin) { + if (this.initialLoginAttempts <= 0) { + return; + } + this.initialLoginAttempts--; + } + this.logger.debug("disconnected - will try new login?" + this.shouldTryLogin); + if (this.shouldTryLogin) { + if (!this.loginConfig) { + throw new Error("no login info"); + } + this.login(this.loginConfig, true) + .catch(() => { + setTimeout(this.handleDisconnected.bind(this), this.settings.reconnectInterval || 1000); + }); + } + } + handleTransportMessage(msg) { + let msgObj; + if (typeof msg === "string") { + msgObj = this.processStringMessage(msg); + } + else { + msgObj = this.processObjectMessage(msg); + } + if (this.isTrace) { + this.logger.trace(`<< ${JSON.stringify(msgObj)}`); + } + this.distributeMessage(msgObj.msg, msgObj.msgType); + } + verifyConnection() { + return PromisePlus$1((resolve) => { + let unsub; + const ready = waitForInvocations(2, () => { + if (unsub) { + unsub(); + } + resolve(); + }); + unsub = this.onLibReAnnounced((lib) => { + if (lib.name === "interop") { + return ready(); + } + if (lib.name === "contexts") { + return ready(); + } + }); + }, 10000, "Transport switch timed out waiting for all libraries to be re-announced"); + } + getNewSecondaryTransport(settings) { + if (!settings.transportConfig?.url) { + throw new Error("Missing secondary transport URL."); + } + return new WS(Object.assign({}, this.settings, { ws: settings.transportConfig.url, reconnectAttempts: 1 }), this.logger.subLogger("ws-secondary")); + } + getNewSecondaryAuth(settings) { + if (!settings.transportConfig?.auth) { + throw new Error("Missing secondary transport auth information."); + } + return settings.transportConfig.auth; + } + transportSwap() { + this._swapTransport = false; + if (!this._targetTransport || !this._targetAuth) { + this.logger.warn(`Error while switching transports - either the target transport or auth is not defined: transport defined -> ${!!this._defaultTransport}, auth defined -> ${!!this._targetAuth}. Staying on the current one.`); + return; + } + this._transportSubscriptions.forEach((unsub) => unsub()); + this._transportSubscriptions = []; + this.transport = this._targetTransport; + const unsubConnectionChanged = this.transport.onConnectedChanged(this.handleConnectionChanged.bind(this)); + const unsubOnMessage = this.transport.onMessage(this.handleTransportMessage.bind(this)); + this._transportSubscriptions.push(unsubConnectionChanged); + this._transportSubscriptions.push(unsubOnMessage); + return this._targetAuth; + } + prepareDefaultSwap() { + this._transportSubscriptions.forEach((unsub) => unsub()); + this._transportSubscriptions = []; + this.transport.close().catch((error) => this.logger.warn(`Error closing the ${this.transport.name()} transport after a failed connection attempt: ${JSON.stringify(error)}`)); + this._targetTransport = this._defaultTransport; + this._targetAuth = this._defaultAuth; + this._swapTransport = true; + } + processStringMessage(message) { + const msg = JSON.parse(message, (key, value) => { + if (typeof value !== "string") { + return value; + } + if (value.length < this.dateMinLen) { + return value; + } + if (!value.startsWith(this.datePrefixFirstChar)) { + return value; + } + if (value.substring(0, this.datePrefixLen) !== this.datePrefix) { + return value; + } + try { + const milliseconds = parseInt(value.substring(this.datePrefixLen, value.length), 10); + if (isNaN(milliseconds)) { + return value; + } + return new Date(milliseconds); + } + catch (ex) { + return value; + } + }); + return { + msg, + msgType: msg.type, + }; + } + createStringMessage(message) { + const oldToJson = Date.prototype.toJSON; + try { + const datePrefix = this.datePrefix; + Date.prototype.toJSON = function () { + return datePrefix + this.getTime(); + }; + const result = JSON.stringify(message); + return result; + } + finally { + Date.prototype.toJSON = oldToJson; + } + } + processObjectMessage(message) { + if (!message.type) { + throw new Error("Object should have type property"); + } + return { + msg: message, + msgType: message.type, + }; + } + createObjectMessage(message) { + return message; + } + async loginCore(config, reconnect) { + this.logger.info("logging in..."); + this.loginConfig = config; + if (!this.loginConfig) { + this.loginConfig = { username: "", password: "" }; + } + this.shouldTryLogin = true; + const authentication = await this.setupAuthConfig(config, reconnect); + const helloMsg = { + type: "hello", + identity: this.settings.identity, + authentication + }; + if (config.sessionId) { + helloMsg.request_id = config.sessionId; + } + this.globalDomain = domainSession("global", this, this.logger.subLogger("global-domain"), [ + "welcome", + "token", + "authentication-request" + ]); + const sendOptions = { skipPeerId: true }; + if (this.initialLogin) { + sendOptions.retryInterval = this.settings.reconnectInterval; + sendOptions.maxRetries = this.settings.reconnectAttempts; + } + try { + const welcomeMsg = await this.tryAuthenticate(this.globalDomain, helloMsg, sendOptions, config); + this.initialLogin = false; + this.logger.info("login successful with peerId " + welcomeMsg.peer_id); + this.peerId = welcomeMsg.peer_id; + this.resolvedIdentity = welcomeMsg.resolved_identity; + this.availableDomains = welcomeMsg.available_domains; + if (welcomeMsg.options) { + this.token = welcomeMsg.options.access_token; + this.info = welcomeMsg.options.info; + } + this.setLoggedIn(true); + return welcomeMsg.resolved_identity; + } + catch (err) { + this.logger.error("error sending hello message - " + (err.message || err.msg || err.reason || err), err); + throw err; + } + finally { + if (config?.flowCallback && config.sessionId) { + config.flowCallback(config.sessionId, null); + } + } + } + async tryAuthenticate(globalDomain, helloMsg, sendOptions, config) { + let welcomeMsg; + while (true) { + const msg = await globalDomain.send(helloMsg, undefined, sendOptions); + if (msg.type === "authentication-request") { + const token = Buffer.from(msg.authentication.token, "base64"); + if (config.flowCallback && config.sessionId) { + helloMsg.authentication.token = + (await config.flowCallback(config.sessionId, token)) + .data + .toString("base64"); + } + helloMsg.request_id = config.sessionId; + } + else if (msg.type === "welcome") { + welcomeMsg = msg; + break; + } + else if (msg.type === "error") { + throw new Error("Authentication failed: " + msg.reason); + } + else { + throw new Error("Unexpected message type during authentication: " + msg.type); + } + } + return welcomeMsg; + } + async setupAuthConfig(config, reconnect) { + const authentication = {}; + this.gatewayToken = config.gatewayToken; + if (config.gatewayToken) { + if (reconnect) { + try { + config.gatewayToken = await this.getNewGWToken(); + } + catch (e) { + this.logger.warn(`failed to get GW token when reconnecting ${e?.message || e}`); + } + } + authentication.method = "gateway-token"; + authentication.token = config.gatewayToken; + this.gatewayToken = config.gatewayToken; + } + else if (config.flowName === "sspi") { + authentication.provider = "win"; + authentication.method = "access-token"; + if (config.flowCallback && config.sessionId) { + authentication.token = + (await config.flowCallback(config.sessionId, null)) + .data + .toString("base64"); + } + else { + throw new Error("Invalid SSPI config"); + } + } + else if (config.token) { + authentication.method = "access-token"; + authentication.token = config.token; + } + else if (config.username) { + authentication.method = "secret"; + authentication.login = config.username; + authentication.secret = config.password; + } + else if (config.provider) { + authentication.provider = config.provider; + authentication.providerContext = config.providerContext; + } + else { + throw new Error("invalid auth message" + JSON.stringify(config)); + } + return authentication; + } + async logoutCore() { + this.logger.debug("logging out..."); + this.shouldTryLogin = false; + if (this.pingTimer) { + clearTimeout(this.pingTimer); + } + const promises = this.sessions.map((session) => { + session.leave(); + }); + await Promise.all(promises); + } + getNewGWToken() { + if (typeof window !== "undefined") { + const glue42gd = window.glue42gd; + if (glue42gd) { + return glue42gd.getGWToken(); + } + } + return Promise.reject(new Error("not running in GD")); + } + ping() { + if (!this.shouldTryLogin) { + return; + } + if (this._isLoggedIn) { + this.send({ type: "ping" }); + } + this.pingTimer = setTimeout(() => { + this.ping(); + }, 30 * 1000); + } + } + + const order = ["trace", "debug", "info", "warn", "error", "off"]; + let Logger$1 = class Logger { + name; + parent; + static Interop; + static InteropMethodName = "T42.AppLogger.Log"; + static Instance; + path; + subLoggers = []; + _consoleLevel; + _publishLevel; + loggerFullName; + includeTimeAndLevel; + logFn = console; + customLogFn = false; + constructor(name, parent, logFn) { + this.name = name; + this.parent = parent; + this.name = name; + if (parent) { + this.path = `${parent.path}.${name}`; + } + else { + this.path = name; + } + this.loggerFullName = `[${this.path}]`; + this.includeTimeAndLevel = !logFn; + if (logFn) { + this.logFn = logFn; + this.customLogFn = true; + } + } + subLogger(name) { + const existingSub = this.subLoggers.filter((subLogger) => { + return subLogger.name === name; + })[0]; + if (existingSub !== undefined) { + return existingSub; + } + Object.keys(this).forEach((key) => { + if (key === name) { + throw new Error("This sub logger name is not allowed."); + } + }); + const sub = new Logger(name, this, this.customLogFn ? this.logFn : undefined); + this.subLoggers.push(sub); + return sub; + } + publishLevel(level) { + if (level) { + this._publishLevel = level; + } + return this._publishLevel || this.parent?.publishLevel(); + } + consoleLevel(level) { + if (level) { + this._consoleLevel = level; + } + return this._consoleLevel || this.parent?.consoleLevel(); + } + log(message, level, error) { + this.publishMessage(level || "info", message, error); + } + trace(message) { + this.log(message, "trace"); + } + debug(message) { + this.log(message, "debug"); + } + info(message) { + this.log(message, "info"); + } + warn(message) { + this.log(message, "warn"); + } + error(message, err) { + this.log(message, "error", err); + } + canPublish(level, compareWith) { + const levelIdx = order.indexOf(level); + const restrictionIdx = order.indexOf(compareWith || this.consoleLevel() || "trace"); + return levelIdx >= restrictionIdx; + } + publishMessage(level, message, error) { + const loggerName = this.loggerFullName; + if (level === "error" && !error) { + const e = new Error(); + if (e.stack) { + message = + message + + "\n" + + e.stack + .split("\n") + .slice(4) + .join("\n"); + } + } + if (this.canPublish(level, this.publishLevel())) { + const interop = Logger.Interop; + if (interop) { + try { + if (interop.methods({ name: Logger.InteropMethodName }).length > 0) { + const args = { + msg: message, + logger: loggerName, + level + }; + if (error && error instanceof Error) { + args.error = { + message: error.message, + stack: error.stack ?? "" + }; + } + interop.invoke(Logger.InteropMethodName, args); + } + } + catch { + } + } + } + if (this.canPublish(level)) { + let prefix = ""; + if (this.includeTimeAndLevel) { + const date = new Date(); + const time = `${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}:${date.getMilliseconds()}`; + prefix = `[${time}] [${level}] `; + } + const toPrint = `${prefix}${loggerName}: ${message}`; + switch (level) { + case "trace": + this.logFn.debug(toPrint); + break; + case "debug": + if (this.logFn.debug) { + this.logFn.debug(toPrint); + } + else { + this.logFn.log(toPrint); + } + break; + case "info": + this.logFn.info(toPrint); + break; + case "warn": + this.logFn.warn(toPrint); + break; + case "error": + this.logFn.error(toPrint, error); + break; + } + } + } + }; + + const GW_MESSAGE_CREATE_CONTEXT = "create-context"; + const GW_MESSAGE_ACTIVITY_CREATED = "created"; + const GW_MESSAGE_ACTIVITY_DESTROYED = "destroyed"; + const GW_MESSAGE_CONTEXT_CREATED = "context-created"; + const GW_MESSAGE_CONTEXT_ADDED = "context-added"; + const GW_MESSAGE_SUBSCRIBE_CONTEXT = "subscribe-context"; + const GW_MESSAGE_SUBSCRIBED_CONTEXT = "subscribed-context"; + const GW_MESSAGE_UNSUBSCRIBE_CONTEXT = "unsubscribe-context"; + const GW_MESSAGE_DESTROY_CONTEXT = "destroy-context"; + const GW_MESSAGE_CONTEXT_DESTROYED = "context-destroyed"; + const GW_MESSAGE_UPDATE_CONTEXT = "update-context"; + const GW_MESSAGE_CONTEXT_UPDATED = "context-updated"; + const GW_MESSAGE_JOINED_ACTIVITY = "joined"; + + const ContextMessageReplaySpec = { + get name() { + return "context"; + }, + get types() { + return [ + GW_MESSAGE_CREATE_CONTEXT, + GW_MESSAGE_ACTIVITY_CREATED, + GW_MESSAGE_ACTIVITY_DESTROYED, + GW_MESSAGE_CONTEXT_CREATED, + GW_MESSAGE_CONTEXT_ADDED, + GW_MESSAGE_SUBSCRIBE_CONTEXT, + GW_MESSAGE_SUBSCRIBED_CONTEXT, + GW_MESSAGE_UNSUBSCRIBE_CONTEXT, + GW_MESSAGE_DESTROY_CONTEXT, + GW_MESSAGE_CONTEXT_DESTROYED, + GW_MESSAGE_UPDATE_CONTEXT, + GW_MESSAGE_CONTEXT_UPDATED, + GW_MESSAGE_JOINED_ACTIVITY + ]; + } + }; + + var version$1 = "6.5.2-fmr-beta"; + + function prepareConfig$1 (configuration, ext, glue42gd) { + let nodeStartingContext; + if (Utils$1.isNode()) { + const startingContextString = process.env._GD_STARTING_CONTEXT_; + if (startingContextString) { + try { + nodeStartingContext = JSON.parse(startingContextString); + } + catch { + } + } + } + function getConnection() { + const gwConfig = configuration.gateway; + const protocolVersion = gwConfig?.protocolVersion ?? 3; + const reconnectInterval = gwConfig?.reconnectInterval; + const reconnectAttempts = gwConfig?.reconnectAttempts; + const defaultWs = "ws://localhost:8385"; + let ws = gwConfig?.ws; + const sharedWorker = gwConfig?.sharedWorker; + const inproc = gwConfig?.inproc; + const webPlatform = gwConfig?.webPlatform ?? undefined; + if (glue42gd) { + ws = glue42gd.gwURL; + } + if (Utils$1.isNode() && nodeStartingContext && nodeStartingContext.gwURL) { + ws = nodeStartingContext.gwURL; + } + if (!ws && !sharedWorker && !inproc) { + ws = defaultWs; + } + let instanceId; + let windowId; + let pid; + let environment; + let region; + const appName = getApplication(); + let uniqueAppName = appName; + if (typeof glue42gd !== "undefined") { + windowId = glue42gd.windowId; + pid = glue42gd.pid; + if (glue42gd.env) { + environment = glue42gd.env.env; + region = glue42gd.env.region; + } + uniqueAppName = glue42gd.application ?? "glue-app"; + instanceId = glue42gd.appInstanceId; + } + else if (Utils$1.isNode()) { + pid = process.pid; + if (nodeStartingContext) { + environment = nodeStartingContext.env; + region = nodeStartingContext.region; + instanceId = nodeStartingContext.instanceId; + } + } + else if (typeof window?.glue42electron !== "undefined") { + windowId = window?.glue42electron.instanceId; + pid = window?.glue42electron.pid; + environment = window?.glue42electron.env; + region = window?.glue42electron.region; + uniqueAppName = window?.glue42electron.application ?? "glue-app"; + instanceId = window?.glue42electron.instanceId; + } + else ; + const replaySpecs = configuration.gateway?.replaySpecs ?? []; + replaySpecs.push(ContextMessageReplaySpec); + let identity = { + application: uniqueAppName, + applicationName: appName, + windowId, + instance: instanceId, + process: pid, + region, + environment, + api: ext.version || version$1 + }; + if (configuration.identity) { + identity = Object.assign(identity, configuration.identity); + } + return { + identity, + reconnectInterval, + ws, + sharedWorker, + webPlatform, + inproc, + protocolVersion, + reconnectAttempts, + replaySpecs, + }; + } + function getContexts() { + if (typeof configuration.contexts === "undefined") { + return { reAnnounceKnownContexts: true }; + } + if (typeof configuration.contexts === "boolean" && configuration.contexts) { + return { reAnnounceKnownContexts: true }; + } + if (typeof configuration.contexts === "object") { + return Object.assign({}, { reAnnounceKnownContexts: true }, configuration.contexts); + } + return false; + } + function getApplication() { + if (configuration.application) { + return configuration.application; + } + if (glue42gd) { + return glue42gd.applicationName; + } + if (typeof window !== "undefined" && typeof window.glue42electron !== "undefined") { + return window.glue42electron.application; + } + const uid = nanoid$1(10); + if (Utils$1.isNode()) { + if (nodeStartingContext) { + return nodeStartingContext.applicationConfig.name; + } + return "NodeJS" + uid; + } + if (typeof window !== "undefined" && typeof document !== "undefined") { + return document.title + ` (${uid})`; + } + return uid; + } + function getAuth() { + if (typeof configuration.auth === "string") { + return { + token: configuration.auth + }; + } + if (configuration.auth) { + return configuration.auth; + } + if (Utils$1.isNode() && nodeStartingContext && nodeStartingContext.gwToken) { + return { + gatewayToken: nodeStartingContext.gwToken + }; + } + if (configuration.gateway?.webPlatform || configuration.gateway?.inproc || configuration.gateway?.sharedWorker) { + return { + username: "glue42", password: "glue42" + }; + } + } + function getLogger() { + let config = configuration.logger; + const defaultLevel = "warn"; + if (!config) { + config = defaultLevel; + } + let gdConsoleLevel; + if (glue42gd) { + gdConsoleLevel = glue42gd.consoleLogLevel; + } + if (typeof config === "string") { + return { console: gdConsoleLevel ?? config, publish: defaultLevel }; + } + return { + console: gdConsoleLevel ?? config.console ?? defaultLevel, + publish: config.publish ?? defaultLevel + }; + } + const connection = getConnection(); + let application = getApplication(); + if (typeof window !== "undefined") { + const windowAsAny = window; + const containerApplication = windowAsAny.htmlContainer ? + `${windowAsAny.htmlContainer.containerName}.${windowAsAny.htmlContainer.application}` : + windowAsAny?.glue42gd?.application; + if (containerApplication) { + application = containerApplication; + } + } + return { + bus: configuration.bus ?? false, + application, + auth: getAuth(), + logger: getLogger(), + connection, + metrics: configuration.metrics ?? true, + contexts: getContexts(), + version: ext.version || version$1, + libs: ext.libs ?? [], + customLogger: configuration.customLogger + }; + } + + class GW3ContextData { + name; + contextId; + context; + isAnnounced; + joinedActivity; + updateCallbacks = {}; + activityId; + sentExplicitSubscription; + hasReceivedSnapshot; + constructor(contextId, name, isAnnounced, activityId) { + this.contextId = contextId; + this.name = name; + this.isAnnounced = isAnnounced; + this.activityId = activityId; + this.context = {}; + } + hasCallbacks() { + return Object.keys(this.updateCallbacks).length > 0; + } + getState() { + if (this.isAnnounced && this.hasCallbacks()) { + return 3; + } + if (this.isAnnounced) { + return 2; + } + if (this.hasCallbacks()) { + return 1; + } + return 0; + } + } + + var lodash_clonedeep = {exports: {}}; + + /** + * lodash (Custom Build) + * Build: `lodash modularize exports="npm" -o ./` + * Copyright jQuery Foundation and other contributors + * Released under MIT license + * Based on Underscore.js 1.8.3 + * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + */ + lodash_clonedeep.exports; + + (function (module, exports) { + /** Used as the size to enable large array optimizations. */ + var LARGE_ARRAY_SIZE = 200; + + /** Used to stand-in for `undefined` hash values. */ + var HASH_UNDEFINED = '__lodash_hash_undefined__'; + + /** Used as references for various `Number` constants. */ + var MAX_SAFE_INTEGER = 9007199254740991; + + /** `Object#toString` result references. */ + var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + boolTag = '[object Boolean]', + dateTag = '[object Date]', + errorTag = '[object Error]', + funcTag = '[object Function]', + genTag = '[object GeneratorFunction]', + mapTag = '[object Map]', + numberTag = '[object Number]', + objectTag = '[object Object]', + promiseTag = '[object Promise]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + symbolTag = '[object Symbol]', + weakMapTag = '[object WeakMap]'; + + var arrayBufferTag = '[object ArrayBuffer]', + dataViewTag = '[object DataView]', + float32Tag = '[object Float32Array]', + float64Tag = '[object Float64Array]', + int8Tag = '[object Int8Array]', + int16Tag = '[object Int16Array]', + int32Tag = '[object Int32Array]', + uint8Tag = '[object Uint8Array]', + uint8ClampedTag = '[object Uint8ClampedArray]', + uint16Tag = '[object Uint16Array]', + uint32Tag = '[object Uint32Array]'; + + /** + * Used to match `RegExp` + * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns). + */ + var reRegExpChar = /[\\^$.*+?()[\]{}|]/g; + + /** Used to match `RegExp` flags from their coerced string values. */ + var reFlags = /\w*$/; + + /** Used to detect host constructors (Safari). */ + var reIsHostCtor = /^\[object .+?Constructor\]$/; + + /** Used to detect unsigned integer values. */ + var reIsUint = /^(?:0|[1-9]\d*)$/; + + /** Used to identify `toStringTag` values supported by `_.clone`. */ + var cloneableTags = {}; + cloneableTags[argsTag] = cloneableTags[arrayTag] = + cloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] = + cloneableTags[boolTag] = cloneableTags[dateTag] = + cloneableTags[float32Tag] = cloneableTags[float64Tag] = + cloneableTags[int8Tag] = cloneableTags[int16Tag] = + cloneableTags[int32Tag] = cloneableTags[mapTag] = + cloneableTags[numberTag] = cloneableTags[objectTag] = + cloneableTags[regexpTag] = cloneableTags[setTag] = + cloneableTags[stringTag] = cloneableTags[symbolTag] = + cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] = + cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true; + cloneableTags[errorTag] = cloneableTags[funcTag] = + cloneableTags[weakMapTag] = false; + + /** Detect free variable `global` from Node.js. */ + var freeGlobal = typeof commonjsGlobal$1 == 'object' && commonjsGlobal$1 && commonjsGlobal$1.Object === Object && commonjsGlobal$1; + + /** Detect free variable `self`. */ + var freeSelf = typeof self == 'object' && self && self.Object === Object && self; + + /** Used as a reference to the global object. */ + var root = freeGlobal || freeSelf || Function('return this')(); + + /** Detect free variable `exports`. */ + var freeExports = exports && !exports.nodeType && exports; + + /** Detect free variable `module`. */ + var freeModule = freeExports && 'object' == 'object' && module && !module.nodeType && module; + + /** Detect the popular CommonJS extension `module.exports`. */ + var moduleExports = freeModule && freeModule.exports === freeExports; + + /** + * Adds the key-value `pair` to `map`. + * + * @private + * @param {Object} map The map to modify. + * @param {Array} pair The key-value pair to add. + * @returns {Object} Returns `map`. + */ + function addMapEntry(map, pair) { + // Don't return `map.set` because it's not chainable in IE 11. + map.set(pair[0], pair[1]); + return map; + } + + /** + * Adds `value` to `set`. + * + * @private + * @param {Object} set The set to modify. + * @param {*} value The value to add. + * @returns {Object} Returns `set`. + */ + function addSetEntry(set, value) { + // Don't return `set.add` because it's not chainable in IE 11. + set.add(value); + return set; + } + + /** + * A specialized version of `_.forEach` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns `array`. + */ + function arrayEach(array, iteratee) { + var index = -1, + length = array ? array.length : 0; + + while (++index < length) { + if (iteratee(array[index], index, array) === false) { + break; + } + } + return array; + } + + /** + * Appends the elements of `values` to `array`. + * + * @private + * @param {Array} array The array to modify. + * @param {Array} values The values to append. + * @returns {Array} Returns `array`. + */ + function arrayPush(array, values) { + var index = -1, + length = values.length, + offset = array.length; + + while (++index < length) { + array[offset + index] = values[index]; + } + return array; + } + + /** + * A specialized version of `_.reduce` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {boolean} [initAccum] Specify using the first element of `array` as + * the initial value. + * @returns {*} Returns the accumulated value. + */ + function arrayReduce(array, iteratee, accumulator, initAccum) { + var index = -1, + length = array ? array.length : 0; + while (++index < length) { + accumulator = iteratee(accumulator, array[index], index, array); + } + return accumulator; + } + + /** + * The base implementation of `_.times` without support for iteratee shorthands + * or max array length checks. + * + * @private + * @param {number} n The number of times to invoke `iteratee`. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the array of results. + */ + function baseTimes(n, iteratee) { + var index = -1, + result = Array(n); + + while (++index < n) { + result[index] = iteratee(index); + } + return result; + } + + /** + * Gets the value at `key` of `object`. + * + * @private + * @param {Object} [object] The object to query. + * @param {string} key The key of the property to get. + * @returns {*} Returns the property value. + */ + function getValue(object, key) { + return object == null ? undefined : object[key]; + } + + /** + * Checks if `value` is a host object in IE < 9. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a host object, else `false`. + */ + function isHostObject(value) { + // Many host objects are `Object` objects that can coerce to strings + // despite having improperly defined `toString` methods. + var result = false; + if (value != null && typeof value.toString != 'function') { + try { + result = !!(value + ''); + } catch (e) {} + } + return result; + } + + /** + * Converts `map` to its key-value pairs. + * + * @private + * @param {Object} map The map to convert. + * @returns {Array} Returns the key-value pairs. + */ + function mapToArray(map) { + var index = -1, + result = Array(map.size); + + map.forEach(function(value, key) { + result[++index] = [key, value]; + }); + return result; + } + + /** + * Creates a unary function that invokes `func` with its argument transformed. + * + * @private + * @param {Function} func The function to wrap. + * @param {Function} transform The argument transform. + * @returns {Function} Returns the new function. + */ + function overArg(func, transform) { + return function(arg) { + return func(transform(arg)); + }; + } + + /** + * Converts `set` to an array of its values. + * + * @private + * @param {Object} set The set to convert. + * @returns {Array} Returns the values. + */ + function setToArray(set) { + var index = -1, + result = Array(set.size); + + set.forEach(function(value) { + result[++index] = value; + }); + return result; + } + + /** Used for built-in method references. */ + var arrayProto = Array.prototype, + funcProto = Function.prototype, + objectProto = Object.prototype; + + /** Used to detect overreaching core-js shims. */ + var coreJsData = root['__core-js_shared__']; + + /** Used to detect methods masquerading as native. */ + var maskSrcKey = (function() { + var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || ''); + return uid ? ('Symbol(src)_1.' + uid) : ''; + }()); + + /** Used to resolve the decompiled source of functions. */ + var funcToString = funcProto.toString; + + /** Used to check objects for own properties. */ + var hasOwnProperty = objectProto.hasOwnProperty; + + /** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ + var objectToString = objectProto.toString; + + /** Used to detect if a method is native. */ + var reIsNative = RegExp('^' + + funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&') + .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' + ); + + /** Built-in value references. */ + var Buffer = moduleExports ? root.Buffer : undefined, + Symbol = root.Symbol, + Uint8Array = root.Uint8Array, + getPrototype = overArg(Object.getPrototypeOf, Object), + objectCreate = Object.create, + propertyIsEnumerable = objectProto.propertyIsEnumerable, + splice = arrayProto.splice; + + /* Built-in method references for those with the same name as other `lodash` methods. */ + var nativeGetSymbols = Object.getOwnPropertySymbols, + nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined, + nativeKeys = overArg(Object.keys, Object); + + /* Built-in method references that are verified to be native. */ + var DataView = getNative(root, 'DataView'), + Map = getNative(root, 'Map'), + Promise = getNative(root, 'Promise'), + Set = getNative(root, 'Set'), + WeakMap = getNative(root, 'WeakMap'), + nativeCreate = getNative(Object, 'create'); + + /** Used to detect maps, sets, and weakmaps. */ + var dataViewCtorString = toSource(DataView), + mapCtorString = toSource(Map), + promiseCtorString = toSource(Promise), + setCtorString = toSource(Set), + weakMapCtorString = toSource(WeakMap); + + /** Used to convert symbols to primitives and strings. */ + var symbolProto = Symbol ? Symbol.prototype : undefined, + symbolValueOf = symbolProto ? symbolProto.valueOf : undefined; + + /** + * Creates a hash object. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + function Hash(entries) { + var index = -1, + length = entries ? entries.length : 0; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } + } + + /** + * Removes all key-value entries from the hash. + * + * @private + * @name clear + * @memberOf Hash + */ + function hashClear() { + this.__data__ = nativeCreate ? nativeCreate(null) : {}; + } + + /** + * Removes `key` and its value from the hash. + * + * @private + * @name delete + * @memberOf Hash + * @param {Object} hash The hash to modify. + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function hashDelete(key) { + return this.has(key) && delete this.__data__[key]; + } + + /** + * Gets the hash value for `key`. + * + * @private + * @name get + * @memberOf Hash + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function hashGet(key) { + var data = this.__data__; + if (nativeCreate) { + var result = data[key]; + return result === HASH_UNDEFINED ? undefined : result; + } + return hasOwnProperty.call(data, key) ? data[key] : undefined; + } + + /** + * Checks if a hash value for `key` exists. + * + * @private + * @name has + * @memberOf Hash + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function hashHas(key) { + var data = this.__data__; + return nativeCreate ? data[key] !== undefined : hasOwnProperty.call(data, key); + } + + /** + * Sets the hash `key` to `value`. + * + * @private + * @name set + * @memberOf Hash + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the hash instance. + */ + function hashSet(key, value) { + var data = this.__data__; + data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value; + return this; + } + + // Add methods to `Hash`. + Hash.prototype.clear = hashClear; + Hash.prototype['delete'] = hashDelete; + Hash.prototype.get = hashGet; + Hash.prototype.has = hashHas; + Hash.prototype.set = hashSet; + + /** + * Creates an list cache object. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + function ListCache(entries) { + var index = -1, + length = entries ? entries.length : 0; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } + } + + /** + * Removes all key-value entries from the list cache. + * + * @private + * @name clear + * @memberOf ListCache + */ + function listCacheClear() { + this.__data__ = []; + } + + /** + * Removes `key` and its value from the list cache. + * + * @private + * @name delete + * @memberOf ListCache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function listCacheDelete(key) { + var data = this.__data__, + index = assocIndexOf(data, key); + + if (index < 0) { + return false; + } + var lastIndex = data.length - 1; + if (index == lastIndex) { + data.pop(); + } else { + splice.call(data, index, 1); + } + return true; + } + + /** + * Gets the list cache value for `key`. + * + * @private + * @name get + * @memberOf ListCache + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function listCacheGet(key) { + var data = this.__data__, + index = assocIndexOf(data, key); + + return index < 0 ? undefined : data[index][1]; + } + + /** + * Checks if a list cache value for `key` exists. + * + * @private + * @name has + * @memberOf ListCache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function listCacheHas(key) { + return assocIndexOf(this.__data__, key) > -1; + } + + /** + * Sets the list cache `key` to `value`. + * + * @private + * @name set + * @memberOf ListCache + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the list cache instance. + */ + function listCacheSet(key, value) { + var data = this.__data__, + index = assocIndexOf(data, key); + + if (index < 0) { + data.push([key, value]); + } else { + data[index][1] = value; + } + return this; + } + + // Add methods to `ListCache`. + ListCache.prototype.clear = listCacheClear; + ListCache.prototype['delete'] = listCacheDelete; + ListCache.prototype.get = listCacheGet; + ListCache.prototype.has = listCacheHas; + ListCache.prototype.set = listCacheSet; + + /** + * Creates a map cache object to store key-value pairs. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + function MapCache(entries) { + var index = -1, + length = entries ? entries.length : 0; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } + } + + /** + * Removes all key-value entries from the map. + * + * @private + * @name clear + * @memberOf MapCache + */ + function mapCacheClear() { + this.__data__ = { + 'hash': new Hash, + 'map': new (Map || ListCache), + 'string': new Hash + }; + } + + /** + * Removes `key` and its value from the map. + * + * @private + * @name delete + * @memberOf MapCache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function mapCacheDelete(key) { + return getMapData(this, key)['delete'](key); + } + + /** + * Gets the map value for `key`. + * + * @private + * @name get + * @memberOf MapCache + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function mapCacheGet(key) { + return getMapData(this, key).get(key); + } + + /** + * Checks if a map value for `key` exists. + * + * @private + * @name has + * @memberOf MapCache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function mapCacheHas(key) { + return getMapData(this, key).has(key); + } + + /** + * Sets the map `key` to `value`. + * + * @private + * @name set + * @memberOf MapCache + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the map cache instance. + */ + function mapCacheSet(key, value) { + getMapData(this, key).set(key, value); + return this; + } + + // Add methods to `MapCache`. + MapCache.prototype.clear = mapCacheClear; + MapCache.prototype['delete'] = mapCacheDelete; + MapCache.prototype.get = mapCacheGet; + MapCache.prototype.has = mapCacheHas; + MapCache.prototype.set = mapCacheSet; + + /** + * Creates a stack cache object to store key-value pairs. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + function Stack(entries) { + this.__data__ = new ListCache(entries); + } + + /** + * Removes all key-value entries from the stack. + * + * @private + * @name clear + * @memberOf Stack + */ + function stackClear() { + this.__data__ = new ListCache; + } + + /** + * Removes `key` and its value from the stack. + * + * @private + * @name delete + * @memberOf Stack + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function stackDelete(key) { + return this.__data__['delete'](key); + } + + /** + * Gets the stack value for `key`. + * + * @private + * @name get + * @memberOf Stack + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function stackGet(key) { + return this.__data__.get(key); + } + + /** + * Checks if a stack value for `key` exists. + * + * @private + * @name has + * @memberOf Stack + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function stackHas(key) { + return this.__data__.has(key); + } + + /** + * Sets the stack `key` to `value`. + * + * @private + * @name set + * @memberOf Stack + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the stack cache instance. + */ + function stackSet(key, value) { + var cache = this.__data__; + if (cache instanceof ListCache) { + var pairs = cache.__data__; + if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) { + pairs.push([key, value]); + return this; + } + cache = this.__data__ = new MapCache(pairs); + } + cache.set(key, value); + return this; + } + + // Add methods to `Stack`. + Stack.prototype.clear = stackClear; + Stack.prototype['delete'] = stackDelete; + Stack.prototype.get = stackGet; + Stack.prototype.has = stackHas; + Stack.prototype.set = stackSet; + + /** + * Creates an array of the enumerable property names of the array-like `value`. + * + * @private + * @param {*} value The value to query. + * @param {boolean} inherited Specify returning inherited property names. + * @returns {Array} Returns the array of property names. + */ + function arrayLikeKeys(value, inherited) { + // Safari 8.1 makes `arguments.callee` enumerable in strict mode. + // Safari 9 makes `arguments.length` enumerable in strict mode. + var result = (isArray(value) || isArguments(value)) + ? baseTimes(value.length, String) + : []; + + var length = result.length, + skipIndexes = !!length; + + for (var key in value) { + if ((hasOwnProperty.call(value, key)) && + !(skipIndexes && (key == 'length' || isIndex(key, length)))) { + result.push(key); + } + } + return result; + } + + /** + * Assigns `value` to `key` of `object` if the existing value is not equivalent + * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. + * + * @private + * @param {Object} object The object to modify. + * @param {string} key The key of the property to assign. + * @param {*} value The value to assign. + */ + function assignValue(object, key, value) { + var objValue = object[key]; + if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) || + (value === undefined && !(key in object))) { + object[key] = value; + } + } + + /** + * Gets the index at which the `key` is found in `array` of key-value pairs. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} key The key to search for. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function assocIndexOf(array, key) { + var length = array.length; + while (length--) { + if (eq(array[length][0], key)) { + return length; + } + } + return -1; + } + + /** + * The base implementation of `_.assign` without support for multiple sources + * or `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @returns {Object} Returns `object`. + */ + function baseAssign(object, source) { + return object && copyObject(source, keys(source), object); + } + + /** + * The base implementation of `_.clone` and `_.cloneDeep` which tracks + * traversed objects. + * + * @private + * @param {*} value The value to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @param {boolean} [isFull] Specify a clone including symbols. + * @param {Function} [customizer] The function to customize cloning. + * @param {string} [key] The key of `value`. + * @param {Object} [object] The parent object of `value`. + * @param {Object} [stack] Tracks traversed objects and their clone counterparts. + * @returns {*} Returns the cloned value. + */ + function baseClone(value, isDeep, isFull, customizer, key, object, stack) { + var result; + if (customizer) { + result = object ? customizer(value, key, object, stack) : customizer(value); + } + if (result !== undefined) { + return result; + } + if (!isObject(value)) { + return value; + } + var isArr = isArray(value); + if (isArr) { + result = initCloneArray(value); + if (!isDeep) { + return copyArray(value, result); + } + } else { + var tag = getTag(value), + isFunc = tag == funcTag || tag == genTag; + + if (isBuffer(value)) { + return cloneBuffer(value, isDeep); + } + if (tag == objectTag || tag == argsTag || (isFunc && !object)) { + if (isHostObject(value)) { + return object ? value : {}; + } + result = initCloneObject(isFunc ? {} : value); + if (!isDeep) { + return copySymbols(value, baseAssign(result, value)); + } + } else { + if (!cloneableTags[tag]) { + return object ? value : {}; + } + result = initCloneByTag(value, tag, baseClone, isDeep); + } + } + // Check for circular references and return its corresponding clone. + stack || (stack = new Stack); + var stacked = stack.get(value); + if (stacked) { + return stacked; + } + stack.set(value, result); + + if (!isArr) { + var props = isFull ? getAllKeys(value) : keys(value); + } + arrayEach(props || value, function(subValue, key) { + if (props) { + key = subValue; + subValue = value[key]; + } + // Recursively populate clone (susceptible to call stack limits). + assignValue(result, key, baseClone(subValue, isDeep, isFull, customizer, key, value, stack)); + }); + return result; + } + + /** + * The base implementation of `_.create` without support for assigning + * properties to the created object. + * + * @private + * @param {Object} prototype The object to inherit from. + * @returns {Object} Returns the new object. + */ + function baseCreate(proto) { + return isObject(proto) ? objectCreate(proto) : {}; + } + + /** + * The base implementation of `getAllKeys` and `getAllKeysIn` which uses + * `keysFunc` and `symbolsFunc` to get the enumerable property names and + * symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Function} keysFunc The function to get the keys of `object`. + * @param {Function} symbolsFunc The function to get the symbols of `object`. + * @returns {Array} Returns the array of property names and symbols. + */ + function baseGetAllKeys(object, keysFunc, symbolsFunc) { + var result = keysFunc(object); + return isArray(object) ? result : arrayPush(result, symbolsFunc(object)); + } + + /** + * The base implementation of `getTag`. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the `toStringTag`. + */ + function baseGetTag(value) { + return objectToString.call(value); + } + + /** + * The base implementation of `_.isNative` without bad shim checks. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a native function, + * else `false`. + */ + function baseIsNative(value) { + if (!isObject(value) || isMasked(value)) { + return false; + } + var pattern = (isFunction(value) || isHostObject(value)) ? reIsNative : reIsHostCtor; + return pattern.test(toSource(value)); + } + + /** + * The base implementation of `_.keys` which doesn't treat sparse arrays as dense. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ + function baseKeys(object) { + if (!isPrototype(object)) { + return nativeKeys(object); + } + var result = []; + for (var key in Object(object)) { + if (hasOwnProperty.call(object, key) && key != 'constructor') { + result.push(key); + } + } + return result; + } + + /** + * Creates a clone of `buffer`. + * + * @private + * @param {Buffer} buffer The buffer to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Buffer} Returns the cloned buffer. + */ + function cloneBuffer(buffer, isDeep) { + if (isDeep) { + return buffer.slice(); + } + var result = new buffer.constructor(buffer.length); + buffer.copy(result); + return result; + } + + /** + * Creates a clone of `arrayBuffer`. + * + * @private + * @param {ArrayBuffer} arrayBuffer The array buffer to clone. + * @returns {ArrayBuffer} Returns the cloned array buffer. + */ + function cloneArrayBuffer(arrayBuffer) { + var result = new arrayBuffer.constructor(arrayBuffer.byteLength); + new Uint8Array(result).set(new Uint8Array(arrayBuffer)); + return result; + } + + /** + * Creates a clone of `dataView`. + * + * @private + * @param {Object} dataView The data view to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned data view. + */ + function cloneDataView(dataView, isDeep) { + var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer; + return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength); + } + + /** + * Creates a clone of `map`. + * + * @private + * @param {Object} map The map to clone. + * @param {Function} cloneFunc The function to clone values. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned map. + */ + function cloneMap(map, isDeep, cloneFunc) { + var array = isDeep ? cloneFunc(mapToArray(map), true) : mapToArray(map); + return arrayReduce(array, addMapEntry, new map.constructor); + } + + /** + * Creates a clone of `regexp`. + * + * @private + * @param {Object} regexp The regexp to clone. + * @returns {Object} Returns the cloned regexp. + */ + function cloneRegExp(regexp) { + var result = new regexp.constructor(regexp.source, reFlags.exec(regexp)); + result.lastIndex = regexp.lastIndex; + return result; + } + + /** + * Creates a clone of `set`. + * + * @private + * @param {Object} set The set to clone. + * @param {Function} cloneFunc The function to clone values. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned set. + */ + function cloneSet(set, isDeep, cloneFunc) { + var array = isDeep ? cloneFunc(setToArray(set), true) : setToArray(set); + return arrayReduce(array, addSetEntry, new set.constructor); + } + + /** + * Creates a clone of the `symbol` object. + * + * @private + * @param {Object} symbol The symbol object to clone. + * @returns {Object} Returns the cloned symbol object. + */ + function cloneSymbol(symbol) { + return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {}; + } + + /** + * Creates a clone of `typedArray`. + * + * @private + * @param {Object} typedArray The typed array to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned typed array. + */ + function cloneTypedArray(typedArray, isDeep) { + var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer; + return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length); + } + + /** + * Copies the values of `source` to `array`. + * + * @private + * @param {Array} source The array to copy values from. + * @param {Array} [array=[]] The array to copy values to. + * @returns {Array} Returns `array`. + */ + function copyArray(source, array) { + var index = -1, + length = source.length; + + array || (array = Array(length)); + while (++index < length) { + array[index] = source[index]; + } + return array; + } + + /** + * Copies properties of `source` to `object`. + * + * @private + * @param {Object} source The object to copy properties from. + * @param {Array} props The property identifiers to copy. + * @param {Object} [object={}] The object to copy properties to. + * @param {Function} [customizer] The function to customize copied values. + * @returns {Object} Returns `object`. + */ + function copyObject(source, props, object, customizer) { + object || (object = {}); + + var index = -1, + length = props.length; + + while (++index < length) { + var key = props[index]; + + var newValue = undefined; + + assignValue(object, key, newValue === undefined ? source[key] : newValue); + } + return object; + } + + /** + * Copies own symbol properties of `source` to `object`. + * + * @private + * @param {Object} source The object to copy symbols from. + * @param {Object} [object={}] The object to copy symbols to. + * @returns {Object} Returns `object`. + */ + function copySymbols(source, object) { + return copyObject(source, getSymbols(source), object); + } + + /** + * Creates an array of own enumerable property names and symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names and symbols. + */ + function getAllKeys(object) { + return baseGetAllKeys(object, keys, getSymbols); + } + + /** + * Gets the data for `map`. + * + * @private + * @param {Object} map The map to query. + * @param {string} key The reference key. + * @returns {*} Returns the map data. + */ + function getMapData(map, key) { + var data = map.__data__; + return isKeyable(key) + ? data[typeof key == 'string' ? 'string' : 'hash'] + : data.map; + } + + /** + * Gets the native function at `key` of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {string} key The key of the method to get. + * @returns {*} Returns the function if it's native, else `undefined`. + */ + function getNative(object, key) { + var value = getValue(object, key); + return baseIsNative(value) ? value : undefined; + } + + /** + * Creates an array of the own enumerable symbol properties of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. + */ + var getSymbols = nativeGetSymbols ? overArg(nativeGetSymbols, Object) : stubArray; + + /** + * Gets the `toStringTag` of `value`. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the `toStringTag`. + */ + var getTag = baseGetTag; + + // Fallback for data views, maps, sets, and weak maps in IE 11, + // for data views in Edge < 14, and promises in Node.js. + if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) || + (Map && getTag(new Map) != mapTag) || + (Promise && getTag(Promise.resolve()) != promiseTag) || + (Set && getTag(new Set) != setTag) || + (WeakMap && getTag(new WeakMap) != weakMapTag)) { + getTag = function(value) { + var result = objectToString.call(value), + Ctor = result == objectTag ? value.constructor : undefined, + ctorString = Ctor ? toSource(Ctor) : undefined; + + if (ctorString) { + switch (ctorString) { + case dataViewCtorString: return dataViewTag; + case mapCtorString: return mapTag; + case promiseCtorString: return promiseTag; + case setCtorString: return setTag; + case weakMapCtorString: return weakMapTag; + } + } + return result; + }; + } + + /** + * Initializes an array clone. + * + * @private + * @param {Array} array The array to clone. + * @returns {Array} Returns the initialized clone. + */ + function initCloneArray(array) { + var length = array.length, + result = array.constructor(length); + + // Add properties assigned by `RegExp#exec`. + if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) { + result.index = array.index; + result.input = array.input; + } + return result; + } + + /** + * Initializes an object clone. + * + * @private + * @param {Object} object The object to clone. + * @returns {Object} Returns the initialized clone. + */ + function initCloneObject(object) { + return (typeof object.constructor == 'function' && !isPrototype(object)) + ? baseCreate(getPrototype(object)) + : {}; + } + + /** + * Initializes an object clone based on its `toStringTag`. + * + * **Note:** This function only supports cloning values with tags of + * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. + * + * @private + * @param {Object} object The object to clone. + * @param {string} tag The `toStringTag` of the object to clone. + * @param {Function} cloneFunc The function to clone values. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the initialized clone. + */ + function initCloneByTag(object, tag, cloneFunc, isDeep) { + var Ctor = object.constructor; + switch (tag) { + case arrayBufferTag: + return cloneArrayBuffer(object); + + case boolTag: + case dateTag: + return new Ctor(+object); + + case dataViewTag: + return cloneDataView(object, isDeep); + + case float32Tag: case float64Tag: + case int8Tag: case int16Tag: case int32Tag: + case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag: + return cloneTypedArray(object, isDeep); + + case mapTag: + return cloneMap(object, isDeep, cloneFunc); + + case numberTag: + case stringTag: + return new Ctor(object); + + case regexpTag: + return cloneRegExp(object); + + case setTag: + return cloneSet(object, isDeep, cloneFunc); + + case symbolTag: + return cloneSymbol(object); + } + } + + /** + * Checks if `value` is a valid array-like index. + * + * @private + * @param {*} value The value to check. + * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. + * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. + */ + function isIndex(value, length) { + length = length == null ? MAX_SAFE_INTEGER : length; + return !!length && + (typeof value == 'number' || reIsUint.test(value)) && + (value > -1 && value % 1 == 0 && value < length); + } + + /** + * Checks if `value` is suitable for use as unique object key. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is suitable, else `false`. + */ + function isKeyable(value) { + var type = typeof value; + return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean') + ? (value !== '__proto__') + : (value === null); + } + + /** + * Checks if `func` has its source masked. + * + * @private + * @param {Function} func The function to check. + * @returns {boolean} Returns `true` if `func` is masked, else `false`. + */ + function isMasked(func) { + return !!maskSrcKey && (maskSrcKey in func); + } + + /** + * Checks if `value` is likely a prototype object. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a prototype, else `false`. + */ + function isPrototype(value) { + var Ctor = value && value.constructor, + proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto; + + return value === proto; + } + + /** + * Converts `func` to its source code. + * + * @private + * @param {Function} func The function to process. + * @returns {string} Returns the source code. + */ + function toSource(func) { + if (func != null) { + try { + return funcToString.call(func); + } catch (e) {} + try { + return (func + ''); + } catch (e) {} + } + return ''; + } + + /** + * This method is like `_.clone` except that it recursively clones `value`. + * + * @static + * @memberOf _ + * @since 1.0.0 + * @category Lang + * @param {*} value The value to recursively clone. + * @returns {*} Returns the deep cloned value. + * @see _.clone + * @example + * + * var objects = [{ 'a': 1 }, { 'b': 2 }]; + * + * var deep = _.cloneDeep(objects); + * console.log(deep[0] === objects[0]); + * // => false + */ + function cloneDeep(value) { + return baseClone(value, true, true); + } + + /** + * Performs a + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * comparison between two values to determine if they are equivalent. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'a': 1 }; + * var other = { 'a': 1 }; + * + * _.eq(object, object); + * // => true + * + * _.eq(object, other); + * // => false + * + * _.eq('a', 'a'); + * // => true + * + * _.eq('a', Object('a')); + * // => false + * + * _.eq(NaN, NaN); + * // => true + */ + function eq(value, other) { + return value === other || (value !== value && other !== other); + } + + /** + * Checks if `value` is likely an `arguments` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an `arguments` object, + * else `false`. + * @example + * + * _.isArguments(function() { return arguments; }()); + * // => true + * + * _.isArguments([1, 2, 3]); + * // => false + */ + function isArguments(value) { + // Safari 8.1 makes `arguments.callee` enumerable in strict mode. + return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') && + (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag); + } + + /** + * Checks if `value` is classified as an `Array` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array, else `false`. + * @example + * + * _.isArray([1, 2, 3]); + * // => true + * + * _.isArray(document.body.children); + * // => false + * + * _.isArray('abc'); + * // => false + * + * _.isArray(_.noop); + * // => false + */ + var isArray = Array.isArray; + + /** + * Checks if `value` is array-like. A value is considered array-like if it's + * not a function and has a `value.length` that's an integer greater than or + * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is array-like, else `false`. + * @example + * + * _.isArrayLike([1, 2, 3]); + * // => true + * + * _.isArrayLike(document.body.children); + * // => true + * + * _.isArrayLike('abc'); + * // => true + * + * _.isArrayLike(_.noop); + * // => false + */ + function isArrayLike(value) { + return value != null && isLength(value.length) && !isFunction(value); + } + + /** + * This method is like `_.isArrayLike` except that it also checks if `value` + * is an object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array-like object, + * else `false`. + * @example + * + * _.isArrayLikeObject([1, 2, 3]); + * // => true + * + * _.isArrayLikeObject(document.body.children); + * // => true + * + * _.isArrayLikeObject('abc'); + * // => false + * + * _.isArrayLikeObject(_.noop); + * // => false + */ + function isArrayLikeObject(value) { + return isObjectLike(value) && isArrayLike(value); + } + + /** + * Checks if `value` is a buffer. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a buffer, else `false`. + * @example + * + * _.isBuffer(new Buffer(2)); + * // => true + * + * _.isBuffer(new Uint8Array(2)); + * // => false + */ + var isBuffer = nativeIsBuffer || stubFalse; + + /** + * Checks if `value` is classified as a `Function` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a function, else `false`. + * @example + * + * _.isFunction(_); + * // => true + * + * _.isFunction(/abc/); + * // => false + */ + function isFunction(value) { + // The use of `Object#toString` avoids issues with the `typeof` operator + // in Safari 8-9 which returns 'object' for typed array and other constructors. + var tag = isObject(value) ? objectToString.call(value) : ''; + return tag == funcTag || tag == genTag; + } + + /** + * Checks if `value` is a valid array-like length. + * + * **Note:** This method is loosely based on + * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. + * @example + * + * _.isLength(3); + * // => true + * + * _.isLength(Number.MIN_VALUE); + * // => false + * + * _.isLength(Infinity); + * // => false + * + * _.isLength('3'); + * // => false + */ + function isLength(value) { + return typeof value == 'number' && + value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; + } + + /** + * Checks if `value` is the + * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) + * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(_.noop); + * // => true + * + * _.isObject(null); + * // => false + */ + function isObject(value) { + var type = typeof value; + return !!value && (type == 'object' || type == 'function'); + } + + /** + * Checks if `value` is object-like. A value is object-like if it's not `null` + * and has a `typeof` result of "object". + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @example + * + * _.isObjectLike({}); + * // => true + * + * _.isObjectLike([1, 2, 3]); + * // => true + * + * _.isObjectLike(_.noop); + * // => false + * + * _.isObjectLike(null); + * // => false + */ + function isObjectLike(value) { + return !!value && typeof value == 'object'; + } + + /** + * Creates an array of the own enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. See the + * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) + * for more details. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keys(new Foo); + * // => ['a', 'b'] (iteration order is not guaranteed) + * + * _.keys('hi'); + * // => ['0', '1'] + */ + function keys(object) { + return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object); + } + + /** + * This method returns a new empty array. + * + * @static + * @memberOf _ + * @since 4.13.0 + * @category Util + * @returns {Array} Returns the new empty array. + * @example + * + * var arrays = _.times(2, _.stubArray); + * + * console.log(arrays); + * // => [[], []] + * + * console.log(arrays[0] === arrays[1]); + * // => false + */ + function stubArray() { + return []; + } + + /** + * This method returns `false`. + * + * @static + * @memberOf _ + * @since 4.13.0 + * @category Util + * @returns {boolean} Returns `false`. + * @example + * + * _.times(2, _.stubFalse); + * // => [false, false] + */ + function stubFalse() { + return false; + } + + module.exports = cloneDeep; + } (lodash_clonedeep, lodash_clonedeep.exports)); + + var lodash_clonedeepExports = lodash_clonedeep.exports; + var cloneDeep = /*@__PURE__*/getDefaultExportFromCjs$1(lodash_clonedeepExports); + + function applyContextDelta(context, delta, logger) { + try { + if (logger?.canPublish("trace")) { + logger?.trace(`applying context delta ${JSON.stringify(delta)} on context ${JSON.stringify(context)}`); + } + if (!delta) { + return context; + } + if (delta.reset) { + context = { ...delta.reset }; + return context; + } + context = deepClone(context, undefined); + if (delta.commands) { + for (const command of delta.commands) { + if (command.type === "remove") { + deletePath(context, command.path); + } + else if (command.type === "set") { + setValueToPath(context, command.value, command.path); + } + } + return context; + } + const added = delta.added; + const updated = delta.updated; + const removed = delta.removed; + if (added) { + Object.keys(added).forEach((key) => { + context[key] = added[key]; + }); + } + if (updated) { + Object.keys(updated).forEach((key) => { + mergeObjectsProperties(key, context, updated); + }); + } + if (removed) { + removed.forEach((key) => { + delete context[key]; + }); + } + return context; + } + catch (e) { + logger?.error(`error applying context delta ${JSON.stringify(delta)} on context ${JSON.stringify(context)}`, e); + return context; + } + } + function deepClone(obj, hash) { + return cloneDeep(obj); + } + const mergeObjectsProperties = (key, what, withWhat) => { + const right = withWhat[key]; + if (right === undefined) { + return what; + } + const left = what[key]; + if (!left || !right) { + what[key] = right; + return what; + } + if (typeof left === "string" || + typeof left === "number" || + typeof left === "boolean" || + typeof right === "string" || + typeof right === "number" || + typeof right === "boolean" || + Array.isArray(left) || + Array.isArray(right)) { + what[key] = right; + return what; + } + what[key] = Object.assign({}, left, right); + return what; + }; + function deepEqual(x, y) { + if (x === y) { + return true; + } + if (!(x instanceof Object) || !(y instanceof Object)) { + return false; + } + if (x.constructor !== y.constructor) { + return false; + } + for (const p in x) { + if (!x.hasOwnProperty(p)) { + continue; + } + if (!y.hasOwnProperty(p)) { + return false; + } + if (x[p] === y[p]) { + continue; + } + if (typeof (x[p]) !== "object") { + return false; + } + if (!deepEqual(x[p], y[p])) { + return false; + } + } + for (const p in y) { + if (y.hasOwnProperty(p) && !x.hasOwnProperty(p)) { + return false; + } + } + return true; + } + function setValueToPath(obj, value, path) { + const pathArr = path.split("."); + let i; + for (i = 0; i < pathArr.length - 1; i++) { + if (!obj[pathArr[i]]) { + obj[pathArr[i]] = {}; + } + if (typeof obj[pathArr[i]] !== "object") { + obj[pathArr[i]] = {}; + } + obj = obj[pathArr[i]]; + } + obj[pathArr[i]] = value; + } + function isSubset(superObj, subObj) { + return Object.keys(subObj).every((ele) => { + if (typeof subObj[ele] === "object") { + return isSubset(superObj?.[ele] || {}, subObj[ele] || {}); + } + return subObj[ele] === superObj?.[ele]; + }); + } + function deletePath(obj, path) { + const pathArr = path.split("."); + let i; + for (i = 0; i < pathArr.length - 1; i++) { + if (!obj[pathArr[i]]) { + return; + } + obj = obj[pathArr[i]]; + } + delete obj[pathArr[i]]; + } + + let GW3Bridge$1 = class GW3Bridge { + _logger; + _connection; + _trackAllContexts; + _reAnnounceKnownContexts; + _gw3Session; + _contextNameToData = {}; + _gw3Subscriptions = []; + _nextCallbackSubscriptionNumber = 0; + _creationPromises = {}; + _contextNameToId = {}; + _contextIdToName = {}; + _protocolVersion = undefined; + _contextsTempCache = {}; + _contextsSubscriptionsCache = []; + _systemContextsSubKey; + get protocolVersion() { + if (!this._protocolVersion) { + const contextsDomainInfo = this._connection.availableDomains.find((d) => d.uri === "context"); + this._protocolVersion = contextsDomainInfo?.version ?? 1; + } + return this._protocolVersion; + } + get setPathSupported() { + return this.protocolVersion >= 2; + } + constructor(config) { + this._connection = config.connection; + this._logger = config.logger; + this._trackAllContexts = config.trackAllContexts; + this._reAnnounceKnownContexts = config.reAnnounceKnownContexts; + this._gw3Session = this._connection.domain("global", [ + GW_MESSAGE_CONTEXT_CREATED, + GW_MESSAGE_SUBSCRIBED_CONTEXT, + GW_MESSAGE_CONTEXT_DESTROYED, + GW_MESSAGE_CONTEXT_UPDATED, + ]); + this._gw3Session.disconnected(this.resetState.bind(this)); + this._gw3Session.onJoined((wasReconnect) => { + if (!wasReconnect) { + return; + } + if (!this._reAnnounceKnownContexts) { + return this._connection.setLibReAnnounced({ name: "contexts" }); + } + this.reInitiateState().then(() => this._connection.setLibReAnnounced({ name: "contexts" })); + }); + this.subscribeToContextCreatedMessages(); + this.subscribeToContextUpdatedMessages(); + this.subscribeToContextDestroyedMessages(); + this._connection.replayer?.drain(ContextMessageReplaySpec.name, (message) => { + const type = message.type; + if (!type) { + return; + } + if (type === GW_MESSAGE_CONTEXT_CREATED || + type === GW_MESSAGE_CONTEXT_ADDED || + type === GW_MESSAGE_ACTIVITY_CREATED) { + this.handleContextCreatedMessage(message); + } + else if (type === GW_MESSAGE_SUBSCRIBED_CONTEXT || + type === GW_MESSAGE_CONTEXT_UPDATED || + type === GW_MESSAGE_JOINED_ACTIVITY) { + this.handleContextUpdatedMessage(message); + } + else if (type === GW_MESSAGE_CONTEXT_DESTROYED || + type === GW_MESSAGE_ACTIVITY_DESTROYED) { + this.handleContextDestroyedMessage(message); + } + }); + } + dispose() { + for (const sub of this._gw3Subscriptions) { + this._connection.off(sub); + } + this._gw3Subscriptions.length = 0; + for (const contextName in this._contextNameToData) { + if (this._contextNameToId.hasOwnProperty(contextName)) { + delete this._contextNameToData[contextName]; + } + } + } + createContext(name, data) { + if (name in this._creationPromises) { + return this._creationPromises[name]; + } + this._creationPromises[name] = + this._gw3Session + .send({ + type: GW_MESSAGE_CREATE_CONTEXT, + domain: "global", + name, + data, + lifetime: "retained", + }) + .then((createContextMsg) => { + this._contextNameToId[name] = createContextMsg.context_id; + this._contextIdToName[createContextMsg.context_id] = name; + const contextData = this._contextNameToData[name] || new GW3ContextData(createContextMsg.context_id, name, true, undefined); + contextData.isAnnounced = true; + contextData.name = name; + contextData.contextId = createContextMsg.context_id; + contextData.context = createContextMsg.data || deepClone(data); + contextData.hasReceivedSnapshot = true; + this._contextNameToData[name] = contextData; + delete this._creationPromises[name]; + return createContextMsg.context_id; + }); + return this._creationPromises[name]; + } + all() { + return Object.keys(this._contextNameToData) + .filter((name) => this._contextNameToData[name].isAnnounced); + } + async update(name, delta) { + if (delta) { + delta = deepClone(delta); + } + if (name in this._creationPromises) { + await this._creationPromises[name]; + } + const contextData = this._contextNameToData[name]; + if (!contextData || !contextData.isAnnounced) { + return this.createContext(name, delta); + } + let currentContext = contextData.context; + if (!contextData.hasCallbacks()) { + currentContext = await this.get(contextData.name); + } + const calculatedDelta = this.setPathSupported ? + this.calculateContextDeltaV2(currentContext, delta) : + this.calculateContextDeltaV1(currentContext, delta); + if (!Object.keys(calculatedDelta.added).length + && !Object.keys(calculatedDelta.updated).length + && !calculatedDelta.removed.length + && !calculatedDelta.commands?.length) { + return Promise.resolve(); + } + return this._gw3Session + .send({ + type: GW_MESSAGE_UPDATE_CONTEXT, + domain: "global", + context_id: contextData.contextId, + delta: calculatedDelta, + }, {}, { skipPeerId: false }) + .then((gwResponse) => { + this.handleUpdated(contextData, calculatedDelta, { + updaterId: gwResponse.peer_id + }); + }); + } + async set(name, data) { + if (data) { + data = deepClone(data); + } + if (name in this._creationPromises) { + await this._creationPromises[name]; + } + const contextData = this._contextNameToData[name]; + if (!contextData || !contextData.isAnnounced) { + return this.createContext(name, data); + } + return this._gw3Session + .send({ + type: GW_MESSAGE_UPDATE_CONTEXT, + domain: "global", + context_id: contextData.contextId, + delta: { reset: data }, + }, {}, { skipPeerId: false }) + .then((gwResponse) => { + this.handleUpdated(contextData, { + reset: data, + added: {}, + removed: [], + updated: {} + }, { + updaterId: gwResponse.peer_id + }); + }); + } + setPath(name, path, value) { + if (!this.setPathSupported) { + return Promise.reject("glue.contexts.setPath operation is not supported, use Glue42 3.10 or later"); + } + return this.setPaths(name, [{ path, value }]); + } + async setPaths(name, pathValues) { + if (!this.setPathSupported) { + return Promise.reject("glue.contexts.setPaths operation is not supported, use Glue42 3.10 or later"); + } + if (pathValues) { + pathValues = deepClone(pathValues); + } + if (name in this._creationPromises) { + await this._creationPromises[name]; + } + const contextData = this._contextNameToData[name]; + if (!contextData || !contextData.isAnnounced) { + const obj = {}; + for (const pathValue of pathValues) { + setValueToPath(obj, pathValue.value, pathValue.path); + } + return this.createContext(name, obj); + } + const commands = []; + for (const pathValue of pathValues) { + if (pathValue.value === null) { + commands.push({ type: "remove", path: pathValue.path }); + } + else { + commands.push({ type: "set", path: pathValue.path, value: pathValue.value }); + } + } + return this._gw3Session + .send({ + type: GW_MESSAGE_UPDATE_CONTEXT, + domain: "global", + context_id: contextData.contextId, + delta: { commands } + }, {}, { skipPeerId: false }) + .then((gwResponse) => { + this.handleUpdated(contextData, { + added: {}, + removed: [], + updated: {}, + commands + }, { + updaterId: gwResponse.peer_id + }); + }); + } + async get(name) { + if (name in this._creationPromises) { + await this._creationPromises[name]; + } + const contextData = this._contextNameToData[name]; + if (!contextData || !contextData.isAnnounced) { + return Promise.resolve({}); + } + if (contextData && (!contextData.hasCallbacks() || !contextData.hasReceivedSnapshot)) { + return new Promise((resolve) => { + this.subscribe(name, (data, _d, _r, un) => { + this.unsubscribe(un); + resolve(data); + }); + }); + } + const context = contextData?.context ?? {}; + return Promise.resolve(deepClone(context)); + } + async subscribe(name, callback, subscriptionKey) { + if (name in this._creationPromises) { + await this._creationPromises[name]; + } + const thisCallbackSubscriptionNumber = typeof subscriptionKey === "undefined" ? this._nextCallbackSubscriptionNumber : subscriptionKey; + if (typeof subscriptionKey === "undefined") { + this._nextCallbackSubscriptionNumber += 1; + } + if (this._contextsSubscriptionsCache.every((subscription) => subscription.subKey !== this._nextCallbackSubscriptionNumber)) { + this._contextsSubscriptionsCache.push({ contextName: name, subKey: thisCallbackSubscriptionNumber, callback }); + } + let contextData = this._contextNameToData[name]; + if (!contextData || + !contextData.isAnnounced) { + contextData = contextData || new GW3ContextData(undefined, name, false, undefined); + this._contextNameToData[name] = contextData; + contextData.updateCallbacks[thisCallbackSubscriptionNumber] = callback; + return Promise.resolve(thisCallbackSubscriptionNumber); + } + const hadCallbacks = contextData.hasCallbacks(); + contextData.updateCallbacks[thisCallbackSubscriptionNumber] = callback; + if (!hadCallbacks) { + if (!contextData.joinedActivity) { + if (contextData.context && contextData.sentExplicitSubscription) { + if (contextData.hasReceivedSnapshot) { + const clone = deepClone(contextData.context); + callback(clone, clone, [], thisCallbackSubscriptionNumber); + } + return Promise.resolve(thisCallbackSubscriptionNumber); + } + return this.sendSubscribe(contextData) + .then(() => thisCallbackSubscriptionNumber); + } + else { + if (contextData.hasReceivedSnapshot) { + const clone = deepClone(contextData.context); + callback(clone, clone, [], thisCallbackSubscriptionNumber); + } + return Promise.resolve(thisCallbackSubscriptionNumber); + } + } + else { + if (contextData.hasReceivedSnapshot) { + const clone = deepClone(contextData.context); + callback(clone, clone, [], thisCallbackSubscriptionNumber); + } + return Promise.resolve(thisCallbackSubscriptionNumber); + } + } + unsubscribe(subscriptionKey) { + this._contextsSubscriptionsCache = this._contextsSubscriptionsCache.filter((subscription) => subscription.subKey !== subscriptionKey); + for (const name of Object.keys(this._contextNameToData)) { + const contextData = this._contextNameToData[name]; + if (!contextData) { + return; + } + const hadCallbacks = contextData.hasCallbacks(); + delete contextData.updateCallbacks[subscriptionKey]; + if (contextData.isAnnounced && + hadCallbacks && + !contextData.hasCallbacks() && + contextData.sentExplicitSubscription) { + this.sendUnsubscribe(contextData).catch(() => { }); + } + if (!contextData.isAnnounced && + !contextData.hasCallbacks()) { + delete this._contextNameToData[name]; + } + } + } + async destroy(name) { + if (name in this._creationPromises) { + await this._creationPromises[name]; + } + const contextData = this._contextNameToData[name]; + if (!contextData) { + return Promise.reject(`context with ${name} does not exist`); + } + return this._gw3Session + .send({ + type: GW_MESSAGE_DESTROY_CONTEXT, + domain: "global", + context_id: contextData.contextId, + }).then((_) => undefined); + } + handleUpdated(contextData, delta, extraData) { + const oldContext = contextData.context; + contextData.context = applyContextDelta(contextData.context, delta, this._logger); + contextData.hasReceivedSnapshot = true; + if (this._contextNameToData[contextData.name] === contextData && + !deepEqual(oldContext, contextData.context)) { + this.invokeUpdateCallbacks(contextData, delta, extraData); + } + } + subscribeToContextCreatedMessages() { + const createdMessageTypes = [ + GW_MESSAGE_CONTEXT_ADDED, + GW_MESSAGE_CONTEXT_CREATED, + GW_MESSAGE_ACTIVITY_CREATED, + ]; + for (const createdMessageType of createdMessageTypes) { + const sub = this._connection.on(createdMessageType, this.handleContextCreatedMessage.bind(this)); + this._gw3Subscriptions.push(sub); + } + } + handleContextCreatedMessage(contextCreatedMsg) { + const createdMessageType = contextCreatedMsg.type; + if (createdMessageType === GW_MESSAGE_ACTIVITY_CREATED) { + this._contextNameToId[contextCreatedMsg.activity_id] = contextCreatedMsg.context_id; + this._contextIdToName[contextCreatedMsg.context_id] = contextCreatedMsg.activity_id; + } + else if (createdMessageType === GW_MESSAGE_CONTEXT_ADDED) { + this._contextNameToId[contextCreatedMsg.name] = contextCreatedMsg.context_id; + this._contextIdToName[contextCreatedMsg.context_id] = contextCreatedMsg.name; + } + else ; + const name = this._contextIdToName[contextCreatedMsg.context_id]; + if (!name) { + throw new Error("Received created event for context with unknown name: " + contextCreatedMsg.context_id); + } + if (!this._contextNameToId[name]) { + throw new Error("Received created event for context with unknown id: " + contextCreatedMsg.context_id); + } + let contextData = this._contextNameToData[name]; + if (contextData) { + if (contextData.isAnnounced) { + return; + } + else { + if (!contextData.hasCallbacks()) { + throw new Error("Assertion failure: contextData.hasCallbacks()"); + } + contextData.isAnnounced = true; + contextData.contextId = contextCreatedMsg.context_id; + contextData.activityId = contextCreatedMsg.activity_id; + if (!contextData.sentExplicitSubscription) { + this.sendSubscribe(contextData); + } + } + } + else { + this._contextNameToData[name] = contextData = + new GW3ContextData(contextCreatedMsg.context_id, name, true, contextCreatedMsg.activity_id); + if (this._trackAllContexts) { + this.subscribe(name, () => { }).then((subKey) => this._systemContextsSubKey = subKey); + } + } + } + subscribeToContextUpdatedMessages() { + const updatedMessageTypes = [ + GW_MESSAGE_CONTEXT_UPDATED, + GW_MESSAGE_SUBSCRIBED_CONTEXT, + GW_MESSAGE_JOINED_ACTIVITY, + ]; + for (const updatedMessageType of updatedMessageTypes) { + const sub = this._connection.on(updatedMessageType, this.handleContextUpdatedMessage.bind(this)); + this._gw3Subscriptions.push(sub); + } + } + handleContextUpdatedMessage(contextUpdatedMsg) { + const updatedMessageType = contextUpdatedMsg.type; + const contextId = contextUpdatedMsg.context_id; + let contextData = this._contextNameToData[this._contextIdToName[contextId]]; + const justSeen = !contextData || !contextData.isAnnounced; + if (updatedMessageType === GW_MESSAGE_JOINED_ACTIVITY) { + if (!contextData) { + contextData = + this._contextNameToData[contextUpdatedMsg.activity_id] || + new GW3ContextData(contextId, contextUpdatedMsg.activity_id, true, contextUpdatedMsg.activity_id); + } + this._contextNameToData[contextUpdatedMsg.activity_id] = contextData; + this._contextIdToName[contextId] = contextUpdatedMsg.activity_id; + this._contextNameToId[contextUpdatedMsg.activity_id] = contextId; + contextData.contextId = contextId; + contextData.isAnnounced = true; + contextData.activityId = contextUpdatedMsg.activity_id; + contextData.joinedActivity = true; + } + else { + if (!contextData || !contextData.isAnnounced) { + if (updatedMessageType === GW_MESSAGE_SUBSCRIBED_CONTEXT) { + contextData = contextData || new GW3ContextData(contextId, contextUpdatedMsg.name, true, undefined); + contextData.sentExplicitSubscription = true; + this._contextNameToData[contextUpdatedMsg.name] = contextData; + this._contextIdToName[contextId] = contextUpdatedMsg.name; + this._contextNameToId[contextUpdatedMsg.name] = contextId; + } + else { + this._logger.error(`Received 'update' for unknown context: ${contextId}`); + } + return; + } + } + const oldContext = contextData.context; + contextData.hasReceivedSnapshot = true; + if (updatedMessageType === GW_MESSAGE_SUBSCRIBED_CONTEXT) { + contextData.context = contextUpdatedMsg.data || {}; + } + else if (updatedMessageType === GW_MESSAGE_JOINED_ACTIVITY) { + contextData.context = contextUpdatedMsg.context_snapshot || {}; + } + else if (updatedMessageType === GW_MESSAGE_CONTEXT_UPDATED) { + contextData.context = applyContextDelta(contextData.context, contextUpdatedMsg.delta, this._logger); + } + else { + throw new Error("Unrecognized context update message " + updatedMessageType); + } + if (justSeen || + !deepEqual(contextData.context, oldContext) || + updatedMessageType === GW_MESSAGE_SUBSCRIBED_CONTEXT) { + this.invokeUpdateCallbacks(contextData, contextUpdatedMsg.delta, { updaterId: contextUpdatedMsg.updater_id }); + } + } + invokeUpdateCallbacks(contextData, delta, extraData) { + delta = delta || { added: {}, updated: {}, reset: {}, removed: [] }; + if (delta.commands) { + delta.added = delta.updated = delta.reset = {}; + delta.removed = []; + for (const command of delta.commands) { + if (command.type === "remove") { + if (command.path.indexOf(".") === -1) { + delta.removed.push(command.path); + } + setValueToPath(delta.updated, null, command.path); + } + else if (command.type === "set") { + setValueToPath(delta.updated, command.value, command.path); + } + } + } + for (const updateCallbackIndex in contextData.updateCallbacks) { + if (contextData.updateCallbacks.hasOwnProperty(updateCallbackIndex)) { + try { + const updateCallback = contextData.updateCallbacks[updateCallbackIndex]; + updateCallback(deepClone(contextData.context), deepClone(Object.assign({}, delta.added || {}, delta.updated || {}, delta.reset || {})), delta.removed, parseInt(updateCallbackIndex, 10), extraData); + } + catch (err) { + this._logger.debug("callback error: " + JSON.stringify(err)); + } + } + } + } + subscribeToContextDestroyedMessages() { + const destroyedMessageTypes = [ + GW_MESSAGE_CONTEXT_DESTROYED, + GW_MESSAGE_ACTIVITY_DESTROYED, + ]; + for (const destroyedMessageType of destroyedMessageTypes) { + const sub = this._connection.on(destroyedMessageType, this.handleContextDestroyedMessage.bind(this)); + this._gw3Subscriptions.push(sub); + } + } + handleContextDestroyedMessage(destroyedMsg) { + const destroyedMessageType = destroyedMsg.type; + let contextId; + let name; + if (destroyedMessageType === GW_MESSAGE_ACTIVITY_DESTROYED) { + name = destroyedMsg.activity_id; + contextId = this._contextNameToId[name]; + if (!contextId) { + this._logger.error(`Received 'destroyed' for unknown activity: ${destroyedMsg.activity_id}`); + return; + } + } + else { + contextId = destroyedMsg.context_id; + name = this._contextIdToName[contextId]; + if (!name) { + this._logger.error(`Received 'destroyed' for unknown context: ${destroyedMsg.context_id}`); + return; + } + } + delete this._contextIdToName[contextId]; + delete this._contextNameToId[name]; + const contextData = this._contextNameToData[name]; + delete this._contextNameToData[name]; + if (!contextData || !contextData.isAnnounced) { + this._logger.error(`Received 'destroyed' for unknown context: ${contextId}`); + return; + } + } + sendSubscribe(contextData) { + contextData.sentExplicitSubscription = true; + return this._gw3Session + .send({ + type: GW_MESSAGE_SUBSCRIBE_CONTEXT, + domain: "global", + context_id: contextData.contextId, + }).then((_) => undefined); + } + sendUnsubscribe(contextData) { + contextData.sentExplicitSubscription = false; + return this._gw3Session + .send({ + type: GW_MESSAGE_UNSUBSCRIBE_CONTEXT, + domain: "global", + context_id: contextData.contextId, + }).then((_) => undefined); + } + calculateContextDeltaV1(from, to) { + const delta = { added: {}, updated: {}, removed: [], reset: undefined }; + if (from) { + for (const x of Object.keys(from)) { + if (Object.keys(to).indexOf(x) !== -1 + && to[x] !== null + && !deepEqual(from[x], to[x])) { + delta.updated[x] = to[x]; + } + } + } + for (const x of Object.keys(to)) { + if (!from || (Object.keys(from).indexOf(x) === -1)) { + if (to[x] !== null) { + delta.added[x] = to[x]; + } + } + else if (to[x] === null) { + delta.removed.push(x); + } + } + return delta; + } + calculateContextDeltaV2(from, to) { + const delta = { added: {}, updated: {}, removed: [], reset: undefined, commands: [] }; + for (const x of Object.keys(to)) { + if (to[x] !== null) { + const fromX = from ? from[x] : null; + if (!deepEqual(fromX, to[x])) { + delta.commands?.push({ type: "set", path: x, value: to[x] }); + } + } + else { + delta.commands?.push({ type: "remove", path: x }); + } + } + return delta; + } + resetState() { + for (const sub of this._gw3Subscriptions) { + this._connection.off(sub); + } + if (this._systemContextsSubKey) { + this.unsubscribe(this._systemContextsSubKey); + delete this._systemContextsSubKey; + } + this._gw3Subscriptions = []; + this._contextNameToId = {}; + this._contextIdToName = {}; + delete this._protocolVersion; + this._contextsTempCache = Object.keys(this._contextNameToData).reduce((cacheSoFar, ctxName) => { + const contextData = this._contextNameToData[ctxName]; + if (contextData.isAnnounced && (contextData.activityId || contextData.sentExplicitSubscription)) { + cacheSoFar[ctxName] = this._contextNameToData[ctxName].context; + } + return cacheSoFar; + }, {}); + this._contextNameToData = {}; + } + async reInitiateState() { + this.subscribeToContextCreatedMessages(); + this.subscribeToContextUpdatedMessages(); + this.subscribeToContextDestroyedMessages(); + this._connection.replayer?.drain(ContextMessageReplaySpec.name, (message) => { + const type = message.type; + if (!type) { + return; + } + if (type === GW_MESSAGE_CONTEXT_CREATED || + type === GW_MESSAGE_CONTEXT_ADDED || + type === GW_MESSAGE_ACTIVITY_CREATED) { + this.handleContextCreatedMessage(message); + } + else if (type === GW_MESSAGE_SUBSCRIBED_CONTEXT || + type === GW_MESSAGE_CONTEXT_UPDATED || + type === GW_MESSAGE_JOINED_ACTIVITY) { + this.handleContextUpdatedMessage(message); + } + else if (type === GW_MESSAGE_CONTEXT_DESTROYED || + type === GW_MESSAGE_ACTIVITY_DESTROYED) { + this.handleContextDestroyedMessage(message); + } + }); + await Promise.all(this._contextsSubscriptionsCache.map((subscription) => this.subscribe(subscription.contextName, subscription.callback, subscription.subKey))); + await this.flushQueue(); + for (const ctxName in this._contextsTempCache) { + if (typeof this._contextsTempCache[ctxName] !== "object" || Object.keys(this._contextsTempCache[ctxName]).length === 0) { + continue; + } + const lastKnownData = this._contextsTempCache[ctxName]; + this._logger.info(`Re-announcing known context: ${ctxName}`); + await this.flushQueue(); + await this.update(ctxName, lastKnownData); + } + this._contextsTempCache = {}; + this._logger.info("Contexts are re-announced"); + } + flushQueue() { + return new Promise((resolve) => setTimeout(() => resolve(), 0)); + } + }; + + class ContextsModule { + initTime; + initStartTime; + initEndTime; + _bridge; + constructor(config) { + this._bridge = new GW3Bridge$1(config); + } + all() { + return this._bridge.all(); + } + update(name, data) { + this.checkName(name); + this.checkData(data); + return this._bridge.update(name, data); + } + set(name, data) { + this.checkName(name); + this.checkData(data); + return this._bridge.set(name, data); + } + setPath(name, path, data) { + this.checkName(name); + this.checkPath(path); + const isTopLevelPath = path === ""; + if (isTopLevelPath) { + this.checkData(data); + return this.set(name, data); + } + return this._bridge.setPath(name, path, data); + } + setPaths(name, paths) { + this.checkName(name); + if (!Array.isArray(paths)) { + throw new Error("Please provide the paths as an array of PathValues!"); + } + for (const { path, value } of paths) { + this.checkPath(path); + const isTopLevelPath = path === ""; + if (isTopLevelPath) { + this.checkData(value); + } + } + return this._bridge.setPaths(name, paths); + } + subscribe(name, callback) { + this.checkName(name); + if (typeof callback !== "function") { + throw new Error("Please provide the callback as a function!"); + } + return this._bridge + .subscribe(name, (data, delta, removed, key, extraData) => callback(data, delta, removed, () => this._bridge.unsubscribe(key), extraData)) + .then((key) => () => { + this._bridge.unsubscribe(key); + }); + } + get(name) { + this.checkName(name); + return this._bridge.get(name); + } + ready() { + return Promise.resolve(this); + } + destroy(name) { + this.checkName(name); + return this._bridge.destroy(name); + } + get setPathSupported() { + return this._bridge.setPathSupported; + } + checkName(name) { + if (typeof name !== "string" || name === "") { + throw new Error("Please provide the name as a non-empty string!"); + } + } + checkPath(path) { + if (typeof path !== "string") { + throw new Error("Please provide the path as a dot delimited string!"); + } + } + checkData(data) { + if (typeof data !== "object") { + throw new Error("Please provide the data as an object!"); + } + } + } + + function promisify$2 (promise, successCallback, errorCallback) { + if (typeof successCallback !== "function" && typeof errorCallback !== "function") { + return promise; + } + if (typeof successCallback !== "function") { + successCallback = () => { }; + } + else if (typeof errorCallback !== "function") { + errorCallback = () => { }; + } + return promise.then(successCallback, errorCallback); + } + + function rejectAfter(ms = 0, promise, error) { + let timeout; + const clearTimeoutIfThere = () => { + if (timeout) { + clearTimeout(timeout); + } + }; + promise + .then(() => { + clearTimeoutIfThere(); + }) + .catch(() => { + clearTimeoutIfThere(); + }); + return new Promise((resolve, reject) => { + timeout = setTimeout(() => reject(error), ms); + }); + } + + var InvokeStatus; + (function (InvokeStatus) { + InvokeStatus[InvokeStatus["Success"] = 0] = "Success"; + InvokeStatus[InvokeStatus["Error"] = 1] = "Error"; + })(InvokeStatus || (InvokeStatus = {})); + class Client { + protocol; + repo; + instance; + configuration; + constructor(protocol, repo, instance, configuration) { + this.protocol = protocol; + this.repo = repo; + this.instance = instance; + this.configuration = configuration; + } + subscribe(method, options, successCallback, errorCallback, existingSub) { + const callProtocolSubscribe = (targetServers, stream, successProxy, errorProxy) => { + options.methodResponseTimeout = options.methodResponseTimeout ?? options.waitTimeoutMs; + this.protocol.client.subscribe(stream, options, targetServers, successProxy, errorProxy, existingSub); + }; + const promise = new Promise((resolve, reject) => { + const successProxy = (sub) => { + resolve(sub); + }; + const errorProxy = (err) => { + reject(err); + }; + if (!method) { + reject(`Method definition is required. Please, provide either a unique string for a method name or a “methodDefinition” object with a required “name” property.`); + return; + } + let methodDef; + if (typeof method === "string") { + methodDef = { name: method }; + } + else { + methodDef = method; + } + if (!methodDef.name) { + reject(`Method definition is required. Please, provide either a unique string for a method name or a “methodDefinition” object with a required “name” property.`); + return; + } + if (options === undefined) { + options = {}; + } + let target = options.target; + if (target === undefined) { + target = "best"; + } + if (typeof target === "string" && target !== "all" && target !== "best") { + reject(new Error(`"${target}" is not a valid target. Valid targets are "all", "best", or an instance.`)); + return; + } + if (options.methodResponseTimeout === undefined) { + options.methodResponseTimeout = options.method_response_timeout; + if (options.methodResponseTimeout === undefined) { + options.methodResponseTimeout = this.configuration.methodResponseTimeout; + } + } + if (options.waitTimeoutMs === undefined) { + options.waitTimeoutMs = options.wait_for_method_timeout; + if (options.waitTimeoutMs === undefined) { + options.waitTimeoutMs = this.configuration.waitTimeoutMs; + } + } + const delayStep = 500; + let delayTillNow = 0; + let currentServers = this.getServerMethodsByFilterAndTarget(methodDef, target); + if (currentServers.length > 0) { + callProtocolSubscribe(currentServers, currentServers[0].methods[0], successProxy, errorProxy); + } + else { + const retry = () => { + if (!target || !(options.waitTimeoutMs)) { + return; + } + delayTillNow += delayStep; + currentServers = this.getServerMethodsByFilterAndTarget(methodDef, target); + if (currentServers.length > 0) { + const streamInfo = currentServers[0].methods[0]; + callProtocolSubscribe(currentServers, streamInfo, successProxy, errorProxy); + } + else if (delayTillNow >= options.waitTimeoutMs) { + const def = typeof method === "string" ? { name: method } : method; + callProtocolSubscribe(currentServers, def, successProxy, errorProxy); + } + else { + setTimeout(retry, delayStep); + } + }; + setTimeout(retry, delayStep); + } + }); + return promisify$2(promise, successCallback, errorCallback); + } + servers(methodFilter) { + const filterCopy = methodFilter === undefined + ? undefined + : { ...methodFilter }; + return this.getServers(filterCopy).map((serverMethodMap) => { + return serverMethodMap.server.instance; + }); + } + methods(methodFilter) { + if (typeof methodFilter === "string") { + methodFilter = { name: methodFilter }; + } + else { + methodFilter = { ...methodFilter }; + } + return this.getMethods(methodFilter); + } + methodsForInstance(instance) { + return this.getMethodsForInstance(instance); + } + methodAdded(callback) { + return this.repo.onMethodAdded(callback); + } + methodRemoved(callback) { + return this.repo.onMethodRemoved(callback); + } + serverAdded(callback) { + return this.repo.onServerAdded(callback); + } + serverRemoved(callback) { + return this.repo.onServerRemoved((server, reason) => { + callback(server, reason); + }); + } + serverMethodAdded(callback) { + return this.repo.onServerMethodAdded((server, method) => { + callback({ server, method }); + }); + } + serverMethodRemoved(callback) { + return this.repo.onServerMethodRemoved((server, method) => { + callback({ server, method }); + }); + } + async invoke(methodFilter, argumentObj, target, additionalOptions, success, error) { + const getInvokePromise = async () => { + let methodDefinition; + if (typeof methodFilter === "string") { + methodDefinition = { name: methodFilter }; + } + else { + methodDefinition = { ...methodFilter }; + } + if (!methodDefinition.name) { + return Promise.reject(`Method definition is required. Please, provide either a unique string for a method name or a “methodDefinition” object with a required “name” property.`); + } + if (!argumentObj) { + argumentObj = {}; + } + if (!target) { + target = "best"; + } + if (typeof target === "string" && target !== "all" && target !== "best" && target !== "skipMine") { + return Promise.reject(new Error(`"${target}" is not a valid target. Valid targets are "all" and "best".`)); + } + if (!additionalOptions) { + additionalOptions = {}; + } + if (additionalOptions.methodResponseTimeoutMs === undefined) { + additionalOptions.methodResponseTimeoutMs = additionalOptions.method_response_timeout; + if (additionalOptions.methodResponseTimeoutMs === undefined) { + additionalOptions.methodResponseTimeoutMs = this.configuration.methodResponseTimeout; + } + } + if (additionalOptions.waitTimeoutMs === undefined) { + additionalOptions.waitTimeoutMs = additionalOptions.wait_for_method_timeout; + if (additionalOptions.waitTimeoutMs === undefined) { + additionalOptions.waitTimeoutMs = this.configuration.waitTimeoutMs; + } + } + if (additionalOptions.waitTimeoutMs !== undefined && typeof additionalOptions.waitTimeoutMs !== "number") { + return Promise.reject(new Error(`"${additionalOptions.waitTimeoutMs}" is not a valid number for "waitTimeoutMs" `)); + } + if (typeof argumentObj !== "object") { + return Promise.reject(new Error(`The method arguments must be an object. method: ${methodDefinition.name}`)); + } + let serversMethodMap = this.getServerMethodsByFilterAndTarget(methodDefinition, target); + if (serversMethodMap.length === 0) { + try { + serversMethodMap = await this.tryToAwaitForMethods(methodDefinition, target, additionalOptions); + } + catch (err) { + const method = { + ...methodDefinition, + getServers: () => [], + supportsStreaming: false, + objectTypes: methodDefinition.objectTypes ?? [], + flags: methodDefinition.flags?.metadata ?? {} + }; + const errorObj = { + method, + called_with: argumentObj, + message: `Can not find a method matching ${JSON.stringify(methodFilter)} with server filter ${JSON.stringify(target)}`, + executed_by: undefined, + returned: undefined, + status: undefined, + }; + return Promise.reject(errorObj); + } + } + const timeout = additionalOptions.methodResponseTimeoutMs; + const additionalOptionsCopy = additionalOptions; + const invokePromises = serversMethodMap.map((serversMethodPair) => { + const invId = nanoid$1(10); + const method = serversMethodPair.methods[0]; + const server = serversMethodPair.server; + const invokePromise = this.protocol.client.invoke(invId, method, argumentObj, server, additionalOptionsCopy); + return Promise.race([ + invokePromise, + rejectAfter(timeout, invokePromise, { + invocationId: invId, + message: `Invocation timeout (${timeout} ms) reached for method name: ${method?.name}, target instance: ${JSON.stringify(server.instance)}, options: ${JSON.stringify(additionalOptionsCopy)}`, + status: InvokeStatus.Error, + }) + ]); + }); + const invocationMessages = await Promise.all(invokePromises); + const results = this.getInvocationResultObj(invocationMessages, methodDefinition, argumentObj); + const allRejected = invocationMessages.every((result) => result.status === InvokeStatus.Error); + if (allRejected) { + return Promise.reject(results); + } + return results; + }; + return promisify$2(getInvokePromise(), success, error); + } + getInvocationResultObj(invocationResults, method, calledWith) { + const all_return_values = invocationResults + .filter((invokeMessage) => invokeMessage.status === InvokeStatus.Success) + .reduce((allValues, currentValue) => { + allValues = [ + ...allValues, + { + executed_by: currentValue.instance, + returned: currentValue.result, + called_with: calledWith, + method, + message: currentValue.message, + status: currentValue.status, + } + ]; + return allValues; + }, []); + const all_errors = invocationResults + .filter((invokeMessage) => invokeMessage.status === InvokeStatus.Error) + .reduce((allErrors, currError) => { + allErrors = [ + ...allErrors, + { + executed_by: currError.instance, + called_with: calledWith, + name: method.name, + message: currError.message, + } + ]; + return allErrors; + }, []); + const invResult = invocationResults[0]; + const result = { + method, + called_with: calledWith, + returned: invResult.result, + executed_by: invResult.instance, + all_return_values, + all_errors, + message: invResult.message, + status: invResult.status + }; + return result; + } + tryToAwaitForMethods(methodDefinition, target, additionalOptions) { + return new Promise((resolve, reject) => { + if (additionalOptions.waitTimeoutMs === 0) { + reject(); + return; + } + const delayStep = 500; + let delayTillNow = 0; + const retry = () => { + delayTillNow += delayStep; + const serversMethodMap = this.getServerMethodsByFilterAndTarget(methodDefinition, target); + if (serversMethodMap.length > 0) { + clearInterval(interval); + resolve(serversMethodMap); + } + else if (delayTillNow >= (additionalOptions.waitTimeoutMs || 10000)) { + clearInterval(interval); + reject(); + return; + } + }; + const interval = setInterval(retry, delayStep); + }); + } + filterByTarget(target, serverMethodMap) { + if (typeof target === "string") { + if (target === "all") { + return [...serverMethodMap]; + } + else if (target === "best") { + const localMachine = serverMethodMap + .find((s) => s.server.instance.isLocal); + if (localMachine) { + return [localMachine]; + } + if (serverMethodMap[0] !== undefined) { + return [serverMethodMap[0]]; + } + } + else if (target === "skipMine") { + return serverMethodMap.filter(({ server }) => server.instance.peerId !== this.instance.peerId); + } + } + else { + let targetArray; + if (!Array.isArray(target)) { + targetArray = [target]; + } + else { + targetArray = target; + } + const allServersMatching = targetArray.reduce((matches, filter) => { + const myMatches = serverMethodMap.filter((serverMethodPair) => { + return this.instanceMatch(filter, serverMethodPair.server.instance); + }); + return matches.concat(myMatches); + }, []); + return allServersMatching; + } + return []; + } + instanceMatch(instanceFilter, instanceDefinition) { + if (instanceFilter?.peerId && instanceFilter?.instance) { + instanceFilter = { ...instanceFilter }; + delete instanceFilter.peerId; + } + return this.containsProps(instanceFilter, instanceDefinition); + } + methodMatch(methodFilter, methodDefinition) { + return this.containsProps(methodFilter, methodDefinition); + } + containsProps(filter, repoMethod) { + const filterProps = Object.keys(filter) + .filter((prop) => { + return filter[prop] !== undefined + && filter[prop] !== null + && typeof filter[prop] !== "function" + && prop !== "object_types" + && prop !== "display_name" + && prop !== "id" + && prop !== "gatewayId" + && prop !== "identifier" + && prop[0] !== "_"; + }); + return filterProps.every((prop) => { + let isMatch; + const filterValue = filter[prop]; + const repoMethodValue = repoMethod[prop]; + switch (prop) { + case "objectTypes": + isMatch = (filterValue || []).every((filterValueEl) => { + return (repoMethodValue || []).includes(filterValueEl); + }); + break; + case "flags": + isMatch = isSubset(repoMethodValue || {}, filterValue || {}); + break; + default: + isMatch = String(filterValue).toLowerCase() === String(repoMethodValue).toLowerCase(); + } + return isMatch; + }); + } + getMethods(methodFilter) { + if (methodFilter === undefined) { + return this.repo.getMethods(); + } + const methods = this.repo.getMethods().filter((method) => { + return this.methodMatch(methodFilter, method); + }); + return methods; + } + getMethodsForInstance(instanceFilter) { + const allServers = this.repo.getServers(); + const matchingServers = allServers.filter((server) => { + return this.instanceMatch(instanceFilter, server.instance); + }); + if (matchingServers.length === 0) { + return []; + } + let resultMethodsObject = {}; + if (matchingServers.length === 1) { + resultMethodsObject = matchingServers[0].methods; + } + else { + matchingServers.forEach((server) => { + Object.keys(server.methods).forEach((methodKey) => { + const method = server.methods[methodKey]; + resultMethodsObject[method.identifier] = method; + }); + }); + } + return Object.keys(resultMethodsObject) + .map((key) => { + return resultMethodsObject[key]; + }); + } + getServers(methodFilter) { + const servers = this.repo.getServers(); + if (methodFilter === undefined) { + return servers.map((server) => { + return { server, methods: [] }; + }); + } + return servers.reduce((prev, current) => { + const methodsForServer = Object.values(current.methods); + const matchingMethods = methodsForServer.filter((method) => { + return this.methodMatch(methodFilter, method); + }); + if (matchingMethods.length > 0) { + prev.push({ server: current, methods: matchingMethods }); + } + return prev; + }, []); + } + getServerMethodsByFilterAndTarget(methodFilter, target) { + const serversMethodMap = this.getServers(methodFilter); + return this.filterByTarget(target, serversMethodMap); + } + } + + class ServerSubscription { + protocol; + repoMethod; + subscription; + constructor(protocol, repoMethod, subscription) { + this.protocol = protocol; + this.repoMethod = repoMethod; + this.subscription = subscription; + } + get stream() { + if (!this.repoMethod.stream) { + throw new Error("no stream"); + } + return this.repoMethod.stream; + } + get arguments() { return this.subscription.arguments || {}; } + get branchKey() { return this.subscription.branchKey; } + get instance() { + if (!this.subscription.instance) { + throw new Error("no instance"); + } + return this.subscription.instance; + } + close() { + this.protocol.server.closeSingleSubscription(this.repoMethod, this.subscription); + } + push(data) { + this.protocol.server.pushDataToSingle(this.repoMethod, this.subscription, data); + } + } + + class Request { + protocol; + repoMethod; + requestContext; + arguments; + instance; + constructor(protocol, repoMethod, requestContext) { + this.protocol = protocol; + this.repoMethod = repoMethod; + this.requestContext = requestContext; + this.arguments = requestContext.arguments; + this.instance = requestContext.instance; + } + accept() { + this.protocol.server.acceptRequestOnBranch(this.requestContext, this.repoMethod, ""); + } + acceptOnBranch(branch) { + this.protocol.server.acceptRequestOnBranch(this.requestContext, this.repoMethod, branch); + } + reject(reason) { + this.protocol.server.rejectRequest(this.requestContext, this.repoMethod, reason); + } + } + + let ServerStreaming$1 = class ServerStreaming { + protocol; + server; + constructor(protocol, server) { + this.protocol = protocol; + this.server = server; + protocol.server.onSubRequest((rc, rm) => this.handleSubRequest(rc, rm)); + protocol.server.onSubAdded((sub, rm) => this.handleSubAdded(sub, rm)); + protocol.server.onSubRemoved((sub, rm) => this.handleSubRemoved(sub, rm)); + } + handleSubRequest(requestContext, repoMethod) { + if (!(repoMethod && + repoMethod.streamCallbacks && + typeof repoMethod.streamCallbacks.subscriptionRequestHandler === "function")) { + return; + } + const request = new Request(this.protocol, repoMethod, requestContext); + repoMethod.streamCallbacks.subscriptionRequestHandler(request); + } + handleSubAdded(subscription, repoMethod) { + if (!(repoMethod && + repoMethod.streamCallbacks && + typeof repoMethod.streamCallbacks.subscriptionAddedHandler === "function")) { + return; + } + const sub = new ServerSubscription(this.protocol, repoMethod, subscription); + repoMethod.streamCallbacks.subscriptionAddedHandler(sub); + } + handleSubRemoved(subscription, repoMethod) { + if (!(repoMethod && + repoMethod.streamCallbacks && + typeof repoMethod.streamCallbacks.subscriptionRemovedHandler === "function")) { + return; + } + const sub = new ServerSubscription(this.protocol, repoMethod, subscription); + repoMethod.streamCallbacks.subscriptionRemovedHandler(sub); + } + }; + + class ServerBranch { + key; + protocol; + repoMethod; + constructor(key, protocol, repoMethod) { + this.key = key; + this.protocol = protocol; + this.repoMethod = repoMethod; + } + subscriptions() { + const subList = this.protocol.server.getSubscriptionList(this.repoMethod, this.key); + return subList.map((sub) => { + return new ServerSubscription(this.protocol, this.repoMethod, sub); + }); + } + close() { + this.protocol.server.closeAllSubscriptions(this.repoMethod, this.key); + } + push(data) { + this.protocol.server.pushData(this.repoMethod, data, [this.key]); + } + } + + class ServerStream { + _protocol; + _repoMethod; + _server; + name; + constructor(_protocol, _repoMethod, _server) { + this._protocol = _protocol; + this._repoMethod = _repoMethod; + this._server = _server; + this.name = this._repoMethod.definition.name; + } + branches(key) { + const bList = this._protocol.server.getBranchList(this._repoMethod); + if (key) { + if (bList.indexOf(key) > -1) { + return new ServerBranch(key, this._protocol, this._repoMethod); + } + return undefined; + } + else { + return bList.map((branchKey) => { + return new ServerBranch(branchKey, this._protocol, this._repoMethod); + }); + } + } + branch(key) { + return this.branches(key); + } + subscriptions() { + const subList = this._protocol.server.getSubscriptionList(this._repoMethod); + return subList.map((sub) => { + return new ServerSubscription(this._protocol, this._repoMethod, sub); + }); + } + get definition() { + const def2 = this._repoMethod.definition; + return { + accepts: def2.accepts, + description: def2.description, + displayName: def2.displayName, + name: def2.name, + objectTypes: def2.objectTypes, + returns: def2.returns, + supportsStreaming: def2.supportsStreaming, + flags: def2.flags?.metadata, + }; + } + close() { + this._protocol.server.closeAllSubscriptions(this._repoMethod); + this._server.unregister(this._repoMethod.definition, true); + } + push(data, branches) { + if (typeof branches !== "string" && !Array.isArray(branches) && branches !== undefined) { + throw new Error("invalid branches should be string or string array"); + } + if (typeof data !== "object") { + throw new Error("Invalid arguments. Data must be an object."); + } + this._protocol.server.pushData(this._repoMethod, data, branches); + } + updateRepoMethod(repoMethod) { + this._repoMethod = repoMethod; + } + } + + class Server { + protocol; + serverRepository; + streaming; + invocations = 0; + currentlyUnregistering = {}; + constructor(protocol, serverRepository) { + this.protocol = protocol; + this.serverRepository = serverRepository; + this.streaming = new ServerStreaming$1(protocol, this); + this.protocol.server.onInvoked(this.onMethodInvoked.bind(this)); + } + createStream(streamDef, callbacks, successCallback, errorCallback, existingStream) { + const promise = new Promise((resolve, reject) => { + if (!streamDef) { + reject("The stream name must be unique! Please, provide either a unique string for a stream name to “glue.interop.createStream()” or a “methodDefinition” object with a unique “name” property for the stream."); + return; + } + let streamMethodDefinition; + if (typeof streamDef === "string") { + streamMethodDefinition = { name: "" + streamDef }; + } + else { + streamMethodDefinition = { ...streamDef }; + } + if (!streamMethodDefinition.name) { + return reject(`The “name” property is required for the “streamDefinition” object and must be unique. Stream definition: ${JSON.stringify(streamMethodDefinition)}`); + } + const nameAlreadyExists = this.serverRepository.getList() + .some((serverMethod) => serverMethod.definition.name === streamMethodDefinition.name); + if (nameAlreadyExists) { + return reject(`A stream with the name "${streamMethodDefinition.name}" already exists! Please, provide a unique name for the stream.`); + } + streamMethodDefinition.supportsStreaming = true; + if (!callbacks) { + callbacks = {}; + } + if (typeof callbacks.subscriptionRequestHandler !== "function") { + callbacks.subscriptionRequestHandler = (request) => { + request.accept(); + }; + } + const repoMethod = this.serverRepository.add({ + definition: streamMethodDefinition, + streamCallbacks: callbacks, + protocolState: {}, + }); + this.protocol.server.createStream(repoMethod) + .then(() => { + let streamUserObject; + if (existingStream) { + streamUserObject = existingStream; + existingStream.updateRepoMethod(repoMethod); + } + else { + streamUserObject = new ServerStream(this.protocol, repoMethod, this); + } + repoMethod.stream = streamUserObject; + resolve(streamUserObject); + }) + .catch((err) => { + if (repoMethod.repoId) { + this.serverRepository.remove(repoMethod.repoId); + } + reject(err); + }); + }); + return promisify$2(promise, successCallback, errorCallback); + } + register(methodDefinition, callback) { + if (!methodDefinition) { + return Promise.reject("Method definition is required. Please, provide either a unique string for a method name or a “methodDefinition” object with a required “name” property."); + } + if (typeof callback !== "function") { + return Promise.reject(`The second parameter must be a callback function. Method: ${typeof methodDefinition === "string" ? methodDefinition : methodDefinition.name}`); + } + const wrappedCallbackFunction = async (context, resultCallback) => { + try { + const result = callback(context.args, context.instance); + if (result && typeof result.then === "function") { + const resultValue = await result; + resultCallback(undefined, resultValue); + } + else { + resultCallback(undefined, result); + } + } + catch (e) { + resultCallback(e ?? "", e ?? ""); + } + }; + wrappedCallbackFunction.userCallback = callback; + return this.registerCore(methodDefinition, wrappedCallbackFunction); + } + registerAsync(methodDefinition, callback) { + if (!methodDefinition) { + return Promise.reject("Method definition is required. Please, provide either a unique string for a method name or a “methodDefinition” object with a required “name” property."); + } + if (typeof callback !== "function") { + return Promise.reject(`The second parameter must be a callback function. Method: ${typeof methodDefinition === "string" ? methodDefinition : methodDefinition.name}`); + } + const wrappedCallback = async (context, resultCallback) => { + try { + let resultCalled = false; + const success = (result) => { + if (!resultCalled) { + resultCallback(undefined, result); + } + resultCalled = true; + }; + const error = (e) => { + if (!resultCalled) { + if (!e) { + e = ""; + } + resultCallback(e, e); + } + resultCalled = true; + }; + const methodResult = callback(context.args, context.instance, success, error); + if (methodResult && typeof methodResult.then === "function") { + methodResult + .then(success) + .catch(error); + } + } + catch (e) { + resultCallback(e, undefined); + } + }; + wrappedCallback.userCallbackAsync = callback; + return this.registerCore(methodDefinition, wrappedCallback); + } + async unregister(methodFilter, forStream = false) { + if (methodFilter === undefined) { + return Promise.reject("Please, provide either a unique string for a name or an object containing a “name” property."); + } + if (typeof methodFilter === "function") { + await this.unregisterWithPredicate(methodFilter, forStream); + return; + } + let methodDefinition; + if (typeof methodFilter === "string") { + methodDefinition = { name: methodFilter }; + } + else { + methodDefinition = methodFilter; + } + if (methodDefinition.name === undefined) { + return Promise.reject("Method name is required. Cannot find a method if the method name is undefined!"); + } + const methodToBeRemoved = this.serverRepository.getList().find((serverMethod) => { + return serverMethod.definition.name === methodDefinition.name + && (serverMethod.definition.supportsStreaming || false) === forStream; + }); + if (!methodToBeRemoved) { + return Promise.reject(`Method with a name "${methodDefinition.name}" does not exist or is not registered by your application!`); + } + await this.removeMethodsOrStreams([methodToBeRemoved]); + } + async unregisterWithPredicate(filterPredicate, forStream) { + const methodsOrStreamsToRemove = this.serverRepository.getList() + .filter((sm) => filterPredicate(sm.definition)) + .filter((serverMethod) => (serverMethod.definition.supportsStreaming || false) === forStream); + if (!methodsOrStreamsToRemove || methodsOrStreamsToRemove.length === 0) { + return Promise.reject(`Could not find a ${forStream ? "stream" : "method"} matching the specified condition!`); + } + await this.removeMethodsOrStreams(methodsOrStreamsToRemove); + } + removeMethodsOrStreams(methodsToRemove) { + const methodUnregPromises = []; + methodsToRemove.forEach((method) => { + const promise = this.protocol.server.unregister(method) + .then(() => { + if (method.repoId) { + this.serverRepository.remove(method.repoId); + } + }); + methodUnregPromises.push(promise); + this.addAsCurrentlyUnregistering(method.definition.name, promise); + }); + return Promise.all(methodUnregPromises); + } + async addAsCurrentlyUnregistering(methodName, promise) { + const timeout = new Promise((resolve) => setTimeout(resolve, 5000)); + this.currentlyUnregistering[methodName] = Promise.race([promise, timeout]).then(() => { + delete this.currentlyUnregistering[methodName]; + }); + } + async registerCore(method, theFunction) { + let methodDefinition; + if (typeof method === "string") { + methodDefinition = { name: "" + method }; + } + else { + methodDefinition = { ...method }; + } + if (!methodDefinition.name) { + return Promise.reject(`Please, provide a (unique) string value for the “name” property in the “methodDefinition” object: ${JSON.stringify(method)}`); + } + const unregisterInProgress = this.currentlyUnregistering[methodDefinition.name]; + if (typeof unregisterInProgress !== "undefined") { + await unregisterInProgress; + } + const nameAlreadyExists = this.serverRepository.getList() + .some((serverMethod) => serverMethod.definition.name === methodDefinition.name); + if (nameAlreadyExists) { + return Promise.reject(`A method with the name "${methodDefinition.name}" already exists! Please, provide a unique name for the method.`); + } + if (methodDefinition.supportsStreaming) { + return Promise.reject(`When you create methods with “glue.interop.register()” or “glue.interop.registerAsync()” the property “supportsStreaming” cannot be “true”. If you want “${methodDefinition.name}” to be a stream, please use the “glue.interop.createStream()” method.`); + } + const repoMethod = this.serverRepository.add({ + definition: methodDefinition, + theFunction, + protocolState: {}, + }); + return this.protocol.server.register(repoMethod) + .catch((err) => { + if (repoMethod?.repoId) { + this.serverRepository.remove(repoMethod.repoId); + } + throw err; + }); + } + onMethodInvoked(methodToExecute, invocationId, invocationArgs) { + if (!methodToExecute || !methodToExecute.theFunction) { + return; + } + methodToExecute.theFunction(invocationArgs, (err, result) => { + if (err !== undefined && err !== null) { + if (err.message && typeof err.message === "string") { + err = err.message; + } + else if (typeof err !== "string") { + try { + err = JSON.stringify(err); + } + catch (unStrException) { + err = `un-stringifyable error in onMethodInvoked! Top level prop names: ${Object.keys(err)}`; + } + } + } + if (!result) { + result = {}; + } + else if (typeof result !== "object" || Array.isArray(result)) { + result = { _value: result }; + } + this.protocol.server.methodInvocationResult(methodToExecute, invocationId, err, result); + }); + } + } + + class InstanceWrapper { + wrapped = {}; + constructor(API, instance, connection) { + this.wrapped.getMethods = function () { + return API.methodsForInstance(this); + }; + this.wrapped.getStreams = function () { + return API.methodsForInstance(this).filter((m) => m.supportsStreaming); + }; + if (instance) { + this.refreshWrappedObject(instance); + } + if (connection) { + connection.loggedIn(() => { + this.refresh(connection); + }); + this.refresh(connection); + } + } + unwrap() { + return this.wrapped; + } + refresh(connection) { + if (!connection) { + return; + } + const resolvedIdentity = connection?.resolvedIdentity; + const instance = Object.assign({}, resolvedIdentity ?? {}, { peerId: connection?.peerId }); + this.refreshWrappedObject(instance); + } + refreshWrappedObject(resolvedIdentity) { + Object.keys(resolvedIdentity).forEach((key) => { + this.wrapped[key] = resolvedIdentity[key]; + }); + this.wrapped.user = resolvedIdentity.user; + this.wrapped.instance = resolvedIdentity.instance; + this.wrapped.application = resolvedIdentity.application ?? nanoid$1(10); + this.wrapped.applicationName = resolvedIdentity.applicationName; + this.wrapped.pid = resolvedIdentity.pid ?? resolvedIdentity.process ?? Math.floor(Math.random() * 10000000000); + this.wrapped.machine = resolvedIdentity.machine; + this.wrapped.environment = resolvedIdentity.environment; + this.wrapped.region = resolvedIdentity.region; + this.wrapped.windowId = resolvedIdentity.windowId; + this.wrapped.isLocal = resolvedIdentity.isLocal ?? true; + this.wrapped.api = resolvedIdentity.api; + this.wrapped.service = resolvedIdentity.service; + this.wrapped.peerId = resolvedIdentity.peerId; + } + } + + const hideMethodSystemFlags = (method) => { + return { + ...method, + flags: method.flags.metadata || {} + }; + }; + class ClientRepository { + logger; + API; + servers = {}; + myServer; + methodsCount = {}; + callbacks = CallbackRegistryFactory$1(); + constructor(logger, API) { + this.logger = logger; + this.API = API; + const peerId = this.API.instance.peerId; + this.myServer = { + id: peerId, + methods: {}, + instance: this.API.instance, + wrapper: this.API.unwrappedInstance, + }; + this.servers[peerId] = this.myServer; + } + addServer(info, serverId) { + this.logger.debug(`adding server ${serverId}`); + const current = this.servers[serverId]; + if (current) { + return current.id; + } + const wrapper = new InstanceWrapper(this.API, info); + const serverEntry = { + id: serverId, + methods: {}, + instance: wrapper.unwrap(), + wrapper, + }; + this.servers[serverId] = serverEntry; + this.callbacks.execute("onServerAdded", serverEntry.instance); + return serverId; + } + removeServerById(id, reason) { + const server = this.servers[id]; + if (!server) { + this.logger.warn(`not aware of server ${id}, my state ${JSON.stringify(Object.keys(this.servers))}`); + return; + } + else { + this.logger.debug(`removing server ${id}`); + } + Object.keys(server.methods).forEach((methodId) => { + this.removeServerMethod(id, methodId); + }); + delete this.servers[id]; + this.callbacks.execute("onServerRemoved", server.instance, reason); + } + addServerMethod(serverId, method) { + const server = this.servers[serverId]; + if (!server) { + throw new Error("server does not exists"); + } + if (server.methods[method.id]) { + return; + } + const identifier = this.createMethodIdentifier(method); + const that = this; + const methodDefinition = { + identifier, + gatewayId: method.id, + name: method.name, + displayName: method.display_name, + description: method.description, + version: method.version, + objectTypes: method.object_types || [], + accepts: method.input_signature, + returns: method.result_signature, + supportsStreaming: typeof method.flags !== "undefined" ? method.flags.streaming : false, + flags: method.flags ?? {}, + getServers: () => { + return that.getServersByMethod(identifier); + } + }; + methodDefinition.object_types = methodDefinition.objectTypes; + methodDefinition.display_name = methodDefinition.displayName; + methodDefinition.version = methodDefinition.version; + server.methods[method.id] = methodDefinition; + const clientMethodDefinition = hideMethodSystemFlags(methodDefinition); + if (!this.methodsCount[identifier]) { + this.methodsCount[identifier] = 0; + this.callbacks.execute("onMethodAdded", clientMethodDefinition); + } + this.methodsCount[identifier] = this.methodsCount[identifier] + 1; + this.callbacks.execute("onServerMethodAdded", server.instance, clientMethodDefinition); + return methodDefinition; + } + removeServerMethod(serverId, methodId) { + const server = this.servers[serverId]; + if (!server) { + throw new Error("server does not exists"); + } + const method = server.methods[methodId]; + delete server.methods[methodId]; + const clientMethodDefinition = hideMethodSystemFlags(method); + this.methodsCount[method.identifier] = this.methodsCount[method.identifier] - 1; + if (this.methodsCount[method.identifier] === 0) { + this.callbacks.execute("onMethodRemoved", clientMethodDefinition); + } + this.callbacks.execute("onServerMethodRemoved", server.instance, clientMethodDefinition); + } + getMethods() { + return this.extractMethodsFromServers(Object.values(this.servers)).map(hideMethodSystemFlags); + } + getServers() { + return Object.values(this.servers).map(this.hideServerMethodSystemFlags); + } + onServerAdded(callback) { + const unsubscribeFunc = this.callbacks.add("onServerAdded", callback); + const serversWithMethodsToReplay = this.getServers().map((s) => s.instance); + return this.returnUnsubWithDelayedReplay(unsubscribeFunc, serversWithMethodsToReplay, callback); + } + onMethodAdded(callback) { + const unsubscribeFunc = this.callbacks.add("onMethodAdded", callback); + const methodsToReplay = this.getMethods(); + return this.returnUnsubWithDelayedReplay(unsubscribeFunc, methodsToReplay, callback); + } + onServerMethodAdded(callback) { + const unsubscribeFunc = this.callbacks.add("onServerMethodAdded", callback); + let unsubCalled = false; + const servers = this.getServers(); + setTimeout(() => { + servers.forEach((server) => { + const methods = server.methods; + Object.keys(methods).forEach((methodId) => { + if (!unsubCalled) { + callback(server.instance, methods[methodId]); + } + }); + }); + }, 0); + return () => { + unsubCalled = true; + unsubscribeFunc(); + }; + } + onMethodRemoved(callback) { + const unsubscribeFunc = this.callbacks.add("onMethodRemoved", callback); + return unsubscribeFunc; + } + onServerRemoved(callback) { + const unsubscribeFunc = this.callbacks.add("onServerRemoved", callback); + return unsubscribeFunc; + } + onServerMethodRemoved(callback) { + const unsubscribeFunc = this.callbacks.add("onServerMethodRemoved", callback); + return unsubscribeFunc; + } + getServerById(id) { + const server = this.servers[id]; + if (!server) { + return undefined; + } + return this.hideServerMethodSystemFlags(this.servers[id]); + } + reset() { + Object.keys(this.servers).forEach((key) => { + this.removeServerById(key, "reset"); + }); + this.servers = { + [this.myServer.id]: this.myServer + }; + this.methodsCount = {}; + } + createMethodIdentifier(methodInfo) { + const accepts = methodInfo.input_signature ?? ""; + const returns = methodInfo.result_signature ?? ""; + return (methodInfo.name + accepts + returns).toLowerCase(); + } + getServersByMethod(identifier) { + const allServers = []; + Object.values(this.servers).forEach((server) => { + Object.values(server.methods).forEach((method) => { + if (method.identifier === identifier) { + allServers.push(server.instance); + } + }); + }); + return allServers; + } + returnUnsubWithDelayedReplay(unsubscribeFunc, collectionToReplay, callback) { + let unsubCalled = false; + setTimeout(() => { + collectionToReplay.forEach((item) => { + if (!unsubCalled) { + callback(item); + } + }); + }, 0); + return () => { + unsubCalled = true; + unsubscribeFunc(); + }; + } + hideServerMethodSystemFlags(server) { + const clientMethods = {}; + Object.entries(server.methods).forEach(([name, method]) => { + clientMethods[name] = hideMethodSystemFlags(method); + }); + return { + ...server, + methods: clientMethods + }; + } + extractMethodsFromServers(servers) { + const methods = Object.values(servers).reduce((clientMethods, server) => { + return [...clientMethods, ...Object.values(server.methods)]; + }, []); + return methods; + } + } + + class ServerRepository { + nextId = 0; + methods = []; + add(method) { + method.repoId = String(this.nextId); + this.nextId += 1; + this.methods.push(method); + return method; + } + remove(repoId) { + if (typeof repoId !== "string") { + return new TypeError("Expecting a string"); + } + this.methods = this.methods.filter((m) => { + return m.repoId !== repoId; + }); + } + getById(id) { + if (typeof id !== "string") { + return undefined; + } + return this.methods.find((m) => { + return m.repoId === id; + }); + } + getList() { + return this.methods.map((m) => m); + } + length() { + return this.methods.length; + } + reset() { + this.methods = []; + } + } + + const SUBSCRIPTION_REQUEST = "onSubscriptionRequest"; + const SUBSCRIPTION_ADDED = "onSubscriptionAdded"; + const SUBSCRIPTION_REMOVED = "onSubscriptionRemoved"; + class ServerStreaming { + session; + repository; + serverRepository; + ERR_URI_SUBSCRIPTION_FAILED = "com.tick42.agm.errors.subscription.failure"; + callbacks = CallbackRegistryFactory$1(); + nextStreamId = 0; + constructor(session, repository, serverRepository) { + this.session = session; + this.repository = repository; + this.serverRepository = serverRepository; + session.on("add-interest", (msg) => { + this.handleAddInterest(msg); + }); + session.on("remove-interest", (msg) => { + this.handleRemoveInterest(msg); + }); + } + acceptRequestOnBranch(requestContext, streamingMethod, branch) { + if (typeof branch !== "string") { + branch = ""; + } + if (typeof streamingMethod.protocolState.subscriptionsMap !== "object") { + throw new TypeError("The streaming method is missing its subscriptions."); + } + if (!Array.isArray(streamingMethod.protocolState.branchKeyToStreamIdMap)) { + throw new TypeError("The streaming method is missing its branches."); + } + const streamId = this.getStreamId(streamingMethod, branch); + const key = requestContext.msg.subscription_id; + const subscription = { + id: key, + arguments: requestContext.arguments, + instance: requestContext.instance, + branchKey: branch, + streamId, + subscribeMsg: requestContext.msg, + }; + streamingMethod.protocolState.subscriptionsMap[key] = subscription; + this.session.sendFireAndForget({ + type: "accepted", + subscription_id: key, + stream_id: streamId, + }); + this.callbacks.execute(SUBSCRIPTION_ADDED, subscription, streamingMethod); + } + rejectRequest(requestContext, streamingMethod, reason) { + if (typeof reason !== "string") { + reason = ""; + } + this.sendSubscriptionFailed("Subscription rejected by user. " + reason, requestContext.msg.subscription_id); + } + pushData(streamingMethod, data, branches) { + if (typeof streamingMethod !== "object" || !Array.isArray(streamingMethod.protocolState.branchKeyToStreamIdMap)) { + return; + } + if (typeof data !== "object") { + throw new Error("Invalid arguments. Data must be an object."); + } + if (typeof branches === "string") { + branches = [branches]; + } + else if (!Array.isArray(branches) || branches.length <= 0) { + branches = []; + } + const streamIdList = streamingMethod.protocolState.branchKeyToStreamIdMap + .filter((br) => { + if (!branches || branches.length === 0) { + return true; + } + return branches.indexOf(br.key) >= 0; + }).map((br) => { + return br.streamId; + }); + streamIdList.forEach((streamId) => { + const publishMessage = { + type: "publish", + stream_id: streamId, + data, + }; + this.session.sendFireAndForget(publishMessage); + }); + } + pushDataToSingle(method, subscription, data) { + if (typeof data !== "object") { + throw new Error("Invalid arguments. Data must be an object."); + } + const postMessage = { + type: "post", + subscription_id: subscription.id, + data, + }; + this.session.sendFireAndForget(postMessage); + } + closeSingleSubscription(streamingMethod, subscription) { + if (streamingMethod.protocolState.subscriptionsMap) { + delete streamingMethod.protocolState.subscriptionsMap[subscription.id]; + } + const dropSubscriptionMessage = { + type: "drop-subscription", + subscription_id: subscription.id, + reason: "Server dropping a single subscription", + }; + this.session.sendFireAndForget(dropSubscriptionMessage); + subscription.instance; + this.callbacks.execute(SUBSCRIPTION_REMOVED, subscription, streamingMethod); + } + closeMultipleSubscriptions(streamingMethod, branchKey) { + if (typeof streamingMethod !== "object" || typeof streamingMethod.protocolState.subscriptionsMap !== "object") { + return; + } + if (!streamingMethod.protocolState.subscriptionsMap) { + return; + } + const subscriptionsMap = streamingMethod.protocolState.subscriptionsMap; + let subscriptionsToClose = Object.keys(subscriptionsMap) + .map((key) => { + return subscriptionsMap[key]; + }); + if (typeof branchKey === "string") { + subscriptionsToClose = subscriptionsToClose.filter((sub) => { + return sub.branchKey === branchKey; + }); + } + subscriptionsToClose.forEach((subscription) => { + delete subscriptionsMap[subscription.id]; + const drop = { + type: "drop-subscription", + subscription_id: subscription.id, + reason: "Server dropping all subscriptions on stream_id: " + subscription.streamId, + }; + this.session.sendFireAndForget(drop); + }); + } + getSubscriptionList(streamingMethod, branchKey) { + if (typeof streamingMethod !== "object") { + return []; + } + let subscriptions = []; + if (!streamingMethod.protocolState.subscriptionsMap) { + return []; + } + const subscriptionsMap = streamingMethod.protocolState.subscriptionsMap; + const allSubscriptions = Object.keys(subscriptionsMap) + .map((key) => { + return subscriptionsMap[key]; + }); + if (typeof branchKey !== "string") { + subscriptions = allSubscriptions; + } + else { + subscriptions = allSubscriptions.filter((sub) => { + return sub.branchKey === branchKey; + }); + } + return subscriptions; + } + getBranchList(streamingMethod) { + if (typeof streamingMethod !== "object") { + return []; + } + if (!streamingMethod.protocolState.subscriptionsMap) { + return []; + } + const subscriptionsMap = streamingMethod.protocolState.subscriptionsMap; + const allSubscriptions = Object.keys(subscriptionsMap) + .map((key) => { + return subscriptionsMap[key]; + }); + const result = []; + allSubscriptions.forEach((sub) => { + let branch = ""; + if (typeof sub === "object" && typeof sub.branchKey === "string") { + branch = sub.branchKey; + } + if (result.indexOf(branch) === -1) { + result.push(branch); + } + }); + return result; + } + onSubAdded(callback) { + this.onSubscriptionLifetimeEvent(SUBSCRIPTION_ADDED, callback); + } + onSubRequest(callback) { + this.onSubscriptionLifetimeEvent(SUBSCRIPTION_REQUEST, callback); + } + onSubRemoved(callback) { + this.onSubscriptionLifetimeEvent(SUBSCRIPTION_REMOVED, callback); + } + handleRemoveInterest(msg) { + const streamingMethod = this.serverRepository.getById(msg.method_id); + if (typeof msg.subscription_id !== "string" || + typeof streamingMethod !== "object") { + return; + } + if (!streamingMethod.protocolState.subscriptionsMap) { + return; + } + if (typeof streamingMethod.protocolState.subscriptionsMap[msg.subscription_id] !== "object") { + return; + } + const subscription = streamingMethod.protocolState.subscriptionsMap[msg.subscription_id]; + delete streamingMethod.protocolState.subscriptionsMap[msg.subscription_id]; + this.callbacks.execute(SUBSCRIPTION_REMOVED, subscription, streamingMethod); + } + onSubscriptionLifetimeEvent(eventName, handlerFunc) { + this.callbacks.add(eventName, handlerFunc); + } + getNextStreamId() { + return this.nextStreamId++ + ""; + } + handleAddInterest(msg) { + const caller = this.repository.getServerById(msg.caller_id); + const instance = caller?.instance ?? {}; + const requestContext = { + msg, + arguments: msg.arguments_kv || {}, + instance, + }; + const streamingMethod = this.serverRepository.getById(msg.method_id); + if (streamingMethod === undefined) { + const errorMsg = "No method with id " + msg.method_id + " on this server."; + this.sendSubscriptionFailed(errorMsg, msg.subscription_id); + return; + } + if (streamingMethod.protocolState.subscriptionsMap && + streamingMethod.protocolState.subscriptionsMap[msg.subscription_id]) { + this.sendSubscriptionFailed("A subscription with id " + msg.subscription_id + " already exists.", msg.subscription_id); + return; + } + this.callbacks.execute(SUBSCRIPTION_REQUEST, requestContext, streamingMethod); + } + sendSubscriptionFailed(reason, subscriptionId) { + const errorMessage = { + type: "error", + reason_uri: this.ERR_URI_SUBSCRIPTION_FAILED, + reason, + request_id: subscriptionId, + }; + this.session.sendFireAndForget(errorMessage); + } + getStreamId(streamingMethod, branchKey) { + if (typeof branchKey !== "string") { + branchKey = ""; + } + if (!streamingMethod.protocolState.branchKeyToStreamIdMap) { + throw new Error(`streaming ${streamingMethod.definition.name} method without protocol state`); + } + const needleBranch = streamingMethod.protocolState.branchKeyToStreamIdMap.filter((branch) => { + return branch.key === branchKey; + })[0]; + let streamId = (needleBranch ? needleBranch.streamId : undefined); + if (typeof streamId !== "string" || streamId === "") { + streamId = this.getNextStreamId(); + streamingMethod.protocolState.branchKeyToStreamIdMap.push({ key: branchKey, streamId }); + } + return streamId; + } + } + + class ServerProtocol { + session; + clientRepository; + serverRepository; + logger; + callbacks = CallbackRegistryFactory$1(); + streaming; + constructor(session, clientRepository, serverRepository, logger) { + this.session = session; + this.clientRepository = clientRepository; + this.serverRepository = serverRepository; + this.logger = logger; + this.streaming = new ServerStreaming(session, clientRepository, serverRepository); + this.session.on("invoke", (msg) => this.handleInvokeMessage(msg)); + } + createStream(repoMethod) { + repoMethod.protocolState.subscriptionsMap = {}; + repoMethod.protocolState.branchKeyToStreamIdMap = []; + return this.register(repoMethod, true); + } + register(repoMethod, isStreaming) { + const methodDef = repoMethod.definition; + const flags = Object.assign({}, { metadata: methodDef.flags ?? {} }, { streaming: isStreaming || false }); + const registerMsg = { + type: "register", + methods: [{ + id: repoMethod.repoId, + name: methodDef.name, + display_name: methodDef.displayName, + description: methodDef.description, + version: methodDef.version, + flags, + object_types: methodDef.objectTypes || methodDef.object_types, + input_signature: methodDef.accepts, + result_signature: methodDef.returns, + restrictions: undefined, + }], + }; + return this.session.send(registerMsg, { methodId: repoMethod.repoId }) + .then(() => { + this.logger.debug("registered method " + repoMethod.definition.name + " with id " + repoMethod.repoId); + }) + .catch((msg) => { + this.logger.warn(`failed to register method ${repoMethod.definition.name} with id ${repoMethod.repoId} - ${JSON.stringify(msg)}`); + throw msg; + }); + } + onInvoked(callback) { + this.callbacks.add("onInvoked", callback); + } + methodInvocationResult(method, invocationId, err, result) { + let msg; + if (err || err === "") { + msg = { + type: "error", + request_id: invocationId, + reason_uri: "agm.errors.client_error", + reason: err, + context: result, + peer_id: undefined, + }; + } + else { + msg = { + type: "yield", + invocation_id: invocationId, + peer_id: this.session.peerId, + result, + request_id: undefined, + }; + } + this.session.sendFireAndForget(msg); + } + async unregister(method) { + const msg = { + type: "unregister", + methods: [method.repoId], + }; + await this.session.send(msg); + } + getBranchList(method) { + return this.streaming.getBranchList(method); + } + getSubscriptionList(method, branchKey) { + return this.streaming.getSubscriptionList(method, branchKey); + } + closeAllSubscriptions(method, branchKey) { + this.streaming.closeMultipleSubscriptions(method, branchKey); + } + pushData(method, data, branches) { + this.streaming.pushData(method, data, branches); + } + pushDataToSingle(method, subscription, data) { + this.streaming.pushDataToSingle(method, subscription, data); + } + closeSingleSubscription(method, subscription) { + this.streaming.closeSingleSubscription(method, subscription); + } + acceptRequestOnBranch(requestContext, method, branch) { + this.streaming.acceptRequestOnBranch(requestContext, method, branch); + } + rejectRequest(requestContext, method, reason) { + this.streaming.rejectRequest(requestContext, method, reason); + } + onSubRequest(callback) { + this.streaming.onSubRequest(callback); + } + onSubAdded(callback) { + this.streaming.onSubAdded(callback); + } + onSubRemoved(callback) { + this.streaming.onSubRemoved(callback); + } + handleInvokeMessage(msg) { + const invocationId = msg.invocation_id; + const callerId = msg.caller_id; + const methodId = msg.method_id; + const args = msg.arguments_kv; + const methodList = this.serverRepository.getList(); + const method = methodList.filter((m) => { + return m.repoId === methodId; + })[0]; + if (method === undefined) { + return; + } + const client = this.clientRepository.getServerById(callerId)?.instance; + const invocationArgs = { args, instance: client }; + this.callbacks.execute("onInvoked", method, invocationId, invocationArgs); + } + } + + class UserSubscription { + repository; + subscriptionData; + get requestArguments() { + return this.subscriptionData.params.arguments || {}; + } + get servers() { + return this.subscriptionData.trackedServers.reduce((servers, pair) => { + if (pair.subscriptionId) { + const server = this.repository.getServerById(pair.serverId)?.instance; + if (server) { + servers.push(server); + } + } + return servers; + }, []); + } + get serverInstance() { + return this.servers[0]; + } + get stream() { + return this.subscriptionData.method; + } + constructor(repository, subscriptionData) { + this.repository = repository; + this.subscriptionData = subscriptionData; + } + onData(dataCallback) { + if (typeof dataCallback !== "function") { + throw new TypeError("The data callback must be a function."); + } + this.subscriptionData.handlers.onData.push(dataCallback); + if (this.subscriptionData.handlers.onData.length === 1 && this.subscriptionData.queued.data.length > 0) { + this.subscriptionData.queued.data.forEach((dataItem) => { + dataCallback(dataItem); + }); + } + } + onClosed(closedCallback) { + if (typeof closedCallback !== "function") { + throw new TypeError("The callback must be a function."); + } + this.subscriptionData.handlers.onClosed.push(closedCallback); + } + onFailed(callback) { + } + onConnected(callback) { + if (typeof callback !== "function") { + throw new TypeError("The callback must be a function."); + } + this.subscriptionData.handlers.onConnected.push(callback); + } + close() { + this.subscriptionData.close(); + } + setNewSubscription(newSub) { + this.subscriptionData = newSub; + } + } + + class TimedCache { + config; + cache = []; + timeoutIds = []; + constructor(config) { + this.config = config; + } + add(element) { + const id = nanoid$1(10); + this.cache.push({ id, element }); + const timeoutId = setTimeout(() => { + const elementIdx = this.cache.findIndex((entry) => entry.id === id); + if (elementIdx < 0) { + return; + } + this.cache.splice(elementIdx, 1); + }, this.config.ELEMENT_TTL_MS); + this.timeoutIds.push(timeoutId); + } + flush() { + const elements = this.cache.map((entry) => entry.element); + this.timeoutIds.forEach((id) => clearInterval(id)); + this.cache = []; + this.timeoutIds = []; + return elements; + } + } + + const STATUS_AWAITING_ACCEPT = "awaitingAccept"; + const STATUS_SUBSCRIBED = "subscribed"; + const ERR_MSG_SUB_FAILED = "Subscription failed."; + const ERR_MSG_SUB_REJECTED = "Subscription rejected."; + const ON_CLOSE_MSG_SERVER_INIT = "ServerInitiated"; + const ON_CLOSE_MSG_CLIENT_INIT = "ClientInitiated"; + class ClientStreaming { + session; + repository; + logger; + subscriptionsList = {}; + timedCache = new TimedCache({ ELEMENT_TTL_MS: 10000 }); + subscriptionIdToLocalKeyMap = {}; + nextSubLocalKey = 0; + constructor(session, repository, logger) { + this.session = session; + this.repository = repository; + this.logger = logger; + session.on("subscribed", this.handleSubscribed); + session.on("event", this.handleEventData); + session.on("subscription-cancelled", this.handleSubscriptionCancelled); + } + subscribe(streamingMethod, params, targetServers, success, error, existingSub) { + if (targetServers.length === 0) { + error({ + method: streamingMethod, + called_with: params.arguments, + message: ERR_MSG_SUB_FAILED + " No available servers matched the target params.", + }); + return; + } + const subLocalKey = this.getNextSubscriptionLocalKey(); + const pendingSub = this.registerSubscription(subLocalKey, streamingMethod, params, success, error, params.methodResponseTimeout || 10000, existingSub); + if (typeof pendingSub !== "object") { + error({ + method: streamingMethod, + called_with: params.arguments, + message: ERR_MSG_SUB_FAILED + " Unable to register the user callbacks.", + }); + return; + } + targetServers.forEach((target) => { + const serverId = target.server.id; + const method = target.methods.find((m) => m.name === streamingMethod.name); + if (!method) { + this.logger.error(`can not find method ${streamingMethod.name} for target ${target.server.id}`); + return; + } + pendingSub.trackedServers.push({ + serverId, + subscriptionId: undefined, + }); + const msg = { + type: "subscribe", + server_id: serverId, + method_id: method.gatewayId, + arguments_kv: params.arguments, + }; + this.session.send(msg, { serverId, subLocalKey }) + .then((m) => this.handleSubscribed(m)) + .catch((err) => this.handleErrorSubscribing(err)); + }); + } + drainSubscriptions() { + const existing = Object.values(this.subscriptionsList); + this.subscriptionsList = {}; + this.subscriptionIdToLocalKeyMap = {}; + return existing; + } + drainSubscriptionsCache() { + return this.timedCache.flush(); + } + getNextSubscriptionLocalKey() { + const current = this.nextSubLocalKey; + this.nextSubLocalKey += 1; + return current; + } + registerSubscription(subLocalKey, method, params, success, error, timeout, existingSub) { + const subsInfo = { + localKey: subLocalKey, + status: STATUS_AWAITING_ACCEPT, + method, + params, + success, + error, + trackedServers: [], + handlers: { + onData: existingSub?.handlers.onData || [], + onClosed: existingSub?.handlers.onClosed || [], + onConnected: existingSub?.handlers.onConnected || [], + }, + queued: { + data: [], + closers: [], + }, + timeoutId: undefined, + close: () => this.closeSubscription(subLocalKey), + subscription: existingSub?.subscription + }; + if (!existingSub) { + if (params.onData) { + subsInfo.handlers.onData.push(params.onData); + } + if (params.onClosed) { + subsInfo.handlers.onClosed.push(params.onClosed); + } + if (params.onConnected) { + subsInfo.handlers.onConnected.push(params.onConnected); + } + } + this.subscriptionsList[subLocalKey] = subsInfo; + subsInfo.timeoutId = setTimeout(() => { + if (this.subscriptionsList[subLocalKey] === undefined) { + return; + } + const pendingSub = this.subscriptionsList[subLocalKey]; + if (pendingSub.status === STATUS_AWAITING_ACCEPT) { + error({ + method, + called_with: params.arguments, + message: ERR_MSG_SUB_FAILED + " Subscription attempt timed out after " + timeout + " ms.", + }); + delete this.subscriptionsList[subLocalKey]; + } + else if (pendingSub.status === STATUS_SUBSCRIBED && pendingSub.trackedServers.length > 0) { + pendingSub.trackedServers = pendingSub.trackedServers.filter((server) => { + return (typeof server.subscriptionId !== "undefined"); + }); + delete pendingSub.timeoutId; + if (pendingSub.trackedServers.length <= 0) { + this.callOnClosedHandlers(pendingSub); + delete this.subscriptionsList[subLocalKey]; + } + } + }, timeout); + return subsInfo; + } + handleErrorSubscribing = (errorResponse) => { + const tag = errorResponse._tag; + const subLocalKey = tag.subLocalKey; + const pendingSub = this.subscriptionsList[subLocalKey]; + if (typeof pendingSub !== "object") { + return; + } + pendingSub.trackedServers = pendingSub.trackedServers.filter((server) => { + return server.serverId !== tag.serverId; + }); + if (pendingSub.trackedServers.length <= 0) { + clearTimeout(pendingSub.timeoutId); + if (pendingSub.status === STATUS_AWAITING_ACCEPT) { + const reason = (typeof errorResponse.reason === "string" && errorResponse.reason !== "") ? + ' Publisher said "' + errorResponse.reason + '".' : + " No reason given."; + const callArgs = typeof pendingSub.params.arguments === "object" ? + JSON.stringify(pendingSub.params.arguments) : + "{}"; + pendingSub.error({ + message: ERR_MSG_SUB_REJECTED + reason + " Called with:" + callArgs, + called_with: pendingSub.params.arguments, + method: pendingSub.method, + }); + } + else if (pendingSub.status === STATUS_SUBSCRIBED) { + this.callOnClosedHandlers(pendingSub); + } + delete this.subscriptionsList[subLocalKey]; + } + }; + handleSubscribed = (msg) => { + const subLocalKey = msg._tag.subLocalKey; + const pendingSub = this.subscriptionsList[subLocalKey]; + if (typeof pendingSub !== "object") { + return; + } + const serverId = msg._tag.serverId; + const acceptingServer = pendingSub.trackedServers + .filter((server) => { + return server.serverId === serverId; + })[0]; + if (typeof acceptingServer !== "object") { + return; + } + acceptingServer.subscriptionId = msg.subscription_id; + this.subscriptionIdToLocalKeyMap[msg.subscription_id] = subLocalKey; + const isFirstResponse = (pendingSub.status === STATUS_AWAITING_ACCEPT); + pendingSub.status = STATUS_SUBSCRIBED; + if (isFirstResponse) { + let reconnect = false; + let sub = pendingSub.subscription; + if (sub) { + sub.setNewSubscription(pendingSub); + pendingSub.success(sub); + reconnect = true; + } + else { + sub = new UserSubscription(this.repository, pendingSub); + pendingSub.subscription = sub; + pendingSub.success(sub); + } + for (const handler of pendingSub.handlers.onConnected) { + try { + handler(sub.serverInstance, reconnect); + } + catch (e) { + } + } + } + }; + handleEventData = (msg) => { + const subLocalKey = this.subscriptionIdToLocalKeyMap[msg.subscription_id]; + if (typeof subLocalKey === "undefined") { + return; + } + const subscription = this.subscriptionsList[subLocalKey]; + if (typeof subscription !== "object") { + return; + } + const trackedServersFound = subscription.trackedServers.filter((s) => { + return s.subscriptionId === msg.subscription_id; + }); + if (trackedServersFound.length !== 1) { + return; + } + const isPrivateData = msg.oob; + const sendingServerId = trackedServersFound[0].serverId; + const server = this.repository.getServerById(sendingServerId); + const receivedStreamData = () => { + return { + data: msg.data, + server: server?.instance ?? {}, + requestArguments: subscription.params.arguments, + message: undefined, + private: isPrivateData, + }; + }; + const onDataHandlers = subscription.handlers.onData; + const queuedData = subscription.queued.data; + if (onDataHandlers.length > 0) { + onDataHandlers.forEach((callback) => { + if (typeof callback === "function") { + callback(receivedStreamData()); + } + }); + } + else { + queuedData.push(receivedStreamData()); + } + }; + handleSubscriptionCancelled = (msg) => { + const subLocalKey = this.subscriptionIdToLocalKeyMap[msg.subscription_id]; + if (typeof subLocalKey === "undefined") { + return; + } + const subscription = this.subscriptionsList[subLocalKey]; + if (typeof subscription !== "object") { + return; + } + const expectedNewLength = subscription.trackedServers.length - 1; + subscription.trackedServers = subscription.trackedServers.filter((server) => { + if (server.subscriptionId === msg.subscription_id) { + subscription.queued.closers.push(server.serverId); + return false; + } + else { + return true; + } + }); + if (subscription.trackedServers.length !== expectedNewLength) { + return; + } + if (subscription.trackedServers.length <= 0) { + this.timedCache.add(subscription); + clearTimeout(subscription.timeoutId); + this.callOnClosedHandlers(subscription); + delete this.subscriptionsList[subLocalKey]; + } + delete this.subscriptionIdToLocalKeyMap[msg.subscription_id]; + }; + callOnClosedHandlers(subscription, reason) { + const closersCount = subscription.queued.closers.length; + const closingServerId = (closersCount > 0) ? subscription.queued.closers[closersCount - 1] : null; + let closingServer; + if (closingServerId !== undefined && typeof closingServerId === "string") { + closingServer = this.repository.getServerById(closingServerId)?.instance ?? {}; + } + subscription.handlers.onClosed.forEach((callback) => { + if (typeof callback !== "function") { + return; + } + callback({ + message: reason || ON_CLOSE_MSG_SERVER_INIT, + requestArguments: subscription.params.arguments || {}, + server: closingServer, + stream: subscription.method, + }); + }); + } + closeSubscription(subLocalKey) { + const subscription = this.subscriptionsList[subLocalKey]; + if (typeof subscription !== "object") { + return; + } + subscription.trackedServers.forEach((server) => { + if (typeof server.subscriptionId === "undefined") { + return; + } + subscription.queued.closers.push(server.serverId); + this.session.sendFireAndForget({ + type: "unsubscribe", + subscription_id: server.subscriptionId, + reason_uri: "", + reason: ON_CLOSE_MSG_CLIENT_INIT, + }); + delete this.subscriptionIdToLocalKeyMap[server.subscriptionId]; + }); + subscription.trackedServers = []; + this.callOnClosedHandlers(subscription, ON_CLOSE_MSG_CLIENT_INIT); + delete this.subscriptionsList[subLocalKey]; + } + } + + class ClientProtocol { + session; + repository; + logger; + streaming; + constructor(session, repository, logger) { + this.session = session; + this.repository = repository; + this.logger = logger; + session.on("peer-added", (msg) => this.handlePeerAdded(msg)); + session.on("peer-removed", (msg) => this.handlePeerRemoved(msg)); + session.on("methods-added", (msg) => this.handleMethodsAddedMessage(msg)); + session.on("methods-removed", (msg) => this.handleMethodsRemovedMessage(msg)); + this.streaming = new ClientStreaming(session, repository, logger); + } + subscribe(stream, options, targetServers, success, error, existingSub) { + this.streaming.subscribe(stream, options, targetServers, success, error, existingSub); + } + invoke(id, method, args, target) { + const serverId = target.id; + const methodId = method.gatewayId; + const msg = { + type: "call", + server_id: serverId, + method_id: methodId, + arguments_kv: args, + }; + return this.session.send(msg, { invocationId: id, serverId }) + .then((m) => this.handleResultMessage(m)) + .catch((err) => this.handleInvocationError(err)); + } + drainSubscriptions() { + return this.streaming.drainSubscriptions(); + } + drainSubscriptionsCache() { + return this.streaming.drainSubscriptionsCache(); + } + handlePeerAdded(msg) { + const newPeerId = msg.new_peer_id; + const remoteId = msg.identity; + const isLocal = msg.meta ? msg.meta.local : true; + const pid = Number(remoteId.process); + const serverInfo = { + machine: remoteId.machine, + pid: isNaN(pid) ? remoteId.process : pid, + instance: remoteId.instance, + application: remoteId.application, + applicationName: remoteId.applicationName, + environment: remoteId.environment, + region: remoteId.region, + user: remoteId.user, + windowId: remoteId.windowId, + peerId: newPeerId, + api: remoteId.api, + isLocal + }; + this.repository.addServer(serverInfo, newPeerId); + } + handlePeerRemoved(msg) { + const removedPeerId = msg.removed_id; + const reason = msg.reason; + this.repository.removeServerById(removedPeerId, reason); + } + handleMethodsAddedMessage(msg) { + const serverId = msg.server_id; + const methods = msg.methods; + methods.forEach((method) => { + this.repository.addServerMethod(serverId, method); + }); + } + handleMethodsRemovedMessage(msg) { + const serverId = msg.server_id; + const methodIdList = msg.methods; + const server = this.repository.getServerById(serverId); + if (server) { + const serverMethodKeys = Object.keys(server.methods); + serverMethodKeys.forEach((methodKey) => { + const method = server.methods[methodKey]; + if (methodIdList.indexOf(method.gatewayId) > -1) { + this.repository.removeServerMethod(serverId, methodKey); + } + }); + } + } + handleResultMessage(msg) { + const invocationId = msg._tag.invocationId; + const result = msg.result; + const serverId = msg._tag.serverId; + const server = this.repository.getServerById(serverId); + return { + invocationId, + result, + instance: server?.instance, + status: InvokeStatus.Success, + message: "" + }; + } + handleInvocationError(msg) { + this.logger.debug(`handle invocation error ${JSON.stringify(msg)}`); + if ("_tag" in msg) { + const invocationId = msg._tag.invocationId; + const serverId = msg._tag.serverId; + const server = this.repository.getServerById(serverId); + const message = msg.reason; + const context = msg.context; + return { + invocationId, + result: context, + instance: server?.instance, + status: InvokeStatus.Error, + message + }; + } + else { + return { + invocationId: "", + message: msg.message, + status: InvokeStatus.Error, + error: msg + }; + } + } + } + + function gW3ProtocolFactory (instance, connection, clientRepository, serverRepository, libConfig, interop) { + const logger = libConfig.logger.subLogger("gw3-protocol"); + let resolveReadyPromise; + const readyPromise = new Promise((resolve) => { + resolveReadyPromise = resolve; + }); + const session = connection.domain("agm", ["subscribed"]); + const server = new ServerProtocol(session, clientRepository, serverRepository, logger.subLogger("server")); + const client = new ClientProtocol(session, clientRepository, logger.subLogger("client")); + async function handleReconnect() { + logger.info("reconnected - will replay registered methods and subscriptions"); + client.drainSubscriptionsCache().forEach((sub) => { + const methodInfo = sub.method; + const params = Object.assign({}, sub.params); + logger.info(`trying to soft-re-subscribe to method ${methodInfo.name}, with params: ${JSON.stringify(params)}`); + interop.client.subscribe(methodInfo, params, undefined, undefined, sub).then(() => logger.info(`soft-subscribing to method ${methodInfo.name} DONE`)).catch((error) => logger.warn(`subscribing to method ${methodInfo.name} failed: ${JSON.stringify(error)}}`)); + }); + const reconnectionPromises = []; + const existingSubscriptions = client.drainSubscriptions(); + for (const sub of existingSubscriptions) { + const methodInfo = sub.method; + const params = Object.assign({}, sub.params); + logger.info(`trying to re-subscribe to method ${methodInfo.name}, with params: ${JSON.stringify(params)}`); + reconnectionPromises.push(interop.client.subscribe(methodInfo, params, undefined, undefined, sub).then(() => logger.info(`subscribing to method ${methodInfo.name} DONE`))); + } + const registeredMethods = serverRepository.getList(); + serverRepository.reset(); + for (const method of registeredMethods) { + const def = method.definition; + if (method.stream) { + reconnectionPromises.push(interop.server.createStream(def, method.streamCallbacks, undefined, undefined, method.stream) + .then(() => logger.info(`subscribing to method ${def.name} DONE`)) + .catch(() => logger.warn(`subscribing to method ${def.name} FAILED`))); + } + else if (method?.theFunction?.userCallback) { + reconnectionPromises.push(interop.register(def, method.theFunction.userCallback) + .then(() => logger.info(`registering method ${def.name} DONE`)) + .catch(() => logger.warn(`registering method ${def.name} FAILED`))); + } + else if (method?.theFunction?.userCallbackAsync) { + reconnectionPromises.push(interop.registerAsync(def, method.theFunction.userCallbackAsync) + .then(() => logger.info(`registering method ${def.name} DONE`)) + .catch(() => logger.warn(`registering method ${def.name} FAILED`))); + } + } + await Promise.all(reconnectionPromises); + logger.info("Interop is re-announced"); + } + function handleInitialJoin() { + if (resolveReadyPromise) { + resolveReadyPromise({ + client, + server, + }); + resolveReadyPromise = undefined; + } + } + session.onJoined((reconnect) => { + clientRepository.addServer(instance, connection.peerId); + if (reconnect) { + handleReconnect().then(() => connection.setLibReAnnounced({ name: "interop" })).catch((error) => logger.warn(`Error while re-announcing interop: ${JSON.stringify(error)}`)); + } + else { + handleInitialJoin(); + } + }); + session.onLeft(() => { + clientRepository.reset(); + }); + session.join(); + return readyPromise; + } + + class Interop { + instance; + readyPromise; + client; + server; + unwrappedInstance; + protocol; + clientRepository; + serverRepository; + constructor(configuration) { + if (typeof configuration === "undefined") { + throw new Error("configuration is required"); + } + if (typeof configuration.connection === "undefined") { + throw new Error("configuration.connections is required"); + } + const connection = configuration.connection; + if (typeof configuration.methodResponseTimeout !== "number") { + configuration.methodResponseTimeout = 30 * 1000; + } + if (typeof configuration.waitTimeoutMs !== "number") { + configuration.waitTimeoutMs = 30 * 1000; + } + this.unwrappedInstance = new InstanceWrapper(this, undefined, connection); + this.instance = this.unwrappedInstance.unwrap(); + this.clientRepository = new ClientRepository(configuration.logger.subLogger("cRep"), this); + this.serverRepository = new ServerRepository(); + let protocolPromise; + if (connection.protocolVersion === 3) { + protocolPromise = gW3ProtocolFactory(this.instance, connection, this.clientRepository, this.serverRepository, configuration, this); + } + else { + throw new Error(`protocol ${connection.protocolVersion} not supported`); + } + this.readyPromise = protocolPromise.then((protocol) => { + this.protocol = protocol; + this.client = new Client(this.protocol, this.clientRepository, this.instance, configuration); + this.server = new Server(this.protocol, this.serverRepository); + return this; + }); + } + ready() { + return this.readyPromise; + } + serverRemoved(callback) { + return this.client.serverRemoved(callback); + } + serverAdded(callback) { + return this.client.serverAdded(callback); + } + serverMethodRemoved(callback) { + return this.client.serverMethodRemoved(callback); + } + serverMethodAdded(callback) { + return this.client.serverMethodAdded(callback); + } + methodRemoved(callback) { + return this.client.methodRemoved(callback); + } + methodAdded(callback) { + return this.client.methodAdded(callback); + } + methodsForInstance(instance) { + return this.client.methodsForInstance(instance); + } + methods(methodFilter) { + return this.client.methods(methodFilter); + } + servers(methodFilter) { + return this.client.servers(methodFilter); + } + subscribe(method, options, successCallback, errorCallback) { + return this.client.subscribe(method, options, successCallback, errorCallback); + } + createStream(streamDef, callbacks, successCallback, errorCallback) { + return this.server.createStream(streamDef, callbacks, successCallback, errorCallback); + } + unregister(methodFilter) { + return this.server.unregister(methodFilter); + } + registerAsync(methodDefinition, callback) { + return this.server.registerAsync(methodDefinition, callback); + } + register(methodDefinition, callback) { + return this.server.register(methodDefinition, callback); + } + invoke(methodFilter, argumentObj, target, additionalOptions, success, error) { + return this.client.invoke(methodFilter, argumentObj, target, additionalOptions, success, error); + } + waitForMethod(name) { + const pw = new PromiseWrapper$1(); + const unsubscribe = this.client.methodAdded((m) => { + if (m.name === name) { + unsubscribe(); + pw.resolve(m); + } + }); + return pw.promise; + } + } + + const successMessages = ["subscribed", "success"]; + class MessageBus { + connection; + logger; + peerId; + session; + subscriptions; + readyPromise; + constructor(connection, logger) { + this.connection = connection; + this.logger = logger; + this.peerId = connection.peerId; + this.subscriptions = []; + this.session = connection.domain("bus", successMessages); + this.readyPromise = this.session.join(); + this.readyPromise.then(() => { + this.watchOnEvent(); + }); + } + ready() { + return this.readyPromise; + } + publish = (topic, data, options) => { + const { routingKey, target } = options || {}; + const args = this.removeEmptyValues({ + type: "publish", + topic, + data, + peer_id: this.peerId, + routing_key: routingKey, + target_identity: target + }); + this.session.send(args); + }; + subscribe = (topic, callback, options) => { + return new Promise((resolve, reject) => { + const { routingKey, target } = options || {}; + const args = this.removeEmptyValues({ + type: "subscribe", + topic, + peer_id: this.peerId, + routing_key: routingKey, + source: target + }); + this.session.send(args) + .then((response) => { + const { subscription_id } = response; + this.subscriptions.push({ subscription_id, topic, callback, source: target }); + resolve({ + unsubscribe: () => { + this.session.send({ type: "unsubscribe", subscription_id, peer_id: this.peerId }); + this.subscriptions = this.subscriptions.filter((s) => s.subscription_id !== subscription_id); + return Promise.resolve(); + } + }); + }) + .catch((error) => reject(error)); + }); + }; + watchOnEvent = () => { + this.session.on("event", (args) => { + const { data, subscription_id } = args; + const source = args["publisher-identity"]; + const subscription = this.subscriptions.find((s) => s.subscription_id === subscription_id); + if (subscription) { + if (!subscription.source) { + subscription.callback(data, subscription.topic, source); + } + else { + if (this.keysMatch(subscription.source, source)) { + subscription.callback(data, subscription.topic, source); + } + } + } + }); + }; + removeEmptyValues(obj) { + const cleaned = {}; + Object.keys(obj).forEach((key) => { + if (obj[key] !== undefined && obj[key] !== null) { + cleaned[key] = obj[key]; + } + }); + return cleaned; + } + keysMatch(obj1, obj2) { + const keysObj1 = Object.keys(obj1); + let allMatch = true; + keysObj1.forEach((key) => { + if (obj1[key] !== obj2[key]) { + allMatch = false; + } + }); + return allMatch; + } + } + + const IOConnectCoreFactory = (userConfig, ext) => { + const iodesktop = typeof window === "object" ? (window.iodesktop ?? window.glue42gd) : undefined; + const preloadPromise = typeof window === "object" ? (window.gdPreloadPromise ?? Promise.resolve()) : Promise.resolve(); + const glueInitTimer = timer("glue"); + userConfig = userConfig || {}; + ext = ext || {}; + const internalConfig = prepareConfig$1(userConfig, ext, iodesktop); + let _connection; + let _interop; + let _logger; + let _metrics; + let _contexts; + let _bus; + let _allowTrace; + const libs = {}; + function registerLib(name, inner, t) { + _allowTrace = _logger.canPublish("trace"); + if (_allowTrace) { + _logger.trace(`registering ${name} module`); + } + const done = (e) => { + inner.initTime = t.stop(); + inner.initEndTime = t.endTime; + inner.marks = t.marks; + if (!_allowTrace) { + return; + } + const traceMessage = e ? + `${name} failed - ${e.message}` : + `${name} is ready - ${t.endTime - t.startTime}`; + _logger.trace(traceMessage); + }; + inner.initStartTime = t.startTime; + if (inner.ready) { + inner.ready() + .then(() => { + done(); + }) + .catch((e) => { + const error = typeof e === "string" ? new Error(e) : e; + done(error); + }); + } + else { + done(); + } + if (!Array.isArray(name)) { + name = [name]; + } + name.forEach((n) => { + libs[n] = inner; + IOConnectCoreFactory[n] = inner; + }); + } + function setupConnection() { + const initTimer = timer("connection"); + _connection = new Connection(internalConfig.connection, _logger.subLogger("connection")); + let authPromise = Promise.resolve(internalConfig.auth); + if (internalConfig.connection && !internalConfig.auth) { + if (iodesktop) { + authPromise = iodesktop.getGWToken() + .then((token) => { + return { + gatewayToken: token + }; + }); + } + else if (typeof window !== "undefined" && window?.glue42electron) { + if (typeof window.glue42electron.gwToken === "string") { + authPromise = Promise.resolve({ + gatewayToken: window.glue42electron.gwToken + }); + } + } + else { + authPromise = Promise.reject("You need to provide auth information"); + } + } + return authPromise + .then((authConfig) => { + initTimer.mark("auth-promise-resolved"); + let authRequest; + if (Object.prototype.toString.call(authConfig) === "[object Object]") { + authRequest = authConfig; + } + else { + throw new Error("Invalid auth object - " + JSON.stringify(authConfig)); + } + return _connection.login(authRequest); + }) + .then(() => { + registerLib("connection", _connection, initTimer); + return internalConfig; + }) + .catch((e) => { + if (_connection) { + _connection.logout(); + } + throw e; + }); + } + function setupLogger() { + const initTimer = timer("logger"); + _logger = new Logger$1(`${internalConfig.connection.identity?.application}`, undefined, internalConfig.customLogger); + _logger.consoleLevel(internalConfig.logger.console); + _logger.publishLevel(internalConfig.logger.publish); + if (_logger.canPublish("debug")) { + _logger.debug("initializing glue..."); + } + registerLib("logger", _logger, initTimer); + return Promise.resolve(undefined); + } + function setupMetrics() { + const initTimer = timer("metrics"); + const config = internalConfig.metrics; + const metricsPublishingEnabledFunc = iodesktop?.getMetricsPublishingEnabled; + const identity = internalConfig.connection.identity; + const canUpdateMetric = metricsPublishingEnabledFunc ? metricsPublishingEnabledFunc : () => true; + const disableAutoAppSystem = (typeof config !== "boolean" && config.disableAutoAppSystem) ?? false; + _metrics = metrics({ + connection: config ? _connection : undefined, + logger: _logger.subLogger("metrics"), + canUpdateMetric, + system: "Glue42", + service: identity?.service ?? iodesktop?.applicationName ?? internalConfig.application, + instance: identity?.instance ?? identity?.windowId ?? nanoid$1(10), + disableAutoAppSystem, + pagePerformanceMetrics: typeof config !== "boolean" ? config?.pagePerformanceMetrics : undefined + }); + registerLib("metrics", _metrics, initTimer); + return Promise.resolve(); + } + function setupInterop() { + const initTimer = timer("interop"); + const agmConfig = { + connection: _connection, + logger: _logger.subLogger("interop"), + }; + _interop = new Interop(agmConfig); + Logger$1.Interop = _interop; + registerLib(["interop", "agm"], _interop, initTimer); + return Promise.resolve(); + } + function setupContexts() { + const hasActivities = (internalConfig.activities && _connection.protocolVersion === 3); + const needsContexts = internalConfig.contexts || hasActivities; + if (needsContexts) { + const initTimer = timer("contexts"); + _contexts = new ContextsModule({ + connection: _connection, + logger: _logger.subLogger("contexts"), + trackAllContexts: typeof internalConfig.contexts === "object" ? internalConfig.contexts.trackAllContexts : false, + reAnnounceKnownContexts: typeof internalConfig.contexts === "object" ? internalConfig.contexts.reAnnounceKnownContexts : false + }); + registerLib("contexts", _contexts, initTimer); + return _contexts; + } + else { + const replayer = _connection.replayer; + if (replayer) { + replayer.drain(ContextMessageReplaySpec.name); + } + } + } + async function setupBus() { + if (!internalConfig.bus) { + return Promise.resolve(); + } + const initTimer = timer("bus"); + _bus = new MessageBus(_connection, _logger.subLogger("bus")); + registerLib("bus", _bus, initTimer); + return Promise.resolve(); + } + function setupExternalLibs(externalLibs) { + try { + externalLibs.forEach((lib) => { + setupExternalLib(lib.name, lib.create); + }); + return Promise.resolve(); + } + catch (e) { + return Promise.reject(e); + } + } + function setupExternalLib(name, createCallback) { + const initTimer = timer(name); + const lib = createCallback(libs); + if (lib) { + registerLib(name, lib, initTimer); + } + } + function waitForLibs() { + const libsReadyPromises = Object.keys(libs).map((key) => { + const lib = libs[key]; + return lib.ready ? + lib.ready() : Promise.resolve(); + }); + return Promise.all(libsReadyPromises); + } + function constructGlueObject() { + const feedbackFunc = (feedbackInfo) => { + if (!_interop) { + return; + } + _interop.invoke("T42.ACS.Feedback", feedbackInfo, "best"); + }; + const info = { + coreVersion: version$1, + version: internalConfig.version + }; + glueInitTimer.stop(); + const glue = { + feedback: feedbackFunc, + info, + logger: _logger, + interop: _interop, + agm: _interop, + connection: _connection, + metrics: _metrics, + contexts: _contexts, + bus: _bus, + version: internalConfig.version, + userConfig, + done: () => { + _logger?.info("done called by user..."); + return _connection.logout(); + } + }; + glue.performance = { + get glueVer() { + return internalConfig.version; + }, + get glueConfig() { + return JSON.stringify(userConfig); + }, + get browser() { + return window.performance.timing.toJSON(); + }, + get memory() { + return window.performance.memory; + }, + get initTimes() { + const all = getAllTimers(); + return Object.keys(all).map((key) => { + const t = all[key]; + return { + name: key, + duration: t.endTime - t.startTime, + marks: t.marks, + startTime: t.startTime, + endTime: t.endTime + }; + }); + } + }; + Object.keys(libs).forEach((key) => { + const lib = libs[key]; + glue[key] = lib; + }); + glue.config = {}; + Object.keys(internalConfig).forEach((k) => { + glue.config[k] = internalConfig[k]; + }); + if (ext && ext.extOptions) { + Object.keys(ext.extOptions).forEach((k) => { + glue.config[k] = ext?.extOptions[k]; + }); + } + if (ext?.enrichGlue) { + ext.enrichGlue(glue); + } + if (iodesktop && iodesktop.updatePerfData) { + iodesktop.updatePerfData(glue.performance); + } + if (glue.agm) { + const deprecatedDecorator = (fn, wrong, proper) => { + return function () { + glue.logger.warn(`glue.js - 'glue.agm.${wrong}' method is deprecated, use 'glue.interop.${proper}' instead.`); + return fn.apply(glue.agm, arguments); + }; + }; + const agmAny = glue.agm; + agmAny.method_added = deprecatedDecorator(glue.agm.methodAdded, "method_added", "methodAdded"); + agmAny.method_removed = deprecatedDecorator(glue.agm.methodRemoved, "method_removed", "methodRemoved"); + agmAny.server_added = deprecatedDecorator(glue.agm.serverAdded, "server_added", "serverAdded"); + agmAny.server_method_aded = deprecatedDecorator(glue.agm.serverMethodAdded, "server_method_aded", "serverMethodAdded"); + agmAny.server_method_removed = deprecatedDecorator(glue.agm.serverMethodRemoved, "server_method_removed", "serverMethodRemoved"); + } + return glue; + } + async function registerInstanceIfNeeded() { + const RegisterInstanceMethodName = "T42.ACS.RegisterInstance"; + if (Utils$1.isNode() && typeof process.env._GD_STARTING_CONTEXT_ === "undefined" && typeof userConfig?.application !== "undefined") { + const isMethodAvailable = _interop.methods({ name: RegisterInstanceMethodName }).length > 0; + if (isMethodAvailable) { + try { + await _interop.invoke(RegisterInstanceMethodName, { appName: userConfig?.application, pid: process.pid }); + } + catch (error) { + const typedError = error; + _logger.error(`Cannot register as an instance: ${JSON.stringify(typedError.message)}`); + } + } + } + } + return preloadPromise + .then(setupLogger) + .then(setupConnection) + .then(() => Promise.all([setupMetrics(), setupInterop(), setupContexts(), setupBus()])) + .then(() => _interop.readyPromise) + .then(() => registerInstanceIfNeeded()) + .then(() => { + return setupExternalLibs(internalConfig.libs || []); + }) + .then(waitForLibs) + .then(constructGlueObject) + .catch((err) => { + return Promise.reject({ + err, + libs + }); + }); + }; + if (typeof window !== "undefined") { + window.IOConnectCore = IOConnectCoreFactory; + } + IOConnectCoreFactory.version = version$1; + IOConnectCoreFactory.default = IOConnectCoreFactory; + + class ActivityEntity { + constructor(id) { + this._id = id; + } + get id() { + return this._id; + } + _update(other) { + if (other._id !== this._id) { + throw Error("Can not update from entity with different id."); + } + this._updateCore(other); + } + _updateCore(other) { + return; + } + _beforeDelete(other) { + return; + } + } + + function isNumber(arg) { + return typeof arg === "number"; + } + function isString(arg) { + return typeof arg === "string"; + } + function isObject(arg) { + return typeof arg === "object" && !Array.isArray(arg) && arg !== null; + } + function isArray(arg) { + if (Array.isArray) { + return Array.isArray(arg); + } + return toString.call(arg) === "[object Array]"; + } + function isUndefined(arg) { + return typeof arg === "undefined"; + } + function isUndefinedOrNull(arg) { + return arg === null || typeof arg === "undefined"; + } + function isNullOrWhiteSpace(str) { + return (typeof str !== "string" || !str || str.length === 0 || /^\s*$/.test(str)); + } + function isBoolean(obj) { + return obj === true || obj === false || toString.call(obj) === "[object Boolean]"; + } + function isFunction(arg) { + return !!(arg && arg.constructor && arg.call && arg.apply); + } + function some(array, predicate) { + for (let index = 0; index < array.length; index++) { + if (predicate(array[index], index)) { + return true; + } + } + return false; + } + function ifNotUndefined(what, doWithIt) { + if (typeof what !== "undefined") { + doWithIt(what); + } + } + function promisify$1(promise, successCallback, errorCallback) { + if (typeof successCallback !== "function" && typeof errorCallback !== "function") { + return promise; + } + if (typeof successCallback !== "function") { + successCallback = () => { return; }; + } + else if (typeof errorCallback !== "function") { + errorCallback = () => { return; }; + } + promise.then(successCallback, errorCallback); + } + + class ActivityType extends ActivityEntity { + constructor(name, ownerWindow, helperWindows, description) { + super(name); + this._name = name; + this._description = description; + this._ownerWindow = ownerWindow; + this._helperWindows = helperWindows || []; + } + get name() { + return this._name; + } + get description() { + return this._description; + } + get helperWindows() { + return this._helperWindows.map((hw) => this.covertToWindowDef(hw)); + } + get ownerWindow() { + return this.covertToWindowDef(this._ownerWindow); + } + initiate(context, callback, configuration) { + return this._manager.initiate(this._name, context, callback, configuration); + } + _updateCore(other) { + super._updateCore(other); + ifNotUndefined(other._description, (x) => this._description = x); + ifNotUndefined(other._ownerWindow, (x) => this._ownerWindow = x); + ifNotUndefined(other._helperWindows, (x) => this._helperWindows = x); + } + covertToWindowDef(windowType) { + var _a, _b; + return { + type: (_a = windowType === null || windowType === void 0 ? void 0 : windowType.id) === null || _a === void 0 ? void 0 : _a.type, + name: (_b = windowType === null || windowType === void 0 ? void 0 : windowType.id) === null || _b === void 0 ? void 0 : _b.name + }; + } + } + + class WindowType extends ActivityEntity { + constructor(name, appByWindowTypeGetter) { + super(name); + this._name = name; + this._appByWindowTypeGetter = appByWindowTypeGetter; + } + get name() { + return this._name; + } + get config() { + return this._appByWindowTypeGetter(this._name); + } + get windows() { + return this._manager.getWindows({ type: this._name }); + } + create(activity, configuration) { + const definition = Object.assign({ type: this.name, name: this.name, isIndependent: false }, configuration); + return this._manager.createWindow(activity, definition); + } + } + + class EntityEvent { + constructor(entitiy, context) { + this.entity = entitiy; + this.context = context; + } + } + class EntityEventContext { + constructor(eventType) { + this.type = eventType; + } + } + class ActivityStatusChangeEventContext extends EntityEventContext { + constructor(newStatus, oldStatus) { + super(EntityEventType.StatusChange); + this.newStatus = newStatus; + this.oldStatus = oldStatus; + } + } + class ActivityContextChangedEventContext extends EntityEventContext { + constructor(context, updated, removed) { + super(EntityEventType.ActivityContextChange); + this.context = typeof context === "string" ? JSON.parse(context) : context; + this.updated = updated; + this.removed = removed; + } + } + class EntityEventType { + } + EntityEventType.Added = "added"; + EntityEventType.Removed = "removed"; + EntityEventType.Updated = "updated"; + EntityEventType.Closed = "closed"; + EntityEventType.StatusChange = "statusChange"; + EntityEventType.ActivityContextChange = "activityContextUpdate"; + EntityEventType.ActivityWindowEvent = "activityWindowEvent"; + EntityEventType.ActivityWindowJoinedActivity = "joined"; + EntityEventType.ActivityWindowLeftActivity = "left"; + class ActivityState { + } + ActivityState.Created = "created"; + ActivityState.Started = "started"; + ActivityState.Destroyed = "destroyed"; + + class ActivityAGM { + constructor(activity) { + this._activity = activity; + } + register(definition, handler) { + this._ensureHasAgm(); + ActivityAGM.AGM.register(definition, handler); + } + servers() { + this._ensureHasAgm(); + if (isUndefinedOrNull(this._activity)) { + return []; + } + return this._activity.windows.map((w) => { + return w.instance; + }); + } + methods() { + this._ensureHasAgm(); + if (isUndefinedOrNull(this._activity)) { + return []; + } + const windows = this._activity.windows; + const methodNames = []; + const methods = []; + windows.forEach((window) => { + const windowMethods = this.methodsForWindow(window); + windowMethods.forEach((currentWindowMethod) => { + if (methodNames.indexOf(currentWindowMethod.name) === -1) { + methodNames.push(currentWindowMethod.name); + methods.push(currentWindowMethod); + } + }); + }); + return methods; + } + methodsForWindow(window) { + this._ensureHasAgm(); + if (!window.instance) { + return []; + } + return ActivityAGM.AGM.methodsForInstance(window.instance); + } + invoke(methodName, arg, target, options, success, error) { + this._ensureHasAgm(); + const activityServers = this.servers(); + if (isUndefinedOrNull(target)) { + target = "activity.all"; + } + if (isString(target)) { + if (target === "activity.all") ; + else if (target === "activity.best") { + const potentialTargets = activityServers.filter((server) => { + const methods = ActivityAGM.AGM.methodsForInstance(server); + return methods.filter((m) => { + return m.name === methodName; + }).length > 0; + }); + if (potentialTargets.length > 0) { + [potentialTargets[0]]; + } + } + else if (target === "all" || target === "best") { + return promisify$1(ActivityAGM.AGM.invoke(methodName, arg, target, options), success, error); + } + else { + throw new Error("Invalid invoke target " + target); + } + } + else if (isArray(target)) { + if (target.length >= 0) { + const firstElem = target[0]; + if (this._isInstance(firstElem)) { + target.map((instance) => instance); + } + else if (this._isActivityWindow(firstElem)) { + target.map((win) => win.instance); + } + else { + throw new Error("Unknown target object"); + } + } + } + else { + if (this._isInstance(target)) ; + else if (this._isActivityWindow(target)) { + [target.instance]; + } + else { + throw new Error("Unknown target object"); + } + } + throw new Error("Not implemented"); + } + unregister(definition) { + this._ensureHasAgm(); + return ActivityAGM.AGM.unregister(definition); + } + createStream(methodDefinition, subscriptionAddedHandler, subscriptionRemovedHandler) { + this._ensureHasAgm(); + ActivityAGM.AGM.createStream(methodDefinition, { + subscriptionAddedHandler, + subscriptionRemovedHandler, + subscriptionRequestHandler: undefined + }); + } + subscribe(methodDefinition, parameters, target) { + this._ensureHasAgm(); + return ActivityAGM.AGM.subscribe(methodDefinition, parameters); + } + _ensureHasAgm() { + if (isUndefinedOrNull(ActivityAGM.AGM)) { + throw new Error("Agm should be configured to be used in activity"); + } + } + _isInstance(obj) { + return obj.application !== undefined; + } + _isActivityWindow(obj) { + return obj.instance !== undefined; + } + } + + class AttachedActivityDescriptor { + constructor(manager, ownerActivityId, state) { + this._manager = manager; + this._ownerActivityId = ownerActivityId; + this._state = state; + } + get ownerId() { + return this._state.ownerId; + } + get windowIds() { + return this._state.windowIds; + } + get frameColor() { + return this._state.frameColor; + } + get context() { + return this._state.context; + } + get tag() { + return this._state.tag; + } + detach(descriptor) { + descriptor = descriptor || {}; + const merged = {}; + Object.keys(this._state).forEach((prop) => { + merged[prop] = this._state[prop]; + }); + merged.context = descriptor.context || merged.context; + merged.frameColor = descriptor.frameColor || merged.frameColor; + return this._manager.detachActivities(this._ownerActivityId, merged); + } + } + + const nextTick = (cb) => { + setTimeout(cb, 0); + }; + function nodeify(promise, callback) { + if (!isFunction(callback)) { + return promise; + } + promise.then((resp) => { + nextTick(() => { + callback(null, resp); + }); + }, (err) => { + nextTick(() => { + callback(err, null); + }); + }); + } + + class Activity extends ActivityEntity { + constructor(id, actType, status, context, ownerId) { + super(id); + this._id = id; + this._actType = actType; + this._status = status; + this._context = context; + this._ownerId = ownerId; + this._agm = new ActivityAGM(this); + } + get type() { + if (this._manager) { + return this._manager.getActivityType(this._actType); + } + return undefined; + } + get context() { + return this._context; + } + get status() { + return this._status; + } + get owner() { + if (!this._ownerId) { + return null; + } + return this._manager.getWindows({ id: this._ownerId })[0]; + } + get windows() { + return this._manager.getWindows({ activityId: this._id }); + } + get agm() { + return this._agm; + } + addWindow(window, callback) { + return this._manager.addWindowToActivity(this, window, callback); + } + createWindow(windowType, callback) { + return this._manager.createWindow(this, windowType, callback); + } + createStackedWindows(windowTypes, timeout, callback) { + return this._manager.createStackedWindows(this, windowTypes, timeout, callback); + } + leave(window, callback) { + return this._manager.leaveWindowFromActivity(this, window, callback); + } + getWindowsByType(windowType) { + const filter = { activityId: this._id, type: windowType }; + return this._manager.getWindows(filter); + } + setContext(context, callback) { + return this._manager.setActivityContext(this, context, callback); + } + updateContext(context, callback) { + return this._manager.updateActivityContext(this, context, callback); + } + onStatusChange(handler) { + return this._manager.subscribeActivityEvents((a, ns, os) => { + if (a.id === this.id) { + handler(a, ns, os); + } + }); + } + onWindowEvent(handler) { + return this._manager.subscribeWindowEvents((a, w, e) => { + if (a.id === this.id) { + handler(a, w, e); + } + }); + } + onContextChanged(handler) { + this._manager.subscribeActivityContextChanged((act, context, updated, removed) => { + if (act.id === this.id) { + handler(context, updated, removed, act); + } + }); + try { + handler(this.context, this.context, [], this); + } + catch (e) { + return; + } + } + stop() { + this._manager.stopActivity(this); + } + clone(options) { + return this._manager.clone(this, options); + } + attach(activity, tag) { + let activityId; + if (typeof activity === "string") { + activityId = activity; + } + else { + activityId = activity.id; + } + return this._manager.attachActivities(activityId, this.id, tag); + } + onActivityAttached(callback) { + this._manager.subscribeActivitiesAttached((newActId, oldActId, descriptor) => { + if (newActId !== this._id) { + return; + } + callback(descriptor); + }); + } + onDetached(callback) { + this._manager.subscribeActivitiesDetached((newAct, originalActivity, state) => { + if (originalActivity.id !== this._id) { + return; + } + callback(newAct, state); + }); + } + _updateCore(other) { + super._updateCore(other); + ifNotUndefined(other._actType, (x) => this._actType = x); + ifNotUndefined(other._context, (x) => this._context = x); + ifNotUndefined(other._ownerId, (x) => this._ownerId = x); + if (other._status && (!this._status || (this._status.state !== other._status.state))) { + this._status = other._status; + } + } + _updateDescriptors(allStates) { + this._attached = allStates.map((s) => { + return new AttachedActivityDescriptor(this._manager, this._id, s); + }); + } + get attached() { + return this._attached; + } + setFrameColor(color, callback) { + const promise = new Promise((resolve, reject) => { + let callbacksToWait = this.windows.length; + if (callbacksToWait === 0) { + resolve(this); + } + this.windows.forEach((w) => { + w.underlyingWindow.setFrameColor(color, () => { + callbacksToWait--; + if (callbacksToWait <= 0) { + resolve(this); + } + }); + }); + setTimeout(() => { + if (callbacksToWait > 0) { + reject(this.id + " - timed out waiting for setFrameColor with" + color); + } + }, 5000); + }); + return nodeify(promise, callback); + } + getFrameColor() { + if (!this.windows || this.windows.length === 0) { + return ""; + } + return this.windows[0].underlyingWindow.frameColor; + } + } + + class LogLevel { + } + LogLevel.Trace = "trace"; + LogLevel.Debug = "debug"; + LogLevel.Info = "info"; + LogLevel.Warn = "warn"; + LogLevel.Error = "error"; + class Logger { + static GetNamed(name) { + return new Logger(name); + } + static Get(owner) { + return new Logger(Logger.GetTypeName(owner)); + } + constructor(name) { + this._name = name; + if (!isUndefinedOrNull(Logger.GlueLogger)) { + this._glueLogger = Logger.GlueLogger.subLogger(name); + } + } + trace(message) { + if (!isUndefinedOrNull(this._glueLogger)) { + this._glueLogger.trace(message); + } + else { + if (Logger.Level === LogLevel.Trace) { + console.info(this._getMessage(message, LogLevel.Trace)); + } + } + } + debug(message) { + if (!isUndefinedOrNull(this._glueLogger)) { + this._glueLogger.debug(message); + } + else { + if (Logger.Level === LogLevel.Debug || + Logger.Level === LogLevel.Trace) { + console.info(this._getMessage(message, LogLevel.Debug)); + } + } + } + info(message) { + if (!isUndefinedOrNull(this._glueLogger)) { + this._glueLogger.info(message); + } + else { + if (Logger.Level === LogLevel.Debug || + Logger.Level === LogLevel.Trace || + Logger.Level === LogLevel.Info) { + console.info(this._getMessage(message, LogLevel.Info)); + } + } + } + warn(message) { + if (!isUndefinedOrNull(this._glueLogger)) { + this._glueLogger.warn(message); + } + else { + if (Logger.Level === LogLevel.Debug || + Logger.Level === LogLevel.Trace || + Logger.Level === LogLevel.Info || + Logger.Level === LogLevel.Warn) { + console.info(this._getMessage(message, LogLevel.Info)); + } + } + } + error(message) { + if (!isUndefinedOrNull(this._glueLogger)) { + this._glueLogger.error(message); + } + else { + console.error(this._getMessage(message, LogLevel.Error)); + console.trace(); + } + } + _getMessage(message, level) { + return "[" + level + "] " + this._name + " - " + message; + } + static GetTypeName(object) { + const funcNameRegex = /function (.{1,})\(/; + const results = (funcNameRegex).exec(object.constructor.toString()); + return (results && results.length > 1) ? results[1] : ""; + } + } + Logger.Level = LogLevel.Info; + + class ActivityWindow extends ActivityEntity { + constructor(id, name, type, activityId, instance, isIndependent, windowGetter, hcWindowId) { + super(id); + this._logger = Logger.Get("window"); + this._type = type; + this._activityId = activityId; + this._name = name; + this._instance = instance; + this._isIndependent = isIndependent; + this._windowGetter = windowGetter; + this._hcWindowId = hcWindowId; + } + getBounds() { + return this._manager.getWindowBounds(this.id); + } + get name() { + return this._name; + } + get isIndependent() { + return this._isIndependent; + } + get type() { + if (this._manager) { + return this._manager.getWindowType(this._type); + } + return undefined; + } + get activity() { + if (isUndefined(this._activityId)) { + return undefined; + } + return this._manager.getActivityById(this._activityId); + } + get isOwner() { + const act = this.activity; + if (isUndefined(act)) { + return false; + } + return act.owner.id === this.id; + } + setVisible(isVisible, callback) { + return this._manager.setWindowVisibility(this.id, isVisible); + } + activate(focus) { + return this._manager.activateWindow(this.id, focus); + } + setBounds(bounds, callback) { + return this._manager.setWindowBounds(this.id, bounds, callback); + } + close() { + return this._manager.closeWindow(this.id); + } + get instance() { + return this._instance; + } + get underlyingWindow() { + const window = this._windowGetter(); + if (!window) { + return { + id: this._hcWindowId + }; + } + return window; + } + onActivityJoined(callback) { + this._subscribeForActivityWindowEvent(EntityEventType.ActivityWindowJoinedActivity, callback); + } + onActivityRemoved(callback) { + this._subscribeForActivityWindowEvent(EntityEventType.ActivityWindowLeftActivity, callback); + } + _updateCore(other) { + ifNotUndefined(other._activityId, (x) => this._activityId = x); + ifNotUndefined(other._isIndependent, (x) => this._isIndependent = x); + ifNotUndefined(other._hcWindowId, (x) => this._hcWindowId = x); + ifNotUndefined(other._type, (x) => this._type = x); + ifNotUndefined(other._name, (x) => this._name = x); + if (!isUndefinedOrNull(other._instance)) { + this._instance = other._instance; + } + } + _subscribeForActivityWindowEvent(eventName, callback) { + this._manager.subscribeWindowEvents((activity, window, event) => { + if (window.id !== this.id) { + return; + } + if (event === eventName) { + callback(activity); + } + }); + } + _beforeDelete(other) { + this._hcWindowId = other._hcWindowId; + } + } + + class ActivityStatus { + constructor(state, message, time) { + this.state = state; + this.message = message; + this.time = time; + } + getState() { + return this.state; + } + getMessage() { + return this.message; + } + getTime() { + return this.time; + } + } + + const gwMmessageError = "error"; + const gwMessageAddActivityTypes = "add-types"; + const gwMmessageActivityTypesAdded = "types-added"; + const gwMessageRemoveActivityTypes = "remove-types"; + const gwMessageActivityTypesRemoved = "types-removed"; + const gwMessageActivityCreated = "created"; + const gwMessageActivityDestroyed = "destroyed"; + const gwMessageActivityInitiated = "initiated"; + const gwMmessageJoinActivity = "join-activity"; + const gwMessageJoinedActivity = "joined"; + const gwMessageActivityJoined = "activity-joined"; + const gwMessageLeaveActivity = "leave-activity"; + const gwMessageActivityLeft = "left"; + const gwNmessageMergeActivities = "merge"; + const gwMessageSplitActivities = "split"; + const gwMessageOwnerChanged = "owner-changed"; + const gwMessageAddPeerFactories = "add-peer-factories"; + const gwMessagePeerFactoriesAdded = "peer-factories-added"; + const gwMessageRemovePeerFactories = "remove-peer-factories"; + const gwMessagePeerFactoriesRemoved = "peer-factories-removed"; + const gwMessageCreateActivity = "create"; + const gwMessageCreatePeer = "create-peer"; + const gwMessagePeerRequested = "peer-requested"; + const gwMessageReady = "ready"; + const gwMessagePeerCreated = "peer-created"; + const gwMessageDestroyActivity = "destroy"; + const gwMessageDisposePeer = "dispose-peer"; + const gwMessageDestroyPeer = "destroy-peer"; + class GW3Bridge { + static activityTypeGwMessageEntityToActivityType(entity, description) { + const nameToWindowType = (windowName) => new WindowType(windowName, undefined); + return new ActivityType(entity.name, entity.owner_type && nameToWindowType(entity.owner_type), entity.helper_types && entity.helper_types.map(nameToWindowType), description); + } + static peerFactoryGwMessageEntityToWindowType(entity) { + return new WindowType(entity.peer_type, (_) => undefined); + } + static activityGwMessageToActivity(msg, status) { + const ownerId = msg.owner !== undefined ? msg.owner.peer_id : msg.owner_id; + return new Activity(msg.activity_id, msg.activity_type, status, msg.context_snapshot, ownerId); + } + static activityToActivityStatusChangeEvent(act) { + return new EntityEvent(act, new ActivityStatusChangeEventContext(act.status, undefined)); + } + constructor(config) { + this._activityChangeCallbacks = []; + this._activityTypeStatusChangeCallbacks = []; + this._activityWindowChangeCallbacks = []; + this._windowTypeStatusChangeCallbacks = []; + this._peerIdAndFactoryIdToPeerType = {}; + this._peerFactoriesRegisteredByUs = {}; + this._gw3Subscriptions = []; + this._contextSubscriptions = {}; + this._activityTypesInitiatedFromMe = {}; + this._config = config; + this._connection = config.connection; + this._logger = config.logger; + this._contexts = config.contexts; + this._windows = config.windows; + this._sessionJoinedPromise = new Promise((resolve) => { + this._sessionJoinedPromiseResolve = resolve; + }); + this._activityJoinedPromise = new Promise((resolve) => { + this._activityJoinedPromiseResolve = resolve; + }); + if (!this._config.activityId) { + this._activityJoinedPromiseResolve({}); + } + this._gw3Session = this._connection.domain("activity", ["joined", "initiated", "peer-created", "token"]); + if (typeof window !== "undefined") { + const glue42gd = (window).glue42gd; + if (glue42gd && glue42gd.activityInfo) { + if (typeof glue42gd.addRefreshHandler === "function") { + glue42gd.addRefreshHandler((success, error) => { + this._gw3Session + .send({ + type: "reload" + }) + .then((msg) => { + if (!msg.token) { + error("Expected gateway token for refreshing."); + return; + } + try { + glue42gd.setGWToken(msg.token); + } + catch (e) { + error(e.message || e); + return; + } + success(); + }, error); + }); + } + if (glue42gd && typeof glue42gd.addWillNavigateHandler === "function") { + glue42gd.addWillNavigateHandler((success, error) => { + this._gw3Session + .send({ + type: "reload" + }) + .then((msg) => { + if (!msg.token) { + error("Expected gateway token for refreshing."); + return; + } + try { + glue42gd.setGWToken(msg.token); + } + catch (e) { + error(e.message || e); + return; + } + success(); + }, error); + }); + } + } + } + } + get bridgeType() { + return "GW3"; + } + init() { + this.forwardActivityTypeMessagesToStatusEventHandlers(); + this.subscribe(gwMessageActivityCreated, this.handleActivityCreatedMessage); + this.subscribe(gwMessageActivityDestroyed, this.handleActivityDestroyedMessage); + this.forwardActivityMessagesToStatusEventHandlers(); + this.forwardActivityCreatedAndJoinedActivityToActivityWindowEventHandlers(); + this.forwardPeerFactoryMessagesToStatusEventHandlers(); + this.forwardPeerFactoryMessagesToPeerFactoryRequests(); + this.subscribe(gwMessagePeerFactoriesAdded, this.handlePeerFactoriesAdded); + this.subscribe(gwMessagePeerFactoriesRemoved, this.handlePeerFactoriesRemoved); + this.forwardActivityWindowMessagesToEventHandlers(); + this.subscribe(gwMessageDisposePeer, () => { + if (this._config.disposeRequestHandling === "dispose") { + this.dispose(); + return; + } + if (this._config.disposeRequestHandling === "exit") { + if (this._windows && typeof this._windows.my() !== "undefined") { + this._windows.my().close(); + return; + } + if (typeof window !== "undefined" && typeof (window).close === "function") { + window.close(); + return; + } + if (typeof process !== "undefined" && typeof (process).exit === "function") { + process.exit(); + return; + } + } + }); + this._gw3Session.onJoined(() => { + if (this._config.mode === "trackMyOnly" || + this._config.mode === "trackMyTypeAndInitiatedFromMe") { + this._sessionJoinedPromiseResolve(this); + } + else { + this._gw3Session + .send({ + type: "subscribe", + activity_types: (this._config.mode === "trackAll" ? [] : + this._config.mode === "trackTypes" ? this._config.typesToTrack : []) + }) + .then(() => { + this._sessionJoinedPromiseResolve(this); + }); + } + }); + this._gw3Session.join(); + } + dispose() { + this._gw3Subscriptions.forEach((sub) => sub && this._connection.off(sub)); + this._gw3Subscriptions.length = 0; + } + ready() { + return Promise.all([this._sessionJoinedPromise, this._activityJoinedPromise]); + } + initReady() { + return this._sessionJoinedPromise; + } + onActivityTypeStatusChange(callback) { + this._activityTypeStatusChangeCallbacks.push(callback); + } + registerActivityType(activityTypeName, ownerWindow, helperWindows, config, description) { + const entity = {}; + entity.name = activityTypeName; + const toActivityPeerConfig = (windowDefinition) => ({ type: windowDefinition.type, name: windowDefinition.name, configuration: windowDefinition }); + entity.owner_type = toActivityPeerConfig(ownerWindow); + entity.helper_types = helperWindows.map(toActivityPeerConfig); + return this._gw3Session + .send({ + type: gwMessageAddActivityTypes, + types: [entity] + }) + .then(() => { + const activityType = GW3Bridge.activityTypeGwMessageEntityToActivityType(entity, description); + this.invokeCallbacks(this._activityTypeStatusChangeCallbacks, new EntityEvent(activityType, new EntityEventContext(EntityEventType.Added)), gwMessageAddActivityTypes); + return activityType; + }); + } + unregisterActivityType(activityTypeName) { + return this._gw3Session + .send({ + type: gwMessageRemoveActivityTypes, + types: [activityTypeName] + }) + .then(() => { + const activityType = new ActivityType(activityTypeName, undefined, undefined, undefined); + this.invokeCallbacks(this._activityTypeStatusChangeCallbacks, new EntityEvent(activityType, new EntityEventContext(EntityEventType.Removed)), gwMessageAddActivityTypes); + }); + } + onWindowTypeStatusChange(callback) { + this._windowTypeStatusChangeCallbacks.push(callback); + } + registerWindowFactory(windowType, factory, parameters) { + if (this._peerFactoriesRegisteredByUs[windowType]) { + return Promise.reject(new Error(`Factory for windowType ${windowType} already registered.`)); + } + this._peerFactoriesRegisteredByUs[windowType] = factory; + const entity = { + id: windowType, + peer_type: windowType, + configuration: parameters + }; + return this._gw3Session.send({ + type: gwMessageAddPeerFactories, + factories: [entity] + }) + .then(() => { + this.invokeCallbacks(this._windowTypeStatusChangeCallbacks, new EntityEvent(GW3Bridge.peerFactoryGwMessageEntityToWindowType(entity), new EntityEventContext(EntityEventType.Added)), gwMessageAddPeerFactories); + }) + .catch(() => { + delete this._peerFactoriesRegisteredByUs[windowType]; + }); + } + unregisterWindowFactory(windowType) { + const factory = this._peerFactoriesRegisteredByUs[windowType]; + if (!factory) { + return Promise.reject(new Error(`Factory for windowType ${windowType} not registered.`)); + } + delete this._peerFactoriesRegisteredByUs[windowType]; + return this._gw3Session.send({ + type: gwMessageRemovePeerFactories, + factory_ids: [windowType] + }).then(() => { + this.invokeCallbacks(this._windowTypeStatusChangeCallbacks, new EntityEvent(new WindowType(windowType, undefined), new EntityEventContext(EntityEventType.Removed)), gwMessageAddPeerFactories); + }); + } + onActivityStatusChange(callback) { + this._activityChangeCallbacks.push(callback); + } + initiateActivity(activityType, context, configuration) { + const initiateMsg = { + type: gwMessageCreateActivity, + activity_type: activityType, + initial_context: context, + }; + if (this.isOverrideTypeDefinition(configuration)) { + initiateMsg.types_override = { + owner_type: { type: configuration.owner.type, name: configuration.owner.name, configuration: configuration.owner }, + helper_types: configuration.helpers && configuration.helpers.map((wd) => ({ type: wd.type, name: wd.name, configuration: wd })) + }; + } + else { + initiateMsg.configuration = configuration && configuration.map((wd) => ({ type: wd.type, name: wd.name, configuration: wd })); + } + return this.sendCreateAndMapResultingMessagesToPromise(initiateMsg, gwMessageActivityInitiated, (msg, requestId) => msg.request_id === requestId, gwMessageActivityCreated, (msg, requestId, initMsg) => msg.activity_id === initMsg.activity_id, gwMessageActivityDestroyed, (msg, requestId, initMsg) => msg.activity_id === initMsg.activity_id, (msg) => msg.activity_id, null).then((id) => { + if (this._config.mode === "trackMyTypeAndInitiatedFromMe") { + if (!this._activityTypesInitiatedFromMe[activityType]) { + this._activityTypesInitiatedFromMe[activityType] = true; + return this._gw3Session + .send({ + type: "subscribe", + activity_types: [activityType] + }) + .then(() => { + return id; + }); + } + } + return id; + }); + } + stopActivity(activity) { + return this._gw3Session.send({ + type: gwMessageDestroyActivity, + activity_id: activity.id, + reason_uri: "com.tick42.glue.activity.constants.destroyReason.general", + reason: "Destroying activity" + }).then((_) => true); + } + updateActivityContext(activity, context, fullReplace, removedKeys) { + if (fullReplace) { + return this._contexts.set(activity.id, context); + } + else { + removedKeys = removedKeys || []; + for (const x of removedKeys) { + context[x] = null; + } + return this._contexts.update(activity.id, context); + } + } + announceWindow(windowType, activityWindowId) { + throw new Error("Invalid operation 'announceWindow' for GW3 protocol"); + } + registerWindow(type, name, independent) { + let shouldSendReady = typeof this._connection.gatewayToken !== "undefined"; + const peerId = this._connection.peerId; + if (typeof window !== "undefined") { + const glue42gd = window.glue42gd; + if (glue42gd) { + shouldSendReady = typeof glue42gd.activityInfo !== "undefined"; + } + } + if (shouldSendReady) { + this._gw3Session.send({ + type: gwMessageReady, + }); + } + this.invokeCallbacks(this._activityWindowChangeCallbacks, new EntityEvent(new ActivityWindow(peerId, name, type, undefined, this.getAgmInstance(peerId), independent, this.generateWindowGetter(peerId), undefined), new EntityEventContext(EntityEventType.Added)), "register window"); + return Promise.resolve(peerId); + } + onActivityWindowChange(callback) { + this._activityWindowChangeCallbacks.push(callback); + } + createWindow(activityId, windowDefinition) { + if (!windowDefinition.layout) { + if (windowDefinition.left || windowDefinition.width || windowDefinition.height || windowDefinition.top) { + windowDefinition.layout = { + mode: "pixels", + cellSize: 1, + }; + } + } + const joinPeer = (id) => { + if (!activityId) { + return; + } + return this.joinActivity(activityId, id, windowDefinition.name) + .then(() => { + return id; + }); + }; + return this.sendCreateAndMapResultingMessagesToPromise({ + type: gwMessageCreatePeer, + peer_type: windowDefinition.type, + peer_name: windowDefinition.name || windowDefinition.type, + configuration: windowDefinition, + activity_id: activityId, + }, undefined, undefined, gwMessagePeerCreated, (msg, requestId) => msg.request_id === requestId, undefined, undefined, (msg) => msg.created_id, joinPeer) + .then(joinPeer); + } + async closeWindow(id) { + await this._gw3Session.send({ + type: gwMessageDestroyPeer, + destroy_peer_id: id + }); + } + getAnnouncementInfo() { + let activityId = this._config.activityId || (this._config.announcementInfo && this._config.announcementInfo.activityId); + let activityWindowType = (this._config.announcementInfo && this._config.announcementInfo.activityWindowType); + let activityWindowIndependent = (this._config.announcementInfo && this._config.announcementInfo.activityWindowIndependent); + let activityWindowName = (this._config.announcementInfo && this._config.announcementInfo.activityWindowName); + if (typeof window !== "undefined" && + typeof window.location !== "undefined" && + window.location.search && + typeof URLSearchParams === "function") { + const searchParams = new URLSearchParams(location.search.slice(1)); + activityWindowType = activityWindowType || searchParams.get("t42PeerType"); + activityWindowType = activityWindowType || searchParams.get("t42ActivityWindowType"); + if (typeof activityWindowIndependent === "undefined") { + activityWindowIndependent = searchParams.get("t42ActivityWindowIndependent"); + } + activityWindowName = activityWindowName || searchParams.get("t42ActivityWindowName"); + activityId = activityId || searchParams.get("t42ActivityId"); + } + activityWindowType = activityWindowType || "unknown"; + activityWindowIndependent = activityWindowIndependent || false; + activityWindowName = activityWindowName || this._connection.peerId; + return { + activityWindowId: undefined, + activityId, + activityWindowType, + activityWindowIndependent, + activityWindowName, + }; + } + joinActivity(activityId, windowId, name) { + const maybeName = (name && { name }) || {}; + return this._gw3Session.send({ + type: gwMmessageJoinActivity, + target_id: windowId, + activity_id: activityId, + ...maybeName + }).then(() => { + this.invokeCallbacks(this._activityWindowChangeCallbacks, new EntityEvent(new ActivityWindow(windowId, undefined, undefined, activityId, this.getAgmInstance(windowId), undefined, this.generateWindowGetter(windowId), undefined), new EntityEventContext(EntityEventType.ActivityWindowJoinedActivity)), "activity joined - ActivityWindow"); + this.invokeCallbacks(this._activityChangeCallbacks, new EntityEvent(new Activity(activityId, undefined, new ActivityStatus("created", undefined, undefined), undefined, undefined), new EntityEventContext(EntityEventType.Updated)), "activity joined - Activity"); + }); + } + leaveActivity(activityId, windowId) { + return this._gw3Session.send({ + type: gwMessageLeaveActivity, + target_id: windowId, + activity_id: activityId + }).then(() => { + this.invokeCallbacks(this._activityWindowChangeCallbacks, new EntityEvent(new ActivityWindow(windowId, undefined, undefined, null, this.getAgmInstance(windowId), undefined, this.generateWindowGetter(windowId), undefined), new EntityEventContext(EntityEventType.ActivityWindowLeftActivity)), "activity left - ActivityWindow"); + this.invokeCallbacks(this._activityChangeCallbacks, new EntityEvent(new Activity(activityId, undefined, new ActivityStatus("created", undefined, undefined), undefined, undefined), new EntityEventContext(EntityEventType.Updated)), "activity left - Activity"); + }); + } + getActivityTypes() { + return Promise.resolve([]); + } + getWindowTypes() { + return Promise.resolve([]); + } + getActivities() { + return Promise.resolve([]); + } + getActivityWindows() { + return Promise.resolve([]); + } + createStackedWindows(id, windowDefinitions, timeout) { + return undefined; + } + getWindowBounds(id) { + return undefined; + } + setWindowBounds(id, bounds) { + return undefined; + } + activateWindow(id, focus) { + return undefined; + } + setWindowVisibility(id, visible) { + return undefined; + } + cloneActivity(id, cloneOptions) { + return undefined; + } + attachActivities(from, to, tag) { + return this._gw3Session.send({ + type: gwNmessageMergeActivities, + into: to, + merge: from + }); + } + detachActivities(activityId, newActivityInfo) { + return this._gw3Session.send({ + type: gwMessageSplitActivities, + from: activityId, + }).then(() => ""); + } + onActivitiesAttached(callback) { + } + onActivitiesDetached(callback) { + } + onActivityAttachedDescriptorsRefreshed(callback) { + } + getAttachedDescriptors() { + return Promise.resolve([]); + } + getRandomRequestId() { + return this._connection.peerId + ":" + Math.floor(Math.random() * 1e9) + ""; + } + forwardAddedAndRemovedMessagesToEventHandler(addedMessageType, removedMessageType, mapper, handlers) { + const getGetEntityEvent = (isAdded) => (entity) => new EntityEvent(entity, new EntityEventContext(isAdded ? + EntityEventType.Added : + EntityEventType.Removed)); + const sub1 = addedMessageType && this.forwardMessageToEventHandler(addedMessageType, (msg) => mapper(msg, true), getGetEntityEvent(true), handlers); + const sub2 = removedMessageType && this.forwardMessageToEventHandler(removedMessageType, (msg) => mapper(msg, false), getGetEntityEvent(false), handlers); + return [sub1, sub2].filter((x) => x); + } + forwardMessageToEventHandler(messageType, mapper, getEntityEvent, handler) { + return this.subscribe(messageType, (msg) => { + mapper(msg) + .forEach((ent) => handler.forEach((h) => h(getEntityEvent(ent, msg)))); + }); + } + sendCreateAndMapResultingMessagesToPromise(msg, initiatedMessageType, initiatedMessageFilter, createdMessageType, createdMessageFilter, cancelledMessageType, cancelledMessageFilter, createdMessageToPromiseResolution, listenForRecreates) { + const reqId = this.getRandomRequestId(); + let resolveCreatedPromise; + let rejectCreatedPromise; + const createdPromise = new Promise((resolve, reject) => { + resolveCreatedPromise = resolve; + rejectCreatedPromise = reject; + }); + let initiatedMessageAck = null; + let initiatedSubscription; + let createdSubscription; + let cancelledSubscription; + let errorSubscription; + const dropSubscriptions = () => { + this.dropSubscription(initiatedSubscription); + if (!listenForRecreates) { + this.dropSubscription(createdSubscription); + } + this.dropSubscription(cancelledSubscription); + this.dropSubscription(errorSubscription); + }; + initiatedSubscription = initiatedMessageType && + this.subscribe(initiatedMessageType, (msg4) => { + if (!initiatedMessageFilter(msg4, reqId)) { + return; + } + initiatedMessageAck = msg4; + this.dropSubscription(initiatedSubscription); + }); + let recreated = false; + createdSubscription = + this.subscribe(createdMessageType, (msg1) => { + if (!createdMessageFilter(msg1, reqId, initiatedMessageAck)) { + return; + } + if (recreated) { + if (listenForRecreates) { + listenForRecreates(createdMessageToPromiseResolution(msg1)); + } + } + else { + recreated = true; + resolveCreatedPromise(createdMessageToPromiseResolution(msg1)); + } + }); + cancelledSubscription = cancelledMessageType && + this.subscribe(cancelledMessageType, (msg2) => { + if (!cancelledMessageFilter(msg2, reqId, initiatedMessageAck)) { + return; + } + rejectCreatedPromise(msg2); + }); + errorSubscription = cancelledMessageType && + this.subscribe(gwMmessageError, (msg3) => { + if (msg3.request_id !== reqId) { + return; + } + rejectCreatedPromise(msg3); + }); + msg.request_id = reqId; + const toReturn = this._gw3Session + .send(msg) + .then(() => { + return createdPromise; + }); + toReturn.then(dropSubscriptions, dropSubscriptions); + return toReturn; + } + peerFactoryIdAndOwnerIdToWindowType(factoryId, ownerId) { + const peerType = this._peerIdAndFactoryIdToPeerType[ownerId + ":" + factoryId]; + if (!peerType) { + return null; + } + else { + return new WindowType(peerType, undefined); + } + } + subscribe(messageType, handler) { + const sub = this._connection.on(messageType, (msg) => handler.bind(this)(msg)); + this._gw3Subscriptions.push(sub); + return sub; + } + dropSubscription(subscription) { + if (subscription) { + this._connection.off(subscription); + delete this._gw3Subscriptions[this._gw3Subscriptions.indexOf(subscription)]; + } + } + invokeCallbacks(callbacks, event, description) { + callbacks.forEach((cb) => { + try { + cb(event); + } + catch (err) { + this._logger.error(`Error in ${description || event.context.type} callback: ` + JSON.stringify(err)); + } + }); + } + handleActivityCreatedMessage(msg) { + if (!msg.context_id) { + this._logger.error("Activity created with unknown context_id: " + msg.activity_id); + } + else { + if (!this._contextSubscriptions[msg.activity_id]) { + this.subscribeToContext(msg); + } + } + } + async subscribeToContext(msg) { + const activityId = msg.activity_id; + this._contextSubscriptions[activityId] = + await this._contexts.subscribe(activityId, (data, updated, removed) => { + const event = new EntityEvent(new Activity(activityId, undefined, undefined, data, undefined), new ActivityContextChangedEventContext(data, updated, removed)); + this.invokeCallbacks(this._activityChangeCallbacks, event, "context updated"); + }); + } + handleActivityDestroyedMessage(msg) { + const unsubscribeContext = this._contextSubscriptions[msg.activity_id]; + if (typeof unsubscribeContext === "function") { + unsubscribeContext(); + } + delete this._contextSubscriptions[msg.activity_id]; + } + handlePeerFactoriesAdded(msg) { + msg.factories.forEach((entity) => { + this._peerIdAndFactoryIdToPeerType[msg.owner_id + ":" + entity.id] = entity.peer_type; + }); + } + handlePeerFactoriesRemoved(msg) { + msg.factory_ids.forEach((factoryId) => { + delete this._peerIdAndFactoryIdToPeerType[msg.owner_id + ":" + factoryId]; + }); + } + forwardActivityTypeMessagesToStatusEventHandlers() { + this.forwardAddedAndRemovedMessagesToEventHandler(gwMmessageActivityTypesAdded, gwMessageActivityTypesRemoved, (msg, isAdded) => isAdded + ? msg.types.map((t) => GW3Bridge.activityTypeGwMessageEntityToActivityType(t, undefined)) + : msg.types.map((t) => new ActivityType(t.name, undefined, undefined, undefined)), this._activityTypeStatusChangeCallbacks); + } + forwardActivityCreatedAndJoinedActivityToActivityWindowEventHandlers() { + for (const activityCreatedMessage of [gwMessageActivityCreated, gwMessageJoinedActivity, gwMessageOwnerChanged]) { + this.forwardMessageToEventHandler(activityCreatedMessage, (msg) => ([msg.owner || { ...msg, type: msg.peer_type, name: msg.peer_name, peer_id: msg.owner_id }]) + .concat(msg.participants || []) + .map((info) => new ActivityWindow(info.peer_id, info.name, info.type, msg.activity_id, this.getAgmInstance(info.peer_id), undefined, this.generateWindowGetter(info.peer_id), undefined)), (ent, msg) => new EntityEvent(ent, new EntityEventContext(EntityEventType.ActivityWindowJoinedActivity)), this._activityWindowChangeCallbacks); + } + } + forwardActivityMessagesToStatusEventHandlers() { + for (const createdMessage of [gwMessageActivityCreated, gwMessageJoinedActivity]) { + this.forwardMessageToEventHandler(createdMessage, (msg) => [GW3Bridge.activityGwMessageToActivity(msg, new ActivityStatus("started", "", new Date()))], (ent, msg) => GW3Bridge.activityToActivityStatusChangeEvent(ent), this._activityChangeCallbacks); + } + this.forwardMessageToEventHandler(gwMessageActivityDestroyed, (msg) => [GW3Bridge.activityGwMessageToActivity(msg, new ActivityStatus("destroyed", msg.reason, new Date()))], (ent, msg) => GW3Bridge.activityToActivityStatusChangeEvent(ent), this._activityChangeCallbacks); + this.forwardMessageToEventHandler(gwMessageActivityInitiated, (msg) => [GW3Bridge.activityGwMessageToActivity(msg, new ActivityStatus("created", "", new Date()))], (ent, msg) => GW3Bridge.activityToActivityStatusChangeEvent(ent), this._activityChangeCallbacks); + this.forwardMessageToEventHandler(gwMessageOwnerChanged, (msg) => [GW3Bridge.activityGwMessageToActivity(msg, new ActivityStatus("created", "", new Date()))], (ent, msg) => GW3Bridge.activityToActivityStatusChangeEvent(ent), this._activityChangeCallbacks); + } + forwardPeerFactoryMessagesToStatusEventHandlers() { + this.forwardAddedAndRemovedMessagesToEventHandler(gwMessagePeerFactoriesAdded, gwMessagePeerFactoriesRemoved, (msg, isAdded) => isAdded + ? msg.factories.map(GW3Bridge.peerFactoryGwMessageEntityToWindowType) + : msg.factory_ids.map((id) => this.peerFactoryIdAndOwnerIdToWindowType(id, msg.owner_id)).filter((x) => x != null), this._windowTypeStatusChangeCallbacks); + } + forwardPeerFactoryMessagesToPeerFactoryRequests() { + this.subscribe(gwMessagePeerRequested, (msg) => { + const factory = this._peerFactoriesRegisteredByUs[msg.peer_factory]; + if (!factory) { + this._gw3Session.send({ + type: gwMmessageError, + request_id: msg.request_id, + reason: `Unknown peer factory ${msg.peer_factory}` + }); + return; + } + try { + const configuration = msg.configuration || {}; + configuration.gateway_token = configuration.gateway_token || msg.gateway_token; + configuration.peer_factory = configuration.peer_factory || msg.peer_factory; + const promise = factory({ + activityId: msg.activity && msg.activity.id, + activityType: msg.activity && msg.activity.type, + type: msg.configuration && msg.configuration.type, + gwToken: configuration.gateway_token, + configuration + }); + if (promise && promise.then && promise.catch) { + promise.catch((err) => this._gw3Session.send({ + type: gwMmessageError, + request_id: msg.request_id, + reason: err && (err.message || JSON.stringify(err)) + })); + } + } + catch (err) { + this._gw3Session.send({ + type: gwMmessageError, + request_id: msg.request_id, + reason: err && (err.message || JSON.stringify(err)) + }); + } + }); + } + forwardActivityWindowMessagesToEventHandlers() { + for (const joinedMessage of [gwMessageActivityJoined, gwMessageJoinedActivity]) { + this.subscribe(joinedMessage, (msg) => { + const joinedId = (joinedMessage === gwMessageActivityJoined) ? msg.joined_id : msg.peer_id; + const joinedType = (joinedMessage === gwMessageActivityJoined) ? msg.joined_type : msg.peer_type; + const joinedName = (joinedMessage === gwMessageActivityJoined) ? msg.joined_name : msg.peer_name; + const entity = new ActivityWindow(joinedId, joinedName, joinedType, msg.activity_id, this.getAgmInstance(joinedId), undefined, this.generateWindowGetter(joinedId), undefined); + if (!this._contextSubscriptions[msg.activity_id]) { + this.subscribeToContext(msg).then(() => { + if (joinedMessage === gwMessageJoinedActivity) { + this._activityJoinedPromiseResolve({}); + } + }); + } + else if (joinedMessage === gwMessageJoinedActivity) { + this._activityJoinedPromiseResolve({}); + } + this.invokeCallbacks(this._activityWindowChangeCallbacks, new EntityEvent(entity, new EntityEventContext(EntityEventType.ActivityWindowJoinedActivity)), joinedMessage); + }); + } + this.subscribe(gwMessageActivityLeft, (msg) => { + const entity = new ActivityWindow(msg.left_id, undefined, undefined, null, this.getAgmInstance(msg.left_id), undefined, this.generateWindowGetter(msg.left_id), undefined); + this.invokeCallbacks(this._activityWindowChangeCallbacks, new EntityEvent(entity, new EntityEventContext(EntityEventType.ActivityWindowLeftActivity)), gwMessageActivityLeft); + }); + this.forwardAddedAndRemovedMessagesToEventHandler(gwMessagePeerCreated, undefined, (msg) => [ + new ActivityWindow(msg.created_id, undefined, undefined, undefined, undefined, undefined, this.generateWindowGetter(msg.created_id), undefined) + ], this._activityWindowChangeCallbacks); + } + getAgmInstance(id) { + return this._config.agm.servers().find((s) => s.peerId === id || s.windowId === id); + } + generateWindowGetter(peerId) { + return () => { + const server = this.getAgmInstance(peerId); + if (!server) { + return; + } + const windowId = server.windowId; + return this._config.windows.list().filter((w) => w.id === windowId)[0]; + }; + } + isOverrideTypeDefinition(value) { + if (typeof value === "undefined") { + return false; + } + if (value.owner) { + return true; + } + return false; + } + } + + class ActivityMy { + constructor(manager, windows) { + this._myAttached = []; + this._myDetached = []; + this._myAttachedTo = []; + this._myDetachedFrom = []; + this._myActivityFrameColorChanged = []; + this._myActivityJoinedCallbacks = []; + this._myActivityRemovedCallbacks = []; + this._myContextUpdateCallbacks = []; + this._logger = Logger.Get(this); + this._m = manager; + manager.ready() + .then((am) => { + am.subscribeActivityContextChanged(this._subscribeMyContextChanged.bind(this)); + am.subscribeWindowEvents(this._subscribeMyWindowEvent.bind(this)); + am.subscribeActivitiesAttached(this._subscribeActivitiesAttached.bind(this)); + am.subscribeActivitiesDetached(this._subscribeActivitiesDetached.bind(this)); + if (windows) { + windows.onWindowFrameColorChanged(this._subscribeWindowFrameColorChanged.bind(this)); + } + }); + } + get window() { + if (isUndefinedOrNull(this._w)) { + const announcedWindows = this._m.announcedWindows; + if (announcedWindows.length > 0) { + this._w = announcedWindows[0]; + } + } + return this._w; + } + get activity() { + const myWin = this.window; + if (isUndefinedOrNull(myWin)) { + return undefined; + } + return myWin.activity; + } + createWindow(windowType) { + return this._m.createWindow(this.activity, windowType); + } + createStackedWindows(windowTypes, timeout) { + return this._m.createStackedWindows(this.activity, windowTypes, timeout); + } + get context() { + const activity = this.activity; + if (isUndefined(activity)) { + return {}; + } + return activity.context; + } + updateContext(context, callback) { + const activity = this.activity; + if (isUndefined(activity)) { + return new Promise((resolve, reject) => { + reject("Not in activity"); + }); + } + return activity.updateContext(context, callback); + } + setContext(context, callback) { + const activity = this.activity; + if (isUndefined(activity)) { + return new Promise((resolve, reject) => { + reject("Not in activity"); + }); + } + return activity.setContext(context, callback); + } + onActivityJoined(callback) { + this._myActivityJoinedCallbacks.push(callback); + const myWin = this.window; + if (!isUndefinedOrNull(myWin) && !isUndefinedOrNull(myWin.activity)) { + callback(myWin.activity); + } + } + onActivityLeft(callback) { + this._myActivityRemovedCallbacks.push(callback); + } + onContextChanged(callback) { + this._myContextUpdateCallbacks.push(callback); + const myWin = this.window; + if (isUndefinedOrNull(myWin)) { + return; + } + const activity = myWin.activity; + if (isUndefinedOrNull(activity)) { + return; + } + callback(activity.context, activity.context, [], activity); + } + clone(options, callback) { + const act = this.activity; + return this._m.clone(act, options, callback); + } + attach(activity, tag) { + let activityId; + if (typeof activity === "string") { + activityId = activity; + } + else { + activityId = activity.id; + } + return this._m.attachActivities(activityId, this.activity.id, tag); + } + onActivityAttached(callback) { + this._myAttached.push(callback); + } + onActivityDetached(callback) { + this._myDetached.push(callback); + } + onAttachedToActivity(callback) { + this._myAttachedTo.push(callback); + } + onDetachedFromActivity(callback) { + this._myDetachedFrom.push(callback); + } + get attached() { + if (!this.activity) { + return []; + } + return this.activity.attached; + } + setFrameColor(color, callback) { + if (this.activity) { + return this.activity.setFrameColor(color, callback); + } + else { + return Promise.resolve(null); + } + } + getFrameColor() { + if (this.activity) { + return this.activity.getFrameColor(); + } + return ""; + } + onFrameColorChanged(callback) { + this._myActivityFrameColorChanged.push(callback); + } + _subscribeMyContextChanged(activity, context, delta, removed) { + const myWin = this.window; + if (isUndefinedOrNull(myWin)) { + return; + } + const myActivity = myWin.activity; + if (isUndefinedOrNull(myActivity)) { + return; + } + if (activity.id !== myActivity.id) { + return; + } + this._notifyMyContextChanged(activity, context, delta, removed); + } + _subscribeMyWindowEvent(activity, window, event) { + if (isUndefinedOrNull(this.window)) { + return; + } + if (this.window.id !== window.id) { + return; + } + if (event === EntityEventType.ActivityWindowJoinedActivity) { + this._notifyMyWindowEvent(activity, this._myActivityJoinedCallbacks); + this._notifyMyContextChanged(activity, activity.context, null, null); + } + else if (event === EntityEventType.ActivityWindowLeftActivity) { + this._notifyMyWindowEvent(activity, this._myActivityRemovedCallbacks); + } + } + _notifyMyWindowEvent(activity, callbackStore) { + callbackStore.forEach((element) => { + try { + element(activity, event); + } + catch (e) { + this._logger.warn("error in user callback " + e); + } + }); + } + _notifyMyContextChanged(activity, context, delta, removed) { + delta = delta || {}; + removed = removed || []; + this._myContextUpdateCallbacks.forEach((element) => { + try { + element(context, delta, removed, activity); + } + catch (e) { + this._logger.warn("error in user callback " + e); + } + }); + } + _notifyAttached(state) { + this._myAttached.forEach((cb) => { + try { + cb(state); + } + catch (e) { + this._logger.warn("error in user callback " + e); + } + }); + } + _notifyDetached(state) { + this._myDetached.forEach((cb) => { + try { + cb(state); + } + catch (e) { + this._logger.warn("error in user callback " + e); + } + }); + } + _notifyAttachedTo(state) { + this._myAttachedTo.forEach((cb) => { + try { + cb(this.activity, state); + } + catch (e) { + this._logger.warn("error in user callback " + e); + } + }); + } + _notifyDetachedFrom(detached, existing, state) { + this._myDetachedFrom.forEach((cb) => { + try { + cb(detached, existing, state); + } + catch (e) { + this._logger.warn("error in user callback " + e); + } + }); + } + _subscribeActivitiesAttached(newAct, state) { + const myWin = this.window; + if (isUndefinedOrNull(myWin)) { + return; + } + const myActivity = myWin.activity; + if (isUndefinedOrNull(myActivity)) { + return; + } + if (newAct.id !== myActivity.id) { + return; + } + if (state.windowIds.indexOf(myWin.id) >= 0) { + this._notifyAttachedTo(state); + return; + } + this._notifyAttached(state); + } + _subscribeActivitiesDetached(newAct, oldAct, state) { + const myWin = this.window; + if (isUndefinedOrNull(myWin)) { + return; + } + const myActivity = myWin.activity; + if (isUndefinedOrNull(myActivity)) { + return; + } + if (oldAct.id === myActivity.id) { + this._notifyDetached(state); + } + if (newAct.id === myActivity.id) { + this._notifyDetachedFrom(newAct, oldAct, state); + } + } + _subscribeWindowFrameColorChanged(window) { + const act = this.activity; + if (!act) { + return; + } + if (!act.owner) { + return; + } + if (act.owner.underlyingWindow.id === window.id) { + this._myActivityFrameColorChanged.forEach((callback) => { + callback(window.frameColor); + }); + } + } + } + + class ReadyMarker { + constructor(name, signalsToWait) { + this._logger = Logger.Get("ReadyMarker [" + name + "]"); + this._logger.debug("Initializing ready marker for '" + name + "' with " + signalsToWait + " signals to wait"); + if (signalsToWait <= 0) { + throw new Error("Invalid signal number. Should be > 0"); + } + this._signals = signalsToWait; + this._callbacks = []; + this._name = name; + } + setCallback(callback) { + if (this.isSet()) { + callback(undefined); + return; + } + else if (this.isError()) { + callback(this._error); + return; + } + this._callbacks.push(callback); + } + signal(message) { + this._logger.debug("Signaled - " + message + " - signals left " + (this._signals - 1)); + this._signals--; + if (this._signals < 0) { + throw new Error("Error in ready marker '" + this._name + " - signals are " + this._signals); + } + if (this.isSet()) { + this._callbacks.forEach((callback) => { + callback(undefined); + }); + } + } + error(error) { + this._error = error; + this._callbacks.forEach((errorCallback) => { + errorCallback(error); + }); + } + isSet() { + if (this.isError()) { + return false; + } + return this._signals === 0; + } + isError() { + return !isUndefined(this._error); + } + getError() { + return this._error; + } + } + + class EntityObservableCollection { + constructor(processNew) { + this._items = {}; + this._listeners = []; + this._processNew = processNew; + } + addOne(item) { + this.add([item]); + } + add(items) { + items.forEach((element) => { + this.process(new EntityEvent(element, new EntityEventContext(EntityEventType.Added))); + }); + } + process(event) { + const context = event.context; + const type = context.type; + const entity = event.entity; + if (type === EntityEventType.StatusChange && + !context.oldStatus) { + const act = this._items[entity.id]; + if (act) { + context.oldStatus = act.status; + } + } + if (type === EntityEventType.StatusChange && + context.oldStatus && + context.newStatus && + context.oldStatus.state === + context.newStatus.state) { + context.type = EntityEventType.Updated; + } + if (typeof htmlContainer === "undefined") { + if (type === EntityEventType.ActivityWindowJoinedActivity && + this._items[entity.id] && + this._items[entity.id].activity) { + context.type = EntityEventType.Updated; + } + if (type === EntityEventType.ActivityWindowLeftActivity && + this._items[entity.id] && + !this._items[entity.id].activity) { + context.type = EntityEventType.Updated; + } + } + const internalEntity = this._updateInternalCollections(entity, type, context); + this._notifyListeners(internalEntity, context); + return internalEntity; + } + get() { + const result = []; + for (const key in this._items) { + if (this._items.hasOwnProperty(key)) { + const element = this._items[key]; + result.push(element); + } + } + return result; + } + getByName(name) { + for (const key in this._items) { + if (key === name) { + return this._items[key]; + } + } + return undefined; + } + getOrWait(name) { + return new Promise((resolve) => { + const entityAddedHandler = (entity) => { + if (entity.id !== name) { + return; + } + resolve(entity); + this.unsubscribe(entityAddedHandler); + }; + this.subscribe(entityAddedHandler); + const window = this.getByName(name); + if (window) { + this.unsubscribe(entityAddedHandler); + resolve(window); + return; + } + }); + } + subscribe(handler) { + this._listeners.push(handler); + Object.keys(this._items).forEach((key) => { + const element = this._items[key]; + handler(element, new EntityEventContext(EntityEventType.Added.toString())); + }); + return () => { + this.unsubscribe(handler); + }; + } + unsubscribe(handler) { + const index = this._listeners.indexOf(handler); + if (index !== -1) { + this._listeners.splice(index, 1); + } + } + _notifyListeners(entity, context) { + this._listeners.forEach((listener) => { + try { + listener(entity, context); + } + catch (e) { + return; + } + }); + } + _updateInternalCollections(entity, type, context) { + const entityAsAny = entity; + const isActivityDestroy = (type === EntityEventType.StatusChange && + entityAsAny.status && + entityAsAny.status.state === ActivityState.Destroyed) || + (type === EntityEventType.StatusChange && + context && + context.newStatus && + context.newStatus.state === ActivityState.Destroyed); + const isWindowClose = type === EntityEventType.Closed; + const isTypeRemove = type === EntityEventType.Removed && typeof entityAsAny.isIndependent === "undefined"; + if (isTypeRemove || isWindowClose || isActivityDestroy) { + const oldEntity = this._items[entity.id]; + delete this._items[entity.id]; + this._processNew(entity); + if (oldEntity) { + entity._beforeDelete(oldEntity); + } + return entity; + } + else { + const key = entity.id; + if (!this._items.hasOwnProperty(key)) { + this._processNew(entity); + this._items[entity.id] = entity; + } + else { + this._items[entity.id]._update(entity); + } + } + return this._items[entity.id]; + } + } + + class ActivityManager { + get usingHc() { + return this._bridge.bridgeType === "HC"; + } + get announcedWindows() { + return this._announcedWindows; + } + set announcedWindows(v) { + throw new Error("not allowed"); + } + constructor(bridge, autoAnnounce, windows) { + this._logger = Logger.Get("activityManager"); + this._announcedWindows = []; + this._attachedCallbacks = []; + this._detachedCallbacks = []; + this._frameColorChangesCallbacks = []; + this._windowHandlers = []; + this._bridge = bridge; + this._activityTypes = new EntityObservableCollection((e) => this._grabEntity(e)); + this._windowTypes = new EntityObservableCollection((e) => this._grabEntity(e)); + this._activities = new EntityObservableCollection((e) => this._grabEntity(e)); + this._windows = new EntityObservableCollection((e) => this._grabEntity(e)); + this._dataReadyMarker = new ReadyMarker("Activity Manager Data", ["GetActivityTypes", "GetWindowTypes", "GetActivities", "GetWindows"].length); + this._descriptorsMarker = new ReadyMarker("Attached Activities Descriptors", ["GetDescriptors"].length); + if (autoAnnounce) { + this._readyMarker = new ReadyMarker("Activity Manager Announce", ["Announcement"].length); + this._dataReadyMarker.setCallback((dataErr) => { + if (dataErr) { + this._readyMarker.error(dataErr); + } + this._descriptorsMarker.setCallback((err) => { + if (err) { + this._readyMarker.error(err); + } + this._logger.debug("Auto announcing window"); + this.announceWindow() + .then((w) => { + this._announcedWindows.push(w); + this._readyMarker.signal("Successfully announced window with id '" + w.id + "'"); + }) + .catch((errCatch) => { + this._logger.debug("Will not announce window - " + errCatch); + this._readyMarker.signal(); + }); + }); + this.refreshDescriptors(); + }); + } + else { + this._readyMarker = this._dataReadyMarker; + } + this._bridge.onActivitiesAttached((e) => { + this._handleActivitiesAttached(e); + }); + this._bridge.onActivitiesDetached((e) => { + this._handleActivitiesDetached(e); + }); + this._bridge.onActivityAttachedDescriptorsRefreshed((e) => { + this._handleActivityDescriptorsRefreshed(e); + }); + if (windows) { + windows.onWindowFrameColorChanged(this._handleWindowFrameColorChanged.bind(this)); + } + this._bridge.init(); + this._subscribeForData(); + this._bridge + .initReady() + .then((aw) => { + this._getInitialData(); + }) + .catch((error) => { + console.log(error); + }); + } + ready(callback) { + const promise = new Promise((resolve, reject) => { + this._readyMarker.setCallback((err) => { + if (!err) { + resolve(this); + } + else { + reject(this._readyMarker.getError()); + } + }); + }); + return nodeify(Promise.all([this._bridge.ready(), promise]).then(() => this), callback); + } + getActivityTypes() { + return this._activityTypes.get(); + } + getActivityType(name) { + return this._activityTypes.getByName(name); + } + registerActivityType(activityTypeName, ownerWindowType, helperWindowTypes, config, description, callback) { + const promise = new Promise((resolve, reject) => { + if (isUndefinedOrNull(activityTypeName)) { + reject("activityTypeName argument can not be undefined"); + return; + } + if (!isString(activityTypeName)) { + reject("activityTypeName should be string"); + return; + } + const actType = this.getActivityType(activityTypeName); + if (!isUndefinedOrNull(actType)) { + reject("Activity type '" + activityTypeName + "' already exists"); + return; + } + let ownerDefinition; + if (isUndefined(ownerWindowType)) { + reject("Owner window type can not be undefined"); + return; + } + if (isString(ownerWindowType)) { + ownerDefinition = { type: (ownerWindowType), name: "", isIndependent: false, arguments: {} }; + } + else { + ownerDefinition = (ownerWindowType); + } + const helperDefinitions = []; + if (!isUndefined(helperWindowTypes) && isArray(helperWindowTypes)) { + for (const index in helperWindowTypes) { + const item = helperWindowTypes[index]; + if (isString(item)) { + const definition = { + type: (item), + name: "", + isIndependent: false, + arguments: {}, + relativeTo: "", + relativeDirection: "", + windowStyleAttributes: {} + }; + helperDefinitions.push(definition); + } + else { + helperDefinitions.push(item); + } + } + } + this._bridge + .registerActivityType(activityTypeName, ownerDefinition, helperDefinitions, config, description) + .then((activityType) => { + this._grabEntity(activityType); + resolve(activityType); + }) + .catch((error) => { + reject(error); + }); + }); + return nodeify(promise, callback); + } + unregisterActivityType(type, callback) { + const promise = new Promise((resolve, reject) => { + const actType = this.getActivityType(type); + if (isUndefined(actType)) { + reject("Activity type '" + type + "' does not exists"); + return; + } + this._bridge.unregisterActivityType(type).then(() => resolve(actType), reject); + }); + return nodeify(promise, callback); + } + initiate(activityType, context, callback, configuration) { + const promise = new Promise((resolve, reject) => { + const actType = this.getActivityType(activityType); + if (isUndefined(actType)) { + reject("Activity type '" + activityType + "' does not exists"); + return; + } + this._bridge + .initiateActivity(activityType, context, configuration) + .then((actId) => { + this._activities + .getOrWait(actId) + .then((act) => { + resolve(act); + }) + .catch((err) => reject(err)); + }) + .catch((err) => { + reject(err); + }); + }); + return nodeify(promise, callback); + } + subscribeActivityTypeEvents(handler) { + this._activityTypes.subscribe((at, context) => { + handler(at, context.type); + }); + } + getWindowTypes() { + return this._windowTypes.get(); + } + getWindowType(name) { + return this._windowTypes.getByName(name); + } + registerWindowFactory(windowType, factoryMethod, callback) { + const promise = new Promise((resolve, reject) => { + if (isUndefinedOrNull(windowType)) { + reject("no windowType specified"); + return; + } + if (isObject(windowType)) { + windowType = windowType.getName(); + } + else if (!isString(windowType)) { + reject("windowType should be string or object that has getName method"); + return; + } + this._bridge + .registerWindowFactory(windowType, factoryMethod) + .then((v) => { + resolve(v); + }) + .catch((err) => { + reject(err); + }); + }); + return nodeify(promise, callback); + } + unregisterWindowFactory(windowType, callback) { + const promise = new Promise((resolve, reject) => { + if (isUndefinedOrNull(windowType)) { + reject("no windowType specified"); + return; + } + if (!isString(windowType)) { + reject("windowType should be a string"); + return; + } + this._bridge + .unregisterWindowFactory(windowType) + .then((v) => { + resolve(v); + }) + .catch((err) => { + reject(err); + }); + }); + return nodeify(promise, callback); + } + getActivities(activityType) { + let act = this._activities.get(); + act = act.filter((a) => a._ownerId); + if (!activityType) { + return act; + } + let types = activityType; + if (isString(activityType)) { + types = [activityType]; + } + else if (activityType instanceof ActivityType) { + types = [activityType.name]; + } + else if (activityType instanceof Array) ; + else { + throw new Error("Invalid input argument 'activityType' = " + activityType); + } + return act.filter((at) => { + const type = at.type; + return some(types, (t) => { + return type.id === t.id; + }); + }); + } + getActivityById(id) { + return this._activities.getByName(id); + } + announceWindow(activityWindowId, windowType) { + const promise = new Promise((resolve, reject) => { + const announcementInfo = this._bridge.getAnnouncementInfo(); + if (isUndefined(activityWindowId)) { + activityWindowId = announcementInfo.activityWindowId; + } + if (isUndefined(windowType)) { + windowType = announcementInfo.activityWindowType; + } + if (isUndefinedOrNull(windowType)) { + throw new Error("Can not announce - unknown windowType"); + } + const activityId = announcementInfo && announcementInfo.activityId; + if (isUndefinedOrNull(activityWindowId)) { + this._logger.debug("Registering window with type:'" + windowType + "', name:'" + announcementInfo.activityWindowName + "', ind.:'" + announcementInfo.activityWindowIndependent + "'"); + this._bridge.registerWindow(windowType, announcementInfo.activityWindowName, announcementInfo.activityWindowIndependent) + .then(this._windows.getOrWait.bind(this._windows)) + .then((w) => { + if (activityId) { + return this._activities.getOrWait(activityId).then((_) => w); + } + else { + return w; + } + }) + .then((w) => { + resolve(w); + }) + .catch((err) => { + this._logger.error(err); + }); + } + else { + this._logger.debug("Announcing window with id '" + activityWindowId + "' and type '" + windowType + "'"); + const currentWindow = this._windows.getByName(activityWindowId); + if (!isUndefinedOrNull(currentWindow)) { + this._logger.debug("Window with id '" + activityWindowId + "' already announced - reusing the window"); + resolve(currentWindow); + return; + } + const windowEventHandler = (a, w, e) => { + if (activityWindowId === w.id) { + if (e === EntityEventType.ActivityWindowJoinedActivity) { + const activity = w.activity; + if (isUndefined(activity)) { + reject("UNDEFINED ACTIVITY"); + } + this._logger.trace("Got joined event for id '" + activityWindowId + "'"); + resolve(w); + this.unsubscribeWindowEvents(windowEventHandler); + } + } + }; + this.subscribeWindowEvents(windowEventHandler); + this._logger.trace("Waiting for joined event for id '" + activityWindowId + "'"); + this._bridge.announceWindow(windowType, activityWindowId); + } + }); + return promise; + } + subscribeWindowTypeEvents(handler) { + this._windowTypes.subscribe((wt, context) => { + handler(wt, context.type); + }); + } + subscribeActivityEvents(handler) { + return this._activities.subscribe((act, context) => { + if (context.type === EntityEventType.StatusChange) { + const p = context; + handler(act, p.newStatus, p.oldStatus); + } + if (context.type === EntityEventType.Removed || + (context.type === EntityEventType.StatusChange && + context.newStatus.getState() === ActivityState.Destroyed)) { + for (const window of this._windows.get()) { + if (window.activity && window.activity.id === act.id) { + this._windows.process(new EntityEvent(window, new EntityEventContext(EntityEventType.ActivityWindowLeftActivity))); + } + } + } + }); + } + subscribeWindowEvents(handler) { + const wrappingHandler = (window, context) => { + let eventType = context.type; + if (eventType === EntityEventType.Added) { + eventType = "opened"; + } + handler(window.activity, window, eventType); + }; + this._windowHandlers.push([handler, wrappingHandler]); + return this._windows.subscribe(wrappingHandler); + } + unsubscribeWindowEvents(handler) { + const found = this._windowHandlers.find((pair) => pair[0] === handler); + if (found) { + this._windowHandlers.splice(this._windowHandlers.indexOf(found), 1); + this._windows.unsubscribe(found[1]); + } + } + createWindow(activity, windowTypeOrConfiguration, callback) { + const promise = new Promise((resolve, reject) => { + if (isUndefinedOrNull(windowTypeOrConfiguration)) { + reject("windowType is undefined"); + } + let windowDefinition; + if (isString(windowTypeOrConfiguration)) { + windowDefinition = { type: (windowTypeOrConfiguration), name: "", isIndependent: false, arguments: {} }; + } + else if (windowTypeOrConfiguration instanceof WindowType) { + windowDefinition = { + type: windowTypeOrConfiguration.type || windowTypeOrConfiguration.id, + name: windowTypeOrConfiguration.name || windowTypeOrConfiguration.type || windowTypeOrConfiguration.id, + isIndependent: false + }; + } + else { + const invalidKeys = ["url"]; + const filteredWindowTypeOrConfiguration = {}; + Object.keys(windowTypeOrConfiguration).forEach((key) => { + if (invalidKeys.indexOf(key) === -1) { + filteredWindowTypeOrConfiguration[key] = windowTypeOrConfiguration[key]; + } + }); + windowDefinition = filteredWindowTypeOrConfiguration; + } + let relativeToWindow; + if (!isUndefinedOrNull(windowDefinition.relativeTo)) { + relativeToWindow = windowDefinition.relativeTo; + if (typeof relativeToWindow === "string") { + const windows = this.getWindows({ type: relativeToWindow }); + if (!isUndefinedOrNull(windows) && windows.length > 0) { + windowDefinition.relativeTo = windows[0].id; + } + } + else if (!isUndefinedOrNull(relativeToWindow.type)) { + const windows = this.getWindows({ type: relativeToWindow.type }); + if (!isUndefinedOrNull(windows) && windows.length > 0) { + windowDefinition.relativeTo = windows[0].id; + } + } + else if (!isUndefinedOrNull(relativeToWindow.windowId)) { + windowDefinition.relativeTo = relativeToWindow.windowId; + } + } + this._bridge.createWindow(activity && activity.id, windowDefinition) + .then((wid) => { + this._logger.debug("Window created, waiting for window entity with id " + wid); + const handler = (window, context) => { + if (window.id === wid && (!activity || window.activity)) { + this._logger.debug("Got entity window with id " + wid); + resolve(window); + this._windows.unsubscribe(handler); + } + }; + this._windows.subscribe(handler); + }) + .catch((err) => { + reject(err); + }); + }); + return nodeify(promise, callback); + } + createStackedWindows(activity, relativeWindowTypes, timeout, callback) { + const promise = new Promise((resolve, reject) => { + if (isUndefinedOrNull(activity)) { + reject("activity is undefined"); + } + if (isUndefinedOrNull(relativeWindowTypes)) { + reject("relativeWindowTypes is undefined"); + } + if (!Array.isArray(relativeWindowTypes)) { + reject("relativeWindowTypes has to be an array"); + } + if (isUndefinedOrNull(timeout)) { + timeout = 20000; + } + const windowDefinitions = []; + relativeWindowTypes.forEach((element) => { + let windowDefinition; + if (isString(element)) { + windowDefinition = { type: (element), name: "", isIndependent: false, arguments: {} }; + } + else { + windowDefinition = (element); + } + windowDefinition.stackedWindow = true; + windowDefinition.timeout = timeout; + let relativeToWindow; + if (!isUndefinedOrNull(windowDefinition.relativeTo)) { + relativeToWindow = windowDefinition.relativeTo; + if (!isUndefinedOrNull(relativeToWindow.type)) { + windowDefinition.relativeTo = relativeToWindow.type; + } + else if (!isUndefinedOrNull(relativeToWindow.windowId)) { + const windows = this.getWindows({ id: relativeToWindow.windowId }); + if (!isUndefinedOrNull(windows) && windows.length > 0) { + windowDefinition.relativeTo = windows[0].type.name; + } + } + } + windowDefinitions.push(windowDefinition); + }); + const tasks = []; + windowDefinitions.forEach((wd) => tasks.push(this.createWindow(activity, wd))); + Promise.all(tasks).then(resolve).catch(reject); + }); + return nodeify(promise, callback); + } + addWindowToActivity(activity, window, callback) { + const toReturn = this._bridge.joinActivity(activity.id, window.id) + .then(() => window); + nodeify(toReturn, callback); + return toReturn; + } + leaveWindowFromActivity(activity, window, callback) { + const toReturn = this._bridge.leaveActivity(activity.id, window.id) + .then(() => window); + nodeify(toReturn, callback); + return toReturn; + } + setActivityContext(activity, context, callback) { + const promise = new Promise((resolve, reject) => { + if (isUndefinedOrNull(activity)) { + reject("activity can not be null"); + } + this._bridge + .updateActivityContext(activity, context, true) + .then((_) => { + resolve(activity); + }) + .catch((err) => { + reject(err); + }); + }); + return nodeify(promise, callback); + } + updateActivityContext(activity, context, callback) { + const promise = new Promise((resolve, reject) => { + if (isUndefinedOrNull(activity)) { + reject("activity can not be null"); + } + const removedKeys = []; + for (const key in context) { + if (context.hasOwnProperty(key) && context[key] === null) { + removedKeys.push(key); + } + } + for (const removedKey of removedKeys) { + delete context[removedKey]; + } + this._bridge + .updateActivityContext(activity, context, false, removedKeys) + .then((_) => { + resolve(activity); + }) + .catch((err) => { + reject(err); + }); + }); + return nodeify(promise, callback); + } + subscribeActivityContextChanged(handler) { + this._activities.subscribe((act, context) => { + if (context.type === EntityEventType.ActivityContextChange) { + const updateContext = context; + handler(act, updateContext.context, updateContext.updated, updateContext.removed); + } + }); + } + stopActivity(activity, callback) { + const promise = this._bridge.stopActivity(activity); + return nodeify(promise, callback); + } + getWindows(filter) { + if (isUndefined(filter)) { + return this._windows.get(); + } + if (!isUndefined(filter.id)) { + return [this._windows.getByName(filter.id)]; + } + const allWindows = this._windows.get(); + return allWindows.filter((w) => { + if (!isUndefined(filter.type) && w.type.id !== filter.type) { + return false; + } + if (!isUndefined(filter.name) && w.name !== filter.name) { + return false; + } + if (!isUndefined(filter.activityId)) { + if (isUndefinedOrNull(w.activity)) { + return false; + } + if (w.activity.id !== filter.activityId) { + return false; + } + } + return true; + }); + } + getWindowBounds(id) { + return this._bridge.getWindowBounds(id); + } + setWindowBounds(id, bounds, callback) { + const promise = new Promise((resolve, reject) => { + this._bridge.setWindowBounds(id, bounds) + .then(() => resolve()) + .catch((err) => reject(err)); + }); + return nodeify(promise, callback); + } + closeWindow(id) { + return this._bridge.closeWindow(id); + } + activateWindow(id, focus) { + return this._bridge.activateWindow(id, focus); + } + setWindowVisibility(id, visible) { + return this._bridge.setWindowVisibility(id, visible); + } + clone(activity, cloneOptions, callback) { + const promise = new Promise((resolve, reject) => { + if (!activity) { + reject("activity can not be null"); + } + this._bridge.cloneActivity(activity.id, cloneOptions) + .then((activityId) => { + this._activities + .getOrWait(activityId) + .then((act) => { + resolve(act); + }) + .catch((err) => reject(err)); + }) + .catch((err) => reject(err)); + }); + return nodeify(promise, callback); + } + attachActivities(from, to, tag, callback) { + tag = tag || {}; + const promise = new Promise((resolve, reject) => { + const fromActivity = this._activities.getByName(from); + if (!fromActivity) { + reject("can not find activity with id " + from); + return; + } + const toActivity = this._activities.getByName(to); + if (!toActivity) { + reject("can not find activity with id " + to); + return; + } + return this._bridge.attachActivities(from, to, tag) + .then((data) => { + const newActId = data.to; + const state = data.descriptor; + const allStates = data.descriptors; + this._activities.getOrWait(newActId).then((act) => { + act._updateDescriptors(allStates); + const stateWrapped = act.attached.filter((u) => u.ownerId === state.ownerId)[0]; + resolve(stateWrapped); + }); + }) + .catch((err) => { + reject(err); + }); + }); + return nodeify(promise, callback); + } + detachActivities(activityId, descriptor, callback) { + const promise = new Promise((resolve, reject) => { + return this._bridge.detachActivities(activityId, descriptor) + .then(() => { + const oldActId = undefined; + const newActId = undefined; + const descriptors = undefined; + this._activities + .getOrWait(oldActId) + .then((oldAct) => { + oldAct._updateDescriptors(descriptors); + this._activities + .getOrWait(newActId) + .then((newAct) => { + resolve(newAct); + }); + }) + .catch((err) => reject(err)); + }) + .catch((err) => { + reject(err); + }); + }); + return nodeify(promise, callback); + } + subscribeActivitiesAttached(callback) { + this._attachedCallbacks.push(callback); + } + subscribeActivitiesDetached(callback) { + this._detachedCallbacks.push(callback); + } + subscribeActivityFrameColorChanged(callback) { + this._frameColorChangesCallbacks.push(callback); + } + _grabEntity(entity) { + entity._manager = this; + } + _getInitialData() { + this._logger.debug("Request initial data..."); + this._bridge.getActivityTypes() + .then((at) => { + this._activityTypes.add(at); + this._dataReadyMarker.signal("Got act types"); + }) + .catch((error) => { + this._logger.error(error); + this._dataReadyMarker.error("Can not initialize ActivityManager - error getting activity types -" + error); + }); + this._bridge.getWindowTypes() + .then((wt) => { + this._windowTypes.add(wt); + this._dataReadyMarker.signal("Got window types"); + }) + .catch((error) => { + this._logger.error(error); + this._dataReadyMarker.error("Can not initialize ActivityManager - error getting window types " + error); + }); + this._bridge.getActivities() + .then((ac) => { + this._activities.add(ac); + this._dataReadyMarker.signal("Got activities"); + }) + .catch((error) => { + this._logger.error(error); + this._dataReadyMarker.error("Can not initialize ActivityManager - error getting activity instances -" + error); + }); + this._bridge.getActivityWindows() + .then((aw) => { + this._windows.add(aw); + this._dataReadyMarker.signal("Got windows"); + }) + .catch((error) => { + this._logger.error(error); + this._dataReadyMarker.error("Can not initialize ActivityManager - error getting activity windows -" + error); + }); + } + _subscribeForData() { + this._logger.debug("Subscribe for data..."); + this._bridge.onActivityTypeStatusChange((event) => { + this._activityTypes.process(event); + }); + this._bridge.onWindowTypeStatusChange((event) => { + this._windowTypes.process(event); + }); + this._bridge.onActivityWindowChange((event) => { + this._windows.process(event); + }); + this._bridge.onActivityStatusChange((event) => { + this._activities.process(event); + }); + } + _handleActivitiesAttached(data) { + const newActId = data.to; + const descriptor = data.descriptor; + const descriptors = data.descriptors; + this._activities.getOrWait(newActId).then((act) => { + act._updateDescriptors(descriptors); + const descriptorAsObjectFromAPI = act.attached.filter((u) => u.ownerId === descriptor.ownerId)[0]; + this._attachedCallbacks.forEach((callback) => { + try { + callback(act, descriptorAsObjectFromAPI); + } + catch (err) { + return; + } + }); + }); + } + _handleActivitiesDetached(data) { + const oldActId = data.oldActivityId; + const newActId = data.newActivityId; + const descriptors = data.descriptors; + const descriptor = data.descriptor; + this._activities.getOrWait(oldActId).then((oldAct) => { + oldAct._updateDescriptors(descriptors); + this._activities.getOrWait(newActId).then((newAct) => { + this._detachedCallbacks.forEach((callback) => { + try { + callback(newAct, oldAct, descriptor); + } + catch (err) { + return; + } + }); + }); + }); + } + _handleActivityDescriptorsRefreshed(data) { + const id = data.id; + const descriptors = data.descriptors; + const act = this._activities.getByName(id); + if (act) { + act._updateDescriptors(descriptors); + } + } + refreshDescriptors() { + this._bridge.getAttachedDescriptors() + .then((map) => { + if (map) { + Object.keys(map).forEach((key) => { + const actId = key; + const descriptors = map[key]; + const act = this._activities.getByName(actId); + if (act) { + act._updateDescriptors(descriptors); + } + }); + } + this._descriptorsMarker.signal("Successfully got descriptors"); + }) + .catch((err) => { + this._descriptorsMarker.error("failed to get descriptors - " + err); + }); + } + _handleWindowFrameColorChanged(win) { + if (!win.activityId) { + return; + } + const act = this._activities.getByName(win.activityId); + if (!act) { + return; + } + if (!act.owner) { + return; + } + if (act.owner.underlyingWindow.id !== win.id) { + return; + } + this._frameColorChangesCallbacks.forEach((callback) => { + try { + callback(act, win.frameColor); + } + catch (e) { + return; + } + }); + } + } + + class ActivityManagementAPI { + constructor(manager, my) { + this._m = manager; + this._my = my; + this.activityTypes = { + get: this._getActivityTypesWrapper.bind(this), + register: this._m.registerActivityType.bind(this._m), + unregister: this._m.unregisterActivityType.bind(this._m), + subscribe: this._m.subscribeActivityTypeEvents.bind(this._m), + unsubscribe: undefined, + initiate: this._m.initiate.bind(this._m) + }; + this.windowTypes = { + get: this._getWindowTypesWrapper.bind(this), + registerFactory: this._m.registerWindowFactory.bind(this._m), + unregisterFactory: this._m.unregisterWindowFactory.bind(this._m), + subscribe: this._m.subscribeWindowTypeEvents.bind(this._m), + unsubscribe: undefined + }; + this.windows = { + get: this._m.getWindows.bind(this._m), + subscribe: this._m.subscribeWindowEvents.bind(this._m), + announce: this._m.announceWindow.bind(this._m), + unsubscribe: undefined, + create: this._m.createWindow.bind(this._m) + }; + this.instances = { + get: this._m.getActivities.bind(this._m), + subscribe: this._m.subscribeActivityEvents.bind(this._m), + unsubscribe: undefined + }; + } + onAttached(callback) { + this._m.subscribeActivitiesAttached(callback); + } + onDetached(callback) { + this._m.subscribeActivitiesDetached(callback); + } + onActivityFrameColorChanged(callback) { + this._m.subscribeActivityFrameColorChanged(callback); + } + _getActivityTypesWrapper(name) { + if (isUndefined(name)) { + return this._m.getActivityTypes(); + } + return this._m.getActivityType(name); + } + _getWindowTypesWrapper(name) { + if (isUndefined(name)) { + return this._m.getWindowTypes(); + } + return this._m.getWindowType(name); + } + } + + class ActivityAPI { + constructor(manager, my) { + this._mgr = manager; + this._my = my; + this.all = new ActivityManagementAPI(manager, my); + } + ready(callback) { + const promise = new Promise((resolve, reject) => { + this._mgr.ready() + .then(() => { + resolve(this); + }) + .catch((err) => { + reject(err); + }); + }); + return nodeify(promise, callback); + } + get my() { + return this._my; + } + get aware() { + return this._my.window !== undefined; + } + get inActivity() { + return this.aware && this._my.activity !== undefined; + } + get agm() { + if (!this.aware) { + return undefined; + } + if (!this.inActivity) { + return new ActivityAGM(null); + } + return this._my.activity.agm; + } + getAvailableFrameColors() { + return []; + } + } + + class ActivityModule { + static checkIsUsingGW3Implementation(connection) { + return connection.protocolVersion === 3; + } + get api() { + return this._api; + } + set api(value) { + this._api = value; + } + constructor(config) { + if (!config) { + throw new Error("config can not be null"); + } + if (!isUndefined(config.logLevel)) { + Logger.Level = config.logLevel; + } + if (!isUndefinedOrNull(config.logger)) { + Logger.GlueLogger = config.logger; + } + let bridge; + this._isUsingHCImplementation = config.gdMajorVersion === 2; + this._isUsingGW3Implementation = ActivityModule.checkIsUsingGW3Implementation(config.connection); + if (this._isUsingHCImplementation) { + throw new Error("GD2 not supported"); + } + else if (this._isUsingGW3Implementation) { + bridge = new GW3Bridge(config); + } + else { + throw new Error("Unable to instantiate activity bridge implementation"); + } + if (!bridge) { + throw new Error("A bridge to native activity is needed to create activity lib."); + } + ActivityAGM.AGM = config.agm; + const activityManager = new ActivityManager(bridge, !config.disableAutoAnnounce, config.windows); + const my = new ActivityMy(activityManager, config.windows); + this._api = new ActivityAPI(activityManager, my); + this._readyPromise = activityManager.ready().then((_) => this); + } + get isUsingHCImplementation() { + return this._isUsingHCImplementation; + } + get isUsingGW3Implementation() { + return this._isUsingGW3Implementation; + } + ready(callback) { + return nodeify(this._readyPromise, callback); + } + } + + const ShutdownMethodName = "T42.ACS.Shutdown"; + const OnGDShutdownMethodName = "T42.ACS.OnGDShutdown"; + const RestartMethodName = "T42.ACS.Restart"; + const GetConfigurationRegionMethodName = "T42.ACS.GetConfigurationRegion"; + const SetConfigurationRegionMethodName = "T42.ACS.SetConfigurationRegion"; + const GetUserMethodName = "T42.ACS.GetUser"; + const GetBranchesMethodName = "T42.ACS.GetBranches"; + const GetCurrentBranchMethodName = "T42.ACS.GetCurrentBranch"; + const SetCurrentBranchMethodName = "T42.ACS.SetCurrentBranch"; + const GetFunctionalEntitlementMethodName = "T42.ACS.GetFunctionalEntitlement"; + const CanIMethodName = "T42.ACS.CanI"; + const StartApplicationMethodName = "T42.ACS.StartApplication"; + const StopApplicationMethodName = "T42.ACS.StopApplication"; + const ActivateApplicationMethodName = "T42.ACS.ActivateApplication"; + const ACSExecute = "T42.ACS.Execute"; + const OnEventMethodName = "T42.ACS.OnEvent"; + const GetApplicationsMethodName = "T42.ACS.GetApplications"; + + var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; + + function getDefaultExportFromCjs (x) { + return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; + } + + function createRegistry(options) { + if (options && options.errorHandling + && typeof options.errorHandling !== "function" + && options.errorHandling !== "log" + && options.errorHandling !== "silent" + && options.errorHandling !== "throw") { + throw new Error("Invalid options passed to createRegistry. Prop errorHandling should be [\"log\" | \"silent\" | \"throw\" | (err) => void], but " + typeof options.errorHandling + " was passed"); + } + var _userErrorHandler = options && typeof options.errorHandling === "function" && options.errorHandling; + var callbacks = {}; + function add(key, callback, replayArgumentsArr) { + var callbacksForKey = callbacks[key]; + if (!callbacksForKey) { + callbacksForKey = []; + callbacks[key] = callbacksForKey; + } + callbacksForKey.push(callback); + if (replayArgumentsArr) { + setTimeout(function () { + replayArgumentsArr.forEach(function (replayArgument) { + var _a; + if ((_a = callbacks[key]) === null || _a === void 0 ? void 0 : _a.includes(callback)) { + try { + if (Array.isArray(replayArgument)) { + callback.apply(undefined, replayArgument); + } + else { + callback.apply(undefined, [replayArgument]); + } + } + catch (err) { + _handleError(err, key); + } + } + }); + }, 0); + } + return function () { + var allForKey = callbacks[key]; + if (!allForKey) { + return; + } + allForKey = allForKey.reduce(function (acc, element, index) { + if (!(element === callback && acc.length === index)) { + acc.push(element); + } + return acc; + }, []); + if (allForKey.length === 0) { + delete callbacks[key]; + } + else { + callbacks[key] = allForKey; + } + }; + } + function execute(key) { + var argumentsArr = []; + for (var _i = 1; _i < arguments.length; _i++) { + argumentsArr[_i - 1] = arguments[_i]; + } + var callbacksForKey = callbacks[key]; + if (!callbacksForKey || callbacksForKey.length === 0) { + return []; + } + var results = []; + callbacksForKey.forEach(function (callback) { + try { + var result = callback.apply(undefined, argumentsArr); + results.push(result); + } + catch (err) { + results.push(undefined); + _handleError(err, key); + } + }); + return results; + } + function _handleError(exceptionArtifact, key) { + var errParam = exceptionArtifact instanceof Error ? exceptionArtifact : new Error(exceptionArtifact); + if (_userErrorHandler) { + _userErrorHandler(errParam); + return; + } + var msg = "[ERROR] callback-registry: User callback for key \"" + key + "\" failed: " + errParam.stack; + if (options) { + switch (options.errorHandling) { + case "log": + return console.error(msg); + case "silent": + return; + case "throw": + throw new Error(msg); + } + } + console.error(msg); + } + function clear() { + callbacks = {}; + } + function clearKey(key) { + var callbacksForKey = callbacks[key]; + if (!callbacksForKey) { + return; + } + delete callbacks[key]; + } + return { + add: add, + execute: execute, + clear: clear, + clearKey: clearKey + }; + } + createRegistry.default = createRegistry; + var lib = createRegistry; + + + var CallbackRegistryFactory = /*@__PURE__*/getDefaultExportFromCjs(lib); + + function objectValues(source) { + if (!source) { + return []; + } + return Object.keys(source).map((key) => source[key]); + } + function objectClone(obj) { + let result; + try { + result = JSON.parse(JSON.stringify(obj || {})); + } + catch (error) { + result = {}; + } + return result; + } + function validate(callback, configuration) { + if (configuration.throwErrors) { + if (typeof callback !== "function") { + throw new Error("Please provide the callback as a function!"); + } + } + } + + const INTEROP_METHOD_RESPONSE_TIMEOUT_MS = 90000; + const INTEROP_METHOD_WAIT_TIMEOUT_MS = 90000; + + let urlAlphabet = + 'useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict'; + let nanoid = (size = 21) => { + let id = ''; + let i = size | 0; + while (i--) { + id += urlAlphabet[(Math.random() * 64) | 0]; + } + return id + }; + + class Utils { + static getGDMajorVersion() { + if (typeof window === "undefined") { + return -1; + } + if (!window.glueDesktop) { + return -1; + } + if (!window.glueDesktop.version) { + return -1; + } + const parsed = window.glueDesktop.version.split("."); + const major = Number(parsed[0]); + return isNaN(major) ? -1 : major; + } + static typedError(error) { + let err; + if (error instanceof Error) { + err = error; + } + else if (typeof error === "string") { + err = new Error(error); + } + else if ("message" in error && typeof error.message === "string" && error.message.length > 0) { + err = new Error(error.message); + } + else if ("returned" in error + && typeof error.returned === "object" + && "errorMsg" in error.returned + && typeof error.returned.errorMsg === "string" + && error.returned.errorMsg.length > 0) { + err = new Error(error.returned.errorMsg); + } + else { + err = new Error("Unknown error"); + } + return err; + } + static async callbackifyPromise(action, successCallback, errorCallback) { + const success = (result) => { + if (typeof successCallback === "function") { + successCallback(result); + } + return Promise.resolve(result); + }; + const fail = (error) => { + const err = Utils.typedError(error); + if (typeof errorCallback === "function") { + errorCallback(err.message); + return; + } + return Promise.reject(err); + }; + try { + const result = await action(); + return success(result); + } + catch (error) { + return fail(error); + } + } + static getMonitor(bounds, displays) { + const monitorsSortedByOverlap = displays.map((m) => { + const { left, top, workingAreaWidth: width, workingAreaHeight: height } = m; + const overlap = this.calculateTotalOverlap({ left, top, width, height }, bounds); + return { + monitor: m, + totalOverlap: overlap + }; + }).sort((a, b) => b.totalOverlap - a.totalOverlap); + return monitorsSortedByOverlap[0].monitor; + } + static getDisplayCenterOfScreen(a, currentDisplay, primaryDisplay) { + const physicalWidth = a.width / currentDisplay.scaleFactor; + const physicalHeight = a.height / currentDisplay.scaleFactor; + const physicalDisplayLeft = currentDisplay.workArea.left / primaryDisplay.scaleFactor; + const physicalDisplayTop = currentDisplay.workArea.top / primaryDisplay.scaleFactor; + const physicalDisplayWidth = currentDisplay.workArea.width / currentDisplay.scaleFactor; + const physicalDisplayHeight = currentDisplay.workArea.height / currentDisplay.scaleFactor; + const physicalHOffset = Math.max((physicalDisplayWidth - physicalWidth) / 2, 0); + const physicalVOffset = Math.max((physicalDisplayHeight - physicalHeight) / 2, 0); + const centeredPhysicalLeft = Math.floor(physicalDisplayLeft + physicalHOffset); + const centeredPhysicalTop = Math.floor(physicalDisplayTop + physicalVOffset); + const left = centeredPhysicalLeft * primaryDisplay.scaleFactor; + const top = centeredPhysicalTop * primaryDisplay.scaleFactor; + return { + left, + top, + width: a.width, + height: a.height + }; + } + static isNode() { + if (typeof Utils._isNode !== "undefined") { + return Utils._isNode; + } + if (typeof window !== "undefined") { + Utils._isNode = false; + return false; + } + try { + Utils._isNode = Object.prototype.toString.call(global.process) === "[object process]"; + } + catch (e) { + Utils._isNode = false; + } + return Utils._isNode; + } + static generateId() { + return nanoid(10); + } + static isPromise(value) { + return Boolean(value && typeof value.then === 'function'); + } + static isAsyncFunction(value) { + return value && {}.toString.call(value) === '[object AsyncFunction]'; + } + static isNullOrUndefined(value) { + return value === null || value === undefined; + } + static calculateTotalOverlap(r1, r2) { + const r1x = r1.left; + const r1y = r1.top; + const r1xMax = r1x + r1.width; + const r1yMax = r1y + r1.height; + const r2x = r2.left; + const r2y = r2.top; + const r2xMax = r2x + r2.width; + const r2yMax = r2y + r2.height; + const xOverlap = Math.max(0, Math.min(r1xMax, r2xMax) - Math.max(r1x, r2x)); + const yOverlap = Math.max(0, Math.min(r1yMax, r2yMax) - Math.max(r1y, r2y)); + return xOverlap * yOverlap; + } + } + + class ApplicationImpl { + constructor(_appManager, _name, _agm, _logger, _configuration) { + this._appManager = _appManager; + this._name = _name; + this._agm = _agm; + this._logger = _logger; + this._configuration = _configuration; + this._registry = CallbackRegistryFactory(); + _appManager.onInstanceStarted((instance) => { + if (instance.application && instance.application.name !== this._name) { + return; + } + this._registry.execute("instanceStarted", instance); + }); + _appManager.onInstanceStopped((instance) => { + if (instance.application && instance.application.name !== this._name) { + return; + } + this._registry.execute("instanceStopped", instance); + }); + _appManager.onAppRemoved((app) => { + if (app.name !== this._name) { + return; + } + this._registry.execute("appRemoved", app); + }); + _appManager.onAppChanged((app) => { + if (app.name !== this._name) { + return; + } + this._registry.execute("appChanged", app); + }); + _appManager.onAppAvailable((app) => { + if (app.name !== this._name) { + return; + } + this._props.IsReady = true; + this._registry.execute("appAvailable", app); + }); + _appManager.onAppUnavailable((app) => { + if (app.name !== this._name) { + return; + } + this._props.IsReady = false; + this._registry.execute("appUnavailable", app); + }); + } + get name() { return this._name; } + get title() { return this._props.Title; } + get version() { return this._props.Version; } + get autoStart() { return this._props.AutoStart; } + get isShell() { return this._props.IsShell; } + get caption() { return this._props.Caption; } + get hidden() { return this._props.IsHidden; } + get container() { return this._props.ApplicationName; } + get activityType() { return this._props.ActivityType; } + get activityWindowType() { return this._props.ActivityWindowType; } + get windowSettings() { + if (!this._props.Arguments) { + return {}; + } + return objectClone(this._props.Arguments); + } + get allowMultiple() { return this._props.AllowMultiple; } + get available() { return this._props.IsReady || true; } + get icon() { return this._props.Icon; } + get iconURL() { return this._props.IconUrl; } + get sortOrder() { return this._props.SortOrder; } + get userProperties() { + if (!this._props.UserProperties) { + return {}; + } + return objectClone(this._props.UserProperties); + } + get keywords() { + if (!this._props.Keywords) { + return []; + } + return this._props.Keywords; + } + get isActivity() { + return this._props.ActivityType !== undefined && this._props.ActivityType !== ""; + } + get configuration() { + return { + autoStart: this._props.AutoStart, + caption: this._props.Caption, + hidden: this._props.IsHidden, + container: this._props.ApplicationName, + activityType: this._props.ActivityType, + allowMultiple: this._props.AllowMultiple + }; + } + get instances() { + return this._appManager.instances().filter((instance) => instance.application.name === this._name); + } + get type() { + return this._props.Type; + } + get mode() { + if (!this._props) { + return "unknown"; + } + if (this._props.Mode && typeof this._props.Mode === "string") { + return this._props.Mode.toLowerCase(); + } + if (this.isActivity) { + return "unknown"; + } + if (this._props.Arguments && this._props.Arguments.mode && typeof this._props.Arguments.mode === "string") { + return this._props.Arguments.mode.toLowerCase(); + } + let styleAttributes = this._props.WindowStyleAttributes; + if (styleAttributes) { + styleAttributes = styleAttributes.split(" ").join(""); + const searchFor = "mode:\""; + const modeIndex = styleAttributes.indexOf(searchFor); + if (modeIndex !== -1) { + const startModeIndex = modeIndex + searchFor.length; + const stopModeIndex = styleAttributes.indexOf("\"", startModeIndex); + const style = styleAttributes.substr(startModeIndex, stopModeIndex - startModeIndex); + if (style && typeof style === "string") { + return style.toLowerCase(); + } + } + } + return "flat"; + } + async getConfiguration() { + const result = await this._agm.invoke(GetApplicationsMethodName, { v2: { apps: [this._name] } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + const config = result.returned.applications[0]; + return config; + } + updateFromProps(props) { + if (!this._props) { + this._props = { Name: props.Name }; + } + Object.keys(props).forEach((key) => { + this._props[key] = props[key]; + }); + } + start(context, options) { + return new Promise(async (resolve, reject) => { + var _a, _b, _c, _d; + if (isUndefinedOrNull(context)) { + context = {}; + } + else if (((_a = this._configuration()) === null || _a === void 0 ? void 0 : _a.throwErrors) && typeof context !== "object" || Array.isArray(context)) { + return reject(new Error(`Invalid "context" parameter - must be an object.`)); + } + if (isUndefinedOrNull(options)) { + options = {}; + } + else if (((_b = this._configuration()) === null || _b === void 0 ? void 0 : _b.throwErrors) && typeof options !== "object") { + return reject(new Error(`Invalid "options" parameter - must be an object.`)); + } + const name = this._name; + let waitForAGMInstance = (_d = ((_c = options.awaitInterop) !== null && _c !== void 0 ? _c : options.waitForAGMReady)) !== null && _d !== void 0 ? _d : true; + let startTimeout = 60000; + if (typeof options.timeout === "number") { + startTimeout = options.timeout * 1000; + } + if (options.relativeTo !== undefined && typeof options.relativeTo !== "string") { + options.relativeTo = options.relativeTo.id || ""; + } + const waitForApplicationInstance = (id) => { + let unsub; + const timeout = setTimeout(() => { + if (unsub) { + unsub(); + } + const errMsg = `timed out while waiting for instance id ${id} for app ${this.name}`; + this._logger.error(errMsg); + reject(new Error(errMsg)); + }, startTimeout); + const waitFunc = (i) => { + if (i.id !== id) { + return; + } + if (unsub) { + unsub(); + unsub = undefined; + } + clearTimeout(timeout); + resolve(i); + }; + if (waitForAGMInstance) { + const instance = this._appManager.instances().find((i) => i.id === id); + if (instance) { + unsub = instance.onAgmReady(waitFunc); + } + else { + unsub = this._appManager.onInstanceAgmServerReady(waitFunc); + } + } + else { + unsub = this._appManager.onInstanceStarted(waitFunc); + } + }; + try { + this._logger.trace(`starting application ${name} with options: ${JSON.stringify(options)}`); + const result = await this._agm.invoke(StartApplicationMethodName, { + Name: name, + Context: context, + Options: options + }, "best", { + methodResponseTimeoutMs: startTimeout, + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + const acsResult = result.returned; + if (typeof acsResult.timeout !== "undefined" && typeof options.timeout === "undefined") { + startTimeout = acsResult.timeout * 1000; + } + if (typeof acsResult.waitForInterop !== "undefined" && (typeof options.waitForAGMReady === "undefined" && typeof options.awaitInterop === "undefined")) { + waitForAGMInstance = acsResult.waitForInterop; + } + if (acsResult && acsResult.Id) { + if (this._appManager.mode === "startOnly") { + const instance = this._appManager.handleInstanceStarted({ + ActivityId: undefined, + IsActivityOwner: undefined, + Context: undefined, + Title: undefined, + AgmServers: undefined, + Id: acsResult.Id, + Name: acsResult.Name, + }); + resolve(instance); + } + else { + waitForApplicationInstance(acsResult.Id); + } + } + else { + resolve(undefined); + } + } + catch (error) { + const err = Utils.typedError(error); + reject(err); + } + }); + } + onInstanceStarted(callback) { + validate(callback, this._configuration()); + return this._registry.add("instanceStarted", callback); + } + onInstanceStopped(callback) { + validate(callback, this._configuration()); + return this._registry.add("instanceStopped", callback); + } + onAvailable(callback) { + validate(callback, this._configuration()); + if (this._props.IsReady) { + setTimeout(() => { + this._registry.execute("appAvailable", this); + }, 0); + } + return this._registry.add("appAvailable", callback); + } + onUnavailable(callback) { + validate(callback, this._configuration()); + if (this._props.IsReady === false) { + setTimeout(() => { + this._registry.execute("appUnavailable", this); + }, 0); + } + return this._registry.add("appUnavailable", callback); + } + onChanged(callback) { + validate(callback, this._configuration()); + this._registry.add("appChanged", callback); + } + onRemoved(callback) { + validate(callback, this._configuration()); + this._registry.add("appRemoved", callback); + } + } + + class InstanceImpl { + constructor(_id, _appName, _appManager, _agm, _activities, _windows, _logger, startFailed, _configuration) { + this._id = _id; + this._appName = _appName; + this._appManager = _appManager; + this._agm = _agm; + this._activities = _activities; + this._windows = _windows; + this._logger = _logger; + this._configuration = _configuration; + this._registry = CallbackRegistryFactory(); + if (startFailed) { + return; + } + this._unsubscribeInstanceStopped = this._appManager.onInstanceStopped((instance) => { + if (instance.id !== this._id) { + return; + } + this._registry.execute("stopped", instance); + }); + this._unsubscribeInstanceAgmServerReady = this._appManager.onInstanceAgmServerReady((instance) => { + if (instance.id !== this._id) { + return; + } + this._registry.execute("agmReady", instance); + }); + } + get id() { return this._id; } + get application() { return this._appManager.application(this._appName); } + get activity() { + if (!this._activities) { + throw new Error("This method requires glue.activities library to be enabled."); + } + return this._activities.all.instances.get() + .filter((activityInstance) => activityInstance.id === this._activityId)[0]; + } + get isActivityOwner() { return this._isActivityOwner; } + get activityInstances() { + return this._appManager.instances().filter((i) => i.application.type !== "activity" && + i.activityId && + i.activityId === this._activityId); + } + get activityOwnerInstance() { + if (!this._activityId) { + return undefined; + } + return this.activityInstances.filter((inst) => inst === null || inst === void 0 ? void 0 : inst.isActivityOwner)[0]; + } + get window() { + if (!this._windows) { + throw new Error("This method requires glue.windows library to be enabled."); + } + let win = this._windows.list().find((w) => w.id === this._id); + if (!win && this._activities && this.activity && this.activityOwnerInstance) { + win = this.activityOwnerInstance.window; + } + return win; + } + get context() { + var _a, _b, _c; + return (_c = (_a = this._startUpContext) !== null && _a !== void 0 ? _a : (_b = this.window) === null || _b === void 0 ? void 0 : _b.context) !== null && _c !== void 0 ? _c : {}; + } + get title() { return this._title; } + get isActivityInstance() { return this._isActivityInstance; } + get activityId() { return this._activityId; } + get inActivity() { return this._inActivity; } + get isSingleWindowApp() { return !this._inActivity; } + get agm() { + return this._agmInstance; + } + get interopInstance() { + return this._agmInstance; + } + onInteropReady(callback) { + validate(callback, this._configuration()); + if (this._agmInstance) { + setTimeout(() => { + this._registry.execute("agmReady", this); + }, 0); + } + return this._registry.add("agmReady", callback); + } + onAgmReady(callback) { + return this.onInteropReady(callback); + } + onStopped(callback) { + validate(callback, this._configuration()); + return this._registry.add("stopped", callback); + } + getWindow() { + return new Promise((resolve, reject) => { + const result = this.window; + if (result) { + resolve(result); + return; + } + const done = (error, window) => { + if (error) { + reject(error); + } + if (window) { + resolve(window); + } + setTimeout(() => { + clearTimeout(timeout); + unsub(); + }, 0); + }; + this._logger.trace(`waiting for window with id ${this._id} to appear`); + const timeoutInSeconds = 60; + const timeout = setTimeout(() => { + this._logger.trace(`window with id ${this._id} did not appear in ${timeoutInSeconds} sec`); + done(new Error(`can not find a window with id ${this._id}`)); + }, timeoutInSeconds * 1000); + const unsub = this._windows.onWindowAdded((w) => { + if (w.id === this._id) { + this._logger.trace(`window with id ${this._id} appeared`); + done(undefined, w); + } + }); + }); + } + updateFromProps(props) { + this._startUpContext = props.Context; + this._title = props.Title; + this._isActivityInstance = false; + if (props.ActivityId && props.ActivityId !== "") { + this._activityId = props.ActivityId; + this._isActivityInstance = true; + } + this._isActivityOwner = props.IsActivityOwner; + if (!this._activityId && this._startUpContext && this._startUpContext.activityId) { + this._activityId = this._startUpContext.activityId; + } + this._inActivity = Boolean(this._activityId); + this.updateAgmInstanceFromProps(props); + } + updateAgmInstanceFromProps(props) { + if (!props.AgmServers) { + return; + } + const agmInstances = props.AgmServers; + if (agmInstances && agmInstances.length > 0 && !isUndefinedOrNull(agmInstances[0])) { + this._agmInstance = agmInstances[0]; + } + } + stop() { + return new Promise((resolve, reject) => { + let idToResolve = this._id; + if (this.isActivityOwner) { + idToResolve = this.activityId; + } + const unsubscribe = this._appManager.onInstanceStopped((instance) => { + if (instance.id === idToResolve) { + this._logger.trace(`instance with id ${idToResolve} stopped`); + unsubscribe(); + resolve(); + } + }); + this._logger.trace(`stopping instance with id ${this._id}`); + this._agm.invoke(StopApplicationMethodName, { + Name: this._appName, + Id: this._id + }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }) + .then(() => { + if (this._appManager.mode === "startOnly") { + this._appManager.handleInstanceStopped({ + Name: this._appName, + Id: this.id + }); + resolve(); + } + }) + .catch((err) => reject(err)); + }); + } + activate() { + return this._agm.invoke(ActivateApplicationMethodName, { Name: this._appName, Id: this._id }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + done() { + this._registry.clear(); + this._unsubscribeInstanceAgmServerReady(); + this._unsubscribeInstanceStopped(); + } + getContext() { + return Promise.resolve(this.context); + } + async startedBy() { + const result = await this._agm.invoke(ACSExecute, { command: "getStartedBy", Name: this._appName, Id: this._id }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return result.returned; + } + } + + class AppManagerImpl { + constructor(mode, _agm, _activities, _windows, _logger, _gdMajorVersion, _configuration) { + this.mode = mode; + this._agm = _agm; + this._activities = _activities; + this._windows = _windows; + this._logger = _logger; + this._gdMajorVersion = _gdMajorVersion; + this._configuration = _configuration; + this._apps = {}; + this._instances = []; + this._registry = CallbackRegistryFactory(); + this.getConfigurations = async (apps) => { + const args = { + v2: { + apps: undefined + } + }; + if (Array.isArray(apps)) { + args.v2 = { + apps + }; + } + const result = await this._agm.invoke(GetApplicationsMethodName, args, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return result.returned.applications; + }; + this.application = (name) => { + var _a; + if (((_a = this._configuration()) === null || _a === void 0 ? void 0 : _a.throwErrors) && typeof name !== "string" || isNullOrWhiteSpace(name)) { + throw new Error(`"name" must be string`); + } + return this._apps[name]; + }; + this.applications = () => { + return Object.keys(this._apps).map((k) => this._apps[k]); + }; + this.instances = () => { + return this._instances.map((i) => i); + }; + this.getMyInstance = () => { + const glue42gd = typeof window !== "undefined" && window.glue42gd; + if (glue42gd) { + if (this._gdMajorVersion >= 3) { + const instanceId = glue42gd.appInstanceId; + return this._instances.find((i) => i.id === instanceId); + } + } + else { + const instanceId = this._agm.instance.instance; + return this._instances.find((i) => i.id === instanceId); + } + return undefined; + }; + this.getMyApplication = () => { + var _a; + if (this._agm.instance) { + return (_a = this.application(this._agm.instance.applicationName)) !== null && _a !== void 0 ? _a : this.application(this._agm.instance.application); + } + }; + this.handleSnapshotAppsAdded = (newApps) => { + const currentApps = this.applications(); + if (currentApps.length > 0) { + currentApps.forEach((item) => { + const name = item.name; + const alreadyExists = newApps.find((i) => i.Name === item.name); + if (!alreadyExists) { + this.handleAppRemoved({ Name: name }); + } + }); + } + newApps.forEach((item) => { + const alreadyExists = currentApps.find((i) => i.name === item.Name); + if (!alreadyExists) { + this.handleAppAdded(item); + } + }); + }; + this.handleSnapshotInstanceStarted = (newInstances) => { + const currentInstances = this.instances(); + if (currentInstances.length > 0) { + currentInstances.forEach((item) => { + const id = item.id; + const alreadyExists = newInstances.find((i) => i.Id === id); + if (!alreadyExists) { + this.handleInstanceStopped({ Name: item.application.name, Id: id }); + } + }); + } + newInstances.forEach((item) => { + const alreadyExists = currentInstances.find((i) => i.id === item.Id); + if (!alreadyExists) { + this.handleInstanceStarted(item); + } + }); + }; + this.handleAppAdded = (props) => { + const id = this._getAppId(props); + this._logger.trace(`adding app ${id}`); + this._apps[id] = new ApplicationImpl(this, id, this._agm, this._logger, this._configuration); + const app = this._updateAppFromProps(props); + this._registry.execute("appAdded", app); + this._registry.execute("appAvailable", app); + }; + this.handleAppUpdated = (props) => { + const app = this._updateAppFromProps(props); + this._registry.execute("appChanged", app); + }; + this.handleAppRemoved = (props) => { + const id = this._getAppId(props); + this._logger.trace(`removing app ${id}`); + const app = this.application(id); + this._instances = this._instances.filter((i) => i.application.name !== app.name); + delete this._apps[id]; + this._registry.execute("appRemoved", app); + }; + this.handleAppReady = (props) => { + const id = this._getAppId(props); + const app = this._getAppOrThrow(id); + app.updateFromProps(props); + if (app.available) { + this._registry.execute("appAvailable", app); + } + else { + this._registry.execute("appUnavailable", app); + } + }; + this.handleInstanceStarted = (props) => { + this._logger.trace(`started app ${props.Name} ${props.Id}`); + const id = this._getInstanceId(props); + const appName = this._getInstanceAppName(props); + const instance = new InstanceImpl(id, appName, this, this._agm, this._activities, this._windows, this._logger, false, this._configuration); + this._updateInstanceFromProps(instance, props); + this._instances.push(instance); + this._registry.execute("instanceStarted", instance); + return instance; + }; + this.handleInstanceStopped = (props) => { + this._logger.trace(`instance stopped ${props.Name} ${props.Id}`); + const id = this._getInstanceId(props); + const appName = this._getInstanceAppName(props); + const instance = this._getInstanceOrThrow(id, appName); + this._instances = this._instances.filter((i) => !this._matchInstance(i, id, appName)); + this._registry.execute("instanceStopped", instance); + instance.done(); + }; + this.handleInstanceAgmServerReady = (props) => { + this._logger.trace(`instance interop server ready ${props.Name} ${props.Id}`); + const id = this._getInstanceId(props); + const appName = this._getInstanceAppName(props); + const instance = this._getInstanceOrThrow(id, appName); + instance.updateAgmInstanceFromProps(props); + this._registry.execute("instanceAgmServerReady", instance); + }; + this.handleInstanceStartFailed = (props) => { + const id = this._getInstanceId(props); + const appName = this._getInstanceAppName(props); + const startFailed = true; + const instance = new InstanceImpl(id, appName, undefined, undefined, undefined, undefined, this._logger, startFailed, this._configuration); + this._updateInstanceFromProps(instance, props); + this._registry.execute("instanceStartFailed", instance); + }; + this.handleInstanceUpdated = (props) => { + const id = this._getInstanceId(props); + const app = this._getInstanceAppName(props); + const instance = this._getInstanceOrThrow(id, app); + this._updateInstanceFromProps(instance, props); + }; + this.onInstanceStarted = (callback) => { + validate(callback, this._configuration()); + return this._registry.add("instanceStarted", callback, this._instances); + }; + this.onInstanceStartFailed = (callback) => { + validate(callback, this._configuration()); + return this._registry.add("instanceStartFailed", callback); + }; + this.onInstanceStopped = (callback) => { + validate(callback, this._configuration()); + return this._registry.add("instanceStopped", callback); + }; + this.onInstanceUpdated = (callback) => { + validate(callback, this._configuration()); + return this._registry.add("instanceChanged", callback); + }; + this.onInstanceAgmServerReady = (callback) => { + validate(callback, this._configuration()); + return this._registry.add("instanceAgmServerReady", callback); + }; + this.onAppAdded = (callback) => { + validate(callback, this._configuration()); + return this._registry.add("appAdded", callback, Object.values(this._apps)); + }; + this.onAppRemoved = (callback) => { + validate(callback, this._configuration()); + return this._registry.add("appRemoved", callback); + }; + this.onAppAvailable = (callback) => { + validate(callback, this._configuration()); + return this._registry.add("appAvailable", callback); + }; + this.onAppUnavailable = (callback) => { + validate(callback, this._configuration()); + return this._registry.add("appUnavailable", callback); + }; + this.onAppChanged = (callback) => { + validate(callback, this._configuration()); + return this._registry.add("appChanged", callback); + }; + } + _getAppOrThrow(id) { + const result = this.application(id); + if (!result) { + throw Error(`app with id ${id} not found`); + } + return result; + } + _getAppId(props) { + return props.Name; + } + _matchInstance(instance, id, appName) { + return instance.id === id && instance.application.name === appName; + } + _getInstanceByIdAndName(id, appName) { + return this._instances.filter((i) => this._matchInstance(i, id, appName))[0]; + } + _getInstanceOrThrow(id, appName) { + const result = this._getInstanceByIdAndName(id, appName); + if (!result) { + throw Error(`instance with id ${id} not found`); + } + return result; + } + _getInstanceId(props) { + return props.Id; + } + _getInstanceAppName(props) { + return props.Name; + } + _updateAppFromProps(props) { + const id = this._getAppId(props); + this._logger.trace(`updating app with + ${id}, ${JSON.stringify(props)}`); + const app = this._getAppOrThrow(id); + app.updateFromProps(props); + return app; + } + _updateInstanceFromProps(instance, props) { + this._logger.trace("updating instance with " + this._getInstanceId(props) + " for app " + this._getInstanceAppName(props)); + instance.updateFromProps(props); + } + } + + function promisify(promise, successCallback, errorCallback) { + const isFunction = (arg) => { + return !!(arg && arg.constructor && arg.call && arg.apply); + }; + if (!isFunction(successCallback) && !isFunction(errorCallback)) { + return promise; + } + if (!isFunction(successCallback)) { + successCallback = () => { + }; + } + else if (!isFunction(errorCallback)) { + errorCallback = () => { + }; + } + return promise.then(successCallback, errorCallback); + } + class EntitlementsImpl { + constructor(_agm) { + this._agm = _agm; + this._registry = CallbackRegistryFactory(); + this._isMethodRegistered = false; + this.handleBranchModified = (branch) => { + this._registry.execute("branchChanged", branch); + }; + this.handleBranchesModified = (branches) => { + this._registry.execute("branchesChanged", branches); + }; + this.getRegion = (success, error) => { + return promisify(this._agmInvoke(GetConfigurationRegionMethodName, (e) => e.returned.Region), success, error); + }; + this.getBranches = (success, error) => { + const promise = this._agmInvoke(GetBranchesMethodName, (e) => { + const obj = e.returned.Branches; + return Object.keys(obj).map((key) => obj[key]); + }); + return promisify(promise, success, error); + }; + this.getCurrentBranch = (success, error) => { + const promise = this._agmInvoke(GetCurrentBranchMethodName, (e) => e.returned.Branch, undefined); + return promisify(promise, success, error); + }; + this.setRegion = (region, success, error) => { + const promise = this._agmInvoke(SetConfigurationRegionMethodName, (e) => e.returned.ResultMessage, { Region: region }); + return promisify(promise, success, error); + }; + this.setCurrentBranch = (branch, success, error) => { + const promise = this._agmInvoke(SetCurrentBranchMethodName, (e) => e.returned.ResultMessage, { Branch: branch }); + return promisify(promise, success, error); + }; + this.currentUser = (success, error) => { + const promise = this._agmInvoke(GetUserMethodName); + return promisify(promise, success, error); + }; + this.getFunctionalEntitlement = (funct, success, error) => { + const promise = this._agmInvoke(GetFunctionalEntitlementMethodName, (e) => e.returned.Entitlement, { Function: funct }); + return promisify(promise, success, error); + }; + this.getFunctionalEntitlementBranch = (funct, branch, success, error) => { + const promise = this._agmInvoke(GetFunctionalEntitlementMethodName, (e) => e.returned.Entitlement, { Function: funct, Branch: branch }); + return promisify(promise, success, error); + }; + this.canI = (func, success, error) => { + const promise = this._agmInvoke(CanIMethodName, (e) => e.returned.Result, { Function: func }); + return promisify(promise, success, error); + }; + this.canIBranch = (func, branch, success, error) => { + const promise = this._agmInvoke(CanIMethodName, (e) => e.returned.Result, { Function: func, Branch: branch }); + return promisify(promise, success, error); + }; + this.onBranchesChanged = (callback) => { + return this._registry.add("branchesChanged", callback); + }; + this.onBranchChanged = (callback) => { + return this._registry.add("branchChanged", callback); + }; + this.exit = (options) => { + return this._agmInvoke(ShutdownMethodName, null, options); + }; + this.onShuttingDown = (callback) => { + this.registerMethod(); + return this._registry.add("onShuttingDown", callback); + }; + this.restart = (options) => { + return this._agmInvoke(RestartMethodName, null, options); + }; + this._agmInvoke = (method, transformFunction, args) => { + args = args || {}; + return new Promise((resolve, reject) => { + const errHandler = (error) => reject(error); + this._agm.invoke(method, args, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }) + .then((result) => { + if (!transformFunction) { + transformFunction = (d) => d.returned; + } + resolve(transformFunction(result)); + }) + .catch(errHandler); + }); + }; + } + registerMethod() { + if (!this._isMethodRegistered) { + this._agm.register(OnGDShutdownMethodName, async (args) => { + try { + const results = await Promise.all(this._registry.execute("onShuttingDown", args)); + const prevent = results.some((r) => r.prevent); + return { prevent }; + } + catch (error) { + } + }); + this._isMethodRegistered = true; + } + } + } + + function snapshot(interop, appManager) { + return new Promise((resolve, reject) => { + interop.invoke(GetApplicationsMethodName, { skipIcon: true }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }) + .then((response) => { + var _a; + const data = response.returned; + const configuration = (_a = response.returned.configuration) !== null && _a !== void 0 ? _a : {}; + if (!data) { + resolve(configuration); + } + const applications = data.applications; + if (!applications) { + resolve(configuration); + } + objectValues(applications).map((item) => appManager.handleAppAdded(item)); + resolve(configuration); + }) + .catch((err) => reject(new Error(`Error getting application snapshot: ${err.message}`))); + }); + } + + const OnBranchChangedEvent = "OnBranchChanged"; + const OnBranchesModifiedEvent = "OnBranchesModified"; + const OnApplicationAddedEvent = "OnApplicationAdded"; + const OnApplicationRemovedEvent = "OnApplicationRemoved"; + const OnApplicationChangedEvent = "OnApplicationChanged"; + const OnApplicationReadyEvent = "OnApplicationReady"; + const OnApplicationStartedEvent = "OnApplicationStarted"; + const OnApplicationAgmServerReadyEvent = "OnApplicationAgmServerReady"; + const OnApplicationUpdatedEvent = "OnApplicationUpdated"; + const OnApplicationStoppedEvent = "OnApplicationStopped"; + const OnApplicationStartFailedEvent = "OnApplicationStartFailed"; + + function createDataSubscription(agm, applications, entitlements, skipIcons) { + let subscription; + let initiated = false; + const start = () => { + let resolveFunc; + let rejectFunc; + const resultPromise = new Promise((resolve, reject) => { + resolveFunc = resolve; + rejectFunc = reject; + }); + agm.subscribe(OnEventMethodName, { arguments: { skipIcon: skipIcons }, waitTimeoutMs: 10000 }) + .then((s) => { + subscription = s; + subscription.onData((streamData) => { + var _a; + const events = streamData.data; + const configuration = (_a = events.configuration) !== null && _a !== void 0 ? _a : {}; + const onApplicationAddedEventArgs = objectValues(events[OnApplicationAddedEvent]); + if (streamData.data.isSnapshot) { + applications.handleSnapshotAppsAdded(onApplicationAddedEventArgs); + } + else { + onApplicationAddedEventArgs.forEach((item) => applications.handleAppAdded(item)); + } + objectValues(events[OnApplicationChangedEvent]) + .forEach((item) => applications.handleAppUpdated(item)); + objectValues(events[OnApplicationRemovedEvent]) + .forEach((item) => applications.handleAppRemoved(item)); + objectValues(events[OnApplicationReadyEvent]) + .forEach((item) => applications.handleAppReady(item)); + const onApplicationStartedEventArgs = objectValues(events[OnApplicationStartedEvent]); + if (streamData.data.isSnapshot) { + applications.handleSnapshotInstanceStarted(onApplicationStartedEventArgs); + } + else { + onApplicationStartedEventArgs.forEach((item) => applications.handleInstanceStarted(item)); + } + objectValues(events[OnApplicationStartFailedEvent]) + .forEach((item) => applications.handleInstanceStartFailed(item)); + objectValues(events[OnApplicationStoppedEvent]) + .forEach((item) => applications.handleInstanceStopped(item)); + objectValues(events[OnApplicationUpdatedEvent]) + .forEach((item) => applications.handleInstanceUpdated(item)); + objectValues(events[OnApplicationAgmServerReadyEvent]) + .forEach((item) => applications.handleInstanceAgmServerReady(item)); + objectValues(events[OnBranchChangedEvent]) + .forEach((item) => entitlements.handleBranchModified(item)); + objectValues(events[OnBranchesModifiedEvent]) + .forEach((item) => entitlements.handleBranchesModified(item)); + if (!initiated) { + initiated = true; + const hasMyAppInSnapShot = onApplicationAddedEventArgs.some((a) => a.Name === agm.instance.application); + const hasMyInstanceInSnapShot = onApplicationStartedEventArgs.some((i) => i.Id === agm.instance.instance); + if (hasMyAppInSnapShot) { + if (hasMyInstanceInSnapShot) { + resolveFunc(configuration); + } + else { + const un = applications.onInstanceStarted((i) => { + if (i.id === agm.instance.instance) { + un(); + resolveFunc(configuration); + } + }); + } + } + else { + resolveFunc(configuration); + } + } + }); + subscription.onFailed((err) => rejectFunc(err)); + }) + .catch((err) => { var _a; return rejectFunc(`Error subscribing for ${OnEventMethodName} stream. Err: ${(_a = err.message) !== null && _a !== void 0 ? _a : JSON.stringify(err)}`); }); + return resultPromise; + }; + const stop = () => { + if (subscription) { + subscription.close(); + } + }; + return { + start, + stop + }; + } + + const InMemoryStoreCommandMethodName = "T42.ACS.InMemoryStoreCommand"; + class InMemoryStore { + constructor(interop) { + this.interop = interop; + } + import(apps, mode) { + if (!apps || !Array.isArray(apps)) { + return Promise.reject(new Error("invalid apps argument - should be an array of application definitions")); + } + if (mode && mode !== "replace" && mode !== "merge") { + return Promise.reject(new Error("invalid mode argument - should be 'replace' or 'merge'")); + } + mode = mode !== null && mode !== void 0 ? mode : "replace"; + const command = { + command: "import", + args: { + apps, + mode + } + }; + return this.interop.invoke(InMemoryStoreCommandMethodName, command, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }) + .then((r) => r.returned); + } + export() { + return this.interop.invoke(InMemoryStoreCommandMethodName, { command: "export" }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }) + .then((r) => r.returned.apps); + } + remove(app) { + if (!app || typeof app !== "string") { + return Promise.reject(new Error("invalid app name, should be a string value")); + } + const command = { + command: "remove", + args: { + apps: [app] + } + }; + return this.interop.invoke(InMemoryStoreCommandMethodName, command, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }).then((r) => r.returned); + } + clear() { + const command = { + command: "clear" + }; + return this.interop.invoke(InMemoryStoreCommandMethodName, command, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }).then((r) => r.returned); + } + createAppDef(name, url) { + if (!url) { + url = "https://google.com"; + } + return { + name, + type: "window", + title: name, + details: { + url + } + }; + } + } + + var AppManagerFactory = (config) => { + if (!config) { + throw Error("config not set"); + } + if (!config.agm) { + throw Error("config.agm is missing"); + } + const START_ONLY = "startOnly"; + const SKIP_ICONS = "skipIcons"; + const FULL = "full"; + const mode = config.mode || START_ONLY; + if (mode !== START_ONLY && mode !== SKIP_ICONS && mode !== FULL) { + throw new Error(`Invalid mode for appManager lib - ${mode} is not supported`); + } + const activities = config.activities; + const agm = config.agm; + const logger = config.logger; + const windows = config.windows; + let configuration = {}; + const appManager = new AppManagerImpl(mode, agm, activities, windows, logger.subLogger("applications"), config.gdMajorVersion, () => configuration); + const entitlements = new EntitlementsImpl(agm); + let readyPromise; + if (mode === START_ONLY) { + readyPromise = snapshot(agm, appManager); + } + else { + const subscription = createDataSubscription(agm, appManager, entitlements, mode === SKIP_ICONS); + readyPromise = subscription.start(); + } + const api = { + ready: () => readyPromise.then((c) => { configuration = c; }), + applications: appManager.applications, + application: appManager.application, + getConfigurations: appManager.getConfigurations, + onAppAdded: appManager.onAppAdded, + onAppRemoved: appManager.onAppRemoved, + onAppChanged: appManager.onAppChanged, + onAppAvailable: appManager.onAppAvailable, + onAppUnavailable: appManager.onAppUnavailable, + instances: appManager.instances, + get myInstance() { + return appManager.getMyInstance(); + }, + get myApplication() { + return appManager.getMyApplication(); + }, + onInstanceStarted: appManager.onInstanceStarted, + onInstanceStopped: appManager.onInstanceStopped, + onInstanceUpdated: appManager.onInstanceUpdated, + onInstanceStartFailed: appManager.onInstanceStartFailed, + getRegion: entitlements.getRegion, + getBranches: entitlements.getBranches, + getCurrentBranch: entitlements.getCurrentBranch, + getFunctionalEntitlement: entitlements.getFunctionalEntitlement, + getFunctionalEntitlementBranch: entitlements.getFunctionalEntitlementBranch, + setCurrentBranch: entitlements.setCurrentBranch, + setRegion: entitlements.setRegion, + currentUser: entitlements.currentUser, + canI: entitlements.canI, + canIBranch: entitlements.canIBranch, + onBranchesChanged: entitlements.onBranchesChanged, + exit: entitlements.exit, + restart: entitlements.restart, + onShuttingDown: entitlements.onShuttingDown, + inMemory: new InMemoryStore(agm) + }; + return api; + }; + + const T42JumpListAction = "T42.JumpList.Action"; + class JumpListManager { + constructor() { + this._groupActionCallbacks = new Map(); + this._registered = false; + } + init(executor, agm, logger) { + this._executor = executor; + this._agm = agm; + this._logger = logger; + this.registerCallbackMethod(); + } + setEnabled(windowId, enabled) { + const settings = { + enabled + }; + return this._executor.updateJumpList(windowId, settings); + } + createCategory(windowId, title, actions) { + this.validateActions(title, actions); + const settings = { + category: { + title, + operation: "create", + actions: this.toUpdateActions(windowId, "create", title, actions) + } + }; + return this._executor.updateJumpList(windowId, settings); + } + removeCategory(windowId, title) { + const settings = { + category: { + title, + operation: "remove", + actions: [] + } + }; + this.manageActionCallback(windowId, settings.category.operation, title); + return this._executor.updateJumpList(windowId, settings); + } + createActions(windowId, categoryTitle, actions) { + this.validateActions(categoryTitle, actions); + const settings = { + category: { + title: categoryTitle, + operation: "update", + actions: this.toUpdateActions(windowId, "create", categoryTitle, actions) + } + }; + return this._executor.updateJumpList(windowId, settings); + } + removeActions(windowId, categoryTitle, actions) { + const settings = { + category: { + title: categoryTitle, + operation: "update", + actions: this.toUpdateActions(windowId, "remove", categoryTitle, actions) + } + }; + return this._executor.updateJumpList(windowId, settings); + } + async getActions(windowId, catgoryTitle) { + const actions = []; + const configuration = await this.getJumpListSettings(windowId); + const currentCategory = configuration.categories.find((category) => category.title === catgoryTitle); + if (currentCategory) { + currentCategory.actions.forEach((action) => { + const actionCallback = this.getActionCallback(action.callbackId); + if (actionCallback) { + action.callback = actionCallback.callback; + } + actions.push({ + icon: action.icon, + callback: action.callback, + singleInstanceTitle: action.singleInstanceTitle, + multiInstanceTitle: action.multiInstanceTitle + }); + }); + } + return Promise.resolve(actions); + } + getJumpListSettings(windowId) { + return this._executor.getJumpList(windowId); + } + toUpdateActions(windowId, operation, categoryTitle, actions) { + return actions.map((action) => { + const updateAction = { + icon: action.icon, + callback: action.callback, + callbackId: Utils.generateId(), + singleInstanceTitle: action.singleInstanceTitle, + multiInstanceTitle: action.multiInstanceTitle, + operation + }; + this.manageActionCallback(windowId, operation, categoryTitle, updateAction); + return updateAction; + }); + } + manageActionCallback(windowId, operation, categoryTitle, updateAction) { + var _a; + const groupCallbacksKey = `${categoryTitle}-${windowId}`; + if (operation === "create") { + if (!this._groupActionCallbacks.has(groupCallbacksKey)) { + this._groupActionCallbacks.set(groupCallbacksKey, []); + } + const categoryActionCallbacks = this._groupActionCallbacks.get(groupCallbacksKey); + categoryActionCallbacks.push({ + callbackId: updateAction.callbackId, + callback: updateAction.callback + }); + } + else if (operation === "remove") { + if (updateAction) { + let categoryActionCallbacks = (_a = this._groupActionCallbacks.get(groupCallbacksKey)) !== null && _a !== void 0 ? _a : []; + categoryActionCallbacks = categoryActionCallbacks.filter((accCal) => accCal.callbackId !== updateAction.callbackId); + if (categoryActionCallbacks.length === 0) { + this._groupActionCallbacks.delete(groupCallbacksKey); + } + else { + this._groupActionCallbacks.set(groupCallbacksKey, categoryActionCallbacks); + } + } + else { + this._groupActionCallbacks.delete(groupCallbacksKey); + } + } + } + registerCallbackMethod() { + if (this._registered) { + return; + } + this._registered = true; + try { + this._agm.register(T42JumpListAction, (args, caller) => { + const actionCallback = this.getActionCallback(args.callbackId); + if (actionCallback) { + try { + actionCallback.callback(); + } + catch (e) { + this._logger.error("Unable to execute user callback for jump list action!", e); + } + } + }); + } + catch (e) { + this._logger.error(`Unable to register method ${T42JumpListAction} for invoking jump list action callbacks!`, e); + return Promise.reject(e); + } + } + getActionCallback(callbackId) { + let callbackAction; + [...this._groupActionCallbacks.values()].forEach((callbacks) => { + const callback = callbacks.find((cal) => cal.callbackId === callbackId); + if (callback) { + callbackAction = callback; + } + }); + return callbackAction; + } + validateActions(category, actions) { + if (!(actions && actions.length > 0)) { + throw new Error(`Category '${category}' doesn't contain any actions!`); + } + actions.forEach((action) => { + if (!action.singleInstanceTitle) { + throw new Error(`Category '${category}' contains an action with undefined singleInstanceTitle!`); + } + if (!action.multiInstanceTitle) { + throw new Error(`Category '${category}' contains an action with undefined multiInstanceTitle!`); + } + if (!action.callback) { + throw new Error(`Category '${category}' contains an action with undefined callback function!`); + } + }); + } + } + var jumpListManager = new JumpListManager(); + + class WindowStore { + constructor() { + this.waitForTimeoutInMilliseconds = 60000; + this._windows = {}; + this._pendingWindows = {}; + this._pendingWindowsStates = {}; + this._registry = CallbackRegistryFactory(); + } + init(logger) { + this._logger = logger; + } + get(id) { + return this._windows[id] || this._pendingWindows[id]; + } + getIfReady(id) { + return this._windows[id]; + } + get list() { + return this._windows; + } + add(window, state) { + const isExist = typeof this._pendingWindows[window.API.id] !== "undefined"; + if (isExist) { + this._logger.error(`trying to add window with id ${window.API.id} from windowStore, which already exists`); + return; + } + this._pendingWindows[window.API.id] = window; + this._pendingWindowsStates[window.API.id] = state; + this._registry.execute("on-added", window); + if (this.shouldMarkReadyToShow(state)) { + this.markReadyToShow(window.API.id); + } + } + remove(window) { + delete this._windows[window.API.id]; + delete this._pendingWindows[window.API.id]; + delete this._pendingWindowsStates[window.API.id]; + this._registry.execute("on-removed", window); + } + setUrlChangedState(windowId) { + const targetWindowState = this._pendingWindowsStates[windowId]; + if (typeof targetWindowState === "undefined") { + return; + } + targetWindowState.urlChanged = true; + if (this.shouldMarkReadyToShow(targetWindowState)) { + this.markReadyToShow(windowId); + } + } + setCompositionChangedState(wrapper) { + const windowId = wrapper.API.id; + const targetWindowState = this._pendingWindowsStates[windowId]; + if (typeof targetWindowState === "undefined") { + return; + } + targetWindowState.compositionChanged = true; + if (this.shouldMarkReadyToShow(targetWindowState)) { + this.markReadyToShow(windowId); + } + } + waitFor(id) { + return new Promise((resolve, reject) => { + let unReady; + let unRemoved; + const timeout = setTimeout(() => { + unReady(); + unRemoved(); + reject(new Error(`Window with id "${id}" was not ready within ${this.waitForTimeoutInMilliseconds} milliseconds.`)); + }, this.waitForTimeoutInMilliseconds); + const win = this._windows[id]; + if (win) { + clearTimeout(timeout); + resolve(win); + } + else { + const cleanup = () => { + clearTimeout(timeout); + unReady(); + unRemoved(); + }; + unReady = this.onReadyWindow((w) => { + if (w.API.id !== id) { + return; + } + cleanup(); + resolve(w); + }); + unRemoved = this.onRemoved((w) => { + if (w.API.id !== id) { + return; + } + cleanup(); + reject(new Error(`Window with id "${id}" was closed before it became ready.`)); + }); + } + }); + } + onReadyWindow(callback) { + return this._registry.add("on-ready", callback); + } + onAdded(callback) { + return this._registry.add("on-added", callback); + } + onRemoved(callback) { + return this._registry.add("on-removed", callback); + } + markReadyToShow(windowId) { + if (this._pendingWindows[windowId]) { + this._windows[windowId] = this._pendingWindows[windowId]; + delete this._pendingWindows[windowId]; + delete this._pendingWindowsStates[windowId]; + } + this._registry.execute("on-ready", this._windows[windowId]); + } + shouldMarkReadyToShow(targetWindowState) { + return targetWindowState && targetWindowState.urlChanged && targetWindowState.ready && targetWindowState.compositionChanged; + } + } + var windowStore = new WindowStore(); + + class JumpListActions { + constructor(windowId, configuration) { + this.windowId = windowId; + this._categoryTitle = configuration.title; + } + list() { + return jumpListManager.getActions(this.windowId, this._categoryTitle); + } + create(actions) { + return jumpListManager.createActions(this.windowId, this._categoryTitle, actions); + } + remove(actions) { + return jumpListManager.removeActions(this.windowId, this._categoryTitle, actions); + } + } + + class JumpListCategories { + constructor(windowId) { + this.windowId = windowId; + } + list() { + return this.getCategories(); + } + create(title, actions) { + return jumpListManager.createCategory(this.windowId, title, actions); + } + remove(title) { + return jumpListManager.removeCategory(this.windowId, title); + } + async find(title) { + const categories = await this.getCategories(); + return categories.find((cat) => cat.title === title); + } + async getCategories() { + const result = []; + const configuration = await jumpListManager.getJumpListSettings(this.windowId); + configuration.categories.forEach((category) => { + result.push({ + title: category.title, + actions: new JumpListActions(this.windowId, category) + }); + }); + return result; + } + } + + class JumpList { + constructor(windowId) { + this.windowId = windowId; + this._categories = new JumpListCategories(windowId); + } + get categories() { + return this._categories; + } + async isEnabled() { + const configuration = await jumpListManager.getJumpListSettings(this.windowId); + return configuration.enabled; + } + setEnabled(enabled) { + return jumpListManager.setEnabled(this.windowId, enabled); + } + } + + var windowFactory = (id, options, executor, logger, appManagerGetter, displayAPIGetter, channelsAPIGetter, agm) => { + var _a, _b, _c, _d; + const _registry = CallbackRegistryFactory(); + const getChannels = () => { + const channels = channelsAPIGetter(); + if (!channels) { + throw new Error(`To use this method you need to enable channels API - set the channels property to true when initializing the Glue42 library`); + } + return channels; + }; + const _id = id; + const _name = options.name; + const _mode = options.mode; + let _bounds = options.bounds; + let _url = options.url; + let _title = options.title; + let _context = (_a = options.context) !== null && _a !== void 0 ? _a : {}; + let _frameColor = options.frameColor; + let _focus = options.focus; + let _neighbours = (_b = options.neighbours) !== null && _b !== void 0 ? _b : {}; + let _groupId = options.groupId; + let _isGroupHeaderVisible = options.isGroupHeaderVisible; + let _isTabHeaderVisible = options.isTabHeaderVisible; + let _isGroupHibernated = options.isGroupHibernated; + let _isGroupVisible = options.isGroupVisible; + let _isTabSelected = (_c = options.isTabSelected) !== null && _c !== void 0 ? _c : false; + let _settings = options.settings; + const _applicationName = options.applicationName; + let _isVisible = options.isVisible; + let _isSticky = options.isSticky; + let _isCollapsed = options.isCollapsed; + let _windowState = options.state; + let _tabGroupId = options.tabGroupId; + let _tabIndex = options.tabIndex; + let _frameId = options.frameId; + let _isLocked = options.isLocked; + let _allowWorkspaceDrop = options.allowWorkspaceDrop; + let _isPinned = options.isPinned; + let _group; + let _frameButtons = (_d = options.frameButtons) !== null && _d !== void 0 ? _d : []; + let _zoomFactor = options.zoomFactor; + let _placementSettings = options.placementSettings; + const _jumpList = new JumpList(id); + function close(cbOrOptions, error) { + if (typeof cbOrOptions === "undefined" || typeof cbOrOptions === "function") { + return Utils.callbackifyPromise(() => { + if (!id) { + throw new Error("The window is already closed."); + } + return executor.close(resultWindow); + }, cbOrOptions, error); + } + else { + return executor.close(resultWindow, cbOrOptions); + } + } + function navigate(newUrl, optionsOrCallback, error) { + if (typeof optionsOrCallback === "function") { + return Utils.callbackifyPromise(() => { + if (isNullOrWhiteSpace(newUrl)) { + throw new Error("The new URL must be a non-empty string."); + } + return executor.navigate(resultWindow, newUrl); + }, optionsOrCallback, error); + } + if (isNullOrWhiteSpace(newUrl)) { + throw new Error("The new URL must be a non-empty string."); + } + if ((optionsOrCallback === null || optionsOrCallback === void 0 ? void 0 : optionsOrCallback.timeout) && typeof optionsOrCallback.timeout !== "number") { + throw new Error("Timeout argument must be a valid number"); + } + return executor.navigate(resultWindow, newUrl, optionsOrCallback); + } + function setStyle(style, success, error) { + return Utils.callbackifyPromise(() => { + if (!style || Object.keys(style).length === 0 || Object.keys(style).every((key) => !key)) { + throw new Error("Invalid style arguments: " + JSON.stringify(style)); + } + if (style && style.focus !== undefined) { + if (typeof style.focus !== "boolean") { + throw new Error("Focus must be a boolean value. Currently, only `focus: true` is supported."); + } + else if (style.focus === false) { + console.warn("`focus: false` is not supported!"); + } + } + if (style && style.hidden !== undefined && typeof style.hidden !== "boolean") { + throw new Error("The `hidden` property must hold a boolean value."); + } + for (const prop of ["minHeight", "maxHeight", "minWidth", "maxWidth"]) { + const styleAsAny = style; + const value = styleAsAny[prop]; + if (prop in style) { + if (isUndefinedOrNull(value)) { + delete styleAsAny[prop]; + continue; + } + if (!isNumber(styleAsAny[prop])) { + throw new Error(`"${prop}" must be a number`); + } + } + } + return executor.setStyle(resultWindow, style); + }, success, error); + } + function resetButtons(buttons, success, error) { + return Utils.callbackifyPromise(() => executor.resetButtons(resultWindow, buttons), success, error); + } + function getButtons() { + return executor.getButtons(resultWindow); + } + function setOnTop(onTop, success, error) { + return Utils.callbackifyPromise(() => { + if (typeof onTop === "string") { + if (onTop !== "always") { + throw new Error("`onTop` must hold a `always` value."); + } + } + else if (typeof onTop !== "boolean") { + throw new Error("`onTop` must hold a boolean or `always` value."); + } + return executor.setOnTop(resultWindow, onTop); + }, success, error); + } + function setSizeConstraints(constraints, success, error) { + return Utils.callbackifyPromise(() => { + if (!constraints || Object.keys(constraints).every((value) => value === undefined)) { + throw new Error("The properties of `constraints` cannot be null or undefined."); + } + return executor.setSizeConstraints(resultWindow, constraints); + }, success, error); + } + function getSizeConstraints() { + return executor.getSizeConstraints(resultWindow); + } + function setTitle(newTitle, success, error) { + return Utils.callbackifyPromise(() => { + if (isUndefinedOrNull(newTitle)) { + throw new Error("`newTitle` must not be null or undefined."); + } + if (newTitle === _title) { + return Promise.resolve(resultWindow); + } + return executor.setTitle(resultWindow, newTitle); + }, success, error); + } + function setSticky(isSticky, success, error) { + return Utils.callbackifyPromise(() => { + if (typeof isSticky !== "boolean") { + throw new Error("`isSticky` must hold a boolean value."); + } + return executor.setSticky(resultWindow, isSticky); + }, success, error); + } + function setAllowWorkspaceDrop(allowWorkspaceDrop) { + if (typeof allowWorkspaceDrop !== "boolean") { + throw new Error("`allowWorkspaceDrop` must hold a boolean value."); + } + return executor.setAllowWorkspaceDrop(resultWindow, allowWorkspaceDrop); + } + function pin() { + return executor.pin(resultWindow); + } + function unpin() { + return executor.unpin(resultWindow); + } + function moveResize(bounds, success, error) { + return Utils.callbackifyPromise(() => { + if (isUndefinedOrNull(bounds)) { + throw new Error("The properties of `bounds` cannot be null or undefined."); + } + return executor.moveResize(resultWindow, bounds); + }, success, error); + } + function addFrameButton(buttonInfo, success, error) { + return Utils.callbackifyPromise(() => { + if (typeof buttonInfo === "undefined" || Object.keys(buttonInfo).length === 0) { + throw new Error("Button info is not available."); + } + if (isNullOrWhiteSpace(buttonInfo.buttonId)) { + throw new Error("`buttonId` must not be null or undefined."); + } + if (isNullOrWhiteSpace(buttonInfo.imageBase64)) { + throw new Error("`imageBase64` must not be null or undefined."); + } + return executor.addFrameButton(resultWindow, buttonInfo); + }, success, error); + } + function removeFrameButton(buttonId, success, error) { + return Utils.callbackifyPromise(() => { + if (isNullOrWhiteSpace(buttonId)) { + throw new Error("`buttonId` must not be null or undefined."); + } + return executor.removeFrameButton(resultWindow, buttonId); + }, success, error); + } + function activate(success, error) { + return Utils.callbackifyPromise(() => { + if (_focus) { + return Promise.resolve(resultWindow); + } + return executor.activate(resultWindow); + }, success, error); + } + function focus(success, error) { + return Utils.callbackifyPromise(() => { + if (_focus) { + return Promise.resolve(resultWindow); + } + return executor.focus(resultWindow); + }, success, error); + } + function maximizeRestore(success, error) { + return Utils.callbackifyPromise(() => { + return executor.maximizeRestore(resultWindow); + }, success, error); + } + function maximize(success, error) { + return Utils.callbackifyPromise(() => { + if (_windowState === "maximized") { + return Promise.resolve(resultWindow); + } + return executor.maximize(resultWindow); + }, success, error); + } + function restore(success, error) { + return Utils.callbackifyPromise(() => { + if (_windowState === "normal") { + return Promise.resolve(resultWindow); + } + return executor.restore(resultWindow); + }, success, error); + } + function minimize(success, error) { + return Utils.callbackifyPromise(() => { + if (_windowState === "minimized") { + return Promise.resolve(resultWindow); + } + return executor.minimize(resultWindow); + }, success, error); + } + function collapse(success, error) { + return Utils.callbackifyPromise(() => { + if (_isCollapsed) { + return Promise.resolve(resultWindow); + } + return executor.collapse(resultWindow); + }, success, error); + } + function expand(success, error) { + return Utils.callbackifyPromise(() => { + if (!_isCollapsed) { + return Promise.resolve(resultWindow); + } + return executor.expand(resultWindow); + }, success, error); + } + function toggleCollapse(success, error) { + return Utils.callbackifyPromise(() => { + return executor.toggleCollapse(resultWindow); + }, success, error); + } + function snap(target, direction, success, error) { + return Utils.callbackifyPromise(() => { + if (isUndefinedOrNull(target)) { + throw new Error(`A target window is not specified - ${typeof target === "string" ? target : JSON.stringify(target)}`); + } + if (typeof target === "string") { + const win = windowStore.get(target); + if (!win) { + throw new Error(`Invalid "target" parameter or no such window. Invoked with: ${target}`); + } + target = win.API; + } + if (typeof direction === "string") { + direction = { + direction, + autoAlign: true + }; + } + return executor.snap(resultWindow, target, direction); + }, success, error); + } + function attachTab(tab, opt, success, error) { + return Utils.callbackifyPromise(() => { + var _a; + const errorMessage = `Invalid "tab" parameter - must be an object with an "id" property or a string. Invoked for source window with ID:`; + if (isUndefinedOrNull(tab)) { + const errMsg = `${errorMessage} ${typeof tab === "string" ? tab : JSON.stringify(tab)}`; + throw new Error(errMsg); + } + let sourceWindow; + if (typeof tab === "string") { + sourceWindow = (_a = windowStore.get(tab)) === null || _a === void 0 ? void 0 : _a.API; + if (isUndefinedOrNull(sourceWindow)) { + const errMsg = `${errorMessage} ${typeof sourceWindow === "string" ? sourceWindow : JSON.stringify(sourceWindow)}`; + throw new Error(errMsg); + } + } + else if (!isUndefinedOrNull(tab.id)) { + sourceWindow = tab; + } + else { + throw new Error(errorMessage); + } + const attachOptions = {}; + if (!isUndefinedOrNull(opt)) { + if (typeof opt === "number") { + attachOptions.index = opt; + } + else { + attachOptions.selected = opt.selected; + attachOptions.index = opt.index; + } + } + return executor.attachTab(resultWindow, sourceWindow, attachOptions); + }, success, error); + } + function detachTab(opt = {}, success, error) { + return Utils.callbackifyPromise(() => { + const argsForSend = {}; + function isDetachRelative(o) { + return o.relativeTo !== undefined; + } + if (isDetachRelative(opt)) { + if (typeof opt.relativeTo === "string") { + argsForSend.relativeTo = opt.relativeTo; + } + else if (!isUndefinedOrNull(opt.relativeTo.id)) { + argsForSend.relativeTo = opt.relativeTo.id; + } + if (!isUndefinedOrNull(opt.relativeDirection)) { + argsForSend.relativeDirection = opt.relativeDirection; + } + if (!isUndefinedOrNull(opt.width)) { + argsForSend.width = opt.width; + } + if (!isUndefinedOrNull(opt.height)) { + argsForSend.height = opt.height; + } + } + else { + if (!isUndefinedOrNull(opt.bounds)) { + argsForSend.bounds = opt.bounds; + } + } + if (!isUndefinedOrNull(opt.hideTabHeader)) { + argsForSend.hideTabHeader = opt.hideTabHeader; + } + return executor.detachTab(resultWindow, argsForSend); + }, success, error); + } + function setVisible(toBeVisible, success, error) { + return Utils.callbackifyPromise(() => { + return executor.setVisible(resultWindow, toBeVisible); + }, success, error); + } + async function center(display) { + if (display) { + validateCenterArguments(display); + } + return executor.center(resultWindow, display); + } + function validateCenterArguments(display) { + if (typeof display !== "object") { + throw Error("display argument must be a valid display object"); + } + if (!display.workArea || !display.scaleFactor) { + throw Error("display argument is not a valid display object"); + } + } + function showLoader(loader) { + return executor.showLoader(resultWindow, loader); + } + function hideLoader() { + return executor.hideLoader(resultWindow); + } + function updateContext(context, success, error) { + return Utils.callbackifyPromise(() => { + if (!isObject(context)) { + throw new Error(`"context" must not be null or undefined.`); + } + return executor.updateContext(resultWindow, context, false); + }, success, error); + } + function lock(success, error) { + return Utils.callbackifyPromise(() => { + return executor.lock(resultWindow); + }, success, error); + } + function unlock(success, error) { + return Utils.callbackifyPromise(() => { + return executor.unlock(resultWindow); + }, success, error); + } + function getIcon(success, error) { + return Utils.callbackifyPromise(() => { + return executor.getIcon(resultWindow); + }, success, error); + } + function setIcon(base64Image, success, error) { + return Utils.callbackifyPromise(() => { + if (isNullOrWhiteSpace(base64Image)) { + throw new Error(`"base64Image" must be a non-empty string.`); + } + return executor.setIcon(resultWindow, base64Image); + }, success, error); + } + function setFrameColor(frameColor, success, error) { + return Utils.callbackifyPromise(() => { + if (isNullOrWhiteSpace(frameColor)) { + throw new Error(`"frameColor" must be a non-empty string`); + } + return executor.setFrameColor(resultWindow, frameColor); + }, success, error); + } + function setTabHeaderVisible(toBeTabHeaderVisible, success, error) { + return Utils.callbackifyPromise(() => { + if (typeof toBeTabHeaderVisible !== "boolean") { + throw new Error(`"toBeTabHeaderVisible" must hold a boolean value.`); + } + return executor.setTabHeaderVisible(resultWindow, toBeTabHeaderVisible); + }, success, error); + } + async function setTabTooltip(tooltip) { + if (isNullOrWhiteSpace(tooltip)) { + throw new Error(`"${tooltip}" must not be null or undefined`); + } + return executor.setTabTooltip(resultWindow, tooltip); + } + async function getTabTooltip() { + return executor.getTabTooltip(resultWindow); + } + function showPopup(config) { + return executor.showPopup(resultWindow, config); + } + function createFlydown(config) { + return executor.createFlydown(resultWindow.id, config); + } + function setModalState(isModal) { + return executor.setModalState(resultWindow.id, isModal || false); + } + function zoomIn(success, error) { + return Utils.callbackifyPromise(() => { + return executor.zoomIn(resultWindow); + }, success, error); + } + function zoomOut(success, error) { + return Utils.callbackifyPromise(() => { + return executor.zoomOut(resultWindow); + }, success, error); + } + function setZoomFactor(zoomFactor, success, error) { + return Utils.callbackifyPromise(() => { + if (isNaN(zoomFactor)) { + throw new Error(`zoomFactor is not a number`); + } + return executor.setZoomFactor(resultWindow, zoomFactor); + }, success, error); + } + function showDevTools() { + return executor.showDevTools(resultWindow); + } + function capture(captureOptions) { + return executor.capture(resultWindow, captureOptions); + } + function flash(suppliedOptions, mode) { + const flashOptions = { + shouldFlash: true, + mode: "auto" + }; + if (typeof suppliedOptions === "boolean") { + flashOptions.shouldFlash = suppliedOptions; + } + if (typeof mode !== "undefined") { + flashOptions.mode = mode; + } + return executor.flash(resultWindow, flashOptions); + } + function flashTab(suppliedOptions) { + const flashOptions = { + shouldFlash: true, + }; + if (typeof suppliedOptions === "boolean") { + flashOptions.shouldFlash = suppliedOptions; + } + return executor.flashTab(resultWindow, flashOptions); + } + function print(printOptions) { + return executor.print(resultWindow, printOptions); + } + function printToPDF(printToPDFOptions) { + return executor.printToPDF(resultWindow, printToPDFOptions); + } + function ungroup(ungroupOptions) { + return new Promise((resolve, reject) => { + const unGroupChanged = onGroupChanged((win, newGroup, oldGroup) => { + if (id === win.id) { + unGroupChanged(); + resolve(resultWindow); + } + }); + executor.ungroup(resultWindow, ungroupOptions) + .catch((e) => { + unGroupChanged(); + reject(e); + }); + }); + } + function place(placementSettings) { + return executor.place(resultWindow, placementSettings); + } + function refresh(ignoreCache) { + return executor.refresh(resultWindow, ignoreCache); + } + function download(url, opts) { + return executor.download(resultWindow, url, opts); + } + function configure(settings) { + return executor.configureWindow(resultWindow, settings); + } + function getConfiguration() { + return executor.getWindowConfiguration(resultWindow); + } + function getDockingPlacement() { + return executor.getDockingPlacement(resultWindow); + } + function dock(opts) { + return executor.dock(resultWindow, opts); + } + async function clone(cloneOptions) { + return executor.clone(resultWindow, cloneOptions); + } + async function executeCode(code) { + if (!code) { + throw new Error("Code argument is missing"); + } + if (typeof code !== "string") { + throw new Error("Code argument must be a valid string"); + } + const response = await executor.executeCode(resultWindow, code); + return response.result; + } + function onTitleChanged(callback) { + if (!isFunction(callback)) { + throw new Error("callback should be a function"); + } + callback(resultWindow.title, resultWindow); + return onEventCore("onTitleChanged", callback); + } + function onClose(callback) { + if (!isFunction(callback)) { + throw new Error("callback should be a function"); + } + if (id === undefined) { + callback(resultWindow); + } + return _registry.add("onClose", callback); + } + function onUrlChanged(callback) { + return onEventCore("onUrlChanged", callback); + } + function onFrameButtonAdded(callback) { + return onEventCore("onFrameButtonAdded", callback); + } + function onFrameButtonRemoved(callback) { + return onEventCore("onFrameButtonRemoved", callback); + } + function onFrameButtonClicked(callback) { + return onEventCore("onFrameButtonClicked", callback); + } + function onCollapsed(callback) { + if (!isFunction(callback)) { + throw new Error("callback should be a function"); + } + if (_isCollapsed) { + callback(resultWindow); + } + return _registry.add("collapsed", callback); + } + function onExpanded(callback) { + if (!isFunction(callback)) { + throw new Error("callback should be a function"); + } + if (!_isCollapsed) { + callback(resultWindow); + } + return _registry.add("expanded", callback); + } + function onMaximized(callback) { + if (_windowState === "maximized") { + return onEventCore("maximized", callback, [resultWindow]); + } + else { + return onEventCore("maximized", callback); + } + } + function onMinimized(callback) { + if (_windowState === "minimized") { + return onEventCore("minimized", callback, [resultWindow]); + } + else { + return onEventCore("minimized", callback); + } + } + function onNormal(callback) { + if (_windowState === "normal") { + return onEventCore("normal", callback, [resultWindow]); + } + else { + return onEventCore("normal", callback); + } + } + function onAttached(callback) { + return onEventCore("attached", callback); + } + function onDetached(callback) { + return onEventCore("detached", callback); + } + function onVisibilityChanged(callback) { + return onEventCore("visibility-changed", callback); + } + function onContextUpdated(callback) { + return onEventCore("context-updated", callback); + } + function onLockingChanged(callback) { + return onEventCore("lock-changed", callback); + } + function onBoundsChanged(callback) { + return onEventCore("bounds-changed", callback); + } + function onFocusChanged(callback) { + return onEventCore("focus-changed", callback); + } + function onStickyChanged(callback) { + return onEventCore("sticky-changed", callback); + } + function onFrameColorChanged(callback) { + return onEventCore("frame-color-changed", callback); + } + function onTabHeaderVisibilityChanged(callback) { + return onEventCore("tab-header-visibility-changed", callback); + } + function onWindowAttached(callback) { + return onEventCore("window-attached", callback); + } + function onWindowDetached(callback) { + return onEventCore("window-detached", callback); + } + function onGroupChanged(callback) { + return onEventCore("group-changed", callback); + } + function onTabSelectionChanged(callback) { + return onEventCore("tab-selection-changed", callback); + } + function onChannelRestrictionsChanged(callback) { + if (!isFunction(callback)) { + throw new Error("callback must be a function"); + } + return onEventCore("channel-restrictions-changed", callback); + } + function onClosing(callback) { + if (!isFunction(callback)) { + throw new Error("callback must be a function"); + } + const callbackWrap = (success, error, prevent) => { + const promise = callback(prevent); + if (promise === null || promise === void 0 ? void 0 : promise.then) { + promise.then(success).catch(error); + } + else { + success(); + } + }; + return executor.onClosing(callbackWrap, resultWindow); + } + function onRefreshing(callback) { + if (!isFunction(callback)) { + throw new Error("callback must be a function"); + } + const callbackWrap = (success, error, prevent) => { + const promise = callback(prevent); + if (promise === null || promise === void 0 ? void 0 : promise.then) { + promise.then(success).catch(error); + } + else { + success(); + } + }; + return executor.onRefreshing(callbackWrap, resultWindow); + } + function onNavigating(callback) { + if (!isFunction(callback)) { + throw new Error("callback must be a function"); + } + const callbackWrap = (success, error, prevent, args) => { + const promise = callback(args); + if (promise === null || promise === void 0 ? void 0 : promise.then) { + promise.then(success).catch(error); + } + else { + success(); + } + }; + return executor.onNavigating(callbackWrap, resultWindow); + } + function onZoomFactorChanged(callback) { + return onEventCore("zoom-factor-changed", callback); + } + function onPlacementSettingsChanged(callback) { + return onEventCore("placementSettingsChanged", callback); + } + function onNeighboursChanged(callback) { + return onEventCore("neighbours-changed", callback); + } + function onDockingChanged(callback) { + return onEventCore("docking-changed", callback); + } + function onEventCore(key, callback, replayArguments) { + if (!isFunction(callback)) { + throw new Error("callback must be a function"); + } + return _registry.add(key, callback, replayArguments); + } + function goBack() { + return executor.goBack(resultWindow); + } + function goForward() { + return executor.goForward(resultWindow); + } + function startDrag(option) { + return executor.startDrag(resultWindow, option); + } + function showDialog(dialogOptions) { + if ((dialogOptions === null || dialogOptions === void 0 ? void 0 : dialogOptions.timerDuration) && isNaN(dialogOptions === null || dialogOptions === void 0 ? void 0 : dialogOptions.timerDuration)) { + throw new Error("timerDuration must be a number"); + } + if ((dialogOptions === null || dialogOptions === void 0 ? void 0 : dialogOptions.showTimer) && typeof (dialogOptions === null || dialogOptions === void 0 ? void 0 : dialogOptions.showTimer) !== "boolean") { + throw new Error("showTimer must be a boolean"); + } + return executor.showDialog(resultWindow, dialogOptions); + } + function handleUpdate(updated) { + _url = updated.url; + _title = updated.title; + _context = updated.context || {}; + _bounds = updated.bounds; + _frameColor = updated.frameColor; + _focus = updated.focus; + _neighbours = updated.neighbours || {}; + _groupId = updated.groupId; + _isGroupHeaderVisible = updated.isGroupHeaderVisible; + _isTabHeaderVisible = updated.isTabHeaderVisible; + _isGroupHibernated = updated.isGroupHibernated; + _isGroupVisible = updated.isGroupVisible; + _isTabSelected = updated.isTabSelected; + _settings = updated.settings; + _isVisible = updated.isVisible; + _isSticky = updated.isSticky; + _isCollapsed = updated.isCollapsed; + _windowState = updated.state; + _tabGroupId = updated.tabGroupId; + _frameId = updated.frameId; + _isLocked = updated.isLocked; + _allowWorkspaceDrop = updated.allowWorkspaceDrop; + _isPinned = updated.isPinned; + _zoomFactor = updated.zoomFactor; + _placementSettings = updated.placementSettings; + } + function handleTitleChanged(newTitle) { + _title = newTitle; + executor.finished + .finally(() => { + _registry.execute("onTitleChanged", newTitle, resultWindow); + }); + } + function handleUrlChanged(newUrl) { + _url = newUrl; + _registry.execute("onUrlChanged", newUrl, resultWindow); + } + function handleVisibilityChanged(isVisible) { + if (isVisible === _isVisible) { + return; + } + _isVisible = isVisible; + _registry.execute("visibility-changed", resultWindow); + } + function handleWindowSettingsChanged(settings) { + _settings = settings; + _registry.execute("settings-changed", resultWindow); + } + function handleContextUpdated(context) { + _context = context; + _registry.execute("context-updated", _context, resultWindow); + } + function handleWindowClose() { + if (id === undefined) { + return; + } + _registry.execute("onClose", resultWindow); + id = undefined; + } + function handleFrameButtonAdded(frameButton) { + const buttonObj = ["buttonId", "imageBase64", "order", "tooltip"].reduce((memo, k) => { + memo[k] = frameButton[k]; + return memo; + }, {}); + const frameButtonsIds = _frameButtons.map((btn) => { + return btn.buttonId; + }); + if (frameButtonsIds.indexOf(frameButton.buttonId) === -1) { + _frameButtons.push(buttonObj); + } + _registry.execute("onFrameButtonAdded", buttonObj, resultWindow); + } + function handleFrameButtonRemoved(frameButtonId) { + let button; + _frameButtons = _frameButtons.reduce((memo, btn) => { + if (btn.buttonId === frameButtonId) { + button = btn; + } + else { + memo.push(btn); + } + return memo; + }, []); + if (button !== undefined) { + _registry.execute("onFrameButtonRemoved", button, resultWindow); + } + } + function handleFrameButtonClicked(frameButton) { + const button = _frameButtons.filter((btn) => { + return btn.buttonId === frameButton.buttonId; + }); + if (button.length > 0) { + _registry.execute("onFrameButtonClicked", button[0], resultWindow); + } + } + async function handleWindowChangeState(state) { + if (state === "collapsed") { + _isCollapsed = true; + } + else if (state === "expanded") { + _isCollapsed = false; + } + else { + _windowState = state; + } + await executor.finished; + _registry.execute(state, resultWindow); + } + function handleFrameIsLockedChanged(isLocked) { + _isLocked = isLocked; + _registry.execute("lock-changed", resultWindow); + } + function handleBoundsChanged(bounds) { + if (_bounds.top === bounds.top && _bounds.left === bounds.left && _bounds.width === bounds.width && _bounds.height === bounds.height) { + return; + } + _bounds = bounds; + _registry.execute("bounds-changed", resultWindow); + } + function handleFocusChanged(isFocused) { + _focus = isFocused; + _registry.execute("focus-changed", resultWindow); + } + function handleIsStickyChanged(isSticky) { + _isSticky = isSticky; + _registry.execute("sticky-changed", isSticky, resultWindow); + } + function handleFrameColorChanged(frameColor) { + _frameColor = frameColor; + _registry.execute("frame-color-changed", resultWindow); + } + function handleFrameAttached(tabGroupId, frameId, isTabHeaderVisible) { + _tabGroupId = tabGroupId; + _frameId = frameId; + _isTabHeaderVisible = isTabHeaderVisible; + _registry.execute("frame-attached", resultWindow); + } + function handleCompositionChanged(state) { + _neighbours = state.neighbors || {}; + _tabIndex = state.index; + _registry.execute("neighbours-changed", _neighbours, resultWindow); + } + function handleAllowWorkspaceDropChanged(allowWorkspaceDrop) { + _allowWorkspaceDrop = allowWorkspaceDrop; + _registry.execute("allow-workspace-drop-changed", resultWindow); + } + function handleIsPinnedChanged(isPinned) { + _isPinned = isPinned; + _registry.execute("is-pinned-changed", resultWindow); + } + function handleGroupHeaderVisibilityChanged(isGroupHeaderVisible) { + _isGroupHeaderVisible = isGroupHeaderVisible; + } + function handleTabHeaderVisibilityChanged(isTabHeaderVisible) { + if (_isTabHeaderVisible !== isTabHeaderVisible) { + _isTabHeaderVisible = isTabHeaderVisible; + _registry.execute("tab-header-visibility-changed", resultWindow); + } + } + async function handleFrameSelectionChanged(newWindow, prevWindow) { + let selectedWindow; + if (newWindow === id) { + _isTabSelected = true; + selectedWindow = resultWindow; + } + else { + _isTabSelected = false; + selectedWindow = windowStore.get(newWindow) ? windowStore.get(newWindow).API : undefined; + } + const previousWindow = windowStore.get(prevWindow) ? windowStore.get(prevWindow).API : undefined; + await executor.finished; + _registry.execute("tab-selection-changed", selectedWindow, previousWindow, resultWindow); + } + async function handleAttached(newTabGroupId, newFrameId, tabHeaderVisible, isLocked, winsToBeNotified) { + _tabGroupId = newTabGroupId; + _isTabHeaderVisible = tabHeaderVisible; + _frameId = newFrameId; + if (typeof isLocked !== "undefined") { + _isLocked = isLocked; + } + await executor.finished; + winsToBeNotified.forEach((w) => { + w.Events.handleWindowAttached(resultWindow); + }); + _registry.execute("attached", resultWindow); + } + function handleWindowAttached(win) { + _registry.execute("window-attached", win); + } + async function handleDetached(isLocked, winsToBeNotified) { + _tabGroupId = undefined; + _isTabSelected = false; + if (typeof isLocked !== "undefined") { + _isLocked = isLocked; + } + await executor.finished; + winsToBeNotified.forEach((w) => { + w.Events.handleWindowDetached(resultWindow); + }); + _registry.execute("detached", resultWindow); + } + function handleWindowDetached(win) { + _registry.execute("window-detached", win); + } + function handleZoomFactorChanged(zoomFactor) { + _zoomFactor = zoomFactor; + _registry.execute("zoom-factor-changed", resultWindow); + } + function handlePlacementSettingsChanged(placementSettings) { + let promise; + const copy = placementSettings; + if (!copy.display) { + promise = Promise.resolve(undefined); + } + else { + const displayAPI = displayAPIGetter(); + if (!displayAPI) { + promise = Promise.resolve(undefined); + } + else { + const index = copy.display - 1; + promise = new Promise((resolve, reject) => { + displayAPI.all().then((displays) => { + const display = displays.find((d) => d.index === index); + resolve(display); + }).catch(reject); + }); + } + } + void promise.then((d) => { + copy.display = d; + _placementSettings = copy; + _registry.execute("placementSettingsChanged", resultWindow); + }); + } + function handleDockingChanged(data) { + _registry.execute("docking-changed", resultWindow, { + docked: data.docked, + position: data.position, + claimScreenArea: data.claimScreenArea + }); + } + function handleChannelRestrictionsChanged(data) { + _registry.execute("channel-restrictions-changed", data); + } + function handleGroupChanged(newGroup, oldGroup) { + _group = newGroup; + _groupId = newGroup === null || newGroup === void 0 ? void 0 : newGroup.id; + if (!isUndefinedOrNull(newGroup) && !isUndefinedOrNull(oldGroup)) { + _registry.execute("group-changed", resultWindow, newGroup, oldGroup); + } + } + function getAllTabs() { + const allWindows = windowStore.list; + if (_mode.toLowerCase() !== "tab") { + return []; + } + const tabs = Object.keys(allWindows).reduce((memo, win) => { + const window = allWindows[win]; + if (window + && window.API.tabGroupId + && typeof window.API.tabGroupId !== "undefined" + && typeof resultWindow.tabGroupId !== "undefined" + && window.API.tabGroupId === resultWindow.tabGroupId) { + memo.push(window.API); + } + return memo; + }, []); + return tabs.sort((w1, w2) => { + if (w1.tabIndex !== w2.tabIndex) { + if (w1.tabIndex === -1) { + return Number.MAX_SAFE_INTEGER; + } + if (w2.tabIndex === -1) { + return Number.MIN_SAFE_INTEGER; + } + } + return w1.tabIndex - w2.tabIndex; + }); + } + function mapWindowIdsToWindowObjects(windowIdArr) { + return windowIdArr.reduce((memo, winId) => { + const window = windowStore.get(winId); + if (window) { + memo.push(window.API); + } + return memo; + }, []); + } + function getNeighboursByDirection(direction) { + const windowIds = _neighbours[direction]; + if (typeof windowIds !== "undefined") { + return mapWindowIdsToWindowObjects(windowIds); + } + } + function getApplicationName() { + var _a; + if (_applicationName) { + return _applicationName; + } + if (_context._APPLICATION_NAME) { + return _context._APPLICATION_NAME; + } + if (_context && _context._t42 && _context._t42.application) { + return _context._t42.application; + } + const info = getWindowInfo(); + if (info && info.applicationName) { + return info.applicationName; + } + const appManager = appManagerGetter(); + if (appManager) { + const instance = appManager.instances().find((i) => id === i.id); + if (instance) { + return (_a = instance.application) === null || _a === void 0 ? void 0 : _a.name; + } + } + return undefined; + } + function getWindowInfo() { + if (typeof window !== "undefined" && window.glue42gd && window.glue42gd.getWindowInfo) { + const info = window.glue42gd.getWindowInfo(id); + if (!info) { + return undefined; + } + else { + return info; + } + } + } + const resultWindow = { + get id() { + return _id; + }, + get name() { + return _name; + }, + get application() { + const appManager = appManagerGetter(); + const appName = getApplicationName(); + if (appName && appManager) { + return appManager.application(appName); + } + }, + get hostInstance() { + return executor.hostInstance; + }, + get interopInstance() { + const instance = agm.servers().find((s) => s.windowId === this.id); + if (instance) { + return instance; + } + else { + const appName = getApplicationName(); + if (appName) { + return { application: appName }; + } + } + }, + get agmInstance() { + return resultWindow.interopInstance; + }, + get url() { + return _url; + }, + get title() { + return _title; + }, + get windowStyleAttributes() { + return _settings; + }, + get settings() { + return _settings; + }, + get tabGroupId() { + return _mode.toLowerCase() === "tab" ? _tabGroupId : undefined; + }, + get tabIndex() { + return _mode.toLowerCase() === "tab" ? _tabIndex : undefined; + }, + get frameId() { + return _frameId; + }, + get frameButtons() { + return _frameButtons.sort((b1, b2) => b1.order - b2.order); + }, + get mode() { + return _mode; + }, + get state() { + return _windowState; + }, + get isCollapsed() { + return _isCollapsed; + }, + get isVisible() { + return _isVisible; + }, + get isLocked() { + return _isLocked; + }, + get context() { + return _context; + }, + get bounds() { + return _bounds; + }, + get minHeight() { + return _settings.minHeight; + }, + get maxHeight() { + return _settings.maxHeight; + }, + get minWidth() { + return _settings.minWidth; + }, + get maxWidth() { + return _settings.maxWidth; + }, + get isFocused() { + return _focus; + }, + get frameColor() { + return _frameColor; + }, + get opened() { + return resultWindow.id !== undefined; + }, + get group() { + return _group; + }, + get groupId() { + return _groupId; + }, + get isSticky() { + return _isSticky; + }, + get topNeighbours() { + return getNeighboursByDirection("top"); + }, + get leftNeighbours() { + return getNeighboursByDirection("left"); + }, + get rightNeighbours() { + return getNeighboursByDirection("right"); + }, + get bottomNeighbours() { + return getNeighboursByDirection("bottom"); + }, + get isGroupHeaderVisible() { + return _isGroupHeaderVisible; + }, + get activityId() { + if (_context._t42) { + return _context._t42.activityId; + } + const info = getWindowInfo(); + if (!info) { + return undefined; + } + return info.activityId; + }, + get activityWindowId() { + if (_context._t42) { + return _context._t42.activityWindowId; + } + const info = getWindowInfo(); + if (!info) { + return undefined; + } + return info.activityWindowId; + }, + get windowType() { + return options.windowType || "electron"; + }, + get zoomFactor() { + return _zoomFactor; + }, + get screen() { + if (typeof window !== "undefined" && window.glue42gd) { + return Utils.getMonitor(resultWindow.bounds, window.glue42gd.monitors); + } + return undefined; + }, + get placementSettings() { + return Object.assign({}, _placementSettings); + }, + get jumpList() { + return _jumpList; + }, + get allowWorkspaceDrop() { + return _allowWorkspaceDrop; + }, + get isPinned() { + return _isPinned; + }, + maximize, + restore, + minimize, + maximizeRestore, + collapse, + expand, + toggleCollapse, + focus, + activate, + moveResize, + setTitle, + setStyle, + setOnTop, + resetButtons, + getButtons, + setSizeConstraints, + getSizeConstraints, + navigate, + addFrameButton, + removeFrameButton, + setVisible, + show: () => setVisible(true), + hide: () => setVisible(false), + center, + close, + snap, + showLoader, + hideLoader, + updateContext, + lock, + unlock, + getIcon, + setIcon, + setFrameColor, + setTabTooltip, + getTabTooltip, + attachTab, + detachTab, + setTabHeaderVisible, + showPopup, + createFlydown, + setModalState, + setZoomFactor, + zoomIn, + zoomOut, + showDevTools, + capture, + flash, + flashTab, + setSticky, + setAllowWorkspaceDrop, + pin, + unpin, + print, + printToPDF, + place, + ungroup, + refresh, + goBack, + goForward, + download, + configure, + getConfiguration, + getDockingPlacement, + dock, + clone, + executeCode, + getChannel: async () => { + var _a; + const wins = await getChannels().getWindowsWithChannels({ windowIds: [_id] }); + return (_a = wins[0]) === null || _a === void 0 ? void 0 : _a.channel; + }, + startDrag, + showDialog, + onClose, + onUrlChanged, + onTitleChanged, + onFrameButtonAdded, + onFrameButtonRemoved, + onFrameButtonClicked, + onCollapsed, + onExpanded, + onMinimized, + onMaximized, + onNormal, + onAttached, + onDetached, + onVisibilityChanged, + onContextUpdated, + onLockingChanged, + onBoundsChanged, + onFrameColorChanged, + onFocusChanged, + onStickyChanged, + onGroupChanged, + onWindowAttached, + onWindowDetached, + onTabSelectionChanged, + onTabHeaderVisibilityChanged, + onClosing, + onRefreshing, + onZoomFactorChanged, + onPlacementSettingsChanged, + onNeighboursChanged, + onDockingChanged, + onNavigating, + onChannelRestrictionsChanged, + get tabs() { + return getAllTabs(); + }, + get isTabHeaderVisible() { + return _isTabHeaderVisible; + }, + get isTabSelected() { + return _isTabSelected; + }, + getURL() { + return Promise.resolve(_url); + }, + getTitle() { + return Promise.resolve(_title); + }, + getBounds() { + return Promise.resolve(_bounds); + }, + getContext() { + return Promise.resolve(_context); + }, + setContext(context) { + if (!isObject(context)) { + throw new Error(`"context" must not be null or undefined, set to empty object if you want to clear it out.`); + } + return executor.updateContext(resultWindow, context, true); + }, + getDisplay() { + const displayAPI = displayAPIGetter(); + return displayAPI.getByWindowId(id); + }, + resizeTo(width, height) { + return moveResize({ width, height }); + }, + moveTo(top, left) { + return moveResize({ top, left }); + }, + async getParentWindow() { + var _a; + const myParentId = _settings.parentInstanceId; + if (!myParentId) { + return undefined; + } + return (_a = windowStore.list[myParentId]) === null || _a === void 0 ? void 0 : _a.API; + }, + async getChildWindows() { + return Object.keys(windowStore.list) + .map((key) => windowStore.list[key].API) + .filter((w) => { + const parentId = w.settings.parentInstanceId; + return parentId === id; + }); + }, + joinChannel: (name) => { + return getChannels().join(name, id); + }, + leaveChannel: () => { + return getChannels().leave(id); + } + }; + const events = { + handleUpdate, + handleWindowClose, + handleWindowChangeState, + handleTitleChanged, + handleVisibilityChanged, + handleUrlChanged, + handleWindowSettingsChanged, + handleContextUpdated, + handleFrameIsLockedChanged, + handleBoundsChanged, + handleFocusChanged, + handleFrameButtonAdded, + handleFrameButtonRemoved, + handleFrameButtonClicked, + handleFrameColorChanged, + handleFrameAttached, + handleFrameSelectionChanged, + handleCompositionChanged, + handleAllowWorkspaceDropChanged, + handleIsPinnedChanged, + handleGroupHeaderVisibilityChanged, + handleTabHeaderVisibilityChanged, + handleGroupChanged, + handleAttached, + handleDetached, + handleWindowAttached, + handleWindowDetached, + handleZoomFactorChanged, + handleIsStickyChanged, + handlePlacementSettingsChanged, + handleDockingChanged, + handleChannelRestrictionsChanged + }; + const groupArgs = { + get isGroupHibernated() { + return _isGroupHibernated; + }, + get isGroupVisible() { + return _isGroupVisible; + }, + }; + return { + API: resultWindow, + Events: events, + GroupCreationArgs: groupArgs + }; + }; + + function getWindowsByTabGroupId(windowId, tabGroupId) { + const windows = windowStore.list; + return Object.keys(windows).reduce((memo, id) => { + const win = windows[id]; + if (win.API.tabGroupId === tabGroupId && win.API.id !== windowId) { + memo.push(win); + } + return memo; + }, []); + } + function isEmpty(object) { + if (!object || Object.keys(object).every((value) => object[value] === undefined)) { + return true; + } + return false; + } + + class GDExecutor { + constructor() { + this.GroupMethodName = "T42.Group.Execute"; + this.WndMethodName = "T42.Wnd.Execute"; + this._registry = CallbackRegistryFactory(); + this._finished = Promise.resolve(); + this._configuration = { + windowAvailableOnURLChanged: true + }; + this.unsubCallbacks = {}; + } + get hostInstance() { + return this.agmTarget; + } + get finished() { + return this._finished; + } + get configuration() { + return this._configuration; + } + init(agm, instance) { + this.agm = agm; + this.agmTarget = instance; + this._registry.add("event", (data) => { + if (data.type === "Closed") { + const keys = Object.keys(this.unsubCallbacks); + keys.forEach((key) => { + const isSameWindow = key.startsWith(data.windowId); + if (isSameWindow) { + delete this.unsubCallbacks[key]; + } + }); + } + }); + } + setConfiguration(config) { + this._configuration = { ...this._configuration, ...config }; + } + handleEvent(data) { + this._registry.execute("event", data); + } + async open(options) { + let finishedResolve; + this._finished = new Promise((resolve) => { + finishedResolve = resolve; + }); + try { + const result = await this.agm.invoke("T42.Wnd.Create", options, this.agmTarget, { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_RESPONSE_TIMEOUT_MS + }); + if (result.returned === undefined) { + throw new Error("failed to execute T42.Wnd.Create - unknown reason"); + } + const id = result.returned.id; + const win = await windowStore.waitFor(id); + if (!this.configuration || this.configuration.windowAvailableOnURLChanged) { + setTimeout(() => { + if (win.API.windowType === "electron") { + win.Events.handleUrlChanged(win.API.url); + } + }, 0); + } + return win.API; + } + finally { + finishedResolve(); + } + } + async close(w, options) { + const result = await this.execute("close", { windowId: w.id, options }, `Closed`); + if (options) { + return result.closed; + } + return w; + } + async navigate(w, newUrl, urlLoadOptions) { + let methodResponseTimeoutMs = 120000; + if (typeof urlLoadOptions === "object" && typeof urlLoadOptions.timeout === "number") { + methodResponseTimeoutMs = urlLoadOptions.timeout * 1000; + delete urlLoadOptions.timeout; + } + await this.execute("navigate", { windowId: w.id, options: { url: newUrl, urlLoadOptions }, invocationOptions: { methodResponseTimeoutMs } }, "UrlChanged"); + return w; + } + async setStyle(w, style) { + var _a; + const stylePromises = []; + const wait = (promise) => stylePromises.push(promise); + if (!isUndefinedOrNull(style.focus) && !w.isFocused) { + wait(w.focus()); + } + if (!isUndefinedOrNull(style.hidden)) { + const toBeVisible = !style.hidden; + wait(w.setVisible(toBeVisible)); + } + if (!isUndefinedOrNull(style.onTop)) { + wait(w.setOnTop(style.onTop)); + } + if (!isNullOrWhiteSpace(style.tabTooltip) || !isNullOrWhiteSpace(style.tabToolTip)) { + const toolTip = (_a = style.tabTooltip) !== null && _a !== void 0 ? _a : style.tabToolTip; + wait(w.setTabTooltip(toolTip)); + } + if (!isNullOrWhiteSpace(style.tabTitle)) { + wait(this.execute("setTabTitle", { windowId: w.id, options: { tabTitle: style.tabTitle } })); + } + const constraints = { + minHeight: style.minHeight, + minWidth: style.minWidth, + maxHeight: style.maxHeight, + maxWidth: style.maxWidth, + }; + const hasConstraints = !isEmpty(constraints); + if (hasConstraints) { + wait(w.setSizeConstraints(constraints)); + } + const buttons = { + allowClose: style.allowClose, + allowCollapse: style.allowCollapse, + allowLockUnlock: style.allowLockUnlock, + allowMaximize: style.allowMaximize, + allowMinimize: style.allowMinimize + }; + const hasButtons = !isEmpty(buttons); + if (hasButtons) { + wait(w.resetButtons(buttons)); + } + await Promise.all(stylePromises); + return w; + } + async setSizeConstraints(w, constraints) { + await this.execute("setSizeConstraints", { windowId: w.id, options: constraints }); + return w; + } + async getSizeConstraints(w) { + const sizeConstraint = await this.execute("getSizeConstraints", { windowId: w.id }); + return sizeConstraint; + } + async setTabTooltip(w, tabTooltip) { + await this.execute("setTabTooltip", { windowId: w.id, options: { tabTooltip } }); + return w; + } + async getTabTooltip(w) { + const result = await this.execute("getTabTooltip", { windowId: w.id }); + return result.tabTooltip; + } + async resetButtons(w, buttonsConfig) { + await this.execute("resetButtons", { windowId: w.id, options: buttonsConfig }); + return w; + } + async getButtons(w) { + const buttons = await this.execute("getButtons", { windowId: w.id }); + return buttons; + } + async setOnTop(w, onTop) { + await this.execute("setOnTop", { windowId: w.id, options: { onTop } }); + return w; + } + async setTitle(w, newTitle) { + const options = { + windowId: w.id, + options: { + title: newTitle + } + }; + await this.execute("setTitle", options, "TitleChanged"); + return w; + } + async setSticky(w, isSticky) { + const options = { + windowId: w.id, + options: { + isSticky + } + }; + await this.execute("setSticky", options); + return w; + } + async setAllowWorkspaceDrop(w, allowWorkspaceDrop) { + const options = { + windowId: w.id, + options: { + allowWorkspaceDrop + } + }; + await this.execute("setAllowWorkspaceDrop", options); + return w; + } + async pin(windowToPin) { + const options = { + windowId: windowToPin.id + }; + await this.execute("pinTab", options); + return windowToPin; + } + async unpin(pinnedWindow) { + const options = { + windowId: pinnedWindow.id + }; + await this.execute("unpinTab", options); + return pinnedWindow; + } + async moveResize(w, bounds) { + if (typeof window !== "undefined" && window.glueDesktop.versionNum < 31200) { + return new Promise(async (res, rej) => { + const resolveImmediately = this.areBoundsEqual(bounds, w); + let isDone = false; + const done = () => { + if (isDone) { + return; + } + isDone = true; + if (unsubscribeBoundsChanged) { + unsubscribeBoundsChanged(); + unsubscribeBoundsChanged = undefined; + } + res(w); + if (resolveTimeout) { + clearTimeout(resolveTimeout); + resolveTimeout = undefined; + } + }; + let resolveTimeout; + let unsubscribeBoundsChanged; + if (!resolveImmediately) { + unsubscribeBoundsChanged = w.onBoundsChanged((win) => { + if (!this.areBoundsEqual(bounds, win)) { + return; + } + done(); + }); + } + try { + await this.execute("moveResize", { windowId: w.id, options: { bounds } }); + } + catch (error) { + rej(error); + return; + } + if (resolveImmediately) { + done(); + return; + } + resolveTimeout = setTimeout(() => { + done(); + }, 1000); + }); + } + else { + await this.execute("moveResize", { windowId: w.id, options: { bounds } }); + } + return w; + } + async addFrameButton(w, buttonInfo) { + await this.execute("addButton", { windowId: w.id, options: buttonInfo }, "ButtonAdded"); + return w; + } + async removeFrameButton(w, buttonId) { + await this.execute("removeButton", { windowId: w.id, options: buttonId }, "ButtonRemoved"); + return w; + } + async activate(w) { + await this.execute("activate", { windowId: w.id }); + return w; + } + async focus(w) { + await this.execute("focus", { windowId: w.id }); + return w; + } + async maximizeRestore(w) { + await this.execute("maximizeRestore", { windowId: w.id }, "StateChanged"); + return w; + } + async maximize(w) { + await this.execute("maximize", { windowId: w.id }, "StateChanged"); + return w; + } + async restore(w) { + await this.execute("restore", { windowId: w.id }, "StateChanged"); + return w; + } + async minimize(w) { + await this.execute("minimize", { windowId: w.id }, "StateChanged"); + return w; + } + async collapse(w) { + await this.execute("collapse", { windowId: w.id }, "StateChanged"); + return w; + } + async expand(w) { + await this.execute("expand", { windowId: w.id }, "StateChanged"); + return w; + } + async toggleCollapse(w) { + await this.execute("toggleCollapse", { windowId: w.id }, "StateChanged"); + return w; + } + async snap(w, targetWindow, options) { + const args = { + targetWindowId: targetWindow.id + }; + args.snappingEdge = options.direction; + args.autoAlign = options.autoAlign; + await this.execute("snap", { windowId: w.id, options: args }, "CompositionChanged", `CompositionChanged-${targetWindow.id}`); + return w; + } + async attachTab(w, sourceWindow, options) { + await this.execute("attachTab", { + windowId: w.id, + options: { + index: options, + sourceWindowId: sourceWindow.id, + targetWindowId: w.id, + } + }, `WindowFrameAdded-${sourceWindow.id}`, `WindowFrameRemoved-${sourceWindow.id}`); + return w; + } + async detachTab(w, options) { + const eventKeys = ["WindowFrameRemoved", `WindowFrameAdded`]; + if (!isUndefinedOrNull(options === null || options === void 0 ? void 0 : options.relativeTo)) { + eventKeys.push(`CompositionChanged`); + eventKeys.push(`CompositionChanged-${options.relativeTo}`); + } + else { + eventKeys.push("BoundsChanged"); + } + await this.execute("detachTab", { windowId: w.id, options }, ...eventKeys); + return w; + } + async setVisible(w, toBeVisible = true) { + let command; + if (toBeVisible) { + command = "show"; + } + else { + command = "hide"; + } + await this.execute(command, { windowId: w.id }, "VisibilityChanged"); + return w; + } + async center(w, display) { + await this.execute("center", { windowId: w.id, options: display }); + return w; + } + async showLoader(w, loader) { + await this.execute("showLoadingAnimation", { windowId: w.id, options: loader }); + return w; + } + async hideLoader(w) { + await this.execute("hideLoadingAnimation", { windowId: w.id }); + return w; + } + async updateContext(w, context, replace) { + let un; + try { + const contextWithoutUndefinedValues = this.swapUndefinedToNull(context); + const done = new Promise((resolve, reject) => { + un = w.onContextUpdated(() => { + resolve(); + }); + }); + await Promise.all([this.execute("updateContext", { + windowId: w.id, context: contextWithoutUndefinedValues, replace + }), done]); + return w; + } + finally { + if (un) { + un(); + } + } + } + async lock(w) { + await this.execute("lockUnlock", { windowId: w.id, options: { lock: true } }, "FrameIsLockedChanged"); + return w; + } + async unlock(w) { + await this.execute("lockUnlock", { windowId: w.id, options: { lock: false } }, "FrameIsLockedChanged"); + return w; + } + async getIcon(w) { + const result = await this.execute("getIcon", { + windowId: w.id, + options: {} + }); + return result.icon; + } + async setIcon(w, base64Image) { + await this.execute("setIcon", { + windowId: w.id, + options: { + dataURL: base64Image + } + }); + return w; + } + async setFrameColor(w, frameColor) { + await this.execute("setFrameColor", { windowId: w.id, options: { frameColor } }, "FrameColorChanged"); + return w; + } + async setTabHeaderVisible(w, toBeTabHeaderVisible) { + await this.execute("setTabHeaderVisible", { + windowId: w.id, + options: { + toShow: toBeTabHeaderVisible + } + }, "TabHeaderVisibilityChanged"); + return w; + } + async showGroupPopup(id, options) { + const reformatedOptions = this.showPopupCore(id, options); + await this.executeGroup("showGroupPopup", { + groupId: id, + options: reformatedOptions + }); + } + async showPopup(targetWindow, options) { + const reformatedOptions = this.showPopupCore(targetWindow.id, options); + await this.execute("showPopupWindow", { + windowId: targetWindow.id, + options: reformatedOptions + }); + return targetWindow; + } + async createFlydown(windowId, options) { + if (!options) { + throw new Error("The options object is not valid!"); + } + const optionsCopy = { ...options }; + if (!optionsCopy.horizontalOffset) { + optionsCopy.horizontalOffset = 0; + } + if (!optionsCopy.verticalOffset) { + optionsCopy.verticalOffset = 0; + } + const fullOptions = this.reformatFlydownOptions(windowId, optionsCopy); + return this.execute("setFlydownArea", { windowId, options: fullOptions }).then(() => { + const zoneIds = fullOptions.zones.map((z) => z.id); + fullOptions.zones.forEach((z) => { + let callback = typeof (z.flydownSize) === "function" ? + z.flydownSize : () => z.flydownSize; + if (options.size instanceof Function && z.flydownSize) { + callback = async (data, cancel) => { + let result; + if (options.size instanceof Function) { + result = await options.size(data, cancel); + } + if (z.flydownSize instanceof Function && z.flydownSize !== options.size) { + return await z.flydownSize(data, cancel) || result; + } + return result || z.flydownSize; + }; + } + this._registry.clearKey(`${fullOptions.targetId}_${z.id}`); + this._registry.add(`${fullOptions.targetId}_${z.id}`, callback); + }); + return { + destroy: () => this.clearFlydownArea(fullOptions.targetId, zoneIds), + options: optionsCopy + }; + }); + } + async setModalState(windowId, isModal) { + return this.execute("setModalState", { windowId, options: { isModal } }); + } + async autoArrange(displayId) { + return this.execute("autoArrange", { options: { displayId } }); + } + async handleFlydownBoundsRequested(targetId, data) { + const cancelCallback = () => data.cancel = true; + const callbackData = { + zoneId: data.flydownId, + flydownWindowBounds: data.flydownWindowBounds, + flydownWindowId: data.flydownWindowId, + }; + const responses = await Promise.all(this._registry.execute(`${targetId}_${data.flydownId}`, callbackData, cancelCallback)); + if (responses.length === 1) { + const defaultResponse = { height: 0, width: 0, top: 0, left: 0 }; + const response = typeof (responses[0]) === "object" && !Array.isArray(responses[0]) ? responses[0] : defaultResponse; + const responseOptions = { ...data, flydownWindowBounds: response }; + return responseOptions; + } + } + async handleOnEventRequested(callbackId, args) { + var _a; + const callbacks = (_a = this.unsubCallbacks[callbackId]) !== null && _a !== void 0 ? _a : []; + let prevented = false; + const preventArgs = []; + await Promise.all(callbacks.map((cb) => { + return new Promise((resolve, reject) => { + cb(() => { + resolve(); + }, () => { + reject(); + }, (pArgs) => { + prevented = true; + preventArgs.push(pArgs); + }, args); + }); + })); + return { prevented, preventArgs }; + } + async zoomIn(window) { + await this.execute("zoomIn", { + windowId: window.id, + }); + return window; + } + async zoomOut(window) { + await this.execute("zoomOut", { + windowId: window.id, + }); + return window; + } + async setZoomFactor(window, zoomFactor) { + await this.execute("setZoomFactor", { + windowId: window.id, + options: { + zoomFactor + } + }); + return window; + } + async showDevTools(window) { + await this.execute("showDevTools", { + windowId: window.id, + }); + return window; + } + async capture(window, options) { + const base64screenshot = (await this.execute("captureScreenshot", { windowId: window.id, options: { ...options } })).data; + return base64screenshot; + } + async captureGroup(windowIds, options) { + const base64screenshot = (await this.execute("captureGroupScreenshot", { windowId: windowIds[0], options: { groupWindowIds: windowIds, ...options } })).data; + return base64screenshot; + } + async flash(resultWindow, options) { + await this.execute("flash", { windowId: resultWindow.id, options: { ...options } }); + return resultWindow; + } + async flashTab(resultWindow, options) { + await this.execute("flashTab", { windowId: resultWindow.id, options: { ...options } }); + return resultWindow; + } + async configure(windowId, options) { + return this.execute("configure", { windowId, options: { ...options } }); + } + async print(resultWindow, options) { + await this.execute("print", { windowId: resultWindow.id, options: { ...options } }); + return resultWindow; + } + async printToPDF(resultWindow, options) { + const filePath = (await this.execute("printToPDF", { windowId: resultWindow.id, options: { ...options } })).filePath; + return filePath; + } + async place(window, options) { + const copy = { ...options }; + if (!options.display || options.display === "current") { + copy.display = await window.getDisplay(); + } + if (copy.display && typeof copy.display !== "string" && typeof copy.display !== "number") { + copy.display = copy.display.index + 1; + } + return this.execute("place", { windowId: window.id, options: { ...copy } }); + } + async refresh(resultWindow, ignoreCache) { + await this.execute("refresh", { windowId: resultWindow.id, options: { ignoreCache } }); + return resultWindow; + } + async download(resultWindow, url, options = {}) { + options.enableDownloadBar = !options.silent; + const result = await this.execute("downloadURL", { windowId: resultWindow.id, options: { url, options } }); + return { + url, + path: result.fullPath, + size: result.fileSize, + }; + } + async configureWindow(resultWindow, options) { + await this.execute("configureWindow", { windowId: resultWindow.id, options }); + return resultWindow; + } + async getWindowConfiguration(resultWindow) { + const config = await this.execute("getWindowConfiguration", { windowId: resultWindow.id }); + return config; + } + async startDrag(resultWindow, options) { + await this.execute("startDrag", { windowId: resultWindow.id, options }); + return resultWindow; + } + showDialog(resultWindow, options) { + return new Promise((res, rej) => { + const token = Utils.generateId(); + const un = this._registry.add("event", (args) => { + if (args.type === "DialogResult" && args.windowId === resultWindow.id && args.data.token === token) { + un(); + const data = args.data; + if ("status" in data) { + if (data.status === "failed") { + rej(new Error(data.message)); + } + else if (data.status === "successful") { + res(data.result); + } + } + } + }); + this.execute("showDialog", { windowId: resultWindow.id, options: Object.assign({}, { ...options }, { token }) }); + }); + } + async execute(command, options, ...eventKeys) { + return this.executeCore(this.WndMethodName, command, options, ...eventKeys); + } + async executeGroup(command, options, ...eventKeys) { + return this.executeCore(this.GroupMethodName, command, options, ...eventKeys); + } + async ungroup(w, options) { + const args = { + windowId: w.id, + options + }; + await this.execute("ungroup", args); + return w; + } + async updateJumpList(windowId, options) { + const args = { + windowId, + options + }; + await this.execute("updateJumplist", args); + } + async getJumpList(windowId) { + const args = { + windowId, + }; + const result = await this.execute("getJumplist", args); + return result; + } + onClosing(callback, gdWindow) { + const glue42gd = typeof window !== "undefined" && window.glue42gd; + if (glue42gd && gdWindow.windowType === "electron") { + return glue42gd.addCloseHandler(callback, gdWindow.id); + } + else { + return this.nonWindowHandlers(callback, gdWindow.id, "OnClosing"); + } + } + onGroupClosing(callback, group) { + return this.nonWindowHandlersCore(group.id, "OnClosing", true, callback); + } + onRefreshing(callback, gdWindow) { + const glue42gd = typeof window !== "undefined" && window.glue42gd; + if (glue42gd && gdWindow.windowType === "electron") { + return glue42gd.addRefreshHandler(callback, gdWindow.id); + } + else { + return this.nonWindowHandlers(callback, gdWindow.id, "OnRefreshing"); + } + } + onNavigating(callback, gdWindow) { + const glue42gd = typeof window !== "undefined" && window.glue42gd; + if (glue42gd && gdWindow.windowType === "electron") { + return glue42gd.addWillNavigateHandler(callback, gdWindow.id); + } + else { + return this.nonWindowHandlers(callback, gdWindow.id, "OnNavigating"); + } + } + async clone(window, cloneOptions) { + const args = { + windowId: window.id, + options: cloneOptions + }; + const result = await this.execute("clone", args); + const win = await windowStore.waitFor(result.id); + return win.API; + } + async executeCode(targetWindow, code) { + const args = { + windowId: targetWindow.id, + options: { + code + } + }; + return this.execute("executeCode", args); + } + async goBack(resultWindow) { + await this.execute("goBack", { windowId: resultWindow.id }); + } + async goForward(resultWindow) { + await this.execute("goForward", { windowId: resultWindow.id }); + } + async getDockingPlacement(window) { + return this.execute("getDockingPlacement", { windowId: window.id }); + } + dock(window, options) { + return this.execute("dock", { windowId: window.id, options }); + } + clearCallbacks(id) { + const keys = Object.keys(this.unsubCallbacks); + keys.forEach((key) => { + if (key.startsWith(id)) { + delete this.unsubCallbacks[key]; + } + }); + } + nonWindowHandlers(callback, targetId, type) { + return this.nonWindowHandlersCore(targetId, type, false, callback); + } + nonWindowHandlersCore(targetId, type, isGroup, callback) { + const id = `${targetId}-${type}`; + const unsub = () => { + var _a; + if (this.unsubCallbacks[id]) { + const callbacks = this.unsubCallbacks[id]; + this.unsubCallbacks[id] = callbacks.filter((cb) => cb !== callback); + if (this.unsubCallbacks[id].length === 0) { + delete this.unsubCallbacks[id]; + } + } + const cbs = (_a = this.unsubCallbacks[id]) !== null && _a !== void 0 ? _a : []; + if (cbs.length === 0) { + const options = { + unsubscribe: true + }; + if (isGroup) { + this.executeGroup(type, { + groupId: targetId, + options + }); + } + else { + this.execute(type, { + windowId: targetId, + options + }); + } + } + }; + if (this.unsubCallbacks[id]) { + this.unsubCallbacks[id].push(callback); + return unsub; + } + else { + this.unsubCallbacks[id] = [callback]; + } + if (isGroup) { + this.executeGroup(type, { groupId: targetId }); + } + else { + this.execute(type, { windowId: targetId }); + } + return unsub; + } + reformatFlydownOptions(windowId, options) { + const assignGeneralIfUnassigned = (zone, prop) => { + if (options[prop] && (zone[prop] === undefined || zone[prop] === null)) { + const valueFromOptions = options[prop]; + zone[prop] = valueFromOptions; + } + }; + const zones = options.zones.map((z) => { + assignGeneralIfUnassigned(z, "windowId"); + assignGeneralIfUnassigned(z, "targetLocation"); + if (options.size && (z.flydownSize === undefined || z.flydownSize === null)) { + z.flydownSize = options.size; + } + z.flydownBounds = z.flydownSize; + z.flydownId = z.windowId; + if (!z.targetLocation) { + z.targetLocation = "bottom"; + } + return z; + }); + return { + ...options, + zones, + targetId: windowId, + flydownBounds: options.size, + flydownActiveArea: options.activeArea + }; + } + clearFlydownArea(windowId, areaIds) { + return this.execute("clearFlydownWindowArea", { + windowId, + options: {} + }).then(() => { + areaIds.forEach((id) => { + this._registry.clearKey(`${windowId}_${id}`); + }); + }); + } + executeWithoutToken(params, ...eventKeys) { + const uns = []; + const executed = eventKeys === null || eventKeys === void 0 ? void 0 : eventKeys.filter((k) => !isUndefinedOrNull(k)).map((key) => { + return new Promise((r) => { + const [type, windowId = params.windowId] = key.split("-"); + uns.push(this._registry.add("event", (data) => { + if (data.type === type && data.windowId === windowId) { + r(); + } + })); + }); + }); + const action = new Promise((resolve, reject) => { + this.agm.invoke("T42.Wnd.Execute", params, this.agmTarget, { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_RESPONSE_TIMEOUT_MS + }) + .then((i) => { + if (i.returned && i.returned.errorMsg) { + reject(i); + } + else { + resolve(i.returned); + } + }) + .catch((e) => reject(e)); + }); + return Promise.all([action, ...executed]) + .then((r) => { + return r[0]; + }) + .finally(() => { + uns.forEach((un) => un()); + }); + } + async executeCore(methodName, command, options, ...eventKeys) { + const { invocationOptions, ...invocationArgs } = options; + const params = { + ...invocationArgs, + command, + }; + let finishedResolve; + this._finished = new Promise((resolve) => { + finishedResolve = resolve; + }); + try { + if (typeof window !== "undefined" && window.glueDesktop.versionNum < 31200) { + return await this.executeWithoutToken(params, ...eventKeys); + } + else { + return await this.executeWithToken(methodName, params, invocationOptions); + } + } + finally { + finishedResolve(); + } + } + async executeWithToken(methodName, options, invocationOptions) { + let un; + try { + const token = Utils.generateId(); + const event = new Promise((r) => { + un = this._registry.add("event", (data) => { + if (data.token === token) { + r(); + } + }); + }); + const execute = new Promise((resolve, reject) => { + options.token = token; + if (!invocationOptions) { + invocationOptions = { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_RESPONSE_TIMEOUT_MS + }; + } + else if (!invocationOptions.methodResponseTimeoutMs) { + invocationOptions.methodResponseTimeoutMs = INTEROP_METHOD_RESPONSE_TIMEOUT_MS; + } + else if (!invocationOptions.waitTimeoutMs) { + invocationOptions.waitTimeoutMs = INTEROP_METHOD_WAIT_TIMEOUT_MS; + } + this.agm.invoke(methodName, options, this.agmTarget, invocationOptions) + .then((i) => { + if (i.returned && i.returned.errorMsg) { + reject(new Error(i.returned.errorMsg)); + } + else { + resolve(i.returned); + } + }) + .catch((e) => { + const error = Utils.typedError(e); + reject(error); + }); + }); + const result = await Promise.all([execute, event]); + return result[0]; + } + finally { + if (un) { + un(); + } + } + } + areBoundsEqual(requested, w) { + const current = w.bounds; + const settings = w.settings; + let height = requested.height; + let width = requested.width; + if (requested.height < settings.minHeight) { + height = settings.minHeight; + } + if (requested.height > settings.maxHeight) { + height = settings.maxHeight; + } + if (requested.width < settings.minWidth) { + width = settings.minWidth; + } + if (requested.width > settings.maxWidth) { + width = settings.maxWidth; + } + const areHeightsEqual = height ? current.height === height : true; + const areWidthsEqual = width ? current.width === width : true; + const areLeftsEqual = requested.left ? current.left === requested.left : true; + const areTopsEqual = requested.top ? current.top === requested.top : true; + return areHeightsEqual && areWidthsEqual && areLeftsEqual && areTopsEqual; + } + swapUndefinedToNull(context) { + try { + const copy = {}; + for (const key of Object.keys(context)) { + let value = context[key]; + if (typeof value === "undefined") { + value = null; + } + copy[key] = value; + } + return copy; + } + catch { + return context; + } + } + showPopupCore(id, options) { + if (!options) { + throw new Error("The options object is not valid!"); + } + const optionsCopy = { ...options }; + if (!optionsCopy.targetLocation) { + optionsCopy.targetLocation = "bottom"; + } + const reformatedOptions = { + ...optionsCopy, + popupBounds: optionsCopy.size, + targetId: id, + popupId: optionsCopy.windowId + }; + return reformatedOptions; + } + } + var executor = new GDExecutor(); + + class GDEnvironment { + constructor(agm, logger, appManagerGetter, displayAPIGetter, channelsAPIGetter, wndId, groupId) { + this._registry = CallbackRegistryFactory(); + this._agm = agm; + this._logger = logger.subLogger("gd-env"); + this._windowId = wndId; + this._groupId = groupId; + this._appManagerGetter = appManagerGetter; + this._displayAPIGetter = displayAPIGetter; + this._channelsAPIGetter = channelsAPIGetter; + } + init() { + return new Promise((resolve, reject) => { + this._agm.register("T42.Wnd.OnEventWithResponse", (args, caller) => { + return this.respondToEvent(args); + }); + new Promise((streamResolve, streamReject) => { + this._agm.subscribe("T42.Wnd.OnEvent", { + target: "best", + arguments: { + withConfig: true + }, + onData: (streamData) => { + if (streamData.data.type === "Configuration") { + this._configuration = streamData.data; + executor.setConfiguration(this._configuration); + return; + } + this.updateWindow(streamData.data, resolve); + executor.handleEvent(streamData.data); + }, + onConnected: (instance) => { + this._agmInstance = instance; + executor.init(this._agm, this._agmInstance); + } + }).catch((error) => { + var _a; + const message = `${(_a = error === null || error === void 0 ? void 0 : error.method) === null || _a === void 0 ? void 0 : _a.name} - ${JSON.stringify(error === null || error === void 0 ? void 0 : error.called_with)} - ${error === null || error === void 0 ? void 0 : error.message}`; + reject(new Error(message)); + }); + }); + }); + } + get executor() { + return executor; + } + open(name, url, options) { + options = options || {}; + const copyOptions = { ...options }; + if (copyOptions.relativeTo !== undefined && typeof copyOptions.relativeTo !== "string") { + copyOptions.relativeTo = copyOptions.relativeTo.id || ""; + } + copyOptions.name = name; + copyOptions.url = url; + copyOptions.windowState = options.windowState || options.state; + delete copyOptions.state; + return this.executor.open(copyOptions); + } + createFlydown(windowId, options) { + return this.executor.createFlydown(windowId, options); + } + async showPopup(windowId, options) { + const window = windowStore.get(windowId); + await this.executor.showPopup(window.API, options); + } + tabAttached(callback) { + return this._registry.add("tab-attached", callback); + } + tabDetached(callback) { + return this._registry.add("tab-detached", callback); + } + onWindowFrameColorChanged(callback) { + return this._registry.add("frame-color-changed", callback); + } + onEvent(callback) { + return this._registry.add("window-event", callback); + } + my() { + return this._windowId; + } + myGroup() { + return this._groupId; + } + onCompositionChanged(callback) { + return this._registry.add("composition-changed", callback); + } + onGroupHeaderVisibilityChanged(callback) { + return this._registry.add("group-header-changed", callback); + } + onGroupVisibilityChanged(callback) { + return this._registry.add("group-visibility-changed", callback); + } + onGroupStateChanged(callback) { + return this._registry.add("group-state-changed", callback); + } + onWindowGotFocus(callback) { + return this._registry.add("got-focus", callback); + } + onWindowLostFocus(callback) { + return this._registry.add("lost-focus", callback); + } + onWindowsAutoArrangeChanged(callback) { + return this._registry.add("windows-auto-arranged-changed", callback); + } + respondToEvent(args) { + if (args.type === "ShowFlydownBoundsRequested") { + return this.executor.handleFlydownBoundsRequested(args.data.windowId, args.data); + } + else if (args.type === "OnClosing" || args.type === "OnRefreshing" || args.type === "OnNavigating") { + return this.executor.handleOnEventRequested(args.data.callbackId, args.data.args); + } + return Promise.reject(`There isn't a handler for ${args.type}`); + } + updateWindow(windowInfo, readyResolve) { + const extendedStreamEvent = this.getExtendedStreamEvent(windowInfo); + if (windowInfo.type === "Snapshot") { + const windowInfoFullInfoEvent = windowInfo; + windowInfoFullInfoEvent.windows.forEach((w) => { + const existingWindow = windowStore.get(w.id); + if (existingWindow) { + existingWindow.Events.handleUpdate(this.mapToWindowConstructorOptions(w)); + existingWindow.GroupCreationArgs = this.mapToGroupCreationArgs(w); + } + else { + this.createWindowFromSnapshot(w.id, w); + } + this._registry.execute("window-event", extendedStreamEvent); + }); + readyResolve(this); + return; + } + if (windowInfo.type === "CommandExecuted") { + this._registry.execute("window-event", extendedStreamEvent); + return; + } + if (windowInfo.type === "Created") { + const windowInfoCreatedEvent = (windowInfo); + this.createWindowFromStream(windowInfoCreatedEvent.windowId, windowInfoCreatedEvent.data || {}); + this._registry.execute("window-event", extendedStreamEvent); + return; + } + if (windowInfo.type === "OnGroupVisibilityChanged") { + const info = windowInfo; + this._registry.execute("group-visibility-changed", info.data); + this._registry.execute("window-event", windowInfo); + return; + } + if (windowInfo.type === "OnGroupStateChanged") { + const info = windowInfo; + this._registry.execute("group-state-changed", info.data); + this._registry.execute("window-event", windowInfo); + return; + } + if (windowInfo.type === "OnWindowsAutoArrangeChanged") { + const info = windowInfo; + this._registry.execute("windows-auto-arranged-changed", info.data); + this._registry.execute("window-event", windowInfo); + return; + } + const windowObjectAndEvents = windowStore.get((windowInfo).windowId); + if (!windowObjectAndEvents) { + this._logger.error(`received update for unknown window. Stream:', ${JSON.stringify(windowInfo, null, 4)}`); + return; + } + const theWindow = windowObjectAndEvents.API; + const theWindowEvents = windowObjectAndEvents.Events; + if (windowInfo.type === "BoundsChanged") { + const windowInfoBoundsChangedEvent = windowInfo; + theWindowEvents.handleBoundsChanged(windowInfoBoundsChangedEvent.data); + } + if (windowInfo.type === "UrlChanged") { + const windowInfoUrlChangedEvent = windowInfo; + windowStore.setUrlChangedState(windowInfoUrlChangedEvent.windowId); + theWindowEvents.handleUrlChanged(windowInfoUrlChangedEvent.data); + } + if (windowInfo.type === "TitleChanged") { + const windowInfoTitleChanged = windowInfo; + theWindowEvents.handleTitleChanged(windowInfoTitleChanged.data); + } + if (windowInfo.type === "IsStickyChanged") { + const windowInfoIsStickyChangedChanged = windowInfo; + theWindowEvents.handleIsStickyChanged(windowInfoIsStickyChangedChanged.data); + } + if (windowInfo.type === "VisibilityChanged") { + theWindowEvents.handleVisibilityChanged(windowInfo.data); + } + if (windowInfo.type === "ContextChanged") { + theWindowEvents.handleContextUpdated(windowInfo.data); + } + if (windowInfo.type === "StateChanged") { + theWindowEvents.handleWindowChangeState(windowInfo.data); + } + if (windowInfo.type === "FrameColorChanged") { + theWindowEvents.handleFrameColorChanged(windowInfo.data); + this._registry.execute("frame-color-changed", theWindow); + } + if (windowInfo.type === "CompositionChanged") { + const windowInfoCompositionChanged = windowInfo; + theWindowEvents.handleCompositionChanged(windowInfoCompositionChanged.data); + windowStore.setCompositionChangedState(windowObjectAndEvents); + this._registry.execute("composition-changed", windowInfoCompositionChanged.data); + } + if (windowInfo.type === "GroupHeaderVisibilityChanged") { + const info = windowInfo; + theWindowEvents.handleGroupHeaderVisibilityChanged(info.data.groupHeaderVisible); + this._registry.execute("group-header-changed", info.data); + } + if (windowInfo.type === "FocusChanged") { + const windowInfoFocusChanged = windowInfo; + this.focusChanged(theWindowEvents, theWindow, windowInfoFocusChanged.data); + } + if (windowInfo.type === "WindowFrameChanged") { + theWindowEvents.handleFrameAttached(windowInfo.data.frameId, windowInfo.data.frameId, windowInfo.data.isTabHeaderVisible); + this._registry.execute("frame-changed"); + } + if (windowInfo.type === "WindowFrameAdded") { + const winsToBeNotified = getWindowsByTabGroupId(theWindow.id, windowInfo.data.frameId); + const data = windowInfo.data; + theWindowEvents.handleAttached(data.frameId, data.frameId, data.isTabHeaderVisible, data.isLocked, winsToBeNotified) + .then(async () => { + if (winsToBeNotified.length > 0) { + await executor.finished; + this._registry.execute("tab-attached", theWindow, windowInfo.data.frameId, windowInfo.data.isTabHeaderVisible); + } + }); + } + if (windowInfo.type === "WindowFrameRemoved") { + const oldTabGroupId = theWindow.tabGroupId; + const winsToBeNotified = getWindowsByTabGroupId(theWindow.id, oldTabGroupId); + theWindowEvents.handleDetached(windowInfo.data.isLocked, winsToBeNotified) + .then(async () => { + if (winsToBeNotified.length > 0) { + await executor.finished; + this._registry.execute("tab-detached", theWindow, windowInfo.data.frameId, theWindow.tabGroupId); + } + }); + } + if (windowInfo.type === "TabHeaderVisibilityChanged") { + theWindowEvents.handleTabHeaderVisibilityChanged(windowInfo.data.isTabHeaderVisible); + } + if (windowInfo.type === "FrameSelectionChanged") { + theWindowEvents.handleFrameSelectionChanged(windowInfo.data.newWindowId, windowInfo.data.prevWindowId); + } + if (windowInfo.type === "ButtonClicked") { + theWindowEvents.handleFrameButtonClicked(windowInfo.data); + } + if (windowInfo.type === "ButtonAdded") { + theWindowEvents.handleFrameButtonAdded(windowInfo.data); + } + if (windowInfo.type === "ButtonRemoved") { + theWindowEvents.handleFrameButtonRemoved(windowInfo.data); + } + if (windowInfo.type === "WindowZoomFactorChanged") { + theWindowEvents.handleZoomFactorChanged(windowInfo.data); + } + if (windowInfo.type === "Closed") { + windowStore.remove(windowObjectAndEvents); + theWindowEvents.handleWindowClose(); + } + if (windowInfo.type === "FrameIsLockedChanged") { + theWindowEvents.handleFrameIsLockedChanged(windowInfo.data); + } + if (windowInfo.type === "PlacementSettingsChanged") { + theWindowEvents.handlePlacementSettingsChanged(windowInfo.data); + } + if (windowInfo.type === "DockingChanged") { + theWindowEvents.handleDockingChanged(windowInfo.data); + } + if (windowInfo.type === "AllowWorkspaceDropChanged") { + theWindowEvents.handleAllowWorkspaceDropChanged(windowInfo.data); + } + if (windowInfo.type === "IsPinnedChanged") { + theWindowEvents.handleIsPinnedChanged(windowInfo.data); + } + if (windowInfo.type === "WindowChannelRestrictionsChanged") { + theWindowEvents.handleChannelRestrictionsChanged(windowInfo.data); + } + this._registry.execute("window-event", extendedStreamEvent); + } + createWindowFromSnapshot(windowId, options) { + const windowObjAndEvents = this.createWindowCore(windowId, options); + windowStore.add(windowObjAndEvents, { + ready: true, + urlChanged: true, + compositionChanged: true + }); + } + createWindowFromStream(windowId, options) { + var _a; + const windowObjAndEvents = this.createWindowCore(windowId, options); + const isRemote = windowObjAndEvents.API.windowType === "remote"; + const isFrameless = windowObjAndEvents.API.windowType === "electron" && windowObjAndEvents.API.mode === "frameless"; + const isHidden = windowObjAndEvents.API.isVisible === false; + let urlChanged = false; + let compositionChanged = false; + if (isRemote) { + urlChanged = true; + } + if (isFrameless || isHidden) { + compositionChanged = true; + } + if (!isRemote) { + urlChanged = !((_a = this._configuration) === null || _a === void 0 ? void 0 : _a.windowAvailableOnURLChanged); + } + windowStore.add(windowObjAndEvents, { + ready: true, + urlChanged, + compositionChanged + }); + } + createWindowCore(windowId, options) { + const windowObjAndEvents = windowFactory(windowId, this.mapToWindowConstructorOptions(options), executor, this._logger, this._appManagerGetter, this._displayAPIGetter, this._channelsAPIGetter, this._agm); + windowObjAndEvents.GroupCreationArgs = this.mapToGroupCreationArgs(options); + return windowObjAndEvents; + } + async focusChanged(theWindowEvents, theWindow, focus) { + theWindowEvents.handleFocusChanged(focus); + try { + if (!this._configuration.windowAvailableOnURLChanged) { + await windowStore.waitFor(theWindow.id); + } + } + catch (error) { + return; + } + if (focus) { + this._registry.execute("got-focus", theWindow); + } + else { + this._registry.execute("lost-focus", theWindow); + } + } + mapToWindowConstructorOptions(args) { + return { + name: args.name, + context: args.context, + bounds: args.bounds, + url: args.url, + title: args.title, + isVisible: args.isVisible, + focus: args.isFocused, + state: args.state, + frameColor: args.frameColor, + groupId: args.groupId, + neighbours: args.neighbors, + isFocused: args.isFocused, + isGroupHeaderVisible: args.groupHeaderVisible, + isCollapsed: args.isCollapsed, + tabGroupId: args.frameId, + frameId: args.frameId, + mode: args.mode, + isTabHeaderVisible: args.isTabHeaderVisible, + isTabSelected: args.isActiveTab, + settings: args.settings, + windowType: args.windowType, + zoomFactor: args.zoomFactor, + isLocked: args.isLocked, + placementSettings: args.placementSettings, + isSticky: args.isSticky, + tabIndex: args.tabIndex, + frameButtons: args.frameButtons, + jumpListOptions: args.jumpList, + applicationName: args.applicationName, + allowWorkspaceDrop: args.allowWorkspaceDrop, + isPinned: args.isPinned + }; + } + mapToGroupCreationArgs(args) { + return { + isGroupHibernated: args.isGroupHibernated, + isGroupVisible: args.isGroupVisible + }; + } + getExtendedStreamEvent(streamEvent) { + try { + if (!streamEvent.windowId) { + return streamEvent; + } + const window = windowStore.get(streamEvent.windowId); + if (!window) { + return streamEvent; + } + const result = { + state: streamEvent.type, + windowName: window.API.name, + ...streamEvent + }; + if (result.state === "WindowFrameAdded") { + result.state = "TabAttached"; + } + if (result.state === "StateChanged") { + result.state = result.data.charAt(0).toUpperCase() + result.data.slice(1); + } + if (result.state === "ButtonAdded") { + result.state = "FrameButtonAdded"; + } + if (result.state === "ButtonRemoved") { + result.state = "FrameButtonRemoved"; + } + return result; + } + catch (error) { + return streamEvent; + } + } + } + + var envDetector = (agm, logger, appManagerGetter, displayAPIGetter, channelsAPIGetter, gdMajorVersion) => { + var _a; + const _logger = logger; + if (gdMajorVersion === 2) { + _logger.trace("running in HC"); + throw new Error("GD2 not supported"); + } + else if (gdMajorVersion >= 3) { + _logger.trace("running in GD 3"); + return new GDEnvironment(agm, _logger, appManagerGetter, displayAPIGetter, channelsAPIGetter, window.glue42gd.windowId, (_a = window.webGroupsManager) === null || _a === void 0 ? void 0 : _a.id).init(); + } + else { + _logger.trace("running in Browser or Node"); + return new GDEnvironment(agm, _logger, appManagerGetter, displayAPIGetter, channelsAPIGetter).init(); + } + }; + + var groupFactory = (id, executor) => { + const _registry = CallbackRegistryFactory(); + const _windowsId = []; + let _isHibernatedFlag; + let _isVisible; + async function addWindow(winId) { + var _a, _b, _c, _d; + if (_windowsId.indexOf(winId) === -1) { + _windowsId.push(winId); + const win = windowStore.get(winId); + win.Events.handleGroupChanged(groupObject, undefined); + _isHibernatedFlag = (_b = (_a = win.GroupCreationArgs.isGroupHibernated) !== null && _a !== void 0 ? _a : _isHibernatedFlag) !== null && _b !== void 0 ? _b : false; + _isVisible = (_d = (_c = win.GroupCreationArgs.isGroupVisible) !== null && _c !== void 0 ? _c : _isVisible) !== null && _d !== void 0 ? _d : true; + await executor.finished; + _registry.execute("window-added", groupObject, win.API); + } + } + async function removeWindow(win) { + const index = _windowsId.indexOf(win.API.id); + if (index !== -1) { + _windowsId.splice(index, 1); + win.Events.handleGroupChanged(undefined, groupObject); + await executor.finished; + _registry.execute("window-removed", groupObject, win.API); + } + } + function find(window, success, error) { + let winId; + if (typeof window === "string") { + winId = window; + } + else if (!isUndefinedOrNull(window)) { + winId = window.id; + } + const win = _mapToWindowObject(winId); + if (win) { + if (typeof success === "function") { + success(win); + } + return win; + } + else { + if (typeof error === "function") { + error(`No window with ID: ${winId}`); + } + } + } + function windows(success) { + const mappedWindows = _mapToWindowObjects(); + return mappedWindows; + } + async function execute(command, options, ...keys) { + await executor.execute(command, options, ...keys); + return groupObject; + } + function handleGroupHeaderVisibilityChanged(windowInfo) { + _registry.execute("header-visibility-changed", groupObject); + } + function handleGroupVisibilityChanged(visibile) { + _isVisible = visibile; + _registry.execute("group-visibility-changed", groupObject); + } + function handleGroupHibernateChanged(isHibernatedFlag) { + _isHibernatedFlag = isHibernatedFlag; + } + function _mapToWindowObjects() { + const winObjects = []; + _windowsId.forEach((winId) => { + const windowObject = _mapToWindowObject(winId); + if (typeof windowObject !== "undefined") { + winObjects.push(windowObject); + } + }); + return winObjects; + } + function _mapToWindowObject(windowId) { + return windowStore.get(windowId) ? windowStore.get(windowId).API : undefined; + } + function _getGroupHeaderVisibility() { + const windowWithHiddenHeader = _mapToWindowObjects().find((w) => !w.isGroupHeaderVisible); + const _isGroupHeaderVisible = windowWithHiddenHeader === undefined; + return _isGroupHeaderVisible; + } + function isHibernated() { + return _isHibernatedFlag; + } + function onHeaderVisibilityChanged(callback) { + return _registry.add("header-visibility-changed", callback); + } + function onWindowAdded(callback) { + return _registry.add("window-added", callback); + } + function onWindowRemoved(callback) { + return _registry.add("window-removed", callback); + } + function onVisibilityChanged(callback) { + if (!callback) { + throw new Error("Callback argument is required"); + } + if (callback && typeof callback !== "function") { + throw new Error("Callback argument must be a function"); + } + return _registry.add("group-visibility-changed", callback); + } + function onClosing(callback) { + if (typeof callback !== "function") { + throw new Error("callback must be a function"); + } + const callbackWrap = (success, error, prevent) => { + const promise = callback(prevent); + if (promise === null || promise === void 0 ? void 0 : promise.then) { + promise.then(success).catch(error); + } + else { + success(); + } + }; + return executor.onGroupClosing(callbackWrap, groupObject); + } + const groupObject = { + id, + get windows() { + return windows(); + }, + find, + get isHeaderVisible() { + return _getGroupHeaderVisibility(); + }, + get isHibernated() { + return isHibernated(); + }, + get isVisible() { + return _isVisible; + }, + showHeader: (success, error) => { + return Utils.callbackifyPromise(() => { + return execute("setGroupHeaderVisibility", { windowId: _windowsId[0], options: { toShow: true } }, ..._windowsId.map((w) => `GroupHeaderVisibilityChanged-${w}`)); + }, success, error); + }, + hideHeader: (success, error) => { + return Utils.callbackifyPromise(() => { + return execute("setGroupHeaderVisibility", { windowId: _windowsId[0], options: { toShow: false } }, ..._windowsId.map((w) => `GroupHeaderVisibilityChanged-${w}`)); + }, success, error); + }, + getTitle: async () => { + const r = await executor.execute("getGroupTitle", { windowId: _windowsId[0] }); + return r.title; + }, + setTitle: async (title) => { + if (isNullOrWhiteSpace(title)) { + throw new Error("`title` must not be null or undefined."); + } + return execute("setGroupTitle", { windowId: _windowsId[0], options: { title } }); + }, + capture: (captureOptions) => { + return executor.captureGroup(_windowsId, captureOptions); + }, + maximize: (success, error) => { + return Utils.callbackifyPromise(() => { + return execute("maximizeGroup", { windowId: _windowsId[0] }, ..._windowsId.map((w) => `StateChanged-${w}`)); + }, success, error); + }, + restore: (success, error) => { + return Utils.callbackifyPromise(() => { + return execute("restoreGroup", { windowId: _windowsId[0] }, ..._windowsId.map((w) => `StateChanged-${w}`)); + }, success, error); + }, + show: (activate) => { + if (!isUndefinedOrNull(activate) && !isBoolean(activate)) { + throw new Error("Activate flag must be a boolean!"); + } + activate = !isUndefinedOrNull(activate) ? activate : true; + return executor.executeGroup("showGroup", { + groupId: id, + options: { activate } + }); + }, + hide: () => { + return executor.executeGroup("hideGroup", { + groupId: id + }); + }, + close: () => { + return executor.executeGroup("closeGroup", { + groupId: id + }); + }, + showPopup: (options) => { + return executor.showGroupPopup(id, options); + }, + onHeaderVisibilityChanged, + onWindowAdded, + onWindowRemoved, + onVisibilityChanged, + onClosing, + }; + const internal = { + get windows() { + return _windowsId; + }, + addWindow, + removeWindow, + handleGroupHeaderVisibilityChanged, + handleGroupVisibilityChanged, + handleGroupHibernateChanged + }; + return { + groupAPI: groupObject, + groupInternal: internal, + }; + }; + + var groupsFactory = (environment, logger) => { + const _registry = CallbackRegistryFactory(); + const _groups = {}; + let heardForWindowsCounter = -1; + const windows = windowStore.list; + Object.keys(windows).forEach((k) => { + const win = windows[k]; + const groupId = win.API.groupId; + const winId = win.API.id; + if (!isNullOrWhiteSpace(groupId)) { + addWindow(groupId, winId); + } + }); + windowStore.onRemoved((w) => { + const group = findGroupWrapperByWindow(w.API); + removeWindow(group, w); + }); + environment.onCompositionChanged((windowInfo) => { + handleCompositionChanged(windowInfo); + }); + environment.onGroupHeaderVisibilityChanged((windowInfo) => { + const windowId = windowInfo.windowId; + const group = findGroupByWindow(windowId); + if (typeof group !== "undefined") { + const groupEvents = _groups[group.id]; + if (heardForWindowsCounter === -1) { + heardForWindowsCounter = group.windows.length; + } + heardForWindowsCounter--; + if (heardForWindowsCounter === 0) { + heardForWindowsCounter = -1; + groupEvents.groupInternal.handleGroupHeaderVisibilityChanged(windowInfo); + } + } + }); + environment.onGroupVisibilityChanged((data) => { + const groupEvents = _groups[data.groupId]; + if (groupEvents) { + groupEvents.groupInternal.handleGroupVisibilityChanged(data.visible); + } + }); + environment.onGroupStateChanged((data) => { + const groupWrapper = _groups[data.groupId]; + if (data.state === "hibernated") { + if (groupWrapper === null || groupWrapper === void 0 ? void 0 : groupWrapper.groupAPI) { + groupWrapper.groupInternal.handleGroupHibernateChanged(true); + } + _registry.execute("group-hibernated", data.groupId); + } + else if (data.state === "resumed") { + if (groupWrapper === null || groupWrapper === void 0 ? void 0 : groupWrapper.groupAPI) { + groupWrapper.groupInternal.handleGroupHibernateChanged(false); + } + _registry.execute("group-resumed", groupWrapper.groupAPI); + } + }); + function my() { + var _a; + return findGroupByWindow((_a = environment.myGroup()) !== null && _a !== void 0 ? _a : environment.my()); + } + async function create(options) { + if (isUndefinedOrNull(options)) { + throw new Error(`options must be defined`); + } + if (isUndefinedOrNull(options.groups) || !Array.isArray(options.groups) || options.groups.length === 0) { + throw new Error(`options.groups must be defined`); + } + const { groupIds } = await executor.executeGroup("createGroups", { + options + }); + const groups = groupIds.map((groupId) => { + return waitForGroup(groupId); + }); + return Promise.all(groups); + } + async function close(idOrGroup, options) { + if (isUndefinedOrNull(idOrGroup)) { + throw new Error(`group must be defined`); + } + let groupId = ""; + if (typeof idOrGroup === "string") { + groupId = idOrGroup; + } + else { + groupId = idOrGroup.id; + } + if (isUndefinedOrNull(options)) { + throw new Error(`options must be defined`); + } + await executor.executeGroup("closeGroup", { + groupId, + options + }); + } + function list(success) { + const result = Object.keys(_groups).map((groupId) => { + if (_groups[groupId]) { + return _groups[groupId].groupAPI; + } + }); + if (typeof success === "function") { + success(result); + } + return result; + } + function findGroupByWindow(winId, success, error) { + let windowId; + if (typeof winId === "string") { + windowId = winId; + } + else if (!isUndefinedOrNull(winId)) { + windowId = winId.id; + } + const result = Object.values(_groups).find((groupObj) => { + const group = groupObj.groupAPI; + const wins = group.windows.filter((w) => w.id === windowId); + return wins.length; + }); + if (result) { + if (typeof success === "function") { + success(result.groupAPI); + } + return result.groupAPI; + } + else if (typeof error === "function") { + error(`Cannot find the group of the window.`); + } + } + function waitForGroup(groupId) { + if (!groupId) { + return Promise.reject(new Error(`groupId must be defined`)); + } + return new Promise((res, rej) => { + const groupWrapper = _groups[groupId]; + if (groupWrapper) { + res(groupWrapper.groupAPI); + } + else { + const un = onGroupAdded((group) => { + if (group.id === groupId) { + un(); + res(group); + } + }); + } + }); + } + function getMyGroup() { + var _a; + return waitForGroup((_a = environment.myGroup()) !== null && _a !== void 0 ? _a : environment.my()); + } + async function resume(groupId, activate) { + validateGroupIdArg(groupId); + if (!isUndefinedOrNull(activate) && !isBoolean(activate)) { + throw new Error("Activate flag must be a boolean!"); + } + activate = !isUndefinedOrNull(activate) ? activate : true; + await executor.executeGroup("resumeGroup", { + groupId, + options: { activate } + }); + } + async function hibernate(groupId) { + validateGroupIdArg(groupId); + await executor.executeGroup("hibernateGroup", { + groupId + }); + return groupId; + } + function onGroupAdded(callback) { + return _registry.add("group-added", callback); + } + function onGroupRemoved(callback) { + return _registry.add("group-removed", callback); + } + function onWindowMoved(callback) { + return _registry.add("window-moved", callback); + } + function onHibernated(callback) { + if (!callback) { + throw new Error("Callback argument is required"); + } + if (callback && typeof callback !== "function") { + throw new Error("Callback argument must be a function"); + } + return _registry.add("group-hibernated", callback); + } + function onResumed(callback) { + if (!callback) { + throw new Error("Callback argument is required"); + } + if (callback && typeof callback !== "function") { + throw new Error("Callback argument must be a function"); + } + return _registry.add("group-resumed", callback); + } + function createOrGet(groupId) { + if (!_groups.hasOwnProperty(groupId)) { + const createdGroupWrapper = groupFactory(groupId, environment.executor); + _groups[groupId] = createdGroupWrapper; + const group = createdGroupWrapper.groupAPI; + _registry.execute("group-added", group); + return createdGroupWrapper; + } + else { + return _groups[groupId]; + } + } + function deleteIfEmpty(groupWrapper) { + const group = groupWrapper.groupAPI; + if (group.windows.length === 0) { + delete _groups[group.id]; + executor.clearCallbacks(group.id); + _registry.execute("group-removed", group); + } + } + function addWindow(groupId, winId) { + const group = createOrGet(groupId); + group.groupInternal.addWindow(winId); + return group; + } + function removeWindow(group, win) { + if (!group) { + return; + } + group.groupInternal.removeWindow(win); + deleteIfEmpty(group); + } + function handleCompositionChanged(state) { + const groupId = state.groupId; + const windowId = state.windowId; + const win = windowStore.get(windowId); + if (!win) { + return; + } + const currentGroup = findGroupWrapperByWindow(win.API); + if (isUndefinedOrNull(groupId)) { + removeWindow(currentGroup, win); + return; + } + if (isUndefinedOrNull(currentGroup) && !isUndefinedOrNull(groupId)) { + addWindow(groupId, win.API.id); + return; + } + if (currentGroup.groupAPI.id !== groupId) { + moveWindow(win, currentGroup.groupAPI.id, groupId); + } + } + function moveWindow(win, from, to) { + const winId = win.API.id; + const fromGroup = _groups[from]; + removeWindow(fromGroup, win); + const toGroup = addWindow(to, winId); + win.Events.handleGroupChanged(toGroup.groupAPI, fromGroup.groupAPI); + _registry.execute("window-moved", winId, from, to); + } + function findGroupWrapperByWindow(winId) { + let windowId; + if (typeof winId === "string") { + windowId = winId; + } + else if (!isUndefinedOrNull(winId)) { + windowId = winId.id; + } + return Object.values(_groups).find((groupObj) => { + const groupInternal = groupObj.groupInternal; + const wins = groupInternal.windows.filter((id) => id === windowId); + return wins.length; + }); + } + function validateGroupIdArg(groupId) { + if (!groupId || typeof groupId !== "string") { + throw new Error("Please provide a valid Group ID as a non-empty string!"); + } + } + const groups = { + get my() { + return my(); + }, + create, + close, + list, + findGroupByWindow, + waitForGroup, + getMyGroup, + onGroupAdded, + onGroupRemoved, + hibernate, + resume, + onHibernated, + onResumed + }; + const events = { onWindowMoved }; + return { + groupsAPI: groups, + groupsEvents: events, + }; + }; + + var WindowsFactory = (agm, logger, appManagerGetter, displayAPIGetter, channelsGetter, gdMajorVersion) => { + const _registry = CallbackRegistryFactory(); + const _logger = logger; + let groups; + let environment; + windowStore.init(_logger); + const isReady = new Promise((resolve, reject) => { + envDetector(agm, _logger, appManagerGetter, displayAPIGetter, channelsGetter, gdMajorVersion) + .then((env) => { + environment = env; + groups = groupsFactory(env); + jumpListManager.init(env.executor, agm, _logger); + resolve(); + }) + .catch((e) => { + const err = `Timed out waiting for connection to Glue42 Enterprise: Error: ${e.message}`; + _logger.error(err, e); + reject(new Error(err)); + }); + }); + function ready() { + return isReady; + } + function my() { + const myWindow = windowStore.getIfReady(environment.my()); + return myWindow ? myWindow.API : undefined; + } + function open(name, url, options, success, error) { + return Utils.callbackifyPromise(() => { + if (isNullOrWhiteSpace(name)) { + throw new Error("The window name is missing."); + } + if (isNullOrWhiteSpace(url)) { + throw new Error("The window URL is missing."); + } + if (!isUndefinedOrNull(options)) { + const optionsAsAny = options; + for (const prop of ["minHeight", "maxHeight", "minWidth", "maxWidth", "width", "height", "top", "left"]) { + if (prop in optionsAsAny) { + const value = optionsAsAny[prop]; + if (isUndefinedOrNull(value)) { + delete optionsAsAny[prop]; + continue; + } + if (!isNumber(value)) { + const errMessage = `${prop} must be a number`; + throw new Error(errMessage); + } + if (optionsAsAny[prop] === "width" || optionsAsAny[prop] === "height") { + if (value <= 0) { + const errMessage = `${prop} must be a positive number`; + throw new Error(errMessage); + } + } + } + } + } + return environment.open(name, url, options); + }, success, error); + } + function find(name, success, error) { + const windows = windowStore.list; + const windowsForListing = Object.keys(windows).reduce((memo, winId) => { + var _a; + const window = windows[winId]; + if (((_a = window === null || window === void 0 ? void 0 : window.API) === null || _a === void 0 ? void 0 : _a.name) === name) { + memo.push(window.API); + } + return memo; + }, []); + const win = windowsForListing[0]; + if (win) { + if (typeof success === "function") { + success(windowsForListing[0]); + } + return windowsForListing[0]; + } + else { + if (typeof error === "function") { + error("There is no window with name:" + name); + } + } + } + function findById(id, success, error) { + const windows = windowStore.list; + const windowsForListing = Object.keys(windows).reduce((memo, winId) => { + const window = windows[winId]; + if (typeof window !== "undefined" && window.API.id === id) { + memo.push(window.API); + } + return memo; + }, []); + const win = windowsForListing[0]; + if (win) { + if (typeof success === "function") { + success(windowsForListing[0]); + } + return windowsForListing[0]; + } + else { + if (typeof error === "function") { + error("There is no window with such id:" + id); + } + } + } + function list(success) { + const windows = windowStore.list; + const windowsForListing = Object.keys(windows) + .map((k) => { + return windows[k].API; + }); + if (typeof success !== "function") { + return windowsForListing; + } + success(windowsForListing); + } + function configure(options) { + const win = my(); + const winId = win ? win.id : ""; + return executor.configure(winId, options); + } + function autoArrange(displayId) { + return executor.autoArrange(displayId); + } + function windowAdded(callback) { + return _registry.add("window-added", callback); + } + function windowRemoved(callback) { + return _registry.add("window-removed", callback); + } + function tabAttached(callback) { + let unsubFunc; + let unsubscribed = false; + isReady.then(() => { + if (unsubscribed) { + return; + } + unsubFunc = environment.tabAttached(callback); + }); + return () => { + unsubscribed = true; + if (unsubFunc) { + unsubFunc(); + } + }; + } + function tabDetached(callback) { + let unsubFunc; + let unsubscribed = false; + isReady.then(() => { + if (unsubscribed) { + return; + } + unsubFunc = environment.tabDetached(callback); + }); + return () => { + unsubscribed = true; + if (unsubFunc) { + unsubFunc(); + } + }; + } + function onWindowFrameColorChanged(callback) { + let unsubFunc; + let unsubscribed = false; + isReady.then(() => { + if (unsubscribed) { + return; + } + unsubFunc = environment.onWindowFrameColorChanged(callback); + }); + return () => { + unsubscribed = true; + if (unsubFunc) { + unsubFunc(); + } + }; + } + function onWindowGotFocus(callback) { + let unsubFunc; + let unsubscribed = false; + isReady.then(() => { + if (unsubscribed) { + return; + } + unsubFunc = environment.onWindowGotFocus(callback); + }); + return () => { + unsubscribed = true; + if (unsubFunc) { + unsubFunc(); + } + }; + } + function onWindowLostFocus(callback) { + let unsubFunc; + let unsubscribed = false; + isReady.then(() => { + if (unsubscribed) { + return; + } + unsubFunc = environment.onWindowLostFocus(callback); + }); + return () => { + unsubscribed = true; + if (unsubFunc) { + unsubFunc(); + } + }; + } + function onArrangementChanged(callback) { + return environment.onWindowsAutoArrangeChanged(callback); + } + function onEvent(callback) { + let unsubFunc; + let unsubscribed = false; + isReady.then(() => { + if (unsubscribed) { + return; + } + unsubFunc = environment.onEvent(callback); + }); + return () => { + unsubscribed = true; + if (unsubFunc) { + unsubFunc(); + } + }; + } + function createFlydown(targetId, config) { + return environment.createFlydown(targetId, config); + } + function showPopup(targetId, config) { + return environment.showPopup(targetId, config); + } + function handleWindowAdded(w) { + _registry.execute("window-added", w.API); + } + function handleWindowRemoved(w) { + _registry.execute("window-removed", w.API); + } + windowStore.onReadyWindow(handleWindowAdded); + windowStore.onRemoved(handleWindowRemoved); + return { + my, + open, + find, + findById, + list, + ready, + onWindowAdded: windowAdded, + windowAdded, + onWindowRemoved: windowRemoved, + windowRemoved, + onTabAttached: tabAttached, + onTabDetached: tabDetached, + onWindowFrameColorChanged, + onArrangementChanged, + get groups() { + return groups.groupsAPI; + }, + onWindowGotFocus, + onWindowLostFocus, + onEvent, + createFlydown, + showPopup, + configure, + autoArrange + }; + }; + + class LayoutStore { + constructor() { + this.layouts = []; + } + removeWhere(condition) { + this.layouts = this.layouts.filter(condition); + } + removeAll() { + this.layouts = []; + } + add(item) { + this.layouts.push(item); + } + get all() { + return this.layouts; + } + where(condition) { + return this.layouts.filter(condition); + } + first(condition) { + return this.where(condition)[0]; + } + } + var store = new LayoutStore(); + + const SaveContextMethodName = "T42.HC.GetSaveContext"; + class ContextProvider { + constructor(config, activitiesGetter, callbacks, logger) { + this.config = config; + this.activitiesGetter = activitiesGetter; + this.callbacks = callbacks; + this.logger = logger; + this.interop = config.agm; + this.registerRequestMethods(); + } + onSaveRequested(callback) { + return this.callbacks.add("saveRequested", callback); + } + isActivityOwner() { + if (typeof htmlContainer !== "undefined") { + const context = htmlContainer.getContext(); + return context && context._t42 && context._t42.activityIsOwner; + } + const activities = this.activitiesGetter(); + if (!activities) { + return false; + } + if (!activities.inActivity) { + return false; + } + const myWindow = activities.my.window; + const myActivity = activities.my.activity; + if (!myActivity && !myWindow) { + return false; + } + return myActivity.owner.id === myWindow.id; + } + registerRequestMethods() { + this.interop.register(SaveContextMethodName, (args) => { + const usersCbs = this.callbacks.execute("saveRequested", args); + if ((usersCbs === null || usersCbs === void 0 ? void 0 : usersCbs.length) > 1) { + this.logger.warn(`Multiple subscriptions for "glue.layouts.onSaveRequested" - only the first one will be used`); + } + const requestResult = usersCbs[0]; + const autoSaveWindowContext = this.config.autoSaveWindowContext; + if (typeof autoSaveWindowContext === "boolean" && autoSaveWindowContext) { + return { autoSaveWindowContext }; + } + else if (Array.isArray(autoSaveWindowContext) && autoSaveWindowContext.length > 0) { + return { autoSaveWindowContext }; + } + const result = { windowContext: requestResult === null || requestResult === void 0 ? void 0 : requestResult.windowContext, activityContext: undefined }; + if (this.isActivityOwner()) { + result.activityContext = requestResult === null || requestResult === void 0 ? void 0 : requestResult.activityContext; + } + return result; + }); + } + } + + function transformACSLayout(something) { + if (!something) { + return something; + } + if (Array.isArray(something)) { + return something.map((item) => { + return transformACSLayout(item); + }); + } + if (typeof something === "string" || typeof something === "number" || typeof something === "boolean") { + return something; + } + const initial = {}; + return Object.keys(something).reduce((accumulator, current) => { + var _a; + const value = something[current]; + const convertedValue = transformACSLayout(value); + let key = current; + if (((_a = current[0]) === null || _a === void 0 ? void 0 : _a.toLowerCase()) !== current[0]) { + key = current[0].toLowerCase() + current.substr(1); + } + accumulator[key] = convertedValue; + return accumulator; + }, initial); + } + + class LayoutImpl { + constructor(data) { + this.name = data.name; + this.type = data.type; + this.components = data.components; + this.context = data.context; + this.metadata = data.metadata; + this.version = data.version; + this.displays = data.displays; + } + } + + var main = {}; + + var application = {}; + + /** + * This file was automatically generated by json-schema-to-typescript. + * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file, + * and run json-schema-to-typescript to regenerate this file. + */ + Object.defineProperty(application, "__esModule", { value: true }); + + var system = {}; + + /** + * This file was automatically generated by json-schema-to-typescript. + * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file, + * and run json-schema-to-typescript to regenerate this file. + */ + Object.defineProperty(system, "__esModule", { value: true }); + + var layout = {}; + + Object.defineProperty(layout, "__esModule", { value: true }); + layout.SwimlaneItemType = layout.LayoutType = void 0; + var LayoutType; + (function (LayoutType) { + LayoutType["Global"] = "Global"; + LayoutType["Activity"] = "Activity"; + LayoutType["ApplicationDefault"] = "ApplicationDefault"; + LayoutType["Swimlane"] = "Swimlane"; + LayoutType["Workspaces"] = "Workspace"; + })(LayoutType || (layout.LayoutType = LayoutType = {})); + var SwimlaneItemType; + (function (SwimlaneItemType) { + SwimlaneItemType["Tab"] = "tab"; + SwimlaneItemType["Window"] = "window"; + SwimlaneItemType["Canvas"] = "canvas"; + })(SwimlaneItemType || (layout.SwimlaneItemType = SwimlaneItemType = {})); + + var swTheme = {}; + + /** + * This file was automatically generated by json-schema-to-typescript. + * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file, + * and run json-schema-to-typescript to regenerate this file. + */ + Object.defineProperty(swTheme, "__esModule", { value: true }); + + var swConfiguration = {}; + + /** + * This file was automatically generated by json-schema-to-typescript. + * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file, + * and run json-schema-to-typescript to regenerate this file. + */ + Object.defineProperty(swConfiguration, "__esModule", { value: true }); + + (function (exports) { + var __createBinding = (commonjsGlobal && commonjsGlobal.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; + })); + var __exportStar = (commonjsGlobal && commonjsGlobal.__exportStar) || function(m, exports) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); + }; + Object.defineProperty(exports, "__esModule", { value: true }); + // export { SchemaValidator } from "./validator"; + // export { FileProvider } from "./fileProvider"; + // export { SchemaProvider } from "./provider"; + __exportStar(application, exports); + __exportStar(system, exports); + __exportStar(layout, exports); + __exportStar(swTheme, exports); + __exportStar(swConfiguration, exports); + + } (main)); + + const LayoutsCommandMethod = "T42.ACS.Command"; + class LayoutsAPIImpl { + constructor(config, stream, callbacks, logger) { + this.config = config; + this.stream = stream; + this.callbacks = callbacks; + this.isRegisterMethodForLayoutModified = false; + this.appManager = config.appManager; + this.provider = new ContextProvider(config, config.activityGetter, callbacks, logger); + stream.subscribe(); + } + async setDefaultGlobal(name) { + const methodName = "SelectDefaultLayout"; + await this.invokeMethodCore(methodName, { name }); + return; + } + async clearDefaultGlobal() { + const methodName = "DeselectDefaultLayout"; + await this.invokeMethodCore(methodName); + return; + } + async getDefaultGlobal() { + const methodName = "GetDefaultLayout"; + const result = await this.invokeMethodCore(methodName); + const layout = result.returned; + if (layout === null || layout === undefined || (typeof layout === 'object' && Object.keys(layout).length === 0)) { + return undefined; + } + return objectClone(this.isSlimMode() ? layout : this.list().find((l) => l.name === layout.name && l.type === layout.type)); + } + ready() { + if (this.config.mode === "fullWaitSnapshot") { + return this.stream.gotSnapshot; + } + return this.stream.ready; + } + save(layout) { + return new Promise((resolve, reject) => { + var _a, _b; + this.verifyNotSlimMode(); + if (isUndefinedOrNull(layout)) { + return reject(new Error("layout is required")); + } + if (isNullOrWhiteSpace(layout.name)) { + return reject(new Error("layout.name argument is required")); + } + if (isNullOrWhiteSpace(layout.type)) { + layout.type = "Global"; + } + if (!isNullOrWhiteSpace(layout.activityId)) { + layout.type = "Activity"; + } + const layoutObject = { + name: layout.name, + type: layout.type, + context: (_a = layout.context) !== null && _a !== void 0 ? _a : {}, + metadata: (_b = layout.metadata) !== null && _b !== void 0 ? _b : {}, + options: {}, + }; + if (layout.type === "Activity") { + let actId = layout.activityId; + if (!actId) { + if (!this.appManager.myInstance.inActivity) { + return reject(new Error("Current application is not in activity. Cannot save activity layout for it.")); + } + actId = this.appManager.myInstance.activityId; + } + layoutObject.activityId = actId; + } + else if (layout.type === "Global") { + if (Array.isArray(layout.ignoreInstances)) { + layoutObject.options.ignoreInstances = layout.ignoreInstances; + } + if (Array.isArray(layout.instances)) { + layoutObject.options.instances = layout.instances; + } + if (typeof layout.setAsCurrent === "boolean") { + layoutObject.options.setAsCurrent = layout.setAsCurrent; + } + } + else { + return reject(new Error(`layout type ${layout.type} is not supported`)); + } + this.invokeMethodAndTrack("SaveLayout", layoutObject, resolve, reject); + }); + } + restore(options) { + return new Promise((resolve, reject) => { + var _a, _b, _c; + this.verifyNotSlimMode(); + if (isUndefinedOrNull(options)) { + return reject(new Error("options argument is required")); + } + if (isNullOrWhiteSpace(options.name)) { + return reject(new Error("options.name argument is required")); + } + if (isNullOrWhiteSpace(options.type)) { + options.type = "Global"; + } + if (!isNullOrWhiteSpace(options.activityIdToJoin)) { + options.type = "Activity"; + } + if (options.type === "Activity") { + if (isUndefinedOrNull(options.setActivityContext)) { + options.setActivityContext = true; + } + if (typeof options.setActivityContext !== "boolean") { + return reject(new Error("`setActivityContext` must hold a boolean value.")); + } + options.activityIdToJoin = (_a = options.activityIdToJoin) !== null && _a !== void 0 ? _a : this.appManager.myInstance.activityId; + } + if (!isUndefinedOrNull(options.closeRunningInstance)) { + options.closeRunningInstances = options.closeRunningInstance; + } + if (isUndefinedOrNull(options.closeRunningInstances)) { + options.closeRunningInstances = true; + } + if (!isBoolean(options.closeRunningInstances)) { + return reject(new Error("`closeRunningInstances` must hold a boolean value.")); + } + if (isUndefinedOrNull(options.closeMe)) { + options.closeMe = options.closeRunningInstances; + } + if (!isBoolean(options.closeMe)) { + return reject(new Error("`closeMe` must hold a boolean value.")); + } + if (!isUndefinedOrNull(options.context) && !isObject(options.context)) { + return reject(new Error("`context` must hold an object value.")); + } + if (!isUndefinedOrNull(options.timeout) && typeof options.timeout !== "number") { + return reject(new Error("`timeout` must hold an number value.")); + } + options.context = (_b = options.context) !== null && _b !== void 0 ? _b : {}; + const restoreOptions = { + activityToJoin: options.activityIdToJoin, + setActivityContext: options.setActivityContext, + ignoreActivityWindowTypes: options.ignoreActivityWindowTypes, + reuseExistingWindows: options.reuseWindows, + closeRunningInstances: options.closeRunningInstances, + excludeFromClosing: options.closeMe ? [] : [(_c = this.appManager.myInstance) === null || _c === void 0 ? void 0 : _c.id] + }; + const arg = { + type: options.type, + name: options.name, + context: options.context, + options: restoreOptions + }; + if (options.timeout) { + arg.timeout = options.timeout; + } + this.invokeMethodAndTrack("RestoreLayout", arg, resolve, reject, true); + }); + } + reset(options) { + return new Promise((resolve, reject) => { + this.verifyNotSlimMode(); + if (typeof options !== "object") { + return reject(new Error("options argument is required")); + } + if (isNullOrWhiteSpace(options.layoutId)) { + return reject(new Error("options.layoutId argument is required")); + } + const msg = { + ...options + }; + this.invokeMethodAndTrack("ResetLayout", msg, resolve, reject, true); + }); + } + remove(type, name) { + return new Promise((resolve, reject) => { + this.verifyNotSlimMode(); + if (!name) { + return reject(new Error("name argument is required")); + } + if (!type) { + return reject(new Error("type argument is required")); + } + const msg = { + type, + name, + }; + this.invokeMethodAndTrack("RemoveLayout", msg, resolve, reject); + }); + } + list() { + this.verifyNotSlimMode(); + return objectClone(store.all); + } + import(layouts, mode) { + return new Promise((resolve, reject) => { + this.verifyNotSlimMode(); + if (!isUndefinedOrNull(mode)) { + if (mode !== "merge" && mode !== "replace") { + return reject(new Error(`${mode} is not supported - only "merge" and "replace"`)); + } + } + if (!Array.isArray(layouts)) { + return reject(new Error("layouts arguments is not an array")); + } + const msg = { + mode: mode || "replace", + layouts + }; + this.invokeMethodAndTrack("ImportLayouts", msg, resolve, reject, true); + }); + } + export(layoutType) { + return new Promise((resolve, reject) => { + var _a; + if (!isUndefinedOrNull(layoutType) && !((_a = Object.values(main.LayoutType)) === null || _a === void 0 ? void 0 : _a.includes(layoutType))) { + return reject(new Error(`${layoutType} is not a supported Layout Type`)); + } + const handleResult = (result) => { + let layouts = this.getObjectValues(result.Layouts).map((t) => new LayoutImpl(transformACSLayout(t))); + if (layoutType) { + layouts = layouts.filter((l) => l.type === layoutType); + } + resolve(layouts); + }; + this.invokeMethodAndTrack("ExportLayouts", {}, handleResult, reject, true); + }); + } + rename(layout, newName) { + return new Promise((resolve, reject) => { + this.verifyNotSlimMode(); + if (!layout) { + return reject(new Error("layout argument is required")); + } + if (!layout.name) { + return reject(new Error("name argument is required")); + } + if (!layout.type) { + return reject(new Error("type argument is required")); + } + const msg = { type: layout.type, oldName: layout.name, newName }; + this.invokeMethodAndTrack("RenameLayout", msg, resolve, reject); + }); + } + updateMetadata(layout) { + return new Promise((resolve, reject) => { + if (!layout) { + return reject(new Error("layout argument is required")); + } + if (!layout.name) { + return reject(new Error("name argument is required")); + } + if (!layout.type) { + return reject(new Error("type argument is required")); + } + if (!layout.metadata) { + return reject(new Error("metadata argument is required")); + } + const layoutObject = { + name: layout.name, + type: layout.type, + metadata: layout.metadata + }; + this.invokeMethodAndTrack("UpdateMetadata", layoutObject, resolve, reject, true); + }); + } + hibernate(name, options) { + return new Promise((resolve, reject) => { + if (!name) { + return reject(new Error("name cannot be empty")); + } + options = options || {}; + const request = { + name, + type: "Global", + context: options.context || {}, + metadata: options.metadata || {}, + }; + this.invokeMethodAndTrack("HibernateLayout", request, resolve, reject, true); + }); + } + resume(name, context, options) { + return new Promise((resolve, reject) => { + if (!name) { + return reject(new Error("name cannot be empty")); + } + const request = { + name, + type: "Global", + context, + ...options + }; + this.invokeMethodAndTrack("ResumeLayout", request, resolve, reject, true); + }); + } + async getCurrentLayout() { + const methodName = "GetCurrentLayout"; + const result = await this.invokeMethodCore(methodName); + let layout = result.returned.layout; + if (!layout) { + return undefined; + } + if (!this.isSlimMode()) { + layout = this.list().find((l) => l.name === layout.name && l.type === layout.type); + } + return objectClone(layout); + } + getRestoredLayoutsInfo() { + return new Promise((resolve, reject) => { + const methodName = "GetRestoredLayoutsInfo"; + this.invokeMethodCore(methodName) + .then((result) => { + const restoredLayouts = result.returned; + resolve(restoredLayouts); + }) + .catch(reject); + }); + } + onAdded(callback) { + const result = this.callbacks.add("added", callback); + if (store.all.length > 0) { + store.all.forEach((layout) => { + try { + callback(layout); + } + catch (err) { } + }); + } + return result; + } + onRemoved(callback) { + return this.callbacks.add("removed", callback); + } + onChanged(callback) { + return this.callbacks.add("changed", callback); + } + onRestored(callback) { + return this.callbacks.add("restored", callback); + } + onRenamed(callback) { + return this.callbacks.add("renamed", callback); + } + onEvent(callback) { + return this.stream.onEvent(callback); + } + onSaveRequested(callback) { + return this.provider.onSaveRequested(callback); + } + onLayoutModified(callback) { + if (this.isRegisterMethodForLayoutModified === false) { + this.isRegisterMethodForLayoutModified = true; + this.registerMethodForLayoutModified(); + } + return this.callbacks.add("layout-modified", callback); + } + updateAppContextInCurrent(context) { + return new Promise((resolve, reject) => { + if (context && typeof context !== "object") { + return reject(new Error("Context must be an object")); + } + context = context !== null && context !== void 0 ? context : {}; + const request = { + context + }; + this.invokeMethodAndTrack("UpdateLayoutComponentContext", request, resolve, reject, true); + }); + } + updateDefaultContext(context) { + return new Promise((resolve, reject) => { + if (context && typeof context !== "object") { + return reject(new Error("Context must be an object")); + } + context = context !== null && context !== void 0 ? context : {}; + const request = { + context + }; + this.invokeMethodAndTrack("UpdateDefaultContext", request, resolve, reject, true); + }); + } + async get(name, type) { + const matching = this.list().find((l) => l.name === name && l.type === type); + if (!matching) { + throw new Error(`cannot find layout with name=${name} and type=${type}`); + } + return objectClone(matching); + } + async getAll(type) { + var _a; + if (!isUndefinedOrNull(type) && !((_a = Object.values(main.LayoutType)) === null || _a === void 0 ? void 0 : _a.includes(type))) { + throw new Error((`${type} is not a supported Layout Type`)); + } + const matching = this.list().filter((l) => type === l.type); + return objectClone(matching); + } + async forceRefresh() { + const methodName = "RefreshLayouts"; + await this.invokeMethodCore(methodName); + } + isSlimMode() { + return this.config.mode === "slim"; + } + verifyNotSlimMode() { + if (this.isSlimMode()) { + throw Error("Operation not allowed in slim mode. Run in full mode."); + } + } + async registerMethodForLayoutModified() { + await this.config.agm.register("T42.ACS.LayoutModified", (args, caller) => { + this.callbacks.execute("layout-modified", args); + }); + } + invokeMethodAndTrack(methodName, args, resolve, reject, skipStreamEvent) { + let streamEventReceived = skipStreamEvent; + let agmResult; + const token = Utils.generateId(); + args.token = token; + const handleResult = () => { + if (streamEventReceived && agmResult) { + resolve(agmResult); + } + }; + const methodResponseTimeoutMs = 120 * 1000; + if (!skipStreamEvent) { + this.stream.waitFor(token, methodResponseTimeoutMs) + .then(() => { + streamEventReceived = true; + handleResult(); + }) + .catch((err) => { + reject(err); + }); + } + const responseHandler = (result) => { + if (!result.returned) { + return reject(new Error("No result from method " + methodName)); + } + if (result.returned.status && (result.returned.status !== "Success" && result.returned.status !== "PartialSuccess")) { + if (typeof (result.returned) === "string") { + return reject(new Error(result.returned)); + } + else if (typeof (result.returned) === "object") { + if (result.returned.status && result.returned.failed) { + return reject(new Error(`${result.returned.status}: ${JSON.stringify(result.returned.failed)}`)); + } + else { + return reject(new Error(result.returned)); + } + } + } + agmResult = result.returned; + handleResult(); + }; + this.invokeMethodCore(methodName, args, "best", { methodResponseTimeoutMs }) + .then(responseHandler) + .catch((err) => reject(err)); + } + async invokeMethodCore(methodName, args, target, options) { + options = options !== null && options !== void 0 ? options : {}; + if (typeof options.methodResponseTimeoutMs === "undefined") { + options.methodResponseTimeoutMs = INTEROP_METHOD_WAIT_TIMEOUT_MS; + } + if (typeof options.waitTimeoutMs === "undefined") { + options.waitTimeoutMs = INTEROP_METHOD_WAIT_TIMEOUT_MS; + } + if (this.isCommandMethodPresent()) { + return await this.config.agm.invoke(LayoutsCommandMethod, { command: methodName, data: args }, target, options); + } + else { + return await this.config.agm.invoke(`T42.ACS.${methodName}`, args, target, options); + } + } + getObjectValues(obj) { + if (!obj) { + return []; + } + return Object.keys(obj).map((k) => obj[k]); + } + isCommandMethodPresent() { + return this.config.agm.methods().some((method) => method.name === LayoutsCommandMethod); + } + } + + class ACSStream { + constructor(agm, callbacks) { + this.agm = agm; + this.callbacks = callbacks; + this.StreamName = "T42.ACS.OnLayoutEvent"; + this.ready = new Promise((resolve, reject) => { + this.resolveReady = resolve; + this.rejectReady = reject; + }); + this.gotSnapshot = new Promise((resolve, reject) => { + this.resolveGotSnapshot = resolve; + this.rejectGotSnapshot = reject; + }); + } + subscribe(noRetry) { + const transform = (obj) => { + return this.getObjectValues(obj).map((t) => transformACSLayout(t)); + }; + if (!this.checkForLayoutEventMethod()) { + if (noRetry) { + this.resolveReady(); + } + setTimeout(() => { + this.subscribe(true); + }, 500); + } + else { + this.agm.subscribe(this.StreamName, { waitTimeoutMs: 10000 }) + .then((subs) => { + subs.onData((args) => { + const data = args.data; + if (data.IsSnapshot) { + this.resolveGotSnapshot(); + } + this.addLayouts(transform(data.OnLayoutAdded), data.IsSnapshot); + this.removeLayouts(transform(data.OnLayoutRemoved)); + this.changeLayouts(transform(data.OnLayoutChanged)); + this.renameLayouts(transform(data.OnLayoutRenamed)); + this.restoredLayout(transform(data.OnLayoutRestored)); + this.callbacks.execute("streamEvent", data); + }); + subs.onFailed((err) => { + const msg = `Can not subscribe to "${this.StreamName}" stream - ${JSON.stringify(err)}`; + this.rejectReady(msg); + this.rejectGotSnapshot(msg); + }); + this.resolveReady(); + }) + .catch((err) => { + const msg = `Error subscribing to "${this.StreamName}" stream - ${JSON.stringify(err)}`; + this.rejectReady(msg); + this.rejectGotSnapshot(msg); + }); + } + } + onEvent(callback) { + return this.callbacks.add("streamEvent", callback); + } + waitFor(token, timeout) { + if (!timeout) { + timeout = 30000; + } + return new Promise((resolve, reject) => { + let done = false; + const unsubscribe = this.onEvent((streamEvent) => { + if (streamEvent.Token === token) { + done = true; + unsubscribe(); + resolve(); + } + }); + setTimeout(() => { + if (!done) { + reject("timed out"); + } + }, timeout); + }); + } + checkForLayoutEventMethod() { + try { + return this.agm + .methods() + .map((m) => m.name) + .indexOf(this.StreamName) !== -1; + } + catch (e) { + return false; + } + } + addLayouts(layoutsData, isSnapshot) { + if (!layoutsData) { + return; + } + const createAndNotifyLayout = (layoutData) => { + const layout = new LayoutImpl(layoutData); + store.add(layout); + this.callbacks.execute("added", layout); + }; + layoutsData.forEach((layoutData) => { + if (isSnapshot) { + const found = store.first((existingLayout) => this.compareLayouts(existingLayout, layoutData)); + if (!found) { + createAndNotifyLayout(layoutData); + } + } + else { + createAndNotifyLayout(layoutData); + } + }); + } + removeLayouts(removedLayouts) { + if (!removedLayouts) { + return; + } + removedLayouts.forEach((removedLayout) => { + store.removeWhere((existingLayout) => !this.compareLayouts(existingLayout, removedLayout)); + this.callbacks.execute("removed", removedLayout); + }); + } + changeLayouts(changedLayouts) { + if (!changedLayouts) { + return; + } + changedLayouts.forEach((changedLayout) => { + store.removeWhere((existingLayout) => !this.compareLayouts(existingLayout, changedLayout)); + store.add(new LayoutImpl(changedLayout)); + this.callbacks.execute("changed", changedLayout); + }); + } + renameLayouts(renamedLayouts) { + if (!renamedLayouts) { + return; + } + renamedLayouts.forEach((renamedLayout) => { + const existingLayout = store.first((current) => this.compareLayouts(current, { type: renamedLayout.type, name: renamedLayout.oldName })); + if (!existingLayout) { + throw Error(`received rename event for unknown layout with type ${renamedLayout.type} and name ${renamedLayout.oldName}`); + } + existingLayout.name = renamedLayout.newName; + this.callbacks.execute("renamed", existingLayout); + }); + } + compareLayouts(layout1, layout2) { + return layout1.name === layout2.name && layout1.type === layout2.type; + } + getObjectValues(obj) { + if (!obj) { + return []; + } + return Object.keys(obj).map((k) => obj[k]); + } + restoredLayout(restoredLayouts) { + if (!restoredLayouts) { + return; + } + restoredLayouts.forEach((restoredLayout) => { + const existingLayout = store.first((current) => this.compareLayouts(current, { type: restoredLayout.type, name: restoredLayout.name })); + this.callbacks.execute("restored", existingLayout); + }); + } + } + + function LayoutsFactory (config) { + if (!config.agm) { + throw Error("config.agm is required"); + } + if (!config.logger) { + throw Error("config.logger is required"); + } + config.mode = config.mode || "slim"; + const logger = config.logger; + const callbacks = CallbackRegistryFactory(); + let acsStream; + if (config.mode === "full" || "fullWaitSnapshot") { + acsStream = new ACSStream(config.agm, callbacks); + } + return new LayoutsAPIImpl(config, acsStream, callbacks, logger); + } + + const T42DisplayCommand = "T42.Displays.Command"; + const T42DisplayOnEvent = "T42.Displays.OnEvent"; + class DisplayManager { + constructor(_agm, _logger) { + this._agm = _agm; + this._logger = _logger; + this._registry = CallbackRegistryFactory(); + this._registered = false; + this.all = async () => { + const displays = await this.callGD(DisplayCommand.GetAll, {}); + return displays.map(this.decorateDisplay); + }; + this.get = async (id) => { + const display = await this.callGD(DisplayCommand.Get, { id }); + return this.decorateDisplay(display); + }; + this.getPrimary = async () => { + const primary = (await this.all()).find((d) => d.isPrimary); + return primary; + }; + this.capture = async (options) => { + const screenshot = await this.callGD(DisplayCommand.Capture, { ...options }); + return screenshot; + }; + this.captureAll = async (options) => { + const screenshots = await this.callGD(DisplayCommand.CaptureAll, { ...options }); + return screenshots; + }; + this.getMousePosition = async () => { + const point = await this.callGD(DisplayCommand.GetMousePosition); + return point; + }; + this.callGD = async (command, options) => { + const invocationResult = await this._agm.invoke(T42DisplayCommand, { options: { ...options }, command }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return invocationResult.returned.data; + }; + this.decorateDisplay = (original) => { + const decoratedDisplay = { + ...original, + capture: (size) => this.capture({ id: original.id, size }) + }; + const workAreaAsAny = decoratedDisplay.workArea; + workAreaAsAny.x = workAreaAsAny.left; + workAreaAsAny.y = decoratedDisplay.workArea.top; + return decoratedDisplay; + }; + } + getByWindowId(id) { + const current = this.callGD(DisplayCommand.GetByWindowId, { id }); + return current; + } + onDisplayChanged(cb) { + this.register(); + return this._registry.add("on-display-changed", cb); + } + register() { + if (this._registered) { + return; + } + this._registered = true; + this._agm.register(T42DisplayOnEvent, (args, caller) => { + const event = args.event; + const data = args.data; + switch (event) { + case "display-changed": + this._registry.execute("on-display-changed", data.displays.map(this.decorateDisplay)); + break; + default: + this._logger.warn(`unknown event - ${event}`); + break; + } + }); + } + } + var DisplayCommand; + (function (DisplayCommand) { + DisplayCommand["Capture"] = "capture"; + DisplayCommand["CaptureAll"] = "captureAll"; + DisplayCommand["GetAll"] = "getAll"; + DisplayCommand["Get"] = "get"; + DisplayCommand["GetByWindowId"] = "getByWindowId"; + DisplayCommand["GetMousePosition"] = "getMousePosition"; + })(DisplayCommand || (DisplayCommand = {})); + + class SingleChannelID { + constructor(channel) { + this.channel = channel; + } + get isJoinedToAnyChannel() { + return !!this.channel; + } + isOnChannel(channel) { + return this.channel === channel; + } + leaveChannel(channel) { + if (channel === undefined || this.channel === channel) { + this.channel = undefined; + } + } + joinChannel(channel) { + this.channel = channel; + } + all() { + if (this.channel) { + return [this.channel]; + } + return []; + } + toString() { + return this.channel; + } + equals(other) { + if (other instanceof SingleChannelID) { + return this.channel === other.channel; + } + return false; + } + } + class MultiChannelId { + constructor(channels) { + this.ChannelDelimiter = "+++"; + if (!channels) { + this.channels = []; + } + else if (typeof channels === "string") { + this.channels = channels === null || channels === void 0 ? void 0 : channels.split(this.ChannelDelimiter).filter(Boolean); + } + else { + this.channels = (channels !== null && channels !== void 0 ? channels : []).filter(Boolean); + } + } + get isJoinedToAnyChannel() { + return this.channels.length > 0; + } + isOnChannel(channel) { + return this.channels.includes(channel); + } + joinChannel(channel) { + const newChannels = new MultiChannelId(channel); + newChannels.all().forEach((newChannel) => { + if (!this.channels.includes(newChannel)) { + this.channels.push(newChannel); + } + }); + } + leaveChannel(channel) { + const channelsToLeave = new MultiChannelId(channel !== null && channel !== void 0 ? channel : this.channels); + channelsToLeave.all().forEach((c) => { + this.channels = this.channels.filter((ch) => ch !== c); + }); + } + all() { + return this.channels; + } + toString() { + if (this.channels.length === 0) { + return undefined; + } + return this.channels.join(this.ChannelDelimiter); + } + equals(other) { + if (other instanceof MultiChannelId) { + return this.channels.length === other.channels.length && + this.channels.every((c, i) => c === other.channels[i]); + } + return false; + } + } + + let interop; + let myInstanceId; + let logger; + const T42_ANNOUNCE_METHOD_NAME = "T42.Channels.Announce"; + const T42_COMMAND_METHOD_NAME = "T42.Channels.Command"; + async function setupInterop(interopLib, channels, loggerAPI) { + var _a, _b; + logger = loggerAPI; + interop = interopLib; + if (typeof window !== "undefined") { + if (window.glue42gd) { + myInstanceId = window.glue42gd.windowId; + } + } + if (!myInstanceId) { + myInstanceId = interopLib.instance.instance; + } + await interop.register(T42_COMMAND_METHOD_NAME, (args) => { + const command = args.command; + if (!command) { + throw new Error("missing command argument"); + } + logger.trace(`received command "${command}" with ${JSON.stringify(args)}`); + if (command === "join") { + const id = args.channel; + if (!id) { + throw new Error("missing argument id"); + } + return channels.joinNoSelectorSwitch(id); + } + if (command === "leave") { + return channels.leaveNoSelectorSwitch(); + } + if (command === "get") { + const id = channels.current(); + return { id }; + } + if (command === "restrictions-changed") { + const restrictions = args.restrictions; + const targetWindowId = args.swId; + channels.handleRestrictionsChanged(restrictions, targetWindowId); + return; + } + if (command === "isFdc3DataWrappingSupported") { + return { isSupported: true }; + } + if (command === "join-multi") { + const channelsToJoin = args.channelsToJoin; + if (!channelsToJoin) { + throw new Error("missing argument channelsToJoin"); + } + return channels.joinNoSelectorSwitch(new MultiChannelId(channelsToJoin).toString()); + } + if (command === "leave-multi") { + const channelsToLeave = args.channelsToLeave; + return channels.leaveNoSelectorSwitch(new MultiChannelId(channelsToLeave).toString()); + } + throw new Error(`unknown command ${command}`); + }); + const result = await interop.invoke(T42_ANNOUNCE_METHOD_NAME, { swId: myInstanceId, instance: interop.instance.instance }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_RESPONSE_TIMEOUT_MS + }); + if ((_a = result.returned) === null || _a === void 0 ? void 0 : _a.restrictions) { + channels.handleRestrictionsChanged((_b = result.returned) === null || _b === void 0 ? void 0 : _b.restrictions, myInstanceId); + } + return result.returned; + } + async function sendLeaveChannel(channel, winId) { + var _a; + await invoke("leaveChannel", { channel }, (_a = winId !== null && winId !== void 0 ? winId : winId) !== null && _a !== void 0 ? _a : myInstanceId); + } + async function sendSwitchChannelUI(channel, winId) { + await invoke("switchChannel", { newChannel: channel }, winId !== null && winId !== void 0 ? winId : myInstanceId); + } + async function setRestrictions(restrictions) { + var _a; + await invoke("restrict", restrictions, (_a = restrictions.windowId) !== null && _a !== void 0 ? _a : myInstanceId); + } + async function getRestrictionsByWindow(id) { + try { + const result = await invoke("getRestrictions", {}, id !== null && id !== void 0 ? id : myInstanceId); + return result.returned; + } + catch (e) { + } + } + async function setRestrictionsForAllChannels(restrictions) { + var _a; + await invoke("restrictAll", restrictions, (_a = restrictions.windowId) !== null && _a !== void 0 ? _a : myInstanceId); + } + async function getChannelsInfo(filter) { + const result = await invoke("getChannelsInfo", { filter }); + return result.returned; + } + async function addOrRemoveChannel(command, id, color, label) { + await invoke(command, { id, color, label }); + } + async function getChannelInitInfo(config, i) { + if (typeof config.operationMode !== "boolean" && typeof config.operationMode === "string") { + validateMode(config.operationMode); + return { mode: config.operationMode, initialChannel: undefined }; + } + try { + const result = await i.invoke(T42_ANNOUNCE_METHOD_NAME, { command: "getChannelsMode" }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_RESPONSE_TIMEOUT_MS, + }); + const initialChannel = result.returned.initialChannel; + if (result.returned.mode === "single") { + return { + mode: "single", + initialChannel + }; + } + else if (result.returned.mode === "multi") { + return { + mode: "multi", + initialChannel + }; + } + else { + return { + mode: "single", + initialChannel + }; + } + } + catch (e) { + return { mode: "single", initialChannel: undefined }; + } + } + function invoke(command, data, swId) { + const args = { command, data }; + if (swId) { + args.swId = swId; + } + return interop.invoke(T42_ANNOUNCE_METHOD_NAME, args, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_RESPONSE_TIMEOUT_MS, + }); + } + function validateMode(mode) { + if (mode !== "single" && mode !== "multi") { + throw new Error(`Invalid mode: ${mode}`); + } + } + + const CONTEXT_PREFIX = "___channel___"; + const LATEST_FDC3_TYPE = "latest_fdc3_type"; + class BaseSharedContextSubscriber { + constructor(contexts) { + this.contexts = contexts; + } + subscribe(callback) { + this.callback = callback; + } + subscribeFor(name, callback) { + if (!this.isChannel(name)) { + return Promise.reject(new Error(`Channel with name: ${name} doesn't exist!`)); + } + const contextName = this.createContextName(name); + return this.contexts.subscribe(contextName, (data, _, __, ___, extraData) => { + callback(data.data, data, extraData === null || extraData === void 0 ? void 0 : extraData.updaterId); + }); + } + all() { + const contextNames = this.contexts.all(); + const channelContextNames = contextNames.filter((contextName) => contextName.startsWith(CONTEXT_PREFIX)); + const channelNames = channelContextNames.map((channelContextName) => channelContextName.substr(CONTEXT_PREFIX.length)); + return channelNames; + } + async getContextData(name) { + if (!this.isChannel(name)) { + throw new Error(`A channel with name: ${name} doesn't exist!`); + } + const contextName = this.createContextName(name); + const contextData = await this.contexts.get(contextName); + if (contextData[LATEST_FDC3_TYPE]) { + return this.getContextWithFdc3Data(contextData); + } + else { + delete contextData[LATEST_FDC3_TYPE]; + } + return contextData; + } + updateChannel(name, data) { + const contextName = this.createContextName(name); + return this.contexts.update(contextName, data); + } + updateData(name, data) { + const contextName = this.createContextName(name); + const fdc3Type = this.getFDC3Type(data); + if (this.contexts.setPathSupported) { + const pathValues = Object.keys(data).map((key) => { + return { + path: `data.` + key, + value: data[key] + }; + }); + if (fdc3Type) { + pathValues.push({ path: LATEST_FDC3_TYPE, value: fdc3Type }); + } + return this.contexts.setPaths(contextName, pathValues); + } + else { + if (fdc3Type) { + data[LATEST_FDC3_TYPE] = fdc3Type; + } + return this.contexts.update(contextName, { data }); + } + } + setPaths(name, paths) { + const contextName = this.createContextName(name); + if (this.contexts.setPathSupported) { + const pathValues = paths.map((p) => { + return { + path: `data.` + p.path, + value: p.value + }; + }); + pathValues.map((p) => { + const fdc3Type = this.getFDC3Type(p.value); + if (fdc3Type) { + pathValues.push({ path: LATEST_FDC3_TYPE, value: fdc3Type }); + } + }); + return this.contexts.setPaths(contextName, pathValues); + } + else { + throw new Error("setPaths is not supported!"); + } + } + clearContextData(name) { + const contextName = this.createContextName(name); + return this.contexts.update(contextName, { data: {}, [LATEST_FDC3_TYPE]: undefined }); + } + isChannel(name) { + return this.all().some((channelName) => channelName === name); + } + async remove(name) { + if (!this.isChannel(name)) { + throw new Error(`A channel with name: ${name} doesn't exist!`); + } + const contextName = this.createContextName(name); + await this.contexts.destroy(contextName); + } + createContextName(name) { + return CONTEXT_PREFIX + name; + } + getFDC3Type(data) { + const fdc3PropsArr = Object.keys(data).filter((key) => key.indexOf("fdc3_") === 0); + if (fdc3PropsArr.length === 0) { + return; + } + if (fdc3PropsArr.length > 1) { + throw new Error("FDC3 does not support updating of multiple context keys"); + } + return fdc3PropsArr[0].split("_").slice(1).join("_"); + } + getContextWithFdc3Data(channelContext) { + const { latest_fdc3_type, ...rest } = channelContext; + const parsedType = latest_fdc3_type.split("&").join("."); + const fdc3Context = { type: parsedType, ...rest.data[`fdc3_${latest_fdc3_type}`] }; + delete rest.data[`fdc3_${latest_fdc3_type}`]; + const context = { + name: channelContext.name, + meta: channelContext.meta, + data: { + ...rest.data, + fdc3: fdc3Context + } + }; + return context; + } + } + class MultiSharedContextSubscriber extends BaseSharedContextSubscriber { + constructor() { + super(...arguments); + this.currentlySubscribedChannels = []; + this.unsubscribeMap = {}; + } + async switchChannel(id) { + const newChannels = new MultiChannelId(id).all(); + for (const newChannel of newChannels) { + if (!this.currentlySubscribedChannels.includes(newChannel)) { + await this.subscribeToChannel(newChannel); + } + } + } + async leave(id) { + const channelsToLeave = new MultiChannelId(id).all(); + for (const newChannel of channelsToLeave) { + if (this.currentlySubscribedChannels.includes(newChannel)) { + this.unsubscribeFromChannel(newChannel); + } + } + } + async updateData(id, data) { + const channels = new MultiChannelId(id).all(); + for (const channel of channels) { + await super.updateData(channel, data); + } + } + async setPaths(id, paths) { + const channels = new MultiChannelId(id).all(); + for (const channel of channels) { + await super.setPaths(channel, paths); + } + } + isChannel(name) { + const channels = new MultiChannelId(name).all(); + return channels.every((channel) => super.isChannel(channel)); + } + async subscribeToChannel(name) { + const contextName = this.createContextName(name); + const usub = await this.contexts.subscribe(contextName, (data, _, __, ___, extraData) => { + if (this.callback) { + this.callback(data.data, data, extraData === null || extraData === void 0 ? void 0 : extraData.updaterId); + } + }); + this.currentlySubscribedChannels.push(name); + this.unsubscribeMap[contextName] = usub; + } + async unsubscribeFromChannel(name) { + const contextName = this.createContextName(name); + const unsub = this.unsubscribeMap[contextName]; + if (unsub) { + unsub(); + delete this.unsubscribeMap[contextName]; + } + this.currentlySubscribedChannels = this.currentlySubscribedChannels.filter((channel) => channel !== name); + } + } + class SharedContextSubscriber extends BaseSharedContextSubscriber { + async switchChannel(name) { + this.unsubscribe(); + const contextName = this.createContextName(name); + this.unsubscribeFunc = await this.contexts.subscribe(contextName, (data, _, __, ___, extraData) => { + if (this.callback) { + this.callback(data.data, data, extraData === null || extraData === void 0 ? void 0 : extraData.updaterId); + } + }); + } + async leave() { + if (this.callback) { + this.callback({}, undefined); + } + this.unsubscribe(); + } + unsubscribe() { + if (this.unsubscribeFunc) { + this.unsubscribeFunc(); + this.unsubscribeFunc = undefined; + } + } + } + + const validateFdc3Options = (options) => { + if (typeof options !== "object" || Array.isArray(options)) { + throw new Error(`Provide options as an object`); + } + if (options.contextType && (typeof options.contextType !== "string" || !options.contextType.length)) { + throw new Error(`Provide options.contextType as a non-empty string`); + } + }; + + class ChannelsImpl { + constructor(interop, getWindowsAPI, getAppManagerAPI, logger) { + this.interop = interop; + this.getWindowsAPI = getWindowsAPI; + this.getAppManagerAPI = getAppManagerAPI; + this.logger = logger; + this.subsKey = "subs"; + this.changedKey = "changed"; + this.channelsChangedKey = "channelsChanged"; + this.isInitialJoin = true; + this.registry = CallbackRegistryFactory(); + this.pendingReplays = {}; + this.pendingRestrictionCallbacks = new Map(); + } + async getMyChannels(options) { + if (!this.currentChannelID) { + return Promise.resolve([]); + } + if (this.currentChannelID.all().length === 0) { + return Promise.resolve([]); + } + const result = []; + for (const channel of this.currentChannelID.all()) { + result.push(await this.get(channel, options)); + } + return result; + } + async init(shared, mode, initial) { + this.mode = mode; + this.shared = shared; + this.shared.subscribe(this.handler.bind(this)); + this.subscribeForChannelRestrictionsChange(); + let initialChannel = initial; + if (typeof window !== "undefined" && typeof window.glue42gd !== "undefined") { + initialChannel = window.glue42gd.initialChannel; + } + this.currentChannelID = this.getID(initialChannel); + this.logger.trace(`initialized with mode: "${mode}" and initial channel: "${initialChannel}"`); + if (this.currentChannelID.isJoinedToAnyChannel) { + this.logger.trace(`joining initial channel: "${this.currentChannelID.toString()}"`); + await this.joinNoSelectorSwitch(this.currentChannelID.toString()); + } + } + subscribe(callback, options) { + if (typeof callback !== "function") { + throw new Error("Please provide the callback as a function!"); + } + const id = Utils.generateId(); + this.pendingReplays[id] = true; + const wrappedCallback = (options === null || options === void 0 ? void 0 : options.contextType) + ? this.getWrappedSubscribeCallbackWithFdc3Type(callback, id, options.contextType) + : this.getWrappedSubscribeCallback(callback, id); + if (this.lastUpdate) { + let lastUpdate = Object.assign({}, this.lastUpdate); + setTimeout(async () => { + if (this.pendingReplays[id]) { + if (this.lastUpdate) { + lastUpdate = this.lastUpdate; + } + wrappedCallback(lastUpdate.context.data, lastUpdate.context, lastUpdate.updaterId); + } + delete this.pendingReplays[id]; + }, 0); + } + const unsub = this.registry.add(this.subsKey, wrappedCallback); + return () => { + this.pendingReplays[id] = false; + this.pendingRestrictionCallbacks.delete(id); + unsub(); + }; + } + async subscribeFor(name, callback, options) { + if (typeof name !== "string") { + throw new Error("Please provide the name as a string!"); + } + if (typeof callback !== "function") { + throw new Error("Please provide the callback as a function!"); + } + const id = Utils.generateId(); + const wrappedCallback = (options === null || options === void 0 ? void 0 : options.contextType) + ? this.getWrappedSubscribeCallbackWithFdc3Type(callback, id, options.contextType) + : this.getWrappedSubscribeCallback(callback, id); + const unsub = await this.shared.subscribeFor(name, wrappedCallback); + return () => { + this.pendingRestrictionCallbacks.delete(id); + unsub(); + }; + } + async publish(data, options) { + if (typeof data !== "object") { + throw new Error("Please provide the data as an object!"); + } + if (options) { + this.validatePublishOptions(options); + } + if (typeof options === "object") { + return this.publishWithOptions(data, options); + } + const channelName = typeof options === "string" ? options : this.currentChannelID.toString(); + if (!channelName) { + throw new Error("Not joined to any channel!"); + } + if (!this.shared.isChannel(channelName)) { + return Promise.reject(new Error(`A channel with name: ${channelName} doesn't exist!`)); + } + if (this.mode === "multi") { + const channelsToPublish = new MultiChannelId(channelName).all(); + const restrictedChannels = []; + for (const cn of channelsToPublish) { + const canPublish = (await this.getRestrictionsByChannel(cn)).write; + if (!canPublish) { + restrictedChannels.push(cn); + continue; + } + await this.shared.updateData(cn, data); + } + if (restrictedChannels.length > 0) { + const restrictedChannelsErr = `Unable to publish due to restrictions to the following channels: ${restrictedChannels.join(", ")}`; + if (restrictedChannels.length === channelsToPublish.length) { + throw new Error(restrictedChannelsErr); + } + else { + this.logger.warn(restrictedChannelsErr); + } + } + } + else { + const canPublish = (await this.getRestrictionsByChannel(channelName)).write; + if (!canPublish) { + throw new Error(`Window does not have permission to write to channel ${channelName}`); + } + return this.shared.updateData(channelName, data); + } + } + async setPaths(paths, name) { + if (name) { + if (typeof name !== "string") { + throw new Error("Please provide the name as a string!"); + } + if (!this.shared.isChannel(name)) { + return Promise.reject(new Error(`A channel with name: ${name} doesn't exist!`)); + } + if (!(await this.getRestrictionsByChannel(name)).write) { + throw new Error(`Window does not have permission to write to channel ${name}`); + } + return this.shared.setPaths(name, paths); + } + if (!this.currentChannelID) { + throw new Error("Not joined to any channel!"); + } + if (!(await this.getRestrictionsByChannel(this.currentChannelID.toString())).write) { + throw new Error(`Window does not have permission to write to channel ${this.currentChannelID.toString()}`); + } + if (!Array.isArray(paths)) { + throw new Error("Path Values argument is not a valid array"); + } + paths.forEach((path) => { + this.validatePathArgs(path); + }); + return this.shared.setPaths(this.currentChannelID.toString(), paths); + } + async setPath(path, name) { + if (name) { + if (typeof name !== "string") { + throw new Error("Please provide the name as a string!"); + } + if (!this.shared.isChannel(name)) { + return Promise.reject(new Error(`A channel with name: ${name} doesn't exist!`)); + } + if (!(await this.getRestrictionsByChannel(name)).write) { + throw new Error(`Window does not have permission to write to channel ${name}`); + } + return this.shared.setPaths(name, [path]); + } + if (!this.currentChannelID) { + throw new Error("Not joined to any channel!"); + } + if (!(await this.getRestrictionsByChannel(this.currentChannelID.toString())).write) { + throw new Error(`Window does not have permission to write to channel ${this.currentChannelID.toString()}`); + } + this.validatePathArgs(path); + return this.shared.setPaths(this.currentChannelID.toString(), [path]); + } + all() { + const channelNames = this.shared.all(); + return Promise.resolve(channelNames); + } + async list() { + const channelNames = await this.all(); + const channelContexts = await Promise.all(channelNames.map((channelName) => this.get(channelName))); + return channelContexts; + } + async get(name, options) { + if (typeof name !== "string") { + return Promise.reject(new Error("Please provide the channel name as a string!")); + } + if (!(options === null || options === void 0 ? void 0 : options.contextType)) { + return this.shared.getContextData(name); + } + validateFdc3Options(options); + const context = await this.shared.getContextData(name); + return this.getContextWithFdc3Type(context, options.contextType); + } + getMy(options) { + if (!this.currentChannelID) { + return Promise.resolve(undefined); + } + if (this.currentChannelID.all().length === 0) { + return Promise.resolve(undefined); + } + return this.get(this.currentChannelID.all()[0], options); + } + async join(name, windowId) { + if (windowId !== undefined && windowId !== null) { + this.validateWindowIdArg(windowId); + this.logger.trace(`joining channel ${name} for window: ${windowId}`); + return sendSwitchChannelUI(name, windowId); + } + return this.joinCore(name); + } + async joinNoSelectorSwitch(channelName) { + this.logger.trace(`joining channel "${channelName}" from command`); + return this.joinCore(channelName, false); + } + leave(options) { + this.logger.trace(`leaving channel with options: ${JSON.stringify(options)}`); + let windowId; + let channelName; + if (typeof options === "string") { + windowId = options; + } + else if (typeof options === "object" && !Array.isArray(options) && options !== null && options !== undefined) { + if (options.windowId) { + windowId = options.windowId; + } + if (options.channel) { + channelName = options.channel; + } + } + if (this.mode === "multi") { + return this.leaveWhenMulti(channelName, windowId); + } + else { + return this.leaveWhenSingle(channelName, windowId); + } + } + leaveNoSelectorSwitch(channelName) { + this.logger.trace(`leaving channel "${channelName}" from command`); + return this.leaveCore(false, channelName); + } + current() { + return this.currentChannelID.toString(); + } + my() { + return this.current(); + } + myChannels() { + var _a; + return (_a = this.currentChannelID.all()) !== null && _a !== void 0 ? _a : []; + } + onChannelsChanged(callback) { + if (typeof callback !== "function") { + throw new Error("Please provide the callback as a function!"); + } + let timeoutId; + const current = this.current(); + if (current) { + timeoutId = setTimeout(() => { + callback(this.myChannels()); + }, 0); + } + const un = this.registry.add(this.channelsChangedKey, callback); + return () => { + un(); + clearTimeout(timeoutId); + }; + } + changed(callback) { + if (typeof callback !== "function") { + throw new Error("Please provide the callback as a function!"); + } + const current = this.current(); + if (current) { + setTimeout(() => { + callback(this.current()); + }, 0); + } + return this.registry.add(this.changedKey, () => { + callback(this.current()); + }); + } + onChanged(callback) { + return this.changed(callback); + } + async add(info) { + var _a; + if (typeof info !== "object") { + throw new Error("Please provide the info as an object!"); + } + if (typeof info.name === "undefined") { + throw new Error("info.name is missing!"); + } + if (typeof info.name !== "string") { + throw new Error("Please provide the info.name as a string!"); + } + if (typeof info.meta === "undefined") { + throw new Error("info.meta is missing!"); + } + if (typeof info.meta !== "object") { + throw new Error("Please provide the info.meta as an object!"); + } + if (typeof info.meta.color === "undefined") { + throw new Error("info.meta.color is missing!"); + } + if (typeof info.meta.color !== "string") { + throw new Error("Please provide the info.meta.color as a string!"); + } + const context = { + name: info.name, + meta: info.meta || {}, + data: info.data || {} + }; + this.logger.trace(`adding channel: ${info.name}`); + await addOrRemoveChannel("addChannel", info.name, info.meta.color, (_a = info.meta) === null || _a === void 0 ? void 0 : _a.label); + await this.shared.updateChannel(info.name, context); + return context; + } + async remove(channel) { + if (typeof channel !== "string") { + throw new Error("Please provide the channel name as a string!"); + } + this.logger.trace(`removing channel: ${channel}`); + await this.shared.remove(channel); + await addOrRemoveChannel("removeChannel", channel); + } + async getWindowsOnChannel(channel) { + this.validateChannelArg(channel); + const windowInfos = await this.getWindowsWithChannels({ channels: [channel] }); + return windowInfos.map((w) => w.window); + } + async getWindowsWithChannels(filter) { + this.validateWindowsWithChannelsFilter(filter); + try { + const info = await getChannelsInfo(filter); + const windowsAPI = this.getWindowsAPI(); + if (info === null || info === void 0 ? void 0 : info.windows) { + return info.windows.reduce((memo, windowInfo) => { + const window = windowsAPI.findById(windowInfo.windowId); + memo.push({ + window, + channel: windowInfo.channel, + application: windowInfo.application + }); + return memo; + }, []); + } + } + catch (er) { + this.logger.error(`Error getting all channel enabled windows. This method is available since Glue42 3.12`, er); + } + return []; + } + async restrict(restriction) { + this.validateRestrictionConfig(restriction); + return setRestrictions(restriction); + } + async getRestrictions(windowId) { + if (windowId) { + this.validateWindowIdArg(windowId); + } + return getRestrictionsByWindow(windowId); + } + async restrictAll(restriction) { + this.validateRestrictionConfig(restriction); + return setRestrictionsForAllChannels(restriction); + } + handleRestrictionsChanged(restrictions, windowId) { + this.registry.execute("restrictions-changed", { + restrictions, + windowId + }); + } + async clearChannelData(channel) { + const channelName = typeof channel === "string" ? channel : this.currentChannelID.toString(); + if (!channelName) { + return; + } + if (!this.shared.isChannel(channelName)) { + return; + } + const canPublish = (await this.getRestrictionsByChannel(channelName)).write; + if (!canPublish) { + return; + } + return this.shared.clearContextData(channelName); + } + handler(data, context, updaterId) { + if (!context && !updaterId) { + this.lastUpdate = undefined; + return; + } + this.lastUpdate = { context, updaterId }; + this.pendingReplays = {}; + this.registry.execute(this.subsKey, data, context, updaterId); + } + async joinCore(name, changeSelector = true) { + this.logger.trace(`joining channel "${name}" ${changeSelector ? "" : "from command"}`); + if (typeof name !== "string") { + throw new Error("Please provide the channel name as a string!"); + } + const newId = this.getID(name); + if (!this.isInitialJoin && this.currentChannelID.isOnChannel(newId.toString())) { + this.logger.trace(`already on channel: "${name}" ${changeSelector ? "" : "from command"}`); + return; + } + this.isInitialJoin = false; + await Promise.all(newId.all().map((n) => this.verifyChannelExists(n))); + this.currentChannelID.joinChannel(name); + this.lastUpdate = undefined; + this.logger.trace(`switching channel context to: "${name}" ${changeSelector ? "" : "from command"}`); + await this.shared.switchChannel(this.currentChannelID.toString()); + if (changeSelector) { + this.logger.trace(`switching UI channel to: "${name}" ${changeSelector ? "" : "from command"}`); + await sendSwitchChannelUI(name); + this.logger.trace(`switched UI channel to: "${name}" ${changeSelector ? "" : "from command"}`); + } + this.raiseChannelsChangedEvents(); + this.logger.trace(`joined channel: ${name} ${changeSelector ? "" : "from command"} - current channel/s: ${this.currentChannelID.toString()}`); + } + async verifyChannelExists(name) { + const doesChannelExist = (channelName) => { + const channelNames = this.shared.all(); + return channelNames.includes(channelName); + }; + if (!doesChannelExist(name)) { + const channelExistsPromise = new Promise((resolve, reject) => { + const intervalId = setInterval(() => { + if (doesChannelExist(name)) { + clearTimeout(timeoutId); + clearInterval(intervalId); + resolve(); + } + }, 100); + const timeoutId = setTimeout(() => { + clearInterval(intervalId); + return reject(new Error(`A channel with name: ${name} doesn't exist!`)); + }, 3000); + }); + await channelExistsPromise; + } + } + async leaveCore(changeSelector = true, channelID) { + if (!this.currentChannelID.isJoinedToAnyChannel) { + this.logger.trace(`leave called ${changeSelector ? "" : "from command"} when not joined to any channel change selector`); + return; + } + if (channelID && !this.currentChannelID.isOnChannel(channelID)) { + this.logger.trace(`leave called ${changeSelector ? "" : "from command"} when not joined to channel: "${channelID}"`); + return; + } + this.logger.trace(`leaving context channel: "${channelID}" ${changeSelector ? "" : "from command"}`); + this.currentChannelID.leaveChannel(channelID); + await this.shared.leave(channelID); + this.lastUpdate = undefined; + this.raiseChannelsChangedEvents(); + if (changeSelector) { + this.logger.trace(`switching UI channel to: "${channelID}" ${changeSelector ? "" : "from command"}`); + await sendSwitchChannelUI(this.currentChannelID.toString()); + this.logger.trace(`switched UI channel to: "${channelID}" ${changeSelector ? "" : "from command"}`); + } + this.logger.trace(`left single channel: "${channelID}" ${changeSelector ? "" : "from command"} - current channel/s: "${this.currentChannelID.toString()}"`); + return Promise.resolve(); + } + async leaveCoreMulti(changeSelector = true, channelID) { + this.logger.trace(`leaving multi channel: "${channelID.toString()}" ${changeSelector ? "" : "from command"}`); + const currentChannels = this.currentChannelID.all(); + const isJoinedToChannel = currentChannels.some((c) => channelID.isOnChannel(c)); + if (!isJoinedToChannel || !this.currentChannelID.isJoinedToAnyChannel) { + this.logger.trace(`leave called ${changeSelector ? "" : "from command"} when not joined to any channel`); + return; + } + const channelName = channelID.toString(); + this.currentChannelID.leaveChannel(channelName); + await this.shared.leave(channelName); + this.lastUpdate = undefined; + this.raiseChannelsChangedEvents(); + if (changeSelector) { + this.logger.trace(`switching UI channel to: "${channelName}" ${changeSelector ? "" : "from command"}`); + await sendLeaveChannel(channelName); + this.logger.trace(`switched UI channel to: "${channelName}" ${changeSelector ? "" : "from command"}`); + } + this.logger.trace(`left multi channel: "${channelName}" ${changeSelector ? "" : "from command"} - current channel/s: ${this.currentChannelID.toString()}`); + return Promise.resolve(); + } + raiseChannelsChangedEvents() { + this.registry.execute(this.changedKey, this.currentChannelID.toString()); + this.registry.execute(this.channelsChangedKey, this.currentChannelID.all()); + } + async getRestrictionsByChannel(channelName) { + var _a; + const restrictions = (_a = this.channelRestrictions) !== null && _a !== void 0 ? _a : await getRestrictionsByWindow(); + if (!restrictions || !Array.isArray(restrictions.channels) || !restrictions.channels.find(c => c.name === channelName)) { + return { + read: true, + write: true + }; + } + const byChannel = restrictions.channels.find(c => c.name === channelName); + return byChannel; + } + onRestrictionsChanged(callback, callbackId, currentChannelName) { + this.pendingRestrictionCallbacks.set(callbackId, { + cb: callback, + channelName: currentChannelName + }); + if (this.onRestrictionsChangedSub) { + return; + } + this.onRestrictionsChangedSub = this.registry.add("restrictions-changed", ({ restrictions }) => { + this.logger.trace(`restrictions changed - ${JSON.stringify(restrictions)}`); + this.pendingRestrictionCallbacks.forEach(({ cb, channelName }, id) => { + const currentChannel = restrictions.channels.find((c) => c.name === channelName); + if (!currentChannel) { + this.logger.trace(`channel "${channelName}" not found in restrictions`); + return; + } + if (currentChannel.read) { + this.pendingRestrictionCallbacks.delete(id); + if (this.pendingRestrictionCallbacks.values.length === 0 && this.onRestrictionsChangedSub) { + this.onRestrictionsChangedSub(); + this.onRestrictionsChangedSub = null; + } + cb(); + } + }); + }); + } + subscribeForChannelRestrictionsChange() { + this.registry.add("restrictions-changed", (r) => { + this.logger.trace(`channel restrictions changed - ${JSON.stringify(r.restrictions)}`); + this.channelRestrictions = r.restrictions; + }); + } + validatePathArgs(path) { + if (!path) { + throw new Error("Please provide a valid path value argument"); + } + if (typeof path !== "object") { + throw new Error(`Path Value argument is not a valid object: ${JSON.stringify(path)}`); + } + if (!path.path) { + throw new Error(`path property is missing from Path Value argument: ${JSON.stringify(path)}`); + } + if (!path.value) { + throw new Error(`value property is missing from Path Value argument: ${JSON.stringify(path)}`); + } + if (typeof path.path !== "string") { + throw new Error(`path property is not a valid string from the Path Value argument: ${JSON.stringify(path)}`); + } + } + validatePublishOptions(options) { + if ((typeof options !== "string" && typeof options !== "object") || Array.isArray(options)) { + throw new Error("Provide options as a string or an object"); + } + if (typeof options === "object") { + this.validatePublishOptionsObject(options); + return; + } + if (options === "string" && !options.length) { + throw new Error("Provide options as a non-empty string"); + } + } + validatePublishOptionsObject(options) { + if (typeof options !== "object" || Array.isArray(options)) { + throw new Error("Provide options as an object"); + } + if (options.name && (typeof options.name !== "string" || !options.name.length)) { + throw new Error("Provide options.name as a non-empty string"); + } + if (Object.keys(options).includes("fdc3") && typeof options.fdc3 !== "boolean") { + throw new Error("Provide options.fdc3 as a boolean"); + } + } + async publishWithOptions(data, options) { + const channelName = options.name || this.currentChannelID.toString(); + if (!this.shared.isChannel(channelName)) { + throw new Error(`A channel with name: ${options.name} doesn't exist!`); + } + if (!channelName) { + throw new Error("Cannot publish to channel, because not joined to a channel!"); + } + const canPublish = (await this.getRestrictionsByChannel(channelName)).write; + if (!canPublish) { + throw new Error(`Window does not have permission to write to channel ${this.currentChannelID.toString()}`); + } + if (!options.fdc3) { + return this.shared.updateData(channelName, data); + } + return this.publishFdc3Data(channelName, data); + } + async publishFdc3Data(channelName, data) { + var _a; + if (typeof data.type !== "string" || !((_a = data.type) === null || _a === void 0 ? void 0 : _a.length)) { + throw new Error("Expected a valid FDC3 Context with compulsory 'type' field"); + } + const { type, ...rest } = data; + const parsedType = type.split(".").join("&"); + const fdc3DataToPublish = { [`fdc3_${parsedType}`]: rest }; + return this.shared.updateData(channelName, fdc3DataToPublish); + } + getWrappedSubscribeCallback(callback, id) { + const wrappedCallback = async (_, context, updaterId) => { + const restrictionByChannel = await this.getRestrictionsByChannel(context.name); + const channelData = this.getDataWithFdc3Encoding(context); + if (restrictionByChannel.read) { + callback(channelData, context, updaterId); + } + else { + this.onRestrictionsChanged(() => { + callback(channelData, context, updaterId); + }, id, context.name); + } + }; + return wrappedCallback; + } + getWrappedSubscribeCallbackWithFdc3Type(callback, id, fdc3Type) { + const didReplay = { replayed: false }; + const wrappedCallback = async (_, context, updaterId) => { + const restrictionByChannel = await this.getRestrictionsByChannel(context.name); + const callbackWithTypesChecks = () => { + const { data, latest_fdc3_type } = context; + const searchedType = `fdc3_${fdc3Type.split(".").join("&")}`; + if (!data[searchedType]) { + return; + } + if (didReplay.replayed) { + return this.parseDataAndInvokeSubscribeCallback({ latestFdc3TypeEncoded: latest_fdc3_type, searchedType: fdc3Type, callback, context, updaterId }); + } + const fdc3Data = { type: fdc3Type, ...data[searchedType] }; + callback({ fdc3: fdc3Data }, context, updaterId); + didReplay.replayed = true; + }; + if (restrictionByChannel.read) { + callbackWithTypesChecks(); + return; + } + this.onRestrictionsChanged(callbackWithTypesChecks, id, context.name); + }; + return wrappedCallback; + } + parseDataAndInvokeSubscribeCallback(args) { + const { latestFdc3TypeEncoded, searchedType, callback, context, updaterId } = args; + const latestPublishedType = latestFdc3TypeEncoded.split("&").join("."); + if (latestPublishedType !== searchedType) { + return; + } + const fdc3Data = { type: searchedType, ...context.data[`fdc3_${latestFdc3TypeEncoded}`] }; + callback({ fdc3: fdc3Data }, context, updaterId); + } + getContextWithFdc3Type(context, searchedType) { + var _a, _b; + if (((_b = (_a = context.data) === null || _a === void 0 ? void 0 : _a.fdc3) === null || _b === void 0 ? void 0 : _b.type) === searchedType) { + return { + name: context.name, + meta: context.meta, + data: { fdc3: context.data.fdc3 } + }; + } + const encodedType = `fdc3_${searchedType.split(".").join("&")}`; + if (!context.data[encodedType]) { + return { + name: context.name, + meta: context.meta, + data: {} + }; + } + const fdc3Context = { type: searchedType, ...context.data[encodedType] }; + return { + name: context.name, + meta: context.meta, + data: { fdc3: fdc3Context } + }; + } + getDataWithFdc3Encoding(context) { + const { data, latest_fdc3_type } = context; + if (!latest_fdc3_type) { + return data; + } + const parsedType = latest_fdc3_type.split("&").join("."); + const latestTypePropName = `fdc3_${latest_fdc3_type}`; + const fdc3Data = { type: parsedType, ...data[latestTypePropName] }; + const { [latestTypePropName]: latestFDC3Type, ...rest } = data; + return { ...rest, fdc3: fdc3Data }; + } + getID(id) { + if (this.mode === "multi") { + return new MultiChannelId(id); + } + else { + return new SingleChannelID(id); + } + } + leaveWhenSingle(channelName, windowId) { + if (windowId) { + this.logger.trace(`leaving single channel "${channelName}" for window: "${windowId}"`); + return sendSwitchChannelUI(undefined, windowId); + } + this.logger.trace(`leaving single channel "${channelName}" for our window`); + return this.leaveCore(true, channelName); + } + async leaveWhenMulti(channelName, windowId) { + if (windowId) { + this.logger.trace(`leaving multi channel "${channelName}" for window: "${windowId}"`); + return sendLeaveChannel(channelName, windowId); + } + else { + const channelId = channelName ? new MultiChannelId(channelName) : this.currentChannelID; + this.logger.trace(`leaving multi channel "${channelId.toString()}" for our window`); + return this.leaveCoreMulti(true, channelId); + } + } + validateWindowIdArg(windowId) { + if (typeof windowId !== "string") { + throw new Error("The window ID must be a non-empty string!"); + } + const windows = this.getWindowsAPI(); + if (!windows.findById(windowId)) { + throw new Error(`Window with ID "${windowId}" doesn't exist!`); + } + } + validateChannelArg(channel) { + if (!channel) { + throw new Error("Please provide a valid Channel name as a non-empty string!"); + } + if (typeof channel !== "string") { + throw new Error("The Channel name must be a non-empty string!"); + } + const channelNames = this.shared.all(); + if (channelNames.every((name) => name !== channel)) { + throw new Error(`Channel "${channel}" does not exist!"`); + } + } + validateWindowsWithChannelsFilter(filter) { + if (filter === undefined) { + return; + } + if (filter === null || Array.isArray(filter) || typeof filter !== "object") { + throw new Error("The `filter` argument must be a valid object!"); + } + } + isRestrictions(restriction) { + return 'name' in restriction; + } + validateRestrictionConfig(restriction) { + if (restriction === null || restriction === undefined || Array.isArray(restriction) || typeof restriction !== "object") { + throw new Error("The `restrictions` argument must be a valid object with Channel restrictions!"); + } + if (this.isRestrictions(restriction) && typeof restriction.name !== "string") { + throw new Error("The `name` restriction property must be a non-empty string!"); + } + if (restriction.read !== null && restriction.read !== undefined && typeof restriction.read !== "boolean") { + throw new Error("The `read` restriction property must be a boolean value!"); + } + if (restriction.write !== null && restriction.write !== undefined && typeof restriction.write !== "boolean") { + throw new Error("The `write` restriction property must be a boolean value!"); + } + if ((restriction.read === null || restriction.read === undefined) && (restriction.write === null || restriction.write === undefined)) { + throw new Error("It's required to set either the `read` or the `write` property of the Channel restriction object!"); + } + if (restriction.windowId !== null && restriction.windowId !== undefined) { + this.validateWindowIdArg(restriction.windowId); + } + } + } + + function factory$4(config, contexts, agm, getWindowsAPI, getAppManagerAPI, logger) { + const channelsReadyPromise = getChannelInitInfo(config, agm) + .then(async ({ mode, initialChannel }) => { + const sharedContexts = mode === "single" ? new SharedContextSubscriber(contexts) : new MultiSharedContextSubscriber(contexts); + if (mode === "multi") { + logger.info(`multi-channel mode enabled`); + } + await channels.init(sharedContexts, mode, initialChannel); + await setupInterop(agm, channels, logger); + return true; + }); + const channels = new ChannelsImpl(agm, getWindowsAPI, getAppManagerAPI, logger); + return { + subscribe: channels.subscribe.bind(channels), + subscribeFor: channels.subscribeFor.bind(channels), + publish: channels.publish.bind(channels), + setPath: channels.setPath.bind(channels), + setPaths: channels.setPaths.bind(channels), + all: channels.all.bind(channels), + list: channels.list.bind(channels), + get: channels.get.bind(channels), + join: channels.join.bind(channels), + leave: channels.leave.bind(channels), + restrict: channels.restrict.bind(channels), + getRestrictions: channels.getRestrictions.bind(channels), + clearChannelData: channels.clearChannelData.bind(channels), + restrictAll: channels.restrictAll.bind(channels), + current: channels.current.bind(channels), + my: channels.my.bind(channels), + changed: channels.changed.bind(channels), + onChanged: channels.onChanged.bind(channels), + add: channels.add.bind(channels), + remove: channels.remove.bind(channels), + getWindowsOnChannel: channels.getWindowsOnChannel.bind(channels), + getWindowsWithChannels: channels.getWindowsWithChannels.bind(channels), + getMy: channels.getMy.bind(channels), + ready: async () => { + await Promise.all([contexts.ready(), channelsReadyPromise]); + }, + get mode() { return channels.mode; }, + getMyChannels: channels.getMyChannels.bind(channels), + myChannels: channels.myChannels.bind(channels), + onChannelsChanged: channels.onChannelsChanged.bind(channels), + }; + } + + const CommandMethod = "T42.Hotkeys.Command"; + const InvokeMethod = "T42.Hotkeys.Invoke"; + const RegisterCommand = "register"; + const UnregisterCommand = "unregister"; + const UnregisterAllCommand = "unregisterAll"; + class HotkeysImpl { + constructor(agm) { + this.agm = agm; + this.registry = CallbackRegistryFactory(); + this.firstHotkey = true; + this.hotkeys = new Map(); + } + async register(info, callback) { + if (typeof info === "undefined") { + throw new Error("Hotkey parameter missing"); + } + if (typeof info === "string") { + info = { + hotkey: info + }; + } + else { + if (!info.hotkey) { + throw new Error("Info's hotkey parameter missing"); + } + info = { + hotkey: info.hotkey, + description: info.description + }; + } + const hkToLower = this.formatHotkey(info.hotkey); + if (this.hotkeys.has(hkToLower)) { + throw new Error(`Shortcut for ${hkToLower} already registered`); + } + if (this.firstHotkey) { + this.firstHotkey = false; + await this.registerInvokeAGMMethod(); + } + this.registry.add(hkToLower, callback); + await this.agm.invoke(CommandMethod, { command: RegisterCommand, hotkey: hkToLower, description: info.description }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + this.hotkeys.set(hkToLower, info); + } + async unregister(hotkey) { + if (typeof hotkey === "undefined") { + throw new Error("hotkey parameter missing"); + } + if (typeof hotkey !== "string") { + throw new Error("hotkey parameter must be string"); + } + const hkToLower = this.formatHotkey(hotkey); + await this.agm.invoke(CommandMethod, { command: UnregisterCommand, hotkey: hkToLower }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + this.hotkeys.delete(hkToLower); + this.registry.clearKey(hkToLower); + } + async unregisterAll() { + await this.agm.invoke(CommandMethod, { command: UnregisterAllCommand }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + this.hotkeys.clear(); + this.registry.clear(); + } + isRegistered(hotkey) { + const hkToLower = this.formatHotkey(hotkey); + return this.hotkeys.has(hkToLower); + } + registerInvokeAGMMethod() { + return this.agm.register(InvokeMethod, (args) => { + const hkToLower = args.key.toLowerCase(); + const info = this.hotkeys.get(hkToLower); + this.registry.execute(hkToLower, info); + }); + } + formatHotkey(hotkey) { + if (hotkey) { + return hotkey.replace(/\s/g, "").toLowerCase(); + } + } + } + + function factory$3(agm) { + const hotkeys = new HotkeysImpl(agm); + return { + register: hotkeys.register.bind(hotkeys), + unregister: hotkeys.unregister.bind(hotkeys), + unregisterAll: hotkeys.unregisterAll.bind(hotkeys), + isRegistered: hotkeys.isRegistered.bind(hotkeys), + ready: () => Promise.resolve() + }; + } + + var version = "6.12.0"; + + var prepareConfig = (options) => { + function getLibConfig(value, defaultMode, trueMode) { + if (typeof value === "boolean" && !value) { + return undefined; + } + const mode = getModeAsString(value, defaultMode, trueMode); + if (typeof mode === "undefined") { + return undefined; + } + if (typeof value === "object") { + value.mode = mode; + return value; + } + return { + mode, + }; + } + function getModeAsString(value, defaultMode, trueMode) { + if (typeof value === "object") { + return getModeAsString(value.mode, defaultMode, trueMode).toString(); + } + else if (typeof value === "undefined") { + if (typeof defaultMode === "boolean" && !defaultMode) { + return undefined; + } + else if (typeof defaultMode === "boolean" && defaultMode) { + return typeof trueMode === "undefined" ? defaultMode : trueMode; + } + else if (typeof defaultMode === "undefined") { + return undefined; + } + else { + return defaultMode; + } + } + else if (typeof value === "boolean") { + if (value) { + return (typeof trueMode === "undefined") ? defaultMode : trueMode; + } + else { + return undefined; + } + } + return value; + } + const appDefaultMode = true; + const appDefaultTrueMode = "startOnly"; + const activitiesDefaultMode = Utils.isNode() ? false : "trackMyTypeAndInitiatedFromMe"; + const activitiesTrueMode = "trackMyTypeAndInitiatedFromMe"; + const layoutsDefaultMode = "slim"; + const layoutsTrueMode = layoutsDefaultMode; + const channelsConfig = () => { + if (typeof options.channels === "boolean") { + return options.channels; + } + else if (typeof options.channels === "object" && typeof options.channels.enabled === "boolean" && options.channels.enabled) { + return { mode: true, ...options.channels }; + } + else { + return false; + } + }; + const exposeAPI = typeof options.exposeAPI === "boolean" || typeof options.exposeGlue === "boolean"; + return { + layouts: getLibConfig(options.layouts, layoutsDefaultMode, layoutsTrueMode), + activities: getLibConfig(options.activities, activitiesDefaultMode, activitiesTrueMode), + appManager: getLibConfig(options.appManager, appDefaultMode, appDefaultTrueMode), + windows: getLibConfig(options.windows, true, true), + channels: getLibConfig(channelsConfig(), false, true), + displays: getLibConfig(options.displays, true, true), + exposeAPI: exposeAPI ? exposeAPI : true + }; + }; + + class Glue42Notification { + constructor(options) { + this.options = options; + this.callbacks = CallbackRegistryFactory(); + this.actions = options.actions; + this.body = options.body; + this.badge = options.badge; + this.data = options.data; + this.dir = options.dir; + this.icon = options.icon; + this.image = options.image; + this.lang = options.lang; + this.renotify = options.renotify; + this.requireInteraction = options.requireInteraction; + this.silent = options.silent; + this.tag = options.tag; + this.timestamp = options.timestamp; + this.title = options.title; + } + close() { + throw new Error("Method not implemented."); + } + addEventListener(type, listener, options) { + this.callbacks.add(type, listener); + } + removeEventListener(type, listener, options) { + } + dispatchEvent(event) { + this.callbacks.execute(event.type, event); + return true; + } + } + + class PanelAPI { + constructor(interop, onStreamEvent) { + this.interop = interop; + this.onStreamEvent = onStreamEvent; + } + onVisibilityChanged(callback) { + return this.onStreamEvent("on-panel-visibility-changed", callback); + } + toggle() { + return this.interop.invoke("T42.Notifications.Show", undefined, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + show() { + return this.interop.invoke("T42.Notifications.Show", { show: true }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + hide() { + return this.interop.invoke("T42.Notifications.Hide"); + } + async isVisible() { + const interopResult = await this.interop.invoke("T42.Notifications.Execute", { command: "isPanelVisible" }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return interopResult.returned.panelVisible; + } + toAPI() { + return { + onVisibilityChanged: this.onVisibilityChanged.bind(this), + toggle: this.toggle.bind(this), + show: this.show.bind(this), + hide: this.hide.bind(this), + isVisible: this.isVisible.bind(this) + }; + } + } + + const STARTING_INDEX = 0; + class Notifications { + constructor(interop, logger) { + this.interop = interop; + this.NotificationsSubscribeStream = "T42.GNS.Subscribe.Notifications"; + this.NotificationsCounterStream = "T42.Notifications.Counter"; + this.RaiseNotificationMethodName = "T42.GNS.Publish.RaiseNotification"; + this.NotificationsExecuteMethod = "T42.Notifications.Execute"; + this.NotificationFilterMethodName = "T42.Notifications.Filter"; + this.methodsRegistered = false; + this.NOTIFICATIONS_CONFIGURE_METHOD_NAME = "T42.Notifications.Configure"; + this.methodNameRoot = "T42.Notifications.Handler-" + Utils.generateId(); + this.nextId = 0; + this.notifications = {}; + this.registry = CallbackRegistryFactory(); + this.subscribedForNotifications = false; + this.subscribedCounterStream = false; + this.subscriptionsCountForNotifications = 0; + this.subscriptionsCountForCounter = 0; + this.logger = logger.subLogger("notifications"); + this._panel = new PanelAPI(interop, this.onStreamEventCore.bind(this)); + this._panelAPI = this._panel.toAPI(); + this.subscribeInternalEvents(); + } + get maxActions() { + return 10; + } + get panel() { + return this._panelAPI; + } + async raise(options) { + var _a; + const notification = await this.createNotification(options); + const g42notification = new Glue42Notification(options); + this.notifications[notification.id] = g42notification; + try { + const invocationResult = await this.interop.invoke(this.RaiseNotificationMethodName, { notification }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + g42notification.id = (_a = invocationResult.returned) === null || _a === void 0 ? void 0 : _a.id; + } + catch (err) { + const errorMessage = err.message; + setTimeout(() => { + this.handleNotificationErrorEvent(g42notification, errorMessage); + }, 1); + } + return g42notification; + } + async setFilter(filter) { + const result = await this.interop.invoke(this.NotificationFilterMethodName, filter, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return result.returned; + } + async getFilter() { + const result = await this.interop.invoke(this.NotificationFilterMethodName, undefined, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return result.returned; + } + async configure(options) { + var _a, _b, _c, _d, _e, _f, _g, _h; + if (!options || Array.isArray(options)) { + throw new Error("Invalid options - should be an object."); + } + if (Object.values(options).length === 0) { + throw new Error("The argument must be a non-empty object."); + } + if (typeof options.enable !== "undefined" && typeof options.enable !== "boolean") { + throw new Error("Expected type of enabled - boolean."); + } + if (typeof options.enableToasts !== "undefined" && typeof options.enableToasts !== "boolean") { + throw new Error("Expected type of enableToasts - boolean."); + } + if (typeof options.toastExpiry !== "undefined" && typeof options.toastExpiry !== "number") { + throw new Error("Expected type of toastExpiry - number."); + } + if (options.sourceFilter && typeof options.sourceFilter !== "object") { + throw new Error("Expected type of sourceFilter - object."); + } + if (((_a = options.sourceFilter) === null || _a === void 0 ? void 0 : _a.allowed) && !Array.isArray((_b = options.sourceFilter) === null || _b === void 0 ? void 0 : _b.allowed)) { + throw new Error("Expected type of sourceFilter.allowed - array."); + } + if (((_c = options.sourceFilter) === null || _c === void 0 ? void 0 : _c.blocked) && !Array.isArray((_d = options.sourceFilter) === null || _d === void 0 ? void 0 : _d.blocked)) { + throw new Error("Expected type of sourceFilter.blocked - array."); + } + if (options.toasts && typeof options.toasts !== "object") { + throw new Error("Expected type of (options.toasts - object."); + } + if (((_e = options.toasts) === null || _e === void 0 ? void 0 : _e.mode) && typeof options.toasts.mode !== "string") { + throw new Error("Expected type of (options.toasts.mode - string."); + } + if (((_f = options.toasts) === null || _f === void 0 ? void 0 : _f.stackBy) && typeof options.toasts.stackBy !== "string") { + throw new Error("Expected type of (options.toasts.stackBy - string."); + } + if (options.placement && typeof options.placement !== "object") { + throw new Error("Expected type of (options.placement - object."); + } + if (((_g = options.placement) === null || _g === void 0 ? void 0 : _g.toasts) && typeof options.placement.toasts !== "string") { + throw new Error("Expected type of (options.placement.toasts - string."); + } + if (((_h = options.placement) === null || _h === void 0 ? void 0 : _h.panel) && typeof options.placement.panel !== "string") { + throw new Error("Expected type of (options.placement.panel - string."); + } + if (typeof options.closeNotificationOnClick !== "undefined" && typeof options.closeNotificationOnClick !== "boolean") { + throw new Error("Expected type of closeNotificationOnClick - boolean."); + } + const result = await this.interop.invoke(this.NOTIFICATIONS_CONFIGURE_METHOD_NAME, options, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return result.returned; + } + async getConfiguration() { + const result = await this.interop.invoke(this.NotificationsExecuteMethod, { command: "getConfiguration" }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return result.returned; + } + async list() { + const interopResult = await this.interop.invoke(this.NotificationsExecuteMethod, { + command: "list", + data: { statesVersion2: true } + }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return interopResult.returned.notifications; + } + async updateData(id, data) { + const replacer = (key, value) => typeof value === "undefined" ? null : value; + const attribute = { + key: "data", + value: { + stringValue: JSON.stringify(data, replacer) + } + }; + const interopResult = await this.interop.invoke(this.NotificationsExecuteMethod, { command: "create-or-update-attribute", data: { id, attribute } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return interopResult.returned; + } + onRaised(callback) { + return this.onStreamEventCore("on-notification-raised", callback); + } + onStateChanged(callback) { + return this.onStreamEventCore("on-state-changed", callback); + } + onClosed(callback) { + return this.onStreamEventCore("on-notification-closed", callback); + } + onConfigurationChanged(callback) { + if (typeof callback !== "function") { + throw new Error("Please provide the callback as a function!"); + } + this.subscribe(); + const un = this.registry.add("on-configuration-changed", callback); + return () => { + un(); + this.closeStreamSubscriptionIfNoNeeded(); + }; + } + onCounterChanged(callback) { + if (typeof callback !== "function") { + throw new Error("Please provide the callback as a function!"); + } + this.subscribeForCounterStream(); + const un = this.registry.add("on-counter-changed", callback); + return () => { + un(); + this.closeStreamCounterSubscriptionIfNoNeeded(); + }; + } + onDataChanged(callback) { + if (typeof callback !== "function") { + throw new Error("Please provide the callback as a function!"); + } + this.subscribe(); + const un = this.registry.add("on-notification-data-changed", callback); + return () => { + un(); + this.closeStreamSubscriptionIfNoNeeded(); + }; + } + async clearAll() { + await this.interop.invoke(this.NotificationsExecuteMethod, { command: "clearAll" }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async clearOld() { + await this.interop.invoke(this.NotificationsExecuteMethod, { command: "clearAllOld", data: { statesVersion2: true } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async clear(id) { + if (!id) { + throw new Error("The 'id' argument cannot be null or undefined"); + } + if (typeof (id) !== "string") { + throw new Error("The 'id' argument must be a string"); + } + await this.interop.invoke(this.NotificationsExecuteMethod, { command: "clear", data: { id } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async clearMany(notifications) { + this.validateNotificationsArr(notifications); + await this.interop.invoke(this.NotificationsExecuteMethod, { command: "clearMany", data: { notifications } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async click(id, action, options) { + await this.interop.invoke(this.NotificationsExecuteMethod, { command: "click", data: { id, action, options } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async snooze(id, duration) { + await this.interop.invoke(this.NotificationsExecuteMethod, { command: "snooze", data: { id, duration } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async snoozeMany(notifications, duration) { + if (!duration) { + throw new Error("The 'duration' argument cannot be null or undefined"); + } + if (typeof duration !== "number") { + throw new Error("The 'duration' argument must be a valid number"); + } + this.validateNotificationsArr(notifications); + await this.interop.invoke(this.NotificationsExecuteMethod, { command: "snoozeMany", data: { notifications, duration } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async setState(id, state) { + if (!id) { + throw new Error("The 'id' argument cannot be null or undefined"); + } + if (typeof (id) !== "string") { + throw new Error("The 'id' argument must be a string"); + } + if (!state) { + throw new Error("The 'state' argument cannot be null or undefined"); + } + this.validateState(state); + await this.interop.invoke(this.NotificationsExecuteMethod, { command: "updateState", data: { id, state } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async setStates(notifications, state) { + if (!state) { + throw new Error("The 'state' argument cannot be null or undefined"); + } + if (typeof state !== "string") { + throw new Error("The 'state' argument must be a valid string"); + } + this.validateNotificationsArr(notifications); + await this.interop.invoke(this.NotificationsExecuteMethod, { command: "updateStates", data: { notifications, state } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + toAPI() { + return { + maxActions: this.maxActions, + panel: this._panel.toAPI(), + raise: this.raise.bind(this), + setFilter: this.setFilter.bind(this), + getFilter: this.getFilter.bind(this), + configure: this.configure.bind(this), + getConfiguration: this.getConfiguration.bind(this), + list: this.list.bind(this), + onRaised: this.onRaised.bind(this), + onStateChanged: this.onStateChanged.bind(this), + onClosed: this.onClosed.bind(this), + onConfigurationChanged: this.onConfigurationChanged.bind(this), + onCounterChanged: this.onCounterChanged.bind(this), + onDataChanged: this.onDataChanged.bind(this), + clearAll: this.clearAll.bind(this), + clearOld: this.clearOld.bind(this), + clear: this.clear.bind(this), + click: this.click.bind(this), + setState: this.setState.bind(this), + updateData: this.updateData.bind(this), + snooze: this.snooze.bind(this), + snoozeMany: this.snoozeMany.bind(this), + clearMany: this.clearMany.bind(this), + setStates: this.setStates.bind(this), + import: this.importNotifications.bind(this) + }; + } + async importNotifications(notifications) { + if (!notifications || !Array.isArray(notifications) || notifications.length === 0) { + throw new Error("Notifications argument must be a valid array with notification options"); + } + const notificationsToImport = await Promise.all(notifications.map((notificationOptions) => this.createNotification(notificationOptions, true))); + const invocationResult = await this.interop.invoke(this.NotificationsExecuteMethod, { command: "importNotifications", data: { notificationSettings: notificationsToImport } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return invocationResult.returned.notifications; + } + async createNotification(options, imported) { + var _a, _b, _c, _d; + this.validate(options, imported); + if (!this.methodsRegistered) { + const bunchOfPromises = []; + for (let index = STARTING_INDEX; index < this.maxActions; index++) { + bunchOfPromises.push(this.interop.register(`${this.methodNameRoot}_${index}`, this.handleNotificationEvent.bind(this))); + } + this.methodsRegistered = true; + await Promise.all(bunchOfPromises); + } + const id = (_a = options.id) !== null && _a !== void 0 ? _a : Utils.generateId(); + const type = (_b = options.type) !== null && _b !== void 0 ? _b : "Notification"; + const notification = { + id, + state: (_c = options.state) !== null && _c !== void 0 ? _c : "Active", + title: options.title, + type, + severity: (_d = options.severity) !== null && _d !== void 0 ? _d : "None", + description: options.body, + glueRoutingDetailMethodName: `${this.methodNameRoot}_${STARTING_INDEX}`, + actions: [], + sourceId: id, + source: options.source, + publishExtraEvents: true, + clickInterop: options.clickInterop + }; + if (options.actions) { + this.handleActions(options, id, notification); + } + this.handleOptions(options, notification); + return notification; + } + onStreamEventCore(key, callback) { + if (typeof callback !== "function") { + throw new Error("Please provide the callback as a function!"); + } + this.subscribe(); + const un = this.registry.add(key, callback); + return () => { + un(); + this.closeStreamSubscriptionIfNoNeeded(); + }; + } + handleOptions(options, notification) { + if (options.icon) { + notification.attributes = notification.attributes || []; + notification.attributes.push({ key: "icon", value: { stringValue: options.icon } }); + } + if (options.data) { + notification.attributes = notification.attributes || []; + const dataAsString = JSON.stringify(options.data); + notification.attributes.push({ key: "data", value: { stringValue: dataAsString } }); + } + if (typeof options.panelExpiry === "number") { + notification.attributes = notification.attributes || []; + notification.attributes.push({ key: "panelExpiry", value: { stringValue: options.panelExpiry.toString() } }); + } + if (typeof options.toastExpiry === "number") { + notification.attributes = notification.attributes || []; + notification.attributes.push({ key: "toastExpiry", value: { stringValue: options.toastExpiry.toString() } }); + } + } + handleActions(options, id, notification) { + var _a, _b, _c; + const validActions = options.actions.slice(0, this.maxActions); + let index = STARTING_INDEX; + for (const action of validActions) { + const args = { + g42notificationId: id, + g42action: action.action, + g42interopMethod: (_a = action.interop) === null || _a === void 0 ? void 0 : _a.method, + g42interopTarget: (_b = action.interop) === null || _b === void 0 ? void 0 : _b.target, + g42interopArguments: JSON.stringify((_c = action.interop) === null || _c === void 0 ? void 0 : _c.arguments) + }; + const parameters = Object.keys(args).map((key) => { + const value = args[key]; + return { + name: key, + value: { + stringValue: value + } + }; + }); + const glueAction = { + name: `${this.methodNameRoot}_${index}`, + description: action.title, + displayName: action.title, + displayPath: action.displayPath, + displayId: action.displayId, + parameters + }; + notification.actions.push(glueAction); + index++; + } + } + validate(options, imported) { + if (!options) { + throw new Error("invalid options - should be an object"); + } + if (typeof options !== "object") { + throw new Error("invalid options - should be an object"); + } + if (!options.title) { + throw new Error("invalid options - should have a title"); + } + if (typeof options.title !== "string") { + throw new Error("invalid options - title should be a string"); + } + if (options.severity && typeof options.severity !== "string") { + throw new Error("invalid options - severity should be a string"); + } + if (options.panelExpiry && typeof options.panelExpiry !== "number") { + throw new Error("invalid options - panelExpiry should be a number"); + } + if (options.toastExpiry && typeof options.toastExpiry !== "number") { + throw new Error("invalid options - toastExpiry should be a number"); + } + if (options.state) { + this.validateState(options.state, imported); + } + } + validateState(state, imported) { + if (typeof (state) !== "string") { + throw new Error("The 'state' argument must be a string"); + } + const validStates = [ + "Active", + "Acknowledged", + "Stale" + ]; + if (imported) { + validStates.push("Seen", "Snoozed", "Processing", "Closed"); + } + if (!validStates.includes(state)) { + throw new Error(`The state argument: ${state} is not valid!`); + } + } + subscribe() { + this.subscriptionsCountForNotifications++; + if (!this.subscribedForNotifications) { + this.subscribedForNotifications = true; + this.logger.info(`Attempting to subscribe to "${this.NotificationsSubscribeStream}".`); + this.interop + .subscribe(this.NotificationsSubscribeStream, { + arguments: { + sendDeltaOnly: true, + statesVersion2: true + } + }) + .then((sub) => { + this.subscriptionForNotifications = sub; + this.logger.info(`Successfully subscribed to "${this.NotificationsSubscribeStream}".`); + sub.onData(({ data }) => { + this.handleData(data); + }); + sub.onClosed((...args) => { + this.subscribedForNotifications = false; + this.logger.info(`Stream subscription Closed - ${JSON.stringify(args)}`); + }); + sub.onFailed((...args) => { + this.subscribedForNotifications = false; + this.logger.warn(`Stream subscription Failed - ${JSON.stringify(args)}`); + }); + }) + .catch((e) => { + this.subscribedForNotifications = false; + this.logger.error(`Unable to subscribe to "${this.NotificationsSubscribeStream}"`, e); + }); + } + } + subscribeForCounterStream() { + this.subscriptionsCountForCounter++; + if (!this.subscribedCounterStream) { + this.subscribedCounterStream = true; + this.logger.info(`Attempting to subscribe to "${this.NotificationsCounterStream}".`); + this.interop + .subscribe(this.NotificationsCounterStream, { + arguments: { + sendDeltaOnly: true + } + }) + .then((sub) => { + this.subscriptionForCounter = sub; + this.logger.info(`Successfully subscribed to "${this.NotificationsCounterStream}".`); + sub.onData(({ data }) => { + this.registry.execute("on-counter-changed", { count: data.count }); + }); + sub.onClosed((...args) => { + this.subscribedCounterStream = false; + this.logger.info(`Stream subscription Closed - ${JSON.stringify(args)}`); + }); + sub.onFailed((...args) => { + this.subscribedCounterStream = false; + this.logger.warn(`Stream subscription Failed - ${JSON.stringify(args)}`); + }); + }) + .catch((e) => { + this.subscribedCounterStream = false; + this.logger.error(`Unable to subscribe to "${this.NotificationsCounterStream}"`, e); + }); + } + } + subscribeInternalEvents() { + this.registry.add("on-notification-closed", (id) => { + this.handleOnClosed(id); + }); + this.registry.add("on-notification-raised", (notification) => { + this.handleOnShow(notification.id); + }); + } + handleData(message) { + var _a; + try { + if ("items" in message && Array.isArray(message.items)) { + this.handleItemsData(message); + } + else if ("deltas" in message && Array.isArray(message.deltas)) { + this.handleDeltas(message); + } + if ("configuration" in message && typeof message.configuration === "object") { + this.logger.info(`Received configuration ${JSON.stringify(message.configuration)} from the stream`); + this.registry.execute("on-configuration-changed", message.configuration, message.configuration.allApplications); + } + if ("command" in message && typeof message.command === "string") { + this.logger.info(`Received command "${(_a = message.command) !== null && _a !== void 0 ? _a : JSON.stringify(message)}" from the stream`); + if (message.command === "showPanel" || message.command === "hidePanel") { + this.registry.execute("on-panel-visibility-changed", message.command === "showPanel"); + } + } + } + catch (e) { + this.logger.error(`Failed to parse data from the stream`, e); + } + } + handleItemsData(message) { + const items = message.items; + this.logger.info(`Received ${items.length} notifications from the stream`); + const notifications = items; + if (message.isSnapshot) { + notifications.forEach((n) => { + this.registry.execute("on-notification-raised", n); + }); + } + else { + const notification = notifications[0]; + if (notification.state === "Closed") { + this.registry.execute("on-notification-closed", { id: notification.id }); + } + else { + this.registry.execute("on-notification-raised", notification); + } + } + } + handleDeltas(message) { + const deltas = message.deltas; + deltas.forEach((info) => { + var _a; + const id = info.id; + const delta = (_a = info.delta) !== null && _a !== void 0 ? _a : {}; + if (delta.state === "Closed") { + this.registry.execute("on-notification-closed", { id, ...delta }); + } + else if (delta.state) { + this.registry.execute("on-state-changed", { id }, delta.state); + } + else if (delta.attributes) { + const attributes = delta.attributes; + const dataAttribute = attributes.find((a) => a.key === "data"); + if (dataAttribute) { + this.registry.execute("on-notification-data-changed", { id }, JSON.parse(dataAttribute.value.stringValue)); + } + } + }); + } + handleOnClosed(id) { + const { notification, key } = this.getNotification(id); + if (notification) { + this.handleEvent(notification, "close"); + delete this.notifications[key]; + } + } + handleOnShow(id) { + const { notification } = this.getNotification(id); + if (notification) { + this.handleEvent(notification, "show"); + } + } + getNotification(id) { + let notification; + let key; + for (const k in this.notifications) { + if (this.notifications[k].id === id) { + notification = this.notifications[k]; + key = k; + break; + } + } + return { notification, key }; + } + handleNotificationEvent(args) { + const gnsNotificationArgs = this.getGnsNotificationArgs(args); + if (gnsNotificationArgs.event === "unknown") { + return; + } + const notification = this.notifications[gnsNotificationArgs.notificationId]; + if (!notification) { + return; + } + this.handleNotificationEventCore(notification, gnsNotificationArgs); + } + handleNotificationEventCore(notification, args) { + switch (args.event) { + case "action": { + return this.handleNotificationActionEvent(notification, args.notificationActionPayload); + } + case "click": { + return this.handleNotificationClickEvent(notification); + } + case "close": { + return this.handleEvent(notification, "close"); + } + case "error": { + return this.handleNotificationErrorEvent(notification, args.error); + } + case "show": { + return this.handleEvent(notification, "show"); + } + } + } + handleNotificationActionEvent(notification, payload) { + const event = { + type: "onaction", + action: payload.g42action + }; + if (notification.onaction) { + notification.onaction(event); + } + notification.dispatchEvent(event); + } + handleNotificationClickEvent(notification) { + const event = { type: "onclick" }; + if (notification.onclick) { + notification.onclick(event); + } + notification.dispatchEvent(event); + } + handleEvent(notification, eventType) { + var _a; + const event = { type: eventType }; + const eventName = `on${eventType}`; + (_a = notification[eventName]) === null || _a === void 0 ? void 0 : _a.call(notification, event); + notification.dispatchEvent(event); + } + handleNotificationErrorEvent(notification, error) { + const event = { type: "onerror", error }; + if (notification.onerror) { + notification.onerror(event); + } + notification.dispatchEvent(event); + } + getGnsNotificationArgs(args) { + var _a; + let result; + const event = (_a = args.notification) === null || _a === void 0 ? void 0 : _a.event; + if (!event) { + result = this.getBackwardGnsNotificationArgs(args); + } + else { + result = { + event, + notificationId: args.notification.sourceNotificationId, + notificationActionPayload: args + }; + } + return result; + } + getBackwardGnsNotificationArgs(args) { + var _a; + let result; + if (args.g42notificationId) { + result = { + event: "action", + notificationId: args.g42notificationId, + notificationActionPayload: args + }; + } + else if ((_a = args.notification) === null || _a === void 0 ? void 0 : _a.sourceNotificationId) { + result = { + event: "click", + notificationId: args.notification.sourceNotificationId, + notificationActionPayload: args + }; + } + else { + result = { + event: "unknown", + notificationId: undefined, + notificationActionPayload: args + }; + } + return result; + } + closeStreamSubscriptionIfNoNeeded() { + this.subscriptionsCountForNotifications--; + if (this.subscriptionForNotifications && this.subscriptionsCountForNotifications === 0) { + this.subscriptionForNotifications.close(); + this.subscriptionForNotifications = undefined; + } + } + closeStreamCounterSubscriptionIfNoNeeded() { + this.subscriptionsCountForCounter--; + if (this.subscriptionForCounter && this.subscriptionsCountForCounter === 0) { + this.subscriptionForCounter.close(); + this.subscriptionForCounter = undefined; + } + } + validateNotificationsArr(notifications) { + if (!Array.isArray(notifications)) { + throw new Error("The 'notifications' argument must be an array with valid notification IDs"); + } + if (notifications.some((n) => typeof n !== "string")) { + throw new Error("The 'notifications' argument must contain only valid string notification IDs"); + } + } + } + + const ThemesConfigurationMethodName = "T42.Themes.Configuration"; + class ThemesImpl { + constructor(contexts, interop) { + this.contexts = contexts; + this.interop = interop; + this.registry = CallbackRegistryFactory(); + this.isSubscribed = false; + this.getConfiguration(); + } + async list() { + await this.getConfiguration(); + if (!this.getMethodName) { + throw new Error("not supported"); + } + return (await this.getAll()).returned.all; + } + async getCurrent() { + await this.getConfiguration(); + if (!this.getMethodName) { + throw new Error("not supported"); + } + const all = await this.getAll(); + return all.returned.all.find((t) => t.name === all.returned.selected); + } + async select(theme) { + await this.getConfiguration(); + if (!this.setMethodName) { + throw new Error("not supported"); + } + await this.interop.invoke(this.setMethodName, { theme }); + } + onChanged(callback) { + if (!callback) { + throw new Error("Callback argument is required"); + } + if (callback && typeof callback !== "function") { + throw new Error("Callback argument must be a function"); + } + this.subscribe(); + return this.registry.add("changed", callback); + } + async getConfiguration() { + try { + if (this.sharedContextName) { + return; + } + const config = await this.interop.invoke(ThemesConfigurationMethodName); + this.sharedContextName = config.returned.sharedContextName; + this.getMethodName = config.returned.getThemesMethodName; + this.setMethodName = config.returned.setThemesMethodName; + } + catch (error) { + return; + } + } + async getAll() { + await this.getConfiguration(); + return await this.interop.invoke(this.getMethodName); + } + async subscribe() { + await this.getConfiguration(); + if (this.isSubscribed) { + return; + } + this.isSubscribed = true; + this.contexts.subscribe(this.sharedContextName, (data) => { + if (data && data.all && data.selected) { + this.registry.execute("changed", data.all.find((t) => t.name === data.selected)); + } + }); + } + } + + function factory$2(contexts, interop) { + const themes = new ThemesImpl(contexts, interop); + return { + list: themes.list.bind(themes), + getCurrent: themes.getCurrent.bind(themes), + select: themes.select.bind(themes), + onChanged: themes.onChanged.bind(themes), + ready: () => Promise.resolve(), + }; + } + + const connectBrowserAppProps = ["name", "title", "version", "customProperties", "icon", "caption", "type"]; + const fdc3v2AppProps = ["appId", "name", "type", "details", "version", "title", "tooltip", "lang", "description", "categories", "icons", "screenshots", "contactEmail", "moreInfo", "publisher", "customConfig", "hostManifests", "interop", "localizedVersions"]; + + /** + * Wraps values in an `Ok` type. + * + * Example: `ok(5) // => {ok: true, result: 5}` + */ + var ok = function (result) { return ({ ok: true, result: result }); }; + /** + * Wraps errors in an `Err` type. + * + * Example: `err('on fire') // => {ok: false, error: 'on fire'}` + */ + var err = function (error) { return ({ ok: false, error: error }); }; + /** + * Create a `Promise` that either resolves with the result of `Ok` or rejects + * with the error of `Err`. + */ + var asPromise = function (r) { + return r.ok === true ? Promise.resolve(r.result) : Promise.reject(r.error); + }; + /** + * Unwraps a `Result` and returns either the result of an `Ok`, or + * `defaultValue`. + * + * Example: + * ``` + * Result.withDefault(5, number().run(json)) + * ``` + * + * It would be nice if `Decoder` had an instance method that mirrored this + * function. Such a method would look something like this: + * ``` + * class Decoder
{ + * runWithDefault = (defaultValue: A, json: any): A => + * Result.withDefault(defaultValue, this.run(json)); + * } + * + * number().runWithDefault(5, json) + * ``` + * Unfortunately, the type of `defaultValue: A` on the method causes issues + * with type inference on the `object` decoder in some situations. While these + * inference issues can be solved by providing the optional type argument for + * `object`s, the extra trouble and confusion doesn't seem worth it. + */ + var withDefault = function (defaultValue, r) { + return r.ok === true ? r.result : defaultValue; + }; + /** + * Return the successful result, or throw an error. + */ + var withException = function (r) { + if (r.ok === true) { + return r.result; + } + else { + throw r.error; + } + }; + /** + * Apply `f` to the result of an `Ok`, or pass the error through. + */ + var map = function (f, r) { + return r.ok === true ? ok(f(r.result)) : r; + }; + /** + * Apply `f` to the result of two `Ok`s, or pass an error through. If both + * `Result`s are errors then the first one is returned. + */ + var map2 = function (f, ar, br) { + return ar.ok === false ? ar : + br.ok === false ? br : + ok(f(ar.result, br.result)); + }; + /** + * Apply `f` to the error of an `Err`, or pass the success through. + */ + var mapError = function (f, r) { + return r.ok === true ? r : err(f(r.error)); + }; + /** + * Chain together a sequence of computations that may fail, similar to a + * `Promise`. If the first computation fails then the error will propagate + * through. If it succeeds, then `f` will be applied to the value, returning a + * new `Result`. + */ + var andThen = function (f, r) { + return r.ok === true ? f(r.result) : r; + }; + + /*! ***************************************************************************** + Copyright (c) Microsoft Corporation. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THIS SOFTWARE. + ***************************************************************************** */ + /* global Reflect, Promise */ + + + + var __assign = function() { + __assign = Object.assign || function __assign(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; + } + return t; + }; + return __assign.apply(this, arguments); + }; + + function __rest(s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { + if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) + t[p[i]] = s[p[i]]; + } + return t; + } + + function isEqual(a, b) { + if (a === b) { + return true; + } + if (a === null && b === null) { + return true; + } + if (typeof (a) !== typeof (b)) { + return false; + } + if (typeof (a) === 'object') { + // Array + if (Array.isArray(a)) { + if (!Array.isArray(b)) { + return false; + } + if (a.length !== b.length) { + return false; + } + for (var i = 0; i < a.length; i++) { + if (!isEqual(a[i], b[i])) { + return false; + } + } + return true; + } + // Hash table + var keys = Object.keys(a); + if (keys.length !== Object.keys(b).length) { + return false; + } + for (var i = 0; i < keys.length; i++) { + if (!b.hasOwnProperty(keys[i])) { + return false; + } + if (!isEqual(a[keys[i]], b[keys[i]])) { + return false; + } + } + return true; + } + } + /* + * Helpers + */ + var isJsonArray = function (json) { return Array.isArray(json); }; + var isJsonObject = function (json) { + return typeof json === 'object' && json !== null && !isJsonArray(json); + }; + var typeString = function (json) { + switch (typeof json) { + case 'string': + return 'a string'; + case 'number': + return 'a number'; + case 'boolean': + return 'a boolean'; + case 'undefined': + return 'undefined'; + case 'object': + if (json instanceof Array) { + return 'an array'; + } + else if (json === null) { + return 'null'; + } + else { + return 'an object'; + } + default: + return JSON.stringify(json); + } + }; + var expectedGot = function (expected, got) { + return "expected " + expected + ", got " + typeString(got); + }; + var printPath = function (paths) { + return paths.map(function (path) { return (typeof path === 'string' ? "." + path : "[" + path + "]"); }).join(''); + }; + var prependAt = function (newAt, _a) { + var at = _a.at, rest = __rest(_a, ["at"]); + return (__assign({ at: newAt + (at || '') }, rest)); + }; + /** + * Decoders transform json objects with unknown structure into known and + * verified forms. You can create objects of type `Decoder` with either the + * primitive decoder functions, such as `boolean()` and `string()`, or by + * applying higher-order decoders to the primitives, such as `array(boolean())` + * or `dict(string())`. + * + * Each of the decoder functions are available both as a static method on + * `Decoder` and as a function alias -- for example the string decoder is + * defined at `Decoder.string()`, but is also aliased to `string()`. Using the + * function aliases exported with the library is recommended. + * + * `Decoder` exposes a number of 'run' methods, which all decode json in the + * same way, but communicate success and failure in different ways. The `map` + * and `andThen` methods modify decoders without having to call a 'run' method. + * + * Alternatively, the main decoder `run()` method returns an object of type + * `Result`. This library provides a number of helper + * functions for dealing with the `Result` type, so you can do all the same + * things with a `Result` as with the decoder methods. + */ + var Decoder = /** @class */ (function () { + /** + * The Decoder class constructor is kept private to separate the internal + * `decode` function from the external `run` function. The distinction + * between the two functions is that `decode` returns a + * `Partial` on failure, which contains an unfinished error + * report. When `run` is called on a decoder, the relevant series of `decode` + * calls is made, and then on failure the resulting `Partial` + * is turned into a `DecoderError` by filling in the missing information. + * + * While hiding the constructor may seem restrictive, leveraging the + * provided decoder combinators and helper functions such as + * `andThen` and `map` should be enough to build specialized decoders as + * needed. + */ + function Decoder(decode) { + var _this = this; + this.decode = decode; + /** + * Run the decoder and return a `Result` with either the decoded value or a + * `DecoderError` containing the json input, the location of the error, and + * the error message. + * + * Examples: + * ``` + * number().run(12) + * // => {ok: true, result: 12} + * + * string().run(9001) + * // => + * // { + * // ok: false, + * // error: { + * // kind: 'DecoderError', + * // input: 9001, + * // at: 'input', + * // message: 'expected a string, got 9001' + * // } + * // } + * ``` + */ + this.run = function (json) { + return mapError(function (error) { return ({ + kind: 'DecoderError', + input: json, + at: 'input' + (error.at || ''), + message: error.message || '' + }); }, _this.decode(json)); + }; + /** + * Run the decoder as a `Promise`. + */ + this.runPromise = function (json) { return asPromise(_this.run(json)); }; + /** + * Run the decoder and return the value on success, or throw an exception + * with a formatted error string. + */ + this.runWithException = function (json) { return withException(_this.run(json)); }; + /** + * Construct a new decoder that applies a transformation to the decoded + * result. If the decoder succeeds then `f` will be applied to the value. If + * it fails the error will propagated through. + * + * Example: + * ``` + * number().map(x => x * 5).run(10) + * // => {ok: true, result: 50} + * ``` + */ + this.map = function (f) { + return new Decoder(function (json) { return map(f, _this.decode(json)); }); + }; + /** + * Chain together a sequence of decoders. The first decoder will run, and + * then the function will determine what decoder to run second. If the result + * of the first decoder succeeds then `f` will be applied to the decoded + * value. If it fails the error will propagate through. + * + * This is a very powerful method -- it can act as both the `map` and `where` + * methods, can improve error messages for edge cases, and can be used to + * make a decoder for custom types. + * + * Example of adding an error message: + * ``` + * const versionDecoder = valueAt(['version'], number()); + * const infoDecoder3 = object({a: boolean()}); + * + * const decoder = versionDecoder.andThen(version => { + * switch (version) { + * case 3: + * return infoDecoder3; + * default: + * return fail(`Unable to decode info, version ${version} is not supported.`); + * } + * }); + * + * decoder.run({version: 3, a: true}) + * // => {ok: true, result: {a: true}} + * + * decoder.run({version: 5, x: 'abc'}) + * // => + * // { + * // ok: false, + * // error: {... message: 'Unable to decode info, version 5 is not supported.'} + * // } + * ``` + * + * Example of decoding a custom type: + * ``` + * // nominal type for arrays with a length of at least one + * type NonEmptyArray = T[] & { __nonEmptyArrayBrand__: void }; + * + * const nonEmptyArrayDecoder = (values: Decoder): Decoder> => + * array(values).andThen(arr => + * arr.length > 0 + * ? succeed(createNonEmptyArray(arr)) + * : fail(`expected a non-empty array, got an empty array`) + * ); + * ``` + */ + this.andThen = function (f) { + return new Decoder(function (json) { + return andThen(function (value) { return f(value).decode(json); }, _this.decode(json)); + }); + }; + /** + * Add constraints to a decoder _without_ changing the resulting type. The + * `test` argument is a predicate function which returns true for valid + * inputs. When `test` fails on an input, the decoder fails with the given + * `errorMessage`. + * + * ``` + * const chars = (length: number): Decoder => + * string().where( + * (s: string) => s.length === length, + * `expected a string of length ${length}` + * ); + * + * chars(5).run('12345') + * // => {ok: true, result: '12345'} + * + * chars(2).run('HELLO') + * // => {ok: false, error: {... message: 'expected a string of length 2'}} + * + * chars(12).run(true) + * // => {ok: false, error: {... message: 'expected a string, got a boolean'}} + * ``` + */ + this.where = function (test, errorMessage) { + return _this.andThen(function (value) { return (test(value) ? Decoder.succeed(value) : Decoder.fail(errorMessage)); }); + }; + } + /** + * Decoder primitive that validates strings, and fails on all other input. + */ + Decoder.string = function () { + return new Decoder(function (json) { + return typeof json === 'string' + ? ok(json) + : err({ message: expectedGot('a string', json) }); + }); + }; + /** + * Decoder primitive that validates numbers, and fails on all other input. + */ + Decoder.number = function () { + return new Decoder(function (json) { + return typeof json === 'number' + ? ok(json) + : err({ message: expectedGot('a number', json) }); + }); + }; + /** + * Decoder primitive that validates booleans, and fails on all other input. + */ + Decoder.boolean = function () { + return new Decoder(function (json) { + return typeof json === 'boolean' + ? ok(json) + : err({ message: expectedGot('a boolean', json) }); + }); + }; + Decoder.constant = function (value) { + return new Decoder(function (json) { + return isEqual(json, value) + ? ok(value) + : err({ message: "expected " + JSON.stringify(value) + ", got " + JSON.stringify(json) }); + }); + }; + Decoder.object = function (decoders) { + return new Decoder(function (json) { + if (isJsonObject(json) && decoders) { + var obj = {}; + for (var key in decoders) { + if (decoders.hasOwnProperty(key)) { + var r = decoders[key].decode(json[key]); + if (r.ok === true) { + // tslint:disable-next-line:strict-type-predicates + if (r.result !== undefined) { + obj[key] = r.result; + } + } + else if (json[key] === undefined) { + return err({ message: "the key '" + key + "' is required but was not present" }); + } + else { + return err(prependAt("." + key, r.error)); + } + } + } + return ok(obj); + } + else if (isJsonObject(json)) { + return ok(json); + } + else { + return err({ message: expectedGot('an object', json) }); + } + }); + }; + Decoder.array = function (decoder) { + return new Decoder(function (json) { + if (isJsonArray(json) && decoder) { + var decodeValue_1 = function (v, i) { + return mapError(function (err$$1) { return prependAt("[" + i + "]", err$$1); }, decoder.decode(v)); + }; + return json.reduce(function (acc, v, i) { + return map2(function (arr, result) { return arr.concat([result]); }, acc, decodeValue_1(v, i)); + }, ok([])); + } + else if (isJsonArray(json)) { + return ok(json); + } + else { + return err({ message: expectedGot('an array', json) }); + } + }); + }; + Decoder.tuple = function (decoders) { + return new Decoder(function (json) { + if (isJsonArray(json)) { + if (json.length !== decoders.length) { + return err({ + message: "expected a tuple of length " + decoders.length + ", got one of length " + json.length + }); + } + var result = []; + for (var i = 0; i < decoders.length; i++) { + var nth = decoders[i].decode(json[i]); + if (nth.ok) { + result[i] = nth.result; + } + else { + return err(prependAt("[" + i + "]", nth.error)); + } + } + return ok(result); + } + else { + return err({ message: expectedGot("a tuple of length " + decoders.length, json) }); + } + }); + }; + Decoder.union = function (ad, bd) { + var decoders = []; + for (var _i = 2; _i < arguments.length; _i++) { + decoders[_i - 2] = arguments[_i]; + } + return Decoder.oneOf.apply(Decoder, [ad, bd].concat(decoders)); + }; + Decoder.intersection = function (ad, bd) { + var ds = []; + for (var _i = 2; _i < arguments.length; _i++) { + ds[_i - 2] = arguments[_i]; + } + return new Decoder(function (json) { + return [ad, bd].concat(ds).reduce(function (acc, decoder) { return map2(Object.assign, acc, decoder.decode(json)); }, ok({})); + }); + }; + /** + * Escape hatch to bypass validation. Always succeeds and types the result as + * `any`. Useful for defining decoders incrementally, particularly for + * complex objects. + * + * Example: + * ``` + * interface User { + * name: string; + * complexUserData: ComplexType; + * } + * + * const userDecoder: Decoder = object({ + * name: string(), + * complexUserData: anyJson() + * }); + * ``` + */ + Decoder.anyJson = function () { return new Decoder(function (json) { return ok(json); }); }; + /** + * Decoder identity function which always succeeds and types the result as + * `unknown`. + */ + Decoder.unknownJson = function () { + return new Decoder(function (json) { return ok(json); }); + }; + /** + * Decoder for json objects where the keys are unknown strings, but the values + * should all be of the same type. + * + * Example: + * ``` + * dict(number()).run({chocolate: 12, vanilla: 10, mint: 37}); + * // => {ok: true, result: {chocolate: 12, vanilla: 10, mint: 37}} + * ``` + */ + Decoder.dict = function (decoder) { + return new Decoder(function (json) { + if (isJsonObject(json)) { + var obj = {}; + for (var key in json) { + if (json.hasOwnProperty(key)) { + var r = decoder.decode(json[key]); + if (r.ok === true) { + obj[key] = r.result; + } + else { + return err(prependAt("." + key, r.error)); + } + } + } + return ok(obj); + } + else { + return err({ message: expectedGot('an object', json) }); + } + }); + }; + /** + * Decoder for values that may be `undefined`. This is primarily helpful for + * decoding interfaces with optional fields. + * + * Example: + * ``` + * interface User { + * id: number; + * isOwner?: boolean; + * } + * + * const decoder: Decoder = object({ + * id: number(), + * isOwner: optional(boolean()) + * }); + * ``` + */ + Decoder.optional = function (decoder) { + return new Decoder(function (json) { return (json === undefined || json === null ? ok(undefined) : decoder.decode(json)); }); + }; + /** + * Decoder that attempts to run each decoder in `decoders` and either succeeds + * with the first successful decoder, or fails after all decoders have failed. + * + * Note that `oneOf` expects the decoders to all have the same return type, + * while `union` creates a decoder for the union type of all the input + * decoders. + * + * Examples: + * ``` + * oneOf(string(), number().map(String)) + * oneOf(constant('start'), constant('stop'), succeed('unknown')) + * ``` + */ + Decoder.oneOf = function () { + var decoders = []; + for (var _i = 0; _i < arguments.length; _i++) { + decoders[_i] = arguments[_i]; + } + return new Decoder(function (json) { + var errors = []; + for (var i = 0; i < decoders.length; i++) { + var r = decoders[i].decode(json); + if (r.ok === true) { + return r; + } + else { + errors[i] = r.error; + } + } + var errorsList = errors + .map(function (error) { return "at error" + (error.at || '') + ": " + error.message; }) + .join('", "'); + return err({ + message: "expected a value matching one of the decoders, got the errors [\"" + errorsList + "\"]" + }); + }); + }; + /** + * Decoder that always succeeds with either the decoded value, or a fallback + * default value. + */ + Decoder.withDefault = function (defaultValue, decoder) { + return new Decoder(function (json) { + return ok(withDefault(defaultValue, decoder.decode(json))); + }); + }; + /** + * Decoder that pulls a specific field out of a json structure, instead of + * decoding and returning the full structure. The `paths` array describes the + * object keys and array indices to traverse, so that values can be pulled out + * of a nested structure. + * + * Example: + * ``` + * const decoder = valueAt(['a', 'b', 0], string()); + * + * decoder.run({a: {b: ['surprise!']}}) + * // => {ok: true, result: 'surprise!'} + * + * decoder.run({a: {x: 'cats'}}) + * // => {ok: false, error: {... at: 'input.a.b[0]' message: 'path does not exist'}} + * ``` + * + * Note that the `decoder` is ran on the value found at the last key in the + * path, even if the last key is not found. This allows the `optional` + * decoder to succeed when appropriate. + * ``` + * const optionalDecoder = valueAt(['a', 'b', 'c'], optional(string())); + * + * optionalDecoder.run({a: {b: {c: 'surprise!'}}}) + * // => {ok: true, result: 'surprise!'} + * + * optionalDecoder.run({a: {b: 'cats'}}) + * // => {ok: false, error: {... at: 'input.a.b.c' message: 'expected an object, got "cats"'} + * + * optionalDecoder.run({a: {b: {z: 1}}}) + * // => {ok: true, result: undefined} + * ``` + */ + Decoder.valueAt = function (paths, decoder) { + return new Decoder(function (json) { + var jsonAtPath = json; + for (var i = 0; i < paths.length; i++) { + if (jsonAtPath === undefined) { + return err({ + at: printPath(paths.slice(0, i + 1)), + message: 'path does not exist' + }); + } + else if (typeof paths[i] === 'string' && !isJsonObject(jsonAtPath)) { + return err({ + at: printPath(paths.slice(0, i + 1)), + message: expectedGot('an object', jsonAtPath) + }); + } + else if (typeof paths[i] === 'number' && !isJsonArray(jsonAtPath)) { + return err({ + at: printPath(paths.slice(0, i + 1)), + message: expectedGot('an array', jsonAtPath) + }); + } + else { + jsonAtPath = jsonAtPath[paths[i]]; + } + } + return mapError(function (error) { + return jsonAtPath === undefined + ? { at: printPath(paths), message: 'path does not exist' } + : prependAt(printPath(paths), error); + }, decoder.decode(jsonAtPath)); + }); + }; + /** + * Decoder that ignores the input json and always succeeds with `fixedValue`. + */ + Decoder.succeed = function (fixedValue) { + return new Decoder(function (json) { return ok(fixedValue); }); + }; + /** + * Decoder that ignores the input json and always fails with `errorMessage`. + */ + Decoder.fail = function (errorMessage) { + return new Decoder(function (json) { return err({ message: errorMessage }); }); + }; + /** + * Decoder that allows for validating recursive data structures. Unlike with + * functions, decoders assigned to variables can't reference themselves + * before they are fully defined. We can avoid prematurely referencing the + * decoder by wrapping it in a function that won't be called until use, at + * which point the decoder has been defined. + * + * Example: + * ``` + * interface Comment { + * msg: string; + * replies: Comment[]; + * } + * + * const decoder: Decoder = object({ + * msg: string(), + * replies: lazy(() => array(decoder)) + * }); + * ``` + */ + Decoder.lazy = function (mkDecoder) { + return new Decoder(function (json) { return mkDecoder().decode(json); }); + }; + return Decoder; + }()); + + /* tslint:disable:variable-name */ + /** See `Decoder.string` */ + var string = Decoder.string; + /** See `Decoder.number` */ + var number = Decoder.number; + /** See `Decoder.boolean` */ + var boolean = Decoder.boolean; + /** See `Decoder.anyJson` */ + var anyJson = Decoder.anyJson; + /** See `Decoder.unknownJson` */ + Decoder.unknownJson; + /** See `Decoder.constant` */ + var constant = Decoder.constant; + /** See `Decoder.object` */ + var object = Decoder.object; + /** See `Decoder.array` */ + var array = Decoder.array; + /** See `Decoder.tuple` */ + Decoder.tuple; + /** See `Decoder.dict` */ + var dict = Decoder.dict; + /** See `Decoder.optional` */ + var optional = Decoder.optional; + /** See `Decoder.oneOf` */ + var oneOf = Decoder.oneOf; + /** See `Decoder.union` */ + Decoder.union; + /** See `Decoder.intersection` */ + Decoder.intersection; + /** See `Decoder.withDefault` */ + Decoder.withDefault; + /** See `Decoder.valueAt` */ + Decoder.valueAt; + /** See `Decoder.succeed` */ + Decoder.succeed; + /** See `Decoder.fail` */ + Decoder.fail; + /** See `Decoder.lazy` */ + Decoder.lazy; + + const nonEmptyStringDecoder = string().where((s) => s.length > 0, "Expected a non-empty string"); + const nonNegativeNumberDecoder = number().where((num) => num >= 0, "Expected a non-negative number"); + + const intentDefinitionDecoder = object({ + name: nonEmptyStringDecoder, + displayName: optional(string()), + contexts: optional(array(string())), + customConfig: optional(object()) + }); + const v2TypeDecoder = oneOf(constant("web"), constant("native"), constant("citrix"), constant("onlineNative"), constant("other")); + const v2DetailsDecoder = object({ + url: nonEmptyStringDecoder + }); + const v2IconDecoder = object({ + src: nonEmptyStringDecoder, + size: optional(nonEmptyStringDecoder), + type: optional(nonEmptyStringDecoder) + }); + const v2ScreenshotDecoder = object({ + src: nonEmptyStringDecoder, + size: optional(nonEmptyStringDecoder), + type: optional(nonEmptyStringDecoder), + label: optional(nonEmptyStringDecoder) + }); + const v2ListensForIntentDecoder = object({ + contexts: array(nonEmptyStringDecoder), + displayName: optional(nonEmptyStringDecoder), + resultType: optional(nonEmptyStringDecoder), + customConfig: optional(anyJson()) + }); + const v2IntentsDecoder = object({ + listensFor: optional(dict(v2ListensForIntentDecoder)), + raises: optional(dict(array(nonEmptyStringDecoder))) + }); + const v2UserChannelDecoder = object({ + broadcasts: optional(array(nonEmptyStringDecoder)), + listensFor: optional(array(nonEmptyStringDecoder)) + }); + const v2AppChannelDecoder = object({ + name: nonEmptyStringDecoder, + description: optional(nonEmptyStringDecoder), + broadcasts: optional(array(nonEmptyStringDecoder)), + listensFor: optional(array(nonEmptyStringDecoder)) + }); + const v2InteropDecoder = object({ + intents: optional(v2IntentsDecoder), + userChannels: optional(v2UserChannelDecoder), + appChannels: optional(array(v2AppChannelDecoder)) + }); + const glue42ApplicationDetailsDecoder = object({ + url: optional(nonEmptyStringDecoder), + top: optional(number()), + left: optional(number()), + width: optional(nonNegativeNumberDecoder), + height: optional(nonNegativeNumberDecoder) + }); + const glue42HostManifestsBrowserDecoder = object({ + name: optional(nonEmptyStringDecoder), + type: optional(nonEmptyStringDecoder.where((s) => s === "window", "Expected a value of window")), + title: optional(nonEmptyStringDecoder), + version: optional(nonEmptyStringDecoder), + customProperties: optional(anyJson()), + icon: optional(string()), + caption: optional(string()), + details: optional(glue42ApplicationDetailsDecoder), + intents: optional(array(intentDefinitionDecoder)), + hidden: optional(boolean()) + }); + const v1DefinitionDecoder = object({ + name: nonEmptyStringDecoder, + appId: nonEmptyStringDecoder, + title: optional(nonEmptyStringDecoder), + version: optional(nonEmptyStringDecoder), + manifest: nonEmptyStringDecoder, + manifestType: nonEmptyStringDecoder, + tooltip: optional(nonEmptyStringDecoder), + description: optional(nonEmptyStringDecoder), + contactEmail: optional(nonEmptyStringDecoder), + supportEmail: optional(nonEmptyStringDecoder), + publisher: optional(nonEmptyStringDecoder), + images: optional(array(object({ url: optional(nonEmptyStringDecoder) }))), + icons: optional(array(object({ icon: optional(nonEmptyStringDecoder) }))), + customConfig: anyJson(), + intents: optional(array(intentDefinitionDecoder)) + }); + const v2LocalizedDefinitionDecoder = object({ + appId: optional(nonEmptyStringDecoder), + name: optional(nonEmptyStringDecoder), + details: optional(v2DetailsDecoder), + version: optional(nonEmptyStringDecoder), + title: optional(nonEmptyStringDecoder), + tooltip: optional(nonEmptyStringDecoder), + lang: optional(nonEmptyStringDecoder), + description: optional(nonEmptyStringDecoder), + categories: optional(array(nonEmptyStringDecoder)), + icons: optional(array(v2IconDecoder)), + screenshots: optional(array(v2ScreenshotDecoder)), + contactEmail: optional(nonEmptyStringDecoder), + supportEmail: optional(nonEmptyStringDecoder), + moreInfo: optional(nonEmptyStringDecoder), + publisher: optional(nonEmptyStringDecoder), + customConfig: optional(array(anyJson())), + hostManifests: optional(anyJson()), + interop: optional(v2InteropDecoder) + }); + const v2DefinitionDecoder = object({ + appId: nonEmptyStringDecoder, + name: nonEmptyStringDecoder, + type: v2TypeDecoder, + details: v2DetailsDecoder, + version: optional(nonEmptyStringDecoder), + title: optional(nonEmptyStringDecoder), + tooltip: optional(nonEmptyStringDecoder), + lang: optional(nonEmptyStringDecoder), + description: optional(nonEmptyStringDecoder), + categories: optional(array(nonEmptyStringDecoder)), + icons: optional(array(v2IconDecoder)), + screenshots: optional(array(v2ScreenshotDecoder)), + contactEmail: optional(nonEmptyStringDecoder), + supportEmail: optional(nonEmptyStringDecoder), + moreInfo: optional(nonEmptyStringDecoder), + publisher: optional(nonEmptyStringDecoder), + customConfig: optional(array(anyJson())), + hostManifests: optional(anyJson()), + interop: optional(v2InteropDecoder), + localizedVersions: optional(dict(v2LocalizedDefinitionDecoder)) + }); + const allDefinitionsDecoder = oneOf(v1DefinitionDecoder, v2DefinitionDecoder); + + const parseDecoderErrorToStringMessage = (error) => { + return `${error.kind} at ${error.at}: ${JSON.stringify(error.input)}. Reason - ${error.message}`; + }; + + class FDC3Service { + fdc3ToDesktopDefinitionType = { + web: "window", + native: "exe", + citrix: "citrix", + onlineNative: "clickonce", + other: "window" + }; + toApi() { + return { + isFdc3Definition: this.isFdc3Definition.bind(this), + parseToBrowserBaseAppData: this.parseToBrowserBaseAppData.bind(this), + parseToDesktopAppConfig: this.parseToDesktopAppConfig.bind(this) + }; + } + isFdc3Definition(definition) { + const decodeRes = allDefinitionsDecoder.run(definition); + if (!decodeRes.ok) { + return { isFdc3: false, reason: parseDecoderErrorToStringMessage(decodeRes.error) }; + } + if (definition.appId && definition.details) { + return { isFdc3: true, version: "2.0" }; + } + if (definition.manifest) { + return { isFdc3: true, version: "1.2" }; + } + return { isFdc3: false, reason: "The passed definition is not FDC3" }; + } + parseToBrowserBaseAppData(definition) { + const { isFdc3, version } = this.isFdc3Definition(definition); + if (!isFdc3) { + throw new Error("The passed definition is not FDC3"); + } + const decodeRes = allDefinitionsDecoder.run(definition); + if (!decodeRes.ok) { + throw new Error(`Invalid FDC3 ${version} definition. Error: ${parseDecoderErrorToStringMessage(decodeRes.error)}`); + } + const userProperties = this.getUserPropertiesFromDefinition(definition, version); + const createOptions = { url: this.getUrl(definition, version) }; + const baseApplicationData = { + name: definition.appId, + type: "window", + createOptions, + userProperties: { + ...userProperties, + intents: version === "1.2" + ? userProperties.intents + : this.getIntentsFromV2AppDefinition(definition), + details: createOptions + }, + title: definition.title, + version: definition.version, + icon: this.getIconFromDefinition(definition, version), + caption: definition.description, + fdc3: version === "2.0" ? { ...definition, definitionVersion: "2.0" } : undefined, + }; + const ioConnectDefinition = definition.hostManifests?.ioConnect || definition.hostManifests?.["Glue42"]; + if (!ioConnectDefinition) { + return baseApplicationData; + } + const ioDefinitionDecodeRes = glue42HostManifestsBrowserDecoder.run(ioConnectDefinition); + if (!ioDefinitionDecodeRes.ok) { + throw new Error(`Invalid FDC3 ${version} definition. Error: ${parseDecoderErrorToStringMessage(ioDefinitionDecodeRes.error)}`); + } + if (!Object.keys(ioDefinitionDecodeRes.result).length) { + return baseApplicationData; + } + return this.mergeBaseAppDataWithGlueManifest(baseApplicationData, ioDefinitionDecodeRes.result); + } + parseToDesktopAppConfig(definition) { + const { isFdc3, version } = this.isFdc3Definition(definition); + if (!isFdc3) { + throw new Error("The passed definition is not FDC3"); + } + const decodeRes = allDefinitionsDecoder.run(definition); + if (!decodeRes.ok) { + throw new Error(`Invalid FDC3 ${version} definition. Error: ${parseDecoderErrorToStringMessage(decodeRes.error)}`); + } + if (version === "1.2") { + const fdc3v1Definition = definition; + return { + name: fdc3v1Definition.appId, + type: "window", + details: { + url: this.getUrl(definition, version) + }, + version: fdc3v1Definition.version, + title: fdc3v1Definition.title, + tooltip: fdc3v1Definition.tooltip, + caption: fdc3v1Definition.description, + icon: fdc3v1Definition.icons?.[0].icon, + intents: fdc3v1Definition.intents, + customProperties: { + manifestType: fdc3v1Definition.manifestType, + images: fdc3v1Definition.images, + contactEmail: fdc3v1Definition.contactEmail, + supportEmail: fdc3v1Definition.supportEmail, + publisher: fdc3v1Definition.publisher, + icons: fdc3v1Definition.icons, + customConfig: fdc3v1Definition.customConfig + } + }; + } + const fdc3v2Definition = definition; + const desktopDefinition = { + name: fdc3v2Definition.appId, + type: this.fdc3ToDesktopDefinitionType[fdc3v2Definition.type], + details: fdc3v2Definition.details, + version: fdc3v2Definition.version, + title: fdc3v2Definition.title, + tooltip: fdc3v2Definition.tooltip, + caption: fdc3v2Definition.description, + icon: this.getIconFromDefinition(fdc3v2Definition, "2.0"), + intents: this.getIntentsFromV2AppDefinition(fdc3v2Definition), + fdc3: { ...fdc3v2Definition, definitionVersion: "2.0" } + }; + const ioConnectDefinition = definition.hostManifests?.ioConnect || definition.hostManifests?.["Glue42"]; + if (!ioConnectDefinition) { + return desktopDefinition; + } + if (typeof ioConnectDefinition !== "object" || Array.isArray(ioConnectDefinition)) { + throw new Error(`Invalid '${definition.hostManifests.ioConnect ? "hostManifests.ioConnect" : "hostManifests['Glue42']"}' key`); + } + return this.mergeDesktopConfigWithGlueManifest(desktopDefinition, ioConnectDefinition); + } + getUserPropertiesFromDefinition(definition, version) { + if (version === "1.2") { + return Object.fromEntries(Object.entries(definition).filter(([key]) => !connectBrowserAppProps.includes(key))); + } + return Object.fromEntries(Object.entries(definition).filter(([key]) => !connectBrowserAppProps.includes(key) && !fdc3v2AppProps.includes(key))); + } + getUrl(definition, version) { + let url; + if (version === "1.2") { + const parsedManifest = JSON.parse(definition.manifest); + url = parsedManifest.details?.url || parsedManifest.url; + } + else { + url = definition.details?.url; + } + if (!url || typeof url !== "string") { + throw new Error(`Invalid FDC3 ${version} definition. Provide valid 'url' under '${version === "1.2" ? "manifest" : "details"}' key`); + } + return url; + } + getIntentsFromV2AppDefinition(definition) { + const fdc3Intents = definition.interop?.intents?.listensFor; + if (!fdc3Intents) { + return; + } + const intents = Object.entries(fdc3Intents).map((fdc3Intent) => { + const [intentName, intentData] = fdc3Intent; + return { + name: intentName, + ...intentData + }; + }); + return intents; + } + getIconFromDefinition(definition, version) { + if (version === "1.2") { + return definition.icons?.find((iconDef) => iconDef.icon)?.icon || undefined; + } + return definition.icons?.find((iconDef) => iconDef.src)?.src || undefined; + } + mergeBaseAppDataWithGlueManifest(baseAppData, hostManifestDefinition) { + let baseApplicationDefinition = baseAppData; + if (hostManifestDefinition.details) { + const details = { ...baseAppData.createOptions, ...hostManifestDefinition.details }; + baseApplicationDefinition.createOptions = details; + baseApplicationDefinition.userProperties.details = details; + } + if (Array.isArray(hostManifestDefinition.intents)) { + baseApplicationDefinition.userProperties.intents = (baseApplicationDefinition.userProperties.intents || []).concat(hostManifestDefinition.intents); + } + baseApplicationDefinition = { ...baseApplicationDefinition, ...hostManifestDefinition }; + delete baseApplicationDefinition.details; + delete baseApplicationDefinition.intents; + return baseApplicationDefinition; + } + mergeDesktopConfigWithGlueManifest(config, desktopDefinition) { + const appConfig = Object.assign({}, config, desktopDefinition, { details: { ...config.details, ...desktopDefinition.details } }); + if (Array.isArray(desktopDefinition.intents)) { + appConfig.intents = (config.intents || []).concat(desktopDefinition.intents); + } + return appConfig; + } + } + + const decoders$1 = { + common: { + nonEmptyStringDecoder, + nonNegativeNumberDecoder + }, + fdc3: { + allDefinitionsDecoder, + v1DefinitionDecoder, + v2DefinitionDecoder + } + }; + + var INTENTS_ERRORS; + (function (INTENTS_ERRORS) { + INTENTS_ERRORS["USER_CANCELLED"] = "User Closed Intents Resolver UI without choosing a handler"; + INTENTS_ERRORS["CALLER_NOT_DEFINED"] = "Caller Id is not defined"; + INTENTS_ERRORS["TIMEOUT_HIT"] = "Timeout hit"; + INTENTS_ERRORS["INTENT_NOT_FOUND"] = "Cannot find Intent"; + INTENTS_ERRORS["HANDLER_NOT_FOUND"] = "Cannot find Intent Handler"; + INTENTS_ERRORS["TARGET_INSTANCE_UNAVAILABLE"] = "Cannot start Target Instance"; + INTENTS_ERRORS["INTENT_DELIVERY_FAILED"] = "Target Instance did not add a listener"; + INTENTS_ERRORS["RESOLVER_UNAVAILABLE"] = "Intents Resolver UI unavailable"; + INTENTS_ERRORS["RESOLVER_TIMEOUT"] = "User did not choose a handler"; + INTENTS_ERRORS["INVALID_RESOLVER_RESPONSE"] = "Intents Resolver UI returned invalid response"; + INTENTS_ERRORS["INTENT_HANDLER_REJECTION"] = "Intent Handler function processing the raised intent threw an error or rejected the promise it returned"; + })(INTENTS_ERRORS || (INTENTS_ERRORS = {})); + + class IoC { + _fdc3; + _decoders = decoders$1; + _errors = { + intents: INTENTS_ERRORS + }; + get fdc3() { + if (!this._fdc3) { + this._fdc3 = new FDC3Service().toApi(); + } + return this._fdc3; + } + get decoders() { + return this._decoders; + } + get errors() { + return this._errors; + } + } + + const ioc = new IoC(); + ioc.fdc3; + ioc.decoders; + const errors = ioc.errors; + + const GLUE42_FDC3_INTENTS_METHOD_PREFIX = "Tick42.FDC3.Intents."; + const INTENTS_RESOLVER_INTEROP_PREFIX = "T42.Intents.Resolver.Control"; + const INTENTS_RESOLVER_WIDTH = 400; + const INTENTS_RESOLVER_HEIGHT = 440; + const DEFAULT_RESOLVER_RESPONSE_TIMEOUT = 60 * 1000; + const INTENT_HANDLER_DEFAULT_PROPS = ["applicationName", "type"]; + const INTENTS_RESOLVER_APP_NAME = "intentsResolver"; + const MAX_SET_TIMEOUT_DELAY = 2147483647; + const DEFAULT_METHOD_RESPONSE_TIMEOUT_MS = 60 * 1000; + const DEFAULT_RAISE_TIMEOUT_MS = 90 * 1000; + const DEFAULT_PICK_HANDLER_BY_TIMEOUT_MS = 90 * 1000; + const ERRORS = errors.intents; + + const PromisePlus = (executor, timeoutMilliseconds, timeoutMessage) => { + return new Promise((resolve, reject) => { + const timeout = setTimeout(() => { + const message = timeoutMessage || `Promise timeout hit: ${timeoutMilliseconds}`; + reject(message); + }, timeoutMilliseconds); + const providedPromise = new Promise(executor); + providedPromise + .then((result) => { + clearTimeout(timeout); + resolve(result); + }) + .catch((error) => { + clearTimeout(timeout); + reject(error); + }); + }); + }; + const PromiseWrap = (promise, timeoutMilliseconds, timeoutMessage) => { + return new Promise((resolve, reject) => { + let promiseActive = true; + const timeout = setTimeout(() => { + if (!promiseActive) { + return; + } + promiseActive = false; + const message = timeoutMessage || `Promise timeout hit: ${timeoutMilliseconds}`; + reject(message); + }, timeoutMilliseconds); + promise() + .then((result) => { + if (!promiseActive) { + return; + } + promiseActive = false; + clearTimeout(timeout); + resolve(result); + }) + .catch((error) => { + if (!promiseActive) { + return; + } + promiseActive = false; + clearTimeout(timeout); + reject(error); + }); + }); + }; + + const validateIntentHandlerAsResponse = (handler) => { + if (typeof handler !== "object") { + return { isValid: false, error: `Response object has invalid 'handler' key. Expected an object, got ${typeof handler}` }; + } + const compulsoryKeysExist = INTENT_HANDLER_DEFAULT_PROPS.filter((key) => !(key in handler)); + if (compulsoryKeysExist.length) { + return { isValid: false, error: `Handler in Response object does not provide compulsory keys: ${compulsoryKeysExist.join(", ")}` }; + } + return { isValid: true, ok: handler }; + }; + const validateIntentRequestTarget = (target) => { + if (!target) { + return; + } + if (typeof target !== "string" && typeof target !== "object") { + throw new Error(`Please provide the intent target as one of the valid values: "reuse", "startNew", { app: string }, { instance: string } `); + } + }; + const validateIntentRequestContext = (context) => { + if (!context) { + return; + } + if (typeof context !== "object") { + throw new Error(`Please provide the intent context as an object`); + } + if (context.type && typeof context.type !== "string") { + throw new Error(`Please provide the intent context as an object with 'type' property as string`); + } + if (context.data && typeof context.data !== "object") { + throw new Error(`Please provide the intent context as an object with 'data' property as object`); + } + }; + const validateIntentRequestHandler = (handler) => { + if (!handler.applicationName) { + throw new Error(`Please provide applicationName for handler ${JSON.stringify(handler)}`); + } + if (!handler.type) { + throw new Error(`Please provide type for handler ${JSON.stringify(handler)}`); + } + if (handler.type === "instance" && !handler.instanceId) { + throw new Error(`Please provide instanceId for handler ${JSON.stringify(handler)}`); + } + }; + const validateIntentRequestTimeout = (timeout) => { + if (!timeout) { + return; + } + if (typeof timeout !== "number") { + throw new Error(`Please provide the timeout as a number`); + } + if (timeout <= 0) { + throw new Error(`Please provide the timeout as a positive number`); + } + }; + const validateWaitUserResponseIndefinitely = (waitUserResponseIndefinitely) => { + if (!waitUserResponseIndefinitely) { + return; + } + if (typeof waitUserResponseIndefinitely !== "boolean") { + throw new Error("Please provide waitUserResponseIndefinitely as a boolean"); + } + }; + const validateHandlerFilter = (handlerFilter) => { + if (!handlerFilter) { + throw new Error(`Provide 'handlerFilter' with at least one filter criteria of the following: 'intent' | 'contextTypes' | 'resultType' | 'applicationNames'`); + } + const { title, openResolver, timeout, intent, contextTypes, resultType, applicationNames } = handlerFilter; + if (typeof title !== "undefined" && (typeof title !== "string" || !title.length)) { + throw new Error(`Provide 'title' as a non empty string`); + } + if (typeof openResolver !== "undefined" && typeof openResolver !== "boolean") { + throw new Error(`Provide 'openResolver' prop as a boolean`); + } + if (typeof timeout !== "undefined" && (typeof timeout !== "number" || timeout <= 0)) { + throw new Error(`Provide 'timeout' prop as a positive number`); + } + if (typeof intent !== "undefined" && (typeof intent !== "string" || !intent.length)) { + throw new Error(`Provide 'intent' as a non empty string`); + } + if (typeof contextTypes !== "undefined" && (!Array.isArray(contextTypes) || contextTypes.some(ctx => typeof ctx !== "string"))) { + throw new Error(`Provide 'contextTypes' as an array of non empty strings`); + } + if (typeof resultType !== "undefined" && (typeof resultType !== "string" || !resultType.length)) { + throw new Error(`Provide 'resultType' as a non empty string`); + } + if (typeof applicationNames !== "undefined" && (!Array.isArray(applicationNames) || applicationNames.some(appName => typeof appName !== "string"))) { + throw new Error(`Provide 'applicationNames' as an array of non empty strings`); + } + const errorMsg = "Provide at least one filter criteria of the following: 'intent' | 'contextTypes' | 'resultType' | 'applicationNames'"; + if (!Object.keys(handlerFilter).length) { + throw new Error(errorMsg); + } + if (!intent && !resultType && (!contextTypes || !contextTypes.length) && (!applicationNames || !applicationNames.length)) { + throw new Error(errorMsg); + } + }; + const validateResolverResponse = (responseObj) => { + var _a, _b; + if (typeof responseObj.intent !== "string") { + return { isValid: false, error: `Response object has invalid 'intent' key. Expected a string, got ${typeof responseObj.intent}` }; + } + if (((_a = responseObj.userSettings) === null || _a === void 0 ? void 0 : _a.preserveChoice) && typeof ((_b = responseObj.userSettings) === null || _b === void 0 ? void 0 : _b.preserveChoice) !== "boolean") { + return { isValid: false, error: `Response object has invalid 'userSettings.preserveChoice' key. Expected a boolean, got ${typeof responseObj.userSettings.preserveChoice}` }; + } + const { isValid, error } = validateIntentHandlerAsResponse(responseObj.handler); + return isValid + ? { isValid: true, ok: responseObj } + : { isValid, error }; + }; + const validateIntentRequest = (request) => { + validateIntentRequestContext(request.context); + validateIntentRequestTarget(request.target); + validateIntentRequestTimeout(request.timeout); + validateWaitUserResponseIndefinitely(request.waitUserResponseIndefinitely); + if (typeof request.clearSavedHandler !== "undefined" && typeof request.clearSavedHandler !== "boolean") { + throw new Error("Please provide 'clearSavedHandler' as a boolean"); + } + if (request.handlers) { + request.handlers.forEach((handler) => validateIntentRequestHandler(handler)); + } + }; + const validateIntentHandler = (handler) => { + if (typeof handler !== "object") { + throw new Error("IntentHandler must be an object"); + } + if (typeof handler.applicationName !== "string" || !handler.applicationName.length) { + throw new Error(`Please provide 'applicationName' as a non-empty string`); + } + if (typeof handler.type !== "string" || !["app", "instance"].includes(handler.type)) { + throw new Error(`Invalid 'type' property. Expected 'app' | 'instance' got ${handler.type}`); + } + if (typeof handler.applicationTitle !== "undefined" && typeof handler.applicationTitle !== "string") { + throw new Error(`Provide 'applicationTitle' as a string`); + } + if (typeof handler.applicationDescription !== "undefined" && typeof handler.applicationDescription !== "string") { + throw new Error(`Provide 'applicationDescription' as a string`); + } + if (typeof handler.applicationIcon !== "undefined" && typeof handler.applicationIcon !== "string") { + throw new Error(`Provide 'applicationIcon' as a string`); + } + if (typeof handler.displayName !== "undefined" && typeof handler.displayName !== "string") { + throw new Error(`Provide 'displayName' as a string`); + } + if (typeof handler.contextTypes !== "undefined" && (!Array.isArray(handler.contextTypes) || handler.contextTypes.some(ctx => typeof ctx !== "string"))) { + throw new Error(`Provide 'contextTypes' as an array of non empty strings`); + } + if (typeof handler.instanceId !== "undefined" && typeof handler.instanceId !== "string") { + throw new Error(`Provide 'instanceId' as a string`); + } + if (typeof handler.instanceTitle !== "undefined" && typeof handler.instanceTitle !== "string") { + throw new Error(`Provide 'instanceTitle' as a string`); + } + if (typeof handler.resultType !== "undefined" && typeof handler.resultType !== "string") { + throw new Error(`Provide 'resultType' as a string`); + } + }; + const clearNullUndefined = (obj) => { + Object.keys(obj).forEach(key => { + if (obj[key] === null || obj[key] === undefined) { + delete obj[key]; + } + }); + }; + + class Intents { + constructor(interop, windows, logger, options, prefsController, appManager) { + this.interop = interop; + this.windows = windows; + this.logger = logger; + this.prefsController = prefsController; + this.appManager = appManager; + this.myIntents = new Set(); + this.intentsResolverResponsePromises = {}; + this.useIntentsResolverUI = true; + this.unregisterIntentPromises = []; + this.addedHandlerInfoPerApp = {}; + this.checkIfIntentsResolverIsEnabled(options, appManager); + } + async find(intentFilter) { + await Promise.all(this.unregisterIntentPromises); + let intents = await this.all(); + if (typeof intentFilter === "undefined") { + return intents; + } + if (typeof intentFilter === "string") { + return intents.filter((intent) => intent.name === intentFilter); + } + if (typeof intentFilter !== "object") { + throw new Error("Please provide the intentFilter as a string or an object!"); + } + if (intentFilter.contextType) { + const ctToLower = intentFilter.contextType.toLowerCase(); + intents = intents.filter((intent) => intent.handlers.some((handler) => { var _a; return (_a = handler.contextTypes) === null || _a === void 0 ? void 0 : _a.some((ct) => ct.toLowerCase() === ctToLower); })); + } + if (intentFilter.resultType) { + const resultTypeToLower = intentFilter.resultType.toLowerCase(); + intents = intents.filter((intent) => intent.handlers.some((handler) => { var _a; return ((_a = handler.resultType) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === resultTypeToLower; })); + } + if (intentFilter.name) { + intents = intents.filter((intent) => intent.name === intentFilter.name); + } + return intents; + } + async raise(intentRequest) { + if ((typeof intentRequest !== "string" && typeof intentRequest !== "object") || (typeof intentRequest === "object" && typeof intentRequest.intent !== "string")) { + throw new Error("Please provide the intent as a string or an object with an intent property!"); + } + if (typeof intentRequest === "string") { + intentRequest = { intent: intentRequest }; + } + validateIntentRequest(intentRequest); + await Promise.all(this.unregisterIntentPromises); + if (intentRequest.clearSavedHandler) { + this.logger.trace(`User removes saved handler for intent ${intentRequest.intent}`); + await this.removeRememberedHandler(intentRequest.intent); + } + const resolverInstance = {}; + const timeout = intentRequest.waitUserResponseIndefinitely ? MAX_SET_TIMEOUT_DELAY : intentRequest.timeout || DEFAULT_RAISE_TIMEOUT_MS; + const resultFromRememberedHandler = await this.checkHandleRaiseWithRememberedHandler(intentRequest, resolverInstance, timeout); + if (resultFromRememberedHandler) { + return resultFromRememberedHandler; + } + const coreRaiseIntentFn = this.coreRaiseIntent.bind(this, { request: intentRequest, resolverInstance, timeout }); + if (intentRequest.waitUserResponseIndefinitely) { + return coreRaiseIntentFn(); + } + const resultPromise = PromiseWrap(coreRaiseIntentFn, timeout, `${ERRORS.TIMEOUT_HIT} hit for intent request ${JSON.stringify(intentRequest)}`); + resultPromise.catch(() => this.handleRaiseOnError(resolverInstance.instanceId)); + return resultPromise; + } + async all() { + await Promise.all(this.unregisterIntentPromises); + let apps; + try { + const result = await this.interop.invoke("T42.ACS.GetApplications", { withIntentsInfo: true }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + apps = result.returned.applications; + } + catch (e) { + this.logger.error(`Failed to get the applications!`, e); + return []; + } + const intents = {}; + const appsWithIntents = apps.filter((app) => app.intents && app.intents.length > 0); + for (const app of appsWithIntents) { + for (const intentDef of app.intents) { + let intent = intents[intentDef.name]; + if (!intent) { + intent = { + name: intentDef.name, + handlers: [], + }; + intents[intentDef.name] = intent; + } + const handler = { + applicationName: app.name, + applicationTitle: app.title || "", + applicationDescription: app.caption, + displayName: intentDef.displayName, + contextTypes: intentDef.contexts, + applicationIcon: app.icon, + type: "app", + resultType: intentDef.resultType + }; + intent.handlers.push(handler); + } + } + const servers = this.interop.servers(); + const serverWindowIds = servers.map((server) => server.windowId).filter((serverWindowId) => typeof serverWindowId !== "undefined"); + const T42WndGetInfo = "T42.Wnd.GetInfo"; + const isT42WndGetInfoMethodRegistered = this.interop.methods().some((method) => method.name === T42WndGetInfo); + let windowsInfos; + if (isT42WndGetInfoMethodRegistered) { + try { + const result = await this.interop.invoke(T42WndGetInfo, { ids: serverWindowIds }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + windowsInfos = result.returned.windows; + } + catch (e) { + } + } + for (const server of servers) { + await Promise.all(server.getMethods() + .filter((method) => method.name.startsWith(GLUE42_FDC3_INTENTS_METHOD_PREFIX)) + .map(async (method) => { + const intentName = method.name.replace(GLUE42_FDC3_INTENTS_METHOD_PREFIX, ""); + let intent = intents[intentName]; + if (!intent) { + intent = { + name: intentName, + handlers: [], + }; + intents[intentName] = intent; + } + const title = await this.windowsIdToTitle(server.windowId, windowsInfos); + const handler = this.constructIntentHandler({ method, apps, server, intentName, title }); + intent.handlers.push(handler); + })); + } + return Object.values(intents); + } + addIntentListener(intent, handler) { + if ((typeof intent !== "string" && typeof intent !== "object") || (typeof intent === "object" && typeof intent.intent !== "string")) { + throw new Error("Please provide the intent as a string or an object with an intent property!"); + } + if (typeof handler !== "function") { + throw new Error("Please provide the handler as a function!"); + } + const intentName = typeof intent === "string" ? intent : intent.intent; + const methodName = `${GLUE42_FDC3_INTENTS_METHOD_PREFIX}${intentName}`; + let intentFlag = {}; + let registerPromise; + const alreadyRegistered = this.myIntents.has(intentName); + if (alreadyRegistered) { + throw new Error(`Intent listener for intent ${intentName} already registered!`); + } + this.myIntents.add(intentName); + const result = { + unsubscribe: () => { + this.myIntents.delete(intentName); + registerPromise + .then(() => this.interop.unregister(methodName)) + .catch((err) => this.logger.trace(`Unregistration of a method with name ${methodName} failed with reason: ${JSON.stringify(err)}`)); + } + }; + if (typeof intent === "object") { + const { intent: removed, ...rest } = intent; + intentFlag = rest; + } + registerPromise = this.interop.register({ name: methodName, flags: { intent: intentFlag } }, (args) => { + if (this.myIntents.has(intentName)) { + return handler(args); + } + }); + registerPromise.catch((err) => { + this.myIntents.delete(intentName); + this.logger.warn(`Registration of a method with name ${methodName} failed with reason: ${JSON.stringify(err)}`); + }); + return result; + } + async register(intent, handler) { + if ((typeof intent !== "string" && typeof intent !== "object") || (typeof intent === "object" && typeof intent.intent !== "string")) { + throw new Error("Please provide the intent as a string or an object with an intent property!"); + } + if (typeof handler !== "function") { + throw new Error("Please provide the handler as a function!"); + } + await Promise.all(this.unregisterIntentPromises); + const intentName = typeof intent === "string" ? intent : intent.intent; + const methodName = this.buildInteropMethodName(intentName); + let intentFlag = {}; + const alreadyRegistered = this.myIntents.has(intentName); + if (alreadyRegistered) { + throw new Error(`Intent listener for intent ${intentName} already registered!`); + } + this.myIntents.add(intentName); + if (typeof intent === "object") { + const { intent: removed, ...rest } = intent; + intentFlag = rest; + } + try { + await this.interop.register({ name: methodName, flags: { intent: intentFlag } }, (args, caller) => { + if (this.myIntents.has(intentName)) { + return handler(args, caller); + } + }); + } + catch (err) { + this.myIntents.delete(intentName); + throw new Error(`Registration of a method with name ${methodName} failed with reason: ${JSON.stringify(err)}`); + } + return { + unsubscribe: () => this.unsubscribeIntent(intentName) + }; + } + async filterHandlers(handlerFilter) { + var _a, _b; + validateHandlerFilter(handlerFilter); + if (handlerFilter.openResolver && !this.useIntentsResolverUI) { + throw new Error("Cannot resolve 'filterHandlers' request using Intents Resolver UI because it's globally disabled"); + } + (_a = this.logger) === null || _a === void 0 ? void 0 : _a.trace(`Received 'filterHandlers' command with request: ${JSON.stringify(handlerFilter)}`); + const filteredHandlers = this.filterHandlersBy(await this.all(), handlerFilter); + if (!filteredHandlers || !filteredHandlers.length) { + return { handlers: [] }; + } + const { open, reason } = this.checkIfResolverShouldBeOpenedForFilterHandlers(filteredHandlers, handlerFilter); + if (!open) { + (_b = this.logger) === null || _b === void 0 ? void 0 : _b.trace(`Intent Resolver UI won't be used. Reason: ${reason}`); + return { handlers: filteredHandlers }; + } + const resolverInstance = { instanceId: undefined }; + const timeout = handlerFilter.timeout || DEFAULT_PICK_HANDLER_BY_TIMEOUT_MS; + const handler = await PromiseWrap(() => this.startResolverApp({ request: handlerFilter, resolverInstance, method: 'filterHandlers' }), timeout, `Timeout of ${timeout}ms hit for 'filterHandlers' request with filter: ${JSON.stringify(handlerFilter)}`); + return { handlers: [handler] }; + } + async getIntents(handler) { + var _a; + this.logger.trace(`Received 'getIntents' command with handler ${JSON.stringify(handler)}`); + validateIntentHandler(handler); + const intents = await this.all(); + clearNullUndefined(handler); + (_a = this.logger) === null || _a === void 0 ? void 0 : _a.trace(`Extracting valid intents for the passed handler`); + const intentsWithInfo = this.extractIntentsWithInfoByHandler(intents, handler); + this.logger.trace(`Returning intents for handler ${JSON.stringify(handler)}`); + return { intents: intentsWithInfo }; + } + async clearSavedHandlers() { + this.logger.trace("Removing all saved handlers from prefs storage for current app"); + await this.prefsController.update({ intents: undefined }); + } + onHandlerAdded(callback) { + var _a; + const unAppAdded = (_a = this.appManager) === null || _a === void 0 ? void 0 : _a.onAppAdded(async (app) => { + var _a; + const appName = app.name; + const appDef = await app.getConfiguration(); + const isIntentHandler = (_a = appDef === null || appDef === void 0 ? void 0 : appDef.intents) === null || _a === void 0 ? void 0 : _a.length; + if (!isIntentHandler) { + return; + } + appDef.intents.forEach((intent) => { + const handler = this.constructIntentHandlerFromApp(appDef, intent); + if (!this.addedHandlerInfoPerApp[appName]) { + this.addedHandlerInfoPerApp[appName] = []; + } + const appHandlers = this.addedHandlerInfoPerApp[appName]; + appHandlers.push({ handler, name: intent.name }); + callback(handler, intent.name); + }); + }); + const unServerMethodAdded = this.interop.serverMethodAdded(({ method, server }) => { + if (!method.name.startsWith(GLUE42_FDC3_INTENTS_METHOD_PREFIX)) { + return; + } + const intentName = method.name.replace(GLUE42_FDC3_INTENTS_METHOD_PREFIX, ""); + const intentsInfo = this.constructIntentHandler({ method, apps: [], server, intentName, title: "" }); + callback(intentsInfo, intentName); + }); + return () => { + if (typeof unServerMethodAdded === "function") { + unServerMethodAdded(); + } + if (typeof unAppAdded === "function") { + unAppAdded(); + } + }; + } + onHandlerRemoved(callback) { + var _a; + const unAppRemoved = (_a = this.appManager) === null || _a === void 0 ? void 0 : _a.onAppRemoved(async (app) => { + const appName = app.name; + const handlers = this.addedHandlerInfoPerApp[appName]; + const isIntentHandler = handlers === null || handlers === void 0 ? void 0 : handlers.length; + if (!isIntentHandler) { + return; + } + delete this.addedHandlerInfoPerApp[appName]; + handlers.forEach((addedHandlerInfo) => { + callback(addedHandlerInfo.handler, addedHandlerInfo.name); + }); + }); + const unServerMethodAdded = this.interop.serverMethodRemoved(({ method, server }) => { + if (!method.name.startsWith(GLUE42_FDC3_INTENTS_METHOD_PREFIX)) { + return; + } + const intentName = method.name.replace(GLUE42_FDC3_INTENTS_METHOD_PREFIX, ""); + const intentsInfo = this.constructIntentHandler({ method, apps: [], server, intentName, title: "" }); + callback(intentsInfo, intentName); + }); + return () => { + if (typeof unServerMethodAdded === "function") { + unServerMethodAdded(); + } + if (typeof unAppRemoved === "function") { + unAppRemoved(); + } + }; + } + toAPI() { + return { + all: this.all.bind(this), + find: this.find.bind(this), + raise: this.raise.bind(this), + addIntentListener: this.addIntentListener.bind(this), + register: this.register.bind(this), + filterHandlers: this.filterHandlers.bind(this), + getIntents: this.getIntents.bind(this), + clearSavedHandlers: this.clearSavedHandlers.bind(this), + onHandlerAdded: this.onHandlerAdded.bind(this), + onHandlerRemoved: this.onHandlerRemoved.bind(this) + }; + } + filterHandlersBy(intents, filter) { + const filteredIntentsWithHandlers = intents.filter((intent) => { + if (filter.intent && filter.intent !== intent.name) { + return; + } + if (filter.resultType) { + const filteredHandlers = intent.handlers.filter((handler) => handler.resultType && handler.resultType === filter.resultType); + if (!filteredHandlers.length) + return; + intent.handlers = filteredHandlers; + } + if (filter.contextTypes) { + const filteredHandlers = intent.handlers.filter((handler) => { var _a; return (_a = filter.contextTypes) === null || _a === void 0 ? void 0 : _a.every((contextType) => { var _a; return (_a = handler.contextTypes) === null || _a === void 0 ? void 0 : _a.includes(contextType); }); }); + if (!filteredHandlers.length) + return; + intent.handlers = filteredHandlers; + } + if (filter.applicationNames) { + const filteredHandlers = intent.handlers.filter((handler) => { var _a; return (_a = filter.applicationNames) === null || _a === void 0 ? void 0 : _a.includes(handler.applicationName); }); + if (!filteredHandlers.length) + return; + intent.handlers = filteredHandlers; + } + return intent; + }); + return filteredIntentsWithHandlers.map((intent) => intent.handlers).flat(1); + } + async coreRaiseIntent({ request, resolverInstance, timeout }) { + var _a, _b; + const intentDef = await this.get(request.intent); + if (typeof intentDef === "undefined") { + throw new Error(`${ERRORS.INTENT_NOT_FOUND} with name ${request.intent}`); + } + const { open, reason } = await this.checkIfResolverShouldBeOpenedForRaise(intentDef, request); + if (!open) { + this.logger.trace(`Intent Resolver UI won't be used. Reason: ${reason}`); + return request.waitUserResponseIndefinitely + ? PromiseWrap(() => this.raiseIntent(request, timeout), timeout, `${ERRORS.TIMEOUT_HIT} - waited ${timeout}ms for 'raise' to resolve`) + : this.raiseIntent(request, timeout); + } + const resolverHandler = await this.startResolverApp({ request, method: "raise", resolverInstance }); + (_a = this.logger) === null || _a === void 0 ? void 0 : _a.trace(`Raising intent to target handler: ${JSON.stringify(resolverHandler)} with timeout of ${timeout}`); + if (request.waitUserResponseIndefinitely) { + return PromiseWrap(() => this.raiseIntentToTargetHandler(request, resolverHandler, timeout), timeout, `${ERRORS.TIMEOUT_HIT} - waited ${timeout}ms for 'raise' to resolve`); + } + const result = await this.raiseIntentToTargetHandler(request, resolverHandler, timeout); + (_b = this.logger) === null || _b === void 0 ? void 0 : _b.trace(`Result from raise() method for intent ${JSON.stringify(request.intent)}: ${JSON.stringify(result)}`); + return result; + } + async get(intent) { + return (await this.all()).find((registeredIntent) => registeredIntent.name === intent); + } + async raiseIntent(intentRequest, timeout) { + const intentName = intentRequest.intent; + const intentDef = await this.get(intentName); + if (typeof intentDef === "undefined") { + throw new Error(`${ERRORS.INTENT_NOT_FOUND} with name ${intentRequest.intent}`); + } + const firstFoundAppHandler = intentRequest.handlers ? this.findHandlerByFilter(intentRequest.handlers, { type: "app" }) : this.findHandlerByFilter(intentDef.handlers, { type: "app" }); + const firstFoundInstanceHandler = intentRequest.handlers ? this.findHandlerByFilter(intentRequest.handlers, { type: "instance" }) : this.findHandlerByFilter(intentDef.handlers, { type: "instance" }); + let handler; + if (!intentRequest.target || intentRequest.target === "reuse") { + handler = firstFoundInstanceHandler || firstFoundAppHandler; + } + if (intentRequest.target === "startNew") { + handler = firstFoundAppHandler; + } + if (typeof intentRequest.target === "object" && intentRequest.target.app) { + handler = this.findHandlerByFilter(intentDef.handlers, { app: intentRequest.target.app }); + } + if (typeof intentRequest.target === "object" && intentRequest.target.instance) { + handler = this.findHandlerByFilter(intentDef.handlers, { instance: intentRequest.target.instance, app: intentRequest.target.app }); + } + if (!handler) { + throw new Error(`Can not raise intent for request ${JSON.stringify(intentRequest)} - can not find intent handler!`); + } + const result = await this.raiseIntentToTargetHandler(intentRequest, handler, timeout); + return result; + } + async raiseIntentToTargetHandler(intentRequest, handler, timeout) { + var _a, _b; + (_a = this.logger) === null || _a === void 0 ? void 0 : _a.trace(`Raising intent to target handler:${JSON.stringify(handler)}`); + if (!handler.instanceId) { + const instanceIdPromise = this.invokeStartApp(handler.applicationName, intentRequest.context, intentRequest.options).catch((err) => { + const reasonMsg = typeof err === "string" ? err : JSON.stringify(err); + throw new Error(`${ERRORS.TARGET_INSTANCE_UNAVAILABLE}. Reason: ${reasonMsg}`); + }); + handler.instanceId = await instanceIdPromise; + } + const methodName = `${GLUE42_FDC3_INTENTS_METHOD_PREFIX}${intentRequest.intent}`; + const invokeOptions = { + methodResponseTimeoutMs: timeout ? timeout + 1000 : DEFAULT_METHOD_RESPONSE_TIMEOUT_MS, + waitTimeoutMs: timeout ? timeout + 1000 : DEFAULT_METHOD_RESPONSE_TIMEOUT_MS + }; + const resultPromise = this.interop.invoke(methodName, intentRequest.context, { instance: handler.instanceId }, invokeOptions) + .catch((err) => { + const reasonMsg = typeof err === "string" ? err : JSON.stringify(err); + throw new Error(`${ERRORS.INTENT_HANDLER_REJECTION}. Reason: ${reasonMsg}`); + }); + const result = await resultPromise; + (_b = this.logger) === null || _b === void 0 ? void 0 : _b.trace(`raiseIntent command completed. Returning result: ${JSON.stringify(result)}`); + return { + request: intentRequest, + handler: { ...handler, type: "instance" }, + result: result.returned + }; + } + async startResolverApp({ request, method, resolverInstance }) { + var _a, _b, _c, _d; + (_a = this.logger) === null || _a === void 0 ? void 0 : _a.trace(`Intents Resolver UI with app name ${this.intentsResolverAppName} will be used for request: ${JSON.stringify(request)}`); + const responseMethodName = await this.registerIntentResolverMethod(); + (_b = this.logger) === null || _b === void 0 ? void 0 : _b.trace(`Registered interop method ${responseMethodName}`); + const startContext = this.buildStartContext(method, request, responseMethodName); + const startOptions = await this.buildStartOptions(); + (_c = this.logger) === null || _c === void 0 ? void 0 : _c.trace(`Starting Intents Resolver UI with context: ${JSON.stringify(startContext)} and options: ${JSON.stringify(startOptions)}`); + const instance = await this.appManager.application(this.intentsResolverAppName).start(startContext, startOptions); + resolverInstance.instanceId = instance.id; + (_d = this.logger) === null || _d === void 0 ? void 0 : _d.trace(`Intents Resolver instance with id ${instance.id} opened`); + this.subscribeOnInstanceStopped(instance, method); + const timeout = request.timeout || method === "raise" ? DEFAULT_RAISE_TIMEOUT_MS : DEFAULT_PICK_HANDLER_BY_TIMEOUT_MS; + this.createResponsePromise({ + intent: method === "raise" ? request.intent : undefined, + instanceId: instance.id, + responseMethodName, + timeout, + errorMsg: `Timeout of ${timeout}ms hit waiting for the user to choose a handler ${method === "raise" + ? `for intent ${request.intent}` + : `for '${method}' method with filter ${JSON.stringify(request)}`}` + }); + const handler = await this.handleInstanceResponse({ instanceId: instance.id, caller: startContext.initialCaller, method, request }); + return handler; + } + async windowsIdToTitle(id, windowsInfos) { + var _a, _b; + if (typeof windowsInfos !== "undefined") { + return (_a = windowsInfos.find((windowsInfo) => windowsInfo.id === id)) === null || _a === void 0 ? void 0 : _a.title; + } + const window = (_b = this.windows) === null || _b === void 0 ? void 0 : _b.findById(id); + const title = await (window === null || window === void 0 ? void 0 : window.getTitle()); + return title; + } + async handleInstanceResponse({ instanceId, method, request, caller }) { + var _a, _b, _c; + try { + const response = await this.intentsResolverResponsePromises[instanceId].promise; + const subMessage = method === "raise" ? `for intent ${response.intent} ` : ""; + (_a = this.logger) === null || _a === void 0 ? void 0 : _a.trace(`Intent handler chosen ${subMessage}: ${JSON.stringify(response.handler)}. Stopping resolver instance with id ${instanceId}`); + this.stopResolverInstance(instanceId); + (_b = this.logger) === null || _b === void 0 ? void 0 : _b.trace(`Instance with id ${instanceId} successfully stopped`); + if ((_c = response.userSettings) === null || _c === void 0 ? void 0 : _c.preserveChoice) { + await this.saveUserChoice({ + intent: response.intent, + handler: response.handler, + filter: method === "filterHandlers" + ? { applicationNames: request.applicationNames, contextTypes: request.contextTypes, resultType: request.resultType } + : undefined, + caller + }); + } + return response.handler; + } + catch (error) { + this.stopResolverInstance(instanceId); + throw new Error(error); + } + } + async registerIntentResolverMethod() { + const methodName = INTENTS_RESOLVER_INTEROP_PREFIX + Utils.generateId(); + await this.interop.register(methodName, (args, callerId) => this.resolverResponseHandler(args, callerId)); + return methodName; + } + resolverResponseHandler(args, callerId) { + const { instance } = callerId; + const isValid = validateResolverResponse(args); + if (!isValid) { + this.logger.trace(`Intent Resolver instance with id ${callerId.instance} sent invalid response. Error: ${isValid.error}`); + this.intentsResolverResponsePromises[instance].reject(isValid.error); + this.stopResolverInstance(instance); + return; + } + const validResponse = isValid.ok; + this.intentsResolverResponsePromises[instance].resolve(validResponse); + this.cleanUpIntentResolverPromise(instance); + } + buildStartContext(method, request, methodName) { + var _a; + const myAppName = this.interop.instance.application || this.interop.instance.applicationName; + const myAppTitle = ((_a = this.appManager.application(myAppName)) === null || _a === void 0 ? void 0 : _a.title) || ""; + const baseStartContext = { + callerId: this.interop.instance.instance, + methodName, + initialCaller: { id: this.interop.instance.instance, applicationName: myAppName, applicationTitle: myAppTitle }, + resolverApi: "1.0" + }; + return method === "raise" + ? { ...baseStartContext, intent: request } + : { ...baseStartContext, handlerFilter: request }; + } + async buildStartOptions() { + const win = this.windows.my(); + if (!win) { + return; + } + const bounds = await win.getBounds(); + return { + top: await this.getResolverStartupTopBound(bounds), + left: (bounds.width - INTENTS_RESOLVER_WIDTH) / 2 + bounds.left, + width: INTENTS_RESOLVER_WIDTH, + height: INTENTS_RESOLVER_HEIGHT + }; + } + async getResolverStartupTopBound(bounds) { + const myDisplay = await this.windows.my().getDisplay(); + const minWorkareaHeight = myDisplay.workArea.height; + const top = (bounds.height - INTENTS_RESOLVER_HEIGHT) / 2 + bounds.top; + if (top < 0) { + return 0; + } + if (top + INTENTS_RESOLVER_HEIGHT > minWorkareaHeight) { + return minWorkareaHeight / 2; + } + return top; + } + createResponsePromise({ instanceId, intent, responseMethodName, timeout, errorMsg }) { + let resolve = () => { }; + let reject = () => { }; + const promise = PromisePlus((res, rej) => { + resolve = res; + reject = rej; + }, timeout, errorMsg); + this.intentsResolverResponsePromises[instanceId] = { intent, resolve, reject, promise, methodName: responseMethodName }; + } + async invokeStartApp(application, context, options) { + const result = await this.interop.invoke("T42.ACS.StartApplication", { Name: application, options: { ...options, startedByIntentAPI: true } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return result.returned.Id; + } + subscribeOnInstanceStopped(instance, method) { + const { application } = instance; + const unsub = application.onInstanceStopped((inst) => { + if (inst.id !== instance.id) { + return; + } + const intentPromise = this.intentsResolverResponsePromises[inst.id]; + if (!intentPromise) { + return unsub(); + } + const errorMsg = `Cannot resolve ${method === "raise" ? `raised intent ${intentPromise.intent}` : `'${method}' method`} - User closed ${instance.application.name} app without choosing a handler`; + intentPromise.reject(errorMsg); + this.cleanUpIntentResolverPromise(inst.id); + unsub(); + }); + } + async cleanUpIntentResolverPromise(instanceId) { + const intentPromise = this.intentsResolverResponsePromises[instanceId]; + if (!intentPromise) { + return; + } + const unregisterPromise = this.interop.unregister(intentPromise.methodName); + unregisterPromise.catch((error) => this.logger.warn(error)); + delete this.intentsResolverResponsePromises[instanceId]; + } + handleRaiseOnError(instanceId) { + if (!instanceId) { + return; + } + this.stopResolverInstance(instanceId); + } + stopResolverInstance(instanceId) { + const gdWin = this.windows.findById(instanceId); + gdWin === null || gdWin === void 0 ? void 0 : gdWin.close().catch((err) => this.logger.error(err)); + } + checkIfIntentsResolverIsEnabled(options, appManager) { + var _a, _b, _c, _d, _e; + if (!appManager) { + this.useIntentsResolverUI = false; + return; + } + this.useIntentsResolverUI = typeof ((_a = options.intents) === null || _a === void 0 ? void 0 : _a.enableIntentsResolverUI) === "boolean" + ? options.intents.enableIntentsResolverUI + : true; + this.intentsResolverAppName = (_c = (_b = options.intents) === null || _b === void 0 ? void 0 : _b.intentsResolverAppName) !== null && _c !== void 0 ? _c : INTENTS_RESOLVER_APP_NAME; + this.intentsResolverResponseTimeout = (_e = (_d = options.intents) === null || _d === void 0 ? void 0 : _d.methodResponseTimeoutMs) !== null && _e !== void 0 ? _e : DEFAULT_RESOLVER_RESPONSE_TIMEOUT; + } + async checkIfResolverShouldBeOpenedForRaise(intent, request) { + const checkOpen = this.checkIfIntentsResolverShouldBeOpened(); + if (!checkOpen.open) { + return checkOpen; + } + const hasMoreThanOneHandler = await this.checkIfIntentHasMoreThanOneHandler(intent, request); + if (!hasMoreThanOneHandler) { + return { open: false, reason: `Raised intent ${intent.name} has only one handler` }; + } + return { open: true }; + } + checkIfResolverShouldBeOpenedForFilterHandlers(handlers, filter) { + if (handlers.length === 1) { + return { open: false, reason: `There's only one valid intent handler for filter ${JSON.stringify(filter)}` }; + } + if (typeof (filter === null || filter === void 0 ? void 0 : filter.openResolver) === "boolean" && !filter.openResolver) { + return { open: false, reason: "Intents resolver is disabled by IntentHandler filter" }; + } + return this.checkIfIntentsResolverShouldBeOpened(); + } + checkIfIntentsResolverShouldBeOpened() { + if (!this.useIntentsResolverUI) { + return { open: false, reason: `Intent Resolver is disabled. Resolving to first found handler` }; + } + const intentsResolverApp = this.appManager.application(this.intentsResolverAppName); + if (!intentsResolverApp) { + return { open: false, reason: `Intent Resolver Application with name ${this.intentsResolverAppName} not found.` }; + } + return { open: true }; + } + async checkIfIntentHasMoreThanOneHandler(intent, request) { + const handlers = await this.removeSingletons(request.handlers || intent.handlers); + if (!request.target) { + return handlers.length > 1; + } + if (request.target === "reuse") { + return handlers.filter(handler => handler.type === "instance" && handler.instanceId).length > 1 || intent.handlers.filter(handler => handler.type === "app").length > 1; + } + if (request.target === "startNew") { + return handlers.filter(handler => handler.type === "app").length > 1; + } + if (request.target.instance) { + return false; + } + if (request.target.app) { + const searchedAppName = request.target.app; + const instanceHandlersByAppName = handlers.filter((handler) => handler.applicationName === searchedAppName && handler.instanceId); + return instanceHandlersByAppName.length > 1; + } + return false; + } + async removeSingletons(handlers) { + const handlersWithSingletonProp = await Promise.all(handlers.map(async (handler) => { + if (handler.type === "instance") { + return handler; + } + const appConfig = await this.appManager.application(handler.applicationName).getConfiguration(); + const isSingleton = appConfig.allowMultiple === false; + return { ...handler, isSingleton }; + })); + const filteredSingletonsWithOpenedInstances = handlersWithSingletonProp.filter((handler, _, currentHandlers) => { + if (handler.instanceId || !handler.isSingleton) { + return handler; + } + const openedInstance = currentHandlers.find((h) => h.instanceId && h.applicationName === handler.applicationName); + if (openedInstance) { + return; + } + return handler; + }); + return filteredSingletonsWithOpenedInstances; + } + buildInteropMethodName(intentName) { + return `${GLUE42_FDC3_INTENTS_METHOD_PREFIX}${intentName}`; + } + clearUnregistrationPromise(promiseToRemove) { + this.unregisterIntentPromises = this.unregisterIntentPromises.filter((promise) => promise !== promiseToRemove); + } + unsubscribeIntent(intentName) { + this.myIntents.delete(intentName); + const methodName = this.buildInteropMethodName(intentName); + const unregisterPromise = this.interop.unregister(methodName); + this.unregisterIntentPromises.push(unregisterPromise); + unregisterPromise + .then(() => { + this.clearUnregistrationPromise(unregisterPromise); + }) + .catch((err) => { + this.logger.error(`Unregistration of a method with name ${methodName} failed with reason: `, err); + this.clearUnregistrationPromise(unregisterPromise); + }); + } + findHandlerByFilter(handlers, filter) { + if (filter.type) { + return handlers.find((handler) => handler.type === filter.type); + } + if (filter.instance) { + return handlers.find((handler) => filter.app + ? handler.applicationName === filter.app && handler.instanceId === filter.instance + : handler.instanceId === filter.instance); + } + if (filter.app) { + return handlers.find((handler) => handler.applicationName === filter.app); + } + } + extractIntentsWithInfoByHandler(intents, handler) { + const intentsWithInfo = intents.reduce((validIntentsWithInfo, intent) => { + intent.handlers.forEach((currentHandler) => { + const isValid = Object.keys(handler).every((key) => { + var _a; + return key === "contextTypes" + ? (_a = handler.contextTypes) === null || _a === void 0 ? void 0 : _a.every((contextType) => { var _a; return (_a = currentHandler.contextTypes) === null || _a === void 0 ? void 0 : _a.includes(contextType); }) + : currentHandler[key] === handler[key]; + }); + if (!isValid) { + return; + } + const intentWithInfo = { + intent: intent.name, + contextTypes: currentHandler.contextTypes, + description: currentHandler.applicationDescription, + displayName: currentHandler.displayName, + icon: currentHandler.applicationIcon, + resultType: currentHandler.resultType + }; + validIntentsWithInfo.push(intentWithInfo); + }); + return validIntentsWithInfo; + }, []); + return intentsWithInfo; + } + async removeRememberedHandler(intentName) { + var _a; + this.logger.trace(`Removing saved handler from prefs storage for intent ${intentName}`); + let prefs; + try { + prefs = await this.prefsController.get(); + } + catch (error) { + this.logger.warn(`prefs.get() threw the following error: ${typeof error === "string" ? error : JSON.stringify(error)}`); + return; + } + const intentPrefs = (_a = prefs.data) === null || _a === void 0 ? void 0 : _a.intents; + if (!intentPrefs) { + this.logger.trace("No app prefs found for current app"); + return; + } + delete intentPrefs[intentName]; + const updatedPrefs = { + ...prefs.data, + intents: intentPrefs + }; + try { + await this.prefsController.update(updatedPrefs); + } + catch (error) { + this.logger.warn(`prefs.update() threw the following error: ${typeof error === "string" ? error : JSON.stringify(error)}`); + return; + } + this.logger.trace(`Handler saved choice for intent ${intentName} removed successfully`); + } + async checkForRememberedHandler(intentRequest) { + var _a, _b; + let prefs; + try { + prefs = await this.prefsController.get(); + } + catch (error) { + this.logger.warn(`prefs.get() threw the following error: ${typeof error === "string" ? error : JSON.stringify(error)}`); + return; + } + const prefsForIntent = (_b = (_a = prefs.data) === null || _a === void 0 ? void 0 : _a.intents) === null || _b === void 0 ? void 0 : _b[intentRequest.intent]; + return prefsForIntent === null || prefsForIntent === void 0 ? void 0 : prefsForIntent.handler; + } + async checkHandleRaiseWithRememberedHandler(intentRequest, resolverInstance, timeout) { + if (intentRequest.target) { + return; + } + const rememberedHandler = await this.checkForRememberedHandler(intentRequest); + if (!rememberedHandler) { + return; + } + const request = { + ...intentRequest, + target: { + app: rememberedHandler.applicationName, + instance: rememberedHandler.instanceId + } + }; + try { + const response = await this.coreRaiseIntent({ request, resolverInstance, timeout }); + return response; + } + catch (error) { + this.logger.trace("Could not raise intent to remembered handler. Removing it from Prefs store"); + await this.removeRememberedHandler(intentRequest.intent); + } + } + async saveUserChoice({ intent, handler, filter, caller }) { + var _a, _b; + const prevPrefs = await this.prefsController.get(caller.applicationName); + const prevIntentsPrefs = ((_a = prevPrefs === null || prevPrefs === void 0 ? void 0 : prevPrefs.data) === null || _a === void 0 ? void 0 : _a.intents) || {}; + const prefsToUpdate = { + ...prevPrefs.data, + intents: { + ...prevIntentsPrefs, + [intent]: { handler, filter } + } + }; + await this.prefsController.update(prefsToUpdate, { app: caller.applicationName }); + (_b = this.logger) === null || _b === void 0 ? void 0 : _b.info(`Saved user's choice of handler for '${caller.applicationName}' app`); + } + constructIntentHandler({ apps, intentName, method, server, title }) { + const info = method.flags.intent; + const app = apps.find((appWithIntents) => appWithIntents.name === server.application); + let appIntent; + if (app === null || app === void 0 ? void 0 : app.intents) { + appIntent = app.intents.find((appDefIntent) => appDefIntent.name === intentName); + } + const handler = { + instanceId: server.instance, + applicationName: server.application, + applicationIcon: info.icon || (app === null || app === void 0 ? void 0 : app.icon), + applicationTitle: (app === null || app === void 0 ? void 0 : app.title) || "", + applicationDescription: info.description || (app === null || app === void 0 ? void 0 : app.caption), + displayName: info.displayName || (appIntent === null || appIntent === void 0 ? void 0 : appIntent.displayName), + contextTypes: info.contextTypes || (appIntent === null || appIntent === void 0 ? void 0 : appIntent.contexts), + instanceTitle: title, + type: "instance", + resultType: (appIntent === null || appIntent === void 0 ? void 0 : appIntent.resultType) || info.resultType + }; + return handler; + } + constructIntentHandlerFromApp(app, intent) { + return { + applicationName: app.name, + applicationTitle: app.title || "", + applicationDescription: app.caption, + displayName: intent.displayName, + contextTypes: intent.contexts, + applicationIcon: app.icon, + type: "app", + resultType: intent.resultType + }; + } + } + + class FactoryCallInfo { + constructor() { + this.initialized = false; + this.details = []; + this.reject = () => { }; + this.resolve = () => { }; + } + init(config) { + this.initialized = true; + this.addCall(config); + this.promise = new Promise((resolve, reject) => { + this.resolve = resolve; + this.reject = reject; + }); + } + addCall(config) { + this.details.push({ date: new Date(), config }); + } + done(g) { + this.resolve(g); + } + error(e) { + this.reject(e); + } + } + + class Prefs { + constructor(appName, interop) { + this.appName = appName; + this.interop = interop; + this.registry = CallbackRegistryFactory(); + this.interopMethodRegistered = false; + } + async get(app) { + const data = (await this.interop.invoke(Prefs.T42GetPrefsMethodName, { app: app !== null && app !== void 0 ? app : this.appName }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + })); + return data.returned; + } + async set(data, options) { + var _a; + this.verifyDataObject(data); + await this.interop.invoke(Prefs.T42SetPrefsMethodName, { app: (_a = options === null || options === void 0 ? void 0 : options.app) !== null && _a !== void 0 ? _a : this.appName, data, merge: false }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async setFor(app, data) { + this.verifyApp(app); + this.verifyDataObject(data); + return this.set(data, { app }); + } + async update(data, options) { + var _a; + this.verifyDataObject(data); + await this.interop.invoke(Prefs.T42SetPrefsMethodName, { app: (_a = options === null || options === void 0 ? void 0 : options.app) !== null && _a !== void 0 ? _a : this.appName, data, merge: true }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async updateFor(app, data) { + this.verifyApp(app); + this.verifyDataObject(data); + return this.update(data, { app }); + } + async clear(app) { + await this.interop.invoke(Prefs.T42SetPrefsMethodName, { app: app !== null && app !== void 0 ? app : this.appName, clear: true }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async clearFor(app) { + this.verifyApp(app); + await this.interop.invoke(Prefs.T42SetPrefsMethodName, { app, clear: true }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async getAll() { + const data = (await this.interop.invoke(Prefs.T42GetPrefsMethodName, undefined, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + })); + return data.returned; + } + async clearAll() { + await this.interop.invoke(Prefs.T42SetPrefsMethodName, { clear: true }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + subscribe(callback) { + this.verifyCallback(callback); + return this.subscribeFor(this.appName, callback); + } + subscribeFor(app, callback) { + this.verifyApp(app); + this.verifyCallback(callback); + const unsubscribeFn = this.registry.add(app, callback); + this.registerInteropIfNeeded() + .then(() => { + this.interop.invoke(Prefs.T42GetPrefsMethodName, { app, subscribe: true }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + }); + return () => { + unsubscribeFn(); + }; + } + async registerInteropIfNeeded() { + if (this.interopMethodRegistered) { + return; + } + this.interopMethodRegistered = true; + await this.interop.register(Prefs.T42UpdatePrefsMethodName, (args) => { + this.registry.execute(args.app, args); + }); + } + verifyApp(app) { + if (!app) { + throw new Error(`app should be defined`); + } + if (!isString(app)) { + throw new Error(`app should be a string`); + } + } + verifyDataObject(data) { + if (!data) { + throw new Error(`data should be defined`); + } + if (!isObject(data)) { + throw new Error(`data should be an object`); + } + } + verifyCallback(callback) { + if (!isFunction(callback)) { + throw new Error(`callback should be defined`); + } + } + } + Prefs.T42UpdatePrefsMethodName = "T42.Prefs.Update"; + Prefs.T42GetPrefsMethodName = "T42.Prefs.Get"; + Prefs.T42SetPrefsMethodName = "T42.Prefs.Set"; + + class Cookies { + constructor(methodName, interop) { + this.methodName = methodName; + this.interop = interop; + } + async get(filter) { + const result = await this.invoke("get-cookies", { filter }); + return result.returned.cookies; + } + async set(cookie) { + this.verifyCookieObject(cookie); + await this.invoke("set-cookie", cookie); + } + async remove(url, name) { + if (!isString(url)) { + throw new Error(`url should be a string`); + } + if (!isString(name)) { + throw new Error(`name should be a string`); + } + await this.invoke("remove-cookie", { url, name }); + } + invoke(command, data) { + return this.interop.invoke(this.methodName, { command, args: data }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_RESPONSE_TIMEOUT_MS, + }); + } + verifyCookieObject(cookie) { + if (!cookie) { + throw new Error(`cookie should be defined`); + } + if (!isObject(cookie)) { + throw new Error(`cookie should be an object`); + } + if (Utils.isNullOrUndefined(cookie.url) || !isString(cookie.url)) { + throw new Error(`cookie.url should be a string`); + } + if (Utils.isNullOrUndefined(cookie.name) || !isString(cookie.name)) { + throw new Error(`cookie.name should be a string`); + } + if (!Utils.isNullOrUndefined(cookie.value) && !isString(cookie.value)) { + throw new Error(`cookie.value should be a string`); + } + if (!Utils.isNullOrUndefined(cookie.domain) && !isString(cookie.domain)) { + throw new Error(`cookie.domain should be a string`); + } + if (!Utils.isNullOrUndefined(cookie.path) && !isString(cookie.path)) { + throw new Error(`cookie.path should be a string`); + } + if (!Utils.isNullOrUndefined(cookie.secure) && typeof cookie.secure !== "boolean") { + throw new Error(`cookie.secure should be a boolean`); + } + if (!Utils.isNullOrUndefined(cookie.httpOnly) && typeof cookie.httpOnly !== "boolean") { + throw new Error(`cookie.httpOnly should be a boolean`); + } + if (!Utils.isNullOrUndefined(cookie.expirationDate) && typeof cookie.expirationDate !== "number") { + throw new Error(`cookie.expirationDate should be a number`); + } + } + } + + function factory$1(agm, methodName) { + const cookies = new Cookies(methodName, agm); + return { + get: cookies.get.bind(cookies), + remove: cookies.remove.bind(cookies), + set: cookies.set.bind(cookies), + ready: () => Promise.resolve() + }; + } + + class EventsDispatcher { + constructor(config) { + this.config = config; + this.glue42EventName = "Glue42"; + this.events = { + notifyStarted: { name: "notifyStarted", handle: this.handleNotifyStarted.bind(this) }, + requestGlue: { name: "requestGlue", handle: this.handleRequestGlue.bind(this) } + }; + } + start(glue) { + if (Utils.isNode()) { + return; + } + this.glue = glue; + this.wireCustomEventListener(); + this.announceStarted(); + } + wireCustomEventListener() { + window.addEventListener(this.glue42EventName, (event) => { + const data = event.detail; + if (!data || !data.glue42) { + return; + } + const glue42Event = data.glue42.event; + const foundHandler = this.events[glue42Event]; + if (!foundHandler) { + return; + } + foundHandler.handle(data.glue42.message); + }); + } + announceStarted() { + this.send("start"); + } + handleRequestGlue() { + if (!this.config.exposeAPI) { + this.send("requestGlueResponse", { error: "Will not give access to the underlying Glue API, because it was explicitly denied upon initialization." }); + return; + } + this.send("requestGlueResponse", { glue: this.glue }); + } + handleNotifyStarted() { + this.announceStarted(); + } + send(eventName, message) { + const payload = { glue42: { event: eventName, message } }; + const event = new CustomEvent(this.glue42EventName, { detail: payload }); + window.dispatchEvent(event); + } + } + + class PromiseWrapper { + static delay(time) { + return new Promise((resolve) => setTimeout(resolve, time)); + } + static async delayForever() { + const biggestPossibleDelay = 2147483647; + while (true) { + await this.delay(biggestPossibleDelay); + } + } + get ended() { + return this.rejected || this.resolved; + } + constructor() { + this.promise = new Promise((resolve, reject) => { + this.resolve = (t) => { + this.resolved = true; + resolve(t); + }; + this.reject = (err) => { + this.rejected = true; + reject(err); + }; + }); + } + } + + class Interception { + constructor() { + this.InterceptorMethodName = "T42.GD.Interception.Execute"; + this.InterceptorHandlerMethodName = "T42.GD.Interception.Handler"; + this.interceptions = []; + } + init(interop) { + this.interop = interop; + } + async register(request) { + if (!request || typeof request !== "object" || Array.isArray(request)) { + throw new Error(`Please provide a valid object.`); + } + const handler = request.handler; + if (typeof handler !== "function") { + throw new Error("Please provide a valid handler function."); + } + const interceptions = request.interceptions; + this.validateInterceptions(interceptions); + this.interceptions.push(request); + try { + await this.interop.invoke(this.InterceptorMethodName, { + command: "register", + interceptions + }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + await this.registerMethodIfNotRegistered(); + } + catch (error) { + this.interceptions = this.interceptions.filter((i) => i !== request); + const message = error.message || "Unknown error"; + const newError = new Error(`Failed to register interception: ${message}`); + throw newError; + } + } + async unregister(request) { + if (!request || typeof request !== "object" || Array.isArray(request)) { + throw new Error(`Please provide a valid object.`); + } + const interceptions = request.interceptions; + this.validateInterceptions(interceptions); + try { + await this.interop.invoke(this.InterceptorMethodName, { + command: "unregister", + interceptions + }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + this.interceptions = this.interceptions.filter((config) => { + return !interceptions.some((interception) => { + return config.interceptions.some((i) => { + return i.domain === interception.domain && i.operation === interception.operation; + }); + }); + }); + } + catch (error) { + const message = error.message || "Unknown error"; + const newError = new Error(`Failed to unregister interception: ${message}`); + throw newError; + } + } + async handleInterception(domain, operation, operationArgs, phase) { + if (this.interop.methods(this.InterceptorMethodName).length === 0) { + return {}; + } + const result = await this.interop.invoke(this.InterceptorMethodName, { + command: "raiseInterception", + interceptions: [{ + operationArgs, + domain, + operation, + phase + }] + }, 'best', { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return result.returned; + } + static createProxyObject(apiToIntercept, domain, interception) { + const methods = Interception.OperationsPerDomain[domain] || []; + const handler = { + get(target, propertyKey, receiver) { + const property = Reflect.get(target, propertyKey, receiver); + try { + if (typeof property !== "function") { + return property; + } + const shouldIntercept = methods.includes(propertyKey); + const isAwaitable = Utils.isPromise(property) || Utils.isAsyncFunction(property); + if (!shouldIntercept || !isAwaitable) { + return property; + } + return Interception.interceptMethod(property, propertyKey, target, domain, interception); + } + catch (error) { + return property; + } + } + }; + const proxyAPI = new Proxy(apiToIntercept, handler); + return proxyAPI; + } + static interceptMethod(originalMethod, propertyKey, target, domain, interception) { + return async function (...args) { + const beforeInterceptionResult = await interception.handleInterception(domain, propertyKey, args, "before"); + if (!Utils.isNullOrUndefined(beforeInterceptionResult.operationResult)) { + return beforeInterceptionResult.operationResult; + } + if (!Utils.isNullOrUndefined(beforeInterceptionResult.operationArgs)) { + args = beforeInterceptionResult.operationArgs; + } + const methodResult = await originalMethod.apply(target, args); + const afterInterceptionResult = await interception.handleInterception(domain, propertyKey, [methodResult], "after"); + if (!Utils.isNullOrUndefined(afterInterceptionResult.operationResult)) { + return afterInterceptionResult.operationResult; + } + return methodResult; + }; + } + toAPI() { + return { + register: this.register.bind(this), + unregister: this.unregister.bind(this), + }; + } + async registerMethodIfNotRegistered() { + var _a; + if ((_a = this.whenRegisteredPromise) === null || _a === void 0 ? void 0 : _a.ended) { + return; + } + this.whenRegisteredPromise = new PromiseWrapper(); + this.registerMethod(); + } + async registerMethod() { + await this.interop.register(this.InterceptorHandlerMethodName, async (data) => { + const command = data.command; + if (command === "raiseInterception") { + const raisedInterception = data.interception; + const interceptor = this.interceptions.find((config) => { + return config.interceptions.some((interception) => { + return interception.domain === raisedInterception.domain && interception.operation === raisedInterception.operation; + }); + }); + const result = await interceptor.handler(raisedInterception); + return result; + } + }); + this.whenRegisteredPromise.resolve(); + } + validateInterceptions(interceptions) { + if (!Array.isArray(interceptions)) { + throw new Error("Please provide a valid array of interceptions."); + } + if (interceptions.length === 0) { + throw new Error("Please provide at least one interception."); + } + for (const interception of interceptions) { + if (typeof interception === "undefined" || interception === null || typeof interception !== "object" || Array.isArray(interception)) { + throw new Error("Please provide a valid interception object."); + } + if (typeof interception.domain !== "string" || !interception.domain) { + throw new Error("Please provide a valid domain string."); + } + if (typeof interception.operation !== "string" || !interception.operation) { + throw new Error("Please provide a valid operation string."); + } + this.validateTypeString(interception); + } + } + validateTypeString(interception) { + if (!isUndefinedOrNull(interception.phase)) { + const isValidType = ["all", "before", "after"].includes(interception.phase); + if (typeof interception.phase !== "string" || !isValidType) { + throw new Error("Please provide a valid phase string."); + } + } + } + } + Interception.OperationsPerDomain = { + "intents": ["raise"] + }; + + const callInfo = new FactoryCallInfo(); + const factory = async (options) => { + let firstRun = false; + if (!callInfo.initialized) { + firstRun = true; + callInfo.init(options); + } + const glue42gd = typeof window !== "undefined" && window.glue42gd; + if (glue42gd) { + if (!firstRun) { + callInfo.addCall(options); + return callInfo.promise; + } + } + const g = await factoryCore(options, glue42gd); + callInfo.resolve(g); + return g; + }; + const factoryCore = async (options, glue42gd) => { + const T42GDExecuteMethod = "T42.GD.Execute"; + const gdMajorVersion = Utils.getGDMajorVersion(); + options = options || {}; + const glueConfig = prepareConfig(options); + options.gateway = options.gateway || {}; + let _appManager; + let _activity; + let _windows; + let _displays; + let _channels; + let _prefs; + const _interceptors = new Interception(); + const _browserEventsDispatcher = new EventsDispatcher(glueConfig); + function createWindows(core) { + if (glueConfig.windows) { + const windowsLogger = getLibLogger("windows", core.logger, glueConfig.windows); + _windows = WindowsFactory(core.agm, windowsLogger, () => { + return _appManager; + }, () => { + return _displays; + }, () => { + return _channels; + }, gdMajorVersion); + debugLog(_windows); + return _windows; + } + } + function createActivities(core) { + var _a; + if (glueConfig.activities) { + if (ActivityModule.checkIsUsingGW3Implementation && ActivityModule.checkIsUsingGW3Implementation(core.connection)) { + const activityLogger = getLibLogger("activity", core.logger, glueConfig.activities); + _activity = new ActivityModule({ + connection: core.connection, + contexts: core.contexts, + agm: core.agm, + logger: activityLogger, + logLevel: "info", + disableAutoAnnounce: false, + disposeRequestHandling: "exit", + announcementInfo: null, + windows: _windows, + appManagerGetter: () => { + return _appManager; + }, + mode: glueConfig.activities.mode, + typesToTrack: glueConfig.activities.typesToTrack, + activityId: (_a = glue42gd === null || glue42gd === void 0 ? void 0 : glue42gd.activityInfo) === null || _a === void 0 ? void 0 : _a.activityId, + gdMajorVersion + }).api; + debugLog(_activity); + return _activity; + } + } + } + function createAppManager(core) { + if (!glueConfig.appManager) { + return; + } + const logger = getLibLogger("appManager", core.logger, glueConfig.appManager); + _appManager = AppManagerFactory({ + agm: core.agm, + windows: _windows, + logger, + activities: _activity, + mode: glueConfig.appManager.mode, + gdMajorVersion + }); + debugLog(_appManager); + return _appManager; + } + function createLayouts(core) { + var _a; + if (!glueConfig.layouts) { + return; + } + const logger = getLibLogger("layouts", core.logger, glueConfig.layouts); + const layoutsConfig = glueConfig.layouts; + const lay = LayoutsFactory({ + agm: core.agm, + appManager: _appManager, + activityGetter: () => _activity, + logger, + mode: layoutsConfig.mode, + autoSaveWindowContext: (_a = layoutsConfig.autoSaveWindowContext) !== null && _a !== void 0 ? _a : false, + gdMajorVersion + }); + debugLog(lay); + return lay; + } + function createChannels(core) { + if (!glueConfig.channels) { + return; + } + const logger = getLibLogger("channels", core.logger, glueConfig.channels); + if (!core.contexts) { + logger.error("Channels library requires Contexts library to be initialized."); + return; + } + _channels = factory$4({ operationMode: glueConfig.channels.operationMode }, core.contexts, core.agm, () => _windows, () => _appManager, logger); + debugLog(_channels); + return _channels; + } + function createHotkeys(core) { + const hotkeysAPI = factory$3(core.agm); + debugLog(hotkeysAPI); + return hotkeysAPI; + } + function createIntents(core) { + const domain = "intents"; + const intents = new Intents(core.agm, _windows, core.logger.subLogger(domain), options, _prefs, _appManager); + const intentsAPI = intents.toAPI(); + const proxyIntentsAPI = Interception.createProxyObject(intentsAPI, domain, _interceptors); + debugLog(proxyIntentsAPI); + return proxyIntentsAPI; + } + function createNotifications(core) { + const notificationsAPI = new Notifications(core.interop, core.logger).toAPI(); + debugLog(notificationsAPI); + return notificationsAPI; + } + function createDisplaysApi(core) { + if (glueConfig.displays) { + const displaysLogger = getLibLogger("displays", core.logger, glueConfig.displays); + _displays = new DisplayManager(core.agm, displaysLogger); + debugLog(_displays); + return _displays; + } + } + function createThemes(core) { + if (!core.contexts) { + return; + } + const themesAPI = factory$2(core.contexts, core.interop); + debugLog(themesAPI); + return themesAPI; + } + function createPrefs(core) { + var _a, _b; + const appName = (_b = (_a = options.application) !== null && _a !== void 0 ? _a : glue42gd === null || glue42gd === void 0 ? void 0 : glue42gd.applicationName) !== null && _b !== void 0 ? _b : core.interop.instance.application; + _prefs = new Prefs(appName, core.interop); + debugLog(_prefs); + return _prefs; + } + function createCookies(core) { + const api = factory$1(core.interop, T42GDExecuteMethod); + debugLog(api); + return api; + } + function createInterception(core) { + _interceptors.init(core.interop); + debugLog(_interceptors); + return _interceptors.toAPI(); + } + function getLibLogger(loggerName, logger, config) { + const newLogger = logger.subLogger(loggerName); + if (config && config.logger) { + const loggerConfig = config.logger; + if (loggerConfig.console) { + newLogger.consoleLevel(loggerConfig.console); + } + if (loggerConfig.publish) { + newLogger.publishLevel(loggerConfig.publish); + } + } + return newLogger; + } + const ext = { + libs: [ + { name: "windows", create: createWindows }, + { name: "activities", create: createActivities }, + { name: "appManager", create: createAppManager }, + { name: "layouts", create: createLayouts }, + { name: "channels", create: createChannels }, + { name: "hotkeys", create: createHotkeys }, + { name: "displays", create: createDisplaysApi }, + { name: "prefs", create: createPrefs }, + { name: "intents", create: createIntents }, + { name: "notifications", create: createNotifications }, + { name: "themes", create: createThemes }, + { name: "cookies", create: createCookies }, + { name: "interception", create: createInterception } + ], + version, + enrichGlue: (glue) => { + glue.config.activities = glueConfig.activities; + glue.config.windows = glueConfig.windows; + glue.config.appManager = glueConfig.appManager; + glue.config.layouts = glueConfig.layouts; + glue.config.channels = glueConfig.channels; + glue.config.displays = glueConfig.displays; + }, + }; + const currentLog = []; + if (typeof window !== "undefined") { + if (!window.glueFactoryLog) { + window.glueFactoryLog = []; + } + window.glueFactoryLog.push(currentLog); + } + function debugLog(entry) { + currentLog.push(entry); + } + const glueApi = (await IOConnectCoreFactory(options, ext)); + if (Array.isArray(options === null || options === void 0 ? void 0 : options.libraries) && options.libraries.length) { + await Promise.all(options.libraries.map((lib) => lib(glueApi, options))); + } + _browserEventsDispatcher.start(glueApi); + return glueApi; + }; + factory.coreVersion = IOConnectCoreFactory.version; + factory.version = version; + factory.calls = callInfo; + + var _a, _b; + let whatToExpose = factory; + let shouldSetToWindow = true; + if (typeof window !== "undefined") { + const windowAsAny = window; + const iodesktop = (_a = windowAsAny.iodesktop) !== null && _a !== void 0 ? _a : windowAsAny.glue42gd; + if (iodesktop && iodesktop.autoInjected) { + whatToExpose = (_b = windowAsAny.IODesktop) !== null && _b !== void 0 ? _b : windowAsAny.Glue; + shouldSetToWindow = false; + } + if (shouldSetToWindow) { + windowAsAny.Glue = whatToExpose; + windowAsAny.IODesktop = whatToExpose; + } + delete windowAsAny.IOBrowser; + delete windowAsAny.GlueCore; + } + whatToExpose.default = whatToExpose; + var whatToExpose$1 = whatToExpose; + + return whatToExpose$1; + +})); +//# sourceMappingURL=desktop.umd.js.map diff --git a/typescript/solution/clients/src/lib/io.applications.css b/typescript/solution/clients/src/lib/io.applications.css new file mode 100644 index 0000000..98e5910 --- /dev/null +++ b/typescript/solution/clients/src/lib/io.applications.css @@ -0,0 +1,12 @@ +:root{--bs-blue: #007be5;--bs-indigo: #6610f2;--bs-purple: #6f42c1;--bs-pink: #fd397a;--bs-red: #ff511f;--bs-orange: #fd7e14;--bs-yellow: #f9a825;--bs-green: #43a047;--bs-teal: #616161;--bs-cyan: #469eb9;--bs-white: #fff;--bs-gray: #6c757d;--bs-gray-dark: #343a40;--bs-gray-100: #f8f9fa;--bs-gray-200: #e9ecef;--bs-gray-300: #dee2e6;--bs-gray-400: #ced4da;--bs-gray-500: #adb5bd;--bs-gray-600: #6c757d;--bs-gray-700: #495057;--bs-gray-800: #343a40;--bs-gray-900: #212529;--bs-primary: #007be5;--bs-secondary: #616161;--bs-success: #43a047;--bs-info: #469eb9;--bs-warning: #f9a825;--bs-danger: #ff511f;--bs-light: #616161;--bs-dark: #616161;--bs-primary-rgb: 0,123,229;--bs-secondary-rgb: 97,97,97;--bs-success-rgb: 67,160,71;--bs-info-rgb: 70,158,185;--bs-warning-rgb: 249,168,37;--bs-danger-rgb: 255,81,31;--bs-light-rgb: 97,97,97;--bs-dark-rgb: 97,97,97;--bs-white-rgb: 255,255,255;--bs-black-rgb: 0,0,0;--bs-body-color-rgb: 33,37,41;--bs-body-bg-rgb: 255,255,255;--bs-font-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--bs-gradient: linear-gradient(180deg, rgba(255,255,255,0.15), rgba(255,255,255,0));--bs-body-font-family: Montserrat,Helvetica Neue,Arial,sans-serif;--bs-body-font-size: .75rem;--bs-body-font-weight: 400;--bs-body-line-height: 1.5;--bs-body-color: #212529;--bs-body-bg: #fff}:root{--t42-font-family: "Montserrat", "Helvetica Neue", Arial, sans-serif;--t42-font-size: 0.75rem;--bs-gutter-x: 0.938rem;--primary: #007be5;--secondary: #616161;--success: #43a047;--info: #616161;--warning: #f9a825;--danger: #ff511f;--light: #616161;--dark: #616161;--white: #ffffff}.dark{--t42-bg-light-base: 0, 0%;--t42-bg-light-l: 18%;--t42-bg-light: 45, 45, 45;--t42-bg-mid: 37, 37, 37;--t42-bg-dark: 30, 30, 30;--t42-content-color-base: 0, 0%;--t42-content-color: #bababa;--t42-content-color-l: 73%;--t42-content-color-muted: hsl(var(--t42-content-color-base), 63%);--t42-content-color-disabled: hsl(var(--t42-content-color-base), 43%);--t42-color-opacity-025: hsla(var(--t42-content-color-base), 100%, 0.025);--t42-color-opacity-05: hsla(var(--t42-content-color-base), 100%, 0.05);--t42-color-opacity-10: hsla(var(--t42-content-color-base), 100%, 0.1);--t42-color-opacity-20: hsla(var(--t42-content-color-base), 100%, 0.2);--t42-color-opacity-30: hsla(var(--t42-content-color-base), 100%, 0.3);--t42-link-color: hsl(var(--t42-content-color-base), 100%);--t42-shadow: 0 0 12px 0 hsla(var(--t42-content-color-base), 0%, 0.15);--t42-border: 0.0625rem solid var(--t42-color-opacity-10);--t42-logo-icon: url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 xmlns:xlink=%27http://www.w3.org/1999/xlink%27 x=%270px%27 y=%270px%27 viewBox=%270 0 100.2 121%27 style=%27enable-background:new 0 0 100.2 121;%27%3E%3Cpath fill=%27%233A77BC%27 d=%27M59.4,10.6l-8.3,8.3c-0.5,0.5-1.4,0.5-1.9,0l-8.3-8.3c-0.5-0.5-0.5-1.4,0-1.9l8.3-8.3c0.5-0.5,1.4-0.5,1.9,0 l8.3,8.3C59.9,9.2,59.9,10.1,59.4,10.6z M59.3,110.4l-8.3-8.3c-0.5-0.5-1.4-0.5-1.9,0l-8.3,8.3c-0.5,0.5-0.5,1.4,0,1.9l8.3,8.3 c0.5,0.5,1.4,0.5,1.9,0l8.3-8.3C59.9,111.8,59.9,110.9,59.3,110.4z%27/%3E%3Cpath fill=%27%23FFFFFF%27 d=%27M100.1,60.1c0.3,7.3-2.9,14.3-9.3,20.6l-24.7,24.7c-0.6,0.6-1.5,0.6-2.1,0l-8.1-8.1c-0.6-0.6-0.6-1.5,0-2.1 l24.7-24.7c0.1-0.1,0.2-0.2,0.3-0.3c3.2-3.3,4.7-6.7,4.4-10.2c0-0.4-0.1-0.8-0.2-1.3c-0.6-3.3-2.8-7-6.8-11l-9.9-9.9 c-0.3-0.3-0.7-0.5-1.1-0.5c-0.4,0-0.8,0.2-1.3,0.6L34.5,69.6c-0.6,0.6-1.5,0.6-2.1,0L27.7,65c-3.3-3.3-3.8-5.1-1.3-7.6 c11.1-11.2,22-22.1,33.2-33.2c2.7-2.7,5.1-4.2,7.5-4.3c2.5-0.1,4.7,1.2,6.9,3.5l14.3,14.3C95.9,45.3,99.8,52.8,100.1,60.1 L100.1,60.1z M0,60.9c0.3,7.3,3.7,14.3,11.2,21.9l14.8,14.8c2.3,2.3,4.5,3.6,6.9,3.5c2.4-0.1,4.8-1.6,7.5-4.3 c11.1-11.1,22.1-22,33.2-33.2c2.5-2.5,2-4.3-1.3-7.6l-4.7-4.7c-0.6-0.6-1.5-0.6-2.1,0L34,83c-0.5,0.5-0.9,0.6-1.3,0.6 c-0.4,0-0.7-0.1-1.1-0.5L21.3,72.7c-4-4-5.7-7.2-6.3-10.5c-0.1-0.4-0.1-0.8-0.2-1.3c-0.3-3.5,1.2-6.9,4.4-10.2 c0.1-0.1,0.2-0.2,0.3-0.3l24.7-24.7c0.6-0.6,0.6-1.5,0-2.1l-8.1-8.1c-0.6-0.6-1.5-0.6-2.1,0L9.3,40.3C2.9,46.6-0.3,53.5,0,60.9 L0,60.9z%27/%3E%3C/svg%3E%0A");--t42-icon-color: var(--t42-link-color);--t42-list-group-hover-bg-special: hsla(var(--t42-content-color-base), 100%, 0.065);--backdrop-filter: blur(5px) saturate(200%);--accordion-filter: invert(1) brightness(1);--filter-close: invert(1);--t42-body: rgb(var(--t42-bg-dark));--pink: rgb(0 170 200);--t42-link-hover-color: hsl(var(--t42-bg-light-base), 100%);--t42-link-hover-bg: var(--t42-color-opacity-05);--t42-link-active-bg: var(--t42-color-opacity-10);--t42-input-bg: rgb(var(--t42-bg-dark));--t42-input-disabled-bg: Hsla(var(--t42-content-color-base), 100%, 0.075);--t42-tooltip-bg: rgba(var(--t42-bg-dark), 0.85);--t42-modal-bg: rgba(var(--t42-bg-light), 0.75);--t42-table-active-bg: rgba(255, 255, 255, 0.1);--t42-select-indicator: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9IiNFRUVFRUUiIHZpZXdCb3g9IjAgMCAxNiAxNiI+PHBhdGggZD0iTTIuNSA1LjVjLjQtLjQgMS0uNSAxLjYgMGwzLjkgMy43bDMuOS0zLjdjLjUtLjUgMS4xLS40IDEuNiAwYy40LjQuNCAxLjIgMCAxLjZjLS40LjQtNC43IDQuNS00LjcgNC41Yy0uMi4yLS41LjMtLjguM3MtLjYtLjEtLjgtLjNjMCAwLTQuMy00LjEtNC43LTQuNXMtLjQtMS4yIDAtMS42eiI+PC9wYXRoPjwvc3ZnPg==)}.light{--t42-bg-light-base: 0, 0%;--t42-bg-light-l: 100%;--t42-bg-light: 255, 255, 255;--t42-bg-mid: 250, 250, 250;--t42-bg-dark: 245, 245, 245;--t42-content-color-base: 0, 0%;--t42-content-color: #757575;--t42-content-color-l: 46%;--t42-content-color-muted: hsl(var(--t42-content-color-base), 66%);--t42-color-opacity-025: hsla(var(--t42-content-color-base), 0%, 0.025);--t42-color-opacity-05: hsla(var(--t42-content-color-base), 0%, 0.05);--t42-color-opacity-10: hsla(var(--t42-content-color-base), 0%, 0.075);--t42-color-opacity-30: hsla(var(--t42-content-color-base), 0%, 0.1);--t42-color-opacity-20: hsla(var(--t42-content-color-base), 0%, 0.2);--t42-link-color: hsl(var(--t42-content-color-base), 5%);--t42-shadow: 0 0 12px 0 hsla(var(--t42-content-color-base), 0%, 0.05);--t42-border: 0.0625rem solid var(--t42-color-opacity-10);--t42-logo-icon: url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 xmlns:xlink=%27http://www.w3.org/1999/xlink%27 x=%270px%27 y=%270px%27 viewBox=%270 0 100.2 121%27 style=%27enable-background:new 0 0 100.2 121;%27%3E%3Cpath fill=%27%233A77BC%27 d=%27M59.4,10.6l-8.3,8.3c-0.5,0.5-1.4,0.5-1.9,0l-8.3-8.3c-0.5-0.5-0.5-1.4,0-1.9l8.3-8.3c0.5-0.5,1.4-0.5,1.9,0 l8.3,8.3C59.9,9.2,59.9,10.1,59.4,10.6z M59.3,110.4l-8.3-8.3c-0.5-0.5-1.4-0.5-1.9,0l-8.3,8.3c-0.5,0.5-0.5,1.4,0,1.9l8.3,8.3 c0.5,0.5,1.4,0.5,1.9,0l8.3-8.3C59.9,111.8,59.9,110.9,59.3,110.4z%27/%3E%3Cpath fill=%27%23083044%27 d=%27M100.1,60.1c0.3,7.3-2.9,14.3-9.3,20.6l-24.7,24.7c-0.6,0.6-1.5,0.6-2.1,0l-8.1-8.1c-0.6-0.6-0.6-1.5,0-2.1 l24.7-24.7c0.1-0.1,0.2-0.2,0.3-0.3c3.2-3.3,4.7-6.7,4.4-10.2c0-0.4-0.1-0.8-0.2-1.3c-0.6-3.3-2.8-7-6.8-11l-9.9-9.9 c-0.3-0.3-0.7-0.5-1.1-0.5c-0.4,0-0.8,0.2-1.3,0.6L34.5,69.6c-0.6,0.6-1.5,0.6-2.1,0L27.7,65c-3.3-3.3-3.8-5.1-1.3-7.6 c11.1-11.2,22-22.1,33.2-33.2c2.7-2.7,5.1-4.2,7.5-4.3c2.5-0.1,4.7,1.2,6.9,3.5l14.3,14.3C95.9,45.3,99.8,52.8,100.1,60.1 L100.1,60.1z M0,60.9c0.3,7.3,3.7,14.3,11.2,21.9l14.8,14.8c2.3,2.3,4.5,3.6,6.9,3.5c2.4-0.1,4.8-1.6,7.5-4.3 c11.1-11.1,22.1-22,33.2-33.2c2.5-2.5,2-4.3-1.3-7.6l-4.7-4.7c-0.6-0.6-1.5-0.6-2.1,0L34,83c-0.5,0.5-0.9,0.6-1.3,0.6 c-0.4,0-0.7-0.1-1.1-0.5L21.3,72.7c-4-4-5.7-7.2-6.3-10.5c-0.1-0.4-0.1-0.8-0.2-1.3c-0.3-3.5,1.2-6.9,4.4-10.2 c0.1-0.1,0.2-0.2,0.3-0.3l24.7-24.7c0.6-0.6,0.6-1.5,0-2.1l-8.1-8.1c-0.6-0.6-1.5-0.6-2.1,0L9.3,40.3C2.9,46.6-0.3,53.5,0,60.9 L0,60.9z%27/%3E%3C/svg%3E%0A");--t42-icon-color: Hsl(var(--t42-content-color-base), 38%);--t42-list-group-hover-bg-special: hsla(var(--t42-content-color-base), 95%, 0.065);--backdrop-filter: blur(5px) saturate(200%);--accordion-filter: brightness(0%);--filter-close: invert(0);--t42-body: rgb(var(--t42-bg-mid));--t42-link-hover-color: hsl(var(--t42-bg-light-base), 0%);--t42-link-hover-bg: hsl(var(--t42-content-color-base), 95%);--t42-link-active-bg: hsl(var(--t42-content-color-base), 90%);--t42-input-bg: rgb(var(--t42-bg-light));--t42-input-disabled-bg: var(--t42-color-opacity-10);--t42-tooltip-bg: rgba(var(--t42-bg-light), 0.95);--t42-modal-bg: rgba(var(--t42-bg-light), 0.95);--t42-table-active-bg: rgba(0, 0, 0, 0.025);--t42-select-indicator: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9IiM2MTYxNjEiIHZpZXdCb3g9IjAgMCAxNiAxNiI+PHBhdGggZD0iTTIuNSA1LjVjLjQtLjQgMS0uNSAxLjYgMGwzLjkgMy43bDMuOS0zLjdjLjUtLjUgMS4xLS40IDEuNiAwYy40LjQuNCAxLjIgMCAxLjZjLS40LjQtNC43IDQuNS00LjcgNC41Yy0uMi4yLS41LjMtLjguM3MtLjYtLjEtLjgtLjNjMCAwLTQuMy00LjEtNC43LTQuNXMtLjQtMS4yIDAtMS42eiI+PC9wYXRoPjwvc3ZnPg==)}*,*::before,*::after{box-sizing:border-box}@media (prefers-reduced-motion: no-preference){:root{scroll-behavior:smooth}}body{margin:0;font-family:var(--bs-body-font-family);font-size:var(--bs-body-font-size);font-weight:var(--bs-body-font-weight);line-height:var(--bs-body-line-height);color:var(--bs-body-color);text-align:var(--bs-body-text-align);background-color:var(--bs-body-bg);-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:rgba(0,0,0,0)}hr{margin:1rem 0;color:inherit;background-color:currentColor;border:0;opacity:.25}hr:not([size]){height:1px}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem;font-weight:500;line-height:1.2;color:var(--t42-link-color)}h1{font-size:calc(1.26563rem + .1875vw)}@media (min-width: 1200px){h1{font-size:1.40625rem}}h2{font-size:1.125rem}h3{font-size:.98475rem}h4{font-size:.84375rem}h5{font-size:.75rem}h6{font-size:.7035rem}p{margin-top:0;margin-bottom:1rem}abbr[title],abbr[data-bs-original-title]{text-decoration:underline dotted;cursor:help;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}ol,ul{padding-left:2rem}ol,ul,dl{margin-top:0;margin-bottom:1rem}ol ol,ul ul,ol ul,ul ol{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:.875em}mark{padding:0.2rem 0.2rem 0;background-color:#007be5}sub,sup{position:relative;font-size:.75em;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:var(--t42-link-color);text-decoration:underline}a:hover{color:var(--t42-link-hover-color)}a:not([href]):not([class]),a:not([href]):not([class]):hover{color:inherit;text-decoration:none}pre,code,kbd,samp{font-family:var(--bs-font-monospace);font-size:1em;direction:ltr /* rtl:ignore */;unicode-bidi:bidi-override}pre{display:block;margin-top:0;margin-bottom:1rem;overflow:auto;font-size:inherit;color:var(--t42-content-color)}pre code{font-size:inherit;color:inherit;word-break:normal}code{font-size:inherit;color:#469eb9;word-wrap:break-word}a>code{color:inherit}kbd{padding:.2rem .4rem;font-size:inherit;color:#fff;background-color:#212529;border-radius:.25rem}kbd kbd{padding:0;font-size:1em;font-weight:700}figure{margin:0 0 1rem}img,svg{vertical-align:middle}table{caption-side:bottom;border-collapse:collapse}caption{padding-top:.25rem;padding-bottom:.25rem;color:var(--t42-content-color-muted);text-align:left}th{text-align:inherit;text-align:-webkit-match-parent}thead,tbody,tfoot,tr,td,th{border-color:inherit;border-style:solid;border-width:0}label{display:inline-block}button{border-radius:0}button:focus:not(:focus-visible){outline:0}input,button,select,optgroup,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,select{text-transform:none}[role="button"]{cursor:pointer}select{word-wrap:normal}select:disabled{opacity:1}[list]::-webkit-calendar-picker-indicator{display:none}button,[type="button"],[type="reset"],[type="submit"]{-webkit-appearance:button}button:not(:disabled),[type="button"]:not(:disabled),[type="reset"]:not(:disabled),[type="submit"]:not(:disabled){cursor:pointer}::-moz-focus-inner{padding:0;border-style:none}textarea{resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{float:left;width:100%;padding:0;margin-bottom:.5rem;font-size:calc(1.275rem + .3vw);line-height:inherit}@media (min-width: 1200px){legend{font-size:1.5rem}}legend+*{clear:left}::-webkit-datetime-edit-fields-wrapper,::-webkit-datetime-edit-text,::-webkit-datetime-edit-minute,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-year-field{padding:0}::-webkit-inner-spin-button{height:auto}[type="search"]{outline-offset:-2px;-webkit-appearance:textfield}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-color-swatch-wrapper{padding:0}::file-selector-button{font:inherit}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}iframe{border:0}summary{display:list-item;cursor:pointer}progress{vertical-align:baseline}[hidden]{display:none !important}body{color:var(--t42-content-color);font-family:var(--t42-font-family);background-color:var(--t42-body)}a:focus,button:focus,div:focus,span:focus{outline:0}a{text-decoration:none}dt{font-weight:normal}::selection{color:var(--white);background-color:var(--primary)}::-webkit-scrollbar{width:4px;height:4px}::-webkit-scrollbar-track{border-radius:.25rem;background:transparent}::-webkit-scrollbar-thumb{border-radius:.25rem;background:var(--t42-color-opacity-10)}::-webkit-resizer{background:transparent}::-webkit-scrollbar-corner{background:transparent}::-webkit-scrollbar-thumb:window-inactive{background:transparent}::-webkit-scrollbar-thumb:hover,::-webkit-scrollbar-thumb:active{background:Hsla(var(--t42-content-color-base), 100%, 0.05)}.accordion-button{position:relative;display:flex;align-items:center;width:100%;padding:1rem 1.25rem;font-size:.75rem;color:var(--t42-link-color);text-align:left;background-color:Rgb(var(--t42-bg-mid));border:0;border-radius:0;overflow-anchor:none;transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out,border-radius 0.15s ease}@media (prefers-reduced-motion: reduce){.accordion-button{transition:none}}.accordion-button:not(.collapsed){color:var(--t42-link-color);background-color:Rgb(var(--t42-bg-mid));box-shadow:inset 0 -1px 0 var(--t42-color-opacity-10)}.accordion-button:not(.collapsed)::after{background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 16 16%27 fill=%27var%28--t42-link-color%29%27%3e%3cpath fill-rule=%27evenodd%27 d=%27M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z%27/%3e%3c/svg%3e");transform:rotate(-180deg)}.accordion-button::after{flex-shrink:0;width:1.25rem;height:1.25rem;margin-left:auto;content:"";background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 16 16%27 fill=%27var%28--t42-link-color%29%27%3e%3cpath fill-rule=%27evenodd%27 d=%27M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z%27/%3e%3c/svg%3e");background-repeat:no-repeat;background-size:1.25rem;transition:transform 0.2s ease-in-out}@media (prefers-reduced-motion: reduce){.accordion-button::after{transition:none}}.accordion-button:hover{z-index:2}.accordion-button:focus{z-index:3;border-color:#007be5;outline:0;box-shadow:0 0 0 0 rgba(0,123,229,0.25)}.accordion-header{margin-bottom:0}.accordion-item{background-color:Rgb(var(--t42-bg-mid));border:1px solid var(--t42-color-opacity-10)}.accordion-item:first-of-type{border-top-left-radius:0;border-top-right-radius:0}.accordion-item:first-of-type .accordion-button{border-top-left-radius:0;border-top-right-radius:0}.accordion-item:not(:first-of-type){border-top:0}.accordion-item:last-of-type{border-bottom-right-radius:0;border-bottom-left-radius:0}.accordion-item:last-of-type .accordion-button.collapsed{border-bottom-right-radius:0;border-bottom-left-radius:0}.accordion-item:last-of-type .accordion-collapse{border-bottom-right-radius:0;border-bottom-left-radius:0}.accordion-body{padding:1rem 1.25rem}.accordion-flush .accordion-collapse{border-width:0}.accordion-flush .accordion-item{border-right:0;border-left:0;border-radius:0}.accordion-flush .accordion-item:first-child{border-top:0}.accordion-flush .accordion-item:last-child{border-bottom:0}.accordion-flush .accordion-item .accordion-button{border-radius:0}.accordion-button::after,.accordion-button:not(.collapsed)::after{filter:var(--accordion-filter)}.accordion-button:disabled,.accordion-button.disabled{color:var(--t42-content-color-disabled)}.accordion-button:disabled::after,.accordion-button.disabled::after{opacity:0.25}.alert{position:relative;padding:.75rem .875rem;margin-bottom:.5rem;border:1px solid transparent;border-radius:0}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-right:2.625rem}.alert-dismissible .btn-close{position:absolute;top:0;right:0;z-index:2;padding:.9375rem .875rem}.alert-primary{color:#004a89;background-color:#cce5fa;border-color:#b3d7f7}.alert-primary .alert-link{color:#003b6e}.alert-secondary{color:#3a3a3a;background-color:#dfdfdf;border-color:#d0d0d0}.alert-secondary .alert-link{color:#2e2e2e}.alert-success{color:#28602b;background-color:#d9ecda;border-color:#c7e3c8}.alert-success .alert-link{color:#204d22}.alert-info{color:#2a5f6f;background-color:#daecf1;border-color:#c8e2ea}.alert-info .alert-link{color:#224c59}.alert-warning{color:#64430f;background-color:#feeed3;border-color:#fde5be}.alert-warning .alert-link{color:#50360c}.alert-danger{color:#993113;background-color:#ffdcd2;border-color:#ffcbbc}.alert-danger .alert-link{color:#7a270f}.alert-light{color:#3a3a3a;background-color:#dfdfdf;border-color:#d0d0d0}.alert-light .alert-link{color:#2e2e2e}.alert-dark{color:#3a3a3a;background-color:#dfdfdf;border-color:#d0d0d0}.alert-dark .alert-link{color:#2e2e2e}.alert{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border-color;position:relative;z-index:10000;display:flex;align-items:center;border:0.0625rem solid var(--t42-color-opacity-10);overflow:hidden;color:var(--t42-content-color);background-color:Rgba(var(--t42-bg-light), 0.75);background-repeat:no-repeat;background-size:100%;backdrop-filter:var(--backdrop-filter)}.alert h5{margin-bottom:0;color:var(--t42-content-color)}.alert p{margin-bottom:0}.alert-link{color:var(--t42-link-color);font-weight:normal}.alert-dismissible .close{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border-color;position:absolute;top:50%;right:0.75rem;width:1.5rem;height:1.5rem;padding:0;border:0;border-radius:50%;color:var(--t42-content-color);font-weight:700;font-size:1rem;line-height:1;background-color:var(--t42-color-opacity-05);transform:translateY(-50%);opacity:0.5}.alert-dismissible .close::before{position:relative;top:-1px}.alert-dismissible .close:hover{opacity:1}.alert::before{z-index:1;width:1.25rem;height:1.25rem;margin-right:0.875rem;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-position:center;mask-position:center;background-color:var(--t42-icon-color);content:""}.alert::after{position:absolute;top:0;left:0;z-index:-1;width:1px;height:1px;border-radius:50%;opacity:1;animation:color-pulse 3s infinite;content:""}.alert-primary:hover,.alert-secondary:hover,.alert-info:hover,.alert-light:hover,.alert-dark:hover{border-color:#616161}.alert-primary::after,.alert-secondary::after,.alert-info::after,.alert-light::after,.alert-dark::after{background:#616161;background:radial-gradient(circle, rgba(255,255,255,0.35) 0%, rgba(97,97,97,0.75) 60%, #616161 75%, #616161 100%)}.alert-primary::before,.alert-secondary::before,.alert-info::before,.alert-light::before,.alert-dark::before{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M260.6 484.4q0-4.1-4.6-4.1q-16.9 0-29.2-12.3t-11.8-29.2q0-4.6-4.6-4.6t-4.6 4.6q0 21 14.8 35.8t35.3 14.3q4.6 0 4.6-4.6zM493.6 402.4q0 14.8-10.8 25.6t-25.6 10.8h-128q0 30.2-21.5 51.7t-51.7 21.5t-51.7-21.5t-21.5-51.7h-128q-14.8 0-25.6-10.8t-10.8-25.6q14.3-12.3 26.1-25.1t24.1-34.3t21.5-45.6t13.8-58.9t5.6-74.2q0-43 33.8-80.4t87.6-45.6q-2.6-5.1-2.6-10.8q0-11.8 8.2-19.5t19.5-8.2t19.5 8.2t8.2 19.5q0 5.6-2.6 10.8q54.3 8.2 87.6 45.6t33.8 80.4q0 39.9 5.6 74.2t14.3 58.9t21 45.6t24.6 34.3t25.6 25.1z%27%3E%3C/path%3E%3C/svg%3E")}.alert-success:hover{border-color:#43a047}.alert-success::after{background:#43a047;background:radial-gradient(circle, rgba(255,255,255,0.35) 0%, rgba(67,160,71,0.75) 60%, #43a047 75%, #43a047 100%)}.alert-success::before{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M477.4 152.8q0 11.3-8.2 19.5l-245.8 245.8q-8.2 7.7-19.5 7.7t-19.5-7.7l-142.3-142.3q-7.7-8.2-7.7-19.5t7.7-19.5l38.9-38.9q8.2-8.2 19.5-8.2t19.5 8.2l84 84.5l187.4-187.9q8.2-8.2 19.5-8.2t19.5 8.2l38.9 38.9q8.2 7.7 8.2 19.5z%27%3E%3C/path%3E%3C/svg%3E")}.alert-warning:hover{border-color:#f9a825}.alert-warning::after{background:#f9a825;background:radial-gradient(circle, rgba(255,255,255,0.35) 0%, rgba(249,168,37,0.75) 60%, #f9a825 75%, #f9a825 100%)}.alert-warning::before{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M292.4 410.9v-54.3q0-4.1-2.6-6.7t-6.1-2.6h-55.3q-3.6 0-6.1 2.6t-2.6 6.7v54.3q0 4.1 2.6 6.7t6.1 3.1h55.3q3.6 0 6.1-3.1t2.6-6.7zM291.8 304.4l5.1-131.6q0-3.1-2.6-5.1q-3.6-3.1-7.2-3.1h-62.5q-3.1 0-7.2 3.1q-2.6 2-2.6 6.1l4.6 130.6q0 2.6 3.1 4.6t6.7 1.5h52.7q4.1 0 7.2-1.5t2.6-4.6zM288.3 37.1l219.1 402.4q10.2 17.9-.5 35.8q-4.6 8.7-13.3 13.3t-17.9 5.1h-439.3q-9.2 0-17.9-5.1t-13.3-13.3q-10.8-17.9-.5-35.8l219.6-402.4q4.6-8.7 13.3-13.8t18.4-5.1t18.4 5.1t13.8 13.8z%27%3E%3C/path%3E%3C/svg%3E%0A")}.alert-danger:hover{border-color:#ff511f}.alert-danger::after{background:#ff511f;background:radial-gradient(circle, rgba(255,255,255,0.35) 0%, rgba(255,81,31,0.75) 60%, #ff511f 75%, #ff511f 100%)}.alert-danger::before{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 402 512%27%3E%3Cpath d=%27M370.728 359.68q0 11.264-7.68 19.456l-38.912 38.912q-8.192 7.68-19.456 7.68t-19.456-7.68l-83.968-84.48-83.968 84.48q-8.192 7.68-19.456 7.68t-19.456-7.68l-38.912-38.912q-8.192-8.192-8.192-19.456t8.192-19.456l83.968-83.968-83.968-83.968q-8.192-8.192-8.192-19.456t8.192-19.456l38.912-38.912q8.192-8.192 19.456-8.192t19.456 8.192l83.968 83.968 83.968-83.968q8.192-8.192 19.456-8.192t19.456 8.192l38.912 38.912q7.68 7.68 7.68 19.456t-7.68 19.456l-83.968 83.968 83.968 83.968q7.68 7.68 7.68 19.456z%27%3E%3C/path%3E%3C/svg%3E")}@keyframes color-pulse{0%{transform:scale(1);opacity:1}50%{transform:scale(250);opacity:0}100%{opacity:0}}.badge{display:inline-block;padding:.2rem .5rem;font-size:.75em;font-weight:300;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:1rem}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.badge{border:var(--t42-border);color:var(--t42-link-color);backdrop-filter:var(--backdrop-filter)}.badge.bg-primary{border:0.0625rem solid #007be5;background-color:rgba(0,123,229,0.15) !important}.badge.bg-secondary{border:0.0625rem solid #616161;background-color:rgba(97,97,97,0.15) !important}.badge.bg-success{border:0.0625rem solid #43a047;background-color:rgba(67,160,71,0.15) !important}.badge.bg-info{border:0.0625rem solid #469eb9;background-color:rgba(70,158,185,0.15) !important}.badge.bg-warning{border:0.0625rem solid #f9a825;background-color:rgba(249,168,37,0.15) !important}.badge.bg-danger{border:0.0625rem solid #ff511f;background-color:rgba(255,81,31,0.15) !important}.badge.bg-light{border:0.0625rem solid #616161;background-color:rgba(97,97,97,0.15) !important}.badge.bg-dark{border:0.0625rem solid #616161;background-color:rgba(97,97,97,0.15) !important}button .badge{border:0.0625rem solid var(--t42-color-opacity-30)}button:hover .badge{color:var(--white)}.btn-close{box-sizing:content-box;width:1em;height:1em;padding:0 0;color:var(--t42-content-color);background:transparent url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 16 16%27 fill=%27var%28--t42-content-color%29%27%3e%3cpath d=%27M.293.293a1 1 0 011.414 0L8 6.586 14.293.293a1 1 0 111.414 1.414L9.414 8l6.293 6.293a1 1 0 01-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 01-1.414-1.414L6.586 8 .293 1.707a1 1 0 010-1.414z%27/%3e%3c/svg%3e") center/1em auto no-repeat;border:0;border-radius:.25rem;opacity:.5}.btn-close:hover{color:var(--t42-content-color);text-decoration:none;opacity:.75}.btn-close:focus{outline:0;box-shadow:0 0 0 0 rgba(0,123,229,0.25);opacity:1}.btn-close:disabled,.btn-close.disabled{pointer-events:none;user-select:none;opacity:.25}.btn-close-white{filter:invert(1) grayscale(100%) brightness(200%)}.btn{display:inline-block;font-weight:400;line-height:1.875rem;color:#212529;text-align:center;text-decoration:none;vertical-align:middle;cursor:pointer;user-select:none;background-color:transparent;border:1px solid transparent;padding:0 .875rem;font-size:.75rem;border-radius:0;transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.btn{transition:none}}.btn:hover{color:#212529}.btn-check:focus+.btn,.btn:focus{outline:0;box-shadow:0 0 0 0 rgba(0,123,229,0.25)}.btn:disabled,.btn.disabled,fieldset:disabled .btn{pointer-events:none;opacity:.35}.btn-primary{color:#000;background-color:#007be5;border-color:#007be5}.btn-primary:hover{color:#000;background-color:#268fe9;border-color:#1a88e8}.btn-check:focus+.btn-primary,.btn-primary:focus{color:#000;background-color:#268fe9;border-color:#1a88e8;box-shadow:0 0 0 0 rgba(0,105,195,0.5)}.btn-check:checked+.btn-primary,.btn-check:active+.btn-primary,.btn-primary:active,.btn-primary.active,.show>.btn-primary.dropdown-toggle{color:#000;background-color:#3395ea;border-color:#1a88e8}.btn-check:checked+.btn-primary:focus,.btn-check:active+.btn-primary:focus,.btn-primary:active:focus,.btn-primary.active:focus,.show>.btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(0,105,195,0.5)}.btn-primary:disabled,.btn-primary.disabled{color:#000;background-color:#007be5;border-color:#007be5}.btn-secondary{color:#fff;background-color:#616161;border-color:#616161}.btn-secondary:hover{color:#fff;background-color:#525252;border-color:#4e4e4e}.btn-check:focus+.btn-secondary,.btn-secondary:focus{color:#fff;background-color:#525252;border-color:#4e4e4e;box-shadow:0 0 0 0 rgba(121,121,121,0.5)}.btn-check:checked+.btn-secondary,.btn-check:active+.btn-secondary,.btn-secondary:active,.btn-secondary.active,.show>.btn-secondary.dropdown-toggle{color:#fff;background-color:#4e4e4e;border-color:#494949}.btn-check:checked+.btn-secondary:focus,.btn-check:active+.btn-secondary:focus,.btn-secondary:active:focus,.btn-secondary.active:focus,.show>.btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(121,121,121,0.5)}.btn-secondary:disabled,.btn-secondary.disabled{color:#fff;background-color:#616161;border-color:#616161}.btn-success{color:#000;background-color:#43a047;border-color:#43a047}.btn-success:hover{color:#000;background-color:#5fae63;border-color:#56aa59}.btn-check:focus+.btn-success,.btn-success:focus{color:#000;background-color:#5fae63;border-color:#56aa59;box-shadow:0 0 0 0 rgba(57,136,60,0.5)}.btn-check:checked+.btn-success,.btn-check:active+.btn-success,.btn-success:active,.btn-success.active,.show>.btn-success.dropdown-toggle{color:#000;background-color:#69b36c;border-color:#56aa59}.btn-check:checked+.btn-success:focus,.btn-check:active+.btn-success:focus,.btn-success:active:focus,.btn-success.active:focus,.show>.btn-success.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(57,136,60,0.5)}.btn-success:disabled,.btn-success.disabled{color:#000;background-color:#43a047;border-color:#43a047}.btn-info{color:#000;background-color:#469eb9;border-color:#469eb9}.btn-info:hover{color:#000;background-color:#62adc4;border-color:#59a8c0}.btn-check:focus+.btn-info,.btn-info:focus{color:#000;background-color:#62adc4;border-color:#59a8c0;box-shadow:0 0 0 0 rgba(60,134,157,0.5)}.btn-check:checked+.btn-info,.btn-check:active+.btn-info,.btn-info:active,.btn-info.active,.show>.btn-info.dropdown-toggle{color:#000;background-color:#6bb1c7;border-color:#59a8c0}.btn-check:checked+.btn-info:focus,.btn-check:active+.btn-info:focus,.btn-info:active:focus,.btn-info.active:focus,.show>.btn-info.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(60,134,157,0.5)}.btn-info:disabled,.btn-info.disabled{color:#000;background-color:#469eb9;border-color:#469eb9}.btn-warning{color:#000;background-color:#f9a825;border-color:#f9a825}.btn-warning:hover{color:#000;background-color:#fab546;border-color:#fab13b}.btn-check:focus+.btn-warning,.btn-warning:focus{color:#000;background-color:#fab546;border-color:#fab13b;box-shadow:0 0 0 0 rgba(212,143,31,0.5)}.btn-check:checked+.btn-warning,.btn-check:active+.btn-warning,.btn-warning:active,.btn-warning.active,.show>.btn-warning.dropdown-toggle{color:#000;background-color:#fab951;border-color:#fab13b}.btn-check:checked+.btn-warning:focus,.btn-check:active+.btn-warning:focus,.btn-warning:active:focus,.btn-warning.active:focus,.show>.btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(212,143,31,0.5)}.btn-warning:disabled,.btn-warning.disabled{color:#000;background-color:#f9a825;border-color:#f9a825}.btn-danger{color:#000;background-color:#ff511f;border-color:#ff511f}.btn-danger:hover{color:#000;background-color:#ff6b41;border-color:#ff6235}.btn-check:focus+.btn-danger,.btn-danger:focus{color:#000;background-color:#ff6b41;border-color:#ff6235;box-shadow:0 0 0 0 rgba(217,69,26,0.5)}.btn-check:checked+.btn-danger,.btn-check:active+.btn-danger,.btn-danger:active,.btn-danger.active,.show>.btn-danger.dropdown-toggle{color:#000;background-color:#ff744c;border-color:#ff6235}.btn-check:checked+.btn-danger:focus,.btn-check:active+.btn-danger:focus,.btn-danger:active:focus,.btn-danger.active:focus,.show>.btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(217,69,26,0.5)}.btn-danger:disabled,.btn-danger.disabled{color:#000;background-color:#ff511f;border-color:#ff511f}.btn-light{color:#fff;background-color:#616161;border-color:#616161}.btn-light:hover{color:#fff;background-color:#525252;border-color:#4e4e4e}.btn-check:focus+.btn-light,.btn-light:focus{color:#fff;background-color:#525252;border-color:#4e4e4e;box-shadow:0 0 0 0 rgba(121,121,121,0.5)}.btn-check:checked+.btn-light,.btn-check:active+.btn-light,.btn-light:active,.btn-light.active,.show>.btn-light.dropdown-toggle{color:#fff;background-color:#4e4e4e;border-color:#494949}.btn-check:checked+.btn-light:focus,.btn-check:active+.btn-light:focus,.btn-light:active:focus,.btn-light.active:focus,.show>.btn-light.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(121,121,121,0.5)}.btn-light:disabled,.btn-light.disabled{color:#fff;background-color:#616161;border-color:#616161}.btn-dark{color:#fff;background-color:#616161;border-color:#616161}.btn-dark:hover{color:#fff;background-color:#525252;border-color:#4e4e4e}.btn-check:focus+.btn-dark,.btn-dark:focus{color:#fff;background-color:#525252;border-color:#4e4e4e;box-shadow:0 0 0 0 rgba(121,121,121,0.5)}.btn-check:checked+.btn-dark,.btn-check:active+.btn-dark,.btn-dark:active,.btn-dark.active,.show>.btn-dark.dropdown-toggle{color:#fff;background-color:#4e4e4e;border-color:#494949}.btn-check:checked+.btn-dark:focus,.btn-check:active+.btn-dark:focus,.btn-dark:active:focus,.btn-dark.active:focus,.show>.btn-dark.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(121,121,121,0.5)}.btn-dark:disabled,.btn-dark.disabled{color:#fff;background-color:#616161;border-color:#616161}.btn-outline-primary{color:#007be5;border-color:#007be5}.btn-outline-primary:hover{color:#000;background-color:#007be5;border-color:#007be5}.btn-check:focus+.btn-outline-primary,.btn-outline-primary:focus{box-shadow:0 0 0 0 rgba(0,123,229,0.5)}.btn-check:checked+.btn-outline-primary,.btn-check:active+.btn-outline-primary,.btn-outline-primary:active,.btn-outline-primary.active,.btn-outline-primary.dropdown-toggle.show{color:#000;background-color:#007be5;border-color:#007be5}.btn-check:checked+.btn-outline-primary:focus,.btn-check:active+.btn-outline-primary:focus,.btn-outline-primary:active:focus,.btn-outline-primary.active:focus,.btn-outline-primary.dropdown-toggle.show:focus{box-shadow:0 0 0 0 rgba(0,123,229,0.5)}.btn-outline-primary:disabled,.btn-outline-primary.disabled{color:#007be5;background-color:transparent}.btn-outline-secondary{color:#616161;border-color:#616161}.btn-outline-secondary:hover{color:#fff;background-color:#616161;border-color:#616161}.btn-check:focus+.btn-outline-secondary,.btn-outline-secondary:focus{box-shadow:0 0 0 0 rgba(97,97,97,0.5)}.btn-check:checked+.btn-outline-secondary,.btn-check:active+.btn-outline-secondary,.btn-outline-secondary:active,.btn-outline-secondary.active,.btn-outline-secondary.dropdown-toggle.show{color:#fff;background-color:#616161;border-color:#616161}.btn-check:checked+.btn-outline-secondary:focus,.btn-check:active+.btn-outline-secondary:focus,.btn-outline-secondary:active:focus,.btn-outline-secondary.active:focus,.btn-outline-secondary.dropdown-toggle.show:focus{box-shadow:0 0 0 0 rgba(97,97,97,0.5)}.btn-outline-secondary:disabled,.btn-outline-secondary.disabled{color:#616161;background-color:transparent}.btn-outline-success{color:#43a047;border-color:#43a047}.btn-outline-success:hover{color:#000;background-color:#43a047;border-color:#43a047}.btn-check:focus+.btn-outline-success,.btn-outline-success:focus{box-shadow:0 0 0 0 rgba(67,160,71,0.5)}.btn-check:checked+.btn-outline-success,.btn-check:active+.btn-outline-success,.btn-outline-success:active,.btn-outline-success.active,.btn-outline-success.dropdown-toggle.show{color:#000;background-color:#43a047;border-color:#43a047}.btn-check:checked+.btn-outline-success:focus,.btn-check:active+.btn-outline-success:focus,.btn-outline-success:active:focus,.btn-outline-success.active:focus,.btn-outline-success.dropdown-toggle.show:focus{box-shadow:0 0 0 0 rgba(67,160,71,0.5)}.btn-outline-success:disabled,.btn-outline-success.disabled{color:#43a047;background-color:transparent}.btn-outline-info{color:#469eb9;border-color:#469eb9}.btn-outline-info:hover{color:#000;background-color:#469eb9;border-color:#469eb9}.btn-check:focus+.btn-outline-info,.btn-outline-info:focus{box-shadow:0 0 0 0 rgba(70,158,185,0.5)}.btn-check:checked+.btn-outline-info,.btn-check:active+.btn-outline-info,.btn-outline-info:active,.btn-outline-info.active,.btn-outline-info.dropdown-toggle.show{color:#000;background-color:#469eb9;border-color:#469eb9}.btn-check:checked+.btn-outline-info:focus,.btn-check:active+.btn-outline-info:focus,.btn-outline-info:active:focus,.btn-outline-info.active:focus,.btn-outline-info.dropdown-toggle.show:focus{box-shadow:0 0 0 0 rgba(70,158,185,0.5)}.btn-outline-info:disabled,.btn-outline-info.disabled{color:#469eb9;background-color:transparent}.btn-outline-warning{color:#f9a825;border-color:#f9a825}.btn-outline-warning:hover{color:#000;background-color:#f9a825;border-color:#f9a825}.btn-check:focus+.btn-outline-warning,.btn-outline-warning:focus{box-shadow:0 0 0 0 rgba(249,168,37,0.5)}.btn-check:checked+.btn-outline-warning,.btn-check:active+.btn-outline-warning,.btn-outline-warning:active,.btn-outline-warning.active,.btn-outline-warning.dropdown-toggle.show{color:#000;background-color:#f9a825;border-color:#f9a825}.btn-check:checked+.btn-outline-warning:focus,.btn-check:active+.btn-outline-warning:focus,.btn-outline-warning:active:focus,.btn-outline-warning.active:focus,.btn-outline-warning.dropdown-toggle.show:focus{box-shadow:0 0 0 0 rgba(249,168,37,0.5)}.btn-outline-warning:disabled,.btn-outline-warning.disabled{color:#f9a825;background-color:transparent}.btn-outline-danger{color:#ff511f;border-color:#ff511f}.btn-outline-danger:hover{color:#000;background-color:#ff511f;border-color:#ff511f}.btn-check:focus+.btn-outline-danger,.btn-outline-danger:focus{box-shadow:0 0 0 0 rgba(255,81,31,0.5)}.btn-check:checked+.btn-outline-danger,.btn-check:active+.btn-outline-danger,.btn-outline-danger:active,.btn-outline-danger.active,.btn-outline-danger.dropdown-toggle.show{color:#000;background-color:#ff511f;border-color:#ff511f}.btn-check:checked+.btn-outline-danger:focus,.btn-check:active+.btn-outline-danger:focus,.btn-outline-danger:active:focus,.btn-outline-danger.active:focus,.btn-outline-danger.dropdown-toggle.show:focus{box-shadow:0 0 0 0 rgba(255,81,31,0.5)}.btn-outline-danger:disabled,.btn-outline-danger.disabled{color:#ff511f;background-color:transparent}.btn-outline-light{color:#616161;border-color:#616161}.btn-outline-light:hover{color:#fff;background-color:#616161;border-color:#616161}.btn-check:focus+.btn-outline-light,.btn-outline-light:focus{box-shadow:0 0 0 0 rgba(97,97,97,0.5)}.btn-check:checked+.btn-outline-light,.btn-check:active+.btn-outline-light,.btn-outline-light:active,.btn-outline-light.active,.btn-outline-light.dropdown-toggle.show{color:#fff;background-color:#616161;border-color:#616161}.btn-check:checked+.btn-outline-light:focus,.btn-check:active+.btn-outline-light:focus,.btn-outline-light:active:focus,.btn-outline-light.active:focus,.btn-outline-light.dropdown-toggle.show:focus{box-shadow:0 0 0 0 rgba(97,97,97,0.5)}.btn-outline-light:disabled,.btn-outline-light.disabled{color:#616161;background-color:transparent}.btn-outline-dark{color:#616161;border-color:#616161}.btn-outline-dark:hover{color:#fff;background-color:#616161;border-color:#616161}.btn-check:focus+.btn-outline-dark,.btn-outline-dark:focus{box-shadow:0 0 0 0 rgba(97,97,97,0.5)}.btn-check:checked+.btn-outline-dark,.btn-check:active+.btn-outline-dark,.btn-outline-dark:active,.btn-outline-dark.active,.btn-outline-dark.dropdown-toggle.show{color:#fff;background-color:#616161;border-color:#616161}.btn-check:checked+.btn-outline-dark:focus,.btn-check:active+.btn-outline-dark:focus,.btn-outline-dark:active:focus,.btn-outline-dark.active:focus,.btn-outline-dark.dropdown-toggle.show:focus{box-shadow:0 0 0 0 rgba(97,97,97,0.5)}.btn-outline-dark:disabled,.btn-outline-dark.disabled{color:#616161;background-color:transparent}.btn-link{font-weight:400;color:var(--t42-link-color);text-decoration:underline}.btn-link:hover{color:var(--t42-link-hover-color)}.btn-link:disabled,.btn-link.disabled{color:#6c757d}.btn-lg,.btn-group-lg>.btn{padding:0 .875rem;font-size:.75rem;border-radius:0}.btn-sm,.btn-group-sm>.btn{padding:0 .875rem;font-size:.75rem;border-radius:0}.btn-group,.btn-group-vertical{position:relative;display:inline-flex;vertical-align:middle}.btn-group>.btn,.btn-group-vertical>.btn{position:relative;flex:1 1 auto}.btn-group>.btn-check:checked+.btn,.btn-group>.btn-check:focus+.btn,.btn-group>.btn:hover,.btn-group>.btn:focus,.btn-group>.btn:active,.btn-group>.btn.active,.btn-group-vertical>.btn-check:checked+.btn,.btn-group-vertical>.btn-check:focus+.btn,.btn-group-vertical>.btn:hover,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn.active{z-index:1}.btn-toolbar{display:flex;flex-wrap:wrap;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group>.btn:not(:first-child),.btn-group>.btn-group:not(:first-child){margin-left:-1px}.btn-group>.btn:not(:last-child):not(.dropdown-toggle),.btn-group>.btn-group:not(:last-child)>.btn{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:nth-child(n+3),.btn-group>:not(.btn-check)+.btn,.btn-group>.btn-group:not(:first-child)>.btn{border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.65625rem;padding-left:.65625rem}.dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after,.dropend .dropdown-toggle-split::after{margin-left:0}.dropstart .dropdown-toggle-split::before{margin-right:0}.btn-sm+.dropdown-toggle-split,.btn-group-sm>.btn+.dropdown-toggle-split{padding-right:.65625rem;padding-left:.65625rem}.btn-lg+.dropdown-toggle-split,.btn-group-lg>.btn+.dropdown-toggle-split{padding-right:.65625rem;padding-left:.65625rem}.btn-group-vertical{flex-direction:column;align-items:flex-start;justify-content:center}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn:not(:first-child),.btn-group-vertical>.btn-group:not(:first-child){margin-top:-1px}.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle),.btn-group-vertical>.btn-group:not(:last-child)>.btn{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn ~ .btn,.btn-group-vertical>.btn-group:not(:first-child)>.btn{border-top-left-radius:0;border-top-right-radius:0}button,button:focus{outline:none}.btn{color:var(--t42-link-color);transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, border-color;cursor:default}.btn.disabled,.btn:disabled{color:var(--t42-link-color);cursor:default}.btn:not(.disabled):not(:disabled).active,.btn:not(.disabled):not(:disabled):hover{border-color:var(--t42-color-opacity-30);color:var(--white);backdrop-filter:var(--backdrop-filter)}.btn:focus,.btn:active{color:var(--white)}.btn-primary{background-color:rgba(0,123,229,0.05)}.btn-primary.disabled,.btn-primary:disabled{background-color:rgba(0,123,229,0.05)}.btn-primary:not(.disabled):not(:disabled).active,.btn-primary:not(.disabled):not(:disabled):hover{background-color:#007be5}.btn-primary:not(.disabled):not(:disabled).btn-icon.active,.btn-primary:not(.disabled):not(:disabled).btn-icon:focus,.btn-primary:not(.disabled):not(:disabled).btn-icon:hover{color:var(--white)}.btn-primary.dropdown-toggle.active,.btn-primary.dropdown-toggle:active,.btn-primary.dropdown-toggle:focus{border-color:var(--t42-color-opacity-30);background-color:#007be5}.btn-secondary{background-color:rgba(97,97,97,0.05)}.btn-secondary.disabled,.btn-secondary:disabled{background-color:rgba(97,97,97,0.05)}.btn-secondary:not(.disabled):not(:disabled).active,.btn-secondary:not(.disabled):not(:disabled):hover{background-color:#616161}.btn-secondary:not(.disabled):not(:disabled).btn-icon.active,.btn-secondary:not(.disabled):not(:disabled).btn-icon:focus,.btn-secondary:not(.disabled):not(:disabled).btn-icon:hover{color:var(--white)}.btn-secondary.dropdown-toggle.active,.btn-secondary.dropdown-toggle:active,.btn-secondary.dropdown-toggle:focus{border-color:var(--t42-color-opacity-30);background-color:#616161}.btn-success{background-color:rgba(67,160,71,0.05)}.btn-success.disabled,.btn-success:disabled{background-color:rgba(67,160,71,0.05)}.btn-success:not(.disabled):not(:disabled).active,.btn-success:not(.disabled):not(:disabled):hover{background-color:#43a047}.btn-success:not(.disabled):not(:disabled).btn-icon.active,.btn-success:not(.disabled):not(:disabled).btn-icon:focus,.btn-success:not(.disabled):not(:disabled).btn-icon:hover{color:var(--white)}.btn-success.dropdown-toggle.active,.btn-success.dropdown-toggle:active,.btn-success.dropdown-toggle:focus{border-color:var(--t42-color-opacity-30);background-color:#43a047}.btn-info{background-color:rgba(70,158,185,0.05)}.btn-info.disabled,.btn-info:disabled{background-color:rgba(70,158,185,0.05)}.btn-info:not(.disabled):not(:disabled).active,.btn-info:not(.disabled):not(:disabled):hover{background-color:#469eb9}.btn-info:not(.disabled):not(:disabled).btn-icon.active,.btn-info:not(.disabled):not(:disabled).btn-icon:focus,.btn-info:not(.disabled):not(:disabled).btn-icon:hover{color:var(--white)}.btn-info.dropdown-toggle.active,.btn-info.dropdown-toggle:active,.btn-info.dropdown-toggle:focus{border-color:var(--t42-color-opacity-30);background-color:#469eb9}.btn-warning{background-color:rgba(249,168,37,0.05)}.btn-warning.disabled,.btn-warning:disabled{background-color:rgba(249,168,37,0.05)}.btn-warning:not(.disabled):not(:disabled).active,.btn-warning:not(.disabled):not(:disabled):hover{background-color:#f9a825}.btn-warning:not(.disabled):not(:disabled).btn-icon.active,.btn-warning:not(.disabled):not(:disabled).btn-icon:focus,.btn-warning:not(.disabled):not(:disabled).btn-icon:hover{color:var(--white)}.btn-warning.dropdown-toggle.active,.btn-warning.dropdown-toggle:active,.btn-warning.dropdown-toggle:focus{border-color:var(--t42-color-opacity-30);background-color:#f9a825}.btn-danger{background-color:rgba(255,81,31,0.05)}.btn-danger.disabled,.btn-danger:disabled{background-color:rgba(255,81,31,0.05)}.btn-danger:not(.disabled):not(:disabled).active,.btn-danger:not(.disabled):not(:disabled):hover{background-color:#ff511f}.btn-danger:not(.disabled):not(:disabled).btn-icon.active,.btn-danger:not(.disabled):not(:disabled).btn-icon:focus,.btn-danger:not(.disabled):not(:disabled).btn-icon:hover{color:var(--white)}.btn-danger.dropdown-toggle.active,.btn-danger.dropdown-toggle:active,.btn-danger.dropdown-toggle:focus{border-color:var(--t42-color-opacity-30);background-color:#ff511f}.btn-light{background-color:rgba(97,97,97,0.05)}.btn-light.disabled,.btn-light:disabled{background-color:rgba(97,97,97,0.05)}.btn-light:not(.disabled):not(:disabled).active,.btn-light:not(.disabled):not(:disabled):hover{background-color:#616161}.btn-light:not(.disabled):not(:disabled).btn-icon.active,.btn-light:not(.disabled):not(:disabled).btn-icon:focus,.btn-light:not(.disabled):not(:disabled).btn-icon:hover{color:var(--white)}.btn-light.dropdown-toggle.active,.btn-light.dropdown-toggle:active,.btn-light.dropdown-toggle:focus{border-color:var(--t42-color-opacity-30);background-color:#616161}.btn-dark{background-color:rgba(97,97,97,0.05)}.btn-dark.disabled,.btn-dark:disabled{background-color:rgba(97,97,97,0.05)}.btn-dark:not(.disabled):not(:disabled).active,.btn-dark:not(.disabled):not(:disabled):hover{background-color:#616161}.btn-dark:not(.disabled):not(:disabled).btn-icon.active,.btn-dark:not(.disabled):not(:disabled).btn-icon:focus,.btn-dark:not(.disabled):not(:disabled).btn-icon:hover{color:var(--white)}.btn-dark.dropdown-toggle.active,.btn-dark.dropdown-toggle:active,.btn-dark.dropdown-toggle:focus{border-color:var(--t42-color-opacity-30);background-color:#616161}.btn-link{text-decoration:none;backdrop-filter:none}.btn-link:not(.disabled):not(:disabled).active,.btn-link:not(.disabled):not(:disabled):focus,.btn-link:not(.disabled):not(:disabled):hover{border-color:transparent;color:var(--t42-link-color);text-decoration:underline}.btn-icon:not(.disabled):not(:disabled).active,.btn-icon:not(.disabled):not(:disabled):focus,.btn-icon:not(.disabled):not(:disabled):hover{color:var(--t42-link-color)}.btn-icon-action{display:flex;justify-content:center;width:1rem;height:1rem;padding:0;border-radius:50%;font-size:0.75rem;transition:all .2s ease-in-out}@media (prefers-reduced-motion: reduce){.btn-icon-action{transition:none}}.btn-icon-action:not(.disabled):not(:disabled).active,.btn-icon-action:not(.disabled):not(:disabled):hover,.btn-icon-action:not(.disabled):not(:disabled):focus{border-color:transparent;background-color:Rgb(var(--t42-bg-light));box-shadow:var(--t42-shadow)}.btn-icon-action-right{position:absolute;right:0.25rem}.btn-icon-action-show-hover{transition:all .2s ease-in-out}@media (prefers-reduced-motion: reduce){.btn-icon-action-show-hover{transition:none}}.btn-icon-action-show-hover .btn-icon-action{opacity:0}.btn-icon-action-show-hover:not(.disabled):not(:disabled):hover .btn-icon-action{opacity:1}.btn-close{width:1rem;height:1rem;filter:var(--filter-close)}.breadcrumb{display:flex;flex-wrap:wrap;padding:0 0;margin-bottom:.5rem;list-style:none;background-color:rgba(0,0,0,0)}.breadcrumb-item+.breadcrumb-item{padding-left:.5rem}.breadcrumb-item+.breadcrumb-item::before{float:left;padding-right:.5rem;color:#6c757d;content:var(--bs-breadcrumb-divider, "/") /* rtl: var(--bs-breadcrumb-divider, "/") */}.breadcrumb-item.active{color:var(--t42-link-color)}.breadcrumb-item{font-size:83.3%}.breadcrumb-item.active{text-decoration:underline}.breadcrumb-item+.breadcrumb-item{padding-left:0}.breadcrumb-item+.breadcrumb-item::before{position:relative;top:0.063rem;left:0.063rem;width:0.75rem;height:0.75rem;background-color:var(--t42-content-color);content:"";-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M339.2,256.3c0,2.4-0.9,4.4-2.6,6.1L203,396c-1.7,1.7-3.8,2.6-6.1,2.6c-2.4,0-4.6-0.9-6.7-2.6l-14.3-14.3 c-2-2-3.1-4.3-3.1-6.7s1-4.6,3.1-6.7L288,256.3L175.9,143.6c-2-1.7-3.1-3.8-3.1-6.1s1-4.6,3.1-6.7l14.3-14.3c1.7-2,3.9-3.1,6.7-3.1 s4.8,1,6.1,3.1l133.6,133.1C338.3,251.3,339.2,253.5,339.2,256.3L339.2,256.3z%27/%3E%3C/svg%3E")}mark,.mark{color:var(--white)}pre{background-color:var(--t42-bg-dark)}blockquote,.blockquote{padding:1rem 1rem 0.01rem;border-left:0.25rem solid var(--secondary);background-color:Rgb(var(--t42-bg-dark))}.blockquote-footer{margin-top:-2rem;margin-left:1.25rem;color:var(--t42-content-color-muted);font-size:0.875em}pre{border:0.0625rem solid var(--t42-color-opacity-10)}.card{position:relative;display:flex;flex-direction:column;min-width:0;word-wrap:break-word;background-color:Rgba(var(--t42-bg-light), 0.75);background-clip:border-box;border:1px solid var(--t42-color-opacity-10);border-radius:0}.card>hr{margin-right:0;margin-left:0}.card>.list-group{border-top:inherit;border-bottom:inherit}.card>.list-group:first-child{border-top-width:0;border-top-left-radius:0;border-top-right-radius:0}.card>.list-group:last-child{border-bottom-width:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.card>.card-header+.list-group,.card>.list-group+.card-footer{border-top:0}.card-body{flex:1 1 auto;padding:1.25rem 1.25rem}.card-title{margin-bottom:.5rem}.card-subtitle{margin-top:-.25rem;margin-bottom:0}.card-text:last-child{margin-bottom:0}.card-link+.card-link{margin-left:1.25rem}.card-header{padding:.625rem 1.25rem;margin-bottom:0;color:var(--t42-link-color);background-color:rgba(0,0,0,0);border-bottom:1px solid var(--t42-color-opacity-10)}.card-header:first-child{border-radius:0 0 0 0}.card-footer{padding:.625rem 1.25rem;color:var(--t42-link-color);background-color:rgba(0,0,0,0);border-top:1px solid var(--t42-color-opacity-10)}.card-footer:last-child{border-radius:0 0 0 0}.card-header-tabs{margin-right:-.625rem;margin-bottom:-.625rem;margin-left:-.625rem;border-bottom:0}.card-header-tabs .nav-link.active{background-color:Rgba(var(--t42-bg-light), 0.75);border-bottom-color:Rgba(var(--t42-bg-light), 0.75)}.card-header-pills{margin-right:-.625rem;margin-left:-.625rem}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1rem;border-radius:0}.card-img,.card-img-top,.card-img-bottom{width:100%}.card-img,.card-img-top{border-top-left-radius:0;border-top-right-radius:0}.card-img,.card-img-bottom{border-bottom-right-radius:0;border-bottom-left-radius:0}.card-group>.card{margin-bottom:.75rem}@media (min-width: 576px){.card-group{display:flex;flex-flow:row wrap}.card-group>.card{flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:not(:last-child) .card-img-top,.card-group>.card:not(:last-child) .card-header{border-top-right-radius:0}.card-group>.card:not(:last-child) .card-img-bottom,.card-group>.card:not(:last-child) .card-footer{border-bottom-right-radius:0}.card-group>.card:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:not(:first-child) .card-img-top,.card-group>.card:not(:first-child) .card-header{border-top-left-radius:0}.card-group>.card:not(:first-child) .card-img-bottom,.card-group>.card:not(:first-child) .card-footer{border-bottom-left-radius:0}}.card{box-shadow:var(--t42-shadow);backdrop-filter:var(--backdrop-filter)}.card .card-header{border-bottom-width:0}.card .card-subtitle{margin-bottom:0.5rem;font-size:83.3%}.card.bg-primary{background-color:transparent !important}.card.bg-primary .card-header{background-color:Rgba(var(--t42-bg-mid), 0.75)}.card.bg-primary .card-body{background-color:Rgba(var(--t42-bg-light), 0.75)}.card.bg-secondary{background-color:transparent !important}.card.bg-secondary .card-header{background-color:Rgba(var(--t42-bg-light), 0.75)}.card.bg-secondary .card-body{background-color:Rgba(var(--t42-bg-mid), 0.75)}.card:not(.bg-primary):not(.bg-secondary) .card-header+.card-body{padding-top:0}.card-header-tabs{margin-bottom:0}.accordion .card:first-of-type,.accordion .card:not(:first-of-type):not(:last-of-type){margin-bottom:0.5rem;border-bottom:var(--t42-border)}.accordion .card-header{position:relative;padding:0}.accordion .card-header .btn-link{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;width:100%;padding:0.75rem 2rem;line-height:1.4;text-align:left}.accordion .card-header .btn-link::before{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:transform;position:absolute;display:inline-block;width:0.75rem;height:0.75rem;background-color:var(--t42-content-color);transform:translateX(-1rem) translateY(0.063rem) rotate(-90deg);content:"";-webkit-mask-image:var(--t42-select-indicator)}.accordion .card-header .btn-link:hover{backdrop-filter:none}.accordion .card-header .btn-link.collapsed::before{transform:translateX(-1rem) translateY(0.063rem)}.accordion .card-header .btn-link.disabled::before,.accordion .card-header .btn-link:disabled::before{opacity:.35}.accordion .card-body{padding:0 1.25rem 1.25rem}.accordion .bg-primary .card-body,.accordion .bg-secondary .card-body{padding:1.25rem}.dropup,.dropend,.dropdown,.dropstart{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:0;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{position:absolute;z-index:1000;display:none;min-width:10rem;padding:0 0;margin:0;font-size:.75rem;color:var(--t42-content-color);text-align:left;list-style:none;background-color:Rgba(var(--t42-bg-light), 0.75);background-clip:padding-box;border:1px solid var(--t42-color-opacity-10);border-radius:0}.dropdown-menu[data-bs-popper]{top:100%;left:0;margin-top:.125rem}.dropdown-menu-start{--bs-position: start}.dropdown-menu-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-end{--bs-position: end}.dropdown-menu-end[data-bs-popper]{right:0;left:auto}@media (min-width: 576px){.dropdown-menu-sm-start{--bs-position: start}.dropdown-menu-sm-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-sm-end{--bs-position: end}.dropdown-menu-sm-end[data-bs-popper]{right:0;left:auto}}@media (min-width: 768px){.dropdown-menu-md-start{--bs-position: start}.dropdown-menu-md-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-md-end{--bs-position: end}.dropdown-menu-md-end[data-bs-popper]{right:0;left:auto}}@media (min-width: 992px){.dropdown-menu-lg-start{--bs-position: start}.dropdown-menu-lg-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-lg-end{--bs-position: end}.dropdown-menu-lg-end[data-bs-popper]{right:0;left:auto}}@media (min-width: 1200px){.dropdown-menu-xl-start{--bs-position: start}.dropdown-menu-xl-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-xl-end{--bs-position: end}.dropdown-menu-xl-end[data-bs-popper]{right:0;left:auto}}@media (min-width: 1400px){.dropdown-menu-xxl-start{--bs-position: start}.dropdown-menu-xxl-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-xxl-end{--bs-position: end}.dropdown-menu-xxl-end[data-bs-popper]{right:0;left:auto}}.dropup .dropdown-menu[data-bs-popper]{top:auto;bottom:100%;margin-top:0;margin-bottom:.125rem}.dropup .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:0;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropend .dropdown-menu[data-bs-popper]{top:0;right:auto;left:100%;margin-top:0;margin-left:.125rem}.dropend .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:0;content:"";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid}.dropend .dropdown-toggle:empty::after{margin-left:0}.dropend .dropdown-toggle::after{vertical-align:0}.dropstart .dropdown-menu[data-bs-popper]{top:0;right:100%;left:auto;margin-top:0;margin-right:.125rem}.dropstart .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:0;content:""}.dropstart .dropdown-toggle::after{display:none}.dropstart .dropdown-toggle::before{display:inline-block;margin-right:.255em;vertical-align:0;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropstart .dropdown-toggle:empty::after{margin-left:0}.dropstart .dropdown-toggle::before{vertical-align:0}.dropdown-divider{height:0;margin:0 0;overflow:hidden;border-top:1px solid var(--t42-color-opacity-10)}.dropdown-item{display:block;width:100%;padding:.375rem 1rem;clear:both;font-weight:400;color:var(--t42-content-color);text-align:inherit;text-decoration:none;white-space:nowrap;background-color:transparent;border:0}.dropdown-item:first-child{border-top-left-radius:0;border-top-right-radius:0}.dropdown-item:last-child{border-bottom-right-radius:0;border-bottom-left-radius:0}.dropdown-item:hover,.dropdown-item:focus{color:var(--t42-link-hover-color);background-color:var(--t42-link-hover-bg)}.dropdown-item.active,.dropdown-item:active{color:var(--t42-link-hover-color);text-decoration:none;background-color:var(--t42-link-active-bg)}.dropdown-item.disabled,.dropdown-item:disabled{color:#adb5bd;pointer-events:none;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:0 1rem;margin-bottom:0;font-size:.65625rem;color:shade-color(#616161, 10%);white-space:nowrap}.dropdown-item-text{display:block;padding:.375rem 1rem;color:var(--t42-content-color)}.dropdown-menu-dark{color:#dee2e6;background-color:#343a40;border-color:var(--t42-color-opacity-10)}.dropdown-menu-dark .dropdown-item{color:#dee2e6}.dropdown-menu-dark .dropdown-item:hover,.dropdown-menu-dark .dropdown-item:focus{color:#fff;background-color:rgba(255,255,255,0.15)}.dropdown-menu-dark .dropdown-item.active,.dropdown-menu-dark .dropdown-item:active{color:var(--t42-link-hover-color);background-color:var(--t42-link-active-bg)}.dropdown-menu-dark .dropdown-item.disabled,.dropdown-menu-dark .dropdown-item:disabled{color:#adb5bd}.dropdown-menu-dark .dropdown-divider{border-color:var(--t42-color-opacity-10)}.dropdown-menu-dark .dropdown-item-text{color:#dee2e6}.dropdown-menu-dark .dropdown-header{color:#adb5bd}.dropdown-menu{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:opacity, visability;display:block;visibility:hidden;opacity:0;backdrop-filter:var(--backdrop-filter)}.dropdown-menu.show{visibility:visible;opacity:1}.dropdown-toggle::after{position:relative;width:0.5rem;height:0.5rem;border:0;background-color:var(--t42-link-color);content:"";-webkit-mask-image:url("data:image/svg+xml,%3Csvg version=%271.1%27 xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M480.768 186.88l-211.968 211.456q-5.12 5.632-12.8 5.632t-12.8-5.632l-211.968-211.456q-5.632-5.632-5.632-13.312t5.632-12.8l47.616-47.104q5.12-5.632 12.8-5.632t12.8 5.632l151.552 151.552 151.552-151.552q5.632-5.632 12.8-5.632t13.312 5.632l47.104 47.104q5.632 5.632 5.632 12.8t-5.632 13.312z%27%3E%3C/path%3E%3C/svg%3E")}.dropdown-toggle.show::after{color:var(--white)}.dropup .dropdown-toggle::after{position:relative;top:0.188rem;width:0.5rem;height:0.5rem;border:0;background-color:var(--t42-link-color);content:"";-webkit-mask-image:url("data:image/svg+xml,%3Csvg version=%271.1%27 xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M480.768 351.488l-47.104 47.104q-5.632 5.12-13.312 5.12t-12.8-5.12l-151.552-152.064-151.552 152.064q-5.632 5.12-12.8 5.12t-12.8-5.12l-47.616-47.104q-5.632-5.632-5.632-13.312t5.632-12.8l211.968-211.968q5.632-5.12 12.8-5.12t12.8 5.12l211.968 211.968q5.632 5.632 5.632 12.8t-5.632 13.312z%27%3E%3C/path%3E%3C/svg%3E%0A")}.form-label{margin-bottom:.5rem}.col-form-label{padding-top:1px;padding-bottom:1px;margin-bottom:0;font-size:inherit;line-height:1.875rem}.col-form-label-lg{padding-top:1px;padding-bottom:1px;font-size:.75rem}.col-form-label-sm{padding-top:1px;padding-bottom:1px;font-size:.75rem}.form-text{margin-top:.25rem;font-size:.875em;color:var(--t42-content-color-muted)}.form-control{display:block;width:100%;padding:0 .875rem;font-size:.75rem;font-weight:400;line-height:1.875rem;color:var(--t42-link-color);background-color:var(--t42-input-bg);background-clip:padding-box;border:1px solid var(--t42-color-opacity-10);appearance:none;border-radius:0;transition:border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.form-control{transition:none}}.form-control[type="file"]{overflow:hidden}.form-control[type="file"]:not(:disabled):not([readonly]){cursor:pointer}.form-control:focus{color:var(--t42-link-color);background-color:var(--t42-input-bg);border-color:#007be5;outline:0;box-shadow:0 0 0 0 rgba(0,123,229,0.25)}.form-control::-webkit-date-and-time-value{height:1.875rem}.form-control::placeholder{color:var(--t42-content-color-muted);opacity:1}.form-control:disabled,.form-control[readonly]{background-color:var(--t42-input-disabled-bg);opacity:1}.form-control::file-selector-button{padding:0 .875rem;margin:0 -.875rem;margin-inline-end:.875rem;color:var(--t42-link-color);background-color:#e9ecef;pointer-events:none;border-color:inherit;border-style:solid;border-width:0;border-inline-end-width:1px;border-radius:0;transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.form-control::file-selector-button{transition:none}}.form-control:hover:not(:disabled):not([readonly])::file-selector-button{background-color:#dde0e3}.form-control::-webkit-file-upload-button{padding:0 .875rem;margin:0 -.875rem;margin-inline-end:.875rem;color:var(--t42-link-color);background-color:#e9ecef;pointer-events:none;border-color:inherit;border-style:solid;border-width:0;border-inline-end-width:1px;border-radius:0;transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.form-control::-webkit-file-upload-button{transition:none}}.form-control:hover:not(:disabled):not([readonly])::-webkit-file-upload-button{background-color:#dde0e3}.form-control-plaintext{display:block;width:100%;padding:0 0;margin-bottom:0;line-height:1.875rem;color:var(--t42-content-color);background-color:transparent;border:solid transparent;border-width:1px 0}.form-control-plaintext.form-control-sm,.form-control-plaintext.form-control-lg{padding-right:0;padding-left:0}.form-control-sm{min-height:2rem;padding:0 .875rem;font-size:.75rem;border-radius:0}.form-control-sm::file-selector-button{padding:0 .875rem;margin:0 -.875rem;margin-inline-end:.875rem}.form-control-sm::-webkit-file-upload-button{padding:0 .875rem;margin:0 -.875rem;margin-inline-end:.875rem}.form-control-lg{min-height:2rem;padding:0 .875rem;font-size:.75rem;border-radius:0}.form-control-lg::file-selector-button{padding:0 .875rem;margin:0 -.875rem;margin-inline-end:.875rem}.form-control-lg::-webkit-file-upload-button{padding:0 .875rem;margin:0 -.875rem;margin-inline-end:.875rem}textarea.form-control{min-height:2rem}textarea.form-control-sm{min-height:2rem}textarea.form-control-lg{min-height:2rem}.form-control-color{width:3rem;height:auto;padding:0}.form-control-color:not(:disabled):not([readonly]){cursor:pointer}.form-control-color::-moz-color-swatch{height:1.875rem;border-radius:0}.form-control-color::-webkit-color-swatch{height:1.875rem;border-radius:0}.form-select{display:block;width:100%;padding:0 2.625rem 0 .875rem;-moz-padding-start:calc(.875rem - 3px);font-size:.75rem;font-weight:400;line-height:1.875rem;color:var(--t42-link-color);background-color:var(--t42-input-bg);background-image:var(--t42-select-indicator);background-repeat:no-repeat;background-position:right 0.5rem center;background-size:1rem;border:1px solid var(--t42-color-opacity-10);border-radius:0;transition:border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out;appearance:none}@media (prefers-reduced-motion: reduce){.form-select{transition:none}}.form-select:focus{border-color:#007be5;outline:0;box-shadow:0 0 0 0 rgba(0,123,229,0.25)}.form-select[multiple],.form-select[size]:not([size="1"]){padding-right:.875rem;background-image:none}.form-select:disabled{background-color:#e9ecef}.form-select:-moz-focusring{color:transparent;text-shadow:0 0 0 var(--t42-link-color)}.form-select-sm{padding-top:0;padding-bottom:0;padding-left:.875rem;font-size:.75rem;border-radius:0}.form-select-lg{padding-top:0;padding-bottom:0;padding-left:.875rem;font-size:.75rem;border-radius:0}.form-check{display:block;min-height:1.125rem;padding-left:1.25rem;margin-bottom:0}.form-check .form-check-input{float:left;margin-left:-1.25rem}.form-check-input{width:1em;height:1em;margin-top:.25em;vertical-align:top;background-color:var(--t42-input-bg);background-repeat:no-repeat;background-position:center;background-size:contain;border:1px solid rgba(0,0,0,0.25);appearance:none;color-adjust:exact}.form-check-input[type="checkbox"]{border-radius:.25em}.form-check-input[type="radio"]{border-radius:50%}.form-check-input:active{filter:brightness(90%)}.form-check-input:focus{border-color:#007be5;outline:0;box-shadow:0 0 0 0 rgba(0,123,229,0.25)}.form-check-input:checked{background-color:#007be5;border-color:#007be5}.form-check-input:checked[type="checkbox"]{background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 20 20%27%3e%3cpath fill=%27none%27 stroke=%27%23fff%27 stroke-linecap=%27round%27 stroke-linejoin=%27round%27 stroke-width=%273%27 d=%27M6 10l3 3l6-6%27/%3e%3c/svg%3e")}.form-check-input:checked[type="radio"]{background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%27-4 -4 8 8%27%3e%3ccircle r=%272%27 fill=%27%23fff%27/%3e%3c/svg%3e")}.form-check-input[type="checkbox"]:indeterminate{background-color:#007be5;border-color:#007be5;background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 20 20%27%3e%3cpath fill=%27none%27 stroke=%27%23fff%27 stroke-linecap=%27round%27 stroke-linejoin=%27round%27 stroke-width=%273%27 d=%27M6 10h8%27/%3e%3c/svg%3e")}.form-check-input:disabled{pointer-events:none;filter:none;opacity:.5}.form-check-input[disabled] ~ .form-check-label,.form-check-input:disabled ~ .form-check-label{opacity:.5}.form-switch{padding-left:2.5em}.form-switch .form-check-input{width:2em;margin-left:-2.5em;background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%27-4 -4 8 8%27%3e%3ccircle r=%273%27 fill=%27rgba%280,0,0,0.25%29%27/%3e%3c/svg%3e");background-position:left center;border-radius:2em;transition:background-position 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.form-switch .form-check-input{transition:none}}.form-switch .form-check-input:focus{background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%27-4 -4 8 8%27%3e%3ccircle r=%273%27 fill=%27%23007be5%27/%3e%3c/svg%3e")}.form-switch .form-check-input:checked{background-position:right center;background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%27-4 -4 8 8%27%3e%3ccircle r=%273%27 fill=%27%23fff%27/%3e%3c/svg%3e")}.form-check-inline{display:inline-block;margin-right:1rem}.btn-check{position:absolute;clip:rect(0, 0, 0, 0);pointer-events:none}.btn-check[disabled]+.btn,.btn-check:disabled+.btn{pointer-events:none;filter:none;opacity:.35}.form-range{width:100%;height:1rem;padding:0;background-color:transparent;appearance:none}.form-range:focus{outline:0}.form-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 0 rgba(0,123,229,0.25)}.form-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 0 rgba(0,123,229,0.25)}.form-range::-moz-focus-outer{border:0}.form-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-.25rem;background-color:#007be5;border:0;border-radius:1rem;transition:background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out;appearance:none}@media (prefers-reduced-motion: reduce){.form-range::-webkit-slider-thumb{transition:none}}.form-range::-webkit-slider-thumb:active{background-color:#b3d7f7}.form-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.form-range::-moz-range-thumb{width:1rem;height:1rem;background-color:#007be5;border:0;border-radius:1rem;transition:background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out;appearance:none}@media (prefers-reduced-motion: reduce){.form-range::-moz-range-thumb{transition:none}}.form-range::-moz-range-thumb:active{background-color:#b3d7f7}.form-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.form-range:disabled{pointer-events:none}.form-range:disabled::-webkit-slider-thumb{background-color:#adb5bd}.form-range:disabled::-moz-range-thumb{background-color:#adb5bd}.form-floating{position:relative}.form-floating>.form-control,.form-floating>.form-select{height:calc(3.5rem + 2px);line-height:1.25}.form-floating>label{position:absolute;top:0;left:0;height:100%;padding:1rem .875rem;pointer-events:none;border:1px solid transparent;transform-origin:0 0;transition:opacity 0.1s ease-in-out,transform 0.1s ease-in-out}@media (prefers-reduced-motion: reduce){.form-floating>label{transition:none}}.form-floating>.form-control{padding:1rem .875rem}.form-floating>.form-control::placeholder{color:transparent}.form-floating>.form-control:focus,.form-floating>.form-control:not(:placeholder-shown){padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control:-webkit-autofill{padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-select{padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control:focus ~ label,.form-floating>.form-control:not(:placeholder-shown) ~ label,.form-floating>.form-select ~ label{opacity:.65;transform:scale(0.85) translateY(-0.5rem) translateX(0.15rem)}.form-floating>.form-control:-webkit-autofill ~ label{opacity:.65;transform:scale(0.85) translateY(-0.5rem) translateX(0.15rem)}.input-group{position:relative;display:flex;flex-wrap:wrap;align-items:stretch;width:100%}.input-group>.form-control,.input-group>.form-select{position:relative;flex:1 1 auto;width:1%;min-width:0}.input-group>.form-control:focus,.input-group>.form-select:focus{z-index:3}.input-group .btn{position:relative;z-index:2}.input-group .btn:focus{z-index:3}.input-group-text{display:flex;align-items:center;padding:0 .875rem;font-size:.75rem;font-weight:400;line-height:1.875rem;color:var(--t42-content-color);text-align:center;white-space:nowrap;background-color:#e9ecef;border:1px solid var(--t42-color-opacity-10);border-radius:0}.input-group-lg>.form-control,.input-group-lg>.form-select,.input-group-lg>.input-group-text,.input-group-lg>.btn{padding:0 .875rem;font-size:.75rem;border-radius:0}.input-group-sm>.form-control,.input-group-sm>.form-select,.input-group-sm>.input-group-text,.input-group-sm>.btn{padding:0 .875rem;font-size:.75rem;border-radius:0}.input-group-lg>.form-select,.input-group-sm>.form-select{padding-right:3.5rem}.input-group:not(.has-validation)>:not(:last-child):not(.dropdown-toggle):not(.dropdown-menu),.input-group:not(.has-validation)>.dropdown-toggle:nth-last-child(n+3){border-top-right-radius:0;border-bottom-right-radius:0}.input-group.has-validation>:nth-last-child(n+3):not(.dropdown-toggle):not(.dropdown-menu),.input-group.has-validation>.dropdown-toggle:nth-last-child(n+4){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>:not(:first-child):not(.dropdown-menu):not(.valid-tooltip):not(.valid-feedback):not(.invalid-tooltip):not(.invalid-feedback){margin-left:-1px;border-top-left-radius:0;border-bottom-left-radius:0}.valid-feedback{display:none;width:100%;margin-top:.5rem;font-size:.7rem;color:#43a047}.valid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem 1rem;margin-top:.1rem;font-size:.65625rem;color:#000;background-color:#43a047;border-radius:0}.was-validated :valid ~ .valid-feedback,.was-validated :valid ~ .valid-tooltip,.is-valid ~ .valid-feedback,.is-valid ~ .valid-tooltip{display:block}.was-validated .form-control:valid,.form-control.is-valid{border-color:#43a047;padding-right:2rem;background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 8 8%27%3e%3cpath fill=%27%2343a047%27 d=%27M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z%27/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right .5rem center;background-size:1rem 1rem}.was-validated .form-control:valid:focus,.form-control.is-valid:focus{border-color:#43a047;box-shadow:0 0 0 0 rgba(67,160,71,0.25)}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{padding-right:2rem;background-position:top .5rem right .5rem}.was-validated .form-select:valid,.form-select.is-valid{border-color:#43a047}.was-validated .form-select:valid:not([multiple]):not([size]),.was-validated .form-select:valid:not([multiple])[size="1"],.form-select.is-valid:not([multiple]):not([size]),.form-select.is-valid:not([multiple])[size="1"]{padding-right:3.5rem;background-image:var(--t42-select-indicator),url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 8 8%27%3e%3cpath fill=%27%2343a047%27 d=%27M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z%27/%3e%3c/svg%3e");background-position:right 0.5rem center,right 1.75rem center;background-size:1rem,1rem}.was-validated .form-select:valid:focus,.form-select.is-valid:focus{border-color:#43a047;box-shadow:0 0 0 0 rgba(67,160,71,0.25)}.was-validated .form-check-input:valid,.form-check-input.is-valid{border-color:#43a047}.was-validated .form-check-input:valid:checked,.form-check-input.is-valid:checked{background-color:#43a047}.was-validated .form-check-input:valid:focus,.form-check-input.is-valid:focus{box-shadow:0 0 0 0 rgba(67,160,71,0.25)}.was-validated .form-check-input:valid ~ .form-check-label,.form-check-input.is-valid ~ .form-check-label{color:#43a047}.form-check-inline .form-check-input ~ .valid-feedback{margin-left:.5em}.was-validated .input-group .form-control:valid,.input-group .form-control.is-valid,.was-validated .input-group .form-select:valid,.input-group .form-select.is-valid{z-index:1}.was-validated .input-group .form-control:valid:focus,.input-group .form-control.is-valid:focus,.was-validated .input-group .form-select:valid:focus,.input-group .form-select.is-valid:focus{z-index:3}.invalid-feedback{display:none;width:100%;margin-top:.5rem;font-size:.7rem;color:#ff511f}.invalid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem 1rem;margin-top:.1rem;font-size:.65625rem;color:#000;background-color:#ff511f;border-radius:0}.was-validated :invalid ~ .invalid-feedback,.was-validated :invalid ~ .invalid-tooltip,.is-invalid ~ .invalid-feedback,.is-invalid ~ .invalid-tooltip{display:block}.was-validated .form-control:invalid,.form-control.is-invalid{border-color:#ff511f;padding-right:2rem;background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 12 12%27 width=%2712%27 height=%2712%27 fill=%27none%27 stroke=%27%23ff511f%27%3e%3ccircle cx=%276%27 cy=%276%27 r=%274.5%27/%3e%3cpath stroke-linejoin=%27round%27 d=%27M5.8 3.6h.4L6 6.5z%27/%3e%3ccircle cx=%276%27 cy=%278.2%27 r=%27.6%27 fill=%27%23ff511f%27 stroke=%27none%27/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right .5rem center;background-size:1rem 1rem}.was-validated .form-control:invalid:focus,.form-control.is-invalid:focus{border-color:#ff511f;box-shadow:0 0 0 0 rgba(255,81,31,0.25)}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{padding-right:2rem;background-position:top .5rem right .5rem}.was-validated .form-select:invalid,.form-select.is-invalid{border-color:#ff511f}.was-validated .form-select:invalid:not([multiple]):not([size]),.was-validated .form-select:invalid:not([multiple])[size="1"],.form-select.is-invalid:not([multiple]):not([size]),.form-select.is-invalid:not([multiple])[size="1"]{padding-right:3.5rem;background-image:var(--t42-select-indicator),url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 12 12%27 width=%2712%27 height=%2712%27 fill=%27none%27 stroke=%27%23ff511f%27%3e%3ccircle cx=%276%27 cy=%276%27 r=%274.5%27/%3e%3cpath stroke-linejoin=%27round%27 d=%27M5.8 3.6h.4L6 6.5z%27/%3e%3ccircle cx=%276%27 cy=%278.2%27 r=%27.6%27 fill=%27%23ff511f%27 stroke=%27none%27/%3e%3c/svg%3e");background-position:right 0.5rem center,right 1.75rem center;background-size:1rem,1rem}.was-validated .form-select:invalid:focus,.form-select.is-invalid:focus{border-color:#ff511f;box-shadow:0 0 0 0 rgba(255,81,31,0.25)}.was-validated .form-check-input:invalid,.form-check-input.is-invalid{border-color:#ff511f}.was-validated .form-check-input:invalid:checked,.form-check-input.is-invalid:checked{background-color:#ff511f}.was-validated .form-check-input:invalid:focus,.form-check-input.is-invalid:focus{box-shadow:0 0 0 0 rgba(255,81,31,0.25)}.was-validated .form-check-input:invalid ~ .form-check-label,.form-check-input.is-invalid ~ .form-check-label{color:#ff511f}.form-check-inline .form-check-input ~ .invalid-feedback{margin-left:.5em}.was-validated .input-group .form-control:invalid,.input-group .form-control.is-invalid,.was-validated .input-group .form-select:invalid,.input-group .form-select.is-invalid{z-index:2}.was-validated .input-group .form-control:invalid:focus,.input-group .form-control.is-invalid:focus,.was-validated .input-group .form-select:invalid:focus,.input-group .form-select.is-invalid:focus{z-index:3}input{background-color:var(--t42-input-bg)}input[type="number"]::-webkit-calendar-picker-indicator,input[type="datetime-local"]::-webkit-calendar-picker-indicator,input[type="month"]::-webkit-calendar-picker-indicator,input[type="week"]::-webkit-calendar-picker-indicator,input[type="time"]::-webkit-calendar-picker-indicator,input[type="date"]::-webkit-calendar-picker-indicator{background:transparent}input[type="number"]::-webkit-inner-spin-button,input[type="datetime-local"]::-webkit-inner-spin-button,input[type="month"]::-webkit-inner-spin-button,input[type="week"]::-webkit-inner-spin-button,input[type="time"]::-webkit-inner-spin-button,input[type="date"]::-webkit-inner-spin-button{appearance:none}input[type="color"],input[type="range"]{padding:0;border:0}form div[class^="col"]{position:relative}.form-check-label input[type="checkbox"],.form-check-label input[type="radio"]{margin-top:0.125rem;margin-left:-1.2rem;opacity:1}.form-check .form-check-input:disabled{opacity:0}.form-check-label{margin-bottom:0}.form-check-inline .form-check-label{padding-left:0.25rem}.form-check-inline input[type="radio"]:checked+label::after{left:-1rem}.form-control{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border;background-color:transparent}.form-control:disabled,.form-control.disabled,.form-control[readonly]{cursor:default;opacity:0.65}.form-control.is-valid,.form-control.is-invalid{border-color:var(--t42-color-opacity-10)}.form-control.is-valid:focus,.form-control.is-invalid:focus{border-color:var(--primary);box-shadow:none}.form-control[type="file"]{opacity:0}.form-text{color:var(--secondary)}.form-control-plaintext:focus{outline:0}select{background-image:var(--t42-select-indicator);background-repeat:no-repeat;background-position:right 0.5rem center;background-size:1rem;cursor:pointer;appearance:none}select[multiple]{padding:0;background-image:none}select[multiple] option{padding:0 0.875rem}select[multiple] option:checked{background-color:var(--primary)}select:disabled{border-color:transparent;cursor:default;opacity:0.65}textarea,textarea.form-control{min-height:90px;max-height:180px;padding-top:5px;padding-bottom:5px}textarea:disabled,textarea.form-control:disabled{border-color:transparent}input[type="range"]{width:100%;appearance:none}input[type="range"]:focus{background-color:transparent;outline:none}input[type="range"]:focus::-ms-fill-lower,input[type="range"]:focus::-ms-fill-upper{background:var(--primary)}input[type="range"]::-webkit-slider-runnable-track{width:100%;height:0.0625rem;border:0;border-radius:0;background:var(--t42-color-opacity-10);box-shadow:none;cursor:pointer}input[type="range"]::-webkit-slider-thumb{width:12px;height:12px;margin-top:-5px;border:0;border-radius:50%;background:var(--primary);box-shadow:none;cursor:pointer;appearance:none}input[type="range"]:focus::-webkit-slider-runnable-track{background:var(--t42-color-opacity-10)}input[type="range"]::-moz-range-track{width:100%;height:2px;border:0;border-radius:0;background:var(--t42-color-opacity-10);box-shadow:none;cursor:pointer}input[type="range"]::-moz-range-thumb{width:12px;height:12px;border:0;border-radius:50px;background:var(--primary);box-shadow:none;cursor:pointer}input[type="range"]::-ms-track{width:100%;height:2px;border-color:transparent;color:transparent;background:transparent;cursor:pointer}input[type="range"]::-ms-fill-lower,input[type="range"]::-ms-fill-upper{border:0;border-radius:0;background:var(--primary);box-shadow:none}input[type="range"]::-ms-thumb{width:12px;height:12px;border:0;border-radius:50px;background:var(--primary);box-shadow:none;cursor:pointer}input[type="checkbox"]{opacity:0}input[type="checkbox"]+label{position:relative;color:var(--t42-content-color-muted);cursor:pointer;user-select:none}input[type="checkbox"]+label::before{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, border-color;position:absolute;top:0.0625rem;left:-1.25rem;display:block;width:0.875rem;height:0.875rem;border:0.0625rem solid var(--t42-content-color-muted);border-radius:0;cursor:pointer;content:"";pointer-events:all}input[type="checkbox"]+label::after{position:absolute;top:0.125rem;left:-1.188rem;display:block;width:0.875rem;height:0.875rem;background-image:none;content:"";-webkit-mask-size:0.75rem;-webkit-mask-repeat:no-repeat;content:""}input[type="checkbox"].indeterminate+label::before,input[type="checkbox"]:indeterminate+label::before{border-color:var(--t42-color-opacity-30);background-color:var(--primary)}input[type="checkbox"].indeterminate+label::after,input[type="checkbox"]:indeterminate+label::after{top:0.375rem;left:-1.063rem;width:0.5rem;height:0.188rem;background-color:var(--white)}input[type="checkbox"]:disabled+label,input[type="checkbox"]:disabled+.form-check-label{color:var(--t42-content-color-disabled)}input[type="checkbox"]:checked.disabled+label,input[type="checkbox"]:checked:disabled+label,input[type="checkbox"]:indeterminate.disabled+label,input[type="checkbox"]:indeterminate:disabled+label,input[type="checkbox"].disabled+label,input[type="checkbox"]:disabled+label{color:var(--t42-content-color-disabled)}input[type="checkbox"]:checked.disabled+label::before,input[type="checkbox"]:checked:disabled+label::before,input[type="checkbox"]:indeterminate.disabled+label::before,input[type="checkbox"]:indeterminate:disabled+label::before,input[type="checkbox"].disabled+label::before,input[type="checkbox"]:disabled+label::before{border-color:transparent;background-color:var(--t42-color-opacity-10)}input[type="checkbox"]:checked+label::before{border-color:var(--t42-color-opacity-30);background-color:var(--primary)}input[type="checkbox"]:checked+label::after{background-color:var(--t42-link-color);-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M212.48599,435.14899c-11.60532,0.00003-21.16266-4.77866-28.672-14.336l-92.16-120.832 c-5.46133-8.19202-7.50933-17.06665-6.144-26.62399s5.80267-17.408,13.312-23.552s16.21333-8.53334,26.112-7.168 c9.89867,1.36533,17.92,6.14401,24.064,14.336l60.416,78.84799L360.966,93.13298c5.46133-8.192,12.79999-13.312,22.01599-15.36 s18.26132-0.68267,27.13599,4.096c8.19199,5.46133,13.31198,12.8,15.35999,22.016s0.68265,18.26133-4.09601,27.136l-179.2,286.71997 c-6.82668,10.9227-16.384,16.384-28.672,16.384L212.48599,435.14899z%27/%3E%3C/svg%3E")}input[type="radio"]{opacity:0}input[type="radio"]+label{position:relative;color:var(--t42-content-color-muted);cursor:pointer;user-select:none}input[type="radio"]+label::before{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, border;position:absolute;top:0.0625rem;left:-1.25rem;display:block;width:0.875rem;height:0.875rem;border:0.0625rem solid var(--t42-content-color-muted);border-radius:50%;cursor:pointer;content:"";pointer-events:all}input[type="radio"]+label::after{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, border;position:absolute;top:0.313rem;left:-1rem;display:block;width:0.375rem;height:0.375rem;border-radius:50%;color:var(--white);background-image:none;transform:scale(0);opacity:0;content:""}input[type="radio"]+label:focus{border-color:var(--primary)}input[type="radio"]:disabled+label,input[type="radio"]:disabled+.form-check-label{color:var(--t42-content-color-disabled)}input[type="radio"]:checked.disabled+label,input[type="radio"]:checked:disabled+label,input[type="radio"].disabled+label,input[type="radio"]:disabled+label{color:var(--t42-content-color-disabled)}input[type="radio"]:checked.disabled+label::before,input[type="radio"]:checked:disabled+label::before,input[type="radio"].disabled+label::before,input[type="radio"]:disabled+label::before{border-color:transparent;background-color:var(--t42-color-opacity-10)}input[type="radio"]:checked+label::before{border-color:var(--t42-color-opacity-30);background-color:var(--primary)}input[type="radio"]:checked+label::after{background-color:var(--white);transform:scale(1);opacity:1}.custom-control{padding-left:1.25rem}.custom-control .custom-control-input:checked ~ .custom-control-label::before{border-color:var(--t42-color-opacity-30)}.custom-select,.form-select{max-height:2rem;background-color:transparent;background-image:var(--t42-select-indicator);background-repeat:no-repeat;background-position:right 0.5rem center;background-size:1rem}.custom-select:focus,.custom-select option,.form-select:focus,.form-select option{background-color:var(--t42-input-bg)}.custom-select:disabled option,.form-select:disabled option{background-color:transparent}.custom-radio .custom-control-label{color:var(--t42-content-color-muted);user-select:none}.custom-radio .custom-control-label::after{background:none}.custom-radio .custom-control-input:checked ~ .custom-control-label::after{background-image:none}.custom-checkbox .custom-control-label{color:var(--t42-content-color-muted);user-select:none}.custom-checkbox .custom-control-label::after{background:none}.custom-checkbox .custom-control-input:checked ~ .custom-control-label::after{background-image:none}.custom-checkbox .custom-control-input:disabled .custom-control-label::after,.custom-checkbox .custom-control-input:disabled:checked ~ .custom-control-label::after,.custom-checkbox .custom-control-input:disabled:indeterminate ~ .custom-control-label::after{opacity:0.4}.custom-checkbox .custom-control-input:disabled ~ .custom-control-label::before{border-color:transparent}.switch{position:relative;display:inline-block;align-items:center;height:0.875rem;margin-bottom:0;padding-left:2rem;cursor:pointer}.switch.disabled{color:var(--t42-content-color-disabled)}.switch .slider{position:absolute;top:0;right:0;bottom:0;left:0;width:1.75rem;border:1px solid var(--t42-content-color-muted);cursor:pointer;transition:0.4s}.switch .slider::before{position:absolute;bottom:0.125rem;left:0.125rem;width:0.5rem;height:0.5rem;background-color:var(--t42-content-color-muted);transition:0.4s;content:""}.switch input{width:0;height:0;opacity:0}.switch input:checked+.slider{border:var(--t42-border);background-color:var(--primary)}.switch input:checked+.slider::before{background-color:var(--white);transform:translateX(0.875rem)}.switch input:focus+.slider{box-shadow:0 0 1px #2196f3}.switch input:disabled+.slider{border:var(--t42-border);background-color:var(--t42-color-opacity-10)}.switch input:disabled+.slider::before{background-color:var(--t42-color-opacity-20)}.input-group-prepend .input-group-text{justify-content:center;border-right:0}.input-group-append .input-group-text{justify-content:center;border-left:0}.input-group-append .custom-control,.input-group-prepend .custom-control{margin-bottom:0;padding-left:0.875rem}.input-group-append .custom-control-label,.input-group-prepend .custom-control-label{position:absolute;left:0;min-width:0.875rem;min-height:0.875rem}.input-group-append .custom-control-label::before,.input-group-prepend .custom-control-label::before{left:0}.input-group-append .custom-control-label::after,.input-group-prepend .custom-control-label::after{left:0.25rem}.input-group-append .custom-checkbox .custom-control-label::after,.input-group-prepend .custom-checkbox .custom-control-label::after{left:0.125rem}.custom-file{margin-bottom:1rem}.custom-file-input,.form-control[type="file"]{z-index:1}.custom-file-input:focus ~ .custom-file-label,.form-control[type="file"]:focus ~ .custom-file-label{background-color:var(--t42-input-bg)}.custom-file-label,.input-group-text{background-color:transparent}.custom-file-label::after,.input-group-text::after{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color;background-color:Rgba(--secondary, 0.05);cursor:pointer}.custom-file-label:hover::after,.input-group-text:hover::after{color:var(--white);background-color:var(--secondary)}.form-control[type="file"]+.input-group-text{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color,color;position:absolute;top:0;right:0;left:0;z-index:1;height:2rem;padding:0.375rem 0.875rem;border:var(--t42-border);color:var(--t42-content-color-muted)}.form-control[type="file"]+.input-group-text::after{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color,color;position:absolute;top:0;right:0;bottom:0;z-index:3;display:block;height:100%;padding:0.375rem 0.875rem;border-left:inherit;color:var(--t42-link-color);line-height:1.5;cursor:pointer;content:"Browse"}.form-control[type="file"]+.input-group-text:hover{background-color:var(--t42-input-bg)}.form-control[type="file"]+.input-group-text:hover::after{color:var(--white);background-color:var(--secondary)}.custom-switch{padding-left:2rem}.custom-switch .custom-control-label::before{left:-2rem}.custom-switch .custom-control-label::after{top:0.25rem;left:-1.813rem;width:0.5rem;height:0.5rem}.custom-switch .custom-control-input:checked ~ .custom-control-label::after{background-color:var(--white);content:""}.custom-switch .custom-control-input:not(:disabled):active ~ .custom-control-label::before{border-color:var(--t42-color-opacity-30);background-color:var(--primary)}.valid-feedback,.valid-tooltip,.invalid-feedback,.invalid-tooltip,.warning-feedback,.warning-tooltip{position:absolute;bottom:-1rem;width:calc(100% - 1.875rem);margin-top:0;overflow:hidden;color:var(--t42-content-color);font-size:.7rem;white-space:nowrap;text-overflow:ellipsis}.valid-tooltip,.invalid-tooltip,.warning-tooltip{color:var(--t42-content-color-muted)}.custom-radio label+div,.custom-checkbox label+div,.form-check label+div{width:calc(100% + 1.25rem);transform:translateX(-1.25rem)}.form-group{margin-bottom:1rem}label{margin-bottom:0.5rem}.form-row{display:flex;flex-wrap:wrap;margin-right:-0.5rem;margin-left:-0.5rem}.form-row>.col,.form-row>[class*="col-"]{padding-right:0.5rem;padding-left:0.5rem}.form-inline{display:flex;flex-flow:row wrap;align-items:center}.form-inline .form-check{width:100%}@media (min-width: 576px){.form-inline label{display:flex;align-items:center;justify-content:center;margin-bottom:0}.form-inline .form-group{display:flex;flex:0 0 auto;flex-flow:row wrap;align-items:center;margin-bottom:0}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-plaintext{display:inline-block}.form-inline .input-group,.form-inline .custom-select,.form-inline .form-select{width:auto}.form-inline .form-check{display:flex;align-items:center;justify-content:center;width:auto;padding-left:0}.form-inline .form-check-input{position:relative;flex-shrink:0;margin-top:0;margin-left:0}.form-inline .custom-control{align-items:center;justify-content:center}.form-inline .custom-control-label{margin-bottom:0}}/*! + * Bootstrap Grid v5.1.3 (https://getbootstrap.com/) + * Copyright 2011-2021 The Bootstrap Authors + * Copyright 2011-2021 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) + */:root{--bs-blue: #007be5;--bs-indigo: #6610f2;--bs-purple: #6f42c1;--bs-pink: #fd397a;--bs-red: #ff511f;--bs-orange: #fd7e14;--bs-yellow: #f9a825;--bs-green: #43a047;--bs-teal: #616161;--bs-cyan: #469eb9;--bs-white: #fff;--bs-gray: #6c757d;--bs-gray-dark: #343a40;--bs-gray-100: #f8f9fa;--bs-gray-200: #e9ecef;--bs-gray-300: #dee2e6;--bs-gray-400: #ced4da;--bs-gray-500: #adb5bd;--bs-gray-600: #6c757d;--bs-gray-700: #495057;--bs-gray-800: #343a40;--bs-gray-900: #212529;--bs-primary: #007be5;--bs-secondary: #616161;--bs-success: #43a047;--bs-info: #469eb9;--bs-warning: #f9a825;--bs-danger: #ff511f;--bs-light: #616161;--bs-dark: #616161;--bs-primary-rgb: 0,123,229;--bs-secondary-rgb: 97,97,97;--bs-success-rgb: 67,160,71;--bs-info-rgb: 70,158,185;--bs-warning-rgb: 249,168,37;--bs-danger-rgb: 255,81,31;--bs-light-rgb: 97,97,97;--bs-dark-rgb: 97,97,97;--bs-white-rgb: 255,255,255;--bs-black-rgb: 0,0,0;--bs-body-color-rgb: 33,37,41;--bs-body-bg-rgb: 255,255,255;--bs-font-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--bs-gradient: linear-gradient(180deg, rgba(255,255,255,0.15), rgba(255,255,255,0));--bs-body-font-family: Montserrat,Helvetica Neue,Arial,sans-serif;--bs-body-font-size: .75rem;--bs-body-font-weight: 400;--bs-body-line-height: 1.5;--bs-body-color: #212529;--bs-body-bg: #fff}.container,.container-fluid,.container-sm,.container-md,.container-lg,.container-xl,.container-xxl{width:100%;padding-right:var(--bs-gutter-x, .75rem);padding-left:var(--bs-gutter-x, .75rem);margin-right:auto;margin-left:auto}@media (min-width: 576px){.container,.container-sm{max-width:540px}}@media (min-width: 768px){.container,.container-sm,.container-md{max-width:720px}}@media (min-width: 992px){.container,.container-sm,.container-md,.container-lg{max-width:960px}}@media (min-width: 1200px){.container,.container-sm,.container-md,.container-lg,.container-xl{max-width:1140px}}@media (min-width: 1400px){.container,.container-sm,.container-md,.container-lg,.container-xl,.container-xxl{max-width:1320px}}.row{--bs-gutter-x: 1.5rem;--bs-gutter-y: 0;display:flex;flex-wrap:wrap;margin-top:calc(-1 * var(--bs-gutter-y));margin-right:calc(-.5 * var(--bs-gutter-x));margin-left:calc(-.5 * var(--bs-gutter-x))}.row>*{box-sizing:border-box;flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--bs-gutter-x) * .5);padding-left:calc(var(--bs-gutter-x) * .5);margin-top:var(--bs-gutter-y)}.col{flex:1 0 0%}.row-cols-auto>*{flex:0 0 auto;width:auto}.row-cols-1>*{flex:0 0 auto;width:100%}.row-cols-2>*{flex:0 0 auto;width:50%}.row-cols-3>*{flex:0 0 auto;width:33.33333%}.row-cols-4>*{flex:0 0 auto;width:25%}.row-cols-5>*{flex:0 0 auto;width:20%}.row-cols-6>*{flex:0 0 auto;width:16.66667%}.col-auto{flex:0 0 auto;width:auto}.col-1{flex:0 0 auto;width:8.33333%}.col-2{flex:0 0 auto;width:16.66667%}.col-3{flex:0 0 auto;width:25%}.col-4{flex:0 0 auto;width:33.33333%}.col-5{flex:0 0 auto;width:41.66667%}.col-6{flex:0 0 auto;width:50%}.col-7{flex:0 0 auto;width:58.33333%}.col-8{flex:0 0 auto;width:66.66667%}.col-9{flex:0 0 auto;width:75%}.col-10{flex:0 0 auto;width:83.33333%}.col-11{flex:0 0 auto;width:91.66667%}.col-12{flex:0 0 auto;width:100%}.offset-1{margin-left:8.33333%}.offset-2{margin-left:16.66667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.33333%}.offset-5{margin-left:41.66667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.33333%}.offset-8{margin-left:66.66667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.33333%}.offset-11{margin-left:91.66667%}.g-0,.gx-0{--bs-gutter-x: 0}.g-0,.gy-0{--bs-gutter-y: 0}.g-1,.gx-1{--bs-gutter-x: .25rem}.g-1,.gy-1{--bs-gutter-y: .25rem}.g-2,.gx-2{--bs-gutter-x: .5rem}.g-2,.gy-2{--bs-gutter-y: .5rem}.g-3,.gx-3{--bs-gutter-x: 1rem}.g-3,.gy-3{--bs-gutter-y: 1rem}.g-4,.gx-4{--bs-gutter-x: 1.5rem}.g-4,.gy-4{--bs-gutter-y: 1.5rem}.g-5,.gx-5{--bs-gutter-x: 3rem}.g-5,.gy-5{--bs-gutter-y: 3rem}@media (min-width: 576px){.col-sm{flex:1 0 0%}.row-cols-sm-auto>*{flex:0 0 auto;width:auto}.row-cols-sm-1>*{flex:0 0 auto;width:100%}.row-cols-sm-2>*{flex:0 0 auto;width:50%}.row-cols-sm-3>*{flex:0 0 auto;width:33.33333%}.row-cols-sm-4>*{flex:0 0 auto;width:25%}.row-cols-sm-5>*{flex:0 0 auto;width:20%}.row-cols-sm-6>*{flex:0 0 auto;width:16.66667%}.col-sm-auto{flex:0 0 auto;width:auto}.col-sm-1{flex:0 0 auto;width:8.33333%}.col-sm-2{flex:0 0 auto;width:16.66667%}.col-sm-3{flex:0 0 auto;width:25%}.col-sm-4{flex:0 0 auto;width:33.33333%}.col-sm-5{flex:0 0 auto;width:41.66667%}.col-sm-6{flex:0 0 auto;width:50%}.col-sm-7{flex:0 0 auto;width:58.33333%}.col-sm-8{flex:0 0 auto;width:66.66667%}.col-sm-9{flex:0 0 auto;width:75%}.col-sm-10{flex:0 0 auto;width:83.33333%}.col-sm-11{flex:0 0 auto;width:91.66667%}.col-sm-12{flex:0 0 auto;width:100%}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.33333%}.offset-sm-2{margin-left:16.66667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.33333%}.offset-sm-5{margin-left:41.66667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.33333%}.offset-sm-8{margin-left:66.66667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.33333%}.offset-sm-11{margin-left:91.66667%}.g-sm-0,.gx-sm-0{--bs-gutter-x: 0}.g-sm-0,.gy-sm-0{--bs-gutter-y: 0}.g-sm-1,.gx-sm-1{--bs-gutter-x: .25rem}.g-sm-1,.gy-sm-1{--bs-gutter-y: .25rem}.g-sm-2,.gx-sm-2{--bs-gutter-x: .5rem}.g-sm-2,.gy-sm-2{--bs-gutter-y: .5rem}.g-sm-3,.gx-sm-3{--bs-gutter-x: 1rem}.g-sm-3,.gy-sm-3{--bs-gutter-y: 1rem}.g-sm-4,.gx-sm-4{--bs-gutter-x: 1.5rem}.g-sm-4,.gy-sm-4{--bs-gutter-y: 1.5rem}.g-sm-5,.gx-sm-5{--bs-gutter-x: 3rem}.g-sm-5,.gy-sm-5{--bs-gutter-y: 3rem}}@media (min-width: 768px){.col-md{flex:1 0 0%}.row-cols-md-auto>*{flex:0 0 auto;width:auto}.row-cols-md-1>*{flex:0 0 auto;width:100%}.row-cols-md-2>*{flex:0 0 auto;width:50%}.row-cols-md-3>*{flex:0 0 auto;width:33.33333%}.row-cols-md-4>*{flex:0 0 auto;width:25%}.row-cols-md-5>*{flex:0 0 auto;width:20%}.row-cols-md-6>*{flex:0 0 auto;width:16.66667%}.col-md-auto{flex:0 0 auto;width:auto}.col-md-1{flex:0 0 auto;width:8.33333%}.col-md-2{flex:0 0 auto;width:16.66667%}.col-md-3{flex:0 0 auto;width:25%}.col-md-4{flex:0 0 auto;width:33.33333%}.col-md-5{flex:0 0 auto;width:41.66667%}.col-md-6{flex:0 0 auto;width:50%}.col-md-7{flex:0 0 auto;width:58.33333%}.col-md-8{flex:0 0 auto;width:66.66667%}.col-md-9{flex:0 0 auto;width:75%}.col-md-10{flex:0 0 auto;width:83.33333%}.col-md-11{flex:0 0 auto;width:91.66667%}.col-md-12{flex:0 0 auto;width:100%}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.33333%}.offset-md-2{margin-left:16.66667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.33333%}.offset-md-5{margin-left:41.66667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.33333%}.offset-md-8{margin-left:66.66667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.33333%}.offset-md-11{margin-left:91.66667%}.g-md-0,.gx-md-0{--bs-gutter-x: 0}.g-md-0,.gy-md-0{--bs-gutter-y: 0}.g-md-1,.gx-md-1{--bs-gutter-x: .25rem}.g-md-1,.gy-md-1{--bs-gutter-y: .25rem}.g-md-2,.gx-md-2{--bs-gutter-x: .5rem}.g-md-2,.gy-md-2{--bs-gutter-y: .5rem}.g-md-3,.gx-md-3{--bs-gutter-x: 1rem}.g-md-3,.gy-md-3{--bs-gutter-y: 1rem}.g-md-4,.gx-md-4{--bs-gutter-x: 1.5rem}.g-md-4,.gy-md-4{--bs-gutter-y: 1.5rem}.g-md-5,.gx-md-5{--bs-gutter-x: 3rem}.g-md-5,.gy-md-5{--bs-gutter-y: 3rem}}@media (min-width: 992px){.col-lg{flex:1 0 0%}.row-cols-lg-auto>*{flex:0 0 auto;width:auto}.row-cols-lg-1>*{flex:0 0 auto;width:100%}.row-cols-lg-2>*{flex:0 0 auto;width:50%}.row-cols-lg-3>*{flex:0 0 auto;width:33.33333%}.row-cols-lg-4>*{flex:0 0 auto;width:25%}.row-cols-lg-5>*{flex:0 0 auto;width:20%}.row-cols-lg-6>*{flex:0 0 auto;width:16.66667%}.col-lg-auto{flex:0 0 auto;width:auto}.col-lg-1{flex:0 0 auto;width:8.33333%}.col-lg-2{flex:0 0 auto;width:16.66667%}.col-lg-3{flex:0 0 auto;width:25%}.col-lg-4{flex:0 0 auto;width:33.33333%}.col-lg-5{flex:0 0 auto;width:41.66667%}.col-lg-6{flex:0 0 auto;width:50%}.col-lg-7{flex:0 0 auto;width:58.33333%}.col-lg-8{flex:0 0 auto;width:66.66667%}.col-lg-9{flex:0 0 auto;width:75%}.col-lg-10{flex:0 0 auto;width:83.33333%}.col-lg-11{flex:0 0 auto;width:91.66667%}.col-lg-12{flex:0 0 auto;width:100%}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.33333%}.offset-lg-2{margin-left:16.66667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.33333%}.offset-lg-5{margin-left:41.66667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.33333%}.offset-lg-8{margin-left:66.66667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.33333%}.offset-lg-11{margin-left:91.66667%}.g-lg-0,.gx-lg-0{--bs-gutter-x: 0}.g-lg-0,.gy-lg-0{--bs-gutter-y: 0}.g-lg-1,.gx-lg-1{--bs-gutter-x: .25rem}.g-lg-1,.gy-lg-1{--bs-gutter-y: .25rem}.g-lg-2,.gx-lg-2{--bs-gutter-x: .5rem}.g-lg-2,.gy-lg-2{--bs-gutter-y: .5rem}.g-lg-3,.gx-lg-3{--bs-gutter-x: 1rem}.g-lg-3,.gy-lg-3{--bs-gutter-y: 1rem}.g-lg-4,.gx-lg-4{--bs-gutter-x: 1.5rem}.g-lg-4,.gy-lg-4{--bs-gutter-y: 1.5rem}.g-lg-5,.gx-lg-5{--bs-gutter-x: 3rem}.g-lg-5,.gy-lg-5{--bs-gutter-y: 3rem}}@media (min-width: 1200px){.col-xl{flex:1 0 0%}.row-cols-xl-auto>*{flex:0 0 auto;width:auto}.row-cols-xl-1>*{flex:0 0 auto;width:100%}.row-cols-xl-2>*{flex:0 0 auto;width:50%}.row-cols-xl-3>*{flex:0 0 auto;width:33.33333%}.row-cols-xl-4>*{flex:0 0 auto;width:25%}.row-cols-xl-5>*{flex:0 0 auto;width:20%}.row-cols-xl-6>*{flex:0 0 auto;width:16.66667%}.col-xl-auto{flex:0 0 auto;width:auto}.col-xl-1{flex:0 0 auto;width:8.33333%}.col-xl-2{flex:0 0 auto;width:16.66667%}.col-xl-3{flex:0 0 auto;width:25%}.col-xl-4{flex:0 0 auto;width:33.33333%}.col-xl-5{flex:0 0 auto;width:41.66667%}.col-xl-6{flex:0 0 auto;width:50%}.col-xl-7{flex:0 0 auto;width:58.33333%}.col-xl-8{flex:0 0 auto;width:66.66667%}.col-xl-9{flex:0 0 auto;width:75%}.col-xl-10{flex:0 0 auto;width:83.33333%}.col-xl-11{flex:0 0 auto;width:91.66667%}.col-xl-12{flex:0 0 auto;width:100%}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.33333%}.offset-xl-2{margin-left:16.66667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.33333%}.offset-xl-5{margin-left:41.66667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.33333%}.offset-xl-8{margin-left:66.66667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.33333%}.offset-xl-11{margin-left:91.66667%}.g-xl-0,.gx-xl-0{--bs-gutter-x: 0}.g-xl-0,.gy-xl-0{--bs-gutter-y: 0}.g-xl-1,.gx-xl-1{--bs-gutter-x: .25rem}.g-xl-1,.gy-xl-1{--bs-gutter-y: .25rem}.g-xl-2,.gx-xl-2{--bs-gutter-x: .5rem}.g-xl-2,.gy-xl-2{--bs-gutter-y: .5rem}.g-xl-3,.gx-xl-3{--bs-gutter-x: 1rem}.g-xl-3,.gy-xl-3{--bs-gutter-y: 1rem}.g-xl-4,.gx-xl-4{--bs-gutter-x: 1.5rem}.g-xl-4,.gy-xl-4{--bs-gutter-y: 1.5rem}.g-xl-5,.gx-xl-5{--bs-gutter-x: 3rem}.g-xl-5,.gy-xl-5{--bs-gutter-y: 3rem}}@media (min-width: 1400px){.col-xxl{flex:1 0 0%}.row-cols-xxl-auto>*{flex:0 0 auto;width:auto}.row-cols-xxl-1>*{flex:0 0 auto;width:100%}.row-cols-xxl-2>*{flex:0 0 auto;width:50%}.row-cols-xxl-3>*{flex:0 0 auto;width:33.33333%}.row-cols-xxl-4>*{flex:0 0 auto;width:25%}.row-cols-xxl-5>*{flex:0 0 auto;width:20%}.row-cols-xxl-6>*{flex:0 0 auto;width:16.66667%}.col-xxl-auto{flex:0 0 auto;width:auto}.col-xxl-1{flex:0 0 auto;width:8.33333%}.col-xxl-2{flex:0 0 auto;width:16.66667%}.col-xxl-3{flex:0 0 auto;width:25%}.col-xxl-4{flex:0 0 auto;width:33.33333%}.col-xxl-5{flex:0 0 auto;width:41.66667%}.col-xxl-6{flex:0 0 auto;width:50%}.col-xxl-7{flex:0 0 auto;width:58.33333%}.col-xxl-8{flex:0 0 auto;width:66.66667%}.col-xxl-9{flex:0 0 auto;width:75%}.col-xxl-10{flex:0 0 auto;width:83.33333%}.col-xxl-11{flex:0 0 auto;width:91.66667%}.col-xxl-12{flex:0 0 auto;width:100%}.offset-xxl-0{margin-left:0}.offset-xxl-1{margin-left:8.33333%}.offset-xxl-2{margin-left:16.66667%}.offset-xxl-3{margin-left:25%}.offset-xxl-4{margin-left:33.33333%}.offset-xxl-5{margin-left:41.66667%}.offset-xxl-6{margin-left:50%}.offset-xxl-7{margin-left:58.33333%}.offset-xxl-8{margin-left:66.66667%}.offset-xxl-9{margin-left:75%}.offset-xxl-10{margin-left:83.33333%}.offset-xxl-11{margin-left:91.66667%}.g-xxl-0,.gx-xxl-0{--bs-gutter-x: 0}.g-xxl-0,.gy-xxl-0{--bs-gutter-y: 0}.g-xxl-1,.gx-xxl-1{--bs-gutter-x: .25rem}.g-xxl-1,.gy-xxl-1{--bs-gutter-y: .25rem}.g-xxl-2,.gx-xxl-2{--bs-gutter-x: .5rem}.g-xxl-2,.gy-xxl-2{--bs-gutter-y: .5rem}.g-xxl-3,.gx-xxl-3{--bs-gutter-x: 1rem}.g-xxl-3,.gy-xxl-3{--bs-gutter-y: 1rem}.g-xxl-4,.gx-xxl-4{--bs-gutter-x: 1.5rem}.g-xxl-4,.gy-xxl-4{--bs-gutter-y: 1.5rem}.g-xxl-5,.gx-xxl-5{--bs-gutter-x: 3rem}.g-xxl-5,.gy-xxl-5{--bs-gutter-y: 3rem}}.d-inline{display:inline !important}.d-inline-block{display:inline-block !important}.d-block{display:block !important}.d-grid{display:grid !important}.d-table{display:table !important}.d-table-row{display:table-row !important}.d-table-cell{display:table-cell !important}.d-flex{display:flex !important}.d-inline-flex{display:inline-flex !important}.d-none{display:none !important}.flex-fill{flex:1 1 auto !important}.flex-row{flex-direction:row !important}.flex-column{flex-direction:column !important}.flex-row-reverse{flex-direction:row-reverse !important}.flex-column-reverse{flex-direction:column-reverse !important}.flex-grow-0{flex-grow:0 !important}.flex-grow-1{flex-grow:1 !important}.flex-shrink-0{flex-shrink:0 !important}.flex-shrink-1{flex-shrink:1 !important}.flex-wrap{flex-wrap:wrap !important}.flex-nowrap{flex-wrap:nowrap !important}.flex-wrap-reverse{flex-wrap:wrap-reverse !important}.justify-content-start{justify-content:flex-start !important}.justify-content-end{justify-content:flex-end !important}.justify-content-center{justify-content:center !important}.justify-content-between{justify-content:space-between !important}.justify-content-around{justify-content:space-around !important}.justify-content-evenly{justify-content:space-evenly !important}.align-items-start{align-items:flex-start !important}.align-items-end{align-items:flex-end !important}.align-items-center{align-items:center !important}.align-items-baseline{align-items:baseline !important}.align-items-stretch{align-items:stretch !important}.align-content-start{align-content:flex-start !important}.align-content-end{align-content:flex-end !important}.align-content-center{align-content:center !important}.align-content-between{align-content:space-between !important}.align-content-around{align-content:space-around !important}.align-content-stretch{align-content:stretch !important}.align-self-auto{align-self:auto !important}.align-self-start{align-self:flex-start !important}.align-self-end{align-self:flex-end !important}.align-self-center{align-self:center !important}.align-self-baseline{align-self:baseline !important}.align-self-stretch{align-self:stretch !important}.order-first{order:-1 !important}.order-0{order:0 !important}.order-1{order:1 !important}.order-2{order:2 !important}.order-3{order:3 !important}.order-4{order:4 !important}.order-5{order:5 !important}.order-last{order:6 !important}.m-0{margin:0 !important}.m-1{margin:.25rem !important}.m-2{margin:.5rem !important}.m-3{margin:1rem !important}.m-4{margin:1.5rem !important}.m-5{margin:3rem !important}.m-auto{margin:auto !important}.mx-0{margin-right:0 !important;margin-left:0 !important}.mx-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-3{margin-right:1rem !important;margin-left:1rem !important}.mx-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-5{margin-right:3rem !important;margin-left:3rem !important}.mx-auto{margin-right:auto !important;margin-left:auto !important}.my-0{margin-top:0 !important;margin-bottom:0 !important}.my-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-0{margin-top:0 !important}.mt-1{margin-top:.25rem !important}.mt-2{margin-top:.5rem !important}.mt-3{margin-top:1rem !important}.mt-4{margin-top:1.5rem !important}.mt-5{margin-top:3rem !important}.mt-auto{margin-top:auto !important}.me-0{margin-right:0 !important}.me-1{margin-right:.25rem !important}.me-2{margin-right:.5rem !important}.me-3{margin-right:1rem !important}.me-4{margin-right:1.5rem !important}.me-5{margin-right:3rem !important}.me-auto{margin-right:auto !important}.mb-0{margin-bottom:0 !important}.mb-1{margin-bottom:.25rem !important}.mb-2{margin-bottom:.5rem !important}.mb-3{margin-bottom:1rem !important}.mb-4{margin-bottom:1.5rem !important}.mb-5{margin-bottom:3rem !important}.mb-auto{margin-bottom:auto !important}.ms-0{margin-left:0 !important}.ms-1{margin-left:.25rem !important}.ms-2{margin-left:.5rem !important}.ms-3{margin-left:1rem !important}.ms-4{margin-left:1.5rem !important}.ms-5{margin-left:3rem !important}.ms-auto{margin-left:auto !important}.p-0{padding:0 !important}.p-1{padding:.25rem !important}.p-2{padding:.5rem !important}.p-3{padding:1rem !important}.p-4{padding:1.5rem !important}.p-5{padding:3rem !important}.px-0{padding-right:0 !important;padding-left:0 !important}.px-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-3{padding-right:1rem !important;padding-left:1rem !important}.px-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-5{padding-right:3rem !important;padding-left:3rem !important}.py-0{padding-top:0 !important;padding-bottom:0 !important}.py-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-0{padding-top:0 !important}.pt-1{padding-top:.25rem !important}.pt-2{padding-top:.5rem !important}.pt-3{padding-top:1rem !important}.pt-4{padding-top:1.5rem !important}.pt-5{padding-top:3rem !important}.pe-0{padding-right:0 !important}.pe-1{padding-right:.25rem !important}.pe-2{padding-right:.5rem !important}.pe-3{padding-right:1rem !important}.pe-4{padding-right:1.5rem !important}.pe-5{padding-right:3rem !important}.pb-0{padding-bottom:0 !important}.pb-1{padding-bottom:.25rem !important}.pb-2{padding-bottom:.5rem !important}.pb-3{padding-bottom:1rem !important}.pb-4{padding-bottom:1.5rem !important}.pb-5{padding-bottom:3rem !important}.ps-0{padding-left:0 !important}.ps-1{padding-left:.25rem !important}.ps-2{padding-left:.5rem !important}.ps-3{padding-left:1rem !important}.ps-4{padding-left:1.5rem !important}.ps-5{padding-left:3rem !important}@media (min-width: 576px){.d-sm-inline{display:inline !important}.d-sm-inline-block{display:inline-block !important}.d-sm-block{display:block !important}.d-sm-grid{display:grid !important}.d-sm-table{display:table !important}.d-sm-table-row{display:table-row !important}.d-sm-table-cell{display:table-cell !important}.d-sm-flex{display:flex !important}.d-sm-inline-flex{display:inline-flex !important}.d-sm-none{display:none !important}.flex-sm-fill{flex:1 1 auto !important}.flex-sm-row{flex-direction:row !important}.flex-sm-column{flex-direction:column !important}.flex-sm-row-reverse{flex-direction:row-reverse !important}.flex-sm-column-reverse{flex-direction:column-reverse !important}.flex-sm-grow-0{flex-grow:0 !important}.flex-sm-grow-1{flex-grow:1 !important}.flex-sm-shrink-0{flex-shrink:0 !important}.flex-sm-shrink-1{flex-shrink:1 !important}.flex-sm-wrap{flex-wrap:wrap !important}.flex-sm-nowrap{flex-wrap:nowrap !important}.flex-sm-wrap-reverse{flex-wrap:wrap-reverse !important}.justify-content-sm-start{justify-content:flex-start !important}.justify-content-sm-end{justify-content:flex-end !important}.justify-content-sm-center{justify-content:center !important}.justify-content-sm-between{justify-content:space-between !important}.justify-content-sm-around{justify-content:space-around !important}.justify-content-sm-evenly{justify-content:space-evenly !important}.align-items-sm-start{align-items:flex-start !important}.align-items-sm-end{align-items:flex-end !important}.align-items-sm-center{align-items:center !important}.align-items-sm-baseline{align-items:baseline !important}.align-items-sm-stretch{align-items:stretch !important}.align-content-sm-start{align-content:flex-start !important}.align-content-sm-end{align-content:flex-end !important}.align-content-sm-center{align-content:center !important}.align-content-sm-between{align-content:space-between !important}.align-content-sm-around{align-content:space-around !important}.align-content-sm-stretch{align-content:stretch !important}.align-self-sm-auto{align-self:auto !important}.align-self-sm-start{align-self:flex-start !important}.align-self-sm-end{align-self:flex-end !important}.align-self-sm-center{align-self:center !important}.align-self-sm-baseline{align-self:baseline !important}.align-self-sm-stretch{align-self:stretch !important}.order-sm-first{order:-1 !important}.order-sm-0{order:0 !important}.order-sm-1{order:1 !important}.order-sm-2{order:2 !important}.order-sm-3{order:3 !important}.order-sm-4{order:4 !important}.order-sm-5{order:5 !important}.order-sm-last{order:6 !important}.m-sm-0{margin:0 !important}.m-sm-1{margin:.25rem !important}.m-sm-2{margin:.5rem !important}.m-sm-3{margin:1rem !important}.m-sm-4{margin:1.5rem !important}.m-sm-5{margin:3rem !important}.m-sm-auto{margin:auto !important}.mx-sm-0{margin-right:0 !important;margin-left:0 !important}.mx-sm-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-sm-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-sm-3{margin-right:1rem !important;margin-left:1rem !important}.mx-sm-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-sm-5{margin-right:3rem !important;margin-left:3rem !important}.mx-sm-auto{margin-right:auto !important;margin-left:auto !important}.my-sm-0{margin-top:0 !important;margin-bottom:0 !important}.my-sm-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-sm-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-sm-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-sm-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-sm-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-sm-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-sm-0{margin-top:0 !important}.mt-sm-1{margin-top:.25rem !important}.mt-sm-2{margin-top:.5rem !important}.mt-sm-3{margin-top:1rem !important}.mt-sm-4{margin-top:1.5rem !important}.mt-sm-5{margin-top:3rem !important}.mt-sm-auto{margin-top:auto !important}.me-sm-0{margin-right:0 !important}.me-sm-1{margin-right:.25rem !important}.me-sm-2{margin-right:.5rem !important}.me-sm-3{margin-right:1rem !important}.me-sm-4{margin-right:1.5rem !important}.me-sm-5{margin-right:3rem !important}.me-sm-auto{margin-right:auto !important}.mb-sm-0{margin-bottom:0 !important}.mb-sm-1{margin-bottom:.25rem !important}.mb-sm-2{margin-bottom:.5rem !important}.mb-sm-3{margin-bottom:1rem !important}.mb-sm-4{margin-bottom:1.5rem !important}.mb-sm-5{margin-bottom:3rem !important}.mb-sm-auto{margin-bottom:auto !important}.ms-sm-0{margin-left:0 !important}.ms-sm-1{margin-left:.25rem !important}.ms-sm-2{margin-left:.5rem !important}.ms-sm-3{margin-left:1rem !important}.ms-sm-4{margin-left:1.5rem !important}.ms-sm-5{margin-left:3rem !important}.ms-sm-auto{margin-left:auto !important}.p-sm-0{padding:0 !important}.p-sm-1{padding:.25rem !important}.p-sm-2{padding:.5rem !important}.p-sm-3{padding:1rem !important}.p-sm-4{padding:1.5rem !important}.p-sm-5{padding:3rem !important}.px-sm-0{padding-right:0 !important;padding-left:0 !important}.px-sm-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-sm-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-sm-3{padding-right:1rem !important;padding-left:1rem !important}.px-sm-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-sm-5{padding-right:3rem !important;padding-left:3rem !important}.py-sm-0{padding-top:0 !important;padding-bottom:0 !important}.py-sm-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-sm-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-sm-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-sm-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-sm-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-sm-0{padding-top:0 !important}.pt-sm-1{padding-top:.25rem !important}.pt-sm-2{padding-top:.5rem !important}.pt-sm-3{padding-top:1rem !important}.pt-sm-4{padding-top:1.5rem !important}.pt-sm-5{padding-top:3rem !important}.pe-sm-0{padding-right:0 !important}.pe-sm-1{padding-right:.25rem !important}.pe-sm-2{padding-right:.5rem !important}.pe-sm-3{padding-right:1rem !important}.pe-sm-4{padding-right:1.5rem !important}.pe-sm-5{padding-right:3rem !important}.pb-sm-0{padding-bottom:0 !important}.pb-sm-1{padding-bottom:.25rem !important}.pb-sm-2{padding-bottom:.5rem !important}.pb-sm-3{padding-bottom:1rem !important}.pb-sm-4{padding-bottom:1.5rem !important}.pb-sm-5{padding-bottom:3rem !important}.ps-sm-0{padding-left:0 !important}.ps-sm-1{padding-left:.25rem !important}.ps-sm-2{padding-left:.5rem !important}.ps-sm-3{padding-left:1rem !important}.ps-sm-4{padding-left:1.5rem !important}.ps-sm-5{padding-left:3rem !important}}@media (min-width: 768px){.d-md-inline{display:inline !important}.d-md-inline-block{display:inline-block !important}.d-md-block{display:block !important}.d-md-grid{display:grid !important}.d-md-table{display:table !important}.d-md-table-row{display:table-row !important}.d-md-table-cell{display:table-cell !important}.d-md-flex{display:flex !important}.d-md-inline-flex{display:inline-flex !important}.d-md-none{display:none !important}.flex-md-fill{flex:1 1 auto !important}.flex-md-row{flex-direction:row !important}.flex-md-column{flex-direction:column !important}.flex-md-row-reverse{flex-direction:row-reverse !important}.flex-md-column-reverse{flex-direction:column-reverse !important}.flex-md-grow-0{flex-grow:0 !important}.flex-md-grow-1{flex-grow:1 !important}.flex-md-shrink-0{flex-shrink:0 !important}.flex-md-shrink-1{flex-shrink:1 !important}.flex-md-wrap{flex-wrap:wrap !important}.flex-md-nowrap{flex-wrap:nowrap !important}.flex-md-wrap-reverse{flex-wrap:wrap-reverse !important}.justify-content-md-start{justify-content:flex-start !important}.justify-content-md-end{justify-content:flex-end !important}.justify-content-md-center{justify-content:center !important}.justify-content-md-between{justify-content:space-between !important}.justify-content-md-around{justify-content:space-around !important}.justify-content-md-evenly{justify-content:space-evenly !important}.align-items-md-start{align-items:flex-start !important}.align-items-md-end{align-items:flex-end !important}.align-items-md-center{align-items:center !important}.align-items-md-baseline{align-items:baseline !important}.align-items-md-stretch{align-items:stretch !important}.align-content-md-start{align-content:flex-start !important}.align-content-md-end{align-content:flex-end !important}.align-content-md-center{align-content:center !important}.align-content-md-between{align-content:space-between !important}.align-content-md-around{align-content:space-around !important}.align-content-md-stretch{align-content:stretch !important}.align-self-md-auto{align-self:auto !important}.align-self-md-start{align-self:flex-start !important}.align-self-md-end{align-self:flex-end !important}.align-self-md-center{align-self:center !important}.align-self-md-baseline{align-self:baseline !important}.align-self-md-stretch{align-self:stretch !important}.order-md-first{order:-1 !important}.order-md-0{order:0 !important}.order-md-1{order:1 !important}.order-md-2{order:2 !important}.order-md-3{order:3 !important}.order-md-4{order:4 !important}.order-md-5{order:5 !important}.order-md-last{order:6 !important}.m-md-0{margin:0 !important}.m-md-1{margin:.25rem !important}.m-md-2{margin:.5rem !important}.m-md-3{margin:1rem !important}.m-md-4{margin:1.5rem !important}.m-md-5{margin:3rem !important}.m-md-auto{margin:auto !important}.mx-md-0{margin-right:0 !important;margin-left:0 !important}.mx-md-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-md-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-md-3{margin-right:1rem !important;margin-left:1rem !important}.mx-md-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-md-5{margin-right:3rem !important;margin-left:3rem !important}.mx-md-auto{margin-right:auto !important;margin-left:auto !important}.my-md-0{margin-top:0 !important;margin-bottom:0 !important}.my-md-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-md-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-md-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-md-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-md-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-md-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-md-0{margin-top:0 !important}.mt-md-1{margin-top:.25rem !important}.mt-md-2{margin-top:.5rem !important}.mt-md-3{margin-top:1rem !important}.mt-md-4{margin-top:1.5rem !important}.mt-md-5{margin-top:3rem !important}.mt-md-auto{margin-top:auto !important}.me-md-0{margin-right:0 !important}.me-md-1{margin-right:.25rem !important}.me-md-2{margin-right:.5rem !important}.me-md-3{margin-right:1rem !important}.me-md-4{margin-right:1.5rem !important}.me-md-5{margin-right:3rem !important}.me-md-auto{margin-right:auto !important}.mb-md-0{margin-bottom:0 !important}.mb-md-1{margin-bottom:.25rem !important}.mb-md-2{margin-bottom:.5rem !important}.mb-md-3{margin-bottom:1rem !important}.mb-md-4{margin-bottom:1.5rem !important}.mb-md-5{margin-bottom:3rem !important}.mb-md-auto{margin-bottom:auto !important}.ms-md-0{margin-left:0 !important}.ms-md-1{margin-left:.25rem !important}.ms-md-2{margin-left:.5rem !important}.ms-md-3{margin-left:1rem !important}.ms-md-4{margin-left:1.5rem !important}.ms-md-5{margin-left:3rem !important}.ms-md-auto{margin-left:auto !important}.p-md-0{padding:0 !important}.p-md-1{padding:.25rem !important}.p-md-2{padding:.5rem !important}.p-md-3{padding:1rem !important}.p-md-4{padding:1.5rem !important}.p-md-5{padding:3rem !important}.px-md-0{padding-right:0 !important;padding-left:0 !important}.px-md-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-md-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-md-3{padding-right:1rem !important;padding-left:1rem !important}.px-md-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-md-5{padding-right:3rem !important;padding-left:3rem !important}.py-md-0{padding-top:0 !important;padding-bottom:0 !important}.py-md-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-md-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-md-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-md-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-md-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-md-0{padding-top:0 !important}.pt-md-1{padding-top:.25rem !important}.pt-md-2{padding-top:.5rem !important}.pt-md-3{padding-top:1rem !important}.pt-md-4{padding-top:1.5rem !important}.pt-md-5{padding-top:3rem !important}.pe-md-0{padding-right:0 !important}.pe-md-1{padding-right:.25rem !important}.pe-md-2{padding-right:.5rem !important}.pe-md-3{padding-right:1rem !important}.pe-md-4{padding-right:1.5rem !important}.pe-md-5{padding-right:3rem !important}.pb-md-0{padding-bottom:0 !important}.pb-md-1{padding-bottom:.25rem !important}.pb-md-2{padding-bottom:.5rem !important}.pb-md-3{padding-bottom:1rem !important}.pb-md-4{padding-bottom:1.5rem !important}.pb-md-5{padding-bottom:3rem !important}.ps-md-0{padding-left:0 !important}.ps-md-1{padding-left:.25rem !important}.ps-md-2{padding-left:.5rem !important}.ps-md-3{padding-left:1rem !important}.ps-md-4{padding-left:1.5rem !important}.ps-md-5{padding-left:3rem !important}}@media (min-width: 992px){.d-lg-inline{display:inline !important}.d-lg-inline-block{display:inline-block !important}.d-lg-block{display:block !important}.d-lg-grid{display:grid !important}.d-lg-table{display:table !important}.d-lg-table-row{display:table-row !important}.d-lg-table-cell{display:table-cell !important}.d-lg-flex{display:flex !important}.d-lg-inline-flex{display:inline-flex !important}.d-lg-none{display:none !important}.flex-lg-fill{flex:1 1 auto !important}.flex-lg-row{flex-direction:row !important}.flex-lg-column{flex-direction:column !important}.flex-lg-row-reverse{flex-direction:row-reverse !important}.flex-lg-column-reverse{flex-direction:column-reverse !important}.flex-lg-grow-0{flex-grow:0 !important}.flex-lg-grow-1{flex-grow:1 !important}.flex-lg-shrink-0{flex-shrink:0 !important}.flex-lg-shrink-1{flex-shrink:1 !important}.flex-lg-wrap{flex-wrap:wrap !important}.flex-lg-nowrap{flex-wrap:nowrap !important}.flex-lg-wrap-reverse{flex-wrap:wrap-reverse !important}.justify-content-lg-start{justify-content:flex-start !important}.justify-content-lg-end{justify-content:flex-end !important}.justify-content-lg-center{justify-content:center !important}.justify-content-lg-between{justify-content:space-between !important}.justify-content-lg-around{justify-content:space-around !important}.justify-content-lg-evenly{justify-content:space-evenly !important}.align-items-lg-start{align-items:flex-start !important}.align-items-lg-end{align-items:flex-end !important}.align-items-lg-center{align-items:center !important}.align-items-lg-baseline{align-items:baseline !important}.align-items-lg-stretch{align-items:stretch !important}.align-content-lg-start{align-content:flex-start !important}.align-content-lg-end{align-content:flex-end !important}.align-content-lg-center{align-content:center !important}.align-content-lg-between{align-content:space-between !important}.align-content-lg-around{align-content:space-around !important}.align-content-lg-stretch{align-content:stretch !important}.align-self-lg-auto{align-self:auto !important}.align-self-lg-start{align-self:flex-start !important}.align-self-lg-end{align-self:flex-end !important}.align-self-lg-center{align-self:center !important}.align-self-lg-baseline{align-self:baseline !important}.align-self-lg-stretch{align-self:stretch !important}.order-lg-first{order:-1 !important}.order-lg-0{order:0 !important}.order-lg-1{order:1 !important}.order-lg-2{order:2 !important}.order-lg-3{order:3 !important}.order-lg-4{order:4 !important}.order-lg-5{order:5 !important}.order-lg-last{order:6 !important}.m-lg-0{margin:0 !important}.m-lg-1{margin:.25rem !important}.m-lg-2{margin:.5rem !important}.m-lg-3{margin:1rem !important}.m-lg-4{margin:1.5rem !important}.m-lg-5{margin:3rem !important}.m-lg-auto{margin:auto !important}.mx-lg-0{margin-right:0 !important;margin-left:0 !important}.mx-lg-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-lg-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-lg-3{margin-right:1rem !important;margin-left:1rem !important}.mx-lg-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-lg-5{margin-right:3rem !important;margin-left:3rem !important}.mx-lg-auto{margin-right:auto !important;margin-left:auto !important}.my-lg-0{margin-top:0 !important;margin-bottom:0 !important}.my-lg-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-lg-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-lg-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-lg-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-lg-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-lg-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-lg-0{margin-top:0 !important}.mt-lg-1{margin-top:.25rem !important}.mt-lg-2{margin-top:.5rem !important}.mt-lg-3{margin-top:1rem !important}.mt-lg-4{margin-top:1.5rem !important}.mt-lg-5{margin-top:3rem !important}.mt-lg-auto{margin-top:auto !important}.me-lg-0{margin-right:0 !important}.me-lg-1{margin-right:.25rem !important}.me-lg-2{margin-right:.5rem !important}.me-lg-3{margin-right:1rem !important}.me-lg-4{margin-right:1.5rem !important}.me-lg-5{margin-right:3rem !important}.me-lg-auto{margin-right:auto !important}.mb-lg-0{margin-bottom:0 !important}.mb-lg-1{margin-bottom:.25rem !important}.mb-lg-2{margin-bottom:.5rem !important}.mb-lg-3{margin-bottom:1rem !important}.mb-lg-4{margin-bottom:1.5rem !important}.mb-lg-5{margin-bottom:3rem !important}.mb-lg-auto{margin-bottom:auto !important}.ms-lg-0{margin-left:0 !important}.ms-lg-1{margin-left:.25rem !important}.ms-lg-2{margin-left:.5rem !important}.ms-lg-3{margin-left:1rem !important}.ms-lg-4{margin-left:1.5rem !important}.ms-lg-5{margin-left:3rem !important}.ms-lg-auto{margin-left:auto !important}.p-lg-0{padding:0 !important}.p-lg-1{padding:.25rem !important}.p-lg-2{padding:.5rem !important}.p-lg-3{padding:1rem !important}.p-lg-4{padding:1.5rem !important}.p-lg-5{padding:3rem !important}.px-lg-0{padding-right:0 !important;padding-left:0 !important}.px-lg-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-lg-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-lg-3{padding-right:1rem !important;padding-left:1rem !important}.px-lg-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-lg-5{padding-right:3rem !important;padding-left:3rem !important}.py-lg-0{padding-top:0 !important;padding-bottom:0 !important}.py-lg-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-lg-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-lg-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-lg-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-lg-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-lg-0{padding-top:0 !important}.pt-lg-1{padding-top:.25rem !important}.pt-lg-2{padding-top:.5rem !important}.pt-lg-3{padding-top:1rem !important}.pt-lg-4{padding-top:1.5rem !important}.pt-lg-5{padding-top:3rem !important}.pe-lg-0{padding-right:0 !important}.pe-lg-1{padding-right:.25rem !important}.pe-lg-2{padding-right:.5rem !important}.pe-lg-3{padding-right:1rem !important}.pe-lg-4{padding-right:1.5rem !important}.pe-lg-5{padding-right:3rem !important}.pb-lg-0{padding-bottom:0 !important}.pb-lg-1{padding-bottom:.25rem !important}.pb-lg-2{padding-bottom:.5rem !important}.pb-lg-3{padding-bottom:1rem !important}.pb-lg-4{padding-bottom:1.5rem !important}.pb-lg-5{padding-bottom:3rem !important}.ps-lg-0{padding-left:0 !important}.ps-lg-1{padding-left:.25rem !important}.ps-lg-2{padding-left:.5rem !important}.ps-lg-3{padding-left:1rem !important}.ps-lg-4{padding-left:1.5rem !important}.ps-lg-5{padding-left:3rem !important}}@media (min-width: 1200px){.d-xl-inline{display:inline !important}.d-xl-inline-block{display:inline-block !important}.d-xl-block{display:block !important}.d-xl-grid{display:grid !important}.d-xl-table{display:table !important}.d-xl-table-row{display:table-row !important}.d-xl-table-cell{display:table-cell !important}.d-xl-flex{display:flex !important}.d-xl-inline-flex{display:inline-flex !important}.d-xl-none{display:none !important}.flex-xl-fill{flex:1 1 auto !important}.flex-xl-row{flex-direction:row !important}.flex-xl-column{flex-direction:column !important}.flex-xl-row-reverse{flex-direction:row-reverse !important}.flex-xl-column-reverse{flex-direction:column-reverse !important}.flex-xl-grow-0{flex-grow:0 !important}.flex-xl-grow-1{flex-grow:1 !important}.flex-xl-shrink-0{flex-shrink:0 !important}.flex-xl-shrink-1{flex-shrink:1 !important}.flex-xl-wrap{flex-wrap:wrap !important}.flex-xl-nowrap{flex-wrap:nowrap !important}.flex-xl-wrap-reverse{flex-wrap:wrap-reverse !important}.justify-content-xl-start{justify-content:flex-start !important}.justify-content-xl-end{justify-content:flex-end !important}.justify-content-xl-center{justify-content:center !important}.justify-content-xl-between{justify-content:space-between !important}.justify-content-xl-around{justify-content:space-around !important}.justify-content-xl-evenly{justify-content:space-evenly !important}.align-items-xl-start{align-items:flex-start !important}.align-items-xl-end{align-items:flex-end !important}.align-items-xl-center{align-items:center !important}.align-items-xl-baseline{align-items:baseline !important}.align-items-xl-stretch{align-items:stretch !important}.align-content-xl-start{align-content:flex-start !important}.align-content-xl-end{align-content:flex-end !important}.align-content-xl-center{align-content:center !important}.align-content-xl-between{align-content:space-between !important}.align-content-xl-around{align-content:space-around !important}.align-content-xl-stretch{align-content:stretch !important}.align-self-xl-auto{align-self:auto !important}.align-self-xl-start{align-self:flex-start !important}.align-self-xl-end{align-self:flex-end !important}.align-self-xl-center{align-self:center !important}.align-self-xl-baseline{align-self:baseline !important}.align-self-xl-stretch{align-self:stretch !important}.order-xl-first{order:-1 !important}.order-xl-0{order:0 !important}.order-xl-1{order:1 !important}.order-xl-2{order:2 !important}.order-xl-3{order:3 !important}.order-xl-4{order:4 !important}.order-xl-5{order:5 !important}.order-xl-last{order:6 !important}.m-xl-0{margin:0 !important}.m-xl-1{margin:.25rem !important}.m-xl-2{margin:.5rem !important}.m-xl-3{margin:1rem !important}.m-xl-4{margin:1.5rem !important}.m-xl-5{margin:3rem !important}.m-xl-auto{margin:auto !important}.mx-xl-0{margin-right:0 !important;margin-left:0 !important}.mx-xl-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-xl-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-xl-3{margin-right:1rem !important;margin-left:1rem !important}.mx-xl-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-xl-5{margin-right:3rem !important;margin-left:3rem !important}.mx-xl-auto{margin-right:auto !important;margin-left:auto !important}.my-xl-0{margin-top:0 !important;margin-bottom:0 !important}.my-xl-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-xl-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-xl-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-xl-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-xl-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-xl-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-xl-0{margin-top:0 !important}.mt-xl-1{margin-top:.25rem !important}.mt-xl-2{margin-top:.5rem !important}.mt-xl-3{margin-top:1rem !important}.mt-xl-4{margin-top:1.5rem !important}.mt-xl-5{margin-top:3rem !important}.mt-xl-auto{margin-top:auto !important}.me-xl-0{margin-right:0 !important}.me-xl-1{margin-right:.25rem !important}.me-xl-2{margin-right:.5rem !important}.me-xl-3{margin-right:1rem !important}.me-xl-4{margin-right:1.5rem !important}.me-xl-5{margin-right:3rem !important}.me-xl-auto{margin-right:auto !important}.mb-xl-0{margin-bottom:0 !important}.mb-xl-1{margin-bottom:.25rem !important}.mb-xl-2{margin-bottom:.5rem !important}.mb-xl-3{margin-bottom:1rem !important}.mb-xl-4{margin-bottom:1.5rem !important}.mb-xl-5{margin-bottom:3rem !important}.mb-xl-auto{margin-bottom:auto !important}.ms-xl-0{margin-left:0 !important}.ms-xl-1{margin-left:.25rem !important}.ms-xl-2{margin-left:.5rem !important}.ms-xl-3{margin-left:1rem !important}.ms-xl-4{margin-left:1.5rem !important}.ms-xl-5{margin-left:3rem !important}.ms-xl-auto{margin-left:auto !important}.p-xl-0{padding:0 !important}.p-xl-1{padding:.25rem !important}.p-xl-2{padding:.5rem !important}.p-xl-3{padding:1rem !important}.p-xl-4{padding:1.5rem !important}.p-xl-5{padding:3rem !important}.px-xl-0{padding-right:0 !important;padding-left:0 !important}.px-xl-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-xl-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-xl-3{padding-right:1rem !important;padding-left:1rem !important}.px-xl-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-xl-5{padding-right:3rem !important;padding-left:3rem !important}.py-xl-0{padding-top:0 !important;padding-bottom:0 !important}.py-xl-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-xl-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-xl-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-xl-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-xl-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-xl-0{padding-top:0 !important}.pt-xl-1{padding-top:.25rem !important}.pt-xl-2{padding-top:.5rem !important}.pt-xl-3{padding-top:1rem !important}.pt-xl-4{padding-top:1.5rem !important}.pt-xl-5{padding-top:3rem !important}.pe-xl-0{padding-right:0 !important}.pe-xl-1{padding-right:.25rem !important}.pe-xl-2{padding-right:.5rem !important}.pe-xl-3{padding-right:1rem !important}.pe-xl-4{padding-right:1.5rem !important}.pe-xl-5{padding-right:3rem !important}.pb-xl-0{padding-bottom:0 !important}.pb-xl-1{padding-bottom:.25rem !important}.pb-xl-2{padding-bottom:.5rem !important}.pb-xl-3{padding-bottom:1rem !important}.pb-xl-4{padding-bottom:1.5rem !important}.pb-xl-5{padding-bottom:3rem !important}.ps-xl-0{padding-left:0 !important}.ps-xl-1{padding-left:.25rem !important}.ps-xl-2{padding-left:.5rem !important}.ps-xl-3{padding-left:1rem !important}.ps-xl-4{padding-left:1.5rem !important}.ps-xl-5{padding-left:3rem !important}}@media (min-width: 1400px){.d-xxl-inline{display:inline !important}.d-xxl-inline-block{display:inline-block !important}.d-xxl-block{display:block !important}.d-xxl-grid{display:grid !important}.d-xxl-table{display:table !important}.d-xxl-table-row{display:table-row !important}.d-xxl-table-cell{display:table-cell !important}.d-xxl-flex{display:flex !important}.d-xxl-inline-flex{display:inline-flex !important}.d-xxl-none{display:none !important}.flex-xxl-fill{flex:1 1 auto !important}.flex-xxl-row{flex-direction:row !important}.flex-xxl-column{flex-direction:column !important}.flex-xxl-row-reverse{flex-direction:row-reverse !important}.flex-xxl-column-reverse{flex-direction:column-reverse !important}.flex-xxl-grow-0{flex-grow:0 !important}.flex-xxl-grow-1{flex-grow:1 !important}.flex-xxl-shrink-0{flex-shrink:0 !important}.flex-xxl-shrink-1{flex-shrink:1 !important}.flex-xxl-wrap{flex-wrap:wrap !important}.flex-xxl-nowrap{flex-wrap:nowrap !important}.flex-xxl-wrap-reverse{flex-wrap:wrap-reverse !important}.justify-content-xxl-start{justify-content:flex-start !important}.justify-content-xxl-end{justify-content:flex-end !important}.justify-content-xxl-center{justify-content:center !important}.justify-content-xxl-between{justify-content:space-between !important}.justify-content-xxl-around{justify-content:space-around !important}.justify-content-xxl-evenly{justify-content:space-evenly !important}.align-items-xxl-start{align-items:flex-start !important}.align-items-xxl-end{align-items:flex-end !important}.align-items-xxl-center{align-items:center !important}.align-items-xxl-baseline{align-items:baseline !important}.align-items-xxl-stretch{align-items:stretch !important}.align-content-xxl-start{align-content:flex-start !important}.align-content-xxl-end{align-content:flex-end !important}.align-content-xxl-center{align-content:center !important}.align-content-xxl-between{align-content:space-between !important}.align-content-xxl-around{align-content:space-around !important}.align-content-xxl-stretch{align-content:stretch !important}.align-self-xxl-auto{align-self:auto !important}.align-self-xxl-start{align-self:flex-start !important}.align-self-xxl-end{align-self:flex-end !important}.align-self-xxl-center{align-self:center !important}.align-self-xxl-baseline{align-self:baseline !important}.align-self-xxl-stretch{align-self:stretch !important}.order-xxl-first{order:-1 !important}.order-xxl-0{order:0 !important}.order-xxl-1{order:1 !important}.order-xxl-2{order:2 !important}.order-xxl-3{order:3 !important}.order-xxl-4{order:4 !important}.order-xxl-5{order:5 !important}.order-xxl-last{order:6 !important}.m-xxl-0{margin:0 !important}.m-xxl-1{margin:.25rem !important}.m-xxl-2{margin:.5rem !important}.m-xxl-3{margin:1rem !important}.m-xxl-4{margin:1.5rem !important}.m-xxl-5{margin:3rem !important}.m-xxl-auto{margin:auto !important}.mx-xxl-0{margin-right:0 !important;margin-left:0 !important}.mx-xxl-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-xxl-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-xxl-3{margin-right:1rem !important;margin-left:1rem !important}.mx-xxl-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-xxl-5{margin-right:3rem !important;margin-left:3rem !important}.mx-xxl-auto{margin-right:auto !important;margin-left:auto !important}.my-xxl-0{margin-top:0 !important;margin-bottom:0 !important}.my-xxl-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-xxl-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-xxl-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-xxl-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-xxl-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-xxl-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-xxl-0{margin-top:0 !important}.mt-xxl-1{margin-top:.25rem !important}.mt-xxl-2{margin-top:.5rem !important}.mt-xxl-3{margin-top:1rem !important}.mt-xxl-4{margin-top:1.5rem !important}.mt-xxl-5{margin-top:3rem !important}.mt-xxl-auto{margin-top:auto !important}.me-xxl-0{margin-right:0 !important}.me-xxl-1{margin-right:.25rem !important}.me-xxl-2{margin-right:.5rem !important}.me-xxl-3{margin-right:1rem !important}.me-xxl-4{margin-right:1.5rem !important}.me-xxl-5{margin-right:3rem !important}.me-xxl-auto{margin-right:auto !important}.mb-xxl-0{margin-bottom:0 !important}.mb-xxl-1{margin-bottom:.25rem !important}.mb-xxl-2{margin-bottom:.5rem !important}.mb-xxl-3{margin-bottom:1rem !important}.mb-xxl-4{margin-bottom:1.5rem !important}.mb-xxl-5{margin-bottom:3rem !important}.mb-xxl-auto{margin-bottom:auto !important}.ms-xxl-0{margin-left:0 !important}.ms-xxl-1{margin-left:.25rem !important}.ms-xxl-2{margin-left:.5rem !important}.ms-xxl-3{margin-left:1rem !important}.ms-xxl-4{margin-left:1.5rem !important}.ms-xxl-5{margin-left:3rem !important}.ms-xxl-auto{margin-left:auto !important}.p-xxl-0{padding:0 !important}.p-xxl-1{padding:.25rem !important}.p-xxl-2{padding:.5rem !important}.p-xxl-3{padding:1rem !important}.p-xxl-4{padding:1.5rem !important}.p-xxl-5{padding:3rem !important}.px-xxl-0{padding-right:0 !important;padding-left:0 !important}.px-xxl-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-xxl-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-xxl-3{padding-right:1rem !important;padding-left:1rem !important}.px-xxl-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-xxl-5{padding-right:3rem !important;padding-left:3rem !important}.py-xxl-0{padding-top:0 !important;padding-bottom:0 !important}.py-xxl-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-xxl-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-xxl-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-xxl-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-xxl-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-xxl-0{padding-top:0 !important}.pt-xxl-1{padding-top:.25rem !important}.pt-xxl-2{padding-top:.5rem !important}.pt-xxl-3{padding-top:1rem !important}.pt-xxl-4{padding-top:1.5rem !important}.pt-xxl-5{padding-top:3rem !important}.pe-xxl-0{padding-right:0 !important}.pe-xxl-1{padding-right:.25rem !important}.pe-xxl-2{padding-right:.5rem !important}.pe-xxl-3{padding-right:1rem !important}.pe-xxl-4{padding-right:1.5rem !important}.pe-xxl-5{padding-right:3rem !important}.pb-xxl-0{padding-bottom:0 !important}.pb-xxl-1{padding-bottom:.25rem !important}.pb-xxl-2{padding-bottom:.5rem !important}.pb-xxl-3{padding-bottom:1rem !important}.pb-xxl-4{padding-bottom:1.5rem !important}.pb-xxl-5{padding-bottom:3rem !important}.ps-xxl-0{padding-left:0 !important}.ps-xxl-1{padding-left:.25rem !important}.ps-xxl-2{padding-left:.5rem !important}.ps-xxl-3{padding-left:1rem !important}.ps-xxl-4{padding-left:1.5rem !important}.ps-xxl-5{padding-left:3rem !important}}@media print{.d-print-inline{display:inline !important}.d-print-inline-block{display:inline-block !important}.d-print-block{display:block !important}.d-print-grid{display:grid !important}.d-print-table{display:table !important}.d-print-table-row{display:table-row !important}.d-print-table-cell{display:table-cell !important}.d-print-flex{display:flex !important}.d-print-inline-flex{display:inline-flex !important}.d-print-none{display:none !important}}.row{--bs-gutter-x: 1.875rem}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:#fff;border:1px solid #dee2e6;border-radius:.25rem;max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:.875em;color:#6c757d}.list-group{display:flex;flex-direction:column;padding-left:0;margin-bottom:0;border-radius:0}.list-group-numbered{list-style-type:none;counter-reset:section}.list-group-numbered>li::before{content:counters(section, ".") ". ";counter-increment:section}.list-group-item-action{width:100%;color:var(--t42-content-color);text-align:inherit}.list-group-item-action:hover,.list-group-item-action:focus{z-index:1;color:var(--t42-link-hover-color);text-decoration:none;background-color:var(--t42-link-hover-bg)}.list-group-item-action:active{color:var(--t42-link-hover-color);background-color:var(--t42-link-active-bg)}.list-group-item{position:relative;display:block;padding:.75rem 1.25rem;color:inherit;text-decoration:none;background-color:Rgb(var(--t42-bg-mid));border:1px solid rgba(0,0,0,0)}.list-group-item:first-child{border-top-left-radius:inherit;border-top-right-radius:inherit}.list-group-item:last-child{border-bottom-right-radius:inherit;border-bottom-left-radius:inherit}.list-group-item.disabled,.list-group-item:disabled{color:var(--t42-content-color-disabled);pointer-events:none;background-color:rgba(0,0,0,0)}.list-group-item.active{z-index:2;color:var(--t42-link-hover-color);background-color:var(--t42-link-active-bg);border-color:rgba(0,0,0,0)}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{margin-top:-1px;border-top-width:1px}.list-group-horizontal{flex-direction:row}.list-group-horizontal>.list-group-item:first-child{border-bottom-left-radius:0;border-top-right-radius:0}.list-group-horizontal>.list-group-item:last-child{border-top-right-radius:0;border-bottom-left-radius:0}.list-group-horizontal>.list-group-item.active{margin-top:0}.list-group-horizontal>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}@media (min-width: 576px){.list-group-horizontal-sm{flex-direction:row}.list-group-horizontal-sm>.list-group-item:first-child{border-bottom-left-radius:0;border-top-right-radius:0}.list-group-horizontal-sm>.list-group-item:last-child{border-top-right-radius:0;border-bottom-left-radius:0}.list-group-horizontal-sm>.list-group-item.active{margin-top:0}.list-group-horizontal-sm>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-sm>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width: 768px){.list-group-horizontal-md{flex-direction:row}.list-group-horizontal-md>.list-group-item:first-child{border-bottom-left-radius:0;border-top-right-radius:0}.list-group-horizontal-md>.list-group-item:last-child{border-top-right-radius:0;border-bottom-left-radius:0}.list-group-horizontal-md>.list-group-item.active{margin-top:0}.list-group-horizontal-md>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-md>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width: 992px){.list-group-horizontal-lg{flex-direction:row}.list-group-horizontal-lg>.list-group-item:first-child{border-bottom-left-radius:0;border-top-right-radius:0}.list-group-horizontal-lg>.list-group-item:last-child{border-top-right-radius:0;border-bottom-left-radius:0}.list-group-horizontal-lg>.list-group-item.active{margin-top:0}.list-group-horizontal-lg>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-lg>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width: 1200px){.list-group-horizontal-xl{flex-direction:row}.list-group-horizontal-xl>.list-group-item:first-child{border-bottom-left-radius:0;border-top-right-radius:0}.list-group-horizontal-xl>.list-group-item:last-child{border-top-right-radius:0;border-bottom-left-radius:0}.list-group-horizontal-xl>.list-group-item.active{margin-top:0}.list-group-horizontal-xl>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-xl>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width: 1400px){.list-group-horizontal-xxl{flex-direction:row}.list-group-horizontal-xxl>.list-group-item:first-child{border-bottom-left-radius:0;border-top-right-radius:0}.list-group-horizontal-xxl>.list-group-item:last-child{border-top-right-radius:0;border-bottom-left-radius:0}.list-group-horizontal-xxl>.list-group-item.active{margin-top:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}.list-group-flush{border-radius:0}.list-group-flush>.list-group-item{border-width:0 0 1px}.list-group-flush>.list-group-item:last-child{border-bottom-width:0}.list-group-item-primary{color:#004a89;background-color:#cce5fa}.list-group-item-primary.list-group-item-action:hover,.list-group-item-primary.list-group-item-action:focus{color:#004a89;background-color:#b8cee1}.list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#004a89;border-color:#004a89}.list-group-item-secondary{color:#3a3a3a;background-color:#dfdfdf}.list-group-item-secondary.list-group-item-action:hover,.list-group-item-secondary.list-group-item-action:focus{color:#3a3a3a;background-color:#c9c9c9}.list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#3a3a3a;border-color:#3a3a3a}.list-group-item-success{color:#28602b;background-color:#d9ecda}.list-group-item-success.list-group-item-action:hover,.list-group-item-success.list-group-item-action:focus{color:#28602b;background-color:#c3d4c4}.list-group-item-success.list-group-item-action.active{color:#fff;background-color:#28602b;border-color:#28602b}.list-group-item-info{color:#2a5f6f;background-color:#daecf1}.list-group-item-info.list-group-item-action:hover,.list-group-item-info.list-group-item-action:focus{color:#2a5f6f;background-color:#c4d4d9}.list-group-item-info.list-group-item-action.active{color:#fff;background-color:#2a5f6f;border-color:#2a5f6f}.list-group-item-warning{color:#64430f;background-color:#feeed3}.list-group-item-warning.list-group-item-action:hover,.list-group-item-warning.list-group-item-action:focus{color:#64430f;background-color:#e5d6be}.list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#64430f;border-color:#64430f}.list-group-item-danger{color:#993113;background-color:#ffdcd2}.list-group-item-danger.list-group-item-action:hover,.list-group-item-danger.list-group-item-action:focus{color:#993113;background-color:#e6c6bd}.list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#993113;border-color:#993113}.list-group-item-light{color:#3a3a3a;background-color:#dfdfdf}.list-group-item-light.list-group-item-action:hover,.list-group-item-light.list-group-item-action:focus{color:#3a3a3a;background-color:#c9c9c9}.list-group-item-light.list-group-item-action.active{color:#fff;background-color:#3a3a3a;border-color:#3a3a3a}.list-group-item-dark{color:#3a3a3a;background-color:#dfdfdf}.list-group-item-dark.list-group-item-action:hover,.list-group-item-dark.list-group-item-action:focus{color:#3a3a3a;background-color:#c9c9c9}.list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#3a3a3a;border-color:#3a3a3a}.list-unstyled{padding-left:0;list-style:none}.list-group{box-shadow:var(--t42-shadow)}.list-group-item{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:color;margin-bottom:0;border:0;border-bottom:var(--t42-border);backdrop-filter:var(--backdrop-filter)}.list-group-item:last-child{border-bottom:transparent}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{margin-top:0;border-top-width:0}.list-group-item-action{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background,color;transition-duration:0.25s}.list-group-item-action:hover,.list-group-item-action:focus{background-color:var(--t42-list-group-hover-bg-special)}.list-group-item-action.active:hover{background-color:var(--t42-color-opacity-05)}.modal{position:fixed;top:0;left:0;z-index:1055;display:none;width:100%;height:100%;overflow-x:hidden;overflow-y:auto;outline:0}.modal-dialog{position:relative;width:auto;margin:.5rem;pointer-events:none}.modal.fade .modal-dialog{transition:transform 0.3s ease-out;transform:translate(0, -50px)}@media (prefers-reduced-motion: reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{transform:none}.modal.modal-static .modal-dialog{transform:scale(1.02)}.modal-dialog-scrollable{height:calc(100% - 1rem)}.modal-dialog-scrollable .modal-content{max-height:100%;overflow:hidden}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{display:flex;align-items:center;min-height:calc(100% - 1rem)}.modal-content{position:relative;display:flex;flex-direction:column;width:100%;pointer-events:auto;background-color:var(--t42-modal-bg);background-clip:padding-box;border:.0625rem solid var(--t42-color-opacity-10);border-radius:0;outline:0}.modal-backdrop{position:fixed;top:0;left:0;z-index:1050;width:100vw;height:100vh;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:.5}.modal-header{display:flex;flex-shrink:0;align-items:center;justify-content:space-between;padding:1rem 1rem;border-bottom:.0625rem solid rgba(0,0,0,0);border-top-left-radius:0;border-top-right-radius:0}.modal-header .btn-close{padding:.5rem .5rem;margin:-.5rem -.5rem -.5rem auto}.modal-title{margin-bottom:0;line-height:1.5}.modal-body{position:relative;flex:1 1 auto;padding:1rem}.modal-footer{display:flex;flex-wrap:wrap;flex-shrink:0;align-items:center;justify-content:flex-end;padding:.75rem;border-top:.0625rem solid rgba(0,0,0,0);border-bottom-right-radius:0;border-bottom-left-radius:0}.modal-footer>*{margin:.25rem}@media (min-width: 576px){.modal-dialog{max-width:500px;margin:1.75rem auto}.modal-dialog-scrollable{height:calc(100% - 3.5rem)}.modal-dialog-centered{min-height:calc(100% - 3.5rem)}.modal-sm{max-width:300px}}@media (min-width: 992px){.modal-lg,.modal-xl{max-width:800px}}@media (min-width: 1200px){.modal-xl{max-width:1140px}}.modal-fullscreen{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen .modal-header{border-radius:0}.modal-fullscreen .modal-body{overflow-y:auto}.modal-fullscreen .modal-footer{border-radius:0}@media (max-width: 575.98px){.modal-fullscreen-sm-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-sm-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-sm-down .modal-header{border-radius:0}.modal-fullscreen-sm-down .modal-body{overflow-y:auto}.modal-fullscreen-sm-down .modal-footer{border-radius:0}}@media (max-width: 767.98px){.modal-fullscreen-md-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-md-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-md-down .modal-header{border-radius:0}.modal-fullscreen-md-down .modal-body{overflow-y:auto}.modal-fullscreen-md-down .modal-footer{border-radius:0}}@media (max-width: 991.98px){.modal-fullscreen-lg-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-lg-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-lg-down .modal-header{border-radius:0}.modal-fullscreen-lg-down .modal-body{overflow-y:auto}.modal-fullscreen-lg-down .modal-footer{border-radius:0}}@media (max-width: 1199.98px){.modal-fullscreen-xl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xl-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-xl-down .modal-header{border-radius:0}.modal-fullscreen-xl-down .modal-body{overflow-y:auto}.modal-fullscreen-xl-down .modal-footer{border-radius:0}}@media (max-width: 1399.98px){.modal-fullscreen-xxl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xxl-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-xxl-down .modal-header{border-radius:0}.modal-fullscreen-xxl-down .modal-body{overflow-y:auto}.modal-fullscreen-xxl-down .modal-footer{border-radius:0}}.modal{backdrop-filter:var(--backdrop-filter)}.modal .btn-close{font-size:1.25rem;background-size:0.75rem;filter:var(--filter-close)}.modal-content{border-top:0;background:linear-gradient(to bottom right, Rgba(var(--t42-bg-light), 0.75) 0%, Rgba(var(--t42-bg-dark), 0.75) 100%);box-shadow:var(--t42-shadow)}.modal-content::before{display:block;height:0.0625rem;background:linear-gradient(90deg, #007be5 0%, rgba(0,123,229,0.5) 100%);content:""}.modal-body{padding:0 1rem}.modal-body p:last-child{margin-bottom:0}.modal-sm .modal-footer{flex-direction:column}.modal-sm .modal-footer .btn{width:100%}.modal-sm .modal-footer .btn:not(:last-of-type){margin-bottom:0.5rem}.modal-fill-in{background-color:Rgba(var(--t42-bg-light), 0.75)}.modal-fill-in.modal-dialog{display:flex;flex-flow:column nowrap;align-content:center;align-items:center;justify-content:center;width:auto;max-width:100%;height:100%;margin:0 auto}.modal-fill-in .modal-content{display:flex;max-width:600px;border-color:transparent;background:transparent;background-color:transparent;box-shadow:none;backdrop-filter:none;pointer-events:auto}.modal-fill-in .modal-content::before{display:none}.modal-fill-in::before{position:fixed;top:0;right:0;left:0;display:block;height:0.0625rem;background:linear-gradient(90deg, #007be5 0%, rgba(0,123,229,0.5) 100%);content:""}.modal-fill-in.modal-lg .modal-content{max-width:800px}.modal-fill-in.modal-sm .modal-content{max-width:300px}.nav{display:flex;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:.45rem 1rem;color:var(--t42-link-color);text-decoration:none;transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.nav-link{transition:none}}.nav-link:hover,.nav-link:focus{color:var(--t42-link-hover-color)}.nav-link.disabled{color:var(--t42-content-color-disabled);pointer-events:none;cursor:default}.nav-tabs{border-bottom:.0625rem solid var(--t42-color-opacity-10)}.nav-tabs .nav-link{margin-bottom:-.0625rem;background:none;border:.0625rem solid transparent;border-top-left-radius:0;border-top-right-radius:0}.nav-tabs .nav-link:hover,.nav-tabs .nav-link:focus{border-color:transparent transparent var(--t42-color-opacity-10);isolation:isolate}.nav-tabs .nav-link.disabled{color:var(--t42-content-color-disabled);background-color:transparent;border-color:transparent}.nav-tabs .nav-link.active,.nav-tabs .nav-item.show .nav-link{color:var(--t42-link-hover-color);background-color:var(--t42-link-active-bg);border-color:transparent transparent #007be5}.nav-tabs .dropdown-menu{margin-top:-.0625rem;border-top-left-radius:0;border-top-right-radius:0}.nav-pills .nav-link{background:none;border:0;border-radius:.25rem}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:var(--t42-link-hover-color);background-color:var(--t42-link-active-bg)}.nav-fill>.nav-link,.nav-fill .nav-item{flex:1 1 auto;text-align:center}.nav-justified>.nav-link,.nav-justified .nav-item{flex-basis:0;flex-grow:1;text-align:center}.nav-fill .nav-item .nav-link,.nav-justified .nav-item .nav-link{width:100%}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-link{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, border-color, color;margin-right:3px;border:.0625rem solid transparent}.nav-link:not(.disabled):not(:disabled):focus,.nav-link:not(.disabled):not(:disabled):active,.nav-link:not(.disabled):not(:disabled).active,.nav-link:not(.disabled):not(:disabled):hover{border-color:var(--t42-color-opacity-10);color:var(--t42-link-color);background-color:var(--t42-link-hover-bg)}.nav-link.dropdown-toggle::after{right:-0.125rem}.navbar-nav .nav-item{bottom:-1px}.navbar-nav .nav-item .nav-link{border-bottom:0}.navbar-nav .nav-item:not(.disabled):not(:disabled):focus .nav-link,.navbar-nav .nav-item:not(.disabled):not(:disabled):active .nav-link,.navbar-nav .nav-item:not(.disabled):not(:disabled).active .nav-link,.navbar-nav .nav-item:not(.disabled):not(:disabled):hover .nav-link{border-color:var(--t42-color-opacity-10)}.nav.flex-column .nav-link{margin-bottom:3px}.nav-tabs .nav-link{position:relative;display:flex;align-items:center;height:2rem}.nav-tabs .nav-link::before{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:height;position:absolute;bottom:-2px;left:-1px;width:calc(100% + 2px);height:0;background-color:var(--primary);content:""}.nav-tabs .nav-link.active::before{height:3px}.nav-tabs .nav-link.active:hover::before{height:0}.nav-tabs .nav-link .btn-close{width:0.5rem;height:0.5rem}.nav-tabs .nav-item{margin-right:0}.nav-tabs .dropdown.show .dropdown-toggle{border-color:transparent}.nav-tabs.flex-column .nav-link.active:hover::before{width:0}.nav-tabs.flex-column .nav-link::before{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:width;top:-1px;width:0;height:100%;margin-left:0;background-color:var(--primary);content:""}.nav-tabs.flex-column .nav-link.active::before{width:3px;height:calc(100% + 2px)}.nav-pills .nav-link{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;width:100%;padding:0.25rem 1rem;border:1px solid transparent;border-radius:1rem}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{position:relative;border-color:transparent}.nav-pills .nav-item{margin-right:3px}.nav-pills .nav-item:last-child{margin-right:0}.nav-pills .nav-link.active:not(.dropdown-toggle),.nav-pills .show>.nav-link:not(.dropdown-toggle){padding:0.25rem 1.75rem 0.25rem 1rem}.nav-pills .nav-link.active:not(.dropdown-toggle)::before,.nav-pills .show>.nav-link:not(.dropdown-toggle)::before{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:right;position:absolute;top:50%;right:10px;width:8px;height:8px;border-radius:50%;background-color:var(--primary);transform:translateY(-50%);content:""}.nav-pills .nav-link.active:not(.dropdown-toggle):hover::before,.nav-pills .show>.nav-link:not(.dropdown-toggle):hover::before{right:-10px}.nav-justified .nav-item .nav-link::before{right:1px;left:-1px;margin-left:0}.tab-content{padding-top:0.5rem}.nav-action-buttons .nav-link{position:relative;padding:0.45rem 1.5rem 0.45rem 1rem}.nav-action-buttons .icon-cancel::before{display:block;width:1rem;height:1rem;background-color:var(--t42-content-color);content:"";-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M366.854,336.384c6.14398,6.14398,9.216,13.48267,9.216,22.01599s-3.07202,15.87198-9.216,22.01599 c-6.14398,5.46133-13.48267,8.19202-22.01599,8.19199c-8.53333,0.00003-15.87201-2.73065-22.01602-8.19199l-67.584-77.82401 l-67.584,77.82401c-6.144,5.46133-13.48267,8.19202-22.01601,8.19199c-8.53333,0.00003-15.87199-2.73065-22.01599-8.19199 c-5.46133-6.14401-8.192-13.48267-8.192-22.01599s2.73067-15.87201,8.192-22.01599l70.65599-79.87201l-70.65601-80.896 c-5.46132-6.144-8.19199-13.48268-8.19199-22.01601c0-8.53334,2.73067-15.87201,8.19199-22.01601 c6.14401-5.46133,13.48267-8.19199,22.01601-8.192c8.53334,0.00001,15.87201,2.73067,22.01601,8.192l67.584,77.82401 l67.584-77.82401c6.14401-5.46133,13.4827-8.19199,22.01602-8.192c8.53333,0.00001,15.87201,2.73067,22.01599,8.192 c6.14398,6.144,9.216,13.48267,9.216,22.01601c0,8.53333-3.07202,15.87201-9.216,22.01601l-70.65601,80.896L366.854,336.384z%27/%3E%3C/svg%3E")}.navbar{position:relative;display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;padding-top:0;padding-right:.875rem;padding-bottom:0;padding-left:.875rem}.navbar>.container,.navbar>.container-fluid,.navbar>.container-sm,.navbar>.container-md,.navbar>.container-lg,.navbar>.container-xl,.navbar>.container-xxl{display:flex;flex-wrap:inherit;align-items:center;justify-content:space-between}.navbar-brand{padding-top:.075rem;padding-bottom:.075rem;margin-right:1rem;font-size:1.25rem;text-decoration:none;white-space:nowrap}.navbar-nav{display:flex;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-nav .dropdown-menu{position:static}.navbar-text{padding-top:.45rem;padding-bottom:.45rem}.navbar-collapse{flex-basis:100%;flex-grow:1;align-items:center}.navbar-toggler{padding:0 0;font-size:.9375rem;line-height:1;background-color:transparent;border:1px solid transparent;border-radius:0;transition:box-shadow 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.navbar-toggler{transition:none}}.navbar-toggler:hover{text-decoration:none}.navbar-toggler:focus{text-decoration:none;outline:0;box-shadow:0 0 0 0}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;background-repeat:no-repeat;background-position:center;background-size:100%}.navbar-nav-scroll{max-height:var(--bs-scroll-height, 75vh);overflow-y:auto}@media (min-width: 576px){.navbar-expand-sm{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-sm .navbar-nav{flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm .navbar-nav-scroll{overflow:visible}.navbar-expand-sm .navbar-collapse{display:flex !important;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}.navbar-expand-sm .offcanvas-header{display:none}.navbar-expand-sm .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;visibility:visible !important;background-color:transparent;border-right:0;border-left:0;transition:none;transform:none}.navbar-expand-sm .offcanvas-top,.navbar-expand-sm .offcanvas-bottom{height:auto;border-top:0;border-bottom:0}.navbar-expand-sm .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width: 768px){.navbar-expand-md{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-md .navbar-nav{flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-md .navbar-nav-scroll{overflow:visible}.navbar-expand-md .navbar-collapse{display:flex !important;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}.navbar-expand-md .offcanvas-header{display:none}.navbar-expand-md .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;visibility:visible !important;background-color:transparent;border-right:0;border-left:0;transition:none;transform:none}.navbar-expand-md .offcanvas-top,.navbar-expand-md .offcanvas-bottom{height:auto;border-top:0;border-bottom:0}.navbar-expand-md .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width: 992px){.navbar-expand-lg{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-lg .navbar-nav{flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-lg .navbar-nav-scroll{overflow:visible}.navbar-expand-lg .navbar-collapse{display:flex !important;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}.navbar-expand-lg .offcanvas-header{display:none}.navbar-expand-lg .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;visibility:visible !important;background-color:transparent;border-right:0;border-left:0;transition:none;transform:none}.navbar-expand-lg .offcanvas-top,.navbar-expand-lg .offcanvas-bottom{height:auto;border-top:0;border-bottom:0}.navbar-expand-lg .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width: 1200px){.navbar-expand-xl{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-xl .navbar-nav{flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xl .navbar-nav-scroll{overflow:visible}.navbar-expand-xl .navbar-collapse{display:flex !important;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}.navbar-expand-xl .offcanvas-header{display:none}.navbar-expand-xl .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;visibility:visible !important;background-color:transparent;border-right:0;border-left:0;transition:none;transform:none}.navbar-expand-xl .offcanvas-top,.navbar-expand-xl .offcanvas-bottom{height:auto;border-top:0;border-bottom:0}.navbar-expand-xl .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width: 1400px){.navbar-expand-xxl{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-xxl .navbar-nav{flex-direction:row}.navbar-expand-xxl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xxl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xxl .navbar-nav-scroll{overflow:visible}.navbar-expand-xxl .navbar-collapse{display:flex !important;flex-basis:auto}.navbar-expand-xxl .navbar-toggler{display:none}.navbar-expand-xxl .offcanvas-header{display:none}.navbar-expand-xxl .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;visibility:visible !important;background-color:transparent;border-right:0;border-left:0;transition:none;transform:none}.navbar-expand-xxl .offcanvas-top,.navbar-expand-xxl .offcanvas-bottom{height:auto;border-top:0;border-bottom:0}.navbar-expand-xxl .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}.navbar-expand{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand .navbar-nav{flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand .navbar-nav-scroll{overflow:visible}.navbar-expand .navbar-collapse{display:flex !important;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-expand .offcanvas-header{display:none}.navbar-expand .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;visibility:visible !important;background-color:transparent;border-right:0;border-left:0;transition:none;transform:none}.navbar-expand .offcanvas-top,.navbar-expand .offcanvas-bottom{height:auto;border-top:0;border-bottom:0}.navbar-expand .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}.navbar-light .navbar-brand{color:var(--t42-link-color)}.navbar-light .navbar-brand:hover,.navbar-light .navbar-brand:focus{color:var(--t42-link-hover-color)}.navbar-light .navbar-nav .nav-link{color:var(--t42-link-color)}.navbar-light .navbar-nav .nav-link:hover,.navbar-light .navbar-nav .nav-link:focus{color:var(--t42-link-hover-color)}.navbar-light .navbar-nav .nav-link.disabled{color:var(--t42-content-color-disabled)}.navbar-light .navbar-nav .show>.nav-link,.navbar-light .navbar-nav .nav-link.active{color:var(--t42-link-hover-color)}.navbar-light .navbar-toggler{color:var(--t42-link-color);border-color:rgba(0,0,0,0.1)}.navbar-light .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 30 30%27%3e%3cpath stroke=%27var%28--t42-link-color%29%27 stroke-linecap=%27round%27 stroke-miterlimit=%2710%27 stroke-width=%272%27 d=%27M4 7h22M4 15h22M4 23h22%27/%3e%3c/svg%3e")}.navbar-light .navbar-text{color:var(--t42-link-color)}.navbar-light .navbar-text a,.navbar-light .navbar-text a:hover,.navbar-light .navbar-text a:focus{color:var(--t42-link-hover-color)}.navbar-dark .navbar-brand{color:var(--t42-link-color)}.navbar-dark .navbar-brand:hover,.navbar-dark .navbar-brand:focus{color:var(--t42-link-hover-color)}.navbar-dark .navbar-nav .nav-link{color:var(--t42-link-color)}.navbar-dark .navbar-nav .nav-link:hover,.navbar-dark .navbar-nav .nav-link:focus{color:var(--t42-link-hover-color)}.navbar-dark .navbar-nav .nav-link.disabled{color:var(--t42-content-color-disabled)}.navbar-dark .navbar-nav .show>.nav-link,.navbar-dark .navbar-nav .nav-link.active{color:var(--t42-link-hover-color)}.navbar-dark .navbar-toggler{color:var(--t42-link-color);border-color:rgba(255,255,255,0.1)}.navbar-dark .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 30 30%27%3e%3cpath stroke=%27var%28--t42-link-color%29%27 stroke-linecap=%27round%27 stroke-miterlimit=%2710%27 stroke-width=%272%27 d=%27M4 7h22M4 15h22M4 23h22%27/%3e%3c/svg%3e")}.navbar-dark .navbar-text{color:var(--t42-link-color)}.navbar-dark .navbar-text a,.navbar-dark .navbar-text a:hover,.navbar-dark .navbar-text a:focus{color:var(--t42-link-hover-color)}.navbar{border-bottom:var(--t42-border);background-color:Rgba(var(--t42-bg-mid), 0.75);backdrop-filter:var(--backdrop-filter)}.navbar-dark{background-color:Rgba(var(--t42-bg-dark), 0.75)}.navbar-light{background-color:Rgba(var(--t42-bg-light), 0.75)}.navbar .nav-item{position:relative}.navbar .nav-item.show:focus .nav-link:not(.disabled):not(:disabled),.navbar .nav-item.show:active .nav-link:not(.disabled):not(:disabled),.navbar .nav-item.show.active .nav-link:not(.disabled):not(:disabled),.navbar .nav-item:not(.disabled):not(:disabled):focus .nav-link:not(.disabled):not(:disabled),.navbar .nav-item:not(.disabled):not(:disabled):active .nav-link:not(.disabled):not(:disabled),.navbar .nav-item:not(.disabled):not(:disabled).active .nav-link:not(.disabled):not(:disabled){color:var(--t42-link-color);background-color:var(--t42-color-opacity-10)}.navbar .nav-item.show:hover .nav-link:not(.disabled):not(:disabled),.navbar .nav-item:not(.disabled):not(:disabled):hover .nav-link:not(.disabled):not(:disabled){color:var(--t42-link-color);background-color:var(--t42-color-opacity-05)}.navbar .nav-link{padding-right:.875rem;padding-left:.875rem}.navbar .btn-group{height:100%;padding-left:.875rem;border-left:var(--t42-border)}.pagination{display:flex;padding-left:0;list-style:none}.page-link{position:relative;display:block;color:var(--t42-content-color);text-decoration:none;background-color:rgba(0,0,0,0);border:0 solid rgba(0,0,0,0);transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.page-link{transition:none}}.page-link:hover{z-index:2;color:var(--t42-link-hover-color);background-color:var(--t42-link-hover-bg);border-color:#dee2e6}.page-link:focus{z-index:3;color:var(--t42-link-hover-color);background-color:rgba(0,0,0,0);outline:0;box-shadow:0 0 0 0 rgba(0,123,229,0.25)}.page-item:not(:first-child) .page-link{margin-left:0}.page-item.active .page-link{z-index:3;color:var(--white);background-color:var(--primary);border-color:var(--primary)}.page-item.disabled .page-link{color:var(--t42-content-color-disabled);pointer-events:none;background-color:rgba(0,0,0,0);border-color:#dee2e6}.page-link{padding:.125rem .5rem}.page-item:first-child .page-link{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.page-item:last-child .page-link{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.pagination-lg .page-link{padding:.75rem 1.5rem;font-size:.9375rem}.pagination-lg .page-item:first-child .page-link{border-top-left-radius:1rem;border-bottom-left-radius:1rem}.pagination-lg .page-item:last-child .page-link{border-top-right-radius:1rem;border-bottom-right-radius:1rem}.pagination-sm .page-link{padding:.25rem .5rem;font-size:.65625rem}.pagination-sm .page-item:first-child .page-link{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.pagination-sm .page-item:last-child .page-link{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.page-link{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, color;display:flex;align-items:center;justify-content:center;min-width:1.5rem;min-height:1.5rem;border-radius:0.25rem;overflow:hidden}.page-link[aria-label="Next"],.page-link[aria-label="Previous"]{padding:0}.page-link[aria-label="Next"] span{background:var(--t42-select-indicator) center center/1rem 1rem no-repeat;transform:rotate(-90deg)}.page-link[aria-label="Previous"] span{background:var(--t42-select-indicator) center center/1rem 1rem no-repeat;transform:rotate(90deg)}.page-link>span{width:100%;height:100%;min-height:1rem;font-size:0;clip:initial}.pagination-lg .page-link[aria-label="Next"],.pagination-lg .page-link[aria-label="Previous"]{padding:0.75rem 1.5rem}.page-item{margin-right:8px}.page-item:first-child .page-link>span:not(.sr-only)::before,.page-item:last-child .page-link>span:not(.sr-only)::before{top:-0.125rem}.page-item.active .page-link:hover,.page-item:active .page-link:hover{background-color:var(--t42-color-opacity-05)}.page-item.active.disabled .page-link{background-color:var(--t42-color-opacity-10)}.popover{position:absolute;top:0;left:0 /* rtl:ignore */;z-index:1070;display:block;max-width:276px;font-family:"Montserrat","Helvetica Neue",Arial,sans-serif;font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.65625rem;word-wrap:break-word;background-color:Rgba(var(--t42-bg-dark), 0.75);background-clip:padding-box;border:1px solid var(--t42-color-opacity-10);border-radius:0}.popover .popover-arrow{position:absolute;display:block;width:1rem;height:.5rem}.popover .popover-arrow::before,.popover .popover-arrow::after{position:absolute;display:block;content:"";border-color:transparent;border-style:solid}.bs-popover-top>.popover-arrow,.bs-popover-auto[data-popper-placement^="top"]>.popover-arrow{bottom:calc(-.5rem - 1px)}.bs-popover-top>.popover-arrow::before,.bs-popover-auto[data-popper-placement^="top"]>.popover-arrow::before{bottom:0;border-width:.5rem .5rem 0;border-top-color:var(--t42-color-opacity-10)}.bs-popover-top>.popover-arrow::after,.bs-popover-auto[data-popper-placement^="top"]>.popover-arrow::after{bottom:1px;border-width:.5rem .5rem 0;border-top-color:var(--t42-color-opacity-10)}.bs-popover-end>.popover-arrow,.bs-popover-auto[data-popper-placement^="right"]>.popover-arrow{left:calc(-.5rem - 1px);width:.5rem;height:1rem}.bs-popover-end>.popover-arrow::before,.bs-popover-auto[data-popper-placement^="right"]>.popover-arrow::before{left:0;border-width:.5rem .5rem .5rem 0;border-right-color:var(--t42-color-opacity-10)}.bs-popover-end>.popover-arrow::after,.bs-popover-auto[data-popper-placement^="right"]>.popover-arrow::after{left:1px;border-width:.5rem .5rem .5rem 0;border-right-color:var(--t42-color-opacity-10)}.bs-popover-bottom>.popover-arrow,.bs-popover-auto[data-popper-placement^="bottom"]>.popover-arrow{top:calc(-.5rem - 1px)}.bs-popover-bottom>.popover-arrow::before,.bs-popover-auto[data-popper-placement^="bottom"]>.popover-arrow::before{top:0;border-width:0 .5rem .5rem .5rem;border-bottom-color:var(--t42-color-opacity-10)}.bs-popover-bottom>.popover-arrow::after,.bs-popover-auto[data-popper-placement^="bottom"]>.popover-arrow::after{top:1px;border-width:0 .5rem .5rem .5rem;border-bottom-color:var(--t42-color-opacity-10)}.bs-popover-bottom .popover-header::before,.bs-popover-auto[data-popper-placement^="bottom"] .popover-header::before{position:absolute;top:0;left:50%;display:block;width:1rem;margin-left:-.5rem;content:"";border-bottom:1px solid Rgba(var(--t42-bg-mid), 0.75)}.bs-popover-start>.popover-arrow,.bs-popover-auto[data-popper-placement^="left"]>.popover-arrow{right:calc(-.5rem - 1px);width:.5rem;height:1rem}.bs-popover-start>.popover-arrow::before,.bs-popover-auto[data-popper-placement^="left"]>.popover-arrow::before{right:0;border-width:.5rem 0 .5rem .5rem;border-left-color:var(--t42-color-opacity-10)}.bs-popover-start>.popover-arrow::after,.bs-popover-auto[data-popper-placement^="left"]>.popover-arrow::after{right:1px;border-width:.5rem 0 .5rem .5rem;border-left-color:var(--t42-color-opacity-10)}.popover-header{padding:.55rem 1rem;margin-bottom:0;font-size:.75rem;color:var(--t42-link-color);background-color:Rgba(var(--t42-bg-mid), 0.75);border-bottom:1px solid var(--t42-color-opacity-10);border-top-left-radius:0;border-top-right-radius:0}.popover-header:empty{display:none}.popover-body{padding:1rem 1rem;color:var(--t42-content-color)}.popover{backdrop-filter:var(--backdrop-filter)}@keyframes progress-bar-stripes{0%{background-position-x:1.063rem}}.progress{display:flex;height:1.063rem;overflow:hidden;font-size:.6rem;background-color:Rgb(var(--t42-bg-mid));border-radius:0}.progress-bar{display:flex;flex-direction:column;justify-content:center;overflow:hidden;color:#fff;text-align:center;white-space:nowrap;background-color:#007be5;transition:width 0.6s ease}@media (prefers-reduced-motion: reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-size:1.063rem 1.063rem}.progress-bar-animated{animation:1s linear infinite progress-bar-stripes}@media (prefers-reduced-motion: reduce){.progress-bar-animated{animation:none}}.progress{border:var(--t42-border)}.table{--bs-table-bg: rgba(0,0,0,0);--bs-table-accent-bg: rgba(0,0,0,0);--bs-table-striped-color: var(--t42-content-color);--bs-table-striped-bg: rgba(0,0,0,0.05);--bs-table-active-color: var(--t42-content-color);--bs-table-active-bg: rgba(0,0,0,0.1);--bs-table-hover-color: var(--t42-link-color);--bs-table-hover-bg: rgba(0,0,0,0.075);width:100%;margin-bottom:1rem;color:var(--t42-content-color);vertical-align:top;border-color:var(--t42-color-opacity-10)}.table>:not(caption)>*>*{padding:.25rem .313rem;background-color:var(--bs-table-bg);border-bottom-width:1px;box-shadow:inset 0 0 0 9999px var(--bs-table-accent-bg)}.table>tbody{vertical-align:inherit}.table>thead{vertical-align:bottom}.table>:not(:first-child){border-top:2px solid currentColor}.caption-top{caption-side:top}.table-sm>:not(caption)>*>*{padding:.25rem .25rem}.table-bordered>:not(caption)>*{border-width:1px 0}.table-bordered>:not(caption)>*>*{border-width:0 1px}.table-borderless>:not(caption)>*>*{border-bottom-width:0}.table-borderless>:not(:first-child){border-top-width:0}.table-striped>tbody>tr:nth-of-type(odd)>*{--bs-table-accent-bg: var(--bs-table-striped-bg);color:var(--bs-table-striped-color)}.table-active{--bs-table-accent-bg: var(--bs-table-active-bg);color:var(--bs-table-active-color)}.table-hover>tbody>tr:hover>*{--bs-table-accent-bg: var(--bs-table-hover-bg);color:var(--bs-table-hover-color)}.table-primary{--bs-table-bg: #cce5fa;--bs-table-striped-bg: #c2daee;--bs-table-striped-color: #000;--bs-table-active-bg: #b8cee1;--bs-table-active-color: #000;--bs-table-hover-bg: #bdd4e7;--bs-table-hover-color: #000;color:#000;border-color:#b8cee1}.table-secondary{--bs-table-bg: #dfdfdf;--bs-table-striped-bg: #d4d4d4;--bs-table-striped-color: #000;--bs-table-active-bg: #c9c9c9;--bs-table-active-color: #000;--bs-table-hover-bg: #cecece;--bs-table-hover-color: #000;color:#000;border-color:#c9c9c9}.table-success{--bs-table-bg: #d9ecda;--bs-table-striped-bg: #cee0cf;--bs-table-striped-color: #000;--bs-table-active-bg: #c3d4c4;--bs-table-active-color: #000;--bs-table-hover-bg: #c9daca;--bs-table-hover-color: #000;color:#000;border-color:#c3d4c4}.table-info{--bs-table-bg: #daecf1;--bs-table-striped-bg: #cfe0e5;--bs-table-striped-color: #000;--bs-table-active-bg: #c4d4d9;--bs-table-active-color: #000;--bs-table-hover-bg: #cadadf;--bs-table-hover-color: #000;color:#000;border-color:#c4d4d9}.table-warning{--bs-table-bg: #feeed3;--bs-table-striped-bg: #f1e2c8;--bs-table-striped-color: #000;--bs-table-active-bg: #e5d6be;--bs-table-active-color: #000;--bs-table-hover-bg: #ebdcc3;--bs-table-hover-color: #000;color:#000;border-color:#e5d6be}.table-danger{--bs-table-bg: #ffdcd2;--bs-table-striped-bg: #f2d1c8;--bs-table-striped-color: #000;--bs-table-active-bg: #e6c6bd;--bs-table-active-color: #000;--bs-table-hover-bg: #ecccc2;--bs-table-hover-color: #000;color:#000;border-color:#e6c6bd}.table-light{--bs-table-bg: #616161;--bs-table-striped-bg: dimgray;--bs-table-striped-color: #fff;--bs-table-active-bg: #717171;--bs-table-active-color: #fff;--bs-table-hover-bg: #6d6d6d;--bs-table-hover-color: #fff;color:#fff;border-color:#717171}.table-dark{--bs-table-bg: #616161;--bs-table-striped-bg: dimgray;--bs-table-striped-color: #fff;--bs-table-active-bg: #717171;--bs-table-active-color: #fff;--bs-table-hover-bg: #6d6d6d;--bs-table-hover-color: #fff;color:#fff;border-color:#717171}.table-responsive{overflow-x:auto;-webkit-overflow-scrolling:touch}@media (max-width: 575.98px){.table-responsive-sm{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width: 767.98px){.table-responsive-md{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width: 991.98px){.table-responsive-lg{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width: 1199.98px){.table-responsive-xl{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width: 1399.98px){.table-responsive-xxl{overflow-x:auto;-webkit-overflow-scrolling:touch}}.table>:not(:first-child){border-width:0}.table td,.table th{white-space:nowrap;vertical-align:middle}.table a{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border;border-bottom:0.063rem dashed var(--dark);color:var(--t42-content-color)}.table a:hover{border-bottom-color:var(--t42-content-color);border-bottom-style:solid;color:var(--t42-link-color);text-decoration:none}.table thead th{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;border-width:1px 0;color:Hsl(var(--t42-content-color-base), calc(var(--t42-content-color-l) - 20%));font-weight:normal;font-size:83.3%;text-transform:uppercase}.table td{position:relative}.table td .btn,.table td .btn-sm,.table td .btn-group-sm>.btn,.table td .btn-lg,.table td .btn-group-lg>.btn{line-height:1.25rem}.table td .btn-icon i{position:relative;top:0.0625rem}.table tr th:first-child,.table tr td:first-child{padding-left:0.5rem}.table tr th:last-child,.table tr td:last-child{padding-right:0.5rem}.table-hover tbody tr:hover{background-color:var(--t42-table-active-bg)}.table-hover tbody tr:hover a{border-bottom-color:var(--t42-content-color);color:var(--t42-link-color)}.table-responsive{border:0}.tooltip{position:absolute;z-index:1080;display:block;margin:0;font-family:"Montserrat","Helvetica Neue",Arial,sans-serif;font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.65625rem;word-wrap:break-word;opacity:0}.tooltip.show{opacity:1}.tooltip .tooltip-arrow{position:absolute;display:block;width:.8rem;height:.4rem}.tooltip .tooltip-arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-top,.bs-tooltip-auto[data-popper-placement^="top"]{padding:.4rem 0}.bs-tooltip-top .tooltip-arrow,.bs-tooltip-auto[data-popper-placement^="top"] .tooltip-arrow{bottom:0}.bs-tooltip-top .tooltip-arrow::before,.bs-tooltip-auto[data-popper-placement^="top"] .tooltip-arrow::before{top:-1px;border-width:.4rem .4rem 0;border-top-color:var(--t42-tooltip-bg)}.bs-tooltip-end,.bs-tooltip-auto[data-popper-placement^="right"]{padding:0 .4rem}.bs-tooltip-end .tooltip-arrow,.bs-tooltip-auto[data-popper-placement^="right"] .tooltip-arrow{left:0;width:.4rem;height:.8rem}.bs-tooltip-end .tooltip-arrow::before,.bs-tooltip-auto[data-popper-placement^="right"] .tooltip-arrow::before{right:-1px;border-width:.4rem .4rem .4rem 0;border-right-color:var(--t42-tooltip-bg)}.bs-tooltip-bottom,.bs-tooltip-auto[data-popper-placement^="bottom"]{padding:.4rem 0}.bs-tooltip-bottom .tooltip-arrow,.bs-tooltip-auto[data-popper-placement^="bottom"] .tooltip-arrow{top:0}.bs-tooltip-bottom .tooltip-arrow::before,.bs-tooltip-auto[data-popper-placement^="bottom"] .tooltip-arrow::before{bottom:-1px;border-width:0 .4rem .4rem;border-bottom-color:var(--t42-tooltip-bg)}.bs-tooltip-start,.bs-tooltip-auto[data-popper-placement^="left"]{padding:0 .4rem}.bs-tooltip-start .tooltip-arrow,.bs-tooltip-auto[data-popper-placement^="left"] .tooltip-arrow{right:0;width:.4rem;height:.8rem}.bs-tooltip-start .tooltip-arrow::before,.bs-tooltip-auto[data-popper-placement^="left"] .tooltip-arrow::before{left:-1px;border-width:.4rem 0 .4rem .4rem;border-left-color:var(--t42-tooltip-bg)}.tooltip-inner{max-width:200px;padding:.25rem 1rem;color:var(--t42-content-color);text-align:center;background-color:var(--t42-tooltip-bg);border-radius:0}.tooltip .tooltip-inner{border:var(--t42-border);box-shadow:var(--t42-shadow)}.bs-tooltip-top .arrow,.bs-tooltip-auto[data-popper-placement^="top"] .arrow{bottom:1px}.bs-tooltip-top .arrow::before,.bs-tooltip-auto[data-popper-placement^="top"] .arrow::before{border-top-color:var(--t42-color-opacity-10)}.bs-tooltip-bottom .arrow,.bs-tooltip-auto[data-popper-placement^="bottom"] .arrow{top:1px}.bs-tooltip-bottom .arrow::before,.bs-tooltip-auto[data-popper-placement^="bottom"] .arrow::before{border-bottom-color:var(--t42-color-opacity-10)}.bs-tooltip-right .arrow{left:1px}.bs-tooltip-right .arrow::before{border-right-color:var(--t42-color-opacity-10)}.bs-tooltip-left .arrow{right:1px}.bs-tooltip-left .arrow::before{border-left-color:var(--t42-color-opacity-10)}.fade{transition:opacity 0.15s linear}@media (prefers-reduced-motion: reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{height:0;overflow:hidden;transition:height 0.35s ease}@media (prefers-reduced-motion: reduce){.collapsing{transition:none}}.collapsing.collapse-horizontal{width:0;height:auto;transition:width 0.35s ease}@media (prefers-reduced-motion: reduce){.collapsing.collapse-horizontal{transition:none}}mark,.mark{color:var(--white)}pre{background-color:var(--t42-bg-dark)}blockquote,.blockquote{padding:1rem 1rem 0.01rem;border-left:0.25rem solid var(--secondary);background-color:Rgb(var(--t42-bg-dark))}.blockquote-footer{margin-top:-2rem;margin-left:1.25rem;color:var(--t42-content-color-muted);font-size:0.875em}.clearfix::after{display:block;clear:both;content:""}.link-primary{color:#007be5}.link-primary:hover,.link-primary:focus{color:#3395ea}.link-secondary{color:#616161}.link-secondary:hover,.link-secondary:focus{color:#4e4e4e}.link-success{color:#43a047}.link-success:hover,.link-success:focus{color:#69b36c}.link-info{color:#469eb9}.link-info:hover,.link-info:focus{color:#6bb1c7}.link-warning{color:#f9a825}.link-warning:hover,.link-warning:focus{color:#fab951}.link-danger{color:#ff511f}.link-danger:hover,.link-danger:focus{color:#ff744c}.link-light{color:#616161}.link-light:hover,.link-light:focus{color:#4e4e4e}.link-dark{color:#616161}.link-dark:hover,.link-dark:focus{color:#4e4e4e}.ratio{position:relative;width:100%}.ratio::before{display:block;padding-top:var(--bs-aspect-ratio);content:""}.ratio>*{position:absolute;top:0;left:0;width:100%;height:100%}.ratio-1x1{--bs-aspect-ratio: 100%}.ratio-4x3{--bs-aspect-ratio: calc(3 / 4 * 100%)}.ratio-16x9{--bs-aspect-ratio: calc(9 / 16 * 100%)}.ratio-21x9{--bs-aspect-ratio: calc(9 / 21 * 100%)}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}.sticky-top{position:sticky;top:0;z-index:1020}@media (min-width: 576px){.sticky-sm-top{position:sticky;top:0;z-index:1020}}@media (min-width: 768px){.sticky-md-top{position:sticky;top:0;z-index:1020}}@media (min-width: 992px){.sticky-lg-top{position:sticky;top:0;z-index:1020}}@media (min-width: 1200px){.sticky-xl-top{position:sticky;top:0;z-index:1020}}@media (min-width: 1400px){.sticky-xxl-top{position:sticky;top:0;z-index:1020}}.hstack{display:flex;flex-direction:row;align-items:center;align-self:stretch}.vstack{display:flex;flex:1 1 auto;flex-direction:column;align-self:stretch}.visually-hidden,.visually-hidden-focusable:not(:focus):not(:focus-within){position:absolute !important;width:1px !important;height:1px !important;padding:0 !important;margin:-1px !important;overflow:hidden !important;clip:rect(0, 0, 0, 0) !important;white-space:nowrap !important;border:0 !important}.stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.vr{display:inline-block;align-self:stretch;width:1px;min-height:1em;background-color:currentColor;opacity:.25}.align-baseline{vertical-align:baseline !important}.align-top{vertical-align:top !important}.align-middle{vertical-align:middle !important}.align-bottom{vertical-align:bottom !important}.align-text-bottom{vertical-align:text-bottom !important}.align-text-top{vertical-align:text-top !important}.float-start{float:left !important}.float-end{float:right !important}.float-none{float:none !important}.opacity-0{opacity:0 !important}.opacity-25{opacity:.25 !important}.opacity-50{opacity:.5 !important}.opacity-75{opacity:.75 !important}.opacity-100{opacity:1 !important}.overflow-auto{overflow:auto !important}.overflow-hidden{overflow:hidden !important}.overflow-visible{overflow:visible !important}.overflow-scroll{overflow:scroll !important}.d-inline{display:inline !important}.d-inline-block{display:inline-block !important}.d-block{display:block !important}.d-grid{display:grid !important}.d-table{display:table !important}.d-table-row{display:table-row !important}.d-table-cell{display:table-cell !important}.d-flex{display:flex !important}.d-inline-flex{display:inline-flex !important}.d-none{display:none !important}.shadow{box-shadow:0 0.5rem 1rem rgba(0,0,0,0.15) !important}.shadow-sm{box-shadow:0 0.125rem 0.25rem rgba(0,0,0,0.075) !important}.shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,0.175) !important}.shadow-none{box-shadow:none !important}.position-static{position:static !important}.position-relative{position:relative !important}.position-absolute{position:absolute !important}.position-fixed{position:fixed !important}.position-sticky{position:sticky !important}.top-0{top:0 !important}.top-50{top:50% !important}.top-100{top:100% !important}.bottom-0{bottom:0 !important}.bottom-50{bottom:50% !important}.bottom-100{bottom:100% !important}.start-0{left:0 !important}.start-50{left:50% !important}.start-100{left:100% !important}.end-0{right:0 !important}.end-50{right:50% !important}.end-100{right:100% !important}.translate-middle{transform:translate(-50%, -50%) !important}.translate-middle-x{transform:translateX(-50%) !important}.translate-middle-y{transform:translateY(-50%) !important}.border{border:1px solid #dee2e6 !important}.border-0{border:0 !important}.border-top{border-top:1px solid #dee2e6 !important}.border-top-0{border-top:0 !important}.border-end{border-right:1px solid #dee2e6 !important}.border-end-0{border-right:0 !important}.border-bottom{border-bottom:1px solid #dee2e6 !important}.border-bottom-0{border-bottom:0 !important}.border-start{border-left:1px solid #dee2e6 !important}.border-start-0{border-left:0 !important}.border-primary{border-color:#007be5 !important}.border-secondary{border-color:#616161 !important}.border-success{border-color:#43a047 !important}.border-info{border-color:#469eb9 !important}.border-warning{border-color:#f9a825 !important}.border-danger{border-color:#ff511f !important}.border-light{border-color:#616161 !important}.border-dark{border-color:#616161 !important}.border-white{border-color:#fff !important}.border-1{border-width:1px !important}.border-2{border-width:2px !important}.border-3{border-width:3px !important}.border-4{border-width:4px !important}.border-5{border-width:5px !important}.w-25{width:25% !important}.w-50{width:50% !important}.w-75{width:75% !important}.w-100{width:100% !important}.w-auto{width:auto !important}.mw-100{max-width:100% !important}.vw-100{width:100vw !important}.min-vw-100{min-width:100vw !important}.h-25{height:25% !important}.h-50{height:50% !important}.h-75{height:75% !important}.h-100{height:100% !important}.h-auto{height:auto !important}.mh-100{max-height:100% !important}.vh-100{height:100vh !important}.min-vh-100{min-height:100vh !important}.flex-fill{flex:1 1 auto !important}.flex-row{flex-direction:row !important}.flex-column{flex-direction:column !important}.flex-row-reverse{flex-direction:row-reverse !important}.flex-column-reverse{flex-direction:column-reverse !important}.flex-grow-0{flex-grow:0 !important}.flex-grow-1{flex-grow:1 !important}.flex-shrink-0{flex-shrink:0 !important}.flex-shrink-1{flex-shrink:1 !important}.flex-wrap{flex-wrap:wrap !important}.flex-nowrap{flex-wrap:nowrap !important}.flex-wrap-reverse{flex-wrap:wrap-reverse !important}.gap-0{gap:0 !important}.gap-1{gap:.25rem !important}.gap-2{gap:.5rem !important}.gap-3{gap:1rem !important}.gap-4{gap:1.5rem !important}.gap-5{gap:3rem !important}.justify-content-start{justify-content:flex-start !important}.justify-content-end{justify-content:flex-end !important}.justify-content-center{justify-content:center !important}.justify-content-between{justify-content:space-between !important}.justify-content-around{justify-content:space-around !important}.justify-content-evenly{justify-content:space-evenly !important}.align-items-start{align-items:flex-start !important}.align-items-end{align-items:flex-end !important}.align-items-center{align-items:center !important}.align-items-baseline{align-items:baseline !important}.align-items-stretch{align-items:stretch !important}.align-content-start{align-content:flex-start !important}.align-content-end{align-content:flex-end !important}.align-content-center{align-content:center !important}.align-content-between{align-content:space-between !important}.align-content-around{align-content:space-around !important}.align-content-stretch{align-content:stretch !important}.align-self-auto{align-self:auto !important}.align-self-start{align-self:flex-start !important}.align-self-end{align-self:flex-end !important}.align-self-center{align-self:center !important}.align-self-baseline{align-self:baseline !important}.align-self-stretch{align-self:stretch !important}.order-first{order:-1 !important}.order-0{order:0 !important}.order-1{order:1 !important}.order-2{order:2 !important}.order-3{order:3 !important}.order-4{order:4 !important}.order-5{order:5 !important}.order-last{order:6 !important}.m-0{margin:0 !important}.m-1{margin:.25rem !important}.m-2{margin:.5rem !important}.m-3{margin:1rem !important}.m-4{margin:1.5rem !important}.m-5{margin:3rem !important}.m-auto{margin:auto !important}.mx-0{margin-right:0 !important;margin-left:0 !important}.mx-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-3{margin-right:1rem !important;margin-left:1rem !important}.mx-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-5{margin-right:3rem !important;margin-left:3rem !important}.mx-auto{margin-right:auto !important;margin-left:auto !important}.my-0{margin-top:0 !important;margin-bottom:0 !important}.my-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-0{margin-top:0 !important}.mt-1{margin-top:.25rem !important}.mt-2{margin-top:.5rem !important}.mt-3{margin-top:1rem !important}.mt-4{margin-top:1.5rem !important}.mt-5{margin-top:3rem !important}.mt-auto{margin-top:auto !important}.me-0{margin-right:0 !important}.me-1{margin-right:.25rem !important}.me-2{margin-right:.5rem !important}.me-3{margin-right:1rem !important}.me-4{margin-right:1.5rem !important}.me-5{margin-right:3rem !important}.me-auto{margin-right:auto !important}.mb-0{margin-bottom:0 !important}.mb-1{margin-bottom:.25rem !important}.mb-2{margin-bottom:.5rem !important}.mb-3{margin-bottom:1rem !important}.mb-4{margin-bottom:1.5rem !important}.mb-5{margin-bottom:3rem !important}.mb-auto{margin-bottom:auto !important}.ms-0{margin-left:0 !important}.ms-1{margin-left:.25rem !important}.ms-2{margin-left:.5rem !important}.ms-3{margin-left:1rem !important}.ms-4{margin-left:1.5rem !important}.ms-5{margin-left:3rem !important}.ms-auto{margin-left:auto !important}.p-0{padding:0 !important}.p-1{padding:.25rem !important}.p-2{padding:.5rem !important}.p-3{padding:1rem !important}.p-4{padding:1.5rem !important}.p-5{padding:3rem !important}.px-0{padding-right:0 !important;padding-left:0 !important}.px-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-3{padding-right:1rem !important;padding-left:1rem !important}.px-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-5{padding-right:3rem !important;padding-left:3rem !important}.py-0{padding-top:0 !important;padding-bottom:0 !important}.py-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-0{padding-top:0 !important}.pt-1{padding-top:.25rem !important}.pt-2{padding-top:.5rem !important}.pt-3{padding-top:1rem !important}.pt-4{padding-top:1.5rem !important}.pt-5{padding-top:3rem !important}.pe-0{padding-right:0 !important}.pe-1{padding-right:.25rem !important}.pe-2{padding-right:.5rem !important}.pe-3{padding-right:1rem !important}.pe-4{padding-right:1.5rem !important}.pe-5{padding-right:3rem !important}.pb-0{padding-bottom:0 !important}.pb-1{padding-bottom:.25rem !important}.pb-2{padding-bottom:.5rem !important}.pb-3{padding-bottom:1rem !important}.pb-4{padding-bottom:1.5rem !important}.pb-5{padding-bottom:3rem !important}.ps-0{padding-left:0 !important}.ps-1{padding-left:.25rem !important}.ps-2{padding-left:.5rem !important}.ps-3{padding-left:1rem !important}.ps-4{padding-left:1.5rem !important}.ps-5{padding-left:3rem !important}.font-monospace{font-family:var(--bs-font-monospace) !important}.fs-1{font-size:calc(1.26563rem + .1875vw) !important}.fs-2{font-size:1.125rem !important}.fs-3{font-size:.98475rem !important}.fs-4{font-size:.84375rem !important}.fs-5{font-size:.75rem !important}.fs-6{font-size:.7035rem !important}.fst-italic{font-style:italic !important}.fst-normal{font-style:normal !important}.fw-light{font-weight:300 !important}.fw-lighter{font-weight:lighter !important}.fw-normal{font-weight:400 !important}.fw-bold{font-weight:700 !important}.fw-bolder{font-weight:bolder !important}.lh-1{line-height:1 !important}.lh-sm{line-height:1.25 !important}.lh-base{line-height:1.5 !important}.lh-lg{line-height:2 !important}.text-start{text-align:left !important}.text-end{text-align:right !important}.text-center{text-align:center !important}.text-decoration-none{text-decoration:none !important}.text-decoration-underline{text-decoration:underline !important}.text-decoration-line-through{text-decoration:line-through !important}.text-lowercase{text-transform:lowercase !important}.text-uppercase{text-transform:uppercase !important}.text-capitalize{text-transform:capitalize !important}.text-wrap{white-space:normal !important}.text-nowrap{white-space:nowrap !important}.text-break{word-wrap:break-word !important;word-break:break-word !important}.text-primary{--bs-text-opacity: 1;color:rgba(var(--bs-primary-rgb), var(--bs-text-opacity)) !important}.text-secondary{--bs-text-opacity: 1;color:rgba(var(--bs-secondary-rgb), var(--bs-text-opacity)) !important}.text-success{--bs-text-opacity: 1;color:rgba(var(--bs-success-rgb), var(--bs-text-opacity)) !important}.text-info{--bs-text-opacity: 1;color:rgba(var(--bs-info-rgb), var(--bs-text-opacity)) !important}.text-warning{--bs-text-opacity: 1;color:rgba(var(--bs-warning-rgb), var(--bs-text-opacity)) !important}.text-danger{--bs-text-opacity: 1;color:rgba(var(--bs-danger-rgb), var(--bs-text-opacity)) !important}.text-light{--bs-text-opacity: 1;color:rgba(var(--bs-light-rgb), var(--bs-text-opacity)) !important}.text-dark{--bs-text-opacity: 1;color:rgba(var(--bs-dark-rgb), var(--bs-text-opacity)) !important}.text-black{--bs-text-opacity: 1;color:rgba(var(--bs-black-rgb), var(--bs-text-opacity)) !important}.text-white{--bs-text-opacity: 1;color:rgba(var(--bs-white-rgb), var(--bs-text-opacity)) !important}.text-body{--bs-text-opacity: 1;color:rgba(var(--bs-body-color-rgb), var(--bs-text-opacity)) !important}.text-muted{--bs-text-opacity: 1;color:var(--t42-content-color-muted) !important}.text-black-50{--bs-text-opacity: 1;color:rgba(0,0,0,0.5) !important}.text-white-50{--bs-text-opacity: 1;color:rgba(255,255,255,0.5) !important}.text-reset{--bs-text-opacity: 1;color:inherit !important}.text-opacity-25{--bs-text-opacity: .25}.text-opacity-50{--bs-text-opacity: .5}.text-opacity-75{--bs-text-opacity: .75}.text-opacity-100{--bs-text-opacity: 1}.bg-primary{--bs-bg-opacity: 1;background-color:rgba(var(--bs-primary-rgb), var(--bs-bg-opacity)) !important}.bg-secondary{--bs-bg-opacity: 1;background-color:rgba(var(--bs-secondary-rgb), var(--bs-bg-opacity)) !important}.bg-success{--bs-bg-opacity: 1;background-color:rgba(var(--bs-success-rgb), var(--bs-bg-opacity)) !important}.bg-info{--bs-bg-opacity: 1;background-color:rgba(var(--bs-info-rgb), var(--bs-bg-opacity)) !important}.bg-warning{--bs-bg-opacity: 1;background-color:rgba(var(--bs-warning-rgb), var(--bs-bg-opacity)) !important}.bg-danger{--bs-bg-opacity: 1;background-color:rgba(var(--bs-danger-rgb), var(--bs-bg-opacity)) !important}.bg-light{--bs-bg-opacity: 1;background-color:rgba(var(--bs-light-rgb), var(--bs-bg-opacity)) !important}.bg-dark{--bs-bg-opacity: 1;background-color:rgba(var(--bs-dark-rgb), var(--bs-bg-opacity)) !important}.bg-black{--bs-bg-opacity: 1;background-color:rgba(var(--bs-black-rgb), var(--bs-bg-opacity)) !important}.bg-white{--bs-bg-opacity: 1;background-color:rgba(var(--bs-white-rgb), var(--bs-bg-opacity)) !important}.bg-body{--bs-bg-opacity: 1;background-color:rgba(var(--bs-body-bg-rgb), var(--bs-bg-opacity)) !important}.bg-transparent{--bs-bg-opacity: 1;background-color:rgba(0,0,0,0) !important}.bg-opacity-10{--bs-bg-opacity: .1}.bg-opacity-25{--bs-bg-opacity: .25}.bg-opacity-50{--bs-bg-opacity: .5}.bg-opacity-75{--bs-bg-opacity: .75}.bg-opacity-100{--bs-bg-opacity: 1}.bg-gradient{background-image:var(--bs-gradient) !important}.user-select-all{user-select:all !important}.user-select-auto{user-select:auto !important}.user-select-none{user-select:none !important}.pe-none{pointer-events:none !important}.pe-auto{pointer-events:auto !important}.rounded{border-radius:.25rem !important}.rounded-0{border-radius:0 !important}.rounded-1{border-radius:.25rem !important}.rounded-2{border-radius:.25rem !important}.rounded-3{border-radius:1rem !important}.rounded-circle{border-radius:50% !important}.rounded-pill{border-radius:50rem !important}.rounded-top{border-top-left-radius:.25rem !important;border-top-right-radius:.25rem !important}.rounded-end{border-top-right-radius:.25rem !important;border-bottom-right-radius:.25rem !important}.rounded-bottom{border-bottom-right-radius:.25rem !important;border-bottom-left-radius:.25rem !important}.rounded-start{border-bottom-left-radius:.25rem !important;border-top-left-radius:.25rem !important}.visible{visibility:visible !important}.invisible{visibility:hidden !important}@media (min-width: 576px){.float-sm-start{float:left !important}.float-sm-end{float:right !important}.float-sm-none{float:none !important}.d-sm-inline{display:inline !important}.d-sm-inline-block{display:inline-block !important}.d-sm-block{display:block !important}.d-sm-grid{display:grid !important}.d-sm-table{display:table !important}.d-sm-table-row{display:table-row !important}.d-sm-table-cell{display:table-cell !important}.d-sm-flex{display:flex !important}.d-sm-inline-flex{display:inline-flex !important}.d-sm-none{display:none !important}.flex-sm-fill{flex:1 1 auto !important}.flex-sm-row{flex-direction:row !important}.flex-sm-column{flex-direction:column !important}.flex-sm-row-reverse{flex-direction:row-reverse !important}.flex-sm-column-reverse{flex-direction:column-reverse !important}.flex-sm-grow-0{flex-grow:0 !important}.flex-sm-grow-1{flex-grow:1 !important}.flex-sm-shrink-0{flex-shrink:0 !important}.flex-sm-shrink-1{flex-shrink:1 !important}.flex-sm-wrap{flex-wrap:wrap !important}.flex-sm-nowrap{flex-wrap:nowrap !important}.flex-sm-wrap-reverse{flex-wrap:wrap-reverse !important}.gap-sm-0{gap:0 !important}.gap-sm-1{gap:.25rem !important}.gap-sm-2{gap:.5rem !important}.gap-sm-3{gap:1rem !important}.gap-sm-4{gap:1.5rem !important}.gap-sm-5{gap:3rem !important}.justify-content-sm-start{justify-content:flex-start !important}.justify-content-sm-end{justify-content:flex-end !important}.justify-content-sm-center{justify-content:center !important}.justify-content-sm-between{justify-content:space-between !important}.justify-content-sm-around{justify-content:space-around !important}.justify-content-sm-evenly{justify-content:space-evenly !important}.align-items-sm-start{align-items:flex-start !important}.align-items-sm-end{align-items:flex-end !important}.align-items-sm-center{align-items:center !important}.align-items-sm-baseline{align-items:baseline !important}.align-items-sm-stretch{align-items:stretch !important}.align-content-sm-start{align-content:flex-start !important}.align-content-sm-end{align-content:flex-end !important}.align-content-sm-center{align-content:center !important}.align-content-sm-between{align-content:space-between !important}.align-content-sm-around{align-content:space-around !important}.align-content-sm-stretch{align-content:stretch !important}.align-self-sm-auto{align-self:auto !important}.align-self-sm-start{align-self:flex-start !important}.align-self-sm-end{align-self:flex-end !important}.align-self-sm-center{align-self:center !important}.align-self-sm-baseline{align-self:baseline !important}.align-self-sm-stretch{align-self:stretch !important}.order-sm-first{order:-1 !important}.order-sm-0{order:0 !important}.order-sm-1{order:1 !important}.order-sm-2{order:2 !important}.order-sm-3{order:3 !important}.order-sm-4{order:4 !important}.order-sm-5{order:5 !important}.order-sm-last{order:6 !important}.m-sm-0{margin:0 !important}.m-sm-1{margin:.25rem !important}.m-sm-2{margin:.5rem !important}.m-sm-3{margin:1rem !important}.m-sm-4{margin:1.5rem !important}.m-sm-5{margin:3rem !important}.m-sm-auto{margin:auto !important}.mx-sm-0{margin-right:0 !important;margin-left:0 !important}.mx-sm-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-sm-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-sm-3{margin-right:1rem !important;margin-left:1rem !important}.mx-sm-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-sm-5{margin-right:3rem !important;margin-left:3rem !important}.mx-sm-auto{margin-right:auto !important;margin-left:auto !important}.my-sm-0{margin-top:0 !important;margin-bottom:0 !important}.my-sm-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-sm-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-sm-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-sm-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-sm-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-sm-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-sm-0{margin-top:0 !important}.mt-sm-1{margin-top:.25rem !important}.mt-sm-2{margin-top:.5rem !important}.mt-sm-3{margin-top:1rem !important}.mt-sm-4{margin-top:1.5rem !important}.mt-sm-5{margin-top:3rem !important}.mt-sm-auto{margin-top:auto !important}.me-sm-0{margin-right:0 !important}.me-sm-1{margin-right:.25rem !important}.me-sm-2{margin-right:.5rem !important}.me-sm-3{margin-right:1rem !important}.me-sm-4{margin-right:1.5rem !important}.me-sm-5{margin-right:3rem !important}.me-sm-auto{margin-right:auto !important}.mb-sm-0{margin-bottom:0 !important}.mb-sm-1{margin-bottom:.25rem !important}.mb-sm-2{margin-bottom:.5rem !important}.mb-sm-3{margin-bottom:1rem !important}.mb-sm-4{margin-bottom:1.5rem !important}.mb-sm-5{margin-bottom:3rem !important}.mb-sm-auto{margin-bottom:auto !important}.ms-sm-0{margin-left:0 !important}.ms-sm-1{margin-left:.25rem !important}.ms-sm-2{margin-left:.5rem !important}.ms-sm-3{margin-left:1rem !important}.ms-sm-4{margin-left:1.5rem !important}.ms-sm-5{margin-left:3rem !important}.ms-sm-auto{margin-left:auto !important}.p-sm-0{padding:0 !important}.p-sm-1{padding:.25rem !important}.p-sm-2{padding:.5rem !important}.p-sm-3{padding:1rem !important}.p-sm-4{padding:1.5rem !important}.p-sm-5{padding:3rem !important}.px-sm-0{padding-right:0 !important;padding-left:0 !important}.px-sm-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-sm-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-sm-3{padding-right:1rem !important;padding-left:1rem !important}.px-sm-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-sm-5{padding-right:3rem !important;padding-left:3rem !important}.py-sm-0{padding-top:0 !important;padding-bottom:0 !important}.py-sm-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-sm-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-sm-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-sm-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-sm-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-sm-0{padding-top:0 !important}.pt-sm-1{padding-top:.25rem !important}.pt-sm-2{padding-top:.5rem !important}.pt-sm-3{padding-top:1rem !important}.pt-sm-4{padding-top:1.5rem !important}.pt-sm-5{padding-top:3rem !important}.pe-sm-0{padding-right:0 !important}.pe-sm-1{padding-right:.25rem !important}.pe-sm-2{padding-right:.5rem !important}.pe-sm-3{padding-right:1rem !important}.pe-sm-4{padding-right:1.5rem !important}.pe-sm-5{padding-right:3rem !important}.pb-sm-0{padding-bottom:0 !important}.pb-sm-1{padding-bottom:.25rem !important}.pb-sm-2{padding-bottom:.5rem !important}.pb-sm-3{padding-bottom:1rem !important}.pb-sm-4{padding-bottom:1.5rem !important}.pb-sm-5{padding-bottom:3rem !important}.ps-sm-0{padding-left:0 !important}.ps-sm-1{padding-left:.25rem !important}.ps-sm-2{padding-left:.5rem !important}.ps-sm-3{padding-left:1rem !important}.ps-sm-4{padding-left:1.5rem !important}.ps-sm-5{padding-left:3rem !important}.text-sm-start{text-align:left !important}.text-sm-end{text-align:right !important}.text-sm-center{text-align:center !important}}@media (min-width: 768px){.float-md-start{float:left !important}.float-md-end{float:right !important}.float-md-none{float:none !important}.d-md-inline{display:inline !important}.d-md-inline-block{display:inline-block !important}.d-md-block{display:block !important}.d-md-grid{display:grid !important}.d-md-table{display:table !important}.d-md-table-row{display:table-row !important}.d-md-table-cell{display:table-cell !important}.d-md-flex{display:flex !important}.d-md-inline-flex{display:inline-flex !important}.d-md-none{display:none !important}.flex-md-fill{flex:1 1 auto !important}.flex-md-row{flex-direction:row !important}.flex-md-column{flex-direction:column !important}.flex-md-row-reverse{flex-direction:row-reverse !important}.flex-md-column-reverse{flex-direction:column-reverse !important}.flex-md-grow-0{flex-grow:0 !important}.flex-md-grow-1{flex-grow:1 !important}.flex-md-shrink-0{flex-shrink:0 !important}.flex-md-shrink-1{flex-shrink:1 !important}.flex-md-wrap{flex-wrap:wrap !important}.flex-md-nowrap{flex-wrap:nowrap !important}.flex-md-wrap-reverse{flex-wrap:wrap-reverse !important}.gap-md-0{gap:0 !important}.gap-md-1{gap:.25rem !important}.gap-md-2{gap:.5rem !important}.gap-md-3{gap:1rem !important}.gap-md-4{gap:1.5rem !important}.gap-md-5{gap:3rem !important}.justify-content-md-start{justify-content:flex-start !important}.justify-content-md-end{justify-content:flex-end !important}.justify-content-md-center{justify-content:center !important}.justify-content-md-between{justify-content:space-between !important}.justify-content-md-around{justify-content:space-around !important}.justify-content-md-evenly{justify-content:space-evenly !important}.align-items-md-start{align-items:flex-start !important}.align-items-md-end{align-items:flex-end !important}.align-items-md-center{align-items:center !important}.align-items-md-baseline{align-items:baseline !important}.align-items-md-stretch{align-items:stretch !important}.align-content-md-start{align-content:flex-start !important}.align-content-md-end{align-content:flex-end !important}.align-content-md-center{align-content:center !important}.align-content-md-between{align-content:space-between !important}.align-content-md-around{align-content:space-around !important}.align-content-md-stretch{align-content:stretch !important}.align-self-md-auto{align-self:auto !important}.align-self-md-start{align-self:flex-start !important}.align-self-md-end{align-self:flex-end !important}.align-self-md-center{align-self:center !important}.align-self-md-baseline{align-self:baseline !important}.align-self-md-stretch{align-self:stretch !important}.order-md-first{order:-1 !important}.order-md-0{order:0 !important}.order-md-1{order:1 !important}.order-md-2{order:2 !important}.order-md-3{order:3 !important}.order-md-4{order:4 !important}.order-md-5{order:5 !important}.order-md-last{order:6 !important}.m-md-0{margin:0 !important}.m-md-1{margin:.25rem !important}.m-md-2{margin:.5rem !important}.m-md-3{margin:1rem !important}.m-md-4{margin:1.5rem !important}.m-md-5{margin:3rem !important}.m-md-auto{margin:auto !important}.mx-md-0{margin-right:0 !important;margin-left:0 !important}.mx-md-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-md-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-md-3{margin-right:1rem !important;margin-left:1rem !important}.mx-md-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-md-5{margin-right:3rem !important;margin-left:3rem !important}.mx-md-auto{margin-right:auto !important;margin-left:auto !important}.my-md-0{margin-top:0 !important;margin-bottom:0 !important}.my-md-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-md-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-md-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-md-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-md-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-md-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-md-0{margin-top:0 !important}.mt-md-1{margin-top:.25rem !important}.mt-md-2{margin-top:.5rem !important}.mt-md-3{margin-top:1rem !important}.mt-md-4{margin-top:1.5rem !important}.mt-md-5{margin-top:3rem !important}.mt-md-auto{margin-top:auto !important}.me-md-0{margin-right:0 !important}.me-md-1{margin-right:.25rem !important}.me-md-2{margin-right:.5rem !important}.me-md-3{margin-right:1rem !important}.me-md-4{margin-right:1.5rem !important}.me-md-5{margin-right:3rem !important}.me-md-auto{margin-right:auto !important}.mb-md-0{margin-bottom:0 !important}.mb-md-1{margin-bottom:.25rem !important}.mb-md-2{margin-bottom:.5rem !important}.mb-md-3{margin-bottom:1rem !important}.mb-md-4{margin-bottom:1.5rem !important}.mb-md-5{margin-bottom:3rem !important}.mb-md-auto{margin-bottom:auto !important}.ms-md-0{margin-left:0 !important}.ms-md-1{margin-left:.25rem !important}.ms-md-2{margin-left:.5rem !important}.ms-md-3{margin-left:1rem !important}.ms-md-4{margin-left:1.5rem !important}.ms-md-5{margin-left:3rem !important}.ms-md-auto{margin-left:auto !important}.p-md-0{padding:0 !important}.p-md-1{padding:.25rem !important}.p-md-2{padding:.5rem !important}.p-md-3{padding:1rem !important}.p-md-4{padding:1.5rem !important}.p-md-5{padding:3rem !important}.px-md-0{padding-right:0 !important;padding-left:0 !important}.px-md-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-md-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-md-3{padding-right:1rem !important;padding-left:1rem !important}.px-md-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-md-5{padding-right:3rem !important;padding-left:3rem !important}.py-md-0{padding-top:0 !important;padding-bottom:0 !important}.py-md-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-md-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-md-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-md-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-md-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-md-0{padding-top:0 !important}.pt-md-1{padding-top:.25rem !important}.pt-md-2{padding-top:.5rem !important}.pt-md-3{padding-top:1rem !important}.pt-md-4{padding-top:1.5rem !important}.pt-md-5{padding-top:3rem !important}.pe-md-0{padding-right:0 !important}.pe-md-1{padding-right:.25rem !important}.pe-md-2{padding-right:.5rem !important}.pe-md-3{padding-right:1rem !important}.pe-md-4{padding-right:1.5rem !important}.pe-md-5{padding-right:3rem !important}.pb-md-0{padding-bottom:0 !important}.pb-md-1{padding-bottom:.25rem !important}.pb-md-2{padding-bottom:.5rem !important}.pb-md-3{padding-bottom:1rem !important}.pb-md-4{padding-bottom:1.5rem !important}.pb-md-5{padding-bottom:3rem !important}.ps-md-0{padding-left:0 !important}.ps-md-1{padding-left:.25rem !important}.ps-md-2{padding-left:.5rem !important}.ps-md-3{padding-left:1rem !important}.ps-md-4{padding-left:1.5rem !important}.ps-md-5{padding-left:3rem !important}.text-md-start{text-align:left !important}.text-md-end{text-align:right !important}.text-md-center{text-align:center !important}}@media (min-width: 992px){.float-lg-start{float:left !important}.float-lg-end{float:right !important}.float-lg-none{float:none !important}.d-lg-inline{display:inline !important}.d-lg-inline-block{display:inline-block !important}.d-lg-block{display:block !important}.d-lg-grid{display:grid !important}.d-lg-table{display:table !important}.d-lg-table-row{display:table-row !important}.d-lg-table-cell{display:table-cell !important}.d-lg-flex{display:flex !important}.d-lg-inline-flex{display:inline-flex !important}.d-lg-none{display:none !important}.flex-lg-fill{flex:1 1 auto !important}.flex-lg-row{flex-direction:row !important}.flex-lg-column{flex-direction:column !important}.flex-lg-row-reverse{flex-direction:row-reverse !important}.flex-lg-column-reverse{flex-direction:column-reverse !important}.flex-lg-grow-0{flex-grow:0 !important}.flex-lg-grow-1{flex-grow:1 !important}.flex-lg-shrink-0{flex-shrink:0 !important}.flex-lg-shrink-1{flex-shrink:1 !important}.flex-lg-wrap{flex-wrap:wrap !important}.flex-lg-nowrap{flex-wrap:nowrap !important}.flex-lg-wrap-reverse{flex-wrap:wrap-reverse !important}.gap-lg-0{gap:0 !important}.gap-lg-1{gap:.25rem !important}.gap-lg-2{gap:.5rem !important}.gap-lg-3{gap:1rem !important}.gap-lg-4{gap:1.5rem !important}.gap-lg-5{gap:3rem !important}.justify-content-lg-start{justify-content:flex-start !important}.justify-content-lg-end{justify-content:flex-end !important}.justify-content-lg-center{justify-content:center !important}.justify-content-lg-between{justify-content:space-between !important}.justify-content-lg-around{justify-content:space-around !important}.justify-content-lg-evenly{justify-content:space-evenly !important}.align-items-lg-start{align-items:flex-start !important}.align-items-lg-end{align-items:flex-end !important}.align-items-lg-center{align-items:center !important}.align-items-lg-baseline{align-items:baseline !important}.align-items-lg-stretch{align-items:stretch !important}.align-content-lg-start{align-content:flex-start !important}.align-content-lg-end{align-content:flex-end !important}.align-content-lg-center{align-content:center !important}.align-content-lg-between{align-content:space-between !important}.align-content-lg-around{align-content:space-around !important}.align-content-lg-stretch{align-content:stretch !important}.align-self-lg-auto{align-self:auto !important}.align-self-lg-start{align-self:flex-start !important}.align-self-lg-end{align-self:flex-end !important}.align-self-lg-center{align-self:center !important}.align-self-lg-baseline{align-self:baseline !important}.align-self-lg-stretch{align-self:stretch !important}.order-lg-first{order:-1 !important}.order-lg-0{order:0 !important}.order-lg-1{order:1 !important}.order-lg-2{order:2 !important}.order-lg-3{order:3 !important}.order-lg-4{order:4 !important}.order-lg-5{order:5 !important}.order-lg-last{order:6 !important}.m-lg-0{margin:0 !important}.m-lg-1{margin:.25rem !important}.m-lg-2{margin:.5rem !important}.m-lg-3{margin:1rem !important}.m-lg-4{margin:1.5rem !important}.m-lg-5{margin:3rem !important}.m-lg-auto{margin:auto !important}.mx-lg-0{margin-right:0 !important;margin-left:0 !important}.mx-lg-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-lg-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-lg-3{margin-right:1rem !important;margin-left:1rem !important}.mx-lg-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-lg-5{margin-right:3rem !important;margin-left:3rem !important}.mx-lg-auto{margin-right:auto !important;margin-left:auto !important}.my-lg-0{margin-top:0 !important;margin-bottom:0 !important}.my-lg-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-lg-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-lg-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-lg-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-lg-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-lg-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-lg-0{margin-top:0 !important}.mt-lg-1{margin-top:.25rem !important}.mt-lg-2{margin-top:.5rem !important}.mt-lg-3{margin-top:1rem !important}.mt-lg-4{margin-top:1.5rem !important}.mt-lg-5{margin-top:3rem !important}.mt-lg-auto{margin-top:auto !important}.me-lg-0{margin-right:0 !important}.me-lg-1{margin-right:.25rem !important}.me-lg-2{margin-right:.5rem !important}.me-lg-3{margin-right:1rem !important}.me-lg-4{margin-right:1.5rem !important}.me-lg-5{margin-right:3rem !important}.me-lg-auto{margin-right:auto !important}.mb-lg-0{margin-bottom:0 !important}.mb-lg-1{margin-bottom:.25rem !important}.mb-lg-2{margin-bottom:.5rem !important}.mb-lg-3{margin-bottom:1rem !important}.mb-lg-4{margin-bottom:1.5rem !important}.mb-lg-5{margin-bottom:3rem !important}.mb-lg-auto{margin-bottom:auto !important}.ms-lg-0{margin-left:0 !important}.ms-lg-1{margin-left:.25rem !important}.ms-lg-2{margin-left:.5rem !important}.ms-lg-3{margin-left:1rem !important}.ms-lg-4{margin-left:1.5rem !important}.ms-lg-5{margin-left:3rem !important}.ms-lg-auto{margin-left:auto !important}.p-lg-0{padding:0 !important}.p-lg-1{padding:.25rem !important}.p-lg-2{padding:.5rem !important}.p-lg-3{padding:1rem !important}.p-lg-4{padding:1.5rem !important}.p-lg-5{padding:3rem !important}.px-lg-0{padding-right:0 !important;padding-left:0 !important}.px-lg-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-lg-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-lg-3{padding-right:1rem !important;padding-left:1rem !important}.px-lg-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-lg-5{padding-right:3rem !important;padding-left:3rem !important}.py-lg-0{padding-top:0 !important;padding-bottom:0 !important}.py-lg-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-lg-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-lg-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-lg-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-lg-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-lg-0{padding-top:0 !important}.pt-lg-1{padding-top:.25rem !important}.pt-lg-2{padding-top:.5rem !important}.pt-lg-3{padding-top:1rem !important}.pt-lg-4{padding-top:1.5rem !important}.pt-lg-5{padding-top:3rem !important}.pe-lg-0{padding-right:0 !important}.pe-lg-1{padding-right:.25rem !important}.pe-lg-2{padding-right:.5rem !important}.pe-lg-3{padding-right:1rem !important}.pe-lg-4{padding-right:1.5rem !important}.pe-lg-5{padding-right:3rem !important}.pb-lg-0{padding-bottom:0 !important}.pb-lg-1{padding-bottom:.25rem !important}.pb-lg-2{padding-bottom:.5rem !important}.pb-lg-3{padding-bottom:1rem !important}.pb-lg-4{padding-bottom:1.5rem !important}.pb-lg-5{padding-bottom:3rem !important}.ps-lg-0{padding-left:0 !important}.ps-lg-1{padding-left:.25rem !important}.ps-lg-2{padding-left:.5rem !important}.ps-lg-3{padding-left:1rem !important}.ps-lg-4{padding-left:1.5rem !important}.ps-lg-5{padding-left:3rem !important}.text-lg-start{text-align:left !important}.text-lg-end{text-align:right !important}.text-lg-center{text-align:center !important}}@media (min-width: 1200px){.float-xl-start{float:left !important}.float-xl-end{float:right !important}.float-xl-none{float:none !important}.d-xl-inline{display:inline !important}.d-xl-inline-block{display:inline-block !important}.d-xl-block{display:block !important}.d-xl-grid{display:grid !important}.d-xl-table{display:table !important}.d-xl-table-row{display:table-row !important}.d-xl-table-cell{display:table-cell !important}.d-xl-flex{display:flex !important}.d-xl-inline-flex{display:inline-flex !important}.d-xl-none{display:none !important}.flex-xl-fill{flex:1 1 auto !important}.flex-xl-row{flex-direction:row !important}.flex-xl-column{flex-direction:column !important}.flex-xl-row-reverse{flex-direction:row-reverse !important}.flex-xl-column-reverse{flex-direction:column-reverse !important}.flex-xl-grow-0{flex-grow:0 !important}.flex-xl-grow-1{flex-grow:1 !important}.flex-xl-shrink-0{flex-shrink:0 !important}.flex-xl-shrink-1{flex-shrink:1 !important}.flex-xl-wrap{flex-wrap:wrap !important}.flex-xl-nowrap{flex-wrap:nowrap !important}.flex-xl-wrap-reverse{flex-wrap:wrap-reverse !important}.gap-xl-0{gap:0 !important}.gap-xl-1{gap:.25rem !important}.gap-xl-2{gap:.5rem !important}.gap-xl-3{gap:1rem !important}.gap-xl-4{gap:1.5rem !important}.gap-xl-5{gap:3rem !important}.justify-content-xl-start{justify-content:flex-start !important}.justify-content-xl-end{justify-content:flex-end !important}.justify-content-xl-center{justify-content:center !important}.justify-content-xl-between{justify-content:space-between !important}.justify-content-xl-around{justify-content:space-around !important}.justify-content-xl-evenly{justify-content:space-evenly !important}.align-items-xl-start{align-items:flex-start !important}.align-items-xl-end{align-items:flex-end !important}.align-items-xl-center{align-items:center !important}.align-items-xl-baseline{align-items:baseline !important}.align-items-xl-stretch{align-items:stretch !important}.align-content-xl-start{align-content:flex-start !important}.align-content-xl-end{align-content:flex-end !important}.align-content-xl-center{align-content:center !important}.align-content-xl-between{align-content:space-between !important}.align-content-xl-around{align-content:space-around !important}.align-content-xl-stretch{align-content:stretch !important}.align-self-xl-auto{align-self:auto !important}.align-self-xl-start{align-self:flex-start !important}.align-self-xl-end{align-self:flex-end !important}.align-self-xl-center{align-self:center !important}.align-self-xl-baseline{align-self:baseline !important}.align-self-xl-stretch{align-self:stretch !important}.order-xl-first{order:-1 !important}.order-xl-0{order:0 !important}.order-xl-1{order:1 !important}.order-xl-2{order:2 !important}.order-xl-3{order:3 !important}.order-xl-4{order:4 !important}.order-xl-5{order:5 !important}.order-xl-last{order:6 !important}.m-xl-0{margin:0 !important}.m-xl-1{margin:.25rem !important}.m-xl-2{margin:.5rem !important}.m-xl-3{margin:1rem !important}.m-xl-4{margin:1.5rem !important}.m-xl-5{margin:3rem !important}.m-xl-auto{margin:auto !important}.mx-xl-0{margin-right:0 !important;margin-left:0 !important}.mx-xl-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-xl-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-xl-3{margin-right:1rem !important;margin-left:1rem !important}.mx-xl-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-xl-5{margin-right:3rem !important;margin-left:3rem !important}.mx-xl-auto{margin-right:auto !important;margin-left:auto !important}.my-xl-0{margin-top:0 !important;margin-bottom:0 !important}.my-xl-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-xl-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-xl-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-xl-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-xl-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-xl-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-xl-0{margin-top:0 !important}.mt-xl-1{margin-top:.25rem !important}.mt-xl-2{margin-top:.5rem !important}.mt-xl-3{margin-top:1rem !important}.mt-xl-4{margin-top:1.5rem !important}.mt-xl-5{margin-top:3rem !important}.mt-xl-auto{margin-top:auto !important}.me-xl-0{margin-right:0 !important}.me-xl-1{margin-right:.25rem !important}.me-xl-2{margin-right:.5rem !important}.me-xl-3{margin-right:1rem !important}.me-xl-4{margin-right:1.5rem !important}.me-xl-5{margin-right:3rem !important}.me-xl-auto{margin-right:auto !important}.mb-xl-0{margin-bottom:0 !important}.mb-xl-1{margin-bottom:.25rem !important}.mb-xl-2{margin-bottom:.5rem !important}.mb-xl-3{margin-bottom:1rem !important}.mb-xl-4{margin-bottom:1.5rem !important}.mb-xl-5{margin-bottom:3rem !important}.mb-xl-auto{margin-bottom:auto !important}.ms-xl-0{margin-left:0 !important}.ms-xl-1{margin-left:.25rem !important}.ms-xl-2{margin-left:.5rem !important}.ms-xl-3{margin-left:1rem !important}.ms-xl-4{margin-left:1.5rem !important}.ms-xl-5{margin-left:3rem !important}.ms-xl-auto{margin-left:auto !important}.p-xl-0{padding:0 !important}.p-xl-1{padding:.25rem !important}.p-xl-2{padding:.5rem !important}.p-xl-3{padding:1rem !important}.p-xl-4{padding:1.5rem !important}.p-xl-5{padding:3rem !important}.px-xl-0{padding-right:0 !important;padding-left:0 !important}.px-xl-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-xl-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-xl-3{padding-right:1rem !important;padding-left:1rem !important}.px-xl-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-xl-5{padding-right:3rem !important;padding-left:3rem !important}.py-xl-0{padding-top:0 !important;padding-bottom:0 !important}.py-xl-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-xl-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-xl-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-xl-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-xl-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-xl-0{padding-top:0 !important}.pt-xl-1{padding-top:.25rem !important}.pt-xl-2{padding-top:.5rem !important}.pt-xl-3{padding-top:1rem !important}.pt-xl-4{padding-top:1.5rem !important}.pt-xl-5{padding-top:3rem !important}.pe-xl-0{padding-right:0 !important}.pe-xl-1{padding-right:.25rem !important}.pe-xl-2{padding-right:.5rem !important}.pe-xl-3{padding-right:1rem !important}.pe-xl-4{padding-right:1.5rem !important}.pe-xl-5{padding-right:3rem !important}.pb-xl-0{padding-bottom:0 !important}.pb-xl-1{padding-bottom:.25rem !important}.pb-xl-2{padding-bottom:.5rem !important}.pb-xl-3{padding-bottom:1rem !important}.pb-xl-4{padding-bottom:1.5rem !important}.pb-xl-5{padding-bottom:3rem !important}.ps-xl-0{padding-left:0 !important}.ps-xl-1{padding-left:.25rem !important}.ps-xl-2{padding-left:.5rem !important}.ps-xl-3{padding-left:1rem !important}.ps-xl-4{padding-left:1.5rem !important}.ps-xl-5{padding-left:3rem !important}.text-xl-start{text-align:left !important}.text-xl-end{text-align:right !important}.text-xl-center{text-align:center !important}}@media (min-width: 1400px){.float-xxl-start{float:left !important}.float-xxl-end{float:right !important}.float-xxl-none{float:none !important}.d-xxl-inline{display:inline !important}.d-xxl-inline-block{display:inline-block !important}.d-xxl-block{display:block !important}.d-xxl-grid{display:grid !important}.d-xxl-table{display:table !important}.d-xxl-table-row{display:table-row !important}.d-xxl-table-cell{display:table-cell !important}.d-xxl-flex{display:flex !important}.d-xxl-inline-flex{display:inline-flex !important}.d-xxl-none{display:none !important}.flex-xxl-fill{flex:1 1 auto !important}.flex-xxl-row{flex-direction:row !important}.flex-xxl-column{flex-direction:column !important}.flex-xxl-row-reverse{flex-direction:row-reverse !important}.flex-xxl-column-reverse{flex-direction:column-reverse !important}.flex-xxl-grow-0{flex-grow:0 !important}.flex-xxl-grow-1{flex-grow:1 !important}.flex-xxl-shrink-0{flex-shrink:0 !important}.flex-xxl-shrink-1{flex-shrink:1 !important}.flex-xxl-wrap{flex-wrap:wrap !important}.flex-xxl-nowrap{flex-wrap:nowrap !important}.flex-xxl-wrap-reverse{flex-wrap:wrap-reverse !important}.gap-xxl-0{gap:0 !important}.gap-xxl-1{gap:.25rem !important}.gap-xxl-2{gap:.5rem !important}.gap-xxl-3{gap:1rem !important}.gap-xxl-4{gap:1.5rem !important}.gap-xxl-5{gap:3rem !important}.justify-content-xxl-start{justify-content:flex-start !important}.justify-content-xxl-end{justify-content:flex-end !important}.justify-content-xxl-center{justify-content:center !important}.justify-content-xxl-between{justify-content:space-between !important}.justify-content-xxl-around{justify-content:space-around !important}.justify-content-xxl-evenly{justify-content:space-evenly !important}.align-items-xxl-start{align-items:flex-start !important}.align-items-xxl-end{align-items:flex-end !important}.align-items-xxl-center{align-items:center !important}.align-items-xxl-baseline{align-items:baseline !important}.align-items-xxl-stretch{align-items:stretch !important}.align-content-xxl-start{align-content:flex-start !important}.align-content-xxl-end{align-content:flex-end !important}.align-content-xxl-center{align-content:center !important}.align-content-xxl-between{align-content:space-between !important}.align-content-xxl-around{align-content:space-around !important}.align-content-xxl-stretch{align-content:stretch !important}.align-self-xxl-auto{align-self:auto !important}.align-self-xxl-start{align-self:flex-start !important}.align-self-xxl-end{align-self:flex-end !important}.align-self-xxl-center{align-self:center !important}.align-self-xxl-baseline{align-self:baseline !important}.align-self-xxl-stretch{align-self:stretch !important}.order-xxl-first{order:-1 !important}.order-xxl-0{order:0 !important}.order-xxl-1{order:1 !important}.order-xxl-2{order:2 !important}.order-xxl-3{order:3 !important}.order-xxl-4{order:4 !important}.order-xxl-5{order:5 !important}.order-xxl-last{order:6 !important}.m-xxl-0{margin:0 !important}.m-xxl-1{margin:.25rem !important}.m-xxl-2{margin:.5rem !important}.m-xxl-3{margin:1rem !important}.m-xxl-4{margin:1.5rem !important}.m-xxl-5{margin:3rem !important}.m-xxl-auto{margin:auto !important}.mx-xxl-0{margin-right:0 !important;margin-left:0 !important}.mx-xxl-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-xxl-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-xxl-3{margin-right:1rem !important;margin-left:1rem !important}.mx-xxl-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-xxl-5{margin-right:3rem !important;margin-left:3rem !important}.mx-xxl-auto{margin-right:auto !important;margin-left:auto !important}.my-xxl-0{margin-top:0 !important;margin-bottom:0 !important}.my-xxl-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-xxl-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-xxl-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-xxl-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-xxl-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-xxl-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-xxl-0{margin-top:0 !important}.mt-xxl-1{margin-top:.25rem !important}.mt-xxl-2{margin-top:.5rem !important}.mt-xxl-3{margin-top:1rem !important}.mt-xxl-4{margin-top:1.5rem !important}.mt-xxl-5{margin-top:3rem !important}.mt-xxl-auto{margin-top:auto !important}.me-xxl-0{margin-right:0 !important}.me-xxl-1{margin-right:.25rem !important}.me-xxl-2{margin-right:.5rem !important}.me-xxl-3{margin-right:1rem !important}.me-xxl-4{margin-right:1.5rem !important}.me-xxl-5{margin-right:3rem !important}.me-xxl-auto{margin-right:auto !important}.mb-xxl-0{margin-bottom:0 !important}.mb-xxl-1{margin-bottom:.25rem !important}.mb-xxl-2{margin-bottom:.5rem !important}.mb-xxl-3{margin-bottom:1rem !important}.mb-xxl-4{margin-bottom:1.5rem !important}.mb-xxl-5{margin-bottom:3rem !important}.mb-xxl-auto{margin-bottom:auto !important}.ms-xxl-0{margin-left:0 !important}.ms-xxl-1{margin-left:.25rem !important}.ms-xxl-2{margin-left:.5rem !important}.ms-xxl-3{margin-left:1rem !important}.ms-xxl-4{margin-left:1.5rem !important}.ms-xxl-5{margin-left:3rem !important}.ms-xxl-auto{margin-left:auto !important}.p-xxl-0{padding:0 !important}.p-xxl-1{padding:.25rem !important}.p-xxl-2{padding:.5rem !important}.p-xxl-3{padding:1rem !important}.p-xxl-4{padding:1.5rem !important}.p-xxl-5{padding:3rem !important}.px-xxl-0{padding-right:0 !important;padding-left:0 !important}.px-xxl-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-xxl-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-xxl-3{padding-right:1rem !important;padding-left:1rem !important}.px-xxl-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-xxl-5{padding-right:3rem !important;padding-left:3rem !important}.py-xxl-0{padding-top:0 !important;padding-bottom:0 !important}.py-xxl-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-xxl-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-xxl-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-xxl-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-xxl-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-xxl-0{padding-top:0 !important}.pt-xxl-1{padding-top:.25rem !important}.pt-xxl-2{padding-top:.5rem !important}.pt-xxl-3{padding-top:1rem !important}.pt-xxl-4{padding-top:1.5rem !important}.pt-xxl-5{padding-top:3rem !important}.pe-xxl-0{padding-right:0 !important}.pe-xxl-1{padding-right:.25rem !important}.pe-xxl-2{padding-right:.5rem !important}.pe-xxl-3{padding-right:1rem !important}.pe-xxl-4{padding-right:1.5rem !important}.pe-xxl-5{padding-right:3rem !important}.pb-xxl-0{padding-bottom:0 !important}.pb-xxl-1{padding-bottom:.25rem !important}.pb-xxl-2{padding-bottom:.5rem !important}.pb-xxl-3{padding-bottom:1rem !important}.pb-xxl-4{padding-bottom:1.5rem !important}.pb-xxl-5{padding-bottom:3rem !important}.ps-xxl-0{padding-left:0 !important}.ps-xxl-1{padding-left:.25rem !important}.ps-xxl-2{padding-left:.5rem !important}.ps-xxl-3{padding-left:1rem !important}.ps-xxl-4{padding-left:1.5rem !important}.ps-xxl-5{padding-left:3rem !important}.text-xxl-start{text-align:left !important}.text-xxl-end{text-align:right !important}.text-xxl-center{text-align:center !important}}@media (min-width: 1200px){.fs-1{font-size:1.40625rem !important}}@media print{.d-print-inline{display:inline !important}.d-print-inline-block{display:inline-block !important}.d-print-block{display:block !important}.d-print-grid{display:grid !important}.d-print-table{display:table !important}.d-print-table-row{display:table-row !important}.d-print-table-cell{display:table-cell !important}.d-print-flex{display:flex !important}.d-print-inline-flex{display:inline-flex !important}.d-print-none{display:none !important}}body{background-size:cover}.bg-light{background-color:Rgb(var(--t42-bg-light)) !important}.bg-dark{background-color:Rgb(var(--t42-bg-dark)) !important}.bg-base{background-color:Rgb(var(--t42-bg-mid)) !important}.border{border:0.0625rem solid var(--t42-color-opacity-10) !important}.border-primary{border-color:#007be5 !important}.border-secondary,.border-info,.border-light,.border-dark,.border-white{border-color:var(--t42-color-opacity-10) !important}.border-success{border-color:#43a047 !important}.border-danger{border-color:#ff511f !important}.border-warning{border-color:#f9a825 !important}.pl-0{padding-left:0}.pl-1{padding-left:0.25rem}.pl-2{padding-left:0.5rem}.pl-3{padding-left:1rem}.pl-4{padding-left:1.5rem}.pl-5{padding-left:3rem}.pl-auto{padding-left:auto}.pr-0{padding-right:0}.pr-1{padding-right:0.25rem}.pr-2{padding-right:0.5rem}.pr-3{padding-right:1rem}.pr-4{padding-right:1.5rem}.pr-5{padding-right:3rem}.pr-auto{padding-right:auto}.ml-0{margin-left:0}.ml-1{margin-left:0.25rem}.ml-2{margin-left:0.5rem}.ml-3{margin-left:1rem}.ml-4{margin-left:1.5rem}.ml-5{margin-left:3rem}.ml-auto{margin-left:auto}.mr-0{margin-right:0}.mr-1{margin-right:0.25rem}.mr-2{margin-right:0.5rem}.mr-3{margin-right:1rem}.mr-4{margin-right:1.5rem}.mr-5{margin-right:3rem}.mr-auto{margin-right:auto}@keyframes spinner-border{to{transform:rotate(360deg) /* rtl:ignore */}}.spinner-border{display:inline-block;width:2rem;height:2rem;vertical-align:-.125em;border:.25em solid currentColor;border-right-color:transparent;border-radius:50%;animation:.75s linear infinite spinner-border}.spinner-border-sm{width:1rem;height:1rem;border-width:.2em}@keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1;transform:none}}.spinner-grow{display:inline-block;width:2rem;height:2rem;vertical-align:-.125em;background-color:currentColor;border-radius:50%;opacity:0;animation:.75s linear infinite spinner-grow}.spinner-grow-sm{width:1rem;height:1rem}@media (prefers-reduced-motion: reduce){.spinner-border,.spinner-grow{animation-duration:1.5s}}.loader-wrapper{display:flex;flex-direction:column;flex-grow:1;gap:1rem;align-items:center;justify-content:center}.loader-wrapper .loader{width:2rem;height:2rem;border-radius:50%;background:radial-gradient(farthest-side, #999d9e 94%, rgba(0,0,0,0)) center top/4px 4px no-repeat,conic-gradient(rgba(0,0,0,0) 15%, #999d9e);-webkit-mask:radial-gradient(farthest-side, rgba(0,0,0,0) calc(100% - 4px), #000 0)}.loader-wrapper.active .loader{animation:s3 1.5s infinite linear}@keyframes s3{to{transform:rotate(1turn)}}.loader-wrapper .loader-text{margin:0 auto;padding:0 0.833rem;overflow:hidden;color:var(--t42-content-color-muted);text-align:center;text-overflow:ellipsis}@keyframes clipMe{0%,100%{clip:rect(0, 220px, 2px, 0)}25%{clip:rect(0, 2px, 220px, 0)}50%{clip:rect(218px, 220px, 220px, 0)}75%{clip:rect(0, 220px, 220px, 218px)}}@keyframes spin{from{transform:rotate(0deg)}to{transform:rotate(360deg)}}.spinner{display:inline-block;animation-name:spin;animation-duration:3000ms;animation-timing-function:linear;animation-iteration-count:infinite}@font-face{font-weight:400;font-family:"Montserrat";font-style:normal;src:url(data:font/ttf;base64,AAEAAAARAQAABAAQR0RFRrFss1wAAmssAAACfkdQT1N2Wb7+AAJtrAABFy5HU1VCjJZZRgADhNwAAC8mT1MvMlYMpE4AAfmwAAAAYGNtYXBfILVpAAH6EAAACuRjdnQgMKUWggACEzwAAADkZnBnbU0kjnwAAgT0AAANbWdhc3AAAAAQAAJrJAAAAAhnbHlmzhsdpQAAARwAAct0aGVhZA5QtXgAAduUAAAANmhoZWEG0AwiAAH5jAAAACRobXR4v8HBsgAB28wAAB3AbG9jYfsbiDIAAcywAAAO4m1heHAIxQ5XAAHMkAAAACBuYW1lKqFFSQACFCAAAAHucG9zdFa6PIcAAhYQAABVE3ByZXDNS6zAAAISZAAAANUAAgAoAAACIwK8AAMABwApQCYAAAACAwACZQQBAwEBA1UEAQMDAV0AAQMBTQQEBAcEBxIREAUNFysTIREhJREhESgB+/4FAav+pQK8/URGAjD90AAAAv//AAAC3QK8AAcACgArQCgJAQQCAUoFAQQAAAEEAGYAAgJCSwMBAQFDAUwICAgKCAoREREQBgoYKyUhByMBMwEjJwMDAif+jE1nAT1jAT5pcJeXr68CvP1E/wFX/qn/////AAAC3QN3ACIABAAAAAMHEgKaAAD/////AAAC3QN3ACIABAAAAAMHGQKaAAD/////AAAC3QPhACIABAAAACcHMQKaAJYBBwcuApoBEQARsQIBsJawMyuxAwG4ARGwMysA//////88At0DdwAiAAQAAAAjBv8CmgAAAAMHGQKaAAD/////AAAC3QPhACIABAAAACcHMQKaAJYBBwctApoBEQARsQIBsJawMyuxAwG4ARGwMysA/////wAAAt0D7QAiAAQAAAAnBzECmgCWAQcHNAKaAP4AELECAbCWsDMrsQMBsP6wMyv/////AAAC3QPgACIABAAAACcHMQKaAJYBBwcyApoBEQARsQIBsJawMyuxAwG4ARGwMysA/////wAAAt0DdwAiAAQAAAADBxcCmgAA/////wAAAt0DdwAiAAQAAAADBxYCmgAA/////wAAAt0DvgAiAAQAAAAnBy8CmgCWAQcHLgNCAO4AELECAbCWsDMrsQMBsO6wMyv//////zwC3QN3ACIABAAAACMG/wKaAAAAAwcWApoAAP////8AAALdA74AIgAEAAAAJwcvApoAlgEHBy0DQgDuABCxAgGwlrAzK7EDAbDusDMr/////wAAAt0D0wAiAAQAAAAnBy8CmgCWAQcHNAMcAOQAELECAbCWsDMrsQMBsOSwMyv/////AAAC3QPmACIABAAAACcHLwKaAJYBBwcyApoBFwARsQIBsJawMyuxAwG4ARewMysA/////wAAAt0DdwAiAAQAAAADByMCmgAA/////wAAAt0DbQAiAAQAAAADBwoCmgAA//////88At0CvAAiAAQAAAADBv8CmgAA/////wAAAt0DdwAiAAQAAAADBxACmgAA/////wAAAt0DuwAiAAQAAAADByICmgAA/////wAAAt0DfQAiAAQAAAADByQCmgAA/////wAAAt0DVAAiAAQAAAADBx4CmgAA//////8gAvMCvAAiAAQAAAADBwMECAAA/////wAAAt0D1gAiAAQAAAEHBvACmgCqAAixAgKwqrAzK/////8AAALdBB0AIgAEAAABBwbxApoAqgAIsQICsKqwMyv/////AAAC3QN3ACIABAAAAAMHGgKaAAAAAv//AAAD3wK8AA8AEwBEQEEABQAGCQUGZQsBCQABBwkBZQgBBAQDXQADA0JLCgEHBwBdAgEAAEMATBAQAAAQExATEhEADwAPEREREREREQwKGyslFSE1IQcjASEVIRUhFSEVJxEjAwPf/gT+6mdnAaECMf51AV/+oWMU01dXr68CvFfXVeKoAWb+mv////8AAAPfA3cAIgAeAAAAAwcSA0AAAAADAGkAAALDArwADgAXAB8APEA5DgEEAgFKAAIABAUCBGUGAQMDAV0AAQFCSwcBBQUAXQAAAEMATBgYDw8YHxgeHRsPFw8WJyEkCAoXKwAWFRQGIyERITIWFRQGBwEVMzI2NTQmIxI2NTQjIxUzAn1GiYP+sgE6eIMzK/6NzU1TU01uVqvm5gFaWURbYgK8YFU3UBUBAOA5Nzc5/eY4PHXpAAABADD/+AKtAsQAGwAuQCsYFwsKBAIBAUoAAQEAXwAAAEhLAAICA18EAQMDSQNMAAAAGwAaJiQmBQoXKwQmJjU0NjYzMhYXByYjIgYGFRQWFjMyNxcGBiMBOalgYKppUogwQU92Tn5HR35OdVBBMIlSCF2jZmajXTc2P1NGe0xMe0ZUPzY4//8AMP/4Aq0DdwAiACEAAAADBxICxwAA//8AMP/4Aq0DdwAiACEAAAADBxcCxwAA//8AMP8gAq0CxAAiACEAAAADBwICvgAA//8AMP8gAq0DdwAiACEAAAAjBwICvgAAAAMHEgLHAAD//wAw//gCrQN3ACIAIQAAAAMHFgLHAAD//wAw//gCrQN9ACIAIQAAAAMHDgLHAAAAAgBpAAADCgK8AAoAFQAmQCMAAwMAXQAAAEJLBAECAgFdAAEBQwFMDAsUEgsVDBUmIAUKFisTITIWFhUUBgYjISUyNjY1NCYmIyMRaQEnb6xfX6xv/tkBIVWBRkaBVb0CvFifZ2efWFdCd05Od0L98gD//wBpAAAFjAN3ACIAKAAAACMA8AMYAAAAAwcXBZQAAP//AAsAAAMSArwAIgAoCAAAAwclAf8AAP//AGkAAAMKA3YAIgAoAAABBwcXAqf//wAJsQIBuP//sDMrAP//AAsAAAMSArwAIgAoCAAAAwclAf8AAP//AGn/PAMKArwAIgAoAAAAAwb/AqsAAP//AGn/UgMKArwAIgAoAAAAAwcFAqsAAP//AGkAAAUeAuEAIgAoAAAAIwJ5AzoAAAADBu0FbAAAAAEAaQAAAmUCvAALAC9ALAADAAQFAwRlAAICAV0AAQFCSwYBBQUAXQAAAEMATAAAAAsACxERERERBwoZKyUVIREhFSEVIRUhFQJl/gQB7v52AV/+oVdXArxX11XiAP//AGkAAAJlA3cAIgAwAAAAAwcSAo0AAP//AGkAAAJlA3cAIgAwAAAAAwcZAo0AAP//AGkAAAJlA3cAIgAwAAAAAwcXAo0AAP//AGn/IAJlA3cAIgAwAAAAIwcCApcAAAADBxkCjQAA//8AaQAAAmUDdwAiADAAAAADBxYCjQAA//8AaQAAAqcDvgAiADAAAAAnBy8CjQCWAQcHLgM1AO4AELEBAbCWsDMrsQIBsO6wMyv//wBp/zwCZQN3ACIAMAAAACMG/wKXAAAAAwcWAo0AAP//AGkAAAJlA74AIgAwAAAAJwcvAo0AlgEHBy0DNQDuABCxAQGwlrAzK7ECAbDusDMr//8AaQAAAmUD0wAiADAAAAAnBy8CjQCWAQcHNAMPAOQAELEBAbCWsDMrsQIBsOSwMyv//wBpAAACZQPmACIAMAAAACcHLwKNAJYBBwcyAo0BFwARsQEBsJawMyuxAgG4ARewMysA//8AaQAAAmUDdwAiADAAAAADByMCjQAA//8AaQAAAmUDbQAiADAAAAADBwoCjQAA//8AaQAAAmUDfQAiADAAAAADBw4CjQAA//8Aaf88AmUCvAAiADAAAAADBv8ClwAA//8AaQAAAmUDdwAiADAAAAADBxACjQAA//8AaQAAAmUDuwAiADAAAAADByICjQAA//8AaQAAAmUDfQAiADAAAAADByQCjQAA//8AaQAAAmUDVAAiADAAAAADBx4CjQAA//8AaQAAAmUD9AAiADAAAAAnBzMCjQCWAQcHLgKNASQAEbEBAbCWsDMrsQIBuAEksDMrAP//AGkAAAJlA/QAIgAwAAAAJwczAo0AlgEHBy0CjQEkABGxAQGwlrAzK7ECAbgBJLAzKwD//wBp/yACewK8ACIAMAAAAAMHAwOQAAD//wBpAAACZQN3ACIAMAAAAAMHGgKNAAD//wAf//gCPgK8AAIExAAA//8AH//4Aj4DdwAiBMQAAAADBxcCWgAAAAEAaQAAAlcCvAAJAClAJgAAAAECAAFlBQEEBANdAAMDQksAAgJDAkwAAAAJAAkRERERBgoYKxMVIRUhESMRIRXNAV/+oWQB7gJl9Fb+5QK8VwABADD/+AK0AsQAHQA4QDUREAIAAx0BBAACSgIBBAFJAAADBAMABH4AAwMCXwACAkhLAAQEAV8AAQFJAUwmJCYjEAUKGSsBMxEGBiMiJiY1NDY2MzIWFwcmIyIGBhUUFhYzMjcCTmA0iktqqmFhq2tUiTA+VHdQf0hIf09eRgFi/u8rLl2jZmakXDc1PlFFe01Me0YtAP//ADD/+AK0A3cAIgBKAAAAAwcZAsYAAP//ADD/+AK0A3cAIgBKAAAAAwcXAsYAAP//ADD/+AK0A3cAIgBKAAAAAwcWAsYAAP//ADD++QK0AsQAIgBKAAAAAwcBAsEAAP//ADD/+AK0A30AIgBKAAAAAwcOAsYAAP//ADD/+AK0A1QAIgBKAAAAAwceAsYAAP//ADD/+AMQAsQAIgBKAAABRwclA3D/iT1MQAAACbEBAbj/ibAzKwAAAQBpAAACwwK8AAsAJ0AkAAQAAQAEAWUGBQIDA0JLAgEAAEMATAAAAAsACxERERERBwoZKwERIxEhESMRMxEhEQLDZP5uZGQBkgK8/UQBOP7IArz+0wEt//8ACQAAAzACvAAiAFIIAAEHBwcDUQBzAAixAQGwc7AzK///AGn/LwLDArwAIgBSAAAAAwcEAsEAAP//AGkAAALDA3cAIgBSAAAAAwcXAsEAAP//AGkAAALDA3cAIgBSAAAAAwcWAsEAAP//AGn/PALDArwAIgBSAAAAAwb/AsEAAAABAGkAAADNArwAAwATQBAAAABCSwABAUMBTBEQAgoWKxMzESNpZGQCvP1EAAIAV//4Am0CvAAPABMAM0AwAwEABAIBAgACSgAEBAFdAwEBAUJLAAAAAl8FAQICSQJMAAATEhEQAA8ADhMlBgoWKwQmJzcWFjMyNjURMxEUBiMDMxEjAQN8MCcsaDdeYmSeiORkZAgmIVAeIG5vAY7+d5miAsT+eQD//wBQAAABUgN3ACIAWAAAAAMHEgHHAAD////5AAABPQN3ACIAWAAAAAMHGQHHAAD////oAAABTgN3ACIAWAAAAAMHFgHHAAD///+uAAABGwN3ACIAWAAAAAMHIwHHAAD//wALAAABKwNtACIAWAAAAAMHCgHHAAD//wAPAAABOQP0ACIAWAAAACcHKwHHAJYBBwcuAccBJAARsQECsJawMyuxAwG4ASSwMysA//8AYAAAANYDfQAiAFgAAAADBw4BxwAA//8AaP88AM4CvAAiAFgAAAADBv8BxwAA////5AAAAOYDdwAiAFgAAAADBxABxwAA//8APwAAAQADuwAiAFgAAAADByIBxwAA////+QAAAT0DfQAiAFgAAAADByQBxwAA//8AFgAAASADVAAiAFgAAAADBygBxwAA//8ATv8gAPECvAAiAFgAAAADByoB+AAA////8wAAAUMDdwAiAFgAAAADBxoBxwAAAAH/9//4AZ4CvAAQACxAKQMCAgABAUoAAQECXQACAkJLAAAAA18EAQMDSQNMAAAAEAAPERMkBQoXKxYmJzcWMzI2NREjNSERFAYjhGwhOjpYOz39AWBvbAg1MERTSEYBiVf+JXR1////9//4AaIDdwAiAGgAAAADBxYCGwAAAAEAaQAAAs4CvAALAB9AHAkGAQMAAQFKAgEBAUJLAwEAAEMATBISERIEChgrAQcVIxEzEQEzAQEjAU2AZGQBfHL+1QE+dQE3grUCvP55AYf+xf5///8AaQAAAs4DdwAiAGoAAAADBxcCowAA//8Aaf75As4CvAAiAGoAAAADBwECowAA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KAcKGSsBERQGBwYVFBYzMjY3FwYjIiY1NDcmJjURMxEUMzI2NRECs15XkCIcECEMEygyOEBFf41kxWBmArz+cnaSHjNJGBwJCDEYNy5DMQifjgGO/nbhb3IBigD//wBj//gCswPWACIAxwAAAQcG8AK4AKoACLEBArCqsDMr//8AY//4ArMDdwAiAMcAAAADBxoCuAAA//8AY//4ArMD9AAiAMcAAAAnBzICuACWAQcHLgK4ASQAEbEBAbCWsDMrsQIBuAEksDMrAAAB//8AAALJArwABgAhQB4FAQABAUoDAgIBAUJLAAAAQwBMAAAABgAGEREEChYrAQEjATMTEwLJ/s1j/sxs/P4CvP1EArz9wQI/AAEAIAAABEYCvAAMACdAJAsIAwMAAgFKBQQDAwICQksBAQAAQwBMAAAADAAMEhESEQYKGCsBAyMDAyMDMxMTMxMTBEbqab+/a+pnvcVcwcECvP1EAi/90QK8/ccCOf3EAjz//wAgAAAERgN3ACIA4AAAAAMHEgNgAAD//wAgAAAERgN3ACIA4AAAAAMHFgNgAAD//wAgAAAERgNtACIA4AAAAAMHCgNgAAD//wAgAAAERgN3ACIA4AAAAAMHEANgAAAAAQANAAAClAK8AAsAJkAjCgcEAQQAAQFKAgEBAUJLBAMCAABDAEwAAAALAAsSEhIFChcrIQMDIwEDMxMTMwMBAiHSz3MBB/dyxMJt9wEJASH+3wFnAVX+8wEN/q7+lgAAAf/8AAACiwK8AAgAHUAaBgMAAwABAUoCAQEBQksAAABDAEwSEhEDChcrJRUjNQEzExMzAXVj/upr4OFj8vL0Acj+jwFx/////AAAAosDdwAiAOYAAAADBxICcAAA/////AAAAosDdwAiAOYAAAADBxYCcAAA/////AAAAosDbQAiAOYAAAADBwoCcAAA/////AAAAosDfQAiAOYAAAADBw4CcAAA/////P88AosCvAAiAOYAAAADBv8CcAAA/////AAAAosDdwAiAOYAAAADBxACcAAA/////AAAAosDuwAiAOYAAAADByICcAAA/////AAAAosDVAAiAOYAAAADBx4CcAAA/////AAAAosDdwAiAOYAAAADBxoCcAAAAAEAKwAAAnQCvAAJAC9ALAgBAQIDAQADAkoAAQECXQACAkJLBAEDAwBdAAAAQwBM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AfIAxAAIsQEBsMSwMyv//wBb/y8CUgLmACIB2AAAAAMHBAKDAAD////YAAACUgO1ACIB2AAAAQcG7QG3ANQACLEBAbDUsDMr////2AAAAlIDoQAiAdgAAAEHBxYBtwAqAAixAQGwKrAzK///AFv/PAJSAuYAIgHYAAAAAwb/AoMAAP//AEoAAADMAvUAIgHfAAAAAwcpAbcAAAABAFsAAAC7AhIAAwATQBAAAABFSwABAUMBTBEQAgoWKxMzESNbYGACEv3u//8AQAAAAUIC4QAiAd8AAAADBucBtwAA//8AAgAAARQC4QAiAd8AAAADBzcBtwAA////8QAAASUC4QAiAd8AAAADBzYBtwAA////ngAAAQsC4QAiAd8AAAADBvsBtwAA//8AEgAAAQQC1gAiAd8AAAADBzUBtwAA/////wAAASkDXgAiAd8AAAAjBysBtwAAAQcHLgG3AI4ACLEDAbCOsDMr//8AUAAAAMYC5wAiAd8AAAADBuMBtwAA//8ASv88AMwC9QAiAd8AAAAjBykBtwAAAAMG/wG3AAD////UAAAA1gLhACIB3wAAAAMG5QG3AAD//wAvAAAA8AMlACIB3wAAAAMG+gG3AAD//wACAAABFALnACIB3wAAAAMHOgG3AAD//wBK/zgB6AL1ACIB3wAAACMHKQG3AAAAIwHwARcAAAADBykC0wAA//8ABgAAARACvgAiAd8AAAADBzkBtwAA//8APP8gAN8C9QAiAd8AAAAjBykBtwAAAAMHKgHmAAD////8AAABGgLhACIB3wAAAAMHOAG3AAD///+k/zgA0QL1ACIB8AAAAAMHKQG8AAAAAf+k/zgAwAISAA4AKUAmAwEAAQIBAgACSgABAUVLAAAAAmADAQICTQJMAAAADgANEyQEChYrBiYnNxYzMjY1ETMRFAYjDDwUHx4wJilgWFHIEBBKGS8uAiz91lJe////pP84ASoC4QAiAfAAAAADBzYBvAAAAAEAWwAAAmYC5gALACNAIAkGAQMAAgFKAAEBREsAAgJFSwMBAABDAEwSEhESBAoYKyUHFSMRMxEBMwcTIwEpbmBgASF03/V292aRAub+JAEI2/7J////2AAAAmYDtQAiAfIAAAEHBu0BtwDUAAixAQGw1LAzK///AFv++QJmAuYAIgHyAAAAAwcBAmUAAAABAFsAAAJm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yNQBDP70/////wAAAmgDBwAiAt8AAAEHBucCXwAmAAixAgGwJrAzK/////8AAAJoAwcAIgLfAAABBwbvAl8AJgAIsQIBsCawMyv/////AAACaANxACIC3wAAACcHMQJfACYBBwcuAl8AoQAQsQIBsCawMyuxAwGwobAzK///////PAJoAwcAIgLfAAAAIwb/Al8AAAEHBu8CXwAmAAixAwGwJrAzK/////8AAAJoA3EAIgLfAAAAJwcxAl8AJgEHBy0CXwChABCxAgGwJrAzK7EDAbChsDMr/////wAAAmgDfQAiAt8AAAAnBzECXwAmAQcHNAJfAI4AELECAbAmsDMrsQMBsI6wMyv/////AAACaANwACIC3wAAACcHMQJfACYBBwcyAl8AoQAQsQIBsCawMyuxAwGwobAzK/////8AAAJoAwcAIgLfAAABBwbtAl8AJgAIsQIBsCawMyv/////AAACaAMHACIC3wAAAQcG7AJfACYACLECAbAmsDMr/////wAAAnkDTgAiAt8AAAAnBy8CXwAmAQcHLgMHAH4AELECAbAmsDMrsQMBsH6wMyv//////zwCaAMHACIC3wAAACMG/wJfAAABBwbsAl8AJgAIsQMBsCawMyv/////AAACaANOACIC3wAAACcHLwJfACYBBwctAwcAfgAQsQIBsCawMyuxAwGwfrAzK/////8AAAJoA2MAIgLfAAAAJwcvAl8AJgEHBzQC4QB0ABCxAgGwJrAzK7EDAbB0sDMr/////wAAAmgDdgAiAt8AAAAnBy8CXwAmAQcHMgJfAKcAELECAbAmsDMrsQMBsKewMyv/////AAACaAMHACIC3wAAAQcG+wJfACYACLECArAmsDMr/////wAAAmgC/QAiAt8AAAEHBt8CXwAmAAixAgKwJrAzK///////PAJoAjgAIgLfAAAAAwb/Al8AAP////8AAAJoAwcAIgLfAAABBwblAl8AJgAIsQIBsCawMyv/////AAACaANLACIC3wAAAQcG+gJfACYACLECAbAmsDMr/////wAAAmgDDQAiAt8AAAEHBvwCXwAmAAixAgGwJrAzK/////8AAAJoAuQAIgLfAAABBwb2Al8AJgAIsQIBsCawMyv//////yACfgI4ACIC3wAAAAMHAwOTAAD/////AAACaANSACIC3wAAAQcG8AJf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VAD////w/zgCNgISAAICbwYA////8P84AjYC4QAiAm8GAAADB1gB8AAAAAMAK/8+AvoC5gARABgAHgA3QDQeAQAGAUoABAMEgwgBBwcDXwUBAwMiSwAGBgBfAgEAACFLAAEBJAFMFhEUEREUERERCQcdKyQGBxUjNSYmNTQ2NzUzFRYWFQQWFxEGBhUENTQmJxEC+qSVXpWjopZelaT9kG1sbWwCEW5sj44Iu7sIjXx7igjPzwiLelVgBwF0B15TrKxUXQf+iwD//wAJAAACFQISAAICbvsAAAEAKgAAAgQCEgARAC9ALBABAwIDAQEDAkoAAwABAAMBZwUEAgICIksAAAAhAEwAAAARABEjEyIRBgcYKwERIzUGIyImNTUzFRQWMzI3NQIEYFZVY2xgRT5GUQIS/e7WKFxcrKY3OCPyAAABAF3/gQKTAhIACwApQCYAAAMAUgQBAgIiSwYFAgMDAV4AAQEhAUwAAAALAAsREREREQcHGSslFSM1IREzESERMxECk1v+JWABImBU038CEv5CAb7+QgAAAQBdAAADUAISAAsAJUAiBgUDAwEBIksEAQICAF4AAAAhAEwAAAALAAsREREREQcHGSsBESERMxEzETMRMxEDUP0NYOpg6QIS/e4CEv5CAb7+QgG+AP//AF3/jwOfAhIAIgUmAAAAAwdaArIAAAABAF3/gQIoAhIACwBGS7AKUFhAGAABAAABbwUBAwMiSwAEBABeAgEAACEATBtAFwABAAGEBQEDAyJLAAQEAF4CAQAAIQBMWUAJEREREREQBgcaKyEjFSM1IxEzESERMwIot1u5YAELYH9/AhL+QgG+AAACAF3//gIhAhIACgATADBALQUBAgADBAIDZQABASJLBgEEBABeAAAAIQBMCwsAAAsTCxIRDwAKAAkRJAcHFisAFhUUBicnETMVFxI2NTQmJycVFwG3anNr5mCVKkNBQ35+AV1aUlZdAQECErMB/uk2NTQwAQLQAQACAAQAAAJhAhIADAAVADZAMwYBAwAEBQMEZQABAQJdAAICIksHAQUFAF0AAAAhAEwNDQAADRUNFBMRAAwACxERJAgHFysAFhUUBiMjESM1IRUzEjY1NCYjIxUzAfhpc2nfogECkCpAPz98fAFfW1JVXQG+VLP+6jY1MzHPAAADAF3//gLJAhIACgAOABcANkAz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hAMBAgIBXQABASEBTAAAAAUABRERBAcWKzcVIzUjNfpccVfwmVcAAQA6/2cA2wBXAAUAH0AcAAABAIQDAQICAV0AAQEhAUwAAAAFAAUREQQHFis3FSM1IzXbXURX8JlXAAEAQP+PANoAUgAFADxLsApQWEASAAABAQBvAwECAgFdAAEBIQFMG0ARAAABAIQDAQICAV0AAQEhAUxZQAsAAAAFAAUREQQHFis3FSM1IzXaV0NSw3FSAP///jICWf92A0sAIgcxAAABBgcuAHsACLEBAbB7sDMr///+MgJZ/3YDSwAiBzEAAAEGBy0AewAIsQEBsHuwMyv///4yAln/dgNXACIHMQAAAQYHNABoAAixAQGwaLAzK////i8CWf95A0oAIgcxAAABBgcyAHsACLEBAbB7sDMr///+IQJfABoDKAAiBy8AAAEHBy4AqABYAAixAQGwWLAzK////iECX//BAygAIgcvAAABBwctAKgAWAAIsQEBsFiwMyv///4hAl//pAM9ACIHLwAAAQcHNACCAE4ACLEBAbBOsDMr///+IQJf/4cDUAAiBy8AAAEHBzIAAACBAAixAQGwgbAzK////jIC7/92A+EAJwcxAAAAlgEHBy4AAAERABGxAAGwlrAzK7EBAbgBEbAzKwD///4yAu//dgPhACcHMQAAAJYBBwctAAABEQARsQABsJawMyuxAQG4ARGwMysA///+MgLv/3YD7QAnBzEAAACWAQcHNAAAAP4AELEAAbCWsDMrsQEBsP6wMyv///4vAu//eQPgACcHMQAAAJYBBwcyAAABEQARsQABsJawMyuxAQG4ARGwMysA///+IQL1ABoDvgAnBy8AAACWAQcHLgCoAO4AELEAAbCWsDMrsQEBsO6wMyv///4hAvX/wQO+ACcHLwAAAJYBBwctAKgA7gAQsQABsJawMyuxAQGw7rAzK////iEC9f+kA9MAJwcvAAAAlgEHBzQAggDkABCxAAGwlrAzK7EBAbDksDMr///+IQL1/4cD5gAnBy8AAACWAQcHMgAAARcAEbEAAbCWsDMrsQEBuAEXsDMrAAABAF//ZwC8ABcAAwAYQBUAAQAAAVUAAQEAXQAAAQBNERACBxYrFyM1M7xdXZmwAAABAF7/jwC5ABUAAwAYQBUAAQAAAVUAAQEAXQAAAQBNERACBxYrFyM1M7lb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UXdRg1GUUaVRtlHHUdhR6VICUhtSgFKLUp9SsFLJUuJS+1NDU3xTuVQOVFFUYlRzVH9UkFScVK1UuVUPVSBVOVVBVVJVa1V3VYhVlFWlVbFVxlZEVmNWdFaFVpFWnVauVrpWxlb0VwVXFlcnVzhXSVdaV2ZXd1eIV5lXslfHV+BX+VgSWCNYNFhFWF5YrFi9WM5Y51kLWTxZTVleWW9ZgFmtWdBZ4VnyWgNaFFogWjFaQlpTWmRaklqjWrRaxVrRWw1bHlsvW0hbXVt2W49bqFu5W8pb41v4XBFcKlxDXFRcZVxxXIJck1ykXLVcwVzSXONc9F1ZXWpdf13WXedd+F4JXh5eL15IXl1edl6PXqheuV7KXtte5174XwlfGl8rX0RfXV/pX/pgSGCBYOJg82EEYRVhJmE3YUhhXGGGYY5hn2HtYf5iD2IgYjFiSmJWYmdieGKJYsVi1mLiYvNjKGM5Y0VjpmOyY/dkCGQZZCVkNmRCZKJkrmS6ZMtlFmVAZVFlYmVuZXpli2WXZaNl7WX+Zg9mIGYxZkJmU2ZfZnBmgWaSZqtmwGbZZvJnC2ccZy1nPmdXZ2NndGeFZ55n5mf3aAhoGWgqaHVohmiXaKhouWjKaNto7Gj9aQ5pSWlaaWtpfGmIad9qH2onamJqr2rNatlq+ms7a0NrT2tba5tr+WwfbCtsN2yNbLtsx20hbVVtXW1lbYltkW2Zbblt8m3+blBugG62buJvDm8ab0Fvem+4b8Rv0HAxcDlwSXCYcK5wunDCcQBxc3G1ciRybXK4csxzGXNJc5hzpHOwc7xz+nQ3dGt0d3SDdNZ04nWZdaV1sXW5dc112XYNdhl2XXaTdp93B3cTdxt3J3dud6x34XggeF54anh2eH54injheO14+XkFeVF5XXlpeXV5iXmhea15uXnFedF53Xnoefh6RnqQesh7I3txe3l7qnvzfEF8f3yLfMJ85n05fWN9b317fYd9j33Ufdx96H30ffx+CH6nfrN+6380fzx/RH9Qf5p/5IA1gKOBM4GugbaCDoIagiaCMoI6gkaCUoJegmqCdoKCgo6CloLvgveDXYOng8SD1oQHhEeET4RbhGeEo4T+hSSFMIU8hZKFvYXJhhiGS4ZxhnmGnYalhq2GzYbVhuGHMIc4h22HmYfEh9CICYhFiISIyYjViTKJOolKiZaJoomuibqKAYqKisiLJouKi9uL44wxjF+MrYy5jRaNIo1djZ6Nz43bjeeN845FjtOO347rjw6PIo8uj2KPbo+vj7eP95BZkGWQbZB5kL6ROJF6ka2R6pImkjKSPpJGklKSpJKwkrySyJMRkx2TKZM1k4eTk5Ofk6uTt5PDk8+T2pPmlDWUepSylQqVXJVklZWV35ZXlpmWpZcDl1qXYpell/6YBpgSmB6YT5hymHqYgpiKmL+Yy5ktmTmZgZnPmkaabpp6moaamJrymv6bBpsSmyabLps2mz6bSptWm16bapvom/ScRJxMnFScYJyonPadXp3GnkCemJ6knrCeuJ7EnxOfH58rnzefQ59Pn1ufZ5+/n+agMqB0oLCgwaDJoQqhKaFpobKh5aItoo+izaM4o5mj36P9pD2kiKS+pQelD6VSpVqlaKV3pYallaWkpbOlwqXRpeCl76X+pkCmaKaopvCnI6drp82oC6h2qNipHqlFqYWpzqoDqkyqVKqXqp+rA6sRqx+rLas7q0mrV6tlq3OrgauPq8mr76wtrHOso6zlrTytd63Xri+uPq5krqKu6K73rzqvSa+Fr5Svo6+yr8Gv0K/fr+6v/bAMsBuwKrA5sFGwYbBxsIGwkbChsLGwwbDRsOGxFrExsVaxe7GNsbqxyrH5siiylLK2swuzZLNws4ezmbOws8yz57QMtBm0PrRVtHq0vrUFtSW1SLVrtZG1nrWrtbi1xbXStd+1+LYRtiq2MrZLtlO2W7ZotnW2graOtpq2ubbbtue287b/tya3Ubd+t5O3qLe1t8K38bgiuC64OrhZuHu4nbjxuUi5VLlguWy5eLmfucq597oNuiq6Oro6ujq6Oro6ujq6OrqWuuG7c7vfvFG8371Jvbq98r5UvsO+/79Xv6C/28BIwFjA5cErwXzBwsHswizCuML4wwDDRcNNw3XDjsOrw/XEJ8SBxJfErsTYxQTFOsW+xjLGUMayxybHacdxx3nHnMfVyATIDMhvyR7J/sodyjXKW8p0ypPKq8rUyuzLHss8y1vLfsuly8vL3sv6zBTMKsxUzGbMdsyOzJ7MxMzczQLNGs3KzjjOY87iz2TP6tAx0HnQj9Cx0QbRK9Fi0cvSU9J60pHSsdK+03fT5dQk1DXURtRX1IHUktSs1L3U1tTn1PjVHtU11VrVf9WP1cHWA9ZI1rzWzdbe1u/XDdce1y/XQNd115vXydf22CLYS9iJ2LnY+dkx2WHZftmc2brZzNnm2iHaONpP2mbajNqj2rna0Nrl2vzbE9s121bbd9uO27zcLNxD3FrccdyL3KLcudzQ3QHdI91N3Wfded2P3andzN4L3lPehN6k3sTe5t8I3zLfld+53+rgMuBU4Hzg8uEJ4S/hU+Ft4Yrhl+Gj4cDh2eH24ibiVOJu4oripuKv4rjiweLK4tPi3OLl4u7i9+MA4wnjEuMb4zTjTeNk45LjwOPs5AnkJuRS5GLkcuSC5JLko+S05MXk1uTt5QTlGuUx5UflXeVz5YrlouW6AAAAAQAAAAczM3QVnhxfDzz1AAcD6AAAAADWC/5GAAAAANYeQAX8uP75Bk0EHQAAAAcAAgAAAAAAAAJLACgAAAAAAQ0AAAENAAAC3P//Atz//wLc//8C3P//Atz//wLc//8C3P//Atz//wLc//8C3P//Atz//wLc//8C3P//Atz//wLc//8C3P//Atz//wLc//8C3P//Atz//wLc//8C3P//Atz//wLc//8C3P//Atz//wQX//8EF///AvUAaQLTADAC0wAwAtMAMALTADAC0wAwAtMAMALTADADOgBpBa4AaQNCAAsDOgBpA0IACwM6AGkDOgBpBUMAaQKeAGkCngBpAp4AaQKeAGkCngBpAp4AaQKeAGkCngBpAp4AaQKeAGkCngBpAp4AaQKeAGkCngBpAp4AaQKeAGkCngBpAp4AaQKeAGkCngBpAp4AaQKeAGkCngBpAm8AHwJvAB8CewBpAwQAMAMEADADBAAwAwQAMAMEADADBAAwAwQAMAMnADADLABpAzwACQMsAGkDLABpAywAaQMsAGkBNgBpAtAAVwE2AFABNv/5ATb/6AE2/64BNgALATYADwE2AGABNgBoATb/5AE2AD8BNv/5ATYAFgE2AE4BNv/zAgH/9wIB//cCzwBpAs8AaQLPAGkCUgBpBFMAaQJSAFACUgBpAlIAaQJSAGkCUgBpA24AaQJSAGkCWgAJA7sAaQO7AGkDLABpBS0AaQMsAGkDLABpAywAaQMsAGkDLABpAywAaQRIAGkDLABpAywAaQNIADADSAAwA0gAMANIADADSAAwA0gAMANIADADSAAwA0gAMANIADADSAAwA0gAMANIADADSAAwA0gAMANIADADSAAwA0gAMANIADADSAAwA0gAMANIADADSAAwA0gAMANIADADSAAwA0gAMANIADADSAAwA0gAMANIADADSAAwA0gAMANIADAEZgAwAtIAaQLSAGkDSAAwAtcAaQLXAGkC1wBpAtcAaQLXAGkC1wBpAtcAaQLXAGkCbQApAm0AKQJtACkBAgBQAm0AKQJtACkCbQApAm0AKQJtACkCbQApAm0AKQJtACkC+wBjAzEAMAJLAAQCSwAEAksABAJLAAQCSwAEAksABAJLAAQDFwBjAxcAYwMXAGMDFwBjAxcAYwMXAGMDFwBjAxcAYwMXAGMDFwBjAx8AYwMfAGMDHwBjAx8AYwMfAGMDHwBjAxcAYwMXAGMDFwBjAxcAYwMXAGMDFwBjAxcAYwMXAGMCyP//BGYAIARmACAEZgAgBGYAIARmACACoQANAof//AKH//wCh//8Aof//AKH//wCh//8Aof//AKH//wCh//8Aof//AKRACsCkQArApEAKwKRACsCkQArAtAAVwMgAGMDIABjAyAAYwMgAGMDIABjAyAAYwMgAGMDIABjAyAAYwMgAGMDIABjAyAAYwMgAGMDIABjAyAAYwMgAGMDIABjAyAAYwMgAGMDIABjAyAAYwMgAGMDIABjAyAAYwMgAGMDIABjBDIAWgQyAFoFrgBpBU0AaQKEADMChAAzAoQAMwKEADMChAAzAoQAMwKEADMChAAzAoQAMwKEADMChAAzAoQAMwKEADMChAAzAoQAMwKEADMChAAzAoQAMwKEADMChAAzAoQAMwKEADMChAAzAl4AYwMEADADBAAwAwQAMAMEADADBAAwAwQAMAMEADADLAAwAcgAKwLQAFcByAArAtAAVwHIACsByAArAcj/+AHIACsByAArAcgAKwHIACsByAArAcgAKwHIACsByAArAcgAKwHIACsB///3Af//9wRvAGkEywBpBMsAaQMeAGkFHQBpAx4AaQMeAGkDHgBpAx4AaQMeAGkDHgBpBDoAaQMeAGkDHgBpA0gAMAMxAEUCVv/8Alb//AJW//wCVv/8Alb//AJW//wCVv/8AxoAYwMaAGMDGgBjAxoAYwMaAGMDGgBjAxoAYwMaAGMDGgBjAxoAYwMaAGMDGgBjAxoAYwMaAGMDGgBjAxoAYwMaAGMDGgBjAxoAYwMaAGMDGgBjAxoAYwMaAGMDGgBjBKYAYwSmAGMEpgBjBKYAYwSmAGMDEwBeAxMAXgMTAF4DEwBeAxMAXgMTAF4DEwBeAxMAXgMTAF4DEwBeApsAMAKbADACmwAwApsAMAKbADACVgAyAlYAMgJWADICVgAyAlYAMgJWADICVgAyAlYAMgJWADICVgAyAlYAMgJWADICVgAyAlYAMgJWADICVgAyAlYAMgJWADICVgAyAlYAMgJWADICVgAyAlYAMgJWADICVgAyAlYAMgPdADID3QAyAqoAWwI7ACoCOwAqAjsAKgI7ACoCOwAqAjsAKgI7ACoCqgAqAoAAKgKqACoCqgAqAqoAKgKqACoEuwAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAg//7AIP/+wBYQAPArIAKgKyACoCsgAqArIAKgKyACoCsgAqArIAKgK6ACoCqQBbAqkAAAKpAFsCqf/YAqn/2AKpAFsBFwBKARcAWwEXAEABFwACARf/8QEX/54BFwASARf//wEXAFABFwBKARf/1AEXAC8BFwACAjMASgEXAAYBFwA8ARf//AEc/6QBHP+kARz/pAJoAFsCaP/YAmgAWwJeAFsBFwBbARcAQAEXAFsBFwBYAVoAWwEXAFgCMwBbARf/6AEn//kEIQBbBCEAWwKpAFsCqQBbAwIANQKpAFsCqQBbAqkAWwKpAFsCqQBbA8UAWwKpAFsCqQBbAnsAKgJ7ACoCewAqAnsAKgJ7ACoCewAqAnsAKgJ7ACoCewAqAnsAKgJ7ACoCewAqAnsAKgJ7ACoCewAqAnsAKgJ7ACoCewAqAnsAKgJ7ACoCewAqAn8AKgJ7ACoCewAqAnsAKgJ7ACoCewAqAnsAKgJ7ACoCewAqAnsAKgJ7ACoCewAqAnsAKgQrACoCqgBbAqoAWwKqACoBmgBbAZoAWwGaADcBmgBYAZr//QGaAFgBmgBIAZr/6AH1ABgB9QAYAfUAGAD/AFAB9QAYAfUAGAH1ABgB9QAYAfUAGAH1ABgB9QAYAfUAGAKkAFsBMgAZAZ4ADwGoABQBngAPAZ4ADwGeAA8BngAJAZ4ADwGeAA8CpQBWAqUAVgKlAFYCpQBWAqUAVgKlAFYCpQBWAqUAVgKlAFYCpQBWAq0AVgKtAFYCrQBWAq0AVgKtAFYCrQBWAqUAVgKlAFYCpQBWAqUAVgKlAFYCpQBWAqUAVgKlAFYCL//+A4MABgODAAYDgwAGA4MABgODAAYCKAAOAi//6gIv/+oCL//qAi//6gIv/+oCL//qAi//6gIv/+oCL//qAi//6gIJACgCCQAoAgkAKAIJACgCCQAoAjIASAKqACoCqgAqAqoAKgKqACoCqgAqAqoAKgKqACoCqgAqAqoAKgKqACoCqgAqAqoAKgKqACoCqgAqAqoAKgKqACoCqgAqAqoAKgKqACoCqgAqAqoAKgKqACoCqgAqAqoAKgKqACoCqgAqA90AMgPdADIEvQAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAArAVMAWwFBAFsBQQBAAUEAWwFBAFsBbQBbAUEAWwI1AFsBQQApAUH/8QQ6ACoBiwBWAZUADAGLAFYBiwBWAYsAVgGL//YBiwBWAYsASAPZAFYD2QBWA9kAVgPZAFYD2QBWAqUAVAKlAFQCpQBUAqUAVAKlAFQCpQBUAqUAVAKlAFQCpQBUAhMALQITAC0CEwAtAhMALQITAC0EsQAEAsgADwJ4AA8CugBbAosADwJn//8CZ///Amf//wJn//8CZ///Amf//wJn//8CZ///Amf//wJn//8CZ///Amf//wJn//8CZ///Amf//wJn//8CZ///Amf//wJn//8CZ///Amf//wJn//8CZ///Amf//wJn//8CZ///A2z//wNs//8ChABhAmEALAJhACwCYQAsAmEALAJhACwCYQAsAmEALAK+AGEC0gAgAr4AYQLSACACvgBhAr4AYQTOAGECOgBhAjoAYQI6AGECOgBhAjoAYQI6AGECOgBhAjoAYQI6AGECOgBhAjoAYQI6AEMCOgBhAjoAYQI6AGECOgBhAjoAYQI6AGECOgBhAjoAYQI6AGECOgBhAjoAYQKcACwCMAAlAjAAJQIgAGECjgAsAo4ALAKOACwCjgAsAo4ALAKOACwCjgAsAq8ALAK7AGEC4wAiArsAYQK7AGECuwBhArsAYQEiAGEBIgBhASIARgJQAEEBIgAIASL/9wEi/6QBIgAYASIABQEiAFYBIgBeASL/2gEiADUBIgAIAm8ATAEiAAwBIgBDASIAAgHB//wBwf/8AmwAYQJsAGECbABhAmwAYQH7AGEB+wBHAfsAYQH7AGEB+wBhAfsAYQO8AGEB+wBhAfv/+AMyAGEDMgBhArsAYQK7AGECuwBhArsAYQK7AGECuwBhArsAYQR8AGECuwBhArsAYQLCACwCwgAsAsIALALCACwCwgAsAsIALALCACwCwgAsAsIALALCACwCwgAsAsIALALCACwCwgAsAsIALALCACwCwgAsAsIALALCACwCwgAsAsIALALCACwCwgAsAsIALALCACwCwgAsAsIALALCACwCwgAsAsIALALCACwCwgAsAsIALALCACwDqwAsAm8AYQJvAGECwgAsAnYAYQJ2AGECdgBhAnYAYQJ2AFQCdgBhAnYAYQJ2AGECEwAlAhMAJQITACUA/wBQAhMAJQITACUCEwAlAhMAJQITACUCEwAlAhMAJQITACUCigBbAe0ABAHtAAQB7QAEAe0ABAHtAAQB7QAEAe0ABAHtAAQCqABbAqgAWwKoAFsCqABbAqgAWwKoAFsCqABbAqgAWwKoAFsCqABbArAAWwKwAFsCsABbArAAWwKwAFsCsABbAqgAWwKoAFsCqABbAqgAWwKoAFsCqABbAqgAWwKoAFsCaQAIA70AIgO9ACIDvQAiA70AIgO9ACICPAAMAjkAAgI5AAICOQACAjkAAgI5AAICOQACAjkAAgI5AAICOQACAjkAAgIrACkCKwApAisAKQIrACkCKwApAq8AWwKvAFsCrwBbAq8AWwKvAFsCrwBbAq8AWwKvAFsCrwBbAq8AWwKvAFsCrwBbAq8AWwKvAFsCrwBbAq8AWwKvAFsCrwBbAq8AWwKvAFsCrwBbAq8AWwKvAFsCrwBbAq8AWwKvAFsDmQBVA5kAVQToAGECJwAqAicAKgInACoCJwAqAicAKgInACoCJwAqAicAKgInACoCJwAqAicAKgInACoCJwAqAicAKgInACoCJwAqAicAKgInACoCJwAqAicAKgInACoCJwAqAicAKgKcADkCCABbAo4ALAKOACwCjgAsAo4ALAKOACwCjgAsAo4ALAK0ACwBqgA5AaoAOQGqADkCbwBBAaoAOQGqADkBqv/pAaoAOQGqADkBqgA5AaoAHwGqADkBqgA5Am8ATAGqADkBqgA5AaoAOQHB//wBwf/8A7wAYQQAAGEEAABhAq4AYQKuAGECrgBhAq4AYQKuAGECrgBhAq4AYQRvAGECrgBhAq4AYQLCACwB9//8Aff//AH3//wB9//8Aff//AH3//wB9//8Aff//AKuAFsCrgBbAq4AWwKuAFsCrgBbAq4AWwKuAFsCrgBbAq4AWwKuAFsCtgBbArYAWwK2AFsCtgBbArYAWwK2AFsCrgBbAq4AWwKuAFsCrgBbAq4AWwKuAFsCrgBbAq4AWwP/AFsD/wBbA/8AWwP/AFsD/wBbAqMAVgKjAFYCowBWAqMAVgKjAFYCowBWAqMAVgKjAFYCowBWAqMAVgIrACkCKwApAisAKQIrACkCKwApAZQAJQGiACAC9gAMAtsAbQLrAG0CQgBtAkIAbQJFAG0DJAANApkAbQKZAG0CmQBtBAUAEwKCACADNwBtAzcAbQM3AG0DUwBtAscAbQLHAG0DFgANA8MAbQM0AG0DUAAzAzUAbQLKAG0CzgA0AlsADQKzABACswAQA54ALQKcABEC4AA2Az0AbQRHAG0EYABtAycAbQLJAG0DPAANA+EAbQSjAA0EnABtAnwAMQLEADUCwwAdAT0AbQE2AAsCHAASA0oADQRLAG0C2wA6A0EADgMrABMDhAASA1AAMwL5AA4CagAeAr8AbQQsABMCggAgAvMAbQLkAG0C3QAjAzsADQNPAG0EPwBtBKwAbQNQAG0DzgA5As4ANAJbAA0CmwAGAof//ALBABEDzgAOAvsANgLgADUC4ABtAyUAbQPdACAD3QAgAT4AbQQFABMCygBtAy8AbQNQAG0C3AAzA+gAbQL2AAwC9gAMBBYABwKZAG0DNwApAzcAKQQFABMCggAgAm8AHwM3AG0DNwBtA1AAMwNQADMDUAAzAsMAHQKzABACswAQArMAEALgADYCQgBtA+EAbQJrAB0CoAAOAqwAGgKCADkDFwAMA1YAMwQ9ABUC4wAfAt0AbQMw/7QDMQANAxkADgLlAA0DnQAxAk8AbQKCACACzgA0As4ANAMgAGMDRAAeAoQAMwKEADMChAAzAxoAYwMaAGMDGgBjAxoAYwMWACACzQBcAncADQMTAF4DEwBeA58AMgLMAF8DaAAOA+EAXwSfAAwEjABtAf//9wM7ABMCdwANAyAAYwMgAGMEMgBaAoQAMwMaAGMDGgBjAxMAXgMTAF4DEwBeA+EAXwNIADAC7wAaAk0AMAKWAD4CZgBdAegAXQHoAF0B0gBdApgACAJ0ACwCdAAsAnQALANRAA0CIAAcArYAXQK2AF0CtgBdAswAXQJWAF0CVgBdAoEABQMeAF0CqQBdAoEALAKlAF0CsABdAjsALAHtAAQCO//wAjv/8AMlACsCHQAJAmEAKgKyAF0DrQBdA60AXQKGAF0CPwBdAn8ABAMnAF0DpgAFA7gAXQIYACsCQQAsAj8AGAEbAEwBFwASARz/ogKi/9wDbABdAmQAMAKj//YCZQAAAsAADwKKACwCVAAFAgQAKwJZAF0DcgANAiAAHAJWAF0CZgBbAlUAAAKeAAQCvgBdA3YAXQKlAF0D0ABdAyYALwI7ACwB7QAEAj4ABgI+AAYCHQAJAwMABQJ6ACoCYQApAqIAXQK8AF0DAwAVAwMAFQEbAF0DUQANAlYAXQKXAAUCrwBdAr8AXQJeACcDPQBdAk0AMAJNADAD4wAwAnQALAJzADgCcwA4A1EADQIgABwCD//sArYAXQK2AF0CgQAsAooALAKKACwCPwAYAjv/8AI7//ACO//wAmEAKgHoAF0DJwBdAewADQIdAAsCOQAWAiAANQKBAAUCsAAuA6oACQJeABYCuwBeAqn/pQKWAAUCfgBMAiEALgKzACkDUQANAe7/9wKeAE0CngBNAp4ATQJVAF4CPAAFAqkAXQKiAF0EGwBdAmMALAK3AE0EGwBOBDQATgJAAFACnAAFA1cAXgH0AF0CIAAcAjsALAHoAF0CbgAnARcABgKzACcCpQBWBBsATgKqACoCswApAmQAKgJkACoCZAAqAp4ATQKeAE0CngBNAp4ATQKWAEYEGwBdAqUAVAKlAFQCSQBQAqUABQMoAFADrQAIA7IAXQJ6//wCqgAqAqoAKgPdADICZAAqAmQAKwJkACsCngBNAp4ATQKlAFQCpQBUAqUAVAMoAFACawARAtz//wOCAAkCqgBbAtT/+ALc//8CzwBpApsAMAFyAAgCPgAOAjwABQKdACYCPgARAmkAMAJWAB4ChAAsAmkAHAKsADIBcgAIAj4ABgI8AAYCnQAmAj4AEQJpADACVgAeAoQALAJpABwBrgAcAa4AUQGuABwBrgAbAa4AFgGuABsBrgAlAa4AJAGuABwBrgAgArwAPQK8AJACvAA8ArwAPgK8ADUCvABBArwASgK8AEkCvAA7ArwAQQK8ADwCvACQArwARwK8AD4CvAA1ArwAQQK8AEoCvABJArwAOwK8AEEBrgAcAa4AUQGuABwBrgAbAa4AFgGuABsBrgAlAa4AJAGuABwBrgAgAa4AHAGuAFEBrgAcAa4AGwGuABYBrgAbAa4AJQGuACQBrgAcAa4AIAGuABwBrgBRAa4AHAGuABsBrgAWAa4AGwGuACUBrgAkAa4AHAGuACABrgAcAa4AUQGuABwBrgAbAa4AFgGuABsBrgAlAa4AJAGuABwBrgAgAK7/QgQKAFEECgBRBAoAHAQKAFEECgAbBAoAUQQKABsECgAbBAoAJAGQABMBYP/aAQsAQgE6AEIA4wAuAOMAMAKzAC4BDABFAQwARQK/ABsA4wAuAj0ACQI9AEUBhwA/ANIAPwDjAC4BYP/kAfQAAAFg/9oBHwBMAU4ATAFYAH4BYP/kAIEALQFfADkBXwATAU0AaQFNABMBUQBfAVIAIAFzAEMBcwAdAWEAcwFhAB0BZQBpAWYAKgPoAAAB9AAAArwALwPoAAABfwA5AX8AOQF/ADkD6AAAAfQAAAGTAEMB+AAuAfgAIgE4AC4BOAAiAaAAMAGgAC4BoAAwAOMALgDjADAA4wAwAgwAOAIMACwBTAA4AUwALAEMAEUBDABFAdwALgHdACIBIgAuASMAIgDnADMCCgAIAgkARQGHAD8BnwAwAZ8ALgGfADAA4gAuAOIAMADjADAA0gA/AUkAJAFJACsCvAAAAGQAAADjAAABDQAAAIYAAAAAAAAC0wAwAjsAKgLTADACvAAfAm0AKQKqACoDJwAeAcH/pAKXAB4DBAAwAzgAVwKUAB4ChgAeAsgAHgOUAGkDcAAeBmoAaQNLAB4C7gAeAtAAHQKGAB4C0QBMAqoAMwSqAB4Cw//8AR8ATAIaAEwBYP/kAkYAQwJGAEMCRgBrAkYAQwJGAEMCRgBDAkYAQwJGAEMCRgBDAkYAQwJGAEMCRgA6AkYAOgJGAEMCRgAlA5sAKgGP/90DggAJAtz//wMsAGkCkQArAyMAQwKqAFsCvABIA0sAJQS6ACUCWABgAlgAeAJYAEMCWAB5AlgAagJYAG4CWABgAlgAbwLZADICWABfAlgAYAJYAEMCWABq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Bz4HPQdEB0MHTAdKB0cHQAdFB0EHRgdJB04HUwdSB1QHUAblBucG7AbyBvYG7wbjBt8G+gbwBuoG7QRuBG8ElwRqBI8EjgSRBJIEkwSMBI0ElAR3BHQEgQSIBGYEZwRoBGkEbARtBHAEcQRyBHMEdgSCBIMEhQSEBIYEhwSKBIsEiQSQBJUElgUGBQcFCAUJBQwFDQUQBREFEgUTBRYFIgUjBSUFJAUmBScFKgUrBSkFMAU1BTYFDgUPBTcFCgUvBS4FMQUyBTMFLAUtBTQFFwUUBSEFKASYBTgEmQU5BJoFOgSbBTsEdQUVBNgFeQTZBXoEawULBJwFPASdBT0EngU+BJ8FPwSgBUAEoQVBBKIFQgSjBUMEpAVEBKUFRQSmBUcEqAVIBKkFSQSqBUoEqwVLBKwFTAStBU0ErgVOBK8FTwSwBVAEsQVRBLMFUwS0BVQEtQS2BVYEtwVXBVgEuAVZBLkFWgS6BVsEuwVcBVUEvAVdBL0FXgS+BV8EvwVgBMAFYQTBBWIEwgVjBMMFZATEBWUExQVmBMYFZwTHBWgEyAVpBMkFagTKBWsEywVsBMwFbQTNBW4EzgVvBM8FcATQBXEE0QVyBNIFcwTTBXQE1AV1BNUFdgTWBXcE1wV4BKcFRgSyBVIE2gV7BNsFfAAlAasALQGyAC4BswBEAckAQwHIADQBuQBQAdYAVwHdAFQB2gBfAeUAcwH7AHUB/QB4AgAAfgIGAH8CBwCCAgoAowIrAKQCLACeAiYAnQIlAK8CNwCxAjkAuwJDALwCRAC0AjwAtwI/AL0CRQDFAk4AxgJPAN4CZwDaAmMA5AJtAOECagDjAmwA6gJzAPQCfQAVAZsAFwGdAA4BlAAQAZYAEQGXABIBmAAPAZUABwGNAAkBjwAKAZAACwGRAAgBjgA+AcMAQAHFAEYBywA2AbsAOAG9ADkBvgA6Ab8ANwG8AGMB6QBhAecAkQIZAJMCGwCIAhAAigISAIsCEwCMAhQAiQIRAJUCHQCXAh8AmAIgAJkCIQCWAh4AzgJXANACWQDSAlsA1AJdANUCXgDWAl8A0wJcAOwCdQDrAnQA7QJ2AO8CeAZzBnUGdwZ0BngGSgZJBkgGSwZXBlgGVgbVBtYGJwaBBoUGfgZ/BoQGjwaKBoIGgwZ5Bo4GjAaGBocGiwW/Bb4GtQavBrEGswa3BrgGtgaw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AREBEgETARQAYwEVAK4AkAEWACUAJgD9AP8AZAEXARgBGQAnARoA6QEbARwBHQEeAR8AKABlASABIQEiAMgBIwEkASUBJgEnASgAygEpASoAywErASwBLQEuAS8BMAExATIBMwApACoA+AE0ATUBNgE3ATgBOQArAToBOwE8AT0BPgAsAT8AzAFAAM0BQQDOAUIA+gFDAM8BRAFFAUYBRwFIAC0BSQAuAUoBSwAvAUwBTQFOAU8BUAFRAVIBUwDiADABVAAxAVUBVgFXAVgBWQFaAVsBXAFdAGYAMgDQAV4A0QFfAWABYQFiAWMBZABnAWUBZgFnANMBaAFpAWoBawFsAW0BbgFvAXABcQFyAXMBdACRAXUArwF2AXcBeACwADMA7QA0ADUBeQF6AXsBfAF9AX4BfwA2AYABgQGCAOQBgwD7AYQBhQGGAYcBiAGJAYoANwGLAYwBjQGOAY8BkAA4ANQBkQGSANUBkwBoAZQA1gGVAZYBlwGYAZkBmgGbAZwBnQGeAZ8BoAGhAaIBowA5ADoBpAGlAaYBpwA7ADwA6wGoALsBqQGqAasBrAGtAa4APQGvAOYBsAGxAbIBswG0AbUBtgG3AbgBuQG6AbsBvAG9Ab4BvwHAAcEBwgHDAcQBxQHGAccByAHJAcoBywHMAc0BzgHPAdAB0QHSAdMB1AHVAdYB1wHYAdkB2gHbAdwB3QHeAd8B4AHhAeIB4wHkAeUB5gHnAegB6QHqAesB7AHtAe4B7wHwAfEB8gHzAfQB9QH2AfcB+AH5AfoB+wH8Af0B/gH/AgACAQICAgMCBAIFAgYCBwIIAgkCCgILAgwCDQIOAg8CEAIRAhICEwIUAhUCFgIXAhgCGQIaAhsCHAIdAh4CHwIgAiECIgIjAiQCJQImAicCKAIpAioCKwIsAi0CLgIvAjACMQIyAjMCNAI1AjYCNwI4AjkCOgI7AjwCPQI+Aj8CQAJBAkICQwJEAkUCRgBEAGkCRwJIAkkCSgJLAkwCTQBrAk4CTwJQAlECUgJTAGwCVABqAlUCVgJXAlgAbgJZAG0AoAJaAEUARgD+AQAAbwJbAlwCXQBHAOoCXgEBAl8CYAJhAEgAcAJiAmMCZAByAmUCZgJnAmgCaQJqAHMCawJsAHECbQJuAm8CcAJxAnICcwJ0AnUCdgBJAEoA+QJ3AngCeQJ6AnsCfABLAn0CfgJ/AoACgQBMANcAdAKCAHYCgwB3AoQChQKGAHUChwKIAokCigKLAowATQKNAo4ATgKPApACkQBPApICkwKUApUClgKXApgA4wBQApkAUQKaApsCnAKdAp4CnwKgAqECogB4AFIAeQKjAHsCpAKlAqYCpwKoAqkAfAKqAqsCrAB6Aq0CrgKvArACsQKyArMCtAK1ArYCtwK4ArkAoQK6AH0CuwK8Ar0AsQBTAO4AVABVAr4CvwLAAsECwgLDAsQAVgLFAsYCxwDlAsgA/ALJAsoCywLMAs0AiQLOAFcCzwLQAtEC0gLTAtQC1QBYAH4C1gLXAIAC2ACBAtkAfwLaAtsC3ALdAt4C3wLgAuEC4gLjAuQC5QLmAucC6ABZAFoC6QLqAusC7ABbAFwA7ALtALoC7gLvAvAC8QLyAvMAXQL0AOcC9QL2AvcC+AL5AvoC+wL8Av0C/gL/AwADAQMCAwMDBAMFAwYDBwMIAwkDCgMLAwwDDQMOAw8DEAMRAxIDEwMUAxUDFgMXAxgDGQMaAxsDHAMdAx4DHwMgAyEDIgMjAyQDJQMmAycDKAMpAyoDKwMsAy0DLgMvAzADMQMyAzMDNAM1AzYDNwM4AzkDOgM7AzwDPQM+Az8DQANBA0IDQwNEA0UDRgNHA0gDSQNKA0sDTANNA04DTwNQA1EDUgNTAMAAwQNUA1UDVgNXA1gDWQNaA1sDXANdA14DXwNgA2EDYgNjA2QDZQNmA2cDaANpA2oDawNsA20DbgNvA3ADcQNyA3MDdAN1A3YDdwN4A3kDegN7A3wDfQN+A38DgAOBA4IDgwOEA4UDhgOHA4gDiQOKA4sDjAONA44DjwOQA5EDkgOTA5QDlQOWA5cDmAOZA5oDmwOcA50DngOfA6ADoQOiA6MDpAOlA6YDpwOoA6kDqgOrA6wDrQOuA68DsAOxA7IDswO0A7UDtgO3A7gDuQO6A7sDvAO9A74DvwPAA8EDwgPDA8QDxQPGA8cDyAPJA8oDywPMA80DzgPPA9AD0QPSA9MD1APVA9YD1wPYA9kD2gPbA9wD3QPeA98D4APhA+ID4wPkA+UD5gPnA+gD6QPqA+sD7APtA+4D7wPwA/ED8gPzA/QD9QP2A/cD+AP5A/oD+wP8A/0D/gP/BAAEAQQCBAMEBAQFBAYEBwQIBAkECgQLBAwEDQQOBA8EEAQRBBIEEwQUBBUEFgQXBBgEGQQaBBsEHAQdBB4EHwQgBCEEIgQjBCQEJQQmBCcEKAQpBCoEKwQsBC0ELgQvBDAEMQQyBDMENAQ1BDYENwQ4BDkEOgQ7BDwEPQQ+BD8EQARBBEIEQwREBEUERgRHBEgESQRKBEsETARNBE4ETwRQBFEEUgRTBFQEVQRWBFcEWARZBFoEWwRcBF0EXgRfBGAEYQRiBGMEZARlBGYEZwRoBGkEagRrBGwEbQRuBG8EcARxBHIEcwR0BHUEdgR3BHgEeQR6BHsEfAR9BH4EfwSABIEEggSDBIQEhQSGBIcEiASJBIoEiwSMBI0EjgSPBJAEkQSSBJMElASVBJYElwSYBJkEmgSbBJwEnQSeBJ8EoAShBKIEowSkBKUEpgSnBKgEqQSqBKsErAStBK4ErwSwBLEEsgSzBLQEtQS2BLcEuAS5BLoEuwS8BL0EvgS/BMAEwQTCBMMExATFBMYExwTIBMkEygTLBMwEzQTOBM8E0ATRBNIE0wTUBNUE1gTXBNgE2QTaAJ0AngTbBNwE3QTeBN8E4AThBOIE4wTkBOUE5gTnBOgE6QTqBOsE7ATtBO4E7wTwBPEE8gTzBPQE9QT2BPcE+AT5BPoE+wT8BP0E/gT/BQAFAQUCBQMFBAUFBQYFBwUIBQkFCgULBQwFDQUOBQ8FEAURBRIFEwUUBRUFFgUXBRgFGQUaBRsFHAUdBR4FHwUgBSEFIgUjBSQFJQUmBScFKAUpBSoFKwUsBS0FLgUvBTAFMQUyBTMFNAU1BTYFNwU4BTkFOgU7BTwFPQU+BT8FQAVBBUIFQwVEBUUFRgVHBUgFSQVKBUsFTAVNBU4FTwVQBVEFUgVTBVQFVQVWBVcFWAVZBVoFWwVcBV0FXgVfBWAFYQViBWMFZAVlBWYFZwVoBWkFagVrBWwFbQVuBW8FcAVxBXIFcwV0BXUFdgV3BXgFeQV6BXsFfAV9BX4FfwWABYEFggWDBYQFhQWGBYcFiAWJBYoFiwWMBY0FjgWPBZAFkQWSBZMFlAWVBZYFlwWYBZkFmgWbBZwFnQWeBZ8FoAWhBaIFowWkBaUFpgWnBagFqQWqBasFrAWtBa4FrwWwBbEFsgWzBbQFtQW2BbcFuAW5BboFuwW8Bb0FvgW/BcAFwQXCBcMFxAXFBcYFxwXIBckFygXLBcwFzQXOBc8F0AXRBdIF0wXUBdUF1gXXBdgF2QXaBdsF3AXdBd4F3wXgBeEF4gXjBeQF5QXmBecF6AXpBeoF6wXsBe0F7gXvBfAF8QXyBfMF9AX1BfYF9wX4BfkF+gX7BfwF/QX+Bf8GAAYBBgIGAwYEBgUGBgYHBggGCQYKBgsGDAYNBg4GDwYQBhEGEgYTBhQGFQYWBhcGGAYZBhoGGwYcBh0GHgYfBiAGIQYiBiMGJAYlBiYGJwYoBikGKgYrBiwGLQYuBi8GMAYxAJsGMgYzABMAFAAVABYAFwAYABkAGgAbABwGNAY1BjYGNwY4BjkGOgY7BjwGPQY+Bj8GQAZBBkIGQwZEBkUGRgZHBkgGSQZKBksGTAZNBk4GTwZQBlEGUgZTBlQGVQZWBlcGWAZZBloGWwZcBl0GXgZfBmAGYQZiBmMGZAZlBmYGZwZoBmkGagZrBmwGbQZuBm8GcAZxBnIGcwZ0BnUGdgZ3BngGeQZ6BnsGfAZ9Bn4GfwaABoEGggaDALwA9AaEBoUA9QD2BoYGhwaIBokADQA/AMMAhwAdAA8AqwAEAKMABgARACIAogAFAAoAHgASAEIGigaLBowGjQaOBo8AXgBgAD4AQAALAAwGkAaRBpIGkwaUBpUAswCyBpYGlwAQBpgGmQaaBpsGnACpAKoAvgC/AMUAtAC1ALYAtwDEBp0GngafBqAGoQaiBqMGpAalBqYGpwaoBqkGqgarBqwGrQauBq8GsAaxBrIGswa0BrUGtga3BrgGuQa6AIQGuwC9AAcGvAa9AKYA9wa+Br8GwAbBBsIGwwbEBsUGxgbHBsgAhQbJBsoGywCWBswGzQbOAA4A7wDwALgAIACPACEAHwCVAJQAkwCnAGEApAbPAJIAnAbQBtEAmgCZAKUG0gCYAAgAxgbTBtQG1QbWBtcG2AbZBtoG2wbcBt0G3gbfBuAG4QbiALkG4wbkBuUG5gbnBugG6QbqBusG7AAjAAkAiACGAIsAigCMAIMAXwDoBu0AggDCBu4G7wBBBvAG8QbyBvMG9Ab1BvYG9wb4BvkG+gb7BvwG/Qb+Bv8HAAcBBwIHAwcEBwUHBgcHBwgHCQcKBwsHDAcNBw4HDwcQBxEHEgcTBxQHFQcWBxcHGAcZBxoHGwccBx0HHgcfByAHIQciByMHJAclByYHJwcoBykHKgcrBywHLQcuBy8HMAcxBzIHMwc0BzUHNgc3BzgHOQc6BzsHPAc9Bz4HPwdAB0EHQgdDB0QHRQdGB0cHSAdJB0oHSwdMB00HTgdPB1AHUQdSB1MHVAdVB1YHVwdYB1kHWgdbB1wHXQCNANsA4QDeANgAjgDcAEMA3wDaAOAA3QDZB14HXwdgB2EHYgdjB2QHZQdmB2cHaAdpB2oHawdsB20HbgdvB3AHcQdyB3MHdAd1B3YHdwd4BE5VTEwGQWJyZXZlB3VuaTFFQUUHdW5pMUVCNgd1bmkxRUIwB3VuaTFFQjIHdW5pMUVCNAd1bmkwMUNEB3VuaTFFQTQHdW5pMUVBQwd1bmkxRUE2B3VuaTFFQTgHdW5pMUVBQQd1bmkwMjAwB3VuaTFFQTAHdW5pMUVBMgd1bmkwMjAyB0FtYWNyb24HQW9nb25lawpBcmluZ2FjdXRlB0FFYWN1dGUHdW5pMUUwOAtDY2lyY3VtZmxleApDZG90YWNjZW50B3VuaTAxQzQGRGNhcm9uBkRjcm9hdAd1bmkxRTBDB3VuaTFFMEUHdW5pMDFDNQZFYnJldmUGRWNhcm9uB3VuaTFFMUMHdW5pMUVCRQd1bmkxRUM2B3VuaTFFQzAHdW5pMUVDMgd1bmkxRUM0B3VuaTAyMDQKRWRvdGFjY2VudAd1bmkxRUI4B3VuaTFFQkEHdW5pMDIwNgdFbWFjcm9uB3VuaTFFMTYHdW5pMUUxNAdFb2dvbmVrB3VuaTFFQkMHdW5pMDFCNwd1bmkwMUVFBkdjYXJvbgtHY2lyY3VtZmxleAxHY29tbWFhY2NlbnQKR2RvdGFjY2VudAd1bmkxRTIwB3VuaTAxRTQESGJhcgd1bmkxRTJBB3VuaTAyMUULSGNpcmN1bWZsZXgHdW5pMUUyNAJJSgZJYnJldmUHdW5pMDIwOAd1bmkxRTJFB3VuaTFFQ0EHdW5pMUVDOAd1bmkwMjBBB0ltYWNyb24HSW9nb25lawZJdGlsZGULSmNpcmN1bWZsZXgHdW5pMDFFOAxLY29tbWFhY2NlbnQHdW5pMDFDNwZMYWN1dGUGTGNhcm9uDExjb21tYWFjY2VudARMZG90B3VuaTFFMzYHdW5pMDFDOAd1bmkxRTNBB3VuaTFFNDIHdW5pMDFDQQZOYWN1dGUGTmNhcm9uDE5jb21tYWFjY2VudAd1bmkxRTQ0B3VuaTFFNDYDRW5nB3VuaTAxQ0IHdW5pMUU0OAZPYnJldmUHdW5pMUVEMAd1bmkxRUQ4B3VuaTFFRDIHdW5pMUVENAd1bmkxRUQ2B3VuaTAyMEMHdW5pMDIyQQd1bmkwMjMwB3VuaTFFQ0MHdW5pMUVDRQVPaG9ybgd1bmkxRURBB3VuaTFFRTIHdW5pMUVEQwd1bmkxRURFB3VuaTFFRTANT2h1bmdhcnVtbGF1dAd1bmkwMjBFB09tYWNyb24HdW5pMUU1Mgd1bmkxRTUwB3VuaTAxRUELT3NsYXNoYWN1dGUHdW5pMUU0Qwd1bmkxRTRFB3VuaTAyMkMGUmFjdXRlBlJjYXJvbgxSY29tbWFhY2NlbnQHdW5pMDIxMAd1bmkxRTVBB3VuaTAyMTIHdW5pMUU1RQZTYWN1dGUHdW5pMUU2NAd1bmlBNzhCB3VuaTFFNjYLU2NpcmN1bWZsZXgMU2NvbW1hYWNjZW50B3VuaTFFNjAHdW5pMUU2Mgd1bmkxRTY4B3VuaTFFOUUHdW5pMDE4RgRUYmFyBlRjYXJvbgd1bmkwMTYyB3VuaTAyMUEHdW5pMUU2Qwd1bmkxRTZFBlVicmV2ZQd1bmkwMUQzB3VuaTAyMTQHdW5pMUVFNAd1bmkxRUU2BVVob3JuB3VuaTFFRTgHdW5pMUVGMAd1bmkxRUVBB3VuaTFFRUMHdW5pMUVFRQ1VaHVuZ2FydW1sYXV0B3VuaTAyMTYHVW1hY3Jvbgd1bmkxRTdBB1VvZ29uZWsFVXJpbmcGVXRpbGRlB3VuaTFFNzgGV2FjdXRlC1djaXJjdW1mbGV4CVdkaWVyZXNpcwZXZ3JhdmULWWNpcmN1bWZsZXgHdW5pMUU4RQd1bmkxRUY0BllncmF2ZQd1bmkxRUY2B3VuaTAyMzIHdW5pMUVGOAZaYWN1dGUKWmRvdGFjY2VudAd1bmkxRTkyEElhY3V0ZV9KLmxvY2xOTEQGQS5zczAxC0FhY3V0ZS5zczAxC0FicmV2ZS5zczAxDHVuaTFFQUUuc3MwMQx1bmkxRUI2LnNzMDEMdW5pMUVCMC5zczAxDHVuaTFFQjIuc3MwMQx1bmkxRUI0LnNzMDEMdW5pMDFDRC5zczAxEEFjaXJjdW1mbGV4LnNzMDEMdW5pMUVBNC5zczAxDHVuaTFFQUMuc3MwMQx1bmkxRUE2LnNzMDEMdW5pMUVBOC5zczAxDHVuaTFFQUEuc3MwMQx1bmkwMjAwLnNzMDEOQWRpZXJlc2lzLnNzMDEMdW5pMUVBMC5zczAxC0FncmF2ZS5zczAxDHVuaTFFQTIuc3MwMQx1bmkwMjAyLnNzMDEMQW1hY3Jvbi5zczAxDEFvZ29uZWsuc3MwMQpBcmluZy5zczAxD0FyaW5nYWN1dGUuc3MwMQtBdGlsZGUuc3MwMQdBRS5zczAxDEFFYWN1dGUuc3MwMQx1bmkwMUM0LnNzMDEMdW5pMDFDNS5zczAxBkUuc3MwMQtFYWN1dGUuc3MwMQtFYnJldmUuc3MwMQtFY2Fyb24uc3MwMQx1bmkxRTFDLnNzMDEQRWNpcmN1bWZsZXguc3MwMQx1bmkxRUJFLnNzMDEMdW5pMUVDNi5zczAxDHVuaTFFQzAuc3MwMQx1bmkxRUMyLnNzMDEMdW5pMUVDNC5zczAxDHVuaTAyMDQuc3MwMQ5FZGllcmVzaXMuc3MwMQ9FZG90YWNjZW50LnNzMDEMdW5pMUVCOC5zczAxC0VncmF2ZS5zczAxDHVuaTFFQkEuc3MwMQx1bmkwMjA2LnNzMDEMRW1hY3Jvbi5zczAxDHVuaTFFMTYuc3MwMQx1bmkxRTE0LnNzMDEMRW9nb25lay5zczAxDHVuaTFFQkMuc3MwMQZGLnNzMDEGRy5zczAxC0dicmV2ZS5zczAxC0djYXJvbi5zczAxEEdjaXJjdW1mbGV4LnNzMDERR2NvbW1hYWNjZW50LnNzMDEPR2RvdGFjY2VudC5zczAxDHVuaTFFMjAuc3MwMQx1bmkwMUU0LnNzMDEGSS5zczAxB0lKLnNzMDELSWFjdXRlLnNzMDEVSWFjdXRlX0oubG9jbE5MRC5zczAxC0licmV2ZS5zczAxEEljaXJjdW1mbGV4LnNzMDEMdW5pMDIwOC5zczAxDklkaWVyZXNpcy5zczAxDHVuaTFFMkUuc3MwMQ9JZG90YWNjZW50LnNzMDEMdW5pMUVDQS5zczAxC0lncmF2ZS5zczAxDHVuaTFFQzguc3MwMQx1bmkwMjBBLnNzMDEMSW1hY3Jvbi5zczAxDElvZ29uZWsuc3MwMQtJdGlsZGUuc3MwMQZKLnNzMDEQSmNpcmN1bWZsZXguc3MwMQx1bmkwMUM3LnNzMDEGTS5zczAxDHVuaTFFNDIuc3MwMQZOLnNzMDEMdW5pMDFDQS5zczAxC05hY3V0ZS5zczAxC05jYXJvbi5zczAxEU5jb21tYWFjY2VudC5zczAxDHVuaTFFNDQuc3MwMQx1bmkxRTQ2LnNzMDEIRW5nLnNzMDEMdW5pMDFDQi5zczAxDHVuaTFFNDguc3MwMQtOdGlsZGUuc3MwMQZRLnNzMDEMdW5pMDE4Ri5zczAxBlQuc3MwMQlUYmFyLnNzMDELVGNhcm9uLnNzMDEMdW5pMDE2Mi5zczAxDHVuaTAyMUEuc3MwMQx1bmkxRTZDLnNzMDEMdW5pMUU2RS5zczAxBlUuc3MwMQtVYWN1dGUuc3MwMQtVYnJldmUuc3MwMQx1bmkwMUQzLnNzMDEQVWNpcmN1bWZsZXguc3MwMQx1bmkwMjE0LnNzMDEOVWRpZXJlc2lzLnNzMDEMdW5pMUVFNC5zczAxC1VncmF2ZS5zczAxDHVuaTFFRTYuc3MwMQpVaG9ybi5zczAxDHVuaTFFRTguc3MwMQx1bmkxRUYwLnNzMDEMdW5pMUVFQS5zczAxDHVuaTFFRUMuc3MwMQx1bmkxRUVFLnNzMDESVWh1bmdhcnVtbGF1dC5zczAxDHVuaTAyMTYuc3MwMQxVbWFjcm9uLnNzMDEMdW5pMUU3QS5zczAxDFVvZ29uZWsuc3MwMQpVcmluZy5zczAxC1V0aWxkZS5zczAxDHVuaTFFNzguc3MwMQZXLnNzMDELV2FjdXRlLnNzMDEQV2NpcmN1bWZsZXguc3MwMQ5XZGllcmVzaXMuc3MwMQtXZ3JhdmUuc3MwMQZZLnNzMDELWWFjdXRlLnNzMDEQWWNpcmN1bWZsZXguc3MwMQ5ZZGllcmVzaXMuc3MwMQx1bmkxRThFLnNzMDEMdW5pMUVGNC5zczAxC1lncmF2ZS5zczAxDHVuaTFFRjYuc3MwMQx1bmkwMjMyLnNzMDEMdW5pMUVGOC5zczAxBlouc3MwMQtaYWN1dGUuc3MwMQtaY2Fyb24uc3MwMQ9aZG90YWNjZW50LnNzMDEMdW5pMUU5Mi5zczAxBmFicmV2ZQd1bmkxRUFGB3VuaTFFQjcHdW5pMUVCMQd1bmkxRUIzB3VuaTFFQjUHdW5pMDFDRQd1bmkxRUE1B3VuaTFFQUQHdW5pMUVBNwd1bmkxRUE5B3VuaTFFQUIHdW5pMDIwMQd1bmkxRUExB3VuaTFFQTMHdW5pMDIwMwdhbWFjcm9uB2FvZ29uZWsKYXJpbmdhY3V0ZQdhZWFjdXRlB3VuaTFFMDkLY2NpcmN1bWZsZXgKY2RvdGFjY2VudAZkY2Fyb24HdW5pMUUwRAd1bmkxRTBGB3VuaTAxQzYGZWJyZXZlBmVjYXJvbgd1bmkxRTFEB3VuaTFFQkYHdW5pMUVDNwd1bmkxRUMxB3VuaTFFQzMHdW5pMUVDNQd1bmkwMjA1CmVkb3RhY2NlbnQHdW5pMUVCOQd1bmkxRUJCB3VuaTAyMDcHZW1hY3Jvbgd1bmkxRTE3B3VuaTFFMTUHZW9nb25lawd1bmkxRUJEB3VuaTAyNTkHdW5pMDI5Mgd1bmkwMUVGBmdjYXJvbgtnY2lyY3VtZmxleAxnY29tbWFhY2NlbnQKZ2RvdGFjY2VudAd1bmkxRTIxB3VuaTAxRTUEaGJhcgd1bmkxRTJCB3VuaTAyMUYLaGNpcmN1bWZsZXgHdW5pMUUyNQZpYnJldmUHdW5pMDIwOQd1bmkxRTJGCWkubG9jbFRSSwd1bmkxRUNCB3VuaTFFQzkHdW5pMDIwQgJpagdpbWFjcm9uB2lvZ29uZWsGaXRpbGRlB3VuaTAyMzcLamNpcmN1bWZsZXgHdW5pMDFFOQxrY29tbWFhY2NlbnQMa2dyZWVubGFuZGljBmxhY3V0ZQZsY2Fyb24MbGNvbW1hYWNjZW50BGxkb3QHdW5pMUUzNwd1bmkwMUM5B3VuaTFFM0IHdW5pMUU0MwZuYWN1dGULbmFwb3N0cm9waGUGbmNhcm9uDG5jb21tYWFjY2VudAd1bmkxRTQ1B3VuaTFFNDcDZW5nB3VuaTAxQ0MHdW5pMUU0OQZvYnJldmUHdW5pMUVEMQd1bmkxRUQ5B3VuaTFFRDMHdW5pMUVENQd1bmkxRUQ3B3VuaTAyMEQHdW5pMDIyQgd1bmkwMjMxB3VuaTFFQ0QHdW5pMUVDRgVvaG9ybgd1bmkxRURCB3VuaTFFRTMHdW5pMUVERAd1bmkxRURGB3VuaTFFRTENb2h1bmdhcnVtbGF1dAd1bmkwMjBGB29tYWNyb24HdW5pMUU1Mwd1bmkxRTUxB3VuaTAxRUILb3NsYXNoYWN1dGUHdW5pMUU0RAd1bmkxRTRGB3VuaTAyMkQGcmFjdXRlBnJjYXJvbgxyY29tbWFhY2NlbnQHdW5pMDIxMQd1bmkxRTVCB3VuaTAyMTMHdW5pMUU1RgZzYWN1dGUHdW5pMUU2NQd1bmlBNzhDB3VuaTFFNjcLc2NpcmN1bWZsZXgMc2NvbW1hYWNjZW50B3VuaTFFNjEHdW5pMUU2Mwd1bmkxRTY5BWxvbmdzBHRiYXIGdGNhcm9uB3VuaTAxNjMHdW5pMDIxQgd1bmkxRTk3B3VuaTFFNkQHdW5pMUU2RgZ1YnJldmUHdW5pMDFENAd1bmkwMjE1B3VuaTFFRTUHdW5pMUVFNwV1aG9ybgd1bmkxRUU5B3VuaTFFRjEHdW5pMUVFQgd1bmkxRUVEB3VuaTFFRUYNdWh1bmdhcnVtbGF1dAd1bmkwMjE3B3VtYWNyb24HdW5pMUU3Qgd1b2dvbmVrBXVyaW5nBnV0aWxkZQd1bmkxRTc5BndhY3V0ZQt3Y2lyY3VtZmxleAl3ZGllcmVzaXMGd2dyYXZlC3ljaXJjdW1mbGV4B3VuaTFFOEYHdW5pMUVGNQZ5Z3JhdmUHdW5pMUVGNwd1bmkwMjMzB3VuaTFFRjkGemFjdXRlCnpkb3RhY2NlbnQHdW5pMUU5MxBpYWN1dGVfai5sb2NsTkxEBmEuc3MwMQthYWN1dGUuc3MwMQthYnJldmUuc3MwMQx1bmkxRUFGLnNzMDEMdW5pMUVCNy5zczAxDHVuaTFFQjEuc3MwMQx1bmkxRUIzLnNzMDEMdW5pMUVCNS5zczAxDHVuaTAxQ0Uuc3MwMRBhY2lyY3VtZmxleC5zczAxDHVuaTFFQTUuc3MwMQx1bmkxRUFELnNzMDEMdW5pMUVBNy5zczAxDHVuaTFFQTkuc3MwMQx1bmkxRUFCLnNzMDEMdW5pMDIwMS5zczAxDmFkaWVyZXNpcy5zczAxDHVuaTFFQTEuc3MwMQthZ3JhdmUuc3MwMQx1bmkxRUEzLnNzMDEMdW5pMDIwMy5zczAxDGFtYWNyb24uc3MwMQxhb2dvbmVrLnNzMDEKYXJpbmcuc3MwMQ9hcmluZ2FjdXRlLnNzMDELYXRpbGRlLnNzMDEHYWUuc3MwMQxhZWFjdXRlLnNzMDEMdW5pMDFDNi5zczAxBmUuc3MwMQtlYWN1dGUuc3MwMQtlYnJldmUuc3MwMQtlY2Fyb24uc3MwMQx1bmkxRTFELnNzMDEQZWNpcmN1bWZsZXguc3MwMQx1bmkxRUJGLnNzMDEMdW5pMUVDNy5zczAxDHVuaTFFQzEuc3MwMQx1bmkxRUMzLnNzMDEMdW5pMUVDNS5zczAxDHVuaTAyMDUuc3MwMQ5lZGllcmVzaXMuc3MwMQ9lZG90YWNjZW50LnNzMDEMdW5pMUVCOS5zczAxC2VncmF2ZS5zczAxDHVuaTFFQkIuc3MwMQx1bmkwMjA3LnNzMDEMZW1hY3Jvbi5zczAxDHVuaTFFMTcuc3MwMQx1bmkxRTE1LnNzMDEMZW9nb25lay5zczAxDHVuaTFFQkQuc3MwMQx1bmkwMjU5LnNzMDEGZi5zczAxBmwuc3MwMQtsYWN1dGUuc3MwMQtsY2Fyb24uc3MwMRFsY29tbWFhY2NlbnQuc3MwMQlsZG90LnNzMDEMdW5pMUUzNy5zczAxDHVuaTAxQzkuc3MwMQx1bmkxRTNCLnNzMDELbHNsYXNoLnNzMDEHb2Uuc3MwMQZ0LnNzMDEJdGJhci5zczAxC3RjYXJvbi5zczAxDHVuaTAxNjMuc3MwMQx1bmkwMjFCLnNzMDEMdW5pMUU5Ny5zczAxDHVuaTFFNkQuc3MwMQx1bmkxRTZGLnNzMDEGdy5zczAxC3dhY3V0ZS5zczAxEHdjaXJjdW1mbGV4LnNzMDEOd2RpZXJlc2lzLnNzMDELd2dyYXZlLnNzMDEGeS5zczAxC3lhY3V0ZS5zczAxEHljaXJjdW1mbGV4LnNzMDEOeWRpZXJlc2lzLnNzMDEMdW5pMUVGNS5zczAxC3lncmF2ZS5zczAxDHVuaTFFRjcuc3MwMQx1bmkwMjMzLnNzMDEMdW5pMUVGOS5zczAxBnouc3MwMQt6YWN1dGUuc3MwMQt6Y2Fyb24uc3MwMQ96ZG90YWNjZW50LnNzMDEMdW5pMUU5My5zczAxA1RfaAdmaS5zczAxB2ZsLnNzMDEEYS5zYwlhYWN1dGUuc2MJYWJyZXZlLnNjCnVuaTFFQUYuc2MKdW5pMUVCNy5zYwp1bmkxRUIxLnNjCnVuaTFFQjMuc2MKdW5pMUVCNS5zYwp1bmkwMUNFLnNjDmFjaXJjdW1mbGV4LnNjCnVuaTFFQTUuc2MKdW5pMUVBRC5zYwp1bmkxRUE3LnNjCnVuaTFFQTkuc2MKdW5pMUVBQi5zYwp1bmkwMjAxLnNjDGFkaWVyZXNpcy5zYwp1bmkxRUExLnNjCWFncmF2ZS5zYwp1bmkxRUEzLnNjCnVuaTAyMDMuc2MKYW1hY3Jvbi5zYwphb2dvbmVrLnNjCGFyaW5nLnNjDWFyaW5nYWN1dGUuc2MJYXRpbGRlLnNjBWFlLnNjCmFlYWN1dGUuc2MEYi5zYwRjLnNjCWNhY3V0ZS5zYwljY2Fyb24uc2MLY2NlZGlsbGEuc2MKdW5pMUUwOS5zYw5jY2lyY3VtZmxleC5zYw1jZG90YWNjZW50LnNjBGQuc2MGZXRoLnNjCWRjYXJvbi5zYwlkY3JvYXQuc2MKdW5pMUUwRC5zYwp1bmkxRTBGLnNjCnVuaTAxQzYuc2MEZS5zYwllYWN1dGUuc2MJZWJyZXZlLnNjCWVjYXJvbi5zYwp1bmkxRTFELnNjDmVjaXJjdW1mbGV4LnNjCnVuaTFFQkYuc2MKdW5pMUVDNy5zYwp1bmkxRUMxLnNjCnVuaTFFQzMuc2MKdW5pMUVDNS5zYwp1bmkwMjA1LnNjDGVkaWVyZXNpcy5zYw1lZG90YWNjZW50LnNjCnVuaTFFQjkuc2MJZWdyYXZlLnNjCnVuaTFFQkIuc2MKdW5pMDIwNy5zYwplbWFjcm9uLnNjCnVuaTFFMTcuc2MKdW5pMUUxNS5zYwplb2dvbmVrLnNjCnVuaTFFQkQuc2MKdW5pMDI1OS5zYwp1bmkwMjkyLnNjCnVuaTAxRUYuc2MEZi5zYwRnLnNjCWdicmV2ZS5zYwlnY2Fyb24uc2MOZ2NpcmN1bWZsZXguc2MPZ2NvbW1hYWNjZW50LnNjDWdkb3RhY2NlbnQuc2MKdW5pMUUyMS5zYwp1bmkwMUU1LnNjBGguc2MHaGJhci5zYwp1bmkxRTJCLnNjCnVuaTAyMUYuc2MOaGNpcmN1bWZsZXguc2MKdW5pMUUyNS5zYwRpLnNjC2RvdGxlc3NpLnNjCWlhY3V0ZS5zYxNpYWN1dGVfai5sb2NsTkxELnNjCWlicmV2ZS5zYw5pY2lyY3VtZmxleC5zYwp1bmkwMjA5LnNjDGlkaWVyZXNpcy5zYwp1bmkxRTJGLnNjDGkuc2MubG9jbFRSSwp1bmkxRUNCLnNjCWlncmF2ZS5zYwp1bmkxRUM5LnNjCnVuaTAyMEIuc2MFaWouc2MKaW1hY3Jvbi5zYwppb2dvbmVrLnNjCWl0aWxkZS5zYwRqLnNjDmpjaXJjdW1mbGV4LnNjBGsuc2MKdW5pMDFFOS5zYw9rY29tbWFhY2NlbnQuc2MPa2dyZWVubGFuZGljLnNjBGwuc2MJbGFjdXRlLnNjCWxjYXJvbi5zYw9sY29tbWFhY2NlbnQuc2MHbGRvdC5zYwp1bmkxRTM3LnNjCnVuaTAxQzkuc2MKdW5pMUUzQi5zYwlsc2xhc2guc2MEbS5zYwp1bmkxRTQzLnNjBG4uc2MJbmFjdXRlLnNjCW5jYXJvbi5zYw9uY29tbWFhY2NlbnQuc2MKdW5pMUU0NS5zYwp1bmkxRTQ3LnNjBmVuZy5zYwp1bmkwMUNDLnNjCnVuaTFFNDkuc2MJbnRpbGRlLnNjBG8uc2MJb2FjdXRlLnNjCW9icmV2ZS5zYw5vY2lyY3VtZmxleC5zYwp1bmkxRUQxLnNjCnVuaTFFRDkuc2MKdW5pMUVEMy5zYwp1bmkxRUQ1LnNjCnVuaTFFRDcuc2MKdW5pMDIwRC5zYwxvZGllcmVzaXMuc2MKdW5pMDIyQi5zYwp1bmkwMjMxLnNjCnVuaTFFQ0Quc2MJb2dyYXZlLnNjCnVuaTFFQ0Yuc2MIb2hvcm4uc2MKdW5pMUVEQi5zYwp1bmkxRUUzLnNjCnVuaTFFREQuc2MKdW5pMUVERi5zYwp1bmkxRUUxLnNjEG9odW5nYXJ1bWxhdXQuc2MKdW5pMDIwRi5zYwpvbWFjcm9uLnNjCnVuaTFFNTMuc2MKdW5pMUU1MS5zYwp1bmkwMUVCLnNjCW9zbGFzaC5zYw5vc2xhc2hhY3V0ZS5zYwlvdGlsZGUuc2MKdW5pMUU0RC5zYwp1bmkxRTRGLnNjCnVuaTAyMkQuc2MFb2Uuc2MEcC5zYwh0aG9ybi5zYwRxLnNjBHIuc2MJcmFjdXRlLnNjCXJjYXJvbi5zYw9yY29tbWFhY2NlbnQuc2MKdW5pMDIxMS5zYwp1bmkxRTVCLnNjCnVuaTAyMTMuc2MKdW5pMUU1Ri5zYwRzLnNjCXNhY3V0ZS5zYwp1bmkxRTY1LnNjCnVuaUE3OEMuc2MJc2Nhcm9uLnNjCnVuaTFFNjcuc2MLc2NlZGlsbGEuc2MOc2NpcmN1bWZsZXguc2MPc2NvbW1hYWNjZW50LnNjCnVuaTFFNjEuc2MKdW5pMUU2My5zYwp1bmkxRTY5LnNjDWdlcm1hbmRibHMuc2MEdC5zYwd0YmFyLnNjCXRjYXJvbi5zYwp1bmkwMTYzLnNjCnVuaTAyMUIuc2MKdW5pMUU5Ny5zYwp1bmkxRTZELnNjCnVuaTFFNkYuc2MEdS5zYwl1YWN1dGUuc2MJdWJyZXZlLnNjCnVuaTAxRDQuc2MOdWNpcmN1bWZsZXguc2MKdW5pMDIxNS5zYwx1ZGllcmVzaXMuc2MKdW5pMUVFNS5zYwl1Z3JhdmUuc2MKdW5pMUVFNy5zYwh1aG9ybi5zYwp1bmkxRUU5LnNjCnVuaTFFRjEuc2MKdW5pMUVFQi5zYwp1bmkxRUVELnNjCnVuaTFFRUYuc2MQdWh1bmdhcnVtbGF1dC5zYwp1bmkwMjE3LnNjCnVtYWNyb24uc2MKdW5pMUU3Qi5zYwp1b2dvbmVrLnNjCHVyaW5nLnNjCXV0aWxkZS5zYwp1bmkxRTc5LnNjBHYuc2MEdy5zYwl3YWN1dGUuc2MOd2NpcmN1bWZsZXguc2MMd2RpZXJlc2lzLnNjCXdncmF2ZS5zYwR4LnNjBHkuc2MJeWFjdXRlLnNjDnljaXJjdW1mbGV4LnNjDHlkaWVyZXNpcy5zYwp1bmkxRThGLnNjCnVuaTFFRjUuc2MJeWdyYXZlLnNjCnVuaTFFRjcuc2MKdW5pMDIzMy5zYwp1bmkxRUY5LnNjBHouc2MJemFjdXRlLnNjCXpjYXJvbi5zYw16ZG90YWNjZW50LnNjCnVuaTFFOTMuc2MJYS5zYy5zczAxDmFhY3V0ZS5zYy5zczAxDmFicmV2ZS5zYy5zczAxD3VuaTFFQUYuc2Muc3MwMQ91bmkxRUI3LnNjLnNzMDEPdW5pMUVCMS5zYy5zczAxD3VuaTFFQjMuc2Muc3MwMQ91bmkxRUI1LnNjLnNzMDEPdW5pMDFDRS5zYy5zczAxE2FjaXJjdW1mbGV4LnNjLnNzMDEPdW5pMUVBNS5zYy5zczAxD3VuaTFFQUQuc2Muc3MwMQ91bmkxRUE3LnNjLnNzMDEPdW5pMUVBOS5zYy5zczAxD3VuaTFFQUIuc2Muc3MwMQ91bmkwMjAxLnNjLnNzMDERYWRpZXJlc2lzLnNjLnNzMDEPdW5pMUVBMS5zYy5zczAxDmFncmF2ZS5zYy5zczAxD3VuaTFFQTMuc2Muc3MwMQ91bmkwMjAzLnNjLnNzMDEPYW1hY3Jvbi5zYy5zczAxD2FvZ29uZWsuc2Muc3MwMQ1hcmluZy5zYy5zczAxEmFyaW5nYWN1dGUuc2Muc3MwMQ5hdGlsZGUuc2Muc3MwMQphZS5zYy5zczAxD2FlYWN1dGUuc2Muc3MwMQ91bmkwMUM2LnNjLnNzMDEJZS5zYy5zczAxDmVhY3V0ZS5zYy5zczAxDmVicmV2ZS5zYy5zczAxDmVjYXJvbi5zYy5zczAxD3VuaTFFMUQuc2Muc3MwMRNlY2lyY3VtZmxleC5zYy5zczAxD3VuaTFFQkYuc2Muc3MwMQ91bmkxRUM3LnNjLnNzMDEPdW5pMUVDMS5zYy5zczAxD3VuaTFFQzMuc2Muc3MwMQ91bmkxRUM1LnNjLnNzMDEPdW5pMDIwNS5zYy5zczAxEWVkaWVyZXNpcy5zYy5zczAxEmVkb3RhY2NlbnQuc2Muc3MwMQ91bmkxRUI5LnNjLnNzMDEOZWdyYXZlLnNjLnNzMDEPdW5pMUVCQi5zYy5zczAxD3VuaTAyMDcuc2Muc3MwMQ9lbWFjcm9uLnNjLnNzMDEPdW5pMUUxNy5zYy5zczAxD3VuaTFFMTUuc2Muc3MwMQ9lb2dvbmVrLnNjLnNzMDEPdW5pMUVCRC5zYy5zczAxD3VuaTAyNTkuc2Muc3MwMQlmLnNjLnNzMDEJZy5zYy5zczAxDmdicmV2ZS5zYy5zczAxDmdjYXJvbi5zYy5zczAxE2djaXJjdW1mbGV4LnNjLnNzMDEUZ2NvbW1hYWNjZW50LnNjLnNzMDESZ2RvdGFjY2VudC5zYy5zczAxD3VuaTFFMjEuc2Muc3MwMQ91bmkwMUU1LnNjLnNzMDEJaS5zYy5zczAxEGRvdGxlc3NpLnNjLnNzMDEOaWFjdXRlLnNjLnNzMDEYaWFjdXRlX2oubG9jbE5MRC5zYy5zczAxDmlicmV2ZS5zYy5zczAxE2ljaXJjdW1mbGV4LnNjLnNzMDEPdW5pMDIwOS5zYy5zczAxEWlkaWVyZXNpcy5zYy5zczAxD3VuaTFFMkYuc2Muc3MwMQ91bmkxRUNCLnNjLnNzMDEOaWdyYXZlLnNjLnNzMDEPdW5pMUVDOS5zYy5zczAxD3VuaTAyMEIuc2Muc3MwMQppai5zYy5zczAxD2ltYWNyb24uc2Muc3MwMQ9pb2dvbmVrLnNjLnNzMDEOaXRpbGRlLnNjLnNzMDEJai5zYy5zczAxE2pjaXJjdW1mbGV4LnNjLnNzMDEPdW5pMDFDOS5zYy5zczAxCW0uc2Muc3MwMQ91bmkxRTQzLnNjLnNzMDEJbi5zYy5zczAxDm5hY3V0ZS5zYy5zczAxDm5jYXJvbi5zYy5zczAxFG5jb21tYWFjY2VudC5zYy5zczAxD3VuaTFFNDUuc2Muc3MwMQ91bmkxRTQ3LnNjLnNzMDELZW5nLnNjLnNzMDEPdW5pMDFDQy5zYy5zczAxD3VuaTFFNDkuc2Muc3MwMQ5udGlsZGUuc2Muc3MwMQlxLnNjLnNzMDEJdC5zYy5zczAxDHRiYXIuc2Muc3MwMQ50Y2Fyb24uc2Muc3MwMQ91bmkwMTYzLnNjLnNzMDEPdW5pMDIxQi5zYy5zczAxD3VuaTFFOTcuc2Muc3MwMQ91bmkxRTZELnNjLnNzMDEPdW5pMUU2Ri5zYy5zczAxCXUuc2Muc3MwMQ51YWN1dGUuc2Muc3MwMQ51YnJldmUuc2Muc3MwMQ91bmkwMUQ0LnNjLnNzMDETdWNpcmN1bWZsZXguc2Muc3MwMQ91bmkwMjE1LnNjLnNzMDERdWRpZXJlc2lzLnNjLnNzMDEPdW5pMUVFNS5zYy5zczAxDnVncmF2ZS5zYy5zczAxD3VuaTFFRTcuc2Muc3MwMQ11aG9ybi5zYy5zczAxD3VuaTFFRTkuc2Muc3MwMQ91bmkxRUYxLnNjLnNzMDEPdW5pMUVFQi5zYy5zczAxD3VuaTFFRUQuc2Muc3MwMQ91bmkxRUVGLnNjLnNzMDEVdWh1bmdhcnVtbGF1dC5zYy5zczAxD3VuaTAyMTcuc2Muc3MwMQ91bWFjcm9uLnNjLnNzMDEPdW5pMUU3Qi5zYy5zczAxD3VvZ29uZWsuc2Muc3MwMQ11cmluZy5zYy5zczAxDnV0aWxkZS5zYy5zczAxD3VuaTFFNzkuc2Muc3MwMQl3LnNjLnNzMDEOd2FjdXRlLnNjLnNzMDETd2NpcmN1bWZsZXguc2Muc3MwMRF3ZGllcmVzaXMuc2Muc3MwMQ53Z3JhdmUuc2Muc3MwMQl5LnNjLnNzMDEOeWFjdXRlLnNjLnNzMDETeWNpcmN1bWZsZXguc2Muc3MwMRF5ZGllcmVzaXMuc2Muc3MwMQ91bmkxRThGLnNjLnNzMDEPdW5pMUVGNS5zYy5zczAxDnlncmF2ZS5zYy5zczAxD3VuaTFFRjcuc2Muc3MwMQ91bmkwMjMzLnNjLnNzMDEPdW5pMUVGOS5zYy5zczAxCXouc2Muc3MwMQ56YWN1dGUuc2Muc3MwMQ56Y2Fyb24uc2Muc3MwMRJ6ZG90YWNjZW50LnNjLnNzMDEPdW5pMUU5My5zYy5zczAxB3VuaTA0MTAHdW5pMDQxMQd1bmkwNDEyB3VuaTA0MTMHdW5pMDQwMwd1bmkwNDkwB3VuaTA0MTQHdW5pMDQxNQd1bmkwNDAwB3VuaTA0MDEHdW5pMDQxNgd1bmkwNDE3B3VuaTA0MTgHdW5pMDQxOQd1bmkwNDBEB3VuaTA0OEEHdW5pMDQxQQd1bmkwNDBDB3VuaTA0MUIHdW5pMDQxQwd1bmkwNDFEB3VuaTA0MUUHdW5pMDQxRgd1bmkwNDIwB3VuaTA0MjEHdW5pMDQyMgd1bmkwNDIzB3VuaTA0MEUHdW5pMDQyNAd1bmkwNDI1B3VuaTA0MjcHdW5pMDQyNgd1bmkwNDI4B3VuaTA0MjkHdW5pMDQwRgd1bmkwNDJDB3VuaTA0MkEHdW5pMDQyQgd1bmkwNDA5B3VuaTA0MEEHdW5pMDQwNQd1bmkwNDA0B3VuaTA0MkQHdW5pMDQwNgd1bmkwNDA3B3VuaTA0MDgHdW5pMDQwQgd1bmkwNDJFB3VuaTA0MkYHdW5pMDQwMgd1bmkwNDYyB3VuaTA0NkEHdW5pMDQ3Mgd1bmkwNDc0B3VuaTA0OTIHdW5pMDQ5NAd1bmkwNDk2B3VuaTA0OTgHdW5pMDQ5QQd1bmkwNDlDB3VuaTA0OUUHdW5pMDRBMAd1bmkwNEEyB3VuaTA0QTQHdW5pMDRBNgd1bmkwNTI0B3VuaTA0QTgHdW5pMDRBQQd1bmkwNEFDB3VuaTA0QUUHdW5pMDRCMAd1bmkwNEIyB3VuaTA0QjQHdW5pMDRCNgd1bmkwNEI4B3VuaTA0QkEHdW5pMDUyNgd1bmkwNEJDB3VuaTA0QkUHdW5pMDRDMAd1bmkwNEMxB3VuaTA0QzMHdW5pMDRDNwd1bmkwNEM5B3VuaTA0Q0IHdW5pMDRDRAd1bmkwNEQwB3VuaTA0RDIHdW5pMDRENAd1bmkwNEQ2B3VuaTA0RDgHdW5pMDREQQd1bmkwNERDB3VuaTA0REUHdW5pMDRFMAd1bmkwNEUyB3VuaTA0RTQHdW5pMDRFNgd1bmkwNEU4B3VuaTA0RUEHdW5pMDRFQwd1bmkwNEVFB3VuaTA0RjAHdW5pMDRGMgd1bmkwNEY0B3VuaTA0RjYHdW5pMDRGOAd1bmkwNEZBB3VuaTA0RkMHdW5pMDRGRQd1bmkwNTEwB3VuaTA1MTIHdW5pMDUxQQd1bmkwNTFDB3VuaTA0OEMHdW5pMDQ4RQd1bmkwNTI4B3VuaTA1MkUPdW5pMDQxNC5sb2NsQkdSD3VuaTA0MUIubG9jbEJHUg91bmkwNDI0LmxvY2xCR1IPdW5pMDQ5Mi5sb2NsQlNID3VuaTA0OTgubG9jbEJTSA91bmkwNEFBLmxvY2xCU0gPdW5pMDRBQS5sb2NsQ0hVDHVuaTA0MTAuc3MwMQx1bmkwNDE0LnNzMDEMdW5pMDQxNS5zczAxDHVuaTA0MDAuc3MwMQx1bmkwNDAxLnNzMDEMdW5pMDQxOC5zczAxDHVuaTA0MTkuc3MwMQx1bmkwNDhBLnNzMDEMdW5pMDQwRC5zczAxDHVuaTA0MUIuc3MwMQx1bmkwNDIwLnNzMDEMdW5pMDQyMi5zczAxDHVuaTA0MjMuc3MwMQx1bmkwNDBFLnNzMDEMdW5pMDQyNC5zczAxDHVuaTA0MkMuc3MwMQx1bmkwNDJBLnNzMDEMdW5pMDQyQi5zczAxDHVuaTA0MDkuc3MwMQx1bmkwNDBBLnNzMDEMdW5pMDQwOC5zczAxDHVuaTA0NjIuc3MwMQx1bmkwNEFDLnNzMDEMdW5pMDREMC5zczAxDHVuaTA0RDIuc3MwMQx1bmkwNEQ0LnNzMDEMdW5pMDRENi5zczAxDHVuaTA0RTIuc3MwMQx1bmkwNEU0LnNzMDEMdW5pMDRFRS5zczAxDHVuaTA0RjAuc3MwMQx1bmkwNEYyLnNzMDEMdW5pMDRGOC5zczAxDHVuaTA1MUEuc3MwMQx1bmkwNDhDLnNzMDEHdW5pMDQzMAd1bmkwNDMxB3VuaTA0MzIHdW5pMDQzMwd1bmkwNDUzB3VuaTA0OTEHdW5pMDQzNAd1bmkwNDM1B3VuaTA0NTAHdW5pMDQ1MQd1bmkwNDM2B3VuaTA0MzcHdW5pMDQzOAd1bmkwNDM5B3VuaTA0NUQHdW5pMDQ4Qgd1bmkwNDNBB3VuaTA0NUMHdW5pMDQzQgd1bmkwNDNDB3VuaTA0M0QHdW5pMDQzRQd1bmkwNDNGB3VuaTA0NDAHdW5pMDQ0MQd1bmkwNDQyB3VuaTA0NDMHdW5pMDQ1RQd1bmkwNDQ0B3VuaTA0NDUHdW5pMDQ0Nwd1bmkwNDQ2B3VuaTA0NDgHdW5pMDQ0OQd1bmkwNDVGB3VuaTA0NEMHdW5pMDQ0QQd1bmkwNDRCB3VuaTA0NTkHdW5pMDQ1QQd1bmkwNDU1B3VuaTA0NTQHdW5pMDQ0RAd1bmkwNDU2B3VuaTA0NTcHdW5pMDQ1OAd1bmkwNDVCB3VuaTA0NEUHdW5pMDQ0Rgd1bmkwNDUyB3VuaTA0NjMHdW5pMDQ2Qgd1bmkwNDczB3VuaTA0NzUHdW5pMDQ5Mwd1bmkwNDk1B3VuaTA0OTcHdW5pMDQ5OQd1bmkwNDlCB3VuaTA0OUQHdW5pMDQ5Rgd1bmkwNEExB3VuaTA0QTMHdW5pMDRBNQd1bmkwNTI1B3VuaTA0QTcHdW5pMDRBOQd1bmkwNEFCB3VuaTA0QUQHdW5pMDRBRgd1bmkwNEIxB3VuaTA0QjMHdW5pMDRCNQd1bmkwNEI3B3VuaTA0QjkHdW5pMDRCQgd1bmkwNTI3B3VuaTA0QkQHdW5pMDRCRgd1bmkwNENGB3VuaTA0QzIHdW5pMDRDNAd1bmkwNEM2B3VuaTA0QzgHdW5pMDRDQQd1bmkwNENDB3VuaTA0Q0UHdW5pMDREMQd1bmkwNEQzB3VuaTA0RDUHdW5pMDRENwd1bmkwNEQ5B3VuaTA0REIHdW5pMDRERAd1bmkwNERGB3VuaTA0RTEHdW5pMDRFMwd1bmkwNEU1B3VuaTA0RTcHdW5pMDRFOQd1bmkwNEVCB3VuaTA0RUQHdW5pMDRFRgd1bmkwNEYxB3VuaTA0RjMHdW5pMDRGNQd1bmkwNEY3B3VuaTA0RjkHdW5pMDRGQgd1bmkwNEZEB3VuaTA0RkYHdW5pMDUxMQd1bmkwNTEzB3VuaTA1MUIHdW5pMDUxRAd1bmkwNDhEB3VuaTA0OEYHdW5pMDUyOQd1bmkwNTJGD3VuaTA0MzIubG9jbEJHUg91bmkwNDMzLmxvY2xCR1IPdW5pMDQzNC5sb2NsQkdSD3VuaTA0MzYubG9jbEJHUg91bmkwNDM3LmxvY2xCR1IPdW5pMDQzOC5sb2NsQkdSD3VuaTA0MzkubG9jbEJHUg91bmkwNDVELmxvY2xCR1IPdW5pMDQzQS5sb2NsQkdSD3VuaTA0M0IubG9jbEJHUg91bmkwNDNELmxvY2xCR1IPdW5pMDQzRi5sb2NsQkdSD3VuaTA0NDIubG9jbEJHUg91bmkwNDQ3LmxvY2xCR1IPdW5pMDQ0Ni5sb2NsQkdSD3VuaTA0NDgubG9jbEJHUg91bmkwNDQ5LmxvY2xCR1IPdW5pMDQ0Qy5sb2NsQkdSD3VuaTA0NEEubG9jbEJHUg91bmkwNDRFLmxvY2xCR1IPdW5pMDQ5My5sb2NsQlNID3VuaTA0OTkubG9jbEJTSA91bmkwNEFCLmxvY2xDSFUPdW5pMDQ1My5sb2NsTUtED3VuaTA0MzEubG9jbFNSQg91bmkwNDMzLmxvY2xTUkIPdW5pMDQzNC5sb2NsU1JCD3VuaTA0M0YubG9jbFNSQg91bmkwNDQyLmxvY2xTUkIMdW5pMDQzMC5zczAxDHVuaTA0MzQuc3MwMQx1bmkwNDM1LnNzMDEMdW5pMDQ1MC5zczAxDHVuaTA0NTEuc3MwMQx1bmkwNDM4LnNzMDEMdW5pMDQzOS5zczAxDHVuaTA0OEIuc3MwMQx1bmkwNDVELnNzMDEMdW5pMDQ0MC5zczAxDHVuaTA0NDIuc3MwMQx1bmkwNDQzLnNzMDEMdW5pMDQ1RS5zczAxDHVuaTA0NEMuc3MwMQx1bmkwNDRBLnNzMDEMdW5pMDQ0Qi5zczAxDHVuaTA0NTkuc3MwMQx1bmkwNDVBLnNzMDEMdW5pMDQ2My5zczAxDHVuaTA0RDEuc3MwMQx1bmkwNEQzLnNzMDEMdW5pMDRENS5zczAxDHVuaTA0RDcuc3MwMQx1bmkwNEQ5LnNzMDEMdW5pMDREQi5zczAxDHVuaTA0RTMuc3MwMQx1bmkwNEU1LnNzMDEMdW5pMDRFRi5zczAxDHVuaTA0RjEuc3MwMQx1bmkwNEYzLnNzMDEMdW5pMDRGOS5zczAxDHVuaTA0OEQuc3MwMQd1bmkwMzk0B3VuaTAzQTkHdW5pMDNCQwd1bmkyMTJCB3VuaTIxMkEIemVyby5vc2YHb25lLm9zZgd0d28ub3NmCXRocmVlLm9zZghmb3VyLm9zZghmaXZlLm9zZgdzaXgub3NmCXNldmVuLm9zZgllaWdodC5vc2YIbmluZS5vc2YJemVyby5zaW5mCG9uZS5zaW5mCHR3by5zaW5mCnRocmVlLnNpbmYJZm91ci5zaW5mCWZpdmUuc2luZghzaXguc2luZgpzZXZlbi5zaW5mCmVpZ2h0LnNpbmYJbmluZS5zaW5mB3plcm8udGYGb25lLnRmBnR3by50Zgh0aHJlZS50Zgdmb3VyLnRmB2ZpdmUudGYGc2l4LnRmCHNldmVuLnRmCGVpZ2h0LnRmB25pbmUudGYJemVyby50b3NmCG9uZS50b3NmCHR3by50b3NmCnRocmVlLnRvc2YJZm91ci50b3NmCWZpdmUudG9zZghzaXgudG9zZgpzZXZlbi50b3NmCmVpZ2h0LnRvc2YJbmluZS50b3NmB3VuaTIwODAHdW5pMjA4MQd1bmkyMDgyB3VuaTIwODMHdW5pMjA4NAd1bmkyMDg1B3VuaTIwODYHdW5pMjA4Nwd1bmkyMDg4B3VuaTIwODkJemVyby5kbm9tCG9uZS5kbm9tCHR3by5kbm9tCnRocmVlLmRub20JZm91ci5kbm9tCWZpdmUuZG5vbQhzaXguZG5vbQpzZXZlbi5kbm9tCmVpZ2h0LmRub20JbmluZS5kbm9tCXplcm8ubnVtcghvbmUubnVtcgh0d28ubnVtcgp0aHJlZS5udW1yCWZvdXIubnVtcglmaXZlLm51bXIIc2l4Lm51bXIKc2V2ZW4ubnVtcgplaWdodC5udW1yCW5pbmUubnVtcgd1bmkyMDcwB3VuaTAwQjkHdW5pMDBCMgd1bmkwMEIzB3VuaTIwNzQHdW5pMjA3NQd1bmkyMDc2B3VuaTIwNzcHdW5pMjA3OAd1bmkyMDc5B3VuaTIxNTMHdW5pMjE1NAlvbmVlaWdodGgMdGhyZWVlaWdodGhzC2ZpdmVlaWdodGhzDHNldmVuZWlnaHRocw5iYWNrc2xhc2guY2FzZRNwZXJpb2RjZW50ZXJlZC5jYXNlC2J1bGxldC5jYXNlG3BlcmlvZGNlbnRlcmVkLmxvY2xDQVQuY2FzZQpzbGFzaC5jYXNlFnBlcmlvZGNlbnRlcmVkLmxvY2xDQVQOYnJhY2VsZWZ0LmNhc2UPYnJhY2VyaWdodC5jYXNlEGJyYWNrZXRsZWZ0LmNhc2URYnJhY2tldHJpZ2h0LmNhc2UOcGFyZW5sZWZ0LmNhc2UPcGFyZW5yaWdodC5jYXNlCmZpZ3VyZWRhc2gHdW5pMjAxNQd1bmkyMDEwB3VuaTAwQUQLZW1kYXNoLmNhc2ULZW5kYXNoLmNhc2ULaHlwaGVuLmNhc2USZ3VpbGxlbW90bGVmdC5jYXNlE2d1aWxsZW1vdHJpZ2h0LmNhc2USZ3VpbHNpbmdsbGVmdC5jYXNlE2d1aWxzaW5nbHJpZ2h0LmNhc2UJZXhjbGFtLnNjDWV4Y2xhbWRvd24uc2MQZ3VpbGxlbW90bGVmdC5zYxFndWlsbGVtb3RyaWdodC5zYxBndWlsc2luZ2xsZWZ0LnNjEWd1aWxzaW5nbHJpZ2h0LnNjCXBlcmlvZC5zYwtxdWVzdGlvbi5zYw9xdWVzdGlvbmRvd24uc2MLcXVvdGVkYmwuc2MPcXVvdGVkYmxiYXNlLnNjD3F1b3RlZGJsbGVmdC5zYxBxdW90ZWRibHJpZ2h0LnNjDHF1b3RlbGVmdC5zYw1xdW90ZXJpZ2h0LnNjEXF1b3Rlc2luZ2xiYXNlLnNjDnF1b3Rlc2luZ2xlLnNjB3VuaTI3RTgHdW5pMjdFOQd1bmkyMDA3B3VuaTIwMEEHdW5pMjAwOAd1bmkwMEEwB3VuaTIwMDkHdW5pMjAwQgd1bmkyMEI1DWNvbG9ubW9uZXRhcnkEZG9uZwRFdXJvB3VuaTIwQjIHdW5pMjBCNAd1bmkyMEFEBGxpcmEHdW5pMjBCQQd1bmkyMEJDB3VuaTIwQTYGcGVzZXRhB3VuaTIwQjEHdW5pMjBCRAd1bmkyMEI5B3VuaTIwQjgHdW5pMjBBRQd1bmkyMEE5B3VuaTIyMTkHdW5pMjA1Mgd1bmkyMjE1CGVtcHR5c2V0B3VuaTIxMjYHdW5pMjIwNgd1bmkwMEI1B2Fycm93dXAHdW5pMjE5NwphcnJvd3JpZ2h0B3VuaTIxOTgJYXJyb3dkb3duB3VuaTIxOTkJYXJyb3dsZWZ0B3VuaTIxOTYJYXJyb3dib3RoCWFycm93dXBkbgxhcnJvd3VwLmNhc2UPYXJyb3dyaWdodC5jYXNlDmFycm93ZG93bi5jYXNlDmFycm93bGVmdC5jYXNlB3VuaTI1QzYHdW5pMjVDNwlmaWxsZWRib3gHdW5pMjVBMQd0cmlhZ3VwB3VuaTI1QjYHdHJpYWdkbgd1bmkyNUMwB3VuaTI1QjMHdW5pMjVCNwd1bmkyNUJEB3VuaTI1QzEHdW5pMjExMwllc3RpbWF0ZWQHdW5pMjExNgZtaW51dGUGc2Vjb25kB2F0LmNhc2UMdW5pMjExNi5zczAxDGFtcGVyc2FuZC5zYwd1bmkwMzA4C3VuaTAzMDgwMzAwC3VuaTAzMDgwMzAxC3VuaTAzMDgwMzA0B3VuaTAzMDcLdW5pMDMwNzAzMDQJZ3JhdmVjb21iC3VuaTAzMDAwMzA0CWFjdXRlY29tYgt1bmkwMzAxMDMwNwt1bmkwMzAxMDMwNAd1bmkwMzBCDWNhcm9uY29tYi5hbHQHdW5pMDMwMgd1bmkwMzBDC3VuaTAzMEMwMzA3B3VuaTAzMDYHdW5pMDMwQQt1bmkwMzBBMDMwMQl0aWxkZWNvbWILdW5pMDMwMzAzMDgTdGlsZGVjb21iX2FjdXRlY29tYgt1bmkwMzAzMDMwNAd1bmkwMzA0C3VuaTAzMDQwMzA4C3VuaTAzMDQwMzAwC3VuaTAzMDQwMzAxDWhvb2thYm92ZWNvbWIHdW5pMDMwRgd1bmkwMzExB3VuaTAzMTIHdW5pMDMxQgxkb3RiZWxvd2NvbWIHdW5pMDMyNAd1bmkwMzI2B3VuaTAzMjcHdW5pMDMyOAd1bmkwMzJFB3VuaTAzMzEHdW5pMDMzNQd1bmkwMzM2B3VuaTAzMzcHdW5pMDMzOAx1bmkwMzA4LmNhc2UQdW5pMDMwODAzMDAuY2FzZRB1bmkwMzA4MDMwMS5jYXNlEHVuaTAzMDgwMzA0LmNhc2UMdW5pMDMwNy5jYXNlEHVuaTAzMDcwMzA0LmNhc2UOZ3JhdmVjb21iLmNhc2UQdW5pMDMwMDAzMDQuY2FzZQ5hY3V0ZWNvbWIuY2FzZRB1bmkwMzAxMDMwNy5jYXNlEHVuaTAzMDEwMzA0LmNhc2UMdW5pMDMwQi5jYXNlDHVuaTAzMDIuY2FzZQx1bmkwMzBDLmNhc2UQdW5pMDMwQzAzMDcuY2FzZQx1bmkwMzA2LmNhc2UOdGlsZGVjb21iLmNhc2UQdW5pMDMwMzAzMDguY2FzZRh0aWxkZWNvbWJfYWN1dGVjb21iLmNhc2UQdW5pMDMwMzAzMDQuY2FzZQx1bmkwMzA0LmNhc2UQdW5pMDMwNDAzMDguY2FzZRB1bmkwMzA0MDMwMC5jYXNlEHVuaTAzMDQwMzAxLmNhc2USaG9va2Fib3ZlY29tYi5jYXNlDHVuaTAzMEYuY2FzZQx1bmkwMzExLmNhc2UMdW5pMDMzNS5jYXNlDHVuaTAzMzcuY2FzZQx1bmkwMzM4LmNhc2UTdW5pMDMwNC5uYXJyb3cuY2FzZQl1bmkwMzA3LmkJdW5pMDMyOC5pEHVuaTAzMDgubG9jbFZJRVQQdW5pMDMwNy5sb2NsVklFVBJncmF2ZWNvbWIubG9jbFZJRVQSYWN1dGVjb21iLmxvY2xWSUVUEHVuaTAzMDIubG9jbFZJRVQQdW5pMDMwQy5sb2NsVklFVBB1bmkwMzA2LmxvY2xWSUVUEnRpbGRlY29tYi5sb2NsVklFVBB1bmkwMzA0LmxvY2xWSUVUFmhvb2thYm92ZWNvbWIubG9jbFZJRVQOdW5pMDMwOC5uYXJyb3cOdW5pMDMwMi5uYXJyb3cOdW5pMDMwNi5uYXJyb3cQdGlsZGVjb21iLm5hcnJvdw51bmkwMzA0Lm5hcnJvdw51bmkwMzExLm5hcnJvdxNjYXJvbmNvbWIuYWx0LnNob3J0CXVuaTAzMzUudAd1bmkwMkJDB3VuaTAyQkIHdW5pMDJCQQd1bmkwMkM5B3VuaTAyQ0IHdW5pMDJCOQd1bmkwMkJGB3VuaTAyQkUHdW5pMDJDQQd1bmkwMkNDB3VuaTAyQzgKdW5pMDMzNS5zYwp1bmkwMzM2LnNjCnVuaTAzMzguc2MLYnJldmVjb21iY3kQYnJldmVjb21iY3kuY2FzZQtkZXNjZW5kZXJjeRBkZXNjZW5kZXJjeS5jYXNlFmRlc2NlbmRlcmN5LmNhc2Uuc2hvcnQRZGVzY2VuZGVyY3kuc2hvcnQLdW5pMDMwNjAzMDELdW5pMDMwNjAzMDALdW5pMDMwNjAzMDkLdW5pMDMwNjAzMDMLdW5pMDMwMjAzMDELdW5pMDMwMjAzMDALdW5pMDMwMjAzMDkLdW5pMDMwMjAzMDMQdW5pMDMwNjAzMDEuY2FzZRB1bmkwMzA2MDMwMC5jYXNlEHVuaTAzMDYwMzA5LmNhc2UQdW5pMDMwNjAzMDMuY2FzZRB1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AAMAAAAAAAMAAwADAAMACAADAAAAAAAAAAAAGwAAAAD/9gAAAAAACAAAAAAAAAAA/+wAAAAAAAAAAAAAAAAAAAAAAAAAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/+QAAAAAAAAAAAAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/2AAAAAAAHAAAAAP/2AAD/9AAAAAAAAAAAAAAAAAAAAAAAAAAA/8cAAAAAAAAAAAAAAAAAAAAHAAAABwAAAAAAAAAAAAD//QAAAAAAAAAAAAP/9gAIAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkAAP/2AAAAAAAKAAoAAAAA//YAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/7QAAAAAAAwAAAAoAAAAKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//bAAoAAAAAAAMAAwADAAMAAwADAAAAAAAAAAAAEwAAAAD/9gAAAAAAAAAAAAD/9gAA/+wAAAAAAAAAAAAAAAAAAAAAAAAAAP+/AAAAAAAAAAAAAAAAAAAAAAAAAAcAAP/2//YAAAAN/+7/qQAAAAD/2//5/9j/3gAA//kAAAADAAAAAwAAAAMAAAAK//YACAAA/+z/9v/s//P//QAAAAcAAAADAAD/6QAAAAf/9gAHAAAAAAAAAAAAAAAA/9YAAAAAAAAAAAAAAAAAAAAAAAcAAP/2AAAAAAAAAAD/8QAAAAAAAAAA//H/2AAA/+b/9AAAAAAAAAAAAAAAAAAAAAD//QAAAAD/5wAAAAD/4gAAAAAAAAAAAAAAAAAAAAAAAP/5AAcAAAAAAAAAAAAAAAAAJgAIAAgAAAAAAAAAAAAAAAAAAP/s/+8AAAAAAAAAAAAKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIQAAAAAAHAAAAAAAAwAAAAAAAAAAAA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAsAAAAAAAAAAAAAAADAAAAAAAA/+//9wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAmAAAAAAAAAAAAAAAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/58AAAAAAAD/wQADAAMAAwAA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BiUADAYmBicANQYoBigAMQYpBioAEAYrBisAQQYsBiwAQgYuBi4AEAYvBi8AEQYwBjAAEgYxBjIAFAYzBjMAMQY0BjQAKwY1BjUALQY2BjYADAY3BjgAUQY6BjoAKwY9Bj0ATQY/Bj8ATQZDBkMATgZFBkUATgZHBkcAUwZMBk4ANQZRBlEAUQZSBlIANQZTBlMARQZUBlQANQZVBlUARQZWBlYAEAZXBlcAEwZYBlgAOwZZBlkAEwZaBloAOwZbBlsAEAZcBlwAUQZdBl0AUAZeBl4AUQZfBl8AUAZiBmIANQZkBmQANQZmBmYAEAZqBmoAEAZvBm8AEAZ5BnkAJQZ6BnoAOAZ7BnsAJQZ8BnwAMgZ9Bn0AJgZ+Bn4AOAZ/Bn8AMgaABoAAKAaBBoEAMgaCBoIAJQaEBoQAMgaFBoUANgaGBoYAMgaIBogAMgaKBosAMgaMBowAFQaNBo0ANgaQBpAAMgaRBpEAGwaUBpQAKwaVBpYANQaYBpgANQahBqIANQanBqcAAQaqBqoANQarBqsAUgatBq4ADwbKBsoAJQbLBssAMAbMBswAOgbNBs0AFgbOBs8AJQbQBtAAPQbRBtEAHgbXBtcAJQbaBtsAFAbcBtwAJQc+Bz4AEwACAAgACgAaBJgFCjDQQfBOrlTMbU6FfI8WAAEAsgAEAAAAVAQKAV4BaAGGAYYBhgGGAYYBhgGGAbQBtAG0AbQBtAG0Af4B/gH+Af4B/gH+Af4B/gH+Af4ENAIoAigCKAIoAigCKAIoA44ClgJCA6oCjAJQAmICcAJ+AowClgKgAs4C3AOOA5wDqgPcBF4EXgReBFgEWAPuBE4D9AROA/4D/gQEBFgEWARYBFgEWARwBHAEWARYBAoENAQ0BE4EWARYBFgEWAReBF4EcAABAFQASQCUAKkAwADBAMIAwwDEAMUAxgDfAOAA4QDiAOMA5ADmAOcA6ADpAOoA6wDsAO0A7gDvASsBVwFYAVkBWgFbAVwBXQGgAbABygHPAd4B4gHjAeoB7QHvAfgB/gIxAkoCTAJkArQDhQRkBGUGJAYmBicGMAY0BjUGOgY8Bj4GQAZMBk0GTgZTBlUGVwZZBmMGZQaBBoUGjQaUBpUGlgaYBqEG2AbdBz4AAgYlAAYGNgAGAAcGNAApBjUAKAY6ACkGPQAIBj8ACAZHAAMGlAApAAsB4QAZ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//YAAAAAAAAAAAAAAAAAAAAAAAD/7wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAAAAAAoAAAAA//YAAAAAAAAAAAAAAAAAAAAA//YAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/s//cAAAAAAAAAAAAAAAD/+QAAAAAAAAAAAAD/9QAA//cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//kAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//0AAP/2AAAAAAAAAAAAAAAA//sAAAAA//0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//kAAAAAAAAAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/j/8YAAP/8/+f/1f/s//b/2P/a/9D/5QAAAAD/5wAI/68AAP/2/+f/6gAA/9H/9AAA/+X//f/D/9//5QAUABP/9v/q/+n/6gAU//H/+AAA/9gAAP/uAAAAAP/v/9IAAP/RAAf/5f/L/9X/+f/8ABQAAv/u/+cAQ//b/+7/1//s/9v/4P/p/+r/5//k//4AAAAA//b/6f/x//P/7v/5/+z/5//9AAD/9P/2/+X/9AAAAAL/9//5//YAAAAAAAgAAAAAAAAAAP/9//YAAP/mAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHv/z/7//v//0/8z/9v+3/+X/uv+6AAAAAwAAABT/vwAA//kAAP/hAAEAAP/5AAcAAP/3/+IAKAAX//b/7f/5//n/2//W/7IAHv+kAAD/1f/RAAAAAAAA/87/vgAW//v/2AAAAAMAAP+8AAr/+f/0ADv/2v/k//kADf/H/+oAAP/q//kAAwAAAAAAAP/5AAD/+QADAB4ACAADAAAAAAAAAAAACgAAAAAAAAAAAAoAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//0AAAAAAAD/+wAA//cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/xAAD/8f/iAAD/9v/2AAD/6v/n/+L/+wAA/+wAAAAA/+4AAAAKAAAAAAAAAAD/7AAAAAAAAAAAAAcAB//2/+wAAAAKAAAAAP/2AAAAAP/s/+L/7P/0//H/7gAA//MAAAAA/+wABQAA//T/9P/9AAUAAAAAAAD/4gAA//b/8//7//YAAAAAAAAAAP/2/+z/7wAAAAD/7AAAAAD/9gAAAAD/7gAAAAAAAAAA//QAAAAA//b/+QAAAAAADAAAAAAAAAAAAAAAAABQAAAAAAAA//v/+AAHAAAAAAAAAAAAAAAAAAD/7v/6/9//0QAA/+AAAP/4/+//5//2AAAAAP/s/+UAAP/uAAAAFP/2//kAAP/i/7sAAAAAAAAAAP/9AA3/9v/2AAAABf/0AAAAAAAFAAD/5AAA/8wAAAAKAAAAAP/qAAAABf/RAAUACv/3//H/+QAAAAAAAAAA/9//+QAA/9//9gAAAAAAAAAAAAD/0//a/9b/7f/7/+4AAP/x/9P/8//g/+0AAP/2AAAAAP/4AAAAAP/7AAAAAP/o//f/8v/3AAAAAAAAAAD/9v/tAAAAAP/2/+8AAP/2AAAAAAAAAAAAAAAAAAAAAP/2/+IAAP/2AAAAAAAA/+z/9gAAAAD/7AAAAAAAAAAAAA8AAAAAAAD/7AAAAAAAAAAAAAD//gAAAAAACAAAAAAAAAAAAAAAAAAAAAD/+//2AAUAAAAAAAAAAAAAAAUAAAAFAAoAAP/5//QAAAAAAAAAAAARAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/+//2AAAAAAAAAAAAAP/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/q/+AAAP/iAAD/9v/4AAAAAP/z//EAAP/s//YAAwAA/+z/+//xAAAAAP/+AAoABQAAAAAAAAAAABEAAAAA/+f/9gAAAAAAAP/2//YAAAAU/+z/9v/n//b/4gAA//H/9v/wAAAAAP/z//T/+f/qAAD/9gAAAAD/7P/2//b/9v/2/+wAAAAAAAAAAAAA/+4AAAAAAAAAAAAAAAAAAAAAAAD/+gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9P/m//b/9v/2AAoAAP/z//j/4v/4AAAAHgAe/+wACP+V//YAKP/l//b/7P+p/6kAAP/0//P/4f/f/+//+f/0AAD/8//J/+AAKAASAB7/4AAL/8cAGwAbAAj/2v/kABT/9P/sAAMAC//tAAr/+QAy/+3/8//3AAD/3wAE/98AAQAE//T/9v/s/+L/3f/b/73/6v/9AAD/9//k/8f/6f/g/9X/7//5/+//+f/P/+oAAAAS//f/+f/zAAD/1wAUABQAAAAAAAAAHf/zAAAAAAAAAAAAAAAA//AAKgAAAAAAAAAAAAAAAAAA//n/9gAAAAAAAAAR//MAFAAAACgAFP/sAAj/uf/2AB7/3//7/+z/sP+s//3/7//z/9r/3//b//b/7wAA/+//yf/bACgAFwAq/+AAHv/MACAAJQAM/9//6QAeAAP/7AAAAAgAAAAK//cAMv/0/+7/9v/5AAAABP/9//4ACf/0/+z/8f/d/9j/9P/g//X/9gAAAAD/4v/I/9r/4v/m/+AABwAA//P/4//nAAAAFP/2//n/9gAA/+gACwAUAAAAAAAA//b/9v/2AAAAAAAAAAAAAP/0AAD/1QAAAAAAAAAAAAD/2P+9AAD/5//vAAD/9v/i/+IAAAAA/9gAAAAAAAAAAAAA//YAAAAAAAD/4gAAAAAAAAAAAAAACv/2/+wAAAAAAAAAAP/sAAAAAP/p/+L/5wAAAAAAAAAAAAAAAAAA/+IABQAAAAD/7P/t//0AAAAAAAD/4gAAAAD/9v/s/+wAAAAAAAAAAP/iAAAAAAAAAAAAAAAA//b/4gAAAAAAAAAA//YAAAAAAAAAAAAA/+cAAAAAAAAAAAAAAAAAAAAAAAAAAP/2AAAAAAAA//H/7gAAAAAAAAAAAAAAAAAAAAD/6P/vAAD/5wAA//MAAAAAAAD/9v/2AAAAAAAAAAAAAP/lAAAAAAAAAAAAAAAA//IAAAAAAAAAAAAAAAD//v/0AAAAAAAAAAAAAAAAAAD/+AAA//kAAAAAAAAAAP/wAAAAAP/2AAAAAP/xAAD/9AAAAAAAAAAA//YAAAAA//kAAAAAAAAAAAAAAAD/8f/q//EAAAAAAAAAAAAA//sAAAAA//EAAAAAAAAAAP/3AAAAAAAAAAAAAAAAAAD/+QAAAAAAAAAAAAD/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//AAAAAAAAAAAAAA//n/+QAAABwAWQAAAB4AAP/4AAv/+P/4//j/+P/qAAD/+AAAAAD/+P/4//j/+AAA//j/+P/4ACAAAAAL//cADv/zAAAAEwAA//gAAAAYAAD/9QAA//gAAAAO//QANP/4//j/+P/1//gAAP/4AAAAAP/4//j/+P/4//EAAAAAAAAAAAAAAAD/+P/z//j/+AAA//gAAAAA//gAAP/4AAAAA//4//gAAAAAAAAAHgATAAAAAAAAAAz/+P/sAAAAAAAAAEYAAAAAAAAAAAAJAAAAAAAA/+X/8f/n/+r/+AARAAAAAP/p/+sAAAAhAB7/6gAL/8b/6QAb/9H/7//i/7f/nAAA/9//8wAA/+n/1f/g/9j/+f/k/8n/2gAeAAAAFv/bAAD/uAATACAAAP/G/90ACv/s/9j//f/4/+wAA//xACj/6v/g/+r/9v/vAAD/3//sAAD/5//k/+f/2v/b/+n/2v/t/+r/+v/x/8n/yv/a/+X/0f/M//j/7v/z/83/1QAAAAD/7P/n/+wACP/tABcACgAAAAAAAP/s/93/7AAAAAD/9gAA//EAAAAZAAAAAP/sAAD/2//GAAD//P/n/+L/8//2/+n/7f/i/+7/9gAA/+UAA/+u//n/7P/k/+r/9v/L/+8AAP/W//gAAP/u/9EACgAO/+//5//i/+AACv/vAAAAAP/iAAP//wAHAAD/7P/d//b/xAAR/+n/3//LAAAAAAAeAAD/5f/oAC//5P/x/9r/5//s/93/8//f/+T/3//3//QAAP/x/8z/8//v/+j/+f/s/9z/9gAA//b/+f/W//YAAAAA//kAAP/xAAAAAAADAAAAAAAAAAAAAP/2AAAAAAAA//YAAP/p//cAAAAAAAAAAAAA//T/5v/2/+z/4v/4ABT/9v/r/+L//QAAABQAHv/wAAv/qP/bABT/t//q/9j/o/+aAAD/1v/uAAD/4P/b/9b/xP/v/9P/xP/CACEAAAAW/9sAAP+uAAwAGwAA/7z/3QAU/+f/7P/s//b/6QAF/+IAMv/d/93/6v/5/9b/+f/O/+L/9v/Y/9//3//V/9b/4f/G/+3/9AAA//H/v/+8/9X/zv/J/8L/7v/k/+z/tv/Q/+z/9v/s/+z/5QAG/+0AHAAUAAAAAAAAABj/2v/sAAAAAAAAAAD/9P/0ABUAAAAAAAAAAAAAAAAAAAAA//gAAAAKAAAAAP/2AAD/+QAKAAAAAAAAAAAAAwAA//n//QAD/+H/8AAA//QAAAAA//T/+QASAAsAAP/0//T/9wAU//kAAAAUAAMAAAAAAAAAAAAAAAAAAP/vAAf/+QAAAAAAAP/0AB4AAP/5//AAHv/0//QAAAAI//7/6gAA/+3/9AAAAAAAAAAAAAAAAAAAAAIACP/5//QAAAAA//3/+QAAAAD/9AAAAAD/+f/5AAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/1v/pAAAAAAAA/6wAAP/0//j/1//PAAAAAP+9AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/+f/5AAAAAAAOAAAAAAAAAAAAAP/5AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+3/8AAAAAAAAAAA//cAAAAAAAAAAP/3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAr/wgAAAAAAAAAAAAAAAAAAAAD/9P/wAAAAAAAAAAD/8wAAAAAAAAAAAAD/+AAA//QACwAAAAMAAAAAAAAAAAAAAAAAAAAAAAMAAAACAAAAAAAA//kAAAAAAAAAAAAW//YAAP/2AAAAAAAAAAAAAP/5AAAAAAAAAAAAAAAAAAAAAAAAAAD/+QAAAAAAAAAAAAAAAAAAAAD/+QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgBYAAQARgAAAEgAtABDALYBNgCwATgBSAExAUoBiQFCAbQBtAGCAdAB1gGDAd4B8QGKAfwB/AGeAjECMQGfAlACWQGgAmACZwGqAnkCmAGyApsCmwHSArsCuwHTAswCzAHUAtUC2QHVBGYEZgHaBGgEaAHbBG0EdAHcBHYEhAHkBIYEhgHzBIgEiAH0BIsEiwH1BI4EkwH2BJUElgH8BJkEnAH+BJ4EowICBKcEpwIIBKkErQIJBLAEsAIOBLMEuAIPBLoEugIVBLwEzgIWBNAE1wIpBNkE2gIxBN0E4wIzBOUE8QI6BPQE9AJHBPcE9wJIBPkFAgJJBQQFBAJTBQYFBgJUBQwFDAJVBRIFFQJWBRgFGgJaBRwFHAJdBSQFKAJeBSsFKwJjBTEFMwJkBTYFNwJnBUQFRAJpBUYFRwJqBU4FUAJsBVgFXAJvBWYFZwJ0BW8FbwJ2BXEFcQJ3BXYFdwJ4BXsFfAJ6BX8FfwJ8BYIFhAJ9BYYFhgKABYoFjQKBBZYFmwKFBZ8FogKLBaUFpgKPBakFqQKRBa0FrgKSBbMFuAKUBboFugKaBb4FvwKbBnkGeQKdBnsGewKeBn0GfQKfBn8GfwKgBoEGggKhBoUGhQKjBocGhwKkBosGiwKlBo0GjQKmBqcGqAKnBqsGqwKpBsoGygKqBswGzAKrBs4GzwKsBtcG1wKuBtwG3AKvAAIA1gAeAB8ABAAgACAAAgAhACcAAwAoACgADwApACkAGwAqAC4ADwAvAC8AHQAwAEYABABIAEgAAgBJAEkABgBKAFEACABSAFgACQBZAFkAFgBaAGcACQBoAGkAFgBqAGwADABtAG0ADQBuAG4AFgBvAHMADQB0AHQAHAB1AHYADQB3AHkACQB6AHoAFgB7AIAACQCBAIEAHACCAIMACQCEAKUADwCmAKYABACnAKcAEACoAKgAFQCpAKkADwCqALEAEQCyALQAEgC2AL0AEgC+AL4AAgC/AL8ADwDAAMYAEwDHANAAFgDRANEAFwDSAN4AFgDfAOQAGADlAOUAGQDmAO8AGgDwAPQAGwD1APUAFgD2AQ8AAQEQAREABAESARIAGwETARMAHQEUASoABQErASsABwEsATMACAE0ATQACgE1ATUACwE2ATYACgE4AUQACgFFAUcACwFIAUgADgFKAUoADgFLAUsACwFMAVEADgFSAVIAHAFTAVQADgFVAVYADwFXAV0AFAFeAWcACQFoAWgAFwFpAXUACQF2AYQAFgGFAYkAGwG0AbQAHQHQAdYAHAHeAfEAHAH8AfwAHAIxAjEAHAJQAlkAHAJgAmcAHAJ5An0AHQJ+ApgAHAKbApsAHQK7ArsAHALMAswAHALVAtkAHQRoBGgAAgRtBG8ABARwBHAAGQRxBHEAAgRyBHQACQR2BHcAGQR4BHoACQR7BHsADwR8BHwACQR9BH0AEAR+BH4AAwR/BH8AEwSABIEAGASCBIIADwSDBIMAGQSEBIQACQSGBIYACQSIBIgACQSLBIsACQSOBI4AEgSPBI8AAwSQBJAADwSRBJIACQSTBJMAFgSVBJUADwSWBJYACQSZBJkAGQSaBJoADwSbBJsAGAScBJwABgSeBJ4AGQSfBJ8AAgSgBKEAGQSiBKIADASjBKMAGQSnBKcACQSpBKkAAwSqBKoAEwSrBKwAGgStBK0AGQSwBLAACQSzBLQADwS1BLUACQS2BLYAGQS3BLcADAS4BLgACQS6BLoACQS+BL8ABATABMEADwTCBMIAGQTDBMQAAgTFBMYACQTHBMoADwTLBM0AGATOBM4ACQTQBNAACQTRBNEAEwTSBNMAGQTUBNQABQTVBNUACQTWBNYADwTXBNcAGATZBNkAEATaBNoACQTeBN4ADwTfBN8ABgTgBOAAAgThBOIAAwTjBOMAAQTlBOcABQToBOsACQTsBOwAAQTtBO0AEATuBO4AFATvBPAAFgTxBPEADwT0BPQACQT3BPcACwT5BPkAFAT6BPsAAQT8BPwABAT9BP0ABQT+BP8ACQUABQIAFgUEBQQADwUGBQYAHAUMBQwAHAUSBRUAHAUYBRoAHAUcBRwAHAUkBSgAHAUrBSsAHAUxBTMAHAU2BTcAHAVEBUQAHAVGBUcAHAVOBVAAHAVYBVwAHAVmBWcAHAVvBW8AHAVxBXEAHAV2BXcAHAV7BXwAHAV/BX8AHAWCBYQAHAWGBYYAHAWKBY0AHAWWBZsAHAWfBaIAHAWlBaYAHAWpBakAHAWtBa4AHAWzBbgAHAW/Bb8ADAZ5BnkAAwZ7BnsAAwZ9Bn0AEgZ/Bn8AAwaBBoEABgaCBoIACAaFBoUABwaHBocACQaLBosAEAaNBo0ABwaoBqgACQarBqsAHAbKBsoADwbMBswACQbOBs8ADwbXBtcADwbcBtwADwACAa8ABAAfAEYAIAAgAGsAIQAnAAUAKABGAGsARwBIAEsASQBJAGsASgBRAAUAUgBnAGsAaABpAAMAagCDAGsAhACmAAUApwCoAGsAqQCpAAUAqgCxAGsAsgC0AEwAtgC9AEwAvgC+AHAAvwC/AAUAwADGAAYAxwDeAAgA3wDkAAkA5QDlAAoA5gDvAAsA8AD0AGkA9QD1AGsA9gEPAFwBEAERAEYBEgETAGsBFAEqAEoBKwErAFwBLAEzAAUBNAE0AGgBNQE1AGsBNgFEAGgBRQFGAAQBRwFIAGsBSgFUAGsBVQFWAAUBVwFdAAcBXgF6AAgBewGEAAwBhQGJAGkBigGlAE0BpgGmAG8BpwHMACMBzgHOAFEB0AHXACMB2AHdAG8B3gHuAGUB7wHxAGQB8gH0AG8B9QH1AGUB9gH+AG8B/wILAGUCDAIuACMCLwIvAGUCMAIwAG8CMQIxACMCMgI5AGUCOgI8AC4CPgJFAC4CRgJGAG8CSAJPADMCUAJnADoCaAJtAD0CbgJuAD8CbwJ4AD0CeQJ9AEMCfwKYACMCmQKaAE0CmwKzACMCtAK9AG8CvgK+ACMCvwLGAG8CxwLUADoC1QLZAEMC2gLaAAYC2wLcADMC3gLeADMC3wL6AE4C+wL7AFUC/AMCACQDAwMgAFUDIQMhACQDJAMkAFUDJQMsACQDLQNEAFUDRQNGAB8DRwNfAFUDYAOCACQDgwOEAFUDhQOFACQDhgONAFUDjgOQAFcDkgOZAFcDmwOiADQDowO6ADsDuwPAAD4DwQPBAEADwgPLAEEDzAPQAFoD0QPqAE8D7QPtAFUD7gQEABQEBQQFACQEBgQGAFIEBwQOACQEDwQRAFsEEgQSAFUEEwQbAFsEHAQcAFUEHQQfAFsEIAQhACAEIgQuAFUELwQvACQEMAQ3ADQEOARUADsEVQReAEIEXwRjAFoEZARlAA0EZgRmAEYEZwRrAGsEbARsAEcEbQRvAGsEcARwAAoEcQRxAEsEcgR3AGsEeAR4AEcEeQR6AGsEewR7AAUEfAR9AGsEfgR+AAUEfwR/AAYEgASBAAoEggSCAAUEgwSDAAoEhASEAAEEhQSJAGsEigSKAAYEiwSLAGsEjASMAEcEjQSNAGsEjgSOAEwEjwSPAAUEkASQAEsEkQSSAGsEkwSTAAMElASUAAYElQSVAGsElgSWAAoElwSYAAYEmQSZAAoEmgSaAAUEmwSbAAkEnQSdAGsEngSeAAoEnwSfAEsEoASiAGsEowSjAAYEpASnAGsEqASpAAUEqgSqAAYEqwSsAAsErQStAAoErgSuAAYErwSwAAEEsQSyAGsEswS0AAIEtQS1AGsEtgS2AAoEtwS5AGsEugS6AAEEuwS7AGsEvAS+AEYEvwS/AGsEwATBAAUEwgTCAAoEwwTEAEsExQTGAGsExwTJAAUEygTKAEsEywTNAAoEzgTOAAEEzwTRAGsE0gTTAAoE1ATUAEoE1QTVAEcE1gTWAAUE1wTXAAkE2ATaAGsE2wTcAEcE3QTdAEYE3gTeAAUE3wTfAGsE4QTiAAUE4wTjAFwE5ATkAF4E5QTnAEoE6ATrAGsE7ATsAEkE7QTtAFwE7gTuAAcE7wTwAAwE8QTxAAUE8gTyAAgE8wTzAAYE9AT0AAgE9QT1AEcE9gT2AGsE9wT3AAQE+QT5AAcE+gT7AFwE/AT8AEYE/QT9AEoE/gT/AGsFAAUCAAwFBAUEAAUFBQUFAAgFBgUGAE0FBwUHAAUFCAULAGUFDAUMAEgFDQUPACMFEAUQAD8FEQURAFEFEgUXAGUFGAUYAEgFGQUaAGUFGwUbACMFHAUdAGUFHgUeACMFHwUfADUFIAUhAD0FIgUiACMFIwUjAD8FJAUkADoFJQUpAGUFKgUqADUFKwUrAGUFLAUsAEgFLQUtAGUFLgUuAC4FLwUvACMFMAUwAFEFMQUyAGUFMwUzAGQFNAU0AG0FNQU1AGUFNgU2AD8FNwU3AG8FOAU4ADUFOQU5AD8FOgU6ACMFOwU7AD0FPAU8ABkFPQU9AGUFPgU+AD8FPwU/AFEFQAVBAGUFQgVCAG8FQwVDADUFRAVHAGUFSAVJACMFSgVKADUFSwVMAD0FTQVNAD8FTgVOADUFTwVQADoFUQVSAG8FUwVUABEFVQVVAG8FVgVWAD8FVwVXAGUFWAVYAEgFWQVaAGUFWwVbADoFXAVcAGUFXQVfAE0FYAViACMFYwVjAD8FZAVlAFEFZgVnAGUFaAVqACMFawVrAFEFbAVuAD0FbwVvADoFcAVyAGUFcwV0AD8FdQV1AFYFdgV2AEgFdwV3ACMFeAV4AD0FeQV5AC8FegV6AGUFewV7AGQFfAV8AEgFfQV9ACMFfgV+AC4FfwV/ACMFgAWAAD8FgQWBAFEFggWEADoFhQWFAG8FhgWGAEgFhwWJAGUFigWOADoFjwWPADUFkAWQAG8FkQWRAGUFkgWSAFEFkwWTACMFlAWUAGUFlQWVAA8FlgWWAGUFlwWXACMFmAWZADoFmgWeACMFnwWiADoFowWjAG4FpQWnADoFqAWoABwFqQWpADoFqgWqAEgFqwWrAGUFrQWuACMFrwWvAE0FsAWxACMFswW4ADoFuQW5AC8FugW6AEYFvgW+AEYFvwW/AGsFwAXAAEQFwQXBACUFwgXCAFkFwwXDADYFxAXEABcFxQXFAFMFxgXGAEQFxwXHADAFyAXIABUFyQXJACEFygXKAEUFywXLACYFzAXMADkFzQXNADcFzgXOABgFzwXPAFQF0AXQAEQF0QXRADEF0gXSABUF0wXTACIGJAYkAA0GJQYlAA4GJgYnAB0GKAYoABIGKQYqACgGKwYrAGAGLAYsABYGLgYuACgGLwYvACkGMAYwACoGMQYyAC0GMwYzABIGNAY0ADIGNQY1ADwGNgY2AA4GNwY4AB4GOgY6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BSMAEwUkBSQAQAUlBSkAPwUrBSsAPwUtBS0APwUuBS4AGwUvBS8AGQUxBTIAPwUzBTMAPQU1BTUAPwU2BTYAEwU3BTcAPgU5BTkAEwU6BToAGQU7BTsAEQU9BT0APwU+BT4AEwVABUEAPwVCBUIAPgVEBUcAPwVIBUkAGQVLBUwAEQVNBU0AEwVPBVAAQAVRBVIAPgVVBVUAPgVWBVYAEwVXBVcAPwVZBVoAPwVbBVsAQAVcBVwAPwVdBV8ACgVgBWIAGQVjBWMAEwVmBWcAPwVoBWoAGQVsBW4AEQVvBW8AQAVwBXIAPwVzBXQAEwV3BXcAGQV4BXgAEQV6BXoAPwV7BXsAPQV9BX0AGQV+BX4AGwV/BX8AGQWABYAAEwWCBYQAQAWFBYUAPgWHBYkAPwWKBY4AQAWQBZAAPgWRBZEAPwWTBZMAGQWUBZQAPwWWBZYAPwWXBZcAGQWYBZkAQAWaBZ4AGQWfBaIAQAWlBacAQAWpBakAQAWrBasAPwWtBa4AGQWvBa8ACgWwBbEAGQWzBbgAQAW6BboAAQW+Bb4AAQXBBcEAKwXCBcIAOQXDBcMAOAXEBcQAJwXHBccANQXKBcoAPAXLBcsALAXMBcwAOgXOBc4AKAXPBc8AJgXRBdEANgYkBiQADAYlBiUAHwYmBicAKgYoBigAIgYpBioALwYrBisAIwYuBi4ALwYvBi8AMAYwBjAAMQYxBjIANAYzBjMAIgY0BjQANwY1BjUAOwY2BjYAHwY6BjoANwY9Bj0AIAY/Bj8AIAZBBkEALQZDBkMAIQZFBkUAIQZHBkcALgZMBk4AKgZSBlIAKgZUBlQAKgZWBlYALwZYBlgAMwZaBloAMwZbBlsALwZgBmAAJAZhBmEAJQZiBmIAKgZjBmMAKQZkBmQAKgZlBmUAKQZmBmYALwZoBmgAMgZqBmoALwZvBm8ALwZ5BnkAFQZ6BnoAGQZ7BnsAFQZ9Bn0AFgZ+Bn4AGQaCBoIAFQaUBpQANwaVBpYAKgaYBpgAKgahBqIAKganBqcAAQaqBqoAKgarBqsAPwbKBsoAFQbOBs8AFQbXBtcAFQbaBtsANAbcBtwAFQACAJ4ABAAAAKwAsAABAEcAAP+j//n/9AAKAB4AKAAh//YAFAAK/6j/9v/2ABQAAwAHAB4ABwAUABH/7P/5//P/2QARAA0AEf/2//0AUAAg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AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9AAA//D/8AAAAAD/7f/3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/8f/q//f/9AAA/+0AAP/s//P/9//w//cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKACUABwAA//b/9gAA/+n/+f/bAAAAAAAAAAAAHgAAAAAAFAAAAAcAAP/9//kAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwAAAAAACP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABf/9AAAABQAFAAAAAoAAAAUAAoABwAAAAAADf/2AAAAFAAAAAAAAwAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAACP/2AAAACAAAAAAAAwAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKAAoAFAAA/+z/7AAA/+L/9v/YAAoAAABkAEQAFAAKAAAACAAAAAD/9gAA//YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAEQAAAAAACAADAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/zAAD/6QAA//T/7wAA/9//1v/WAAAAEf/0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA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ABIFhQWFAAQFhwWJAAgFkAWQAAkFkgWSABIFlAWUAAsFlQWVAAkFnAWeAAEFowWjAAkFrwWwAAEFsQWxAAkGiQaJAAwAAgFrAAQAHwBMACAAIABNACEAJwAwACgARgBNAEcASABIAEkASQBNAEoAUQAwAFIAZwBNAGoAgwBNAIQApgAwAKcAqABNAKkAqQAwAKoAsQBNALIAtABOALYAvQBOAL8AvwAwAMAAxgACAMcA3gAxAN8A5AAyAOUA5QA2AOYA7wAzAPUA9QBNAPYBDwABARABEQBMARIBEwBNASsBKwABASwBMwAwATUBNQBNAUUBRgBJAUcBSABNAUoBVABNAVUBVgAwAVcBXQBKAV4BegAxAYoBpQA3AaYBpgATAacBzAAWAc4BzgAPAdAB1wAWAdgB3QATAd4B7gBCAe8B8QBBAfIB9AATAfUB9QBCAfYB/gATAf8CCwBCAgwCLgAWAi8CLwBCAjACMAATAjECMQAWAjICOQBCAjoCPABFAj4CRQBFAkYCRgATAkgCTwAjAlACZwBGAmgCbQApAm4CbgAqAm8CeAApAnkCfQArAn8CmAAWApkCmgA3ApsCswAWArQCvQATAr4CvgAWAr8CxgATAscC1ABGAtUC2QArAtoC2gACAtsC3AAjAt4C3gAjBGQEZQAEBGYEZgBMBGcEawBNBGwEbAA1BG0EbwBNBHAEcAA2BHEEcQBIBHIEdwBNBHgEeAA1BHkEegBNBHsEewAwBHwEfQBNBH4EfgAwBH8EfwACBIAEgQA2BIIEggAwBIMEgwA2BIQEhAAuBIUEiQBNBIoEigACBIsEiwBNBIwEjAA1BI0EjQBNBI4EjgBOBI8EjwAwBJAEkABIBJEEkgBNBJQElAACBJUElQBNBJYElgA2BJcEmAACBJkEmQA2BJoEmgAwBJsEmwAyBJ0EnQBNBJ4EngA2BJ8EnwBIBKAEogBNBKMEowACBKQEpwBNBKgEqQAwBKoEqgACBKsErAAzBK0ErQA2BK4ErgACBK8EsAAuBLEEsgBNBLMEtAAvBLUEtQBNBLYEtgA2BLcEuQBNBLoEugAuBLsEuwBNBLwEvgBMBL8EvwBNBMAEwQAwBMIEwgA2BMMExABIBMUExgBNBMcEyQAwBMoEygBIBMsEzQA2BM4EzgAuBM8E0QBNBNIE0wA2BNUE1QA1BNYE1gAwBNcE1wAyBNgE2gBNBNsE3AA1BN0E3QBMBN4E3gAwBN8E3wBNBOEE4gAwBOME4wABBOQE5ABHBOgE6wBNBO0E7QABBO4E7gBKBPEE8QAwBPIE8gAxBPME8wACBPQE9AAxBPUE9QA1BPYE9gBNBPcE9wBJBPkE+QBKBPoE+wABBPwE/ABMBP4E/wBNBQQFBAAwBQUFBQAxBQYFBgA3BQcFBwAwBQgFCwBCBQwFDAAOBQ0FDwAWBRAFEAAqBREFEQAPBRIFFwBCBRgFGAAOBRkFGgBCBRsFGwAWBRwFHQBCBR4FHgAWBR8FHwAkBSAFIQApBSIFIgAWBSMFIwAqBSQFJABGBSUFKQBCBSoFKgAkBSsFKwBCBSwFLAAOBS0FLQBCBS4FLgBFBS8FLwAWBTAFMAAPBTEFMgBCBTMFMwBBBTUFNQBCBTYFNgAqBTcFNwATBTgFOAAkBTkFOQAqBToFOgAWBTsFOwApBT0FPQBCBT4FPgAqBT8FPwAPBUAFQQBCBUIFQgATBUMFQwAkBUQFRwBCBUgFSQAWBUoFSgAkBUsFTAApBU0FTQAqBU4FTgAkBU8FUABGBVEFUgATBVMFVAAJBVUFVQATBVYFVgAqBVcFVwBCBVgFWAAOBVkFWgBCBVsFWwBGBVwFXABCBV0FXwA3BWAFYgAWBWMFYwAqBWQFZQAPBWYFZwBCBWgFagAWBWsFawAPBWwFbgApBW8FbwBGBXAFcgBCBXMFdAAqBXUFdQBEBXYFdgAOBXcFdwAWBXgFeAApBXkFeQAgBXoFegBCBXsFewBBBXwFfAAOBX0FfQAWBX4FfgBFBX8FfwAWBYAFgAAqBYEFgQAPBYIFhABGBYUFhQATBYYFhgAOBYcFiQBCBYoFjgBGBY8FjwAkBZAFkAATBZEFkQBCBZIFkgAPBZMFkwAWBZQFlABCBZUFlQAGBZYFlgBCBZcFlwAWBZgFmQBGBZoFngAWBZ8FogBGBaUFpwBGBagFqABLBakFqQBGBaoFqgAOBasFqwBCBa0FrgAWBa8FrwA3BbAFsQAWBbMFuABGBbkFuQAgBboFugBMBb4FvgBMBb8FvwBNBcAFwAAsBcEFwQAXBcIFwgAoBcMFwwAlBcQFxAAQBcUFxQA/BcYFxgAsBccFxwAhBcgFyAANBckFyQAUBcoFygAtBcsFywAYBcwFzAA7Bc0FzQAm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D4oPig+KCrAPig+KD4oPig+KD4oPig+KD4oKqg+KD4oPig+KD4oPig+KD4oPig+KD4oPig+KD4oPigugD4oLjguUCg4LoA+KD4oPig+KChQPigoaD4oLuA+KD4oKIA+KD4oPig+KD4oPigomD4oPigrCCiwKzg+KD4oKMgo4Cj4Pig+KD4oPigpED4oPig+KD4oPigv0D4oLUgtYC6wLZAtqD4oPigsoD4oPig+KD4oK1A+KD4oOOg+KC74Pig+KD4oPigpKD4oPig+KD4oKUA+KD4oKVg+KClwPig+KCtoPigrgCuYPigraD4oKYgrmD4oPig+KD4oPig+KD4oPig+KD4oPigvED4oLyg+KD4oOOg+KCmgKbg+KCnQPigp6CoAPigqGD4oKjAqSD4oPig+KD4oPig+KCpgPigqeCqQPig+KD4oKqg+KD4oPig+KCrAPig+KD4oPig+KD4oPig+KD4oPig+KD4oKtg+KCrwPig+KCrYPigq8D4oPigrCCsgKzg+KD4oPig+KCtQPig+KCtoPigrgCuYPigrsD4oK8g+KD4oK/gsECvgPig+KCv4LBAsKD4oPigsQD4oLFg+KD4oLHAsiCygPig+KD4oPigsuD4oPig+KD4oLNA+KD4oPig+KCzoPig+KDjoPigtAD4oPig+KD4oLRg+KD4oPig+KC0wPig+KC1ILWAteC2QLagtSC1gLrAtkC2oLUgtYC14LZAtqD4oPigtwD4oPig+KD4oLdg+KD4oPig+KC3wPig+KD4oPiguCD4oPig+KD4oLiA+KD4oPig+KC7gPig+KC44LlAuaC6APig+KD4oLpg+KD4oPig+KC6wPig+KD4oPig+KC7IPig+KD4oPig+KD4oPig+KC7gPig+KDjoPigu+D4oPigvED4oLyg+KD4oLxA+KC8oPig+KDXoMEgwMD4oPigweDCQMKg+KD4oMHgwkC9APig+KDB4MJAvWD4oPigw2DDwMDA+KDEgMNgw8DAwPigxIDDYMPAwMD4oMSAw2DDwL3A+KDEgPig+KD4oPig+KC/oPigwADAYPigxaD4oL4g+KD4oMWg+KC+IPig+KD4oPigvoD4oPig+KD4oL7g+KD4oPig+KD4oL9A+KC/oPigwADAYPig16DBIMDA+KD4oNegwSDEIPig+KDvQPigwYD4oPigweDCQMKg+KD4oMNgw8DDAPigxIDDYMPAxCD4oMSAxaD4oMTg+KD4oMWg+KDFQPig+KDFoPigxgD4oPig+KD4oMZg+KD4oPig+KD4oMbA+KDYwNkg2GD4oPigxyD4oMeA+KD4oPig+KDigPig+KD4oPig6UD4oPig2qDbANtg+KD4oNqg2wDH4Pig+KDaoNsAyED4oPig+KD4oNdA+KD4oOfA+KDoIPig+KD4oPigyKD4oPig+KD4oMig+KD4oPig+KDJAPig+KD4oPigyWD4oPig+KD4oPNg+KD4oPig+KDJwPig+KD4oPig+KD4oPig16D4oNgA+KD4oOWA+KDl4OZA+KDdoN4A28DewN8g+KD4oPig+KD4oMog+KDKgPig+KDogPig6OD4oPig0gD4oNJg0sD4oOFg+KDK4Pig+KDhYPigyuD4oPig+KD4oPig+KD4oPig+KDTgPig+KD4oPig+KD4oPig+KD4oPig+KD4oPig+KD4oONA+KD4oPigy0DjQPig+KD4oPigy6D4oMwA+KDMYPig+KDMwPig+KD4oPig+KD4oOgg+KD4oNXAzSDNgPig+KDpoOoAzeD4oPig+KD4oM5A+KD4oM6g+KDPAM9g6CD4oPig34D4oPig+KD4oM/A+KD4oPig+KDXQPig+KDnwPig6CD4oPig+KD4oPNg+KD4oNAg+KDQgPig+KDQ4Pig0UD4oPig5YD4oOXg5kD4oOWA+KDRoOZA+KD4oPig+KD4oPig6ID4oOjg+KD4oNIA+KDSYNLA+KD4oPig+KDTIPig+KD4oPig0yD4oPig+KD4oPig+KD4oPig04D4oPig+KD4oNPg+KD4oOag+KDWINRA1KDVAPig1WD4oPig1QD4oNVg+KD4oNXA+KDWINaA1uD4oPig10D4oPig+KD4oPig+KD4oOWA+KDl4OZA+KDXoPig2AD4oPig2MDZINhg+KD4oNjA2SDZgPig+KDZ4Pig2kD4oPig2qDbANtg+KD4oN2g3CDbwPig+KDdoNwg3mD4oPig+KD4oNyA+KD4oOfA+KDgQPig+KD4oPig3OD4oPig+KD4oN1A+KD4oN2g3gDeYN7A3yD4oPig34D4oPig+KD4oN/g+KD4oPig+KDgQPig+KDhYPig4KD4oPig4WD4oOEA+KD4oOFg+KDhwPig+KD4oPig4iD4oPig+KD4oOKA+KD4oPig+KDi4ONA+KD4oPig+KD4oPig46D4oOQA+KD4oORg+KDkwPig+KD4oPig+KD4oPig+KD4oOxA+KD4oPVA9aDtYPig9mD1QPWg7WD4oPZg9UD1oO4g+KD2YPig+KDlIPig+KDlgPig5eDmQPig5qD4oOcA+KD4oO9A+KD4oPig+KD4oPig+KD4oPig9UD1oO1g+KD2YPig+KDnYPig+KD4oPig52D4oPig58D4oOgg+KD4oOiA+KDo4Pig+KD4oPig6UD4oPig6aDqAOpg+KD4oPig+KDtYPig+KDqwOsg9sD4oOuA+KD4oOvg+KD4oPDA8SDwYPig+KD4oPig7ED4oPig8kDyoPMA+KD4oPJA8qDsoPig+KDyQPKg7QD4oPig9UD1oO1g+KD2YPVA9aDtYPig9mD1QPWg7cD4oPZg9UD1oO4g+KD2YO6A+KDu4Pig+KDvQPig+KD4oPig94D4oO+g+KD4oPeA+KDvoPig+KD4oPig8AD4oPig8MDxIPBg+KD4oPDA8SDxgPig+KD4oPig8eD4oPig8kDyoPMA+KD4oPPA9CDzYPig+KDzwPQg9ID4oPig9UD1oPTg+KD2YPVA9aD2APig9mD3gPig9sD4oPig94D4oPcg+KD4oPeA+KD34Pig+KD4oPig+ED4oPigABAX0AAAABAUoDUwABAWUDUwABAWUDOQABAZoDUwABAZoCvAABAWcDUwABAfICvAABAogCSgABAUoAAAABAYMAAAABAUACvAABANAAAAABAJsAAAABAM0AAAABAJsDOQABAQoCvAABAWcCvAABAX0CvAABAfAAAAABAfACvQABA0QCvAABAS8CvAABAS8BUwABAU4AAAABAU4CvAABAUsA+QABAUQAAAABAUQCvAABAUEA+QABAS4AAAABAS4CvAABAS4BUwABAVUCvAABAVQCvAABAlUAAAABAk8CvwABAJ8AAAABANEAAAABAJ8CvAABAgQCvAABAZkAAAABAZkCvAABAZkCKQABAeEAAAABAeECvAABAXsCvAABAXsAAAABAuoAAAABAXsDOQABAhwAAAABAhwCvAABAW8AAAABAmkAAAABAWUCvAABAZ0CvAABAZ0DOQABAgQDOQABAT8DOQABAZoDNQABAZoDOQABAagAAAABAfUAAAABAagDOQABAagBXgABAoECvAABAUADOQABAVQDNQABAVQDOQABAVQDUwABAVUDOQABA0MAAAABA3QAAAABAfIDOQABAK4CSgABAWYCvAABAagCvAABAMcCSgABAUoCvAABAT8CvAABAZYAAAABAZ8CvAABAV4DUwABAV4DOQABAY8DUwABAYoCvAABAfECvAABAOwCvAABAQ4CSgABATwAAAABAT4CvAABATsBSgABAY8CvAABAr0AAAABAhQCvAABAV4AAAABAlEAAAABAV4CvAABAY8DNQABAYgAAAABArEAAAABAY8DOQABAo4CvAABAYoDNQABAYoDOQABApcAAAABAYoDUwABAfEDOQABAMMCSgABATgAAAABATgCEwABATUCvQABATUCowABAVUCEgABAVUCvQABAVUCswABATQCvQABAYIAAAABAW4CEgABARACEgABAaACEgABAgEBugABAQsAAAABAQsCEgABATkAAAABAL0AAAABAI0CxQABAIsCowABAI4CxQABAVsAAAABAJAC5gABAMMCeQABATMCEAABAUEAAAABAUECEgABAYoAAAABAYoCEgABArECEAABAPgAAAABAPgCEgABAPgA/AABAR4ABQABARQCEgABARMCEgABAMgCegABAQQCEgABAdAAAAABAcoCEAABAI0AAAABAI0C5gABAI0BZgABARYC5gABAagCEgABAY8AAAABAY8CEgABASECEgABAR8AAAABAf0AAAABASECowABAdkAAAABAc0CEgABATUAAAABAgkAAAABATUCEgABAT8CEgABAGsCEgABAagCowABAVUCnwABAVUCowABAT8AAAABAaIAAAABAT8CowABAT8BCQABAcgCEgABAUUCEgABAUUCowABAQcCowABARACnwABARACowABAaAAAAABARACvQABARQCowABASMCEAABAaACowABAJoBugABAS8AAAABAUICEgABAdQAAAABAdQCEgABATECEgABAVIAAAABAVICEgABAVIBpgABAVkAAAABAVkCEgABAgYCEAABAPsAAAABAQcCEgABAToAAAABAS4CEgABASMCuwABAIsAAAABALsAAAABAIsCnwABAVAAAAABAkkAAAABAhoCEgABAgYCnQABAUgCEgABATACvQABATACowABAUYCEgABAUYCswABAUYCvQABAWkAAAABAVYCEgABAhQAAAABAVACEgABAZUCEgABAU8CEgABAU8AAAABAk8AAAABAU8CowABAeUCEgABATAAAAABAb0AAAABATACEgABATQCEgABATQAAAABAKcCEgABATQCowABAUYCnwABAUcAAAABAkAAAAABAUYCowABAhECEgABAVACnwABAVACowABApUAAAABAVACvQABAZUCowABAAAAAAAJAAAAAQAIAAEABAAAA7wABgEAAAEACAABAAwAHAABACoASgABAAYG/wcABwEHAgcEBwUAAQAFBv8HAAcBBwQHBQAGAAAAGgAAABoAAAAaAAAAGgAAABoAAAAaAAH+1AAAAAUAEgAMABIAGAAeAAH+1P9qAAH+1P9vAAH+1P9jAAH+1P9yAAYCAAABAAgAAQF6AAwAAQGgAEAAAgAIBt8G6gAABuwG/QAMBwoHJAAeB0AHQQA5B0UHRQA7B0gHSgA8B0wHUQA/B1MHVABFAEcAkACuAK4ArgKSAJYAugCuALoAnACuALoAwADAAsAAwACiAKIAwACuAK4ArgCoAK4ArgCuALQAugDAAMYAzADqAOoA6gDSANgA9gDqAPYA3gDqAPYA/AD8At4A/AD8AOoA6gDqAOQA6gDqAOoA8AD2APwBFAEOAQ4BDgEgASABIAECAQgBDgEOARQBGgEgAAH+1AKjAAH+1AMwAAH+1AMxAAH+1AL9AAH+1AKfAAH+1AMtAAH+1AMDAAH+1AK9AAH+1AKzAAH+1ALfAAH+1AM5AAH+1ANSAAH+1APGAAH+1APHAAH+1AM1AAH+1APDAAH+1AOZAAH+1ANTAAH+1ANJAAEBLAKjAAEBLAK8AAEBLAK9AAEBLAKfAAEBLAL9AAEBLAKzAAYCAAABAAgAAQAMACgAAQAyAWoAAgAEBt8G6gAABuwG/QAMBwoHJAAeB14HbQA5AAIAAQdeB20AAABJAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABMgAAATIAAAEyAAABMgAAATIAAAEyAAABMgAAATIAAAEyAAABMgAAATIAAAEyAAABMgAAATIAAAEyAAABMgAAATIAAAEyAAABMgAAATIAAAEyAAABJgAAATIAAAEyAAABMgAAATIAAAEyAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEyAAABMgAAATIAAAEyAAABMgAAATIAAAEyAAABMgAB/tQCuwAB/tQCEgAB/tQCvAAQACgAKAAiACgALgAuADQAOgBGAEYAQABGAEwATABSAFgAAf7UAyUAAf7UAxoAAf98AvcAAf9WAwsAAf7UAyAAAf7UA7sAAf7UA7AAAf98A40AAf9WA6EAAf7UA7YAAQAMACIABQEKAq4AAgADBt8G6gAABuwHJwAMB14HbQBIAAIAJgAEAEgAAABKAH8ARQCBAKYAewCpALQAoQC2AL0ArQC/ANoAtQDcAN4A0QDgAOQA1ADmAPQA2QD2ASoA6AEsATYBHQE4AVABKAFSAVQBQQFWAaUBRAGnAa4BlAGwAc4BnAHQAdYBuwHYAgcBwgIJAjwB8gI+AkUCJgJIAm0CLgJvAn0CVAJ/ArMCYwK1AtkCmALfAyMCvQMlAzUDAgM3A1sDEwNdA4IDOAOFA5ADXgOSA5kDagObA7YDcgO4A7oDjgO8A8ADkQPCBAUDlgQHBBED2gQTBCoD5QQsBC4D/QQwBGMEAABYAAIBmAACAZgAAgGYAAIBmAACAZgAAgGYAAIBmAACAZgAAgGYAAIBmAACAZgAAgGYAAIBmAACAZgAAgGYAAIBmAACAZgAAgGYAAIBmAACAZgAAgGYAAIBmAACAZgAAgGYAAIBmAACAZgAAgGYAAIBmAACAZgAAgGYAAQBmAAAAWgAAAFoAAABaAAAAWgAAQFiAAABaAAAAWgAAwFuAAMBdAADAYwAAwF6AAIBngACAZ4AAgGeAAIBngACAZ4AAgGeAAIBngACAZ4AAgGeAAIBngACAZ4AAgGeAAIBngACAZ4AAgGeAAIBngACAZ4AAgGeAAIBngACAZ4AAgGeAAIBgAACAZ4AAgGeAAIBngACAZ4AAgGeAAMBhgADAYwAAwGSAAIBmAACAZgAAgGYAAIBmAACAZgAAgGYAAIBmAACAZgAAgGeAAIBngACAZ4AAgGeAAIBngACAZ4AAgGeAAIBngAB/tUAAAAB/tQAAAAB/tQBtgAB/kwBtgAB/soBCgAB/tQCuwAB/tQBZAAB/ycBggAB/mMBXgAB/tQCEgAB/tQCvAQ0KlIqWCpGPJQ8lCpSKlgqNDyUPJQqUipYKl48lDyUKlIqWCoQPJQ8lCouKlgqXjyUPJQqUipYKhA8lDyUKlIqWCoKPJQ8lCpSKlgqEDyUPJQqUipYKl48lDyUKlIqWCpePJQ8lCpSKlgqFjyUPJQqLipYKl48lDyUKlIqWCoWPJQ8lCpSKlgqHDyUPJQqUipYKiI8lDyUKlIqWCo0PJQ8lCpSKlgqKDyUPJQqLipYKkY8lDyUKlIqWCo0PJQ8lCpSKlgqOjyUPJQqUipYKl48lDyUKlIqWCpAPJQ8lCpSKlgqRjyUPJQqUipYKkw8lDyUKlIqWCpMPJQ8lCpSKlgqXjyUPJQuWjyULlQ8lDyULlo8lC5gPJQ8lCpkPJQqajyUPJQqgjyUKnA8lDyUKoI8lCp2PJQ8lCqCPJQqfDyUPJQqgjyUKnA8lDyUKoI8lCp2PJQ8lCqCPJQqfDyUPJQqgjyUKog8lDyUM0w8lCrQLn48lCqOPJQqlC5+PJQqmjyUKqAqpjyUM0w8lCqsLn48lCqyPJQquCq+PJQqxDyUKtAufjyUKso8lCrQLn48lCrWPJQq3C5+PJQrHiskKxg8lDyUKx4rJDjaPJQ8lCseKyQrKjyUPJQrHiskKyo8lDyUKx4rJCsqPJQ8lCseKyQrKjyUPJQrHiskKuI8lDyUKwArJCsqPJQ8lCseKyQq4jyUPJQrHiskKug8lDyUKx4rJCruPJQ8lCseKyQ42jyUPJQrHiskKvQ8lDyUKx4rJCr6PJQ8lCsAKyQrGDyUPJQrHiskONo8lDyUKx4rJCsGPJQ8lCseKyQrKjyUPJQrHiskKww8lDyUKx4rJCsSPJQ8lCseKyQrEjyUPJQrHiskKxg8lDyUKx4rJCsqPJQ8lCs2PJQrMDyUPJQrNjyUKzw8lDyULDg8lC72PJQ8lCw4PJQu2DyUPJQsODyULtg8lDyULDg8lC7YPJQ8lCwgPJQu9jyUPJQsODyULuQ8lDyULDg8lC7qPJQ8lCw4PJQu9jyUPJQsODyULDIrWjyUK0I8lCtIK048lCtUPJQsMitaPJQsODyULD4rWjyULDg8lCw+K1o8lCwgPJQsMitaPJQriiuQK948lDyUPJQ8lCtgPJQ8lCuKK5ArxjyUPJQriiuQK5Y8lDyUK4orkCuWPJQ8lCuKK5ArxjyUPJQriiuQK2Y8lDyUK4orkCtsPJQ8lCuKK5ArcjyUPJQreCuQK948lDyUK4orkCvGPJQ8lCuKK5ArfjyUPJQriiuQK5Y8lDyUK4orkCuEPJQ8lCuKK5Ar3jyUPJQriiuQK5Y8lDyUPJQ8lCucPJQ8lDyUPJQrojyUPJQrqDyUK7o8lDyUK6g8lCuuPJQ8lCu0PJQrujyUPJQvUDyUK94vXC9iL1A8lCvAL1wvYi9QPJQrxi9cL2IvUDyUK94vXC9iK8w8lCveL1wvYi9QPJQr3i9cL2IrzDyUK94vXC9iL1A8lCvSL1wvYivYPJQr3i9cL2Ir5DyUK+or8Cv2K/w8lCwIPJQ8lCwCPJQsCDyUPJQsODyULDI8lDyULDg8lCwOPJQ8lCw4PJQsFDyUPJQsODyULD48lDyULCA8lCwyPJQ8lCw4PJQsGjyUPJQsIDyULDI8lDyULDg8lCwmPJQ8lCwsPJQsMjyUPJQsODyULD48lDyULIAshiyqLJIsmCyALIYsdCySLJgsgCyGLHoskiyYLIAshix6LJIsmCyALIYsRCySLJgsYiyGLHoskiyYLIAshixELJIsmCyALIYsSiySLJgsgCyGLFAskiyYLIAshix0LJIsmCyALIYsViySLJgsgCyGLIwskiyYLIAshixcLJIsmCxiLIYsqiySLJgsgCyGLHQskiyYLIAshixoLJIsmCyAPJQsqjyUPJQsgDyULHQ8lDyULGI8lCyqPJQ8lCyAPJQsdDyUPJQsgDyULGg8lDyULIA8lCx6PJQ8lCyALIYsdCySLJgsgCyGLHoskiyYLIAshixuLJIsmCyALIYsjCySLJgsgCyGLIwskiyYPJQ8lCyqPJQ8lCyALIYsqiySLJgsgCyGLHQskiyYLIAshix6LJIsmCyALIYsjCySLJgsgCyGLIwskiyYLIAshiyMLJIsmCyePJQspDyUPJQ8lDyULKo8lDyULLw8lCzOPJQ8lCy8PJQssDyUPJQsvDyULMI8lDyULLY8lCzOPJQ8lCy8PJQssDyUPJQstjyULM48lDyULLw8lCzCPJQ8lCzIPJQszjyUPJQs7DyULPI8lDyULOw8lCzUPJQ8lCzsPJQs2jyUPJQs7DyULOY8lDyULOw8lCzgPJQ8lCzsPJQs8jyUPJQs7DyULOY8lDyULPg8lCzyPJQ8lCzsPJQs/jyUPJQs+DyULPI8lDyULPg8lCz+PJQ8lDhEPJQtBDyUPJQtEDyULSItKDyULRA8lC0iLSg8lC0QPJQtCi0oPJQtEDyULSItKDyULRY8lC0iLSg8lC0WPJQtIi0oPJQtHDyULSItKDyULWQtai06PJQtdi1kLWotRjyULXYtZC1qLV48lC12LWQtai1ePJQtdi1kLWotXjyULXYtZC1qLUY8lC12LWQtai0uPJQtdi00LWotOjyULXYtZC1qLUY8lC12LWQtai1APJQtdi1kLWotOjyULXYtZC1qLUY8lC12LTQtai06PJQtdi1kLWotRjyULXYtZC1qLUA8lC12LWQtai1ePJQtdi1kLWotRjyULXYtZC1qLV48lC12LWQtai1MPJQtdi1kLWotUjyULXYtZC1qLVg8lC12LWQtai1ePJQtdi1kLWotcDyULXYtjjyULXw8lDyULY48lC2UPJQ8lC2OPJQtgjyUPJQtjjyULYg8lDyULY48lC2UPJQ8lC3EPJQtrC3QPJQtxDyULbIt0DyULcQ8lC3KLdA8lC3EPJQtmi3QPJQtxDyULaAt0DyULaY8lC2sLdA8lC3EPJQtsi3QPJQtxDyULbgt0DyULcQ8lC2+LdA8lC3EPJQtyi3QPJQt4jyULfQ8lDyULeI8lC3WPJQ8lC3iPJQt3DyUPJQt4jyULeg8lDyULe48lC30PJQ8lC5CLkguNjyUPJQuQi5ILiQ8lDyULkIuSC5OPJQ8lC5CLkguADyUPJQuHi5ILk48lDyULkIuSC4APJQ8lC5CLkgt+jyUPJQuQi5ILgA8lDyULkIuSC5OPJQ8lC5CLkguTjyUPJQuQi5ILgY8lDyULh4uSC5OPJQ8lC5CLkguBjyUPJQuQi5ILgw8lDyULkIuSC4SPJQ8lC5CLkguJDyUPJQuQi5ILhg8lDyULh4uSC42PJQ8lC5CLkguJDyUPJQuQi5ILio8lDyULkIuSC5OPJQ8lC5CLkguMDyUPJQuQi5ILjY8lDyULkIuSC48PJQ8lC5CLkguPDyUPJQuQi5ILk48lDyULlo8lC5UPJQ8lC5aPJQuYDyUPJQuZjyULmwufjyULnI8lC54Ln48lC7GLswuwDyUPJQuxi7MLqg8lDyULsYuzC7SPJQ8lC7GLswu0jyUPJQuxi7MLtI8lDyULsYuzC7SPJQ8lC7GLswuhDyUPJQuoi7MLtI8lDyULsYuzC6EPJQ8lC7GLswuijyUPJQuxi7MLpA8lDyULsYuzC6oPJQ8lC7GLswuljyUPJQuxi7MLpw8lDyULqIuzC7APJQ8lC7GLswuqDyUPJQuxi7MLq48lDyULsYuzC7SPJQ8lC7GLswutDyUPJQuxi7MLro8lDyULsYuzC66PJQ8lC7GPJQuwDyUPJQuxi7MLtI8lDyULvA8lC72PJQ8lC7wPJQu2DyUPJQu8DyULtg8lDyULvA8lC7YPJQ8lC7ePJQu9jyUPJQu8DyULuQ8lDyULvA8lC7qPJQ8lC7wPJQu9jyUPJQvMi84Lyw8lDyUPJQ8lC78PJQ8lC8yLzgvGjyUPJQvMi84Lz48lDyULzIvOC8+PJQ8lC8yLzgvGjyUPJQvMi84LwI8lDyULzIvOC8IPJQ8lC8yLzgvDjyUPJQvFC84Lyw8lDyULzIvOC8aPJQ8lC8yLzgvIDyUPJQvMi84Lz48lDyULzIvOC8mPJQ8lC8yLzgvLDyUPJQvMi84Lz48lDyUPJQ8lC9EPJQ8lDyUPJQvSjyUPJQvUDyUL1YvXC9iL2g8lC90PJQ8lC9uPJQvdDyUPJQvpDyUL548lDyUL6Q8lC96PJQ8lC+kPJQvgDyUPJQvpDyUL6o8lDyUL4w8lC+ePJQ8lC+kPJQvhjyUPJQvjDyUL548lDyUL6Q8lC+SPJQ8lC+YPJQvnjyUPJQvpDyUL6o8lDyUL7A8lC+2PJQ8lDNYPJQvzi/UPJQzWDyUL84v1DyUM1g8lC+8L9Q8lDNYPJQvzi/UPJQvwjyUL84v1DyUL8I8lC/OL9Q8lC/IPJQvzi/UPJQwEDAWL/48lDAiMBAwFi/sPJQwIjAQMBYwCjyUMCIwEDAWMAo8lDAiMBAwFjAKPJQwIjAQMBYv7DyUMCIwEDAWL9o8lDAiL+AwFi/+PJQwIjAQMBYv7DyUMCIwEDAWL+Y8lDAiMBAwFi/+PJQwIjAQMBYv7DyUMCIv4DAWL/48lDAiMBAwFi/sPJQwIjAQMBYv5jyUMCIwEDAWMAo8lDAiMBAwFi/sPJQwIjAQMBYwCjyUMCIwEDAWL/I8lDAiMBAwFi/4PJQwIjAQMBYv/jyUMCIwEDAWMAQ8lDAiMBAwFjAKPJQwIjAQMBYwHDyUMCIwOjyUMCg8lDyUMDo8lDBAPJQ8lDA6PJQwLjyUPJQwOjyUMDQ8lDyUMDo8lDBAPJQ8lDBwPJQwWDyUPJQwcDyUMF48lDyUMHA8lDB2PJQ8lDBwPJQwRjyUPJQwcDyUMEw8lDyUMFI8lDBYPJQ8lDBwPJQwXjyUPJQwcDyUMGQ8lDyUMHA8lDBqPJQ8lDBwPJQwdjyUPJQ6SDyUMI48lDyUOkg8lDB8PJQ8lDpIPJQwgjyUPJQ6SDyUMIg8lDyUOiQ8lDCOPJQ8lDnoMNYwyjyUPJQ56DDWMLg8lDyUOegw1jDcPJQ8lDnoMNYwmjyUPJQ59DDWMNw8lDyUOegw1jCaPJQ8lDnoMNYwlDyUPJQ56DDWMJo8lDyUOegw1jDcPJQ8lDnoMNYw3DyUPJQ56DDWMKA8lDyUOfQw1jDcPJQ8lDnoMNYwoDyUPJQ56DDWMKY8lDyUOegw1jCsPJQ8lDnoMNYwuDyUPJQ56DDWMLI8lDyUOfQw1jDKPJQ8lDnoMNYwuDyUPJQ56DDWML48lDyUOegw1jDcPJQ8lDnoMNYwxDyUPJQ56DDWMMo8lDyUOegw1jDQPJQ8lDnoMNYw0DyUPJQ56DDWMNw8lDyUMOg8lDDiPJQ8lDDoPJQw7jyUPJQxBjyUMPQ8lDyUMQY8lDD6PJQ8lDEGPJQxADyUPJQxBjyUMPQ8lDyUMQY8lDD6PJQ8lDEGPJQxADyUPJQxBjyUMQw8lDyUMRI8lDyUNQ41FDESPJQ8lDUONRQxEjyUPJQ1DjUUMRg8lDyUNQ41FDEePJQ8lDUONRQxJDyUMSo1DjUUO1AxeDFOPJQ8lDtQMXgxVDyUPJQ7UDF4MX48lDyUO1AxeDF+PJQ8lDtQMXgxfjyUPJQ7UDF4MX48lDyUO1AxeDEwPJQ8lDgUMXgxfjyUPJQ7UDF4MTA8lDyUO1AxeDE2PJQ8lDtQMXgxPDyUPJQ7UDF4MVQ8lDyUO1AxeDFCPJQ8lDtQMXgxSDyUPJQ4FDF4MU48lDyUO1AxeDFUPJQ8lDtQMXgxWjyUPJQ7UDF4MX48lDyUO1AxeDFgPJQ8lDtQMXgxZjyUPJQ7UDF4MWY8lDyUMWw8lDFyPJQ8lDtQMXgxfjyUPJQxhDGKMZA8lDyUMZw8lDGWPJQ8lDGcPJQxojyUPJQ8lDyUMag8lDyUPJQ8lDGuPJQ8lDyUPJQxrjyUPJQ8lDyUMa48lDyUPJQ8lDG0PJQ8lDyUPJQxujyUPJQ8lDyUMcA8lDyUOkg8lDWkMdIx2DpIPJQ1pDHSMdgxxjyUNaQx0jHYOkg8lDIyMdIx2DpIPJQxzDHSMdg6JDyUNaQx0jHYM3AyDjIIPJQ8lDNwMg4x3jyUPJQzcDIOMfY8lDyUM3AyDjIUPJQ8lDNwMg4yFDyUPJQzcDIOMfY8lDyUM3AyDjHkPJQ8lDNwMg4x6jyUPJQzcDIOMfA8lDyUM2oyDjIIPJQ8lDNwMg4x9jyUPJQzcDIOMfw8lDyUM3AyDjIUPJQ8lDNwMg4ySjyUPJQzcDIOMgI8lDyUM3AyDjIIPJQ8lDNwMg4yFDyUPJQ8lDyUMho8lDyUPJQ8lDIgPJQ8lDyUPJQyJjyUPJQyLDyUNaQ8lDI+Miw8lDIyPJQyPjI4PJQ1pDyUMj44LDyUMkQ8lDyUM3A8lDWkNaoyUDNwPJQ1hjWqMlAzcDyUNaQ1qjJQM2o8lDWkNaoyUDNwPJQ1pDWqMlAzajyUNaQ1qjJQM3A8lDJKNaoyUDN8PJQ1pDWqMlAyVjyUMlwyYjJoMm48lDyUPJQ8lDJ0PJQ8lDyUPJQ6SDyUMp48lDyUOkg8lDJ6PJQ8lDKAPJQyhjyUPJQ6SDyUMqQ8lDyUOiQ8lDKePJQ8lDpIPJQyjDyUPJQ6JDyUMp48lDyUOkg8lDKSPJQ8lDKYPJQynjyUPJQ6SDyUMqQ8lDyUMxYzHDL4MygzLjMWMxwy7DMoMy4zFjMcMxAzKDMuMxYzHDMQMygzLjMWMxwyqjMoMy4yyDMcMxAzKDMuMxYzHDKqMygzLjMWMxwysDMoMy4zFjMcMrYzKDMuMxYzHDLsMygzLjMWMxwyvDMoMy4zFjMcMyIzKDMuMxYzHDLCMygzLjLIMxwy+DMoMy4zFjMcMuwzKDMuMxYzHDLOMygzLjLmPJQzXjyUPJQy5jyUMto8lDyUMtQ8lDNePJQ8lDLmPJQy2jyUPJQy5jyUMuA8lDyUMuY8lDMQPJQ8lDMWMxwy7DMoMy4zFjMcMxAzKDMuMxYzHDLyMygzLjMWMxwzIjMoMy4zFjMcMyIzKDMuMxY8lDL4Mygy/jMWMxwzBDMoMy4zFjMcMwozKDMuMxYzHDMQMygzLjMWMxwzIjMoMy4zFjMcMyIzKDMuMxYzHDMiMygzLjM0PJQzOjyUPJQzQDyUM0Y8lDyUM0w8lDNSPJQ8lDNYPJQzXjyUPJQzcDyUM4I8lDyUM3A8lDNkPJQ8lDNwPJQzdjyUPJQzajyUM4I8lDyUM3A8lDNkPJQ8lDNqPJQzgjyUPJQzcDyUM3Y8lDyUM3w8lDOCPJQ8lDOgPJQzpjyUPJQzoDyUM4g8lDyUM6A8lDOOPJQ8lDOgPJQzmjyUPJQzoDyUM5Q8lDyUM6A8lDOmPJQ8lDOgPJQzmjyUPJQzrDyUM6Y8lDyUM6A8lDOyPJQ8lDOsPJQzpjyUPJQzrDyUM7I8lDyUM9A8lDPoM+4z9DO4PJQzvjPEM8oz0DyUM+gz7jP0M9A8lDPoM+4z9DPcPJQz6DPuM/Qz0DyUM9Yz7jP0M9w8lDPoM+4z9DPiPJQz6DPuM/Q23DQGNig8lDQSNtw0BjYuPJQ0EjbcNAY2RjyUNBI23DQGNkY8lDQSNtw0BjZGPJQ0EjbcNAY2LjyUNBI23DQGNhw8lDQSM/o0BjYoPJQ0EjbcNAY2LjyUNBI23DQGNjQ8lDQSNtw0BjYoPJQ0EjbcNAY2LjyUNBIz+jQGNig8lDQSNtw0BjYuPJQ0EjbcNAY2NDyUNBI23DQGNkY8lDQSNtw0BjYuPJQ0EjbcNAY2RjyUNBI23DQGNjo8lDQSNtw0BjQMPJQ0EjbcNAY2KDyUNBI23DQGNAA8lDQSNtw0BjZGPJQ0EjbcNAY0DDyUNBI0GDyUNB48lDyUNDY8lDQkPJQ8lDQ2PJQ0PDyUPJQ0NjyUNCo8lDyUNDY8lDQwPJQ8lDQ2PJQ0PDyUPJQ0bDyUNFQ8lDyUNGw8lDRaPJQ8lDRsPJQ0cjyUPJQ0bDyUNEI8lDyUNGw8lDRIPJQ8lDROPJQ0VDyUPJQ0bDyUNFo8lDyUNGw8lDRgPJQ8lDRsPJQ0ZjyUPJQ0bDyUNHI8lDyUNIQ8lDSWPJQ8lDSEPJQ0eDyUPJQ0hDyUNH48lDyUNIQ8lDSKPJQ8lDSQPJQ0ljyUPJQ05DTqNNg8lDyUNOQ06jTGPJQ8lDTkNOo08DyUPJQ05DTqNKI8lDyUNMA06jTwPJQ8lDTkNOo0ojyUPJQ05DTqNJw8lDyUNOQ06jSiPJQ8lDTkNOo08DyUPJQ05DTqNPA8lDyUNOQ06jSoPJQ8lDTANOo08DyUPJQ05DTqNKg8lDyUNOQ06jSuPJQ8lDTkNOo0tDyUPJQ05DTqNMY8lDyUNOQ06jS6PJQ8lDTANOo02DyUPJQ05DTqNMY8lDyUNOQ06jTMPJQ8lDTkNOo08DyUPJQ05DTqNNI8lDyUNOQ06jTYPJQ8lDTkNOo03jyUPJQ05DTqNN48lDyUNOQ06jTwPJQ8lDyUPJQ09jyUPJQ8lDyUNPw8lDyUNQI8lDUINQ41FDViNWg1PjyUPJQ1YjVoNUQ8lDyUNWI1aDVuPJQ8lDViNWg1bjyUPJQ1YjVoNW48lDyUNWI1aDVuPJQ8lDViNWg1GjyUPJQ1ODVoNW48lDyUNWI1aDUaPJQ8lDViNWg1IDyUPJQ1YjVoNSY8lDyUNWI1aDVEPJQ8lDViNWg1LDyUPJQ1YjVoNTI8lDyUNTg1aDU+PJQ8lDViNWg1RDyUPJQ1YjVoNUo8lDyUNWI1aDVuPJQ8lDViNWg1UDyUPJQ1YjVoNVY8lDyUNWI1aDVWPJQ8lDdmPJQ1XDyUPJQ1YjVoNW48lDyUNXQ1ejWAPJQ8lDWePJQ1pDWqNc41njyUNYY1qjXONZ48lDWkNao1zjWMPJQ1pDWqNc41njyUNaQ1qjXONYw8lDWkNao1zjWePJQ1kjWqNc41mDyUNaQ1qjXONZ48lDWkNao1zjWwPJQ1tjyUPJQ11DyUNew18jX4Nbw8lDXCNcg1zjXUPJQ17DXyNfg11DyUNew18jX4NeA8lDXsNfI1+DXUPJQ12jXyNfg14DyUNew18jX4NeY8lDXsNfI1+DYQPJQ1/jyUPJQ2EDyUNhY8lDyUNhA8lDYEPJQ8lDYQPJQ2CjyUPJQ2EDyUNhY8lDyUNkA8lDYoPJQ8lDZAPJQ2LjyUPJQ2QDyUNkY8lDyUNkA8lDYcPJQ8lDYiPJQ2KDyUPJQ2QDyUNi48lDyUNkA8lDY0PJQ8lDZAPJQ2OjyUPJQ2QDyUNkY8lDyUNlg8lDZqPJQ8lDZYPJQ2TDyUPJQ2WDyUNlI8lDyUNlg8lDZePJQ8lDZkPJQ2ajyUPJQ7UDayNqY8lDyUO1A2sjaUPJQ8lDtQNrI2uDyUPJQ7UDayNnY8lDyUOBQ2sja4PJQ8lDtQNrI2djyUPJQ7UDayNnA8lDyUO1A2sjZ2PJQ8lDtQNrI2uDyUPJQ7UDayNrg8lDyUO1A2sjZ8PJQ8lDgUNrI2uDyUPJQ7UDayNnw8lDyUO1A2sjaCPJQ8lDtQNrI2iDyUPJQ7UDayNpQ8lDyUO1A2sjaOPJQ8lDgUNrI2pjyUPJQ7UDayNpQ8lDyUO1A2sjaaPJQ8lDtQNrI2uDyUPJQ7UDayNqA8lDyUO1A2sjamPJQ8lDtQNrI2rDyUPJQ7UDayNqw8lDyUO1A2sja4PJQ8lDbEPJQ2vjyUPJQ2xDyUNso8lDyUNvQ8lDbQPJQ8lDbcPJQ6/DyUPJQ23DyUNtY8lDyUNtw8lDrePJQ8lDbcPJQ6/DyUPJQ23DyUNtY8lDyUNtw8lDrePJQ8lDbcPJQ66jyUPJQ29DyUOAg6eDyUNuI8lDboNu48lDb0PJQ39jp4PJQ2+jyUNwA3BjyUNww8lDgIOng8lDcSPJQ4CDp4PJQ3GDyUNx46eDyUN2Y3bDdgPJQ8lDdmN2w3SDyUPJQ3ZjdsN3I8lDyUN2Y3bDdyPJQ8lDdmN2w3cjyUPJQ3ZjdsN3I8lDyUN2Y3bDckPJQ8lDdCN2w3cjyUPJQ3ZjdsNyQ8lDyUN2Y3bDcqPJQ8lDdmN2w3MDyUPJQ3ZjdsN0g8lDyUN2Y3bDc2PJQ8lDdmN2w3PDyUPJQ3QjdsN2A8lDyUN2Y3bDdIPJQ8lDdmN2w3TjyUPJQ3ZjdsN3I8lDyUN2Y3bDdUPJQ8lDdmN2w3WjyUPJQ3ZjdsN1o8lDyUN2Y3bDdgPJQ8lDdmN2w3cjyUPJQ60jyUOtg8lDyUN348lDd4PJQ8lDd+PJQ3hDyUPJQ8BDyUOvw8lDyUPAQ8lDrePJQ8lDwEPJQ63jyUPJQ8BDyUOt48lDyUO9o8lDr8PJQ8lDwEPJQ66jyUPJQ8BDyUOvA8lDyUPAQ8lDr8PJQ8lDh6PJQ4dDeiPJQ3ijyUN5A3ljyUN5w8lDh0N6I8lDh6PJQ4gDeiPJQ4ejyUOIA3ojyUOGI8lDh0N6I8lDfYN9430jyUPJQ32DfeN9I8lDyUN9g33jfAPJQ8lDfYN9435DyUPJQ32DfeN+Q8lDyUN9g33jfAPJQ8lDfYN943qDyUPJQ32DfeN648lDyUN9g33je0PJQ8lDe6N9430jyUPJQ32DfeN8A8lDyUN9g33jfGPJQ8lDfYN9435DyUPJQ8lDyUOyA8lDyUN9g33jfMPJQ8lDfYN9430jyUPJQ32DfeN+Q8lDyUPJQ8lDfqPJQ8lDyUPJQ38DyUPJQ4AjyUOAg8lDyUOAI8lDf2PJQ8lDf8PJQ4CDyUPJQ4AjyUOAg8lDyUO1A8lDgmO1w7YjtQPJQ4DjtcO2I7UDyUOCY7XDtiOBQ8lDgmO1w7YjtQPJQ4JjtcO2I4FDyUOCY7XDtiO1A8lDgaO1w7YjggPJQ4JjtcO2I4LDyUODI4ODg+OEQ8lDhQPJQ8lDhKPJQ4UDyUPJQ4ejyUOHQ8lDyUOHo8lDhWPJQ8lDh6PJQ4gDyUPJQ4YjyUOHQ8lDyUOHo8lDhcPJQ8lDhiPJQ4dDyUPJQ4ejyUOGg8lDyUOG48lDh0PJQ8lDh6PJQ4gDyUPJQ4zjjUOLw44DjmOM441DiwOOA45jjOONQ4yDjgOOY4zjjUOMg44DjmOM441DiGOOA45jikONQ4yDjgOOY4zjjUOIY44DjmOM441DiMOOA45jjOONQ4kjjgOOY4zjjUOLA44DjmOM441DiYOOA45jjOONQ42jjgOOY4zjjUOJ444DjmOKQ41Di8OOA45jjOONQ4sDjgOOY4zjjUOKo44DjmOM48lDi8PJQ8lDjOPJQ4sDyUPJQ4pDyUOLw8lDyUOM48lDiwPJQ8lDjOPJQ4qjyUPJQ4zjyUOMg8lDyUOM441DiwOOA45jjOONQ4yDjgOOY4zjjUOLY44DjmOM441DjaOOA45jjOONQ42jjgOOY8lDyUOLw8lDyUOMI41DuYOOA45jjCONQ7ejjgOOY4zjjUOMg44DjmOM441DjaOOA45jjOONQ42jjgOOY4zjjUONo44DjmOOw8lDjyPJQ8lDyUPJQ4+DyUPJQ5CjyUORw8lDyUOQo8lDj+PJQ8lDkKPJQ5EDyUPJQ5BDyUORw8lDyUOQo8lDj+PJQ8lDkEPJQ5HDyUPJQ5CjyUORA8lDyUORY8lDkcPJQ8lDk6PJQ5QDyUPJQ5OjyUOSI8lDyUOTo8lDkoPJQ8lDk6PJQ5NDyUPJQ5OjyUOS48lDyUOTo8lDlAPJQ8lDk6PJQ5NDyUPJQ5RjyUOUA8lDyUOTo8lDlMPJQ8lDlGPJQ5QDyUPJQ5RjyUOUw8lDyUOVg8lDlwOXY8lDlYPJQ5cDl2PJQ5WDyUOVI5djyUOVg8lDlwOXY8lDlkPJQ5cDl2PJQ5WDyUOV45djyUOWQ8lDlwOXY8lDlqPJQ5cDl2PJQ8BDl8O/I8lDmCPAQ5fDvmPJQ5gjwEOXw7/jyUOYI8BDl8O/48lDmCPAQ5fDv+PJQ5gjwEOXw75jyUOYI8BDl8O9Q8lDmCO9o5fDvyPJQ5gjwEOXw75jyUOYI8BDl8O+A8lDmCPAQ5fDvyPJQ5gjwEOXw75jyUOYI72jl8O/I8lDmCPAQ5fDvmPJQ5gjwEOXw74DyUOYI8BDl8O/48lDmCPAQ5fDvmPJQ5gjwEOXw7/jyUOYI8BDl8O+w8lDmCPAQ5fDwQPJQ5gjwEOXw7+DyUOYI8BDl8O/48lDmCPAQ5fDwQPJQ5gjmaPJQ5iDyUPJQ5mjyUOaA8lDyUOZo8lDmOPJQ8lDmaPJQ5lDyUPJQ5mjyUOaA8lDyUOdA8lDm4PJQ8lDnQPJQ5vjyUPJQ50DyUOdY8lDyUOdA8lDmmPJQ8lDnQPJQ5rDyUPJQ5sjyUObg8lDyUOdA8lDm+PJQ8lDnQPJQ5xDyUPJQ50DyUOco8lDyUOdA8lDnWPJQ8lDnoPJQ5+jyUPJQ56DyUOdw8lDyUOeg8lDniPJQ8lDnoPJQ57jyUPJQ59DyUOfo8lDyUOkg6Tjo8PJQ8lDpIOk46KjyUPJQ6SDpOOlQ8lDyUOkg6TjoGPJQ8lDokOk46VDyUPJQ6SDpOOgY8lDyUOkg6TjoAPJQ8lDpIOk46BjyUPJQ6SDpOOlQ8lDyUOkg6TjpUPJQ8lDpIOk46DDyUPJQ6JDpOOlQ8lDyUOkg6TjoMPJQ8lDpIOk46EjyUPJQ6SDpOOhg8lDyUOkg6TjoqPJQ8lDpIOk46HjyUPJQ6JDpOOjw8lDyUOkg6TjoqPJQ8lDpIOk46MDyUPJQ6SDpOOlQ8lDyUOkg6Tjo2PJQ8lDpIOk46PDyUPJQ6SDpOOkI8lDyUOkg6TjpCPJQ8lDpIOk46VDyUPJQ6YDyUOlo8lDyUOmA8lDpmPJQ8lDpsPJQ6cjp4PJQ6wDrGOro8lDyUOsA6xjqiPJQ8lDrAOsY6zDyUPJQ6wDrGOsw8lDyUOsA6xjrMPJQ8lDrAOsY6zDyUPJQ6wDrGOn48lDyUOpw6xjrMPJQ8lDrAOsY6fjyUPJQ6wDrGOoQ8lDyUOsA6xjqKPJQ8lDrAOsY6ojyUPJQ6wDrGOpA8lDyUOsA6xjqWPJQ8lDqcOsY6ujyUPJQ6wDrGOqI8lDyUOsA6xjqoPJQ8lDrAOsY6zDyUPJQ6wDrGOq48lDyUOsA6xjq0PJQ8lDrAOsY6tDyUPJQ8lDyUOro8lDyUOsA6xjrMPJQ8lDrSPJQ62DyUPJQ69jyUOvw8lDyUOvY8lDrePJQ8lDr2PJQ63jyUPJQ69jyUOt48lDyUOuQ8lDr8PJQ8lDr2PJQ66jyUPJQ69jyUOvA8lDyUOvY8lDr8PJQ8lDsyOzg7LDyUPJQ7Mjs4Oyw8lDyUOzI7ODsUPJQ8lDsyOzg7PjyUPJQ7Mjs4Oz48lDyUOzI7ODsUPJQ8lDsyOzg7AjyUPJQ7Mjs4Owg8lDyUOw47ODssPJQ8lDsyOzg7FDyUPJQ7Mjs4Oxo8lDyUOzI7ODs+PJQ8lDyUPJQ7IDyUPJQ7Mjs4OyY8lDyUOzI7ODssPJQ8lDsyOzg7PjyUPJQ8lDyUO0Q8lDyUPJQ8lDtKPJQ8lDtQPJQ7VjtcO2I7aDyUO3Q8lDyUO248lDt0PJQ8lDuePJQ7mDyUPJQ7njyUO3o8lDyUO548lDukPJQ8lDuGPJQ7mDyUPJQ7njyUO4A8lDyUO4Y8lDuYPJQ8lDuePJQ7jDyUPJQ7kjyUO5g8lDyUO548lDukPJQ8lDuwPJQ7yDvOPJQ7sDyUO8g7zjyUO7A8lDuqO848lDuwPJQ7yDvOPJQ7vDyUO8g7zjyUO7A8lDu2O848lDu8PJQ7yDvOPJQ7wjyUO8g7zjyUPAQ8CjvyPJQ8FjwEPAo75jyUPBY8BDwKO/48lDwWPAQ8Cjv+PJQ8FjwEPAo7/jyUPBY8BDwKO+Y8lDwWPAQ8CjvUPJQ8FjvaPAo78jyUPBY8BDwKO+Y8lDwWPAQ8CjvgPJQ8FjwEPAo78jyUPBY8BDwKO+Y8lDwWO9o8CjvyPJQ8FjwEPAo75jyUPBY8BDwKO+A8lDwWPAQ8Cjv+PJQ8FjwEPAo75jyUPBY8BDwKO/48lDwWPAQ8CjvsPJQ8FjwEPAo8EDyUPBY8BDwKO/I8lDwWPAQ8Cjv4PJQ8FjwEPAo7/jyUPBY8BDwKPBA8lDwWPC48lDwcPJQ8lDwuPJQ8NDyUPJQ8LjyUPCI8lDyUPC48lDwoPJQ8lDwuPJQ8NDyUPJQ8ZDyUPEw8lDyUPGQ8lDxSPJQ8lDxkPJQ8ajyUPJQ8ZDyUPDo8lDyUPGQ8lDxAPJQ8lDxGPJQ8TDyUPJQ8ZDyUPFI8lDyUPGQ8lDxYPJQ8lDxkPJQ8XjyUPJQ8ZDyUPGo8lDyUPHw8lDyOPJQ8lDx8PJQ8cDyUPJQ8fDyUPHY8lDyUPHw8lDyCPJQ8lDyIPJQ8jjyUPJQAAQFuA7sAAQFuA7AAAQIWA40AAQHwA6EAAQFuA7YAAQFu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AFYAZQB0AIMAkQCgAK8AvgDNANwA6wD6AQkBGAEnATYAAP//ABUADAAbACoAOQBIAFcAZgB1AIQAkgChALAAvwDOAN0A7AD7AQoBGQEoATcAAP//ABUADQAcACsAOgBJAFgAZwB2AIUAkwCiALEAwADPAN4A7QD8AQsBGgEpATgAAP//ABUADgAdACwAOwBKAFkAaAB3AIYAlACjALIAwQDQAN8A7gD9AQwBGwEqATkBOmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNjbXAHgmNjbXAHgmNjbXAHgmNjbXAHgmNjbXAHgmNjbXAHcmNjbXAHgmNjbXAHgmNjbXAHgmNjbXAHgmNjbXAHgmNjbXAHgmNjbXAHgmNjbXAHgmNjbXAHgmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxvY2wHsGxvY2wHtmxvY2wHvGxvY2wHwmxvY2wHyGxvY2wHzmxvY2wH1GxvY2wH2mxvY2wH4GxvY2wH5mxvY2wH7GxvY2wH8mxvY2wH+GxvY2wH/m51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQgAAAAIAAAABAAAAAQAkAAAAAQAmAAAABgACAAMABAAFAAYABwAAAAQAAgADAAQABQAAAAEAJwAAAAEAGgAAAAMAGwAcAB0AAAABACgAAAABACAAAAABABEAAAABABUAAAABABQAAAABABIAAAABABMAAAABABAAAAABAAkAAAABAA8AAAABAAwAAAABAAsAAAABAAgAAAABAAoAAAABAA0AAAABAA4AAAABABkAAAABACMAAAACAB4AHwAAAAEAIQAAAAEAKQAAAAEAFwAAAAEAJQAAAAEAKgAAAAEAFgAAAAEAGAAAAAEAIgAtAFwG3hGaEkgSrhKuFAIUAhSsFNoVHhUeFUAVQBVAFUAVQBVUFcIV1hX8FhYWPBZKFlgWiBZmFnQWiBaWFt4XJhdIF2AXeBeQF64Z+BxUHUYdZh2OHY4iniM4AAEAAAABAAgAAgRCAh4C+wL8Av0C/gL/AwADAQMCAwMDBAMFAwYDBwMIAyIDIwMtAy4DLwMwAzEDMgNHA0gDSQNLA0wDTQNOA08DUANRA1IDUwNhA2IDYwNkA2UDZgNnA2gDaQNqA2sDbANtA24DbwNwA3EDcgNzA3QDdQN2A3cDeAN5A3oDewN8A30DfgN/A4ADgQOCA4MDhAOGA4cDiAOJA4oDiwOMA40DjgOPA5ADkQOSA5MDlQOWA5cDmAOZA5oDuwPBAvsC/AL9Av4C/wMAAwEDAgMDAwQDBQMGAwcDCAMiAyMDJQMmAycDKAMpAyoDKwMsAy0DLgMvAzADMQMyAzQDNQM3AzgDOQM6AzsDPAM9Az4DPwNAA0EDQgNDA0QDRgNHA0gDSQNKA1QDVQNWA1cDWANZA1oDWwNcA10DXgNfA2EDYgNjA2QDZQNmA2cDaANpA2oDawNsA20DbgNvA3ADcQNyA3MDdAN1A3YDdwN4A3kDegN7A3wDfQN+A38DgAOBA4MDhAOFA4YDhwOIA4kDigOLA4wDjQOOA48DkAORA5IDkwOVA5YDlwOYA5kDmgOjA6QDpQOmA6cDqAOpA6oDqwOsA60DrgOvA7ADsQOyA7MDtAO1A7YDtwO4A7kDugO7A8EDxgM2At0C3gPRA9ID0wPUA9UD1gPXA9gD2QPaA9sD3APdA94D3wPgA+ED4gPjA+QD5QPmA+cD6APpA+oD6wPsA+0D7gPvA/AD8QPyA/MD9AP1A/YD9wP4A/kD+gP7A/wD/QP+A/8EAAQBBAIEAwQEBAUEBgQHBAgECQQKBAsEDAQNBA4EDwQQBBEEEgQTBBQEFQQWBBcEGAQZBBoEGwQcBB0EHgQfBCAEIQQiBCMEJAQlBCYEJwQoBCkEKgQrBCwELQQuBC8EMAQxBDIEMwQ0BDUENgQ3BDgEOQQ6BDsEPAQ9BD4EPwRABEEEQgRDBEQERQRGBEcESARJBEoESwRMBE0ETgRPBFAEUQRSBFMEVARVBFYEVwRYBFkEWgRbBFwEXQReBF8EYARhBGIEYwTjBOUE5gTnBOgE6QTrBOoE7QTuBO8E8ATyBPME9AT1BPYE9wT4BN8E4AT5BPoE+wT8BP0E/gT/BQAFAQUCBQMFBAUFBZoFlQV9BZQFnAWdBZ4FgAWBBaEFhQWGBYcFowWlBaYFigWLBYwFjQWpBaoFqwWQBawFkQWSBZMFrQWuBa8FsAWxBbIFswW0BbUFtgW3BbgFuQX8Bf0F/gX/BgAGAQYCBgMGBAYFBjYGOAZgBmEGZgZnBmgGaQZwBjkGQgZDBkQGRQZGBkcGTwZQBlEGagZrBmwGbQZuBm8GuQa6BrsGvAbcBt4G3QcKBwsHDAcNBw4HDwcQBxEHEgcTBxQHFQcWBxcHGAcZBxoHGwccBx0HHgcfByAHIQciByMHJAdWByYHZgdnB2gHaQdqB2sHbAdtAAIAXgAgACgAAAAqAC4ACQBHAEgADgBSAFcAEABqAG0AFgBvAHYAGgCFAKgAIgCqALcARgC5AL4AVADfAN8AWgDlAOUAWwGmAbMAXAHNAc4AagHQAd0AbAHfAe4AegHxAfUAigH/AgIAjwIEAgsAkwINAi0AmwIvAj8AvAJBAkYAzQJQAmgA0wJuAm4A7AJzAnMA7QJ+An4A7gLbAtwA7wLfAvoA8QMJAyEBDQMkAywBJgMzAzsBLwM9A0YBOANRA1EBQgNUA18BQwOFA4UBTwObA7oBUAO8A8ABcAPCA9ABdQRmBGYBhARtBG8BhQRyBHUBiAR9BH0BjAR/BIEBjQSJBI0BkASTBJMBlQSYBJgBlgScBJwBlwSfBJ8BmASqBKoBmQS8BL8BmgTFBMYBngTLBM0BoATQBNABowTWBNYBpATYBNgBpQUGBQgBpgUKBQoBqQUNBREBqgUVBRYBrwUYBRgBsQUaBRoBsgUdBR0BswUgBSEBtAUkBScBtgUrBS0BugU1BTUBvQU4BTgBvgU8BTwBvwU/BT8BwAVJBUkBwQVdBWIBwgVmBWcByAVsBW4BygVxBXEBzQV5BXkBzgYGBg8BzwYlBiUB2QYnBicB2gYrBiwB2wYuBjIB3QY7BkEB4gZIBkkB6QZMBkwB6wZWBlsB7AavBq8B8gaxBrEB8wazBrMB9Aa1BrUB9QbKBssB9gbYBtgB+AbfBuoB+QbsBu8CBQbyBvwCCQcHBwgCFAdeB2UCFgADAAAAAQAIAAEJtAEyAmoCcgJ4An4ChAKKApAClgKcAqICqAKuArQCugLAAsYCzALSAtgC3gLkAuoC8AL2AvwDAgMIAw4DFAMaAyADJgMsAzIDOAM+A0QDSgNQA1YDXANiA2gDbgN0A3oDgAOGA4wDkgOYA54DpAOqA7ADtgO8A8IDyAPOA9QD2gPgA+YD7APyA/gD/gQEBAoEEAQWBBwEIgQoBC4ENAQ6BEAERgRMBFIEWAReBGQEagRwBHYEfASCBIgEjgSUBJoHdgSgBKYErASyBLgEvgTEBMwE0gTYBN4E5ATqBPAE9gT8BQIFCAUOBRQFGgUgBSYFLAUyBTgFPgVEBUoFUAVWBVwFYgVoBW4FdAV6BYAFhgWMBZIFmAWeBaQFqgWwBbYFvAXCBcgFzgXUBdoF4AXmBewF9AX6BgAGBgYMBhIGGAYeBiQGKgYwBjYGPAZCBkgGTgZUBloGYAZmBmwGcgZ4Bn4GhAaKBpAGlgacBqIGqAauBrQGugbABsYGzAbSBtgG3gbkBuoG8Ab2BvwHAgcIBw4HFAcaByAHJgcsBzIHOgdAB0YHTAdSB1gHXgdkB2oHcAd2B3wHggeIB44HlAeaB6IHqAeuB7QHugfAB8YHzAfSB9gH3gfkB+oH8Af2B/wIAggICA4IFAgaCCAIJggsCDIIOAg+CEQISghSCFgIXghkCGoIcgh4CH4IjgieCK4IvgjOCN4I7gj+CQ4JHgkkCSoJMAk2CTwJQglICU4JVAkeCSQJKgkwCTYJPAlCCUgJTglUCVoJXgliCWYJagluCXIJdgl6CX4JggmKCZAJlgmcCaIJqAmuAAMEZALfAPYAAgLgAPcAAgLhAPgAAgLiAPkAAgLjAPoAAgLkAPsAAgLlAPwAAgLmAP0AAgLnAP4AAgLoAP8AAgLpAQAAAgLqAQEAAgLrAQIAAgLsAQMAAgLtAQQAAgLuAQUAAgLvAQYAAgLwAQcAAgLxAQgAAgLyAQkAAgLzAQoAAgL0AQsAAgL1AQwAAgL2AQ0AAgL3AQ4AAgL4AQ8AAgL5ARAAAgL6AREAAgMJARIAAgMJARMAAgMKARQAAgMLARUAAgMMARYAAgMNARcAAgMOARgAAgMPARkAAgMQARoAAgMRARsAAgMSARwAAgMTAR0AAgMUAR4AAgMVAR8AAgMWASAAAgMXASEAAgMYASIAAgMZASMAAgMaASQAAgMbASUAAgMcASYAAgMdAScAAgMeASgAAgMfASkAAgMgASoAAgMkASsAAgMlASwAAgMmAS0AAgMnAS4AAgMoAS8AAgMpATAAAgMqATEAAgMrATIAAgMsATMAAgMzATQAAgNBATUAAgM1ATYAAgM3ATgAAgM4ATkAAgM5AToAAgM6ATsAAgM7ATwAAgM8AT0AAgM9AT4AAgM+AT8AAgM/AUAAAgNAAUEAAgNCAUIAAgNDAUMAAgNEAUQAAgNFAUUAAgNGAUYAAgNRAUcAAgNUAUgAAgNVAUkAAgNWAUoAAgNdAUsAAgNXAUwAAgNYAU0AAgNZAU4AAgNaAU8AAgNbAVAAAgNcAVEAAgNdAVIAAgNeAVMAAgNfAVQAAgOFAVUAAgC6A5QAAgMhAVYAAgObAVcAAgOcAVgAAgOdAVkAAwDEA54BWgACA58BWwACA6EBXAACA6IBXQACA6MBXgACA6QBXwACA6UBYAACA6YBYQACA6cBYgACA6gBYwACA6kBZAACA6oBZQACA6sBZgACA6wBZwACA60BaAACA64BaQACA68BagACA7ABawACA7EBbAACA7IBbQACA7MBbgACA7QBbwACA7UBcAACA7YBcQACA7cBcgACA7gBcwACA7kBdAACA7oBdQACA7wBdgACA70BdwACA74BeAACA78BeQACA8ABegACA8IBewACA8MBfAACA8QBfQACA8UBfgACA8YBfwACA8cBgAACA8gBgQACA8kBggACA8oBgwACA8sBhAACA8wBhQACA80BhgACA84BhwACA88BiAACA9ABiQACAzYBNwADBGQC3wJ/AAIC4AKAAAIC4QKBAAIC4gKCAAIC4wKDAAIC5AKEAAIC5QKFAAIC5gKGAAIC5wKHAAIC6AKIAAIC6QKJAAIC6gKKAAIC6wKLAAIC7AKMAAIC7QKNAAIC7gKOAAIC7wKPAAIC8AKQAAIC8QKRAAIC8gKSAAIC8wKTAAIC9AKUAAIC9QKVAAIC9gKWAAIC9wKXAAIC+AKYAAIC+QKZAAIC+gKaAAIDCQKbAAIDCgKcAAIDCwKdAAIDDAKeAAIDDQKfAAIDDgKgAAIDDwKhAAIDEAKiAAIDEQKjAAIDEgKkAAIDEwKlAAIDFAKmAAIDFQKnAAIDFgKoAAIDFwKpAAIDGAKqAAIDGQKrAAIDGgKsAAIDGwKtAAIDHAKuAAIDHQKvAAIDHgKwAAIDHwKxAAIDIAKyAAIDIQKzAAIDJAK0AAMB3wHmAzMAAgHwA0UAAgNLArUAAgNMArYAAgNNArcAAgNOArgAAgNPArkAAgNQAroAAgNRArsAAgNSArwAAgNTAr0AAgRlA2AAAgOCAr4AAgJCA5QAAgObAr8AAgOcAsAAAgOdAsEAAwJMA54CwgACA58CwwACA6ACxAACA6ECxQACA6ICxgACA7wCxwACA70CyAACA74CyQACA78CygACA8ACywACA8ICzAACA8MCzQACA8QCzgACA8UCzwACA8cC0AACA8gC0QACA8kC0gACA8oC0wACA8sC1AACA8wC1QACA80C1gACA84C1wACA88C2AACA9AC2QACBNwE5AACBN0E7AACBN4E8QACBOIE4QACBX4FlgADBX8FlwWbAAIFggWfAAIFgwWgAAIFhAWiAAIFiAWYAAMFiQWZBaQAAgWOBacAAgWPBagABwXyBdQGEAYGBfwF3gXKAAcF8wXVBhEGBwX9Bd8FywAHBfQF1gYSBggF/gXgBcwABwX1BdcGEwYJBf8F4QXNAAcF9gXYBhQGCgYABeIFzgAHBfcF2QYVBgsGAQXjBc8ABwX4BdoGFgYMBgIF5AXQAAcF+QXbBhcGDQYDBeUF0QAHBfoF3AYYBg4GBAXmBdIABwX7Bd0GGQYPBgUF5wXTAAIFwAXoAAIFwQXpAAIFwgXqAAIFwwXrAAIFxAXsAAIFxQXtAAIFxgXuAAIFxwXvAAIFyAXwAAIFyQXxAAEFygABBcsAAQXMAAEFzQABBc4AAQXPAAEF0AABBdEAAQXSAAEF0wADBjsGOQY3AAIGGgY6AAIGYgZcAAIGYwZdAAIGZAZeAAIGZQZfAAIHJQdVAAIHJwdXAAIAKgAEAB8AAAApACkAHAAvAEYAHQBJAFEANQBYAGkAPgBuAG4AUAB3AIQAUQCpAKkAXwC4ALgAYAC/AN4AYQDgAOQAgQDmAPUAhgGKAaUAlgG0AcwAsgHPAc8AywHeAd4AzAHvAe8AzQH2Af4AzgIMAgwA1wIuAi4A2AJAAkAA2QJIAk8A2gJpAm0A4gJvAnIA5wJ0An0A6wRsBGwA9QR4BHgA9gSCBIIA9wSpBKkA+AUJBQkA+QUMBQwA+gUSBRQA+wUcBRwA/gUfBR8A/wUpBSoBAAXABdMBAgXeBfEBFgYmBiYBKgY0BjQBKwZSBlUBLAcGBwYBMAcJBwkBMQAGAAAABAAOACAAbgCAAAMAAAABACYAAQA+AAEAAAArAAMAAAABABQAAgAcACwAAQAAACsAAQACAd4B7wACAAIG/gcAAAAHAgcJAAMAAQAPBt8G4wblBucG6gbsBu0G7wbwBvIG9gb6BvsG/Ab9AAMAAQB+AAEAfgAAAAEAAAArAAMAAQASAAEAbAAAAAEAAAArAAIABAAEAYkAAARmBQUBhgW6BbsCJgW+Bb8CKAAGAAAAAgAKABwAAwAAAAEANAABACQAAQAAACsAAwABABIAAQAiAAAAAQAAACsAAgACBwoHJwAAB2YHbQAeAAIABgbfBuoAAAbsBu8ADAbyBvwAEAcGBwYAGwcIBwkAHAdeB2UAHgAEAAAAAQAIAAEBKgAPACQAPgBIAFIAZABuAHgAkgCsAMYA0ADaAOwA9gEQAAMACAAOABQG4AACBuUG4QACBucG4gACBvYAAQAEBuQAAgb2AAEABAbmAAIG9gACAAYADAboAAIG4wbpAAIG9gABAAQG7gACBuMAAQAEBvEAAgbnAAMACAAOABQG8wACBt8G9AACBucG9QACBvYAAwAIAA4AFAb3AAIG3wb4AAIG5Qb5AAIG5wADAAgADgAUBwsAAgcQBwwAAgcSBw0AAgceAAEABAcPAAIHHgABAAQHEQACBx4AAgAGAAwHEwACBw4HFAACBx4AAQAEBxgAAgcOAAMACAAOABQHGwACBwoHHAACBxIHHQACBx4AAwAIAA4AFAcfAAIHCgcgAAIHEAchAAIHEgABAA8G3wbjBuUG5wbtBvAG8gb2BwoHDgcQBxIHFwcaBx4ABAAAAAEACAABAJYABAAOADAAUgB0AAQACgAQABYAHAdjAAIG5QdiAAIG5wdlAAIG8gdkAAIG+gAEAAoAEAAWABwHXwACBuUHXgACBucHYQACBvIHYAACBvoABAAKABAAFgAcB2sAAgcQB2oAAgcSB20AAgcaB2wAAgciAAQACgAQABYAHAdnAAIHEAdmAAIHEgdpAAIHGgdoAAIHIgABAAQG7AbvBxYHGQAEAAAAAQAIAAEAHgACAAoAFAABAAQA9QACAGgAAQAEAn4AAgHvAAEAAgBaAeAABgAAAAIACgAkAAMAAQAUAAEALgABABQAAQAAACsAAQABAfYAAwABABoAAQAUAAEAGgABAAAALAABAAEGJgABAAEAbQABAAAAAQAIAAIADgAEALoAxAJCAkwAAQAEALgAwwJAAksAAQAAAAEACAABAAYACAABAAEB3gABAAAAAQAIAAIANAAXBNwE3QTeBX0FfgV/BYAFgQWCBYMFhAWFBYYFhwWIBYkFigWLBYwFjQWOBY8FkAABABcEbAR4BIIFCAUJBQwFEAURBRIFEwUUBRYFGAUaBRwFHwUkBSUFJgUnBSkFKgU1AAEAAAABAAgAAQAGAIoAAQABBQoAAQAAAAEACAACABAABQWVBZYFlwWYBZkAAQAFBQcFCQUMBRwFHwABAAAAAQAIAAIACgACBOIFkwABAAIEqQVJAAEAAAABAAgAAgAQAAUE3wTgBOEFkQWSAAEABQScBJ8EqQU8BT8AAQAAAAEACAABANAAMgABAAAAAQAIAAEAwgAUAAEAAAABAAgAAQC0AFAAAQAAAAEACAABAKYAPAABAAAAAQAIAAEABv/mAAEAAQY0AAEAAAABAAgAAQCEAEYABgAAAAIACgAiAAMAAQASAAEANAAAAAEAAAAsAAEAAQYaAAMAAQASAAEAHAAAAAEAAAAsAAIAAQX8BgUAAAACAAEGBgYPAAAABgAAAAIACgAkAAMAAQAsAAEAEgAAAAEAAAAsAAEAAgAEAYoAAwABABIAAQAcAAAAAQAAACwAAgABBcAFyQAAAAEAAgCEAgwABAAAAAEACAABABQAAQAIAAEABAbYAAMCDAYuAAEAAQB5AAEAAAABAAgAAQAG//YAAgABBcoF0wAAAAEAAAABAAgAAQAG/+IAAgABBd4F8QAAAAEAAAABAAgAAQAGAB4AAgABBcAF0wAAAAEAAAABAAgAAQAGAAoAAgACBcAFyQAABd4F5wAKAAEAAAABAAgAAgIUAQcC3wLgAuEC4gLjAuQC5QLmAucC6ALpAuoC6wLsAu0C7gLvAvAC8QLyAvMC9AL1AvYC9wL4AvkC+gL7AvwC/QL+Av8DAAMBAwIDAwMJAwQDBQMGAwcDCAMJAwoDCwMMAw0DDgMPAxADEQMSAxMDFAMVAxYDFwMYAxkDGgMbAxwDHQMeAx8DIAMiAyMDJAMlAyYDJwMoAykDKgMrAywDLQMuAy8DMAMxAzIDMwNBAzUDNwM4AzkDOgM7AzwDPQM+Az8DQANCA0MDRANFA0YDRwNIA0kDSwNRA0wDTQNOA08DUANRA1IDUwNUA1UDVgNdA1cDWANZA1oDWwNcA10DXgNfA2ADYQNiA2MDZANlA2YDZwNoA2kDagNrA2wDbQNuA28DcANxA3IDcwN0A3UDdgN3A3gDeQN6A3sDfAN9A34DfwOAA4EDggODA4QDhQOGA4cDiAOJA4oDiwOMA40DjgOPA5ADkQOSA5MDlAOVA5YDlwOYA5kDmgMhA5sDnAOdA54DnwOhA6IDowOkA6UDpgOnA6gDqQOqA6sDrAOtA64DrwOwA7EDsgOzA7QDtQO2A7cDuAO5A7oDuwO8A70DvgO/A8ADwQPCA8MDxAPFA8YDxwPIA8kDygPLA8wDzQPOA88D0AM2BmAGYQZmBmcGaAZpBnAGYgZjBmQGZQZqBmsGbAZtBm4GbwbeB1UHVgdXAAIABwAEAPUAAAYrBiwA8gYuBjIA9AZSBlsA+QbLBssBAwcGBwcBBAcJBwkBBgABAAAAAQAIAAICFAEHAt8C4ALhAuIC4wLkAuUC5gLnAugC6QLqAusC7ALtAu4C7wLwAvEC8gLzAvQC9QL2AvcC+AL5AvoC+wL8Av0C/gL/AwADAQMCAwMDBAMFAwYDBwMIAwkDCgMLAwwDDQMOAw8DEAMRAxIDEwMUAxUDFgMXAxgDGQMaAxsDHAMdAx4DHwMgAyEDIgMjAyQDJQMmAycDKAMpAyoDKwMsAy0DLgMvAzADMQMyAzMDNAM1AzcDOAM5AzoDOwM8Az0DPgM/A0ADQQNCA0MDRANFA0YDRwNIA0kDSgNLA0wDTQNOA08DUANRA1IDUwNUA1UDVgNXA1gDWQNaA1sDXANdA14DXwNgA2EDYgNjA2QDZQNmA2cDaANpA2oDawNsA20DbgNvA3ADcQNyA3MDdAN1A3YDdwN4A3kDegN7A3wDfQN+A38DgAOBA4IDgwOEA4UDhgOHA4gDiQOKA4sDjAONA44DjwOQA5EDkgOTA5QDlQOWA5cDmAOZA5oDmwOcA50DngOfA6ADoQOiA6MDpAOlA6YDpwOoA6kDqgOrA6wDrQOuA68DsAOxA7IDswO0A7UDtgO3A7gDuQO6A7sDvAO9A74DvwPAA8EDwgPDA8QDxQPGA8cDyAPJA8oDywPMA80DzgPPA9ADNgZgBmEGZgZnBmgGaQZwBmIGYwZkBmUGagZrBmwGbQZuBm8G3gdVB1YHVwACAAoBigHvAAAB8QICAGYCBAJGAHgCSAJ+ALsGKwYsAPIGLgYyAPQGUgZbAPkGywbLAQMHBgcHAQQHCQcJAQYAAQAAAAEACAACAIAAPQY2BjcGOAY6BjkGQgZDBkQGRQZGBkcGTwZQBlEGXAZdBl4GXwa5BroGuwa8BtwHCgcLBwwHDQcOBw8HEAcRBxIHEwcUBxUHFgcXBxgHGQcaBxsHHAcdBx4HHwcgByEHIgcjByQHJQcmBycHZgdnB2gHaQdqB2sHbAdtAAIAEQYlBicAAAY0BjQAAwY7BkEABAZIBkkACwZMBkwADQZSBlUADgavBq8AEgaxBrEAEwazBrMAFAa1BrUAFQbKBsoAFgbfBuoAFwbsBu8AIwbyBvwAJwcGBwYAMgcIBwkAMwdeB2UANQAEAAAAAQAIAAEAEgABAAgAAQAEAtoAAgHYAAEAAQDAAAQAAAABAAgAAQAaAAEACAACAAYADALbAAIB3gLcAAIB9gABAAEBzwABAAAAAQAIAAIDlgHIAPYA9wD4APkA+gD7APwA/QD+AP8BAAEBAQIBAwEEAQUBBgEHAQgBCQEKAQsBDAENAQ4BDwEQAREBEgETARQBFQEWARcBGAEZARoBGwEcAR0BHgEfASABIQEiASMBJAElASYBJwEoASkBKgErASwBLQEuAS8BMAExATIBMwE0ATUBNgE4ATkBOgE7ATwBPQE+AT8BQAFBAUIBQwFEAUUBRgFHAUgBSQFKAUsBTAFNAU4BTwFQAVEBUgFTAVQBVQFWAVcBWAFZAVoBWwFcAV0BXgFfAWABYQFiAWMBZAFlAWYBZwFoAWkBagFrAWwBbQFuAW8BcAFxAXIBcwF0AXUBdgF3AXgBeQF6AXsBfAF9AX4BfwGAAYEBggGDAYQBhQGGAYcBiAGJATcCfwKAAoECggKDAoQChQKGAocCiAKJAooCiwKMAo0CjgKPApACkQKSApMClAKVApYClwKYApkCmgKbApwCnQKeAp8CoAKhAqICowKkAqUCpgKnAqgCqQKqAqsCrAKtAq4CrwKwArECsgKzArQCtQK2ArcCuAK5AroCuwK8Ar0CvgK/AsACwQLCAsMCxALFAsYCxwLIAskCygLLAswCzQLOAs8C0ALRAtIC0wLUAtUC1gLXAtgC2QLdAt4D0QPSA9MD1APVA9YD1wPYA9kD2gPbA9wD3QPeA98D4APhA+ID4wPkA+UD5gPnA+gD6QPqA+sD7APtA+4D7wPwA/ED8gPzA/QD9QP2A/cD+AP5A/oD+wP8A/0D/gP/BAAEAQQCBAMEBAQFBAYEBwQIBAkECgQLBAwEDQQOBA8EEAQRBBIEEwQUBBUEFgQXBBgEGQQaBBsEHAQdBB4EHwQgBCEEIgQjBCQEJQQmBCcEKAQpBCoEKwQsBC0ELgQvBDAEMQQyBDMENAQ1BDYENwQ4BDkEOgQ7BDwEPQQ+BD8EQARBBEIEQwREBEUERgRHBEgESQRKBEsETARNBE4ETwRQBFEEUgRTBFQEVQRWBFcEWARZBFoEWwRcBF0EXgRfBGAEYQRiBGME4wTkBOUE5gTnBOgE6QTrBOoE7ATtBO4E7wTwBPEE8gTzBPQE9QT2BPcE+AT5BPoE+wT8BP0E/gT/BQAFAQUCBQMFBAUFBZoFmwWcBZ0FngWfBaAFogWhBaMFpAWlBaYFpwWoBakFqgWrBawFrQWuBa8FsAWxBbIFswW0BbUFtgW3BbgFuQbdAAIAPQAEAB8AAAApACkAHAAvAEYAHQBJAFEANQBYAGkAPgBuAG4AUAB3AIMAUQCpAKkAXgC/AN4AXwDgAOQAfwDmAPUAhAGKAaUAlAG0AcwAsAHPAc8AyQH2Af4AygIuAi4A0wJIAk8A1AJpAm0A3AJvAnIA4QJ0An0A5QLbAtwA7wLfAvoA8QMJAyEBDQMkAywBJgMzAzsBLwM9A0YBOANRA1EBQgNUA18BQwOFA4UBTwObA7oBUAO8A8ABcAPCA9ABdQRmBGYBhARsBG8BhQRyBHUBiQR4BHgBjQR9BH0BjgR/BIIBjwSJBI0BkwSTBJMBmASYBJgBmQSqBKoBmgS8BL8BmwTFBMYBnwTLBM0BoQTQBNABpATWBNYBpQTYBNgBpgUGBQYBpwUMBQ8BqAUSBRUBrAUdBR0BsAUfBSEBsQUpBS0BtAU4BTgBuQVdBWIBugVmBWcBwAVsBW4BwgVxBXEBxQV5BXkBxgbYBtgBxwABAAAAAQAIAAIAWAApAd8B8AY7BwoHCwcMBw0HDgcPBxAHEQcSBxMHFAcVBxYHFwcYBxkHGgcbBxwHHQceBx8HIAchByIHIwckByUHJgcnB2YHZwdoB2kHagdrB2wHbQACAAkB3gHeAAAB7wHvAAEGJgYmAAIG3wbqAAMG7AbvAA8G8gb8ABMHBgcGAB4HCAcJAB8HXgdlACEAAQAAAAEACAACACQADwRkBGUEZARlBfwF/QX+Bf8GAAYBBgIGAwYEBgUGOQABAA8ABACEAYoCDAYGBgcGCAYJBgoGCwYMBg0GDgYPBiYAAA==) format("truetype")}@font-face{font-weight:normal;font-family:"tick42-icons";font-style:normal;src:url(data:font/ttf;base64,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YGAGCAcGqgJK/bYCgP1KJhsaARscJQK2JhsaARscJQAAAQAAAAEAAH2fuHdfDzz1AAsEAAAAAADhVnMIAAAAAOFWcwj//f+9BQADwwAAAAgAAgAAAAAAAAABAAADwP/AAAAFJP/9//0FAAABAAAAAAAAAAAAAAAAAAAA9wQAAAAAAAAAAAAAAAIAAAAEAAAABAAAAAO2//8ESQAAA24AAANuAAACkf//A24AAAO2//8CSQAABAAAAAO2//8CAAAAAmYAAALNAAACHwAAAmYAAAJmAAACqwAAAeEAAAOFAAADhQAAA24AAAQAAAAEkf//AyQAAANWAAACZgAAAOEAAAJIAAADrgAAAysAAAOaAAAEAAAAA24AAAQAAAAEAAAABAAAAAQAAAAEAP/9A24AAAQAAAADWAAAAyQAAANuAAADbgAAA24AAAQAAAADtgAAAbYAAAQAAAAEAAAAA24AAANuAAADbgAAA24AAAQAAAAEAAAABAAAAAQAAAAEAQAABAAAAAQAAAAEAAAAApH//wQA//0EAAAABAD//QQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAAA24AAAO2AAAEAAAAA7b//wMkAAADJAAAAyQAAAQAAAAEAAAAA24AAANuAAADtgAAA7YAAAMkAAADtv//BAAAAAQAAAADbgAABEkAAALbAAADtv//A7b//wQAAAACSQAAAkkAAAFuAAABbgAAAtsAAAQAAAAC2wAABAAAAAO2AAADbgAAA24AAAO2AAADtgAAA7YAAANHAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAADJAAAAtsAAAMkAAADbgAABAAAAANuAAADtv//A7b//wJJAAACSQAAAkkAAAQAAAAEAAAABAAAAAQAAAAESQAABEkAAAQAAAAEAAAAA24AAANuAAACSQAAAkkAAAKRAAACkQAAAW4AAAFuAAACkQAAApEAAARJAAADbgAAA7b//wO2//8EAAAAA24AAAQAAAADtv//BEkAAAO2AAAESQAABAAAAAMkAAACSQAAA7b//wJJAAABbgAAAW4AAAKR//8DJAAAA7b//wKR//8DJAAAANsAAANuAAADbgAAA24AAANuAAACSQAAAkkAAANuAAADtgAAA7YAAAQAAAAEAAAAA24AAANuAAABtgAAAbYAAAQAAAAEAAAABAAAAAUkAAADbgAAA24AAANuAAADbgAAA24AAANuAAADbgAAA24AAANuAAADbgAAA24AAANuAAADbgAABJEAAASRAAAEkQAAA24AAASR//8Ekf//BJH//wSR//8Ekf//BJEAAAQAAAADbgAAA24AAANuAAADbgAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAO2//8DbgAABAAAAAQAAAAEkf//BAAAAAQAAAAAAAAAAAoAFAAeAQgBbAHkAk4DIgP+BEIIOAj2CTQJjAosCkoKZAqCCqQK0Ar8CyoLZguaC9IMNAzEDPINnA4gDl4OfA6wDvoPGg84D2wP0hAGEFQQhBD0EfgSOBJ8Ep4TVhO4FBoUYBXAFioWbBaqFzAXdBfiGFAY1hmWGpYcAhx2HQIdih64IAQgZiFGIhQjcCRuJKwk3iU4JbwmBCYeJjgmuCc6J9IoKihsKJAo0ikCKbIqQiq2KxYr0Cw+LIws+i2gLeguWi6SLxgvoC/8MCAwRjBqMI4wvjDuMRwxTDGIMcQyADI8MqIzGjNgM8o0HjR6NMg1fjbONx43Xjd8OFg4zjlcOdQ6SjrEOwY7SDtyO+Q8VDywPcA+Aj5EPmg+jD8GP5A/+kBUQLRBFEFcQcxCZELCQxRDZkO4RApEOERmRJREwkUkRXJF8EZuRzJHXEe4SAxIiEjQSURJrkniSppLiEv+TFRMlE0ITZpOFk5gTrhPEE9QT5xP7FBEUPZRyFH+UnxS/FOWVDBUyFViVY5VulXoVhZWXFbcV2pYSljeWWxZ4FpIWuJbjlwGXLZdEF2SXeBejF8OX7JgXGB6YLphSmG2YlJi7GNaY/xkdmTkZXRmKGbCZ3poHmiSaWBqSGsga6Zr1Gv4bERspm0SAAEAAAD3As4ADwAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAOAK4AAQAAAAAAAQAMAAAAAQAAAAAAAgAHAI0AAQAAAAAAAwAMAEUAAQAAAAAABAAMAKIAAQAAAAAABQALACQAAQAAAAAABgAMAGkAAQAAAAAACgAaAMYAAwABBAkAAQAYAAwAAwABBAkAAgAOAJQAAwABBAkAAwAYAFEAAwABBAkABAAYAK4AAwABBAkABQAWAC8AAwABBAkABgAYAHUAAwABBAkACgA0AOB0aWNrNDItaWNvbnMAdABpAGMAawA0ADIALQBpAGMAbwBuAHNWZXJzaW9uIDEuMABWAGUAcgBzAGkAbwBuACAAMQAuADB0aWNrNDItaWNvbnMAdABpAGMAawA0ADIALQBpAGMAbwBuAHN0aWNrNDItaWNvbnMAdABpAGMAawA0ADIALQBpAGMAbwBuAHNSZWd1bGFyAFIAZQBnAHUAbABhAHJ0aWNrNDItaWNvbnMAdABpAGMAawA0ADIALQBpAGMAbwBuAHNGb250IGdlbmVyYXRlZCBieSBJY29Nb29uLgBGAG8AbgB0ACAAZwBlAG4AZQByAGEAdABlAGQAIABiAHkAIABJAGMAbwBNAG8AbwBuAC4AAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA) format("truetype")}[class^="icon-"],[class*=" icon-"]{font-weight:normal;font-family:"tick42-icons";font-style:normal;font-variant:normal;line-height:1;text-transform:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.tick42-custom-icon i{color:var(--t42-link-color)}.tick42-custom-icon img{display:block}.tick42-custom-icon.disabled i,.tick42-custom-icon:disabled i{color:var(--t42-content-color-disabled)}i.disabled,.disabled i{color:var(--t42-content-color-disabled)}.icon-size-12 i{font-size:0.75rem}.icon-size-12 i,.icon-size-12 img{width:0.75rem;height:0.75rem}.icon-size-14 i{font-size:0.875rem}.icon-size-14 i,.icon-size-14 img{width:0.875rem;height:0.875rem}.icon-size-24 i{font-size:1.5rem}.icon-size-24 i,.icon-size-24 img{width:1.5rem;height:1.5rem}.icon-size-16 i,.icon-size-16 img{width:1rem;height:1rem}.icon-size-16 i{font-size:1rem}.icon-size-32 i,.icon-size-32 img{width:2rem;height:2rem}.icon-size-32 i{font-size:2rem}.icon-size-48 i,.icon-size-48 img{width:3rem;height:3rem}.icon-size-48 i{font-size:3rem}.icon-size-64 i,.icon-size-64 img{width:4rem;height:4rem}.icon-size-64 i{font-size:4rem}.icon-size-80 i,.icon-size-80 img{width:5rem;height:5rem}.icon-size-80 i{font-size:5rem}.icon-size-96 i,.icon-size-96 img{width:6rem;height:6rem}.icon-size-96 i{font-size:6rem}.icon-size-112 i,.icon-size-112 img{width:7rem;height:7rem}.icon-size-112 i{font-size:7rem}.icon-size-128 i,.icon-size-128 img{width:8rem;height:8rem}.icon-size-128 i{font-size:8rem}.icon-primary i::before{color:#007be5}.icon-secondary i::before{color:#616161}.icon-success i::before{color:#43a047}.icon-info i::before{color:#469eb9}.icon-warning i::before{color:#f9a825}.icon-danger i::before{color:#ff511f}.icon-light i::before{color:#616161}.icon-dark i::before{color:#616161}.icon-dev-tools::before{content:"\e901"}.icon-interop::before{content:"\e900"}.icon-mail::before{content:"\e800"}.icon-attention::before{content:"\e801"}.icon-print::before{content:"\e802"}.icon-picture::before{content:"\e803"}.icon-thumbs-up::before{content:"\e804"}.icon-thumbs-down::before{content:"\e805"}.icon-lock::before{content:"\e806"}.icon-globe::before{content:"\e807"}.icon-calendar::before{content:"\e808"}.icon-location::before{content:"\e809"}.icon-briefcase::before{content:"\e80a"}.icon-export::before{content:"\e80b"}.icon-play::before{content:"\e80c"}.icon-stop::before{content:"\e80d"}.icon-record::before{content:"\e80e"}.icon-pause::before{content:"\e80f"}.icon-to-end::before{content:"\e810"}.icon-to-start::before{content:"\e811"}.icon-check::before{content:"\e812"}.icon-cancel::before{content:"\e813"}.icon-fast-forward::before{content:"\e814"}.icon-fast-backward::before{content:"\e815"}.icon-attention-circled::before{content:"\e816"}.icon-bell::before{content:"\e817"}.icon-chart-bar::before{content:"\e818"}.icon-phone::before{content:"\e819"}.icon-doc-add::before{content:"\e81a"}.icon-layout::before{content:"\e81b"}.icon-dot::before{content:"\e81c"}.icon-dot-2::before{content:"\e81d"}.icon-dot-3::before{content:"\e81e"}.icon-resize-full-1::before{content:"\e81f"}.icon-resize-small-1::before{content:"\e820"}.icon-checkbox::before{content:"\e821"}.icon-cancel-circled::before{content:"\e822"}.icon-03-context-viewer::before{content:"\e823"}.icon-volume-off-1::before{content:"\e824"}.icon-volume::before{content:"\e825"}.icon-headphones-1::before{content:"\e826"}.icon-performance-report::before{content:"\e827"}.icon-pause-1::before{content:"\e828"}.icon-volume-up-1::before{content:"\e829"}.icon-volume-down-1::before{content:"\e82a"}.icon-trash-empty::before{content:"\e839"}.icon-resize-small::before{content:"\e83b"}.icon-resize-full::before{content:"\e83c"}.icon-doc::before{content:"\e83d"}.icon-cog::before{content:"\e83e"}.icon-wrench::before{content:"\e83f"}.icon-resize-vertical::before{content:"\e840"}.icon-resize-horizontal::before{content:"\e841"}.icon-edit::before{content:"\e842"}.icon-pencil-1::before{content:"\e843"}.icon-cw-2::before{content:"\e844"}.icon-ccw-1::before{content:"\e845"}.icon-arrows-cw-1::before{content:"\e847"}.icon-th-large::before{content:"\e848"}.icon-th::before{content:"\e849"}.icon-spin5::before{content:"\e84a"}.icon-spin6::before{content:"\e84b"}.icon-spin4::before{content:"\e84c"}.icon-spin3::before{content:"\e84d"}.icon-spin2::before{content:"\e84e"}.icon-spin1::before{content:"\e84f"}.icon-pin::before{content:"\e850"}.icon-trading-controls::before{content:"\e856"}.icon-icon-coverage::before{content:"\e857"}.icon-taxes::before{content:"\e858"}.icon-credit::before{content:"\e859"}.icon-checkbox-checked::before{content:"\e85a"}.icon-checkbox-indeterminate::before{content:"\e85b"}.icon-radio::before{content:"\e85c"}.icon-radio-choose::before{content:"\e85d"}.icon-arrow-up-down::before{content:"\e85e"}.icon-arrow-double-left::before{content:"\e85f"}.icon-arrow-double-right::before{content:"\e860"}.icon-floppy::before{content:"\e861"}.icon-logout::before{content:"\e862"}.icon-mail-1::before{content:"\e864"}.icon-search-1::before{content:"\e865"}.icon-plus-1::before{content:"\e866"}.icon-minus-1::before{content:"\e867"}.icon-cancel-1::before{content:"\e868"}.icon-ok::before{content:"\e869"}.icon-th-list::before{content:"\e86a"}.icon-help-circled::before{content:"\e86b"}.icon-info-circled::before{content:"\e86c"}.icon-home::before{content:"\e86d"}.icon-link-1::before{content:"\e86e"}.icon-attach-1::before{content:"\e86f"}.icon-lock-open-1::before{content:"\e870"}.icon-eye::before{content:"\e871"}.icon-eye-off::before{content:"\e872"}.icon-tag::before{content:"\e873"}.icon-tags::before{content:"\e874"}.icon-bookmark::before{content:"\e875"}.icon-download-1::before{content:"\e876"}.icon-upload-1::before{content:"\e877"}.icon-forward-1::before{content:"\e878"}.icon-down-dir::before{content:"\e879"}.icon-up-dir::before{content:"\e87a"}.icon-left-dir::before{content:"\e87b"}.icon-right-dir::before{content:"\e87c"}.icon-left-open-1::before{content:"\e87d"}.icon-down-open-1::before{content:"\e87e"}.icon-right-open-1::before{content:"\e87f"}.icon-up-open-1::before{content:"\e880"}.icon-down-big::before{content:"\e881"}.icon-left-big::before{content:"\e882"}.icon-right-big::before{content:"\e883"}.icon-up-big::before{content:"\e884"}.icon-asterisk::before{content:"\e885"}.icon-check-1::before{content:"\e886"}.icon-tick42-icon-monochrome::before{content:"\e887"}.icon-task-manager::before{content:"\e888"}.icon-context-viewer::before{content:"\e889"}.icon-help-2::before{content:"\e88a"}.icon-star-empty-1::before{content:"\e88b"}.icon-star-full::before{content:"\e902"}.icon-move::before{content:"\f047"}.icon-link-ext::before{content:"\f08e"}.icon-check-empty::before{content:"\f096"}.icon-bookmark-empty::before{content:"\f097"}.icon-filter::before{content:"\f0b0"}.icon-resize-full-alt::before{content:"\f0b2"}.icon-docs::before{content:"\f0c5"}.icon-menu-1::before{content:"\f0c9"}.icon-table::before{content:"\f0ce"}.icon-columns::before{content:"\f0db"}.icon-sort::before{content:"\f0dc"}.icon-sort-down::before{content:"\f0dd"}.icon-sort-up::before{content:"\f0de"}.icon-mail-alt::before{content:"\f0e0"}.icon-sitemap::before{content:"\f0e8"}.icon-paste::before{content:"\f0ea"}.icon-exchange::before{content:"\f0ec"}.icon-download-cloud::before{content:"\f0ed"}.icon-upload-cloud::before{content:"\f0ee"}.icon-suitcase-1::before{content:"\f0f2"}.icon-bell-alt::before{content:"\f0f3"}.icon-doc-text-1::before{content:"\f0f6"}.icon-plus-squared::before{content:"\f0fe"}.icon-angle-double-left::before{content:"\f100"}.icon-angle-double-right::before{content:"\f101"}.icon-angle-double-up::before{content:"\f102"}.icon-angle-double-down::before{content:"\f103"}.icon-angle-left::before{content:"\f104"}.icon-angle-right::before{content:"\f105"}.icon-angle-up::before{content:"\f106"}.icon-angle-down::before{content:"\f107"}.icon-laptop::before{content:"\f109"}.icon-circle-empty::before{content:"\f10c"}.icon-quote-left::before{content:"\f10d"}.icon-quote-right::before{content:"\f10e"}.icon-spinner::before{content:"\f110"}.icon-circle::before{content:"\f111"}.icon-reply-1::before{content:"\f112"}.icon-folder-empty::before{content:"\f114"}.icon-folder-open-empty::before{content:"\f115"}.icon-terminal::before{content:"\f120"}.icon-code::before{content:"\f121"}.icon-reply-all-1::before{content:"\f122"}.icon-direction::before{content:"\f124"}.icon-fork::before{content:"\f126"}.icon-unlink::before{content:"\f127"}.icon-help::before{content:"\f128"}.icon-info::before{content:"\f129"}.icon-attention-alt::before{content:"\f12a"}.icon-mic::before{content:"\f130"}.icon-mute::before{content:"\f131"}.icon-calendar-empty::before{content:"\f133"}.icon-lock-open-alt::before{content:"\f13e"}.icon-ellipsis::before{content:"\f141"}.icon-ellipsis-vert::before{content:"\f142"}.icon-minus-squared::before{content:"\f146"}.icon-ok-squared::before{content:"\f14a"}.icon-link-ext-alt::before{content:"\f14c"}.icon-expand-right::before{content:"\f152"}.icon-euro::before{content:"\f153"}.icon-dollar::before{content:"\f155"}.icon-doc-inv::before{content:"\f15b"}.icon-sort-name-up::before{content:"\f15d"}.icon-sort-name-down::before{content:"\f15e"}.icon-sort-alt-up::before{content:"\f160"}.icon-sort-alt-down::before{content:"\f161"}.icon-sort-number-up::before{content:"\f162"}.icon-sort-number-down::before{content:"\f163"}.icon-down::before{content:"\f175"}.icon-up::before{content:"\f176"}.icon-left::before{content:"\f177"}.icon-right::before{content:"\f178"}.icon-cube::before{content:"\f1b2"}.icon-cubes::before{content:"\f1b3"}.icon-database::before{content:"\f1c0"}.icon-file-pdf::before{content:"\f1c1"}.icon-file-word::before{content:"\f1c2"}.icon-file-excel::before{content:"\f1c3"}.icon-file-powerpoint::before{content:"\f1c4"}.icon-file-image::before{content:"\f1c5"}.icon-file-archive::before{content:"\f1c6"}.icon-file-audio::before{content:"\f1c7"}.icon-file-video::before{content:"\f1c8"}.icon-file-code::before{content:"\f1c9"}.icon-circle-thin::before{content:"\f1db"}.icon-sliders::before{content:"\f1de"}.icon-share::before{content:"\f1e0"}.icon-wifi::before{content:"\f1eb"}.icon-bell-off::before{content:"\f1f6"}.icon-bell-off-empty::before{content:"\f1f7"}.icon-copyright::before{content:"\f1f9"}.icon-chart-area::before{content:"\f1fe"}.icon-chart-line::before{content:"\f201"}.icon-toggle-off::before{content:"\f204"}.icon-toggle-on::before{content:"\f205"}.icon-user-plus::before{content:"\f234"}.icon-user-times::before{content:"\f235"}.icon-clone::before{content:"\f24d"}.icon-hourglass-o::before{content:"\f250"}.icon-hourglass-1::before{content:"\f251"}.icon-hourglass-2::before{content:"\f252"}.icon-hourglass-3::before{content:"\f253"}.icon-calendar-plus-o::before{content:"\f271"}.icon-calendar-minus-o::before{content:"\f272"}.icon-calendar-times-o::before{content:"\f273"}.icon-calendar-check-o::before{content:"\f274"}.icon-hashtag::before{content:"\f292"}.icon-low-vision::before{content:"\f2a8"}.icon-envelope-open-o::before{content:"\f2b7"}.icon-address-book-o::before{content:"\f2ba"}.icon-user-o::before{content:"\f2c0"}.icon-window-maximize::before{content:"\f2d0"}.icon-window-minimize::before{content:"\f2d1"}.icon-window-restore::before{content:"\f2d2"}.icon-window-close::before{content:"\f2d3"}.icon-window-close-o::before{content:"\f2d4"}.icon-app::before{content:"\e903"}.icon-download-arrow::before{content:"\e904"}.icon-logo::before{content:"\e905"}.icon-feedback::before{content:"\e906"}.icon-action::before{content:"\e907"}.icon-swimlane::before{content:"\e908"}div.ag-dnd-ghost{border-color:transparent;border-radius:0.25rem;color:var(--white);font-size:0.75rem;font-family:inherit;line-height:inherit;background-color:var(--primary);cursor:default}div .ag-dnd-ghost-icon{display:flex;float:none;padding:0 0.25rem 0 0}div .ag-dnd-ghost-icon .ag-icon{background-color:var(--white)}.ag-tick42{padding-top:0}.ag-tick42 a{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border;border-bottom:0.063rem dashed var(--dark);color:var(--t42-content-color)}.ag-tick42 a:hover{text-decoration:none}.ag-tick42 .ag-filter-body{margin:0}.ag-tick42 input{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border;padding:0 0.5rem;border:var(--t42-border);color:var(--t42-content-color);line-height:2rem;background-color:var(--t42-input-bg)}.ag-tick42 input:focus{border-color:var(--primary);outline:0}.ag-tick42 input.ag-column-name-filter{margin-left:0.5rem}.ag-tick42 .ag-input-wrapper{padding:0.25rem}.ag-tick42 .ag-input-wrapper.ag-checkbox-input-wrapper{padding:0}.ag-tick42 .ag-cell-wrapper.ag-row-group{align-items:center}.ag-tick42 .ag-cell{padding:0 0.25rem;border-bottom:var(--t42-border);line-height:1.875rem;white-space:nowrap;text-overflow:ellipsis}.ag-tick42 .ag-cell .btn,.ag-tick42 .ag-cell .btn-sm,.ag-tick42 .ag-cell .btn-group-sm>.btn,.ag-tick42 .ag-cell .btn-lg,.ag-tick42 .ag-cell .btn-group-lg>.btn{line-height:1.25rem}.ag-tick42 .ag-cell .btn-icon i{position:relative;top:0.0625rem}.ag-tick42 .ag-cell:focus{outline:1px solid var(--primary)}.ag-tick42 .ag-cell .dropdown-toggle{width:20px;height:20px;margin-top:-3px;padding:0;border:0;line-height:22px}.ag-tick42 .ag-cell .dropdown-toggle::after{background-color:transparent;content:""}.ag-tick42 .ag-row::before{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:width;position:absolute;top:0;bottom:0;left:0;z-index:1;width:0;background-color:var(--primary);content:""}.ag-tick42 .ag-row.ag-row-selected{color:var(--t42-link-color);background-color:var(--t42-color-opacity-10)}.ag-tick42 .ag-row.ag-row-selected .ag-icon{color:var(--t42-link-color)}.ag-tick42 .ag-pinned-left-header,.ag-tick42 .ag-pinned-left-cols-container,.ag-tick42 .ag-pinned-right-header,.ag-tick42 .ag-pinned-right-cols-container{background-color:Rgb(var(--t42-bg-mid))}.ag-tick42 .ag-pinned-left-cols-container .ag-row-selected::before,.ag-tick42 .ag-pinned-left-cols-container.ag-hidden+.ag-center-cols-clipper .ag-row-selected::before{width:2px}.ag-tick42 .ag-row-hover{background-color:var(--t42-color-opacity-10)}.ag-tick42 .ag-row-hover .ag-cell{color:var(--t42-link-color)}.ag-tick42 .ag-row-hover .ag-loading .ag-icon-loading::after{background:Rgb(var(--t42-bg-light))}.ag-tick42 .ag-row-hover a{border-bottom-color:var(--t42-content-color);color:var(--t42-link-color)}.ag-tick42 .ag-row-hover a:hover{border-bottom-style:solid}.ag-tick42 .ag-header-row:last-of-type{border-bottom:var(--t42-border)}.ag-tick42 .ag-header-cell,.ag-tick42 .ag-header-group-cell{padding:0 0.25rem;border-top:var(--t42-border);border-left:var(--t42-border);color:Hsl(var(--t42-content-color-base), calc(var(--t42-content-color-l) - 20%))}.ag-tick42 .ag-header-cell:first-of-type,.ag-tick42 .ag-header-group-cell:first-of-type{border-left:0}.ag-tick42 .ag-header-cell .ag-header-cell-label,.ag-tick42 .ag-header-cell .ag-header-group-cell-label,.ag-tick42 .ag-header-group-cell .ag-header-cell-label,.ag-tick42 .ag-header-group-cell .ag-header-group-cell-label{font-weight:normal;font-size:83.3%;line-height:1.875rem;text-transform:uppercase}.ag-tick42 .ag-header-cell .ag-header-select-all,.ag-tick42 .ag-header-group-cell .ag-header-select-all{margin-right:0.5rem}.ag-tick42 .ag-header-cell-moving{background-color:Hsl(var(--t42-bg-light-base), calc(var(--t42-bg-light-l) + 5%))}.ag-tick42 .ag-cell-inline-editing{padding-top:0}.ag-tick42 .ag-cell-edit-input{border-top:0;border-bottom:0;border-radius:0}.ag-tick42 .ag-icon{font-family:inherit}.ag-tick42 .ag-icon::before{content:""}.ag-tick42 .ag-react-container .btn-icon{margin-bottom:0.125rem;padding:0 0.5rem}.ag-tick42 .ag-tabs-header{display:flex;height:1.875rem;border-bottom:var(--t42-border);border-bottom-width:0.063rem}.ag-tick42 .ag-tabs-header .ag-tab{display:flex;align-items:center;justify-content:center;width:1.875rem;height:1.875rem;color:var(--primary);cursor:pointer}.ag-tick42 .ag-tabs-header .ag-tab.ag-tab-selected{background-color:var(--primary)}.ag-tick42 .ag-tabs-header .ag-tab.ag-tab-selected .ag-icon{background-color:var(--white)}.ag-tick42 .ag-tabs-body{max-height:280px;overflow:auto}.ag-tick42 .ag-menu,.ag-tick42 .ag-tool-panel{z-index:1040;border:var(--t42-border);border-radius:0;overflow:initial;background-color:rgba(var(--t42-bg-light), 0.75);box-shadow:var(--t42-shadow);backdrop-filter:var(--backdrop-filter)}.ag-tick42 .ag-menu .ag-column-select-column,.ag-tick42 .ag-menu .ag-column-select-column-group,.ag-tick42 .ag-tool-panel .ag-column-select-column,.ag-tick42 .ag-tool-panel .ag-column-select-column-group{display:flex;align-items:center;margin-left:0;line-height:2rem;cursor:pointer}.ag-tick42 .ag-menu .ag-column-select-column .ag-column-select-checkbox:hover,.ag-tick42 .ag-menu .ag-column-select-column-group .ag-column-select-checkbox:hover,.ag-tick42 .ag-tool-panel .ag-column-select-column .ag-column-select-checkbox:hover,.ag-tick42 .ag-tool-panel .ag-column-select-column-group .ag-column-select-checkbox:hover{color:var(--t42-link-color)}.ag-tick42 .ag-menu .ag-column-select-column:hover,.ag-tick42 .ag-menu .ag-column-select-column-group:hover,.ag-tick42 .ag-tool-panel .ag-column-select-column:hover,.ag-tick42 .ag-tool-panel .ag-column-select-column-group:hover{color:Hsl(var(--t42-content--base), 100%);background-color:var(--t42-color-opacity-10)}.ag-tick42 .ag-menu .ag-column-select-header,.ag-tick42 .ag-tool-panel .ag-column-select-header{padding:0.5rem}.ag-tick42 .ag-menu .ag-column-select-column-label,.ag-tick42 .ag-tool-panel .ag-column-select-column-label{margin-left:0.25rem}.ag-tick42 .ag-tab-body{max-height:220px;overflow:auto}.ag-tick42 .ag-tab-body .ag-set-filter-list{height:9rem}.ag-tick42 .ag-tab-body input{border:var(--t42-border)}.ag-tick42 .ag-tab-body input:focus{border-color:var(--primary)}.ag-tick42 .ag-menu-option{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:color;line-height:2rem;cursor:pointer}.ag-tick42 .ag-menu-option .ag-menu-option-icon{color:var(--t42-content-color)}.ag-tick42 .ag-menu-option .ag-menu-option-icon,.ag-tick42 .ag-menu-option .ag-menu-option-popup-pointer{width:2rem;color:var(--t42-content-color);text-align:center}.ag-tick42 .ag-menu-option .ag-menu-option-icon.ag-menu-option-popup-pointer,.ag-tick42 .ag-menu-option .ag-menu-option-icon:hover,.ag-tick42 .ag-menu-option .ag-menu-option-popup-pointer.ag-menu-option-popup-pointer,.ag-tick42 .ag-menu-option .ag-menu-option-popup-pointer:hover{color:var(--t42-content-color)}.ag-tick42 .ag-menu-option .ag-menu-option-icon.ag-menu-option-popup-pointer .ag-icon,.ag-tick42 .ag-menu-option .ag-menu-option-icon:hover .ag-icon,.ag-tick42 .ag-menu-option .ag-menu-option-popup-pointer.ag-menu-option-popup-pointer .ag-icon,.ag-tick42 .ag-menu-option .ag-menu-option-popup-pointer:hover .ag-icon{color:var(--t42-content-color)}.ag-tick42 .ag-menu-option.ag-menu-option-active{color:var(--t42-link-color);background-color:var(--t42-color-opacity-10)}.ag-tick42 .ag-menu-option.ag-menu-option-active .ag-icon{color:var(--t42-content-color)}.ag-tick42 .ag-menu-separator{border-bottom:var(--t42-border);border-bottom-color:var(--t42-color-opacity-10)}.ag-tick42 .ag-menu-column-select-wrapper,.ag-tick42 .ag-primary-cols-list-panel{height:auto}.ag-tick42 .ag-tool-panel .ag-pivot-mode{padding-top:0.5rem}.ag-tick42 .ag-column-tool-panel-column{padding:0 0.25rem}.ag-tick42 .ag-column-tool-panel-column .ag-icon{margin:0 0.25rem}.ag-tick42 .ag-column-tool-panel-column-label,.ag-tick42 span.ag-column-tool-panel-column-group{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;padding-left:0.25rem}.ag-tick42 .ag-column-tool-panel-column-group .ag-icon{margin:0 0.25rem 0 0}.ag-tick42 .ag-root+.ag-tool-panel{box-shadow:none}.ag-tick42 .ag-row-group-leaf-indent{margin-left:24px}.ag-tick42 .ag-group-expanded,.ag-tick42 .ag-group-contracted{display:flex;align-items:center;min-width:0.75rem;height:100%;margin-right:0.5rem}.ag-tick42 .ag-group-value .ag-react-container{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;display:inline;font-size:87.5%}.ag-tick42 .ag-popup-editor{box-shadow:var(--t42-shadow)}.ag-tick42 .ag-rich-select{border:var(--t42-border);border-radius:0;overflow-y:auto;background-color:Rgb(var(--t42-bg-light), 1)}.ag-tick42 .ag-rich-select-row{padding-left:0.75rem}.ag-tick42 .ag-rich-select-row-selected{background:var(--t42-color-opacity-10)}.ag-tick42 .ag-rich-select-value{position:relative;height:2rem;padding-left:0.75rem;border-bottom:var(--t42-border);line-height:2rem}.ag-tick42 .ag-rich-select-value::before{position:absolute;top:0;bottom:0;left:0;width:3px;background-color:var(--primary);content:""}.ag-tick42 .icon-window-maximize::before,.ag-tick42 .icon-window-minimize::before,.ag-tick42 .icon-window-ok::before{font-size:0.813rem}.ag-tick42 .ag-column-drop{border-top:var(--t42-border)}.ag-tick42 .ag-column-drop.ag-column-drop-horizontal{display:flex;height:1.875rem}.ag-tick42 .ag-column-drop.ag-column-drop-horizontal div{display:flex;align-items:center}.ag-tick42 .ag-column-drop.ag-column-drop-horizontal div:first-of-type{margin-right:0.25rem}.ag-tick42 .ag-column-drop .ag-column-drop-empty-message{align-self:center}.ag-tick42 .ag-column-drop .ag-column-drop-cell{display:flex;height:1.125rem;margin:0.125rem 0.25rem;padding:0 0.125rem 0 0.25rem;border-radius:0.25rem;background-color:Rgb(var(--t42-bg-light))}.ag-tick42 .ag-column-drop .ag-column-drop-cell .ag-column-drop-cell-text{padding:0 0.25rem;line-height:1.125rem}.ag-tick42 .ag-column-drop.ag-column-drop-vertical div{justify-content:start}.ag-tick42 .ag-column-drop.ag-column-drop-vertical .ag-icon-group{margin:0 0.25rem}.ag-tick42 .ag-right-arrow{width:1.5rem;padding:0 0.25rem;overflow:hidden;text-indent:-999px;background-color:var(--t42-content-color);transform:rotate(-90deg);-webkit-mask-image:var(--t42-select-indicator)}.ag-tick42 .ag-right-arrow::before{position:absolute;text-indent:999px}.ag-tick42 .ag-group-checkbox{display:flex;align-items:center;width:1rem;height:100%;margin-right:0.5rem}.ag-tick42 .ag-group-checkbox .ag-icon{width:0.875rem;height:0.875rem}.ag-tick42 .ag-group-checkbox:empty{width:initial}.ag-tick42 .ag-ltr .ag-toolpanel-indent-1{padding-left:1rem}.ag-tick42 .ag-ltr .ag-toolpanel-indent-2{padding-left:2rem}.ag-tick42 .ag-ltr .ag-toolpanel-indent-3{padding-left:3rem}.ag-tick42 .ag-ltr .ag-row-group-indent-1{padding-left:calc(1 * 1.45rem)}.ag-tick42 .ag-ltr .ag-row-group-indent-2{padding-left:calc(2 * 1.45rem)}.ag-tick42 .ag-ltr .ag-row-group-indent-3{padding-left:calc(3 * 1.45rem)}.ag-menu .ag-filter-checkbox{min-width:2rem}.ag-menu .ag-icon-checkbox-checked::after{width:0.625rem;height:0.625rem}.ag-menu .ag-column-group-icons{width:1.5rem}.ag-menu .ag-labeled.ag-label-align-right>div{margin-left:0.25rem}.ag-filter-panel{width:100%}.loading-filter{background-color:rgba(var(--t42-bg-light), 0.75);backdrop-filter:var(--backdrop-filter)}#selectAllContainer,.ag-set-filter-item{display:flex;align-items:center;cursor:pointer}#selectAllContainer .ag-filter-value,#selectAllContainer .ag-set-filter-item-value,.ag-set-filter-item .ag-filter-value,.ag-set-filter-item .ag-set-filter-item-value{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}#selectAllContainer .ag-set-filter-item-value,.ag-set-filter-item .ag-set-filter-item-value{margin-left:0.25rem}.ag-filter-checkbox{justify-content:center;min-width:2rem;color:var(--primary)}.ag-set-filter-item:hover,.ag-filter-header-container:hover label{color:var(--t42-link-color);background-color:var(--t42-color-opacity-10)}.ag-set-filter-item:hover .ag-icon,.ag-filter-header-container:hover label .ag-icon{color:var(--t42-link-color)}.ag-input-text-wrapper{padding:0.25rem 0.25rem 0}.ag-primary-cols-header-panel{align-items:center;padding:0.25rem 0.25rem 0.25rem 0}.ag-primary-cols-header-panel div:nth-child(1){width:1.25rem}.ag-primary-cols-header-panel div:nth-child(2){width:1rem;margin-right:0.25rem}.ag-filter-toolpanel-header{display:flex}.ag-filter-toolpanel-header .ag-header-cell-text{padding:0 0.25rem}.ag-filter-condition{justify-content:space-evenly;padding:0.5rem 0}.ag-filter-condition .ag-labeled.ag-label-align-right div{margin-left:0}.ag-radio-button-label{position:relative;color:var(--t42-content-color-muted);cursor:pointer;user-select:none}.ag-radio-button-input-wrapper::before{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, border;position:absolute;left:-1.125rem;display:block;width:0.875rem;height:0.875rem;border:0.0625rem solid var(--t42-content-color-muted);border-radius:50%;cursor:pointer;content:"";pointer-events:all}.ag-radio-button-input-wrapper::after{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, border;position:absolute;left:-0.875rem;display:block;width:0.375rem;height:0.375rem;border-radius:50%;color:var(--white);background-image:none;transform:scale(0);opacity:0;content:""}.ag-radio-button-input-wrapper:focus{border-color:var(--primary)}.ag-radio-button-input-wrapper.ag-checked::before{border-color:var(--t42-color-opacity-30);background-color:var(--primary)}.ag-radio-button-input-wrapper.ag-checked::after{background-color:var(--white);transform:scale(1);opacity:1}.ag-list{z-index:1100;background-color:rgba(var(--t42-bg-mid), 0.7);backdrop-filter:var(--backdrop-filter)}.ag-list .ag-list-item{padding:0 0.5rem;line-height:2rem;cursor:pointer}.ag-list .ag-list-item:hover{background-color:Rgb(var(--t42-bg-light))}.ag-picker-field-wrapper{height:2rem;padding:0 0.5rem;line-height:2rem;cursor:pointer}.ag-column-select-header-icon{display:flex;align-items:center}.ag-column-select-header .ag-text-field-input{height:1.875rem;line-height:1.875rem}.ag-filter-list-panel .ag-filter-toolpanel-expand{margin:0 0.25rem}.ag-filter-list-panel .ag-filter-toolpanel-group-container,.ag-filter-list-panel .ag-filter-toolpanel-instance-filter{padding-left:0.25rem}.ag-side-bar{position:relative}.ag-side-bar .ag-side-bar-right .ag-tool-panel-horizontal-resize{left:-0.375rem}.ag-side-bar>div:first-child{border:var(--t42-border);background-color:var(--t42-color-opacity-10)}.ag-side-bar .ag-pivot-mode-select{display:flex;padding:0.25rem;border-bottom:var(--t42-border)}.ag-side-bar .ag-pivot-mode-select label{margin:0 0 0 0.5rem}.ag-side-bar .ag-pivot-mode-select .ag-checkbox-label{padding-left:0.25rem}.ag-side-bar .ag-side-buttons div.ag-side-button button{width:1rem;height:1rem;padding:0;border:0.0625rem solid transparent;color:Hsl(var(--t42-content-color-base), 100%);background-color:transparent}.ag-side-bar .ag-side-buttons div.ag-side-button button:hover{color:Hsl(var(--t42-content-color-base), 100%);background-color:Rgb(var(--t42-bg-dark))}.ag-side-bar .ag-side-buttons div.ag-side-button button>span{display:none}.ag-side-bar .ag-side-buttons div.ag-side-button.ag-selected button{border-color:var(--t42-color-opacity-30);background-color:var(--primary)}.ag-side-bar .ag-side-buttons div.ag-side-button.ag-selected button [class*="ag-icon-"]{background-color:var(--white)}.ag-side-bar .ag-icon-checkbox-checked::after{width:0.625rem;height:0.625rem}.ag-side-bar .ag-column-panel,.ag-side-bar .ag-filter-panel{padding-left:0.25rem}.ag-side-bar .ag-filter-checkbox{margin-right:0.25rem}.ag-tool-panel-wrapper{border-top:var(--t42-border);border-bottom:var(--t42-border)}.ag-tool-panel-wrapper .ag-set-filter-list{width:100%;height:auto}.ag-tool-panel-wrapper .ag-column-select-checkbox,.ag-tool-panel-wrapper .ag-column-select-header-checkbox{margin:0 0.25rem}.ag-tool-panel-horizontal-resize{top:initial;width:0.188rem;background-color:var(--t42-color-opacity-10)}.ag-column-panel,.ag-column-select-panel,.ag-column-drop-vertical,.ag-column-drop-list{display:block;min-height:initial;max-height:initial;overflow:visible}.ag-column-panel input,.ag-column-select-panel input,.ag-column-drop-vertical input,.ag-column-drop-list input{border:var(--t42-border)}.ag-column-panel input:focus,.ag-column-select-panel input:focus,.ag-column-drop-vertical input:focus,.ag-column-drop-list input:focus{border-color:var(--primary)}[class*="ag-icon-"],.icon-check-1,.icon-check-empty,.icon-resize-horizontal{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:color, transform;display:block;width:0.75rem;height:0.75rem;margin:0 auto;background-color:var(--t42-content-color);background-image:none;mask-repeat:no-repeat;mask-position:center;cursor:pointer}[class*="ag-icon-"]:hover,.icon-check-1:hover,.icon-check-empty:hover,.icon-resize-horizontal:hover{background-color:var(--t42-link-color)}.ag-menu-option-disabled{color:var(--t42-content-color-disabled)}.ag-menu-option-disabled .ag-icon{background-color:var(--t42-content-color-disabled)}.ag-icon-menu{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M475.4,384v36.4c0,5.1-1.7,9.4-5.1,12.8s-7.9,5.3-13.3,5.6H55c-5.1,0-9.4-1.9-12.8-5.6c-3.4-3.8-5.3-8-5.6-12.8V384 c0-5.1,1.9-9.4,5.6-12.8c3.8-3.4,8-5.3,12.8-5.6h401.9c5.1,0,9.6,1.9,13.3,5.6C474,375,475.7,379.2,475.4,384z M475.4,237.6v36.9 c0,4.8-1.7,9-5.1,12.8s-7.9,5.5-13.3,5.1H55c-5.1,0-9.4-1.7-12.8-5.1s-5.3-7.7-5.6-12.8v-36.9c0-4.8,1.9-9,5.6-12.8 c3.8-3.8,8-5.5,12.8-5.1h401.9c5.1,0,9.6,1.7,13.3,5.1S475.7,232.5,475.4,237.6z M475.4,91.7V128c0,4.8-1.7,9-5.1,12.8 s-7.9,5.6-13.3,5.6H55c-5.1,0-9.4-1.9-12.8-5.6s-5.3-8-5.6-12.8V91.7c0-5.1,1.9-9.6,5.6-13.3c3.8-3.8,8-5.5,12.8-5.1h401.9 c5.1,0,9.6,1.7,13.3,5.1S475.7,86.2,475.4,91.7z%27/%3E%3C/svg%3E%0A")}.ag-header-icon{margin-left:0.125rem}.ag-header-icon .ag-icon-menu{line-height:1.875rem}.ag-icon-asc{-webkit-mask-image:var(--t42-select-indicator);transform:rotate(180deg)}.ag-icon-desc{-webkit-mask-image:var(--t42-select-indicator);margin-bottom:2px}.ag-icon-filter{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 16 16%27%3E%3Cpath d=%27M14.9,1.4c0.1,0.3,0.1,0.5-0.1,0.7L9.9,7v7.4c0,0.3-0.1,0.5-0.4,0.6C9.4,15,9.4,15,9.3,15c-0.2,0-0.3-0.1-0.4-0.2l-2.5-2.5 c-0.1-0.1-0.2-0.3-0.2-0.4V7L1.2,2.1C1,1.9,0.9,1.7,1.1,1.4C1.2,1.1,1.4,1,1.7,1h12.7C14.6,1,14.8,1.1,14.9,1.4L14.9,1.4z%27/%3E%3C/svg%3E")}.ag-icon-none{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 16 16%27%3E%3Cpath d=%27M1 6L5 2Q6 1 7 2L11 6Q11 7 10 7L2 7Q1 7 1 6M2 8Q1 8 1 9L5 13Q6 14 7 13L11 9Q11 8 10 8L2 8%27/%3E%3C/svg%3E%0A")}.ag-icon-indeterminate,.ag-icon-checkbox-indeterminate,.ag-icon-checkbox-indeterminate-readonly,.ag-icon-checkbox-unchecked,.ag-icon-checkbox-unchecked-readonly,.ag-icon-checkbox-checked-readonly,.ag-icon-checkbox-checked,.icon-check-1,.icon-check-empty,.ag-checkbox-input-wrapper,.ag-toggle-button-input-wrapper{position:relative;padding:0;color:var(--t42-content-color-muted);background-color:transparent;cursor:pointer;user-select:none}.ag-icon-indeterminate::before,.ag-icon-checkbox-indeterminate::before,.ag-icon-checkbox-indeterminate-readonly::before,.ag-icon-checkbox-unchecked::before,.ag-icon-checkbox-unchecked-readonly::before,.ag-icon-checkbox-checked-readonly::before,.ag-icon-checkbox-checked::before,.icon-check-1::before,.icon-check-empty::before,.ag-checkbox-input-wrapper::before,.ag-toggle-button-input-wrapper::before{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, border-color;display:block;width:100%;height:100%;border:var(--t42-border);border-color:var(--t42-content-color);cursor:pointer;content:"";pointer-events:all}.ag-icon-indeterminate:focus,.ag-icon-checkbox-indeterminate:focus,.ag-icon-checkbox-indeterminate-readonly:focus,.ag-icon-checkbox-unchecked:focus,.ag-icon-checkbox-unchecked-readonly:focus,.ag-icon-checkbox-checked-readonly:focus,.ag-icon-checkbox-checked:focus,.icon-check-1:focus,.icon-check-empty:focus,.ag-checkbox-input-wrapper:focus,.ag-toggle-button-input-wrapper:focus{border-color:var(--primary)}.ag-icon-indeterminate:hover,.ag-icon-checkbox-indeterminate:hover,.ag-icon-checkbox-indeterminate-readonly:hover,.ag-icon-checkbox-unchecked:hover,.ag-icon-checkbox-unchecked-readonly:hover,.ag-icon-checkbox-checked-readonly:hover,.ag-icon-checkbox-checked:hover,.icon-check-1:hover,.icon-check-empty:hover,.ag-checkbox-input-wrapper:hover,.ag-toggle-button-input-wrapper:hover{background-color:transparent}.ag-icon-checkbox-indeterminate,.ag-icon-checkbox-indeterminate-readonly,.ag-icon-checkbox-checked,.ag-icon-checkbox-checked-readonly,.icon-check-empty,.ag-checkbox-input-wrapper.ag-indeterminate,.ag-checkbox-input-wrapper.ag-checked,.ag-toggle-button-input-wrapper.ag-checked{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background, color}.ag-icon-checkbox-indeterminate::before,.ag-icon-checkbox-indeterminate-readonly::before,.ag-icon-checkbox-checked::before,.ag-icon-checkbox-checked-readonly::before,.icon-check-empty::before,.ag-checkbox-input-wrapper.ag-indeterminate::before,.ag-checkbox-input-wrapper.ag-checked::before,.ag-toggle-button-input-wrapper.ag-checked::before{border:0.0625rem solid var(--t42-color-opacity-30);background:var(--primary)}.ag-icon-checkbox-indeterminate::after,.ag-icon-checkbox-indeterminate-readonly::after,.ag-icon-checkbox-checked::after,.ag-icon-checkbox-checked-readonly::after,.icon-check-empty::after,.ag-checkbox-input-wrapper.ag-indeterminate::after,.ag-checkbox-input-wrapper.ag-checked::after,.ag-toggle-button-input-wrapper.ag-checked::after{position:absolute;top:0.063rem;left:0.063rem;display:block;width:0.75rem;height:0.75rem;background:var(--white);content:""}.ag-icon-checkbox-checked::after,.ag-icon-checkbox-checked-readonly::after,.icon-check-empty::after,.ag-checkbox-input-wrapper.ag-checked::after,.ag-toggle-button-input-wrapper.ag-checked::after{-webkit-mask-image:url("data:image/svg+xml,%3Csvg version=%271.1%27 xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M477.44 152.832q0 11.264-8.192 19.456l-245.76 245.76q-8.192 7.68-19.456 7.68t-19.456-7.68l-142.336-142.336q-7.68-8.192-7.68-19.456t7.68-19.456l38.912-38.912q8.192-8.192 19.456-8.192t19.456 8.192l83.968 84.48 187.392-187.904q8.192-8.192 19.456-8.192t19.456 8.192l38.912 38.912q8.192 7.68 8.192 19.456z%27%3E%3C/path%3E%3C/svg%3E%0A")}.ag-icon-checkbox-indeterminate::after,.ag-icon-checkbox-indeterminate-readonly::after,.ag-checkbox-input-wrapper.ag-indeterminate::after{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 -1 5 6%27%3E%3Cpath d=%27M 1 1 A 1 1 0 0 0 1 2 L 4 2 A 1 1 0 0 0 4 1 L 1 1%27/%3E%3C/svg%3E%0A")}.ag-checkbox-input-wrapper.ag-indeterminate::after{top:0.125rem;left:0.125rem}.ag-checkbox-input-wrapper::before,.ag-toggle-button-input-wrapper::before{width:0.875rem;height:0.875rem}.ag-checkbox-input-wrapper .ag-checkbox-input,.ag-checkbox-input-wrapper .ag-toggle-button-input,.ag-toggle-button-input-wrapper .ag-checkbox-input,.ag-toggle-button-input-wrapper .ag-toggle-button-input{position:absolute;z-index:2;width:0.875rem;height:0.875rem}.ag-icon-columns{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M146.432 374.784v55.296q0 11.264-8.192 18.944t-19.456 8.192h-91.136q-11.776 0-19.456-8.192t-8.192-18.944v-55.296q0-11.264 8.192-19.456t19.456-7.68h91.136q11.776 0 19.456 7.68t8.192 19.456zM146.432 228.864v54.784q0 11.264-8.192 19.456t-19.456 7.68h-91.136q-11.776 0-19.456-7.68t-8.192-19.456v-54.784q0-11.776 8.192-19.456t19.456-8.192h91.136q11.776 0 19.456 8.192t8.192 19.456zM329.216 374.784v55.296q0 11.264-8.192 18.944t-19.456 8.192h-91.136q-11.776 0-19.456-8.192t-8.192-18.944v-55.296q0-11.264 8.192-19.456t19.456-7.68h91.136q11.776 0 19.456 7.68t8.192 19.456zM146.432 82.432v54.784q0 11.264-8.192 19.456t-19.456 8.192h-91.136q-11.776 0-19.456-8.192t-8.192-19.456v-54.784q0-11.264 8.192-19.456t19.456-8.192h91.136q11.776 0 19.456 8.192t8.192 19.456zM329.216 228.864v54.784q0 11.264-8.192 19.456t-19.456 7.68h-91.136q-11.776 0-19.456-7.68t-8.192-19.456v-54.784q0-11.776 8.192-19.456t19.456-8.192h91.136q11.776 0 19.456 8.192t8.192 19.456zM512 374.784v55.296q0 11.264-8.192 18.944t-19.456 8.192h-91.136q-11.264 0-19.456-8.192t-8.192-18.944v-55.296q0-11.264 8.192-19.456t19.456-7.68h91.136q11.776 0 19.456 7.68t8.192 19.456zM329.216 82.432v54.784q0 11.264-8.192 19.456t-19.456 8.192h-91.136q-11.776 0-19.456-8.192t-8.192-19.456v-54.784q0-11.264 8.192-19.456t19.456-8.192h91.136q11.776 0 19.456 8.192t8.192 19.456zM512 228.864v54.784q0 11.264-8.192 19.456t-19.456 7.68h-91.136q-11.264 0-19.456-7.68t-8.192-19.456v-54.784q0-11.776 8.192-19.456t19.456-8.192h91.136q11.776 0 19.456 8.192t8.192 19.456zM512 82.432v54.784q0 11.264-8.192 19.456t-19.456 8.192h-91.136q-11.264 0-19.456-8.192t-8.192-19.456v-54.784q0-11.264 8.192-19.456t19.456-8.192h91.136q11.776 0 19.456 8.192t8.192 19.456z%27%3E%3C/path%3E%3C/svg%3E")}.ag-icon-pin{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M228.4,228.6v-128c0-2.7-0.9-4.9-2.6-6.7s-3.9-2.6-6.7-2.6c-2.7,0-4.9,0.9-6.7,2.6c-1.7,1.7-2.6,3.9-2.6,6.7v128 c0,2.7,0.9,4.9,2.6,6.7c1.7,1.7,3.9,2.6,6.7,2.6c2.7,0,4.9-0.9,6.7-2.6S228.4,231.3,228.4,228.6z M420.4,329.5c0,4.8-1.9,9-5.6,12.8 c-3.8,3.8-8,5.5-12.8,5.1H279.6l-14.8,138.2c-0.3,2.4-1.4,4.3-3.1,5.6c-1.7,1.4-3.6,2.2-5.6,2.6h-0.5c-5.1,0-8-2.6-8.7-7.7 l-22-138.8H109.6c-5.1,0-9.4-1.7-12.8-5.1c-3.4-3.4-5.3-7.7-5.6-12.8c0-23.6,7.5-44.7,22.5-63.5s31.9-28.2,50.7-28.2V91.4 c-9.9,0-18.4-3.6-25.6-10.8c-7.2-7.2-10.9-15.7-11.3-25.6s3.4-18.4,11.3-25.6c7.9-7.2,16.4-10.9,25.6-11.3h182.8 c9.9,0,18.4,3.8,25.6,11.3s10.8,16,10.8,25.6s-3.6,18.1-10.8,25.6S357,91.7,347.1,91.4v146.4c18.8,0,35.7,9.4,50.7,28.2 C412.8,284.8,420.4,305.9,420.4,329.5L420.4,329.5z%27/%3E%3C/svg%3E")}.ag-icon-small-right,.ag-icon-small-down{width:0.65rem;height:0.65rem;-webkit-mask-image:var(--t42-select-indicator);transform:rotate(-90deg)}.ag-icon-small-down{transform:rotate(0)}.ag-icon-tick{-webkit-mask-image:url("data:image/svg+xml,%3Csvg version=%271.1%27 xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M477.44 152.832q0 11.264-8.192 19.456l-245.76 245.76q-8.192 7.68-19.456 7.68t-19.456-7.68l-142.336-142.336q-7.68-8.192-7.68-19.456t7.68-19.456l38.912-38.912q8.192-8.192 19.456-8.192t19.456 8.192l83.968 84.48 187.392-187.904q8.192-8.192 19.456-8.192t19.456 8.192l38.912 38.912q8.192 7.68 8.192 19.456z%27%3E%3C/path%3E%3C/svg%3E%0A")}.ag-icon-copy{-webkit-mask-image:url("data:image/svg+xml,")}.ag-icon-csv,.ag-icon-excel{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M0 0zq0-7.7-5.1-12.8zM475.3 356.6v91.6q0 11.3-8.2 18.9t-19.5 8.2h-420.4q-11.8 0-19.5-8.2t-8.2-18.9v-91.6q0-11.3 8.2-19.5t19.5-8.2h132.6l38.4 38.9q16.9 16.4 38.9 16.4t38.9-16.4l38.9-38.9h132.6q11.3 0 19.5 8.2t8.2 19.5zM382.1 193.8q5.1 11.8-4.1 20l-128 128q-5.1 5.6-12.8 5.6t-12.8-5.6l-128-128q-8.7-8.2-4.1-20q5.1-10.8 16.9-10.8h73.2v-128q0-7.7 5.6-12.8t12.8-5.6h73.2q7.2 0 12.8 5.6t5.1 12.8v128h73.2q12.3 0 16.9 10.8M347 439A1 1 0 00347 402A1 1 0 00347 439M420 439A1 1 0 00420 402A1 1 0 00420 439zz%27/%3E%3C/svg%3E%0A")}.ag-icon-expanded{-webkit-mask-image:var(--t42-select-indicator);transform:rotate(-90deg)}.ag-icon-contracted{-webkit-mask-image:var(--t42-select-indicator);transform:rotate(90deg)}.ag-header-expand-icon-collapsed .ag-icon-contracted{margin-bottom:1px;transform:rotate(90deg);-webkit-mask-image:var(--t42-select-indicator)}.ag-icon-paste{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M219.648 475.648h256v-183.296h-119.296q-11.264 0-18.944-7.68t-8.192-19.456v-118.784h-109.568v329.216zM292.352 64v-18.432q0-3.584-2.56-6.144t-6.144-3.072h-201.216q-3.584 0-6.656 3.072t-2.56 6.144v18.432q0 3.584 2.56 6.656t6.656 2.56h201.216q3.584 0 6.144-2.56t2.56-6.656zM365.568 256h85.504l-85.504-85.504v85.504zM512 292.352v192q0 11.776-8.192 19.456t-19.456 8.192h-273.92q-11.776 0-19.456-8.192t-8.192-19.456v-45.568h-155.136q-11.776 0-19.456-8.192t-8.192-18.944v-384q0-11.776 8.192-19.456t19.456-8.192h310.784q11.264 0 19.456 8.192t7.68 19.456v93.696q6.144 3.584 10.24 7.68l116.736 116.736q8.192 7.68 13.824 21.504t5.632 25.088z%27%3E%3C/path%3E%3C/svg%3E%0A")}.ag-icon-arrows{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M512 256q0 7.168-5.632 12.8l-72.704 73.216q-5.632 5.632-13.312 5.632t-12.8-5.632-5.12-12.8v-36.864h-110.080v110.080h36.864q7.168 0 12.8 5.12t5.632 12.8-5.632 12.8l-73.216 73.216q-5.12 5.632-12.8 5.632t-12.8-5.632l-73.216-73.216q-5.632-5.12-5.632-12.8t5.632-12.8 12.8-5.12h36.864v-110.080h-110.080v36.864q0 7.168-5.12 12.8t-12.8 5.632-12.8-5.632l-73.216-73.216q-5.632-5.632-5.632-12.8t5.632-12.8l73.216-73.216q5.12-5.632 12.8-5.632t12.8 5.632 5.12 12.8v36.864h110.080v-110.080h-36.864q-7.168 0-12.8-5.12t-5.632-12.8 5.632-13.312l73.216-72.704q5.632-5.632 12.8-5.632t12.8 5.632l73.216 72.704q5.632 5.632 5.632 13.312t-5.632 12.8-12.8 5.12h-36.864v110.080h110.080v-36.864q0-7.168 5.12-12.8t12.8-5.632 13.312 5.632l72.704 73.216q5.632 5.12 5.632 12.8z%27%3E%3C/path%3E%3C/svg%3E%0A")}.ag-icon-not-allowed{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27m 182.8 238.1 h 145.9 v -55.3 c 0 -20.1 -7.2 -37.4 -21.5 -51.7 s -31.6 -21.3 -51.7 -21 c -20.1 0.3 -37.4 7.3 -51.7 21 s -21.3 30.9 -21 51.7 l -0 55.3 l 0 0 z m 237.6 27.1 v 164.9 c 0 7.5 -2.7 13.8 -8.2 18.9 s -11.9 7.9 -19.5 8.2 h -273.9 c -7.9 0 -14.3 -2.7 -19.5 -8.2 c -5.1 -5.5 -7.9 -11.8 -8.2 -18.9 v -164.9 c 0 -7.5 2.7 -14 8.2 -19.5 s 11.9 -8 19.5 -7.7 h 8.7 v -55.3 c 0 -34.8 12.6 -64.9 37.9 -90.1 s 55.3 -37.9 90.1 -37.9 s 65 12.6 90.6 37.9 s 38.1 55.3 37.4 90.1 v 55.3 h 9.2 c 7.9 0 14.3 2.6 19.5 7.7 s 7.8 11.7 8.2 19.5 z%27/%3E%3C/svg%3E")}.ag-icon-eye-slash{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M 475.6 256.3 q -43.5 -67.6 -109.1 -100.9 q 17.4 29.7 17.4 64 q 0 52.7 -37.4 90.6 t -90.6 37.4 t -90.6 -37.4 t -37.4 -90.6 q 0 -34.3 17.4 -64 q -65.5 33.3 -109.1 100.9 q 38.4 58.4 95.7 93.2 t 123.9 34.8 t 124.4 -34.8 t 95.2 -93.2 z M 269.8 146.2 q 0 -5.6 -4.1 -9.7 t -9.7 -3.6 q -35.8 0 -61.4 25.6 t -25.6 60.9 q 0 5.6 4.1 9.7 t 9.7 4.1 t 9.7 -4.1 t 4.1 -9.7 q 0 -24.6 17.4 -42 t 42 -17.4 q 5.6 0 9.7 -4.1 t 4.1 -9.7 z M 512 256.3 q 0 9.7 -5.6 19.5 q -39.9 66 -107.5 105.5 t -142.8 39.4 t -142.8 -39.4 t -107.5 -105.5 q -5.6 -9.7 -5.6 -19.5 t 5.6 -20 q 39.9 -65.5 107.5 -105 t 142.8 -39.9 t 142.8 39.9 t 107.5 105 q 5.6 10.2 5.6 20 z%27%3E%3C/path%3E%3C/svg%3E%0A")}.ag-icon-group{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M146.4 374.8v55.3q0 11.3-8.2 18.9t-19.5 8.2h-91.1q-11.8 0-19.5-8.2t-8.2-18.9v-55.3q0-11.3 8.2-19.5t19.5-7.7h91.1q11.8 0 19.5 7.7t8.2 19.5zM146.4 228.9v54.8q0 11.3-8.2 19.5t-19.5 7.7h-91.1q-11.8 0-19.5-7.7t-8.2-19.5v-54.8q0-11.8 8.2-19.5t19.5-8.2h91.1q11.8 0 19.5 8.2t8.2 19.5zM512 374.8v55.3q0 11.3-8.2 18.9t-19.5 8.2h-273.9q-11.8 0-19.5-8.2t-8.2-18.9v-55.3q0-11.3 8.2-19.5t19.5-7.7h273.9q11.8 0 19.5 7.7t8.2 19.5zM146.4 82.4v54.8q0 11.3-8.2 19.5t-19.5 8.2h-91.1q-11.8 0-19.5-8.2t-8.2-19.5v-54.8q0-11.3 8.2-19.5t19.5-8.2h91.1q11.8 0 19.5 8.2t8.2 19.5zM512 228.9v54.8q0 11.3-8.2 19.5t-19.5 7.7h-273.9q-11.8 0-19.5-7.7t-8.2-19.5v-54.8q0-11.8 8.2-19.5t19.5-8.2h273.9q11.8 0 19.5 8.2t8.2 19.5zM512 82.4v54.8q0 11.3-8.2 19.5t-19.5 8.2h-273.9q-11.8 0-19.5-8.2t-8.2-19.5v-54.8q0-11.3 8.2-19.5t19.5-8.2h273.9q11.8 0 19.5 8.2t8.2 19.5z%27%3E%3C/path%3E%3C/svg%3E%0A")}.ag-icon-grip{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 16 16%27%3E%3Cpath d=%27M4 3L6 3L6 5L4 5L4 3M4 7L6 7L6 9L4 9L4 7M4 11L6 11L6 13L4 13L4 11M8 3L10 3L10 5L8 5L8 3M8 7L10 7L10 9L8 9L8 7M8 11L10 11L10 13L8 13L8 11%27/%3E%3C/svg%3E%0A");margin:0}.ag-icon-tree-open{-webkit-mask-image:var(--t42-select-indicator);transform:rotate(180deg)}.ag-icon-tree-closed{-webkit-mask-image:var(--t42-select-indicator);transform:rotate(270deg)}.ag-icon-tree-indeterminate{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 -1 5 6%27%3E%3Cpath d=%27M 1 1 A 1 1 0 0 0 1 2 L 4 2 A 1 1 0 0 0 4 1 L 1 1%27/%3E%3C/svg%3E%0A")}.ag-icon-save{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M 420.6 319.2 V 393 c 0 22.9 -8 42.3 -24.1 58.4 s -35.5 24.1 -58.4 24.1 H 100.6 c -22.9 0 -42.3 -8 -58.4 -24.1 S 18.2 415.8 18.2 393 V 155.4 c 0 -22.5 8 -41.8 24.1 -57.9 S 77.7 73.3 100.6 73 h 72.7 c 2.4 0 4.6 1 6.7 3.1 c 2 2 2.9 4.1 2.6 6.1 c 0 5.1 -2.6 8.2 -7.7 9.2 c -14.7 5.1 -27.3 10.9 -37.9 17.4 c -1.7 0.7 -3.2 1 -4.6 1 h -31.7 c -12.6 0 -23.4 4.4 -32.3 13.3 s -13.5 19.6 -13.8 32.3 V 393 c 0 12.6 4.6 23.4 13.8 32.3 c 9.2 8.9 20 13.5 32.3 13.8 h 237.6 c 12.6 0 23.4 -4.6 32.3 -13.8 c 8.9 -9.2 13.3 -20 13.3 -32.3 V 332 c 0 -3.8 1.7 -6.5 5.1 -8.2 c 5.5 -2.4 10.8 -6 15.9 -10.8 c 2.7 -3.1 6 -3.8 9.7 -2 C 418.6 312.7 420.6 315.5 420.6 319.2 L 420.6 319.2 z M 488.2 177.4 L 378.6 287 c -3.4 3.8 -7.7 5.6 -12.8 5.6 c -2.4 0 -4.8 -0.5 -7.2 -1.5 c -7.5 -3.1 -11.3 -8.7 -11.3 -16.9 v -54.8 h -45.6 c -61.8 0 -103.6 12.5 -125.4 37.4 c -22.5 26.3 -29.5 71.3 -21 135.2 c 0.7 4.4 -1.2 7.7 -5.6 9.7 c -1.7 0.3 -2.9 0.5 -3.6 0.5 c -3.1 0 -5.5 -1.2 -7.2 -3.6 c -2 -2.7 -4.1 -5.6 -6.1 -8.7 c -2 -3.1 -5.8 -9.7 -11.3 -20 c -5.5 -10.2 -10.2 -19.6 -14.3 -28.2 c -4.1 -8.5 -7.7 -19.5 -10.8 -32.8 c -3.1 -13.3 -4.8 -24.9 -5.1 -34.8 c 0 -9.2 0.3 -17.9 1 -26.1 c 0.7 -8.2 2 -16.7 4.1 -25.6 c 2 -8.9 4.6 -17.2 7.7 -25.1 c 3.1 -7.9 7.7 -15.5 13.8 -23 c 6.1 -7.5 12.6 -14.7 19.5 -21.5 s 15.7 -12.6 26.6 -17.4 c 10.9 -4.8 22.9 -9.4 35.8 -13.8 c 13 -4.4 28.2 -7.3 45.6 -8.7 s 36.2 -2.4 56.3 -3.1 h 45.6 V 55 c 0 -8.2 3.8 -13.8 11.3 -16.9 c 2.4 -1 4.8 -1.5 7.2 -1.5 c 4.8 0 9 1.9 12.8 5.6 l 109.6 109.6 c 3.8 3.4 5.6 7.7 5.6 12.8 S 491.9 174 488.2 177.4 L 488.2 177.4 z%27/%3E%3C/svg%3E")}.ag-tooltip{padding:0.125rem 0.5rem;border:0.0625rem solid var(--t42-color-opacity-10);border-radius:0.25rem;background:Rgb(var(--t42-bg-light));box-shadow:var(--t42-shadow)}.ag-icon-cancel{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M366.9 336.4c6.1 6.1 9.2 13.5 9.2 22s-3.1 15.9-9.2 22c-6.1 5.5-13.5 8.2-22 8.2c-8.5 0-15.9-2.7-22-8.2l-67.6-77.8l-67.6 77.8c-6.1 5.5-13.5 8.2-22 8.2c-8.5 0-15.9-2.7-22-8.2c-5.5-6.1-8.2-13.5-8.2-22s2.7-15.9 8.2-22l70.7-79.9l-70.7-80.9c-5.5-6.1-8.2-13.5-8.2-22c0-8.5 2.7-15.9 8.2-22c6.1-5.5 13.5-8.2 22-8.2c8.5 0 15.9 2.7 22 8.2l67.6 77.8l67.6-77.8c6.1-5.5 13.5-8.2 22-8.2c8.5 0 15.9 2.7 22 8.2c6.1 6.1 9.2 13.5 9.2 22c0 8.5-3.1 15.9-9.2 22l-70.7 80.9L366.9 336.4z%27/%3E%3C/svg%3E")}.icon-check-empty::after{width:0.65rem;height:0.65rem}.icon-resize-horizontal{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M512 256q0 7.2-5.6 12.8l-72.7 73.2q-5.6 5.6-13.3 5.6t-12.8-5.6t-5.1-12.8v-36.9h-292.9v36.9q0 7.2-5.1 12.8t-12.8 5.6t-12.8-5.6l-73.2-73.2q-5.6-5.6-5.6-12.8t5.6-12.8l73.2-73.2q5.1-5.6 12.8-5.6t12.8 5.6t5.1 12.8v36.9h292.9v-36.9q0-7.2 5.1-12.8t12.8-5.6t13.3 5.6l72.7 73.2q5.6 5.1 5.6 12.8z%27%3E%3C/path%3E%3C/svg%3E%0A")}.ag-icon-aggregation{margin:0 0.25rem;-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 16 16%27%3E%3Cpath d=%27M3.6,1.7c-0.2,0.7-0.9,1.1-1.5,1C1.5,2.6,1,2,1,1.3C1,0.7,1.5,0.1,2.1,0c0.4-0.1,0.7,0,1,0.2C3.4,0.4,3.6,0.7,3.7,1 c0.3,0,0.5,0.1,0.8,0.3C4.7,1.5,5,1.8,5.2,2.1c0.2,0.3,0.4,0.7,0.6,1c0.1,0.2,0.3,0.5,0.5,0.7c0.2,0.2,0.5,0.5,0.8,0.6 c0.1,0.1,0.3,0.1,0.5,0.1c0.6,0,2.3,0,2.9,0c0.4,0,0.7,0,1.1,0c0,0,0,0,0.1,0c0,0,0,0,0-0.1c0-0.1,0-0.2,0-0.3c0,0,0-0.1,0-0.1 c0-0.1,0.1-0.1,0.2-0.1c0.1,0,0.1,0,0.1,0.1c0.1,0,0.1,0.1,0.2,0.2c0.2,0.2,0.3,0.3,0.5,0.5C12.8,4.8,13,5,13.1,5.1c0,0,0,0,0,0 c0,0,0,0-0.1,0c-1.5,0-4.1,0-5.7,0C7.2,5.2,7,5.1,6.8,5C6.6,4.9,6.3,4.8,6.1,4.6C5.7,4.3,5.5,4,5.2,3.5C5,3.2,4.8,2.8,4.6,2.4 C4.4,2.2,4.3,2.1,4.1,1.9C4,1.8,3.9,1.7,3.8,1.7C3.7,1.7,3.7,1.7,3.6,1.7z%27/%3E%3Cpath d=%27M3.6,7.7c1,0,10.6,0,11,0c0.1,0,0.1,0,0.1,0.1C14.8,7.8,14.9,7.9,15,8c-0.1,0.1-0.2,0.2-0.3,0.3c0,0,0,0-0.1,0 c0,0,0,0-0.1,0c-3.3,0-7.7,0-10.9,0C3.5,8.8,3.2,9.1,2.8,9.3C2.5,9.4,2.2,9.4,2,9.3C1.4,9.1,1,8.6,1,8c0-0.7,0.5-1.2,1.1-1.3 c0.3-0.1,0.7,0,1,0.2C3.4,7.1,3.6,7.3,3.6,7.7z%27/%3E%3Cpath d=%27M13.1,10.9C13.1,10.9,13.1,10.9,13.1,10.9c-0.3,0.3-0.6,0.6-0.8,0.8c-0.1,0.1-0.2,0.2-0.3,0.3c0,0-0.1,0.1-0.1,0.1 c0,0-0.1,0-0.1,0c-0.1,0-0.1,0-0.2-0.1c0,0,0-0.1,0-0.1c0-0.1,0-0.2,0-0.3c0,0,0,0,0-0.1c-1,0-3.1,0-4.1,0c-0.1,0-0.3,0-0.4,0.1 c-0.3,0.1-0.5,0.2-0.7,0.4c-0.2,0.2-0.4,0.5-0.6,0.8c-0.2,0.4-0.4,0.7-0.7,1.1c-0.2,0.2-0.4,0.4-0.6,0.6c-0.1,0.1-0.3,0.2-0.4,0.3 c-0.1,0.1-0.3,0.2-0.4,0.2c0,0-0.1,0-0.1,0c-0.1,0.4-0.3,0.7-0.7,0.9C2.7,16,2.4,16,2.1,16C1.5,15.9,1,15.3,1,14.7 c0-0.7,0.5-1.2,1-1.3c0.3-0.1,0.7,0,1,0.2c0.3,0.2,0.5,0.5,0.6,0.8c0.1,0,0.2,0,0.2,0C4,14.2,4.1,14.1,4.2,14 c0.2-0.2,0.3-0.4,0.5-0.6c0.2-0.3,0.4-0.6,0.6-1c0.2-0.3,0.4-0.6,0.6-0.9c0.3-0.2,0.5-0.5,0.9-0.6c0.2-0.1,0.4-0.1,0.6-0.1 c0,0,0.1,0,0.1,0c0.6,0,2.4,0,3,0c0.8,0,1.7,0,2.5,0C13.1,10.9,13.1,10.9,13.1,10.9C13.1,10.9,13.1,10.9,13.1,10.9z%27/%3E%3Cpath d=%27M3.6,11.7c-0.1,0.4-0.3,0.7-0.7,0.9c-0.3,0.2-0.6,0.2-0.9,0.1C1.5,12.6,1,12.1,1,11.4c0-0.7,0.5-1.2,1.1-1.3 c0.3-0.1,0.7,0,1,0.2c0.3,0.2,0.5,0.5,0.6,0.8c0.1,0,0.1,0,0.2,0c0.2,0,0.3-0.1,0.4-0.2c0.2-0.1,0.4-0.3,0.5-0.4 C4.9,10.3,5,10.2,5,10.2C5.3,9.9,5.6,9.7,6,9.6c0.3-0.1,0.6-0.2,0.8-0.2c0.1,0,0.1,0,0.2,0c1.1,0,3.4,0,4.5,0c0.9,0,1.8,0,2.6,0 c0,0,0,0,0.1,0c0,0,0,0,0,0C14,9.6,13.8,9.8,13.6,10c-1.8,0-4.8,0-6.6,0c-0.3,0-0.6,0.1-0.9,0.2c-0.2,0.1-0.5,0.3-0.6,0.5 c-0.3,0.3-0.5,0.5-0.8,0.7c-0.2,0.1-0.4,0.2-0.6,0.3C3.9,11.7,3.8,11.7,3.6,11.7C3.7,11.7,3.7,11.7,3.6,11.7z%27/%3E%3Cpath d=%27M3.6,4.9C3.5,5.3,3.3,5.6,2.9,5.8C2.6,5.9,2.3,6,2,5.9C1.4,5.7,1,5.2,1,4.5c0-0.6,0.5-1.2,1.1-1.3c0.7-0.1,1.4,0.3,1.5,1 c0,0,0.1,0,0.1,0c0.3,0,0.5,0.1,0.7,0.3C4.7,4.7,5,4.9,5.2,5c0.1,0.1,0.2,0.2,0.4,0.4c0.3,0.3,0.6,0.5,1,0.5C6.7,6,6.9,6,7,6 c1.8,0,4.8,0,6.6,0c0.1,0.1,0.3,0.3,0.6,0.6c0,0,0,0,0,0c0,0,0,0,0,0c0,0,0,0-0.1,0c-2,0-5.1,0-7.1,0c-0.3,0-0.5,0-0.8-0.1 C6,6.5,5.7,6.4,5.5,6.2C5.3,6.1,5.1,5.9,5,5.8C4.8,5.5,4.5,5.3,4.2,5.1C4.1,5,3.9,4.9,3.6,4.9z%27/%3E%3C/svg%3E%0A")}.ag-icon-loading{position:relative;width:1rem;height:1rem;border-radius:50%;background:linear-gradient(to right, var(--t42-icon-color), Rgba(var(--t42-bg-dark) 42%));transform:translateZ(0);animation:icon-loading 1.4s infinite linear}.ag-icon-loading::before{position:absolute;top:0;left:0;width:50%;height:50%;border-radius:100% 0 0;background:var(--t42-icon-color);content:""}.ag-icon-loading::after{position:absolute;top:0;right:0;bottom:0;left:0;width:75%;height:75%;margin:auto;border-radius:50%;background:Rgb(var(--t42-bg-dark));content:""}.ag-loading{display:flex;padding-left:0.5rem}@keyframes icon-loading{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.search{position:relative}.search i{position:absolute;top:0.625rem;right:0.75rem;width:.75rem;height:.75rem;background-color:var(--t42-content-color);-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M328.9 219.4q0-52.7-37.4-90.1t-90.6-37.9t-90.6 37.9t-37.4 90.1t37.4 90.6t90.6 37.4t90.6-37.4t37.4-90.6zM475.3 457.5q0 14.8-11.3 25.6t-25.6 10.8q-15.4 0-25.6-10.8l-97.8-97.8q-51.2 35.3-114.2 35.3q-41 0-78.3-15.9t-64-43t-43-64t-15.9-78.3t15.9-77.8t43-64.5t64-43t78.3-15.9t78.3 15.9t64 43t43 64.5t15.9 77.8q0 63-35.3 114.2l97.8 97.8q10.8 10.8 10.8 26.1z%27%3E%3C/path%3E%3C/svg%3E%0A")}.search-results{position:absolute;top:33px;max-height:215px;overflow-y:auto}.search-results .list-group-item{white-space:nowrap}.select{position:relative;z-index:12;display:flex;align-items:center;justify-content:center;width:100%;height:2rem;list-style:none;cursor:pointer}.select input[type="radio"]{opacity:1}.select_expand{position:absolute;top:0;right:0;width:0;height:2rem}.select_expand::after{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:transform;position:absolute;top:50%;right:0;z-index:2;width:1rem;height:1rem;background:var(--t42-select-indicator) center center/1rem 1rem no-repeat;transform:translate(-65%, -55%);content:"";pointer-events:none}.select_expand:checked+.select_close_label+.select_options .select_label:hover{color:var(--t42-link-hover-color);background-color:var(--t42-link-active-bg)}.select_expand:checked::after{transform:translate(-65%, -55%) rotate(-180deg)}.select_expand_label{position:absolute;top:0;left:0;display:block;width:100%;height:2rem;margin-bottom:0;cursor:pointer}.select_close{display:none}.select_close_label{position:fixed;top:0;left:0;display:none;margin-bottom:0}.select_items{position:absolute;top:0;left:0;width:100%;min-height:2rem;border-color:var(--t42-color-opacity-10);border-style:solid;border-width:1px}.select_items:hover{border-color:var(--primary)}.select_input{display:none}.select_label{display:block;height:0;margin-bottom:0;padding-left:0.875rem;overflow:hidden;line-height:2rem;cursor:pointer;transition:all 200ms cubic-bezier(0.4, 0.25, 0.3, 1)}.select_label-placeholder{position:absolute;top:0;left:0;height:2rem;vertical-align:middle;background-color:transparent}.select_expand:checked+.select_close_label{display:block}.select_expand:checked+.select_close_label::before,.select_expand:checked+.select_close_label::after{display:none}.select_expand:checked+.select_close_label+.select_options .select_label{height:2rem}.select_expand:checked+.select_close_label+.select_options+.select_expand_label{display:none}.select_input:checked+.select_label{height:2rem}.select_option label{color:var(--t42-content-color)}.select_options{max-height:10rem;padding-left:0;overflow:auto;list-style:none}.dark{--t42-json-icons: url("data:image/svg+xml,%3C%3Fxml version=%271.0%27 encoding=%27UTF-8%27 standalone=%27no%27%3F%3E%3Csvg xmlns:dc=%27http://purl.org/dc/elements/1.1/%27 xmlns:cc=%27http://creativecommons.org/ns%23%27 xmlns:rdf=%27http://www.w3.org/1999/02/22-rdf-syntax-ns%23%27 xmlns:svg=%27http://www.w3.org/2000/svg%27 xmlns=%27http://www.w3.org/2000/svg%27 xmlns:sodipodi=%27http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd%27 xmlns:inkscape=%27http://www.inkscape.org/namespaces/inkscape%27 width=%27240%27 height=%27144%27 id=%27svg4136%27 version=%271.1%27 inkscape:version=%270.91 r13725%27 sodipodi:docname=%27jsoneditor-icons.svg%27%3E%3Ctitle id=%27title6512%27%3EJSON Editor Icons%3C/title%3E%3Crect id=%27svg_1-7%27 height=%2716%27 width=%2716%27 y=%273.999995%27 x=%2728.000006%27 style=%27fill:%23ff511f;%27 /%3E%3Crect x=%277%27 y=%2711%27 width=%2710%27 height=%272%27 id=%27svg_1-1%27 style=%27fill:%23ffffff;%27 /%3E%3Crect x=%2711%27 y=%277%27 width=%272%27 height=%2710%27 id=%27svg_1-1-1%27 style=%27fill:%23ffffff;%27 /%3E%3Cg id=%27g4299-3%27 transform=%27matrix%280.70710678,-0.70710678,0.70710678,0.70710678,19.029435,12.000001%29%27 style=%27%27%3E%3Crect x=%277%27 y=%2711%27 width=%2710%27 height=%272%27 id=%27svg_1-1-0%27 style=%27fill:%23ffffff;%27 /%3E%3Crect x=%2711%27 y=%277%27 width=%272%27 height=%2710%27 id=%27svg_1-1-1-9%27 style=%27fill:%23ffffff;%27 /%3E%3C/g%3E%3Crect height=%277%27 width=%277%27 y=%277%27 x=%2755%27 style=%27fill:%23ffffff;stroke-width:1;stroke:%23ffffff%27 /%3E%3Crect id=%27svg_1-7-5-7%27 height=%277%27 width=%277%27 y=%2710%27 x=%2758%27 style=%27fill:%23ffffff;stroke-width:1;stroke:%231d1d1d%27 /%3E%3Cg id=%27g4378%27%3E%3Crect style=%27fill:%23ffffff;%27 x=%27198%27 y=%2711%27 width=%278%27 height=%272%27 id=%27svg_1-7-5-3%27 /%3E%3Crect id=%27rect4374%27 height=%272%27 width=%2712%27 y=%277%27 x=%27198%27 style=%27fill:%23ffffff;%27 /%3E%3Crect id=%27rect4376%27 height=%272%27 width=%274%27 y=%2715%27 x=%27198%27 style=%27fill:%23ffffff;%27 /%3E%3C/g%3E%3Cg transform=%27matrix%281,0,0,-1,-23.999995,23.999995%29%27 id=%27g4383%27%3E%3Crect id=%27rect4385%27 height=%272%27 width=%278%27 y=%2711%27 x=%27198%27 style=%27fill:%23ffffff;%27 /%3E%3Crect style=%27fill:%23ffffff;%27 x=%27198%27 y=%277%27 width=%2712%27 height=%272%27 id=%27rect4387%27 /%3E%3Crect style=%27fill:%23ffffff;%27 x=%27198%27 y=%2715%27 width=%274%27 height=%272%27 id=%27rect4389%27 /%3E%3C/g%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 85.10447,6.0157384 -0.0156,1.4063 c 3.02669,-0.2402 0.33008,3.6507996 2.48438,4.5780996 -2.18694,1.0938 0.49191,4.9069 -2.45313,4.5781 l -0.0156,1.4219 c 5.70828,0.559 1.03264,-5.1005 4.70313,-5.2656 l 0,-1.4063 c -3.61303,-0.027 1.11893,-5.7069996 -4.70313,-5.3124996 z%27 id=%27path4351%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 82.78125,5.9984384 0.0156,1.4063 c -3.02668,-0.2402 -0.33007,3.6506996 -2.48437,4.5780996 2.18694,1.0938 -0.49192,4.9069 2.45312,4.5781 l 0.0156,1.4219 c -5.70827,0.559 -1.03263,-5.1004 -4.70312,-5.2656 l 0,-1.4063 c 3.61303,-0.027 -1.11894,-5.7070996 4.70312,-5.3124996 z%27 id=%27path4351-9%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 103.719,5.6719384 0,12.7187996 3.03125,0 0,-1.5313 -1.34375,0 0,-9.6249996 1.375,0 0,-1.5625 z%27 id=%27path2987%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 112.2185,5.6721984 0,12.7187996 -3.03125,0 0,-1.5313 1.34375,0 0,-9.6249996 -1.375,0 0,-1.5625 z%27 id=%27path2987-1%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27M133,6.4h-1.9l-4.8,11.2h1.8l1.1-2.9h5.7l1.1,2.9h1.8L133,6.4z M129.7,13.5l2.3-5.5l2.3,5.5L129.7,13.5z%27 id=%27path3780%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 156.47655,5.8917384 0,2.1797 0.46093,2.3983996 1.82813,0 0.39844,-2.3983996 0,-2.1797 z%27 id=%27path5008-2%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 152.51561,5.8906384 0,2.1797 0.46094,2.3983996 1.82812,0 0.39844,-2.3983996 0,-2.1797 z%27 id=%27path5008-2-8%27 /%3E%3Crect id=%27svg_1-7-2%27 height=%272%27 width=%2712%27 y=%2764%27 x=%2754%27 style=%27fill:%236e6e6e;%27 /%3E%3Crect id=%27svg_1-7-2-2%27 height=%273%27 width=%273%27 y=%2752%27 x=%2780%27 style=%27fill:%236e6e6e;%27 /%3E%3Crect style=%27fill:%236e6e6e;%27 x=%2785%27 y=%2752%27 width=%273%27 height=%273%27 id=%27rect4561%27 /%3E%3Crect style=%27fill:%236e6e6e;%27 x=%2780%27 y=%2758%27 width=%273%27 height=%273%27 id=%27rect4563%27 /%3E%3Crect id=%27rect4565%27 height=%273%27 width=%273%27 y=%2758%27 x=%2785%27 style=%27fill:%236e6e6e;%27 /%3E%3Crect id=%27rect4567%27 height=%273%27 width=%273%27 y=%2764%27 x=%2780%27 style=%27fill:%236e6e6e;%27 /%3E%3Crect style=%27fill:%236e6e6e;%27 x=%2785%27 y=%2764%27 width=%273%27 height=%273%27 id=%27rect4569%27 /%3E%3Ccircle style=%27opacity:1;fill:none;stroke:%236e6e6e;stroke-width:2;%27 id=%27path4571%27 cx=%27110.06081%27 cy=%2757.939209%27 r=%274.7438836%27 /%3E%3Crect style=%27fill:%236e6e6e;%27 x=%27116.64566%27 y=%27-31.79752%27 width=%274.229713%27 height=%276.4053884%27 id=%27rect4563-2%27 transform=%27matrix%280.70710678,0.70710678,-0.70710678,0.70710678,0,0%29%27 /%3E%3Cpath style=%27fill:%236e6e6e;fill-rule:evenodd;%27 d=%27M 125,56 138.77027,56.095 132,64 Z%27 id=%27path4613%27 /%3E%3Cpath id=%27path4615%27 d=%27M 149,64 162.77027,63.905 156,56 Z%27 style=%27fill:%236e6e6e;fill-rule:evenodd;%27 /%3E%3Crect style=%27fill:%236e6e6e;%27 x=%2754%27 y=%2753%27 width=%2712%27 height=%272%27 id=%27rect4638%27 /%3E%3Crect id=%27svg_1-7-2-24%27 height=%272%27 width=%2713%27 y=%27-56%27 x=%2753%27 style=%27fill:%236e6e6e;%27 transform=%27matrix%280,1,-1,0,0,0%29%27 /%3E%3Crect transform=%27matrix%280,1,-1,0,0,0%29%27 style=%27fill:%236e6e6e;%27 x=%2753%27 y=%27-66%27 width=%2713%27 height=%272%27 id=%27rect4657%27 /%3E%3Crect id=%27rect4659%27 height=%271%27 width=%2712%27 y=%2757%27 x=%2754%27 style=%27fill:%236e6e6e;%27 /%3E%3Crect style=%27fill:%23ffffff;%27 x=%2754%27 y=%2788%27 width=%2712%27 height=%272%27 id=%27rect4661%27 /%3E%3Crect style=%27fill:%23ffffff;%27 x=%2780%27 y=%2776%27 width=%273%27 height=%273%27 id=%27rect4663%27 /%3E%3Crect id=%27rect4665%27 height=%273%27 width=%273%27 y=%2776%27 x=%2785%27 style=%27fill:%23ffffff;%27 /%3E%3Crect id=%27rect4667%27 height=%273%27 width=%273%27 y=%2782%27 x=%2780%27 style=%27fill:%23ffffff;%27 /%3E%3Crect style=%27fill:%23ffffff;%27 x=%2785%27 y=%2782%27 width=%273%27 height=%273%27 id=%27rect4669%27 /%3E%3Crect style=%27fill:%23ffffff;%27 x=%2780%27 y=%2788%27 width=%273%27 height=%273%27 id=%27rect4671%27 /%3E%3Crect id=%27rect4673%27 height=%273%27 width=%273%27 y=%2788%27 x=%2785%27 style=%27fill:%23ffffff;%27 /%3E%3Ccircle r=%274.7438836%27 cy=%2781.939331%27 cx=%27110.06081%27 id=%27circle4675%27 style=%27opacity:1;fill:none;stroke:%23ffffff;stroke-width:2;%27 /%3E%3Crect transform=%27matrix%280.70710678,0.70710678,-0.70710678,0.70710678,0,0%29%27 id=%27rect4677%27 height=%276.4053884%27 width=%274.229713%27 y=%27-14.826816%27 x=%27133.6163%27 style=%27fill:%23ffffff;%27 /%3E%3Cpath id=%27path4679%27 d=%27m 125,80.000005 13.77027,0.09499 L 132,87.999992 Z%27 style=%27fill:%23ffffff;%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27M 149,88.0002 162.77027,87.9052 156,80.0002 Z%27 id=%27path4681%27 /%3E%3Crect id=%27rect4683%27 height=%272%27 width=%2712%27 y=%2777%27 x=%2754%27 style=%27fill:%23ffffff;%27 /%3E%3Crect transform=%27matrix%280,1,-1,0,0,0%29%27 style=%27fill:%23ffffff;%27 x=%2777%27 y=%27-56%27 width=%2713%27 height=%272%27 id=%27rect4685%27 /%3E%3Crect id=%27rect4687%27 height=%272%27 width=%2713%27 y=%27-66%27 x=%2777%27 style=%27fill:%23ffffff;%27 transform=%27matrix%280,1,-1,0,0,0%29%27 /%3E%3Crect style=%27fill:%23ffffff;%27 x=%2754%27 y=%2781%27 width=%2712%27 height=%271%27 id=%27rect4689%27 /%3E%3Crect id=%27rect4761-1%27 height=%272%27 width=%2716%27 y=%27101%27 x=%2776%27 style=%27fill:%23ffffff;%27 /%3E%3Crect id=%27rect4761-0%27 height=%272%27 width=%2716%27 y=%27105%27 x=%2776%27 style=%27fill:%23ffffff;%27 /%3E%3Crect id=%27rect4761-7%27 height=%272%27 width=%279%27 y=%27109%27 x=%2776%27 style=%27fill:%23ffffff;%27 /%3E%3Crect id=%27rect4761-1-1%27 height=%272%27 width=%2712%27 y=%27125%27 x=%2776%27 style=%27fill:%23ffffff;%27 /%3E%3Crect id=%27rect4761-1-1-4%27 height=%272%27 width=%2710%27 y=%27137%27 x=%2776%27 style=%27fill:%23ffffff;%27 /%3E%3Crect id=%27rect4761-1-1-4-4%27 height=%272%27 width=%2710%27 y=%27129%27 x=%2782%27 style=%27fill:%23ffffff;%27 /%3E%3Crect id=%27rect4761-1-1-4-4-3%27 height=%272%27 width=%279%27 y=%27133%27 x=%2782%27 style=%27fill:%23ffffff;%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 36.398438,100.0254 c -0.423362,-0.013 -0.846847,0.01 -1.265626,0.062 -1.656562,0.2196 -3.244567,0.9739 -4.507812,2.2266 L 29,100.5991 l -2.324219,7.7129 7.826172,-1.9062 -1.804687,-1.9063 c 1.597702,-1.5308 4.048706,-1.8453 5.984375,-0.7207 1.971162,1.1452 2.881954,3.3975 2.308593,5.5508 -0.573361,2.1533 -2.533865,3.6953 -4.830078,3.6953 l 0,3.0742 c 3.550756,0 6.710442,-2.4113 7.650391,-5.9414 0.939949,-3.5301 -0.618463,-7.2736 -3.710938,-9.0703 -1.159678,-0.6738 -2.431087,-1.0231 -3.701171,-1.0625 z%27 id=%27path4138%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 59.722656,99.9629 c -1.270084,0.039 -2.541493,0.3887 -3.701172,1.0625 -3.092475,1.7967 -4.650886,5.5402 -3.710937,9.0703 0.939949,3.5301 4.09768,5.9414 7.648437,5.9414 l 0,-3.0742 c -2.296214,0 -4.256717,-1.542 -4.830078,-3.6953 -0.573361,-2.1533 0.337432,-4.4056 2.308594,-5.5508 1.935731,-1.1246 4.38863,-0.8102 5.986326,0.7207 l -1.806638,1.9063 7.828128,1.9062 -2.32422,-7.7129 -1.62696,1.7168 c -1.26338,-1.2531 -2.848917,-2.0088 -4.505855,-2.2285 -0.418778,-0.055 -0.842263,-0.076 -1.265625,-0.062 z%27 id=%27path4138-1%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 10.5,100 0,2 -2.4999996,0 L 12,107 l 4,-5 -2.5,0 0,-2 -3,0 z%27 id=%27path3055-0-77%27 /%3E%3Cpath style=%27fill:none;stroke:%23ffffff;%27 d=%27m 4.9850574,108.015 14.0298856,-0.03%27 id=%27path5244-5-0-5%27 /%3E%3Cpath style=%27fill:none;stroke:%23ffffff;%27 d=%27m 4.9849874,132.015 14.0298866,-0.03%27 id=%27path5244-5-0-5-8%27 /%3E%3Cpath style=%27color:%23000000;fill:%236e6e6e;%27 d=%27m 36.398438,123.9629 c -0.423362,-0.013 -0.846847,0.01 -1.265626,0.062 -1.656562,0.2196 -3.244567,0.9739 -4.507812,2.2266 L 29,124.5366 l -2.324219,7.7129 7.826172,-1.9062 -1.804687,-1.9063 c 1.597702,-1.5308 4.048706,-1.8453 5.984375,-0.7207 1.971162,1.1453 2.881954,3.3975 2.308593,5.5508 -0.573361,2.1533 -2.533864,3.6953 -4.830078,3.6953 l 0,3.0742 c 3.550757,0 6.710442,-2.4093 7.650391,-5.9394 0.939949,-3.5301 -0.618463,-7.2756 -3.710938,-9.0723 -1.159678,-0.6737 -2.431087,-1.0231 -3.701171,-1.0625 z%27 id=%27path4138-12%27 /%3E%3Cpath style=%27color:%23000000;fill:%236e6e6e;%27 d=%27m 59.722656,123.9629 c -1.270084,0.039 -2.541493,0.3888 -3.701172,1.0625 -3.092475,1.7967 -4.650886,5.5422 -3.710937,9.0723 0.939949,3.5301 4.09768,5.9394 7.648437,5.9394 l 0,-3.0742 c -2.296214,0 -4.256717,-1.542 -4.830078,-3.6953 -0.573361,-2.1533 0.337432,-4.4055 2.308594,-5.5508 1.935731,-1.1246 4.38863,-0.8102 5.986326,0.7207 l -1.806638,1.9063 7.828128,1.9062 -2.32422,-7.7129 -1.62696,1.7168 c -1.26338,-1.2531 -2.848917,-2.0088 -4.505855,-2.2285 -0.418778,-0.055 -0.842263,-0.076 -1.265625,-0.062 z%27 id=%27path4138-1-3%27 /%3E%3Cpath id=%27path6191%27 d=%27m 10.5,116 0,-2 -2.4999996,0 L 12,109 l 4,5 -2.5,0 0,2 -3,0 z%27 style=%27fill:%23ffffff;stroke-width:1.96599996;%27 /%3E%3Cpath style=%27fill:%23ffffff;stroke-width:1.96599996;%27 d=%27m 10.5,129 0,-2 -2.4999996,0 L 12,122 l 4,5 -2.5,0 0,2 -3,0 z%27 id=%27path6193%27 /%3E%3Cpath id=%27path6195%27 d=%27m 10.5,135 0,2 -2.4999996,0 L 12,142 l 4,-5 -2.5,0 0,-2 -3,0 z%27 style=%27fill:%23ffffff;stroke-width:1.96599996;%27 /%3E%3Cpath sodipodi:type=%27star%27 style=%27fill:%236e6e6e;%27 id=%27path4500%27 sodipodi:sides=%273%27 sodipodi:cx=%2711.55581%27 sodipodi:cy=%2760.073242%27 sodipodi:r1=%275.1116104%27 sodipodi:r2=%272.5558052%27 sodipodi:arg1=%270%27 sodipodi:arg2=%271.0471976%27 inkscape:flatsided=%27false%27 inkscape:rounded=%270%27 inkscape:randomized=%270%27 d=%27m 16.66742,60.073242 -3.833708,2.213392 -3.8337072,2.213393 0,-4.426785 0,-4.426784 3.8337082,2.213392 z%27 inkscape:transform-center-x=%27-1.2779026%27 /%3E%3Cpath inkscape:transform-center-x=%271.277902%27 d=%27m -31.500004,60.073242 -3.833708,2.213392 -3.833707,2.213393 0,-4.426785 0,-4.426784 3.833707,2.213392 z%27 inkscape:randomized=%270%27 inkscape:rounded=%270%27 inkscape:flatsided=%27false%27 sodipodi:arg2=%271.0471976%27 sodipodi:arg1=%270%27 sodipodi:r2=%272.5558052%27 sodipodi:r1=%275.1116104%27 sodipodi:cy=%2760.073242%27 sodipodi:cx=%27-36.611614%27 sodipodi:sides=%273%27 id=%27path4502%27 style=%27fill:%236e6e6e;%27 sodipodi:type=%27star%27 transform=%27scale%28-1,1%29%27 /%3E%3Cpath d=%27m 16.66742,60.073212 -3.833708,2.213392 -3.8337072,2.213392 0,-4.426784 0,-4.426785 3.8337082,2.213392 z%27 inkscape:randomized=%270%27 inkscape:rounded=%270%27 inkscape:flatsided=%27false%27 sodipodi:arg2=%271.0471976%27 sodipodi:arg1=%270%27 sodipodi:r2=%272.5558052%27 sodipodi:r1=%275.1116104%27 sodipodi:cy=%2760.073212%27 sodipodi:cx=%2711.55581%27 sodipodi:sides=%273%27 id=%27path4504%27 style=%27fill:%236e6e6e;%27 sodipodi:type=%27star%27 transform=%27matrix%280,1,-1,0,72.0074,71.7877%29%27 inkscape:transform-center-y=%271.2779029%27 /%3E%3Cpath inkscape:transform-center-y=%27-1.2779026%27 transform=%27matrix%280,-1,-1,0,96,96%29%27 sodipodi:type=%27star%27 style=%27fill:%236e6e6e;%27 id=%27path4506%27 sodipodi:sides=%273%27 sodipodi:cx=%2711.55581%27 sodipodi:cy=%2760.073212%27 sodipodi:r1=%275.1116104%27 sodipodi:r2=%272.5558052%27 sodipodi:arg1=%270%27 sodipodi:arg2=%271.0471976%27 inkscape:flatsided=%27false%27 inkscape:rounded=%270%27 inkscape:randomized=%270%27 d=%27m 16.66742,60.073212 -3.833708,2.213392 -3.8337072,2.213392 0,-4.426784 0,-4.426785 3.8337082,2.213392 z%27 /%3E%3Cpath id=%27path4615-5%27 d=%27m 171.82574,65.174193 16.34854,0 -8.17427,-13.348454 z%27 style=%27fill:%23f9a825;fill-rule:evenodd;stroke:%23f9a825;stroke-width:2;%27 /%3E%3Cpath style=%27opacity:1;fill:%23ffffff;%27 d=%27m 179,55 0,6 2,0 0,-6%27 id=%27path4300%27 /%3E%3Cpath style=%27opacity:1;fill:%23ffffff;%27 d=%27m 179,62 0,2 2,0 0,-2%27 id=%27path4300-6%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27M 99.994369,113.0221 102,114.98353 l 7,-6.9558 3,0.97227 2,-1 1,-2 0,-3 -3,3 -3,-3 3,-3 -3,0 -2,1 -1,2 0.99437,3.0221 z%27 id=%27path4268%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 234,6 0,2 -5,5 0,5 -2,0 0,-5 -5,-5 0,-2%27 id=%27path3546%27 /%3E%3Cg transform=%27matrix%281.3333328,0,0,-1.5999992,-139.9999,127.19999%29%27 id=%27g4383-6%27%3E%3Crect id=%27rect4385-2%27 height=%271%27 width=%276%27 y=%2712.625005%27 x=%27198%27 style=%27fill:%23ffffff;stroke:%23000000;stroke-width:0%27 /%3E%3Crect style=%27fill:%23ffffff;stroke:%23000000;stroke-width:0%27 x=%27198%27 y=%2715.125007%27 width=%278%27 height=%271%27 id=%27rect4387-9%27 /%3E%3Crect style=%27fill:%23ffffff;stroke:%23000000;stroke-width:0%27 x=%27198%27 y=%277.6250024%27 width=%273%27 height=%271%27 id=%27rect4389-1-0%27 /%3E%3Crect style=%27fill:%23ffffff;stroke:%23000000;stroke-width:0%27 x=%27198%27 y=%2710.125004%27 width=%274%27 height=%271%27 id=%27rect4389-1-9%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 207.00001,16.375004 0,-5.625005 -2.25,0 3,-3.1250014 3,3.1250014 -2.25,0 0,5.625005 -1.5,0%27 id=%27path4402%27 /%3E%3C/g%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 164,100 0,3 -6,6 0,7 -4,0 0,-7 -6,-6 0,-3%27 id=%27path3546-2-2%27 /%3E%3Cpath id=%27path4402-5-7%27 d=%27m 15,41 0,-7 -4,0 0,3 -5,-4 5,-4 0,3 6,0 0,9%27 style=%27fill:%23ffffff;%27 /%3E%3C/svg%3E%0A")}.light{--t42-json-icons: url("data:image/svg+xml,%3C%3Fxml version=%271.0%27 encoding=%27UTF-8%27 standalone=%27no%27%3F%3E%3Csvg xmlns:dc=%27http://purl.org/dc/elements/1.1/%27 xmlns:cc=%27http://creativecommons.org/ns%23%27 xmlns:rdf=%27http://www.w3.org/1999/02/22-rdf-syntax-ns%23%27 xmlns:svg=%27http://www.w3.org/2000/svg%27 xmlns=%27http://www.w3.org/2000/svg%27 xmlns:sodipodi=%27http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd%27 xmlns:inkscape=%27http://www.inkscape.org/namespaces/inkscape%27 width=%27240%27 height=%27144%27 id=%27svg4136%27 version=%271.1%27 inkscape:version=%270.91 r13725%27 sodipodi:docname=%27jsoneditor-icons.svg%27%3E%3Ctitle id=%27title6512%27%3EJSON Editor Icons%3C/title%3E%3Crect id=%27svg_1-7%27 height=%2716%27 width=%2716%27 y=%273.999995%27 x=%2728.000006%27 style=%27fill:%23ff511f;%27 /%3E%3Crect x=%277%27 y=%2711%27 width=%2710%27 height=%272%27 id=%27svg_1-1%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect x=%2711%27 y=%277%27 width=%272%27 height=%2710%27 id=%27svg_1-1-1%27 style=%27fill:%230d0d0d;%27 /%3E%3Cg id=%27g4299-3%27 transform=%27matrix%280.70710678,-0.70710678,0.70710678,0.70710678,19.029435,12.000001%29%27 style=%27%27%3E%3Crect x=%277%27 y=%2711%27 width=%2710%27 height=%272%27 id=%27svg_1-1-0%27 style=%27fill:%23ffffff;%27 /%3E%3Crect x=%2711%27 y=%277%27 width=%272%27 height=%2710%27 id=%27svg_1-1-1-9%27 style=%27fill:%23ffffff;%27 /%3E%3C/g%3E%3Crect height=%277%27 width=%277%27 y=%277%27 x=%2755%27 style=%27fill:%230d0d0d;stroke-width:1;stroke:%230d0d0d%27 /%3E%3Crect id=%27svg_1-7-5-7%27 height=%277%27 width=%277%27 y=%2710%27 x=%2758%27 style=%27fill:%230d0d0d;stroke-width:1;stroke:%23ffffff%27 /%3E%3Cg id=%27g4378%27%3E%3Crect style=%27fill:%230d0d0d;%27 x=%27198%27 y=%2711%27 width=%278%27 height=%272%27 id=%27svg_1-7-5-3%27 /%3E%3Crect id=%27rect4374%27 height=%272%27 width=%2712%27 y=%277%27 x=%27198%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect id=%27rect4376%27 height=%272%27 width=%274%27 y=%2715%27 x=%27198%27 style=%27fill:%230d0d0d;%27 /%3E%3C/g%3E%3Cg transform=%27matrix%281,0,0,-1,-23.999995,23.999995%29%27 id=%27g4383%27%3E%3Crect id=%27rect4385%27 height=%272%27 width=%278%27 y=%2711%27 x=%27198%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect style=%27fill:%230d0d0d;%27 x=%27198%27 y=%277%27 width=%2712%27 height=%272%27 id=%27rect4387%27 /%3E%3Crect style=%27fill:%230d0d0d;%27 x=%27198%27 y=%2715%27 width=%274%27 height=%272%27 id=%27rect4389%27 /%3E%3C/g%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 85.10447,6.0157384 -0.0156,1.4063 c 3.02669,-0.2402 0.33008,3.6507996 2.48438,4.5780996 -2.18694,1.0938 0.49191,4.9069 -2.45313,4.5781 l -0.0156,1.4219 c 5.70828,0.559 1.03264,-5.1005 4.70313,-5.2656 l 0,-1.4063 c -3.61303,-0.027 1.11893,-5.7069996 -4.70313,-5.3124996 z%27 id=%27path4351%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 82.78125,5.9984384 0.0156,1.4063 c -3.02668,-0.2402 -0.33007,3.6506996 -2.48437,4.5780996 2.18694,1.0938 -0.49192,4.9069 2.45312,4.5781 l 0.0156,1.4219 c -5.70827,0.559 -1.03263,-5.1004 -4.70312,-5.2656 l 0,-1.4063 c 3.61303,-0.027 -1.11894,-5.7070996 4.70312,-5.3124996 z%27 id=%27path4351-9%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 103.719,5.6719384 0,12.7187996 3.03125,0 0,-1.5313 -1.34375,0 0,-9.6249996 1.375,0 0,-1.5625 z%27 id=%27path2987%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 112.2185,5.6721984 0,12.7187996 -3.03125,0 0,-1.5313 1.34375,0 0,-9.6249996 -1.375,0 0,-1.5625 z%27 id=%27path2987-1%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27M133,6.4h-1.9l-4.8,11.2h1.8l1.1-2.9h5.7l1.1,2.9h1.8L133,6.4z M129.7,13.5l2.3-5.5l2.3,5.5L129.7,13.5z%27 id=%27path3780%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 156.47655,5.8917384 0,2.1797 0.46093,2.3983996 1.82813,0 0.39844,-2.3983996 0,-2.1797 z%27 id=%27path5008-2%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 152.51561,5.8906384 0,2.1797 0.46094,2.3983996 1.82812,0 0.39844,-2.3983996 0,-2.1797 z%27 id=%27path5008-2-8%27 /%3E%3Crect id=%27svg_1-7-2%27 height=%272%27 width=%2712%27 y=%2764%27 x=%2754%27 style=%27fill:%236e6e6e;%27 /%3E%3Crect id=%27svg_1-7-2-2%27 height=%273%27 width=%273%27 y=%2752%27 x=%2780%27 style=%27fill:%236e6e6e;%27 /%3E%3Crect style=%27fill:%236e6e6e;%27 x=%2785%27 y=%2752%27 width=%273%27 height=%273%27 id=%27rect4561%27 /%3E%3Crect style=%27fill:%236e6e6e;%27 x=%2780%27 y=%2758%27 width=%273%27 height=%273%27 id=%27rect4563%27 /%3E%3Crect id=%27rect4565%27 height=%273%27 width=%273%27 y=%2758%27 x=%2785%27 style=%27fill:%236e6e6e;%27 /%3E%3Crect id=%27rect4567%27 height=%273%27 width=%273%27 y=%2764%27 x=%2780%27 style=%27fill:%236e6e6e;%27 /%3E%3Crect style=%27fill:%236e6e6e;%27 x=%2785%27 y=%2764%27 width=%273%27 height=%273%27 id=%27rect4569%27 /%3E%3Ccircle style=%27opacity:1;fill:none;stroke:%236e6e6e;stroke-width:2;%27 id=%27path4571%27 cx=%27110.06081%27 cy=%2757.939209%27 r=%274.7438836%27 /%3E%3Crect style=%27fill:%236e6e6e;%27 x=%27116.64566%27 y=%27-31.79752%27 width=%274.229713%27 height=%276.4053884%27 id=%27rect4563-2%27 transform=%27matrix%280.70710678,0.70710678,-0.70710678,0.70710678,0,0%29%27 /%3E%3Cpath style=%27fill:%236e6e6e;fill-rule:evenodd;%27 d=%27M 125,56 138.77027,56.095 132,64 Z%27 id=%27path4613%27 /%3E%3Cpath id=%27path4615%27 d=%27M 149,64 162.77027,63.905 156,56 Z%27 style=%27fill:%236e6e6e;fill-rule:evenodd;%27 /%3E%3Crect style=%27fill:%236e6e6e;%27 x=%2754%27 y=%2753%27 width=%2712%27 height=%272%27 id=%27rect4638%27 /%3E%3Crect id=%27svg_1-7-2-24%27 height=%272%27 width=%2713%27 y=%27-56%27 x=%2753%27 style=%27fill:%236e6e6e;%27 transform=%27matrix%280,1,-1,0,0,0%29%27 /%3E%3Crect transform=%27matrix%280,1,-1,0,0,0%29%27 style=%27fill:%236e6e6e;%27 x=%2753%27 y=%27-66%27 width=%2713%27 height=%272%27 id=%27rect4657%27 /%3E%3Crect id=%27rect4659%27 height=%271%27 width=%2712%27 y=%2757%27 x=%2754%27 style=%27fill:%236e6e6e;%27 /%3E%3Crect style=%27fill:%230d0d0d;%27 x=%2754%27 y=%2788%27 width=%2712%27 height=%272%27 id=%27rect4661%27 /%3E%3Crect style=%27fill:%230d0d0d;%27 x=%2780%27 y=%2776%27 width=%273%27 height=%273%27 id=%27rect4663%27 /%3E%3Crect id=%27rect4665%27 height=%273%27 width=%273%27 y=%2776%27 x=%2785%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect id=%27rect4667%27 height=%273%27 width=%273%27 y=%2782%27 x=%2780%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect style=%27fill:%230d0d0d;%27 x=%2785%27 y=%2782%27 width=%273%27 height=%273%27 id=%27rect4669%27 /%3E%3Crect style=%27fill:%230d0d0d;%27 x=%2780%27 y=%2788%27 width=%273%27 height=%273%27 id=%27rect4671%27 /%3E%3Crect id=%27rect4673%27 height=%273%27 width=%273%27 y=%2788%27 x=%2785%27 style=%27fill:%230d0d0d;%27 /%3E%3Ccircle r=%274.7438836%27 cy=%2781.939331%27 cx=%27110.06081%27 id=%27circle4675%27 style=%27opacity:1;fill:none;stroke:%230d0d0d;stroke-width:2;%27 /%3E%3Crect transform=%27matrix%280.70710678,0.70710678,-0.70710678,0.70710678,0,0%29%27 id=%27rect4677%27 height=%276.4053884%27 width=%274.229713%27 y=%27-14.826816%27 x=%27133.6163%27 style=%27fill:%230d0d0d;%27 /%3E%3Cpath id=%27path4679%27 d=%27m 125,80.000005 13.77027,0.09499 L 132,87.999992 Z%27 style=%27fill:%230d0d0d;%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27M 149,88.0002 162.77027,87.9052 156,80.0002 Z%27 id=%27path4681%27 /%3E%3Crect id=%27rect4683%27 height=%272%27 width=%2712%27 y=%2777%27 x=%2754%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect transform=%27matrix%280,1,-1,0,0,0%29%27 style=%27fill:%230d0d0d;%27 x=%2777%27 y=%27-56%27 width=%2713%27 height=%272%27 id=%27rect4685%27 /%3E%3Crect id=%27rect4687%27 height=%272%27 width=%2713%27 y=%27-66%27 x=%2777%27 style=%27fill:%230d0d0d;%27 transform=%27matrix%280,1,-1,0,0,0%29%27 /%3E%3Crect style=%27fill:%230d0d0d;%27 x=%2754%27 y=%2781%27 width=%2712%27 height=%271%27 id=%27rect4689%27 /%3E%3Crect id=%27rect4761-1%27 height=%272%27 width=%2716%27 y=%27101%27 x=%2776%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect id=%27rect4761-0%27 height=%272%27 width=%2716%27 y=%27105%27 x=%2776%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect id=%27rect4761-7%27 height=%272%27 width=%279%27 y=%27109%27 x=%2776%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect id=%27rect4761-1-1%27 height=%272%27 width=%2712%27 y=%27125%27 x=%2776%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect id=%27rect4761-1-1-4%27 height=%272%27 width=%2710%27 y=%27137%27 x=%2776%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect id=%27rect4761-1-1-4-4%27 height=%272%27 width=%2710%27 y=%27129%27 x=%2782%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect id=%27rect4761-1-1-4-4-3%27 height=%272%27 width=%279%27 y=%27133%27 x=%2782%27 style=%27fill:%230d0d0d;%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 36.398438,100.0254 c -0.423362,-0.013 -0.846847,0.01 -1.265626,0.062 -1.656562,0.2196 -3.244567,0.9739 -4.507812,2.2266 L 29,100.5991 l -2.324219,7.7129 7.826172,-1.9062 -1.804687,-1.9063 c 1.597702,-1.5308 4.048706,-1.8453 5.984375,-0.7207 1.971162,1.1452 2.881954,3.3975 2.308593,5.5508 -0.573361,2.1533 -2.533865,3.6953 -4.830078,3.6953 l 0,3.0742 c 3.550756,0 6.710442,-2.4113 7.650391,-5.9414 0.939949,-3.5301 -0.618463,-7.2736 -3.710938,-9.0703 -1.159678,-0.6738 -2.431087,-1.0231 -3.701171,-1.0625 z%27 id=%27path4138%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 59.722656,99.9629 c -1.270084,0.039 -2.541493,0.3887 -3.701172,1.0625 -3.092475,1.7967 -4.650886,5.5402 -3.710937,9.0703 0.939949,3.5301 4.09768,5.9414 7.648437,5.9414 l 0,-3.0742 c -2.296214,0 -4.256717,-1.542 -4.830078,-3.6953 -0.573361,-2.1533 0.337432,-4.4056 2.308594,-5.5508 1.935731,-1.1246 4.38863,-0.8102 5.986326,0.7207 l -1.806638,1.9063 7.828128,1.9062 -2.32422,-7.7129 -1.62696,1.7168 c -1.26338,-1.2531 -2.848917,-2.0088 -4.505855,-2.2285 -0.418778,-0.055 -0.842263,-0.076 -1.265625,-0.062 z%27 id=%27path4138-1%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 10.5,100 0,2 -2.4999996,0 L 12,107 l 4,-5 -2.5,0 0,-2 -3,0 z%27 id=%27path3055-0-77%27 /%3E%3Cpath style=%27fill:none;stroke:%230d0d0d;%27 d=%27m 4.9850574,108.015 14.0298856,-0.03%27 id=%27path5244-5-0-5%27 /%3E%3Cpath style=%27fill:none;stroke:%230d0d0d;%27 d=%27m 4.9849874,132.015 14.0298866,-0.03%27 id=%27path5244-5-0-5-8%27 /%3E%3Cpath style=%27color:%23000000;fill:%236e6e6e;%27 d=%27m 36.398438,123.9629 c -0.423362,-0.013 -0.846847,0.01 -1.265626,0.062 -1.656562,0.2196 -3.244567,0.9739 -4.507812,2.2266 L 29,124.5366 l -2.324219,7.7129 7.826172,-1.9062 -1.804687,-1.9063 c 1.597702,-1.5308 4.048706,-1.8453 5.984375,-0.7207 1.971162,1.1453 2.881954,3.3975 2.308593,5.5508 -0.573361,2.1533 -2.533864,3.6953 -4.830078,3.6953 l 0,3.0742 c 3.550757,0 6.710442,-2.4093 7.650391,-5.9394 0.939949,-3.5301 -0.618463,-7.2756 -3.710938,-9.0723 -1.159678,-0.6737 -2.431087,-1.0231 -3.701171,-1.0625 z%27 id=%27path4138-12%27 /%3E%3Cpath style=%27color:%23000000;fill:%236e6e6e;%27 d=%27m 59.722656,123.9629 c -1.270084,0.039 -2.541493,0.3888 -3.701172,1.0625 -3.092475,1.7967 -4.650886,5.5422 -3.710937,9.0723 0.939949,3.5301 4.09768,5.9394 7.648437,5.9394 l 0,-3.0742 c -2.296214,0 -4.256717,-1.542 -4.830078,-3.6953 -0.573361,-2.1533 0.337432,-4.4055 2.308594,-5.5508 1.935731,-1.1246 4.38863,-0.8102 5.986326,0.7207 l -1.806638,1.9063 7.828128,1.9062 -2.32422,-7.7129 -1.62696,1.7168 c -1.26338,-1.2531 -2.848917,-2.0088 -4.505855,-2.2285 -0.418778,-0.055 -0.842263,-0.076 -1.265625,-0.062 z%27 id=%27path4138-1-3%27 /%3E%3Cpath id=%27path6191%27 d=%27m 10.5,116 0,-2 -2.4999996,0 L 12,109 l 4,5 -2.5,0 0,2 -3,0 z%27 style=%27fill:%230d0d0d;stroke-width:2;%27 /%3E%3Cpath style=%27fill:%230d0d0d;stroke-width:2;%27 d=%27m 10.5,129 0,-2 -2.4999996,0 L 12,122 l 4,5 -2.5,0 0,2 -3,0 z%27 id=%27path6193%27 /%3E%3Cpath id=%27path6195%27 d=%27m 10.5,135 0,2 -2.4999996,0 L 12,142 l 4,-5 -2.5,0 0,-2 -3,0 z%27 style=%27fill:%230d0d0d;stroke-width:2;%27 /%3E%3Cpath sodipodi:type=%27star%27 style=%27fill:%236e6e6e;%27 id=%27path4500%27 sodipodi:sides=%273%27 sodipodi:cx=%2711.55581%27 sodipodi:cy=%2760.073242%27 sodipodi:r1=%275.1116104%27 sodipodi:r2=%272.5558052%27 sodipodi:arg1=%270%27 sodipodi:arg2=%271.0471976%27 inkscape:flatsided=%27false%27 inkscape:rounded=%270%27 inkscape:randomized=%270%27 d=%27m 16.66742,60.073242 -3.833708,2.213392 -3.8337072,2.213393 0,-4.426785 0,-4.426784 3.8337082,2.213392 z%27 inkscape:transform-center-x=%27-1.2779026%27 /%3E%3Cpath inkscape:transform-center-x=%271.277902%27 d=%27m -31.500004,60.073242 -3.833708,2.213392 -3.833707,2.213393 0,-4.426785 0,-4.426784 3.833707,2.213392 z%27 inkscape:randomized=%270%27 inkscape:rounded=%270%27 inkscape:flatsided=%27false%27 sodipodi:arg2=%271.0471976%27 sodipodi:arg1=%270%27 sodipodi:r2=%272.5558052%27 sodipodi:r1=%275.1116104%27 sodipodi:cy=%2760.073242%27 sodipodi:cx=%27-36.611614%27 sodipodi:sides=%273%27 id=%27path4502%27 style=%27fill:%236e6e6e;%27 sodipodi:type=%27star%27 transform=%27scale%28-1,1%29%27 /%3E%3Cpath d=%27m 16.66742,60.073212 -3.833708,2.213392 -3.8337072,2.213392 0,-4.426784 0,-4.426785 3.8337082,2.213392 z%27 inkscape:randomized=%270%27 inkscape:rounded=%270%27 inkscape:flatsided=%27false%27 sodipodi:arg2=%271.0471976%27 sodipodi:arg1=%270%27 sodipodi:r2=%272.5558052%27 sodipodi:r1=%275.1116104%27 sodipodi:cy=%2760.073212%27 sodipodi:cx=%2711.55581%27 sodipodi:sides=%273%27 id=%27path4504%27 style=%27fill:%236e6e6e;%27 sodipodi:type=%27star%27 transform=%27matrix%280,1,-1,0,72.0074,71.7877%29%27 inkscape:transform-center-y=%271.2779029%27 /%3E%3Cpath inkscape:transform-center-y=%27-1.2779026%27 transform=%27matrix%280,-1,-1,0,96,96%29%27 sodipodi:type=%27star%27 style=%27fill:%236e6e6e;%27 id=%27path4506%27 sodipodi:sides=%273%27 sodipodi:cx=%2711.55581%27 sodipodi:cy=%2760.073212%27 sodipodi:r1=%275.1116104%27 sodipodi:r2=%272.5558052%27 sodipodi:arg1=%270%27 sodipodi:arg2=%271.0471976%27 inkscape:flatsided=%27false%27 inkscape:rounded=%270%27 inkscape:randomized=%270%27 d=%27m 16.66742,60.073212 -3.833708,2.213392 -3.8337072,2.213392 0,-4.426784 0,-4.426785 3.8337082,2.213392 z%27 /%3E%3Cpath id=%27path4615-5%27 d=%27m 171.82574,65.174193 16.34854,0 -8.17427,-13.348454 z%27 style=%27fill:%23f9a825;fill-rule:evenodd;stroke:%23f9a825;stroke-width:2;%27 /%3E%3Cpath style=%27opacity:1;fill:%23ffffff;%27 d=%27m 179,55 0,6 2,0 0,-6%27 id=%27path4300%27 /%3E%3Cpath style=%27opacity:1;fill:%23ffffff;%27 d=%27m 179,62 0,2 2,0 0,-2%27 id=%27path4300-6%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27M 99.994369,113.0221 102,114.98353 l 7,-6.9558 3,0.97227 2,-1 1,-2 0,-3 -3,3 -3,-3 3,-3 -3,0 -2,1 -1,2 0.99437,3.0221 z%27 id=%27path4268%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 234,6 0,2 -5,5 0,5 -2,0 0,-5 -5,-5 0,-2%27 id=%27path3546%27 /%3E%3Cg transform=%27matrix%281.3333328,0,0,-1.5999992,-139.9999,127.19999%29%27 id=%27g4383-6%27%3E%3Crect id=%27rect4385-2%27 height=%271%27 width=%276%27 y=%2712.625005%27 x=%27198%27 style=%27fill:%230d0d0d;stroke:%23000000;stroke-width:0%27 /%3E%3Crect style=%27fill:%230d0d0d;stroke:%23000000;stroke-width:0%27 x=%27198%27 y=%2715.125007%27 width=%278%27 height=%271%27 id=%27rect4387-9%27 /%3E%3Crect style=%27fill:%230d0d0d;stroke:%23000000;stroke-width:0%27 x=%27198%27 y=%277.6250024%27 width=%273%27 height=%271%27 id=%27rect4389-1-0%27 /%3E%3Crect style=%27fill:%230d0d0d;stroke:%23000000;stroke-width:0%27 x=%27198%27 y=%2710.125004%27 width=%274%27 height=%271%27 id=%27rect4389-1-9%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 207.00001,16.375004 0,-5.625005 -2.25,0 3,-3.1250014 3,3.1250014 -2.25,0 0,5.625005 -1.5,0%27 id=%27path4402%27 /%3E%3C/g%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 164,100 0,3 -6,6 0,7 -4,0 0,-7 -6,-6 0,-3%27 id=%27path3546-2-2%27 /%3E%3Cpath id=%27path4402-5-7%27 d=%27m 15,41 0,-7 -4,0 0,3 -5,-4 5,-4 0,3 6,0 0,9%27 style=%27fill:%230d0d0d;%27 /%3E%3C/svg%3E%0A")}body{/*! + * Selectr 2.4.13 + * http://mobius.ovh/docs/selectr + * + * Released under the MIT license + */}body .jsoneditor,body .jsoneditor-modal{-webkit-text-size-adjust:none;text-size-adjust:none}body .jsoneditor input,body .jsoneditor input:not([type]),body .jsoneditor input[type="text"],body .jsoneditor input[type="search"],body .jsoneditor-modal input,body .jsoneditor-modal input:not([type]),body .jsoneditor-modal input[type="text"],body .jsoneditor-modal input[type="search"]{height:auto;border:inherit;box-shadow:none;font-size:inherit;box-sizing:inherit;padding:inherit;font-family:inherit;transition:none;line-height:inherit}body .jsoneditor input:focus,body .jsoneditor input:not([type]):focus,body .jsoneditor input[type="text"]:focus,body .jsoneditor input[type="search"]:focus,body .jsoneditor-modal input:focus,body .jsoneditor-modal input:not([type]):focus,body .jsoneditor-modal input[type="text"]:focus,body .jsoneditor-modal input[type="search"]:focus{border:inherit;box-shadow:inherit}body .jsoneditor textarea,body .jsoneditor-modal textarea{height:inherit}body .jsoneditor select,body .jsoneditor-modal select{display:inherit;height:inherit}body .jsoneditor label,body .jsoneditor-modal label{font-size:inherit;font-weight:inherit;color:inherit}body .jsoneditor table,body .jsoneditor-modal table{border-collapse:collapse;width:auto}body .jsoneditor td,body .jsoneditor th,body .jsoneditor-modal td,body .jsoneditor-modal th{padding:0;display:table-cell;text-align:left;vertical-align:inherit;border-radius:inherit}body .jsoneditor .autocomplete.dropdown{position:absolute;background:var(--t42-content-color);box-shadow:var(--t42-shadow);border:1px solid var(--t42-color-opacity-10);overflow-x:hidden;overflow-y:auto;cursor:default;margin:0;padding:5px;text-align:left;outline:0;font-family:var(--bs-font-monospace);font-size:var(--t42-font-size)}body .jsoneditor .autocomplete.dropdown .item{color:var(--t42-content-color)}body .jsoneditor .autocomplete.dropdown .item.hover{background-color:Rgb(var(--t42-bg-mid))}body .jsoneditor .autocomplete.hint{color:var(--t42-content-color);top:4px;left:4px}body .jsoneditor-contextmenu-root{position:relative;width:0;height:0}body .jsoneditor-contextmenu{position:absolute;box-sizing:content-box;z-index:2}body .jsoneditor-contextmenu .jsoneditor-menu{position:relative;left:0;top:0;width:128px;height:auto;background:var(--t42-content-color);border:1px solid var(--t42-color-opacity-10);box-shadow:var(--t42-shadow);list-style:none;margin:0;padding:0}body .jsoneditor-contextmenu .jsoneditor-menu button{position:relative;padding:0 8px 0 0;margin:0;width:128px;height:auto;border:none;cursor:pointer;color:var(--t42-content-color);background:transparent;font-size:var(--t42-font-size);font-family:var(--t42-font-family);box-sizing:border-box;text-align:left}body .jsoneditor-contextmenu .jsoneditor-menu button::-moz-focus-inner{padding:0;border:0}body .jsoneditor-contextmenu .jsoneditor-menu button.jsoneditor-default{width:96px}body .jsoneditor-contextmenu .jsoneditor-menu button.jsoneditor-expand{float:right;width:32px;height:24px;border-left:1px solid var(--t42-color-opacity-10)}body .jsoneditor-contextmenu .jsoneditor-menu li{overflow:hidden}body .jsoneditor-contextmenu .jsoneditor-menu li ul{display:none;position:relative;left:-10px;top:0;border:none;box-shadow:inset var(--t42-shadow);padding:0 10px;-webkit-transition:all 0.3s ease-out;-moz-transition:all 0.3s ease-out;-o-transition:all 0.3s ease-out;transition:all 0.3s ease-out}body .jsoneditor-contextmenu .jsoneditor-menu li ul .jsoneditor-icon{margin-left:24px}body .jsoneditor-contextmenu .jsoneditor-menu li ul li button{padding-left:24px;animation:all ease-in-out 1s}body .jsoneditor-contextmenu .jsoneditor-menu li button .jsoneditor-expand{position:absolute;top:0;right:0;width:24px;height:24px;padding:0;margin:0 4px 0 0;background-image:"/";background-position:0 -72px}body .jsoneditor-contextmenu .jsoneditor-icon{position:absolute;top:0;left:0;width:24px;height:24px;border:none;padding:0;margin:0;background-image:"/"}body .jsoneditor-contextmenu .jsoneditor-text{padding:4px 0 4px 24px;word-wrap:break-word}body .jsoneditor-contextmenu .jsoneditor-text.jsoneditor-right-margin{padding-right:24px}body .jsoneditor-contextmenu .jsoneditor-separator{height:0;border-top:1px solid var(--t42-color-opacity-10);padding-top:5px;margin-top:5px}body .jsoneditor-contextmenu button.jsoneditor-remove .jsoneditor-icon{background-position:-24px 0}body .jsoneditor-contextmenu button.jsoneditor-append .jsoneditor-icon{background-position:0 0}body .jsoneditor-contextmenu button.jsoneditor-insert .jsoneditor-icon{background-position:0 0}body .jsoneditor-contextmenu button.jsoneditor-duplicate .jsoneditor-icon{background-position:-48px 0}body .jsoneditor-contextmenu button.jsoneditor-sort-asc .jsoneditor-icon{background-position:-168px 0}body .jsoneditor-contextmenu button.jsoneditor-sort-desc .jsoneditor-icon{background-position:-192px 0}body .jsoneditor-contextmenu button.jsoneditor-transform .jsoneditor-icon{background-position:-216px 0}body .jsoneditor-contextmenu button.jsoneditor-extract .jsoneditor-icon{background-position:0 -24px}body .jsoneditor-contextmenu button.jsoneditor-type-string .jsoneditor-icon{background-position:-144px 0}body .jsoneditor-contextmenu button.jsoneditor-type-auto .jsoneditor-icon{background-position:-120px 0}body .jsoneditor-contextmenu button.jsoneditor-type-object .jsoneditor-icon{background-position:-72px 0}body .jsoneditor-contextmenu button.jsoneditor-type-array .jsoneditor-icon{background-position:-96px 0}body .jsoneditor-contextmenu button.jsoneditor-type-modes .jsoneditor-icon{background-image:none;width:6px}body .jsoneditor-contextmenu ul,body .jsoneditor-contextmenu li{box-sizing:content-box;position:relative}body .jsoneditor-contextmenu .jsoneditor-menu button:hover,body .jsoneditor-contextmenu .jsoneditor-menu button:focus{color:var(--t42-content-color);background-color:var(--t42-color-opacity-10);outline:none}body .jsoneditor-contextmenu .jsoneditor-menu li button.jsoneditor-selected,body .jsoneditor-contextmenu .jsoneditor-menu li button.jsoneditor-selected:hover,body .jsoneditor-contextmenu .jsoneditor-menu li button.jsoneditor-selected:focus{color:var(--t42-content-color);background-color:var(--red)}body .jsoneditor-contextmenu .jsoneditor-menu li ul li button:hover,body .jsoneditor-contextmenu .jsoneditor-menu li ul li button:focus{background-color:var(--t42-color-opacity-10)}body .jsoneditor-modal{max-width:95%;border-radius:2px !important;padding:45px 15px 15px 15px !important;box-shadow:var(--t42-shadow);color:var(--t42-content-color);line-height:1.3em}body .jsoneditor-modal.jsoneditor-modal-transform{width:600px !important}body .jsoneditor-modal .pico-modal-header{position:absolute;box-sizing:border-box;top:0;left:0;width:100%;padding:0 10px;height:30px;line-height:30px;font-family:var(--t42-font-family);font-size:11pt;background:var(--primary);color:var(--t42-content-color)}body .jsoneditor-modal table{width:100%}body .jsoneditor-modal table td{padding:3px 0}body .jsoneditor-modal table td.jsoneditor-modal-input{text-align:right;padding-right:0;white-space:nowrap}body .jsoneditor-modal table td.jsoneditor-modal-actions{padding-top:15px}body .jsoneditor-modal table th{vertical-align:middle}body .jsoneditor-modal p:first-child{margin-top:0}body .jsoneditor-modal a{color:var(--primary)}body .jsoneditor-modal .jsoneditor-jmespath-block{margin-bottom:10px}body .jsoneditor-modal .pico-close{background:none !important;font-size:24px !important;top:7px !important;right:7px !important;color:var(--t42-content-color)}body .jsoneditor-modal input{padding:4px}body .jsoneditor-modal input[type="text"]{cursor:inherit}body .jsoneditor-modal input[disabled]{background:var(--t42-content-color-muted);color:var(--t42-content-color-muted)}body .jsoneditor-modal .jsoneditor-select-wrapper{position:relative;display:inline-block}body .jsoneditor-modal .jsoneditor-select-wrapper:after{content:"";width:0;height:0;border-left:5px solid transparent;border-right:5px solid transparent;border-top:6px solid #666;position:absolute;right:8px;top:14px;pointer-events:none}body .jsoneditor-modal select{padding:3px 24px 3px 10px;min-width:180px;max-width:350px;-webkit-appearance:none;-moz-appearance:none;appearance:none;text-indent:0;text-overflow:"";font-size:var(--t42-font-size);line-height:1.5em}body .jsoneditor-modal select::-ms-expand{display:none}body .jsoneditor-modal .jsoneditor-button-group input{padding:4px 10px;margin:0;border-radius:0;border-left-style:none}body .jsoneditor-modal .jsoneditor-button-group input.jsoneditor-button-first{border-top-left-radius:3px;border-bottom-left-radius:3px;border-left-style:solid}body .jsoneditor-modal .jsoneditor-button-group input.jsoneditor-button-last{border-top-right-radius:3px;border-bottom-right-radius:3px}body .jsoneditor-modal .jsoneditor-transform-preview{background:var(--t42-color-opacity-10);height:200px}body .jsoneditor-modal .jsoneditor-transform-preview.jsoneditor-error{color:var(--red)}body .jsoneditor-modal .jsoneditor-jmespath-wizard{line-height:1.2em;width:100%;padding:0;border-radius:3px}body .jsoneditor-modal .jsoneditor-jmespath-label{font-weight:bold;color:dodgerblue;margin-top:20px;margin-bottom:5px}body .jsoneditor-modal .jsoneditor-jmespath-wizard-table{width:100%;border-collapse:collapse}body .jsoneditor-modal .jsoneditor-jmespath-wizard-label{font-style:italic;margin:4px 0 2px 0}body .jsoneditor-modal .jsoneditor-inline{position:relative;display:inline-block;width:100%;padding-top:2px;padding-bottom:2px}body .jsoneditor-modal .jsoneditor-inline:not(:last-child){padding-right:2px}body .jsoneditor-modal .jsoneditor-jmespath-filter{display:flex;flex-wrap:wrap}body .jsoneditor-modal .jsoneditor-jmespath-filter-field{width:180px}body .jsoneditor-modal .jsoneditor-jmespath-filter-relation{width:100px}body .jsoneditor-modal .jsoneditor-jmespath-filter-value{min-width:180px;flex:1}body .jsoneditor-modal .jsoneditor-jmespath-sort-field{width:170px}body .jsoneditor-modal .jsoneditor-jmespath-sort-order{width:150px}body .jsoneditor-modal .jsoneditor-jmespath-select-fields{width:100%}body .jsoneditor-modal .selectr-selected{border-color:var(--t42-color-opacity-10);padding:4px 28px 4px 8px}body .jsoneditor-modal .selectr-selected .selectr-tag{background-color:var(--primary);border-radius:5px}body .jsoneditor-modal table th,body .jsoneditor-modal table td{text-align:left;vertical-align:middle;font-weight:normal;color:var(--t42-content-color);border-spacing:0;border-collapse:collapse}body .jsoneditor-modal select,body .jsoneditor-modal textarea,body .jsoneditor-modal input,body .jsoneditor-modal input[type="text"],body .jsoneditor-modal input[type="text"]:focus,body .jsoneditor-modal #query{background:#ffffff;border:1px solid var(--t42-color-opacity-10);color:var(--t42-content-color);border-radius:3px;padding:4px}body .jsoneditor-modal textarea,body .jsoneditor-modal #query{border-radius:unset}body .jsoneditor-modal,body .jsoneditor-modal table td,body .jsoneditor-modal table th,body .jsoneditor-modal select,body .jsoneditor-modal option,body .jsoneditor-modal textarea,body .jsoneditor-modal input,body .jsoneditor-modal input[type="text"],body .jsoneditor-modal #query{font-size:10.5pt;font-family:var(--t42-font-family)}body .jsoneditor-modal #query,body .jsoneditor-modal .jsoneditor-transform-preview{font-family:var(--bs-font-monospace);font-size:var(--t42-font-size);width:100%;box-sizing:border-box}body .jsoneditor-modal input[type="button"],body .jsoneditor-modal input[type="submit"]{background:var(--t42-color-opacity-10);padding:4px 20px}body .jsoneditor-modal select,body .jsoneditor-modal input{cursor:pointer}body .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-asc input.jsoneditor-button-asc,body .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-desc input.jsoneditor-button-desc{background:var(--primary);border-color:var(--primary);color:var(--t42-content-color)}body .jsoneditor{color:var(--t42-content-color);border:thin solid var(--primary);-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;width:100%;height:100%;position:relative;padding:0;line-height:100%}body div.jsoneditor-field,body div.jsoneditor-value,body a.jsoneditor-value,body div.jsoneditor-readonly,body div.jsoneditor-default{border:1px solid transparent;min-height:16px;min-width:32px;line-height:16px;padding:2px;margin:1px;word-wrap:break-word;word-break:break-word;overflow-wrap:break-word;float:left}body div.jsoneditor-field p,body div.jsoneditor-value p{margin:0}body div.jsoneditor-value.jsoneditor-empty::after{content:"value"}body div.jsoneditor-value.jsoneditor-string{color:var(--green)}body div.jsoneditor-value.jsoneditor-number{color:var(--red)}body div.jsoneditor-value.jsoneditor-boolean{color:var(--yellow)}body div.jsoneditor-value.jsoneditor-null{color:var(--primary)}body div.jsoneditor-value.jsoneditor-color-value{color:var(--t42-content-color)}body div.jsoneditor-value.jsoneditor-invalid{color:var(--white)}body div.jsoneditor-readonly{min-width:16px;color:var(--t42-content-color-muted)}body div.jsoneditor-empty{border-color:var(--t42-color-opacity-10);border-style:dashed;border-radius:2px}body div.jsoneditor-field.jsoneditor-empty::after{content:"field"}body div.jsoneditor td{vertical-align:top}body div.jsoneditor td.jsoneditor-separator{padding:3px 0;vertical-align:top;color:var(--t42-content-color-muted)}body div.jsoneditor td.jsoneditor-tree{vertical-align:top}body div.jsoneditor.busy pre.jsoneditor-preview{background:var(--t42-color-opacity-10);color:var(--t42-content-color-muted)}body div.jsoneditor.busy div.jsoneditor-busy{display:inherit}body div.jsoneditor code.jsoneditor-preview{background:none}body div.jsoneditor.jsoneditor-mode-preview pre.jsoneditor-preview{width:100%;height:100%;box-sizing:border-box;overflow:auto;padding:2px;margin:0;white-space:pre-wrap;word-break:break-all}body div.jsoneditor-default{color:var(--t42-content-color-muted);padding-left:10px}body div.jsoneditor-tree{width:100%;height:100%;position:relative;overflow:auto;background:var(--t42-content-color)}body div.jsoneditor-tree button.jsoneditor-button{width:24px;height:24px;padding:0;margin:0;border:none;cursor:pointer;background-color:transparent;background-image:"/"}body div.jsoneditor-tree button.jsoneditor-button:focus{background-color:var(--t42-color-opacity-10);outline:#e5e5e5 solid 1px}body div.jsoneditor-tree button.jsoneditor-collapsed{background-position:0 -48px}body div.jsoneditor-tree button.jsoneditor-expanded{background-position:0 -72px}body div.jsoneditor-tree button.jsoneditor-contextmenu-button{background-position:-48px -72px}body div.jsoneditor-tree button.jsoneditor-invisible{visibility:hidden;background:none}body div.jsoneditor-tree button.jsoneditor-dragarea{background-image:"/";background-position:-72px -72px;cursor:move}body div.jsoneditor-tree *:focus{outline:none}body div.jsoneditor-tree div.jsoneditor-show-more{display:inline-block;padding:3px 4px;margin:2px 0;background-color:var(--t42-color-opacity-10);border-radius:3px;color:var(--t42-content-color-muted);font-family:var(--t42-font-family);font-size:var(--t42-font-size)}body div.jsoneditor-tree div.jsoneditor-show-more a{display:inline-block;color:var(--t42-content-color-muted)}body div.jsoneditor-tree div.jsoneditor-color{display:inline-block;width:12px;height:12px;margin:4px;border:1px solid var(--t42-content-color-muted);cursor:pointer}body div.jsoneditor-tree div.jsoneditor-color.jsoneditor-color-readonly{cursor:inherit}body div.jsoneditor-tree div.jsoneditor-date{background:var(--t42-content-color);color:var(--t42-content-color);font-family:var(--t42-font-family);border-radius:3px;display:inline-block;padding:3px;margin:0 3px}body div.jsoneditor-tree table.jsoneditor-tree{border-collapse:collapse;border-spacing:0;width:100%}body div.jsoneditor-tree .jsoneditor-button{display:block}body div.jsoneditor-tree .jsoneditor-button.jsoneditor-schema-error{width:24px;height:24px;padding:0;margin:0 4px 0 0;background-image:"/";background-position:-168px -48px;background-color:transparent}body div.jsoneditor-outer{position:static;width:100%;height:100%;margin:0;padding:0;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}body div.jsoneditor-outer.has-nav-bar{margin-top:-26px;padding-top:26px}body div.jsoneditor-outer.has-nav-bar.has-main-menu-bar{margin-top:-61px;padding-top:61px}body div.jsoneditor-outer.has-status-bar{margin-bottom:-26px;padding-bottom:26px}body div.jsoneditor-outer.has-main-menu-bar{margin-top:-35px;padding-top:35px}body div.jsoneditor-busy{position:absolute;top:15%;left:0;box-sizing:border-box;width:100%;text-align:center;display:none}body div.jsoneditor-busy span{background-color:var(--t42-color-opacity-10);border:1px solid var(--t42-color-opacity-10);border-radius:3px;padding:5px 15px;box-shadow:var(--t42-shadow)}body div.jsoneditor-field.jsoneditor-empty::after,body div.jsoneditor-value.jsoneditor-empty::after{pointer-events:none;color:var(--t42-content-color-muted);font-size:8pt}body div.jsoneditor-value.jsoneditor-url,body a.jsoneditor-value.jsoneditor-url{color:var(--green);text-decoration:underline}body a.jsoneditor-value.jsoneditor-url{display:inline-block;padding:2px;margin:2px}body a.jsoneditor-value.jsoneditor-url:hover,body a.jsoneditor-value.jsoneditor-url:focus{color:var(--red)}body div.jsoneditor-field[contenteditable="true"]:focus,body div.jsoneditor-field[contenteditable="true"]:hover,body div.jsoneditor-value[contenteditable="true"]:focus,body div.jsoneditor-value[contenteditable="true"]:hover,body div.jsoneditor-field.jsoneditor-highlight,body div.jsoneditor-value.jsoneditor-highlight{background-color:var(--t42-color-opacity-10);border:1px solid var(--t42-color-opacity-10);border-radius:2px}body div.jsoneditor-field.jsoneditor-highlight-active,body div.jsoneditor-field.jsoneditor-highlight-active:focus,body div.jsoneditor-field.jsoneditor-highlight-active:hover,body div.jsoneditor-value.jsoneditor-highlight-active,body div.jsoneditor-value.jsoneditor-highlight-active:focus,body div.jsoneditor-value.jsoneditor-highlight-active:hover{background-color:#fe0;border:1px solid #ffc700;border-radius:2px}body div.jsoneditor-value.jsoneditor-object,body div.jsoneditor-value.jsoneditor-array{min-width:16px}body div.jsoneditor-tree button.jsoneditor-contextmenu-button:hover,body div.jsoneditor-tree button.jsoneditor-contextmenu-button:focus,body div.jsoneditor-tree button.jsoneditor-contextmenu-button.jsoneditor-selected,body tr.jsoneditor-selected.jsoneditor-first button.jsoneditor-contextmenu-button{background-position:-48px -48px}body div.jsoneditor-tree div.jsoneditor-show-more a:hover,body div.jsoneditor-tree div.jsoneditor-show-more a:focus{color:var(--red)}body textarea.jsoneditor-text,body .ace-jsoneditor{min-height:150px}body textarea.jsoneditor-text.ace_editor,body .ace-jsoneditor.ace_editor{font-family:var(--bs-font-monospace)}body textarea.jsoneditor-text{width:100%;height:100%;margin:0;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;outline-width:0;border:none;background-color:var(--t42-content-color);resize:none}body tr.jsoneditor-highlight,body tr.jsoneditor-selected{background-color:var(--t42-content-color-muted)}body tr.jsoneditor-selected button.jsoneditor-dragarea,body tr.jsoneditor-selected button.jsoneditor-contextmenu-button{visibility:hidden}body tr.jsoneditor-selected.jsoneditor-first button.jsoneditor-dragarea,body tr.jsoneditor-selected.jsoneditor-first button.jsoneditor-contextmenu-button{visibility:visible}body div.jsoneditor-tree button.jsoneditor-dragarea:hover,body div.jsoneditor-tree button.jsoneditor-dragarea:focus,body tr.jsoneditor-selected.jsoneditor-first button.jsoneditor-dragarea{background-position:-72px -48px}body div.jsoneditor tr,body div.jsoneditor th,body div.jsoneditor td{padding:0;margin:0}body div.jsoneditor-field,body div.jsoneditor-value,body div.jsoneditor td,body div.jsoneditor th,body div.jsoneditor textarea,body pre.jsoneditor-preview,body .jsoneditor-schema-error,body .jsoneditor-popover{font-family:var(--bs-font-monospace);font-size:var(--t42-font-size);color:var(--t42-content-color)}body .jsoneditor-schema-error{cursor:default;display:inline-block;height:24px;line-height:24px;position:relative;text-align:center;width:24px}body .jsoneditor-popover{background-color:Rgb(var(--t42-bg-light));border-radius:3px;box-shadow:var(--t42-shadow);color:var(--t42-content-color);padding:7px 10px;position:absolute;cursor:auto;width:200px}body .jsoneditor-popover.jsoneditor-above{bottom:32px;left:-98px}body .jsoneditor-popover.jsoneditor-above:before{border-top:7px solid Rgb(var(--t42-bg-light));bottom:-7px}body .jsoneditor-popover.jsoneditor-below{top:32px;left:-98px}body .jsoneditor-popover.jsoneditor-below:before{border-bottom:7px solid Rgb(var(--t42-bg-light));top:-7px}body .jsoneditor-popover.jsoneditor-left{top:-7px;right:32px}body .jsoneditor-popover.jsoneditor-left:before{border-left:7px solid Rgb(var(--t42-bg-light));border-top:7px solid transparent;border-bottom:7px solid transparent;content:"";top:19px;right:-14px;left:inherit;margin-left:inherit;margin-top:-7px;position:absolute}body .jsoneditor-popover.jsoneditor-right{top:-7px;left:32px}body .jsoneditor-popover.jsoneditor-right:before{border-right:7px solid Rgb(var(--t42-bg-light));border-top:7px solid transparent;border-bottom:7px solid transparent;content:"";top:19px;left:-14px;margin-left:inherit;margin-top:-7px;position:absolute}body .jsoneditor-popover:before{border-right:7px solid transparent;border-left:7px solid transparent;content:"";display:block;left:50%;margin-left:-7px;position:absolute}body .jsoneditor-text-errors tr.jump-to-line:hover{text-decoration:underline;cursor:pointer}body .jsoneditor-schema-error:hover .jsoneditor-popover,body .jsoneditor-schema-error:focus .jsoneditor-popover{display:block;animation:fade-in 0.3s linear 1, move-up 0.3s linear 1}@keyframes fade-in{from{opacity:0}to{opacity:1}}body .jsoneditor .jsoneditor-validation-errors-container{max-height:130px;overflow-y:auto}body .jsoneditor .jsoneditor-validation-errors{width:100%;overflow:hidden}body .jsoneditor .jsoneditor-additional-errors{position:absolute;margin:auto;bottom:31px;left:calc(50% - 92px);color:var(--t42-content-color-muted);background-color:Rgb(var(--t42-bg-mid));padding:7px 15px;border-radius:8px}body .jsoneditor .jsoneditor-additional-errors.visible{visibility:visible;opacity:1;transition:opacity 2s linear}body .jsoneditor .jsoneditor-additional-errors.hidden{visibility:hidden;opacity:0;transition:visibility 0s 2s, opacity 2s linear}body .jsoneditor .jsoneditor-text-errors{width:100%;border-collapse:collapse;border-top:1px solid #ffc700}body .jsoneditor .jsoneditor-text-errors td{padding:3px 6px;vertical-align:middle}body .jsoneditor .jsoneditor-text-errors td pre{margin:0;white-space:pre-wrap}body .jsoneditor .jsoneditor-text-errors tr{background-color:var(--t42-color-opacity-10)}body .jsoneditor .jsoneditor-text-errors tr.parse-error{background-color:var(--red)}body .jsoneditor-text-errors .jsoneditor-schema-error{border:none;width:24px;height:24px;padding:0;margin:0 4px 0 0;cursor:pointer}body .jsoneditor-text-errors tr .jsoneditor-schema-error{background-image:"/";background-position:-168px -48px;background-color:transparent}body .jsoneditor-text-errors tr.parse-error .jsoneditor-schema-error{background-image:"/";background-position:-25px 0px;background-color:transparent}body .jsoneditor-anchor{cursor:pointer}body .jsoneditor-anchor .picker_wrapper.popup.popup_bottom{top:28px;left:-10px}body .fadein{-webkit-animation:fadein 0.3s;animation:fadein 0.3s;-moz-animation:fadein 0.3s;-o-animation:fadein 0.3s}@keyframes fadein{0%{opacity:0}100%{opacity:1}}body .jsoneditor-modal input[type="search"].selectr-input{border:1px solid #d3d3d3;width:calc(100% - 4px);margin:2px;padding:4px;box-sizing:border-box}body .jsoneditor-modal button.selectr-input-clear{right:8px}body .jsoneditor-menu{width:100%;height:35px;padding:2px;margin:0;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;color:var(--t42-content-color);background-color:var(--primary);border-bottom:1px solid var(--primary)}body .jsoneditor-menu>button,body .jsoneditor-menu>.jsoneditor-modes>button{width:26px;height:26px;margin:2px;padding:0;border-radius:2px;border:1px solid transparent;background-color:transparent;background-image:"/";color:var(--t42-content-color);opacity:0.8;font-family:var(--t42-font-family);font-size:var(--t42-font-size);float:left}body .jsoneditor-menu>button:hover,body .jsoneditor-menu>.jsoneditor-modes>button:hover{background-color:rgba(255,255,255,0.2);border:1px solid rgba(255,255,255,0.4)}body .jsoneditor-menu>button:focus,body .jsoneditor-menu>button:active,body .jsoneditor-menu>.jsoneditor-modes>button:focus,body .jsoneditor-menu>.jsoneditor-modes>button:active{background-color:rgba(255,255,255,0.3)}body .jsoneditor-menu>button:disabled,body .jsoneditor-menu>.jsoneditor-modes>button:disabled{opacity:0.5;background-color:transparent;border:none}body .jsoneditor-menu>button.jsoneditor-collapse-all{background-position:0 -96px}body .jsoneditor-menu>button.jsoneditor-expand-all{background-position:0 -120px}body .jsoneditor-menu>button.jsoneditor-sort{background-position:-120px -96px}body .jsoneditor-menu>button.jsoneditor-transform{background-position:-144px -96px}body .jsoneditor.jsoneditor-mode-view>.jsoneditor-menu>button.jsoneditor-sort,body .jsoneditor.jsoneditor-mode-form>.jsoneditor-menu>button.jsoneditor-sort,body .jsoneditor.jsoneditor-mode-view>.jsoneditor-menu>button.jsoneditor-transform,body .jsoneditor.jsoneditor-mode-form>.jsoneditor-menu>button.jsoneditor-transform{display:none}body .jsoneditor-menu>button.jsoneditor-undo{background-position:-24px -96px}body .jsoneditor-menu>button.jsoneditor-undo:disabled{background-position:-24px -120px}body .jsoneditor-menu>button.jsoneditor-redo{background-position:-48px -96px}body .jsoneditor-menu>button.jsoneditor-redo:disabled{background-position:-48px -120px}body .jsoneditor-menu>button.jsoneditor-compact{background-position:-72px -96px}body .jsoneditor-menu>button.jsoneditor-format{background-position:-72px -120px}body .jsoneditor-menu>button.jsoneditor-repair{background-position:-96px -96px}body .jsoneditor-menu>.jsoneditor-modes{display:inline-block;float:left}body .jsoneditor-menu>.jsoneditor-modes>button{background-image:none;width:auto;padding-left:6px;padding-right:6px}body .jsoneditor-menu>button.jsoneditor-separator,body .jsoneditor-menu>.jsoneditor-modes>button.jsoneditor-separator{margin-left:10px}body .jsoneditor-menu a{font-family:var(--t42-font-family);font-size:var(--t42-font-size);color:var(--t42-content-color);opacity:0.8;vertical-align:middle}body .jsoneditor-menu a:hover{opacity:1}body .jsoneditor-menu a.jsoneditor-poweredBy{font-size:8pt;position:absolute;right:0;top:0;padding:10px}body .jsoneditor-navigation-bar{width:100%;height:26px;line-height:26px;padding:0;margin:0;border-bottom:1px solid var(--t42-color-opacity-10);-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;color:var(--t42-content-color-muted);background-color:Rgb(var(--t42-bg-mid));overflow:hidden;font-family:var(--t42-font-family);font-size:var(--t42-font-size)}body .jsoneditor-search{font-family:var(--t42-font-family);position:absolute;right:4px;top:4px;border-collapse:collapse;border-spacing:0;display:flex}body .jsoneditor-search input{color:var(--t42-content-color);width:120px;border:none;outline:none;margin:1px;line-height:20px;font-family:var(--t42-font-family)}body .jsoneditor-search button{width:16px;height:24px;padding:0;margin:0;border:none;background:"/";vertical-align:top}body .jsoneditor-search button:hover{background-color:transparent}body .jsoneditor-search button.jsoneditor-refresh{width:18px;background-position:-99px -73px}body .jsoneditor-search button.jsoneditor-next{cursor:pointer;background-position:-124px -73px}body .jsoneditor-search button.jsoneditor-next:hover{background-position:-124px -49px}body .jsoneditor-search button.jsoneditor-previous{cursor:pointer;background-position:-148px -73px;margin-right:2px}body .jsoneditor-search button.jsoneditor-previous:hover{background-position:-148px -49px}body .jsoneditor-results{font-family:var(--t42-font-family);color:var(--t42-content-color);padding-right:5px;line-height:26px}body .jsoneditor-frame{border:1px solid transparent;background-color:var(--t42-content-color);padding:0 2px;margin:0}body .jsoneditor-statusbar{line-height:26px;height:26px;color:var(--t42-content-color-muted);background-color:Rgb(var(--t42-bg-mid));border-top:1px solid var(--t42-color-opacity-10);-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;font-size:var(--t42-font-size)}body .jsoneditor-statusbar>.jsoneditor-curserinfo-val{margin-right:12px}body .jsoneditor-statusbar>.jsoneditor-curserinfo-count{margin-left:4px}body .jsoneditor-statusbar>.jsoneditor-validation-error-icon{float:right;width:24px;height:24px;padding:0;margin-top:1px;background-image:"/";background-position:-168px -48px;cursor:pointer}body .jsoneditor-statusbar>.jsoneditor-validation-error-count{float:right;margin:0 4px 0 0;cursor:pointer}body .jsoneditor-statusbar>.jsoneditor-parse-error-icon{float:right;width:24px;height:24px;padding:0;margin:1px;background-image:"/";background-position:-25px 0px}body .jsoneditor-statusbar .jsoneditor-array-info a{color:inherit}body div.jsoneditor-statusbar>.jsoneditor-curserinfo-label,body div.jsoneditor-statusbar>.jsoneditor-size-info{margin:0 4px}body .jsoneditor-treepath{padding:0 5px;overflow:hidden;white-space:nowrap;outline:none}body .jsoneditor-treepath.show-all{word-wrap:break-word;white-space:normal;position:absolute;background-color:Rgb(var(--t42-bg-mid));z-index:1;box-shadow:var(--t42-shadow)}body .jsoneditor-treepath.show-all span.jsoneditor-treepath-show-all-btn{display:none}body .jsoneditor-treepath div.jsoneditor-contextmenu-root{position:absolute;left:0}body .jsoneditor-treepath .jsoneditor-treepath-show-all-btn{position:absolute;background-color:Rgb(var(--t42-bg-mid));left:0;height:20px;padding:0 3px;cursor:pointer}body .jsoneditor-treepath .jsoneditor-treepath-element{margin:1px;font-family:var(--t42-font-family);font-size:var(--t42-font-size)}body .jsoneditor-treepath .jsoneditor-treepath-seperator{margin:2px;font-size:9pt;font-family:var(--t42-font-family)}body .jsoneditor-treepath span.jsoneditor-treepath-element:hover,body .jsoneditor-treepath span.jsoneditor-treepath-seperator:hover{cursor:pointer;text-decoration:underline}body .selectr-container{position:relative}body .selectr-container li{list-style:none}body .selectr-hidden{position:absolute;overflow:hidden;clip:rect(0px, 0px, 0px, 0px);width:1px;height:1px;margin:-1px;padding:0;border:0 none}body .selectr-visible{position:absolute;left:0;top:0;width:100%;height:100%;opacity:0;z-index:11}body .selectr-desktop.multiple .selectr-visible{display:none}body .selectr-desktop.multiple.native-open .selectr-visible{top:100%;min-height:200px !important;height:auto;opacity:1;display:block}body .selectr-container.multiple.selectr-mobile .selectr-selected{z-index:0}body .selectr-selected{position:relative;z-index:1;box-sizing:border-box;width:100%;padding:7px 28px 7px 14px;cursor:pointer;border:1px solid Rgb(var(--t42-bg-mid));border-radius:3px;background-color:var(--t42-content-color)}body .selectr-selected::before{position:absolute;top:50%;right:10px;width:0;height:0;content:'';-o-transform:rotate(0deg) translate3d(0px, -50%, 0px);-ms-transform:rotate(0deg) translate3d(0px, -50%, 0px);-moz-transform:rotate(0deg) translate3d(0px, -50%, 0px);-webkit-transform:rotate(0deg) translate3d(0px, -50%, 0px);transform:rotate(0deg) translate3d(0px, -50%, 0px);border-width:4px 4px 0 4px;border-style:solid;border-color:#6c7a86 transparent transparent}body .selectr-container.open .selectr-selected::before,body .selectr-container.native-open .selectr-selected::before{border-width:0 4px 4px 4px;border-style:solid;border-color:transparent transparent #6c7a86}body .selectr-label{display:none;overflow:hidden;width:100%;white-space:nowrap;text-overflow:ellipsis}body .selectr-placeholder{color:#6c7a86}body .selectr-tags{margin:0;padding:0;white-space:normal}body .has-selected .selectr-tags{margin:0 0 -2px}body .selectr-tag{list-style:none;position:relative;float:left;padding:2px 25px 2px 8px;margin:0 2px 2px 0;cursor:default;color:var(--t42-content-color);border:medium none;border-radius:10px;background:#acb7bf none repeat scroll 0 0}body .selectr-container.multiple.has-selected .selectr-selected{padding:5px 28px 5px 5px}body .selectr-options-container{position:absolute;z-index:10000;top:calc(100% - 1px);left:0;display:none;box-sizing:border-box;width:100%;border-width:0 1px 1px;border-style:solid;border-color:transparent Rgb(var(--t42-bg-mid)) Rgb(var(--t42-bg-mid));border-radius:0 0 3px 3px;background-color:var(--t42-content-color)}body .selectr-container.open .selectr-options-container{display:block}body .selectr-input-container{position:relative;display:none}body .selectr-clear,body .selectr-input-clear,body .selectr-tag-remove{position:absolute;top:50%;right:22px;width:20px;height:20px;padding:0;cursor:pointer;-o-transform:translate3d(0px, -50%, 0px);-ms-transform:translate3d(0px, -50%, 0px);-moz-transform:translate3d(0px, -50%, 0px);-webkit-transform:translate3d(0px, -50%, 0px);transform:translate3d(0px, -50%, 0px);border:medium none;background-color:transparent;z-index:11}body .selectr-clear,body .selectr-input-clear{display:none}body .selectr-container.has-selected .selectr-clear,body .selectr-input-container.active .selectr-input-clear{display:block}body .selectr-selected .selectr-tag-remove{right:2px}body .selectr-clear::before,body .selectr-clear::after,body .selectr-input-clear::before,body .selectr-input-clear::after,body .selectr-tag-remove::before,body .selectr-tag-remove::after{position:absolute;top:5px;left:9px;width:2px;height:10px;content:' ';background-color:#6c7a86}body .selectr-tag-remove::before,body .selectr-tag-remove::after{top:4px;width:3px;height:12px;background-color:var(--t42-content-color)}body .selectr-clear:before,body .selectr-input-clear::before,body .selectr-tag-remove::before{-o-transform:rotate(45deg);-ms-transform:rotate(45deg);-moz-transform:rotate(45deg);-webkit-transform:rotate(45deg);transform:rotate(45deg)}body .selectr-clear:after,body .selectr-input-clear::after,body .selectr-tag-remove::after{-o-transform:rotate(-45deg);-ms-transform:rotate(-45deg);-moz-transform:rotate(-45deg);-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}body .selectr-input-container.active,body .selectr-input-container.active .selectr-clear{display:block}body .selectr-input{top:5px;left:5px;box-sizing:border-box;width:calc(100% - 30px);margin:10px 15px;padding:7px 30px 7px 9px;border:1px solid Rgb(var(--t42-bg-mid));border-radius:3px}body .selectr-notice{display:none;box-sizing:border-box;width:100%;padding:8px 16px;border-top:1px solid Rgb(var(--t42-bg-mid));border-radius:0 0 3px 3px;background-color:var(--t42-content-color)}body .selectr-container.notice .selectr-notice{display:block}body .selectr-container.notice .selectr-selected{border-radius:3px 3px 0 0}body .selectr-options{position:relative;top:calc(100% + 2px);display:none;overflow-x:auto;overflow-y:scroll;max-height:200px;margin:0;padding:0}body .selectr-container.open .selectr-options,body .selectr-container.open .selectr-input-container,body .selectr-container.notice .selectr-options-container{display:block}body .selectr-option{position:relative;display:block;padding:5px 20px;list-style:outside none none;cursor:pointer;font-weight:normal}body .selectr-options.optgroups>.selectr-option{padding-left:25px}body .selectr-optgroup{font-weight:bold;padding:0}body .selectr-optgroup--label{font-weight:bold;margin-top:10px;padding:5px 15px}body .selectr-match{text-decoration:underline}body .selectr-option.selected{background-color:#ddd}body .selectr-option.active{color:var(--t42-content-color);background-color:#5897fb}body .selectr-option.disabled{opacity:0.4}body .selectr-option.excluded{display:none}body .selectr-container.open .selectr-selected{border-color:Rgb(var(--t42-bg-mid)) Rgb(var(--t42-bg-mid)) transparent Rgb(var(--t42-bg-mid));border-radius:3px 3px 0 0}body .selectr-container.open .selectr-selected::after{-o-transform:rotate(180deg) translate3d(0px, 50%, 0px);-ms-transform:rotate(180deg) translate3d(0px, 50%, 0px);-moz-transform:rotate(180deg) translate3d(0px, 50%, 0px);-webkit-transform:rotate(180deg) translate3d(0px, 50%, 0px);transform:rotate(180deg) translate3d(0px, 50%, 0px)}body .selectr-disabled{opacity:.6}body .selectr-empty,body .has-selected .selectr-placeholder{display:none}body .has-selected .selectr-label{display:block}body .taggable .selectr-selected{padding:4px 28px 4px 4px}body .taggable .selectr-selected::after{display:table;content:" ";clear:both}body .taggable .selectr-label{width:auto}body .taggable .selectr-tags{float:left;display:block}body .taggable .selectr-placeholder{display:none}body .input-tag{float:left;min-width:90px;width:auto}body .selectr-tag-input{border:medium none;padding:3px 10px;width:100%;font-family:inherit;font-weight:inherit;font-size:inherit}body .selectr-input-container.loading::after{position:absolute;top:50%;right:20px;width:20px;height:20px;content:'';-o-transform:translate3d(0px, -50%, 0px);-ms-transform:translate3d(0px, -50%, 0px);-moz-transform:translate3d(0px, -50%, 0px);-webkit-transform:translate3d(0px, -50%, 0px);transform:translate3d(0px, -50%, 0px);-o-transform-origin:50% 0 0;-ms-transform-origin:50% 0 0;-moz-transform-origin:50% 0 0;-webkit-transform-origin:50% 0 0;transform-origin:50% 0 0;-moz-animation:500ms linear 0s normal forwards infinite running selectr-spin;-webkit-animation:500ms linear 0s normal forwards infinite running selectr-spin;animation:500ms linear 0s normal forwards infinite running selectr-spin;border-width:3px;border-style:solid;border-color:#aaa #ddd #ddd;border-radius:50%}@-webkit-keyframes selectr-spin{0%{-webkit-transform:rotate(0deg) translate3d(0px, -50%, 0px);transform:rotate(0deg) translate3d(0px, -50%, 0px)}100%{-webkit-transform:rotate(360deg) translate3d(0px, -50%, 0px);transform:rotate(360deg) translate3d(0px, -50%, 0px)}}@keyframes selectr-spin{0%{-webkit-transform:rotate(0deg) translate3d(0px, -50%, 0px);transform:rotate(0deg) translate3d(0px, -50%, 0px)}100%{-webkit-transform:rotate(360deg) translate3d(0px, -50%, 0px);transform:rotate(360deg) translate3d(0px, -50%, 0px)}}body .selectr-container.open.inverted .selectr-selected{border-color:transparent Rgb(var(--t42-bg-mid)) Rgb(var(--t42-bg-mid));border-radius:0 0 3px 3px}body .selectr-container.inverted .selectr-options-container{border-width:1px 1px 0;border-color:Rgb(var(--t42-bg-mid)) Rgb(var(--t42-bg-mid)) transparent;border-radius:3px 3px 0 0;background-color:var(--t42-content-color)}body .selectr-container.inverted .selectr-options-container{top:auto;bottom:calc(100% - 1px)}body .selectr-container ::-webkit-input-placeholder{color:#6c7a86;opacity:1}body .selectr-container ::-moz-placeholder{color:#6c7a86;opacity:1}body .selectr-container :-ms-input-placeholder{color:#6c7a86;opacity:1}body .selectr-container ::placeholder{color:#6c7a86;opacity:1}body #jsoneditor{height:100%}body .jsoneditor{border-color:var(--t42-color-opacity-10)}body .jsoneditor textarea{line-height:1.5;background-color:Rgb(var(--t42-bg-dark));min-height:100%}body .jsoneditor input{outline:0}body .jsoneditor input:focus{outline:0}body .jsoneditor-button:focus{outline:none}body .jsoneditor-menu{border-bottom-color:var(--t42-color-opacity-10);background-color:Rgb(var(--t42-bg-light))}body .jsoneditor-menu button{background-image:var(--t42-json-icons);background-color:transparent}body .jsoneditor-menu button:hover,body .jsoneditor-menu button:focus{color:var(--t42-link-hover-color)}body .jsoneditor-menu>button,body .jsoneditor-menu>.jsoneditor-modes>button{border-radius:0;font-size:.75rem;backdrop-filter:var(--backdrop-filter);transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, color}body .jsoneditor-menu>button:hover:not(.disabled):not(:disabled),body .jsoneditor-menu>button:active,body .jsoneditor-menu>.jsoneditor-modes>button:hover:not(.disabled):not(:disabled),body .jsoneditor-menu>.jsoneditor-modes>button:active{border-color:transparent;color:var(--t42-link-hover-color);background-color:var(--t42-color-opacity-10)}body .jsoneditor-menu li button.jsoneditor-selected{background-color:var(--t42-color-opacity-10)}body .jsoneditor-menu .jsoneditor-poweredBy{display:none}body .jsoneditor-frame{padding:0 .875rem;border-color:var(--t42-color-opacity-10);background-color:transparent;display:flex;transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border-color}body .jsoneditor-frame:focus-within{border-color:var(--primary);background-color:var(--t42-input-bg);outline:0}body .jsoneditor-frame table td{vertical-align:middle}body .jsoneditor-search input[type="text"]{border:0}body .jsoneditor-search input[type="text"]:focus{border:0}body .jsoneditor-search input{background-color:transparent}body .jsoneditor-contextmenu{z-index:2}body .jsoneditor-contextmenu .jsoneditor-menu{border-color:var(--t42-color-opacity-10);background:linear-gradient(to bottom right, rgba(var(--t42-bg-light), 0.75) 0%, rgba(var(--t42-bg-dark), 0.75) 100%);box-shadow:var(--t42-shadow);backdrop-filter:var(--backdrop-filter)}body .jsoneditor-contextmenu .jsoneditor-menu button button .jsoneditor-expand,body .jsoneditor-contextmenu .jsoneditor-menu li button .jsoneditor-expand{background-image:var(--t42-json-icons);z-index:1}body .jsoneditor-contextmenu .jsoneditor-menu button button.jsoneditor-selected,body .jsoneditor-contextmenu .jsoneditor-menu li button.jsoneditor-selected{background-color:var(--t42-color-opacity-10);transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, color}body .jsoneditor-contextmenu .jsoneditor-menu button button.jsoneditor-selected:hover,body .jsoneditor-contextmenu .jsoneditor-menu button button.jsoneditor-selected:focus,body .jsoneditor-contextmenu .jsoneditor-menu li button.jsoneditor-selected:hover,body .jsoneditor-contextmenu .jsoneditor-menu li button.jsoneditor-selected:focus{color:var(--t42-link-hover-color);background-color:var(--t42-color-opacity-10)}body .jsoneditor-contextmenu .jsoneditor-menu button{display:flex;justify-content:start}body .jsoneditor-contextmenu .jsoneditor-menu button.jsoneditor-default{float:left;z-index:1}body .jsoneditor-contextmenu .jsoneditor-menu li ul{padding:0 !important;left:0}body .jsoneditor-contextmenu .jsoneditor-menu li ul li button{padding-left:1rem}body .jsoneditor-contextmenu .jsoneditor-menu li ul .jsoneditor-icon{position:relative;margin-left:0}body .jsoneditor-contextmenu .jsoneditor-menu .jsoneditor-text{padding:0;line-height:1.5rem}body .jsoneditor-contextmenu .jsoneditor-icon{position:relative;background-image:var(--t42-json-icons)}body .jsoneditor-contextmenu .jsoneditor-separator{margin-top:0;padding-top:0}body .jsoneditor-mode-preview pre.jsoneditor-preview{border:0;line-height:1.5}body .jsoneditor-modal{border-top:0;background:linear-gradient(to bottom right, rgba(var(--t42-bg-light), 0.75) 0%, rgba(var(--t42-bg-dark), 0.75) 100%) !important;box-shadow:var(--t42-shadow) !important;backdrop-filter:var(--backdrop-filter)}body .jsoneditor-modal::before{position:absolute;top:0;right:0;left:0;display:block;width:100%;height:0.0625rem;background:linear-gradient(90deg, #007be5 0%, rgba(0,123,229,0.5) 100%);content:""}body .jsoneditor-modal .pico-modal-header{padding:0.5rem 0.988rem;background:transparent;font-size:0.75rem}body .jsoneditor-modal .pico-close{top:1rem !important;right:1rem !important;color:var(--t42-content-color-muted);transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:color}body .jsoneditor-modal .pico-close:not(.disabled):not(:disabled).active,body .jsoneditor-modal .pico-close:not(.disabled):not(:disabled):focus,body .jsoneditor-modal .pico-close:not(.disabled):not(:disabled):hover{color:var(--t42-link-color)}body .jsoneditor-modal table td{font-size:0.75rem;padding:0 0.25rem}body .jsoneditor-modal table td.jsoneditor-modal-input{padding-top:0.25rem;padding-bottom:0.25rem;text-align:left}body .jsoneditor-modal table td.jsoneditor-modal-input.jsoneditor-modal-actions{text-align:right}body .jsoneditor-modal table th{font-size:0.75rem}body .jsoneditor-modal label,body .jsoneditor-modal p{font-size:0.75rem}body .jsoneditor-modal select{min-width:12.375rem}body .jsoneditor-modal .selectr-selected{padding:0 0.857rem}body .jsoneditor-modal select,body .jsoneditor-modal textarea,body .jsoneditor-modal input,body .jsoneditor-modal input[type="text"],body .jsoneditor-modal input[type="search"],body .jsoneditor-modal #query{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border;border-color:var(--t42-color-opacity-10);border-radius:0;font-size:0.75rem;background-color:var(--t42-input-bg)}body .jsoneditor-modal select:focus,body .jsoneditor-modal textarea:focus,body .jsoneditor-modal input:focus,body .jsoneditor-modal input[type="text"]:focus,body .jsoneditor-modal input[type="search"]:focus,body .jsoneditor-modal #query:focus{border-color:var(--primary);box-shadow:none;outline:0;padding:0 0 0 .875rem;border-radius:0}body .jsoneditor-modal select:disabled,body .jsoneditor-modal select.disabled,body .jsoneditor-modal select[readonly],body .jsoneditor-modal textarea:disabled,body .jsoneditor-modal textarea.disabled,body .jsoneditor-modal textarea[readonly],body .jsoneditor-modal input:disabled,body .jsoneditor-modal input.disabled,body .jsoneditor-modal input[readonly],body .jsoneditor-modal input[type="text"]:disabled,body .jsoneditor-modal input[type="text"].disabled,body .jsoneditor-modal input[type="text"][readonly],body .jsoneditor-modal input[type="search"]:disabled,body .jsoneditor-modal input[type="search"].disabled,body .jsoneditor-modal input[type="search"][readonly],body .jsoneditor-modal #query:disabled,body .jsoneditor-modal #query.disabled,body .jsoneditor-modal #query[readonly]{cursor:default;opacity:0.65}body .jsoneditor-modal input[type="search"].selectr-input{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border-color;border:var(--t42-border);background-color:var(--t42-input-bg);margin:0;line-height:1.5rem;width:100%;padding:0 0.5rem}body .jsoneditor-modal input[type="search"].selectr-input:hover{border-color:var(--primary)}body .jsoneditor-modal .jsoneditor-select-wrapper::after{border-top:var(--t42-color-opacity-10)}body .jsoneditor-modal input[type="button"],body .jsoneditor-modal input[type="submit"]{padding:0 .875rem;border-radius:0;color:var(--t42-link-color);line-height:1.875rem;background:transparent;transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, border-color}body .jsoneditor-modal input[type="button"]:not(.disabled):not(:disabled).active,body .jsoneditor-modal input[type="button"]:not(.disabled):not(:disabled):hover,body .jsoneditor-modal input[type="submit"]:not(.disabled):not(:disabled).active,body .jsoneditor-modal input[type="submit"]:not(.disabled):not(:disabled):hover{border-color:var(--t42-color-opacity-30);color:var(--white);background:var(--primary)}body .jsoneditor-modal .jsoneditor-button-group input.jsoneditor-button-first{border-left-style:solid;border-top-left-radius:0;border-bottom-left-radius:0}body .jsoneditor-modal .jsoneditor-button-group input.jsoneditor-button-last{border-top-right-radius:0;border-bottom-right-radius:0}body .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-asc input.jsoneditor-button-asc,body .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-desc input.jsoneditor-button-desc{color:var(--white);background:var(--primary)}body .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-asc input.jsoneditor-button-asc:hover,body .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-asc input.jsoneditor-button-asc:focus,body .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-asc input.jsoneditor-button-asc:active,body .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-desc input.jsoneditor-button-desc:hover,body .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-desc input.jsoneditor-button-desc:focus,body .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-desc input.jsoneditor-button-desc:active{border-color:var(--t42-color-opacity-30);color:var(--white)}body .jsoneditor-modal .jsoneditor-jmespath-label{color:var(--t42-content-color);font-weight:400}body .jsoneditor-modal .jsoneditor-jmespath-filter-value input{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border-color;line-height:1.875rem;padding:0 0 0 .875rem;font-size:0.75rem;background-color:var(--t42-input-bg)}body .jsoneditor-modal .jsoneditor-jmespath-filter-value input:focus,body .jsoneditor-modal .jsoneditor-jmespath-filter-value input:hover{background-color:var(--t42-input-bg);border-color:var(--primary)}body .jsoneditor-jmespath-block .jsoneditor-modal-actions{text-align:right}body div.jsoneditor td.jsoneditor-tree{vertical-align:middle}body div.jsoneditor td.jsoneditor-separator{vertical-align:middle}body div.jsoneditor-tree{background:transparent}body div.jsoneditor-tree button.jsoneditor-button{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, outline-color;background-image:var(--t42-json-icons)}body div.jsoneditor-tree button.jsoneditor-button:focus{background-color:transparent;outline-color:var(--t42-color-opacity-10)}body tr.jsoneditor-selected,body tr.jsoneditor-highlight{background-color:var(--t42-color-opacity-10)}body .selectr-selected{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border-color;height:2rem;font-size:0.75rem;font-weight:400;line-height:1.875rem;background-color:var(--t42-input-bg);border-radius:0}body .selectr-selected::before{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:transform;right:0.5rem;border:0;width:0.75rem;height:0.75rem;background:var(--t42-select-indicator) center center/1rem 1rem no-repeat;transform:translateY(-50%)}body .selectr-placeholder{color:var(--t42-content-color-muted)}body .selectr-container.open .selectr-selected{border-radius:0;border-color:var(--primary)}body .selectr-container.open .selectr-selected::before{border:0;transform:rotate(180deg) translateY(50%)}body .selectr-container.open .selectr-options-container{border-left-color:var(--primary);border-right-color:var(--primary);border-bottom-color:var(--primary)}body .selectr-options{overflow-y:auto}body .selectr-options-container{min-height:2rem;border-color:var(--t42-color-opacity-10);border-style:solid;border-width:1px;background-color:Rgb(var(--t42-bg-dark))}body .selectr-options .active{color:var(--t42-link-hover-color);background-color:var(--t42-color-opacity-10)}body .selectr-options .selected{color:var(--t42-link-hover-color);background-color:var(--primary)}body .selectr-option{padding:0 0 0 0.875rem;line-height:2rem;font-size:0.75rem}body .selectr-input{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border-color;border:var(--t42-border);background-color:var(--t42-input-bg)}body .selectr-input:hover{border-color:var(--primary)}body .selectr-input-container{padding:0.25rem}body .selectr-clear::before,body .selectr-clear::after{background-color:var(--t42-content-color)}body .jsoneditor .ace-jsoneditor .ace_text-input{min-height:auto}body .jsoneditor .ace-jsoneditor.ace_editor,body .jsoneditor .ace-jsoneditor .ace_scroller{background-color:Rgb(var(--t42-bg-dark))}body .jsoneditor .ace-jsoneditor .ace_gutter{color:var(--t42-content-color-muted);background-color:Rgb(var(--t42-bg-mid))}body .jsoneditor .ace-jsoneditor .ace_gutter-active-line{background-color:Rgb(var(--t42-bg-light))}body .jsoneditor .ace-jsoneditor .ace_cursor{border-color:Rgb(var(--t42-content-color))}body .jsoneditor .ace-jsoneditor .ace_marker-layer .ace_active-line{background-color:rgba(var(--secondary), 0.25)}body .jsoneditor .ace-jsoneditor .ace_marker-layer .ace_selection{background-color:var(--t42-color-opacity-10)}body .jsoneditor .ace-jsoneditor .ace_marker-layer .ace_selected-word{border-color:var(--t42-color-opacity-10);background-color:var(--t42-color-opacity-10)}body .jsoneditor .ace-jsoneditor .ace_marker-layer .ace_bracket{border:var(--t42-border)}body .jsoneditor .ace-jsoneditor .ace_variable{color:var(--t42-content-color)}body .jsoneditor .ace-jsoneditor .ace_constant.ace_numeric{color:#ff511f}body .jsoneditor .ace-jsoneditor .ace_constant.ace_language{color:#f9a825}body .jsoneditor .ace-jsoneditor .ace_string{color:#43a047}body .jsoneditor .ace-jsoneditor .ace_fold{border-color:var(--t42-color-opacity-10);background-color:Rgb(var(--t42-bg-light));transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-image}body .jsoneditor .ace-jsoneditor .ace_fold-widget:hover,body .jsoneditor .ace-jsoneditor .ace_fold-widget:active{border-color:var(--t42-color-opacity-30);background-color:var(--t42-color-opacity-10);box-shadow:none}body .pico-modal-contents{display:block} + diff --git a/typescript/solution/clients/src/lib/workspaces.umd.js b/typescript/solution/clients/src/lib/workspaces.umd.js new file mode 100644 index 0000000..53ca1d8 --- /dev/null +++ b/typescript/solution/clients/src/lib/workspaces.umd.js @@ -0,0 +1,5302 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define(factory) : + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.workspaces = factory()); +})(this, (function () { 'use strict'; + + function getDefaultExportFromCjs (x) { + return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; + } + + function createRegistry(options) { + if (options && options.errorHandling + && typeof options.errorHandling !== "function" + && options.errorHandling !== "log" + && options.errorHandling !== "silent" + && options.errorHandling !== "throw") { + throw new Error("Invalid options passed to createRegistry. Prop errorHandling should be [\"log\" | \"silent\" | \"throw\" | (err) => void], but " + typeof options.errorHandling + " was passed"); + } + var _userErrorHandler = options && typeof options.errorHandling === "function" && options.errorHandling; + var callbacks = {}; + function add(key, callback, replayArgumentsArr) { + var callbacksForKey = callbacks[key]; + if (!callbacksForKey) { + callbacksForKey = []; + callbacks[key] = callbacksForKey; + } + callbacksForKey.push(callback); + if (replayArgumentsArr) { + setTimeout(function () { + replayArgumentsArr.forEach(function (replayArgument) { + var _a; + if ((_a = callbacks[key]) === null || _a === void 0 ? void 0 : _a.includes(callback)) { + try { + if (Array.isArray(replayArgument)) { + callback.apply(undefined, replayArgument); + } + else { + callback.apply(undefined, [replayArgument]); + } + } + catch (err) { + _handleError(err, key); + } + } + }); + }, 0); + } + return function () { + var allForKey = callbacks[key]; + if (!allForKey) { + return; + } + allForKey = allForKey.reduce(function (acc, element, index) { + if (!(element === callback && acc.length === index)) { + acc.push(element); + } + return acc; + }, []); + if (allForKey.length === 0) { + delete callbacks[key]; + } + else { + callbacks[key] = allForKey; + } + }; + } + function execute(key) { + var argumentsArr = []; + for (var _i = 1; _i < arguments.length; _i++) { + argumentsArr[_i - 1] = arguments[_i]; + } + var callbacksForKey = callbacks[key]; + if (!callbacksForKey || callbacksForKey.length === 0) { + return []; + } + var results = []; + callbacksForKey.forEach(function (callback) { + try { + var result = callback.apply(undefined, argumentsArr); + results.push(result); + } + catch (err) { + results.push(undefined); + _handleError(err, key); + } + }); + return results; + } + function _handleError(exceptionArtifact, key) { + var errParam = exceptionArtifact instanceof Error ? exceptionArtifact : new Error(exceptionArtifact); + if (_userErrorHandler) { + _userErrorHandler(errParam); + return; + } + var msg = "[ERROR] callback-registry: User callback for key \"" + key + "\" failed: " + errParam.stack; + if (options) { + switch (options.errorHandling) { + case "log": + return console.error(msg); + case "silent": + return; + case "throw": + throw new Error(msg); + } + } + console.error(msg); + } + function clear() { + callbacks = {}; + } + function clearKey(key) { + var callbacksForKey = callbacks[key]; + if (!callbacksForKey) { + return; + } + delete callbacks[key]; + } + return { + add: add, + execute: execute, + clear: clear, + clearKey: clearKey + }; + } + createRegistry.default = createRegistry; + var lib = createRegistry; + + + var CallbackFactory = /*@__PURE__*/getDefaultExportFromCjs(lib); + + /** + * Wraps values in an `Ok` type. + * + * Example: `ok(5) // => {ok: true, result: 5}` + */ + var ok = function (result) { return ({ ok: true, result: result }); }; + /** + * Wraps errors in an `Err` type. + * + * Example: `err('on fire') // => {ok: false, error: 'on fire'}` + */ + var err = function (error) { return ({ ok: false, error: error }); }; + /** + * Create a `Promise` that either resolves with the result of `Ok` or rejects + * with the error of `Err`. + */ + var asPromise = function (r) { + return r.ok === true ? Promise.resolve(r.result) : Promise.reject(r.error); + }; + /** + * Unwraps a `Result` and returns either the result of an `Ok`, or + * `defaultValue`. + * + * Example: + * ``` + * Result.withDefault(5, number().run(json)) + * ``` + * + * It would be nice if `Decoder` had an instance method that mirrored this + * function. Such a method would look something like this: + * ``` + * class Decoder { + * runWithDefault = (defaultValue: A, json: any): A => + * Result.withDefault(defaultValue, this.run(json)); + * } + * + * number().runWithDefault(5, json) + * ``` + * Unfortunately, the type of `defaultValue: A` on the method causes issues + * with type inference on the `object` decoder in some situations. While these + * inference issues can be solved by providing the optional type argument for + * `object`s, the extra trouble and confusion doesn't seem worth it. + */ + var withDefault = function (defaultValue, r) { + return r.ok === true ? r.result : defaultValue; + }; + /** + * Return the successful result, or throw an error. + */ + var withException = function (r) { + if (r.ok === true) { + return r.result; + } + else { + throw r.error; + } + }; + /** + * Apply `f` to the result of an `Ok`, or pass the error through. + */ + var map = function (f, r) { + return r.ok === true ? ok(f(r.result)) : r; + }; + /** + * Apply `f` to the result of two `Ok`s, or pass an error through. If both + * `Result`s are errors then the first one is returned. + */ + var map2 = function (f, ar, br) { + return ar.ok === false ? ar : + br.ok === false ? br : + ok(f(ar.result, br.result)); + }; + /** + * Apply `f` to the error of an `Err`, or pass the success through. + */ + var mapError = function (f, r) { + return r.ok === true ? r : err(f(r.error)); + }; + /** + * Chain together a sequence of computations that may fail, similar to a + * `Promise`. If the first computation fails then the error will propagate + * through. If it succeeds, then `f` will be applied to the value, returning a + * new `Result`. + */ + var andThen = function (f, r) { + return r.ok === true ? f(r.result) : r; + }; + + /*! ***************************************************************************** + Copyright (c) Microsoft Corporation. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THIS SOFTWARE. + ***************************************************************************** */ + /* global Reflect, Promise */ + + + + var __assign = function() { + __assign = Object.assign || function __assign(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; + } + return t; + }; + return __assign.apply(this, arguments); + }; + + function __rest(s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { + if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) + t[p[i]] = s[p[i]]; + } + return t; + } + + function isEqual(a, b) { + if (a === b) { + return true; + } + if (a === null && b === null) { + return true; + } + if (typeof (a) !== typeof (b)) { + return false; + } + if (typeof (a) === 'object') { + // Array + if (Array.isArray(a)) { + if (!Array.isArray(b)) { + return false; + } + if (a.length !== b.length) { + return false; + } + for (var i = 0; i < a.length; i++) { + if (!isEqual(a[i], b[i])) { + return false; + } + } + return true; + } + // Hash table + var keys = Object.keys(a); + if (keys.length !== Object.keys(b).length) { + return false; + } + for (var i = 0; i < keys.length; i++) { + if (!b.hasOwnProperty(keys[i])) { + return false; + } + if (!isEqual(a[keys[i]], b[keys[i]])) { + return false; + } + } + return true; + } + } + /* + * Helpers + */ + var isJsonArray = function (json) { return Array.isArray(json); }; + var isJsonObject = function (json) { + return typeof json === 'object' && json !== null && !isJsonArray(json); + }; + var typeString = function (json) { + switch (typeof json) { + case 'string': + return 'a string'; + case 'number': + return 'a number'; + case 'boolean': + return 'a boolean'; + case 'undefined': + return 'undefined'; + case 'object': + if (json instanceof Array) { + return 'an array'; + } + else if (json === null) { + return 'null'; + } + else { + return 'an object'; + } + default: + return JSON.stringify(json); + } + }; + var expectedGot = function (expected, got) { + return "expected " + expected + ", got " + typeString(got); + }; + var printPath = function (paths) { + return paths.map(function (path) { return (typeof path === 'string' ? "." + path : "[" + path + "]"); }).join(''); + }; + var prependAt = function (newAt, _a) { + var at = _a.at, rest = __rest(_a, ["at"]); + return (__assign({ at: newAt + (at || '') }, rest)); + }; + /** + * Decoders transform json objects with unknown structure into known and + * verified forms. You can create objects of type `Decoder` with either the + * primitive decoder functions, such as `boolean()` and `string()`, or by + * applying higher-order decoders to the primitives, such as `array(boolean())` + * or `dict(string())`. + * + * Each of the decoder functions are available both as a static method on + * `Decoder` and as a function alias -- for example the string decoder is + * defined at `Decoder.string()`, but is also aliased to `string()`. Using the + * function aliases exported with the library is recommended. + * + * `Decoder` exposes a number of 'run' methods, which all decode json in the + * same way, but communicate success and failure in different ways. The `map` + * and `andThen` methods modify decoders without having to call a 'run' method. + * + * Alternatively, the main decoder `run()` method returns an object of type + * `Result`. This library provides a number of helper + * functions for dealing with the `Result` type, so you can do all the same + * things with a `Result` as with the decoder methods. + */ + var Decoder = /** @class */ (function () { + /** + * The Decoder class constructor is kept private to separate the internal + * `decode` function from the external `run` function. The distinction + * between the two functions is that `decode` returns a + * `Partial` on failure, which contains an unfinished error + * report. When `run` is called on a decoder, the relevant series of `decode` + * calls is made, and then on failure the resulting `Partial` + * is turned into a `DecoderError` by filling in the missing information. + * + * While hiding the constructor may seem restrictive, leveraging the + * provided decoder combinators and helper functions such as + * `andThen` and `map` should be enough to build specialized decoders as + * needed. + */ + function Decoder(decode) { + var _this = this; + this.decode = decode; + /** + * Run the decoder and return a `Result` with either the decoded value or a + * `DecoderError` containing the json input, the location of the error, and + * the error message. + * + * Examples: + * ``` + * number().run(12) + * // => {ok: true, result: 12} + * + * string().run(9001) + * // => + * // { + * // ok: false, + * // error: { + * // kind: 'DecoderError', + * // input: 9001, + * // at: 'input', + * // message: 'expected a string, got 9001' + * // } + * // } + * ``` + */ + this.run = function (json) { + return mapError(function (error) { return ({ + kind: 'DecoderError', + input: json, + at: 'input' + (error.at || ''), + message: error.message || '' + }); }, _this.decode(json)); + }; + /** + * Run the decoder as a `Promise`. + */ + this.runPromise = function (json) { return asPromise(_this.run(json)); }; + /** + * Run the decoder and return the value on success, or throw an exception + * with a formatted error string. + */ + this.runWithException = function (json) { return withException(_this.run(json)); }; + /** + * Construct a new decoder that applies a transformation to the decoded + * result. If the decoder succeeds then `f` will be applied to the value. If + * it fails the error will propagated through. + * + * Example: + * ``` + * number().map(x => x * 5).run(10) + * // => {ok: true, result: 50} + * ``` + */ + this.map = function (f) { + return new Decoder(function (json) { return map(f, _this.decode(json)); }); + }; + /** + * Chain together a sequence of decoders. The first decoder will run, and + * then the function will determine what decoder to run second. If the result + * of the first decoder succeeds then `f` will be applied to the decoded + * value. If it fails the error will propagate through. + * + * This is a very powerful method -- it can act as both the `map` and `where` + * methods, can improve error messages for edge cases, and can be used to + * make a decoder for custom types. + * + * Example of adding an error message: + * ``` + * const versionDecoder = valueAt(['version'], number()); + * const infoDecoder3 = object({a: boolean()}); + * + * const decoder = versionDecoder.andThen(version => { + * switch (version) { + * case 3: + * return infoDecoder3; + * default: + * return fail(`Unable to decode info, version ${version} is not supported.`); + * } + * }); + * + * decoder.run({version: 3, a: true}) + * // => {ok: true, result: {a: true}} + * + * decoder.run({version: 5, x: 'abc'}) + * // => + * // { + * // ok: false, + * // error: {... message: 'Unable to decode info, version 5 is not supported.'} + * // } + * ``` + * + * Example of decoding a custom type: + * ``` + * // nominal type for arrays with a length of at least one + * type NonEmptyArray = T[] & { __nonEmptyArrayBrand__: void }; + * + * const nonEmptyArrayDecoder = (values: Decoder): Decoder> => + * array(values).andThen(arr => + * arr.length > 0 + * ? succeed(createNonEmptyArray(arr)) + * : fail(`expected a non-empty array, got an empty array`) + * ); + * ``` + */ + this.andThen = function (f) { + return new Decoder(function (json) { + return andThen(function (value) { return f(value).decode(json); }, _this.decode(json)); + }); + }; + /** + * Add constraints to a decoder _without_ changing the resulting type. The + * `test` argument is a predicate function which returns true for valid + * inputs. When `test` fails on an input, the decoder fails with the given + * `errorMessage`. + * + * ``` + * const chars = (length: number): Decoder => + * string().where( + * (s: string) => s.length === length, + * `expected a string of length ${length}` + * ); + * + * chars(5).run('12345') + * // => {ok: true, result: '12345'} + * + * chars(2).run('HELLO') + * // => {ok: false, error: {... message: 'expected a string of length 2'}} + * + * chars(12).run(true) + * // => {ok: false, error: {... message: 'expected a string, got a boolean'}} + * ``` + */ + this.where = function (test, errorMessage) { + return _this.andThen(function (value) { return (test(value) ? Decoder.succeed(value) : Decoder.fail(errorMessage)); }); + }; + } + /** + * Decoder primitive that validates strings, and fails on all other input. + */ + Decoder.string = function () { + return new Decoder(function (json) { + return typeof json === 'string' + ? ok(json) + : err({ message: expectedGot('a string', json) }); + }); + }; + /** + * Decoder primitive that validates numbers, and fails on all other input. + */ + Decoder.number = function () { + return new Decoder(function (json) { + return typeof json === 'number' + ? ok(json) + : err({ message: expectedGot('a number', json) }); + }); + }; + /** + * Decoder primitive that validates booleans, and fails on all other input. + */ + Decoder.boolean = function () { + return new Decoder(function (json) { + return typeof json === 'boolean' + ? ok(json) + : err({ message: expectedGot('a boolean', json) }); + }); + }; + Decoder.constant = function (value) { + return new Decoder(function (json) { + return isEqual(json, value) + ? ok(value) + : err({ message: "expected " + JSON.stringify(value) + ", got " + JSON.stringify(json) }); + }); + }; + Decoder.object = function (decoders) { + return new Decoder(function (json) { + if (isJsonObject(json) && decoders) { + var obj = {}; + for (var key in decoders) { + if (decoders.hasOwnProperty(key)) { + var r = decoders[key].decode(json[key]); + if (r.ok === true) { + // tslint:disable-next-line:strict-type-predicates + if (r.result !== undefined) { + obj[key] = r.result; + } + } + else if (json[key] === undefined) { + return err({ message: "the key '" + key + "' is required but was not present" }); + } + else { + return err(prependAt("." + key, r.error)); + } + } + } + return ok(obj); + } + else if (isJsonObject(json)) { + return ok(json); + } + else { + return err({ message: expectedGot('an object', json) }); + } + }); + }; + Decoder.array = function (decoder) { + return new Decoder(function (json) { + if (isJsonArray(json) && decoder) { + var decodeValue_1 = function (v, i) { + return mapError(function (err$$1) { return prependAt("[" + i + "]", err$$1); }, decoder.decode(v)); + }; + return json.reduce(function (acc, v, i) { + return map2(function (arr, result) { return arr.concat([result]); }, acc, decodeValue_1(v, i)); + }, ok([])); + } + else if (isJsonArray(json)) { + return ok(json); + } + else { + return err({ message: expectedGot('an array', json) }); + } + }); + }; + Decoder.tuple = function (decoders) { + return new Decoder(function (json) { + if (isJsonArray(json)) { + if (json.length !== decoders.length) { + return err({ + message: "expected a tuple of length " + decoders.length + ", got one of length " + json.length + }); + } + var result = []; + for (var i = 0; i < decoders.length; i++) { + var nth = decoders[i].decode(json[i]); + if (nth.ok) { + result[i] = nth.result; + } + else { + return err(prependAt("[" + i + "]", nth.error)); + } + } + return ok(result); + } + else { + return err({ message: expectedGot("a tuple of length " + decoders.length, json) }); + } + }); + }; + Decoder.union = function (ad, bd) { + var decoders = []; + for (var _i = 2; _i < arguments.length; _i++) { + decoders[_i - 2] = arguments[_i]; + } + return Decoder.oneOf.apply(Decoder, [ad, bd].concat(decoders)); + }; + Decoder.intersection = function (ad, bd) { + var ds = []; + for (var _i = 2; _i < arguments.length; _i++) { + ds[_i - 2] = arguments[_i]; + } + return new Decoder(function (json) { + return [ad, bd].concat(ds).reduce(function (acc, decoder) { return map2(Object.assign, acc, decoder.decode(json)); }, ok({})); + }); + }; + /** + * Escape hatch to bypass validation. Always succeeds and types the result as + * `any`. Useful for defining decoders incrementally, particularly for + * complex objects. + * + * Example: + * ``` + * interface User { + * name: string; + * complexUserData: ComplexType; + * } + * + * const userDecoder: Decoder = object({ + * name: string(), + * complexUserData: anyJson() + * }); + * ``` + */ + Decoder.anyJson = function () { return new Decoder(function (json) { return ok(json); }); }; + /** + * Decoder identity function which always succeeds and types the result as + * `unknown`. + */ + Decoder.unknownJson = function () { + return new Decoder(function (json) { return ok(json); }); + }; + /** + * Decoder for json objects where the keys are unknown strings, but the values + * should all be of the same type. + * + * Example: + * ``` + * dict(number()).run({chocolate: 12, vanilla: 10, mint: 37}); + * // => {ok: true, result: {chocolate: 12, vanilla: 10, mint: 37}} + * ``` + */ + Decoder.dict = function (decoder) { + return new Decoder(function (json) { + if (isJsonObject(json)) { + var obj = {}; + for (var key in json) { + if (json.hasOwnProperty(key)) { + var r = decoder.decode(json[key]); + if (r.ok === true) { + obj[key] = r.result; + } + else { + return err(prependAt("." + key, r.error)); + } + } + } + return ok(obj); + } + else { + return err({ message: expectedGot('an object', json) }); + } + }); + }; + /** + * Decoder for values that may be `undefined`. This is primarily helpful for + * decoding interfaces with optional fields. + * + * Example: + * ``` + * interface User { + * id: number; + * isOwner?: boolean; + * } + * + * const decoder: Decoder = object({ + * id: number(), + * isOwner: optional(boolean()) + * }); + * ``` + */ + Decoder.optional = function (decoder) { + return new Decoder(function (json) { return (json === undefined || json === null ? ok(undefined) : decoder.decode(json)); }); + }; + /** + * Decoder that attempts to run each decoder in `decoders` and either succeeds + * with the first successful decoder, or fails after all decoders have failed. + * + * Note that `oneOf` expects the decoders to all have the same return type, + * while `union` creates a decoder for the union type of all the input + * decoders. + * + * Examples: + * ``` + * oneOf(string(), number().map(String)) + * oneOf(constant('start'), constant('stop'), succeed('unknown')) + * ``` + */ + Decoder.oneOf = function () { + var decoders = []; + for (var _i = 0; _i < arguments.length; _i++) { + decoders[_i] = arguments[_i]; + } + return new Decoder(function (json) { + var errors = []; + for (var i = 0; i < decoders.length; i++) { + var r = decoders[i].decode(json); + if (r.ok === true) { + return r; + } + else { + errors[i] = r.error; + } + } + var errorsList = errors + .map(function (error) { return "at error" + (error.at || '') + ": " + error.message; }) + .join('", "'); + return err({ + message: "expected a value matching one of the decoders, got the errors [\"" + errorsList + "\"]" + }); + }); + }; + /** + * Decoder that always succeeds with either the decoded value, or a fallback + * default value. + */ + Decoder.withDefault = function (defaultValue, decoder) { + return new Decoder(function (json) { + return ok(withDefault(defaultValue, decoder.decode(json))); + }); + }; + /** + * Decoder that pulls a specific field out of a json structure, instead of + * decoding and returning the full structure. The `paths` array describes the + * object keys and array indices to traverse, so that values can be pulled out + * of a nested structure. + * + * Example: + * ``` + * const decoder = valueAt(['a', 'b', 0], string()); + * + * decoder.run({a: {b: ['surprise!']}}) + * // => {ok: true, result: 'surprise!'} + * + * decoder.run({a: {x: 'cats'}}) + * // => {ok: false, error: {... at: 'input.a.b[0]' message: 'path does not exist'}} + * ``` + * + * Note that the `decoder` is ran on the value found at the last key in the + * path, even if the last key is not found. This allows the `optional` + * decoder to succeed when appropriate. + * ``` + * const optionalDecoder = valueAt(['a', 'b', 'c'], optional(string())); + * + * optionalDecoder.run({a: {b: {c: 'surprise!'}}}) + * // => {ok: true, result: 'surprise!'} + * + * optionalDecoder.run({a: {b: 'cats'}}) + * // => {ok: false, error: {... at: 'input.a.b.c' message: 'expected an object, got "cats"'} + * + * optionalDecoder.run({a: {b: {z: 1}}}) + * // => {ok: true, result: undefined} + * ``` + */ + Decoder.valueAt = function (paths, decoder) { + return new Decoder(function (json) { + var jsonAtPath = json; + for (var i = 0; i < paths.length; i++) { + if (jsonAtPath === undefined) { + return err({ + at: printPath(paths.slice(0, i + 1)), + message: 'path does not exist' + }); + } + else if (typeof paths[i] === 'string' && !isJsonObject(jsonAtPath)) { + return err({ + at: printPath(paths.slice(0, i + 1)), + message: expectedGot('an object', jsonAtPath) + }); + } + else if (typeof paths[i] === 'number' && !isJsonArray(jsonAtPath)) { + return err({ + at: printPath(paths.slice(0, i + 1)), + message: expectedGot('an array', jsonAtPath) + }); + } + else { + jsonAtPath = jsonAtPath[paths[i]]; + } + } + return mapError(function (error) { + return jsonAtPath === undefined + ? { at: printPath(paths), message: 'path does not exist' } + : prependAt(printPath(paths), error); + }, decoder.decode(jsonAtPath)); + }); + }; + /** + * Decoder that ignores the input json and always succeeds with `fixedValue`. + */ + Decoder.succeed = function (fixedValue) { + return new Decoder(function (json) { return ok(fixedValue); }); + }; + /** + * Decoder that ignores the input json and always fails with `errorMessage`. + */ + Decoder.fail = function (errorMessage) { + return new Decoder(function (json) { return err({ message: errorMessage }); }); + }; + /** + * Decoder that allows for validating recursive data structures. Unlike with + * functions, decoders assigned to variables can't reference themselves + * before they are fully defined. We can avoid prematurely referencing the + * decoder by wrapping it in a function that won't be called until use, at + * which point the decoder has been defined. + * + * Example: + * ``` + * interface Comment { + * msg: string; + * replies: Comment[]; + * } + * + * const decoder: Decoder = object({ + * msg: string(), + * replies: lazy(() => array(decoder)) + * }); + * ``` + */ + Decoder.lazy = function (mkDecoder) { + return new Decoder(function (json) { return mkDecoder().decode(json); }); + }; + return Decoder; + }()); + + /* tslint:disable:variable-name */ + /** See `Decoder.string` */ + var string = Decoder.string; + /** See `Decoder.number` */ + var number = Decoder.number; + /** See `Decoder.boolean` */ + var boolean = Decoder.boolean; + /** See `Decoder.anyJson` */ + var anyJson = Decoder.anyJson; + /** See `Decoder.unknownJson` */ + Decoder.unknownJson; + /** See `Decoder.constant` */ + var constant = Decoder.constant; + /** See `Decoder.object` */ + var object = Decoder.object; + /** See `Decoder.array` */ + var array = Decoder.array; + /** See `Decoder.tuple` */ + Decoder.tuple; + /** See `Decoder.dict` */ + Decoder.dict; + /** See `Decoder.optional` */ + var optional = Decoder.optional; + /** See `Decoder.oneOf` */ + var oneOf = Decoder.oneOf; + /** See `Decoder.union` */ + Decoder.union; + /** See `Decoder.intersection` */ + var intersection = Decoder.intersection; + /** See `Decoder.withDefault` */ + Decoder.withDefault; + /** See `Decoder.valueAt` */ + Decoder.valueAt; + /** See `Decoder.succeed` */ + Decoder.succeed; + /** See `Decoder.fail` */ + Decoder.fail; + /** See `Decoder.lazy` */ + var lazy = Decoder.lazy; + + const nonEmptyStringDecoder = string().where((s) => s.length > 0, "Expected a non-empty string"); + const nonNegativeNumberDecoder = number().where((num) => num >= 0, "Expected a non-negative number"); + const positiveNumberDecoder = number().where((num) => num > 0, "Expected a positive number"); + const windowDragModeDecoder = oneOf(constant("keepInside"), constant("autoEject")); + const isWindowInSwimlaneResultDecoder = object({ + inWorkspace: boolean() + }); + const allParentDecoder = oneOf(constant("workspace"), constant("row"), constant("column"), constant("group")); + const subParentDecoder = oneOf(constant("row"), constant("column"), constant("group")); + const frameStateDecoder = oneOf(constant("maximized"), constant("minimized"), constant("normal")); + const loadingAnimationTypeDecoder = oneOf(constant("workspace")); + const checkThrowCallback = (callback, allowUndefined) => { + const argumentType = typeof callback; + if (allowUndefined && argumentType !== "function" && argumentType !== "undefined") { + throw new Error(`Provided argument must be either undefined or of type function, provided: ${argumentType}`); + } + if (!allowUndefined && argumentType !== "function") { + throw new Error(`Provided argument must be of type function, provided: ${argumentType}`); + } + }; + const workspaceBuilderCreateConfigDecoder = optional(object({ + saveLayout: optional(boolean()) + })); + const deleteLayoutConfigDecoder = object({ + name: nonEmptyStringDecoder + }); + const windowDefinitionConfigDecoder = object({ + minWidth: optional(number()), + maxWidth: optional(number()), + minHeight: optional(number()), + maxHeight: optional(number()), + allowExtract: optional(boolean()), + allowReorder: optional(boolean()), + showCloseButton: optional(boolean()) + }); + const groupDefinitionConfigDecoder = object({ + minWidth: optional(number()), + maxWidth: optional(number()), + minHeight: optional(number()), + maxHeight: optional(number()), + allowExtract: optional(boolean()), + allowReorder: optional(boolean()), + allowDrop: optional(boolean()), + allowDropHeader: optional(boolean()), + allowDropLeft: optional(boolean()), + allowDropRight: optional(boolean()), + allowDropTop: optional(boolean()), + allowDropBottom: optional(boolean()), + showMaximizeButton: optional(boolean()), + showEjectButton: optional(boolean()), + showAddWindowButton: optional(boolean()) + }); + const rowDefinitionConfigDecoder = object({ + minHeight: optional(number()), + maxHeight: optional(number()), + allowDrop: optional(boolean()), + allowSplitters: optional(boolean()), + isPinned: optional(boolean()), + maximizationBoundary: optional(boolean()) + }); + const columnDefinitionConfigDecoder = object({ + minWidth: optional(number()), + maxWidth: optional(number()), + allowDrop: optional(boolean()), + allowSplitters: optional(boolean()), + isPinned: optional(boolean()), + maximizationBoundary: optional(boolean()) + }); + const swimlaneWindowDefinitionDecoder = object({ + type: optional(constant("window")), + appName: optional(nonEmptyStringDecoder), + windowId: optional(nonEmptyStringDecoder), + context: optional(anyJson()), + config: optional(windowDefinitionConfigDecoder) + }); + const strictSwimlaneWindowDefinitionDecoder = object({ + type: constant("window"), + appName: optional(nonEmptyStringDecoder), + windowId: optional(nonEmptyStringDecoder), + context: optional(anyJson()), + config: optional(windowDefinitionConfigDecoder) + }); + const parentDefinitionDecoder = optional(object({ + type: optional(subParentDecoder), + children: optional(lazy(() => array(oneOf(swimlaneWindowDefinitionDecoder, parentDefinitionDecoder)))), + config: optional(anyJson()) + })); + const strictColumnDefinitionDecoder = object({ + type: constant("column"), + children: optional(lazy(() => array(oneOf(strictSwimlaneWindowDefinitionDecoder, strictParentDefinitionDecoder)))), + config: optional(columnDefinitionConfigDecoder) + }); + const strictRowDefinitionDecoder = object({ + type: constant("row"), + children: optional(lazy(() => array(oneOf(strictSwimlaneWindowDefinitionDecoder, strictParentDefinitionDecoder)))), + config: optional(rowDefinitionConfigDecoder) + }); + const strictGroupDefinitionDecoder = object({ + type: constant("group"), + children: optional(lazy(() => array(oneOf(strictSwimlaneWindowDefinitionDecoder, strictParentDefinitionDecoder)))), + config: optional(groupDefinitionConfigDecoder) + }); + const strictParentDefinitionDecoder = oneOf(strictGroupDefinitionDecoder, strictColumnDefinitionDecoder, strictRowDefinitionDecoder); + oneOf(string().where((s) => s.toLowerCase() === "maximized", "Expected a case insensitive variation of 'maximized'"), string().where((s) => s.toLowerCase() === "normal", "Expected a case insensitive variation of 'normal'")); + const newFrameConfigDecoder = object({ + bounds: optional(object({ + left: optional(number()), + top: optional(number()), + width: optional(nonNegativeNumberDecoder), + height: optional(nonNegativeNumberDecoder) + })), + frameId: optional(nonEmptyStringDecoder) + }); + const loadingStrategyDecoder = oneOf(constant("direct"), constant("delayed"), constant("lazy")); + const restoreWorkspaceConfigDecoder = optional(object({ + app: optional(nonEmptyStringDecoder), + context: optional(anyJson()), + loadingStrategy: optional(loadingStrategyDecoder), + title: optional(nonEmptyStringDecoder), + reuseWorkspaceId: optional(nonEmptyStringDecoder), + frameId: optional(nonEmptyStringDecoder), + applicationName: optional(nonEmptyStringDecoder), + lockdown: optional(boolean()), + activateFrame: optional(boolean()), + newFrame: optional(oneOf(newFrameConfigDecoder, boolean())), + noTabHeader: optional(boolean()), + inMemoryLayout: optional(boolean()), + icon: optional(nonEmptyStringDecoder), + isPinned: optional(boolean()), + isSelected: optional(boolean()), + positionIndex: optional(nonNegativeNumberDecoder), + allowSystemHibernation: optional(boolean()) + })); + const openWorkspaceConfigDecoder = object({ + name: nonEmptyStringDecoder, + restoreOptions: optional(restoreWorkspaceConfigDecoder) + }); + const workspaceDefinitionDecoder = object({ + children: optional(array(oneOf(swimlaneWindowDefinitionDecoder, strictParentDefinitionDecoder))), + context: optional(anyJson()), + config: optional(object({ + title: optional(nonEmptyStringDecoder), + position: optional(nonNegativeNumberDecoder), + isFocused: optional(boolean()), + noTabHeader: optional(boolean()), + reuseWorkspaceId: optional(nonEmptyStringDecoder), + loadingStrategy: optional(loadingStrategyDecoder), + allowDrop: optional(boolean()), + allowDropLeft: optional(boolean()), + allowDropTop: optional(boolean()), + allowDropRight: optional(boolean()), + allowDropBottom: optional(boolean()), + allowSystemHibernation: optional(boolean()), + allowExtract: optional(boolean()), + allowWindowReorder: optional(boolean()), + showSaveButton: optional(boolean()), + allowWorkspaceTabReorder: optional(boolean()), + allowWorkspaceTabExtract: optional(boolean()), + showCloseButton: optional(boolean()), + allowSplitters: optional(boolean()), + showWindowCloseButtons: optional(boolean()), + showEjectButtons: optional(boolean()), + showAddWindowButtons: optional(boolean()), + icon: optional(nonEmptyStringDecoder), + isPinned: optional(boolean()), + isSelected: optional(boolean()), + positionIndex: optional(nonNegativeNumberDecoder), + windowDragMode: optional(windowDragModeDecoder) + })), + frame: optional(object({ + activate: optional(boolean()), + reuseFrameId: optional(nonEmptyStringDecoder), + applicationName: optional(nonEmptyStringDecoder), + newFrame: optional(oneOf(boolean(), newFrameConfigDecoder)) + })) + }); + const workspaceSelectorDecoder = object({ + workspaceId: nonEmptyStringDecoder + }); + const restoreWorkspaceDefinitionDecoder = object({ + name: nonEmptyStringDecoder, + restoreOptions: optional(restoreWorkspaceConfigDecoder) + }); + const emptyFrameDefinitionDecoder = optional(object({ + applicationName: optional(string()), + frameConfig: optional(newFrameConfigDecoder), + context: optional(object()), + layoutComponentId: optional(nonEmptyStringDecoder) + })); + const frameInitConfigDecoder = object({ + workspaces: array(oneOf(optional(workspaceDefinitionDecoder), optional(restoreWorkspaceDefinitionDecoder))) + }); + const frameInitProtocolConfigDecoder = object({ + frameId: nonEmptyStringDecoder, + workspaces: array(oneOf(workspaceDefinitionDecoder, restoreWorkspaceDefinitionDecoder)) + }); + const builderConfigDecoder = object({ + type: allParentDecoder, + definition: optional(oneOf(workspaceDefinitionDecoder, parentDefinitionDecoder)) + }); + const workspaceCreateConfigDecoder = intersection(workspaceDefinitionDecoder, object({ + saveConfig: optional(object({ + saveLayout: optional(boolean()) + })) + })); + const getFrameSummaryConfigDecoder = object({ + itemId: nonEmptyStringDecoder + }); + const frameInitializationContextDecoder = object({ + context: optional(object()) + }); + const frameSummaryDecoder = object({ + id: nonEmptyStringDecoder, + isFocused: optional(boolean()), + isInitialized: optional(boolean()), + initializationContext: optional(frameInitializationContextDecoder) + }); + object({ + type: subParentDecoder, + id: nonEmptyStringDecoder, + frameId: nonEmptyStringDecoder, + workspaceId: nonEmptyStringDecoder, + positionIndex: number() + }); + const eventTypeDecoder = oneOf(constant("frame"), constant("workspace"), constant("container"), constant("window")); + const streamRequestArgumentsDecoder = object({ + type: eventTypeDecoder, + branch: nonEmptyStringDecoder + }); + const workspaceEventActionDecoder = oneOf(constant("opened"), constant("closing"), constant("closed"), constant("focus"), constant("added"), constant("loaded"), constant("removed"), constant("childrenUpdate"), constant("containerChange"), constant("maximized"), constant("restored"), constant("minimized"), constant("normal"), constant("selected"), constant("lock-configuration-changed"), constant("hibernated"), constant("resumed")); + const workspaceConfigResultDecoder = object({ + frameId: nonEmptyStringDecoder, + title: nonEmptyStringDecoder, + positionIndex: nonNegativeNumberDecoder, + name: nonEmptyStringDecoder, + layoutName: optional(nonEmptyStringDecoder), + isHibernated: optional(boolean()), + isSelected: optional(boolean()), + allowDrop: optional(boolean()), + allowSystemHibernation: optional(boolean()), + allowExtract: optional(boolean()), + allowWindowReorder: optional(boolean()), + allowSplitters: optional(boolean()), + showCloseButton: optional(boolean()), + showSaveButton: optional(boolean()), + allowWorkspaceTabReorder: optional(boolean()), + allowWorkspaceTabExtract: optional(boolean()), + allowDropLeft: optional(boolean()), + allowDropTop: optional(boolean()), + allowDropRight: optional(boolean()), + allowDropBottom: optional(boolean()), + minWidth: optional(number()), + maxWidth: optional(number()), + minHeight: optional(number()), + maxHeight: optional(number()), + showAddWindowButtons: optional(boolean()), + showEjectButtons: optional(boolean()), + showWindowCloseButtons: optional(boolean()), + widthInPx: optional(number()), + heightInPx: optional(number()), + isPinned: optional(boolean()), + windowDragMode: optional(windowDragModeDecoder), + loadingStrategy: optional(loadingStrategyDecoder) + }); + const baseChildSnapshotConfigDecoder = object({ + frameId: nonEmptyStringDecoder, + workspaceId: nonEmptyStringDecoder, + positionIndex: number(), + minWidth: optional(number()), + maxWidth: optional(number()), + minHeight: optional(number()), + maxHeight: optional(number()) + }); + const parentSnapshotConfigDecoder = anyJson(); + const swimlaneWindowSnapshotConfigDecoder = intersection(baseChildSnapshotConfigDecoder, object({ + windowId: optional(nonEmptyStringDecoder), + isMaximized: optional(boolean()), + isFocused: boolean(), + isSelected: optional(boolean()), + title: optional(string()), + appName: optional(nonEmptyStringDecoder), + allowExtract: optional(boolean()), + allowReorder: optional(boolean()), + showCloseButton: optional(boolean()), + minWidth: optional(number()), + minHeight: optional(number()), + maxWidth: optional(number()), + maxHeight: optional(number()), + widthInPx: optional(number()), + heightInPx: optional(number()), + context: optional(anyJson()) + })); + const customWorkspaceSubParentSnapshotDecoder = object({ + id: optional(nonEmptyStringDecoder), + config: parentSnapshotConfigDecoder, + children: optional(lazy(() => array(customWorkspaceChildSnapshotDecoder))), + type: oneOf(constant("row"), constant("column"), constant("group")) + }); + const customWorkspaceWindowSnapshotDecoder = object({ + id: optional(nonEmptyStringDecoder), + config: swimlaneWindowSnapshotConfigDecoder, + type: constant("window") + }); + const customWorkspaceChildSnapshotDecoder = oneOf(customWorkspaceWindowSnapshotDecoder, customWorkspaceSubParentSnapshotDecoder); + const childSnapshotResultDecoder = customWorkspaceChildSnapshotDecoder; + const workspaceSnapshotResultDecoder = object({ + id: nonEmptyStringDecoder, + config: workspaceConfigResultDecoder, + children: array(childSnapshotResultDecoder), + frameSummary: frameSummaryDecoder, + context: optional(anyJson()) + }); + const windowLayoutItemDecoder = object({ + type: constant("window"), + config: object({ + appName: nonEmptyStringDecoder, + windowId: optional(nonEmptyStringDecoder), + context: optional(anyJson()), + url: optional(nonEmptyStringDecoder), + title: optional(string()), + allowExtract: optional(boolean()), + allowReorder: optional(boolean()), + showCloseButton: optional(boolean()), + minWidth: optional(number()), + minHeight: optional(number()), + maxWidth: optional(number()), + maxHeight: optional(number()), + isMaximized: optional(boolean()) + }) + }); + const groupLayoutItemDecoder = object({ + type: constant("group"), + config: anyJson(), + children: array(oneOf(windowLayoutItemDecoder)) + }); + const columnLayoutItemDecoder = object({ + type: constant("column"), + config: anyJson(), + children: array(oneOf(groupLayoutItemDecoder, windowLayoutItemDecoder, lazy(() => columnLayoutItemDecoder), lazy(() => rowLayoutItemDecoder))) + }); + const rowLayoutItemDecoder = object({ + type: constant("row"), + config: anyJson(), + children: array(oneOf(columnLayoutItemDecoder, groupLayoutItemDecoder, windowLayoutItemDecoder, lazy(() => rowLayoutItemDecoder))) + }); + const workspaceLayoutDecoder = object({ + name: nonEmptyStringDecoder, + type: constant("Workspace"), + metadata: optional(anyJson()), + components: array(object({ + type: constant("Workspace"), + application: optional(string()), + state: object({ + config: anyJson(), + context: anyJson(), + children: array(oneOf(rowLayoutItemDecoder, columnLayoutItemDecoder, groupLayoutItemDecoder, windowLayoutItemDecoder)) + }) + })) + }); + const workspacesImportLayoutDecoder = object({ + layout: workspaceLayoutDecoder, + mode: oneOf(constant("replace"), constant("merge")) + }); + const workspacesImportLayoutsDecoder = object({ + layouts: array(workspaceLayoutDecoder), + mode: oneOf(constant("replace"), constant("merge")) + }); + const exportedLayoutsResultDecoder = object({ + layouts: array(workspaceLayoutDecoder) + }); + const frameSummaryResultDecoder = object({ + id: nonEmptyStringDecoder, + isFocused: optional(boolean()), + isInitialized: optional(boolean()), + initializationContext: optional(frameInitializationContextDecoder) + }); + const frameSummariesResultDecoder = object({ + summaries: array(frameSummaryResultDecoder) + }); + const workspaceSummaryResultDecoder = object({ + id: nonEmptyStringDecoder, + config: workspaceConfigResultDecoder + }); + const workspaceSummariesResultDecoder = object({ + summaries: array(workspaceSummaryResultDecoder) + }); + const frameSnapshotResultDecoder = object({ + id: nonEmptyStringDecoder, + config: anyJson(), + workspaces: array(workspaceSnapshotResultDecoder) + }); + const layoutSummaryDecoder = object({ + name: nonEmptyStringDecoder, + applicationName: optional(string()) + }); + const layoutSummariesDecoder = object({ + summaries: array(layoutSummaryDecoder) + }); + const simpleWindowOperationSuccessResultDecoder = object({ + windowId: nonEmptyStringDecoder + }); + const voidResultDecoder = anyJson(); + const frameStateResultDecoder = object({ + state: frameStateDecoder + }); + const frameBoundsDecoder = object({ + top: number(), + left: number(), + width: nonNegativeNumberDecoder, + height: nonNegativeNumberDecoder + }); + const frameBoundsResultDecoder = object({ + bounds: frameBoundsDecoder + }); + const getWorkspaceIconResultDecoder = object({ + icon: optional(nonEmptyStringDecoder) + }); + const getPlatformFrameIdResultDecoder = object({ + id: optional(nonEmptyStringDecoder) + }); + const operationCheckResultDecoder = object({ + isSupported: boolean() + }); + const resizeConfigDecoder = object({ + width: optional(positiveNumberDecoder), + height: optional(positiveNumberDecoder), + relative: optional(boolean()) + }); + const moveConfigDecoder = object({ + top: optional(number()), + left: optional(number()), + relative: optional(boolean()) + }); + const simpleItemConfigDecoder = object({ + itemId: nonEmptyStringDecoder + }); + const frameSnapshotConfigDecoder = object({ + itemId: nonEmptyStringDecoder, + excludeIds: optional(boolean()) + }); + const frameStateConfigDecoder = object({ + frameId: nonEmptyStringDecoder, + requestedState: frameStateDecoder + }); + const setItemTitleConfigDecoder = object({ + itemId: nonEmptyStringDecoder, + title: nonEmptyStringDecoder + }); + const moveWindowConfigDecoder = object({ + itemId: nonEmptyStringDecoder, + containerId: nonEmptyStringDecoder + }); + const resizeItemConfigDecoder = intersection(simpleItemConfigDecoder, resizeConfigDecoder); + const setMaximizationBoundaryConfigDecoder = object({ + itemId: nonEmptyStringDecoder, + enabled: boolean() + }); + const moveFrameConfigDecoder = intersection(simpleItemConfigDecoder, moveConfigDecoder); + object({ + id: nonEmptyStringDecoder, + type: subParentDecoder + }); + const addWindowConfigDecoder = object({ + definition: swimlaneWindowDefinitionDecoder, + parentId: nonEmptyStringDecoder, + parentType: allParentDecoder + }); + const addContainerConfigDecoder = object({ + definition: strictParentDefinitionDecoder, + parentId: nonEmptyStringDecoder, + parentType: allParentDecoder + }); + const addItemResultDecoder = object({ + itemId: nonEmptyStringDecoder, + windowId: optional(nonEmptyStringDecoder) + }); + const pingResultDecoder = object({ + live: boolean() + }); + const bundleWorkspaceConfigDecoder = object({ + type: oneOf(constant("row"), constant("column")), + workspaceId: nonEmptyStringDecoder + }); + const bundleItemConfigDecoder = object({ + type: oneOf(constant("row"), constant("column")), + itemId: nonEmptyStringDecoder + }); + const containerSummaryResultDecoder = object({ + itemId: nonEmptyStringDecoder, + config: parentSnapshotConfigDecoder + }); + const frameStreamDataDecoder = object({ + frameSummary: frameSummaryDecoder, + frameBounds: optional(frameBoundsDecoder) + }); + const workspaceStreamDataDecoder = object({ + workspaceSummary: workspaceSummaryResultDecoder, + frameSummary: frameSummaryDecoder, + workspaceSnapshot: optional(workspaceSnapshotResultDecoder), + frameBounds: optional(frameBoundsDecoder) + }); + const containerStreamDataDecoder = object({ + containerSummary: containerSummaryResultDecoder + }); + const windowStreamDataDecoder = object({ + windowSummary: object({ + itemId: nonEmptyStringDecoder, + parentId: nonEmptyStringDecoder, + config: swimlaneWindowSnapshotConfigDecoder + }) + }); + const workspaceLayoutSaveConfigDecoder = object({ + name: nonEmptyStringDecoder, + workspaceId: nonEmptyStringDecoder, + saveContext: optional(boolean()), + allowMultiple: optional(boolean()), + metadata: optional(object()) + }); + const workspaceLockConfigDecoder = object({ + allowDrop: optional(boolean()), + allowDropLeft: optional(boolean()), + allowDropTop: optional(boolean()), + allowDropRight: optional(boolean()), + allowDropBottom: optional(boolean()), + allowSystemHibernation: optional(boolean()), + allowExtract: optional(boolean()), + allowWindowReorder: optional(boolean()), + allowSplitters: optional(boolean()), + showCloseButton: optional(boolean()), + showSaveButton: optional(boolean()), + allowWorkspaceTabReorder: optional(boolean()), + allowWorkspaceTabExtract: optional(boolean()), + showWindowCloseButtons: optional(boolean()), + showAddWindowButtons: optional(boolean()), + showEjectButtons: optional(boolean()), + }); + const lockWorkspaceDecoder = object({ + workspaceId: nonEmptyStringDecoder, + config: optional(workspaceLockConfigDecoder) + }); + const windowLockConfigDecoder = object({ + allowExtract: optional(boolean()), + allowReorder: optional(boolean()), + showCloseButton: optional(boolean()) + }); + const elementResizeConfigDecoder = object({ + width: optional(nonNegativeNumberDecoder), + height: optional(nonNegativeNumberDecoder) + }); + const lockWindowDecoder = object({ + windowPlacementId: nonEmptyStringDecoder, + config: optional(windowLockConfigDecoder) + }); + const rowLockConfigDecoder = object({ + allowDrop: optional(boolean()), + allowSplitters: optional(boolean()), + }); + const columnLockConfigDecoder = object({ + allowDrop: optional(boolean()), + allowSplitters: optional(boolean()), + }); + const groupLockConfigDecoder = object({ + allowExtract: optional(boolean()), + allowReorder: optional(boolean()), + allowDrop: optional(boolean()), + allowDropLeft: optional(boolean()), + allowDropRight: optional(boolean()), + allowDropTop: optional(boolean()), + allowDropBottom: optional(boolean()), + allowDropHeader: optional(boolean()), + showMaximizeButton: optional(boolean()), + showEjectButton: optional(boolean()), + showAddWindowButton: optional(boolean()), + }); + const lockRowDecoder = object({ + itemId: nonEmptyStringDecoder, + type: constant("row"), + config: optional(rowLockConfigDecoder) + }); + const lockColumnDecoder = object({ + itemId: nonEmptyStringDecoder, + type: constant("column"), + config: optional(columnLockConfigDecoder) + }); + const lockGroupDecoder = object({ + itemId: nonEmptyStringDecoder, + type: constant("group"), + config: optional(groupLockConfigDecoder) + }); + const lockContainerDecoder = oneOf(lockRowDecoder, lockColumnDecoder, lockGroupDecoder); + const pinWorkspaceDecoder = object({ + workspaceId: nonEmptyStringDecoder, + icon: optional(nonEmptyStringDecoder) + }); + const setWorkspaceIconDecoder = object({ + workspaceId: nonEmptyStringDecoder, + icon: optional(nonEmptyStringDecoder) + }); + const workspacePinOptionsDecoder = optional(object({ + icon: optional(nonEmptyStringDecoder) + })); + const shortcutConfigDecoder = object({ + shortcut: nonEmptyStringDecoder, + frameId: nonEmptyStringDecoder + }); + const shortcutClickedDataDecoder = object({ + shortcut: nonEmptyStringDecoder, + frameId: nonEmptyStringDecoder + }); + const setMaximizationBoundaryAPIConfigDecoder = object({ + enabled: boolean() + }); + const loadingAnimationConfigDecoder = object({ + itemId: nonEmptyStringDecoder, + type: loadingAnimationTypeDecoder + }); + const operationCheckConfigDecoder = object({ + operation: nonEmptyStringDecoder + }); + const setWindowDragModeDecoder = object({ + itemId: nonEmptyStringDecoder, + dragMode: windowDragModeDecoder + }); + const setLoadingStrategyDecoder = object({ + itemId: nonEmptyStringDecoder, + strategy: loadingStrategyDecoder + }); + + const webPlatformMethodName = "T42.Web.Platform.Control"; + const webPlatformWspStreamName = "T42.Web.Platform.WSP.Stream"; + const OUTGOING_METHODS = { + control: { name: "T42.Workspaces.Control", isStream: false }, + frameStream: { name: "T42.Workspaces.Stream.Frame", isStream: true }, + workspaceStream: { name: "T42.Workspaces.Stream.Workspace", isStream: true }, + containerStream: { name: "T42.Workspaces.Stream.Container", isStream: true }, + windowStream: { name: "T42.Workspaces.Stream.Window", isStream: true } + }; + const INCOMING_METHODS = { + control: { name: "T42.Workspaces.Client.Control", isStream: false }, + }; + const STREAMS = { + frame: { name: "T42.Workspaces.Stream.Frame", payloadDecoder: frameStreamDataDecoder }, + workspace: { name: "T42.Workspaces.Stream.Workspace", payloadDecoder: workspaceStreamDataDecoder }, + container: { name: "T42.Workspaces.Stream.Container", payloadDecoder: containerStreamDataDecoder }, + window: { name: "T42.Workspaces.Stream.Window", payloadDecoder: windowStreamDataDecoder } + }; + const CLIENT_OPERATIONS = { + shortcutClicked: { name: "shortcutClicked", argsDecoder: shortcutClickedDataDecoder, resultDecoder: voidResultDecoder }, + }; + const OPERATIONS = { + ping: { name: "ping", resultDecoder: pingResultDecoder }, + isWindowInWorkspace: { name: "isWindowInWorkspace", argsDecoder: simpleItemConfigDecoder, resultDecoder: isWindowInSwimlaneResultDecoder }, + createWorkspace: { name: "createWorkspace", resultDecoder: workspaceSnapshotResultDecoder, argsDecoder: workspaceCreateConfigDecoder }, + createFrame: { name: "createFrame", resultDecoder: frameSummaryResultDecoder, argsDecoder: emptyFrameDefinitionDecoder }, + initFrame: { name: "initFrame", resultDecoder: voidResultDecoder, argsDecoder: frameInitProtocolConfigDecoder }, + getAllFramesSummaries: { name: "getAllFramesSummaries", resultDecoder: frameSummariesResultDecoder }, + getFrameSummary: { name: "getFrameSummary", resultDecoder: frameSummaryDecoder, argsDecoder: getFrameSummaryConfigDecoder }, + getAllWorkspacesSummaries: { name: "getAllWorkspacesSummaries", resultDecoder: workspaceSummariesResultDecoder }, + getWorkspaceSnapshot: { name: "getWorkspaceSnapshot", resultDecoder: workspaceSnapshotResultDecoder, argsDecoder: simpleItemConfigDecoder }, + getAllLayoutsSummaries: { name: "getAllLayoutsSummaries", resultDecoder: layoutSummariesDecoder }, + openWorkspace: { name: "openWorkspace", argsDecoder: openWorkspaceConfigDecoder, resultDecoder: workspaceSnapshotResultDecoder }, + deleteLayout: { name: "deleteLayout", resultDecoder: voidResultDecoder, argsDecoder: deleteLayoutConfigDecoder }, + saveLayout: { name: "saveLayout", resultDecoder: workspaceLayoutDecoder, argsDecoder: workspaceLayoutSaveConfigDecoder }, + importLayout: { name: "importLayout", resultDecoder: voidResultDecoder, argsDecoder: workspacesImportLayoutDecoder }, + importLayouts: { name: "importLayouts", resultDecoder: voidResultDecoder, argsDecoder: workspacesImportLayoutsDecoder }, + exportAllLayouts: { name: "exportAllLayouts", resultDecoder: exportedLayoutsResultDecoder }, + restoreItem: { name: "restoreItem", argsDecoder: simpleItemConfigDecoder, resultDecoder: voidResultDecoder }, + maximizeItem: { name: "maximizeItem", argsDecoder: simpleItemConfigDecoder, resultDecoder: voidResultDecoder }, + focusItem: { name: "focusItem", argsDecoder: simpleItemConfigDecoder, resultDecoder: voidResultDecoder }, + closeItem: { name: "closeItem", argsDecoder: simpleItemConfigDecoder, resultDecoder: voidResultDecoder }, + resizeItem: { name: "resizeItem", argsDecoder: resizeItemConfigDecoder, resultDecoder: voidResultDecoder }, + setMaximizationBoundary: { name: "setMaximizationBoundary", argsDecoder: setMaximizationBoundaryConfigDecoder, resultDecoder: voidResultDecoder }, + changeFrameState: { name: "changeFrameState", argsDecoder: frameStateConfigDecoder, resultDecoder: voidResultDecoder }, + getFrameState: { name: "getFrameState", argsDecoder: simpleItemConfigDecoder, resultDecoder: frameStateResultDecoder }, + getFrameBounds: { name: "getFrameBounds", argsDecoder: simpleItemConfigDecoder, resultDecoder: frameBoundsResultDecoder }, + moveFrame: { name: "moveFrame", argsDecoder: moveFrameConfigDecoder, resultDecoder: voidResultDecoder }, + getFrameSnapshot: { name: "getFrameSnapshot", argsDecoder: frameSnapshotConfigDecoder, resultDecoder: frameSnapshotResultDecoder }, + forceLoadWindow: { name: "forceLoadWindow", argsDecoder: simpleItemConfigDecoder, resultDecoder: simpleWindowOperationSuccessResultDecoder }, + ejectWindow: { name: "ejectWindow", argsDecoder: simpleItemConfigDecoder, resultDecoder: simpleWindowOperationSuccessResultDecoder }, + setItemTitle: { name: "setItemTitle", argsDecoder: setItemTitleConfigDecoder, resultDecoder: voidResultDecoder }, + moveWindowTo: { name: "moveWindowTo", argsDecoder: moveWindowConfigDecoder, resultDecoder: voidResultDecoder }, + addWindow: { name: "addWindow", argsDecoder: addWindowConfigDecoder, resultDecoder: addItemResultDecoder }, + addContainer: { name: "addContainer", argsDecoder: addContainerConfigDecoder, resultDecoder: addItemResultDecoder }, + bundleWorkspace: { name: "bundleWorkspace", argsDecoder: bundleWorkspaceConfigDecoder, resultDecoder: voidResultDecoder }, + bundleItem: { name: "bundleItem", argsDecoder: bundleItemConfigDecoder, resultDecoder: voidResultDecoder }, + hibernateWorkspace: { name: "hibernateWorkspace", argsDecoder: workspaceSelectorDecoder, resultDecoder: voidResultDecoder }, + resumeWorkspace: { name: "resumeWorkspace", argsDecoder: workspaceSelectorDecoder, resultDecoder: voidResultDecoder }, + lockWorkspace: { name: "lockWorkspace", argsDecoder: lockWorkspaceDecoder, resultDecoder: voidResultDecoder }, + lockWindow: { name: "lockWindow", argsDecoder: lockWindowDecoder, resultDecoder: voidResultDecoder }, + lockContainer: { name: "lockContainer", argsDecoder: lockContainerDecoder, resultDecoder: voidResultDecoder }, + pinWorkspace: { name: "pinWorkspace", argsDecoder: pinWorkspaceDecoder, resultDecoder: voidResultDecoder }, + unpinWorkspace: { name: "unpinWorkspace", argsDecoder: workspaceSelectorDecoder, resultDecoder: voidResultDecoder }, + getWorkspaceIcon: { name: "getWorkspaceIcon", argsDecoder: workspaceSelectorDecoder, resultDecoder: getWorkspaceIconResultDecoder }, + setWorkspaceIcon: { name: "setWorkspaceIcon", argsDecoder: setWorkspaceIconDecoder, resultDecoder: voidResultDecoder }, + registerShortcut: { name: "registerShortcut", argsDecoder: shortcutConfigDecoder, resultDecoder: voidResultDecoder }, + unregisterShortcut: { name: "unregisterShortcut", argsDecoder: shortcutConfigDecoder, resultDecoder: voidResultDecoder }, + showLoadingAnimation: { name: "showLoadingAnimation", argsDecoder: loadingAnimationConfigDecoder, resultDecoder: voidResultDecoder }, + hideLoadingAnimation: { name: "hideLoadingAnimation", argsDecoder: loadingAnimationConfigDecoder, resultDecoder: voidResultDecoder }, + getPlatformFrameId: { name: "getPlatformFrameId", resultDecoder: getPlatformFrameIdResultDecoder }, + operationCheck: { name: "operationCheck", argsDecoder: operationCheckConfigDecoder, resultDecoder: operationCheckResultDecoder }, + setWindowDragMode: { name: "setWindowDragMode", argsDecoder: setWindowDragModeDecoder, resultDecoder: voidResultDecoder }, + setLoadingStrategy: { name: "setLoadingStrategy", argsDecoder: setLoadingStrategyDecoder, resultDecoder: voidResultDecoder } + }; + + class PromiseWrapper { + resolve; + reject; + promise; + constructor() { + this.promise = new Promise((res, rej) => { + this.resolve = res; + this.reject = rej; + }); + } + } + + class Bridge { + transport; + registry; + activeSubscriptions = []; + pendingSubScriptions = []; + constructor(transport, registry) { + this.transport = transport; + this.registry = registry; + } + async createCoreEventSubscription() { + await this.transport.coreSubscriptionReady(this.handleCoreEvent.bind(this)); + } + handleCoreSubscription(config) { + const registryKey = `${config.eventType}-${config.action}`; + const scope = config.scope; + const scopeId = config.scopeId; + return this.registry.add(registryKey, (args) => { + const scopeConfig = { + type: scope, + id: scopeId + }; + const receivedIds = { + frame: args.frameSummary?.id || args.windowSummary?.config.frameId, + workspace: args.workspaceSummary?.id || args.windowSummary?.config.workspaceId, + container: args.containerSummary?.itemId, + window: args.windowSummary?.itemId + }; + const shouldInvokeCallback = this.checkScopeMatch(scopeConfig, receivedIds); + if (!shouldInvokeCallback) { + return; + } + config.callback(args); + }); + } + async send(operationName, operationArgs) { + const operationDefinition = Object.values(OPERATIONS).find((operation) => operation.name === operationName); + if (!operationDefinition) { + throw new Error(`Cannot find definition for operation name: ${operationName}`); + } + if (operationDefinition.argsDecoder) { + try { + operationDefinition.argsDecoder.runWithException(operationArgs); + } + catch (error) { + throw new Error(`Unexpected internal outgoing validation error: ${error.message}, for input: ${JSON.stringify(error.input)}, for operation ${operationName}`); + } + } + try { + const operationResult = await this.transport.transmitControl(operationDefinition.name, operationArgs); + operationDefinition.resultDecoder.runWithException(operationResult); + return operationResult; + } + catch (error) { + if (error.kind) { + throw new Error(`Unexpected internal incoming validation error: ${error.message}, for input: ${JSON.stringify(error.input)}, for operation ${operationName}`); + } + throw new Error(error.message); + } + } + async subscribe(config) { + const pendingSub = this.getPendingSubscription(config); + if (pendingSub) { + await pendingSub.promise; + } + let activeSub = this.getActiveSubscription(config); + const registryKey = this.getRegistryKey(config); + if (!activeSub) { + const pendingPromise = new PromiseWrapper(); + const pendingSubscription = { + streamType: config.eventType, + level: config.scope, + levelId: config.scopeId, + promise: pendingPromise.promise + }; + this.pendingSubScriptions.push(pendingSubscription); + try { + const stream = STREAMS[config.eventType]; + const gdSub = await this.transport.subscribe(stream.name, this.getBranchKey(config), config.eventType); + gdSub.onData((streamData) => { + const data = streamData.data; + const requestedArgumentsResult = streamRequestArgumentsDecoder.run(streamData.requestArguments); + const actionResult = workspaceEventActionDecoder.run(data.action); + if (!requestedArgumentsResult.ok || !actionResult.ok) { + return; + } + const streamType = requestedArgumentsResult.result.type; + const branch = requestedArgumentsResult.result.branch; + const keyToExecute = `${streamType}-${branch}-${actionResult.result}`; + const validatedPayload = STREAMS[streamType].payloadDecoder.run(data.payload); + if (!validatedPayload.ok) { + return; + } + this.registry.execute(keyToExecute, validatedPayload.result); + }); + activeSub = { + streamType: config.eventType, + level: config.scope, + levelId: config.scopeId, + callbacksCount: 0, + gdSub + }; + this.activeSubscriptions.push(activeSub); + pendingPromise.resolve(); + } + catch (error) { + pendingPromise.reject(error); + throw error; + } + finally { + this.removePendingSubscription(pendingSubscription); + } + } + const unsubscribe = this.registry.add(registryKey, config.callback); + ++activeSub.callbacksCount; + return () => { + unsubscribe(); + --activeSub.callbacksCount; + if (activeSub.callbacksCount === 0) { + activeSub.gdSub.close(); + this.activeSubscriptions.splice(this.activeSubscriptions.indexOf(activeSub), 1); + } + }; + } + onOperation(callback) { + const wrappedCallback = (payload, caller) => { + const operationName = payload.operation; + const operationArgs = payload.data; + const operationDefinition = Object.values(CLIENT_OPERATIONS).find((operation) => operation.name === operationName); + if (!operationDefinition) { + throw new Error(`Cannot find definition for operation name: ${operationName}`); + } + if (operationDefinition.argsDecoder) { + try { + operationDefinition.argsDecoder.runWithException(operationArgs); + } + catch (error) { + throw new Error(`Unexpected internal outgoing validation error: ${error.message}, for input: ${JSON.stringify(error.input)}, for operation ${operationName}`); + } + } + callback(payload, caller); + }; + return this.transport.onInternalMethodInvoked("control", wrappedCallback); + } + checkScopeMatch(scope, receivedIds) { + if (scope.type === "global") { + return true; + } + if (scope.type === "frame" && scope.id === receivedIds.frame) { + return true; + } + if (scope.type === "workspace" && scope.id === receivedIds.workspace) { + return true; + } + if (scope.type === "container" && scope.id === receivedIds.container) { + return true; + } + if (scope.type === "window" && scope.id === receivedIds.window) { + return true; + } + return false; + } + handleCoreEvent(args) { + const data = args.data; + try { + const verifiedAction = workspaceEventActionDecoder.runWithException(data.action); + const verifiedType = eventTypeDecoder.runWithException(data.type); + const verifiedPayload = STREAMS[verifiedType].payloadDecoder.runWithException(data.payload); + const registryKey = `${verifiedType}-${verifiedAction}`; + this.registry.execute(registryKey, verifiedPayload); + } + catch (error) { + console.warn(`Cannot handle event with data ${JSON.stringify(data)}, because of validation error: ${error.message}`); + } + } + getBranchKey(config) { + return config.scope === "global" ? config.scope : `${config.scope}_${config.scopeId}`; + } + getRegistryKey(config) { + return `${config.eventType}-${this.getBranchKey(config)}-${config.action}`; + } + getActiveSubscription(config) { + return this.activeSubscriptions + .find((activeSub) => activeSub.streamType === config.eventType && + activeSub.level === config.scope && + activeSub.levelId === config.scopeId); + } + getPendingSubscription(config) { + return this.pendingSubScriptions + .find((activeSub) => activeSub.streamType === config.eventType && + activeSub.level === config.scope && + activeSub.levelId === config.scopeId); + } + removePendingSubscription(pendingSubscription) { + const index = this.pendingSubScriptions.indexOf(pendingSubscription); + if (index >= 0) { + this.pendingSubScriptions.splice(index, 1); + } + } + } + + const promisePlus = (promise, timeoutMilliseconds, timeoutMessage) => { + return new Promise((resolve, reject) => { + let promiseActive = true; + const timeout = setTimeout(() => { + if (!promiseActive) { + return; + } + promiseActive = false; + const message = timeoutMessage; + reject(message); + }, timeoutMilliseconds); + promise() + .then((result) => { + if (!promiseActive) { + return; + } + promiseActive = false; + clearTimeout(timeout); + resolve(result); + }) + .catch((error) => { + if (!promiseActive) { + return; + } + promiseActive = false; + clearTimeout(timeout); + reject(error); + }); + }); + }; + + const isDesktop = () => { + return typeof window === "undefined" ? + true : + window.glue42gd || window.iodesktop; + }; + const browserGlobal = () => { + return typeof window === "undefined" ? null : + window.glue42core || window.iobrowser; + }; + + class InteropTransport { + agm; + registry; + defaultTransportTimeout = 120000; + coreEventMethodInitiated = false; + corePlatformSubPromise; + constructor(agm, registry) { + this.agm = agm; + this.registry = registry; + } + async initiate(actualWindowId) { + if (isDesktop()) { + await Promise.all(Object.values(OUTGOING_METHODS).map((method) => { + return this.verifyMethodLive(method.name); + })); + await Promise.all(Object.keys(INCOMING_METHODS).map((method) => { + return this.registerMethod(method); + })); + return; + } + const systemId = browserGlobal().communicationId; + await Promise.all([ + this.verifyMethodLive(webPlatformMethodName, systemId), + this.verifyMethodLive(webPlatformWspStreamName, systemId) + ]); + await this.transmitControl("frameHello", { windowId: actualWindowId }); + } + coreSubscriptionReady(eventCallback) { + if (!this.coreEventMethodInitiated) { + this.subscribePlatform(eventCallback); + } + return this.corePlatformSubPromise; + } + subscribePlatform(eventCallback) { + this.coreEventMethodInitiated = true; + const systemId = browserGlobal().communicationId; + this.corePlatformSubPromise = this.agm.subscribe(webPlatformWspStreamName, systemId ? { target: { instance: systemId } } : undefined); + this.corePlatformSubPromise + .then((sub) => { + sub.onData((data) => eventCallback(data.data)); + }); + } + async subscribe(streamName, streamBranch, streamType) { + const subscriptionArgs = { + branch: streamBranch, + type: streamType + }; + let subscription; + try { + subscription = await this.agm.subscribe(streamName, { arguments: subscriptionArgs }); + } + catch (error) { + const message = `Internal subscription error! Error details: stream - ${streamName}, branch: ${streamBranch}. Internal message: ${error.message}`; + throw new Error(message); + } + return subscription; + } + async transmitControl(operation, operationArguments) { + const invocationArguments = isDesktop() ? { operation, operationArguments } : { operation, domain: "workspaces", data: operationArguments }; + const methodName = isDesktop() ? OUTGOING_METHODS.control.name : webPlatformMethodName; + const platformTarget = isDesktop() ? undefined : browserGlobal().communicationId; + let invocationResult; + const baseErrorMessage = `Internal Workspaces Communication Error. Attempted operation: ${JSON.stringify(invocationArguments)}. `; + try { + invocationResult = await this.agm.invoke(methodName, invocationArguments, platformTarget ? { instance: platformTarget } : "best", { methodResponseTimeoutMs: this.defaultTransportTimeout }); + if (!invocationResult) { + throw new Error("Received unsupported result from GD - empty result"); + } + if (!Array.isArray(invocationResult.all_return_values) || invocationResult.all_return_values.length === 0) { + throw new Error("Received unsupported result from GD - empty values collection"); + } + } + catch (error) { + if (error && error.all_errors && error.all_errors.length) { + const invocationErrorMessage = error.all_errors[0].message; + throw new Error(`${baseErrorMessage} -> Inner message: ${invocationErrorMessage}`); + } + throw new Error(`${baseErrorMessage} -> Inner message: ${error.message}`); + } + return invocationResult.all_return_values[0].returned; + } + onInternalMethodInvoked(key, callback) { + return this.registry.add(key, callback); + } + verifyMethodLive(name, systemId) { + return promisePlus(() => { + return new Promise((resolve) => { + const hasMethod = this.agm.methods().some((method) => { + const nameMatch = method.name === name; + const serverMatch = systemId ? + method.getServers().some((server) => server.instance === systemId) : + true; + return nameMatch && serverMatch; + }); + if (hasMethod) { + resolve(); + return; + } + const unSub = this.agm.serverMethodAdded((data) => { + const method = data.method; + const server = data.server; + const serverMatch = systemId ? + server.instance === systemId : + true; + if (method.name === name && serverMatch) { + unSub(); + resolve(); + } + }); + }); + }, 15000, "Timeout waiting for the Workspaces communication channels"); + } + registerMethod(key) { + const method = INCOMING_METHODS[key]; + return this.agm.register(method.name, (args, caller) => { + this.registry.execute(key, args, caller); + }); + } + } + + const privateData$4 = new WeakMap(); + class ParentBuilder { + constructor(definition, base) { + const children = base.wrapChildren(definition.children); + delete definition.children; + privateData$4.set(this, { base, children, definition }); + } + get type() { + return privateData$4.get(this).definition.type; + } + addColumn(definition) { + const base = privateData$4.get(this).base; + return base.add("column", privateData$4.get(this).children, definition); + } + addRow(definition) { + const base = privateData$4.get(this).base; + return base.add("row", privateData$4.get(this).children, definition); + } + addGroup(definition) { + const base = privateData$4.get(this).base; + return base.add("group", privateData$4.get(this).children, definition); + } + addWindow(definition) { + const base = privateData$4.get(this).base; + base.addWindow(privateData$4.get(this).children, definition); + return this; + } + serialize() { + const definition = privateData$4.get(this).definition; + definition.children = privateData$4.get(this).base.serializeChildren(privateData$4.get(this).children); + return definition; + } + } + + class BaseBuilder { + getBuilder; + constructor(getBuilder) { + this.getBuilder = getBuilder; + } + wrapChildren(children) { + return children.map((child) => { + if (child.type === "window") { + return child; + } + return this.getBuilder({ type: child.type, definition: child }); + }); + } + add(type, children, definition) { + const validatedDefinition = parentDefinitionDecoder.runWithException(definition); + const childBuilder = this.getBuilder({ type, definition: validatedDefinition }); + children.push(childBuilder); + return childBuilder; + } + addWindow(children, definition) { + const validatedDefinition = swimlaneWindowDefinitionDecoder.runWithException(definition); + validatedDefinition.type = "window"; + children.push(validatedDefinition); + } + serializeChildren(children) { + return children.map((child) => { + if (child instanceof ParentBuilder) { + return child.serialize(); + } + else { + return child; + } + }); + } + } + + const privateData$3 = new WeakMap(); + class WorkspaceBuilder { + constructor(definition, base, controller) { + const children = base.wrapChildren(definition.children); + delete definition.children; + privateData$3.set(this, { base, children, definition, controller }); + } + addColumn(definition) { + const children = privateData$3.get(this).children; + const areAllColumns = children.every((child) => child instanceof ParentBuilder && child.type === "column"); + if (!areAllColumns) { + throw new Error("Cannot add a column to this workspace, because there are already children of another type"); + } + const base = privateData$3.get(this).base; + return base.add("column", children, definition); + } + addRow(definition) { + const children = privateData$3.get(this).children; + const areAllRows = children.every((child) => child instanceof ParentBuilder && child.type === "row"); + if (!areAllRows) { + throw new Error("Cannot add a row to this workspace, because there are already children of another type"); + } + const base = privateData$3.get(this).base; + return base.add("row", children, definition); + } + addGroup(definition) { + const children = privateData$3.get(this).children; + if (children.length !== 0) { + throw new Error("Cannot add a group to this workspace, because there are already defined children."); + } + const base = privateData$3.get(this).base; + return base.add("group", children, definition); + } + addWindow(definition) { + const children = privateData$3.get(this).children; + if (children.length !== 0) { + throw new Error("Cannot add a window to this workspace, because there are already defined children."); + } + const base = privateData$3.get(this).base; + base.addWindow(children, definition); + return this; + } + getChildAt(index) { + nonNegativeNumberDecoder.runWithException(index); + const data = privateData$3.get(this).children; + return data[index]; + } + async create(config) { + const saveConfig = workspaceBuilderCreateConfigDecoder.runWithException(config); + const definition = privateData$3.get(this).definition; + definition.children = privateData$3.get(this).base.serializeChildren(privateData$3.get(this).children); + const controller = privateData$3.get(this).controller; + return controller.createWorkspace(definition, saveConfig); + } + } + + const privateData$2 = new WeakMap(); + const getBase$2 = (model) => { + return privateData$2.get(model).base; + }; + class Row { + constructor(base) { + privateData$2.set(this, { base }); + } + get type() { + return "row"; + } + get id() { + return getBase$2(this).getId(this); + } + get frameId() { + return getBase$2(this).getFrameId(this); + } + get workspaceId() { + return getBase$2(this).getWorkspaceId(this); + } + get positionIndex() { + return getBase$2(this).getPositionIndex(this); + } + get children() { + return getBase$2(this).getAllChildren(this); + } + get parent() { + return getBase$2(this).getMyParent(this); + } + get frame() { + return getBase$2(this).getMyFrame(this); + } + get workspace() { + return getBase$2(this).getMyWorkspace(this); + } + get allowDrop() { + return getBase$2(this).getAllowDrop(this); + } + get allowSplitters() { + return getBase$2(this).getAllowSplitters(this); + } + get minWidth() { + return getBase$2(this).getMinWidth(this); + } + get minHeight() { + return getBase$2(this).getMinHeight(this); + } + get maxWidth() { + return getBase$2(this).getMaxWidth(this); + } + get maxHeight() { + return getBase$2(this).getMaxHeight(this); + } + get width() { + return getBase$2(this).getWidthInPx(this); + } + get height() { + return getBase$2(this).getHeightInPx(this); + } + get isPinned() { + return getBase$2(this).getIsPinned(this); + } + get isMaximized() { + return getBase$2(this).getIsMaximized(this); + } + get maximizationBoundary() { + return getBase$2(this).getMaximizationBoundary(this); + } + addWindow(definition) { + return getBase$2(this).addWindow(this, definition, "row"); + } + async addGroup(definition) { + if (definition?.type && definition.type !== "group") { + throw new Error(`Expected a group definition, but received ${definition.type}`); + } + return getBase$2(this).addParent(this, "group", "row", definition); + } + async addColumn(definition) { + if (definition?.type && definition.type !== "column") { + throw new Error(`Expected a column definition, but received ${definition.type}`); + } + return getBase$2(this).addParent(this, "column", "row", definition); + } + async addRow() { + throw new Error("Adding rows as row children is not supported"); + } + removeChild(predicate) { + return getBase$2(this).removeChild(this, predicate); + } + maximize() { + return getBase$2(this).maximize(this); + } + restore() { + return getBase$2(this).restore(this); + } + close() { + return getBase$2(this).close(this); + } + lock(config) { + let lockConfigResult = undefined; + if (typeof config === "function") { + const currentLockConfig = { + allowDrop: this.allowDrop, + allowSplitters: this.allowSplitters + }; + lockConfigResult = config(currentLockConfig); + } + else { + lockConfigResult = config; + } + const verifiedConfig = lockConfigResult === undefined ? undefined : rowLockConfigDecoder.runWithException(lockConfigResult); + return getBase$2(this).lockContainer(this, verifiedConfig); + } + async setHeight(height) { + nonNegativeNumberDecoder.runWithException(height); + return getBase$2(this).setHeight(this, height); + } + async onLockConfigurationChanged(callback) { + checkThrowCallback(callback); + const wrappedCallback = async () => { + await this.workspace.refreshReference(); + callback({ + allowDrop: this.allowDrop, + allowSplitters: this.allowSplitters + }); + }; + const config = { + callback: wrappedCallback, + action: "lock-configuration-changed", + eventType: "container", + scope: "container" + }; + const unsubscribe = await getBase$2(this).processLocalSubscription(this, config); + return unsubscribe; + } + async setMaximizationBoundary(config) { + const validatedConfig = setMaximizationBoundaryAPIConfigDecoder.runWithException(config); + return getBase$2(this).setMaximizationBoundary(this, validatedConfig); + } + } + + const privateData$1 = new WeakMap(); + const getBase$1 = (model) => { + return privateData$1.get(model).base; + }; + class Column { + constructor(base) { + privateData$1.set(this, { base }); + } + get type() { + return "column"; + } + get id() { + return getBase$1(this).getId(this); + } + get frameId() { + return getBase$1(this).getFrameId(this); + } + get workspaceId() { + return getBase$1(this).getWorkspaceId(this); + } + get positionIndex() { + return getBase$1(this).getPositionIndex(this); + } + get children() { + return getBase$1(this).getAllChildren(this); + } + get parent() { + return getBase$1(this).getMyParent(this); + } + get frame() { + return getBase$1(this).getMyFrame(this); + } + get workspace() { + return getBase$1(this).getMyWorkspace(this); + } + get allowDrop() { + return getBase$1(this).getAllowDrop(this); + } + get allowSplitters() { + return getBase$1(this).getAllowSplitters(this); + } + get minWidth() { + return getBase$1(this).getMinWidth(this); + } + get minHeight() { + return getBase$1(this).getMinHeight(this); + } + get maxWidth() { + return getBase$1(this).getMaxWidth(this); + } + get maxHeight() { + return getBase$1(this).getMaxHeight(this); + } + get width() { + return getBase$1(this).getWidthInPx(this); + } + get height() { + return getBase$1(this).getHeightInPx(this); + } + get isPinned() { + return getBase$1(this).getIsPinned(this); + } + get isMaximized() { + return getBase$1(this).getIsMaximized(this); + } + get maximizationBoundary() { + return getBase$1(this).getMaximizationBoundary(this); + } + addWindow(definition) { + return getBase$1(this).addWindow(this, definition, "column"); + } + async addGroup(definition) { + if (definition?.type && definition.type !== "group") { + throw new Error(`Expected a group definition, but received ${definition.type}`); + } + return getBase$1(this).addParent(this, "group", "column", definition); + } + async addColumn() { + throw new Error("Adding columns as column children is not supported"); + } + async addRow(definition) { + if (definition?.type && definition.type !== "row") { + throw new Error(`Expected a row definition, but received ${definition.type}`); + } + return getBase$1(this).addParent(this, "row", "column", definition); + } + removeChild(predicate) { + return getBase$1(this).removeChild(this, predicate); + } + maximize() { + return getBase$1(this).maximize(this); + } + restore() { + return getBase$1(this).restore(this); + } + close() { + return getBase$1(this).close(this); + } + lock(config) { + let lockConfigResult = undefined; + if (typeof config === "function") { + const currentLockConfig = { + allowDrop: this.allowDrop, + allowSplitters: this.allowSplitters + }; + lockConfigResult = config(currentLockConfig); + } + else { + lockConfigResult = config; + } + const verifiedConfig = lockConfigResult === undefined ? undefined : columnLockConfigDecoder.runWithException(lockConfigResult); + return getBase$1(this).lockContainer(this, verifiedConfig); + } + async setWidth(width) { + nonNegativeNumberDecoder.runWithException(width); + return getBase$1(this).setWidth(this, width); + } + async onLockConfigurationChanged(callback) { + checkThrowCallback(callback); + const wrappedCallback = async () => { + await this.workspace.refreshReference(); + callback({ + allowDrop: this.allowDrop, + allowSplitters: this.allowSplitters + }); + }; + const config = { + callback: wrappedCallback, + action: "lock-configuration-changed", + eventType: "container", + scope: "container" + }; + const unsubscribe = await getBase$1(this).processLocalSubscription(this, config); + return unsubscribe; + } + async setMaximizationBoundary(config) { + const validatedConfig = setMaximizationBoundaryAPIConfigDecoder.runWithException(config); + return getBase$1(this).setMaximizationBoundary(this, validatedConfig); + } + } + + const privateData = new WeakMap(); + const getBase = (model) => { + return privateData.get(model).base; + }; + class Group { + constructor(base) { + privateData.set(this, { base }); + } + get type() { + return "group"; + } + get id() { + return getBase(this).getId(this); + } + get frameId() { + return getBase(this).getFrameId(this); + } + get workspaceId() { + return getBase(this).getWorkspaceId(this); + } + get positionIndex() { + return getBase(this).getPositionIndex(this); + } + get children() { + return getBase(this).getAllChildren(this); + } + get parent() { + return getBase(this).getMyParent(this); + } + get frame() { + return getBase(this).getMyFrame(this); + } + get workspace() { + return getBase(this).getMyWorkspace(this); + } + get allowExtract() { + return getBase(this).getAllowExtract(this); + } + get allowReorder() { + return getBase(this).getAllowReorder(this); + } + get allowDropLeft() { + return getBase(this).getAllowDropLeft(this); + } + get allowDropRight() { + return getBase(this).getAllowDropRight(this); + } + get allowDropTop() { + return getBase(this).getAllowDropTop(this); + } + get allowDropBottom() { + return getBase(this).getAllowDropBottom(this); + } + get allowDropHeader() { + return getBase(this).getAllowDropHeader(this); + } + get allowDrop() { + return getBase(this).getAllowDrop(this); + } + get showMaximizeButton() { + return getBase(this).getShowMaximizeButton(this); + } + get showEjectButton() { + return getBase(this).getShowEjectButton(this); + } + get showAddWindowButton() { + return getBase(this).getShowAddWindowButton(this); + } + get minWidth() { + return getBase(this).getMinWidth(this); + } + get minHeight() { + return getBase(this).getMinHeight(this); + } + get maxWidth() { + return getBase(this).getMaxWidth(this); + } + get maxHeight() { + return getBase(this).getMaxHeight(this); + } + get width() { + return getBase(this).getWidthInPx(this); + } + get height() { + return getBase(this).getHeightInPx(this); + } + get isMaximized() { + return getBase(this).getIsMaximized(this); + } + addWindow(definition) { + return getBase(this).addWindow(this, definition, "group"); + } + async addGroup() { + throw new Error("Adding groups as group child is not supported"); + } + async addColumn() { + throw new Error("Adding columns as group child is not supported"); + } + async addRow() { + throw new Error("Adding rows as group child is not supported"); + } + removeChild(predicate) { + return getBase(this).removeChild(this, predicate); + } + maximize() { + return getBase(this).maximize(this); + } + restore() { + return getBase(this).restore(this); + } + close() { + return getBase(this).close(this); + } + lock(config) { + let lockConfigResult = undefined; + if (typeof config === "function") { + const currentLockConfig = { + allowDrop: this.allowDrop, + allowDropHeader: this.allowDropHeader, + allowDropLeft: this.allowDropLeft, + allowDropRight: this.allowDropRight, + allowDropTop: this.allowDropTop, + allowDropBottom: this.allowDropBottom, + allowExtract: this.allowExtract, + allowReorder: this.allowReorder, + showAddWindowButton: this.showAddWindowButton, + showEjectButton: this.showEjectButton, + showMaximizeButton: this.showMaximizeButton + }; + lockConfigResult = config(currentLockConfig); + } + else { + lockConfigResult = config; + } + const verifiedConfig = lockConfigResult === undefined ? undefined : groupLockConfigDecoder.runWithException(lockConfigResult); + return getBase(this).lockContainer(this, verifiedConfig); + } + async setSize(config) { + const verifiedConfig = elementResizeConfigDecoder.runWithException(config); + if (!verifiedConfig.width && !verifiedConfig.height) { + throw new Error("Expected either width or height to be passed."); + } + return getBase(this).setSize(this, config.width, config.height); + } + async bundleToRow() { + await getBase(this).bundleTo(this, "row"); + await this.workspace.refreshReference(); + } + async bundleToColumn() { + await getBase(this).bundleTo(this, "column"); + await this.workspace.refreshReference(); + } + async onLockConfigurationChanged(callback) { + checkThrowCallback(callback); + const wrappedCallback = async () => { + await this.workspace.refreshReference(); + callback({ + allowDrop: this.allowDrop, + allowDropHeader: this.allowDropHeader, + allowDropLeft: this.allowDropLeft, + allowDropTop: this.allowDropTop, + allowDropRight: this.allowDropRight, + allowDropBottom: this.allowDropBottom, + allowExtract: this.allowExtract, + allowReorder: this.allowReorder, + showAddWindowButton: this.showAddWindowButton, + showEjectButton: this.showEjectButton, + showMaximizeButton: this.showMaximizeButton + }); + }; + const config = { + callback: wrappedCallback, + action: "lock-configuration-changed", + eventType: "container", + scope: "container" + }; + const unsubscribe = await getBase(this).processLocalSubscription(this, config); + return unsubscribe; + } + } + + const DEFAULT_WINDOW_DRAG_MODE = "keepInside"; + + const data$3 = new WeakMap(); + const getData$3 = (model) => { + return data$3.get(model).manager.getWorkspaceData(model); + }; + const getDataManager = (model) => { + return data$3.get(model).manager; + }; + class Workspace { + constructor(dataManager) { + data$3.set(this, { manager: dataManager }); + } + get id() { + return getData$3(this).id; + } + get frameId() { + return getData$3(this).config.frameId; + } + get positionIndex() { + return getData$3(this).config.positionIndex; + } + get title() { + return getData$3(this).config.title; + } + get layoutName() { + return getData$3(this).config.layoutName; + } + get isHibernated() { + return getData$3(this).config.isHibernated; + } + get isSelected() { + return getData$3(this).config.isSelected; + } + get children() { + return getData$3(this).children; + } + get frame() { + return getData$3(this).frame; + } + get allowSplitters() { + return getData$3(this).config.allowSplitters; + } + get allowSystemHibernation() { + return getData$3(this).config.allowSystemHibernation; + } + get allowDrop() { + return getData$3(this).config.allowDrop; + } + get allowDropLeft() { + return getData$3(this).config.allowDropLeft; + } + get allowDropTop() { + return getData$3(this).config.allowDropTop; + } + get allowDropRight() { + return getData$3(this).config.allowDropRight; + } + get allowDropBottom() { + return getData$3(this).config.allowDropBottom; + } + get allowExtract() { + return getData$3(this).config.allowExtract; + } + get allowWindowReorder() { + return getData$3(this).config.allowWindowReorder; + } + get showCloseButton() { + return getData$3(this).config.showCloseButton; + } + get showSaveButton() { + return getData$3(this).config.showSaveButton; + } + get allowWorkspaceTabReorder() { + return getData$3(this).config.allowWorkspaceTabReorder; + } + get allowWorkspaceTabExtract() { + return getData$3(this).config.allowWorkspaceTabExtract; + } + get minWidth() { + return getData$3(this).config.minWidth; + } + get minHeight() { + return getData$3(this).config.minHeight; + } + get maxWidth() { + return getData$3(this).config.maxWidth; + } + get maxHeight() { + return getData$3(this).config.maxHeight; + } + get width() { + return getData$3(this).config.widthInPx; + } + get height() { + return getData$3(this).config.heightInPx; + } + get showWindowCloseButtons() { + return getData$3(this).config.showWindowCloseButtons; + } + get showEjectButtons() { + return getData$3(this).config.showEjectButtons; + } + get showAddWindowButtons() { + return getData$3(this).config.showAddWindowButtons; + } + get isPinned() { + return getData$3(this).config.isPinned; + } + get windowDragMode() { + const desktopGlobal = isDesktop(); + if (!desktopGlobal) { + return DEFAULT_WINDOW_DRAG_MODE; + } + return getData$3(this).config.windowDragMode; + } + get loadingStrategy() { + if (!isDesktop()) { + console.warn("The workspace.loadingStrategy property is not supported in IO Connect Browser"); + } + return getData$3(this).config.loadingStrategy; + } + async setLoadingStrategy(strategy) { + if (!isDesktop()) { + throw new Error("Not supported in IO Connect Browser"); + } + const controller = getData$3(this).controller; + await controller.setLoadingStrategy(this.id, strategy); + await this.refreshReference(); + } + async removeChild(predicate) { + checkThrowCallback(predicate); + const child = this.children.find(predicate); + if (!child) { + return; + } + await child.close(); + await this.refreshReference(); + } + async remove(predicate) { + checkThrowCallback(predicate); + const controller = getData$3(this).controller; + const child = controller.iterateFindChild(this.children, predicate); + await child.close(); + await this.refreshReference(); + } + async focus() { + await getData$3(this).controller.focusItem(this.id); + await this.refreshReference(); + } + async close() { + const controller = getData$3(this).controller; + const workspaces = await getData$3(this).frame.workspaces(); + const platformFrameId = (await controller.getPlatformFrameId()).id; + const shouldCloseFrame = workspaces.length === 1 && + workspaces.every((wsp) => wsp.id === this.id) && + platformFrameId !== this.frame.id; + if (shouldCloseFrame) { + return this.frame.close(); + } + await controller.closeItem(this.id); + } + snapshot() { + return getData$3(this).controller.getSnapshot(this.id, "workspace"); + } + async saveLayout(name, config) { + nonEmptyStringDecoder.runWithException(name); + await getData$3(this).controller.saveLayout({ name, workspaceId: this.id, saveContext: config?.saveContext, metadata: config?.metadata, allowMultiple: config?.allowMultiple }); + } + async setTitle(title) { + nonEmptyStringDecoder.runWithException(title); + const controller = getData$3(this).controller; + await controller.setItemTitle(this.id, title); + await this.refreshReference(); + } + getContext() { + const controller = getData$3(this).controller; + return controller.getWorkspaceContext(this.id); + } + setContext(data) { + const controller = getData$3(this).controller; + return controller.setWorkspaceContext(this.id, data); + } + updateContext(data) { + const controller = getData$3(this).controller; + return controller.updateWorkspaceContext(this.id, data); + } + onContextUpdated(callback) { + const controller = getData$3(this).controller; + return controller.subscribeWorkspaceContextUpdated(this.id, callback); + } + async refreshReference() { + const newSnapshot = (await getData$3(this).controller.getSnapshot(this.id, "workspace")); + const currentChildrenFlat = getData$3(this).controller.flatChildren(getData$3(this).children); + const newChildren = getData$3(this).controller.refreshChildren({ + existingChildren: currentChildrenFlat, + workspace: this, + parent: this, + children: newSnapshot.children + }); + const currentFrame = this.frame; + let actualFrame; + if (currentFrame.id === newSnapshot.config.frameId) { + getDataManager(this).remapFrame(currentFrame, newSnapshot.frameSummary); + actualFrame = currentFrame; + } + else { + const frameCreateConfig = { + summary: newSnapshot.frameSummary + }; + const newFrame = getData$3(this).ioc.getModel("frame", frameCreateConfig); + actualFrame = newFrame; + } + getDataManager(this).remapWorkspace(this, { + config: newSnapshot.config, + children: newChildren, + frame: actualFrame + }); + } + async getIcon() { + const controller = getData$3(this).controller; + return controller.getWorkspaceIcon(this.id); + } + async setIcon(icon) { + const controller = getData$3(this).controller; + return controller.setWorkspaceIcon(this.id, icon); + } + getBox(predicate) { + checkThrowCallback(predicate); + const children = getData$3(this).children; + const controller = getData$3(this).controller; + return controller.iterateFindChild(children, (child) => child.type !== "window" && predicate(child)); + } + getAllBoxes(predicate) { + checkThrowCallback(predicate, true); + const children = getData$3(this).children; + const controller = getData$3(this).controller; + const allParents = controller.iterateFilterChildren(children, (child) => child.type !== "window"); + if (!predicate) { + return allParents; + } + return allParents.filter(predicate); + } + getRow(predicate) { + checkThrowCallback(predicate); + return this.getBox((parent) => parent.type === "row" && predicate(parent)); + } + getAllRows(predicate) { + checkThrowCallback(predicate, true); + if (predicate) { + return this.getAllBoxes((parent) => parent.type === "row" && predicate(parent)); + } + return this.getAllBoxes((parent) => parent.type === "row"); + } + getColumn(predicate) { + checkThrowCallback(predicate); + return this.getBox((parent) => parent.type === "column" && predicate(parent)); + } + getAllColumns(predicate) { + checkThrowCallback(predicate, true); + if (predicate) { + return this.getAllBoxes((parent) => parent.type === "column" && predicate(parent)); + } + return this.getAllBoxes((parent) => parent.type === "column"); + } + getGroup(predicate) { + checkThrowCallback(predicate); + return this.getBox((parent) => parent.type === "group" && predicate(parent)); + } + getAllGroups(predicate) { + checkThrowCallback(predicate, true); + if (predicate) { + return this.getAllBoxes((parent) => parent.type === "group" && predicate(parent)); + } + return this.getAllBoxes((parent) => parent.type === "group"); + } + getWindow(predicate) { + checkThrowCallback(predicate); + const children = getData$3(this).children; + const controller = getData$3(this).controller; + return controller.iterateFindChild(children, (child) => child.type === "window" && predicate(child)); + } + getAllWindows(predicate) { + checkThrowCallback(predicate, true); + const children = getData$3(this).children; + const controller = getData$3(this).controller; + const allWindows = controller.iterateFilterChildren(children, (child) => child.type === "window"); + if (!predicate) { + return allWindows; + } + return allWindows.filter(predicate); + } + addRow(definition) { + return getData$3(this).base.addParent(this, "row", "workspace", definition); + } + addColumn(definition) { + return getData$3(this).base.addParent(this, "column", "workspace", definition); + } + addGroup(definition) { + return getData$3(this).base.addParent(this, "group", "workspace", definition); + } + addWindow(definition) { + return getData$3(this).base.addWindow(this, definition, "workspace"); + } + async bundleToRow() { + await getData$3(this).controller.bundleWorkspaceTo("row", this.id); + await this.refreshReference(); + } + async bundleToColumn() { + await getData$3(this).controller.bundleWorkspaceTo("column", this.id); + await this.refreshReference(); + } + async hibernate() { + await getData$3(this).controller.hibernateWorkspace(this.id); + await this.refreshReference(); + } + async resume() { + await getData$3(this).controller.resumeWorkspace(this.id); + await this.refreshReference(); + } + async lock(config) { + let lockConfigResult = undefined; + if (typeof config === "function") { + const currentLockConfig = { + allowDrop: this.allowDrop, + allowDropLeft: this.allowDropLeft, + allowDropTop: this.allowDropTop, + allowDropRight: this.allowDropRight, + allowDropBottom: this.allowDropBottom, + allowSystemHibernation: this.allowSystemHibernation, + allowExtract: this.allowExtract, + allowWindowReorder: this.allowWindowReorder, + allowSplitters: this.allowSplitters, + showCloseButton: this.showCloseButton, + showSaveButton: this.showSaveButton, + allowWorkspaceTabReorder: this.allowWorkspaceTabReorder, + allowWorkspaceTabExtract: this.allowWorkspaceTabExtract, + showAddWindowButtons: this.showAddWindowButtons, + showEjectButtons: this.showEjectButtons, + showWindowCloseButtons: this.showWindowCloseButtons + }; + lockConfigResult = config(currentLockConfig); + } + else { + lockConfigResult = config; + } + const verifiedConfig = lockConfigResult === undefined ? undefined : workspaceLockConfigDecoder.runWithException(lockConfigResult); + await getData$3(this).controller.lockWorkspace(this.id, verifiedConfig); + await this.refreshReference(); + } + async pin(options) { + workspacePinOptionsDecoder.runWithException(options); + await getData$3(this).controller.pinWorkspace(this.id, options?.icon); + await this.refreshReference(); + } + async unpin() { + await getData$3(this).controller.unpinWorkspace(this.id); + await this.refreshReference(); + } + async showLoadingAnimation() { + if (!isDesktop()) { + throw new Error("Not supported in IO Connect Browser"); + } + await getData$3(this).controller.showWorkspaceLoadingAnimation(this.id); + } + async hideLoadingAnimation() { + if (!isDesktop()) { + throw new Error("Not supported in IO Connect Browser"); + } + await getData$3(this).controller.hideWorkspaceLoadingAnimation(this.id); + } + async setWindowDragMode(mode) { + const desktopGlobal = isDesktop(); + if (!desktopGlobal) { + throw new Error("Not supported in IO Connect Browser"); + } + windowDragModeDecoder.runWithException(mode); + await getData$3(this).controller.setWindowDragMode(this.id, mode); + await this.refreshReference(); + } + async onClosed(callback) { + checkThrowCallback(callback); + const id = getData$3(this).id; + const wrappedCallback = async (payload) => { + callback({ frameId: payload.frameSummary.id, workspaceId: payload.workspaceSummary.id, frameBounds: payload.frameBounds }); + }; + const config = { + action: "closed", + eventType: "workspace", + scope: "workspace", + scopeId: id, + callback: wrappedCallback + }; + const unsubscribe = await getData$3(this).controller.processLocalSubscription(config, id); + return unsubscribe; + } + async onHibernated(callback) { + checkThrowCallback(callback); + const id = getData$3(this).id; + const wrappedCallback = async () => { + await this.refreshReference(); + callback(); + }; + const config = { + action: "hibernated", + eventType: "workspace", + scope: "workspace", + scopeId: id, + callback: wrappedCallback + }; + const unsubscribe = await getData$3(this).controller.processLocalSubscription(config, id); + return unsubscribe; + } + async onResumed(callback) { + checkThrowCallback(callback); + const id = getData$3(this).id; + const wrappedCallback = async () => { + await this.refreshReference(); + callback(); + }; + const config = { + action: "resumed", + eventType: "workspace", + scope: "workspace", + scopeId: id, + callback: wrappedCallback + }; + const unsubscribe = await getData$3(this).controller.processLocalSubscription(config, id); + return unsubscribe; + } + async onWindowAdded(callback) { + checkThrowCallback(callback); + const id = getData$3(this).id; + const wrappedCallback = async (payload) => { + await this.refreshReference(); + const windowParent = this.getBox((parent) => parent.id === payload.windowSummary.parentId); + const foundWindow = windowParent.children.find((child) => { + return child.type === "window" && child.elementId === payload.windowSummary.itemId; + }); + callback(foundWindow); + }; + const config = { + action: "added", + eventType: "window", + scope: "workspace", + scopeId: id, + callback: wrappedCallback + }; + const unsubscribe = await getData$3(this).controller.processLocalSubscription(config, id); + return unsubscribe; + } + async onWindowRemoved(callback) { + checkThrowCallback(callback); + const id = getData$3(this).id; + const wrappedCallback = async (payload) => { + await this.refreshReference(); + const { windowId, workspaceId, frameId } = payload.windowSummary.config; + callback({ windowId, workspaceId, frameId }); + }; + const config = { + action: "removed", + eventType: "window", + scope: "workspace", + scopeId: id, + callback: wrappedCallback + }; + const unsubscribe = await getData$3(this).controller.processLocalSubscription(config, id); + return unsubscribe; + } + async onWindowLoaded(callback) { + checkThrowCallback(callback); + const id = getData$3(this).id; + const wrappedCallback = async (payload) => { + await this.refreshReference(); + const foundWindow = this.getWindow((win) => { + return win.id && win.id === payload.windowSummary.config.windowId; + }); + callback(foundWindow); + }; + const config = { + action: "loaded", + eventType: "window", + scope: "workspace", + scopeId: id, + callback: wrappedCallback + }; + const unsubscribe = await getData$3(this).controller.processLocalSubscription(config, id); + return unsubscribe; + } + async onWindowMaximized(callback) { + checkThrowCallback(callback); + const id = getData$3(this).id; + const wrappedCallback = async (payload) => { + await this.refreshReference(); + const windowParent = this.getBox((parent) => parent.id === payload.windowSummary.parentId); + const foundWindow = windowParent.children.find((child) => { + return child.type === "window" && child.elementId === payload.windowSummary.itemId; + }); + callback(foundWindow); + }; + const config = { + action: "maximized", + eventType: "window", + scope: "workspace", + scopeId: id, + callback: wrappedCallback + }; + const unsubscribe = await getData$3(this).controller.processLocalSubscription(config, id); + return unsubscribe; + } + async onWindowRestored(callback) { + checkThrowCallback(callback); + const id = getData$3(this).id; + const wrappedCallback = async (payload) => { + await this.refreshReference(); + const windowParent = this.getBox((parent) => parent.id === payload.windowSummary.parentId); + const foundWindow = windowParent.children.find((child) => { + return child.type === "window" && child.elementId === payload.windowSummary.itemId; + }); + callback(foundWindow); + }; + const config = { + action: "restored", + eventType: "window", + scope: "workspace", + scopeId: id, + callback: wrappedCallback + }; + const unsubscribe = await getData$3(this).controller.processLocalSubscription(config, id); + return unsubscribe; + } + async onWindowSelected(callback) { + checkThrowCallback(callback); + const id = getData$3(this).id; + const wrappedCallback = async (payload) => { + await this.refreshReference(); + const windowParent = this.getBox((parent) => parent.id === payload.windowSummary.parentId); + const foundWindow = windowParent.children.find((child) => { + return child.type === "window" && child.elementId === payload.windowSummary.itemId; + }); + callback(foundWindow); + }; + const config = { + action: "selected", + eventType: "window", + scope: "workspace", + scopeId: id, + callback: wrappedCallback + }; + const unsubscribe = await getData$3(this).controller.processLocalSubscription(config, id); + return unsubscribe; + } + async onLockConfigurationChanged(callback) { + checkThrowCallback(callback); + const id = getData$3(this).id; + const wrappedCallback = async () => { + await this.refreshReference(); + callback({ + allowDrop: this.allowDrop, + allowDropLeft: this.allowDropLeft, + allowDropTop: this.allowDropTop, + allowDropRight: this.allowDropRight, + allowDropBottom: this.allowDropBottom, + allowSystemHibernation: this.allowSystemHibernation, + allowExtract: this.allowExtract, + allowSplitters: this.allowSplitters, + allowWindowReorder: this.allowWindowReorder, + allowWorkspaceTabExtract: this.allowWorkspaceTabExtract, + allowWorkspaceTabReorder: this.allowWorkspaceTabReorder, + showAddWindowButtons: this.showAddWindowButtons, + showCloseButton: this.showCloseButton, + showEjectButtons: this.showEjectButtons, + showSaveButton: this.showSaveButton, + showWindowCloseButtons: this.showWindowCloseButtons + }); + }; + const config = { + action: "lock-configuration-changed", + eventType: "workspace", + scope: "workspace", + scopeId: id, + callback: wrappedCallback + }; + const unsubscribe = await getData$3(this).controller.processLocalSubscription(config, id); + return unsubscribe; + } + } + + const data$2 = new WeakMap(); + const getData$2 = (model) => { + return data$2.get(model).manager.getWindowData(model); + }; + class Window { + constructor(dataManager) { + data$2.set(this, { manager: dataManager }); + } + get id() { + return getData$2(this).config.windowId; + } + get elementId() { + return getData$2(this).id; + } + get type() { + return "window"; + } + get frameId() { + return getData$2(this).frame.id; + } + get workspaceId() { + return getData$2(this).workspace.id; + } + get positionIndex() { + return getData$2(this).config.positionIndex; + } + get isMaximized() { + return getData$2(this).config.isMaximized; + } + get isLoaded() { + return getData$2(this).controller.checkIsWindowLoaded(this.id); + } + get isSelected() { + return getData$2(this).config.isSelected; + } + get focused() { + return this.getGdWindow().isFocused; + } + get title() { + return getData$2(this).config.title; + } + get allowExtract() { + return getData$2(this).config.allowExtract; + } + get allowReorder() { + return getData$2(this).config.allowReorder; + } + get showCloseButton() { + return getData$2(this).config.showCloseButton; + } + get width() { + return getData$2(this).config.widthInPx; + } + get height() { + return getData$2(this).config.heightInPx; + } + get minWidth() { + return getData$2(this).config.minWidth; + } + get minHeight() { + return getData$2(this).config.minHeight; + } + get maxWidth() { + return getData$2(this).config.maxWidth; + } + get maxHeight() { + return getData$2(this).config.maxHeight; + } + get workspace() { + return getData$2(this).workspace; + } + get frame() { + return getData$2(this).frame; + } + get parent() { + return getData$2(this).parent; + } + get appName() { + return getData$2(this).config.appName; + } + async forceLoad() { + if (this.isLoaded) { + return; + } + const controller = getData$2(this).controller; + const itemId = getData$2(this).id; + const windowId = await controller.forceLoadWindow(itemId); + getData$2(this).config.windowId = windowId; + await this.workspace.refreshReference(); + } + async focus() { + const id = getData$2(this).id; + const controller = getData$2(this).controller; + await controller.focusItem(id); + await this.workspace.refreshReference(); + } + async close() { + const id = getData$2(this).id; + const controller = getData$2(this).controller; + await controller.closeItem(id); + await getData$2(this) + .parent + .removeChild((child) => child.id === id); + await this.workspace.refreshReference(); + } + async setTitle(title) { + nonEmptyStringDecoder.runWithException(title); + const itemId = getData$2(this).id; + const controller = getData$2(this).controller; + await controller.setItemTitle(itemId, title); + await this.workspace.refreshReference(); + } + async maximize() { + const id = getData$2(this).id; + const controller = getData$2(this).controller; + await controller.maximizeItem(id); + await this.workspace.refreshReference(); + } + async restore() { + const id = getData$2(this).id; + const controller = getData$2(this).controller; + await controller.restoreItem(id); + await this.workspace.refreshReference(); + } + async eject() { + if (!this.isLoaded) { + throw new Error("Cannot eject this window, because it is not loaded yet"); + } + const itemId = getData$2(this).id; + const newWindowId = await getData$2(this).controller.ejectWindow(itemId); + getData$2(this).config.windowId = newWindowId; + await this.workspace.refreshReference(); + return this.getGdWindow(); + } + getGdWindow() { + if (!this.isLoaded) { + throw new Error("Cannot fetch this GD window, because the window is not yet loaded"); + } + const myId = getData$2(this).config.windowId; + const controller = getData$2(this).controller; + return controller.getGDWindow(myId); + } + async moveTo(parent) { + if (!(parent instanceof Row || parent instanceof Column || parent instanceof Group)) { + throw new Error("Cannot add to the provided parent, because the provided parent is not an instance of Row, Column or Group"); + } + const myId = getData$2(this).id; + const controller = getData$2(this).controller; + const foundParent = await controller.getParent((p) => p.id === parent.id); + if (!foundParent) { + throw new Error("Cannot move the window to the selected parent, because this parent does not exist."); + } + await controller.moveWindowTo(myId, parent.id); + await this.workspace.refreshReference(); + } + async lock(config) { + let lockConfigResult = undefined; + if (typeof config === "function") { + const currentLockConfig = { + allowExtract: this.allowExtract, + allowReorder: this.allowReorder, + showCloseButton: this.showCloseButton + }; + lockConfigResult = config(currentLockConfig); + } + else { + lockConfigResult = config; + } + const verifiedConfig = lockConfigResult === undefined ? undefined : windowLockConfigDecoder.runWithException(lockConfigResult); + const windowPlacementId = getData$2(this).id; + await getData$2(this).controller.lockWindow(windowPlacementId, verifiedConfig); + await this.workspace.refreshReference(); + } + async setSize(config) { + const verifiedConfig = elementResizeConfigDecoder.runWithException(config); + if (!verifiedConfig.width && !verifiedConfig.height) { + throw new Error("Expected either width or height to be passed."); + } + const myId = getData$2(this).id; + const controller = getData$2(this).controller; + await controller.resizeItem(myId, { + height: verifiedConfig.height, + width: verifiedConfig.width, + relative: false + }); + await this.workspace.refreshReference(); + } + async onRemoved(callback) { + checkThrowCallback(callback); + const id = getData$2(this).id; + const wrappedCallback = async () => { + await this.workspace.refreshReference(); + callback(); + }; + const config = { + callback: wrappedCallback, + action: "removed", + eventType: "window", + scope: "window" + }; + const unsubscribe = await getData$2(this).controller.processLocalSubscription(config, id); + return unsubscribe; + } + async onLockConfigurationChanged(callback) { + checkThrowCallback(callback); + const id = getData$2(this).id; + const wrappedCallback = async () => { + await this.workspace.refreshReference(); + callback({ + allowExtract: this.allowExtract, + allowReorder: this.allowReorder, + showCloseButton: this.showCloseButton + }); + }; + const config = { + callback: wrappedCallback, + action: "lock-configuration-changed", + eventType: "window", + scope: "window" + }; + const unsubscribe = await getData$2(this).controller.processLocalSubscription(config, id); + return unsubscribe; + } + } + + const data$1 = new WeakMap(); + const getData$1 = (model) => { + return data$1.get(model).manager.getFrameData(model); + }; + class Frame { + constructor(dataManager) { + data$1.set(this, { manager: dataManager }); + } + async registerShortcut(shortcut, callback) { + nonEmptyStringDecoder.runWithException(shortcut); + checkThrowCallback(callback); + const myId = getData$1(this).summary.id; + const unsubscribe = await getData$1(this).controller.registerShortcut(shortcut, myId, callback); + return unsubscribe; + } + get id() { + return getData$1(this).summary.id; + } + get isInitialized() { + return getData$1(this).summary.isInitialized; + } + getBounds() { + const myId = getData$1(this).summary.id; + return getData$1(this).controller.getFrameBounds(myId); + } + async resize(config) { + const validatedConfig = resizeConfigDecoder.runWithException(config); + const myId = getData$1(this).summary.id; + return getData$1(this).controller.resizeItem(myId, validatedConfig); + } + async move(config) { + const validatedConfig = moveConfigDecoder.runWithException(config); + const myId = getData$1(this).summary.id; + return getData$1(this).controller.moveFrame(myId, validatedConfig); + } + focus() { + const myId = getData$1(this).summary.id; + return getData$1(this).controller.focusItem(myId); + } + async state() { + if (!isDesktop()) { + throw new Error("State operations are not supported in IO Connect Browser"); + } + const myId = getData$1(this).summary.id; + return getData$1(this).controller.getFrameState(myId); + } + async minimize() { + if (!isDesktop()) { + throw new Error("State operations are not supported in IO Connect Browser"); + } + const myId = getData$1(this).summary.id; + return getData$1(this).controller.changeFrameState(myId, "minimized"); + } + async maximize() { + if (!isDesktop()) { + throw new Error("State operations are not supported in IO Connect Browser"); + } + const myId = getData$1(this).summary.id; + return getData$1(this).controller.changeFrameState(myId, "maximized"); + } + async restore() { + if (!isDesktop()) { + throw new Error("State operations are not supported in IO Connect Browser"); + } + const myId = getData$1(this).summary.id; + return getData$1(this).controller.changeFrameState(myId, "normal"); + } + close() { + const myId = getData$1(this).summary.id; + return getData$1(this).controller.closeItem(myId); + } + snapshot() { + const myId = getData$1(this).summary.id; + return getData$1(this).controller.getSnapshot(myId, "frame"); + } + async workspaces() { + const controller = getData$1(this).controller; + return controller.getWorkspacesByFrameId(this.id); + } + async getConstraints() { + const controller = getData$1(this).controller; + const myId = getData$1(this).summary.id; + return controller.getFrameConstraints(myId); + } + async restoreWorkspace(name, options) { + nonEmptyStringDecoder.runWithException(name); + const validatedOptions = restoreWorkspaceConfigDecoder.runWithException(options); + return getData$1(this).controller.restoreWorkspace(name, validatedOptions); + } + createWorkspace(definition, config) { + const validatedDefinition = workspaceDefinitionDecoder.runWithException(definition); + const validatedConfig = workspaceBuilderCreateConfigDecoder.runWithException(config); + return getData$1(this).controller.createWorkspace(validatedDefinition, validatedConfig); + } + async init(config) { + frameInitConfigDecoder.runWithException(config); + if (getData$1(this).summary.isInitialized) { + throw new Error("The frame has already been initialized"); + } + return getData$1(this).controller.initFrame(this.id, config); + } + async onClosed(callback) { + checkThrowCallback(callback); + const myId = getData$1(this).summary.id; + const wrappedCallback = (payload) => { + callback({ frameId: payload.frameSummary.id, frameBounds: payload.frameBounds }); + }; + const config = { + callback: wrappedCallback, + action: "closed", + eventType: "frame", + scope: "frame" + }; + const unsubscribe = await getData$1(this).controller.processLocalSubscription(config, myId); + return unsubscribe; + } + async onMaximized(callback) { + checkThrowCallback(callback); + const myId = getData$1(this).summary.id; + const wrappedCallback = () => { + callback(); + }; + const config = { + callback: wrappedCallback, + action: "maximized", + eventType: "frame", + scope: "frame" + }; + const unsubscribe = await getData$1(this).controller.processLocalSubscription(config, myId); + return unsubscribe; + } + async onMinimized(callback) { + checkThrowCallback(callback); + const myId = getData$1(this).summary.id; + const wrappedCallback = () => { + callback(); + }; + const config = { + callback: wrappedCallback, + action: "minimized", + eventType: "frame", + scope: "frame" + }; + const unsubscribe = await getData$1(this).controller.processLocalSubscription(config, myId); + return unsubscribe; + } + async onNormal(callback) { + checkThrowCallback(callback); + const myId = getData$1(this).summary.id; + const wrappedCallback = () => { + callback(); + }; + const config = { + callback: wrappedCallback, + action: "normal", + eventType: "frame", + scope: "frame" + }; + const unsubscribe = await getData$1(this).controller.processLocalSubscription(config, myId); + return unsubscribe; + } + async onWorkspaceOpened(callback) { + checkThrowCallback(callback); + const myId = getData$1(this).summary.id; + const wrappedCallback = async (payload) => { + const workspace = await getData$1(this).controller.transformStreamPayloadToWorkspace(payload); + callback(workspace); + }; + const config = { + callback: wrappedCallback, + action: "opened", + eventType: "workspace", + scope: "frame" + }; + const unsubscribe = await getData$1(this).controller.processLocalSubscription(config, myId); + return unsubscribe; + } + async onWorkspaceSelected(callback) { + checkThrowCallback(callback); + const myId = getData$1(this).summary.id; + const wrappedCallback = async (payload) => { + const workspace = await getData$1(this).controller.getWorkspaceById(payload.workspaceSummary.id); + callback(workspace); + }; + const config = { + callback: wrappedCallback, + action: "selected", + eventType: "workspace", + scope: "frame" + }; + const unsubscribe = await getData$1(this).controller.processLocalSubscription(config, myId); + return unsubscribe; + } + async onWorkspaceClosed(callback) { + checkThrowCallback(callback); + const myId = getData$1(this).summary.id; + const wrappedCallback = (payload) => { + callback({ frameId: payload.frameSummary.id, workspaceId: payload.workspaceSummary.id, frameBounds: payload.frameBounds }); + }; + const config = { + callback: wrappedCallback, + action: "closed", + eventType: "workspace", + scope: "frame" + }; + const unsubscribe = await getData$1(this).controller.processLocalSubscription(config, myId); + return unsubscribe; + } + async onWindowAdded(callback) { + checkThrowCallback(callback); + const myId = getData$1(this).summary.id; + const wrappedCallback = async (payload) => { + const foundParent = await getData$1(this).controller.getParent((parent) => parent.id === payload.windowSummary.parentId); + const foundWindow = foundParent.children.find((child) => child.type === "window" && child.positionIndex === payload.windowSummary.config.positionIndex); + callback(foundWindow); + }; + const config = { + callback: wrappedCallback, + action: "added", + eventType: "window", + scope: "frame" + }; + const unsubscribe = await getData$1(this).controller.processLocalSubscription(config, myId); + return unsubscribe; + } + async onWindowRemoved(callback) { + checkThrowCallback(callback); + const myId = getData$1(this).summary.id; + const wrappedCallback = (payload) => { + const { windowId, workspaceId, frameId } = payload.windowSummary.config; + callback({ windowId, workspaceId, frameId }); + }; + const config = { + callback: wrappedCallback, + action: "removed", + eventType: "window", + scope: "frame" + }; + const unsubscribe = await getData$1(this).controller.processLocalSubscription(config, myId); + return unsubscribe; + } + async onWindowLoaded(callback) { + checkThrowCallback(callback); + const myId = getData$1(this).summary.id; + const wrappedCallback = async (payload) => { + const foundParent = await getData$1(this).controller.getParent((parent) => { + return parent.id === payload.windowSummary.parentId; + }); + const foundWindow = foundParent.children.find((child) => child.type === "window" && child.positionIndex === payload.windowSummary.config.positionIndex); + callback(foundWindow); + }; + const config = { + callback: wrappedCallback, + action: "loaded", + eventType: "window", + scope: "frame" + }; + const unsubscribe = await getData$1(this).controller.processLocalSubscription(config, myId); + return unsubscribe; + } + async onInitializationRequested(callback) { + checkThrowCallback(callback); + if (!this.isInitialized) { + callback(getData$1(this).summary.initializationContext); + } + return () => { }; + } + async onFocusChanged(callback) { + checkThrowCallback(callback); + const myData = getData$1(this); + const { id } = myData.summary; + const wrappedCallback = (args) => { + callback({ isFocused: args.frameSummary.isFocused }); + }; + const config = { + callback: wrappedCallback, + action: "focus", + eventType: "frame", + scope: "frame" + }; + const unsubscribe = await myData.controller.processLocalSubscription(config, id); + return unsubscribe; + } + } + + class PrivateDataManager { + parentsData = new WeakMap(); + workspacesData = new WeakMap(); + windowsData = new WeakMap(); + framesData = new WeakMap(); + deleteData(model) { + if (model instanceof Window) { + this.windowsData.delete(model); + } + if (model instanceof Workspace) { + this.workspacesData.delete(model); + } + if (model instanceof Row || model instanceof Column || model instanceof Group) { + this.parentsData.delete(model); + } + if (model instanceof Frame) { + this.framesData.delete(model); + } + } + setWindowData(model, data) { + this.windowsData.set(model, data); + } + setWorkspaceData(model, data) { + this.workspacesData.set(model, data); + } + setParentData(model, data) { + this.parentsData.set(model, data); + } + setFrameData(model, data) { + this.framesData.set(model, data); + } + getWindowData(model) { + return this.windowsData.get(model); + } + getWorkspaceData(model) { + return this.workspacesData.get(model); + } + getParentData(model) { + return this.parentsData.get(model); + } + getFrameData(model) { + return this.framesData.get(model); + } + remapChild(model, newData) { + if (model instanceof Window) { + const data = this.windowsData.get(model); + data.parent = newData.parent || data.parent; + data.config = newData.config || data.config; + } + if (model instanceof Row || model instanceof Column || model instanceof Group) { + const data = this.parentsData.get(model); + data.parent = newData.parent || data.parent; + data.config = newData.config || data.config; + data.children = newData.children || data.children; + } + } + remapFrame(model, newData) { + const data = this.framesData.get(model); + data.summary = newData; + } + remapWorkspace(model, newData) { + const data = this.workspacesData.get(model); + data.frame = newData.frame || data.frame; + data.config = newData.config || data.config; + data.children = newData.children || data.children; + } + } + + const data = new WeakMap(); + const getData = (base, model) => { + const manager = data.get(base).manager; + if (model instanceof Workspace) { + return manager.getWorkspaceData(model); + } + return data.get(base).manager.getParentData(model); + }; + class Base { + frameId; + workspaceId; + positionIndex; + constructor(dataManager) { + data.set(this, { manager: dataManager }); + } + getId(model) { + return getData(this, model).id; + } + getPositionIndex(model) { + return getData(this, model).config.positionIndex; + } + getWorkspaceId(model) { + const privateData = getData(this, model); + return privateData.config.workspaceId || privateData.workspace.id; + } + getFrameId(model) { + return getData(this, model).frame.id; + } + getAllChildren(model, predicate) { + checkThrowCallback(predicate, true); + const children = getData(this, model).children; + if (typeof predicate === "undefined") { + return children; + } + return children.filter(predicate); + } + getMyParent(model) { + if (model instanceof Workspace) { + return model; + } + return getData(this, model).parent; + } + getMyFrame(model) { + return getData(this, model).frame; + } + getMyWorkspace(model) { + if (model instanceof Workspace) { + return model; + } + return getData(this, model).workspace; + } + async addWindow(model, definition, parentType) { + if (!definition.appName && !definition.windowId) { + throw new Error("The window definition should contain either an appName or a windowId"); + } + const validatedDefinition = swimlaneWindowDefinitionDecoder.runWithException(definition); + const controller = getData(this, model).controller; + const operationResult = await controller.add("window", getData(this, model).id, parentType, validatedDefinition); + if (model instanceof Workspace) { + await model.refreshReference(); + return model.getWindow(w => w.elementId === operationResult.itemId); + } + const myWorkspace = this.getMyWorkspace(model); + await myWorkspace.refreshReference(); + return myWorkspace.getWindow(w => w.elementId === operationResult.itemId); + } + async addParent(model, typeToAdd, parentType, definition) { + const parentDefinition = this.transformDefinition(typeToAdd, definition); + const controller = getData(this, model).controller; + const newParentId = (await controller.add("container", getData(this, model).id, parentType, parentDefinition)).itemId; + if (model instanceof Workspace) { + await model.refreshReference(); + return model.getBox((parent) => parent.id === newParentId); + } + const myWorkspace = this.getMyWorkspace(model); + await myWorkspace.refreshReference(); + return myWorkspace.getBox((parent) => parent.id === newParentId); + } + async removeChild(model, predicate) { + checkThrowCallback(predicate); + const child = this.getAllChildren(model).find(predicate); + if (!child) { + return; + } + await child.close(); + if (model instanceof Workspace) { + await model.refreshReference(); + return; + } + await this.getMyWorkspace(model).refreshReference(); + } + async maximize(model) { + const { controller, id } = getData(this, model); + await controller.maximizeItem(id); + await this.getMyWorkspace(model.parent).refreshReference(); + } + async restore(model) { + const { controller, id } = getData(this, model); + await controller.restoreItem(id); + await this.getMyWorkspace(model.parent).refreshReference(); + } + async close(model) { + const modelData = getData(this, model); + const controller = getData(this, model).controller; + await controller.closeItem(modelData.id); + await this.getMyWorkspace(modelData.parent).refreshReference(); + } + async lockContainer(model, config) { + const modelData = getData(this, model); + const controller = getData(this, model).controller; + await controller.lockContainer(modelData.id, model.type, config); + await this.getMyWorkspace(modelData.parent).refreshReference(); + } + getAllowDrop(model) { + return getData(this, model).config.allowDrop; + } + getAllowDropLeft(model) { + const privateData = getData(this, model); + if (privateData.type !== "group") { + throw new Error(`Property allowDropLeft is available only for groups and not on ${model.type} ${model.id}`); + } + return privateData.config.allowDropLeft; + } + getAllowDropRight(model) { + const privateData = getData(this, model); + if (privateData.type !== "group") { + throw new Error(`Property allowDropRight is available only for groups and not on ${model.type} ${model.id}`); + } + return privateData.config.allowDropRight; + } + getAllowDropTop(model) { + const privateData = getData(this, model); + if (privateData.type !== "group") { + throw new Error(`Property allowDropTop is available only for groups and not on ${model.type} ${model.id}`); + } + return privateData.config.allowDropTop; + } + getAllowDropBottom(model) { + const privateData = getData(this, model); + if (privateData.type !== "group") { + throw new Error(`Property allowDropBottom is available only for groups and not on ${model.type} ${model.id}`); + } + return privateData.config.allowDropBottom; + } + getAllowDropHeader(model) { + const privateData = getData(this, model); + if (privateData.type !== "group") { + throw new Error(`Property allowDropHeader is available only for groups and not on ${model.type} ${model.id}`); + } + return privateData.config.allowDropHeader; + } + getAllowSplitters(model) { + const privateData = getData(this, model); + if (privateData.type === "group") { + throw new Error(`Cannot get allow splitters from private data ${privateData.type}`); + } + return privateData.config.allowSplitters; + } + getAllowExtract(model) { + const privateData = getData(this, model); + if (privateData.type !== "group") { + throw new Error(`Cannot get allow extract from private data ${privateData.type} with config ${privateData.type !== "workspace" ? privateData.config.type : ""}`); + } + return privateData.config.allowExtract; + } + getAllowReorder(model) { + const privateData = getData(this, model); + if (privateData.type !== "group") { + throw new Error(`Cannot get allow extract from private data ${privateData.type} with config ${privateData.type !== "workspace" ? privateData.config.type : ""}`); + } + return privateData.config.allowReorder; + } + getShowMaximizeButton(model) { + const privateData = getData(this, model); + if (privateData.type !== "group") { + throw new Error(`Cannot get show maximize button from private data${privateData.type} with config ${privateData.type !== "workspace" ? privateData.config.type : ""}`); + } + return privateData.config.showMaximizeButton; + } + getShowEjectButton(model) { + const privateData = getData(this, model); + if (privateData.type !== "group") { + throw new Error(`Cannot get show eject button from private data${privateData.type} with config ${privateData.type !== "workspace" ? privateData.config.type : ""}`); + } + return privateData.config.showEjectButton; + } + getShowAddWindowButton(model) { + const privateData = getData(this, model); + if (privateData.type !== "group") { + throw new Error(`Cannot get add window button from private data${privateData.type} with config ${privateData.type !== "workspace" ? privateData.config.type : ""}`); + } + return privateData.config.showAddWindowButton; + } + getMinWidth(model) { + const privateData = getData(this, model); + return privateData.config.minWidth; + } + getMaxWidth(model) { + const privateData = getData(this, model); + return privateData.config.maxWidth; + } + getMinHeight(model) { + const privateData = getData(this, model); + return privateData.config.minHeight; + } + getMaxHeight(model) { + const privateData = getData(this, model); + return privateData.config.maxHeight; + } + getWidthInPx(model) { + const privateData = getData(this, model); + return privateData.config.widthInPx; + } + getHeightInPx(model) { + const privateData = getData(this, model); + return privateData.config.heightInPx; + } + getIsPinned(model) { + const privateData = getData(this, model); + return privateData.config.isPinned; + } + getIsMaximized(model) { + const privateData = getData(this, model); + return privateData.config.isMaximized; + } + getMaximizationBoundary(model) { + const privateData = getData(this, model); + return privateData.config.maximizationBoundary; + } + async setHeight(model, height) { + const modelData = getData(this, model); + const { controller, id } = modelData; + await controller.resizeItem(id, { + height + }); + await this.getMyWorkspace(modelData.parent).refreshReference(); + } + async setWidth(model, width) { + const modelData = getData(this, model); + const { controller, id } = modelData; + await controller.resizeItem(id, { + width + }); + await this.getMyWorkspace(modelData.parent).refreshReference(); + } + async setSize(model, width, height) { + const modelData = getData(this, model); + const { controller, id } = modelData; + await controller.resizeItem(id, { + width, + height + }); + await this.getMyWorkspace(modelData.parent).refreshReference(); + } + async setMaximizationBoundary(model, config) { + const modelData = getData(this, model); + const { controller, id } = modelData; + await controller.setMaximizationBoundary(id, config); + await this.getMyWorkspace(modelData.parent).refreshReference(); + } + async bundleTo(model, type) { + const modelData = getData(this, model); + const { controller, id } = modelData; + await controller.bundleItemTo(type, id); + } + async processLocalSubscription(model, subscriptionConfig) { + return getData(this, model).controller.processLocalSubscription(subscriptionConfig, this.getId(model)); + } + transformDefinition(type, definition) { + let parentDefinition; + if (typeof definition === "undefined") { + parentDefinition = { type, children: [] }; + } + else if (definition instanceof ParentBuilder) { + parentDefinition = definition.serialize(); + } + else { + if (typeof definition.type === "undefined") { + definition.type = type; + } + parentDefinition = strictParentDefinitionDecoder.runWithException(definition); + parentDefinition.children = parentDefinition.children || []; + } + return parentDefinition; + } + } + + class BaseController { + ioc; + windows; + contexts; + layouts; + constructor(ioc, windows, contexts, layouts) { + this.ioc = ioc; + this.windows = windows; + this.contexts = contexts; + this.layouts = layouts; + } + get bridge() { + return this.ioc.bridge; + } + get privateDataManager() { + return this.ioc.privateDataManager; + } + checkIsWindowLoaded(windowId) { + return (!!windowId) && this.windows.list().some((win) => win.id === windowId); + } + async createWorkspace(createConfig) { + const snapshot = await this.bridge.send(OPERATIONS.createWorkspace.name, createConfig); + const frameConfig = { + summary: snapshot.frameSummary + }; + const frame = this.ioc.getModel("frame", frameConfig); + const workspaceConfig = { frame, snapshot }; + return this.ioc.getModel("workspace", workspaceConfig); + } + async createEmptyFrame(definition) { + const frameSummary = await this.bridge.send(OPERATIONS.createFrame.name, definition); + const frameConfig = { + summary: frameSummary + }; + return this.ioc.getModel("frame", frameConfig); + } + async initFrame(frameId, config) { + await this.bridge.send(OPERATIONS.initFrame.name, { frameId, ...config }); + } + async restoreWorkspace(name, options) { + const snapshot = await this.bridge.send(OPERATIONS.openWorkspace.name, { name, restoreOptions: options }); + const frameSummary = await this.bridge.send(OPERATIONS.getFrameSummary.name, { itemId: snapshot.config.frameId }); + const frameConfig = { + summary: frameSummary + }; + const frame = this.ioc.getModel("frame", frameConfig); + const workspaceConfig = { frame, snapshot }; + return this.ioc.getModel("workspace", workspaceConfig); + } + async add(type, parentId, parentType, definition) { + let operationName; + const operationArgs = { definition, parentId, parentType }; + if (type === "window") { + operationName = OPERATIONS.addWindow.name; + } + else if (type === "container") { + operationName = OPERATIONS.addContainer.name; + } + else { + throw new Error(`Unrecognized add type: ${type}`); + } + return await this.bridge.send(operationName, operationArgs); + } + async getFrame(windowId) { + const frameSummary = await this.bridge.send(OPERATIONS.getFrameSummary.name, { itemId: windowId }); + const frameConfig = { + summary: frameSummary + }; + return this.ioc.getModel("frame", frameConfig); + } + getFrames(allFrameSummaries, predicate) { + return allFrameSummaries.reduce((frames, frameSummary) => { + const frameConfig = { + summary: frameSummary + }; + const frameToCheck = this.ioc.getModel("frame", frameConfig); + if (!predicate || predicate(frameToCheck)) { + frames.push(frameToCheck); + } + return frames; + }, []); + } + getAllWorkspaceSummaries(...bridgeResults) { + const allSummaries = bridgeResults.reduce((summaries, summaryResult) => { + summaries.push(...summaryResult.summaries); + return summaries; + }, []); + return allSummaries.map((summary) => { + return Object.assign({}, { id: summary.id, width: summary.config.widthInPx, height: summary.config.heightInPx }, summary.config); + }); + } + handleOnSaved(callback) { + const wrappedCallback = (layout) => { + if (layout.type !== "Workspace") { + return; + } + callback(layout); + }; + const addedUnSub = this.layouts.onAdded(wrappedCallback); + const changedUnSub = this.layouts.onChanged(wrappedCallback); + return () => { + addedUnSub(); + changedUnSub(); + }; + } + handleOnRemoved(callback) { + const wrappedCallback = (layout) => { + if (layout.type !== "Workspace") { + return; + } + callback(layout); + }; + return this.layouts.onRemoved(wrappedCallback); + } + async importLayouts(layouts, mode) { + await this.layouts.import(layouts, mode); + } + async transformStreamPayloadToWorkspace(payload) { + const frameConfig = { + summary: payload.frameSummary + }; + const frame = this.ioc.getModel("frame", frameConfig); + const snapshot = payload.workspaceSnapshot || (await this.bridge.send(OPERATIONS.getWorkspaceSnapshot.name, { itemId: payload.workspaceSummary.id })); + const workspaceConfig = { frame, snapshot }; + const workspace = this.ioc.getModel("workspace", workspaceConfig); + return workspace; + } + async fetchWorkspace(itemId) { + const snapshot = await this.bridge.send(OPERATIONS.getWorkspaceSnapshot.name, { itemId }); + const frameConfig = { + summary: snapshot.frameSummary + }; + const frame = this.ioc.getModel("frame", frameConfig); + const workspaceConfig = { frame, snapshot }; + return this.ioc.getModel("workspace", workspaceConfig); + } + async bundleWorkspaceTo(type, workspaceId) { + await this.bridge.send(OPERATIONS.bundleWorkspace.name, { type, workspaceId }); + } + async bundleItemTo(type, itemId) { + const isSupported = await this.isOperationSupported(OPERATIONS.bundleItem.name); + if (!isSupported) { + throw new Error(`Operation ${OPERATIONS.bundleItem.name} is not supported. Ensure that you are running the latest version of all packages`); + } + await this.bridge.send(OPERATIONS.bundleItem.name, { type, itemId }); + } + getWorkspaceContext(workspaceId) { + const contextName = `___workspace___${workspaceId}`; + return this.contexts.get(contextName); + } + setWorkspaceContext(workspaceId, data) { + const contextName = `___workspace___${workspaceId}`; + return this.contexts.set(contextName, data); + } + updateWorkspaceContext(workspaceId, data) { + const contextName = `___workspace___${workspaceId}`; + return this.contexts.update(contextName, data); + } + subscribeWorkspaceContextUpdated(workspaceId, callback) { + const contextName = `___workspace___${workspaceId}`; + return this.contexts.subscribe(contextName, callback); + } + async restoreItem(itemId) { + await this.bridge.send(OPERATIONS.restoreItem.name, { itemId }); + } + async maximizeItem(itemId) { + await this.bridge.send(OPERATIONS.maximizeItem.name, { itemId }); + } + async focusItem(itemId) { + await this.bridge.send(OPERATIONS.focusItem.name, { itemId }); + } + async closeItem(itemId) { + await this.bridge.send(OPERATIONS.closeItem.name, { itemId }); + } + async resizeItem(itemId, config) { + await this.bridge.send(OPERATIONS.resizeItem.name, Object.assign({}, { itemId }, config)); + } + async setMaximizationBoundary(itemId, config) { + await this.bridge.send(OPERATIONS.setMaximizationBoundary.name, Object.assign({}, { itemId }, config)); + } + async showWorkspaceLoadingAnimation(workspaceId) { + await this.bridge.send(OPERATIONS.showLoadingAnimation.name, { itemId: workspaceId, type: "workspace" }); + } + async hideWorkspaceLoadingAnimation(workspaceId) { + await this.bridge.send(OPERATIONS.hideLoadingAnimation.name, { itemId: workspaceId, type: "workspace" }); + } + async setWindowDragMode(workspaceId, dragMode) { + await this.bridge.send(OPERATIONS.setWindowDragMode.name, { itemId: workspaceId, dragMode }); + } + async moveFrame(itemId, config) { + await this.bridge.send(OPERATIONS.moveFrame.name, Object.assign({}, { itemId }, config)); + } + getGDWindow(itemId) { + return this.windows.list().find((gdWindow) => gdWindow.id === itemId); + } + async forceLoadWindow(itemId) { + const controlResult = await this.bridge.send(OPERATIONS.forceLoadWindow.name, { itemId }); + return controlResult.windowId; + } + async ejectWindow(itemId) { + return await this.bridge.send(OPERATIONS.ejectWindow.name, { itemId }); + } + async moveWindowTo(itemId, newParentId) { + await this.bridge.send(OPERATIONS.moveWindowTo.name, { itemId, containerId: newParentId }); + } + async getSnapshot(itemId, type) { + let result; + if (type === "workspace") { + result = await this.bridge.send(OPERATIONS.getWorkspaceSnapshot.name, { itemId }); + } + else if (type === "frame") { + result = await this.bridge.send(OPERATIONS.getFrameSnapshot.name, { itemId }); + } + return result; + } + async setItemTitle(itemId, title) { + await this.bridge.send(OPERATIONS.setItemTitle.name, { itemId, title }); + } + refreshChildren(config) { + const { parent, children, existingChildren, workspace } = config; + if (parent instanceof Window || parent.type === "window") { + return; + } + const newChildren = children.map((newChildSnapshot) => { + let childToAdd = existingChildren.find((child) => { + return child.type === "window" ? child.elementId === newChildSnapshot.id : child.id === newChildSnapshot.id; + }); + if (childToAdd) { + this.privateDataManager.remapChild(childToAdd, { + parent: parent, + children: [], + config: newChildSnapshot.config + }); + } + else { + let createConfig; + if (newChildSnapshot.type === "window") { + createConfig = { + id: newChildSnapshot.id, + parent: parent, + frame: workspace.frame, + workspace, + config: newChildSnapshot.config, + }; + } + else { + createConfig = { + id: newChildSnapshot.id, + parent: parent, + frame: workspace.frame, + workspace, + config: newChildSnapshot.config, + children: [] + }; + } + childToAdd = this.ioc.getModel(newChildSnapshot.type, createConfig); + } + if (newChildSnapshot.type !== "window") { + this.refreshChildren({ + workspace, existingChildren, + children: newChildSnapshot.children, + parent: childToAdd + }); + } + return childToAdd; + }); + if (parent instanceof Workspace) { + return newChildren; + } + else { + this.privateDataManager.remapChild(parent, { children: newChildren }); + return newChildren; + } + } + iterateFindChild(children, predicate) { + let foundChild = children.find((child) => predicate(child)); + if (foundChild) { + return foundChild; + } + children.some((child) => { + if (child instanceof Window) { + return false; + } + foundChild = this.iterateFindChild(child.children, predicate); + if (foundChild) { + return true; + } + }); + return foundChild; + } + iterateFilterChildren(children, predicate) { + const foundChildren = children.filter((child) => predicate(child)); + const grandChildren = children.reduce((innerFound, child) => { + if (child instanceof Window) { + return innerFound; + } + innerFound.push(...this.iterateFilterChildren(child.children, predicate)); + return innerFound; + }, []); + foundChildren.push(...grandChildren); + return foundChildren; + } + notifyWindowAdded(windowId) { + return new Promise((resolve) => { + const alreadyPresent = this.windows.list().some((win) => win.id === windowId); + if (alreadyPresent) { + return resolve(); + } + const unsubscribe = this.windows.onWindowAdded((win) => { + if (win.id !== windowId) { + return; + } + if (unsubscribe) { + unsubscribe(); + } + resolve(); + }); + }); + } + async hibernateWorkspace(workspaceId) { + await this.bridge.send(OPERATIONS.hibernateWorkspace.name, { workspaceId }); + } + async resumeWorkspace(workspaceId) { + await this.bridge.send(OPERATIONS.resumeWorkspace.name, { workspaceId }); + } + async lockWorkspace(workspaceId, config) { + await this.bridge.send(OPERATIONS.lockWorkspace.name, { workspaceId, config }); + } + async lockWindow(windowPlacementId, config) { + await this.bridge.send(OPERATIONS.lockWindow.name, { windowPlacementId, config }); + } + async lockContainer(itemId, type, config) { + await this.bridge.send(OPERATIONS.lockContainer.name, { itemId, type, config }); + } + async pinWorkspace(workspaceId, icon) { + await this.bridge.send(OPERATIONS.pinWorkspace.name, { workspaceId, icon }); + } + async unpinWorkspace(workspaceId) { + await this.bridge.send(OPERATIONS.unpinWorkspace.name, { workspaceId }); + } + async getWorkspaceIcon(workspaceId) { + const result = await this.bridge.send(OPERATIONS.getWorkspaceIcon.name, { workspaceId }); + return result.icon; + } + setWorkspaceIcon(workspaceId, icon) { + return this.bridge.send(OPERATIONS.setWorkspaceIcon.name, { workspaceId, icon }); + } + async getPlatformFrameId() { + try { + const result = await this.bridge.send(OPERATIONS.getPlatformFrameId.name, {}); + return result; + } + catch (error) { + return {}; + } + } + async setLoadingStrategy(workspaceId, strategy) { + await this.isOperationSupported(OPERATIONS.setLoadingStrategy.name); + return this.bridge.send(OPERATIONS.setLoadingStrategy.name, { itemId: workspaceId, strategy }); + } + async isOperationSupported(operation) { + if (isDesktop()) { + return { isSupported: true }; + } + return await this.bridge.send(OPERATIONS.operationCheck.name, { operation }); + } + } + + class MainController { + bridge; + base; + shortcutsController; + constructor(bridge, base, shortcutsController) { + this.bridge = bridge; + this.base = base; + this.shortcutsController = shortcutsController; + } + checkIsWindowLoaded(windowId) { + return this.base.checkIsWindowLoaded(windowId); + } + async checkIsInSwimlane(windowId) { + const controlResult = await this.bridge.send(OPERATIONS.isWindowInWorkspace.name, { itemId: windowId }); + return controlResult.inWorkspace; + } + async createWorkspace(definition, saveConfig) { + const createConfig = Object.assign({}, definition, { saveConfig }); + return await this.base.createWorkspace(createConfig); + } + async createEmptyFrame(definition) { + return await this.base.createEmptyFrame(definition); + } + async initFrame(frameId, config) { + return this.base.initFrame(frameId, config); + } + async restoreWorkspace(name, options) { + const allLayouts = await this.getLayoutSummaries(); + const layoutExists = allLayouts.some((summary) => summary.name === name); + if (!layoutExists) { + throw new Error(`This layout: ${name} cannot be restored, because it doesn't exist.`); + } + if (options?.frameId) { + const allFrameSummaries = await this.bridge.send(OPERATIONS.getAllFramesSummaries.name); + const foundMatchingFrame = allFrameSummaries.summaries.some((summary) => summary.id === options.frameId); + if (!foundMatchingFrame) { + throw new Error(`Cannot reuse the frame with id: ${options.frameId}, because there is no frame with that ID found`); + } + } + return await this.base.restoreWorkspace(name, options); + } + async add(type, parentId, parentType, definition) { + return await this.base.add(type, parentId, parentType, definition); + } + processLocalSubscription(config, levelId) { + return isDesktop() ? + this.handleEnterpriseLocalSubscription(config, levelId) : + this.handleCoreLocalSubscription(config, levelId); + } + processGlobalSubscription(callback, eventType, action) { + return isDesktop() ? + this.handleEnterpriseGlobalSubscription(callback, eventType, action) : + this.handleCoreGlobalSubscription(callback, eventType, action); + } + async getFrame(selector) { + if (selector.windowId) { + return await this.base.getFrame(selector.windowId); + } + if (selector.predicate) { + return (await this.getFrames(selector.predicate))[0]; + } + throw new Error(`The provided selector is not valid: ${JSON.stringify(selector)}`); + } + async getFrames(predicate) { + const allFrameSummaries = await this.bridge.send(OPERATIONS.getAllFramesSummaries.name); + return this.base.getFrames(allFrameSummaries.summaries, predicate); + } + getWorkspaceById(workspaceId) { + return this.base.fetchWorkspace(workspaceId); + } + async getWorkspaceByWindowId(itemId) { + if (!isDesktop()) { + return (await this.getWorkspaces((wsp) => !!wsp.getWindow((w) => w.id === itemId)))[0]; + } + return this.base.fetchWorkspace(itemId); + } + transformStreamPayloadToWorkspace(payload) { + return this.base.transformStreamPayloadToWorkspace(payload); + } + async getWorkspace(predicate) { + let foundWorkspace; + await this.iterateWorkspaces((wsp, end) => { + if (predicate(wsp)) { + foundWorkspace = wsp; + end(); + } + }); + return foundWorkspace; + } + async getWorkspaces(predicate) { + const matchingWorkspaces = []; + await this.iterateWorkspaces((wsp) => { + if (!predicate || predicate(wsp)) { + matchingWorkspaces.push(wsp); + } + }); + return matchingWorkspaces; + } + async getWorkspacesByFrameId(frameId) { + const workspaceSummaries = await this.getAllWorkspaceSummaries(); + const summariesForFrame = workspaceSummaries.filter((s) => s.frameId === frameId); + const workspacesForFrame = await Promise.all(summariesForFrame.map((summary) => { + return this.base.fetchWorkspace(summary.id); + })); + return workspacesForFrame; + } + async getAllWorkspaceSummaries() { + const allSummariesResult = await this.bridge.send(OPERATIONS.getAllWorkspacesSummaries.name, {}); + return this.base.getAllWorkspaceSummaries(allSummariesResult); + } + async getWindow(predicate) { + let resultWindow; + await this.iterateWorkspaces((wsp, end) => { + const foundWindow = wsp.getWindow(predicate); + if (foundWindow) { + resultWindow = foundWindow; + end(); + } + }); + return resultWindow; + } + async getParent(predicate) { + let resultParent; + await this.iterateWorkspaces((wsp, end) => { + const foundParent = wsp.getBox(predicate); + if (foundParent) { + resultParent = foundParent; + end(); + } + }); + return resultParent; + } + async getLayoutSummaries() { + const allLayouts = await this.bridge.send(OPERATIONS.getAllLayoutsSummaries.name); + return allLayouts.summaries; + } + async deleteLayout(name) { + await this.bridge.send(OPERATIONS.deleteLayout.name, { name }); + } + async exportLayout(predicate) { + const allLayoutsResult = await this.bridge.send(OPERATIONS.exportAllLayouts.name); + return allLayoutsResult.layouts.reduce((matchingLayouts, layout) => { + if (!predicate || predicate(layout)) { + matchingLayouts.push(layout); + } + return matchingLayouts; + }, []); + } + async saveLayout(config) { + return await this.bridge.send(OPERATIONS.saveLayout.name, config); + } + async importLayouts(layouts, mode) { + if (isDesktop()) { + try { + await this.bridge.send(OPERATIONS.importLayouts.name, { layouts, mode }); + } + catch (error) { + await Promise.all(layouts.map((layout) => this.bridge.send(OPERATIONS.importLayout.name, { layout, mode }))); + } + return; + } + await this.base.importLayouts(layouts, mode); + } + handleOnSaved(callback) { + return this.base.handleOnSaved(callback); + } + handleOnRemoved(callback) { + return this.base.handleOnRemoved(callback); + } + async bundleWorkspaceTo(type, workspaceId) { + return await this.base.bundleWorkspaceTo(type, workspaceId); + } + async bundleItemTo(type, id) { + return await this.base.bundleItemTo(type, id); + } + getWorkspaceContext(workspaceId) { + return this.base.getWorkspaceContext(workspaceId); + } + setWorkspaceContext(workspaceId, data) { + return this.base.setWorkspaceContext(workspaceId, data); + } + updateWorkspaceContext(workspaceId, data) { + return this.base.updateWorkspaceContext(workspaceId, data); + } + subscribeWorkspaceContextUpdated(workspaceId, callback) { + return this.base.subscribeWorkspaceContextUpdated(workspaceId, callback); + } + async restoreItem(itemId) { + return await this.base.restoreItem(itemId); + } + async maximizeItem(itemId) { + return await this.base.maximizeItem(itemId); + } + async focusItem(itemId) { + return await this.base.focusItem(itemId); + } + async changeFrameState(frameId, state) { + await this.bridge.send(OPERATIONS.changeFrameState.name, { frameId, requestedState: state }); + } + async getFrameBounds(frameId) { + const frameResult = await this.bridge.send(OPERATIONS.getFrameBounds.name, { itemId: frameId }); + return frameResult.bounds; + } + async getFrameState(frameId) { + const frameResult = await this.bridge.send(OPERATIONS.getFrameState.name, { itemId: frameId }); + return frameResult.state; + } + async closeItem(itemId) { + return await this.base.closeItem(itemId); + } + async resizeItem(itemId, config) { + return await this.base.resizeItem(itemId, config); + } + async setMaximizationBoundary(itemId, config) { + return await this.base.setMaximizationBoundary(itemId, config); + } + async showWorkspaceLoadingAnimation(workspaceId) { + return await this.base.showWorkspaceLoadingAnimation(workspaceId); + } + async hideWorkspaceLoadingAnimation(workspaceId) { + return await this.base.hideWorkspaceLoadingAnimation(workspaceId); + } + async setWindowDragMode(workspaceId, dragMode) { + return await this.base.setWindowDragMode(workspaceId, dragMode); + } + async moveFrame(itemId, config) { + return await this.base.moveFrame(itemId, config); + } + getGDWindow(itemId) { + return this.base.getGDWindow(itemId); + } + async forceLoadWindow(itemId) { + const windowId = await this.base.forceLoadWindow(itemId); + await this.base.notifyWindowAdded(windowId); + return windowId; + } + async ejectWindow(itemId) { + const windowId = (await this.base.ejectWindow(itemId)).windowId; + await this.base.notifyWindowAdded(windowId); + return windowId; + } + async moveWindowTo(itemId, newParentId) { + return await this.base.moveWindowTo(itemId, newParentId); + } + async getSnapshot(itemId, type) { + return await this.base.getSnapshot(itemId, type); + } + async setItemTitle(itemId, title) { + return await this.base.setItemTitle(itemId, title); + } + flatChildren(children) { + return children.reduce((soFar, child) => { + soFar.push(child); + if (child.type !== "window") { + soFar.push(...this.flatChildren(child.children)); + } + return soFar; + }, []); + } + refreshChildren(config) { + return this.base.refreshChildren(config); + } + iterateFindChild(children, predicate) { + return this.base.iterateFindChild(children, predicate); + } + iterateFilterChildren(children, predicate) { + return this.base.iterateFilterChildren(children, predicate); + } + hibernateWorkspace(workspaceId) { + return this.base.hibernateWorkspace(workspaceId); + } + resumeWorkspace(workspaceId) { + return this.base.resumeWorkspace(workspaceId); + } + lockWorkspace(workspaceId, config) { + return this.base.lockWorkspace(workspaceId, config); + } + lockWindow(windowPlacementId, config) { + return this.base.lockWindow(windowPlacementId, config); + } + lockContainer(itemId, type, config) { + return this.base.lockContainer(itemId, type, config); + } + pinWorkspace(workspaceId, icon) { + return this.base.pinWorkspace(workspaceId, icon); + } + unpinWorkspace(workspaceId) { + return this.base.unpinWorkspace(workspaceId); + } + getWorkspaceIcon(workspaceId) { + return this.base.getWorkspaceIcon(workspaceId); + } + setWorkspaceIcon(workspaceId, icon) { + return this.base.setWorkspaceIcon(workspaceId, icon); + } + async getFrameConstraints(frameId) { + const frameSnapshot = await this.getSnapshot(frameId, "frame"); + return { + minWidth: frameSnapshot.config.minWidth, + maxWidth: frameSnapshot.config.maxWidth, + minHeight: frameSnapshot.config.minHeight, + maxHeight: frameSnapshot.config.maxHeight, + }; + } + registerShortcut(shortcut, frameId, callback) { + return this.shortcutsController.registerShortcut(shortcut, frameId, callback); + } + getPlatformFrameId() { + return this.base.getPlatformFrameId(); + } + setLoadingStrategy(workspaceId, strategy) { + return this.base.setLoadingStrategy(workspaceId, strategy); + } + async handleCoreLocalSubscription(config, levelId) { + await this.bridge.createCoreEventSubscription(); + config.scopeId = config.scopeId || levelId; + if (config.eventType === "window" && config.action === "loaded") { + const originalCB = config.callback; + const wrappedCB = async (callbackData) => { + await this.base.notifyWindowAdded(callbackData.windowSummary.config.windowId); + originalCB(callbackData); + }; + config.callback = wrappedCB; + } + return this.bridge.handleCoreSubscription(config); + } + handleEnterpriseLocalSubscription(config, levelId) { + config.scopeId = config.scopeId || levelId; + if (config.eventType === "window" && config.action === "loaded") { + const originalCB = config.callback; + const wrappedCB = async (callbackData) => { + await this.base.notifyWindowAdded(callbackData.windowSummary.config.windowId); + originalCB(callbackData); + }; + config.callback = wrappedCB; + } + return this.bridge.subscribe(config); + } + async handleCoreGlobalSubscription(callback, eventType, action) { + await this.bridge.createCoreEventSubscription(); + const config = { + eventType, callback, action, + scope: "global", + }; + if (eventType === "window" && action === "loaded") { + const wrappedCB = async (callbackData) => { + await this.base.notifyWindowAdded(callbackData.windowSummary.config.windowId); + callback(callbackData); + }; + config.callback = wrappedCB; + } + return this.bridge.handleCoreSubscription(config); + } + handleEnterpriseGlobalSubscription(callback, eventType, action) { + const config = { + eventType, callback, action, + scope: "global", + }; + if (eventType === "window" && action === "loaded") { + const wrappedCB = async (callbackData) => { + await this.base.notifyWindowAdded(callbackData.windowSummary.config.windowId); + callback(callbackData); + }; + config.callback = wrappedCB; + } + return this.bridge.subscribe(config); + } + async iterateWorkspaces(callback) { + let ended = false; + const end = () => { ended = true; }; + const workspaceSummaries = await this.getAllWorkspaceSummaries(); + for (const summary of workspaceSummaries) { + if (ended) { + return; + } + const wsp = await this.base.fetchWorkspace(summary.id); + callback(wsp, end); + } + } + } + + class ShortcutsController { + bridge; + _shortcuts = CallbackFactory(); + constructor(bridge) { + this.bridge = bridge; + this.bridge.onOperation((payload, caller) => { + if (payload.operation === CLIENT_OPERATIONS.shortcutClicked.name) { + const data = payload.data; + this._shortcuts.execute(`${data.frameId}-${data.shortcut}`); + } + }); + } + async registerShortcut(shortcut, frameId, callback) { + await this.bridge.send(OPERATIONS.registerShortcut.name, { shortcut, frameId }); + const un = this._shortcuts.add(`${frameId}-${shortcut}`, callback); + return () => { + un(); + this.bridge.send(OPERATIONS.unregisterShortcut.name, { shortcut, frameId }); + }; + } + } + + class IoC { + agm; + windows; + layouts; + contexts; + _controllerInstance; + _bridgeInstance; + _transportInstance; + _privateDataManagerInstance; + _parentBaseInstance; + _baseController; + _shortcutsController; + constructor(agm, windows, layouts, contexts) { + this.agm = agm; + this.windows = windows; + this.layouts = layouts; + this.contexts = contexts; + } + get baseController() { + if (!this._baseController) { + this._baseController = new BaseController(this, this.windows, this.contexts, this.layouts); + } + return this._baseController; + } + get controller() { + if (!this._controllerInstance) { + this._controllerInstance = new MainController(this.bridge, this.baseController, this.shortcutsController); + } + return this._controllerInstance; + } + get shortcutsController() { + if (!this._shortcutsController) { + this._shortcutsController = new ShortcutsController(this.bridge); + } + return this._shortcutsController; + } + get bridge() { + if (!this._bridgeInstance) { + this._bridgeInstance = new Bridge(this.transport, CallbackFactory()); + } + return this._bridgeInstance; + } + get transport() { + if (!this._transportInstance) { + this._transportInstance = new InteropTransport(this.agm, CallbackFactory()); + } + return this._transportInstance; + } + get privateDataManager() { + if (!this._privateDataManagerInstance) { + this._privateDataManagerInstance = new PrivateDataManager(); + } + return this._privateDataManagerInstance; + } + get parentBase() { + if (!this._parentBaseInstance) { + this._parentBaseInstance = new Base(this.privateDataManager); + } + return this._parentBaseInstance; + } + async initiate(actualWindowId) { + await this.transport.initiate(actualWindowId); + } + getModel(type, createConfig) { + switch (type) { + case "frame": { + const newFrame = new Frame(this.privateDataManager); + const { summary } = createConfig; + const frameData = { summary, controller: this.controller }; + this.privateDataManager.setFrameData(newFrame, frameData); + return newFrame; + } + case "window": { + const { id, parent, frame, workspace, config } = createConfig; + const windowPrivateData = { + type: "window", + controller: this.controller, + config, id, parent, frame, workspace + }; + const newWindow = new Window(this.privateDataManager); + this.privateDataManager.setWindowData(newWindow, windowPrivateData); + return newWindow; + } + case "row": + case "column": + case "group": { + const { id, children, parent, frame, workspace, config } = createConfig; + const newParent = type === "column" ? new Column(this.parentBase) : + type === "row" ? new Row(this.parentBase) : new Group(this.parentBase); + const builtChildren = this.buildChildren(children, frame, workspace, newParent); + const parentPrivateData = { + id, parent, frame, workspace, + config, + type, + controller: this.controller, + children: builtChildren, + }; + this.privateDataManager.setParentData(newParent, parentPrivateData); + return newParent; + } + case "workspace": { + const { snapshot, frame } = createConfig; + const newWorkspace = new Workspace(this.privateDataManager); + const children = this.buildChildren(snapshot.children, frame, newWorkspace, newWorkspace); + const workspacePrivateData = { + id: snapshot.id, + type: "workspace", + config: snapshot.config, + base: this.parentBase, + controller: this.controller, + children, frame, ioc: this + }; + this.privateDataManager.setWorkspaceData(newWorkspace, workspacePrivateData); + return newWorkspace; + } + default: throw new Error(`Unrecognized type: ${type}`); + } + } + getBuilder(config) { + config.definition = config.definition || {}; + if (!Array.isArray(config.definition.children)) { + config.definition.children = []; + } + const baseBuilder = new BaseBuilder(this.getBuilder.bind(this)); + switch (config.type) { + case "workspace": { + return new WorkspaceBuilder(config.definition, baseBuilder, this.controller); + } + case "row": + case "column": + case "group": { + config.definition.type = config.type; + return new ParentBuilder(config.definition, baseBuilder); + } + default: throw new Error(`Unexpected Builder creation error, provided config: ${JSON.stringify(config)}`); + } + } + buildChildren(children, frame, workspace, parent) { + return children.map((child) => { + switch (child.type) { + case "window": return this.getModel("window", { + id: child.id, + config: child.config, + frame, workspace, parent + }); + case "column": return this.getModel(child.type, { + id: child.id, + config: child.config, + children: child.children, + frame, workspace, parent + }); + case "row": return this.getModel(child.type, { + id: child.id, + config: child.config, + children: child.children, + frame, workspace, parent + }); + case "group": return this.getModel(child.type, { + id: child.id, + config: child.config, + children: child.children, + frame, workspace, parent + }); + default: throw new Error(`Unsupported child type: ${child.type}`); + } + }); + } + } + + var version = "3.5.6"; + + const composeAPI = (glue, ioc) => { + const controller = ioc.controller; + const inWorkspace = () => { + const myId = glue.windows.my().id; + if (!myId) { + throw new Error("Cannot get my frame, because my id is undefined."); + } + return controller.checkIsInSwimlane(myId); + }; + const getBuilder = (config) => { + const validatedConfig = builderConfigDecoder.runWithException(config); + return ioc.getBuilder(validatedConfig); + }; + const getMyFrame = async () => { + const windowId = glue.windows.my().id; + if (!windowId) { + throw new Error("Cannot get my frame, because my id is undefined."); + } + const isInSwimlane = await controller.checkIsInSwimlane(windowId); + if (!isInSwimlane) { + throw new Error("Cannot fetch your frame, because this window is not in a workspace"); + } + return controller.getFrame({ windowId }); + }; + const getFrame = async (predicate) => { + checkThrowCallback(predicate); + return controller.getFrame({ predicate }); + }; + const getAllFrames = async (predicate) => { + checkThrowCallback(predicate, true); + return controller.getFrames(predicate); + }; + const getAllWorkspacesSummaries = () => { + return controller.getAllWorkspaceSummaries(); + }; + const getMyWorkspace = async () => { + const myId = glue.windows.my().id; + if (!myId) { + throw new Error("Cannot get my workspace, because my id is undefined."); + } + const isInSwimlane = await controller.checkIsInSwimlane(myId); + if (!isInSwimlane) { + throw new Error("Cannot fetch your workspace, because this window is not in a workspace"); + } + return await controller.getWorkspaceByWindowId(myId); + }; + const getWorkspace = async (predicate) => { + checkThrowCallback(predicate); + return (await controller.getWorkspaces(predicate))[0]; + }; + const getWorkspaceById = async (workspaceId) => { + nonEmptyStringDecoder.runWithException(workspaceId); + return controller.getWorkspaceById(workspaceId); + }; + const getAllWorkspaces = (predicate) => { + checkThrowCallback(predicate, true); + return controller.getWorkspaces(predicate); + }; + const getWindow = async (predicate) => { + checkThrowCallback(predicate); + return controller.getWindow(predicate); + }; + const getParent = async (predicate) => { + checkThrowCallback(predicate); + return controller.getParent(predicate); + }; + const restoreWorkspace = async (name, options) => { + nonEmptyStringDecoder.runWithException(name); + const validatedOptions = restoreWorkspaceConfigDecoder.runWithException(options); + return controller.restoreWorkspace(name, validatedOptions); + }; + const createWorkspace = async (definition, saveConfig) => { + const validatedDefinition = workspaceDefinitionDecoder.runWithException(definition); + const validatedConfig = workspaceBuilderCreateConfigDecoder.runWithException(saveConfig); + return controller.createWorkspace(validatedDefinition, validatedConfig); + }; + const createEmptyFrame = async (definition) => { + const validatedDefinition = emptyFrameDefinitionDecoder.runWithException(definition); + return controller.createEmptyFrame(validatedDefinition ?? {}); + }; + const layouts = { + getSummaries: () => { + return controller.getLayoutSummaries(); + }, + delete: async (name) => { + nonEmptyStringDecoder.runWithException(name); + return controller.deleteLayout(name); + }, + export: async (predicate) => { + checkThrowCallback(predicate, true); + return controller.exportLayout(predicate); + }, + import: async (layouts, mode = "replace") => { + if (!Array.isArray(layouts)) { + throw new Error(`The provided layouts argument is not an array: ${JSON.stringify(layouts)}`); + } + layouts.forEach((layout) => workspaceLayoutDecoder.runWithException(layout)); + return controller.importLayouts(layouts, mode); + }, + save: async (config) => { + const verifiedConfig = workspaceLayoutSaveConfigDecoder.runWithException(config); + return controller.saveLayout(verifiedConfig); + }, + onSaved: async (callback) => { + checkThrowCallback(callback); + return controller.handleOnSaved(callback); + }, + onRemoved: async (callback) => { + checkThrowCallback(callback); + return controller.handleOnRemoved(callback); + } + }; + const onFrameOpened = async (callback) => { + checkThrowCallback(callback); + const wrappedCallback = (payload) => { + const frameConfig = { + summary: payload.frameSummary + }; + const frame = ioc.getModel("frame", frameConfig); + callback(frame); + }; + const unsubscribe = await controller.processGlobalSubscription(wrappedCallback, "frame", "opened"); + return unsubscribe; + }; + const onFrameClosed = async (callback) => { + checkThrowCallback(callback); + const wrappedCallback = (payload) => { + callback({ frameId: payload.frameSummary.id, frameBounds: payload.frameBounds }); + }; + const unsubscribe = await controller.processGlobalSubscription(wrappedCallback, "frame", "closed"); + return unsubscribe; + }; + const onWorkspaceOpened = async (callback) => { + checkThrowCallback(callback); + const wrappedCallback = async (payload) => { + const workspace = await controller.transformStreamPayloadToWorkspace(payload); + callback(workspace); + }; + const unsubscribe = await controller.processGlobalSubscription(wrappedCallback, "workspace", "opened"); + return unsubscribe; + }; + const onWorkspaceClosed = async (callback) => { + checkThrowCallback(callback); + const wrappedCallback = (payload) => { + callback({ frameId: payload.frameSummary.id, workspaceId: payload.workspaceSummary.id, frameBounds: payload.frameBounds }); + }; + const unsubscribe = await controller.processGlobalSubscription(wrappedCallback, "workspace", "closed"); + return unsubscribe; + }; + const onWorkspaceHibernated = async (callback) => { + checkThrowCallback(callback); + const wrappedCallback = async (payload) => { + const workspace = await controller.transformStreamPayloadToWorkspace(payload); + callback(workspace); + }; + const unsubscribe = await controller.processGlobalSubscription(wrappedCallback, "workspace", "hibernated"); + return unsubscribe; + }; + const onWorkspaceResumed = async (callback) => { + checkThrowCallback(callback); + const wrappedCallback = async (payload) => { + const workspace = await controller.transformStreamPayloadToWorkspace(payload); + callback(workspace); + }; + const unsubscribe = await controller.processGlobalSubscription(wrappedCallback, "workspace", "resumed"); + return unsubscribe; + }; + const onWindowAdded = async (callback) => { + checkThrowCallback(callback); + const wrappedCallback = async (payload) => { + const snapshot = (await controller.getSnapshot(payload.windowSummary.config.workspaceId, "workspace")); + const frameConfig = { + summary: snapshot.frameSummary + }; + const frame = ioc.getModel("frame", frameConfig); + const workspaceConfig = { frame, snapshot }; + const workspace = ioc.getModel("workspace", workspaceConfig); + const windowParent = workspace.getBox((parent) => parent.id === payload.windowSummary.parentId); + const foundWindow = windowParent.children.find((child) => child.type === "window" && child.elementId === payload.windowSummary.itemId); + callback(foundWindow); + }; + const unsubscribe = await controller.processGlobalSubscription(wrappedCallback, "window", "added"); + return unsubscribe; + }; + const onWindowLoaded = async (callback) => { + checkThrowCallback(callback); + const wrappedCallback = async (payload) => { + const snapshot = (await controller.getSnapshot(payload.windowSummary.config.workspaceId, "workspace")); + const frameConfig = { + summary: snapshot.frameSummary + }; + const frame = ioc.getModel("frame", frameConfig); + const workspaceConfig = { frame, snapshot }; + const workspace = ioc.getModel("workspace", workspaceConfig); + const foundWindow = workspace.getWindow((win) => win.id && win.id === payload.windowSummary.config.windowId); + callback(foundWindow); + }; + const unsubscribe = await controller.processGlobalSubscription(wrappedCallback, "window", "loaded"); + return unsubscribe; + }; + const onWindowRemoved = async (callback) => { + checkThrowCallback(callback); + const wrappedCallback = (payload) => { + const { windowId, workspaceId, frameId } = payload.windowSummary.config; + callback({ windowId, workspaceId, frameId }); + }; + const unsubscribe = await controller.processGlobalSubscription(wrappedCallback, "window", "removed"); + return unsubscribe; + }; + const onWindowMaximized = async (callback) => { + checkThrowCallback(callback); + const wrappedCallback = async (payload) => { + const snapshot = (await controller.getSnapshot(payload.windowSummary.config.workspaceId, "workspace")); + const frameConfig = { + summary: snapshot.frameSummary + }; + const frame = ioc.getModel("frame", frameConfig); + const workspaceConfig = { frame, snapshot }; + const workspace = ioc.getModel("workspace", workspaceConfig); + const windowParent = workspace.getBox((parent) => parent.id === payload.windowSummary.parentId); + const foundWindow = windowParent.children.find((child) => child.type === "window" && child.elementId === payload.windowSummary.itemId); + callback(foundWindow); + }; + const unsubscribe = await controller.processGlobalSubscription(wrappedCallback, "window", "maximized"); + return unsubscribe; + }; + const onWindowRestored = async (callback) => { + checkThrowCallback(callback); + const wrappedCallback = async (payload) => { + const snapshot = (await controller.getSnapshot(payload.windowSummary.config.workspaceId, "workspace")); + const frameConfig = { + summary: snapshot.frameSummary + }; + const frame = ioc.getModel("frame", frameConfig); + const workspaceConfig = { frame, snapshot }; + const workspace = ioc.getModel("workspace", workspaceConfig); + const windowParent = workspace.getBox((parent) => parent.id === payload.windowSummary.parentId); + const foundWindow = windowParent.children.find((child) => child.type === "window" && child.elementId === payload.windowSummary.itemId); + callback(foundWindow); + }; + const unsubscribe = await controller.processGlobalSubscription(wrappedCallback, "window", "restored"); + return unsubscribe; + }; + const onWindowSelected = async (callback) => { + checkThrowCallback(callback); + const wrappedCallback = async (payload) => { + const snapshot = (await controller.getSnapshot(payload.windowSummary.config.workspaceId, "workspace")); + const frameConfig = { + summary: snapshot.frameSummary + }; + const frame = ioc.getModel("frame", frameConfig); + const workspaceConfig = { frame, snapshot }; + const workspace = ioc.getModel("workspace", workspaceConfig); + const windowParent = workspace.getBox((parent) => parent.id === payload.windowSummary.parentId); + const foundWindow = windowParent.children.find((child) => child.type === "window" && child.elementId === payload.windowSummary.itemId); + callback(foundWindow); + }; + const unsubscribe = await controller.processGlobalSubscription(wrappedCallback, "window", "selected"); + return unsubscribe; + }; + const waitForFrame = async (id) => { + nonEmptyStringDecoder.runWithException(id); + return new Promise((res, rej) => { + let unsub = () => { + }; + onFrameOpened((f) => { + if (f.id === id) { + res(f); + unsub(); + } + }).then((u) => { + unsub = u; + return getAllFrames(); + }).then((frames) => { + const myFrame = frames.find((f) => f.id === id); + if (myFrame) { + res(myFrame); + unsub(); + } + }).catch(rej); + }); + }; + return { + inWorkspace, + getBuilder, + getMyFrame, + getFrame, + getAllFrames, + getAllWorkspacesSummaries, + getMyWorkspace, + getWorkspace, + getWorkspaceById, + getAllWorkspaces, + getWindow, + getBox: getParent, + restoreWorkspace, + createWorkspace, + createEmptyFrame, + waitForFrame, + layouts, + onFrameOpened, + onFrameClosed, + onWorkspaceOpened, + onWorkspaceClosed, + onWorkspaceHibernated, + onWorkspaceResumed, + onWindowAdded, + onWindowLoaded, + onWindowRemoved, + onWindowMaximized, + onWindowRestored, + onWindowSelected, + version + }; + }; + + const factoryFunction = async (io) => { + const ioc = new IoC(io.agm, io.windows, io.layouts, io.contexts); + const actualWindowId = io.interop.instance.windowId; + await ioc.initiate(actualWindowId); + io.workspaces = composeAPI(io, ioc); + }; + if (typeof window !== "undefined") { + window.IOWorkspaces = factoryFunction; + } + + return factoryFunction; + +})); +//# sourceMappingURL=workspaces.umd.js.map diff --git a/typescript/solution/clients/tsconfig.json b/typescript/solution/clients/tsconfig.json new file mode 100644 index 0000000..11ec879 --- /dev/null +++ b/typescript/solution/clients/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "./dist", + "rootDir": "./src" + }, + "include": ["./src", "../../types"] +} \ No newline at end of file diff --git a/typescript/solution/clients/webpack.config.js b/typescript/solution/clients/webpack.config.js new file mode 100644 index 0000000..cf31d79 --- /dev/null +++ b/typescript/solution/clients/webpack.config.js @@ -0,0 +1,31 @@ +const path = require('path'); +const CopyWebpackPlugin = require('copy-webpack-plugin'); + +module.exports = { + mode: 'development', + entry: './src/index.ts', + module: { + rules: [ + { + test: /\.tsx?$/, + use: 'ts-loader', + exclude: /node_modules/, + }, + ], + }, + resolve: { + extensions: ['.tsx', '.ts', '.js'], + }, + output: { + filename: 'index.js', + path: path.resolve(__dirname, 'dist'), + }, + plugins: [ + new CopyWebpackPlugin({ + patterns: [ + { from: 'src/index.html', to: 'index.html' }, + { from: 'src/lib', to: 'lib' } + ], + }), + ], +}; \ No newline at end of file diff --git a/typescript/solution/layouts/Client Space.json b/typescript/solution/layouts/Client Space.json new file mode 100644 index 0000000..b4ef1a8 --- /dev/null +++ b/typescript/solution/layouts/Client Space.json @@ -0,0 +1,63 @@ +{ + "name": "Client Space", + "type": "Workspace", + "metadata": {}, + "components": [ + { + "type": "Workspace", + "state": { + "children": [ + { + "type": "column", + "children": [ + { + "type": "row", + "children": [ + { + "type": "group", + "children": [ + { + "type": "window", + "config": { + "appName": "client-details", + "title": "Client Details" + } + } + ], + "config": {} + }, + { + "type": "column", + "children": [ + { + "type": "group", + "children": [ + { + "type": "window", + "config": { + "appName": "stocks", + "title": "Stocks" + } + } + ], + "config": {} + } + ], + "config": {} + } + ], + "config": {} + } + ], + "config": {} + } + ], + "config": { + "name": "Client Space", + "title": "Client Space" + }, + "context": {} + } + } + ] +} \ No newline at end of file diff --git a/typescript/solution/package-lock.json b/typescript/solution/package-lock.json new file mode 100644 index 0000000..63a793c --- /dev/null +++ b/typescript/solution/package-lock.json @@ -0,0 +1,1270 @@ +{ + "name": "ts-tutorial-solution", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "ts-tutorial-solution", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "concurrently": "^9.1.2", + "http-server": "^14.1.1" + }, + "devDependencies": { + "esbuild": "^0.20.1", + "typescript": "^5.3.3" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz", + "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz", + "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz", + "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz", + "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz", + "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz", + "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz", + "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz", + "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz", + "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz", + "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz", + "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz", + "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz", + "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz", + "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz", + "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz", + "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz", + "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz", + "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz", + "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz", + "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz", + "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz", + "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz", + "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/async": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", + "license": "MIT" + }, + "node_modules/basic-auth": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", + "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", + "license": "MIT", + "dependencies": { + "safe-buffer": "5.1.2" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chalk/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" + }, + "node_modules/concurrently": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-9.1.2.tgz", + "integrity": "sha512-H9MWcoPsYddwbOGM6difjVwVZHl63nwMEwDJG/L7VGtuaJhb12h2caPG2tVPWs7emuYix252iGfqOyrz1GczTQ==", + "license": "MIT", + "dependencies": { + "chalk": "^4.1.2", + "lodash": "^4.17.21", + "rxjs": "^7.8.1", + "shell-quote": "^1.8.1", + "supports-color": "^8.1.1", + "tree-kill": "^1.2.2", + "yargs": "^17.7.2" + }, + "bin": { + "conc": "dist/bin/concurrently.js", + "concurrently": "dist/bin/concurrently.js" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/open-cli-tools/concurrently?sponsor=1" + } + }, + "node_modules/corser": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/corser/-/corser-2.0.1.tgz", + "integrity": "sha512-utCYNzRSQIZNPIcGZdQc92UVJYAhtGAteCFg0yRaFm8f0P+CPtyGyHXJcGXnffjCybUCEx3FQ2G7U3/o9eIkVQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/debug": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", + "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/esbuild": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz", + "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.20.2", + "@esbuild/android-arm": "0.20.2", + "@esbuild/android-arm64": "0.20.2", + "@esbuild/android-x64": "0.20.2", + "@esbuild/darwin-arm64": "0.20.2", + "@esbuild/darwin-x64": "0.20.2", + "@esbuild/freebsd-arm64": "0.20.2", + "@esbuild/freebsd-x64": "0.20.2", + "@esbuild/linux-arm": "0.20.2", + "@esbuild/linux-arm64": "0.20.2", + "@esbuild/linux-ia32": "0.20.2", + "@esbuild/linux-loong64": "0.20.2", + "@esbuild/linux-mips64el": "0.20.2", + "@esbuild/linux-ppc64": "0.20.2", + "@esbuild/linux-riscv64": "0.20.2", + "@esbuild/linux-s390x": "0.20.2", + "@esbuild/linux-x64": "0.20.2", + "@esbuild/netbsd-x64": "0.20.2", + "@esbuild/openbsd-x64": "0.20.2", + "@esbuild/sunos-x64": "0.20.2", + "@esbuild/win32-arm64": "0.20.2", + "@esbuild/win32-ia32": "0.20.2", + "@esbuild/win32-x64": "0.20.2" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "license": "MIT" + }, + "node_modules/follow-redirects": { + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "license": "MIT", + "bin": { + "he": "bin/he" + } + }, + "node_modules/html-encoding-sniffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", + "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==", + "license": "MIT", + "dependencies": { + "whatwg-encoding": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "license": "MIT", + "dependencies": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/http-server": { + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/http-server/-/http-server-14.1.1.tgz", + "integrity": "sha512-+cbxadF40UXd9T01zUHgA+rlo2Bg1Srer4+B4NwIHdaGxAGGv59nYRnGGDJ9LBk7alpS0US+J+bLLdQOOkJq4A==", + "license": "MIT", + "dependencies": { + "basic-auth": "^2.0.1", + "chalk": "^4.1.2", + "corser": "^2.0.1", + "he": "^1.2.0", + "html-encoding-sniffer": "^3.0.0", + "http-proxy": "^1.18.1", + "mime": "^1.6.0", + "minimist": "^1.2.6", + "opener": "^1.5.1", + "portfinder": "^1.0.28", + "secure-compare": "3.0.1", + "union": "~0.5.0", + "url-join": "^4.0.1" + }, + "bin": { + "http-server": "bin/http-server" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "license": "MIT" + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/opener": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", + "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", + "license": "(WTFPL OR MIT)", + "bin": { + "opener": "bin/opener-bin.js" + } + }, + "node_modules/portfinder": { + "version": "1.0.37", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.37.tgz", + "integrity": "sha512-yuGIEjDAYnnOex9ddMnKZEMFE0CcGo6zbfzDklkmT1m5z734ss6JMzN9rNB3+RR7iS+F10D4/BVIaXOyh8PQKw==", + "license": "MIT", + "dependencies": { + "async": "^3.2.6", + "debug": "^4.3.6" + }, + "engines": { + "node": ">= 10.12" + } + }, + "node_modules/qs": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz", + "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==", + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "license": "MIT" + }, + "node_modules/rxjs": { + "version": "7.8.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", + "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" + }, + "node_modules/secure-compare": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/secure-compare/-/secure-compare-3.0.1.tgz", + "integrity": "sha512-AckIIV90rPDcBcglUwXPF3kg0P0qmPsPXAj6BBEENQE1p5yA1xfmDJzfi1Tappj37Pv2mVbKpL3Z1T+Nn7k1Qw==", + "license": "MIT" + }, + "node_modules/shell-quote": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.2.tgz", + "integrity": "sha512-AzqKpGKjrj7EM6rKVQEPpB288oCfnrEIuyoT9cyF4nmGa7V8Zk6f7RRqYisX8X9m+Q7bd632aZW4ky7EhbQztA==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "license": "MIT", + "bin": { + "tree-kill": "cli.js" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/typescript": { + "version": "5.8.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", + "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/union": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/union/-/union-0.5.0.tgz", + "integrity": "sha512-N6uOhuW6zO95P3Mel2I2zMsbsanvvtgn6jVqJv4vbVcz/JN0OkL9suomjQGmWtxJQXOCqUJvquc1sMeNz/IwlA==", + "dependencies": { + "qs": "^6.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/url-join": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz", + "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==", + "license": "MIT" + }, + "node_modules/whatwg-encoding": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz", + "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==", + "license": "MIT", + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "license": "ISC", + "engines": { + "node": ">=12" + } + } + } +} diff --git a/typescript/solution/package.json b/typescript/solution/package.json new file mode 100644 index 0000000..de1f68f --- /dev/null +++ b/typescript/solution/package.json @@ -0,0 +1,28 @@ +{ + "name": "ts-tutorial-solution", + "version": "1.0.0", + "description": "io.Connect Desktop TypeScript Tutorial - Solution", + "scripts": { + "build": "npm run build:clients && npm run build:stocks && npm run build:client-details && npm run build:portfolio-downloader", + "build:clients": "node clients/esbuild.js", + "build:stocks": "node stocks/esbuild.js", + "build:client-details": "node client-details/esbuild.js", + "build:portfolio-downloader": "node portfolio-downloader/esbuild.js", + "start:clients": "http-server ./clients/dist -p 9000 -c-1", + "start:stocks": "http-server ./stocks/dist -p 9100 -c-1", + "start:clientDetails": "http-server ./client-details/dist -p 9200 -c-1", + "start:downloader": "http-server ./portfolio-downloader/dist -p 9300 -c-1", + "start": "concurrently \"npm run start:clients\" \"npm run start:stocks\" \"npm run start:clientDetails\" \"npm run start:downloader\"" + }, + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "concurrently": "^9.1.2", + "http-server": "^14.1.1" + }, + "devDependencies": { + "esbuild": "^0.20.1", + "typescript": "^5.3.3" + } +} \ No newline at end of file diff --git a/typescript/solution/portfolio-downloader/esbuild.js b/typescript/solution/portfolio-downloader/esbuild.js new file mode 100644 index 0000000..27c80dc --- /dev/null +++ b/typescript/solution/portfolio-downloader/esbuild.js @@ -0,0 +1,48 @@ +const fs = require('fs'); +const path = require('path'); +const { build } = require('esbuild'); + +// Directory paths +const srcDir = path.join(__dirname, 'src'); +const distDir = path.join(__dirname, 'dist'); + +// Ensure dist directory exists +if (!fs.existsSync(distDir)) { + fs.mkdirSync(distDir, { recursive: true }); +} + +// Copy HTML file +fs.copyFileSync( + path.join(srcDir, 'index.html'), + path.join(distDir, 'index.html') +); + +// Copy lib directory +const libSrcDir = path.join(srcDir, 'lib'); +const libDistDir = path.join(distDir, 'lib'); + +if (!fs.existsSync(libDistDir)) { + fs.mkdirSync(libDistDir, { recursive: true }); +} + +fs.readdirSync(libSrcDir).forEach(file => { + fs.copyFileSync( + path.join(libSrcDir, file), + path.join(libDistDir, file) + ); +}); + +// Build with esbuild +build({ + entryPoints: [path.join(srcDir, 'index.ts')], + bundle: true, + outfile: path.join(distDir, 'index.js'), + platform: 'browser', + format: 'iife', + sourcemap: true, + target: ['es2020'], + tsconfig: path.join(__dirname, 'tsconfig.json'), +}).catch((error) => { + console.error(error); + process.exit(1); +}); \ No newline at end of file diff --git a/typescript/solution/portfolio-downloader/src/index.html b/typescript/solution/portfolio-downloader/src/index.html new file mode 100644 index 0000000..523221a --- /dev/null +++ b/typescript/solution/portfolio-downloader/src/index.html @@ -0,0 +1,42 @@ + + + + + + + + + + + + Portfolio Downloader + + + + + + + + + + + +
+
+
+
+ io.Connect is unavailable +
+
+
+

Portfolio Downloader

+
+
+
+

+
+
+
+ + + \ No newline at end of file diff --git a/typescript/solution/portfolio-downloader/src/index.ts b/typescript/solution/portfolio-downloader/src/index.ts new file mode 100644 index 0000000..678ce09 --- /dev/null +++ b/typescript/solution/portfolio-downloader/src/index.ts @@ -0,0 +1,78 @@ +interface IntentContext { + data: { + clientName: string; + portfolio: Stock[]; + }; +} + +const intentHandler = (context: IntentContext | null): void => { + if (!context) { + return; + } + + setupTitle(context.data.clientName); + + const dataToWrite = JSON.stringify({ + date: new Date(Date.now()).toLocaleString("en-US"), + portfolio: context.data.portfolio + }, null, 4); + const blob = new Blob([dataToWrite], { type: "application/json" }); + const download = document.getElementById("download") as HTMLAnchorElement; + if (!download) return; + + const href = URL.createObjectURL(blob); + + download.href = href; + download.click(); + URL.revokeObjectURL(href); +}; + +const setupTitle = (clientName: string): void => { + const title = document.getElementById("portfolioName"); + if (!title) return; + + title.innerText = `Downloading the portfolio of ${clientName}...`; +}; + +// TODO: Chapter 3 +const toggleIOAvailable = (): void => { + const span = document.getElementById("ioConnectSpan"); + if (!span) return; + + span.classList.remove("bg-danger"); + span.classList.add("bg-success"); + span.textContent = "io.Connect is available"; +}; + +async function start(): Promise { + const html = document.documentElement; + const initialTheme = iodesktop.theme; + + html.className = initialTheme; + + // TODO: Chapter 3 + const io = await IODesktop(); + + window.io = io; + + toggleIOAvailable(); + + // TODO: Chapter 12.1 + const themeHandler = (newTheme: Theme): void => { + html.className = newTheme.name; + }; + + io.themes.onChanged(themeHandler); + + // TODO: Chapter 10.1 + io.intents.register("ExportPortfolio", intentHandler); +} + +// Add io property to window object +declare global { + interface Window { + io: IODesktopAPI; + } +} + +start().catch(console.error); \ No newline at end of file diff --git a/typescript/solution/portfolio-downloader/src/lib/desktop.umd.js b/typescript/solution/portfolio-downloader/src/lib/desktop.umd.js new file mode 100644 index 0000000..6cea2c9 --- /dev/null +++ b/typescript/solution/portfolio-downloader/src/lib/desktop.umd.js @@ -0,0 +1,23144 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define(factory) : + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.desktop = factory()); +})(this, (function () { 'use strict'; + + var MetricTypes = { + STRING: 1, + NUMBER: 2, + TIMESTAMP: 3, + OBJECT: 4 + }; + + function getMetricTypeByValue(metric) { + if (metric.type === MetricTypes.TIMESTAMP) { + return "timestamp"; + } + else if (metric.type === MetricTypes.NUMBER) { + return "number"; + } + else if (metric.type === MetricTypes.STRING) { + return "string"; + } + else if (metric.type === MetricTypes.OBJECT) { + return "object"; + } + return "unknown"; + } + function getTypeByValue(value) { + if (value.constructor === Date) { + return "timestamp"; + } + else if (typeof value === "number") { + return "number"; + } + else if (typeof value === "string") { + return "string"; + } + else if (typeof value === "object") { + return "object"; + } + else { + return "string"; + } + } + function serializeMetric(metric) { + const serializedMetrics = {}; + const type = getMetricTypeByValue(metric); + if (type === "object") { + const values = Object.keys(metric.value).reduce((memo, key) => { + const innerType = getTypeByValue(metric.value[key]); + if (innerType === "object") { + const composite = defineNestedComposite(metric.value[key]); + memo[key] = { + type: "object", + description: "", + context: {}, + composite, + }; + } + else { + memo[key] = { + type: innerType, + description: "", + context: {}, + }; + } + return memo; + }, {}); + serializedMetrics.composite = values; + } + serializedMetrics.name = normalizeMetricName(metric.path.join("/") + "/" + metric.name); + serializedMetrics.type = type; + serializedMetrics.description = metric.description; + serializedMetrics.context = {}; + return serializedMetrics; + } + function defineNestedComposite(values) { + return Object.keys(values).reduce((memo, key) => { + const type = getTypeByValue(values[key]); + if (type === "object") { + memo[key] = { + type: "object", + description: "", + context: {}, + composite: defineNestedComposite(values[key]), + }; + } + else { + memo[key] = { + type, + description: "", + context: {}, + }; + } + return memo; + }, {}); + } + function normalizeMetricName(name) { + if (typeof name !== "undefined" && name.length > 0 && name[0] !== "/") { + return "/" + name; + } + else { + return name; + } + } + function getMetricValueByType(metric) { + const type = getMetricTypeByValue(metric); + if (type === "timestamp") { + return Date.now(); + } + else { + return publishNestedComposite(metric.value); + } + } + function publishNestedComposite(values) { + if (typeof values !== "object") { + return values; + } + return Object.keys(values).reduce((memo, key) => { + const value = values[key]; + if (typeof value === "object" && value.constructor !== Date) { + memo[key] = publishNestedComposite(value); + } + else if (value.constructor === Date) { + memo[key] = new Date(value).getTime(); + } + else if (value.constructor === Boolean) { + memo[key] = value.toString(); + } + else { + memo[key] = value; + } + return memo; + }, {}); + } + function flatten(arr) { + return arr.reduce((flat, toFlatten) => { + return flat.concat(Array.isArray(toFlatten) ? flatten(toFlatten) : toFlatten); + }, []); + } + function getHighestState(arr) { + return arr.sort((a, b) => { + if (!a.state) { + return 1; + } + if (!b.state) { + return -1; + } + return b.state - a.state; + })[0]; + } + function aggregateDescription(arr) { + let msg = ""; + arr.forEach((m, idx, a) => { + const path = m.path.join("."); + if (idx === a.length - 1) { + msg += path + "." + m.name + ": " + m.description; + } + else { + msg += path + "." + m.name + ": " + m.description + ","; + } + }); + if (msg.length > 100) { + return msg.slice(0, 100) + "..."; + } + else { + return msg; + } + } + function composeMsgForRootStateMetric(system) { + const aggregatedState = system.root.getAggregateState(); + const merged = flatten(aggregatedState); + const highestState = getHighestState(merged); + const aggregateDesc = aggregateDescription(merged); + return { + description: aggregateDesc, + value: highestState.state, + }; + } + + function gw3 (connection, config) { + if (!connection || typeof connection !== "object") { + throw new Error("Connection is required parameter"); + } + let joinPromise; + let session; + const init = (repo) => { + let resolveReadyPromise; + joinPromise = new Promise((resolve) => { + resolveReadyPromise = resolve; + }); + session = connection.domain("metrics"); + session.onJoined((reconnect) => { + if (!reconnect && resolveReadyPromise) { + resolveReadyPromise(); + resolveReadyPromise = undefined; + } + const rootStateMetric = { + name: "/State", + type: "object", + composite: { + Description: { + type: "string", + description: "", + }, + Value: { + type: "number", + description: "", + }, + }, + description: "System state", + context: {}, + }; + const defineRootMetricsMsg = { + type: "define", + metrics: [rootStateMetric], + }; + session.send(defineRootMetricsMsg); + if (reconnect) { + replayRepo(repo); + } + }); + session.join({ + system: config.system, + service: config.service, + instance: config.instance + }); + }; + const replayRepo = (repo) => { + replaySystem(repo.root); + }; + const replaySystem = (system) => { + createSystem(system); + system.metrics.forEach((m) => { + createMetric(m); + }); + system.subSystems.forEach((ss) => { + replaySystem(ss); + }); + }; + const createSystem = async (system) => { + if (system.parent === undefined) { + return; + } + await joinPromise; + const metric = { + name: normalizeMetricName(system.path.join("/") + "/" + system.name + "/State"), + type: "object", + composite: { + Description: { + type: "string", + description: "", + }, + Value: { + type: "number", + description: "", + }, + }, + description: "System state", + context: {}, + }; + const createMetricsMsg = { + type: "define", + metrics: [metric], + }; + session.send(createMetricsMsg); + }; + const updateSystem = async (system, state) => { + await joinPromise; + const shadowedUpdateMetric = { + type: "publish", + values: [{ + name: normalizeMetricName(system.path.join("/") + "/" + system.name + "/State"), + value: { + Description: state.description, + Value: state.state, + }, + timestamp: Date.now(), + }], + }; + session.send(shadowedUpdateMetric); + const stateObj = composeMsgForRootStateMetric(system); + const rootMetric = { + type: "publish", + peer_id: connection.peerId, + values: [{ + name: "/State", + value: { + Description: stateObj.description, + Value: stateObj.value, + }, + timestamp: Date.now(), + }], + }; + session.send(rootMetric); + }; + const createMetric = async (metric) => { + const metricClone = cloneMetric(metric); + await joinPromise; + const m = serializeMetric(metricClone); + const createMetricsMsg = { + type: "define", + metrics: [m], + }; + session.send(createMetricsMsg); + if (typeof metricClone.value !== "undefined") { + updateMetricCore(metricClone); + } + }; + const updateMetric = async (metric) => { + const metricClone = cloneMetric(metric); + await joinPromise; + updateMetricCore(metricClone); + }; + const updateMetricCore = (metric) => { + if (canUpdate()) { + const value = getMetricValueByType(metric); + const publishMetricsMsg = { + type: "publish", + values: [{ + name: normalizeMetricName(metric.path.join("/") + "/" + metric.name), + value, + timestamp: Date.now(), + }], + }; + return session.sendFireAndForget(publishMetricsMsg); + } + return Promise.resolve(); + }; + const cloneMetric = (metric) => { + const metricClone = { ...metric }; + if (typeof metric.value === "object" && metric.value !== null) { + metricClone.value = { ...metric.value }; + } + return metricClone; + }; + const canUpdate = () => { + try { + const func = config.canUpdateMetric ?? (() => true); + return func(); + } + catch { + return true; + } + }; + return { + init, + createSystem, + updateSystem, + createMetric, + updateMetric, + }; + } + + var Helpers = { + validate: (definition, parent, transport) => { + if (definition === null || typeof definition !== "object") { + throw new Error("Missing definition"); + } + if (parent === null || typeof parent !== "object") { + throw new Error("Missing parent"); + } + if (transport === null || typeof transport !== "object") { + throw new Error("Missing transport"); + } + }, + }; + + class BaseMetric { + definition; + system; + transport; + value; + type; + path = []; + name; + description; + get repo() { + return this.system?.repo; + } + get id() { return `${this.system.path}/${name}`; } + constructor(definition, system, transport, value, type) { + this.definition = definition; + this.system = system; + this.transport = transport; + this.value = value; + this.type = type; + Helpers.validate(definition, system, transport); + this.path = system.path.slice(0); + this.path.push(system.name); + this.name = definition.name; + this.description = definition.description; + transport.createMetric(this); + } + update(newValue) { + this.value = newValue; + return this.transport.updateMetric(this); + } + } + + class NumberMetric extends BaseMetric { + constructor(definition, system, transport, value) { + super(definition, system, transport, value, MetricTypes.NUMBER); + } + incrementBy(num) { + this.update(this.value + num); + } + increment() { + this.incrementBy(1); + } + decrement() { + this.incrementBy(-1); + } + decrementBy(num) { + this.incrementBy(num * -1); + } + } + + class ObjectMetric extends BaseMetric { + constructor(definition, system, transport, value) { + super(definition, system, transport, value, MetricTypes.OBJECT); + } + update(newValue) { + this.mergeValues(newValue); + return this.transport.updateMetric(this); + } + mergeValues(values) { + return Object.keys(this.value).forEach((k) => { + if (typeof values[k] !== "undefined") { + this.value[k] = values[k]; + } + }); + } + } + + class StringMetric extends BaseMetric { + constructor(definition, system, transport, value) { + super(definition, system, transport, value, MetricTypes.STRING); + } + } + + class TimestampMetric extends BaseMetric { + constructor(definition, system, transport, value) { + super(definition, system, transport, value, MetricTypes.TIMESTAMP); + } + now() { + this.update(new Date()); + } + } + + function system$1(name, repo, protocol, parent, description) { + if (!repo) { + throw new Error("Repository is required"); + } + if (!protocol) { + throw new Error("Transport is required"); + } + const _transport = protocol; + const _name = name; + const _description = description || ""; + const _repo = repo; + const _parent = parent; + const _path = _buildPath(parent); + let _state = {}; + const id = _arrayToString(_path, "/") + name; + const root = repo.root; + const _subSystems = []; + const _metrics = []; + function subSystem(nameSystem, descriptionSystem) { + if (!nameSystem || nameSystem.length === 0) { + throw new Error("name is required"); + } + const match = _subSystems.filter((s) => s.name === nameSystem); + if (match.length > 0) { + return match[0]; + } + const _system = system$1(nameSystem, _repo, _transport, me, descriptionSystem); + _subSystems.push(_system); + return _system; + } + function setState(state, stateDescription) { + _state = { state, description: stateDescription }; + _transport.updateSystem(me, _state); + } + function stringMetric(definition, value) { + return _getOrCreateMetric(definition, MetricTypes.STRING, value, (metricDef) => new StringMetric(metricDef, me, _transport, value)); + } + function numberMetric(definition, value) { + return _getOrCreateMetric(definition, MetricTypes.NUMBER, value, (metricDef) => new NumberMetric(metricDef, me, _transport, value)); + } + function objectMetric(definition, value) { + return _getOrCreateMetric(definition, MetricTypes.OBJECT, value, (metricDef) => new ObjectMetric(metricDef, me, _transport, value)); + } + function timestampMetric(definition, value) { + return _getOrCreateMetric(definition, MetricTypes.TIMESTAMP, value, (metricDef) => new TimestampMetric(metricDef, me, _transport, value)); + } + function _getOrCreateMetric(metricObject, expectedType, value, createMetric) { + let metricDef = { name: "" }; + if (typeof metricObject === "string") { + metricDef = { name: metricObject }; + } + else { + metricDef = metricObject; + } + const matching = _metrics.filter((shadowedMetric) => shadowedMetric.name === metricDef.name); + if (matching.length > 0) { + const existing = matching[0]; + if (existing.type !== expectedType) { + throw new Error(`A metric named ${metricDef.name} is already defined with different type.`); + } + if (typeof value !== "undefined") { + existing + .update(value) + .catch(() => { }); + } + return existing; + } + const metric = createMetric(metricDef); + _metrics.push(metric); + return metric; + } + function _buildPath(shadowedSystem) { + if (!shadowedSystem || !shadowedSystem.parent) { + return []; + } + const path = _buildPath(shadowedSystem.parent); + path.push(shadowedSystem.name); + return path; + } + function _arrayToString(path, separator) { + return ((path && path.length > 0) ? path.join(separator) : ""); + } + function getAggregateState() { + const aggState = []; + if (Object.keys(_state).length > 0) { + aggState.push({ + name: _name, + path: _path, + state: _state.state, + description: _state.description, + }); + } + _subSystems.forEach((shadowedSubSystem) => { + const result = shadowedSubSystem.getAggregateState(); + if (result.length > 0) { + aggState.push(...result); + } + }); + return aggState; + } + const me = { + get name() { + return _name; + }, + get description() { + return _description; + }, + get repo() { + return _repo; + }, + get parent() { + return _parent; + }, + path: _path, + id, + root, + get subSystems() { + return _subSystems; + }, + get metrics() { + return _metrics; + }, + subSystem, + getState: () => { + return _state; + }, + setState, + stringMetric, + timestampMetric, + objectMetric, + numberMetric, + getAggregateState, + }; + _transport.createSystem(me); + return me; + } + + class Repository { + root; + constructor(options, protocol) { + protocol.init(this); + this.root = system$1("", this, protocol); + this.addSystemMetrics(this.root, options.clickStream || options.clickStream === undefined); + } + addSystemMetrics(rootSystem, useClickStream) { + if (typeof navigator !== "undefined") { + rootSystem.stringMetric("UserAgent", navigator.userAgent); + } + if (useClickStream && typeof document !== "undefined") { + const clickStream = rootSystem.subSystem("ClickStream"); + const documentClickHandler = (e) => { + if (!e.target) { + return; + } + const target = e.target; + const className = target ? target.getAttribute("class") ?? "" : ""; + clickStream.objectMetric("LastBrowserEvent", { + type: "click", + timestamp: new Date(), + target: { + className, + id: target.id, + type: "<" + target.tagName.toLowerCase() + ">", + href: target.href || "", + }, + }); + }; + clickStream.objectMetric("Page", { + title: document.title, + page: window.location.href, + }); + if (document.addEventListener) { + document.addEventListener("click", documentClickHandler); + } + else { + document.attachEvent("onclick", documentClickHandler); + } + } + rootSystem.stringMetric("StartTime", (new Date()).toString()); + const urlMetric = rootSystem.stringMetric("StartURL", ""); + const appNameMetric = rootSystem.stringMetric("AppName", ""); + if (typeof window !== "undefined") { + if (typeof window.location !== "undefined") { + const startUrl = window.location.href; + urlMetric.update(startUrl); + } + if (typeof window.glue42gd !== "undefined") { + appNameMetric.update(window.glue42gd.appName); + } + } + } + } + + class NullProtocol { + init(repo) { + } + createSystem(system) { + return Promise.resolve(); + } + updateSystem(metric, state) { + return Promise.resolve(); + } + createMetric(metric) { + return Promise.resolve(); + } + updateMetric(metric) { + return Promise.resolve(); + } + } + + class PerfTracker { + api; + lastCount = 0; + initialPublishTimeout = 10 * 1000; + publishInterval = 60 * 1000; + system; + constructor(api, initialPublishTimeout, publishInterval) { + this.api = api; + this.initialPublishTimeout = initialPublishTimeout ?? this.initialPublishTimeout; + this.publishInterval = publishInterval ?? this.publishInterval; + this.scheduleCollection(); + this.system = this.api.subSystem("performance", "Performance data published by the web application"); + } + scheduleCollection() { + setTimeout(() => { + this.collect(); + setInterval(() => { + this.collect(); + }, this.publishInterval); + }, this.initialPublishTimeout); + } + collect() { + try { + this.collectMemory(); + this.collectEntries(); + } + catch { + } + } + collectMemory() { + const memory = window.performance.memory; + this.system.stringMetric("memory", JSON.stringify({ + totalJSHeapSize: memory.totalJSHeapSize, + usedJSHeapSize: memory.usedJSHeapSize + })); + } + collectEntries() { + const allEntries = window.performance.getEntries(); + if (allEntries.length <= this.lastCount) { + return; + } + this.lastCount = allEntries.length; + const jsonfiedEntries = allEntries.map((i) => i.toJSON()); + this.system.stringMetric("entries", JSON.stringify(jsonfiedEntries)); + } + } + + var metrics = (options) => { + let protocol; + if (!options.connection || typeof options.connection !== "object") { + protocol = new NullProtocol(); + } + else { + protocol = gw3(options.connection, options); + } + const repo = new Repository(options, protocol); + let rootSystem = repo.root; + if (!options.disableAutoAppSystem) { + rootSystem = rootSystem.subSystem("App"); + } + const api = addFAVSupport(rootSystem); + initPerf(api, options.pagePerformanceMetrics); + return api; + }; + function initPerf(api, config) { + if (typeof window === "undefined") { + return; + } + const perfConfig = window?.glue42gd?.metrics?.pagePerformanceMetrics; + if (perfConfig) { + config = perfConfig; + } + if (config?.enabled) { + new PerfTracker(api, config.initialPublishTimeout, config.publishInterval); + } + } + function addFAVSupport(system) { + const reportingSystem = system.subSystem("reporting"); + const def = { + name: "features" + }; + let featureMetric; + const featureMetricFunc = (name, action, payload) => { + if (typeof name === "undefined" || name === "") { + throw new Error("name is mandatory"); + } + else if (typeof action === "undefined" || action === "") { + throw new Error("action is mandatory"); + } + else if (typeof payload === "undefined" || payload === "") { + throw new Error("payload is mandatory"); + } + if (!featureMetric) { + featureMetric = reportingSystem.objectMetric(def, { name, action, payload }); + } + else { + featureMetric.update({ + name, + action, + payload + }); + } + }; + system.featureMetric = featureMetricFunc; + return system; + } + + var commonjsGlobal$1 = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; + + function getDefaultExportFromCjs$1 (x) { + return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; + } + + function createRegistry$1(options) { + if (options && options.errorHandling + && typeof options.errorHandling !== "function" + && options.errorHandling !== "log" + && options.errorHandling !== "silent" + && options.errorHandling !== "throw") { + throw new Error("Invalid options passed to createRegistry. Prop errorHandling should be [\"log\" | \"silent\" | \"throw\" | (err) => void], but " + typeof options.errorHandling + " was passed"); + } + var _userErrorHandler = options && typeof options.errorHandling === "function" && options.errorHandling; + var callbacks = {}; + function add(key, callback, replayArgumentsArr) { + var callbacksForKey = callbacks[key]; + if (!callbacksForKey) { + callbacksForKey = []; + callbacks[key] = callbacksForKey; + } + callbacksForKey.push(callback); + if (replayArgumentsArr) { + setTimeout(function () { + replayArgumentsArr.forEach(function (replayArgument) { + var _a; + if ((_a = callbacks[key]) === null || _a === void 0 ? void 0 : _a.includes(callback)) { + try { + if (Array.isArray(replayArgument)) { + callback.apply(undefined, replayArgument); + } + else { + callback.apply(undefined, [replayArgument]); + } + } + catch (err) { + _handleError(err, key); + } + } + }); + }, 0); + } + return function () { + var allForKey = callbacks[key]; + if (!allForKey) { + return; + } + allForKey = allForKey.reduce(function (acc, element, index) { + if (!(element === callback && acc.length === index)) { + acc.push(element); + } + return acc; + }, []); + if (allForKey.length === 0) { + delete callbacks[key]; + } + else { + callbacks[key] = allForKey; + } + }; + } + function execute(key) { + var argumentsArr = []; + for (var _i = 1; _i < arguments.length; _i++) { + argumentsArr[_i - 1] = arguments[_i]; + } + var callbacksForKey = callbacks[key]; + if (!callbacksForKey || callbacksForKey.length === 0) { + return []; + } + var results = []; + callbacksForKey.forEach(function (callback) { + try { + var result = callback.apply(undefined, argumentsArr); + results.push(result); + } + catch (err) { + results.push(undefined); + _handleError(err, key); + } + }); + return results; + } + function _handleError(exceptionArtifact, key) { + var errParam = exceptionArtifact instanceof Error ? exceptionArtifact : new Error(exceptionArtifact); + if (_userErrorHandler) { + _userErrorHandler(errParam); + return; + } + var msg = "[ERROR] callback-registry: User callback for key \"" + key + "\" failed: " + errParam.stack; + if (options) { + switch (options.errorHandling) { + case "log": + return console.error(msg); + case "silent": + return; + case "throw": + throw new Error(msg); + } + } + console.error(msg); + } + function clear() { + callbacks = {}; + } + function clearKey(key) { + var callbacksForKey = callbacks[key]; + if (!callbacksForKey) { + return; + } + delete callbacks[key]; + } + return { + add: add, + execute: execute, + clear: clear, + clearKey: clearKey + }; + } + createRegistry$1.default = createRegistry$1; + var lib$1 = createRegistry$1; + + + var CallbackRegistryFactory$1 = /*@__PURE__*/getDefaultExportFromCjs$1(lib$1); + + class InProcTransport { + gw; + registry = CallbackRegistryFactory$1(); + client; + constructor(settings, logger) { + this.gw = settings.facade; + this.gw.connect((_client, message) => { + this.messageHandler(message); + }).then((client) => { + this.client = client; + }); + } + get isObjectBasedTransport() { + return true; + } + sendObject(msg) { + if (this.client) { + this.client.send(msg); + return Promise.resolve(undefined); + } + else { + return Promise.reject(`not connected`); + } + } + send(_msg) { + return Promise.reject("not supported"); + } + onMessage(callback) { + return this.registry.add("onMessage", callback); + } + onConnectedChanged(callback) { + callback(true); + return () => { }; + } + close() { + return Promise.resolve(); + } + open() { + return Promise.resolve(); + } + name() { + return "in-memory"; + } + reconnect() { + return Promise.resolve(); + } + messageHandler(msg) { + this.registry.execute("onMessage", msg); + } + } + + class SharedWorkerTransport { + logger; + worker; + registry = CallbackRegistryFactory$1(); + constructor(workerFile, logger) { + this.logger = logger; + this.worker = new SharedWorker(workerFile); + this.worker.port.onmessage = (e) => { + this.messageHandler(e.data); + }; + } + get isObjectBasedTransport() { + return true; + } + sendObject(msg) { + this.worker.port.postMessage(msg); + return Promise.resolve(); + } + send(_msg) { + return Promise.reject("not supported"); + } + onMessage(callback) { + return this.registry.add("onMessage", callback); + } + onConnectedChanged(callback) { + callback(true); + return () => { }; + } + close() { + return Promise.resolve(); + } + open() { + return Promise.resolve(); + } + name() { + return "shared-worker"; + } + reconnect() { + return Promise.resolve(); + } + messageHandler(msg) { + this.registry.execute("onMessage", msg); + } + } + + let Utils$1 = class Utils { + static isNode() { + if (typeof Utils._isNode !== "undefined") { + return Utils._isNode; + } + if (typeof window !== "undefined") { + Utils._isNode = false; + return false; + } + try { + Utils._isNode = Object.prototype.toString.call(global.process) === "[object process]"; + } + catch (e) { + Utils._isNode = false; + } + return Utils._isNode; + } + static _isNode; + }; + + let PromiseWrapper$1 = class PromiseWrapper { + static delay(time) { + return new Promise((resolve) => setTimeout(resolve, time)); + } + resolve; + reject; + promise; + rejected = false; + resolved = false; + get ended() { + return this.rejected || this.resolved; + } + constructor() { + this.promise = new Promise((resolve, reject) => { + this.resolve = (t) => { + this.resolved = true; + resolve(t); + }; + this.reject = (err) => { + this.rejected = true; + reject(err); + }; + }); + } + }; + + const timers = {}; + function getAllTimers() { + return timers; + } + function timer (timerName) { + const existing = timers[timerName]; + if (existing) { + return existing; + } + const marks = []; + function now() { + return new Date().getTime(); + } + const startTime = now(); + mark("start", startTime); + let endTime; + let period; + function stop() { + endTime = now(); + mark("end", endTime); + period = endTime - startTime; + return period; + } + function mark(name, time) { + const currentTime = time ?? now(); + let diff = 0; + if (marks.length > 0) { + diff = currentTime - marks[marks.length - 1].time; + } + marks.push({ name, time: currentTime, diff }); + } + const timerObj = { + get startTime() { + return startTime; + }, + get endTime() { + return endTime; + }, + get period() { + return period; + }, + stop, + mark, + marks + }; + timers[timerName] = timerObj; + return timerObj; + } + + const WebSocketConstructor = Utils$1.isNode() ? require("ws") : window.WebSocket; + class WS { + ws; + logger; + settings; + startupTimer = timer("connection"); + _running = true; + _registry = CallbackRegistryFactory$1(); + wsRequests = []; + constructor(settings, logger) { + this.settings = settings; + this.logger = logger; + if (!this.settings.ws) { + throw new Error("ws is missing"); + } + } + onMessage(callback) { + return this._registry.add("onMessage", callback); + } + send(msg, options) { + return new Promise((resolve, reject) => { + this.waitForSocketConnection(() => { + try { + this.ws?.send(msg); + resolve(); + } + catch (e) { + reject(e); + } + }, reject); + }); + } + open() { + this.logger.info("opening ws..."); + this._running = true; + return new Promise((resolve, reject) => { + this.waitForSocketConnection(resolve, reject); + }); + } + close() { + this._running = false; + if (this.ws) { + this.ws.close(); + } + return Promise.resolve(); + } + onConnectedChanged(callback) { + return this._registry.add("onConnectedChanged", callback); + } + name() { + return this.settings.ws; + } + reconnect() { + this.ws?.close(); + const pw = new PromiseWrapper$1(); + this.waitForSocketConnection(() => { + pw.resolve(); + }); + return pw.promise; + } + waitForSocketConnection(callback, failed) { + failed = failed ?? (() => { }); + if (!this._running) { + failed(`wait for socket on ${this.settings.ws} failed - socket closed by user`); + return; + } + if (this.ws?.readyState === 1) { + callback(); + return; + } + this.wsRequests.push({ callback, failed }); + if (this.wsRequests.length > 1) { + return; + } + this.openSocket(); + } + async openSocket(retryInterval, retriesLeft) { + this.logger.info(`opening ws to ${this.settings.ws}, retryInterval: ${retryInterval}, retriesLeft: ${retriesLeft}...`); + this.startupTimer.mark("opening-socket"); + if (retryInterval === undefined) { + retryInterval = this.settings.reconnectInterval; + } + if (typeof retriesLeft === "undefined") { + retriesLeft = this.settings.reconnectAttempts; + } + if (retriesLeft !== undefined) { + if (retriesLeft === 0) { + this.notifyForSocketState(`wait for socket on ${this.settings.ws} failed - no more retries left`); + return; + } + this.logger.debug(`will retry ${retriesLeft} more times (every ${retryInterval} ms)`); + } + try { + await this.initiateSocket(); + this.startupTimer.mark("socket-initiated"); + this.notifyForSocketState(); + } + catch { + setTimeout(() => { + const retries = retriesLeft === undefined ? undefined : retriesLeft - 1; + this.openSocket(retryInterval, retries); + }, retryInterval); + } + } + initiateSocket() { + const pw = new PromiseWrapper$1(); + this.logger.debug(`initiating ws to ${this.settings.ws}...`); + this.ws = new WebSocketConstructor(this.settings.ws ?? ""); + this.ws.onerror = (err) => { + let reason = ""; + try { + reason = JSON.stringify(err); + } + catch (error) { + const seen = new WeakSet(); + const replacer = (key, value) => { + if (typeof value === "object" && value !== null) { + if (seen.has(value)) { + return; + } + seen.add(value); + } + return value; + }; + reason = JSON.stringify(err, replacer); + } + this.logger.info(`ws error - reason: ${reason}`); + pw.reject("error"); + this.notifyStatusChanged(false, reason); + }; + this.ws.onclose = (err) => { + this.logger.info(`ws closed - code: ${err?.code} reason: ${err?.reason}`); + pw.reject("closed"); + this.notifyStatusChanged(false); + }; + this.ws.onopen = () => { + this.startupTimer.mark("ws-opened"); + this.logger.info(`ws opened ${this.settings.identity?.application}`); + pw.resolve(); + this.notifyStatusChanged(true); + }; + this.ws.onmessage = (message) => { + this._registry.execute("onMessage", message.data); + }; + return pw.promise; + } + notifyForSocketState(error) { + this.wsRequests.forEach((wsRequest) => { + if (error) { + if (wsRequest.failed) { + wsRequest.failed(error); + } + } + else { + wsRequest.callback(); + } + }); + this.wsRequests = []; + } + notifyStatusChanged(status, reason) { + this._registry.execute("onConnectedChanged", status, reason); + } + } + + class MessageReplayerImpl { + specs; + specsNames = []; + messages = {}; + isDone; + subs = {}; + subsRefCount = {}; + connection; + constructor(specs) { + this.specs = {}; + for (const spec of specs) { + this.specs[spec.name] = spec; + this.specsNames.push(spec.name); + } + } + init(connection) { + this.connection = connection; + for (const name of this.specsNames) { + for (const type of this.specs[name].types) { + let refCount = this.subsRefCount[type]; + if (!refCount) { + refCount = 0; + } + refCount += 1; + this.subsRefCount[type] = refCount; + if (refCount > 1) { + continue; + } + const sub = connection.on(type, (msg) => this.processMessage(type, msg)); + this.subs[type] = sub; + } + } + } + processMessage(type, msg) { + if (this.isDone || !msg) { + return; + } + for (const name of this.specsNames) { + if (this.specs[name].types.indexOf(type) !== -1) { + const messages = this.messages[name] || []; + this.messages[name] = messages; + messages.push(msg); + } + } + } + drain(name, callback) { + if (callback) { + (this.messages[name] || []).forEach(callback); + } + delete this.messages[name]; + for (const type of this.specs[name].types) { + this.subsRefCount[type] -= 1; + if (this.subsRefCount[type] <= 0) { + this.connection?.off(this.subs[type]); + delete this.subs[type]; + delete this.subsRefCount[type]; + } + } + delete this.specs[name]; + if (!this.specs.length) { + this.isDone = true; + } + } + } + + let urlAlphabet$1 = + 'useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict'; + let nanoid$1 = (size = 21) => { + let id = ''; + let i = size; + while (i--) { + id += urlAlphabet$1[(Math.random() * 64) | 0]; + } + return id + }; + + const PromisePlus$1 = (executor, timeoutMilliseconds, timeoutMessage) => { + return new Promise((resolve, reject) => { + const timeout = setTimeout(() => { + const message = timeoutMessage || `Promise timeout hit: ${timeoutMilliseconds}`; + reject(message); + }, timeoutMilliseconds); + const providedPromise = new Promise(executor); + providedPromise + .then((result) => { + clearTimeout(timeout); + resolve(result); + }) + .catch((error) => { + clearTimeout(timeout); + reject(error); + }); + }); + }; + + class WebPlatformTransport { + settings; + logger; + identity; + isPreferredActivated; + _communicationId; + publicWindowId; + selfAssignedWindowId; + iAmConnected = false; + parentReady = false; + rejected = false; + parentPingResolve; + parentPingInterval; + connectionResolve; + extConnectionResolve; + extConnectionReject; + connectionReject; + port; + myClientId; + children = []; + extContentAvailable = false; + extContentConnecting = false; + extContentConnected = false; + parentWindowId; + parentInExtMode = false; + webNamespace = "g42_core_web"; + parent; + parentType; + parentPingTimeout = 5000; + connectionRequestTimeout = 7000; + defaultTargetString = "*"; + registry = CallbackRegistryFactory$1(); + messages = { + connectionAccepted: { name: "connectionAccepted", handle: this.handleConnectionAccepted.bind(this) }, + connectionRejected: { name: "connectionRejected", handle: this.handleConnectionRejected.bind(this) }, + connectionRequest: { name: "connectionRequest", handle: this.handleConnectionRequest.bind(this) }, + parentReady: { + name: "parentReady", handle: () => { + } + }, + parentPing: { name: "parentPing", handle: this.handleParentPing.bind(this) }, + platformPing: { name: "platformPing", handle: this.handlePlatformPing.bind(this) }, + platformReady: { name: "platformReady", handle: this.handlePlatformReady.bind(this) }, + clientUnload: { name: "clientUnload", handle: this.handleClientUnload.bind(this) }, + manualUnload: { name: "manualUnload", handle: this.handleManualUnload.bind(this) }, + extConnectionResponse: { name: "extConnectionResponse", handle: this.handleExtConnectionResponse.bind(this) }, + extSetupRequest: { name: "extSetupRequest", handle: this.handleExtSetupRequest.bind(this) }, + gatewayDisconnect: { name: "gatewayDisconnect", handle: this.handleGatewayDisconnect.bind(this) }, + gatewayInternalConnect: { name: "gatewayInternalConnect", handle: this.handleGatewayInternalConnect.bind(this) } + }; + constructor(settings, logger, identity) { + this.settings = settings; + this.logger = logger; + this.identity = identity; + this.extContentAvailable = !!window.glue42ext; + this.setUpMessageListener(); + this.setUpUnload(); + this.setupPlatformUnloadListener(); + this.parentType = window.name.includes("#wsp") ? "workspace" : undefined; + } + manualSetReadyState() { + this.iAmConnected = true; + this.parentReady = true; + } + get transportWindowId() { + return this.publicWindowId; + } + get communicationId() { + return this._communicationId; + } + async sendObject(msg) { + if (this.extContentConnected) { + return window.postMessage({ glue42ExtOut: msg }, this.defaultTargetString); + } + if (!this.port) { + throw new Error("Cannot send message, because the port was not opened yet"); + } + this.port.postMessage(msg); + } + get isObjectBasedTransport() { + return true; + } + onMessage(callback) { + return this.registry.add("onMessage", callback); + } + send() { + return Promise.reject("not supported"); + } + onConnectedChanged(callback) { + return this.registry.add("onConnectedChanged", callback); + } + async open() { + this.logger.debug("opening a connection to the web platform gateway."); + await this.connect(); + this.notifyStatusChanged(true); + } + close() { + const message = { + glue42core: { + type: this.messages.gatewayDisconnect.name, + data: { + clientId: this.myClientId, + ownWindowId: this.identity?.windowId + } + } + }; + this.port?.postMessage(message); + this.parentReady = false; + this.notifyStatusChanged(false, "manual reconnection"); + return Promise.resolve(); + } + name() { + return "web-platform"; + } + async reconnect() { + await this.close(); + return Promise.resolve(); + } + initiateInternalConnection() { + return new Promise((resolve, reject) => { + this.logger.debug("opening an internal web platform connection"); + this.port = this.settings.port; + if (this.iAmConnected) { + this.logger.warn("cannot open a new connection, because this client is currently connected"); + return; + } + this.port.onmessage = (event) => { + if (this.iAmConnected && !event.data?.glue42core) { + this.registry.execute("onMessage", event.data); + return; + } + const data = event.data?.glue42core; + if (!data) { + return; + } + if (data.type === this.messages.gatewayInternalConnect.name && data.success) { + this.publicWindowId = this.settings.windowId; + if (this.identity && this.publicWindowId) { + this.identity.windowId = this.publicWindowId; + this.identity.instance = this.publicWindowId; + } + resolve(); + } + if (data.type === this.messages.gatewayInternalConnect.name && data.error) { + reject(data.error); + } + }; + this.port.postMessage({ + glue42core: { + type: this.messages.gatewayInternalConnect.name + } + }); + }); + } + initiateRemoteConnection(target) { + return PromisePlus$1((resolve, reject) => { + this.connectionResolve = resolve; + this.connectionReject = reject; + this.myClientId = this.myClientId ?? nanoid$1(10); + const bridgeInstanceId = this.getMyWindowId() || nanoid$1(10); + const request = { + glue42core: { + type: this.messages.connectionRequest.name, + clientId: this.myClientId, + clientType: "child", + bridgeInstanceId, + selfAssignedWindowId: this.selfAssignedWindowId + } + }; + this.logger.debug("sending connection request"); + if (this.extContentConnecting) { + request.glue42core.clientType = "child"; + request.glue42core.bridgeInstanceId = this.myClientId; + request.glue42core.parentWindowId = this.parentWindowId; + return window.postMessage(request, this.defaultTargetString); + } + if (!target) { + throw new Error("Cannot send a connection request, because no glue target was specified!"); + } + target.postMessage(request, this.defaultTargetString); + }, this.connectionRequestTimeout, "The connection to the target glue window timed out"); + } + async isParentCheckSuccess(parentCheck) { + try { + await parentCheck; + return { success: true }; + } + catch (error) { + return { success: false }; + } + } + setUpMessageListener() { + if (this.settings.port) { + this.logger.debug("skipping generic message listener, because this is an internal client"); + return; + } + window.addEventListener("message", (event) => { + const data = event.data?.glue42core; + if (!data || this.rejected) { + return; + } + const allowedOrigins = this.settings.allowedOrigins || []; + if (allowedOrigins.length && !allowedOrigins.includes(event.origin)) { + this.logger.warn(`received a message from an origin which is not in the allowed list: ${event.origin}`); + return; + } + if (!this.checkMessageTypeValid(data.type)) { + this.logger.error(`cannot handle the incoming glue42 core message, because the type is invalid: ${data.type}`); + return; + } + const messageType = data.type; + this.logger.debug(`received valid glue42core message of type: ${messageType}`); + this.messages[messageType].handle(event); + }); + } + setUpUnload() { + if (this.settings.port) { + this.logger.debug("skipping unload event listener, because this is an internal client"); + return; + } + window.addEventListener("beforeunload", () => { + if (this.extContentConnected) { + return; + } + const message = { + glue42core: { + type: this.messages.clientUnload.name, + data: { + clientId: this.myClientId, + ownWindowId: this.identity?.windowId + } + } + }; + if (this.parent) { + this.parent.postMessage(message, this.defaultTargetString); + } + this.port?.postMessage(message); + }); + } + handlePlatformReady(event) { + this.logger.debug("the web platform gave the ready signal"); + this.parentReady = true; + if (this.parentPingResolve) { + this.parentPingResolve(); + delete this.parentPingResolve; + } + if (this.parentPingInterval) { + clearInterval(this.parentPingInterval); + delete this.parentPingInterval; + } + this.parent = event.source; + this.parentType = window.name.includes("#wsp") ? "workspace" : "window"; + } + handleConnectionAccepted(event) { + const data = event.data?.glue42core; + if (this.myClientId === data.clientId) { + return this.handleAcceptanceOfMyRequest(data); + } + return this.handleAcceptanceOfGrandChildRequest(data, event); + } + handleAcceptanceOfMyRequest(data) { + this.logger.debug("handling a connection accepted signal targeted at me."); + this.isPreferredActivated = data.isPreferredActivated; + if (this.extContentConnecting) { + return this.processExtContentConnection(data); + } + if (!data.port) { + this.logger.error("cannot set up my connection, because I was not provided with a port"); + return; + } + this.publicWindowId = this.getMyWindowId(); + if (this.identity) { + this.identity.windowId = this.publicWindowId; + this.identity.instance = this.identity.instance ? this.identity.instance : this.publicWindowId || nanoid$1(10); + } + if (this.identity && data.appName) { + this.identity.application = data.appName; + this.identity.applicationName = data.appName; + } + this._communicationId = data.communicationId; + this.port = data.port; + this.port.onmessage = (e) => this.registry.execute("onMessage", e.data); + if (this.connectionResolve) { + this.logger.debug("my connection is set up, calling the connection resolve."); + this.connectionResolve(); + delete this.connectionResolve; + return; + } + this.logger.error("unable to call the connection resolve, because no connection promise was found"); + } + processExtContentConnection(data) { + this.logger.debug("handling a connection accepted signal targeted at me for extension content connection."); + this.extContentConnecting = false; + this.extContentConnected = true; + this.publicWindowId = this.parentWindowId || this.myClientId; + if (this.extContentConnecting && this.identity) { + this.identity.windowId = this.publicWindowId; + } + if (this.identity && data.appName) { + this.identity.application = data.appName; + this.identity.applicationName = data.appName; + } + window.addEventListener("message", (event) => { + const extData = event.data?.glue42ExtInc; + if (!extData) { + return; + } + const allowedOrigins = this.settings.allowedOrigins || []; + if (allowedOrigins.length && !allowedOrigins.includes(event.origin)) { + this.logger.warn(`received a message from an origin which is not in the allowed list: ${event.origin}`); + return; + } + this.registry.execute("onMessage", extData); + }); + if (this.connectionResolve) { + this.logger.debug("my connection is set up, calling the connection resolve."); + this.connectionResolve(); + delete this.connectionResolve; + return; + } + } + handleAcceptanceOfGrandChildRequest(data, event) { + if (this.extContentConnecting || this.extContentConnected) { + this.logger.debug("cannot process acceptance of a grandchild, because I am connected to a content script"); + return; + } + this.logger.debug(`handling a connection accepted signal targeted at a grandchild: ${data.clientId}`); + const child = this.children.find((c) => c.grandChildId === data.clientId); + if (!child) { + this.logger.error(`cannot handle connection accepted for grandchild: ${data.clientId}, because there is no grandchild with this id`); + return; + } + child.connected = true; + this.logger.debug(`the grandchild connection for ${data.clientId} is set up, forwarding the success message and the gateway port`); + data.parentWindowId = this.publicWindowId; + child.source.postMessage(event.data, child.origin, [data.port]); + return; + } + handleConnectionRejected(event) { + this.logger.debug("handling a connection rejection. Most likely the reason is that this window was not created by a glue API call"); + if (!this.connectionReject) { + return; + } + const errorMsg = typeof event.data.glue42core?.error === "string" + ? `Connection was rejected. ${event.data.glue42core?.error}` + : "The platform connection was rejected. Most likely because this window was not created by a glue API call"; + this.connectionReject(errorMsg); + delete this.connectionReject; + } + handleConnectionRequest(event) { + if (this.extContentConnecting) { + this.logger.debug("This connection request event is targeted at the extension content"); + return; + } + const source = event.source; + const data = event.data.glue42core; + if (!data.clientType || data.clientType !== "grandChild") { + return this.rejectConnectionRequest(source, event.origin, "rejecting a connection request, because the source was not opened by a glue API call"); + } + if (!data.clientId) { + return this.rejectConnectionRequest(source, event.origin, "rejecting a connection request, because the source did not provide a valid id"); + } + if (!this.parent) { + return this.rejectConnectionRequest(source, event.origin, "Cannot forward the connection request, because no direct connection to the platform was found"); + } + this.logger.debug(`handling a connection request for a grandchild: ${data.clientId}`); + this.children.push({ grandChildId: data.clientId, source, connected: false, origin: event.origin }); + this.logger.debug(`grandchild: ${data.clientId} is prepared, forwarding connection request to the platform`); + this.parent.postMessage(event.data, this.defaultTargetString); + } + handleParentPing(event) { + if (!this.parentReady) { + this.logger.debug("my parent is not ready, I am ignoring the parent ping"); + return; + } + if (!this.iAmConnected) { + this.logger.debug("i am not fully connected yet, I am ignoring the parent ping"); + return; + } + const message = { + glue42core: { + type: this.messages.parentReady.name + } + }; + if (this.extContentConnected) { + message.glue42core.extMode = { windowId: this.myClientId }; + } + const source = event.source; + this.logger.debug("responding to a parent ping with a ready message"); + source.postMessage(message, event.origin); + } + setupPlatformUnloadListener() { + this.onMessage((msg) => { + if (msg.type === "platformUnload") { + this.logger.debug("detected a web platform unload"); + this.parentReady = false; + this.notifyStatusChanged(false, "Gateway unloaded"); + } + }); + } + handleManualUnload() { + const message = { + glue42core: { + type: this.messages.clientUnload.name, + data: { + clientId: this.myClientId, + ownWindowId: this.identity?.windowId + } + } + }; + if (this.extContentConnected) { + return window.postMessage({ glue42ExtOut: message }, this.defaultTargetString); + } + this.port?.postMessage(message); + } + handleClientUnload(event) { + const data = event.data.glue42core; + const clientId = data?.data.clientId; + if (!clientId) { + this.logger.warn("cannot process grand child unload, because the provided id was not valid"); + return; + } + const foundChild = this.children.find((child) => child.grandChildId === clientId); + if (!foundChild) { + this.logger.warn("cannot process grand child unload, because this client is unaware of this grandchild"); + return; + } + this.logger.debug(`handling grandchild unload for id: ${clientId}`); + this.children = this.children.filter((child) => child.grandChildId !== clientId); + } + handlePlatformPing() { + return; + } + notifyStatusChanged(status, reason) { + this.iAmConnected = status; + this.registry.execute("onConnectedChanged", status, reason); + } + checkMessageTypeValid(typeToValidate) { + return typeof typeToValidate === "string" && !!this.messages[typeToValidate]; + } + rejectConnectionRequest(source, origin, reason) { + this.rejected = true; + this.logger.error(reason); + const rejection = { + glue42core: { + type: this.messages.connectionRejected.name + } + }; + source.postMessage(rejection, origin); + } + requestConnectionPermissionFromExt() { + return this.waitForContentScript() + .then(() => PromisePlus$1((resolve, reject) => { + this.extConnectionResolve = resolve; + this.extConnectionReject = reject; + const message = { + glue42core: { + type: "extSetupRequest" + } + }; + this.logger.debug("permission request to the extension content script was sent"); + window.postMessage(message, this.defaultTargetString); + }, this.parentPingTimeout, "Cannot initialize glue, because this app was not opened or created by a Glue Client and the request for extension connection timed out")); + } + handleExtConnectionResponse(event) { + const data = event.data?.glue42core; + if (!data.approved) { + return this.extConnectionReject ? this.extConnectionReject("Cannot initialize glue, because this app was not opened or created by a Glue Client and the request for extension connection was rejected") : undefined; + } + if (this.extConnectionResolve) { + this.extConnectionResolve(); + delete this.extConnectionResolve; + } + this.extContentConnecting = true; + this.parentType = "extension"; + this.logger.debug("The extension connection was approved, proceeding."); + } + handleExtSetupRequest() { + return; + } + handleGatewayDisconnect() { + return; + } + handleGatewayInternalConnect() { + return; + } + waitForContentScript() { + const contentReady = !!window.glue42ext?.content; + if (contentReady) { + return Promise.resolve(); + } + return PromisePlus$1((resolve) => { + window.addEventListener("Glue42EXTReady", () => { + resolve(); + }); + }, this.connectionRequestTimeout, "The content script was available, but was never heard to be ready"); + } + async connect() { + if (this.settings.port) { + await this.initiateInternalConnection(); + this.logger.debug("internal web platform connection completed"); + return; + } + this.logger.debug("opening a client web platform connection"); + await this.findParent(); + await this.initiateRemoteConnection(this.parent); + this.logger.debug("the client is connected"); + } + async findParent() { + const connectionNotPossibleMsg = "Cannot initiate glue, because this window was not opened or created by a glue client"; + const myInsideParents = this.getPossibleParentsInWindow(window); + const myOutsideParents = this.getPossibleParentsOutsideWindow(window.top?.opener, window.top); + const uniqueParents = new Set([...myInsideParents, ...myOutsideParents]); + if (!uniqueParents.size && !this.extContentAvailable) { + throw new Error(connectionNotPossibleMsg); + } + if (!uniqueParents.size && this.extContentAvailable) { + await this.requestConnectionPermissionFromExt(); + return; + } + const defaultParentCheck = await this.isParentCheckSuccess(this.confirmParent(Array.from(uniqueParents))); + if (defaultParentCheck.success) { + this.logger.debug("The default parent was found!"); + return; + } + if (!this.extContentAvailable) { + throw new Error(connectionNotPossibleMsg); + } + await this.requestConnectionPermissionFromExt(); + } + getPossibleParentsInWindow(currentWindow) { + return (!currentWindow?.parent || currentWindow === currentWindow.parent) ? [] : [currentWindow.parent, ...this.getPossibleParentsInWindow(currentWindow.parent)]; + } + getPossibleParentsOutsideWindow(opener, current) { + return (!opener || !current || opener === current) ? [] : [opener, ...this.getPossibleParentsInWindow(opener), ...this.getPossibleParentsOutsideWindow(opener.opener, opener)]; + } + confirmParent(targets) { + const connectionNotPossibleMsg = "Cannot initiate glue, because this window was not opened or created by a glue client"; + const parentCheck = PromisePlus$1((resolve) => { + this.parentPingResolve = resolve; + const message = { + glue42core: { + type: this.messages.platformPing.name + } + }; + this.parentPingInterval = setInterval(() => { + targets.forEach((target) => { + target.postMessage(message, this.defaultTargetString); + }); + }, 1000); + }, this.parentPingTimeout, connectionNotPossibleMsg); + parentCheck.catch(() => { + if (this.parentPingInterval) { + clearInterval(this.parentPingInterval); + delete this.parentPingInterval; + } + }); + return parentCheck; + } + getMyWindowId() { + if (this.parentType === "workspace") { + return window.name.substring(0, window.name.indexOf("#wsp")); + } + if (window !== window.top) { + return; + } + if (window.name?.includes("g42")) { + return window.name; + } + this.selfAssignedWindowId = this.selfAssignedWindowId || `g42-${nanoid$1(10)}`; + return this.selfAssignedWindowId; + } + } + + const waitForInvocations = (invocations, callback) => { + let left = invocations; + return () => { + left--; + if (left === 0) { + callback(); + } + }; + }; + + class AsyncSequelizer { + minSequenceInterval; + queue = []; + isExecutingQueue = false; + constructor(minSequenceInterval = 0) { + this.minSequenceInterval = minSequenceInterval; + } + enqueue(action) { + return new Promise((resolve, reject) => { + this.queue.push({ action, resolve, reject }); + this.executeQueue(); + }); + } + async executeQueue() { + if (this.isExecutingQueue) { + return; + } + this.isExecutingQueue = true; + while (this.queue.length) { + const operation = this.queue.shift(); + if (!operation) { + this.isExecutingQueue = false; + return; + } + try { + const actionResult = await operation.action(); + operation.resolve(actionResult); + } + catch (error) { + operation.reject(error); + } + await this.intervalBreak(); + } + this.isExecutingQueue = false; + } + intervalBreak() { + return new Promise((res) => setTimeout(res, this.minSequenceInterval)); + } + } + + function domainSession (domain, connection, logger, successMessages, errorMessages) { + if (domain == null) { + domain = "global"; + } + successMessages = successMessages ?? ["success"]; + errorMessages = errorMessages ?? ["error"]; + let isJoined = domain === "global"; + let tryReconnecting = false; + let _latestOptions; + let _connectionOn = false; + const callbacks = CallbackRegistryFactory$1(); + connection.disconnected(handleConnectionDisconnected); + connection.loggedIn(handleConnectionLoggedIn); + connection.on("success", (msg) => handleSuccessMessage(msg)); + connection.on("error", (msg) => handleErrorMessage(msg)); + connection.on("result", (msg) => handleSuccessMessage(msg)); + if (successMessages) { + successMessages.forEach((sm) => { + connection.on(sm, (msg) => handleSuccessMessage(msg)); + }); + } + if (errorMessages) { + errorMessages.forEach((sm) => { + connection.on(sm, (msg) => handleErrorMessage(msg)); + }); + } + const requestsMap = {}; + function join(options) { + _latestOptions = options; + return new Promise((resolve, reject) => { + if (isJoined) { + resolve({}); + return; + } + let joinPromise; + if (domain === "global") { + joinPromise = _connectionOn ? Promise.resolve({}) : Promise.reject("not connected to gateway"); + } + else { + logger.debug(`joining domain ${domain}`); + const joinMsg = { + type: "join", + destination: domain, + domain: "global", + options, + }; + joinPromise = send(joinMsg); + } + joinPromise + .then(() => { + handleJoined(); + resolve({}); + }) + .catch((err) => { + logger.debug("error joining " + domain + " domain: " + JSON.stringify(err)); + reject(err); + }); + }); + } + function leave() { + if (domain === "global") { + return Promise.resolve(); + } + logger.debug("stopping session " + domain + "..."); + const leaveMsg = { + type: "leave", + destination: domain, + domain: "global", + }; + tryReconnecting = false; + return send(leaveMsg) + .then(() => { + isJoined = false; + callbacks.execute("onLeft"); + }) + .catch(() => { + isJoined = false; + callbacks.execute("onLeft"); + }); + } + function handleJoined() { + logger.debug("did join " + domain); + isJoined = true; + const wasReconnect = tryReconnecting; + tryReconnecting = false; + callbacks.execute("onJoined", wasReconnect); + } + function handleConnectionDisconnected() { + _connectionOn = false; + logger.debug("connection is down"); + isJoined = false; + tryReconnecting = true; + callbacks.execute("onLeft", { disconnected: true }); + } + function handleConnectionLoggedIn() { + _connectionOn = true; + if (tryReconnecting) { + logger.debug("connection is now up - trying to reconnect..."); + join(_latestOptions); + } + } + function onJoined(callback) { + if (isJoined) { + callback(false); + } + return callbacks.add("onJoined", callback); + } + function onLeft(callback) { + if (!isJoined) { + callback(); + } + return callbacks.add("onLeft", callback); + } + function handleErrorMessage(msg) { + if (domain !== msg.domain) { + return; + } + const requestId = msg.request_id; + if (!requestId) { + return; + } + const entry = requestsMap[requestId]; + if (!entry) { + return; + } + entry.error(msg); + } + function handleSuccessMessage(msg) { + if (msg.domain !== domain) { + return; + } + const requestId = msg.request_id; + if (!requestId) { + return; + } + const entry = requestsMap[requestId]; + if (!entry) { + return; + } + entry.success(msg); + } + function getNextRequestId() { + return nanoid$1(10); + } + let queuedCalls = []; + function send(msg, tag, options) { + const ignore = ["hello", "join"]; + if (msg.type && ignore.indexOf(msg.type) === -1) { + if (!isJoined) { + console.warn(`trying to send a message (${msg.domain} ${msg.type}) but not connected, will queue`); + const pw = new PromiseWrapper$1(); + queuedCalls.push({ msg, tag, options, pw }); + if (queuedCalls.length === 1) { + const unsubscribe = onJoined(() => { + logger.info(`joined - will now send queued messages (${queuedCalls.length} -> [${queuedCalls.map((m) => m.msg.type)}])`); + queuedCalls.forEach((qm) => { + send(qm.msg, qm.tag, qm.options) + .then((t) => qm.pw.resolve(t)) + .catch((e) => qm.pw.reject(e)); + }); + queuedCalls = []; + unsubscribe(); + }); + } + return pw.promise; + } + } + options = options ?? {}; + msg.request_id = msg.request_id ?? getNextRequestId(); + msg.domain = msg.domain ?? domain; + if (!options.skipPeerId) { + msg.peer_id = connection.peerId; + } + const requestId = msg.request_id; + return new Promise((resolve, reject) => { + requestsMap[requestId] = { + success: (successMsg) => { + delete requestsMap[requestId]; + successMsg._tag = tag; + resolve(successMsg); + }, + error: (errorMsg) => { + logger.warn(`Gateway error - ${JSON.stringify(errorMsg)}`); + delete requestsMap[requestId]; + errorMsg._tag = tag; + reject(errorMsg); + }, + }; + connection + .send(msg, options) + .catch((err) => { + requestsMap[requestId].error({ err }); + }); + }); + } + function sendFireAndForget(msg) { + msg.request_id = msg.request_id ? msg.request_id : getNextRequestId(); + msg.domain = msg.domain ?? domain; + msg.peer_id = connection.peerId; + return connection.send(msg); + } + return { + join, + leave, + onJoined, + onLeft, + send, + sendFireAndForget, + on: (type, callback) => { + connection.on(type, (msg) => { + if (msg.domain !== domain) { + return; + } + try { + callback(msg); + } + catch (e) { + logger.error(`Callback failed: ${e} \n ${e.stack} \n msg was: ${JSON.stringify(msg)}`, e); + } + }); + }, + loggedIn: (callback) => connection.loggedIn(callback), + connected: (callback) => connection.connected(callback), + disconnected: (callback) => connection.disconnected(callback), + get peerId() { + return connection.peerId; + }, + get domain() { + return domain; + }, + }; + } + + class Connection { + settings; + logger; + protocolVersion = 3; + peerId; + token; + info; + resolvedIdentity; + availableDomains; + gatewayToken; + replayer; + messageHandlers = {}; + ids = 1; + registry = CallbackRegistryFactory$1(); + _connected = false; + isTrace = false; + transport; + _defaultTransport; + _defaultAuth; + _targetTransport; + _targetAuth; + _swapTransport = false; + _switchInProgress = false; + _transportSubscriptions = []; + datePrefix = "#T42_DATE#"; + datePrefixLen = this.datePrefix.length; + dateMinLen = this.datePrefixLen + 1; + datePrefixFirstChar = this.datePrefix[0]; + _sequelizer = new AsyncSequelizer(); + _isLoggedIn = false; + shouldTryLogin = true; + pingTimer; + sessions = []; + globalDomain; + initialLogin = true; + initialLoginAttempts = 3; + loginConfig; + constructor(settings, logger) { + this.settings = settings; + this.logger = logger; + settings = settings || {}; + settings.reconnectAttempts = settings.reconnectAttempts ?? 10; + settings.reconnectInterval = settings.reconnectInterval ?? 1000; + if (settings.inproc) { + this.transport = new InProcTransport(settings.inproc, logger.subLogger("inMemory")); + } + else if (settings.sharedWorker) { + this.transport = new SharedWorkerTransport(settings.sharedWorker, logger.subLogger("shared-worker")); + } + else if (settings.webPlatform) { + this.transport = new WebPlatformTransport(settings.webPlatform, logger.subLogger("web-platform"), settings.identity); + } + else if (settings.ws !== undefined) { + this.transport = new WS(settings, logger.subLogger("ws")); + } + else { + throw new Error("No connection information specified"); + } + this.isTrace = logger.canPublish("trace"); + logger.debug(`starting with ${this.transport.name()} transport`); + const unsubConnectionChanged = this.transport.onConnectedChanged(this.handleConnectionChanged.bind(this)); + const unsubOnMessage = this.transport.onMessage(this.handleTransportMessage.bind(this)); + this._transportSubscriptions.push(unsubConnectionChanged); + this._transportSubscriptions.push(unsubOnMessage); + this._defaultTransport = this.transport; + this.ping(); + } + async switchTransport(settings) { + return this._sequelizer.enqueue(async () => { + if (!settings || typeof settings !== "object") { + throw new Error("Cannot switch transports, because the settings are missing or invalid."); + } + if (typeof settings.type === "undefined") { + throw new Error("Cannot switch the transport, because the type is not defined"); + } + this.logger.trace(`Starting transport switch with settings: ${JSON.stringify(settings)}`); + const switchTargetTransport = settings.type === "secondary" ? this.getNewSecondaryTransport(settings) : this._defaultTransport; + this._targetTransport = switchTargetTransport; + this._targetAuth = settings.type === "secondary" ? this.getNewSecondaryAuth(settings) : this._defaultAuth; + const verifyPromise = this.verifyConnection(); + this._swapTransport = true; + this._switchInProgress = true; + this.logger.trace("The new transport has been set, closing the current transport"); + await this.transport.close(); + try { + await verifyPromise; + const isSwitchSuccess = this.transport === switchTargetTransport; + this.logger.info(`The reconnection after the switch was completed. Was the switch a success: ${isSwitchSuccess}`); + this._switchInProgress = false; + return { success: isSwitchSuccess }; + } + catch (error) { + this.logger.info("The reconnection after the switch timed out, reverting back to the default transport."); + this.switchTransport({ type: "default" }); + this._switchInProgress = false; + return { success: false }; + } + }); + } + onLibReAnnounced(callback) { + return this.registry.add("libReAnnounced", callback); + } + setLibReAnnounced(lib) { + this.registry.execute("libReAnnounced", lib); + } + send(message, options) { + if (this.transport.sendObject && + this.transport.isObjectBasedTransport) { + const msg = this.createObjectMessage(message); + if (this.isTrace) { + this.logger.trace(`>> ${JSON.stringify(msg)}`); + } + return this.transport.sendObject(msg, options); + } + else { + const strMessage = this.createStringMessage(message); + if (this.isTrace) { + this.logger.trace(`>> ${strMessage}`); + } + return this.transport.send(strMessage, options); + } + } + on(type, messageHandler) { + type = type.toLowerCase(); + if (this.messageHandlers[type] === undefined) { + this.messageHandlers[type] = {}; + } + const id = this.ids++; + this.messageHandlers[type][id] = messageHandler; + return { + type, + id, + }; + } + off(info) { + delete this.messageHandlers[info.type.toLowerCase()][info.id]; + } + get isConnected() { + return this._isLoggedIn; + } + connected(callback) { + return this.loggedIn(() => { + const currentServer = this.transport.name(); + callback(currentServer); + }); + } + disconnected(callback) { + return this.registry.add("disconnected", callback); + } + async login(authRequest, reconnect) { + if (!this._defaultAuth) { + this._defaultAuth = authRequest; + } + if (this._swapTransport) { + this.logger.trace("Detected a transport swap, swapping transports"); + const newAuth = this.transportSwap(); + authRequest = newAuth ?? authRequest; + } + this.logger.trace(`Starting login for transport: ${this.transport.name()} and auth ${JSON.stringify(authRequest)}`); + try { + await this.transport.open(); + this.logger.trace(`Transport: ${this.transport.name()} opened, logging in`); + timer("connection").mark("transport-opened"); + const identity = await this.loginCore(authRequest, reconnect); + this.logger.trace(`Logged in with identity: ${JSON.stringify(identity)}`); + timer("connection").mark("protocol-logged-in"); + return identity; + } + catch (error) { + if (this._switchInProgress) { + this.logger.trace("An error while logging in after a transport swap, preparing a default swap."); + this.prepareDefaultSwap(); + } + throw new Error(error); + } + } + async logout() { + await this.logoutCore(); + await this.transport.close(); + } + loggedIn(callback) { + if (this._isLoggedIn) { + callback(); + } + return this.registry.add("onLoggedIn", callback); + } + domain(domain, successMessages, errorMessages) { + let session = this.sessions.find((s) => s.domain === domain); + if (!session) { + session = domainSession(domain, this, this.logger.subLogger(`domain=${domain}`), successMessages, errorMessages); + this.sessions.push(session); + } + return session; + } + authToken() { + const createTokenReq = { + domain: "global", + type: "create-token" + }; + if (!this.globalDomain) { + return Promise.reject(new Error("no global domain session")); + } + return this.globalDomain.send(createTokenReq) + .then((res) => { + return res.token; + }); + } + reconnect() { + return this.transport.reconnect(); + } + setLoggedIn(value) { + this._isLoggedIn = value; + if (this._isLoggedIn) { + this.registry.execute("onLoggedIn"); + } + } + distributeMessage(message, type) { + const handlers = this.messageHandlers[type.toLowerCase()]; + if (handlers !== undefined) { + Object.keys(handlers).forEach((handlerId) => { + const handler = handlers[handlerId]; + if (handler !== undefined) { + try { + handler(message); + } + catch (error) { + try { + this.logger.error(`Message handler failed with ${error.stack}`, error); + } + catch (loggerError) { + console.log("Message handler failed", error); + } + } + } + }); + } + } + handleConnectionChanged(connected) { + if (this._connected === connected) { + return; + } + this._connected = connected; + if (connected) { + if (this.settings?.replaySpecs?.length) { + this.replayer = new MessageReplayerImpl(this.settings.replaySpecs); + this.replayer.init(this); + } + this.registry.execute("connected"); + } + else { + this.handleDisconnected(); + this.registry.execute("disconnected"); + } + } + handleDisconnected() { + this.setLoggedIn(false); + const tryToLogin = this.shouldTryLogin; + if (tryToLogin && this.initialLogin) { + if (this.initialLoginAttempts <= 0) { + return; + } + this.initialLoginAttempts--; + } + this.logger.debug("disconnected - will try new login?" + this.shouldTryLogin); + if (this.shouldTryLogin) { + if (!this.loginConfig) { + throw new Error("no login info"); + } + this.login(this.loginConfig, true) + .catch(() => { + setTimeout(this.handleDisconnected.bind(this), this.settings.reconnectInterval || 1000); + }); + } + } + handleTransportMessage(msg) { + let msgObj; + if (typeof msg === "string") { + msgObj = this.processStringMessage(msg); + } + else { + msgObj = this.processObjectMessage(msg); + } + if (this.isTrace) { + this.logger.trace(`<< ${JSON.stringify(msgObj)}`); + } + this.distributeMessage(msgObj.msg, msgObj.msgType); + } + verifyConnection() { + return PromisePlus$1((resolve) => { + let unsub; + const ready = waitForInvocations(2, () => { + if (unsub) { + unsub(); + } + resolve(); + }); + unsub = this.onLibReAnnounced((lib) => { + if (lib.name === "interop") { + return ready(); + } + if (lib.name === "contexts") { + return ready(); + } + }); + }, 10000, "Transport switch timed out waiting for all libraries to be re-announced"); + } + getNewSecondaryTransport(settings) { + if (!settings.transportConfig?.url) { + throw new Error("Missing secondary transport URL."); + } + return new WS(Object.assign({}, this.settings, { ws: settings.transportConfig.url, reconnectAttempts: 1 }), this.logger.subLogger("ws-secondary")); + } + getNewSecondaryAuth(settings) { + if (!settings.transportConfig?.auth) { + throw new Error("Missing secondary transport auth information."); + } + return settings.transportConfig.auth; + } + transportSwap() { + this._swapTransport = false; + if (!this._targetTransport || !this._targetAuth) { + this.logger.warn(`Error while switching transports - either the target transport or auth is not defined: transport defined -> ${!!this._defaultTransport}, auth defined -> ${!!this._targetAuth}. Staying on the current one.`); + return; + } + this._transportSubscriptions.forEach((unsub) => unsub()); + this._transportSubscriptions = []; + this.transport = this._targetTransport; + const unsubConnectionChanged = this.transport.onConnectedChanged(this.handleConnectionChanged.bind(this)); + const unsubOnMessage = this.transport.onMessage(this.handleTransportMessage.bind(this)); + this._transportSubscriptions.push(unsubConnectionChanged); + this._transportSubscriptions.push(unsubOnMessage); + return this._targetAuth; + } + prepareDefaultSwap() { + this._transportSubscriptions.forEach((unsub) => unsub()); + this._transportSubscriptions = []; + this.transport.close().catch((error) => this.logger.warn(`Error closing the ${this.transport.name()} transport after a failed connection attempt: ${JSON.stringify(error)}`)); + this._targetTransport = this._defaultTransport; + this._targetAuth = this._defaultAuth; + this._swapTransport = true; + } + processStringMessage(message) { + const msg = JSON.parse(message, (key, value) => { + if (typeof value !== "string") { + return value; + } + if (value.length < this.dateMinLen) { + return value; + } + if (!value.startsWith(this.datePrefixFirstChar)) { + return value; + } + if (value.substring(0, this.datePrefixLen) !== this.datePrefix) { + return value; + } + try { + const milliseconds = parseInt(value.substring(this.datePrefixLen, value.length), 10); + if (isNaN(milliseconds)) { + return value; + } + return new Date(milliseconds); + } + catch (ex) { + return value; + } + }); + return { + msg, + msgType: msg.type, + }; + } + createStringMessage(message) { + const oldToJson = Date.prototype.toJSON; + try { + const datePrefix = this.datePrefix; + Date.prototype.toJSON = function () { + return datePrefix + this.getTime(); + }; + const result = JSON.stringify(message); + return result; + } + finally { + Date.prototype.toJSON = oldToJson; + } + } + processObjectMessage(message) { + if (!message.type) { + throw new Error("Object should have type property"); + } + return { + msg: message, + msgType: message.type, + }; + } + createObjectMessage(message) { + return message; + } + async loginCore(config, reconnect) { + this.logger.info("logging in..."); + this.loginConfig = config; + if (!this.loginConfig) { + this.loginConfig = { username: "", password: "" }; + } + this.shouldTryLogin = true; + const authentication = await this.setupAuthConfig(config, reconnect); + const helloMsg = { + type: "hello", + identity: this.settings.identity, + authentication + }; + if (config.sessionId) { + helloMsg.request_id = config.sessionId; + } + this.globalDomain = domainSession("global", this, this.logger.subLogger("global-domain"), [ + "welcome", + "token", + "authentication-request" + ]); + const sendOptions = { skipPeerId: true }; + if (this.initialLogin) { + sendOptions.retryInterval = this.settings.reconnectInterval; + sendOptions.maxRetries = this.settings.reconnectAttempts; + } + try { + const welcomeMsg = await this.tryAuthenticate(this.globalDomain, helloMsg, sendOptions, config); + this.initialLogin = false; + this.logger.info("login successful with peerId " + welcomeMsg.peer_id); + this.peerId = welcomeMsg.peer_id; + this.resolvedIdentity = welcomeMsg.resolved_identity; + this.availableDomains = welcomeMsg.available_domains; + if (welcomeMsg.options) { + this.token = welcomeMsg.options.access_token; + this.info = welcomeMsg.options.info; + } + this.setLoggedIn(true); + return welcomeMsg.resolved_identity; + } + catch (err) { + this.logger.error("error sending hello message - " + (err.message || err.msg || err.reason || err), err); + throw err; + } + finally { + if (config?.flowCallback && config.sessionId) { + config.flowCallback(config.sessionId, null); + } + } + } + async tryAuthenticate(globalDomain, helloMsg, sendOptions, config) { + let welcomeMsg; + while (true) { + const msg = await globalDomain.send(helloMsg, undefined, sendOptions); + if (msg.type === "authentication-request") { + const token = Buffer.from(msg.authentication.token, "base64"); + if (config.flowCallback && config.sessionId) { + helloMsg.authentication.token = + (await config.flowCallback(config.sessionId, token)) + .data + .toString("base64"); + } + helloMsg.request_id = config.sessionId; + } + else if (msg.type === "welcome") { + welcomeMsg = msg; + break; + } + else if (msg.type === "error") { + throw new Error("Authentication failed: " + msg.reason); + } + else { + throw new Error("Unexpected message type during authentication: " + msg.type); + } + } + return welcomeMsg; + } + async setupAuthConfig(config, reconnect) { + const authentication = {}; + this.gatewayToken = config.gatewayToken; + if (config.gatewayToken) { + if (reconnect) { + try { + config.gatewayToken = await this.getNewGWToken(); + } + catch (e) { + this.logger.warn(`failed to get GW token when reconnecting ${e?.message || e}`); + } + } + authentication.method = "gateway-token"; + authentication.token = config.gatewayToken; + this.gatewayToken = config.gatewayToken; + } + else if (config.flowName === "sspi") { + authentication.provider = "win"; + authentication.method = "access-token"; + if (config.flowCallback && config.sessionId) { + authentication.token = + (await config.flowCallback(config.sessionId, null)) + .data + .toString("base64"); + } + else { + throw new Error("Invalid SSPI config"); + } + } + else if (config.token) { + authentication.method = "access-token"; + authentication.token = config.token; + } + else if (config.username) { + authentication.method = "secret"; + authentication.login = config.username; + authentication.secret = config.password; + } + else if (config.provider) { + authentication.provider = config.provider; + authentication.providerContext = config.providerContext; + } + else { + throw new Error("invalid auth message" + JSON.stringify(config)); + } + return authentication; + } + async logoutCore() { + this.logger.debug("logging out..."); + this.shouldTryLogin = false; + if (this.pingTimer) { + clearTimeout(this.pingTimer); + } + const promises = this.sessions.map((session) => { + session.leave(); + }); + await Promise.all(promises); + } + getNewGWToken() { + if (typeof window !== "undefined") { + const glue42gd = window.glue42gd; + if (glue42gd) { + return glue42gd.getGWToken(); + } + } + return Promise.reject(new Error("not running in GD")); + } + ping() { + if (!this.shouldTryLogin) { + return; + } + if (this._isLoggedIn) { + this.send({ type: "ping" }); + } + this.pingTimer = setTimeout(() => { + this.ping(); + }, 30 * 1000); + } + } + + const order = ["trace", "debug", "info", "warn", "error", "off"]; + let Logger$1 = class Logger { + name; + parent; + static Interop; + static InteropMethodName = "T42.AppLogger.Log"; + static Instance; + path; + subLoggers = []; + _consoleLevel; + _publishLevel; + loggerFullName; + includeTimeAndLevel; + logFn = console; + customLogFn = false; + constructor(name, parent, logFn) { + this.name = name; + this.parent = parent; + this.name = name; + if (parent) { + this.path = `${parent.path}.${name}`; + } + else { + this.path = name; + } + this.loggerFullName = `[${this.path}]`; + this.includeTimeAndLevel = !logFn; + if (logFn) { + this.logFn = logFn; + this.customLogFn = true; + } + } + subLogger(name) { + const existingSub = this.subLoggers.filter((subLogger) => { + return subLogger.name === name; + })[0]; + if (existingSub !== undefined) { + return existingSub; + } + Object.keys(this).forEach((key) => { + if (key === name) { + throw new Error("This sub logger name is not allowed."); + } + }); + const sub = new Logger(name, this, this.customLogFn ? this.logFn : undefined); + this.subLoggers.push(sub); + return sub; + } + publishLevel(level) { + if (level) { + this._publishLevel = level; + } + return this._publishLevel || this.parent?.publishLevel(); + } + consoleLevel(level) { + if (level) { + this._consoleLevel = level; + } + return this._consoleLevel || this.parent?.consoleLevel(); + } + log(message, level, error) { + this.publishMessage(level || "info", message, error); + } + trace(message) { + this.log(message, "trace"); + } + debug(message) { + this.log(message, "debug"); + } + info(message) { + this.log(message, "info"); + } + warn(message) { + this.log(message, "warn"); + } + error(message, err) { + this.log(message, "error", err); + } + canPublish(level, compareWith) { + const levelIdx = order.indexOf(level); + const restrictionIdx = order.indexOf(compareWith || this.consoleLevel() || "trace"); + return levelIdx >= restrictionIdx; + } + publishMessage(level, message, error) { + const loggerName = this.loggerFullName; + if (level === "error" && !error) { + const e = new Error(); + if (e.stack) { + message = + message + + "\n" + + e.stack + .split("\n") + .slice(4) + .join("\n"); + } + } + if (this.canPublish(level, this.publishLevel())) { + const interop = Logger.Interop; + if (interop) { + try { + if (interop.methods({ name: Logger.InteropMethodName }).length > 0) { + const args = { + msg: message, + logger: loggerName, + level + }; + if (error && error instanceof Error) { + args.error = { + message: error.message, + stack: error.stack ?? "" + }; + } + interop.invoke(Logger.InteropMethodName, args); + } + } + catch { + } + } + } + if (this.canPublish(level)) { + let prefix = ""; + if (this.includeTimeAndLevel) { + const date = new Date(); + const time = `${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}:${date.getMilliseconds()}`; + prefix = `[${time}] [${level}] `; + } + const toPrint = `${prefix}${loggerName}: ${message}`; + switch (level) { + case "trace": + this.logFn.debug(toPrint); + break; + case "debug": + if (this.logFn.debug) { + this.logFn.debug(toPrint); + } + else { + this.logFn.log(toPrint); + } + break; + case "info": + this.logFn.info(toPrint); + break; + case "warn": + this.logFn.warn(toPrint); + break; + case "error": + this.logFn.error(toPrint, error); + break; + } + } + } + }; + + const GW_MESSAGE_CREATE_CONTEXT = "create-context"; + const GW_MESSAGE_ACTIVITY_CREATED = "created"; + const GW_MESSAGE_ACTIVITY_DESTROYED = "destroyed"; + const GW_MESSAGE_CONTEXT_CREATED = "context-created"; + const GW_MESSAGE_CONTEXT_ADDED = "context-added"; + const GW_MESSAGE_SUBSCRIBE_CONTEXT = "subscribe-context"; + const GW_MESSAGE_SUBSCRIBED_CONTEXT = "subscribed-context"; + const GW_MESSAGE_UNSUBSCRIBE_CONTEXT = "unsubscribe-context"; + const GW_MESSAGE_DESTROY_CONTEXT = "destroy-context"; + const GW_MESSAGE_CONTEXT_DESTROYED = "context-destroyed"; + const GW_MESSAGE_UPDATE_CONTEXT = "update-context"; + const GW_MESSAGE_CONTEXT_UPDATED = "context-updated"; + const GW_MESSAGE_JOINED_ACTIVITY = "joined"; + + const ContextMessageReplaySpec = { + get name() { + return "context"; + }, + get types() { + return [ + GW_MESSAGE_CREATE_CONTEXT, + GW_MESSAGE_ACTIVITY_CREATED, + GW_MESSAGE_ACTIVITY_DESTROYED, + GW_MESSAGE_CONTEXT_CREATED, + GW_MESSAGE_CONTEXT_ADDED, + GW_MESSAGE_SUBSCRIBE_CONTEXT, + GW_MESSAGE_SUBSCRIBED_CONTEXT, + GW_MESSAGE_UNSUBSCRIBE_CONTEXT, + GW_MESSAGE_DESTROY_CONTEXT, + GW_MESSAGE_CONTEXT_DESTROYED, + GW_MESSAGE_UPDATE_CONTEXT, + GW_MESSAGE_CONTEXT_UPDATED, + GW_MESSAGE_JOINED_ACTIVITY + ]; + } + }; + + var version$1 = "6.5.2-fmr-beta"; + + function prepareConfig$1 (configuration, ext, glue42gd) { + let nodeStartingContext; + if (Utils$1.isNode()) { + const startingContextString = process.env._GD_STARTING_CONTEXT_; + if (startingContextString) { + try { + nodeStartingContext = JSON.parse(startingContextString); + } + catch { + } + } + } + function getConnection() { + const gwConfig = configuration.gateway; + const protocolVersion = gwConfig?.protocolVersion ?? 3; + const reconnectInterval = gwConfig?.reconnectInterval; + const reconnectAttempts = gwConfig?.reconnectAttempts; + const defaultWs = "ws://localhost:8385"; + let ws = gwConfig?.ws; + const sharedWorker = gwConfig?.sharedWorker; + const inproc = gwConfig?.inproc; + const webPlatform = gwConfig?.webPlatform ?? undefined; + if (glue42gd) { + ws = glue42gd.gwURL; + } + if (Utils$1.isNode() && nodeStartingContext && nodeStartingContext.gwURL) { + ws = nodeStartingContext.gwURL; + } + if (!ws && !sharedWorker && !inproc) { + ws = defaultWs; + } + let instanceId; + let windowId; + let pid; + let environment; + let region; + const appName = getApplication(); + let uniqueAppName = appName; + if (typeof glue42gd !== "undefined") { + windowId = glue42gd.windowId; + pid = glue42gd.pid; + if (glue42gd.env) { + environment = glue42gd.env.env; + region = glue42gd.env.region; + } + uniqueAppName = glue42gd.application ?? "glue-app"; + instanceId = glue42gd.appInstanceId; + } + else if (Utils$1.isNode()) { + pid = process.pid; + if (nodeStartingContext) { + environment = nodeStartingContext.env; + region = nodeStartingContext.region; + instanceId = nodeStartingContext.instanceId; + } + } + else if (typeof window?.glue42electron !== "undefined") { + windowId = window?.glue42electron.instanceId; + pid = window?.glue42electron.pid; + environment = window?.glue42electron.env; + region = window?.glue42electron.region; + uniqueAppName = window?.glue42electron.application ?? "glue-app"; + instanceId = window?.glue42electron.instanceId; + } + else ; + const replaySpecs = configuration.gateway?.replaySpecs ?? []; + replaySpecs.push(ContextMessageReplaySpec); + let identity = { + application: uniqueAppName, + applicationName: appName, + windowId, + instance: instanceId, + process: pid, + region, + environment, + api: ext.version || version$1 + }; + if (configuration.identity) { + identity = Object.assign(identity, configuration.identity); + } + return { + identity, + reconnectInterval, + ws, + sharedWorker, + webPlatform, + inproc, + protocolVersion, + reconnectAttempts, + replaySpecs, + }; + } + function getContexts() { + if (typeof configuration.contexts === "undefined") { + return { reAnnounceKnownContexts: true }; + } + if (typeof configuration.contexts === "boolean" && configuration.contexts) { + return { reAnnounceKnownContexts: true }; + } + if (typeof configuration.contexts === "object") { + return Object.assign({}, { reAnnounceKnownContexts: true }, configuration.contexts); + } + return false; + } + function getApplication() { + if (configuration.application) { + return configuration.application; + } + if (glue42gd) { + return glue42gd.applicationName; + } + if (typeof window !== "undefined" && typeof window.glue42electron !== "undefined") { + return window.glue42electron.application; + } + const uid = nanoid$1(10); + if (Utils$1.isNode()) { + if (nodeStartingContext) { + return nodeStartingContext.applicationConfig.name; + } + return "NodeJS" + uid; + } + if (typeof window !== "undefined" && typeof document !== "undefined") { + return document.title + ` (${uid})`; + } + return uid; + } + function getAuth() { + if (typeof configuration.auth === "string") { + return { + token: configuration.auth + }; + } + if (configuration.auth) { + return configuration.auth; + } + if (Utils$1.isNode() && nodeStartingContext && nodeStartingContext.gwToken) { + return { + gatewayToken: nodeStartingContext.gwToken + }; + } + if (configuration.gateway?.webPlatform || configuration.gateway?.inproc || configuration.gateway?.sharedWorker) { + return { + username: "glue42", password: "glue42" + }; + } + } + function getLogger() { + let config = configuration.logger; + const defaultLevel = "warn"; + if (!config) { + config = defaultLevel; + } + let gdConsoleLevel; + if (glue42gd) { + gdConsoleLevel = glue42gd.consoleLogLevel; + } + if (typeof config === "string") { + return { console: gdConsoleLevel ?? config, publish: defaultLevel }; + } + return { + console: gdConsoleLevel ?? config.console ?? defaultLevel, + publish: config.publish ?? defaultLevel + }; + } + const connection = getConnection(); + let application = getApplication(); + if (typeof window !== "undefined") { + const windowAsAny = window; + const containerApplication = windowAsAny.htmlContainer ? + `${windowAsAny.htmlContainer.containerName}.${windowAsAny.htmlContainer.application}` : + windowAsAny?.glue42gd?.application; + if (containerApplication) { + application = containerApplication; + } + } + return { + bus: configuration.bus ?? false, + application, + auth: getAuth(), + logger: getLogger(), + connection, + metrics: configuration.metrics ?? true, + contexts: getContexts(), + version: ext.version || version$1, + libs: ext.libs ?? [], + customLogger: configuration.customLogger + }; + } + + class GW3ContextData { + name; + contextId; + context; + isAnnounced; + joinedActivity; + updateCallbacks = {}; + activityId; + sentExplicitSubscription; + hasReceivedSnapshot; + constructor(contextId, name, isAnnounced, activityId) { + this.contextId = contextId; + this.name = name; + this.isAnnounced = isAnnounced; + this.activityId = activityId; + this.context = {}; + } + hasCallbacks() { + return Object.keys(this.updateCallbacks).length > 0; + } + getState() { + if (this.isAnnounced && this.hasCallbacks()) { + return 3; + } + if (this.isAnnounced) { + return 2; + } + if (this.hasCallbacks()) { + return 1; + } + return 0; + } + } + + var lodash_clonedeep = {exports: {}}; + + /** + * lodash (Custom Build) + * Build: `lodash modularize exports="npm" -o ./` + * Copyright jQuery Foundation and other contributors + * Released under MIT license + * Based on Underscore.js 1.8.3 + * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + */ + lodash_clonedeep.exports; + + (function (module, exports) { + /** Used as the size to enable large array optimizations. */ + var LARGE_ARRAY_SIZE = 200; + + /** Used to stand-in for `undefined` hash values. */ + var HASH_UNDEFINED = '__lodash_hash_undefined__'; + + /** Used as references for various `Number` constants. */ + var MAX_SAFE_INTEGER = 9007199254740991; + + /** `Object#toString` result references. */ + var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + boolTag = '[object Boolean]', + dateTag = '[object Date]', + errorTag = '[object Error]', + funcTag = '[object Function]', + genTag = '[object GeneratorFunction]', + mapTag = '[object Map]', + numberTag = '[object Number]', + objectTag = '[object Object]', + promiseTag = '[object Promise]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + symbolTag = '[object Symbol]', + weakMapTag = '[object WeakMap]'; + + var arrayBufferTag = '[object ArrayBuffer]', + dataViewTag = '[object DataView]', + float32Tag = '[object Float32Array]', + float64Tag = '[object Float64Array]', + int8Tag = '[object Int8Array]', + int16Tag = '[object Int16Array]', + int32Tag = '[object Int32Array]', + uint8Tag = '[object Uint8Array]', + uint8ClampedTag = '[object Uint8ClampedArray]', + uint16Tag = '[object Uint16Array]', + uint32Tag = '[object Uint32Array]'; + + /** + * Used to match `RegExp` + * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns). + */ + var reRegExpChar = /[\\^$.*+?()[\]{}|]/g; + + /** Used to match `RegExp` flags from their coerced string values. */ + var reFlags = /\w*$/; + + /** Used to detect host constructors (Safari). */ + var reIsHostCtor = /^\[object .+?Constructor\]$/; + + /** Used to detect unsigned integer values. */ + var reIsUint = /^(?:0|[1-9]\d*)$/; + + /** Used to identify `toStringTag` values supported by `_.clone`. */ + var cloneableTags = {}; + cloneableTags[argsTag] = cloneableTags[arrayTag] = + cloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] = + cloneableTags[boolTag] = cloneableTags[dateTag] = + cloneableTags[float32Tag] = cloneableTags[float64Tag] = + cloneableTags[int8Tag] = cloneableTags[int16Tag] = + cloneableTags[int32Tag] = cloneableTags[mapTag] = + cloneableTags[numberTag] = cloneableTags[objectTag] = + cloneableTags[regexpTag] = cloneableTags[setTag] = + cloneableTags[stringTag] = cloneableTags[symbolTag] = + cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] = + cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true; + cloneableTags[errorTag] = cloneableTags[funcTag] = + cloneableTags[weakMapTag] = false; + + /** Detect free variable `global` from Node.js. */ + var freeGlobal = typeof commonjsGlobal$1 == 'object' && commonjsGlobal$1 && commonjsGlobal$1.Object === Object && commonjsGlobal$1; + + /** Detect free variable `self`. */ + var freeSelf = typeof self == 'object' && self && self.Object === Object && self; + + /** Used as a reference to the global object. */ + var root = freeGlobal || freeSelf || Function('return this')(); + + /** Detect free variable `exports`. */ + var freeExports = exports && !exports.nodeType && exports; + + /** Detect free variable `module`. */ + var freeModule = freeExports && 'object' == 'object' && module && !module.nodeType && module; + + /** Detect the popular CommonJS extension `module.exports`. */ + var moduleExports = freeModule && freeModule.exports === freeExports; + + /** + * Adds the key-value `pair` to `map`. + * + * @private + * @param {Object} map The map to modify. + * @param {Array} pair The key-value pair to add. + * @returns {Object} Returns `map`. + */ + function addMapEntry(map, pair) { + // Don't return `map.set` because it's not chainable in IE 11. + map.set(pair[0], pair[1]); + return map; + } + + /** + * Adds `value` to `set`. + * + * @private + * @param {Object} set The set to modify. + * @param {*} value The value to add. + * @returns {Object} Returns `set`. + */ + function addSetEntry(set, value) { + // Don't return `set.add` because it's not chainable in IE 11. + set.add(value); + return set; + } + + /** + * A specialized version of `_.forEach` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns `array`. + */ + function arrayEach(array, iteratee) { + var index = -1, + length = array ? array.length : 0; + + while (++index < length) { + if (iteratee(array[index], index, array) === false) { + break; + } + } + return array; + } + + /** + * Appends the elements of `values` to `array`. + * + * @private + * @param {Array} array The array to modify. + * @param {Array} values The values to append. + * @returns {Array} Returns `array`. + */ + function arrayPush(array, values) { + var index = -1, + length = values.length, + offset = array.length; + + while (++index < length) { + array[offset + index] = values[index]; + } + return array; + } + + /** + * A specialized version of `_.reduce` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {boolean} [initAccum] Specify using the first element of `array` as + * the initial value. + * @returns {*} Returns the accumulated value. + */ + function arrayReduce(array, iteratee, accumulator, initAccum) { + var index = -1, + length = array ? array.length : 0; + while (++index < length) { + accumulator = iteratee(accumulator, array[index], index, array); + } + return accumulator; + } + + /** + * The base implementation of `_.times` without support for iteratee shorthands + * or max array length checks. + * + * @private + * @param {number} n The number of times to invoke `iteratee`. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the array of results. + */ + function baseTimes(n, iteratee) { + var index = -1, + result = Array(n); + + while (++index < n) { + result[index] = iteratee(index); + } + return result; + } + + /** + * Gets the value at `key` of `object`. + * + * @private + * @param {Object} [object] The object to query. + * @param {string} key The key of the property to get. + * @returns {*} Returns the property value. + */ + function getValue(object, key) { + return object == null ? undefined : object[key]; + } + + /** + * Checks if `value` is a host object in IE < 9. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a host object, else `false`. + */ + function isHostObject(value) { + // Many host objects are `Object` objects that can coerce to strings + // despite having improperly defined `toString` methods. + var result = false; + if (value != null && typeof value.toString != 'function') { + try { + result = !!(value + ''); + } catch (e) {} + } + return result; + } + + /** + * Converts `map` to its key-value pairs. + * + * @private + * @param {Object} map The map to convert. + * @returns {Array} Returns the key-value pairs. + */ + function mapToArray(map) { + var index = -1, + result = Array(map.size); + + map.forEach(function(value, key) { + result[++index] = [key, value]; + }); + return result; + } + + /** + * Creates a unary function that invokes `func` with its argument transformed. + * + * @private + * @param {Function} func The function to wrap. + * @param {Function} transform The argument transform. + * @returns {Function} Returns the new function. + */ + function overArg(func, transform) { + return function(arg) { + return func(transform(arg)); + }; + } + + /** + * Converts `set` to an array of its values. + * + * @private + * @param {Object} set The set to convert. + * @returns {Array} Returns the values. + */ + function setToArray(set) { + var index = -1, + result = Array(set.size); + + set.forEach(function(value) { + result[++index] = value; + }); + return result; + } + + /** Used for built-in method references. */ + var arrayProto = Array.prototype, + funcProto = Function.prototype, + objectProto = Object.prototype; + + /** Used to detect overreaching core-js shims. */ + var coreJsData = root['__core-js_shared__']; + + /** Used to detect methods masquerading as native. */ + var maskSrcKey = (function() { + var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || ''); + return uid ? ('Symbol(src)_1.' + uid) : ''; + }()); + + /** Used to resolve the decompiled source of functions. */ + var funcToString = funcProto.toString; + + /** Used to check objects for own properties. */ + var hasOwnProperty = objectProto.hasOwnProperty; + + /** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ + var objectToString = objectProto.toString; + + /** Used to detect if a method is native. */ + var reIsNative = RegExp('^' + + funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&') + .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' + ); + + /** Built-in value references. */ + var Buffer = moduleExports ? root.Buffer : undefined, + Symbol = root.Symbol, + Uint8Array = root.Uint8Array, + getPrototype = overArg(Object.getPrototypeOf, Object), + objectCreate = Object.create, + propertyIsEnumerable = objectProto.propertyIsEnumerable, + splice = arrayProto.splice; + + /* Built-in method references for those with the same name as other `lodash` methods. */ + var nativeGetSymbols = Object.getOwnPropertySymbols, + nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined, + nativeKeys = overArg(Object.keys, Object); + + /* Built-in method references that are verified to be native. */ + var DataView = getNative(root, 'DataView'), + Map = getNative(root, 'Map'), + Promise = getNative(root, 'Promise'), + Set = getNative(root, 'Set'), + WeakMap = getNative(root, 'WeakMap'), + nativeCreate = getNative(Object, 'create'); + + /** Used to detect maps, sets, and weakmaps. */ + var dataViewCtorString = toSource(DataView), + mapCtorString = toSource(Map), + promiseCtorString = toSource(Promise), + setCtorString = toSource(Set), + weakMapCtorString = toSource(WeakMap); + + /** Used to convert symbols to primitives and strings. */ + var symbolProto = Symbol ? Symbol.prototype : undefined, + symbolValueOf = symbolProto ? symbolProto.valueOf : undefined; + + /** + * Creates a hash object. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + function Hash(entries) { + var index = -1, + length = entries ? entries.length : 0; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } + } + + /** + * Removes all key-value entries from the hash. + * + * @private + * @name clear + * @memberOf Hash + */ + function hashClear() { + this.__data__ = nativeCreate ? nativeCreate(null) : {}; + } + + /** + * Removes `key` and its value from the hash. + * + * @private + * @name delete + * @memberOf Hash + * @param {Object} hash The hash to modify. + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function hashDelete(key) { + return this.has(key) && delete this.__data__[key]; + } + + /** + * Gets the hash value for `key`. + * + * @private + * @name get + * @memberOf Hash + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function hashGet(key) { + var data = this.__data__; + if (nativeCreate) { + var result = data[key]; + return result === HASH_UNDEFINED ? undefined : result; + } + return hasOwnProperty.call(data, key) ? data[key] : undefined; + } + + /** + * Checks if a hash value for `key` exists. + * + * @private + * @name has + * @memberOf Hash + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function hashHas(key) { + var data = this.__data__; + return nativeCreate ? data[key] !== undefined : hasOwnProperty.call(data, key); + } + + /** + * Sets the hash `key` to `value`. + * + * @private + * @name set + * @memberOf Hash + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the hash instance. + */ + function hashSet(key, value) { + var data = this.__data__; + data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value; + return this; + } + + // Add methods to `Hash`. + Hash.prototype.clear = hashClear; + Hash.prototype['delete'] = hashDelete; + Hash.prototype.get = hashGet; + Hash.prototype.has = hashHas; + Hash.prototype.set = hashSet; + + /** + * Creates an list cache object. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + function ListCache(entries) { + var index = -1, + length = entries ? entries.length : 0; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } + } + + /** + * Removes all key-value entries from the list cache. + * + * @private + * @name clear + * @memberOf ListCache + */ + function listCacheClear() { + this.__data__ = []; + } + + /** + * Removes `key` and its value from the list cache. + * + * @private + * @name delete + * @memberOf ListCache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function listCacheDelete(key) { + var data = this.__data__, + index = assocIndexOf(data, key); + + if (index < 0) { + return false; + } + var lastIndex = data.length - 1; + if (index == lastIndex) { + data.pop(); + } else { + splice.call(data, index, 1); + } + return true; + } + + /** + * Gets the list cache value for `key`. + * + * @private + * @name get + * @memberOf ListCache + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function listCacheGet(key) { + var data = this.__data__, + index = assocIndexOf(data, key); + + return index < 0 ? undefined : data[index][1]; + } + + /** + * Checks if a list cache value for `key` exists. + * + * @private + * @name has + * @memberOf ListCache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function listCacheHas(key) { + return assocIndexOf(this.__data__, key) > -1; + } + + /** + * Sets the list cache `key` to `value`. + * + * @private + * @name set + * @memberOf ListCache + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the list cache instance. + */ + function listCacheSet(key, value) { + var data = this.__data__, + index = assocIndexOf(data, key); + + if (index < 0) { + data.push([key, value]); + } else { + data[index][1] = value; + } + return this; + } + + // Add methods to `ListCache`. + ListCache.prototype.clear = listCacheClear; + ListCache.prototype['delete'] = listCacheDelete; + ListCache.prototype.get = listCacheGet; + ListCache.prototype.has = listCacheHas; + ListCache.prototype.set = listCacheSet; + + /** + * Creates a map cache object to store key-value pairs. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + function MapCache(entries) { + var index = -1, + length = entries ? entries.length : 0; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } + } + + /** + * Removes all key-value entries from the map. + * + * @private + * @name clear + * @memberOf MapCache + */ + function mapCacheClear() { + this.__data__ = { + 'hash': new Hash, + 'map': new (Map || ListCache), + 'string': new Hash + }; + } + + /** + * Removes `key` and its value from the map. + * + * @private + * @name delete + * @memberOf MapCache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function mapCacheDelete(key) { + return getMapData(this, key)['delete'](key); + } + + /** + * Gets the map value for `key`. + * + * @private + * @name get + * @memberOf MapCache + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function mapCacheGet(key) { + return getMapData(this, key).get(key); + } + + /** + * Checks if a map value for `key` exists. + * + * @private + * @name has + * @memberOf MapCache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function mapCacheHas(key) { + return getMapData(this, key).has(key); + } + + /** + * Sets the map `key` to `value`. + * + * @private + * @name set + * @memberOf MapCache + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the map cache instance. + */ + function mapCacheSet(key, value) { + getMapData(this, key).set(key, value); + return this; + } + + // Add methods to `MapCache`. + MapCache.prototype.clear = mapCacheClear; + MapCache.prototype['delete'] = mapCacheDelete; + MapCache.prototype.get = mapCacheGet; + MapCache.prototype.has = mapCacheHas; + MapCache.prototype.set = mapCacheSet; + + /** + * Creates a stack cache object to store key-value pairs. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + function Stack(entries) { + this.__data__ = new ListCache(entries); + } + + /** + * Removes all key-value entries from the stack. + * + * @private + * @name clear + * @memberOf Stack + */ + function stackClear() { + this.__data__ = new ListCache; + } + + /** + * Removes `key` and its value from the stack. + * + * @private + * @name delete + * @memberOf Stack + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function stackDelete(key) { + return this.__data__['delete'](key); + } + + /** + * Gets the stack value for `key`. + * + * @private + * @name get + * @memberOf Stack + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function stackGet(key) { + return this.__data__.get(key); + } + + /** + * Checks if a stack value for `key` exists. + * + * @private + * @name has + * @memberOf Stack + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function stackHas(key) { + return this.__data__.has(key); + } + + /** + * Sets the stack `key` to `value`. + * + * @private + * @name set + * @memberOf Stack + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the stack cache instance. + */ + function stackSet(key, value) { + var cache = this.__data__; + if (cache instanceof ListCache) { + var pairs = cache.__data__; + if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) { + pairs.push([key, value]); + return this; + } + cache = this.__data__ = new MapCache(pairs); + } + cache.set(key, value); + return this; + } + + // Add methods to `Stack`. + Stack.prototype.clear = stackClear; + Stack.prototype['delete'] = stackDelete; + Stack.prototype.get = stackGet; + Stack.prototype.has = stackHas; + Stack.prototype.set = stackSet; + + /** + * Creates an array of the enumerable property names of the array-like `value`. + * + * @private + * @param {*} value The value to query. + * @param {boolean} inherited Specify returning inherited property names. + * @returns {Array} Returns the array of property names. + */ + function arrayLikeKeys(value, inherited) { + // Safari 8.1 makes `arguments.callee` enumerable in strict mode. + // Safari 9 makes `arguments.length` enumerable in strict mode. + var result = (isArray(value) || isArguments(value)) + ? baseTimes(value.length, String) + : []; + + var length = result.length, + skipIndexes = !!length; + + for (var key in value) { + if ((hasOwnProperty.call(value, key)) && + !(skipIndexes && (key == 'length' || isIndex(key, length)))) { + result.push(key); + } + } + return result; + } + + /** + * Assigns `value` to `key` of `object` if the existing value is not equivalent + * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. + * + * @private + * @param {Object} object The object to modify. + * @param {string} key The key of the property to assign. + * @param {*} value The value to assign. + */ + function assignValue(object, key, value) { + var objValue = object[key]; + if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) || + (value === undefined && !(key in object))) { + object[key] = value; + } + } + + /** + * Gets the index at which the `key` is found in `array` of key-value pairs. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} key The key to search for. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function assocIndexOf(array, key) { + var length = array.length; + while (length--) { + if (eq(array[length][0], key)) { + return length; + } + } + return -1; + } + + /** + * The base implementation of `_.assign` without support for multiple sources + * or `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @returns {Object} Returns `object`. + */ + function baseAssign(object, source) { + return object && copyObject(source, keys(source), object); + } + + /** + * The base implementation of `_.clone` and `_.cloneDeep` which tracks + * traversed objects. + * + * @private + * @param {*} value The value to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @param {boolean} [isFull] Specify a clone including symbols. + * @param {Function} [customizer] The function to customize cloning. + * @param {string} [key] The key of `value`. + * @param {Object} [object] The parent object of `value`. + * @param {Object} [stack] Tracks traversed objects and their clone counterparts. + * @returns {*} Returns the cloned value. + */ + function baseClone(value, isDeep, isFull, customizer, key, object, stack) { + var result; + if (customizer) { + result = object ? customizer(value, key, object, stack) : customizer(value); + } + if (result !== undefined) { + return result; + } + if (!isObject(value)) { + return value; + } + var isArr = isArray(value); + if (isArr) { + result = initCloneArray(value); + if (!isDeep) { + return copyArray(value, result); + } + } else { + var tag = getTag(value), + isFunc = tag == funcTag || tag == genTag; + + if (isBuffer(value)) { + return cloneBuffer(value, isDeep); + } + if (tag == objectTag || tag == argsTag || (isFunc && !object)) { + if (isHostObject(value)) { + return object ? value : {}; + } + result = initCloneObject(isFunc ? {} : value); + if (!isDeep) { + return copySymbols(value, baseAssign(result, value)); + } + } else { + if (!cloneableTags[tag]) { + return object ? value : {}; + } + result = initCloneByTag(value, tag, baseClone, isDeep); + } + } + // Check for circular references and return its corresponding clone. + stack || (stack = new Stack); + var stacked = stack.get(value); + if (stacked) { + return stacked; + } + stack.set(value, result); + + if (!isArr) { + var props = isFull ? getAllKeys(value) : keys(value); + } + arrayEach(props || value, function(subValue, key) { + if (props) { + key = subValue; + subValue = value[key]; + } + // Recursively populate clone (susceptible to call stack limits). + assignValue(result, key, baseClone(subValue, isDeep, isFull, customizer, key, value, stack)); + }); + return result; + } + + /** + * The base implementation of `_.create` without support for assigning + * properties to the created object. + * + * @private + * @param {Object} prototype The object to inherit from. + * @returns {Object} Returns the new object. + */ + function baseCreate(proto) { + return isObject(proto) ? objectCreate(proto) : {}; + } + + /** + * The base implementation of `getAllKeys` and `getAllKeysIn` which uses + * `keysFunc` and `symbolsFunc` to get the enumerable property names and + * symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Function} keysFunc The function to get the keys of `object`. + * @param {Function} symbolsFunc The function to get the symbols of `object`. + * @returns {Array} Returns the array of property names and symbols. + */ + function baseGetAllKeys(object, keysFunc, symbolsFunc) { + var result = keysFunc(object); + return isArray(object) ? result : arrayPush(result, symbolsFunc(object)); + } + + /** + * The base implementation of `getTag`. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the `toStringTag`. + */ + function baseGetTag(value) { + return objectToString.call(value); + } + + /** + * The base implementation of `_.isNative` without bad shim checks. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a native function, + * else `false`. + */ + function baseIsNative(value) { + if (!isObject(value) || isMasked(value)) { + return false; + } + var pattern = (isFunction(value) || isHostObject(value)) ? reIsNative : reIsHostCtor; + return pattern.test(toSource(value)); + } + + /** + * The base implementation of `_.keys` which doesn't treat sparse arrays as dense. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ + function baseKeys(object) { + if (!isPrototype(object)) { + return nativeKeys(object); + } + var result = []; + for (var key in Object(object)) { + if (hasOwnProperty.call(object, key) && key != 'constructor') { + result.push(key); + } + } + return result; + } + + /** + * Creates a clone of `buffer`. + * + * @private + * @param {Buffer} buffer The buffer to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Buffer} Returns the cloned buffer. + */ + function cloneBuffer(buffer, isDeep) { + if (isDeep) { + return buffer.slice(); + } + var result = new buffer.constructor(buffer.length); + buffer.copy(result); + return result; + } + + /** + * Creates a clone of `arrayBuffer`. + * + * @private + * @param {ArrayBuffer} arrayBuffer The array buffer to clone. + * @returns {ArrayBuffer} Returns the cloned array buffer. + */ + function cloneArrayBuffer(arrayBuffer) { + var result = new arrayBuffer.constructor(arrayBuffer.byteLength); + new Uint8Array(result).set(new Uint8Array(arrayBuffer)); + return result; + } + + /** + * Creates a clone of `dataView`. + * + * @private + * @param {Object} dataView The data view to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned data view. + */ + function cloneDataView(dataView, isDeep) { + var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer; + return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength); + } + + /** + * Creates a clone of `map`. + * + * @private + * @param {Object} map The map to clone. + * @param {Function} cloneFunc The function to clone values. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned map. + */ + function cloneMap(map, isDeep, cloneFunc) { + var array = isDeep ? cloneFunc(mapToArray(map), true) : mapToArray(map); + return arrayReduce(array, addMapEntry, new map.constructor); + } + + /** + * Creates a clone of `regexp`. + * + * @private + * @param {Object} regexp The regexp to clone. + * @returns {Object} Returns the cloned regexp. + */ + function cloneRegExp(regexp) { + var result = new regexp.constructor(regexp.source, reFlags.exec(regexp)); + result.lastIndex = regexp.lastIndex; + return result; + } + + /** + * Creates a clone of `set`. + * + * @private + * @param {Object} set The set to clone. + * @param {Function} cloneFunc The function to clone values. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned set. + */ + function cloneSet(set, isDeep, cloneFunc) { + var array = isDeep ? cloneFunc(setToArray(set), true) : setToArray(set); + return arrayReduce(array, addSetEntry, new set.constructor); + } + + /** + * Creates a clone of the `symbol` object. + * + * @private + * @param {Object} symbol The symbol object to clone. + * @returns {Object} Returns the cloned symbol object. + */ + function cloneSymbol(symbol) { + return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {}; + } + + /** + * Creates a clone of `typedArray`. + * + * @private + * @param {Object} typedArray The typed array to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned typed array. + */ + function cloneTypedArray(typedArray, isDeep) { + var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer; + return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length); + } + + /** + * Copies the values of `source` to `array`. + * + * @private + * @param {Array} source The array to copy values from. + * @param {Array} [array=[]] The array to copy values to. + * @returns {Array} Returns `array`. + */ + function copyArray(source, array) { + var index = -1, + length = source.length; + + array || (array = Array(length)); + while (++index < length) { + array[index] = source[index]; + } + return array; + } + + /** + * Copies properties of `source` to `object`. + * + * @private + * @param {Object} source The object to copy properties from. + * @param {Array} props The property identifiers to copy. + * @param {Object} [object={}] The object to copy properties to. + * @param {Function} [customizer] The function to customize copied values. + * @returns {Object} Returns `object`. + */ + function copyObject(source, props, object, customizer) { + object || (object = {}); + + var index = -1, + length = props.length; + + while (++index < length) { + var key = props[index]; + + var newValue = undefined; + + assignValue(object, key, newValue === undefined ? source[key] : newValue); + } + return object; + } + + /** + * Copies own symbol properties of `source` to `object`. + * + * @private + * @param {Object} source The object to copy symbols from. + * @param {Object} [object={}] The object to copy symbols to. + * @returns {Object} Returns `object`. + */ + function copySymbols(source, object) { + return copyObject(source, getSymbols(source), object); + } + + /** + * Creates an array of own enumerable property names and symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names and symbols. + */ + function getAllKeys(object) { + return baseGetAllKeys(object, keys, getSymbols); + } + + /** + * Gets the data for `map`. + * + * @private + * @param {Object} map The map to query. + * @param {string} key The reference key. + * @returns {*} Returns the map data. + */ + function getMapData(map, key) { + var data = map.__data__; + return isKeyable(key) + ? data[typeof key == 'string' ? 'string' : 'hash'] + : data.map; + } + + /** + * Gets the native function at `key` of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {string} key The key of the method to get. + * @returns {*} Returns the function if it's native, else `undefined`. + */ + function getNative(object, key) { + var value = getValue(object, key); + return baseIsNative(value) ? value : undefined; + } + + /** + * Creates an array of the own enumerable symbol properties of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. + */ + var getSymbols = nativeGetSymbols ? overArg(nativeGetSymbols, Object) : stubArray; + + /** + * Gets the `toStringTag` of `value`. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the `toStringTag`. + */ + var getTag = baseGetTag; + + // Fallback for data views, maps, sets, and weak maps in IE 11, + // for data views in Edge < 14, and promises in Node.js. + if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) || + (Map && getTag(new Map) != mapTag) || + (Promise && getTag(Promise.resolve()) != promiseTag) || + (Set && getTag(new Set) != setTag) || + (WeakMap && getTag(new WeakMap) != weakMapTag)) { + getTag = function(value) { + var result = objectToString.call(value), + Ctor = result == objectTag ? value.constructor : undefined, + ctorString = Ctor ? toSource(Ctor) : undefined; + + if (ctorString) { + switch (ctorString) { + case dataViewCtorString: return dataViewTag; + case mapCtorString: return mapTag; + case promiseCtorString: return promiseTag; + case setCtorString: return setTag; + case weakMapCtorString: return weakMapTag; + } + } + return result; + }; + } + + /** + * Initializes an array clone. + * + * @private + * @param {Array} array The array to clone. + * @returns {Array} Returns the initialized clone. + */ + function initCloneArray(array) { + var length = array.length, + result = array.constructor(length); + + // Add properties assigned by `RegExp#exec`. + if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) { + result.index = array.index; + result.input = array.input; + } + return result; + } + + /** + * Initializes an object clone. + * + * @private + * @param {Object} object The object to clone. + * @returns {Object} Returns the initialized clone. + */ + function initCloneObject(object) { + return (typeof object.constructor == 'function' && !isPrototype(object)) + ? baseCreate(getPrototype(object)) + : {}; + } + + /** + * Initializes an object clone based on its `toStringTag`. + * + * **Note:** This function only supports cloning values with tags of + * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. + * + * @private + * @param {Object} object The object to clone. + * @param {string} tag The `toStringTag` of the object to clone. + * @param {Function} cloneFunc The function to clone values. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the initialized clone. + */ + function initCloneByTag(object, tag, cloneFunc, isDeep) { + var Ctor = object.constructor; + switch (tag) { + case arrayBufferTag: + return cloneArrayBuffer(object); + + case boolTag: + case dateTag: + return new Ctor(+object); + + case dataViewTag: + return cloneDataView(object, isDeep); + + case float32Tag: case float64Tag: + case int8Tag: case int16Tag: case int32Tag: + case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag: + return cloneTypedArray(object, isDeep); + + case mapTag: + return cloneMap(object, isDeep, cloneFunc); + + case numberTag: + case stringTag: + return new Ctor(object); + + case regexpTag: + return cloneRegExp(object); + + case setTag: + return cloneSet(object, isDeep, cloneFunc); + + case symbolTag: + return cloneSymbol(object); + } + } + + /** + * Checks if `value` is a valid array-like index. + * + * @private + * @param {*} value The value to check. + * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. + * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. + */ + function isIndex(value, length) { + length = length == null ? MAX_SAFE_INTEGER : length; + return !!length && + (typeof value == 'number' || reIsUint.test(value)) && + (value > -1 && value % 1 == 0 && value < length); + } + + /** + * Checks if `value` is suitable for use as unique object key. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is suitable, else `false`. + */ + function isKeyable(value) { + var type = typeof value; + return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean') + ? (value !== '__proto__') + : (value === null); + } + + /** + * Checks if `func` has its source masked. + * + * @private + * @param {Function} func The function to check. + * @returns {boolean} Returns `true` if `func` is masked, else `false`. + */ + function isMasked(func) { + return !!maskSrcKey && (maskSrcKey in func); + } + + /** + * Checks if `value` is likely a prototype object. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a prototype, else `false`. + */ + function isPrototype(value) { + var Ctor = value && value.constructor, + proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto; + + return value === proto; + } + + /** + * Converts `func` to its source code. + * + * @private + * @param {Function} func The function to process. + * @returns {string} Returns the source code. + */ + function toSource(func) { + if (func != null) { + try { + return funcToString.call(func); + } catch (e) {} + try { + return (func + ''); + } catch (e) {} + } + return ''; + } + + /** + * This method is like `_.clone` except that it recursively clones `value`. + * + * @static + * @memberOf _ + * @since 1.0.0 + * @category Lang + * @param {*} value The value to recursively clone. + * @returns {*} Returns the deep cloned value. + * @see _.clone + * @example + * + * var objects = [{ 'a': 1 }, { 'b': 2 }]; + * + * var deep = _.cloneDeep(objects); + * console.log(deep[0] === objects[0]); + * // => false + */ + function cloneDeep(value) { + return baseClone(value, true, true); + } + + /** + * Performs a + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * comparison between two values to determine if they are equivalent. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'a': 1 }; + * var other = { 'a': 1 }; + * + * _.eq(object, object); + * // => true + * + * _.eq(object, other); + * // => false + * + * _.eq('a', 'a'); + * // => true + * + * _.eq('a', Object('a')); + * // => false + * + * _.eq(NaN, NaN); + * // => true + */ + function eq(value, other) { + return value === other || (value !== value && other !== other); + } + + /** + * Checks if `value` is likely an `arguments` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an `arguments` object, + * else `false`. + * @example + * + * _.isArguments(function() { return arguments; }()); + * // => true + * + * _.isArguments([1, 2, 3]); + * // => false + */ + function isArguments(value) { + // Safari 8.1 makes `arguments.callee` enumerable in strict mode. + return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') && + (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag); + } + + /** + * Checks if `value` is classified as an `Array` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array, else `false`. + * @example + * + * _.isArray([1, 2, 3]); + * // => true + * + * _.isArray(document.body.children); + * // => false + * + * _.isArray('abc'); + * // => false + * + * _.isArray(_.noop); + * // => false + */ + var isArray = Array.isArray; + + /** + * Checks if `value` is array-like. A value is considered array-like if it's + * not a function and has a `value.length` that's an integer greater than or + * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is array-like, else `false`. + * @example + * + * _.isArrayLike([1, 2, 3]); + * // => true + * + * _.isArrayLike(document.body.children); + * // => true + * + * _.isArrayLike('abc'); + * // => true + * + * _.isArrayLike(_.noop); + * // => false + */ + function isArrayLike(value) { + return value != null && isLength(value.length) && !isFunction(value); + } + + /** + * This method is like `_.isArrayLike` except that it also checks if `value` + * is an object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array-like object, + * else `false`. + * @example + * + * _.isArrayLikeObject([1, 2, 3]); + * // => true + * + * _.isArrayLikeObject(document.body.children); + * // => true + * + * _.isArrayLikeObject('abc'); + * // => false + * + * _.isArrayLikeObject(_.noop); + * // => false + */ + function isArrayLikeObject(value) { + return isObjectLike(value) && isArrayLike(value); + } + + /** + * Checks if `value` is a buffer. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a buffer, else `false`. + * @example + * + * _.isBuffer(new Buffer(2)); + * // => true + * + * _.isBuffer(new Uint8Array(2)); + * // => false + */ + var isBuffer = nativeIsBuffer || stubFalse; + + /** + * Checks if `value` is classified as a `Function` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a function, else `false`. + * @example + * + * _.isFunction(_); + * // => true + * + * _.isFunction(/abc/); + * // => false + */ + function isFunction(value) { + // The use of `Object#toString` avoids issues with the `typeof` operator + // in Safari 8-9 which returns 'object' for typed array and other constructors. + var tag = isObject(value) ? objectToString.call(value) : ''; + return tag == funcTag || tag == genTag; + } + + /** + * Checks if `value` is a valid array-like length. + * + * **Note:** This method is loosely based on + * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. + * @example + * + * _.isLength(3); + * // => true + * + * _.isLength(Number.MIN_VALUE); + * // => false + * + * _.isLength(Infinity); + * // => false + * + * _.isLength('3'); + * // => false + */ + function isLength(value) { + return typeof value == 'number' && + value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; + } + + /** + * Checks if `value` is the + * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) + * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(_.noop); + * // => true + * + * _.isObject(null); + * // => false + */ + function isObject(value) { + var type = typeof value; + return !!value && (type == 'object' || type == 'function'); + } + + /** + * Checks if `value` is object-like. A value is object-like if it's not `null` + * and has a `typeof` result of "object". + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @example + * + * _.isObjectLike({}); + * // => true + * + * _.isObjectLike([1, 2, 3]); + * // => true + * + * _.isObjectLike(_.noop); + * // => false + * + * _.isObjectLike(null); + * // => false + */ + function isObjectLike(value) { + return !!value && typeof value == 'object'; + } + + /** + * Creates an array of the own enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. See the + * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) + * for more details. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keys(new Foo); + * // => ['a', 'b'] (iteration order is not guaranteed) + * + * _.keys('hi'); + * // => ['0', '1'] + */ + function keys(object) { + return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object); + } + + /** + * This method returns a new empty array. + * + * @static + * @memberOf _ + * @since 4.13.0 + * @category Util + * @returns {Array} Returns the new empty array. + * @example + * + * var arrays = _.times(2, _.stubArray); + * + * console.log(arrays); + * // => [[], []] + * + * console.log(arrays[0] === arrays[1]); + * // => false + */ + function stubArray() { + return []; + } + + /** + * This method returns `false`. + * + * @static + * @memberOf _ + * @since 4.13.0 + * @category Util + * @returns {boolean} Returns `false`. + * @example + * + * _.times(2, _.stubFalse); + * // => [false, false] + */ + function stubFalse() { + return false; + } + + module.exports = cloneDeep; + } (lodash_clonedeep, lodash_clonedeep.exports)); + + var lodash_clonedeepExports = lodash_clonedeep.exports; + var cloneDeep = /*@__PURE__*/getDefaultExportFromCjs$1(lodash_clonedeepExports); + + function applyContextDelta(context, delta, logger) { + try { + if (logger?.canPublish("trace")) { + logger?.trace(`applying context delta ${JSON.stringify(delta)} on context ${JSON.stringify(context)}`); + } + if (!delta) { + return context; + } + if (delta.reset) { + context = { ...delta.reset }; + return context; + } + context = deepClone(context, undefined); + if (delta.commands) { + for (const command of delta.commands) { + if (command.type === "remove") { + deletePath(context, command.path); + } + else if (command.type === "set") { + setValueToPath(context, command.value, command.path); + } + } + return context; + } + const added = delta.added; + const updated = delta.updated; + const removed = delta.removed; + if (added) { + Object.keys(added).forEach((key) => { + context[key] = added[key]; + }); + } + if (updated) { + Object.keys(updated).forEach((key) => { + mergeObjectsProperties(key, context, updated); + }); + } + if (removed) { + removed.forEach((key) => { + delete context[key]; + }); + } + return context; + } + catch (e) { + logger?.error(`error applying context delta ${JSON.stringify(delta)} on context ${JSON.stringify(context)}`, e); + return context; + } + } + function deepClone(obj, hash) { + return cloneDeep(obj); + } + const mergeObjectsProperties = (key, what, withWhat) => { + const right = withWhat[key]; + if (right === undefined) { + return what; + } + const left = what[key]; + if (!left || !right) { + what[key] = right; + return what; + } + if (typeof left === "string" || + typeof left === "number" || + typeof left === "boolean" || + typeof right === "string" || + typeof right === "number" || + typeof right === "boolean" || + Array.isArray(left) || + Array.isArray(right)) { + what[key] = right; + return what; + } + what[key] = Object.assign({}, left, right); + return what; + }; + function deepEqual(x, y) { + if (x === y) { + return true; + } + if (!(x instanceof Object) || !(y instanceof Object)) { + return false; + } + if (x.constructor !== y.constructor) { + return false; + } + for (const p in x) { + if (!x.hasOwnProperty(p)) { + continue; + } + if (!y.hasOwnProperty(p)) { + return false; + } + if (x[p] === y[p]) { + continue; + } + if (typeof (x[p]) !== "object") { + return false; + } + if (!deepEqual(x[p], y[p])) { + return false; + } + } + for (const p in y) { + if (y.hasOwnProperty(p) && !x.hasOwnProperty(p)) { + return false; + } + } + return true; + } + function setValueToPath(obj, value, path) { + const pathArr = path.split("."); + let i; + for (i = 0; i < pathArr.length - 1; i++) { + if (!obj[pathArr[i]]) { + obj[pathArr[i]] = {}; + } + if (typeof obj[pathArr[i]] !== "object") { + obj[pathArr[i]] = {}; + } + obj = obj[pathArr[i]]; + } + obj[pathArr[i]] = value; + } + function isSubset(superObj, subObj) { + return Object.keys(subObj).every((ele) => { + if (typeof subObj[ele] === "object") { + return isSubset(superObj?.[ele] || {}, subObj[ele] || {}); + } + return subObj[ele] === superObj?.[ele]; + }); + } + function deletePath(obj, path) { + const pathArr = path.split("."); + let i; + for (i = 0; i < pathArr.length - 1; i++) { + if (!obj[pathArr[i]]) { + return; + } + obj = obj[pathArr[i]]; + } + delete obj[pathArr[i]]; + } + + let GW3Bridge$1 = class GW3Bridge { + _logger; + _connection; + _trackAllContexts; + _reAnnounceKnownContexts; + _gw3Session; + _contextNameToData = {}; + _gw3Subscriptions = []; + _nextCallbackSubscriptionNumber = 0; + _creationPromises = {}; + _contextNameToId = {}; + _contextIdToName = {}; + _protocolVersion = undefined; + _contextsTempCache = {}; + _contextsSubscriptionsCache = []; + _systemContextsSubKey; + get protocolVersion() { + if (!this._protocolVersion) { + const contextsDomainInfo = this._connection.availableDomains.find((d) => d.uri === "context"); + this._protocolVersion = contextsDomainInfo?.version ?? 1; + } + return this._protocolVersion; + } + get setPathSupported() { + return this.protocolVersion >= 2; + } + constructor(config) { + this._connection = config.connection; + this._logger = config.logger; + this._trackAllContexts = config.trackAllContexts; + this._reAnnounceKnownContexts = config.reAnnounceKnownContexts; + this._gw3Session = this._connection.domain("global", [ + GW_MESSAGE_CONTEXT_CREATED, + GW_MESSAGE_SUBSCRIBED_CONTEXT, + GW_MESSAGE_CONTEXT_DESTROYED, + GW_MESSAGE_CONTEXT_UPDATED, + ]); + this._gw3Session.disconnected(this.resetState.bind(this)); + this._gw3Session.onJoined((wasReconnect) => { + if (!wasReconnect) { + return; + } + if (!this._reAnnounceKnownContexts) { + return this._connection.setLibReAnnounced({ name: "contexts" }); + } + this.reInitiateState().then(() => this._connection.setLibReAnnounced({ name: "contexts" })); + }); + this.subscribeToContextCreatedMessages(); + this.subscribeToContextUpdatedMessages(); + this.subscribeToContextDestroyedMessages(); + this._connection.replayer?.drain(ContextMessageReplaySpec.name, (message) => { + const type = message.type; + if (!type) { + return; + } + if (type === GW_MESSAGE_CONTEXT_CREATED || + type === GW_MESSAGE_CONTEXT_ADDED || + type === GW_MESSAGE_ACTIVITY_CREATED) { + this.handleContextCreatedMessage(message); + } + else if (type === GW_MESSAGE_SUBSCRIBED_CONTEXT || + type === GW_MESSAGE_CONTEXT_UPDATED || + type === GW_MESSAGE_JOINED_ACTIVITY) { + this.handleContextUpdatedMessage(message); + } + else if (type === GW_MESSAGE_CONTEXT_DESTROYED || + type === GW_MESSAGE_ACTIVITY_DESTROYED) { + this.handleContextDestroyedMessage(message); + } + }); + } + dispose() { + for (const sub of this._gw3Subscriptions) { + this._connection.off(sub); + } + this._gw3Subscriptions.length = 0; + for (const contextName in this._contextNameToData) { + if (this._contextNameToId.hasOwnProperty(contextName)) { + delete this._contextNameToData[contextName]; + } + } + } + createContext(name, data) { + if (name in this._creationPromises) { + return this._creationPromises[name]; + } + this._creationPromises[name] = + this._gw3Session + .send({ + type: GW_MESSAGE_CREATE_CONTEXT, + domain: "global", + name, + data, + lifetime: "retained", + }) + .then((createContextMsg) => { + this._contextNameToId[name] = createContextMsg.context_id; + this._contextIdToName[createContextMsg.context_id] = name; + const contextData = this._contextNameToData[name] || new GW3ContextData(createContextMsg.context_id, name, true, undefined); + contextData.isAnnounced = true; + contextData.name = name; + contextData.contextId = createContextMsg.context_id; + contextData.context = createContextMsg.data || deepClone(data); + contextData.hasReceivedSnapshot = true; + this._contextNameToData[name] = contextData; + delete this._creationPromises[name]; + return createContextMsg.context_id; + }); + return this._creationPromises[name]; + } + all() { + return Object.keys(this._contextNameToData) + .filter((name) => this._contextNameToData[name].isAnnounced); + } + async update(name, delta) { + if (delta) { + delta = deepClone(delta); + } + if (name in this._creationPromises) { + await this._creationPromises[name]; + } + const contextData = this._contextNameToData[name]; + if (!contextData || !contextData.isAnnounced) { + return this.createContext(name, delta); + } + let currentContext = contextData.context; + if (!contextData.hasCallbacks()) { + currentContext = await this.get(contextData.name); + } + const calculatedDelta = this.setPathSupported ? + this.calculateContextDeltaV2(currentContext, delta) : + this.calculateContextDeltaV1(currentContext, delta); + if (!Object.keys(calculatedDelta.added).length + && !Object.keys(calculatedDelta.updated).length + && !calculatedDelta.removed.length + && !calculatedDelta.commands?.length) { + return Promise.resolve(); + } + return this._gw3Session + .send({ + type: GW_MESSAGE_UPDATE_CONTEXT, + domain: "global", + context_id: contextData.contextId, + delta: calculatedDelta, + }, {}, { skipPeerId: false }) + .then((gwResponse) => { + this.handleUpdated(contextData, calculatedDelta, { + updaterId: gwResponse.peer_id + }); + }); + } + async set(name, data) { + if (data) { + data = deepClone(data); + } + if (name in this._creationPromises) { + await this._creationPromises[name]; + } + const contextData = this._contextNameToData[name]; + if (!contextData || !contextData.isAnnounced) { + return this.createContext(name, data); + } + return this._gw3Session + .send({ + type: GW_MESSAGE_UPDATE_CONTEXT, + domain: "global", + context_id: contextData.contextId, + delta: { reset: data }, + }, {}, { skipPeerId: false }) + .then((gwResponse) => { + this.handleUpdated(contextData, { + reset: data, + added: {}, + removed: [], + updated: {} + }, { + updaterId: gwResponse.peer_id + }); + }); + } + setPath(name, path, value) { + if (!this.setPathSupported) { + return Promise.reject("glue.contexts.setPath operation is not supported, use Glue42 3.10 or later"); + } + return this.setPaths(name, [{ path, value }]); + } + async setPaths(name, pathValues) { + if (!this.setPathSupported) { + return Promise.reject("glue.contexts.setPaths operation is not supported, use Glue42 3.10 or later"); + } + if (pathValues) { + pathValues = deepClone(pathValues); + } + if (name in this._creationPromises) { + await this._creationPromises[name]; + } + const contextData = this._contextNameToData[name]; + if (!contextData || !contextData.isAnnounced) { + const obj = {}; + for (const pathValue of pathValues) { + setValueToPath(obj, pathValue.value, pathValue.path); + } + return this.createContext(name, obj); + } + const commands = []; + for (const pathValue of pathValues) { + if (pathValue.value === null) { + commands.push({ type: "remove", path: pathValue.path }); + } + else { + commands.push({ type: "set", path: pathValue.path, value: pathValue.value }); + } + } + return this._gw3Session + .send({ + type: GW_MESSAGE_UPDATE_CONTEXT, + domain: "global", + context_id: contextData.contextId, + delta: { commands } + }, {}, { skipPeerId: false }) + .then((gwResponse) => { + this.handleUpdated(contextData, { + added: {}, + removed: [], + updated: {}, + commands + }, { + updaterId: gwResponse.peer_id + }); + }); + } + async get(name) { + if (name in this._creationPromises) { + await this._creationPromises[name]; + } + const contextData = this._contextNameToData[name]; + if (!contextData || !contextData.isAnnounced) { + return Promise.resolve({}); + } + if (contextData && (!contextData.hasCallbacks() || !contextData.hasReceivedSnapshot)) { + return new Promise((resolve) => { + this.subscribe(name, (data, _d, _r, un) => { + this.unsubscribe(un); + resolve(data); + }); + }); + } + const context = contextData?.context ?? {}; + return Promise.resolve(deepClone(context)); + } + async subscribe(name, callback, subscriptionKey) { + if (name in this._creationPromises) { + await this._creationPromises[name]; + } + const thisCallbackSubscriptionNumber = typeof subscriptionKey === "undefined" ? this._nextCallbackSubscriptionNumber : subscriptionKey; + if (typeof subscriptionKey === "undefined") { + this._nextCallbackSubscriptionNumber += 1; + } + if (this._contextsSubscriptionsCache.every((subscription) => subscription.subKey !== this._nextCallbackSubscriptionNumber)) { + this._contextsSubscriptionsCache.push({ contextName: name, subKey: thisCallbackSubscriptionNumber, callback }); + } + let contextData = this._contextNameToData[name]; + if (!contextData || + !contextData.isAnnounced) { + contextData = contextData || new GW3ContextData(undefined, name, false, undefined); + this._contextNameToData[name] = contextData; + contextData.updateCallbacks[thisCallbackSubscriptionNumber] = callback; + return Promise.resolve(thisCallbackSubscriptionNumber); + } + const hadCallbacks = contextData.hasCallbacks(); + contextData.updateCallbacks[thisCallbackSubscriptionNumber] = callback; + if (!hadCallbacks) { + if (!contextData.joinedActivity) { + if (contextData.context && contextData.sentExplicitSubscription) { + if (contextData.hasReceivedSnapshot) { + const clone = deepClone(contextData.context); + callback(clone, clone, [], thisCallbackSubscriptionNumber); + } + return Promise.resolve(thisCallbackSubscriptionNumber); + } + return this.sendSubscribe(contextData) + .then(() => thisCallbackSubscriptionNumber); + } + else { + if (contextData.hasReceivedSnapshot) { + const clone = deepClone(contextData.context); + callback(clone, clone, [], thisCallbackSubscriptionNumber); + } + return Promise.resolve(thisCallbackSubscriptionNumber); + } + } + else { + if (contextData.hasReceivedSnapshot) { + const clone = deepClone(contextData.context); + callback(clone, clone, [], thisCallbackSubscriptionNumber); + } + return Promise.resolve(thisCallbackSubscriptionNumber); + } + } + unsubscribe(subscriptionKey) { + this._contextsSubscriptionsCache = this._contextsSubscriptionsCache.filter((subscription) => subscription.subKey !== subscriptionKey); + for (const name of Object.keys(this._contextNameToData)) { + const contextData = this._contextNameToData[name]; + if (!contextData) { + return; + } + const hadCallbacks = contextData.hasCallbacks(); + delete contextData.updateCallbacks[subscriptionKey]; + if (contextData.isAnnounced && + hadCallbacks && + !contextData.hasCallbacks() && + contextData.sentExplicitSubscription) { + this.sendUnsubscribe(contextData).catch(() => { }); + } + if (!contextData.isAnnounced && + !contextData.hasCallbacks()) { + delete this._contextNameToData[name]; + } + } + } + async destroy(name) { + if (name in this._creationPromises) { + await this._creationPromises[name]; + } + const contextData = this._contextNameToData[name]; + if (!contextData) { + return Promise.reject(`context with ${name} does not exist`); + } + return this._gw3Session + .send({ + type: GW_MESSAGE_DESTROY_CONTEXT, + domain: "global", + context_id: contextData.contextId, + }).then((_) => undefined); + } + handleUpdated(contextData, delta, extraData) { + const oldContext = contextData.context; + contextData.context = applyContextDelta(contextData.context, delta, this._logger); + contextData.hasReceivedSnapshot = true; + if (this._contextNameToData[contextData.name] === contextData && + !deepEqual(oldContext, contextData.context)) { + this.invokeUpdateCallbacks(contextData, delta, extraData); + } + } + subscribeToContextCreatedMessages() { + const createdMessageTypes = [ + GW_MESSAGE_CONTEXT_ADDED, + GW_MESSAGE_CONTEXT_CREATED, + GW_MESSAGE_ACTIVITY_CREATED, + ]; + for (const createdMessageType of createdMessageTypes) { + const sub = this._connection.on(createdMessageType, this.handleContextCreatedMessage.bind(this)); + this._gw3Subscriptions.push(sub); + } + } + handleContextCreatedMessage(contextCreatedMsg) { + const createdMessageType = contextCreatedMsg.type; + if (createdMessageType === GW_MESSAGE_ACTIVITY_CREATED) { + this._contextNameToId[contextCreatedMsg.activity_id] = contextCreatedMsg.context_id; + this._contextIdToName[contextCreatedMsg.context_id] = contextCreatedMsg.activity_id; + } + else if (createdMessageType === GW_MESSAGE_CONTEXT_ADDED) { + this._contextNameToId[contextCreatedMsg.name] = contextCreatedMsg.context_id; + this._contextIdToName[contextCreatedMsg.context_id] = contextCreatedMsg.name; + } + else ; + const name = this._contextIdToName[contextCreatedMsg.context_id]; + if (!name) { + throw new Error("Received created event for context with unknown name: " + contextCreatedMsg.context_id); + } + if (!this._contextNameToId[name]) { + throw new Error("Received created event for context with unknown id: " + contextCreatedMsg.context_id); + } + let contextData = this._contextNameToData[name]; + if (contextData) { + if (contextData.isAnnounced) { + return; + } + else { + if (!contextData.hasCallbacks()) { + throw new Error("Assertion failure: contextData.hasCallbacks()"); + } + contextData.isAnnounced = true; + contextData.contextId = contextCreatedMsg.context_id; + contextData.activityId = contextCreatedMsg.activity_id; + if (!contextData.sentExplicitSubscription) { + this.sendSubscribe(contextData); + } + } + } + else { + this._contextNameToData[name] = contextData = + new GW3ContextData(contextCreatedMsg.context_id, name, true, contextCreatedMsg.activity_id); + if (this._trackAllContexts) { + this.subscribe(name, () => { }).then((subKey) => this._systemContextsSubKey = subKey); + } + } + } + subscribeToContextUpdatedMessages() { + const updatedMessageTypes = [ + GW_MESSAGE_CONTEXT_UPDATED, + GW_MESSAGE_SUBSCRIBED_CONTEXT, + GW_MESSAGE_JOINED_ACTIVITY, + ]; + for (const updatedMessageType of updatedMessageTypes) { + const sub = this._connection.on(updatedMessageType, this.handleContextUpdatedMessage.bind(this)); + this._gw3Subscriptions.push(sub); + } + } + handleContextUpdatedMessage(contextUpdatedMsg) { + const updatedMessageType = contextUpdatedMsg.type; + const contextId = contextUpdatedMsg.context_id; + let contextData = this._contextNameToData[this._contextIdToName[contextId]]; + const justSeen = !contextData || !contextData.isAnnounced; + if (updatedMessageType === GW_MESSAGE_JOINED_ACTIVITY) { + if (!contextData) { + contextData = + this._contextNameToData[contextUpdatedMsg.activity_id] || + new GW3ContextData(contextId, contextUpdatedMsg.activity_id, true, contextUpdatedMsg.activity_id); + } + this._contextNameToData[contextUpdatedMsg.activity_id] = contextData; + this._contextIdToName[contextId] = contextUpdatedMsg.activity_id; + this._contextNameToId[contextUpdatedMsg.activity_id] = contextId; + contextData.contextId = contextId; + contextData.isAnnounced = true; + contextData.activityId = contextUpdatedMsg.activity_id; + contextData.joinedActivity = true; + } + else { + if (!contextData || !contextData.isAnnounced) { + if (updatedMessageType === GW_MESSAGE_SUBSCRIBED_CONTEXT) { + contextData = contextData || new GW3ContextData(contextId, contextUpdatedMsg.name, true, undefined); + contextData.sentExplicitSubscription = true; + this._contextNameToData[contextUpdatedMsg.name] = contextData; + this._contextIdToName[contextId] = contextUpdatedMsg.name; + this._contextNameToId[contextUpdatedMsg.name] = contextId; + } + else { + this._logger.error(`Received 'update' for unknown context: ${contextId}`); + } + return; + } + } + const oldContext = contextData.context; + contextData.hasReceivedSnapshot = true; + if (updatedMessageType === GW_MESSAGE_SUBSCRIBED_CONTEXT) { + contextData.context = contextUpdatedMsg.data || {}; + } + else if (updatedMessageType === GW_MESSAGE_JOINED_ACTIVITY) { + contextData.context = contextUpdatedMsg.context_snapshot || {}; + } + else if (updatedMessageType === GW_MESSAGE_CONTEXT_UPDATED) { + contextData.context = applyContextDelta(contextData.context, contextUpdatedMsg.delta, this._logger); + } + else { + throw new Error("Unrecognized context update message " + updatedMessageType); + } + if (justSeen || + !deepEqual(contextData.context, oldContext) || + updatedMessageType === GW_MESSAGE_SUBSCRIBED_CONTEXT) { + this.invokeUpdateCallbacks(contextData, contextUpdatedMsg.delta, { updaterId: contextUpdatedMsg.updater_id }); + } + } + invokeUpdateCallbacks(contextData, delta, extraData) { + delta = delta || { added: {}, updated: {}, reset: {}, removed: [] }; + if (delta.commands) { + delta.added = delta.updated = delta.reset = {}; + delta.removed = []; + for (const command of delta.commands) { + if (command.type === "remove") { + if (command.path.indexOf(".") === -1) { + delta.removed.push(command.path); + } + setValueToPath(delta.updated, null, command.path); + } + else if (command.type === "set") { + setValueToPath(delta.updated, command.value, command.path); + } + } + } + for (const updateCallbackIndex in contextData.updateCallbacks) { + if (contextData.updateCallbacks.hasOwnProperty(updateCallbackIndex)) { + try { + const updateCallback = contextData.updateCallbacks[updateCallbackIndex]; + updateCallback(deepClone(contextData.context), deepClone(Object.assign({}, delta.added || {}, delta.updated || {}, delta.reset || {})), delta.removed, parseInt(updateCallbackIndex, 10), extraData); + } + catch (err) { + this._logger.debug("callback error: " + JSON.stringify(err)); + } + } + } + } + subscribeToContextDestroyedMessages() { + const destroyedMessageTypes = [ + GW_MESSAGE_CONTEXT_DESTROYED, + GW_MESSAGE_ACTIVITY_DESTROYED, + ]; + for (const destroyedMessageType of destroyedMessageTypes) { + const sub = this._connection.on(destroyedMessageType, this.handleContextDestroyedMessage.bind(this)); + this._gw3Subscriptions.push(sub); + } + } + handleContextDestroyedMessage(destroyedMsg) { + const destroyedMessageType = destroyedMsg.type; + let contextId; + let name; + if (destroyedMessageType === GW_MESSAGE_ACTIVITY_DESTROYED) { + name = destroyedMsg.activity_id; + contextId = this._contextNameToId[name]; + if (!contextId) { + this._logger.error(`Received 'destroyed' for unknown activity: ${destroyedMsg.activity_id}`); + return; + } + } + else { + contextId = destroyedMsg.context_id; + name = this._contextIdToName[contextId]; + if (!name) { + this._logger.error(`Received 'destroyed' for unknown context: ${destroyedMsg.context_id}`); + return; + } + } + delete this._contextIdToName[contextId]; + delete this._contextNameToId[name]; + const contextData = this._contextNameToData[name]; + delete this._contextNameToData[name]; + if (!contextData || !contextData.isAnnounced) { + this._logger.error(`Received 'destroyed' for unknown context: ${contextId}`); + return; + } + } + sendSubscribe(contextData) { + contextData.sentExplicitSubscription = true; + return this._gw3Session + .send({ + type: GW_MESSAGE_SUBSCRIBE_CONTEXT, + domain: "global", + context_id: contextData.contextId, + }).then((_) => undefined); + } + sendUnsubscribe(contextData) { + contextData.sentExplicitSubscription = false; + return this._gw3Session + .send({ + type: GW_MESSAGE_UNSUBSCRIBE_CONTEXT, + domain: "global", + context_id: contextData.contextId, + }).then((_) => undefined); + } + calculateContextDeltaV1(from, to) { + const delta = { added: {}, updated: {}, removed: [], reset: undefined }; + if (from) { + for (const x of Object.keys(from)) { + if (Object.keys(to).indexOf(x) !== -1 + && to[x] !== null + && !deepEqual(from[x], to[x])) { + delta.updated[x] = to[x]; + } + } + } + for (const x of Object.keys(to)) { + if (!from || (Object.keys(from).indexOf(x) === -1)) { + if (to[x] !== null) { + delta.added[x] = to[x]; + } + } + else if (to[x] === null) { + delta.removed.push(x); + } + } + return delta; + } + calculateContextDeltaV2(from, to) { + const delta = { added: {}, updated: {}, removed: [], reset: undefined, commands: [] }; + for (const x of Object.keys(to)) { + if (to[x] !== null) { + const fromX = from ? from[x] : null; + if (!deepEqual(fromX, to[x])) { + delta.commands?.push({ type: "set", path: x, value: to[x] }); + } + } + else { + delta.commands?.push({ type: "remove", path: x }); + } + } + return delta; + } + resetState() { + for (const sub of this._gw3Subscriptions) { + this._connection.off(sub); + } + if (this._systemContextsSubKey) { + this.unsubscribe(this._systemContextsSubKey); + delete this._systemContextsSubKey; + } + this._gw3Subscriptions = []; + this._contextNameToId = {}; + this._contextIdToName = {}; + delete this._protocolVersion; + this._contextsTempCache = Object.keys(this._contextNameToData).reduce((cacheSoFar, ctxName) => { + const contextData = this._contextNameToData[ctxName]; + if (contextData.isAnnounced && (contextData.activityId || contextData.sentExplicitSubscription)) { + cacheSoFar[ctxName] = this._contextNameToData[ctxName].context; + } + return cacheSoFar; + }, {}); + this._contextNameToData = {}; + } + async reInitiateState() { + this.subscribeToContextCreatedMessages(); + this.subscribeToContextUpdatedMessages(); + this.subscribeToContextDestroyedMessages(); + this._connection.replayer?.drain(ContextMessageReplaySpec.name, (message) => { + const type = message.type; + if (!type) { + return; + } + if (type === GW_MESSAGE_CONTEXT_CREATED || + type === GW_MESSAGE_CONTEXT_ADDED || + type === GW_MESSAGE_ACTIVITY_CREATED) { + this.handleContextCreatedMessage(message); + } + else if (type === GW_MESSAGE_SUBSCRIBED_CONTEXT || + type === GW_MESSAGE_CONTEXT_UPDATED || + type === GW_MESSAGE_JOINED_ACTIVITY) { + this.handleContextUpdatedMessage(message); + } + else if (type === GW_MESSAGE_CONTEXT_DESTROYED || + type === GW_MESSAGE_ACTIVITY_DESTROYED) { + this.handleContextDestroyedMessage(message); + } + }); + await Promise.all(this._contextsSubscriptionsCache.map((subscription) => this.subscribe(subscription.contextName, subscription.callback, subscription.subKey))); + await this.flushQueue(); + for (const ctxName in this._contextsTempCache) { + if (typeof this._contextsTempCache[ctxName] !== "object" || Object.keys(this._contextsTempCache[ctxName]).length === 0) { + continue; + } + const lastKnownData = this._contextsTempCache[ctxName]; + this._logger.info(`Re-announcing known context: ${ctxName}`); + await this.flushQueue(); + await this.update(ctxName, lastKnownData); + } + this._contextsTempCache = {}; + this._logger.info("Contexts are re-announced"); + } + flushQueue() { + return new Promise((resolve) => setTimeout(() => resolve(), 0)); + } + }; + + class ContextsModule { + initTime; + initStartTime; + initEndTime; + _bridge; + constructor(config) { + this._bridge = new GW3Bridge$1(config); + } + all() { + return this._bridge.all(); + } + update(name, data) { + this.checkName(name); + this.checkData(data); + return this._bridge.update(name, data); + } + set(name, data) { + this.checkName(name); + this.checkData(data); + return this._bridge.set(name, data); + } + setPath(name, path, data) { + this.checkName(name); + this.checkPath(path); + const isTopLevelPath = path === ""; + if (isTopLevelPath) { + this.checkData(data); + return this.set(name, data); + } + return this._bridge.setPath(name, path, data); + } + setPaths(name, paths) { + this.checkName(name); + if (!Array.isArray(paths)) { + throw new Error("Please provide the paths as an array of PathValues!"); + } + for (const { path, value } of paths) { + this.checkPath(path); + const isTopLevelPath = path === ""; + if (isTopLevelPath) { + this.checkData(value); + } + } + return this._bridge.setPaths(name, paths); + } + subscribe(name, callback) { + this.checkName(name); + if (typeof callback !== "function") { + throw new Error("Please provide the callback as a function!"); + } + return this._bridge + .subscribe(name, (data, delta, removed, key, extraData) => callback(data, delta, removed, () => this._bridge.unsubscribe(key), extraData)) + .then((key) => () => { + this._bridge.unsubscribe(key); + }); + } + get(name) { + this.checkName(name); + return this._bridge.get(name); + } + ready() { + return Promise.resolve(this); + } + destroy(name) { + this.checkName(name); + return this._bridge.destroy(name); + } + get setPathSupported() { + return this._bridge.setPathSupported; + } + checkName(name) { + if (typeof name !== "string" || name === "") { + throw new Error("Please provide the name as a non-empty string!"); + } + } + checkPath(path) { + if (typeof path !== "string") { + throw new Error("Please provide the path as a dot delimited string!"); + } + } + checkData(data) { + if (typeof data !== "object") { + throw new Error("Please provide the data as an object!"); + } + } + } + + function promisify$2 (promise, successCallback, errorCallback) { + if (typeof successCallback !== "function" && typeof errorCallback !== "function") { + return promise; + } + if (typeof successCallback !== "function") { + successCallback = () => { }; + } + else if (typeof errorCallback !== "function") { + errorCallback = () => { }; + } + return promise.then(successCallback, errorCallback); + } + + function rejectAfter(ms = 0, promise, error) { + let timeout; + const clearTimeoutIfThere = () => { + if (timeout) { + clearTimeout(timeout); + } + }; + promise + .then(() => { + clearTimeoutIfThere(); + }) + .catch(() => { + clearTimeoutIfThere(); + }); + return new Promise((resolve, reject) => { + timeout = setTimeout(() => reject(error), ms); + }); + } + + var InvokeStatus; + (function (InvokeStatus) { + InvokeStatus[InvokeStatus["Success"] = 0] = "Success"; + InvokeStatus[InvokeStatus["Error"] = 1] = "Error"; + })(InvokeStatus || (InvokeStatus = {})); + class Client { + protocol; + repo; + instance; + configuration; + constructor(protocol, repo, instance, configuration) { + this.protocol = protocol; + this.repo = repo; + this.instance = instance; + this.configuration = configuration; + } + subscribe(method, options, successCallback, errorCallback, existingSub) { + const callProtocolSubscribe = (targetServers, stream, successProxy, errorProxy) => { + options.methodResponseTimeout = options.methodResponseTimeout ?? options.waitTimeoutMs; + this.protocol.client.subscribe(stream, options, targetServers, successProxy, errorProxy, existingSub); + }; + const promise = new Promise((resolve, reject) => { + const successProxy = (sub) => { + resolve(sub); + }; + const errorProxy = (err) => { + reject(err); + }; + if (!method) { + reject(`Method definition is required. Please, provide either a unique string for a method name or a “methodDefinition” object with a required “name” property.`); + return; + } + let methodDef; + if (typeof method === "string") { + methodDef = { name: method }; + } + else { + methodDef = method; + } + if (!methodDef.name) { + reject(`Method definition is required. Please, provide either a unique string for a method name or a “methodDefinition” object with a required “name” property.`); + return; + } + if (options === undefined) { + options = {}; + } + let target = options.target; + if (target === undefined) { + target = "best"; + } + if (typeof target === "string" && target !== "all" && target !== "best") { + reject(new Error(`"${target}" is not a valid target. Valid targets are "all", "best", or an instance.`)); + return; + } + if (options.methodResponseTimeout === undefined) { + options.methodResponseTimeout = options.method_response_timeout; + if (options.methodResponseTimeout === undefined) { + options.methodResponseTimeout = this.configuration.methodResponseTimeout; + } + } + if (options.waitTimeoutMs === undefined) { + options.waitTimeoutMs = options.wait_for_method_timeout; + if (options.waitTimeoutMs === undefined) { + options.waitTimeoutMs = this.configuration.waitTimeoutMs; + } + } + const delayStep = 500; + let delayTillNow = 0; + let currentServers = this.getServerMethodsByFilterAndTarget(methodDef, target); + if (currentServers.length > 0) { + callProtocolSubscribe(currentServers, currentServers[0].methods[0], successProxy, errorProxy); + } + else { + const retry = () => { + if (!target || !(options.waitTimeoutMs)) { + return; + } + delayTillNow += delayStep; + currentServers = this.getServerMethodsByFilterAndTarget(methodDef, target); + if (currentServers.length > 0) { + const streamInfo = currentServers[0].methods[0]; + callProtocolSubscribe(currentServers, streamInfo, successProxy, errorProxy); + } + else if (delayTillNow >= options.waitTimeoutMs) { + const def = typeof method === "string" ? { name: method } : method; + callProtocolSubscribe(currentServers, def, successProxy, errorProxy); + } + else { + setTimeout(retry, delayStep); + } + }; + setTimeout(retry, delayStep); + } + }); + return promisify$2(promise, successCallback, errorCallback); + } + servers(methodFilter) { + const filterCopy = methodFilter === undefined + ? undefined + : { ...methodFilter }; + return this.getServers(filterCopy).map((serverMethodMap) => { + return serverMethodMap.server.instance; + }); + } + methods(methodFilter) { + if (typeof methodFilter === "string") { + methodFilter = { name: methodFilter }; + } + else { + methodFilter = { ...methodFilter }; + } + return this.getMethods(methodFilter); + } + methodsForInstance(instance) { + return this.getMethodsForInstance(instance); + } + methodAdded(callback) { + return this.repo.onMethodAdded(callback); + } + methodRemoved(callback) { + return this.repo.onMethodRemoved(callback); + } + serverAdded(callback) { + return this.repo.onServerAdded(callback); + } + serverRemoved(callback) { + return this.repo.onServerRemoved((server, reason) => { + callback(server, reason); + }); + } + serverMethodAdded(callback) { + return this.repo.onServerMethodAdded((server, method) => { + callback({ server, method }); + }); + } + serverMethodRemoved(callback) { + return this.repo.onServerMethodRemoved((server, method) => { + callback({ server, method }); + }); + } + async invoke(methodFilter, argumentObj, target, additionalOptions, success, error) { + const getInvokePromise = async () => { + let methodDefinition; + if (typeof methodFilter === "string") { + methodDefinition = { name: methodFilter }; + } + else { + methodDefinition = { ...methodFilter }; + } + if (!methodDefinition.name) { + return Promise.reject(`Method definition is required. Please, provide either a unique string for a method name or a “methodDefinition” object with a required “name” property.`); + } + if (!argumentObj) { + argumentObj = {}; + } + if (!target) { + target = "best"; + } + if (typeof target === "string" && target !== "all" && target !== "best" && target !== "skipMine") { + return Promise.reject(new Error(`"${target}" is not a valid target. Valid targets are "all" and "best".`)); + } + if (!additionalOptions) { + additionalOptions = {}; + } + if (additionalOptions.methodResponseTimeoutMs === undefined) { + additionalOptions.methodResponseTimeoutMs = additionalOptions.method_response_timeout; + if (additionalOptions.methodResponseTimeoutMs === undefined) { + additionalOptions.methodResponseTimeoutMs = this.configuration.methodResponseTimeout; + } + } + if (additionalOptions.waitTimeoutMs === undefined) { + additionalOptions.waitTimeoutMs = additionalOptions.wait_for_method_timeout; + if (additionalOptions.waitTimeoutMs === undefined) { + additionalOptions.waitTimeoutMs = this.configuration.waitTimeoutMs; + } + } + if (additionalOptions.waitTimeoutMs !== undefined && typeof additionalOptions.waitTimeoutMs !== "number") { + return Promise.reject(new Error(`"${additionalOptions.waitTimeoutMs}" is not a valid number for "waitTimeoutMs" `)); + } + if (typeof argumentObj !== "object") { + return Promise.reject(new Error(`The method arguments must be an object. method: ${methodDefinition.name}`)); + } + let serversMethodMap = this.getServerMethodsByFilterAndTarget(methodDefinition, target); + if (serversMethodMap.length === 0) { + try { + serversMethodMap = await this.tryToAwaitForMethods(methodDefinition, target, additionalOptions); + } + catch (err) { + const method = { + ...methodDefinition, + getServers: () => [], + supportsStreaming: false, + objectTypes: methodDefinition.objectTypes ?? [], + flags: methodDefinition.flags?.metadata ?? {} + }; + const errorObj = { + method, + called_with: argumentObj, + message: `Can not find a method matching ${JSON.stringify(methodFilter)} with server filter ${JSON.stringify(target)}`, + executed_by: undefined, + returned: undefined, + status: undefined, + }; + return Promise.reject(errorObj); + } + } + const timeout = additionalOptions.methodResponseTimeoutMs; + const additionalOptionsCopy = additionalOptions; + const invokePromises = serversMethodMap.map((serversMethodPair) => { + const invId = nanoid$1(10); + const method = serversMethodPair.methods[0]; + const server = serversMethodPair.server; + const invokePromise = this.protocol.client.invoke(invId, method, argumentObj, server, additionalOptionsCopy); + return Promise.race([ + invokePromise, + rejectAfter(timeout, invokePromise, { + invocationId: invId, + message: `Invocation timeout (${timeout} ms) reached for method name: ${method?.name}, target instance: ${JSON.stringify(server.instance)}, options: ${JSON.stringify(additionalOptionsCopy)}`, + status: InvokeStatus.Error, + }) + ]); + }); + const invocationMessages = await Promise.all(invokePromises); + const results = this.getInvocationResultObj(invocationMessages, methodDefinition, argumentObj); + const allRejected = invocationMessages.every((result) => result.status === InvokeStatus.Error); + if (allRejected) { + return Promise.reject(results); + } + return results; + }; + return promisify$2(getInvokePromise(), success, error); + } + getInvocationResultObj(invocationResults, method, calledWith) { + const all_return_values = invocationResults + .filter((invokeMessage) => invokeMessage.status === InvokeStatus.Success) + .reduce((allValues, currentValue) => { + allValues = [ + ...allValues, + { + executed_by: currentValue.instance, + returned: currentValue.result, + called_with: calledWith, + method, + message: currentValue.message, + status: currentValue.status, + } + ]; + return allValues; + }, []); + const all_errors = invocationResults + .filter((invokeMessage) => invokeMessage.status === InvokeStatus.Error) + .reduce((allErrors, currError) => { + allErrors = [ + ...allErrors, + { + executed_by: currError.instance, + called_with: calledWith, + name: method.name, + message: currError.message, + } + ]; + return allErrors; + }, []); + const invResult = invocationResults[0]; + const result = { + method, + called_with: calledWith, + returned: invResult.result, + executed_by: invResult.instance, + all_return_values, + all_errors, + message: invResult.message, + status: invResult.status + }; + return result; + } + tryToAwaitForMethods(methodDefinition, target, additionalOptions) { + return new Promise((resolve, reject) => { + if (additionalOptions.waitTimeoutMs === 0) { + reject(); + return; + } + const delayStep = 500; + let delayTillNow = 0; + const retry = () => { + delayTillNow += delayStep; + const serversMethodMap = this.getServerMethodsByFilterAndTarget(methodDefinition, target); + if (serversMethodMap.length > 0) { + clearInterval(interval); + resolve(serversMethodMap); + } + else if (delayTillNow >= (additionalOptions.waitTimeoutMs || 10000)) { + clearInterval(interval); + reject(); + return; + } + }; + const interval = setInterval(retry, delayStep); + }); + } + filterByTarget(target, serverMethodMap) { + if (typeof target === "string") { + if (target === "all") { + return [...serverMethodMap]; + } + else if (target === "best") { + const localMachine = serverMethodMap + .find((s) => s.server.instance.isLocal); + if (localMachine) { + return [localMachine]; + } + if (serverMethodMap[0] !== undefined) { + return [serverMethodMap[0]]; + } + } + else if (target === "skipMine") { + return serverMethodMap.filter(({ server }) => server.instance.peerId !== this.instance.peerId); + } + } + else { + let targetArray; + if (!Array.isArray(target)) { + targetArray = [target]; + } + else { + targetArray = target; + } + const allServersMatching = targetArray.reduce((matches, filter) => { + const myMatches = serverMethodMap.filter((serverMethodPair) => { + return this.instanceMatch(filter, serverMethodPair.server.instance); + }); + return matches.concat(myMatches); + }, []); + return allServersMatching; + } + return []; + } + instanceMatch(instanceFilter, instanceDefinition) { + if (instanceFilter?.peerId && instanceFilter?.instance) { + instanceFilter = { ...instanceFilter }; + delete instanceFilter.peerId; + } + return this.containsProps(instanceFilter, instanceDefinition); + } + methodMatch(methodFilter, methodDefinition) { + return this.containsProps(methodFilter, methodDefinition); + } + containsProps(filter, repoMethod) { + const filterProps = Object.keys(filter) + .filter((prop) => { + return filter[prop] !== undefined + && filter[prop] !== null + && typeof filter[prop] !== "function" + && prop !== "object_types" + && prop !== "display_name" + && prop !== "id" + && prop !== "gatewayId" + && prop !== "identifier" + && prop[0] !== "_"; + }); + return filterProps.every((prop) => { + let isMatch; + const filterValue = filter[prop]; + const repoMethodValue = repoMethod[prop]; + switch (prop) { + case "objectTypes": + isMatch = (filterValue || []).every((filterValueEl) => { + return (repoMethodValue || []).includes(filterValueEl); + }); + break; + case "flags": + isMatch = isSubset(repoMethodValue || {}, filterValue || {}); + break; + default: + isMatch = String(filterValue).toLowerCase() === String(repoMethodValue).toLowerCase(); + } + return isMatch; + }); + } + getMethods(methodFilter) { + if (methodFilter === undefined) { + return this.repo.getMethods(); + } + const methods = this.repo.getMethods().filter((method) => { + return this.methodMatch(methodFilter, method); + }); + return methods; + } + getMethodsForInstance(instanceFilter) { + const allServers = this.repo.getServers(); + const matchingServers = allServers.filter((server) => { + return this.instanceMatch(instanceFilter, server.instance); + }); + if (matchingServers.length === 0) { + return []; + } + let resultMethodsObject = {}; + if (matchingServers.length === 1) { + resultMethodsObject = matchingServers[0].methods; + } + else { + matchingServers.forEach((server) => { + Object.keys(server.methods).forEach((methodKey) => { + const method = server.methods[methodKey]; + resultMethodsObject[method.identifier] = method; + }); + }); + } + return Object.keys(resultMethodsObject) + .map((key) => { + return resultMethodsObject[key]; + }); + } + getServers(methodFilter) { + const servers = this.repo.getServers(); + if (methodFilter === undefined) { + return servers.map((server) => { + return { server, methods: [] }; + }); + } + return servers.reduce((prev, current) => { + const methodsForServer = Object.values(current.methods); + const matchingMethods = methodsForServer.filter((method) => { + return this.methodMatch(methodFilter, method); + }); + if (matchingMethods.length > 0) { + prev.push({ server: current, methods: matchingMethods }); + } + return prev; + }, []); + } + getServerMethodsByFilterAndTarget(methodFilter, target) { + const serversMethodMap = this.getServers(methodFilter); + return this.filterByTarget(target, serversMethodMap); + } + } + + class ServerSubscription { + protocol; + repoMethod; + subscription; + constructor(protocol, repoMethod, subscription) { + this.protocol = protocol; + this.repoMethod = repoMethod; + this.subscription = subscription; + } + get stream() { + if (!this.repoMethod.stream) { + throw new Error("no stream"); + } + return this.repoMethod.stream; + } + get arguments() { return this.subscription.arguments || {}; } + get branchKey() { return this.subscription.branchKey; } + get instance() { + if (!this.subscription.instance) { + throw new Error("no instance"); + } + return this.subscription.instance; + } + close() { + this.protocol.server.closeSingleSubscription(this.repoMethod, this.subscription); + } + push(data) { + this.protocol.server.pushDataToSingle(this.repoMethod, this.subscription, data); + } + } + + class Request { + protocol; + repoMethod; + requestContext; + arguments; + instance; + constructor(protocol, repoMethod, requestContext) { + this.protocol = protocol; + this.repoMethod = repoMethod; + this.requestContext = requestContext; + this.arguments = requestContext.arguments; + this.instance = requestContext.instance; + } + accept() { + this.protocol.server.acceptRequestOnBranch(this.requestContext, this.repoMethod, ""); + } + acceptOnBranch(branch) { + this.protocol.server.acceptRequestOnBranch(this.requestContext, this.repoMethod, branch); + } + reject(reason) { + this.protocol.server.rejectRequest(this.requestContext, this.repoMethod, reason); + } + } + + let ServerStreaming$1 = class ServerStreaming { + protocol; + server; + constructor(protocol, server) { + this.protocol = protocol; + this.server = server; + protocol.server.onSubRequest((rc, rm) => this.handleSubRequest(rc, rm)); + protocol.server.onSubAdded((sub, rm) => this.handleSubAdded(sub, rm)); + protocol.server.onSubRemoved((sub, rm) => this.handleSubRemoved(sub, rm)); + } + handleSubRequest(requestContext, repoMethod) { + if (!(repoMethod && + repoMethod.streamCallbacks && + typeof repoMethod.streamCallbacks.subscriptionRequestHandler === "function")) { + return; + } + const request = new Request(this.protocol, repoMethod, requestContext); + repoMethod.streamCallbacks.subscriptionRequestHandler(request); + } + handleSubAdded(subscription, repoMethod) { + if (!(repoMethod && + repoMethod.streamCallbacks && + typeof repoMethod.streamCallbacks.subscriptionAddedHandler === "function")) { + return; + } + const sub = new ServerSubscription(this.protocol, repoMethod, subscription); + repoMethod.streamCallbacks.subscriptionAddedHandler(sub); + } + handleSubRemoved(subscription, repoMethod) { + if (!(repoMethod && + repoMethod.streamCallbacks && + typeof repoMethod.streamCallbacks.subscriptionRemovedHandler === "function")) { + return; + } + const sub = new ServerSubscription(this.protocol, repoMethod, subscription); + repoMethod.streamCallbacks.subscriptionRemovedHandler(sub); + } + }; + + class ServerBranch { + key; + protocol; + repoMethod; + constructor(key, protocol, repoMethod) { + this.key = key; + this.protocol = protocol; + this.repoMethod = repoMethod; + } + subscriptions() { + const subList = this.protocol.server.getSubscriptionList(this.repoMethod, this.key); + return subList.map((sub) => { + return new ServerSubscription(this.protocol, this.repoMethod, sub); + }); + } + close() { + this.protocol.server.closeAllSubscriptions(this.repoMethod, this.key); + } + push(data) { + this.protocol.server.pushData(this.repoMethod, data, [this.key]); + } + } + + class ServerStream { + _protocol; + _repoMethod; + _server; + name; + constructor(_protocol, _repoMethod, _server) { + this._protocol = _protocol; + this._repoMethod = _repoMethod; + this._server = _server; + this.name = this._repoMethod.definition.name; + } + branches(key) { + const bList = this._protocol.server.getBranchList(this._repoMethod); + if (key) { + if (bList.indexOf(key) > -1) { + return new ServerBranch(key, this._protocol, this._repoMethod); + } + return undefined; + } + else { + return bList.map((branchKey) => { + return new ServerBranch(branchKey, this._protocol, this._repoMethod); + }); + } + } + branch(key) { + return this.branches(key); + } + subscriptions() { + const subList = this._protocol.server.getSubscriptionList(this._repoMethod); + return subList.map((sub) => { + return new ServerSubscription(this._protocol, this._repoMethod, sub); + }); + } + get definition() { + const def2 = this._repoMethod.definition; + return { + accepts: def2.accepts, + description: def2.description, + displayName: def2.displayName, + name: def2.name, + objectTypes: def2.objectTypes, + returns: def2.returns, + supportsStreaming: def2.supportsStreaming, + flags: def2.flags?.metadata, + }; + } + close() { + this._protocol.server.closeAllSubscriptions(this._repoMethod); + this._server.unregister(this._repoMethod.definition, true); + } + push(data, branches) { + if (typeof branches !== "string" && !Array.isArray(branches) && branches !== undefined) { + throw new Error("invalid branches should be string or string array"); + } + if (typeof data !== "object") { + throw new Error("Invalid arguments. Data must be an object."); + } + this._protocol.server.pushData(this._repoMethod, data, branches); + } + updateRepoMethod(repoMethod) { + this._repoMethod = repoMethod; + } + } + + class Server { + protocol; + serverRepository; + streaming; + invocations = 0; + currentlyUnregistering = {}; + constructor(protocol, serverRepository) { + this.protocol = protocol; + this.serverRepository = serverRepository; + this.streaming = new ServerStreaming$1(protocol, this); + this.protocol.server.onInvoked(this.onMethodInvoked.bind(this)); + } + createStream(streamDef, callbacks, successCallback, errorCallback, existingStream) { + const promise = new Promise((resolve, reject) => { + if (!streamDef) { + reject("The stream name must be unique! Please, provide either a unique string for a stream name to “glue.interop.createStream()” or a “methodDefinition” object with a unique “name” property for the stream."); + return; + } + let streamMethodDefinition; + if (typeof streamDef === "string") { + streamMethodDefinition = { name: "" + streamDef }; + } + else { + streamMethodDefinition = { ...streamDef }; + } + if (!streamMethodDefinition.name) { + return reject(`The “name” property is required for the “streamDefinition” object and must be unique. Stream definition: ${JSON.stringify(streamMethodDefinition)}`); + } + const nameAlreadyExists = this.serverRepository.getList() + .some((serverMethod) => serverMethod.definition.name === streamMethodDefinition.name); + if (nameAlreadyExists) { + return reject(`A stream with the name "${streamMethodDefinition.name}" already exists! Please, provide a unique name for the stream.`); + } + streamMethodDefinition.supportsStreaming = true; + if (!callbacks) { + callbacks = {}; + } + if (typeof callbacks.subscriptionRequestHandler !== "function") { + callbacks.subscriptionRequestHandler = (request) => { + request.accept(); + }; + } + const repoMethod = this.serverRepository.add({ + definition: streamMethodDefinition, + streamCallbacks: callbacks, + protocolState: {}, + }); + this.protocol.server.createStream(repoMethod) + .then(() => { + let streamUserObject; + if (existingStream) { + streamUserObject = existingStream; + existingStream.updateRepoMethod(repoMethod); + } + else { + streamUserObject = new ServerStream(this.protocol, repoMethod, this); + } + repoMethod.stream = streamUserObject; + resolve(streamUserObject); + }) + .catch((err) => { + if (repoMethod.repoId) { + this.serverRepository.remove(repoMethod.repoId); + } + reject(err); + }); + }); + return promisify$2(promise, successCallback, errorCallback); + } + register(methodDefinition, callback) { + if (!methodDefinition) { + return Promise.reject("Method definition is required. Please, provide either a unique string for a method name or a “methodDefinition” object with a required “name” property."); + } + if (typeof callback !== "function") { + return Promise.reject(`The second parameter must be a callback function. Method: ${typeof methodDefinition === "string" ? methodDefinition : methodDefinition.name}`); + } + const wrappedCallbackFunction = async (context, resultCallback) => { + try { + const result = callback(context.args, context.instance); + if (result && typeof result.then === "function") { + const resultValue = await result; + resultCallback(undefined, resultValue); + } + else { + resultCallback(undefined, result); + } + } + catch (e) { + resultCallback(e ?? "", e ?? ""); + } + }; + wrappedCallbackFunction.userCallback = callback; + return this.registerCore(methodDefinition, wrappedCallbackFunction); + } + registerAsync(methodDefinition, callback) { + if (!methodDefinition) { + return Promise.reject("Method definition is required. Please, provide either a unique string for a method name or a “methodDefinition” object with a required “name” property."); + } + if (typeof callback !== "function") { + return Promise.reject(`The second parameter must be a callback function. Method: ${typeof methodDefinition === "string" ? methodDefinition : methodDefinition.name}`); + } + const wrappedCallback = async (context, resultCallback) => { + try { + let resultCalled = false; + const success = (result) => { + if (!resultCalled) { + resultCallback(undefined, result); + } + resultCalled = true; + }; + const error = (e) => { + if (!resultCalled) { + if (!e) { + e = ""; + } + resultCallback(e, e); + } + resultCalled = true; + }; + const methodResult = callback(context.args, context.instance, success, error); + if (methodResult && typeof methodResult.then === "function") { + methodResult + .then(success) + .catch(error); + } + } + catch (e) { + resultCallback(e, undefined); + } + }; + wrappedCallback.userCallbackAsync = callback; + return this.registerCore(methodDefinition, wrappedCallback); + } + async unregister(methodFilter, forStream = false) { + if (methodFilter === undefined) { + return Promise.reject("Please, provide either a unique string for a name or an object containing a “name” property."); + } + if (typeof methodFilter === "function") { + await this.unregisterWithPredicate(methodFilter, forStream); + return; + } + let methodDefinition; + if (typeof methodFilter === "string") { + methodDefinition = { name: methodFilter }; + } + else { + methodDefinition = methodFilter; + } + if (methodDefinition.name === undefined) { + return Promise.reject("Method name is required. Cannot find a method if the method name is undefined!"); + } + const methodToBeRemoved = this.serverRepository.getList().find((serverMethod) => { + return serverMethod.definition.name === methodDefinition.name + && (serverMethod.definition.supportsStreaming || false) === forStream; + }); + if (!methodToBeRemoved) { + return Promise.reject(`Method with a name "${methodDefinition.name}" does not exist or is not registered by your application!`); + } + await this.removeMethodsOrStreams([methodToBeRemoved]); + } + async unregisterWithPredicate(filterPredicate, forStream) { + const methodsOrStreamsToRemove = this.serverRepository.getList() + .filter((sm) => filterPredicate(sm.definition)) + .filter((serverMethod) => (serverMethod.definition.supportsStreaming || false) === forStream); + if (!methodsOrStreamsToRemove || methodsOrStreamsToRemove.length === 0) { + return Promise.reject(`Could not find a ${forStream ? "stream" : "method"} matching the specified condition!`); + } + await this.removeMethodsOrStreams(methodsOrStreamsToRemove); + } + removeMethodsOrStreams(methodsToRemove) { + const methodUnregPromises = []; + methodsToRemove.forEach((method) => { + const promise = this.protocol.server.unregister(method) + .then(() => { + if (method.repoId) { + this.serverRepository.remove(method.repoId); + } + }); + methodUnregPromises.push(promise); + this.addAsCurrentlyUnregistering(method.definition.name, promise); + }); + return Promise.all(methodUnregPromises); + } + async addAsCurrentlyUnregistering(methodName, promise) { + const timeout = new Promise((resolve) => setTimeout(resolve, 5000)); + this.currentlyUnregistering[methodName] = Promise.race([promise, timeout]).then(() => { + delete this.currentlyUnregistering[methodName]; + }); + } + async registerCore(method, theFunction) { + let methodDefinition; + if (typeof method === "string") { + methodDefinition = { name: "" + method }; + } + else { + methodDefinition = { ...method }; + } + if (!methodDefinition.name) { + return Promise.reject(`Please, provide a (unique) string value for the “name” property in the “methodDefinition” object: ${JSON.stringify(method)}`); + } + const unregisterInProgress = this.currentlyUnregistering[methodDefinition.name]; + if (typeof unregisterInProgress !== "undefined") { + await unregisterInProgress; + } + const nameAlreadyExists = this.serverRepository.getList() + .some((serverMethod) => serverMethod.definition.name === methodDefinition.name); + if (nameAlreadyExists) { + return Promise.reject(`A method with the name "${methodDefinition.name}" already exists! Please, provide a unique name for the method.`); + } + if (methodDefinition.supportsStreaming) { + return Promise.reject(`When you create methods with “glue.interop.register()” or “glue.interop.registerAsync()” the property “supportsStreaming” cannot be “true”. If you want “${methodDefinition.name}” to be a stream, please use the “glue.interop.createStream()” method.`); + } + const repoMethod = this.serverRepository.add({ + definition: methodDefinition, + theFunction, + protocolState: {}, + }); + return this.protocol.server.register(repoMethod) + .catch((err) => { + if (repoMethod?.repoId) { + this.serverRepository.remove(repoMethod.repoId); + } + throw err; + }); + } + onMethodInvoked(methodToExecute, invocationId, invocationArgs) { + if (!methodToExecute || !methodToExecute.theFunction) { + return; + } + methodToExecute.theFunction(invocationArgs, (err, result) => { + if (err !== undefined && err !== null) { + if (err.message && typeof err.message === "string") { + err = err.message; + } + else if (typeof err !== "string") { + try { + err = JSON.stringify(err); + } + catch (unStrException) { + err = `un-stringifyable error in onMethodInvoked! Top level prop names: ${Object.keys(err)}`; + } + } + } + if (!result) { + result = {}; + } + else if (typeof result !== "object" || Array.isArray(result)) { + result = { _value: result }; + } + this.protocol.server.methodInvocationResult(methodToExecute, invocationId, err, result); + }); + } + } + + class InstanceWrapper { + wrapped = {}; + constructor(API, instance, connection) { + this.wrapped.getMethods = function () { + return API.methodsForInstance(this); + }; + this.wrapped.getStreams = function () { + return API.methodsForInstance(this).filter((m) => m.supportsStreaming); + }; + if (instance) { + this.refreshWrappedObject(instance); + } + if (connection) { + connection.loggedIn(() => { + this.refresh(connection); + }); + this.refresh(connection); + } + } + unwrap() { + return this.wrapped; + } + refresh(connection) { + if (!connection) { + return; + } + const resolvedIdentity = connection?.resolvedIdentity; + const instance = Object.assign({}, resolvedIdentity ?? {}, { peerId: connection?.peerId }); + this.refreshWrappedObject(instance); + } + refreshWrappedObject(resolvedIdentity) { + Object.keys(resolvedIdentity).forEach((key) => { + this.wrapped[key] = resolvedIdentity[key]; + }); + this.wrapped.user = resolvedIdentity.user; + this.wrapped.instance = resolvedIdentity.instance; + this.wrapped.application = resolvedIdentity.application ?? nanoid$1(10); + this.wrapped.applicationName = resolvedIdentity.applicationName; + this.wrapped.pid = resolvedIdentity.pid ?? resolvedIdentity.process ?? Math.floor(Math.random() * 10000000000); + this.wrapped.machine = resolvedIdentity.machine; + this.wrapped.environment = resolvedIdentity.environment; + this.wrapped.region = resolvedIdentity.region; + this.wrapped.windowId = resolvedIdentity.windowId; + this.wrapped.isLocal = resolvedIdentity.isLocal ?? true; + this.wrapped.api = resolvedIdentity.api; + this.wrapped.service = resolvedIdentity.service; + this.wrapped.peerId = resolvedIdentity.peerId; + } + } + + const hideMethodSystemFlags = (method) => { + return { + ...method, + flags: method.flags.metadata || {} + }; + }; + class ClientRepository { + logger; + API; + servers = {}; + myServer; + methodsCount = {}; + callbacks = CallbackRegistryFactory$1(); + constructor(logger, API) { + this.logger = logger; + this.API = API; + const peerId = this.API.instance.peerId; + this.myServer = { + id: peerId, + methods: {}, + instance: this.API.instance, + wrapper: this.API.unwrappedInstance, + }; + this.servers[peerId] = this.myServer; + } + addServer(info, serverId) { + this.logger.debug(`adding server ${serverId}`); + const current = this.servers[serverId]; + if (current) { + return current.id; + } + const wrapper = new InstanceWrapper(this.API, info); + const serverEntry = { + id: serverId, + methods: {}, + instance: wrapper.unwrap(), + wrapper, + }; + this.servers[serverId] = serverEntry; + this.callbacks.execute("onServerAdded", serverEntry.instance); + return serverId; + } + removeServerById(id, reason) { + const server = this.servers[id]; + if (!server) { + this.logger.warn(`not aware of server ${id}, my state ${JSON.stringify(Object.keys(this.servers))}`); + return; + } + else { + this.logger.debug(`removing server ${id}`); + } + Object.keys(server.methods).forEach((methodId) => { + this.removeServerMethod(id, methodId); + }); + delete this.servers[id]; + this.callbacks.execute("onServerRemoved", server.instance, reason); + } + addServerMethod(serverId, method) { + const server = this.servers[serverId]; + if (!server) { + throw new Error("server does not exists"); + } + if (server.methods[method.id]) { + return; + } + const identifier = this.createMethodIdentifier(method); + const that = this; + const methodDefinition = { + identifier, + gatewayId: method.id, + name: method.name, + displayName: method.display_name, + description: method.description, + version: method.version, + objectTypes: method.object_types || [], + accepts: method.input_signature, + returns: method.result_signature, + supportsStreaming: typeof method.flags !== "undefined" ? method.flags.streaming : false, + flags: method.flags ?? {}, + getServers: () => { + return that.getServersByMethod(identifier); + } + }; + methodDefinition.object_types = methodDefinition.objectTypes; + methodDefinition.display_name = methodDefinition.displayName; + methodDefinition.version = methodDefinition.version; + server.methods[method.id] = methodDefinition; + const clientMethodDefinition = hideMethodSystemFlags(methodDefinition); + if (!this.methodsCount[identifier]) { + this.methodsCount[identifier] = 0; + this.callbacks.execute("onMethodAdded", clientMethodDefinition); + } + this.methodsCount[identifier] = this.methodsCount[identifier] + 1; + this.callbacks.execute("onServerMethodAdded", server.instance, clientMethodDefinition); + return methodDefinition; + } + removeServerMethod(serverId, methodId) { + const server = this.servers[serverId]; + if (!server) { + throw new Error("server does not exists"); + } + const method = server.methods[methodId]; + delete server.methods[methodId]; + const clientMethodDefinition = hideMethodSystemFlags(method); + this.methodsCount[method.identifier] = this.methodsCount[method.identifier] - 1; + if (this.methodsCount[method.identifier] === 0) { + this.callbacks.execute("onMethodRemoved", clientMethodDefinition); + } + this.callbacks.execute("onServerMethodRemoved", server.instance, clientMethodDefinition); + } + getMethods() { + return this.extractMethodsFromServers(Object.values(this.servers)).map(hideMethodSystemFlags); + } + getServers() { + return Object.values(this.servers).map(this.hideServerMethodSystemFlags); + } + onServerAdded(callback) { + const unsubscribeFunc = this.callbacks.add("onServerAdded", callback); + const serversWithMethodsToReplay = this.getServers().map((s) => s.instance); + return this.returnUnsubWithDelayedReplay(unsubscribeFunc, serversWithMethodsToReplay, callback); + } + onMethodAdded(callback) { + const unsubscribeFunc = this.callbacks.add("onMethodAdded", callback); + const methodsToReplay = this.getMethods(); + return this.returnUnsubWithDelayedReplay(unsubscribeFunc, methodsToReplay, callback); + } + onServerMethodAdded(callback) { + const unsubscribeFunc = this.callbacks.add("onServerMethodAdded", callback); + let unsubCalled = false; + const servers = this.getServers(); + setTimeout(() => { + servers.forEach((server) => { + const methods = server.methods; + Object.keys(methods).forEach((methodId) => { + if (!unsubCalled) { + callback(server.instance, methods[methodId]); + } + }); + }); + }, 0); + return () => { + unsubCalled = true; + unsubscribeFunc(); + }; + } + onMethodRemoved(callback) { + const unsubscribeFunc = this.callbacks.add("onMethodRemoved", callback); + return unsubscribeFunc; + } + onServerRemoved(callback) { + const unsubscribeFunc = this.callbacks.add("onServerRemoved", callback); + return unsubscribeFunc; + } + onServerMethodRemoved(callback) { + const unsubscribeFunc = this.callbacks.add("onServerMethodRemoved", callback); + return unsubscribeFunc; + } + getServerById(id) { + const server = this.servers[id]; + if (!server) { + return undefined; + } + return this.hideServerMethodSystemFlags(this.servers[id]); + } + reset() { + Object.keys(this.servers).forEach((key) => { + this.removeServerById(key, "reset"); + }); + this.servers = { + [this.myServer.id]: this.myServer + }; + this.methodsCount = {}; + } + createMethodIdentifier(methodInfo) { + const accepts = methodInfo.input_signature ?? ""; + const returns = methodInfo.result_signature ?? ""; + return (methodInfo.name + accepts + returns).toLowerCase(); + } + getServersByMethod(identifier) { + const allServers = []; + Object.values(this.servers).forEach((server) => { + Object.values(server.methods).forEach((method) => { + if (method.identifier === identifier) { + allServers.push(server.instance); + } + }); + }); + return allServers; + } + returnUnsubWithDelayedReplay(unsubscribeFunc, collectionToReplay, callback) { + let unsubCalled = false; + setTimeout(() => { + collectionToReplay.forEach((item) => { + if (!unsubCalled) { + callback(item); + } + }); + }, 0); + return () => { + unsubCalled = true; + unsubscribeFunc(); + }; + } + hideServerMethodSystemFlags(server) { + const clientMethods = {}; + Object.entries(server.methods).forEach(([name, method]) => { + clientMethods[name] = hideMethodSystemFlags(method); + }); + return { + ...server, + methods: clientMethods + }; + } + extractMethodsFromServers(servers) { + const methods = Object.values(servers).reduce((clientMethods, server) => { + return [...clientMethods, ...Object.values(server.methods)]; + }, []); + return methods; + } + } + + class ServerRepository { + nextId = 0; + methods = []; + add(method) { + method.repoId = String(this.nextId); + this.nextId += 1; + this.methods.push(method); + return method; + } + remove(repoId) { + if (typeof repoId !== "string") { + return new TypeError("Expecting a string"); + } + this.methods = this.methods.filter((m) => { + return m.repoId !== repoId; + }); + } + getById(id) { + if (typeof id !== "string") { + return undefined; + } + return this.methods.find((m) => { + return m.repoId === id; + }); + } + getList() { + return this.methods.map((m) => m); + } + length() { + return this.methods.length; + } + reset() { + this.methods = []; + } + } + + const SUBSCRIPTION_REQUEST = "onSubscriptionRequest"; + const SUBSCRIPTION_ADDED = "onSubscriptionAdded"; + const SUBSCRIPTION_REMOVED = "onSubscriptionRemoved"; + class ServerStreaming { + session; + repository; + serverRepository; + ERR_URI_SUBSCRIPTION_FAILED = "com.tick42.agm.errors.subscription.failure"; + callbacks = CallbackRegistryFactory$1(); + nextStreamId = 0; + constructor(session, repository, serverRepository) { + this.session = session; + this.repository = repository; + this.serverRepository = serverRepository; + session.on("add-interest", (msg) => { + this.handleAddInterest(msg); + }); + session.on("remove-interest", (msg) => { + this.handleRemoveInterest(msg); + }); + } + acceptRequestOnBranch(requestContext, streamingMethod, branch) { + if (typeof branch !== "string") { + branch = ""; + } + if (typeof streamingMethod.protocolState.subscriptionsMap !== "object") { + throw new TypeError("The streaming method is missing its subscriptions."); + } + if (!Array.isArray(streamingMethod.protocolState.branchKeyToStreamIdMap)) { + throw new TypeError("The streaming method is missing its branches."); + } + const streamId = this.getStreamId(streamingMethod, branch); + const key = requestContext.msg.subscription_id; + const subscription = { + id: key, + arguments: requestContext.arguments, + instance: requestContext.instance, + branchKey: branch, + streamId, + subscribeMsg: requestContext.msg, + }; + streamingMethod.protocolState.subscriptionsMap[key] = subscription; + this.session.sendFireAndForget({ + type: "accepted", + subscription_id: key, + stream_id: streamId, + }); + this.callbacks.execute(SUBSCRIPTION_ADDED, subscription, streamingMethod); + } + rejectRequest(requestContext, streamingMethod, reason) { + if (typeof reason !== "string") { + reason = ""; + } + this.sendSubscriptionFailed("Subscription rejected by user. " + reason, requestContext.msg.subscription_id); + } + pushData(streamingMethod, data, branches) { + if (typeof streamingMethod !== "object" || !Array.isArray(streamingMethod.protocolState.branchKeyToStreamIdMap)) { + return; + } + if (typeof data !== "object") { + throw new Error("Invalid arguments. Data must be an object."); + } + if (typeof branches === "string") { + branches = [branches]; + } + else if (!Array.isArray(branches) || branches.length <= 0) { + branches = []; + } + const streamIdList = streamingMethod.protocolState.branchKeyToStreamIdMap + .filter((br) => { + if (!branches || branches.length === 0) { + return true; + } + return branches.indexOf(br.key) >= 0; + }).map((br) => { + return br.streamId; + }); + streamIdList.forEach((streamId) => { + const publishMessage = { + type: "publish", + stream_id: streamId, + data, + }; + this.session.sendFireAndForget(publishMessage); + }); + } + pushDataToSingle(method, subscription, data) { + if (typeof data !== "object") { + throw new Error("Invalid arguments. Data must be an object."); + } + const postMessage = { + type: "post", + subscription_id: subscription.id, + data, + }; + this.session.sendFireAndForget(postMessage); + } + closeSingleSubscription(streamingMethod, subscription) { + if (streamingMethod.protocolState.subscriptionsMap) { + delete streamingMethod.protocolState.subscriptionsMap[subscription.id]; + } + const dropSubscriptionMessage = { + type: "drop-subscription", + subscription_id: subscription.id, + reason: "Server dropping a single subscription", + }; + this.session.sendFireAndForget(dropSubscriptionMessage); + subscription.instance; + this.callbacks.execute(SUBSCRIPTION_REMOVED, subscription, streamingMethod); + } + closeMultipleSubscriptions(streamingMethod, branchKey) { + if (typeof streamingMethod !== "object" || typeof streamingMethod.protocolState.subscriptionsMap !== "object") { + return; + } + if (!streamingMethod.protocolState.subscriptionsMap) { + return; + } + const subscriptionsMap = streamingMethod.protocolState.subscriptionsMap; + let subscriptionsToClose = Object.keys(subscriptionsMap) + .map((key) => { + return subscriptionsMap[key]; + }); + if (typeof branchKey === "string") { + subscriptionsToClose = subscriptionsToClose.filter((sub) => { + return sub.branchKey === branchKey; + }); + } + subscriptionsToClose.forEach((subscription) => { + delete subscriptionsMap[subscription.id]; + const drop = { + type: "drop-subscription", + subscription_id: subscription.id, + reason: "Server dropping all subscriptions on stream_id: " + subscription.streamId, + }; + this.session.sendFireAndForget(drop); + }); + } + getSubscriptionList(streamingMethod, branchKey) { + if (typeof streamingMethod !== "object") { + return []; + } + let subscriptions = []; + if (!streamingMethod.protocolState.subscriptionsMap) { + return []; + } + const subscriptionsMap = streamingMethod.protocolState.subscriptionsMap; + const allSubscriptions = Object.keys(subscriptionsMap) + .map((key) => { + return subscriptionsMap[key]; + }); + if (typeof branchKey !== "string") { + subscriptions = allSubscriptions; + } + else { + subscriptions = allSubscriptions.filter((sub) => { + return sub.branchKey === branchKey; + }); + } + return subscriptions; + } + getBranchList(streamingMethod) { + if (typeof streamingMethod !== "object") { + return []; + } + if (!streamingMethod.protocolState.subscriptionsMap) { + return []; + } + const subscriptionsMap = streamingMethod.protocolState.subscriptionsMap; + const allSubscriptions = Object.keys(subscriptionsMap) + .map((key) => { + return subscriptionsMap[key]; + }); + const result = []; + allSubscriptions.forEach((sub) => { + let branch = ""; + if (typeof sub === "object" && typeof sub.branchKey === "string") { + branch = sub.branchKey; + } + if (result.indexOf(branch) === -1) { + result.push(branch); + } + }); + return result; + } + onSubAdded(callback) { + this.onSubscriptionLifetimeEvent(SUBSCRIPTION_ADDED, callback); + } + onSubRequest(callback) { + this.onSubscriptionLifetimeEvent(SUBSCRIPTION_REQUEST, callback); + } + onSubRemoved(callback) { + this.onSubscriptionLifetimeEvent(SUBSCRIPTION_REMOVED, callback); + } + handleRemoveInterest(msg) { + const streamingMethod = this.serverRepository.getById(msg.method_id); + if (typeof msg.subscription_id !== "string" || + typeof streamingMethod !== "object") { + return; + } + if (!streamingMethod.protocolState.subscriptionsMap) { + return; + } + if (typeof streamingMethod.protocolState.subscriptionsMap[msg.subscription_id] !== "object") { + return; + } + const subscription = streamingMethod.protocolState.subscriptionsMap[msg.subscription_id]; + delete streamingMethod.protocolState.subscriptionsMap[msg.subscription_id]; + this.callbacks.execute(SUBSCRIPTION_REMOVED, subscription, streamingMethod); + } + onSubscriptionLifetimeEvent(eventName, handlerFunc) { + this.callbacks.add(eventName, handlerFunc); + } + getNextStreamId() { + return this.nextStreamId++ + ""; + } + handleAddInterest(msg) { + const caller = this.repository.getServerById(msg.caller_id); + const instance = caller?.instance ?? {}; + const requestContext = { + msg, + arguments: msg.arguments_kv || {}, + instance, + }; + const streamingMethod = this.serverRepository.getById(msg.method_id); + if (streamingMethod === undefined) { + const errorMsg = "No method with id " + msg.method_id + " on this server."; + this.sendSubscriptionFailed(errorMsg, msg.subscription_id); + return; + } + if (streamingMethod.protocolState.subscriptionsMap && + streamingMethod.protocolState.subscriptionsMap[msg.subscription_id]) { + this.sendSubscriptionFailed("A subscription with id " + msg.subscription_id + " already exists.", msg.subscription_id); + return; + } + this.callbacks.execute(SUBSCRIPTION_REQUEST, requestContext, streamingMethod); + } + sendSubscriptionFailed(reason, subscriptionId) { + const errorMessage = { + type: "error", + reason_uri: this.ERR_URI_SUBSCRIPTION_FAILED, + reason, + request_id: subscriptionId, + }; + this.session.sendFireAndForget(errorMessage); + } + getStreamId(streamingMethod, branchKey) { + if (typeof branchKey !== "string") { + branchKey = ""; + } + if (!streamingMethod.protocolState.branchKeyToStreamIdMap) { + throw new Error(`streaming ${streamingMethod.definition.name} method without protocol state`); + } + const needleBranch = streamingMethod.protocolState.branchKeyToStreamIdMap.filter((branch) => { + return branch.key === branchKey; + })[0]; + let streamId = (needleBranch ? needleBranch.streamId : undefined); + if (typeof streamId !== "string" || streamId === "") { + streamId = this.getNextStreamId(); + streamingMethod.protocolState.branchKeyToStreamIdMap.push({ key: branchKey, streamId }); + } + return streamId; + } + } + + class ServerProtocol { + session; + clientRepository; + serverRepository; + logger; + callbacks = CallbackRegistryFactory$1(); + streaming; + constructor(session, clientRepository, serverRepository, logger) { + this.session = session; + this.clientRepository = clientRepository; + this.serverRepository = serverRepository; + this.logger = logger; + this.streaming = new ServerStreaming(session, clientRepository, serverRepository); + this.session.on("invoke", (msg) => this.handleInvokeMessage(msg)); + } + createStream(repoMethod) { + repoMethod.protocolState.subscriptionsMap = {}; + repoMethod.protocolState.branchKeyToStreamIdMap = []; + return this.register(repoMethod, true); + } + register(repoMethod, isStreaming) { + const methodDef = repoMethod.definition; + const flags = Object.assign({}, { metadata: methodDef.flags ?? {} }, { streaming: isStreaming || false }); + const registerMsg = { + type: "register", + methods: [{ + id: repoMethod.repoId, + name: methodDef.name, + display_name: methodDef.displayName, + description: methodDef.description, + version: methodDef.version, + flags, + object_types: methodDef.objectTypes || methodDef.object_types, + input_signature: methodDef.accepts, + result_signature: methodDef.returns, + restrictions: undefined, + }], + }; + return this.session.send(registerMsg, { methodId: repoMethod.repoId }) + .then(() => { + this.logger.debug("registered method " + repoMethod.definition.name + " with id " + repoMethod.repoId); + }) + .catch((msg) => { + this.logger.warn(`failed to register method ${repoMethod.definition.name} with id ${repoMethod.repoId} - ${JSON.stringify(msg)}`); + throw msg; + }); + } + onInvoked(callback) { + this.callbacks.add("onInvoked", callback); + } + methodInvocationResult(method, invocationId, err, result) { + let msg; + if (err || err === "") { + msg = { + type: "error", + request_id: invocationId, + reason_uri: "agm.errors.client_error", + reason: err, + context: result, + peer_id: undefined, + }; + } + else { + msg = { + type: "yield", + invocation_id: invocationId, + peer_id: this.session.peerId, + result, + request_id: undefined, + }; + } + this.session.sendFireAndForget(msg); + } + async unregister(method) { + const msg = { + type: "unregister", + methods: [method.repoId], + }; + await this.session.send(msg); + } + getBranchList(method) { + return this.streaming.getBranchList(method); + } + getSubscriptionList(method, branchKey) { + return this.streaming.getSubscriptionList(method, branchKey); + } + closeAllSubscriptions(method, branchKey) { + this.streaming.closeMultipleSubscriptions(method, branchKey); + } + pushData(method, data, branches) { + this.streaming.pushData(method, data, branches); + } + pushDataToSingle(method, subscription, data) { + this.streaming.pushDataToSingle(method, subscription, data); + } + closeSingleSubscription(method, subscription) { + this.streaming.closeSingleSubscription(method, subscription); + } + acceptRequestOnBranch(requestContext, method, branch) { + this.streaming.acceptRequestOnBranch(requestContext, method, branch); + } + rejectRequest(requestContext, method, reason) { + this.streaming.rejectRequest(requestContext, method, reason); + } + onSubRequest(callback) { + this.streaming.onSubRequest(callback); + } + onSubAdded(callback) { + this.streaming.onSubAdded(callback); + } + onSubRemoved(callback) { + this.streaming.onSubRemoved(callback); + } + handleInvokeMessage(msg) { + const invocationId = msg.invocation_id; + const callerId = msg.caller_id; + const methodId = msg.method_id; + const args = msg.arguments_kv; + const methodList = this.serverRepository.getList(); + const method = methodList.filter((m) => { + return m.repoId === methodId; + })[0]; + if (method === undefined) { + return; + } + const client = this.clientRepository.getServerById(callerId)?.instance; + const invocationArgs = { args, instance: client }; + this.callbacks.execute("onInvoked", method, invocationId, invocationArgs); + } + } + + class UserSubscription { + repository; + subscriptionData; + get requestArguments() { + return this.subscriptionData.params.arguments || {}; + } + get servers() { + return this.subscriptionData.trackedServers.reduce((servers, pair) => { + if (pair.subscriptionId) { + const server = this.repository.getServerById(pair.serverId)?.instance; + if (server) { + servers.push(server); + } + } + return servers; + }, []); + } + get serverInstance() { + return this.servers[0]; + } + get stream() { + return this.subscriptionData.method; + } + constructor(repository, subscriptionData) { + this.repository = repository; + this.subscriptionData = subscriptionData; + } + onData(dataCallback) { + if (typeof dataCallback !== "function") { + throw new TypeError("The data callback must be a function."); + } + this.subscriptionData.handlers.onData.push(dataCallback); + if (this.subscriptionData.handlers.onData.length === 1 && this.subscriptionData.queued.data.length > 0) { + this.subscriptionData.queued.data.forEach((dataItem) => { + dataCallback(dataItem); + }); + } + } + onClosed(closedCallback) { + if (typeof closedCallback !== "function") { + throw new TypeError("The callback must be a function."); + } + this.subscriptionData.handlers.onClosed.push(closedCallback); + } + onFailed(callback) { + } + onConnected(callback) { + if (typeof callback !== "function") { + throw new TypeError("The callback must be a function."); + } + this.subscriptionData.handlers.onConnected.push(callback); + } + close() { + this.subscriptionData.close(); + } + setNewSubscription(newSub) { + this.subscriptionData = newSub; + } + } + + class TimedCache { + config; + cache = []; + timeoutIds = []; + constructor(config) { + this.config = config; + } + add(element) { + const id = nanoid$1(10); + this.cache.push({ id, element }); + const timeoutId = setTimeout(() => { + const elementIdx = this.cache.findIndex((entry) => entry.id === id); + if (elementIdx < 0) { + return; + } + this.cache.splice(elementIdx, 1); + }, this.config.ELEMENT_TTL_MS); + this.timeoutIds.push(timeoutId); + } + flush() { + const elements = this.cache.map((entry) => entry.element); + this.timeoutIds.forEach((id) => clearInterval(id)); + this.cache = []; + this.timeoutIds = []; + return elements; + } + } + + const STATUS_AWAITING_ACCEPT = "awaitingAccept"; + const STATUS_SUBSCRIBED = "subscribed"; + const ERR_MSG_SUB_FAILED = "Subscription failed."; + const ERR_MSG_SUB_REJECTED = "Subscription rejected."; + const ON_CLOSE_MSG_SERVER_INIT = "ServerInitiated"; + const ON_CLOSE_MSG_CLIENT_INIT = "ClientInitiated"; + class ClientStreaming { + session; + repository; + logger; + subscriptionsList = {}; + timedCache = new TimedCache({ ELEMENT_TTL_MS: 10000 }); + subscriptionIdToLocalKeyMap = {}; + nextSubLocalKey = 0; + constructor(session, repository, logger) { + this.session = session; + this.repository = repository; + this.logger = logger; + session.on("subscribed", this.handleSubscribed); + session.on("event", this.handleEventData); + session.on("subscription-cancelled", this.handleSubscriptionCancelled); + } + subscribe(streamingMethod, params, targetServers, success, error, existingSub) { + if (targetServers.length === 0) { + error({ + method: streamingMethod, + called_with: params.arguments, + message: ERR_MSG_SUB_FAILED + " No available servers matched the target params.", + }); + return; + } + const subLocalKey = this.getNextSubscriptionLocalKey(); + const pendingSub = this.registerSubscription(subLocalKey, streamingMethod, params, success, error, params.methodResponseTimeout || 10000, existingSub); + if (typeof pendingSub !== "object") { + error({ + method: streamingMethod, + called_with: params.arguments, + message: ERR_MSG_SUB_FAILED + " Unable to register the user callbacks.", + }); + return; + } + targetServers.forEach((target) => { + const serverId = target.server.id; + const method = target.methods.find((m) => m.name === streamingMethod.name); + if (!method) { + this.logger.error(`can not find method ${streamingMethod.name} for target ${target.server.id}`); + return; + } + pendingSub.trackedServers.push({ + serverId, + subscriptionId: undefined, + }); + const msg = { + type: "subscribe", + server_id: serverId, + method_id: method.gatewayId, + arguments_kv: params.arguments, + }; + this.session.send(msg, { serverId, subLocalKey }) + .then((m) => this.handleSubscribed(m)) + .catch((err) => this.handleErrorSubscribing(err)); + }); + } + drainSubscriptions() { + const existing = Object.values(this.subscriptionsList); + this.subscriptionsList = {}; + this.subscriptionIdToLocalKeyMap = {}; + return existing; + } + drainSubscriptionsCache() { + return this.timedCache.flush(); + } + getNextSubscriptionLocalKey() { + const current = this.nextSubLocalKey; + this.nextSubLocalKey += 1; + return current; + } + registerSubscription(subLocalKey, method, params, success, error, timeout, existingSub) { + const subsInfo = { + localKey: subLocalKey, + status: STATUS_AWAITING_ACCEPT, + method, + params, + success, + error, + trackedServers: [], + handlers: { + onData: existingSub?.handlers.onData || [], + onClosed: existingSub?.handlers.onClosed || [], + onConnected: existingSub?.handlers.onConnected || [], + }, + queued: { + data: [], + closers: [], + }, + timeoutId: undefined, + close: () => this.closeSubscription(subLocalKey), + subscription: existingSub?.subscription + }; + if (!existingSub) { + if (params.onData) { + subsInfo.handlers.onData.push(params.onData); + } + if (params.onClosed) { + subsInfo.handlers.onClosed.push(params.onClosed); + } + if (params.onConnected) { + subsInfo.handlers.onConnected.push(params.onConnected); + } + } + this.subscriptionsList[subLocalKey] = subsInfo; + subsInfo.timeoutId = setTimeout(() => { + if (this.subscriptionsList[subLocalKey] === undefined) { + return; + } + const pendingSub = this.subscriptionsList[subLocalKey]; + if (pendingSub.status === STATUS_AWAITING_ACCEPT) { + error({ + method, + called_with: params.arguments, + message: ERR_MSG_SUB_FAILED + " Subscription attempt timed out after " + timeout + " ms.", + }); + delete this.subscriptionsList[subLocalKey]; + } + else if (pendingSub.status === STATUS_SUBSCRIBED && pendingSub.trackedServers.length > 0) { + pendingSub.trackedServers = pendingSub.trackedServers.filter((server) => { + return (typeof server.subscriptionId !== "undefined"); + }); + delete pendingSub.timeoutId; + if (pendingSub.trackedServers.length <= 0) { + this.callOnClosedHandlers(pendingSub); + delete this.subscriptionsList[subLocalKey]; + } + } + }, timeout); + return subsInfo; + } + handleErrorSubscribing = (errorResponse) => { + const tag = errorResponse._tag; + const subLocalKey = tag.subLocalKey; + const pendingSub = this.subscriptionsList[subLocalKey]; + if (typeof pendingSub !== "object") { + return; + } + pendingSub.trackedServers = pendingSub.trackedServers.filter((server) => { + return server.serverId !== tag.serverId; + }); + if (pendingSub.trackedServers.length <= 0) { + clearTimeout(pendingSub.timeoutId); + if (pendingSub.status === STATUS_AWAITING_ACCEPT) { + const reason = (typeof errorResponse.reason === "string" && errorResponse.reason !== "") ? + ' Publisher said "' + errorResponse.reason + '".' : + " No reason given."; + const callArgs = typeof pendingSub.params.arguments === "object" ? + JSON.stringify(pendingSub.params.arguments) : + "{}"; + pendingSub.error({ + message: ERR_MSG_SUB_REJECTED + reason + " Called with:" + callArgs, + called_with: pendingSub.params.arguments, + method: pendingSub.method, + }); + } + else if (pendingSub.status === STATUS_SUBSCRIBED) { + this.callOnClosedHandlers(pendingSub); + } + delete this.subscriptionsList[subLocalKey]; + } + }; + handleSubscribed = (msg) => { + const subLocalKey = msg._tag.subLocalKey; + const pendingSub = this.subscriptionsList[subLocalKey]; + if (typeof pendingSub !== "object") { + return; + } + const serverId = msg._tag.serverId; + const acceptingServer = pendingSub.trackedServers + .filter((server) => { + return server.serverId === serverId; + })[0]; + if (typeof acceptingServer !== "object") { + return; + } + acceptingServer.subscriptionId = msg.subscription_id; + this.subscriptionIdToLocalKeyMap[msg.subscription_id] = subLocalKey; + const isFirstResponse = (pendingSub.status === STATUS_AWAITING_ACCEPT); + pendingSub.status = STATUS_SUBSCRIBED; + if (isFirstResponse) { + let reconnect = false; + let sub = pendingSub.subscription; + if (sub) { + sub.setNewSubscription(pendingSub); + pendingSub.success(sub); + reconnect = true; + } + else { + sub = new UserSubscription(this.repository, pendingSub); + pendingSub.subscription = sub; + pendingSub.success(sub); + } + for (const handler of pendingSub.handlers.onConnected) { + try { + handler(sub.serverInstance, reconnect); + } + catch (e) { + } + } + } + }; + handleEventData = (msg) => { + const subLocalKey = this.subscriptionIdToLocalKeyMap[msg.subscription_id]; + if (typeof subLocalKey === "undefined") { + return; + } + const subscription = this.subscriptionsList[subLocalKey]; + if (typeof subscription !== "object") { + return; + } + const trackedServersFound = subscription.trackedServers.filter((s) => { + return s.subscriptionId === msg.subscription_id; + }); + if (trackedServersFound.length !== 1) { + return; + } + const isPrivateData = msg.oob; + const sendingServerId = trackedServersFound[0].serverId; + const server = this.repository.getServerById(sendingServerId); + const receivedStreamData = () => { + return { + data: msg.data, + server: server?.instance ?? {}, + requestArguments: subscription.params.arguments, + message: undefined, + private: isPrivateData, + }; + }; + const onDataHandlers = subscription.handlers.onData; + const queuedData = subscription.queued.data; + if (onDataHandlers.length > 0) { + onDataHandlers.forEach((callback) => { + if (typeof callback === "function") { + callback(receivedStreamData()); + } + }); + } + else { + queuedData.push(receivedStreamData()); + } + }; + handleSubscriptionCancelled = (msg) => { + const subLocalKey = this.subscriptionIdToLocalKeyMap[msg.subscription_id]; + if (typeof subLocalKey === "undefined") { + return; + } + const subscription = this.subscriptionsList[subLocalKey]; + if (typeof subscription !== "object") { + return; + } + const expectedNewLength = subscription.trackedServers.length - 1; + subscription.trackedServers = subscription.trackedServers.filter((server) => { + if (server.subscriptionId === msg.subscription_id) { + subscription.queued.closers.push(server.serverId); + return false; + } + else { + return true; + } + }); + if (subscription.trackedServers.length !== expectedNewLength) { + return; + } + if (subscription.trackedServers.length <= 0) { + this.timedCache.add(subscription); + clearTimeout(subscription.timeoutId); + this.callOnClosedHandlers(subscription); + delete this.subscriptionsList[subLocalKey]; + } + delete this.subscriptionIdToLocalKeyMap[msg.subscription_id]; + }; + callOnClosedHandlers(subscription, reason) { + const closersCount = subscription.queued.closers.length; + const closingServerId = (closersCount > 0) ? subscription.queued.closers[closersCount - 1] : null; + let closingServer; + if (closingServerId !== undefined && typeof closingServerId === "string") { + closingServer = this.repository.getServerById(closingServerId)?.instance ?? {}; + } + subscription.handlers.onClosed.forEach((callback) => { + if (typeof callback !== "function") { + return; + } + callback({ + message: reason || ON_CLOSE_MSG_SERVER_INIT, + requestArguments: subscription.params.arguments || {}, + server: closingServer, + stream: subscription.method, + }); + }); + } + closeSubscription(subLocalKey) { + const subscription = this.subscriptionsList[subLocalKey]; + if (typeof subscription !== "object") { + return; + } + subscription.trackedServers.forEach((server) => { + if (typeof server.subscriptionId === "undefined") { + return; + } + subscription.queued.closers.push(server.serverId); + this.session.sendFireAndForget({ + type: "unsubscribe", + subscription_id: server.subscriptionId, + reason_uri: "", + reason: ON_CLOSE_MSG_CLIENT_INIT, + }); + delete this.subscriptionIdToLocalKeyMap[server.subscriptionId]; + }); + subscription.trackedServers = []; + this.callOnClosedHandlers(subscription, ON_CLOSE_MSG_CLIENT_INIT); + delete this.subscriptionsList[subLocalKey]; + } + } + + class ClientProtocol { + session; + repository; + logger; + streaming; + constructor(session, repository, logger) { + this.session = session; + this.repository = repository; + this.logger = logger; + session.on("peer-added", (msg) => this.handlePeerAdded(msg)); + session.on("peer-removed", (msg) => this.handlePeerRemoved(msg)); + session.on("methods-added", (msg) => this.handleMethodsAddedMessage(msg)); + session.on("methods-removed", (msg) => this.handleMethodsRemovedMessage(msg)); + this.streaming = new ClientStreaming(session, repository, logger); + } + subscribe(stream, options, targetServers, success, error, existingSub) { + this.streaming.subscribe(stream, options, targetServers, success, error, existingSub); + } + invoke(id, method, args, target) { + const serverId = target.id; + const methodId = method.gatewayId; + const msg = { + type: "call", + server_id: serverId, + method_id: methodId, + arguments_kv: args, + }; + return this.session.send(msg, { invocationId: id, serverId }) + .then((m) => this.handleResultMessage(m)) + .catch((err) => this.handleInvocationError(err)); + } + drainSubscriptions() { + return this.streaming.drainSubscriptions(); + } + drainSubscriptionsCache() { + return this.streaming.drainSubscriptionsCache(); + } + handlePeerAdded(msg) { + const newPeerId = msg.new_peer_id; + const remoteId = msg.identity; + const isLocal = msg.meta ? msg.meta.local : true; + const pid = Number(remoteId.process); + const serverInfo = { + machine: remoteId.machine, + pid: isNaN(pid) ? remoteId.process : pid, + instance: remoteId.instance, + application: remoteId.application, + applicationName: remoteId.applicationName, + environment: remoteId.environment, + region: remoteId.region, + user: remoteId.user, + windowId: remoteId.windowId, + peerId: newPeerId, + api: remoteId.api, + isLocal + }; + this.repository.addServer(serverInfo, newPeerId); + } + handlePeerRemoved(msg) { + const removedPeerId = msg.removed_id; + const reason = msg.reason; + this.repository.removeServerById(removedPeerId, reason); + } + handleMethodsAddedMessage(msg) { + const serverId = msg.server_id; + const methods = msg.methods; + methods.forEach((method) => { + this.repository.addServerMethod(serverId, method); + }); + } + handleMethodsRemovedMessage(msg) { + const serverId = msg.server_id; + const methodIdList = msg.methods; + const server = this.repository.getServerById(serverId); + if (server) { + const serverMethodKeys = Object.keys(server.methods); + serverMethodKeys.forEach((methodKey) => { + const method = server.methods[methodKey]; + if (methodIdList.indexOf(method.gatewayId) > -1) { + this.repository.removeServerMethod(serverId, methodKey); + } + }); + } + } + handleResultMessage(msg) { + const invocationId = msg._tag.invocationId; + const result = msg.result; + const serverId = msg._tag.serverId; + const server = this.repository.getServerById(serverId); + return { + invocationId, + result, + instance: server?.instance, + status: InvokeStatus.Success, + message: "" + }; + } + handleInvocationError(msg) { + this.logger.debug(`handle invocation error ${JSON.stringify(msg)}`); + if ("_tag" in msg) { + const invocationId = msg._tag.invocationId; + const serverId = msg._tag.serverId; + const server = this.repository.getServerById(serverId); + const message = msg.reason; + const context = msg.context; + return { + invocationId, + result: context, + instance: server?.instance, + status: InvokeStatus.Error, + message + }; + } + else { + return { + invocationId: "", + message: msg.message, + status: InvokeStatus.Error, + error: msg + }; + } + } + } + + function gW3ProtocolFactory (instance, connection, clientRepository, serverRepository, libConfig, interop) { + const logger = libConfig.logger.subLogger("gw3-protocol"); + let resolveReadyPromise; + const readyPromise = new Promise((resolve) => { + resolveReadyPromise = resolve; + }); + const session = connection.domain("agm", ["subscribed"]); + const server = new ServerProtocol(session, clientRepository, serverRepository, logger.subLogger("server")); + const client = new ClientProtocol(session, clientRepository, logger.subLogger("client")); + async function handleReconnect() { + logger.info("reconnected - will replay registered methods and subscriptions"); + client.drainSubscriptionsCache().forEach((sub) => { + const methodInfo = sub.method; + const params = Object.assign({}, sub.params); + logger.info(`trying to soft-re-subscribe to method ${methodInfo.name}, with params: ${JSON.stringify(params)}`); + interop.client.subscribe(methodInfo, params, undefined, undefined, sub).then(() => logger.info(`soft-subscribing to method ${methodInfo.name} DONE`)).catch((error) => logger.warn(`subscribing to method ${methodInfo.name} failed: ${JSON.stringify(error)}}`)); + }); + const reconnectionPromises = []; + const existingSubscriptions = client.drainSubscriptions(); + for (const sub of existingSubscriptions) { + const methodInfo = sub.method; + const params = Object.assign({}, sub.params); + logger.info(`trying to re-subscribe to method ${methodInfo.name}, with params: ${JSON.stringify(params)}`); + reconnectionPromises.push(interop.client.subscribe(methodInfo, params, undefined, undefined, sub).then(() => logger.info(`subscribing to method ${methodInfo.name} DONE`))); + } + const registeredMethods = serverRepository.getList(); + serverRepository.reset(); + for (const method of registeredMethods) { + const def = method.definition; + if (method.stream) { + reconnectionPromises.push(interop.server.createStream(def, method.streamCallbacks, undefined, undefined, method.stream) + .then(() => logger.info(`subscribing to method ${def.name} DONE`)) + .catch(() => logger.warn(`subscribing to method ${def.name} FAILED`))); + } + else if (method?.theFunction?.userCallback) { + reconnectionPromises.push(interop.register(def, method.theFunction.userCallback) + .then(() => logger.info(`registering method ${def.name} DONE`)) + .catch(() => logger.warn(`registering method ${def.name} FAILED`))); + } + else if (method?.theFunction?.userCallbackAsync) { + reconnectionPromises.push(interop.registerAsync(def, method.theFunction.userCallbackAsync) + .then(() => logger.info(`registering method ${def.name} DONE`)) + .catch(() => logger.warn(`registering method ${def.name} FAILED`))); + } + } + await Promise.all(reconnectionPromises); + logger.info("Interop is re-announced"); + } + function handleInitialJoin() { + if (resolveReadyPromise) { + resolveReadyPromise({ + client, + server, + }); + resolveReadyPromise = undefined; + } + } + session.onJoined((reconnect) => { + clientRepository.addServer(instance, connection.peerId); + if (reconnect) { + handleReconnect().then(() => connection.setLibReAnnounced({ name: "interop" })).catch((error) => logger.warn(`Error while re-announcing interop: ${JSON.stringify(error)}`)); + } + else { + handleInitialJoin(); + } + }); + session.onLeft(() => { + clientRepository.reset(); + }); + session.join(); + return readyPromise; + } + + class Interop { + instance; + readyPromise; + client; + server; + unwrappedInstance; + protocol; + clientRepository; + serverRepository; + constructor(configuration) { + if (typeof configuration === "undefined") { + throw new Error("configuration is required"); + } + if (typeof configuration.connection === "undefined") { + throw new Error("configuration.connections is required"); + } + const connection = configuration.connection; + if (typeof configuration.methodResponseTimeout !== "number") { + configuration.methodResponseTimeout = 30 * 1000; + } + if (typeof configuration.waitTimeoutMs !== "number") { + configuration.waitTimeoutMs = 30 * 1000; + } + this.unwrappedInstance = new InstanceWrapper(this, undefined, connection); + this.instance = this.unwrappedInstance.unwrap(); + this.clientRepository = new ClientRepository(configuration.logger.subLogger("cRep"), this); + this.serverRepository = new ServerRepository(); + let protocolPromise; + if (connection.protocolVersion === 3) { + protocolPromise = gW3ProtocolFactory(this.instance, connection, this.clientRepository, this.serverRepository, configuration, this); + } + else { + throw new Error(`protocol ${connection.protocolVersion} not supported`); + } + this.readyPromise = protocolPromise.then((protocol) => { + this.protocol = protocol; + this.client = new Client(this.protocol, this.clientRepository, this.instance, configuration); + this.server = new Server(this.protocol, this.serverRepository); + return this; + }); + } + ready() { + return this.readyPromise; + } + serverRemoved(callback) { + return this.client.serverRemoved(callback); + } + serverAdded(callback) { + return this.client.serverAdded(callback); + } + serverMethodRemoved(callback) { + return this.client.serverMethodRemoved(callback); + } + serverMethodAdded(callback) { + return this.client.serverMethodAdded(callback); + } + methodRemoved(callback) { + return this.client.methodRemoved(callback); + } + methodAdded(callback) { + return this.client.methodAdded(callback); + } + methodsForInstance(instance) { + return this.client.methodsForInstance(instance); + } + methods(methodFilter) { + return this.client.methods(methodFilter); + } + servers(methodFilter) { + return this.client.servers(methodFilter); + } + subscribe(method, options, successCallback, errorCallback) { + return this.client.subscribe(method, options, successCallback, errorCallback); + } + createStream(streamDef, callbacks, successCallback, errorCallback) { + return this.server.createStream(streamDef, callbacks, successCallback, errorCallback); + } + unregister(methodFilter) { + return this.server.unregister(methodFilter); + } + registerAsync(methodDefinition, callback) { + return this.server.registerAsync(methodDefinition, callback); + } + register(methodDefinition, callback) { + return this.server.register(methodDefinition, callback); + } + invoke(methodFilter, argumentObj, target, additionalOptions, success, error) { + return this.client.invoke(methodFilter, argumentObj, target, additionalOptions, success, error); + } + waitForMethod(name) { + const pw = new PromiseWrapper$1(); + const unsubscribe = this.client.methodAdded((m) => { + if (m.name === name) { + unsubscribe(); + pw.resolve(m); + } + }); + return pw.promise; + } + } + + const successMessages = ["subscribed", "success"]; + class MessageBus { + connection; + logger; + peerId; + session; + subscriptions; + readyPromise; + constructor(connection, logger) { + this.connection = connection; + this.logger = logger; + this.peerId = connection.peerId; + this.subscriptions = []; + this.session = connection.domain("bus", successMessages); + this.readyPromise = this.session.join(); + this.readyPromise.then(() => { + this.watchOnEvent(); + }); + } + ready() { + return this.readyPromise; + } + publish = (topic, data, options) => { + const { routingKey, target } = options || {}; + const args = this.removeEmptyValues({ + type: "publish", + topic, + data, + peer_id: this.peerId, + routing_key: routingKey, + target_identity: target + }); + this.session.send(args); + }; + subscribe = (topic, callback, options) => { + return new Promise((resolve, reject) => { + const { routingKey, target } = options || {}; + const args = this.removeEmptyValues({ + type: "subscribe", + topic, + peer_id: this.peerId, + routing_key: routingKey, + source: target + }); + this.session.send(args) + .then((response) => { + const { subscription_id } = response; + this.subscriptions.push({ subscription_id, topic, callback, source: target }); + resolve({ + unsubscribe: () => { + this.session.send({ type: "unsubscribe", subscription_id, peer_id: this.peerId }); + this.subscriptions = this.subscriptions.filter((s) => s.subscription_id !== subscription_id); + return Promise.resolve(); + } + }); + }) + .catch((error) => reject(error)); + }); + }; + watchOnEvent = () => { + this.session.on("event", (args) => { + const { data, subscription_id } = args; + const source = args["publisher-identity"]; + const subscription = this.subscriptions.find((s) => s.subscription_id === subscription_id); + if (subscription) { + if (!subscription.source) { + subscription.callback(data, subscription.topic, source); + } + else { + if (this.keysMatch(subscription.source, source)) { + subscription.callback(data, subscription.topic, source); + } + } + } + }); + }; + removeEmptyValues(obj) { + const cleaned = {}; + Object.keys(obj).forEach((key) => { + if (obj[key] !== undefined && obj[key] !== null) { + cleaned[key] = obj[key]; + } + }); + return cleaned; + } + keysMatch(obj1, obj2) { + const keysObj1 = Object.keys(obj1); + let allMatch = true; + keysObj1.forEach((key) => { + if (obj1[key] !== obj2[key]) { + allMatch = false; + } + }); + return allMatch; + } + } + + const IOConnectCoreFactory = (userConfig, ext) => { + const iodesktop = typeof window === "object" ? (window.iodesktop ?? window.glue42gd) : undefined; + const preloadPromise = typeof window === "object" ? (window.gdPreloadPromise ?? Promise.resolve()) : Promise.resolve(); + const glueInitTimer = timer("glue"); + userConfig = userConfig || {}; + ext = ext || {}; + const internalConfig = prepareConfig$1(userConfig, ext, iodesktop); + let _connection; + let _interop; + let _logger; + let _metrics; + let _contexts; + let _bus; + let _allowTrace; + const libs = {}; + function registerLib(name, inner, t) { + _allowTrace = _logger.canPublish("trace"); + if (_allowTrace) { + _logger.trace(`registering ${name} module`); + } + const done = (e) => { + inner.initTime = t.stop(); + inner.initEndTime = t.endTime; + inner.marks = t.marks; + if (!_allowTrace) { + return; + } + const traceMessage = e ? + `${name} failed - ${e.message}` : + `${name} is ready - ${t.endTime - t.startTime}`; + _logger.trace(traceMessage); + }; + inner.initStartTime = t.startTime; + if (inner.ready) { + inner.ready() + .then(() => { + done(); + }) + .catch((e) => { + const error = typeof e === "string" ? new Error(e) : e; + done(error); + }); + } + else { + done(); + } + if (!Array.isArray(name)) { + name = [name]; + } + name.forEach((n) => { + libs[n] = inner; + IOConnectCoreFactory[n] = inner; + }); + } + function setupConnection() { + const initTimer = timer("connection"); + _connection = new Connection(internalConfig.connection, _logger.subLogger("connection")); + let authPromise = Promise.resolve(internalConfig.auth); + if (internalConfig.connection && !internalConfig.auth) { + if (iodesktop) { + authPromise = iodesktop.getGWToken() + .then((token) => { + return { + gatewayToken: token + }; + }); + } + else if (typeof window !== "undefined" && window?.glue42electron) { + if (typeof window.glue42electron.gwToken === "string") { + authPromise = Promise.resolve({ + gatewayToken: window.glue42electron.gwToken + }); + } + } + else { + authPromise = Promise.reject("You need to provide auth information"); + } + } + return authPromise + .then((authConfig) => { + initTimer.mark("auth-promise-resolved"); + let authRequest; + if (Object.prototype.toString.call(authConfig) === "[object Object]") { + authRequest = authConfig; + } + else { + throw new Error("Invalid auth object - " + JSON.stringify(authConfig)); + } + return _connection.login(authRequest); + }) + .then(() => { + registerLib("connection", _connection, initTimer); + return internalConfig; + }) + .catch((e) => { + if (_connection) { + _connection.logout(); + } + throw e; + }); + } + function setupLogger() { + const initTimer = timer("logger"); + _logger = new Logger$1(`${internalConfig.connection.identity?.application}`, undefined, internalConfig.customLogger); + _logger.consoleLevel(internalConfig.logger.console); + _logger.publishLevel(internalConfig.logger.publish); + if (_logger.canPublish("debug")) { + _logger.debug("initializing glue..."); + } + registerLib("logger", _logger, initTimer); + return Promise.resolve(undefined); + } + function setupMetrics() { + const initTimer = timer("metrics"); + const config = internalConfig.metrics; + const metricsPublishingEnabledFunc = iodesktop?.getMetricsPublishingEnabled; + const identity = internalConfig.connection.identity; + const canUpdateMetric = metricsPublishingEnabledFunc ? metricsPublishingEnabledFunc : () => true; + const disableAutoAppSystem = (typeof config !== "boolean" && config.disableAutoAppSystem) ?? false; + _metrics = metrics({ + connection: config ? _connection : undefined, + logger: _logger.subLogger("metrics"), + canUpdateMetric, + system: "Glue42", + service: identity?.service ?? iodesktop?.applicationName ?? internalConfig.application, + instance: identity?.instance ?? identity?.windowId ?? nanoid$1(10), + disableAutoAppSystem, + pagePerformanceMetrics: typeof config !== "boolean" ? config?.pagePerformanceMetrics : undefined + }); + registerLib("metrics", _metrics, initTimer); + return Promise.resolve(); + } + function setupInterop() { + const initTimer = timer("interop"); + const agmConfig = { + connection: _connection, + logger: _logger.subLogger("interop"), + }; + _interop = new Interop(agmConfig); + Logger$1.Interop = _interop; + registerLib(["interop", "agm"], _interop, initTimer); + return Promise.resolve(); + } + function setupContexts() { + const hasActivities = (internalConfig.activities && _connection.protocolVersion === 3); + const needsContexts = internalConfig.contexts || hasActivities; + if (needsContexts) { + const initTimer = timer("contexts"); + _contexts = new ContextsModule({ + connection: _connection, + logger: _logger.subLogger("contexts"), + trackAllContexts: typeof internalConfig.contexts === "object" ? internalConfig.contexts.trackAllContexts : false, + reAnnounceKnownContexts: typeof internalConfig.contexts === "object" ? internalConfig.contexts.reAnnounceKnownContexts : false + }); + registerLib("contexts", _contexts, initTimer); + return _contexts; + } + else { + const replayer = _connection.replayer; + if (replayer) { + replayer.drain(ContextMessageReplaySpec.name); + } + } + } + async function setupBus() { + if (!internalConfig.bus) { + return Promise.resolve(); + } + const initTimer = timer("bus"); + _bus = new MessageBus(_connection, _logger.subLogger("bus")); + registerLib("bus", _bus, initTimer); + return Promise.resolve(); + } + function setupExternalLibs(externalLibs) { + try { + externalLibs.forEach((lib) => { + setupExternalLib(lib.name, lib.create); + }); + return Promise.resolve(); + } + catch (e) { + return Promise.reject(e); + } + } + function setupExternalLib(name, createCallback) { + const initTimer = timer(name); + const lib = createCallback(libs); + if (lib) { + registerLib(name, lib, initTimer); + } + } + function waitForLibs() { + const libsReadyPromises = Object.keys(libs).map((key) => { + const lib = libs[key]; + return lib.ready ? + lib.ready() : Promise.resolve(); + }); + return Promise.all(libsReadyPromises); + } + function constructGlueObject() { + const feedbackFunc = (feedbackInfo) => { + if (!_interop) { + return; + } + _interop.invoke("T42.ACS.Feedback", feedbackInfo, "best"); + }; + const info = { + coreVersion: version$1, + version: internalConfig.version + }; + glueInitTimer.stop(); + const glue = { + feedback: feedbackFunc, + info, + logger: _logger, + interop: _interop, + agm: _interop, + connection: _connection, + metrics: _metrics, + contexts: _contexts, + bus: _bus, + version: internalConfig.version, + userConfig, + done: () => { + _logger?.info("done called by user..."); + return _connection.logout(); + } + }; + glue.performance = { + get glueVer() { + return internalConfig.version; + }, + get glueConfig() { + return JSON.stringify(userConfig); + }, + get browser() { + return window.performance.timing.toJSON(); + }, + get memory() { + return window.performance.memory; + }, + get initTimes() { + const all = getAllTimers(); + return Object.keys(all).map((key) => { + const t = all[key]; + return { + name: key, + duration: t.endTime - t.startTime, + marks: t.marks, + startTime: t.startTime, + endTime: t.endTime + }; + }); + } + }; + Object.keys(libs).forEach((key) => { + const lib = libs[key]; + glue[key] = lib; + }); + glue.config = {}; + Object.keys(internalConfig).forEach((k) => { + glue.config[k] = internalConfig[k]; + }); + if (ext && ext.extOptions) { + Object.keys(ext.extOptions).forEach((k) => { + glue.config[k] = ext?.extOptions[k]; + }); + } + if (ext?.enrichGlue) { + ext.enrichGlue(glue); + } + if (iodesktop && iodesktop.updatePerfData) { + iodesktop.updatePerfData(glue.performance); + } + if (glue.agm) { + const deprecatedDecorator = (fn, wrong, proper) => { + return function () { + glue.logger.warn(`glue.js - 'glue.agm.${wrong}' method is deprecated, use 'glue.interop.${proper}' instead.`); + return fn.apply(glue.agm, arguments); + }; + }; + const agmAny = glue.agm; + agmAny.method_added = deprecatedDecorator(glue.agm.methodAdded, "method_added", "methodAdded"); + agmAny.method_removed = deprecatedDecorator(glue.agm.methodRemoved, "method_removed", "methodRemoved"); + agmAny.server_added = deprecatedDecorator(glue.agm.serverAdded, "server_added", "serverAdded"); + agmAny.server_method_aded = deprecatedDecorator(glue.agm.serverMethodAdded, "server_method_aded", "serverMethodAdded"); + agmAny.server_method_removed = deprecatedDecorator(glue.agm.serverMethodRemoved, "server_method_removed", "serverMethodRemoved"); + } + return glue; + } + async function registerInstanceIfNeeded() { + const RegisterInstanceMethodName = "T42.ACS.RegisterInstance"; + if (Utils$1.isNode() && typeof process.env._GD_STARTING_CONTEXT_ === "undefined" && typeof userConfig?.application !== "undefined") { + const isMethodAvailable = _interop.methods({ name: RegisterInstanceMethodName }).length > 0; + if (isMethodAvailable) { + try { + await _interop.invoke(RegisterInstanceMethodName, { appName: userConfig?.application, pid: process.pid }); + } + catch (error) { + const typedError = error; + _logger.error(`Cannot register as an instance: ${JSON.stringify(typedError.message)}`); + } + } + } + } + return preloadPromise + .then(setupLogger) + .then(setupConnection) + .then(() => Promise.all([setupMetrics(), setupInterop(), setupContexts(), setupBus()])) + .then(() => _interop.readyPromise) + .then(() => registerInstanceIfNeeded()) + .then(() => { + return setupExternalLibs(internalConfig.libs || []); + }) + .then(waitForLibs) + .then(constructGlueObject) + .catch((err) => { + return Promise.reject({ + err, + libs + }); + }); + }; + if (typeof window !== "undefined") { + window.IOConnectCore = IOConnectCoreFactory; + } + IOConnectCoreFactory.version = version$1; + IOConnectCoreFactory.default = IOConnectCoreFactory; + + class ActivityEntity { + constructor(id) { + this._id = id; + } + get id() { + return this._id; + } + _update(other) { + if (other._id !== this._id) { + throw Error("Can not update from entity with different id."); + } + this._updateCore(other); + } + _updateCore(other) { + return; + } + _beforeDelete(other) { + return; + } + } + + function isNumber(arg) { + return typeof arg === "number"; + } + function isString(arg) { + return typeof arg === "string"; + } + function isObject(arg) { + return typeof arg === "object" && !Array.isArray(arg) && arg !== null; + } + function isArray(arg) { + if (Array.isArray) { + return Array.isArray(arg); + } + return toString.call(arg) === "[object Array]"; + } + function isUndefined(arg) { + return typeof arg === "undefined"; + } + function isUndefinedOrNull(arg) { + return arg === null || typeof arg === "undefined"; + } + function isNullOrWhiteSpace(str) { + return (typeof str !== "string" || !str || str.length === 0 || /^\s*$/.test(str)); + } + function isBoolean(obj) { + return obj === true || obj === false || toString.call(obj) === "[object Boolean]"; + } + function isFunction(arg) { + return !!(arg && arg.constructor && arg.call && arg.apply); + } + function some(array, predicate) { + for (let index = 0; index < array.length; index++) { + if (predicate(array[index], index)) { + return true; + } + } + return false; + } + function ifNotUndefined(what, doWithIt) { + if (typeof what !== "undefined") { + doWithIt(what); + } + } + function promisify$1(promise, successCallback, errorCallback) { + if (typeof successCallback !== "function" && typeof errorCallback !== "function") { + return promise; + } + if (typeof successCallback !== "function") { + successCallback = () => { return; }; + } + else if (typeof errorCallback !== "function") { + errorCallback = () => { return; }; + } + promise.then(successCallback, errorCallback); + } + + class ActivityType extends ActivityEntity { + constructor(name, ownerWindow, helperWindows, description) { + super(name); + this._name = name; + this._description = description; + this._ownerWindow = ownerWindow; + this._helperWindows = helperWindows || []; + } + get name() { + return this._name; + } + get description() { + return this._description; + } + get helperWindows() { + return this._helperWindows.map((hw) => this.covertToWindowDef(hw)); + } + get ownerWindow() { + return this.covertToWindowDef(this._ownerWindow); + } + initiate(context, callback, configuration) { + return this._manager.initiate(this._name, context, callback, configuration); + } + _updateCore(other) { + super._updateCore(other); + ifNotUndefined(other._description, (x) => this._description = x); + ifNotUndefined(other._ownerWindow, (x) => this._ownerWindow = x); + ifNotUndefined(other._helperWindows, (x) => this._helperWindows = x); + } + covertToWindowDef(windowType) { + var _a, _b; + return { + type: (_a = windowType === null || windowType === void 0 ? void 0 : windowType.id) === null || _a === void 0 ? void 0 : _a.type, + name: (_b = windowType === null || windowType === void 0 ? void 0 : windowType.id) === null || _b === void 0 ? void 0 : _b.name + }; + } + } + + class WindowType extends ActivityEntity { + constructor(name, appByWindowTypeGetter) { + super(name); + this._name = name; + this._appByWindowTypeGetter = appByWindowTypeGetter; + } + get name() { + return this._name; + } + get config() { + return this._appByWindowTypeGetter(this._name); + } + get windows() { + return this._manager.getWindows({ type: this._name }); + } + create(activity, configuration) { + const definition = Object.assign({ type: this.name, name: this.name, isIndependent: false }, configuration); + return this._manager.createWindow(activity, definition); + } + } + + class EntityEvent { + constructor(entitiy, context) { + this.entity = entitiy; + this.context = context; + } + } + class EntityEventContext { + constructor(eventType) { + this.type = eventType; + } + } + class ActivityStatusChangeEventContext extends EntityEventContext { + constructor(newStatus, oldStatus) { + super(EntityEventType.StatusChange); + this.newStatus = newStatus; + this.oldStatus = oldStatus; + } + } + class ActivityContextChangedEventContext extends EntityEventContext { + constructor(context, updated, removed) { + super(EntityEventType.ActivityContextChange); + this.context = typeof context === "string" ? JSON.parse(context) : context; + this.updated = updated; + this.removed = removed; + } + } + class EntityEventType { + } + EntityEventType.Added = "added"; + EntityEventType.Removed = "removed"; + EntityEventType.Updated = "updated"; + EntityEventType.Closed = "closed"; + EntityEventType.StatusChange = "statusChange"; + EntityEventType.ActivityContextChange = "activityContextUpdate"; + EntityEventType.ActivityWindowEvent = "activityWindowEvent"; + EntityEventType.ActivityWindowJoinedActivity = "joined"; + EntityEventType.ActivityWindowLeftActivity = "left"; + class ActivityState { + } + ActivityState.Created = "created"; + ActivityState.Started = "started"; + ActivityState.Destroyed = "destroyed"; + + class ActivityAGM { + constructor(activity) { + this._activity = activity; + } + register(definition, handler) { + this._ensureHasAgm(); + ActivityAGM.AGM.register(definition, handler); + } + servers() { + this._ensureHasAgm(); + if (isUndefinedOrNull(this._activity)) { + return []; + } + return this._activity.windows.map((w) => { + return w.instance; + }); + } + methods() { + this._ensureHasAgm(); + if (isUndefinedOrNull(this._activity)) { + return []; + } + const windows = this._activity.windows; + const methodNames = []; + const methods = []; + windows.forEach((window) => { + const windowMethods = this.methodsForWindow(window); + windowMethods.forEach((currentWindowMethod) => { + if (methodNames.indexOf(currentWindowMethod.name) === -1) { + methodNames.push(currentWindowMethod.name); + methods.push(currentWindowMethod); + } + }); + }); + return methods; + } + methodsForWindow(window) { + this._ensureHasAgm(); + if (!window.instance) { + return []; + } + return ActivityAGM.AGM.methodsForInstance(window.instance); + } + invoke(methodName, arg, target, options, success, error) { + this._ensureHasAgm(); + const activityServers = this.servers(); + if (isUndefinedOrNull(target)) { + target = "activity.all"; + } + if (isString(target)) { + if (target === "activity.all") ; + else if (target === "activity.best") { + const potentialTargets = activityServers.filter((server) => { + const methods = ActivityAGM.AGM.methodsForInstance(server); + return methods.filter((m) => { + return m.name === methodName; + }).length > 0; + }); + if (potentialTargets.length > 0) { + [potentialTargets[0]]; + } + } + else if (target === "all" || target === "best") { + return promisify$1(ActivityAGM.AGM.invoke(methodName, arg, target, options), success, error); + } + else { + throw new Error("Invalid invoke target " + target); + } + } + else if (isArray(target)) { + if (target.length >= 0) { + const firstElem = target[0]; + if (this._isInstance(firstElem)) { + target.map((instance) => instance); + } + else if (this._isActivityWindow(firstElem)) { + target.map((win) => win.instance); + } + else { + throw new Error("Unknown target object"); + } + } + } + else { + if (this._isInstance(target)) ; + else if (this._isActivityWindow(target)) { + [target.instance]; + } + else { + throw new Error("Unknown target object"); + } + } + throw new Error("Not implemented"); + } + unregister(definition) { + this._ensureHasAgm(); + return ActivityAGM.AGM.unregister(definition); + } + createStream(methodDefinition, subscriptionAddedHandler, subscriptionRemovedHandler) { + this._ensureHasAgm(); + ActivityAGM.AGM.createStream(methodDefinition, { + subscriptionAddedHandler, + subscriptionRemovedHandler, + subscriptionRequestHandler: undefined + }); + } + subscribe(methodDefinition, parameters, target) { + this._ensureHasAgm(); + return ActivityAGM.AGM.subscribe(methodDefinition, parameters); + } + _ensureHasAgm() { + if (isUndefinedOrNull(ActivityAGM.AGM)) { + throw new Error("Agm should be configured to be used in activity"); + } + } + _isInstance(obj) { + return obj.application !== undefined; + } + _isActivityWindow(obj) { + return obj.instance !== undefined; + } + } + + class AttachedActivityDescriptor { + constructor(manager, ownerActivityId, state) { + this._manager = manager; + this._ownerActivityId = ownerActivityId; + this._state = state; + } + get ownerId() { + return this._state.ownerId; + } + get windowIds() { + return this._state.windowIds; + } + get frameColor() { + return this._state.frameColor; + } + get context() { + return this._state.context; + } + get tag() { + return this._state.tag; + } + detach(descriptor) { + descriptor = descriptor || {}; + const merged = {}; + Object.keys(this._state).forEach((prop) => { + merged[prop] = this._state[prop]; + }); + merged.context = descriptor.context || merged.context; + merged.frameColor = descriptor.frameColor || merged.frameColor; + return this._manager.detachActivities(this._ownerActivityId, merged); + } + } + + const nextTick = (cb) => { + setTimeout(cb, 0); + }; + function nodeify(promise, callback) { + if (!isFunction(callback)) { + return promise; + } + promise.then((resp) => { + nextTick(() => { + callback(null, resp); + }); + }, (err) => { + nextTick(() => { + callback(err, null); + }); + }); + } + + class Activity extends ActivityEntity { + constructor(id, actType, status, context, ownerId) { + super(id); + this._id = id; + this._actType = actType; + this._status = status; + this._context = context; + this._ownerId = ownerId; + this._agm = new ActivityAGM(this); + } + get type() { + if (this._manager) { + return this._manager.getActivityType(this._actType); + } + return undefined; + } + get context() { + return this._context; + } + get status() { + return this._status; + } + get owner() { + if (!this._ownerId) { + return null; + } + return this._manager.getWindows({ id: this._ownerId })[0]; + } + get windows() { + return this._manager.getWindows({ activityId: this._id }); + } + get agm() { + return this._agm; + } + addWindow(window, callback) { + return this._manager.addWindowToActivity(this, window, callback); + } + createWindow(windowType, callback) { + return this._manager.createWindow(this, windowType, callback); + } + createStackedWindows(windowTypes, timeout, callback) { + return this._manager.createStackedWindows(this, windowTypes, timeout, callback); + } + leave(window, callback) { + return this._manager.leaveWindowFromActivity(this, window, callback); + } + getWindowsByType(windowType) { + const filter = { activityId: this._id, type: windowType }; + return this._manager.getWindows(filter); + } + setContext(context, callback) { + return this._manager.setActivityContext(this, context, callback); + } + updateContext(context, callback) { + return this._manager.updateActivityContext(this, context, callback); + } + onStatusChange(handler) { + return this._manager.subscribeActivityEvents((a, ns, os) => { + if (a.id === this.id) { + handler(a, ns, os); + } + }); + } + onWindowEvent(handler) { + return this._manager.subscribeWindowEvents((a, w, e) => { + if (a.id === this.id) { + handler(a, w, e); + } + }); + } + onContextChanged(handler) { + this._manager.subscribeActivityContextChanged((act, context, updated, removed) => { + if (act.id === this.id) { + handler(context, updated, removed, act); + } + }); + try { + handler(this.context, this.context, [], this); + } + catch (e) { + return; + } + } + stop() { + this._manager.stopActivity(this); + } + clone(options) { + return this._manager.clone(this, options); + } + attach(activity, tag) { + let activityId; + if (typeof activity === "string") { + activityId = activity; + } + else { + activityId = activity.id; + } + return this._manager.attachActivities(activityId, this.id, tag); + } + onActivityAttached(callback) { + this._manager.subscribeActivitiesAttached((newActId, oldActId, descriptor) => { + if (newActId !== this._id) { + return; + } + callback(descriptor); + }); + } + onDetached(callback) { + this._manager.subscribeActivitiesDetached((newAct, originalActivity, state) => { + if (originalActivity.id !== this._id) { + return; + } + callback(newAct, state); + }); + } + _updateCore(other) { + super._updateCore(other); + ifNotUndefined(other._actType, (x) => this._actType = x); + ifNotUndefined(other._context, (x) => this._context = x); + ifNotUndefined(other._ownerId, (x) => this._ownerId = x); + if (other._status && (!this._status || (this._status.state !== other._status.state))) { + this._status = other._status; + } + } + _updateDescriptors(allStates) { + this._attached = allStates.map((s) => { + return new AttachedActivityDescriptor(this._manager, this._id, s); + }); + } + get attached() { + return this._attached; + } + setFrameColor(color, callback) { + const promise = new Promise((resolve, reject) => { + let callbacksToWait = this.windows.length; + if (callbacksToWait === 0) { + resolve(this); + } + this.windows.forEach((w) => { + w.underlyingWindow.setFrameColor(color, () => { + callbacksToWait--; + if (callbacksToWait <= 0) { + resolve(this); + } + }); + }); + setTimeout(() => { + if (callbacksToWait > 0) { + reject(this.id + " - timed out waiting for setFrameColor with" + color); + } + }, 5000); + }); + return nodeify(promise, callback); + } + getFrameColor() { + if (!this.windows || this.windows.length === 0) { + return ""; + } + return this.windows[0].underlyingWindow.frameColor; + } + } + + class LogLevel { + } + LogLevel.Trace = "trace"; + LogLevel.Debug = "debug"; + LogLevel.Info = "info"; + LogLevel.Warn = "warn"; + LogLevel.Error = "error"; + class Logger { + static GetNamed(name) { + return new Logger(name); + } + static Get(owner) { + return new Logger(Logger.GetTypeName(owner)); + } + constructor(name) { + this._name = name; + if (!isUndefinedOrNull(Logger.GlueLogger)) { + this._glueLogger = Logger.GlueLogger.subLogger(name); + } + } + trace(message) { + if (!isUndefinedOrNull(this._glueLogger)) { + this._glueLogger.trace(message); + } + else { + if (Logger.Level === LogLevel.Trace) { + console.info(this._getMessage(message, LogLevel.Trace)); + } + } + } + debug(message) { + if (!isUndefinedOrNull(this._glueLogger)) { + this._glueLogger.debug(message); + } + else { + if (Logger.Level === LogLevel.Debug || + Logger.Level === LogLevel.Trace) { + console.info(this._getMessage(message, LogLevel.Debug)); + } + } + } + info(message) { + if (!isUndefinedOrNull(this._glueLogger)) { + this._glueLogger.info(message); + } + else { + if (Logger.Level === LogLevel.Debug || + Logger.Level === LogLevel.Trace || + Logger.Level === LogLevel.Info) { + console.info(this._getMessage(message, LogLevel.Info)); + } + } + } + warn(message) { + if (!isUndefinedOrNull(this._glueLogger)) { + this._glueLogger.warn(message); + } + else { + if (Logger.Level === LogLevel.Debug || + Logger.Level === LogLevel.Trace || + Logger.Level === LogLevel.Info || + Logger.Level === LogLevel.Warn) { + console.info(this._getMessage(message, LogLevel.Info)); + } + } + } + error(message) { + if (!isUndefinedOrNull(this._glueLogger)) { + this._glueLogger.error(message); + } + else { + console.error(this._getMessage(message, LogLevel.Error)); + console.trace(); + } + } + _getMessage(message, level) { + return "[" + level + "] " + this._name + " - " + message; + } + static GetTypeName(object) { + const funcNameRegex = /function (.{1,})\(/; + const results = (funcNameRegex).exec(object.constructor.toString()); + return (results && results.length > 1) ? results[1] : ""; + } + } + Logger.Level = LogLevel.Info; + + class ActivityWindow extends ActivityEntity { + constructor(id, name, type, activityId, instance, isIndependent, windowGetter, hcWindowId) { + super(id); + this._logger = Logger.Get("window"); + this._type = type; + this._activityId = activityId; + this._name = name; + this._instance = instance; + this._isIndependent = isIndependent; + this._windowGetter = windowGetter; + this._hcWindowId = hcWindowId; + } + getBounds() { + return this._manager.getWindowBounds(this.id); + } + get name() { + return this._name; + } + get isIndependent() { + return this._isIndependent; + } + get type() { + if (this._manager) { + return this._manager.getWindowType(this._type); + } + return undefined; + } + get activity() { + if (isUndefined(this._activityId)) { + return undefined; + } + return this._manager.getActivityById(this._activityId); + } + get isOwner() { + const act = this.activity; + if (isUndefined(act)) { + return false; + } + return act.owner.id === this.id; + } + setVisible(isVisible, callback) { + return this._manager.setWindowVisibility(this.id, isVisible); + } + activate(focus) { + return this._manager.activateWindow(this.id, focus); + } + setBounds(bounds, callback) { + return this._manager.setWindowBounds(this.id, bounds, callback); + } + close() { + return this._manager.closeWindow(this.id); + } + get instance() { + return this._instance; + } + get underlyingWindow() { + const window = this._windowGetter(); + if (!window) { + return { + id: this._hcWindowId + }; + } + return window; + } + onActivityJoined(callback) { + this._subscribeForActivityWindowEvent(EntityEventType.ActivityWindowJoinedActivity, callback); + } + onActivityRemoved(callback) { + this._subscribeForActivityWindowEvent(EntityEventType.ActivityWindowLeftActivity, callback); + } + _updateCore(other) { + ifNotUndefined(other._activityId, (x) => this._activityId = x); + ifNotUndefined(other._isIndependent, (x) => this._isIndependent = x); + ifNotUndefined(other._hcWindowId, (x) => this._hcWindowId = x); + ifNotUndefined(other._type, (x) => this._type = x); + ifNotUndefined(other._name, (x) => this._name = x); + if (!isUndefinedOrNull(other._instance)) { + this._instance = other._instance; + } + } + _subscribeForActivityWindowEvent(eventName, callback) { + this._manager.subscribeWindowEvents((activity, window, event) => { + if (window.id !== this.id) { + return; + } + if (event === eventName) { + callback(activity); + } + }); + } + _beforeDelete(other) { + this._hcWindowId = other._hcWindowId; + } + } + + class ActivityStatus { + constructor(state, message, time) { + this.state = state; + this.message = message; + this.time = time; + } + getState() { + return this.state; + } + getMessage() { + return this.message; + } + getTime() { + return this.time; + } + } + + const gwMmessageError = "error"; + const gwMessageAddActivityTypes = "add-types"; + const gwMmessageActivityTypesAdded = "types-added"; + const gwMessageRemoveActivityTypes = "remove-types"; + const gwMessageActivityTypesRemoved = "types-removed"; + const gwMessageActivityCreated = "created"; + const gwMessageActivityDestroyed = "destroyed"; + const gwMessageActivityInitiated = "initiated"; + const gwMmessageJoinActivity = "join-activity"; + const gwMessageJoinedActivity = "joined"; + const gwMessageActivityJoined = "activity-joined"; + const gwMessageLeaveActivity = "leave-activity"; + const gwMessageActivityLeft = "left"; + const gwNmessageMergeActivities = "merge"; + const gwMessageSplitActivities = "split"; + const gwMessageOwnerChanged = "owner-changed"; + const gwMessageAddPeerFactories = "add-peer-factories"; + const gwMessagePeerFactoriesAdded = "peer-factories-added"; + const gwMessageRemovePeerFactories = "remove-peer-factories"; + const gwMessagePeerFactoriesRemoved = "peer-factories-removed"; + const gwMessageCreateActivity = "create"; + const gwMessageCreatePeer = "create-peer"; + const gwMessagePeerRequested = "peer-requested"; + const gwMessageReady = "ready"; + const gwMessagePeerCreated = "peer-created"; + const gwMessageDestroyActivity = "destroy"; + const gwMessageDisposePeer = "dispose-peer"; + const gwMessageDestroyPeer = "destroy-peer"; + class GW3Bridge { + static activityTypeGwMessageEntityToActivityType(entity, description) { + const nameToWindowType = (windowName) => new WindowType(windowName, undefined); + return new ActivityType(entity.name, entity.owner_type && nameToWindowType(entity.owner_type), entity.helper_types && entity.helper_types.map(nameToWindowType), description); + } + static peerFactoryGwMessageEntityToWindowType(entity) { + return new WindowType(entity.peer_type, (_) => undefined); + } + static activityGwMessageToActivity(msg, status) { + const ownerId = msg.owner !== undefined ? msg.owner.peer_id : msg.owner_id; + return new Activity(msg.activity_id, msg.activity_type, status, msg.context_snapshot, ownerId); + } + static activityToActivityStatusChangeEvent(act) { + return new EntityEvent(act, new ActivityStatusChangeEventContext(act.status, undefined)); + } + constructor(config) { + this._activityChangeCallbacks = []; + this._activityTypeStatusChangeCallbacks = []; + this._activityWindowChangeCallbacks = []; + this._windowTypeStatusChangeCallbacks = []; + this._peerIdAndFactoryIdToPeerType = {}; + this._peerFactoriesRegisteredByUs = {}; + this._gw3Subscriptions = []; + this._contextSubscriptions = {}; + this._activityTypesInitiatedFromMe = {}; + this._config = config; + this._connection = config.connection; + this._logger = config.logger; + this._contexts = config.contexts; + this._windows = config.windows; + this._sessionJoinedPromise = new Promise((resolve) => { + this._sessionJoinedPromiseResolve = resolve; + }); + this._activityJoinedPromise = new Promise((resolve) => { + this._activityJoinedPromiseResolve = resolve; + }); + if (!this._config.activityId) { + this._activityJoinedPromiseResolve({}); + } + this._gw3Session = this._connection.domain("activity", ["joined", "initiated", "peer-created", "token"]); + if (typeof window !== "undefined") { + const glue42gd = (window).glue42gd; + if (glue42gd && glue42gd.activityInfo) { + if (typeof glue42gd.addRefreshHandler === "function") { + glue42gd.addRefreshHandler((success, error) => { + this._gw3Session + .send({ + type: "reload" + }) + .then((msg) => { + if (!msg.token) { + error("Expected gateway token for refreshing."); + return; + } + try { + glue42gd.setGWToken(msg.token); + } + catch (e) { + error(e.message || e); + return; + } + success(); + }, error); + }); + } + if (glue42gd && typeof glue42gd.addWillNavigateHandler === "function") { + glue42gd.addWillNavigateHandler((success, error) => { + this._gw3Session + .send({ + type: "reload" + }) + .then((msg) => { + if (!msg.token) { + error("Expected gateway token for refreshing."); + return; + } + try { + glue42gd.setGWToken(msg.token); + } + catch (e) { + error(e.message || e); + return; + } + success(); + }, error); + }); + } + } + } + } + get bridgeType() { + return "GW3"; + } + init() { + this.forwardActivityTypeMessagesToStatusEventHandlers(); + this.subscribe(gwMessageActivityCreated, this.handleActivityCreatedMessage); + this.subscribe(gwMessageActivityDestroyed, this.handleActivityDestroyedMessage); + this.forwardActivityMessagesToStatusEventHandlers(); + this.forwardActivityCreatedAndJoinedActivityToActivityWindowEventHandlers(); + this.forwardPeerFactoryMessagesToStatusEventHandlers(); + this.forwardPeerFactoryMessagesToPeerFactoryRequests(); + this.subscribe(gwMessagePeerFactoriesAdded, this.handlePeerFactoriesAdded); + this.subscribe(gwMessagePeerFactoriesRemoved, this.handlePeerFactoriesRemoved); + this.forwardActivityWindowMessagesToEventHandlers(); + this.subscribe(gwMessageDisposePeer, () => { + if (this._config.disposeRequestHandling === "dispose") { + this.dispose(); + return; + } + if (this._config.disposeRequestHandling === "exit") { + if (this._windows && typeof this._windows.my() !== "undefined") { + this._windows.my().close(); + return; + } + if (typeof window !== "undefined" && typeof (window).close === "function") { + window.close(); + return; + } + if (typeof process !== "undefined" && typeof (process).exit === "function") { + process.exit(); + return; + } + } + }); + this._gw3Session.onJoined(() => { + if (this._config.mode === "trackMyOnly" || + this._config.mode === "trackMyTypeAndInitiatedFromMe") { + this._sessionJoinedPromiseResolve(this); + } + else { + this._gw3Session + .send({ + type: "subscribe", + activity_types: (this._config.mode === "trackAll" ? [] : + this._config.mode === "trackTypes" ? this._config.typesToTrack : []) + }) + .then(() => { + this._sessionJoinedPromiseResolve(this); + }); + } + }); + this._gw3Session.join(); + } + dispose() { + this._gw3Subscriptions.forEach((sub) => sub && this._connection.off(sub)); + this._gw3Subscriptions.length = 0; + } + ready() { + return Promise.all([this._sessionJoinedPromise, this._activityJoinedPromise]); + } + initReady() { + return this._sessionJoinedPromise; + } + onActivityTypeStatusChange(callback) { + this._activityTypeStatusChangeCallbacks.push(callback); + } + registerActivityType(activityTypeName, ownerWindow, helperWindows, config, description) { + const entity = {}; + entity.name = activityTypeName; + const toActivityPeerConfig = (windowDefinition) => ({ type: windowDefinition.type, name: windowDefinition.name, configuration: windowDefinition }); + entity.owner_type = toActivityPeerConfig(ownerWindow); + entity.helper_types = helperWindows.map(toActivityPeerConfig); + return this._gw3Session + .send({ + type: gwMessageAddActivityTypes, + types: [entity] + }) + .then(() => { + const activityType = GW3Bridge.activityTypeGwMessageEntityToActivityType(entity, description); + this.invokeCallbacks(this._activityTypeStatusChangeCallbacks, new EntityEvent(activityType, new EntityEventContext(EntityEventType.Added)), gwMessageAddActivityTypes); + return activityType; + }); + } + unregisterActivityType(activityTypeName) { + return this._gw3Session + .send({ + type: gwMessageRemoveActivityTypes, + types: [activityTypeName] + }) + .then(() => { + const activityType = new ActivityType(activityTypeName, undefined, undefined, undefined); + this.invokeCallbacks(this._activityTypeStatusChangeCallbacks, new EntityEvent(activityType, new EntityEventContext(EntityEventType.Removed)), gwMessageAddActivityTypes); + }); + } + onWindowTypeStatusChange(callback) { + this._windowTypeStatusChangeCallbacks.push(callback); + } + registerWindowFactory(windowType, factory, parameters) { + if (this._peerFactoriesRegisteredByUs[windowType]) { + return Promise.reject(new Error(`Factory for windowType ${windowType} already registered.`)); + } + this._peerFactoriesRegisteredByUs[windowType] = factory; + const entity = { + id: windowType, + peer_type: windowType, + configuration: parameters + }; + return this._gw3Session.send({ + type: gwMessageAddPeerFactories, + factories: [entity] + }) + .then(() => { + this.invokeCallbacks(this._windowTypeStatusChangeCallbacks, new EntityEvent(GW3Bridge.peerFactoryGwMessageEntityToWindowType(entity), new EntityEventContext(EntityEventType.Added)), gwMessageAddPeerFactories); + }) + .catch(() => { + delete this._peerFactoriesRegisteredByUs[windowType]; + }); + } + unregisterWindowFactory(windowType) { + const factory = this._peerFactoriesRegisteredByUs[windowType]; + if (!factory) { + return Promise.reject(new Error(`Factory for windowType ${windowType} not registered.`)); + } + delete this._peerFactoriesRegisteredByUs[windowType]; + return this._gw3Session.send({ + type: gwMessageRemovePeerFactories, + factory_ids: [windowType] + }).then(() => { + this.invokeCallbacks(this._windowTypeStatusChangeCallbacks, new EntityEvent(new WindowType(windowType, undefined), new EntityEventContext(EntityEventType.Removed)), gwMessageAddPeerFactories); + }); + } + onActivityStatusChange(callback) { + this._activityChangeCallbacks.push(callback); + } + initiateActivity(activityType, context, configuration) { + const initiateMsg = { + type: gwMessageCreateActivity, + activity_type: activityType, + initial_context: context, + }; + if (this.isOverrideTypeDefinition(configuration)) { + initiateMsg.types_override = { + owner_type: { type: configuration.owner.type, name: configuration.owner.name, configuration: configuration.owner }, + helper_types: configuration.helpers && configuration.helpers.map((wd) => ({ type: wd.type, name: wd.name, configuration: wd })) + }; + } + else { + initiateMsg.configuration = configuration && configuration.map((wd) => ({ type: wd.type, name: wd.name, configuration: wd })); + } + return this.sendCreateAndMapResultingMessagesToPromise(initiateMsg, gwMessageActivityInitiated, (msg, requestId) => msg.request_id === requestId, gwMessageActivityCreated, (msg, requestId, initMsg) => msg.activity_id === initMsg.activity_id, gwMessageActivityDestroyed, (msg, requestId, initMsg) => msg.activity_id === initMsg.activity_id, (msg) => msg.activity_id, null).then((id) => { + if (this._config.mode === "trackMyTypeAndInitiatedFromMe") { + if (!this._activityTypesInitiatedFromMe[activityType]) { + this._activityTypesInitiatedFromMe[activityType] = true; + return this._gw3Session + .send({ + type: "subscribe", + activity_types: [activityType] + }) + .then(() => { + return id; + }); + } + } + return id; + }); + } + stopActivity(activity) { + return this._gw3Session.send({ + type: gwMessageDestroyActivity, + activity_id: activity.id, + reason_uri: "com.tick42.glue.activity.constants.destroyReason.general", + reason: "Destroying activity" + }).then((_) => true); + } + updateActivityContext(activity, context, fullReplace, removedKeys) { + if (fullReplace) { + return this._contexts.set(activity.id, context); + } + else { + removedKeys = removedKeys || []; + for (const x of removedKeys) { + context[x] = null; + } + return this._contexts.update(activity.id, context); + } + } + announceWindow(windowType, activityWindowId) { + throw new Error("Invalid operation 'announceWindow' for GW3 protocol"); + } + registerWindow(type, name, independent) { + let shouldSendReady = typeof this._connection.gatewayToken !== "undefined"; + const peerId = this._connection.peerId; + if (typeof window !== "undefined") { + const glue42gd = window.glue42gd; + if (glue42gd) { + shouldSendReady = typeof glue42gd.activityInfo !== "undefined"; + } + } + if (shouldSendReady) { + this._gw3Session.send({ + type: gwMessageReady, + }); + } + this.invokeCallbacks(this._activityWindowChangeCallbacks, new EntityEvent(new ActivityWindow(peerId, name, type, undefined, this.getAgmInstance(peerId), independent, this.generateWindowGetter(peerId), undefined), new EntityEventContext(EntityEventType.Added)), "register window"); + return Promise.resolve(peerId); + } + onActivityWindowChange(callback) { + this._activityWindowChangeCallbacks.push(callback); + } + createWindow(activityId, windowDefinition) { + if (!windowDefinition.layout) { + if (windowDefinition.left || windowDefinition.width || windowDefinition.height || windowDefinition.top) { + windowDefinition.layout = { + mode: "pixels", + cellSize: 1, + }; + } + } + const joinPeer = (id) => { + if (!activityId) { + return; + } + return this.joinActivity(activityId, id, windowDefinition.name) + .then(() => { + return id; + }); + }; + return this.sendCreateAndMapResultingMessagesToPromise({ + type: gwMessageCreatePeer, + peer_type: windowDefinition.type, + peer_name: windowDefinition.name || windowDefinition.type, + configuration: windowDefinition, + activity_id: activityId, + }, undefined, undefined, gwMessagePeerCreated, (msg, requestId) => msg.request_id === requestId, undefined, undefined, (msg) => msg.created_id, joinPeer) + .then(joinPeer); + } + async closeWindow(id) { + await this._gw3Session.send({ + type: gwMessageDestroyPeer, + destroy_peer_id: id + }); + } + getAnnouncementInfo() { + let activityId = this._config.activityId || (this._config.announcementInfo && this._config.announcementInfo.activityId); + let activityWindowType = (this._config.announcementInfo && this._config.announcementInfo.activityWindowType); + let activityWindowIndependent = (this._config.announcementInfo && this._config.announcementInfo.activityWindowIndependent); + let activityWindowName = (this._config.announcementInfo && this._config.announcementInfo.activityWindowName); + if (typeof window !== "undefined" && + typeof window.location !== "undefined" && + window.location.search && + typeof URLSearchParams === "function") { + const searchParams = new URLSearchParams(location.search.slice(1)); + activityWindowType = activityWindowType || searchParams.get("t42PeerType"); + activityWindowType = activityWindowType || searchParams.get("t42ActivityWindowType"); + if (typeof activityWindowIndependent === "undefined") { + activityWindowIndependent = searchParams.get("t42ActivityWindowIndependent"); + } + activityWindowName = activityWindowName || searchParams.get("t42ActivityWindowName"); + activityId = activityId || searchParams.get("t42ActivityId"); + } + activityWindowType = activityWindowType || "unknown"; + activityWindowIndependent = activityWindowIndependent || false; + activityWindowName = activityWindowName || this._connection.peerId; + return { + activityWindowId: undefined, + activityId, + activityWindowType, + activityWindowIndependent, + activityWindowName, + }; + } + joinActivity(activityId, windowId, name) { + const maybeName = (name && { name }) || {}; + return this._gw3Session.send({ + type: gwMmessageJoinActivity, + target_id: windowId, + activity_id: activityId, + ...maybeName + }).then(() => { + this.invokeCallbacks(this._activityWindowChangeCallbacks, new EntityEvent(new ActivityWindow(windowId, undefined, undefined, activityId, this.getAgmInstance(windowId), undefined, this.generateWindowGetter(windowId), undefined), new EntityEventContext(EntityEventType.ActivityWindowJoinedActivity)), "activity joined - ActivityWindow"); + this.invokeCallbacks(this._activityChangeCallbacks, new EntityEvent(new Activity(activityId, undefined, new ActivityStatus("created", undefined, undefined), undefined, undefined), new EntityEventContext(EntityEventType.Updated)), "activity joined - Activity"); + }); + } + leaveActivity(activityId, windowId) { + return this._gw3Session.send({ + type: gwMessageLeaveActivity, + target_id: windowId, + activity_id: activityId + }).then(() => { + this.invokeCallbacks(this._activityWindowChangeCallbacks, new EntityEvent(new ActivityWindow(windowId, undefined, undefined, null, this.getAgmInstance(windowId), undefined, this.generateWindowGetter(windowId), undefined), new EntityEventContext(EntityEventType.ActivityWindowLeftActivity)), "activity left - ActivityWindow"); + this.invokeCallbacks(this._activityChangeCallbacks, new EntityEvent(new Activity(activityId, undefined, new ActivityStatus("created", undefined, undefined), undefined, undefined), new EntityEventContext(EntityEventType.Updated)), "activity left - Activity"); + }); + } + getActivityTypes() { + return Promise.resolve([]); + } + getWindowTypes() { + return Promise.resolve([]); + } + getActivities() { + return Promise.resolve([]); + } + getActivityWindows() { + return Promise.resolve([]); + } + createStackedWindows(id, windowDefinitions, timeout) { + return undefined; + } + getWindowBounds(id) { + return undefined; + } + setWindowBounds(id, bounds) { + return undefined; + } + activateWindow(id, focus) { + return undefined; + } + setWindowVisibility(id, visible) { + return undefined; + } + cloneActivity(id, cloneOptions) { + return undefined; + } + attachActivities(from, to, tag) { + return this._gw3Session.send({ + type: gwNmessageMergeActivities, + into: to, + merge: from + }); + } + detachActivities(activityId, newActivityInfo) { + return this._gw3Session.send({ + type: gwMessageSplitActivities, + from: activityId, + }).then(() => ""); + } + onActivitiesAttached(callback) { + } + onActivitiesDetached(callback) { + } + onActivityAttachedDescriptorsRefreshed(callback) { + } + getAttachedDescriptors() { + return Promise.resolve([]); + } + getRandomRequestId() { + return this._connection.peerId + ":" + Math.floor(Math.random() * 1e9) + ""; + } + forwardAddedAndRemovedMessagesToEventHandler(addedMessageType, removedMessageType, mapper, handlers) { + const getGetEntityEvent = (isAdded) => (entity) => new EntityEvent(entity, new EntityEventContext(isAdded ? + EntityEventType.Added : + EntityEventType.Removed)); + const sub1 = addedMessageType && this.forwardMessageToEventHandler(addedMessageType, (msg) => mapper(msg, true), getGetEntityEvent(true), handlers); + const sub2 = removedMessageType && this.forwardMessageToEventHandler(removedMessageType, (msg) => mapper(msg, false), getGetEntityEvent(false), handlers); + return [sub1, sub2].filter((x) => x); + } + forwardMessageToEventHandler(messageType, mapper, getEntityEvent, handler) { + return this.subscribe(messageType, (msg) => { + mapper(msg) + .forEach((ent) => handler.forEach((h) => h(getEntityEvent(ent, msg)))); + }); + } + sendCreateAndMapResultingMessagesToPromise(msg, initiatedMessageType, initiatedMessageFilter, createdMessageType, createdMessageFilter, cancelledMessageType, cancelledMessageFilter, createdMessageToPromiseResolution, listenForRecreates) { + const reqId = this.getRandomRequestId(); + let resolveCreatedPromise; + let rejectCreatedPromise; + const createdPromise = new Promise((resolve, reject) => { + resolveCreatedPromise = resolve; + rejectCreatedPromise = reject; + }); + let initiatedMessageAck = null; + let initiatedSubscription; + let createdSubscription; + let cancelledSubscription; + let errorSubscription; + const dropSubscriptions = () => { + this.dropSubscription(initiatedSubscription); + if (!listenForRecreates) { + this.dropSubscription(createdSubscription); + } + this.dropSubscription(cancelledSubscription); + this.dropSubscription(errorSubscription); + }; + initiatedSubscription = initiatedMessageType && + this.subscribe(initiatedMessageType, (msg4) => { + if (!initiatedMessageFilter(msg4, reqId)) { + return; + } + initiatedMessageAck = msg4; + this.dropSubscription(initiatedSubscription); + }); + let recreated = false; + createdSubscription = + this.subscribe(createdMessageType, (msg1) => { + if (!createdMessageFilter(msg1, reqId, initiatedMessageAck)) { + return; + } + if (recreated) { + if (listenForRecreates) { + listenForRecreates(createdMessageToPromiseResolution(msg1)); + } + } + else { + recreated = true; + resolveCreatedPromise(createdMessageToPromiseResolution(msg1)); + } + }); + cancelledSubscription = cancelledMessageType && + this.subscribe(cancelledMessageType, (msg2) => { + if (!cancelledMessageFilter(msg2, reqId, initiatedMessageAck)) { + return; + } + rejectCreatedPromise(msg2); + }); + errorSubscription = cancelledMessageType && + this.subscribe(gwMmessageError, (msg3) => { + if (msg3.request_id !== reqId) { + return; + } + rejectCreatedPromise(msg3); + }); + msg.request_id = reqId; + const toReturn = this._gw3Session + .send(msg) + .then(() => { + return createdPromise; + }); + toReturn.then(dropSubscriptions, dropSubscriptions); + return toReturn; + } + peerFactoryIdAndOwnerIdToWindowType(factoryId, ownerId) { + const peerType = this._peerIdAndFactoryIdToPeerType[ownerId + ":" + factoryId]; + if (!peerType) { + return null; + } + else { + return new WindowType(peerType, undefined); + } + } + subscribe(messageType, handler) { + const sub = this._connection.on(messageType, (msg) => handler.bind(this)(msg)); + this._gw3Subscriptions.push(sub); + return sub; + } + dropSubscription(subscription) { + if (subscription) { + this._connection.off(subscription); + delete this._gw3Subscriptions[this._gw3Subscriptions.indexOf(subscription)]; + } + } + invokeCallbacks(callbacks, event, description) { + callbacks.forEach((cb) => { + try { + cb(event); + } + catch (err) { + this._logger.error(`Error in ${description || event.context.type} callback: ` + JSON.stringify(err)); + } + }); + } + handleActivityCreatedMessage(msg) { + if (!msg.context_id) { + this._logger.error("Activity created with unknown context_id: " + msg.activity_id); + } + else { + if (!this._contextSubscriptions[msg.activity_id]) { + this.subscribeToContext(msg); + } + } + } + async subscribeToContext(msg) { + const activityId = msg.activity_id; + this._contextSubscriptions[activityId] = + await this._contexts.subscribe(activityId, (data, updated, removed) => { + const event = new EntityEvent(new Activity(activityId, undefined, undefined, data, undefined), new ActivityContextChangedEventContext(data, updated, removed)); + this.invokeCallbacks(this._activityChangeCallbacks, event, "context updated"); + }); + } + handleActivityDestroyedMessage(msg) { + const unsubscribeContext = this._contextSubscriptions[msg.activity_id]; + if (typeof unsubscribeContext === "function") { + unsubscribeContext(); + } + delete this._contextSubscriptions[msg.activity_id]; + } + handlePeerFactoriesAdded(msg) { + msg.factories.forEach((entity) => { + this._peerIdAndFactoryIdToPeerType[msg.owner_id + ":" + entity.id] = entity.peer_type; + }); + } + handlePeerFactoriesRemoved(msg) { + msg.factory_ids.forEach((factoryId) => { + delete this._peerIdAndFactoryIdToPeerType[msg.owner_id + ":" + factoryId]; + }); + } + forwardActivityTypeMessagesToStatusEventHandlers() { + this.forwardAddedAndRemovedMessagesToEventHandler(gwMmessageActivityTypesAdded, gwMessageActivityTypesRemoved, (msg, isAdded) => isAdded + ? msg.types.map((t) => GW3Bridge.activityTypeGwMessageEntityToActivityType(t, undefined)) + : msg.types.map((t) => new ActivityType(t.name, undefined, undefined, undefined)), this._activityTypeStatusChangeCallbacks); + } + forwardActivityCreatedAndJoinedActivityToActivityWindowEventHandlers() { + for (const activityCreatedMessage of [gwMessageActivityCreated, gwMessageJoinedActivity, gwMessageOwnerChanged]) { + this.forwardMessageToEventHandler(activityCreatedMessage, (msg) => ([msg.owner || { ...msg, type: msg.peer_type, name: msg.peer_name, peer_id: msg.owner_id }]) + .concat(msg.participants || []) + .map((info) => new ActivityWindow(info.peer_id, info.name, info.type, msg.activity_id, this.getAgmInstance(info.peer_id), undefined, this.generateWindowGetter(info.peer_id), undefined)), (ent, msg) => new EntityEvent(ent, new EntityEventContext(EntityEventType.ActivityWindowJoinedActivity)), this._activityWindowChangeCallbacks); + } + } + forwardActivityMessagesToStatusEventHandlers() { + for (const createdMessage of [gwMessageActivityCreated, gwMessageJoinedActivity]) { + this.forwardMessageToEventHandler(createdMessage, (msg) => [GW3Bridge.activityGwMessageToActivity(msg, new ActivityStatus("started", "", new Date()))], (ent, msg) => GW3Bridge.activityToActivityStatusChangeEvent(ent), this._activityChangeCallbacks); + } + this.forwardMessageToEventHandler(gwMessageActivityDestroyed, (msg) => [GW3Bridge.activityGwMessageToActivity(msg, new ActivityStatus("destroyed", msg.reason, new Date()))], (ent, msg) => GW3Bridge.activityToActivityStatusChangeEvent(ent), this._activityChangeCallbacks); + this.forwardMessageToEventHandler(gwMessageActivityInitiated, (msg) => [GW3Bridge.activityGwMessageToActivity(msg, new ActivityStatus("created", "", new Date()))], (ent, msg) => GW3Bridge.activityToActivityStatusChangeEvent(ent), this._activityChangeCallbacks); + this.forwardMessageToEventHandler(gwMessageOwnerChanged, (msg) => [GW3Bridge.activityGwMessageToActivity(msg, new ActivityStatus("created", "", new Date()))], (ent, msg) => GW3Bridge.activityToActivityStatusChangeEvent(ent), this._activityChangeCallbacks); + } + forwardPeerFactoryMessagesToStatusEventHandlers() { + this.forwardAddedAndRemovedMessagesToEventHandler(gwMessagePeerFactoriesAdded, gwMessagePeerFactoriesRemoved, (msg, isAdded) => isAdded + ? msg.factories.map(GW3Bridge.peerFactoryGwMessageEntityToWindowType) + : msg.factory_ids.map((id) => this.peerFactoryIdAndOwnerIdToWindowType(id, msg.owner_id)).filter((x) => x != null), this._windowTypeStatusChangeCallbacks); + } + forwardPeerFactoryMessagesToPeerFactoryRequests() { + this.subscribe(gwMessagePeerRequested, (msg) => { + const factory = this._peerFactoriesRegisteredByUs[msg.peer_factory]; + if (!factory) { + this._gw3Session.send({ + type: gwMmessageError, + request_id: msg.request_id, + reason: `Unknown peer factory ${msg.peer_factory}` + }); + return; + } + try { + const configuration = msg.configuration || {}; + configuration.gateway_token = configuration.gateway_token || msg.gateway_token; + configuration.peer_factory = configuration.peer_factory || msg.peer_factory; + const promise = factory({ + activityId: msg.activity && msg.activity.id, + activityType: msg.activity && msg.activity.type, + type: msg.configuration && msg.configuration.type, + gwToken: configuration.gateway_token, + configuration + }); + if (promise && promise.then && promise.catch) { + promise.catch((err) => this._gw3Session.send({ + type: gwMmessageError, + request_id: msg.request_id, + reason: err && (err.message || JSON.stringify(err)) + })); + } + } + catch (err) { + this._gw3Session.send({ + type: gwMmessageError, + request_id: msg.request_id, + reason: err && (err.message || JSON.stringify(err)) + }); + } + }); + } + forwardActivityWindowMessagesToEventHandlers() { + for (const joinedMessage of [gwMessageActivityJoined, gwMessageJoinedActivity]) { + this.subscribe(joinedMessage, (msg) => { + const joinedId = (joinedMessage === gwMessageActivityJoined) ? msg.joined_id : msg.peer_id; + const joinedType = (joinedMessage === gwMessageActivityJoined) ? msg.joined_type : msg.peer_type; + const joinedName = (joinedMessage === gwMessageActivityJoined) ? msg.joined_name : msg.peer_name; + const entity = new ActivityWindow(joinedId, joinedName, joinedType, msg.activity_id, this.getAgmInstance(joinedId), undefined, this.generateWindowGetter(joinedId), undefined); + if (!this._contextSubscriptions[msg.activity_id]) { + this.subscribeToContext(msg).then(() => { + if (joinedMessage === gwMessageJoinedActivity) { + this._activityJoinedPromiseResolve({}); + } + }); + } + else if (joinedMessage === gwMessageJoinedActivity) { + this._activityJoinedPromiseResolve({}); + } + this.invokeCallbacks(this._activityWindowChangeCallbacks, new EntityEvent(entity, new EntityEventContext(EntityEventType.ActivityWindowJoinedActivity)), joinedMessage); + }); + } + this.subscribe(gwMessageActivityLeft, (msg) => { + const entity = new ActivityWindow(msg.left_id, undefined, undefined, null, this.getAgmInstance(msg.left_id), undefined, this.generateWindowGetter(msg.left_id), undefined); + this.invokeCallbacks(this._activityWindowChangeCallbacks, new EntityEvent(entity, new EntityEventContext(EntityEventType.ActivityWindowLeftActivity)), gwMessageActivityLeft); + }); + this.forwardAddedAndRemovedMessagesToEventHandler(gwMessagePeerCreated, undefined, (msg) => [ + new ActivityWindow(msg.created_id, undefined, undefined, undefined, undefined, undefined, this.generateWindowGetter(msg.created_id), undefined) + ], this._activityWindowChangeCallbacks); + } + getAgmInstance(id) { + return this._config.agm.servers().find((s) => s.peerId === id || s.windowId === id); + } + generateWindowGetter(peerId) { + return () => { + const server = this.getAgmInstance(peerId); + if (!server) { + return; + } + const windowId = server.windowId; + return this._config.windows.list().filter((w) => w.id === windowId)[0]; + }; + } + isOverrideTypeDefinition(value) { + if (typeof value === "undefined") { + return false; + } + if (value.owner) { + return true; + } + return false; + } + } + + class ActivityMy { + constructor(manager, windows) { + this._myAttached = []; + this._myDetached = []; + this._myAttachedTo = []; + this._myDetachedFrom = []; + this._myActivityFrameColorChanged = []; + this._myActivityJoinedCallbacks = []; + this._myActivityRemovedCallbacks = []; + this._myContextUpdateCallbacks = []; + this._logger = Logger.Get(this); + this._m = manager; + manager.ready() + .then((am) => { + am.subscribeActivityContextChanged(this._subscribeMyContextChanged.bind(this)); + am.subscribeWindowEvents(this._subscribeMyWindowEvent.bind(this)); + am.subscribeActivitiesAttached(this._subscribeActivitiesAttached.bind(this)); + am.subscribeActivitiesDetached(this._subscribeActivitiesDetached.bind(this)); + if (windows) { + windows.onWindowFrameColorChanged(this._subscribeWindowFrameColorChanged.bind(this)); + } + }); + } + get window() { + if (isUndefinedOrNull(this._w)) { + const announcedWindows = this._m.announcedWindows; + if (announcedWindows.length > 0) { + this._w = announcedWindows[0]; + } + } + return this._w; + } + get activity() { + const myWin = this.window; + if (isUndefinedOrNull(myWin)) { + return undefined; + } + return myWin.activity; + } + createWindow(windowType) { + return this._m.createWindow(this.activity, windowType); + } + createStackedWindows(windowTypes, timeout) { + return this._m.createStackedWindows(this.activity, windowTypes, timeout); + } + get context() { + const activity = this.activity; + if (isUndefined(activity)) { + return {}; + } + return activity.context; + } + updateContext(context, callback) { + const activity = this.activity; + if (isUndefined(activity)) { + return new Promise((resolve, reject) => { + reject("Not in activity"); + }); + } + return activity.updateContext(context, callback); + } + setContext(context, callback) { + const activity = this.activity; + if (isUndefined(activity)) { + return new Promise((resolve, reject) => { + reject("Not in activity"); + }); + } + return activity.setContext(context, callback); + } + onActivityJoined(callback) { + this._myActivityJoinedCallbacks.push(callback); + const myWin = this.window; + if (!isUndefinedOrNull(myWin) && !isUndefinedOrNull(myWin.activity)) { + callback(myWin.activity); + } + } + onActivityLeft(callback) { + this._myActivityRemovedCallbacks.push(callback); + } + onContextChanged(callback) { + this._myContextUpdateCallbacks.push(callback); + const myWin = this.window; + if (isUndefinedOrNull(myWin)) { + return; + } + const activity = myWin.activity; + if (isUndefinedOrNull(activity)) { + return; + } + callback(activity.context, activity.context, [], activity); + } + clone(options, callback) { + const act = this.activity; + return this._m.clone(act, options, callback); + } + attach(activity, tag) { + let activityId; + if (typeof activity === "string") { + activityId = activity; + } + else { + activityId = activity.id; + } + return this._m.attachActivities(activityId, this.activity.id, tag); + } + onActivityAttached(callback) { + this._myAttached.push(callback); + } + onActivityDetached(callback) { + this._myDetached.push(callback); + } + onAttachedToActivity(callback) { + this._myAttachedTo.push(callback); + } + onDetachedFromActivity(callback) { + this._myDetachedFrom.push(callback); + } + get attached() { + if (!this.activity) { + return []; + } + return this.activity.attached; + } + setFrameColor(color, callback) { + if (this.activity) { + return this.activity.setFrameColor(color, callback); + } + else { + return Promise.resolve(null); + } + } + getFrameColor() { + if (this.activity) { + return this.activity.getFrameColor(); + } + return ""; + } + onFrameColorChanged(callback) { + this._myActivityFrameColorChanged.push(callback); + } + _subscribeMyContextChanged(activity, context, delta, removed) { + const myWin = this.window; + if (isUndefinedOrNull(myWin)) { + return; + } + const myActivity = myWin.activity; + if (isUndefinedOrNull(myActivity)) { + return; + } + if (activity.id !== myActivity.id) { + return; + } + this._notifyMyContextChanged(activity, context, delta, removed); + } + _subscribeMyWindowEvent(activity, window, event) { + if (isUndefinedOrNull(this.window)) { + return; + } + if (this.window.id !== window.id) { + return; + } + if (event === EntityEventType.ActivityWindowJoinedActivity) { + this._notifyMyWindowEvent(activity, this._myActivityJoinedCallbacks); + this._notifyMyContextChanged(activity, activity.context, null, null); + } + else if (event === EntityEventType.ActivityWindowLeftActivity) { + this._notifyMyWindowEvent(activity, this._myActivityRemovedCallbacks); + } + } + _notifyMyWindowEvent(activity, callbackStore) { + callbackStore.forEach((element) => { + try { + element(activity, event); + } + catch (e) { + this._logger.warn("error in user callback " + e); + } + }); + } + _notifyMyContextChanged(activity, context, delta, removed) { + delta = delta || {}; + removed = removed || []; + this._myContextUpdateCallbacks.forEach((element) => { + try { + element(context, delta, removed, activity); + } + catch (e) { + this._logger.warn("error in user callback " + e); + } + }); + } + _notifyAttached(state) { + this._myAttached.forEach((cb) => { + try { + cb(state); + } + catch (e) { + this._logger.warn("error in user callback " + e); + } + }); + } + _notifyDetached(state) { + this._myDetached.forEach((cb) => { + try { + cb(state); + } + catch (e) { + this._logger.warn("error in user callback " + e); + } + }); + } + _notifyAttachedTo(state) { + this._myAttachedTo.forEach((cb) => { + try { + cb(this.activity, state); + } + catch (e) { + this._logger.warn("error in user callback " + e); + } + }); + } + _notifyDetachedFrom(detached, existing, state) { + this._myDetachedFrom.forEach((cb) => { + try { + cb(detached, existing, state); + } + catch (e) { + this._logger.warn("error in user callback " + e); + } + }); + } + _subscribeActivitiesAttached(newAct, state) { + const myWin = this.window; + if (isUndefinedOrNull(myWin)) { + return; + } + const myActivity = myWin.activity; + if (isUndefinedOrNull(myActivity)) { + return; + } + if (newAct.id !== myActivity.id) { + return; + } + if (state.windowIds.indexOf(myWin.id) >= 0) { + this._notifyAttachedTo(state); + return; + } + this._notifyAttached(state); + } + _subscribeActivitiesDetached(newAct, oldAct, state) { + const myWin = this.window; + if (isUndefinedOrNull(myWin)) { + return; + } + const myActivity = myWin.activity; + if (isUndefinedOrNull(myActivity)) { + return; + } + if (oldAct.id === myActivity.id) { + this._notifyDetached(state); + } + if (newAct.id === myActivity.id) { + this._notifyDetachedFrom(newAct, oldAct, state); + } + } + _subscribeWindowFrameColorChanged(window) { + const act = this.activity; + if (!act) { + return; + } + if (!act.owner) { + return; + } + if (act.owner.underlyingWindow.id === window.id) { + this._myActivityFrameColorChanged.forEach((callback) => { + callback(window.frameColor); + }); + } + } + } + + class ReadyMarker { + constructor(name, signalsToWait) { + this._logger = Logger.Get("ReadyMarker [" + name + "]"); + this._logger.debug("Initializing ready marker for '" + name + "' with " + signalsToWait + " signals to wait"); + if (signalsToWait <= 0) { + throw new Error("Invalid signal number. Should be > 0"); + } + this._signals = signalsToWait; + this._callbacks = []; + this._name = name; + } + setCallback(callback) { + if (this.isSet()) { + callback(undefined); + return; + } + else if (this.isError()) { + callback(this._error); + return; + } + this._callbacks.push(callback); + } + signal(message) { + this._logger.debug("Signaled - " + message + " - signals left " + (this._signals - 1)); + this._signals--; + if (this._signals < 0) { + throw new Error("Error in ready marker '" + this._name + " - signals are " + this._signals); + } + if (this.isSet()) { + this._callbacks.forEach((callback) => { + callback(undefined); + }); + } + } + error(error) { + this._error = error; + this._callbacks.forEach((errorCallback) => { + errorCallback(error); + }); + } + isSet() { + if (this.isError()) { + return false; + } + return this._signals === 0; + } + isError() { + return !isUndefined(this._error); + } + getError() { + return this._error; + } + } + + class EntityObservableCollection { + constructor(processNew) { + this._items = {}; + this._listeners = []; + this._processNew = processNew; + } + addOne(item) { + this.add([item]); + } + add(items) { + items.forEach((element) => { + this.process(new EntityEvent(element, new EntityEventContext(EntityEventType.Added))); + }); + } + process(event) { + const context = event.context; + const type = context.type; + const entity = event.entity; + if (type === EntityEventType.StatusChange && + !context.oldStatus) { + const act = this._items[entity.id]; + if (act) { + context.oldStatus = act.status; + } + } + if (type === EntityEventType.StatusChange && + context.oldStatus && + context.newStatus && + context.oldStatus.state === + context.newStatus.state) { + context.type = EntityEventType.Updated; + } + if (typeof htmlContainer === "undefined") { + if (type === EntityEventType.ActivityWindowJoinedActivity && + this._items[entity.id] && + this._items[entity.id].activity) { + context.type = EntityEventType.Updated; + } + if (type === EntityEventType.ActivityWindowLeftActivity && + this._items[entity.id] && + !this._items[entity.id].activity) { + context.type = EntityEventType.Updated; + } + } + const internalEntity = this._updateInternalCollections(entity, type, context); + this._notifyListeners(internalEntity, context); + return internalEntity; + } + get() { + const result = []; + for (const key in this._items) { + if (this._items.hasOwnProperty(key)) { + const element = this._items[key]; + result.push(element); + } + } + return result; + } + getByName(name) { + for (const key in this._items) { + if (key === name) { + return this._items[key]; + } + } + return undefined; + } + getOrWait(name) { + return new Promise((resolve) => { + const entityAddedHandler = (entity) => { + if (entity.id !== name) { + return; + } + resolve(entity); + this.unsubscribe(entityAddedHandler); + }; + this.subscribe(entityAddedHandler); + const window = this.getByName(name); + if (window) { + this.unsubscribe(entityAddedHandler); + resolve(window); + return; + } + }); + } + subscribe(handler) { + this._listeners.push(handler); + Object.keys(this._items).forEach((key) => { + const element = this._items[key]; + handler(element, new EntityEventContext(EntityEventType.Added.toString())); + }); + return () => { + this.unsubscribe(handler); + }; + } + unsubscribe(handler) { + const index = this._listeners.indexOf(handler); + if (index !== -1) { + this._listeners.splice(index, 1); + } + } + _notifyListeners(entity, context) { + this._listeners.forEach((listener) => { + try { + listener(entity, context); + } + catch (e) { + return; + } + }); + } + _updateInternalCollections(entity, type, context) { + const entityAsAny = entity; + const isActivityDestroy = (type === EntityEventType.StatusChange && + entityAsAny.status && + entityAsAny.status.state === ActivityState.Destroyed) || + (type === EntityEventType.StatusChange && + context && + context.newStatus && + context.newStatus.state === ActivityState.Destroyed); + const isWindowClose = type === EntityEventType.Closed; + const isTypeRemove = type === EntityEventType.Removed && typeof entityAsAny.isIndependent === "undefined"; + if (isTypeRemove || isWindowClose || isActivityDestroy) { + const oldEntity = this._items[entity.id]; + delete this._items[entity.id]; + this._processNew(entity); + if (oldEntity) { + entity._beforeDelete(oldEntity); + } + return entity; + } + else { + const key = entity.id; + if (!this._items.hasOwnProperty(key)) { + this._processNew(entity); + this._items[entity.id] = entity; + } + else { + this._items[entity.id]._update(entity); + } + } + return this._items[entity.id]; + } + } + + class ActivityManager { + get usingHc() { + return this._bridge.bridgeType === "HC"; + } + get announcedWindows() { + return this._announcedWindows; + } + set announcedWindows(v) { + throw new Error("not allowed"); + } + constructor(bridge, autoAnnounce, windows) { + this._logger = Logger.Get("activityManager"); + this._announcedWindows = []; + this._attachedCallbacks = []; + this._detachedCallbacks = []; + this._frameColorChangesCallbacks = []; + this._windowHandlers = []; + this._bridge = bridge; + this._activityTypes = new EntityObservableCollection((e) => this._grabEntity(e)); + this._windowTypes = new EntityObservableCollection((e) => this._grabEntity(e)); + this._activities = new EntityObservableCollection((e) => this._grabEntity(e)); + this._windows = new EntityObservableCollection((e) => this._grabEntity(e)); + this._dataReadyMarker = new ReadyMarker("Activity Manager Data", ["GetActivityTypes", "GetWindowTypes", "GetActivities", "GetWindows"].length); + this._descriptorsMarker = new ReadyMarker("Attached Activities Descriptors", ["GetDescriptors"].length); + if (autoAnnounce) { + this._readyMarker = new ReadyMarker("Activity Manager Announce", ["Announcement"].length); + this._dataReadyMarker.setCallback((dataErr) => { + if (dataErr) { + this._readyMarker.error(dataErr); + } + this._descriptorsMarker.setCallback((err) => { + if (err) { + this._readyMarker.error(err); + } + this._logger.debug("Auto announcing window"); + this.announceWindow() + .then((w) => { + this._announcedWindows.push(w); + this._readyMarker.signal("Successfully announced window with id '" + w.id + "'"); + }) + .catch((errCatch) => { + this._logger.debug("Will not announce window - " + errCatch); + this._readyMarker.signal(); + }); + }); + this.refreshDescriptors(); + }); + } + else { + this._readyMarker = this._dataReadyMarker; + } + this._bridge.onActivitiesAttached((e) => { + this._handleActivitiesAttached(e); + }); + this._bridge.onActivitiesDetached((e) => { + this._handleActivitiesDetached(e); + }); + this._bridge.onActivityAttachedDescriptorsRefreshed((e) => { + this._handleActivityDescriptorsRefreshed(e); + }); + if (windows) { + windows.onWindowFrameColorChanged(this._handleWindowFrameColorChanged.bind(this)); + } + this._bridge.init(); + this._subscribeForData(); + this._bridge + .initReady() + .then((aw) => { + this._getInitialData(); + }) + .catch((error) => { + console.log(error); + }); + } + ready(callback) { + const promise = new Promise((resolve, reject) => { + this._readyMarker.setCallback((err) => { + if (!err) { + resolve(this); + } + else { + reject(this._readyMarker.getError()); + } + }); + }); + return nodeify(Promise.all([this._bridge.ready(), promise]).then(() => this), callback); + } + getActivityTypes() { + return this._activityTypes.get(); + } + getActivityType(name) { + return this._activityTypes.getByName(name); + } + registerActivityType(activityTypeName, ownerWindowType, helperWindowTypes, config, description, callback) { + const promise = new Promise((resolve, reject) => { + if (isUndefinedOrNull(activityTypeName)) { + reject("activityTypeName argument can not be undefined"); + return; + } + if (!isString(activityTypeName)) { + reject("activityTypeName should be string"); + return; + } + const actType = this.getActivityType(activityTypeName); + if (!isUndefinedOrNull(actType)) { + reject("Activity type '" + activityTypeName + "' already exists"); + return; + } + let ownerDefinition; + if (isUndefined(ownerWindowType)) { + reject("Owner window type can not be undefined"); + return; + } + if (isString(ownerWindowType)) { + ownerDefinition = { type: (ownerWindowType), name: "", isIndependent: false, arguments: {} }; + } + else { + ownerDefinition = (ownerWindowType); + } + const helperDefinitions = []; + if (!isUndefined(helperWindowTypes) && isArray(helperWindowTypes)) { + for (const index in helperWindowTypes) { + const item = helperWindowTypes[index]; + if (isString(item)) { + const definition = { + type: (item), + name: "", + isIndependent: false, + arguments: {}, + relativeTo: "", + relativeDirection: "", + windowStyleAttributes: {} + }; + helperDefinitions.push(definition); + } + else { + helperDefinitions.push(item); + } + } + } + this._bridge + .registerActivityType(activityTypeName, ownerDefinition, helperDefinitions, config, description) + .then((activityType) => { + this._grabEntity(activityType); + resolve(activityType); + }) + .catch((error) => { + reject(error); + }); + }); + return nodeify(promise, callback); + } + unregisterActivityType(type, callback) { + const promise = new Promise((resolve, reject) => { + const actType = this.getActivityType(type); + if (isUndefined(actType)) { + reject("Activity type '" + type + "' does not exists"); + return; + } + this._bridge.unregisterActivityType(type).then(() => resolve(actType), reject); + }); + return nodeify(promise, callback); + } + initiate(activityType, context, callback, configuration) { + const promise = new Promise((resolve, reject) => { + const actType = this.getActivityType(activityType); + if (isUndefined(actType)) { + reject("Activity type '" + activityType + "' does not exists"); + return; + } + this._bridge + .initiateActivity(activityType, context, configuration) + .then((actId) => { + this._activities + .getOrWait(actId) + .then((act) => { + resolve(act); + }) + .catch((err) => reject(err)); + }) + .catch((err) => { + reject(err); + }); + }); + return nodeify(promise, callback); + } + subscribeActivityTypeEvents(handler) { + this._activityTypes.subscribe((at, context) => { + handler(at, context.type); + }); + } + getWindowTypes() { + return this._windowTypes.get(); + } + getWindowType(name) { + return this._windowTypes.getByName(name); + } + registerWindowFactory(windowType, factoryMethod, callback) { + const promise = new Promise((resolve, reject) => { + if (isUndefinedOrNull(windowType)) { + reject("no windowType specified"); + return; + } + if (isObject(windowType)) { + windowType = windowType.getName(); + } + else if (!isString(windowType)) { + reject("windowType should be string or object that has getName method"); + return; + } + this._bridge + .registerWindowFactory(windowType, factoryMethod) + .then((v) => { + resolve(v); + }) + .catch((err) => { + reject(err); + }); + }); + return nodeify(promise, callback); + } + unregisterWindowFactory(windowType, callback) { + const promise = new Promise((resolve, reject) => { + if (isUndefinedOrNull(windowType)) { + reject("no windowType specified"); + return; + } + if (!isString(windowType)) { + reject("windowType should be a string"); + return; + } + this._bridge + .unregisterWindowFactory(windowType) + .then((v) => { + resolve(v); + }) + .catch((err) => { + reject(err); + }); + }); + return nodeify(promise, callback); + } + getActivities(activityType) { + let act = this._activities.get(); + act = act.filter((a) => a._ownerId); + if (!activityType) { + return act; + } + let types = activityType; + if (isString(activityType)) { + types = [activityType]; + } + else if (activityType instanceof ActivityType) { + types = [activityType.name]; + } + else if (activityType instanceof Array) ; + else { + throw new Error("Invalid input argument 'activityType' = " + activityType); + } + return act.filter((at) => { + const type = at.type; + return some(types, (t) => { + return type.id === t.id; + }); + }); + } + getActivityById(id) { + return this._activities.getByName(id); + } + announceWindow(activityWindowId, windowType) { + const promise = new Promise((resolve, reject) => { + const announcementInfo = this._bridge.getAnnouncementInfo(); + if (isUndefined(activityWindowId)) { + activityWindowId = announcementInfo.activityWindowId; + } + if (isUndefined(windowType)) { + windowType = announcementInfo.activityWindowType; + } + if (isUndefinedOrNull(windowType)) { + throw new Error("Can not announce - unknown windowType"); + } + const activityId = announcementInfo && announcementInfo.activityId; + if (isUndefinedOrNull(activityWindowId)) { + this._logger.debug("Registering window with type:'" + windowType + "', name:'" + announcementInfo.activityWindowName + "', ind.:'" + announcementInfo.activityWindowIndependent + "'"); + this._bridge.registerWindow(windowType, announcementInfo.activityWindowName, announcementInfo.activityWindowIndependent) + .then(this._windows.getOrWait.bind(this._windows)) + .then((w) => { + if (activityId) { + return this._activities.getOrWait(activityId).then((_) => w); + } + else { + return w; + } + }) + .then((w) => { + resolve(w); + }) + .catch((err) => { + this._logger.error(err); + }); + } + else { + this._logger.debug("Announcing window with id '" + activityWindowId + "' and type '" + windowType + "'"); + const currentWindow = this._windows.getByName(activityWindowId); + if (!isUndefinedOrNull(currentWindow)) { + this._logger.debug("Window with id '" + activityWindowId + "' already announced - reusing the window"); + resolve(currentWindow); + return; + } + const windowEventHandler = (a, w, e) => { + if (activityWindowId === w.id) { + if (e === EntityEventType.ActivityWindowJoinedActivity) { + const activity = w.activity; + if (isUndefined(activity)) { + reject("UNDEFINED ACTIVITY"); + } + this._logger.trace("Got joined event for id '" + activityWindowId + "'"); + resolve(w); + this.unsubscribeWindowEvents(windowEventHandler); + } + } + }; + this.subscribeWindowEvents(windowEventHandler); + this._logger.trace("Waiting for joined event for id '" + activityWindowId + "'"); + this._bridge.announceWindow(windowType, activityWindowId); + } + }); + return promise; + } + subscribeWindowTypeEvents(handler) { + this._windowTypes.subscribe((wt, context) => { + handler(wt, context.type); + }); + } + subscribeActivityEvents(handler) { + return this._activities.subscribe((act, context) => { + if (context.type === EntityEventType.StatusChange) { + const p = context; + handler(act, p.newStatus, p.oldStatus); + } + if (context.type === EntityEventType.Removed || + (context.type === EntityEventType.StatusChange && + context.newStatus.getState() === ActivityState.Destroyed)) { + for (const window of this._windows.get()) { + if (window.activity && window.activity.id === act.id) { + this._windows.process(new EntityEvent(window, new EntityEventContext(EntityEventType.ActivityWindowLeftActivity))); + } + } + } + }); + } + subscribeWindowEvents(handler) { + const wrappingHandler = (window, context) => { + let eventType = context.type; + if (eventType === EntityEventType.Added) { + eventType = "opened"; + } + handler(window.activity, window, eventType); + }; + this._windowHandlers.push([handler, wrappingHandler]); + return this._windows.subscribe(wrappingHandler); + } + unsubscribeWindowEvents(handler) { + const found = this._windowHandlers.find((pair) => pair[0] === handler); + if (found) { + this._windowHandlers.splice(this._windowHandlers.indexOf(found), 1); + this._windows.unsubscribe(found[1]); + } + } + createWindow(activity, windowTypeOrConfiguration, callback) { + const promise = new Promise((resolve, reject) => { + if (isUndefinedOrNull(windowTypeOrConfiguration)) { + reject("windowType is undefined"); + } + let windowDefinition; + if (isString(windowTypeOrConfiguration)) { + windowDefinition = { type: (windowTypeOrConfiguration), name: "", isIndependent: false, arguments: {} }; + } + else if (windowTypeOrConfiguration instanceof WindowType) { + windowDefinition = { + type: windowTypeOrConfiguration.type || windowTypeOrConfiguration.id, + name: windowTypeOrConfiguration.name || windowTypeOrConfiguration.type || windowTypeOrConfiguration.id, + isIndependent: false + }; + } + else { + const invalidKeys = ["url"]; + const filteredWindowTypeOrConfiguration = {}; + Object.keys(windowTypeOrConfiguration).forEach((key) => { + if (invalidKeys.indexOf(key) === -1) { + filteredWindowTypeOrConfiguration[key] = windowTypeOrConfiguration[key]; + } + }); + windowDefinition = filteredWindowTypeOrConfiguration; + } + let relativeToWindow; + if (!isUndefinedOrNull(windowDefinition.relativeTo)) { + relativeToWindow = windowDefinition.relativeTo; + if (typeof relativeToWindow === "string") { + const windows = this.getWindows({ type: relativeToWindow }); + if (!isUndefinedOrNull(windows) && windows.length > 0) { + windowDefinition.relativeTo = windows[0].id; + } + } + else if (!isUndefinedOrNull(relativeToWindow.type)) { + const windows = this.getWindows({ type: relativeToWindow.type }); + if (!isUndefinedOrNull(windows) && windows.length > 0) { + windowDefinition.relativeTo = windows[0].id; + } + } + else if (!isUndefinedOrNull(relativeToWindow.windowId)) { + windowDefinition.relativeTo = relativeToWindow.windowId; + } + } + this._bridge.createWindow(activity && activity.id, windowDefinition) + .then((wid) => { + this._logger.debug("Window created, waiting for window entity with id " + wid); + const handler = (window, context) => { + if (window.id === wid && (!activity || window.activity)) { + this._logger.debug("Got entity window with id " + wid); + resolve(window); + this._windows.unsubscribe(handler); + } + }; + this._windows.subscribe(handler); + }) + .catch((err) => { + reject(err); + }); + }); + return nodeify(promise, callback); + } + createStackedWindows(activity, relativeWindowTypes, timeout, callback) { + const promise = new Promise((resolve, reject) => { + if (isUndefinedOrNull(activity)) { + reject("activity is undefined"); + } + if (isUndefinedOrNull(relativeWindowTypes)) { + reject("relativeWindowTypes is undefined"); + } + if (!Array.isArray(relativeWindowTypes)) { + reject("relativeWindowTypes has to be an array"); + } + if (isUndefinedOrNull(timeout)) { + timeout = 20000; + } + const windowDefinitions = []; + relativeWindowTypes.forEach((element) => { + let windowDefinition; + if (isString(element)) { + windowDefinition = { type: (element), name: "", isIndependent: false, arguments: {} }; + } + else { + windowDefinition = (element); + } + windowDefinition.stackedWindow = true; + windowDefinition.timeout = timeout; + let relativeToWindow; + if (!isUndefinedOrNull(windowDefinition.relativeTo)) { + relativeToWindow = windowDefinition.relativeTo; + if (!isUndefinedOrNull(relativeToWindow.type)) { + windowDefinition.relativeTo = relativeToWindow.type; + } + else if (!isUndefinedOrNull(relativeToWindow.windowId)) { + const windows = this.getWindows({ id: relativeToWindow.windowId }); + if (!isUndefinedOrNull(windows) && windows.length > 0) { + windowDefinition.relativeTo = windows[0].type.name; + } + } + } + windowDefinitions.push(windowDefinition); + }); + const tasks = []; + windowDefinitions.forEach((wd) => tasks.push(this.createWindow(activity, wd))); + Promise.all(tasks).then(resolve).catch(reject); + }); + return nodeify(promise, callback); + } + addWindowToActivity(activity, window, callback) { + const toReturn = this._bridge.joinActivity(activity.id, window.id) + .then(() => window); + nodeify(toReturn, callback); + return toReturn; + } + leaveWindowFromActivity(activity, window, callback) { + const toReturn = this._bridge.leaveActivity(activity.id, window.id) + .then(() => window); + nodeify(toReturn, callback); + return toReturn; + } + setActivityContext(activity, context, callback) { + const promise = new Promise((resolve, reject) => { + if (isUndefinedOrNull(activity)) { + reject("activity can not be null"); + } + this._bridge + .updateActivityContext(activity, context, true) + .then((_) => { + resolve(activity); + }) + .catch((err) => { + reject(err); + }); + }); + return nodeify(promise, callback); + } + updateActivityContext(activity, context, callback) { + const promise = new Promise((resolve, reject) => { + if (isUndefinedOrNull(activity)) { + reject("activity can not be null"); + } + const removedKeys = []; + for (const key in context) { + if (context.hasOwnProperty(key) && context[key] === null) { + removedKeys.push(key); + } + } + for (const removedKey of removedKeys) { + delete context[removedKey]; + } + this._bridge + .updateActivityContext(activity, context, false, removedKeys) + .then((_) => { + resolve(activity); + }) + .catch((err) => { + reject(err); + }); + }); + return nodeify(promise, callback); + } + subscribeActivityContextChanged(handler) { + this._activities.subscribe((act, context) => { + if (context.type === EntityEventType.ActivityContextChange) { + const updateContext = context; + handler(act, updateContext.context, updateContext.updated, updateContext.removed); + } + }); + } + stopActivity(activity, callback) { + const promise = this._bridge.stopActivity(activity); + return nodeify(promise, callback); + } + getWindows(filter) { + if (isUndefined(filter)) { + return this._windows.get(); + } + if (!isUndefined(filter.id)) { + return [this._windows.getByName(filter.id)]; + } + const allWindows = this._windows.get(); + return allWindows.filter((w) => { + if (!isUndefined(filter.type) && w.type.id !== filter.type) { + return false; + } + if (!isUndefined(filter.name) && w.name !== filter.name) { + return false; + } + if (!isUndefined(filter.activityId)) { + if (isUndefinedOrNull(w.activity)) { + return false; + } + if (w.activity.id !== filter.activityId) { + return false; + } + } + return true; + }); + } + getWindowBounds(id) { + return this._bridge.getWindowBounds(id); + } + setWindowBounds(id, bounds, callback) { + const promise = new Promise((resolve, reject) => { + this._bridge.setWindowBounds(id, bounds) + .then(() => resolve()) + .catch((err) => reject(err)); + }); + return nodeify(promise, callback); + } + closeWindow(id) { + return this._bridge.closeWindow(id); + } + activateWindow(id, focus) { + return this._bridge.activateWindow(id, focus); + } + setWindowVisibility(id, visible) { + return this._bridge.setWindowVisibility(id, visible); + } + clone(activity, cloneOptions, callback) { + const promise = new Promise((resolve, reject) => { + if (!activity) { + reject("activity can not be null"); + } + this._bridge.cloneActivity(activity.id, cloneOptions) + .then((activityId) => { + this._activities + .getOrWait(activityId) + .then((act) => { + resolve(act); + }) + .catch((err) => reject(err)); + }) + .catch((err) => reject(err)); + }); + return nodeify(promise, callback); + } + attachActivities(from, to, tag, callback) { + tag = tag || {}; + const promise = new Promise((resolve, reject) => { + const fromActivity = this._activities.getByName(from); + if (!fromActivity) { + reject("can not find activity with id " + from); + return; + } + const toActivity = this._activities.getByName(to); + if (!toActivity) { + reject("can not find activity with id " + to); + return; + } + return this._bridge.attachActivities(from, to, tag) + .then((data) => { + const newActId = data.to; + const state = data.descriptor; + const allStates = data.descriptors; + this._activities.getOrWait(newActId).then((act) => { + act._updateDescriptors(allStates); + const stateWrapped = act.attached.filter((u) => u.ownerId === state.ownerId)[0]; + resolve(stateWrapped); + }); + }) + .catch((err) => { + reject(err); + }); + }); + return nodeify(promise, callback); + } + detachActivities(activityId, descriptor, callback) { + const promise = new Promise((resolve, reject) => { + return this._bridge.detachActivities(activityId, descriptor) + .then(() => { + const oldActId = undefined; + const newActId = undefined; + const descriptors = undefined; + this._activities + .getOrWait(oldActId) + .then((oldAct) => { + oldAct._updateDescriptors(descriptors); + this._activities + .getOrWait(newActId) + .then((newAct) => { + resolve(newAct); + }); + }) + .catch((err) => reject(err)); + }) + .catch((err) => { + reject(err); + }); + }); + return nodeify(promise, callback); + } + subscribeActivitiesAttached(callback) { + this._attachedCallbacks.push(callback); + } + subscribeActivitiesDetached(callback) { + this._detachedCallbacks.push(callback); + } + subscribeActivityFrameColorChanged(callback) { + this._frameColorChangesCallbacks.push(callback); + } + _grabEntity(entity) { + entity._manager = this; + } + _getInitialData() { + this._logger.debug("Request initial data..."); + this._bridge.getActivityTypes() + .then((at) => { + this._activityTypes.add(at); + this._dataReadyMarker.signal("Got act types"); + }) + .catch((error) => { + this._logger.error(error); + this._dataReadyMarker.error("Can not initialize ActivityManager - error getting activity types -" + error); + }); + this._bridge.getWindowTypes() + .then((wt) => { + this._windowTypes.add(wt); + this._dataReadyMarker.signal("Got window types"); + }) + .catch((error) => { + this._logger.error(error); + this._dataReadyMarker.error("Can not initialize ActivityManager - error getting window types " + error); + }); + this._bridge.getActivities() + .then((ac) => { + this._activities.add(ac); + this._dataReadyMarker.signal("Got activities"); + }) + .catch((error) => { + this._logger.error(error); + this._dataReadyMarker.error("Can not initialize ActivityManager - error getting activity instances -" + error); + }); + this._bridge.getActivityWindows() + .then((aw) => { + this._windows.add(aw); + this._dataReadyMarker.signal("Got windows"); + }) + .catch((error) => { + this._logger.error(error); + this._dataReadyMarker.error("Can not initialize ActivityManager - error getting activity windows -" + error); + }); + } + _subscribeForData() { + this._logger.debug("Subscribe for data..."); + this._bridge.onActivityTypeStatusChange((event) => { + this._activityTypes.process(event); + }); + this._bridge.onWindowTypeStatusChange((event) => { + this._windowTypes.process(event); + }); + this._bridge.onActivityWindowChange((event) => { + this._windows.process(event); + }); + this._bridge.onActivityStatusChange((event) => { + this._activities.process(event); + }); + } + _handleActivitiesAttached(data) { + const newActId = data.to; + const descriptor = data.descriptor; + const descriptors = data.descriptors; + this._activities.getOrWait(newActId).then((act) => { + act._updateDescriptors(descriptors); + const descriptorAsObjectFromAPI = act.attached.filter((u) => u.ownerId === descriptor.ownerId)[0]; + this._attachedCallbacks.forEach((callback) => { + try { + callback(act, descriptorAsObjectFromAPI); + } + catch (err) { + return; + } + }); + }); + } + _handleActivitiesDetached(data) { + const oldActId = data.oldActivityId; + const newActId = data.newActivityId; + const descriptors = data.descriptors; + const descriptor = data.descriptor; + this._activities.getOrWait(oldActId).then((oldAct) => { + oldAct._updateDescriptors(descriptors); + this._activities.getOrWait(newActId).then((newAct) => { + this._detachedCallbacks.forEach((callback) => { + try { + callback(newAct, oldAct, descriptor); + } + catch (err) { + return; + } + }); + }); + }); + } + _handleActivityDescriptorsRefreshed(data) { + const id = data.id; + const descriptors = data.descriptors; + const act = this._activities.getByName(id); + if (act) { + act._updateDescriptors(descriptors); + } + } + refreshDescriptors() { + this._bridge.getAttachedDescriptors() + .then((map) => { + if (map) { + Object.keys(map).forEach((key) => { + const actId = key; + const descriptors = map[key]; + const act = this._activities.getByName(actId); + if (act) { + act._updateDescriptors(descriptors); + } + }); + } + this._descriptorsMarker.signal("Successfully got descriptors"); + }) + .catch((err) => { + this._descriptorsMarker.error("failed to get descriptors - " + err); + }); + } + _handleWindowFrameColorChanged(win) { + if (!win.activityId) { + return; + } + const act = this._activities.getByName(win.activityId); + if (!act) { + return; + } + if (!act.owner) { + return; + } + if (act.owner.underlyingWindow.id !== win.id) { + return; + } + this._frameColorChangesCallbacks.forEach((callback) => { + try { + callback(act, win.frameColor); + } + catch (e) { + return; + } + }); + } + } + + class ActivityManagementAPI { + constructor(manager, my) { + this._m = manager; + this._my = my; + this.activityTypes = { + get: this._getActivityTypesWrapper.bind(this), + register: this._m.registerActivityType.bind(this._m), + unregister: this._m.unregisterActivityType.bind(this._m), + subscribe: this._m.subscribeActivityTypeEvents.bind(this._m), + unsubscribe: undefined, + initiate: this._m.initiate.bind(this._m) + }; + this.windowTypes = { + get: this._getWindowTypesWrapper.bind(this), + registerFactory: this._m.registerWindowFactory.bind(this._m), + unregisterFactory: this._m.unregisterWindowFactory.bind(this._m), + subscribe: this._m.subscribeWindowTypeEvents.bind(this._m), + unsubscribe: undefined + }; + this.windows = { + get: this._m.getWindows.bind(this._m), + subscribe: this._m.subscribeWindowEvents.bind(this._m), + announce: this._m.announceWindow.bind(this._m), + unsubscribe: undefined, + create: this._m.createWindow.bind(this._m) + }; + this.instances = { + get: this._m.getActivities.bind(this._m), + subscribe: this._m.subscribeActivityEvents.bind(this._m), + unsubscribe: undefined + }; + } + onAttached(callback) { + this._m.subscribeActivitiesAttached(callback); + } + onDetached(callback) { + this._m.subscribeActivitiesDetached(callback); + } + onActivityFrameColorChanged(callback) { + this._m.subscribeActivityFrameColorChanged(callback); + } + _getActivityTypesWrapper(name) { + if (isUndefined(name)) { + return this._m.getActivityTypes(); + } + return this._m.getActivityType(name); + } + _getWindowTypesWrapper(name) { + if (isUndefined(name)) { + return this._m.getWindowTypes(); + } + return this._m.getWindowType(name); + } + } + + class ActivityAPI { + constructor(manager, my) { + this._mgr = manager; + this._my = my; + this.all = new ActivityManagementAPI(manager, my); + } + ready(callback) { + const promise = new Promise((resolve, reject) => { + this._mgr.ready() + .then(() => { + resolve(this); + }) + .catch((err) => { + reject(err); + }); + }); + return nodeify(promise, callback); + } + get my() { + return this._my; + } + get aware() { + return this._my.window !== undefined; + } + get inActivity() { + return this.aware && this._my.activity !== undefined; + } + get agm() { + if (!this.aware) { + return undefined; + } + if (!this.inActivity) { + return new ActivityAGM(null); + } + return this._my.activity.agm; + } + getAvailableFrameColors() { + return []; + } + } + + class ActivityModule { + static checkIsUsingGW3Implementation(connection) { + return connection.protocolVersion === 3; + } + get api() { + return this._api; + } + set api(value) { + this._api = value; + } + constructor(config) { + if (!config) { + throw new Error("config can not be null"); + } + if (!isUndefined(config.logLevel)) { + Logger.Level = config.logLevel; + } + if (!isUndefinedOrNull(config.logger)) { + Logger.GlueLogger = config.logger; + } + let bridge; + this._isUsingHCImplementation = config.gdMajorVersion === 2; + this._isUsingGW3Implementation = ActivityModule.checkIsUsingGW3Implementation(config.connection); + if (this._isUsingHCImplementation) { + throw new Error("GD2 not supported"); + } + else if (this._isUsingGW3Implementation) { + bridge = new GW3Bridge(config); + } + else { + throw new Error("Unable to instantiate activity bridge implementation"); + } + if (!bridge) { + throw new Error("A bridge to native activity is needed to create activity lib."); + } + ActivityAGM.AGM = config.agm; + const activityManager = new ActivityManager(bridge, !config.disableAutoAnnounce, config.windows); + const my = new ActivityMy(activityManager, config.windows); + this._api = new ActivityAPI(activityManager, my); + this._readyPromise = activityManager.ready().then((_) => this); + } + get isUsingHCImplementation() { + return this._isUsingHCImplementation; + } + get isUsingGW3Implementation() { + return this._isUsingGW3Implementation; + } + ready(callback) { + return nodeify(this._readyPromise, callback); + } + } + + const ShutdownMethodName = "T42.ACS.Shutdown"; + const OnGDShutdownMethodName = "T42.ACS.OnGDShutdown"; + const RestartMethodName = "T42.ACS.Restart"; + const GetConfigurationRegionMethodName = "T42.ACS.GetConfigurationRegion"; + const SetConfigurationRegionMethodName = "T42.ACS.SetConfigurationRegion"; + const GetUserMethodName = "T42.ACS.GetUser"; + const GetBranchesMethodName = "T42.ACS.GetBranches"; + const GetCurrentBranchMethodName = "T42.ACS.GetCurrentBranch"; + const SetCurrentBranchMethodName = "T42.ACS.SetCurrentBranch"; + const GetFunctionalEntitlementMethodName = "T42.ACS.GetFunctionalEntitlement"; + const CanIMethodName = "T42.ACS.CanI"; + const StartApplicationMethodName = "T42.ACS.StartApplication"; + const StopApplicationMethodName = "T42.ACS.StopApplication"; + const ActivateApplicationMethodName = "T42.ACS.ActivateApplication"; + const ACSExecute = "T42.ACS.Execute"; + const OnEventMethodName = "T42.ACS.OnEvent"; + const GetApplicationsMethodName = "T42.ACS.GetApplications"; + + var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; + + function getDefaultExportFromCjs (x) { + return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; + } + + function createRegistry(options) { + if (options && options.errorHandling + && typeof options.errorHandling !== "function" + && options.errorHandling !== "log" + && options.errorHandling !== "silent" + && options.errorHandling !== "throw") { + throw new Error("Invalid options passed to createRegistry. Prop errorHandling should be [\"log\" | \"silent\" | \"throw\" | (err) => void], but " + typeof options.errorHandling + " was passed"); + } + var _userErrorHandler = options && typeof options.errorHandling === "function" && options.errorHandling; + var callbacks = {}; + function add(key, callback, replayArgumentsArr) { + var callbacksForKey = callbacks[key]; + if (!callbacksForKey) { + callbacksForKey = []; + callbacks[key] = callbacksForKey; + } + callbacksForKey.push(callback); + if (replayArgumentsArr) { + setTimeout(function () { + replayArgumentsArr.forEach(function (replayArgument) { + var _a; + if ((_a = callbacks[key]) === null || _a === void 0 ? void 0 : _a.includes(callback)) { + try { + if (Array.isArray(replayArgument)) { + callback.apply(undefined, replayArgument); + } + else { + callback.apply(undefined, [replayArgument]); + } + } + catch (err) { + _handleError(err, key); + } + } + }); + }, 0); + } + return function () { + var allForKey = callbacks[key]; + if (!allForKey) { + return; + } + allForKey = allForKey.reduce(function (acc, element, index) { + if (!(element === callback && acc.length === index)) { + acc.push(element); + } + return acc; + }, []); + if (allForKey.length === 0) { + delete callbacks[key]; + } + else { + callbacks[key] = allForKey; + } + }; + } + function execute(key) { + var argumentsArr = []; + for (var _i = 1; _i < arguments.length; _i++) { + argumentsArr[_i - 1] = arguments[_i]; + } + var callbacksForKey = callbacks[key]; + if (!callbacksForKey || callbacksForKey.length === 0) { + return []; + } + var results = []; + callbacksForKey.forEach(function (callback) { + try { + var result = callback.apply(undefined, argumentsArr); + results.push(result); + } + catch (err) { + results.push(undefined); + _handleError(err, key); + } + }); + return results; + } + function _handleError(exceptionArtifact, key) { + var errParam = exceptionArtifact instanceof Error ? exceptionArtifact : new Error(exceptionArtifact); + if (_userErrorHandler) { + _userErrorHandler(errParam); + return; + } + var msg = "[ERROR] callback-registry: User callback for key \"" + key + "\" failed: " + errParam.stack; + if (options) { + switch (options.errorHandling) { + case "log": + return console.error(msg); + case "silent": + return; + case "throw": + throw new Error(msg); + } + } + console.error(msg); + } + function clear() { + callbacks = {}; + } + function clearKey(key) { + var callbacksForKey = callbacks[key]; + if (!callbacksForKey) { + return; + } + delete callbacks[key]; + } + return { + add: add, + execute: execute, + clear: clear, + clearKey: clearKey + }; + } + createRegistry.default = createRegistry; + var lib = createRegistry; + + + var CallbackRegistryFactory = /*@__PURE__*/getDefaultExportFromCjs(lib); + + function objectValues(source) { + if (!source) { + return []; + } + return Object.keys(source).map((key) => source[key]); + } + function objectClone(obj) { + let result; + try { + result = JSON.parse(JSON.stringify(obj || {})); + } + catch (error) { + result = {}; + } + return result; + } + function validate(callback, configuration) { + if (configuration.throwErrors) { + if (typeof callback !== "function") { + throw new Error("Please provide the callback as a function!"); + } + } + } + + const INTEROP_METHOD_RESPONSE_TIMEOUT_MS = 90000; + const INTEROP_METHOD_WAIT_TIMEOUT_MS = 90000; + + let urlAlphabet = + 'useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict'; + let nanoid = (size = 21) => { + let id = ''; + let i = size | 0; + while (i--) { + id += urlAlphabet[(Math.random() * 64) | 0]; + } + return id + }; + + class Utils { + static getGDMajorVersion() { + if (typeof window === "undefined") { + return -1; + } + if (!window.glueDesktop) { + return -1; + } + if (!window.glueDesktop.version) { + return -1; + } + const parsed = window.glueDesktop.version.split("."); + const major = Number(parsed[0]); + return isNaN(major) ? -1 : major; + } + static typedError(error) { + let err; + if (error instanceof Error) { + err = error; + } + else if (typeof error === "string") { + err = new Error(error); + } + else if ("message" in error && typeof error.message === "string" && error.message.length > 0) { + err = new Error(error.message); + } + else if ("returned" in error + && typeof error.returned === "object" + && "errorMsg" in error.returned + && typeof error.returned.errorMsg === "string" + && error.returned.errorMsg.length > 0) { + err = new Error(error.returned.errorMsg); + } + else { + err = new Error("Unknown error"); + } + return err; + } + static async callbackifyPromise(action, successCallback, errorCallback) { + const success = (result) => { + if (typeof successCallback === "function") { + successCallback(result); + } + return Promise.resolve(result); + }; + const fail = (error) => { + const err = Utils.typedError(error); + if (typeof errorCallback === "function") { + errorCallback(err.message); + return; + } + return Promise.reject(err); + }; + try { + const result = await action(); + return success(result); + } + catch (error) { + return fail(error); + } + } + static getMonitor(bounds, displays) { + const monitorsSortedByOverlap = displays.map((m) => { + const { left, top, workingAreaWidth: width, workingAreaHeight: height } = m; + const overlap = this.calculateTotalOverlap({ left, top, width, height }, bounds); + return { + monitor: m, + totalOverlap: overlap + }; + }).sort((a, b) => b.totalOverlap - a.totalOverlap); + return monitorsSortedByOverlap[0].monitor; + } + static getDisplayCenterOfScreen(a, currentDisplay, primaryDisplay) { + const physicalWidth = a.width / currentDisplay.scaleFactor; + const physicalHeight = a.height / currentDisplay.scaleFactor; + const physicalDisplayLeft = currentDisplay.workArea.left / primaryDisplay.scaleFactor; + const physicalDisplayTop = currentDisplay.workArea.top / primaryDisplay.scaleFactor; + const physicalDisplayWidth = currentDisplay.workArea.width / currentDisplay.scaleFactor; + const physicalDisplayHeight = currentDisplay.workArea.height / currentDisplay.scaleFactor; + const physicalHOffset = Math.max((physicalDisplayWidth - physicalWidth) / 2, 0); + const physicalVOffset = Math.max((physicalDisplayHeight - physicalHeight) / 2, 0); + const centeredPhysicalLeft = Math.floor(physicalDisplayLeft + physicalHOffset); + const centeredPhysicalTop = Math.floor(physicalDisplayTop + physicalVOffset); + const left = centeredPhysicalLeft * primaryDisplay.scaleFactor; + const top = centeredPhysicalTop * primaryDisplay.scaleFactor; + return { + left, + top, + width: a.width, + height: a.height + }; + } + static isNode() { + if (typeof Utils._isNode !== "undefined") { + return Utils._isNode; + } + if (typeof window !== "undefined") { + Utils._isNode = false; + return false; + } + try { + Utils._isNode = Object.prototype.toString.call(global.process) === "[object process]"; + } + catch (e) { + Utils._isNode = false; + } + return Utils._isNode; + } + static generateId() { + return nanoid(10); + } + static isPromise(value) { + return Boolean(value && typeof value.then === 'function'); + } + static isAsyncFunction(value) { + return value && {}.toString.call(value) === '[object AsyncFunction]'; + } + static isNullOrUndefined(value) { + return value === null || value === undefined; + } + static calculateTotalOverlap(r1, r2) { + const r1x = r1.left; + const r1y = r1.top; + const r1xMax = r1x + r1.width; + const r1yMax = r1y + r1.height; + const r2x = r2.left; + const r2y = r2.top; + const r2xMax = r2x + r2.width; + const r2yMax = r2y + r2.height; + const xOverlap = Math.max(0, Math.min(r1xMax, r2xMax) - Math.max(r1x, r2x)); + const yOverlap = Math.max(0, Math.min(r1yMax, r2yMax) - Math.max(r1y, r2y)); + return xOverlap * yOverlap; + } + } + + class ApplicationImpl { + constructor(_appManager, _name, _agm, _logger, _configuration) { + this._appManager = _appManager; + this._name = _name; + this._agm = _agm; + this._logger = _logger; + this._configuration = _configuration; + this._registry = CallbackRegistryFactory(); + _appManager.onInstanceStarted((instance) => { + if (instance.application && instance.application.name !== this._name) { + return; + } + this._registry.execute("instanceStarted", instance); + }); + _appManager.onInstanceStopped((instance) => { + if (instance.application && instance.application.name !== this._name) { + return; + } + this._registry.execute("instanceStopped", instance); + }); + _appManager.onAppRemoved((app) => { + if (app.name !== this._name) { + return; + } + this._registry.execute("appRemoved", app); + }); + _appManager.onAppChanged((app) => { + if (app.name !== this._name) { + return; + } + this._registry.execute("appChanged", app); + }); + _appManager.onAppAvailable((app) => { + if (app.name !== this._name) { + return; + } + this._props.IsReady = true; + this._registry.execute("appAvailable", app); + }); + _appManager.onAppUnavailable((app) => { + if (app.name !== this._name) { + return; + } + this._props.IsReady = false; + this._registry.execute("appUnavailable", app); + }); + } + get name() { return this._name; } + get title() { return this._props.Title; } + get version() { return this._props.Version; } + get autoStart() { return this._props.AutoStart; } + get isShell() { return this._props.IsShell; } + get caption() { return this._props.Caption; } + get hidden() { return this._props.IsHidden; } + get container() { return this._props.ApplicationName; } + get activityType() { return this._props.ActivityType; } + get activityWindowType() { return this._props.ActivityWindowType; } + get windowSettings() { + if (!this._props.Arguments) { + return {}; + } + return objectClone(this._props.Arguments); + } + get allowMultiple() { return this._props.AllowMultiple; } + get available() { return this._props.IsReady || true; } + get icon() { return this._props.Icon; } + get iconURL() { return this._props.IconUrl; } + get sortOrder() { return this._props.SortOrder; } + get userProperties() { + if (!this._props.UserProperties) { + return {}; + } + return objectClone(this._props.UserProperties); + } + get keywords() { + if (!this._props.Keywords) { + return []; + } + return this._props.Keywords; + } + get isActivity() { + return this._props.ActivityType !== undefined && this._props.ActivityType !== ""; + } + get configuration() { + return { + autoStart: this._props.AutoStart, + caption: this._props.Caption, + hidden: this._props.IsHidden, + container: this._props.ApplicationName, + activityType: this._props.ActivityType, + allowMultiple: this._props.AllowMultiple + }; + } + get instances() { + return this._appManager.instances().filter((instance) => instance.application.name === this._name); + } + get type() { + return this._props.Type; + } + get mode() { + if (!this._props) { + return "unknown"; + } + if (this._props.Mode && typeof this._props.Mode === "string") { + return this._props.Mode.toLowerCase(); + } + if (this.isActivity) { + return "unknown"; + } + if (this._props.Arguments && this._props.Arguments.mode && typeof this._props.Arguments.mode === "string") { + return this._props.Arguments.mode.toLowerCase(); + } + let styleAttributes = this._props.WindowStyleAttributes; + if (styleAttributes) { + styleAttributes = styleAttributes.split(" ").join(""); + const searchFor = "mode:\""; + const modeIndex = styleAttributes.indexOf(searchFor); + if (modeIndex !== -1) { + const startModeIndex = modeIndex + searchFor.length; + const stopModeIndex = styleAttributes.indexOf("\"", startModeIndex); + const style = styleAttributes.substr(startModeIndex, stopModeIndex - startModeIndex); + if (style && typeof style === "string") { + return style.toLowerCase(); + } + } + } + return "flat"; + } + async getConfiguration() { + const result = await this._agm.invoke(GetApplicationsMethodName, { v2: { apps: [this._name] } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + const config = result.returned.applications[0]; + return config; + } + updateFromProps(props) { + if (!this._props) { + this._props = { Name: props.Name }; + } + Object.keys(props).forEach((key) => { + this._props[key] = props[key]; + }); + } + start(context, options) { + return new Promise(async (resolve, reject) => { + var _a, _b, _c, _d; + if (isUndefinedOrNull(context)) { + context = {}; + } + else if (((_a = this._configuration()) === null || _a === void 0 ? void 0 : _a.throwErrors) && typeof context !== "object" || Array.isArray(context)) { + return reject(new Error(`Invalid "context" parameter - must be an object.`)); + } + if (isUndefinedOrNull(options)) { + options = {}; + } + else if (((_b = this._configuration()) === null || _b === void 0 ? void 0 : _b.throwErrors) && typeof options !== "object") { + return reject(new Error(`Invalid "options" parameter - must be an object.`)); + } + const name = this._name; + let waitForAGMInstance = (_d = ((_c = options.awaitInterop) !== null && _c !== void 0 ? _c : options.waitForAGMReady)) !== null && _d !== void 0 ? _d : true; + let startTimeout = 60000; + if (typeof options.timeout === "number") { + startTimeout = options.timeout * 1000; + } + if (options.relativeTo !== undefined && typeof options.relativeTo !== "string") { + options.relativeTo = options.relativeTo.id || ""; + } + const waitForApplicationInstance = (id) => { + let unsub; + const timeout = setTimeout(() => { + if (unsub) { + unsub(); + } + const errMsg = `timed out while waiting for instance id ${id} for app ${this.name}`; + this._logger.error(errMsg); + reject(new Error(errMsg)); + }, startTimeout); + const waitFunc = (i) => { + if (i.id !== id) { + return; + } + if (unsub) { + unsub(); + unsub = undefined; + } + clearTimeout(timeout); + resolve(i); + }; + if (waitForAGMInstance) { + const instance = this._appManager.instances().find((i) => i.id === id); + if (instance) { + unsub = instance.onAgmReady(waitFunc); + } + else { + unsub = this._appManager.onInstanceAgmServerReady(waitFunc); + } + } + else { + unsub = this._appManager.onInstanceStarted(waitFunc); + } + }; + try { + this._logger.trace(`starting application ${name} with options: ${JSON.stringify(options)}`); + const result = await this._agm.invoke(StartApplicationMethodName, { + Name: name, + Context: context, + Options: options + }, "best", { + methodResponseTimeoutMs: startTimeout, + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + const acsResult = result.returned; + if (typeof acsResult.timeout !== "undefined" && typeof options.timeout === "undefined") { + startTimeout = acsResult.timeout * 1000; + } + if (typeof acsResult.waitForInterop !== "undefined" && (typeof options.waitForAGMReady === "undefined" && typeof options.awaitInterop === "undefined")) { + waitForAGMInstance = acsResult.waitForInterop; + } + if (acsResult && acsResult.Id) { + if (this._appManager.mode === "startOnly") { + const instance = this._appManager.handleInstanceStarted({ + ActivityId: undefined, + IsActivityOwner: undefined, + Context: undefined, + Title: undefined, + AgmServers: undefined, + Id: acsResult.Id, + Name: acsResult.Name, + }); + resolve(instance); + } + else { + waitForApplicationInstance(acsResult.Id); + } + } + else { + resolve(undefined); + } + } + catch (error) { + const err = Utils.typedError(error); + reject(err); + } + }); + } + onInstanceStarted(callback) { + validate(callback, this._configuration()); + return this._registry.add("instanceStarted", callback); + } + onInstanceStopped(callback) { + validate(callback, this._configuration()); + return this._registry.add("instanceStopped", callback); + } + onAvailable(callback) { + validate(callback, this._configuration()); + if (this._props.IsReady) { + setTimeout(() => { + this._registry.execute("appAvailable", this); + }, 0); + } + return this._registry.add("appAvailable", callback); + } + onUnavailable(callback) { + validate(callback, this._configuration()); + if (this._props.IsReady === false) { + setTimeout(() => { + this._registry.execute("appUnavailable", this); + }, 0); + } + return this._registry.add("appUnavailable", callback); + } + onChanged(callback) { + validate(callback, this._configuration()); + this._registry.add("appChanged", callback); + } + onRemoved(callback) { + validate(callback, this._configuration()); + this._registry.add("appRemoved", callback); + } + } + + class InstanceImpl { + constructor(_id, _appName, _appManager, _agm, _activities, _windows, _logger, startFailed, _configuration) { + this._id = _id; + this._appName = _appName; + this._appManager = _appManager; + this._agm = _agm; + this._activities = _activities; + this._windows = _windows; + this._logger = _logger; + this._configuration = _configuration; + this._registry = CallbackRegistryFactory(); + if (startFailed) { + return; + } + this._unsubscribeInstanceStopped = this._appManager.onInstanceStopped((instance) => { + if (instance.id !== this._id) { + return; + } + this._registry.execute("stopped", instance); + }); + this._unsubscribeInstanceAgmServerReady = this._appManager.onInstanceAgmServerReady((instance) => { + if (instance.id !== this._id) { + return; + } + this._registry.execute("agmReady", instance); + }); + } + get id() { return this._id; } + get application() { return this._appManager.application(this._appName); } + get activity() { + if (!this._activities) { + throw new Error("This method requires glue.activities library to be enabled."); + } + return this._activities.all.instances.get() + .filter((activityInstance) => activityInstance.id === this._activityId)[0]; + } + get isActivityOwner() { return this._isActivityOwner; } + get activityInstances() { + return this._appManager.instances().filter((i) => i.application.type !== "activity" && + i.activityId && + i.activityId === this._activityId); + } + get activityOwnerInstance() { + if (!this._activityId) { + return undefined; + } + return this.activityInstances.filter((inst) => inst === null || inst === void 0 ? void 0 : inst.isActivityOwner)[0]; + } + get window() { + if (!this._windows) { + throw new Error("This method requires glue.windows library to be enabled."); + } + let win = this._windows.list().find((w) => w.id === this._id); + if (!win && this._activities && this.activity && this.activityOwnerInstance) { + win = this.activityOwnerInstance.window; + } + return win; + } + get context() { + var _a, _b, _c; + return (_c = (_a = this._startUpContext) !== null && _a !== void 0 ? _a : (_b = this.window) === null || _b === void 0 ? void 0 : _b.context) !== null && _c !== void 0 ? _c : {}; + } + get title() { return this._title; } + get isActivityInstance() { return this._isActivityInstance; } + get activityId() { return this._activityId; } + get inActivity() { return this._inActivity; } + get isSingleWindowApp() { return !this._inActivity; } + get agm() { + return this._agmInstance; + } + get interopInstance() { + return this._agmInstance; + } + onInteropReady(callback) { + validate(callback, this._configuration()); + if (this._agmInstance) { + setTimeout(() => { + this._registry.execute("agmReady", this); + }, 0); + } + return this._registry.add("agmReady", callback); + } + onAgmReady(callback) { + return this.onInteropReady(callback); + } + onStopped(callback) { + validate(callback, this._configuration()); + return this._registry.add("stopped", callback); + } + getWindow() { + return new Promise((resolve, reject) => { + const result = this.window; + if (result) { + resolve(result); + return; + } + const done = (error, window) => { + if (error) { + reject(error); + } + if (window) { + resolve(window); + } + setTimeout(() => { + clearTimeout(timeout); + unsub(); + }, 0); + }; + this._logger.trace(`waiting for window with id ${this._id} to appear`); + const timeoutInSeconds = 60; + const timeout = setTimeout(() => { + this._logger.trace(`window with id ${this._id} did not appear in ${timeoutInSeconds} sec`); + done(new Error(`can not find a window with id ${this._id}`)); + }, timeoutInSeconds * 1000); + const unsub = this._windows.onWindowAdded((w) => { + if (w.id === this._id) { + this._logger.trace(`window with id ${this._id} appeared`); + done(undefined, w); + } + }); + }); + } + updateFromProps(props) { + this._startUpContext = props.Context; + this._title = props.Title; + this._isActivityInstance = false; + if (props.ActivityId && props.ActivityId !== "") { + this._activityId = props.ActivityId; + this._isActivityInstance = true; + } + this._isActivityOwner = props.IsActivityOwner; + if (!this._activityId && this._startUpContext && this._startUpContext.activityId) { + this._activityId = this._startUpContext.activityId; + } + this._inActivity = Boolean(this._activityId); + this.updateAgmInstanceFromProps(props); + } + updateAgmInstanceFromProps(props) { + if (!props.AgmServers) { + return; + } + const agmInstances = props.AgmServers; + if (agmInstances && agmInstances.length > 0 && !isUndefinedOrNull(agmInstances[0])) { + this._agmInstance = agmInstances[0]; + } + } + stop() { + return new Promise((resolve, reject) => { + let idToResolve = this._id; + if (this.isActivityOwner) { + idToResolve = this.activityId; + } + const unsubscribe = this._appManager.onInstanceStopped((instance) => { + if (instance.id === idToResolve) { + this._logger.trace(`instance with id ${idToResolve} stopped`); + unsubscribe(); + resolve(); + } + }); + this._logger.trace(`stopping instance with id ${this._id}`); + this._agm.invoke(StopApplicationMethodName, { + Name: this._appName, + Id: this._id + }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }) + .then(() => { + if (this._appManager.mode === "startOnly") { + this._appManager.handleInstanceStopped({ + Name: this._appName, + Id: this.id + }); + resolve(); + } + }) + .catch((err) => reject(err)); + }); + } + activate() { + return this._agm.invoke(ActivateApplicationMethodName, { Name: this._appName, Id: this._id }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + done() { + this._registry.clear(); + this._unsubscribeInstanceAgmServerReady(); + this._unsubscribeInstanceStopped(); + } + getContext() { + return Promise.resolve(this.context); + } + async startedBy() { + const result = await this._agm.invoke(ACSExecute, { command: "getStartedBy", Name: this._appName, Id: this._id }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return result.returned; + } + } + + class AppManagerImpl { + constructor(mode, _agm, _activities, _windows, _logger, _gdMajorVersion, _configuration) { + this.mode = mode; + this._agm = _agm; + this._activities = _activities; + this._windows = _windows; + this._logger = _logger; + this._gdMajorVersion = _gdMajorVersion; + this._configuration = _configuration; + this._apps = {}; + this._instances = []; + this._registry = CallbackRegistryFactory(); + this.getConfigurations = async (apps) => { + const args = { + v2: { + apps: undefined + } + }; + if (Array.isArray(apps)) { + args.v2 = { + apps + }; + } + const result = await this._agm.invoke(GetApplicationsMethodName, args, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return result.returned.applications; + }; + this.application = (name) => { + var _a; + if (((_a = this._configuration()) === null || _a === void 0 ? void 0 : _a.throwErrors) && typeof name !== "string" || isNullOrWhiteSpace(name)) { + throw new Error(`"name" must be string`); + } + return this._apps[name]; + }; + this.applications = () => { + return Object.keys(this._apps).map((k) => this._apps[k]); + }; + this.instances = () => { + return this._instances.map((i) => i); + }; + this.getMyInstance = () => { + const glue42gd = typeof window !== "undefined" && window.glue42gd; + if (glue42gd) { + if (this._gdMajorVersion >= 3) { + const instanceId = glue42gd.appInstanceId; + return this._instances.find((i) => i.id === instanceId); + } + } + else { + const instanceId = this._agm.instance.instance; + return this._instances.find((i) => i.id === instanceId); + } + return undefined; + }; + this.getMyApplication = () => { + var _a; + if (this._agm.instance) { + return (_a = this.application(this._agm.instance.applicationName)) !== null && _a !== void 0 ? _a : this.application(this._agm.instance.application); + } + }; + this.handleSnapshotAppsAdded = (newApps) => { + const currentApps = this.applications(); + if (currentApps.length > 0) { + currentApps.forEach((item) => { + const name = item.name; + const alreadyExists = newApps.find((i) => i.Name === item.name); + if (!alreadyExists) { + this.handleAppRemoved({ Name: name }); + } + }); + } + newApps.forEach((item) => { + const alreadyExists = currentApps.find((i) => i.name === item.Name); + if (!alreadyExists) { + this.handleAppAdded(item); + } + }); + }; + this.handleSnapshotInstanceStarted = (newInstances) => { + const currentInstances = this.instances(); + if (currentInstances.length > 0) { + currentInstances.forEach((item) => { + const id = item.id; + const alreadyExists = newInstances.find((i) => i.Id === id); + if (!alreadyExists) { + this.handleInstanceStopped({ Name: item.application.name, Id: id }); + } + }); + } + newInstances.forEach((item) => { + const alreadyExists = currentInstances.find((i) => i.id === item.Id); + if (!alreadyExists) { + this.handleInstanceStarted(item); + } + }); + }; + this.handleAppAdded = (props) => { + const id = this._getAppId(props); + this._logger.trace(`adding app ${id}`); + this._apps[id] = new ApplicationImpl(this, id, this._agm, this._logger, this._configuration); + const app = this._updateAppFromProps(props); + this._registry.execute("appAdded", app); + this._registry.execute("appAvailable", app); + }; + this.handleAppUpdated = (props) => { + const app = this._updateAppFromProps(props); + this._registry.execute("appChanged", app); + }; + this.handleAppRemoved = (props) => { + const id = this._getAppId(props); + this._logger.trace(`removing app ${id}`); + const app = this.application(id); + this._instances = this._instances.filter((i) => i.application.name !== app.name); + delete this._apps[id]; + this._registry.execute("appRemoved", app); + }; + this.handleAppReady = (props) => { + const id = this._getAppId(props); + const app = this._getAppOrThrow(id); + app.updateFromProps(props); + if (app.available) { + this._registry.execute("appAvailable", app); + } + else { + this._registry.execute("appUnavailable", app); + } + }; + this.handleInstanceStarted = (props) => { + this._logger.trace(`started app ${props.Name} ${props.Id}`); + const id = this._getInstanceId(props); + const appName = this._getInstanceAppName(props); + const instance = new InstanceImpl(id, appName, this, this._agm, this._activities, this._windows, this._logger, false, this._configuration); + this._updateInstanceFromProps(instance, props); + this._instances.push(instance); + this._registry.execute("instanceStarted", instance); + return instance; + }; + this.handleInstanceStopped = (props) => { + this._logger.trace(`instance stopped ${props.Name} ${props.Id}`); + const id = this._getInstanceId(props); + const appName = this._getInstanceAppName(props); + const instance = this._getInstanceOrThrow(id, appName); + this._instances = this._instances.filter((i) => !this._matchInstance(i, id, appName)); + this._registry.execute("instanceStopped", instance); + instance.done(); + }; + this.handleInstanceAgmServerReady = (props) => { + this._logger.trace(`instance interop server ready ${props.Name} ${props.Id}`); + const id = this._getInstanceId(props); + const appName = this._getInstanceAppName(props); + const instance = this._getInstanceOrThrow(id, appName); + instance.updateAgmInstanceFromProps(props); + this._registry.execute("instanceAgmServerReady", instance); + }; + this.handleInstanceStartFailed = (props) => { + const id = this._getInstanceId(props); + const appName = this._getInstanceAppName(props); + const startFailed = true; + const instance = new InstanceImpl(id, appName, undefined, undefined, undefined, undefined, this._logger, startFailed, this._configuration); + this._updateInstanceFromProps(instance, props); + this._registry.execute("instanceStartFailed", instance); + }; + this.handleInstanceUpdated = (props) => { + const id = this._getInstanceId(props); + const app = this._getInstanceAppName(props); + const instance = this._getInstanceOrThrow(id, app); + this._updateInstanceFromProps(instance, props); + }; + this.onInstanceStarted = (callback) => { + validate(callback, this._configuration()); + return this._registry.add("instanceStarted", callback, this._instances); + }; + this.onInstanceStartFailed = (callback) => { + validate(callback, this._configuration()); + return this._registry.add("instanceStartFailed", callback); + }; + this.onInstanceStopped = (callback) => { + validate(callback, this._configuration()); + return this._registry.add("instanceStopped", callback); + }; + this.onInstanceUpdated = (callback) => { + validate(callback, this._configuration()); + return this._registry.add("instanceChanged", callback); + }; + this.onInstanceAgmServerReady = (callback) => { + validate(callback, this._configuration()); + return this._registry.add("instanceAgmServerReady", callback); + }; + this.onAppAdded = (callback) => { + validate(callback, this._configuration()); + return this._registry.add("appAdded", callback, Object.values(this._apps)); + }; + this.onAppRemoved = (callback) => { + validate(callback, this._configuration()); + return this._registry.add("appRemoved", callback); + }; + this.onAppAvailable = (callback) => { + validate(callback, this._configuration()); + return this._registry.add("appAvailable", callback); + }; + this.onAppUnavailable = (callback) => { + validate(callback, this._configuration()); + return this._registry.add("appUnavailable", callback); + }; + this.onAppChanged = (callback) => { + validate(callback, this._configuration()); + return this._registry.add("appChanged", callback); + }; + } + _getAppOrThrow(id) { + const result = this.application(id); + if (!result) { + throw Error(`app with id ${id} not found`); + } + return result; + } + _getAppId(props) { + return props.Name; + } + _matchInstance(instance, id, appName) { + return instance.id === id && instance.application.name === appName; + } + _getInstanceByIdAndName(id, appName) { + return this._instances.filter((i) => this._matchInstance(i, id, appName))[0]; + } + _getInstanceOrThrow(id, appName) { + const result = this._getInstanceByIdAndName(id, appName); + if (!result) { + throw Error(`instance with id ${id} not found`); + } + return result; + } + _getInstanceId(props) { + return props.Id; + } + _getInstanceAppName(props) { + return props.Name; + } + _updateAppFromProps(props) { + const id = this._getAppId(props); + this._logger.trace(`updating app with + ${id}, ${JSON.stringify(props)}`); + const app = this._getAppOrThrow(id); + app.updateFromProps(props); + return app; + } + _updateInstanceFromProps(instance, props) { + this._logger.trace("updating instance with " + this._getInstanceId(props) + " for app " + this._getInstanceAppName(props)); + instance.updateFromProps(props); + } + } + + function promisify(promise, successCallback, errorCallback) { + const isFunction = (arg) => { + return !!(arg && arg.constructor && arg.call && arg.apply); + }; + if (!isFunction(successCallback) && !isFunction(errorCallback)) { + return promise; + } + if (!isFunction(successCallback)) { + successCallback = () => { + }; + } + else if (!isFunction(errorCallback)) { + errorCallback = () => { + }; + } + return promise.then(successCallback, errorCallback); + } + class EntitlementsImpl { + constructor(_agm) { + this._agm = _agm; + this._registry = CallbackRegistryFactory(); + this._isMethodRegistered = false; + this.handleBranchModified = (branch) => { + this._registry.execute("branchChanged", branch); + }; + this.handleBranchesModified = (branches) => { + this._registry.execute("branchesChanged", branches); + }; + this.getRegion = (success, error) => { + return promisify(this._agmInvoke(GetConfigurationRegionMethodName, (e) => e.returned.Region), success, error); + }; + this.getBranches = (success, error) => { + const promise = this._agmInvoke(GetBranchesMethodName, (e) => { + const obj = e.returned.Branches; + return Object.keys(obj).map((key) => obj[key]); + }); + return promisify(promise, success, error); + }; + this.getCurrentBranch = (success, error) => { + const promise = this._agmInvoke(GetCurrentBranchMethodName, (e) => e.returned.Branch, undefined); + return promisify(promise, success, error); + }; + this.setRegion = (region, success, error) => { + const promise = this._agmInvoke(SetConfigurationRegionMethodName, (e) => e.returned.ResultMessage, { Region: region }); + return promisify(promise, success, error); + }; + this.setCurrentBranch = (branch, success, error) => { + const promise = this._agmInvoke(SetCurrentBranchMethodName, (e) => e.returned.ResultMessage, { Branch: branch }); + return promisify(promise, success, error); + }; + this.currentUser = (success, error) => { + const promise = this._agmInvoke(GetUserMethodName); + return promisify(promise, success, error); + }; + this.getFunctionalEntitlement = (funct, success, error) => { + const promise = this._agmInvoke(GetFunctionalEntitlementMethodName, (e) => e.returned.Entitlement, { Function: funct }); + return promisify(promise, success, error); + }; + this.getFunctionalEntitlementBranch = (funct, branch, success, error) => { + const promise = this._agmInvoke(GetFunctionalEntitlementMethodName, (e) => e.returned.Entitlement, { Function: funct, Branch: branch }); + return promisify(promise, success, error); + }; + this.canI = (func, success, error) => { + const promise = this._agmInvoke(CanIMethodName, (e) => e.returned.Result, { Function: func }); + return promisify(promise, success, error); + }; + this.canIBranch = (func, branch, success, error) => { + const promise = this._agmInvoke(CanIMethodName, (e) => e.returned.Result, { Function: func, Branch: branch }); + return promisify(promise, success, error); + }; + this.onBranchesChanged = (callback) => { + return this._registry.add("branchesChanged", callback); + }; + this.onBranchChanged = (callback) => { + return this._registry.add("branchChanged", callback); + }; + this.exit = (options) => { + return this._agmInvoke(ShutdownMethodName, null, options); + }; + this.onShuttingDown = (callback) => { + this.registerMethod(); + return this._registry.add("onShuttingDown", callback); + }; + this.restart = (options) => { + return this._agmInvoke(RestartMethodName, null, options); + }; + this._agmInvoke = (method, transformFunction, args) => { + args = args || {}; + return new Promise((resolve, reject) => { + const errHandler = (error) => reject(error); + this._agm.invoke(method, args, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }) + .then((result) => { + if (!transformFunction) { + transformFunction = (d) => d.returned; + } + resolve(transformFunction(result)); + }) + .catch(errHandler); + }); + }; + } + registerMethod() { + if (!this._isMethodRegistered) { + this._agm.register(OnGDShutdownMethodName, async (args) => { + try { + const results = await Promise.all(this._registry.execute("onShuttingDown", args)); + const prevent = results.some((r) => r.prevent); + return { prevent }; + } + catch (error) { + } + }); + this._isMethodRegistered = true; + } + } + } + + function snapshot(interop, appManager) { + return new Promise((resolve, reject) => { + interop.invoke(GetApplicationsMethodName, { skipIcon: true }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }) + .then((response) => { + var _a; + const data = response.returned; + const configuration = (_a = response.returned.configuration) !== null && _a !== void 0 ? _a : {}; + if (!data) { + resolve(configuration); + } + const applications = data.applications; + if (!applications) { + resolve(configuration); + } + objectValues(applications).map((item) => appManager.handleAppAdded(item)); + resolve(configuration); + }) + .catch((err) => reject(new Error(`Error getting application snapshot: ${err.message}`))); + }); + } + + const OnBranchChangedEvent = "OnBranchChanged"; + const OnBranchesModifiedEvent = "OnBranchesModified"; + const OnApplicationAddedEvent = "OnApplicationAdded"; + const OnApplicationRemovedEvent = "OnApplicationRemoved"; + const OnApplicationChangedEvent = "OnApplicationChanged"; + const OnApplicationReadyEvent = "OnApplicationReady"; + const OnApplicationStartedEvent = "OnApplicationStarted"; + const OnApplicationAgmServerReadyEvent = "OnApplicationAgmServerReady"; + const OnApplicationUpdatedEvent = "OnApplicationUpdated"; + const OnApplicationStoppedEvent = "OnApplicationStopped"; + const OnApplicationStartFailedEvent = "OnApplicationStartFailed"; + + function createDataSubscription(agm, applications, entitlements, skipIcons) { + let subscription; + let initiated = false; + const start = () => { + let resolveFunc; + let rejectFunc; + const resultPromise = new Promise((resolve, reject) => { + resolveFunc = resolve; + rejectFunc = reject; + }); + agm.subscribe(OnEventMethodName, { arguments: { skipIcon: skipIcons }, waitTimeoutMs: 10000 }) + .then((s) => { + subscription = s; + subscription.onData((streamData) => { + var _a; + const events = streamData.data; + const configuration = (_a = events.configuration) !== null && _a !== void 0 ? _a : {}; + const onApplicationAddedEventArgs = objectValues(events[OnApplicationAddedEvent]); + if (streamData.data.isSnapshot) { + applications.handleSnapshotAppsAdded(onApplicationAddedEventArgs); + } + else { + onApplicationAddedEventArgs.forEach((item) => applications.handleAppAdded(item)); + } + objectValues(events[OnApplicationChangedEvent]) + .forEach((item) => applications.handleAppUpdated(item)); + objectValues(events[OnApplicationRemovedEvent]) + .forEach((item) => applications.handleAppRemoved(item)); + objectValues(events[OnApplicationReadyEvent]) + .forEach((item) => applications.handleAppReady(item)); + const onApplicationStartedEventArgs = objectValues(events[OnApplicationStartedEvent]); + if (streamData.data.isSnapshot) { + applications.handleSnapshotInstanceStarted(onApplicationStartedEventArgs); + } + else { + onApplicationStartedEventArgs.forEach((item) => applications.handleInstanceStarted(item)); + } + objectValues(events[OnApplicationStartFailedEvent]) + .forEach((item) => applications.handleInstanceStartFailed(item)); + objectValues(events[OnApplicationStoppedEvent]) + .forEach((item) => applications.handleInstanceStopped(item)); + objectValues(events[OnApplicationUpdatedEvent]) + .forEach((item) => applications.handleInstanceUpdated(item)); + objectValues(events[OnApplicationAgmServerReadyEvent]) + .forEach((item) => applications.handleInstanceAgmServerReady(item)); + objectValues(events[OnBranchChangedEvent]) + .forEach((item) => entitlements.handleBranchModified(item)); + objectValues(events[OnBranchesModifiedEvent]) + .forEach((item) => entitlements.handleBranchesModified(item)); + if (!initiated) { + initiated = true; + const hasMyAppInSnapShot = onApplicationAddedEventArgs.some((a) => a.Name === agm.instance.application); + const hasMyInstanceInSnapShot = onApplicationStartedEventArgs.some((i) => i.Id === agm.instance.instance); + if (hasMyAppInSnapShot) { + if (hasMyInstanceInSnapShot) { + resolveFunc(configuration); + } + else { + const un = applications.onInstanceStarted((i) => { + if (i.id === agm.instance.instance) { + un(); + resolveFunc(configuration); + } + }); + } + } + else { + resolveFunc(configuration); + } + } + }); + subscription.onFailed((err) => rejectFunc(err)); + }) + .catch((err) => { var _a; return rejectFunc(`Error subscribing for ${OnEventMethodName} stream. Err: ${(_a = err.message) !== null && _a !== void 0 ? _a : JSON.stringify(err)}`); }); + return resultPromise; + }; + const stop = () => { + if (subscription) { + subscription.close(); + } + }; + return { + start, + stop + }; + } + + const InMemoryStoreCommandMethodName = "T42.ACS.InMemoryStoreCommand"; + class InMemoryStore { + constructor(interop) { + this.interop = interop; + } + import(apps, mode) { + if (!apps || !Array.isArray(apps)) { + return Promise.reject(new Error("invalid apps argument - should be an array of application definitions")); + } + if (mode && mode !== "replace" && mode !== "merge") { + return Promise.reject(new Error("invalid mode argument - should be 'replace' or 'merge'")); + } + mode = mode !== null && mode !== void 0 ? mode : "replace"; + const command = { + command: "import", + args: { + apps, + mode + } + }; + return this.interop.invoke(InMemoryStoreCommandMethodName, command, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }) + .then((r) => r.returned); + } + export() { + return this.interop.invoke(InMemoryStoreCommandMethodName, { command: "export" }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }) + .then((r) => r.returned.apps); + } + remove(app) { + if (!app || typeof app !== "string") { + return Promise.reject(new Error("invalid app name, should be a string value")); + } + const command = { + command: "remove", + args: { + apps: [app] + } + }; + return this.interop.invoke(InMemoryStoreCommandMethodName, command, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }).then((r) => r.returned); + } + clear() { + const command = { + command: "clear" + }; + return this.interop.invoke(InMemoryStoreCommandMethodName, command, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }).then((r) => r.returned); + } + createAppDef(name, url) { + if (!url) { + url = "https://google.com"; + } + return { + name, + type: "window", + title: name, + details: { + url + } + }; + } + } + + var AppManagerFactory = (config) => { + if (!config) { + throw Error("config not set"); + } + if (!config.agm) { + throw Error("config.agm is missing"); + } + const START_ONLY = "startOnly"; + const SKIP_ICONS = "skipIcons"; + const FULL = "full"; + const mode = config.mode || START_ONLY; + if (mode !== START_ONLY && mode !== SKIP_ICONS && mode !== FULL) { + throw new Error(`Invalid mode for appManager lib - ${mode} is not supported`); + } + const activities = config.activities; + const agm = config.agm; + const logger = config.logger; + const windows = config.windows; + let configuration = {}; + const appManager = new AppManagerImpl(mode, agm, activities, windows, logger.subLogger("applications"), config.gdMajorVersion, () => configuration); + const entitlements = new EntitlementsImpl(agm); + let readyPromise; + if (mode === START_ONLY) { + readyPromise = snapshot(agm, appManager); + } + else { + const subscription = createDataSubscription(agm, appManager, entitlements, mode === SKIP_ICONS); + readyPromise = subscription.start(); + } + const api = { + ready: () => readyPromise.then((c) => { configuration = c; }), + applications: appManager.applications, + application: appManager.application, + getConfigurations: appManager.getConfigurations, + onAppAdded: appManager.onAppAdded, + onAppRemoved: appManager.onAppRemoved, + onAppChanged: appManager.onAppChanged, + onAppAvailable: appManager.onAppAvailable, + onAppUnavailable: appManager.onAppUnavailable, + instances: appManager.instances, + get myInstance() { + return appManager.getMyInstance(); + }, + get myApplication() { + return appManager.getMyApplication(); + }, + onInstanceStarted: appManager.onInstanceStarted, + onInstanceStopped: appManager.onInstanceStopped, + onInstanceUpdated: appManager.onInstanceUpdated, + onInstanceStartFailed: appManager.onInstanceStartFailed, + getRegion: entitlements.getRegion, + getBranches: entitlements.getBranches, + getCurrentBranch: entitlements.getCurrentBranch, + getFunctionalEntitlement: entitlements.getFunctionalEntitlement, + getFunctionalEntitlementBranch: entitlements.getFunctionalEntitlementBranch, + setCurrentBranch: entitlements.setCurrentBranch, + setRegion: entitlements.setRegion, + currentUser: entitlements.currentUser, + canI: entitlements.canI, + canIBranch: entitlements.canIBranch, + onBranchesChanged: entitlements.onBranchesChanged, + exit: entitlements.exit, + restart: entitlements.restart, + onShuttingDown: entitlements.onShuttingDown, + inMemory: new InMemoryStore(agm) + }; + return api; + }; + + const T42JumpListAction = "T42.JumpList.Action"; + class JumpListManager { + constructor() { + this._groupActionCallbacks = new Map(); + this._registered = false; + } + init(executor, agm, logger) { + this._executor = executor; + this._agm = agm; + this._logger = logger; + this.registerCallbackMethod(); + } + setEnabled(windowId, enabled) { + const settings = { + enabled + }; + return this._executor.updateJumpList(windowId, settings); + } + createCategory(windowId, title, actions) { + this.validateActions(title, actions); + const settings = { + category: { + title, + operation: "create", + actions: this.toUpdateActions(windowId, "create", title, actions) + } + }; + return this._executor.updateJumpList(windowId, settings); + } + removeCategory(windowId, title) { + const settings = { + category: { + title, + operation: "remove", + actions: [] + } + }; + this.manageActionCallback(windowId, settings.category.operation, title); + return this._executor.updateJumpList(windowId, settings); + } + createActions(windowId, categoryTitle, actions) { + this.validateActions(categoryTitle, actions); + const settings = { + category: { + title: categoryTitle, + operation: "update", + actions: this.toUpdateActions(windowId, "create", categoryTitle, actions) + } + }; + return this._executor.updateJumpList(windowId, settings); + } + removeActions(windowId, categoryTitle, actions) { + const settings = { + category: { + title: categoryTitle, + operation: "update", + actions: this.toUpdateActions(windowId, "remove", categoryTitle, actions) + } + }; + return this._executor.updateJumpList(windowId, settings); + } + async getActions(windowId, catgoryTitle) { + const actions = []; + const configuration = await this.getJumpListSettings(windowId); + const currentCategory = configuration.categories.find((category) => category.title === catgoryTitle); + if (currentCategory) { + currentCategory.actions.forEach((action) => { + const actionCallback = this.getActionCallback(action.callbackId); + if (actionCallback) { + action.callback = actionCallback.callback; + } + actions.push({ + icon: action.icon, + callback: action.callback, + singleInstanceTitle: action.singleInstanceTitle, + multiInstanceTitle: action.multiInstanceTitle + }); + }); + } + return Promise.resolve(actions); + } + getJumpListSettings(windowId) { + return this._executor.getJumpList(windowId); + } + toUpdateActions(windowId, operation, categoryTitle, actions) { + return actions.map((action) => { + const updateAction = { + icon: action.icon, + callback: action.callback, + callbackId: Utils.generateId(), + singleInstanceTitle: action.singleInstanceTitle, + multiInstanceTitle: action.multiInstanceTitle, + operation + }; + this.manageActionCallback(windowId, operation, categoryTitle, updateAction); + return updateAction; + }); + } + manageActionCallback(windowId, operation, categoryTitle, updateAction) { + var _a; + const groupCallbacksKey = `${categoryTitle}-${windowId}`; + if (operation === "create") { + if (!this._groupActionCallbacks.has(groupCallbacksKey)) { + this._groupActionCallbacks.set(groupCallbacksKey, []); + } + const categoryActionCallbacks = this._groupActionCallbacks.get(groupCallbacksKey); + categoryActionCallbacks.push({ + callbackId: updateAction.callbackId, + callback: updateAction.callback + }); + } + else if (operation === "remove") { + if (updateAction) { + let categoryActionCallbacks = (_a = this._groupActionCallbacks.get(groupCallbacksKey)) !== null && _a !== void 0 ? _a : []; + categoryActionCallbacks = categoryActionCallbacks.filter((accCal) => accCal.callbackId !== updateAction.callbackId); + if (categoryActionCallbacks.length === 0) { + this._groupActionCallbacks.delete(groupCallbacksKey); + } + else { + this._groupActionCallbacks.set(groupCallbacksKey, categoryActionCallbacks); + } + } + else { + this._groupActionCallbacks.delete(groupCallbacksKey); + } + } + } + registerCallbackMethod() { + if (this._registered) { + return; + } + this._registered = true; + try { + this._agm.register(T42JumpListAction, (args, caller) => { + const actionCallback = this.getActionCallback(args.callbackId); + if (actionCallback) { + try { + actionCallback.callback(); + } + catch (e) { + this._logger.error("Unable to execute user callback for jump list action!", e); + } + } + }); + } + catch (e) { + this._logger.error(`Unable to register method ${T42JumpListAction} for invoking jump list action callbacks!`, e); + return Promise.reject(e); + } + } + getActionCallback(callbackId) { + let callbackAction; + [...this._groupActionCallbacks.values()].forEach((callbacks) => { + const callback = callbacks.find((cal) => cal.callbackId === callbackId); + if (callback) { + callbackAction = callback; + } + }); + return callbackAction; + } + validateActions(category, actions) { + if (!(actions && actions.length > 0)) { + throw new Error(`Category '${category}' doesn't contain any actions!`); + } + actions.forEach((action) => { + if (!action.singleInstanceTitle) { + throw new Error(`Category '${category}' contains an action with undefined singleInstanceTitle!`); + } + if (!action.multiInstanceTitle) { + throw new Error(`Category '${category}' contains an action with undefined multiInstanceTitle!`); + } + if (!action.callback) { + throw new Error(`Category '${category}' contains an action with undefined callback function!`); + } + }); + } + } + var jumpListManager = new JumpListManager(); + + class WindowStore { + constructor() { + this.waitForTimeoutInMilliseconds = 60000; + this._windows = {}; + this._pendingWindows = {}; + this._pendingWindowsStates = {}; + this._registry = CallbackRegistryFactory(); + } + init(logger) { + this._logger = logger; + } + get(id) { + return this._windows[id] || this._pendingWindows[id]; + } + getIfReady(id) { + return this._windows[id]; + } + get list() { + return this._windows; + } + add(window, state) { + const isExist = typeof this._pendingWindows[window.API.id] !== "undefined"; + if (isExist) { + this._logger.error(`trying to add window with id ${window.API.id} from windowStore, which already exists`); + return; + } + this._pendingWindows[window.API.id] = window; + this._pendingWindowsStates[window.API.id] = state; + this._registry.execute("on-added", window); + if (this.shouldMarkReadyToShow(state)) { + this.markReadyToShow(window.API.id); + } + } + remove(window) { + delete this._windows[window.API.id]; + delete this._pendingWindows[window.API.id]; + delete this._pendingWindowsStates[window.API.id]; + this._registry.execute("on-removed", window); + } + setUrlChangedState(windowId) { + const targetWindowState = this._pendingWindowsStates[windowId]; + if (typeof targetWindowState === "undefined") { + return; + } + targetWindowState.urlChanged = true; + if (this.shouldMarkReadyToShow(targetWindowState)) { + this.markReadyToShow(windowId); + } + } + setCompositionChangedState(wrapper) { + const windowId = wrapper.API.id; + const targetWindowState = this._pendingWindowsStates[windowId]; + if (typeof targetWindowState === "undefined") { + return; + } + targetWindowState.compositionChanged = true; + if (this.shouldMarkReadyToShow(targetWindowState)) { + this.markReadyToShow(windowId); + } + } + waitFor(id) { + return new Promise((resolve, reject) => { + let unReady; + let unRemoved; + const timeout = setTimeout(() => { + unReady(); + unRemoved(); + reject(new Error(`Window with id "${id}" was not ready within ${this.waitForTimeoutInMilliseconds} milliseconds.`)); + }, this.waitForTimeoutInMilliseconds); + const win = this._windows[id]; + if (win) { + clearTimeout(timeout); + resolve(win); + } + else { + const cleanup = () => { + clearTimeout(timeout); + unReady(); + unRemoved(); + }; + unReady = this.onReadyWindow((w) => { + if (w.API.id !== id) { + return; + } + cleanup(); + resolve(w); + }); + unRemoved = this.onRemoved((w) => { + if (w.API.id !== id) { + return; + } + cleanup(); + reject(new Error(`Window with id "${id}" was closed before it became ready.`)); + }); + } + }); + } + onReadyWindow(callback) { + return this._registry.add("on-ready", callback); + } + onAdded(callback) { + return this._registry.add("on-added", callback); + } + onRemoved(callback) { + return this._registry.add("on-removed", callback); + } + markReadyToShow(windowId) { + if (this._pendingWindows[windowId]) { + this._windows[windowId] = this._pendingWindows[windowId]; + delete this._pendingWindows[windowId]; + delete this._pendingWindowsStates[windowId]; + } + this._registry.execute("on-ready", this._windows[windowId]); + } + shouldMarkReadyToShow(targetWindowState) { + return targetWindowState && targetWindowState.urlChanged && targetWindowState.ready && targetWindowState.compositionChanged; + } + } + var windowStore = new WindowStore(); + + class JumpListActions { + constructor(windowId, configuration) { + this.windowId = windowId; + this._categoryTitle = configuration.title; + } + list() { + return jumpListManager.getActions(this.windowId, this._categoryTitle); + } + create(actions) { + return jumpListManager.createActions(this.windowId, this._categoryTitle, actions); + } + remove(actions) { + return jumpListManager.removeActions(this.windowId, this._categoryTitle, actions); + } + } + + class JumpListCategories { + constructor(windowId) { + this.windowId = windowId; + } + list() { + return this.getCategories(); + } + create(title, actions) { + return jumpListManager.createCategory(this.windowId, title, actions); + } + remove(title) { + return jumpListManager.removeCategory(this.windowId, title); + } + async find(title) { + const categories = await this.getCategories(); + return categories.find((cat) => cat.title === title); + } + async getCategories() { + const result = []; + const configuration = await jumpListManager.getJumpListSettings(this.windowId); + configuration.categories.forEach((category) => { + result.push({ + title: category.title, + actions: new JumpListActions(this.windowId, category) + }); + }); + return result; + } + } + + class JumpList { + constructor(windowId) { + this.windowId = windowId; + this._categories = new JumpListCategories(windowId); + } + get categories() { + return this._categories; + } + async isEnabled() { + const configuration = await jumpListManager.getJumpListSettings(this.windowId); + return configuration.enabled; + } + setEnabled(enabled) { + return jumpListManager.setEnabled(this.windowId, enabled); + } + } + + var windowFactory = (id, options, executor, logger, appManagerGetter, displayAPIGetter, channelsAPIGetter, agm) => { + var _a, _b, _c, _d; + const _registry = CallbackRegistryFactory(); + const getChannels = () => { + const channels = channelsAPIGetter(); + if (!channels) { + throw new Error(`To use this method you need to enable channels API - set the channels property to true when initializing the Glue42 library`); + } + return channels; + }; + const _id = id; + const _name = options.name; + const _mode = options.mode; + let _bounds = options.bounds; + let _url = options.url; + let _title = options.title; + let _context = (_a = options.context) !== null && _a !== void 0 ? _a : {}; + let _frameColor = options.frameColor; + let _focus = options.focus; + let _neighbours = (_b = options.neighbours) !== null && _b !== void 0 ? _b : {}; + let _groupId = options.groupId; + let _isGroupHeaderVisible = options.isGroupHeaderVisible; + let _isTabHeaderVisible = options.isTabHeaderVisible; + let _isGroupHibernated = options.isGroupHibernated; + let _isGroupVisible = options.isGroupVisible; + let _isTabSelected = (_c = options.isTabSelected) !== null && _c !== void 0 ? _c : false; + let _settings = options.settings; + const _applicationName = options.applicationName; + let _isVisible = options.isVisible; + let _isSticky = options.isSticky; + let _isCollapsed = options.isCollapsed; + let _windowState = options.state; + let _tabGroupId = options.tabGroupId; + let _tabIndex = options.tabIndex; + let _frameId = options.frameId; + let _isLocked = options.isLocked; + let _allowWorkspaceDrop = options.allowWorkspaceDrop; + let _isPinned = options.isPinned; + let _group; + let _frameButtons = (_d = options.frameButtons) !== null && _d !== void 0 ? _d : []; + let _zoomFactor = options.zoomFactor; + let _placementSettings = options.placementSettings; + const _jumpList = new JumpList(id); + function close(cbOrOptions, error) { + if (typeof cbOrOptions === "undefined" || typeof cbOrOptions === "function") { + return Utils.callbackifyPromise(() => { + if (!id) { + throw new Error("The window is already closed."); + } + return executor.close(resultWindow); + }, cbOrOptions, error); + } + else { + return executor.close(resultWindow, cbOrOptions); + } + } + function navigate(newUrl, optionsOrCallback, error) { + if (typeof optionsOrCallback === "function") { + return Utils.callbackifyPromise(() => { + if (isNullOrWhiteSpace(newUrl)) { + throw new Error("The new URL must be a non-empty string."); + } + return executor.navigate(resultWindow, newUrl); + }, optionsOrCallback, error); + } + if (isNullOrWhiteSpace(newUrl)) { + throw new Error("The new URL must be a non-empty string."); + } + if ((optionsOrCallback === null || optionsOrCallback === void 0 ? void 0 : optionsOrCallback.timeout) && typeof optionsOrCallback.timeout !== "number") { + throw new Error("Timeout argument must be a valid number"); + } + return executor.navigate(resultWindow, newUrl, optionsOrCallback); + } + function setStyle(style, success, error) { + return Utils.callbackifyPromise(() => { + if (!style || Object.keys(style).length === 0 || Object.keys(style).every((key) => !key)) { + throw new Error("Invalid style arguments: " + JSON.stringify(style)); + } + if (style && style.focus !== undefined) { + if (typeof style.focus !== "boolean") { + throw new Error("Focus must be a boolean value. Currently, only `focus: true` is supported."); + } + else if (style.focus === false) { + console.warn("`focus: false` is not supported!"); + } + } + if (style && style.hidden !== undefined && typeof style.hidden !== "boolean") { + throw new Error("The `hidden` property must hold a boolean value."); + } + for (const prop of ["minHeight", "maxHeight", "minWidth", "maxWidth"]) { + const styleAsAny = style; + const value = styleAsAny[prop]; + if (prop in style) { + if (isUndefinedOrNull(value)) { + delete styleAsAny[prop]; + continue; + } + if (!isNumber(styleAsAny[prop])) { + throw new Error(`"${prop}" must be a number`); + } + } + } + return executor.setStyle(resultWindow, style); + }, success, error); + } + function resetButtons(buttons, success, error) { + return Utils.callbackifyPromise(() => executor.resetButtons(resultWindow, buttons), success, error); + } + function getButtons() { + return executor.getButtons(resultWindow); + } + function setOnTop(onTop, success, error) { + return Utils.callbackifyPromise(() => { + if (typeof onTop === "string") { + if (onTop !== "always") { + throw new Error("`onTop` must hold a `always` value."); + } + } + else if (typeof onTop !== "boolean") { + throw new Error("`onTop` must hold a boolean or `always` value."); + } + return executor.setOnTop(resultWindow, onTop); + }, success, error); + } + function setSizeConstraints(constraints, success, error) { + return Utils.callbackifyPromise(() => { + if (!constraints || Object.keys(constraints).every((value) => value === undefined)) { + throw new Error("The properties of `constraints` cannot be null or undefined."); + } + return executor.setSizeConstraints(resultWindow, constraints); + }, success, error); + } + function getSizeConstraints() { + return executor.getSizeConstraints(resultWindow); + } + function setTitle(newTitle, success, error) { + return Utils.callbackifyPromise(() => { + if (isUndefinedOrNull(newTitle)) { + throw new Error("`newTitle` must not be null or undefined."); + } + if (newTitle === _title) { + return Promise.resolve(resultWindow); + } + return executor.setTitle(resultWindow, newTitle); + }, success, error); + } + function setSticky(isSticky, success, error) { + return Utils.callbackifyPromise(() => { + if (typeof isSticky !== "boolean") { + throw new Error("`isSticky` must hold a boolean value."); + } + return executor.setSticky(resultWindow, isSticky); + }, success, error); + } + function setAllowWorkspaceDrop(allowWorkspaceDrop) { + if (typeof allowWorkspaceDrop !== "boolean") { + throw new Error("`allowWorkspaceDrop` must hold a boolean value."); + } + return executor.setAllowWorkspaceDrop(resultWindow, allowWorkspaceDrop); + } + function pin() { + return executor.pin(resultWindow); + } + function unpin() { + return executor.unpin(resultWindow); + } + function moveResize(bounds, success, error) { + return Utils.callbackifyPromise(() => { + if (isUndefinedOrNull(bounds)) { + throw new Error("The properties of `bounds` cannot be null or undefined."); + } + return executor.moveResize(resultWindow, bounds); + }, success, error); + } + function addFrameButton(buttonInfo, success, error) { + return Utils.callbackifyPromise(() => { + if (typeof buttonInfo === "undefined" || Object.keys(buttonInfo).length === 0) { + throw new Error("Button info is not available."); + } + if (isNullOrWhiteSpace(buttonInfo.buttonId)) { + throw new Error("`buttonId` must not be null or undefined."); + } + if (isNullOrWhiteSpace(buttonInfo.imageBase64)) { + throw new Error("`imageBase64` must not be null or undefined."); + } + return executor.addFrameButton(resultWindow, buttonInfo); + }, success, error); + } + function removeFrameButton(buttonId, success, error) { + return Utils.callbackifyPromise(() => { + if (isNullOrWhiteSpace(buttonId)) { + throw new Error("`buttonId` must not be null or undefined."); + } + return executor.removeFrameButton(resultWindow, buttonId); + }, success, error); + } + function activate(success, error) { + return Utils.callbackifyPromise(() => { + if (_focus) { + return Promise.resolve(resultWindow); + } + return executor.activate(resultWindow); + }, success, error); + } + function focus(success, error) { + return Utils.callbackifyPromise(() => { + if (_focus) { + return Promise.resolve(resultWindow); + } + return executor.focus(resultWindow); + }, success, error); + } + function maximizeRestore(success, error) { + return Utils.callbackifyPromise(() => { + return executor.maximizeRestore(resultWindow); + }, success, error); + } + function maximize(success, error) { + return Utils.callbackifyPromise(() => { + if (_windowState === "maximized") { + return Promise.resolve(resultWindow); + } + return executor.maximize(resultWindow); + }, success, error); + } + function restore(success, error) { + return Utils.callbackifyPromise(() => { + if (_windowState === "normal") { + return Promise.resolve(resultWindow); + } + return executor.restore(resultWindow); + }, success, error); + } + function minimize(success, error) { + return Utils.callbackifyPromise(() => { + if (_windowState === "minimized") { + return Promise.resolve(resultWindow); + } + return executor.minimize(resultWindow); + }, success, error); + } + function collapse(success, error) { + return Utils.callbackifyPromise(() => { + if (_isCollapsed) { + return Promise.resolve(resultWindow); + } + return executor.collapse(resultWindow); + }, success, error); + } + function expand(success, error) { + return Utils.callbackifyPromise(() => { + if (!_isCollapsed) { + return Promise.resolve(resultWindow); + } + return executor.expand(resultWindow); + }, success, error); + } + function toggleCollapse(success, error) { + return Utils.callbackifyPromise(() => { + return executor.toggleCollapse(resultWindow); + }, success, error); + } + function snap(target, direction, success, error) { + return Utils.callbackifyPromise(() => { + if (isUndefinedOrNull(target)) { + throw new Error(`A target window is not specified - ${typeof target === "string" ? target : JSON.stringify(target)}`); + } + if (typeof target === "string") { + const win = windowStore.get(target); + if (!win) { + throw new Error(`Invalid "target" parameter or no such window. Invoked with: ${target}`); + } + target = win.API; + } + if (typeof direction === "string") { + direction = { + direction, + autoAlign: true + }; + } + return executor.snap(resultWindow, target, direction); + }, success, error); + } + function attachTab(tab, opt, success, error) { + return Utils.callbackifyPromise(() => { + var _a; + const errorMessage = `Invalid "tab" parameter - must be an object with an "id" property or a string. Invoked for source window with ID:`; + if (isUndefinedOrNull(tab)) { + const errMsg = `${errorMessage} ${typeof tab === "string" ? tab : JSON.stringify(tab)}`; + throw new Error(errMsg); + } + let sourceWindow; + if (typeof tab === "string") { + sourceWindow = (_a = windowStore.get(tab)) === null || _a === void 0 ? void 0 : _a.API; + if (isUndefinedOrNull(sourceWindow)) { + const errMsg = `${errorMessage} ${typeof sourceWindow === "string" ? sourceWindow : JSON.stringify(sourceWindow)}`; + throw new Error(errMsg); + } + } + else if (!isUndefinedOrNull(tab.id)) { + sourceWindow = tab; + } + else { + throw new Error(errorMessage); + } + const attachOptions = {}; + if (!isUndefinedOrNull(opt)) { + if (typeof opt === "number") { + attachOptions.index = opt; + } + else { + attachOptions.selected = opt.selected; + attachOptions.index = opt.index; + } + } + return executor.attachTab(resultWindow, sourceWindow, attachOptions); + }, success, error); + } + function detachTab(opt = {}, success, error) { + return Utils.callbackifyPromise(() => { + const argsForSend = {}; + function isDetachRelative(o) { + return o.relativeTo !== undefined; + } + if (isDetachRelative(opt)) { + if (typeof opt.relativeTo === "string") { + argsForSend.relativeTo = opt.relativeTo; + } + else if (!isUndefinedOrNull(opt.relativeTo.id)) { + argsForSend.relativeTo = opt.relativeTo.id; + } + if (!isUndefinedOrNull(opt.relativeDirection)) { + argsForSend.relativeDirection = opt.relativeDirection; + } + if (!isUndefinedOrNull(opt.width)) { + argsForSend.width = opt.width; + } + if (!isUndefinedOrNull(opt.height)) { + argsForSend.height = opt.height; + } + } + else { + if (!isUndefinedOrNull(opt.bounds)) { + argsForSend.bounds = opt.bounds; + } + } + if (!isUndefinedOrNull(opt.hideTabHeader)) { + argsForSend.hideTabHeader = opt.hideTabHeader; + } + return executor.detachTab(resultWindow, argsForSend); + }, success, error); + } + function setVisible(toBeVisible, success, error) { + return Utils.callbackifyPromise(() => { + return executor.setVisible(resultWindow, toBeVisible); + }, success, error); + } + async function center(display) { + if (display) { + validateCenterArguments(display); + } + return executor.center(resultWindow, display); + } + function validateCenterArguments(display) { + if (typeof display !== "object") { + throw Error("display argument must be a valid display object"); + } + if (!display.workArea || !display.scaleFactor) { + throw Error("display argument is not a valid display object"); + } + } + function showLoader(loader) { + return executor.showLoader(resultWindow, loader); + } + function hideLoader() { + return executor.hideLoader(resultWindow); + } + function updateContext(context, success, error) { + return Utils.callbackifyPromise(() => { + if (!isObject(context)) { + throw new Error(`"context" must not be null or undefined.`); + } + return executor.updateContext(resultWindow, context, false); + }, success, error); + } + function lock(success, error) { + return Utils.callbackifyPromise(() => { + return executor.lock(resultWindow); + }, success, error); + } + function unlock(success, error) { + return Utils.callbackifyPromise(() => { + return executor.unlock(resultWindow); + }, success, error); + } + function getIcon(success, error) { + return Utils.callbackifyPromise(() => { + return executor.getIcon(resultWindow); + }, success, error); + } + function setIcon(base64Image, success, error) { + return Utils.callbackifyPromise(() => { + if (isNullOrWhiteSpace(base64Image)) { + throw new Error(`"base64Image" must be a non-empty string.`); + } + return executor.setIcon(resultWindow, base64Image); + }, success, error); + } + function setFrameColor(frameColor, success, error) { + return Utils.callbackifyPromise(() => { + if (isNullOrWhiteSpace(frameColor)) { + throw new Error(`"frameColor" must be a non-empty string`); + } + return executor.setFrameColor(resultWindow, frameColor); + }, success, error); + } + function setTabHeaderVisible(toBeTabHeaderVisible, success, error) { + return Utils.callbackifyPromise(() => { + if (typeof toBeTabHeaderVisible !== "boolean") { + throw new Error(`"toBeTabHeaderVisible" must hold a boolean value.`); + } + return executor.setTabHeaderVisible(resultWindow, toBeTabHeaderVisible); + }, success, error); + } + async function setTabTooltip(tooltip) { + if (isNullOrWhiteSpace(tooltip)) { + throw new Error(`"${tooltip}" must not be null or undefined`); + } + return executor.setTabTooltip(resultWindow, tooltip); + } + async function getTabTooltip() { + return executor.getTabTooltip(resultWindow); + } + function showPopup(config) { + return executor.showPopup(resultWindow, config); + } + function createFlydown(config) { + return executor.createFlydown(resultWindow.id, config); + } + function setModalState(isModal) { + return executor.setModalState(resultWindow.id, isModal || false); + } + function zoomIn(success, error) { + return Utils.callbackifyPromise(() => { + return executor.zoomIn(resultWindow); + }, success, error); + } + function zoomOut(success, error) { + return Utils.callbackifyPromise(() => { + return executor.zoomOut(resultWindow); + }, success, error); + } + function setZoomFactor(zoomFactor, success, error) { + return Utils.callbackifyPromise(() => { + if (isNaN(zoomFactor)) { + throw new Error(`zoomFactor is not a number`); + } + return executor.setZoomFactor(resultWindow, zoomFactor); + }, success, error); + } + function showDevTools() { + return executor.showDevTools(resultWindow); + } + function capture(captureOptions) { + return executor.capture(resultWindow, captureOptions); + } + function flash(suppliedOptions, mode) { + const flashOptions = { + shouldFlash: true, + mode: "auto" + }; + if (typeof suppliedOptions === "boolean") { + flashOptions.shouldFlash = suppliedOptions; + } + if (typeof mode !== "undefined") { + flashOptions.mode = mode; + } + return executor.flash(resultWindow, flashOptions); + } + function flashTab(suppliedOptions) { + const flashOptions = { + shouldFlash: true, + }; + if (typeof suppliedOptions === "boolean") { + flashOptions.shouldFlash = suppliedOptions; + } + return executor.flashTab(resultWindow, flashOptions); + } + function print(printOptions) { + return executor.print(resultWindow, printOptions); + } + function printToPDF(printToPDFOptions) { + return executor.printToPDF(resultWindow, printToPDFOptions); + } + function ungroup(ungroupOptions) { + return new Promise((resolve, reject) => { + const unGroupChanged = onGroupChanged((win, newGroup, oldGroup) => { + if (id === win.id) { + unGroupChanged(); + resolve(resultWindow); + } + }); + executor.ungroup(resultWindow, ungroupOptions) + .catch((e) => { + unGroupChanged(); + reject(e); + }); + }); + } + function place(placementSettings) { + return executor.place(resultWindow, placementSettings); + } + function refresh(ignoreCache) { + return executor.refresh(resultWindow, ignoreCache); + } + function download(url, opts) { + return executor.download(resultWindow, url, opts); + } + function configure(settings) { + return executor.configureWindow(resultWindow, settings); + } + function getConfiguration() { + return executor.getWindowConfiguration(resultWindow); + } + function getDockingPlacement() { + return executor.getDockingPlacement(resultWindow); + } + function dock(opts) { + return executor.dock(resultWindow, opts); + } + async function clone(cloneOptions) { + return executor.clone(resultWindow, cloneOptions); + } + async function executeCode(code) { + if (!code) { + throw new Error("Code argument is missing"); + } + if (typeof code !== "string") { + throw new Error("Code argument must be a valid string"); + } + const response = await executor.executeCode(resultWindow, code); + return response.result; + } + function onTitleChanged(callback) { + if (!isFunction(callback)) { + throw new Error("callback should be a function"); + } + callback(resultWindow.title, resultWindow); + return onEventCore("onTitleChanged", callback); + } + function onClose(callback) { + if (!isFunction(callback)) { + throw new Error("callback should be a function"); + } + if (id === undefined) { + callback(resultWindow); + } + return _registry.add("onClose", callback); + } + function onUrlChanged(callback) { + return onEventCore("onUrlChanged", callback); + } + function onFrameButtonAdded(callback) { + return onEventCore("onFrameButtonAdded", callback); + } + function onFrameButtonRemoved(callback) { + return onEventCore("onFrameButtonRemoved", callback); + } + function onFrameButtonClicked(callback) { + return onEventCore("onFrameButtonClicked", callback); + } + function onCollapsed(callback) { + if (!isFunction(callback)) { + throw new Error("callback should be a function"); + } + if (_isCollapsed) { + callback(resultWindow); + } + return _registry.add("collapsed", callback); + } + function onExpanded(callback) { + if (!isFunction(callback)) { + throw new Error("callback should be a function"); + } + if (!_isCollapsed) { + callback(resultWindow); + } + return _registry.add("expanded", callback); + } + function onMaximized(callback) { + if (_windowState === "maximized") { + return onEventCore("maximized", callback, [resultWindow]); + } + else { + return onEventCore("maximized", callback); + } + } + function onMinimized(callback) { + if (_windowState === "minimized") { + return onEventCore("minimized", callback, [resultWindow]); + } + else { + return onEventCore("minimized", callback); + } + } + function onNormal(callback) { + if (_windowState === "normal") { + return onEventCore("normal", callback, [resultWindow]); + } + else { + return onEventCore("normal", callback); + } + } + function onAttached(callback) { + return onEventCore("attached", callback); + } + function onDetached(callback) { + return onEventCore("detached", callback); + } + function onVisibilityChanged(callback) { + return onEventCore("visibility-changed", callback); + } + function onContextUpdated(callback) { + return onEventCore("context-updated", callback); + } + function onLockingChanged(callback) { + return onEventCore("lock-changed", callback); + } + function onBoundsChanged(callback) { + return onEventCore("bounds-changed", callback); + } + function onFocusChanged(callback) { + return onEventCore("focus-changed", callback); + } + function onStickyChanged(callback) { + return onEventCore("sticky-changed", callback); + } + function onFrameColorChanged(callback) { + return onEventCore("frame-color-changed", callback); + } + function onTabHeaderVisibilityChanged(callback) { + return onEventCore("tab-header-visibility-changed", callback); + } + function onWindowAttached(callback) { + return onEventCore("window-attached", callback); + } + function onWindowDetached(callback) { + return onEventCore("window-detached", callback); + } + function onGroupChanged(callback) { + return onEventCore("group-changed", callback); + } + function onTabSelectionChanged(callback) { + return onEventCore("tab-selection-changed", callback); + } + function onChannelRestrictionsChanged(callback) { + if (!isFunction(callback)) { + throw new Error("callback must be a function"); + } + return onEventCore("channel-restrictions-changed", callback); + } + function onClosing(callback) { + if (!isFunction(callback)) { + throw new Error("callback must be a function"); + } + const callbackWrap = (success, error, prevent) => { + const promise = callback(prevent); + if (promise === null || promise === void 0 ? void 0 : promise.then) { + promise.then(success).catch(error); + } + else { + success(); + } + }; + return executor.onClosing(callbackWrap, resultWindow); + } + function onRefreshing(callback) { + if (!isFunction(callback)) { + throw new Error("callback must be a function"); + } + const callbackWrap = (success, error, prevent) => { + const promise = callback(prevent); + if (promise === null || promise === void 0 ? void 0 : promise.then) { + promise.then(success).catch(error); + } + else { + success(); + } + }; + return executor.onRefreshing(callbackWrap, resultWindow); + } + function onNavigating(callback) { + if (!isFunction(callback)) { + throw new Error("callback must be a function"); + } + const callbackWrap = (success, error, prevent, args) => { + const promise = callback(args); + if (promise === null || promise === void 0 ? void 0 : promise.then) { + promise.then(success).catch(error); + } + else { + success(); + } + }; + return executor.onNavigating(callbackWrap, resultWindow); + } + function onZoomFactorChanged(callback) { + return onEventCore("zoom-factor-changed", callback); + } + function onPlacementSettingsChanged(callback) { + return onEventCore("placementSettingsChanged", callback); + } + function onNeighboursChanged(callback) { + return onEventCore("neighbours-changed", callback); + } + function onDockingChanged(callback) { + return onEventCore("docking-changed", callback); + } + function onEventCore(key, callback, replayArguments) { + if (!isFunction(callback)) { + throw new Error("callback must be a function"); + } + return _registry.add(key, callback, replayArguments); + } + function goBack() { + return executor.goBack(resultWindow); + } + function goForward() { + return executor.goForward(resultWindow); + } + function startDrag(option) { + return executor.startDrag(resultWindow, option); + } + function showDialog(dialogOptions) { + if ((dialogOptions === null || dialogOptions === void 0 ? void 0 : dialogOptions.timerDuration) && isNaN(dialogOptions === null || dialogOptions === void 0 ? void 0 : dialogOptions.timerDuration)) { + throw new Error("timerDuration must be a number"); + } + if ((dialogOptions === null || dialogOptions === void 0 ? void 0 : dialogOptions.showTimer) && typeof (dialogOptions === null || dialogOptions === void 0 ? void 0 : dialogOptions.showTimer) !== "boolean") { + throw new Error("showTimer must be a boolean"); + } + return executor.showDialog(resultWindow, dialogOptions); + } + function handleUpdate(updated) { + _url = updated.url; + _title = updated.title; + _context = updated.context || {}; + _bounds = updated.bounds; + _frameColor = updated.frameColor; + _focus = updated.focus; + _neighbours = updated.neighbours || {}; + _groupId = updated.groupId; + _isGroupHeaderVisible = updated.isGroupHeaderVisible; + _isTabHeaderVisible = updated.isTabHeaderVisible; + _isGroupHibernated = updated.isGroupHibernated; + _isGroupVisible = updated.isGroupVisible; + _isTabSelected = updated.isTabSelected; + _settings = updated.settings; + _isVisible = updated.isVisible; + _isSticky = updated.isSticky; + _isCollapsed = updated.isCollapsed; + _windowState = updated.state; + _tabGroupId = updated.tabGroupId; + _frameId = updated.frameId; + _isLocked = updated.isLocked; + _allowWorkspaceDrop = updated.allowWorkspaceDrop; + _isPinned = updated.isPinned; + _zoomFactor = updated.zoomFactor; + _placementSettings = updated.placementSettings; + } + function handleTitleChanged(newTitle) { + _title = newTitle; + executor.finished + .finally(() => { + _registry.execute("onTitleChanged", newTitle, resultWindow); + }); + } + function handleUrlChanged(newUrl) { + _url = newUrl; + _registry.execute("onUrlChanged", newUrl, resultWindow); + } + function handleVisibilityChanged(isVisible) { + if (isVisible === _isVisible) { + return; + } + _isVisible = isVisible; + _registry.execute("visibility-changed", resultWindow); + } + function handleWindowSettingsChanged(settings) { + _settings = settings; + _registry.execute("settings-changed", resultWindow); + } + function handleContextUpdated(context) { + _context = context; + _registry.execute("context-updated", _context, resultWindow); + } + function handleWindowClose() { + if (id === undefined) { + return; + } + _registry.execute("onClose", resultWindow); + id = undefined; + } + function handleFrameButtonAdded(frameButton) { + const buttonObj = ["buttonId", "imageBase64", "order", "tooltip"].reduce((memo, k) => { + memo[k] = frameButton[k]; + return memo; + }, {}); + const frameButtonsIds = _frameButtons.map((btn) => { + return btn.buttonId; + }); + if (frameButtonsIds.indexOf(frameButton.buttonId) === -1) { + _frameButtons.push(buttonObj); + } + _registry.execute("onFrameButtonAdded", buttonObj, resultWindow); + } + function handleFrameButtonRemoved(frameButtonId) { + let button; + _frameButtons = _frameButtons.reduce((memo, btn) => { + if (btn.buttonId === frameButtonId) { + button = btn; + } + else { + memo.push(btn); + } + return memo; + }, []); + if (button !== undefined) { + _registry.execute("onFrameButtonRemoved", button, resultWindow); + } + } + function handleFrameButtonClicked(frameButton) { + const button = _frameButtons.filter((btn) => { + return btn.buttonId === frameButton.buttonId; + }); + if (button.length > 0) { + _registry.execute("onFrameButtonClicked", button[0], resultWindow); + } + } + async function handleWindowChangeState(state) { + if (state === "collapsed") { + _isCollapsed = true; + } + else if (state === "expanded") { + _isCollapsed = false; + } + else { + _windowState = state; + } + await executor.finished; + _registry.execute(state, resultWindow); + } + function handleFrameIsLockedChanged(isLocked) { + _isLocked = isLocked; + _registry.execute("lock-changed", resultWindow); + } + function handleBoundsChanged(bounds) { + if (_bounds.top === bounds.top && _bounds.left === bounds.left && _bounds.width === bounds.width && _bounds.height === bounds.height) { + return; + } + _bounds = bounds; + _registry.execute("bounds-changed", resultWindow); + } + function handleFocusChanged(isFocused) { + _focus = isFocused; + _registry.execute("focus-changed", resultWindow); + } + function handleIsStickyChanged(isSticky) { + _isSticky = isSticky; + _registry.execute("sticky-changed", isSticky, resultWindow); + } + function handleFrameColorChanged(frameColor) { + _frameColor = frameColor; + _registry.execute("frame-color-changed", resultWindow); + } + function handleFrameAttached(tabGroupId, frameId, isTabHeaderVisible) { + _tabGroupId = tabGroupId; + _frameId = frameId; + _isTabHeaderVisible = isTabHeaderVisible; + _registry.execute("frame-attached", resultWindow); + } + function handleCompositionChanged(state) { + _neighbours = state.neighbors || {}; + _tabIndex = state.index; + _registry.execute("neighbours-changed", _neighbours, resultWindow); + } + function handleAllowWorkspaceDropChanged(allowWorkspaceDrop) { + _allowWorkspaceDrop = allowWorkspaceDrop; + _registry.execute("allow-workspace-drop-changed", resultWindow); + } + function handleIsPinnedChanged(isPinned) { + _isPinned = isPinned; + _registry.execute("is-pinned-changed", resultWindow); + } + function handleGroupHeaderVisibilityChanged(isGroupHeaderVisible) { + _isGroupHeaderVisible = isGroupHeaderVisible; + } + function handleTabHeaderVisibilityChanged(isTabHeaderVisible) { + if (_isTabHeaderVisible !== isTabHeaderVisible) { + _isTabHeaderVisible = isTabHeaderVisible; + _registry.execute("tab-header-visibility-changed", resultWindow); + } + } + async function handleFrameSelectionChanged(newWindow, prevWindow) { + let selectedWindow; + if (newWindow === id) { + _isTabSelected = true; + selectedWindow = resultWindow; + } + else { + _isTabSelected = false; + selectedWindow = windowStore.get(newWindow) ? windowStore.get(newWindow).API : undefined; + } + const previousWindow = windowStore.get(prevWindow) ? windowStore.get(prevWindow).API : undefined; + await executor.finished; + _registry.execute("tab-selection-changed", selectedWindow, previousWindow, resultWindow); + } + async function handleAttached(newTabGroupId, newFrameId, tabHeaderVisible, isLocked, winsToBeNotified) { + _tabGroupId = newTabGroupId; + _isTabHeaderVisible = tabHeaderVisible; + _frameId = newFrameId; + if (typeof isLocked !== "undefined") { + _isLocked = isLocked; + } + await executor.finished; + winsToBeNotified.forEach((w) => { + w.Events.handleWindowAttached(resultWindow); + }); + _registry.execute("attached", resultWindow); + } + function handleWindowAttached(win) { + _registry.execute("window-attached", win); + } + async function handleDetached(isLocked, winsToBeNotified) { + _tabGroupId = undefined; + _isTabSelected = false; + if (typeof isLocked !== "undefined") { + _isLocked = isLocked; + } + await executor.finished; + winsToBeNotified.forEach((w) => { + w.Events.handleWindowDetached(resultWindow); + }); + _registry.execute("detached", resultWindow); + } + function handleWindowDetached(win) { + _registry.execute("window-detached", win); + } + function handleZoomFactorChanged(zoomFactor) { + _zoomFactor = zoomFactor; + _registry.execute("zoom-factor-changed", resultWindow); + } + function handlePlacementSettingsChanged(placementSettings) { + let promise; + const copy = placementSettings; + if (!copy.display) { + promise = Promise.resolve(undefined); + } + else { + const displayAPI = displayAPIGetter(); + if (!displayAPI) { + promise = Promise.resolve(undefined); + } + else { + const index = copy.display - 1; + promise = new Promise((resolve, reject) => { + displayAPI.all().then((displays) => { + const display = displays.find((d) => d.index === index); + resolve(display); + }).catch(reject); + }); + } + } + void promise.then((d) => { + copy.display = d; + _placementSettings = copy; + _registry.execute("placementSettingsChanged", resultWindow); + }); + } + function handleDockingChanged(data) { + _registry.execute("docking-changed", resultWindow, { + docked: data.docked, + position: data.position, + claimScreenArea: data.claimScreenArea + }); + } + function handleChannelRestrictionsChanged(data) { + _registry.execute("channel-restrictions-changed", data); + } + function handleGroupChanged(newGroup, oldGroup) { + _group = newGroup; + _groupId = newGroup === null || newGroup === void 0 ? void 0 : newGroup.id; + if (!isUndefinedOrNull(newGroup) && !isUndefinedOrNull(oldGroup)) { + _registry.execute("group-changed", resultWindow, newGroup, oldGroup); + } + } + function getAllTabs() { + const allWindows = windowStore.list; + if (_mode.toLowerCase() !== "tab") { + return []; + } + const tabs = Object.keys(allWindows).reduce((memo, win) => { + const window = allWindows[win]; + if (window + && window.API.tabGroupId + && typeof window.API.tabGroupId !== "undefined" + && typeof resultWindow.tabGroupId !== "undefined" + && window.API.tabGroupId === resultWindow.tabGroupId) { + memo.push(window.API); + } + return memo; + }, []); + return tabs.sort((w1, w2) => { + if (w1.tabIndex !== w2.tabIndex) { + if (w1.tabIndex === -1) { + return Number.MAX_SAFE_INTEGER; + } + if (w2.tabIndex === -1) { + return Number.MIN_SAFE_INTEGER; + } + } + return w1.tabIndex - w2.tabIndex; + }); + } + function mapWindowIdsToWindowObjects(windowIdArr) { + return windowIdArr.reduce((memo, winId) => { + const window = windowStore.get(winId); + if (window) { + memo.push(window.API); + } + return memo; + }, []); + } + function getNeighboursByDirection(direction) { + const windowIds = _neighbours[direction]; + if (typeof windowIds !== "undefined") { + return mapWindowIdsToWindowObjects(windowIds); + } + } + function getApplicationName() { + var _a; + if (_applicationName) { + return _applicationName; + } + if (_context._APPLICATION_NAME) { + return _context._APPLICATION_NAME; + } + if (_context && _context._t42 && _context._t42.application) { + return _context._t42.application; + } + const info = getWindowInfo(); + if (info && info.applicationName) { + return info.applicationName; + } + const appManager = appManagerGetter(); + if (appManager) { + const instance = appManager.instances().find((i) => id === i.id); + if (instance) { + return (_a = instance.application) === null || _a === void 0 ? void 0 : _a.name; + } + } + return undefined; + } + function getWindowInfo() { + if (typeof window !== "undefined" && window.glue42gd && window.glue42gd.getWindowInfo) { + const info = window.glue42gd.getWindowInfo(id); + if (!info) { + return undefined; + } + else { + return info; + } + } + } + const resultWindow = { + get id() { + return _id; + }, + get name() { + return _name; + }, + get application() { + const appManager = appManagerGetter(); + const appName = getApplicationName(); + if (appName && appManager) { + return appManager.application(appName); + } + }, + get hostInstance() { + return executor.hostInstance; + }, + get interopInstance() { + const instance = agm.servers().find((s) => s.windowId === this.id); + if (instance) { + return instance; + } + else { + const appName = getApplicationName(); + if (appName) { + return { application: appName }; + } + } + }, + get agmInstance() { + return resultWindow.interopInstance; + }, + get url() { + return _url; + }, + get title() { + return _title; + }, + get windowStyleAttributes() { + return _settings; + }, + get settings() { + return _settings; + }, + get tabGroupId() { + return _mode.toLowerCase() === "tab" ? _tabGroupId : undefined; + }, + get tabIndex() { + return _mode.toLowerCase() === "tab" ? _tabIndex : undefined; + }, + get frameId() { + return _frameId; + }, + get frameButtons() { + return _frameButtons.sort((b1, b2) => b1.order - b2.order); + }, + get mode() { + return _mode; + }, + get state() { + return _windowState; + }, + get isCollapsed() { + return _isCollapsed; + }, + get isVisible() { + return _isVisible; + }, + get isLocked() { + return _isLocked; + }, + get context() { + return _context; + }, + get bounds() { + return _bounds; + }, + get minHeight() { + return _settings.minHeight; + }, + get maxHeight() { + return _settings.maxHeight; + }, + get minWidth() { + return _settings.minWidth; + }, + get maxWidth() { + return _settings.maxWidth; + }, + get isFocused() { + return _focus; + }, + get frameColor() { + return _frameColor; + }, + get opened() { + return resultWindow.id !== undefined; + }, + get group() { + return _group; + }, + get groupId() { + return _groupId; + }, + get isSticky() { + return _isSticky; + }, + get topNeighbours() { + return getNeighboursByDirection("top"); + }, + get leftNeighbours() { + return getNeighboursByDirection("left"); + }, + get rightNeighbours() { + return getNeighboursByDirection("right"); + }, + get bottomNeighbours() { + return getNeighboursByDirection("bottom"); + }, + get isGroupHeaderVisible() { + return _isGroupHeaderVisible; + }, + get activityId() { + if (_context._t42) { + return _context._t42.activityId; + } + const info = getWindowInfo(); + if (!info) { + return undefined; + } + return info.activityId; + }, + get activityWindowId() { + if (_context._t42) { + return _context._t42.activityWindowId; + } + const info = getWindowInfo(); + if (!info) { + return undefined; + } + return info.activityWindowId; + }, + get windowType() { + return options.windowType || "electron"; + }, + get zoomFactor() { + return _zoomFactor; + }, + get screen() { + if (typeof window !== "undefined" && window.glue42gd) { + return Utils.getMonitor(resultWindow.bounds, window.glue42gd.monitors); + } + return undefined; + }, + get placementSettings() { + return Object.assign({}, _placementSettings); + }, + get jumpList() { + return _jumpList; + }, + get allowWorkspaceDrop() { + return _allowWorkspaceDrop; + }, + get isPinned() { + return _isPinned; + }, + maximize, + restore, + minimize, + maximizeRestore, + collapse, + expand, + toggleCollapse, + focus, + activate, + moveResize, + setTitle, + setStyle, + setOnTop, + resetButtons, + getButtons, + setSizeConstraints, + getSizeConstraints, + navigate, + addFrameButton, + removeFrameButton, + setVisible, + show: () => setVisible(true), + hide: () => setVisible(false), + center, + close, + snap, + showLoader, + hideLoader, + updateContext, + lock, + unlock, + getIcon, + setIcon, + setFrameColor, + setTabTooltip, + getTabTooltip, + attachTab, + detachTab, + setTabHeaderVisible, + showPopup, + createFlydown, + setModalState, + setZoomFactor, + zoomIn, + zoomOut, + showDevTools, + capture, + flash, + flashTab, + setSticky, + setAllowWorkspaceDrop, + pin, + unpin, + print, + printToPDF, + place, + ungroup, + refresh, + goBack, + goForward, + download, + configure, + getConfiguration, + getDockingPlacement, + dock, + clone, + executeCode, + getChannel: async () => { + var _a; + const wins = await getChannels().getWindowsWithChannels({ windowIds: [_id] }); + return (_a = wins[0]) === null || _a === void 0 ? void 0 : _a.channel; + }, + startDrag, + showDialog, + onClose, + onUrlChanged, + onTitleChanged, + onFrameButtonAdded, + onFrameButtonRemoved, + onFrameButtonClicked, + onCollapsed, + onExpanded, + onMinimized, + onMaximized, + onNormal, + onAttached, + onDetached, + onVisibilityChanged, + onContextUpdated, + onLockingChanged, + onBoundsChanged, + onFrameColorChanged, + onFocusChanged, + onStickyChanged, + onGroupChanged, + onWindowAttached, + onWindowDetached, + onTabSelectionChanged, + onTabHeaderVisibilityChanged, + onClosing, + onRefreshing, + onZoomFactorChanged, + onPlacementSettingsChanged, + onNeighboursChanged, + onDockingChanged, + onNavigating, + onChannelRestrictionsChanged, + get tabs() { + return getAllTabs(); + }, + get isTabHeaderVisible() { + return _isTabHeaderVisible; + }, + get isTabSelected() { + return _isTabSelected; + }, + getURL() { + return Promise.resolve(_url); + }, + getTitle() { + return Promise.resolve(_title); + }, + getBounds() { + return Promise.resolve(_bounds); + }, + getContext() { + return Promise.resolve(_context); + }, + setContext(context) { + if (!isObject(context)) { + throw new Error(`"context" must not be null or undefined, set to empty object if you want to clear it out.`); + } + return executor.updateContext(resultWindow, context, true); + }, + getDisplay() { + const displayAPI = displayAPIGetter(); + return displayAPI.getByWindowId(id); + }, + resizeTo(width, height) { + return moveResize({ width, height }); + }, + moveTo(top, left) { + return moveResize({ top, left }); + }, + async getParentWindow() { + var _a; + const myParentId = _settings.parentInstanceId; + if (!myParentId) { + return undefined; + } + return (_a = windowStore.list[myParentId]) === null || _a === void 0 ? void 0 : _a.API; + }, + async getChildWindows() { + return Object.keys(windowStore.list) + .map((key) => windowStore.list[key].API) + .filter((w) => { + const parentId = w.settings.parentInstanceId; + return parentId === id; + }); + }, + joinChannel: (name) => { + return getChannels().join(name, id); + }, + leaveChannel: () => { + return getChannels().leave(id); + } + }; + const events = { + handleUpdate, + handleWindowClose, + handleWindowChangeState, + handleTitleChanged, + handleVisibilityChanged, + handleUrlChanged, + handleWindowSettingsChanged, + handleContextUpdated, + handleFrameIsLockedChanged, + handleBoundsChanged, + handleFocusChanged, + handleFrameButtonAdded, + handleFrameButtonRemoved, + handleFrameButtonClicked, + handleFrameColorChanged, + handleFrameAttached, + handleFrameSelectionChanged, + handleCompositionChanged, + handleAllowWorkspaceDropChanged, + handleIsPinnedChanged, + handleGroupHeaderVisibilityChanged, + handleTabHeaderVisibilityChanged, + handleGroupChanged, + handleAttached, + handleDetached, + handleWindowAttached, + handleWindowDetached, + handleZoomFactorChanged, + handleIsStickyChanged, + handlePlacementSettingsChanged, + handleDockingChanged, + handleChannelRestrictionsChanged + }; + const groupArgs = { + get isGroupHibernated() { + return _isGroupHibernated; + }, + get isGroupVisible() { + return _isGroupVisible; + }, + }; + return { + API: resultWindow, + Events: events, + GroupCreationArgs: groupArgs + }; + }; + + function getWindowsByTabGroupId(windowId, tabGroupId) { + const windows = windowStore.list; + return Object.keys(windows).reduce((memo, id) => { + const win = windows[id]; + if (win.API.tabGroupId === tabGroupId && win.API.id !== windowId) { + memo.push(win); + } + return memo; + }, []); + } + function isEmpty(object) { + if (!object || Object.keys(object).every((value) => object[value] === undefined)) { + return true; + } + return false; + } + + class GDExecutor { + constructor() { + this.GroupMethodName = "T42.Group.Execute"; + this.WndMethodName = "T42.Wnd.Execute"; + this._registry = CallbackRegistryFactory(); + this._finished = Promise.resolve(); + this._configuration = { + windowAvailableOnURLChanged: true + }; + this.unsubCallbacks = {}; + } + get hostInstance() { + return this.agmTarget; + } + get finished() { + return this._finished; + } + get configuration() { + return this._configuration; + } + init(agm, instance) { + this.agm = agm; + this.agmTarget = instance; + this._registry.add("event", (data) => { + if (data.type === "Closed") { + const keys = Object.keys(this.unsubCallbacks); + keys.forEach((key) => { + const isSameWindow = key.startsWith(data.windowId); + if (isSameWindow) { + delete this.unsubCallbacks[key]; + } + }); + } + }); + } + setConfiguration(config) { + this._configuration = { ...this._configuration, ...config }; + } + handleEvent(data) { + this._registry.execute("event", data); + } + async open(options) { + let finishedResolve; + this._finished = new Promise((resolve) => { + finishedResolve = resolve; + }); + try { + const result = await this.agm.invoke("T42.Wnd.Create", options, this.agmTarget, { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_RESPONSE_TIMEOUT_MS + }); + if (result.returned === undefined) { + throw new Error("failed to execute T42.Wnd.Create - unknown reason"); + } + const id = result.returned.id; + const win = await windowStore.waitFor(id); + if (!this.configuration || this.configuration.windowAvailableOnURLChanged) { + setTimeout(() => { + if (win.API.windowType === "electron") { + win.Events.handleUrlChanged(win.API.url); + } + }, 0); + } + return win.API; + } + finally { + finishedResolve(); + } + } + async close(w, options) { + const result = await this.execute("close", { windowId: w.id, options }, `Closed`); + if (options) { + return result.closed; + } + return w; + } + async navigate(w, newUrl, urlLoadOptions) { + let methodResponseTimeoutMs = 120000; + if (typeof urlLoadOptions === "object" && typeof urlLoadOptions.timeout === "number") { + methodResponseTimeoutMs = urlLoadOptions.timeout * 1000; + delete urlLoadOptions.timeout; + } + await this.execute("navigate", { windowId: w.id, options: { url: newUrl, urlLoadOptions }, invocationOptions: { methodResponseTimeoutMs } }, "UrlChanged"); + return w; + } + async setStyle(w, style) { + var _a; + const stylePromises = []; + const wait = (promise) => stylePromises.push(promise); + if (!isUndefinedOrNull(style.focus) && !w.isFocused) { + wait(w.focus()); + } + if (!isUndefinedOrNull(style.hidden)) { + const toBeVisible = !style.hidden; + wait(w.setVisible(toBeVisible)); + } + if (!isUndefinedOrNull(style.onTop)) { + wait(w.setOnTop(style.onTop)); + } + if (!isNullOrWhiteSpace(style.tabTooltip) || !isNullOrWhiteSpace(style.tabToolTip)) { + const toolTip = (_a = style.tabTooltip) !== null && _a !== void 0 ? _a : style.tabToolTip; + wait(w.setTabTooltip(toolTip)); + } + if (!isNullOrWhiteSpace(style.tabTitle)) { + wait(this.execute("setTabTitle", { windowId: w.id, options: { tabTitle: style.tabTitle } })); + } + const constraints = { + minHeight: style.minHeight, + minWidth: style.minWidth, + maxHeight: style.maxHeight, + maxWidth: style.maxWidth, + }; + const hasConstraints = !isEmpty(constraints); + if (hasConstraints) { + wait(w.setSizeConstraints(constraints)); + } + const buttons = { + allowClose: style.allowClose, + allowCollapse: style.allowCollapse, + allowLockUnlock: style.allowLockUnlock, + allowMaximize: style.allowMaximize, + allowMinimize: style.allowMinimize + }; + const hasButtons = !isEmpty(buttons); + if (hasButtons) { + wait(w.resetButtons(buttons)); + } + await Promise.all(stylePromises); + return w; + } + async setSizeConstraints(w, constraints) { + await this.execute("setSizeConstraints", { windowId: w.id, options: constraints }); + return w; + } + async getSizeConstraints(w) { + const sizeConstraint = await this.execute("getSizeConstraints", { windowId: w.id }); + return sizeConstraint; + } + async setTabTooltip(w, tabTooltip) { + await this.execute("setTabTooltip", { windowId: w.id, options: { tabTooltip } }); + return w; + } + async getTabTooltip(w) { + const result = await this.execute("getTabTooltip", { windowId: w.id }); + return result.tabTooltip; + } + async resetButtons(w, buttonsConfig) { + await this.execute("resetButtons", { windowId: w.id, options: buttonsConfig }); + return w; + } + async getButtons(w) { + const buttons = await this.execute("getButtons", { windowId: w.id }); + return buttons; + } + async setOnTop(w, onTop) { + await this.execute("setOnTop", { windowId: w.id, options: { onTop } }); + return w; + } + async setTitle(w, newTitle) { + const options = { + windowId: w.id, + options: { + title: newTitle + } + }; + await this.execute("setTitle", options, "TitleChanged"); + return w; + } + async setSticky(w, isSticky) { + const options = { + windowId: w.id, + options: { + isSticky + } + }; + await this.execute("setSticky", options); + return w; + } + async setAllowWorkspaceDrop(w, allowWorkspaceDrop) { + const options = { + windowId: w.id, + options: { + allowWorkspaceDrop + } + }; + await this.execute("setAllowWorkspaceDrop", options); + return w; + } + async pin(windowToPin) { + const options = { + windowId: windowToPin.id + }; + await this.execute("pinTab", options); + return windowToPin; + } + async unpin(pinnedWindow) { + const options = { + windowId: pinnedWindow.id + }; + await this.execute("unpinTab", options); + return pinnedWindow; + } + async moveResize(w, bounds) { + if (typeof window !== "undefined" && window.glueDesktop.versionNum < 31200) { + return new Promise(async (res, rej) => { + const resolveImmediately = this.areBoundsEqual(bounds, w); + let isDone = false; + const done = () => { + if (isDone) { + return; + } + isDone = true; + if (unsubscribeBoundsChanged) { + unsubscribeBoundsChanged(); + unsubscribeBoundsChanged = undefined; + } + res(w); + if (resolveTimeout) { + clearTimeout(resolveTimeout); + resolveTimeout = undefined; + } + }; + let resolveTimeout; + let unsubscribeBoundsChanged; + if (!resolveImmediately) { + unsubscribeBoundsChanged = w.onBoundsChanged((win) => { + if (!this.areBoundsEqual(bounds, win)) { + return; + } + done(); + }); + } + try { + await this.execute("moveResize", { windowId: w.id, options: { bounds } }); + } + catch (error) { + rej(error); + return; + } + if (resolveImmediately) { + done(); + return; + } + resolveTimeout = setTimeout(() => { + done(); + }, 1000); + }); + } + else { + await this.execute("moveResize", { windowId: w.id, options: { bounds } }); + } + return w; + } + async addFrameButton(w, buttonInfo) { + await this.execute("addButton", { windowId: w.id, options: buttonInfo }, "ButtonAdded"); + return w; + } + async removeFrameButton(w, buttonId) { + await this.execute("removeButton", { windowId: w.id, options: buttonId }, "ButtonRemoved"); + return w; + } + async activate(w) { + await this.execute("activate", { windowId: w.id }); + return w; + } + async focus(w) { + await this.execute("focus", { windowId: w.id }); + return w; + } + async maximizeRestore(w) { + await this.execute("maximizeRestore", { windowId: w.id }, "StateChanged"); + return w; + } + async maximize(w) { + await this.execute("maximize", { windowId: w.id }, "StateChanged"); + return w; + } + async restore(w) { + await this.execute("restore", { windowId: w.id }, "StateChanged"); + return w; + } + async minimize(w) { + await this.execute("minimize", { windowId: w.id }, "StateChanged"); + return w; + } + async collapse(w) { + await this.execute("collapse", { windowId: w.id }, "StateChanged"); + return w; + } + async expand(w) { + await this.execute("expand", { windowId: w.id }, "StateChanged"); + return w; + } + async toggleCollapse(w) { + await this.execute("toggleCollapse", { windowId: w.id }, "StateChanged"); + return w; + } + async snap(w, targetWindow, options) { + const args = { + targetWindowId: targetWindow.id + }; + args.snappingEdge = options.direction; + args.autoAlign = options.autoAlign; + await this.execute("snap", { windowId: w.id, options: args }, "CompositionChanged", `CompositionChanged-${targetWindow.id}`); + return w; + } + async attachTab(w, sourceWindow, options) { + await this.execute("attachTab", { + windowId: w.id, + options: { + index: options, + sourceWindowId: sourceWindow.id, + targetWindowId: w.id, + } + }, `WindowFrameAdded-${sourceWindow.id}`, `WindowFrameRemoved-${sourceWindow.id}`); + return w; + } + async detachTab(w, options) { + const eventKeys = ["WindowFrameRemoved", `WindowFrameAdded`]; + if (!isUndefinedOrNull(options === null || options === void 0 ? void 0 : options.relativeTo)) { + eventKeys.push(`CompositionChanged`); + eventKeys.push(`CompositionChanged-${options.relativeTo}`); + } + else { + eventKeys.push("BoundsChanged"); + } + await this.execute("detachTab", { windowId: w.id, options }, ...eventKeys); + return w; + } + async setVisible(w, toBeVisible = true) { + let command; + if (toBeVisible) { + command = "show"; + } + else { + command = "hide"; + } + await this.execute(command, { windowId: w.id }, "VisibilityChanged"); + return w; + } + async center(w, display) { + await this.execute("center", { windowId: w.id, options: display }); + return w; + } + async showLoader(w, loader) { + await this.execute("showLoadingAnimation", { windowId: w.id, options: loader }); + return w; + } + async hideLoader(w) { + await this.execute("hideLoadingAnimation", { windowId: w.id }); + return w; + } + async updateContext(w, context, replace) { + let un; + try { + const contextWithoutUndefinedValues = this.swapUndefinedToNull(context); + const done = new Promise((resolve, reject) => { + un = w.onContextUpdated(() => { + resolve(); + }); + }); + await Promise.all([this.execute("updateContext", { + windowId: w.id, context: contextWithoutUndefinedValues, replace + }), done]); + return w; + } + finally { + if (un) { + un(); + } + } + } + async lock(w) { + await this.execute("lockUnlock", { windowId: w.id, options: { lock: true } }, "FrameIsLockedChanged"); + return w; + } + async unlock(w) { + await this.execute("lockUnlock", { windowId: w.id, options: { lock: false } }, "FrameIsLockedChanged"); + return w; + } + async getIcon(w) { + const result = await this.execute("getIcon", { + windowId: w.id, + options: {} + }); + return result.icon; + } + async setIcon(w, base64Image) { + await this.execute("setIcon", { + windowId: w.id, + options: { + dataURL: base64Image + } + }); + return w; + } + async setFrameColor(w, frameColor) { + await this.execute("setFrameColor", { windowId: w.id, options: { frameColor } }, "FrameColorChanged"); + return w; + } + async setTabHeaderVisible(w, toBeTabHeaderVisible) { + await this.execute("setTabHeaderVisible", { + windowId: w.id, + options: { + toShow: toBeTabHeaderVisible + } + }, "TabHeaderVisibilityChanged"); + return w; + } + async showGroupPopup(id, options) { + const reformatedOptions = this.showPopupCore(id, options); + await this.executeGroup("showGroupPopup", { + groupId: id, + options: reformatedOptions + }); + } + async showPopup(targetWindow, options) { + const reformatedOptions = this.showPopupCore(targetWindow.id, options); + await this.execute("showPopupWindow", { + windowId: targetWindow.id, + options: reformatedOptions + }); + return targetWindow; + } + async createFlydown(windowId, options) { + if (!options) { + throw new Error("The options object is not valid!"); + } + const optionsCopy = { ...options }; + if (!optionsCopy.horizontalOffset) { + optionsCopy.horizontalOffset = 0; + } + if (!optionsCopy.verticalOffset) { + optionsCopy.verticalOffset = 0; + } + const fullOptions = this.reformatFlydownOptions(windowId, optionsCopy); + return this.execute("setFlydownArea", { windowId, options: fullOptions }).then(() => { + const zoneIds = fullOptions.zones.map((z) => z.id); + fullOptions.zones.forEach((z) => { + let callback = typeof (z.flydownSize) === "function" ? + z.flydownSize : () => z.flydownSize; + if (options.size instanceof Function && z.flydownSize) { + callback = async (data, cancel) => { + let result; + if (options.size instanceof Function) { + result = await options.size(data, cancel); + } + if (z.flydownSize instanceof Function && z.flydownSize !== options.size) { + return await z.flydownSize(data, cancel) || result; + } + return result || z.flydownSize; + }; + } + this._registry.clearKey(`${fullOptions.targetId}_${z.id}`); + this._registry.add(`${fullOptions.targetId}_${z.id}`, callback); + }); + return { + destroy: () => this.clearFlydownArea(fullOptions.targetId, zoneIds), + options: optionsCopy + }; + }); + } + async setModalState(windowId, isModal) { + return this.execute("setModalState", { windowId, options: { isModal } }); + } + async autoArrange(displayId) { + return this.execute("autoArrange", { options: { displayId } }); + } + async handleFlydownBoundsRequested(targetId, data) { + const cancelCallback = () => data.cancel = true; + const callbackData = { + zoneId: data.flydownId, + flydownWindowBounds: data.flydownWindowBounds, + flydownWindowId: data.flydownWindowId, + }; + const responses = await Promise.all(this._registry.execute(`${targetId}_${data.flydownId}`, callbackData, cancelCallback)); + if (responses.length === 1) { + const defaultResponse = { height: 0, width: 0, top: 0, left: 0 }; + const response = typeof (responses[0]) === "object" && !Array.isArray(responses[0]) ? responses[0] : defaultResponse; + const responseOptions = { ...data, flydownWindowBounds: response }; + return responseOptions; + } + } + async handleOnEventRequested(callbackId, args) { + var _a; + const callbacks = (_a = this.unsubCallbacks[callbackId]) !== null && _a !== void 0 ? _a : []; + let prevented = false; + const preventArgs = []; + await Promise.all(callbacks.map((cb) => { + return new Promise((resolve, reject) => { + cb(() => { + resolve(); + }, () => { + reject(); + }, (pArgs) => { + prevented = true; + preventArgs.push(pArgs); + }, args); + }); + })); + return { prevented, preventArgs }; + } + async zoomIn(window) { + await this.execute("zoomIn", { + windowId: window.id, + }); + return window; + } + async zoomOut(window) { + await this.execute("zoomOut", { + windowId: window.id, + }); + return window; + } + async setZoomFactor(window, zoomFactor) { + await this.execute("setZoomFactor", { + windowId: window.id, + options: { + zoomFactor + } + }); + return window; + } + async showDevTools(window) { + await this.execute("showDevTools", { + windowId: window.id, + }); + return window; + } + async capture(window, options) { + const base64screenshot = (await this.execute("captureScreenshot", { windowId: window.id, options: { ...options } })).data; + return base64screenshot; + } + async captureGroup(windowIds, options) { + const base64screenshot = (await this.execute("captureGroupScreenshot", { windowId: windowIds[0], options: { groupWindowIds: windowIds, ...options } })).data; + return base64screenshot; + } + async flash(resultWindow, options) { + await this.execute("flash", { windowId: resultWindow.id, options: { ...options } }); + return resultWindow; + } + async flashTab(resultWindow, options) { + await this.execute("flashTab", { windowId: resultWindow.id, options: { ...options } }); + return resultWindow; + } + async configure(windowId, options) { + return this.execute("configure", { windowId, options: { ...options } }); + } + async print(resultWindow, options) { + await this.execute("print", { windowId: resultWindow.id, options: { ...options } }); + return resultWindow; + } + async printToPDF(resultWindow, options) { + const filePath = (await this.execute("printToPDF", { windowId: resultWindow.id, options: { ...options } })).filePath; + return filePath; + } + async place(window, options) { + const copy = { ...options }; + if (!options.display || options.display === "current") { + copy.display = await window.getDisplay(); + } + if (copy.display && typeof copy.display !== "string" && typeof copy.display !== "number") { + copy.display = copy.display.index + 1; + } + return this.execute("place", { windowId: window.id, options: { ...copy } }); + } + async refresh(resultWindow, ignoreCache) { + await this.execute("refresh", { windowId: resultWindow.id, options: { ignoreCache } }); + return resultWindow; + } + async download(resultWindow, url, options = {}) { + options.enableDownloadBar = !options.silent; + const result = await this.execute("downloadURL", { windowId: resultWindow.id, options: { url, options } }); + return { + url, + path: result.fullPath, + size: result.fileSize, + }; + } + async configureWindow(resultWindow, options) { + await this.execute("configureWindow", { windowId: resultWindow.id, options }); + return resultWindow; + } + async getWindowConfiguration(resultWindow) { + const config = await this.execute("getWindowConfiguration", { windowId: resultWindow.id }); + return config; + } + async startDrag(resultWindow, options) { + await this.execute("startDrag", { windowId: resultWindow.id, options }); + return resultWindow; + } + showDialog(resultWindow, options) { + return new Promise((res, rej) => { + const token = Utils.generateId(); + const un = this._registry.add("event", (args) => { + if (args.type === "DialogResult" && args.windowId === resultWindow.id && args.data.token === token) { + un(); + const data = args.data; + if ("status" in data) { + if (data.status === "failed") { + rej(new Error(data.message)); + } + else if (data.status === "successful") { + res(data.result); + } + } + } + }); + this.execute("showDialog", { windowId: resultWindow.id, options: Object.assign({}, { ...options }, { token }) }); + }); + } + async execute(command, options, ...eventKeys) { + return this.executeCore(this.WndMethodName, command, options, ...eventKeys); + } + async executeGroup(command, options, ...eventKeys) { + return this.executeCore(this.GroupMethodName, command, options, ...eventKeys); + } + async ungroup(w, options) { + const args = { + windowId: w.id, + options + }; + await this.execute("ungroup", args); + return w; + } + async updateJumpList(windowId, options) { + const args = { + windowId, + options + }; + await this.execute("updateJumplist", args); + } + async getJumpList(windowId) { + const args = { + windowId, + }; + const result = await this.execute("getJumplist", args); + return result; + } + onClosing(callback, gdWindow) { + const glue42gd = typeof window !== "undefined" && window.glue42gd; + if (glue42gd && gdWindow.windowType === "electron") { + return glue42gd.addCloseHandler(callback, gdWindow.id); + } + else { + return this.nonWindowHandlers(callback, gdWindow.id, "OnClosing"); + } + } + onGroupClosing(callback, group) { + return this.nonWindowHandlersCore(group.id, "OnClosing", true, callback); + } + onRefreshing(callback, gdWindow) { + const glue42gd = typeof window !== "undefined" && window.glue42gd; + if (glue42gd && gdWindow.windowType === "electron") { + return glue42gd.addRefreshHandler(callback, gdWindow.id); + } + else { + return this.nonWindowHandlers(callback, gdWindow.id, "OnRefreshing"); + } + } + onNavigating(callback, gdWindow) { + const glue42gd = typeof window !== "undefined" && window.glue42gd; + if (glue42gd && gdWindow.windowType === "electron") { + return glue42gd.addWillNavigateHandler(callback, gdWindow.id); + } + else { + return this.nonWindowHandlers(callback, gdWindow.id, "OnNavigating"); + } + } + async clone(window, cloneOptions) { + const args = { + windowId: window.id, + options: cloneOptions + }; + const result = await this.execute("clone", args); + const win = await windowStore.waitFor(result.id); + return win.API; + } + async executeCode(targetWindow, code) { + const args = { + windowId: targetWindow.id, + options: { + code + } + }; + return this.execute("executeCode", args); + } + async goBack(resultWindow) { + await this.execute("goBack", { windowId: resultWindow.id }); + } + async goForward(resultWindow) { + await this.execute("goForward", { windowId: resultWindow.id }); + } + async getDockingPlacement(window) { + return this.execute("getDockingPlacement", { windowId: window.id }); + } + dock(window, options) { + return this.execute("dock", { windowId: window.id, options }); + } + clearCallbacks(id) { + const keys = Object.keys(this.unsubCallbacks); + keys.forEach((key) => { + if (key.startsWith(id)) { + delete this.unsubCallbacks[key]; + } + }); + } + nonWindowHandlers(callback, targetId, type) { + return this.nonWindowHandlersCore(targetId, type, false, callback); + } + nonWindowHandlersCore(targetId, type, isGroup, callback) { + const id = `${targetId}-${type}`; + const unsub = () => { + var _a; + if (this.unsubCallbacks[id]) { + const callbacks = this.unsubCallbacks[id]; + this.unsubCallbacks[id] = callbacks.filter((cb) => cb !== callback); + if (this.unsubCallbacks[id].length === 0) { + delete this.unsubCallbacks[id]; + } + } + const cbs = (_a = this.unsubCallbacks[id]) !== null && _a !== void 0 ? _a : []; + if (cbs.length === 0) { + const options = { + unsubscribe: true + }; + if (isGroup) { + this.executeGroup(type, { + groupId: targetId, + options + }); + } + else { + this.execute(type, { + windowId: targetId, + options + }); + } + } + }; + if (this.unsubCallbacks[id]) { + this.unsubCallbacks[id].push(callback); + return unsub; + } + else { + this.unsubCallbacks[id] = [callback]; + } + if (isGroup) { + this.executeGroup(type, { groupId: targetId }); + } + else { + this.execute(type, { windowId: targetId }); + } + return unsub; + } + reformatFlydownOptions(windowId, options) { + const assignGeneralIfUnassigned = (zone, prop) => { + if (options[prop] && (zone[prop] === undefined || zone[prop] === null)) { + const valueFromOptions = options[prop]; + zone[prop] = valueFromOptions; + } + }; + const zones = options.zones.map((z) => { + assignGeneralIfUnassigned(z, "windowId"); + assignGeneralIfUnassigned(z, "targetLocation"); + if (options.size && (z.flydownSize === undefined || z.flydownSize === null)) { + z.flydownSize = options.size; + } + z.flydownBounds = z.flydownSize; + z.flydownId = z.windowId; + if (!z.targetLocation) { + z.targetLocation = "bottom"; + } + return z; + }); + return { + ...options, + zones, + targetId: windowId, + flydownBounds: options.size, + flydownActiveArea: options.activeArea + }; + } + clearFlydownArea(windowId, areaIds) { + return this.execute("clearFlydownWindowArea", { + windowId, + options: {} + }).then(() => { + areaIds.forEach((id) => { + this._registry.clearKey(`${windowId}_${id}`); + }); + }); + } + executeWithoutToken(params, ...eventKeys) { + const uns = []; + const executed = eventKeys === null || eventKeys === void 0 ? void 0 : eventKeys.filter((k) => !isUndefinedOrNull(k)).map((key) => { + return new Promise((r) => { + const [type, windowId = params.windowId] = key.split("-"); + uns.push(this._registry.add("event", (data) => { + if (data.type === type && data.windowId === windowId) { + r(); + } + })); + }); + }); + const action = new Promise((resolve, reject) => { + this.agm.invoke("T42.Wnd.Execute", params, this.agmTarget, { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_RESPONSE_TIMEOUT_MS + }) + .then((i) => { + if (i.returned && i.returned.errorMsg) { + reject(i); + } + else { + resolve(i.returned); + } + }) + .catch((e) => reject(e)); + }); + return Promise.all([action, ...executed]) + .then((r) => { + return r[0]; + }) + .finally(() => { + uns.forEach((un) => un()); + }); + } + async executeCore(methodName, command, options, ...eventKeys) { + const { invocationOptions, ...invocationArgs } = options; + const params = { + ...invocationArgs, + command, + }; + let finishedResolve; + this._finished = new Promise((resolve) => { + finishedResolve = resolve; + }); + try { + if (typeof window !== "undefined" && window.glueDesktop.versionNum < 31200) { + return await this.executeWithoutToken(params, ...eventKeys); + } + else { + return await this.executeWithToken(methodName, params, invocationOptions); + } + } + finally { + finishedResolve(); + } + } + async executeWithToken(methodName, options, invocationOptions) { + let un; + try { + const token = Utils.generateId(); + const event = new Promise((r) => { + un = this._registry.add("event", (data) => { + if (data.token === token) { + r(); + } + }); + }); + const execute = new Promise((resolve, reject) => { + options.token = token; + if (!invocationOptions) { + invocationOptions = { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_RESPONSE_TIMEOUT_MS + }; + } + else if (!invocationOptions.methodResponseTimeoutMs) { + invocationOptions.methodResponseTimeoutMs = INTEROP_METHOD_RESPONSE_TIMEOUT_MS; + } + else if (!invocationOptions.waitTimeoutMs) { + invocationOptions.waitTimeoutMs = INTEROP_METHOD_WAIT_TIMEOUT_MS; + } + this.agm.invoke(methodName, options, this.agmTarget, invocationOptions) + .then((i) => { + if (i.returned && i.returned.errorMsg) { + reject(new Error(i.returned.errorMsg)); + } + else { + resolve(i.returned); + } + }) + .catch((e) => { + const error = Utils.typedError(e); + reject(error); + }); + }); + const result = await Promise.all([execute, event]); + return result[0]; + } + finally { + if (un) { + un(); + } + } + } + areBoundsEqual(requested, w) { + const current = w.bounds; + const settings = w.settings; + let height = requested.height; + let width = requested.width; + if (requested.height < settings.minHeight) { + height = settings.minHeight; + } + if (requested.height > settings.maxHeight) { + height = settings.maxHeight; + } + if (requested.width < settings.minWidth) { + width = settings.minWidth; + } + if (requested.width > settings.maxWidth) { + width = settings.maxWidth; + } + const areHeightsEqual = height ? current.height === height : true; + const areWidthsEqual = width ? current.width === width : true; + const areLeftsEqual = requested.left ? current.left === requested.left : true; + const areTopsEqual = requested.top ? current.top === requested.top : true; + return areHeightsEqual && areWidthsEqual && areLeftsEqual && areTopsEqual; + } + swapUndefinedToNull(context) { + try { + const copy = {}; + for (const key of Object.keys(context)) { + let value = context[key]; + if (typeof value === "undefined") { + value = null; + } + copy[key] = value; + } + return copy; + } + catch { + return context; + } + } + showPopupCore(id, options) { + if (!options) { + throw new Error("The options object is not valid!"); + } + const optionsCopy = { ...options }; + if (!optionsCopy.targetLocation) { + optionsCopy.targetLocation = "bottom"; + } + const reformatedOptions = { + ...optionsCopy, + popupBounds: optionsCopy.size, + targetId: id, + popupId: optionsCopy.windowId + }; + return reformatedOptions; + } + } + var executor = new GDExecutor(); + + class GDEnvironment { + constructor(agm, logger, appManagerGetter, displayAPIGetter, channelsAPIGetter, wndId, groupId) { + this._registry = CallbackRegistryFactory(); + this._agm = agm; + this._logger = logger.subLogger("gd-env"); + this._windowId = wndId; + this._groupId = groupId; + this._appManagerGetter = appManagerGetter; + this._displayAPIGetter = displayAPIGetter; + this._channelsAPIGetter = channelsAPIGetter; + } + init() { + return new Promise((resolve, reject) => { + this._agm.register("T42.Wnd.OnEventWithResponse", (args, caller) => { + return this.respondToEvent(args); + }); + new Promise((streamResolve, streamReject) => { + this._agm.subscribe("T42.Wnd.OnEvent", { + target: "best", + arguments: { + withConfig: true + }, + onData: (streamData) => { + if (streamData.data.type === "Configuration") { + this._configuration = streamData.data; + executor.setConfiguration(this._configuration); + return; + } + this.updateWindow(streamData.data, resolve); + executor.handleEvent(streamData.data); + }, + onConnected: (instance) => { + this._agmInstance = instance; + executor.init(this._agm, this._agmInstance); + } + }).catch((error) => { + var _a; + const message = `${(_a = error === null || error === void 0 ? void 0 : error.method) === null || _a === void 0 ? void 0 : _a.name} - ${JSON.stringify(error === null || error === void 0 ? void 0 : error.called_with)} - ${error === null || error === void 0 ? void 0 : error.message}`; + reject(new Error(message)); + }); + }); + }); + } + get executor() { + return executor; + } + open(name, url, options) { + options = options || {}; + const copyOptions = { ...options }; + if (copyOptions.relativeTo !== undefined && typeof copyOptions.relativeTo !== "string") { + copyOptions.relativeTo = copyOptions.relativeTo.id || ""; + } + copyOptions.name = name; + copyOptions.url = url; + copyOptions.windowState = options.windowState || options.state; + delete copyOptions.state; + return this.executor.open(copyOptions); + } + createFlydown(windowId, options) { + return this.executor.createFlydown(windowId, options); + } + async showPopup(windowId, options) { + const window = windowStore.get(windowId); + await this.executor.showPopup(window.API, options); + } + tabAttached(callback) { + return this._registry.add("tab-attached", callback); + } + tabDetached(callback) { + return this._registry.add("tab-detached", callback); + } + onWindowFrameColorChanged(callback) { + return this._registry.add("frame-color-changed", callback); + } + onEvent(callback) { + return this._registry.add("window-event", callback); + } + my() { + return this._windowId; + } + myGroup() { + return this._groupId; + } + onCompositionChanged(callback) { + return this._registry.add("composition-changed", callback); + } + onGroupHeaderVisibilityChanged(callback) { + return this._registry.add("group-header-changed", callback); + } + onGroupVisibilityChanged(callback) { + return this._registry.add("group-visibility-changed", callback); + } + onGroupStateChanged(callback) { + return this._registry.add("group-state-changed", callback); + } + onWindowGotFocus(callback) { + return this._registry.add("got-focus", callback); + } + onWindowLostFocus(callback) { + return this._registry.add("lost-focus", callback); + } + onWindowsAutoArrangeChanged(callback) { + return this._registry.add("windows-auto-arranged-changed", callback); + } + respondToEvent(args) { + if (args.type === "ShowFlydownBoundsRequested") { + return this.executor.handleFlydownBoundsRequested(args.data.windowId, args.data); + } + else if (args.type === "OnClosing" || args.type === "OnRefreshing" || args.type === "OnNavigating") { + return this.executor.handleOnEventRequested(args.data.callbackId, args.data.args); + } + return Promise.reject(`There isn't a handler for ${args.type}`); + } + updateWindow(windowInfo, readyResolve) { + const extendedStreamEvent = this.getExtendedStreamEvent(windowInfo); + if (windowInfo.type === "Snapshot") { + const windowInfoFullInfoEvent = windowInfo; + windowInfoFullInfoEvent.windows.forEach((w) => { + const existingWindow = windowStore.get(w.id); + if (existingWindow) { + existingWindow.Events.handleUpdate(this.mapToWindowConstructorOptions(w)); + existingWindow.GroupCreationArgs = this.mapToGroupCreationArgs(w); + } + else { + this.createWindowFromSnapshot(w.id, w); + } + this._registry.execute("window-event", extendedStreamEvent); + }); + readyResolve(this); + return; + } + if (windowInfo.type === "CommandExecuted") { + this._registry.execute("window-event", extendedStreamEvent); + return; + } + if (windowInfo.type === "Created") { + const windowInfoCreatedEvent = (windowInfo); + this.createWindowFromStream(windowInfoCreatedEvent.windowId, windowInfoCreatedEvent.data || {}); + this._registry.execute("window-event", extendedStreamEvent); + return; + } + if (windowInfo.type === "OnGroupVisibilityChanged") { + const info = windowInfo; + this._registry.execute("group-visibility-changed", info.data); + this._registry.execute("window-event", windowInfo); + return; + } + if (windowInfo.type === "OnGroupStateChanged") { + const info = windowInfo; + this._registry.execute("group-state-changed", info.data); + this._registry.execute("window-event", windowInfo); + return; + } + if (windowInfo.type === "OnWindowsAutoArrangeChanged") { + const info = windowInfo; + this._registry.execute("windows-auto-arranged-changed", info.data); + this._registry.execute("window-event", windowInfo); + return; + } + const windowObjectAndEvents = windowStore.get((windowInfo).windowId); + if (!windowObjectAndEvents) { + this._logger.error(`received update for unknown window. Stream:', ${JSON.stringify(windowInfo, null, 4)}`); + return; + } + const theWindow = windowObjectAndEvents.API; + const theWindowEvents = windowObjectAndEvents.Events; + if (windowInfo.type === "BoundsChanged") { + const windowInfoBoundsChangedEvent = windowInfo; + theWindowEvents.handleBoundsChanged(windowInfoBoundsChangedEvent.data); + } + if (windowInfo.type === "UrlChanged") { + const windowInfoUrlChangedEvent = windowInfo; + windowStore.setUrlChangedState(windowInfoUrlChangedEvent.windowId); + theWindowEvents.handleUrlChanged(windowInfoUrlChangedEvent.data); + } + if (windowInfo.type === "TitleChanged") { + const windowInfoTitleChanged = windowInfo; + theWindowEvents.handleTitleChanged(windowInfoTitleChanged.data); + } + if (windowInfo.type === "IsStickyChanged") { + const windowInfoIsStickyChangedChanged = windowInfo; + theWindowEvents.handleIsStickyChanged(windowInfoIsStickyChangedChanged.data); + } + if (windowInfo.type === "VisibilityChanged") { + theWindowEvents.handleVisibilityChanged(windowInfo.data); + } + if (windowInfo.type === "ContextChanged") { + theWindowEvents.handleContextUpdated(windowInfo.data); + } + if (windowInfo.type === "StateChanged") { + theWindowEvents.handleWindowChangeState(windowInfo.data); + } + if (windowInfo.type === "FrameColorChanged") { + theWindowEvents.handleFrameColorChanged(windowInfo.data); + this._registry.execute("frame-color-changed", theWindow); + } + if (windowInfo.type === "CompositionChanged") { + const windowInfoCompositionChanged = windowInfo; + theWindowEvents.handleCompositionChanged(windowInfoCompositionChanged.data); + windowStore.setCompositionChangedState(windowObjectAndEvents); + this._registry.execute("composition-changed", windowInfoCompositionChanged.data); + } + if (windowInfo.type === "GroupHeaderVisibilityChanged") { + const info = windowInfo; + theWindowEvents.handleGroupHeaderVisibilityChanged(info.data.groupHeaderVisible); + this._registry.execute("group-header-changed", info.data); + } + if (windowInfo.type === "FocusChanged") { + const windowInfoFocusChanged = windowInfo; + this.focusChanged(theWindowEvents, theWindow, windowInfoFocusChanged.data); + } + if (windowInfo.type === "WindowFrameChanged") { + theWindowEvents.handleFrameAttached(windowInfo.data.frameId, windowInfo.data.frameId, windowInfo.data.isTabHeaderVisible); + this._registry.execute("frame-changed"); + } + if (windowInfo.type === "WindowFrameAdded") { + const winsToBeNotified = getWindowsByTabGroupId(theWindow.id, windowInfo.data.frameId); + const data = windowInfo.data; + theWindowEvents.handleAttached(data.frameId, data.frameId, data.isTabHeaderVisible, data.isLocked, winsToBeNotified) + .then(async () => { + if (winsToBeNotified.length > 0) { + await executor.finished; + this._registry.execute("tab-attached", theWindow, windowInfo.data.frameId, windowInfo.data.isTabHeaderVisible); + } + }); + } + if (windowInfo.type === "WindowFrameRemoved") { + const oldTabGroupId = theWindow.tabGroupId; + const winsToBeNotified = getWindowsByTabGroupId(theWindow.id, oldTabGroupId); + theWindowEvents.handleDetached(windowInfo.data.isLocked, winsToBeNotified) + .then(async () => { + if (winsToBeNotified.length > 0) { + await executor.finished; + this._registry.execute("tab-detached", theWindow, windowInfo.data.frameId, theWindow.tabGroupId); + } + }); + } + if (windowInfo.type === "TabHeaderVisibilityChanged") { + theWindowEvents.handleTabHeaderVisibilityChanged(windowInfo.data.isTabHeaderVisible); + } + if (windowInfo.type === "FrameSelectionChanged") { + theWindowEvents.handleFrameSelectionChanged(windowInfo.data.newWindowId, windowInfo.data.prevWindowId); + } + if (windowInfo.type === "ButtonClicked") { + theWindowEvents.handleFrameButtonClicked(windowInfo.data); + } + if (windowInfo.type === "ButtonAdded") { + theWindowEvents.handleFrameButtonAdded(windowInfo.data); + } + if (windowInfo.type === "ButtonRemoved") { + theWindowEvents.handleFrameButtonRemoved(windowInfo.data); + } + if (windowInfo.type === "WindowZoomFactorChanged") { + theWindowEvents.handleZoomFactorChanged(windowInfo.data); + } + if (windowInfo.type === "Closed") { + windowStore.remove(windowObjectAndEvents); + theWindowEvents.handleWindowClose(); + } + if (windowInfo.type === "FrameIsLockedChanged") { + theWindowEvents.handleFrameIsLockedChanged(windowInfo.data); + } + if (windowInfo.type === "PlacementSettingsChanged") { + theWindowEvents.handlePlacementSettingsChanged(windowInfo.data); + } + if (windowInfo.type === "DockingChanged") { + theWindowEvents.handleDockingChanged(windowInfo.data); + } + if (windowInfo.type === "AllowWorkspaceDropChanged") { + theWindowEvents.handleAllowWorkspaceDropChanged(windowInfo.data); + } + if (windowInfo.type === "IsPinnedChanged") { + theWindowEvents.handleIsPinnedChanged(windowInfo.data); + } + if (windowInfo.type === "WindowChannelRestrictionsChanged") { + theWindowEvents.handleChannelRestrictionsChanged(windowInfo.data); + } + this._registry.execute("window-event", extendedStreamEvent); + } + createWindowFromSnapshot(windowId, options) { + const windowObjAndEvents = this.createWindowCore(windowId, options); + windowStore.add(windowObjAndEvents, { + ready: true, + urlChanged: true, + compositionChanged: true + }); + } + createWindowFromStream(windowId, options) { + var _a; + const windowObjAndEvents = this.createWindowCore(windowId, options); + const isRemote = windowObjAndEvents.API.windowType === "remote"; + const isFrameless = windowObjAndEvents.API.windowType === "electron" && windowObjAndEvents.API.mode === "frameless"; + const isHidden = windowObjAndEvents.API.isVisible === false; + let urlChanged = false; + let compositionChanged = false; + if (isRemote) { + urlChanged = true; + } + if (isFrameless || isHidden) { + compositionChanged = true; + } + if (!isRemote) { + urlChanged = !((_a = this._configuration) === null || _a === void 0 ? void 0 : _a.windowAvailableOnURLChanged); + } + windowStore.add(windowObjAndEvents, { + ready: true, + urlChanged, + compositionChanged + }); + } + createWindowCore(windowId, options) { + const windowObjAndEvents = windowFactory(windowId, this.mapToWindowConstructorOptions(options), executor, this._logger, this._appManagerGetter, this._displayAPIGetter, this._channelsAPIGetter, this._agm); + windowObjAndEvents.GroupCreationArgs = this.mapToGroupCreationArgs(options); + return windowObjAndEvents; + } + async focusChanged(theWindowEvents, theWindow, focus) { + theWindowEvents.handleFocusChanged(focus); + try { + if (!this._configuration.windowAvailableOnURLChanged) { + await windowStore.waitFor(theWindow.id); + } + } + catch (error) { + return; + } + if (focus) { + this._registry.execute("got-focus", theWindow); + } + else { + this._registry.execute("lost-focus", theWindow); + } + } + mapToWindowConstructorOptions(args) { + return { + name: args.name, + context: args.context, + bounds: args.bounds, + url: args.url, + title: args.title, + isVisible: args.isVisible, + focus: args.isFocused, + state: args.state, + frameColor: args.frameColor, + groupId: args.groupId, + neighbours: args.neighbors, + isFocused: args.isFocused, + isGroupHeaderVisible: args.groupHeaderVisible, + isCollapsed: args.isCollapsed, + tabGroupId: args.frameId, + frameId: args.frameId, + mode: args.mode, + isTabHeaderVisible: args.isTabHeaderVisible, + isTabSelected: args.isActiveTab, + settings: args.settings, + windowType: args.windowType, + zoomFactor: args.zoomFactor, + isLocked: args.isLocked, + placementSettings: args.placementSettings, + isSticky: args.isSticky, + tabIndex: args.tabIndex, + frameButtons: args.frameButtons, + jumpListOptions: args.jumpList, + applicationName: args.applicationName, + allowWorkspaceDrop: args.allowWorkspaceDrop, + isPinned: args.isPinned + }; + } + mapToGroupCreationArgs(args) { + return { + isGroupHibernated: args.isGroupHibernated, + isGroupVisible: args.isGroupVisible + }; + } + getExtendedStreamEvent(streamEvent) { + try { + if (!streamEvent.windowId) { + return streamEvent; + } + const window = windowStore.get(streamEvent.windowId); + if (!window) { + return streamEvent; + } + const result = { + state: streamEvent.type, + windowName: window.API.name, + ...streamEvent + }; + if (result.state === "WindowFrameAdded") { + result.state = "TabAttached"; + } + if (result.state === "StateChanged") { + result.state = result.data.charAt(0).toUpperCase() + result.data.slice(1); + } + if (result.state === "ButtonAdded") { + result.state = "FrameButtonAdded"; + } + if (result.state === "ButtonRemoved") { + result.state = "FrameButtonRemoved"; + } + return result; + } + catch (error) { + return streamEvent; + } + } + } + + var envDetector = (agm, logger, appManagerGetter, displayAPIGetter, channelsAPIGetter, gdMajorVersion) => { + var _a; + const _logger = logger; + if (gdMajorVersion === 2) { + _logger.trace("running in HC"); + throw new Error("GD2 not supported"); + } + else if (gdMajorVersion >= 3) { + _logger.trace("running in GD 3"); + return new GDEnvironment(agm, _logger, appManagerGetter, displayAPIGetter, channelsAPIGetter, window.glue42gd.windowId, (_a = window.webGroupsManager) === null || _a === void 0 ? void 0 : _a.id).init(); + } + else { + _logger.trace("running in Browser or Node"); + return new GDEnvironment(agm, _logger, appManagerGetter, displayAPIGetter, channelsAPIGetter).init(); + } + }; + + var groupFactory = (id, executor) => { + const _registry = CallbackRegistryFactory(); + const _windowsId = []; + let _isHibernatedFlag; + let _isVisible; + async function addWindow(winId) { + var _a, _b, _c, _d; + if (_windowsId.indexOf(winId) === -1) { + _windowsId.push(winId); + const win = windowStore.get(winId); + win.Events.handleGroupChanged(groupObject, undefined); + _isHibernatedFlag = (_b = (_a = win.GroupCreationArgs.isGroupHibernated) !== null && _a !== void 0 ? _a : _isHibernatedFlag) !== null && _b !== void 0 ? _b : false; + _isVisible = (_d = (_c = win.GroupCreationArgs.isGroupVisible) !== null && _c !== void 0 ? _c : _isVisible) !== null && _d !== void 0 ? _d : true; + await executor.finished; + _registry.execute("window-added", groupObject, win.API); + } + } + async function removeWindow(win) { + const index = _windowsId.indexOf(win.API.id); + if (index !== -1) { + _windowsId.splice(index, 1); + win.Events.handleGroupChanged(undefined, groupObject); + await executor.finished; + _registry.execute("window-removed", groupObject, win.API); + } + } + function find(window, success, error) { + let winId; + if (typeof window === "string") { + winId = window; + } + else if (!isUndefinedOrNull(window)) { + winId = window.id; + } + const win = _mapToWindowObject(winId); + if (win) { + if (typeof success === "function") { + success(win); + } + return win; + } + else { + if (typeof error === "function") { + error(`No window with ID: ${winId}`); + } + } + } + function windows(success) { + const mappedWindows = _mapToWindowObjects(); + return mappedWindows; + } + async function execute(command, options, ...keys) { + await executor.execute(command, options, ...keys); + return groupObject; + } + function handleGroupHeaderVisibilityChanged(windowInfo) { + _registry.execute("header-visibility-changed", groupObject); + } + function handleGroupVisibilityChanged(visibile) { + _isVisible = visibile; + _registry.execute("group-visibility-changed", groupObject); + } + function handleGroupHibernateChanged(isHibernatedFlag) { + _isHibernatedFlag = isHibernatedFlag; + } + function _mapToWindowObjects() { + const winObjects = []; + _windowsId.forEach((winId) => { + const windowObject = _mapToWindowObject(winId); + if (typeof windowObject !== "undefined") { + winObjects.push(windowObject); + } + }); + return winObjects; + } + function _mapToWindowObject(windowId) { + return windowStore.get(windowId) ? windowStore.get(windowId).API : undefined; + } + function _getGroupHeaderVisibility() { + const windowWithHiddenHeader = _mapToWindowObjects().find((w) => !w.isGroupHeaderVisible); + const _isGroupHeaderVisible = windowWithHiddenHeader === undefined; + return _isGroupHeaderVisible; + } + function isHibernated() { + return _isHibernatedFlag; + } + function onHeaderVisibilityChanged(callback) { + return _registry.add("header-visibility-changed", callback); + } + function onWindowAdded(callback) { + return _registry.add("window-added", callback); + } + function onWindowRemoved(callback) { + return _registry.add("window-removed", callback); + } + function onVisibilityChanged(callback) { + if (!callback) { + throw new Error("Callback argument is required"); + } + if (callback && typeof callback !== "function") { + throw new Error("Callback argument must be a function"); + } + return _registry.add("group-visibility-changed", callback); + } + function onClosing(callback) { + if (typeof callback !== "function") { + throw new Error("callback must be a function"); + } + const callbackWrap = (success, error, prevent) => { + const promise = callback(prevent); + if (promise === null || promise === void 0 ? void 0 : promise.then) { + promise.then(success).catch(error); + } + else { + success(); + } + }; + return executor.onGroupClosing(callbackWrap, groupObject); + } + const groupObject = { + id, + get windows() { + return windows(); + }, + find, + get isHeaderVisible() { + return _getGroupHeaderVisibility(); + }, + get isHibernated() { + return isHibernated(); + }, + get isVisible() { + return _isVisible; + }, + showHeader: (success, error) => { + return Utils.callbackifyPromise(() => { + return execute("setGroupHeaderVisibility", { windowId: _windowsId[0], options: { toShow: true } }, ..._windowsId.map((w) => `GroupHeaderVisibilityChanged-${w}`)); + }, success, error); + }, + hideHeader: (success, error) => { + return Utils.callbackifyPromise(() => { + return execute("setGroupHeaderVisibility", { windowId: _windowsId[0], options: { toShow: false } }, ..._windowsId.map((w) => `GroupHeaderVisibilityChanged-${w}`)); + }, success, error); + }, + getTitle: async () => { + const r = await executor.execute("getGroupTitle", { windowId: _windowsId[0] }); + return r.title; + }, + setTitle: async (title) => { + if (isNullOrWhiteSpace(title)) { + throw new Error("`title` must not be null or undefined."); + } + return execute("setGroupTitle", { windowId: _windowsId[0], options: { title } }); + }, + capture: (captureOptions) => { + return executor.captureGroup(_windowsId, captureOptions); + }, + maximize: (success, error) => { + return Utils.callbackifyPromise(() => { + return execute("maximizeGroup", { windowId: _windowsId[0] }, ..._windowsId.map((w) => `StateChanged-${w}`)); + }, success, error); + }, + restore: (success, error) => { + return Utils.callbackifyPromise(() => { + return execute("restoreGroup", { windowId: _windowsId[0] }, ..._windowsId.map((w) => `StateChanged-${w}`)); + }, success, error); + }, + show: (activate) => { + if (!isUndefinedOrNull(activate) && !isBoolean(activate)) { + throw new Error("Activate flag must be a boolean!"); + } + activate = !isUndefinedOrNull(activate) ? activate : true; + return executor.executeGroup("showGroup", { + groupId: id, + options: { activate } + }); + }, + hide: () => { + return executor.executeGroup("hideGroup", { + groupId: id + }); + }, + close: () => { + return executor.executeGroup("closeGroup", { + groupId: id + }); + }, + showPopup: (options) => { + return executor.showGroupPopup(id, options); + }, + onHeaderVisibilityChanged, + onWindowAdded, + onWindowRemoved, + onVisibilityChanged, + onClosing, + }; + const internal = { + get windows() { + return _windowsId; + }, + addWindow, + removeWindow, + handleGroupHeaderVisibilityChanged, + handleGroupVisibilityChanged, + handleGroupHibernateChanged + }; + return { + groupAPI: groupObject, + groupInternal: internal, + }; + }; + + var groupsFactory = (environment, logger) => { + const _registry = CallbackRegistryFactory(); + const _groups = {}; + let heardForWindowsCounter = -1; + const windows = windowStore.list; + Object.keys(windows).forEach((k) => { + const win = windows[k]; + const groupId = win.API.groupId; + const winId = win.API.id; + if (!isNullOrWhiteSpace(groupId)) { + addWindow(groupId, winId); + } + }); + windowStore.onRemoved((w) => { + const group = findGroupWrapperByWindow(w.API); + removeWindow(group, w); + }); + environment.onCompositionChanged((windowInfo) => { + handleCompositionChanged(windowInfo); + }); + environment.onGroupHeaderVisibilityChanged((windowInfo) => { + const windowId = windowInfo.windowId; + const group = findGroupByWindow(windowId); + if (typeof group !== "undefined") { + const groupEvents = _groups[group.id]; + if (heardForWindowsCounter === -1) { + heardForWindowsCounter = group.windows.length; + } + heardForWindowsCounter--; + if (heardForWindowsCounter === 0) { + heardForWindowsCounter = -1; + groupEvents.groupInternal.handleGroupHeaderVisibilityChanged(windowInfo); + } + } + }); + environment.onGroupVisibilityChanged((data) => { + const groupEvents = _groups[data.groupId]; + if (groupEvents) { + groupEvents.groupInternal.handleGroupVisibilityChanged(data.visible); + } + }); + environment.onGroupStateChanged((data) => { + const groupWrapper = _groups[data.groupId]; + if (data.state === "hibernated") { + if (groupWrapper === null || groupWrapper === void 0 ? void 0 : groupWrapper.groupAPI) { + groupWrapper.groupInternal.handleGroupHibernateChanged(true); + } + _registry.execute("group-hibernated", data.groupId); + } + else if (data.state === "resumed") { + if (groupWrapper === null || groupWrapper === void 0 ? void 0 : groupWrapper.groupAPI) { + groupWrapper.groupInternal.handleGroupHibernateChanged(false); + } + _registry.execute("group-resumed", groupWrapper.groupAPI); + } + }); + function my() { + var _a; + return findGroupByWindow((_a = environment.myGroup()) !== null && _a !== void 0 ? _a : environment.my()); + } + async function create(options) { + if (isUndefinedOrNull(options)) { + throw new Error(`options must be defined`); + } + if (isUndefinedOrNull(options.groups) || !Array.isArray(options.groups) || options.groups.length === 0) { + throw new Error(`options.groups must be defined`); + } + const { groupIds } = await executor.executeGroup("createGroups", { + options + }); + const groups = groupIds.map((groupId) => { + return waitForGroup(groupId); + }); + return Promise.all(groups); + } + async function close(idOrGroup, options) { + if (isUndefinedOrNull(idOrGroup)) { + throw new Error(`group must be defined`); + } + let groupId = ""; + if (typeof idOrGroup === "string") { + groupId = idOrGroup; + } + else { + groupId = idOrGroup.id; + } + if (isUndefinedOrNull(options)) { + throw new Error(`options must be defined`); + } + await executor.executeGroup("closeGroup", { + groupId, + options + }); + } + function list(success) { + const result = Object.keys(_groups).map((groupId) => { + if (_groups[groupId]) { + return _groups[groupId].groupAPI; + } + }); + if (typeof success === "function") { + success(result); + } + return result; + } + function findGroupByWindow(winId, success, error) { + let windowId; + if (typeof winId === "string") { + windowId = winId; + } + else if (!isUndefinedOrNull(winId)) { + windowId = winId.id; + } + const result = Object.values(_groups).find((groupObj) => { + const group = groupObj.groupAPI; + const wins = group.windows.filter((w) => w.id === windowId); + return wins.length; + }); + if (result) { + if (typeof success === "function") { + success(result.groupAPI); + } + return result.groupAPI; + } + else if (typeof error === "function") { + error(`Cannot find the group of the window.`); + } + } + function waitForGroup(groupId) { + if (!groupId) { + return Promise.reject(new Error(`groupId must be defined`)); + } + return new Promise((res, rej) => { + const groupWrapper = _groups[groupId]; + if (groupWrapper) { + res(groupWrapper.groupAPI); + } + else { + const un = onGroupAdded((group) => { + if (group.id === groupId) { + un(); + res(group); + } + }); + } + }); + } + function getMyGroup() { + var _a; + return waitForGroup((_a = environment.myGroup()) !== null && _a !== void 0 ? _a : environment.my()); + } + async function resume(groupId, activate) { + validateGroupIdArg(groupId); + if (!isUndefinedOrNull(activate) && !isBoolean(activate)) { + throw new Error("Activate flag must be a boolean!"); + } + activate = !isUndefinedOrNull(activate) ? activate : true; + await executor.executeGroup("resumeGroup", { + groupId, + options: { activate } + }); + } + async function hibernate(groupId) { + validateGroupIdArg(groupId); + await executor.executeGroup("hibernateGroup", { + groupId + }); + return groupId; + } + function onGroupAdded(callback) { + return _registry.add("group-added", callback); + } + function onGroupRemoved(callback) { + return _registry.add("group-removed", callback); + } + function onWindowMoved(callback) { + return _registry.add("window-moved", callback); + } + function onHibernated(callback) { + if (!callback) { + throw new Error("Callback argument is required"); + } + if (callback && typeof callback !== "function") { + throw new Error("Callback argument must be a function"); + } + return _registry.add("group-hibernated", callback); + } + function onResumed(callback) { + if (!callback) { + throw new Error("Callback argument is required"); + } + if (callback && typeof callback !== "function") { + throw new Error("Callback argument must be a function"); + } + return _registry.add("group-resumed", callback); + } + function createOrGet(groupId) { + if (!_groups.hasOwnProperty(groupId)) { + const createdGroupWrapper = groupFactory(groupId, environment.executor); + _groups[groupId] = createdGroupWrapper; + const group = createdGroupWrapper.groupAPI; + _registry.execute("group-added", group); + return createdGroupWrapper; + } + else { + return _groups[groupId]; + } + } + function deleteIfEmpty(groupWrapper) { + const group = groupWrapper.groupAPI; + if (group.windows.length === 0) { + delete _groups[group.id]; + executor.clearCallbacks(group.id); + _registry.execute("group-removed", group); + } + } + function addWindow(groupId, winId) { + const group = createOrGet(groupId); + group.groupInternal.addWindow(winId); + return group; + } + function removeWindow(group, win) { + if (!group) { + return; + } + group.groupInternal.removeWindow(win); + deleteIfEmpty(group); + } + function handleCompositionChanged(state) { + const groupId = state.groupId; + const windowId = state.windowId; + const win = windowStore.get(windowId); + if (!win) { + return; + } + const currentGroup = findGroupWrapperByWindow(win.API); + if (isUndefinedOrNull(groupId)) { + removeWindow(currentGroup, win); + return; + } + if (isUndefinedOrNull(currentGroup) && !isUndefinedOrNull(groupId)) { + addWindow(groupId, win.API.id); + return; + } + if (currentGroup.groupAPI.id !== groupId) { + moveWindow(win, currentGroup.groupAPI.id, groupId); + } + } + function moveWindow(win, from, to) { + const winId = win.API.id; + const fromGroup = _groups[from]; + removeWindow(fromGroup, win); + const toGroup = addWindow(to, winId); + win.Events.handleGroupChanged(toGroup.groupAPI, fromGroup.groupAPI); + _registry.execute("window-moved", winId, from, to); + } + function findGroupWrapperByWindow(winId) { + let windowId; + if (typeof winId === "string") { + windowId = winId; + } + else if (!isUndefinedOrNull(winId)) { + windowId = winId.id; + } + return Object.values(_groups).find((groupObj) => { + const groupInternal = groupObj.groupInternal; + const wins = groupInternal.windows.filter((id) => id === windowId); + return wins.length; + }); + } + function validateGroupIdArg(groupId) { + if (!groupId || typeof groupId !== "string") { + throw new Error("Please provide a valid Group ID as a non-empty string!"); + } + } + const groups = { + get my() { + return my(); + }, + create, + close, + list, + findGroupByWindow, + waitForGroup, + getMyGroup, + onGroupAdded, + onGroupRemoved, + hibernate, + resume, + onHibernated, + onResumed + }; + const events = { onWindowMoved }; + return { + groupsAPI: groups, + groupsEvents: events, + }; + }; + + var WindowsFactory = (agm, logger, appManagerGetter, displayAPIGetter, channelsGetter, gdMajorVersion) => { + const _registry = CallbackRegistryFactory(); + const _logger = logger; + let groups; + let environment; + windowStore.init(_logger); + const isReady = new Promise((resolve, reject) => { + envDetector(agm, _logger, appManagerGetter, displayAPIGetter, channelsGetter, gdMajorVersion) + .then((env) => { + environment = env; + groups = groupsFactory(env); + jumpListManager.init(env.executor, agm, _logger); + resolve(); + }) + .catch((e) => { + const err = `Timed out waiting for connection to Glue42 Enterprise: Error: ${e.message}`; + _logger.error(err, e); + reject(new Error(err)); + }); + }); + function ready() { + return isReady; + } + function my() { + const myWindow = windowStore.getIfReady(environment.my()); + return myWindow ? myWindow.API : undefined; + } + function open(name, url, options, success, error) { + return Utils.callbackifyPromise(() => { + if (isNullOrWhiteSpace(name)) { + throw new Error("The window name is missing."); + } + if (isNullOrWhiteSpace(url)) { + throw new Error("The window URL is missing."); + } + if (!isUndefinedOrNull(options)) { + const optionsAsAny = options; + for (const prop of ["minHeight", "maxHeight", "minWidth", "maxWidth", "width", "height", "top", "left"]) { + if (prop in optionsAsAny) { + const value = optionsAsAny[prop]; + if (isUndefinedOrNull(value)) { + delete optionsAsAny[prop]; + continue; + } + if (!isNumber(value)) { + const errMessage = `${prop} must be a number`; + throw new Error(errMessage); + } + if (optionsAsAny[prop] === "width" || optionsAsAny[prop] === "height") { + if (value <= 0) { + const errMessage = `${prop} must be a positive number`; + throw new Error(errMessage); + } + } + } + } + } + return environment.open(name, url, options); + }, success, error); + } + function find(name, success, error) { + const windows = windowStore.list; + const windowsForListing = Object.keys(windows).reduce((memo, winId) => { + var _a; + const window = windows[winId]; + if (((_a = window === null || window === void 0 ? void 0 : window.API) === null || _a === void 0 ? void 0 : _a.name) === name) { + memo.push(window.API); + } + return memo; + }, []); + const win = windowsForListing[0]; + if (win) { + if (typeof success === "function") { + success(windowsForListing[0]); + } + return windowsForListing[0]; + } + else { + if (typeof error === "function") { + error("There is no window with name:" + name); + } + } + } + function findById(id, success, error) { + const windows = windowStore.list; + const windowsForListing = Object.keys(windows).reduce((memo, winId) => { + const window = windows[winId]; + if (typeof window !== "undefined" && window.API.id === id) { + memo.push(window.API); + } + return memo; + }, []); + const win = windowsForListing[0]; + if (win) { + if (typeof success === "function") { + success(windowsForListing[0]); + } + return windowsForListing[0]; + } + else { + if (typeof error === "function") { + error("There is no window with such id:" + id); + } + } + } + function list(success) { + const windows = windowStore.list; + const windowsForListing = Object.keys(windows) + .map((k) => { + return windows[k].API; + }); + if (typeof success !== "function") { + return windowsForListing; + } + success(windowsForListing); + } + function configure(options) { + const win = my(); + const winId = win ? win.id : ""; + return executor.configure(winId, options); + } + function autoArrange(displayId) { + return executor.autoArrange(displayId); + } + function windowAdded(callback) { + return _registry.add("window-added", callback); + } + function windowRemoved(callback) { + return _registry.add("window-removed", callback); + } + function tabAttached(callback) { + let unsubFunc; + let unsubscribed = false; + isReady.then(() => { + if (unsubscribed) { + return; + } + unsubFunc = environment.tabAttached(callback); + }); + return () => { + unsubscribed = true; + if (unsubFunc) { + unsubFunc(); + } + }; + } + function tabDetached(callback) { + let unsubFunc; + let unsubscribed = false; + isReady.then(() => { + if (unsubscribed) { + return; + } + unsubFunc = environment.tabDetached(callback); + }); + return () => { + unsubscribed = true; + if (unsubFunc) { + unsubFunc(); + } + }; + } + function onWindowFrameColorChanged(callback) { + let unsubFunc; + let unsubscribed = false; + isReady.then(() => { + if (unsubscribed) { + return; + } + unsubFunc = environment.onWindowFrameColorChanged(callback); + }); + return () => { + unsubscribed = true; + if (unsubFunc) { + unsubFunc(); + } + }; + } + function onWindowGotFocus(callback) { + let unsubFunc; + let unsubscribed = false; + isReady.then(() => { + if (unsubscribed) { + return; + } + unsubFunc = environment.onWindowGotFocus(callback); + }); + return () => { + unsubscribed = true; + if (unsubFunc) { + unsubFunc(); + } + }; + } + function onWindowLostFocus(callback) { + let unsubFunc; + let unsubscribed = false; + isReady.then(() => { + if (unsubscribed) { + return; + } + unsubFunc = environment.onWindowLostFocus(callback); + }); + return () => { + unsubscribed = true; + if (unsubFunc) { + unsubFunc(); + } + }; + } + function onArrangementChanged(callback) { + return environment.onWindowsAutoArrangeChanged(callback); + } + function onEvent(callback) { + let unsubFunc; + let unsubscribed = false; + isReady.then(() => { + if (unsubscribed) { + return; + } + unsubFunc = environment.onEvent(callback); + }); + return () => { + unsubscribed = true; + if (unsubFunc) { + unsubFunc(); + } + }; + } + function createFlydown(targetId, config) { + return environment.createFlydown(targetId, config); + } + function showPopup(targetId, config) { + return environment.showPopup(targetId, config); + } + function handleWindowAdded(w) { + _registry.execute("window-added", w.API); + } + function handleWindowRemoved(w) { + _registry.execute("window-removed", w.API); + } + windowStore.onReadyWindow(handleWindowAdded); + windowStore.onRemoved(handleWindowRemoved); + return { + my, + open, + find, + findById, + list, + ready, + onWindowAdded: windowAdded, + windowAdded, + onWindowRemoved: windowRemoved, + windowRemoved, + onTabAttached: tabAttached, + onTabDetached: tabDetached, + onWindowFrameColorChanged, + onArrangementChanged, + get groups() { + return groups.groupsAPI; + }, + onWindowGotFocus, + onWindowLostFocus, + onEvent, + createFlydown, + showPopup, + configure, + autoArrange + }; + }; + + class LayoutStore { + constructor() { + this.layouts = []; + } + removeWhere(condition) { + this.layouts = this.layouts.filter(condition); + } + removeAll() { + this.layouts = []; + } + add(item) { + this.layouts.push(item); + } + get all() { + return this.layouts; + } + where(condition) { + return this.layouts.filter(condition); + } + first(condition) { + return this.where(condition)[0]; + } + } + var store = new LayoutStore(); + + const SaveContextMethodName = "T42.HC.GetSaveContext"; + class ContextProvider { + constructor(config, activitiesGetter, callbacks, logger) { + this.config = config; + this.activitiesGetter = activitiesGetter; + this.callbacks = callbacks; + this.logger = logger; + this.interop = config.agm; + this.registerRequestMethods(); + } + onSaveRequested(callback) { + return this.callbacks.add("saveRequested", callback); + } + isActivityOwner() { + if (typeof htmlContainer !== "undefined") { + const context = htmlContainer.getContext(); + return context && context._t42 && context._t42.activityIsOwner; + } + const activities = this.activitiesGetter(); + if (!activities) { + return false; + } + if (!activities.inActivity) { + return false; + } + const myWindow = activities.my.window; + const myActivity = activities.my.activity; + if (!myActivity && !myWindow) { + return false; + } + return myActivity.owner.id === myWindow.id; + } + registerRequestMethods() { + this.interop.register(SaveContextMethodName, (args) => { + const usersCbs = this.callbacks.execute("saveRequested", args); + if ((usersCbs === null || usersCbs === void 0 ? void 0 : usersCbs.length) > 1) { + this.logger.warn(`Multiple subscriptions for "glue.layouts.onSaveRequested" - only the first one will be used`); + } + const requestResult = usersCbs[0]; + const autoSaveWindowContext = this.config.autoSaveWindowContext; + if (typeof autoSaveWindowContext === "boolean" && autoSaveWindowContext) { + return { autoSaveWindowContext }; + } + else if (Array.isArray(autoSaveWindowContext) && autoSaveWindowContext.length > 0) { + return { autoSaveWindowContext }; + } + const result = { windowContext: requestResult === null || requestResult === void 0 ? void 0 : requestResult.windowContext, activityContext: undefined }; + if (this.isActivityOwner()) { + result.activityContext = requestResult === null || requestResult === void 0 ? void 0 : requestResult.activityContext; + } + return result; + }); + } + } + + function transformACSLayout(something) { + if (!something) { + return something; + } + if (Array.isArray(something)) { + return something.map((item) => { + return transformACSLayout(item); + }); + } + if (typeof something === "string" || typeof something === "number" || typeof something === "boolean") { + return something; + } + const initial = {}; + return Object.keys(something).reduce((accumulator, current) => { + var _a; + const value = something[current]; + const convertedValue = transformACSLayout(value); + let key = current; + if (((_a = current[0]) === null || _a === void 0 ? void 0 : _a.toLowerCase()) !== current[0]) { + key = current[0].toLowerCase() + current.substr(1); + } + accumulator[key] = convertedValue; + return accumulator; + }, initial); + } + + class LayoutImpl { + constructor(data) { + this.name = data.name; + this.type = data.type; + this.components = data.components; + this.context = data.context; + this.metadata = data.metadata; + this.version = data.version; + this.displays = data.displays; + } + } + + var main = {}; + + var application = {}; + + /** + * This file was automatically generated by json-schema-to-typescript. + * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file, + * and run json-schema-to-typescript to regenerate this file. + */ + Object.defineProperty(application, "__esModule", { value: true }); + + var system = {}; + + /** + * This file was automatically generated by json-schema-to-typescript. + * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file, + * and run json-schema-to-typescript to regenerate this file. + */ + Object.defineProperty(system, "__esModule", { value: true }); + + var layout = {}; + + Object.defineProperty(layout, "__esModule", { value: true }); + layout.SwimlaneItemType = layout.LayoutType = void 0; + var LayoutType; + (function (LayoutType) { + LayoutType["Global"] = "Global"; + LayoutType["Activity"] = "Activity"; + LayoutType["ApplicationDefault"] = "ApplicationDefault"; + LayoutType["Swimlane"] = "Swimlane"; + LayoutType["Workspaces"] = "Workspace"; + })(LayoutType || (layout.LayoutType = LayoutType = {})); + var SwimlaneItemType; + (function (SwimlaneItemType) { + SwimlaneItemType["Tab"] = "tab"; + SwimlaneItemType["Window"] = "window"; + SwimlaneItemType["Canvas"] = "canvas"; + })(SwimlaneItemType || (layout.SwimlaneItemType = SwimlaneItemType = {})); + + var swTheme = {}; + + /** + * This file was automatically generated by json-schema-to-typescript. + * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file, + * and run json-schema-to-typescript to regenerate this file. + */ + Object.defineProperty(swTheme, "__esModule", { value: true }); + + var swConfiguration = {}; + + /** + * This file was automatically generated by json-schema-to-typescript. + * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file, + * and run json-schema-to-typescript to regenerate this file. + */ + Object.defineProperty(swConfiguration, "__esModule", { value: true }); + + (function (exports) { + var __createBinding = (commonjsGlobal && commonjsGlobal.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; + })); + var __exportStar = (commonjsGlobal && commonjsGlobal.__exportStar) || function(m, exports) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); + }; + Object.defineProperty(exports, "__esModule", { value: true }); + // export { SchemaValidator } from "./validator"; + // export { FileProvider } from "./fileProvider"; + // export { SchemaProvider } from "./provider"; + __exportStar(application, exports); + __exportStar(system, exports); + __exportStar(layout, exports); + __exportStar(swTheme, exports); + __exportStar(swConfiguration, exports); + + } (main)); + + const LayoutsCommandMethod = "T42.ACS.Command"; + class LayoutsAPIImpl { + constructor(config, stream, callbacks, logger) { + this.config = config; + this.stream = stream; + this.callbacks = callbacks; + this.isRegisterMethodForLayoutModified = false; + this.appManager = config.appManager; + this.provider = new ContextProvider(config, config.activityGetter, callbacks, logger); + stream.subscribe(); + } + async setDefaultGlobal(name) { + const methodName = "SelectDefaultLayout"; + await this.invokeMethodCore(methodName, { name }); + return; + } + async clearDefaultGlobal() { + const methodName = "DeselectDefaultLayout"; + await this.invokeMethodCore(methodName); + return; + } + async getDefaultGlobal() { + const methodName = "GetDefaultLayout"; + const result = await this.invokeMethodCore(methodName); + const layout = result.returned; + if (layout === null || layout === undefined || (typeof layout === 'object' && Object.keys(layout).length === 0)) { + return undefined; + } + return objectClone(this.isSlimMode() ? layout : this.list().find((l) => l.name === layout.name && l.type === layout.type)); + } + ready() { + if (this.config.mode === "fullWaitSnapshot") { + return this.stream.gotSnapshot; + } + return this.stream.ready; + } + save(layout) { + return new Promise((resolve, reject) => { + var _a, _b; + this.verifyNotSlimMode(); + if (isUndefinedOrNull(layout)) { + return reject(new Error("layout is required")); + } + if (isNullOrWhiteSpace(layout.name)) { + return reject(new Error("layout.name argument is required")); + } + if (isNullOrWhiteSpace(layout.type)) { + layout.type = "Global"; + } + if (!isNullOrWhiteSpace(layout.activityId)) { + layout.type = "Activity"; + } + const layoutObject = { + name: layout.name, + type: layout.type, + context: (_a = layout.context) !== null && _a !== void 0 ? _a : {}, + metadata: (_b = layout.metadata) !== null && _b !== void 0 ? _b : {}, + options: {}, + }; + if (layout.type === "Activity") { + let actId = layout.activityId; + if (!actId) { + if (!this.appManager.myInstance.inActivity) { + return reject(new Error("Current application is not in activity. Cannot save activity layout for it.")); + } + actId = this.appManager.myInstance.activityId; + } + layoutObject.activityId = actId; + } + else if (layout.type === "Global") { + if (Array.isArray(layout.ignoreInstances)) { + layoutObject.options.ignoreInstances = layout.ignoreInstances; + } + if (Array.isArray(layout.instances)) { + layoutObject.options.instances = layout.instances; + } + if (typeof layout.setAsCurrent === "boolean") { + layoutObject.options.setAsCurrent = layout.setAsCurrent; + } + } + else { + return reject(new Error(`layout type ${layout.type} is not supported`)); + } + this.invokeMethodAndTrack("SaveLayout", layoutObject, resolve, reject); + }); + } + restore(options) { + return new Promise((resolve, reject) => { + var _a, _b, _c; + this.verifyNotSlimMode(); + if (isUndefinedOrNull(options)) { + return reject(new Error("options argument is required")); + } + if (isNullOrWhiteSpace(options.name)) { + return reject(new Error("options.name argument is required")); + } + if (isNullOrWhiteSpace(options.type)) { + options.type = "Global"; + } + if (!isNullOrWhiteSpace(options.activityIdToJoin)) { + options.type = "Activity"; + } + if (options.type === "Activity") { + if (isUndefinedOrNull(options.setActivityContext)) { + options.setActivityContext = true; + } + if (typeof options.setActivityContext !== "boolean") { + return reject(new Error("`setActivityContext` must hold a boolean value.")); + } + options.activityIdToJoin = (_a = options.activityIdToJoin) !== null && _a !== void 0 ? _a : this.appManager.myInstance.activityId; + } + if (!isUndefinedOrNull(options.closeRunningInstance)) { + options.closeRunningInstances = options.closeRunningInstance; + } + if (isUndefinedOrNull(options.closeRunningInstances)) { + options.closeRunningInstances = true; + } + if (!isBoolean(options.closeRunningInstances)) { + return reject(new Error("`closeRunningInstances` must hold a boolean value.")); + } + if (isUndefinedOrNull(options.closeMe)) { + options.closeMe = options.closeRunningInstances; + } + if (!isBoolean(options.closeMe)) { + return reject(new Error("`closeMe` must hold a boolean value.")); + } + if (!isUndefinedOrNull(options.context) && !isObject(options.context)) { + return reject(new Error("`context` must hold an object value.")); + } + if (!isUndefinedOrNull(options.timeout) && typeof options.timeout !== "number") { + return reject(new Error("`timeout` must hold an number value.")); + } + options.context = (_b = options.context) !== null && _b !== void 0 ? _b : {}; + const restoreOptions = { + activityToJoin: options.activityIdToJoin, + setActivityContext: options.setActivityContext, + ignoreActivityWindowTypes: options.ignoreActivityWindowTypes, + reuseExistingWindows: options.reuseWindows, + closeRunningInstances: options.closeRunningInstances, + excludeFromClosing: options.closeMe ? [] : [(_c = this.appManager.myInstance) === null || _c === void 0 ? void 0 : _c.id] + }; + const arg = { + type: options.type, + name: options.name, + context: options.context, + options: restoreOptions + }; + if (options.timeout) { + arg.timeout = options.timeout; + } + this.invokeMethodAndTrack("RestoreLayout", arg, resolve, reject, true); + }); + } + reset(options) { + return new Promise((resolve, reject) => { + this.verifyNotSlimMode(); + if (typeof options !== "object") { + return reject(new Error("options argument is required")); + } + if (isNullOrWhiteSpace(options.layoutId)) { + return reject(new Error("options.layoutId argument is required")); + } + const msg = { + ...options + }; + this.invokeMethodAndTrack("ResetLayout", msg, resolve, reject, true); + }); + } + remove(type, name) { + return new Promise((resolve, reject) => { + this.verifyNotSlimMode(); + if (!name) { + return reject(new Error("name argument is required")); + } + if (!type) { + return reject(new Error("type argument is required")); + } + const msg = { + type, + name, + }; + this.invokeMethodAndTrack("RemoveLayout", msg, resolve, reject); + }); + } + list() { + this.verifyNotSlimMode(); + return objectClone(store.all); + } + import(layouts, mode) { + return new Promise((resolve, reject) => { + this.verifyNotSlimMode(); + if (!isUndefinedOrNull(mode)) { + if (mode !== "merge" && mode !== "replace") { + return reject(new Error(`${mode} is not supported - only "merge" and "replace"`)); + } + } + if (!Array.isArray(layouts)) { + return reject(new Error("layouts arguments is not an array")); + } + const msg = { + mode: mode || "replace", + layouts + }; + this.invokeMethodAndTrack("ImportLayouts", msg, resolve, reject, true); + }); + } + export(layoutType) { + return new Promise((resolve, reject) => { + var _a; + if (!isUndefinedOrNull(layoutType) && !((_a = Object.values(main.LayoutType)) === null || _a === void 0 ? void 0 : _a.includes(layoutType))) { + return reject(new Error(`${layoutType} is not a supported Layout Type`)); + } + const handleResult = (result) => { + let layouts = this.getObjectValues(result.Layouts).map((t) => new LayoutImpl(transformACSLayout(t))); + if (layoutType) { + layouts = layouts.filter((l) => l.type === layoutType); + } + resolve(layouts); + }; + this.invokeMethodAndTrack("ExportLayouts", {}, handleResult, reject, true); + }); + } + rename(layout, newName) { + return new Promise((resolve, reject) => { + this.verifyNotSlimMode(); + if (!layout) { + return reject(new Error("layout argument is required")); + } + if (!layout.name) { + return reject(new Error("name argument is required")); + } + if (!layout.type) { + return reject(new Error("type argument is required")); + } + const msg = { type: layout.type, oldName: layout.name, newName }; + this.invokeMethodAndTrack("RenameLayout", msg, resolve, reject); + }); + } + updateMetadata(layout) { + return new Promise((resolve, reject) => { + if (!layout) { + return reject(new Error("layout argument is required")); + } + if (!layout.name) { + return reject(new Error("name argument is required")); + } + if (!layout.type) { + return reject(new Error("type argument is required")); + } + if (!layout.metadata) { + return reject(new Error("metadata argument is required")); + } + const layoutObject = { + name: layout.name, + type: layout.type, + metadata: layout.metadata + }; + this.invokeMethodAndTrack("UpdateMetadata", layoutObject, resolve, reject, true); + }); + } + hibernate(name, options) { + return new Promise((resolve, reject) => { + if (!name) { + return reject(new Error("name cannot be empty")); + } + options = options || {}; + const request = { + name, + type: "Global", + context: options.context || {}, + metadata: options.metadata || {}, + }; + this.invokeMethodAndTrack("HibernateLayout", request, resolve, reject, true); + }); + } + resume(name, context, options) { + return new Promise((resolve, reject) => { + if (!name) { + return reject(new Error("name cannot be empty")); + } + const request = { + name, + type: "Global", + context, + ...options + }; + this.invokeMethodAndTrack("ResumeLayout", request, resolve, reject, true); + }); + } + async getCurrentLayout() { + const methodName = "GetCurrentLayout"; + const result = await this.invokeMethodCore(methodName); + let layout = result.returned.layout; + if (!layout) { + return undefined; + } + if (!this.isSlimMode()) { + layout = this.list().find((l) => l.name === layout.name && l.type === layout.type); + } + return objectClone(layout); + } + getRestoredLayoutsInfo() { + return new Promise((resolve, reject) => { + const methodName = "GetRestoredLayoutsInfo"; + this.invokeMethodCore(methodName) + .then((result) => { + const restoredLayouts = result.returned; + resolve(restoredLayouts); + }) + .catch(reject); + }); + } + onAdded(callback) { + const result = this.callbacks.add("added", callback); + if (store.all.length > 0) { + store.all.forEach((layout) => { + try { + callback(layout); + } + catch (err) { } + }); + } + return result; + } + onRemoved(callback) { + return this.callbacks.add("removed", callback); + } + onChanged(callback) { + return this.callbacks.add("changed", callback); + } + onRestored(callback) { + return this.callbacks.add("restored", callback); + } + onRenamed(callback) { + return this.callbacks.add("renamed", callback); + } + onEvent(callback) { + return this.stream.onEvent(callback); + } + onSaveRequested(callback) { + return this.provider.onSaveRequested(callback); + } + onLayoutModified(callback) { + if (this.isRegisterMethodForLayoutModified === false) { + this.isRegisterMethodForLayoutModified = true; + this.registerMethodForLayoutModified(); + } + return this.callbacks.add("layout-modified", callback); + } + updateAppContextInCurrent(context) { + return new Promise((resolve, reject) => { + if (context && typeof context !== "object") { + return reject(new Error("Context must be an object")); + } + context = context !== null && context !== void 0 ? context : {}; + const request = { + context + }; + this.invokeMethodAndTrack("UpdateLayoutComponentContext", request, resolve, reject, true); + }); + } + updateDefaultContext(context) { + return new Promise((resolve, reject) => { + if (context && typeof context !== "object") { + return reject(new Error("Context must be an object")); + } + context = context !== null && context !== void 0 ? context : {}; + const request = { + context + }; + this.invokeMethodAndTrack("UpdateDefaultContext", request, resolve, reject, true); + }); + } + async get(name, type) { + const matching = this.list().find((l) => l.name === name && l.type === type); + if (!matching) { + throw new Error(`cannot find layout with name=${name} and type=${type}`); + } + return objectClone(matching); + } + async getAll(type) { + var _a; + if (!isUndefinedOrNull(type) && !((_a = Object.values(main.LayoutType)) === null || _a === void 0 ? void 0 : _a.includes(type))) { + throw new Error((`${type} is not a supported Layout Type`)); + } + const matching = this.list().filter((l) => type === l.type); + return objectClone(matching); + } + async forceRefresh() { + const methodName = "RefreshLayouts"; + await this.invokeMethodCore(methodName); + } + isSlimMode() { + return this.config.mode === "slim"; + } + verifyNotSlimMode() { + if (this.isSlimMode()) { + throw Error("Operation not allowed in slim mode. Run in full mode."); + } + } + async registerMethodForLayoutModified() { + await this.config.agm.register("T42.ACS.LayoutModified", (args, caller) => { + this.callbacks.execute("layout-modified", args); + }); + } + invokeMethodAndTrack(methodName, args, resolve, reject, skipStreamEvent) { + let streamEventReceived = skipStreamEvent; + let agmResult; + const token = Utils.generateId(); + args.token = token; + const handleResult = () => { + if (streamEventReceived && agmResult) { + resolve(agmResult); + } + }; + const methodResponseTimeoutMs = 120 * 1000; + if (!skipStreamEvent) { + this.stream.waitFor(token, methodResponseTimeoutMs) + .then(() => { + streamEventReceived = true; + handleResult(); + }) + .catch((err) => { + reject(err); + }); + } + const responseHandler = (result) => { + if (!result.returned) { + return reject(new Error("No result from method " + methodName)); + } + if (result.returned.status && (result.returned.status !== "Success" && result.returned.status !== "PartialSuccess")) { + if (typeof (result.returned) === "string") { + return reject(new Error(result.returned)); + } + else if (typeof (result.returned) === "object") { + if (result.returned.status && result.returned.failed) { + return reject(new Error(`${result.returned.status}: ${JSON.stringify(result.returned.failed)}`)); + } + else { + return reject(new Error(result.returned)); + } + } + } + agmResult = result.returned; + handleResult(); + }; + this.invokeMethodCore(methodName, args, "best", { methodResponseTimeoutMs }) + .then(responseHandler) + .catch((err) => reject(err)); + } + async invokeMethodCore(methodName, args, target, options) { + options = options !== null && options !== void 0 ? options : {}; + if (typeof options.methodResponseTimeoutMs === "undefined") { + options.methodResponseTimeoutMs = INTEROP_METHOD_WAIT_TIMEOUT_MS; + } + if (typeof options.waitTimeoutMs === "undefined") { + options.waitTimeoutMs = INTEROP_METHOD_WAIT_TIMEOUT_MS; + } + if (this.isCommandMethodPresent()) { + return await this.config.agm.invoke(LayoutsCommandMethod, { command: methodName, data: args }, target, options); + } + else { + return await this.config.agm.invoke(`T42.ACS.${methodName}`, args, target, options); + } + } + getObjectValues(obj) { + if (!obj) { + return []; + } + return Object.keys(obj).map((k) => obj[k]); + } + isCommandMethodPresent() { + return this.config.agm.methods().some((method) => method.name === LayoutsCommandMethod); + } + } + + class ACSStream { + constructor(agm, callbacks) { + this.agm = agm; + this.callbacks = callbacks; + this.StreamName = "T42.ACS.OnLayoutEvent"; + this.ready = new Promise((resolve, reject) => { + this.resolveReady = resolve; + this.rejectReady = reject; + }); + this.gotSnapshot = new Promise((resolve, reject) => { + this.resolveGotSnapshot = resolve; + this.rejectGotSnapshot = reject; + }); + } + subscribe(noRetry) { + const transform = (obj) => { + return this.getObjectValues(obj).map((t) => transformACSLayout(t)); + }; + if (!this.checkForLayoutEventMethod()) { + if (noRetry) { + this.resolveReady(); + } + setTimeout(() => { + this.subscribe(true); + }, 500); + } + else { + this.agm.subscribe(this.StreamName, { waitTimeoutMs: 10000 }) + .then((subs) => { + subs.onData((args) => { + const data = args.data; + if (data.IsSnapshot) { + this.resolveGotSnapshot(); + } + this.addLayouts(transform(data.OnLayoutAdded), data.IsSnapshot); + this.removeLayouts(transform(data.OnLayoutRemoved)); + this.changeLayouts(transform(data.OnLayoutChanged)); + this.renameLayouts(transform(data.OnLayoutRenamed)); + this.restoredLayout(transform(data.OnLayoutRestored)); + this.callbacks.execute("streamEvent", data); + }); + subs.onFailed((err) => { + const msg = `Can not subscribe to "${this.StreamName}" stream - ${JSON.stringify(err)}`; + this.rejectReady(msg); + this.rejectGotSnapshot(msg); + }); + this.resolveReady(); + }) + .catch((err) => { + const msg = `Error subscribing to "${this.StreamName}" stream - ${JSON.stringify(err)}`; + this.rejectReady(msg); + this.rejectGotSnapshot(msg); + }); + } + } + onEvent(callback) { + return this.callbacks.add("streamEvent", callback); + } + waitFor(token, timeout) { + if (!timeout) { + timeout = 30000; + } + return new Promise((resolve, reject) => { + let done = false; + const unsubscribe = this.onEvent((streamEvent) => { + if (streamEvent.Token === token) { + done = true; + unsubscribe(); + resolve(); + } + }); + setTimeout(() => { + if (!done) { + reject("timed out"); + } + }, timeout); + }); + } + checkForLayoutEventMethod() { + try { + return this.agm + .methods() + .map((m) => m.name) + .indexOf(this.StreamName) !== -1; + } + catch (e) { + return false; + } + } + addLayouts(layoutsData, isSnapshot) { + if (!layoutsData) { + return; + } + const createAndNotifyLayout = (layoutData) => { + const layout = new LayoutImpl(layoutData); + store.add(layout); + this.callbacks.execute("added", layout); + }; + layoutsData.forEach((layoutData) => { + if (isSnapshot) { + const found = store.first((existingLayout) => this.compareLayouts(existingLayout, layoutData)); + if (!found) { + createAndNotifyLayout(layoutData); + } + } + else { + createAndNotifyLayout(layoutData); + } + }); + } + removeLayouts(removedLayouts) { + if (!removedLayouts) { + return; + } + removedLayouts.forEach((removedLayout) => { + store.removeWhere((existingLayout) => !this.compareLayouts(existingLayout, removedLayout)); + this.callbacks.execute("removed", removedLayout); + }); + } + changeLayouts(changedLayouts) { + if (!changedLayouts) { + return; + } + changedLayouts.forEach((changedLayout) => { + store.removeWhere((existingLayout) => !this.compareLayouts(existingLayout, changedLayout)); + store.add(new LayoutImpl(changedLayout)); + this.callbacks.execute("changed", changedLayout); + }); + } + renameLayouts(renamedLayouts) { + if (!renamedLayouts) { + return; + } + renamedLayouts.forEach((renamedLayout) => { + const existingLayout = store.first((current) => this.compareLayouts(current, { type: renamedLayout.type, name: renamedLayout.oldName })); + if (!existingLayout) { + throw Error(`received rename event for unknown layout with type ${renamedLayout.type} and name ${renamedLayout.oldName}`); + } + existingLayout.name = renamedLayout.newName; + this.callbacks.execute("renamed", existingLayout); + }); + } + compareLayouts(layout1, layout2) { + return layout1.name === layout2.name && layout1.type === layout2.type; + } + getObjectValues(obj) { + if (!obj) { + return []; + } + return Object.keys(obj).map((k) => obj[k]); + } + restoredLayout(restoredLayouts) { + if (!restoredLayouts) { + return; + } + restoredLayouts.forEach((restoredLayout) => { + const existingLayout = store.first((current) => this.compareLayouts(current, { type: restoredLayout.type, name: restoredLayout.name })); + this.callbacks.execute("restored", existingLayout); + }); + } + } + + function LayoutsFactory (config) { + if (!config.agm) { + throw Error("config.agm is required"); + } + if (!config.logger) { + throw Error("config.logger is required"); + } + config.mode = config.mode || "slim"; + const logger = config.logger; + const callbacks = CallbackRegistryFactory(); + let acsStream; + if (config.mode === "full" || "fullWaitSnapshot") { + acsStream = new ACSStream(config.agm, callbacks); + } + return new LayoutsAPIImpl(config, acsStream, callbacks, logger); + } + + const T42DisplayCommand = "T42.Displays.Command"; + const T42DisplayOnEvent = "T42.Displays.OnEvent"; + class DisplayManager { + constructor(_agm, _logger) { + this._agm = _agm; + this._logger = _logger; + this._registry = CallbackRegistryFactory(); + this._registered = false; + this.all = async () => { + const displays = await this.callGD(DisplayCommand.GetAll, {}); + return displays.map(this.decorateDisplay); + }; + this.get = async (id) => { + const display = await this.callGD(DisplayCommand.Get, { id }); + return this.decorateDisplay(display); + }; + this.getPrimary = async () => { + const primary = (await this.all()).find((d) => d.isPrimary); + return primary; + }; + this.capture = async (options) => { + const screenshot = await this.callGD(DisplayCommand.Capture, { ...options }); + return screenshot; + }; + this.captureAll = async (options) => { + const screenshots = await this.callGD(DisplayCommand.CaptureAll, { ...options }); + return screenshots; + }; + this.getMousePosition = async () => { + const point = await this.callGD(DisplayCommand.GetMousePosition); + return point; + }; + this.callGD = async (command, options) => { + const invocationResult = await this._agm.invoke(T42DisplayCommand, { options: { ...options }, command }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return invocationResult.returned.data; + }; + this.decorateDisplay = (original) => { + const decoratedDisplay = { + ...original, + capture: (size) => this.capture({ id: original.id, size }) + }; + const workAreaAsAny = decoratedDisplay.workArea; + workAreaAsAny.x = workAreaAsAny.left; + workAreaAsAny.y = decoratedDisplay.workArea.top; + return decoratedDisplay; + }; + } + getByWindowId(id) { + const current = this.callGD(DisplayCommand.GetByWindowId, { id }); + return current; + } + onDisplayChanged(cb) { + this.register(); + return this._registry.add("on-display-changed", cb); + } + register() { + if (this._registered) { + return; + } + this._registered = true; + this._agm.register(T42DisplayOnEvent, (args, caller) => { + const event = args.event; + const data = args.data; + switch (event) { + case "display-changed": + this._registry.execute("on-display-changed", data.displays.map(this.decorateDisplay)); + break; + default: + this._logger.warn(`unknown event - ${event}`); + break; + } + }); + } + } + var DisplayCommand; + (function (DisplayCommand) { + DisplayCommand["Capture"] = "capture"; + DisplayCommand["CaptureAll"] = "captureAll"; + DisplayCommand["GetAll"] = "getAll"; + DisplayCommand["Get"] = "get"; + DisplayCommand["GetByWindowId"] = "getByWindowId"; + DisplayCommand["GetMousePosition"] = "getMousePosition"; + })(DisplayCommand || (DisplayCommand = {})); + + class SingleChannelID { + constructor(channel) { + this.channel = channel; + } + get isJoinedToAnyChannel() { + return !!this.channel; + } + isOnChannel(channel) { + return this.channel === channel; + } + leaveChannel(channel) { + if (channel === undefined || this.channel === channel) { + this.channel = undefined; + } + } + joinChannel(channel) { + this.channel = channel; + } + all() { + if (this.channel) { + return [this.channel]; + } + return []; + } + toString() { + return this.channel; + } + equals(other) { + if (other instanceof SingleChannelID) { + return this.channel === other.channel; + } + return false; + } + } + class MultiChannelId { + constructor(channels) { + this.ChannelDelimiter = "+++"; + if (!channels) { + this.channels = []; + } + else if (typeof channels === "string") { + this.channels = channels === null || channels === void 0 ? void 0 : channels.split(this.ChannelDelimiter).filter(Boolean); + } + else { + this.channels = (channels !== null && channels !== void 0 ? channels : []).filter(Boolean); + } + } + get isJoinedToAnyChannel() { + return this.channels.length > 0; + } + isOnChannel(channel) { + return this.channels.includes(channel); + } + joinChannel(channel) { + const newChannels = new MultiChannelId(channel); + newChannels.all().forEach((newChannel) => { + if (!this.channels.includes(newChannel)) { + this.channels.push(newChannel); + } + }); + } + leaveChannel(channel) { + const channelsToLeave = new MultiChannelId(channel !== null && channel !== void 0 ? channel : this.channels); + channelsToLeave.all().forEach((c) => { + this.channels = this.channels.filter((ch) => ch !== c); + }); + } + all() { + return this.channels; + } + toString() { + if (this.channels.length === 0) { + return undefined; + } + return this.channels.join(this.ChannelDelimiter); + } + equals(other) { + if (other instanceof MultiChannelId) { + return this.channels.length === other.channels.length && + this.channels.every((c, i) => c === other.channels[i]); + } + return false; + } + } + + let interop; + let myInstanceId; + let logger; + const T42_ANNOUNCE_METHOD_NAME = "T42.Channels.Announce"; + const T42_COMMAND_METHOD_NAME = "T42.Channels.Command"; + async function setupInterop(interopLib, channels, loggerAPI) { + var _a, _b; + logger = loggerAPI; + interop = interopLib; + if (typeof window !== "undefined") { + if (window.glue42gd) { + myInstanceId = window.glue42gd.windowId; + } + } + if (!myInstanceId) { + myInstanceId = interopLib.instance.instance; + } + await interop.register(T42_COMMAND_METHOD_NAME, (args) => { + const command = args.command; + if (!command) { + throw new Error("missing command argument"); + } + logger.trace(`received command "${command}" with ${JSON.stringify(args)}`); + if (command === "join") { + const id = args.channel; + if (!id) { + throw new Error("missing argument id"); + } + return channels.joinNoSelectorSwitch(id); + } + if (command === "leave") { + return channels.leaveNoSelectorSwitch(); + } + if (command === "get") { + const id = channels.current(); + return { id }; + } + if (command === "restrictions-changed") { + const restrictions = args.restrictions; + const targetWindowId = args.swId; + channels.handleRestrictionsChanged(restrictions, targetWindowId); + return; + } + if (command === "isFdc3DataWrappingSupported") { + return { isSupported: true }; + } + if (command === "join-multi") { + const channelsToJoin = args.channelsToJoin; + if (!channelsToJoin) { + throw new Error("missing argument channelsToJoin"); + } + return channels.joinNoSelectorSwitch(new MultiChannelId(channelsToJoin).toString()); + } + if (command === "leave-multi") { + const channelsToLeave = args.channelsToLeave; + return channels.leaveNoSelectorSwitch(new MultiChannelId(channelsToLeave).toString()); + } + throw new Error(`unknown command ${command}`); + }); + const result = await interop.invoke(T42_ANNOUNCE_METHOD_NAME, { swId: myInstanceId, instance: interop.instance.instance }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_RESPONSE_TIMEOUT_MS + }); + if ((_a = result.returned) === null || _a === void 0 ? void 0 : _a.restrictions) { + channels.handleRestrictionsChanged((_b = result.returned) === null || _b === void 0 ? void 0 : _b.restrictions, myInstanceId); + } + return result.returned; + } + async function sendLeaveChannel(channel, winId) { + var _a; + await invoke("leaveChannel", { channel }, (_a = winId !== null && winId !== void 0 ? winId : winId) !== null && _a !== void 0 ? _a : myInstanceId); + } + async function sendSwitchChannelUI(channel, winId) { + await invoke("switchChannel", { newChannel: channel }, winId !== null && winId !== void 0 ? winId : myInstanceId); + } + async function setRestrictions(restrictions) { + var _a; + await invoke("restrict", restrictions, (_a = restrictions.windowId) !== null && _a !== void 0 ? _a : myInstanceId); + } + async function getRestrictionsByWindow(id) { + try { + const result = await invoke("getRestrictions", {}, id !== null && id !== void 0 ? id : myInstanceId); + return result.returned; + } + catch (e) { + } + } + async function setRestrictionsForAllChannels(restrictions) { + var _a; + await invoke("restrictAll", restrictions, (_a = restrictions.windowId) !== null && _a !== void 0 ? _a : myInstanceId); + } + async function getChannelsInfo(filter) { + const result = await invoke("getChannelsInfo", { filter }); + return result.returned; + } + async function addOrRemoveChannel(command, id, color, label) { + await invoke(command, { id, color, label }); + } + async function getChannelInitInfo(config, i) { + if (typeof config.operationMode !== "boolean" && typeof config.operationMode === "string") { + validateMode(config.operationMode); + return { mode: config.operationMode, initialChannel: undefined }; + } + try { + const result = await i.invoke(T42_ANNOUNCE_METHOD_NAME, { command: "getChannelsMode" }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_RESPONSE_TIMEOUT_MS, + }); + const initialChannel = result.returned.initialChannel; + if (result.returned.mode === "single") { + return { + mode: "single", + initialChannel + }; + } + else if (result.returned.mode === "multi") { + return { + mode: "multi", + initialChannel + }; + } + else { + return { + mode: "single", + initialChannel + }; + } + } + catch (e) { + return { mode: "single", initialChannel: undefined }; + } + } + function invoke(command, data, swId) { + const args = { command, data }; + if (swId) { + args.swId = swId; + } + return interop.invoke(T42_ANNOUNCE_METHOD_NAME, args, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_RESPONSE_TIMEOUT_MS, + }); + } + function validateMode(mode) { + if (mode !== "single" && mode !== "multi") { + throw new Error(`Invalid mode: ${mode}`); + } + } + + const CONTEXT_PREFIX = "___channel___"; + const LATEST_FDC3_TYPE = "latest_fdc3_type"; + class BaseSharedContextSubscriber { + constructor(contexts) { + this.contexts = contexts; + } + subscribe(callback) { + this.callback = callback; + } + subscribeFor(name, callback) { + if (!this.isChannel(name)) { + return Promise.reject(new Error(`Channel with name: ${name} doesn't exist!`)); + } + const contextName = this.createContextName(name); + return this.contexts.subscribe(contextName, (data, _, __, ___, extraData) => { + callback(data.data, data, extraData === null || extraData === void 0 ? void 0 : extraData.updaterId); + }); + } + all() { + const contextNames = this.contexts.all(); + const channelContextNames = contextNames.filter((contextName) => contextName.startsWith(CONTEXT_PREFIX)); + const channelNames = channelContextNames.map((channelContextName) => channelContextName.substr(CONTEXT_PREFIX.length)); + return channelNames; + } + async getContextData(name) { + if (!this.isChannel(name)) { + throw new Error(`A channel with name: ${name} doesn't exist!`); + } + const contextName = this.createContextName(name); + const contextData = await this.contexts.get(contextName); + if (contextData[LATEST_FDC3_TYPE]) { + return this.getContextWithFdc3Data(contextData); + } + else { + delete contextData[LATEST_FDC3_TYPE]; + } + return contextData; + } + updateChannel(name, data) { + const contextName = this.createContextName(name); + return this.contexts.update(contextName, data); + } + updateData(name, data) { + const contextName = this.createContextName(name); + const fdc3Type = this.getFDC3Type(data); + if (this.contexts.setPathSupported) { + const pathValues = Object.keys(data).map((key) => { + return { + path: `data.` + key, + value: data[key] + }; + }); + if (fdc3Type) { + pathValues.push({ path: LATEST_FDC3_TYPE, value: fdc3Type }); + } + return this.contexts.setPaths(contextName, pathValues); + } + else { + if (fdc3Type) { + data[LATEST_FDC3_TYPE] = fdc3Type; + } + return this.contexts.update(contextName, { data }); + } + } + setPaths(name, paths) { + const contextName = this.createContextName(name); + if (this.contexts.setPathSupported) { + const pathValues = paths.map((p) => { + return { + path: `data.` + p.path, + value: p.value + }; + }); + pathValues.map((p) => { + const fdc3Type = this.getFDC3Type(p.value); + if (fdc3Type) { + pathValues.push({ path: LATEST_FDC3_TYPE, value: fdc3Type }); + } + }); + return this.contexts.setPaths(contextName, pathValues); + } + else { + throw new Error("setPaths is not supported!"); + } + } + clearContextData(name) { + const contextName = this.createContextName(name); + return this.contexts.update(contextName, { data: {}, [LATEST_FDC3_TYPE]: undefined }); + } + isChannel(name) { + return this.all().some((channelName) => channelName === name); + } + async remove(name) { + if (!this.isChannel(name)) { + throw new Error(`A channel with name: ${name} doesn't exist!`); + } + const contextName = this.createContextName(name); + await this.contexts.destroy(contextName); + } + createContextName(name) { + return CONTEXT_PREFIX + name; + } + getFDC3Type(data) { + const fdc3PropsArr = Object.keys(data).filter((key) => key.indexOf("fdc3_") === 0); + if (fdc3PropsArr.length === 0) { + return; + } + if (fdc3PropsArr.length > 1) { + throw new Error("FDC3 does not support updating of multiple context keys"); + } + return fdc3PropsArr[0].split("_").slice(1).join("_"); + } + getContextWithFdc3Data(channelContext) { + const { latest_fdc3_type, ...rest } = channelContext; + const parsedType = latest_fdc3_type.split("&").join("."); + const fdc3Context = { type: parsedType, ...rest.data[`fdc3_${latest_fdc3_type}`] }; + delete rest.data[`fdc3_${latest_fdc3_type}`]; + const context = { + name: channelContext.name, + meta: channelContext.meta, + data: { + ...rest.data, + fdc3: fdc3Context + } + }; + return context; + } + } + class MultiSharedContextSubscriber extends BaseSharedContextSubscriber { + constructor() { + super(...arguments); + this.currentlySubscribedChannels = []; + this.unsubscribeMap = {}; + } + async switchChannel(id) { + const newChannels = new MultiChannelId(id).all(); + for (const newChannel of newChannels) { + if (!this.currentlySubscribedChannels.includes(newChannel)) { + await this.subscribeToChannel(newChannel); + } + } + } + async leave(id) { + const channelsToLeave = new MultiChannelId(id).all(); + for (const newChannel of channelsToLeave) { + if (this.currentlySubscribedChannels.includes(newChannel)) { + this.unsubscribeFromChannel(newChannel); + } + } + } + async updateData(id, data) { + const channels = new MultiChannelId(id).all(); + for (const channel of channels) { + await super.updateData(channel, data); + } + } + async setPaths(id, paths) { + const channels = new MultiChannelId(id).all(); + for (const channel of channels) { + await super.setPaths(channel, paths); + } + } + isChannel(name) { + const channels = new MultiChannelId(name).all(); + return channels.every((channel) => super.isChannel(channel)); + } + async subscribeToChannel(name) { + const contextName = this.createContextName(name); + const usub = await this.contexts.subscribe(contextName, (data, _, __, ___, extraData) => { + if (this.callback) { + this.callback(data.data, data, extraData === null || extraData === void 0 ? void 0 : extraData.updaterId); + } + }); + this.currentlySubscribedChannels.push(name); + this.unsubscribeMap[contextName] = usub; + } + async unsubscribeFromChannel(name) { + const contextName = this.createContextName(name); + const unsub = this.unsubscribeMap[contextName]; + if (unsub) { + unsub(); + delete this.unsubscribeMap[contextName]; + } + this.currentlySubscribedChannels = this.currentlySubscribedChannels.filter((channel) => channel !== name); + } + } + class SharedContextSubscriber extends BaseSharedContextSubscriber { + async switchChannel(name) { + this.unsubscribe(); + const contextName = this.createContextName(name); + this.unsubscribeFunc = await this.contexts.subscribe(contextName, (data, _, __, ___, extraData) => { + if (this.callback) { + this.callback(data.data, data, extraData === null || extraData === void 0 ? void 0 : extraData.updaterId); + } + }); + } + async leave() { + if (this.callback) { + this.callback({}, undefined); + } + this.unsubscribe(); + } + unsubscribe() { + if (this.unsubscribeFunc) { + this.unsubscribeFunc(); + this.unsubscribeFunc = undefined; + } + } + } + + const validateFdc3Options = (options) => { + if (typeof options !== "object" || Array.isArray(options)) { + throw new Error(`Provide options as an object`); + } + if (options.contextType && (typeof options.contextType !== "string" || !options.contextType.length)) { + throw new Error(`Provide options.contextType as a non-empty string`); + } + }; + + class ChannelsImpl { + constructor(interop, getWindowsAPI, getAppManagerAPI, logger) { + this.interop = interop; + this.getWindowsAPI = getWindowsAPI; + this.getAppManagerAPI = getAppManagerAPI; + this.logger = logger; + this.subsKey = "subs"; + this.changedKey = "changed"; + this.channelsChangedKey = "channelsChanged"; + this.isInitialJoin = true; + this.registry = CallbackRegistryFactory(); + this.pendingReplays = {}; + this.pendingRestrictionCallbacks = new Map(); + } + async getMyChannels(options) { + if (!this.currentChannelID) { + return Promise.resolve([]); + } + if (this.currentChannelID.all().length === 0) { + return Promise.resolve([]); + } + const result = []; + for (const channel of this.currentChannelID.all()) { + result.push(await this.get(channel, options)); + } + return result; + } + async init(shared, mode, initial) { + this.mode = mode; + this.shared = shared; + this.shared.subscribe(this.handler.bind(this)); + this.subscribeForChannelRestrictionsChange(); + let initialChannel = initial; + if (typeof window !== "undefined" && typeof window.glue42gd !== "undefined") { + initialChannel = window.glue42gd.initialChannel; + } + this.currentChannelID = this.getID(initialChannel); + this.logger.trace(`initialized with mode: "${mode}" and initial channel: "${initialChannel}"`); + if (this.currentChannelID.isJoinedToAnyChannel) { + this.logger.trace(`joining initial channel: "${this.currentChannelID.toString()}"`); + await this.joinNoSelectorSwitch(this.currentChannelID.toString()); + } + } + subscribe(callback, options) { + if (typeof callback !== "function") { + throw new Error("Please provide the callback as a function!"); + } + const id = Utils.generateId(); + this.pendingReplays[id] = true; + const wrappedCallback = (options === null || options === void 0 ? void 0 : options.contextType) + ? this.getWrappedSubscribeCallbackWithFdc3Type(callback, id, options.contextType) + : this.getWrappedSubscribeCallback(callback, id); + if (this.lastUpdate) { + let lastUpdate = Object.assign({}, this.lastUpdate); + setTimeout(async () => { + if (this.pendingReplays[id]) { + if (this.lastUpdate) { + lastUpdate = this.lastUpdate; + } + wrappedCallback(lastUpdate.context.data, lastUpdate.context, lastUpdate.updaterId); + } + delete this.pendingReplays[id]; + }, 0); + } + const unsub = this.registry.add(this.subsKey, wrappedCallback); + return () => { + this.pendingReplays[id] = false; + this.pendingRestrictionCallbacks.delete(id); + unsub(); + }; + } + async subscribeFor(name, callback, options) { + if (typeof name !== "string") { + throw new Error("Please provide the name as a string!"); + } + if (typeof callback !== "function") { + throw new Error("Please provide the callback as a function!"); + } + const id = Utils.generateId(); + const wrappedCallback = (options === null || options === void 0 ? void 0 : options.contextType) + ? this.getWrappedSubscribeCallbackWithFdc3Type(callback, id, options.contextType) + : this.getWrappedSubscribeCallback(callback, id); + const unsub = await this.shared.subscribeFor(name, wrappedCallback); + return () => { + this.pendingRestrictionCallbacks.delete(id); + unsub(); + }; + } + async publish(data, options) { + if (typeof data !== "object") { + throw new Error("Please provide the data as an object!"); + } + if (options) { + this.validatePublishOptions(options); + } + if (typeof options === "object") { + return this.publishWithOptions(data, options); + } + const channelName = typeof options === "string" ? options : this.currentChannelID.toString(); + if (!channelName) { + throw new Error("Not joined to any channel!"); + } + if (!this.shared.isChannel(channelName)) { + return Promise.reject(new Error(`A channel with name: ${channelName} doesn't exist!`)); + } + if (this.mode === "multi") { + const channelsToPublish = new MultiChannelId(channelName).all(); + const restrictedChannels = []; + for (const cn of channelsToPublish) { + const canPublish = (await this.getRestrictionsByChannel(cn)).write; + if (!canPublish) { + restrictedChannels.push(cn); + continue; + } + await this.shared.updateData(cn, data); + } + if (restrictedChannels.length > 0) { + const restrictedChannelsErr = `Unable to publish due to restrictions to the following channels: ${restrictedChannels.join(", ")}`; + if (restrictedChannels.length === channelsToPublish.length) { + throw new Error(restrictedChannelsErr); + } + else { + this.logger.warn(restrictedChannelsErr); + } + } + } + else { + const canPublish = (await this.getRestrictionsByChannel(channelName)).write; + if (!canPublish) { + throw new Error(`Window does not have permission to write to channel ${channelName}`); + } + return this.shared.updateData(channelName, data); + } + } + async setPaths(paths, name) { + if (name) { + if (typeof name !== "string") { + throw new Error("Please provide the name as a string!"); + } + if (!this.shared.isChannel(name)) { + return Promise.reject(new Error(`A channel with name: ${name} doesn't exist!`)); + } + if (!(await this.getRestrictionsByChannel(name)).write) { + throw new Error(`Window does not have permission to write to channel ${name}`); + } + return this.shared.setPaths(name, paths); + } + if (!this.currentChannelID) { + throw new Error("Not joined to any channel!"); + } + if (!(await this.getRestrictionsByChannel(this.currentChannelID.toString())).write) { + throw new Error(`Window does not have permission to write to channel ${this.currentChannelID.toString()}`); + } + if (!Array.isArray(paths)) { + throw new Error("Path Values argument is not a valid array"); + } + paths.forEach((path) => { + this.validatePathArgs(path); + }); + return this.shared.setPaths(this.currentChannelID.toString(), paths); + } + async setPath(path, name) { + if (name) { + if (typeof name !== "string") { + throw new Error("Please provide the name as a string!"); + } + if (!this.shared.isChannel(name)) { + return Promise.reject(new Error(`A channel with name: ${name} doesn't exist!`)); + } + if (!(await this.getRestrictionsByChannel(name)).write) { + throw new Error(`Window does not have permission to write to channel ${name}`); + } + return this.shared.setPaths(name, [path]); + } + if (!this.currentChannelID) { + throw new Error("Not joined to any channel!"); + } + if (!(await this.getRestrictionsByChannel(this.currentChannelID.toString())).write) { + throw new Error(`Window does not have permission to write to channel ${this.currentChannelID.toString()}`); + } + this.validatePathArgs(path); + return this.shared.setPaths(this.currentChannelID.toString(), [path]); + } + all() { + const channelNames = this.shared.all(); + return Promise.resolve(channelNames); + } + async list() { + const channelNames = await this.all(); + const channelContexts = await Promise.all(channelNames.map((channelName) => this.get(channelName))); + return channelContexts; + } + async get(name, options) { + if (typeof name !== "string") { + return Promise.reject(new Error("Please provide the channel name as a string!")); + } + if (!(options === null || options === void 0 ? void 0 : options.contextType)) { + return this.shared.getContextData(name); + } + validateFdc3Options(options); + const context = await this.shared.getContextData(name); + return this.getContextWithFdc3Type(context, options.contextType); + } + getMy(options) { + if (!this.currentChannelID) { + return Promise.resolve(undefined); + } + if (this.currentChannelID.all().length === 0) { + return Promise.resolve(undefined); + } + return this.get(this.currentChannelID.all()[0], options); + } + async join(name, windowId) { + if (windowId !== undefined && windowId !== null) { + this.validateWindowIdArg(windowId); + this.logger.trace(`joining channel ${name} for window: ${windowId}`); + return sendSwitchChannelUI(name, windowId); + } + return this.joinCore(name); + } + async joinNoSelectorSwitch(channelName) { + this.logger.trace(`joining channel "${channelName}" from command`); + return this.joinCore(channelName, false); + } + leave(options) { + this.logger.trace(`leaving channel with options: ${JSON.stringify(options)}`); + let windowId; + let channelName; + if (typeof options === "string") { + windowId = options; + } + else if (typeof options === "object" && !Array.isArray(options) && options !== null && options !== undefined) { + if (options.windowId) { + windowId = options.windowId; + } + if (options.channel) { + channelName = options.channel; + } + } + if (this.mode === "multi") { + return this.leaveWhenMulti(channelName, windowId); + } + else { + return this.leaveWhenSingle(channelName, windowId); + } + } + leaveNoSelectorSwitch(channelName) { + this.logger.trace(`leaving channel "${channelName}" from command`); + return this.leaveCore(false, channelName); + } + current() { + return this.currentChannelID.toString(); + } + my() { + return this.current(); + } + myChannels() { + var _a; + return (_a = this.currentChannelID.all()) !== null && _a !== void 0 ? _a : []; + } + onChannelsChanged(callback) { + if (typeof callback !== "function") { + throw new Error("Please provide the callback as a function!"); + } + let timeoutId; + const current = this.current(); + if (current) { + timeoutId = setTimeout(() => { + callback(this.myChannels()); + }, 0); + } + const un = this.registry.add(this.channelsChangedKey, callback); + return () => { + un(); + clearTimeout(timeoutId); + }; + } + changed(callback) { + if (typeof callback !== "function") { + throw new Error("Please provide the callback as a function!"); + } + const current = this.current(); + if (current) { + setTimeout(() => { + callback(this.current()); + }, 0); + } + return this.registry.add(this.changedKey, () => { + callback(this.current()); + }); + } + onChanged(callback) { + return this.changed(callback); + } + async add(info) { + var _a; + if (typeof info !== "object") { + throw new Error("Please provide the info as an object!"); + } + if (typeof info.name === "undefined") { + throw new Error("info.name is missing!"); + } + if (typeof info.name !== "string") { + throw new Error("Please provide the info.name as a string!"); + } + if (typeof info.meta === "undefined") { + throw new Error("info.meta is missing!"); + } + if (typeof info.meta !== "object") { + throw new Error("Please provide the info.meta as an object!"); + } + if (typeof info.meta.color === "undefined") { + throw new Error("info.meta.color is missing!"); + } + if (typeof info.meta.color !== "string") { + throw new Error("Please provide the info.meta.color as a string!"); + } + const context = { + name: info.name, + meta: info.meta || {}, + data: info.data || {} + }; + this.logger.trace(`adding channel: ${info.name}`); + await addOrRemoveChannel("addChannel", info.name, info.meta.color, (_a = info.meta) === null || _a === void 0 ? void 0 : _a.label); + await this.shared.updateChannel(info.name, context); + return context; + } + async remove(channel) { + if (typeof channel !== "string") { + throw new Error("Please provide the channel name as a string!"); + } + this.logger.trace(`removing channel: ${channel}`); + await this.shared.remove(channel); + await addOrRemoveChannel("removeChannel", channel); + } + async getWindowsOnChannel(channel) { + this.validateChannelArg(channel); + const windowInfos = await this.getWindowsWithChannels({ channels: [channel] }); + return windowInfos.map((w) => w.window); + } + async getWindowsWithChannels(filter) { + this.validateWindowsWithChannelsFilter(filter); + try { + const info = await getChannelsInfo(filter); + const windowsAPI = this.getWindowsAPI(); + if (info === null || info === void 0 ? void 0 : info.windows) { + return info.windows.reduce((memo, windowInfo) => { + const window = windowsAPI.findById(windowInfo.windowId); + memo.push({ + window, + channel: windowInfo.channel, + application: windowInfo.application + }); + return memo; + }, []); + } + } + catch (er) { + this.logger.error(`Error getting all channel enabled windows. This method is available since Glue42 3.12`, er); + } + return []; + } + async restrict(restriction) { + this.validateRestrictionConfig(restriction); + return setRestrictions(restriction); + } + async getRestrictions(windowId) { + if (windowId) { + this.validateWindowIdArg(windowId); + } + return getRestrictionsByWindow(windowId); + } + async restrictAll(restriction) { + this.validateRestrictionConfig(restriction); + return setRestrictionsForAllChannels(restriction); + } + handleRestrictionsChanged(restrictions, windowId) { + this.registry.execute("restrictions-changed", { + restrictions, + windowId + }); + } + async clearChannelData(channel) { + const channelName = typeof channel === "string" ? channel : this.currentChannelID.toString(); + if (!channelName) { + return; + } + if (!this.shared.isChannel(channelName)) { + return; + } + const canPublish = (await this.getRestrictionsByChannel(channelName)).write; + if (!canPublish) { + return; + } + return this.shared.clearContextData(channelName); + } + handler(data, context, updaterId) { + if (!context && !updaterId) { + this.lastUpdate = undefined; + return; + } + this.lastUpdate = { context, updaterId }; + this.pendingReplays = {}; + this.registry.execute(this.subsKey, data, context, updaterId); + } + async joinCore(name, changeSelector = true) { + this.logger.trace(`joining channel "${name}" ${changeSelector ? "" : "from command"}`); + if (typeof name !== "string") { + throw new Error("Please provide the channel name as a string!"); + } + const newId = this.getID(name); + if (!this.isInitialJoin && this.currentChannelID.isOnChannel(newId.toString())) { + this.logger.trace(`already on channel: "${name}" ${changeSelector ? "" : "from command"}`); + return; + } + this.isInitialJoin = false; + await Promise.all(newId.all().map((n) => this.verifyChannelExists(n))); + this.currentChannelID.joinChannel(name); + this.lastUpdate = undefined; + this.logger.trace(`switching channel context to: "${name}" ${changeSelector ? "" : "from command"}`); + await this.shared.switchChannel(this.currentChannelID.toString()); + if (changeSelector) { + this.logger.trace(`switching UI channel to: "${name}" ${changeSelector ? "" : "from command"}`); + await sendSwitchChannelUI(name); + this.logger.trace(`switched UI channel to: "${name}" ${changeSelector ? "" : "from command"}`); + } + this.raiseChannelsChangedEvents(); + this.logger.trace(`joined channel: ${name} ${changeSelector ? "" : "from command"} - current channel/s: ${this.currentChannelID.toString()}`); + } + async verifyChannelExists(name) { + const doesChannelExist = (channelName) => { + const channelNames = this.shared.all(); + return channelNames.includes(channelName); + }; + if (!doesChannelExist(name)) { + const channelExistsPromise = new Promise((resolve, reject) => { + const intervalId = setInterval(() => { + if (doesChannelExist(name)) { + clearTimeout(timeoutId); + clearInterval(intervalId); + resolve(); + } + }, 100); + const timeoutId = setTimeout(() => { + clearInterval(intervalId); + return reject(new Error(`A channel with name: ${name} doesn't exist!`)); + }, 3000); + }); + await channelExistsPromise; + } + } + async leaveCore(changeSelector = true, channelID) { + if (!this.currentChannelID.isJoinedToAnyChannel) { + this.logger.trace(`leave called ${changeSelector ? "" : "from command"} when not joined to any channel change selector`); + return; + } + if (channelID && !this.currentChannelID.isOnChannel(channelID)) { + this.logger.trace(`leave called ${changeSelector ? "" : "from command"} when not joined to channel: "${channelID}"`); + return; + } + this.logger.trace(`leaving context channel: "${channelID}" ${changeSelector ? "" : "from command"}`); + this.currentChannelID.leaveChannel(channelID); + await this.shared.leave(channelID); + this.lastUpdate = undefined; + this.raiseChannelsChangedEvents(); + if (changeSelector) { + this.logger.trace(`switching UI channel to: "${channelID}" ${changeSelector ? "" : "from command"}`); + await sendSwitchChannelUI(this.currentChannelID.toString()); + this.logger.trace(`switched UI channel to: "${channelID}" ${changeSelector ? "" : "from command"}`); + } + this.logger.trace(`left single channel: "${channelID}" ${changeSelector ? "" : "from command"} - current channel/s: "${this.currentChannelID.toString()}"`); + return Promise.resolve(); + } + async leaveCoreMulti(changeSelector = true, channelID) { + this.logger.trace(`leaving multi channel: "${channelID.toString()}" ${changeSelector ? "" : "from command"}`); + const currentChannels = this.currentChannelID.all(); + const isJoinedToChannel = currentChannels.some((c) => channelID.isOnChannel(c)); + if (!isJoinedToChannel || !this.currentChannelID.isJoinedToAnyChannel) { + this.logger.trace(`leave called ${changeSelector ? "" : "from command"} when not joined to any channel`); + return; + } + const channelName = channelID.toString(); + this.currentChannelID.leaveChannel(channelName); + await this.shared.leave(channelName); + this.lastUpdate = undefined; + this.raiseChannelsChangedEvents(); + if (changeSelector) { + this.logger.trace(`switching UI channel to: "${channelName}" ${changeSelector ? "" : "from command"}`); + await sendLeaveChannel(channelName); + this.logger.trace(`switched UI channel to: "${channelName}" ${changeSelector ? "" : "from command"}`); + } + this.logger.trace(`left multi channel: "${channelName}" ${changeSelector ? "" : "from command"} - current channel/s: ${this.currentChannelID.toString()}`); + return Promise.resolve(); + } + raiseChannelsChangedEvents() { + this.registry.execute(this.changedKey, this.currentChannelID.toString()); + this.registry.execute(this.channelsChangedKey, this.currentChannelID.all()); + } + async getRestrictionsByChannel(channelName) { + var _a; + const restrictions = (_a = this.channelRestrictions) !== null && _a !== void 0 ? _a : await getRestrictionsByWindow(); + if (!restrictions || !Array.isArray(restrictions.channels) || !restrictions.channels.find(c => c.name === channelName)) { + return { + read: true, + write: true + }; + } + const byChannel = restrictions.channels.find(c => c.name === channelName); + return byChannel; + } + onRestrictionsChanged(callback, callbackId, currentChannelName) { + this.pendingRestrictionCallbacks.set(callbackId, { + cb: callback, + channelName: currentChannelName + }); + if (this.onRestrictionsChangedSub) { + return; + } + this.onRestrictionsChangedSub = this.registry.add("restrictions-changed", ({ restrictions }) => { + this.logger.trace(`restrictions changed - ${JSON.stringify(restrictions)}`); + this.pendingRestrictionCallbacks.forEach(({ cb, channelName }, id) => { + const currentChannel = restrictions.channels.find((c) => c.name === channelName); + if (!currentChannel) { + this.logger.trace(`channel "${channelName}" not found in restrictions`); + return; + } + if (currentChannel.read) { + this.pendingRestrictionCallbacks.delete(id); + if (this.pendingRestrictionCallbacks.values.length === 0 && this.onRestrictionsChangedSub) { + this.onRestrictionsChangedSub(); + this.onRestrictionsChangedSub = null; + } + cb(); + } + }); + }); + } + subscribeForChannelRestrictionsChange() { + this.registry.add("restrictions-changed", (r) => { + this.logger.trace(`channel restrictions changed - ${JSON.stringify(r.restrictions)}`); + this.channelRestrictions = r.restrictions; + }); + } + validatePathArgs(path) { + if (!path) { + throw new Error("Please provide a valid path value argument"); + } + if (typeof path !== "object") { + throw new Error(`Path Value argument is not a valid object: ${JSON.stringify(path)}`); + } + if (!path.path) { + throw new Error(`path property is missing from Path Value argument: ${JSON.stringify(path)}`); + } + if (!path.value) { + throw new Error(`value property is missing from Path Value argument: ${JSON.stringify(path)}`); + } + if (typeof path.path !== "string") { + throw new Error(`path property is not a valid string from the Path Value argument: ${JSON.stringify(path)}`); + } + } + validatePublishOptions(options) { + if ((typeof options !== "string" && typeof options !== "object") || Array.isArray(options)) { + throw new Error("Provide options as a string or an object"); + } + if (typeof options === "object") { + this.validatePublishOptionsObject(options); + return; + } + if (options === "string" && !options.length) { + throw new Error("Provide options as a non-empty string"); + } + } + validatePublishOptionsObject(options) { + if (typeof options !== "object" || Array.isArray(options)) { + throw new Error("Provide options as an object"); + } + if (options.name && (typeof options.name !== "string" || !options.name.length)) { + throw new Error("Provide options.name as a non-empty string"); + } + if (Object.keys(options).includes("fdc3") && typeof options.fdc3 !== "boolean") { + throw new Error("Provide options.fdc3 as a boolean"); + } + } + async publishWithOptions(data, options) { + const channelName = options.name || this.currentChannelID.toString(); + if (!this.shared.isChannel(channelName)) { + throw new Error(`A channel with name: ${options.name} doesn't exist!`); + } + if (!channelName) { + throw new Error("Cannot publish to channel, because not joined to a channel!"); + } + const canPublish = (await this.getRestrictionsByChannel(channelName)).write; + if (!canPublish) { + throw new Error(`Window does not have permission to write to channel ${this.currentChannelID.toString()}`); + } + if (!options.fdc3) { + return this.shared.updateData(channelName, data); + } + return this.publishFdc3Data(channelName, data); + } + async publishFdc3Data(channelName, data) { + var _a; + if (typeof data.type !== "string" || !((_a = data.type) === null || _a === void 0 ? void 0 : _a.length)) { + throw new Error("Expected a valid FDC3 Context with compulsory 'type' field"); + } + const { type, ...rest } = data; + const parsedType = type.split(".").join("&"); + const fdc3DataToPublish = { [`fdc3_${parsedType}`]: rest }; + return this.shared.updateData(channelName, fdc3DataToPublish); + } + getWrappedSubscribeCallback(callback, id) { + const wrappedCallback = async (_, context, updaterId) => { + const restrictionByChannel = await this.getRestrictionsByChannel(context.name); + const channelData = this.getDataWithFdc3Encoding(context); + if (restrictionByChannel.read) { + callback(channelData, context, updaterId); + } + else { + this.onRestrictionsChanged(() => { + callback(channelData, context, updaterId); + }, id, context.name); + } + }; + return wrappedCallback; + } + getWrappedSubscribeCallbackWithFdc3Type(callback, id, fdc3Type) { + const didReplay = { replayed: false }; + const wrappedCallback = async (_, context, updaterId) => { + const restrictionByChannel = await this.getRestrictionsByChannel(context.name); + const callbackWithTypesChecks = () => { + const { data, latest_fdc3_type } = context; + const searchedType = `fdc3_${fdc3Type.split(".").join("&")}`; + if (!data[searchedType]) { + return; + } + if (didReplay.replayed) { + return this.parseDataAndInvokeSubscribeCallback({ latestFdc3TypeEncoded: latest_fdc3_type, searchedType: fdc3Type, callback, context, updaterId }); + } + const fdc3Data = { type: fdc3Type, ...data[searchedType] }; + callback({ fdc3: fdc3Data }, context, updaterId); + didReplay.replayed = true; + }; + if (restrictionByChannel.read) { + callbackWithTypesChecks(); + return; + } + this.onRestrictionsChanged(callbackWithTypesChecks, id, context.name); + }; + return wrappedCallback; + } + parseDataAndInvokeSubscribeCallback(args) { + const { latestFdc3TypeEncoded, searchedType, callback, context, updaterId } = args; + const latestPublishedType = latestFdc3TypeEncoded.split("&").join("."); + if (latestPublishedType !== searchedType) { + return; + } + const fdc3Data = { type: searchedType, ...context.data[`fdc3_${latestFdc3TypeEncoded}`] }; + callback({ fdc3: fdc3Data }, context, updaterId); + } + getContextWithFdc3Type(context, searchedType) { + var _a, _b; + if (((_b = (_a = context.data) === null || _a === void 0 ? void 0 : _a.fdc3) === null || _b === void 0 ? void 0 : _b.type) === searchedType) { + return { + name: context.name, + meta: context.meta, + data: { fdc3: context.data.fdc3 } + }; + } + const encodedType = `fdc3_${searchedType.split(".").join("&")}`; + if (!context.data[encodedType]) { + return { + name: context.name, + meta: context.meta, + data: {} + }; + } + const fdc3Context = { type: searchedType, ...context.data[encodedType] }; + return { + name: context.name, + meta: context.meta, + data: { fdc3: fdc3Context } + }; + } + getDataWithFdc3Encoding(context) { + const { data, latest_fdc3_type } = context; + if (!latest_fdc3_type) { + return data; + } + const parsedType = latest_fdc3_type.split("&").join("."); + const latestTypePropName = `fdc3_${latest_fdc3_type}`; + const fdc3Data = { type: parsedType, ...data[latestTypePropName] }; + const { [latestTypePropName]: latestFDC3Type, ...rest } = data; + return { ...rest, fdc3: fdc3Data }; + } + getID(id) { + if (this.mode === "multi") { + return new MultiChannelId(id); + } + else { + return new SingleChannelID(id); + } + } + leaveWhenSingle(channelName, windowId) { + if (windowId) { + this.logger.trace(`leaving single channel "${channelName}" for window: "${windowId}"`); + return sendSwitchChannelUI(undefined, windowId); + } + this.logger.trace(`leaving single channel "${channelName}" for our window`); + return this.leaveCore(true, channelName); + } + async leaveWhenMulti(channelName, windowId) { + if (windowId) { + this.logger.trace(`leaving multi channel "${channelName}" for window: "${windowId}"`); + return sendLeaveChannel(channelName, windowId); + } + else { + const channelId = channelName ? new MultiChannelId(channelName) : this.currentChannelID; + this.logger.trace(`leaving multi channel "${channelId.toString()}" for our window`); + return this.leaveCoreMulti(true, channelId); + } + } + validateWindowIdArg(windowId) { + if (typeof windowId !== "string") { + throw new Error("The window ID must be a non-empty string!"); + } + const windows = this.getWindowsAPI(); + if (!windows.findById(windowId)) { + throw new Error(`Window with ID "${windowId}" doesn't exist!`); + } + } + validateChannelArg(channel) { + if (!channel) { + throw new Error("Please provide a valid Channel name as a non-empty string!"); + } + if (typeof channel !== "string") { + throw new Error("The Channel name must be a non-empty string!"); + } + const channelNames = this.shared.all(); + if (channelNames.every((name) => name !== channel)) { + throw new Error(`Channel "${channel}" does not exist!"`); + } + } + validateWindowsWithChannelsFilter(filter) { + if (filter === undefined) { + return; + } + if (filter === null || Array.isArray(filter) || typeof filter !== "object") { + throw new Error("The `filter` argument must be a valid object!"); + } + } + isRestrictions(restriction) { + return 'name' in restriction; + } + validateRestrictionConfig(restriction) { + if (restriction === null || restriction === undefined || Array.isArray(restriction) || typeof restriction !== "object") { + throw new Error("The `restrictions` argument must be a valid object with Channel restrictions!"); + } + if (this.isRestrictions(restriction) && typeof restriction.name !== "string") { + throw new Error("The `name` restriction property must be a non-empty string!"); + } + if (restriction.read !== null && restriction.read !== undefined && typeof restriction.read !== "boolean") { + throw new Error("The `read` restriction property must be a boolean value!"); + } + if (restriction.write !== null && restriction.write !== undefined && typeof restriction.write !== "boolean") { + throw new Error("The `write` restriction property must be a boolean value!"); + } + if ((restriction.read === null || restriction.read === undefined) && (restriction.write === null || restriction.write === undefined)) { + throw new Error("It's required to set either the `read` or the `write` property of the Channel restriction object!"); + } + if (restriction.windowId !== null && restriction.windowId !== undefined) { + this.validateWindowIdArg(restriction.windowId); + } + } + } + + function factory$4(config, contexts, agm, getWindowsAPI, getAppManagerAPI, logger) { + const channelsReadyPromise = getChannelInitInfo(config, agm) + .then(async ({ mode, initialChannel }) => { + const sharedContexts = mode === "single" ? new SharedContextSubscriber(contexts) : new MultiSharedContextSubscriber(contexts); + if (mode === "multi") { + logger.info(`multi-channel mode enabled`); + } + await channels.init(sharedContexts, mode, initialChannel); + await setupInterop(agm, channels, logger); + return true; + }); + const channels = new ChannelsImpl(agm, getWindowsAPI, getAppManagerAPI, logger); + return { + subscribe: channels.subscribe.bind(channels), + subscribeFor: channels.subscribeFor.bind(channels), + publish: channels.publish.bind(channels), + setPath: channels.setPath.bind(channels), + setPaths: channels.setPaths.bind(channels), + all: channels.all.bind(channels), + list: channels.list.bind(channels), + get: channels.get.bind(channels), + join: channels.join.bind(channels), + leave: channels.leave.bind(channels), + restrict: channels.restrict.bind(channels), + getRestrictions: channels.getRestrictions.bind(channels), + clearChannelData: channels.clearChannelData.bind(channels), + restrictAll: channels.restrictAll.bind(channels), + current: channels.current.bind(channels), + my: channels.my.bind(channels), + changed: channels.changed.bind(channels), + onChanged: channels.onChanged.bind(channels), + add: channels.add.bind(channels), + remove: channels.remove.bind(channels), + getWindowsOnChannel: channels.getWindowsOnChannel.bind(channels), + getWindowsWithChannels: channels.getWindowsWithChannels.bind(channels), + getMy: channels.getMy.bind(channels), + ready: async () => { + await Promise.all([contexts.ready(), channelsReadyPromise]); + }, + get mode() { return channels.mode; }, + getMyChannels: channels.getMyChannels.bind(channels), + myChannels: channels.myChannels.bind(channels), + onChannelsChanged: channels.onChannelsChanged.bind(channels), + }; + } + + const CommandMethod = "T42.Hotkeys.Command"; + const InvokeMethod = "T42.Hotkeys.Invoke"; + const RegisterCommand = "register"; + const UnregisterCommand = "unregister"; + const UnregisterAllCommand = "unregisterAll"; + class HotkeysImpl { + constructor(agm) { + this.agm = agm; + this.registry = CallbackRegistryFactory(); + this.firstHotkey = true; + this.hotkeys = new Map(); + } + async register(info, callback) { + if (typeof info === "undefined") { + throw new Error("Hotkey parameter missing"); + } + if (typeof info === "string") { + info = { + hotkey: info + }; + } + else { + if (!info.hotkey) { + throw new Error("Info's hotkey parameter missing"); + } + info = { + hotkey: info.hotkey, + description: info.description + }; + } + const hkToLower = this.formatHotkey(info.hotkey); + if (this.hotkeys.has(hkToLower)) { + throw new Error(`Shortcut for ${hkToLower} already registered`); + } + if (this.firstHotkey) { + this.firstHotkey = false; + await this.registerInvokeAGMMethod(); + } + this.registry.add(hkToLower, callback); + await this.agm.invoke(CommandMethod, { command: RegisterCommand, hotkey: hkToLower, description: info.description }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + this.hotkeys.set(hkToLower, info); + } + async unregister(hotkey) { + if (typeof hotkey === "undefined") { + throw new Error("hotkey parameter missing"); + } + if (typeof hotkey !== "string") { + throw new Error("hotkey parameter must be string"); + } + const hkToLower = this.formatHotkey(hotkey); + await this.agm.invoke(CommandMethod, { command: UnregisterCommand, hotkey: hkToLower }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + this.hotkeys.delete(hkToLower); + this.registry.clearKey(hkToLower); + } + async unregisterAll() { + await this.agm.invoke(CommandMethod, { command: UnregisterAllCommand }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + this.hotkeys.clear(); + this.registry.clear(); + } + isRegistered(hotkey) { + const hkToLower = this.formatHotkey(hotkey); + return this.hotkeys.has(hkToLower); + } + registerInvokeAGMMethod() { + return this.agm.register(InvokeMethod, (args) => { + const hkToLower = args.key.toLowerCase(); + const info = this.hotkeys.get(hkToLower); + this.registry.execute(hkToLower, info); + }); + } + formatHotkey(hotkey) { + if (hotkey) { + return hotkey.replace(/\s/g, "").toLowerCase(); + } + } + } + + function factory$3(agm) { + const hotkeys = new HotkeysImpl(agm); + return { + register: hotkeys.register.bind(hotkeys), + unregister: hotkeys.unregister.bind(hotkeys), + unregisterAll: hotkeys.unregisterAll.bind(hotkeys), + isRegistered: hotkeys.isRegistered.bind(hotkeys), + ready: () => Promise.resolve() + }; + } + + var version = "6.12.0"; + + var prepareConfig = (options) => { + function getLibConfig(value, defaultMode, trueMode) { + if (typeof value === "boolean" && !value) { + return undefined; + } + const mode = getModeAsString(value, defaultMode, trueMode); + if (typeof mode === "undefined") { + return undefined; + } + if (typeof value === "object") { + value.mode = mode; + return value; + } + return { + mode, + }; + } + function getModeAsString(value, defaultMode, trueMode) { + if (typeof value === "object") { + return getModeAsString(value.mode, defaultMode, trueMode).toString(); + } + else if (typeof value === "undefined") { + if (typeof defaultMode === "boolean" && !defaultMode) { + return undefined; + } + else if (typeof defaultMode === "boolean" && defaultMode) { + return typeof trueMode === "undefined" ? defaultMode : trueMode; + } + else if (typeof defaultMode === "undefined") { + return undefined; + } + else { + return defaultMode; + } + } + else if (typeof value === "boolean") { + if (value) { + return (typeof trueMode === "undefined") ? defaultMode : trueMode; + } + else { + return undefined; + } + } + return value; + } + const appDefaultMode = true; + const appDefaultTrueMode = "startOnly"; + const activitiesDefaultMode = Utils.isNode() ? false : "trackMyTypeAndInitiatedFromMe"; + const activitiesTrueMode = "trackMyTypeAndInitiatedFromMe"; + const layoutsDefaultMode = "slim"; + const layoutsTrueMode = layoutsDefaultMode; + const channelsConfig = () => { + if (typeof options.channels === "boolean") { + return options.channels; + } + else if (typeof options.channels === "object" && typeof options.channels.enabled === "boolean" && options.channels.enabled) { + return { mode: true, ...options.channels }; + } + else { + return false; + } + }; + const exposeAPI = typeof options.exposeAPI === "boolean" || typeof options.exposeGlue === "boolean"; + return { + layouts: getLibConfig(options.layouts, layoutsDefaultMode, layoutsTrueMode), + activities: getLibConfig(options.activities, activitiesDefaultMode, activitiesTrueMode), + appManager: getLibConfig(options.appManager, appDefaultMode, appDefaultTrueMode), + windows: getLibConfig(options.windows, true, true), + channels: getLibConfig(channelsConfig(), false, true), + displays: getLibConfig(options.displays, true, true), + exposeAPI: exposeAPI ? exposeAPI : true + }; + }; + + class Glue42Notification { + constructor(options) { + this.options = options; + this.callbacks = CallbackRegistryFactory(); + this.actions = options.actions; + this.body = options.body; + this.badge = options.badge; + this.data = options.data; + this.dir = options.dir; + this.icon = options.icon; + this.image = options.image; + this.lang = options.lang; + this.renotify = options.renotify; + this.requireInteraction = options.requireInteraction; + this.silent = options.silent; + this.tag = options.tag; + this.timestamp = options.timestamp; + this.title = options.title; + } + close() { + throw new Error("Method not implemented."); + } + addEventListener(type, listener, options) { + this.callbacks.add(type, listener); + } + removeEventListener(type, listener, options) { + } + dispatchEvent(event) { + this.callbacks.execute(event.type, event); + return true; + } + } + + class PanelAPI { + constructor(interop, onStreamEvent) { + this.interop = interop; + this.onStreamEvent = onStreamEvent; + } + onVisibilityChanged(callback) { + return this.onStreamEvent("on-panel-visibility-changed", callback); + } + toggle() { + return this.interop.invoke("T42.Notifications.Show", undefined, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + show() { + return this.interop.invoke("T42.Notifications.Show", { show: true }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + hide() { + return this.interop.invoke("T42.Notifications.Hide"); + } + async isVisible() { + const interopResult = await this.interop.invoke("T42.Notifications.Execute", { command: "isPanelVisible" }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return interopResult.returned.panelVisible; + } + toAPI() { + return { + onVisibilityChanged: this.onVisibilityChanged.bind(this), + toggle: this.toggle.bind(this), + show: this.show.bind(this), + hide: this.hide.bind(this), + isVisible: this.isVisible.bind(this) + }; + } + } + + const STARTING_INDEX = 0; + class Notifications { + constructor(interop, logger) { + this.interop = interop; + this.NotificationsSubscribeStream = "T42.GNS.Subscribe.Notifications"; + this.NotificationsCounterStream = "T42.Notifications.Counter"; + this.RaiseNotificationMethodName = "T42.GNS.Publish.RaiseNotification"; + this.NotificationsExecuteMethod = "T42.Notifications.Execute"; + this.NotificationFilterMethodName = "T42.Notifications.Filter"; + this.methodsRegistered = false; + this.NOTIFICATIONS_CONFIGURE_METHOD_NAME = "T42.Notifications.Configure"; + this.methodNameRoot = "T42.Notifications.Handler-" + Utils.generateId(); + this.nextId = 0; + this.notifications = {}; + this.registry = CallbackRegistryFactory(); + this.subscribedForNotifications = false; + this.subscribedCounterStream = false; + this.subscriptionsCountForNotifications = 0; + this.subscriptionsCountForCounter = 0; + this.logger = logger.subLogger("notifications"); + this._panel = new PanelAPI(interop, this.onStreamEventCore.bind(this)); + this._panelAPI = this._panel.toAPI(); + this.subscribeInternalEvents(); + } + get maxActions() { + return 10; + } + get panel() { + return this._panelAPI; + } + async raise(options) { + var _a; + const notification = await this.createNotification(options); + const g42notification = new Glue42Notification(options); + this.notifications[notification.id] = g42notification; + try { + const invocationResult = await this.interop.invoke(this.RaiseNotificationMethodName, { notification }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + g42notification.id = (_a = invocationResult.returned) === null || _a === void 0 ? void 0 : _a.id; + } + catch (err) { + const errorMessage = err.message; + setTimeout(() => { + this.handleNotificationErrorEvent(g42notification, errorMessage); + }, 1); + } + return g42notification; + } + async setFilter(filter) { + const result = await this.interop.invoke(this.NotificationFilterMethodName, filter, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return result.returned; + } + async getFilter() { + const result = await this.interop.invoke(this.NotificationFilterMethodName, undefined, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return result.returned; + } + async configure(options) { + var _a, _b, _c, _d, _e, _f, _g, _h; + if (!options || Array.isArray(options)) { + throw new Error("Invalid options - should be an object."); + } + if (Object.values(options).length === 0) { + throw new Error("The argument must be a non-empty object."); + } + if (typeof options.enable !== "undefined" && typeof options.enable !== "boolean") { + throw new Error("Expected type of enabled - boolean."); + } + if (typeof options.enableToasts !== "undefined" && typeof options.enableToasts !== "boolean") { + throw new Error("Expected type of enableToasts - boolean."); + } + if (typeof options.toastExpiry !== "undefined" && typeof options.toastExpiry !== "number") { + throw new Error("Expected type of toastExpiry - number."); + } + if (options.sourceFilter && typeof options.sourceFilter !== "object") { + throw new Error("Expected type of sourceFilter - object."); + } + if (((_a = options.sourceFilter) === null || _a === void 0 ? void 0 : _a.allowed) && !Array.isArray((_b = options.sourceFilter) === null || _b === void 0 ? void 0 : _b.allowed)) { + throw new Error("Expected type of sourceFilter.allowed - array."); + } + if (((_c = options.sourceFilter) === null || _c === void 0 ? void 0 : _c.blocked) && !Array.isArray((_d = options.sourceFilter) === null || _d === void 0 ? void 0 : _d.blocked)) { + throw new Error("Expected type of sourceFilter.blocked - array."); + } + if (options.toasts && typeof options.toasts !== "object") { + throw new Error("Expected type of (options.toasts - object."); + } + if (((_e = options.toasts) === null || _e === void 0 ? void 0 : _e.mode) && typeof options.toasts.mode !== "string") { + throw new Error("Expected type of (options.toasts.mode - string."); + } + if (((_f = options.toasts) === null || _f === void 0 ? void 0 : _f.stackBy) && typeof options.toasts.stackBy !== "string") { + throw new Error("Expected type of (options.toasts.stackBy - string."); + } + if (options.placement && typeof options.placement !== "object") { + throw new Error("Expected type of (options.placement - object."); + } + if (((_g = options.placement) === null || _g === void 0 ? void 0 : _g.toasts) && typeof options.placement.toasts !== "string") { + throw new Error("Expected type of (options.placement.toasts - string."); + } + if (((_h = options.placement) === null || _h === void 0 ? void 0 : _h.panel) && typeof options.placement.panel !== "string") { + throw new Error("Expected type of (options.placement.panel - string."); + } + if (typeof options.closeNotificationOnClick !== "undefined" && typeof options.closeNotificationOnClick !== "boolean") { + throw new Error("Expected type of closeNotificationOnClick - boolean."); + } + const result = await this.interop.invoke(this.NOTIFICATIONS_CONFIGURE_METHOD_NAME, options, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return result.returned; + } + async getConfiguration() { + const result = await this.interop.invoke(this.NotificationsExecuteMethod, { command: "getConfiguration" }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return result.returned; + } + async list() { + const interopResult = await this.interop.invoke(this.NotificationsExecuteMethod, { + command: "list", + data: { statesVersion2: true } + }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return interopResult.returned.notifications; + } + async updateData(id, data) { + const replacer = (key, value) => typeof value === "undefined" ? null : value; + const attribute = { + key: "data", + value: { + stringValue: JSON.stringify(data, replacer) + } + }; + const interopResult = await this.interop.invoke(this.NotificationsExecuteMethod, { command: "create-or-update-attribute", data: { id, attribute } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return interopResult.returned; + } + onRaised(callback) { + return this.onStreamEventCore("on-notification-raised", callback); + } + onStateChanged(callback) { + return this.onStreamEventCore("on-state-changed", callback); + } + onClosed(callback) { + return this.onStreamEventCore("on-notification-closed", callback); + } + onConfigurationChanged(callback) { + if (typeof callback !== "function") { + throw new Error("Please provide the callback as a function!"); + } + this.subscribe(); + const un = this.registry.add("on-configuration-changed", callback); + return () => { + un(); + this.closeStreamSubscriptionIfNoNeeded(); + }; + } + onCounterChanged(callback) { + if (typeof callback !== "function") { + throw new Error("Please provide the callback as a function!"); + } + this.subscribeForCounterStream(); + const un = this.registry.add("on-counter-changed", callback); + return () => { + un(); + this.closeStreamCounterSubscriptionIfNoNeeded(); + }; + } + onDataChanged(callback) { + if (typeof callback !== "function") { + throw new Error("Please provide the callback as a function!"); + } + this.subscribe(); + const un = this.registry.add("on-notification-data-changed", callback); + return () => { + un(); + this.closeStreamSubscriptionIfNoNeeded(); + }; + } + async clearAll() { + await this.interop.invoke(this.NotificationsExecuteMethod, { command: "clearAll" }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async clearOld() { + await this.interop.invoke(this.NotificationsExecuteMethod, { command: "clearAllOld", data: { statesVersion2: true } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async clear(id) { + if (!id) { + throw new Error("The 'id' argument cannot be null or undefined"); + } + if (typeof (id) !== "string") { + throw new Error("The 'id' argument must be a string"); + } + await this.interop.invoke(this.NotificationsExecuteMethod, { command: "clear", data: { id } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async clearMany(notifications) { + this.validateNotificationsArr(notifications); + await this.interop.invoke(this.NotificationsExecuteMethod, { command: "clearMany", data: { notifications } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async click(id, action, options) { + await this.interop.invoke(this.NotificationsExecuteMethod, { command: "click", data: { id, action, options } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async snooze(id, duration) { + await this.interop.invoke(this.NotificationsExecuteMethod, { command: "snooze", data: { id, duration } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async snoozeMany(notifications, duration) { + if (!duration) { + throw new Error("The 'duration' argument cannot be null or undefined"); + } + if (typeof duration !== "number") { + throw new Error("The 'duration' argument must be a valid number"); + } + this.validateNotificationsArr(notifications); + await this.interop.invoke(this.NotificationsExecuteMethod, { command: "snoozeMany", data: { notifications, duration } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async setState(id, state) { + if (!id) { + throw new Error("The 'id' argument cannot be null or undefined"); + } + if (typeof (id) !== "string") { + throw new Error("The 'id' argument must be a string"); + } + if (!state) { + throw new Error("The 'state' argument cannot be null or undefined"); + } + this.validateState(state); + await this.interop.invoke(this.NotificationsExecuteMethod, { command: "updateState", data: { id, state } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async setStates(notifications, state) { + if (!state) { + throw new Error("The 'state' argument cannot be null or undefined"); + } + if (typeof state !== "string") { + throw new Error("The 'state' argument must be a valid string"); + } + this.validateNotificationsArr(notifications); + await this.interop.invoke(this.NotificationsExecuteMethod, { command: "updateStates", data: { notifications, state } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + toAPI() { + return { + maxActions: this.maxActions, + panel: this._panel.toAPI(), + raise: this.raise.bind(this), + setFilter: this.setFilter.bind(this), + getFilter: this.getFilter.bind(this), + configure: this.configure.bind(this), + getConfiguration: this.getConfiguration.bind(this), + list: this.list.bind(this), + onRaised: this.onRaised.bind(this), + onStateChanged: this.onStateChanged.bind(this), + onClosed: this.onClosed.bind(this), + onConfigurationChanged: this.onConfigurationChanged.bind(this), + onCounterChanged: this.onCounterChanged.bind(this), + onDataChanged: this.onDataChanged.bind(this), + clearAll: this.clearAll.bind(this), + clearOld: this.clearOld.bind(this), + clear: this.clear.bind(this), + click: this.click.bind(this), + setState: this.setState.bind(this), + updateData: this.updateData.bind(this), + snooze: this.snooze.bind(this), + snoozeMany: this.snoozeMany.bind(this), + clearMany: this.clearMany.bind(this), + setStates: this.setStates.bind(this), + import: this.importNotifications.bind(this) + }; + } + async importNotifications(notifications) { + if (!notifications || !Array.isArray(notifications) || notifications.length === 0) { + throw new Error("Notifications argument must be a valid array with notification options"); + } + const notificationsToImport = await Promise.all(notifications.map((notificationOptions) => this.createNotification(notificationOptions, true))); + const invocationResult = await this.interop.invoke(this.NotificationsExecuteMethod, { command: "importNotifications", data: { notificationSettings: notificationsToImport } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return invocationResult.returned.notifications; + } + async createNotification(options, imported) { + var _a, _b, _c, _d; + this.validate(options, imported); + if (!this.methodsRegistered) { + const bunchOfPromises = []; + for (let index = STARTING_INDEX; index < this.maxActions; index++) { + bunchOfPromises.push(this.interop.register(`${this.methodNameRoot}_${index}`, this.handleNotificationEvent.bind(this))); + } + this.methodsRegistered = true; + await Promise.all(bunchOfPromises); + } + const id = (_a = options.id) !== null && _a !== void 0 ? _a : Utils.generateId(); + const type = (_b = options.type) !== null && _b !== void 0 ? _b : "Notification"; + const notification = { + id, + state: (_c = options.state) !== null && _c !== void 0 ? _c : "Active", + title: options.title, + type, + severity: (_d = options.severity) !== null && _d !== void 0 ? _d : "None", + description: options.body, + glueRoutingDetailMethodName: `${this.methodNameRoot}_${STARTING_INDEX}`, + actions: [], + sourceId: id, + source: options.source, + publishExtraEvents: true, + clickInterop: options.clickInterop + }; + if (options.actions) { + this.handleActions(options, id, notification); + } + this.handleOptions(options, notification); + return notification; + } + onStreamEventCore(key, callback) { + if (typeof callback !== "function") { + throw new Error("Please provide the callback as a function!"); + } + this.subscribe(); + const un = this.registry.add(key, callback); + return () => { + un(); + this.closeStreamSubscriptionIfNoNeeded(); + }; + } + handleOptions(options, notification) { + if (options.icon) { + notification.attributes = notification.attributes || []; + notification.attributes.push({ key: "icon", value: { stringValue: options.icon } }); + } + if (options.data) { + notification.attributes = notification.attributes || []; + const dataAsString = JSON.stringify(options.data); + notification.attributes.push({ key: "data", value: { stringValue: dataAsString } }); + } + if (typeof options.panelExpiry === "number") { + notification.attributes = notification.attributes || []; + notification.attributes.push({ key: "panelExpiry", value: { stringValue: options.panelExpiry.toString() } }); + } + if (typeof options.toastExpiry === "number") { + notification.attributes = notification.attributes || []; + notification.attributes.push({ key: "toastExpiry", value: { stringValue: options.toastExpiry.toString() } }); + } + } + handleActions(options, id, notification) { + var _a, _b, _c; + const validActions = options.actions.slice(0, this.maxActions); + let index = STARTING_INDEX; + for (const action of validActions) { + const args = { + g42notificationId: id, + g42action: action.action, + g42interopMethod: (_a = action.interop) === null || _a === void 0 ? void 0 : _a.method, + g42interopTarget: (_b = action.interop) === null || _b === void 0 ? void 0 : _b.target, + g42interopArguments: JSON.stringify((_c = action.interop) === null || _c === void 0 ? void 0 : _c.arguments) + }; + const parameters = Object.keys(args).map((key) => { + const value = args[key]; + return { + name: key, + value: { + stringValue: value + } + }; + }); + const glueAction = { + name: `${this.methodNameRoot}_${index}`, + description: action.title, + displayName: action.title, + displayPath: action.displayPath, + displayId: action.displayId, + parameters + }; + notification.actions.push(glueAction); + index++; + } + } + validate(options, imported) { + if (!options) { + throw new Error("invalid options - should be an object"); + } + if (typeof options !== "object") { + throw new Error("invalid options - should be an object"); + } + if (!options.title) { + throw new Error("invalid options - should have a title"); + } + if (typeof options.title !== "string") { + throw new Error("invalid options - title should be a string"); + } + if (options.severity && typeof options.severity !== "string") { + throw new Error("invalid options - severity should be a string"); + } + if (options.panelExpiry && typeof options.panelExpiry !== "number") { + throw new Error("invalid options - panelExpiry should be a number"); + } + if (options.toastExpiry && typeof options.toastExpiry !== "number") { + throw new Error("invalid options - toastExpiry should be a number"); + } + if (options.state) { + this.validateState(options.state, imported); + } + } + validateState(state, imported) { + if (typeof (state) !== "string") { + throw new Error("The 'state' argument must be a string"); + } + const validStates = [ + "Active", + "Acknowledged", + "Stale" + ]; + if (imported) { + validStates.push("Seen", "Snoozed", "Processing", "Closed"); + } + if (!validStates.includes(state)) { + throw new Error(`The state argument: ${state} is not valid!`); + } + } + subscribe() { + this.subscriptionsCountForNotifications++; + if (!this.subscribedForNotifications) { + this.subscribedForNotifications = true; + this.logger.info(`Attempting to subscribe to "${this.NotificationsSubscribeStream}".`); + this.interop + .subscribe(this.NotificationsSubscribeStream, { + arguments: { + sendDeltaOnly: true, + statesVersion2: true + } + }) + .then((sub) => { + this.subscriptionForNotifications = sub; + this.logger.info(`Successfully subscribed to "${this.NotificationsSubscribeStream}".`); + sub.onData(({ data }) => { + this.handleData(data); + }); + sub.onClosed((...args) => { + this.subscribedForNotifications = false; + this.logger.info(`Stream subscription Closed - ${JSON.stringify(args)}`); + }); + sub.onFailed((...args) => { + this.subscribedForNotifications = false; + this.logger.warn(`Stream subscription Failed - ${JSON.stringify(args)}`); + }); + }) + .catch((e) => { + this.subscribedForNotifications = false; + this.logger.error(`Unable to subscribe to "${this.NotificationsSubscribeStream}"`, e); + }); + } + } + subscribeForCounterStream() { + this.subscriptionsCountForCounter++; + if (!this.subscribedCounterStream) { + this.subscribedCounterStream = true; + this.logger.info(`Attempting to subscribe to "${this.NotificationsCounterStream}".`); + this.interop + .subscribe(this.NotificationsCounterStream, { + arguments: { + sendDeltaOnly: true + } + }) + .then((sub) => { + this.subscriptionForCounter = sub; + this.logger.info(`Successfully subscribed to "${this.NotificationsCounterStream}".`); + sub.onData(({ data }) => { + this.registry.execute("on-counter-changed", { count: data.count }); + }); + sub.onClosed((...args) => { + this.subscribedCounterStream = false; + this.logger.info(`Stream subscription Closed - ${JSON.stringify(args)}`); + }); + sub.onFailed((...args) => { + this.subscribedCounterStream = false; + this.logger.warn(`Stream subscription Failed - ${JSON.stringify(args)}`); + }); + }) + .catch((e) => { + this.subscribedCounterStream = false; + this.logger.error(`Unable to subscribe to "${this.NotificationsCounterStream}"`, e); + }); + } + } + subscribeInternalEvents() { + this.registry.add("on-notification-closed", (id) => { + this.handleOnClosed(id); + }); + this.registry.add("on-notification-raised", (notification) => { + this.handleOnShow(notification.id); + }); + } + handleData(message) { + var _a; + try { + if ("items" in message && Array.isArray(message.items)) { + this.handleItemsData(message); + } + else if ("deltas" in message && Array.isArray(message.deltas)) { + this.handleDeltas(message); + } + if ("configuration" in message && typeof message.configuration === "object") { + this.logger.info(`Received configuration ${JSON.stringify(message.configuration)} from the stream`); + this.registry.execute("on-configuration-changed", message.configuration, message.configuration.allApplications); + } + if ("command" in message && typeof message.command === "string") { + this.logger.info(`Received command "${(_a = message.command) !== null && _a !== void 0 ? _a : JSON.stringify(message)}" from the stream`); + if (message.command === "showPanel" || message.command === "hidePanel") { + this.registry.execute("on-panel-visibility-changed", message.command === "showPanel"); + } + } + } + catch (e) { + this.logger.error(`Failed to parse data from the stream`, e); + } + } + handleItemsData(message) { + const items = message.items; + this.logger.info(`Received ${items.length} notifications from the stream`); + const notifications = items; + if (message.isSnapshot) { + notifications.forEach((n) => { + this.registry.execute("on-notification-raised", n); + }); + } + else { + const notification = notifications[0]; + if (notification.state === "Closed") { + this.registry.execute("on-notification-closed", { id: notification.id }); + } + else { + this.registry.execute("on-notification-raised", notification); + } + } + } + handleDeltas(message) { + const deltas = message.deltas; + deltas.forEach((info) => { + var _a; + const id = info.id; + const delta = (_a = info.delta) !== null && _a !== void 0 ? _a : {}; + if (delta.state === "Closed") { + this.registry.execute("on-notification-closed", { id, ...delta }); + } + else if (delta.state) { + this.registry.execute("on-state-changed", { id }, delta.state); + } + else if (delta.attributes) { + const attributes = delta.attributes; + const dataAttribute = attributes.find((a) => a.key === "data"); + if (dataAttribute) { + this.registry.execute("on-notification-data-changed", { id }, JSON.parse(dataAttribute.value.stringValue)); + } + } + }); + } + handleOnClosed(id) { + const { notification, key } = this.getNotification(id); + if (notification) { + this.handleEvent(notification, "close"); + delete this.notifications[key]; + } + } + handleOnShow(id) { + const { notification } = this.getNotification(id); + if (notification) { + this.handleEvent(notification, "show"); + } + } + getNotification(id) { + let notification; + let key; + for (const k in this.notifications) { + if (this.notifications[k].id === id) { + notification = this.notifications[k]; + key = k; + break; + } + } + return { notification, key }; + } + handleNotificationEvent(args) { + const gnsNotificationArgs = this.getGnsNotificationArgs(args); + if (gnsNotificationArgs.event === "unknown") { + return; + } + const notification = this.notifications[gnsNotificationArgs.notificationId]; + if (!notification) { + return; + } + this.handleNotificationEventCore(notification, gnsNotificationArgs); + } + handleNotificationEventCore(notification, args) { + switch (args.event) { + case "action": { + return this.handleNotificationActionEvent(notification, args.notificationActionPayload); + } + case "click": { + return this.handleNotificationClickEvent(notification); + } + case "close": { + return this.handleEvent(notification, "close"); + } + case "error": { + return this.handleNotificationErrorEvent(notification, args.error); + } + case "show": { + return this.handleEvent(notification, "show"); + } + } + } + handleNotificationActionEvent(notification, payload) { + const event = { + type: "onaction", + action: payload.g42action + }; + if (notification.onaction) { + notification.onaction(event); + } + notification.dispatchEvent(event); + } + handleNotificationClickEvent(notification) { + const event = { type: "onclick" }; + if (notification.onclick) { + notification.onclick(event); + } + notification.dispatchEvent(event); + } + handleEvent(notification, eventType) { + var _a; + const event = { type: eventType }; + const eventName = `on${eventType}`; + (_a = notification[eventName]) === null || _a === void 0 ? void 0 : _a.call(notification, event); + notification.dispatchEvent(event); + } + handleNotificationErrorEvent(notification, error) { + const event = { type: "onerror", error }; + if (notification.onerror) { + notification.onerror(event); + } + notification.dispatchEvent(event); + } + getGnsNotificationArgs(args) { + var _a; + let result; + const event = (_a = args.notification) === null || _a === void 0 ? void 0 : _a.event; + if (!event) { + result = this.getBackwardGnsNotificationArgs(args); + } + else { + result = { + event, + notificationId: args.notification.sourceNotificationId, + notificationActionPayload: args + }; + } + return result; + } + getBackwardGnsNotificationArgs(args) { + var _a; + let result; + if (args.g42notificationId) { + result = { + event: "action", + notificationId: args.g42notificationId, + notificationActionPayload: args + }; + } + else if ((_a = args.notification) === null || _a === void 0 ? void 0 : _a.sourceNotificationId) { + result = { + event: "click", + notificationId: args.notification.sourceNotificationId, + notificationActionPayload: args + }; + } + else { + result = { + event: "unknown", + notificationId: undefined, + notificationActionPayload: args + }; + } + return result; + } + closeStreamSubscriptionIfNoNeeded() { + this.subscriptionsCountForNotifications--; + if (this.subscriptionForNotifications && this.subscriptionsCountForNotifications === 0) { + this.subscriptionForNotifications.close(); + this.subscriptionForNotifications = undefined; + } + } + closeStreamCounterSubscriptionIfNoNeeded() { + this.subscriptionsCountForCounter--; + if (this.subscriptionForCounter && this.subscriptionsCountForCounter === 0) { + this.subscriptionForCounter.close(); + this.subscriptionForCounter = undefined; + } + } + validateNotificationsArr(notifications) { + if (!Array.isArray(notifications)) { + throw new Error("The 'notifications' argument must be an array with valid notification IDs"); + } + if (notifications.some((n) => typeof n !== "string")) { + throw new Error("The 'notifications' argument must contain only valid string notification IDs"); + } + } + } + + const ThemesConfigurationMethodName = "T42.Themes.Configuration"; + class ThemesImpl { + constructor(contexts, interop) { + this.contexts = contexts; + this.interop = interop; + this.registry = CallbackRegistryFactory(); + this.isSubscribed = false; + this.getConfiguration(); + } + async list() { + await this.getConfiguration(); + if (!this.getMethodName) { + throw new Error("not supported"); + } + return (await this.getAll()).returned.all; + } + async getCurrent() { + await this.getConfiguration(); + if (!this.getMethodName) { + throw new Error("not supported"); + } + const all = await this.getAll(); + return all.returned.all.find((t) => t.name === all.returned.selected); + } + async select(theme) { + await this.getConfiguration(); + if (!this.setMethodName) { + throw new Error("not supported"); + } + await this.interop.invoke(this.setMethodName, { theme }); + } + onChanged(callback) { + if (!callback) { + throw new Error("Callback argument is required"); + } + if (callback && typeof callback !== "function") { + throw new Error("Callback argument must be a function"); + } + this.subscribe(); + return this.registry.add("changed", callback); + } + async getConfiguration() { + try { + if (this.sharedContextName) { + return; + } + const config = await this.interop.invoke(ThemesConfigurationMethodName); + this.sharedContextName = config.returned.sharedContextName; + this.getMethodName = config.returned.getThemesMethodName; + this.setMethodName = config.returned.setThemesMethodName; + } + catch (error) { + return; + } + } + async getAll() { + await this.getConfiguration(); + return await this.interop.invoke(this.getMethodName); + } + async subscribe() { + await this.getConfiguration(); + if (this.isSubscribed) { + return; + } + this.isSubscribed = true; + this.contexts.subscribe(this.sharedContextName, (data) => { + if (data && data.all && data.selected) { + this.registry.execute("changed", data.all.find((t) => t.name === data.selected)); + } + }); + } + } + + function factory$2(contexts, interop) { + const themes = new ThemesImpl(contexts, interop); + return { + list: themes.list.bind(themes), + getCurrent: themes.getCurrent.bind(themes), + select: themes.select.bind(themes), + onChanged: themes.onChanged.bind(themes), + ready: () => Promise.resolve(), + }; + } + + const connectBrowserAppProps = ["name", "title", "version", "customProperties", "icon", "caption", "type"]; + const fdc3v2AppProps = ["appId", "name", "type", "details", "version", "title", "tooltip", "lang", "description", "categories", "icons", "screenshots", "contactEmail", "moreInfo", "publisher", "customConfig", "hostManifests", "interop", "localizedVersions"]; + + /** + * Wraps values in an `Ok` type. + * + * Example: `ok(5) // => {ok: true, result: 5}` + */ + var ok = function (result) { return ({ ok: true, result: result }); }; + /** + * Wraps errors in an `Err` type. + * + * Example: `err('on fire') // => {ok: false, error: 'on fire'}` + */ + var err = function (error) { return ({ ok: false, error: error }); }; + /** + * Create a `Promise` that either resolves with the result of `Ok` or rejects + * with the error of `Err`. + */ + var asPromise = function (r) { + return r.ok === true ? Promise.resolve(r.result) : Promise.reject(r.error); + }; + /** + * Unwraps a `Result` and returns either the result of an `Ok`, or + * `defaultValue`. + * + * Example: + * ``` + * Result.withDefault(5, number().run(json)) + * ``` + * + * It would be nice if `Decoder` had an instance method that mirrored this + * function. Such a method would look something like this: + * ``` + * class Decoder { + * runWithDefault = (defaultValue: A, json: any): A => + * Result.withDefault(defaultValue, this.run(json)); + * } + * + * number().runWithDefault(5, json) + * ``` + * Unfortunately, the type of `defaultValue: A` on the method causes issues + * with type inference on the `object` decoder in some situations. While these + * inference issues can be solved by providing the optional type argument for + * `object`s, the extra trouble and confusion doesn't seem worth it. + */ + var withDefault = function (defaultValue, r) { + return r.ok === true ? r.result : defaultValue; + }; + /** + * Return the successful result, or throw an error. + */ + var withException = function (r) { + if (r.ok === true) { + return r.result; + } + else { + throw r.error; + } + }; + /** + * Apply `f` to the result of an `Ok`, or pass the error through. + */ + var map = function (f, r) { + return r.ok === true ? ok(f(r.result)) : r; + }; + /** + * Apply `f` to the result of two `Ok`s, or pass an error through. If both + * `Result`s are errors then the first one is returned. + */ + var map2 = function (f, ar, br) { + return ar.ok === false ? ar : + br.ok === false ? br : + ok(f(ar.result, br.result)); + }; + /** + * Apply `f` to the error of an `Err`, or pass the success through. + */ + var mapError = function (f, r) { + return r.ok === true ? r : err(f(r.error)); + }; + /** + * Chain together a sequence of computations that may fail, similar to a + * `Promise`. If the first computation fails then the error will propagate + * through. If it succeeds, then `f` will be applied to the value, returning a + * new `Result`. + */ + var andThen = function (f, r) { + return r.ok === true ? f(r.result) : r; + }; + + /*! ***************************************************************************** + Copyright (c) Microsoft Corporation. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THIS SOFTWARE. + ***************************************************************************** */ + /* global Reflect, Promise */ + + + + var __assign = function() { + __assign = Object.assign || function __assign(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; + } + return t; + }; + return __assign.apply(this, arguments); + }; + + function __rest(s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { + if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) + t[p[i]] = s[p[i]]; + } + return t; + } + + function isEqual(a, b) { + if (a === b) { + return true; + } + if (a === null && b === null) { + return true; + } + if (typeof (a) !== typeof (b)) { + return false; + } + if (typeof (a) === 'object') { + // Array + if (Array.isArray(a)) { + if (!Array.isArray(b)) { + return false; + } + if (a.length !== b.length) { + return false; + } + for (var i = 0; i < a.length; i++) { + if (!isEqual(a[i], b[i])) { + return false; + } + } + return true; + } + // Hash table + var keys = Object.keys(a); + if (keys.length !== Object.keys(b).length) { + return false; + } + for (var i = 0; i < keys.length; i++) { + if (!b.hasOwnProperty(keys[i])) { + return false; + } + if (!isEqual(a[keys[i]], b[keys[i]])) { + return false; + } + } + return true; + } + } + /* + * Helpers + */ + var isJsonArray = function (json) { return Array.isArray(json); }; + var isJsonObject = function (json) { + return typeof json === 'object' && json !== null && !isJsonArray(json); + }; + var typeString = function (json) { + switch (typeof json) { + case 'string': + return 'a string'; + case 'number': + return 'a number'; + case 'boolean': + return 'a boolean'; + case 'undefined': + return 'undefined'; + case 'object': + if (json instanceof Array) { + return 'an array'; + } + else if (json === null) { + return 'null'; + } + else { + return 'an object'; + } + default: + return JSON.stringify(json); + } + }; + var expectedGot = function (expected, got) { + return "expected " + expected + ", got " + typeString(got); + }; + var printPath = function (paths) { + return paths.map(function (path) { return (typeof path === 'string' ? "." + path : "[" + path + "]"); }).join(''); + }; + var prependAt = function (newAt, _a) { + var at = _a.at, rest = __rest(_a, ["at"]); + return (__assign({ at: newAt + (at || '') }, rest)); + }; + /** + * Decoders transform json objects with unknown structure into known and + * verified forms. You can create objects of type `Decoder` with either the + * primitive decoder functions, such as `boolean()` and `string()`, or by + * applying higher-order decoders to the primitives, such as `array(boolean())` + * or `dict(string())`. + * + * Each of the decoder functions are available both as a static method on + * `Decoder` and as a function alias -- for example the string decoder is + * defined at `Decoder.string()`, but is also aliased to `string()`. Using the + * function aliases exported with the library is recommended. + * + * `Decoder` exposes a number of 'run' methods, which all decode json in the + * same way, but communicate success and failure in different ways. The `map` + * and `andThen` methods modify decoders without having to call a 'run' method. + * + * Alternatively, the main decoder `run()` method returns an object of type + * `Result`. This library provides a number of helper + * functions for dealing with the `Result` type, so you can do all the same + * things with a `Result` as with the decoder methods. + */ + var Decoder = /** @class */ (function () { + /** + * The Decoder class constructor is kept private to separate the internal + * `decode` function from the external `run` function. The distinction + * between the two functions is that `decode` returns a + * `Partial` on failure, which contains an unfinished error + * report. When `run` is called on a decoder, the relevant series of `decode` + * calls is made, and then on failure the resulting `Partial` + * is turned into a `DecoderError` by filling in the missing information. + * + * While hiding the constructor may seem restrictive, leveraging the + * provided decoder combinators and helper functions such as + * `andThen` and `map` should be enough to build specialized decoders as + * needed. + */ + function Decoder(decode) { + var _this = this; + this.decode = decode; + /** + * Run the decoder and return a `Result` with either the decoded value or a + * `DecoderError` containing the json input, the location of the error, and + * the error message. + * + * Examples: + * ``` + * number().run(12) + * // => {ok: true, result: 12} + * + * string().run(9001) + * // => + * // { + * // ok: false, + * // error: { + * // kind: 'DecoderError', + * // input: 9001, + * // at: 'input', + * // message: 'expected a string, got 9001' + * // } + * // } + * ``` + */ + this.run = function (json) { + return mapError(function (error) { return ({ + kind: 'DecoderError', + input: json, + at: 'input' + (error.at || ''), + message: error.message || '' + }); }, _this.decode(json)); + }; + /** + * Run the decoder as a `Promise`. + */ + this.runPromise = function (json) { return asPromise(_this.run(json)); }; + /** + * Run the decoder and return the value on success, or throw an exception + * with a formatted error string. + */ + this.runWithException = function (json) { return withException(_this.run(json)); }; + /** + * Construct a new decoder that applies a transformation to the decoded + * result. If the decoder succeeds then `f` will be applied to the value. If + * it fails the error will propagated through. + * + * Example: + * ``` + * number().map(x => x * 5).run(10) + * // => {ok: true, result: 50} + * ``` + */ + this.map = function (f) { + return new Decoder(function (json) { return map(f, _this.decode(json)); }); + }; + /** + * Chain together a sequence of decoders. The first decoder will run, and + * then the function will determine what decoder to run second. If the result + * of the first decoder succeeds then `f` will be applied to the decoded + * value. If it fails the error will propagate through. + * + * This is a very powerful method -- it can act as both the `map` and `where` + * methods, can improve error messages for edge cases, and can be used to + * make a decoder for custom types. + * + * Example of adding an error message: + * ``` + * const versionDecoder = valueAt(['version'], number()); + * const infoDecoder3 = object({a: boolean()}); + * + * const decoder = versionDecoder.andThen(version => { + * switch (version) { + * case 3: + * return infoDecoder3; + * default: + * return fail(`Unable to decode info, version ${version} is not supported.`); + * } + * }); + * + * decoder.run({version: 3, a: true}) + * // => {ok: true, result: {a: true}} + * + * decoder.run({version: 5, x: 'abc'}) + * // => + * // { + * // ok: false, + * // error: {... message: 'Unable to decode info, version 5 is not supported.'} + * // } + * ``` + * + * Example of decoding a custom type: + * ``` + * // nominal type for arrays with a length of at least one + * type NonEmptyArray = T[] & { __nonEmptyArrayBrand__: void }; + * + * const nonEmptyArrayDecoder = (values: Decoder): Decoder> => + * array(values).andThen(arr => + * arr.length > 0 + * ? succeed(createNonEmptyArray(arr)) + * : fail(`expected a non-empty array, got an empty array`) + * ); + * ``` + */ + this.andThen = function (f) { + return new Decoder(function (json) { + return andThen(function (value) { return f(value).decode(json); }, _this.decode(json)); + }); + }; + /** + * Add constraints to a decoder _without_ changing the resulting type. The + * `test` argument is a predicate function which returns true for valid + * inputs. When `test` fails on an input, the decoder fails with the given + * `errorMessage`. + * + * ``` + * const chars = (length: number): Decoder => + * string().where( + * (s: string) => s.length === length, + * `expected a string of length ${length}` + * ); + * + * chars(5).run('12345') + * // => {ok: true, result: '12345'} + * + * chars(2).run('HELLO') + * // => {ok: false, error: {... message: 'expected a string of length 2'}} + * + * chars(12).run(true) + * // => {ok: false, error: {... message: 'expected a string, got a boolean'}} + * ``` + */ + this.where = function (test, errorMessage) { + return _this.andThen(function (value) { return (test(value) ? Decoder.succeed(value) : Decoder.fail(errorMessage)); }); + }; + } + /** + * Decoder primitive that validates strings, and fails on all other input. + */ + Decoder.string = function () { + return new Decoder(function (json) { + return typeof json === 'string' + ? ok(json) + : err({ message: expectedGot('a string', json) }); + }); + }; + /** + * Decoder primitive that validates numbers, and fails on all other input. + */ + Decoder.number = function () { + return new Decoder(function (json) { + return typeof json === 'number' + ? ok(json) + : err({ message: expectedGot('a number', json) }); + }); + }; + /** + * Decoder primitive that validates booleans, and fails on all other input. + */ + Decoder.boolean = function () { + return new Decoder(function (json) { + return typeof json === 'boolean' + ? ok(json) + : err({ message: expectedGot('a boolean', json) }); + }); + }; + Decoder.constant = function (value) { + return new Decoder(function (json) { + return isEqual(json, value) + ? ok(value) + : err({ message: "expected " + JSON.stringify(value) + ", got " + JSON.stringify(json) }); + }); + }; + Decoder.object = function (decoders) { + return new Decoder(function (json) { + if (isJsonObject(json) && decoders) { + var obj = {}; + for (var key in decoders) { + if (decoders.hasOwnProperty(key)) { + var r = decoders[key].decode(json[key]); + if (r.ok === true) { + // tslint:disable-next-line:strict-type-predicates + if (r.result !== undefined) { + obj[key] = r.result; + } + } + else if (json[key] === undefined) { + return err({ message: "the key '" + key + "' is required but was not present" }); + } + else { + return err(prependAt("." + key, r.error)); + } + } + } + return ok(obj); + } + else if (isJsonObject(json)) { + return ok(json); + } + else { + return err({ message: expectedGot('an object', json) }); + } + }); + }; + Decoder.array = function (decoder) { + return new Decoder(function (json) { + if (isJsonArray(json) && decoder) { + var decodeValue_1 = function (v, i) { + return mapError(function (err$$1) { return prependAt("[" + i + "]", err$$1); }, decoder.decode(v)); + }; + return json.reduce(function (acc, v, i) { + return map2(function (arr, result) { return arr.concat([result]); }, acc, decodeValue_1(v, i)); + }, ok([])); + } + else if (isJsonArray(json)) { + return ok(json); + } + else { + return err({ message: expectedGot('an array', json) }); + } + }); + }; + Decoder.tuple = function (decoders) { + return new Decoder(function (json) { + if (isJsonArray(json)) { + if (json.length !== decoders.length) { + return err({ + message: "expected a tuple of length " + decoders.length + ", got one of length " + json.length + }); + } + var result = []; + for (var i = 0; i < decoders.length; i++) { + var nth = decoders[i].decode(json[i]); + if (nth.ok) { + result[i] = nth.result; + } + else { + return err(prependAt("[" + i + "]", nth.error)); + } + } + return ok(result); + } + else { + return err({ message: expectedGot("a tuple of length " + decoders.length, json) }); + } + }); + }; + Decoder.union = function (ad, bd) { + var decoders = []; + for (var _i = 2; _i < arguments.length; _i++) { + decoders[_i - 2] = arguments[_i]; + } + return Decoder.oneOf.apply(Decoder, [ad, bd].concat(decoders)); + }; + Decoder.intersection = function (ad, bd) { + var ds = []; + for (var _i = 2; _i < arguments.length; _i++) { + ds[_i - 2] = arguments[_i]; + } + return new Decoder(function (json) { + return [ad, bd].concat(ds).reduce(function (acc, decoder) { return map2(Object.assign, acc, decoder.decode(json)); }, ok({})); + }); + }; + /** + * Escape hatch to bypass validation. Always succeeds and types the result as + * `any`. Useful for defining decoders incrementally, particularly for + * complex objects. + * + * Example: + * ``` + * interface User { + * name: string; + * complexUserData: ComplexType; + * } + * + * const userDecoder: Decoder = object({ + * name: string(), + * complexUserData: anyJson() + * }); + * ``` + */ + Decoder.anyJson = function () { return new Decoder(function (json) { return ok(json); }); }; + /** + * Decoder identity function which always succeeds and types the result as + * `unknown`. + */ + Decoder.unknownJson = function () { + return new Decoder(function (json) { return ok(json); }); + }; + /** + * Decoder for json objects where the keys are unknown strings, but the values + * should all be of the same type. + * + * Example: + * ``` + * dict(number()).run({chocolate: 12, vanilla: 10, mint: 37}); + * // => {ok: true, result: {chocolate: 12, vanilla: 10, mint: 37}} + * ``` + */ + Decoder.dict = function (decoder) { + return new Decoder(function (json) { + if (isJsonObject(json)) { + var obj = {}; + for (var key in json) { + if (json.hasOwnProperty(key)) { + var r = decoder.decode(json[key]); + if (r.ok === true) { + obj[key] = r.result; + } + else { + return err(prependAt("." + key, r.error)); + } + } + } + return ok(obj); + } + else { + return err({ message: expectedGot('an object', json) }); + } + }); + }; + /** + * Decoder for values that may be `undefined`. This is primarily helpful for + * decoding interfaces with optional fields. + * + * Example: + * ``` + * interface User { + * id: number; + * isOwner?: boolean; + * } + * + * const decoder: Decoder = object({ + * id: number(), + * isOwner: optional(boolean()) + * }); + * ``` + */ + Decoder.optional = function (decoder) { + return new Decoder(function (json) { return (json === undefined || json === null ? ok(undefined) : decoder.decode(json)); }); + }; + /** + * Decoder that attempts to run each decoder in `decoders` and either succeeds + * with the first successful decoder, or fails after all decoders have failed. + * + * Note that `oneOf` expects the decoders to all have the same return type, + * while `union` creates a decoder for the union type of all the input + * decoders. + * + * Examples: + * ``` + * oneOf(string(), number().map(String)) + * oneOf(constant('start'), constant('stop'), succeed('unknown')) + * ``` + */ + Decoder.oneOf = function () { + var decoders = []; + for (var _i = 0; _i < arguments.length; _i++) { + decoders[_i] = arguments[_i]; + } + return new Decoder(function (json) { + var errors = []; + for (var i = 0; i < decoders.length; i++) { + var r = decoders[i].decode(json); + if (r.ok === true) { + return r; + } + else { + errors[i] = r.error; + } + } + var errorsList = errors + .map(function (error) { return "at error" + (error.at || '') + ": " + error.message; }) + .join('", "'); + return err({ + message: "expected a value matching one of the decoders, got the errors [\"" + errorsList + "\"]" + }); + }); + }; + /** + * Decoder that always succeeds with either the decoded value, or a fallback + * default value. + */ + Decoder.withDefault = function (defaultValue, decoder) { + return new Decoder(function (json) { + return ok(withDefault(defaultValue, decoder.decode(json))); + }); + }; + /** + * Decoder that pulls a specific field out of a json structure, instead of + * decoding and returning the full structure. The `paths` array describes the + * object keys and array indices to traverse, so that values can be pulled out + * of a nested structure. + * + * Example: + * ``` + * const decoder = valueAt(['a', 'b', 0], string()); + * + * decoder.run({a: {b: ['surprise!']}}) + * // => {ok: true, result: 'surprise!'} + * + * decoder.run({a: {x: 'cats'}}) + * // => {ok: false, error: {... at: 'input.a.b[0]' message: 'path does not exist'}} + * ``` + * + * Note that the `decoder` is ran on the value found at the last key in the + * path, even if the last key is not found. This allows the `optional` + * decoder to succeed when appropriate. + * ``` + * const optionalDecoder = valueAt(['a', 'b', 'c'], optional(string())); + * + * optionalDecoder.run({a: {b: {c: 'surprise!'}}}) + * // => {ok: true, result: 'surprise!'} + * + * optionalDecoder.run({a: {b: 'cats'}}) + * // => {ok: false, error: {... at: 'input.a.b.c' message: 'expected an object, got "cats"'} + * + * optionalDecoder.run({a: {b: {z: 1}}}) + * // => {ok: true, result: undefined} + * ``` + */ + Decoder.valueAt = function (paths, decoder) { + return new Decoder(function (json) { + var jsonAtPath = json; + for (var i = 0; i < paths.length; i++) { + if (jsonAtPath === undefined) { + return err({ + at: printPath(paths.slice(0, i + 1)), + message: 'path does not exist' + }); + } + else if (typeof paths[i] === 'string' && !isJsonObject(jsonAtPath)) { + return err({ + at: printPath(paths.slice(0, i + 1)), + message: expectedGot('an object', jsonAtPath) + }); + } + else if (typeof paths[i] === 'number' && !isJsonArray(jsonAtPath)) { + return err({ + at: printPath(paths.slice(0, i + 1)), + message: expectedGot('an array', jsonAtPath) + }); + } + else { + jsonAtPath = jsonAtPath[paths[i]]; + } + } + return mapError(function (error) { + return jsonAtPath === undefined + ? { at: printPath(paths), message: 'path does not exist' } + : prependAt(printPath(paths), error); + }, decoder.decode(jsonAtPath)); + }); + }; + /** + * Decoder that ignores the input json and always succeeds with `fixedValue`. + */ + Decoder.succeed = function (fixedValue) { + return new Decoder(function (json) { return ok(fixedValue); }); + }; + /** + * Decoder that ignores the input json and always fails with `errorMessage`. + */ + Decoder.fail = function (errorMessage) { + return new Decoder(function (json) { return err({ message: errorMessage }); }); + }; + /** + * Decoder that allows for validating recursive data structures. Unlike with + * functions, decoders assigned to variables can't reference themselves + * before they are fully defined. We can avoid prematurely referencing the + * decoder by wrapping it in a function that won't be called until use, at + * which point the decoder has been defined. + * + * Example: + * ``` + * interface Comment { + * msg: string; + * replies: Comment[]; + * } + * + * const decoder: Decoder = object({ + * msg: string(), + * replies: lazy(() => array(decoder)) + * }); + * ``` + */ + Decoder.lazy = function (mkDecoder) { + return new Decoder(function (json) { return mkDecoder().decode(json); }); + }; + return Decoder; + }()); + + /* tslint:disable:variable-name */ + /** See `Decoder.string` */ + var string = Decoder.string; + /** See `Decoder.number` */ + var number = Decoder.number; + /** See `Decoder.boolean` */ + var boolean = Decoder.boolean; + /** See `Decoder.anyJson` */ + var anyJson = Decoder.anyJson; + /** See `Decoder.unknownJson` */ + Decoder.unknownJson; + /** See `Decoder.constant` */ + var constant = Decoder.constant; + /** See `Decoder.object` */ + var object = Decoder.object; + /** See `Decoder.array` */ + var array = Decoder.array; + /** See `Decoder.tuple` */ + Decoder.tuple; + /** See `Decoder.dict` */ + var dict = Decoder.dict; + /** See `Decoder.optional` */ + var optional = Decoder.optional; + /** See `Decoder.oneOf` */ + var oneOf = Decoder.oneOf; + /** See `Decoder.union` */ + Decoder.union; + /** See `Decoder.intersection` */ + Decoder.intersection; + /** See `Decoder.withDefault` */ + Decoder.withDefault; + /** See `Decoder.valueAt` */ + Decoder.valueAt; + /** See `Decoder.succeed` */ + Decoder.succeed; + /** See `Decoder.fail` */ + Decoder.fail; + /** See `Decoder.lazy` */ + Decoder.lazy; + + const nonEmptyStringDecoder = string().where((s) => s.length > 0, "Expected a non-empty string"); + const nonNegativeNumberDecoder = number().where((num) => num >= 0, "Expected a non-negative number"); + + const intentDefinitionDecoder = object({ + name: nonEmptyStringDecoder, + displayName: optional(string()), + contexts: optional(array(string())), + customConfig: optional(object()) + }); + const v2TypeDecoder = oneOf(constant("web"), constant("native"), constant("citrix"), constant("onlineNative"), constant("other")); + const v2DetailsDecoder = object({ + url: nonEmptyStringDecoder + }); + const v2IconDecoder = object({ + src: nonEmptyStringDecoder, + size: optional(nonEmptyStringDecoder), + type: optional(nonEmptyStringDecoder) + }); + const v2ScreenshotDecoder = object({ + src: nonEmptyStringDecoder, + size: optional(nonEmptyStringDecoder), + type: optional(nonEmptyStringDecoder), + label: optional(nonEmptyStringDecoder) + }); + const v2ListensForIntentDecoder = object({ + contexts: array(nonEmptyStringDecoder), + displayName: optional(nonEmptyStringDecoder), + resultType: optional(nonEmptyStringDecoder), + customConfig: optional(anyJson()) + }); + const v2IntentsDecoder = object({ + listensFor: optional(dict(v2ListensForIntentDecoder)), + raises: optional(dict(array(nonEmptyStringDecoder))) + }); + const v2UserChannelDecoder = object({ + broadcasts: optional(array(nonEmptyStringDecoder)), + listensFor: optional(array(nonEmptyStringDecoder)) + }); + const v2AppChannelDecoder = object({ + name: nonEmptyStringDecoder, + description: optional(nonEmptyStringDecoder), + broadcasts: optional(array(nonEmptyStringDecoder)), + listensFor: optional(array(nonEmptyStringDecoder)) + }); + const v2InteropDecoder = object({ + intents: optional(v2IntentsDecoder), + userChannels: optional(v2UserChannelDecoder), + appChannels: optional(array(v2AppChannelDecoder)) + }); + const glue42ApplicationDetailsDecoder = object({ + url: optional(nonEmptyStringDecoder), + top: optional(number()), + left: optional(number()), + width: optional(nonNegativeNumberDecoder), + height: optional(nonNegativeNumberDecoder) + }); + const glue42HostManifestsBrowserDecoder = object({ + name: optional(nonEmptyStringDecoder), + type: optional(nonEmptyStringDecoder.where((s) => s === "window", "Expected a value of window")), + title: optional(nonEmptyStringDecoder), + version: optional(nonEmptyStringDecoder), + customProperties: optional(anyJson()), + icon: optional(string()), + caption: optional(string()), + details: optional(glue42ApplicationDetailsDecoder), + intents: optional(array(intentDefinitionDecoder)), + hidden: optional(boolean()) + }); + const v1DefinitionDecoder = object({ + name: nonEmptyStringDecoder, + appId: nonEmptyStringDecoder, + title: optional(nonEmptyStringDecoder), + version: optional(nonEmptyStringDecoder), + manifest: nonEmptyStringDecoder, + manifestType: nonEmptyStringDecoder, + tooltip: optional(nonEmptyStringDecoder), + description: optional(nonEmptyStringDecoder), + contactEmail: optional(nonEmptyStringDecoder), + supportEmail: optional(nonEmptyStringDecoder), + publisher: optional(nonEmptyStringDecoder), + images: optional(array(object({ url: optional(nonEmptyStringDecoder) }))), + icons: optional(array(object({ icon: optional(nonEmptyStringDecoder) }))), + customConfig: anyJson(), + intents: optional(array(intentDefinitionDecoder)) + }); + const v2LocalizedDefinitionDecoder = object({ + appId: optional(nonEmptyStringDecoder), + name: optional(nonEmptyStringDecoder), + details: optional(v2DetailsDecoder), + version: optional(nonEmptyStringDecoder), + title: optional(nonEmptyStringDecoder), + tooltip: optional(nonEmptyStringDecoder), + lang: optional(nonEmptyStringDecoder), + description: optional(nonEmptyStringDecoder), + categories: optional(array(nonEmptyStringDecoder)), + icons: optional(array(v2IconDecoder)), + screenshots: optional(array(v2ScreenshotDecoder)), + contactEmail: optional(nonEmptyStringDecoder), + supportEmail: optional(nonEmptyStringDecoder), + moreInfo: optional(nonEmptyStringDecoder), + publisher: optional(nonEmptyStringDecoder), + customConfig: optional(array(anyJson())), + hostManifests: optional(anyJson()), + interop: optional(v2InteropDecoder) + }); + const v2DefinitionDecoder = object({ + appId: nonEmptyStringDecoder, + name: nonEmptyStringDecoder, + type: v2TypeDecoder, + details: v2DetailsDecoder, + version: optional(nonEmptyStringDecoder), + title: optional(nonEmptyStringDecoder), + tooltip: optional(nonEmptyStringDecoder), + lang: optional(nonEmptyStringDecoder), + description: optional(nonEmptyStringDecoder), + categories: optional(array(nonEmptyStringDecoder)), + icons: optional(array(v2IconDecoder)), + screenshots: optional(array(v2ScreenshotDecoder)), + contactEmail: optional(nonEmptyStringDecoder), + supportEmail: optional(nonEmptyStringDecoder), + moreInfo: optional(nonEmptyStringDecoder), + publisher: optional(nonEmptyStringDecoder), + customConfig: optional(array(anyJson())), + hostManifests: optional(anyJson()), + interop: optional(v2InteropDecoder), + localizedVersions: optional(dict(v2LocalizedDefinitionDecoder)) + }); + const allDefinitionsDecoder = oneOf(v1DefinitionDecoder, v2DefinitionDecoder); + + const parseDecoderErrorToStringMessage = (error) => { + return `${error.kind} at ${error.at}: ${JSON.stringify(error.input)}. Reason - ${error.message}`; + }; + + class FDC3Service { + fdc3ToDesktopDefinitionType = { + web: "window", + native: "exe", + citrix: "citrix", + onlineNative: "clickonce", + other: "window" + }; + toApi() { + return { + isFdc3Definition: this.isFdc3Definition.bind(this), + parseToBrowserBaseAppData: this.parseToBrowserBaseAppData.bind(this), + parseToDesktopAppConfig: this.parseToDesktopAppConfig.bind(this) + }; + } + isFdc3Definition(definition) { + const decodeRes = allDefinitionsDecoder.run(definition); + if (!decodeRes.ok) { + return { isFdc3: false, reason: parseDecoderErrorToStringMessage(decodeRes.error) }; + } + if (definition.appId && definition.details) { + return { isFdc3: true, version: "2.0" }; + } + if (definition.manifest) { + return { isFdc3: true, version: "1.2" }; + } + return { isFdc3: false, reason: "The passed definition is not FDC3" }; + } + parseToBrowserBaseAppData(definition) { + const { isFdc3, version } = this.isFdc3Definition(definition); + if (!isFdc3) { + throw new Error("The passed definition is not FDC3"); + } + const decodeRes = allDefinitionsDecoder.run(definition); + if (!decodeRes.ok) { + throw new Error(`Invalid FDC3 ${version} definition. Error: ${parseDecoderErrorToStringMessage(decodeRes.error)}`); + } + const userProperties = this.getUserPropertiesFromDefinition(definition, version); + const createOptions = { url: this.getUrl(definition, version) }; + const baseApplicationData = { + name: definition.appId, + type: "window", + createOptions, + userProperties: { + ...userProperties, + intents: version === "1.2" + ? userProperties.intents + : this.getIntentsFromV2AppDefinition(definition), + details: createOptions + }, + title: definition.title, + version: definition.version, + icon: this.getIconFromDefinition(definition, version), + caption: definition.description, + fdc3: version === "2.0" ? { ...definition, definitionVersion: "2.0" } : undefined, + }; + const ioConnectDefinition = definition.hostManifests?.ioConnect || definition.hostManifests?.["Glue42"]; + if (!ioConnectDefinition) { + return baseApplicationData; + } + const ioDefinitionDecodeRes = glue42HostManifestsBrowserDecoder.run(ioConnectDefinition); + if (!ioDefinitionDecodeRes.ok) { + throw new Error(`Invalid FDC3 ${version} definition. Error: ${parseDecoderErrorToStringMessage(ioDefinitionDecodeRes.error)}`); + } + if (!Object.keys(ioDefinitionDecodeRes.result).length) { + return baseApplicationData; + } + return this.mergeBaseAppDataWithGlueManifest(baseApplicationData, ioDefinitionDecodeRes.result); + } + parseToDesktopAppConfig(definition) { + const { isFdc3, version } = this.isFdc3Definition(definition); + if (!isFdc3) { + throw new Error("The passed definition is not FDC3"); + } + const decodeRes = allDefinitionsDecoder.run(definition); + if (!decodeRes.ok) { + throw new Error(`Invalid FDC3 ${version} definition. Error: ${parseDecoderErrorToStringMessage(decodeRes.error)}`); + } + if (version === "1.2") { + const fdc3v1Definition = definition; + return { + name: fdc3v1Definition.appId, + type: "window", + details: { + url: this.getUrl(definition, version) + }, + version: fdc3v1Definition.version, + title: fdc3v1Definition.title, + tooltip: fdc3v1Definition.tooltip, + caption: fdc3v1Definition.description, + icon: fdc3v1Definition.icons?.[0].icon, + intents: fdc3v1Definition.intents, + customProperties: { + manifestType: fdc3v1Definition.manifestType, + images: fdc3v1Definition.images, + contactEmail: fdc3v1Definition.contactEmail, + supportEmail: fdc3v1Definition.supportEmail, + publisher: fdc3v1Definition.publisher, + icons: fdc3v1Definition.icons, + customConfig: fdc3v1Definition.customConfig + } + }; + } + const fdc3v2Definition = definition; + const desktopDefinition = { + name: fdc3v2Definition.appId, + type: this.fdc3ToDesktopDefinitionType[fdc3v2Definition.type], + details: fdc3v2Definition.details, + version: fdc3v2Definition.version, + title: fdc3v2Definition.title, + tooltip: fdc3v2Definition.tooltip, + caption: fdc3v2Definition.description, + icon: this.getIconFromDefinition(fdc3v2Definition, "2.0"), + intents: this.getIntentsFromV2AppDefinition(fdc3v2Definition), + fdc3: { ...fdc3v2Definition, definitionVersion: "2.0" } + }; + const ioConnectDefinition = definition.hostManifests?.ioConnect || definition.hostManifests?.["Glue42"]; + if (!ioConnectDefinition) { + return desktopDefinition; + } + if (typeof ioConnectDefinition !== "object" || Array.isArray(ioConnectDefinition)) { + throw new Error(`Invalid '${definition.hostManifests.ioConnect ? "hostManifests.ioConnect" : "hostManifests['Glue42']"}' key`); + } + return this.mergeDesktopConfigWithGlueManifest(desktopDefinition, ioConnectDefinition); + } + getUserPropertiesFromDefinition(definition, version) { + if (version === "1.2") { + return Object.fromEntries(Object.entries(definition).filter(([key]) => !connectBrowserAppProps.includes(key))); + } + return Object.fromEntries(Object.entries(definition).filter(([key]) => !connectBrowserAppProps.includes(key) && !fdc3v2AppProps.includes(key))); + } + getUrl(definition, version) { + let url; + if (version === "1.2") { + const parsedManifest = JSON.parse(definition.manifest); + url = parsedManifest.details?.url || parsedManifest.url; + } + else { + url = definition.details?.url; + } + if (!url || typeof url !== "string") { + throw new Error(`Invalid FDC3 ${version} definition. Provide valid 'url' under '${version === "1.2" ? "manifest" : "details"}' key`); + } + return url; + } + getIntentsFromV2AppDefinition(definition) { + const fdc3Intents = definition.interop?.intents?.listensFor; + if (!fdc3Intents) { + return; + } + const intents = Object.entries(fdc3Intents).map((fdc3Intent) => { + const [intentName, intentData] = fdc3Intent; + return { + name: intentName, + ...intentData + }; + }); + return intents; + } + getIconFromDefinition(definition, version) { + if (version === "1.2") { + return definition.icons?.find((iconDef) => iconDef.icon)?.icon || undefined; + } + return definition.icons?.find((iconDef) => iconDef.src)?.src || undefined; + } + mergeBaseAppDataWithGlueManifest(baseAppData, hostManifestDefinition) { + let baseApplicationDefinition = baseAppData; + if (hostManifestDefinition.details) { + const details = { ...baseAppData.createOptions, ...hostManifestDefinition.details }; + baseApplicationDefinition.createOptions = details; + baseApplicationDefinition.userProperties.details = details; + } + if (Array.isArray(hostManifestDefinition.intents)) { + baseApplicationDefinition.userProperties.intents = (baseApplicationDefinition.userProperties.intents || []).concat(hostManifestDefinition.intents); + } + baseApplicationDefinition = { ...baseApplicationDefinition, ...hostManifestDefinition }; + delete baseApplicationDefinition.details; + delete baseApplicationDefinition.intents; + return baseApplicationDefinition; + } + mergeDesktopConfigWithGlueManifest(config, desktopDefinition) { + const appConfig = Object.assign({}, config, desktopDefinition, { details: { ...config.details, ...desktopDefinition.details } }); + if (Array.isArray(desktopDefinition.intents)) { + appConfig.intents = (config.intents || []).concat(desktopDefinition.intents); + } + return appConfig; + } + } + + const decoders$1 = { + common: { + nonEmptyStringDecoder, + nonNegativeNumberDecoder + }, + fdc3: { + allDefinitionsDecoder, + v1DefinitionDecoder, + v2DefinitionDecoder + } + }; + + var INTENTS_ERRORS; + (function (INTENTS_ERRORS) { + INTENTS_ERRORS["USER_CANCELLED"] = "User Closed Intents Resolver UI without choosing a handler"; + INTENTS_ERRORS["CALLER_NOT_DEFINED"] = "Caller Id is not defined"; + INTENTS_ERRORS["TIMEOUT_HIT"] = "Timeout hit"; + INTENTS_ERRORS["INTENT_NOT_FOUND"] = "Cannot find Intent"; + INTENTS_ERRORS["HANDLER_NOT_FOUND"] = "Cannot find Intent Handler"; + INTENTS_ERRORS["TARGET_INSTANCE_UNAVAILABLE"] = "Cannot start Target Instance"; + INTENTS_ERRORS["INTENT_DELIVERY_FAILED"] = "Target Instance did not add a listener"; + INTENTS_ERRORS["RESOLVER_UNAVAILABLE"] = "Intents Resolver UI unavailable"; + INTENTS_ERRORS["RESOLVER_TIMEOUT"] = "User did not choose a handler"; + INTENTS_ERRORS["INVALID_RESOLVER_RESPONSE"] = "Intents Resolver UI returned invalid response"; + INTENTS_ERRORS["INTENT_HANDLER_REJECTION"] = "Intent Handler function processing the raised intent threw an error or rejected the promise it returned"; + })(INTENTS_ERRORS || (INTENTS_ERRORS = {})); + + class IoC { + _fdc3; + _decoders = decoders$1; + _errors = { + intents: INTENTS_ERRORS + }; + get fdc3() { + if (!this._fdc3) { + this._fdc3 = new FDC3Service().toApi(); + } + return this._fdc3; + } + get decoders() { + return this._decoders; + } + get errors() { + return this._errors; + } + } + + const ioc = new IoC(); + ioc.fdc3; + ioc.decoders; + const errors = ioc.errors; + + const GLUE42_FDC3_INTENTS_METHOD_PREFIX = "Tick42.FDC3.Intents."; + const INTENTS_RESOLVER_INTEROP_PREFIX = "T42.Intents.Resolver.Control"; + const INTENTS_RESOLVER_WIDTH = 400; + const INTENTS_RESOLVER_HEIGHT = 440; + const DEFAULT_RESOLVER_RESPONSE_TIMEOUT = 60 * 1000; + const INTENT_HANDLER_DEFAULT_PROPS = ["applicationName", "type"]; + const INTENTS_RESOLVER_APP_NAME = "intentsResolver"; + const MAX_SET_TIMEOUT_DELAY = 2147483647; + const DEFAULT_METHOD_RESPONSE_TIMEOUT_MS = 60 * 1000; + const DEFAULT_RAISE_TIMEOUT_MS = 90 * 1000; + const DEFAULT_PICK_HANDLER_BY_TIMEOUT_MS = 90 * 1000; + const ERRORS = errors.intents; + + const PromisePlus = (executor, timeoutMilliseconds, timeoutMessage) => { + return new Promise((resolve, reject) => { + const timeout = setTimeout(() => { + const message = timeoutMessage || `Promise timeout hit: ${timeoutMilliseconds}`; + reject(message); + }, timeoutMilliseconds); + const providedPromise = new Promise(executor); + providedPromise + .then((result) => { + clearTimeout(timeout); + resolve(result); + }) + .catch((error) => { + clearTimeout(timeout); + reject(error); + }); + }); + }; + const PromiseWrap = (promise, timeoutMilliseconds, timeoutMessage) => { + return new Promise((resolve, reject) => { + let promiseActive = true; + const timeout = setTimeout(() => { + if (!promiseActive) { + return; + } + promiseActive = false; + const message = timeoutMessage || `Promise timeout hit: ${timeoutMilliseconds}`; + reject(message); + }, timeoutMilliseconds); + promise() + .then((result) => { + if (!promiseActive) { + return; + } + promiseActive = false; + clearTimeout(timeout); + resolve(result); + }) + .catch((error) => { + if (!promiseActive) { + return; + } + promiseActive = false; + clearTimeout(timeout); + reject(error); + }); + }); + }; + + const validateIntentHandlerAsResponse = (handler) => { + if (typeof handler !== "object") { + return { isValid: false, error: `Response object has invalid 'handler' key. Expected an object, got ${typeof handler}` }; + } + const compulsoryKeysExist = INTENT_HANDLER_DEFAULT_PROPS.filter((key) => !(key in handler)); + if (compulsoryKeysExist.length) { + return { isValid: false, error: `Handler in Response object does not provide compulsory keys: ${compulsoryKeysExist.join(", ")}` }; + } + return { isValid: true, ok: handler }; + }; + const validateIntentRequestTarget = (target) => { + if (!target) { + return; + } + if (typeof target !== "string" && typeof target !== "object") { + throw new Error(`Please provide the intent target as one of the valid values: "reuse", "startNew", { app: string }, { instance: string } `); + } + }; + const validateIntentRequestContext = (context) => { + if (!context) { + return; + } + if (typeof context !== "object") { + throw new Error(`Please provide the intent context as an object`); + } + if (context.type && typeof context.type !== "string") { + throw new Error(`Please provide the intent context as an object with 'type' property as string`); + } + if (context.data && typeof context.data !== "object") { + throw new Error(`Please provide the intent context as an object with 'data' property as object`); + } + }; + const validateIntentRequestHandler = (handler) => { + if (!handler.applicationName) { + throw new Error(`Please provide applicationName for handler ${JSON.stringify(handler)}`); + } + if (!handler.type) { + throw new Error(`Please provide type for handler ${JSON.stringify(handler)}`); + } + if (handler.type === "instance" && !handler.instanceId) { + throw new Error(`Please provide instanceId for handler ${JSON.stringify(handler)}`); + } + }; + const validateIntentRequestTimeout = (timeout) => { + if (!timeout) { + return; + } + if (typeof timeout !== "number") { + throw new Error(`Please provide the timeout as a number`); + } + if (timeout <= 0) { + throw new Error(`Please provide the timeout as a positive number`); + } + }; + const validateWaitUserResponseIndefinitely = (waitUserResponseIndefinitely) => { + if (!waitUserResponseIndefinitely) { + return; + } + if (typeof waitUserResponseIndefinitely !== "boolean") { + throw new Error("Please provide waitUserResponseIndefinitely as a boolean"); + } + }; + const validateHandlerFilter = (handlerFilter) => { + if (!handlerFilter) { + throw new Error(`Provide 'handlerFilter' with at least one filter criteria of the following: 'intent' | 'contextTypes' | 'resultType' | 'applicationNames'`); + } + const { title, openResolver, timeout, intent, contextTypes, resultType, applicationNames } = handlerFilter; + if (typeof title !== "undefined" && (typeof title !== "string" || !title.length)) { + throw new Error(`Provide 'title' as a non empty string`); + } + if (typeof openResolver !== "undefined" && typeof openResolver !== "boolean") { + throw new Error(`Provide 'openResolver' prop as a boolean`); + } + if (typeof timeout !== "undefined" && (typeof timeout !== "number" || timeout <= 0)) { + throw new Error(`Provide 'timeout' prop as a positive number`); + } + if (typeof intent !== "undefined" && (typeof intent !== "string" || !intent.length)) { + throw new Error(`Provide 'intent' as a non empty string`); + } + if (typeof contextTypes !== "undefined" && (!Array.isArray(contextTypes) || contextTypes.some(ctx => typeof ctx !== "string"))) { + throw new Error(`Provide 'contextTypes' as an array of non empty strings`); + } + if (typeof resultType !== "undefined" && (typeof resultType !== "string" || !resultType.length)) { + throw new Error(`Provide 'resultType' as a non empty string`); + } + if (typeof applicationNames !== "undefined" && (!Array.isArray(applicationNames) || applicationNames.some(appName => typeof appName !== "string"))) { + throw new Error(`Provide 'applicationNames' as an array of non empty strings`); + } + const errorMsg = "Provide at least one filter criteria of the following: 'intent' | 'contextTypes' | 'resultType' | 'applicationNames'"; + if (!Object.keys(handlerFilter).length) { + throw new Error(errorMsg); + } + if (!intent && !resultType && (!contextTypes || !contextTypes.length) && (!applicationNames || !applicationNames.length)) { + throw new Error(errorMsg); + } + }; + const validateResolverResponse = (responseObj) => { + var _a, _b; + if (typeof responseObj.intent !== "string") { + return { isValid: false, error: `Response object has invalid 'intent' key. Expected a string, got ${typeof responseObj.intent}` }; + } + if (((_a = responseObj.userSettings) === null || _a === void 0 ? void 0 : _a.preserveChoice) && typeof ((_b = responseObj.userSettings) === null || _b === void 0 ? void 0 : _b.preserveChoice) !== "boolean") { + return { isValid: false, error: `Response object has invalid 'userSettings.preserveChoice' key. Expected a boolean, got ${typeof responseObj.userSettings.preserveChoice}` }; + } + const { isValid, error } = validateIntentHandlerAsResponse(responseObj.handler); + return isValid + ? { isValid: true, ok: responseObj } + : { isValid, error }; + }; + const validateIntentRequest = (request) => { + validateIntentRequestContext(request.context); + validateIntentRequestTarget(request.target); + validateIntentRequestTimeout(request.timeout); + validateWaitUserResponseIndefinitely(request.waitUserResponseIndefinitely); + if (typeof request.clearSavedHandler !== "undefined" && typeof request.clearSavedHandler !== "boolean") { + throw new Error("Please provide 'clearSavedHandler' as a boolean"); + } + if (request.handlers) { + request.handlers.forEach((handler) => validateIntentRequestHandler(handler)); + } + }; + const validateIntentHandler = (handler) => { + if (typeof handler !== "object") { + throw new Error("IntentHandler must be an object"); + } + if (typeof handler.applicationName !== "string" || !handler.applicationName.length) { + throw new Error(`Please provide 'applicationName' as a non-empty string`); + } + if (typeof handler.type !== "string" || !["app", "instance"].includes(handler.type)) { + throw new Error(`Invalid 'type' property. Expected 'app' | 'instance' got ${handler.type}`); + } + if (typeof handler.applicationTitle !== "undefined" && typeof handler.applicationTitle !== "string") { + throw new Error(`Provide 'applicationTitle' as a string`); + } + if (typeof handler.applicationDescription !== "undefined" && typeof handler.applicationDescription !== "string") { + throw new Error(`Provide 'applicationDescription' as a string`); + } + if (typeof handler.applicationIcon !== "undefined" && typeof handler.applicationIcon !== "string") { + throw new Error(`Provide 'applicationIcon' as a string`); + } + if (typeof handler.displayName !== "undefined" && typeof handler.displayName !== "string") { + throw new Error(`Provide 'displayName' as a string`); + } + if (typeof handler.contextTypes !== "undefined" && (!Array.isArray(handler.contextTypes) || handler.contextTypes.some(ctx => typeof ctx !== "string"))) { + throw new Error(`Provide 'contextTypes' as an array of non empty strings`); + } + if (typeof handler.instanceId !== "undefined" && typeof handler.instanceId !== "string") { + throw new Error(`Provide 'instanceId' as a string`); + } + if (typeof handler.instanceTitle !== "undefined" && typeof handler.instanceTitle !== "string") { + throw new Error(`Provide 'instanceTitle' as a string`); + } + if (typeof handler.resultType !== "undefined" && typeof handler.resultType !== "string") { + throw new Error(`Provide 'resultType' as a string`); + } + }; + const clearNullUndefined = (obj) => { + Object.keys(obj).forEach(key => { + if (obj[key] === null || obj[key] === undefined) { + delete obj[key]; + } + }); + }; + + class Intents { + constructor(interop, windows, logger, options, prefsController, appManager) { + this.interop = interop; + this.windows = windows; + this.logger = logger; + this.prefsController = prefsController; + this.appManager = appManager; + this.myIntents = new Set(); + this.intentsResolverResponsePromises = {}; + this.useIntentsResolverUI = true; + this.unregisterIntentPromises = []; + this.addedHandlerInfoPerApp = {}; + this.checkIfIntentsResolverIsEnabled(options, appManager); + } + async find(intentFilter) { + await Promise.all(this.unregisterIntentPromises); + let intents = await this.all(); + if (typeof intentFilter === "undefined") { + return intents; + } + if (typeof intentFilter === "string") { + return intents.filter((intent) => intent.name === intentFilter); + } + if (typeof intentFilter !== "object") { + throw new Error("Please provide the intentFilter as a string or an object!"); + } + if (intentFilter.contextType) { + const ctToLower = intentFilter.contextType.toLowerCase(); + intents = intents.filter((intent) => intent.handlers.some((handler) => { var _a; return (_a = handler.contextTypes) === null || _a === void 0 ? void 0 : _a.some((ct) => ct.toLowerCase() === ctToLower); })); + } + if (intentFilter.resultType) { + const resultTypeToLower = intentFilter.resultType.toLowerCase(); + intents = intents.filter((intent) => intent.handlers.some((handler) => { var _a; return ((_a = handler.resultType) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === resultTypeToLower; })); + } + if (intentFilter.name) { + intents = intents.filter((intent) => intent.name === intentFilter.name); + } + return intents; + } + async raise(intentRequest) { + if ((typeof intentRequest !== "string" && typeof intentRequest !== "object") || (typeof intentRequest === "object" && typeof intentRequest.intent !== "string")) { + throw new Error("Please provide the intent as a string or an object with an intent property!"); + } + if (typeof intentRequest === "string") { + intentRequest = { intent: intentRequest }; + } + validateIntentRequest(intentRequest); + await Promise.all(this.unregisterIntentPromises); + if (intentRequest.clearSavedHandler) { + this.logger.trace(`User removes saved handler for intent ${intentRequest.intent}`); + await this.removeRememberedHandler(intentRequest.intent); + } + const resolverInstance = {}; + const timeout = intentRequest.waitUserResponseIndefinitely ? MAX_SET_TIMEOUT_DELAY : intentRequest.timeout || DEFAULT_RAISE_TIMEOUT_MS; + const resultFromRememberedHandler = await this.checkHandleRaiseWithRememberedHandler(intentRequest, resolverInstance, timeout); + if (resultFromRememberedHandler) { + return resultFromRememberedHandler; + } + const coreRaiseIntentFn = this.coreRaiseIntent.bind(this, { request: intentRequest, resolverInstance, timeout }); + if (intentRequest.waitUserResponseIndefinitely) { + return coreRaiseIntentFn(); + } + const resultPromise = PromiseWrap(coreRaiseIntentFn, timeout, `${ERRORS.TIMEOUT_HIT} hit for intent request ${JSON.stringify(intentRequest)}`); + resultPromise.catch(() => this.handleRaiseOnError(resolverInstance.instanceId)); + return resultPromise; + } + async all() { + await Promise.all(this.unregisterIntentPromises); + let apps; + try { + const result = await this.interop.invoke("T42.ACS.GetApplications", { withIntentsInfo: true }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + apps = result.returned.applications; + } + catch (e) { + this.logger.error(`Failed to get the applications!`, e); + return []; + } + const intents = {}; + const appsWithIntents = apps.filter((app) => app.intents && app.intents.length > 0); + for (const app of appsWithIntents) { + for (const intentDef of app.intents) { + let intent = intents[intentDef.name]; + if (!intent) { + intent = { + name: intentDef.name, + handlers: [], + }; + intents[intentDef.name] = intent; + } + const handler = { + applicationName: app.name, + applicationTitle: app.title || "", + applicationDescription: app.caption, + displayName: intentDef.displayName, + contextTypes: intentDef.contexts, + applicationIcon: app.icon, + type: "app", + resultType: intentDef.resultType + }; + intent.handlers.push(handler); + } + } + const servers = this.interop.servers(); + const serverWindowIds = servers.map((server) => server.windowId).filter((serverWindowId) => typeof serverWindowId !== "undefined"); + const T42WndGetInfo = "T42.Wnd.GetInfo"; + const isT42WndGetInfoMethodRegistered = this.interop.methods().some((method) => method.name === T42WndGetInfo); + let windowsInfos; + if (isT42WndGetInfoMethodRegistered) { + try { + const result = await this.interop.invoke(T42WndGetInfo, { ids: serverWindowIds }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + windowsInfos = result.returned.windows; + } + catch (e) { + } + } + for (const server of servers) { + await Promise.all(server.getMethods() + .filter((method) => method.name.startsWith(GLUE42_FDC3_INTENTS_METHOD_PREFIX)) + .map(async (method) => { + const intentName = method.name.replace(GLUE42_FDC3_INTENTS_METHOD_PREFIX, ""); + let intent = intents[intentName]; + if (!intent) { + intent = { + name: intentName, + handlers: [], + }; + intents[intentName] = intent; + } + const title = await this.windowsIdToTitle(server.windowId, windowsInfos); + const handler = this.constructIntentHandler({ method, apps, server, intentName, title }); + intent.handlers.push(handler); + })); + } + return Object.values(intents); + } + addIntentListener(intent, handler) { + if ((typeof intent !== "string" && typeof intent !== "object") || (typeof intent === "object" && typeof intent.intent !== "string")) { + throw new Error("Please provide the intent as a string or an object with an intent property!"); + } + if (typeof handler !== "function") { + throw new Error("Please provide the handler as a function!"); + } + const intentName = typeof intent === "string" ? intent : intent.intent; + const methodName = `${GLUE42_FDC3_INTENTS_METHOD_PREFIX}${intentName}`; + let intentFlag = {}; + let registerPromise; + const alreadyRegistered = this.myIntents.has(intentName); + if (alreadyRegistered) { + throw new Error(`Intent listener for intent ${intentName} already registered!`); + } + this.myIntents.add(intentName); + const result = { + unsubscribe: () => { + this.myIntents.delete(intentName); + registerPromise + .then(() => this.interop.unregister(methodName)) + .catch((err) => this.logger.trace(`Unregistration of a method with name ${methodName} failed with reason: ${JSON.stringify(err)}`)); + } + }; + if (typeof intent === "object") { + const { intent: removed, ...rest } = intent; + intentFlag = rest; + } + registerPromise = this.interop.register({ name: methodName, flags: { intent: intentFlag } }, (args) => { + if (this.myIntents.has(intentName)) { + return handler(args); + } + }); + registerPromise.catch((err) => { + this.myIntents.delete(intentName); + this.logger.warn(`Registration of a method with name ${methodName} failed with reason: ${JSON.stringify(err)}`); + }); + return result; + } + async register(intent, handler) { + if ((typeof intent !== "string" && typeof intent !== "object") || (typeof intent === "object" && typeof intent.intent !== "string")) { + throw new Error("Please provide the intent as a string or an object with an intent property!"); + } + if (typeof handler !== "function") { + throw new Error("Please provide the handler as a function!"); + } + await Promise.all(this.unregisterIntentPromises); + const intentName = typeof intent === "string" ? intent : intent.intent; + const methodName = this.buildInteropMethodName(intentName); + let intentFlag = {}; + const alreadyRegistered = this.myIntents.has(intentName); + if (alreadyRegistered) { + throw new Error(`Intent listener for intent ${intentName} already registered!`); + } + this.myIntents.add(intentName); + if (typeof intent === "object") { + const { intent: removed, ...rest } = intent; + intentFlag = rest; + } + try { + await this.interop.register({ name: methodName, flags: { intent: intentFlag } }, (args, caller) => { + if (this.myIntents.has(intentName)) { + return handler(args, caller); + } + }); + } + catch (err) { + this.myIntents.delete(intentName); + throw new Error(`Registration of a method with name ${methodName} failed with reason: ${JSON.stringify(err)}`); + } + return { + unsubscribe: () => this.unsubscribeIntent(intentName) + }; + } + async filterHandlers(handlerFilter) { + var _a, _b; + validateHandlerFilter(handlerFilter); + if (handlerFilter.openResolver && !this.useIntentsResolverUI) { + throw new Error("Cannot resolve 'filterHandlers' request using Intents Resolver UI because it's globally disabled"); + } + (_a = this.logger) === null || _a === void 0 ? void 0 : _a.trace(`Received 'filterHandlers' command with request: ${JSON.stringify(handlerFilter)}`); + const filteredHandlers = this.filterHandlersBy(await this.all(), handlerFilter); + if (!filteredHandlers || !filteredHandlers.length) { + return { handlers: [] }; + } + const { open, reason } = this.checkIfResolverShouldBeOpenedForFilterHandlers(filteredHandlers, handlerFilter); + if (!open) { + (_b = this.logger) === null || _b === void 0 ? void 0 : _b.trace(`Intent Resolver UI won't be used. Reason: ${reason}`); + return { handlers: filteredHandlers }; + } + const resolverInstance = { instanceId: undefined }; + const timeout = handlerFilter.timeout || DEFAULT_PICK_HANDLER_BY_TIMEOUT_MS; + const handler = await PromiseWrap(() => this.startResolverApp({ request: handlerFilter, resolverInstance, method: 'filterHandlers' }), timeout, `Timeout of ${timeout}ms hit for 'filterHandlers' request with filter: ${JSON.stringify(handlerFilter)}`); + return { handlers: [handler] }; + } + async getIntents(handler) { + var _a; + this.logger.trace(`Received 'getIntents' command with handler ${JSON.stringify(handler)}`); + validateIntentHandler(handler); + const intents = await this.all(); + clearNullUndefined(handler); + (_a = this.logger) === null || _a === void 0 ? void 0 : _a.trace(`Extracting valid intents for the passed handler`); + const intentsWithInfo = this.extractIntentsWithInfoByHandler(intents, handler); + this.logger.trace(`Returning intents for handler ${JSON.stringify(handler)}`); + return { intents: intentsWithInfo }; + } + async clearSavedHandlers() { + this.logger.trace("Removing all saved handlers from prefs storage for current app"); + await this.prefsController.update({ intents: undefined }); + } + onHandlerAdded(callback) { + var _a; + const unAppAdded = (_a = this.appManager) === null || _a === void 0 ? void 0 : _a.onAppAdded(async (app) => { + var _a; + const appName = app.name; + const appDef = await app.getConfiguration(); + const isIntentHandler = (_a = appDef === null || appDef === void 0 ? void 0 : appDef.intents) === null || _a === void 0 ? void 0 : _a.length; + if (!isIntentHandler) { + return; + } + appDef.intents.forEach((intent) => { + const handler = this.constructIntentHandlerFromApp(appDef, intent); + if (!this.addedHandlerInfoPerApp[appName]) { + this.addedHandlerInfoPerApp[appName] = []; + } + const appHandlers = this.addedHandlerInfoPerApp[appName]; + appHandlers.push({ handler, name: intent.name }); + callback(handler, intent.name); + }); + }); + const unServerMethodAdded = this.interop.serverMethodAdded(({ method, server }) => { + if (!method.name.startsWith(GLUE42_FDC3_INTENTS_METHOD_PREFIX)) { + return; + } + const intentName = method.name.replace(GLUE42_FDC3_INTENTS_METHOD_PREFIX, ""); + const intentsInfo = this.constructIntentHandler({ method, apps: [], server, intentName, title: "" }); + callback(intentsInfo, intentName); + }); + return () => { + if (typeof unServerMethodAdded === "function") { + unServerMethodAdded(); + } + if (typeof unAppAdded === "function") { + unAppAdded(); + } + }; + } + onHandlerRemoved(callback) { + var _a; + const unAppRemoved = (_a = this.appManager) === null || _a === void 0 ? void 0 : _a.onAppRemoved(async (app) => { + const appName = app.name; + const handlers = this.addedHandlerInfoPerApp[appName]; + const isIntentHandler = handlers === null || handlers === void 0 ? void 0 : handlers.length; + if (!isIntentHandler) { + return; + } + delete this.addedHandlerInfoPerApp[appName]; + handlers.forEach((addedHandlerInfo) => { + callback(addedHandlerInfo.handler, addedHandlerInfo.name); + }); + }); + const unServerMethodAdded = this.interop.serverMethodRemoved(({ method, server }) => { + if (!method.name.startsWith(GLUE42_FDC3_INTENTS_METHOD_PREFIX)) { + return; + } + const intentName = method.name.replace(GLUE42_FDC3_INTENTS_METHOD_PREFIX, ""); + const intentsInfo = this.constructIntentHandler({ method, apps: [], server, intentName, title: "" }); + callback(intentsInfo, intentName); + }); + return () => { + if (typeof unServerMethodAdded === "function") { + unServerMethodAdded(); + } + if (typeof unAppRemoved === "function") { + unAppRemoved(); + } + }; + } + toAPI() { + return { + all: this.all.bind(this), + find: this.find.bind(this), + raise: this.raise.bind(this), + addIntentListener: this.addIntentListener.bind(this), + register: this.register.bind(this), + filterHandlers: this.filterHandlers.bind(this), + getIntents: this.getIntents.bind(this), + clearSavedHandlers: this.clearSavedHandlers.bind(this), + onHandlerAdded: this.onHandlerAdded.bind(this), + onHandlerRemoved: this.onHandlerRemoved.bind(this) + }; + } + filterHandlersBy(intents, filter) { + const filteredIntentsWithHandlers = intents.filter((intent) => { + if (filter.intent && filter.intent !== intent.name) { + return; + } + if (filter.resultType) { + const filteredHandlers = intent.handlers.filter((handler) => handler.resultType && handler.resultType === filter.resultType); + if (!filteredHandlers.length) + return; + intent.handlers = filteredHandlers; + } + if (filter.contextTypes) { + const filteredHandlers = intent.handlers.filter((handler) => { var _a; return (_a = filter.contextTypes) === null || _a === void 0 ? void 0 : _a.every((contextType) => { var _a; return (_a = handler.contextTypes) === null || _a === void 0 ? void 0 : _a.includes(contextType); }); }); + if (!filteredHandlers.length) + return; + intent.handlers = filteredHandlers; + } + if (filter.applicationNames) { + const filteredHandlers = intent.handlers.filter((handler) => { var _a; return (_a = filter.applicationNames) === null || _a === void 0 ? void 0 : _a.includes(handler.applicationName); }); + if (!filteredHandlers.length) + return; + intent.handlers = filteredHandlers; + } + return intent; + }); + return filteredIntentsWithHandlers.map((intent) => intent.handlers).flat(1); + } + async coreRaiseIntent({ request, resolverInstance, timeout }) { + var _a, _b; + const intentDef = await this.get(request.intent); + if (typeof intentDef === "undefined") { + throw new Error(`${ERRORS.INTENT_NOT_FOUND} with name ${request.intent}`); + } + const { open, reason } = await this.checkIfResolverShouldBeOpenedForRaise(intentDef, request); + if (!open) { + this.logger.trace(`Intent Resolver UI won't be used. Reason: ${reason}`); + return request.waitUserResponseIndefinitely + ? PromiseWrap(() => this.raiseIntent(request, timeout), timeout, `${ERRORS.TIMEOUT_HIT} - waited ${timeout}ms for 'raise' to resolve`) + : this.raiseIntent(request, timeout); + } + const resolverHandler = await this.startResolverApp({ request, method: "raise", resolverInstance }); + (_a = this.logger) === null || _a === void 0 ? void 0 : _a.trace(`Raising intent to target handler: ${JSON.stringify(resolverHandler)} with timeout of ${timeout}`); + if (request.waitUserResponseIndefinitely) { + return PromiseWrap(() => this.raiseIntentToTargetHandler(request, resolverHandler, timeout), timeout, `${ERRORS.TIMEOUT_HIT} - waited ${timeout}ms for 'raise' to resolve`); + } + const result = await this.raiseIntentToTargetHandler(request, resolverHandler, timeout); + (_b = this.logger) === null || _b === void 0 ? void 0 : _b.trace(`Result from raise() method for intent ${JSON.stringify(request.intent)}: ${JSON.stringify(result)}`); + return result; + } + async get(intent) { + return (await this.all()).find((registeredIntent) => registeredIntent.name === intent); + } + async raiseIntent(intentRequest, timeout) { + const intentName = intentRequest.intent; + const intentDef = await this.get(intentName); + if (typeof intentDef === "undefined") { + throw new Error(`${ERRORS.INTENT_NOT_FOUND} with name ${intentRequest.intent}`); + } + const firstFoundAppHandler = intentRequest.handlers ? this.findHandlerByFilter(intentRequest.handlers, { type: "app" }) : this.findHandlerByFilter(intentDef.handlers, { type: "app" }); + const firstFoundInstanceHandler = intentRequest.handlers ? this.findHandlerByFilter(intentRequest.handlers, { type: "instance" }) : this.findHandlerByFilter(intentDef.handlers, { type: "instance" }); + let handler; + if (!intentRequest.target || intentRequest.target === "reuse") { + handler = firstFoundInstanceHandler || firstFoundAppHandler; + } + if (intentRequest.target === "startNew") { + handler = firstFoundAppHandler; + } + if (typeof intentRequest.target === "object" && intentRequest.target.app) { + handler = this.findHandlerByFilter(intentDef.handlers, { app: intentRequest.target.app }); + } + if (typeof intentRequest.target === "object" && intentRequest.target.instance) { + handler = this.findHandlerByFilter(intentDef.handlers, { instance: intentRequest.target.instance, app: intentRequest.target.app }); + } + if (!handler) { + throw new Error(`Can not raise intent for request ${JSON.stringify(intentRequest)} - can not find intent handler!`); + } + const result = await this.raiseIntentToTargetHandler(intentRequest, handler, timeout); + return result; + } + async raiseIntentToTargetHandler(intentRequest, handler, timeout) { + var _a, _b; + (_a = this.logger) === null || _a === void 0 ? void 0 : _a.trace(`Raising intent to target handler:${JSON.stringify(handler)}`); + if (!handler.instanceId) { + const instanceIdPromise = this.invokeStartApp(handler.applicationName, intentRequest.context, intentRequest.options).catch((err) => { + const reasonMsg = typeof err === "string" ? err : JSON.stringify(err); + throw new Error(`${ERRORS.TARGET_INSTANCE_UNAVAILABLE}. Reason: ${reasonMsg}`); + }); + handler.instanceId = await instanceIdPromise; + } + const methodName = `${GLUE42_FDC3_INTENTS_METHOD_PREFIX}${intentRequest.intent}`; + const invokeOptions = { + methodResponseTimeoutMs: timeout ? timeout + 1000 : DEFAULT_METHOD_RESPONSE_TIMEOUT_MS, + waitTimeoutMs: timeout ? timeout + 1000 : DEFAULT_METHOD_RESPONSE_TIMEOUT_MS + }; + const resultPromise = this.interop.invoke(methodName, intentRequest.context, { instance: handler.instanceId }, invokeOptions) + .catch((err) => { + const reasonMsg = typeof err === "string" ? err : JSON.stringify(err); + throw new Error(`${ERRORS.INTENT_HANDLER_REJECTION}. Reason: ${reasonMsg}`); + }); + const result = await resultPromise; + (_b = this.logger) === null || _b === void 0 ? void 0 : _b.trace(`raiseIntent command completed. Returning result: ${JSON.stringify(result)}`); + return { + request: intentRequest, + handler: { ...handler, type: "instance" }, + result: result.returned + }; + } + async startResolverApp({ request, method, resolverInstance }) { + var _a, _b, _c, _d; + (_a = this.logger) === null || _a === void 0 ? void 0 : _a.trace(`Intents Resolver UI with app name ${this.intentsResolverAppName} will be used for request: ${JSON.stringify(request)}`); + const responseMethodName = await this.registerIntentResolverMethod(); + (_b = this.logger) === null || _b === void 0 ? void 0 : _b.trace(`Registered interop method ${responseMethodName}`); + const startContext = this.buildStartContext(method, request, responseMethodName); + const startOptions = await this.buildStartOptions(); + (_c = this.logger) === null || _c === void 0 ? void 0 : _c.trace(`Starting Intents Resolver UI with context: ${JSON.stringify(startContext)} and options: ${JSON.stringify(startOptions)}`); + const instance = await this.appManager.application(this.intentsResolverAppName).start(startContext, startOptions); + resolverInstance.instanceId = instance.id; + (_d = this.logger) === null || _d === void 0 ? void 0 : _d.trace(`Intents Resolver instance with id ${instance.id} opened`); + this.subscribeOnInstanceStopped(instance, method); + const timeout = request.timeout || method === "raise" ? DEFAULT_RAISE_TIMEOUT_MS : DEFAULT_PICK_HANDLER_BY_TIMEOUT_MS; + this.createResponsePromise({ + intent: method === "raise" ? request.intent : undefined, + instanceId: instance.id, + responseMethodName, + timeout, + errorMsg: `Timeout of ${timeout}ms hit waiting for the user to choose a handler ${method === "raise" + ? `for intent ${request.intent}` + : `for '${method}' method with filter ${JSON.stringify(request)}`}` + }); + const handler = await this.handleInstanceResponse({ instanceId: instance.id, caller: startContext.initialCaller, method, request }); + return handler; + } + async windowsIdToTitle(id, windowsInfos) { + var _a, _b; + if (typeof windowsInfos !== "undefined") { + return (_a = windowsInfos.find((windowsInfo) => windowsInfo.id === id)) === null || _a === void 0 ? void 0 : _a.title; + } + const window = (_b = this.windows) === null || _b === void 0 ? void 0 : _b.findById(id); + const title = await (window === null || window === void 0 ? void 0 : window.getTitle()); + return title; + } + async handleInstanceResponse({ instanceId, method, request, caller }) { + var _a, _b, _c; + try { + const response = await this.intentsResolverResponsePromises[instanceId].promise; + const subMessage = method === "raise" ? `for intent ${response.intent} ` : ""; + (_a = this.logger) === null || _a === void 0 ? void 0 : _a.trace(`Intent handler chosen ${subMessage}: ${JSON.stringify(response.handler)}. Stopping resolver instance with id ${instanceId}`); + this.stopResolverInstance(instanceId); + (_b = this.logger) === null || _b === void 0 ? void 0 : _b.trace(`Instance with id ${instanceId} successfully stopped`); + if ((_c = response.userSettings) === null || _c === void 0 ? void 0 : _c.preserveChoice) { + await this.saveUserChoice({ + intent: response.intent, + handler: response.handler, + filter: method === "filterHandlers" + ? { applicationNames: request.applicationNames, contextTypes: request.contextTypes, resultType: request.resultType } + : undefined, + caller + }); + } + return response.handler; + } + catch (error) { + this.stopResolverInstance(instanceId); + throw new Error(error); + } + } + async registerIntentResolverMethod() { + const methodName = INTENTS_RESOLVER_INTEROP_PREFIX + Utils.generateId(); + await this.interop.register(methodName, (args, callerId) => this.resolverResponseHandler(args, callerId)); + return methodName; + } + resolverResponseHandler(args, callerId) { + const { instance } = callerId; + const isValid = validateResolverResponse(args); + if (!isValid) { + this.logger.trace(`Intent Resolver instance with id ${callerId.instance} sent invalid response. Error: ${isValid.error}`); + this.intentsResolverResponsePromises[instance].reject(isValid.error); + this.stopResolverInstance(instance); + return; + } + const validResponse = isValid.ok; + this.intentsResolverResponsePromises[instance].resolve(validResponse); + this.cleanUpIntentResolverPromise(instance); + } + buildStartContext(method, request, methodName) { + var _a; + const myAppName = this.interop.instance.application || this.interop.instance.applicationName; + const myAppTitle = ((_a = this.appManager.application(myAppName)) === null || _a === void 0 ? void 0 : _a.title) || ""; + const baseStartContext = { + callerId: this.interop.instance.instance, + methodName, + initialCaller: { id: this.interop.instance.instance, applicationName: myAppName, applicationTitle: myAppTitle }, + resolverApi: "1.0" + }; + return method === "raise" + ? { ...baseStartContext, intent: request } + : { ...baseStartContext, handlerFilter: request }; + } + async buildStartOptions() { + const win = this.windows.my(); + if (!win) { + return; + } + const bounds = await win.getBounds(); + return { + top: await this.getResolverStartupTopBound(bounds), + left: (bounds.width - INTENTS_RESOLVER_WIDTH) / 2 + bounds.left, + width: INTENTS_RESOLVER_WIDTH, + height: INTENTS_RESOLVER_HEIGHT + }; + } + async getResolverStartupTopBound(bounds) { + const myDisplay = await this.windows.my().getDisplay(); + const minWorkareaHeight = myDisplay.workArea.height; + const top = (bounds.height - INTENTS_RESOLVER_HEIGHT) / 2 + bounds.top; + if (top < 0) { + return 0; + } + if (top + INTENTS_RESOLVER_HEIGHT > minWorkareaHeight) { + return minWorkareaHeight / 2; + } + return top; + } + createResponsePromise({ instanceId, intent, responseMethodName, timeout, errorMsg }) { + let resolve = () => { }; + let reject = () => { }; + const promise = PromisePlus((res, rej) => { + resolve = res; + reject = rej; + }, timeout, errorMsg); + this.intentsResolverResponsePromises[instanceId] = { intent, resolve, reject, promise, methodName: responseMethodName }; + } + async invokeStartApp(application, context, options) { + const result = await this.interop.invoke("T42.ACS.StartApplication", { Name: application, options: { ...options, startedByIntentAPI: true } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return result.returned.Id; + } + subscribeOnInstanceStopped(instance, method) { + const { application } = instance; + const unsub = application.onInstanceStopped((inst) => { + if (inst.id !== instance.id) { + return; + } + const intentPromise = this.intentsResolverResponsePromises[inst.id]; + if (!intentPromise) { + return unsub(); + } + const errorMsg = `Cannot resolve ${method === "raise" ? `raised intent ${intentPromise.intent}` : `'${method}' method`} - User closed ${instance.application.name} app without choosing a handler`; + intentPromise.reject(errorMsg); + this.cleanUpIntentResolverPromise(inst.id); + unsub(); + }); + } + async cleanUpIntentResolverPromise(instanceId) { + const intentPromise = this.intentsResolverResponsePromises[instanceId]; + if (!intentPromise) { + return; + } + const unregisterPromise = this.interop.unregister(intentPromise.methodName); + unregisterPromise.catch((error) => this.logger.warn(error)); + delete this.intentsResolverResponsePromises[instanceId]; + } + handleRaiseOnError(instanceId) { + if (!instanceId) { + return; + } + this.stopResolverInstance(instanceId); + } + stopResolverInstance(instanceId) { + const gdWin = this.windows.findById(instanceId); + gdWin === null || gdWin === void 0 ? void 0 : gdWin.close().catch((err) => this.logger.error(err)); + } + checkIfIntentsResolverIsEnabled(options, appManager) { + var _a, _b, _c, _d, _e; + if (!appManager) { + this.useIntentsResolverUI = false; + return; + } + this.useIntentsResolverUI = typeof ((_a = options.intents) === null || _a === void 0 ? void 0 : _a.enableIntentsResolverUI) === "boolean" + ? options.intents.enableIntentsResolverUI + : true; + this.intentsResolverAppName = (_c = (_b = options.intents) === null || _b === void 0 ? void 0 : _b.intentsResolverAppName) !== null && _c !== void 0 ? _c : INTENTS_RESOLVER_APP_NAME; + this.intentsResolverResponseTimeout = (_e = (_d = options.intents) === null || _d === void 0 ? void 0 : _d.methodResponseTimeoutMs) !== null && _e !== void 0 ? _e : DEFAULT_RESOLVER_RESPONSE_TIMEOUT; + } + async checkIfResolverShouldBeOpenedForRaise(intent, request) { + const checkOpen = this.checkIfIntentsResolverShouldBeOpened(); + if (!checkOpen.open) { + return checkOpen; + } + const hasMoreThanOneHandler = await this.checkIfIntentHasMoreThanOneHandler(intent, request); + if (!hasMoreThanOneHandler) { + return { open: false, reason: `Raised intent ${intent.name} has only one handler` }; + } + return { open: true }; + } + checkIfResolverShouldBeOpenedForFilterHandlers(handlers, filter) { + if (handlers.length === 1) { + return { open: false, reason: `There's only one valid intent handler for filter ${JSON.stringify(filter)}` }; + } + if (typeof (filter === null || filter === void 0 ? void 0 : filter.openResolver) === "boolean" && !filter.openResolver) { + return { open: false, reason: "Intents resolver is disabled by IntentHandler filter" }; + } + return this.checkIfIntentsResolverShouldBeOpened(); + } + checkIfIntentsResolverShouldBeOpened() { + if (!this.useIntentsResolverUI) { + return { open: false, reason: `Intent Resolver is disabled. Resolving to first found handler` }; + } + const intentsResolverApp = this.appManager.application(this.intentsResolverAppName); + if (!intentsResolverApp) { + return { open: false, reason: `Intent Resolver Application with name ${this.intentsResolverAppName} not found.` }; + } + return { open: true }; + } + async checkIfIntentHasMoreThanOneHandler(intent, request) { + const handlers = await this.removeSingletons(request.handlers || intent.handlers); + if (!request.target) { + return handlers.length > 1; + } + if (request.target === "reuse") { + return handlers.filter(handler => handler.type === "instance" && handler.instanceId).length > 1 || intent.handlers.filter(handler => handler.type === "app").length > 1; + } + if (request.target === "startNew") { + return handlers.filter(handler => handler.type === "app").length > 1; + } + if (request.target.instance) { + return false; + } + if (request.target.app) { + const searchedAppName = request.target.app; + const instanceHandlersByAppName = handlers.filter((handler) => handler.applicationName === searchedAppName && handler.instanceId); + return instanceHandlersByAppName.length > 1; + } + return false; + } + async removeSingletons(handlers) { + const handlersWithSingletonProp = await Promise.all(handlers.map(async (handler) => { + if (handler.type === "instance") { + return handler; + } + const appConfig = await this.appManager.application(handler.applicationName).getConfiguration(); + const isSingleton = appConfig.allowMultiple === false; + return { ...handler, isSingleton }; + })); + const filteredSingletonsWithOpenedInstances = handlersWithSingletonProp.filter((handler, _, currentHandlers) => { + if (handler.instanceId || !handler.isSingleton) { + return handler; + } + const openedInstance = currentHandlers.find((h) => h.instanceId && h.applicationName === handler.applicationName); + if (openedInstance) { + return; + } + return handler; + }); + return filteredSingletonsWithOpenedInstances; + } + buildInteropMethodName(intentName) { + return `${GLUE42_FDC3_INTENTS_METHOD_PREFIX}${intentName}`; + } + clearUnregistrationPromise(promiseToRemove) { + this.unregisterIntentPromises = this.unregisterIntentPromises.filter((promise) => promise !== promiseToRemove); + } + unsubscribeIntent(intentName) { + this.myIntents.delete(intentName); + const methodName = this.buildInteropMethodName(intentName); + const unregisterPromise = this.interop.unregister(methodName); + this.unregisterIntentPromises.push(unregisterPromise); + unregisterPromise + .then(() => { + this.clearUnregistrationPromise(unregisterPromise); + }) + .catch((err) => { + this.logger.error(`Unregistration of a method with name ${methodName} failed with reason: `, err); + this.clearUnregistrationPromise(unregisterPromise); + }); + } + findHandlerByFilter(handlers, filter) { + if (filter.type) { + return handlers.find((handler) => handler.type === filter.type); + } + if (filter.instance) { + return handlers.find((handler) => filter.app + ? handler.applicationName === filter.app && handler.instanceId === filter.instance + : handler.instanceId === filter.instance); + } + if (filter.app) { + return handlers.find((handler) => handler.applicationName === filter.app); + } + } + extractIntentsWithInfoByHandler(intents, handler) { + const intentsWithInfo = intents.reduce((validIntentsWithInfo, intent) => { + intent.handlers.forEach((currentHandler) => { + const isValid = Object.keys(handler).every((key) => { + var _a; + return key === "contextTypes" + ? (_a = handler.contextTypes) === null || _a === void 0 ? void 0 : _a.every((contextType) => { var _a; return (_a = currentHandler.contextTypes) === null || _a === void 0 ? void 0 : _a.includes(contextType); }) + : currentHandler[key] === handler[key]; + }); + if (!isValid) { + return; + } + const intentWithInfo = { + intent: intent.name, + contextTypes: currentHandler.contextTypes, + description: currentHandler.applicationDescription, + displayName: currentHandler.displayName, + icon: currentHandler.applicationIcon, + resultType: currentHandler.resultType + }; + validIntentsWithInfo.push(intentWithInfo); + }); + return validIntentsWithInfo; + }, []); + return intentsWithInfo; + } + async removeRememberedHandler(intentName) { + var _a; + this.logger.trace(`Removing saved handler from prefs storage for intent ${intentName}`); + let prefs; + try { + prefs = await this.prefsController.get(); + } + catch (error) { + this.logger.warn(`prefs.get() threw the following error: ${typeof error === "string" ? error : JSON.stringify(error)}`); + return; + } + const intentPrefs = (_a = prefs.data) === null || _a === void 0 ? void 0 : _a.intents; + if (!intentPrefs) { + this.logger.trace("No app prefs found for current app"); + return; + } + delete intentPrefs[intentName]; + const updatedPrefs = { + ...prefs.data, + intents: intentPrefs + }; + try { + await this.prefsController.update(updatedPrefs); + } + catch (error) { + this.logger.warn(`prefs.update() threw the following error: ${typeof error === "string" ? error : JSON.stringify(error)}`); + return; + } + this.logger.trace(`Handler saved choice for intent ${intentName} removed successfully`); + } + async checkForRememberedHandler(intentRequest) { + var _a, _b; + let prefs; + try { + prefs = await this.prefsController.get(); + } + catch (error) { + this.logger.warn(`prefs.get() threw the following error: ${typeof error === "string" ? error : JSON.stringify(error)}`); + return; + } + const prefsForIntent = (_b = (_a = prefs.data) === null || _a === void 0 ? void 0 : _a.intents) === null || _b === void 0 ? void 0 : _b[intentRequest.intent]; + return prefsForIntent === null || prefsForIntent === void 0 ? void 0 : prefsForIntent.handler; + } + async checkHandleRaiseWithRememberedHandler(intentRequest, resolverInstance, timeout) { + if (intentRequest.target) { + return; + } + const rememberedHandler = await this.checkForRememberedHandler(intentRequest); + if (!rememberedHandler) { + return; + } + const request = { + ...intentRequest, + target: { + app: rememberedHandler.applicationName, + instance: rememberedHandler.instanceId + } + }; + try { + const response = await this.coreRaiseIntent({ request, resolverInstance, timeout }); + return response; + } + catch (error) { + this.logger.trace("Could not raise intent to remembered handler. Removing it from Prefs store"); + await this.removeRememberedHandler(intentRequest.intent); + } + } + async saveUserChoice({ intent, handler, filter, caller }) { + var _a, _b; + const prevPrefs = await this.prefsController.get(caller.applicationName); + const prevIntentsPrefs = ((_a = prevPrefs === null || prevPrefs === void 0 ? void 0 : prevPrefs.data) === null || _a === void 0 ? void 0 : _a.intents) || {}; + const prefsToUpdate = { + ...prevPrefs.data, + intents: { + ...prevIntentsPrefs, + [intent]: { handler, filter } + } + }; + await this.prefsController.update(prefsToUpdate, { app: caller.applicationName }); + (_b = this.logger) === null || _b === void 0 ? void 0 : _b.info(`Saved user's choice of handler for '${caller.applicationName}' app`); + } + constructIntentHandler({ apps, intentName, method, server, title }) { + const info = method.flags.intent; + const app = apps.find((appWithIntents) => appWithIntents.name === server.application); + let appIntent; + if (app === null || app === void 0 ? void 0 : app.intents) { + appIntent = app.intents.find((appDefIntent) => appDefIntent.name === intentName); + } + const handler = { + instanceId: server.instance, + applicationName: server.application, + applicationIcon: info.icon || (app === null || app === void 0 ? void 0 : app.icon), + applicationTitle: (app === null || app === void 0 ? void 0 : app.title) || "", + applicationDescription: info.description || (app === null || app === void 0 ? void 0 : app.caption), + displayName: info.displayName || (appIntent === null || appIntent === void 0 ? void 0 : appIntent.displayName), + contextTypes: info.contextTypes || (appIntent === null || appIntent === void 0 ? void 0 : appIntent.contexts), + instanceTitle: title, + type: "instance", + resultType: (appIntent === null || appIntent === void 0 ? void 0 : appIntent.resultType) || info.resultType + }; + return handler; + } + constructIntentHandlerFromApp(app, intent) { + return { + applicationName: app.name, + applicationTitle: app.title || "", + applicationDescription: app.caption, + displayName: intent.displayName, + contextTypes: intent.contexts, + applicationIcon: app.icon, + type: "app", + resultType: intent.resultType + }; + } + } + + class FactoryCallInfo { + constructor() { + this.initialized = false; + this.details = []; + this.reject = () => { }; + this.resolve = () => { }; + } + init(config) { + this.initialized = true; + this.addCall(config); + this.promise = new Promise((resolve, reject) => { + this.resolve = resolve; + this.reject = reject; + }); + } + addCall(config) { + this.details.push({ date: new Date(), config }); + } + done(g) { + this.resolve(g); + } + error(e) { + this.reject(e); + } + } + + class Prefs { + constructor(appName, interop) { + this.appName = appName; + this.interop = interop; + this.registry = CallbackRegistryFactory(); + this.interopMethodRegistered = false; + } + async get(app) { + const data = (await this.interop.invoke(Prefs.T42GetPrefsMethodName, { app: app !== null && app !== void 0 ? app : this.appName }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + })); + return data.returned; + } + async set(data, options) { + var _a; + this.verifyDataObject(data); + await this.interop.invoke(Prefs.T42SetPrefsMethodName, { app: (_a = options === null || options === void 0 ? void 0 : options.app) !== null && _a !== void 0 ? _a : this.appName, data, merge: false }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async setFor(app, data) { + this.verifyApp(app); + this.verifyDataObject(data); + return this.set(data, { app }); + } + async update(data, options) { + var _a; + this.verifyDataObject(data); + await this.interop.invoke(Prefs.T42SetPrefsMethodName, { app: (_a = options === null || options === void 0 ? void 0 : options.app) !== null && _a !== void 0 ? _a : this.appName, data, merge: true }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async updateFor(app, data) { + this.verifyApp(app); + this.verifyDataObject(data); + return this.update(data, { app }); + } + async clear(app) { + await this.interop.invoke(Prefs.T42SetPrefsMethodName, { app: app !== null && app !== void 0 ? app : this.appName, clear: true }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async clearFor(app) { + this.verifyApp(app); + await this.interop.invoke(Prefs.T42SetPrefsMethodName, { app, clear: true }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async getAll() { + const data = (await this.interop.invoke(Prefs.T42GetPrefsMethodName, undefined, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + })); + return data.returned; + } + async clearAll() { + await this.interop.invoke(Prefs.T42SetPrefsMethodName, { clear: true }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + subscribe(callback) { + this.verifyCallback(callback); + return this.subscribeFor(this.appName, callback); + } + subscribeFor(app, callback) { + this.verifyApp(app); + this.verifyCallback(callback); + const unsubscribeFn = this.registry.add(app, callback); + this.registerInteropIfNeeded() + .then(() => { + this.interop.invoke(Prefs.T42GetPrefsMethodName, { app, subscribe: true }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + }); + return () => { + unsubscribeFn(); + }; + } + async registerInteropIfNeeded() { + if (this.interopMethodRegistered) { + return; + } + this.interopMethodRegistered = true; + await this.interop.register(Prefs.T42UpdatePrefsMethodName, (args) => { + this.registry.execute(args.app, args); + }); + } + verifyApp(app) { + if (!app) { + throw new Error(`app should be defined`); + } + if (!isString(app)) { + throw new Error(`app should be a string`); + } + } + verifyDataObject(data) { + if (!data) { + throw new Error(`data should be defined`); + } + if (!isObject(data)) { + throw new Error(`data should be an object`); + } + } + verifyCallback(callback) { + if (!isFunction(callback)) { + throw new Error(`callback should be defined`); + } + } + } + Prefs.T42UpdatePrefsMethodName = "T42.Prefs.Update"; + Prefs.T42GetPrefsMethodName = "T42.Prefs.Get"; + Prefs.T42SetPrefsMethodName = "T42.Prefs.Set"; + + class Cookies { + constructor(methodName, interop) { + this.methodName = methodName; + this.interop = interop; + } + async get(filter) { + const result = await this.invoke("get-cookies", { filter }); + return result.returned.cookies; + } + async set(cookie) { + this.verifyCookieObject(cookie); + await this.invoke("set-cookie", cookie); + } + async remove(url, name) { + if (!isString(url)) { + throw new Error(`url should be a string`); + } + if (!isString(name)) { + throw new Error(`name should be a string`); + } + await this.invoke("remove-cookie", { url, name }); + } + invoke(command, data) { + return this.interop.invoke(this.methodName, { command, args: data }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_RESPONSE_TIMEOUT_MS, + }); + } + verifyCookieObject(cookie) { + if (!cookie) { + throw new Error(`cookie should be defined`); + } + if (!isObject(cookie)) { + throw new Error(`cookie should be an object`); + } + if (Utils.isNullOrUndefined(cookie.url) || !isString(cookie.url)) { + throw new Error(`cookie.url should be a string`); + } + if (Utils.isNullOrUndefined(cookie.name) || !isString(cookie.name)) { + throw new Error(`cookie.name should be a string`); + } + if (!Utils.isNullOrUndefined(cookie.value) && !isString(cookie.value)) { + throw new Error(`cookie.value should be a string`); + } + if (!Utils.isNullOrUndefined(cookie.domain) && !isString(cookie.domain)) { + throw new Error(`cookie.domain should be a string`); + } + if (!Utils.isNullOrUndefined(cookie.path) && !isString(cookie.path)) { + throw new Error(`cookie.path should be a string`); + } + if (!Utils.isNullOrUndefined(cookie.secure) && typeof cookie.secure !== "boolean") { + throw new Error(`cookie.secure should be a boolean`); + } + if (!Utils.isNullOrUndefined(cookie.httpOnly) && typeof cookie.httpOnly !== "boolean") { + throw new Error(`cookie.httpOnly should be a boolean`); + } + if (!Utils.isNullOrUndefined(cookie.expirationDate) && typeof cookie.expirationDate !== "number") { + throw new Error(`cookie.expirationDate should be a number`); + } + } + } + + function factory$1(agm, methodName) { + const cookies = new Cookies(methodName, agm); + return { + get: cookies.get.bind(cookies), + remove: cookies.remove.bind(cookies), + set: cookies.set.bind(cookies), + ready: () => Promise.resolve() + }; + } + + class EventsDispatcher { + constructor(config) { + this.config = config; + this.glue42EventName = "Glue42"; + this.events = { + notifyStarted: { name: "notifyStarted", handle: this.handleNotifyStarted.bind(this) }, + requestGlue: { name: "requestGlue", handle: this.handleRequestGlue.bind(this) } + }; + } + start(glue) { + if (Utils.isNode()) { + return; + } + this.glue = glue; + this.wireCustomEventListener(); + this.announceStarted(); + } + wireCustomEventListener() { + window.addEventListener(this.glue42EventName, (event) => { + const data = event.detail; + if (!data || !data.glue42) { + return; + } + const glue42Event = data.glue42.event; + const foundHandler = this.events[glue42Event]; + if (!foundHandler) { + return; + } + foundHandler.handle(data.glue42.message); + }); + } + announceStarted() { + this.send("start"); + } + handleRequestGlue() { + if (!this.config.exposeAPI) { + this.send("requestGlueResponse", { error: "Will not give access to the underlying Glue API, because it was explicitly denied upon initialization." }); + return; + } + this.send("requestGlueResponse", { glue: this.glue }); + } + handleNotifyStarted() { + this.announceStarted(); + } + send(eventName, message) { + const payload = { glue42: { event: eventName, message } }; + const event = new CustomEvent(this.glue42EventName, { detail: payload }); + window.dispatchEvent(event); + } + } + + class PromiseWrapper { + static delay(time) { + return new Promise((resolve) => setTimeout(resolve, time)); + } + static async delayForever() { + const biggestPossibleDelay = 2147483647; + while (true) { + await this.delay(biggestPossibleDelay); + } + } + get ended() { + return this.rejected || this.resolved; + } + constructor() { + this.promise = new Promise((resolve, reject) => { + this.resolve = (t) => { + this.resolved = true; + resolve(t); + }; + this.reject = (err) => { + this.rejected = true; + reject(err); + }; + }); + } + } + + class Interception { + constructor() { + this.InterceptorMethodName = "T42.GD.Interception.Execute"; + this.InterceptorHandlerMethodName = "T42.GD.Interception.Handler"; + this.interceptions = []; + } + init(interop) { + this.interop = interop; + } + async register(request) { + if (!request || typeof request !== "object" || Array.isArray(request)) { + throw new Error(`Please provide a valid object.`); + } + const handler = request.handler; + if (typeof handler !== "function") { + throw new Error("Please provide a valid handler function."); + } + const interceptions = request.interceptions; + this.validateInterceptions(interceptions); + this.interceptions.push(request); + try { + await this.interop.invoke(this.InterceptorMethodName, { + command: "register", + interceptions + }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + await this.registerMethodIfNotRegistered(); + } + catch (error) { + this.interceptions = this.interceptions.filter((i) => i !== request); + const message = error.message || "Unknown error"; + const newError = new Error(`Failed to register interception: ${message}`); + throw newError; + } + } + async unregister(request) { + if (!request || typeof request !== "object" || Array.isArray(request)) { + throw new Error(`Please provide a valid object.`); + } + const interceptions = request.interceptions; + this.validateInterceptions(interceptions); + try { + await this.interop.invoke(this.InterceptorMethodName, { + command: "unregister", + interceptions + }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + this.interceptions = this.interceptions.filter((config) => { + return !interceptions.some((interception) => { + return config.interceptions.some((i) => { + return i.domain === interception.domain && i.operation === interception.operation; + }); + }); + }); + } + catch (error) { + const message = error.message || "Unknown error"; + const newError = new Error(`Failed to unregister interception: ${message}`); + throw newError; + } + } + async handleInterception(domain, operation, operationArgs, phase) { + if (this.interop.methods(this.InterceptorMethodName).length === 0) { + return {}; + } + const result = await this.interop.invoke(this.InterceptorMethodName, { + command: "raiseInterception", + interceptions: [{ + operationArgs, + domain, + operation, + phase + }] + }, 'best', { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return result.returned; + } + static createProxyObject(apiToIntercept, domain, interception) { + const methods = Interception.OperationsPerDomain[domain] || []; + const handler = { + get(target, propertyKey, receiver) { + const property = Reflect.get(target, propertyKey, receiver); + try { + if (typeof property !== "function") { + return property; + } + const shouldIntercept = methods.includes(propertyKey); + const isAwaitable = Utils.isPromise(property) || Utils.isAsyncFunction(property); + if (!shouldIntercept || !isAwaitable) { + return property; + } + return Interception.interceptMethod(property, propertyKey, target, domain, interception); + } + catch (error) { + return property; + } + } + }; + const proxyAPI = new Proxy(apiToIntercept, handler); + return proxyAPI; + } + static interceptMethod(originalMethod, propertyKey, target, domain, interception) { + return async function (...args) { + const beforeInterceptionResult = await interception.handleInterception(domain, propertyKey, args, "before"); + if (!Utils.isNullOrUndefined(beforeInterceptionResult.operationResult)) { + return beforeInterceptionResult.operationResult; + } + if (!Utils.isNullOrUndefined(beforeInterceptionResult.operationArgs)) { + args = beforeInterceptionResult.operationArgs; + } + const methodResult = await originalMethod.apply(target, args); + const afterInterceptionResult = await interception.handleInterception(domain, propertyKey, [methodResult], "after"); + if (!Utils.isNullOrUndefined(afterInterceptionResult.operationResult)) { + return afterInterceptionResult.operationResult; + } + return methodResult; + }; + } + toAPI() { + return { + register: this.register.bind(this), + unregister: this.unregister.bind(this), + }; + } + async registerMethodIfNotRegistered() { + var _a; + if ((_a = this.whenRegisteredPromise) === null || _a === void 0 ? void 0 : _a.ended) { + return; + } + this.whenRegisteredPromise = new PromiseWrapper(); + this.registerMethod(); + } + async registerMethod() { + await this.interop.register(this.InterceptorHandlerMethodName, async (data) => { + const command = data.command; + if (command === "raiseInterception") { + const raisedInterception = data.interception; + const interceptor = this.interceptions.find((config) => { + return config.interceptions.some((interception) => { + return interception.domain === raisedInterception.domain && interception.operation === raisedInterception.operation; + }); + }); + const result = await interceptor.handler(raisedInterception); + return result; + } + }); + this.whenRegisteredPromise.resolve(); + } + validateInterceptions(interceptions) { + if (!Array.isArray(interceptions)) { + throw new Error("Please provide a valid array of interceptions."); + } + if (interceptions.length === 0) { + throw new Error("Please provide at least one interception."); + } + for (const interception of interceptions) { + if (typeof interception === "undefined" || interception === null || typeof interception !== "object" || Array.isArray(interception)) { + throw new Error("Please provide a valid interception object."); + } + if (typeof interception.domain !== "string" || !interception.domain) { + throw new Error("Please provide a valid domain string."); + } + if (typeof interception.operation !== "string" || !interception.operation) { + throw new Error("Please provide a valid operation string."); + } + this.validateTypeString(interception); + } + } + validateTypeString(interception) { + if (!isUndefinedOrNull(interception.phase)) { + const isValidType = ["all", "before", "after"].includes(interception.phase); + if (typeof interception.phase !== "string" || !isValidType) { + throw new Error("Please provide a valid phase string."); + } + } + } + } + Interception.OperationsPerDomain = { + "intents": ["raise"] + }; + + const callInfo = new FactoryCallInfo(); + const factory = async (options) => { + let firstRun = false; + if (!callInfo.initialized) { + firstRun = true; + callInfo.init(options); + } + const glue42gd = typeof window !== "undefined" && window.glue42gd; + if (glue42gd) { + if (!firstRun) { + callInfo.addCall(options); + return callInfo.promise; + } + } + const g = await factoryCore(options, glue42gd); + callInfo.resolve(g); + return g; + }; + const factoryCore = async (options, glue42gd) => { + const T42GDExecuteMethod = "T42.GD.Execute"; + const gdMajorVersion = Utils.getGDMajorVersion(); + options = options || {}; + const glueConfig = prepareConfig(options); + options.gateway = options.gateway || {}; + let _appManager; + let _activity; + let _windows; + let _displays; + let _channels; + let _prefs; + const _interceptors = new Interception(); + const _browserEventsDispatcher = new EventsDispatcher(glueConfig); + function createWindows(core) { + if (glueConfig.windows) { + const windowsLogger = getLibLogger("windows", core.logger, glueConfig.windows); + _windows = WindowsFactory(core.agm, windowsLogger, () => { + return _appManager; + }, () => { + return _displays; + }, () => { + return _channels; + }, gdMajorVersion); + debugLog(_windows); + return _windows; + } + } + function createActivities(core) { + var _a; + if (glueConfig.activities) { + if (ActivityModule.checkIsUsingGW3Implementation && ActivityModule.checkIsUsingGW3Implementation(core.connection)) { + const activityLogger = getLibLogger("activity", core.logger, glueConfig.activities); + _activity = new ActivityModule({ + connection: core.connection, + contexts: core.contexts, + agm: core.agm, + logger: activityLogger, + logLevel: "info", + disableAutoAnnounce: false, + disposeRequestHandling: "exit", + announcementInfo: null, + windows: _windows, + appManagerGetter: () => { + return _appManager; + }, + mode: glueConfig.activities.mode, + typesToTrack: glueConfig.activities.typesToTrack, + activityId: (_a = glue42gd === null || glue42gd === void 0 ? void 0 : glue42gd.activityInfo) === null || _a === void 0 ? void 0 : _a.activityId, + gdMajorVersion + }).api; + debugLog(_activity); + return _activity; + } + } + } + function createAppManager(core) { + if (!glueConfig.appManager) { + return; + } + const logger = getLibLogger("appManager", core.logger, glueConfig.appManager); + _appManager = AppManagerFactory({ + agm: core.agm, + windows: _windows, + logger, + activities: _activity, + mode: glueConfig.appManager.mode, + gdMajorVersion + }); + debugLog(_appManager); + return _appManager; + } + function createLayouts(core) { + var _a; + if (!glueConfig.layouts) { + return; + } + const logger = getLibLogger("layouts", core.logger, glueConfig.layouts); + const layoutsConfig = glueConfig.layouts; + const lay = LayoutsFactory({ + agm: core.agm, + appManager: _appManager, + activityGetter: () => _activity, + logger, + mode: layoutsConfig.mode, + autoSaveWindowContext: (_a = layoutsConfig.autoSaveWindowContext) !== null && _a !== void 0 ? _a : false, + gdMajorVersion + }); + debugLog(lay); + return lay; + } + function createChannels(core) { + if (!glueConfig.channels) { + return; + } + const logger = getLibLogger("channels", core.logger, glueConfig.channels); + if (!core.contexts) { + logger.error("Channels library requires Contexts library to be initialized."); + return; + } + _channels = factory$4({ operationMode: glueConfig.channels.operationMode }, core.contexts, core.agm, () => _windows, () => _appManager, logger); + debugLog(_channels); + return _channels; + } + function createHotkeys(core) { + const hotkeysAPI = factory$3(core.agm); + debugLog(hotkeysAPI); + return hotkeysAPI; + } + function createIntents(core) { + const domain = "intents"; + const intents = new Intents(core.agm, _windows, core.logger.subLogger(domain), options, _prefs, _appManager); + const intentsAPI = intents.toAPI(); + const proxyIntentsAPI = Interception.createProxyObject(intentsAPI, domain, _interceptors); + debugLog(proxyIntentsAPI); + return proxyIntentsAPI; + } + function createNotifications(core) { + const notificationsAPI = new Notifications(core.interop, core.logger).toAPI(); + debugLog(notificationsAPI); + return notificationsAPI; + } + function createDisplaysApi(core) { + if (glueConfig.displays) { + const displaysLogger = getLibLogger("displays", core.logger, glueConfig.displays); + _displays = new DisplayManager(core.agm, displaysLogger); + debugLog(_displays); + return _displays; + } + } + function createThemes(core) { + if (!core.contexts) { + return; + } + const themesAPI = factory$2(core.contexts, core.interop); + debugLog(themesAPI); + return themesAPI; + } + function createPrefs(core) { + var _a, _b; + const appName = (_b = (_a = options.application) !== null && _a !== void 0 ? _a : glue42gd === null || glue42gd === void 0 ? void 0 : glue42gd.applicationName) !== null && _b !== void 0 ? _b : core.interop.instance.application; + _prefs = new Prefs(appName, core.interop); + debugLog(_prefs); + return _prefs; + } + function createCookies(core) { + const api = factory$1(core.interop, T42GDExecuteMethod); + debugLog(api); + return api; + } + function createInterception(core) { + _interceptors.init(core.interop); + debugLog(_interceptors); + return _interceptors.toAPI(); + } + function getLibLogger(loggerName, logger, config) { + const newLogger = logger.subLogger(loggerName); + if (config && config.logger) { + const loggerConfig = config.logger; + if (loggerConfig.console) { + newLogger.consoleLevel(loggerConfig.console); + } + if (loggerConfig.publish) { + newLogger.publishLevel(loggerConfig.publish); + } + } + return newLogger; + } + const ext = { + libs: [ + { name: "windows", create: createWindows }, + { name: "activities", create: createActivities }, + { name: "appManager", create: createAppManager }, + { name: "layouts", create: createLayouts }, + { name: "channels", create: createChannels }, + { name: "hotkeys", create: createHotkeys }, + { name: "displays", create: createDisplaysApi }, + { name: "prefs", create: createPrefs }, + { name: "intents", create: createIntents }, + { name: "notifications", create: createNotifications }, + { name: "themes", create: createThemes }, + { name: "cookies", create: createCookies }, + { name: "interception", create: createInterception } + ], + version, + enrichGlue: (glue) => { + glue.config.activities = glueConfig.activities; + glue.config.windows = glueConfig.windows; + glue.config.appManager = glueConfig.appManager; + glue.config.layouts = glueConfig.layouts; + glue.config.channels = glueConfig.channels; + glue.config.displays = glueConfig.displays; + }, + }; + const currentLog = []; + if (typeof window !== "undefined") { + if (!window.glueFactoryLog) { + window.glueFactoryLog = []; + } + window.glueFactoryLog.push(currentLog); + } + function debugLog(entry) { + currentLog.push(entry); + } + const glueApi = (await IOConnectCoreFactory(options, ext)); + if (Array.isArray(options === null || options === void 0 ? void 0 : options.libraries) && options.libraries.length) { + await Promise.all(options.libraries.map((lib) => lib(glueApi, options))); + } + _browserEventsDispatcher.start(glueApi); + return glueApi; + }; + factory.coreVersion = IOConnectCoreFactory.version; + factory.version = version; + factory.calls = callInfo; + + var _a, _b; + let whatToExpose = factory; + let shouldSetToWindow = true; + if (typeof window !== "undefined") { + const windowAsAny = window; + const iodesktop = (_a = windowAsAny.iodesktop) !== null && _a !== void 0 ? _a : windowAsAny.glue42gd; + if (iodesktop && iodesktop.autoInjected) { + whatToExpose = (_b = windowAsAny.IODesktop) !== null && _b !== void 0 ? _b : windowAsAny.Glue; + shouldSetToWindow = false; + } + if (shouldSetToWindow) { + windowAsAny.Glue = whatToExpose; + windowAsAny.IODesktop = whatToExpose; + } + delete windowAsAny.IOBrowser; + delete windowAsAny.GlueCore; + } + whatToExpose.default = whatToExpose; + var whatToExpose$1 = whatToExpose; + + return whatToExpose$1; + +})); +//# sourceMappingURL=desktop.umd.js.map diff --git a/typescript/solution/portfolio-downloader/src/lib/io.applications.css b/typescript/solution/portfolio-downloader/src/lib/io.applications.css new file mode 100644 index 0000000..98e5910 --- /dev/null +++ b/typescript/solution/portfolio-downloader/src/lib/io.applications.css @@ -0,0 +1,12 @@ +:root{--bs-blue: #007be5;--bs-indigo: #6610f2;--bs-purple: #6f42c1;--bs-pink: #fd397a;--bs-red: #ff511f;--bs-orange: #fd7e14;--bs-yellow: #f9a825;--bs-green: #43a047;--bs-teal: #616161;--bs-cyan: #469eb9;--bs-white: #fff;--bs-gray: #6c757d;--bs-gray-dark: #343a40;--bs-gray-100: #f8f9fa;--bs-gray-200: #e9ecef;--bs-gray-300: #dee2e6;--bs-gray-400: #ced4da;--bs-gray-500: #adb5bd;--bs-gray-600: #6c757d;--bs-gray-700: #495057;--bs-gray-800: #343a40;--bs-gray-900: #212529;--bs-primary: #007be5;--bs-secondary: #616161;--bs-success: #43a047;--bs-info: #469eb9;--bs-warning: #f9a825;--bs-danger: #ff511f;--bs-light: #616161;--bs-dark: #616161;--bs-primary-rgb: 0,123,229;--bs-secondary-rgb: 97,97,97;--bs-success-rgb: 67,160,71;--bs-info-rgb: 70,158,185;--bs-warning-rgb: 249,168,37;--bs-danger-rgb: 255,81,31;--bs-light-rgb: 97,97,97;--bs-dark-rgb: 97,97,97;--bs-white-rgb: 255,255,255;--bs-black-rgb: 0,0,0;--bs-body-color-rgb: 33,37,41;--bs-body-bg-rgb: 255,255,255;--bs-font-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--bs-gradient: linear-gradient(180deg, rgba(255,255,255,0.15), rgba(255,255,255,0));--bs-body-font-family: Montserrat,Helvetica Neue,Arial,sans-serif;--bs-body-font-size: .75rem;--bs-body-font-weight: 400;--bs-body-line-height: 1.5;--bs-body-color: #212529;--bs-body-bg: #fff}:root{--t42-font-family: "Montserrat", "Helvetica Neue", Arial, sans-serif;--t42-font-size: 0.75rem;--bs-gutter-x: 0.938rem;--primary: #007be5;--secondary: #616161;--success: #43a047;--info: #616161;--warning: #f9a825;--danger: #ff511f;--light: #616161;--dark: #616161;--white: #ffffff}.dark{--t42-bg-light-base: 0, 0%;--t42-bg-light-l: 18%;--t42-bg-light: 45, 45, 45;--t42-bg-mid: 37, 37, 37;--t42-bg-dark: 30, 30, 30;--t42-content-color-base: 0, 0%;--t42-content-color: #bababa;--t42-content-color-l: 73%;--t42-content-color-muted: hsl(var(--t42-content-color-base), 63%);--t42-content-color-disabled: hsl(var(--t42-content-color-base), 43%);--t42-color-opacity-025: hsla(var(--t42-content-color-base), 100%, 0.025);--t42-color-opacity-05: hsla(var(--t42-content-color-base), 100%, 0.05);--t42-color-opacity-10: hsla(var(--t42-content-color-base), 100%, 0.1);--t42-color-opacity-20: hsla(var(--t42-content-color-base), 100%, 0.2);--t42-color-opacity-30: hsla(var(--t42-content-color-base), 100%, 0.3);--t42-link-color: hsl(var(--t42-content-color-base), 100%);--t42-shadow: 0 0 12px 0 hsla(var(--t42-content-color-base), 0%, 0.15);--t42-border: 0.0625rem solid var(--t42-color-opacity-10);--t42-logo-icon: url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 xmlns:xlink=%27http://www.w3.org/1999/xlink%27 x=%270px%27 y=%270px%27 viewBox=%270 0 100.2 121%27 style=%27enable-background:new 0 0 100.2 121;%27%3E%3Cpath fill=%27%233A77BC%27 d=%27M59.4,10.6l-8.3,8.3c-0.5,0.5-1.4,0.5-1.9,0l-8.3-8.3c-0.5-0.5-0.5-1.4,0-1.9l8.3-8.3c0.5-0.5,1.4-0.5,1.9,0 l8.3,8.3C59.9,9.2,59.9,10.1,59.4,10.6z M59.3,110.4l-8.3-8.3c-0.5-0.5-1.4-0.5-1.9,0l-8.3,8.3c-0.5,0.5-0.5,1.4,0,1.9l8.3,8.3 c0.5,0.5,1.4,0.5,1.9,0l8.3-8.3C59.9,111.8,59.9,110.9,59.3,110.4z%27/%3E%3Cpath fill=%27%23FFFFFF%27 d=%27M100.1,60.1c0.3,7.3-2.9,14.3-9.3,20.6l-24.7,24.7c-0.6,0.6-1.5,0.6-2.1,0l-8.1-8.1c-0.6-0.6-0.6-1.5,0-2.1 l24.7-24.7c0.1-0.1,0.2-0.2,0.3-0.3c3.2-3.3,4.7-6.7,4.4-10.2c0-0.4-0.1-0.8-0.2-1.3c-0.6-3.3-2.8-7-6.8-11l-9.9-9.9 c-0.3-0.3-0.7-0.5-1.1-0.5c-0.4,0-0.8,0.2-1.3,0.6L34.5,69.6c-0.6,0.6-1.5,0.6-2.1,0L27.7,65c-3.3-3.3-3.8-5.1-1.3-7.6 c11.1-11.2,22-22.1,33.2-33.2c2.7-2.7,5.1-4.2,7.5-4.3c2.5-0.1,4.7,1.2,6.9,3.5l14.3,14.3C95.9,45.3,99.8,52.8,100.1,60.1 L100.1,60.1z M0,60.9c0.3,7.3,3.7,14.3,11.2,21.9l14.8,14.8c2.3,2.3,4.5,3.6,6.9,3.5c2.4-0.1,4.8-1.6,7.5-4.3 c11.1-11.1,22.1-22,33.2-33.2c2.5-2.5,2-4.3-1.3-7.6l-4.7-4.7c-0.6-0.6-1.5-0.6-2.1,0L34,83c-0.5,0.5-0.9,0.6-1.3,0.6 c-0.4,0-0.7-0.1-1.1-0.5L21.3,72.7c-4-4-5.7-7.2-6.3-10.5c-0.1-0.4-0.1-0.8-0.2-1.3c-0.3-3.5,1.2-6.9,4.4-10.2 c0.1-0.1,0.2-0.2,0.3-0.3l24.7-24.7c0.6-0.6,0.6-1.5,0-2.1l-8.1-8.1c-0.6-0.6-1.5-0.6-2.1,0L9.3,40.3C2.9,46.6-0.3,53.5,0,60.9 L0,60.9z%27/%3E%3C/svg%3E%0A");--t42-icon-color: var(--t42-link-color);--t42-list-group-hover-bg-special: hsla(var(--t42-content-color-base), 100%, 0.065);--backdrop-filter: blur(5px) saturate(200%);--accordion-filter: invert(1) brightness(1);--filter-close: invert(1);--t42-body: rgb(var(--t42-bg-dark));--pink: rgb(0 170 200);--t42-link-hover-color: hsl(var(--t42-bg-light-base), 100%);--t42-link-hover-bg: var(--t42-color-opacity-05);--t42-link-active-bg: var(--t42-color-opacity-10);--t42-input-bg: rgb(var(--t42-bg-dark));--t42-input-disabled-bg: Hsla(var(--t42-content-color-base), 100%, 0.075);--t42-tooltip-bg: rgba(var(--t42-bg-dark), 0.85);--t42-modal-bg: rgba(var(--t42-bg-light), 0.75);--t42-table-active-bg: rgba(255, 255, 255, 0.1);--t42-select-indicator: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9IiNFRUVFRUUiIHZpZXdCb3g9IjAgMCAxNiAxNiI+PHBhdGggZD0iTTIuNSA1LjVjLjQtLjQgMS0uNSAxLjYgMGwzLjkgMy43bDMuOS0zLjdjLjUtLjUgMS4xLS40IDEuNiAwYy40LjQuNCAxLjIgMCAxLjZjLS40LjQtNC43IDQuNS00LjcgNC41Yy0uMi4yLS41LjMtLjguM3MtLjYtLjEtLjgtLjNjMCAwLTQuMy00LjEtNC43LTQuNXMtLjQtMS4yIDAtMS42eiI+PC9wYXRoPjwvc3ZnPg==)}.light{--t42-bg-light-base: 0, 0%;--t42-bg-light-l: 100%;--t42-bg-light: 255, 255, 255;--t42-bg-mid: 250, 250, 250;--t42-bg-dark: 245, 245, 245;--t42-content-color-base: 0, 0%;--t42-content-color: #757575;--t42-content-color-l: 46%;--t42-content-color-muted: hsl(var(--t42-content-color-base), 66%);--t42-color-opacity-025: hsla(var(--t42-content-color-base), 0%, 0.025);--t42-color-opacity-05: hsla(var(--t42-content-color-base), 0%, 0.05);--t42-color-opacity-10: hsla(var(--t42-content-color-base), 0%, 0.075);--t42-color-opacity-30: hsla(var(--t42-content-color-base), 0%, 0.1);--t42-color-opacity-20: hsla(var(--t42-content-color-base), 0%, 0.2);--t42-link-color: hsl(var(--t42-content-color-base), 5%);--t42-shadow: 0 0 12px 0 hsla(var(--t42-content-color-base), 0%, 0.05);--t42-border: 0.0625rem solid var(--t42-color-opacity-10);--t42-logo-icon: url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 xmlns:xlink=%27http://www.w3.org/1999/xlink%27 x=%270px%27 y=%270px%27 viewBox=%270 0 100.2 121%27 style=%27enable-background:new 0 0 100.2 121;%27%3E%3Cpath fill=%27%233A77BC%27 d=%27M59.4,10.6l-8.3,8.3c-0.5,0.5-1.4,0.5-1.9,0l-8.3-8.3c-0.5-0.5-0.5-1.4,0-1.9l8.3-8.3c0.5-0.5,1.4-0.5,1.9,0 l8.3,8.3C59.9,9.2,59.9,10.1,59.4,10.6z M59.3,110.4l-8.3-8.3c-0.5-0.5-1.4-0.5-1.9,0l-8.3,8.3c-0.5,0.5-0.5,1.4,0,1.9l8.3,8.3 c0.5,0.5,1.4,0.5,1.9,0l8.3-8.3C59.9,111.8,59.9,110.9,59.3,110.4z%27/%3E%3Cpath fill=%27%23083044%27 d=%27M100.1,60.1c0.3,7.3-2.9,14.3-9.3,20.6l-24.7,24.7c-0.6,0.6-1.5,0.6-2.1,0l-8.1-8.1c-0.6-0.6-0.6-1.5,0-2.1 l24.7-24.7c0.1-0.1,0.2-0.2,0.3-0.3c3.2-3.3,4.7-6.7,4.4-10.2c0-0.4-0.1-0.8-0.2-1.3c-0.6-3.3-2.8-7-6.8-11l-9.9-9.9 c-0.3-0.3-0.7-0.5-1.1-0.5c-0.4,0-0.8,0.2-1.3,0.6L34.5,69.6c-0.6,0.6-1.5,0.6-2.1,0L27.7,65c-3.3-3.3-3.8-5.1-1.3-7.6 c11.1-11.2,22-22.1,33.2-33.2c2.7-2.7,5.1-4.2,7.5-4.3c2.5-0.1,4.7,1.2,6.9,3.5l14.3,14.3C95.9,45.3,99.8,52.8,100.1,60.1 L100.1,60.1z M0,60.9c0.3,7.3,3.7,14.3,11.2,21.9l14.8,14.8c2.3,2.3,4.5,3.6,6.9,3.5c2.4-0.1,4.8-1.6,7.5-4.3 c11.1-11.1,22.1-22,33.2-33.2c2.5-2.5,2-4.3-1.3-7.6l-4.7-4.7c-0.6-0.6-1.5-0.6-2.1,0L34,83c-0.5,0.5-0.9,0.6-1.3,0.6 c-0.4,0-0.7-0.1-1.1-0.5L21.3,72.7c-4-4-5.7-7.2-6.3-10.5c-0.1-0.4-0.1-0.8-0.2-1.3c-0.3-3.5,1.2-6.9,4.4-10.2 c0.1-0.1,0.2-0.2,0.3-0.3l24.7-24.7c0.6-0.6,0.6-1.5,0-2.1l-8.1-8.1c-0.6-0.6-1.5-0.6-2.1,0L9.3,40.3C2.9,46.6-0.3,53.5,0,60.9 L0,60.9z%27/%3E%3C/svg%3E%0A");--t42-icon-color: Hsl(var(--t42-content-color-base), 38%);--t42-list-group-hover-bg-special: hsla(var(--t42-content-color-base), 95%, 0.065);--backdrop-filter: blur(5px) saturate(200%);--accordion-filter: brightness(0%);--filter-close: invert(0);--t42-body: rgb(var(--t42-bg-mid));--t42-link-hover-color: hsl(var(--t42-bg-light-base), 0%);--t42-link-hover-bg: hsl(var(--t42-content-color-base), 95%);--t42-link-active-bg: hsl(var(--t42-content-color-base), 90%);--t42-input-bg: rgb(var(--t42-bg-light));--t42-input-disabled-bg: var(--t42-color-opacity-10);--t42-tooltip-bg: rgba(var(--t42-bg-light), 0.95);--t42-modal-bg: rgba(var(--t42-bg-light), 0.95);--t42-table-active-bg: rgba(0, 0, 0, 0.025);--t42-select-indicator: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9IiM2MTYxNjEiIHZpZXdCb3g9IjAgMCAxNiAxNiI+PHBhdGggZD0iTTIuNSA1LjVjLjQtLjQgMS0uNSAxLjYgMGwzLjkgMy43bDMuOS0zLjdjLjUtLjUgMS4xLS40IDEuNiAwYy40LjQuNCAxLjIgMCAxLjZjLS40LjQtNC43IDQuNS00LjcgNC41Yy0uMi4yLS41LjMtLjguM3MtLjYtLjEtLjgtLjNjMCAwLTQuMy00LjEtNC43LTQuNXMtLjQtMS4yIDAtMS42eiI+PC9wYXRoPjwvc3ZnPg==)}*,*::before,*::after{box-sizing:border-box}@media (prefers-reduced-motion: no-preference){:root{scroll-behavior:smooth}}body{margin:0;font-family:var(--bs-body-font-family);font-size:var(--bs-body-font-size);font-weight:var(--bs-body-font-weight);line-height:var(--bs-body-line-height);color:var(--bs-body-color);text-align:var(--bs-body-text-align);background-color:var(--bs-body-bg);-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:rgba(0,0,0,0)}hr{margin:1rem 0;color:inherit;background-color:currentColor;border:0;opacity:.25}hr:not([size]){height:1px}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem;font-weight:500;line-height:1.2;color:var(--t42-link-color)}h1{font-size:calc(1.26563rem + .1875vw)}@media (min-width: 1200px){h1{font-size:1.40625rem}}h2{font-size:1.125rem}h3{font-size:.98475rem}h4{font-size:.84375rem}h5{font-size:.75rem}h6{font-size:.7035rem}p{margin-top:0;margin-bottom:1rem}abbr[title],abbr[data-bs-original-title]{text-decoration:underline dotted;cursor:help;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}ol,ul{padding-left:2rem}ol,ul,dl{margin-top:0;margin-bottom:1rem}ol ol,ul ul,ol ul,ul ol{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:.875em}mark{padding:0.2rem 0.2rem 0;background-color:#007be5}sub,sup{position:relative;font-size:.75em;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:var(--t42-link-color);text-decoration:underline}a:hover{color:var(--t42-link-hover-color)}a:not([href]):not([class]),a:not([href]):not([class]):hover{color:inherit;text-decoration:none}pre,code,kbd,samp{font-family:var(--bs-font-monospace);font-size:1em;direction:ltr /* rtl:ignore */;unicode-bidi:bidi-override}pre{display:block;margin-top:0;margin-bottom:1rem;overflow:auto;font-size:inherit;color:var(--t42-content-color)}pre code{font-size:inherit;color:inherit;word-break:normal}code{font-size:inherit;color:#469eb9;word-wrap:break-word}a>code{color:inherit}kbd{padding:.2rem .4rem;font-size:inherit;color:#fff;background-color:#212529;border-radius:.25rem}kbd kbd{padding:0;font-size:1em;font-weight:700}figure{margin:0 0 1rem}img,svg{vertical-align:middle}table{caption-side:bottom;border-collapse:collapse}caption{padding-top:.25rem;padding-bottom:.25rem;color:var(--t42-content-color-muted);text-align:left}th{text-align:inherit;text-align:-webkit-match-parent}thead,tbody,tfoot,tr,td,th{border-color:inherit;border-style:solid;border-width:0}label{display:inline-block}button{border-radius:0}button:focus:not(:focus-visible){outline:0}input,button,select,optgroup,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,select{text-transform:none}[role="button"]{cursor:pointer}select{word-wrap:normal}select:disabled{opacity:1}[list]::-webkit-calendar-picker-indicator{display:none}button,[type="button"],[type="reset"],[type="submit"]{-webkit-appearance:button}button:not(:disabled),[type="button"]:not(:disabled),[type="reset"]:not(:disabled),[type="submit"]:not(:disabled){cursor:pointer}::-moz-focus-inner{padding:0;border-style:none}textarea{resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{float:left;width:100%;padding:0;margin-bottom:.5rem;font-size:calc(1.275rem + .3vw);line-height:inherit}@media (min-width: 1200px){legend{font-size:1.5rem}}legend+*{clear:left}::-webkit-datetime-edit-fields-wrapper,::-webkit-datetime-edit-text,::-webkit-datetime-edit-minute,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-year-field{padding:0}::-webkit-inner-spin-button{height:auto}[type="search"]{outline-offset:-2px;-webkit-appearance:textfield}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-color-swatch-wrapper{padding:0}::file-selector-button{font:inherit}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}iframe{border:0}summary{display:list-item;cursor:pointer}progress{vertical-align:baseline}[hidden]{display:none !important}body{color:var(--t42-content-color);font-family:var(--t42-font-family);background-color:var(--t42-body)}a:focus,button:focus,div:focus,span:focus{outline:0}a{text-decoration:none}dt{font-weight:normal}::selection{color:var(--white);background-color:var(--primary)}::-webkit-scrollbar{width:4px;height:4px}::-webkit-scrollbar-track{border-radius:.25rem;background:transparent}::-webkit-scrollbar-thumb{border-radius:.25rem;background:var(--t42-color-opacity-10)}::-webkit-resizer{background:transparent}::-webkit-scrollbar-corner{background:transparent}::-webkit-scrollbar-thumb:window-inactive{background:transparent}::-webkit-scrollbar-thumb:hover,::-webkit-scrollbar-thumb:active{background:Hsla(var(--t42-content-color-base), 100%, 0.05)}.accordion-button{position:relative;display:flex;align-items:center;width:100%;padding:1rem 1.25rem;font-size:.75rem;color:var(--t42-link-color);text-align:left;background-color:Rgb(var(--t42-bg-mid));border:0;border-radius:0;overflow-anchor:none;transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out,border-radius 0.15s ease}@media (prefers-reduced-motion: reduce){.accordion-button{transition:none}}.accordion-button:not(.collapsed){color:var(--t42-link-color);background-color:Rgb(var(--t42-bg-mid));box-shadow:inset 0 -1px 0 var(--t42-color-opacity-10)}.accordion-button:not(.collapsed)::after{background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 16 16%27 fill=%27var%28--t42-link-color%29%27%3e%3cpath fill-rule=%27evenodd%27 d=%27M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z%27/%3e%3c/svg%3e");transform:rotate(-180deg)}.accordion-button::after{flex-shrink:0;width:1.25rem;height:1.25rem;margin-left:auto;content:"";background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 16 16%27 fill=%27var%28--t42-link-color%29%27%3e%3cpath fill-rule=%27evenodd%27 d=%27M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z%27/%3e%3c/svg%3e");background-repeat:no-repeat;background-size:1.25rem;transition:transform 0.2s ease-in-out}@media (prefers-reduced-motion: reduce){.accordion-button::after{transition:none}}.accordion-button:hover{z-index:2}.accordion-button:focus{z-index:3;border-color:#007be5;outline:0;box-shadow:0 0 0 0 rgba(0,123,229,0.25)}.accordion-header{margin-bottom:0}.accordion-item{background-color:Rgb(var(--t42-bg-mid));border:1px solid var(--t42-color-opacity-10)}.accordion-item:first-of-type{border-top-left-radius:0;border-top-right-radius:0}.accordion-item:first-of-type .accordion-button{border-top-left-radius:0;border-top-right-radius:0}.accordion-item:not(:first-of-type){border-top:0}.accordion-item:last-of-type{border-bottom-right-radius:0;border-bottom-left-radius:0}.accordion-item:last-of-type .accordion-button.collapsed{border-bottom-right-radius:0;border-bottom-left-radius:0}.accordion-item:last-of-type .accordion-collapse{border-bottom-right-radius:0;border-bottom-left-radius:0}.accordion-body{padding:1rem 1.25rem}.accordion-flush .accordion-collapse{border-width:0}.accordion-flush .accordion-item{border-right:0;border-left:0;border-radius:0}.accordion-flush .accordion-item:first-child{border-top:0}.accordion-flush .accordion-item:last-child{border-bottom:0}.accordion-flush .accordion-item .accordion-button{border-radius:0}.accordion-button::after,.accordion-button:not(.collapsed)::after{filter:var(--accordion-filter)}.accordion-button:disabled,.accordion-button.disabled{color:var(--t42-content-color-disabled)}.accordion-button:disabled::after,.accordion-button.disabled::after{opacity:0.25}.alert{position:relative;padding:.75rem .875rem;margin-bottom:.5rem;border:1px solid transparent;border-radius:0}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-right:2.625rem}.alert-dismissible .btn-close{position:absolute;top:0;right:0;z-index:2;padding:.9375rem .875rem}.alert-primary{color:#004a89;background-color:#cce5fa;border-color:#b3d7f7}.alert-primary .alert-link{color:#003b6e}.alert-secondary{color:#3a3a3a;background-color:#dfdfdf;border-color:#d0d0d0}.alert-secondary .alert-link{color:#2e2e2e}.alert-success{color:#28602b;background-color:#d9ecda;border-color:#c7e3c8}.alert-success .alert-link{color:#204d22}.alert-info{color:#2a5f6f;background-color:#daecf1;border-color:#c8e2ea}.alert-info .alert-link{color:#224c59}.alert-warning{color:#64430f;background-color:#feeed3;border-color:#fde5be}.alert-warning .alert-link{color:#50360c}.alert-danger{color:#993113;background-color:#ffdcd2;border-color:#ffcbbc}.alert-danger .alert-link{color:#7a270f}.alert-light{color:#3a3a3a;background-color:#dfdfdf;border-color:#d0d0d0}.alert-light .alert-link{color:#2e2e2e}.alert-dark{color:#3a3a3a;background-color:#dfdfdf;border-color:#d0d0d0}.alert-dark .alert-link{color:#2e2e2e}.alert{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border-color;position:relative;z-index:10000;display:flex;align-items:center;border:0.0625rem solid var(--t42-color-opacity-10);overflow:hidden;color:var(--t42-content-color);background-color:Rgba(var(--t42-bg-light), 0.75);background-repeat:no-repeat;background-size:100%;backdrop-filter:var(--backdrop-filter)}.alert h5{margin-bottom:0;color:var(--t42-content-color)}.alert p{margin-bottom:0}.alert-link{color:var(--t42-link-color);font-weight:normal}.alert-dismissible .close{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border-color;position:absolute;top:50%;right:0.75rem;width:1.5rem;height:1.5rem;padding:0;border:0;border-radius:50%;color:var(--t42-content-color);font-weight:700;font-size:1rem;line-height:1;background-color:var(--t42-color-opacity-05);transform:translateY(-50%);opacity:0.5}.alert-dismissible .close::before{position:relative;top:-1px}.alert-dismissible .close:hover{opacity:1}.alert::before{z-index:1;width:1.25rem;height:1.25rem;margin-right:0.875rem;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-position:center;mask-position:center;background-color:var(--t42-icon-color);content:""}.alert::after{position:absolute;top:0;left:0;z-index:-1;width:1px;height:1px;border-radius:50%;opacity:1;animation:color-pulse 3s infinite;content:""}.alert-primary:hover,.alert-secondary:hover,.alert-info:hover,.alert-light:hover,.alert-dark:hover{border-color:#616161}.alert-primary::after,.alert-secondary::after,.alert-info::after,.alert-light::after,.alert-dark::after{background:#616161;background:radial-gradient(circle, rgba(255,255,255,0.35) 0%, rgba(97,97,97,0.75) 60%, #616161 75%, #616161 100%)}.alert-primary::before,.alert-secondary::before,.alert-info::before,.alert-light::before,.alert-dark::before{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M260.6 484.4q0-4.1-4.6-4.1q-16.9 0-29.2-12.3t-11.8-29.2q0-4.6-4.6-4.6t-4.6 4.6q0 21 14.8 35.8t35.3 14.3q4.6 0 4.6-4.6zM493.6 402.4q0 14.8-10.8 25.6t-25.6 10.8h-128q0 30.2-21.5 51.7t-51.7 21.5t-51.7-21.5t-21.5-51.7h-128q-14.8 0-25.6-10.8t-10.8-25.6q14.3-12.3 26.1-25.1t24.1-34.3t21.5-45.6t13.8-58.9t5.6-74.2q0-43 33.8-80.4t87.6-45.6q-2.6-5.1-2.6-10.8q0-11.8 8.2-19.5t19.5-8.2t19.5 8.2t8.2 19.5q0 5.6-2.6 10.8q54.3 8.2 87.6 45.6t33.8 80.4q0 39.9 5.6 74.2t14.3 58.9t21 45.6t24.6 34.3t25.6 25.1z%27%3E%3C/path%3E%3C/svg%3E")}.alert-success:hover{border-color:#43a047}.alert-success::after{background:#43a047;background:radial-gradient(circle, rgba(255,255,255,0.35) 0%, rgba(67,160,71,0.75) 60%, #43a047 75%, #43a047 100%)}.alert-success::before{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M477.4 152.8q0 11.3-8.2 19.5l-245.8 245.8q-8.2 7.7-19.5 7.7t-19.5-7.7l-142.3-142.3q-7.7-8.2-7.7-19.5t7.7-19.5l38.9-38.9q8.2-8.2 19.5-8.2t19.5 8.2l84 84.5l187.4-187.9q8.2-8.2 19.5-8.2t19.5 8.2l38.9 38.9q8.2 7.7 8.2 19.5z%27%3E%3C/path%3E%3C/svg%3E")}.alert-warning:hover{border-color:#f9a825}.alert-warning::after{background:#f9a825;background:radial-gradient(circle, rgba(255,255,255,0.35) 0%, rgba(249,168,37,0.75) 60%, #f9a825 75%, #f9a825 100%)}.alert-warning::before{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M292.4 410.9v-54.3q0-4.1-2.6-6.7t-6.1-2.6h-55.3q-3.6 0-6.1 2.6t-2.6 6.7v54.3q0 4.1 2.6 6.7t6.1 3.1h55.3q3.6 0 6.1-3.1t2.6-6.7zM291.8 304.4l5.1-131.6q0-3.1-2.6-5.1q-3.6-3.1-7.2-3.1h-62.5q-3.1 0-7.2 3.1q-2.6 2-2.6 6.1l4.6 130.6q0 2.6 3.1 4.6t6.7 1.5h52.7q4.1 0 7.2-1.5t2.6-4.6zM288.3 37.1l219.1 402.4q10.2 17.9-.5 35.8q-4.6 8.7-13.3 13.3t-17.9 5.1h-439.3q-9.2 0-17.9-5.1t-13.3-13.3q-10.8-17.9-.5-35.8l219.6-402.4q4.6-8.7 13.3-13.8t18.4-5.1t18.4 5.1t13.8 13.8z%27%3E%3C/path%3E%3C/svg%3E%0A")}.alert-danger:hover{border-color:#ff511f}.alert-danger::after{background:#ff511f;background:radial-gradient(circle, rgba(255,255,255,0.35) 0%, rgba(255,81,31,0.75) 60%, #ff511f 75%, #ff511f 100%)}.alert-danger::before{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 402 512%27%3E%3Cpath d=%27M370.728 359.68q0 11.264-7.68 19.456l-38.912 38.912q-8.192 7.68-19.456 7.68t-19.456-7.68l-83.968-84.48-83.968 84.48q-8.192 7.68-19.456 7.68t-19.456-7.68l-38.912-38.912q-8.192-8.192-8.192-19.456t8.192-19.456l83.968-83.968-83.968-83.968q-8.192-8.192-8.192-19.456t8.192-19.456l38.912-38.912q8.192-8.192 19.456-8.192t19.456 8.192l83.968 83.968 83.968-83.968q8.192-8.192 19.456-8.192t19.456 8.192l38.912 38.912q7.68 7.68 7.68 19.456t-7.68 19.456l-83.968 83.968 83.968 83.968q7.68 7.68 7.68 19.456z%27%3E%3C/path%3E%3C/svg%3E")}@keyframes color-pulse{0%{transform:scale(1);opacity:1}50%{transform:scale(250);opacity:0}100%{opacity:0}}.badge{display:inline-block;padding:.2rem .5rem;font-size:.75em;font-weight:300;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:1rem}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.badge{border:var(--t42-border);color:var(--t42-link-color);backdrop-filter:var(--backdrop-filter)}.badge.bg-primary{border:0.0625rem solid #007be5;background-color:rgba(0,123,229,0.15) !important}.badge.bg-secondary{border:0.0625rem solid #616161;background-color:rgba(97,97,97,0.15) !important}.badge.bg-success{border:0.0625rem solid #43a047;background-color:rgba(67,160,71,0.15) !important}.badge.bg-info{border:0.0625rem solid #469eb9;background-color:rgba(70,158,185,0.15) !important}.badge.bg-warning{border:0.0625rem solid #f9a825;background-color:rgba(249,168,37,0.15) !important}.badge.bg-danger{border:0.0625rem solid #ff511f;background-color:rgba(255,81,31,0.15) !important}.badge.bg-light{border:0.0625rem solid #616161;background-color:rgba(97,97,97,0.15) !important}.badge.bg-dark{border:0.0625rem solid #616161;background-color:rgba(97,97,97,0.15) !important}button .badge{border:0.0625rem solid var(--t42-color-opacity-30)}button:hover .badge{color:var(--white)}.btn-close{box-sizing:content-box;width:1em;height:1em;padding:0 0;color:var(--t42-content-color);background:transparent url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 16 16%27 fill=%27var%28--t42-content-color%29%27%3e%3cpath d=%27M.293.293a1 1 0 011.414 0L8 6.586 14.293.293a1 1 0 111.414 1.414L9.414 8l6.293 6.293a1 1 0 01-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 01-1.414-1.414L6.586 8 .293 1.707a1 1 0 010-1.414z%27/%3e%3c/svg%3e") center/1em auto no-repeat;border:0;border-radius:.25rem;opacity:.5}.btn-close:hover{color:var(--t42-content-color);text-decoration:none;opacity:.75}.btn-close:focus{outline:0;box-shadow:0 0 0 0 rgba(0,123,229,0.25);opacity:1}.btn-close:disabled,.btn-close.disabled{pointer-events:none;user-select:none;opacity:.25}.btn-close-white{filter:invert(1) grayscale(100%) brightness(200%)}.btn{display:inline-block;font-weight:400;line-height:1.875rem;color:#212529;text-align:center;text-decoration:none;vertical-align:middle;cursor:pointer;user-select:none;background-color:transparent;border:1px solid transparent;padding:0 .875rem;font-size:.75rem;border-radius:0;transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.btn{transition:none}}.btn:hover{color:#212529}.btn-check:focus+.btn,.btn:focus{outline:0;box-shadow:0 0 0 0 rgba(0,123,229,0.25)}.btn:disabled,.btn.disabled,fieldset:disabled .btn{pointer-events:none;opacity:.35}.btn-primary{color:#000;background-color:#007be5;border-color:#007be5}.btn-primary:hover{color:#000;background-color:#268fe9;border-color:#1a88e8}.btn-check:focus+.btn-primary,.btn-primary:focus{color:#000;background-color:#268fe9;border-color:#1a88e8;box-shadow:0 0 0 0 rgba(0,105,195,0.5)}.btn-check:checked+.btn-primary,.btn-check:active+.btn-primary,.btn-primary:active,.btn-primary.active,.show>.btn-primary.dropdown-toggle{color:#000;background-color:#3395ea;border-color:#1a88e8}.btn-check:checked+.btn-primary:focus,.btn-check:active+.btn-primary:focus,.btn-primary:active:focus,.btn-primary.active:focus,.show>.btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(0,105,195,0.5)}.btn-primary:disabled,.btn-primary.disabled{color:#000;background-color:#007be5;border-color:#007be5}.btn-secondary{color:#fff;background-color:#616161;border-color:#616161}.btn-secondary:hover{color:#fff;background-color:#525252;border-color:#4e4e4e}.btn-check:focus+.btn-secondary,.btn-secondary:focus{color:#fff;background-color:#525252;border-color:#4e4e4e;box-shadow:0 0 0 0 rgba(121,121,121,0.5)}.btn-check:checked+.btn-secondary,.btn-check:active+.btn-secondary,.btn-secondary:active,.btn-secondary.active,.show>.btn-secondary.dropdown-toggle{color:#fff;background-color:#4e4e4e;border-color:#494949}.btn-check:checked+.btn-secondary:focus,.btn-check:active+.btn-secondary:focus,.btn-secondary:active:focus,.btn-secondary.active:focus,.show>.btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(121,121,121,0.5)}.btn-secondary:disabled,.btn-secondary.disabled{color:#fff;background-color:#616161;border-color:#616161}.btn-success{color:#000;background-color:#43a047;border-color:#43a047}.btn-success:hover{color:#000;background-color:#5fae63;border-color:#56aa59}.btn-check:focus+.btn-success,.btn-success:focus{color:#000;background-color:#5fae63;border-color:#56aa59;box-shadow:0 0 0 0 rgba(57,136,60,0.5)}.btn-check:checked+.btn-success,.btn-check:active+.btn-success,.btn-success:active,.btn-success.active,.show>.btn-success.dropdown-toggle{color:#000;background-color:#69b36c;border-color:#56aa59}.btn-check:checked+.btn-success:focus,.btn-check:active+.btn-success:focus,.btn-success:active:focus,.btn-success.active:focus,.show>.btn-success.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(57,136,60,0.5)}.btn-success:disabled,.btn-success.disabled{color:#000;background-color:#43a047;border-color:#43a047}.btn-info{color:#000;background-color:#469eb9;border-color:#469eb9}.btn-info:hover{color:#000;background-color:#62adc4;border-color:#59a8c0}.btn-check:focus+.btn-info,.btn-info:focus{color:#000;background-color:#62adc4;border-color:#59a8c0;box-shadow:0 0 0 0 rgba(60,134,157,0.5)}.btn-check:checked+.btn-info,.btn-check:active+.btn-info,.btn-info:active,.btn-info.active,.show>.btn-info.dropdown-toggle{color:#000;background-color:#6bb1c7;border-color:#59a8c0}.btn-check:checked+.btn-info:focus,.btn-check:active+.btn-info:focus,.btn-info:active:focus,.btn-info.active:focus,.show>.btn-info.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(60,134,157,0.5)}.btn-info:disabled,.btn-info.disabled{color:#000;background-color:#469eb9;border-color:#469eb9}.btn-warning{color:#000;background-color:#f9a825;border-color:#f9a825}.btn-warning:hover{color:#000;background-color:#fab546;border-color:#fab13b}.btn-check:focus+.btn-warning,.btn-warning:focus{color:#000;background-color:#fab546;border-color:#fab13b;box-shadow:0 0 0 0 rgba(212,143,31,0.5)}.btn-check:checked+.btn-warning,.btn-check:active+.btn-warning,.btn-warning:active,.btn-warning.active,.show>.btn-warning.dropdown-toggle{color:#000;background-color:#fab951;border-color:#fab13b}.btn-check:checked+.btn-warning:focus,.btn-check:active+.btn-warning:focus,.btn-warning:active:focus,.btn-warning.active:focus,.show>.btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(212,143,31,0.5)}.btn-warning:disabled,.btn-warning.disabled{color:#000;background-color:#f9a825;border-color:#f9a825}.btn-danger{color:#000;background-color:#ff511f;border-color:#ff511f}.btn-danger:hover{color:#000;background-color:#ff6b41;border-color:#ff6235}.btn-check:focus+.btn-danger,.btn-danger:focus{color:#000;background-color:#ff6b41;border-color:#ff6235;box-shadow:0 0 0 0 rgba(217,69,26,0.5)}.btn-check:checked+.btn-danger,.btn-check:active+.btn-danger,.btn-danger:active,.btn-danger.active,.show>.btn-danger.dropdown-toggle{color:#000;background-color:#ff744c;border-color:#ff6235}.btn-check:checked+.btn-danger:focus,.btn-check:active+.btn-danger:focus,.btn-danger:active:focus,.btn-danger.active:focus,.show>.btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(217,69,26,0.5)}.btn-danger:disabled,.btn-danger.disabled{color:#000;background-color:#ff511f;border-color:#ff511f}.btn-light{color:#fff;background-color:#616161;border-color:#616161}.btn-light:hover{color:#fff;background-color:#525252;border-color:#4e4e4e}.btn-check:focus+.btn-light,.btn-light:focus{color:#fff;background-color:#525252;border-color:#4e4e4e;box-shadow:0 0 0 0 rgba(121,121,121,0.5)}.btn-check:checked+.btn-light,.btn-check:active+.btn-light,.btn-light:active,.btn-light.active,.show>.btn-light.dropdown-toggle{color:#fff;background-color:#4e4e4e;border-color:#494949}.btn-check:checked+.btn-light:focus,.btn-check:active+.btn-light:focus,.btn-light:active:focus,.btn-light.active:focus,.show>.btn-light.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(121,121,121,0.5)}.btn-light:disabled,.btn-light.disabled{color:#fff;background-color:#616161;border-color:#616161}.btn-dark{color:#fff;background-color:#616161;border-color:#616161}.btn-dark:hover{color:#fff;background-color:#525252;border-color:#4e4e4e}.btn-check:focus+.btn-dark,.btn-dark:focus{color:#fff;background-color:#525252;border-color:#4e4e4e;box-shadow:0 0 0 0 rgba(121,121,121,0.5)}.btn-check:checked+.btn-dark,.btn-check:active+.btn-dark,.btn-dark:active,.btn-dark.active,.show>.btn-dark.dropdown-toggle{color:#fff;background-color:#4e4e4e;border-color:#494949}.btn-check:checked+.btn-dark:focus,.btn-check:active+.btn-dark:focus,.btn-dark:active:focus,.btn-dark.active:focus,.show>.btn-dark.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(121,121,121,0.5)}.btn-dark:disabled,.btn-dark.disabled{color:#fff;background-color:#616161;border-color:#616161}.btn-outline-primary{color:#007be5;border-color:#007be5}.btn-outline-primary:hover{color:#000;background-color:#007be5;border-color:#007be5}.btn-check:focus+.btn-outline-primary,.btn-outline-primary:focus{box-shadow:0 0 0 0 rgba(0,123,229,0.5)}.btn-check:checked+.btn-outline-primary,.btn-check:active+.btn-outline-primary,.btn-outline-primary:active,.btn-outline-primary.active,.btn-outline-primary.dropdown-toggle.show{color:#000;background-color:#007be5;border-color:#007be5}.btn-check:checked+.btn-outline-primary:focus,.btn-check:active+.btn-outline-primary:focus,.btn-outline-primary:active:focus,.btn-outline-primary.active:focus,.btn-outline-primary.dropdown-toggle.show:focus{box-shadow:0 0 0 0 rgba(0,123,229,0.5)}.btn-outline-primary:disabled,.btn-outline-primary.disabled{color:#007be5;background-color:transparent}.btn-outline-secondary{color:#616161;border-color:#616161}.btn-outline-secondary:hover{color:#fff;background-color:#616161;border-color:#616161}.btn-check:focus+.btn-outline-secondary,.btn-outline-secondary:focus{box-shadow:0 0 0 0 rgba(97,97,97,0.5)}.btn-check:checked+.btn-outline-secondary,.btn-check:active+.btn-outline-secondary,.btn-outline-secondary:active,.btn-outline-secondary.active,.btn-outline-secondary.dropdown-toggle.show{color:#fff;background-color:#616161;border-color:#616161}.btn-check:checked+.btn-outline-secondary:focus,.btn-check:active+.btn-outline-secondary:focus,.btn-outline-secondary:active:focus,.btn-outline-secondary.active:focus,.btn-outline-secondary.dropdown-toggle.show:focus{box-shadow:0 0 0 0 rgba(97,97,97,0.5)}.btn-outline-secondary:disabled,.btn-outline-secondary.disabled{color:#616161;background-color:transparent}.btn-outline-success{color:#43a047;border-color:#43a047}.btn-outline-success:hover{color:#000;background-color:#43a047;border-color:#43a047}.btn-check:focus+.btn-outline-success,.btn-outline-success:focus{box-shadow:0 0 0 0 rgba(67,160,71,0.5)}.btn-check:checked+.btn-outline-success,.btn-check:active+.btn-outline-success,.btn-outline-success:active,.btn-outline-success.active,.btn-outline-success.dropdown-toggle.show{color:#000;background-color:#43a047;border-color:#43a047}.btn-check:checked+.btn-outline-success:focus,.btn-check:active+.btn-outline-success:focus,.btn-outline-success:active:focus,.btn-outline-success.active:focus,.btn-outline-success.dropdown-toggle.show:focus{box-shadow:0 0 0 0 rgba(67,160,71,0.5)}.btn-outline-success:disabled,.btn-outline-success.disabled{color:#43a047;background-color:transparent}.btn-outline-info{color:#469eb9;border-color:#469eb9}.btn-outline-info:hover{color:#000;background-color:#469eb9;border-color:#469eb9}.btn-check:focus+.btn-outline-info,.btn-outline-info:focus{box-shadow:0 0 0 0 rgba(70,158,185,0.5)}.btn-check:checked+.btn-outline-info,.btn-check:active+.btn-outline-info,.btn-outline-info:active,.btn-outline-info.active,.btn-outline-info.dropdown-toggle.show{color:#000;background-color:#469eb9;border-color:#469eb9}.btn-check:checked+.btn-outline-info:focus,.btn-check:active+.btn-outline-info:focus,.btn-outline-info:active:focus,.btn-outline-info.active:focus,.btn-outline-info.dropdown-toggle.show:focus{box-shadow:0 0 0 0 rgba(70,158,185,0.5)}.btn-outline-info:disabled,.btn-outline-info.disabled{color:#469eb9;background-color:transparent}.btn-outline-warning{color:#f9a825;border-color:#f9a825}.btn-outline-warning:hover{color:#000;background-color:#f9a825;border-color:#f9a825}.btn-check:focus+.btn-outline-warning,.btn-outline-warning:focus{box-shadow:0 0 0 0 rgba(249,168,37,0.5)}.btn-check:checked+.btn-outline-warning,.btn-check:active+.btn-outline-warning,.btn-outline-warning:active,.btn-outline-warning.active,.btn-outline-warning.dropdown-toggle.show{color:#000;background-color:#f9a825;border-color:#f9a825}.btn-check:checked+.btn-outline-warning:focus,.btn-check:active+.btn-outline-warning:focus,.btn-outline-warning:active:focus,.btn-outline-warning.active:focus,.btn-outline-warning.dropdown-toggle.show:focus{box-shadow:0 0 0 0 rgba(249,168,37,0.5)}.btn-outline-warning:disabled,.btn-outline-warning.disabled{color:#f9a825;background-color:transparent}.btn-outline-danger{color:#ff511f;border-color:#ff511f}.btn-outline-danger:hover{color:#000;background-color:#ff511f;border-color:#ff511f}.btn-check:focus+.btn-outline-danger,.btn-outline-danger:focus{box-shadow:0 0 0 0 rgba(255,81,31,0.5)}.btn-check:checked+.btn-outline-danger,.btn-check:active+.btn-outline-danger,.btn-outline-danger:active,.btn-outline-danger.active,.btn-outline-danger.dropdown-toggle.show{color:#000;background-color:#ff511f;border-color:#ff511f}.btn-check:checked+.btn-outline-danger:focus,.btn-check:active+.btn-outline-danger:focus,.btn-outline-danger:active:focus,.btn-outline-danger.active:focus,.btn-outline-danger.dropdown-toggle.show:focus{box-shadow:0 0 0 0 rgba(255,81,31,0.5)}.btn-outline-danger:disabled,.btn-outline-danger.disabled{color:#ff511f;background-color:transparent}.btn-outline-light{color:#616161;border-color:#616161}.btn-outline-light:hover{color:#fff;background-color:#616161;border-color:#616161}.btn-check:focus+.btn-outline-light,.btn-outline-light:focus{box-shadow:0 0 0 0 rgba(97,97,97,0.5)}.btn-check:checked+.btn-outline-light,.btn-check:active+.btn-outline-light,.btn-outline-light:active,.btn-outline-light.active,.btn-outline-light.dropdown-toggle.show{color:#fff;background-color:#616161;border-color:#616161}.btn-check:checked+.btn-outline-light:focus,.btn-check:active+.btn-outline-light:focus,.btn-outline-light:active:focus,.btn-outline-light.active:focus,.btn-outline-light.dropdown-toggle.show:focus{box-shadow:0 0 0 0 rgba(97,97,97,0.5)}.btn-outline-light:disabled,.btn-outline-light.disabled{color:#616161;background-color:transparent}.btn-outline-dark{color:#616161;border-color:#616161}.btn-outline-dark:hover{color:#fff;background-color:#616161;border-color:#616161}.btn-check:focus+.btn-outline-dark,.btn-outline-dark:focus{box-shadow:0 0 0 0 rgba(97,97,97,0.5)}.btn-check:checked+.btn-outline-dark,.btn-check:active+.btn-outline-dark,.btn-outline-dark:active,.btn-outline-dark.active,.btn-outline-dark.dropdown-toggle.show{color:#fff;background-color:#616161;border-color:#616161}.btn-check:checked+.btn-outline-dark:focus,.btn-check:active+.btn-outline-dark:focus,.btn-outline-dark:active:focus,.btn-outline-dark.active:focus,.btn-outline-dark.dropdown-toggle.show:focus{box-shadow:0 0 0 0 rgba(97,97,97,0.5)}.btn-outline-dark:disabled,.btn-outline-dark.disabled{color:#616161;background-color:transparent}.btn-link{font-weight:400;color:var(--t42-link-color);text-decoration:underline}.btn-link:hover{color:var(--t42-link-hover-color)}.btn-link:disabled,.btn-link.disabled{color:#6c757d}.btn-lg,.btn-group-lg>.btn{padding:0 .875rem;font-size:.75rem;border-radius:0}.btn-sm,.btn-group-sm>.btn{padding:0 .875rem;font-size:.75rem;border-radius:0}.btn-group,.btn-group-vertical{position:relative;display:inline-flex;vertical-align:middle}.btn-group>.btn,.btn-group-vertical>.btn{position:relative;flex:1 1 auto}.btn-group>.btn-check:checked+.btn,.btn-group>.btn-check:focus+.btn,.btn-group>.btn:hover,.btn-group>.btn:focus,.btn-group>.btn:active,.btn-group>.btn.active,.btn-group-vertical>.btn-check:checked+.btn,.btn-group-vertical>.btn-check:focus+.btn,.btn-group-vertical>.btn:hover,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn.active{z-index:1}.btn-toolbar{display:flex;flex-wrap:wrap;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group>.btn:not(:first-child),.btn-group>.btn-group:not(:first-child){margin-left:-1px}.btn-group>.btn:not(:last-child):not(.dropdown-toggle),.btn-group>.btn-group:not(:last-child)>.btn{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:nth-child(n+3),.btn-group>:not(.btn-check)+.btn,.btn-group>.btn-group:not(:first-child)>.btn{border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.65625rem;padding-left:.65625rem}.dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after,.dropend .dropdown-toggle-split::after{margin-left:0}.dropstart .dropdown-toggle-split::before{margin-right:0}.btn-sm+.dropdown-toggle-split,.btn-group-sm>.btn+.dropdown-toggle-split{padding-right:.65625rem;padding-left:.65625rem}.btn-lg+.dropdown-toggle-split,.btn-group-lg>.btn+.dropdown-toggle-split{padding-right:.65625rem;padding-left:.65625rem}.btn-group-vertical{flex-direction:column;align-items:flex-start;justify-content:center}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn:not(:first-child),.btn-group-vertical>.btn-group:not(:first-child){margin-top:-1px}.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle),.btn-group-vertical>.btn-group:not(:last-child)>.btn{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn ~ .btn,.btn-group-vertical>.btn-group:not(:first-child)>.btn{border-top-left-radius:0;border-top-right-radius:0}button,button:focus{outline:none}.btn{color:var(--t42-link-color);transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, border-color;cursor:default}.btn.disabled,.btn:disabled{color:var(--t42-link-color);cursor:default}.btn:not(.disabled):not(:disabled).active,.btn:not(.disabled):not(:disabled):hover{border-color:var(--t42-color-opacity-30);color:var(--white);backdrop-filter:var(--backdrop-filter)}.btn:focus,.btn:active{color:var(--white)}.btn-primary{background-color:rgba(0,123,229,0.05)}.btn-primary.disabled,.btn-primary:disabled{background-color:rgba(0,123,229,0.05)}.btn-primary:not(.disabled):not(:disabled).active,.btn-primary:not(.disabled):not(:disabled):hover{background-color:#007be5}.btn-primary:not(.disabled):not(:disabled).btn-icon.active,.btn-primary:not(.disabled):not(:disabled).btn-icon:focus,.btn-primary:not(.disabled):not(:disabled).btn-icon:hover{color:var(--white)}.btn-primary.dropdown-toggle.active,.btn-primary.dropdown-toggle:active,.btn-primary.dropdown-toggle:focus{border-color:var(--t42-color-opacity-30);background-color:#007be5}.btn-secondary{background-color:rgba(97,97,97,0.05)}.btn-secondary.disabled,.btn-secondary:disabled{background-color:rgba(97,97,97,0.05)}.btn-secondary:not(.disabled):not(:disabled).active,.btn-secondary:not(.disabled):not(:disabled):hover{background-color:#616161}.btn-secondary:not(.disabled):not(:disabled).btn-icon.active,.btn-secondary:not(.disabled):not(:disabled).btn-icon:focus,.btn-secondary:not(.disabled):not(:disabled).btn-icon:hover{color:var(--white)}.btn-secondary.dropdown-toggle.active,.btn-secondary.dropdown-toggle:active,.btn-secondary.dropdown-toggle:focus{border-color:var(--t42-color-opacity-30);background-color:#616161}.btn-success{background-color:rgba(67,160,71,0.05)}.btn-success.disabled,.btn-success:disabled{background-color:rgba(67,160,71,0.05)}.btn-success:not(.disabled):not(:disabled).active,.btn-success:not(.disabled):not(:disabled):hover{background-color:#43a047}.btn-success:not(.disabled):not(:disabled).btn-icon.active,.btn-success:not(.disabled):not(:disabled).btn-icon:focus,.btn-success:not(.disabled):not(:disabled).btn-icon:hover{color:var(--white)}.btn-success.dropdown-toggle.active,.btn-success.dropdown-toggle:active,.btn-success.dropdown-toggle:focus{border-color:var(--t42-color-opacity-30);background-color:#43a047}.btn-info{background-color:rgba(70,158,185,0.05)}.btn-info.disabled,.btn-info:disabled{background-color:rgba(70,158,185,0.05)}.btn-info:not(.disabled):not(:disabled).active,.btn-info:not(.disabled):not(:disabled):hover{background-color:#469eb9}.btn-info:not(.disabled):not(:disabled).btn-icon.active,.btn-info:not(.disabled):not(:disabled).btn-icon:focus,.btn-info:not(.disabled):not(:disabled).btn-icon:hover{color:var(--white)}.btn-info.dropdown-toggle.active,.btn-info.dropdown-toggle:active,.btn-info.dropdown-toggle:focus{border-color:var(--t42-color-opacity-30);background-color:#469eb9}.btn-warning{background-color:rgba(249,168,37,0.05)}.btn-warning.disabled,.btn-warning:disabled{background-color:rgba(249,168,37,0.05)}.btn-warning:not(.disabled):not(:disabled).active,.btn-warning:not(.disabled):not(:disabled):hover{background-color:#f9a825}.btn-warning:not(.disabled):not(:disabled).btn-icon.active,.btn-warning:not(.disabled):not(:disabled).btn-icon:focus,.btn-warning:not(.disabled):not(:disabled).btn-icon:hover{color:var(--white)}.btn-warning.dropdown-toggle.active,.btn-warning.dropdown-toggle:active,.btn-warning.dropdown-toggle:focus{border-color:var(--t42-color-opacity-30);background-color:#f9a825}.btn-danger{background-color:rgba(255,81,31,0.05)}.btn-danger.disabled,.btn-danger:disabled{background-color:rgba(255,81,31,0.05)}.btn-danger:not(.disabled):not(:disabled).active,.btn-danger:not(.disabled):not(:disabled):hover{background-color:#ff511f}.btn-danger:not(.disabled):not(:disabled).btn-icon.active,.btn-danger:not(.disabled):not(:disabled).btn-icon:focus,.btn-danger:not(.disabled):not(:disabled).btn-icon:hover{color:var(--white)}.btn-danger.dropdown-toggle.active,.btn-danger.dropdown-toggle:active,.btn-danger.dropdown-toggle:focus{border-color:var(--t42-color-opacity-30);background-color:#ff511f}.btn-light{background-color:rgba(97,97,97,0.05)}.btn-light.disabled,.btn-light:disabled{background-color:rgba(97,97,97,0.05)}.btn-light:not(.disabled):not(:disabled).active,.btn-light:not(.disabled):not(:disabled):hover{background-color:#616161}.btn-light:not(.disabled):not(:disabled).btn-icon.active,.btn-light:not(.disabled):not(:disabled).btn-icon:focus,.btn-light:not(.disabled):not(:disabled).btn-icon:hover{color:var(--white)}.btn-light.dropdown-toggle.active,.btn-light.dropdown-toggle:active,.btn-light.dropdown-toggle:focus{border-color:var(--t42-color-opacity-30);background-color:#616161}.btn-dark{background-color:rgba(97,97,97,0.05)}.btn-dark.disabled,.btn-dark:disabled{background-color:rgba(97,97,97,0.05)}.btn-dark:not(.disabled):not(:disabled).active,.btn-dark:not(.disabled):not(:disabled):hover{background-color:#616161}.btn-dark:not(.disabled):not(:disabled).btn-icon.active,.btn-dark:not(.disabled):not(:disabled).btn-icon:focus,.btn-dark:not(.disabled):not(:disabled).btn-icon:hover{color:var(--white)}.btn-dark.dropdown-toggle.active,.btn-dark.dropdown-toggle:active,.btn-dark.dropdown-toggle:focus{border-color:var(--t42-color-opacity-30);background-color:#616161}.btn-link{text-decoration:none;backdrop-filter:none}.btn-link:not(.disabled):not(:disabled).active,.btn-link:not(.disabled):not(:disabled):focus,.btn-link:not(.disabled):not(:disabled):hover{border-color:transparent;color:var(--t42-link-color);text-decoration:underline}.btn-icon:not(.disabled):not(:disabled).active,.btn-icon:not(.disabled):not(:disabled):focus,.btn-icon:not(.disabled):not(:disabled):hover{color:var(--t42-link-color)}.btn-icon-action{display:flex;justify-content:center;width:1rem;height:1rem;padding:0;border-radius:50%;font-size:0.75rem;transition:all .2s ease-in-out}@media (prefers-reduced-motion: reduce){.btn-icon-action{transition:none}}.btn-icon-action:not(.disabled):not(:disabled).active,.btn-icon-action:not(.disabled):not(:disabled):hover,.btn-icon-action:not(.disabled):not(:disabled):focus{border-color:transparent;background-color:Rgb(var(--t42-bg-light));box-shadow:var(--t42-shadow)}.btn-icon-action-right{position:absolute;right:0.25rem}.btn-icon-action-show-hover{transition:all .2s ease-in-out}@media (prefers-reduced-motion: reduce){.btn-icon-action-show-hover{transition:none}}.btn-icon-action-show-hover .btn-icon-action{opacity:0}.btn-icon-action-show-hover:not(.disabled):not(:disabled):hover .btn-icon-action{opacity:1}.btn-close{width:1rem;height:1rem;filter:var(--filter-close)}.breadcrumb{display:flex;flex-wrap:wrap;padding:0 0;margin-bottom:.5rem;list-style:none;background-color:rgba(0,0,0,0)}.breadcrumb-item+.breadcrumb-item{padding-left:.5rem}.breadcrumb-item+.breadcrumb-item::before{float:left;padding-right:.5rem;color:#6c757d;content:var(--bs-breadcrumb-divider, "/") /* rtl: var(--bs-breadcrumb-divider, "/") */}.breadcrumb-item.active{color:var(--t42-link-color)}.breadcrumb-item{font-size:83.3%}.breadcrumb-item.active{text-decoration:underline}.breadcrumb-item+.breadcrumb-item{padding-left:0}.breadcrumb-item+.breadcrumb-item::before{position:relative;top:0.063rem;left:0.063rem;width:0.75rem;height:0.75rem;background-color:var(--t42-content-color);content:"";-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M339.2,256.3c0,2.4-0.9,4.4-2.6,6.1L203,396c-1.7,1.7-3.8,2.6-6.1,2.6c-2.4,0-4.6-0.9-6.7-2.6l-14.3-14.3 c-2-2-3.1-4.3-3.1-6.7s1-4.6,3.1-6.7L288,256.3L175.9,143.6c-2-1.7-3.1-3.8-3.1-6.1s1-4.6,3.1-6.7l14.3-14.3c1.7-2,3.9-3.1,6.7-3.1 s4.8,1,6.1,3.1l133.6,133.1C338.3,251.3,339.2,253.5,339.2,256.3L339.2,256.3z%27/%3E%3C/svg%3E")}mark,.mark{color:var(--white)}pre{background-color:var(--t42-bg-dark)}blockquote,.blockquote{padding:1rem 1rem 0.01rem;border-left:0.25rem solid var(--secondary);background-color:Rgb(var(--t42-bg-dark))}.blockquote-footer{margin-top:-2rem;margin-left:1.25rem;color:var(--t42-content-color-muted);font-size:0.875em}pre{border:0.0625rem solid var(--t42-color-opacity-10)}.card{position:relative;display:flex;flex-direction:column;min-width:0;word-wrap:break-word;background-color:Rgba(var(--t42-bg-light), 0.75);background-clip:border-box;border:1px solid var(--t42-color-opacity-10);border-radius:0}.card>hr{margin-right:0;margin-left:0}.card>.list-group{border-top:inherit;border-bottom:inherit}.card>.list-group:first-child{border-top-width:0;border-top-left-radius:0;border-top-right-radius:0}.card>.list-group:last-child{border-bottom-width:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.card>.card-header+.list-group,.card>.list-group+.card-footer{border-top:0}.card-body{flex:1 1 auto;padding:1.25rem 1.25rem}.card-title{margin-bottom:.5rem}.card-subtitle{margin-top:-.25rem;margin-bottom:0}.card-text:last-child{margin-bottom:0}.card-link+.card-link{margin-left:1.25rem}.card-header{padding:.625rem 1.25rem;margin-bottom:0;color:var(--t42-link-color);background-color:rgba(0,0,0,0);border-bottom:1px solid var(--t42-color-opacity-10)}.card-header:first-child{border-radius:0 0 0 0}.card-footer{padding:.625rem 1.25rem;color:var(--t42-link-color);background-color:rgba(0,0,0,0);border-top:1px solid var(--t42-color-opacity-10)}.card-footer:last-child{border-radius:0 0 0 0}.card-header-tabs{margin-right:-.625rem;margin-bottom:-.625rem;margin-left:-.625rem;border-bottom:0}.card-header-tabs .nav-link.active{background-color:Rgba(var(--t42-bg-light), 0.75);border-bottom-color:Rgba(var(--t42-bg-light), 0.75)}.card-header-pills{margin-right:-.625rem;margin-left:-.625rem}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1rem;border-radius:0}.card-img,.card-img-top,.card-img-bottom{width:100%}.card-img,.card-img-top{border-top-left-radius:0;border-top-right-radius:0}.card-img,.card-img-bottom{border-bottom-right-radius:0;border-bottom-left-radius:0}.card-group>.card{margin-bottom:.75rem}@media (min-width: 576px){.card-group{display:flex;flex-flow:row wrap}.card-group>.card{flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:not(:last-child) .card-img-top,.card-group>.card:not(:last-child) .card-header{border-top-right-radius:0}.card-group>.card:not(:last-child) .card-img-bottom,.card-group>.card:not(:last-child) .card-footer{border-bottom-right-radius:0}.card-group>.card:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:not(:first-child) .card-img-top,.card-group>.card:not(:first-child) .card-header{border-top-left-radius:0}.card-group>.card:not(:first-child) .card-img-bottom,.card-group>.card:not(:first-child) .card-footer{border-bottom-left-radius:0}}.card{box-shadow:var(--t42-shadow);backdrop-filter:var(--backdrop-filter)}.card .card-header{border-bottom-width:0}.card .card-subtitle{margin-bottom:0.5rem;font-size:83.3%}.card.bg-primary{background-color:transparent !important}.card.bg-primary .card-header{background-color:Rgba(var(--t42-bg-mid), 0.75)}.card.bg-primary .card-body{background-color:Rgba(var(--t42-bg-light), 0.75)}.card.bg-secondary{background-color:transparent !important}.card.bg-secondary .card-header{background-color:Rgba(var(--t42-bg-light), 0.75)}.card.bg-secondary .card-body{background-color:Rgba(var(--t42-bg-mid), 0.75)}.card:not(.bg-primary):not(.bg-secondary) .card-header+.card-body{padding-top:0}.card-header-tabs{margin-bottom:0}.accordion .card:first-of-type,.accordion .card:not(:first-of-type):not(:last-of-type){margin-bottom:0.5rem;border-bottom:var(--t42-border)}.accordion .card-header{position:relative;padding:0}.accordion .card-header .btn-link{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;width:100%;padding:0.75rem 2rem;line-height:1.4;text-align:left}.accordion .card-header .btn-link::before{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:transform;position:absolute;display:inline-block;width:0.75rem;height:0.75rem;background-color:var(--t42-content-color);transform:translateX(-1rem) translateY(0.063rem) rotate(-90deg);content:"";-webkit-mask-image:var(--t42-select-indicator)}.accordion .card-header .btn-link:hover{backdrop-filter:none}.accordion .card-header .btn-link.collapsed::before{transform:translateX(-1rem) translateY(0.063rem)}.accordion .card-header .btn-link.disabled::before,.accordion .card-header .btn-link:disabled::before{opacity:.35}.accordion .card-body{padding:0 1.25rem 1.25rem}.accordion .bg-primary .card-body,.accordion .bg-secondary .card-body{padding:1.25rem}.dropup,.dropend,.dropdown,.dropstart{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:0;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{position:absolute;z-index:1000;display:none;min-width:10rem;padding:0 0;margin:0;font-size:.75rem;color:var(--t42-content-color);text-align:left;list-style:none;background-color:Rgba(var(--t42-bg-light), 0.75);background-clip:padding-box;border:1px solid var(--t42-color-opacity-10);border-radius:0}.dropdown-menu[data-bs-popper]{top:100%;left:0;margin-top:.125rem}.dropdown-menu-start{--bs-position: start}.dropdown-menu-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-end{--bs-position: end}.dropdown-menu-end[data-bs-popper]{right:0;left:auto}@media (min-width: 576px){.dropdown-menu-sm-start{--bs-position: start}.dropdown-menu-sm-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-sm-end{--bs-position: end}.dropdown-menu-sm-end[data-bs-popper]{right:0;left:auto}}@media (min-width: 768px){.dropdown-menu-md-start{--bs-position: start}.dropdown-menu-md-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-md-end{--bs-position: end}.dropdown-menu-md-end[data-bs-popper]{right:0;left:auto}}@media (min-width: 992px){.dropdown-menu-lg-start{--bs-position: start}.dropdown-menu-lg-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-lg-end{--bs-position: end}.dropdown-menu-lg-end[data-bs-popper]{right:0;left:auto}}@media (min-width: 1200px){.dropdown-menu-xl-start{--bs-position: start}.dropdown-menu-xl-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-xl-end{--bs-position: end}.dropdown-menu-xl-end[data-bs-popper]{right:0;left:auto}}@media (min-width: 1400px){.dropdown-menu-xxl-start{--bs-position: start}.dropdown-menu-xxl-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-xxl-end{--bs-position: end}.dropdown-menu-xxl-end[data-bs-popper]{right:0;left:auto}}.dropup .dropdown-menu[data-bs-popper]{top:auto;bottom:100%;margin-top:0;margin-bottom:.125rem}.dropup .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:0;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropend .dropdown-menu[data-bs-popper]{top:0;right:auto;left:100%;margin-top:0;margin-left:.125rem}.dropend .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:0;content:"";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid}.dropend .dropdown-toggle:empty::after{margin-left:0}.dropend .dropdown-toggle::after{vertical-align:0}.dropstart .dropdown-menu[data-bs-popper]{top:0;right:100%;left:auto;margin-top:0;margin-right:.125rem}.dropstart .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:0;content:""}.dropstart .dropdown-toggle::after{display:none}.dropstart .dropdown-toggle::before{display:inline-block;margin-right:.255em;vertical-align:0;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropstart .dropdown-toggle:empty::after{margin-left:0}.dropstart .dropdown-toggle::before{vertical-align:0}.dropdown-divider{height:0;margin:0 0;overflow:hidden;border-top:1px solid var(--t42-color-opacity-10)}.dropdown-item{display:block;width:100%;padding:.375rem 1rem;clear:both;font-weight:400;color:var(--t42-content-color);text-align:inherit;text-decoration:none;white-space:nowrap;background-color:transparent;border:0}.dropdown-item:first-child{border-top-left-radius:0;border-top-right-radius:0}.dropdown-item:last-child{border-bottom-right-radius:0;border-bottom-left-radius:0}.dropdown-item:hover,.dropdown-item:focus{color:var(--t42-link-hover-color);background-color:var(--t42-link-hover-bg)}.dropdown-item.active,.dropdown-item:active{color:var(--t42-link-hover-color);text-decoration:none;background-color:var(--t42-link-active-bg)}.dropdown-item.disabled,.dropdown-item:disabled{color:#adb5bd;pointer-events:none;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:0 1rem;margin-bottom:0;font-size:.65625rem;color:shade-color(#616161, 10%);white-space:nowrap}.dropdown-item-text{display:block;padding:.375rem 1rem;color:var(--t42-content-color)}.dropdown-menu-dark{color:#dee2e6;background-color:#343a40;border-color:var(--t42-color-opacity-10)}.dropdown-menu-dark .dropdown-item{color:#dee2e6}.dropdown-menu-dark .dropdown-item:hover,.dropdown-menu-dark .dropdown-item:focus{color:#fff;background-color:rgba(255,255,255,0.15)}.dropdown-menu-dark .dropdown-item.active,.dropdown-menu-dark .dropdown-item:active{color:var(--t42-link-hover-color);background-color:var(--t42-link-active-bg)}.dropdown-menu-dark .dropdown-item.disabled,.dropdown-menu-dark .dropdown-item:disabled{color:#adb5bd}.dropdown-menu-dark .dropdown-divider{border-color:var(--t42-color-opacity-10)}.dropdown-menu-dark .dropdown-item-text{color:#dee2e6}.dropdown-menu-dark .dropdown-header{color:#adb5bd}.dropdown-menu{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:opacity, visability;display:block;visibility:hidden;opacity:0;backdrop-filter:var(--backdrop-filter)}.dropdown-menu.show{visibility:visible;opacity:1}.dropdown-toggle::after{position:relative;width:0.5rem;height:0.5rem;border:0;background-color:var(--t42-link-color);content:"";-webkit-mask-image:url("data:image/svg+xml,%3Csvg version=%271.1%27 xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M480.768 186.88l-211.968 211.456q-5.12 5.632-12.8 5.632t-12.8-5.632l-211.968-211.456q-5.632-5.632-5.632-13.312t5.632-12.8l47.616-47.104q5.12-5.632 12.8-5.632t12.8 5.632l151.552 151.552 151.552-151.552q5.632-5.632 12.8-5.632t13.312 5.632l47.104 47.104q5.632 5.632 5.632 12.8t-5.632 13.312z%27%3E%3C/path%3E%3C/svg%3E")}.dropdown-toggle.show::after{color:var(--white)}.dropup .dropdown-toggle::after{position:relative;top:0.188rem;width:0.5rem;height:0.5rem;border:0;background-color:var(--t42-link-color);content:"";-webkit-mask-image:url("data:image/svg+xml,%3Csvg version=%271.1%27 xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M480.768 351.488l-47.104 47.104q-5.632 5.12-13.312 5.12t-12.8-5.12l-151.552-152.064-151.552 152.064q-5.632 5.12-12.8 5.12t-12.8-5.12l-47.616-47.104q-5.632-5.632-5.632-13.312t5.632-12.8l211.968-211.968q5.632-5.12 12.8-5.12t12.8 5.12l211.968 211.968q5.632 5.632 5.632 12.8t-5.632 13.312z%27%3E%3C/path%3E%3C/svg%3E%0A")}.form-label{margin-bottom:.5rem}.col-form-label{padding-top:1px;padding-bottom:1px;margin-bottom:0;font-size:inherit;line-height:1.875rem}.col-form-label-lg{padding-top:1px;padding-bottom:1px;font-size:.75rem}.col-form-label-sm{padding-top:1px;padding-bottom:1px;font-size:.75rem}.form-text{margin-top:.25rem;font-size:.875em;color:var(--t42-content-color-muted)}.form-control{display:block;width:100%;padding:0 .875rem;font-size:.75rem;font-weight:400;line-height:1.875rem;color:var(--t42-link-color);background-color:var(--t42-input-bg);background-clip:padding-box;border:1px solid var(--t42-color-opacity-10);appearance:none;border-radius:0;transition:border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.form-control{transition:none}}.form-control[type="file"]{overflow:hidden}.form-control[type="file"]:not(:disabled):not([readonly]){cursor:pointer}.form-control:focus{color:var(--t42-link-color);background-color:var(--t42-input-bg);border-color:#007be5;outline:0;box-shadow:0 0 0 0 rgba(0,123,229,0.25)}.form-control::-webkit-date-and-time-value{height:1.875rem}.form-control::placeholder{color:var(--t42-content-color-muted);opacity:1}.form-control:disabled,.form-control[readonly]{background-color:var(--t42-input-disabled-bg);opacity:1}.form-control::file-selector-button{padding:0 .875rem;margin:0 -.875rem;margin-inline-end:.875rem;color:var(--t42-link-color);background-color:#e9ecef;pointer-events:none;border-color:inherit;border-style:solid;border-width:0;border-inline-end-width:1px;border-radius:0;transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.form-control::file-selector-button{transition:none}}.form-control:hover:not(:disabled):not([readonly])::file-selector-button{background-color:#dde0e3}.form-control::-webkit-file-upload-button{padding:0 .875rem;margin:0 -.875rem;margin-inline-end:.875rem;color:var(--t42-link-color);background-color:#e9ecef;pointer-events:none;border-color:inherit;border-style:solid;border-width:0;border-inline-end-width:1px;border-radius:0;transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.form-control::-webkit-file-upload-button{transition:none}}.form-control:hover:not(:disabled):not([readonly])::-webkit-file-upload-button{background-color:#dde0e3}.form-control-plaintext{display:block;width:100%;padding:0 0;margin-bottom:0;line-height:1.875rem;color:var(--t42-content-color);background-color:transparent;border:solid transparent;border-width:1px 0}.form-control-plaintext.form-control-sm,.form-control-plaintext.form-control-lg{padding-right:0;padding-left:0}.form-control-sm{min-height:2rem;padding:0 .875rem;font-size:.75rem;border-radius:0}.form-control-sm::file-selector-button{padding:0 .875rem;margin:0 -.875rem;margin-inline-end:.875rem}.form-control-sm::-webkit-file-upload-button{padding:0 .875rem;margin:0 -.875rem;margin-inline-end:.875rem}.form-control-lg{min-height:2rem;padding:0 .875rem;font-size:.75rem;border-radius:0}.form-control-lg::file-selector-button{padding:0 .875rem;margin:0 -.875rem;margin-inline-end:.875rem}.form-control-lg::-webkit-file-upload-button{padding:0 .875rem;margin:0 -.875rem;margin-inline-end:.875rem}textarea.form-control{min-height:2rem}textarea.form-control-sm{min-height:2rem}textarea.form-control-lg{min-height:2rem}.form-control-color{width:3rem;height:auto;padding:0}.form-control-color:not(:disabled):not([readonly]){cursor:pointer}.form-control-color::-moz-color-swatch{height:1.875rem;border-radius:0}.form-control-color::-webkit-color-swatch{height:1.875rem;border-radius:0}.form-select{display:block;width:100%;padding:0 2.625rem 0 .875rem;-moz-padding-start:calc(.875rem - 3px);font-size:.75rem;font-weight:400;line-height:1.875rem;color:var(--t42-link-color);background-color:var(--t42-input-bg);background-image:var(--t42-select-indicator);background-repeat:no-repeat;background-position:right 0.5rem center;background-size:1rem;border:1px solid var(--t42-color-opacity-10);border-radius:0;transition:border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out;appearance:none}@media (prefers-reduced-motion: reduce){.form-select{transition:none}}.form-select:focus{border-color:#007be5;outline:0;box-shadow:0 0 0 0 rgba(0,123,229,0.25)}.form-select[multiple],.form-select[size]:not([size="1"]){padding-right:.875rem;background-image:none}.form-select:disabled{background-color:#e9ecef}.form-select:-moz-focusring{color:transparent;text-shadow:0 0 0 var(--t42-link-color)}.form-select-sm{padding-top:0;padding-bottom:0;padding-left:.875rem;font-size:.75rem;border-radius:0}.form-select-lg{padding-top:0;padding-bottom:0;padding-left:.875rem;font-size:.75rem;border-radius:0}.form-check{display:block;min-height:1.125rem;padding-left:1.25rem;margin-bottom:0}.form-check .form-check-input{float:left;margin-left:-1.25rem}.form-check-input{width:1em;height:1em;margin-top:.25em;vertical-align:top;background-color:var(--t42-input-bg);background-repeat:no-repeat;background-position:center;background-size:contain;border:1px solid rgba(0,0,0,0.25);appearance:none;color-adjust:exact}.form-check-input[type="checkbox"]{border-radius:.25em}.form-check-input[type="radio"]{border-radius:50%}.form-check-input:active{filter:brightness(90%)}.form-check-input:focus{border-color:#007be5;outline:0;box-shadow:0 0 0 0 rgba(0,123,229,0.25)}.form-check-input:checked{background-color:#007be5;border-color:#007be5}.form-check-input:checked[type="checkbox"]{background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 20 20%27%3e%3cpath fill=%27none%27 stroke=%27%23fff%27 stroke-linecap=%27round%27 stroke-linejoin=%27round%27 stroke-width=%273%27 d=%27M6 10l3 3l6-6%27/%3e%3c/svg%3e")}.form-check-input:checked[type="radio"]{background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%27-4 -4 8 8%27%3e%3ccircle r=%272%27 fill=%27%23fff%27/%3e%3c/svg%3e")}.form-check-input[type="checkbox"]:indeterminate{background-color:#007be5;border-color:#007be5;background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 20 20%27%3e%3cpath fill=%27none%27 stroke=%27%23fff%27 stroke-linecap=%27round%27 stroke-linejoin=%27round%27 stroke-width=%273%27 d=%27M6 10h8%27/%3e%3c/svg%3e")}.form-check-input:disabled{pointer-events:none;filter:none;opacity:.5}.form-check-input[disabled] ~ .form-check-label,.form-check-input:disabled ~ .form-check-label{opacity:.5}.form-switch{padding-left:2.5em}.form-switch .form-check-input{width:2em;margin-left:-2.5em;background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%27-4 -4 8 8%27%3e%3ccircle r=%273%27 fill=%27rgba%280,0,0,0.25%29%27/%3e%3c/svg%3e");background-position:left center;border-radius:2em;transition:background-position 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.form-switch .form-check-input{transition:none}}.form-switch .form-check-input:focus{background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%27-4 -4 8 8%27%3e%3ccircle r=%273%27 fill=%27%23007be5%27/%3e%3c/svg%3e")}.form-switch .form-check-input:checked{background-position:right center;background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%27-4 -4 8 8%27%3e%3ccircle r=%273%27 fill=%27%23fff%27/%3e%3c/svg%3e")}.form-check-inline{display:inline-block;margin-right:1rem}.btn-check{position:absolute;clip:rect(0, 0, 0, 0);pointer-events:none}.btn-check[disabled]+.btn,.btn-check:disabled+.btn{pointer-events:none;filter:none;opacity:.35}.form-range{width:100%;height:1rem;padding:0;background-color:transparent;appearance:none}.form-range:focus{outline:0}.form-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 0 rgba(0,123,229,0.25)}.form-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 0 rgba(0,123,229,0.25)}.form-range::-moz-focus-outer{border:0}.form-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-.25rem;background-color:#007be5;border:0;border-radius:1rem;transition:background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out;appearance:none}@media (prefers-reduced-motion: reduce){.form-range::-webkit-slider-thumb{transition:none}}.form-range::-webkit-slider-thumb:active{background-color:#b3d7f7}.form-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.form-range::-moz-range-thumb{width:1rem;height:1rem;background-color:#007be5;border:0;border-radius:1rem;transition:background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out;appearance:none}@media (prefers-reduced-motion: reduce){.form-range::-moz-range-thumb{transition:none}}.form-range::-moz-range-thumb:active{background-color:#b3d7f7}.form-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.form-range:disabled{pointer-events:none}.form-range:disabled::-webkit-slider-thumb{background-color:#adb5bd}.form-range:disabled::-moz-range-thumb{background-color:#adb5bd}.form-floating{position:relative}.form-floating>.form-control,.form-floating>.form-select{height:calc(3.5rem + 2px);line-height:1.25}.form-floating>label{position:absolute;top:0;left:0;height:100%;padding:1rem .875rem;pointer-events:none;border:1px solid transparent;transform-origin:0 0;transition:opacity 0.1s ease-in-out,transform 0.1s ease-in-out}@media (prefers-reduced-motion: reduce){.form-floating>label{transition:none}}.form-floating>.form-control{padding:1rem .875rem}.form-floating>.form-control::placeholder{color:transparent}.form-floating>.form-control:focus,.form-floating>.form-control:not(:placeholder-shown){padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control:-webkit-autofill{padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-select{padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control:focus ~ label,.form-floating>.form-control:not(:placeholder-shown) ~ label,.form-floating>.form-select ~ label{opacity:.65;transform:scale(0.85) translateY(-0.5rem) translateX(0.15rem)}.form-floating>.form-control:-webkit-autofill ~ label{opacity:.65;transform:scale(0.85) translateY(-0.5rem) translateX(0.15rem)}.input-group{position:relative;display:flex;flex-wrap:wrap;align-items:stretch;width:100%}.input-group>.form-control,.input-group>.form-select{position:relative;flex:1 1 auto;width:1%;min-width:0}.input-group>.form-control:focus,.input-group>.form-select:focus{z-index:3}.input-group .btn{position:relative;z-index:2}.input-group .btn:focus{z-index:3}.input-group-text{display:flex;align-items:center;padding:0 .875rem;font-size:.75rem;font-weight:400;line-height:1.875rem;color:var(--t42-content-color);text-align:center;white-space:nowrap;background-color:#e9ecef;border:1px solid var(--t42-color-opacity-10);border-radius:0}.input-group-lg>.form-control,.input-group-lg>.form-select,.input-group-lg>.input-group-text,.input-group-lg>.btn{padding:0 .875rem;font-size:.75rem;border-radius:0}.input-group-sm>.form-control,.input-group-sm>.form-select,.input-group-sm>.input-group-text,.input-group-sm>.btn{padding:0 .875rem;font-size:.75rem;border-radius:0}.input-group-lg>.form-select,.input-group-sm>.form-select{padding-right:3.5rem}.input-group:not(.has-validation)>:not(:last-child):not(.dropdown-toggle):not(.dropdown-menu),.input-group:not(.has-validation)>.dropdown-toggle:nth-last-child(n+3){border-top-right-radius:0;border-bottom-right-radius:0}.input-group.has-validation>:nth-last-child(n+3):not(.dropdown-toggle):not(.dropdown-menu),.input-group.has-validation>.dropdown-toggle:nth-last-child(n+4){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>:not(:first-child):not(.dropdown-menu):not(.valid-tooltip):not(.valid-feedback):not(.invalid-tooltip):not(.invalid-feedback){margin-left:-1px;border-top-left-radius:0;border-bottom-left-radius:0}.valid-feedback{display:none;width:100%;margin-top:.5rem;font-size:.7rem;color:#43a047}.valid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem 1rem;margin-top:.1rem;font-size:.65625rem;color:#000;background-color:#43a047;border-radius:0}.was-validated :valid ~ .valid-feedback,.was-validated :valid ~ .valid-tooltip,.is-valid ~ .valid-feedback,.is-valid ~ .valid-tooltip{display:block}.was-validated .form-control:valid,.form-control.is-valid{border-color:#43a047;padding-right:2rem;background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 8 8%27%3e%3cpath fill=%27%2343a047%27 d=%27M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z%27/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right .5rem center;background-size:1rem 1rem}.was-validated .form-control:valid:focus,.form-control.is-valid:focus{border-color:#43a047;box-shadow:0 0 0 0 rgba(67,160,71,0.25)}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{padding-right:2rem;background-position:top .5rem right .5rem}.was-validated .form-select:valid,.form-select.is-valid{border-color:#43a047}.was-validated .form-select:valid:not([multiple]):not([size]),.was-validated .form-select:valid:not([multiple])[size="1"],.form-select.is-valid:not([multiple]):not([size]),.form-select.is-valid:not([multiple])[size="1"]{padding-right:3.5rem;background-image:var(--t42-select-indicator),url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 8 8%27%3e%3cpath fill=%27%2343a047%27 d=%27M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z%27/%3e%3c/svg%3e");background-position:right 0.5rem center,right 1.75rem center;background-size:1rem,1rem}.was-validated .form-select:valid:focus,.form-select.is-valid:focus{border-color:#43a047;box-shadow:0 0 0 0 rgba(67,160,71,0.25)}.was-validated .form-check-input:valid,.form-check-input.is-valid{border-color:#43a047}.was-validated .form-check-input:valid:checked,.form-check-input.is-valid:checked{background-color:#43a047}.was-validated .form-check-input:valid:focus,.form-check-input.is-valid:focus{box-shadow:0 0 0 0 rgba(67,160,71,0.25)}.was-validated .form-check-input:valid ~ .form-check-label,.form-check-input.is-valid ~ .form-check-label{color:#43a047}.form-check-inline .form-check-input ~ .valid-feedback{margin-left:.5em}.was-validated .input-group .form-control:valid,.input-group .form-control.is-valid,.was-validated .input-group .form-select:valid,.input-group .form-select.is-valid{z-index:1}.was-validated .input-group .form-control:valid:focus,.input-group .form-control.is-valid:focus,.was-validated .input-group .form-select:valid:focus,.input-group .form-select.is-valid:focus{z-index:3}.invalid-feedback{display:none;width:100%;margin-top:.5rem;font-size:.7rem;color:#ff511f}.invalid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem 1rem;margin-top:.1rem;font-size:.65625rem;color:#000;background-color:#ff511f;border-radius:0}.was-validated :invalid ~ .invalid-feedback,.was-validated :invalid ~ .invalid-tooltip,.is-invalid ~ .invalid-feedback,.is-invalid ~ .invalid-tooltip{display:block}.was-validated .form-control:invalid,.form-control.is-invalid{border-color:#ff511f;padding-right:2rem;background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 12 12%27 width=%2712%27 height=%2712%27 fill=%27none%27 stroke=%27%23ff511f%27%3e%3ccircle cx=%276%27 cy=%276%27 r=%274.5%27/%3e%3cpath stroke-linejoin=%27round%27 d=%27M5.8 3.6h.4L6 6.5z%27/%3e%3ccircle cx=%276%27 cy=%278.2%27 r=%27.6%27 fill=%27%23ff511f%27 stroke=%27none%27/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right .5rem center;background-size:1rem 1rem}.was-validated .form-control:invalid:focus,.form-control.is-invalid:focus{border-color:#ff511f;box-shadow:0 0 0 0 rgba(255,81,31,0.25)}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{padding-right:2rem;background-position:top .5rem right .5rem}.was-validated .form-select:invalid,.form-select.is-invalid{border-color:#ff511f}.was-validated .form-select:invalid:not([multiple]):not([size]),.was-validated .form-select:invalid:not([multiple])[size="1"],.form-select.is-invalid:not([multiple]):not([size]),.form-select.is-invalid:not([multiple])[size="1"]{padding-right:3.5rem;background-image:var(--t42-select-indicator),url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 12 12%27 width=%2712%27 height=%2712%27 fill=%27none%27 stroke=%27%23ff511f%27%3e%3ccircle cx=%276%27 cy=%276%27 r=%274.5%27/%3e%3cpath stroke-linejoin=%27round%27 d=%27M5.8 3.6h.4L6 6.5z%27/%3e%3ccircle cx=%276%27 cy=%278.2%27 r=%27.6%27 fill=%27%23ff511f%27 stroke=%27none%27/%3e%3c/svg%3e");background-position:right 0.5rem center,right 1.75rem center;background-size:1rem,1rem}.was-validated .form-select:invalid:focus,.form-select.is-invalid:focus{border-color:#ff511f;box-shadow:0 0 0 0 rgba(255,81,31,0.25)}.was-validated .form-check-input:invalid,.form-check-input.is-invalid{border-color:#ff511f}.was-validated .form-check-input:invalid:checked,.form-check-input.is-invalid:checked{background-color:#ff511f}.was-validated .form-check-input:invalid:focus,.form-check-input.is-invalid:focus{box-shadow:0 0 0 0 rgba(255,81,31,0.25)}.was-validated .form-check-input:invalid ~ .form-check-label,.form-check-input.is-invalid ~ .form-check-label{color:#ff511f}.form-check-inline .form-check-input ~ .invalid-feedback{margin-left:.5em}.was-validated .input-group .form-control:invalid,.input-group .form-control.is-invalid,.was-validated .input-group .form-select:invalid,.input-group .form-select.is-invalid{z-index:2}.was-validated .input-group .form-control:invalid:focus,.input-group .form-control.is-invalid:focus,.was-validated .input-group .form-select:invalid:focus,.input-group .form-select.is-invalid:focus{z-index:3}input{background-color:var(--t42-input-bg)}input[type="number"]::-webkit-calendar-picker-indicator,input[type="datetime-local"]::-webkit-calendar-picker-indicator,input[type="month"]::-webkit-calendar-picker-indicator,input[type="week"]::-webkit-calendar-picker-indicator,input[type="time"]::-webkit-calendar-picker-indicator,input[type="date"]::-webkit-calendar-picker-indicator{background:transparent}input[type="number"]::-webkit-inner-spin-button,input[type="datetime-local"]::-webkit-inner-spin-button,input[type="month"]::-webkit-inner-spin-button,input[type="week"]::-webkit-inner-spin-button,input[type="time"]::-webkit-inner-spin-button,input[type="date"]::-webkit-inner-spin-button{appearance:none}input[type="color"],input[type="range"]{padding:0;border:0}form div[class^="col"]{position:relative}.form-check-label input[type="checkbox"],.form-check-label input[type="radio"]{margin-top:0.125rem;margin-left:-1.2rem;opacity:1}.form-check .form-check-input:disabled{opacity:0}.form-check-label{margin-bottom:0}.form-check-inline .form-check-label{padding-left:0.25rem}.form-check-inline input[type="radio"]:checked+label::after{left:-1rem}.form-control{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border;background-color:transparent}.form-control:disabled,.form-control.disabled,.form-control[readonly]{cursor:default;opacity:0.65}.form-control.is-valid,.form-control.is-invalid{border-color:var(--t42-color-opacity-10)}.form-control.is-valid:focus,.form-control.is-invalid:focus{border-color:var(--primary);box-shadow:none}.form-control[type="file"]{opacity:0}.form-text{color:var(--secondary)}.form-control-plaintext:focus{outline:0}select{background-image:var(--t42-select-indicator);background-repeat:no-repeat;background-position:right 0.5rem center;background-size:1rem;cursor:pointer;appearance:none}select[multiple]{padding:0;background-image:none}select[multiple] option{padding:0 0.875rem}select[multiple] option:checked{background-color:var(--primary)}select:disabled{border-color:transparent;cursor:default;opacity:0.65}textarea,textarea.form-control{min-height:90px;max-height:180px;padding-top:5px;padding-bottom:5px}textarea:disabled,textarea.form-control:disabled{border-color:transparent}input[type="range"]{width:100%;appearance:none}input[type="range"]:focus{background-color:transparent;outline:none}input[type="range"]:focus::-ms-fill-lower,input[type="range"]:focus::-ms-fill-upper{background:var(--primary)}input[type="range"]::-webkit-slider-runnable-track{width:100%;height:0.0625rem;border:0;border-radius:0;background:var(--t42-color-opacity-10);box-shadow:none;cursor:pointer}input[type="range"]::-webkit-slider-thumb{width:12px;height:12px;margin-top:-5px;border:0;border-radius:50%;background:var(--primary);box-shadow:none;cursor:pointer;appearance:none}input[type="range"]:focus::-webkit-slider-runnable-track{background:var(--t42-color-opacity-10)}input[type="range"]::-moz-range-track{width:100%;height:2px;border:0;border-radius:0;background:var(--t42-color-opacity-10);box-shadow:none;cursor:pointer}input[type="range"]::-moz-range-thumb{width:12px;height:12px;border:0;border-radius:50px;background:var(--primary);box-shadow:none;cursor:pointer}input[type="range"]::-ms-track{width:100%;height:2px;border-color:transparent;color:transparent;background:transparent;cursor:pointer}input[type="range"]::-ms-fill-lower,input[type="range"]::-ms-fill-upper{border:0;border-radius:0;background:var(--primary);box-shadow:none}input[type="range"]::-ms-thumb{width:12px;height:12px;border:0;border-radius:50px;background:var(--primary);box-shadow:none;cursor:pointer}input[type="checkbox"]{opacity:0}input[type="checkbox"]+label{position:relative;color:var(--t42-content-color-muted);cursor:pointer;user-select:none}input[type="checkbox"]+label::before{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, border-color;position:absolute;top:0.0625rem;left:-1.25rem;display:block;width:0.875rem;height:0.875rem;border:0.0625rem solid var(--t42-content-color-muted);border-radius:0;cursor:pointer;content:"";pointer-events:all}input[type="checkbox"]+label::after{position:absolute;top:0.125rem;left:-1.188rem;display:block;width:0.875rem;height:0.875rem;background-image:none;content:"";-webkit-mask-size:0.75rem;-webkit-mask-repeat:no-repeat;content:""}input[type="checkbox"].indeterminate+label::before,input[type="checkbox"]:indeterminate+label::before{border-color:var(--t42-color-opacity-30);background-color:var(--primary)}input[type="checkbox"].indeterminate+label::after,input[type="checkbox"]:indeterminate+label::after{top:0.375rem;left:-1.063rem;width:0.5rem;height:0.188rem;background-color:var(--white)}input[type="checkbox"]:disabled+label,input[type="checkbox"]:disabled+.form-check-label{color:var(--t42-content-color-disabled)}input[type="checkbox"]:checked.disabled+label,input[type="checkbox"]:checked:disabled+label,input[type="checkbox"]:indeterminate.disabled+label,input[type="checkbox"]:indeterminate:disabled+label,input[type="checkbox"].disabled+label,input[type="checkbox"]:disabled+label{color:var(--t42-content-color-disabled)}input[type="checkbox"]:checked.disabled+label::before,input[type="checkbox"]:checked:disabled+label::before,input[type="checkbox"]:indeterminate.disabled+label::before,input[type="checkbox"]:indeterminate:disabled+label::before,input[type="checkbox"].disabled+label::before,input[type="checkbox"]:disabled+label::before{border-color:transparent;background-color:var(--t42-color-opacity-10)}input[type="checkbox"]:checked+label::before{border-color:var(--t42-color-opacity-30);background-color:var(--primary)}input[type="checkbox"]:checked+label::after{background-color:var(--t42-link-color);-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M212.48599,435.14899c-11.60532,0.00003-21.16266-4.77866-28.672-14.336l-92.16-120.832 c-5.46133-8.19202-7.50933-17.06665-6.144-26.62399s5.80267-17.408,13.312-23.552s16.21333-8.53334,26.112-7.168 c9.89867,1.36533,17.92,6.14401,24.064,14.336l60.416,78.84799L360.966,93.13298c5.46133-8.192,12.79999-13.312,22.01599-15.36 s18.26132-0.68267,27.13599,4.096c8.19199,5.46133,13.31198,12.8,15.35999,22.016s0.68265,18.26133-4.09601,27.136l-179.2,286.71997 c-6.82668,10.9227-16.384,16.384-28.672,16.384L212.48599,435.14899z%27/%3E%3C/svg%3E")}input[type="radio"]{opacity:0}input[type="radio"]+label{position:relative;color:var(--t42-content-color-muted);cursor:pointer;user-select:none}input[type="radio"]+label::before{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, border;position:absolute;top:0.0625rem;left:-1.25rem;display:block;width:0.875rem;height:0.875rem;border:0.0625rem solid var(--t42-content-color-muted);border-radius:50%;cursor:pointer;content:"";pointer-events:all}input[type="radio"]+label::after{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, border;position:absolute;top:0.313rem;left:-1rem;display:block;width:0.375rem;height:0.375rem;border-radius:50%;color:var(--white);background-image:none;transform:scale(0);opacity:0;content:""}input[type="radio"]+label:focus{border-color:var(--primary)}input[type="radio"]:disabled+label,input[type="radio"]:disabled+.form-check-label{color:var(--t42-content-color-disabled)}input[type="radio"]:checked.disabled+label,input[type="radio"]:checked:disabled+label,input[type="radio"].disabled+label,input[type="radio"]:disabled+label{color:var(--t42-content-color-disabled)}input[type="radio"]:checked.disabled+label::before,input[type="radio"]:checked:disabled+label::before,input[type="radio"].disabled+label::before,input[type="radio"]:disabled+label::before{border-color:transparent;background-color:var(--t42-color-opacity-10)}input[type="radio"]:checked+label::before{border-color:var(--t42-color-opacity-30);background-color:var(--primary)}input[type="radio"]:checked+label::after{background-color:var(--white);transform:scale(1);opacity:1}.custom-control{padding-left:1.25rem}.custom-control .custom-control-input:checked ~ .custom-control-label::before{border-color:var(--t42-color-opacity-30)}.custom-select,.form-select{max-height:2rem;background-color:transparent;background-image:var(--t42-select-indicator);background-repeat:no-repeat;background-position:right 0.5rem center;background-size:1rem}.custom-select:focus,.custom-select option,.form-select:focus,.form-select option{background-color:var(--t42-input-bg)}.custom-select:disabled option,.form-select:disabled option{background-color:transparent}.custom-radio .custom-control-label{color:var(--t42-content-color-muted);user-select:none}.custom-radio .custom-control-label::after{background:none}.custom-radio .custom-control-input:checked ~ .custom-control-label::after{background-image:none}.custom-checkbox .custom-control-label{color:var(--t42-content-color-muted);user-select:none}.custom-checkbox .custom-control-label::after{background:none}.custom-checkbox .custom-control-input:checked ~ .custom-control-label::after{background-image:none}.custom-checkbox .custom-control-input:disabled .custom-control-label::after,.custom-checkbox .custom-control-input:disabled:checked ~ .custom-control-label::after,.custom-checkbox .custom-control-input:disabled:indeterminate ~ .custom-control-label::after{opacity:0.4}.custom-checkbox .custom-control-input:disabled ~ .custom-control-label::before{border-color:transparent}.switch{position:relative;display:inline-block;align-items:center;height:0.875rem;margin-bottom:0;padding-left:2rem;cursor:pointer}.switch.disabled{color:var(--t42-content-color-disabled)}.switch .slider{position:absolute;top:0;right:0;bottom:0;left:0;width:1.75rem;border:1px solid var(--t42-content-color-muted);cursor:pointer;transition:0.4s}.switch .slider::before{position:absolute;bottom:0.125rem;left:0.125rem;width:0.5rem;height:0.5rem;background-color:var(--t42-content-color-muted);transition:0.4s;content:""}.switch input{width:0;height:0;opacity:0}.switch input:checked+.slider{border:var(--t42-border);background-color:var(--primary)}.switch input:checked+.slider::before{background-color:var(--white);transform:translateX(0.875rem)}.switch input:focus+.slider{box-shadow:0 0 1px #2196f3}.switch input:disabled+.slider{border:var(--t42-border);background-color:var(--t42-color-opacity-10)}.switch input:disabled+.slider::before{background-color:var(--t42-color-opacity-20)}.input-group-prepend .input-group-text{justify-content:center;border-right:0}.input-group-append .input-group-text{justify-content:center;border-left:0}.input-group-append .custom-control,.input-group-prepend .custom-control{margin-bottom:0;padding-left:0.875rem}.input-group-append .custom-control-label,.input-group-prepend .custom-control-label{position:absolute;left:0;min-width:0.875rem;min-height:0.875rem}.input-group-append .custom-control-label::before,.input-group-prepend .custom-control-label::before{left:0}.input-group-append .custom-control-label::after,.input-group-prepend .custom-control-label::after{left:0.25rem}.input-group-append .custom-checkbox .custom-control-label::after,.input-group-prepend .custom-checkbox .custom-control-label::after{left:0.125rem}.custom-file{margin-bottom:1rem}.custom-file-input,.form-control[type="file"]{z-index:1}.custom-file-input:focus ~ .custom-file-label,.form-control[type="file"]:focus ~ .custom-file-label{background-color:var(--t42-input-bg)}.custom-file-label,.input-group-text{background-color:transparent}.custom-file-label::after,.input-group-text::after{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color;background-color:Rgba(--secondary, 0.05);cursor:pointer}.custom-file-label:hover::after,.input-group-text:hover::after{color:var(--white);background-color:var(--secondary)}.form-control[type="file"]+.input-group-text{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color,color;position:absolute;top:0;right:0;left:0;z-index:1;height:2rem;padding:0.375rem 0.875rem;border:var(--t42-border);color:var(--t42-content-color-muted)}.form-control[type="file"]+.input-group-text::after{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color,color;position:absolute;top:0;right:0;bottom:0;z-index:3;display:block;height:100%;padding:0.375rem 0.875rem;border-left:inherit;color:var(--t42-link-color);line-height:1.5;cursor:pointer;content:"Browse"}.form-control[type="file"]+.input-group-text:hover{background-color:var(--t42-input-bg)}.form-control[type="file"]+.input-group-text:hover::after{color:var(--white);background-color:var(--secondary)}.custom-switch{padding-left:2rem}.custom-switch .custom-control-label::before{left:-2rem}.custom-switch .custom-control-label::after{top:0.25rem;left:-1.813rem;width:0.5rem;height:0.5rem}.custom-switch .custom-control-input:checked ~ .custom-control-label::after{background-color:var(--white);content:""}.custom-switch .custom-control-input:not(:disabled):active ~ .custom-control-label::before{border-color:var(--t42-color-opacity-30);background-color:var(--primary)}.valid-feedback,.valid-tooltip,.invalid-feedback,.invalid-tooltip,.warning-feedback,.warning-tooltip{position:absolute;bottom:-1rem;width:calc(100% - 1.875rem);margin-top:0;overflow:hidden;color:var(--t42-content-color);font-size:.7rem;white-space:nowrap;text-overflow:ellipsis}.valid-tooltip,.invalid-tooltip,.warning-tooltip{color:var(--t42-content-color-muted)}.custom-radio label+div,.custom-checkbox label+div,.form-check label+div{width:calc(100% + 1.25rem);transform:translateX(-1.25rem)}.form-group{margin-bottom:1rem}label{margin-bottom:0.5rem}.form-row{display:flex;flex-wrap:wrap;margin-right:-0.5rem;margin-left:-0.5rem}.form-row>.col,.form-row>[class*="col-"]{padding-right:0.5rem;padding-left:0.5rem}.form-inline{display:flex;flex-flow:row wrap;align-items:center}.form-inline .form-check{width:100%}@media (min-width: 576px){.form-inline label{display:flex;align-items:center;justify-content:center;margin-bottom:0}.form-inline .form-group{display:flex;flex:0 0 auto;flex-flow:row wrap;align-items:center;margin-bottom:0}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-plaintext{display:inline-block}.form-inline .input-group,.form-inline .custom-select,.form-inline .form-select{width:auto}.form-inline .form-check{display:flex;align-items:center;justify-content:center;width:auto;padding-left:0}.form-inline .form-check-input{position:relative;flex-shrink:0;margin-top:0;margin-left:0}.form-inline .custom-control{align-items:center;justify-content:center}.form-inline .custom-control-label{margin-bottom:0}}/*! + * Bootstrap Grid v5.1.3 (https://getbootstrap.com/) + * Copyright 2011-2021 The Bootstrap Authors + * Copyright 2011-2021 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) + */:root{--bs-blue: #007be5;--bs-indigo: #6610f2;--bs-purple: #6f42c1;--bs-pink: #fd397a;--bs-red: #ff511f;--bs-orange: #fd7e14;--bs-yellow: #f9a825;--bs-green: #43a047;--bs-teal: #616161;--bs-cyan: #469eb9;--bs-white: #fff;--bs-gray: #6c757d;--bs-gray-dark: #343a40;--bs-gray-100: #f8f9fa;--bs-gray-200: #e9ecef;--bs-gray-300: #dee2e6;--bs-gray-400: #ced4da;--bs-gray-500: #adb5bd;--bs-gray-600: #6c757d;--bs-gray-700: #495057;--bs-gray-800: #343a40;--bs-gray-900: #212529;--bs-primary: #007be5;--bs-secondary: #616161;--bs-success: #43a047;--bs-info: #469eb9;--bs-warning: #f9a825;--bs-danger: #ff511f;--bs-light: #616161;--bs-dark: #616161;--bs-primary-rgb: 0,123,229;--bs-secondary-rgb: 97,97,97;--bs-success-rgb: 67,160,71;--bs-info-rgb: 70,158,185;--bs-warning-rgb: 249,168,37;--bs-danger-rgb: 255,81,31;--bs-light-rgb: 97,97,97;--bs-dark-rgb: 97,97,97;--bs-white-rgb: 255,255,255;--bs-black-rgb: 0,0,0;--bs-body-color-rgb: 33,37,41;--bs-body-bg-rgb: 255,255,255;--bs-font-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--bs-gradient: linear-gradient(180deg, rgba(255,255,255,0.15), rgba(255,255,255,0));--bs-body-font-family: Montserrat,Helvetica Neue,Arial,sans-serif;--bs-body-font-size: .75rem;--bs-body-font-weight: 400;--bs-body-line-height: 1.5;--bs-body-color: #212529;--bs-body-bg: #fff}.container,.container-fluid,.container-sm,.container-md,.container-lg,.container-xl,.container-xxl{width:100%;padding-right:var(--bs-gutter-x, .75rem);padding-left:var(--bs-gutter-x, .75rem);margin-right:auto;margin-left:auto}@media (min-width: 576px){.container,.container-sm{max-width:540px}}@media (min-width: 768px){.container,.container-sm,.container-md{max-width:720px}}@media (min-width: 992px){.container,.container-sm,.container-md,.container-lg{max-width:960px}}@media (min-width: 1200px){.container,.container-sm,.container-md,.container-lg,.container-xl{max-width:1140px}}@media (min-width: 1400px){.container,.container-sm,.container-md,.container-lg,.container-xl,.container-xxl{max-width:1320px}}.row{--bs-gutter-x: 1.5rem;--bs-gutter-y: 0;display:flex;flex-wrap:wrap;margin-top:calc(-1 * var(--bs-gutter-y));margin-right:calc(-.5 * var(--bs-gutter-x));margin-left:calc(-.5 * var(--bs-gutter-x))}.row>*{box-sizing:border-box;flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--bs-gutter-x) * .5);padding-left:calc(var(--bs-gutter-x) * .5);margin-top:var(--bs-gutter-y)}.col{flex:1 0 0%}.row-cols-auto>*{flex:0 0 auto;width:auto}.row-cols-1>*{flex:0 0 auto;width:100%}.row-cols-2>*{flex:0 0 auto;width:50%}.row-cols-3>*{flex:0 0 auto;width:33.33333%}.row-cols-4>*{flex:0 0 auto;width:25%}.row-cols-5>*{flex:0 0 auto;width:20%}.row-cols-6>*{flex:0 0 auto;width:16.66667%}.col-auto{flex:0 0 auto;width:auto}.col-1{flex:0 0 auto;width:8.33333%}.col-2{flex:0 0 auto;width:16.66667%}.col-3{flex:0 0 auto;width:25%}.col-4{flex:0 0 auto;width:33.33333%}.col-5{flex:0 0 auto;width:41.66667%}.col-6{flex:0 0 auto;width:50%}.col-7{flex:0 0 auto;width:58.33333%}.col-8{flex:0 0 auto;width:66.66667%}.col-9{flex:0 0 auto;width:75%}.col-10{flex:0 0 auto;width:83.33333%}.col-11{flex:0 0 auto;width:91.66667%}.col-12{flex:0 0 auto;width:100%}.offset-1{margin-left:8.33333%}.offset-2{margin-left:16.66667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.33333%}.offset-5{margin-left:41.66667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.33333%}.offset-8{margin-left:66.66667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.33333%}.offset-11{margin-left:91.66667%}.g-0,.gx-0{--bs-gutter-x: 0}.g-0,.gy-0{--bs-gutter-y: 0}.g-1,.gx-1{--bs-gutter-x: .25rem}.g-1,.gy-1{--bs-gutter-y: .25rem}.g-2,.gx-2{--bs-gutter-x: .5rem}.g-2,.gy-2{--bs-gutter-y: .5rem}.g-3,.gx-3{--bs-gutter-x: 1rem}.g-3,.gy-3{--bs-gutter-y: 1rem}.g-4,.gx-4{--bs-gutter-x: 1.5rem}.g-4,.gy-4{--bs-gutter-y: 1.5rem}.g-5,.gx-5{--bs-gutter-x: 3rem}.g-5,.gy-5{--bs-gutter-y: 3rem}@media (min-width: 576px){.col-sm{flex:1 0 0%}.row-cols-sm-auto>*{flex:0 0 auto;width:auto}.row-cols-sm-1>*{flex:0 0 auto;width:100%}.row-cols-sm-2>*{flex:0 0 auto;width:50%}.row-cols-sm-3>*{flex:0 0 auto;width:33.33333%}.row-cols-sm-4>*{flex:0 0 auto;width:25%}.row-cols-sm-5>*{flex:0 0 auto;width:20%}.row-cols-sm-6>*{flex:0 0 auto;width:16.66667%}.col-sm-auto{flex:0 0 auto;width:auto}.col-sm-1{flex:0 0 auto;width:8.33333%}.col-sm-2{flex:0 0 auto;width:16.66667%}.col-sm-3{flex:0 0 auto;width:25%}.col-sm-4{flex:0 0 auto;width:33.33333%}.col-sm-5{flex:0 0 auto;width:41.66667%}.col-sm-6{flex:0 0 auto;width:50%}.col-sm-7{flex:0 0 auto;width:58.33333%}.col-sm-8{flex:0 0 auto;width:66.66667%}.col-sm-9{flex:0 0 auto;width:75%}.col-sm-10{flex:0 0 auto;width:83.33333%}.col-sm-11{flex:0 0 auto;width:91.66667%}.col-sm-12{flex:0 0 auto;width:100%}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.33333%}.offset-sm-2{margin-left:16.66667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.33333%}.offset-sm-5{margin-left:41.66667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.33333%}.offset-sm-8{margin-left:66.66667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.33333%}.offset-sm-11{margin-left:91.66667%}.g-sm-0,.gx-sm-0{--bs-gutter-x: 0}.g-sm-0,.gy-sm-0{--bs-gutter-y: 0}.g-sm-1,.gx-sm-1{--bs-gutter-x: .25rem}.g-sm-1,.gy-sm-1{--bs-gutter-y: .25rem}.g-sm-2,.gx-sm-2{--bs-gutter-x: .5rem}.g-sm-2,.gy-sm-2{--bs-gutter-y: .5rem}.g-sm-3,.gx-sm-3{--bs-gutter-x: 1rem}.g-sm-3,.gy-sm-3{--bs-gutter-y: 1rem}.g-sm-4,.gx-sm-4{--bs-gutter-x: 1.5rem}.g-sm-4,.gy-sm-4{--bs-gutter-y: 1.5rem}.g-sm-5,.gx-sm-5{--bs-gutter-x: 3rem}.g-sm-5,.gy-sm-5{--bs-gutter-y: 3rem}}@media (min-width: 768px){.col-md{flex:1 0 0%}.row-cols-md-auto>*{flex:0 0 auto;width:auto}.row-cols-md-1>*{flex:0 0 auto;width:100%}.row-cols-md-2>*{flex:0 0 auto;width:50%}.row-cols-md-3>*{flex:0 0 auto;width:33.33333%}.row-cols-md-4>*{flex:0 0 auto;width:25%}.row-cols-md-5>*{flex:0 0 auto;width:20%}.row-cols-md-6>*{flex:0 0 auto;width:16.66667%}.col-md-auto{flex:0 0 auto;width:auto}.col-md-1{flex:0 0 auto;width:8.33333%}.col-md-2{flex:0 0 auto;width:16.66667%}.col-md-3{flex:0 0 auto;width:25%}.col-md-4{flex:0 0 auto;width:33.33333%}.col-md-5{flex:0 0 auto;width:41.66667%}.col-md-6{flex:0 0 auto;width:50%}.col-md-7{flex:0 0 auto;width:58.33333%}.col-md-8{flex:0 0 auto;width:66.66667%}.col-md-9{flex:0 0 auto;width:75%}.col-md-10{flex:0 0 auto;width:83.33333%}.col-md-11{flex:0 0 auto;width:91.66667%}.col-md-12{flex:0 0 auto;width:100%}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.33333%}.offset-md-2{margin-left:16.66667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.33333%}.offset-md-5{margin-left:41.66667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.33333%}.offset-md-8{margin-left:66.66667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.33333%}.offset-md-11{margin-left:91.66667%}.g-md-0,.gx-md-0{--bs-gutter-x: 0}.g-md-0,.gy-md-0{--bs-gutter-y: 0}.g-md-1,.gx-md-1{--bs-gutter-x: .25rem}.g-md-1,.gy-md-1{--bs-gutter-y: .25rem}.g-md-2,.gx-md-2{--bs-gutter-x: .5rem}.g-md-2,.gy-md-2{--bs-gutter-y: .5rem}.g-md-3,.gx-md-3{--bs-gutter-x: 1rem}.g-md-3,.gy-md-3{--bs-gutter-y: 1rem}.g-md-4,.gx-md-4{--bs-gutter-x: 1.5rem}.g-md-4,.gy-md-4{--bs-gutter-y: 1.5rem}.g-md-5,.gx-md-5{--bs-gutter-x: 3rem}.g-md-5,.gy-md-5{--bs-gutter-y: 3rem}}@media (min-width: 992px){.col-lg{flex:1 0 0%}.row-cols-lg-auto>*{flex:0 0 auto;width:auto}.row-cols-lg-1>*{flex:0 0 auto;width:100%}.row-cols-lg-2>*{flex:0 0 auto;width:50%}.row-cols-lg-3>*{flex:0 0 auto;width:33.33333%}.row-cols-lg-4>*{flex:0 0 auto;width:25%}.row-cols-lg-5>*{flex:0 0 auto;width:20%}.row-cols-lg-6>*{flex:0 0 auto;width:16.66667%}.col-lg-auto{flex:0 0 auto;width:auto}.col-lg-1{flex:0 0 auto;width:8.33333%}.col-lg-2{flex:0 0 auto;width:16.66667%}.col-lg-3{flex:0 0 auto;width:25%}.col-lg-4{flex:0 0 auto;width:33.33333%}.col-lg-5{flex:0 0 auto;width:41.66667%}.col-lg-6{flex:0 0 auto;width:50%}.col-lg-7{flex:0 0 auto;width:58.33333%}.col-lg-8{flex:0 0 auto;width:66.66667%}.col-lg-9{flex:0 0 auto;width:75%}.col-lg-10{flex:0 0 auto;width:83.33333%}.col-lg-11{flex:0 0 auto;width:91.66667%}.col-lg-12{flex:0 0 auto;width:100%}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.33333%}.offset-lg-2{margin-left:16.66667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.33333%}.offset-lg-5{margin-left:41.66667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.33333%}.offset-lg-8{margin-left:66.66667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.33333%}.offset-lg-11{margin-left:91.66667%}.g-lg-0,.gx-lg-0{--bs-gutter-x: 0}.g-lg-0,.gy-lg-0{--bs-gutter-y: 0}.g-lg-1,.gx-lg-1{--bs-gutter-x: .25rem}.g-lg-1,.gy-lg-1{--bs-gutter-y: .25rem}.g-lg-2,.gx-lg-2{--bs-gutter-x: .5rem}.g-lg-2,.gy-lg-2{--bs-gutter-y: .5rem}.g-lg-3,.gx-lg-3{--bs-gutter-x: 1rem}.g-lg-3,.gy-lg-3{--bs-gutter-y: 1rem}.g-lg-4,.gx-lg-4{--bs-gutter-x: 1.5rem}.g-lg-4,.gy-lg-4{--bs-gutter-y: 1.5rem}.g-lg-5,.gx-lg-5{--bs-gutter-x: 3rem}.g-lg-5,.gy-lg-5{--bs-gutter-y: 3rem}}@media (min-width: 1200px){.col-xl{flex:1 0 0%}.row-cols-xl-auto>*{flex:0 0 auto;width:auto}.row-cols-xl-1>*{flex:0 0 auto;width:100%}.row-cols-xl-2>*{flex:0 0 auto;width:50%}.row-cols-xl-3>*{flex:0 0 auto;width:33.33333%}.row-cols-xl-4>*{flex:0 0 auto;width:25%}.row-cols-xl-5>*{flex:0 0 auto;width:20%}.row-cols-xl-6>*{flex:0 0 auto;width:16.66667%}.col-xl-auto{flex:0 0 auto;width:auto}.col-xl-1{flex:0 0 auto;width:8.33333%}.col-xl-2{flex:0 0 auto;width:16.66667%}.col-xl-3{flex:0 0 auto;width:25%}.col-xl-4{flex:0 0 auto;width:33.33333%}.col-xl-5{flex:0 0 auto;width:41.66667%}.col-xl-6{flex:0 0 auto;width:50%}.col-xl-7{flex:0 0 auto;width:58.33333%}.col-xl-8{flex:0 0 auto;width:66.66667%}.col-xl-9{flex:0 0 auto;width:75%}.col-xl-10{flex:0 0 auto;width:83.33333%}.col-xl-11{flex:0 0 auto;width:91.66667%}.col-xl-12{flex:0 0 auto;width:100%}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.33333%}.offset-xl-2{margin-left:16.66667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.33333%}.offset-xl-5{margin-left:41.66667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.33333%}.offset-xl-8{margin-left:66.66667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.33333%}.offset-xl-11{margin-left:91.66667%}.g-xl-0,.gx-xl-0{--bs-gutter-x: 0}.g-xl-0,.gy-xl-0{--bs-gutter-y: 0}.g-xl-1,.gx-xl-1{--bs-gutter-x: .25rem}.g-xl-1,.gy-xl-1{--bs-gutter-y: .25rem}.g-xl-2,.gx-xl-2{--bs-gutter-x: .5rem}.g-xl-2,.gy-xl-2{--bs-gutter-y: .5rem}.g-xl-3,.gx-xl-3{--bs-gutter-x: 1rem}.g-xl-3,.gy-xl-3{--bs-gutter-y: 1rem}.g-xl-4,.gx-xl-4{--bs-gutter-x: 1.5rem}.g-xl-4,.gy-xl-4{--bs-gutter-y: 1.5rem}.g-xl-5,.gx-xl-5{--bs-gutter-x: 3rem}.g-xl-5,.gy-xl-5{--bs-gutter-y: 3rem}}@media (min-width: 1400px){.col-xxl{flex:1 0 0%}.row-cols-xxl-auto>*{flex:0 0 auto;width:auto}.row-cols-xxl-1>*{flex:0 0 auto;width:100%}.row-cols-xxl-2>*{flex:0 0 auto;width:50%}.row-cols-xxl-3>*{flex:0 0 auto;width:33.33333%}.row-cols-xxl-4>*{flex:0 0 auto;width:25%}.row-cols-xxl-5>*{flex:0 0 auto;width:20%}.row-cols-xxl-6>*{flex:0 0 auto;width:16.66667%}.col-xxl-auto{flex:0 0 auto;width:auto}.col-xxl-1{flex:0 0 auto;width:8.33333%}.col-xxl-2{flex:0 0 auto;width:16.66667%}.col-xxl-3{flex:0 0 auto;width:25%}.col-xxl-4{flex:0 0 auto;width:33.33333%}.col-xxl-5{flex:0 0 auto;width:41.66667%}.col-xxl-6{flex:0 0 auto;width:50%}.col-xxl-7{flex:0 0 auto;width:58.33333%}.col-xxl-8{flex:0 0 auto;width:66.66667%}.col-xxl-9{flex:0 0 auto;width:75%}.col-xxl-10{flex:0 0 auto;width:83.33333%}.col-xxl-11{flex:0 0 auto;width:91.66667%}.col-xxl-12{flex:0 0 auto;width:100%}.offset-xxl-0{margin-left:0}.offset-xxl-1{margin-left:8.33333%}.offset-xxl-2{margin-left:16.66667%}.offset-xxl-3{margin-left:25%}.offset-xxl-4{margin-left:33.33333%}.offset-xxl-5{margin-left:41.66667%}.offset-xxl-6{margin-left:50%}.offset-xxl-7{margin-left:58.33333%}.offset-xxl-8{margin-left:66.66667%}.offset-xxl-9{margin-left:75%}.offset-xxl-10{margin-left:83.33333%}.offset-xxl-11{margin-left:91.66667%}.g-xxl-0,.gx-xxl-0{--bs-gutter-x: 0}.g-xxl-0,.gy-xxl-0{--bs-gutter-y: 0}.g-xxl-1,.gx-xxl-1{--bs-gutter-x: .25rem}.g-xxl-1,.gy-xxl-1{--bs-gutter-y: .25rem}.g-xxl-2,.gx-xxl-2{--bs-gutter-x: .5rem}.g-xxl-2,.gy-xxl-2{--bs-gutter-y: .5rem}.g-xxl-3,.gx-xxl-3{--bs-gutter-x: 1rem}.g-xxl-3,.gy-xxl-3{--bs-gutter-y: 1rem}.g-xxl-4,.gx-xxl-4{--bs-gutter-x: 1.5rem}.g-xxl-4,.gy-xxl-4{--bs-gutter-y: 1.5rem}.g-xxl-5,.gx-xxl-5{--bs-gutter-x: 3rem}.g-xxl-5,.gy-xxl-5{--bs-gutter-y: 3rem}}.d-inline{display:inline !important}.d-inline-block{display:inline-block !important}.d-block{display:block !important}.d-grid{display:grid !important}.d-table{display:table !important}.d-table-row{display:table-row !important}.d-table-cell{display:table-cell !important}.d-flex{display:flex !important}.d-inline-flex{display:inline-flex !important}.d-none{display:none !important}.flex-fill{flex:1 1 auto !important}.flex-row{flex-direction:row !important}.flex-column{flex-direction:column !important}.flex-row-reverse{flex-direction:row-reverse !important}.flex-column-reverse{flex-direction:column-reverse !important}.flex-grow-0{flex-grow:0 !important}.flex-grow-1{flex-grow:1 !important}.flex-shrink-0{flex-shrink:0 !important}.flex-shrink-1{flex-shrink:1 !important}.flex-wrap{flex-wrap:wrap !important}.flex-nowrap{flex-wrap:nowrap !important}.flex-wrap-reverse{flex-wrap:wrap-reverse !important}.justify-content-start{justify-content:flex-start !important}.justify-content-end{justify-content:flex-end !important}.justify-content-center{justify-content:center !important}.justify-content-between{justify-content:space-between !important}.justify-content-around{justify-content:space-around !important}.justify-content-evenly{justify-content:space-evenly !important}.align-items-start{align-items:flex-start !important}.align-items-end{align-items:flex-end !important}.align-items-center{align-items:center !important}.align-items-baseline{align-items:baseline !important}.align-items-stretch{align-items:stretch !important}.align-content-start{align-content:flex-start !important}.align-content-end{align-content:flex-end !important}.align-content-center{align-content:center !important}.align-content-between{align-content:space-between !important}.align-content-around{align-content:space-around !important}.align-content-stretch{align-content:stretch !important}.align-self-auto{align-self:auto !important}.align-self-start{align-self:flex-start !important}.align-self-end{align-self:flex-end !important}.align-self-center{align-self:center !important}.align-self-baseline{align-self:baseline !important}.align-self-stretch{align-self:stretch !important}.order-first{order:-1 !important}.order-0{order:0 !important}.order-1{order:1 !important}.order-2{order:2 !important}.order-3{order:3 !important}.order-4{order:4 !important}.order-5{order:5 !important}.order-last{order:6 !important}.m-0{margin:0 !important}.m-1{margin:.25rem !important}.m-2{margin:.5rem !important}.m-3{margin:1rem !important}.m-4{margin:1.5rem !important}.m-5{margin:3rem !important}.m-auto{margin:auto !important}.mx-0{margin-right:0 !important;margin-left:0 !important}.mx-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-3{margin-right:1rem !important;margin-left:1rem !important}.mx-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-5{margin-right:3rem !important;margin-left:3rem !important}.mx-auto{margin-right:auto !important;margin-left:auto !important}.my-0{margin-top:0 !important;margin-bottom:0 !important}.my-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-0{margin-top:0 !important}.mt-1{margin-top:.25rem !important}.mt-2{margin-top:.5rem !important}.mt-3{margin-top:1rem !important}.mt-4{margin-top:1.5rem !important}.mt-5{margin-top:3rem !important}.mt-auto{margin-top:auto !important}.me-0{margin-right:0 !important}.me-1{margin-right:.25rem !important}.me-2{margin-right:.5rem !important}.me-3{margin-right:1rem !important}.me-4{margin-right:1.5rem !important}.me-5{margin-right:3rem !important}.me-auto{margin-right:auto !important}.mb-0{margin-bottom:0 !important}.mb-1{margin-bottom:.25rem !important}.mb-2{margin-bottom:.5rem !important}.mb-3{margin-bottom:1rem !important}.mb-4{margin-bottom:1.5rem !important}.mb-5{margin-bottom:3rem !important}.mb-auto{margin-bottom:auto !important}.ms-0{margin-left:0 !important}.ms-1{margin-left:.25rem !important}.ms-2{margin-left:.5rem !important}.ms-3{margin-left:1rem !important}.ms-4{margin-left:1.5rem !important}.ms-5{margin-left:3rem !important}.ms-auto{margin-left:auto !important}.p-0{padding:0 !important}.p-1{padding:.25rem !important}.p-2{padding:.5rem !important}.p-3{padding:1rem !important}.p-4{padding:1.5rem !important}.p-5{padding:3rem !important}.px-0{padding-right:0 !important;padding-left:0 !important}.px-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-3{padding-right:1rem !important;padding-left:1rem !important}.px-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-5{padding-right:3rem !important;padding-left:3rem !important}.py-0{padding-top:0 !important;padding-bottom:0 !important}.py-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-0{padding-top:0 !important}.pt-1{padding-top:.25rem !important}.pt-2{padding-top:.5rem !important}.pt-3{padding-top:1rem !important}.pt-4{padding-top:1.5rem !important}.pt-5{padding-top:3rem !important}.pe-0{padding-right:0 !important}.pe-1{padding-right:.25rem !important}.pe-2{padding-right:.5rem !important}.pe-3{padding-right:1rem !important}.pe-4{padding-right:1.5rem !important}.pe-5{padding-right:3rem !important}.pb-0{padding-bottom:0 !important}.pb-1{padding-bottom:.25rem !important}.pb-2{padding-bottom:.5rem !important}.pb-3{padding-bottom:1rem !important}.pb-4{padding-bottom:1.5rem !important}.pb-5{padding-bottom:3rem !important}.ps-0{padding-left:0 !important}.ps-1{padding-left:.25rem !important}.ps-2{padding-left:.5rem !important}.ps-3{padding-left:1rem !important}.ps-4{padding-left:1.5rem !important}.ps-5{padding-left:3rem !important}@media (min-width: 576px){.d-sm-inline{display:inline !important}.d-sm-inline-block{display:inline-block !important}.d-sm-block{display:block !important}.d-sm-grid{display:grid !important}.d-sm-table{display:table !important}.d-sm-table-row{display:table-row !important}.d-sm-table-cell{display:table-cell !important}.d-sm-flex{display:flex !important}.d-sm-inline-flex{display:inline-flex !important}.d-sm-none{display:none !important}.flex-sm-fill{flex:1 1 auto !important}.flex-sm-row{flex-direction:row !important}.flex-sm-column{flex-direction:column !important}.flex-sm-row-reverse{flex-direction:row-reverse !important}.flex-sm-column-reverse{flex-direction:column-reverse !important}.flex-sm-grow-0{flex-grow:0 !important}.flex-sm-grow-1{flex-grow:1 !important}.flex-sm-shrink-0{flex-shrink:0 !important}.flex-sm-shrink-1{flex-shrink:1 !important}.flex-sm-wrap{flex-wrap:wrap !important}.flex-sm-nowrap{flex-wrap:nowrap !important}.flex-sm-wrap-reverse{flex-wrap:wrap-reverse !important}.justify-content-sm-start{justify-content:flex-start !important}.justify-content-sm-end{justify-content:flex-end !important}.justify-content-sm-center{justify-content:center !important}.justify-content-sm-between{justify-content:space-between !important}.justify-content-sm-around{justify-content:space-around !important}.justify-content-sm-evenly{justify-content:space-evenly !important}.align-items-sm-start{align-items:flex-start !important}.align-items-sm-end{align-items:flex-end !important}.align-items-sm-center{align-items:center !important}.align-items-sm-baseline{align-items:baseline !important}.align-items-sm-stretch{align-items:stretch !important}.align-content-sm-start{align-content:flex-start !important}.align-content-sm-end{align-content:flex-end !important}.align-content-sm-center{align-content:center !important}.align-content-sm-between{align-content:space-between !important}.align-content-sm-around{align-content:space-around !important}.align-content-sm-stretch{align-content:stretch !important}.align-self-sm-auto{align-self:auto !important}.align-self-sm-start{align-self:flex-start !important}.align-self-sm-end{align-self:flex-end !important}.align-self-sm-center{align-self:center !important}.align-self-sm-baseline{align-self:baseline !important}.align-self-sm-stretch{align-self:stretch !important}.order-sm-first{order:-1 !important}.order-sm-0{order:0 !important}.order-sm-1{order:1 !important}.order-sm-2{order:2 !important}.order-sm-3{order:3 !important}.order-sm-4{order:4 !important}.order-sm-5{order:5 !important}.order-sm-last{order:6 !important}.m-sm-0{margin:0 !important}.m-sm-1{margin:.25rem !important}.m-sm-2{margin:.5rem !important}.m-sm-3{margin:1rem !important}.m-sm-4{margin:1.5rem !important}.m-sm-5{margin:3rem !important}.m-sm-auto{margin:auto !important}.mx-sm-0{margin-right:0 !important;margin-left:0 !important}.mx-sm-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-sm-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-sm-3{margin-right:1rem !important;margin-left:1rem !important}.mx-sm-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-sm-5{margin-right:3rem !important;margin-left:3rem !important}.mx-sm-auto{margin-right:auto !important;margin-left:auto !important}.my-sm-0{margin-top:0 !important;margin-bottom:0 !important}.my-sm-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-sm-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-sm-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-sm-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-sm-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-sm-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-sm-0{margin-top:0 !important}.mt-sm-1{margin-top:.25rem !important}.mt-sm-2{margin-top:.5rem !important}.mt-sm-3{margin-top:1rem !important}.mt-sm-4{margin-top:1.5rem !important}.mt-sm-5{margin-top:3rem !important}.mt-sm-auto{margin-top:auto !important}.me-sm-0{margin-right:0 !important}.me-sm-1{margin-right:.25rem !important}.me-sm-2{margin-right:.5rem !important}.me-sm-3{margin-right:1rem !important}.me-sm-4{margin-right:1.5rem !important}.me-sm-5{margin-right:3rem !important}.me-sm-auto{margin-right:auto !important}.mb-sm-0{margin-bottom:0 !important}.mb-sm-1{margin-bottom:.25rem !important}.mb-sm-2{margin-bottom:.5rem !important}.mb-sm-3{margin-bottom:1rem !important}.mb-sm-4{margin-bottom:1.5rem !important}.mb-sm-5{margin-bottom:3rem !important}.mb-sm-auto{margin-bottom:auto !important}.ms-sm-0{margin-left:0 !important}.ms-sm-1{margin-left:.25rem !important}.ms-sm-2{margin-left:.5rem !important}.ms-sm-3{margin-left:1rem !important}.ms-sm-4{margin-left:1.5rem !important}.ms-sm-5{margin-left:3rem !important}.ms-sm-auto{margin-left:auto !important}.p-sm-0{padding:0 !important}.p-sm-1{padding:.25rem !important}.p-sm-2{padding:.5rem !important}.p-sm-3{padding:1rem !important}.p-sm-4{padding:1.5rem !important}.p-sm-5{padding:3rem !important}.px-sm-0{padding-right:0 !important;padding-left:0 !important}.px-sm-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-sm-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-sm-3{padding-right:1rem !important;padding-left:1rem !important}.px-sm-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-sm-5{padding-right:3rem !important;padding-left:3rem !important}.py-sm-0{padding-top:0 !important;padding-bottom:0 !important}.py-sm-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-sm-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-sm-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-sm-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-sm-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-sm-0{padding-top:0 !important}.pt-sm-1{padding-top:.25rem !important}.pt-sm-2{padding-top:.5rem !important}.pt-sm-3{padding-top:1rem !important}.pt-sm-4{padding-top:1.5rem !important}.pt-sm-5{padding-top:3rem !important}.pe-sm-0{padding-right:0 !important}.pe-sm-1{padding-right:.25rem !important}.pe-sm-2{padding-right:.5rem !important}.pe-sm-3{padding-right:1rem !important}.pe-sm-4{padding-right:1.5rem !important}.pe-sm-5{padding-right:3rem !important}.pb-sm-0{padding-bottom:0 !important}.pb-sm-1{padding-bottom:.25rem !important}.pb-sm-2{padding-bottom:.5rem !important}.pb-sm-3{padding-bottom:1rem !important}.pb-sm-4{padding-bottom:1.5rem !important}.pb-sm-5{padding-bottom:3rem !important}.ps-sm-0{padding-left:0 !important}.ps-sm-1{padding-left:.25rem !important}.ps-sm-2{padding-left:.5rem !important}.ps-sm-3{padding-left:1rem !important}.ps-sm-4{padding-left:1.5rem !important}.ps-sm-5{padding-left:3rem !important}}@media (min-width: 768px){.d-md-inline{display:inline !important}.d-md-inline-block{display:inline-block !important}.d-md-block{display:block !important}.d-md-grid{display:grid !important}.d-md-table{display:table !important}.d-md-table-row{display:table-row !important}.d-md-table-cell{display:table-cell !important}.d-md-flex{display:flex !important}.d-md-inline-flex{display:inline-flex !important}.d-md-none{display:none !important}.flex-md-fill{flex:1 1 auto !important}.flex-md-row{flex-direction:row !important}.flex-md-column{flex-direction:column !important}.flex-md-row-reverse{flex-direction:row-reverse !important}.flex-md-column-reverse{flex-direction:column-reverse !important}.flex-md-grow-0{flex-grow:0 !important}.flex-md-grow-1{flex-grow:1 !important}.flex-md-shrink-0{flex-shrink:0 !important}.flex-md-shrink-1{flex-shrink:1 !important}.flex-md-wrap{flex-wrap:wrap !important}.flex-md-nowrap{flex-wrap:nowrap !important}.flex-md-wrap-reverse{flex-wrap:wrap-reverse !important}.justify-content-md-start{justify-content:flex-start !important}.justify-content-md-end{justify-content:flex-end !important}.justify-content-md-center{justify-content:center !important}.justify-content-md-between{justify-content:space-between !important}.justify-content-md-around{justify-content:space-around !important}.justify-content-md-evenly{justify-content:space-evenly !important}.align-items-md-start{align-items:flex-start !important}.align-items-md-end{align-items:flex-end !important}.align-items-md-center{align-items:center !important}.align-items-md-baseline{align-items:baseline !important}.align-items-md-stretch{align-items:stretch !important}.align-content-md-start{align-content:flex-start !important}.align-content-md-end{align-content:flex-end !important}.align-content-md-center{align-content:center !important}.align-content-md-between{align-content:space-between !important}.align-content-md-around{align-content:space-around !important}.align-content-md-stretch{align-content:stretch !important}.align-self-md-auto{align-self:auto !important}.align-self-md-start{align-self:flex-start !important}.align-self-md-end{align-self:flex-end !important}.align-self-md-center{align-self:center !important}.align-self-md-baseline{align-self:baseline !important}.align-self-md-stretch{align-self:stretch !important}.order-md-first{order:-1 !important}.order-md-0{order:0 !important}.order-md-1{order:1 !important}.order-md-2{order:2 !important}.order-md-3{order:3 !important}.order-md-4{order:4 !important}.order-md-5{order:5 !important}.order-md-last{order:6 !important}.m-md-0{margin:0 !important}.m-md-1{margin:.25rem !important}.m-md-2{margin:.5rem !important}.m-md-3{margin:1rem !important}.m-md-4{margin:1.5rem !important}.m-md-5{margin:3rem !important}.m-md-auto{margin:auto !important}.mx-md-0{margin-right:0 !important;margin-left:0 !important}.mx-md-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-md-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-md-3{margin-right:1rem !important;margin-left:1rem !important}.mx-md-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-md-5{margin-right:3rem !important;margin-left:3rem !important}.mx-md-auto{margin-right:auto !important;margin-left:auto !important}.my-md-0{margin-top:0 !important;margin-bottom:0 !important}.my-md-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-md-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-md-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-md-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-md-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-md-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-md-0{margin-top:0 !important}.mt-md-1{margin-top:.25rem !important}.mt-md-2{margin-top:.5rem !important}.mt-md-3{margin-top:1rem !important}.mt-md-4{margin-top:1.5rem !important}.mt-md-5{margin-top:3rem !important}.mt-md-auto{margin-top:auto !important}.me-md-0{margin-right:0 !important}.me-md-1{margin-right:.25rem !important}.me-md-2{margin-right:.5rem !important}.me-md-3{margin-right:1rem !important}.me-md-4{margin-right:1.5rem !important}.me-md-5{margin-right:3rem !important}.me-md-auto{margin-right:auto !important}.mb-md-0{margin-bottom:0 !important}.mb-md-1{margin-bottom:.25rem !important}.mb-md-2{margin-bottom:.5rem !important}.mb-md-3{margin-bottom:1rem !important}.mb-md-4{margin-bottom:1.5rem !important}.mb-md-5{margin-bottom:3rem !important}.mb-md-auto{margin-bottom:auto !important}.ms-md-0{margin-left:0 !important}.ms-md-1{margin-left:.25rem !important}.ms-md-2{margin-left:.5rem !important}.ms-md-3{margin-left:1rem !important}.ms-md-4{margin-left:1.5rem !important}.ms-md-5{margin-left:3rem !important}.ms-md-auto{margin-left:auto !important}.p-md-0{padding:0 !important}.p-md-1{padding:.25rem !important}.p-md-2{padding:.5rem !important}.p-md-3{padding:1rem !important}.p-md-4{padding:1.5rem !important}.p-md-5{padding:3rem !important}.px-md-0{padding-right:0 !important;padding-left:0 !important}.px-md-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-md-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-md-3{padding-right:1rem !important;padding-left:1rem !important}.px-md-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-md-5{padding-right:3rem !important;padding-left:3rem !important}.py-md-0{padding-top:0 !important;padding-bottom:0 !important}.py-md-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-md-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-md-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-md-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-md-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-md-0{padding-top:0 !important}.pt-md-1{padding-top:.25rem !important}.pt-md-2{padding-top:.5rem !important}.pt-md-3{padding-top:1rem !important}.pt-md-4{padding-top:1.5rem !important}.pt-md-5{padding-top:3rem !important}.pe-md-0{padding-right:0 !important}.pe-md-1{padding-right:.25rem !important}.pe-md-2{padding-right:.5rem !important}.pe-md-3{padding-right:1rem !important}.pe-md-4{padding-right:1.5rem !important}.pe-md-5{padding-right:3rem !important}.pb-md-0{padding-bottom:0 !important}.pb-md-1{padding-bottom:.25rem !important}.pb-md-2{padding-bottom:.5rem !important}.pb-md-3{padding-bottom:1rem !important}.pb-md-4{padding-bottom:1.5rem !important}.pb-md-5{padding-bottom:3rem !important}.ps-md-0{padding-left:0 !important}.ps-md-1{padding-left:.25rem !important}.ps-md-2{padding-left:.5rem !important}.ps-md-3{padding-left:1rem !important}.ps-md-4{padding-left:1.5rem !important}.ps-md-5{padding-left:3rem !important}}@media (min-width: 992px){.d-lg-inline{display:inline !important}.d-lg-inline-block{display:inline-block !important}.d-lg-block{display:block !important}.d-lg-grid{display:grid !important}.d-lg-table{display:table !important}.d-lg-table-row{display:table-row !important}.d-lg-table-cell{display:table-cell !important}.d-lg-flex{display:flex !important}.d-lg-inline-flex{display:inline-flex !important}.d-lg-none{display:none !important}.flex-lg-fill{flex:1 1 auto !important}.flex-lg-row{flex-direction:row !important}.flex-lg-column{flex-direction:column !important}.flex-lg-row-reverse{flex-direction:row-reverse !important}.flex-lg-column-reverse{flex-direction:column-reverse !important}.flex-lg-grow-0{flex-grow:0 !important}.flex-lg-grow-1{flex-grow:1 !important}.flex-lg-shrink-0{flex-shrink:0 !important}.flex-lg-shrink-1{flex-shrink:1 !important}.flex-lg-wrap{flex-wrap:wrap !important}.flex-lg-nowrap{flex-wrap:nowrap !important}.flex-lg-wrap-reverse{flex-wrap:wrap-reverse !important}.justify-content-lg-start{justify-content:flex-start !important}.justify-content-lg-end{justify-content:flex-end !important}.justify-content-lg-center{justify-content:center !important}.justify-content-lg-between{justify-content:space-between !important}.justify-content-lg-around{justify-content:space-around !important}.justify-content-lg-evenly{justify-content:space-evenly !important}.align-items-lg-start{align-items:flex-start !important}.align-items-lg-end{align-items:flex-end !important}.align-items-lg-center{align-items:center !important}.align-items-lg-baseline{align-items:baseline !important}.align-items-lg-stretch{align-items:stretch !important}.align-content-lg-start{align-content:flex-start !important}.align-content-lg-end{align-content:flex-end !important}.align-content-lg-center{align-content:center !important}.align-content-lg-between{align-content:space-between !important}.align-content-lg-around{align-content:space-around !important}.align-content-lg-stretch{align-content:stretch !important}.align-self-lg-auto{align-self:auto !important}.align-self-lg-start{align-self:flex-start !important}.align-self-lg-end{align-self:flex-end !important}.align-self-lg-center{align-self:center !important}.align-self-lg-baseline{align-self:baseline !important}.align-self-lg-stretch{align-self:stretch !important}.order-lg-first{order:-1 !important}.order-lg-0{order:0 !important}.order-lg-1{order:1 !important}.order-lg-2{order:2 !important}.order-lg-3{order:3 !important}.order-lg-4{order:4 !important}.order-lg-5{order:5 !important}.order-lg-last{order:6 !important}.m-lg-0{margin:0 !important}.m-lg-1{margin:.25rem !important}.m-lg-2{margin:.5rem !important}.m-lg-3{margin:1rem !important}.m-lg-4{margin:1.5rem !important}.m-lg-5{margin:3rem !important}.m-lg-auto{margin:auto !important}.mx-lg-0{margin-right:0 !important;margin-left:0 !important}.mx-lg-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-lg-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-lg-3{margin-right:1rem !important;margin-left:1rem !important}.mx-lg-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-lg-5{margin-right:3rem !important;margin-left:3rem !important}.mx-lg-auto{margin-right:auto !important;margin-left:auto !important}.my-lg-0{margin-top:0 !important;margin-bottom:0 !important}.my-lg-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-lg-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-lg-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-lg-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-lg-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-lg-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-lg-0{margin-top:0 !important}.mt-lg-1{margin-top:.25rem !important}.mt-lg-2{margin-top:.5rem !important}.mt-lg-3{margin-top:1rem !important}.mt-lg-4{margin-top:1.5rem !important}.mt-lg-5{margin-top:3rem !important}.mt-lg-auto{margin-top:auto !important}.me-lg-0{margin-right:0 !important}.me-lg-1{margin-right:.25rem !important}.me-lg-2{margin-right:.5rem !important}.me-lg-3{margin-right:1rem !important}.me-lg-4{margin-right:1.5rem !important}.me-lg-5{margin-right:3rem !important}.me-lg-auto{margin-right:auto !important}.mb-lg-0{margin-bottom:0 !important}.mb-lg-1{margin-bottom:.25rem !important}.mb-lg-2{margin-bottom:.5rem !important}.mb-lg-3{margin-bottom:1rem !important}.mb-lg-4{margin-bottom:1.5rem !important}.mb-lg-5{margin-bottom:3rem !important}.mb-lg-auto{margin-bottom:auto !important}.ms-lg-0{margin-left:0 !important}.ms-lg-1{margin-left:.25rem !important}.ms-lg-2{margin-left:.5rem !important}.ms-lg-3{margin-left:1rem !important}.ms-lg-4{margin-left:1.5rem !important}.ms-lg-5{margin-left:3rem !important}.ms-lg-auto{margin-left:auto !important}.p-lg-0{padding:0 !important}.p-lg-1{padding:.25rem !important}.p-lg-2{padding:.5rem !important}.p-lg-3{padding:1rem !important}.p-lg-4{padding:1.5rem !important}.p-lg-5{padding:3rem !important}.px-lg-0{padding-right:0 !important;padding-left:0 !important}.px-lg-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-lg-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-lg-3{padding-right:1rem !important;padding-left:1rem !important}.px-lg-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-lg-5{padding-right:3rem !important;padding-left:3rem !important}.py-lg-0{padding-top:0 !important;padding-bottom:0 !important}.py-lg-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-lg-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-lg-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-lg-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-lg-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-lg-0{padding-top:0 !important}.pt-lg-1{padding-top:.25rem !important}.pt-lg-2{padding-top:.5rem !important}.pt-lg-3{padding-top:1rem !important}.pt-lg-4{padding-top:1.5rem !important}.pt-lg-5{padding-top:3rem !important}.pe-lg-0{padding-right:0 !important}.pe-lg-1{padding-right:.25rem !important}.pe-lg-2{padding-right:.5rem !important}.pe-lg-3{padding-right:1rem !important}.pe-lg-4{padding-right:1.5rem !important}.pe-lg-5{padding-right:3rem !important}.pb-lg-0{padding-bottom:0 !important}.pb-lg-1{padding-bottom:.25rem !important}.pb-lg-2{padding-bottom:.5rem !important}.pb-lg-3{padding-bottom:1rem !important}.pb-lg-4{padding-bottom:1.5rem !important}.pb-lg-5{padding-bottom:3rem !important}.ps-lg-0{padding-left:0 !important}.ps-lg-1{padding-left:.25rem !important}.ps-lg-2{padding-left:.5rem !important}.ps-lg-3{padding-left:1rem !important}.ps-lg-4{padding-left:1.5rem !important}.ps-lg-5{padding-left:3rem !important}}@media (min-width: 1200px){.d-xl-inline{display:inline !important}.d-xl-inline-block{display:inline-block !important}.d-xl-block{display:block !important}.d-xl-grid{display:grid !important}.d-xl-table{display:table !important}.d-xl-table-row{display:table-row !important}.d-xl-table-cell{display:table-cell !important}.d-xl-flex{display:flex !important}.d-xl-inline-flex{display:inline-flex !important}.d-xl-none{display:none !important}.flex-xl-fill{flex:1 1 auto !important}.flex-xl-row{flex-direction:row !important}.flex-xl-column{flex-direction:column !important}.flex-xl-row-reverse{flex-direction:row-reverse !important}.flex-xl-column-reverse{flex-direction:column-reverse !important}.flex-xl-grow-0{flex-grow:0 !important}.flex-xl-grow-1{flex-grow:1 !important}.flex-xl-shrink-0{flex-shrink:0 !important}.flex-xl-shrink-1{flex-shrink:1 !important}.flex-xl-wrap{flex-wrap:wrap !important}.flex-xl-nowrap{flex-wrap:nowrap !important}.flex-xl-wrap-reverse{flex-wrap:wrap-reverse !important}.justify-content-xl-start{justify-content:flex-start !important}.justify-content-xl-end{justify-content:flex-end !important}.justify-content-xl-center{justify-content:center !important}.justify-content-xl-between{justify-content:space-between !important}.justify-content-xl-around{justify-content:space-around !important}.justify-content-xl-evenly{justify-content:space-evenly !important}.align-items-xl-start{align-items:flex-start !important}.align-items-xl-end{align-items:flex-end !important}.align-items-xl-center{align-items:center !important}.align-items-xl-baseline{align-items:baseline !important}.align-items-xl-stretch{align-items:stretch !important}.align-content-xl-start{align-content:flex-start !important}.align-content-xl-end{align-content:flex-end !important}.align-content-xl-center{align-content:center !important}.align-content-xl-between{align-content:space-between !important}.align-content-xl-around{align-content:space-around !important}.align-content-xl-stretch{align-content:stretch !important}.align-self-xl-auto{align-self:auto !important}.align-self-xl-start{align-self:flex-start !important}.align-self-xl-end{align-self:flex-end !important}.align-self-xl-center{align-self:center !important}.align-self-xl-baseline{align-self:baseline !important}.align-self-xl-stretch{align-self:stretch !important}.order-xl-first{order:-1 !important}.order-xl-0{order:0 !important}.order-xl-1{order:1 !important}.order-xl-2{order:2 !important}.order-xl-3{order:3 !important}.order-xl-4{order:4 !important}.order-xl-5{order:5 !important}.order-xl-last{order:6 !important}.m-xl-0{margin:0 !important}.m-xl-1{margin:.25rem !important}.m-xl-2{margin:.5rem !important}.m-xl-3{margin:1rem !important}.m-xl-4{margin:1.5rem !important}.m-xl-5{margin:3rem !important}.m-xl-auto{margin:auto !important}.mx-xl-0{margin-right:0 !important;margin-left:0 !important}.mx-xl-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-xl-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-xl-3{margin-right:1rem !important;margin-left:1rem !important}.mx-xl-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-xl-5{margin-right:3rem !important;margin-left:3rem !important}.mx-xl-auto{margin-right:auto !important;margin-left:auto !important}.my-xl-0{margin-top:0 !important;margin-bottom:0 !important}.my-xl-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-xl-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-xl-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-xl-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-xl-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-xl-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-xl-0{margin-top:0 !important}.mt-xl-1{margin-top:.25rem !important}.mt-xl-2{margin-top:.5rem !important}.mt-xl-3{margin-top:1rem !important}.mt-xl-4{margin-top:1.5rem !important}.mt-xl-5{margin-top:3rem !important}.mt-xl-auto{margin-top:auto !important}.me-xl-0{margin-right:0 !important}.me-xl-1{margin-right:.25rem !important}.me-xl-2{margin-right:.5rem !important}.me-xl-3{margin-right:1rem !important}.me-xl-4{margin-right:1.5rem !important}.me-xl-5{margin-right:3rem !important}.me-xl-auto{margin-right:auto !important}.mb-xl-0{margin-bottom:0 !important}.mb-xl-1{margin-bottom:.25rem !important}.mb-xl-2{margin-bottom:.5rem !important}.mb-xl-3{margin-bottom:1rem !important}.mb-xl-4{margin-bottom:1.5rem !important}.mb-xl-5{margin-bottom:3rem !important}.mb-xl-auto{margin-bottom:auto !important}.ms-xl-0{margin-left:0 !important}.ms-xl-1{margin-left:.25rem !important}.ms-xl-2{margin-left:.5rem !important}.ms-xl-3{margin-left:1rem !important}.ms-xl-4{margin-left:1.5rem !important}.ms-xl-5{margin-left:3rem !important}.ms-xl-auto{margin-left:auto !important}.p-xl-0{padding:0 !important}.p-xl-1{padding:.25rem !important}.p-xl-2{padding:.5rem !important}.p-xl-3{padding:1rem !important}.p-xl-4{padding:1.5rem !important}.p-xl-5{padding:3rem !important}.px-xl-0{padding-right:0 !important;padding-left:0 !important}.px-xl-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-xl-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-xl-3{padding-right:1rem !important;padding-left:1rem !important}.px-xl-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-xl-5{padding-right:3rem !important;padding-left:3rem !important}.py-xl-0{padding-top:0 !important;padding-bottom:0 !important}.py-xl-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-xl-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-xl-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-xl-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-xl-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-xl-0{padding-top:0 !important}.pt-xl-1{padding-top:.25rem !important}.pt-xl-2{padding-top:.5rem !important}.pt-xl-3{padding-top:1rem !important}.pt-xl-4{padding-top:1.5rem !important}.pt-xl-5{padding-top:3rem !important}.pe-xl-0{padding-right:0 !important}.pe-xl-1{padding-right:.25rem !important}.pe-xl-2{padding-right:.5rem !important}.pe-xl-3{padding-right:1rem !important}.pe-xl-4{padding-right:1.5rem !important}.pe-xl-5{padding-right:3rem !important}.pb-xl-0{padding-bottom:0 !important}.pb-xl-1{padding-bottom:.25rem !important}.pb-xl-2{padding-bottom:.5rem !important}.pb-xl-3{padding-bottom:1rem !important}.pb-xl-4{padding-bottom:1.5rem !important}.pb-xl-5{padding-bottom:3rem !important}.ps-xl-0{padding-left:0 !important}.ps-xl-1{padding-left:.25rem !important}.ps-xl-2{padding-left:.5rem !important}.ps-xl-3{padding-left:1rem !important}.ps-xl-4{padding-left:1.5rem !important}.ps-xl-5{padding-left:3rem !important}}@media (min-width: 1400px){.d-xxl-inline{display:inline !important}.d-xxl-inline-block{display:inline-block !important}.d-xxl-block{display:block !important}.d-xxl-grid{display:grid !important}.d-xxl-table{display:table !important}.d-xxl-table-row{display:table-row !important}.d-xxl-table-cell{display:table-cell !important}.d-xxl-flex{display:flex !important}.d-xxl-inline-flex{display:inline-flex !important}.d-xxl-none{display:none !important}.flex-xxl-fill{flex:1 1 auto !important}.flex-xxl-row{flex-direction:row !important}.flex-xxl-column{flex-direction:column !important}.flex-xxl-row-reverse{flex-direction:row-reverse !important}.flex-xxl-column-reverse{flex-direction:column-reverse !important}.flex-xxl-grow-0{flex-grow:0 !important}.flex-xxl-grow-1{flex-grow:1 !important}.flex-xxl-shrink-0{flex-shrink:0 !important}.flex-xxl-shrink-1{flex-shrink:1 !important}.flex-xxl-wrap{flex-wrap:wrap !important}.flex-xxl-nowrap{flex-wrap:nowrap !important}.flex-xxl-wrap-reverse{flex-wrap:wrap-reverse !important}.justify-content-xxl-start{justify-content:flex-start !important}.justify-content-xxl-end{justify-content:flex-end !important}.justify-content-xxl-center{justify-content:center !important}.justify-content-xxl-between{justify-content:space-between !important}.justify-content-xxl-around{justify-content:space-around !important}.justify-content-xxl-evenly{justify-content:space-evenly !important}.align-items-xxl-start{align-items:flex-start !important}.align-items-xxl-end{align-items:flex-end !important}.align-items-xxl-center{align-items:center !important}.align-items-xxl-baseline{align-items:baseline !important}.align-items-xxl-stretch{align-items:stretch !important}.align-content-xxl-start{align-content:flex-start !important}.align-content-xxl-end{align-content:flex-end !important}.align-content-xxl-center{align-content:center !important}.align-content-xxl-between{align-content:space-between !important}.align-content-xxl-around{align-content:space-around !important}.align-content-xxl-stretch{align-content:stretch !important}.align-self-xxl-auto{align-self:auto !important}.align-self-xxl-start{align-self:flex-start !important}.align-self-xxl-end{align-self:flex-end !important}.align-self-xxl-center{align-self:center !important}.align-self-xxl-baseline{align-self:baseline !important}.align-self-xxl-stretch{align-self:stretch !important}.order-xxl-first{order:-1 !important}.order-xxl-0{order:0 !important}.order-xxl-1{order:1 !important}.order-xxl-2{order:2 !important}.order-xxl-3{order:3 !important}.order-xxl-4{order:4 !important}.order-xxl-5{order:5 !important}.order-xxl-last{order:6 !important}.m-xxl-0{margin:0 !important}.m-xxl-1{margin:.25rem !important}.m-xxl-2{margin:.5rem !important}.m-xxl-3{margin:1rem !important}.m-xxl-4{margin:1.5rem !important}.m-xxl-5{margin:3rem !important}.m-xxl-auto{margin:auto !important}.mx-xxl-0{margin-right:0 !important;margin-left:0 !important}.mx-xxl-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-xxl-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-xxl-3{margin-right:1rem !important;margin-left:1rem !important}.mx-xxl-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-xxl-5{margin-right:3rem !important;margin-left:3rem !important}.mx-xxl-auto{margin-right:auto !important;margin-left:auto !important}.my-xxl-0{margin-top:0 !important;margin-bottom:0 !important}.my-xxl-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-xxl-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-xxl-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-xxl-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-xxl-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-xxl-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-xxl-0{margin-top:0 !important}.mt-xxl-1{margin-top:.25rem !important}.mt-xxl-2{margin-top:.5rem !important}.mt-xxl-3{margin-top:1rem !important}.mt-xxl-4{margin-top:1.5rem !important}.mt-xxl-5{margin-top:3rem !important}.mt-xxl-auto{margin-top:auto !important}.me-xxl-0{margin-right:0 !important}.me-xxl-1{margin-right:.25rem !important}.me-xxl-2{margin-right:.5rem !important}.me-xxl-3{margin-right:1rem !important}.me-xxl-4{margin-right:1.5rem !important}.me-xxl-5{margin-right:3rem !important}.me-xxl-auto{margin-right:auto !important}.mb-xxl-0{margin-bottom:0 !important}.mb-xxl-1{margin-bottom:.25rem !important}.mb-xxl-2{margin-bottom:.5rem !important}.mb-xxl-3{margin-bottom:1rem !important}.mb-xxl-4{margin-bottom:1.5rem !important}.mb-xxl-5{margin-bottom:3rem !important}.mb-xxl-auto{margin-bottom:auto !important}.ms-xxl-0{margin-left:0 !important}.ms-xxl-1{margin-left:.25rem !important}.ms-xxl-2{margin-left:.5rem !important}.ms-xxl-3{margin-left:1rem !important}.ms-xxl-4{margin-left:1.5rem !important}.ms-xxl-5{margin-left:3rem !important}.ms-xxl-auto{margin-left:auto !important}.p-xxl-0{padding:0 !important}.p-xxl-1{padding:.25rem !important}.p-xxl-2{padding:.5rem !important}.p-xxl-3{padding:1rem !important}.p-xxl-4{padding:1.5rem !important}.p-xxl-5{padding:3rem !important}.px-xxl-0{padding-right:0 !important;padding-left:0 !important}.px-xxl-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-xxl-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-xxl-3{padding-right:1rem !important;padding-left:1rem !important}.px-xxl-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-xxl-5{padding-right:3rem !important;padding-left:3rem !important}.py-xxl-0{padding-top:0 !important;padding-bottom:0 !important}.py-xxl-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-xxl-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-xxl-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-xxl-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-xxl-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-xxl-0{padding-top:0 !important}.pt-xxl-1{padding-top:.25rem !important}.pt-xxl-2{padding-top:.5rem !important}.pt-xxl-3{padding-top:1rem !important}.pt-xxl-4{padding-top:1.5rem !important}.pt-xxl-5{padding-top:3rem !important}.pe-xxl-0{padding-right:0 !important}.pe-xxl-1{padding-right:.25rem !important}.pe-xxl-2{padding-right:.5rem !important}.pe-xxl-3{padding-right:1rem !important}.pe-xxl-4{padding-right:1.5rem !important}.pe-xxl-5{padding-right:3rem !important}.pb-xxl-0{padding-bottom:0 !important}.pb-xxl-1{padding-bottom:.25rem !important}.pb-xxl-2{padding-bottom:.5rem !important}.pb-xxl-3{padding-bottom:1rem !important}.pb-xxl-4{padding-bottom:1.5rem !important}.pb-xxl-5{padding-bottom:3rem !important}.ps-xxl-0{padding-left:0 !important}.ps-xxl-1{padding-left:.25rem !important}.ps-xxl-2{padding-left:.5rem !important}.ps-xxl-3{padding-left:1rem !important}.ps-xxl-4{padding-left:1.5rem !important}.ps-xxl-5{padding-left:3rem !important}}@media print{.d-print-inline{display:inline !important}.d-print-inline-block{display:inline-block !important}.d-print-block{display:block !important}.d-print-grid{display:grid !important}.d-print-table{display:table !important}.d-print-table-row{display:table-row !important}.d-print-table-cell{display:table-cell !important}.d-print-flex{display:flex !important}.d-print-inline-flex{display:inline-flex !important}.d-print-none{display:none !important}}.row{--bs-gutter-x: 1.875rem}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:#fff;border:1px solid #dee2e6;border-radius:.25rem;max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:.875em;color:#6c757d}.list-group{display:flex;flex-direction:column;padding-left:0;margin-bottom:0;border-radius:0}.list-group-numbered{list-style-type:none;counter-reset:section}.list-group-numbered>li::before{content:counters(section, ".") ". ";counter-increment:section}.list-group-item-action{width:100%;color:var(--t42-content-color);text-align:inherit}.list-group-item-action:hover,.list-group-item-action:focus{z-index:1;color:var(--t42-link-hover-color);text-decoration:none;background-color:var(--t42-link-hover-bg)}.list-group-item-action:active{color:var(--t42-link-hover-color);background-color:var(--t42-link-active-bg)}.list-group-item{position:relative;display:block;padding:.75rem 1.25rem;color:inherit;text-decoration:none;background-color:Rgb(var(--t42-bg-mid));border:1px solid rgba(0,0,0,0)}.list-group-item:first-child{border-top-left-radius:inherit;border-top-right-radius:inherit}.list-group-item:last-child{border-bottom-right-radius:inherit;border-bottom-left-radius:inherit}.list-group-item.disabled,.list-group-item:disabled{color:var(--t42-content-color-disabled);pointer-events:none;background-color:rgba(0,0,0,0)}.list-group-item.active{z-index:2;color:var(--t42-link-hover-color);background-color:var(--t42-link-active-bg);border-color:rgba(0,0,0,0)}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{margin-top:-1px;border-top-width:1px}.list-group-horizontal{flex-direction:row}.list-group-horizontal>.list-group-item:first-child{border-bottom-left-radius:0;border-top-right-radius:0}.list-group-horizontal>.list-group-item:last-child{border-top-right-radius:0;border-bottom-left-radius:0}.list-group-horizontal>.list-group-item.active{margin-top:0}.list-group-horizontal>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}@media (min-width: 576px){.list-group-horizontal-sm{flex-direction:row}.list-group-horizontal-sm>.list-group-item:first-child{border-bottom-left-radius:0;border-top-right-radius:0}.list-group-horizontal-sm>.list-group-item:last-child{border-top-right-radius:0;border-bottom-left-radius:0}.list-group-horizontal-sm>.list-group-item.active{margin-top:0}.list-group-horizontal-sm>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-sm>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width: 768px){.list-group-horizontal-md{flex-direction:row}.list-group-horizontal-md>.list-group-item:first-child{border-bottom-left-radius:0;border-top-right-radius:0}.list-group-horizontal-md>.list-group-item:last-child{border-top-right-radius:0;border-bottom-left-radius:0}.list-group-horizontal-md>.list-group-item.active{margin-top:0}.list-group-horizontal-md>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-md>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width: 992px){.list-group-horizontal-lg{flex-direction:row}.list-group-horizontal-lg>.list-group-item:first-child{border-bottom-left-radius:0;border-top-right-radius:0}.list-group-horizontal-lg>.list-group-item:last-child{border-top-right-radius:0;border-bottom-left-radius:0}.list-group-horizontal-lg>.list-group-item.active{margin-top:0}.list-group-horizontal-lg>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-lg>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width: 1200px){.list-group-horizontal-xl{flex-direction:row}.list-group-horizontal-xl>.list-group-item:first-child{border-bottom-left-radius:0;border-top-right-radius:0}.list-group-horizontal-xl>.list-group-item:last-child{border-top-right-radius:0;border-bottom-left-radius:0}.list-group-horizontal-xl>.list-group-item.active{margin-top:0}.list-group-horizontal-xl>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-xl>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width: 1400px){.list-group-horizontal-xxl{flex-direction:row}.list-group-horizontal-xxl>.list-group-item:first-child{border-bottom-left-radius:0;border-top-right-radius:0}.list-group-horizontal-xxl>.list-group-item:last-child{border-top-right-radius:0;border-bottom-left-radius:0}.list-group-horizontal-xxl>.list-group-item.active{margin-top:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}.list-group-flush{border-radius:0}.list-group-flush>.list-group-item{border-width:0 0 1px}.list-group-flush>.list-group-item:last-child{border-bottom-width:0}.list-group-item-primary{color:#004a89;background-color:#cce5fa}.list-group-item-primary.list-group-item-action:hover,.list-group-item-primary.list-group-item-action:focus{color:#004a89;background-color:#b8cee1}.list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#004a89;border-color:#004a89}.list-group-item-secondary{color:#3a3a3a;background-color:#dfdfdf}.list-group-item-secondary.list-group-item-action:hover,.list-group-item-secondary.list-group-item-action:focus{color:#3a3a3a;background-color:#c9c9c9}.list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#3a3a3a;border-color:#3a3a3a}.list-group-item-success{color:#28602b;background-color:#d9ecda}.list-group-item-success.list-group-item-action:hover,.list-group-item-success.list-group-item-action:focus{color:#28602b;background-color:#c3d4c4}.list-group-item-success.list-group-item-action.active{color:#fff;background-color:#28602b;border-color:#28602b}.list-group-item-info{color:#2a5f6f;background-color:#daecf1}.list-group-item-info.list-group-item-action:hover,.list-group-item-info.list-group-item-action:focus{color:#2a5f6f;background-color:#c4d4d9}.list-group-item-info.list-group-item-action.active{color:#fff;background-color:#2a5f6f;border-color:#2a5f6f}.list-group-item-warning{color:#64430f;background-color:#feeed3}.list-group-item-warning.list-group-item-action:hover,.list-group-item-warning.list-group-item-action:focus{color:#64430f;background-color:#e5d6be}.list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#64430f;border-color:#64430f}.list-group-item-danger{color:#993113;background-color:#ffdcd2}.list-group-item-danger.list-group-item-action:hover,.list-group-item-danger.list-group-item-action:focus{color:#993113;background-color:#e6c6bd}.list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#993113;border-color:#993113}.list-group-item-light{color:#3a3a3a;background-color:#dfdfdf}.list-group-item-light.list-group-item-action:hover,.list-group-item-light.list-group-item-action:focus{color:#3a3a3a;background-color:#c9c9c9}.list-group-item-light.list-group-item-action.active{color:#fff;background-color:#3a3a3a;border-color:#3a3a3a}.list-group-item-dark{color:#3a3a3a;background-color:#dfdfdf}.list-group-item-dark.list-group-item-action:hover,.list-group-item-dark.list-group-item-action:focus{color:#3a3a3a;background-color:#c9c9c9}.list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#3a3a3a;border-color:#3a3a3a}.list-unstyled{padding-left:0;list-style:none}.list-group{box-shadow:var(--t42-shadow)}.list-group-item{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:color;margin-bottom:0;border:0;border-bottom:var(--t42-border);backdrop-filter:var(--backdrop-filter)}.list-group-item:last-child{border-bottom:transparent}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{margin-top:0;border-top-width:0}.list-group-item-action{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background,color;transition-duration:0.25s}.list-group-item-action:hover,.list-group-item-action:focus{background-color:var(--t42-list-group-hover-bg-special)}.list-group-item-action.active:hover{background-color:var(--t42-color-opacity-05)}.modal{position:fixed;top:0;left:0;z-index:1055;display:none;width:100%;height:100%;overflow-x:hidden;overflow-y:auto;outline:0}.modal-dialog{position:relative;width:auto;margin:.5rem;pointer-events:none}.modal.fade .modal-dialog{transition:transform 0.3s ease-out;transform:translate(0, -50px)}@media (prefers-reduced-motion: reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{transform:none}.modal.modal-static .modal-dialog{transform:scale(1.02)}.modal-dialog-scrollable{height:calc(100% - 1rem)}.modal-dialog-scrollable .modal-content{max-height:100%;overflow:hidden}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{display:flex;align-items:center;min-height:calc(100% - 1rem)}.modal-content{position:relative;display:flex;flex-direction:column;width:100%;pointer-events:auto;background-color:var(--t42-modal-bg);background-clip:padding-box;border:.0625rem solid var(--t42-color-opacity-10);border-radius:0;outline:0}.modal-backdrop{position:fixed;top:0;left:0;z-index:1050;width:100vw;height:100vh;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:.5}.modal-header{display:flex;flex-shrink:0;align-items:center;justify-content:space-between;padding:1rem 1rem;border-bottom:.0625rem solid rgba(0,0,0,0);border-top-left-radius:0;border-top-right-radius:0}.modal-header .btn-close{padding:.5rem .5rem;margin:-.5rem -.5rem -.5rem auto}.modal-title{margin-bottom:0;line-height:1.5}.modal-body{position:relative;flex:1 1 auto;padding:1rem}.modal-footer{display:flex;flex-wrap:wrap;flex-shrink:0;align-items:center;justify-content:flex-end;padding:.75rem;border-top:.0625rem solid rgba(0,0,0,0);border-bottom-right-radius:0;border-bottom-left-radius:0}.modal-footer>*{margin:.25rem}@media (min-width: 576px){.modal-dialog{max-width:500px;margin:1.75rem auto}.modal-dialog-scrollable{height:calc(100% - 3.5rem)}.modal-dialog-centered{min-height:calc(100% - 3.5rem)}.modal-sm{max-width:300px}}@media (min-width: 992px){.modal-lg,.modal-xl{max-width:800px}}@media (min-width: 1200px){.modal-xl{max-width:1140px}}.modal-fullscreen{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen .modal-header{border-radius:0}.modal-fullscreen .modal-body{overflow-y:auto}.modal-fullscreen .modal-footer{border-radius:0}@media (max-width: 575.98px){.modal-fullscreen-sm-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-sm-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-sm-down .modal-header{border-radius:0}.modal-fullscreen-sm-down .modal-body{overflow-y:auto}.modal-fullscreen-sm-down .modal-footer{border-radius:0}}@media (max-width: 767.98px){.modal-fullscreen-md-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-md-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-md-down .modal-header{border-radius:0}.modal-fullscreen-md-down .modal-body{overflow-y:auto}.modal-fullscreen-md-down .modal-footer{border-radius:0}}@media (max-width: 991.98px){.modal-fullscreen-lg-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-lg-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-lg-down .modal-header{border-radius:0}.modal-fullscreen-lg-down .modal-body{overflow-y:auto}.modal-fullscreen-lg-down .modal-footer{border-radius:0}}@media (max-width: 1199.98px){.modal-fullscreen-xl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xl-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-xl-down .modal-header{border-radius:0}.modal-fullscreen-xl-down .modal-body{overflow-y:auto}.modal-fullscreen-xl-down .modal-footer{border-radius:0}}@media (max-width: 1399.98px){.modal-fullscreen-xxl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xxl-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-xxl-down .modal-header{border-radius:0}.modal-fullscreen-xxl-down .modal-body{overflow-y:auto}.modal-fullscreen-xxl-down .modal-footer{border-radius:0}}.modal{backdrop-filter:var(--backdrop-filter)}.modal .btn-close{font-size:1.25rem;background-size:0.75rem;filter:var(--filter-close)}.modal-content{border-top:0;background:linear-gradient(to bottom right, Rgba(var(--t42-bg-light), 0.75) 0%, Rgba(var(--t42-bg-dark), 0.75) 100%);box-shadow:var(--t42-shadow)}.modal-content::before{display:block;height:0.0625rem;background:linear-gradient(90deg, #007be5 0%, rgba(0,123,229,0.5) 100%);content:""}.modal-body{padding:0 1rem}.modal-body p:last-child{margin-bottom:0}.modal-sm .modal-footer{flex-direction:column}.modal-sm .modal-footer .btn{width:100%}.modal-sm .modal-footer .btn:not(:last-of-type){margin-bottom:0.5rem}.modal-fill-in{background-color:Rgba(var(--t42-bg-light), 0.75)}.modal-fill-in.modal-dialog{display:flex;flex-flow:column nowrap;align-content:center;align-items:center;justify-content:center;width:auto;max-width:100%;height:100%;margin:0 auto}.modal-fill-in .modal-content{display:flex;max-width:600px;border-color:transparent;background:transparent;background-color:transparent;box-shadow:none;backdrop-filter:none;pointer-events:auto}.modal-fill-in .modal-content::before{display:none}.modal-fill-in::before{position:fixed;top:0;right:0;left:0;display:block;height:0.0625rem;background:linear-gradient(90deg, #007be5 0%, rgba(0,123,229,0.5) 100%);content:""}.modal-fill-in.modal-lg .modal-content{max-width:800px}.modal-fill-in.modal-sm .modal-content{max-width:300px}.nav{display:flex;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:.45rem 1rem;color:var(--t42-link-color);text-decoration:none;transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.nav-link{transition:none}}.nav-link:hover,.nav-link:focus{color:var(--t42-link-hover-color)}.nav-link.disabled{color:var(--t42-content-color-disabled);pointer-events:none;cursor:default}.nav-tabs{border-bottom:.0625rem solid var(--t42-color-opacity-10)}.nav-tabs .nav-link{margin-bottom:-.0625rem;background:none;border:.0625rem solid transparent;border-top-left-radius:0;border-top-right-radius:0}.nav-tabs .nav-link:hover,.nav-tabs .nav-link:focus{border-color:transparent transparent var(--t42-color-opacity-10);isolation:isolate}.nav-tabs .nav-link.disabled{color:var(--t42-content-color-disabled);background-color:transparent;border-color:transparent}.nav-tabs .nav-link.active,.nav-tabs .nav-item.show .nav-link{color:var(--t42-link-hover-color);background-color:var(--t42-link-active-bg);border-color:transparent transparent #007be5}.nav-tabs .dropdown-menu{margin-top:-.0625rem;border-top-left-radius:0;border-top-right-radius:0}.nav-pills .nav-link{background:none;border:0;border-radius:.25rem}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:var(--t42-link-hover-color);background-color:var(--t42-link-active-bg)}.nav-fill>.nav-link,.nav-fill .nav-item{flex:1 1 auto;text-align:center}.nav-justified>.nav-link,.nav-justified .nav-item{flex-basis:0;flex-grow:1;text-align:center}.nav-fill .nav-item .nav-link,.nav-justified .nav-item .nav-link{width:100%}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-link{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, border-color, color;margin-right:3px;border:.0625rem solid transparent}.nav-link:not(.disabled):not(:disabled):focus,.nav-link:not(.disabled):not(:disabled):active,.nav-link:not(.disabled):not(:disabled).active,.nav-link:not(.disabled):not(:disabled):hover{border-color:var(--t42-color-opacity-10);color:var(--t42-link-color);background-color:var(--t42-link-hover-bg)}.nav-link.dropdown-toggle::after{right:-0.125rem}.navbar-nav .nav-item{bottom:-1px}.navbar-nav .nav-item .nav-link{border-bottom:0}.navbar-nav .nav-item:not(.disabled):not(:disabled):focus .nav-link,.navbar-nav .nav-item:not(.disabled):not(:disabled):active .nav-link,.navbar-nav .nav-item:not(.disabled):not(:disabled).active .nav-link,.navbar-nav .nav-item:not(.disabled):not(:disabled):hover .nav-link{border-color:var(--t42-color-opacity-10)}.nav.flex-column .nav-link{margin-bottom:3px}.nav-tabs .nav-link{position:relative;display:flex;align-items:center;height:2rem}.nav-tabs .nav-link::before{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:height;position:absolute;bottom:-2px;left:-1px;width:calc(100% + 2px);height:0;background-color:var(--primary);content:""}.nav-tabs .nav-link.active::before{height:3px}.nav-tabs .nav-link.active:hover::before{height:0}.nav-tabs .nav-link .btn-close{width:0.5rem;height:0.5rem}.nav-tabs .nav-item{margin-right:0}.nav-tabs .dropdown.show .dropdown-toggle{border-color:transparent}.nav-tabs.flex-column .nav-link.active:hover::before{width:0}.nav-tabs.flex-column .nav-link::before{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:width;top:-1px;width:0;height:100%;margin-left:0;background-color:var(--primary);content:""}.nav-tabs.flex-column .nav-link.active::before{width:3px;height:calc(100% + 2px)}.nav-pills .nav-link{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;width:100%;padding:0.25rem 1rem;border:1px solid transparent;border-radius:1rem}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{position:relative;border-color:transparent}.nav-pills .nav-item{margin-right:3px}.nav-pills .nav-item:last-child{margin-right:0}.nav-pills .nav-link.active:not(.dropdown-toggle),.nav-pills .show>.nav-link:not(.dropdown-toggle){padding:0.25rem 1.75rem 0.25rem 1rem}.nav-pills .nav-link.active:not(.dropdown-toggle)::before,.nav-pills .show>.nav-link:not(.dropdown-toggle)::before{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:right;position:absolute;top:50%;right:10px;width:8px;height:8px;border-radius:50%;background-color:var(--primary);transform:translateY(-50%);content:""}.nav-pills .nav-link.active:not(.dropdown-toggle):hover::before,.nav-pills .show>.nav-link:not(.dropdown-toggle):hover::before{right:-10px}.nav-justified .nav-item .nav-link::before{right:1px;left:-1px;margin-left:0}.tab-content{padding-top:0.5rem}.nav-action-buttons .nav-link{position:relative;padding:0.45rem 1.5rem 0.45rem 1rem}.nav-action-buttons .icon-cancel::before{display:block;width:1rem;height:1rem;background-color:var(--t42-content-color);content:"";-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M366.854,336.384c6.14398,6.14398,9.216,13.48267,9.216,22.01599s-3.07202,15.87198-9.216,22.01599 c-6.14398,5.46133-13.48267,8.19202-22.01599,8.19199c-8.53333,0.00003-15.87201-2.73065-22.01602-8.19199l-67.584-77.82401 l-67.584,77.82401c-6.144,5.46133-13.48267,8.19202-22.01601,8.19199c-8.53333,0.00003-15.87199-2.73065-22.01599-8.19199 c-5.46133-6.14401-8.192-13.48267-8.192-22.01599s2.73067-15.87201,8.192-22.01599l70.65599-79.87201l-70.65601-80.896 c-5.46132-6.144-8.19199-13.48268-8.19199-22.01601c0-8.53334,2.73067-15.87201,8.19199-22.01601 c6.14401-5.46133,13.48267-8.19199,22.01601-8.192c8.53334,0.00001,15.87201,2.73067,22.01601,8.192l67.584,77.82401 l67.584-77.82401c6.14401-5.46133,13.4827-8.19199,22.01602-8.192c8.53333,0.00001,15.87201,2.73067,22.01599,8.192 c6.14398,6.144,9.216,13.48267,9.216,22.01601c0,8.53333-3.07202,15.87201-9.216,22.01601l-70.65601,80.896L366.854,336.384z%27/%3E%3C/svg%3E")}.navbar{position:relative;display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;padding-top:0;padding-right:.875rem;padding-bottom:0;padding-left:.875rem}.navbar>.container,.navbar>.container-fluid,.navbar>.container-sm,.navbar>.container-md,.navbar>.container-lg,.navbar>.container-xl,.navbar>.container-xxl{display:flex;flex-wrap:inherit;align-items:center;justify-content:space-between}.navbar-brand{padding-top:.075rem;padding-bottom:.075rem;margin-right:1rem;font-size:1.25rem;text-decoration:none;white-space:nowrap}.navbar-nav{display:flex;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-nav .dropdown-menu{position:static}.navbar-text{padding-top:.45rem;padding-bottom:.45rem}.navbar-collapse{flex-basis:100%;flex-grow:1;align-items:center}.navbar-toggler{padding:0 0;font-size:.9375rem;line-height:1;background-color:transparent;border:1px solid transparent;border-radius:0;transition:box-shadow 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.navbar-toggler{transition:none}}.navbar-toggler:hover{text-decoration:none}.navbar-toggler:focus{text-decoration:none;outline:0;box-shadow:0 0 0 0}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;background-repeat:no-repeat;background-position:center;background-size:100%}.navbar-nav-scroll{max-height:var(--bs-scroll-height, 75vh);overflow-y:auto}@media (min-width: 576px){.navbar-expand-sm{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-sm .navbar-nav{flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm .navbar-nav-scroll{overflow:visible}.navbar-expand-sm .navbar-collapse{display:flex !important;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}.navbar-expand-sm .offcanvas-header{display:none}.navbar-expand-sm .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;visibility:visible !important;background-color:transparent;border-right:0;border-left:0;transition:none;transform:none}.navbar-expand-sm .offcanvas-top,.navbar-expand-sm .offcanvas-bottom{height:auto;border-top:0;border-bottom:0}.navbar-expand-sm .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width: 768px){.navbar-expand-md{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-md .navbar-nav{flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-md .navbar-nav-scroll{overflow:visible}.navbar-expand-md .navbar-collapse{display:flex !important;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}.navbar-expand-md .offcanvas-header{display:none}.navbar-expand-md .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;visibility:visible !important;background-color:transparent;border-right:0;border-left:0;transition:none;transform:none}.navbar-expand-md .offcanvas-top,.navbar-expand-md .offcanvas-bottom{height:auto;border-top:0;border-bottom:0}.navbar-expand-md .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width: 992px){.navbar-expand-lg{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-lg .navbar-nav{flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-lg .navbar-nav-scroll{overflow:visible}.navbar-expand-lg .navbar-collapse{display:flex !important;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}.navbar-expand-lg .offcanvas-header{display:none}.navbar-expand-lg .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;visibility:visible !important;background-color:transparent;border-right:0;border-left:0;transition:none;transform:none}.navbar-expand-lg .offcanvas-top,.navbar-expand-lg .offcanvas-bottom{height:auto;border-top:0;border-bottom:0}.navbar-expand-lg .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width: 1200px){.navbar-expand-xl{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-xl .navbar-nav{flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xl .navbar-nav-scroll{overflow:visible}.navbar-expand-xl .navbar-collapse{display:flex !important;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}.navbar-expand-xl .offcanvas-header{display:none}.navbar-expand-xl .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;visibility:visible !important;background-color:transparent;border-right:0;border-left:0;transition:none;transform:none}.navbar-expand-xl .offcanvas-top,.navbar-expand-xl .offcanvas-bottom{height:auto;border-top:0;border-bottom:0}.navbar-expand-xl .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width: 1400px){.navbar-expand-xxl{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-xxl .navbar-nav{flex-direction:row}.navbar-expand-xxl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xxl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xxl .navbar-nav-scroll{overflow:visible}.navbar-expand-xxl .navbar-collapse{display:flex !important;flex-basis:auto}.navbar-expand-xxl .navbar-toggler{display:none}.navbar-expand-xxl .offcanvas-header{display:none}.navbar-expand-xxl .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;visibility:visible !important;background-color:transparent;border-right:0;border-left:0;transition:none;transform:none}.navbar-expand-xxl .offcanvas-top,.navbar-expand-xxl .offcanvas-bottom{height:auto;border-top:0;border-bottom:0}.navbar-expand-xxl .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}.navbar-expand{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand .navbar-nav{flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand .navbar-nav-scroll{overflow:visible}.navbar-expand .navbar-collapse{display:flex !important;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-expand .offcanvas-header{display:none}.navbar-expand .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;visibility:visible !important;background-color:transparent;border-right:0;border-left:0;transition:none;transform:none}.navbar-expand .offcanvas-top,.navbar-expand .offcanvas-bottom{height:auto;border-top:0;border-bottom:0}.navbar-expand .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}.navbar-light .navbar-brand{color:var(--t42-link-color)}.navbar-light .navbar-brand:hover,.navbar-light .navbar-brand:focus{color:var(--t42-link-hover-color)}.navbar-light .navbar-nav .nav-link{color:var(--t42-link-color)}.navbar-light .navbar-nav .nav-link:hover,.navbar-light .navbar-nav .nav-link:focus{color:var(--t42-link-hover-color)}.navbar-light .navbar-nav .nav-link.disabled{color:var(--t42-content-color-disabled)}.navbar-light .navbar-nav .show>.nav-link,.navbar-light .navbar-nav .nav-link.active{color:var(--t42-link-hover-color)}.navbar-light .navbar-toggler{color:var(--t42-link-color);border-color:rgba(0,0,0,0.1)}.navbar-light .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 30 30%27%3e%3cpath stroke=%27var%28--t42-link-color%29%27 stroke-linecap=%27round%27 stroke-miterlimit=%2710%27 stroke-width=%272%27 d=%27M4 7h22M4 15h22M4 23h22%27/%3e%3c/svg%3e")}.navbar-light .navbar-text{color:var(--t42-link-color)}.navbar-light .navbar-text a,.navbar-light .navbar-text a:hover,.navbar-light .navbar-text a:focus{color:var(--t42-link-hover-color)}.navbar-dark .navbar-brand{color:var(--t42-link-color)}.navbar-dark .navbar-brand:hover,.navbar-dark .navbar-brand:focus{color:var(--t42-link-hover-color)}.navbar-dark .navbar-nav .nav-link{color:var(--t42-link-color)}.navbar-dark .navbar-nav .nav-link:hover,.navbar-dark .navbar-nav .nav-link:focus{color:var(--t42-link-hover-color)}.navbar-dark .navbar-nav .nav-link.disabled{color:var(--t42-content-color-disabled)}.navbar-dark .navbar-nav .show>.nav-link,.navbar-dark .navbar-nav .nav-link.active{color:var(--t42-link-hover-color)}.navbar-dark .navbar-toggler{color:var(--t42-link-color);border-color:rgba(255,255,255,0.1)}.navbar-dark .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 30 30%27%3e%3cpath stroke=%27var%28--t42-link-color%29%27 stroke-linecap=%27round%27 stroke-miterlimit=%2710%27 stroke-width=%272%27 d=%27M4 7h22M4 15h22M4 23h22%27/%3e%3c/svg%3e")}.navbar-dark .navbar-text{color:var(--t42-link-color)}.navbar-dark .navbar-text a,.navbar-dark .navbar-text a:hover,.navbar-dark .navbar-text a:focus{color:var(--t42-link-hover-color)}.navbar{border-bottom:var(--t42-border);background-color:Rgba(var(--t42-bg-mid), 0.75);backdrop-filter:var(--backdrop-filter)}.navbar-dark{background-color:Rgba(var(--t42-bg-dark), 0.75)}.navbar-light{background-color:Rgba(var(--t42-bg-light), 0.75)}.navbar .nav-item{position:relative}.navbar .nav-item.show:focus .nav-link:not(.disabled):not(:disabled),.navbar .nav-item.show:active .nav-link:not(.disabled):not(:disabled),.navbar .nav-item.show.active .nav-link:not(.disabled):not(:disabled),.navbar .nav-item:not(.disabled):not(:disabled):focus .nav-link:not(.disabled):not(:disabled),.navbar .nav-item:not(.disabled):not(:disabled):active .nav-link:not(.disabled):not(:disabled),.navbar .nav-item:not(.disabled):not(:disabled).active .nav-link:not(.disabled):not(:disabled){color:var(--t42-link-color);background-color:var(--t42-color-opacity-10)}.navbar .nav-item.show:hover .nav-link:not(.disabled):not(:disabled),.navbar .nav-item:not(.disabled):not(:disabled):hover .nav-link:not(.disabled):not(:disabled){color:var(--t42-link-color);background-color:var(--t42-color-opacity-05)}.navbar .nav-link{padding-right:.875rem;padding-left:.875rem}.navbar .btn-group{height:100%;padding-left:.875rem;border-left:var(--t42-border)}.pagination{display:flex;padding-left:0;list-style:none}.page-link{position:relative;display:block;color:var(--t42-content-color);text-decoration:none;background-color:rgba(0,0,0,0);border:0 solid rgba(0,0,0,0);transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.page-link{transition:none}}.page-link:hover{z-index:2;color:var(--t42-link-hover-color);background-color:var(--t42-link-hover-bg);border-color:#dee2e6}.page-link:focus{z-index:3;color:var(--t42-link-hover-color);background-color:rgba(0,0,0,0);outline:0;box-shadow:0 0 0 0 rgba(0,123,229,0.25)}.page-item:not(:first-child) .page-link{margin-left:0}.page-item.active .page-link{z-index:3;color:var(--white);background-color:var(--primary);border-color:var(--primary)}.page-item.disabled .page-link{color:var(--t42-content-color-disabled);pointer-events:none;background-color:rgba(0,0,0,0);border-color:#dee2e6}.page-link{padding:.125rem .5rem}.page-item:first-child .page-link{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.page-item:last-child .page-link{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.pagination-lg .page-link{padding:.75rem 1.5rem;font-size:.9375rem}.pagination-lg .page-item:first-child .page-link{border-top-left-radius:1rem;border-bottom-left-radius:1rem}.pagination-lg .page-item:last-child .page-link{border-top-right-radius:1rem;border-bottom-right-radius:1rem}.pagination-sm .page-link{padding:.25rem .5rem;font-size:.65625rem}.pagination-sm .page-item:first-child .page-link{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.pagination-sm .page-item:last-child .page-link{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.page-link{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, color;display:flex;align-items:center;justify-content:center;min-width:1.5rem;min-height:1.5rem;border-radius:0.25rem;overflow:hidden}.page-link[aria-label="Next"],.page-link[aria-label="Previous"]{padding:0}.page-link[aria-label="Next"] span{background:var(--t42-select-indicator) center center/1rem 1rem no-repeat;transform:rotate(-90deg)}.page-link[aria-label="Previous"] span{background:var(--t42-select-indicator) center center/1rem 1rem no-repeat;transform:rotate(90deg)}.page-link>span{width:100%;height:100%;min-height:1rem;font-size:0;clip:initial}.pagination-lg .page-link[aria-label="Next"],.pagination-lg .page-link[aria-label="Previous"]{padding:0.75rem 1.5rem}.page-item{margin-right:8px}.page-item:first-child .page-link>span:not(.sr-only)::before,.page-item:last-child .page-link>span:not(.sr-only)::before{top:-0.125rem}.page-item.active .page-link:hover,.page-item:active .page-link:hover{background-color:var(--t42-color-opacity-05)}.page-item.active.disabled .page-link{background-color:var(--t42-color-opacity-10)}.popover{position:absolute;top:0;left:0 /* rtl:ignore */;z-index:1070;display:block;max-width:276px;font-family:"Montserrat","Helvetica Neue",Arial,sans-serif;font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.65625rem;word-wrap:break-word;background-color:Rgba(var(--t42-bg-dark), 0.75);background-clip:padding-box;border:1px solid var(--t42-color-opacity-10);border-radius:0}.popover .popover-arrow{position:absolute;display:block;width:1rem;height:.5rem}.popover .popover-arrow::before,.popover .popover-arrow::after{position:absolute;display:block;content:"";border-color:transparent;border-style:solid}.bs-popover-top>.popover-arrow,.bs-popover-auto[data-popper-placement^="top"]>.popover-arrow{bottom:calc(-.5rem - 1px)}.bs-popover-top>.popover-arrow::before,.bs-popover-auto[data-popper-placement^="top"]>.popover-arrow::before{bottom:0;border-width:.5rem .5rem 0;border-top-color:var(--t42-color-opacity-10)}.bs-popover-top>.popover-arrow::after,.bs-popover-auto[data-popper-placement^="top"]>.popover-arrow::after{bottom:1px;border-width:.5rem .5rem 0;border-top-color:var(--t42-color-opacity-10)}.bs-popover-end>.popover-arrow,.bs-popover-auto[data-popper-placement^="right"]>.popover-arrow{left:calc(-.5rem - 1px);width:.5rem;height:1rem}.bs-popover-end>.popover-arrow::before,.bs-popover-auto[data-popper-placement^="right"]>.popover-arrow::before{left:0;border-width:.5rem .5rem .5rem 0;border-right-color:var(--t42-color-opacity-10)}.bs-popover-end>.popover-arrow::after,.bs-popover-auto[data-popper-placement^="right"]>.popover-arrow::after{left:1px;border-width:.5rem .5rem .5rem 0;border-right-color:var(--t42-color-opacity-10)}.bs-popover-bottom>.popover-arrow,.bs-popover-auto[data-popper-placement^="bottom"]>.popover-arrow{top:calc(-.5rem - 1px)}.bs-popover-bottom>.popover-arrow::before,.bs-popover-auto[data-popper-placement^="bottom"]>.popover-arrow::before{top:0;border-width:0 .5rem .5rem .5rem;border-bottom-color:var(--t42-color-opacity-10)}.bs-popover-bottom>.popover-arrow::after,.bs-popover-auto[data-popper-placement^="bottom"]>.popover-arrow::after{top:1px;border-width:0 .5rem .5rem .5rem;border-bottom-color:var(--t42-color-opacity-10)}.bs-popover-bottom .popover-header::before,.bs-popover-auto[data-popper-placement^="bottom"] .popover-header::before{position:absolute;top:0;left:50%;display:block;width:1rem;margin-left:-.5rem;content:"";border-bottom:1px solid Rgba(var(--t42-bg-mid), 0.75)}.bs-popover-start>.popover-arrow,.bs-popover-auto[data-popper-placement^="left"]>.popover-arrow{right:calc(-.5rem - 1px);width:.5rem;height:1rem}.bs-popover-start>.popover-arrow::before,.bs-popover-auto[data-popper-placement^="left"]>.popover-arrow::before{right:0;border-width:.5rem 0 .5rem .5rem;border-left-color:var(--t42-color-opacity-10)}.bs-popover-start>.popover-arrow::after,.bs-popover-auto[data-popper-placement^="left"]>.popover-arrow::after{right:1px;border-width:.5rem 0 .5rem .5rem;border-left-color:var(--t42-color-opacity-10)}.popover-header{padding:.55rem 1rem;margin-bottom:0;font-size:.75rem;color:var(--t42-link-color);background-color:Rgba(var(--t42-bg-mid), 0.75);border-bottom:1px solid var(--t42-color-opacity-10);border-top-left-radius:0;border-top-right-radius:0}.popover-header:empty{display:none}.popover-body{padding:1rem 1rem;color:var(--t42-content-color)}.popover{backdrop-filter:var(--backdrop-filter)}@keyframes progress-bar-stripes{0%{background-position-x:1.063rem}}.progress{display:flex;height:1.063rem;overflow:hidden;font-size:.6rem;background-color:Rgb(var(--t42-bg-mid));border-radius:0}.progress-bar{display:flex;flex-direction:column;justify-content:center;overflow:hidden;color:#fff;text-align:center;white-space:nowrap;background-color:#007be5;transition:width 0.6s ease}@media (prefers-reduced-motion: reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-size:1.063rem 1.063rem}.progress-bar-animated{animation:1s linear infinite progress-bar-stripes}@media (prefers-reduced-motion: reduce){.progress-bar-animated{animation:none}}.progress{border:var(--t42-border)}.table{--bs-table-bg: rgba(0,0,0,0);--bs-table-accent-bg: rgba(0,0,0,0);--bs-table-striped-color: var(--t42-content-color);--bs-table-striped-bg: rgba(0,0,0,0.05);--bs-table-active-color: var(--t42-content-color);--bs-table-active-bg: rgba(0,0,0,0.1);--bs-table-hover-color: var(--t42-link-color);--bs-table-hover-bg: rgba(0,0,0,0.075);width:100%;margin-bottom:1rem;color:var(--t42-content-color);vertical-align:top;border-color:var(--t42-color-opacity-10)}.table>:not(caption)>*>*{padding:.25rem .313rem;background-color:var(--bs-table-bg);border-bottom-width:1px;box-shadow:inset 0 0 0 9999px var(--bs-table-accent-bg)}.table>tbody{vertical-align:inherit}.table>thead{vertical-align:bottom}.table>:not(:first-child){border-top:2px solid currentColor}.caption-top{caption-side:top}.table-sm>:not(caption)>*>*{padding:.25rem .25rem}.table-bordered>:not(caption)>*{border-width:1px 0}.table-bordered>:not(caption)>*>*{border-width:0 1px}.table-borderless>:not(caption)>*>*{border-bottom-width:0}.table-borderless>:not(:first-child){border-top-width:0}.table-striped>tbody>tr:nth-of-type(odd)>*{--bs-table-accent-bg: var(--bs-table-striped-bg);color:var(--bs-table-striped-color)}.table-active{--bs-table-accent-bg: var(--bs-table-active-bg);color:var(--bs-table-active-color)}.table-hover>tbody>tr:hover>*{--bs-table-accent-bg: var(--bs-table-hover-bg);color:var(--bs-table-hover-color)}.table-primary{--bs-table-bg: #cce5fa;--bs-table-striped-bg: #c2daee;--bs-table-striped-color: #000;--bs-table-active-bg: #b8cee1;--bs-table-active-color: #000;--bs-table-hover-bg: #bdd4e7;--bs-table-hover-color: #000;color:#000;border-color:#b8cee1}.table-secondary{--bs-table-bg: #dfdfdf;--bs-table-striped-bg: #d4d4d4;--bs-table-striped-color: #000;--bs-table-active-bg: #c9c9c9;--bs-table-active-color: #000;--bs-table-hover-bg: #cecece;--bs-table-hover-color: #000;color:#000;border-color:#c9c9c9}.table-success{--bs-table-bg: #d9ecda;--bs-table-striped-bg: #cee0cf;--bs-table-striped-color: #000;--bs-table-active-bg: #c3d4c4;--bs-table-active-color: #000;--bs-table-hover-bg: #c9daca;--bs-table-hover-color: #000;color:#000;border-color:#c3d4c4}.table-info{--bs-table-bg: #daecf1;--bs-table-striped-bg: #cfe0e5;--bs-table-striped-color: #000;--bs-table-active-bg: #c4d4d9;--bs-table-active-color: #000;--bs-table-hover-bg: #cadadf;--bs-table-hover-color: #000;color:#000;border-color:#c4d4d9}.table-warning{--bs-table-bg: #feeed3;--bs-table-striped-bg: #f1e2c8;--bs-table-striped-color: #000;--bs-table-active-bg: #e5d6be;--bs-table-active-color: #000;--bs-table-hover-bg: #ebdcc3;--bs-table-hover-color: #000;color:#000;border-color:#e5d6be}.table-danger{--bs-table-bg: #ffdcd2;--bs-table-striped-bg: #f2d1c8;--bs-table-striped-color: #000;--bs-table-active-bg: #e6c6bd;--bs-table-active-color: #000;--bs-table-hover-bg: #ecccc2;--bs-table-hover-color: #000;color:#000;border-color:#e6c6bd}.table-light{--bs-table-bg: #616161;--bs-table-striped-bg: dimgray;--bs-table-striped-color: #fff;--bs-table-active-bg: #717171;--bs-table-active-color: #fff;--bs-table-hover-bg: #6d6d6d;--bs-table-hover-color: #fff;color:#fff;border-color:#717171}.table-dark{--bs-table-bg: #616161;--bs-table-striped-bg: dimgray;--bs-table-striped-color: #fff;--bs-table-active-bg: #717171;--bs-table-active-color: #fff;--bs-table-hover-bg: #6d6d6d;--bs-table-hover-color: #fff;color:#fff;border-color:#717171}.table-responsive{overflow-x:auto;-webkit-overflow-scrolling:touch}@media (max-width: 575.98px){.table-responsive-sm{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width: 767.98px){.table-responsive-md{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width: 991.98px){.table-responsive-lg{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width: 1199.98px){.table-responsive-xl{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width: 1399.98px){.table-responsive-xxl{overflow-x:auto;-webkit-overflow-scrolling:touch}}.table>:not(:first-child){border-width:0}.table td,.table th{white-space:nowrap;vertical-align:middle}.table a{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border;border-bottom:0.063rem dashed var(--dark);color:var(--t42-content-color)}.table a:hover{border-bottom-color:var(--t42-content-color);border-bottom-style:solid;color:var(--t42-link-color);text-decoration:none}.table thead th{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;border-width:1px 0;color:Hsl(var(--t42-content-color-base), calc(var(--t42-content-color-l) - 20%));font-weight:normal;font-size:83.3%;text-transform:uppercase}.table td{position:relative}.table td .btn,.table td .btn-sm,.table td .btn-group-sm>.btn,.table td .btn-lg,.table td .btn-group-lg>.btn{line-height:1.25rem}.table td .btn-icon i{position:relative;top:0.0625rem}.table tr th:first-child,.table tr td:first-child{padding-left:0.5rem}.table tr th:last-child,.table tr td:last-child{padding-right:0.5rem}.table-hover tbody tr:hover{background-color:var(--t42-table-active-bg)}.table-hover tbody tr:hover a{border-bottom-color:var(--t42-content-color);color:var(--t42-link-color)}.table-responsive{border:0}.tooltip{position:absolute;z-index:1080;display:block;margin:0;font-family:"Montserrat","Helvetica Neue",Arial,sans-serif;font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.65625rem;word-wrap:break-word;opacity:0}.tooltip.show{opacity:1}.tooltip .tooltip-arrow{position:absolute;display:block;width:.8rem;height:.4rem}.tooltip .tooltip-arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-top,.bs-tooltip-auto[data-popper-placement^="top"]{padding:.4rem 0}.bs-tooltip-top .tooltip-arrow,.bs-tooltip-auto[data-popper-placement^="top"] .tooltip-arrow{bottom:0}.bs-tooltip-top .tooltip-arrow::before,.bs-tooltip-auto[data-popper-placement^="top"] .tooltip-arrow::before{top:-1px;border-width:.4rem .4rem 0;border-top-color:var(--t42-tooltip-bg)}.bs-tooltip-end,.bs-tooltip-auto[data-popper-placement^="right"]{padding:0 .4rem}.bs-tooltip-end .tooltip-arrow,.bs-tooltip-auto[data-popper-placement^="right"] .tooltip-arrow{left:0;width:.4rem;height:.8rem}.bs-tooltip-end .tooltip-arrow::before,.bs-tooltip-auto[data-popper-placement^="right"] .tooltip-arrow::before{right:-1px;border-width:.4rem .4rem .4rem 0;border-right-color:var(--t42-tooltip-bg)}.bs-tooltip-bottom,.bs-tooltip-auto[data-popper-placement^="bottom"]{padding:.4rem 0}.bs-tooltip-bottom .tooltip-arrow,.bs-tooltip-auto[data-popper-placement^="bottom"] .tooltip-arrow{top:0}.bs-tooltip-bottom .tooltip-arrow::before,.bs-tooltip-auto[data-popper-placement^="bottom"] .tooltip-arrow::before{bottom:-1px;border-width:0 .4rem .4rem;border-bottom-color:var(--t42-tooltip-bg)}.bs-tooltip-start,.bs-tooltip-auto[data-popper-placement^="left"]{padding:0 .4rem}.bs-tooltip-start .tooltip-arrow,.bs-tooltip-auto[data-popper-placement^="left"] .tooltip-arrow{right:0;width:.4rem;height:.8rem}.bs-tooltip-start .tooltip-arrow::before,.bs-tooltip-auto[data-popper-placement^="left"] .tooltip-arrow::before{left:-1px;border-width:.4rem 0 .4rem .4rem;border-left-color:var(--t42-tooltip-bg)}.tooltip-inner{max-width:200px;padding:.25rem 1rem;color:var(--t42-content-color);text-align:center;background-color:var(--t42-tooltip-bg);border-radius:0}.tooltip .tooltip-inner{border:var(--t42-border);box-shadow:var(--t42-shadow)}.bs-tooltip-top .arrow,.bs-tooltip-auto[data-popper-placement^="top"] .arrow{bottom:1px}.bs-tooltip-top .arrow::before,.bs-tooltip-auto[data-popper-placement^="top"] .arrow::before{border-top-color:var(--t42-color-opacity-10)}.bs-tooltip-bottom .arrow,.bs-tooltip-auto[data-popper-placement^="bottom"] .arrow{top:1px}.bs-tooltip-bottom .arrow::before,.bs-tooltip-auto[data-popper-placement^="bottom"] .arrow::before{border-bottom-color:var(--t42-color-opacity-10)}.bs-tooltip-right .arrow{left:1px}.bs-tooltip-right .arrow::before{border-right-color:var(--t42-color-opacity-10)}.bs-tooltip-left .arrow{right:1px}.bs-tooltip-left .arrow::before{border-left-color:var(--t42-color-opacity-10)}.fade{transition:opacity 0.15s linear}@media (prefers-reduced-motion: reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{height:0;overflow:hidden;transition:height 0.35s ease}@media (prefers-reduced-motion: reduce){.collapsing{transition:none}}.collapsing.collapse-horizontal{width:0;height:auto;transition:width 0.35s ease}@media (prefers-reduced-motion: reduce){.collapsing.collapse-horizontal{transition:none}}mark,.mark{color:var(--white)}pre{background-color:var(--t42-bg-dark)}blockquote,.blockquote{padding:1rem 1rem 0.01rem;border-left:0.25rem solid var(--secondary);background-color:Rgb(var(--t42-bg-dark))}.blockquote-footer{margin-top:-2rem;margin-left:1.25rem;color:var(--t42-content-color-muted);font-size:0.875em}.clearfix::after{display:block;clear:both;content:""}.link-primary{color:#007be5}.link-primary:hover,.link-primary:focus{color:#3395ea}.link-secondary{color:#616161}.link-secondary:hover,.link-secondary:focus{color:#4e4e4e}.link-success{color:#43a047}.link-success:hover,.link-success:focus{color:#69b36c}.link-info{color:#469eb9}.link-info:hover,.link-info:focus{color:#6bb1c7}.link-warning{color:#f9a825}.link-warning:hover,.link-warning:focus{color:#fab951}.link-danger{color:#ff511f}.link-danger:hover,.link-danger:focus{color:#ff744c}.link-light{color:#616161}.link-light:hover,.link-light:focus{color:#4e4e4e}.link-dark{color:#616161}.link-dark:hover,.link-dark:focus{color:#4e4e4e}.ratio{position:relative;width:100%}.ratio::before{display:block;padding-top:var(--bs-aspect-ratio);content:""}.ratio>*{position:absolute;top:0;left:0;width:100%;height:100%}.ratio-1x1{--bs-aspect-ratio: 100%}.ratio-4x3{--bs-aspect-ratio: calc(3 / 4 * 100%)}.ratio-16x9{--bs-aspect-ratio: calc(9 / 16 * 100%)}.ratio-21x9{--bs-aspect-ratio: calc(9 / 21 * 100%)}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}.sticky-top{position:sticky;top:0;z-index:1020}@media (min-width: 576px){.sticky-sm-top{position:sticky;top:0;z-index:1020}}@media (min-width: 768px){.sticky-md-top{position:sticky;top:0;z-index:1020}}@media (min-width: 992px){.sticky-lg-top{position:sticky;top:0;z-index:1020}}@media (min-width: 1200px){.sticky-xl-top{position:sticky;top:0;z-index:1020}}@media (min-width: 1400px){.sticky-xxl-top{position:sticky;top:0;z-index:1020}}.hstack{display:flex;flex-direction:row;align-items:center;align-self:stretch}.vstack{display:flex;flex:1 1 auto;flex-direction:column;align-self:stretch}.visually-hidden,.visually-hidden-focusable:not(:focus):not(:focus-within){position:absolute !important;width:1px !important;height:1px !important;padding:0 !important;margin:-1px !important;overflow:hidden !important;clip:rect(0, 0, 0, 0) !important;white-space:nowrap !important;border:0 !important}.stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.vr{display:inline-block;align-self:stretch;width:1px;min-height:1em;background-color:currentColor;opacity:.25}.align-baseline{vertical-align:baseline !important}.align-top{vertical-align:top !important}.align-middle{vertical-align:middle !important}.align-bottom{vertical-align:bottom !important}.align-text-bottom{vertical-align:text-bottom !important}.align-text-top{vertical-align:text-top !important}.float-start{float:left !important}.float-end{float:right !important}.float-none{float:none !important}.opacity-0{opacity:0 !important}.opacity-25{opacity:.25 !important}.opacity-50{opacity:.5 !important}.opacity-75{opacity:.75 !important}.opacity-100{opacity:1 !important}.overflow-auto{overflow:auto !important}.overflow-hidden{overflow:hidden !important}.overflow-visible{overflow:visible !important}.overflow-scroll{overflow:scroll !important}.d-inline{display:inline !important}.d-inline-block{display:inline-block !important}.d-block{display:block !important}.d-grid{display:grid !important}.d-table{display:table !important}.d-table-row{display:table-row !important}.d-table-cell{display:table-cell !important}.d-flex{display:flex !important}.d-inline-flex{display:inline-flex !important}.d-none{display:none !important}.shadow{box-shadow:0 0.5rem 1rem rgba(0,0,0,0.15) !important}.shadow-sm{box-shadow:0 0.125rem 0.25rem rgba(0,0,0,0.075) !important}.shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,0.175) !important}.shadow-none{box-shadow:none !important}.position-static{position:static !important}.position-relative{position:relative !important}.position-absolute{position:absolute !important}.position-fixed{position:fixed !important}.position-sticky{position:sticky !important}.top-0{top:0 !important}.top-50{top:50% !important}.top-100{top:100% !important}.bottom-0{bottom:0 !important}.bottom-50{bottom:50% !important}.bottom-100{bottom:100% !important}.start-0{left:0 !important}.start-50{left:50% !important}.start-100{left:100% !important}.end-0{right:0 !important}.end-50{right:50% !important}.end-100{right:100% !important}.translate-middle{transform:translate(-50%, -50%) !important}.translate-middle-x{transform:translateX(-50%) !important}.translate-middle-y{transform:translateY(-50%) !important}.border{border:1px solid #dee2e6 !important}.border-0{border:0 !important}.border-top{border-top:1px solid #dee2e6 !important}.border-top-0{border-top:0 !important}.border-end{border-right:1px solid #dee2e6 !important}.border-end-0{border-right:0 !important}.border-bottom{border-bottom:1px solid #dee2e6 !important}.border-bottom-0{border-bottom:0 !important}.border-start{border-left:1px solid #dee2e6 !important}.border-start-0{border-left:0 !important}.border-primary{border-color:#007be5 !important}.border-secondary{border-color:#616161 !important}.border-success{border-color:#43a047 !important}.border-info{border-color:#469eb9 !important}.border-warning{border-color:#f9a825 !important}.border-danger{border-color:#ff511f !important}.border-light{border-color:#616161 !important}.border-dark{border-color:#616161 !important}.border-white{border-color:#fff !important}.border-1{border-width:1px !important}.border-2{border-width:2px !important}.border-3{border-width:3px !important}.border-4{border-width:4px !important}.border-5{border-width:5px !important}.w-25{width:25% !important}.w-50{width:50% !important}.w-75{width:75% !important}.w-100{width:100% !important}.w-auto{width:auto !important}.mw-100{max-width:100% !important}.vw-100{width:100vw !important}.min-vw-100{min-width:100vw !important}.h-25{height:25% !important}.h-50{height:50% !important}.h-75{height:75% !important}.h-100{height:100% !important}.h-auto{height:auto !important}.mh-100{max-height:100% !important}.vh-100{height:100vh !important}.min-vh-100{min-height:100vh !important}.flex-fill{flex:1 1 auto !important}.flex-row{flex-direction:row !important}.flex-column{flex-direction:column !important}.flex-row-reverse{flex-direction:row-reverse !important}.flex-column-reverse{flex-direction:column-reverse !important}.flex-grow-0{flex-grow:0 !important}.flex-grow-1{flex-grow:1 !important}.flex-shrink-0{flex-shrink:0 !important}.flex-shrink-1{flex-shrink:1 !important}.flex-wrap{flex-wrap:wrap !important}.flex-nowrap{flex-wrap:nowrap !important}.flex-wrap-reverse{flex-wrap:wrap-reverse !important}.gap-0{gap:0 !important}.gap-1{gap:.25rem !important}.gap-2{gap:.5rem !important}.gap-3{gap:1rem !important}.gap-4{gap:1.5rem !important}.gap-5{gap:3rem !important}.justify-content-start{justify-content:flex-start !important}.justify-content-end{justify-content:flex-end !important}.justify-content-center{justify-content:center !important}.justify-content-between{justify-content:space-between !important}.justify-content-around{justify-content:space-around !important}.justify-content-evenly{justify-content:space-evenly !important}.align-items-start{align-items:flex-start !important}.align-items-end{align-items:flex-end !important}.align-items-center{align-items:center !important}.align-items-baseline{align-items:baseline !important}.align-items-stretch{align-items:stretch !important}.align-content-start{align-content:flex-start !important}.align-content-end{align-content:flex-end !important}.align-content-center{align-content:center !important}.align-content-between{align-content:space-between !important}.align-content-around{align-content:space-around !important}.align-content-stretch{align-content:stretch !important}.align-self-auto{align-self:auto !important}.align-self-start{align-self:flex-start !important}.align-self-end{align-self:flex-end !important}.align-self-center{align-self:center !important}.align-self-baseline{align-self:baseline !important}.align-self-stretch{align-self:stretch !important}.order-first{order:-1 !important}.order-0{order:0 !important}.order-1{order:1 !important}.order-2{order:2 !important}.order-3{order:3 !important}.order-4{order:4 !important}.order-5{order:5 !important}.order-last{order:6 !important}.m-0{margin:0 !important}.m-1{margin:.25rem !important}.m-2{margin:.5rem !important}.m-3{margin:1rem !important}.m-4{margin:1.5rem !important}.m-5{margin:3rem !important}.m-auto{margin:auto !important}.mx-0{margin-right:0 !important;margin-left:0 !important}.mx-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-3{margin-right:1rem !important;margin-left:1rem !important}.mx-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-5{margin-right:3rem !important;margin-left:3rem !important}.mx-auto{margin-right:auto !important;margin-left:auto !important}.my-0{margin-top:0 !important;margin-bottom:0 !important}.my-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-0{margin-top:0 !important}.mt-1{margin-top:.25rem !important}.mt-2{margin-top:.5rem !important}.mt-3{margin-top:1rem !important}.mt-4{margin-top:1.5rem !important}.mt-5{margin-top:3rem !important}.mt-auto{margin-top:auto !important}.me-0{margin-right:0 !important}.me-1{margin-right:.25rem !important}.me-2{margin-right:.5rem !important}.me-3{margin-right:1rem !important}.me-4{margin-right:1.5rem !important}.me-5{margin-right:3rem !important}.me-auto{margin-right:auto !important}.mb-0{margin-bottom:0 !important}.mb-1{margin-bottom:.25rem !important}.mb-2{margin-bottom:.5rem !important}.mb-3{margin-bottom:1rem !important}.mb-4{margin-bottom:1.5rem !important}.mb-5{margin-bottom:3rem !important}.mb-auto{margin-bottom:auto !important}.ms-0{margin-left:0 !important}.ms-1{margin-left:.25rem !important}.ms-2{margin-left:.5rem !important}.ms-3{margin-left:1rem !important}.ms-4{margin-left:1.5rem !important}.ms-5{margin-left:3rem !important}.ms-auto{margin-left:auto !important}.p-0{padding:0 !important}.p-1{padding:.25rem !important}.p-2{padding:.5rem !important}.p-3{padding:1rem !important}.p-4{padding:1.5rem !important}.p-5{padding:3rem !important}.px-0{padding-right:0 !important;padding-left:0 !important}.px-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-3{padding-right:1rem !important;padding-left:1rem !important}.px-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-5{padding-right:3rem !important;padding-left:3rem !important}.py-0{padding-top:0 !important;padding-bottom:0 !important}.py-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-0{padding-top:0 !important}.pt-1{padding-top:.25rem !important}.pt-2{padding-top:.5rem !important}.pt-3{padding-top:1rem !important}.pt-4{padding-top:1.5rem !important}.pt-5{padding-top:3rem !important}.pe-0{padding-right:0 !important}.pe-1{padding-right:.25rem !important}.pe-2{padding-right:.5rem !important}.pe-3{padding-right:1rem !important}.pe-4{padding-right:1.5rem !important}.pe-5{padding-right:3rem !important}.pb-0{padding-bottom:0 !important}.pb-1{padding-bottom:.25rem !important}.pb-2{padding-bottom:.5rem !important}.pb-3{padding-bottom:1rem !important}.pb-4{padding-bottom:1.5rem !important}.pb-5{padding-bottom:3rem !important}.ps-0{padding-left:0 !important}.ps-1{padding-left:.25rem !important}.ps-2{padding-left:.5rem !important}.ps-3{padding-left:1rem !important}.ps-4{padding-left:1.5rem !important}.ps-5{padding-left:3rem !important}.font-monospace{font-family:var(--bs-font-monospace) !important}.fs-1{font-size:calc(1.26563rem + .1875vw) !important}.fs-2{font-size:1.125rem !important}.fs-3{font-size:.98475rem !important}.fs-4{font-size:.84375rem !important}.fs-5{font-size:.75rem !important}.fs-6{font-size:.7035rem !important}.fst-italic{font-style:italic !important}.fst-normal{font-style:normal !important}.fw-light{font-weight:300 !important}.fw-lighter{font-weight:lighter !important}.fw-normal{font-weight:400 !important}.fw-bold{font-weight:700 !important}.fw-bolder{font-weight:bolder !important}.lh-1{line-height:1 !important}.lh-sm{line-height:1.25 !important}.lh-base{line-height:1.5 !important}.lh-lg{line-height:2 !important}.text-start{text-align:left !important}.text-end{text-align:right !important}.text-center{text-align:center !important}.text-decoration-none{text-decoration:none !important}.text-decoration-underline{text-decoration:underline !important}.text-decoration-line-through{text-decoration:line-through !important}.text-lowercase{text-transform:lowercase !important}.text-uppercase{text-transform:uppercase !important}.text-capitalize{text-transform:capitalize !important}.text-wrap{white-space:normal !important}.text-nowrap{white-space:nowrap !important}.text-break{word-wrap:break-word !important;word-break:break-word !important}.text-primary{--bs-text-opacity: 1;color:rgba(var(--bs-primary-rgb), var(--bs-text-opacity)) !important}.text-secondary{--bs-text-opacity: 1;color:rgba(var(--bs-secondary-rgb), var(--bs-text-opacity)) !important}.text-success{--bs-text-opacity: 1;color:rgba(var(--bs-success-rgb), var(--bs-text-opacity)) !important}.text-info{--bs-text-opacity: 1;color:rgba(var(--bs-info-rgb), var(--bs-text-opacity)) !important}.text-warning{--bs-text-opacity: 1;color:rgba(var(--bs-warning-rgb), var(--bs-text-opacity)) !important}.text-danger{--bs-text-opacity: 1;color:rgba(var(--bs-danger-rgb), var(--bs-text-opacity)) !important}.text-light{--bs-text-opacity: 1;color:rgba(var(--bs-light-rgb), var(--bs-text-opacity)) !important}.text-dark{--bs-text-opacity: 1;color:rgba(var(--bs-dark-rgb), var(--bs-text-opacity)) !important}.text-black{--bs-text-opacity: 1;color:rgba(var(--bs-black-rgb), var(--bs-text-opacity)) !important}.text-white{--bs-text-opacity: 1;color:rgba(var(--bs-white-rgb), var(--bs-text-opacity)) !important}.text-body{--bs-text-opacity: 1;color:rgba(var(--bs-body-color-rgb), var(--bs-text-opacity)) !important}.text-muted{--bs-text-opacity: 1;color:var(--t42-content-color-muted) !important}.text-black-50{--bs-text-opacity: 1;color:rgba(0,0,0,0.5) !important}.text-white-50{--bs-text-opacity: 1;color:rgba(255,255,255,0.5) !important}.text-reset{--bs-text-opacity: 1;color:inherit !important}.text-opacity-25{--bs-text-opacity: .25}.text-opacity-50{--bs-text-opacity: .5}.text-opacity-75{--bs-text-opacity: .75}.text-opacity-100{--bs-text-opacity: 1}.bg-primary{--bs-bg-opacity: 1;background-color:rgba(var(--bs-primary-rgb), var(--bs-bg-opacity)) !important}.bg-secondary{--bs-bg-opacity: 1;background-color:rgba(var(--bs-secondary-rgb), var(--bs-bg-opacity)) !important}.bg-success{--bs-bg-opacity: 1;background-color:rgba(var(--bs-success-rgb), var(--bs-bg-opacity)) !important}.bg-info{--bs-bg-opacity: 1;background-color:rgba(var(--bs-info-rgb), var(--bs-bg-opacity)) !important}.bg-warning{--bs-bg-opacity: 1;background-color:rgba(var(--bs-warning-rgb), var(--bs-bg-opacity)) !important}.bg-danger{--bs-bg-opacity: 1;background-color:rgba(var(--bs-danger-rgb), var(--bs-bg-opacity)) !important}.bg-light{--bs-bg-opacity: 1;background-color:rgba(var(--bs-light-rgb), var(--bs-bg-opacity)) !important}.bg-dark{--bs-bg-opacity: 1;background-color:rgba(var(--bs-dark-rgb), var(--bs-bg-opacity)) !important}.bg-black{--bs-bg-opacity: 1;background-color:rgba(var(--bs-black-rgb), var(--bs-bg-opacity)) !important}.bg-white{--bs-bg-opacity: 1;background-color:rgba(var(--bs-white-rgb), var(--bs-bg-opacity)) !important}.bg-body{--bs-bg-opacity: 1;background-color:rgba(var(--bs-body-bg-rgb), var(--bs-bg-opacity)) !important}.bg-transparent{--bs-bg-opacity: 1;background-color:rgba(0,0,0,0) !important}.bg-opacity-10{--bs-bg-opacity: .1}.bg-opacity-25{--bs-bg-opacity: .25}.bg-opacity-50{--bs-bg-opacity: .5}.bg-opacity-75{--bs-bg-opacity: .75}.bg-opacity-100{--bs-bg-opacity: 1}.bg-gradient{background-image:var(--bs-gradient) !important}.user-select-all{user-select:all !important}.user-select-auto{user-select:auto !important}.user-select-none{user-select:none !important}.pe-none{pointer-events:none !important}.pe-auto{pointer-events:auto !important}.rounded{border-radius:.25rem !important}.rounded-0{border-radius:0 !important}.rounded-1{border-radius:.25rem !important}.rounded-2{border-radius:.25rem !important}.rounded-3{border-radius:1rem !important}.rounded-circle{border-radius:50% !important}.rounded-pill{border-radius:50rem !important}.rounded-top{border-top-left-radius:.25rem !important;border-top-right-radius:.25rem !important}.rounded-end{border-top-right-radius:.25rem !important;border-bottom-right-radius:.25rem !important}.rounded-bottom{border-bottom-right-radius:.25rem !important;border-bottom-left-radius:.25rem !important}.rounded-start{border-bottom-left-radius:.25rem !important;border-top-left-radius:.25rem !important}.visible{visibility:visible !important}.invisible{visibility:hidden !important}@media (min-width: 576px){.float-sm-start{float:left !important}.float-sm-end{float:right !important}.float-sm-none{float:none !important}.d-sm-inline{display:inline !important}.d-sm-inline-block{display:inline-block !important}.d-sm-block{display:block !important}.d-sm-grid{display:grid !important}.d-sm-table{display:table !important}.d-sm-table-row{display:table-row !important}.d-sm-table-cell{display:table-cell !important}.d-sm-flex{display:flex !important}.d-sm-inline-flex{display:inline-flex !important}.d-sm-none{display:none !important}.flex-sm-fill{flex:1 1 auto !important}.flex-sm-row{flex-direction:row !important}.flex-sm-column{flex-direction:column !important}.flex-sm-row-reverse{flex-direction:row-reverse !important}.flex-sm-column-reverse{flex-direction:column-reverse !important}.flex-sm-grow-0{flex-grow:0 !important}.flex-sm-grow-1{flex-grow:1 !important}.flex-sm-shrink-0{flex-shrink:0 !important}.flex-sm-shrink-1{flex-shrink:1 !important}.flex-sm-wrap{flex-wrap:wrap !important}.flex-sm-nowrap{flex-wrap:nowrap !important}.flex-sm-wrap-reverse{flex-wrap:wrap-reverse !important}.gap-sm-0{gap:0 !important}.gap-sm-1{gap:.25rem !important}.gap-sm-2{gap:.5rem !important}.gap-sm-3{gap:1rem !important}.gap-sm-4{gap:1.5rem !important}.gap-sm-5{gap:3rem !important}.justify-content-sm-start{justify-content:flex-start !important}.justify-content-sm-end{justify-content:flex-end !important}.justify-content-sm-center{justify-content:center !important}.justify-content-sm-between{justify-content:space-between !important}.justify-content-sm-around{justify-content:space-around !important}.justify-content-sm-evenly{justify-content:space-evenly !important}.align-items-sm-start{align-items:flex-start !important}.align-items-sm-end{align-items:flex-end !important}.align-items-sm-center{align-items:center !important}.align-items-sm-baseline{align-items:baseline !important}.align-items-sm-stretch{align-items:stretch !important}.align-content-sm-start{align-content:flex-start !important}.align-content-sm-end{align-content:flex-end !important}.align-content-sm-center{align-content:center !important}.align-content-sm-between{align-content:space-between !important}.align-content-sm-around{align-content:space-around !important}.align-content-sm-stretch{align-content:stretch !important}.align-self-sm-auto{align-self:auto !important}.align-self-sm-start{align-self:flex-start !important}.align-self-sm-end{align-self:flex-end !important}.align-self-sm-center{align-self:center !important}.align-self-sm-baseline{align-self:baseline !important}.align-self-sm-stretch{align-self:stretch !important}.order-sm-first{order:-1 !important}.order-sm-0{order:0 !important}.order-sm-1{order:1 !important}.order-sm-2{order:2 !important}.order-sm-3{order:3 !important}.order-sm-4{order:4 !important}.order-sm-5{order:5 !important}.order-sm-last{order:6 !important}.m-sm-0{margin:0 !important}.m-sm-1{margin:.25rem !important}.m-sm-2{margin:.5rem !important}.m-sm-3{margin:1rem !important}.m-sm-4{margin:1.5rem !important}.m-sm-5{margin:3rem !important}.m-sm-auto{margin:auto !important}.mx-sm-0{margin-right:0 !important;margin-left:0 !important}.mx-sm-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-sm-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-sm-3{margin-right:1rem !important;margin-left:1rem !important}.mx-sm-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-sm-5{margin-right:3rem !important;margin-left:3rem !important}.mx-sm-auto{margin-right:auto !important;margin-left:auto !important}.my-sm-0{margin-top:0 !important;margin-bottom:0 !important}.my-sm-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-sm-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-sm-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-sm-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-sm-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-sm-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-sm-0{margin-top:0 !important}.mt-sm-1{margin-top:.25rem !important}.mt-sm-2{margin-top:.5rem !important}.mt-sm-3{margin-top:1rem !important}.mt-sm-4{margin-top:1.5rem !important}.mt-sm-5{margin-top:3rem !important}.mt-sm-auto{margin-top:auto !important}.me-sm-0{margin-right:0 !important}.me-sm-1{margin-right:.25rem !important}.me-sm-2{margin-right:.5rem !important}.me-sm-3{margin-right:1rem !important}.me-sm-4{margin-right:1.5rem !important}.me-sm-5{margin-right:3rem !important}.me-sm-auto{margin-right:auto !important}.mb-sm-0{margin-bottom:0 !important}.mb-sm-1{margin-bottom:.25rem !important}.mb-sm-2{margin-bottom:.5rem !important}.mb-sm-3{margin-bottom:1rem !important}.mb-sm-4{margin-bottom:1.5rem !important}.mb-sm-5{margin-bottom:3rem !important}.mb-sm-auto{margin-bottom:auto !important}.ms-sm-0{margin-left:0 !important}.ms-sm-1{margin-left:.25rem !important}.ms-sm-2{margin-left:.5rem !important}.ms-sm-3{margin-left:1rem !important}.ms-sm-4{margin-left:1.5rem !important}.ms-sm-5{margin-left:3rem !important}.ms-sm-auto{margin-left:auto !important}.p-sm-0{padding:0 !important}.p-sm-1{padding:.25rem !important}.p-sm-2{padding:.5rem !important}.p-sm-3{padding:1rem !important}.p-sm-4{padding:1.5rem !important}.p-sm-5{padding:3rem !important}.px-sm-0{padding-right:0 !important;padding-left:0 !important}.px-sm-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-sm-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-sm-3{padding-right:1rem !important;padding-left:1rem !important}.px-sm-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-sm-5{padding-right:3rem !important;padding-left:3rem !important}.py-sm-0{padding-top:0 !important;padding-bottom:0 !important}.py-sm-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-sm-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-sm-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-sm-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-sm-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-sm-0{padding-top:0 !important}.pt-sm-1{padding-top:.25rem !important}.pt-sm-2{padding-top:.5rem !important}.pt-sm-3{padding-top:1rem !important}.pt-sm-4{padding-top:1.5rem !important}.pt-sm-5{padding-top:3rem !important}.pe-sm-0{padding-right:0 !important}.pe-sm-1{padding-right:.25rem !important}.pe-sm-2{padding-right:.5rem !important}.pe-sm-3{padding-right:1rem !important}.pe-sm-4{padding-right:1.5rem !important}.pe-sm-5{padding-right:3rem !important}.pb-sm-0{padding-bottom:0 !important}.pb-sm-1{padding-bottom:.25rem !important}.pb-sm-2{padding-bottom:.5rem !important}.pb-sm-3{padding-bottom:1rem !important}.pb-sm-4{padding-bottom:1.5rem !important}.pb-sm-5{padding-bottom:3rem !important}.ps-sm-0{padding-left:0 !important}.ps-sm-1{padding-left:.25rem !important}.ps-sm-2{padding-left:.5rem !important}.ps-sm-3{padding-left:1rem !important}.ps-sm-4{padding-left:1.5rem !important}.ps-sm-5{padding-left:3rem !important}.text-sm-start{text-align:left !important}.text-sm-end{text-align:right !important}.text-sm-center{text-align:center !important}}@media (min-width: 768px){.float-md-start{float:left !important}.float-md-end{float:right !important}.float-md-none{float:none !important}.d-md-inline{display:inline !important}.d-md-inline-block{display:inline-block !important}.d-md-block{display:block !important}.d-md-grid{display:grid !important}.d-md-table{display:table !important}.d-md-table-row{display:table-row !important}.d-md-table-cell{display:table-cell !important}.d-md-flex{display:flex !important}.d-md-inline-flex{display:inline-flex !important}.d-md-none{display:none !important}.flex-md-fill{flex:1 1 auto !important}.flex-md-row{flex-direction:row !important}.flex-md-column{flex-direction:column !important}.flex-md-row-reverse{flex-direction:row-reverse !important}.flex-md-column-reverse{flex-direction:column-reverse !important}.flex-md-grow-0{flex-grow:0 !important}.flex-md-grow-1{flex-grow:1 !important}.flex-md-shrink-0{flex-shrink:0 !important}.flex-md-shrink-1{flex-shrink:1 !important}.flex-md-wrap{flex-wrap:wrap !important}.flex-md-nowrap{flex-wrap:nowrap !important}.flex-md-wrap-reverse{flex-wrap:wrap-reverse !important}.gap-md-0{gap:0 !important}.gap-md-1{gap:.25rem !important}.gap-md-2{gap:.5rem !important}.gap-md-3{gap:1rem !important}.gap-md-4{gap:1.5rem !important}.gap-md-5{gap:3rem !important}.justify-content-md-start{justify-content:flex-start !important}.justify-content-md-end{justify-content:flex-end !important}.justify-content-md-center{justify-content:center !important}.justify-content-md-between{justify-content:space-between !important}.justify-content-md-around{justify-content:space-around !important}.justify-content-md-evenly{justify-content:space-evenly !important}.align-items-md-start{align-items:flex-start !important}.align-items-md-end{align-items:flex-end !important}.align-items-md-center{align-items:center !important}.align-items-md-baseline{align-items:baseline !important}.align-items-md-stretch{align-items:stretch !important}.align-content-md-start{align-content:flex-start !important}.align-content-md-end{align-content:flex-end !important}.align-content-md-center{align-content:center !important}.align-content-md-between{align-content:space-between !important}.align-content-md-around{align-content:space-around !important}.align-content-md-stretch{align-content:stretch !important}.align-self-md-auto{align-self:auto !important}.align-self-md-start{align-self:flex-start !important}.align-self-md-end{align-self:flex-end !important}.align-self-md-center{align-self:center !important}.align-self-md-baseline{align-self:baseline !important}.align-self-md-stretch{align-self:stretch !important}.order-md-first{order:-1 !important}.order-md-0{order:0 !important}.order-md-1{order:1 !important}.order-md-2{order:2 !important}.order-md-3{order:3 !important}.order-md-4{order:4 !important}.order-md-5{order:5 !important}.order-md-last{order:6 !important}.m-md-0{margin:0 !important}.m-md-1{margin:.25rem !important}.m-md-2{margin:.5rem !important}.m-md-3{margin:1rem !important}.m-md-4{margin:1.5rem !important}.m-md-5{margin:3rem !important}.m-md-auto{margin:auto !important}.mx-md-0{margin-right:0 !important;margin-left:0 !important}.mx-md-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-md-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-md-3{margin-right:1rem !important;margin-left:1rem !important}.mx-md-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-md-5{margin-right:3rem !important;margin-left:3rem !important}.mx-md-auto{margin-right:auto !important;margin-left:auto !important}.my-md-0{margin-top:0 !important;margin-bottom:0 !important}.my-md-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-md-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-md-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-md-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-md-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-md-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-md-0{margin-top:0 !important}.mt-md-1{margin-top:.25rem !important}.mt-md-2{margin-top:.5rem !important}.mt-md-3{margin-top:1rem !important}.mt-md-4{margin-top:1.5rem !important}.mt-md-5{margin-top:3rem !important}.mt-md-auto{margin-top:auto !important}.me-md-0{margin-right:0 !important}.me-md-1{margin-right:.25rem !important}.me-md-2{margin-right:.5rem !important}.me-md-3{margin-right:1rem !important}.me-md-4{margin-right:1.5rem !important}.me-md-5{margin-right:3rem !important}.me-md-auto{margin-right:auto !important}.mb-md-0{margin-bottom:0 !important}.mb-md-1{margin-bottom:.25rem !important}.mb-md-2{margin-bottom:.5rem !important}.mb-md-3{margin-bottom:1rem !important}.mb-md-4{margin-bottom:1.5rem !important}.mb-md-5{margin-bottom:3rem !important}.mb-md-auto{margin-bottom:auto !important}.ms-md-0{margin-left:0 !important}.ms-md-1{margin-left:.25rem !important}.ms-md-2{margin-left:.5rem !important}.ms-md-3{margin-left:1rem !important}.ms-md-4{margin-left:1.5rem !important}.ms-md-5{margin-left:3rem !important}.ms-md-auto{margin-left:auto !important}.p-md-0{padding:0 !important}.p-md-1{padding:.25rem !important}.p-md-2{padding:.5rem !important}.p-md-3{padding:1rem !important}.p-md-4{padding:1.5rem !important}.p-md-5{padding:3rem !important}.px-md-0{padding-right:0 !important;padding-left:0 !important}.px-md-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-md-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-md-3{padding-right:1rem !important;padding-left:1rem !important}.px-md-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-md-5{padding-right:3rem !important;padding-left:3rem !important}.py-md-0{padding-top:0 !important;padding-bottom:0 !important}.py-md-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-md-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-md-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-md-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-md-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-md-0{padding-top:0 !important}.pt-md-1{padding-top:.25rem !important}.pt-md-2{padding-top:.5rem !important}.pt-md-3{padding-top:1rem !important}.pt-md-4{padding-top:1.5rem !important}.pt-md-5{padding-top:3rem !important}.pe-md-0{padding-right:0 !important}.pe-md-1{padding-right:.25rem !important}.pe-md-2{padding-right:.5rem !important}.pe-md-3{padding-right:1rem !important}.pe-md-4{padding-right:1.5rem !important}.pe-md-5{padding-right:3rem !important}.pb-md-0{padding-bottom:0 !important}.pb-md-1{padding-bottom:.25rem !important}.pb-md-2{padding-bottom:.5rem !important}.pb-md-3{padding-bottom:1rem !important}.pb-md-4{padding-bottom:1.5rem !important}.pb-md-5{padding-bottom:3rem !important}.ps-md-0{padding-left:0 !important}.ps-md-1{padding-left:.25rem !important}.ps-md-2{padding-left:.5rem !important}.ps-md-3{padding-left:1rem !important}.ps-md-4{padding-left:1.5rem !important}.ps-md-5{padding-left:3rem !important}.text-md-start{text-align:left !important}.text-md-end{text-align:right !important}.text-md-center{text-align:center !important}}@media (min-width: 992px){.float-lg-start{float:left !important}.float-lg-end{float:right !important}.float-lg-none{float:none !important}.d-lg-inline{display:inline !important}.d-lg-inline-block{display:inline-block !important}.d-lg-block{display:block !important}.d-lg-grid{display:grid !important}.d-lg-table{display:table !important}.d-lg-table-row{display:table-row !important}.d-lg-table-cell{display:table-cell !important}.d-lg-flex{display:flex !important}.d-lg-inline-flex{display:inline-flex !important}.d-lg-none{display:none !important}.flex-lg-fill{flex:1 1 auto !important}.flex-lg-row{flex-direction:row !important}.flex-lg-column{flex-direction:column !important}.flex-lg-row-reverse{flex-direction:row-reverse !important}.flex-lg-column-reverse{flex-direction:column-reverse !important}.flex-lg-grow-0{flex-grow:0 !important}.flex-lg-grow-1{flex-grow:1 !important}.flex-lg-shrink-0{flex-shrink:0 !important}.flex-lg-shrink-1{flex-shrink:1 !important}.flex-lg-wrap{flex-wrap:wrap !important}.flex-lg-nowrap{flex-wrap:nowrap !important}.flex-lg-wrap-reverse{flex-wrap:wrap-reverse !important}.gap-lg-0{gap:0 !important}.gap-lg-1{gap:.25rem !important}.gap-lg-2{gap:.5rem !important}.gap-lg-3{gap:1rem !important}.gap-lg-4{gap:1.5rem !important}.gap-lg-5{gap:3rem !important}.justify-content-lg-start{justify-content:flex-start !important}.justify-content-lg-end{justify-content:flex-end !important}.justify-content-lg-center{justify-content:center !important}.justify-content-lg-between{justify-content:space-between !important}.justify-content-lg-around{justify-content:space-around !important}.justify-content-lg-evenly{justify-content:space-evenly !important}.align-items-lg-start{align-items:flex-start !important}.align-items-lg-end{align-items:flex-end !important}.align-items-lg-center{align-items:center !important}.align-items-lg-baseline{align-items:baseline !important}.align-items-lg-stretch{align-items:stretch !important}.align-content-lg-start{align-content:flex-start !important}.align-content-lg-end{align-content:flex-end !important}.align-content-lg-center{align-content:center !important}.align-content-lg-between{align-content:space-between !important}.align-content-lg-around{align-content:space-around !important}.align-content-lg-stretch{align-content:stretch !important}.align-self-lg-auto{align-self:auto !important}.align-self-lg-start{align-self:flex-start !important}.align-self-lg-end{align-self:flex-end !important}.align-self-lg-center{align-self:center !important}.align-self-lg-baseline{align-self:baseline !important}.align-self-lg-stretch{align-self:stretch !important}.order-lg-first{order:-1 !important}.order-lg-0{order:0 !important}.order-lg-1{order:1 !important}.order-lg-2{order:2 !important}.order-lg-3{order:3 !important}.order-lg-4{order:4 !important}.order-lg-5{order:5 !important}.order-lg-last{order:6 !important}.m-lg-0{margin:0 !important}.m-lg-1{margin:.25rem !important}.m-lg-2{margin:.5rem !important}.m-lg-3{margin:1rem !important}.m-lg-4{margin:1.5rem !important}.m-lg-5{margin:3rem !important}.m-lg-auto{margin:auto !important}.mx-lg-0{margin-right:0 !important;margin-left:0 !important}.mx-lg-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-lg-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-lg-3{margin-right:1rem !important;margin-left:1rem !important}.mx-lg-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-lg-5{margin-right:3rem !important;margin-left:3rem !important}.mx-lg-auto{margin-right:auto !important;margin-left:auto !important}.my-lg-0{margin-top:0 !important;margin-bottom:0 !important}.my-lg-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-lg-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-lg-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-lg-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-lg-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-lg-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-lg-0{margin-top:0 !important}.mt-lg-1{margin-top:.25rem !important}.mt-lg-2{margin-top:.5rem !important}.mt-lg-3{margin-top:1rem !important}.mt-lg-4{margin-top:1.5rem !important}.mt-lg-5{margin-top:3rem !important}.mt-lg-auto{margin-top:auto !important}.me-lg-0{margin-right:0 !important}.me-lg-1{margin-right:.25rem !important}.me-lg-2{margin-right:.5rem !important}.me-lg-3{margin-right:1rem !important}.me-lg-4{margin-right:1.5rem !important}.me-lg-5{margin-right:3rem !important}.me-lg-auto{margin-right:auto !important}.mb-lg-0{margin-bottom:0 !important}.mb-lg-1{margin-bottom:.25rem !important}.mb-lg-2{margin-bottom:.5rem !important}.mb-lg-3{margin-bottom:1rem !important}.mb-lg-4{margin-bottom:1.5rem !important}.mb-lg-5{margin-bottom:3rem !important}.mb-lg-auto{margin-bottom:auto !important}.ms-lg-0{margin-left:0 !important}.ms-lg-1{margin-left:.25rem !important}.ms-lg-2{margin-left:.5rem !important}.ms-lg-3{margin-left:1rem !important}.ms-lg-4{margin-left:1.5rem !important}.ms-lg-5{margin-left:3rem !important}.ms-lg-auto{margin-left:auto !important}.p-lg-0{padding:0 !important}.p-lg-1{padding:.25rem !important}.p-lg-2{padding:.5rem !important}.p-lg-3{padding:1rem !important}.p-lg-4{padding:1.5rem !important}.p-lg-5{padding:3rem !important}.px-lg-0{padding-right:0 !important;padding-left:0 !important}.px-lg-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-lg-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-lg-3{padding-right:1rem !important;padding-left:1rem !important}.px-lg-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-lg-5{padding-right:3rem !important;padding-left:3rem !important}.py-lg-0{padding-top:0 !important;padding-bottom:0 !important}.py-lg-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-lg-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-lg-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-lg-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-lg-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-lg-0{padding-top:0 !important}.pt-lg-1{padding-top:.25rem !important}.pt-lg-2{padding-top:.5rem !important}.pt-lg-3{padding-top:1rem !important}.pt-lg-4{padding-top:1.5rem !important}.pt-lg-5{padding-top:3rem !important}.pe-lg-0{padding-right:0 !important}.pe-lg-1{padding-right:.25rem !important}.pe-lg-2{padding-right:.5rem !important}.pe-lg-3{padding-right:1rem !important}.pe-lg-4{padding-right:1.5rem !important}.pe-lg-5{padding-right:3rem !important}.pb-lg-0{padding-bottom:0 !important}.pb-lg-1{padding-bottom:.25rem !important}.pb-lg-2{padding-bottom:.5rem !important}.pb-lg-3{padding-bottom:1rem !important}.pb-lg-4{padding-bottom:1.5rem !important}.pb-lg-5{padding-bottom:3rem !important}.ps-lg-0{padding-left:0 !important}.ps-lg-1{padding-left:.25rem !important}.ps-lg-2{padding-left:.5rem !important}.ps-lg-3{padding-left:1rem !important}.ps-lg-4{padding-left:1.5rem !important}.ps-lg-5{padding-left:3rem !important}.text-lg-start{text-align:left !important}.text-lg-end{text-align:right !important}.text-lg-center{text-align:center !important}}@media (min-width: 1200px){.float-xl-start{float:left !important}.float-xl-end{float:right !important}.float-xl-none{float:none !important}.d-xl-inline{display:inline !important}.d-xl-inline-block{display:inline-block !important}.d-xl-block{display:block !important}.d-xl-grid{display:grid !important}.d-xl-table{display:table !important}.d-xl-table-row{display:table-row !important}.d-xl-table-cell{display:table-cell !important}.d-xl-flex{display:flex !important}.d-xl-inline-flex{display:inline-flex !important}.d-xl-none{display:none !important}.flex-xl-fill{flex:1 1 auto !important}.flex-xl-row{flex-direction:row !important}.flex-xl-column{flex-direction:column !important}.flex-xl-row-reverse{flex-direction:row-reverse !important}.flex-xl-column-reverse{flex-direction:column-reverse !important}.flex-xl-grow-0{flex-grow:0 !important}.flex-xl-grow-1{flex-grow:1 !important}.flex-xl-shrink-0{flex-shrink:0 !important}.flex-xl-shrink-1{flex-shrink:1 !important}.flex-xl-wrap{flex-wrap:wrap !important}.flex-xl-nowrap{flex-wrap:nowrap !important}.flex-xl-wrap-reverse{flex-wrap:wrap-reverse !important}.gap-xl-0{gap:0 !important}.gap-xl-1{gap:.25rem !important}.gap-xl-2{gap:.5rem !important}.gap-xl-3{gap:1rem !important}.gap-xl-4{gap:1.5rem !important}.gap-xl-5{gap:3rem !important}.justify-content-xl-start{justify-content:flex-start !important}.justify-content-xl-end{justify-content:flex-end !important}.justify-content-xl-center{justify-content:center !important}.justify-content-xl-between{justify-content:space-between !important}.justify-content-xl-around{justify-content:space-around !important}.justify-content-xl-evenly{justify-content:space-evenly !important}.align-items-xl-start{align-items:flex-start !important}.align-items-xl-end{align-items:flex-end !important}.align-items-xl-center{align-items:center !important}.align-items-xl-baseline{align-items:baseline !important}.align-items-xl-stretch{align-items:stretch !important}.align-content-xl-start{align-content:flex-start !important}.align-content-xl-end{align-content:flex-end !important}.align-content-xl-center{align-content:center !important}.align-content-xl-between{align-content:space-between !important}.align-content-xl-around{align-content:space-around !important}.align-content-xl-stretch{align-content:stretch !important}.align-self-xl-auto{align-self:auto !important}.align-self-xl-start{align-self:flex-start !important}.align-self-xl-end{align-self:flex-end !important}.align-self-xl-center{align-self:center !important}.align-self-xl-baseline{align-self:baseline !important}.align-self-xl-stretch{align-self:stretch !important}.order-xl-first{order:-1 !important}.order-xl-0{order:0 !important}.order-xl-1{order:1 !important}.order-xl-2{order:2 !important}.order-xl-3{order:3 !important}.order-xl-4{order:4 !important}.order-xl-5{order:5 !important}.order-xl-last{order:6 !important}.m-xl-0{margin:0 !important}.m-xl-1{margin:.25rem !important}.m-xl-2{margin:.5rem !important}.m-xl-3{margin:1rem !important}.m-xl-4{margin:1.5rem !important}.m-xl-5{margin:3rem !important}.m-xl-auto{margin:auto !important}.mx-xl-0{margin-right:0 !important;margin-left:0 !important}.mx-xl-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-xl-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-xl-3{margin-right:1rem !important;margin-left:1rem !important}.mx-xl-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-xl-5{margin-right:3rem !important;margin-left:3rem !important}.mx-xl-auto{margin-right:auto !important;margin-left:auto !important}.my-xl-0{margin-top:0 !important;margin-bottom:0 !important}.my-xl-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-xl-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-xl-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-xl-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-xl-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-xl-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-xl-0{margin-top:0 !important}.mt-xl-1{margin-top:.25rem !important}.mt-xl-2{margin-top:.5rem !important}.mt-xl-3{margin-top:1rem !important}.mt-xl-4{margin-top:1.5rem !important}.mt-xl-5{margin-top:3rem !important}.mt-xl-auto{margin-top:auto !important}.me-xl-0{margin-right:0 !important}.me-xl-1{margin-right:.25rem !important}.me-xl-2{margin-right:.5rem !important}.me-xl-3{margin-right:1rem !important}.me-xl-4{margin-right:1.5rem !important}.me-xl-5{margin-right:3rem !important}.me-xl-auto{margin-right:auto !important}.mb-xl-0{margin-bottom:0 !important}.mb-xl-1{margin-bottom:.25rem !important}.mb-xl-2{margin-bottom:.5rem !important}.mb-xl-3{margin-bottom:1rem !important}.mb-xl-4{margin-bottom:1.5rem !important}.mb-xl-5{margin-bottom:3rem !important}.mb-xl-auto{margin-bottom:auto !important}.ms-xl-0{margin-left:0 !important}.ms-xl-1{margin-left:.25rem !important}.ms-xl-2{margin-left:.5rem !important}.ms-xl-3{margin-left:1rem !important}.ms-xl-4{margin-left:1.5rem !important}.ms-xl-5{margin-left:3rem !important}.ms-xl-auto{margin-left:auto !important}.p-xl-0{padding:0 !important}.p-xl-1{padding:.25rem !important}.p-xl-2{padding:.5rem !important}.p-xl-3{padding:1rem !important}.p-xl-4{padding:1.5rem !important}.p-xl-5{padding:3rem !important}.px-xl-0{padding-right:0 !important;padding-left:0 !important}.px-xl-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-xl-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-xl-3{padding-right:1rem !important;padding-left:1rem !important}.px-xl-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-xl-5{padding-right:3rem !important;padding-left:3rem !important}.py-xl-0{padding-top:0 !important;padding-bottom:0 !important}.py-xl-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-xl-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-xl-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-xl-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-xl-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-xl-0{padding-top:0 !important}.pt-xl-1{padding-top:.25rem !important}.pt-xl-2{padding-top:.5rem !important}.pt-xl-3{padding-top:1rem !important}.pt-xl-4{padding-top:1.5rem !important}.pt-xl-5{padding-top:3rem !important}.pe-xl-0{padding-right:0 !important}.pe-xl-1{padding-right:.25rem !important}.pe-xl-2{padding-right:.5rem !important}.pe-xl-3{padding-right:1rem !important}.pe-xl-4{padding-right:1.5rem !important}.pe-xl-5{padding-right:3rem !important}.pb-xl-0{padding-bottom:0 !important}.pb-xl-1{padding-bottom:.25rem !important}.pb-xl-2{padding-bottom:.5rem !important}.pb-xl-3{padding-bottom:1rem !important}.pb-xl-4{padding-bottom:1.5rem !important}.pb-xl-5{padding-bottom:3rem !important}.ps-xl-0{padding-left:0 !important}.ps-xl-1{padding-left:.25rem !important}.ps-xl-2{padding-left:.5rem !important}.ps-xl-3{padding-left:1rem !important}.ps-xl-4{padding-left:1.5rem !important}.ps-xl-5{padding-left:3rem !important}.text-xl-start{text-align:left !important}.text-xl-end{text-align:right !important}.text-xl-center{text-align:center !important}}@media (min-width: 1400px){.float-xxl-start{float:left !important}.float-xxl-end{float:right !important}.float-xxl-none{float:none !important}.d-xxl-inline{display:inline !important}.d-xxl-inline-block{display:inline-block !important}.d-xxl-block{display:block !important}.d-xxl-grid{display:grid !important}.d-xxl-table{display:table !important}.d-xxl-table-row{display:table-row !important}.d-xxl-table-cell{display:table-cell !important}.d-xxl-flex{display:flex !important}.d-xxl-inline-flex{display:inline-flex !important}.d-xxl-none{display:none !important}.flex-xxl-fill{flex:1 1 auto !important}.flex-xxl-row{flex-direction:row !important}.flex-xxl-column{flex-direction:column !important}.flex-xxl-row-reverse{flex-direction:row-reverse !important}.flex-xxl-column-reverse{flex-direction:column-reverse !important}.flex-xxl-grow-0{flex-grow:0 !important}.flex-xxl-grow-1{flex-grow:1 !important}.flex-xxl-shrink-0{flex-shrink:0 !important}.flex-xxl-shrink-1{flex-shrink:1 !important}.flex-xxl-wrap{flex-wrap:wrap !important}.flex-xxl-nowrap{flex-wrap:nowrap !important}.flex-xxl-wrap-reverse{flex-wrap:wrap-reverse !important}.gap-xxl-0{gap:0 !important}.gap-xxl-1{gap:.25rem !important}.gap-xxl-2{gap:.5rem !important}.gap-xxl-3{gap:1rem !important}.gap-xxl-4{gap:1.5rem !important}.gap-xxl-5{gap:3rem !important}.justify-content-xxl-start{justify-content:flex-start !important}.justify-content-xxl-end{justify-content:flex-end !important}.justify-content-xxl-center{justify-content:center !important}.justify-content-xxl-between{justify-content:space-between !important}.justify-content-xxl-around{justify-content:space-around !important}.justify-content-xxl-evenly{justify-content:space-evenly !important}.align-items-xxl-start{align-items:flex-start !important}.align-items-xxl-end{align-items:flex-end !important}.align-items-xxl-center{align-items:center !important}.align-items-xxl-baseline{align-items:baseline !important}.align-items-xxl-stretch{align-items:stretch !important}.align-content-xxl-start{align-content:flex-start !important}.align-content-xxl-end{align-content:flex-end !important}.align-content-xxl-center{align-content:center !important}.align-content-xxl-between{align-content:space-between !important}.align-content-xxl-around{align-content:space-around !important}.align-content-xxl-stretch{align-content:stretch !important}.align-self-xxl-auto{align-self:auto !important}.align-self-xxl-start{align-self:flex-start !important}.align-self-xxl-end{align-self:flex-end !important}.align-self-xxl-center{align-self:center !important}.align-self-xxl-baseline{align-self:baseline !important}.align-self-xxl-stretch{align-self:stretch !important}.order-xxl-first{order:-1 !important}.order-xxl-0{order:0 !important}.order-xxl-1{order:1 !important}.order-xxl-2{order:2 !important}.order-xxl-3{order:3 !important}.order-xxl-4{order:4 !important}.order-xxl-5{order:5 !important}.order-xxl-last{order:6 !important}.m-xxl-0{margin:0 !important}.m-xxl-1{margin:.25rem !important}.m-xxl-2{margin:.5rem !important}.m-xxl-3{margin:1rem !important}.m-xxl-4{margin:1.5rem !important}.m-xxl-5{margin:3rem !important}.m-xxl-auto{margin:auto !important}.mx-xxl-0{margin-right:0 !important;margin-left:0 !important}.mx-xxl-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-xxl-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-xxl-3{margin-right:1rem !important;margin-left:1rem !important}.mx-xxl-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-xxl-5{margin-right:3rem !important;margin-left:3rem !important}.mx-xxl-auto{margin-right:auto !important;margin-left:auto !important}.my-xxl-0{margin-top:0 !important;margin-bottom:0 !important}.my-xxl-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-xxl-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-xxl-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-xxl-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-xxl-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-xxl-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-xxl-0{margin-top:0 !important}.mt-xxl-1{margin-top:.25rem !important}.mt-xxl-2{margin-top:.5rem !important}.mt-xxl-3{margin-top:1rem !important}.mt-xxl-4{margin-top:1.5rem !important}.mt-xxl-5{margin-top:3rem !important}.mt-xxl-auto{margin-top:auto !important}.me-xxl-0{margin-right:0 !important}.me-xxl-1{margin-right:.25rem !important}.me-xxl-2{margin-right:.5rem !important}.me-xxl-3{margin-right:1rem !important}.me-xxl-4{margin-right:1.5rem !important}.me-xxl-5{margin-right:3rem !important}.me-xxl-auto{margin-right:auto !important}.mb-xxl-0{margin-bottom:0 !important}.mb-xxl-1{margin-bottom:.25rem !important}.mb-xxl-2{margin-bottom:.5rem !important}.mb-xxl-3{margin-bottom:1rem !important}.mb-xxl-4{margin-bottom:1.5rem !important}.mb-xxl-5{margin-bottom:3rem !important}.mb-xxl-auto{margin-bottom:auto !important}.ms-xxl-0{margin-left:0 !important}.ms-xxl-1{margin-left:.25rem !important}.ms-xxl-2{margin-left:.5rem !important}.ms-xxl-3{margin-left:1rem !important}.ms-xxl-4{margin-left:1.5rem !important}.ms-xxl-5{margin-left:3rem !important}.ms-xxl-auto{margin-left:auto !important}.p-xxl-0{padding:0 !important}.p-xxl-1{padding:.25rem !important}.p-xxl-2{padding:.5rem !important}.p-xxl-3{padding:1rem !important}.p-xxl-4{padding:1.5rem !important}.p-xxl-5{padding:3rem !important}.px-xxl-0{padding-right:0 !important;padding-left:0 !important}.px-xxl-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-xxl-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-xxl-3{padding-right:1rem !important;padding-left:1rem !important}.px-xxl-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-xxl-5{padding-right:3rem !important;padding-left:3rem !important}.py-xxl-0{padding-top:0 !important;padding-bottom:0 !important}.py-xxl-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-xxl-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-xxl-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-xxl-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-xxl-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-xxl-0{padding-top:0 !important}.pt-xxl-1{padding-top:.25rem !important}.pt-xxl-2{padding-top:.5rem !important}.pt-xxl-3{padding-top:1rem !important}.pt-xxl-4{padding-top:1.5rem !important}.pt-xxl-5{padding-top:3rem !important}.pe-xxl-0{padding-right:0 !important}.pe-xxl-1{padding-right:.25rem !important}.pe-xxl-2{padding-right:.5rem !important}.pe-xxl-3{padding-right:1rem !important}.pe-xxl-4{padding-right:1.5rem !important}.pe-xxl-5{padding-right:3rem !important}.pb-xxl-0{padding-bottom:0 !important}.pb-xxl-1{padding-bottom:.25rem !important}.pb-xxl-2{padding-bottom:.5rem !important}.pb-xxl-3{padding-bottom:1rem !important}.pb-xxl-4{padding-bottom:1.5rem !important}.pb-xxl-5{padding-bottom:3rem !important}.ps-xxl-0{padding-left:0 !important}.ps-xxl-1{padding-left:.25rem !important}.ps-xxl-2{padding-left:.5rem !important}.ps-xxl-3{padding-left:1rem !important}.ps-xxl-4{padding-left:1.5rem !important}.ps-xxl-5{padding-left:3rem !important}.text-xxl-start{text-align:left !important}.text-xxl-end{text-align:right !important}.text-xxl-center{text-align:center !important}}@media (min-width: 1200px){.fs-1{font-size:1.40625rem !important}}@media print{.d-print-inline{display:inline !important}.d-print-inline-block{display:inline-block !important}.d-print-block{display:block !important}.d-print-grid{display:grid !important}.d-print-table{display:table !important}.d-print-table-row{display:table-row !important}.d-print-table-cell{display:table-cell !important}.d-print-flex{display:flex !important}.d-print-inline-flex{display:inline-flex !important}.d-print-none{display:none !important}}body{background-size:cover}.bg-light{background-color:Rgb(var(--t42-bg-light)) !important}.bg-dark{background-color:Rgb(var(--t42-bg-dark)) !important}.bg-base{background-color:Rgb(var(--t42-bg-mid)) !important}.border{border:0.0625rem solid var(--t42-color-opacity-10) !important}.border-primary{border-color:#007be5 !important}.border-secondary,.border-info,.border-light,.border-dark,.border-white{border-color:var(--t42-color-opacity-10) !important}.border-success{border-color:#43a047 !important}.border-danger{border-color:#ff511f !important}.border-warning{border-color:#f9a825 !important}.pl-0{padding-left:0}.pl-1{padding-left:0.25rem}.pl-2{padding-left:0.5rem}.pl-3{padding-left:1rem}.pl-4{padding-left:1.5rem}.pl-5{padding-left:3rem}.pl-auto{padding-left:auto}.pr-0{padding-right:0}.pr-1{padding-right:0.25rem}.pr-2{padding-right:0.5rem}.pr-3{padding-right:1rem}.pr-4{padding-right:1.5rem}.pr-5{padding-right:3rem}.pr-auto{padding-right:auto}.ml-0{margin-left:0}.ml-1{margin-left:0.25rem}.ml-2{margin-left:0.5rem}.ml-3{margin-left:1rem}.ml-4{margin-left:1.5rem}.ml-5{margin-left:3rem}.ml-auto{margin-left:auto}.mr-0{margin-right:0}.mr-1{margin-right:0.25rem}.mr-2{margin-right:0.5rem}.mr-3{margin-right:1rem}.mr-4{margin-right:1.5rem}.mr-5{margin-right:3rem}.mr-auto{margin-right:auto}@keyframes spinner-border{to{transform:rotate(360deg) /* rtl:ignore */}}.spinner-border{display:inline-block;width:2rem;height:2rem;vertical-align:-.125em;border:.25em solid currentColor;border-right-color:transparent;border-radius:50%;animation:.75s linear infinite spinner-border}.spinner-border-sm{width:1rem;height:1rem;border-width:.2em}@keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1;transform:none}}.spinner-grow{display:inline-block;width:2rem;height:2rem;vertical-align:-.125em;background-color:currentColor;border-radius:50%;opacity:0;animation:.75s linear infinite spinner-grow}.spinner-grow-sm{width:1rem;height:1rem}@media (prefers-reduced-motion: reduce){.spinner-border,.spinner-grow{animation-duration:1.5s}}.loader-wrapper{display:flex;flex-direction:column;flex-grow:1;gap:1rem;align-items:center;justify-content:center}.loader-wrapper .loader{width:2rem;height:2rem;border-radius:50%;background:radial-gradient(farthest-side, #999d9e 94%, rgba(0,0,0,0)) center top/4px 4px no-repeat,conic-gradient(rgba(0,0,0,0) 15%, #999d9e);-webkit-mask:radial-gradient(farthest-side, rgba(0,0,0,0) calc(100% - 4px), #000 0)}.loader-wrapper.active .loader{animation:s3 1.5s infinite linear}@keyframes s3{to{transform:rotate(1turn)}}.loader-wrapper .loader-text{margin:0 auto;padding:0 0.833rem;overflow:hidden;color:var(--t42-content-color-muted);text-align:center;text-overflow:ellipsis}@keyframes clipMe{0%,100%{clip:rect(0, 220px, 2px, 0)}25%{clip:rect(0, 2px, 220px, 0)}50%{clip:rect(218px, 220px, 220px, 0)}75%{clip:rect(0, 220px, 220px, 218px)}}@keyframes spin{from{transform:rotate(0deg)}to{transform:rotate(360deg)}}.spinner{display:inline-block;animation-name:spin;animation-duration:3000ms;animation-timing-function:linear;animation-iteration-count:infinite}@font-face{font-weight:400;font-family:"Montserrat";font-style:normal;src:url(data:font/ttf;base64,AAEAAAARAQAABAAQR0RFRrFss1wAAmssAAACfkdQT1N2Wb7+AAJtrAABFy5HU1VCjJZZRgADhNwAAC8mT1MvMlYMpE4AAfmwAAAAYGNtYXBfILVpAAH6EAAACuRjdnQgMKUWggACEzwAAADkZnBnbU0kjnwAAgT0AAANbWdhc3AAAAAQAAJrJAAAAAhnbHlmzhsdpQAAARwAAct0aGVhZA5QtXgAAduUAAAANmhoZWEG0AwiAAH5jAAAACRobXR4v8HBsgAB28wAAB3AbG9jYfsbiDIAAcywAAAO4m1heHAIxQ5XAAHMkAAAACBuYW1lKqFFSQACFCAAAAHucG9zdFa6PIcAAhYQAABVE3ByZXDNS6zAAAISZAAAANUAAgAoAAACIwK8AAMABwApQCYAAAACAwACZQQBAwEBA1UEAQMDAV0AAQMBTQQEBAcEBxIREAUNFysTIREhJREhESgB+/4FAav+pQK8/URGAjD90AAAAv//AAAC3QK8AAcACgArQCgJAQQCAUoFAQQAAAEEAGYAAgJCSwMBAQFDAUwICAgKCAoREREQBgoYKyUhByMBMwEjJwMDAif+jE1nAT1jAT5pcJeXr68CvP1E/wFX/qn/////AAAC3QN3ACIABAAAAAMHEgKaAAD/////AAAC3QN3ACIABAAAAAMHGQKaAAD/////AAAC3QPhACIABAAAACcHMQKaAJYBBwcuApoBEQARsQIBsJawMyuxAwG4ARGwMysA//////88At0DdwAiAAQAAAAjBv8CmgAAAAMHGQKaAAD/////AAAC3QPhACIABAAAACcHMQKaAJYBBwctApoBEQARsQIBsJawMyuxAwG4ARGwMysA/////wAAAt0D7QAiAAQAAAAnBzECmgCWAQcHNAKaAP4AELECAbCWsDMrsQMBsP6wMyv/////AAAC3QPgACIABAAAACcHMQKaAJYBBwcyApoBEQARsQIBsJawMyuxAwG4ARGwMysA/////wAAAt0DdwAiAAQAAAADBxcCmgAA/////wAAAt0DdwAiAAQAAAADBxYCmgAA/////wAAAt0DvgAiAAQAAAAnBy8CmgCWAQcHLgNCAO4AELECAbCWsDMrsQMBsO6wMyv//////zwC3QN3ACIABAAAACMG/wKaAAAAAwcWApoAAP////8AAALdA74AIgAEAAAAJwcvApoAlgEHBy0DQgDuABCxAgGwlrAzK7EDAbDusDMr/////wAAAt0D0wAiAAQAAAAnBy8CmgCWAQcHNAMcAOQAELECAbCWsDMrsQMBsOSwMyv/////AAAC3QPmACIABAAAACcHLwKaAJYBBwcyApoBFwARsQIBsJawMyuxAwG4ARewMysA/////wAAAt0DdwAiAAQAAAADByMCmgAA/////wAAAt0DbQAiAAQAAAADBwoCmgAA//////88At0CvAAiAAQAAAADBv8CmgAA/////wAAAt0DdwAiAAQAAAADBxACmgAA/////wAAAt0DuwAiAAQAAAADByICmgAA/////wAAAt0DfQAiAAQAAAADByQCmgAA/////wAAAt0DVAAiAAQAAAADBx4CmgAA//////8gAvMCvAAiAAQAAAADBwMECAAA/////wAAAt0D1gAiAAQAAAEHBvACmgCqAAixAgKwqrAzK/////8AAALdBB0AIgAEAAABBwbxApoAqgAIsQICsKqwMyv/////AAAC3QN3ACIABAAAAAMHGgKaAAAAAv//AAAD3wK8AA8AEwBEQEEABQAGCQUGZQsBCQABBwkBZQgBBAQDXQADA0JLCgEHBwBdAgEAAEMATBAQAAAQExATEhEADwAPEREREREREQwKGyslFSE1IQcjASEVIRUhFSEVJxEjAwPf/gT+6mdnAaECMf51AV/+oWMU01dXr68CvFfXVeKoAWb+mv////8AAAPfA3cAIgAeAAAAAwcSA0AAAAADAGkAAALDArwADgAXAB8APEA5DgEEAgFKAAIABAUCBGUGAQMDAV0AAQFCSwcBBQUAXQAAAEMATBgYDw8YHxgeHRsPFw8WJyEkCAoXKwAWFRQGIyERITIWFRQGBwEVMzI2NTQmIxI2NTQjIxUzAn1GiYP+sgE6eIMzK/6NzU1TU01uVqvm5gFaWURbYgK8YFU3UBUBAOA5Nzc5/eY4PHXpAAABADD/+AKtAsQAGwAuQCsYFwsKBAIBAUoAAQEAXwAAAEhLAAICA18EAQMDSQNMAAAAGwAaJiQmBQoXKwQmJjU0NjYzMhYXByYjIgYGFRQWFjMyNxcGBiMBOalgYKppUogwQU92Tn5HR35OdVBBMIlSCF2jZmajXTc2P1NGe0xMe0ZUPzY4//8AMP/4Aq0DdwAiACEAAAADBxICxwAA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BwcDUQBzAAixAQGwc7AzK///AGn/LwLDArwAIgBSAAAAAwcEAsEAAP//AGkAAALDA3cAIgBSAAAAAwcXAsEAAP//AGkAAALDA3cAIgBSAAAAAwcWAsEAAP//AGn/PALDArwAIgBSAAAAAwb/AsEAAAABAGkAAADNArwAAwATQBAAAABCSwABAUMBTBEQAgoWKxMzESNpZGQCvP1EAAIAV//4Am0CvAAPABMAM0AwAwEABAIBAgACSgAEBAFdAwEBAUJLAAAAAl8FAQICSQJMAAATEhEQAA8ADhMlBgoWKwQmJzcWFjMyNjURMxEUBiMDMxEjAQN8MCcsaDdeYmSeiORkZAgmIVAeIG5vAY7+d5miAsT+eQD//wBQAAABUgN3ACIAWAAAAAMHEgHHAAD////5AAABPQN3ACIAWAAAAAMHGQHHAAD////oAAABTgN3ACIAWAAAAAMHFgHHAAD///+uAAABGwN3ACIAWAAAAAMHIwHHAAD//wALAAABKwNtACIAWAAAAAMHCgHHAAD//wAPAAABOQP0ACIAWAAAACcHKwHHAJYBBwcuAccBJAARsQECsJawMyuxAwG4ASSwMysA//8AYAAAANYDfQAiAFgAAAADBw4BxwAA//8AaP88AM4CvAAiAFgAAAADBv8BxwAA////5AAAAOYDdwAiAFgAAAADBxABxwAA//8APwAAAQADuwAiAFgAAAADByIBxwAA////+QAAAT0DfQAiAFgAAAADByQBxwAA//8AFgAAASADVAAiAFgAAAADBygBxwAA//8ATv8gAPECvAAiAFgAAAADByoB+AAA////8wAAAUMDdwAiAFgAAAADBxoBxwAAAAH/9//4AZ4CvAAQACxAKQMCAgABAUoAAQECXQACAkJLAAAAA18EAQMDSQNMAAAAEAAPERMkBQoXKxYmJzcWMzI2NREjNSERFAYjhGwhOjpYOz39AWBvbAg1MERTSEYBiVf+JXR1////9//4AaIDdwAiAGgAAAADBxYCGwAAAAEAaQAAAs4CvAALAB9AHAkGAQMAAQFKAgEBAUJLAwEAAEMATBISERIEChgrAQcVIxEzEQEzAQEjAU2AZGQBfHL+1QE+dQE3grUCvP55AYf+xf5///8AaQAAAs4DdwAiAGoAAAADBxcCowAA//8Aaf75As4CvAAiAGoAAAADBwECowAA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KAcKGSsBERQGBwYVFBYzMjY3FwYjIiY1NDcmJjURMxEUMzI2NRECs15XkCIcECEMEygyOEBFf41kxWBmArz+cnaSHjNJGBwJCDEYNy5DMQifjgGO/nbhb3IBigD//wBj//gCswPWACIAxwAAAQcG8AK4AKoACLEBArCqsDMr//8AY//4ArMDdwAiAMcAAAADBxoCuAAA//8AY//4ArMD9AAiAMcAAAAnBzICuACWAQcHLgK4ASQAEbEBAbCWsDMrsQIBuAEksDMrAAAB//8AAALJArwABgAhQB4FAQABAUoDAgIBAUJLAAAAQwBMAAAABgAGEREEChYrAQEjATMTEwLJ/s1j/sxs/P4CvP1EArz9wQI/AAEAIAAABEYCvAAMACdAJAsIAwMAAgFKBQQDAwICQksBAQAAQwBMAAAADAAMEhESEQYKGCsBAyMDAyMDMxMTMxMTBEbqab+/a+pnvcVcwcECvP1EAi/90QK8/ccCOf3EAjz//wAgAAAERgN3ACIA4AAAAAMHEgNgAAD//wAgAAAERgN3ACIA4AAAAAMHFgNgAAD//wAgAAAERgNtACIA4AAAAAMHCgNgAAD//wAgAAAERgN3ACIA4AAAAAMHEANgAAAAAQANAAAClAK8AAsAJkAjCgcEAQQAAQFKAgEBAUJLBAMCAABDAEwAAAALAAsSEhIFChcrIQMDIwEDMxMTMwMBAiHSz3MBB/dyxMJt9wEJASH+3wFnAVX+8wEN/q7+lgAAAf/8AAACiwK8AAgAHUAaBgMAAwABAUoCAQEBQksAAABDAEwSEhEDChcrJRUjNQEzExMzAXVj/upr4OFj8vL0Acj+jwFx/////AAAAosDdwAiAOYAAAADBxICcAAA/////AAAAosDdwAiAOYAAAADBxYCcAAA/////AAAAosDbQAiAOYAAAADBwoCcAAA/////AAAAosDfQAiAOYAAAADBw4CcAAA/////P88AosCvAAiAOYAAAADBv8CcAAA/////AAAAosDdwAiAOYAAAADBxACcAAA/////AAAAosDuwAiAOYAAAADByICcAAA/////AAAAosDVAAiAOYAAAADBx4CcAAA/////AAAAosDdwAiAOYAAAADBxoCcAAAAAEAKwAAAnQCvAAJAC9ALAgBAQIDAQADAkoAAQECXQACAkJLBAEDAwBdAAAAQwBM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AfIAxAAIsQEBsMSwMyv//wBb/y8CUgLmACIB2AAAAAMHBAKDAAD////YAAACUgO1ACIB2AAAAQcG7QG3ANQACLEBAbDUsDMr////2AAAAlIDoQAiAdgAAAEHBxYBtwAqAAixAQGwKrAzK///AFv/PAJSAuYAIgHYAAAAAwb/AoMAAP//AEoAAADMAvUAIgHfAAAAAwcpAbcAAAABAFsAAAC7AhIAAwATQBAAAABFSwABAUMBTBEQAgoWKxMzESNbYGACEv3u//8AQAAAAUIC4QAiAd8AAAADBucBtwAA//8AAgAAARQC4QAiAd8AAAADBzcBtwAA////8QAAASUC4QAiAd8AAAADBzYBtwAA////ngAAAQsC4QAiAd8AAAADBvsBtwAA//8AEgAAAQQC1gAiAd8AAAADBzUBtwAA/////wAAASkDXgAiAd8AAAAjBysBtwAAAQcHLgG3AI4ACLEDAbCOsDMr//8AUAAAAMYC5wAiAd8AAAADBuMBtwAA//8ASv88AMwC9QAiAd8AAAAjBykBtwAAAAMG/wG3AAD////UAAAA1gLhACIB3wAAAAMG5QG3AAD//wAvAAAA8AMlACIB3wAAAAMG+gG3AAD//wACAAABFALnACIB3wAAAAMHOgG3AAD//wBK/zgB6AL1ACIB3wAAACMHKQG3AAAAIwHwARcAAAADBykC0wAA//8ABgAAARACvgAiAd8AAAADBzkBtwAA//8APP8gAN8C9QAiAd8AAAAjBykBtwAAAAMHKgHmAAD////8AAABGgLhACIB3wAAAAMHOAG3AAD///+k/zgA0QL1ACIB8AAAAAMHKQG8AAAAAf+k/zgAwAISAA4AKUAmAwEAAQIBAgACSgABAUVLAAAAAmADAQICTQJMAAAADgANEyQEChYrBiYnNxYzMjY1ETMRFAYjDDwUHx4wJilgWFHIEBBKGS8uAiz91lJe////pP84ASoC4QAiAfAAAAADBzYBvAAAAAEAWwAAAmYC5gALACNAIAkGAQMAAgFKAAEBREsAAgJFSwMBAABDAEwSEhESBAoYKyUHFSMRMxEBMwcTIwEpbmBgASF03/V292aRAub+JAEI2/7J////2AAAAmYDtQAiAfIAAAEHBu0BtwDUAAixAQGw1LAzK///AFv++QJmAuYAIgHyAAAAAwcBAmUAAAABAFsAAAJm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yNQBDP70/////wAAAmgDBwAiAt8AAAEHBucCXwAmAAixAgGwJrAzK/////8AAAJoAwcAIgLfAAABBwbvAl8AJgAIsQIBsCawMyv/////AAACaANxACIC3wAAACcHMQJfACYBBwcuAl8AoQAQsQIBsCawMyuxAwGwobAzK///////PAJoAwcAIgLfAAAAIwb/Al8AAAEHBu8CXwAmAAixAwGwJrAzK/////8AAAJoA3EAIgLfAAAAJwcxAl8AJgEHBy0CXwChABCxAgGwJrAzK7EDAbChsDMr/////wAAAmgDfQAiAt8AAAAnBzECXwAmAQcHNAJfAI4AELECAbAmsDMrsQMBsI6wMyv/////AAACaANwACIC3wAAACcHMQJfACYBBwcyAl8AoQAQsQIBsCawMyuxAwGwobAzK/////8AAAJoAwcAIgLfAAABBwbtAl8AJgAIsQIBsCawMyv/////AAACaAMHACIC3wAAAQcG7AJfACYACLECAbAmsDMr/////wAAAnkDTgAiAt8AAAAnBy8CXwAmAQcHLgMHAH4AELECAbAmsDMrsQMBsH6wMyv//////zwCaAMHACIC3wAAACMG/wJfAAABBwbsAl8AJgAIsQMBsCawMyv/////AAACaANOACIC3wAAACcHLwJfACYBBwctAwcAfgAQsQIBsCawMyuxAwGwfrAzK/////8AAAJoA2MAIgLfAAAAJwcvAl8AJgEHBzQC4QB0ABCxAgGwJrAzK7EDAbB0sDMr/////wAAAmgDdgAiAt8AAAAnBy8CXwAmAQcHMgJfAKcAELECAbAmsDMrsQMBsKewMyv/////AAACaAMHACIC3wAAAQcG+wJfACYACLECArAmsDMr/////wAAAmgC/QAiAt8AAAEHBt8CXwAmAAixAgKwJrAzK///////PAJoAjgAIgLfAAAAAwb/Al8AAP////8AAAJoAwcAIgLfAAABBwblAl8AJgAIsQIBsCawMyv/////AAACaANLACIC3wAAAQcG+gJfACYACLECAbAmsDMr/////wAAAmgDDQAiAt8AAAEHBvwCXwAmAAixAgGwJrAzK/////8AAAJoAuQAIgLfAAABBwb2Al8AJgAIsQIBsCawMyv//////yACfgI4ACIC3wAAAAMHAwOTAAD/////AAACaANSACIC3wAAAQcG8AJf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VAD////w/zgCNgISAAICbwYA////8P84AjYC4QAiAm8GAAADB1gB8AAAAAMAK/8+AvoC5gARABgAHgA3QDQeAQAGAUoABAMEgwgBBwcDXwUBAwMiSwAGBgBfAgEAACFLAAEBJAFMFhEUEREUERERCQcdKyQGBxUjNSYmNTQ2NzUzFRYWFQQWFxEGBhUENTQmJxEC+qSVXpWjopZelaT9kG1sbWwCEW5sj44Iu7sIjXx7igjPzwiLelVgBwF0B15TrKxUXQf+iwD//wAJAAACFQISAAICbvsAAAEAKgAAAgQCEgARAC9ALBABAwIDAQEDAkoAAwABAAMBZwUEAgICIksAAAAhAEwAAAARABEjEyIRBgcYKwERIzUGIyImNTUzFRQWMzI3NQIEYFZVY2xgRT5GUQIS/e7WKFxcrKY3OCPyAAABAF3/gQKTAhIACwApQCYAAAMAUgQBAgIiSwYFAgMDAV4AAQEhAUwAAAALAAsREREREQcHGSslFSM1IREzESERMxECk1v+JWABImBU038CEv5CAb7+QgAAAQBdAAADUAISAAsAJUAiBgUDAwEBIksEAQICAF4AAAAhAEwAAAALAAsREREREQcHGSsBESERMxEzETMRMxEDUP0NYOpg6QIS/e4CEv5CAb7+QgG+AP//AF3/jwOfAhIAIgUmAAAAAwdaArIAAAABAF3/gQIoAhIACwBGS7AKUFhAGAABAAABbwUBAwMiSwAEBABeAgEAACEATBtAFwABAAGEBQEDAyJLAAQEAF4CAQAAIQBMWUAJEREREREQBgcaKyEjFSM1IxEzESERMwIot1u5YAELYH9/AhL+QgG+AAACAF3//gIhAhIACgATADBALQUBAgADBAIDZQABASJLBgEEBABeAAAAIQBMCwsAAAsTCxIRDwAKAAkRJAcHFisAFhUUBicnETMVFxI2NTQmJycVFwG3anNr5mCVKkNBQ35+AV1aUlZdAQECErMB/uk2NTQwAQLQAQACAAQAAAJhAhIADAAVADZAMwYBAwAEBQMEZQABAQJdAAICIksHAQUFAF0AAAAhAEwNDQAADRUNFBMRAAwACxERJAgHFysAFhUUBiMjESM1IRUzEjY1NCYjIxUzAfhpc2nfogECkCpAPz98fAFfW1JVXQG+VLP+6jY1MzHPAAADAF3//gLJAhIACgAOABcANkAz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hAMBAgIBXQABASEBTAAAAAUABRERBAcWKzcVIzUjNfpccVfwmVcAAQA6/2cA2wBXAAUAH0AcAAABAIQDAQICAV0AAQEhAUwAAAAFAAUREQQHFis3FSM1IzXbXURX8JlXAAEAQP+PANoAUgAFADxLsApQWEASAAABAQBvAwECAgFdAAEBIQFMG0ARAAABAIQDAQICAV0AAQEhAUxZQAsAAAAFAAUREQQHFis3FSM1IzXaV0NSw3FSAP///jICWf92A0sAIgcxAAABBgcuAHsACLEBAbB7sDMr///+MgJZ/3YDSwAiBzEAAAEGBy0AewAIsQEBsHuwMyv///4yAln/dgNXACIHMQAAAQYHNABoAAixAQGwaLAzK////i8CWf95A0oAIgcxAAABBgcyAHsACLEBAbB7sDMr///+IQJfABoDKAAiBy8AAAEHBy4AqABYAAixAQGwWLAzK////iECX//BAygAIgcvAAABBwctAKgAWAAIsQEBsFiwMyv///4hAl//pAM9ACIHLwAAAQcHNACCAE4ACLEBAbBOsDMr///+IQJf/4cDUAAiBy8AAAEHBzIAAACBAAixAQGwgbAzK////jIC7/92A+EAJwcxAAAAlgEHBy4AAAERABGxAAGwlrAzK7EBAbgBEbAzKwD///4yAu//dgPhACcHMQAAAJYBBwctAAABEQARsQABsJawMyuxAQG4ARGwMysA///+MgLv/3YD7QAnBzEAAACWAQcHNAAAAP4AELEAAbCWsDMrsQEBsP6wMyv///4vAu//eQPgACcHMQAAAJYBBwcyAAABEQARsQABsJawMyuxAQG4ARGwMysA///+IQL1ABoDvgAnBy8AAACWAQcHLgCoAO4AELEAAbCWsDMrsQEBsO6wMyv///4hAvX/wQO+ACcHLwAAAJYBBwctAKgA7gAQsQABsJawMyuxAQGw7rAzK////iEC9f+kA9MAJwcvAAAAlgEHBzQAggDkABCxAAGwlrAzK7EBAbDksDMr///+IQL1/4cD5gAnBy8AAACWAQcHMgAAARcAEbEAAbCWsDMrsQEBuAEXsDMrAAABAF//ZwC8ABcAAwAYQBUAAQAAAVUAAQEAXQAAAQBNERACBxYrFyM1M7xdXZmwAAABAF7/jwC5ABUAAwAYQBUAAQAAAVUAAQEAXQAAAQBNERACBxYrFyM1M7lb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UXdRg1GUUaVRtlHHUdhR6VICUhtSgFKLUp9SsFLJUuJS+1NDU3xTuVQOVFFUYlRzVH9UkFScVK1UuVUPVSBVOVVBVVJVa1V3VYhVlFWlVbFVxlZEVmNWdFaFVpFWnVauVrpWxlb0VwVXFlcnVzhXSVdaV2ZXd1eIV5lXslfHV+BX+VgSWCNYNFhFWF5YrFi9WM5Y51kLWTxZTVleWW9ZgFmtWdBZ4VnyWgNaFFogWjFaQlpTWmRaklqjWrRaxVrRWw1bHlsvW0hbXVt2W49bqFu5W8pb41v4XBFcKlxDXFRcZVxxXIJck1ykXLVcwVzSXONc9F1ZXWpdf13WXedd+F4JXh5eL15IXl1edl6PXqheuV7KXtte5174XwlfGl8rX0RfXV/pX/pgSGCBYOJg82EEYRVhJmE3YUhhXGGGYY5hn2HtYf5iD2IgYjFiSmJWYmdieGKJYsVi1mLiYvNjKGM5Y0VjpmOyY/dkCGQZZCVkNmRCZKJkrmS6ZMtlFmVAZVFlYmVuZXpli2WXZaNl7WX+Zg9mIGYxZkJmU2ZfZnBmgWaSZqtmwGbZZvJnC2ccZy1nPmdXZ2NndGeFZ55n5mf3aAhoGWgqaHVohmiXaKhouWjKaNto7Gj9aQ5pSWlaaWtpfGmIad9qH2onamJqr2rNatlq+ms7a0NrT2tba5tr+WwfbCtsN2yNbLtsx20hbVVtXW1lbYltkW2Zbblt8m3+blBugG62buJvDm8ab0Fvem+4b8Rv0HAxcDlwSXCYcK5wunDCcQBxc3G1ciRybXK4csxzGXNJc5hzpHOwc7xz+nQ3dGt0d3SDdNZ04nWZdaV1sXW5dc112XYNdhl2XXaTdp93B3cTdxt3J3dud6x34XggeF54anh2eH54injheO14+XkFeVF5XXlpeXV5iXmhea15uXnFedF53Xnoefh6RnqQesh7I3txe3l7qnvzfEF8f3yLfMJ85n05fWN9b317fYd9j33Ufdx96H30ffx+CH6nfrN+6380fzx/RH9Qf5p/5IA1gKOBM4GugbaCDoIagiaCMoI6gkaCUoJegmqCdoKCgo6CloLvgveDXYOng8SD1oQHhEeET4RbhGeEo4T+hSSFMIU8hZKFvYXJhhiGS4ZxhnmGnYalhq2GzYbVhuGHMIc4h22HmYfEh9CICYhFiISIyYjViTKJOolKiZaJoomuibqKAYqKisiLJouKi9uL44wxjF+MrYy5jRaNIo1djZ6Nz43bjeeN845FjtOO347rjw6PIo8uj2KPbo+vj7eP95BZkGWQbZB5kL6ROJF6ka2R6pImkjKSPpJGklKSpJKwkrySyJMRkx2TKZM1k4eTk5Ofk6uTt5PDk8+T2pPmlDWUepSylQqVXJVklZWV35ZXlpmWpZcDl1qXYpell/6YBpgSmB6YT5hymHqYgpiKmL+Yy5ktmTmZgZnPmkaabpp6moaamJrymv6bBpsSmyabLps2mz6bSptWm16bapvom/ScRJxMnFScYJyonPadXp3GnkCemJ6knrCeuJ7EnxOfH58rnzefQ59Pn1ufZ5+/n+agMqB0oLCgwaDJoQqhKaFpobKh5aItoo+izaM4o5mj36P9pD2kiKS+pQelD6VSpVqlaKV3pYallaWkpbOlwqXRpeCl76X+pkCmaKaopvCnI6drp82oC6h2qNipHqlFqYWpzqoDqkyqVKqXqp+rA6sRqx+rLas7q0mrV6tlq3OrgauPq8mr76wtrHOso6zlrTytd63Xri+uPq5krqKu6K73rzqvSa+Fr5Svo6+yr8Gv0K/fr+6v/bAMsBuwKrA5sFGwYbBxsIGwkbChsLGwwbDRsOGxFrExsVaxe7GNsbqxyrH5siiylLK2swuzZLNws4ezmbOws8yz57QMtBm0PrRVtHq0vrUFtSW1SLVrtZG1nrWrtbi1xbXStd+1+LYRtiq2MrZLtlO2W7ZotnW2graOtpq2ubbbtue287b/tya3Ubd+t5O3qLe1t8K38bgiuC64OrhZuHu4nbjxuUi5VLlguWy5eLmfucq597oNuiq6Oro6ujq6Oro6ujq6OrqWuuG7c7vfvFG8371Jvbq98r5UvsO+/79Xv6C/28BIwFjA5cErwXzBwsHswizCuML4wwDDRcNNw3XDjsOrw/XEJ8SBxJfErsTYxQTFOsW+xjLGUMayxybHacdxx3nHnMfVyATIDMhvyR7J/sodyjXKW8p0ypPKq8rUyuzLHss8y1vLfsuly8vL3sv6zBTMKsxUzGbMdsyOzJ7MxMzczQLNGs3KzjjOY87iz2TP6tAx0HnQj9Cx0QbRK9Fi0cvSU9J60pHSsdK+03fT5dQk1DXURtRX1IHUktSs1L3U1tTn1PjVHtU11VrVf9WP1cHWA9ZI1rzWzdbe1u/XDdce1y/XQNd115vXydf22CLYS9iJ2LnY+dkx2WHZftmc2brZzNnm2iHaONpP2mbajNqj2rna0Nrl2vzbE9s121bbd9uO27zcLNxD3FrccdyL3KLcudzQ3QHdI91N3Wfded2P3andzN4L3lPehN6k3sTe5t8I3zLfld+53+rgMuBU4Hzg8uEJ4S/hU+Ft4Yrhl+Gj4cDh2eH24ibiVOJu4oripuKv4rjiweLK4tPi3OLl4u7i9+MA4wnjEuMb4zTjTeNk45LjwOPs5AnkJuRS5GLkcuSC5JLko+S05MXk1uTt5QTlGuUx5UflXeVz5YrlouW6AAAAAQAAAAczM3QVnhxfDzz1AAcD6AAAAADWC/5GAAAAANYeQAX8uP75Bk0EHQAAAAcAAgAAAAAAAAJLACgAAAAAAQ0AAAENAAAC3P//Atz//wLc//8C3P//Atz//wLc//8C3P//Atz//wLc//8C3P//Atz//wLc//8C3P//Atz//wLc//8C3P//Atz//wLc//8C3P//Atz//wLc//8C3P//Atz//wLc//8C3P//Atz//wQX//8EF///AvUAaQLTADAC0wAwAtMAMALTADAC0wAwAtMAMALTADADOgBpBa4AaQNCAAsDOgBpA0IACwM6AGkDOgBpBUMAaQKeAGkCngBpAp4AaQKeAGkCngBpAp4AaQKeAGkCngBpAp4AaQKeAGkCngBpAp4AaQKeAGkCngBpAp4AaQKeAGkCngBpAp4AaQKeAGkCngBpAp4AaQKeAGkCngBpAm8AHwJvAB8CewBpAwQAMAMEADADBAAwAwQAMAMEADADBAAwAwQAMAMnADADLABpAzwACQMsAGkDLABpAywAaQMsAGkBNgBpAtAAVwE2AFABNv/5ATb/6AE2/64BNgALATYADwE2AGABNgBoATb/5AE2AD8BNv/5ATYAFgE2AE4BNv/zAgH/9wIB//cCzwBpAs8AaQLPAGkCUgBpBFMAaQJSAFACUgBpAlIAaQJSAGkCUgBpA24AaQJSAGkCWgAJA7sAaQO7AGkDLABpBS0AaQMsAGkDLABpAywAaQMsAGkDLABpAywAaQRIAGkDLABpAywAaQNIADADSAAwA0gAMANIADADSAAwA0gAMANIADADSAAwA0gAMANIADADSAAwA0gAMANIADADSAAwA0gAMANIADADSAAwA0gAMANIADADSAAwA0gAMANIADADSAAwA0gAMANIADADSAAwA0gAMANIADADSAAwA0gAMANIADADSAAwA0gAMANIADAEZgAwAtIAaQLSAGkDSAAwAtcAaQLXAGkC1wBpAtcAaQLXAGkC1wBpAtcAaQLXAGkCbQApAm0AKQJtACkBAgBQAm0AKQJtACkCbQApAm0AKQJtACkCbQApAm0AKQJtACkC+wBjAzEAMAJLAAQCSwAEAksABAJLAAQCSwAEAksABAJLAAQDFwBjAxcAYwMXAGMDFwBjAxcAYwMXAGMDFwBjAxcAYwMXAGMDFwBjAx8AYwMfAGMDHwBjAx8AYwMfAGMDHwBjAxcAYwMXAGMDFwBjAxcAYwMXAGMDFwBjAxcAYwMXAGMCyP//BGYAIARmACAEZgAgBGYAIARmACACoQANAof//AKH//wCh//8Aof//AKH//wCh//8Aof//AKH//wCh//8Aof//AKRACsCkQArApEAKwKRACsCkQArAtAAVwMgAGMDIABjAyAAYwMgAGMDIABjAyAAYwMgAGMDIABjAyAAYwMgAGMDIABjAyAAYwMgAGMDIABjAyAAYwMgAGMDIABjAyAAYwMgAGMDIABjAyAAYwMgAGMDIABjAyAAYwMgAGMDIABjBDIAWgQyAFoFrgBpBU0AaQKEADMChAAzAoQAMwKEADMChAAzAoQAMwKEADMChAAzAoQAMwKEADMChAAzAoQAMwKEADMChAAzAoQAMwKEADMChAAzAoQAMwKEADMChAAzAoQAMwKEADMChAAzAl4AYwMEADADBAAwAwQAMAMEADADBAAwAwQAMAMEADADLAAwAcgAKwLQAFcByAArAtAAVwHIACsByAArAcj/+AHIACsByAArAcgAKwHIACsByAArAcgAKwHIACsByAArAcgAKwHIACsB///3Af//9wRvAGkEywBpBMsAaQMeAGkFHQBpAx4AaQMeAGkDHgBpAx4AaQMeAGkDHgBpBDoAaQMeAGkDHgBpA0gAMAMxAEUCVv/8Alb//AJW//wCVv/8Alb//AJW//wCVv/8AxoAYwMaAGMDGgBjAxoAYwMaAGMDGgBjAxoAYwMaAGMDGgBjAxoAYwMaAGMDGgBjAxoAYwMaAGMDGgBjAxoAYwMaAGMDGgBjAxoAYwMaAGMDGgBjAxoAYwMaAGMDGgBjBKYAYwSmAGMEpgBjBKYAYwSmAGMDEwBeAxMAXgMTAF4DEwBeAxMAXgMTAF4DEwBeAxMAXgMTAF4DEwBeApsAMAKbADACmwAwApsAMAKbADACVgAyAlYAMgJWADICVgAyAlYAMgJWADICVgAyAlYAMgJWADICVgAyAlYAMgJWADICVgAyAlYAMgJWADICVgAyAlYAMgJWADICVgAyAlYAMgJWADICVgAyAlYAMgJWADICVgAyAlYAMgPdADID3QAyAqoAWwI7ACoCOwAqAjsAKgI7ACoCOwAqAjsAKgI7ACoCqgAqAoAAKgKqACoCqgAqAqoAKgKqACoEuwAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAg//7AIP/+wBYQAPArIAKgKyACoCsgAqArIAKgKyACoCsgAqArIAKgK6ACoCqQBbAqkAAAKpAFsCqf/YAqn/2AKpAFsBFwBKARcAWwEXAEABFwACARf/8QEX/54BFwASARf//wEXAFABFwBKARf/1AEXAC8BFwACAjMASgEXAAYBFwA8ARf//AEc/6QBHP+kARz/pAJoAFsCaP/YAmgAWwJeAFsBFwBbARcAQAEXAFsBFwBYAVoAWwEXAFgCMwBbARf/6AEn//kEIQBbBCEAWwKpAFsCqQBbAwIANQKpAFsCqQBbAqkAWwKpAFsCqQBbA8UAWwKpAFsCqQBbAnsAKgJ7ACoCewAqAnsAKgJ7ACoCewAqAnsAKgJ7ACoCewAqAnsAKgJ7ACoCewAqAnsAKgJ7ACoCewAqAnsAKgJ7ACoCewAqAnsAKgJ7ACoCewAqAn8AKgJ7ACoCewAqAnsAKgJ7ACoCewAqAnsAKgJ7ACoCewAqAnsAKgJ7ACoCewAqAnsAKgQrACoCqgBbAqoAWwKqACoBmgBbAZoAWwGaADcBmgBYAZr//QGaAFgBmgBIAZr/6AH1ABgB9QAYAfUAGAD/AFAB9QAYAfUAGAH1ABgB9QAYAfUAGAH1ABgB9QAYAfUAGAKkAFsBMgAZAZ4ADwGoABQBngAPAZ4ADwGeAA8BngAJAZ4ADwGeAA8CpQBWAqUAVgKlAFYCpQBWAqUAVgKlAFYCpQBWAqUAVgKlAFYCpQBWAq0AVgKtAFYCrQBWAq0AVgKtAFYCrQBWAqUAVgKlAFYCpQBWAqUAVgKlAFYCpQBWAqUAVgKlAFYCL//+A4MABgODAAYDgwAGA4MABgODAAYCKAAOAi//6gIv/+oCL//qAi//6gIv/+oCL//qAi//6gIv/+oCL//qAi//6gIJACgCCQAoAgkAKAIJACgCCQAoAjIASAKqACoCqgAqAqoAKgKqACoCqgAqAqoAKgKqACoCqgAqAqoAKgKqACoCqgAqAqoAKgKqACoCqgAqAqoAKgKqACoCqgAqAqoAKgKqACoCqgAqAqoAKgKqACoCqgAqAqoAKgKqACoCqgAqA90AMgPdADIEvQAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAArAVMAWwFBAFsBQQBAAUEAWwFBAFsBbQBbAUEAWwI1AFsBQQApAUH/8QQ6ACoBiwBWAZUADAGLAFYBiwBWAYsAVgGL//YBiwBWAYsASAPZAFYD2QBWA9kAVgPZAFYD2QBWAqUAVAKlAFQCpQBUAqUAVAKlAFQCpQBUAqUAVAKlAFQCpQBUAhMALQITAC0CEwAtAhMALQITAC0EsQAEAsgADwJ4AA8CugBbAosADwJn//8CZ///Amf//wJn//8CZ///Amf//wJn//8CZ///Amf//wJn//8CZ///Amf//wJn//8CZ///Amf//wJn//8CZ///Amf//wJn//8CZ///Amf//wJn//8CZ///Amf//wJn//8CZ///A2z//wNs//8ChABhAmEALAJhACwCYQAsAmEALAJhACwCYQAsAmEALAK+AGEC0gAgAr4AYQLSACACvgBhAr4AYQTOAGECOgBhAjoAYQI6AGECOgBhAjoAYQI6AGECOgBhAjoAYQI6AGECOgBhAjoAYQI6AEMCOgBhAjoAYQI6AGECOgBhAjoAYQI6AGECOgBhAjoAYQI6AGECOgBhAjoAYQKcACwCMAAlAjAAJQIgAGECjgAsAo4ALAKOACwCjgAsAo4ALAKOACwCjgAsAq8ALAK7AGEC4wAiArsAYQK7AGECuwBhArsAYQEiAGEBIgBhASIARgJQAEEBIgAIASL/9wEi/6QBIgAYASIABQEiAFYBIgBeASL/2gEiADUBIgAIAm8ATAEiAAwBIgBDASIAAgHB//wBwf/8AmwAYQJsAGECbABhAmwAYQH7AGEB+wBHAfsAYQH7AGEB+wBhAfsAYQO8AGEB+wBhAfv/+AMyAGEDMgBhArsAYQK7AGECuwBhArsAYQK7AGECuwBhArsAYQR8AGECuwBhArsAYQLCACwCwgAsAsIALALCACwCwgAsAsIALALCACwCwgAsAsIALALCACwCwgAsAsIALALCACwCwgAsAsIALALCACwCwgAsAsIALALCACwCwgAsAsIALALCACwCwgAsAsIALALCACwCwgAsAsIALALCACwCwgAsAsIALALCACwCwgAsAsIALALCACwDqwAsAm8AYQJvAGECwgAsAnYAYQJ2AGECdgBhAnYAYQJ2AFQCdgBhAnYAYQJ2AGECEwAlAhMAJQITACUA/wBQAhMAJQITACUCEwAlAhMAJQITACUCEwAlAhMAJQITACUCigBbAe0ABAHtAAQB7QAEAe0ABAHtAAQB7QAEAe0ABAHtAAQCqABbAqgAWwKoAFsCqABbAqgAWwKoAFsCqABbAqgAWwKoAFsCqABbArAAWwKwAFsCsABbArAAWwKwAFsCsABbAqgAWwKoAFsCqABbAqgAWwKoAFsCqABbAqgAWwKoAFsCaQAIA70AIgO9ACIDvQAiA70AIgO9ACICPAAMAjkAAgI5AAICOQACAjkAAgI5AAICOQACAjkAAgI5AAICOQACAjkAAgIrACkCKwApAisAKQIrACkCKwApAq8AWwKvAFsCrwBbAq8AWwKvAFsCrwBbAq8AWwKvAFsCrwBbAq8AWwKvAFsCrwBbAq8AWwKvAFsCrwBbAq8AWwKvAFsCrwBbAq8AWwKvAFsCrwBbAq8AWwKvAFsCrwBbAq8AWwKvAFsDmQBVA5kAVQToAGECJwAqAicAKgInACoCJwAqAicAKgInACoCJwAqAicAKgInACoCJwAqAicAKgInACoCJwAqAicAKgInACoCJwAqAicAKgInACoCJwAqAicAKgInACoCJwAqAicAKgKcADkCCABbAo4ALAKOACwCjgAsAo4ALAKOACwCjgAsAo4ALAK0ACwBqgA5AaoAOQGqADkCbwBBAaoAOQGqADkBqv/pAaoAOQGqADkBqgA5AaoAHwGqADkBqgA5Am8ATAGqADkBqgA5AaoAOQHB//wBwf/8A7wAYQQAAGEEAABhAq4AYQKuAGECrgBhAq4AYQKuAGECrgBhAq4AYQRvAGECrgBhAq4AYQLCACwB9//8Aff//AH3//wB9//8Aff//AH3//wB9//8Aff//AKuAFsCrgBbAq4AWwKuAFsCrgBbAq4AWwKuAFsCrgBbAq4AWwKuAFsCtgBbArYAWwK2AFsCtgBbArYAWwK2AFsCrgBbAq4AWwKuAFsCrgBbAq4AWwKuAFsCrgBbAq4AWwP/AFsD/wBbA/8AWwP/AFsD/wBbAqMAVgKjAFYCowBWAqMAVgKjAFYCowBWAqMAVgKjAFYCowBWAqMAVgIrACkCKwApAisAKQIrACkCKwApAZQAJQGiACAC9gAMAtsAbQLrAG0CQgBtAkIAbQJFAG0DJAANApkAbQKZAG0CmQBtBAUAEwKCACADNwBtAzcAbQM3AG0DUwBtAscAbQLHAG0DFgANA8MAbQM0AG0DUAAzAzUAbQLKAG0CzgA0AlsADQKzABACswAQA54ALQKcABEC4AA2Az0AbQRHAG0EYABtAycAbQLJAG0DPAANA+EAbQSjAA0EnABtAnwAMQLEADUCwwAdAT0AbQE2AAsCHAASA0oADQRLAG0C2wA6A0EADgMrABMDhAASA1AAMwL5AA4CagAeAr8AbQQsABMCggAgAvMAbQLkAG0C3QAjAzsADQNPAG0EPwBtBKwAbQNQAG0DzgA5As4ANAJbAA0CmwAGAof//ALBABEDzgAOAvsANgLgADUC4ABtAyUAbQPdACAD3QAgAT4AbQQFABMCygBtAy8AbQNQAG0C3AAzA+gAbQL2AAwC9gAMBBYABwKZAG0DNwApAzcAKQQFABMCggAgAm8AHwM3AG0DNwBtA1AAMwNQADMDUAAzAsMAHQKzABACswAQArMAEALgADYCQgBtA+EAbQJrAB0CoAAOAqwAGgKCADkDFwAMA1YAMwQ9ABUC4wAfAt0AbQMw/7QDMQANAxkADgLlAA0DnQAxAk8AbQKCACACzgA0As4ANAMgAGMDRAAeAoQAMwKEADMChAAzAxoAYwMaAGMDGgBjAxoAYwMWACACzQBcAncADQMTAF4DEwBeA58AMgLMAF8DaAAOA+EAXwSfAAwEjABtAf//9wM7ABMCdwANAyAAYwMgAGMEMgBaAoQAMwMaAGMDGgBjAxMAXgMTAF4DEwBeA+EAXwNIADAC7wAaAk0AMAKWAD4CZgBdAegAXQHoAF0B0gBdApgACAJ0ACwCdAAsAnQALANRAA0CIAAcArYAXQK2AF0CtgBdAswAXQJWAF0CVgBdAoEABQMeAF0CqQBdAoEALAKlAF0CsABdAjsALAHtAAQCO//wAjv/8AMlACsCHQAJAmEAKgKyAF0DrQBdA60AXQKGAF0CPwBdAn8ABAMnAF0DpgAFA7gAXQIYACsCQQAsAj8AGAEbAEwBFwASARz/ogKi/9wDbABdAmQAMAKj//YCZQAAAsAADwKKACwCVAAFAgQAKwJZAF0DcgANAiAAHAJWAF0CZgBbAlUAAAKeAAQCvgBdA3YAXQKlAF0D0ABdAyYALwI7ACwB7QAEAj4ABgI+AAYCHQAJAwMABQJ6ACoCYQApAqIAXQK8AF0DAwAVAwMAFQEbAF0DUQANAlYAXQKXAAUCrwBdAr8AXQJeACcDPQBdAk0AMAJNADAD4wAwAnQALAJzADgCcwA4A1EADQIgABwCD//sArYAXQK2AF0CgQAsAooALAKKACwCPwAYAjv/8AI7//ACO//wAmEAKgHoAF0DJwBdAewADQIdAAsCOQAWAiAANQKBAAUCsAAuA6oACQJeABYCuwBeAqn/pQKWAAUCfgBMAiEALgKzACkDUQANAe7/9wKeAE0CngBNAp4ATQJVAF4CPAAFAqkAXQKiAF0EGwBdAmMALAK3AE0EGwBOBDQATgJAAFACnAAFA1cAXgH0AF0CIAAcAjsALAHoAF0CbgAnARcABgKzACcCpQBWBBsATgKqACoCswApAmQAKgJkACoCZAAqAp4ATQKeAE0CngBNAp4ATQKWAEYEGwBdAqUAVAKlAFQCSQBQAqUABQMoAFADrQAIA7IAXQJ6//wCqgAqAqoAKgPdADICZAAqAmQAKwJkACsCngBNAp4ATQKlAFQCpQBUAqUAVAMoAFACawARAtz//wOCAAkCqgBbAtT/+ALc//8CzwBpApsAMAFyAAgCPgAOAjwABQKdACYCPgARAmkAMAJWAB4ChAAsAmkAHAKsADIBcgAIAj4ABgI8AAYCnQAmAj4AEQJpADACVgAeAoQALAJpABwBrgAcAa4AUQGuABwBrgAbAa4AFgGuABsBrgAlAa4AJAGuABwBrgAgArwAPQK8AJACvAA8ArwAPgK8ADUCvABBArwASgK8AEkCvAA7ArwAQQK8ADwCvACQArwARwK8AD4CvAA1ArwAQQK8AEoCvABJArwAOwK8AEEBrgAcAa4AUQGuABwBrgAbAa4AFgGuABsBrgAlAa4AJAGuABwBrgAgAa4AHAGuAFEBrgAcAa4AGwGuABYBrgAbAa4AJQGuACQBrgAcAa4AIAGuABwBrgBRAa4AHAGuABsBrgAWAa4AGwGuACUBrgAkAa4AHAGuACABrgAcAa4AUQGuABwBrgAbAa4AFgGuABsBrgAlAa4AJAGuABwBrgAgAK7/QgQKAFEECgBRBAoAHAQKAFEECgAbBAoAUQQKABsECgAbBAoAJAGQABMBYP/aAQsAQgE6AEIA4wAuAOMAMAKzAC4BDABFAQwARQK/ABsA4wAuAj0ACQI9AEUBhwA/ANIAPwDjAC4BYP/kAfQAAAFg/9oBHwBMAU4ATAFYAH4BYP/kAIEALQFfADkBXwATAU0AaQFNABMBUQBfAVIAIAFzAEMBcwAdAWEAcwFhAB0BZQBpAWYAKgPoAAAB9AAAArwALwPoAAABfwA5AX8AOQF/ADkD6AAAAfQAAAGTAEMB+AAuAfgAIgE4AC4BOAAiAaAAMAGgAC4BoAAwAOMALgDjADAA4wAwAgwAOAIMACwBTAA4AUwALAEMAEUBDABFAdwALgHdACIBIgAuASMAIgDnADMCCgAIAgkARQGHAD8BnwAwAZ8ALgGfADAA4gAuAOIAMADjADAA0gA/AUkAJAFJACsCvAAAAGQAAADjAAABDQAAAIYAAAAAAAAC0wAwAjsAKgLTADACvAAfAm0AKQKqACoDJwAeAcH/pAKXAB4DBAAwAzgAVwKUAB4ChgAeAsgAHgOUAGkDcAAeBmoAaQNLAB4C7gAeAtAAHQKGAB4C0QBMAqoAMwSqAB4Cw//8AR8ATAIaAEwBYP/kAkYAQwJGAEMCRgBrAkYAQwJGAEMCRgBDAkYAQwJGAEMCRgBDAkYAQwJGAEMCRgA6AkYAOgJGAEMCRgAlA5sAKgGP/90DggAJAtz//wMsAGkCkQArAyMAQwKqAFsCvABIA0sAJQS6ACUCWABgAlgAeAJYAEMCWAB5AlgAagJYAG4CWABgAlgAbwLZADICWABfAlgAYAJYAEMCWABq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Bz4HPQdEB0MHTAdKB0cHQAdFB0EHRgdJB04HUwdSB1QHUAblBucG7AbyBvYG7wbjBt8G+gbwBuoG7QRuBG8ElwRqBI8EjgSRBJIEkwSMBI0ElAR3BHQEgQSIBGYEZwRoBGkEbARtBHAEcQRyBHMEdgSCBIMEhQSEBIYEhwSKBIsEiQSQBJUElgUGBQcFCAUJBQwFDQUQBREFEgUTBRYFIgUjBSUFJAUmBScFKgUrBSkFMAU1BTYFDgUPBTcFCgUvBS4FMQUyBTMFLAUtBTQFFwUUBSEFKASYBTgEmQU5BJoFOgSbBTsEdQUVBNgFeQTZBXoEawULBJwFPASdBT0EngU+BJ8FPwSgBUAEoQVBBKIFQgSjBUMEpAVEBKUFRQSmBUcEqAVIBKkFSQSqBUoEqwVLBKwFTAStBU0ErgVOBK8FTwSwBVAEsQVRBLMFUwS0BVQEtQS2BVYEtwVXBVgEuAVZBLkFWgS6BVsEuwVcBVUEvAVdBL0FXgS+BV8EvwVgBMAFYQTBBWIEwgVjBMMFZATEBWUExQVmBMYFZwTHBWgEyAVpBMkFagTKBWsEywVsBMwFbQTNBW4EzgVvBM8FcATQBXEE0QVyBNIFcwTTBXQE1AV1BNUFdgTWBXcE1wV4BKcFRgSyBVIE2gV7BNsFfAAlAasALQGyAC4BswBEAckAQwHIADQBuQBQAdYAVwHdAFQB2gBfAeUAcwH7AHUB/QB4AgAAfgIGAH8CBwCCAgoAowIrAKQCLACeAiYAnQIlAK8CNwCxAjkAuwJDALwCRAC0AjwAtwI/AL0CRQDFAk4AxgJPAN4CZwDaAmMA5AJtAOECagDjAmwA6gJzAPQCfQAVAZsAFwGdAA4BlAAQAZYAEQGXABIBmAAPAZUABwGNAAkBjwAKAZAACwGRAAgBjgA+AcMAQAHFAEYBywA2AbsAOAG9ADkBvgA6Ab8ANwG8AGMB6QBhAecAkQIZAJMCGwCIAhAAigISAIsCEwCMAhQAiQIRAJUCHQCXAh8AmAIgAJkCIQCWAh4AzgJXANACWQDSAlsA1AJdANUCXgDWAl8A0wJcAOwCdQDrAnQA7QJ2AO8CeAZzBnUGdwZ0BngGSgZJBkgGSwZXBlgGVgbVBtYGJwaBBoUGfgZ/BoQGjwaKBoIGgwZ5Bo4GjAaGBocGiwW/Bb4GtQavBrEGswa3BrgGtgaw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AREBEgETARQAYwEVAK4AkAEWACUAJgD9AP8AZAEXARgBGQAnARoA6QEbARwBHQEeAR8AKABlASABIQEiAMgBIwEkASUBJgEnASgAygEpASoAywErASwBLQEuAS8BMAExATIBMwApACoA+AE0ATUBNgE3ATgBOQArAToBOwE8AT0BPgAsAT8AzAFAAM0BQQDOAUIA+gFDAM8BRAFFAUYBRwFIAC0BSQAuAUoBSwAvAUwBTQFOAU8BUAFRAVIBUwDiADABVAAxAVUBVgFXAVgBWQFaAVsBXAFdAGYAMgDQAV4A0QFfAWABYQFiAWMBZABnAWUBZgFnANMBaAFpAWoBawFsAW0BbgFvAXABcQFyAXMBdACRAXUArwF2AXcBeACwADMA7QA0ADUBeQF6AXsBfAF9AX4BfwA2AYABgQGCAOQBgwD7AYQBhQGGAYcBiAGJAYoANwGLAYwBjQGOAY8BkAA4ANQBkQGSANUBkwBoAZQA1gGVAZYBlwGYAZkBmgGbAZwBnQGeAZ8BoAGhAaIBowA5ADoBpAGlAaYBpwA7ADwA6wGoALsBqQGqAasBrAGtAa4APQGvAOYBsAGxAbIBswG0AbUBtgG3AbgBuQG6AbsBvAG9Ab4BvwHAAcEBwgHDAcQBxQHGAccByAHJAcoBywHMAc0BzgHPAdAB0QHSAdMB1AHVAdYB1wHYAdkB2gHbAdwB3QHeAd8B4AHhAeIB4wHkAeUB5gHnAegB6QHqAesB7AHtAe4B7wHwAfEB8gHzAfQB9QH2AfcB+AH5AfoB+wH8Af0B/gH/AgACAQICAgMCBAIFAgYCBwIIAgkCCgILAgwCDQIOAg8CEAIRAhICEwIUAhUCFgIXAhgCGQIaAhsCHAIdAh4CHwIgAiECIgIjAiQCJQImAicCKAIpAioCKwIsAi0CLgIvAjACMQIyAjMCNAI1AjYCNwI4AjkCOgI7AjwCPQI+Aj8CQAJBAkICQwJEAkUCRgBEAGkCRwJIAkkCSgJLAkwCTQBrAk4CTwJQAlECUgJTAGwCVABqAlUCVgJXAlgAbgJZAG0AoAJaAEUARgD+AQAAbwJbAlwCXQBHAOoCXgEBAl8CYAJhAEgAcAJiAmMCZAByAmUCZgJnAmgCaQJqAHMCawJsAHECbQJuAm8CcAJxAnICcwJ0AnUCdgBJAEoA+QJ3AngCeQJ6AnsCfABLAn0CfgJ/AoACgQBMANcAdAKCAHYCgwB3AoQChQKGAHUChwKIAokCigKLAowATQKNAo4ATgKPApACkQBPApICkwKUApUClgKXApgA4wBQApkAUQKaApsCnAKdAp4CnwKgAqECogB4AFIAeQKjAHsCpAKlAqYCpwKoAqkAfAKqAqsCrAB6Aq0CrgKvArACsQKyArMCtAK1ArYCtwK4ArkAoQK6AH0CuwK8Ar0AsQBTAO4AVABVAr4CvwLAAsECwgLDAsQAVgLFAsYCxwDlAsgA/ALJAsoCywLMAs0AiQLOAFcCzwLQAtEC0gLTAtQC1QBYAH4C1gLXAIAC2ACBAtkAfwLaAtsC3ALdAt4C3wLgAuEC4gLjAuQC5QLmAucC6ABZAFoC6QLqAusC7ABbAFwA7ALtALoC7gLvAvAC8QLyAvMAXQL0AOcC9QL2AvcC+AL5AvoC+wL8Av0C/gL/AwADAQMCAwMDBAMFAwYDBwMIAwkDCgMLAwwDDQMOAw8DEAMRAxIDEwMUAxUDFgMXAxgDGQMaAxsDHAMdAx4DHwMgAyEDIgMjAyQDJQMmAycDKAMpAyoDKwMsAy0DLgMvAzADMQMyAzMDNAM1AzYDNwM4AzkDOgM7AzwDPQM+Az8DQANBA0IDQwNEA0UDRgNHA0gDSQNKA0sDTANNA04DTwNQA1EDUgNTAMAAwQNUA1UDVgNXA1gDWQNaA1sDXANdA14DXwNgA2EDYgNjA2QDZQNmA2cDaANpA2oDawNsA20DbgNvA3ADcQNyA3MDdAN1A3YDdwN4A3kDegN7A3wDfQN+A38DgAOBA4IDgwOEA4UDhgOHA4gDiQOKA4sDjAONA44DjwOQA5EDkgOTA5QDlQOWA5cDmAOZA5oDmwOcA50DngOfA6ADoQOiA6MDpAOlA6YDpwOoA6kDqgOrA6wDrQOuA68DsAOxA7IDswO0A7UDtgO3A7gDuQO6A7sDvAO9A74DvwPAA8EDwgPDA8QDxQPGA8cDyAPJA8oDywPMA80DzgPPA9AD0QPSA9MD1APVA9YD1wPYA9kD2gPbA9wD3QPeA98D4APhA+ID4wPkA+UD5gPnA+gD6QPqA+sD7APtA+4D7wPwA/ED8gPzA/QD9QP2A/cD+AP5A/oD+wP8A/0D/gP/BAAEAQQCBAMEBAQFBAYEBwQIBAkECgQLBAwEDQQOBA8EEAQRBBIEEwQUBBUEFgQXBBgEGQQaBBsEHAQdBB4EHwQgBCEEIgQjBCQEJQQmBCcEKAQpBCoEKwQsBC0ELgQvBDAEMQQyBDMENAQ1BDYENwQ4BDkEOgQ7BDwEPQQ+BD8EQARBBEIEQwREBEUERgRHBEgESQRKBEsETARNBE4ETwRQBFEEUgRTBFQEVQRWBFcEWARZBFoEWwRcBF0EXgRfBGAEYQRiBGMEZARlBGYEZwRoBGkEagRrBGwEbQRuBG8EcARxBHIEcwR0BHUEdgR3BHgEeQR6BHsEfAR9BH4EfwSABIEEggSDBIQEhQSGBIcEiASJBIoEiwSMBI0EjgSPBJAEkQSSBJMElASVBJYElwSYBJkEmgSbBJwEnQSeBJ8EoAShBKIEowSkBKUEpgSnBKgEqQSqBKsErAStBK4ErwSwBLEEsgSzBLQEtQS2BLcEuAS5BLoEuwS8BL0EvgS/BMAEwQTCBMMExATFBMYExwTIBMkEygTLBMwEzQTOBM8E0ATRBNIE0wTUBNUE1gTXBNgE2QTaAJ0AngTbBNwE3QTeBN8E4AThBOIE4wTkBOUE5gTnBOgE6QTqBOsE7ATtBO4E7wTwBPEE8gTzBPQE9QT2BPcE+AT5BPoE+wT8BP0E/gT/BQAFAQUCBQMFBAUFBQYFBwUIBQkFCgULBQwFDQUOBQ8FEAURBRIFEwUUBRUFFgUXBRgFGQUaBRsFHAUdBR4FHwUgBSEFIgUjBSQFJQUmBScFKAUpBSoFKwUsBS0FLgUvBTAFMQUyBTMFNAU1BTYFNwU4BTkFOgU7BTwFPQU+BT8FQAVBBUIFQwVEBUUFRgVHBUgFSQVKBUsFTAVNBU4FTwVQBVEFUgVTBVQFVQVWBVcFWAVZBVoFWwVcBV0FXgVfBWAFYQViBWMFZAVlBWYFZwVoBWkFagVrBWwFbQVuBW8FcAVxBXIFcwV0BXUFdgV3BXgFeQV6BXsFfAV9BX4FfwWABYEFggWDBYQFhQWGBYcFiAWJBYoFiwWMBY0FjgWPBZAFkQWSBZMFlAWVBZYFlwWYBZkFmgWbBZwFnQWeBZ8FoAWhBaIFowWkBaUFpgWnBagFqQWqBasFrAWtBa4FrwWwBbEFsgWzBbQFtQW2BbcFuAW5BboFuwW8Bb0FvgW/BcAFwQXCBcMFxAXFBcYFxwXIBckFygXLBcwFzQXOBc8F0AXRBdIF0wXUBdUF1gXXBdgF2QXaBdsF3AXdBd4F3wXgBeEF4gXjBeQF5QXmBecF6AXpBeoF6wXsBe0F7gXvBfAF8QXyBfMF9AX1BfYF9wX4BfkF+gX7BfwF/QX+Bf8GAAYBBgIGAwYEBgUGBgYHBggGCQYKBgsGDAYNBg4GDwYQBhEGEgYTBhQGFQYWBhcGGAYZBhoGGwYcBh0GHgYfBiAGIQYiBiMGJAYlBiYGJwYoBikGKgYrBiwGLQYuBi8GMAYxAJsGMgYzABMAFAAVABYAFwAYABkAGgAbABwGNAY1BjYGNwY4BjkGOgY7BjwGPQY+Bj8GQAZBBkIGQwZEBkUGRgZHBkgGSQZKBksGTAZNBk4GTwZQBlEGUgZTBlQGVQZWBlcGWAZZBloGWwZcBl0GXgZfBmAGYQZiBmMGZAZlBmYGZwZoBmkGagZrBmwGbQZuBm8GcAZxBnIGcwZ0BnUGdgZ3BngGeQZ6BnsGfAZ9Bn4GfwaABoEGggaDALwA9AaEBoUA9QD2BoYGhwaIBokADQA/AMMAhwAdAA8AqwAEAKMABgARACIAogAFAAoAHgASAEIGigaLBowGjQaOBo8AXgBgAD4AQAALAAwGkAaRBpIGkwaUBpUAswCyBpYGlwAQBpgGmQaaBpsGnACpAKoAvgC/AMUAtAC1ALYAtwDEBp0GngafBqAGoQaiBqMGpAalBqYGpwaoBqkGqgarBqwGrQauBq8GsAaxBrIGswa0BrUGtga3BrgGuQa6AIQGuwC9AAcGvAa9AKYA9wa+Br8GwAbBBsIGwwbEBsUGxgbHBsgAhQbJBsoGywCWBswGzQbOAA4A7wDwALgAIACPACEAHwCVAJQAkwCnAGEApAbPAJIAnAbQBtEAmgCZAKUG0gCYAAgAxgbTBtQG1QbWBtcG2AbZBtoG2wbcBt0G3gbfBuAG4QbiALkG4wbkBuUG5gbnBugG6QbqBusG7AAjAAkAiACGAIsAigCMAIMAXwDoBu0AggDCBu4G7wBBBvAG8QbyBvMG9Ab1BvYG9wb4BvkG+gb7BvwG/Qb+Bv8HAAcBBwIHAwcEBwUHBgcHBwgHCQcKBwsHDAcNBw4HDwcQBxEHEgcTBxQHFQcWBxcHGAcZBxoHGwccBx0HHgcfByAHIQciByMHJAclByYHJwcoBykHKgcrBywHLQcuBy8HMAcxBzIHMwc0BzUHNgc3BzgHOQc6BzsHPAc9Bz4HPwdAB0EHQgdDB0QHRQdGB0cHSAdJB0oHSwdMB00HTgdPB1AHUQdSB1MHVAdVB1YHVwdYB1kHWgdbB1wHXQCNANsA4QDeANgAjgDcAEMA3wDaAOAA3QDZB14HXwdgB2EHYgdjB2QHZQdmB2cHaAdpB2oHawdsB20HbgdvB3AHcQdyB3MHdAd1B3YHdwd4BE5VTEwGQWJyZXZlB3VuaTFFQUUHdW5pMUVCNgd1bmkxRUIwB3VuaTFFQjIHdW5pMUVCNAd1bmkwMUNEB3VuaTFFQTQHdW5pMUVBQwd1bmkxRUE2B3VuaTFFQTgHdW5pMUVBQQd1bmkwMjAwB3VuaTFFQTAHdW5pMUVBMgd1bmkwMjAyB0FtYWNyb24HQW9nb25lawpBcmluZ2FjdXRlB0FFYWN1dGUHdW5pMUUwOAtDY2lyY3VtZmxleApDZG90YWNjZW50B3VuaTAxQzQGRGNhcm9uBkRjcm9hdAd1bmkxRTBDB3VuaTFFMEUHdW5pMDFDNQZFYnJldmUGRWNhcm9uB3VuaTFFMUMHdW5pMUVCRQd1bmkxRUM2B3VuaTFFQzAHdW5pMUVDMgd1bmkxRUM0B3VuaTAyMDQKRWRvdGFjY2VudAd1bmkxRUI4B3VuaTFFQkEHdW5pMDIwNgdFbWFjcm9uB3VuaTFFMTYHdW5pMUUxNAdFb2dvbmVrB3VuaTFFQkMHdW5pMDFCNwd1bmkwMUVFBkdjYXJvbgtHY2lyY3VtZmxleAxHY29tbWFhY2NlbnQKR2RvdGFjY2VudAd1bmkxRTIwB3VuaTAxRTQESGJhcgd1bmkxRTJBB3VuaTAyMUULSGNpcmN1bWZsZXgHdW5pMUUyNAJJSgZJYnJldmUHdW5pMDIwOAd1bmkxRTJFB3VuaTFFQ0EHdW5pMUVDOAd1bmkwMjBBB0ltYWNyb24HSW9nb25lawZJdGlsZGULSmNpcmN1bWZsZXgHdW5pMDFFOAxLY29tbWFhY2NlbnQHdW5pMDFDNwZMYWN1dGUGTGNhcm9uDExjb21tYWFjY2VudARMZG90B3VuaTFFMzYHdW5pMDFDOAd1bmkxRTNBB3VuaTFFNDIHdW5pMDFDQQZOYWN1dGUGTmNhcm9uDE5jb21tYWFjY2VudAd1bmkxRTQ0B3VuaTFFNDYDRW5nB3VuaTAxQ0IHdW5pMUU0OAZPYnJldmUHdW5pMUVEMAd1bmkxRUQ4B3VuaTFFRDIHdW5pMUVENAd1bmkxRUQ2B3VuaTAyMEMHdW5pMDIyQQd1bmkwMjMwB3VuaTFFQ0MHdW5pMUVDRQVPaG9ybgd1bmkxRURBB3VuaTFFRTIHdW5pMUVEQwd1bmkxRURFB3VuaTFFRTANT2h1bmdhcnVtbGF1dAd1bmkwMjBFB09tYWNyb24HdW5pMUU1Mgd1bmkxRTUwB3VuaTAxRUELT3NsYXNoYWN1dGUHdW5pMUU0Qwd1bmkxRTRFB3VuaTAyMkMGUmFjdXRlBlJjYXJvbgxSY29tbWFhY2NlbnQHdW5pMDIxMAd1bmkxRTVBB3VuaTAyMTIHdW5pMUU1RQZTYWN1dGUHdW5pMUU2NAd1bmlBNzhCB3VuaTFFNjYLU2NpcmN1bWZsZXgMU2NvbW1hYWNjZW50B3VuaTFFNjAHdW5pMUU2Mgd1bmkxRTY4B3VuaTFFOUUHdW5pMDE4RgRUYmFyBlRjYXJvbgd1bmkwMTYyB3VuaTAyMUEHdW5pMUU2Qwd1bmkxRTZFBlVicmV2ZQd1bmkwMUQzB3VuaTAyMTQHdW5pMUVFNAd1bmkxRUU2BVVob3JuB3VuaTFFRTgHdW5pMUVGMAd1bmkxRUVBB3VuaTFFRUMHdW5pMUVFRQ1VaHVuZ2FydW1sYXV0B3VuaTAyMTYHVW1hY3Jvbgd1bmkxRTdBB1VvZ29uZWsFVXJpbmcGVXRpbGRlB3VuaTFFNzgGV2FjdXRlC1djaXJjdW1mbGV4CVdkaWVyZXNpcwZXZ3JhdmULWWNpcmN1bWZsZXgHdW5pMUU4RQd1bmkxRUY0BllncmF2ZQd1bmkxRUY2B3VuaTAyMzIHdW5pMUVGOAZaYWN1dGUKWmRvdGFjY2VudAd1bmkxRTkyEElhY3V0ZV9KLmxvY2xOTEQGQS5zczAxC0FhY3V0ZS5zczAxC0FicmV2ZS5zczAxDHVuaTFFQUUuc3MwMQx1bmkxRUI2LnNzMDEMdW5pMUVCMC5zczAxDHVuaTFFQjIuc3MwMQx1bmkxRUI0LnNzMDEMdW5pMDFDRC5zczAxEEFjaXJjdW1mbGV4LnNzMDEMdW5pMUVBNC5zczAxDHVuaTFFQUMuc3MwMQx1bmkxRUE2LnNzMDEMdW5pMUVBOC5zczAxDHVuaTFFQUEuc3MwMQx1bmkwMjAwLnNzMDEOQWRpZXJlc2lzLnNzMDEMdW5pMUVBMC5zczAxC0FncmF2ZS5zczAxDHVuaTFFQTIuc3MwMQx1bmkwMjAyLnNzMDEMQW1hY3Jvbi5zczAxDEFvZ29uZWsuc3MwMQpBcmluZy5zczAxD0FyaW5nYWN1dGUuc3MwMQtBdGlsZGUuc3MwMQdBRS5zczAxDEFFYWN1dGUuc3MwMQx1bmkwMUM0LnNzMDEMdW5pMDFDNS5zczAxBkUuc3MwMQtFYWN1dGUuc3MwMQtFYnJldmUuc3MwMQtFY2Fyb24uc3MwMQx1bmkxRTFDLnNzMDEQRWNpcmN1bWZsZXguc3MwMQx1bmkxRUJFLnNzMDEMdW5pMUVDNi5zczAxDHVuaTFFQzAuc3MwMQx1bmkxRUMyLnNzMDEMdW5pMUVDNC5zczAxDHVuaTAyMDQuc3MwMQ5FZGllcmVzaXMuc3MwMQ9FZG90YWNjZW50LnNzMDEMdW5pMUVCOC5zczAxC0VncmF2ZS5zczAxDHVuaTFFQkEuc3MwMQx1bmkwMjA2LnNzMDEMRW1hY3Jvbi5zczAxDHVuaTFFMTYuc3MwMQx1bmkxRTE0LnNzMDEMRW9nb25lay5zczAxDHVuaTFFQkMuc3MwMQZGLnNzMDEGRy5zczAxC0dicmV2ZS5zczAxC0djYXJvbi5zczAxEEdjaXJjdW1mbGV4LnNzMDERR2NvbW1hYWNjZW50LnNzMDEPR2RvdGFjY2VudC5zczAxDHVuaTFFMjAuc3MwMQx1bmkwMUU0LnNzMDEGSS5zczAxB0lKLnNzMDELSWFjdXRlLnNzMDEVSWFjdXRlX0oubG9jbE5MRC5zczAxC0licmV2ZS5zczAxEEljaXJjdW1mbGV4LnNzMDEMdW5pMDIwOC5zczAxDklkaWVyZXNpcy5zczAxDHVuaTFFMkUuc3MwMQ9JZG90YWNjZW50LnNzMDEMdW5pMUVDQS5zczAxC0lncmF2ZS5zczAxDHVuaTFFQzguc3MwMQx1bmkwMjBBLnNzMDEMSW1hY3Jvbi5zczAxDElvZ29uZWsuc3MwMQtJdGlsZGUuc3MwMQZKLnNzMDEQSmNpcmN1bWZsZXguc3MwMQx1bmkwMUM3LnNzMDEGTS5zczAxDHVuaTFFNDIuc3MwMQZOLnNzMDEMdW5pMDFDQS5zczAxC05hY3V0ZS5zczAxC05jYXJvbi5zczAxEU5jb21tYWFjY2VudC5zczAxDHVuaTFFNDQuc3MwMQx1bmkxRTQ2LnNzMDEIRW5nLnNzMDEMdW5pMDFDQi5zczAxDHVuaTFFNDguc3MwMQtOdGlsZGUuc3MwMQZRLnNzMDEMdW5pMDE4Ri5zczAxBlQuc3MwMQlUYmFyLnNzMDELVGNhcm9uLnNzMDEMdW5pMDE2Mi5zczAxDHVuaTAyMUEuc3MwMQx1bmkxRTZDLnNzMDEMdW5pMUU2RS5zczAxBlUuc3MwMQtVYWN1dGUuc3MwMQtVYnJldmUuc3MwMQx1bmkwMUQzLnNzMDEQVWNpcmN1bWZsZXguc3MwMQx1bmkwMjE0LnNzMDEOVWRpZXJlc2lzLnNzMDEMdW5pMUVFNC5zczAxC1VncmF2ZS5zczAxDHVuaTFFRTYuc3MwMQpVaG9ybi5zczAxDHVuaTFFRTguc3MwMQx1bmkxRUYwLnNzMDEMdW5pMUVFQS5zczAxDHVuaTFFRUMuc3MwMQx1bmkxRUVFLnNzMDESVWh1bmdhcnVtbGF1dC5zczAxDHVuaTAyMTYuc3MwMQxVbWFjcm9uLnNzMDEMdW5pMUU3QS5zczAxDFVvZ29uZWsuc3MwMQpVcmluZy5zczAxC1V0aWxkZS5zczAxDHVuaTFFNzguc3MwMQZXLnNzMDELV2FjdXRlLnNzMDEQV2NpcmN1bWZsZXguc3MwMQ5XZGllcmVzaXMuc3MwMQtXZ3JhdmUuc3MwMQZZLnNzMDELWWFjdXRlLnNzMDEQWWNpcmN1bWZsZXguc3MwMQ5ZZGllcmVzaXMuc3MwMQx1bmkxRThFLnNzMDEMdW5pMUVGNC5zczAxC1lncmF2ZS5zczAxDHVuaTFFRjYuc3MwMQx1bmkwMjMyLnNzMDEMdW5pMUVGOC5zczAxBlouc3MwMQtaYWN1dGUuc3MwMQtaY2Fyb24uc3MwMQ9aZG90YWNjZW50LnNzMDEMdW5pMUU5Mi5zczAxBmFicmV2ZQd1bmkxRUFGB3VuaTFFQjcHdW5pMUVCMQd1bmkxRUIzB3VuaTFFQjUHdW5pMDFDRQd1bmkxRUE1B3VuaTFFQUQHdW5pMUVBNwd1bmkxRUE5B3VuaTFFQUIHdW5pMDIwMQd1bmkxRUExB3VuaTFFQTMHdW5pMDIwMwdhbWFjcm9uB2FvZ29uZWsKYXJpbmdhY3V0ZQdhZWFjdXRlB3VuaTFFMDkLY2NpcmN1bWZsZXgKY2RvdGFjY2VudAZkY2Fyb24HdW5pMUUwRAd1bmkxRTBGB3VuaTAxQzYGZWJyZXZlBmVjYXJvbgd1bmkxRTFEB3VuaTFFQkYHdW5pMUVDNwd1bmkxRUMxB3VuaTFFQzMHdW5pMUVDNQd1bmkwMjA1CmVkb3RhY2NlbnQHdW5pMUVCOQd1bmkxRUJCB3VuaTAyMDcHZW1hY3Jvbgd1bmkxRTE3B3VuaTFFMTUHZW9nb25lawd1bmkxRUJEB3VuaTAyNTkHdW5pMDI5Mgd1bmkwMUVGBmdjYXJvbgtnY2lyY3VtZmxleAxnY29tbWFhY2NlbnQKZ2RvdGFjY2VudAd1bmkxRTIxB3VuaTAxRTUEaGJhcgd1bmkxRTJCB3VuaTAyMUYLaGNpcmN1bWZsZXgHdW5pMUUyNQZpYnJldmUHdW5pMDIwOQd1bmkxRTJGCWkubG9jbFRSSwd1bmkxRUNCB3VuaTFFQzkHdW5pMDIwQgJpagdpbWFjcm9uB2lvZ29uZWsGaXRpbGRlB3VuaTAyMzcLamNpcmN1bWZsZXgHdW5pMDFFOQxrY29tbWFhY2NlbnQMa2dyZWVubGFuZGljBmxhY3V0ZQZsY2Fyb24MbGNvbW1hYWNjZW50BGxkb3QHdW5pMUUzNwd1bmkwMUM5B3VuaTFFM0IHdW5pMUU0MwZuYWN1dGULbmFwb3N0cm9waGUGbmNhcm9uDG5jb21tYWFjY2VudAd1bmkxRTQ1B3VuaTFFNDcDZW5nB3VuaTAxQ0MHdW5pMUU0OQZvYnJldmUHdW5pMUVEMQd1bmkxRUQ5B3VuaTFFRDMHdW5pMUVENQd1bmkxRUQ3B3VuaTAyMEQHdW5pMDIyQgd1bmkwMjMxB3VuaTFFQ0QHdW5pMUVDRgVvaG9ybgd1bmkxRURCB3VuaTFFRTMHdW5pMUVERAd1bmkxRURGB3VuaTFFRTENb2h1bmdhcnVtbGF1dAd1bmkwMjBGB29tYWNyb24HdW5pMUU1Mwd1bmkxRTUxB3VuaTAxRUILb3NsYXNoYWN1dGUHdW5pMUU0RAd1bmkxRTRGB3VuaTAyMkQGcmFjdXRlBnJjYXJvbgxyY29tbWFhY2NlbnQHdW5pMDIxMQd1bmkxRTVCB3VuaTAyMTMHdW5pMUU1RgZzYWN1dGUHdW5pMUU2NQd1bmlBNzhDB3VuaTFFNjcLc2NpcmN1bWZsZXgMc2NvbW1hYWNjZW50B3VuaTFFNjEHdW5pMUU2Mwd1bmkxRTY5BWxvbmdzBHRiYXIGdGNhcm9uB3VuaTAxNjMHdW5pMDIxQgd1bmkxRTk3B3VuaTFFNkQHdW5pMUU2RgZ1YnJldmUHdW5pMDFENAd1bmkwMjE1B3VuaTFFRTUHdW5pMUVFNwV1aG9ybgd1bmkxRUU5B3VuaTFFRjEHdW5pMUVFQgd1bmkxRUVEB3VuaTFFRUYNdWh1bmdhcnVtbGF1dAd1bmkwMjE3B3VtYWNyb24HdW5pMUU3Qgd1b2dvbmVrBXVyaW5nBnV0aWxkZQd1bmkxRTc5BndhY3V0ZQt3Y2lyY3VtZmxleAl3ZGllcmVzaXMGd2dyYXZlC3ljaXJjdW1mbGV4B3VuaTFFOEYHdW5pMUVGNQZ5Z3JhdmUHdW5pMUVGNwd1bmkwMjMzB3VuaTFFRjkGemFjdXRlCnpkb3RhY2NlbnQHdW5pMUU5MxBpYWN1dGVfai5sb2NsTkxEBmEuc3MwMQthYWN1dGUuc3MwMQthYnJldmUuc3MwMQx1bmkxRUFGLnNzMDEMdW5pMUVCNy5zczAxDHVuaTFFQjEuc3MwMQx1bmkxRUIzLnNzMDEMdW5pMUVCNS5zczAxDHVuaTAxQ0Uuc3MwMRBhY2lyY3VtZmxleC5zczAxDHVuaTFFQTUuc3MwMQx1bmkxRUFELnNzMDEMdW5pMUVBNy5zczAxDHVuaTFFQTkuc3MwMQx1bmkxRUFCLnNzMDEMdW5pMDIwMS5zczAxDmFkaWVyZXNpcy5zczAxDHVuaTFFQTEuc3MwMQthZ3JhdmUuc3MwMQx1bmkxRUEzLnNzMDEMdW5pMDIwMy5zczAxDGFtYWNyb24uc3MwMQxhb2dvbmVrLnNzMDEKYXJpbmcuc3MwMQ9hcmluZ2FjdXRlLnNzMDELYXRpbGRlLnNzMDEHYWUuc3MwMQxhZWFjdXRlLnNzMDEMdW5pMDFDNi5zczAxBmUuc3MwMQtlYWN1dGUuc3MwMQtlYnJldmUuc3MwMQtlY2Fyb24uc3MwMQx1bmkxRTFELnNzMDEQZWNpcmN1bWZsZXguc3MwMQx1bmkxRUJGLnNzMDEMdW5pMUVDNy5zczAxDHVuaTFFQzEuc3MwMQx1bmkxRUMzLnNzMDEMdW5pMUVDNS5zczAxDHVuaTAyMDUuc3MwMQ5lZGllcmVzaXMuc3MwMQ9lZG90YWNjZW50LnNzMDEMdW5pMUVCOS5zczAxC2VncmF2ZS5zczAxDHVuaTFFQkIuc3MwMQx1bmkwMjA3LnNzMDEMZW1hY3Jvbi5zczAxDHVuaTFFMTcuc3MwMQx1bmkxRTE1LnNzMDEMZW9nb25lay5zczAxDHVuaTFFQkQuc3MwMQx1bmkwMjU5LnNzMDEGZi5zczAxBmwuc3MwMQtsYWN1dGUuc3MwMQtsY2Fyb24uc3MwMRFsY29tbWFhY2NlbnQuc3MwMQlsZG90LnNzMDEMdW5pMUUzNy5zczAxDHVuaTAxQzkuc3MwMQx1bmkxRTNCLnNzMDELbHNsYXNoLnNzMDEHb2Uuc3MwMQZ0LnNzMDEJdGJhci5zczAxC3RjYXJvbi5zczAxDHVuaTAxNjMuc3MwMQx1bmkwMjFCLnNzMDEMdW5pMUU5Ny5zczAxDHVuaTFFNkQuc3MwMQx1bmkxRTZGLnNzMDEGdy5zczAxC3dhY3V0ZS5zczAxEHdjaXJjdW1mbGV4LnNzMDEOd2RpZXJlc2lzLnNzMDELd2dyYXZlLnNzMDEGeS5zczAxC3lhY3V0ZS5zczAxEHljaXJjdW1mbGV4LnNzMDEOeWRpZXJlc2lzLnNzMDEMdW5pMUVGNS5zczAxC3lncmF2ZS5zczAxDHVuaTFFRjcuc3MwMQx1bmkwMjMzLnNzMDEMdW5pMUVGOS5zczAxBnouc3MwMQt6YWN1dGUuc3MwMQt6Y2Fyb24uc3MwMQ96ZG90YWNjZW50LnNzMDEMdW5pMUU5My5zczAxA1RfaAdmaS5zczAxB2ZsLnNzMDEEYS5zYwlhYWN1dGUuc2MJYWJyZXZlLnNjCnVuaTFFQUYuc2MKdW5pMUVCNy5zYwp1bmkxRUIxLnNjCnVuaTFFQjMuc2MKdW5pMUVCNS5zYwp1bmkwMUNFLnNjDmFjaXJjdW1mbGV4LnNjCnVuaTFFQTUuc2MKdW5pMUVBRC5zYwp1bmkxRUE3LnNjCnVuaTFFQTkuc2MKdW5pMUVBQi5zYwp1bmkwMjAxLnNjDGFkaWVyZXNpcy5zYwp1bmkxRUExLnNjCWFncmF2ZS5zYwp1bmkxRUEzLnNjCnVuaTAyMDMuc2MKYW1hY3Jvbi5zYwphb2dvbmVrLnNjCGFyaW5nLnNjDWFyaW5nYWN1dGUuc2MJYXRpbGRlLnNjBWFlLnNjCmFlYWN1dGUuc2MEYi5zYwRjLnNjCWNhY3V0ZS5zYwljY2Fyb24uc2MLY2NlZGlsbGEuc2MKdW5pMUUwOS5zYw5jY2lyY3VtZmxleC5zYw1jZG90YWNjZW50LnNjBGQuc2MGZXRoLnNjCWRjYXJvbi5zYwlkY3JvYXQuc2MKdW5pMUUwRC5zYwp1bmkxRTBGLnNjCnVuaTAxQzYuc2MEZS5zYwllYWN1dGUuc2MJZWJyZXZlLnNjCWVjYXJvbi5zYwp1bmkxRTFELnNjDmVjaXJjdW1mbGV4LnNjCnVuaTFFQkYuc2MKdW5pMUVDNy5zYwp1bmkxRUMxLnNjCnVuaTFFQzMuc2MKdW5pMUVDNS5zYwp1bmkwMjA1LnNjDGVkaWVyZXNpcy5zYw1lZG90YWNjZW50LnNjCnVuaTFFQjkuc2MJZWdyYXZlLnNjCnVuaTFFQkIuc2MKdW5pMDIwNy5zYwplbWFjcm9uLnNjCnVuaTFFMTcuc2MKdW5pMUUxNS5zYwplb2dvbmVrLnNjCnVuaTFFQkQuc2MKdW5pMDI1OS5zYwp1bmkwMjkyLnNjCnVuaTAxRUYuc2MEZi5zYwRnLnNjCWdicmV2ZS5zYwlnY2Fyb24uc2MOZ2NpcmN1bWZsZXguc2MPZ2NvbW1hYWNjZW50LnNjDWdkb3RhY2NlbnQuc2MKdW5pMUUyMS5zYwp1bmkwMUU1LnNjBGguc2MHaGJhci5zYwp1bmkxRTJCLnNjCnVuaTAyMUYuc2MOaGNpcmN1bWZsZXguc2MKdW5pMUUyNS5zYwRpLnNjC2RvdGxlc3NpLnNjCWlhY3V0ZS5zYxNpYWN1dGVfai5sb2NsTkxELnNjCWlicmV2ZS5zYw5pY2lyY3VtZmxleC5zYwp1bmkwMjA5LnNjDGlkaWVyZXNpcy5zYwp1bmkxRTJGLnNjDGkuc2MubG9jbFRSSwp1bmkxRUNCLnNjCWlncmF2ZS5zYwp1bmkxRUM5LnNjCnVuaTAyMEIuc2MFaWouc2MKaW1hY3Jvbi5zYwppb2dvbmVrLnNjCWl0aWxkZS5zYwRqLnNjDmpjaXJjdW1mbGV4LnNjBGsuc2MKdW5pMDFFOS5zYw9rY29tbWFhY2NlbnQuc2MPa2dyZWVubGFuZGljLnNjBGwuc2MJbGFjdXRlLnNjCWxjYXJvbi5zYw9sY29tbWFhY2NlbnQuc2MHbGRvdC5zYwp1bmkxRTM3LnNjCnVuaTAxQzkuc2MKdW5pMUUzQi5zYwlsc2xhc2guc2MEbS5zYwp1bmkxRTQzLnNjBG4uc2MJbmFjdXRlLnNjCW5jYXJvbi5zYw9uY29tbWFhY2NlbnQuc2MKdW5pMUU0NS5zYwp1bmkxRTQ3LnNjBmVuZy5zYwp1bmkwMUNDLnNjCnVuaTFFNDkuc2MJbnRpbGRlLnNjBG8uc2MJb2FjdXRlLnNjCW9icmV2ZS5zYw5vY2lyY3VtZmxleC5zYwp1bmkxRUQxLnNjCnVuaTFFRDkuc2MKdW5pMUVEMy5zYwp1bmkxRUQ1LnNjCnVuaTFFRDcuc2MKdW5pMDIwRC5zYwxvZGllcmVzaXMuc2MKdW5pMDIyQi5zYwp1bmkwMjMxLnNjCnVuaTFFQ0Quc2MJb2dyYXZlLnNjCnVuaTFFQ0Yuc2MIb2hvcm4uc2MKdW5pMUVEQi5zYwp1bmkxRUUzLnNjCnVuaTFFREQuc2MKdW5pMUVERi5zYwp1bmkxRUUxLnNjEG9odW5nYXJ1bWxhdXQuc2MKdW5pMDIwRi5zYwpvbWFjcm9uLnNjCnVuaTFFNTMuc2MKdW5pMUU1MS5zYwp1bmkwMUVCLnNjCW9zbGFzaC5zYw5vc2xhc2hhY3V0ZS5zYwlvdGlsZGUuc2MKdW5pMUU0RC5zYwp1bmkxRTRGLnNjCnVuaTAyMkQuc2MFb2Uuc2MEcC5zYwh0aG9ybi5zYwRxLnNjBHIuc2MJcmFjdXRlLnNjCXJjYXJvbi5zYw9yY29tbWFhY2NlbnQuc2MKdW5pMDIxMS5zYwp1bmkxRTVCLnNjCnVuaTAyMTMuc2MKdW5pMUU1Ri5zYwRzLnNjCXNhY3V0ZS5zYwp1bmkxRTY1LnNjCnVuaUE3OEMuc2MJc2Nhcm9uLnNjCnVuaTFFNjcuc2MLc2NlZGlsbGEuc2MOc2NpcmN1bWZsZXguc2MPc2NvbW1hYWNjZW50LnNjCnVuaTFFNjEuc2MKdW5pMUU2My5zYwp1bmkxRTY5LnNjDWdlcm1hbmRibHMuc2MEdC5zYwd0YmFyLnNjCXRjYXJvbi5zYwp1bmkwMTYzLnNjCnVuaTAyMUIuc2MKdW5pMUU5Ny5zYwp1bmkxRTZELnNjCnVuaTFFNkYuc2MEdS5zYwl1YWN1dGUuc2MJdWJyZXZlLnNjCnVuaTAxRDQuc2MOdWNpcmN1bWZsZXguc2MKdW5pMDIxNS5zYwx1ZGllcmVzaXMuc2MKdW5pMUVFNS5zYwl1Z3JhdmUuc2MKdW5pMUVFNy5zYwh1aG9ybi5zYwp1bmkxRUU5LnNjCnVuaTFFRjEuc2MKdW5pMUVFQi5zYwp1bmkxRUVELnNjCnVuaTFFRUYuc2MQdWh1bmdhcnVtbGF1dC5zYwp1bmkwMjE3LnNjCnVtYWNyb24uc2MKdW5pMUU3Qi5zYwp1b2dvbmVrLnNjCHVyaW5nLnNjCXV0aWxkZS5zYwp1bmkxRTc5LnNjBHYuc2MEdy5zYwl3YWN1dGUuc2MOd2NpcmN1bWZsZXguc2MMd2RpZXJlc2lzLnNjCXdncmF2ZS5zYwR4LnNjBHkuc2MJeWFjdXRlLnNjDnljaXJjdW1mbGV4LnNjDHlkaWVyZXNpcy5zYwp1bmkxRThGLnNjCnVuaTFFRjUuc2MJeWdyYXZlLnNjCnVuaTFFRjcuc2MKdW5pMDIzMy5zYwp1bmkxRUY5LnNjBHouc2MJemFjdXRlLnNjCXpjYXJvbi5zYw16ZG90YWNjZW50LnNjCnVuaTFFOTMuc2MJYS5zYy5zczAxDmFhY3V0ZS5zYy5zczAxDmFicmV2ZS5zYy5zczAxD3VuaTFFQUYuc2Muc3MwMQ91bmkxRUI3LnNjLnNzMDEPdW5pMUVCMS5zYy5zczAxD3VuaTFFQjMuc2Muc3MwMQ91bmkxRUI1LnNjLnNzMDEPdW5pMDFDRS5zYy5zczAxE2FjaXJjdW1mbGV4LnNjLnNzMDEPdW5pMUVBNS5zYy5zczAxD3VuaTFFQUQuc2Muc3MwMQ91bmkxRUE3LnNjLnNzMDEPdW5pMUVBOS5zYy5zczAxD3VuaTFFQUIuc2Muc3MwMQ91bmkwMjAxLnNjLnNzMDERYWRpZXJlc2lzLnNjLnNzMDEPdW5pMUVBMS5zYy5zczAxDmFncmF2ZS5zYy5zczAxD3VuaTFFQTMuc2Muc3MwMQ91bmkwMjAzLnNjLnNzMDEPYW1hY3Jvbi5zYy5zczAxD2FvZ29uZWsuc2Muc3MwMQ1hcmluZy5zYy5zczAxEmFyaW5nYWN1dGUuc2Muc3MwMQ5hdGlsZGUuc2Muc3MwMQphZS5zYy5zczAxD2FlYWN1dGUuc2Muc3MwMQ91bmkwMUM2LnNjLnNzMDEJZS5zYy5zczAxDmVhY3V0ZS5zYy5zczAxDmVicmV2ZS5zYy5zczAxDmVjYXJvbi5zYy5zczAxD3VuaTFFMUQuc2Muc3MwMRNlY2lyY3VtZmxleC5zYy5zczAxD3VuaTFFQkYuc2Muc3MwMQ91bmkxRUM3LnNjLnNzMDEPdW5pMUVDMS5zYy5zczAxD3VuaTFFQzMuc2Muc3MwMQ91bmkxRUM1LnNjLnNzMDEPdW5pMDIwNS5zYy5zczAxEWVkaWVyZXNpcy5zYy5zczAxEmVkb3RhY2NlbnQuc2Muc3MwMQ91bmkxRUI5LnNjLnNzMDEOZWdyYXZlLnNjLnNzMDEPdW5pMUVCQi5zYy5zczAxD3VuaTAyMDcuc2Muc3MwMQ9lbWFjcm9uLnNjLnNzMDEPdW5pMUUxNy5zYy5zczAxD3VuaTFFMTUuc2Muc3MwMQ9lb2dvbmVrLnNjLnNzMDEPdW5pMUVCRC5zYy5zczAxD3VuaTAyNTkuc2Muc3MwMQlmLnNjLnNzMDEJZy5zYy5zczAxDmdicmV2ZS5zYy5zczAxDmdjYXJvbi5zYy5zczAxE2djaXJjdW1mbGV4LnNjLnNzMDEUZ2NvbW1hYWNjZW50LnNjLnNzMDESZ2RvdGFjY2VudC5zYy5zczAxD3VuaTFFMjEuc2Muc3MwMQ91bmkwMUU1LnNjLnNzMDEJaS5zYy5zczAxEGRvdGxlc3NpLnNjLnNzMDEOaWFjdXRlLnNjLnNzMDEYaWFjdXRlX2oubG9jbE5MRC5zYy5zczAxDmlicmV2ZS5zYy5zczAxE2ljaXJjdW1mbGV4LnNjLnNzMDEPdW5pMDIwOS5zYy5zczAxEWlkaWVyZXNpcy5zYy5zczAxD3VuaTFFMkYuc2Muc3MwMQ91bmkxRUNCLnNjLnNzMDEOaWdyYXZlLnNjLnNzMDEPdW5pMUVDOS5zYy5zczAxD3VuaTAyMEIuc2Muc3MwMQppai5zYy5zczAxD2ltYWNyb24uc2Muc3MwMQ9pb2dvbmVrLnNjLnNzMDEOaXRpbGRlLnNjLnNzMDEJai5zYy5zczAxE2pjaXJjdW1mbGV4LnNjLnNzMDEPdW5pMDFDOS5zYy5zczAxCW0uc2Muc3MwMQ91bmkxRTQzLnNjLnNzMDEJbi5zYy5zczAxDm5hY3V0ZS5zYy5zczAxDm5jYXJvbi5zYy5zczAxFG5jb21tYWFjY2VudC5zYy5zczAxD3VuaTFFNDUuc2Muc3MwMQ91bmkxRTQ3LnNjLnNzMDELZW5nLnNjLnNzMDEPdW5pMDFDQy5zYy5zczAxD3VuaTFFNDkuc2Muc3MwMQ5udGlsZGUuc2Muc3MwMQlxLnNjLnNzMDEJdC5zYy5zczAxDHRiYXIuc2Muc3MwMQ50Y2Fyb24uc2Muc3MwMQ91bmkwMTYzLnNjLnNzMDEPdW5pMDIxQi5zYy5zczAxD3VuaTFFOTcuc2Muc3MwMQ91bmkxRTZELnNjLnNzMDEPdW5pMUU2Ri5zYy5zczAxCXUuc2Muc3MwMQ51YWN1dGUuc2Muc3MwMQ51YnJldmUuc2Muc3MwMQ91bmkwMUQ0LnNjLnNzMDETdWNpcmN1bWZsZXguc2Muc3MwMQ91bmkwMjE1LnNjLnNzMDERdWRpZXJlc2lzLnNjLnNzMDEPdW5pMUVFNS5zYy5zczAxDnVncmF2ZS5zYy5zczAxD3VuaTFFRTcuc2Muc3MwMQ11aG9ybi5zYy5zczAxD3VuaTFFRTkuc2Muc3MwMQ91bmkxRUYxLnNjLnNzMDEPdW5pMUVFQi5zYy5zczAxD3VuaTFFRUQuc2Muc3MwMQ91bmkxRUVGLnNjLnNzMDEVdWh1bmdhcnVtbGF1dC5zYy5zczAxD3VuaTAyMTcuc2Muc3MwMQ91bWFjcm9uLnNjLnNzMDEPdW5pMUU3Qi5zYy5zczAxD3VvZ29uZWsuc2Muc3MwMQ11cmluZy5zYy5zczAxDnV0aWxkZS5zYy5zczAxD3VuaTFFNzkuc2Muc3MwMQl3LnNjLnNzMDEOd2FjdXRlLnNjLnNzMDETd2NpcmN1bWZsZXguc2Muc3MwMRF3ZGllcmVzaXMuc2Muc3MwMQ53Z3JhdmUuc2Muc3MwMQl5LnNjLnNzMDEOeWFjdXRlLnNjLnNzMDETeWNpcmN1bWZsZXguc2Muc3MwMRF5ZGllcmVzaXMuc2Muc3MwMQ91bmkxRThGLnNjLnNzMDEPdW5pMUVGNS5zYy5zczAxDnlncmF2ZS5zYy5zczAxD3VuaTFFRjcuc2Muc3MwMQ91bmkwMjMzLnNjLnNzMDEPdW5pMUVGOS5zYy5zczAxCXouc2Muc3MwMQ56YWN1dGUuc2Muc3MwMQ56Y2Fyb24uc2Muc3MwMRJ6ZG90YWNjZW50LnNjLnNzMDEPdW5pMUU5My5zYy5zczAxB3VuaTA0MTAHdW5pMDQxMQd1bmkwNDEyB3VuaTA0MTMHdW5pMDQwMwd1bmkwNDkwB3VuaTA0MTQHdW5pMDQxNQd1bmkwNDAwB3VuaTA0MDEHdW5pMDQxNgd1bmkwNDE3B3VuaTA0MTgHdW5pMDQxOQd1bmkwNDBEB3VuaTA0OEEHdW5pMDQxQQd1bmkwNDBDB3VuaTA0MUIHdW5pMDQxQwd1bmkwNDFEB3VuaTA0MUUHdW5pMDQxRgd1bmkwNDIwB3VuaTA0MjEHdW5pMDQyMgd1bmkwNDIzB3VuaTA0MEUHdW5pMDQyNAd1bmkwNDI1B3VuaTA0MjcHdW5pMDQyNgd1bmkwNDI4B3VuaTA0MjkHdW5pMDQwRgd1bmkwNDJDB3VuaTA0MkEHdW5pMDQyQgd1bmkwNDA5B3VuaTA0MEEHdW5pMDQwNQd1bmkwNDA0B3VuaTA0MkQHdW5pMDQwNgd1bmkwNDA3B3VuaTA0MDgHdW5pMDQwQgd1bmkwNDJFB3VuaTA0MkYHdW5pMDQwMgd1bmkwNDYyB3VuaTA0NkEHdW5pMDQ3Mgd1bmkwNDc0B3VuaTA0OTIHdW5pMDQ5NAd1bmkwNDk2B3VuaTA0OTgHdW5pMDQ5QQd1bmkwNDlDB3VuaTA0OUUHdW5pMDRBMAd1bmkwNEEyB3VuaTA0QTQHdW5pMDRBNgd1bmkwNTI0B3VuaTA0QTgHdW5pMDRBQQd1bmkwNEFDB3VuaTA0QUUHdW5pMDRCMAd1bmkwNEIyB3VuaTA0QjQHdW5pMDRCNgd1bmkwNEI4B3VuaTA0QkEHdW5pMDUyNgd1bmkwNEJDB3VuaTA0QkUHdW5pMDRDMAd1bmkwNEMxB3VuaTA0QzMHdW5pMDRDNwd1bmkwNEM5B3VuaTA0Q0IHdW5pMDRDRAd1bmkwNEQwB3VuaTA0RDIHdW5pMDRENAd1bmkwNEQ2B3VuaTA0RDgHdW5pMDREQQd1bmkwNERDB3VuaTA0REUHdW5pMDRFMAd1bmkwNEUyB3VuaTA0RTQHdW5pMDRFNgd1bmkwNEU4B3VuaTA0RUEHdW5pMDRFQwd1bmkwNEVFB3VuaTA0RjAHdW5pMDRGMgd1bmkwNEY0B3VuaTA0RjYHdW5pMDRGOAd1bmkwNEZBB3VuaTA0RkMHdW5pMDRGRQd1bmkwNTEwB3VuaTA1MTIHdW5pMDUxQQd1bmkwNTFDB3VuaTA0OEMHdW5pMDQ4RQd1bmkwNTI4B3VuaTA1MkUPdW5pMDQxNC5sb2NsQkdSD3VuaTA0MUIubG9jbEJHUg91bmkwNDI0LmxvY2xCR1IPdW5pMDQ5Mi5sb2NsQlNID3VuaTA0OTgubG9jbEJTSA91bmkwNEFBLmxvY2xCU0gPdW5pMDRBQS5sb2NsQ0hVDHVuaTA0MTAuc3MwMQx1bmkwNDE0LnNzMDEMdW5pMDQxNS5zczAxDHVuaTA0MDAuc3MwMQx1bmkwNDAxLnNzMDEMdW5pMDQxOC5zczAxDHVuaTA0MTkuc3MwMQx1bmkwNDhBLnNzMDEMdW5pMDQwRC5zczAxDHVuaTA0MUIuc3MwMQx1bmkwNDIwLnNzMDEMdW5pMDQyMi5zczAxDHVuaTA0MjMuc3MwMQx1bmkwNDBFLnNzMDEMdW5pMDQyNC5zczAxDHVuaTA0MkMuc3MwMQx1bmkwNDJBLnNzMDEMdW5pMDQyQi5zczAxDHVuaTA0MDkuc3MwMQx1bmkwNDBBLnNzMDEMdW5pMDQwOC5zczAxDHVuaTA0NjIuc3MwMQx1bmkwNEFDLnNzMDEMdW5pMDREMC5zczAxDHVuaTA0RDIuc3MwMQx1bmkwNEQ0LnNzMDEMdW5pMDRENi5zczAxDHVuaTA0RTIuc3MwMQx1bmkwNEU0LnNzMDEMdW5pMDRFRS5zczAxDHVuaTA0RjAuc3MwMQx1bmkwNEYyLnNzMDEMdW5pMDRGOC5zczAxDHVuaTA1MUEuc3MwMQx1bmkwNDhDLnNzMDEHdW5pMDQzMAd1bmkwNDMxB3VuaTA0MzIHdW5pMDQzMwd1bmkwNDUzB3VuaTA0OTEHdW5pMDQzNAd1bmkwNDM1B3VuaTA0NTAHdW5pMDQ1MQd1bmkwNDM2B3VuaTA0MzcHdW5pMDQzOAd1bmkwNDM5B3VuaTA0NUQHdW5pMDQ4Qgd1bmkwNDNBB3VuaTA0NUMHdW5pMDQzQgd1bmkwNDNDB3VuaTA0M0QHdW5pMDQzRQd1bmkwNDNGB3VuaTA0NDAHdW5pMDQ0MQd1bmkwNDQyB3VuaTA0NDMHdW5pMDQ1RQd1bmkwNDQ0B3VuaTA0NDUHdW5pMDQ0Nwd1bmkwNDQ2B3VuaTA0NDgHdW5pMDQ0OQd1bmkwNDVGB3VuaTA0NEMHdW5pMDQ0QQd1bmkwNDRCB3VuaTA0NTkHdW5pMDQ1QQd1bmkwNDU1B3VuaTA0NTQHdW5pMDQ0RAd1bmkwNDU2B3VuaTA0NTcHdW5pMDQ1OAd1bmkwNDVCB3VuaTA0NEUHdW5pMDQ0Rgd1bmkwNDUyB3VuaTA0NjMHdW5pMDQ2Qgd1bmkwNDczB3VuaTA0NzUHdW5pMDQ5Mwd1bmkwNDk1B3VuaTA0OTcHdW5pMDQ5OQd1bmkwNDlCB3VuaTA0OUQHdW5pMDQ5Rgd1bmkwNEExB3VuaTA0QTMHdW5pMDRBNQd1bmkwNTI1B3VuaTA0QTcHdW5pMDRBOQd1bmkwNEFCB3VuaTA0QUQHdW5pMDRBRgd1bmkwNEIxB3VuaTA0QjMHdW5pMDRCNQd1bmkwNEI3B3VuaTA0QjkHdW5pMDRCQgd1bmkwNTI3B3VuaTA0QkQHdW5pMDRCRgd1bmkwNENGB3VuaTA0QzIHdW5pMDRDNAd1bmkwNEM2B3VuaTA0QzgHdW5pMDRDQQd1bmkwNENDB3VuaTA0Q0UHdW5pMDREMQd1bmkwNEQzB3VuaTA0RDUHdW5pMDRENwd1bmkwNEQ5B3VuaTA0REIHdW5pMDRERAd1bmkwNERGB3VuaTA0RTEHdW5pMDRFMwd1bmkwNEU1B3VuaTA0RTcHdW5pMDRFOQd1bmkwNEVCB3VuaTA0RUQHdW5pMDRFRgd1bmkwNEYxB3VuaTA0RjMHdW5pMDRGNQd1bmkwNEY3B3VuaTA0RjkHdW5pMDRGQgd1bmkwNEZEB3VuaTA0RkYHdW5pMDUxMQd1bmkwNTEzB3VuaTA1MUIHdW5pMDUxRAd1bmkwNDhEB3VuaTA0OEYHdW5pMDUyOQd1bmkwNTJGD3VuaTA0MzIubG9jbEJHUg91bmkwNDMzLmxvY2xCR1IPdW5pMDQzNC5sb2NsQkdSD3VuaTA0MzYubG9jbEJHUg91bmkwNDM3LmxvY2xCR1IPdW5pMDQzOC5sb2NsQkdSD3VuaTA0MzkubG9jbEJHUg91bmkwNDVELmxvY2xCR1IPdW5pMDQzQS5sb2NsQkdSD3VuaTA0M0IubG9jbEJHUg91bmkwNDNELmxvY2xCR1IPdW5pMDQzRi5sb2NsQkdSD3VuaTA0NDIubG9jbEJHUg91bmkwNDQ3LmxvY2xCR1IPdW5pMDQ0Ni5sb2NsQkdSD3VuaTA0NDgubG9jbEJHUg91bmkwNDQ5LmxvY2xCR1IPdW5pMDQ0Qy5sb2NsQkdSD3VuaTA0NEEubG9jbEJHUg91bmkwNDRFLmxvY2xCR1IPdW5pMDQ5My5sb2NsQlNID3VuaTA0OTkubG9jbEJTSA91bmkwNEFCLmxvY2xDSFUPdW5pMDQ1My5sb2NsTUtED3VuaTA0MzEubG9jbFNSQg91bmkwNDMzLmxvY2xTUkIPdW5pMDQzNC5sb2NsU1JCD3VuaTA0M0YubG9jbFNSQg91bmkwNDQyLmxvY2xTUkIMdW5pMDQzMC5zczAxDHVuaTA0MzQuc3MwMQx1bmkwNDM1LnNzMDEMdW5pMDQ1MC5zczAxDHVuaTA0NTEuc3MwMQx1bmkwNDM4LnNzMDEMdW5pMDQzOS5zczAxDHVuaTA0OEIuc3MwMQx1bmkwNDVELnNzMDEMdW5pMDQ0MC5zczAxDHVuaTA0NDIuc3MwMQx1bmkwNDQzLnNzMDEMdW5pMDQ1RS5zczAxDHVuaTA0NEMuc3MwMQx1bmkwNDRBLnNzMDEMdW5pMDQ0Qi5zczAxDHVuaTA0NTkuc3MwMQx1bmkwNDVBLnNzMDEMdW5pMDQ2My5zczAxDHVuaTA0RDEuc3MwMQx1bmkwNEQzLnNzMDEMdW5pMDRENS5zczAxDHVuaTA0RDcuc3MwMQx1bmkwNEQ5LnNzMDEMdW5pMDREQi5zczAxDHVuaTA0RTMuc3MwMQx1bmkwNEU1LnNzMDEMdW5pMDRFRi5zczAxDHVuaTA0RjEuc3MwMQx1bmkwNEYzLnNzMDEMdW5pMDRGOS5zczAxDHVuaTA0OEQuc3MwMQd1bmkwMzk0B3VuaTAzQTkHdW5pMDNCQwd1bmkyMTJCB3VuaTIxMkEIemVyby5vc2YHb25lLm9zZgd0d28ub3NmCXRocmVlLm9zZghmb3VyLm9zZghmaXZlLm9zZgdzaXgub3NmCXNldmVuLm9zZgllaWdodC5vc2YIbmluZS5vc2YJemVyby5zaW5mCG9uZS5zaW5mCHR3by5zaW5mCnRocmVlLnNpbmYJZm91ci5zaW5mCWZpdmUuc2luZghzaXguc2luZgpzZXZlbi5zaW5mCmVpZ2h0LnNpbmYJbmluZS5zaW5mB3plcm8udGYGb25lLnRmBnR3by50Zgh0aHJlZS50Zgdmb3VyLnRmB2ZpdmUudGYGc2l4LnRmCHNldmVuLnRmCGVpZ2h0LnRmB25pbmUudGYJemVyby50b3NmCG9uZS50b3NmCHR3by50b3NmCnRocmVlLnRvc2YJZm91ci50b3NmCWZpdmUudG9zZghzaXgudG9zZgpzZXZlbi50b3NmCmVpZ2h0LnRvc2YJbmluZS50b3NmB3VuaTIwODAHdW5pMjA4MQd1bmkyMDgyB3VuaTIwODMHdW5pMjA4NAd1bmkyMDg1B3VuaTIwODYHdW5pMjA4Nwd1bmkyMDg4B3VuaTIwODkJemVyby5kbm9tCG9uZS5kbm9tCHR3by5kbm9tCnRocmVlLmRub20JZm91ci5kbm9tCWZpdmUuZG5vbQhzaXguZG5vbQpzZXZlbi5kbm9tCmVpZ2h0LmRub20JbmluZS5kbm9tCXplcm8ubnVtcghvbmUubnVtcgh0d28ubnVtcgp0aHJlZS5udW1yCWZvdXIubnVtcglmaXZlLm51bXIIc2l4Lm51bXIKc2V2ZW4ubnVtcgplaWdodC5udW1yCW5pbmUubnVtcgd1bmkyMDcwB3VuaTAwQjkHdW5pMDBCMgd1bmkwMEIzB3VuaTIwNzQHdW5pMjA3NQd1bmkyMDc2B3VuaTIwNzcHdW5pMjA3OAd1bmkyMDc5B3VuaTIxNTMHdW5pMjE1NAlvbmVlaWdodGgMdGhyZWVlaWdodGhzC2ZpdmVlaWdodGhzDHNldmVuZWlnaHRocw5iYWNrc2xhc2guY2FzZRNwZXJpb2RjZW50ZXJlZC5jYXNlC2J1bGxldC5jYXNlG3BlcmlvZGNlbnRlcmVkLmxvY2xDQVQuY2FzZQpzbGFzaC5jYXNlFnBlcmlvZGNlbnRlcmVkLmxvY2xDQVQOYnJhY2VsZWZ0LmNhc2UPYnJhY2VyaWdodC5jYXNlEGJyYWNrZXRsZWZ0LmNhc2URYnJhY2tldHJpZ2h0LmNhc2UOcGFyZW5sZWZ0LmNhc2UPcGFyZW5yaWdodC5jYXNlCmZpZ3VyZWRhc2gHdW5pMjAxNQd1bmkyMDEwB3VuaTAwQUQLZW1kYXNoLmNhc2ULZW5kYXNoLmNhc2ULaHlwaGVuLmNhc2USZ3VpbGxlbW90bGVmdC5jYXNlE2d1aWxsZW1vdHJpZ2h0LmNhc2USZ3VpbHNpbmdsbGVmdC5jYXNlE2d1aWxzaW5nbHJpZ2h0LmNhc2UJZXhjbGFtLnNjDWV4Y2xhbWRvd24uc2MQZ3VpbGxlbW90bGVmdC5zYxFndWlsbGVtb3RyaWdodC5zYxBndWlsc2luZ2xsZWZ0LnNjEWd1aWxzaW5nbHJpZ2h0LnNjCXBlcmlvZC5zYwtxdWVzdGlvbi5zYw9xdWVzdGlvbmRvd24uc2MLcXVvdGVkYmwuc2MPcXVvdGVkYmxiYXNlLnNjD3F1b3RlZGJsbGVmdC5zYxBxdW90ZWRibHJpZ2h0LnNjDHF1b3RlbGVmdC5zYw1xdW90ZXJpZ2h0LnNjEXF1b3Rlc2luZ2xiYXNlLnNjDnF1b3Rlc2luZ2xlLnNjB3VuaTI3RTgHdW5pMjdFOQd1bmkyMDA3B3VuaTIwMEEHdW5pMjAwOAd1bmkwMEEwB3VuaTIwMDkHdW5pMjAwQgd1bmkyMEI1DWNvbG9ubW9uZXRhcnkEZG9uZwRFdXJvB3VuaTIwQjIHdW5pMjBCNAd1bmkyMEFEBGxpcmEHdW5pMjBCQQd1bmkyMEJDB3VuaTIwQTYGcGVzZXRhB3VuaTIwQjEHdW5pMjBCRAd1bmkyMEI5B3VuaTIwQjgHdW5pMjBBRQd1bmkyMEE5B3VuaTIyMTkHdW5pMjA1Mgd1bmkyMjE1CGVtcHR5c2V0B3VuaTIxMjYHdW5pMjIwNgd1bmkwMEI1B2Fycm93dXAHdW5pMjE5NwphcnJvd3JpZ2h0B3VuaTIxOTgJYXJyb3dkb3duB3VuaTIxOTkJYXJyb3dsZWZ0B3VuaTIxOTYJYXJyb3dib3RoCWFycm93dXBkbgxhcnJvd3VwLmNhc2UPYXJyb3dyaWdodC5jYXNlDmFycm93ZG93bi5jYXNlDmFycm93bGVmdC5jYXNlB3VuaTI1QzYHdW5pMjVDNwlmaWxsZWRib3gHdW5pMjVBMQd0cmlhZ3VwB3VuaTI1QjYHdHJpYWdkbgd1bmkyNUMwB3VuaTI1QjMHdW5pMjVCNwd1bmkyNUJEB3VuaTI1QzEHdW5pMjExMwllc3RpbWF0ZWQHdW5pMjExNgZtaW51dGUGc2Vjb25kB2F0LmNhc2UMdW5pMjExNi5zczAxDGFtcGVyc2FuZC5zYwd1bmkwMzA4C3VuaTAzMDgwMzAwC3VuaTAzMDgwMzAxC3VuaTAzMDgwMzA0B3VuaTAzMDcLdW5pMDMwNzAzMDQJZ3JhdmVjb21iC3VuaTAzMDAwMzA0CWFjdXRlY29tYgt1bmkwMzAxMDMwNwt1bmkwMzAxMDMwNAd1bmkwMzBCDWNhcm9uY29tYi5hbHQHdW5pMDMwMgd1bmkwMzBDC3VuaTAzMEMwMzA3B3VuaTAzMDYHdW5pMDMwQQt1bmkwMzBBMDMwMQl0aWxkZWNvbWILdW5pMDMwMzAzMDgTdGlsZGVjb21iX2FjdXRlY29tYgt1bmkwMzAzMDMwNAd1bmkwMzA0C3VuaTAzMDQwMzA4C3VuaTAzMDQwMzAwC3VuaTAzMDQwMzAxDWhvb2thYm92ZWNvbWIHdW5pMDMwRgd1bmkwMzExB3VuaTAzMTIHdW5pMDMxQgxkb3RiZWxvd2NvbWIHdW5pMDMyNAd1bmkwMzI2B3VuaTAzMjcHdW5pMDMyOAd1bmkwMzJFB3VuaTAzMzEHdW5pMDMzNQd1bmkwMzM2B3VuaTAzMzcHdW5pMDMzOAx1bmkwMzA4LmNhc2UQdW5pMDMwODAzMDAuY2FzZRB1bmkwMzA4MDMwMS5jYXNlEHVuaTAzMDgwMzA0LmNhc2UMdW5pMDMwNy5jYXNlEHVuaTAzMDcwMzA0LmNhc2UOZ3JhdmVjb21iLmNhc2UQdW5pMDMwMDAzMDQuY2FzZQ5hY3V0ZWNvbWIuY2FzZRB1bmkwMzAxMDMwNy5jYXNlEHVuaTAzMDEwMzA0LmNhc2UMdW5pMDMwQi5jYXNlDHVuaTAzMDIuY2FzZQx1bmkwMzBDLmNhc2UQdW5pMDMwQzAzMDcuY2FzZQx1bmkwMzA2LmNhc2UOdGlsZGVjb21iLmNhc2UQdW5pMDMwMzAzMDguY2FzZRh0aWxkZWNvbWJfYWN1dGVjb21iLmNhc2UQdW5pMDMwMzAzMDQuY2FzZQx1bmkwMzA0LmNhc2UQdW5pMDMwNDAzMDguY2FzZRB1bmkwMzA0MDMwMC5jYXNlEHVuaTAzMDQwMzAxLmNhc2USaG9va2Fib3ZlY29tYi5jYXNlDHVuaTAzMEYuY2FzZQx1bmkwMzExLmNhc2UMdW5pMDMzNS5jYXNlDHVuaTAzMzcuY2FzZQx1bmkwMzM4LmNhc2UTdW5pMDMwNC5uYXJyb3cuY2FzZQl1bmkwMzA3LmkJdW5pMDMyOC5pEHVuaTAzMDgubG9jbFZJRVQQdW5pMDMwNy5sb2NsVklFVBJncmF2ZWNvbWIubG9jbFZJRVQSYWN1dGVjb21iLmxvY2xWSUVUEHVuaTAzMDIubG9jbFZJRVQQdW5pMDMwQy5sb2NsVklFVBB1bmkwMzA2LmxvY2xWSUVUEnRpbGRlY29tYi5sb2NsVklFVBB1bmkwMzA0LmxvY2xWSUVUFmhvb2thYm92ZWNvbWIubG9jbFZJRVQOdW5pMDMwOC5uYXJyb3cOdW5pMDMwMi5uYXJyb3cOdW5pMDMwNi5uYXJyb3cQdGlsZGVjb21iLm5hcnJvdw51bmkwMzA0Lm5hcnJvdw51bmkwMzExLm5hcnJvdxNjYXJvbmNvbWIuYWx0LnNob3J0CXVuaTAzMzUudAd1bmkwMkJDB3VuaTAyQkIHdW5pMDJCQQd1bmkwMkM5B3VuaTAyQ0IHdW5pMDJCOQd1bmkwMkJGB3VuaTAyQkUHdW5pMDJDQQd1bmkwMkNDB3VuaTAyQzgKdW5pMDMzNS5zYwp1bmkwMzM2LnNjCnVuaTAzMzguc2MLYnJldmVjb21iY3kQYnJldmVjb21iY3kuY2FzZQtkZXNjZW5kZXJjeRBkZXNjZW5kZXJjeS5jYXNlFmRlc2NlbmRlcmN5LmNhc2Uuc2hvcnQRZGVzY2VuZGVyY3kuc2hvcnQLdW5pMDMwNjAzMDELdW5pMDMwNjAzMDALdW5pMDMwNjAzMDkLdW5pMDMwNjAzMDMLdW5pMDMwMjAzMDELdW5pMDMwMjAzMDALdW5pMDMwMjAzMDkLdW5pMDMwMjAzMDMQdW5pMDMwNjAzMDEuY2FzZRB1bmkwMzA2MDMwMC5jYXNlEHVuaTAzMDYwMzA5LmNhc2UQdW5pMDMwNjAzMDMuY2FzZRB1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AAMAAAAAAAMAAwADAAMACAADAAAAAAAAAAAAGwAAAAD/9gAAAAAACAAAAAAAAAAA/+wAAAAAAAAAAAAAAAAAAAAAAAAAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/+QAAAAAAAAAAAAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/2AAAAAAAHAAAAAP/2AAD/9AAAAAAAAAAAAAAAAAAAAAAAAAAA/8cAAAAAAAAAAAAAAAAAAAAHAAAABwAAAAAAAAAAAAD//QAAAAAAAAAAAAP/9gAIAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkAAP/2AAAAAAAKAAoAAAAA//YAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/7QAAAAAAAwAAAAoAAAAKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//bAAoAAAAAAAMAAwADAAMAAwADAAAAAAAAAAAAEwAAAAD/9gAAAAAAAAAAAAD/9gAA/+wAAAAAAAAAAAAAAAAAAAAAAAAAAP+/AAAAAAAAAAAAAAAAAAAAAAAAAAcAAP/2//YAAAAN/+7/qQAAAAD/2//5/9j/3gAA//kAAAADAAAAAwAAAAMAAAAK//YACAAA/+z/9v/s//P//QAAAAcAAAADAAD/6QAAAAf/9gAHAAAAAAAAAAAAAAAA/9YAAAAAAAAAAAAAAAAAAAAAAAcAAP/2AAAAAAAAAAD/8QAAAAAAAAAA//H/2AAA/+b/9AAAAAAAAAAAAAAAAAAAAAD//QAAAAD/5wAAAAD/4gAAAAAAAAAAAAAAAAAAAAAAAP/5AAcAAAAAAAAAAAAAAAAAJgAIAAgAAAAAAAAAAAAAAAAAAP/s/+8AAAAAAAAAAAAKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIQAAAAAAHAAAAAAAAwAAAAAAAAAAAA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAsAAAAAAAAAAAAAAADAAAAAAAA/+//9wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAmAAAAAAAAAAAAAAAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/58AAAAAAAD/wQADAAMAAwAA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BiUADAYmBicANQYoBigAMQYpBioAEAYrBisAQQYsBiwAQgYuBi4AEAYvBi8AEQYwBjAAEgYxBjIAFAYzBjMAMQY0BjQAKwY1BjUALQY2BjYADAY3BjgAUQY6BjoAKwY9Bj0ATQY/Bj8ATQZDBkMATgZFBkUATgZHBkcAUwZMBk4ANQZRBlEAUQZSBlIANQZTBlMARQZUBlQANQZVBlUARQZWBlYAEAZXBlcAEwZYBlgAOwZZBlkAEwZaBloAOwZbBlsAEAZcBlwAUQZdBl0AUAZeBl4AUQZfBl8AUAZiBmIANQZkBmQANQZmBmYAEAZqBmoAEAZvBm8AEAZ5BnkAJQZ6BnoAOAZ7BnsAJQZ8BnwAMgZ9Bn0AJgZ+Bn4AOAZ/Bn8AMgaABoAAKAaBBoEAMgaCBoIAJQaEBoQAMgaFBoUANgaGBoYAMgaIBogAMgaKBosAMgaMBowAFQaNBo0ANgaQBpAAMgaRBpEAGwaUBpQAKwaVBpYANQaYBpgANQahBqIANQanBqcAAQaqBqoANQarBqsAUgatBq4ADwbKBsoAJQbLBssAMAbMBswAOgbNBs0AFgbOBs8AJQbQBtAAPQbRBtEAHgbXBtcAJQbaBtsAFAbcBtwAJQc+Bz4AEwACAAgACgAaBJgFCjDQQfBOrlTMbU6FfI8WAAEAsgAEAAAAVAQKAV4BaAGGAYYBhgGGAYYBhgGGAbQBtAG0AbQBtAG0Af4B/gH+Af4B/gH+Af4B/gH+Af4ENAIoAigCKAIoAigCKAIoA44ClgJCA6oCjAJQAmICcAJ+AowClgKgAs4C3AOOA5wDqgPcBF4EXgReBFgEWAPuBE4D9AROA/4D/gQEBFgEWARYBFgEWARwBHAEWARYBAoENAQ0BE4EWARYBFgEWAReBF4EcAABAFQASQCUAKkAwADBAMIAwwDEAMUAxgDfAOAA4QDiAOMA5ADmAOcA6ADpAOoA6wDsAO0A7gDvASsBVwFYAVkBWgFbAVwBXQGgAbABygHPAd4B4gHjAeoB7QHvAfgB/gIxAkoCTAJkArQDhQRkBGUGJAYmBicGMAY0BjUGOgY8Bj4GQAZMBk0GTgZTBlUGVwZZBmMGZQaBBoUGjQaUBpUGlgaYBqEG2AbdBz4AAgYlAAYGNgAGAAcGNAApBjUAKAY6ACkGPQAIBj8ACAZHAAMGlAApAAsB4QAZ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//YAAAAAAAAAAAAAAAAAAAAAAAD/7wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAAAAAAoAAAAA//YAAAAAAAAAAAAAAAAAAAAA//YAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/s//cAAAAAAAAAAAAAAAD/+QAAAAAAAAAAAAD/9QAA//cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//kAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//0AAP/2AAAAAAAAAAAAAAAA//sAAAAA//0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//kAAAAAAAAAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/j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ACMCmQKaAE0CmwKzACMCtAK9AG8CvgK+ACMCvwLGAG8CxwLUADoC1QLZAEMC2gLaAAYC2wLcADMC3gLeADMC3wL6AE4C+wL7AFUC/AMCACQDAwMgAFUDIQMhACQDJAMkAFUDJQMsACQDLQNEAFUDRQNGAB8DRwNfAFUDYAOCACQDgwOEAFUDhQOFACQDhgONAFUDjgOQAFcDkgOZAFcDmwOiADQDowO6ADsDuwPAAD4DwQPBAEADwgPLAEEDzAPQAFoD0QPqAE8D7QPtAFUD7gQEABQEBQQFACQEBgQGAFIEBwQOACQEDwQRAFsEEgQSAFUEEwQbAFsEHAQcAFUEHQQfAFsEIAQhACAEIgQuAFUELwQvACQEMAQ3ADQEOARUADsEVQReAEIEXwRjAFoEZARlAA0EZgRmAEYEZwRrAGsEbARsAEcEbQRvAGsEcARwAAoEcQRxAEsEcgR3AGsEeAR4AEcEeQR6AGsEewR7AAUEfAR9AGsEfgR+AAUEfwR/AAYEgASBAAoEggSCAAUEgwSDAAoEhASEAAEEhQSJAGsEigSKAAYEiwSLAGsEjASMAEcEjQSNAGsEjgSOAEwEjwSPAAUEkASQAEsEkQSSAGsEkwSTAAMElASUAAYElQSVAGsElgSWAAoElwSYAAYEmQSZAAoEmgSaAAUEmwSbAAkEnQSdAGsEngSeAAoEnwSfAEsEoASiAGsEowSjAAYEpASnAGsEqASpAAUEqgSqAAYEqwSsAAsErQStAAoErgSuAAYErwSwAAEEsQSyAGsEswS0AAIEtQS1AGsEtgS2AAoEtwS5AGsEugS6AAEEuwS7AGsEvAS+AEYEvwS/AGsEwATBAAUEwgTCAAoEwwTEAEsExQTGAGsExwTJAAUEygTKAEsEywTNAAoEzgTOAAEEzwTRAGsE0gTTAAoE1ATUAEoE1QTVAEcE1gTWAAUE1wTXAAkE2ATaAGsE2wTcAEcE3QTdAEYE3gTeAAUE3wTfAGsE4QTiAAUE4wTjAFwE5ATkAF4E5QTnAEoE6ATrAGsE7ATsAEkE7QTtAFwE7gTuAAcE7wTwAAwE8QTxAAUE8gTyAAgE8wTzAAYE9AT0AAgE9QT1AEcE9gT2AGsE9wT3AAQE+QT5AAcE+gT7AFwE/AT8AEYE/QT9AEoE/gT/AGsFAAUCAAwFBAUEAAUFBQUFAAgFBgUGAE0FBwUHAAUFCAULAGUFDAUMAEgFDQUPACMFEAUQAD8FEQURAFEFEgUXAGUFGAUYAEgFGQUaAGUFGwUbACMFHAUdAGUFHgUeACMFHwUfADUFIAUhAD0FIgUiACMFIwUjAD8FJAUkADoFJQUpAGUFKgUqADUFKwUrAGUFLAUsAEgFLQUtAGUFLgUuAC4FLwUvACMFMAUwAFEFMQUyAGUFMwUzAGQFNAU0AG0FNQU1AGUFNgU2AD8FNwU3AG8FOAU4ADUFOQU5AD8FOgU6ACMFOwU7AD0FPAU8ABkFPQU9AGUFPgU+AD8FPwU/AFEFQAVBAGUFQgVCAG8FQwVDADUFRAVHAGUFSAVJACMFSgVKADUFSwVMAD0FTQVNAD8FTgVOADUFTwVQADoFUQVSAG8FUwVUABEFVQVVAG8FVgVWAD8FVwVXAGUFWAVYAEgFWQVaAGUFWwVbADoFXAVcAGUFXQVfAE0FYAViACMFYwVjAD8FZAVlAFEFZgVnAGUFaAVqACMFawVrAFEFbAVuAD0FbwVvADoFcAVyAGUFcwV0AD8FdQV1AFYFdgV2AEgFdwV3ACMFeAV4AD0FeQV5AC8FegV6AGUFewV7AGQFfAV8AEgFfQV9ACMFfgV+AC4FfwV/ACMFgAWAAD8FgQWBAFEFggWEADoFhQWFAG8FhgWGAEgFhwWJAGUFigWOADoFjwWPADUFkAWQAG8FkQWRAGUFkgWSAFEFkwWTACMFlAWUAGUFlQWVAA8FlgWWAGUFlwWXACMFmAWZADoFmgWeACMFnwWiADoFowWjAG4FpQWnADoFqAWoABwFqQWpADoFqgWqAEgFqwWrAGUFrQWuACMFrwWvAE0FsAWxACMFswW4ADoFuQW5AC8FugW6AEYFvgW+AEYFvwW/AGsFwAXAAEQFwQXBACUFwgXCAFkFwwXDADYFxAXEABcFxQXFAFMFxgXGAEQFxwXHADAFyAXIABUFyQXJACEFygXKAEUFywXLACYFzAXMADkFzQXNADcFzgXOABgFzwXPAFQF0AXQAEQF0QXRADEF0gXSABUF0wXTACIGJAYkAA0GJQYlAA4GJgYnAB0GKAYoABIGKQYqACgGKwYrAGAGLAYsABYGLgYuACgGLwYvACkGMAYwACoGMQYyAC0GMwYzABIGNAY0ADIGNQY1ADwGNgY2AA4GNwY4AB4GOgY6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BSMAEwUkBSQAQAUlBSkAPwUrBSsAPwUtBS0APwUuBS4AGwUvBS8AGQUxBTIAPwUzBTMAPQU1BTUAPwU2BTYAEwU3BTcAPgU5BTkAEwU6BToAGQU7BTsAEQU9BT0APwU+BT4AEwVABUEAPwVCBUIAPgVEBUcAPwVIBUkAGQVLBUwAEQVNBU0AEwVPBVAAQAVRBVIAPgVVBVUAPgVWBVYAEwVXBVcAPwVZBVoAPwVbBVsAQAVcBVwAPwVdBV8ACgVgBWIAGQVjBWMAEwVmBWcAPwVoBWoAGQVsBW4AEQVvBW8AQAVwBXIAPwVzBXQAEwV3BXcAGQV4BXgAEQV6BXoAPwV7BXsAPQV9BX0AGQV+BX4AGwV/BX8AGQWABYAAEwWCBYQAQAWFBYUAPgWHBYkAPwWKBY4AQAWQBZAAPgWRBZEAPwWTBZMAGQWUBZQAPwWWBZYAPwWXBZcAGQWYBZkAQAWaBZ4AGQWfBaIAQAWlBacAQAWpBakAQAWrBasAPwWtBa4AGQWvBa8ACgWwBbEAGQWzBbgAQAW6BboAAQW+Bb4AAQXBBcEAKwXCBcIAOQXDBcMAOAXEBcQAJwXHBccANQXKBcoAPAXLBcsALAXMBcwAOgXOBc4AKAXPBc8AJgXRBdEANgYkBiQADAYlBiUAHwYmBicAKgYoBigAIgYpBioALwYrBisAIwYuBi4ALwYvBi8AMAYwBjAAMQYxBjIANAYzBjMAIgY0BjQANwY1BjUAOwY2BjYAHwY6BjoANwY9Bj0AIAY/Bj8AIAZBBkEALQZDBkMAIQZFBkUAIQZHBkcALgZMBk4AKgZSBlIAKgZUBlQAKgZWBlYALwZYBlgAMwZaBloAMwZbBlsALwZgBmAAJAZhBmEAJQZiBmIAKgZjBmMAKQZkBmQAKgZlBmUAKQZmBmYALwZoBmgAMgZqBmoALwZvBm8ALwZ5BnkAFQZ6BnoAGQZ7BnsAFQZ9Bn0AFgZ+Bn4AGQaCBoIAFQaUBpQANwaVBpYAKgaYBpgAKgahBqIAKganBqcAAQaqBqoAKgarBqsAPwbKBsoAFQbOBs8AFQbXBtcAFQbaBtsANAbcBtwAFQACAJ4ABAAAAKwAsAABAEcAAP+j//n/9AAKAB4AKAAh//YAFAAK/6j/9v/2ABQAAwAHAB4ABwAUABH/7P/5//P/2QARAA0AEf/2//0AUAAg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AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9AAA//D/8AAAAAD/7f/3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/8f/q//f/9AAA/+0AAP/s//P/9//w//cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKACUABwAA//b/9gAA/+n/+f/bAAAAAAAAAAAAHgAAAAAAFAAAAAcAAP/9//kAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwAAAAAACP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABf/9AAAABQAFAAAAAoAAAAUAAoABwAAAAAADf/2AAAAFAAAAAAAAwAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAACP/2AAAACAAAAAAAAwAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKAAoAFAAA/+z/7AAA/+L/9v/YAAoAAABkAEQAFAAKAAAACAAAAAD/9gAA//YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAEQAAAAAACAADAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/zAAD/6QAA//T/7wAA/9//1v/WAAAAEf/0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA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ABIFhQWFAAQFhwWJAAgFkAWQAAkFkgWSABIFlAWUAAsFlQWVAAkFnAWeAAEFowWjAAkFrwWwAAEFsQWxAAkGiQaJAAwAAgFrAAQAHwBMACAAIABNACEAJwAwACgARgBNAEcASABIAEkASQBNAEoAUQAwAFIAZwBNAGoAgwBNAIQApgAwAKcAqABNAKkAqQAwAKoAsQBNALIAtABOALYAvQBOAL8AvwAwAMAAxgACAMcA3gAxAN8A5AAyAOUA5QA2AOYA7wAzAPUA9QBNAPYBDwABARABEQBMARIBEwBNASsBKwABASwBMwAwATUBNQBNAUUBRgBJAUcBSABNAUoBVABNAVUBVgAwAVcBXQBKAV4BegAxAYoBpQA3AaYBpgATAacBzAAWAc4BzgAPAdAB1wAWAdgB3QATAd4B7gBCAe8B8QBBAfIB9AATAfUB9QBCAfYB/gATAf8CCwBCAgwCLgAWAi8CLwBCAjACMAATAjECMQAWAjICOQBCAjoCPABFAj4CRQBFAkYCRgATAkgCTwAjAlACZwBGAmgCbQApAm4CbgAqAm8CeAApAnkCfQArAn8CmAAWApkCmgA3ApsCswAWArQCvQATAr4CvgAWAr8CxgATAscC1ABGAtUC2QArAtoC2gACAtsC3AAjAt4C3gAjBGQEZQAEBGYEZgBMBGcEawBNBGwEbAA1BG0EbwBNBHAEcAA2BHEEcQBIBHIEdwBNBHgEeAA1BHkEegBNBHsEewAwBHwEfQBNBH4EfgAwBH8EfwACBIAEgQA2BIIEggAwBIMEgwA2BIQEhAAuBIUEiQBNBIoEigACBIsEiwBNBIwEjAA1BI0EjQBNBI4EjgBOBI8EjwAwBJAEkABIBJEEkgBNBJQElAACBJUElQBNBJYElgA2BJcEmAACBJkEmQA2BJoEmgAwBJsEmwAyBJ0EnQBNBJ4EngA2BJ8EnwBIBKAEogBNBKMEowACBKQEpwBNBKgEqQAwBKoEqgACBKsErAAzBK0ErQA2BK4ErgACBK8EsAAuBLEEsgBNBLMEtAAvBLUEtQBNBLYEtgA2BLcEuQBNBLoEugAuBLsEuwBNBLwEvgBMBL8EvwBNBMAEwQAwBMIEwgA2BMMExABIBMUExgBNBMcEyQAwBMoEygBIBMsEzQA2BM4EzgAuBM8E0QBNBNIE0wA2BNUE1QA1BNYE1gAwBNcE1wAyBNgE2gBNBNsE3AA1BN0E3QBMBN4E3gAwBN8E3wBNBOEE4gAwBOME4wABBOQE5ABHBOgE6wBNBO0E7QABBO4E7gBKBPEE8QAwBPIE8gAxBPME8wACBPQE9AAxBPUE9QA1BPYE9gBNBPcE9wBJBPkE+QBKBPoE+wABBPwE/ABMBP4E/wBNBQQFBAAwBQUFBQAxBQYFBgA3BQcFBwAwBQgFCwBCBQwFDAAOBQ0FDwAWBRAFEAAqBREFEQAPBRIFFwBCBRgFGAAOBRkFGgBCBRsFGwAWBRwFHQBCBR4FHgAWBR8FHwAkBSAFIQApBSIFIgAWBSMFIwAqBSQFJABGBSUFKQBCBSoFKgAkBSsFKwBCBSwFLAAOBS0FLQBCBS4FLgBFBS8FLwAWBTAFMAAPBTEFMgBCBTMFMwBBBTUFNQBCBTYFNgAqBTcFNwATBTgFOAAkBTkFOQAqBToFOgAWBTsFOwApBT0FPQBCBT4FPgAqBT8FPwAPBUAFQQBCBUIFQgATBUMFQwAkBUQFRwBCBUgFSQAWBUoFSgAkBUsFTAApBU0FTQAqBU4FTgAkBU8FUABGBVEFUgATBVMFVAAJBVUFVQATBVYFVgAqBVcFVwBCBVgFWAAOBVkFWgBCBVsFWwBGBVwFXABCBV0FXwA3BWAFYgAWBWMFYwAqBWQFZQAPBWYFZwBCBWgFagAWBWsFawAPBWwFbgApBW8FbwBGBXAFcgBCBXMFdAAqBXUFdQBEBXYFdgAOBXcFdwAWBXgFeAApBXkFeQAgBXoFegBCBXsFewBBBXwFfAAOBX0FfQAWBX4FfgBFBX8FfwAWBYAFgAAqBYEFgQAPBYIFhABGBYUFhQATBYYFhgAOBYcFiQBCBYoFjgBGBY8FjwAkBZAFkAATBZEFkQBCBZIFkgAPBZMFkwAWBZQFlABCBZUFlQAGBZYFlgBCBZcFlwAWBZgFmQBGBZoFngAWBZ8FogBGBaUFpwBGBagFqABLBakFqQBGBaoFqgAOBasFqwBCBa0FrgAWBa8FrwA3BbAFsQAWBbMFuABGBbkFuQAgBboFugBMBb4FvgBMBb8FvwBNBcAFwAAsBcEFwQAXBcIFwgAoBcMFwwAlBcQFxAAQBcUFxQA/BcYFxgAsBccFxwAhBcgFyAANBckFyQAUBcoFygAtBcsFywAYBcwFzAA7Bc0FzQAm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D4oPig+KCrAPig+KD4oPig+KD4oPig+KD4oKqg+KD4oPig+KD4oPig+KD4oPig+KD4oPig+KD4oPigugD4oLjguUCg4LoA+KD4oPig+KChQPigoaD4oLuA+KD4oKIA+KD4oPig+KD4oPigomD4oPigrCCiwKzg+KD4oKMgo4Cj4Pig+KD4oPigpED4oPig+KD4oPigv0D4oLUgtYC6wLZAtqD4oPigsoD4oPig+KD4oK1A+KD4oOOg+KC74Pig+KD4oPigpKD4oPig+KD4oKUA+KD4oKVg+KClwPig+KCtoPigrgCuYPigraD4oKYgrmD4oPig+KD4oPig+KD4oPig+KD4oPigvED4oLyg+KD4oOOg+KCmgKbg+KCnQPigp6CoAPigqGD4oKjAqSD4oPig+KD4oPig+KCpgPigqeCqQPig+KD4oKqg+KD4oPig+KCrAPig+KD4oPig+KD4oPig+KD4oPig+KD4oKtg+KCrwPig+KCrYPigq8D4oPigrCCsgKzg+KD4oPig+KCtQPig+KCtoPigrgCuYPigrsD4oK8g+KD4oK/gsECvgPig+KCv4LBAsKD4oPigsQD4oLFg+KD4oLHAsiCygPig+KD4oPigsuD4oPig+KD4oLNA+KD4oPig+KCzoPig+KDjoPigtAD4oPig+KD4oLRg+KD4oPig+KC0wPig+KC1ILWAteC2QLagtSC1gLrAtkC2oLUgtYC14LZAtqD4oPigtwD4oPig+KD4oLdg+KD4oPig+KC3wPig+KD4oPiguCD4oPig+KD4oLiA+KD4oPig+KC7gPig+KC44LlAuaC6APig+KD4oLpg+KD4oPig+KC6wPig+KD4oPig+KC7IPig+KD4oPig+KD4oPig+KC7gPig+KDjoPigu+D4oPigvED4oLyg+KD4oLxA+KC8oPig+KDXoMEgwMD4oPigweDCQMKg+KD4oMHgwkC9APig+KDB4MJAvWD4oPigw2DDwMDA+KDEgMNgw8DAwPigxIDDYMPAwMD4oMSAw2DDwL3A+KDEgPig+KD4oPig+KC/oPigwADAYPigxaD4oL4g+KD4oMWg+KC+IPig+KD4oPigvoD4oPig+KD4oL7g+KD4oPig+KD4oL9A+KC/oPigwADAYPig16DBIMDA+KD4oNegwSDEIPig+KDvQPigwYD4oPigweDCQMKg+KD4oMNgw8DDAPigxIDDYMPAxCD4oMSAxaD4oMTg+KD4oMWg+KDFQPig+KDFoPigxgD4oPig+KD4oMZg+KD4oPig+KD4oMbA+KDYwNkg2GD4oPigxyD4oMeA+KD4oPig+KDigPig+KD4oPig6UD4oPig2qDbANtg+KD4oNqg2wDH4Pig+KDaoNsAyED4oPig+KD4oNdA+KD4oOfA+KDoIPig+KD4oPigyKD4oPig+KD4oMig+KD4oPig+KDJAPig+KD4oPigyWD4oPig+KD4oPNg+KD4oPig+KDJwPig+KD4oPig+KD4oPig16D4oNgA+KD4oOWA+KDl4OZA+KDdoN4A28DewN8g+KD4oPig+KD4oMog+KDKgPig+KDogPig6OD4oPig0gD4oNJg0sD4oOFg+KDK4Pig+KDhYPigyuD4oPig+KD4oPig+KD4oPig+KDTgPig+KD4oPig+KD4oPig+KD4oPig+KD4oPig+KD4oONA+KD4oPigy0DjQPig+KD4oPigy6D4oMwA+KDMYPig+KDMwPig+KD4oPig+KD4oOgg+KD4oNXAzSDNgPig+KDpoOoAzeD4oPig+KD4oM5A+KD4oM6g+KDPAM9g6CD4oPig34D4oPig+KD4oM/A+KD4oPig+KDXQPig+KDnwPig6CD4oPig+KD4oPNg+KD4oNAg+KDQgPig+KDQ4Pig0UD4oPig5YD4oOXg5kD4oOWA+KDRoOZA+KD4oPig+KD4oPig6ID4oOjg+KD4oNIA+KDSYNLA+KD4oPig+KDTIPig+KD4oPig0yD4oPig+KD4oPig+KD4oPig04D4oPig+KD4oNPg+KD4oOag+KDWINRA1KDVAPig1WD4oPig1QD4oNVg+KD4oNXA+KDWINaA1uD4oPig10D4oPig+KD4oPig+KD4oOWA+KDl4OZA+KDXoPig2AD4oPig2MDZINhg+KD4oNjA2SDZgPig+KDZ4Pig2kD4oPig2qDbANtg+KD4oN2g3CDbwPig+KDdoNwg3mD4oPig+KD4oNyA+KD4oOfA+KDgQPig+KD4oPig3OD4oPig+KD4oN1A+KD4oN2g3gDeYN7A3yD4oPig34D4oPig+KD4oN/g+KD4oPig+KDgQPig+KDhYPig4KD4oPig4WD4oOEA+KD4oOFg+KDhwPig+KD4oPig4iD4oPig+KD4oOKA+KD4oPig+KDi4ONA+KD4oPig+KD4oPig46D4oOQA+KD4oORg+KDkwPig+KD4oPig+KD4oPig+KD4oOxA+KD4oPVA9aDtYPig9mD1QPWg7WD4oPZg9UD1oO4g+KD2YPig+KDlIPig+KDlgPig5eDmQPig5qD4oOcA+KD4oO9A+KD4oPig+KD4oPig+KD4oPig9UD1oO1g+KD2YPig+KDnYPig+KD4oPig52D4oPig58D4oOgg+KD4oOiA+KDo4Pig+KD4oPig6UD4oPig6aDqAOpg+KD4oPig+KDtYPig+KDqwOsg9sD4oOuA+KD4oOvg+KD4oPDA8SDwYPig+KD4oPig7ED4oPig8kDyoPMA+KD4oPJA8qDsoPig+KDyQPKg7QD4oPig9UD1oO1g+KD2YPVA9aDtYPig9mD1QPWg7cD4oPZg9UD1oO4g+KD2YO6A+KDu4Pig+KDvQPig+KD4oPig94D4oO+g+KD4oPeA+KDvoPig+KD4oPig8AD4oPig8MDxIPBg+KD4oPDA8SDxgPig+KD4oPig8eD4oPig8kDyoPMA+KD4oPPA9CDzYPig+KDzwPQg9ID4oPig9UD1oPTg+KD2YPVA9aD2APig9mD3gPig9sD4oPig94D4oPcg+KD4oPeA+KD34Pig+KD4oPig+ED4oPigABAX0AAAABAUoDUwABAWUDUwABAWUDOQABAZoDUwABAZoCvAABAWcDUwABAfICvAABAogCSgABAUoAAAABAYMAAAABAUACvAABANAAAAABAJsAAAABAM0AAAABAJsDOQABAQoCvAABAWcCvAABAX0CvAABAfAAAAABAfACvQABA0QCvAABAS8CvAABAS8BUwABAU4AAAABAU4CvAABAUsA+QABAUQAAAABAUQCvAABAUEA+QABAS4AAAABAS4CvAABAS4BUwABAVUCvAABAVQCvAABAlUAAAABAk8CvwABAJ8AAAABANEAAAABAJ8CvAABAgQCvAABAZkAAAABAZkCvAABAZkCKQABAeEAAAABAeECvAABAXsCvAABAXsAAAABAuoAAAABAXsDOQABAhwAAAABAhwCvAABAW8AAAABAmkAAAABAWUCvAABAZ0CvAABAZ0DOQABAgQDOQABAT8DOQABAZoDNQABAZoDOQABAagAAAABAfUAAAABAagDOQABAagBXgABAoECvAABAUADOQABAVQDNQABAVQDOQABAVQDUwABAVUDOQABA0MAAAABA3QAAAABAfIDOQABAK4CSgABAWYCvAABAagCvAABAMcCSgABAUoCvAABAT8CvAABAZYAAAABAZ8CvAABAV4DUwABAV4DOQABAY8DUwABAYoCvAABAfECvAABAOwCvAABAQ4CSgABATwAAAABAT4CvAABATsBSgABAY8CvAABAr0AAAABAhQCvAABAV4AAAABAlEAAAABAV4CvAABAY8DNQABAYgAAAABArEAAAABAY8DOQABAo4CvAABAYoDNQABAYoDOQABApcAAAABAYoDUwABAfEDOQABAMMCSgABATgAAAABATgCEwABATUCvQABATUCowABAVUCEgABAVUCvQABAVUCswABATQCvQABAYIAAAABAW4CEgABARACEgABAaACEgABAgEBugABAQsAAAABAQsCEgABATkAAAABAL0AAAABAI0CxQABAIsCowABAI4CxQABAVsAAAABAJAC5gABAMMCeQABATMCEAABAUEAAAABAUECEgABAYoAAAABAYoCEgABArECEAABAPgAAAABAPgCEgABAPgA/AABAR4ABQABARQCEgABARMCEgABAMgCegABAQQCEgABAdAAAAABAcoCEAABAI0AAAABAI0C5gABAI0BZgABARYC5gABAagCEgABAY8AAAABAY8CEgABASECEgABAR8AAAABAf0AAAABASECowABAdkAAAABAc0CEgABATUAAAABAgkAAAABATUCEgABAT8CEgABAGsCEgABAagCowABAVUCnwABAVUCowABAT8AAAABAaIAAAABAT8CowABAT8BCQABAcgCEgABAUUCEgABAUUCowABAQcCowABARACnwABARACowABAaAAAAABARACvQABARQCowABASMCEAABAaACowABAJoBugABAS8AAAABAUICEgABAdQAAAABAdQCEgABATECEgABAVIAAAABAVICEgABAVIBpgABAVkAAAABAVkCEgABAgYCEAABAPsAAAABAQcCEgABAToAAAABAS4CEgABASMCuwABAIsAAAABALsAAAABAIsCnwABAVAAAAABAkkAAAABAhoCEgABAgYCnQABAUgCEgABATACvQABATACowABAUYCEgABAUYCswABAUYCvQABAWkAAAABAVYCEgABAhQAAAABAVACEgABAZUCEgABAU8CEgABAU8AAAABAk8AAAABAU8CowABAeUCEgABATAAAAABAb0AAAABATACEgABATQCEgABATQAAAABAKcCEgABATQCowABAUYCnwABAUcAAAABAkAAAAABAUYCowABAhECEgABAVACnwABAVACowABApUAAAABAVACvQABAZUCowABAAAAAAAJAAAAAQAIAAEABAAAA7wABgEAAAEACAABAAwAHAABACoASgABAAYG/wcABwEHAgcEBwUAAQAFBv8HAAcBBwQHBQAGAAAAGgAAABoAAAAaAAAAGgAAABoAAAAaAAH+1AAAAAUAEgAMABIAGAAeAAH+1P9qAAH+1P9vAAH+1P9jAAH+1P9yAAYCAAABAAgAAQF6AAwAAQGgAEAAAgAIBt8G6gAABuwG/QAMBwoHJAAeB0AHQQA5B0UHRQA7B0gHSgA8B0wHUQA/B1MHVABFAEcAkACuAK4ArgKSAJYAugCuALoAnACuALoAwADAAsAAwACiAKIAwACuAK4ArgCoAK4ArgCuALQAugDAAMYAzADqAOoA6gDSANgA9gDqAPYA3gDqAPYA/AD8At4A/AD8AOoA6gDqAOQA6gDqAOoA8AD2APwBFAEOAQ4BDgEgASABIAECAQgBDgEOARQBGgEgAAH+1AKjAAH+1AMwAAH+1AMxAAH+1AL9AAH+1AKfAAH+1AMtAAH+1AMDAAH+1AK9AAH+1AKzAAH+1ALfAAH+1AM5AAH+1ANSAAH+1APGAAH+1APHAAH+1AM1AAH+1APDAAH+1AOZAAH+1ANTAAH+1ANJAAEBLAKjAAEBLAK8AAEBLAK9AAEBLAKfAAEBLAL9AAEBLAKzAAYCAAABAAgAAQAMACgAAQAyAWoAAgAEBt8G6gAABuwG/QAMBwoHJAAeB14HbQA5AAIAAQdeB20AAABJAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABMgAAATIAAAEyAAABMgAAATIAAAEyAAABMgAAATIAAAEyAAABMgAAATIAAAEyAAABMgAAATIAAAEyAAABMgAAATIAAAEyAAABMgAAATIAAAEyAAABJgAAATIAAAEyAAABMgAAATIAAAEyAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEyAAABMgAAATIAAAEyAAABMgAAATIAAAEyAAABMgAB/tQCuwAB/tQCEgAB/tQCvAAQACgAKAAiACgALgAuADQAOgBGAEYAQABGAEwATABSAFgAAf7UAyUAAf7UAxoAAf98AvcAAf9WAwsAAf7UAyAAAf7UA7sAAf7UA7AAAf98A40AAf9WA6EAAf7UA7YAAQAMACIABQEKAq4AAgADBt8G6gAABuwHJwAMB14HbQBIAAIAJgAEAEgAAABKAH8ARQCBAKYAewCpALQAoQC2AL0ArQC/ANoAtQDcAN4A0QDgAOQA1ADmAPQA2QD2ASoA6AEsATYBHQE4AVABKAFSAVQBQQFWAaUBRAGnAa4BlAGwAc4BnAHQAdYBuwHYAgcBwgIJAjwB8gI+AkUCJgJIAm0CLgJvAn0CVAJ/ArMCYwK1AtkCmALfAyMCvQMlAzUDAgM3A1sDEwNdA4IDOAOFA5ADXgOSA5kDagObA7YDcgO4A7oDjgO8A8ADkQPCBAUDlgQHBBED2gQTBCoD5QQsBC4D/QQwBGMEAABYAAIBmAACAZgAAgGYAAIBmAACAZgAAgGYAAIBmAACAZgAAgGYAAIBmAACAZgAAgGYAAIBmAACAZgAAgGYAAIBmAACAZgAAgGYAAIBmAACAZgAAgGYAAIBmAACAZgAAgGYAAIBmAACAZgAAgGYAAIBmAACAZgAAgGYAAQBmAAAAWgAAAFoAAABaAAAAWgAAQFiAAABaAAAAWgAAwFuAAMBdAADAYwAAwF6AAIBngACAZ4AAgGeAAIBngACAZ4AAgGeAAIBngACAZ4AAgGeAAIBngACAZ4AAgGeAAIBngACAZ4AAgGeAAIBngACAZ4AAgGeAAIBngACAZ4AAgGeAAIBgAACAZ4AAgGeAAIBngACAZ4AAgGeAAMBhgADAYwAAwGSAAIBmAACAZgAAgGYAAIBmAACAZgAAgGYAAIBmAACAZgAAgGeAAIBngACAZ4AAgGeAAIBngACAZ4AAgGeAAIBngAB/tUAAAAB/tQAAAAB/tQBtgAB/kwBtgAB/soBCgAB/tQCuwAB/tQBZAAB/ycBggAB/mMBXgAB/tQCEgAB/tQCvAQ0KlIqWCpGPJQ8lCpSKlgqNDyUPJQqUipYKl48lDyUKlIqWCoQPJQ8lCouKlgqXjyUPJQqUipYKhA8lDyUKlIqWCoKPJQ8lCpSKlgqEDyUPJQqUipYKl48lDyUKlIqWCpePJQ8lCpSKlgqFjyUPJQqLipYKl48lDyUKlIqWCoWPJQ8lCpSKlgqHDyUPJQqUipYKiI8lDyUKlIqWCo0PJQ8lCpSKlgqKDyUPJQqLipYKkY8lDyUKlIqWCo0PJQ8lCpSKlgqOjyUPJQqUipYKl48lDyUKlIqWCpAPJQ8lCpSKlgqRjyUPJQqUipYKkw8lDyUKlIqWCpMPJQ8lCpSKlgqXjyUPJQuWjyULlQ8lDyULlo8lC5gPJQ8lCpkPJQqajyUPJQqgjyUKnA8lDyUKoI8lCp2PJQ8lCqCPJQqfDyUPJQqgjyUKnA8lDyUKoI8lCp2PJQ8lCqCPJQqfDyUPJQqgjyUKog8lDyUM0w8lCrQLn48lCqOPJQqlC5+PJQqmjyUKqAqpjyUM0w8lCqsLn48lCqyPJQquCq+PJQqxDyUKtAufjyUKso8lCrQLn48lCrWPJQq3C5+PJQrHiskKxg8lDyUKx4rJDjaPJQ8lCseKyQrKjyUPJQrHiskKyo8lDyUKx4rJCsqPJQ8lCseKyQrKjyUPJQrHiskKuI8lDyUKwArJCsqPJQ8lCseKyQq4jyUPJQrHiskKug8lDyUKx4rJCruPJQ8lCseKyQ42jyUPJQrHiskKvQ8lDyUKx4rJCr6PJQ8lCsAKyQrGDyUPJQrHiskONo8lDyUKx4rJCsGPJQ8lCseKyQrKjyUPJQrHiskKww8lDyUKx4rJCsSPJQ8lCseKyQrEjyUPJQrHiskKxg8lDyUKx4rJCsqPJQ8lCs2PJQrMDyUPJQrNjyUKzw8lDyULDg8lC72PJQ8lCw4PJQu2DyUPJQsODyULtg8lDyULDg8lC7YPJQ8lCwgPJQu9jyUPJQsODyULuQ8lDyULDg8lC7qPJQ8lCw4PJQu9jyUPJQsODyULDIrWjyUK0I8lCtIK048lCtUPJQsMitaPJQsODyULD4rWjyULDg8lCw+K1o8lCwgPJQsMitaPJQriiuQK948lDyUPJQ8lCtgPJQ8lCuKK5ArxjyUPJQriiuQK5Y8lDyUK4orkCuWPJQ8lCuKK5ArxjyUPJQriiuQK2Y8lDyUK4orkCtsPJQ8lCuKK5ArcjyUPJQreCuQK948lDyUK4orkCvGPJQ8lCuKK5ArfjyUPJQriiuQK5Y8lDyUK4orkCuEPJQ8lCuKK5Ar3jyUPJQriiuQK5Y8lDyUPJQ8lCucPJQ8lDyUPJQrojyUPJQrqDyUK7o8lDyUK6g8lCuuPJQ8lCu0PJQrujyUPJQvUDyUK94vXC9iL1A8lCvAL1wvYi9QPJQrxi9cL2IvUDyUK94vXC9iK8w8lCveL1wvYi9QPJQr3i9cL2IrzDyUK94vXC9iL1A8lCvSL1wvYivYPJQr3i9cL2Ir5DyUK+or8Cv2K/w8lCwIPJQ8lCwCPJQsCDyUPJQsODyULDI8lDyULDg8lCwOPJQ8lCw4PJQsFDyUPJQsODyULD48lDyULCA8lCwyPJQ8lCw4PJQsGjyUPJQsIDyULDI8lDyULDg8lCwmPJQ8lCwsPJQsMjyUPJQsODyULD48lDyULIAshiyqLJIsmCyALIYsdCySLJgsgCyGLHoskiyYLIAshix6LJIsmCyALIYsRCySLJgsYiyGLHoskiyYLIAshixELJIsmCyALIYsSiySLJgsgCyGLFAskiyYLIAshix0LJIsmCyALIYsViySLJgsgCyGLIwskiyYLIAshixcLJIsmCxiLIYsqiySLJgsgCyGLHQskiyYLIAshixoLJIsmCyAPJQsqjyUPJQsgDyULHQ8lDyULGI8lCyqPJQ8lCyAPJQsdDyUPJQsgDyULGg8lDyULIA8lCx6PJQ8lCyALIYsdCySLJgsgCyGLHoskiyYLIAshixuLJIsmCyALIYsjCySLJgsgCyGLIwskiyYPJQ8lCyqPJQ8lCyALIYsqiySLJgsgCyGLHQskiyYLIAshix6LJIsmCyALIYsjCySLJgsgCyGLIwskiyYLIAshiyMLJIsmCyePJQspDyUPJQ8lDyULKo8lDyULLw8lCzOPJQ8lCy8PJQssDyUPJQsvDyULMI8lDyULLY8lCzOPJQ8lCy8PJQssDyUPJQstjyULM48lDyULLw8lCzCPJQ8lCzIPJQszjyUPJQs7DyULPI8lDyULOw8lCzUPJQ8lCzsPJQs2jyUPJQs7DyULOY8lDyULOw8lCzgPJQ8lCzsPJQs8jyUPJQs7DyULOY8lDyULPg8lCzyPJQ8lCzsPJQs/jyUPJQs+DyULPI8lDyULPg8lCz+PJQ8lDhEPJQtBDyUPJQtEDyULSItKDyULRA8lC0iLSg8lC0QPJQtCi0oPJQtEDyULSItKDyULRY8lC0iLSg8lC0WPJQtIi0oPJQtHDyULSItKDyULWQtai06PJQtdi1kLWotRjyULXYtZC1qLV48lC12LWQtai1ePJQtdi1kLWotXjyULXYtZC1qLUY8lC12LWQtai0uPJQtdi00LWotOjyULXYtZC1qLUY8lC12LWQtai1APJQtdi1kLWotOjyULXYtZC1qLUY8lC12LTQtai06PJQtdi1kLWotRjyULXYtZC1qLUA8lC12LWQtai1ePJQtdi1kLWotRjyULXYtZC1qLV48lC12LWQtai1MPJQtdi1kLWotUjyULXYtZC1qLVg8lC12LWQtai1ePJQtdi1kLWotcDyULXYtjjyULXw8lDyULY48lC2UPJQ8lC2OPJQtgjyUPJQtjjyULYg8lDyULY48lC2UPJQ8lC3EPJQtrC3QPJQtxDyULbIt0DyULcQ8lC3KLdA8lC3EPJQtmi3QPJQtxDyULaAt0DyULaY8lC2sLdA8lC3EPJQtsi3QPJQtxDyULbgt0DyULcQ8lC2+LdA8lC3EPJQtyi3QPJQt4jyULfQ8lDyULeI8lC3WPJQ8lC3iPJQt3DyUPJQt4jyULeg8lDyULe48lC30PJQ8lC5CLkguNjyUPJQuQi5ILiQ8lDyULkIuSC5OPJQ8lC5CLkguADyUPJQuHi5ILk48lDyULkIuSC4APJQ8lC5CLkgt+jyUPJQuQi5ILgA8lDyULkIuSC5OPJQ8lC5CLkguTjyUPJQuQi5ILgY8lDyULh4uSC5OPJQ8lC5CLkguBjyUPJQuQi5ILgw8lDyULkIuSC4SPJQ8lC5CLkguJDyUPJQuQi5ILhg8lDyULh4uSC42PJQ8lC5CLkguJDyUPJQuQi5ILio8lDyULkIuSC5OPJQ8lC5CLkguMDyUPJQuQi5ILjY8lDyULkIuSC48PJQ8lC5CLkguPDyUPJQuQi5ILk48lDyULlo8lC5UPJQ8lC5aPJQuYDyUPJQuZjyULmwufjyULnI8lC54Ln48lC7GLswuwDyUPJQuxi7MLqg8lDyULsYuzC7SPJQ8lC7GLswu0jyUPJQuxi7MLtI8lDyULsYuzC7SPJQ8lC7GLswuhDyUPJQuoi7MLtI8lDyULsYuzC6EPJQ8lC7GLswuijyUPJQuxi7MLpA8lDyULsYuzC6oPJQ8lC7GLswuljyUPJQuxi7MLpw8lDyULqIuzC7APJQ8lC7GLswuqDyUPJQuxi7MLq48lDyULsYuzC7SPJQ8lC7GLswutDyUPJQuxi7MLro8lDyULsYuzC66PJQ8lC7GPJQuwDyUPJQuxi7MLtI8lDyULvA8lC72PJQ8lC7wPJQu2DyUPJQu8DyULtg8lDyULvA8lC7YPJQ8lC7ePJQu9jyUPJQu8DyULuQ8lDyULvA8lC7qPJQ8lC7wPJQu9jyUPJQvMi84Lyw8lDyUPJQ8lC78PJQ8lC8yLzgvGjyUPJQvMi84Lz48lDyULzIvOC8+PJQ8lC8yLzgvGjyUPJQvMi84LwI8lDyULzIvOC8IPJQ8lC8yLzgvDjyUPJQvFC84Lyw8lDyULzIvOC8aPJQ8lC8yLzgvIDyUPJQvMi84Lz48lDyULzIvOC8mPJQ8lC8yLzgvLDyUPJQvMi84Lz48lDyUPJQ8lC9EPJQ8lDyUPJQvSjyUPJQvUDyUL1YvXC9iL2g8lC90PJQ8lC9uPJQvdDyUPJQvpDyUL548lDyUL6Q8lC96PJQ8lC+kPJQvgDyUPJQvpDyUL6o8lDyUL4w8lC+ePJQ8lC+kPJQvhjyUPJQvjDyUL548lDyUL6Q8lC+SPJQ8lC+YPJQvnjyUPJQvpDyUL6o8lDyUL7A8lC+2PJQ8lDNYPJQvzi/UPJQzWDyUL84v1DyUM1g8lC+8L9Q8lDNYPJQvzi/UPJQvwjyUL84v1DyUL8I8lC/OL9Q8lC/IPJQvzi/UPJQwEDAWL/48lDAiMBAwFi/sPJQwIjAQMBYwCjyUMCIwEDAWMAo8lDAiMBAwFjAKPJQwIjAQMBYv7DyUMCIwEDAWL9o8lDAiL+AwFi/+PJQwIjAQMBYv7DyUMCIwEDAWL+Y8lDAiMBAwFi/+PJQwIjAQMBYv7DyUMCIv4DAWL/48lDAiMBAwFi/sPJQwIjAQMBYv5jyUMCIwEDAWMAo8lDAiMBAwFi/sPJQwIjAQMBYwCjyUMCIwEDAWL/I8lDAiMBAwFi/4PJQwIjAQMBYv/jyUMCIwEDAWMAQ8lDAiMBAwFjAKPJQwIjAQMBYwHDyUMCIwOjyUMCg8lDyUMDo8lDBAPJQ8lDA6PJQwLjyUPJQwOjyUMDQ8lDyUMDo8lDBAPJQ8lDBwPJQwWDyUPJQwcDyUMF48lDyUMHA8lDB2PJQ8lDBwPJQwRjyUPJQwcDyUMEw8lDyUMFI8lDBYPJQ8lDBwPJQwXjyUPJQwcDyUMGQ8lDyUMHA8lDBqPJQ8lDBwPJQwdjyUPJQ6SDyUMI48lDyUOkg8lDB8PJQ8lDpIPJQwgjyUPJQ6SDyUMIg8lDyUOiQ8lDCOPJQ8lDnoMNYwyjyUPJQ56DDWMLg8lDyUOegw1jDcPJQ8lDnoMNYwmjyUPJQ59DDWMNw8lDyUOegw1jCaPJQ8lDnoMNYwlDyUPJQ56DDWMJo8lDyUOegw1jDcPJQ8lDnoMNYw3DyUPJQ56DDWMKA8lDyUOfQw1jDcPJQ8lDnoMNYwoDyUPJQ56DDWMKY8lDyUOegw1jCsPJQ8lDnoMNYwuDyUPJQ56DDWMLI8lDyUOfQw1jDKPJQ8lDnoMNYwuDyUPJQ56DDWML48lDyUOegw1jDcPJQ8lDnoMNYwxDyUPJQ56DDWMMo8lDyUOegw1jDQPJQ8lDnoMNYw0DyUPJQ56DDWMNw8lDyUMOg8lDDiPJQ8lDDoPJQw7jyUPJQxBjyUMPQ8lDyUMQY8lDD6PJQ8lDEGPJQxADyUPJQxBjyUMPQ8lDyUMQY8lDD6PJQ8lDEGPJQxADyUPJQxBjyUMQw8lDyUMRI8lDyUNQ41FDESPJQ8lDUONRQxEjyUPJQ1DjUUMRg8lDyUNQ41FDEePJQ8lDUONRQxJDyUMSo1DjUUO1AxeDFOPJQ8lDtQMXgxVDyUPJQ7UDF4MX48lDyUO1AxeDF+PJQ8lDtQMXgxfjyUPJQ7UDF4MX48lDyUO1AxeDEwPJQ8lDgUMXgxfjyUPJQ7UDF4MTA8lDyUO1AxeDE2PJQ8lDtQMXgxPDyUPJQ7UDF4MVQ8lDyUO1AxeDFCPJQ8lDtQMXgxSDyUPJQ4FDF4MU48lDyUO1AxeDFUPJQ8lDtQMXgxWjyUPJQ7UDF4MX48lDyUO1AxeDFgPJQ8lDtQMXgxZjyUPJQ7UDF4MWY8lDyUMWw8lDFyPJQ8lDtQMXgxfjyUPJQxhDGKMZA8lDyUMZw8lDGWPJQ8lDGcPJQxojyUPJQ8lDyUMag8lDyUPJQ8lDGuPJQ8lDyUPJQxrjyUPJQ8lDyUMa48lDyUPJQ8lDG0PJQ8lDyUPJQxujyUPJQ8lDyUMcA8lDyUOkg8lDWkMdIx2DpIPJQ1pDHSMdgxxjyUNaQx0jHYOkg8lDIyMdIx2DpIPJQxzDHSMdg6JDyUNaQx0jHYM3AyDjIIPJQ8lDNwMg4x3jyUPJQzcDIOMfY8lDyUM3AyDjIUPJQ8lDNwMg4yFDyUPJQzcDIOMfY8lDyUM3AyDjHkPJQ8lDNwMg4x6jyUPJQzcDIOMfA8lDyUM2oyDjIIPJQ8lDNwMg4x9jyUPJQzcDIOMfw8lDyUM3AyDjIUPJQ8lDNwMg4ySjyUPJQzcDIOMgI8lDyUM3AyDjIIPJQ8lDNwMg4yFDyUPJQ8lDyUMho8lDyUPJQ8lDIgPJQ8lDyUPJQyJjyUPJQyLDyUNaQ8lDI+Miw8lDIyPJQyPjI4PJQ1pDyUMj44LDyUMkQ8lDyUM3A8lDWkNaoyUDNwPJQ1hjWqMlAzcDyUNaQ1qjJQM2o8lDWkNaoyUDNwPJQ1pDWqMlAzajyUNaQ1qjJQM3A8lDJKNaoyUDN8PJQ1pDWqMlAyVjyUMlwyYjJoMm48lDyUPJQ8lDJ0PJQ8lDyUPJQ6SDyUMp48lDyUOkg8lDJ6PJQ8lDKAPJQyhjyUPJQ6SDyUMqQ8lDyUOiQ8lDKePJQ8lDpIPJQyjDyUPJQ6JDyUMp48lDyUOkg8lDKSPJQ8lDKYPJQynjyUPJQ6SDyUMqQ8lDyUMxYzHDL4MygzLjMWMxwy7DMoMy4zFjMcMxAzKDMuMxYzHDMQMygzLjMWMxwyqjMoMy4yyDMcMxAzKDMuMxYzHDKqMygzLjMWMxwysDMoMy4zFjMcMrYzKDMuMxYzHDLsMygzLjMWMxwyvDMoMy4zFjMcMyIzKDMuMxYzHDLCMygzLjLIMxwy+DMoMy4zFjMcMuwzKDMuMxYzHDLOMygzLjLmPJQzXjyUPJQy5jyUMto8lDyUMtQ8lDNePJQ8lDLmPJQy2jyUPJQy5jyUMuA8lDyUMuY8lDMQPJQ8lDMWMxwy7DMoMy4zFjMcMxAzKDMuMxYzHDLyMygzLjMWMxwzIjMoMy4zFjMcMyIzKDMuMxY8lDL4Mygy/jMWMxwzBDMoMy4zFjMcMwozKDMuMxYzHDMQMygzLjMWMxwzIjMoMy4zFjMcMyIzKDMuMxYzHDMiMygzLjM0PJQzOjyUPJQzQDyUM0Y8lDyUM0w8lDNSPJQ8lDNYPJQzXjyUPJQzcDyUM4I8lDyUM3A8lDNkPJQ8lDNwPJQzdjyUPJQzajyUM4I8lDyUM3A8lDNkPJQ8lDNqPJQzgjyUPJQzcDyUM3Y8lDyUM3w8lDOCPJQ8lDOgPJQzpjyUPJQzoDyUM4g8lDyUM6A8lDOOPJQ8lDOgPJQzmjyUPJQzoDyUM5Q8lDyUM6A8lDOmPJQ8lDOgPJQzmjyUPJQzrDyUM6Y8lDyUM6A8lDOyPJQ8lDOsPJQzpjyUPJQzrDyUM7I8lDyUM9A8lDPoM+4z9DO4PJQzvjPEM8oz0DyUM+gz7jP0M9A8lDPoM+4z9DPcPJQz6DPuM/Qz0DyUM9Yz7jP0M9w8lDPoM+4z9DPiPJQz6DPuM/Q23DQGNig8lDQSNtw0BjYuPJQ0EjbcNAY2RjyUNBI23DQGNkY8lDQSNtw0BjZGPJQ0EjbcNAY2LjyUNBI23DQGNhw8lDQSM/o0BjYoPJQ0EjbcNAY2LjyUNBI23DQGNjQ8lDQSNtw0BjYoPJQ0EjbcNAY2LjyUNBIz+jQGNig8lDQSNtw0BjYuPJQ0EjbcNAY2NDyUNBI23DQGNkY8lDQSNtw0BjYuPJQ0EjbcNAY2RjyUNBI23DQGNjo8lDQSNtw0BjQMPJQ0EjbcNAY2KDyUNBI23DQGNAA8lDQSNtw0BjZGPJQ0EjbcNAY0DDyUNBI0GDyUNB48lDyUNDY8lDQkPJQ8lDQ2PJQ0PDyUPJQ0NjyUNCo8lDyUNDY8lDQwPJQ8lDQ2PJQ0PDyUPJQ0bDyUNFQ8lDyUNGw8lDRaPJQ8lDRsPJQ0cjyUPJQ0bDyUNEI8lDyUNGw8lDRIPJQ8lDROPJQ0VDyUPJQ0bDyUNFo8lDyUNGw8lDRgPJQ8lDRsPJQ0ZjyUPJQ0bDyUNHI8lDyUNIQ8lDSWPJQ8lDSEPJQ0eDyUPJQ0hDyUNH48lDyUNIQ8lDSKPJQ8lDSQPJQ0ljyUPJQ05DTqNNg8lDyUNOQ06jTGPJQ8lDTkNOo08DyUPJQ05DTqNKI8lDyUNMA06jTwPJQ8lDTkNOo0ojyUPJQ05DTqNJw8lDyUNOQ06jSiPJQ8lDTkNOo08DyUPJQ05DTqNPA8lDyUNOQ06jSoPJQ8lDTANOo08DyUPJQ05DTqNKg8lDyUNOQ06jSuPJQ8lDTkNOo0tDyUPJQ05DTqNMY8lDyUNOQ06jS6PJQ8lDTANOo02DyUPJQ05DTqNMY8lDyUNOQ06jTMPJQ8lDTkNOo08DyUPJQ05DTqNNI8lDyUNOQ06jTYPJQ8lDTkNOo03jyUPJQ05DTqNN48lDyUNOQ06jTwPJQ8lDyUPJQ09jyUPJQ8lDyUNPw8lDyUNQI8lDUINQ41FDViNWg1PjyUPJQ1YjVoNUQ8lDyUNWI1aDVuPJQ8lDViNWg1bjyUPJQ1YjVoNW48lDyUNWI1aDVuPJQ8lDViNWg1GjyUPJQ1ODVoNW48lDyUNWI1aDUaPJQ8lDViNWg1IDyUPJQ1YjVoNSY8lDyUNWI1aDVEPJQ8lDViNWg1LDyUPJQ1YjVoNTI8lDyUNTg1aDU+PJQ8lDViNWg1RDyUPJQ1YjVoNUo8lDyUNWI1aDVuPJQ8lDViNWg1UDyUPJQ1YjVoNVY8lDyUNWI1aDVWPJQ8lDdmPJQ1XDyUPJQ1YjVoNW48lDyUNXQ1ejWAPJQ8lDWePJQ1pDWqNc41njyUNYY1qjXONZ48lDWkNao1zjWMPJQ1pDWqNc41njyUNaQ1qjXONYw8lDWkNao1zjWePJQ1kjWqNc41mDyUNaQ1qjXONZ48lDWkNao1zjWwPJQ1tjyUPJQ11DyUNew18jX4Nbw8lDXCNcg1zjXUPJQ17DXyNfg11DyUNew18jX4NeA8lDXsNfI1+DXUPJQ12jXyNfg14DyUNew18jX4NeY8lDXsNfI1+DYQPJQ1/jyUPJQ2EDyUNhY8lDyUNhA8lDYEPJQ8lDYQPJQ2CjyUPJQ2EDyUNhY8lDyUNkA8lDYoPJQ8lDZAPJQ2LjyUPJQ2QDyUNkY8lDyUNkA8lDYcPJQ8lDYiPJQ2KDyUPJQ2QDyUNi48lDyUNkA8lDY0PJQ8lDZAPJQ2OjyUPJQ2QDyUNkY8lDyUNlg8lDZqPJQ8lDZYPJQ2TDyUPJQ2WDyUNlI8lDyUNlg8lDZePJQ8lDZkPJQ2ajyUPJQ7UDayNqY8lDyUO1A2sjaUPJQ8lDtQNrI2uDyUPJQ7UDayNnY8lDyUOBQ2sja4PJQ8lDtQNrI2djyUPJQ7UDayNnA8lDyUO1A2sjZ2PJQ8lDtQNrI2uDyUPJQ7UDayNrg8lDyUO1A2sjZ8PJQ8lDgUNrI2uDyUPJQ7UDayNnw8lDyUO1A2sjaCPJQ8lDtQNrI2iDyUPJQ7UDayNpQ8lDyUO1A2sjaOPJQ8lDgUNrI2pjyUPJQ7UDayNpQ8lDyUO1A2sjaaPJQ8lDtQNrI2uDyUPJQ7UDayNqA8lDyUO1A2sjamPJQ8lDtQNrI2rDyUPJQ7UDayNqw8lDyUO1A2sja4PJQ8lDbEPJQ2vjyUPJQ2xDyUNso8lDyUNvQ8lDbQPJQ8lDbcPJQ6/DyUPJQ23DyUNtY8lDyUNtw8lDrePJQ8lDbcPJQ6/DyUPJQ23DyUNtY8lDyUNtw8lDrePJQ8lDbcPJQ66jyUPJQ29DyUOAg6eDyUNuI8lDboNu48lDb0PJQ39jp4PJQ2+jyUNwA3BjyUNww8lDgIOng8lDcSPJQ4CDp4PJQ3GDyUNx46eDyUN2Y3bDdgPJQ8lDdmN2w3SDyUPJQ3ZjdsN3I8lDyUN2Y3bDdyPJQ8lDdmN2w3cjyUPJQ3ZjdsN3I8lDyUN2Y3bDckPJQ8lDdCN2w3cjyUPJQ3ZjdsNyQ8lDyUN2Y3bDcqPJQ8lDdmN2w3MDyUPJQ3ZjdsN0g8lDyUN2Y3bDc2PJQ8lDdmN2w3PDyUPJQ3QjdsN2A8lDyUN2Y3bDdIPJQ8lDdmN2w3TjyUPJQ3ZjdsN3I8lDyUN2Y3bDdUPJQ8lDdmN2w3WjyUPJQ3ZjdsN1o8lDyUN2Y3bDdgPJQ8lDdmN2w3cjyUPJQ60jyUOtg8lDyUN348lDd4PJQ8lDd+PJQ3hDyUPJQ8BDyUOvw8lDyUPAQ8lDrePJQ8lDwEPJQ63jyUPJQ8BDyUOt48lDyUO9o8lDr8PJQ8lDwEPJQ66jyUPJQ8BDyUOvA8lDyUPAQ8lDr8PJQ8lDh6PJQ4dDeiPJQ3ijyUN5A3ljyUN5w8lDh0N6I8lDh6PJQ4gDeiPJQ4ejyUOIA3ojyUOGI8lDh0N6I8lDfYN9430jyUPJQ32DfeN9I8lDyUN9g33jfAPJQ8lDfYN9435DyUPJQ32DfeN+Q8lDyUN9g33jfAPJQ8lDfYN943qDyUPJQ32DfeN648lDyUN9g33je0PJQ8lDe6N9430jyUPJQ32DfeN8A8lDyUN9g33jfGPJQ8lDfYN9435DyUPJQ8lDyUOyA8lDyUN9g33jfMPJQ8lDfYN9430jyUPJQ32DfeN+Q8lDyUPJQ8lDfqPJQ8lDyUPJQ38DyUPJQ4AjyUOAg8lDyUOAI8lDf2PJQ8lDf8PJQ4CDyUPJQ4AjyUOAg8lDyUO1A8lDgmO1w7YjtQPJQ4DjtcO2I7UDyUOCY7XDtiOBQ8lDgmO1w7YjtQPJQ4JjtcO2I4FDyUOCY7XDtiO1A8lDgaO1w7YjggPJQ4JjtcO2I4LDyUODI4ODg+OEQ8lDhQPJQ8lDhKPJQ4UDyUPJQ4ejyUOHQ8lDyUOHo8lDhWPJQ8lDh6PJQ4gDyUPJQ4YjyUOHQ8lDyUOHo8lDhcPJQ8lDhiPJQ4dDyUPJQ4ejyUOGg8lDyUOG48lDh0PJQ8lDh6PJQ4gDyUPJQ4zjjUOLw44DjmOM441DiwOOA45jjOONQ4yDjgOOY4zjjUOMg44DjmOM441DiGOOA45jikONQ4yDjgOOY4zjjUOIY44DjmOM441DiMOOA45jjOONQ4kjjgOOY4zjjUOLA44DjmOM441DiYOOA45jjOONQ42jjgOOY4zjjUOJ444DjmOKQ41Di8OOA45jjOONQ4sDjgOOY4zjjUOKo44DjmOM48lDi8PJQ8lDjOPJQ4sDyUPJQ4pDyUOLw8lDyUOM48lDiwPJQ8lDjOPJQ4qjyUPJQ4zjyUOMg8lDyUOM441DiwOOA45jjOONQ4yDjgOOY4zjjUOLY44DjmOM441DjaOOA45jjOONQ42jjgOOY8lDyUOLw8lDyUOMI41DuYOOA45jjCONQ7ejjgOOY4zjjUOMg44DjmOM441DjaOOA45jjOONQ42jjgOOY4zjjUONo44DjmOOw8lDjyPJQ8lDyUPJQ4+DyUPJQ5CjyUORw8lDyUOQo8lDj+PJQ8lDkKPJQ5EDyUPJQ5BDyUORw8lDyUOQo8lDj+PJQ8lDkEPJQ5HDyUPJQ5CjyUORA8lDyUORY8lDkcPJQ8lDk6PJQ5QDyUPJQ5OjyUOSI8lDyUOTo8lDkoPJQ8lDk6PJQ5NDyUPJQ5OjyUOS48lDyUOTo8lDlAPJQ8lDk6PJQ5NDyUPJQ5RjyUOUA8lDyUOTo8lDlMPJQ8lDlGPJQ5QDyUPJQ5RjyUOUw8lDyUOVg8lDlwOXY8lDlYPJQ5cDl2PJQ5WDyUOVI5djyUOVg8lDlwOXY8lDlkPJQ5cDl2PJQ5WDyUOV45djyUOWQ8lDlwOXY8lDlqPJQ5cDl2PJQ8BDl8O/I8lDmCPAQ5fDvmPJQ5gjwEOXw7/jyUOYI8BDl8O/48lDmCPAQ5fDv+PJQ5gjwEOXw75jyUOYI8BDl8O9Q8lDmCO9o5fDvyPJQ5gjwEOXw75jyUOYI8BDl8O+A8lDmCPAQ5fDvyPJQ5gjwEOXw75jyUOYI72jl8O/I8lDmCPAQ5fDvmPJQ5gjwEOXw74DyUOYI8BDl8O/48lDmCPAQ5fDvmPJQ5gjwEOXw7/jyUOYI8BDl8O+w8lDmCPAQ5fDwQPJQ5gjwEOXw7+DyUOYI8BDl8O/48lDmCPAQ5fDwQPJQ5gjmaPJQ5iDyUPJQ5mjyUOaA8lDyUOZo8lDmOPJQ8lDmaPJQ5lDyUPJQ5mjyUOaA8lDyUOdA8lDm4PJQ8lDnQPJQ5vjyUPJQ50DyUOdY8lDyUOdA8lDmmPJQ8lDnQPJQ5rDyUPJQ5sjyUObg8lDyUOdA8lDm+PJQ8lDnQPJQ5xDyUPJQ50DyUOco8lDyUOdA8lDnWPJQ8lDnoPJQ5+jyUPJQ56DyUOdw8lDyUOeg8lDniPJQ8lDnoPJQ57jyUPJQ59DyUOfo8lDyUOkg6Tjo8PJQ8lDpIOk46KjyUPJQ6SDpOOlQ8lDyUOkg6TjoGPJQ8lDokOk46VDyUPJQ6SDpOOgY8lDyUOkg6TjoAPJQ8lDpIOk46BjyUPJQ6SDpOOlQ8lDyUOkg6TjpUPJQ8lDpIOk46DDyUPJQ6JDpOOlQ8lDyUOkg6TjoMPJQ8lDpIOk46EjyUPJQ6SDpOOhg8lDyUOkg6TjoqPJQ8lDpIOk46HjyUPJQ6JDpOOjw8lDyUOkg6TjoqPJQ8lDpIOk46MDyUPJQ6SDpOOlQ8lDyUOkg6Tjo2PJQ8lDpIOk46PDyUPJQ6SDpOOkI8lDyUOkg6TjpCPJQ8lDpIOk46VDyUPJQ6YDyUOlo8lDyUOmA8lDpmPJQ8lDpsPJQ6cjp4PJQ6wDrGOro8lDyUOsA6xjqiPJQ8lDrAOsY6zDyUPJQ6wDrGOsw8lDyUOsA6xjrMPJQ8lDrAOsY6zDyUPJQ6wDrGOn48lDyUOpw6xjrMPJQ8lDrAOsY6fjyUPJQ6wDrGOoQ8lDyUOsA6xjqKPJQ8lDrAOsY6ojyUPJQ6wDrGOpA8lDyUOsA6xjqWPJQ8lDqcOsY6ujyUPJQ6wDrGOqI8lDyUOsA6xjqoPJQ8lDrAOsY6zDyUPJQ6wDrGOq48lDyUOsA6xjq0PJQ8lDrAOsY6tDyUPJQ8lDyUOro8lDyUOsA6xjrMPJQ8lDrSPJQ62DyUPJQ69jyUOvw8lDyUOvY8lDrePJQ8lDr2PJQ63jyUPJQ69jyUOt48lDyUOuQ8lDr8PJQ8lDr2PJQ66jyUPJQ69jyUOvA8lDyUOvY8lDr8PJQ8lDsyOzg7LDyUPJQ7Mjs4Oyw8lDyUOzI7ODsUPJQ8lDsyOzg7PjyUPJQ7Mjs4Oz48lDyUOzI7ODsUPJQ8lDsyOzg7AjyUPJQ7Mjs4Owg8lDyUOw47ODssPJQ8lDsyOzg7FDyUPJQ7Mjs4Oxo8lDyUOzI7ODs+PJQ8lDyUPJQ7IDyUPJQ7Mjs4OyY8lDyUOzI7ODssPJQ8lDsyOzg7PjyUPJQ8lDyUO0Q8lDyUPJQ8lDtKPJQ8lDtQPJQ7VjtcO2I7aDyUO3Q8lDyUO248lDt0PJQ8lDuePJQ7mDyUPJQ7njyUO3o8lDyUO548lDukPJQ8lDuGPJQ7mDyUPJQ7njyUO4A8lDyUO4Y8lDuYPJQ8lDuePJQ7jDyUPJQ7kjyUO5g8lDyUO548lDukPJQ8lDuwPJQ7yDvOPJQ7sDyUO8g7zjyUO7A8lDuqO848lDuwPJQ7yDvOPJQ7vDyUO8g7zjyUO7A8lDu2O848lDu8PJQ7yDvOPJQ7wjyUO8g7zjyUPAQ8CjvyPJQ8FjwEPAo75jyUPBY8BDwKO/48lDwWPAQ8Cjv+PJQ8FjwEPAo7/jyUPBY8BDwKO+Y8lDwWPAQ8CjvUPJQ8FjvaPAo78jyUPBY8BDwKO+Y8lDwWPAQ8CjvgPJQ8FjwEPAo78jyUPBY8BDwKO+Y8lDwWO9o8CjvyPJQ8FjwEPAo75jyUPBY8BDwKO+A8lDwWPAQ8Cjv+PJQ8FjwEPAo75jyUPBY8BDwKO/48lDwWPAQ8CjvsPJQ8FjwEPAo8EDyUPBY8BDwKO/I8lDwWPAQ8Cjv4PJQ8FjwEPAo7/jyUPBY8BDwKPBA8lDwWPC48lDwcPJQ8lDwuPJQ8NDyUPJQ8LjyUPCI8lDyUPC48lDwoPJQ8lDwuPJQ8NDyUPJQ8ZDyUPEw8lDyUPGQ8lDxSPJQ8lDxkPJQ8ajyUPJQ8ZDyUPDo8lDyUPGQ8lDxAPJQ8lDxGPJQ8TDyUPJQ8ZDyUPFI8lDyUPGQ8lDxYPJQ8lDxkPJQ8XjyUPJQ8ZDyUPGo8lDyUPHw8lDyOPJQ8lDx8PJQ8cDyUPJQ8fDyUPHY8lDyUPHw8lDyCPJQ8lDyIPJQ8jjyUPJQAAQFuA7sAAQFuA7AAAQIWA40AAQHwA6EAAQFuA7YAAQFu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AFYAZQB0AIMAkQCgAK8AvgDNANwA6wD6AQkBGAEnATYAAP//ABUADAAbACoAOQBIAFcAZgB1AIQAkgChALAAvwDOAN0A7AD7AQoBGQEoATcAAP//ABUADQAcACsAOgBJAFgAZwB2AIUAkwCiALEAwADPAN4A7QD8AQsBGgEpATgAAP//ABUADgAdACwAOwBKAFkAaAB3AIYAlACjALIAwQDQAN8A7gD9AQwBGwEqATkBOmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNjbXAHgmNjbXAHgmNjbXAHgmNjbXAHgmNjbXAHgmNjbXAHcmNjbXAHgmNjbXAHgmNjbXAHgmNjbXAHgmNjbXAHgmNjbXAHgmNjbXAHgmNjbXAHgmNjbXAHgmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxvY2wHsGxvY2wHtmxvY2wHvGxvY2wHwmxvY2wHyGxvY2wHzmxvY2wH1GxvY2wH2mxvY2wH4GxvY2wH5mxvY2wH7GxvY2wH8mxvY2wH+GxvY2wH/m51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQgAAAAIAAAABAAAAAQAkAAAAAQAmAAAABgACAAMABAAFAAYABwAAAAQAAgADAAQABQAAAAEAJwAAAAEAGgAAAAMAGwAcAB0AAAABACgAAAABACAAAAABABEAAAABABUAAAABABQAAAABABIAAAABABMAAAABABAAAAABAAkAAAABAA8AAAABAAwAAAABAAsAAAABAAgAAAABAAoAAAABAA0AAAABAA4AAAABABkAAAABACMAAAACAB4AHwAAAAEAIQAAAAEAKQAAAAEAFwAAAAEAJQAAAAEAKgAAAAEAFgAAAAEAGAAAAAEAIgAtAFwG3hGaEkgSrhKuFAIUAhSsFNoVHhUeFUAVQBVAFUAVQBVUFcIV1hX8FhYWPBZKFlgWiBZmFnQWiBaWFt4XJhdIF2AXeBeQF64Z+BxUHUYdZh2OHY4iniM4AAEAAAABAAgAAgRCAh4C+wL8Av0C/gL/AwADAQMCAwMDBAMFAwYDBwMIAyIDIwMtAy4DLwMwAzEDMgNHA0gDSQNLA0wDTQNOA08DUANRA1IDUwNhA2IDYwNkA2UDZgNnA2gDaQNqA2sDbANtA24DbwNwA3EDcgNzA3QDdQN2A3cDeAN5A3oDewN8A30DfgN/A4ADgQOCA4MDhAOGA4cDiAOJA4oDiwOMA40DjgOPA5ADkQOSA5MDlQOWA5cDmAOZA5oDuwPBAvsC/AL9Av4C/wMAAwEDAgMDAwQDBQMGAwcDCAMiAyMDJQMmAycDKAMpAyoDKwMsAy0DLgMvAzADMQMyAzQDNQM3AzgDOQM6AzsDPAM9Az4DPwNAA0EDQgNDA0QDRgNHA0gDSQNKA1QDVQNWA1cDWANZA1oDWwNcA10DXgNfA2EDYgNjA2QDZQNmA2cDaANpA2oDawNsA20DbgNvA3ADcQNyA3MDdAN1A3YDdwN4A3kDegN7A3wDfQN+A38DgAOBA4MDhAOFA4YDhwOIA4kDigOLA4wDjQOOA48DkAORA5IDkwOVA5YDlwOYA5kDmgOjA6QDpQOmA6cDqAOpA6oDqwOsA60DrgOvA7ADsQOyA7MDtAO1A7YDtwO4A7kDugO7A8EDxgM2At0C3gPRA9ID0wPUA9UD1gPXA9gD2QPaA9sD3APdA94D3wPgA+ED4gPjA+QD5QPmA+cD6APpA+oD6wPsA+0D7gPvA/AD8QPyA/MD9AP1A/YD9wP4A/kD+gP7A/wD/QP+A/8EAAQBBAIEAwQEBAUEBgQHBAgECQQKBAsEDAQNBA4EDwQQBBEEEgQTBBQEFQQWBBcEGAQZBBoEGwQcBB0EHgQfBCAEIQQiBCMEJAQlBCYEJwQoBCkEKgQrBCwELQQuBC8EMAQxBDIEMwQ0BDUENgQ3BDgEOQQ6BDsEPAQ9BD4EPwRABEEEQgRDBEQERQRGBEcESARJBEoESwRMBE0ETgRPBFAEUQRSBFMEVARVBFYEVwRYBFkEWgRbBFwEXQReBF8EYARhBGIEYwTjBOUE5gTnBOgE6QTrBOoE7QTuBO8E8ATyBPME9AT1BPYE9wT4BN8E4AT5BPoE+wT8BP0E/gT/BQAFAQUCBQMFBAUFBZoFlQV9BZQFnAWdBZ4FgAWBBaEFhQWGBYcFowWlBaYFigWLBYwFjQWpBaoFqwWQBawFkQWSBZMFrQWuBa8FsAWxBbIFswW0BbUFtgW3BbgFuQX8Bf0F/gX/BgAGAQYCBgMGBAYFBjYGOAZgBmEGZgZnBmgGaQZwBjkGQgZDBkQGRQZGBkcGTwZQBlEGagZrBmwGbQZuBm8GuQa6BrsGvAbcBt4G3QcKBwsHDAcNBw4HDwcQBxEHEgcTBxQHFQcWBxcHGAcZBxoHGwccBx0HHgcfByAHIQciByMHJAdWByYHZgdnB2gHaQdqB2sHbAdtAAIAXgAgACgAAAAqAC4ACQBHAEgADgBSAFcAEABqAG0AFgBvAHYAGgCFAKgAIgCqALcARgC5AL4AVADfAN8AWgDlAOUAWwGmAbMAXAHNAc4AagHQAd0AbAHfAe4AegHxAfUAigH/AgIAjwIEAgsAkwINAi0AmwIvAj8AvAJBAkYAzQJQAmgA0wJuAm4A7AJzAnMA7QJ+An4A7gLbAtwA7wLfAvoA8QMJAyEBDQMkAywBJgMzAzsBLwM9A0YBOANRA1EBQgNUA18BQwOFA4UBTwObA7oBUAO8A8ABcAPCA9ABdQRmBGYBhARtBG8BhQRyBHUBiAR9BH0BjAR/BIEBjQSJBI0BkASTBJMBlQSYBJgBlgScBJwBlwSfBJ8BmASqBKoBmQS8BL8BmgTFBMYBngTLBM0BoATQBNABowTWBNYBpATYBNgBpQUGBQgBpgUKBQoBqQUNBREBqgUVBRYBrwUYBRgBsQUaBRoBsgUdBR0BswUgBSEBtAUkBScBtgUrBS0BugU1BTUBvQU4BTgBvgU8BTwBvwU/BT8BwAVJBUkBwQVdBWIBwgVmBWcByAVsBW4BygVxBXEBzQV5BXkBzgYGBg8BzwYlBiUB2QYnBicB2gYrBiwB2wYuBjIB3QY7BkEB4gZIBkkB6QZMBkwB6wZWBlsB7AavBq8B8gaxBrEB8wazBrMB9Aa1BrUB9QbKBssB9gbYBtgB+AbfBuoB+QbsBu8CBQbyBvwCCQcHBwgCFAdeB2UCFgADAAAAAQAIAAEJtAEyAmoCcgJ4An4ChAKKApAClgKcAqICqAKuArQCugLAAsYCzALSAtgC3gLkAuoC8AL2AvwDAgMIAw4DFAMaAyADJgMsAzIDOAM+A0QDSgNQA1YDXANiA2gDbgN0A3oDgAOGA4wDkgOYA54DpAOqA7ADtgO8A8IDyAPOA9QD2gPgA+YD7APyA/gD/gQEBAoEEAQWBBwEIgQoBC4ENAQ6BEAERgRMBFIEWAReBGQEagRwBHYEfASCBIgEjgSUBJoHdgSgBKYErASyBLgEvgTEBMwE0gTYBN4E5ATqBPAE9gT8BQIFCAUOBRQFGgUgBSYFLAUyBTgFPgVEBUoFUAVWBVwFYgVoBW4FdAV6BYAFhgWMBZIFmAWeBaQFqgWwBbYFvAXCBcgFzgXUBdoF4AXmBewF9AX6BgAGBgYMBhIGGAYeBiQGKgYwBjYGPAZCBkgGTgZUBloGYAZmBmwGcgZ4Bn4GhAaKBpAGlgacBqIGqAauBrQGugbABsYGzAbSBtgG3gbkBuoG8Ab2BvwHAgcIBw4HFAcaByAHJgcsBzIHOgdAB0YHTAdSB1gHXgdkB2oHcAd2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AQIBAwEEAQUBBgEHAQgBCQEKAQsBDAENAQ4BDwEQAREBEgETARQBFQEWARcBGAEZARoBGwEcAR0BHgEfASABIQEiASMBJAElASYBJwEoASkBKgErASwBLQEuAS8BMAExATIBMwE0ATUBNgE4ATkBOgE7ATwBPQE+AT8BQAFBAUIBQwFEAUUBRgFHAUgBSQFKAUsBTAFNAU4BTwFQAVEBUgFTAVQBVQFWAVcBWAFZAVoBWwFcAV0BXgFfAWABYQFiAWMBZAFlAWYBZwFoAWkBagFrAWwBbQFuAW8BcAFxAXIBcwF0AXUBdgF3AXgBeQF6AXsBfAF9AX4BfwGAAYEBggGDAYQBhQGGAYcBiAGJATcCfwKAAoECggKDAoQChQKGAocCiAKJAooCiwKMAo0CjgKPApACkQKSApMClAKVApYClwKYApkCmgKbApwCnQKeAp8CoAKhAqICowKkAqUCpgKnAqgCqQKqAqsCrAKtAq4CrwKwArECsgKzArQCtQK2ArcCuAK5AroCuwK8Ar0CvgK/AsACwQLCAsMCxALFAsYCxwLIAskCygLLAswCzQLOAs8C0ALRAtIC0wLUAtUC1gLXAtgC2QLdAt4D0QPSA9MD1APVA9YD1wPYA9kD2gPbA9wD3QPeA98D4APhA+ID4wPkA+UD5gPnA+gD6QPqA+sD7APtA+4D7wPwA/ED8gPzA/QD9QP2A/cD+AP5A/oD+wP8A/0D/gP/BAAEAQQCBAMEBAQFBAYEBwQIBAkECgQLBAwEDQQOBA8EEAQRBBIEEwQUBBUEFgQXBBgEGQQaBBsEHAQdBB4EHwQgBCEEIgQjBCQEJQQmBCcEKAQpBCoEKwQsBC0ELgQvBDAEMQQyBDMENAQ1BDYENwQ4BDkEOgQ7BDwEPQQ+BD8EQARBBEIEQwREBEUERgRHBEgESQRKBEsETARNBE4ETwRQBFEEUgRTBFQEVQRWBFcEWARZBFoEWwRcBF0EXgRfBGAEYQRiBGME4wTkBOUE5gTnBOgE6QTrBOoE7ATtBO4E7wTwBPEE8gTzBPQE9QT2BPcE+AT5BPoE+wT8BP0E/gT/BQAFAQUCBQMFBAUFBZoFmwWcBZ0FngWfBaAFogWhBaMFpAWlBaYFpwWoBakFqgWrBawFrQWuBa8FsAWxBbIFswW0BbUFtgW3BbgFuQbdAAIAPQAEAB8AAAApACkAHAAvAEYAHQBJAFEANQBYAGkAPgBuAG4AUAB3AIMAUQCpAKkAXgC/AN4AXwDgAOQAfwDmAPUAhAGKAaUAlAG0AcwAsAHPAc8AyQH2Af4AygIuAi4A0wJIAk8A1AJpAm0A3AJvAnIA4QJ0An0A5QLbAtwA7wLfAvoA8QMJAyEBDQMkAywBJgMzAzsBLwM9A0YBOANRA1EBQgNUA18BQwOFA4UBTwObA7oBUAO8A8ABcAPCA9ABdQRmBGYBhARsBG8BhQRyBHUBiQR4BHgBjQR9BH0BjgR/BIIBjwSJBI0BkwSTBJMBmASYBJgBmQSqBKoBmgS8BL8BmwTFBMYBnwTLBM0BoQTQBNABpATWBNYBpQTYBNgBpgUGBQYBpwUMBQ8BqAUSBRUBrAUdBR0BsAUfBSEBsQUpBS0BtAU4BTgBuQVdBWIBugVmBWcBwAVsBW4BwgVxBXEBxQV5BXkBxgbYBtgBxwABAAAAAQAIAAIAWAApAd8B8AY7BwoHCwcMBw0HDgcPBxAHEQcSBxMHFAcVBxYHFwcYBxkHGgcbBxwHHQceBx8HIAchByIHIwckByUHJgcnB2YHZwdoB2kHagdrB2wHbQACAAkB3gHeAAAB7wHvAAEGJgYmAAIG3wbqAAMG7AbvAA8G8gb8ABMHBgcGAB4HCAcJAB8HXgdlACEAAQAAAAEACAACACQADwRkBGUEZARlBfwF/QX+Bf8GAAYBBgIGAwYEBgUGOQABAA8ABACEAYoCDAYGBgcGCAYJBgoGCwYMBg0GDgYPBiYAAA==) format("truetype")}@font-face{font-weight:normal;font-family:"tick42-icons";font-style:normal;src:url(data:font/ttf;base64,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YGAGCAcGqgJK/bYCgP1KJhsaARscJQK2JhsaARscJQAAAQAAAAEAAH2fuHdfDzz1AAsEAAAAAADhVnMIAAAAAOFWcwj//f+9BQADwwAAAAgAAgAAAAAAAAABAAADwP/AAAAFJP/9//0FAAABAAAAAAAAAAAAAAAAAAAA9wQAAAAAAAAAAAAAAAIAAAAEAAAABAAAAAO2//8ESQAAA24AAANuAAACkf//A24AAAO2//8CSQAABAAAAAO2//8CAAAAAmYAAALNAAACHwAAAmYAAAJmAAACqwAAAeEAAAOFAAADhQAAA24AAAQAAAAEkf//AyQAAANWAAACZgAAAOEAAAJIAAADrgAAAysAAAOaAAAEAAAAA24AAAQAAAAEAAAABAAAAAQAAAAEAP/9A24AAAQAAAADWAAAAyQAAANuAAADbgAAA24AAAQAAAADtgAAAbYAAAQAAAAEAAAAA24AAANuAAADbgAAA24AAAQAAAAEAAAABAAAAAQAAAAEAQAABAAAAAQAAAAEAAAAApH//wQA//0EAAAABAD//QQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAAA24AAAO2AAAEAAAAA7b//wMkAAADJAAAAyQAAAQAAAAEAAAAA24AAANuAAADtgAAA7YAAAMkAAADtv//BAAAAAQAAAADbgAABEkAAALbAAADtv//A7b//wQAAAACSQAAAkkAAAFuAAABbgAAAtsAAAQAAAAC2wAABAAAAAO2AAADbgAAA24AAAO2AAADtgAAA7YAAANHAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAADJAAAAtsAAAMkAAADbgAABAAAAANuAAADtv//A7b//wJJAAACSQAAAkkAAAQAAAAEAAAABAAAAAQAAAAESQAABEkAAAQAAAAEAAAAA24AAANuAAACSQAAAkkAAAKRAAACkQAAAW4AAAFuAAACkQAAApEAAARJAAADbgAAA7b//wO2//8EAAAAA24AAAQAAAADtv//BEkAAAO2AAAESQAABAAAAAMkAAACSQAAA7b//wJJAAABbgAAAW4AAAKR//8DJAAAA7b//wKR//8DJAAAANsAAANuAAADbgAAA24AAANuAAACSQAAAkkAAANuAAADtgAAA7YAAAQAAAAEAAAAA24AAANuAAABtgAAAbYAAAQAAAAEAAAABAAAAAUkAAADbgAAA24AAANuAAADbgAAA24AAANuAAADbgAAA24AAANuAAADbgAAA24AAANuAAADbgAABJEAAASRAAAEkQAAA24AAASR//8Ekf//BJH//wSR//8Ekf//BJEAAAQAAAADbgAAA24AAANuAAADbgAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAO2//8DbgAABAAAAAQAAAAEkf//BAAAAAQAAAAAAAAAAAoAFAAeAQgBbAHkAk4DIgP+BEIIOAj2CTQJjAosCkoKZAqCCqQK0Ar8CyoLZguaC9IMNAzEDPINnA4gDl4OfA6wDvoPGg84D2wP0hAGEFQQhBD0EfgSOBJ8Ep4TVhO4FBoUYBXAFioWbBaqFzAXdBfiGFAY1hmWGpYcAhx2HQIdih64IAQgZiFGIhQjcCRuJKwk3iU4JbwmBCYeJjgmuCc6J9IoKihsKJAo0ikCKbIqQiq2KxYr0Cw+LIws+i2gLeguWi6SLxgvoC/8MCAwRjBqMI4wvjDuMRwxTDGIMcQyADI8MqIzGjNgM8o0HjR6NMg1fjbONx43Xjd8OFg4zjlcOdQ6SjrEOwY7SDtyO+Q8VDywPcA+Aj5EPmg+jD8GP5A/+kBUQLRBFEFcQcxCZELCQxRDZkO4RApEOERmRJREwkUkRXJF8EZuRzJHXEe4SAxIiEjQSURJrkniSppLiEv+TFRMlE0ITZpOFk5gTrhPEE9QT5xP7FBEUPZRyFH+UnxS/FOWVDBUyFViVY5VulXoVhZWXFbcV2pYSljeWWxZ4FpIWuJbjlwGXLZdEF2SXeBejF8OX7JgXGB6YLphSmG2YlJi7GNaY/xkdmTkZXRmKGbCZ3poHmiSaWBqSGsga6Zr1Gv4bERspm0SAAEAAAD3As4ADwAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAOAK4AAQAAAAAAAQAMAAAAAQAAAAAAAgAHAI0AAQAAAAAAAwAMAEUAAQAAAAAABAAMAKIAAQAAAAAABQALACQAAQAAAAAABgAMAGkAAQAAAAAACgAaAMYAAwABBAkAAQAYAAwAAwABBAkAAgAOAJQAAwABBAkAAwAYAFEAAwABBAkABAAYAK4AAwABBAkABQAWAC8AAwABBAkABgAYAHUAAwABBAkACgA0AOB0aWNrNDItaWNvbnMAdABpAGMAawA0ADIALQBpAGMAbwBuAHNWZXJzaW9uIDEuMABWAGUAcgBzAGkAbwBuACAAMQAuADB0aWNrNDItaWNvbnMAdABpAGMAawA0ADIALQBpAGMAbwBuAHN0aWNrNDItaWNvbnMAdABpAGMAawA0ADIALQBpAGMAbwBuAHNSZWd1bGFyAFIAZQBnAHUAbABhAHJ0aWNrNDItaWNvbnMAdABpAGMAawA0ADIALQBpAGMAbwBuAHNGb250IGdlbmVyYXRlZCBieSBJY29Nb29uLgBGAG8AbgB0ACAAZwBlAG4AZQByAGEAdABlAGQAIABiAHkAIABJAGMAbwBNAG8AbwBuAC4AAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA) format("truetype")}[class^="icon-"],[class*=" icon-"]{font-weight:normal;font-family:"tick42-icons";font-style:normal;font-variant:normal;line-height:1;text-transform:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.tick42-custom-icon i{color:var(--t42-link-color)}.tick42-custom-icon img{display:block}.tick42-custom-icon.disabled i,.tick42-custom-icon:disabled i{color:var(--t42-content-color-disabled)}i.disabled,.disabled i{color:var(--t42-content-color-disabled)}.icon-size-12 i{font-size:0.75rem}.icon-size-12 i,.icon-size-12 img{width:0.75rem;height:0.75rem}.icon-size-14 i{font-size:0.875rem}.icon-size-14 i,.icon-size-14 img{width:0.875rem;height:0.875rem}.icon-size-24 i{font-size:1.5rem}.icon-size-24 i,.icon-size-24 img{width:1.5rem;height:1.5rem}.icon-size-16 i,.icon-size-16 img{width:1rem;height:1rem}.icon-size-16 i{font-size:1rem}.icon-size-32 i,.icon-size-32 img{width:2rem;height:2rem}.icon-size-32 i{font-size:2rem}.icon-size-48 i,.icon-size-48 img{width:3rem;height:3rem}.icon-size-48 i{font-size:3rem}.icon-size-64 i,.icon-size-64 img{width:4rem;height:4rem}.icon-size-64 i{font-size:4rem}.icon-size-80 i,.icon-size-80 img{width:5rem;height:5rem}.icon-size-80 i{font-size:5rem}.icon-size-96 i,.icon-size-96 img{width:6rem;height:6rem}.icon-size-96 i{font-size:6rem}.icon-size-112 i,.icon-size-112 img{width:7rem;height:7rem}.icon-size-112 i{font-size:7rem}.icon-size-128 i,.icon-size-128 img{width:8rem;height:8rem}.icon-size-128 i{font-size:8rem}.icon-primary i::before{color:#007be5}.icon-secondary i::before{color:#616161}.icon-success i::before{color:#43a047}.icon-info i::before{color:#469eb9}.icon-warning i::before{color:#f9a825}.icon-danger i::before{color:#ff511f}.icon-light i::before{color:#616161}.icon-dark i::before{color:#616161}.icon-dev-tools::before{content:"\e901"}.icon-interop::before{content:"\e900"}.icon-mail::before{content:"\e800"}.icon-attention::before{content:"\e801"}.icon-print::before{content:"\e802"}.icon-picture::before{content:"\e803"}.icon-thumbs-up::before{content:"\e804"}.icon-thumbs-down::before{content:"\e805"}.icon-lock::before{content:"\e806"}.icon-globe::before{content:"\e807"}.icon-calendar::before{content:"\e808"}.icon-location::before{content:"\e809"}.icon-briefcase::before{content:"\e80a"}.icon-export::before{content:"\e80b"}.icon-play::before{content:"\e80c"}.icon-stop::before{content:"\e80d"}.icon-record::before{content:"\e80e"}.icon-pause::before{content:"\e80f"}.icon-to-end::before{content:"\e810"}.icon-to-start::before{content:"\e811"}.icon-check::before{content:"\e812"}.icon-cancel::before{content:"\e813"}.icon-fast-forward::before{content:"\e814"}.icon-fast-backward::before{content:"\e815"}.icon-attention-circled::before{content:"\e816"}.icon-bell::before{content:"\e817"}.icon-chart-bar::before{content:"\e818"}.icon-phone::before{content:"\e819"}.icon-doc-add::before{content:"\e81a"}.icon-layout::before{content:"\e81b"}.icon-dot::before{content:"\e81c"}.icon-dot-2::before{content:"\e81d"}.icon-dot-3::before{content:"\e81e"}.icon-resize-full-1::before{content:"\e81f"}.icon-resize-small-1::before{content:"\e820"}.icon-checkbox::before{content:"\e821"}.icon-cancel-circled::before{content:"\e822"}.icon-03-context-viewer::before{content:"\e823"}.icon-volume-off-1::before{content:"\e824"}.icon-volume::before{content:"\e825"}.icon-headphones-1::before{content:"\e826"}.icon-performance-report::before{content:"\e827"}.icon-pause-1::before{content:"\e828"}.icon-volume-up-1::before{content:"\e829"}.icon-volume-down-1::before{content:"\e82a"}.icon-trash-empty::before{content:"\e839"}.icon-resize-small::before{content:"\e83b"}.icon-resize-full::before{content:"\e83c"}.icon-doc::before{content:"\e83d"}.icon-cog::before{content:"\e83e"}.icon-wrench::before{content:"\e83f"}.icon-resize-vertical::before{content:"\e840"}.icon-resize-horizontal::before{content:"\e841"}.icon-edit::before{content:"\e842"}.icon-pencil-1::before{content:"\e843"}.icon-cw-2::before{content:"\e844"}.icon-ccw-1::before{content:"\e845"}.icon-arrows-cw-1::before{content:"\e847"}.icon-th-large::before{content:"\e848"}.icon-th::before{content:"\e849"}.icon-spin5::before{content:"\e84a"}.icon-spin6::before{content:"\e84b"}.icon-spin4::before{content:"\e84c"}.icon-spin3::before{content:"\e84d"}.icon-spin2::before{content:"\e84e"}.icon-spin1::before{content:"\e84f"}.icon-pin::before{content:"\e850"}.icon-trading-controls::before{content:"\e856"}.icon-icon-coverage::before{content:"\e857"}.icon-taxes::before{content:"\e858"}.icon-credit::before{content:"\e859"}.icon-checkbox-checked::before{content:"\e85a"}.icon-checkbox-indeterminate::before{content:"\e85b"}.icon-radio::before{content:"\e85c"}.icon-radio-choose::before{content:"\e85d"}.icon-arrow-up-down::before{content:"\e85e"}.icon-arrow-double-left::before{content:"\e85f"}.icon-arrow-double-right::before{content:"\e860"}.icon-floppy::before{content:"\e861"}.icon-logout::before{content:"\e862"}.icon-mail-1::before{content:"\e864"}.icon-search-1::before{content:"\e865"}.icon-plus-1::before{content:"\e866"}.icon-minus-1::before{content:"\e867"}.icon-cancel-1::before{content:"\e868"}.icon-ok::before{content:"\e869"}.icon-th-list::before{content:"\e86a"}.icon-help-circled::before{content:"\e86b"}.icon-info-circled::before{content:"\e86c"}.icon-home::before{content:"\e86d"}.icon-link-1::before{content:"\e86e"}.icon-attach-1::before{content:"\e86f"}.icon-lock-open-1::before{content:"\e870"}.icon-eye::before{content:"\e871"}.icon-eye-off::before{content:"\e872"}.icon-tag::before{content:"\e873"}.icon-tags::before{content:"\e874"}.icon-bookmark::before{content:"\e875"}.icon-download-1::before{content:"\e876"}.icon-upload-1::before{content:"\e877"}.icon-forward-1::before{content:"\e878"}.icon-down-dir::before{content:"\e879"}.icon-up-dir::before{content:"\e87a"}.icon-left-dir::before{content:"\e87b"}.icon-right-dir::before{content:"\e87c"}.icon-left-open-1::before{content:"\e87d"}.icon-down-open-1::before{content:"\e87e"}.icon-right-open-1::before{content:"\e87f"}.icon-up-open-1::before{content:"\e880"}.icon-down-big::before{content:"\e881"}.icon-left-big::before{content:"\e882"}.icon-right-big::before{content:"\e883"}.icon-up-big::before{content:"\e884"}.icon-asterisk::before{content:"\e885"}.icon-check-1::before{content:"\e886"}.icon-tick42-icon-monochrome::before{content:"\e887"}.icon-task-manager::before{content:"\e888"}.icon-context-viewer::before{content:"\e889"}.icon-help-2::before{content:"\e88a"}.icon-star-empty-1::before{content:"\e88b"}.icon-star-full::before{content:"\e902"}.icon-move::before{content:"\f047"}.icon-link-ext::before{content:"\f08e"}.icon-check-empty::before{content:"\f096"}.icon-bookmark-empty::before{content:"\f097"}.icon-filter::before{content:"\f0b0"}.icon-resize-full-alt::before{content:"\f0b2"}.icon-docs::before{content:"\f0c5"}.icon-menu-1::before{content:"\f0c9"}.icon-table::before{content:"\f0ce"}.icon-columns::before{content:"\f0db"}.icon-sort::before{content:"\f0dc"}.icon-sort-down::before{content:"\f0dd"}.icon-sort-up::before{content:"\f0de"}.icon-mail-alt::before{content:"\f0e0"}.icon-sitemap::before{content:"\f0e8"}.icon-paste::before{content:"\f0ea"}.icon-exchange::before{content:"\f0ec"}.icon-download-cloud::before{content:"\f0ed"}.icon-upload-cloud::before{content:"\f0ee"}.icon-suitcase-1::before{content:"\f0f2"}.icon-bell-alt::before{content:"\f0f3"}.icon-doc-text-1::before{content:"\f0f6"}.icon-plus-squared::before{content:"\f0fe"}.icon-angle-double-left::before{content:"\f100"}.icon-angle-double-right::before{content:"\f101"}.icon-angle-double-up::before{content:"\f102"}.icon-angle-double-down::before{content:"\f103"}.icon-angle-left::before{content:"\f104"}.icon-angle-right::before{content:"\f105"}.icon-angle-up::before{content:"\f106"}.icon-angle-down::before{content:"\f107"}.icon-laptop::before{content:"\f109"}.icon-circle-empty::before{content:"\f10c"}.icon-quote-left::before{content:"\f10d"}.icon-quote-right::before{content:"\f10e"}.icon-spinner::before{content:"\f110"}.icon-circle::before{content:"\f111"}.icon-reply-1::before{content:"\f112"}.icon-folder-empty::before{content:"\f114"}.icon-folder-open-empty::before{content:"\f115"}.icon-terminal::before{content:"\f120"}.icon-code::before{content:"\f121"}.icon-reply-all-1::before{content:"\f122"}.icon-direction::before{content:"\f124"}.icon-fork::before{content:"\f126"}.icon-unlink::before{content:"\f127"}.icon-help::before{content:"\f128"}.icon-info::before{content:"\f129"}.icon-attention-alt::before{content:"\f12a"}.icon-mic::before{content:"\f130"}.icon-mute::before{content:"\f131"}.icon-calendar-empty::before{content:"\f133"}.icon-lock-open-alt::before{content:"\f13e"}.icon-ellipsis::before{content:"\f141"}.icon-ellipsis-vert::before{content:"\f142"}.icon-minus-squared::before{content:"\f146"}.icon-ok-squared::before{content:"\f14a"}.icon-link-ext-alt::before{content:"\f14c"}.icon-expand-right::before{content:"\f152"}.icon-euro::before{content:"\f153"}.icon-dollar::before{content:"\f155"}.icon-doc-inv::before{content:"\f15b"}.icon-sort-name-up::before{content:"\f15d"}.icon-sort-name-down::before{content:"\f15e"}.icon-sort-alt-up::before{content:"\f160"}.icon-sort-alt-down::before{content:"\f161"}.icon-sort-number-up::before{content:"\f162"}.icon-sort-number-down::before{content:"\f163"}.icon-down::before{content:"\f175"}.icon-up::before{content:"\f176"}.icon-left::before{content:"\f177"}.icon-right::before{content:"\f178"}.icon-cube::before{content:"\f1b2"}.icon-cubes::before{content:"\f1b3"}.icon-database::before{content:"\f1c0"}.icon-file-pdf::before{content:"\f1c1"}.icon-file-word::before{content:"\f1c2"}.icon-file-excel::before{content:"\f1c3"}.icon-file-powerpoint::before{content:"\f1c4"}.icon-file-image::before{content:"\f1c5"}.icon-file-archive::before{content:"\f1c6"}.icon-file-audio::before{content:"\f1c7"}.icon-file-video::before{content:"\f1c8"}.icon-file-code::before{content:"\f1c9"}.icon-circle-thin::before{content:"\f1db"}.icon-sliders::before{content:"\f1de"}.icon-share::before{content:"\f1e0"}.icon-wifi::before{content:"\f1eb"}.icon-bell-off::before{content:"\f1f6"}.icon-bell-off-empty::before{content:"\f1f7"}.icon-copyright::before{content:"\f1f9"}.icon-chart-area::before{content:"\f1fe"}.icon-chart-line::before{content:"\f201"}.icon-toggle-off::before{content:"\f204"}.icon-toggle-on::before{content:"\f205"}.icon-user-plus::before{content:"\f234"}.icon-user-times::before{content:"\f235"}.icon-clone::before{content:"\f24d"}.icon-hourglass-o::before{content:"\f250"}.icon-hourglass-1::before{content:"\f251"}.icon-hourglass-2::before{content:"\f252"}.icon-hourglass-3::before{content:"\f253"}.icon-calendar-plus-o::before{content:"\f271"}.icon-calendar-minus-o::before{content:"\f272"}.icon-calendar-times-o::before{content:"\f273"}.icon-calendar-check-o::before{content:"\f274"}.icon-hashtag::before{content:"\f292"}.icon-low-vision::before{content:"\f2a8"}.icon-envelope-open-o::before{content:"\f2b7"}.icon-address-book-o::before{content:"\f2ba"}.icon-user-o::before{content:"\f2c0"}.icon-window-maximize::before{content:"\f2d0"}.icon-window-minimize::before{content:"\f2d1"}.icon-window-restore::before{content:"\f2d2"}.icon-window-close::before{content:"\f2d3"}.icon-window-close-o::before{content:"\f2d4"}.icon-app::before{content:"\e903"}.icon-download-arrow::before{content:"\e904"}.icon-logo::before{content:"\e905"}.icon-feedback::before{content:"\e906"}.icon-action::before{content:"\e907"}.icon-swimlane::before{content:"\e908"}div.ag-dnd-ghost{border-color:transparent;border-radius:0.25rem;color:var(--white);font-size:0.75rem;font-family:inherit;line-height:inherit;background-color:var(--primary);cursor:default}div .ag-dnd-ghost-icon{display:flex;float:none;padding:0 0.25rem 0 0}div .ag-dnd-ghost-icon .ag-icon{background-color:var(--white)}.ag-tick42{padding-top:0}.ag-tick42 a{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border;border-bottom:0.063rem dashed var(--dark);color:var(--t42-content-color)}.ag-tick42 a:hover{text-decoration:none}.ag-tick42 .ag-filter-body{margin:0}.ag-tick42 input{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border;padding:0 0.5rem;border:var(--t42-border);color:var(--t42-content-color);line-height:2rem;background-color:var(--t42-input-bg)}.ag-tick42 input:focus{border-color:var(--primary);outline:0}.ag-tick42 input.ag-column-name-filter{margin-left:0.5rem}.ag-tick42 .ag-input-wrapper{padding:0.25rem}.ag-tick42 .ag-input-wrapper.ag-checkbox-input-wrapper{padding:0}.ag-tick42 .ag-cell-wrapper.ag-row-group{align-items:center}.ag-tick42 .ag-cell{padding:0 0.25rem;border-bottom:var(--t42-border);line-height:1.875rem;white-space:nowrap;text-overflow:ellipsis}.ag-tick42 .ag-cell .btn,.ag-tick42 .ag-cell .btn-sm,.ag-tick42 .ag-cell .btn-group-sm>.btn,.ag-tick42 .ag-cell .btn-lg,.ag-tick42 .ag-cell .btn-group-lg>.btn{line-height:1.25rem}.ag-tick42 .ag-cell .btn-icon i{position:relative;top:0.0625rem}.ag-tick42 .ag-cell:focus{outline:1px solid var(--primary)}.ag-tick42 .ag-cell .dropdown-toggle{width:20px;height:20px;margin-top:-3px;padding:0;border:0;line-height:22px}.ag-tick42 .ag-cell .dropdown-toggle::after{background-color:transparent;content:""}.ag-tick42 .ag-row::before{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:width;position:absolute;top:0;bottom:0;left:0;z-index:1;width:0;background-color:var(--primary);content:""}.ag-tick42 .ag-row.ag-row-selected{color:var(--t42-link-color);background-color:var(--t42-color-opacity-10)}.ag-tick42 .ag-row.ag-row-selected .ag-icon{color:var(--t42-link-color)}.ag-tick42 .ag-pinned-left-header,.ag-tick42 .ag-pinned-left-cols-container,.ag-tick42 .ag-pinned-right-header,.ag-tick42 .ag-pinned-right-cols-container{background-color:Rgb(var(--t42-bg-mid))}.ag-tick42 .ag-pinned-left-cols-container .ag-row-selected::before,.ag-tick42 .ag-pinned-left-cols-container.ag-hidden+.ag-center-cols-clipper .ag-row-selected::before{width:2px}.ag-tick42 .ag-row-hover{background-color:var(--t42-color-opacity-10)}.ag-tick42 .ag-row-hover .ag-cell{color:var(--t42-link-color)}.ag-tick42 .ag-row-hover .ag-loading .ag-icon-loading::after{background:Rgb(var(--t42-bg-light))}.ag-tick42 .ag-row-hover a{border-bottom-color:var(--t42-content-color);color:var(--t42-link-color)}.ag-tick42 .ag-row-hover a:hover{border-bottom-style:solid}.ag-tick42 .ag-header-row:last-of-type{border-bottom:var(--t42-border)}.ag-tick42 .ag-header-cell,.ag-tick42 .ag-header-group-cell{padding:0 0.25rem;border-top:var(--t42-border);border-left:var(--t42-border);color:Hsl(var(--t42-content-color-base), calc(var(--t42-content-color-l) - 20%))}.ag-tick42 .ag-header-cell:first-of-type,.ag-tick42 .ag-header-group-cell:first-of-type{border-left:0}.ag-tick42 .ag-header-cell .ag-header-cell-label,.ag-tick42 .ag-header-cell .ag-header-group-cell-label,.ag-tick42 .ag-header-group-cell .ag-header-cell-label,.ag-tick42 .ag-header-group-cell .ag-header-group-cell-label{font-weight:normal;font-size:83.3%;line-height:1.875rem;text-transform:uppercase}.ag-tick42 .ag-header-cell .ag-header-select-all,.ag-tick42 .ag-header-group-cell .ag-header-select-all{margin-right:0.5rem}.ag-tick42 .ag-header-cell-moving{background-color:Hsl(var(--t42-bg-light-base), calc(var(--t42-bg-light-l) + 5%))}.ag-tick42 .ag-cell-inline-editing{padding-top:0}.ag-tick42 .ag-cell-edit-input{border-top:0;border-bottom:0;border-radius:0}.ag-tick42 .ag-icon{font-family:inherit}.ag-tick42 .ag-icon::before{content:""}.ag-tick42 .ag-react-container .btn-icon{margin-bottom:0.125rem;padding:0 0.5rem}.ag-tick42 .ag-tabs-header{display:flex;height:1.875rem;border-bottom:var(--t42-border);border-bottom-width:0.063rem}.ag-tick42 .ag-tabs-header .ag-tab{display:flex;align-items:center;justify-content:center;width:1.875rem;height:1.875rem;color:var(--primary);cursor:pointer}.ag-tick42 .ag-tabs-header .ag-tab.ag-tab-selected{background-color:var(--primary)}.ag-tick42 .ag-tabs-header .ag-tab.ag-tab-selected .ag-icon{background-color:var(--white)}.ag-tick42 .ag-tabs-body{max-height:280px;overflow:auto}.ag-tick42 .ag-menu,.ag-tick42 .ag-tool-panel{z-index:1040;border:var(--t42-border);border-radius:0;overflow:initial;background-color:rgba(var(--t42-bg-light), 0.75);box-shadow:var(--t42-shadow);backdrop-filter:var(--backdrop-filter)}.ag-tick42 .ag-menu .ag-column-select-column,.ag-tick42 .ag-menu .ag-column-select-column-group,.ag-tick42 .ag-tool-panel .ag-column-select-column,.ag-tick42 .ag-tool-panel .ag-column-select-column-group{display:flex;align-items:center;margin-left:0;line-height:2rem;cursor:pointer}.ag-tick42 .ag-menu .ag-column-select-column .ag-column-select-checkbox:hover,.ag-tick42 .ag-menu .ag-column-select-column-group .ag-column-select-checkbox:hover,.ag-tick42 .ag-tool-panel .ag-column-select-column .ag-column-select-checkbox:hover,.ag-tick42 .ag-tool-panel .ag-column-select-column-group .ag-column-select-checkbox:hover{color:var(--t42-link-color)}.ag-tick42 .ag-menu .ag-column-select-column:hover,.ag-tick42 .ag-menu .ag-column-select-column-group:hover,.ag-tick42 .ag-tool-panel .ag-column-select-column:hover,.ag-tick42 .ag-tool-panel .ag-column-select-column-group:hover{color:Hsl(var(--t42-content--base), 100%);background-color:var(--t42-color-opacity-10)}.ag-tick42 .ag-menu .ag-column-select-header,.ag-tick42 .ag-tool-panel .ag-column-select-header{padding:0.5rem}.ag-tick42 .ag-menu .ag-column-select-column-label,.ag-tick42 .ag-tool-panel .ag-column-select-column-label{margin-left:0.25rem}.ag-tick42 .ag-tab-body{max-height:220px;overflow:auto}.ag-tick42 .ag-tab-body .ag-set-filter-list{height:9rem}.ag-tick42 .ag-tab-body input{border:var(--t42-border)}.ag-tick42 .ag-tab-body input:focus{border-color:var(--primary)}.ag-tick42 .ag-menu-option{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:color;line-height:2rem;cursor:pointer}.ag-tick42 .ag-menu-option .ag-menu-option-icon{color:var(--t42-content-color)}.ag-tick42 .ag-menu-option .ag-menu-option-icon,.ag-tick42 .ag-menu-option .ag-menu-option-popup-pointer{width:2rem;color:var(--t42-content-color);text-align:center}.ag-tick42 .ag-menu-option .ag-menu-option-icon.ag-menu-option-popup-pointer,.ag-tick42 .ag-menu-option .ag-menu-option-icon:hover,.ag-tick42 .ag-menu-option .ag-menu-option-popup-pointer.ag-menu-option-popup-pointer,.ag-tick42 .ag-menu-option .ag-menu-option-popup-pointer:hover{color:var(--t42-content-color)}.ag-tick42 .ag-menu-option .ag-menu-option-icon.ag-menu-option-popup-pointer .ag-icon,.ag-tick42 .ag-menu-option .ag-menu-option-icon:hover .ag-icon,.ag-tick42 .ag-menu-option .ag-menu-option-popup-pointer.ag-menu-option-popup-pointer .ag-icon,.ag-tick42 .ag-menu-option .ag-menu-option-popup-pointer:hover .ag-icon{color:var(--t42-content-color)}.ag-tick42 .ag-menu-option.ag-menu-option-active{color:var(--t42-link-color);background-color:var(--t42-color-opacity-10)}.ag-tick42 .ag-menu-option.ag-menu-option-active .ag-icon{color:var(--t42-content-color)}.ag-tick42 .ag-menu-separator{border-bottom:var(--t42-border);border-bottom-color:var(--t42-color-opacity-10)}.ag-tick42 .ag-menu-column-select-wrapper,.ag-tick42 .ag-primary-cols-list-panel{height:auto}.ag-tick42 .ag-tool-panel .ag-pivot-mode{padding-top:0.5rem}.ag-tick42 .ag-column-tool-panel-column{padding:0 0.25rem}.ag-tick42 .ag-column-tool-panel-column .ag-icon{margin:0 0.25rem}.ag-tick42 .ag-column-tool-panel-column-label,.ag-tick42 span.ag-column-tool-panel-column-group{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;padding-left:0.25rem}.ag-tick42 .ag-column-tool-panel-column-group .ag-icon{margin:0 0.25rem 0 0}.ag-tick42 .ag-root+.ag-tool-panel{box-shadow:none}.ag-tick42 .ag-row-group-leaf-indent{margin-left:24px}.ag-tick42 .ag-group-expanded,.ag-tick42 .ag-group-contracted{display:flex;align-items:center;min-width:0.75rem;height:100%;margin-right:0.5rem}.ag-tick42 .ag-group-value .ag-react-container{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;display:inline;font-size:87.5%}.ag-tick42 .ag-popup-editor{box-shadow:var(--t42-shadow)}.ag-tick42 .ag-rich-select{border:var(--t42-border);border-radius:0;overflow-y:auto;background-color:Rgb(var(--t42-bg-light), 1)}.ag-tick42 .ag-rich-select-row{padding-left:0.75rem}.ag-tick42 .ag-rich-select-row-selected{background:var(--t42-color-opacity-10)}.ag-tick42 .ag-rich-select-value{position:relative;height:2rem;padding-left:0.75rem;border-bottom:var(--t42-border);line-height:2rem}.ag-tick42 .ag-rich-select-value::before{position:absolute;top:0;bottom:0;left:0;width:3px;background-color:var(--primary);content:""}.ag-tick42 .icon-window-maximize::before,.ag-tick42 .icon-window-minimize::before,.ag-tick42 .icon-window-ok::before{font-size:0.813rem}.ag-tick42 .ag-column-drop{border-top:var(--t42-border)}.ag-tick42 .ag-column-drop.ag-column-drop-horizontal{display:flex;height:1.875rem}.ag-tick42 .ag-column-drop.ag-column-drop-horizontal div{display:flex;align-items:center}.ag-tick42 .ag-column-drop.ag-column-drop-horizontal div:first-of-type{margin-right:0.25rem}.ag-tick42 .ag-column-drop .ag-column-drop-empty-message{align-self:center}.ag-tick42 .ag-column-drop .ag-column-drop-cell{display:flex;height:1.125rem;margin:0.125rem 0.25rem;padding:0 0.125rem 0 0.25rem;border-radius:0.25rem;background-color:Rgb(var(--t42-bg-light))}.ag-tick42 .ag-column-drop .ag-column-drop-cell .ag-column-drop-cell-text{padding:0 0.25rem;line-height:1.125rem}.ag-tick42 .ag-column-drop.ag-column-drop-vertical div{justify-content:start}.ag-tick42 .ag-column-drop.ag-column-drop-vertical .ag-icon-group{margin:0 0.25rem}.ag-tick42 .ag-right-arrow{width:1.5rem;padding:0 0.25rem;overflow:hidden;text-indent:-999px;background-color:var(--t42-content-color);transform:rotate(-90deg);-webkit-mask-image:var(--t42-select-indicator)}.ag-tick42 .ag-right-arrow::before{position:absolute;text-indent:999px}.ag-tick42 .ag-group-checkbox{display:flex;align-items:center;width:1rem;height:100%;margin-right:0.5rem}.ag-tick42 .ag-group-checkbox .ag-icon{width:0.875rem;height:0.875rem}.ag-tick42 .ag-group-checkbox:empty{width:initial}.ag-tick42 .ag-ltr .ag-toolpanel-indent-1{padding-left:1rem}.ag-tick42 .ag-ltr .ag-toolpanel-indent-2{padding-left:2rem}.ag-tick42 .ag-ltr .ag-toolpanel-indent-3{padding-left:3rem}.ag-tick42 .ag-ltr .ag-row-group-indent-1{padding-left:calc(1 * 1.45rem)}.ag-tick42 .ag-ltr .ag-row-group-indent-2{padding-left:calc(2 * 1.45rem)}.ag-tick42 .ag-ltr .ag-row-group-indent-3{padding-left:calc(3 * 1.45rem)}.ag-menu .ag-filter-checkbox{min-width:2rem}.ag-menu .ag-icon-checkbox-checked::after{width:0.625rem;height:0.625rem}.ag-menu .ag-column-group-icons{width:1.5rem}.ag-menu .ag-labeled.ag-label-align-right>div{margin-left:0.25rem}.ag-filter-panel{width:100%}.loading-filter{background-color:rgba(var(--t42-bg-light), 0.75);backdrop-filter:var(--backdrop-filter)}#selectAllContainer,.ag-set-filter-item{display:flex;align-items:center;cursor:pointer}#selectAllContainer .ag-filter-value,#selectAllContainer .ag-set-filter-item-value,.ag-set-filter-item .ag-filter-value,.ag-set-filter-item .ag-set-filter-item-value{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}#selectAllContainer .ag-set-filter-item-value,.ag-set-filter-item .ag-set-filter-item-value{margin-left:0.25rem}.ag-filter-checkbox{justify-content:center;min-width:2rem;color:var(--primary)}.ag-set-filter-item:hover,.ag-filter-header-container:hover label{color:var(--t42-link-color);background-color:var(--t42-color-opacity-10)}.ag-set-filter-item:hover .ag-icon,.ag-filter-header-container:hover label .ag-icon{color:var(--t42-link-color)}.ag-input-text-wrapper{padding:0.25rem 0.25rem 0}.ag-primary-cols-header-panel{align-items:center;padding:0.25rem 0.25rem 0.25rem 0}.ag-primary-cols-header-panel div:nth-child(1){width:1.25rem}.ag-primary-cols-header-panel div:nth-child(2){width:1rem;margin-right:0.25rem}.ag-filter-toolpanel-header{display:flex}.ag-filter-toolpanel-header .ag-header-cell-text{padding:0 0.25rem}.ag-filter-condition{justify-content:space-evenly;padding:0.5rem 0}.ag-filter-condition .ag-labeled.ag-label-align-right div{margin-left:0}.ag-radio-button-label{position:relative;color:var(--t42-content-color-muted);cursor:pointer;user-select:none}.ag-radio-button-input-wrapper::before{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, border;position:absolute;left:-1.125rem;display:block;width:0.875rem;height:0.875rem;border:0.0625rem solid var(--t42-content-color-muted);border-radius:50%;cursor:pointer;content:"";pointer-events:all}.ag-radio-button-input-wrapper::after{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, border;position:absolute;left:-0.875rem;display:block;width:0.375rem;height:0.375rem;border-radius:50%;color:var(--white);background-image:none;transform:scale(0);opacity:0;content:""}.ag-radio-button-input-wrapper:focus{border-color:var(--primary)}.ag-radio-button-input-wrapper.ag-checked::before{border-color:var(--t42-color-opacity-30);background-color:var(--primary)}.ag-radio-button-input-wrapper.ag-checked::after{background-color:var(--white);transform:scale(1);opacity:1}.ag-list{z-index:1100;background-color:rgba(var(--t42-bg-mid), 0.7);backdrop-filter:var(--backdrop-filter)}.ag-list .ag-list-item{padding:0 0.5rem;line-height:2rem;cursor:pointer}.ag-list .ag-list-item:hover{background-color:Rgb(var(--t42-bg-light))}.ag-picker-field-wrapper{height:2rem;padding:0 0.5rem;line-height:2rem;cursor:pointer}.ag-column-select-header-icon{display:flex;align-items:center}.ag-column-select-header .ag-text-field-input{height:1.875rem;line-height:1.875rem}.ag-filter-list-panel .ag-filter-toolpanel-expand{margin:0 0.25rem}.ag-filter-list-panel .ag-filter-toolpanel-group-container,.ag-filter-list-panel .ag-filter-toolpanel-instance-filter{padding-left:0.25rem}.ag-side-bar{position:relative}.ag-side-bar .ag-side-bar-right .ag-tool-panel-horizontal-resize{left:-0.375rem}.ag-side-bar>div:first-child{border:var(--t42-border);background-color:var(--t42-color-opacity-10)}.ag-side-bar .ag-pivot-mode-select{display:flex;padding:0.25rem;border-bottom:var(--t42-border)}.ag-side-bar .ag-pivot-mode-select label{margin:0 0 0 0.5rem}.ag-side-bar .ag-pivot-mode-select .ag-checkbox-label{padding-left:0.25rem}.ag-side-bar .ag-side-buttons div.ag-side-button button{width:1rem;height:1rem;padding:0;border:0.0625rem solid transparent;color:Hsl(var(--t42-content-color-base), 100%);background-color:transparent}.ag-side-bar .ag-side-buttons div.ag-side-button button:hover{color:Hsl(var(--t42-content-color-base), 100%);background-color:Rgb(var(--t42-bg-dark))}.ag-side-bar .ag-side-buttons div.ag-side-button button>span{display:none}.ag-side-bar .ag-side-buttons div.ag-side-button.ag-selected button{border-color:var(--t42-color-opacity-30);background-color:var(--primary)}.ag-side-bar .ag-side-buttons div.ag-side-button.ag-selected button [class*="ag-icon-"]{background-color:var(--white)}.ag-side-bar .ag-icon-checkbox-checked::after{width:0.625rem;height:0.625rem}.ag-side-bar .ag-column-panel,.ag-side-bar .ag-filter-panel{padding-left:0.25rem}.ag-side-bar .ag-filter-checkbox{margin-right:0.25rem}.ag-tool-panel-wrapper{border-top:var(--t42-border);border-bottom:var(--t42-border)}.ag-tool-panel-wrapper .ag-set-filter-list{width:100%;height:auto}.ag-tool-panel-wrapper .ag-column-select-checkbox,.ag-tool-panel-wrapper .ag-column-select-header-checkbox{margin:0 0.25rem}.ag-tool-panel-horizontal-resize{top:initial;width:0.188rem;background-color:var(--t42-color-opacity-10)}.ag-column-panel,.ag-column-select-panel,.ag-column-drop-vertical,.ag-column-drop-list{display:block;min-height:initial;max-height:initial;overflow:visible}.ag-column-panel input,.ag-column-select-panel input,.ag-column-drop-vertical input,.ag-column-drop-list input{border:var(--t42-border)}.ag-column-panel input:focus,.ag-column-select-panel input:focus,.ag-column-drop-vertical input:focus,.ag-column-drop-list input:focus{border-color:var(--primary)}[class*="ag-icon-"],.icon-check-1,.icon-check-empty,.icon-resize-horizontal{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:color, transform;display:block;width:0.75rem;height:0.75rem;margin:0 auto;background-color:var(--t42-content-color);background-image:none;mask-repeat:no-repeat;mask-position:center;cursor:pointer}[class*="ag-icon-"]:hover,.icon-check-1:hover,.icon-check-empty:hover,.icon-resize-horizontal:hover{background-color:var(--t42-link-color)}.ag-menu-option-disabled{color:var(--t42-content-color-disabled)}.ag-menu-option-disabled .ag-icon{background-color:var(--t42-content-color-disabled)}.ag-icon-menu{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M475.4,384v36.4c0,5.1-1.7,9.4-5.1,12.8s-7.9,5.3-13.3,5.6H55c-5.1,0-9.4-1.9-12.8-5.6c-3.4-3.8-5.3-8-5.6-12.8V384 c0-5.1,1.9-9.4,5.6-12.8c3.8-3.4,8-5.3,12.8-5.6h401.9c5.1,0,9.6,1.9,13.3,5.6C474,375,475.7,379.2,475.4,384z M475.4,237.6v36.9 c0,4.8-1.7,9-5.1,12.8s-7.9,5.5-13.3,5.1H55c-5.1,0-9.4-1.7-12.8-5.1s-5.3-7.7-5.6-12.8v-36.9c0-4.8,1.9-9,5.6-12.8 c3.8-3.8,8-5.5,12.8-5.1h401.9c5.1,0,9.6,1.7,13.3,5.1S475.7,232.5,475.4,237.6z M475.4,91.7V128c0,4.8-1.7,9-5.1,12.8 s-7.9,5.6-13.3,5.6H55c-5.1,0-9.4-1.9-12.8-5.6s-5.3-8-5.6-12.8V91.7c0-5.1,1.9-9.6,5.6-13.3c3.8-3.8,8-5.5,12.8-5.1h401.9 c5.1,0,9.6,1.7,13.3,5.1S475.7,86.2,475.4,91.7z%27/%3E%3C/svg%3E%0A")}.ag-header-icon{margin-left:0.125rem}.ag-header-icon .ag-icon-menu{line-height:1.875rem}.ag-icon-asc{-webkit-mask-image:var(--t42-select-indicator);transform:rotate(180deg)}.ag-icon-desc{-webkit-mask-image:var(--t42-select-indicator);margin-bottom:2px}.ag-icon-filter{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 16 16%27%3E%3Cpath d=%27M14.9,1.4c0.1,0.3,0.1,0.5-0.1,0.7L9.9,7v7.4c0,0.3-0.1,0.5-0.4,0.6C9.4,15,9.4,15,9.3,15c-0.2,0-0.3-0.1-0.4-0.2l-2.5-2.5 c-0.1-0.1-0.2-0.3-0.2-0.4V7L1.2,2.1C1,1.9,0.9,1.7,1.1,1.4C1.2,1.1,1.4,1,1.7,1h12.7C14.6,1,14.8,1.1,14.9,1.4L14.9,1.4z%27/%3E%3C/svg%3E")}.ag-icon-none{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 16 16%27%3E%3Cpath d=%27M1 6L5 2Q6 1 7 2L11 6Q11 7 10 7L2 7Q1 7 1 6M2 8Q1 8 1 9L5 13Q6 14 7 13L11 9Q11 8 10 8L2 8%27/%3E%3C/svg%3E%0A")}.ag-icon-indeterminate,.ag-icon-checkbox-indeterminate,.ag-icon-checkbox-indeterminate-readonly,.ag-icon-checkbox-unchecked,.ag-icon-checkbox-unchecked-readonly,.ag-icon-checkbox-checked-readonly,.ag-icon-checkbox-checked,.icon-check-1,.icon-check-empty,.ag-checkbox-input-wrapper,.ag-toggle-button-input-wrapper{position:relative;padding:0;color:var(--t42-content-color-muted);background-color:transparent;cursor:pointer;user-select:none}.ag-icon-indeterminate::before,.ag-icon-checkbox-indeterminate::before,.ag-icon-checkbox-indeterminate-readonly::before,.ag-icon-checkbox-unchecked::before,.ag-icon-checkbox-unchecked-readonly::before,.ag-icon-checkbox-checked-readonly::before,.ag-icon-checkbox-checked::before,.icon-check-1::before,.icon-check-empty::before,.ag-checkbox-input-wrapper::before,.ag-toggle-button-input-wrapper::before{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, border-color;display:block;width:100%;height:100%;border:var(--t42-border);border-color:var(--t42-content-color);cursor:pointer;content:"";pointer-events:all}.ag-icon-indeterminate:focus,.ag-icon-checkbox-indeterminate:focus,.ag-icon-checkbox-indeterminate-readonly:focus,.ag-icon-checkbox-unchecked:focus,.ag-icon-checkbox-unchecked-readonly:focus,.ag-icon-checkbox-checked-readonly:focus,.ag-icon-checkbox-checked:focus,.icon-check-1:focus,.icon-check-empty:focus,.ag-checkbox-input-wrapper:focus,.ag-toggle-button-input-wrapper:focus{border-color:var(--primary)}.ag-icon-indeterminate:hover,.ag-icon-checkbox-indeterminate:hover,.ag-icon-checkbox-indeterminate-readonly:hover,.ag-icon-checkbox-unchecked:hover,.ag-icon-checkbox-unchecked-readonly:hover,.ag-icon-checkbox-checked-readonly:hover,.ag-icon-checkbox-checked:hover,.icon-check-1:hover,.icon-check-empty:hover,.ag-checkbox-input-wrapper:hover,.ag-toggle-button-input-wrapper:hover{background-color:transparent}.ag-icon-checkbox-indeterminate,.ag-icon-checkbox-indeterminate-readonly,.ag-icon-checkbox-checked,.ag-icon-checkbox-checked-readonly,.icon-check-empty,.ag-checkbox-input-wrapper.ag-indeterminate,.ag-checkbox-input-wrapper.ag-checked,.ag-toggle-button-input-wrapper.ag-checked{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background, color}.ag-icon-checkbox-indeterminate::before,.ag-icon-checkbox-indeterminate-readonly::before,.ag-icon-checkbox-checked::before,.ag-icon-checkbox-checked-readonly::before,.icon-check-empty::before,.ag-checkbox-input-wrapper.ag-indeterminate::before,.ag-checkbox-input-wrapper.ag-checked::before,.ag-toggle-button-input-wrapper.ag-checked::before{border:0.0625rem solid var(--t42-color-opacity-30);background:var(--primary)}.ag-icon-checkbox-indeterminate::after,.ag-icon-checkbox-indeterminate-readonly::after,.ag-icon-checkbox-checked::after,.ag-icon-checkbox-checked-readonly::after,.icon-check-empty::after,.ag-checkbox-input-wrapper.ag-indeterminate::after,.ag-checkbox-input-wrapper.ag-checked::after,.ag-toggle-button-input-wrapper.ag-checked::after{position:absolute;top:0.063rem;left:0.063rem;display:block;width:0.75rem;height:0.75rem;background:var(--white);content:""}.ag-icon-checkbox-checked::after,.ag-icon-checkbox-checked-readonly::after,.icon-check-empty::after,.ag-checkbox-input-wrapper.ag-checked::after,.ag-toggle-button-input-wrapper.ag-checked::after{-webkit-mask-image:url("data:image/svg+xml,%3Csvg version=%271.1%27 xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M477.44 152.832q0 11.264-8.192 19.456l-245.76 245.76q-8.192 7.68-19.456 7.68t-19.456-7.68l-142.336-142.336q-7.68-8.192-7.68-19.456t7.68-19.456l38.912-38.912q8.192-8.192 19.456-8.192t19.456 8.192l83.968 84.48 187.392-187.904q8.192-8.192 19.456-8.192t19.456 8.192l38.912 38.912q8.192 7.68 8.192 19.456z%27%3E%3C/path%3E%3C/svg%3E%0A")}.ag-icon-checkbox-indeterminate::after,.ag-icon-checkbox-indeterminate-readonly::after,.ag-checkbox-input-wrapper.ag-indeterminate::after{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 -1 5 6%27%3E%3Cpath d=%27M 1 1 A 1 1 0 0 0 1 2 L 4 2 A 1 1 0 0 0 4 1 L 1 1%27/%3E%3C/svg%3E%0A")}.ag-checkbox-input-wrapper.ag-indeterminate::after{top:0.125rem;left:0.125rem}.ag-checkbox-input-wrapper::before,.ag-toggle-button-input-wrapper::before{width:0.875rem;height:0.875rem}.ag-checkbox-input-wrapper .ag-checkbox-input,.ag-checkbox-input-wrapper .ag-toggle-button-input,.ag-toggle-button-input-wrapper .ag-checkbox-input,.ag-toggle-button-input-wrapper .ag-toggle-button-input{position:absolute;z-index:2;width:0.875rem;height:0.875rem}.ag-icon-columns{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M146.432 374.784v55.296q0 11.264-8.192 18.944t-19.456 8.192h-91.136q-11.776 0-19.456-8.192t-8.192-18.944v-55.296q0-11.264 8.192-19.456t19.456-7.68h91.136q11.776 0 19.456 7.68t8.192 19.456zM146.432 228.864v54.784q0 11.264-8.192 19.456t-19.456 7.68h-91.136q-11.776 0-19.456-7.68t-8.192-19.456v-54.784q0-11.776 8.192-19.456t19.456-8.192h91.136q11.776 0 19.456 8.192t8.192 19.456zM329.216 374.784v55.296q0 11.264-8.192 18.944t-19.456 8.192h-91.136q-11.776 0-19.456-8.192t-8.192-18.944v-55.296q0-11.264 8.192-19.456t19.456-7.68h91.136q11.776 0 19.456 7.68t8.192 19.456zM146.432 82.432v54.784q0 11.264-8.192 19.456t-19.456 8.192h-91.136q-11.776 0-19.456-8.192t-8.192-19.456v-54.784q0-11.264 8.192-19.456t19.456-8.192h91.136q11.776 0 19.456 8.192t8.192 19.456zM329.216 228.864v54.784q0 11.264-8.192 19.456t-19.456 7.68h-91.136q-11.776 0-19.456-7.68t-8.192-19.456v-54.784q0-11.776 8.192-19.456t19.456-8.192h91.136q11.776 0 19.456 8.192t8.192 19.456zM512 374.784v55.296q0 11.264-8.192 18.944t-19.456 8.192h-91.136q-11.264 0-19.456-8.192t-8.192-18.944v-55.296q0-11.264 8.192-19.456t19.456-7.68h91.136q11.776 0 19.456 7.68t8.192 19.456zM329.216 82.432v54.784q0 11.264-8.192 19.456t-19.456 8.192h-91.136q-11.776 0-19.456-8.192t-8.192-19.456v-54.784q0-11.264 8.192-19.456t19.456-8.192h91.136q11.776 0 19.456 8.192t8.192 19.456zM512 228.864v54.784q0 11.264-8.192 19.456t-19.456 7.68h-91.136q-11.264 0-19.456-7.68t-8.192-19.456v-54.784q0-11.776 8.192-19.456t19.456-8.192h91.136q11.776 0 19.456 8.192t8.192 19.456zM512 82.432v54.784q0 11.264-8.192 19.456t-19.456 8.192h-91.136q-11.264 0-19.456-8.192t-8.192-19.456v-54.784q0-11.264 8.192-19.456t19.456-8.192h91.136q11.776 0 19.456 8.192t8.192 19.456z%27%3E%3C/path%3E%3C/svg%3E")}.ag-icon-pin{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M228.4,228.6v-128c0-2.7-0.9-4.9-2.6-6.7s-3.9-2.6-6.7-2.6c-2.7,0-4.9,0.9-6.7,2.6c-1.7,1.7-2.6,3.9-2.6,6.7v128 c0,2.7,0.9,4.9,2.6,6.7c1.7,1.7,3.9,2.6,6.7,2.6c2.7,0,4.9-0.9,6.7-2.6S228.4,231.3,228.4,228.6z M420.4,329.5c0,4.8-1.9,9-5.6,12.8 c-3.8,3.8-8,5.5-12.8,5.1H279.6l-14.8,138.2c-0.3,2.4-1.4,4.3-3.1,5.6c-1.7,1.4-3.6,2.2-5.6,2.6h-0.5c-5.1,0-8-2.6-8.7-7.7 l-22-138.8H109.6c-5.1,0-9.4-1.7-12.8-5.1c-3.4-3.4-5.3-7.7-5.6-12.8c0-23.6,7.5-44.7,22.5-63.5s31.9-28.2,50.7-28.2V91.4 c-9.9,0-18.4-3.6-25.6-10.8c-7.2-7.2-10.9-15.7-11.3-25.6s3.4-18.4,11.3-25.6c7.9-7.2,16.4-10.9,25.6-11.3h182.8 c9.9,0,18.4,3.8,25.6,11.3s10.8,16,10.8,25.6s-3.6,18.1-10.8,25.6S357,91.7,347.1,91.4v146.4c18.8,0,35.7,9.4,50.7,28.2 C412.8,284.8,420.4,305.9,420.4,329.5L420.4,329.5z%27/%3E%3C/svg%3E")}.ag-icon-small-right,.ag-icon-small-down{width:0.65rem;height:0.65rem;-webkit-mask-image:var(--t42-select-indicator);transform:rotate(-90deg)}.ag-icon-small-down{transform:rotate(0)}.ag-icon-tick{-webkit-mask-image:url("data:image/svg+xml,%3Csvg version=%271.1%27 xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M477.44 152.832q0 11.264-8.192 19.456l-245.76 245.76q-8.192 7.68-19.456 7.68t-19.456-7.68l-142.336-142.336q-7.68-8.192-7.68-19.456t7.68-19.456l38.912-38.912q8.192-8.192 19.456-8.192t19.456 8.192l83.968 84.48 187.392-187.904q8.192-8.192 19.456-8.192t19.456 8.192l38.912 38.912q8.192 7.68 8.192 19.456z%27%3E%3C/path%3E%3C/svg%3E%0A")}.ag-icon-copy{-webkit-mask-image:url("data:image/svg+xml,")}.ag-icon-csv,.ag-icon-excel{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M0 0zq0-7.7-5.1-12.8zM475.3 356.6v91.6q0 11.3-8.2 18.9t-19.5 8.2h-420.4q-11.8 0-19.5-8.2t-8.2-18.9v-91.6q0-11.3 8.2-19.5t19.5-8.2h132.6l38.4 38.9q16.9 16.4 38.9 16.4t38.9-16.4l38.9-38.9h132.6q11.3 0 19.5 8.2t8.2 19.5zM382.1 193.8q5.1 11.8-4.1 20l-128 128q-5.1 5.6-12.8 5.6t-12.8-5.6l-128-128q-8.7-8.2-4.1-20q5.1-10.8 16.9-10.8h73.2v-128q0-7.7 5.6-12.8t12.8-5.6h73.2q7.2 0 12.8 5.6t5.1 12.8v128h73.2q12.3 0 16.9 10.8M347 439A1 1 0 00347 402A1 1 0 00347 439M420 439A1 1 0 00420 402A1 1 0 00420 439zz%27/%3E%3C/svg%3E%0A")}.ag-icon-expanded{-webkit-mask-image:var(--t42-select-indicator);transform:rotate(-90deg)}.ag-icon-contracted{-webkit-mask-image:var(--t42-select-indicator);transform:rotate(90deg)}.ag-header-expand-icon-collapsed .ag-icon-contracted{margin-bottom:1px;transform:rotate(90deg);-webkit-mask-image:var(--t42-select-indicator)}.ag-icon-paste{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M219.648 475.648h256v-183.296h-119.296q-11.264 0-18.944-7.68t-8.192-19.456v-118.784h-109.568v329.216zM292.352 64v-18.432q0-3.584-2.56-6.144t-6.144-3.072h-201.216q-3.584 0-6.656 3.072t-2.56 6.144v18.432q0 3.584 2.56 6.656t6.656 2.56h201.216q3.584 0 6.144-2.56t2.56-6.656zM365.568 256h85.504l-85.504-85.504v85.504zM512 292.352v192q0 11.776-8.192 19.456t-19.456 8.192h-273.92q-11.776 0-19.456-8.192t-8.192-19.456v-45.568h-155.136q-11.776 0-19.456-8.192t-8.192-18.944v-384q0-11.776 8.192-19.456t19.456-8.192h310.784q11.264 0 19.456 8.192t7.68 19.456v93.696q6.144 3.584 10.24 7.68l116.736 116.736q8.192 7.68 13.824 21.504t5.632 25.088z%27%3E%3C/path%3E%3C/svg%3E%0A")}.ag-icon-arrows{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M512 256q0 7.168-5.632 12.8l-72.704 73.216q-5.632 5.632-13.312 5.632t-12.8-5.632-5.12-12.8v-36.864h-110.080v110.080h36.864q7.168 0 12.8 5.12t5.632 12.8-5.632 12.8l-73.216 73.216q-5.12 5.632-12.8 5.632t-12.8-5.632l-73.216-73.216q-5.632-5.12-5.632-12.8t5.632-12.8 12.8-5.12h36.864v-110.080h-110.080v36.864q0 7.168-5.12 12.8t-12.8 5.632-12.8-5.632l-73.216-73.216q-5.632-5.632-5.632-12.8t5.632-12.8l73.216-73.216q5.12-5.632 12.8-5.632t12.8 5.632 5.12 12.8v36.864h110.080v-110.080h-36.864q-7.168 0-12.8-5.12t-5.632-12.8 5.632-13.312l73.216-72.704q5.632-5.632 12.8-5.632t12.8 5.632l73.216 72.704q5.632 5.632 5.632 13.312t-5.632 12.8-12.8 5.12h-36.864v110.080h110.080v-36.864q0-7.168 5.12-12.8t12.8-5.632 13.312 5.632l72.704 73.216q5.632 5.12 5.632 12.8z%27%3E%3C/path%3E%3C/svg%3E%0A")}.ag-icon-not-allowed{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27m 182.8 238.1 h 145.9 v -55.3 c 0 -20.1 -7.2 -37.4 -21.5 -51.7 s -31.6 -21.3 -51.7 -21 c -20.1 0.3 -37.4 7.3 -51.7 21 s -21.3 30.9 -21 51.7 l -0 55.3 l 0 0 z m 237.6 27.1 v 164.9 c 0 7.5 -2.7 13.8 -8.2 18.9 s -11.9 7.9 -19.5 8.2 h -273.9 c -7.9 0 -14.3 -2.7 -19.5 -8.2 c -5.1 -5.5 -7.9 -11.8 -8.2 -18.9 v -164.9 c 0 -7.5 2.7 -14 8.2 -19.5 s 11.9 -8 19.5 -7.7 h 8.7 v -55.3 c 0 -34.8 12.6 -64.9 37.9 -90.1 s 55.3 -37.9 90.1 -37.9 s 65 12.6 90.6 37.9 s 38.1 55.3 37.4 90.1 v 55.3 h 9.2 c 7.9 0 14.3 2.6 19.5 7.7 s 7.8 11.7 8.2 19.5 z%27/%3E%3C/svg%3E")}.ag-icon-eye-slash{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M 475.6 256.3 q -43.5 -67.6 -109.1 -100.9 q 17.4 29.7 17.4 64 q 0 52.7 -37.4 90.6 t -90.6 37.4 t -90.6 -37.4 t -37.4 -90.6 q 0 -34.3 17.4 -64 q -65.5 33.3 -109.1 100.9 q 38.4 58.4 95.7 93.2 t 123.9 34.8 t 124.4 -34.8 t 95.2 -93.2 z M 269.8 146.2 q 0 -5.6 -4.1 -9.7 t -9.7 -3.6 q -35.8 0 -61.4 25.6 t -25.6 60.9 q 0 5.6 4.1 9.7 t 9.7 4.1 t 9.7 -4.1 t 4.1 -9.7 q 0 -24.6 17.4 -42 t 42 -17.4 q 5.6 0 9.7 -4.1 t 4.1 -9.7 z M 512 256.3 q 0 9.7 -5.6 19.5 q -39.9 66 -107.5 105.5 t -142.8 39.4 t -142.8 -39.4 t -107.5 -105.5 q -5.6 -9.7 -5.6 -19.5 t 5.6 -20 q 39.9 -65.5 107.5 -105 t 142.8 -39.9 t 142.8 39.9 t 107.5 105 q 5.6 10.2 5.6 20 z%27%3E%3C/path%3E%3C/svg%3E%0A")}.ag-icon-group{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M146.4 374.8v55.3q0 11.3-8.2 18.9t-19.5 8.2h-91.1q-11.8 0-19.5-8.2t-8.2-18.9v-55.3q0-11.3 8.2-19.5t19.5-7.7h91.1q11.8 0 19.5 7.7t8.2 19.5zM146.4 228.9v54.8q0 11.3-8.2 19.5t-19.5 7.7h-91.1q-11.8 0-19.5-7.7t-8.2-19.5v-54.8q0-11.8 8.2-19.5t19.5-8.2h91.1q11.8 0 19.5 8.2t8.2 19.5zM512 374.8v55.3q0 11.3-8.2 18.9t-19.5 8.2h-273.9q-11.8 0-19.5-8.2t-8.2-18.9v-55.3q0-11.3 8.2-19.5t19.5-7.7h273.9q11.8 0 19.5 7.7t8.2 19.5zM146.4 82.4v54.8q0 11.3-8.2 19.5t-19.5 8.2h-91.1q-11.8 0-19.5-8.2t-8.2-19.5v-54.8q0-11.3 8.2-19.5t19.5-8.2h91.1q11.8 0 19.5 8.2t8.2 19.5zM512 228.9v54.8q0 11.3-8.2 19.5t-19.5 7.7h-273.9q-11.8 0-19.5-7.7t-8.2-19.5v-54.8q0-11.8 8.2-19.5t19.5-8.2h273.9q11.8 0 19.5 8.2t8.2 19.5zM512 82.4v54.8q0 11.3-8.2 19.5t-19.5 8.2h-273.9q-11.8 0-19.5-8.2t-8.2-19.5v-54.8q0-11.3 8.2-19.5t19.5-8.2h273.9q11.8 0 19.5 8.2t8.2 19.5z%27%3E%3C/path%3E%3C/svg%3E%0A")}.ag-icon-grip{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 16 16%27%3E%3Cpath d=%27M4 3L6 3L6 5L4 5L4 3M4 7L6 7L6 9L4 9L4 7M4 11L6 11L6 13L4 13L4 11M8 3L10 3L10 5L8 5L8 3M8 7L10 7L10 9L8 9L8 7M8 11L10 11L10 13L8 13L8 11%27/%3E%3C/svg%3E%0A");margin:0}.ag-icon-tree-open{-webkit-mask-image:var(--t42-select-indicator);transform:rotate(180deg)}.ag-icon-tree-closed{-webkit-mask-image:var(--t42-select-indicator);transform:rotate(270deg)}.ag-icon-tree-indeterminate{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 -1 5 6%27%3E%3Cpath d=%27M 1 1 A 1 1 0 0 0 1 2 L 4 2 A 1 1 0 0 0 4 1 L 1 1%27/%3E%3C/svg%3E%0A")}.ag-icon-save{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M 420.6 319.2 V 393 c 0 22.9 -8 42.3 -24.1 58.4 s -35.5 24.1 -58.4 24.1 H 100.6 c -22.9 0 -42.3 -8 -58.4 -24.1 S 18.2 415.8 18.2 393 V 155.4 c 0 -22.5 8 -41.8 24.1 -57.9 S 77.7 73.3 100.6 73 h 72.7 c 2.4 0 4.6 1 6.7 3.1 c 2 2 2.9 4.1 2.6 6.1 c 0 5.1 -2.6 8.2 -7.7 9.2 c -14.7 5.1 -27.3 10.9 -37.9 17.4 c -1.7 0.7 -3.2 1 -4.6 1 h -31.7 c -12.6 0 -23.4 4.4 -32.3 13.3 s -13.5 19.6 -13.8 32.3 V 393 c 0 12.6 4.6 23.4 13.8 32.3 c 9.2 8.9 20 13.5 32.3 13.8 h 237.6 c 12.6 0 23.4 -4.6 32.3 -13.8 c 8.9 -9.2 13.3 -20 13.3 -32.3 V 332 c 0 -3.8 1.7 -6.5 5.1 -8.2 c 5.5 -2.4 10.8 -6 15.9 -10.8 c 2.7 -3.1 6 -3.8 9.7 -2 C 418.6 312.7 420.6 315.5 420.6 319.2 L 420.6 319.2 z M 488.2 177.4 L 378.6 287 c -3.4 3.8 -7.7 5.6 -12.8 5.6 c -2.4 0 -4.8 -0.5 -7.2 -1.5 c -7.5 -3.1 -11.3 -8.7 -11.3 -16.9 v -54.8 h -45.6 c -61.8 0 -103.6 12.5 -125.4 37.4 c -22.5 26.3 -29.5 71.3 -21 135.2 c 0.7 4.4 -1.2 7.7 -5.6 9.7 c -1.7 0.3 -2.9 0.5 -3.6 0.5 c -3.1 0 -5.5 -1.2 -7.2 -3.6 c -2 -2.7 -4.1 -5.6 -6.1 -8.7 c -2 -3.1 -5.8 -9.7 -11.3 -20 c -5.5 -10.2 -10.2 -19.6 -14.3 -28.2 c -4.1 -8.5 -7.7 -19.5 -10.8 -32.8 c -3.1 -13.3 -4.8 -24.9 -5.1 -34.8 c 0 -9.2 0.3 -17.9 1 -26.1 c 0.7 -8.2 2 -16.7 4.1 -25.6 c 2 -8.9 4.6 -17.2 7.7 -25.1 c 3.1 -7.9 7.7 -15.5 13.8 -23 c 6.1 -7.5 12.6 -14.7 19.5 -21.5 s 15.7 -12.6 26.6 -17.4 c 10.9 -4.8 22.9 -9.4 35.8 -13.8 c 13 -4.4 28.2 -7.3 45.6 -8.7 s 36.2 -2.4 56.3 -3.1 h 45.6 V 55 c 0 -8.2 3.8 -13.8 11.3 -16.9 c 2.4 -1 4.8 -1.5 7.2 -1.5 c 4.8 0 9 1.9 12.8 5.6 l 109.6 109.6 c 3.8 3.4 5.6 7.7 5.6 12.8 S 491.9 174 488.2 177.4 L 488.2 177.4 z%27/%3E%3C/svg%3E")}.ag-tooltip{padding:0.125rem 0.5rem;border:0.0625rem solid var(--t42-color-opacity-10);border-radius:0.25rem;background:Rgb(var(--t42-bg-light));box-shadow:var(--t42-shadow)}.ag-icon-cancel{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M366.9 336.4c6.1 6.1 9.2 13.5 9.2 22s-3.1 15.9-9.2 22c-6.1 5.5-13.5 8.2-22 8.2c-8.5 0-15.9-2.7-22-8.2l-67.6-77.8l-67.6 77.8c-6.1 5.5-13.5 8.2-22 8.2c-8.5 0-15.9-2.7-22-8.2c-5.5-6.1-8.2-13.5-8.2-22s2.7-15.9 8.2-22l70.7-79.9l-70.7-80.9c-5.5-6.1-8.2-13.5-8.2-22c0-8.5 2.7-15.9 8.2-22c6.1-5.5 13.5-8.2 22-8.2c8.5 0 15.9 2.7 22 8.2l67.6 77.8l67.6-77.8c6.1-5.5 13.5-8.2 22-8.2c8.5 0 15.9 2.7 22 8.2c6.1 6.1 9.2 13.5 9.2 22c0 8.5-3.1 15.9-9.2 22l-70.7 80.9L366.9 336.4z%27/%3E%3C/svg%3E")}.icon-check-empty::after{width:0.65rem;height:0.65rem}.icon-resize-horizontal{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M512 256q0 7.2-5.6 12.8l-72.7 73.2q-5.6 5.6-13.3 5.6t-12.8-5.6t-5.1-12.8v-36.9h-292.9v36.9q0 7.2-5.1 12.8t-12.8 5.6t-12.8-5.6l-73.2-73.2q-5.6-5.6-5.6-12.8t5.6-12.8l73.2-73.2q5.1-5.6 12.8-5.6t12.8 5.6t5.1 12.8v36.9h292.9v-36.9q0-7.2 5.1-12.8t12.8-5.6t13.3 5.6l72.7 73.2q5.6 5.1 5.6 12.8z%27%3E%3C/path%3E%3C/svg%3E%0A")}.ag-icon-aggregation{margin:0 0.25rem;-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 16 16%27%3E%3Cpath d=%27M3.6,1.7c-0.2,0.7-0.9,1.1-1.5,1C1.5,2.6,1,2,1,1.3C1,0.7,1.5,0.1,2.1,0c0.4-0.1,0.7,0,1,0.2C3.4,0.4,3.6,0.7,3.7,1 c0.3,0,0.5,0.1,0.8,0.3C4.7,1.5,5,1.8,5.2,2.1c0.2,0.3,0.4,0.7,0.6,1c0.1,0.2,0.3,0.5,0.5,0.7c0.2,0.2,0.5,0.5,0.8,0.6 c0.1,0.1,0.3,0.1,0.5,0.1c0.6,0,2.3,0,2.9,0c0.4,0,0.7,0,1.1,0c0,0,0,0,0.1,0c0,0,0,0,0-0.1c0-0.1,0-0.2,0-0.3c0,0,0-0.1,0-0.1 c0-0.1,0.1-0.1,0.2-0.1c0.1,0,0.1,0,0.1,0.1c0.1,0,0.1,0.1,0.2,0.2c0.2,0.2,0.3,0.3,0.5,0.5C12.8,4.8,13,5,13.1,5.1c0,0,0,0,0,0 c0,0,0,0-0.1,0c-1.5,0-4.1,0-5.7,0C7.2,5.2,7,5.1,6.8,5C6.6,4.9,6.3,4.8,6.1,4.6C5.7,4.3,5.5,4,5.2,3.5C5,3.2,4.8,2.8,4.6,2.4 C4.4,2.2,4.3,2.1,4.1,1.9C4,1.8,3.9,1.7,3.8,1.7C3.7,1.7,3.7,1.7,3.6,1.7z%27/%3E%3Cpath d=%27M3.6,7.7c1,0,10.6,0,11,0c0.1,0,0.1,0,0.1,0.1C14.8,7.8,14.9,7.9,15,8c-0.1,0.1-0.2,0.2-0.3,0.3c0,0,0,0-0.1,0 c0,0,0,0-0.1,0c-3.3,0-7.7,0-10.9,0C3.5,8.8,3.2,9.1,2.8,9.3C2.5,9.4,2.2,9.4,2,9.3C1.4,9.1,1,8.6,1,8c0-0.7,0.5-1.2,1.1-1.3 c0.3-0.1,0.7,0,1,0.2C3.4,7.1,3.6,7.3,3.6,7.7z%27/%3E%3Cpath d=%27M13.1,10.9C13.1,10.9,13.1,10.9,13.1,10.9c-0.3,0.3-0.6,0.6-0.8,0.8c-0.1,0.1-0.2,0.2-0.3,0.3c0,0-0.1,0.1-0.1,0.1 c0,0-0.1,0-0.1,0c-0.1,0-0.1,0-0.2-0.1c0,0,0-0.1,0-0.1c0-0.1,0-0.2,0-0.3c0,0,0,0,0-0.1c-1,0-3.1,0-4.1,0c-0.1,0-0.3,0-0.4,0.1 c-0.3,0.1-0.5,0.2-0.7,0.4c-0.2,0.2-0.4,0.5-0.6,0.8c-0.2,0.4-0.4,0.7-0.7,1.1c-0.2,0.2-0.4,0.4-0.6,0.6c-0.1,0.1-0.3,0.2-0.4,0.3 c-0.1,0.1-0.3,0.2-0.4,0.2c0,0-0.1,0-0.1,0c-0.1,0.4-0.3,0.7-0.7,0.9C2.7,16,2.4,16,2.1,16C1.5,15.9,1,15.3,1,14.7 c0-0.7,0.5-1.2,1-1.3c0.3-0.1,0.7,0,1,0.2c0.3,0.2,0.5,0.5,0.6,0.8c0.1,0,0.2,0,0.2,0C4,14.2,4.1,14.1,4.2,14 c0.2-0.2,0.3-0.4,0.5-0.6c0.2-0.3,0.4-0.6,0.6-1c0.2-0.3,0.4-0.6,0.6-0.9c0.3-0.2,0.5-0.5,0.9-0.6c0.2-0.1,0.4-0.1,0.6-0.1 c0,0,0.1,0,0.1,0c0.6,0,2.4,0,3,0c0.8,0,1.7,0,2.5,0C13.1,10.9,13.1,10.9,13.1,10.9C13.1,10.9,13.1,10.9,13.1,10.9z%27/%3E%3Cpath d=%27M3.6,11.7c-0.1,0.4-0.3,0.7-0.7,0.9c-0.3,0.2-0.6,0.2-0.9,0.1C1.5,12.6,1,12.1,1,11.4c0-0.7,0.5-1.2,1.1-1.3 c0.3-0.1,0.7,0,1,0.2c0.3,0.2,0.5,0.5,0.6,0.8c0.1,0,0.1,0,0.2,0c0.2,0,0.3-0.1,0.4-0.2c0.2-0.1,0.4-0.3,0.5-0.4 C4.9,10.3,5,10.2,5,10.2C5.3,9.9,5.6,9.7,6,9.6c0.3-0.1,0.6-0.2,0.8-0.2c0.1,0,0.1,0,0.2,0c1.1,0,3.4,0,4.5,0c0.9,0,1.8,0,2.6,0 c0,0,0,0,0.1,0c0,0,0,0,0,0C14,9.6,13.8,9.8,13.6,10c-1.8,0-4.8,0-6.6,0c-0.3,0-0.6,0.1-0.9,0.2c-0.2,0.1-0.5,0.3-0.6,0.5 c-0.3,0.3-0.5,0.5-0.8,0.7c-0.2,0.1-0.4,0.2-0.6,0.3C3.9,11.7,3.8,11.7,3.6,11.7C3.7,11.7,3.7,11.7,3.6,11.7z%27/%3E%3Cpath d=%27M3.6,4.9C3.5,5.3,3.3,5.6,2.9,5.8C2.6,5.9,2.3,6,2,5.9C1.4,5.7,1,5.2,1,4.5c0-0.6,0.5-1.2,1.1-1.3c0.7-0.1,1.4,0.3,1.5,1 c0,0,0.1,0,0.1,0c0.3,0,0.5,0.1,0.7,0.3C4.7,4.7,5,4.9,5.2,5c0.1,0.1,0.2,0.2,0.4,0.4c0.3,0.3,0.6,0.5,1,0.5C6.7,6,6.9,6,7,6 c1.8,0,4.8,0,6.6,0c0.1,0.1,0.3,0.3,0.6,0.6c0,0,0,0,0,0c0,0,0,0,0,0c0,0,0,0-0.1,0c-2,0-5.1,0-7.1,0c-0.3,0-0.5,0-0.8-0.1 C6,6.5,5.7,6.4,5.5,6.2C5.3,6.1,5.1,5.9,5,5.8C4.8,5.5,4.5,5.3,4.2,5.1C4.1,5,3.9,4.9,3.6,4.9z%27/%3E%3C/svg%3E%0A")}.ag-icon-loading{position:relative;width:1rem;height:1rem;border-radius:50%;background:linear-gradient(to right, var(--t42-icon-color), Rgba(var(--t42-bg-dark) 42%));transform:translateZ(0);animation:icon-loading 1.4s infinite linear}.ag-icon-loading::before{position:absolute;top:0;left:0;width:50%;height:50%;border-radius:100% 0 0;background:var(--t42-icon-color);content:""}.ag-icon-loading::after{position:absolute;top:0;right:0;bottom:0;left:0;width:75%;height:75%;margin:auto;border-radius:50%;background:Rgb(var(--t42-bg-dark));content:""}.ag-loading{display:flex;padding-left:0.5rem}@keyframes icon-loading{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.search{position:relative}.search i{position:absolute;top:0.625rem;right:0.75rem;width:.75rem;height:.75rem;background-color:var(--t42-content-color);-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M328.9 219.4q0-52.7-37.4-90.1t-90.6-37.9t-90.6 37.9t-37.4 90.1t37.4 90.6t90.6 37.4t90.6-37.4t37.4-90.6zM475.3 457.5q0 14.8-11.3 25.6t-25.6 10.8q-15.4 0-25.6-10.8l-97.8-97.8q-51.2 35.3-114.2 35.3q-41 0-78.3-15.9t-64-43t-43-64t-15.9-78.3t15.9-77.8t43-64.5t64-43t78.3-15.9t78.3 15.9t64 43t43 64.5t15.9 77.8q0 63-35.3 114.2l97.8 97.8q10.8 10.8 10.8 26.1z%27%3E%3C/path%3E%3C/svg%3E%0A")}.search-results{position:absolute;top:33px;max-height:215px;overflow-y:auto}.search-results .list-group-item{white-space:nowrap}.select{position:relative;z-index:12;display:flex;align-items:center;justify-content:center;width:100%;height:2rem;list-style:none;cursor:pointer}.select input[type="radio"]{opacity:1}.select_expand{position:absolute;top:0;right:0;width:0;height:2rem}.select_expand::after{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:transform;position:absolute;top:50%;right:0;z-index:2;width:1rem;height:1rem;background:var(--t42-select-indicator) center center/1rem 1rem no-repeat;transform:translate(-65%, -55%);content:"";pointer-events:none}.select_expand:checked+.select_close_label+.select_options .select_label:hover{color:var(--t42-link-hover-color);background-color:var(--t42-link-active-bg)}.select_expand:checked::after{transform:translate(-65%, -55%) rotate(-180deg)}.select_expand_label{position:absolute;top:0;left:0;display:block;width:100%;height:2rem;margin-bottom:0;cursor:pointer}.select_close{display:none}.select_close_label{position:fixed;top:0;left:0;display:none;margin-bottom:0}.select_items{position:absolute;top:0;left:0;width:100%;min-height:2rem;border-color:var(--t42-color-opacity-10);border-style:solid;border-width:1px}.select_items:hover{border-color:var(--primary)}.select_input{display:none}.select_label{display:block;height:0;margin-bottom:0;padding-left:0.875rem;overflow:hidden;line-height:2rem;cursor:pointer;transition:all 200ms cubic-bezier(0.4, 0.25, 0.3, 1)}.select_label-placeholder{position:absolute;top:0;left:0;height:2rem;vertical-align:middle;background-color:transparent}.select_expand:checked+.select_close_label{display:block}.select_expand:checked+.select_close_label::before,.select_expand:checked+.select_close_label::after{display:none}.select_expand:checked+.select_close_label+.select_options .select_label{height:2rem}.select_expand:checked+.select_close_label+.select_options+.select_expand_label{display:none}.select_input:checked+.select_label{height:2rem}.select_option label{color:var(--t42-content-color)}.select_options{max-height:10rem;padding-left:0;overflow:auto;list-style:none}.dark{--t42-json-icons: url("data:image/svg+xml,%3C%3Fxml version=%271.0%27 encoding=%27UTF-8%27 standalone=%27no%27%3F%3E%3Csvg xmlns:dc=%27http://purl.org/dc/elements/1.1/%27 xmlns:cc=%27http://creativecommons.org/ns%23%27 xmlns:rdf=%27http://www.w3.org/1999/02/22-rdf-syntax-ns%23%27 xmlns:svg=%27http://www.w3.org/2000/svg%27 xmlns=%27http://www.w3.org/2000/svg%27 xmlns:sodipodi=%27http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd%27 xmlns:inkscape=%27http://www.inkscape.org/namespaces/inkscape%27 width=%27240%27 height=%27144%27 id=%27svg4136%27 version=%271.1%27 inkscape:version=%270.91 r13725%27 sodipodi:docname=%27jsoneditor-icons.svg%27%3E%3Ctitle id=%27title6512%27%3EJSON Editor Icons%3C/title%3E%3Crect id=%27svg_1-7%27 height=%2716%27 width=%2716%27 y=%273.999995%27 x=%2728.000006%27 style=%27fill:%23ff511f;%27 /%3E%3Crect x=%277%27 y=%2711%27 width=%2710%27 height=%272%27 id=%27svg_1-1%27 style=%27fill:%23ffffff;%27 /%3E%3Crect x=%2711%27 y=%277%27 width=%272%27 height=%2710%27 id=%27svg_1-1-1%27 style=%27fill:%23ffffff;%27 /%3E%3Cg id=%27g4299-3%27 transform=%27matrix%280.70710678,-0.70710678,0.70710678,0.70710678,19.029435,12.000001%29%27 style=%27%27%3E%3Crect x=%277%27 y=%2711%27 width=%2710%27 height=%272%27 id=%27svg_1-1-0%27 style=%27fill:%23ffffff;%27 /%3E%3Crect x=%2711%27 y=%277%27 width=%272%27 height=%2710%27 id=%27svg_1-1-1-9%27 style=%27fill:%23ffffff;%27 /%3E%3C/g%3E%3Crect height=%277%27 width=%277%27 y=%277%27 x=%2755%27 style=%27fill:%23ffffff;stroke-width:1;stroke:%23ffffff%27 /%3E%3Crect id=%27svg_1-7-5-7%27 height=%277%27 width=%277%27 y=%2710%27 x=%2758%27 style=%27fill:%23ffffff;stroke-width:1;stroke:%231d1d1d%27 /%3E%3Cg id=%27g4378%27%3E%3Crect style=%27fill:%23ffffff;%27 x=%27198%27 y=%2711%27 width=%278%27 height=%272%27 id=%27svg_1-7-5-3%27 /%3E%3Crect id=%27rect4374%27 height=%272%27 width=%2712%27 y=%277%27 x=%27198%27 style=%27fill:%23ffffff;%27 /%3E%3Crect id=%27rect4376%27 height=%272%27 width=%274%27 y=%2715%27 x=%27198%27 style=%27fill:%23ffffff;%27 /%3E%3C/g%3E%3Cg transform=%27matrix%281,0,0,-1,-23.999995,23.999995%29%27 id=%27g4383%27%3E%3Crect id=%27rect4385%27 height=%272%27 width=%278%27 y=%2711%27 x=%27198%27 style=%27fill:%23ffffff;%27 /%3E%3Crect style=%27fill:%23ffffff;%27 x=%27198%27 y=%277%27 width=%2712%27 height=%272%27 id=%27rect4387%27 /%3E%3Crect style=%27fill:%23ffffff;%27 x=%27198%27 y=%2715%27 width=%274%27 height=%272%27 id=%27rect4389%27 /%3E%3C/g%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 85.10447,6.0157384 -0.0156,1.4063 c 3.02669,-0.2402 0.33008,3.6507996 2.48438,4.5780996 -2.18694,1.0938 0.49191,4.9069 -2.45313,4.5781 l -0.0156,1.4219 c 5.70828,0.559 1.03264,-5.1005 4.70313,-5.2656 l 0,-1.4063 c -3.61303,-0.027 1.11893,-5.7069996 -4.70313,-5.3124996 z%27 id=%27path4351%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 82.78125,5.9984384 0.0156,1.4063 c -3.02668,-0.2402 -0.33007,3.6506996 -2.48437,4.5780996 2.18694,1.0938 -0.49192,4.9069 2.45312,4.5781 l 0.0156,1.4219 c -5.70827,0.559 -1.03263,-5.1004 -4.70312,-5.2656 l 0,-1.4063 c 3.61303,-0.027 -1.11894,-5.7070996 4.70312,-5.3124996 z%27 id=%27path4351-9%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 103.719,5.6719384 0,12.7187996 3.03125,0 0,-1.5313 -1.34375,0 0,-9.6249996 1.375,0 0,-1.5625 z%27 id=%27path2987%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 112.2185,5.6721984 0,12.7187996 -3.03125,0 0,-1.5313 1.34375,0 0,-9.6249996 -1.375,0 0,-1.5625 z%27 id=%27path2987-1%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27M133,6.4h-1.9l-4.8,11.2h1.8l1.1-2.9h5.7l1.1,2.9h1.8L133,6.4z M129.7,13.5l2.3-5.5l2.3,5.5L129.7,13.5z%27 id=%27path3780%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 156.47655,5.8917384 0,2.1797 0.46093,2.3983996 1.82813,0 0.39844,-2.3983996 0,-2.1797 z%27 id=%27path5008-2%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 152.51561,5.8906384 0,2.1797 0.46094,2.3983996 1.82812,0 0.39844,-2.3983996 0,-2.1797 z%27 id=%27path5008-2-8%27 /%3E%3Crect id=%27svg_1-7-2%27 height=%272%27 width=%2712%27 y=%2764%27 x=%2754%27 style=%27fill:%236e6e6e;%27 /%3E%3Crect id=%27svg_1-7-2-2%27 height=%273%27 width=%273%27 y=%2752%27 x=%2780%27 style=%27fill:%236e6e6e;%27 /%3E%3Crect style=%27fill:%236e6e6e;%27 x=%2785%27 y=%2752%27 width=%273%27 height=%273%27 id=%27rect4561%27 /%3E%3Crect style=%27fill:%236e6e6e;%27 x=%2780%27 y=%2758%27 width=%273%27 height=%273%27 id=%27rect4563%27 /%3E%3Crect id=%27rect4565%27 height=%273%27 width=%273%27 y=%2758%27 x=%2785%27 style=%27fill:%236e6e6e;%27 /%3E%3Crect id=%27rect4567%27 height=%273%27 width=%273%27 y=%2764%27 x=%2780%27 style=%27fill:%236e6e6e;%27 /%3E%3Crect style=%27fill:%236e6e6e;%27 x=%2785%27 y=%2764%27 width=%273%27 height=%273%27 id=%27rect4569%27 /%3E%3Ccircle style=%27opacity:1;fill:none;stroke:%236e6e6e;stroke-width:2;%27 id=%27path4571%27 cx=%27110.06081%27 cy=%2757.939209%27 r=%274.7438836%27 /%3E%3Crect style=%27fill:%236e6e6e;%27 x=%27116.64566%27 y=%27-31.79752%27 width=%274.229713%27 height=%276.4053884%27 id=%27rect4563-2%27 transform=%27matrix%280.70710678,0.70710678,-0.70710678,0.70710678,0,0%29%27 /%3E%3Cpath style=%27fill:%236e6e6e;fill-rule:evenodd;%27 d=%27M 125,56 138.77027,56.095 132,64 Z%27 id=%27path4613%27 /%3E%3Cpath id=%27path4615%27 d=%27M 149,64 162.77027,63.905 156,56 Z%27 style=%27fill:%236e6e6e;fill-rule:evenodd;%27 /%3E%3Crect style=%27fill:%236e6e6e;%27 x=%2754%27 y=%2753%27 width=%2712%27 height=%272%27 id=%27rect4638%27 /%3E%3Crect id=%27svg_1-7-2-24%27 height=%272%27 width=%2713%27 y=%27-56%27 x=%2753%27 style=%27fill:%236e6e6e;%27 transform=%27matrix%280,1,-1,0,0,0%29%27 /%3E%3Crect transform=%27matrix%280,1,-1,0,0,0%29%27 style=%27fill:%236e6e6e;%27 x=%2753%27 y=%27-66%27 width=%2713%27 height=%272%27 id=%27rect4657%27 /%3E%3Crect id=%27rect4659%27 height=%271%27 width=%2712%27 y=%2757%27 x=%2754%27 style=%27fill:%236e6e6e;%27 /%3E%3Crect style=%27fill:%23ffffff;%27 x=%2754%27 y=%2788%27 width=%2712%27 height=%272%27 id=%27rect4661%27 /%3E%3Crect style=%27fill:%23ffffff;%27 x=%2780%27 y=%2776%27 width=%273%27 height=%273%27 id=%27rect4663%27 /%3E%3Crect id=%27rect4665%27 height=%273%27 width=%273%27 y=%2776%27 x=%2785%27 style=%27fill:%23ffffff;%27 /%3E%3Crect id=%27rect4667%27 height=%273%27 width=%273%27 y=%2782%27 x=%2780%27 style=%27fill:%23ffffff;%27 /%3E%3Crect style=%27fill:%23ffffff;%27 x=%2785%27 y=%2782%27 width=%273%27 height=%273%27 id=%27rect4669%27 /%3E%3Crect style=%27fill:%23ffffff;%27 x=%2780%27 y=%2788%27 width=%273%27 height=%273%27 id=%27rect4671%27 /%3E%3Crect id=%27rect4673%27 height=%273%27 width=%273%27 y=%2788%27 x=%2785%27 style=%27fill:%23ffffff;%27 /%3E%3Ccircle r=%274.7438836%27 cy=%2781.939331%27 cx=%27110.06081%27 id=%27circle4675%27 style=%27opacity:1;fill:none;stroke:%23ffffff;stroke-width:2;%27 /%3E%3Crect transform=%27matrix%280.70710678,0.70710678,-0.70710678,0.70710678,0,0%29%27 id=%27rect4677%27 height=%276.4053884%27 width=%274.229713%27 y=%27-14.826816%27 x=%27133.6163%27 style=%27fill:%23ffffff;%27 /%3E%3Cpath id=%27path4679%27 d=%27m 125,80.000005 13.77027,0.09499 L 132,87.999992 Z%27 style=%27fill:%23ffffff;%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27M 149,88.0002 162.77027,87.9052 156,80.0002 Z%27 id=%27path4681%27 /%3E%3Crect id=%27rect4683%27 height=%272%27 width=%2712%27 y=%2777%27 x=%2754%27 style=%27fill:%23ffffff;%27 /%3E%3Crect transform=%27matrix%280,1,-1,0,0,0%29%27 style=%27fill:%23ffffff;%27 x=%2777%27 y=%27-56%27 width=%2713%27 height=%272%27 id=%27rect4685%27 /%3E%3Crect id=%27rect4687%27 height=%272%27 width=%2713%27 y=%27-66%27 x=%2777%27 style=%27fill:%23ffffff;%27 transform=%27matrix%280,1,-1,0,0,0%29%27 /%3E%3Crect style=%27fill:%23ffffff;%27 x=%2754%27 y=%2781%27 width=%2712%27 height=%271%27 id=%27rect4689%27 /%3E%3Crect id=%27rect4761-1%27 height=%272%27 width=%2716%27 y=%27101%27 x=%2776%27 style=%27fill:%23ffffff;%27 /%3E%3Crect id=%27rect4761-0%27 height=%272%27 width=%2716%27 y=%27105%27 x=%2776%27 style=%27fill:%23ffffff;%27 /%3E%3Crect id=%27rect4761-7%27 height=%272%27 width=%279%27 y=%27109%27 x=%2776%27 style=%27fill:%23ffffff;%27 /%3E%3Crect id=%27rect4761-1-1%27 height=%272%27 width=%2712%27 y=%27125%27 x=%2776%27 style=%27fill:%23ffffff;%27 /%3E%3Crect id=%27rect4761-1-1-4%27 height=%272%27 width=%2710%27 y=%27137%27 x=%2776%27 style=%27fill:%23ffffff;%27 /%3E%3Crect id=%27rect4761-1-1-4-4%27 height=%272%27 width=%2710%27 y=%27129%27 x=%2782%27 style=%27fill:%23ffffff;%27 /%3E%3Crect id=%27rect4761-1-1-4-4-3%27 height=%272%27 width=%279%27 y=%27133%27 x=%2782%27 style=%27fill:%23ffffff;%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 36.398438,100.0254 c -0.423362,-0.013 -0.846847,0.01 -1.265626,0.062 -1.656562,0.2196 -3.244567,0.9739 -4.507812,2.2266 L 29,100.5991 l -2.324219,7.7129 7.826172,-1.9062 -1.804687,-1.9063 c 1.597702,-1.5308 4.048706,-1.8453 5.984375,-0.7207 1.971162,1.1452 2.881954,3.3975 2.308593,5.5508 -0.573361,2.1533 -2.533865,3.6953 -4.830078,3.6953 l 0,3.0742 c 3.550756,0 6.710442,-2.4113 7.650391,-5.9414 0.939949,-3.5301 -0.618463,-7.2736 -3.710938,-9.0703 -1.159678,-0.6738 -2.431087,-1.0231 -3.701171,-1.0625 z%27 id=%27path4138%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 59.722656,99.9629 c -1.270084,0.039 -2.541493,0.3887 -3.701172,1.0625 -3.092475,1.7967 -4.650886,5.5402 -3.710937,9.0703 0.939949,3.5301 4.09768,5.9414 7.648437,5.9414 l 0,-3.0742 c -2.296214,0 -4.256717,-1.542 -4.830078,-3.6953 -0.573361,-2.1533 0.337432,-4.4056 2.308594,-5.5508 1.935731,-1.1246 4.38863,-0.8102 5.986326,0.7207 l -1.806638,1.9063 7.828128,1.9062 -2.32422,-7.7129 -1.62696,1.7168 c -1.26338,-1.2531 -2.848917,-2.0088 -4.505855,-2.2285 -0.418778,-0.055 -0.842263,-0.076 -1.265625,-0.062 z%27 id=%27path4138-1%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 10.5,100 0,2 -2.4999996,0 L 12,107 l 4,-5 -2.5,0 0,-2 -3,0 z%27 id=%27path3055-0-77%27 /%3E%3Cpath style=%27fill:none;stroke:%23ffffff;%27 d=%27m 4.9850574,108.015 14.0298856,-0.03%27 id=%27path5244-5-0-5%27 /%3E%3Cpath style=%27fill:none;stroke:%23ffffff;%27 d=%27m 4.9849874,132.015 14.0298866,-0.03%27 id=%27path5244-5-0-5-8%27 /%3E%3Cpath style=%27color:%23000000;fill:%236e6e6e;%27 d=%27m 36.398438,123.9629 c -0.423362,-0.013 -0.846847,0.01 -1.265626,0.062 -1.656562,0.2196 -3.244567,0.9739 -4.507812,2.2266 L 29,124.5366 l -2.324219,7.7129 7.826172,-1.9062 -1.804687,-1.9063 c 1.597702,-1.5308 4.048706,-1.8453 5.984375,-0.7207 1.971162,1.1453 2.881954,3.3975 2.308593,5.5508 -0.573361,2.1533 -2.533864,3.6953 -4.830078,3.6953 l 0,3.0742 c 3.550757,0 6.710442,-2.4093 7.650391,-5.9394 0.939949,-3.5301 -0.618463,-7.2756 -3.710938,-9.0723 -1.159678,-0.6737 -2.431087,-1.0231 -3.701171,-1.0625 z%27 id=%27path4138-12%27 /%3E%3Cpath style=%27color:%23000000;fill:%236e6e6e;%27 d=%27m 59.722656,123.9629 c -1.270084,0.039 -2.541493,0.3888 -3.701172,1.0625 -3.092475,1.7967 -4.650886,5.5422 -3.710937,9.0723 0.939949,3.5301 4.09768,5.9394 7.648437,5.9394 l 0,-3.0742 c -2.296214,0 -4.256717,-1.542 -4.830078,-3.6953 -0.573361,-2.1533 0.337432,-4.4055 2.308594,-5.5508 1.935731,-1.1246 4.38863,-0.8102 5.986326,0.7207 l -1.806638,1.9063 7.828128,1.9062 -2.32422,-7.7129 -1.62696,1.7168 c -1.26338,-1.2531 -2.848917,-2.0088 -4.505855,-2.2285 -0.418778,-0.055 -0.842263,-0.076 -1.265625,-0.062 z%27 id=%27path4138-1-3%27 /%3E%3Cpath id=%27path6191%27 d=%27m 10.5,116 0,-2 -2.4999996,0 L 12,109 l 4,5 -2.5,0 0,2 -3,0 z%27 style=%27fill:%23ffffff;stroke-width:1.96599996;%27 /%3E%3Cpath style=%27fill:%23ffffff;stroke-width:1.96599996;%27 d=%27m 10.5,129 0,-2 -2.4999996,0 L 12,122 l 4,5 -2.5,0 0,2 -3,0 z%27 id=%27path6193%27 /%3E%3Cpath id=%27path6195%27 d=%27m 10.5,135 0,2 -2.4999996,0 L 12,142 l 4,-5 -2.5,0 0,-2 -3,0 z%27 style=%27fill:%23ffffff;stroke-width:1.96599996;%27 /%3E%3Cpath sodipodi:type=%27star%27 style=%27fill:%236e6e6e;%27 id=%27path4500%27 sodipodi:sides=%273%27 sodipodi:cx=%2711.55581%27 sodipodi:cy=%2760.073242%27 sodipodi:r1=%275.1116104%27 sodipodi:r2=%272.5558052%27 sodipodi:arg1=%270%27 sodipodi:arg2=%271.0471976%27 inkscape:flatsided=%27false%27 inkscape:rounded=%270%27 inkscape:randomized=%270%27 d=%27m 16.66742,60.073242 -3.833708,2.213392 -3.8337072,2.213393 0,-4.426785 0,-4.426784 3.8337082,2.213392 z%27 inkscape:transform-center-x=%27-1.2779026%27 /%3E%3Cpath inkscape:transform-center-x=%271.277902%27 d=%27m -31.500004,60.073242 -3.833708,2.213392 -3.833707,2.213393 0,-4.426785 0,-4.426784 3.833707,2.213392 z%27 inkscape:randomized=%270%27 inkscape:rounded=%270%27 inkscape:flatsided=%27false%27 sodipodi:arg2=%271.0471976%27 sodipodi:arg1=%270%27 sodipodi:r2=%272.5558052%27 sodipodi:r1=%275.1116104%27 sodipodi:cy=%2760.073242%27 sodipodi:cx=%27-36.611614%27 sodipodi:sides=%273%27 id=%27path4502%27 style=%27fill:%236e6e6e;%27 sodipodi:type=%27star%27 transform=%27scale%28-1,1%29%27 /%3E%3Cpath d=%27m 16.66742,60.073212 -3.833708,2.213392 -3.8337072,2.213392 0,-4.426784 0,-4.426785 3.8337082,2.213392 z%27 inkscape:randomized=%270%27 inkscape:rounded=%270%27 inkscape:flatsided=%27false%27 sodipodi:arg2=%271.0471976%27 sodipodi:arg1=%270%27 sodipodi:r2=%272.5558052%27 sodipodi:r1=%275.1116104%27 sodipodi:cy=%2760.073212%27 sodipodi:cx=%2711.55581%27 sodipodi:sides=%273%27 id=%27path4504%27 style=%27fill:%236e6e6e;%27 sodipodi:type=%27star%27 transform=%27matrix%280,1,-1,0,72.0074,71.7877%29%27 inkscape:transform-center-y=%271.2779029%27 /%3E%3Cpath inkscape:transform-center-y=%27-1.2779026%27 transform=%27matrix%280,-1,-1,0,96,96%29%27 sodipodi:type=%27star%27 style=%27fill:%236e6e6e;%27 id=%27path4506%27 sodipodi:sides=%273%27 sodipodi:cx=%2711.55581%27 sodipodi:cy=%2760.073212%27 sodipodi:r1=%275.1116104%27 sodipodi:r2=%272.5558052%27 sodipodi:arg1=%270%27 sodipodi:arg2=%271.0471976%27 inkscape:flatsided=%27false%27 inkscape:rounded=%270%27 inkscape:randomized=%270%27 d=%27m 16.66742,60.073212 -3.833708,2.213392 -3.8337072,2.213392 0,-4.426784 0,-4.426785 3.8337082,2.213392 z%27 /%3E%3Cpath id=%27path4615-5%27 d=%27m 171.82574,65.174193 16.34854,0 -8.17427,-13.348454 z%27 style=%27fill:%23f9a825;fill-rule:evenodd;stroke:%23f9a825;stroke-width:2;%27 /%3E%3Cpath style=%27opacity:1;fill:%23ffffff;%27 d=%27m 179,55 0,6 2,0 0,-6%27 id=%27path4300%27 /%3E%3Cpath style=%27opacity:1;fill:%23ffffff;%27 d=%27m 179,62 0,2 2,0 0,-2%27 id=%27path4300-6%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27M 99.994369,113.0221 102,114.98353 l 7,-6.9558 3,0.97227 2,-1 1,-2 0,-3 -3,3 -3,-3 3,-3 -3,0 -2,1 -1,2 0.99437,3.0221 z%27 id=%27path4268%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 234,6 0,2 -5,5 0,5 -2,0 0,-5 -5,-5 0,-2%27 id=%27path3546%27 /%3E%3Cg transform=%27matrix%281.3333328,0,0,-1.5999992,-139.9999,127.19999%29%27 id=%27g4383-6%27%3E%3Crect id=%27rect4385-2%27 height=%271%27 width=%276%27 y=%2712.625005%27 x=%27198%27 style=%27fill:%23ffffff;stroke:%23000000;stroke-width:0%27 /%3E%3Crect style=%27fill:%23ffffff;stroke:%23000000;stroke-width:0%27 x=%27198%27 y=%2715.125007%27 width=%278%27 height=%271%27 id=%27rect4387-9%27 /%3E%3Crect style=%27fill:%23ffffff;stroke:%23000000;stroke-width:0%27 x=%27198%27 y=%277.6250024%27 width=%273%27 height=%271%27 id=%27rect4389-1-0%27 /%3E%3Crect style=%27fill:%23ffffff;stroke:%23000000;stroke-width:0%27 x=%27198%27 y=%2710.125004%27 width=%274%27 height=%271%27 id=%27rect4389-1-9%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 207.00001,16.375004 0,-5.625005 -2.25,0 3,-3.1250014 3,3.1250014 -2.25,0 0,5.625005 -1.5,0%27 id=%27path4402%27 /%3E%3C/g%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 164,100 0,3 -6,6 0,7 -4,0 0,-7 -6,-6 0,-3%27 id=%27path3546-2-2%27 /%3E%3Cpath id=%27path4402-5-7%27 d=%27m 15,41 0,-7 -4,0 0,3 -5,-4 5,-4 0,3 6,0 0,9%27 style=%27fill:%23ffffff;%27 /%3E%3C/svg%3E%0A")}.light{--t42-json-icons: url("data:image/svg+xml,%3C%3Fxml version=%271.0%27 encoding=%27UTF-8%27 standalone=%27no%27%3F%3E%3Csvg xmlns:dc=%27http://purl.org/dc/elements/1.1/%27 xmlns:cc=%27http://creativecommons.org/ns%23%27 xmlns:rdf=%27http://www.w3.org/1999/02/22-rdf-syntax-ns%23%27 xmlns:svg=%27http://www.w3.org/2000/svg%27 xmlns=%27http://www.w3.org/2000/svg%27 xmlns:sodipodi=%27http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd%27 xmlns:inkscape=%27http://www.inkscape.org/namespaces/inkscape%27 width=%27240%27 height=%27144%27 id=%27svg4136%27 version=%271.1%27 inkscape:version=%270.91 r13725%27 sodipodi:docname=%27jsoneditor-icons.svg%27%3E%3Ctitle id=%27title6512%27%3EJSON Editor Icons%3C/title%3E%3Crect id=%27svg_1-7%27 height=%2716%27 width=%2716%27 y=%273.999995%27 x=%2728.000006%27 style=%27fill:%23ff511f;%27 /%3E%3Crect x=%277%27 y=%2711%27 width=%2710%27 height=%272%27 id=%27svg_1-1%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect x=%2711%27 y=%277%27 width=%272%27 height=%2710%27 id=%27svg_1-1-1%27 style=%27fill:%230d0d0d;%27 /%3E%3Cg id=%27g4299-3%27 transform=%27matrix%280.70710678,-0.70710678,0.70710678,0.70710678,19.029435,12.000001%29%27 style=%27%27%3E%3Crect x=%277%27 y=%2711%27 width=%2710%27 height=%272%27 id=%27svg_1-1-0%27 style=%27fill:%23ffffff;%27 /%3E%3Crect x=%2711%27 y=%277%27 width=%272%27 height=%2710%27 id=%27svg_1-1-1-9%27 style=%27fill:%23ffffff;%27 /%3E%3C/g%3E%3Crect height=%277%27 width=%277%27 y=%277%27 x=%2755%27 style=%27fill:%230d0d0d;stroke-width:1;stroke:%230d0d0d%27 /%3E%3Crect id=%27svg_1-7-5-7%27 height=%277%27 width=%277%27 y=%2710%27 x=%2758%27 style=%27fill:%230d0d0d;stroke-width:1;stroke:%23ffffff%27 /%3E%3Cg id=%27g4378%27%3E%3Crect style=%27fill:%230d0d0d;%27 x=%27198%27 y=%2711%27 width=%278%27 height=%272%27 id=%27svg_1-7-5-3%27 /%3E%3Crect id=%27rect4374%27 height=%272%27 width=%2712%27 y=%277%27 x=%27198%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect id=%27rect4376%27 height=%272%27 width=%274%27 y=%2715%27 x=%27198%27 style=%27fill:%230d0d0d;%27 /%3E%3C/g%3E%3Cg transform=%27matrix%281,0,0,-1,-23.999995,23.999995%29%27 id=%27g4383%27%3E%3Crect id=%27rect4385%27 height=%272%27 width=%278%27 y=%2711%27 x=%27198%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect style=%27fill:%230d0d0d;%27 x=%27198%27 y=%277%27 width=%2712%27 height=%272%27 id=%27rect4387%27 /%3E%3Crect style=%27fill:%230d0d0d;%27 x=%27198%27 y=%2715%27 width=%274%27 height=%272%27 id=%27rect4389%27 /%3E%3C/g%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 85.10447,6.0157384 -0.0156,1.4063 c 3.02669,-0.2402 0.33008,3.6507996 2.48438,4.5780996 -2.18694,1.0938 0.49191,4.9069 -2.45313,4.5781 l -0.0156,1.4219 c 5.70828,0.559 1.03264,-5.1005 4.70313,-5.2656 l 0,-1.4063 c -3.61303,-0.027 1.11893,-5.7069996 -4.70313,-5.3124996 z%27 id=%27path4351%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 82.78125,5.9984384 0.0156,1.4063 c -3.02668,-0.2402 -0.33007,3.6506996 -2.48437,4.5780996 2.18694,1.0938 -0.49192,4.9069 2.45312,4.5781 l 0.0156,1.4219 c -5.70827,0.559 -1.03263,-5.1004 -4.70312,-5.2656 l 0,-1.4063 c 3.61303,-0.027 -1.11894,-5.7070996 4.70312,-5.3124996 z%27 id=%27path4351-9%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 103.719,5.6719384 0,12.7187996 3.03125,0 0,-1.5313 -1.34375,0 0,-9.6249996 1.375,0 0,-1.5625 z%27 id=%27path2987%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 112.2185,5.6721984 0,12.7187996 -3.03125,0 0,-1.5313 1.34375,0 0,-9.6249996 -1.375,0 0,-1.5625 z%27 id=%27path2987-1%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27M133,6.4h-1.9l-4.8,11.2h1.8l1.1-2.9h5.7l1.1,2.9h1.8L133,6.4z M129.7,13.5l2.3-5.5l2.3,5.5L129.7,13.5z%27 id=%27path3780%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 156.47655,5.8917384 0,2.1797 0.46093,2.3983996 1.82813,0 0.39844,-2.3983996 0,-2.1797 z%27 id=%27path5008-2%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 152.51561,5.8906384 0,2.1797 0.46094,2.3983996 1.82812,0 0.39844,-2.3983996 0,-2.1797 z%27 id=%27path5008-2-8%27 /%3E%3Crect id=%27svg_1-7-2%27 height=%272%27 width=%2712%27 y=%2764%27 x=%2754%27 style=%27fill:%236e6e6e;%27 /%3E%3Crect id=%27svg_1-7-2-2%27 height=%273%27 width=%273%27 y=%2752%27 x=%2780%27 style=%27fill:%236e6e6e;%27 /%3E%3Crect style=%27fill:%236e6e6e;%27 x=%2785%27 y=%2752%27 width=%273%27 height=%273%27 id=%27rect4561%27 /%3E%3Crect style=%27fill:%236e6e6e;%27 x=%2780%27 y=%2758%27 width=%273%27 height=%273%27 id=%27rect4563%27 /%3E%3Crect id=%27rect4565%27 height=%273%27 width=%273%27 y=%2758%27 x=%2785%27 style=%27fill:%236e6e6e;%27 /%3E%3Crect id=%27rect4567%27 height=%273%27 width=%273%27 y=%2764%27 x=%2780%27 style=%27fill:%236e6e6e;%27 /%3E%3Crect style=%27fill:%236e6e6e;%27 x=%2785%27 y=%2764%27 width=%273%27 height=%273%27 id=%27rect4569%27 /%3E%3Ccircle style=%27opacity:1;fill:none;stroke:%236e6e6e;stroke-width:2;%27 id=%27path4571%27 cx=%27110.06081%27 cy=%2757.939209%27 r=%274.7438836%27 /%3E%3Crect style=%27fill:%236e6e6e;%27 x=%27116.64566%27 y=%27-31.79752%27 width=%274.229713%27 height=%276.4053884%27 id=%27rect4563-2%27 transform=%27matrix%280.70710678,0.70710678,-0.70710678,0.70710678,0,0%29%27 /%3E%3Cpath style=%27fill:%236e6e6e;fill-rule:evenodd;%27 d=%27M 125,56 138.77027,56.095 132,64 Z%27 id=%27path4613%27 /%3E%3Cpath id=%27path4615%27 d=%27M 149,64 162.77027,63.905 156,56 Z%27 style=%27fill:%236e6e6e;fill-rule:evenodd;%27 /%3E%3Crect style=%27fill:%236e6e6e;%27 x=%2754%27 y=%2753%27 width=%2712%27 height=%272%27 id=%27rect4638%27 /%3E%3Crect id=%27svg_1-7-2-24%27 height=%272%27 width=%2713%27 y=%27-56%27 x=%2753%27 style=%27fill:%236e6e6e;%27 transform=%27matrix%280,1,-1,0,0,0%29%27 /%3E%3Crect transform=%27matrix%280,1,-1,0,0,0%29%27 style=%27fill:%236e6e6e;%27 x=%2753%27 y=%27-66%27 width=%2713%27 height=%272%27 id=%27rect4657%27 /%3E%3Crect id=%27rect4659%27 height=%271%27 width=%2712%27 y=%2757%27 x=%2754%27 style=%27fill:%236e6e6e;%27 /%3E%3Crect style=%27fill:%230d0d0d;%27 x=%2754%27 y=%2788%27 width=%2712%27 height=%272%27 id=%27rect4661%27 /%3E%3Crect style=%27fill:%230d0d0d;%27 x=%2780%27 y=%2776%27 width=%273%27 height=%273%27 id=%27rect4663%27 /%3E%3Crect id=%27rect4665%27 height=%273%27 width=%273%27 y=%2776%27 x=%2785%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect id=%27rect4667%27 height=%273%27 width=%273%27 y=%2782%27 x=%2780%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect style=%27fill:%230d0d0d;%27 x=%2785%27 y=%2782%27 width=%273%27 height=%273%27 id=%27rect4669%27 /%3E%3Crect style=%27fill:%230d0d0d;%27 x=%2780%27 y=%2788%27 width=%273%27 height=%273%27 id=%27rect4671%27 /%3E%3Crect id=%27rect4673%27 height=%273%27 width=%273%27 y=%2788%27 x=%2785%27 style=%27fill:%230d0d0d;%27 /%3E%3Ccircle r=%274.7438836%27 cy=%2781.939331%27 cx=%27110.06081%27 id=%27circle4675%27 style=%27opacity:1;fill:none;stroke:%230d0d0d;stroke-width:2;%27 /%3E%3Crect transform=%27matrix%280.70710678,0.70710678,-0.70710678,0.70710678,0,0%29%27 id=%27rect4677%27 height=%276.4053884%27 width=%274.229713%27 y=%27-14.826816%27 x=%27133.6163%27 style=%27fill:%230d0d0d;%27 /%3E%3Cpath id=%27path4679%27 d=%27m 125,80.000005 13.77027,0.09499 L 132,87.999992 Z%27 style=%27fill:%230d0d0d;%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27M 149,88.0002 162.77027,87.9052 156,80.0002 Z%27 id=%27path4681%27 /%3E%3Crect id=%27rect4683%27 height=%272%27 width=%2712%27 y=%2777%27 x=%2754%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect transform=%27matrix%280,1,-1,0,0,0%29%27 style=%27fill:%230d0d0d;%27 x=%2777%27 y=%27-56%27 width=%2713%27 height=%272%27 id=%27rect4685%27 /%3E%3Crect id=%27rect4687%27 height=%272%27 width=%2713%27 y=%27-66%27 x=%2777%27 style=%27fill:%230d0d0d;%27 transform=%27matrix%280,1,-1,0,0,0%29%27 /%3E%3Crect style=%27fill:%230d0d0d;%27 x=%2754%27 y=%2781%27 width=%2712%27 height=%271%27 id=%27rect4689%27 /%3E%3Crect id=%27rect4761-1%27 height=%272%27 width=%2716%27 y=%27101%27 x=%2776%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect id=%27rect4761-0%27 height=%272%27 width=%2716%27 y=%27105%27 x=%2776%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect id=%27rect4761-7%27 height=%272%27 width=%279%27 y=%27109%27 x=%2776%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect id=%27rect4761-1-1%27 height=%272%27 width=%2712%27 y=%27125%27 x=%2776%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect id=%27rect4761-1-1-4%27 height=%272%27 width=%2710%27 y=%27137%27 x=%2776%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect id=%27rect4761-1-1-4-4%27 height=%272%27 width=%2710%27 y=%27129%27 x=%2782%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect id=%27rect4761-1-1-4-4-3%27 height=%272%27 width=%279%27 y=%27133%27 x=%2782%27 style=%27fill:%230d0d0d;%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 36.398438,100.0254 c -0.423362,-0.013 -0.846847,0.01 -1.265626,0.062 -1.656562,0.2196 -3.244567,0.9739 -4.507812,2.2266 L 29,100.5991 l -2.324219,7.7129 7.826172,-1.9062 -1.804687,-1.9063 c 1.597702,-1.5308 4.048706,-1.8453 5.984375,-0.7207 1.971162,1.1452 2.881954,3.3975 2.308593,5.5508 -0.573361,2.1533 -2.533865,3.6953 -4.830078,3.6953 l 0,3.0742 c 3.550756,0 6.710442,-2.4113 7.650391,-5.9414 0.939949,-3.5301 -0.618463,-7.2736 -3.710938,-9.0703 -1.159678,-0.6738 -2.431087,-1.0231 -3.701171,-1.0625 z%27 id=%27path4138%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 59.722656,99.9629 c -1.270084,0.039 -2.541493,0.3887 -3.701172,1.0625 -3.092475,1.7967 -4.650886,5.5402 -3.710937,9.0703 0.939949,3.5301 4.09768,5.9414 7.648437,5.9414 l 0,-3.0742 c -2.296214,0 -4.256717,-1.542 -4.830078,-3.6953 -0.573361,-2.1533 0.337432,-4.4056 2.308594,-5.5508 1.935731,-1.1246 4.38863,-0.8102 5.986326,0.7207 l -1.806638,1.9063 7.828128,1.9062 -2.32422,-7.7129 -1.62696,1.7168 c -1.26338,-1.2531 -2.848917,-2.0088 -4.505855,-2.2285 -0.418778,-0.055 -0.842263,-0.076 -1.265625,-0.062 z%27 id=%27path4138-1%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 10.5,100 0,2 -2.4999996,0 L 12,107 l 4,-5 -2.5,0 0,-2 -3,0 z%27 id=%27path3055-0-77%27 /%3E%3Cpath style=%27fill:none;stroke:%230d0d0d;%27 d=%27m 4.9850574,108.015 14.0298856,-0.03%27 id=%27path5244-5-0-5%27 /%3E%3Cpath style=%27fill:none;stroke:%230d0d0d;%27 d=%27m 4.9849874,132.015 14.0298866,-0.03%27 id=%27path5244-5-0-5-8%27 /%3E%3Cpath style=%27color:%23000000;fill:%236e6e6e;%27 d=%27m 36.398438,123.9629 c -0.423362,-0.013 -0.846847,0.01 -1.265626,0.062 -1.656562,0.2196 -3.244567,0.9739 -4.507812,2.2266 L 29,124.5366 l -2.324219,7.7129 7.826172,-1.9062 -1.804687,-1.9063 c 1.597702,-1.5308 4.048706,-1.8453 5.984375,-0.7207 1.971162,1.1453 2.881954,3.3975 2.308593,5.5508 -0.573361,2.1533 -2.533864,3.6953 -4.830078,3.6953 l 0,3.0742 c 3.550757,0 6.710442,-2.4093 7.650391,-5.9394 0.939949,-3.5301 -0.618463,-7.2756 -3.710938,-9.0723 -1.159678,-0.6737 -2.431087,-1.0231 -3.701171,-1.0625 z%27 id=%27path4138-12%27 /%3E%3Cpath style=%27color:%23000000;fill:%236e6e6e;%27 d=%27m 59.722656,123.9629 c -1.270084,0.039 -2.541493,0.3888 -3.701172,1.0625 -3.092475,1.7967 -4.650886,5.5422 -3.710937,9.0723 0.939949,3.5301 4.09768,5.9394 7.648437,5.9394 l 0,-3.0742 c -2.296214,0 -4.256717,-1.542 -4.830078,-3.6953 -0.573361,-2.1533 0.337432,-4.4055 2.308594,-5.5508 1.935731,-1.1246 4.38863,-0.8102 5.986326,0.7207 l -1.806638,1.9063 7.828128,1.9062 -2.32422,-7.7129 -1.62696,1.7168 c -1.26338,-1.2531 -2.848917,-2.0088 -4.505855,-2.2285 -0.418778,-0.055 -0.842263,-0.076 -1.265625,-0.062 z%27 id=%27path4138-1-3%27 /%3E%3Cpath id=%27path6191%27 d=%27m 10.5,116 0,-2 -2.4999996,0 L 12,109 l 4,5 -2.5,0 0,2 -3,0 z%27 style=%27fill:%230d0d0d;stroke-width:2;%27 /%3E%3Cpath style=%27fill:%230d0d0d;stroke-width:2;%27 d=%27m 10.5,129 0,-2 -2.4999996,0 L 12,122 l 4,5 -2.5,0 0,2 -3,0 z%27 id=%27path6193%27 /%3E%3Cpath id=%27path6195%27 d=%27m 10.5,135 0,2 -2.4999996,0 L 12,142 l 4,-5 -2.5,0 0,-2 -3,0 z%27 style=%27fill:%230d0d0d;stroke-width:2;%27 /%3E%3Cpath sodipodi:type=%27star%27 style=%27fill:%236e6e6e;%27 id=%27path4500%27 sodipodi:sides=%273%27 sodipodi:cx=%2711.55581%27 sodipodi:cy=%2760.073242%27 sodipodi:r1=%275.1116104%27 sodipodi:r2=%272.5558052%27 sodipodi:arg1=%270%27 sodipodi:arg2=%271.0471976%27 inkscape:flatsided=%27false%27 inkscape:rounded=%270%27 inkscape:randomized=%270%27 d=%27m 16.66742,60.073242 -3.833708,2.213392 -3.8337072,2.213393 0,-4.426785 0,-4.426784 3.8337082,2.213392 z%27 inkscape:transform-center-x=%27-1.2779026%27 /%3E%3Cpath inkscape:transform-center-x=%271.277902%27 d=%27m -31.500004,60.073242 -3.833708,2.213392 -3.833707,2.213393 0,-4.426785 0,-4.426784 3.833707,2.213392 z%27 inkscape:randomized=%270%27 inkscape:rounded=%270%27 inkscape:flatsided=%27false%27 sodipodi:arg2=%271.0471976%27 sodipodi:arg1=%270%27 sodipodi:r2=%272.5558052%27 sodipodi:r1=%275.1116104%27 sodipodi:cy=%2760.073242%27 sodipodi:cx=%27-36.611614%27 sodipodi:sides=%273%27 id=%27path4502%27 style=%27fill:%236e6e6e;%27 sodipodi:type=%27star%27 transform=%27scale%28-1,1%29%27 /%3E%3Cpath d=%27m 16.66742,60.073212 -3.833708,2.213392 -3.8337072,2.213392 0,-4.426784 0,-4.426785 3.8337082,2.213392 z%27 inkscape:randomized=%270%27 inkscape:rounded=%270%27 inkscape:flatsided=%27false%27 sodipodi:arg2=%271.0471976%27 sodipodi:arg1=%270%27 sodipodi:r2=%272.5558052%27 sodipodi:r1=%275.1116104%27 sodipodi:cy=%2760.073212%27 sodipodi:cx=%2711.55581%27 sodipodi:sides=%273%27 id=%27path4504%27 style=%27fill:%236e6e6e;%27 sodipodi:type=%27star%27 transform=%27matrix%280,1,-1,0,72.0074,71.7877%29%27 inkscape:transform-center-y=%271.2779029%27 /%3E%3Cpath inkscape:transform-center-y=%27-1.2779026%27 transform=%27matrix%280,-1,-1,0,96,96%29%27 sodipodi:type=%27star%27 style=%27fill:%236e6e6e;%27 id=%27path4506%27 sodipodi:sides=%273%27 sodipodi:cx=%2711.55581%27 sodipodi:cy=%2760.073212%27 sodipodi:r1=%275.1116104%27 sodipodi:r2=%272.5558052%27 sodipodi:arg1=%270%27 sodipodi:arg2=%271.0471976%27 inkscape:flatsided=%27false%27 inkscape:rounded=%270%27 inkscape:randomized=%270%27 d=%27m 16.66742,60.073212 -3.833708,2.213392 -3.8337072,2.213392 0,-4.426784 0,-4.426785 3.8337082,2.213392 z%27 /%3E%3Cpath id=%27path4615-5%27 d=%27m 171.82574,65.174193 16.34854,0 -8.17427,-13.348454 z%27 style=%27fill:%23f9a825;fill-rule:evenodd;stroke:%23f9a825;stroke-width:2;%27 /%3E%3Cpath style=%27opacity:1;fill:%23ffffff;%27 d=%27m 179,55 0,6 2,0 0,-6%27 id=%27path4300%27 /%3E%3Cpath style=%27opacity:1;fill:%23ffffff;%27 d=%27m 179,62 0,2 2,0 0,-2%27 id=%27path4300-6%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27M 99.994369,113.0221 102,114.98353 l 7,-6.9558 3,0.97227 2,-1 1,-2 0,-3 -3,3 -3,-3 3,-3 -3,0 -2,1 -1,2 0.99437,3.0221 z%27 id=%27path4268%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 234,6 0,2 -5,5 0,5 -2,0 0,-5 -5,-5 0,-2%27 id=%27path3546%27 /%3E%3Cg transform=%27matrix%281.3333328,0,0,-1.5999992,-139.9999,127.19999%29%27 id=%27g4383-6%27%3E%3Crect id=%27rect4385-2%27 height=%271%27 width=%276%27 y=%2712.625005%27 x=%27198%27 style=%27fill:%230d0d0d;stroke:%23000000;stroke-width:0%27 /%3E%3Crect style=%27fill:%230d0d0d;stroke:%23000000;stroke-width:0%27 x=%27198%27 y=%2715.125007%27 width=%278%27 height=%271%27 id=%27rect4387-9%27 /%3E%3Crect style=%27fill:%230d0d0d;stroke:%23000000;stroke-width:0%27 x=%27198%27 y=%277.6250024%27 width=%273%27 height=%271%27 id=%27rect4389-1-0%27 /%3E%3Crect style=%27fill:%230d0d0d;stroke:%23000000;stroke-width:0%27 x=%27198%27 y=%2710.125004%27 width=%274%27 height=%271%27 id=%27rect4389-1-9%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 207.00001,16.375004 0,-5.625005 -2.25,0 3,-3.1250014 3,3.1250014 -2.25,0 0,5.625005 -1.5,0%27 id=%27path4402%27 /%3E%3C/g%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 164,100 0,3 -6,6 0,7 -4,0 0,-7 -6,-6 0,-3%27 id=%27path3546-2-2%27 /%3E%3Cpath id=%27path4402-5-7%27 d=%27m 15,41 0,-7 -4,0 0,3 -5,-4 5,-4 0,3 6,0 0,9%27 style=%27fill:%230d0d0d;%27 /%3E%3C/svg%3E%0A")}body{/*! + * Selectr 2.4.13 + * http://mobius.ovh/docs/selectr + * + * Released under the MIT license + */}body .jsoneditor,body .jsoneditor-modal{-webkit-text-size-adjust:none;text-size-adjust:none}body .jsoneditor input,body .jsoneditor input:not([type]),body .jsoneditor input[type="text"],body .jsoneditor input[type="search"],body .jsoneditor-modal input,body .jsoneditor-modal input:not([type]),body .jsoneditor-modal input[type="text"],body .jsoneditor-modal input[type="search"]{height:auto;border:inherit;box-shadow:none;font-size:inherit;box-sizing:inherit;padding:inherit;font-family:inherit;transition:none;line-height:inherit}body .jsoneditor input:focus,body .jsoneditor input:not([type]):focus,body .jsoneditor input[type="text"]:focus,body .jsoneditor input[type="search"]:focus,body .jsoneditor-modal input:focus,body .jsoneditor-modal input:not([type]):focus,body .jsoneditor-modal input[type="text"]:focus,body .jsoneditor-modal input[type="search"]:focus{border:inherit;box-shadow:inherit}body .jsoneditor textarea,body .jsoneditor-modal textarea{height:inherit}body .jsoneditor select,body .jsoneditor-modal select{display:inherit;height:inherit}body .jsoneditor label,body .jsoneditor-modal label{font-size:inherit;font-weight:inherit;color:inherit}body .jsoneditor table,body .jsoneditor-modal table{border-collapse:collapse;width:auto}body .jsoneditor td,body .jsoneditor th,body .jsoneditor-modal td,body .jsoneditor-modal th{padding:0;display:table-cell;text-align:left;vertical-align:inherit;border-radius:inherit}body .jsoneditor .autocomplete.dropdown{position:absolute;background:var(--t42-content-color);box-shadow:var(--t42-shadow);border:1px solid var(--t42-color-opacity-10);overflow-x:hidden;overflow-y:auto;cursor:default;margin:0;padding:5px;text-align:left;outline:0;font-family:var(--bs-font-monospace);font-size:var(--t42-font-size)}body .jsoneditor .autocomplete.dropdown .item{color:var(--t42-content-color)}body .jsoneditor .autocomplete.dropdown .item.hover{background-color:Rgb(var(--t42-bg-mid))}body .jsoneditor .autocomplete.hint{color:var(--t42-content-color);top:4px;left:4px}body .jsoneditor-contextmenu-root{position:relative;width:0;height:0}body .jsoneditor-contextmenu{position:absolute;box-sizing:content-box;z-index:2}body .jsoneditor-contextmenu .jsoneditor-menu{position:relative;left:0;top:0;width:128px;height:auto;background:var(--t42-content-color);border:1px solid var(--t42-color-opacity-10);box-shadow:var(--t42-shadow);list-style:none;margin:0;padding:0}body .jsoneditor-contextmenu .jsoneditor-menu button{position:relative;padding:0 8px 0 0;margin:0;width:128px;height:auto;border:none;cursor:pointer;color:var(--t42-content-color);background:transparent;font-size:var(--t42-font-size);font-family:var(--t42-font-family);box-sizing:border-box;text-align:left}body .jsoneditor-contextmenu .jsoneditor-menu button::-moz-focus-inner{padding:0;border:0}body .jsoneditor-contextmenu .jsoneditor-menu button.jsoneditor-default{width:96px}body .jsoneditor-contextmenu .jsoneditor-menu button.jsoneditor-expand{float:right;width:32px;height:24px;border-left:1px solid var(--t42-color-opacity-10)}body .jsoneditor-contextmenu .jsoneditor-menu li{overflow:hidden}body .jsoneditor-contextmenu .jsoneditor-menu li ul{display:none;position:relative;left:-10px;top:0;border:none;box-shadow:inset var(--t42-shadow);padding:0 10px;-webkit-transition:all 0.3s ease-out;-moz-transition:all 0.3s ease-out;-o-transition:all 0.3s ease-out;transition:all 0.3s ease-out}body .jsoneditor-contextmenu .jsoneditor-menu li ul .jsoneditor-icon{margin-left:24px}body .jsoneditor-contextmenu .jsoneditor-menu li ul li button{padding-left:24px;animation:all ease-in-out 1s}body .jsoneditor-contextmenu .jsoneditor-menu li button .jsoneditor-expand{position:absolute;top:0;right:0;width:24px;height:24px;padding:0;margin:0 4px 0 0;background-image:"/";background-position:0 -72px}body .jsoneditor-contextmenu .jsoneditor-icon{position:absolute;top:0;left:0;width:24px;height:24px;border:none;padding:0;margin:0;background-image:"/"}body .jsoneditor-contextmenu .jsoneditor-text{padding:4px 0 4px 24px;word-wrap:break-word}body .jsoneditor-contextmenu .jsoneditor-text.jsoneditor-right-margin{padding-right:24px}body .jsoneditor-contextmenu .jsoneditor-separator{height:0;border-top:1px solid var(--t42-color-opacity-10);padding-top:5px;margin-top:5px}body .jsoneditor-contextmenu button.jsoneditor-remove .jsoneditor-icon{background-position:-24px 0}body .jsoneditor-contextmenu button.jsoneditor-append .jsoneditor-icon{background-position:0 0}body .jsoneditor-contextmenu button.jsoneditor-insert .jsoneditor-icon{background-position:0 0}body .jsoneditor-contextmenu button.jsoneditor-duplicate .jsoneditor-icon{background-position:-48px 0}body .jsoneditor-contextmenu button.jsoneditor-sort-asc .jsoneditor-icon{background-position:-168px 0}body .jsoneditor-contextmenu button.jsoneditor-sort-desc .jsoneditor-icon{background-position:-192px 0}body .jsoneditor-contextmenu button.jsoneditor-transform .jsoneditor-icon{background-position:-216px 0}body .jsoneditor-contextmenu button.jsoneditor-extract .jsoneditor-icon{background-position:0 -24px}body .jsoneditor-contextmenu button.jsoneditor-type-string .jsoneditor-icon{background-position:-144px 0}body .jsoneditor-contextmenu button.jsoneditor-type-auto .jsoneditor-icon{background-position:-120px 0}body .jsoneditor-contextmenu button.jsoneditor-type-object .jsoneditor-icon{background-position:-72px 0}body .jsoneditor-contextmenu button.jsoneditor-type-array .jsoneditor-icon{background-position:-96px 0}body .jsoneditor-contextmenu button.jsoneditor-type-modes .jsoneditor-icon{background-image:none;width:6px}body .jsoneditor-contextmenu ul,body .jsoneditor-contextmenu li{box-sizing:content-box;position:relative}body .jsoneditor-contextmenu .jsoneditor-menu button:hover,body .jsoneditor-contextmenu .jsoneditor-menu button:focus{color:var(--t42-content-color);background-color:var(--t42-color-opacity-10);outline:none}body .jsoneditor-contextmenu .jsoneditor-menu li button.jsoneditor-selected,body .jsoneditor-contextmenu .jsoneditor-menu li button.jsoneditor-selected:hover,body .jsoneditor-contextmenu .jsoneditor-menu li button.jsoneditor-selected:focus{color:var(--t42-content-color);background-color:var(--red)}body .jsoneditor-contextmenu .jsoneditor-menu li ul li button:hover,body .jsoneditor-contextmenu .jsoneditor-menu li ul li button:focus{background-color:var(--t42-color-opacity-10)}body .jsoneditor-modal{max-width:95%;border-radius:2px !important;padding:45px 15px 15px 15px !important;box-shadow:var(--t42-shadow);color:var(--t42-content-color);line-height:1.3em}body .jsoneditor-modal.jsoneditor-modal-transform{width:600px !important}body .jsoneditor-modal .pico-modal-header{position:absolute;box-sizing:border-box;top:0;left:0;width:100%;padding:0 10px;height:30px;line-height:30px;font-family:var(--t42-font-family);font-size:11pt;background:var(--primary);color:var(--t42-content-color)}body .jsoneditor-modal table{width:100%}body .jsoneditor-modal table td{padding:3px 0}body .jsoneditor-modal table td.jsoneditor-modal-input{text-align:right;padding-right:0;white-space:nowrap}body .jsoneditor-modal table td.jsoneditor-modal-actions{padding-top:15px}body .jsoneditor-modal table th{vertical-align:middle}body .jsoneditor-modal p:first-child{margin-top:0}body .jsoneditor-modal a{color:var(--primary)}body .jsoneditor-modal .jsoneditor-jmespath-block{margin-bottom:10px}body .jsoneditor-modal .pico-close{background:none !important;font-size:24px !important;top:7px !important;right:7px !important;color:var(--t42-content-color)}body .jsoneditor-modal input{padding:4px}body .jsoneditor-modal input[type="text"]{cursor:inherit}body .jsoneditor-modal input[disabled]{background:var(--t42-content-color-muted);color:var(--t42-content-color-muted)}body .jsoneditor-modal .jsoneditor-select-wrapper{position:relative;display:inline-block}body .jsoneditor-modal .jsoneditor-select-wrapper:after{content:"";width:0;height:0;border-left:5px solid transparent;border-right:5px solid transparent;border-top:6px solid #666;position:absolute;right:8px;top:14px;pointer-events:none}body .jsoneditor-modal select{padding:3px 24px 3px 10px;min-width:180px;max-width:350px;-webkit-appearance:none;-moz-appearance:none;appearance:none;text-indent:0;text-overflow:"";font-size:var(--t42-font-size);line-height:1.5em}body .jsoneditor-modal select::-ms-expand{display:none}body .jsoneditor-modal .jsoneditor-button-group input{padding:4px 10px;margin:0;border-radius:0;border-left-style:none}body .jsoneditor-modal .jsoneditor-button-group input.jsoneditor-button-first{border-top-left-radius:3px;border-bottom-left-radius:3px;border-left-style:solid}body .jsoneditor-modal .jsoneditor-button-group input.jsoneditor-button-last{border-top-right-radius:3px;border-bottom-right-radius:3px}body .jsoneditor-modal .jsoneditor-transform-preview{background:var(--t42-color-opacity-10);height:200px}body .jsoneditor-modal .jsoneditor-transform-preview.jsoneditor-error{color:var(--red)}body .jsoneditor-modal .jsoneditor-jmespath-wizard{line-height:1.2em;width:100%;padding:0;border-radius:3px}body .jsoneditor-modal .jsoneditor-jmespath-label{font-weight:bold;color:dodgerblue;margin-top:20px;margin-bottom:5px}body .jsoneditor-modal .jsoneditor-jmespath-wizard-table{width:100%;border-collapse:collapse}body .jsoneditor-modal .jsoneditor-jmespath-wizard-label{font-style:italic;margin:4px 0 2px 0}body .jsoneditor-modal .jsoneditor-inline{position:relative;display:inline-block;width:100%;padding-top:2px;padding-bottom:2px}body .jsoneditor-modal .jsoneditor-inline:not(:last-child){padding-right:2px}body .jsoneditor-modal .jsoneditor-jmespath-filter{display:flex;flex-wrap:wrap}body .jsoneditor-modal .jsoneditor-jmespath-filter-field{width:180px}body .jsoneditor-modal .jsoneditor-jmespath-filter-relation{width:100px}body .jsoneditor-modal .jsoneditor-jmespath-filter-value{min-width:180px;flex:1}body .jsoneditor-modal .jsoneditor-jmespath-sort-field{width:170px}body .jsoneditor-modal .jsoneditor-jmespath-sort-order{width:150px}body .jsoneditor-modal .jsoneditor-jmespath-select-fields{width:100%}body .jsoneditor-modal .selectr-selected{border-color:var(--t42-color-opacity-10);padding:4px 28px 4px 8px}body .jsoneditor-modal .selectr-selected .selectr-tag{background-color:var(--primary);border-radius:5px}body .jsoneditor-modal table th,body .jsoneditor-modal table td{text-align:left;vertical-align:middle;font-weight:normal;color:var(--t42-content-color);border-spacing:0;border-collapse:collapse}body .jsoneditor-modal select,body .jsoneditor-modal textarea,body .jsoneditor-modal input,body .jsoneditor-modal input[type="text"],body .jsoneditor-modal input[type="text"]:focus,body .jsoneditor-modal #query{background:#ffffff;border:1px solid var(--t42-color-opacity-10);color:var(--t42-content-color);border-radius:3px;padding:4px}body .jsoneditor-modal textarea,body .jsoneditor-modal #query{border-radius:unset}body .jsoneditor-modal,body .jsoneditor-modal table td,body .jsoneditor-modal table th,body .jsoneditor-modal select,body .jsoneditor-modal option,body .jsoneditor-modal textarea,body .jsoneditor-modal input,body .jsoneditor-modal input[type="text"],body .jsoneditor-modal #query{font-size:10.5pt;font-family:var(--t42-font-family)}body .jsoneditor-modal #query,body .jsoneditor-modal .jsoneditor-transform-preview{font-family:var(--bs-font-monospace);font-size:var(--t42-font-size);width:100%;box-sizing:border-box}body .jsoneditor-modal input[type="button"],body .jsoneditor-modal input[type="submit"]{background:var(--t42-color-opacity-10);padding:4px 20px}body .jsoneditor-modal select,body .jsoneditor-modal input{cursor:pointer}body .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-asc input.jsoneditor-button-asc,body .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-desc input.jsoneditor-button-desc{background:var(--primary);border-color:var(--primary);color:var(--t42-content-color)}body .jsoneditor{color:var(--t42-content-color);border:thin solid var(--primary);-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;width:100%;height:100%;position:relative;padding:0;line-height:100%}body div.jsoneditor-field,body div.jsoneditor-value,body a.jsoneditor-value,body div.jsoneditor-readonly,body div.jsoneditor-default{border:1px solid transparent;min-height:16px;min-width:32px;line-height:16px;padding:2px;margin:1px;word-wrap:break-word;word-break:break-word;overflow-wrap:break-word;float:left}body div.jsoneditor-field p,body div.jsoneditor-value p{margin:0}body div.jsoneditor-value.jsoneditor-empty::after{content:"value"}body div.jsoneditor-value.jsoneditor-string{color:var(--green)}body div.jsoneditor-value.jsoneditor-number{color:var(--red)}body div.jsoneditor-value.jsoneditor-boolean{color:var(--yellow)}body div.jsoneditor-value.jsoneditor-null{color:var(--primary)}body div.jsoneditor-value.jsoneditor-color-value{color:var(--t42-content-color)}body div.jsoneditor-value.jsoneditor-invalid{color:var(--white)}body div.jsoneditor-readonly{min-width:16px;color:var(--t42-content-color-muted)}body div.jsoneditor-empty{border-color:var(--t42-color-opacity-10);border-style:dashed;border-radius:2px}body div.jsoneditor-field.jsoneditor-empty::after{content:"field"}body div.jsoneditor td{vertical-align:top}body div.jsoneditor td.jsoneditor-separator{padding:3px 0;vertical-align:top;color:var(--t42-content-color-muted)}body div.jsoneditor td.jsoneditor-tree{vertical-align:top}body div.jsoneditor.busy pre.jsoneditor-preview{background:var(--t42-color-opacity-10);color:var(--t42-content-color-muted)}body div.jsoneditor.busy div.jsoneditor-busy{display:inherit}body div.jsoneditor code.jsoneditor-preview{background:none}body div.jsoneditor.jsoneditor-mode-preview pre.jsoneditor-preview{width:100%;height:100%;box-sizing:border-box;overflow:auto;padding:2px;margin:0;white-space:pre-wrap;word-break:break-all}body div.jsoneditor-default{color:var(--t42-content-color-muted);padding-left:10px}body div.jsoneditor-tree{width:100%;height:100%;position:relative;overflow:auto;background:var(--t42-content-color)}body div.jsoneditor-tree button.jsoneditor-button{width:24px;height:24px;padding:0;margin:0;border:none;cursor:pointer;background-color:transparent;background-image:"/"}body div.jsoneditor-tree button.jsoneditor-button:focus{background-color:var(--t42-color-opacity-10);outline:#e5e5e5 solid 1px}body div.jsoneditor-tree button.jsoneditor-collapsed{background-position:0 -48px}body div.jsoneditor-tree button.jsoneditor-expanded{background-position:0 -72px}body div.jsoneditor-tree button.jsoneditor-contextmenu-button{background-position:-48px -72px}body div.jsoneditor-tree button.jsoneditor-invisible{visibility:hidden;background:none}body div.jsoneditor-tree button.jsoneditor-dragarea{background-image:"/";background-position:-72px -72px;cursor:move}body div.jsoneditor-tree *:focus{outline:none}body div.jsoneditor-tree div.jsoneditor-show-more{display:inline-block;padding:3px 4px;margin:2px 0;background-color:var(--t42-color-opacity-10);border-radius:3px;color:var(--t42-content-color-muted);font-family:var(--t42-font-family);font-size:var(--t42-font-size)}body div.jsoneditor-tree div.jsoneditor-show-more a{display:inline-block;color:var(--t42-content-color-muted)}body div.jsoneditor-tree div.jsoneditor-color{display:inline-block;width:12px;height:12px;margin:4px;border:1px solid var(--t42-content-color-muted);cursor:pointer}body div.jsoneditor-tree div.jsoneditor-color.jsoneditor-color-readonly{cursor:inherit}body div.jsoneditor-tree div.jsoneditor-date{background:var(--t42-content-color);color:var(--t42-content-color);font-family:var(--t42-font-family);border-radius:3px;display:inline-block;padding:3px;margin:0 3px}body div.jsoneditor-tree table.jsoneditor-tree{border-collapse:collapse;border-spacing:0;width:100%}body div.jsoneditor-tree .jsoneditor-button{display:block}body div.jsoneditor-tree .jsoneditor-button.jsoneditor-schema-error{width:24px;height:24px;padding:0;margin:0 4px 0 0;background-image:"/";background-position:-168px -48px;background-color:transparent}body div.jsoneditor-outer{position:static;width:100%;height:100%;margin:0;padding:0;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}body div.jsoneditor-outer.has-nav-bar{margin-top:-26px;padding-top:26px}body div.jsoneditor-outer.has-nav-bar.has-main-menu-bar{margin-top:-61px;padding-top:61px}body div.jsoneditor-outer.has-status-bar{margin-bottom:-26px;padding-bottom:26px}body div.jsoneditor-outer.has-main-menu-bar{margin-top:-35px;padding-top:35px}body div.jsoneditor-busy{position:absolute;top:15%;left:0;box-sizing:border-box;width:100%;text-align:center;display:none}body div.jsoneditor-busy span{background-color:var(--t42-color-opacity-10);border:1px solid var(--t42-color-opacity-10);border-radius:3px;padding:5px 15px;box-shadow:var(--t42-shadow)}body div.jsoneditor-field.jsoneditor-empty::after,body div.jsoneditor-value.jsoneditor-empty::after{pointer-events:none;color:var(--t42-content-color-muted);font-size:8pt}body div.jsoneditor-value.jsoneditor-url,body a.jsoneditor-value.jsoneditor-url{color:var(--green);text-decoration:underline}body a.jsoneditor-value.jsoneditor-url{display:inline-block;padding:2px;margin:2px}body a.jsoneditor-value.jsoneditor-url:hover,body a.jsoneditor-value.jsoneditor-url:focus{color:var(--red)}body div.jsoneditor-field[contenteditable="true"]:focus,body div.jsoneditor-field[contenteditable="true"]:hover,body div.jsoneditor-value[contenteditable="true"]:focus,body div.jsoneditor-value[contenteditable="true"]:hover,body div.jsoneditor-field.jsoneditor-highlight,body div.jsoneditor-value.jsoneditor-highlight{background-color:var(--t42-color-opacity-10);border:1px solid var(--t42-color-opacity-10);border-radius:2px}body div.jsoneditor-field.jsoneditor-highlight-active,body div.jsoneditor-field.jsoneditor-highlight-active:focus,body div.jsoneditor-field.jsoneditor-highlight-active:hover,body div.jsoneditor-value.jsoneditor-highlight-active,body div.jsoneditor-value.jsoneditor-highlight-active:focus,body div.jsoneditor-value.jsoneditor-highlight-active:hover{background-color:#fe0;border:1px solid #ffc700;border-radius:2px}body div.jsoneditor-value.jsoneditor-object,body div.jsoneditor-value.jsoneditor-array{min-width:16px}body div.jsoneditor-tree button.jsoneditor-contextmenu-button:hover,body div.jsoneditor-tree button.jsoneditor-contextmenu-button:focus,body div.jsoneditor-tree button.jsoneditor-contextmenu-button.jsoneditor-selected,body tr.jsoneditor-selected.jsoneditor-first button.jsoneditor-contextmenu-button{background-position:-48px -48px}body div.jsoneditor-tree div.jsoneditor-show-more a:hover,body div.jsoneditor-tree div.jsoneditor-show-more a:focus{color:var(--red)}body textarea.jsoneditor-text,body .ace-jsoneditor{min-height:150px}body textarea.jsoneditor-text.ace_editor,body .ace-jsoneditor.ace_editor{font-family:var(--bs-font-monospace)}body textarea.jsoneditor-text{width:100%;height:100%;margin:0;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;outline-width:0;border:none;background-color:var(--t42-content-color);resize:none}body tr.jsoneditor-highlight,body tr.jsoneditor-selected{background-color:var(--t42-content-color-muted)}body tr.jsoneditor-selected button.jsoneditor-dragarea,body tr.jsoneditor-selected button.jsoneditor-contextmenu-button{visibility:hidden}body tr.jsoneditor-selected.jsoneditor-first button.jsoneditor-dragarea,body tr.jsoneditor-selected.jsoneditor-first button.jsoneditor-contextmenu-button{visibility:visible}body div.jsoneditor-tree button.jsoneditor-dragarea:hover,body div.jsoneditor-tree button.jsoneditor-dragarea:focus,body tr.jsoneditor-selected.jsoneditor-first button.jsoneditor-dragarea{background-position:-72px -48px}body div.jsoneditor tr,body div.jsoneditor th,body div.jsoneditor td{padding:0;margin:0}body div.jsoneditor-field,body div.jsoneditor-value,body div.jsoneditor td,body div.jsoneditor th,body div.jsoneditor textarea,body pre.jsoneditor-preview,body .jsoneditor-schema-error,body .jsoneditor-popover{font-family:var(--bs-font-monospace);font-size:var(--t42-font-size);color:var(--t42-content-color)}body .jsoneditor-schema-error{cursor:default;display:inline-block;height:24px;line-height:24px;position:relative;text-align:center;width:24px}body .jsoneditor-popover{background-color:Rgb(var(--t42-bg-light));border-radius:3px;box-shadow:var(--t42-shadow);color:var(--t42-content-color);padding:7px 10px;position:absolute;cursor:auto;width:200px}body .jsoneditor-popover.jsoneditor-above{bottom:32px;left:-98px}body .jsoneditor-popover.jsoneditor-above:before{border-top:7px solid Rgb(var(--t42-bg-light));bottom:-7px}body .jsoneditor-popover.jsoneditor-below{top:32px;left:-98px}body .jsoneditor-popover.jsoneditor-below:before{border-bottom:7px solid Rgb(var(--t42-bg-light));top:-7px}body .jsoneditor-popover.jsoneditor-left{top:-7px;right:32px}body .jsoneditor-popover.jsoneditor-left:before{border-left:7px solid Rgb(var(--t42-bg-light));border-top:7px solid transparent;border-bottom:7px solid transparent;content:"";top:19px;right:-14px;left:inherit;margin-left:inherit;margin-top:-7px;position:absolute}body .jsoneditor-popover.jsoneditor-right{top:-7px;left:32px}body .jsoneditor-popover.jsoneditor-right:before{border-right:7px solid Rgb(var(--t42-bg-light));border-top:7px solid transparent;border-bottom:7px solid transparent;content:"";top:19px;left:-14px;margin-left:inherit;margin-top:-7px;position:absolute}body .jsoneditor-popover:before{border-right:7px solid transparent;border-left:7px solid transparent;content:"";display:block;left:50%;margin-left:-7px;position:absolute}body .jsoneditor-text-errors tr.jump-to-line:hover{text-decoration:underline;cursor:pointer}body .jsoneditor-schema-error:hover .jsoneditor-popover,body .jsoneditor-schema-error:focus .jsoneditor-popover{display:block;animation:fade-in 0.3s linear 1, move-up 0.3s linear 1}@keyframes fade-in{from{opacity:0}to{opacity:1}}body .jsoneditor .jsoneditor-validation-errors-container{max-height:130px;overflow-y:auto}body .jsoneditor .jsoneditor-validation-errors{width:100%;overflow:hidden}body .jsoneditor .jsoneditor-additional-errors{position:absolute;margin:auto;bottom:31px;left:calc(50% - 92px);color:var(--t42-content-color-muted);background-color:Rgb(var(--t42-bg-mid));padding:7px 15px;border-radius:8px}body .jsoneditor .jsoneditor-additional-errors.visible{visibility:visible;opacity:1;transition:opacity 2s linear}body .jsoneditor .jsoneditor-additional-errors.hidden{visibility:hidden;opacity:0;transition:visibility 0s 2s, opacity 2s linear}body .jsoneditor .jsoneditor-text-errors{width:100%;border-collapse:collapse;border-top:1px solid #ffc700}body .jsoneditor .jsoneditor-text-errors td{padding:3px 6px;vertical-align:middle}body .jsoneditor .jsoneditor-text-errors td pre{margin:0;white-space:pre-wrap}body .jsoneditor .jsoneditor-text-errors tr{background-color:var(--t42-color-opacity-10)}body .jsoneditor .jsoneditor-text-errors tr.parse-error{background-color:var(--red)}body .jsoneditor-text-errors .jsoneditor-schema-error{border:none;width:24px;height:24px;padding:0;margin:0 4px 0 0;cursor:pointer}body .jsoneditor-text-errors tr .jsoneditor-schema-error{background-image:"/";background-position:-168px -48px;background-color:transparent}body .jsoneditor-text-errors tr.parse-error .jsoneditor-schema-error{background-image:"/";background-position:-25px 0px;background-color:transparent}body .jsoneditor-anchor{cursor:pointer}body .jsoneditor-anchor .picker_wrapper.popup.popup_bottom{top:28px;left:-10px}body .fadein{-webkit-animation:fadein 0.3s;animation:fadein 0.3s;-moz-animation:fadein 0.3s;-o-animation:fadein 0.3s}@keyframes fadein{0%{opacity:0}100%{opacity:1}}body .jsoneditor-modal input[type="search"].selectr-input{border:1px solid #d3d3d3;width:calc(100% - 4px);margin:2px;padding:4px;box-sizing:border-box}body .jsoneditor-modal button.selectr-input-clear{right:8px}body .jsoneditor-menu{width:100%;height:35px;padding:2px;margin:0;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;color:var(--t42-content-color);background-color:var(--primary);border-bottom:1px solid var(--primary)}body .jsoneditor-menu>button,body .jsoneditor-menu>.jsoneditor-modes>button{width:26px;height:26px;margin:2px;padding:0;border-radius:2px;border:1px solid transparent;background-color:transparent;background-image:"/";color:var(--t42-content-color);opacity:0.8;font-family:var(--t42-font-family);font-size:var(--t42-font-size);float:left}body .jsoneditor-menu>button:hover,body .jsoneditor-menu>.jsoneditor-modes>button:hover{background-color:rgba(255,255,255,0.2);border:1px solid rgba(255,255,255,0.4)}body .jsoneditor-menu>button:focus,body .jsoneditor-menu>button:active,body .jsoneditor-menu>.jsoneditor-modes>button:focus,body .jsoneditor-menu>.jsoneditor-modes>button:active{background-color:rgba(255,255,255,0.3)}body .jsoneditor-menu>button:disabled,body .jsoneditor-menu>.jsoneditor-modes>button:disabled{opacity:0.5;background-color:transparent;border:none}body .jsoneditor-menu>button.jsoneditor-collapse-all{background-position:0 -96px}body .jsoneditor-menu>button.jsoneditor-expand-all{background-position:0 -120px}body .jsoneditor-menu>button.jsoneditor-sort{background-position:-120px -96px}body .jsoneditor-menu>button.jsoneditor-transform{background-position:-144px -96px}body .jsoneditor.jsoneditor-mode-view>.jsoneditor-menu>button.jsoneditor-sort,body .jsoneditor.jsoneditor-mode-form>.jsoneditor-menu>button.jsoneditor-sort,body .jsoneditor.jsoneditor-mode-view>.jsoneditor-menu>button.jsoneditor-transform,body .jsoneditor.jsoneditor-mode-form>.jsoneditor-menu>button.jsoneditor-transform{display:none}body .jsoneditor-menu>button.jsoneditor-undo{background-position:-24px -96px}body .jsoneditor-menu>button.jsoneditor-undo:disabled{background-position:-24px -120px}body .jsoneditor-menu>button.jsoneditor-redo{background-position:-48px -96px}body .jsoneditor-menu>button.jsoneditor-redo:disabled{background-position:-48px -120px}body .jsoneditor-menu>button.jsoneditor-compact{background-position:-72px -96px}body .jsoneditor-menu>button.jsoneditor-format{background-position:-72px -120px}body .jsoneditor-menu>button.jsoneditor-repair{background-position:-96px -96px}body .jsoneditor-menu>.jsoneditor-modes{display:inline-block;float:left}body .jsoneditor-menu>.jsoneditor-modes>button{background-image:none;width:auto;padding-left:6px;padding-right:6px}body .jsoneditor-menu>button.jsoneditor-separator,body .jsoneditor-menu>.jsoneditor-modes>button.jsoneditor-separator{margin-left:10px}body .jsoneditor-menu a{font-family:var(--t42-font-family);font-size:var(--t42-font-size);color:var(--t42-content-color);opacity:0.8;vertical-align:middle}body .jsoneditor-menu a:hover{opacity:1}body .jsoneditor-menu a.jsoneditor-poweredBy{font-size:8pt;position:absolute;right:0;top:0;padding:10px}body .jsoneditor-navigation-bar{width:100%;height:26px;line-height:26px;padding:0;margin:0;border-bottom:1px solid var(--t42-color-opacity-10);-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;color:var(--t42-content-color-muted);background-color:Rgb(var(--t42-bg-mid));overflow:hidden;font-family:var(--t42-font-family);font-size:var(--t42-font-size)}body .jsoneditor-search{font-family:var(--t42-font-family);position:absolute;right:4px;top:4px;border-collapse:collapse;border-spacing:0;display:flex}body .jsoneditor-search input{color:var(--t42-content-color);width:120px;border:none;outline:none;margin:1px;line-height:20px;font-family:var(--t42-font-family)}body .jsoneditor-search button{width:16px;height:24px;padding:0;margin:0;border:none;background:"/";vertical-align:top}body .jsoneditor-search button:hover{background-color:transparent}body .jsoneditor-search button.jsoneditor-refresh{width:18px;background-position:-99px -73px}body .jsoneditor-search button.jsoneditor-next{cursor:pointer;background-position:-124px -73px}body .jsoneditor-search button.jsoneditor-next:hover{background-position:-124px -49px}body .jsoneditor-search button.jsoneditor-previous{cursor:pointer;background-position:-148px -73px;margin-right:2px}body .jsoneditor-search button.jsoneditor-previous:hover{background-position:-148px -49px}body .jsoneditor-results{font-family:var(--t42-font-family);color:var(--t42-content-color);padding-right:5px;line-height:26px}body .jsoneditor-frame{border:1px solid transparent;background-color:var(--t42-content-color);padding:0 2px;margin:0}body .jsoneditor-statusbar{line-height:26px;height:26px;color:var(--t42-content-color-muted);background-color:Rgb(var(--t42-bg-mid));border-top:1px solid var(--t42-color-opacity-10);-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;font-size:var(--t42-font-size)}body .jsoneditor-statusbar>.jsoneditor-curserinfo-val{margin-right:12px}body .jsoneditor-statusbar>.jsoneditor-curserinfo-count{margin-left:4px}body .jsoneditor-statusbar>.jsoneditor-validation-error-icon{float:right;width:24px;height:24px;padding:0;margin-top:1px;background-image:"/";background-position:-168px -48px;cursor:pointer}body .jsoneditor-statusbar>.jsoneditor-validation-error-count{float:right;margin:0 4px 0 0;cursor:pointer}body .jsoneditor-statusbar>.jsoneditor-parse-error-icon{float:right;width:24px;height:24px;padding:0;margin:1px;background-image:"/";background-position:-25px 0px}body .jsoneditor-statusbar .jsoneditor-array-info a{color:inherit}body div.jsoneditor-statusbar>.jsoneditor-curserinfo-label,body div.jsoneditor-statusbar>.jsoneditor-size-info{margin:0 4px}body .jsoneditor-treepath{padding:0 5px;overflow:hidden;white-space:nowrap;outline:none}body .jsoneditor-treepath.show-all{word-wrap:break-word;white-space:normal;position:absolute;background-color:Rgb(var(--t42-bg-mid));z-index:1;box-shadow:var(--t42-shadow)}body .jsoneditor-treepath.show-all span.jsoneditor-treepath-show-all-btn{display:none}body .jsoneditor-treepath div.jsoneditor-contextmenu-root{position:absolute;left:0}body .jsoneditor-treepath .jsoneditor-treepath-show-all-btn{position:absolute;background-color:Rgb(var(--t42-bg-mid));left:0;height:20px;padding:0 3px;cursor:pointer}body .jsoneditor-treepath .jsoneditor-treepath-element{margin:1px;font-family:var(--t42-font-family);font-size:var(--t42-font-size)}body .jsoneditor-treepath .jsoneditor-treepath-seperator{margin:2px;font-size:9pt;font-family:var(--t42-font-family)}body .jsoneditor-treepath span.jsoneditor-treepath-element:hover,body .jsoneditor-treepath span.jsoneditor-treepath-seperator:hover{cursor:pointer;text-decoration:underline}body .selectr-container{position:relative}body .selectr-container li{list-style:none}body .selectr-hidden{position:absolute;overflow:hidden;clip:rect(0px, 0px, 0px, 0px);width:1px;height:1px;margin:-1px;padding:0;border:0 none}body .selectr-visible{position:absolute;left:0;top:0;width:100%;height:100%;opacity:0;z-index:11}body .selectr-desktop.multiple .selectr-visible{display:none}body .selectr-desktop.multiple.native-open .selectr-visible{top:100%;min-height:200px !important;height:auto;opacity:1;display:block}body .selectr-container.multiple.selectr-mobile .selectr-selected{z-index:0}body .selectr-selected{position:relative;z-index:1;box-sizing:border-box;width:100%;padding:7px 28px 7px 14px;cursor:pointer;border:1px solid Rgb(var(--t42-bg-mid));border-radius:3px;background-color:var(--t42-content-color)}body .selectr-selected::before{position:absolute;top:50%;right:10px;width:0;height:0;content:'';-o-transform:rotate(0deg) translate3d(0px, -50%, 0px);-ms-transform:rotate(0deg) translate3d(0px, -50%, 0px);-moz-transform:rotate(0deg) translate3d(0px, -50%, 0px);-webkit-transform:rotate(0deg) translate3d(0px, -50%, 0px);transform:rotate(0deg) translate3d(0px, -50%, 0px);border-width:4px 4px 0 4px;border-style:solid;border-color:#6c7a86 transparent transparent}body .selectr-container.open .selectr-selected::before,body .selectr-container.native-open .selectr-selected::before{border-width:0 4px 4px 4px;border-style:solid;border-color:transparent transparent #6c7a86}body .selectr-label{display:none;overflow:hidden;width:100%;white-space:nowrap;text-overflow:ellipsis}body .selectr-placeholder{color:#6c7a86}body .selectr-tags{margin:0;padding:0;white-space:normal}body .has-selected .selectr-tags{margin:0 0 -2px}body .selectr-tag{list-style:none;position:relative;float:left;padding:2px 25px 2px 8px;margin:0 2px 2px 0;cursor:default;color:var(--t42-content-color);border:medium none;border-radius:10px;background:#acb7bf none repeat scroll 0 0}body .selectr-container.multiple.has-selected .selectr-selected{padding:5px 28px 5px 5px}body .selectr-options-container{position:absolute;z-index:10000;top:calc(100% - 1px);left:0;display:none;box-sizing:border-box;width:100%;border-width:0 1px 1px;border-style:solid;border-color:transparent Rgb(var(--t42-bg-mid)) Rgb(var(--t42-bg-mid));border-radius:0 0 3px 3px;background-color:var(--t42-content-color)}body .selectr-container.open .selectr-options-container{display:block}body .selectr-input-container{position:relative;display:none}body .selectr-clear,body .selectr-input-clear,body .selectr-tag-remove{position:absolute;top:50%;right:22px;width:20px;height:20px;padding:0;cursor:pointer;-o-transform:translate3d(0px, -50%, 0px);-ms-transform:translate3d(0px, -50%, 0px);-moz-transform:translate3d(0px, -50%, 0px);-webkit-transform:translate3d(0px, -50%, 0px);transform:translate3d(0px, -50%, 0px);border:medium none;background-color:transparent;z-index:11}body .selectr-clear,body .selectr-input-clear{display:none}body .selectr-container.has-selected .selectr-clear,body .selectr-input-container.active .selectr-input-clear{display:block}body .selectr-selected .selectr-tag-remove{right:2px}body .selectr-clear::before,body .selectr-clear::after,body .selectr-input-clear::before,body .selectr-input-clear::after,body .selectr-tag-remove::before,body .selectr-tag-remove::after{position:absolute;top:5px;left:9px;width:2px;height:10px;content:' ';background-color:#6c7a86}body .selectr-tag-remove::before,body .selectr-tag-remove::after{top:4px;width:3px;height:12px;background-color:var(--t42-content-color)}body .selectr-clear:before,body .selectr-input-clear::before,body .selectr-tag-remove::before{-o-transform:rotate(45deg);-ms-transform:rotate(45deg);-moz-transform:rotate(45deg);-webkit-transform:rotate(45deg);transform:rotate(45deg)}body .selectr-clear:after,body .selectr-input-clear::after,body .selectr-tag-remove::after{-o-transform:rotate(-45deg);-ms-transform:rotate(-45deg);-moz-transform:rotate(-45deg);-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}body .selectr-input-container.active,body .selectr-input-container.active .selectr-clear{display:block}body .selectr-input{top:5px;left:5px;box-sizing:border-box;width:calc(100% - 30px);margin:10px 15px;padding:7px 30px 7px 9px;border:1px solid Rgb(var(--t42-bg-mid));border-radius:3px}body .selectr-notice{display:none;box-sizing:border-box;width:100%;padding:8px 16px;border-top:1px solid Rgb(var(--t42-bg-mid));border-radius:0 0 3px 3px;background-color:var(--t42-content-color)}body .selectr-container.notice .selectr-notice{display:block}body .selectr-container.notice .selectr-selected{border-radius:3px 3px 0 0}body .selectr-options{position:relative;top:calc(100% + 2px);display:none;overflow-x:auto;overflow-y:scroll;max-height:200px;margin:0;padding:0}body .selectr-container.open .selectr-options,body .selectr-container.open .selectr-input-container,body .selectr-container.notice .selectr-options-container{display:block}body .selectr-option{position:relative;display:block;padding:5px 20px;list-style:outside none none;cursor:pointer;font-weight:normal}body .selectr-options.optgroups>.selectr-option{padding-left:25px}body .selectr-optgroup{font-weight:bold;padding:0}body .selectr-optgroup--label{font-weight:bold;margin-top:10px;padding:5px 15px}body .selectr-match{text-decoration:underline}body .selectr-option.selected{background-color:#ddd}body .selectr-option.active{color:var(--t42-content-color);background-color:#5897fb}body .selectr-option.disabled{opacity:0.4}body .selectr-option.excluded{display:none}body .selectr-container.open .selectr-selected{border-color:Rgb(var(--t42-bg-mid)) Rgb(var(--t42-bg-mid)) transparent Rgb(var(--t42-bg-mid));border-radius:3px 3px 0 0}body .selectr-container.open .selectr-selected::after{-o-transform:rotate(180deg) translate3d(0px, 50%, 0px);-ms-transform:rotate(180deg) translate3d(0px, 50%, 0px);-moz-transform:rotate(180deg) translate3d(0px, 50%, 0px);-webkit-transform:rotate(180deg) translate3d(0px, 50%, 0px);transform:rotate(180deg) translate3d(0px, 50%, 0px)}body .selectr-disabled{opacity:.6}body .selectr-empty,body .has-selected .selectr-placeholder{display:none}body .has-selected .selectr-label{display:block}body .taggable .selectr-selected{padding:4px 28px 4px 4px}body .taggable .selectr-selected::after{display:table;content:" ";clear:both}body .taggable .selectr-label{width:auto}body .taggable .selectr-tags{float:left;display:block}body .taggable .selectr-placeholder{display:none}body .input-tag{float:left;min-width:90px;width:auto}body .selectr-tag-input{border:medium none;padding:3px 10px;width:100%;font-family:inherit;font-weight:inherit;font-size:inherit}body .selectr-input-container.loading::after{position:absolute;top:50%;right:20px;width:20px;height:20px;content:'';-o-transform:translate3d(0px, -50%, 0px);-ms-transform:translate3d(0px, -50%, 0px);-moz-transform:translate3d(0px, -50%, 0px);-webkit-transform:translate3d(0px, -50%, 0px);transform:translate3d(0px, -50%, 0px);-o-transform-origin:50% 0 0;-ms-transform-origin:50% 0 0;-moz-transform-origin:50% 0 0;-webkit-transform-origin:50% 0 0;transform-origin:50% 0 0;-moz-animation:500ms linear 0s normal forwards infinite running selectr-spin;-webkit-animation:500ms linear 0s normal forwards infinite running selectr-spin;animation:500ms linear 0s normal forwards infinite running selectr-spin;border-width:3px;border-style:solid;border-color:#aaa #ddd #ddd;border-radius:50%}@-webkit-keyframes selectr-spin{0%{-webkit-transform:rotate(0deg) translate3d(0px, -50%, 0px);transform:rotate(0deg) translate3d(0px, -50%, 0px)}100%{-webkit-transform:rotate(360deg) translate3d(0px, -50%, 0px);transform:rotate(360deg) translate3d(0px, -50%, 0px)}}@keyframes selectr-spin{0%{-webkit-transform:rotate(0deg) translate3d(0px, -50%, 0px);transform:rotate(0deg) translate3d(0px, -50%, 0px)}100%{-webkit-transform:rotate(360deg) translate3d(0px, -50%, 0px);transform:rotate(360deg) translate3d(0px, -50%, 0px)}}body .selectr-container.open.inverted .selectr-selected{border-color:transparent Rgb(var(--t42-bg-mid)) Rgb(var(--t42-bg-mid));border-radius:0 0 3px 3px}body .selectr-container.inverted .selectr-options-container{border-width:1px 1px 0;border-color:Rgb(var(--t42-bg-mid)) Rgb(var(--t42-bg-mid)) transparent;border-radius:3px 3px 0 0;background-color:var(--t42-content-color)}body .selectr-container.inverted .selectr-options-container{top:auto;bottom:calc(100% - 1px)}body .selectr-container ::-webkit-input-placeholder{color:#6c7a86;opacity:1}body .selectr-container ::-moz-placeholder{color:#6c7a86;opacity:1}body .selectr-container :-ms-input-placeholder{color:#6c7a86;opacity:1}body .selectr-container ::placeholder{color:#6c7a86;opacity:1}body #jsoneditor{height:100%}body .jsoneditor{border-color:var(--t42-color-opacity-10)}body .jsoneditor textarea{line-height:1.5;background-color:Rgb(var(--t42-bg-dark));min-height:100%}body .jsoneditor input{outline:0}body .jsoneditor input:focus{outline:0}body .jsoneditor-button:focus{outline:none}body .jsoneditor-menu{border-bottom-color:var(--t42-color-opacity-10);background-color:Rgb(var(--t42-bg-light))}body .jsoneditor-menu button{background-image:var(--t42-json-icons);background-color:transparent}body .jsoneditor-menu button:hover,body .jsoneditor-menu button:focus{color:var(--t42-link-hover-color)}body .jsoneditor-menu>button,body .jsoneditor-menu>.jsoneditor-modes>button{border-radius:0;font-size:.75rem;backdrop-filter:var(--backdrop-filter);transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, color}body .jsoneditor-menu>button:hover:not(.disabled):not(:disabled),body .jsoneditor-menu>button:active,body .jsoneditor-menu>.jsoneditor-modes>button:hover:not(.disabled):not(:disabled),body .jsoneditor-menu>.jsoneditor-modes>button:active{border-color:transparent;color:var(--t42-link-hover-color);background-color:var(--t42-color-opacity-10)}body .jsoneditor-menu li button.jsoneditor-selected{background-color:var(--t42-color-opacity-10)}body .jsoneditor-menu .jsoneditor-poweredBy{display:none}body .jsoneditor-frame{padding:0 .875rem;border-color:var(--t42-color-opacity-10);background-color:transparent;display:flex;transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border-color}body .jsoneditor-frame:focus-within{border-color:var(--primary);background-color:var(--t42-input-bg);outline:0}body .jsoneditor-frame table td{vertical-align:middle}body .jsoneditor-search input[type="text"]{border:0}body .jsoneditor-search input[type="text"]:focus{border:0}body .jsoneditor-search input{background-color:transparent}body .jsoneditor-contextmenu{z-index:2}body .jsoneditor-contextmenu .jsoneditor-menu{border-color:var(--t42-color-opacity-10);background:linear-gradient(to bottom right, rgba(var(--t42-bg-light), 0.75) 0%, rgba(var(--t42-bg-dark), 0.75) 100%);box-shadow:var(--t42-shadow);backdrop-filter:var(--backdrop-filter)}body .jsoneditor-contextmenu .jsoneditor-menu button button .jsoneditor-expand,body .jsoneditor-contextmenu .jsoneditor-menu li button .jsoneditor-expand{background-image:var(--t42-json-icons);z-index:1}body .jsoneditor-contextmenu .jsoneditor-menu button button.jsoneditor-selected,body .jsoneditor-contextmenu .jsoneditor-menu li button.jsoneditor-selected{background-color:var(--t42-color-opacity-10);transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, color}body .jsoneditor-contextmenu .jsoneditor-menu button button.jsoneditor-selected:hover,body .jsoneditor-contextmenu .jsoneditor-menu button button.jsoneditor-selected:focus,body .jsoneditor-contextmenu .jsoneditor-menu li button.jsoneditor-selected:hover,body .jsoneditor-contextmenu .jsoneditor-menu li button.jsoneditor-selected:focus{color:var(--t42-link-hover-color);background-color:var(--t42-color-opacity-10)}body .jsoneditor-contextmenu .jsoneditor-menu button{display:flex;justify-content:start}body .jsoneditor-contextmenu .jsoneditor-menu button.jsoneditor-default{float:left;z-index:1}body .jsoneditor-contextmenu .jsoneditor-menu li ul{padding:0 !important;left:0}body .jsoneditor-contextmenu .jsoneditor-menu li ul li button{padding-left:1rem}body .jsoneditor-contextmenu .jsoneditor-menu li ul .jsoneditor-icon{position:relative;margin-left:0}body .jsoneditor-contextmenu .jsoneditor-menu .jsoneditor-text{padding:0;line-height:1.5rem}body .jsoneditor-contextmenu .jsoneditor-icon{position:relative;background-image:var(--t42-json-icons)}body .jsoneditor-contextmenu .jsoneditor-separator{margin-top:0;padding-top:0}body .jsoneditor-mode-preview pre.jsoneditor-preview{border:0;line-height:1.5}body .jsoneditor-modal{border-top:0;background:linear-gradient(to bottom right, rgba(var(--t42-bg-light), 0.75) 0%, rgba(var(--t42-bg-dark), 0.75) 100%) !important;box-shadow:var(--t42-shadow) !important;backdrop-filter:var(--backdrop-filter)}body .jsoneditor-modal::before{position:absolute;top:0;right:0;left:0;display:block;width:100%;height:0.0625rem;background:linear-gradient(90deg, #007be5 0%, rgba(0,123,229,0.5) 100%);content:""}body .jsoneditor-modal .pico-modal-header{padding:0.5rem 0.988rem;background:transparent;font-size:0.75rem}body .jsoneditor-modal .pico-close{top:1rem !important;right:1rem !important;color:var(--t42-content-color-muted);transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:color}body .jsoneditor-modal .pico-close:not(.disabled):not(:disabled).active,body .jsoneditor-modal .pico-close:not(.disabled):not(:disabled):focus,body .jsoneditor-modal .pico-close:not(.disabled):not(:disabled):hover{color:var(--t42-link-color)}body .jsoneditor-modal table td{font-size:0.75rem;padding:0 0.25rem}body .jsoneditor-modal table td.jsoneditor-modal-input{padding-top:0.25rem;padding-bottom:0.25rem;text-align:left}body .jsoneditor-modal table td.jsoneditor-modal-input.jsoneditor-modal-actions{text-align:right}body .jsoneditor-modal table th{font-size:0.75rem}body .jsoneditor-modal label,body .jsoneditor-modal p{font-size:0.75rem}body .jsoneditor-modal select{min-width:12.375rem}body .jsoneditor-modal .selectr-selected{padding:0 0.857rem}body .jsoneditor-modal select,body .jsoneditor-modal textarea,body .jsoneditor-modal input,body .jsoneditor-modal input[type="text"],body .jsoneditor-modal input[type="search"],body .jsoneditor-modal #query{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border;border-color:var(--t42-color-opacity-10);border-radius:0;font-size:0.75rem;background-color:var(--t42-input-bg)}body .jsoneditor-modal select:focus,body .jsoneditor-modal textarea:focus,body .jsoneditor-modal input:focus,body .jsoneditor-modal input[type="text"]:focus,body .jsoneditor-modal input[type="search"]:focus,body .jsoneditor-modal #query:focus{border-color:var(--primary);box-shadow:none;outline:0;padding:0 0 0 .875rem;border-radius:0}body .jsoneditor-modal select:disabled,body .jsoneditor-modal select.disabled,body .jsoneditor-modal select[readonly],body .jsoneditor-modal textarea:disabled,body .jsoneditor-modal textarea.disabled,body .jsoneditor-modal textarea[readonly],body .jsoneditor-modal input:disabled,body .jsoneditor-modal input.disabled,body .jsoneditor-modal input[readonly],body .jsoneditor-modal input[type="text"]:disabled,body .jsoneditor-modal input[type="text"].disabled,body .jsoneditor-modal input[type="text"][readonly],body .jsoneditor-modal input[type="search"]:disabled,body .jsoneditor-modal input[type="search"].disabled,body .jsoneditor-modal input[type="search"][readonly],body .jsoneditor-modal #query:disabled,body .jsoneditor-modal #query.disabled,body .jsoneditor-modal #query[readonly]{cursor:default;opacity:0.65}body .jsoneditor-modal input[type="search"].selectr-input{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border-color;border:var(--t42-border);background-color:var(--t42-input-bg);margin:0;line-height:1.5rem;width:100%;padding:0 0.5rem}body .jsoneditor-modal input[type="search"].selectr-input:hover{border-color:var(--primary)}body .jsoneditor-modal .jsoneditor-select-wrapper::after{border-top:var(--t42-color-opacity-10)}body .jsoneditor-modal input[type="button"],body .jsoneditor-modal input[type="submit"]{padding:0 .875rem;border-radius:0;color:var(--t42-link-color);line-height:1.875rem;background:transparent;transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, border-color}body .jsoneditor-modal input[type="button"]:not(.disabled):not(:disabled).active,body .jsoneditor-modal input[type="button"]:not(.disabled):not(:disabled):hover,body .jsoneditor-modal input[type="submit"]:not(.disabled):not(:disabled).active,body .jsoneditor-modal input[type="submit"]:not(.disabled):not(:disabled):hover{border-color:var(--t42-color-opacity-30);color:var(--white);background:var(--primary)}body .jsoneditor-modal .jsoneditor-button-group input.jsoneditor-button-first{border-left-style:solid;border-top-left-radius:0;border-bottom-left-radius:0}body .jsoneditor-modal .jsoneditor-button-group input.jsoneditor-button-last{border-top-right-radius:0;border-bottom-right-radius:0}body .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-asc input.jsoneditor-button-asc,body .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-desc input.jsoneditor-button-desc{color:var(--white);background:var(--primary)}body .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-asc input.jsoneditor-button-asc:hover,body .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-asc input.jsoneditor-button-asc:focus,body .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-asc input.jsoneditor-button-asc:active,body .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-desc input.jsoneditor-button-desc:hover,body .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-desc input.jsoneditor-button-desc:focus,body .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-desc input.jsoneditor-button-desc:active{border-color:var(--t42-color-opacity-30);color:var(--white)}body .jsoneditor-modal .jsoneditor-jmespath-label{color:var(--t42-content-color);font-weight:400}body .jsoneditor-modal .jsoneditor-jmespath-filter-value input{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border-color;line-height:1.875rem;padding:0 0 0 .875rem;font-size:0.75rem;background-color:var(--t42-input-bg)}body .jsoneditor-modal .jsoneditor-jmespath-filter-value input:focus,body .jsoneditor-modal .jsoneditor-jmespath-filter-value input:hover{background-color:var(--t42-input-bg);border-color:var(--primary)}body .jsoneditor-jmespath-block .jsoneditor-modal-actions{text-align:right}body div.jsoneditor td.jsoneditor-tree{vertical-align:middle}body div.jsoneditor td.jsoneditor-separator{vertical-align:middle}body div.jsoneditor-tree{background:transparent}body div.jsoneditor-tree button.jsoneditor-button{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, outline-color;background-image:var(--t42-json-icons)}body div.jsoneditor-tree button.jsoneditor-button:focus{background-color:transparent;outline-color:var(--t42-color-opacity-10)}body tr.jsoneditor-selected,body tr.jsoneditor-highlight{background-color:var(--t42-color-opacity-10)}body .selectr-selected{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border-color;height:2rem;font-size:0.75rem;font-weight:400;line-height:1.875rem;background-color:var(--t42-input-bg);border-radius:0}body .selectr-selected::before{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:transform;right:0.5rem;border:0;width:0.75rem;height:0.75rem;background:var(--t42-select-indicator) center center/1rem 1rem no-repeat;transform:translateY(-50%)}body .selectr-placeholder{color:var(--t42-content-color-muted)}body .selectr-container.open .selectr-selected{border-radius:0;border-color:var(--primary)}body .selectr-container.open .selectr-selected::before{border:0;transform:rotate(180deg) translateY(50%)}body .selectr-container.open .selectr-options-container{border-left-color:var(--primary);border-right-color:var(--primary);border-bottom-color:var(--primary)}body .selectr-options{overflow-y:auto}body .selectr-options-container{min-height:2rem;border-color:var(--t42-color-opacity-10);border-style:solid;border-width:1px;background-color:Rgb(var(--t42-bg-dark))}body .selectr-options .active{color:var(--t42-link-hover-color);background-color:var(--t42-color-opacity-10)}body .selectr-options .selected{color:var(--t42-link-hover-color);background-color:var(--primary)}body .selectr-option{padding:0 0 0 0.875rem;line-height:2rem;font-size:0.75rem}body .selectr-input{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border-color;border:var(--t42-border);background-color:var(--t42-input-bg)}body .selectr-input:hover{border-color:var(--primary)}body .selectr-input-container{padding:0.25rem}body .selectr-clear::before,body .selectr-clear::after{background-color:var(--t42-content-color)}body .jsoneditor .ace-jsoneditor .ace_text-input{min-height:auto}body .jsoneditor .ace-jsoneditor.ace_editor,body .jsoneditor .ace-jsoneditor .ace_scroller{background-color:Rgb(var(--t42-bg-dark))}body .jsoneditor .ace-jsoneditor .ace_gutter{color:var(--t42-content-color-muted);background-color:Rgb(var(--t42-bg-mid))}body .jsoneditor .ace-jsoneditor .ace_gutter-active-line{background-color:Rgb(var(--t42-bg-light))}body .jsoneditor .ace-jsoneditor .ace_cursor{border-color:Rgb(var(--t42-content-color))}body .jsoneditor .ace-jsoneditor .ace_marker-layer .ace_active-line{background-color:rgba(var(--secondary), 0.25)}body .jsoneditor .ace-jsoneditor .ace_marker-layer .ace_selection{background-color:var(--t42-color-opacity-10)}body .jsoneditor .ace-jsoneditor .ace_marker-layer .ace_selected-word{border-color:var(--t42-color-opacity-10);background-color:var(--t42-color-opacity-10)}body .jsoneditor .ace-jsoneditor .ace_marker-layer .ace_bracket{border:var(--t42-border)}body .jsoneditor .ace-jsoneditor .ace_variable{color:var(--t42-content-color)}body .jsoneditor .ace-jsoneditor .ace_constant.ace_numeric{color:#ff511f}body .jsoneditor .ace-jsoneditor .ace_constant.ace_language{color:#f9a825}body .jsoneditor .ace-jsoneditor .ace_string{color:#43a047}body .jsoneditor .ace-jsoneditor .ace_fold{border-color:var(--t42-color-opacity-10);background-color:Rgb(var(--t42-bg-light));transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-image}body .jsoneditor .ace-jsoneditor .ace_fold-widget:hover,body .jsoneditor .ace-jsoneditor .ace_fold-widget:active{border-color:var(--t42-color-opacity-30);background-color:var(--t42-color-opacity-10);box-shadow:none}body .pico-modal-contents{display:block} + diff --git a/typescript/solution/portfolio-downloader/tsconfig.json b/typescript/solution/portfolio-downloader/tsconfig.json new file mode 100644 index 0000000..11ec879 --- /dev/null +++ b/typescript/solution/portfolio-downloader/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "./dist", + "rootDir": "./src" + }, + "include": ["./src", "../../types"] +} \ No newline at end of file diff --git a/typescript/solution/portfolio-downloader/webpack.config.js b/typescript/solution/portfolio-downloader/webpack.config.js new file mode 100644 index 0000000..cf31d79 --- /dev/null +++ b/typescript/solution/portfolio-downloader/webpack.config.js @@ -0,0 +1,31 @@ +const path = require('path'); +const CopyWebpackPlugin = require('copy-webpack-plugin'); + +module.exports = { + mode: 'development', + entry: './src/index.ts', + module: { + rules: [ + { + test: /\.tsx?$/, + use: 'ts-loader', + exclude: /node_modules/, + }, + ], + }, + resolve: { + extensions: ['.tsx', '.ts', '.js'], + }, + output: { + filename: 'index.js', + path: path.resolve(__dirname, 'dist'), + }, + plugins: [ + new CopyWebpackPlugin({ + patterns: [ + { from: 'src/index.html', to: 'index.html' }, + { from: 'src/lib', to: 'lib' } + ], + }), + ], +}; \ No newline at end of file diff --git a/typescript/solution/stocks/esbuild.js b/typescript/solution/stocks/esbuild.js new file mode 100644 index 0000000..27c80dc --- /dev/null +++ b/typescript/solution/stocks/esbuild.js @@ -0,0 +1,48 @@ +const fs = require('fs'); +const path = require('path'); +const { build } = require('esbuild'); + +// Directory paths +const srcDir = path.join(__dirname, 'src'); +const distDir = path.join(__dirname, 'dist'); + +// Ensure dist directory exists +if (!fs.existsSync(distDir)) { + fs.mkdirSync(distDir, { recursive: true }); +} + +// Copy HTML file +fs.copyFileSync( + path.join(srcDir, 'index.html'), + path.join(distDir, 'index.html') +); + +// Copy lib directory +const libSrcDir = path.join(srcDir, 'lib'); +const libDistDir = path.join(distDir, 'lib'); + +if (!fs.existsSync(libDistDir)) { + fs.mkdirSync(libDistDir, { recursive: true }); +} + +fs.readdirSync(libSrcDir).forEach(file => { + fs.copyFileSync( + path.join(libSrcDir, file), + path.join(libDistDir, file) + ); +}); + +// Build with esbuild +build({ + entryPoints: [path.join(srcDir, 'index.ts')], + bundle: true, + outfile: path.join(distDir, 'index.js'), + platform: 'browser', + format: 'iife', + sourcemap: true, + target: ['es2020'], + tsconfig: path.join(__dirname, 'tsconfig.json'), +}).catch((error) => { + console.error(error); + process.exit(1); +}); \ No newline at end of file diff --git a/typescript/solution/stocks/src/index.html b/typescript/solution/stocks/src/index.html new file mode 100644 index 0000000..2b996d6 --- /dev/null +++ b/typescript/solution/stocks/src/index.html @@ -0,0 +1,58 @@ + + + + + + + + + + + + Stocks + + + + + + + + + + + + + +
+
+
+
+ io.Connect is unavailable +
+ +
+ +
+
+
+

Stocks

+
+
+
+ + + + + + + + + + + +
SymbolDescriptionBidAsk
+
+
+ + + diff --git a/typescript/solution/stocks/src/index.ts b/typescript/solution/stocks/src/index.ts new file mode 100644 index 0000000..59ba4f9 --- /dev/null +++ b/typescript/solution/stocks/src/index.ts @@ -0,0 +1,285 @@ +let clientPortfolioStocks: Stock[] | undefined; +let clientName: string | undefined; + +interface PriceUpdate { + stocks: { + RIC: string; + Bid: string; + Ask: string; + }[]; +} + +interface StockWithPrices extends Stock { + Bid?: string; + Ask?: string; + Description?: string; +} + +const generateStockPrices = (handleNewPrices: (update: PriceUpdate) => void): void => { + setInterval(() => { + const priceUpdate: PriceUpdate = { + stocks: [ + { + RIC: "VOD.L", + Bid: Number(70 - Math.random() * 10).toFixed(2), + Ask: Number(70 + Math.random() * 10).toFixed(2) + }, + { + RIC: "TSCO.L", + Bid: Number(90 - Math.random() * 10).toFixed(2), + Ask: Number(90 + Math.random() * 10).toFixed(2) + }, + { + RIC: "BARC.L", + Bid: Number(105 - Math.random() * 10).toFixed(2), + Ask: Number(105 + Math.random() * 10).toFixed(2) + }, + { + RIC: "BMWG.DE", + Bid: Number(29 - Math.random() * 10).toFixed(2), + Ask: Number(29 + Math.random() * 10).toFixed(2) + }, + { + RIC: "AAL.L", + Bid: Number(46 - Math.random() * 10).toFixed(2), + Ask: Number(46 + Math.random() * 10).toFixed(2) + }, + { + RIC: "IBM.N", + Bid: Number(70 - Math.random() * 10).toFixed(2), + Ask: Number(70 + Math.random() * 10).toFixed(2) + }, + { + RIC: "AAPL.OQ", + Bid: Number(90 - Math.random() * 10).toFixed(2), + Ask: Number(90 + Math.random() * 10).toFixed(2) + }, + { + RIC: "BA.N", + Bid: Number(105 - Math.random() * 10).toFixed(2), + Ask: Number(105 + Math.random() * 10).toFixed(2) + }, + { + RIC: "TSLA:OQ", + Bid: Number(29 - Math.random() * 10).toFixed(2), + Ask: Number(29 + Math.random() * 10).toFixed(2) + }, + { + RIC: "ENBD.DU", + Bid: Number(46 - Math.random() * 10).toFixed(2), + Ask: Number(46 + Math.random() * 10).toFixed(2) + }, + { + RIC: "AMZN.OQ", + Bid: Number(29 - Math.random() * 10).toFixed(2), + Ask: Number(29 + Math.random() * 10).toFixed(2) + }, + { + RIC: "MSFT:OQ", + Bid: Number(46 - Math.random() * 10).toFixed(2), + Ask: Number(46 + Math.random() * 10).toFixed(2) + } + ] + }; + + handleNewPrices(priceUpdate); + }, 1500); +}; + +const setupStocks = (stocks: StockWithPrices[]): void => { + const tableElement = document.getElementById("stocksTable"); + if (!tableElement) return; + + const table = tableElement.getElementsByTagName("tbody")[0]; + if (!table) return; + + table.innerHTML = ""; + + const addRowCell = (row: HTMLTableRowElement, cellData: string, cssClass?: string): void => { + const cell = document.createElement("td"); + + cell.innerText = cellData; + + if (cssClass) { + cell.className = cssClass; + } + row.appendChild(cell); + }; + + const addRow = (table: HTMLTableSectionElement, stock: StockWithPrices): void => { + const row = document.createElement("tr"); + + addRowCell(row, stock.RIC || ""); + addRowCell(row, stock.Description || ""); + addRowCell(row, stock.Bid || ""); + addRowCell(row, stock.Ask || ""); + + row.setAttribute("data-ric", stock.RIC); + + row.onclick = () => { + stockClickedHandler(stock); + }; + + table.appendChild(row); + }; + + stocks.forEach((stock) => { + addRow(table, stock); + }); +}; + +// TODO: Chapter 3 +const toggleIOAvailable = (): void => { + const span = document.getElementById("ioConnectSpan"); + if (!span) return; + + span.classList.remove("bg-danger"); + span.classList.add("bg-success"); + span.textContent = "io.Connect is available"; +}; + +const newPricesHandler = (priceUpdate: PriceUpdate): void => { + priceUpdate.stocks.forEach((stock) => { + const row = document.querySelectorAll(`[data-ric="${stock.RIC}"]`)[0] as HTMLTableRowElement; + + if (!row) { + return; + } + + const bidElement = row.children[2]; + if (bidElement) bidElement.textContent = stock.Bid; + + const askElement = row.children[3]; + if (askElement) askElement.textContent = stock.Ask; + }); + + // TODO: Chapter 5.1 + if (window.priceStream) { + window.priceStream.push(priceUpdate); + } +}; + +const stockClickedHandler = async (stock: StockWithPrices): Promise => { + // TODO: Chapter 9.5 + let detailsWindow; + + const myWorkspace = await window.io.workspaces.getMyWorkspace(); + + // Using any here since the API is not fully typed + let detailsWorkspaceWindow = (myWorkspace as any).getWindow((window: any) => window.appName === "stock-details"); + + if (detailsWorkspaceWindow) { + detailsWindow = detailsWorkspaceWindow.getGdWindow(); + } else { + const myId = (window.io.windows as any).my().id; + const myImmediateParent = myWorkspace.getWindow((window: any) => window.id === myId).parent; + const group = await myImmediateParent.parent.addGroup(); + + detailsWorkspaceWindow = await group.addWindow({ appName: "stock-details" }); + + await detailsWorkspaceWindow.forceLoad(); + + detailsWindow = detailsWorkspaceWindow.getGdWindow(); + } + + detailsWindow.updateContext({ stock }); +}; + +const exportPortfolioButtonHandler = async (portfolio: Stock[]): Promise => { + // TODO: Chapter 10.2 + try { + const intents = await (window.io.intents as any).find("ExportPortfolio"); + + if (!intents) { + return; + } + + const intentRequest = { + intent: "ExportPortfolio", + context: { + type: "ClientPortfolio", + data: { portfolio, clientName } + } + }; + + await (window.io.intents as any).raise(intentRequest); + + } catch (error) { + console.error((error as Error).message); + } +}; + +const start = async (): Promise => { + const html = document.documentElement; + const initialTheme = iodesktop.theme; + + html.className = initialTheme; + + const stocksResponse = await fetch("http://localhost:8080/api/portfolio"); + const stocks = await stocksResponse.json() as StockWithPrices[]; + + setupStocks(stocks); + generateStockPrices(newPricesHandler); + + // TODO: Chapter 3 + const config = { + // channels: true, + // appManager: "full", + libraries: [IOWorkspaces] + }; + + const io = await IODesktop(config); + + window.io = io; + + toggleIOAvailable(); + + // TODO: Chapter 12.1 + const themeHandler = (newTheme: Theme): void => { + html.className = newTheme.name; + }; + + io.themes.onChanged(themeHandler); + + // TODO: Chapter 5.1 + window.priceStream = await (io.interop as any).createStream("LivePrices"); + + // TODO: Chapter 9.4 + const myWorkspace = await io.workspaces.getMyWorkspace(); + + if (myWorkspace) { + const updateHandler = (context: any): void => { + if (context.client) { + const clientPortfolio = context.client.portfolio; + clientPortfolioStocks = stocks.filter((stock) => clientPortfolio.includes(stock.RIC)); + clientName = context.client.name; + + setupStocks(clientPortfolioStocks); + } + }; + + myWorkspace.onContextUpdated(updateHandler); + } + + // TODO: Chapter 10.2 + const exportPortfolioButton = document.getElementById("exportPortfolio"); + if (!exportPortfolioButton) return; + + exportPortfolioButton.onclick = () => { + if (!clientPortfolioStocks) { + return; + } + + exportPortfolioButtonHandler(clientPortfolioStocks).catch(console.error); + }; +}; + +// Add extended properties to window object +declare global { + interface Window { + io: IODesktopAPI; + priceStream: any; + } +} + +start().catch(console.error); \ No newline at end of file diff --git a/typescript/solution/stocks/src/lib/desktop.umd.js b/typescript/solution/stocks/src/lib/desktop.umd.js new file mode 100644 index 0000000..6cea2c9 --- /dev/null +++ b/typescript/solution/stocks/src/lib/desktop.umd.js @@ -0,0 +1,23144 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define(factory) : + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.desktop = factory()); +})(this, (function () { 'use strict'; + + var MetricTypes = { + STRING: 1, + NUMBER: 2, + TIMESTAMP: 3, + OBJECT: 4 + }; + + function getMetricTypeByValue(metric) { + if (metric.type === MetricTypes.TIMESTAMP) { + return "timestamp"; + } + else if (metric.type === MetricTypes.NUMBER) { + return "number"; + } + else if (metric.type === MetricTypes.STRING) { + return "string"; + } + else if (metric.type === MetricTypes.OBJECT) { + return "object"; + } + return "unknown"; + } + function getTypeByValue(value) { + if (value.constructor === Date) { + return "timestamp"; + } + else if (typeof value === "number") { + return "number"; + } + else if (typeof value === "string") { + return "string"; + } + else if (typeof value === "object") { + return "object"; + } + else { + return "string"; + } + } + function serializeMetric(metric) { + const serializedMetrics = {}; + const type = getMetricTypeByValue(metric); + if (type === "object") { + const values = Object.keys(metric.value).reduce((memo, key) => { + const innerType = getTypeByValue(metric.value[key]); + if (innerType === "object") { + const composite = defineNestedComposite(metric.value[key]); + memo[key] = { + type: "object", + description: "", + context: {}, + composite, + }; + } + else { + memo[key] = { + type: innerType, + description: "", + context: {}, + }; + } + return memo; + }, {}); + serializedMetrics.composite = values; + } + serializedMetrics.name = normalizeMetricName(metric.path.join("/") + "/" + metric.name); + serializedMetrics.type = type; + serializedMetrics.description = metric.description; + serializedMetrics.context = {}; + return serializedMetrics; + } + function defineNestedComposite(values) { + return Object.keys(values).reduce((memo, key) => { + const type = getTypeByValue(values[key]); + if (type === "object") { + memo[key] = { + type: "object", + description: "", + context: {}, + composite: defineNestedComposite(values[key]), + }; + } + else { + memo[key] = { + type, + description: "", + context: {}, + }; + } + return memo; + }, {}); + } + function normalizeMetricName(name) { + if (typeof name !== "undefined" && name.length > 0 && name[0] !== "/") { + return "/" + name; + } + else { + return name; + } + } + function getMetricValueByType(metric) { + const type = getMetricTypeByValue(metric); + if (type === "timestamp") { + return Date.now(); + } + else { + return publishNestedComposite(metric.value); + } + } + function publishNestedComposite(values) { + if (typeof values !== "object") { + return values; + } + return Object.keys(values).reduce((memo, key) => { + const value = values[key]; + if (typeof value === "object" && value.constructor !== Date) { + memo[key] = publishNestedComposite(value); + } + else if (value.constructor === Date) { + memo[key] = new Date(value).getTime(); + } + else if (value.constructor === Boolean) { + memo[key] = value.toString(); + } + else { + memo[key] = value; + } + return memo; + }, {}); + } + function flatten(arr) { + return arr.reduce((flat, toFlatten) => { + return flat.concat(Array.isArray(toFlatten) ? flatten(toFlatten) : toFlatten); + }, []); + } + function getHighestState(arr) { + return arr.sort((a, b) => { + if (!a.state) { + return 1; + } + if (!b.state) { + return -1; + } + return b.state - a.state; + })[0]; + } + function aggregateDescription(arr) { + let msg = ""; + arr.forEach((m, idx, a) => { + const path = m.path.join("."); + if (idx === a.length - 1) { + msg += path + "." + m.name + ": " + m.description; + } + else { + msg += path + "." + m.name + ": " + m.description + ","; + } + }); + if (msg.length > 100) { + return msg.slice(0, 100) + "..."; + } + else { + return msg; + } + } + function composeMsgForRootStateMetric(system) { + const aggregatedState = system.root.getAggregateState(); + const merged = flatten(aggregatedState); + const highestState = getHighestState(merged); + const aggregateDesc = aggregateDescription(merged); + return { + description: aggregateDesc, + value: highestState.state, + }; + } + + function gw3 (connection, config) { + if (!connection || typeof connection !== "object") { + throw new Error("Connection is required parameter"); + } + let joinPromise; + let session; + const init = (repo) => { + let resolveReadyPromise; + joinPromise = new Promise((resolve) => { + resolveReadyPromise = resolve; + }); + session = connection.domain("metrics"); + session.onJoined((reconnect) => { + if (!reconnect && resolveReadyPromise) { + resolveReadyPromise(); + resolveReadyPromise = undefined; + } + const rootStateMetric = { + name: "/State", + type: "object", + composite: { + Description: { + type: "string", + description: "", + }, + Value: { + type: "number", + description: "", + }, + }, + description: "System state", + context: {}, + }; + const defineRootMetricsMsg = { + type: "define", + metrics: [rootStateMetric], + }; + session.send(defineRootMetricsMsg); + if (reconnect) { + replayRepo(repo); + } + }); + session.join({ + system: config.system, + service: config.service, + instance: config.instance + }); + }; + const replayRepo = (repo) => { + replaySystem(repo.root); + }; + const replaySystem = (system) => { + createSystem(system); + system.metrics.forEach((m) => { + createMetric(m); + }); + system.subSystems.forEach((ss) => { + replaySystem(ss); + }); + }; + const createSystem = async (system) => { + if (system.parent === undefined) { + return; + } + await joinPromise; + const metric = { + name: normalizeMetricName(system.path.join("/") + "/" + system.name + "/State"), + type: "object", + composite: { + Description: { + type: "string", + description: "", + }, + Value: { + type: "number", + description: "", + }, + }, + description: "System state", + context: {}, + }; + const createMetricsMsg = { + type: "define", + metrics: [metric], + }; + session.send(createMetricsMsg); + }; + const updateSystem = async (system, state) => { + await joinPromise; + const shadowedUpdateMetric = { + type: "publish", + values: [{ + name: normalizeMetricName(system.path.join("/") + "/" + system.name + "/State"), + value: { + Description: state.description, + Value: state.state, + }, + timestamp: Date.now(), + }], + }; + session.send(shadowedUpdateMetric); + const stateObj = composeMsgForRootStateMetric(system); + const rootMetric = { + type: "publish", + peer_id: connection.peerId, + values: [{ + name: "/State", + value: { + Description: stateObj.description, + Value: stateObj.value, + }, + timestamp: Date.now(), + }], + }; + session.send(rootMetric); + }; + const createMetric = async (metric) => { + const metricClone = cloneMetric(metric); + await joinPromise; + const m = serializeMetric(metricClone); + const createMetricsMsg = { + type: "define", + metrics: [m], + }; + session.send(createMetricsMsg); + if (typeof metricClone.value !== "undefined") { + updateMetricCore(metricClone); + } + }; + const updateMetric = async (metric) => { + const metricClone = cloneMetric(metric); + await joinPromise; + updateMetricCore(metricClone); + }; + const updateMetricCore = (metric) => { + if (canUpdate()) { + const value = getMetricValueByType(metric); + const publishMetricsMsg = { + type: "publish", + values: [{ + name: normalizeMetricName(metric.path.join("/") + "/" + metric.name), + value, + timestamp: Date.now(), + }], + }; + return session.sendFireAndForget(publishMetricsMsg); + } + return Promise.resolve(); + }; + const cloneMetric = (metric) => { + const metricClone = { ...metric }; + if (typeof metric.value === "object" && metric.value !== null) { + metricClone.value = { ...metric.value }; + } + return metricClone; + }; + const canUpdate = () => { + try { + const func = config.canUpdateMetric ?? (() => true); + return func(); + } + catch { + return true; + } + }; + return { + init, + createSystem, + updateSystem, + createMetric, + updateMetric, + }; + } + + var Helpers = { + validate: (definition, parent, transport) => { + if (definition === null || typeof definition !== "object") { + throw new Error("Missing definition"); + } + if (parent === null || typeof parent !== "object") { + throw new Error("Missing parent"); + } + if (transport === null || typeof transport !== "object") { + throw new Error("Missing transport"); + } + }, + }; + + class BaseMetric { + definition; + system; + transport; + value; + type; + path = []; + name; + description; + get repo() { + return this.system?.repo; + } + get id() { return `${this.system.path}/${name}`; } + constructor(definition, system, transport, value, type) { + this.definition = definition; + this.system = system; + this.transport = transport; + this.value = value; + this.type = type; + Helpers.validate(definition, system, transport); + this.path = system.path.slice(0); + this.path.push(system.name); + this.name = definition.name; + this.description = definition.description; + transport.createMetric(this); + } + update(newValue) { + this.value = newValue; + return this.transport.updateMetric(this); + } + } + + class NumberMetric extends BaseMetric { + constructor(definition, system, transport, value) { + super(definition, system, transport, value, MetricTypes.NUMBER); + } + incrementBy(num) { + this.update(this.value + num); + } + increment() { + this.incrementBy(1); + } + decrement() { + this.incrementBy(-1); + } + decrementBy(num) { + this.incrementBy(num * -1); + } + } + + class ObjectMetric extends BaseMetric { + constructor(definition, system, transport, value) { + super(definition, system, transport, value, MetricTypes.OBJECT); + } + update(newValue) { + this.mergeValues(newValue); + return this.transport.updateMetric(this); + } + mergeValues(values) { + return Object.keys(this.value).forEach((k) => { + if (typeof values[k] !== "undefined") { + this.value[k] = values[k]; + } + }); + } + } + + class StringMetric extends BaseMetric { + constructor(definition, system, transport, value) { + super(definition, system, transport, value, MetricTypes.STRING); + } + } + + class TimestampMetric extends BaseMetric { + constructor(definition, system, transport, value) { + super(definition, system, transport, value, MetricTypes.TIMESTAMP); + } + now() { + this.update(new Date()); + } + } + + function system$1(name, repo, protocol, parent, description) { + if (!repo) { + throw new Error("Repository is required"); + } + if (!protocol) { + throw new Error("Transport is required"); + } + const _transport = protocol; + const _name = name; + const _description = description || ""; + const _repo = repo; + const _parent = parent; + const _path = _buildPath(parent); + let _state = {}; + const id = _arrayToString(_path, "/") + name; + const root = repo.root; + const _subSystems = []; + const _metrics = []; + function subSystem(nameSystem, descriptionSystem) { + if (!nameSystem || nameSystem.length === 0) { + throw new Error("name is required"); + } + const match = _subSystems.filter((s) => s.name === nameSystem); + if (match.length > 0) { + return match[0]; + } + const _system = system$1(nameSystem, _repo, _transport, me, descriptionSystem); + _subSystems.push(_system); + return _system; + } + function setState(state, stateDescription) { + _state = { state, description: stateDescription }; + _transport.updateSystem(me, _state); + } + function stringMetric(definition, value) { + return _getOrCreateMetric(definition, MetricTypes.STRING, value, (metricDef) => new StringMetric(metricDef, me, _transport, value)); + } + function numberMetric(definition, value) { + return _getOrCreateMetric(definition, MetricTypes.NUMBER, value, (metricDef) => new NumberMetric(metricDef, me, _transport, value)); + } + function objectMetric(definition, value) { + return _getOrCreateMetric(definition, MetricTypes.OBJECT, value, (metricDef) => new ObjectMetric(metricDef, me, _transport, value)); + } + function timestampMetric(definition, value) { + return _getOrCreateMetric(definition, MetricTypes.TIMESTAMP, value, (metricDef) => new TimestampMetric(metricDef, me, _transport, value)); + } + function _getOrCreateMetric(metricObject, expectedType, value, createMetric) { + let metricDef = { name: "" }; + if (typeof metricObject === "string") { + metricDef = { name: metricObject }; + } + else { + metricDef = metricObject; + } + const matching = _metrics.filter((shadowedMetric) => shadowedMetric.name === metricDef.name); + if (matching.length > 0) { + const existing = matching[0]; + if (existing.type !== expectedType) { + throw new Error(`A metric named ${metricDef.name} is already defined with different type.`); + } + if (typeof value !== "undefined") { + existing + .update(value) + .catch(() => { }); + } + return existing; + } + const metric = createMetric(metricDef); + _metrics.push(metric); + return metric; + } + function _buildPath(shadowedSystem) { + if (!shadowedSystem || !shadowedSystem.parent) { + return []; + } + const path = _buildPath(shadowedSystem.parent); + path.push(shadowedSystem.name); + return path; + } + function _arrayToString(path, separator) { + return ((path && path.length > 0) ? path.join(separator) : ""); + } + function getAggregateState() { + const aggState = []; + if (Object.keys(_state).length > 0) { + aggState.push({ + name: _name, + path: _path, + state: _state.state, + description: _state.description, + }); + } + _subSystems.forEach((shadowedSubSystem) => { + const result = shadowedSubSystem.getAggregateState(); + if (result.length > 0) { + aggState.push(...result); + } + }); + return aggState; + } + const me = { + get name() { + return _name; + }, + get description() { + return _description; + }, + get repo() { + return _repo; + }, + get parent() { + return _parent; + }, + path: _path, + id, + root, + get subSystems() { + return _subSystems; + }, + get metrics() { + return _metrics; + }, + subSystem, + getState: () => { + return _state; + }, + setState, + stringMetric, + timestampMetric, + objectMetric, + numberMetric, + getAggregateState, + }; + _transport.createSystem(me); + return me; + } + + class Repository { + root; + constructor(options, protocol) { + protocol.init(this); + this.root = system$1("", this, protocol); + this.addSystemMetrics(this.root, options.clickStream || options.clickStream === undefined); + } + addSystemMetrics(rootSystem, useClickStream) { + if (typeof navigator !== "undefined") { + rootSystem.stringMetric("UserAgent", navigator.userAgent); + } + if (useClickStream && typeof document !== "undefined") { + const clickStream = rootSystem.subSystem("ClickStream"); + const documentClickHandler = (e) => { + if (!e.target) { + return; + } + const target = e.target; + const className = target ? target.getAttribute("class") ?? "" : ""; + clickStream.objectMetric("LastBrowserEvent", { + type: "click", + timestamp: new Date(), + target: { + className, + id: target.id, + type: "<" + target.tagName.toLowerCase() + ">", + href: target.href || "", + }, + }); + }; + clickStream.objectMetric("Page", { + title: document.title, + page: window.location.href, + }); + if (document.addEventListener) { + document.addEventListener("click", documentClickHandler); + } + else { + document.attachEvent("onclick", documentClickHandler); + } + } + rootSystem.stringMetric("StartTime", (new Date()).toString()); + const urlMetric = rootSystem.stringMetric("StartURL", ""); + const appNameMetric = rootSystem.stringMetric("AppName", ""); + if (typeof window !== "undefined") { + if (typeof window.location !== "undefined") { + const startUrl = window.location.href; + urlMetric.update(startUrl); + } + if (typeof window.glue42gd !== "undefined") { + appNameMetric.update(window.glue42gd.appName); + } + } + } + } + + class NullProtocol { + init(repo) { + } + createSystem(system) { + return Promise.resolve(); + } + updateSystem(metric, state) { + return Promise.resolve(); + } + createMetric(metric) { + return Promise.resolve(); + } + updateMetric(metric) { + return Promise.resolve(); + } + } + + class PerfTracker { + api; + lastCount = 0; + initialPublishTimeout = 10 * 1000; + publishInterval = 60 * 1000; + system; + constructor(api, initialPublishTimeout, publishInterval) { + this.api = api; + this.initialPublishTimeout = initialPublishTimeout ?? this.initialPublishTimeout; + this.publishInterval = publishInterval ?? this.publishInterval; + this.scheduleCollection(); + this.system = this.api.subSystem("performance", "Performance data published by the web application"); + } + scheduleCollection() { + setTimeout(() => { + this.collect(); + setInterval(() => { + this.collect(); + }, this.publishInterval); + }, this.initialPublishTimeout); + } + collect() { + try { + this.collectMemory(); + this.collectEntries(); + } + catch { + } + } + collectMemory() { + const memory = window.performance.memory; + this.system.stringMetric("memory", JSON.stringify({ + totalJSHeapSize: memory.totalJSHeapSize, + usedJSHeapSize: memory.usedJSHeapSize + })); + } + collectEntries() { + const allEntries = window.performance.getEntries(); + if (allEntries.length <= this.lastCount) { + return; + } + this.lastCount = allEntries.length; + const jsonfiedEntries = allEntries.map((i) => i.toJSON()); + this.system.stringMetric("entries", JSON.stringify(jsonfiedEntries)); + } + } + + var metrics = (options) => { + let protocol; + if (!options.connection || typeof options.connection !== "object") { + protocol = new NullProtocol(); + } + else { + protocol = gw3(options.connection, options); + } + const repo = new Repository(options, protocol); + let rootSystem = repo.root; + if (!options.disableAutoAppSystem) { + rootSystem = rootSystem.subSystem("App"); + } + const api = addFAVSupport(rootSystem); + initPerf(api, options.pagePerformanceMetrics); + return api; + }; + function initPerf(api, config) { + if (typeof window === "undefined") { + return; + } + const perfConfig = window?.glue42gd?.metrics?.pagePerformanceMetrics; + if (perfConfig) { + config = perfConfig; + } + if (config?.enabled) { + new PerfTracker(api, config.initialPublishTimeout, config.publishInterval); + } + } + function addFAVSupport(system) { + const reportingSystem = system.subSystem("reporting"); + const def = { + name: "features" + }; + let featureMetric; + const featureMetricFunc = (name, action, payload) => { + if (typeof name === "undefined" || name === "") { + throw new Error("name is mandatory"); + } + else if (typeof action === "undefined" || action === "") { + throw new Error("action is mandatory"); + } + else if (typeof payload === "undefined" || payload === "") { + throw new Error("payload is mandatory"); + } + if (!featureMetric) { + featureMetric = reportingSystem.objectMetric(def, { name, action, payload }); + } + else { + featureMetric.update({ + name, + action, + payload + }); + } + }; + system.featureMetric = featureMetricFunc; + return system; + } + + var commonjsGlobal$1 = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; + + function getDefaultExportFromCjs$1 (x) { + return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; + } + + function createRegistry$1(options) { + if (options && options.errorHandling + && typeof options.errorHandling !== "function" + && options.errorHandling !== "log" + && options.errorHandling !== "silent" + && options.errorHandling !== "throw") { + throw new Error("Invalid options passed to createRegistry. Prop errorHandling should be [\"log\" | \"silent\" | \"throw\" | (err) => void], but " + typeof options.errorHandling + " was passed"); + } + var _userErrorHandler = options && typeof options.errorHandling === "function" && options.errorHandling; + var callbacks = {}; + function add(key, callback, replayArgumentsArr) { + var callbacksForKey = callbacks[key]; + if (!callbacksForKey) { + callbacksForKey = []; + callbacks[key] = callbacksForKey; + } + callbacksForKey.push(callback); + if (replayArgumentsArr) { + setTimeout(function () { + replayArgumentsArr.forEach(function (replayArgument) { + var _a; + if ((_a = callbacks[key]) === null || _a === void 0 ? void 0 : _a.includes(callback)) { + try { + if (Array.isArray(replayArgument)) { + callback.apply(undefined, replayArgument); + } + else { + callback.apply(undefined, [replayArgument]); + } + } + catch (err) { + _handleError(err, key); + } + } + }); + }, 0); + } + return function () { + var allForKey = callbacks[key]; + if (!allForKey) { + return; + } + allForKey = allForKey.reduce(function (acc, element, index) { + if (!(element === callback && acc.length === index)) { + acc.push(element); + } + return acc; + }, []); + if (allForKey.length === 0) { + delete callbacks[key]; + } + else { + callbacks[key] = allForKey; + } + }; + } + function execute(key) { + var argumentsArr = []; + for (var _i = 1; _i < arguments.length; _i++) { + argumentsArr[_i - 1] = arguments[_i]; + } + var callbacksForKey = callbacks[key]; + if (!callbacksForKey || callbacksForKey.length === 0) { + return []; + } + var results = []; + callbacksForKey.forEach(function (callback) { + try { + var result = callback.apply(undefined, argumentsArr); + results.push(result); + } + catch (err) { + results.push(undefined); + _handleError(err, key); + } + }); + return results; + } + function _handleError(exceptionArtifact, key) { + var errParam = exceptionArtifact instanceof Error ? exceptionArtifact : new Error(exceptionArtifact); + if (_userErrorHandler) { + _userErrorHandler(errParam); + return; + } + var msg = "[ERROR] callback-registry: User callback for key \"" + key + "\" failed: " + errParam.stack; + if (options) { + switch (options.errorHandling) { + case "log": + return console.error(msg); + case "silent": + return; + case "throw": + throw new Error(msg); + } + } + console.error(msg); + } + function clear() { + callbacks = {}; + } + function clearKey(key) { + var callbacksForKey = callbacks[key]; + if (!callbacksForKey) { + return; + } + delete callbacks[key]; + } + return { + add: add, + execute: execute, + clear: clear, + clearKey: clearKey + }; + } + createRegistry$1.default = createRegistry$1; + var lib$1 = createRegistry$1; + + + var CallbackRegistryFactory$1 = /*@__PURE__*/getDefaultExportFromCjs$1(lib$1); + + class InProcTransport { + gw; + registry = CallbackRegistryFactory$1(); + client; + constructor(settings, logger) { + this.gw = settings.facade; + this.gw.connect((_client, message) => { + this.messageHandler(message); + }).then((client) => { + this.client = client; + }); + } + get isObjectBasedTransport() { + return true; + } + sendObject(msg) { + if (this.client) { + this.client.send(msg); + return Promise.resolve(undefined); + } + else { + return Promise.reject(`not connected`); + } + } + send(_msg) { + return Promise.reject("not supported"); + } + onMessage(callback) { + return this.registry.add("onMessage", callback); + } + onConnectedChanged(callback) { + callback(true); + return () => { }; + } + close() { + return Promise.resolve(); + } + open() { + return Promise.resolve(); + } + name() { + return "in-memory"; + } + reconnect() { + return Promise.resolve(); + } + messageHandler(msg) { + this.registry.execute("onMessage", msg); + } + } + + class SharedWorkerTransport { + logger; + worker; + registry = CallbackRegistryFactory$1(); + constructor(workerFile, logger) { + this.logger = logger; + this.worker = new SharedWorker(workerFile); + this.worker.port.onmessage = (e) => { + this.messageHandler(e.data); + }; + } + get isObjectBasedTransport() { + return true; + } + sendObject(msg) { + this.worker.port.postMessage(msg); + return Promise.resolve(); + } + send(_msg) { + return Promise.reject("not supported"); + } + onMessage(callback) { + return this.registry.add("onMessage", callback); + } + onConnectedChanged(callback) { + callback(true); + return () => { }; + } + close() { + return Promise.resolve(); + } + open() { + return Promise.resolve(); + } + name() { + return "shared-worker"; + } + reconnect() { + return Promise.resolve(); + } + messageHandler(msg) { + this.registry.execute("onMessage", msg); + } + } + + let Utils$1 = class Utils { + static isNode() { + if (typeof Utils._isNode !== "undefined") { + return Utils._isNode; + } + if (typeof window !== "undefined") { + Utils._isNode = false; + return false; + } + try { + Utils._isNode = Object.prototype.toString.call(global.process) === "[object process]"; + } + catch (e) { + Utils._isNode = false; + } + return Utils._isNode; + } + static _isNode; + }; + + let PromiseWrapper$1 = class PromiseWrapper { + static delay(time) { + return new Promise((resolve) => setTimeout(resolve, time)); + } + resolve; + reject; + promise; + rejected = false; + resolved = false; + get ended() { + return this.rejected || this.resolved; + } + constructor() { + this.promise = new Promise((resolve, reject) => { + this.resolve = (t) => { + this.resolved = true; + resolve(t); + }; + this.reject = (err) => { + this.rejected = true; + reject(err); + }; + }); + } + }; + + const timers = {}; + function getAllTimers() { + return timers; + } + function timer (timerName) { + const existing = timers[timerName]; + if (existing) { + return existing; + } + const marks = []; + function now() { + return new Date().getTime(); + } + const startTime = now(); + mark("start", startTime); + let endTime; + let period; + function stop() { + endTime = now(); + mark("end", endTime); + period = endTime - startTime; + return period; + } + function mark(name, time) { + const currentTime = time ?? now(); + let diff = 0; + if (marks.length > 0) { + diff = currentTime - marks[marks.length - 1].time; + } + marks.push({ name, time: currentTime, diff }); + } + const timerObj = { + get startTime() { + return startTime; + }, + get endTime() { + return endTime; + }, + get period() { + return period; + }, + stop, + mark, + marks + }; + timers[timerName] = timerObj; + return timerObj; + } + + const WebSocketConstructor = Utils$1.isNode() ? require("ws") : window.WebSocket; + class WS { + ws; + logger; + settings; + startupTimer = timer("connection"); + _running = true; + _registry = CallbackRegistryFactory$1(); + wsRequests = []; + constructor(settings, logger) { + this.settings = settings; + this.logger = logger; + if (!this.settings.ws) { + throw new Error("ws is missing"); + } + } + onMessage(callback) { + return this._registry.add("onMessage", callback); + } + send(msg, options) { + return new Promise((resolve, reject) => { + this.waitForSocketConnection(() => { + try { + this.ws?.send(msg); + resolve(); + } + catch (e) { + reject(e); + } + }, reject); + }); + } + open() { + this.logger.info("opening ws..."); + this._running = true; + return new Promise((resolve, reject) => { + this.waitForSocketConnection(resolve, reject); + }); + } + close() { + this._running = false; + if (this.ws) { + this.ws.close(); + } + return Promise.resolve(); + } + onConnectedChanged(callback) { + return this._registry.add("onConnectedChanged", callback); + } + name() { + return this.settings.ws; + } + reconnect() { + this.ws?.close(); + const pw = new PromiseWrapper$1(); + this.waitForSocketConnection(() => { + pw.resolve(); + }); + return pw.promise; + } + waitForSocketConnection(callback, failed) { + failed = failed ?? (() => { }); + if (!this._running) { + failed(`wait for socket on ${this.settings.ws} failed - socket closed by user`); + return; + } + if (this.ws?.readyState === 1) { + callback(); + return; + } + this.wsRequests.push({ callback, failed }); + if (this.wsRequests.length > 1) { + return; + } + this.openSocket(); + } + async openSocket(retryInterval, retriesLeft) { + this.logger.info(`opening ws to ${this.settings.ws}, retryInterval: ${retryInterval}, retriesLeft: ${retriesLeft}...`); + this.startupTimer.mark("opening-socket"); + if (retryInterval === undefined) { + retryInterval = this.settings.reconnectInterval; + } + if (typeof retriesLeft === "undefined") { + retriesLeft = this.settings.reconnectAttempts; + } + if (retriesLeft !== undefined) { + if (retriesLeft === 0) { + this.notifyForSocketState(`wait for socket on ${this.settings.ws} failed - no more retries left`); + return; + } + this.logger.debug(`will retry ${retriesLeft} more times (every ${retryInterval} ms)`); + } + try { + await this.initiateSocket(); + this.startupTimer.mark("socket-initiated"); + this.notifyForSocketState(); + } + catch { + setTimeout(() => { + const retries = retriesLeft === undefined ? undefined : retriesLeft - 1; + this.openSocket(retryInterval, retries); + }, retryInterval); + } + } + initiateSocket() { + const pw = new PromiseWrapper$1(); + this.logger.debug(`initiating ws to ${this.settings.ws}...`); + this.ws = new WebSocketConstructor(this.settings.ws ?? ""); + this.ws.onerror = (err) => { + let reason = ""; + try { + reason = JSON.stringify(err); + } + catch (error) { + const seen = new WeakSet(); + const replacer = (key, value) => { + if (typeof value === "object" && value !== null) { + if (seen.has(value)) { + return; + } + seen.add(value); + } + return value; + }; + reason = JSON.stringify(err, replacer); + } + this.logger.info(`ws error - reason: ${reason}`); + pw.reject("error"); + this.notifyStatusChanged(false, reason); + }; + this.ws.onclose = (err) => { + this.logger.info(`ws closed - code: ${err?.code} reason: ${err?.reason}`); + pw.reject("closed"); + this.notifyStatusChanged(false); + }; + this.ws.onopen = () => { + this.startupTimer.mark("ws-opened"); + this.logger.info(`ws opened ${this.settings.identity?.application}`); + pw.resolve(); + this.notifyStatusChanged(true); + }; + this.ws.onmessage = (message) => { + this._registry.execute("onMessage", message.data); + }; + return pw.promise; + } + notifyForSocketState(error) { + this.wsRequests.forEach((wsRequest) => { + if (error) { + if (wsRequest.failed) { + wsRequest.failed(error); + } + } + else { + wsRequest.callback(); + } + }); + this.wsRequests = []; + } + notifyStatusChanged(status, reason) { + this._registry.execute("onConnectedChanged", status, reason); + } + } + + class MessageReplayerImpl { + specs; + specsNames = []; + messages = {}; + isDone; + subs = {}; + subsRefCount = {}; + connection; + constructor(specs) { + this.specs = {}; + for (const spec of specs) { + this.specs[spec.name] = spec; + this.specsNames.push(spec.name); + } + } + init(connection) { + this.connection = connection; + for (const name of this.specsNames) { + for (const type of this.specs[name].types) { + let refCount = this.subsRefCount[type]; + if (!refCount) { + refCount = 0; + } + refCount += 1; + this.subsRefCount[type] = refCount; + if (refCount > 1) { + continue; + } + const sub = connection.on(type, (msg) => this.processMessage(type, msg)); + this.subs[type] = sub; + } + } + } + processMessage(type, msg) { + if (this.isDone || !msg) { + return; + } + for (const name of this.specsNames) { + if (this.specs[name].types.indexOf(type) !== -1) { + const messages = this.messages[name] || []; + this.messages[name] = messages; + messages.push(msg); + } + } + } + drain(name, callback) { + if (callback) { + (this.messages[name] || []).forEach(callback); + } + delete this.messages[name]; + for (const type of this.specs[name].types) { + this.subsRefCount[type] -= 1; + if (this.subsRefCount[type] <= 0) { + this.connection?.off(this.subs[type]); + delete this.subs[type]; + delete this.subsRefCount[type]; + } + } + delete this.specs[name]; + if (!this.specs.length) { + this.isDone = true; + } + } + } + + let urlAlphabet$1 = + 'useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict'; + let nanoid$1 = (size = 21) => { + let id = ''; + let i = size; + while (i--) { + id += urlAlphabet$1[(Math.random() * 64) | 0]; + } + return id + }; + + const PromisePlus$1 = (executor, timeoutMilliseconds, timeoutMessage) => { + return new Promise((resolve, reject) => { + const timeout = setTimeout(() => { + const message = timeoutMessage || `Promise timeout hit: ${timeoutMilliseconds}`; + reject(message); + }, timeoutMilliseconds); + const providedPromise = new Promise(executor); + providedPromise + .then((result) => { + clearTimeout(timeout); + resolve(result); + }) + .catch((error) => { + clearTimeout(timeout); + reject(error); + }); + }); + }; + + class WebPlatformTransport { + settings; + logger; + identity; + isPreferredActivated; + _communicationId; + publicWindowId; + selfAssignedWindowId; + iAmConnected = false; + parentReady = false; + rejected = false; + parentPingResolve; + parentPingInterval; + connectionResolve; + extConnectionResolve; + extConnectionReject; + connectionReject; + port; + myClientId; + children = []; + extContentAvailable = false; + extContentConnecting = false; + extContentConnected = false; + parentWindowId; + parentInExtMode = false; + webNamespace = "g42_core_web"; + parent; + parentType; + parentPingTimeout = 5000; + connectionRequestTimeout = 7000; + defaultTargetString = "*"; + registry = CallbackRegistryFactory$1(); + messages = { + connectionAccepted: { name: "connectionAccepted", handle: this.handleConnectionAccepted.bind(this) }, + connectionRejected: { name: "connectionRejected", handle: this.handleConnectionRejected.bind(this) }, + connectionRequest: { name: "connectionRequest", handle: this.handleConnectionRequest.bind(this) }, + parentReady: { + name: "parentReady", handle: () => { + } + }, + parentPing: { name: "parentPing", handle: this.handleParentPing.bind(this) }, + platformPing: { name: "platformPing", handle: this.handlePlatformPing.bind(this) }, + platformReady: { name: "platformReady", handle: this.handlePlatformReady.bind(this) }, + clientUnload: { name: "clientUnload", handle: this.handleClientUnload.bind(this) }, + manualUnload: { name: "manualUnload", handle: this.handleManualUnload.bind(this) }, + extConnectionResponse: { name: "extConnectionResponse", handle: this.handleExtConnectionResponse.bind(this) }, + extSetupRequest: { name: "extSetupRequest", handle: this.handleExtSetupRequest.bind(this) }, + gatewayDisconnect: { name: "gatewayDisconnect", handle: this.handleGatewayDisconnect.bind(this) }, + gatewayInternalConnect: { name: "gatewayInternalConnect", handle: this.handleGatewayInternalConnect.bind(this) } + }; + constructor(settings, logger, identity) { + this.settings = settings; + this.logger = logger; + this.identity = identity; + this.extContentAvailable = !!window.glue42ext; + this.setUpMessageListener(); + this.setUpUnload(); + this.setupPlatformUnloadListener(); + this.parentType = window.name.includes("#wsp") ? "workspace" : undefined; + } + manualSetReadyState() { + this.iAmConnected = true; + this.parentReady = true; + } + get transportWindowId() { + return this.publicWindowId; + } + get communicationId() { + return this._communicationId; + } + async sendObject(msg) { + if (this.extContentConnected) { + return window.postMessage({ glue42ExtOut: msg }, this.defaultTargetString); + } + if (!this.port) { + throw new Error("Cannot send message, because the port was not opened yet"); + } + this.port.postMessage(msg); + } + get isObjectBasedTransport() { + return true; + } + onMessage(callback) { + return this.registry.add("onMessage", callback); + } + send() { + return Promise.reject("not supported"); + } + onConnectedChanged(callback) { + return this.registry.add("onConnectedChanged", callback); + } + async open() { + this.logger.debug("opening a connection to the web platform gateway."); + await this.connect(); + this.notifyStatusChanged(true); + } + close() { + const message = { + glue42core: { + type: this.messages.gatewayDisconnect.name, + data: { + clientId: this.myClientId, + ownWindowId: this.identity?.windowId + } + } + }; + this.port?.postMessage(message); + this.parentReady = false; + this.notifyStatusChanged(false, "manual reconnection"); + return Promise.resolve(); + } + name() { + return "web-platform"; + } + async reconnect() { + await this.close(); + return Promise.resolve(); + } + initiateInternalConnection() { + return new Promise((resolve, reject) => { + this.logger.debug("opening an internal web platform connection"); + this.port = this.settings.port; + if (this.iAmConnected) { + this.logger.warn("cannot open a new connection, because this client is currently connected"); + return; + } + this.port.onmessage = (event) => { + if (this.iAmConnected && !event.data?.glue42core) { + this.registry.execute("onMessage", event.data); + return; + } + const data = event.data?.glue42core; + if (!data) { + return; + } + if (data.type === this.messages.gatewayInternalConnect.name && data.success) { + this.publicWindowId = this.settings.windowId; + if (this.identity && this.publicWindowId) { + this.identity.windowId = this.publicWindowId; + this.identity.instance = this.publicWindowId; + } + resolve(); + } + if (data.type === this.messages.gatewayInternalConnect.name && data.error) { + reject(data.error); + } + }; + this.port.postMessage({ + glue42core: { + type: this.messages.gatewayInternalConnect.name + } + }); + }); + } + initiateRemoteConnection(target) { + return PromisePlus$1((resolve, reject) => { + this.connectionResolve = resolve; + this.connectionReject = reject; + this.myClientId = this.myClientId ?? nanoid$1(10); + const bridgeInstanceId = this.getMyWindowId() || nanoid$1(10); + const request = { + glue42core: { + type: this.messages.connectionRequest.name, + clientId: this.myClientId, + clientType: "child", + bridgeInstanceId, + selfAssignedWindowId: this.selfAssignedWindowId + } + }; + this.logger.debug("sending connection request"); + if (this.extContentConnecting) { + request.glue42core.clientType = "child"; + request.glue42core.bridgeInstanceId = this.myClientId; + request.glue42core.parentWindowId = this.parentWindowId; + return window.postMessage(request, this.defaultTargetString); + } + if (!target) { + throw new Error("Cannot send a connection request, because no glue target was specified!"); + } + target.postMessage(request, this.defaultTargetString); + }, this.connectionRequestTimeout, "The connection to the target glue window timed out"); + } + async isParentCheckSuccess(parentCheck) { + try { + await parentCheck; + return { success: true }; + } + catch (error) { + return { success: false }; + } + } + setUpMessageListener() { + if (this.settings.port) { + this.logger.debug("skipping generic message listener, because this is an internal client"); + return; + } + window.addEventListener("message", (event) => { + const data = event.data?.glue42core; + if (!data || this.rejected) { + return; + } + const allowedOrigins = this.settings.allowedOrigins || []; + if (allowedOrigins.length && !allowedOrigins.includes(event.origin)) { + this.logger.warn(`received a message from an origin which is not in the allowed list: ${event.origin}`); + return; + } + if (!this.checkMessageTypeValid(data.type)) { + this.logger.error(`cannot handle the incoming glue42 core message, because the type is invalid: ${data.type}`); + return; + } + const messageType = data.type; + this.logger.debug(`received valid glue42core message of type: ${messageType}`); + this.messages[messageType].handle(event); + }); + } + setUpUnload() { + if (this.settings.port) { + this.logger.debug("skipping unload event listener, because this is an internal client"); + return; + } + window.addEventListener("beforeunload", () => { + if (this.extContentConnected) { + return; + } + const message = { + glue42core: { + type: this.messages.clientUnload.name, + data: { + clientId: this.myClientId, + ownWindowId: this.identity?.windowId + } + } + }; + if (this.parent) { + this.parent.postMessage(message, this.defaultTargetString); + } + this.port?.postMessage(message); + }); + } + handlePlatformReady(event) { + this.logger.debug("the web platform gave the ready signal"); + this.parentReady = true; + if (this.parentPingResolve) { + this.parentPingResolve(); + delete this.parentPingResolve; + } + if (this.parentPingInterval) { + clearInterval(this.parentPingInterval); + delete this.parentPingInterval; + } + this.parent = event.source; + this.parentType = window.name.includes("#wsp") ? "workspace" : "window"; + } + handleConnectionAccepted(event) { + const data = event.data?.glue42core; + if (this.myClientId === data.clientId) { + return this.handleAcceptanceOfMyRequest(data); + } + return this.handleAcceptanceOfGrandChildRequest(data, event); + } + handleAcceptanceOfMyRequest(data) { + this.logger.debug("handling a connection accepted signal targeted at me."); + this.isPreferredActivated = data.isPreferredActivated; + if (this.extContentConnecting) { + return this.processExtContentConnection(data); + } + if (!data.port) { + this.logger.error("cannot set up my connection, because I was not provided with a port"); + return; + } + this.publicWindowId = this.getMyWindowId(); + if (this.identity) { + this.identity.windowId = this.publicWindowId; + this.identity.instance = this.identity.instance ? this.identity.instance : this.publicWindowId || nanoid$1(10); + } + if (this.identity && data.appName) { + this.identity.application = data.appName; + this.identity.applicationName = data.appName; + } + this._communicationId = data.communicationId; + this.port = data.port; + this.port.onmessage = (e) => this.registry.execute("onMessage", e.data); + if (this.connectionResolve) { + this.logger.debug("my connection is set up, calling the connection resolve."); + this.connectionResolve(); + delete this.connectionResolve; + return; + } + this.logger.error("unable to call the connection resolve, because no connection promise was found"); + } + processExtContentConnection(data) { + this.logger.debug("handling a connection accepted signal targeted at me for extension content connection."); + this.extContentConnecting = false; + this.extContentConnected = true; + this.publicWindowId = this.parentWindowId || this.myClientId; + if (this.extContentConnecting && this.identity) { + this.identity.windowId = this.publicWindowId; + } + if (this.identity && data.appName) { + this.identity.application = data.appName; + this.identity.applicationName = data.appName; + } + window.addEventListener("message", (event) => { + const extData = event.data?.glue42ExtInc; + if (!extData) { + return; + } + const allowedOrigins = this.settings.allowedOrigins || []; + if (allowedOrigins.length && !allowedOrigins.includes(event.origin)) { + this.logger.warn(`received a message from an origin which is not in the allowed list: ${event.origin}`); + return; + } + this.registry.execute("onMessage", extData); + }); + if (this.connectionResolve) { + this.logger.debug("my connection is set up, calling the connection resolve."); + this.connectionResolve(); + delete this.connectionResolve; + return; + } + } + handleAcceptanceOfGrandChildRequest(data, event) { + if (this.extContentConnecting || this.extContentConnected) { + this.logger.debug("cannot process acceptance of a grandchild, because I am connected to a content script"); + return; + } + this.logger.debug(`handling a connection accepted signal targeted at a grandchild: ${data.clientId}`); + const child = this.children.find((c) => c.grandChildId === data.clientId); + if (!child) { + this.logger.error(`cannot handle connection accepted for grandchild: ${data.clientId}, because there is no grandchild with this id`); + return; + } + child.connected = true; + this.logger.debug(`the grandchild connection for ${data.clientId} is set up, forwarding the success message and the gateway port`); + data.parentWindowId = this.publicWindowId; + child.source.postMessage(event.data, child.origin, [data.port]); + return; + } + handleConnectionRejected(event) { + this.logger.debug("handling a connection rejection. Most likely the reason is that this window was not created by a glue API call"); + if (!this.connectionReject) { + return; + } + const errorMsg = typeof event.data.glue42core?.error === "string" + ? `Connection was rejected. ${event.data.glue42core?.error}` + : "The platform connection was rejected. Most likely because this window was not created by a glue API call"; + this.connectionReject(errorMsg); + delete this.connectionReject; + } + handleConnectionRequest(event) { + if (this.extContentConnecting) { + this.logger.debug("This connection request event is targeted at the extension content"); + return; + } + const source = event.source; + const data = event.data.glue42core; + if (!data.clientType || data.clientType !== "grandChild") { + return this.rejectConnectionRequest(source, event.origin, "rejecting a connection request, because the source was not opened by a glue API call"); + } + if (!data.clientId) { + return this.rejectConnectionRequest(source, event.origin, "rejecting a connection request, because the source did not provide a valid id"); + } + if (!this.parent) { + return this.rejectConnectionRequest(source, event.origin, "Cannot forward the connection request, because no direct connection to the platform was found"); + } + this.logger.debug(`handling a connection request for a grandchild: ${data.clientId}`); + this.children.push({ grandChildId: data.clientId, source, connected: false, origin: event.origin }); + this.logger.debug(`grandchild: ${data.clientId} is prepared, forwarding connection request to the platform`); + this.parent.postMessage(event.data, this.defaultTargetString); + } + handleParentPing(event) { + if (!this.parentReady) { + this.logger.debug("my parent is not ready, I am ignoring the parent ping"); + return; + } + if (!this.iAmConnected) { + this.logger.debug("i am not fully connected yet, I am ignoring the parent ping"); + return; + } + const message = { + glue42core: { + type: this.messages.parentReady.name + } + }; + if (this.extContentConnected) { + message.glue42core.extMode = { windowId: this.myClientId }; + } + const source = event.source; + this.logger.debug("responding to a parent ping with a ready message"); + source.postMessage(message, event.origin); + } + setupPlatformUnloadListener() { + this.onMessage((msg) => { + if (msg.type === "platformUnload") { + this.logger.debug("detected a web platform unload"); + this.parentReady = false; + this.notifyStatusChanged(false, "Gateway unloaded"); + } + }); + } + handleManualUnload() { + const message = { + glue42core: { + type: this.messages.clientUnload.name, + data: { + clientId: this.myClientId, + ownWindowId: this.identity?.windowId + } + } + }; + if (this.extContentConnected) { + return window.postMessage({ glue42ExtOut: message }, this.defaultTargetString); + } + this.port?.postMessage(message); + } + handleClientUnload(event) { + const data = event.data.glue42core; + const clientId = data?.data.clientId; + if (!clientId) { + this.logger.warn("cannot process grand child unload, because the provided id was not valid"); + return; + } + const foundChild = this.children.find((child) => child.grandChildId === clientId); + if (!foundChild) { + this.logger.warn("cannot process grand child unload, because this client is unaware of this grandchild"); + return; + } + this.logger.debug(`handling grandchild unload for id: ${clientId}`); + this.children = this.children.filter((child) => child.grandChildId !== clientId); + } + handlePlatformPing() { + return; + } + notifyStatusChanged(status, reason) { + this.iAmConnected = status; + this.registry.execute("onConnectedChanged", status, reason); + } + checkMessageTypeValid(typeToValidate) { + return typeof typeToValidate === "string" && !!this.messages[typeToValidate]; + } + rejectConnectionRequest(source, origin, reason) { + this.rejected = true; + this.logger.error(reason); + const rejection = { + glue42core: { + type: this.messages.connectionRejected.name + } + }; + source.postMessage(rejection, origin); + } + requestConnectionPermissionFromExt() { + return this.waitForContentScript() + .then(() => PromisePlus$1((resolve, reject) => { + this.extConnectionResolve = resolve; + this.extConnectionReject = reject; + const message = { + glue42core: { + type: "extSetupRequest" + } + }; + this.logger.debug("permission request to the extension content script was sent"); + window.postMessage(message, this.defaultTargetString); + }, this.parentPingTimeout, "Cannot initialize glue, because this app was not opened or created by a Glue Client and the request for extension connection timed out")); + } + handleExtConnectionResponse(event) { + const data = event.data?.glue42core; + if (!data.approved) { + return this.extConnectionReject ? this.extConnectionReject("Cannot initialize glue, because this app was not opened or created by a Glue Client and the request for extension connection was rejected") : undefined; + } + if (this.extConnectionResolve) { + this.extConnectionResolve(); + delete this.extConnectionResolve; + } + this.extContentConnecting = true; + this.parentType = "extension"; + this.logger.debug("The extension connection was approved, proceeding."); + } + handleExtSetupRequest() { + return; + } + handleGatewayDisconnect() { + return; + } + handleGatewayInternalConnect() { + return; + } + waitForContentScript() { + const contentReady = !!window.glue42ext?.content; + if (contentReady) { + return Promise.resolve(); + } + return PromisePlus$1((resolve) => { + window.addEventListener("Glue42EXTReady", () => { + resolve(); + }); + }, this.connectionRequestTimeout, "The content script was available, but was never heard to be ready"); + } + async connect() { + if (this.settings.port) { + await this.initiateInternalConnection(); + this.logger.debug("internal web platform connection completed"); + return; + } + this.logger.debug("opening a client web platform connection"); + await this.findParent(); + await this.initiateRemoteConnection(this.parent); + this.logger.debug("the client is connected"); + } + async findParent() { + const connectionNotPossibleMsg = "Cannot initiate glue, because this window was not opened or created by a glue client"; + const myInsideParents = this.getPossibleParentsInWindow(window); + const myOutsideParents = this.getPossibleParentsOutsideWindow(window.top?.opener, window.top); + const uniqueParents = new Set([...myInsideParents, ...myOutsideParents]); + if (!uniqueParents.size && !this.extContentAvailable) { + throw new Error(connectionNotPossibleMsg); + } + if (!uniqueParents.size && this.extContentAvailable) { + await this.requestConnectionPermissionFromExt(); + return; + } + const defaultParentCheck = await this.isParentCheckSuccess(this.confirmParent(Array.from(uniqueParents))); + if (defaultParentCheck.success) { + this.logger.debug("The default parent was found!"); + return; + } + if (!this.extContentAvailable) { + throw new Error(connectionNotPossibleMsg); + } + await this.requestConnectionPermissionFromExt(); + } + getPossibleParentsInWindow(currentWindow) { + return (!currentWindow?.parent || currentWindow === currentWindow.parent) ? [] : [currentWindow.parent, ...this.getPossibleParentsInWindow(currentWindow.parent)]; + } + getPossibleParentsOutsideWindow(opener, current) { + return (!opener || !current || opener === current) ? [] : [opener, ...this.getPossibleParentsInWindow(opener), ...this.getPossibleParentsOutsideWindow(opener.opener, opener)]; + } + confirmParent(targets) { + const connectionNotPossibleMsg = "Cannot initiate glue, because this window was not opened or created by a glue client"; + const parentCheck = PromisePlus$1((resolve) => { + this.parentPingResolve = resolve; + const message = { + glue42core: { + type: this.messages.platformPing.name + } + }; + this.parentPingInterval = setInterval(() => { + targets.forEach((target) => { + target.postMessage(message, this.defaultTargetString); + }); + }, 1000); + }, this.parentPingTimeout, connectionNotPossibleMsg); + parentCheck.catch(() => { + if (this.parentPingInterval) { + clearInterval(this.parentPingInterval); + delete this.parentPingInterval; + } + }); + return parentCheck; + } + getMyWindowId() { + if (this.parentType === "workspace") { + return window.name.substring(0, window.name.indexOf("#wsp")); + } + if (window !== window.top) { + return; + } + if (window.name?.includes("g42")) { + return window.name; + } + this.selfAssignedWindowId = this.selfAssignedWindowId || `g42-${nanoid$1(10)}`; + return this.selfAssignedWindowId; + } + } + + const waitForInvocations = (invocations, callback) => { + let left = invocations; + return () => { + left--; + if (left === 0) { + callback(); + } + }; + }; + + class AsyncSequelizer { + minSequenceInterval; + queue = []; + isExecutingQueue = false; + constructor(minSequenceInterval = 0) { + this.minSequenceInterval = minSequenceInterval; + } + enqueue(action) { + return new Promise((resolve, reject) => { + this.queue.push({ action, resolve, reject }); + this.executeQueue(); + }); + } + async executeQueue() { + if (this.isExecutingQueue) { + return; + } + this.isExecutingQueue = true; + while (this.queue.length) { + const operation = this.queue.shift(); + if (!operation) { + this.isExecutingQueue = false; + return; + } + try { + const actionResult = await operation.action(); + operation.resolve(actionResult); + } + catch (error) { + operation.reject(error); + } + await this.intervalBreak(); + } + this.isExecutingQueue = false; + } + intervalBreak() { + return new Promise((res) => setTimeout(res, this.minSequenceInterval)); + } + } + + function domainSession (domain, connection, logger, successMessages, errorMessages) { + if (domain == null) { + domain = "global"; + } + successMessages = successMessages ?? ["success"]; + errorMessages = errorMessages ?? ["error"]; + let isJoined = domain === "global"; + let tryReconnecting = false; + let _latestOptions; + let _connectionOn = false; + const callbacks = CallbackRegistryFactory$1(); + connection.disconnected(handleConnectionDisconnected); + connection.loggedIn(handleConnectionLoggedIn); + connection.on("success", (msg) => handleSuccessMessage(msg)); + connection.on("error", (msg) => handleErrorMessage(msg)); + connection.on("result", (msg) => handleSuccessMessage(msg)); + if (successMessages) { + successMessages.forEach((sm) => { + connection.on(sm, (msg) => handleSuccessMessage(msg)); + }); + } + if (errorMessages) { + errorMessages.forEach((sm) => { + connection.on(sm, (msg) => handleErrorMessage(msg)); + }); + } + const requestsMap = {}; + function join(options) { + _latestOptions = options; + return new Promise((resolve, reject) => { + if (isJoined) { + resolve({}); + return; + } + let joinPromise; + if (domain === "global") { + joinPromise = _connectionOn ? Promise.resolve({}) : Promise.reject("not connected to gateway"); + } + else { + logger.debug(`joining domain ${domain}`); + const joinMsg = { + type: "join", + destination: domain, + domain: "global", + options, + }; + joinPromise = send(joinMsg); + } + joinPromise + .then(() => { + handleJoined(); + resolve({}); + }) + .catch((err) => { + logger.debug("error joining " + domain + " domain: " + JSON.stringify(err)); + reject(err); + }); + }); + } + function leave() { + if (domain === "global") { + return Promise.resolve(); + } + logger.debug("stopping session " + domain + "..."); + const leaveMsg = { + type: "leave", + destination: domain, + domain: "global", + }; + tryReconnecting = false; + return send(leaveMsg) + .then(() => { + isJoined = false; + callbacks.execute("onLeft"); + }) + .catch(() => { + isJoined = false; + callbacks.execute("onLeft"); + }); + } + function handleJoined() { + logger.debug("did join " + domain); + isJoined = true; + const wasReconnect = tryReconnecting; + tryReconnecting = false; + callbacks.execute("onJoined", wasReconnect); + } + function handleConnectionDisconnected() { + _connectionOn = false; + logger.debug("connection is down"); + isJoined = false; + tryReconnecting = true; + callbacks.execute("onLeft", { disconnected: true }); + } + function handleConnectionLoggedIn() { + _connectionOn = true; + if (tryReconnecting) { + logger.debug("connection is now up - trying to reconnect..."); + join(_latestOptions); + } + } + function onJoined(callback) { + if (isJoined) { + callback(false); + } + return callbacks.add("onJoined", callback); + } + function onLeft(callback) { + if (!isJoined) { + callback(); + } + return callbacks.add("onLeft", callback); + } + function handleErrorMessage(msg) { + if (domain !== msg.domain) { + return; + } + const requestId = msg.request_id; + if (!requestId) { + return; + } + const entry = requestsMap[requestId]; + if (!entry) { + return; + } + entry.error(msg); + } + function handleSuccessMessage(msg) { + if (msg.domain !== domain) { + return; + } + const requestId = msg.request_id; + if (!requestId) { + return; + } + const entry = requestsMap[requestId]; + if (!entry) { + return; + } + entry.success(msg); + } + function getNextRequestId() { + return nanoid$1(10); + } + let queuedCalls = []; + function send(msg, tag, options) { + const ignore = ["hello", "join"]; + if (msg.type && ignore.indexOf(msg.type) === -1) { + if (!isJoined) { + console.warn(`trying to send a message (${msg.domain} ${msg.type}) but not connected, will queue`); + const pw = new PromiseWrapper$1(); + queuedCalls.push({ msg, tag, options, pw }); + if (queuedCalls.length === 1) { + const unsubscribe = onJoined(() => { + logger.info(`joined - will now send queued messages (${queuedCalls.length} -> [${queuedCalls.map((m) => m.msg.type)}])`); + queuedCalls.forEach((qm) => { + send(qm.msg, qm.tag, qm.options) + .then((t) => qm.pw.resolve(t)) + .catch((e) => qm.pw.reject(e)); + }); + queuedCalls = []; + unsubscribe(); + }); + } + return pw.promise; + } + } + options = options ?? {}; + msg.request_id = msg.request_id ?? getNextRequestId(); + msg.domain = msg.domain ?? domain; + if (!options.skipPeerId) { + msg.peer_id = connection.peerId; + } + const requestId = msg.request_id; + return new Promise((resolve, reject) => { + requestsMap[requestId] = { + success: (successMsg) => { + delete requestsMap[requestId]; + successMsg._tag = tag; + resolve(successMsg); + }, + error: (errorMsg) => { + logger.warn(`Gateway error - ${JSON.stringify(errorMsg)}`); + delete requestsMap[requestId]; + errorMsg._tag = tag; + reject(errorMsg); + }, + }; + connection + .send(msg, options) + .catch((err) => { + requestsMap[requestId].error({ err }); + }); + }); + } + function sendFireAndForget(msg) { + msg.request_id = msg.request_id ? msg.request_id : getNextRequestId(); + msg.domain = msg.domain ?? domain; + msg.peer_id = connection.peerId; + return connection.send(msg); + } + return { + join, + leave, + onJoined, + onLeft, + send, + sendFireAndForget, + on: (type, callback) => { + connection.on(type, (msg) => { + if (msg.domain !== domain) { + return; + } + try { + callback(msg); + } + catch (e) { + logger.error(`Callback failed: ${e} \n ${e.stack} \n msg was: ${JSON.stringify(msg)}`, e); + } + }); + }, + loggedIn: (callback) => connection.loggedIn(callback), + connected: (callback) => connection.connected(callback), + disconnected: (callback) => connection.disconnected(callback), + get peerId() { + return connection.peerId; + }, + get domain() { + return domain; + }, + }; + } + + class Connection { + settings; + logger; + protocolVersion = 3; + peerId; + token; + info; + resolvedIdentity; + availableDomains; + gatewayToken; + replayer; + messageHandlers = {}; + ids = 1; + registry = CallbackRegistryFactory$1(); + _connected = false; + isTrace = false; + transport; + _defaultTransport; + _defaultAuth; + _targetTransport; + _targetAuth; + _swapTransport = false; + _switchInProgress = false; + _transportSubscriptions = []; + datePrefix = "#T42_DATE#"; + datePrefixLen = this.datePrefix.length; + dateMinLen = this.datePrefixLen + 1; + datePrefixFirstChar = this.datePrefix[0]; + _sequelizer = new AsyncSequelizer(); + _isLoggedIn = false; + shouldTryLogin = true; + pingTimer; + sessions = []; + globalDomain; + initialLogin = true; + initialLoginAttempts = 3; + loginConfig; + constructor(settings, logger) { + this.settings = settings; + this.logger = logger; + settings = settings || {}; + settings.reconnectAttempts = settings.reconnectAttempts ?? 10; + settings.reconnectInterval = settings.reconnectInterval ?? 1000; + if (settings.inproc) { + this.transport = new InProcTransport(settings.inproc, logger.subLogger("inMemory")); + } + else if (settings.sharedWorker) { + this.transport = new SharedWorkerTransport(settings.sharedWorker, logger.subLogger("shared-worker")); + } + else if (settings.webPlatform) { + this.transport = new WebPlatformTransport(settings.webPlatform, logger.subLogger("web-platform"), settings.identity); + } + else if (settings.ws !== undefined) { + this.transport = new WS(settings, logger.subLogger("ws")); + } + else { + throw new Error("No connection information specified"); + } + this.isTrace = logger.canPublish("trace"); + logger.debug(`starting with ${this.transport.name()} transport`); + const unsubConnectionChanged = this.transport.onConnectedChanged(this.handleConnectionChanged.bind(this)); + const unsubOnMessage = this.transport.onMessage(this.handleTransportMessage.bind(this)); + this._transportSubscriptions.push(unsubConnectionChanged); + this._transportSubscriptions.push(unsubOnMessage); + this._defaultTransport = this.transport; + this.ping(); + } + async switchTransport(settings) { + return this._sequelizer.enqueue(async () => { + if (!settings || typeof settings !== "object") { + throw new Error("Cannot switch transports, because the settings are missing or invalid."); + } + if (typeof settings.type === "undefined") { + throw new Error("Cannot switch the transport, because the type is not defined"); + } + this.logger.trace(`Starting transport switch with settings: ${JSON.stringify(settings)}`); + const switchTargetTransport = settings.type === "secondary" ? this.getNewSecondaryTransport(settings) : this._defaultTransport; + this._targetTransport = switchTargetTransport; + this._targetAuth = settings.type === "secondary" ? this.getNewSecondaryAuth(settings) : this._defaultAuth; + const verifyPromise = this.verifyConnection(); + this._swapTransport = true; + this._switchInProgress = true; + this.logger.trace("The new transport has been set, closing the current transport"); + await this.transport.close(); + try { + await verifyPromise; + const isSwitchSuccess = this.transport === switchTargetTransport; + this.logger.info(`The reconnection after the switch was completed. Was the switch a success: ${isSwitchSuccess}`); + this._switchInProgress = false; + return { success: isSwitchSuccess }; + } + catch (error) { + this.logger.info("The reconnection after the switch timed out, reverting back to the default transport."); + this.switchTransport({ type: "default" }); + this._switchInProgress = false; + return { success: false }; + } + }); + } + onLibReAnnounced(callback) { + return this.registry.add("libReAnnounced", callback); + } + setLibReAnnounced(lib) { + this.registry.execute("libReAnnounced", lib); + } + send(message, options) { + if (this.transport.sendObject && + this.transport.isObjectBasedTransport) { + const msg = this.createObjectMessage(message); + if (this.isTrace) { + this.logger.trace(`>> ${JSON.stringify(msg)}`); + } + return this.transport.sendObject(msg, options); + } + else { + const strMessage = this.createStringMessage(message); + if (this.isTrace) { + this.logger.trace(`>> ${strMessage}`); + } + return this.transport.send(strMessage, options); + } + } + on(type, messageHandler) { + type = type.toLowerCase(); + if (this.messageHandlers[type] === undefined) { + this.messageHandlers[type] = {}; + } + const id = this.ids++; + this.messageHandlers[type][id] = messageHandler; + return { + type, + id, + }; + } + off(info) { + delete this.messageHandlers[info.type.toLowerCase()][info.id]; + } + get isConnected() { + return this._isLoggedIn; + } + connected(callback) { + return this.loggedIn(() => { + const currentServer = this.transport.name(); + callback(currentServer); + }); + } + disconnected(callback) { + return this.registry.add("disconnected", callback); + } + async login(authRequest, reconnect) { + if (!this._defaultAuth) { + this._defaultAuth = authRequest; + } + if (this._swapTransport) { + this.logger.trace("Detected a transport swap, swapping transports"); + const newAuth = this.transportSwap(); + authRequest = newAuth ?? authRequest; + } + this.logger.trace(`Starting login for transport: ${this.transport.name()} and auth ${JSON.stringify(authRequest)}`); + try { + await this.transport.open(); + this.logger.trace(`Transport: ${this.transport.name()} opened, logging in`); + timer("connection").mark("transport-opened"); + const identity = await this.loginCore(authRequest, reconnect); + this.logger.trace(`Logged in with identity: ${JSON.stringify(identity)}`); + timer("connection").mark("protocol-logged-in"); + return identity; + } + catch (error) { + if (this._switchInProgress) { + this.logger.trace("An error while logging in after a transport swap, preparing a default swap."); + this.prepareDefaultSwap(); + } + throw new Error(error); + } + } + async logout() { + await this.logoutCore(); + await this.transport.close(); + } + loggedIn(callback) { + if (this._isLoggedIn) { + callback(); + } + return this.registry.add("onLoggedIn", callback); + } + domain(domain, successMessages, errorMessages) { + let session = this.sessions.find((s) => s.domain === domain); + if (!session) { + session = domainSession(domain, this, this.logger.subLogger(`domain=${domain}`), successMessages, errorMessages); + this.sessions.push(session); + } + return session; + } + authToken() { + const createTokenReq = { + domain: "global", + type: "create-token" + }; + if (!this.globalDomain) { + return Promise.reject(new Error("no global domain session")); + } + return this.globalDomain.send(createTokenReq) + .then((res) => { + return res.token; + }); + } + reconnect() { + return this.transport.reconnect(); + } + setLoggedIn(value) { + this._isLoggedIn = value; + if (this._isLoggedIn) { + this.registry.execute("onLoggedIn"); + } + } + distributeMessage(message, type) { + const handlers = this.messageHandlers[type.toLowerCase()]; + if (handlers !== undefined) { + Object.keys(handlers).forEach((handlerId) => { + const handler = handlers[handlerId]; + if (handler !== undefined) { + try { + handler(message); + } + catch (error) { + try { + this.logger.error(`Message handler failed with ${error.stack}`, error); + } + catch (loggerError) { + console.log("Message handler failed", error); + } + } + } + }); + } + } + handleConnectionChanged(connected) { + if (this._connected === connected) { + return; + } + this._connected = connected; + if (connected) { + if (this.settings?.replaySpecs?.length) { + this.replayer = new MessageReplayerImpl(this.settings.replaySpecs); + this.replayer.init(this); + } + this.registry.execute("connected"); + } + else { + this.handleDisconnected(); + this.registry.execute("disconnected"); + } + } + handleDisconnected() { + this.setLoggedIn(false); + const tryToLogin = this.shouldTryLogin; + if (tryToLogin && this.initialLogin) { + if (this.initialLoginAttempts <= 0) { + return; + } + this.initialLoginAttempts--; + } + this.logger.debug("disconnected - will try new login?" + this.shouldTryLogin); + if (this.shouldTryLogin) { + if (!this.loginConfig) { + throw new Error("no login info"); + } + this.login(this.loginConfig, true) + .catch(() => { + setTimeout(this.handleDisconnected.bind(this), this.settings.reconnectInterval || 1000); + }); + } + } + handleTransportMessage(msg) { + let msgObj; + if (typeof msg === "string") { + msgObj = this.processStringMessage(msg); + } + else { + msgObj = this.processObjectMessage(msg); + } + if (this.isTrace) { + this.logger.trace(`<< ${JSON.stringify(msgObj)}`); + } + this.distributeMessage(msgObj.msg, msgObj.msgType); + } + verifyConnection() { + return PromisePlus$1((resolve) => { + let unsub; + const ready = waitForInvocations(2, () => { + if (unsub) { + unsub(); + } + resolve(); + }); + unsub = this.onLibReAnnounced((lib) => { + if (lib.name === "interop") { + return ready(); + } + if (lib.name === "contexts") { + return ready(); + } + }); + }, 10000, "Transport switch timed out waiting for all libraries to be re-announced"); + } + getNewSecondaryTransport(settings) { + if (!settings.transportConfig?.url) { + throw new Error("Missing secondary transport URL."); + } + return new WS(Object.assign({}, this.settings, { ws: settings.transportConfig.url, reconnectAttempts: 1 }), this.logger.subLogger("ws-secondary")); + } + getNewSecondaryAuth(settings) { + if (!settings.transportConfig?.auth) { + throw new Error("Missing secondary transport auth information."); + } + return settings.transportConfig.auth; + } + transportSwap() { + this._swapTransport = false; + if (!this._targetTransport || !this._targetAuth) { + this.logger.warn(`Error while switching transports - either the target transport or auth is not defined: transport defined -> ${!!this._defaultTransport}, auth defined -> ${!!this._targetAuth}. Staying on the current one.`); + return; + } + this._transportSubscriptions.forEach((unsub) => unsub()); + this._transportSubscriptions = []; + this.transport = this._targetTransport; + const unsubConnectionChanged = this.transport.onConnectedChanged(this.handleConnectionChanged.bind(this)); + const unsubOnMessage = this.transport.onMessage(this.handleTransportMessage.bind(this)); + this._transportSubscriptions.push(unsubConnectionChanged); + this._transportSubscriptions.push(unsubOnMessage); + return this._targetAuth; + } + prepareDefaultSwap() { + this._transportSubscriptions.forEach((unsub) => unsub()); + this._transportSubscriptions = []; + this.transport.close().catch((error) => this.logger.warn(`Error closing the ${this.transport.name()} transport after a failed connection attempt: ${JSON.stringify(error)}`)); + this._targetTransport = this._defaultTransport; + this._targetAuth = this._defaultAuth; + this._swapTransport = true; + } + processStringMessage(message) { + const msg = JSON.parse(message, (key, value) => { + if (typeof value !== "string") { + return value; + } + if (value.length < this.dateMinLen) { + return value; + } + if (!value.startsWith(this.datePrefixFirstChar)) { + return value; + } + if (value.substring(0, this.datePrefixLen) !== this.datePrefix) { + return value; + } + try { + const milliseconds = parseInt(value.substring(this.datePrefixLen, value.length), 10); + if (isNaN(milliseconds)) { + return value; + } + return new Date(milliseconds); + } + catch (ex) { + return value; + } + }); + return { + msg, + msgType: msg.type, + }; + } + createStringMessage(message) { + const oldToJson = Date.prototype.toJSON; + try { + const datePrefix = this.datePrefix; + Date.prototype.toJSON = function () { + return datePrefix + this.getTime(); + }; + const result = JSON.stringify(message); + return result; + } + finally { + Date.prototype.toJSON = oldToJson; + } + } + processObjectMessage(message) { + if (!message.type) { + throw new Error("Object should have type property"); + } + return { + msg: message, + msgType: message.type, + }; + } + createObjectMessage(message) { + return message; + } + async loginCore(config, reconnect) { + this.logger.info("logging in..."); + this.loginConfig = config; + if (!this.loginConfig) { + this.loginConfig = { username: "", password: "" }; + } + this.shouldTryLogin = true; + const authentication = await this.setupAuthConfig(config, reconnect); + const helloMsg = { + type: "hello", + identity: this.settings.identity, + authentication + }; + if (config.sessionId) { + helloMsg.request_id = config.sessionId; + } + this.globalDomain = domainSession("global", this, this.logger.subLogger("global-domain"), [ + "welcome", + "token", + "authentication-request" + ]); + const sendOptions = { skipPeerId: true }; + if (this.initialLogin) { + sendOptions.retryInterval = this.settings.reconnectInterval; + sendOptions.maxRetries = this.settings.reconnectAttempts; + } + try { + const welcomeMsg = await this.tryAuthenticate(this.globalDomain, helloMsg, sendOptions, config); + this.initialLogin = false; + this.logger.info("login successful with peerId " + welcomeMsg.peer_id); + this.peerId = welcomeMsg.peer_id; + this.resolvedIdentity = welcomeMsg.resolved_identity; + this.availableDomains = welcomeMsg.available_domains; + if (welcomeMsg.options) { + this.token = welcomeMsg.options.access_token; + this.info = welcomeMsg.options.info; + } + this.setLoggedIn(true); + return welcomeMsg.resolved_identity; + } + catch (err) { + this.logger.error("error sending hello message - " + (err.message || err.msg || err.reason || err), err); + throw err; + } + finally { + if (config?.flowCallback && config.sessionId) { + config.flowCallback(config.sessionId, null); + } + } + } + async tryAuthenticate(globalDomain, helloMsg, sendOptions, config) { + let welcomeMsg; + while (true) { + const msg = await globalDomain.send(helloMsg, undefined, sendOptions); + if (msg.type === "authentication-request") { + const token = Buffer.from(msg.authentication.token, "base64"); + if (config.flowCallback && config.sessionId) { + helloMsg.authentication.token = + (await config.flowCallback(config.sessionId, token)) + .data + .toString("base64"); + } + helloMsg.request_id = config.sessionId; + } + else if (msg.type === "welcome") { + welcomeMsg = msg; + break; + } + else if (msg.type === "error") { + throw new Error("Authentication failed: " + msg.reason); + } + else { + throw new Error("Unexpected message type during authentication: " + msg.type); + } + } + return welcomeMsg; + } + async setupAuthConfig(config, reconnect) { + const authentication = {}; + this.gatewayToken = config.gatewayToken; + if (config.gatewayToken) { + if (reconnect) { + try { + config.gatewayToken = await this.getNewGWToken(); + } + catch (e) { + this.logger.warn(`failed to get GW token when reconnecting ${e?.message || e}`); + } + } + authentication.method = "gateway-token"; + authentication.token = config.gatewayToken; + this.gatewayToken = config.gatewayToken; + } + else if (config.flowName === "sspi") { + authentication.provider = "win"; + authentication.method = "access-token"; + if (config.flowCallback && config.sessionId) { + authentication.token = + (await config.flowCallback(config.sessionId, null)) + .data + .toString("base64"); + } + else { + throw new Error("Invalid SSPI config"); + } + } + else if (config.token) { + authentication.method = "access-token"; + authentication.token = config.token; + } + else if (config.username) { + authentication.method = "secret"; + authentication.login = config.username; + authentication.secret = config.password; + } + else if (config.provider) { + authentication.provider = config.provider; + authentication.providerContext = config.providerContext; + } + else { + throw new Error("invalid auth message" + JSON.stringify(config)); + } + return authentication; + } + async logoutCore() { + this.logger.debug("logging out..."); + this.shouldTryLogin = false; + if (this.pingTimer) { + clearTimeout(this.pingTimer); + } + const promises = this.sessions.map((session) => { + session.leave(); + }); + await Promise.all(promises); + } + getNewGWToken() { + if (typeof window !== "undefined") { + const glue42gd = window.glue42gd; + if (glue42gd) { + return glue42gd.getGWToken(); + } + } + return Promise.reject(new Error("not running in GD")); + } + ping() { + if (!this.shouldTryLogin) { + return; + } + if (this._isLoggedIn) { + this.send({ type: "ping" }); + } + this.pingTimer = setTimeout(() => { + this.ping(); + }, 30 * 1000); + } + } + + const order = ["trace", "debug", "info", "warn", "error", "off"]; + let Logger$1 = class Logger { + name; + parent; + static Interop; + static InteropMethodName = "T42.AppLogger.Log"; + static Instance; + path; + subLoggers = []; + _consoleLevel; + _publishLevel; + loggerFullName; + includeTimeAndLevel; + logFn = console; + customLogFn = false; + constructor(name, parent, logFn) { + this.name = name; + this.parent = parent; + this.name = name; + if (parent) { + this.path = `${parent.path}.${name}`; + } + else { + this.path = name; + } + this.loggerFullName = `[${this.path}]`; + this.includeTimeAndLevel = !logFn; + if (logFn) { + this.logFn = logFn; + this.customLogFn = true; + } + } + subLogger(name) { + const existingSub = this.subLoggers.filter((subLogger) => { + return subLogger.name === name; + })[0]; + if (existingSub !== undefined) { + return existingSub; + } + Object.keys(this).forEach((key) => { + if (key === name) { + throw new Error("This sub logger name is not allowed."); + } + }); + const sub = new Logger(name, this, this.customLogFn ? this.logFn : undefined); + this.subLoggers.push(sub); + return sub; + } + publishLevel(level) { + if (level) { + this._publishLevel = level; + } + return this._publishLevel || this.parent?.publishLevel(); + } + consoleLevel(level) { + if (level) { + this._consoleLevel = level; + } + return this._consoleLevel || this.parent?.consoleLevel(); + } + log(message, level, error) { + this.publishMessage(level || "info", message, error); + } + trace(message) { + this.log(message, "trace"); + } + debug(message) { + this.log(message, "debug"); + } + info(message) { + this.log(message, "info"); + } + warn(message) { + this.log(message, "warn"); + } + error(message, err) { + this.log(message, "error", err); + } + canPublish(level, compareWith) { + const levelIdx = order.indexOf(level); + const restrictionIdx = order.indexOf(compareWith || this.consoleLevel() || "trace"); + return levelIdx >= restrictionIdx; + } + publishMessage(level, message, error) { + const loggerName = this.loggerFullName; + if (level === "error" && !error) { + const e = new Error(); + if (e.stack) { + message = + message + + "\n" + + e.stack + .split("\n") + .slice(4) + .join("\n"); + } + } + if (this.canPublish(level, this.publishLevel())) { + const interop = Logger.Interop; + if (interop) { + try { + if (interop.methods({ name: Logger.InteropMethodName }).length > 0) { + const args = { + msg: message, + logger: loggerName, + level + }; + if (error && error instanceof Error) { + args.error = { + message: error.message, + stack: error.stack ?? "" + }; + } + interop.invoke(Logger.InteropMethodName, args); + } + } + catch { + } + } + } + if (this.canPublish(level)) { + let prefix = ""; + if (this.includeTimeAndLevel) { + const date = new Date(); + const time = `${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}:${date.getMilliseconds()}`; + prefix = `[${time}] [${level}] `; + } + const toPrint = `${prefix}${loggerName}: ${message}`; + switch (level) { + case "trace": + this.logFn.debug(toPrint); + break; + case "debug": + if (this.logFn.debug) { + this.logFn.debug(toPrint); + } + else { + this.logFn.log(toPrint); + } + break; + case "info": + this.logFn.info(toPrint); + break; + case "warn": + this.logFn.warn(toPrint); + break; + case "error": + this.logFn.error(toPrint, error); + break; + } + } + } + }; + + const GW_MESSAGE_CREATE_CONTEXT = "create-context"; + const GW_MESSAGE_ACTIVITY_CREATED = "created"; + const GW_MESSAGE_ACTIVITY_DESTROYED = "destroyed"; + const GW_MESSAGE_CONTEXT_CREATED = "context-created"; + const GW_MESSAGE_CONTEXT_ADDED = "context-added"; + const GW_MESSAGE_SUBSCRIBE_CONTEXT = "subscribe-context"; + const GW_MESSAGE_SUBSCRIBED_CONTEXT = "subscribed-context"; + const GW_MESSAGE_UNSUBSCRIBE_CONTEXT = "unsubscribe-context"; + const GW_MESSAGE_DESTROY_CONTEXT = "destroy-context"; + const GW_MESSAGE_CONTEXT_DESTROYED = "context-destroyed"; + const GW_MESSAGE_UPDATE_CONTEXT = "update-context"; + const GW_MESSAGE_CONTEXT_UPDATED = "context-updated"; + const GW_MESSAGE_JOINED_ACTIVITY = "joined"; + + const ContextMessageReplaySpec = { + get name() { + return "context"; + }, + get types() { + return [ + GW_MESSAGE_CREATE_CONTEXT, + GW_MESSAGE_ACTIVITY_CREATED, + GW_MESSAGE_ACTIVITY_DESTROYED, + GW_MESSAGE_CONTEXT_CREATED, + GW_MESSAGE_CONTEXT_ADDED, + GW_MESSAGE_SUBSCRIBE_CONTEXT, + GW_MESSAGE_SUBSCRIBED_CONTEXT, + GW_MESSAGE_UNSUBSCRIBE_CONTEXT, + GW_MESSAGE_DESTROY_CONTEXT, + GW_MESSAGE_CONTEXT_DESTROYED, + GW_MESSAGE_UPDATE_CONTEXT, + GW_MESSAGE_CONTEXT_UPDATED, + GW_MESSAGE_JOINED_ACTIVITY + ]; + } + }; + + var version$1 = "6.5.2-fmr-beta"; + + function prepareConfig$1 (configuration, ext, glue42gd) { + let nodeStartingContext; + if (Utils$1.isNode()) { + const startingContextString = process.env._GD_STARTING_CONTEXT_; + if (startingContextString) { + try { + nodeStartingContext = JSON.parse(startingContextString); + } + catch { + } + } + } + function getConnection() { + const gwConfig = configuration.gateway; + const protocolVersion = gwConfig?.protocolVersion ?? 3; + const reconnectInterval = gwConfig?.reconnectInterval; + const reconnectAttempts = gwConfig?.reconnectAttempts; + const defaultWs = "ws://localhost:8385"; + let ws = gwConfig?.ws; + const sharedWorker = gwConfig?.sharedWorker; + const inproc = gwConfig?.inproc; + const webPlatform = gwConfig?.webPlatform ?? undefined; + if (glue42gd) { + ws = glue42gd.gwURL; + } + if (Utils$1.isNode() && nodeStartingContext && nodeStartingContext.gwURL) { + ws = nodeStartingContext.gwURL; + } + if (!ws && !sharedWorker && !inproc) { + ws = defaultWs; + } + let instanceId; + let windowId; + let pid; + let environment; + let region; + const appName = getApplication(); + let uniqueAppName = appName; + if (typeof glue42gd !== "undefined") { + windowId = glue42gd.windowId; + pid = glue42gd.pid; + if (glue42gd.env) { + environment = glue42gd.env.env; + region = glue42gd.env.region; + } + uniqueAppName = glue42gd.application ?? "glue-app"; + instanceId = glue42gd.appInstanceId; + } + else if (Utils$1.isNode()) { + pid = process.pid; + if (nodeStartingContext) { + environment = nodeStartingContext.env; + region = nodeStartingContext.region; + instanceId = nodeStartingContext.instanceId; + } + } + else if (typeof window?.glue42electron !== "undefined") { + windowId = window?.glue42electron.instanceId; + pid = window?.glue42electron.pid; + environment = window?.glue42electron.env; + region = window?.glue42electron.region; + uniqueAppName = window?.glue42electron.application ?? "glue-app"; + instanceId = window?.glue42electron.instanceId; + } + else ; + const replaySpecs = configuration.gateway?.replaySpecs ?? []; + replaySpecs.push(ContextMessageReplaySpec); + let identity = { + application: uniqueAppName, + applicationName: appName, + windowId, + instance: instanceId, + process: pid, + region, + environment, + api: ext.version || version$1 + }; + if (configuration.identity) { + identity = Object.assign(identity, configuration.identity); + } + return { + identity, + reconnectInterval, + ws, + sharedWorker, + webPlatform, + inproc, + protocolVersion, + reconnectAttempts, + replaySpecs, + }; + } + function getContexts() { + if (typeof configuration.contexts === "undefined") { + return { reAnnounceKnownContexts: true }; + } + if (typeof configuration.contexts === "boolean" && configuration.contexts) { + return { reAnnounceKnownContexts: true }; + } + if (typeof configuration.contexts === "object") { + return Object.assign({}, { reAnnounceKnownContexts: true }, configuration.contexts); + } + return false; + } + function getApplication() { + if (configuration.application) { + return configuration.application; + } + if (glue42gd) { + return glue42gd.applicationName; + } + if (typeof window !== "undefined" && typeof window.glue42electron !== "undefined") { + return window.glue42electron.application; + } + const uid = nanoid$1(10); + if (Utils$1.isNode()) { + if (nodeStartingContext) { + return nodeStartingContext.applicationConfig.name; + } + return "NodeJS" + uid; + } + if (typeof window !== "undefined" && typeof document !== "undefined") { + return document.title + ` (${uid})`; + } + return uid; + } + function getAuth() { + if (typeof configuration.auth === "string") { + return { + token: configuration.auth + }; + } + if (configuration.auth) { + return configuration.auth; + } + if (Utils$1.isNode() && nodeStartingContext && nodeStartingContext.gwToken) { + return { + gatewayToken: nodeStartingContext.gwToken + }; + } + if (configuration.gateway?.webPlatform || configuration.gateway?.inproc || configuration.gateway?.sharedWorker) { + return { + username: "glue42", password: "glue42" + }; + } + } + function getLogger() { + let config = configuration.logger; + const defaultLevel = "warn"; + if (!config) { + config = defaultLevel; + } + let gdConsoleLevel; + if (glue42gd) { + gdConsoleLevel = glue42gd.consoleLogLevel; + } + if (typeof config === "string") { + return { console: gdConsoleLevel ?? config, publish: defaultLevel }; + } + return { + console: gdConsoleLevel ?? config.console ?? defaultLevel, + publish: config.publish ?? defaultLevel + }; + } + const connection = getConnection(); + let application = getApplication(); + if (typeof window !== "undefined") { + const windowAsAny = window; + const containerApplication = windowAsAny.htmlContainer ? + `${windowAsAny.htmlContainer.containerName}.${windowAsAny.htmlContainer.application}` : + windowAsAny?.glue42gd?.application; + if (containerApplication) { + application = containerApplication; + } + } + return { + bus: configuration.bus ?? false, + application, + auth: getAuth(), + logger: getLogger(), + connection, + metrics: configuration.metrics ?? true, + contexts: getContexts(), + version: ext.version || version$1, + libs: ext.libs ?? [], + customLogger: configuration.customLogger + }; + } + + class GW3ContextData { + name; + contextId; + context; + isAnnounced; + joinedActivity; + updateCallbacks = {}; + activityId; + sentExplicitSubscription; + hasReceivedSnapshot; + constructor(contextId, name, isAnnounced, activityId) { + this.contextId = contextId; + this.name = name; + this.isAnnounced = isAnnounced; + this.activityId = activityId; + this.context = {}; + } + hasCallbacks() { + return Object.keys(this.updateCallbacks).length > 0; + } + getState() { + if (this.isAnnounced && this.hasCallbacks()) { + return 3; + } + if (this.isAnnounced) { + return 2; + } + if (this.hasCallbacks()) { + return 1; + } + return 0; + } + } + + var lodash_clonedeep = {exports: {}}; + + /** + * lodash (Custom Build) + * Build: `lodash modularize exports="npm" -o ./` + * Copyright jQuery Foundation and other contributors + * Released under MIT license + * Based on Underscore.js 1.8.3 + * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + */ + lodash_clonedeep.exports; + + (function (module, exports) { + /** Used as the size to enable large array optimizations. */ + var LARGE_ARRAY_SIZE = 200; + + /** Used to stand-in for `undefined` hash values. */ + var HASH_UNDEFINED = '__lodash_hash_undefined__'; + + /** Used as references for various `Number` constants. */ + var MAX_SAFE_INTEGER = 9007199254740991; + + /** `Object#toString` result references. */ + var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + boolTag = '[object Boolean]', + dateTag = '[object Date]', + errorTag = '[object Error]', + funcTag = '[object Function]', + genTag = '[object GeneratorFunction]', + mapTag = '[object Map]', + numberTag = '[object Number]', + objectTag = '[object Object]', + promiseTag = '[object Promise]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + symbolTag = '[object Symbol]', + weakMapTag = '[object WeakMap]'; + + var arrayBufferTag = '[object ArrayBuffer]', + dataViewTag = '[object DataView]', + float32Tag = '[object Float32Array]', + float64Tag = '[object Float64Array]', + int8Tag = '[object Int8Array]', + int16Tag = '[object Int16Array]', + int32Tag = '[object Int32Array]', + uint8Tag = '[object Uint8Array]', + uint8ClampedTag = '[object Uint8ClampedArray]', + uint16Tag = '[object Uint16Array]', + uint32Tag = '[object Uint32Array]'; + + /** + * Used to match `RegExp` + * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns). + */ + var reRegExpChar = /[\\^$.*+?()[\]{}|]/g; + + /** Used to match `RegExp` flags from their coerced string values. */ + var reFlags = /\w*$/; + + /** Used to detect host constructors (Safari). */ + var reIsHostCtor = /^\[object .+?Constructor\]$/; + + /** Used to detect unsigned integer values. */ + var reIsUint = /^(?:0|[1-9]\d*)$/; + + /** Used to identify `toStringTag` values supported by `_.clone`. */ + var cloneableTags = {}; + cloneableTags[argsTag] = cloneableTags[arrayTag] = + cloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] = + cloneableTags[boolTag] = cloneableTags[dateTag] = + cloneableTags[float32Tag] = cloneableTags[float64Tag] = + cloneableTags[int8Tag] = cloneableTags[int16Tag] = + cloneableTags[int32Tag] = cloneableTags[mapTag] = + cloneableTags[numberTag] = cloneableTags[objectTag] = + cloneableTags[regexpTag] = cloneableTags[setTag] = + cloneableTags[stringTag] = cloneableTags[symbolTag] = + cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] = + cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true; + cloneableTags[errorTag] = cloneableTags[funcTag] = + cloneableTags[weakMapTag] = false; + + /** Detect free variable `global` from Node.js. */ + var freeGlobal = typeof commonjsGlobal$1 == 'object' && commonjsGlobal$1 && commonjsGlobal$1.Object === Object && commonjsGlobal$1; + + /** Detect free variable `self`. */ + var freeSelf = typeof self == 'object' && self && self.Object === Object && self; + + /** Used as a reference to the global object. */ + var root = freeGlobal || freeSelf || Function('return this')(); + + /** Detect free variable `exports`. */ + var freeExports = exports && !exports.nodeType && exports; + + /** Detect free variable `module`. */ + var freeModule = freeExports && 'object' == 'object' && module && !module.nodeType && module; + + /** Detect the popular CommonJS extension `module.exports`. */ + var moduleExports = freeModule && freeModule.exports === freeExports; + + /** + * Adds the key-value `pair` to `map`. + * + * @private + * @param {Object} map The map to modify. + * @param {Array} pair The key-value pair to add. + * @returns {Object} Returns `map`. + */ + function addMapEntry(map, pair) { + // Don't return `map.set` because it's not chainable in IE 11. + map.set(pair[0], pair[1]); + return map; + } + + /** + * Adds `value` to `set`. + * + * @private + * @param {Object} set The set to modify. + * @param {*} value The value to add. + * @returns {Object} Returns `set`. + */ + function addSetEntry(set, value) { + // Don't return `set.add` because it's not chainable in IE 11. + set.add(value); + return set; + } + + /** + * A specialized version of `_.forEach` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns `array`. + */ + function arrayEach(array, iteratee) { + var index = -1, + length = array ? array.length : 0; + + while (++index < length) { + if (iteratee(array[index], index, array) === false) { + break; + } + } + return array; + } + + /** + * Appends the elements of `values` to `array`. + * + * @private + * @param {Array} array The array to modify. + * @param {Array} values The values to append. + * @returns {Array} Returns `array`. + */ + function arrayPush(array, values) { + var index = -1, + length = values.length, + offset = array.length; + + while (++index < length) { + array[offset + index] = values[index]; + } + return array; + } + + /** + * A specialized version of `_.reduce` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {boolean} [initAccum] Specify using the first element of `array` as + * the initial value. + * @returns {*} Returns the accumulated value. + */ + function arrayReduce(array, iteratee, accumulator, initAccum) { + var index = -1, + length = array ? array.length : 0; + while (++index < length) { + accumulator = iteratee(accumulator, array[index], index, array); + } + return accumulator; + } + + /** + * The base implementation of `_.times` without support for iteratee shorthands + * or max array length checks. + * + * @private + * @param {number} n The number of times to invoke `iteratee`. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the array of results. + */ + function baseTimes(n, iteratee) { + var index = -1, + result = Array(n); + + while (++index < n) { + result[index] = iteratee(index); + } + return result; + } + + /** + * Gets the value at `key` of `object`. + * + * @private + * @param {Object} [object] The object to query. + * @param {string} key The key of the property to get. + * @returns {*} Returns the property value. + */ + function getValue(object, key) { + return object == null ? undefined : object[key]; + } + + /** + * Checks if `value` is a host object in IE < 9. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a host object, else `false`. + */ + function isHostObject(value) { + // Many host objects are `Object` objects that can coerce to strings + // despite having improperly defined `toString` methods. + var result = false; + if (value != null && typeof value.toString != 'function') { + try { + result = !!(value + ''); + } catch (e) {} + } + return result; + } + + /** + * Converts `map` to its key-value pairs. + * + * @private + * @param {Object} map The map to convert. + * @returns {Array} Returns the key-value pairs. + */ + function mapToArray(map) { + var index = -1, + result = Array(map.size); + + map.forEach(function(value, key) { + result[++index] = [key, value]; + }); + return result; + } + + /** + * Creates a unary function that invokes `func` with its argument transformed. + * + * @private + * @param {Function} func The function to wrap. + * @param {Function} transform The argument transform. + * @returns {Function} Returns the new function. + */ + function overArg(func, transform) { + return function(arg) { + return func(transform(arg)); + }; + } + + /** + * Converts `set` to an array of its values. + * + * @private + * @param {Object} set The set to convert. + * @returns {Array} Returns the values. + */ + function setToArray(set) { + var index = -1, + result = Array(set.size); + + set.forEach(function(value) { + result[++index] = value; + }); + return result; + } + + /** Used for built-in method references. */ + var arrayProto = Array.prototype, + funcProto = Function.prototype, + objectProto = Object.prototype; + + /** Used to detect overreaching core-js shims. */ + var coreJsData = root['__core-js_shared__']; + + /** Used to detect methods masquerading as native. */ + var maskSrcKey = (function() { + var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || ''); + return uid ? ('Symbol(src)_1.' + uid) : ''; + }()); + + /** Used to resolve the decompiled source of functions. */ + var funcToString = funcProto.toString; + + /** Used to check objects for own properties. */ + var hasOwnProperty = objectProto.hasOwnProperty; + + /** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ + var objectToString = objectProto.toString; + + /** Used to detect if a method is native. */ + var reIsNative = RegExp('^' + + funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&') + .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' + ); + + /** Built-in value references. */ + var Buffer = moduleExports ? root.Buffer : undefined, + Symbol = root.Symbol, + Uint8Array = root.Uint8Array, + getPrototype = overArg(Object.getPrototypeOf, Object), + objectCreate = Object.create, + propertyIsEnumerable = objectProto.propertyIsEnumerable, + splice = arrayProto.splice; + + /* Built-in method references for those with the same name as other `lodash` methods. */ + var nativeGetSymbols = Object.getOwnPropertySymbols, + nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined, + nativeKeys = overArg(Object.keys, Object); + + /* Built-in method references that are verified to be native. */ + var DataView = getNative(root, 'DataView'), + Map = getNative(root, 'Map'), + Promise = getNative(root, 'Promise'), + Set = getNative(root, 'Set'), + WeakMap = getNative(root, 'WeakMap'), + nativeCreate = getNative(Object, 'create'); + + /** Used to detect maps, sets, and weakmaps. */ + var dataViewCtorString = toSource(DataView), + mapCtorString = toSource(Map), + promiseCtorString = toSource(Promise), + setCtorString = toSource(Set), + weakMapCtorString = toSource(WeakMap); + + /** Used to convert symbols to primitives and strings. */ + var symbolProto = Symbol ? Symbol.prototype : undefined, + symbolValueOf = symbolProto ? symbolProto.valueOf : undefined; + + /** + * Creates a hash object. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + function Hash(entries) { + var index = -1, + length = entries ? entries.length : 0; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } + } + + /** + * Removes all key-value entries from the hash. + * + * @private + * @name clear + * @memberOf Hash + */ + function hashClear() { + this.__data__ = nativeCreate ? nativeCreate(null) : {}; + } + + /** + * Removes `key` and its value from the hash. + * + * @private + * @name delete + * @memberOf Hash + * @param {Object} hash The hash to modify. + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function hashDelete(key) { + return this.has(key) && delete this.__data__[key]; + } + + /** + * Gets the hash value for `key`. + * + * @private + * @name get + * @memberOf Hash + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function hashGet(key) { + var data = this.__data__; + if (nativeCreate) { + var result = data[key]; + return result === HASH_UNDEFINED ? undefined : result; + } + return hasOwnProperty.call(data, key) ? data[key] : undefined; + } + + /** + * Checks if a hash value for `key` exists. + * + * @private + * @name has + * @memberOf Hash + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function hashHas(key) { + var data = this.__data__; + return nativeCreate ? data[key] !== undefined : hasOwnProperty.call(data, key); + } + + /** + * Sets the hash `key` to `value`. + * + * @private + * @name set + * @memberOf Hash + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the hash instance. + */ + function hashSet(key, value) { + var data = this.__data__; + data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value; + return this; + } + + // Add methods to `Hash`. + Hash.prototype.clear = hashClear; + Hash.prototype['delete'] = hashDelete; + Hash.prototype.get = hashGet; + Hash.prototype.has = hashHas; + Hash.prototype.set = hashSet; + + /** + * Creates an list cache object. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + function ListCache(entries) { + var index = -1, + length = entries ? entries.length : 0; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } + } + + /** + * Removes all key-value entries from the list cache. + * + * @private + * @name clear + * @memberOf ListCache + */ + function listCacheClear() { + this.__data__ = []; + } + + /** + * Removes `key` and its value from the list cache. + * + * @private + * @name delete + * @memberOf ListCache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function listCacheDelete(key) { + var data = this.__data__, + index = assocIndexOf(data, key); + + if (index < 0) { + return false; + } + var lastIndex = data.length - 1; + if (index == lastIndex) { + data.pop(); + } else { + splice.call(data, index, 1); + } + return true; + } + + /** + * Gets the list cache value for `key`. + * + * @private + * @name get + * @memberOf ListCache + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function listCacheGet(key) { + var data = this.__data__, + index = assocIndexOf(data, key); + + return index < 0 ? undefined : data[index][1]; + } + + /** + * Checks if a list cache value for `key` exists. + * + * @private + * @name has + * @memberOf ListCache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function listCacheHas(key) { + return assocIndexOf(this.__data__, key) > -1; + } + + /** + * Sets the list cache `key` to `value`. + * + * @private + * @name set + * @memberOf ListCache + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the list cache instance. + */ + function listCacheSet(key, value) { + var data = this.__data__, + index = assocIndexOf(data, key); + + if (index < 0) { + data.push([key, value]); + } else { + data[index][1] = value; + } + return this; + } + + // Add methods to `ListCache`. + ListCache.prototype.clear = listCacheClear; + ListCache.prototype['delete'] = listCacheDelete; + ListCache.prototype.get = listCacheGet; + ListCache.prototype.has = listCacheHas; + ListCache.prototype.set = listCacheSet; + + /** + * Creates a map cache object to store key-value pairs. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + function MapCache(entries) { + var index = -1, + length = entries ? entries.length : 0; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } + } + + /** + * Removes all key-value entries from the map. + * + * @private + * @name clear + * @memberOf MapCache + */ + function mapCacheClear() { + this.__data__ = { + 'hash': new Hash, + 'map': new (Map || ListCache), + 'string': new Hash + }; + } + + /** + * Removes `key` and its value from the map. + * + * @private + * @name delete + * @memberOf MapCache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function mapCacheDelete(key) { + return getMapData(this, key)['delete'](key); + } + + /** + * Gets the map value for `key`. + * + * @private + * @name get + * @memberOf MapCache + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function mapCacheGet(key) { + return getMapData(this, key).get(key); + } + + /** + * Checks if a map value for `key` exists. + * + * @private + * @name has + * @memberOf MapCache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function mapCacheHas(key) { + return getMapData(this, key).has(key); + } + + /** + * Sets the map `key` to `value`. + * + * @private + * @name set + * @memberOf MapCache + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the map cache instance. + */ + function mapCacheSet(key, value) { + getMapData(this, key).set(key, value); + return this; + } + + // Add methods to `MapCache`. + MapCache.prototype.clear = mapCacheClear; + MapCache.prototype['delete'] = mapCacheDelete; + MapCache.prototype.get = mapCacheGet; + MapCache.prototype.has = mapCacheHas; + MapCache.prototype.set = mapCacheSet; + + /** + * Creates a stack cache object to store key-value pairs. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + function Stack(entries) { + this.__data__ = new ListCache(entries); + } + + /** + * Removes all key-value entries from the stack. + * + * @private + * @name clear + * @memberOf Stack + */ + function stackClear() { + this.__data__ = new ListCache; + } + + /** + * Removes `key` and its value from the stack. + * + * @private + * @name delete + * @memberOf Stack + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function stackDelete(key) { + return this.__data__['delete'](key); + } + + /** + * Gets the stack value for `key`. + * + * @private + * @name get + * @memberOf Stack + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function stackGet(key) { + return this.__data__.get(key); + } + + /** + * Checks if a stack value for `key` exists. + * + * @private + * @name has + * @memberOf Stack + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function stackHas(key) { + return this.__data__.has(key); + } + + /** + * Sets the stack `key` to `value`. + * + * @private + * @name set + * @memberOf Stack + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the stack cache instance. + */ + function stackSet(key, value) { + var cache = this.__data__; + if (cache instanceof ListCache) { + var pairs = cache.__data__; + if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) { + pairs.push([key, value]); + return this; + } + cache = this.__data__ = new MapCache(pairs); + } + cache.set(key, value); + return this; + } + + // Add methods to `Stack`. + Stack.prototype.clear = stackClear; + Stack.prototype['delete'] = stackDelete; + Stack.prototype.get = stackGet; + Stack.prototype.has = stackHas; + Stack.prototype.set = stackSet; + + /** + * Creates an array of the enumerable property names of the array-like `value`. + * + * @private + * @param {*} value The value to query. + * @param {boolean} inherited Specify returning inherited property names. + * @returns {Array} Returns the array of property names. + */ + function arrayLikeKeys(value, inherited) { + // Safari 8.1 makes `arguments.callee` enumerable in strict mode. + // Safari 9 makes `arguments.length` enumerable in strict mode. + var result = (isArray(value) || isArguments(value)) + ? baseTimes(value.length, String) + : []; + + var length = result.length, + skipIndexes = !!length; + + for (var key in value) { + if ((hasOwnProperty.call(value, key)) && + !(skipIndexes && (key == 'length' || isIndex(key, length)))) { + result.push(key); + } + } + return result; + } + + /** + * Assigns `value` to `key` of `object` if the existing value is not equivalent + * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. + * + * @private + * @param {Object} object The object to modify. + * @param {string} key The key of the property to assign. + * @param {*} value The value to assign. + */ + function assignValue(object, key, value) { + var objValue = object[key]; + if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) || + (value === undefined && !(key in object))) { + object[key] = value; + } + } + + /** + * Gets the index at which the `key` is found in `array` of key-value pairs. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} key The key to search for. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function assocIndexOf(array, key) { + var length = array.length; + while (length--) { + if (eq(array[length][0], key)) { + return length; + } + } + return -1; + } + + /** + * The base implementation of `_.assign` without support for multiple sources + * or `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @returns {Object} Returns `object`. + */ + function baseAssign(object, source) { + return object && copyObject(source, keys(source), object); + } + + /** + * The base implementation of `_.clone` and `_.cloneDeep` which tracks + * traversed objects. + * + * @private + * @param {*} value The value to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @param {boolean} [isFull] Specify a clone including symbols. + * @param {Function} [customizer] The function to customize cloning. + * @param {string} [key] The key of `value`. + * @param {Object} [object] The parent object of `value`. + * @param {Object} [stack] Tracks traversed objects and their clone counterparts. + * @returns {*} Returns the cloned value. + */ + function baseClone(value, isDeep, isFull, customizer, key, object, stack) { + var result; + if (customizer) { + result = object ? customizer(value, key, object, stack) : customizer(value); + } + if (result !== undefined) { + return result; + } + if (!isObject(value)) { + return value; + } + var isArr = isArray(value); + if (isArr) { + result = initCloneArray(value); + if (!isDeep) { + return copyArray(value, result); + } + } else { + var tag = getTag(value), + isFunc = tag == funcTag || tag == genTag; + + if (isBuffer(value)) { + return cloneBuffer(value, isDeep); + } + if (tag == objectTag || tag == argsTag || (isFunc && !object)) { + if (isHostObject(value)) { + return object ? value : {}; + } + result = initCloneObject(isFunc ? {} : value); + if (!isDeep) { + return copySymbols(value, baseAssign(result, value)); + } + } else { + if (!cloneableTags[tag]) { + return object ? value : {}; + } + result = initCloneByTag(value, tag, baseClone, isDeep); + } + } + // Check for circular references and return its corresponding clone. + stack || (stack = new Stack); + var stacked = stack.get(value); + if (stacked) { + return stacked; + } + stack.set(value, result); + + if (!isArr) { + var props = isFull ? getAllKeys(value) : keys(value); + } + arrayEach(props || value, function(subValue, key) { + if (props) { + key = subValue; + subValue = value[key]; + } + // Recursively populate clone (susceptible to call stack limits). + assignValue(result, key, baseClone(subValue, isDeep, isFull, customizer, key, value, stack)); + }); + return result; + } + + /** + * The base implementation of `_.create` without support for assigning + * properties to the created object. + * + * @private + * @param {Object} prototype The object to inherit from. + * @returns {Object} Returns the new object. + */ + function baseCreate(proto) { + return isObject(proto) ? objectCreate(proto) : {}; + } + + /** + * The base implementation of `getAllKeys` and `getAllKeysIn` which uses + * `keysFunc` and `symbolsFunc` to get the enumerable property names and + * symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Function} keysFunc The function to get the keys of `object`. + * @param {Function} symbolsFunc The function to get the symbols of `object`. + * @returns {Array} Returns the array of property names and symbols. + */ + function baseGetAllKeys(object, keysFunc, symbolsFunc) { + var result = keysFunc(object); + return isArray(object) ? result : arrayPush(result, symbolsFunc(object)); + } + + /** + * The base implementation of `getTag`. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the `toStringTag`. + */ + function baseGetTag(value) { + return objectToString.call(value); + } + + /** + * The base implementation of `_.isNative` without bad shim checks. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a native function, + * else `false`. + */ + function baseIsNative(value) { + if (!isObject(value) || isMasked(value)) { + return false; + } + var pattern = (isFunction(value) || isHostObject(value)) ? reIsNative : reIsHostCtor; + return pattern.test(toSource(value)); + } + + /** + * The base implementation of `_.keys` which doesn't treat sparse arrays as dense. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ + function baseKeys(object) { + if (!isPrototype(object)) { + return nativeKeys(object); + } + var result = []; + for (var key in Object(object)) { + if (hasOwnProperty.call(object, key) && key != 'constructor') { + result.push(key); + } + } + return result; + } + + /** + * Creates a clone of `buffer`. + * + * @private + * @param {Buffer} buffer The buffer to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Buffer} Returns the cloned buffer. + */ + function cloneBuffer(buffer, isDeep) { + if (isDeep) { + return buffer.slice(); + } + var result = new buffer.constructor(buffer.length); + buffer.copy(result); + return result; + } + + /** + * Creates a clone of `arrayBuffer`. + * + * @private + * @param {ArrayBuffer} arrayBuffer The array buffer to clone. + * @returns {ArrayBuffer} Returns the cloned array buffer. + */ + function cloneArrayBuffer(arrayBuffer) { + var result = new arrayBuffer.constructor(arrayBuffer.byteLength); + new Uint8Array(result).set(new Uint8Array(arrayBuffer)); + return result; + } + + /** + * Creates a clone of `dataView`. + * + * @private + * @param {Object} dataView The data view to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned data view. + */ + function cloneDataView(dataView, isDeep) { + var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer; + return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength); + } + + /** + * Creates a clone of `map`. + * + * @private + * @param {Object} map The map to clone. + * @param {Function} cloneFunc The function to clone values. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned map. + */ + function cloneMap(map, isDeep, cloneFunc) { + var array = isDeep ? cloneFunc(mapToArray(map), true) : mapToArray(map); + return arrayReduce(array, addMapEntry, new map.constructor); + } + + /** + * Creates a clone of `regexp`. + * + * @private + * @param {Object} regexp The regexp to clone. + * @returns {Object} Returns the cloned regexp. + */ + function cloneRegExp(regexp) { + var result = new regexp.constructor(regexp.source, reFlags.exec(regexp)); + result.lastIndex = regexp.lastIndex; + return result; + } + + /** + * Creates a clone of `set`. + * + * @private + * @param {Object} set The set to clone. + * @param {Function} cloneFunc The function to clone values. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned set. + */ + function cloneSet(set, isDeep, cloneFunc) { + var array = isDeep ? cloneFunc(setToArray(set), true) : setToArray(set); + return arrayReduce(array, addSetEntry, new set.constructor); + } + + /** + * Creates a clone of the `symbol` object. + * + * @private + * @param {Object} symbol The symbol object to clone. + * @returns {Object} Returns the cloned symbol object. + */ + function cloneSymbol(symbol) { + return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {}; + } + + /** + * Creates a clone of `typedArray`. + * + * @private + * @param {Object} typedArray The typed array to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned typed array. + */ + function cloneTypedArray(typedArray, isDeep) { + var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer; + return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length); + } + + /** + * Copies the values of `source` to `array`. + * + * @private + * @param {Array} source The array to copy values from. + * @param {Array} [array=[]] The array to copy values to. + * @returns {Array} Returns `array`. + */ + function copyArray(source, array) { + var index = -1, + length = source.length; + + array || (array = Array(length)); + while (++index < length) { + array[index] = source[index]; + } + return array; + } + + /** + * Copies properties of `source` to `object`. + * + * @private + * @param {Object} source The object to copy properties from. + * @param {Array} props The property identifiers to copy. + * @param {Object} [object={}] The object to copy properties to. + * @param {Function} [customizer] The function to customize copied values. + * @returns {Object} Returns `object`. + */ + function copyObject(source, props, object, customizer) { + object || (object = {}); + + var index = -1, + length = props.length; + + while (++index < length) { + var key = props[index]; + + var newValue = undefined; + + assignValue(object, key, newValue === undefined ? source[key] : newValue); + } + return object; + } + + /** + * Copies own symbol properties of `source` to `object`. + * + * @private + * @param {Object} source The object to copy symbols from. + * @param {Object} [object={}] The object to copy symbols to. + * @returns {Object} Returns `object`. + */ + function copySymbols(source, object) { + return copyObject(source, getSymbols(source), object); + } + + /** + * Creates an array of own enumerable property names and symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names and symbols. + */ + function getAllKeys(object) { + return baseGetAllKeys(object, keys, getSymbols); + } + + /** + * Gets the data for `map`. + * + * @private + * @param {Object} map The map to query. + * @param {string} key The reference key. + * @returns {*} Returns the map data. + */ + function getMapData(map, key) { + var data = map.__data__; + return isKeyable(key) + ? data[typeof key == 'string' ? 'string' : 'hash'] + : data.map; + } + + /** + * Gets the native function at `key` of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {string} key The key of the method to get. + * @returns {*} Returns the function if it's native, else `undefined`. + */ + function getNative(object, key) { + var value = getValue(object, key); + return baseIsNative(value) ? value : undefined; + } + + /** + * Creates an array of the own enumerable symbol properties of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. + */ + var getSymbols = nativeGetSymbols ? overArg(nativeGetSymbols, Object) : stubArray; + + /** + * Gets the `toStringTag` of `value`. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the `toStringTag`. + */ + var getTag = baseGetTag; + + // Fallback for data views, maps, sets, and weak maps in IE 11, + // for data views in Edge < 14, and promises in Node.js. + if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) || + (Map && getTag(new Map) != mapTag) || + (Promise && getTag(Promise.resolve()) != promiseTag) || + (Set && getTag(new Set) != setTag) || + (WeakMap && getTag(new WeakMap) != weakMapTag)) { + getTag = function(value) { + var result = objectToString.call(value), + Ctor = result == objectTag ? value.constructor : undefined, + ctorString = Ctor ? toSource(Ctor) : undefined; + + if (ctorString) { + switch (ctorString) { + case dataViewCtorString: return dataViewTag; + case mapCtorString: return mapTag; + case promiseCtorString: return promiseTag; + case setCtorString: return setTag; + case weakMapCtorString: return weakMapTag; + } + } + return result; + }; + } + + /** + * Initializes an array clone. + * + * @private + * @param {Array} array The array to clone. + * @returns {Array} Returns the initialized clone. + */ + function initCloneArray(array) { + var length = array.length, + result = array.constructor(length); + + // Add properties assigned by `RegExp#exec`. + if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) { + result.index = array.index; + result.input = array.input; + } + return result; + } + + /** + * Initializes an object clone. + * + * @private + * @param {Object} object The object to clone. + * @returns {Object} Returns the initialized clone. + */ + function initCloneObject(object) { + return (typeof object.constructor == 'function' && !isPrototype(object)) + ? baseCreate(getPrototype(object)) + : {}; + } + + /** + * Initializes an object clone based on its `toStringTag`. + * + * **Note:** This function only supports cloning values with tags of + * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. + * + * @private + * @param {Object} object The object to clone. + * @param {string} tag The `toStringTag` of the object to clone. + * @param {Function} cloneFunc The function to clone values. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the initialized clone. + */ + function initCloneByTag(object, tag, cloneFunc, isDeep) { + var Ctor = object.constructor; + switch (tag) { + case arrayBufferTag: + return cloneArrayBuffer(object); + + case boolTag: + case dateTag: + return new Ctor(+object); + + case dataViewTag: + return cloneDataView(object, isDeep); + + case float32Tag: case float64Tag: + case int8Tag: case int16Tag: case int32Tag: + case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag: + return cloneTypedArray(object, isDeep); + + case mapTag: + return cloneMap(object, isDeep, cloneFunc); + + case numberTag: + case stringTag: + return new Ctor(object); + + case regexpTag: + return cloneRegExp(object); + + case setTag: + return cloneSet(object, isDeep, cloneFunc); + + case symbolTag: + return cloneSymbol(object); + } + } + + /** + * Checks if `value` is a valid array-like index. + * + * @private + * @param {*} value The value to check. + * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. + * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. + */ + function isIndex(value, length) { + length = length == null ? MAX_SAFE_INTEGER : length; + return !!length && + (typeof value == 'number' || reIsUint.test(value)) && + (value > -1 && value % 1 == 0 && value < length); + } + + /** + * Checks if `value` is suitable for use as unique object key. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is suitable, else `false`. + */ + function isKeyable(value) { + var type = typeof value; + return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean') + ? (value !== '__proto__') + : (value === null); + } + + /** + * Checks if `func` has its source masked. + * + * @private + * @param {Function} func The function to check. + * @returns {boolean} Returns `true` if `func` is masked, else `false`. + */ + function isMasked(func) { + return !!maskSrcKey && (maskSrcKey in func); + } + + /** + * Checks if `value` is likely a prototype object. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a prototype, else `false`. + */ + function isPrototype(value) { + var Ctor = value && value.constructor, + proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto; + + return value === proto; + } + + /** + * Converts `func` to its source code. + * + * @private + * @param {Function} func The function to process. + * @returns {string} Returns the source code. + */ + function toSource(func) { + if (func != null) { + try { + return funcToString.call(func); + } catch (e) {} + try { + return (func + ''); + } catch (e) {} + } + return ''; + } + + /** + * This method is like `_.clone` except that it recursively clones `value`. + * + * @static + * @memberOf _ + * @since 1.0.0 + * @category Lang + * @param {*} value The value to recursively clone. + * @returns {*} Returns the deep cloned value. + * @see _.clone + * @example + * + * var objects = [{ 'a': 1 }, { 'b': 2 }]; + * + * var deep = _.cloneDeep(objects); + * console.log(deep[0] === objects[0]); + * // => false + */ + function cloneDeep(value) { + return baseClone(value, true, true); + } + + /** + * Performs a + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * comparison between two values to determine if they are equivalent. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'a': 1 }; + * var other = { 'a': 1 }; + * + * _.eq(object, object); + * // => true + * + * _.eq(object, other); + * // => false + * + * _.eq('a', 'a'); + * // => true + * + * _.eq('a', Object('a')); + * // => false + * + * _.eq(NaN, NaN); + * // => true + */ + function eq(value, other) { + return value === other || (value !== value && other !== other); + } + + /** + * Checks if `value` is likely an `arguments` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an `arguments` object, + * else `false`. + * @example + * + * _.isArguments(function() { return arguments; }()); + * // => true + * + * _.isArguments([1, 2, 3]); + * // => false + */ + function isArguments(value) { + // Safari 8.1 makes `arguments.callee` enumerable in strict mode. + return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') && + (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag); + } + + /** + * Checks if `value` is classified as an `Array` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array, else `false`. + * @example + * + * _.isArray([1, 2, 3]); + * // => true + * + * _.isArray(document.body.children); + * // => false + * + * _.isArray('abc'); + * // => false + * + * _.isArray(_.noop); + * // => false + */ + var isArray = Array.isArray; + + /** + * Checks if `value` is array-like. A value is considered array-like if it's + * not a function and has a `value.length` that's an integer greater than or + * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is array-like, else `false`. + * @example + * + * _.isArrayLike([1, 2, 3]); + * // => true + * + * _.isArrayLike(document.body.children); + * // => true + * + * _.isArrayLike('abc'); + * // => true + * + * _.isArrayLike(_.noop); + * // => false + */ + function isArrayLike(value) { + return value != null && isLength(value.length) && !isFunction(value); + } + + /** + * This method is like `_.isArrayLike` except that it also checks if `value` + * is an object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array-like object, + * else `false`. + * @example + * + * _.isArrayLikeObject([1, 2, 3]); + * // => true + * + * _.isArrayLikeObject(document.body.children); + * // => true + * + * _.isArrayLikeObject('abc'); + * // => false + * + * _.isArrayLikeObject(_.noop); + * // => false + */ + function isArrayLikeObject(value) { + return isObjectLike(value) && isArrayLike(value); + } + + /** + * Checks if `value` is a buffer. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a buffer, else `false`. + * @example + * + * _.isBuffer(new Buffer(2)); + * // => true + * + * _.isBuffer(new Uint8Array(2)); + * // => false + */ + var isBuffer = nativeIsBuffer || stubFalse; + + /** + * Checks if `value` is classified as a `Function` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a function, else `false`. + * @example + * + * _.isFunction(_); + * // => true + * + * _.isFunction(/abc/); + * // => false + */ + function isFunction(value) { + // The use of `Object#toString` avoids issues with the `typeof` operator + // in Safari 8-9 which returns 'object' for typed array and other constructors. + var tag = isObject(value) ? objectToString.call(value) : ''; + return tag == funcTag || tag == genTag; + } + + /** + * Checks if `value` is a valid array-like length. + * + * **Note:** This method is loosely based on + * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. + * @example + * + * _.isLength(3); + * // => true + * + * _.isLength(Number.MIN_VALUE); + * // => false + * + * _.isLength(Infinity); + * // => false + * + * _.isLength('3'); + * // => false + */ + function isLength(value) { + return typeof value == 'number' && + value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; + } + + /** + * Checks if `value` is the + * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) + * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(_.noop); + * // => true + * + * _.isObject(null); + * // => false + */ + function isObject(value) { + var type = typeof value; + return !!value && (type == 'object' || type == 'function'); + } + + /** + * Checks if `value` is object-like. A value is object-like if it's not `null` + * and has a `typeof` result of "object". + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @example + * + * _.isObjectLike({}); + * // => true + * + * _.isObjectLike([1, 2, 3]); + * // => true + * + * _.isObjectLike(_.noop); + * // => false + * + * _.isObjectLike(null); + * // => false + */ + function isObjectLike(value) { + return !!value && typeof value == 'object'; + } + + /** + * Creates an array of the own enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. See the + * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) + * for more details. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keys(new Foo); + * // => ['a', 'b'] (iteration order is not guaranteed) + * + * _.keys('hi'); + * // => ['0', '1'] + */ + function keys(object) { + return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object); + } + + /** + * This method returns a new empty array. + * + * @static + * @memberOf _ + * @since 4.13.0 + * @category Util + * @returns {Array} Returns the new empty array. + * @example + * + * var arrays = _.times(2, _.stubArray); + * + * console.log(arrays); + * // => [[], []] + * + * console.log(arrays[0] === arrays[1]); + * // => false + */ + function stubArray() { + return []; + } + + /** + * This method returns `false`. + * + * @static + * @memberOf _ + * @since 4.13.0 + * @category Util + * @returns {boolean} Returns `false`. + * @example + * + * _.times(2, _.stubFalse); + * // => [false, false] + */ + function stubFalse() { + return false; + } + + module.exports = cloneDeep; + } (lodash_clonedeep, lodash_clonedeep.exports)); + + var lodash_clonedeepExports = lodash_clonedeep.exports; + var cloneDeep = /*@__PURE__*/getDefaultExportFromCjs$1(lodash_clonedeepExports); + + function applyContextDelta(context, delta, logger) { + try { + if (logger?.canPublish("trace")) { + logger?.trace(`applying context delta ${JSON.stringify(delta)} on context ${JSON.stringify(context)}`); + } + if (!delta) { + return context; + } + if (delta.reset) { + context = { ...delta.reset }; + return context; + } + context = deepClone(context, undefined); + if (delta.commands) { + for (const command of delta.commands) { + if (command.type === "remove") { + deletePath(context, command.path); + } + else if (command.type === "set") { + setValueToPath(context, command.value, command.path); + } + } + return context; + } + const added = delta.added; + const updated = delta.updated; + const removed = delta.removed; + if (added) { + Object.keys(added).forEach((key) => { + context[key] = added[key]; + }); + } + if (updated) { + Object.keys(updated).forEach((key) => { + mergeObjectsProperties(key, context, updated); + }); + } + if (removed) { + removed.forEach((key) => { + delete context[key]; + }); + } + return context; + } + catch (e) { + logger?.error(`error applying context delta ${JSON.stringify(delta)} on context ${JSON.stringify(context)}`, e); + return context; + } + } + function deepClone(obj, hash) { + return cloneDeep(obj); + } + const mergeObjectsProperties = (key, what, withWhat) => { + const right = withWhat[key]; + if (right === undefined) { + return what; + } + const left = what[key]; + if (!left || !right) { + what[key] = right; + return what; + } + if (typeof left === "string" || + typeof left === "number" || + typeof left === "boolean" || + typeof right === "string" || + typeof right === "number" || + typeof right === "boolean" || + Array.isArray(left) || + Array.isArray(right)) { + what[key] = right; + return what; + } + what[key] = Object.assign({}, left, right); + return what; + }; + function deepEqual(x, y) { + if (x === y) { + return true; + } + if (!(x instanceof Object) || !(y instanceof Object)) { + return false; + } + if (x.constructor !== y.constructor) { + return false; + } + for (const p in x) { + if (!x.hasOwnProperty(p)) { + continue; + } + if (!y.hasOwnProperty(p)) { + return false; + } + if (x[p] === y[p]) { + continue; + } + if (typeof (x[p]) !== "object") { + return false; + } + if (!deepEqual(x[p], y[p])) { + return false; + } + } + for (const p in y) { + if (y.hasOwnProperty(p) && !x.hasOwnProperty(p)) { + return false; + } + } + return true; + } + function setValueToPath(obj, value, path) { + const pathArr = path.split("."); + let i; + for (i = 0; i < pathArr.length - 1; i++) { + if (!obj[pathArr[i]]) { + obj[pathArr[i]] = {}; + } + if (typeof obj[pathArr[i]] !== "object") { + obj[pathArr[i]] = {}; + } + obj = obj[pathArr[i]]; + } + obj[pathArr[i]] = value; + } + function isSubset(superObj, subObj) { + return Object.keys(subObj).every((ele) => { + if (typeof subObj[ele] === "object") { + return isSubset(superObj?.[ele] || {}, subObj[ele] || {}); + } + return subObj[ele] === superObj?.[ele]; + }); + } + function deletePath(obj, path) { + const pathArr = path.split("."); + let i; + for (i = 0; i < pathArr.length - 1; i++) { + if (!obj[pathArr[i]]) { + return; + } + obj = obj[pathArr[i]]; + } + delete obj[pathArr[i]]; + } + + let GW3Bridge$1 = class GW3Bridge { + _logger; + _connection; + _trackAllContexts; + _reAnnounceKnownContexts; + _gw3Session; + _contextNameToData = {}; + _gw3Subscriptions = []; + _nextCallbackSubscriptionNumber = 0; + _creationPromises = {}; + _contextNameToId = {}; + _contextIdToName = {}; + _protocolVersion = undefined; + _contextsTempCache = {}; + _contextsSubscriptionsCache = []; + _systemContextsSubKey; + get protocolVersion() { + if (!this._protocolVersion) { + const contextsDomainInfo = this._connection.availableDomains.find((d) => d.uri === "context"); + this._protocolVersion = contextsDomainInfo?.version ?? 1; + } + return this._protocolVersion; + } + get setPathSupported() { + return this.protocolVersion >= 2; + } + constructor(config) { + this._connection = config.connection; + this._logger = config.logger; + this._trackAllContexts = config.trackAllContexts; + this._reAnnounceKnownContexts = config.reAnnounceKnownContexts; + this._gw3Session = this._connection.domain("global", [ + GW_MESSAGE_CONTEXT_CREATED, + GW_MESSAGE_SUBSCRIBED_CONTEXT, + GW_MESSAGE_CONTEXT_DESTROYED, + GW_MESSAGE_CONTEXT_UPDATED, + ]); + this._gw3Session.disconnected(this.resetState.bind(this)); + this._gw3Session.onJoined((wasReconnect) => { + if (!wasReconnect) { + return; + } + if (!this._reAnnounceKnownContexts) { + return this._connection.setLibReAnnounced({ name: "contexts" }); + } + this.reInitiateState().then(() => this._connection.setLibReAnnounced({ name: "contexts" })); + }); + this.subscribeToContextCreatedMessages(); + this.subscribeToContextUpdatedMessages(); + this.subscribeToContextDestroyedMessages(); + this._connection.replayer?.drain(ContextMessageReplaySpec.name, (message) => { + const type = message.type; + if (!type) { + return; + } + if (type === GW_MESSAGE_CONTEXT_CREATED || + type === GW_MESSAGE_CONTEXT_ADDED || + type === GW_MESSAGE_ACTIVITY_CREATED) { + this.handleContextCreatedMessage(message); + } + else if (type === GW_MESSAGE_SUBSCRIBED_CONTEXT || + type === GW_MESSAGE_CONTEXT_UPDATED || + type === GW_MESSAGE_JOINED_ACTIVITY) { + this.handleContextUpdatedMessage(message); + } + else if (type === GW_MESSAGE_CONTEXT_DESTROYED || + type === GW_MESSAGE_ACTIVITY_DESTROYED) { + this.handleContextDestroyedMessage(message); + } + }); + } + dispose() { + for (const sub of this._gw3Subscriptions) { + this._connection.off(sub); + } + this._gw3Subscriptions.length = 0; + for (const contextName in this._contextNameToData) { + if (this._contextNameToId.hasOwnProperty(contextName)) { + delete this._contextNameToData[contextName]; + } + } + } + createContext(name, data) { + if (name in this._creationPromises) { + return this._creationPromises[name]; + } + this._creationPromises[name] = + this._gw3Session + .send({ + type: GW_MESSAGE_CREATE_CONTEXT, + domain: "global", + name, + data, + lifetime: "retained", + }) + .then((createContextMsg) => { + this._contextNameToId[name] = createContextMsg.context_id; + this._contextIdToName[createContextMsg.context_id] = name; + const contextData = this._contextNameToData[name] || new GW3ContextData(createContextMsg.context_id, name, true, undefined); + contextData.isAnnounced = true; + contextData.name = name; + contextData.contextId = createContextMsg.context_id; + contextData.context = createContextMsg.data || deepClone(data); + contextData.hasReceivedSnapshot = true; + this._contextNameToData[name] = contextData; + delete this._creationPromises[name]; + return createContextMsg.context_id; + }); + return this._creationPromises[name]; + } + all() { + return Object.keys(this._contextNameToData) + .filter((name) => this._contextNameToData[name].isAnnounced); + } + async update(name, delta) { + if (delta) { + delta = deepClone(delta); + } + if (name in this._creationPromises) { + await this._creationPromises[name]; + } + const contextData = this._contextNameToData[name]; + if (!contextData || !contextData.isAnnounced) { + return this.createContext(name, delta); + } + let currentContext = contextData.context; + if (!contextData.hasCallbacks()) { + currentContext = await this.get(contextData.name); + } + const calculatedDelta = this.setPathSupported ? + this.calculateContextDeltaV2(currentContext, delta) : + this.calculateContextDeltaV1(currentContext, delta); + if (!Object.keys(calculatedDelta.added).length + && !Object.keys(calculatedDelta.updated).length + && !calculatedDelta.removed.length + && !calculatedDelta.commands?.length) { + return Promise.resolve(); + } + return this._gw3Session + .send({ + type: GW_MESSAGE_UPDATE_CONTEXT, + domain: "global", + context_id: contextData.contextId, + delta: calculatedDelta, + }, {}, { skipPeerId: false }) + .then((gwResponse) => { + this.handleUpdated(contextData, calculatedDelta, { + updaterId: gwResponse.peer_id + }); + }); + } + async set(name, data) { + if (data) { + data = deepClone(data); + } + if (name in this._creationPromises) { + await this._creationPromises[name]; + } + const contextData = this._contextNameToData[name]; + if (!contextData || !contextData.isAnnounced) { + return this.createContext(name, data); + } + return this._gw3Session + .send({ + type: GW_MESSAGE_UPDATE_CONTEXT, + domain: "global", + context_id: contextData.contextId, + delta: { reset: data }, + }, {}, { skipPeerId: false }) + .then((gwResponse) => { + this.handleUpdated(contextData, { + reset: data, + added: {}, + removed: [], + updated: {} + }, { + updaterId: gwResponse.peer_id + }); + }); + } + setPath(name, path, value) { + if (!this.setPathSupported) { + return Promise.reject("glue.contexts.setPath operation is not supported, use Glue42 3.10 or later"); + } + return this.setPaths(name, [{ path, value }]); + } + async setPaths(name, pathValues) { + if (!this.setPathSupported) { + return Promise.reject("glue.contexts.setPaths operation is not supported, use Glue42 3.10 or later"); + } + if (pathValues) { + pathValues = deepClone(pathValues); + } + if (name in this._creationPromises) { + await this._creationPromises[name]; + } + const contextData = this._contextNameToData[name]; + if (!contextData || !contextData.isAnnounced) { + const obj = {}; + for (const pathValue of pathValues) { + setValueToPath(obj, pathValue.value, pathValue.path); + } + return this.createContext(name, obj); + } + const commands = []; + for (const pathValue of pathValues) { + if (pathValue.value === null) { + commands.push({ type: "remove", path: pathValue.path }); + } + else { + commands.push({ type: "set", path: pathValue.path, value: pathValue.value }); + } + } + return this._gw3Session + .send({ + type: GW_MESSAGE_UPDATE_CONTEXT, + domain: "global", + context_id: contextData.contextId, + delta: { commands } + }, {}, { skipPeerId: false }) + .then((gwResponse) => { + this.handleUpdated(contextData, { + added: {}, + removed: [], + updated: {}, + commands + }, { + updaterId: gwResponse.peer_id + }); + }); + } + async get(name) { + if (name in this._creationPromises) { + await this._creationPromises[name]; + } + const contextData = this._contextNameToData[name]; + if (!contextData || !contextData.isAnnounced) { + return Promise.resolve({}); + } + if (contextData && (!contextData.hasCallbacks() || !contextData.hasReceivedSnapshot)) { + return new Promise((resolve) => { + this.subscribe(name, (data, _d, _r, un) => { + this.unsubscribe(un); + resolve(data); + }); + }); + } + const context = contextData?.context ?? {}; + return Promise.resolve(deepClone(context)); + } + async subscribe(name, callback, subscriptionKey) { + if (name in this._creationPromises) { + await this._creationPromises[name]; + } + const thisCallbackSubscriptionNumber = typeof subscriptionKey === "undefined" ? this._nextCallbackSubscriptionNumber : subscriptionKey; + if (typeof subscriptionKey === "undefined") { + this._nextCallbackSubscriptionNumber += 1; + } + if (this._contextsSubscriptionsCache.every((subscription) => subscription.subKey !== this._nextCallbackSubscriptionNumber)) { + this._contextsSubscriptionsCache.push({ contextName: name, subKey: thisCallbackSubscriptionNumber, callback }); + } + let contextData = this._contextNameToData[name]; + if (!contextData || + !contextData.isAnnounced) { + contextData = contextData || new GW3ContextData(undefined, name, false, undefined); + this._contextNameToData[name] = contextData; + contextData.updateCallbacks[thisCallbackSubscriptionNumber] = callback; + return Promise.resolve(thisCallbackSubscriptionNumber); + } + const hadCallbacks = contextData.hasCallbacks(); + contextData.updateCallbacks[thisCallbackSubscriptionNumber] = callback; + if (!hadCallbacks) { + if (!contextData.joinedActivity) { + if (contextData.context && contextData.sentExplicitSubscription) { + if (contextData.hasReceivedSnapshot) { + const clone = deepClone(contextData.context); + callback(clone, clone, [], thisCallbackSubscriptionNumber); + } + return Promise.resolve(thisCallbackSubscriptionNumber); + } + return this.sendSubscribe(contextData) + .then(() => thisCallbackSubscriptionNumber); + } + else { + if (contextData.hasReceivedSnapshot) { + const clone = deepClone(contextData.context); + callback(clone, clone, [], thisCallbackSubscriptionNumber); + } + return Promise.resolve(thisCallbackSubscriptionNumber); + } + } + else { + if (contextData.hasReceivedSnapshot) { + const clone = deepClone(contextData.context); + callback(clone, clone, [], thisCallbackSubscriptionNumber); + } + return Promise.resolve(thisCallbackSubscriptionNumber); + } + } + unsubscribe(subscriptionKey) { + this._contextsSubscriptionsCache = this._contextsSubscriptionsCache.filter((subscription) => subscription.subKey !== subscriptionKey); + for (const name of Object.keys(this._contextNameToData)) { + const contextData = this._contextNameToData[name]; + if (!contextData) { + return; + } + const hadCallbacks = contextData.hasCallbacks(); + delete contextData.updateCallbacks[subscriptionKey]; + if (contextData.isAnnounced && + hadCallbacks && + !contextData.hasCallbacks() && + contextData.sentExplicitSubscription) { + this.sendUnsubscribe(contextData).catch(() => { }); + } + if (!contextData.isAnnounced && + !contextData.hasCallbacks()) { + delete this._contextNameToData[name]; + } + } + } + async destroy(name) { + if (name in this._creationPromises) { + await this._creationPromises[name]; + } + const contextData = this._contextNameToData[name]; + if (!contextData) { + return Promise.reject(`context with ${name} does not exist`); + } + return this._gw3Session + .send({ + type: GW_MESSAGE_DESTROY_CONTEXT, + domain: "global", + context_id: contextData.contextId, + }).then((_) => undefined); + } + handleUpdated(contextData, delta, extraData) { + const oldContext = contextData.context; + contextData.context = applyContextDelta(contextData.context, delta, this._logger); + contextData.hasReceivedSnapshot = true; + if (this._contextNameToData[contextData.name] === contextData && + !deepEqual(oldContext, contextData.context)) { + this.invokeUpdateCallbacks(contextData, delta, extraData); + } + } + subscribeToContextCreatedMessages() { + const createdMessageTypes = [ + GW_MESSAGE_CONTEXT_ADDED, + GW_MESSAGE_CONTEXT_CREATED, + GW_MESSAGE_ACTIVITY_CREATED, + ]; + for (const createdMessageType of createdMessageTypes) { + const sub = this._connection.on(createdMessageType, this.handleContextCreatedMessage.bind(this)); + this._gw3Subscriptions.push(sub); + } + } + handleContextCreatedMessage(contextCreatedMsg) { + const createdMessageType = contextCreatedMsg.type; + if (createdMessageType === GW_MESSAGE_ACTIVITY_CREATED) { + this._contextNameToId[contextCreatedMsg.activity_id] = contextCreatedMsg.context_id; + this._contextIdToName[contextCreatedMsg.context_id] = contextCreatedMsg.activity_id; + } + else if (createdMessageType === GW_MESSAGE_CONTEXT_ADDED) { + this._contextNameToId[contextCreatedMsg.name] = contextCreatedMsg.context_id; + this._contextIdToName[contextCreatedMsg.context_id] = contextCreatedMsg.name; + } + else ; + const name = this._contextIdToName[contextCreatedMsg.context_id]; + if (!name) { + throw new Error("Received created event for context with unknown name: " + contextCreatedMsg.context_id); + } + if (!this._contextNameToId[name]) { + throw new Error("Received created event for context with unknown id: " + contextCreatedMsg.context_id); + } + let contextData = this._contextNameToData[name]; + if (contextData) { + if (contextData.isAnnounced) { + return; + } + else { + if (!contextData.hasCallbacks()) { + throw new Error("Assertion failure: contextData.hasCallbacks()"); + } + contextData.isAnnounced = true; + contextData.contextId = contextCreatedMsg.context_id; + contextData.activityId = contextCreatedMsg.activity_id; + if (!contextData.sentExplicitSubscription) { + this.sendSubscribe(contextData); + } + } + } + else { + this._contextNameToData[name] = contextData = + new GW3ContextData(contextCreatedMsg.context_id, name, true, contextCreatedMsg.activity_id); + if (this._trackAllContexts) { + this.subscribe(name, () => { }).then((subKey) => this._systemContextsSubKey = subKey); + } + } + } + subscribeToContextUpdatedMessages() { + const updatedMessageTypes = [ + GW_MESSAGE_CONTEXT_UPDATED, + GW_MESSAGE_SUBSCRIBED_CONTEXT, + GW_MESSAGE_JOINED_ACTIVITY, + ]; + for (const updatedMessageType of updatedMessageTypes) { + const sub = this._connection.on(updatedMessageType, this.handleContextUpdatedMessage.bind(this)); + this._gw3Subscriptions.push(sub); + } + } + handleContextUpdatedMessage(contextUpdatedMsg) { + const updatedMessageType = contextUpdatedMsg.type; + const contextId = contextUpdatedMsg.context_id; + let contextData = this._contextNameToData[this._contextIdToName[contextId]]; + const justSeen = !contextData || !contextData.isAnnounced; + if (updatedMessageType === GW_MESSAGE_JOINED_ACTIVITY) { + if (!contextData) { + contextData = + this._contextNameToData[contextUpdatedMsg.activity_id] || + new GW3ContextData(contextId, contextUpdatedMsg.activity_id, true, contextUpdatedMsg.activity_id); + } + this._contextNameToData[contextUpdatedMsg.activity_id] = contextData; + this._contextIdToName[contextId] = contextUpdatedMsg.activity_id; + this._contextNameToId[contextUpdatedMsg.activity_id] = contextId; + contextData.contextId = contextId; + contextData.isAnnounced = true; + contextData.activityId = contextUpdatedMsg.activity_id; + contextData.joinedActivity = true; + } + else { + if (!contextData || !contextData.isAnnounced) { + if (updatedMessageType === GW_MESSAGE_SUBSCRIBED_CONTEXT) { + contextData = contextData || new GW3ContextData(contextId, contextUpdatedMsg.name, true, undefined); + contextData.sentExplicitSubscription = true; + this._contextNameToData[contextUpdatedMsg.name] = contextData; + this._contextIdToName[contextId] = contextUpdatedMsg.name; + this._contextNameToId[contextUpdatedMsg.name] = contextId; + } + else { + this._logger.error(`Received 'update' for unknown context: ${contextId}`); + } + return; + } + } + const oldContext = contextData.context; + contextData.hasReceivedSnapshot = true; + if (updatedMessageType === GW_MESSAGE_SUBSCRIBED_CONTEXT) { + contextData.context = contextUpdatedMsg.data || {}; + } + else if (updatedMessageType === GW_MESSAGE_JOINED_ACTIVITY) { + contextData.context = contextUpdatedMsg.context_snapshot || {}; + } + else if (updatedMessageType === GW_MESSAGE_CONTEXT_UPDATED) { + contextData.context = applyContextDelta(contextData.context, contextUpdatedMsg.delta, this._logger); + } + else { + throw new Error("Unrecognized context update message " + updatedMessageType); + } + if (justSeen || + !deepEqual(contextData.context, oldContext) || + updatedMessageType === GW_MESSAGE_SUBSCRIBED_CONTEXT) { + this.invokeUpdateCallbacks(contextData, contextUpdatedMsg.delta, { updaterId: contextUpdatedMsg.updater_id }); + } + } + invokeUpdateCallbacks(contextData, delta, extraData) { + delta = delta || { added: {}, updated: {}, reset: {}, removed: [] }; + if (delta.commands) { + delta.added = delta.updated = delta.reset = {}; + delta.removed = []; + for (const command of delta.commands) { + if (command.type === "remove") { + if (command.path.indexOf(".") === -1) { + delta.removed.push(command.path); + } + setValueToPath(delta.updated, null, command.path); + } + else if (command.type === "set") { + setValueToPath(delta.updated, command.value, command.path); + } + } + } + for (const updateCallbackIndex in contextData.updateCallbacks) { + if (contextData.updateCallbacks.hasOwnProperty(updateCallbackIndex)) { + try { + const updateCallback = contextData.updateCallbacks[updateCallbackIndex]; + updateCallback(deepClone(contextData.context), deepClone(Object.assign({}, delta.added || {}, delta.updated || {}, delta.reset || {})), delta.removed, parseInt(updateCallbackIndex, 10), extraData); + } + catch (err) { + this._logger.debug("callback error: " + JSON.stringify(err)); + } + } + } + } + subscribeToContextDestroyedMessages() { + const destroyedMessageTypes = [ + GW_MESSAGE_CONTEXT_DESTROYED, + GW_MESSAGE_ACTIVITY_DESTROYED, + ]; + for (const destroyedMessageType of destroyedMessageTypes) { + const sub = this._connection.on(destroyedMessageType, this.handleContextDestroyedMessage.bind(this)); + this._gw3Subscriptions.push(sub); + } + } + handleContextDestroyedMessage(destroyedMsg) { + const destroyedMessageType = destroyedMsg.type; + let contextId; + let name; + if (destroyedMessageType === GW_MESSAGE_ACTIVITY_DESTROYED) { + name = destroyedMsg.activity_id; + contextId = this._contextNameToId[name]; + if (!contextId) { + this._logger.error(`Received 'destroyed' for unknown activity: ${destroyedMsg.activity_id}`); + return; + } + } + else { + contextId = destroyedMsg.context_id; + name = this._contextIdToName[contextId]; + if (!name) { + this._logger.error(`Received 'destroyed' for unknown context: ${destroyedMsg.context_id}`); + return; + } + } + delete this._contextIdToName[contextId]; + delete this._contextNameToId[name]; + const contextData = this._contextNameToData[name]; + delete this._contextNameToData[name]; + if (!contextData || !contextData.isAnnounced) { + this._logger.error(`Received 'destroyed' for unknown context: ${contextId}`); + return; + } + } + sendSubscribe(contextData) { + contextData.sentExplicitSubscription = true; + return this._gw3Session + .send({ + type: GW_MESSAGE_SUBSCRIBE_CONTEXT, + domain: "global", + context_id: contextData.contextId, + }).then((_) => undefined); + } + sendUnsubscribe(contextData) { + contextData.sentExplicitSubscription = false; + return this._gw3Session + .send({ + type: GW_MESSAGE_UNSUBSCRIBE_CONTEXT, + domain: "global", + context_id: contextData.contextId, + }).then((_) => undefined); + } + calculateContextDeltaV1(from, to) { + const delta = { added: {}, updated: {}, removed: [], reset: undefined }; + if (from) { + for (const x of Object.keys(from)) { + if (Object.keys(to).indexOf(x) !== -1 + && to[x] !== null + && !deepEqual(from[x], to[x])) { + delta.updated[x] = to[x]; + } + } + } + for (const x of Object.keys(to)) { + if (!from || (Object.keys(from).indexOf(x) === -1)) { + if (to[x] !== null) { + delta.added[x] = to[x]; + } + } + else if (to[x] === null) { + delta.removed.push(x); + } + } + return delta; + } + calculateContextDeltaV2(from, to) { + const delta = { added: {}, updated: {}, removed: [], reset: undefined, commands: [] }; + for (const x of Object.keys(to)) { + if (to[x] !== null) { + const fromX = from ? from[x] : null; + if (!deepEqual(fromX, to[x])) { + delta.commands?.push({ type: "set", path: x, value: to[x] }); + } + } + else { + delta.commands?.push({ type: "remove", path: x }); + } + } + return delta; + } + resetState() { + for (const sub of this._gw3Subscriptions) { + this._connection.off(sub); + } + if (this._systemContextsSubKey) { + this.unsubscribe(this._systemContextsSubKey); + delete this._systemContextsSubKey; + } + this._gw3Subscriptions = []; + this._contextNameToId = {}; + this._contextIdToName = {}; + delete this._protocolVersion; + this._contextsTempCache = Object.keys(this._contextNameToData).reduce((cacheSoFar, ctxName) => { + const contextData = this._contextNameToData[ctxName]; + if (contextData.isAnnounced && (contextData.activityId || contextData.sentExplicitSubscription)) { + cacheSoFar[ctxName] = this._contextNameToData[ctxName].context; + } + return cacheSoFar; + }, {}); + this._contextNameToData = {}; + } + async reInitiateState() { + this.subscribeToContextCreatedMessages(); + this.subscribeToContextUpdatedMessages(); + this.subscribeToContextDestroyedMessages(); + this._connection.replayer?.drain(ContextMessageReplaySpec.name, (message) => { + const type = message.type; + if (!type) { + return; + } + if (type === GW_MESSAGE_CONTEXT_CREATED || + type === GW_MESSAGE_CONTEXT_ADDED || + type === GW_MESSAGE_ACTIVITY_CREATED) { + this.handleContextCreatedMessage(message); + } + else if (type === GW_MESSAGE_SUBSCRIBED_CONTEXT || + type === GW_MESSAGE_CONTEXT_UPDATED || + type === GW_MESSAGE_JOINED_ACTIVITY) { + this.handleContextUpdatedMessage(message); + } + else if (type === GW_MESSAGE_CONTEXT_DESTROYED || + type === GW_MESSAGE_ACTIVITY_DESTROYED) { + this.handleContextDestroyedMessage(message); + } + }); + await Promise.all(this._contextsSubscriptionsCache.map((subscription) => this.subscribe(subscription.contextName, subscription.callback, subscription.subKey))); + await this.flushQueue(); + for (const ctxName in this._contextsTempCache) { + if (typeof this._contextsTempCache[ctxName] !== "object" || Object.keys(this._contextsTempCache[ctxName]).length === 0) { + continue; + } + const lastKnownData = this._contextsTempCache[ctxName]; + this._logger.info(`Re-announcing known context: ${ctxName}`); + await this.flushQueue(); + await this.update(ctxName, lastKnownData); + } + this._contextsTempCache = {}; + this._logger.info("Contexts are re-announced"); + } + flushQueue() { + return new Promise((resolve) => setTimeout(() => resolve(), 0)); + } + }; + + class ContextsModule { + initTime; + initStartTime; + initEndTime; + _bridge; + constructor(config) { + this._bridge = new GW3Bridge$1(config); + } + all() { + return this._bridge.all(); + } + update(name, data) { + this.checkName(name); + this.checkData(data); + return this._bridge.update(name, data); + } + set(name, data) { + this.checkName(name); + this.checkData(data); + return this._bridge.set(name, data); + } + setPath(name, path, data) { + this.checkName(name); + this.checkPath(path); + const isTopLevelPath = path === ""; + if (isTopLevelPath) { + this.checkData(data); + return this.set(name, data); + } + return this._bridge.setPath(name, path, data); + } + setPaths(name, paths) { + this.checkName(name); + if (!Array.isArray(paths)) { + throw new Error("Please provide the paths as an array of PathValues!"); + } + for (const { path, value } of paths) { + this.checkPath(path); + const isTopLevelPath = path === ""; + if (isTopLevelPath) { + this.checkData(value); + } + } + return this._bridge.setPaths(name, paths); + } + subscribe(name, callback) { + this.checkName(name); + if (typeof callback !== "function") { + throw new Error("Please provide the callback as a function!"); + } + return this._bridge + .subscribe(name, (data, delta, removed, key, extraData) => callback(data, delta, removed, () => this._bridge.unsubscribe(key), extraData)) + .then((key) => () => { + this._bridge.unsubscribe(key); + }); + } + get(name) { + this.checkName(name); + return this._bridge.get(name); + } + ready() { + return Promise.resolve(this); + } + destroy(name) { + this.checkName(name); + return this._bridge.destroy(name); + } + get setPathSupported() { + return this._bridge.setPathSupported; + } + checkName(name) { + if (typeof name !== "string" || name === "") { + throw new Error("Please provide the name as a non-empty string!"); + } + } + checkPath(path) { + if (typeof path !== "string") { + throw new Error("Please provide the path as a dot delimited string!"); + } + } + checkData(data) { + if (typeof data !== "object") { + throw new Error("Please provide the data as an object!"); + } + } + } + + function promisify$2 (promise, successCallback, errorCallback) { + if (typeof successCallback !== "function" && typeof errorCallback !== "function") { + return promise; + } + if (typeof successCallback !== "function") { + successCallback = () => { }; + } + else if (typeof errorCallback !== "function") { + errorCallback = () => { }; + } + return promise.then(successCallback, errorCallback); + } + + function rejectAfter(ms = 0, promise, error) { + let timeout; + const clearTimeoutIfThere = () => { + if (timeout) { + clearTimeout(timeout); + } + }; + promise + .then(() => { + clearTimeoutIfThere(); + }) + .catch(() => { + clearTimeoutIfThere(); + }); + return new Promise((resolve, reject) => { + timeout = setTimeout(() => reject(error), ms); + }); + } + + var InvokeStatus; + (function (InvokeStatus) { + InvokeStatus[InvokeStatus["Success"] = 0] = "Success"; + InvokeStatus[InvokeStatus["Error"] = 1] = "Error"; + })(InvokeStatus || (InvokeStatus = {})); + class Client { + protocol; + repo; + instance; + configuration; + constructor(protocol, repo, instance, configuration) { + this.protocol = protocol; + this.repo = repo; + this.instance = instance; + this.configuration = configuration; + } + subscribe(method, options, successCallback, errorCallback, existingSub) { + const callProtocolSubscribe = (targetServers, stream, successProxy, errorProxy) => { + options.methodResponseTimeout = options.methodResponseTimeout ?? options.waitTimeoutMs; + this.protocol.client.subscribe(stream, options, targetServers, successProxy, errorProxy, existingSub); + }; + const promise = new Promise((resolve, reject) => { + const successProxy = (sub) => { + resolve(sub); + }; + const errorProxy = (err) => { + reject(err); + }; + if (!method) { + reject(`Method definition is required. Please, provide either a unique string for a method name or a “methodDefinition” object with a required “name” property.`); + return; + } + let methodDef; + if (typeof method === "string") { + methodDef = { name: method }; + } + else { + methodDef = method; + } + if (!methodDef.name) { + reject(`Method definition is required. Please, provide either a unique string for a method name or a “methodDefinition” object with a required “name” property.`); + return; + } + if (options === undefined) { + options = {}; + } + let target = options.target; + if (target === undefined) { + target = "best"; + } + if (typeof target === "string" && target !== "all" && target !== "best") { + reject(new Error(`"${target}" is not a valid target. Valid targets are "all", "best", or an instance.`)); + return; + } + if (options.methodResponseTimeout === undefined) { + options.methodResponseTimeout = options.method_response_timeout; + if (options.methodResponseTimeout === undefined) { + options.methodResponseTimeout = this.configuration.methodResponseTimeout; + } + } + if (options.waitTimeoutMs === undefined) { + options.waitTimeoutMs = options.wait_for_method_timeout; + if (options.waitTimeoutMs === undefined) { + options.waitTimeoutMs = this.configuration.waitTimeoutMs; + } + } + const delayStep = 500; + let delayTillNow = 0; + let currentServers = this.getServerMethodsByFilterAndTarget(methodDef, target); + if (currentServers.length > 0) { + callProtocolSubscribe(currentServers, currentServers[0].methods[0], successProxy, errorProxy); + } + else { + const retry = () => { + if (!target || !(options.waitTimeoutMs)) { + return; + } + delayTillNow += delayStep; + currentServers = this.getServerMethodsByFilterAndTarget(methodDef, target); + if (currentServers.length > 0) { + const streamInfo = currentServers[0].methods[0]; + callProtocolSubscribe(currentServers, streamInfo, successProxy, errorProxy); + } + else if (delayTillNow >= options.waitTimeoutMs) { + const def = typeof method === "string" ? { name: method } : method; + callProtocolSubscribe(currentServers, def, successProxy, errorProxy); + } + else { + setTimeout(retry, delayStep); + } + }; + setTimeout(retry, delayStep); + } + }); + return promisify$2(promise, successCallback, errorCallback); + } + servers(methodFilter) { + const filterCopy = methodFilter === undefined + ? undefined + : { ...methodFilter }; + return this.getServers(filterCopy).map((serverMethodMap) => { + return serverMethodMap.server.instance; + }); + } + methods(methodFilter) { + if (typeof methodFilter === "string") { + methodFilter = { name: methodFilter }; + } + else { + methodFilter = { ...methodFilter }; + } + return this.getMethods(methodFilter); + } + methodsForInstance(instance) { + return this.getMethodsForInstance(instance); + } + methodAdded(callback) { + return this.repo.onMethodAdded(callback); + } + methodRemoved(callback) { + return this.repo.onMethodRemoved(callback); + } + serverAdded(callback) { + return this.repo.onServerAdded(callback); + } + serverRemoved(callback) { + return this.repo.onServerRemoved((server, reason) => { + callback(server, reason); + }); + } + serverMethodAdded(callback) { + return this.repo.onServerMethodAdded((server, method) => { + callback({ server, method }); + }); + } + serverMethodRemoved(callback) { + return this.repo.onServerMethodRemoved((server, method) => { + callback({ server, method }); + }); + } + async invoke(methodFilter, argumentObj, target, additionalOptions, success, error) { + const getInvokePromise = async () => { + let methodDefinition; + if (typeof methodFilter === "string") { + methodDefinition = { name: methodFilter }; + } + else { + methodDefinition = { ...methodFilter }; + } + if (!methodDefinition.name) { + return Promise.reject(`Method definition is required. Please, provide either a unique string for a method name or a “methodDefinition” object with a required “name” property.`); + } + if (!argumentObj) { + argumentObj = {}; + } + if (!target) { + target = "best"; + } + if (typeof target === "string" && target !== "all" && target !== "best" && target !== "skipMine") { + return Promise.reject(new Error(`"${target}" is not a valid target. Valid targets are "all" and "best".`)); + } + if (!additionalOptions) { + additionalOptions = {}; + } + if (additionalOptions.methodResponseTimeoutMs === undefined) { + additionalOptions.methodResponseTimeoutMs = additionalOptions.method_response_timeout; + if (additionalOptions.methodResponseTimeoutMs === undefined) { + additionalOptions.methodResponseTimeoutMs = this.configuration.methodResponseTimeout; + } + } + if (additionalOptions.waitTimeoutMs === undefined) { + additionalOptions.waitTimeoutMs = additionalOptions.wait_for_method_timeout; + if (additionalOptions.waitTimeoutMs === undefined) { + additionalOptions.waitTimeoutMs = this.configuration.waitTimeoutMs; + } + } + if (additionalOptions.waitTimeoutMs !== undefined && typeof additionalOptions.waitTimeoutMs !== "number") { + return Promise.reject(new Error(`"${additionalOptions.waitTimeoutMs}" is not a valid number for "waitTimeoutMs" `)); + } + if (typeof argumentObj !== "object") { + return Promise.reject(new Error(`The method arguments must be an object. method: ${methodDefinition.name}`)); + } + let serversMethodMap = this.getServerMethodsByFilterAndTarget(methodDefinition, target); + if (serversMethodMap.length === 0) { + try { + serversMethodMap = await this.tryToAwaitForMethods(methodDefinition, target, additionalOptions); + } + catch (err) { + const method = { + ...methodDefinition, + getServers: () => [], + supportsStreaming: false, + objectTypes: methodDefinition.objectTypes ?? [], + flags: methodDefinition.flags?.metadata ?? {} + }; + const errorObj = { + method, + called_with: argumentObj, + message: `Can not find a method matching ${JSON.stringify(methodFilter)} with server filter ${JSON.stringify(target)}`, + executed_by: undefined, + returned: undefined, + status: undefined, + }; + return Promise.reject(errorObj); + } + } + const timeout = additionalOptions.methodResponseTimeoutMs; + const additionalOptionsCopy = additionalOptions; + const invokePromises = serversMethodMap.map((serversMethodPair) => { + const invId = nanoid$1(10); + const method = serversMethodPair.methods[0]; + const server = serversMethodPair.server; + const invokePromise = this.protocol.client.invoke(invId, method, argumentObj, server, additionalOptionsCopy); + return Promise.race([ + invokePromise, + rejectAfter(timeout, invokePromise, { + invocationId: invId, + message: `Invocation timeout (${timeout} ms) reached for method name: ${method?.name}, target instance: ${JSON.stringify(server.instance)}, options: ${JSON.stringify(additionalOptionsCopy)}`, + status: InvokeStatus.Error, + }) + ]); + }); + const invocationMessages = await Promise.all(invokePromises); + const results = this.getInvocationResultObj(invocationMessages, methodDefinition, argumentObj); + const allRejected = invocationMessages.every((result) => result.status === InvokeStatus.Error); + if (allRejected) { + return Promise.reject(results); + } + return results; + }; + return promisify$2(getInvokePromise(), success, error); + } + getInvocationResultObj(invocationResults, method, calledWith) { + const all_return_values = invocationResults + .filter((invokeMessage) => invokeMessage.status === InvokeStatus.Success) + .reduce((allValues, currentValue) => { + allValues = [ + ...allValues, + { + executed_by: currentValue.instance, + returned: currentValue.result, + called_with: calledWith, + method, + message: currentValue.message, + status: currentValue.status, + } + ]; + return allValues; + }, []); + const all_errors = invocationResults + .filter((invokeMessage) => invokeMessage.status === InvokeStatus.Error) + .reduce((allErrors, currError) => { + allErrors = [ + ...allErrors, + { + executed_by: currError.instance, + called_with: calledWith, + name: method.name, + message: currError.message, + } + ]; + return allErrors; + }, []); + const invResult = invocationResults[0]; + const result = { + method, + called_with: calledWith, + returned: invResult.result, + executed_by: invResult.instance, + all_return_values, + all_errors, + message: invResult.message, + status: invResult.status + }; + return result; + } + tryToAwaitForMethods(methodDefinition, target, additionalOptions) { + return new Promise((resolve, reject) => { + if (additionalOptions.waitTimeoutMs === 0) { + reject(); + return; + } + const delayStep = 500; + let delayTillNow = 0; + const retry = () => { + delayTillNow += delayStep; + const serversMethodMap = this.getServerMethodsByFilterAndTarget(methodDefinition, target); + if (serversMethodMap.length > 0) { + clearInterval(interval); + resolve(serversMethodMap); + } + else if (delayTillNow >= (additionalOptions.waitTimeoutMs || 10000)) { + clearInterval(interval); + reject(); + return; + } + }; + const interval = setInterval(retry, delayStep); + }); + } + filterByTarget(target, serverMethodMap) { + if (typeof target === "string") { + if (target === "all") { + return [...serverMethodMap]; + } + else if (target === "best") { + const localMachine = serverMethodMap + .find((s) => s.server.instance.isLocal); + if (localMachine) { + return [localMachine]; + } + if (serverMethodMap[0] !== undefined) { + return [serverMethodMap[0]]; + } + } + else if (target === "skipMine") { + return serverMethodMap.filter(({ server }) => server.instance.peerId !== this.instance.peerId); + } + } + else { + let targetArray; + if (!Array.isArray(target)) { + targetArray = [target]; + } + else { + targetArray = target; + } + const allServersMatching = targetArray.reduce((matches, filter) => { + const myMatches = serverMethodMap.filter((serverMethodPair) => { + return this.instanceMatch(filter, serverMethodPair.server.instance); + }); + return matches.concat(myMatches); + }, []); + return allServersMatching; + } + return []; + } + instanceMatch(instanceFilter, instanceDefinition) { + if (instanceFilter?.peerId && instanceFilter?.instance) { + instanceFilter = { ...instanceFilter }; + delete instanceFilter.peerId; + } + return this.containsProps(instanceFilter, instanceDefinition); + } + methodMatch(methodFilter, methodDefinition) { + return this.containsProps(methodFilter, methodDefinition); + } + containsProps(filter, repoMethod) { + const filterProps = Object.keys(filter) + .filter((prop) => { + return filter[prop] !== undefined + && filter[prop] !== null + && typeof filter[prop] !== "function" + && prop !== "object_types" + && prop !== "display_name" + && prop !== "id" + && prop !== "gatewayId" + && prop !== "identifier" + && prop[0] !== "_"; + }); + return filterProps.every((prop) => { + let isMatch; + const filterValue = filter[prop]; + const repoMethodValue = repoMethod[prop]; + switch (prop) { + case "objectTypes": + isMatch = (filterValue || []).every((filterValueEl) => { + return (repoMethodValue || []).includes(filterValueEl); + }); + break; + case "flags": + isMatch = isSubset(repoMethodValue || {}, filterValue || {}); + break; + default: + isMatch = String(filterValue).toLowerCase() === String(repoMethodValue).toLowerCase(); + } + return isMatch; + }); + } + getMethods(methodFilter) { + if (methodFilter === undefined) { + return this.repo.getMethods(); + } + const methods = this.repo.getMethods().filter((method) => { + return this.methodMatch(methodFilter, method); + }); + return methods; + } + getMethodsForInstance(instanceFilter) { + const allServers = this.repo.getServers(); + const matchingServers = allServers.filter((server) => { + return this.instanceMatch(instanceFilter, server.instance); + }); + if (matchingServers.length === 0) { + return []; + } + let resultMethodsObject = {}; + if (matchingServers.length === 1) { + resultMethodsObject = matchingServers[0].methods; + } + else { + matchingServers.forEach((server) => { + Object.keys(server.methods).forEach((methodKey) => { + const method = server.methods[methodKey]; + resultMethodsObject[method.identifier] = method; + }); + }); + } + return Object.keys(resultMethodsObject) + .map((key) => { + return resultMethodsObject[key]; + }); + } + getServers(methodFilter) { + const servers = this.repo.getServers(); + if (methodFilter === undefined) { + return servers.map((server) => { + return { server, methods: [] }; + }); + } + return servers.reduce((prev, current) => { + const methodsForServer = Object.values(current.methods); + const matchingMethods = methodsForServer.filter((method) => { + return this.methodMatch(methodFilter, method); + }); + if (matchingMethods.length > 0) { + prev.push({ server: current, methods: matchingMethods }); + } + return prev; + }, []); + } + getServerMethodsByFilterAndTarget(methodFilter, target) { + const serversMethodMap = this.getServers(methodFilter); + return this.filterByTarget(target, serversMethodMap); + } + } + + class ServerSubscription { + protocol; + repoMethod; + subscription; + constructor(protocol, repoMethod, subscription) { + this.protocol = protocol; + this.repoMethod = repoMethod; + this.subscription = subscription; + } + get stream() { + if (!this.repoMethod.stream) { + throw new Error("no stream"); + } + return this.repoMethod.stream; + } + get arguments() { return this.subscription.arguments || {}; } + get branchKey() { return this.subscription.branchKey; } + get instance() { + if (!this.subscription.instance) { + throw new Error("no instance"); + } + return this.subscription.instance; + } + close() { + this.protocol.server.closeSingleSubscription(this.repoMethod, this.subscription); + } + push(data) { + this.protocol.server.pushDataToSingle(this.repoMethod, this.subscription, data); + } + } + + class Request { + protocol; + repoMethod; + requestContext; + arguments; + instance; + constructor(protocol, repoMethod, requestContext) { + this.protocol = protocol; + this.repoMethod = repoMethod; + this.requestContext = requestContext; + this.arguments = requestContext.arguments; + this.instance = requestContext.instance; + } + accept() { + this.protocol.server.acceptRequestOnBranch(this.requestContext, this.repoMethod, ""); + } + acceptOnBranch(branch) { + this.protocol.server.acceptRequestOnBranch(this.requestContext, this.repoMethod, branch); + } + reject(reason) { + this.protocol.server.rejectRequest(this.requestContext, this.repoMethod, reason); + } + } + + let ServerStreaming$1 = class ServerStreaming { + protocol; + server; + constructor(protocol, server) { + this.protocol = protocol; + this.server = server; + protocol.server.onSubRequest((rc, rm) => this.handleSubRequest(rc, rm)); + protocol.server.onSubAdded((sub, rm) => this.handleSubAdded(sub, rm)); + protocol.server.onSubRemoved((sub, rm) => this.handleSubRemoved(sub, rm)); + } + handleSubRequest(requestContext, repoMethod) { + if (!(repoMethod && + repoMethod.streamCallbacks && + typeof repoMethod.streamCallbacks.subscriptionRequestHandler === "function")) { + return; + } + const request = new Request(this.protocol, repoMethod, requestContext); + repoMethod.streamCallbacks.subscriptionRequestHandler(request); + } + handleSubAdded(subscription, repoMethod) { + if (!(repoMethod && + repoMethod.streamCallbacks && + typeof repoMethod.streamCallbacks.subscriptionAddedHandler === "function")) { + return; + } + const sub = new ServerSubscription(this.protocol, repoMethod, subscription); + repoMethod.streamCallbacks.subscriptionAddedHandler(sub); + } + handleSubRemoved(subscription, repoMethod) { + if (!(repoMethod && + repoMethod.streamCallbacks && + typeof repoMethod.streamCallbacks.subscriptionRemovedHandler === "function")) { + return; + } + const sub = new ServerSubscription(this.protocol, repoMethod, subscription); + repoMethod.streamCallbacks.subscriptionRemovedHandler(sub); + } + }; + + class ServerBranch { + key; + protocol; + repoMethod; + constructor(key, protocol, repoMethod) { + this.key = key; + this.protocol = protocol; + this.repoMethod = repoMethod; + } + subscriptions() { + const subList = this.protocol.server.getSubscriptionList(this.repoMethod, this.key); + return subList.map((sub) => { + return new ServerSubscription(this.protocol, this.repoMethod, sub); + }); + } + close() { + this.protocol.server.closeAllSubscriptions(this.repoMethod, this.key); + } + push(data) { + this.protocol.server.pushData(this.repoMethod, data, [this.key]); + } + } + + class ServerStream { + _protocol; + _repoMethod; + _server; + name; + constructor(_protocol, _repoMethod, _server) { + this._protocol = _protocol; + this._repoMethod = _repoMethod; + this._server = _server; + this.name = this._repoMethod.definition.name; + } + branches(key) { + const bList = this._protocol.server.getBranchList(this._repoMethod); + if (key) { + if (bList.indexOf(key) > -1) { + return new ServerBranch(key, this._protocol, this._repoMethod); + } + return undefined; + } + else { + return bList.map((branchKey) => { + return new ServerBranch(branchKey, this._protocol, this._repoMethod); + }); + } + } + branch(key) { + return this.branches(key); + } + subscriptions() { + const subList = this._protocol.server.getSubscriptionList(this._repoMethod); + return subList.map((sub) => { + return new ServerSubscription(this._protocol, this._repoMethod, sub); + }); + } + get definition() { + const def2 = this._repoMethod.definition; + return { + accepts: def2.accepts, + description: def2.description, + displayName: def2.displayName, + name: def2.name, + objectTypes: def2.objectTypes, + returns: def2.returns, + supportsStreaming: def2.supportsStreaming, + flags: def2.flags?.metadata, + }; + } + close() { + this._protocol.server.closeAllSubscriptions(this._repoMethod); + this._server.unregister(this._repoMethod.definition, true); + } + push(data, branches) { + if (typeof branches !== "string" && !Array.isArray(branches) && branches !== undefined) { + throw new Error("invalid branches should be string or string array"); + } + if (typeof data !== "object") { + throw new Error("Invalid arguments. Data must be an object."); + } + this._protocol.server.pushData(this._repoMethod, data, branches); + } + updateRepoMethod(repoMethod) { + this._repoMethod = repoMethod; + } + } + + class Server { + protocol; + serverRepository; + streaming; + invocations = 0; + currentlyUnregistering = {}; + constructor(protocol, serverRepository) { + this.protocol = protocol; + this.serverRepository = serverRepository; + this.streaming = new ServerStreaming$1(protocol, this); + this.protocol.server.onInvoked(this.onMethodInvoked.bind(this)); + } + createStream(streamDef, callbacks, successCallback, errorCallback, existingStream) { + const promise = new Promise((resolve, reject) => { + if (!streamDef) { + reject("The stream name must be unique! Please, provide either a unique string for a stream name to “glue.interop.createStream()” or a “methodDefinition” object with a unique “name” property for the stream."); + return; + } + let streamMethodDefinition; + if (typeof streamDef === "string") { + streamMethodDefinition = { name: "" + streamDef }; + } + else { + streamMethodDefinition = { ...streamDef }; + } + if (!streamMethodDefinition.name) { + return reject(`The “name” property is required for the “streamDefinition” object and must be unique. Stream definition: ${JSON.stringify(streamMethodDefinition)}`); + } + const nameAlreadyExists = this.serverRepository.getList() + .some((serverMethod) => serverMethod.definition.name === streamMethodDefinition.name); + if (nameAlreadyExists) { + return reject(`A stream with the name "${streamMethodDefinition.name}" already exists! Please, provide a unique name for the stream.`); + } + streamMethodDefinition.supportsStreaming = true; + if (!callbacks) { + callbacks = {}; + } + if (typeof callbacks.subscriptionRequestHandler !== "function") { + callbacks.subscriptionRequestHandler = (request) => { + request.accept(); + }; + } + const repoMethod = this.serverRepository.add({ + definition: streamMethodDefinition, + streamCallbacks: callbacks, + protocolState: {}, + }); + this.protocol.server.createStream(repoMethod) + .then(() => { + let streamUserObject; + if (existingStream) { + streamUserObject = existingStream; + existingStream.updateRepoMethod(repoMethod); + } + else { + streamUserObject = new ServerStream(this.protocol, repoMethod, this); + } + repoMethod.stream = streamUserObject; + resolve(streamUserObject); + }) + .catch((err) => { + if (repoMethod.repoId) { + this.serverRepository.remove(repoMethod.repoId); + } + reject(err); + }); + }); + return promisify$2(promise, successCallback, errorCallback); + } + register(methodDefinition, callback) { + if (!methodDefinition) { + return Promise.reject("Method definition is required. Please, provide either a unique string for a method name or a “methodDefinition” object with a required “name” property."); + } + if (typeof callback !== "function") { + return Promise.reject(`The second parameter must be a callback function. Method: ${typeof methodDefinition === "string" ? methodDefinition : methodDefinition.name}`); + } + const wrappedCallbackFunction = async (context, resultCallback) => { + try { + const result = callback(context.args, context.instance); + if (result && typeof result.then === "function") { + const resultValue = await result; + resultCallback(undefined, resultValue); + } + else { + resultCallback(undefined, result); + } + } + catch (e) { + resultCallback(e ?? "", e ?? ""); + } + }; + wrappedCallbackFunction.userCallback = callback; + return this.registerCore(methodDefinition, wrappedCallbackFunction); + } + registerAsync(methodDefinition, callback) { + if (!methodDefinition) { + return Promise.reject("Method definition is required. Please, provide either a unique string for a method name or a “methodDefinition” object with a required “name” property."); + } + if (typeof callback !== "function") { + return Promise.reject(`The second parameter must be a callback function. Method: ${typeof methodDefinition === "string" ? methodDefinition : methodDefinition.name}`); + } + const wrappedCallback = async (context, resultCallback) => { + try { + let resultCalled = false; + const success = (result) => { + if (!resultCalled) { + resultCallback(undefined, result); + } + resultCalled = true; + }; + const error = (e) => { + if (!resultCalled) { + if (!e) { + e = ""; + } + resultCallback(e, e); + } + resultCalled = true; + }; + const methodResult = callback(context.args, context.instance, success, error); + if (methodResult && typeof methodResult.then === "function") { + methodResult + .then(success) + .catch(error); + } + } + catch (e) { + resultCallback(e, undefined); + } + }; + wrappedCallback.userCallbackAsync = callback; + return this.registerCore(methodDefinition, wrappedCallback); + } + async unregister(methodFilter, forStream = false) { + if (methodFilter === undefined) { + return Promise.reject("Please, provide either a unique string for a name or an object containing a “name” property."); + } + if (typeof methodFilter === "function") { + await this.unregisterWithPredicate(methodFilter, forStream); + return; + } + let methodDefinition; + if (typeof methodFilter === "string") { + methodDefinition = { name: methodFilter }; + } + else { + methodDefinition = methodFilter; + } + if (methodDefinition.name === undefined) { + return Promise.reject("Method name is required. Cannot find a method if the method name is undefined!"); + } + const methodToBeRemoved = this.serverRepository.getList().find((serverMethod) => { + return serverMethod.definition.name === methodDefinition.name + && (serverMethod.definition.supportsStreaming || false) === forStream; + }); + if (!methodToBeRemoved) { + return Promise.reject(`Method with a name "${methodDefinition.name}" does not exist or is not registered by your application!`); + } + await this.removeMethodsOrStreams([methodToBeRemoved]); + } + async unregisterWithPredicate(filterPredicate, forStream) { + const methodsOrStreamsToRemove = this.serverRepository.getList() + .filter((sm) => filterPredicate(sm.definition)) + .filter((serverMethod) => (serverMethod.definition.supportsStreaming || false) === forStream); + if (!methodsOrStreamsToRemove || methodsOrStreamsToRemove.length === 0) { + return Promise.reject(`Could not find a ${forStream ? "stream" : "method"} matching the specified condition!`); + } + await this.removeMethodsOrStreams(methodsOrStreamsToRemove); + } + removeMethodsOrStreams(methodsToRemove) { + const methodUnregPromises = []; + methodsToRemove.forEach((method) => { + const promise = this.protocol.server.unregister(method) + .then(() => { + if (method.repoId) { + this.serverRepository.remove(method.repoId); + } + }); + methodUnregPromises.push(promise); + this.addAsCurrentlyUnregistering(method.definition.name, promise); + }); + return Promise.all(methodUnregPromises); + } + async addAsCurrentlyUnregistering(methodName, promise) { + const timeout = new Promise((resolve) => setTimeout(resolve, 5000)); + this.currentlyUnregistering[methodName] = Promise.race([promise, timeout]).then(() => { + delete this.currentlyUnregistering[methodName]; + }); + } + async registerCore(method, theFunction) { + let methodDefinition; + if (typeof method === "string") { + methodDefinition = { name: "" + method }; + } + else { + methodDefinition = { ...method }; + } + if (!methodDefinition.name) { + return Promise.reject(`Please, provide a (unique) string value for the “name” property in the “methodDefinition” object: ${JSON.stringify(method)}`); + } + const unregisterInProgress = this.currentlyUnregistering[methodDefinition.name]; + if (typeof unregisterInProgress !== "undefined") { + await unregisterInProgress; + } + const nameAlreadyExists = this.serverRepository.getList() + .some((serverMethod) => serverMethod.definition.name === methodDefinition.name); + if (nameAlreadyExists) { + return Promise.reject(`A method with the name "${methodDefinition.name}" already exists! Please, provide a unique name for the method.`); + } + if (methodDefinition.supportsStreaming) { + return Promise.reject(`When you create methods with “glue.interop.register()” or “glue.interop.registerAsync()” the property “supportsStreaming” cannot be “true”. If you want “${methodDefinition.name}” to be a stream, please use the “glue.interop.createStream()” method.`); + } + const repoMethod = this.serverRepository.add({ + definition: methodDefinition, + theFunction, + protocolState: {}, + }); + return this.protocol.server.register(repoMethod) + .catch((err) => { + if (repoMethod?.repoId) { + this.serverRepository.remove(repoMethod.repoId); + } + throw err; + }); + } + onMethodInvoked(methodToExecute, invocationId, invocationArgs) { + if (!methodToExecute || !methodToExecute.theFunction) { + return; + } + methodToExecute.theFunction(invocationArgs, (err, result) => { + if (err !== undefined && err !== null) { + if (err.message && typeof err.message === "string") { + err = err.message; + } + else if (typeof err !== "string") { + try { + err = JSON.stringify(err); + } + catch (unStrException) { + err = `un-stringifyable error in onMethodInvoked! Top level prop names: ${Object.keys(err)}`; + } + } + } + if (!result) { + result = {}; + } + else if (typeof result !== "object" || Array.isArray(result)) { + result = { _value: result }; + } + this.protocol.server.methodInvocationResult(methodToExecute, invocationId, err, result); + }); + } + } + + class InstanceWrapper { + wrapped = {}; + constructor(API, instance, connection) { + this.wrapped.getMethods = function () { + return API.methodsForInstance(this); + }; + this.wrapped.getStreams = function () { + return API.methodsForInstance(this).filter((m) => m.supportsStreaming); + }; + if (instance) { + this.refreshWrappedObject(instance); + } + if (connection) { + connection.loggedIn(() => { + this.refresh(connection); + }); + this.refresh(connection); + } + } + unwrap() { + return this.wrapped; + } + refresh(connection) { + if (!connection) { + return; + } + const resolvedIdentity = connection?.resolvedIdentity; + const instance = Object.assign({}, resolvedIdentity ?? {}, { peerId: connection?.peerId }); + this.refreshWrappedObject(instance); + } + refreshWrappedObject(resolvedIdentity) { + Object.keys(resolvedIdentity).forEach((key) => { + this.wrapped[key] = resolvedIdentity[key]; + }); + this.wrapped.user = resolvedIdentity.user; + this.wrapped.instance = resolvedIdentity.instance; + this.wrapped.application = resolvedIdentity.application ?? nanoid$1(10); + this.wrapped.applicationName = resolvedIdentity.applicationName; + this.wrapped.pid = resolvedIdentity.pid ?? resolvedIdentity.process ?? Math.floor(Math.random() * 10000000000); + this.wrapped.machine = resolvedIdentity.machine; + this.wrapped.environment = resolvedIdentity.environment; + this.wrapped.region = resolvedIdentity.region; + this.wrapped.windowId = resolvedIdentity.windowId; + this.wrapped.isLocal = resolvedIdentity.isLocal ?? true; + this.wrapped.api = resolvedIdentity.api; + this.wrapped.service = resolvedIdentity.service; + this.wrapped.peerId = resolvedIdentity.peerId; + } + } + + const hideMethodSystemFlags = (method) => { + return { + ...method, + flags: method.flags.metadata || {} + }; + }; + class ClientRepository { + logger; + API; + servers = {}; + myServer; + methodsCount = {}; + callbacks = CallbackRegistryFactory$1(); + constructor(logger, API) { + this.logger = logger; + this.API = API; + const peerId = this.API.instance.peerId; + this.myServer = { + id: peerId, + methods: {}, + instance: this.API.instance, + wrapper: this.API.unwrappedInstance, + }; + this.servers[peerId] = this.myServer; + } + addServer(info, serverId) { + this.logger.debug(`adding server ${serverId}`); + const current = this.servers[serverId]; + if (current) { + return current.id; + } + const wrapper = new InstanceWrapper(this.API, info); + const serverEntry = { + id: serverId, + methods: {}, + instance: wrapper.unwrap(), + wrapper, + }; + this.servers[serverId] = serverEntry; + this.callbacks.execute("onServerAdded", serverEntry.instance); + return serverId; + } + removeServerById(id, reason) { + const server = this.servers[id]; + if (!server) { + this.logger.warn(`not aware of server ${id}, my state ${JSON.stringify(Object.keys(this.servers))}`); + return; + } + else { + this.logger.debug(`removing server ${id}`); + } + Object.keys(server.methods).forEach((methodId) => { + this.removeServerMethod(id, methodId); + }); + delete this.servers[id]; + this.callbacks.execute("onServerRemoved", server.instance, reason); + } + addServerMethod(serverId, method) { + const server = this.servers[serverId]; + if (!server) { + throw new Error("server does not exists"); + } + if (server.methods[method.id]) { + return; + } + const identifier = this.createMethodIdentifier(method); + const that = this; + const methodDefinition = { + identifier, + gatewayId: method.id, + name: method.name, + displayName: method.display_name, + description: method.description, + version: method.version, + objectTypes: method.object_types || [], + accepts: method.input_signature, + returns: method.result_signature, + supportsStreaming: typeof method.flags !== "undefined" ? method.flags.streaming : false, + flags: method.flags ?? {}, + getServers: () => { + return that.getServersByMethod(identifier); + } + }; + methodDefinition.object_types = methodDefinition.objectTypes; + methodDefinition.display_name = methodDefinition.displayName; + methodDefinition.version = methodDefinition.version; + server.methods[method.id] = methodDefinition; + const clientMethodDefinition = hideMethodSystemFlags(methodDefinition); + if (!this.methodsCount[identifier]) { + this.methodsCount[identifier] = 0; + this.callbacks.execute("onMethodAdded", clientMethodDefinition); + } + this.methodsCount[identifier] = this.methodsCount[identifier] + 1; + this.callbacks.execute("onServerMethodAdded", server.instance, clientMethodDefinition); + return methodDefinition; + } + removeServerMethod(serverId, methodId) { + const server = this.servers[serverId]; + if (!server) { + throw new Error("server does not exists"); + } + const method = server.methods[methodId]; + delete server.methods[methodId]; + const clientMethodDefinition = hideMethodSystemFlags(method); + this.methodsCount[method.identifier] = this.methodsCount[method.identifier] - 1; + if (this.methodsCount[method.identifier] === 0) { + this.callbacks.execute("onMethodRemoved", clientMethodDefinition); + } + this.callbacks.execute("onServerMethodRemoved", server.instance, clientMethodDefinition); + } + getMethods() { + return this.extractMethodsFromServers(Object.values(this.servers)).map(hideMethodSystemFlags); + } + getServers() { + return Object.values(this.servers).map(this.hideServerMethodSystemFlags); + } + onServerAdded(callback) { + const unsubscribeFunc = this.callbacks.add("onServerAdded", callback); + const serversWithMethodsToReplay = this.getServers().map((s) => s.instance); + return this.returnUnsubWithDelayedReplay(unsubscribeFunc, serversWithMethodsToReplay, callback); + } + onMethodAdded(callback) { + const unsubscribeFunc = this.callbacks.add("onMethodAdded", callback); + const methodsToReplay = this.getMethods(); + return this.returnUnsubWithDelayedReplay(unsubscribeFunc, methodsToReplay, callback); + } + onServerMethodAdded(callback) { + const unsubscribeFunc = this.callbacks.add("onServerMethodAdded", callback); + let unsubCalled = false; + const servers = this.getServers(); + setTimeout(() => { + servers.forEach((server) => { + const methods = server.methods; + Object.keys(methods).forEach((methodId) => { + if (!unsubCalled) { + callback(server.instance, methods[methodId]); + } + }); + }); + }, 0); + return () => { + unsubCalled = true; + unsubscribeFunc(); + }; + } + onMethodRemoved(callback) { + const unsubscribeFunc = this.callbacks.add("onMethodRemoved", callback); + return unsubscribeFunc; + } + onServerRemoved(callback) { + const unsubscribeFunc = this.callbacks.add("onServerRemoved", callback); + return unsubscribeFunc; + } + onServerMethodRemoved(callback) { + const unsubscribeFunc = this.callbacks.add("onServerMethodRemoved", callback); + return unsubscribeFunc; + } + getServerById(id) { + const server = this.servers[id]; + if (!server) { + return undefined; + } + return this.hideServerMethodSystemFlags(this.servers[id]); + } + reset() { + Object.keys(this.servers).forEach((key) => { + this.removeServerById(key, "reset"); + }); + this.servers = { + [this.myServer.id]: this.myServer + }; + this.methodsCount = {}; + } + createMethodIdentifier(methodInfo) { + const accepts = methodInfo.input_signature ?? ""; + const returns = methodInfo.result_signature ?? ""; + return (methodInfo.name + accepts + returns).toLowerCase(); + } + getServersByMethod(identifier) { + const allServers = []; + Object.values(this.servers).forEach((server) => { + Object.values(server.methods).forEach((method) => { + if (method.identifier === identifier) { + allServers.push(server.instance); + } + }); + }); + return allServers; + } + returnUnsubWithDelayedReplay(unsubscribeFunc, collectionToReplay, callback) { + let unsubCalled = false; + setTimeout(() => { + collectionToReplay.forEach((item) => { + if (!unsubCalled) { + callback(item); + } + }); + }, 0); + return () => { + unsubCalled = true; + unsubscribeFunc(); + }; + } + hideServerMethodSystemFlags(server) { + const clientMethods = {}; + Object.entries(server.methods).forEach(([name, method]) => { + clientMethods[name] = hideMethodSystemFlags(method); + }); + return { + ...server, + methods: clientMethods + }; + } + extractMethodsFromServers(servers) { + const methods = Object.values(servers).reduce((clientMethods, server) => { + return [...clientMethods, ...Object.values(server.methods)]; + }, []); + return methods; + } + } + + class ServerRepository { + nextId = 0; + methods = []; + add(method) { + method.repoId = String(this.nextId); + this.nextId += 1; + this.methods.push(method); + return method; + } + remove(repoId) { + if (typeof repoId !== "string") { + return new TypeError("Expecting a string"); + } + this.methods = this.methods.filter((m) => { + return m.repoId !== repoId; + }); + } + getById(id) { + if (typeof id !== "string") { + return undefined; + } + return this.methods.find((m) => { + return m.repoId === id; + }); + } + getList() { + return this.methods.map((m) => m); + } + length() { + return this.methods.length; + } + reset() { + this.methods = []; + } + } + + const SUBSCRIPTION_REQUEST = "onSubscriptionRequest"; + const SUBSCRIPTION_ADDED = "onSubscriptionAdded"; + const SUBSCRIPTION_REMOVED = "onSubscriptionRemoved"; + class ServerStreaming { + session; + repository; + serverRepository; + ERR_URI_SUBSCRIPTION_FAILED = "com.tick42.agm.errors.subscription.failure"; + callbacks = CallbackRegistryFactory$1(); + nextStreamId = 0; + constructor(session, repository, serverRepository) { + this.session = session; + this.repository = repository; + this.serverRepository = serverRepository; + session.on("add-interest", (msg) => { + this.handleAddInterest(msg); + }); + session.on("remove-interest", (msg) => { + this.handleRemoveInterest(msg); + }); + } + acceptRequestOnBranch(requestContext, streamingMethod, branch) { + if (typeof branch !== "string") { + branch = ""; + } + if (typeof streamingMethod.protocolState.subscriptionsMap !== "object") { + throw new TypeError("The streaming method is missing its subscriptions."); + } + if (!Array.isArray(streamingMethod.protocolState.branchKeyToStreamIdMap)) { + throw new TypeError("The streaming method is missing its branches."); + } + const streamId = this.getStreamId(streamingMethod, branch); + const key = requestContext.msg.subscription_id; + const subscription = { + id: key, + arguments: requestContext.arguments, + instance: requestContext.instance, + branchKey: branch, + streamId, + subscribeMsg: requestContext.msg, + }; + streamingMethod.protocolState.subscriptionsMap[key] = subscription; + this.session.sendFireAndForget({ + type: "accepted", + subscription_id: key, + stream_id: streamId, + }); + this.callbacks.execute(SUBSCRIPTION_ADDED, subscription, streamingMethod); + } + rejectRequest(requestContext, streamingMethod, reason) { + if (typeof reason !== "string") { + reason = ""; + } + this.sendSubscriptionFailed("Subscription rejected by user. " + reason, requestContext.msg.subscription_id); + } + pushData(streamingMethod, data, branches) { + if (typeof streamingMethod !== "object" || !Array.isArray(streamingMethod.protocolState.branchKeyToStreamIdMap)) { + return; + } + if (typeof data !== "object") { + throw new Error("Invalid arguments. Data must be an object."); + } + if (typeof branches === "string") { + branches = [branches]; + } + else if (!Array.isArray(branches) || branches.length <= 0) { + branches = []; + } + const streamIdList = streamingMethod.protocolState.branchKeyToStreamIdMap + .filter((br) => { + if (!branches || branches.length === 0) { + return true; + } + return branches.indexOf(br.key) >= 0; + }).map((br) => { + return br.streamId; + }); + streamIdList.forEach((streamId) => { + const publishMessage = { + type: "publish", + stream_id: streamId, + data, + }; + this.session.sendFireAndForget(publishMessage); + }); + } + pushDataToSingle(method, subscription, data) { + if (typeof data !== "object") { + throw new Error("Invalid arguments. Data must be an object."); + } + const postMessage = { + type: "post", + subscription_id: subscription.id, + data, + }; + this.session.sendFireAndForget(postMessage); + } + closeSingleSubscription(streamingMethod, subscription) { + if (streamingMethod.protocolState.subscriptionsMap) { + delete streamingMethod.protocolState.subscriptionsMap[subscription.id]; + } + const dropSubscriptionMessage = { + type: "drop-subscription", + subscription_id: subscription.id, + reason: "Server dropping a single subscription", + }; + this.session.sendFireAndForget(dropSubscriptionMessage); + subscription.instance; + this.callbacks.execute(SUBSCRIPTION_REMOVED, subscription, streamingMethod); + } + closeMultipleSubscriptions(streamingMethod, branchKey) { + if (typeof streamingMethod !== "object" || typeof streamingMethod.protocolState.subscriptionsMap !== "object") { + return; + } + if (!streamingMethod.protocolState.subscriptionsMap) { + return; + } + const subscriptionsMap = streamingMethod.protocolState.subscriptionsMap; + let subscriptionsToClose = Object.keys(subscriptionsMap) + .map((key) => { + return subscriptionsMap[key]; + }); + if (typeof branchKey === "string") { + subscriptionsToClose = subscriptionsToClose.filter((sub) => { + return sub.branchKey === branchKey; + }); + } + subscriptionsToClose.forEach((subscription) => { + delete subscriptionsMap[subscription.id]; + const drop = { + type: "drop-subscription", + subscription_id: subscription.id, + reason: "Server dropping all subscriptions on stream_id: " + subscription.streamId, + }; + this.session.sendFireAndForget(drop); + }); + } + getSubscriptionList(streamingMethod, branchKey) { + if (typeof streamingMethod !== "object") { + return []; + } + let subscriptions = []; + if (!streamingMethod.protocolState.subscriptionsMap) { + return []; + } + const subscriptionsMap = streamingMethod.protocolState.subscriptionsMap; + const allSubscriptions = Object.keys(subscriptionsMap) + .map((key) => { + return subscriptionsMap[key]; + }); + if (typeof branchKey !== "string") { + subscriptions = allSubscriptions; + } + else { + subscriptions = allSubscriptions.filter((sub) => { + return sub.branchKey === branchKey; + }); + } + return subscriptions; + } + getBranchList(streamingMethod) { + if (typeof streamingMethod !== "object") { + return []; + } + if (!streamingMethod.protocolState.subscriptionsMap) { + return []; + } + const subscriptionsMap = streamingMethod.protocolState.subscriptionsMap; + const allSubscriptions = Object.keys(subscriptionsMap) + .map((key) => { + return subscriptionsMap[key]; + }); + const result = []; + allSubscriptions.forEach((sub) => { + let branch = ""; + if (typeof sub === "object" && typeof sub.branchKey === "string") { + branch = sub.branchKey; + } + if (result.indexOf(branch) === -1) { + result.push(branch); + } + }); + return result; + } + onSubAdded(callback) { + this.onSubscriptionLifetimeEvent(SUBSCRIPTION_ADDED, callback); + } + onSubRequest(callback) { + this.onSubscriptionLifetimeEvent(SUBSCRIPTION_REQUEST, callback); + } + onSubRemoved(callback) { + this.onSubscriptionLifetimeEvent(SUBSCRIPTION_REMOVED, callback); + } + handleRemoveInterest(msg) { + const streamingMethod = this.serverRepository.getById(msg.method_id); + if (typeof msg.subscription_id !== "string" || + typeof streamingMethod !== "object") { + return; + } + if (!streamingMethod.protocolState.subscriptionsMap) { + return; + } + if (typeof streamingMethod.protocolState.subscriptionsMap[msg.subscription_id] !== "object") { + return; + } + const subscription = streamingMethod.protocolState.subscriptionsMap[msg.subscription_id]; + delete streamingMethod.protocolState.subscriptionsMap[msg.subscription_id]; + this.callbacks.execute(SUBSCRIPTION_REMOVED, subscription, streamingMethod); + } + onSubscriptionLifetimeEvent(eventName, handlerFunc) { + this.callbacks.add(eventName, handlerFunc); + } + getNextStreamId() { + return this.nextStreamId++ + ""; + } + handleAddInterest(msg) { + const caller = this.repository.getServerById(msg.caller_id); + const instance = caller?.instance ?? {}; + const requestContext = { + msg, + arguments: msg.arguments_kv || {}, + instance, + }; + const streamingMethod = this.serverRepository.getById(msg.method_id); + if (streamingMethod === undefined) { + const errorMsg = "No method with id " + msg.method_id + " on this server."; + this.sendSubscriptionFailed(errorMsg, msg.subscription_id); + return; + } + if (streamingMethod.protocolState.subscriptionsMap && + streamingMethod.protocolState.subscriptionsMap[msg.subscription_id]) { + this.sendSubscriptionFailed("A subscription with id " + msg.subscription_id + " already exists.", msg.subscription_id); + return; + } + this.callbacks.execute(SUBSCRIPTION_REQUEST, requestContext, streamingMethod); + } + sendSubscriptionFailed(reason, subscriptionId) { + const errorMessage = { + type: "error", + reason_uri: this.ERR_URI_SUBSCRIPTION_FAILED, + reason, + request_id: subscriptionId, + }; + this.session.sendFireAndForget(errorMessage); + } + getStreamId(streamingMethod, branchKey) { + if (typeof branchKey !== "string") { + branchKey = ""; + } + if (!streamingMethod.protocolState.branchKeyToStreamIdMap) { + throw new Error(`streaming ${streamingMethod.definition.name} method without protocol state`); + } + const needleBranch = streamingMethod.protocolState.branchKeyToStreamIdMap.filter((branch) => { + return branch.key === branchKey; + })[0]; + let streamId = (needleBranch ? needleBranch.streamId : undefined); + if (typeof streamId !== "string" || streamId === "") { + streamId = this.getNextStreamId(); + streamingMethod.protocolState.branchKeyToStreamIdMap.push({ key: branchKey, streamId }); + } + return streamId; + } + } + + class ServerProtocol { + session; + clientRepository; + serverRepository; + logger; + callbacks = CallbackRegistryFactory$1(); + streaming; + constructor(session, clientRepository, serverRepository, logger) { + this.session = session; + this.clientRepository = clientRepository; + this.serverRepository = serverRepository; + this.logger = logger; + this.streaming = new ServerStreaming(session, clientRepository, serverRepository); + this.session.on("invoke", (msg) => this.handleInvokeMessage(msg)); + } + createStream(repoMethod) { + repoMethod.protocolState.subscriptionsMap = {}; + repoMethod.protocolState.branchKeyToStreamIdMap = []; + return this.register(repoMethod, true); + } + register(repoMethod, isStreaming) { + const methodDef = repoMethod.definition; + const flags = Object.assign({}, { metadata: methodDef.flags ?? {} }, { streaming: isStreaming || false }); + const registerMsg = { + type: "register", + methods: [{ + id: repoMethod.repoId, + name: methodDef.name, + display_name: methodDef.displayName, + description: methodDef.description, + version: methodDef.version, + flags, + object_types: methodDef.objectTypes || methodDef.object_types, + input_signature: methodDef.accepts, + result_signature: methodDef.returns, + restrictions: undefined, + }], + }; + return this.session.send(registerMsg, { methodId: repoMethod.repoId }) + .then(() => { + this.logger.debug("registered method " + repoMethod.definition.name + " with id " + repoMethod.repoId); + }) + .catch((msg) => { + this.logger.warn(`failed to register method ${repoMethod.definition.name} with id ${repoMethod.repoId} - ${JSON.stringify(msg)}`); + throw msg; + }); + } + onInvoked(callback) { + this.callbacks.add("onInvoked", callback); + } + methodInvocationResult(method, invocationId, err, result) { + let msg; + if (err || err === "") { + msg = { + type: "error", + request_id: invocationId, + reason_uri: "agm.errors.client_error", + reason: err, + context: result, + peer_id: undefined, + }; + } + else { + msg = { + type: "yield", + invocation_id: invocationId, + peer_id: this.session.peerId, + result, + request_id: undefined, + }; + } + this.session.sendFireAndForget(msg); + } + async unregister(method) { + const msg = { + type: "unregister", + methods: [method.repoId], + }; + await this.session.send(msg); + } + getBranchList(method) { + return this.streaming.getBranchList(method); + } + getSubscriptionList(method, branchKey) { + return this.streaming.getSubscriptionList(method, branchKey); + } + closeAllSubscriptions(method, branchKey) { + this.streaming.closeMultipleSubscriptions(method, branchKey); + } + pushData(method, data, branches) { + this.streaming.pushData(method, data, branches); + } + pushDataToSingle(method, subscription, data) { + this.streaming.pushDataToSingle(method, subscription, data); + } + closeSingleSubscription(method, subscription) { + this.streaming.closeSingleSubscription(method, subscription); + } + acceptRequestOnBranch(requestContext, method, branch) { + this.streaming.acceptRequestOnBranch(requestContext, method, branch); + } + rejectRequest(requestContext, method, reason) { + this.streaming.rejectRequest(requestContext, method, reason); + } + onSubRequest(callback) { + this.streaming.onSubRequest(callback); + } + onSubAdded(callback) { + this.streaming.onSubAdded(callback); + } + onSubRemoved(callback) { + this.streaming.onSubRemoved(callback); + } + handleInvokeMessage(msg) { + const invocationId = msg.invocation_id; + const callerId = msg.caller_id; + const methodId = msg.method_id; + const args = msg.arguments_kv; + const methodList = this.serverRepository.getList(); + const method = methodList.filter((m) => { + return m.repoId === methodId; + })[0]; + if (method === undefined) { + return; + } + const client = this.clientRepository.getServerById(callerId)?.instance; + const invocationArgs = { args, instance: client }; + this.callbacks.execute("onInvoked", method, invocationId, invocationArgs); + } + } + + class UserSubscription { + repository; + subscriptionData; + get requestArguments() { + return this.subscriptionData.params.arguments || {}; + } + get servers() { + return this.subscriptionData.trackedServers.reduce((servers, pair) => { + if (pair.subscriptionId) { + const server = this.repository.getServerById(pair.serverId)?.instance; + if (server) { + servers.push(server); + } + } + return servers; + }, []); + } + get serverInstance() { + return this.servers[0]; + } + get stream() { + return this.subscriptionData.method; + } + constructor(repository, subscriptionData) { + this.repository = repository; + this.subscriptionData = subscriptionData; + } + onData(dataCallback) { + if (typeof dataCallback !== "function") { + throw new TypeError("The data callback must be a function."); + } + this.subscriptionData.handlers.onData.push(dataCallback); + if (this.subscriptionData.handlers.onData.length === 1 && this.subscriptionData.queued.data.length > 0) { + this.subscriptionData.queued.data.forEach((dataItem) => { + dataCallback(dataItem); + }); + } + } + onClosed(closedCallback) { + if (typeof closedCallback !== "function") { + throw new TypeError("The callback must be a function."); + } + this.subscriptionData.handlers.onClosed.push(closedCallback); + } + onFailed(callback) { + } + onConnected(callback) { + if (typeof callback !== "function") { + throw new TypeError("The callback must be a function."); + } + this.subscriptionData.handlers.onConnected.push(callback); + } + close() { + this.subscriptionData.close(); + } + setNewSubscription(newSub) { + this.subscriptionData = newSub; + } + } + + class TimedCache { + config; + cache = []; + timeoutIds = []; + constructor(config) { + this.config = config; + } + add(element) { + const id = nanoid$1(10); + this.cache.push({ id, element }); + const timeoutId = setTimeout(() => { + const elementIdx = this.cache.findIndex((entry) => entry.id === id); + if (elementIdx < 0) { + return; + } + this.cache.splice(elementIdx, 1); + }, this.config.ELEMENT_TTL_MS); + this.timeoutIds.push(timeoutId); + } + flush() { + const elements = this.cache.map((entry) => entry.element); + this.timeoutIds.forEach((id) => clearInterval(id)); + this.cache = []; + this.timeoutIds = []; + return elements; + } + } + + const STATUS_AWAITING_ACCEPT = "awaitingAccept"; + const STATUS_SUBSCRIBED = "subscribed"; + const ERR_MSG_SUB_FAILED = "Subscription failed."; + const ERR_MSG_SUB_REJECTED = "Subscription rejected."; + const ON_CLOSE_MSG_SERVER_INIT = "ServerInitiated"; + const ON_CLOSE_MSG_CLIENT_INIT = "ClientInitiated"; + class ClientStreaming { + session; + repository; + logger; + subscriptionsList = {}; + timedCache = new TimedCache({ ELEMENT_TTL_MS: 10000 }); + subscriptionIdToLocalKeyMap = {}; + nextSubLocalKey = 0; + constructor(session, repository, logger) { + this.session = session; + this.repository = repository; + this.logger = logger; + session.on("subscribed", this.handleSubscribed); + session.on("event", this.handleEventData); + session.on("subscription-cancelled", this.handleSubscriptionCancelled); + } + subscribe(streamingMethod, params, targetServers, success, error, existingSub) { + if (targetServers.length === 0) { + error({ + method: streamingMethod, + called_with: params.arguments, + message: ERR_MSG_SUB_FAILED + " No available servers matched the target params.", + }); + return; + } + const subLocalKey = this.getNextSubscriptionLocalKey(); + const pendingSub = this.registerSubscription(subLocalKey, streamingMethod, params, success, error, params.methodResponseTimeout || 10000, existingSub); + if (typeof pendingSub !== "object") { + error({ + method: streamingMethod, + called_with: params.arguments, + message: ERR_MSG_SUB_FAILED + " Unable to register the user callbacks.", + }); + return; + } + targetServers.forEach((target) => { + const serverId = target.server.id; + const method = target.methods.find((m) => m.name === streamingMethod.name); + if (!method) { + this.logger.error(`can not find method ${streamingMethod.name} for target ${target.server.id}`); + return; + } + pendingSub.trackedServers.push({ + serverId, + subscriptionId: undefined, + }); + const msg = { + type: "subscribe", + server_id: serverId, + method_id: method.gatewayId, + arguments_kv: params.arguments, + }; + this.session.send(msg, { serverId, subLocalKey }) + .then((m) => this.handleSubscribed(m)) + .catch((err) => this.handleErrorSubscribing(err)); + }); + } + drainSubscriptions() { + const existing = Object.values(this.subscriptionsList); + this.subscriptionsList = {}; + this.subscriptionIdToLocalKeyMap = {}; + return existing; + } + drainSubscriptionsCache() { + return this.timedCache.flush(); + } + getNextSubscriptionLocalKey() { + const current = this.nextSubLocalKey; + this.nextSubLocalKey += 1; + return current; + } + registerSubscription(subLocalKey, method, params, success, error, timeout, existingSub) { + const subsInfo = { + localKey: subLocalKey, + status: STATUS_AWAITING_ACCEPT, + method, + params, + success, + error, + trackedServers: [], + handlers: { + onData: existingSub?.handlers.onData || [], + onClosed: existingSub?.handlers.onClosed || [], + onConnected: existingSub?.handlers.onConnected || [], + }, + queued: { + data: [], + closers: [], + }, + timeoutId: undefined, + close: () => this.closeSubscription(subLocalKey), + subscription: existingSub?.subscription + }; + if (!existingSub) { + if (params.onData) { + subsInfo.handlers.onData.push(params.onData); + } + if (params.onClosed) { + subsInfo.handlers.onClosed.push(params.onClosed); + } + if (params.onConnected) { + subsInfo.handlers.onConnected.push(params.onConnected); + } + } + this.subscriptionsList[subLocalKey] = subsInfo; + subsInfo.timeoutId = setTimeout(() => { + if (this.subscriptionsList[subLocalKey] === undefined) { + return; + } + const pendingSub = this.subscriptionsList[subLocalKey]; + if (pendingSub.status === STATUS_AWAITING_ACCEPT) { + error({ + method, + called_with: params.arguments, + message: ERR_MSG_SUB_FAILED + " Subscription attempt timed out after " + timeout + " ms.", + }); + delete this.subscriptionsList[subLocalKey]; + } + else if (pendingSub.status === STATUS_SUBSCRIBED && pendingSub.trackedServers.length > 0) { + pendingSub.trackedServers = pendingSub.trackedServers.filter((server) => { + return (typeof server.subscriptionId !== "undefined"); + }); + delete pendingSub.timeoutId; + if (pendingSub.trackedServers.length <= 0) { + this.callOnClosedHandlers(pendingSub); + delete this.subscriptionsList[subLocalKey]; + } + } + }, timeout); + return subsInfo; + } + handleErrorSubscribing = (errorResponse) => { + const tag = errorResponse._tag; + const subLocalKey = tag.subLocalKey; + const pendingSub = this.subscriptionsList[subLocalKey]; + if (typeof pendingSub !== "object") { + return; + } + pendingSub.trackedServers = pendingSub.trackedServers.filter((server) => { + return server.serverId !== tag.serverId; + }); + if (pendingSub.trackedServers.length <= 0) { + clearTimeout(pendingSub.timeoutId); + if (pendingSub.status === STATUS_AWAITING_ACCEPT) { + const reason = (typeof errorResponse.reason === "string" && errorResponse.reason !== "") ? + ' Publisher said "' + errorResponse.reason + '".' : + " No reason given."; + const callArgs = typeof pendingSub.params.arguments === "object" ? + JSON.stringify(pendingSub.params.arguments) : + "{}"; + pendingSub.error({ + message: ERR_MSG_SUB_REJECTED + reason + " Called with:" + callArgs, + called_with: pendingSub.params.arguments, + method: pendingSub.method, + }); + } + else if (pendingSub.status === STATUS_SUBSCRIBED) { + this.callOnClosedHandlers(pendingSub); + } + delete this.subscriptionsList[subLocalKey]; + } + }; + handleSubscribed = (msg) => { + const subLocalKey = msg._tag.subLocalKey; + const pendingSub = this.subscriptionsList[subLocalKey]; + if (typeof pendingSub !== "object") { + return; + } + const serverId = msg._tag.serverId; + const acceptingServer = pendingSub.trackedServers + .filter((server) => { + return server.serverId === serverId; + })[0]; + if (typeof acceptingServer !== "object") { + return; + } + acceptingServer.subscriptionId = msg.subscription_id; + this.subscriptionIdToLocalKeyMap[msg.subscription_id] = subLocalKey; + const isFirstResponse = (pendingSub.status === STATUS_AWAITING_ACCEPT); + pendingSub.status = STATUS_SUBSCRIBED; + if (isFirstResponse) { + let reconnect = false; + let sub = pendingSub.subscription; + if (sub) { + sub.setNewSubscription(pendingSub); + pendingSub.success(sub); + reconnect = true; + } + else { + sub = new UserSubscription(this.repository, pendingSub); + pendingSub.subscription = sub; + pendingSub.success(sub); + } + for (const handler of pendingSub.handlers.onConnected) { + try { + handler(sub.serverInstance, reconnect); + } + catch (e) { + } + } + } + }; + handleEventData = (msg) => { + const subLocalKey = this.subscriptionIdToLocalKeyMap[msg.subscription_id]; + if (typeof subLocalKey === "undefined") { + return; + } + const subscription = this.subscriptionsList[subLocalKey]; + if (typeof subscription !== "object") { + return; + } + const trackedServersFound = subscription.trackedServers.filter((s) => { + return s.subscriptionId === msg.subscription_id; + }); + if (trackedServersFound.length !== 1) { + return; + } + const isPrivateData = msg.oob; + const sendingServerId = trackedServersFound[0].serverId; + const server = this.repository.getServerById(sendingServerId); + const receivedStreamData = () => { + return { + data: msg.data, + server: server?.instance ?? {}, + requestArguments: subscription.params.arguments, + message: undefined, + private: isPrivateData, + }; + }; + const onDataHandlers = subscription.handlers.onData; + const queuedData = subscription.queued.data; + if (onDataHandlers.length > 0) { + onDataHandlers.forEach((callback) => { + if (typeof callback === "function") { + callback(receivedStreamData()); + } + }); + } + else { + queuedData.push(receivedStreamData()); + } + }; + handleSubscriptionCancelled = (msg) => { + const subLocalKey = this.subscriptionIdToLocalKeyMap[msg.subscription_id]; + if (typeof subLocalKey === "undefined") { + return; + } + const subscription = this.subscriptionsList[subLocalKey]; + if (typeof subscription !== "object") { + return; + } + const expectedNewLength = subscription.trackedServers.length - 1; + subscription.trackedServers = subscription.trackedServers.filter((server) => { + if (server.subscriptionId === msg.subscription_id) { + subscription.queued.closers.push(server.serverId); + return false; + } + else { + return true; + } + }); + if (subscription.trackedServers.length !== expectedNewLength) { + return; + } + if (subscription.trackedServers.length <= 0) { + this.timedCache.add(subscription); + clearTimeout(subscription.timeoutId); + this.callOnClosedHandlers(subscription); + delete this.subscriptionsList[subLocalKey]; + } + delete this.subscriptionIdToLocalKeyMap[msg.subscription_id]; + }; + callOnClosedHandlers(subscription, reason) { + const closersCount = subscription.queued.closers.length; + const closingServerId = (closersCount > 0) ? subscription.queued.closers[closersCount - 1] : null; + let closingServer; + if (closingServerId !== undefined && typeof closingServerId === "string") { + closingServer = this.repository.getServerById(closingServerId)?.instance ?? {}; + } + subscription.handlers.onClosed.forEach((callback) => { + if (typeof callback !== "function") { + return; + } + callback({ + message: reason || ON_CLOSE_MSG_SERVER_INIT, + requestArguments: subscription.params.arguments || {}, + server: closingServer, + stream: subscription.method, + }); + }); + } + closeSubscription(subLocalKey) { + const subscription = this.subscriptionsList[subLocalKey]; + if (typeof subscription !== "object") { + return; + } + subscription.trackedServers.forEach((server) => { + if (typeof server.subscriptionId === "undefined") { + return; + } + subscription.queued.closers.push(server.serverId); + this.session.sendFireAndForget({ + type: "unsubscribe", + subscription_id: server.subscriptionId, + reason_uri: "", + reason: ON_CLOSE_MSG_CLIENT_INIT, + }); + delete this.subscriptionIdToLocalKeyMap[server.subscriptionId]; + }); + subscription.trackedServers = []; + this.callOnClosedHandlers(subscription, ON_CLOSE_MSG_CLIENT_INIT); + delete this.subscriptionsList[subLocalKey]; + } + } + + class ClientProtocol { + session; + repository; + logger; + streaming; + constructor(session, repository, logger) { + this.session = session; + this.repository = repository; + this.logger = logger; + session.on("peer-added", (msg) => this.handlePeerAdded(msg)); + session.on("peer-removed", (msg) => this.handlePeerRemoved(msg)); + session.on("methods-added", (msg) => this.handleMethodsAddedMessage(msg)); + session.on("methods-removed", (msg) => this.handleMethodsRemovedMessage(msg)); + this.streaming = new ClientStreaming(session, repository, logger); + } + subscribe(stream, options, targetServers, success, error, existingSub) { + this.streaming.subscribe(stream, options, targetServers, success, error, existingSub); + } + invoke(id, method, args, target) { + const serverId = target.id; + const methodId = method.gatewayId; + const msg = { + type: "call", + server_id: serverId, + method_id: methodId, + arguments_kv: args, + }; + return this.session.send(msg, { invocationId: id, serverId }) + .then((m) => this.handleResultMessage(m)) + .catch((err) => this.handleInvocationError(err)); + } + drainSubscriptions() { + return this.streaming.drainSubscriptions(); + } + drainSubscriptionsCache() { + return this.streaming.drainSubscriptionsCache(); + } + handlePeerAdded(msg) { + const newPeerId = msg.new_peer_id; + const remoteId = msg.identity; + const isLocal = msg.meta ? msg.meta.local : true; + const pid = Number(remoteId.process); + const serverInfo = { + machine: remoteId.machine, + pid: isNaN(pid) ? remoteId.process : pid, + instance: remoteId.instance, + application: remoteId.application, + applicationName: remoteId.applicationName, + environment: remoteId.environment, + region: remoteId.region, + user: remoteId.user, + windowId: remoteId.windowId, + peerId: newPeerId, + api: remoteId.api, + isLocal + }; + this.repository.addServer(serverInfo, newPeerId); + } + handlePeerRemoved(msg) { + const removedPeerId = msg.removed_id; + const reason = msg.reason; + this.repository.removeServerById(removedPeerId, reason); + } + handleMethodsAddedMessage(msg) { + const serverId = msg.server_id; + const methods = msg.methods; + methods.forEach((method) => { + this.repository.addServerMethod(serverId, method); + }); + } + handleMethodsRemovedMessage(msg) { + const serverId = msg.server_id; + const methodIdList = msg.methods; + const server = this.repository.getServerById(serverId); + if (server) { + const serverMethodKeys = Object.keys(server.methods); + serverMethodKeys.forEach((methodKey) => { + const method = server.methods[methodKey]; + if (methodIdList.indexOf(method.gatewayId) > -1) { + this.repository.removeServerMethod(serverId, methodKey); + } + }); + } + } + handleResultMessage(msg) { + const invocationId = msg._tag.invocationId; + const result = msg.result; + const serverId = msg._tag.serverId; + const server = this.repository.getServerById(serverId); + return { + invocationId, + result, + instance: server?.instance, + status: InvokeStatus.Success, + message: "" + }; + } + handleInvocationError(msg) { + this.logger.debug(`handle invocation error ${JSON.stringify(msg)}`); + if ("_tag" in msg) { + const invocationId = msg._tag.invocationId; + const serverId = msg._tag.serverId; + const server = this.repository.getServerById(serverId); + const message = msg.reason; + const context = msg.context; + return { + invocationId, + result: context, + instance: server?.instance, + status: InvokeStatus.Error, + message + }; + } + else { + return { + invocationId: "", + message: msg.message, + status: InvokeStatus.Error, + error: msg + }; + } + } + } + + function gW3ProtocolFactory (instance, connection, clientRepository, serverRepository, libConfig, interop) { + const logger = libConfig.logger.subLogger("gw3-protocol"); + let resolveReadyPromise; + const readyPromise = new Promise((resolve) => { + resolveReadyPromise = resolve; + }); + const session = connection.domain("agm", ["subscribed"]); + const server = new ServerProtocol(session, clientRepository, serverRepository, logger.subLogger("server")); + const client = new ClientProtocol(session, clientRepository, logger.subLogger("client")); + async function handleReconnect() { + logger.info("reconnected - will replay registered methods and subscriptions"); + client.drainSubscriptionsCache().forEach((sub) => { + const methodInfo = sub.method; + const params = Object.assign({}, sub.params); + logger.info(`trying to soft-re-subscribe to method ${methodInfo.name}, with params: ${JSON.stringify(params)}`); + interop.client.subscribe(methodInfo, params, undefined, undefined, sub).then(() => logger.info(`soft-subscribing to method ${methodInfo.name} DONE`)).catch((error) => logger.warn(`subscribing to method ${methodInfo.name} failed: ${JSON.stringify(error)}}`)); + }); + const reconnectionPromises = []; + const existingSubscriptions = client.drainSubscriptions(); + for (const sub of existingSubscriptions) { + const methodInfo = sub.method; + const params = Object.assign({}, sub.params); + logger.info(`trying to re-subscribe to method ${methodInfo.name}, with params: ${JSON.stringify(params)}`); + reconnectionPromises.push(interop.client.subscribe(methodInfo, params, undefined, undefined, sub).then(() => logger.info(`subscribing to method ${methodInfo.name} DONE`))); + } + const registeredMethods = serverRepository.getList(); + serverRepository.reset(); + for (const method of registeredMethods) { + const def = method.definition; + if (method.stream) { + reconnectionPromises.push(interop.server.createStream(def, method.streamCallbacks, undefined, undefined, method.stream) + .then(() => logger.info(`subscribing to method ${def.name} DONE`)) + .catch(() => logger.warn(`subscribing to method ${def.name} FAILED`))); + } + else if (method?.theFunction?.userCallback) { + reconnectionPromises.push(interop.register(def, method.theFunction.userCallback) + .then(() => logger.info(`registering method ${def.name} DONE`)) + .catch(() => logger.warn(`registering method ${def.name} FAILED`))); + } + else if (method?.theFunction?.userCallbackAsync) { + reconnectionPromises.push(interop.registerAsync(def, method.theFunction.userCallbackAsync) + .then(() => logger.info(`registering method ${def.name} DONE`)) + .catch(() => logger.warn(`registering method ${def.name} FAILED`))); + } + } + await Promise.all(reconnectionPromises); + logger.info("Interop is re-announced"); + } + function handleInitialJoin() { + if (resolveReadyPromise) { + resolveReadyPromise({ + client, + server, + }); + resolveReadyPromise = undefined; + } + } + session.onJoined((reconnect) => { + clientRepository.addServer(instance, connection.peerId); + if (reconnect) { + handleReconnect().then(() => connection.setLibReAnnounced({ name: "interop" })).catch((error) => logger.warn(`Error while re-announcing interop: ${JSON.stringify(error)}`)); + } + else { + handleInitialJoin(); + } + }); + session.onLeft(() => { + clientRepository.reset(); + }); + session.join(); + return readyPromise; + } + + class Interop { + instance; + readyPromise; + client; + server; + unwrappedInstance; + protocol; + clientRepository; + serverRepository; + constructor(configuration) { + if (typeof configuration === "undefined") { + throw new Error("configuration is required"); + } + if (typeof configuration.connection === "undefined") { + throw new Error("configuration.connections is required"); + } + const connection = configuration.connection; + if (typeof configuration.methodResponseTimeout !== "number") { + configuration.methodResponseTimeout = 30 * 1000; + } + if (typeof configuration.waitTimeoutMs !== "number") { + configuration.waitTimeoutMs = 30 * 1000; + } + this.unwrappedInstance = new InstanceWrapper(this, undefined, connection); + this.instance = this.unwrappedInstance.unwrap(); + this.clientRepository = new ClientRepository(configuration.logger.subLogger("cRep"), this); + this.serverRepository = new ServerRepository(); + let protocolPromise; + if (connection.protocolVersion === 3) { + protocolPromise = gW3ProtocolFactory(this.instance, connection, this.clientRepository, this.serverRepository, configuration, this); + } + else { + throw new Error(`protocol ${connection.protocolVersion} not supported`); + } + this.readyPromise = protocolPromise.then((protocol) => { + this.protocol = protocol; + this.client = new Client(this.protocol, this.clientRepository, this.instance, configuration); + this.server = new Server(this.protocol, this.serverRepository); + return this; + }); + } + ready() { + return this.readyPromise; + } + serverRemoved(callback) { + return this.client.serverRemoved(callback); + } + serverAdded(callback) { + return this.client.serverAdded(callback); + } + serverMethodRemoved(callback) { + return this.client.serverMethodRemoved(callback); + } + serverMethodAdded(callback) { + return this.client.serverMethodAdded(callback); + } + methodRemoved(callback) { + return this.client.methodRemoved(callback); + } + methodAdded(callback) { + return this.client.methodAdded(callback); + } + methodsForInstance(instance) { + return this.client.methodsForInstance(instance); + } + methods(methodFilter) { + return this.client.methods(methodFilter); + } + servers(methodFilter) { + return this.client.servers(methodFilter); + } + subscribe(method, options, successCallback, errorCallback) { + return this.client.subscribe(method, options, successCallback, errorCallback); + } + createStream(streamDef, callbacks, successCallback, errorCallback) { + return this.server.createStream(streamDef, callbacks, successCallback, errorCallback); + } + unregister(methodFilter) { + return this.server.unregister(methodFilter); + } + registerAsync(methodDefinition, callback) { + return this.server.registerAsync(methodDefinition, callback); + } + register(methodDefinition, callback) { + return this.server.register(methodDefinition, callback); + } + invoke(methodFilter, argumentObj, target, additionalOptions, success, error) { + return this.client.invoke(methodFilter, argumentObj, target, additionalOptions, success, error); + } + waitForMethod(name) { + const pw = new PromiseWrapper$1(); + const unsubscribe = this.client.methodAdded((m) => { + if (m.name === name) { + unsubscribe(); + pw.resolve(m); + } + }); + return pw.promise; + } + } + + const successMessages = ["subscribed", "success"]; + class MessageBus { + connection; + logger; + peerId; + session; + subscriptions; + readyPromise; + constructor(connection, logger) { + this.connection = connection; + this.logger = logger; + this.peerId = connection.peerId; + this.subscriptions = []; + this.session = connection.domain("bus", successMessages); + this.readyPromise = this.session.join(); + this.readyPromise.then(() => { + this.watchOnEvent(); + }); + } + ready() { + return this.readyPromise; + } + publish = (topic, data, options) => { + const { routingKey, target } = options || {}; + const args = this.removeEmptyValues({ + type: "publish", + topic, + data, + peer_id: this.peerId, + routing_key: routingKey, + target_identity: target + }); + this.session.send(args); + }; + subscribe = (topic, callback, options) => { + return new Promise((resolve, reject) => { + const { routingKey, target } = options || {}; + const args = this.removeEmptyValues({ + type: "subscribe", + topic, + peer_id: this.peerId, + routing_key: routingKey, + source: target + }); + this.session.send(args) + .then((response) => { + const { subscription_id } = response; + this.subscriptions.push({ subscription_id, topic, callback, source: target }); + resolve({ + unsubscribe: () => { + this.session.send({ type: "unsubscribe", subscription_id, peer_id: this.peerId }); + this.subscriptions = this.subscriptions.filter((s) => s.subscription_id !== subscription_id); + return Promise.resolve(); + } + }); + }) + .catch((error) => reject(error)); + }); + }; + watchOnEvent = () => { + this.session.on("event", (args) => { + const { data, subscription_id } = args; + const source = args["publisher-identity"]; + const subscription = this.subscriptions.find((s) => s.subscription_id === subscription_id); + if (subscription) { + if (!subscription.source) { + subscription.callback(data, subscription.topic, source); + } + else { + if (this.keysMatch(subscription.source, source)) { + subscription.callback(data, subscription.topic, source); + } + } + } + }); + }; + removeEmptyValues(obj) { + const cleaned = {}; + Object.keys(obj).forEach((key) => { + if (obj[key] !== undefined && obj[key] !== null) { + cleaned[key] = obj[key]; + } + }); + return cleaned; + } + keysMatch(obj1, obj2) { + const keysObj1 = Object.keys(obj1); + let allMatch = true; + keysObj1.forEach((key) => { + if (obj1[key] !== obj2[key]) { + allMatch = false; + } + }); + return allMatch; + } + } + + const IOConnectCoreFactory = (userConfig, ext) => { + const iodesktop = typeof window === "object" ? (window.iodesktop ?? window.glue42gd) : undefined; + const preloadPromise = typeof window === "object" ? (window.gdPreloadPromise ?? Promise.resolve()) : Promise.resolve(); + const glueInitTimer = timer("glue"); + userConfig = userConfig || {}; + ext = ext || {}; + const internalConfig = prepareConfig$1(userConfig, ext, iodesktop); + let _connection; + let _interop; + let _logger; + let _metrics; + let _contexts; + let _bus; + let _allowTrace; + const libs = {}; + function registerLib(name, inner, t) { + _allowTrace = _logger.canPublish("trace"); + if (_allowTrace) { + _logger.trace(`registering ${name} module`); + } + const done = (e) => { + inner.initTime = t.stop(); + inner.initEndTime = t.endTime; + inner.marks = t.marks; + if (!_allowTrace) { + return; + } + const traceMessage = e ? + `${name} failed - ${e.message}` : + `${name} is ready - ${t.endTime - t.startTime}`; + _logger.trace(traceMessage); + }; + inner.initStartTime = t.startTime; + if (inner.ready) { + inner.ready() + .then(() => { + done(); + }) + .catch((e) => { + const error = typeof e === "string" ? new Error(e) : e; + done(error); + }); + } + else { + done(); + } + if (!Array.isArray(name)) { + name = [name]; + } + name.forEach((n) => { + libs[n] = inner; + IOConnectCoreFactory[n] = inner; + }); + } + function setupConnection() { + const initTimer = timer("connection"); + _connection = new Connection(internalConfig.connection, _logger.subLogger("connection")); + let authPromise = Promise.resolve(internalConfig.auth); + if (internalConfig.connection && !internalConfig.auth) { + if (iodesktop) { + authPromise = iodesktop.getGWToken() + .then((token) => { + return { + gatewayToken: token + }; + }); + } + else if (typeof window !== "undefined" && window?.glue42electron) { + if (typeof window.glue42electron.gwToken === "string") { + authPromise = Promise.resolve({ + gatewayToken: window.glue42electron.gwToken + }); + } + } + else { + authPromise = Promise.reject("You need to provide auth information"); + } + } + return authPromise + .then((authConfig) => { + initTimer.mark("auth-promise-resolved"); + let authRequest; + if (Object.prototype.toString.call(authConfig) === "[object Object]") { + authRequest = authConfig; + } + else { + throw new Error("Invalid auth object - " + JSON.stringify(authConfig)); + } + return _connection.login(authRequest); + }) + .then(() => { + registerLib("connection", _connection, initTimer); + return internalConfig; + }) + .catch((e) => { + if (_connection) { + _connection.logout(); + } + throw e; + }); + } + function setupLogger() { + const initTimer = timer("logger"); + _logger = new Logger$1(`${internalConfig.connection.identity?.application}`, undefined, internalConfig.customLogger); + _logger.consoleLevel(internalConfig.logger.console); + _logger.publishLevel(internalConfig.logger.publish); + if (_logger.canPublish("debug")) { + _logger.debug("initializing glue..."); + } + registerLib("logger", _logger, initTimer); + return Promise.resolve(undefined); + } + function setupMetrics() { + const initTimer = timer("metrics"); + const config = internalConfig.metrics; + const metricsPublishingEnabledFunc = iodesktop?.getMetricsPublishingEnabled; + const identity = internalConfig.connection.identity; + const canUpdateMetric = metricsPublishingEnabledFunc ? metricsPublishingEnabledFunc : () => true; + const disableAutoAppSystem = (typeof config !== "boolean" && config.disableAutoAppSystem) ?? false; + _metrics = metrics({ + connection: config ? _connection : undefined, + logger: _logger.subLogger("metrics"), + canUpdateMetric, + system: "Glue42", + service: identity?.service ?? iodesktop?.applicationName ?? internalConfig.application, + instance: identity?.instance ?? identity?.windowId ?? nanoid$1(10), + disableAutoAppSystem, + pagePerformanceMetrics: typeof config !== "boolean" ? config?.pagePerformanceMetrics : undefined + }); + registerLib("metrics", _metrics, initTimer); + return Promise.resolve(); + } + function setupInterop() { + const initTimer = timer("interop"); + const agmConfig = { + connection: _connection, + logger: _logger.subLogger("interop"), + }; + _interop = new Interop(agmConfig); + Logger$1.Interop = _interop; + registerLib(["interop", "agm"], _interop, initTimer); + return Promise.resolve(); + } + function setupContexts() { + const hasActivities = (internalConfig.activities && _connection.protocolVersion === 3); + const needsContexts = internalConfig.contexts || hasActivities; + if (needsContexts) { + const initTimer = timer("contexts"); + _contexts = new ContextsModule({ + connection: _connection, + logger: _logger.subLogger("contexts"), + trackAllContexts: typeof internalConfig.contexts === "object" ? internalConfig.contexts.trackAllContexts : false, + reAnnounceKnownContexts: typeof internalConfig.contexts === "object" ? internalConfig.contexts.reAnnounceKnownContexts : false + }); + registerLib("contexts", _contexts, initTimer); + return _contexts; + } + else { + const replayer = _connection.replayer; + if (replayer) { + replayer.drain(ContextMessageReplaySpec.name); + } + } + } + async function setupBus() { + if (!internalConfig.bus) { + return Promise.resolve(); + } + const initTimer = timer("bus"); + _bus = new MessageBus(_connection, _logger.subLogger("bus")); + registerLib("bus", _bus, initTimer); + return Promise.resolve(); + } + function setupExternalLibs(externalLibs) { + try { + externalLibs.forEach((lib) => { + setupExternalLib(lib.name, lib.create); + }); + return Promise.resolve(); + } + catch (e) { + return Promise.reject(e); + } + } + function setupExternalLib(name, createCallback) { + const initTimer = timer(name); + const lib = createCallback(libs); + if (lib) { + registerLib(name, lib, initTimer); + } + } + function waitForLibs() { + const libsReadyPromises = Object.keys(libs).map((key) => { + const lib = libs[key]; + return lib.ready ? + lib.ready() : Promise.resolve(); + }); + return Promise.all(libsReadyPromises); + } + function constructGlueObject() { + const feedbackFunc = (feedbackInfo) => { + if (!_interop) { + return; + } + _interop.invoke("T42.ACS.Feedback", feedbackInfo, "best"); + }; + const info = { + coreVersion: version$1, + version: internalConfig.version + }; + glueInitTimer.stop(); + const glue = { + feedback: feedbackFunc, + info, + logger: _logger, + interop: _interop, + agm: _interop, + connection: _connection, + metrics: _metrics, + contexts: _contexts, + bus: _bus, + version: internalConfig.version, + userConfig, + done: () => { + _logger?.info("done called by user..."); + return _connection.logout(); + } + }; + glue.performance = { + get glueVer() { + return internalConfig.version; + }, + get glueConfig() { + return JSON.stringify(userConfig); + }, + get browser() { + return window.performance.timing.toJSON(); + }, + get memory() { + return window.performance.memory; + }, + get initTimes() { + const all = getAllTimers(); + return Object.keys(all).map((key) => { + const t = all[key]; + return { + name: key, + duration: t.endTime - t.startTime, + marks: t.marks, + startTime: t.startTime, + endTime: t.endTime + }; + }); + } + }; + Object.keys(libs).forEach((key) => { + const lib = libs[key]; + glue[key] = lib; + }); + glue.config = {}; + Object.keys(internalConfig).forEach((k) => { + glue.config[k] = internalConfig[k]; + }); + if (ext && ext.extOptions) { + Object.keys(ext.extOptions).forEach((k) => { + glue.config[k] = ext?.extOptions[k]; + }); + } + if (ext?.enrichGlue) { + ext.enrichGlue(glue); + } + if (iodesktop && iodesktop.updatePerfData) { + iodesktop.updatePerfData(glue.performance); + } + if (glue.agm) { + const deprecatedDecorator = (fn, wrong, proper) => { + return function () { + glue.logger.warn(`glue.js - 'glue.agm.${wrong}' method is deprecated, use 'glue.interop.${proper}' instead.`); + return fn.apply(glue.agm, arguments); + }; + }; + const agmAny = glue.agm; + agmAny.method_added = deprecatedDecorator(glue.agm.methodAdded, "method_added", "methodAdded"); + agmAny.method_removed = deprecatedDecorator(glue.agm.methodRemoved, "method_removed", "methodRemoved"); + agmAny.server_added = deprecatedDecorator(glue.agm.serverAdded, "server_added", "serverAdded"); + agmAny.server_method_aded = deprecatedDecorator(glue.agm.serverMethodAdded, "server_method_aded", "serverMethodAdded"); + agmAny.server_method_removed = deprecatedDecorator(glue.agm.serverMethodRemoved, "server_method_removed", "serverMethodRemoved"); + } + return glue; + } + async function registerInstanceIfNeeded() { + const RegisterInstanceMethodName = "T42.ACS.RegisterInstance"; + if (Utils$1.isNode() && typeof process.env._GD_STARTING_CONTEXT_ === "undefined" && typeof userConfig?.application !== "undefined") { + const isMethodAvailable = _interop.methods({ name: RegisterInstanceMethodName }).length > 0; + if (isMethodAvailable) { + try { + await _interop.invoke(RegisterInstanceMethodName, { appName: userConfig?.application, pid: process.pid }); + } + catch (error) { + const typedError = error; + _logger.error(`Cannot register as an instance: ${JSON.stringify(typedError.message)}`); + } + } + } + } + return preloadPromise + .then(setupLogger) + .then(setupConnection) + .then(() => Promise.all([setupMetrics(), setupInterop(), setupContexts(), setupBus()])) + .then(() => _interop.readyPromise) + .then(() => registerInstanceIfNeeded()) + .then(() => { + return setupExternalLibs(internalConfig.libs || []); + }) + .then(waitForLibs) + .then(constructGlueObject) + .catch((err) => { + return Promise.reject({ + err, + libs + }); + }); + }; + if (typeof window !== "undefined") { + window.IOConnectCore = IOConnectCoreFactory; + } + IOConnectCoreFactory.version = version$1; + IOConnectCoreFactory.default = IOConnectCoreFactory; + + class ActivityEntity { + constructor(id) { + this._id = id; + } + get id() { + return this._id; + } + _update(other) { + if (other._id !== this._id) { + throw Error("Can not update from entity with different id."); + } + this._updateCore(other); + } + _updateCore(other) { + return; + } + _beforeDelete(other) { + return; + } + } + + function isNumber(arg) { + return typeof arg === "number"; + } + function isString(arg) { + return typeof arg === "string"; + } + function isObject(arg) { + return typeof arg === "object" && !Array.isArray(arg) && arg !== null; + } + function isArray(arg) { + if (Array.isArray) { + return Array.isArray(arg); + } + return toString.call(arg) === "[object Array]"; + } + function isUndefined(arg) { + return typeof arg === "undefined"; + } + function isUndefinedOrNull(arg) { + return arg === null || typeof arg === "undefined"; + } + function isNullOrWhiteSpace(str) { + return (typeof str !== "string" || !str || str.length === 0 || /^\s*$/.test(str)); + } + function isBoolean(obj) { + return obj === true || obj === false || toString.call(obj) === "[object Boolean]"; + } + function isFunction(arg) { + return !!(arg && arg.constructor && arg.call && arg.apply); + } + function some(array, predicate) { + for (let index = 0; index < array.length; index++) { + if (predicate(array[index], index)) { + return true; + } + } + return false; + } + function ifNotUndefined(what, doWithIt) { + if (typeof what !== "undefined") { + doWithIt(what); + } + } + function promisify$1(promise, successCallback, errorCallback) { + if (typeof successCallback !== "function" && typeof errorCallback !== "function") { + return promise; + } + if (typeof successCallback !== "function") { + successCallback = () => { return; }; + } + else if (typeof errorCallback !== "function") { + errorCallback = () => { return; }; + } + promise.then(successCallback, errorCallback); + } + + class ActivityType extends ActivityEntity { + constructor(name, ownerWindow, helperWindows, description) { + super(name); + this._name = name; + this._description = description; + this._ownerWindow = ownerWindow; + this._helperWindows = helperWindows || []; + } + get name() { + return this._name; + } + get description() { + return this._description; + } + get helperWindows() { + return this._helperWindows.map((hw) => this.covertToWindowDef(hw)); + } + get ownerWindow() { + return this.covertToWindowDef(this._ownerWindow); + } + initiate(context, callback, configuration) { + return this._manager.initiate(this._name, context, callback, configuration); + } + _updateCore(other) { + super._updateCore(other); + ifNotUndefined(other._description, (x) => this._description = x); + ifNotUndefined(other._ownerWindow, (x) => this._ownerWindow = x); + ifNotUndefined(other._helperWindows, (x) => this._helperWindows = x); + } + covertToWindowDef(windowType) { + var _a, _b; + return { + type: (_a = windowType === null || windowType === void 0 ? void 0 : windowType.id) === null || _a === void 0 ? void 0 : _a.type, + name: (_b = windowType === null || windowType === void 0 ? void 0 : windowType.id) === null || _b === void 0 ? void 0 : _b.name + }; + } + } + + class WindowType extends ActivityEntity { + constructor(name, appByWindowTypeGetter) { + super(name); + this._name = name; + this._appByWindowTypeGetter = appByWindowTypeGetter; + } + get name() { + return this._name; + } + get config() { + return this._appByWindowTypeGetter(this._name); + } + get windows() { + return this._manager.getWindows({ type: this._name }); + } + create(activity, configuration) { + const definition = Object.assign({ type: this.name, name: this.name, isIndependent: false }, configuration); + return this._manager.createWindow(activity, definition); + } + } + + class EntityEvent { + constructor(entitiy, context) { + this.entity = entitiy; + this.context = context; + } + } + class EntityEventContext { + constructor(eventType) { + this.type = eventType; + } + } + class ActivityStatusChangeEventContext extends EntityEventContext { + constructor(newStatus, oldStatus) { + super(EntityEventType.StatusChange); + this.newStatus = newStatus; + this.oldStatus = oldStatus; + } + } + class ActivityContextChangedEventContext extends EntityEventContext { + constructor(context, updated, removed) { + super(EntityEventType.ActivityContextChange); + this.context = typeof context === "string" ? JSON.parse(context) : context; + this.updated = updated; + this.removed = removed; + } + } + class EntityEventType { + } + EntityEventType.Added = "added"; + EntityEventType.Removed = "removed"; + EntityEventType.Updated = "updated"; + EntityEventType.Closed = "closed"; + EntityEventType.StatusChange = "statusChange"; + EntityEventType.ActivityContextChange = "activityContextUpdate"; + EntityEventType.ActivityWindowEvent = "activityWindowEvent"; + EntityEventType.ActivityWindowJoinedActivity = "joined"; + EntityEventType.ActivityWindowLeftActivity = "left"; + class ActivityState { + } + ActivityState.Created = "created"; + ActivityState.Started = "started"; + ActivityState.Destroyed = "destroyed"; + + class ActivityAGM { + constructor(activity) { + this._activity = activity; + } + register(definition, handler) { + this._ensureHasAgm(); + ActivityAGM.AGM.register(definition, handler); + } + servers() { + this._ensureHasAgm(); + if (isUndefinedOrNull(this._activity)) { + return []; + } + return this._activity.windows.map((w) => { + return w.instance; + }); + } + methods() { + this._ensureHasAgm(); + if (isUndefinedOrNull(this._activity)) { + return []; + } + const windows = this._activity.windows; + const methodNames = []; + const methods = []; + windows.forEach((window) => { + const windowMethods = this.methodsForWindow(window); + windowMethods.forEach((currentWindowMethod) => { + if (methodNames.indexOf(currentWindowMethod.name) === -1) { + methodNames.push(currentWindowMethod.name); + methods.push(currentWindowMethod); + } + }); + }); + return methods; + } + methodsForWindow(window) { + this._ensureHasAgm(); + if (!window.instance) { + return []; + } + return ActivityAGM.AGM.methodsForInstance(window.instance); + } + invoke(methodName, arg, target, options, success, error) { + this._ensureHasAgm(); + const activityServers = this.servers(); + if (isUndefinedOrNull(target)) { + target = "activity.all"; + } + if (isString(target)) { + if (target === "activity.all") ; + else if (target === "activity.best") { + const potentialTargets = activityServers.filter((server) => { + const methods = ActivityAGM.AGM.methodsForInstance(server); + return methods.filter((m) => { + return m.name === methodName; + }).length > 0; + }); + if (potentialTargets.length > 0) { + [potentialTargets[0]]; + } + } + else if (target === "all" || target === "best") { + return promisify$1(ActivityAGM.AGM.invoke(methodName, arg, target, options), success, error); + } + else { + throw new Error("Invalid invoke target " + target); + } + } + else if (isArray(target)) { + if (target.length >= 0) { + const firstElem = target[0]; + if (this._isInstance(firstElem)) { + target.map((instance) => instance); + } + else if (this._isActivityWindow(firstElem)) { + target.map((win) => win.instance); + } + else { + throw new Error("Unknown target object"); + } + } + } + else { + if (this._isInstance(target)) ; + else if (this._isActivityWindow(target)) { + [target.instance]; + } + else { + throw new Error("Unknown target object"); + } + } + throw new Error("Not implemented"); + } + unregister(definition) { + this._ensureHasAgm(); + return ActivityAGM.AGM.unregister(definition); + } + createStream(methodDefinition, subscriptionAddedHandler, subscriptionRemovedHandler) { + this._ensureHasAgm(); + ActivityAGM.AGM.createStream(methodDefinition, { + subscriptionAddedHandler, + subscriptionRemovedHandler, + subscriptionRequestHandler: undefined + }); + } + subscribe(methodDefinition, parameters, target) { + this._ensureHasAgm(); + return ActivityAGM.AGM.subscribe(methodDefinition, parameters); + } + _ensureHasAgm() { + if (isUndefinedOrNull(ActivityAGM.AGM)) { + throw new Error("Agm should be configured to be used in activity"); + } + } + _isInstance(obj) { + return obj.application !== undefined; + } + _isActivityWindow(obj) { + return obj.instance !== undefined; + } + } + + class AttachedActivityDescriptor { + constructor(manager, ownerActivityId, state) { + this._manager = manager; + this._ownerActivityId = ownerActivityId; + this._state = state; + } + get ownerId() { + return this._state.ownerId; + } + get windowIds() { + return this._state.windowIds; + } + get frameColor() { + return this._state.frameColor; + } + get context() { + return this._state.context; + } + get tag() { + return this._state.tag; + } + detach(descriptor) { + descriptor = descriptor || {}; + const merged = {}; + Object.keys(this._state).forEach((prop) => { + merged[prop] = this._state[prop]; + }); + merged.context = descriptor.context || merged.context; + merged.frameColor = descriptor.frameColor || merged.frameColor; + return this._manager.detachActivities(this._ownerActivityId, merged); + } + } + + const nextTick = (cb) => { + setTimeout(cb, 0); + }; + function nodeify(promise, callback) { + if (!isFunction(callback)) { + return promise; + } + promise.then((resp) => { + nextTick(() => { + callback(null, resp); + }); + }, (err) => { + nextTick(() => { + callback(err, null); + }); + }); + } + + class Activity extends ActivityEntity { + constructor(id, actType, status, context, ownerId) { + super(id); + this._id = id; + this._actType = actType; + this._status = status; + this._context = context; + this._ownerId = ownerId; + this._agm = new ActivityAGM(this); + } + get type() { + if (this._manager) { + return this._manager.getActivityType(this._actType); + } + return undefined; + } + get context() { + return this._context; + } + get status() { + return this._status; + } + get owner() { + if (!this._ownerId) { + return null; + } + return this._manager.getWindows({ id: this._ownerId })[0]; + } + get windows() { + return this._manager.getWindows({ activityId: this._id }); + } + get agm() { + return this._agm; + } + addWindow(window, callback) { + return this._manager.addWindowToActivity(this, window, callback); + } + createWindow(windowType, callback) { + return this._manager.createWindow(this, windowType, callback); + } + createStackedWindows(windowTypes, timeout, callback) { + return this._manager.createStackedWindows(this, windowTypes, timeout, callback); + } + leave(window, callback) { + return this._manager.leaveWindowFromActivity(this, window, callback); + } + getWindowsByType(windowType) { + const filter = { activityId: this._id, type: windowType }; + return this._manager.getWindows(filter); + } + setContext(context, callback) { + return this._manager.setActivityContext(this, context, callback); + } + updateContext(context, callback) { + return this._manager.updateActivityContext(this, context, callback); + } + onStatusChange(handler) { + return this._manager.subscribeActivityEvents((a, ns, os) => { + if (a.id === this.id) { + handler(a, ns, os); + } + }); + } + onWindowEvent(handler) { + return this._manager.subscribeWindowEvents((a, w, e) => { + if (a.id === this.id) { + handler(a, w, e); + } + }); + } + onContextChanged(handler) { + this._manager.subscribeActivityContextChanged((act, context, updated, removed) => { + if (act.id === this.id) { + handler(context, updated, removed, act); + } + }); + try { + handler(this.context, this.context, [], this); + } + catch (e) { + return; + } + } + stop() { + this._manager.stopActivity(this); + } + clone(options) { + return this._manager.clone(this, options); + } + attach(activity, tag) { + let activityId; + if (typeof activity === "string") { + activityId = activity; + } + else { + activityId = activity.id; + } + return this._manager.attachActivities(activityId, this.id, tag); + } + onActivityAttached(callback) { + this._manager.subscribeActivitiesAttached((newActId, oldActId, descriptor) => { + if (newActId !== this._id) { + return; + } + callback(descriptor); + }); + } + onDetached(callback) { + this._manager.subscribeActivitiesDetached((newAct, originalActivity, state) => { + if (originalActivity.id !== this._id) { + return; + } + callback(newAct, state); + }); + } + _updateCore(other) { + super._updateCore(other); + ifNotUndefined(other._actType, (x) => this._actType = x); + ifNotUndefined(other._context, (x) => this._context = x); + ifNotUndefined(other._ownerId, (x) => this._ownerId = x); + if (other._status && (!this._status || (this._status.state !== other._status.state))) { + this._status = other._status; + } + } + _updateDescriptors(allStates) { + this._attached = allStates.map((s) => { + return new AttachedActivityDescriptor(this._manager, this._id, s); + }); + } + get attached() { + return this._attached; + } + setFrameColor(color, callback) { + const promise = new Promise((resolve, reject) => { + let callbacksToWait = this.windows.length; + if (callbacksToWait === 0) { + resolve(this); + } + this.windows.forEach((w) => { + w.underlyingWindow.setFrameColor(color, () => { + callbacksToWait--; + if (callbacksToWait <= 0) { + resolve(this); + } + }); + }); + setTimeout(() => { + if (callbacksToWait > 0) { + reject(this.id + " - timed out waiting for setFrameColor with" + color); + } + }, 5000); + }); + return nodeify(promise, callback); + } + getFrameColor() { + if (!this.windows || this.windows.length === 0) { + return ""; + } + return this.windows[0].underlyingWindow.frameColor; + } + } + + class LogLevel { + } + LogLevel.Trace = "trace"; + LogLevel.Debug = "debug"; + LogLevel.Info = "info"; + LogLevel.Warn = "warn"; + LogLevel.Error = "error"; + class Logger { + static GetNamed(name) { + return new Logger(name); + } + static Get(owner) { + return new Logger(Logger.GetTypeName(owner)); + } + constructor(name) { + this._name = name; + if (!isUndefinedOrNull(Logger.GlueLogger)) { + this._glueLogger = Logger.GlueLogger.subLogger(name); + } + } + trace(message) { + if (!isUndefinedOrNull(this._glueLogger)) { + this._glueLogger.trace(message); + } + else { + if (Logger.Level === LogLevel.Trace) { + console.info(this._getMessage(message, LogLevel.Trace)); + } + } + } + debug(message) { + if (!isUndefinedOrNull(this._glueLogger)) { + this._glueLogger.debug(message); + } + else { + if (Logger.Level === LogLevel.Debug || + Logger.Level === LogLevel.Trace) { + console.info(this._getMessage(message, LogLevel.Debug)); + } + } + } + info(message) { + if (!isUndefinedOrNull(this._glueLogger)) { + this._glueLogger.info(message); + } + else { + if (Logger.Level === LogLevel.Debug || + Logger.Level === LogLevel.Trace || + Logger.Level === LogLevel.Info) { + console.info(this._getMessage(message, LogLevel.Info)); + } + } + } + warn(message) { + if (!isUndefinedOrNull(this._glueLogger)) { + this._glueLogger.warn(message); + } + else { + if (Logger.Level === LogLevel.Debug || + Logger.Level === LogLevel.Trace || + Logger.Level === LogLevel.Info || + Logger.Level === LogLevel.Warn) { + console.info(this._getMessage(message, LogLevel.Info)); + } + } + } + error(message) { + if (!isUndefinedOrNull(this._glueLogger)) { + this._glueLogger.error(message); + } + else { + console.error(this._getMessage(message, LogLevel.Error)); + console.trace(); + } + } + _getMessage(message, level) { + return "[" + level + "] " + this._name + " - " + message; + } + static GetTypeName(object) { + const funcNameRegex = /function (.{1,})\(/; + const results = (funcNameRegex).exec(object.constructor.toString()); + return (results && results.length > 1) ? results[1] : ""; + } + } + Logger.Level = LogLevel.Info; + + class ActivityWindow extends ActivityEntity { + constructor(id, name, type, activityId, instance, isIndependent, windowGetter, hcWindowId) { + super(id); + this._logger = Logger.Get("window"); + this._type = type; + this._activityId = activityId; + this._name = name; + this._instance = instance; + this._isIndependent = isIndependent; + this._windowGetter = windowGetter; + this._hcWindowId = hcWindowId; + } + getBounds() { + return this._manager.getWindowBounds(this.id); + } + get name() { + return this._name; + } + get isIndependent() { + return this._isIndependent; + } + get type() { + if (this._manager) { + return this._manager.getWindowType(this._type); + } + return undefined; + } + get activity() { + if (isUndefined(this._activityId)) { + return undefined; + } + return this._manager.getActivityById(this._activityId); + } + get isOwner() { + const act = this.activity; + if (isUndefined(act)) { + return false; + } + return act.owner.id === this.id; + } + setVisible(isVisible, callback) { + return this._manager.setWindowVisibility(this.id, isVisible); + } + activate(focus) { + return this._manager.activateWindow(this.id, focus); + } + setBounds(bounds, callback) { + return this._manager.setWindowBounds(this.id, bounds, callback); + } + close() { + return this._manager.closeWindow(this.id); + } + get instance() { + return this._instance; + } + get underlyingWindow() { + const window = this._windowGetter(); + if (!window) { + return { + id: this._hcWindowId + }; + } + return window; + } + onActivityJoined(callback) { + this._subscribeForActivityWindowEvent(EntityEventType.ActivityWindowJoinedActivity, callback); + } + onActivityRemoved(callback) { + this._subscribeForActivityWindowEvent(EntityEventType.ActivityWindowLeftActivity, callback); + } + _updateCore(other) { + ifNotUndefined(other._activityId, (x) => this._activityId = x); + ifNotUndefined(other._isIndependent, (x) => this._isIndependent = x); + ifNotUndefined(other._hcWindowId, (x) => this._hcWindowId = x); + ifNotUndefined(other._type, (x) => this._type = x); + ifNotUndefined(other._name, (x) => this._name = x); + if (!isUndefinedOrNull(other._instance)) { + this._instance = other._instance; + } + } + _subscribeForActivityWindowEvent(eventName, callback) { + this._manager.subscribeWindowEvents((activity, window, event) => { + if (window.id !== this.id) { + return; + } + if (event === eventName) { + callback(activity); + } + }); + } + _beforeDelete(other) { + this._hcWindowId = other._hcWindowId; + } + } + + class ActivityStatus { + constructor(state, message, time) { + this.state = state; + this.message = message; + this.time = time; + } + getState() { + return this.state; + } + getMessage() { + return this.message; + } + getTime() { + return this.time; + } + } + + const gwMmessageError = "error"; + const gwMessageAddActivityTypes = "add-types"; + const gwMmessageActivityTypesAdded = "types-added"; + const gwMessageRemoveActivityTypes = "remove-types"; + const gwMessageActivityTypesRemoved = "types-removed"; + const gwMessageActivityCreated = "created"; + const gwMessageActivityDestroyed = "destroyed"; + const gwMessageActivityInitiated = "initiated"; + const gwMmessageJoinActivity = "join-activity"; + const gwMessageJoinedActivity = "joined"; + const gwMessageActivityJoined = "activity-joined"; + const gwMessageLeaveActivity = "leave-activity"; + const gwMessageActivityLeft = "left"; + const gwNmessageMergeActivities = "merge"; + const gwMessageSplitActivities = "split"; + const gwMessageOwnerChanged = "owner-changed"; + const gwMessageAddPeerFactories = "add-peer-factories"; + const gwMessagePeerFactoriesAdded = "peer-factories-added"; + const gwMessageRemovePeerFactories = "remove-peer-factories"; + const gwMessagePeerFactoriesRemoved = "peer-factories-removed"; + const gwMessageCreateActivity = "create"; + const gwMessageCreatePeer = "create-peer"; + const gwMessagePeerRequested = "peer-requested"; + const gwMessageReady = "ready"; + const gwMessagePeerCreated = "peer-created"; + const gwMessageDestroyActivity = "destroy"; + const gwMessageDisposePeer = "dispose-peer"; + const gwMessageDestroyPeer = "destroy-peer"; + class GW3Bridge { + static activityTypeGwMessageEntityToActivityType(entity, description) { + const nameToWindowType = (windowName) => new WindowType(windowName, undefined); + return new ActivityType(entity.name, entity.owner_type && nameToWindowType(entity.owner_type), entity.helper_types && entity.helper_types.map(nameToWindowType), description); + } + static peerFactoryGwMessageEntityToWindowType(entity) { + return new WindowType(entity.peer_type, (_) => undefined); + } + static activityGwMessageToActivity(msg, status) { + const ownerId = msg.owner !== undefined ? msg.owner.peer_id : msg.owner_id; + return new Activity(msg.activity_id, msg.activity_type, status, msg.context_snapshot, ownerId); + } + static activityToActivityStatusChangeEvent(act) { + return new EntityEvent(act, new ActivityStatusChangeEventContext(act.status, undefined)); + } + constructor(config) { + this._activityChangeCallbacks = []; + this._activityTypeStatusChangeCallbacks = []; + this._activityWindowChangeCallbacks = []; + this._windowTypeStatusChangeCallbacks = []; + this._peerIdAndFactoryIdToPeerType = {}; + this._peerFactoriesRegisteredByUs = {}; + this._gw3Subscriptions = []; + this._contextSubscriptions = {}; + this._activityTypesInitiatedFromMe = {}; + this._config = config; + this._connection = config.connection; + this._logger = config.logger; + this._contexts = config.contexts; + this._windows = config.windows; + this._sessionJoinedPromise = new Promise((resolve) => { + this._sessionJoinedPromiseResolve = resolve; + }); + this._activityJoinedPromise = new Promise((resolve) => { + this._activityJoinedPromiseResolve = resolve; + }); + if (!this._config.activityId) { + this._activityJoinedPromiseResolve({}); + } + this._gw3Session = this._connection.domain("activity", ["joined", "initiated", "peer-created", "token"]); + if (typeof window !== "undefined") { + const glue42gd = (window).glue42gd; + if (glue42gd && glue42gd.activityInfo) { + if (typeof glue42gd.addRefreshHandler === "function") { + glue42gd.addRefreshHandler((success, error) => { + this._gw3Session + .send({ + type: "reload" + }) + .then((msg) => { + if (!msg.token) { + error("Expected gateway token for refreshing."); + return; + } + try { + glue42gd.setGWToken(msg.token); + } + catch (e) { + error(e.message || e); + return; + } + success(); + }, error); + }); + } + if (glue42gd && typeof glue42gd.addWillNavigateHandler === "function") { + glue42gd.addWillNavigateHandler((success, error) => { + this._gw3Session + .send({ + type: "reload" + }) + .then((msg) => { + if (!msg.token) { + error("Expected gateway token for refreshing."); + return; + } + try { + glue42gd.setGWToken(msg.token); + } + catch (e) { + error(e.message || e); + return; + } + success(); + }, error); + }); + } + } + } + } + get bridgeType() { + return "GW3"; + } + init() { + this.forwardActivityTypeMessagesToStatusEventHandlers(); + this.subscribe(gwMessageActivityCreated, this.handleActivityCreatedMessage); + this.subscribe(gwMessageActivityDestroyed, this.handleActivityDestroyedMessage); + this.forwardActivityMessagesToStatusEventHandlers(); + this.forwardActivityCreatedAndJoinedActivityToActivityWindowEventHandlers(); + this.forwardPeerFactoryMessagesToStatusEventHandlers(); + this.forwardPeerFactoryMessagesToPeerFactoryRequests(); + this.subscribe(gwMessagePeerFactoriesAdded, this.handlePeerFactoriesAdded); + this.subscribe(gwMessagePeerFactoriesRemoved, this.handlePeerFactoriesRemoved); + this.forwardActivityWindowMessagesToEventHandlers(); + this.subscribe(gwMessageDisposePeer, () => { + if (this._config.disposeRequestHandling === "dispose") { + this.dispose(); + return; + } + if (this._config.disposeRequestHandling === "exit") { + if (this._windows && typeof this._windows.my() !== "undefined") { + this._windows.my().close(); + return; + } + if (typeof window !== "undefined" && typeof (window).close === "function") { + window.close(); + return; + } + if (typeof process !== "undefined" && typeof (process).exit === "function") { + process.exit(); + return; + } + } + }); + this._gw3Session.onJoined(() => { + if (this._config.mode === "trackMyOnly" || + this._config.mode === "trackMyTypeAndInitiatedFromMe") { + this._sessionJoinedPromiseResolve(this); + } + else { + this._gw3Session + .send({ + type: "subscribe", + activity_types: (this._config.mode === "trackAll" ? [] : + this._config.mode === "trackTypes" ? this._config.typesToTrack : []) + }) + .then(() => { + this._sessionJoinedPromiseResolve(this); + }); + } + }); + this._gw3Session.join(); + } + dispose() { + this._gw3Subscriptions.forEach((sub) => sub && this._connection.off(sub)); + this._gw3Subscriptions.length = 0; + } + ready() { + return Promise.all([this._sessionJoinedPromise, this._activityJoinedPromise]); + } + initReady() { + return this._sessionJoinedPromise; + } + onActivityTypeStatusChange(callback) { + this._activityTypeStatusChangeCallbacks.push(callback); + } + registerActivityType(activityTypeName, ownerWindow, helperWindows, config, description) { + const entity = {}; + entity.name = activityTypeName; + const toActivityPeerConfig = (windowDefinition) => ({ type: windowDefinition.type, name: windowDefinition.name, configuration: windowDefinition }); + entity.owner_type = toActivityPeerConfig(ownerWindow); + entity.helper_types = helperWindows.map(toActivityPeerConfig); + return this._gw3Session + .send({ + type: gwMessageAddActivityTypes, + types: [entity] + }) + .then(() => { + const activityType = GW3Bridge.activityTypeGwMessageEntityToActivityType(entity, description); + this.invokeCallbacks(this._activityTypeStatusChangeCallbacks, new EntityEvent(activityType, new EntityEventContext(EntityEventType.Added)), gwMessageAddActivityTypes); + return activityType; + }); + } + unregisterActivityType(activityTypeName) { + return this._gw3Session + .send({ + type: gwMessageRemoveActivityTypes, + types: [activityTypeName] + }) + .then(() => { + const activityType = new ActivityType(activityTypeName, undefined, undefined, undefined); + this.invokeCallbacks(this._activityTypeStatusChangeCallbacks, new EntityEvent(activityType, new EntityEventContext(EntityEventType.Removed)), gwMessageAddActivityTypes); + }); + } + onWindowTypeStatusChange(callback) { + this._windowTypeStatusChangeCallbacks.push(callback); + } + registerWindowFactory(windowType, factory, parameters) { + if (this._peerFactoriesRegisteredByUs[windowType]) { + return Promise.reject(new Error(`Factory for windowType ${windowType} already registered.`)); + } + this._peerFactoriesRegisteredByUs[windowType] = factory; + const entity = { + id: windowType, + peer_type: windowType, + configuration: parameters + }; + return this._gw3Session.send({ + type: gwMessageAddPeerFactories, + factories: [entity] + }) + .then(() => { + this.invokeCallbacks(this._windowTypeStatusChangeCallbacks, new EntityEvent(GW3Bridge.peerFactoryGwMessageEntityToWindowType(entity), new EntityEventContext(EntityEventType.Added)), gwMessageAddPeerFactories); + }) + .catch(() => { + delete this._peerFactoriesRegisteredByUs[windowType]; + }); + } + unregisterWindowFactory(windowType) { + const factory = this._peerFactoriesRegisteredByUs[windowType]; + if (!factory) { + return Promise.reject(new Error(`Factory for windowType ${windowType} not registered.`)); + } + delete this._peerFactoriesRegisteredByUs[windowType]; + return this._gw3Session.send({ + type: gwMessageRemovePeerFactories, + factory_ids: [windowType] + }).then(() => { + this.invokeCallbacks(this._windowTypeStatusChangeCallbacks, new EntityEvent(new WindowType(windowType, undefined), new EntityEventContext(EntityEventType.Removed)), gwMessageAddPeerFactories); + }); + } + onActivityStatusChange(callback) { + this._activityChangeCallbacks.push(callback); + } + initiateActivity(activityType, context, configuration) { + const initiateMsg = { + type: gwMessageCreateActivity, + activity_type: activityType, + initial_context: context, + }; + if (this.isOverrideTypeDefinition(configuration)) { + initiateMsg.types_override = { + owner_type: { type: configuration.owner.type, name: configuration.owner.name, configuration: configuration.owner }, + helper_types: configuration.helpers && configuration.helpers.map((wd) => ({ type: wd.type, name: wd.name, configuration: wd })) + }; + } + else { + initiateMsg.configuration = configuration && configuration.map((wd) => ({ type: wd.type, name: wd.name, configuration: wd })); + } + return this.sendCreateAndMapResultingMessagesToPromise(initiateMsg, gwMessageActivityInitiated, (msg, requestId) => msg.request_id === requestId, gwMessageActivityCreated, (msg, requestId, initMsg) => msg.activity_id === initMsg.activity_id, gwMessageActivityDestroyed, (msg, requestId, initMsg) => msg.activity_id === initMsg.activity_id, (msg) => msg.activity_id, null).then((id) => { + if (this._config.mode === "trackMyTypeAndInitiatedFromMe") { + if (!this._activityTypesInitiatedFromMe[activityType]) { + this._activityTypesInitiatedFromMe[activityType] = true; + return this._gw3Session + .send({ + type: "subscribe", + activity_types: [activityType] + }) + .then(() => { + return id; + }); + } + } + return id; + }); + } + stopActivity(activity) { + return this._gw3Session.send({ + type: gwMessageDestroyActivity, + activity_id: activity.id, + reason_uri: "com.tick42.glue.activity.constants.destroyReason.general", + reason: "Destroying activity" + }).then((_) => true); + } + updateActivityContext(activity, context, fullReplace, removedKeys) { + if (fullReplace) { + return this._contexts.set(activity.id, context); + } + else { + removedKeys = removedKeys || []; + for (const x of removedKeys) { + context[x] = null; + } + return this._contexts.update(activity.id, context); + } + } + announceWindow(windowType, activityWindowId) { + throw new Error("Invalid operation 'announceWindow' for GW3 protocol"); + } + registerWindow(type, name, independent) { + let shouldSendReady = typeof this._connection.gatewayToken !== "undefined"; + const peerId = this._connection.peerId; + if (typeof window !== "undefined") { + const glue42gd = window.glue42gd; + if (glue42gd) { + shouldSendReady = typeof glue42gd.activityInfo !== "undefined"; + } + } + if (shouldSendReady) { + this._gw3Session.send({ + type: gwMessageReady, + }); + } + this.invokeCallbacks(this._activityWindowChangeCallbacks, new EntityEvent(new ActivityWindow(peerId, name, type, undefined, this.getAgmInstance(peerId), independent, this.generateWindowGetter(peerId), undefined), new EntityEventContext(EntityEventType.Added)), "register window"); + return Promise.resolve(peerId); + } + onActivityWindowChange(callback) { + this._activityWindowChangeCallbacks.push(callback); + } + createWindow(activityId, windowDefinition) { + if (!windowDefinition.layout) { + if (windowDefinition.left || windowDefinition.width || windowDefinition.height || windowDefinition.top) { + windowDefinition.layout = { + mode: "pixels", + cellSize: 1, + }; + } + } + const joinPeer = (id) => { + if (!activityId) { + return; + } + return this.joinActivity(activityId, id, windowDefinition.name) + .then(() => { + return id; + }); + }; + return this.sendCreateAndMapResultingMessagesToPromise({ + type: gwMessageCreatePeer, + peer_type: windowDefinition.type, + peer_name: windowDefinition.name || windowDefinition.type, + configuration: windowDefinition, + activity_id: activityId, + }, undefined, undefined, gwMessagePeerCreated, (msg, requestId) => msg.request_id === requestId, undefined, undefined, (msg) => msg.created_id, joinPeer) + .then(joinPeer); + } + async closeWindow(id) { + await this._gw3Session.send({ + type: gwMessageDestroyPeer, + destroy_peer_id: id + }); + } + getAnnouncementInfo() { + let activityId = this._config.activityId || (this._config.announcementInfo && this._config.announcementInfo.activityId); + let activityWindowType = (this._config.announcementInfo && this._config.announcementInfo.activityWindowType); + let activityWindowIndependent = (this._config.announcementInfo && this._config.announcementInfo.activityWindowIndependent); + let activityWindowName = (this._config.announcementInfo && this._config.announcementInfo.activityWindowName); + if (typeof window !== "undefined" && + typeof window.location !== "undefined" && + window.location.search && + typeof URLSearchParams === "function") { + const searchParams = new URLSearchParams(location.search.slice(1)); + activityWindowType = activityWindowType || searchParams.get("t42PeerType"); + activityWindowType = activityWindowType || searchParams.get("t42ActivityWindowType"); + if (typeof activityWindowIndependent === "undefined") { + activityWindowIndependent = searchParams.get("t42ActivityWindowIndependent"); + } + activityWindowName = activityWindowName || searchParams.get("t42ActivityWindowName"); + activityId = activityId || searchParams.get("t42ActivityId"); + } + activityWindowType = activityWindowType || "unknown"; + activityWindowIndependent = activityWindowIndependent || false; + activityWindowName = activityWindowName || this._connection.peerId; + return { + activityWindowId: undefined, + activityId, + activityWindowType, + activityWindowIndependent, + activityWindowName, + }; + } + joinActivity(activityId, windowId, name) { + const maybeName = (name && { name }) || {}; + return this._gw3Session.send({ + type: gwMmessageJoinActivity, + target_id: windowId, + activity_id: activityId, + ...maybeName + }).then(() => { + this.invokeCallbacks(this._activityWindowChangeCallbacks, new EntityEvent(new ActivityWindow(windowId, undefined, undefined, activityId, this.getAgmInstance(windowId), undefined, this.generateWindowGetter(windowId), undefined), new EntityEventContext(EntityEventType.ActivityWindowJoinedActivity)), "activity joined - ActivityWindow"); + this.invokeCallbacks(this._activityChangeCallbacks, new EntityEvent(new Activity(activityId, undefined, new ActivityStatus("created", undefined, undefined), undefined, undefined), new EntityEventContext(EntityEventType.Updated)), "activity joined - Activity"); + }); + } + leaveActivity(activityId, windowId) { + return this._gw3Session.send({ + type: gwMessageLeaveActivity, + target_id: windowId, + activity_id: activityId + }).then(() => { + this.invokeCallbacks(this._activityWindowChangeCallbacks, new EntityEvent(new ActivityWindow(windowId, undefined, undefined, null, this.getAgmInstance(windowId), undefined, this.generateWindowGetter(windowId), undefined), new EntityEventContext(EntityEventType.ActivityWindowLeftActivity)), "activity left - ActivityWindow"); + this.invokeCallbacks(this._activityChangeCallbacks, new EntityEvent(new Activity(activityId, undefined, new ActivityStatus("created", undefined, undefined), undefined, undefined), new EntityEventContext(EntityEventType.Updated)), "activity left - Activity"); + }); + } + getActivityTypes() { + return Promise.resolve([]); + } + getWindowTypes() { + return Promise.resolve([]); + } + getActivities() { + return Promise.resolve([]); + } + getActivityWindows() { + return Promise.resolve([]); + } + createStackedWindows(id, windowDefinitions, timeout) { + return undefined; + } + getWindowBounds(id) { + return undefined; + } + setWindowBounds(id, bounds) { + return undefined; + } + activateWindow(id, focus) { + return undefined; + } + setWindowVisibility(id, visible) { + return undefined; + } + cloneActivity(id, cloneOptions) { + return undefined; + } + attachActivities(from, to, tag) { + return this._gw3Session.send({ + type: gwNmessageMergeActivities, + into: to, + merge: from + }); + } + detachActivities(activityId, newActivityInfo) { + return this._gw3Session.send({ + type: gwMessageSplitActivities, + from: activityId, + }).then(() => ""); + } + onActivitiesAttached(callback) { + } + onActivitiesDetached(callback) { + } + onActivityAttachedDescriptorsRefreshed(callback) { + } + getAttachedDescriptors() { + return Promise.resolve([]); + } + getRandomRequestId() { + return this._connection.peerId + ":" + Math.floor(Math.random() * 1e9) + ""; + } + forwardAddedAndRemovedMessagesToEventHandler(addedMessageType, removedMessageType, mapper, handlers) { + const getGetEntityEvent = (isAdded) => (entity) => new EntityEvent(entity, new EntityEventContext(isAdded ? + EntityEventType.Added : + EntityEventType.Removed)); + const sub1 = addedMessageType && this.forwardMessageToEventHandler(addedMessageType, (msg) => mapper(msg, true), getGetEntityEvent(true), handlers); + const sub2 = removedMessageType && this.forwardMessageToEventHandler(removedMessageType, (msg) => mapper(msg, false), getGetEntityEvent(false), handlers); + return [sub1, sub2].filter((x) => x); + } + forwardMessageToEventHandler(messageType, mapper, getEntityEvent, handler) { + return this.subscribe(messageType, (msg) => { + mapper(msg) + .forEach((ent) => handler.forEach((h) => h(getEntityEvent(ent, msg)))); + }); + } + sendCreateAndMapResultingMessagesToPromise(msg, initiatedMessageType, initiatedMessageFilter, createdMessageType, createdMessageFilter, cancelledMessageType, cancelledMessageFilter, createdMessageToPromiseResolution, listenForRecreates) { + const reqId = this.getRandomRequestId(); + let resolveCreatedPromise; + let rejectCreatedPromise; + const createdPromise = new Promise((resolve, reject) => { + resolveCreatedPromise = resolve; + rejectCreatedPromise = reject; + }); + let initiatedMessageAck = null; + let initiatedSubscription; + let createdSubscription; + let cancelledSubscription; + let errorSubscription; + const dropSubscriptions = () => { + this.dropSubscription(initiatedSubscription); + if (!listenForRecreates) { + this.dropSubscription(createdSubscription); + } + this.dropSubscription(cancelledSubscription); + this.dropSubscription(errorSubscription); + }; + initiatedSubscription = initiatedMessageType && + this.subscribe(initiatedMessageType, (msg4) => { + if (!initiatedMessageFilter(msg4, reqId)) { + return; + } + initiatedMessageAck = msg4; + this.dropSubscription(initiatedSubscription); + }); + let recreated = false; + createdSubscription = + this.subscribe(createdMessageType, (msg1) => { + if (!createdMessageFilter(msg1, reqId, initiatedMessageAck)) { + return; + } + if (recreated) { + if (listenForRecreates) { + listenForRecreates(createdMessageToPromiseResolution(msg1)); + } + } + else { + recreated = true; + resolveCreatedPromise(createdMessageToPromiseResolution(msg1)); + } + }); + cancelledSubscription = cancelledMessageType && + this.subscribe(cancelledMessageType, (msg2) => { + if (!cancelledMessageFilter(msg2, reqId, initiatedMessageAck)) { + return; + } + rejectCreatedPromise(msg2); + }); + errorSubscription = cancelledMessageType && + this.subscribe(gwMmessageError, (msg3) => { + if (msg3.request_id !== reqId) { + return; + } + rejectCreatedPromise(msg3); + }); + msg.request_id = reqId; + const toReturn = this._gw3Session + .send(msg) + .then(() => { + return createdPromise; + }); + toReturn.then(dropSubscriptions, dropSubscriptions); + return toReturn; + } + peerFactoryIdAndOwnerIdToWindowType(factoryId, ownerId) { + const peerType = this._peerIdAndFactoryIdToPeerType[ownerId + ":" + factoryId]; + if (!peerType) { + return null; + } + else { + return new WindowType(peerType, undefined); + } + } + subscribe(messageType, handler) { + const sub = this._connection.on(messageType, (msg) => handler.bind(this)(msg)); + this._gw3Subscriptions.push(sub); + return sub; + } + dropSubscription(subscription) { + if (subscription) { + this._connection.off(subscription); + delete this._gw3Subscriptions[this._gw3Subscriptions.indexOf(subscription)]; + } + } + invokeCallbacks(callbacks, event, description) { + callbacks.forEach((cb) => { + try { + cb(event); + } + catch (err) { + this._logger.error(`Error in ${description || event.context.type} callback: ` + JSON.stringify(err)); + } + }); + } + handleActivityCreatedMessage(msg) { + if (!msg.context_id) { + this._logger.error("Activity created with unknown context_id: " + msg.activity_id); + } + else { + if (!this._contextSubscriptions[msg.activity_id]) { + this.subscribeToContext(msg); + } + } + } + async subscribeToContext(msg) { + const activityId = msg.activity_id; + this._contextSubscriptions[activityId] = + await this._contexts.subscribe(activityId, (data, updated, removed) => { + const event = new EntityEvent(new Activity(activityId, undefined, undefined, data, undefined), new ActivityContextChangedEventContext(data, updated, removed)); + this.invokeCallbacks(this._activityChangeCallbacks, event, "context updated"); + }); + } + handleActivityDestroyedMessage(msg) { + const unsubscribeContext = this._contextSubscriptions[msg.activity_id]; + if (typeof unsubscribeContext === "function") { + unsubscribeContext(); + } + delete this._contextSubscriptions[msg.activity_id]; + } + handlePeerFactoriesAdded(msg) { + msg.factories.forEach((entity) => { + this._peerIdAndFactoryIdToPeerType[msg.owner_id + ":" + entity.id] = entity.peer_type; + }); + } + handlePeerFactoriesRemoved(msg) { + msg.factory_ids.forEach((factoryId) => { + delete this._peerIdAndFactoryIdToPeerType[msg.owner_id + ":" + factoryId]; + }); + } + forwardActivityTypeMessagesToStatusEventHandlers() { + this.forwardAddedAndRemovedMessagesToEventHandler(gwMmessageActivityTypesAdded, gwMessageActivityTypesRemoved, (msg, isAdded) => isAdded + ? msg.types.map((t) => GW3Bridge.activityTypeGwMessageEntityToActivityType(t, undefined)) + : msg.types.map((t) => new ActivityType(t.name, undefined, undefined, undefined)), this._activityTypeStatusChangeCallbacks); + } + forwardActivityCreatedAndJoinedActivityToActivityWindowEventHandlers() { + for (const activityCreatedMessage of [gwMessageActivityCreated, gwMessageJoinedActivity, gwMessageOwnerChanged]) { + this.forwardMessageToEventHandler(activityCreatedMessage, (msg) => ([msg.owner || { ...msg, type: msg.peer_type, name: msg.peer_name, peer_id: msg.owner_id }]) + .concat(msg.participants || []) + .map((info) => new ActivityWindow(info.peer_id, info.name, info.type, msg.activity_id, this.getAgmInstance(info.peer_id), undefined, this.generateWindowGetter(info.peer_id), undefined)), (ent, msg) => new EntityEvent(ent, new EntityEventContext(EntityEventType.ActivityWindowJoinedActivity)), this._activityWindowChangeCallbacks); + } + } + forwardActivityMessagesToStatusEventHandlers() { + for (const createdMessage of [gwMessageActivityCreated, gwMessageJoinedActivity]) { + this.forwardMessageToEventHandler(createdMessage, (msg) => [GW3Bridge.activityGwMessageToActivity(msg, new ActivityStatus("started", "", new Date()))], (ent, msg) => GW3Bridge.activityToActivityStatusChangeEvent(ent), this._activityChangeCallbacks); + } + this.forwardMessageToEventHandler(gwMessageActivityDestroyed, (msg) => [GW3Bridge.activityGwMessageToActivity(msg, new ActivityStatus("destroyed", msg.reason, new Date()))], (ent, msg) => GW3Bridge.activityToActivityStatusChangeEvent(ent), this._activityChangeCallbacks); + this.forwardMessageToEventHandler(gwMessageActivityInitiated, (msg) => [GW3Bridge.activityGwMessageToActivity(msg, new ActivityStatus("created", "", new Date()))], (ent, msg) => GW3Bridge.activityToActivityStatusChangeEvent(ent), this._activityChangeCallbacks); + this.forwardMessageToEventHandler(gwMessageOwnerChanged, (msg) => [GW3Bridge.activityGwMessageToActivity(msg, new ActivityStatus("created", "", new Date()))], (ent, msg) => GW3Bridge.activityToActivityStatusChangeEvent(ent), this._activityChangeCallbacks); + } + forwardPeerFactoryMessagesToStatusEventHandlers() { + this.forwardAddedAndRemovedMessagesToEventHandler(gwMessagePeerFactoriesAdded, gwMessagePeerFactoriesRemoved, (msg, isAdded) => isAdded + ? msg.factories.map(GW3Bridge.peerFactoryGwMessageEntityToWindowType) + : msg.factory_ids.map((id) => this.peerFactoryIdAndOwnerIdToWindowType(id, msg.owner_id)).filter((x) => x != null), this._windowTypeStatusChangeCallbacks); + } + forwardPeerFactoryMessagesToPeerFactoryRequests() { + this.subscribe(gwMessagePeerRequested, (msg) => { + const factory = this._peerFactoriesRegisteredByUs[msg.peer_factory]; + if (!factory) { + this._gw3Session.send({ + type: gwMmessageError, + request_id: msg.request_id, + reason: `Unknown peer factory ${msg.peer_factory}` + }); + return; + } + try { + const configuration = msg.configuration || {}; + configuration.gateway_token = configuration.gateway_token || msg.gateway_token; + configuration.peer_factory = configuration.peer_factory || msg.peer_factory; + const promise = factory({ + activityId: msg.activity && msg.activity.id, + activityType: msg.activity && msg.activity.type, + type: msg.configuration && msg.configuration.type, + gwToken: configuration.gateway_token, + configuration + }); + if (promise && promise.then && promise.catch) { + promise.catch((err) => this._gw3Session.send({ + type: gwMmessageError, + request_id: msg.request_id, + reason: err && (err.message || JSON.stringify(err)) + })); + } + } + catch (err) { + this._gw3Session.send({ + type: gwMmessageError, + request_id: msg.request_id, + reason: err && (err.message || JSON.stringify(err)) + }); + } + }); + } + forwardActivityWindowMessagesToEventHandlers() { + for (const joinedMessage of [gwMessageActivityJoined, gwMessageJoinedActivity]) { + this.subscribe(joinedMessage, (msg) => { + const joinedId = (joinedMessage === gwMessageActivityJoined) ? msg.joined_id : msg.peer_id; + const joinedType = (joinedMessage === gwMessageActivityJoined) ? msg.joined_type : msg.peer_type; + const joinedName = (joinedMessage === gwMessageActivityJoined) ? msg.joined_name : msg.peer_name; + const entity = new ActivityWindow(joinedId, joinedName, joinedType, msg.activity_id, this.getAgmInstance(joinedId), undefined, this.generateWindowGetter(joinedId), undefined); + if (!this._contextSubscriptions[msg.activity_id]) { + this.subscribeToContext(msg).then(() => { + if (joinedMessage === gwMessageJoinedActivity) { + this._activityJoinedPromiseResolve({}); + } + }); + } + else if (joinedMessage === gwMessageJoinedActivity) { + this._activityJoinedPromiseResolve({}); + } + this.invokeCallbacks(this._activityWindowChangeCallbacks, new EntityEvent(entity, new EntityEventContext(EntityEventType.ActivityWindowJoinedActivity)), joinedMessage); + }); + } + this.subscribe(gwMessageActivityLeft, (msg) => { + const entity = new ActivityWindow(msg.left_id, undefined, undefined, null, this.getAgmInstance(msg.left_id), undefined, this.generateWindowGetter(msg.left_id), undefined); + this.invokeCallbacks(this._activityWindowChangeCallbacks, new EntityEvent(entity, new EntityEventContext(EntityEventType.ActivityWindowLeftActivity)), gwMessageActivityLeft); + }); + this.forwardAddedAndRemovedMessagesToEventHandler(gwMessagePeerCreated, undefined, (msg) => [ + new ActivityWindow(msg.created_id, undefined, undefined, undefined, undefined, undefined, this.generateWindowGetter(msg.created_id), undefined) + ], this._activityWindowChangeCallbacks); + } + getAgmInstance(id) { + return this._config.agm.servers().find((s) => s.peerId === id || s.windowId === id); + } + generateWindowGetter(peerId) { + return () => { + const server = this.getAgmInstance(peerId); + if (!server) { + return; + } + const windowId = server.windowId; + return this._config.windows.list().filter((w) => w.id === windowId)[0]; + }; + } + isOverrideTypeDefinition(value) { + if (typeof value === "undefined") { + return false; + } + if (value.owner) { + return true; + } + return false; + } + } + + class ActivityMy { + constructor(manager, windows) { + this._myAttached = []; + this._myDetached = []; + this._myAttachedTo = []; + this._myDetachedFrom = []; + this._myActivityFrameColorChanged = []; + this._myActivityJoinedCallbacks = []; + this._myActivityRemovedCallbacks = []; + this._myContextUpdateCallbacks = []; + this._logger = Logger.Get(this); + this._m = manager; + manager.ready() + .then((am) => { + am.subscribeActivityContextChanged(this._subscribeMyContextChanged.bind(this)); + am.subscribeWindowEvents(this._subscribeMyWindowEvent.bind(this)); + am.subscribeActivitiesAttached(this._subscribeActivitiesAttached.bind(this)); + am.subscribeActivitiesDetached(this._subscribeActivitiesDetached.bind(this)); + if (windows) { + windows.onWindowFrameColorChanged(this._subscribeWindowFrameColorChanged.bind(this)); + } + }); + } + get window() { + if (isUndefinedOrNull(this._w)) { + const announcedWindows = this._m.announcedWindows; + if (announcedWindows.length > 0) { + this._w = announcedWindows[0]; + } + } + return this._w; + } + get activity() { + const myWin = this.window; + if (isUndefinedOrNull(myWin)) { + return undefined; + } + return myWin.activity; + } + createWindow(windowType) { + return this._m.createWindow(this.activity, windowType); + } + createStackedWindows(windowTypes, timeout) { + return this._m.createStackedWindows(this.activity, windowTypes, timeout); + } + get context() { + const activity = this.activity; + if (isUndefined(activity)) { + return {}; + } + return activity.context; + } + updateContext(context, callback) { + const activity = this.activity; + if (isUndefined(activity)) { + return new Promise((resolve, reject) => { + reject("Not in activity"); + }); + } + return activity.updateContext(context, callback); + } + setContext(context, callback) { + const activity = this.activity; + if (isUndefined(activity)) { + return new Promise((resolve, reject) => { + reject("Not in activity"); + }); + } + return activity.setContext(context, callback); + } + onActivityJoined(callback) { + this._myActivityJoinedCallbacks.push(callback); + const myWin = this.window; + if (!isUndefinedOrNull(myWin) && !isUndefinedOrNull(myWin.activity)) { + callback(myWin.activity); + } + } + onActivityLeft(callback) { + this._myActivityRemovedCallbacks.push(callback); + } + onContextChanged(callback) { + this._myContextUpdateCallbacks.push(callback); + const myWin = this.window; + if (isUndefinedOrNull(myWin)) { + return; + } + const activity = myWin.activity; + if (isUndefinedOrNull(activity)) { + return; + } + callback(activity.context, activity.context, [], activity); + } + clone(options, callback) { + const act = this.activity; + return this._m.clone(act, options, callback); + } + attach(activity, tag) { + let activityId; + if (typeof activity === "string") { + activityId = activity; + } + else { + activityId = activity.id; + } + return this._m.attachActivities(activityId, this.activity.id, tag); + } + onActivityAttached(callback) { + this._myAttached.push(callback); + } + onActivityDetached(callback) { + this._myDetached.push(callback); + } + onAttachedToActivity(callback) { + this._myAttachedTo.push(callback); + } + onDetachedFromActivity(callback) { + this._myDetachedFrom.push(callback); + } + get attached() { + if (!this.activity) { + return []; + } + return this.activity.attached; + } + setFrameColor(color, callback) { + if (this.activity) { + return this.activity.setFrameColor(color, callback); + } + else { + return Promise.resolve(null); + } + } + getFrameColor() { + if (this.activity) { + return this.activity.getFrameColor(); + } + return ""; + } + onFrameColorChanged(callback) { + this._myActivityFrameColorChanged.push(callback); + } + _subscribeMyContextChanged(activity, context, delta, removed) { + const myWin = this.window; + if (isUndefinedOrNull(myWin)) { + return; + } + const myActivity = myWin.activity; + if (isUndefinedOrNull(myActivity)) { + return; + } + if (activity.id !== myActivity.id) { + return; + } + this._notifyMyContextChanged(activity, context, delta, removed); + } + _subscribeMyWindowEvent(activity, window, event) { + if (isUndefinedOrNull(this.window)) { + return; + } + if (this.window.id !== window.id) { + return; + } + if (event === EntityEventType.ActivityWindowJoinedActivity) { + this._notifyMyWindowEvent(activity, this._myActivityJoinedCallbacks); + this._notifyMyContextChanged(activity, activity.context, null, null); + } + else if (event === EntityEventType.ActivityWindowLeftActivity) { + this._notifyMyWindowEvent(activity, this._myActivityRemovedCallbacks); + } + } + _notifyMyWindowEvent(activity, callbackStore) { + callbackStore.forEach((element) => { + try { + element(activity, event); + } + catch (e) { + this._logger.warn("error in user callback " + e); + } + }); + } + _notifyMyContextChanged(activity, context, delta, removed) { + delta = delta || {}; + removed = removed || []; + this._myContextUpdateCallbacks.forEach((element) => { + try { + element(context, delta, removed, activity); + } + catch (e) { + this._logger.warn("error in user callback " + e); + } + }); + } + _notifyAttached(state) { + this._myAttached.forEach((cb) => { + try { + cb(state); + } + catch (e) { + this._logger.warn("error in user callback " + e); + } + }); + } + _notifyDetached(state) { + this._myDetached.forEach((cb) => { + try { + cb(state); + } + catch (e) { + this._logger.warn("error in user callback " + e); + } + }); + } + _notifyAttachedTo(state) { + this._myAttachedTo.forEach((cb) => { + try { + cb(this.activity, state); + } + catch (e) { + this._logger.warn("error in user callback " + e); + } + }); + } + _notifyDetachedFrom(detached, existing, state) { + this._myDetachedFrom.forEach((cb) => { + try { + cb(detached, existing, state); + } + catch (e) { + this._logger.warn("error in user callback " + e); + } + }); + } + _subscribeActivitiesAttached(newAct, state) { + const myWin = this.window; + if (isUndefinedOrNull(myWin)) { + return; + } + const myActivity = myWin.activity; + if (isUndefinedOrNull(myActivity)) { + return; + } + if (newAct.id !== myActivity.id) { + return; + } + if (state.windowIds.indexOf(myWin.id) >= 0) { + this._notifyAttachedTo(state); + return; + } + this._notifyAttached(state); + } + _subscribeActivitiesDetached(newAct, oldAct, state) { + const myWin = this.window; + if (isUndefinedOrNull(myWin)) { + return; + } + const myActivity = myWin.activity; + if (isUndefinedOrNull(myActivity)) { + return; + } + if (oldAct.id === myActivity.id) { + this._notifyDetached(state); + } + if (newAct.id === myActivity.id) { + this._notifyDetachedFrom(newAct, oldAct, state); + } + } + _subscribeWindowFrameColorChanged(window) { + const act = this.activity; + if (!act) { + return; + } + if (!act.owner) { + return; + } + if (act.owner.underlyingWindow.id === window.id) { + this._myActivityFrameColorChanged.forEach((callback) => { + callback(window.frameColor); + }); + } + } + } + + class ReadyMarker { + constructor(name, signalsToWait) { + this._logger = Logger.Get("ReadyMarker [" + name + "]"); + this._logger.debug("Initializing ready marker for '" + name + "' with " + signalsToWait + " signals to wait"); + if (signalsToWait <= 0) { + throw new Error("Invalid signal number. Should be > 0"); + } + this._signals = signalsToWait; + this._callbacks = []; + this._name = name; + } + setCallback(callback) { + if (this.isSet()) { + callback(undefined); + return; + } + else if (this.isError()) { + callback(this._error); + return; + } + this._callbacks.push(callback); + } + signal(message) { + this._logger.debug("Signaled - " + message + " - signals left " + (this._signals - 1)); + this._signals--; + if (this._signals < 0) { + throw new Error("Error in ready marker '" + this._name + " - signals are " + this._signals); + } + if (this.isSet()) { + this._callbacks.forEach((callback) => { + callback(undefined); + }); + } + } + error(error) { + this._error = error; + this._callbacks.forEach((errorCallback) => { + errorCallback(error); + }); + } + isSet() { + if (this.isError()) { + return false; + } + return this._signals === 0; + } + isError() { + return !isUndefined(this._error); + } + getError() { + return this._error; + } + } + + class EntityObservableCollection { + constructor(processNew) { + this._items = {}; + this._listeners = []; + this._processNew = processNew; + } + addOne(item) { + this.add([item]); + } + add(items) { + items.forEach((element) => { + this.process(new EntityEvent(element, new EntityEventContext(EntityEventType.Added))); + }); + } + process(event) { + const context = event.context; + const type = context.type; + const entity = event.entity; + if (type === EntityEventType.StatusChange && + !context.oldStatus) { + const act = this._items[entity.id]; + if (act) { + context.oldStatus = act.status; + } + } + if (type === EntityEventType.StatusChange && + context.oldStatus && + context.newStatus && + context.oldStatus.state === + context.newStatus.state) { + context.type = EntityEventType.Updated; + } + if (typeof htmlContainer === "undefined") { + if (type === EntityEventType.ActivityWindowJoinedActivity && + this._items[entity.id] && + this._items[entity.id].activity) { + context.type = EntityEventType.Updated; + } + if (type === EntityEventType.ActivityWindowLeftActivity && + this._items[entity.id] && + !this._items[entity.id].activity) { + context.type = EntityEventType.Updated; + } + } + const internalEntity = this._updateInternalCollections(entity, type, context); + this._notifyListeners(internalEntity, context); + return internalEntity; + } + get() { + const result = []; + for (const key in this._items) { + if (this._items.hasOwnProperty(key)) { + const element = this._items[key]; + result.push(element); + } + } + return result; + } + getByName(name) { + for (const key in this._items) { + if (key === name) { + return this._items[key]; + } + } + return undefined; + } + getOrWait(name) { + return new Promise((resolve) => { + const entityAddedHandler = (entity) => { + if (entity.id !== name) { + return; + } + resolve(entity); + this.unsubscribe(entityAddedHandler); + }; + this.subscribe(entityAddedHandler); + const window = this.getByName(name); + if (window) { + this.unsubscribe(entityAddedHandler); + resolve(window); + return; + } + }); + } + subscribe(handler) { + this._listeners.push(handler); + Object.keys(this._items).forEach((key) => { + const element = this._items[key]; + handler(element, new EntityEventContext(EntityEventType.Added.toString())); + }); + return () => { + this.unsubscribe(handler); + }; + } + unsubscribe(handler) { + const index = this._listeners.indexOf(handler); + if (index !== -1) { + this._listeners.splice(index, 1); + } + } + _notifyListeners(entity, context) { + this._listeners.forEach((listener) => { + try { + listener(entity, context); + } + catch (e) { + return; + } + }); + } + _updateInternalCollections(entity, type, context) { + const entityAsAny = entity; + const isActivityDestroy = (type === EntityEventType.StatusChange && + entityAsAny.status && + entityAsAny.status.state === ActivityState.Destroyed) || + (type === EntityEventType.StatusChange && + context && + context.newStatus && + context.newStatus.state === ActivityState.Destroyed); + const isWindowClose = type === EntityEventType.Closed; + const isTypeRemove = type === EntityEventType.Removed && typeof entityAsAny.isIndependent === "undefined"; + if (isTypeRemove || isWindowClose || isActivityDestroy) { + const oldEntity = this._items[entity.id]; + delete this._items[entity.id]; + this._processNew(entity); + if (oldEntity) { + entity._beforeDelete(oldEntity); + } + return entity; + } + else { + const key = entity.id; + if (!this._items.hasOwnProperty(key)) { + this._processNew(entity); + this._items[entity.id] = entity; + } + else { + this._items[entity.id]._update(entity); + } + } + return this._items[entity.id]; + } + } + + class ActivityManager { + get usingHc() { + return this._bridge.bridgeType === "HC"; + } + get announcedWindows() { + return this._announcedWindows; + } + set announcedWindows(v) { + throw new Error("not allowed"); + } + constructor(bridge, autoAnnounce, windows) { + this._logger = Logger.Get("activityManager"); + this._announcedWindows = []; + this._attachedCallbacks = []; + this._detachedCallbacks = []; + this._frameColorChangesCallbacks = []; + this._windowHandlers = []; + this._bridge = bridge; + this._activityTypes = new EntityObservableCollection((e) => this._grabEntity(e)); + this._windowTypes = new EntityObservableCollection((e) => this._grabEntity(e)); + this._activities = new EntityObservableCollection((e) => this._grabEntity(e)); + this._windows = new EntityObservableCollection((e) => this._grabEntity(e)); + this._dataReadyMarker = new ReadyMarker("Activity Manager Data", ["GetActivityTypes", "GetWindowTypes", "GetActivities", "GetWindows"].length); + this._descriptorsMarker = new ReadyMarker("Attached Activities Descriptors", ["GetDescriptors"].length); + if (autoAnnounce) { + this._readyMarker = new ReadyMarker("Activity Manager Announce", ["Announcement"].length); + this._dataReadyMarker.setCallback((dataErr) => { + if (dataErr) { + this._readyMarker.error(dataErr); + } + this._descriptorsMarker.setCallback((err) => { + if (err) { + this._readyMarker.error(err); + } + this._logger.debug("Auto announcing window"); + this.announceWindow() + .then((w) => { + this._announcedWindows.push(w); + this._readyMarker.signal("Successfully announced window with id '" + w.id + "'"); + }) + .catch((errCatch) => { + this._logger.debug("Will not announce window - " + errCatch); + this._readyMarker.signal(); + }); + }); + this.refreshDescriptors(); + }); + } + else { + this._readyMarker = this._dataReadyMarker; + } + this._bridge.onActivitiesAttached((e) => { + this._handleActivitiesAttached(e); + }); + this._bridge.onActivitiesDetached((e) => { + this._handleActivitiesDetached(e); + }); + this._bridge.onActivityAttachedDescriptorsRefreshed((e) => { + this._handleActivityDescriptorsRefreshed(e); + }); + if (windows) { + windows.onWindowFrameColorChanged(this._handleWindowFrameColorChanged.bind(this)); + } + this._bridge.init(); + this._subscribeForData(); + this._bridge + .initReady() + .then((aw) => { + this._getInitialData(); + }) + .catch((error) => { + console.log(error); + }); + } + ready(callback) { + const promise = new Promise((resolve, reject) => { + this._readyMarker.setCallback((err) => { + if (!err) { + resolve(this); + } + else { + reject(this._readyMarker.getError()); + } + }); + }); + return nodeify(Promise.all([this._bridge.ready(), promise]).then(() => this), callback); + } + getActivityTypes() { + return this._activityTypes.get(); + } + getActivityType(name) { + return this._activityTypes.getByName(name); + } + registerActivityType(activityTypeName, ownerWindowType, helperWindowTypes, config, description, callback) { + const promise = new Promise((resolve, reject) => { + if (isUndefinedOrNull(activityTypeName)) { + reject("activityTypeName argument can not be undefined"); + return; + } + if (!isString(activityTypeName)) { + reject("activityTypeName should be string"); + return; + } + const actType = this.getActivityType(activityTypeName); + if (!isUndefinedOrNull(actType)) { + reject("Activity type '" + activityTypeName + "' already exists"); + return; + } + let ownerDefinition; + if (isUndefined(ownerWindowType)) { + reject("Owner window type can not be undefined"); + return; + } + if (isString(ownerWindowType)) { + ownerDefinition = { type: (ownerWindowType), name: "", isIndependent: false, arguments: {} }; + } + else { + ownerDefinition = (ownerWindowType); + } + const helperDefinitions = []; + if (!isUndefined(helperWindowTypes) && isArray(helperWindowTypes)) { + for (const index in helperWindowTypes) { + const item = helperWindowTypes[index]; + if (isString(item)) { + const definition = { + type: (item), + name: "", + isIndependent: false, + arguments: {}, + relativeTo: "", + relativeDirection: "", + windowStyleAttributes: {} + }; + helperDefinitions.push(definition); + } + else { + helperDefinitions.push(item); + } + } + } + this._bridge + .registerActivityType(activityTypeName, ownerDefinition, helperDefinitions, config, description) + .then((activityType) => { + this._grabEntity(activityType); + resolve(activityType); + }) + .catch((error) => { + reject(error); + }); + }); + return nodeify(promise, callback); + } + unregisterActivityType(type, callback) { + const promise = new Promise((resolve, reject) => { + const actType = this.getActivityType(type); + if (isUndefined(actType)) { + reject("Activity type '" + type + "' does not exists"); + return; + } + this._bridge.unregisterActivityType(type).then(() => resolve(actType), reject); + }); + return nodeify(promise, callback); + } + initiate(activityType, context, callback, configuration) { + const promise = new Promise((resolve, reject) => { + const actType = this.getActivityType(activityType); + if (isUndefined(actType)) { + reject("Activity type '" + activityType + "' does not exists"); + return; + } + this._bridge + .initiateActivity(activityType, context, configuration) + .then((actId) => { + this._activities + .getOrWait(actId) + .then((act) => { + resolve(act); + }) + .catch((err) => reject(err)); + }) + .catch((err) => { + reject(err); + }); + }); + return nodeify(promise, callback); + } + subscribeActivityTypeEvents(handler) { + this._activityTypes.subscribe((at, context) => { + handler(at, context.type); + }); + } + getWindowTypes() { + return this._windowTypes.get(); + } + getWindowType(name) { + return this._windowTypes.getByName(name); + } + registerWindowFactory(windowType, factoryMethod, callback) { + const promise = new Promise((resolve, reject) => { + if (isUndefinedOrNull(windowType)) { + reject("no windowType specified"); + return; + } + if (isObject(windowType)) { + windowType = windowType.getName(); + } + else if (!isString(windowType)) { + reject("windowType should be string or object that has getName method"); + return; + } + this._bridge + .registerWindowFactory(windowType, factoryMethod) + .then((v) => { + resolve(v); + }) + .catch((err) => { + reject(err); + }); + }); + return nodeify(promise, callback); + } + unregisterWindowFactory(windowType, callback) { + const promise = new Promise((resolve, reject) => { + if (isUndefinedOrNull(windowType)) { + reject("no windowType specified"); + return; + } + if (!isString(windowType)) { + reject("windowType should be a string"); + return; + } + this._bridge + .unregisterWindowFactory(windowType) + .then((v) => { + resolve(v); + }) + .catch((err) => { + reject(err); + }); + }); + return nodeify(promise, callback); + } + getActivities(activityType) { + let act = this._activities.get(); + act = act.filter((a) => a._ownerId); + if (!activityType) { + return act; + } + let types = activityType; + if (isString(activityType)) { + types = [activityType]; + } + else if (activityType instanceof ActivityType) { + types = [activityType.name]; + } + else if (activityType instanceof Array) ; + else { + throw new Error("Invalid input argument 'activityType' = " + activityType); + } + return act.filter((at) => { + const type = at.type; + return some(types, (t) => { + return type.id === t.id; + }); + }); + } + getActivityById(id) { + return this._activities.getByName(id); + } + announceWindow(activityWindowId, windowType) { + const promise = new Promise((resolve, reject) => { + const announcementInfo = this._bridge.getAnnouncementInfo(); + if (isUndefined(activityWindowId)) { + activityWindowId = announcementInfo.activityWindowId; + } + if (isUndefined(windowType)) { + windowType = announcementInfo.activityWindowType; + } + if (isUndefinedOrNull(windowType)) { + throw new Error("Can not announce - unknown windowType"); + } + const activityId = announcementInfo && announcementInfo.activityId; + if (isUndefinedOrNull(activityWindowId)) { + this._logger.debug("Registering window with type:'" + windowType + "', name:'" + announcementInfo.activityWindowName + "', ind.:'" + announcementInfo.activityWindowIndependent + "'"); + this._bridge.registerWindow(windowType, announcementInfo.activityWindowName, announcementInfo.activityWindowIndependent) + .then(this._windows.getOrWait.bind(this._windows)) + .then((w) => { + if (activityId) { + return this._activities.getOrWait(activityId).then((_) => w); + } + else { + return w; + } + }) + .then((w) => { + resolve(w); + }) + .catch((err) => { + this._logger.error(err); + }); + } + else { + this._logger.debug("Announcing window with id '" + activityWindowId + "' and type '" + windowType + "'"); + const currentWindow = this._windows.getByName(activityWindowId); + if (!isUndefinedOrNull(currentWindow)) { + this._logger.debug("Window with id '" + activityWindowId + "' already announced - reusing the window"); + resolve(currentWindow); + return; + } + const windowEventHandler = (a, w, e) => { + if (activityWindowId === w.id) { + if (e === EntityEventType.ActivityWindowJoinedActivity) { + const activity = w.activity; + if (isUndefined(activity)) { + reject("UNDEFINED ACTIVITY"); + } + this._logger.trace("Got joined event for id '" + activityWindowId + "'"); + resolve(w); + this.unsubscribeWindowEvents(windowEventHandler); + } + } + }; + this.subscribeWindowEvents(windowEventHandler); + this._logger.trace("Waiting for joined event for id '" + activityWindowId + "'"); + this._bridge.announceWindow(windowType, activityWindowId); + } + }); + return promise; + } + subscribeWindowTypeEvents(handler) { + this._windowTypes.subscribe((wt, context) => { + handler(wt, context.type); + }); + } + subscribeActivityEvents(handler) { + return this._activities.subscribe((act, context) => { + if (context.type === EntityEventType.StatusChange) { + const p = context; + handler(act, p.newStatus, p.oldStatus); + } + if (context.type === EntityEventType.Removed || + (context.type === EntityEventType.StatusChange && + context.newStatus.getState() === ActivityState.Destroyed)) { + for (const window of this._windows.get()) { + if (window.activity && window.activity.id === act.id) { + this._windows.process(new EntityEvent(window, new EntityEventContext(EntityEventType.ActivityWindowLeftActivity))); + } + } + } + }); + } + subscribeWindowEvents(handler) { + const wrappingHandler = (window, context) => { + let eventType = context.type; + if (eventType === EntityEventType.Added) { + eventType = "opened"; + } + handler(window.activity, window, eventType); + }; + this._windowHandlers.push([handler, wrappingHandler]); + return this._windows.subscribe(wrappingHandler); + } + unsubscribeWindowEvents(handler) { + const found = this._windowHandlers.find((pair) => pair[0] === handler); + if (found) { + this._windowHandlers.splice(this._windowHandlers.indexOf(found), 1); + this._windows.unsubscribe(found[1]); + } + } + createWindow(activity, windowTypeOrConfiguration, callback) { + const promise = new Promise((resolve, reject) => { + if (isUndefinedOrNull(windowTypeOrConfiguration)) { + reject("windowType is undefined"); + } + let windowDefinition; + if (isString(windowTypeOrConfiguration)) { + windowDefinition = { type: (windowTypeOrConfiguration), name: "", isIndependent: false, arguments: {} }; + } + else if (windowTypeOrConfiguration instanceof WindowType) { + windowDefinition = { + type: windowTypeOrConfiguration.type || windowTypeOrConfiguration.id, + name: windowTypeOrConfiguration.name || windowTypeOrConfiguration.type || windowTypeOrConfiguration.id, + isIndependent: false + }; + } + else { + const invalidKeys = ["url"]; + const filteredWindowTypeOrConfiguration = {}; + Object.keys(windowTypeOrConfiguration).forEach((key) => { + if (invalidKeys.indexOf(key) === -1) { + filteredWindowTypeOrConfiguration[key] = windowTypeOrConfiguration[key]; + } + }); + windowDefinition = filteredWindowTypeOrConfiguration; + } + let relativeToWindow; + if (!isUndefinedOrNull(windowDefinition.relativeTo)) { + relativeToWindow = windowDefinition.relativeTo; + if (typeof relativeToWindow === "string") { + const windows = this.getWindows({ type: relativeToWindow }); + if (!isUndefinedOrNull(windows) && windows.length > 0) { + windowDefinition.relativeTo = windows[0].id; + } + } + else if (!isUndefinedOrNull(relativeToWindow.type)) { + const windows = this.getWindows({ type: relativeToWindow.type }); + if (!isUndefinedOrNull(windows) && windows.length > 0) { + windowDefinition.relativeTo = windows[0].id; + } + } + else if (!isUndefinedOrNull(relativeToWindow.windowId)) { + windowDefinition.relativeTo = relativeToWindow.windowId; + } + } + this._bridge.createWindow(activity && activity.id, windowDefinition) + .then((wid) => { + this._logger.debug("Window created, waiting for window entity with id " + wid); + const handler = (window, context) => { + if (window.id === wid && (!activity || window.activity)) { + this._logger.debug("Got entity window with id " + wid); + resolve(window); + this._windows.unsubscribe(handler); + } + }; + this._windows.subscribe(handler); + }) + .catch((err) => { + reject(err); + }); + }); + return nodeify(promise, callback); + } + createStackedWindows(activity, relativeWindowTypes, timeout, callback) { + const promise = new Promise((resolve, reject) => { + if (isUndefinedOrNull(activity)) { + reject("activity is undefined"); + } + if (isUndefinedOrNull(relativeWindowTypes)) { + reject("relativeWindowTypes is undefined"); + } + if (!Array.isArray(relativeWindowTypes)) { + reject("relativeWindowTypes has to be an array"); + } + if (isUndefinedOrNull(timeout)) { + timeout = 20000; + } + const windowDefinitions = []; + relativeWindowTypes.forEach((element) => { + let windowDefinition; + if (isString(element)) { + windowDefinition = { type: (element), name: "", isIndependent: false, arguments: {} }; + } + else { + windowDefinition = (element); + } + windowDefinition.stackedWindow = true; + windowDefinition.timeout = timeout; + let relativeToWindow; + if (!isUndefinedOrNull(windowDefinition.relativeTo)) { + relativeToWindow = windowDefinition.relativeTo; + if (!isUndefinedOrNull(relativeToWindow.type)) { + windowDefinition.relativeTo = relativeToWindow.type; + } + else if (!isUndefinedOrNull(relativeToWindow.windowId)) { + const windows = this.getWindows({ id: relativeToWindow.windowId }); + if (!isUndefinedOrNull(windows) && windows.length > 0) { + windowDefinition.relativeTo = windows[0].type.name; + } + } + } + windowDefinitions.push(windowDefinition); + }); + const tasks = []; + windowDefinitions.forEach((wd) => tasks.push(this.createWindow(activity, wd))); + Promise.all(tasks).then(resolve).catch(reject); + }); + return nodeify(promise, callback); + } + addWindowToActivity(activity, window, callback) { + const toReturn = this._bridge.joinActivity(activity.id, window.id) + .then(() => window); + nodeify(toReturn, callback); + return toReturn; + } + leaveWindowFromActivity(activity, window, callback) { + const toReturn = this._bridge.leaveActivity(activity.id, window.id) + .then(() => window); + nodeify(toReturn, callback); + return toReturn; + } + setActivityContext(activity, context, callback) { + const promise = new Promise((resolve, reject) => { + if (isUndefinedOrNull(activity)) { + reject("activity can not be null"); + } + this._bridge + .updateActivityContext(activity, context, true) + .then((_) => { + resolve(activity); + }) + .catch((err) => { + reject(err); + }); + }); + return nodeify(promise, callback); + } + updateActivityContext(activity, context, callback) { + const promise = new Promise((resolve, reject) => { + if (isUndefinedOrNull(activity)) { + reject("activity can not be null"); + } + const removedKeys = []; + for (const key in context) { + if (context.hasOwnProperty(key) && context[key] === null) { + removedKeys.push(key); + } + } + for (const removedKey of removedKeys) { + delete context[removedKey]; + } + this._bridge + .updateActivityContext(activity, context, false, removedKeys) + .then((_) => { + resolve(activity); + }) + .catch((err) => { + reject(err); + }); + }); + return nodeify(promise, callback); + } + subscribeActivityContextChanged(handler) { + this._activities.subscribe((act, context) => { + if (context.type === EntityEventType.ActivityContextChange) { + const updateContext = context; + handler(act, updateContext.context, updateContext.updated, updateContext.removed); + } + }); + } + stopActivity(activity, callback) { + const promise = this._bridge.stopActivity(activity); + return nodeify(promise, callback); + } + getWindows(filter) { + if (isUndefined(filter)) { + return this._windows.get(); + } + if (!isUndefined(filter.id)) { + return [this._windows.getByName(filter.id)]; + } + const allWindows = this._windows.get(); + return allWindows.filter((w) => { + if (!isUndefined(filter.type) && w.type.id !== filter.type) { + return false; + } + if (!isUndefined(filter.name) && w.name !== filter.name) { + return false; + } + if (!isUndefined(filter.activityId)) { + if (isUndefinedOrNull(w.activity)) { + return false; + } + if (w.activity.id !== filter.activityId) { + return false; + } + } + return true; + }); + } + getWindowBounds(id) { + return this._bridge.getWindowBounds(id); + } + setWindowBounds(id, bounds, callback) { + const promise = new Promise((resolve, reject) => { + this._bridge.setWindowBounds(id, bounds) + .then(() => resolve()) + .catch((err) => reject(err)); + }); + return nodeify(promise, callback); + } + closeWindow(id) { + return this._bridge.closeWindow(id); + } + activateWindow(id, focus) { + return this._bridge.activateWindow(id, focus); + } + setWindowVisibility(id, visible) { + return this._bridge.setWindowVisibility(id, visible); + } + clone(activity, cloneOptions, callback) { + const promise = new Promise((resolve, reject) => { + if (!activity) { + reject("activity can not be null"); + } + this._bridge.cloneActivity(activity.id, cloneOptions) + .then((activityId) => { + this._activities + .getOrWait(activityId) + .then((act) => { + resolve(act); + }) + .catch((err) => reject(err)); + }) + .catch((err) => reject(err)); + }); + return nodeify(promise, callback); + } + attachActivities(from, to, tag, callback) { + tag = tag || {}; + const promise = new Promise((resolve, reject) => { + const fromActivity = this._activities.getByName(from); + if (!fromActivity) { + reject("can not find activity with id " + from); + return; + } + const toActivity = this._activities.getByName(to); + if (!toActivity) { + reject("can not find activity with id " + to); + return; + } + return this._bridge.attachActivities(from, to, tag) + .then((data) => { + const newActId = data.to; + const state = data.descriptor; + const allStates = data.descriptors; + this._activities.getOrWait(newActId).then((act) => { + act._updateDescriptors(allStates); + const stateWrapped = act.attached.filter((u) => u.ownerId === state.ownerId)[0]; + resolve(stateWrapped); + }); + }) + .catch((err) => { + reject(err); + }); + }); + return nodeify(promise, callback); + } + detachActivities(activityId, descriptor, callback) { + const promise = new Promise((resolve, reject) => { + return this._bridge.detachActivities(activityId, descriptor) + .then(() => { + const oldActId = undefined; + const newActId = undefined; + const descriptors = undefined; + this._activities + .getOrWait(oldActId) + .then((oldAct) => { + oldAct._updateDescriptors(descriptors); + this._activities + .getOrWait(newActId) + .then((newAct) => { + resolve(newAct); + }); + }) + .catch((err) => reject(err)); + }) + .catch((err) => { + reject(err); + }); + }); + return nodeify(promise, callback); + } + subscribeActivitiesAttached(callback) { + this._attachedCallbacks.push(callback); + } + subscribeActivitiesDetached(callback) { + this._detachedCallbacks.push(callback); + } + subscribeActivityFrameColorChanged(callback) { + this._frameColorChangesCallbacks.push(callback); + } + _grabEntity(entity) { + entity._manager = this; + } + _getInitialData() { + this._logger.debug("Request initial data..."); + this._bridge.getActivityTypes() + .then((at) => { + this._activityTypes.add(at); + this._dataReadyMarker.signal("Got act types"); + }) + .catch((error) => { + this._logger.error(error); + this._dataReadyMarker.error("Can not initialize ActivityManager - error getting activity types -" + error); + }); + this._bridge.getWindowTypes() + .then((wt) => { + this._windowTypes.add(wt); + this._dataReadyMarker.signal("Got window types"); + }) + .catch((error) => { + this._logger.error(error); + this._dataReadyMarker.error("Can not initialize ActivityManager - error getting window types " + error); + }); + this._bridge.getActivities() + .then((ac) => { + this._activities.add(ac); + this._dataReadyMarker.signal("Got activities"); + }) + .catch((error) => { + this._logger.error(error); + this._dataReadyMarker.error("Can not initialize ActivityManager - error getting activity instances -" + error); + }); + this._bridge.getActivityWindows() + .then((aw) => { + this._windows.add(aw); + this._dataReadyMarker.signal("Got windows"); + }) + .catch((error) => { + this._logger.error(error); + this._dataReadyMarker.error("Can not initialize ActivityManager - error getting activity windows -" + error); + }); + } + _subscribeForData() { + this._logger.debug("Subscribe for data..."); + this._bridge.onActivityTypeStatusChange((event) => { + this._activityTypes.process(event); + }); + this._bridge.onWindowTypeStatusChange((event) => { + this._windowTypes.process(event); + }); + this._bridge.onActivityWindowChange((event) => { + this._windows.process(event); + }); + this._bridge.onActivityStatusChange((event) => { + this._activities.process(event); + }); + } + _handleActivitiesAttached(data) { + const newActId = data.to; + const descriptor = data.descriptor; + const descriptors = data.descriptors; + this._activities.getOrWait(newActId).then((act) => { + act._updateDescriptors(descriptors); + const descriptorAsObjectFromAPI = act.attached.filter((u) => u.ownerId === descriptor.ownerId)[0]; + this._attachedCallbacks.forEach((callback) => { + try { + callback(act, descriptorAsObjectFromAPI); + } + catch (err) { + return; + } + }); + }); + } + _handleActivitiesDetached(data) { + const oldActId = data.oldActivityId; + const newActId = data.newActivityId; + const descriptors = data.descriptors; + const descriptor = data.descriptor; + this._activities.getOrWait(oldActId).then((oldAct) => { + oldAct._updateDescriptors(descriptors); + this._activities.getOrWait(newActId).then((newAct) => { + this._detachedCallbacks.forEach((callback) => { + try { + callback(newAct, oldAct, descriptor); + } + catch (err) { + return; + } + }); + }); + }); + } + _handleActivityDescriptorsRefreshed(data) { + const id = data.id; + const descriptors = data.descriptors; + const act = this._activities.getByName(id); + if (act) { + act._updateDescriptors(descriptors); + } + } + refreshDescriptors() { + this._bridge.getAttachedDescriptors() + .then((map) => { + if (map) { + Object.keys(map).forEach((key) => { + const actId = key; + const descriptors = map[key]; + const act = this._activities.getByName(actId); + if (act) { + act._updateDescriptors(descriptors); + } + }); + } + this._descriptorsMarker.signal("Successfully got descriptors"); + }) + .catch((err) => { + this._descriptorsMarker.error("failed to get descriptors - " + err); + }); + } + _handleWindowFrameColorChanged(win) { + if (!win.activityId) { + return; + } + const act = this._activities.getByName(win.activityId); + if (!act) { + return; + } + if (!act.owner) { + return; + } + if (act.owner.underlyingWindow.id !== win.id) { + return; + } + this._frameColorChangesCallbacks.forEach((callback) => { + try { + callback(act, win.frameColor); + } + catch (e) { + return; + } + }); + } + } + + class ActivityManagementAPI { + constructor(manager, my) { + this._m = manager; + this._my = my; + this.activityTypes = { + get: this._getActivityTypesWrapper.bind(this), + register: this._m.registerActivityType.bind(this._m), + unregister: this._m.unregisterActivityType.bind(this._m), + subscribe: this._m.subscribeActivityTypeEvents.bind(this._m), + unsubscribe: undefined, + initiate: this._m.initiate.bind(this._m) + }; + this.windowTypes = { + get: this._getWindowTypesWrapper.bind(this), + registerFactory: this._m.registerWindowFactory.bind(this._m), + unregisterFactory: this._m.unregisterWindowFactory.bind(this._m), + subscribe: this._m.subscribeWindowTypeEvents.bind(this._m), + unsubscribe: undefined + }; + this.windows = { + get: this._m.getWindows.bind(this._m), + subscribe: this._m.subscribeWindowEvents.bind(this._m), + announce: this._m.announceWindow.bind(this._m), + unsubscribe: undefined, + create: this._m.createWindow.bind(this._m) + }; + this.instances = { + get: this._m.getActivities.bind(this._m), + subscribe: this._m.subscribeActivityEvents.bind(this._m), + unsubscribe: undefined + }; + } + onAttached(callback) { + this._m.subscribeActivitiesAttached(callback); + } + onDetached(callback) { + this._m.subscribeActivitiesDetached(callback); + } + onActivityFrameColorChanged(callback) { + this._m.subscribeActivityFrameColorChanged(callback); + } + _getActivityTypesWrapper(name) { + if (isUndefined(name)) { + return this._m.getActivityTypes(); + } + return this._m.getActivityType(name); + } + _getWindowTypesWrapper(name) { + if (isUndefined(name)) { + return this._m.getWindowTypes(); + } + return this._m.getWindowType(name); + } + } + + class ActivityAPI { + constructor(manager, my) { + this._mgr = manager; + this._my = my; + this.all = new ActivityManagementAPI(manager, my); + } + ready(callback) { + const promise = new Promise((resolve, reject) => { + this._mgr.ready() + .then(() => { + resolve(this); + }) + .catch((err) => { + reject(err); + }); + }); + return nodeify(promise, callback); + } + get my() { + return this._my; + } + get aware() { + return this._my.window !== undefined; + } + get inActivity() { + return this.aware && this._my.activity !== undefined; + } + get agm() { + if (!this.aware) { + return undefined; + } + if (!this.inActivity) { + return new ActivityAGM(null); + } + return this._my.activity.agm; + } + getAvailableFrameColors() { + return []; + } + } + + class ActivityModule { + static checkIsUsingGW3Implementation(connection) { + return connection.protocolVersion === 3; + } + get api() { + return this._api; + } + set api(value) { + this._api = value; + } + constructor(config) { + if (!config) { + throw new Error("config can not be null"); + } + if (!isUndefined(config.logLevel)) { + Logger.Level = config.logLevel; + } + if (!isUndefinedOrNull(config.logger)) { + Logger.GlueLogger = config.logger; + } + let bridge; + this._isUsingHCImplementation = config.gdMajorVersion === 2; + this._isUsingGW3Implementation = ActivityModule.checkIsUsingGW3Implementation(config.connection); + if (this._isUsingHCImplementation) { + throw new Error("GD2 not supported"); + } + else if (this._isUsingGW3Implementation) { + bridge = new GW3Bridge(config); + } + else { + throw new Error("Unable to instantiate activity bridge implementation"); + } + if (!bridge) { + throw new Error("A bridge to native activity is needed to create activity lib."); + } + ActivityAGM.AGM = config.agm; + const activityManager = new ActivityManager(bridge, !config.disableAutoAnnounce, config.windows); + const my = new ActivityMy(activityManager, config.windows); + this._api = new ActivityAPI(activityManager, my); + this._readyPromise = activityManager.ready().then((_) => this); + } + get isUsingHCImplementation() { + return this._isUsingHCImplementation; + } + get isUsingGW3Implementation() { + return this._isUsingGW3Implementation; + } + ready(callback) { + return nodeify(this._readyPromise, callback); + } + } + + const ShutdownMethodName = "T42.ACS.Shutdown"; + const OnGDShutdownMethodName = "T42.ACS.OnGDShutdown"; + const RestartMethodName = "T42.ACS.Restart"; + const GetConfigurationRegionMethodName = "T42.ACS.GetConfigurationRegion"; + const SetConfigurationRegionMethodName = "T42.ACS.SetConfigurationRegion"; + const GetUserMethodName = "T42.ACS.GetUser"; + const GetBranchesMethodName = "T42.ACS.GetBranches"; + const GetCurrentBranchMethodName = "T42.ACS.GetCurrentBranch"; + const SetCurrentBranchMethodName = "T42.ACS.SetCurrentBranch"; + const GetFunctionalEntitlementMethodName = "T42.ACS.GetFunctionalEntitlement"; + const CanIMethodName = "T42.ACS.CanI"; + const StartApplicationMethodName = "T42.ACS.StartApplication"; + const StopApplicationMethodName = "T42.ACS.StopApplication"; + const ActivateApplicationMethodName = "T42.ACS.ActivateApplication"; + const ACSExecute = "T42.ACS.Execute"; + const OnEventMethodName = "T42.ACS.OnEvent"; + const GetApplicationsMethodName = "T42.ACS.GetApplications"; + + var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; + + function getDefaultExportFromCjs (x) { + return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; + } + + function createRegistry(options) { + if (options && options.errorHandling + && typeof options.errorHandling !== "function" + && options.errorHandling !== "log" + && options.errorHandling !== "silent" + && options.errorHandling !== "throw") { + throw new Error("Invalid options passed to createRegistry. Prop errorHandling should be [\"log\" | \"silent\" | \"throw\" | (err) => void], but " + typeof options.errorHandling + " was passed"); + } + var _userErrorHandler = options && typeof options.errorHandling === "function" && options.errorHandling; + var callbacks = {}; + function add(key, callback, replayArgumentsArr) { + var callbacksForKey = callbacks[key]; + if (!callbacksForKey) { + callbacksForKey = []; + callbacks[key] = callbacksForKey; + } + callbacksForKey.push(callback); + if (replayArgumentsArr) { + setTimeout(function () { + replayArgumentsArr.forEach(function (replayArgument) { + var _a; + if ((_a = callbacks[key]) === null || _a === void 0 ? void 0 : _a.includes(callback)) { + try { + if (Array.isArray(replayArgument)) { + callback.apply(undefined, replayArgument); + } + else { + callback.apply(undefined, [replayArgument]); + } + } + catch (err) { + _handleError(err, key); + } + } + }); + }, 0); + } + return function () { + var allForKey = callbacks[key]; + if (!allForKey) { + return; + } + allForKey = allForKey.reduce(function (acc, element, index) { + if (!(element === callback && acc.length === index)) { + acc.push(element); + } + return acc; + }, []); + if (allForKey.length === 0) { + delete callbacks[key]; + } + else { + callbacks[key] = allForKey; + } + }; + } + function execute(key) { + var argumentsArr = []; + for (var _i = 1; _i < arguments.length; _i++) { + argumentsArr[_i - 1] = arguments[_i]; + } + var callbacksForKey = callbacks[key]; + if (!callbacksForKey || callbacksForKey.length === 0) { + return []; + } + var results = []; + callbacksForKey.forEach(function (callback) { + try { + var result = callback.apply(undefined, argumentsArr); + results.push(result); + } + catch (err) { + results.push(undefined); + _handleError(err, key); + } + }); + return results; + } + function _handleError(exceptionArtifact, key) { + var errParam = exceptionArtifact instanceof Error ? exceptionArtifact : new Error(exceptionArtifact); + if (_userErrorHandler) { + _userErrorHandler(errParam); + return; + } + var msg = "[ERROR] callback-registry: User callback for key \"" + key + "\" failed: " + errParam.stack; + if (options) { + switch (options.errorHandling) { + case "log": + return console.error(msg); + case "silent": + return; + case "throw": + throw new Error(msg); + } + } + console.error(msg); + } + function clear() { + callbacks = {}; + } + function clearKey(key) { + var callbacksForKey = callbacks[key]; + if (!callbacksForKey) { + return; + } + delete callbacks[key]; + } + return { + add: add, + execute: execute, + clear: clear, + clearKey: clearKey + }; + } + createRegistry.default = createRegistry; + var lib = createRegistry; + + + var CallbackRegistryFactory = /*@__PURE__*/getDefaultExportFromCjs(lib); + + function objectValues(source) { + if (!source) { + return []; + } + return Object.keys(source).map((key) => source[key]); + } + function objectClone(obj) { + let result; + try { + result = JSON.parse(JSON.stringify(obj || {})); + } + catch (error) { + result = {}; + } + return result; + } + function validate(callback, configuration) { + if (configuration.throwErrors) { + if (typeof callback !== "function") { + throw new Error("Please provide the callback as a function!"); + } + } + } + + const INTEROP_METHOD_RESPONSE_TIMEOUT_MS = 90000; + const INTEROP_METHOD_WAIT_TIMEOUT_MS = 90000; + + let urlAlphabet = + 'useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict'; + let nanoid = (size = 21) => { + let id = ''; + let i = size | 0; + while (i--) { + id += urlAlphabet[(Math.random() * 64) | 0]; + } + return id + }; + + class Utils { + static getGDMajorVersion() { + if (typeof window === "undefined") { + return -1; + } + if (!window.glueDesktop) { + return -1; + } + if (!window.glueDesktop.version) { + return -1; + } + const parsed = window.glueDesktop.version.split("."); + const major = Number(parsed[0]); + return isNaN(major) ? -1 : major; + } + static typedError(error) { + let err; + if (error instanceof Error) { + err = error; + } + else if (typeof error === "string") { + err = new Error(error); + } + else if ("message" in error && typeof error.message === "string" && error.message.length > 0) { + err = new Error(error.message); + } + else if ("returned" in error + && typeof error.returned === "object" + && "errorMsg" in error.returned + && typeof error.returned.errorMsg === "string" + && error.returned.errorMsg.length > 0) { + err = new Error(error.returned.errorMsg); + } + else { + err = new Error("Unknown error"); + } + return err; + } + static async callbackifyPromise(action, successCallback, errorCallback) { + const success = (result) => { + if (typeof successCallback === "function") { + successCallback(result); + } + return Promise.resolve(result); + }; + const fail = (error) => { + const err = Utils.typedError(error); + if (typeof errorCallback === "function") { + errorCallback(err.message); + return; + } + return Promise.reject(err); + }; + try { + const result = await action(); + return success(result); + } + catch (error) { + return fail(error); + } + } + static getMonitor(bounds, displays) { + const monitorsSortedByOverlap = displays.map((m) => { + const { left, top, workingAreaWidth: width, workingAreaHeight: height } = m; + const overlap = this.calculateTotalOverlap({ left, top, width, height }, bounds); + return { + monitor: m, + totalOverlap: overlap + }; + }).sort((a, b) => b.totalOverlap - a.totalOverlap); + return monitorsSortedByOverlap[0].monitor; + } + static getDisplayCenterOfScreen(a, currentDisplay, primaryDisplay) { + const physicalWidth = a.width / currentDisplay.scaleFactor; + const physicalHeight = a.height / currentDisplay.scaleFactor; + const physicalDisplayLeft = currentDisplay.workArea.left / primaryDisplay.scaleFactor; + const physicalDisplayTop = currentDisplay.workArea.top / primaryDisplay.scaleFactor; + const physicalDisplayWidth = currentDisplay.workArea.width / currentDisplay.scaleFactor; + const physicalDisplayHeight = currentDisplay.workArea.height / currentDisplay.scaleFactor; + const physicalHOffset = Math.max((physicalDisplayWidth - physicalWidth) / 2, 0); + const physicalVOffset = Math.max((physicalDisplayHeight - physicalHeight) / 2, 0); + const centeredPhysicalLeft = Math.floor(physicalDisplayLeft + physicalHOffset); + const centeredPhysicalTop = Math.floor(physicalDisplayTop + physicalVOffset); + const left = centeredPhysicalLeft * primaryDisplay.scaleFactor; + const top = centeredPhysicalTop * primaryDisplay.scaleFactor; + return { + left, + top, + width: a.width, + height: a.height + }; + } + static isNode() { + if (typeof Utils._isNode !== "undefined") { + return Utils._isNode; + } + if (typeof window !== "undefined") { + Utils._isNode = false; + return false; + } + try { + Utils._isNode = Object.prototype.toString.call(global.process) === "[object process]"; + } + catch (e) { + Utils._isNode = false; + } + return Utils._isNode; + } + static generateId() { + return nanoid(10); + } + static isPromise(value) { + return Boolean(value && typeof value.then === 'function'); + } + static isAsyncFunction(value) { + return value && {}.toString.call(value) === '[object AsyncFunction]'; + } + static isNullOrUndefined(value) { + return value === null || value === undefined; + } + static calculateTotalOverlap(r1, r2) { + const r1x = r1.left; + const r1y = r1.top; + const r1xMax = r1x + r1.width; + const r1yMax = r1y + r1.height; + const r2x = r2.left; + const r2y = r2.top; + const r2xMax = r2x + r2.width; + const r2yMax = r2y + r2.height; + const xOverlap = Math.max(0, Math.min(r1xMax, r2xMax) - Math.max(r1x, r2x)); + const yOverlap = Math.max(0, Math.min(r1yMax, r2yMax) - Math.max(r1y, r2y)); + return xOverlap * yOverlap; + } + } + + class ApplicationImpl { + constructor(_appManager, _name, _agm, _logger, _configuration) { + this._appManager = _appManager; + this._name = _name; + this._agm = _agm; + this._logger = _logger; + this._configuration = _configuration; + this._registry = CallbackRegistryFactory(); + _appManager.onInstanceStarted((instance) => { + if (instance.application && instance.application.name !== this._name) { + return; + } + this._registry.execute("instanceStarted", instance); + }); + _appManager.onInstanceStopped((instance) => { + if (instance.application && instance.application.name !== this._name) { + return; + } + this._registry.execute("instanceStopped", instance); + }); + _appManager.onAppRemoved((app) => { + if (app.name !== this._name) { + return; + } + this._registry.execute("appRemoved", app); + }); + _appManager.onAppChanged((app) => { + if (app.name !== this._name) { + return; + } + this._registry.execute("appChanged", app); + }); + _appManager.onAppAvailable((app) => { + if (app.name !== this._name) { + return; + } + this._props.IsReady = true; + this._registry.execute("appAvailable", app); + }); + _appManager.onAppUnavailable((app) => { + if (app.name !== this._name) { + return; + } + this._props.IsReady = false; + this._registry.execute("appUnavailable", app); + }); + } + get name() { return this._name; } + get title() { return this._props.Title; } + get version() { return this._props.Version; } + get autoStart() { return this._props.AutoStart; } + get isShell() { return this._props.IsShell; } + get caption() { return this._props.Caption; } + get hidden() { return this._props.IsHidden; } + get container() { return this._props.ApplicationName; } + get activityType() { return this._props.ActivityType; } + get activityWindowType() { return this._props.ActivityWindowType; } + get windowSettings() { + if (!this._props.Arguments) { + return {}; + } + return objectClone(this._props.Arguments); + } + get allowMultiple() { return this._props.AllowMultiple; } + get available() { return this._props.IsReady || true; } + get icon() { return this._props.Icon; } + get iconURL() { return this._props.IconUrl; } + get sortOrder() { return this._props.SortOrder; } + get userProperties() { + if (!this._props.UserProperties) { + return {}; + } + return objectClone(this._props.UserProperties); + } + get keywords() { + if (!this._props.Keywords) { + return []; + } + return this._props.Keywords; + } + get isActivity() { + return this._props.ActivityType !== undefined && this._props.ActivityType !== ""; + } + get configuration() { + return { + autoStart: this._props.AutoStart, + caption: this._props.Caption, + hidden: this._props.IsHidden, + container: this._props.ApplicationName, + activityType: this._props.ActivityType, + allowMultiple: this._props.AllowMultiple + }; + } + get instances() { + return this._appManager.instances().filter((instance) => instance.application.name === this._name); + } + get type() { + return this._props.Type; + } + get mode() { + if (!this._props) { + return "unknown"; + } + if (this._props.Mode && typeof this._props.Mode === "string") { + return this._props.Mode.toLowerCase(); + } + if (this.isActivity) { + return "unknown"; + } + if (this._props.Arguments && this._props.Arguments.mode && typeof this._props.Arguments.mode === "string") { + return this._props.Arguments.mode.toLowerCase(); + } + let styleAttributes = this._props.WindowStyleAttributes; + if (styleAttributes) { + styleAttributes = styleAttributes.split(" ").join(""); + const searchFor = "mode:\""; + const modeIndex = styleAttributes.indexOf(searchFor); + if (modeIndex !== -1) { + const startModeIndex = modeIndex + searchFor.length; + const stopModeIndex = styleAttributes.indexOf("\"", startModeIndex); + const style = styleAttributes.substr(startModeIndex, stopModeIndex - startModeIndex); + if (style && typeof style === "string") { + return style.toLowerCase(); + } + } + } + return "flat"; + } + async getConfiguration() { + const result = await this._agm.invoke(GetApplicationsMethodName, { v2: { apps: [this._name] } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + const config = result.returned.applications[0]; + return config; + } + updateFromProps(props) { + if (!this._props) { + this._props = { Name: props.Name }; + } + Object.keys(props).forEach((key) => { + this._props[key] = props[key]; + }); + } + start(context, options) { + return new Promise(async (resolve, reject) => { + var _a, _b, _c, _d; + if (isUndefinedOrNull(context)) { + context = {}; + } + else if (((_a = this._configuration()) === null || _a === void 0 ? void 0 : _a.throwErrors) && typeof context !== "object" || Array.isArray(context)) { + return reject(new Error(`Invalid "context" parameter - must be an object.`)); + } + if (isUndefinedOrNull(options)) { + options = {}; + } + else if (((_b = this._configuration()) === null || _b === void 0 ? void 0 : _b.throwErrors) && typeof options !== "object") { + return reject(new Error(`Invalid "options" parameter - must be an object.`)); + } + const name = this._name; + let waitForAGMInstance = (_d = ((_c = options.awaitInterop) !== null && _c !== void 0 ? _c : options.waitForAGMReady)) !== null && _d !== void 0 ? _d : true; + let startTimeout = 60000; + if (typeof options.timeout === "number") { + startTimeout = options.timeout * 1000; + } + if (options.relativeTo !== undefined && typeof options.relativeTo !== "string") { + options.relativeTo = options.relativeTo.id || ""; + } + const waitForApplicationInstance = (id) => { + let unsub; + const timeout = setTimeout(() => { + if (unsub) { + unsub(); + } + const errMsg = `timed out while waiting for instance id ${id} for app ${this.name}`; + this._logger.error(errMsg); + reject(new Error(errMsg)); + }, startTimeout); + const waitFunc = (i) => { + if (i.id !== id) { + return; + } + if (unsub) { + unsub(); + unsub = undefined; + } + clearTimeout(timeout); + resolve(i); + }; + if (waitForAGMInstance) { + const instance = this._appManager.instances().find((i) => i.id === id); + if (instance) { + unsub = instance.onAgmReady(waitFunc); + } + else { + unsub = this._appManager.onInstanceAgmServerReady(waitFunc); + } + } + else { + unsub = this._appManager.onInstanceStarted(waitFunc); + } + }; + try { + this._logger.trace(`starting application ${name} with options: ${JSON.stringify(options)}`); + const result = await this._agm.invoke(StartApplicationMethodName, { + Name: name, + Context: context, + Options: options + }, "best", { + methodResponseTimeoutMs: startTimeout, + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + const acsResult = result.returned; + if (typeof acsResult.timeout !== "undefined" && typeof options.timeout === "undefined") { + startTimeout = acsResult.timeout * 1000; + } + if (typeof acsResult.waitForInterop !== "undefined" && (typeof options.waitForAGMReady === "undefined" && typeof options.awaitInterop === "undefined")) { + waitForAGMInstance = acsResult.waitForInterop; + } + if (acsResult && acsResult.Id) { + if (this._appManager.mode === "startOnly") { + const instance = this._appManager.handleInstanceStarted({ + ActivityId: undefined, + IsActivityOwner: undefined, + Context: undefined, + Title: undefined, + AgmServers: undefined, + Id: acsResult.Id, + Name: acsResult.Name, + }); + resolve(instance); + } + else { + waitForApplicationInstance(acsResult.Id); + } + } + else { + resolve(undefined); + } + } + catch (error) { + const err = Utils.typedError(error); + reject(err); + } + }); + } + onInstanceStarted(callback) { + validate(callback, this._configuration()); + return this._registry.add("instanceStarted", callback); + } + onInstanceStopped(callback) { + validate(callback, this._configuration()); + return this._registry.add("instanceStopped", callback); + } + onAvailable(callback) { + validate(callback, this._configuration()); + if (this._props.IsReady) { + setTimeout(() => { + this._registry.execute("appAvailable", this); + }, 0); + } + return this._registry.add("appAvailable", callback); + } + onUnavailable(callback) { + validate(callback, this._configuration()); + if (this._props.IsReady === false) { + setTimeout(() => { + this._registry.execute("appUnavailable", this); + }, 0); + } + return this._registry.add("appUnavailable", callback); + } + onChanged(callback) { + validate(callback, this._configuration()); + this._registry.add("appChanged", callback); + } + onRemoved(callback) { + validate(callback, this._configuration()); + this._registry.add("appRemoved", callback); + } + } + + class InstanceImpl { + constructor(_id, _appName, _appManager, _agm, _activities, _windows, _logger, startFailed, _configuration) { + this._id = _id; + this._appName = _appName; + this._appManager = _appManager; + this._agm = _agm; + this._activities = _activities; + this._windows = _windows; + this._logger = _logger; + this._configuration = _configuration; + this._registry = CallbackRegistryFactory(); + if (startFailed) { + return; + } + this._unsubscribeInstanceStopped = this._appManager.onInstanceStopped((instance) => { + if (instance.id !== this._id) { + return; + } + this._registry.execute("stopped", instance); + }); + this._unsubscribeInstanceAgmServerReady = this._appManager.onInstanceAgmServerReady((instance) => { + if (instance.id !== this._id) { + return; + } + this._registry.execute("agmReady", instance); + }); + } + get id() { return this._id; } + get application() { return this._appManager.application(this._appName); } + get activity() { + if (!this._activities) { + throw new Error("This method requires glue.activities library to be enabled."); + } + return this._activities.all.instances.get() + .filter((activityInstance) => activityInstance.id === this._activityId)[0]; + } + get isActivityOwner() { return this._isActivityOwner; } + get activityInstances() { + return this._appManager.instances().filter((i) => i.application.type !== "activity" && + i.activityId && + i.activityId === this._activityId); + } + get activityOwnerInstance() { + if (!this._activityId) { + return undefined; + } + return this.activityInstances.filter((inst) => inst === null || inst === void 0 ? void 0 : inst.isActivityOwner)[0]; + } + get window() { + if (!this._windows) { + throw new Error("This method requires glue.windows library to be enabled."); + } + let win = this._windows.list().find((w) => w.id === this._id); + if (!win && this._activities && this.activity && this.activityOwnerInstance) { + win = this.activityOwnerInstance.window; + } + return win; + } + get context() { + var _a, _b, _c; + return (_c = (_a = this._startUpContext) !== null && _a !== void 0 ? _a : (_b = this.window) === null || _b === void 0 ? void 0 : _b.context) !== null && _c !== void 0 ? _c : {}; + } + get title() { return this._title; } + get isActivityInstance() { return this._isActivityInstance; } + get activityId() { return this._activityId; } + get inActivity() { return this._inActivity; } + get isSingleWindowApp() { return !this._inActivity; } + get agm() { + return this._agmInstance; + } + get interopInstance() { + return this._agmInstance; + } + onInteropReady(callback) { + validate(callback, this._configuration()); + if (this._agmInstance) { + setTimeout(() => { + this._registry.execute("agmReady", this); + }, 0); + } + return this._registry.add("agmReady", callback); + } + onAgmReady(callback) { + return this.onInteropReady(callback); + } + onStopped(callback) { + validate(callback, this._configuration()); + return this._registry.add("stopped", callback); + } + getWindow() { + return new Promise((resolve, reject) => { + const result = this.window; + if (result) { + resolve(result); + return; + } + const done = (error, window) => { + if (error) { + reject(error); + } + if (window) { + resolve(window); + } + setTimeout(() => { + clearTimeout(timeout); + unsub(); + }, 0); + }; + this._logger.trace(`waiting for window with id ${this._id} to appear`); + const timeoutInSeconds = 60; + const timeout = setTimeout(() => { + this._logger.trace(`window with id ${this._id} did not appear in ${timeoutInSeconds} sec`); + done(new Error(`can not find a window with id ${this._id}`)); + }, timeoutInSeconds * 1000); + const unsub = this._windows.onWindowAdded((w) => { + if (w.id === this._id) { + this._logger.trace(`window with id ${this._id} appeared`); + done(undefined, w); + } + }); + }); + } + updateFromProps(props) { + this._startUpContext = props.Context; + this._title = props.Title; + this._isActivityInstance = false; + if (props.ActivityId && props.ActivityId !== "") { + this._activityId = props.ActivityId; + this._isActivityInstance = true; + } + this._isActivityOwner = props.IsActivityOwner; + if (!this._activityId && this._startUpContext && this._startUpContext.activityId) { + this._activityId = this._startUpContext.activityId; + } + this._inActivity = Boolean(this._activityId); + this.updateAgmInstanceFromProps(props); + } + updateAgmInstanceFromProps(props) { + if (!props.AgmServers) { + return; + } + const agmInstances = props.AgmServers; + if (agmInstances && agmInstances.length > 0 && !isUndefinedOrNull(agmInstances[0])) { + this._agmInstance = agmInstances[0]; + } + } + stop() { + return new Promise((resolve, reject) => { + let idToResolve = this._id; + if (this.isActivityOwner) { + idToResolve = this.activityId; + } + const unsubscribe = this._appManager.onInstanceStopped((instance) => { + if (instance.id === idToResolve) { + this._logger.trace(`instance with id ${idToResolve} stopped`); + unsubscribe(); + resolve(); + } + }); + this._logger.trace(`stopping instance with id ${this._id}`); + this._agm.invoke(StopApplicationMethodName, { + Name: this._appName, + Id: this._id + }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }) + .then(() => { + if (this._appManager.mode === "startOnly") { + this._appManager.handleInstanceStopped({ + Name: this._appName, + Id: this.id + }); + resolve(); + } + }) + .catch((err) => reject(err)); + }); + } + activate() { + return this._agm.invoke(ActivateApplicationMethodName, { Name: this._appName, Id: this._id }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + done() { + this._registry.clear(); + this._unsubscribeInstanceAgmServerReady(); + this._unsubscribeInstanceStopped(); + } + getContext() { + return Promise.resolve(this.context); + } + async startedBy() { + const result = await this._agm.invoke(ACSExecute, { command: "getStartedBy", Name: this._appName, Id: this._id }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return result.returned; + } + } + + class AppManagerImpl { + constructor(mode, _agm, _activities, _windows, _logger, _gdMajorVersion, _configuration) { + this.mode = mode; + this._agm = _agm; + this._activities = _activities; + this._windows = _windows; + this._logger = _logger; + this._gdMajorVersion = _gdMajorVersion; + this._configuration = _configuration; + this._apps = {}; + this._instances = []; + this._registry = CallbackRegistryFactory(); + this.getConfigurations = async (apps) => { + const args = { + v2: { + apps: undefined + } + }; + if (Array.isArray(apps)) { + args.v2 = { + apps + }; + } + const result = await this._agm.invoke(GetApplicationsMethodName, args, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return result.returned.applications; + }; + this.application = (name) => { + var _a; + if (((_a = this._configuration()) === null || _a === void 0 ? void 0 : _a.throwErrors) && typeof name !== "string" || isNullOrWhiteSpace(name)) { + throw new Error(`"name" must be string`); + } + return this._apps[name]; + }; + this.applications = () => { + return Object.keys(this._apps).map((k) => this._apps[k]); + }; + this.instances = () => { + return this._instances.map((i) => i); + }; + this.getMyInstance = () => { + const glue42gd = typeof window !== "undefined" && window.glue42gd; + if (glue42gd) { + if (this._gdMajorVersion >= 3) { + const instanceId = glue42gd.appInstanceId; + return this._instances.find((i) => i.id === instanceId); + } + } + else { + const instanceId = this._agm.instance.instance; + return this._instances.find((i) => i.id === instanceId); + } + return undefined; + }; + this.getMyApplication = () => { + var _a; + if (this._agm.instance) { + return (_a = this.application(this._agm.instance.applicationName)) !== null && _a !== void 0 ? _a : this.application(this._agm.instance.application); + } + }; + this.handleSnapshotAppsAdded = (newApps) => { + const currentApps = this.applications(); + if (currentApps.length > 0) { + currentApps.forEach((item) => { + const name = item.name; + const alreadyExists = newApps.find((i) => i.Name === item.name); + if (!alreadyExists) { + this.handleAppRemoved({ Name: name }); + } + }); + } + newApps.forEach((item) => { + const alreadyExists = currentApps.find((i) => i.name === item.Name); + if (!alreadyExists) { + this.handleAppAdded(item); + } + }); + }; + this.handleSnapshotInstanceStarted = (newInstances) => { + const currentInstances = this.instances(); + if (currentInstances.length > 0) { + currentInstances.forEach((item) => { + const id = item.id; + const alreadyExists = newInstances.find((i) => i.Id === id); + if (!alreadyExists) { + this.handleInstanceStopped({ Name: item.application.name, Id: id }); + } + }); + } + newInstances.forEach((item) => { + const alreadyExists = currentInstances.find((i) => i.id === item.Id); + if (!alreadyExists) { + this.handleInstanceStarted(item); + } + }); + }; + this.handleAppAdded = (props) => { + const id = this._getAppId(props); + this._logger.trace(`adding app ${id}`); + this._apps[id] = new ApplicationImpl(this, id, this._agm, this._logger, this._configuration); + const app = this._updateAppFromProps(props); + this._registry.execute("appAdded", app); + this._registry.execute("appAvailable", app); + }; + this.handleAppUpdated = (props) => { + const app = this._updateAppFromProps(props); + this._registry.execute("appChanged", app); + }; + this.handleAppRemoved = (props) => { + const id = this._getAppId(props); + this._logger.trace(`removing app ${id}`); + const app = this.application(id); + this._instances = this._instances.filter((i) => i.application.name !== app.name); + delete this._apps[id]; + this._registry.execute("appRemoved", app); + }; + this.handleAppReady = (props) => { + const id = this._getAppId(props); + const app = this._getAppOrThrow(id); + app.updateFromProps(props); + if (app.available) { + this._registry.execute("appAvailable", app); + } + else { + this._registry.execute("appUnavailable", app); + } + }; + this.handleInstanceStarted = (props) => { + this._logger.trace(`started app ${props.Name} ${props.Id}`); + const id = this._getInstanceId(props); + const appName = this._getInstanceAppName(props); + const instance = new InstanceImpl(id, appName, this, this._agm, this._activities, this._windows, this._logger, false, this._configuration); + this._updateInstanceFromProps(instance, props); + this._instances.push(instance); + this._registry.execute("instanceStarted", instance); + return instance; + }; + this.handleInstanceStopped = (props) => { + this._logger.trace(`instance stopped ${props.Name} ${props.Id}`); + const id = this._getInstanceId(props); + const appName = this._getInstanceAppName(props); + const instance = this._getInstanceOrThrow(id, appName); + this._instances = this._instances.filter((i) => !this._matchInstance(i, id, appName)); + this._registry.execute("instanceStopped", instance); + instance.done(); + }; + this.handleInstanceAgmServerReady = (props) => { + this._logger.trace(`instance interop server ready ${props.Name} ${props.Id}`); + const id = this._getInstanceId(props); + const appName = this._getInstanceAppName(props); + const instance = this._getInstanceOrThrow(id, appName); + instance.updateAgmInstanceFromProps(props); + this._registry.execute("instanceAgmServerReady", instance); + }; + this.handleInstanceStartFailed = (props) => { + const id = this._getInstanceId(props); + const appName = this._getInstanceAppName(props); + const startFailed = true; + const instance = new InstanceImpl(id, appName, undefined, undefined, undefined, undefined, this._logger, startFailed, this._configuration); + this._updateInstanceFromProps(instance, props); + this._registry.execute("instanceStartFailed", instance); + }; + this.handleInstanceUpdated = (props) => { + const id = this._getInstanceId(props); + const app = this._getInstanceAppName(props); + const instance = this._getInstanceOrThrow(id, app); + this._updateInstanceFromProps(instance, props); + }; + this.onInstanceStarted = (callback) => { + validate(callback, this._configuration()); + return this._registry.add("instanceStarted", callback, this._instances); + }; + this.onInstanceStartFailed = (callback) => { + validate(callback, this._configuration()); + return this._registry.add("instanceStartFailed", callback); + }; + this.onInstanceStopped = (callback) => { + validate(callback, this._configuration()); + return this._registry.add("instanceStopped", callback); + }; + this.onInstanceUpdated = (callback) => { + validate(callback, this._configuration()); + return this._registry.add("instanceChanged", callback); + }; + this.onInstanceAgmServerReady = (callback) => { + validate(callback, this._configuration()); + return this._registry.add("instanceAgmServerReady", callback); + }; + this.onAppAdded = (callback) => { + validate(callback, this._configuration()); + return this._registry.add("appAdded", callback, Object.values(this._apps)); + }; + this.onAppRemoved = (callback) => { + validate(callback, this._configuration()); + return this._registry.add("appRemoved", callback); + }; + this.onAppAvailable = (callback) => { + validate(callback, this._configuration()); + return this._registry.add("appAvailable", callback); + }; + this.onAppUnavailable = (callback) => { + validate(callback, this._configuration()); + return this._registry.add("appUnavailable", callback); + }; + this.onAppChanged = (callback) => { + validate(callback, this._configuration()); + return this._registry.add("appChanged", callback); + }; + } + _getAppOrThrow(id) { + const result = this.application(id); + if (!result) { + throw Error(`app with id ${id} not found`); + } + return result; + } + _getAppId(props) { + return props.Name; + } + _matchInstance(instance, id, appName) { + return instance.id === id && instance.application.name === appName; + } + _getInstanceByIdAndName(id, appName) { + return this._instances.filter((i) => this._matchInstance(i, id, appName))[0]; + } + _getInstanceOrThrow(id, appName) { + const result = this._getInstanceByIdAndName(id, appName); + if (!result) { + throw Error(`instance with id ${id} not found`); + } + return result; + } + _getInstanceId(props) { + return props.Id; + } + _getInstanceAppName(props) { + return props.Name; + } + _updateAppFromProps(props) { + const id = this._getAppId(props); + this._logger.trace(`updating app with + ${id}, ${JSON.stringify(props)}`); + const app = this._getAppOrThrow(id); + app.updateFromProps(props); + return app; + } + _updateInstanceFromProps(instance, props) { + this._logger.trace("updating instance with " + this._getInstanceId(props) + " for app " + this._getInstanceAppName(props)); + instance.updateFromProps(props); + } + } + + function promisify(promise, successCallback, errorCallback) { + const isFunction = (arg) => { + return !!(arg && arg.constructor && arg.call && arg.apply); + }; + if (!isFunction(successCallback) && !isFunction(errorCallback)) { + return promise; + } + if (!isFunction(successCallback)) { + successCallback = () => { + }; + } + else if (!isFunction(errorCallback)) { + errorCallback = () => { + }; + } + return promise.then(successCallback, errorCallback); + } + class EntitlementsImpl { + constructor(_agm) { + this._agm = _agm; + this._registry = CallbackRegistryFactory(); + this._isMethodRegistered = false; + this.handleBranchModified = (branch) => { + this._registry.execute("branchChanged", branch); + }; + this.handleBranchesModified = (branches) => { + this._registry.execute("branchesChanged", branches); + }; + this.getRegion = (success, error) => { + return promisify(this._agmInvoke(GetConfigurationRegionMethodName, (e) => e.returned.Region), success, error); + }; + this.getBranches = (success, error) => { + const promise = this._agmInvoke(GetBranchesMethodName, (e) => { + const obj = e.returned.Branches; + return Object.keys(obj).map((key) => obj[key]); + }); + return promisify(promise, success, error); + }; + this.getCurrentBranch = (success, error) => { + const promise = this._agmInvoke(GetCurrentBranchMethodName, (e) => e.returned.Branch, undefined); + return promisify(promise, success, error); + }; + this.setRegion = (region, success, error) => { + const promise = this._agmInvoke(SetConfigurationRegionMethodName, (e) => e.returned.ResultMessage, { Region: region }); + return promisify(promise, success, error); + }; + this.setCurrentBranch = (branch, success, error) => { + const promise = this._agmInvoke(SetCurrentBranchMethodName, (e) => e.returned.ResultMessage, { Branch: branch }); + return promisify(promise, success, error); + }; + this.currentUser = (success, error) => { + const promise = this._agmInvoke(GetUserMethodName); + return promisify(promise, success, error); + }; + this.getFunctionalEntitlement = (funct, success, error) => { + const promise = this._agmInvoke(GetFunctionalEntitlementMethodName, (e) => e.returned.Entitlement, { Function: funct }); + return promisify(promise, success, error); + }; + this.getFunctionalEntitlementBranch = (funct, branch, success, error) => { + const promise = this._agmInvoke(GetFunctionalEntitlementMethodName, (e) => e.returned.Entitlement, { Function: funct, Branch: branch }); + return promisify(promise, success, error); + }; + this.canI = (func, success, error) => { + const promise = this._agmInvoke(CanIMethodName, (e) => e.returned.Result, { Function: func }); + return promisify(promise, success, error); + }; + this.canIBranch = (func, branch, success, error) => { + const promise = this._agmInvoke(CanIMethodName, (e) => e.returned.Result, { Function: func, Branch: branch }); + return promisify(promise, success, error); + }; + this.onBranchesChanged = (callback) => { + return this._registry.add("branchesChanged", callback); + }; + this.onBranchChanged = (callback) => { + return this._registry.add("branchChanged", callback); + }; + this.exit = (options) => { + return this._agmInvoke(ShutdownMethodName, null, options); + }; + this.onShuttingDown = (callback) => { + this.registerMethod(); + return this._registry.add("onShuttingDown", callback); + }; + this.restart = (options) => { + return this._agmInvoke(RestartMethodName, null, options); + }; + this._agmInvoke = (method, transformFunction, args) => { + args = args || {}; + return new Promise((resolve, reject) => { + const errHandler = (error) => reject(error); + this._agm.invoke(method, args, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }) + .then((result) => { + if (!transformFunction) { + transformFunction = (d) => d.returned; + } + resolve(transformFunction(result)); + }) + .catch(errHandler); + }); + }; + } + registerMethod() { + if (!this._isMethodRegistered) { + this._agm.register(OnGDShutdownMethodName, async (args) => { + try { + const results = await Promise.all(this._registry.execute("onShuttingDown", args)); + const prevent = results.some((r) => r.prevent); + return { prevent }; + } + catch (error) { + } + }); + this._isMethodRegistered = true; + } + } + } + + function snapshot(interop, appManager) { + return new Promise((resolve, reject) => { + interop.invoke(GetApplicationsMethodName, { skipIcon: true }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }) + .then((response) => { + var _a; + const data = response.returned; + const configuration = (_a = response.returned.configuration) !== null && _a !== void 0 ? _a : {}; + if (!data) { + resolve(configuration); + } + const applications = data.applications; + if (!applications) { + resolve(configuration); + } + objectValues(applications).map((item) => appManager.handleAppAdded(item)); + resolve(configuration); + }) + .catch((err) => reject(new Error(`Error getting application snapshot: ${err.message}`))); + }); + } + + const OnBranchChangedEvent = "OnBranchChanged"; + const OnBranchesModifiedEvent = "OnBranchesModified"; + const OnApplicationAddedEvent = "OnApplicationAdded"; + const OnApplicationRemovedEvent = "OnApplicationRemoved"; + const OnApplicationChangedEvent = "OnApplicationChanged"; + const OnApplicationReadyEvent = "OnApplicationReady"; + const OnApplicationStartedEvent = "OnApplicationStarted"; + const OnApplicationAgmServerReadyEvent = "OnApplicationAgmServerReady"; + const OnApplicationUpdatedEvent = "OnApplicationUpdated"; + const OnApplicationStoppedEvent = "OnApplicationStopped"; + const OnApplicationStartFailedEvent = "OnApplicationStartFailed"; + + function createDataSubscription(agm, applications, entitlements, skipIcons) { + let subscription; + let initiated = false; + const start = () => { + let resolveFunc; + let rejectFunc; + const resultPromise = new Promise((resolve, reject) => { + resolveFunc = resolve; + rejectFunc = reject; + }); + agm.subscribe(OnEventMethodName, { arguments: { skipIcon: skipIcons }, waitTimeoutMs: 10000 }) + .then((s) => { + subscription = s; + subscription.onData((streamData) => { + var _a; + const events = streamData.data; + const configuration = (_a = events.configuration) !== null && _a !== void 0 ? _a : {}; + const onApplicationAddedEventArgs = objectValues(events[OnApplicationAddedEvent]); + if (streamData.data.isSnapshot) { + applications.handleSnapshotAppsAdded(onApplicationAddedEventArgs); + } + else { + onApplicationAddedEventArgs.forEach((item) => applications.handleAppAdded(item)); + } + objectValues(events[OnApplicationChangedEvent]) + .forEach((item) => applications.handleAppUpdated(item)); + objectValues(events[OnApplicationRemovedEvent]) + .forEach((item) => applications.handleAppRemoved(item)); + objectValues(events[OnApplicationReadyEvent]) + .forEach((item) => applications.handleAppReady(item)); + const onApplicationStartedEventArgs = objectValues(events[OnApplicationStartedEvent]); + if (streamData.data.isSnapshot) { + applications.handleSnapshotInstanceStarted(onApplicationStartedEventArgs); + } + else { + onApplicationStartedEventArgs.forEach((item) => applications.handleInstanceStarted(item)); + } + objectValues(events[OnApplicationStartFailedEvent]) + .forEach((item) => applications.handleInstanceStartFailed(item)); + objectValues(events[OnApplicationStoppedEvent]) + .forEach((item) => applications.handleInstanceStopped(item)); + objectValues(events[OnApplicationUpdatedEvent]) + .forEach((item) => applications.handleInstanceUpdated(item)); + objectValues(events[OnApplicationAgmServerReadyEvent]) + .forEach((item) => applications.handleInstanceAgmServerReady(item)); + objectValues(events[OnBranchChangedEvent]) + .forEach((item) => entitlements.handleBranchModified(item)); + objectValues(events[OnBranchesModifiedEvent]) + .forEach((item) => entitlements.handleBranchesModified(item)); + if (!initiated) { + initiated = true; + const hasMyAppInSnapShot = onApplicationAddedEventArgs.some((a) => a.Name === agm.instance.application); + const hasMyInstanceInSnapShot = onApplicationStartedEventArgs.some((i) => i.Id === agm.instance.instance); + if (hasMyAppInSnapShot) { + if (hasMyInstanceInSnapShot) { + resolveFunc(configuration); + } + else { + const un = applications.onInstanceStarted((i) => { + if (i.id === agm.instance.instance) { + un(); + resolveFunc(configuration); + } + }); + } + } + else { + resolveFunc(configuration); + } + } + }); + subscription.onFailed((err) => rejectFunc(err)); + }) + .catch((err) => { var _a; return rejectFunc(`Error subscribing for ${OnEventMethodName} stream. Err: ${(_a = err.message) !== null && _a !== void 0 ? _a : JSON.stringify(err)}`); }); + return resultPromise; + }; + const stop = () => { + if (subscription) { + subscription.close(); + } + }; + return { + start, + stop + }; + } + + const InMemoryStoreCommandMethodName = "T42.ACS.InMemoryStoreCommand"; + class InMemoryStore { + constructor(interop) { + this.interop = interop; + } + import(apps, mode) { + if (!apps || !Array.isArray(apps)) { + return Promise.reject(new Error("invalid apps argument - should be an array of application definitions")); + } + if (mode && mode !== "replace" && mode !== "merge") { + return Promise.reject(new Error("invalid mode argument - should be 'replace' or 'merge'")); + } + mode = mode !== null && mode !== void 0 ? mode : "replace"; + const command = { + command: "import", + args: { + apps, + mode + } + }; + return this.interop.invoke(InMemoryStoreCommandMethodName, command, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }) + .then((r) => r.returned); + } + export() { + return this.interop.invoke(InMemoryStoreCommandMethodName, { command: "export" }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }) + .then((r) => r.returned.apps); + } + remove(app) { + if (!app || typeof app !== "string") { + return Promise.reject(new Error("invalid app name, should be a string value")); + } + const command = { + command: "remove", + args: { + apps: [app] + } + }; + return this.interop.invoke(InMemoryStoreCommandMethodName, command, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }).then((r) => r.returned); + } + clear() { + const command = { + command: "clear" + }; + return this.interop.invoke(InMemoryStoreCommandMethodName, command, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }).then((r) => r.returned); + } + createAppDef(name, url) { + if (!url) { + url = "https://google.com"; + } + return { + name, + type: "window", + title: name, + details: { + url + } + }; + } + } + + var AppManagerFactory = (config) => { + if (!config) { + throw Error("config not set"); + } + if (!config.agm) { + throw Error("config.agm is missing"); + } + const START_ONLY = "startOnly"; + const SKIP_ICONS = "skipIcons"; + const FULL = "full"; + const mode = config.mode || START_ONLY; + if (mode !== START_ONLY && mode !== SKIP_ICONS && mode !== FULL) { + throw new Error(`Invalid mode for appManager lib - ${mode} is not supported`); + } + const activities = config.activities; + const agm = config.agm; + const logger = config.logger; + const windows = config.windows; + let configuration = {}; + const appManager = new AppManagerImpl(mode, agm, activities, windows, logger.subLogger("applications"), config.gdMajorVersion, () => configuration); + const entitlements = new EntitlementsImpl(agm); + let readyPromise; + if (mode === START_ONLY) { + readyPromise = snapshot(agm, appManager); + } + else { + const subscription = createDataSubscription(agm, appManager, entitlements, mode === SKIP_ICONS); + readyPromise = subscription.start(); + } + const api = { + ready: () => readyPromise.then((c) => { configuration = c; }), + applications: appManager.applications, + application: appManager.application, + getConfigurations: appManager.getConfigurations, + onAppAdded: appManager.onAppAdded, + onAppRemoved: appManager.onAppRemoved, + onAppChanged: appManager.onAppChanged, + onAppAvailable: appManager.onAppAvailable, + onAppUnavailable: appManager.onAppUnavailable, + instances: appManager.instances, + get myInstance() { + return appManager.getMyInstance(); + }, + get myApplication() { + return appManager.getMyApplication(); + }, + onInstanceStarted: appManager.onInstanceStarted, + onInstanceStopped: appManager.onInstanceStopped, + onInstanceUpdated: appManager.onInstanceUpdated, + onInstanceStartFailed: appManager.onInstanceStartFailed, + getRegion: entitlements.getRegion, + getBranches: entitlements.getBranches, + getCurrentBranch: entitlements.getCurrentBranch, + getFunctionalEntitlement: entitlements.getFunctionalEntitlement, + getFunctionalEntitlementBranch: entitlements.getFunctionalEntitlementBranch, + setCurrentBranch: entitlements.setCurrentBranch, + setRegion: entitlements.setRegion, + currentUser: entitlements.currentUser, + canI: entitlements.canI, + canIBranch: entitlements.canIBranch, + onBranchesChanged: entitlements.onBranchesChanged, + exit: entitlements.exit, + restart: entitlements.restart, + onShuttingDown: entitlements.onShuttingDown, + inMemory: new InMemoryStore(agm) + }; + return api; + }; + + const T42JumpListAction = "T42.JumpList.Action"; + class JumpListManager { + constructor() { + this._groupActionCallbacks = new Map(); + this._registered = false; + } + init(executor, agm, logger) { + this._executor = executor; + this._agm = agm; + this._logger = logger; + this.registerCallbackMethod(); + } + setEnabled(windowId, enabled) { + const settings = { + enabled + }; + return this._executor.updateJumpList(windowId, settings); + } + createCategory(windowId, title, actions) { + this.validateActions(title, actions); + const settings = { + category: { + title, + operation: "create", + actions: this.toUpdateActions(windowId, "create", title, actions) + } + }; + return this._executor.updateJumpList(windowId, settings); + } + removeCategory(windowId, title) { + const settings = { + category: { + title, + operation: "remove", + actions: [] + } + }; + this.manageActionCallback(windowId, settings.category.operation, title); + return this._executor.updateJumpList(windowId, settings); + } + createActions(windowId, categoryTitle, actions) { + this.validateActions(categoryTitle, actions); + const settings = { + category: { + title: categoryTitle, + operation: "update", + actions: this.toUpdateActions(windowId, "create", categoryTitle, actions) + } + }; + return this._executor.updateJumpList(windowId, settings); + } + removeActions(windowId, categoryTitle, actions) { + const settings = { + category: { + title: categoryTitle, + operation: "update", + actions: this.toUpdateActions(windowId, "remove", categoryTitle, actions) + } + }; + return this._executor.updateJumpList(windowId, settings); + } + async getActions(windowId, catgoryTitle) { + const actions = []; + const configuration = await this.getJumpListSettings(windowId); + const currentCategory = configuration.categories.find((category) => category.title === catgoryTitle); + if (currentCategory) { + currentCategory.actions.forEach((action) => { + const actionCallback = this.getActionCallback(action.callbackId); + if (actionCallback) { + action.callback = actionCallback.callback; + } + actions.push({ + icon: action.icon, + callback: action.callback, + singleInstanceTitle: action.singleInstanceTitle, + multiInstanceTitle: action.multiInstanceTitle + }); + }); + } + return Promise.resolve(actions); + } + getJumpListSettings(windowId) { + return this._executor.getJumpList(windowId); + } + toUpdateActions(windowId, operation, categoryTitle, actions) { + return actions.map((action) => { + const updateAction = { + icon: action.icon, + callback: action.callback, + callbackId: Utils.generateId(), + singleInstanceTitle: action.singleInstanceTitle, + multiInstanceTitle: action.multiInstanceTitle, + operation + }; + this.manageActionCallback(windowId, operation, categoryTitle, updateAction); + return updateAction; + }); + } + manageActionCallback(windowId, operation, categoryTitle, updateAction) { + var _a; + const groupCallbacksKey = `${categoryTitle}-${windowId}`; + if (operation === "create") { + if (!this._groupActionCallbacks.has(groupCallbacksKey)) { + this._groupActionCallbacks.set(groupCallbacksKey, []); + } + const categoryActionCallbacks = this._groupActionCallbacks.get(groupCallbacksKey); + categoryActionCallbacks.push({ + callbackId: updateAction.callbackId, + callback: updateAction.callback + }); + } + else if (operation === "remove") { + if (updateAction) { + let categoryActionCallbacks = (_a = this._groupActionCallbacks.get(groupCallbacksKey)) !== null && _a !== void 0 ? _a : []; + categoryActionCallbacks = categoryActionCallbacks.filter((accCal) => accCal.callbackId !== updateAction.callbackId); + if (categoryActionCallbacks.length === 0) { + this._groupActionCallbacks.delete(groupCallbacksKey); + } + else { + this._groupActionCallbacks.set(groupCallbacksKey, categoryActionCallbacks); + } + } + else { + this._groupActionCallbacks.delete(groupCallbacksKey); + } + } + } + registerCallbackMethod() { + if (this._registered) { + return; + } + this._registered = true; + try { + this._agm.register(T42JumpListAction, (args, caller) => { + const actionCallback = this.getActionCallback(args.callbackId); + if (actionCallback) { + try { + actionCallback.callback(); + } + catch (e) { + this._logger.error("Unable to execute user callback for jump list action!", e); + } + } + }); + } + catch (e) { + this._logger.error(`Unable to register method ${T42JumpListAction} for invoking jump list action callbacks!`, e); + return Promise.reject(e); + } + } + getActionCallback(callbackId) { + let callbackAction; + [...this._groupActionCallbacks.values()].forEach((callbacks) => { + const callback = callbacks.find((cal) => cal.callbackId === callbackId); + if (callback) { + callbackAction = callback; + } + }); + return callbackAction; + } + validateActions(category, actions) { + if (!(actions && actions.length > 0)) { + throw new Error(`Category '${category}' doesn't contain any actions!`); + } + actions.forEach((action) => { + if (!action.singleInstanceTitle) { + throw new Error(`Category '${category}' contains an action with undefined singleInstanceTitle!`); + } + if (!action.multiInstanceTitle) { + throw new Error(`Category '${category}' contains an action with undefined multiInstanceTitle!`); + } + if (!action.callback) { + throw new Error(`Category '${category}' contains an action with undefined callback function!`); + } + }); + } + } + var jumpListManager = new JumpListManager(); + + class WindowStore { + constructor() { + this.waitForTimeoutInMilliseconds = 60000; + this._windows = {}; + this._pendingWindows = {}; + this._pendingWindowsStates = {}; + this._registry = CallbackRegistryFactory(); + } + init(logger) { + this._logger = logger; + } + get(id) { + return this._windows[id] || this._pendingWindows[id]; + } + getIfReady(id) { + return this._windows[id]; + } + get list() { + return this._windows; + } + add(window, state) { + const isExist = typeof this._pendingWindows[window.API.id] !== "undefined"; + if (isExist) { + this._logger.error(`trying to add window with id ${window.API.id} from windowStore, which already exists`); + return; + } + this._pendingWindows[window.API.id] = window; + this._pendingWindowsStates[window.API.id] = state; + this._registry.execute("on-added", window); + if (this.shouldMarkReadyToShow(state)) { + this.markReadyToShow(window.API.id); + } + } + remove(window) { + delete this._windows[window.API.id]; + delete this._pendingWindows[window.API.id]; + delete this._pendingWindowsStates[window.API.id]; + this._registry.execute("on-removed", window); + } + setUrlChangedState(windowId) { + const targetWindowState = this._pendingWindowsStates[windowId]; + if (typeof targetWindowState === "undefined") { + return; + } + targetWindowState.urlChanged = true; + if (this.shouldMarkReadyToShow(targetWindowState)) { + this.markReadyToShow(windowId); + } + } + setCompositionChangedState(wrapper) { + const windowId = wrapper.API.id; + const targetWindowState = this._pendingWindowsStates[windowId]; + if (typeof targetWindowState === "undefined") { + return; + } + targetWindowState.compositionChanged = true; + if (this.shouldMarkReadyToShow(targetWindowState)) { + this.markReadyToShow(windowId); + } + } + waitFor(id) { + return new Promise((resolve, reject) => { + let unReady; + let unRemoved; + const timeout = setTimeout(() => { + unReady(); + unRemoved(); + reject(new Error(`Window with id "${id}" was not ready within ${this.waitForTimeoutInMilliseconds} milliseconds.`)); + }, this.waitForTimeoutInMilliseconds); + const win = this._windows[id]; + if (win) { + clearTimeout(timeout); + resolve(win); + } + else { + const cleanup = () => { + clearTimeout(timeout); + unReady(); + unRemoved(); + }; + unReady = this.onReadyWindow((w) => { + if (w.API.id !== id) { + return; + } + cleanup(); + resolve(w); + }); + unRemoved = this.onRemoved((w) => { + if (w.API.id !== id) { + return; + } + cleanup(); + reject(new Error(`Window with id "${id}" was closed before it became ready.`)); + }); + } + }); + } + onReadyWindow(callback) { + return this._registry.add("on-ready", callback); + } + onAdded(callback) { + return this._registry.add("on-added", callback); + } + onRemoved(callback) { + return this._registry.add("on-removed", callback); + } + markReadyToShow(windowId) { + if (this._pendingWindows[windowId]) { + this._windows[windowId] = this._pendingWindows[windowId]; + delete this._pendingWindows[windowId]; + delete this._pendingWindowsStates[windowId]; + } + this._registry.execute("on-ready", this._windows[windowId]); + } + shouldMarkReadyToShow(targetWindowState) { + return targetWindowState && targetWindowState.urlChanged && targetWindowState.ready && targetWindowState.compositionChanged; + } + } + var windowStore = new WindowStore(); + + class JumpListActions { + constructor(windowId, configuration) { + this.windowId = windowId; + this._categoryTitle = configuration.title; + } + list() { + return jumpListManager.getActions(this.windowId, this._categoryTitle); + } + create(actions) { + return jumpListManager.createActions(this.windowId, this._categoryTitle, actions); + } + remove(actions) { + return jumpListManager.removeActions(this.windowId, this._categoryTitle, actions); + } + } + + class JumpListCategories { + constructor(windowId) { + this.windowId = windowId; + } + list() { + return this.getCategories(); + } + create(title, actions) { + return jumpListManager.createCategory(this.windowId, title, actions); + } + remove(title) { + return jumpListManager.removeCategory(this.windowId, title); + } + async find(title) { + const categories = await this.getCategories(); + return categories.find((cat) => cat.title === title); + } + async getCategories() { + const result = []; + const configuration = await jumpListManager.getJumpListSettings(this.windowId); + configuration.categories.forEach((category) => { + result.push({ + title: category.title, + actions: new JumpListActions(this.windowId, category) + }); + }); + return result; + } + } + + class JumpList { + constructor(windowId) { + this.windowId = windowId; + this._categories = new JumpListCategories(windowId); + } + get categories() { + return this._categories; + } + async isEnabled() { + const configuration = await jumpListManager.getJumpListSettings(this.windowId); + return configuration.enabled; + } + setEnabled(enabled) { + return jumpListManager.setEnabled(this.windowId, enabled); + } + } + + var windowFactory = (id, options, executor, logger, appManagerGetter, displayAPIGetter, channelsAPIGetter, agm) => { + var _a, _b, _c, _d; + const _registry = CallbackRegistryFactory(); + const getChannels = () => { + const channels = channelsAPIGetter(); + if (!channels) { + throw new Error(`To use this method you need to enable channels API - set the channels property to true when initializing the Glue42 library`); + } + return channels; + }; + const _id = id; + const _name = options.name; + const _mode = options.mode; + let _bounds = options.bounds; + let _url = options.url; + let _title = options.title; + let _context = (_a = options.context) !== null && _a !== void 0 ? _a : {}; + let _frameColor = options.frameColor; + let _focus = options.focus; + let _neighbours = (_b = options.neighbours) !== null && _b !== void 0 ? _b : {}; + let _groupId = options.groupId; + let _isGroupHeaderVisible = options.isGroupHeaderVisible; + let _isTabHeaderVisible = options.isTabHeaderVisible; + let _isGroupHibernated = options.isGroupHibernated; + let _isGroupVisible = options.isGroupVisible; + let _isTabSelected = (_c = options.isTabSelected) !== null && _c !== void 0 ? _c : false; + let _settings = options.settings; + const _applicationName = options.applicationName; + let _isVisible = options.isVisible; + let _isSticky = options.isSticky; + let _isCollapsed = options.isCollapsed; + let _windowState = options.state; + let _tabGroupId = options.tabGroupId; + let _tabIndex = options.tabIndex; + let _frameId = options.frameId; + let _isLocked = options.isLocked; + let _allowWorkspaceDrop = options.allowWorkspaceDrop; + let _isPinned = options.isPinned; + let _group; + let _frameButtons = (_d = options.frameButtons) !== null && _d !== void 0 ? _d : []; + let _zoomFactor = options.zoomFactor; + let _placementSettings = options.placementSettings; + const _jumpList = new JumpList(id); + function close(cbOrOptions, error) { + if (typeof cbOrOptions === "undefined" || typeof cbOrOptions === "function") { + return Utils.callbackifyPromise(() => { + if (!id) { + throw new Error("The window is already closed."); + } + return executor.close(resultWindow); + }, cbOrOptions, error); + } + else { + return executor.close(resultWindow, cbOrOptions); + } + } + function navigate(newUrl, optionsOrCallback, error) { + if (typeof optionsOrCallback === "function") { + return Utils.callbackifyPromise(() => { + if (isNullOrWhiteSpace(newUrl)) { + throw new Error("The new URL must be a non-empty string."); + } + return executor.navigate(resultWindow, newUrl); + }, optionsOrCallback, error); + } + if (isNullOrWhiteSpace(newUrl)) { + throw new Error("The new URL must be a non-empty string."); + } + if ((optionsOrCallback === null || optionsOrCallback === void 0 ? void 0 : optionsOrCallback.timeout) && typeof optionsOrCallback.timeout !== "number") { + throw new Error("Timeout argument must be a valid number"); + } + return executor.navigate(resultWindow, newUrl, optionsOrCallback); + } + function setStyle(style, success, error) { + return Utils.callbackifyPromise(() => { + if (!style || Object.keys(style).length === 0 || Object.keys(style).every((key) => !key)) { + throw new Error("Invalid style arguments: " + JSON.stringify(style)); + } + if (style && style.focus !== undefined) { + if (typeof style.focus !== "boolean") { + throw new Error("Focus must be a boolean value. Currently, only `focus: true` is supported."); + } + else if (style.focus === false) { + console.warn("`focus: false` is not supported!"); + } + } + if (style && style.hidden !== undefined && typeof style.hidden !== "boolean") { + throw new Error("The `hidden` property must hold a boolean value."); + } + for (const prop of ["minHeight", "maxHeight", "minWidth", "maxWidth"]) { + const styleAsAny = style; + const value = styleAsAny[prop]; + if (prop in style) { + if (isUndefinedOrNull(value)) { + delete styleAsAny[prop]; + continue; + } + if (!isNumber(styleAsAny[prop])) { + throw new Error(`"${prop}" must be a number`); + } + } + } + return executor.setStyle(resultWindow, style); + }, success, error); + } + function resetButtons(buttons, success, error) { + return Utils.callbackifyPromise(() => executor.resetButtons(resultWindow, buttons), success, error); + } + function getButtons() { + return executor.getButtons(resultWindow); + } + function setOnTop(onTop, success, error) { + return Utils.callbackifyPromise(() => { + if (typeof onTop === "string") { + if (onTop !== "always") { + throw new Error("`onTop` must hold a `always` value."); + } + } + else if (typeof onTop !== "boolean") { + throw new Error("`onTop` must hold a boolean or `always` value."); + } + return executor.setOnTop(resultWindow, onTop); + }, success, error); + } + function setSizeConstraints(constraints, success, error) { + return Utils.callbackifyPromise(() => { + if (!constraints || Object.keys(constraints).every((value) => value === undefined)) { + throw new Error("The properties of `constraints` cannot be null or undefined."); + } + return executor.setSizeConstraints(resultWindow, constraints); + }, success, error); + } + function getSizeConstraints() { + return executor.getSizeConstraints(resultWindow); + } + function setTitle(newTitle, success, error) { + return Utils.callbackifyPromise(() => { + if (isUndefinedOrNull(newTitle)) { + throw new Error("`newTitle` must not be null or undefined."); + } + if (newTitle === _title) { + return Promise.resolve(resultWindow); + } + return executor.setTitle(resultWindow, newTitle); + }, success, error); + } + function setSticky(isSticky, success, error) { + return Utils.callbackifyPromise(() => { + if (typeof isSticky !== "boolean") { + throw new Error("`isSticky` must hold a boolean value."); + } + return executor.setSticky(resultWindow, isSticky); + }, success, error); + } + function setAllowWorkspaceDrop(allowWorkspaceDrop) { + if (typeof allowWorkspaceDrop !== "boolean") { + throw new Error("`allowWorkspaceDrop` must hold a boolean value."); + } + return executor.setAllowWorkspaceDrop(resultWindow, allowWorkspaceDrop); + } + function pin() { + return executor.pin(resultWindow); + } + function unpin() { + return executor.unpin(resultWindow); + } + function moveResize(bounds, success, error) { + return Utils.callbackifyPromise(() => { + if (isUndefinedOrNull(bounds)) { + throw new Error("The properties of `bounds` cannot be null or undefined."); + } + return executor.moveResize(resultWindow, bounds); + }, success, error); + } + function addFrameButton(buttonInfo, success, error) { + return Utils.callbackifyPromise(() => { + if (typeof buttonInfo === "undefined" || Object.keys(buttonInfo).length === 0) { + throw new Error("Button info is not available."); + } + if (isNullOrWhiteSpace(buttonInfo.buttonId)) { + throw new Error("`buttonId` must not be null or undefined."); + } + if (isNullOrWhiteSpace(buttonInfo.imageBase64)) { + throw new Error("`imageBase64` must not be null or undefined."); + } + return executor.addFrameButton(resultWindow, buttonInfo); + }, success, error); + } + function removeFrameButton(buttonId, success, error) { + return Utils.callbackifyPromise(() => { + if (isNullOrWhiteSpace(buttonId)) { + throw new Error("`buttonId` must not be null or undefined."); + } + return executor.removeFrameButton(resultWindow, buttonId); + }, success, error); + } + function activate(success, error) { + return Utils.callbackifyPromise(() => { + if (_focus) { + return Promise.resolve(resultWindow); + } + return executor.activate(resultWindow); + }, success, error); + } + function focus(success, error) { + return Utils.callbackifyPromise(() => { + if (_focus) { + return Promise.resolve(resultWindow); + } + return executor.focus(resultWindow); + }, success, error); + } + function maximizeRestore(success, error) { + return Utils.callbackifyPromise(() => { + return executor.maximizeRestore(resultWindow); + }, success, error); + } + function maximize(success, error) { + return Utils.callbackifyPromise(() => { + if (_windowState === "maximized") { + return Promise.resolve(resultWindow); + } + return executor.maximize(resultWindow); + }, success, error); + } + function restore(success, error) { + return Utils.callbackifyPromise(() => { + if (_windowState === "normal") { + return Promise.resolve(resultWindow); + } + return executor.restore(resultWindow); + }, success, error); + } + function minimize(success, error) { + return Utils.callbackifyPromise(() => { + if (_windowState === "minimized") { + return Promise.resolve(resultWindow); + } + return executor.minimize(resultWindow); + }, success, error); + } + function collapse(success, error) { + return Utils.callbackifyPromise(() => { + if (_isCollapsed) { + return Promise.resolve(resultWindow); + } + return executor.collapse(resultWindow); + }, success, error); + } + function expand(success, error) { + return Utils.callbackifyPromise(() => { + if (!_isCollapsed) { + return Promise.resolve(resultWindow); + } + return executor.expand(resultWindow); + }, success, error); + } + function toggleCollapse(success, error) { + return Utils.callbackifyPromise(() => { + return executor.toggleCollapse(resultWindow); + }, success, error); + } + function snap(target, direction, success, error) { + return Utils.callbackifyPromise(() => { + if (isUndefinedOrNull(target)) { + throw new Error(`A target window is not specified - ${typeof target === "string" ? target : JSON.stringify(target)}`); + } + if (typeof target === "string") { + const win = windowStore.get(target); + if (!win) { + throw new Error(`Invalid "target" parameter or no such window. Invoked with: ${target}`); + } + target = win.API; + } + if (typeof direction === "string") { + direction = { + direction, + autoAlign: true + }; + } + return executor.snap(resultWindow, target, direction); + }, success, error); + } + function attachTab(tab, opt, success, error) { + return Utils.callbackifyPromise(() => { + var _a; + const errorMessage = `Invalid "tab" parameter - must be an object with an "id" property or a string. Invoked for source window with ID:`; + if (isUndefinedOrNull(tab)) { + const errMsg = `${errorMessage} ${typeof tab === "string" ? tab : JSON.stringify(tab)}`; + throw new Error(errMsg); + } + let sourceWindow; + if (typeof tab === "string") { + sourceWindow = (_a = windowStore.get(tab)) === null || _a === void 0 ? void 0 : _a.API; + if (isUndefinedOrNull(sourceWindow)) { + const errMsg = `${errorMessage} ${typeof sourceWindow === "string" ? sourceWindow : JSON.stringify(sourceWindow)}`; + throw new Error(errMsg); + } + } + else if (!isUndefinedOrNull(tab.id)) { + sourceWindow = tab; + } + else { + throw new Error(errorMessage); + } + const attachOptions = {}; + if (!isUndefinedOrNull(opt)) { + if (typeof opt === "number") { + attachOptions.index = opt; + } + else { + attachOptions.selected = opt.selected; + attachOptions.index = opt.index; + } + } + return executor.attachTab(resultWindow, sourceWindow, attachOptions); + }, success, error); + } + function detachTab(opt = {}, success, error) { + return Utils.callbackifyPromise(() => { + const argsForSend = {}; + function isDetachRelative(o) { + return o.relativeTo !== undefined; + } + if (isDetachRelative(opt)) { + if (typeof opt.relativeTo === "string") { + argsForSend.relativeTo = opt.relativeTo; + } + else if (!isUndefinedOrNull(opt.relativeTo.id)) { + argsForSend.relativeTo = opt.relativeTo.id; + } + if (!isUndefinedOrNull(opt.relativeDirection)) { + argsForSend.relativeDirection = opt.relativeDirection; + } + if (!isUndefinedOrNull(opt.width)) { + argsForSend.width = opt.width; + } + if (!isUndefinedOrNull(opt.height)) { + argsForSend.height = opt.height; + } + } + else { + if (!isUndefinedOrNull(opt.bounds)) { + argsForSend.bounds = opt.bounds; + } + } + if (!isUndefinedOrNull(opt.hideTabHeader)) { + argsForSend.hideTabHeader = opt.hideTabHeader; + } + return executor.detachTab(resultWindow, argsForSend); + }, success, error); + } + function setVisible(toBeVisible, success, error) { + return Utils.callbackifyPromise(() => { + return executor.setVisible(resultWindow, toBeVisible); + }, success, error); + } + async function center(display) { + if (display) { + validateCenterArguments(display); + } + return executor.center(resultWindow, display); + } + function validateCenterArguments(display) { + if (typeof display !== "object") { + throw Error("display argument must be a valid display object"); + } + if (!display.workArea || !display.scaleFactor) { + throw Error("display argument is not a valid display object"); + } + } + function showLoader(loader) { + return executor.showLoader(resultWindow, loader); + } + function hideLoader() { + return executor.hideLoader(resultWindow); + } + function updateContext(context, success, error) { + return Utils.callbackifyPromise(() => { + if (!isObject(context)) { + throw new Error(`"context" must not be null or undefined.`); + } + return executor.updateContext(resultWindow, context, false); + }, success, error); + } + function lock(success, error) { + return Utils.callbackifyPromise(() => { + return executor.lock(resultWindow); + }, success, error); + } + function unlock(success, error) { + return Utils.callbackifyPromise(() => { + return executor.unlock(resultWindow); + }, success, error); + } + function getIcon(success, error) { + return Utils.callbackifyPromise(() => { + return executor.getIcon(resultWindow); + }, success, error); + } + function setIcon(base64Image, success, error) { + return Utils.callbackifyPromise(() => { + if (isNullOrWhiteSpace(base64Image)) { + throw new Error(`"base64Image" must be a non-empty string.`); + } + return executor.setIcon(resultWindow, base64Image); + }, success, error); + } + function setFrameColor(frameColor, success, error) { + return Utils.callbackifyPromise(() => { + if (isNullOrWhiteSpace(frameColor)) { + throw new Error(`"frameColor" must be a non-empty string`); + } + return executor.setFrameColor(resultWindow, frameColor); + }, success, error); + } + function setTabHeaderVisible(toBeTabHeaderVisible, success, error) { + return Utils.callbackifyPromise(() => { + if (typeof toBeTabHeaderVisible !== "boolean") { + throw new Error(`"toBeTabHeaderVisible" must hold a boolean value.`); + } + return executor.setTabHeaderVisible(resultWindow, toBeTabHeaderVisible); + }, success, error); + } + async function setTabTooltip(tooltip) { + if (isNullOrWhiteSpace(tooltip)) { + throw new Error(`"${tooltip}" must not be null or undefined`); + } + return executor.setTabTooltip(resultWindow, tooltip); + } + async function getTabTooltip() { + return executor.getTabTooltip(resultWindow); + } + function showPopup(config) { + return executor.showPopup(resultWindow, config); + } + function createFlydown(config) { + return executor.createFlydown(resultWindow.id, config); + } + function setModalState(isModal) { + return executor.setModalState(resultWindow.id, isModal || false); + } + function zoomIn(success, error) { + return Utils.callbackifyPromise(() => { + return executor.zoomIn(resultWindow); + }, success, error); + } + function zoomOut(success, error) { + return Utils.callbackifyPromise(() => { + return executor.zoomOut(resultWindow); + }, success, error); + } + function setZoomFactor(zoomFactor, success, error) { + return Utils.callbackifyPromise(() => { + if (isNaN(zoomFactor)) { + throw new Error(`zoomFactor is not a number`); + } + return executor.setZoomFactor(resultWindow, zoomFactor); + }, success, error); + } + function showDevTools() { + return executor.showDevTools(resultWindow); + } + function capture(captureOptions) { + return executor.capture(resultWindow, captureOptions); + } + function flash(suppliedOptions, mode) { + const flashOptions = { + shouldFlash: true, + mode: "auto" + }; + if (typeof suppliedOptions === "boolean") { + flashOptions.shouldFlash = suppliedOptions; + } + if (typeof mode !== "undefined") { + flashOptions.mode = mode; + } + return executor.flash(resultWindow, flashOptions); + } + function flashTab(suppliedOptions) { + const flashOptions = { + shouldFlash: true, + }; + if (typeof suppliedOptions === "boolean") { + flashOptions.shouldFlash = suppliedOptions; + } + return executor.flashTab(resultWindow, flashOptions); + } + function print(printOptions) { + return executor.print(resultWindow, printOptions); + } + function printToPDF(printToPDFOptions) { + return executor.printToPDF(resultWindow, printToPDFOptions); + } + function ungroup(ungroupOptions) { + return new Promise((resolve, reject) => { + const unGroupChanged = onGroupChanged((win, newGroup, oldGroup) => { + if (id === win.id) { + unGroupChanged(); + resolve(resultWindow); + } + }); + executor.ungroup(resultWindow, ungroupOptions) + .catch((e) => { + unGroupChanged(); + reject(e); + }); + }); + } + function place(placementSettings) { + return executor.place(resultWindow, placementSettings); + } + function refresh(ignoreCache) { + return executor.refresh(resultWindow, ignoreCache); + } + function download(url, opts) { + return executor.download(resultWindow, url, opts); + } + function configure(settings) { + return executor.configureWindow(resultWindow, settings); + } + function getConfiguration() { + return executor.getWindowConfiguration(resultWindow); + } + function getDockingPlacement() { + return executor.getDockingPlacement(resultWindow); + } + function dock(opts) { + return executor.dock(resultWindow, opts); + } + async function clone(cloneOptions) { + return executor.clone(resultWindow, cloneOptions); + } + async function executeCode(code) { + if (!code) { + throw new Error("Code argument is missing"); + } + if (typeof code !== "string") { + throw new Error("Code argument must be a valid string"); + } + const response = await executor.executeCode(resultWindow, code); + return response.result; + } + function onTitleChanged(callback) { + if (!isFunction(callback)) { + throw new Error("callback should be a function"); + } + callback(resultWindow.title, resultWindow); + return onEventCore("onTitleChanged", callback); + } + function onClose(callback) { + if (!isFunction(callback)) { + throw new Error("callback should be a function"); + } + if (id === undefined) { + callback(resultWindow); + } + return _registry.add("onClose", callback); + } + function onUrlChanged(callback) { + return onEventCore("onUrlChanged", callback); + } + function onFrameButtonAdded(callback) { + return onEventCore("onFrameButtonAdded", callback); + } + function onFrameButtonRemoved(callback) { + return onEventCore("onFrameButtonRemoved", callback); + } + function onFrameButtonClicked(callback) { + return onEventCore("onFrameButtonClicked", callback); + } + function onCollapsed(callback) { + if (!isFunction(callback)) { + throw new Error("callback should be a function"); + } + if (_isCollapsed) { + callback(resultWindow); + } + return _registry.add("collapsed", callback); + } + function onExpanded(callback) { + if (!isFunction(callback)) { + throw new Error("callback should be a function"); + } + if (!_isCollapsed) { + callback(resultWindow); + } + return _registry.add("expanded", callback); + } + function onMaximized(callback) { + if (_windowState === "maximized") { + return onEventCore("maximized", callback, [resultWindow]); + } + else { + return onEventCore("maximized", callback); + } + } + function onMinimized(callback) { + if (_windowState === "minimized") { + return onEventCore("minimized", callback, [resultWindow]); + } + else { + return onEventCore("minimized", callback); + } + } + function onNormal(callback) { + if (_windowState === "normal") { + return onEventCore("normal", callback, [resultWindow]); + } + else { + return onEventCore("normal", callback); + } + } + function onAttached(callback) { + return onEventCore("attached", callback); + } + function onDetached(callback) { + return onEventCore("detached", callback); + } + function onVisibilityChanged(callback) { + return onEventCore("visibility-changed", callback); + } + function onContextUpdated(callback) { + return onEventCore("context-updated", callback); + } + function onLockingChanged(callback) { + return onEventCore("lock-changed", callback); + } + function onBoundsChanged(callback) { + return onEventCore("bounds-changed", callback); + } + function onFocusChanged(callback) { + return onEventCore("focus-changed", callback); + } + function onStickyChanged(callback) { + return onEventCore("sticky-changed", callback); + } + function onFrameColorChanged(callback) { + return onEventCore("frame-color-changed", callback); + } + function onTabHeaderVisibilityChanged(callback) { + return onEventCore("tab-header-visibility-changed", callback); + } + function onWindowAttached(callback) { + return onEventCore("window-attached", callback); + } + function onWindowDetached(callback) { + return onEventCore("window-detached", callback); + } + function onGroupChanged(callback) { + return onEventCore("group-changed", callback); + } + function onTabSelectionChanged(callback) { + return onEventCore("tab-selection-changed", callback); + } + function onChannelRestrictionsChanged(callback) { + if (!isFunction(callback)) { + throw new Error("callback must be a function"); + } + return onEventCore("channel-restrictions-changed", callback); + } + function onClosing(callback) { + if (!isFunction(callback)) { + throw new Error("callback must be a function"); + } + const callbackWrap = (success, error, prevent) => { + const promise = callback(prevent); + if (promise === null || promise === void 0 ? void 0 : promise.then) { + promise.then(success).catch(error); + } + else { + success(); + } + }; + return executor.onClosing(callbackWrap, resultWindow); + } + function onRefreshing(callback) { + if (!isFunction(callback)) { + throw new Error("callback must be a function"); + } + const callbackWrap = (success, error, prevent) => { + const promise = callback(prevent); + if (promise === null || promise === void 0 ? void 0 : promise.then) { + promise.then(success).catch(error); + } + else { + success(); + } + }; + return executor.onRefreshing(callbackWrap, resultWindow); + } + function onNavigating(callback) { + if (!isFunction(callback)) { + throw new Error("callback must be a function"); + } + const callbackWrap = (success, error, prevent, args) => { + const promise = callback(args); + if (promise === null || promise === void 0 ? void 0 : promise.then) { + promise.then(success).catch(error); + } + else { + success(); + } + }; + return executor.onNavigating(callbackWrap, resultWindow); + } + function onZoomFactorChanged(callback) { + return onEventCore("zoom-factor-changed", callback); + } + function onPlacementSettingsChanged(callback) { + return onEventCore("placementSettingsChanged", callback); + } + function onNeighboursChanged(callback) { + return onEventCore("neighbours-changed", callback); + } + function onDockingChanged(callback) { + return onEventCore("docking-changed", callback); + } + function onEventCore(key, callback, replayArguments) { + if (!isFunction(callback)) { + throw new Error("callback must be a function"); + } + return _registry.add(key, callback, replayArguments); + } + function goBack() { + return executor.goBack(resultWindow); + } + function goForward() { + return executor.goForward(resultWindow); + } + function startDrag(option) { + return executor.startDrag(resultWindow, option); + } + function showDialog(dialogOptions) { + if ((dialogOptions === null || dialogOptions === void 0 ? void 0 : dialogOptions.timerDuration) && isNaN(dialogOptions === null || dialogOptions === void 0 ? void 0 : dialogOptions.timerDuration)) { + throw new Error("timerDuration must be a number"); + } + if ((dialogOptions === null || dialogOptions === void 0 ? void 0 : dialogOptions.showTimer) && typeof (dialogOptions === null || dialogOptions === void 0 ? void 0 : dialogOptions.showTimer) !== "boolean") { + throw new Error("showTimer must be a boolean"); + } + return executor.showDialog(resultWindow, dialogOptions); + } + function handleUpdate(updated) { + _url = updated.url; + _title = updated.title; + _context = updated.context || {}; + _bounds = updated.bounds; + _frameColor = updated.frameColor; + _focus = updated.focus; + _neighbours = updated.neighbours || {}; + _groupId = updated.groupId; + _isGroupHeaderVisible = updated.isGroupHeaderVisible; + _isTabHeaderVisible = updated.isTabHeaderVisible; + _isGroupHibernated = updated.isGroupHibernated; + _isGroupVisible = updated.isGroupVisible; + _isTabSelected = updated.isTabSelected; + _settings = updated.settings; + _isVisible = updated.isVisible; + _isSticky = updated.isSticky; + _isCollapsed = updated.isCollapsed; + _windowState = updated.state; + _tabGroupId = updated.tabGroupId; + _frameId = updated.frameId; + _isLocked = updated.isLocked; + _allowWorkspaceDrop = updated.allowWorkspaceDrop; + _isPinned = updated.isPinned; + _zoomFactor = updated.zoomFactor; + _placementSettings = updated.placementSettings; + } + function handleTitleChanged(newTitle) { + _title = newTitle; + executor.finished + .finally(() => { + _registry.execute("onTitleChanged", newTitle, resultWindow); + }); + } + function handleUrlChanged(newUrl) { + _url = newUrl; + _registry.execute("onUrlChanged", newUrl, resultWindow); + } + function handleVisibilityChanged(isVisible) { + if (isVisible === _isVisible) { + return; + } + _isVisible = isVisible; + _registry.execute("visibility-changed", resultWindow); + } + function handleWindowSettingsChanged(settings) { + _settings = settings; + _registry.execute("settings-changed", resultWindow); + } + function handleContextUpdated(context) { + _context = context; + _registry.execute("context-updated", _context, resultWindow); + } + function handleWindowClose() { + if (id === undefined) { + return; + } + _registry.execute("onClose", resultWindow); + id = undefined; + } + function handleFrameButtonAdded(frameButton) { + const buttonObj = ["buttonId", "imageBase64", "order", "tooltip"].reduce((memo, k) => { + memo[k] = frameButton[k]; + return memo; + }, {}); + const frameButtonsIds = _frameButtons.map((btn) => { + return btn.buttonId; + }); + if (frameButtonsIds.indexOf(frameButton.buttonId) === -1) { + _frameButtons.push(buttonObj); + } + _registry.execute("onFrameButtonAdded", buttonObj, resultWindow); + } + function handleFrameButtonRemoved(frameButtonId) { + let button; + _frameButtons = _frameButtons.reduce((memo, btn) => { + if (btn.buttonId === frameButtonId) { + button = btn; + } + else { + memo.push(btn); + } + return memo; + }, []); + if (button !== undefined) { + _registry.execute("onFrameButtonRemoved", button, resultWindow); + } + } + function handleFrameButtonClicked(frameButton) { + const button = _frameButtons.filter((btn) => { + return btn.buttonId === frameButton.buttonId; + }); + if (button.length > 0) { + _registry.execute("onFrameButtonClicked", button[0], resultWindow); + } + } + async function handleWindowChangeState(state) { + if (state === "collapsed") { + _isCollapsed = true; + } + else if (state === "expanded") { + _isCollapsed = false; + } + else { + _windowState = state; + } + await executor.finished; + _registry.execute(state, resultWindow); + } + function handleFrameIsLockedChanged(isLocked) { + _isLocked = isLocked; + _registry.execute("lock-changed", resultWindow); + } + function handleBoundsChanged(bounds) { + if (_bounds.top === bounds.top && _bounds.left === bounds.left && _bounds.width === bounds.width && _bounds.height === bounds.height) { + return; + } + _bounds = bounds; + _registry.execute("bounds-changed", resultWindow); + } + function handleFocusChanged(isFocused) { + _focus = isFocused; + _registry.execute("focus-changed", resultWindow); + } + function handleIsStickyChanged(isSticky) { + _isSticky = isSticky; + _registry.execute("sticky-changed", isSticky, resultWindow); + } + function handleFrameColorChanged(frameColor) { + _frameColor = frameColor; + _registry.execute("frame-color-changed", resultWindow); + } + function handleFrameAttached(tabGroupId, frameId, isTabHeaderVisible) { + _tabGroupId = tabGroupId; + _frameId = frameId; + _isTabHeaderVisible = isTabHeaderVisible; + _registry.execute("frame-attached", resultWindow); + } + function handleCompositionChanged(state) { + _neighbours = state.neighbors || {}; + _tabIndex = state.index; + _registry.execute("neighbours-changed", _neighbours, resultWindow); + } + function handleAllowWorkspaceDropChanged(allowWorkspaceDrop) { + _allowWorkspaceDrop = allowWorkspaceDrop; + _registry.execute("allow-workspace-drop-changed", resultWindow); + } + function handleIsPinnedChanged(isPinned) { + _isPinned = isPinned; + _registry.execute("is-pinned-changed", resultWindow); + } + function handleGroupHeaderVisibilityChanged(isGroupHeaderVisible) { + _isGroupHeaderVisible = isGroupHeaderVisible; + } + function handleTabHeaderVisibilityChanged(isTabHeaderVisible) { + if (_isTabHeaderVisible !== isTabHeaderVisible) { + _isTabHeaderVisible = isTabHeaderVisible; + _registry.execute("tab-header-visibility-changed", resultWindow); + } + } + async function handleFrameSelectionChanged(newWindow, prevWindow) { + let selectedWindow; + if (newWindow === id) { + _isTabSelected = true; + selectedWindow = resultWindow; + } + else { + _isTabSelected = false; + selectedWindow = windowStore.get(newWindow) ? windowStore.get(newWindow).API : undefined; + } + const previousWindow = windowStore.get(prevWindow) ? windowStore.get(prevWindow).API : undefined; + await executor.finished; + _registry.execute("tab-selection-changed", selectedWindow, previousWindow, resultWindow); + } + async function handleAttached(newTabGroupId, newFrameId, tabHeaderVisible, isLocked, winsToBeNotified) { + _tabGroupId = newTabGroupId; + _isTabHeaderVisible = tabHeaderVisible; + _frameId = newFrameId; + if (typeof isLocked !== "undefined") { + _isLocked = isLocked; + } + await executor.finished; + winsToBeNotified.forEach((w) => { + w.Events.handleWindowAttached(resultWindow); + }); + _registry.execute("attached", resultWindow); + } + function handleWindowAttached(win) { + _registry.execute("window-attached", win); + } + async function handleDetached(isLocked, winsToBeNotified) { + _tabGroupId = undefined; + _isTabSelected = false; + if (typeof isLocked !== "undefined") { + _isLocked = isLocked; + } + await executor.finished; + winsToBeNotified.forEach((w) => { + w.Events.handleWindowDetached(resultWindow); + }); + _registry.execute("detached", resultWindow); + } + function handleWindowDetached(win) { + _registry.execute("window-detached", win); + } + function handleZoomFactorChanged(zoomFactor) { + _zoomFactor = zoomFactor; + _registry.execute("zoom-factor-changed", resultWindow); + } + function handlePlacementSettingsChanged(placementSettings) { + let promise; + const copy = placementSettings; + if (!copy.display) { + promise = Promise.resolve(undefined); + } + else { + const displayAPI = displayAPIGetter(); + if (!displayAPI) { + promise = Promise.resolve(undefined); + } + else { + const index = copy.display - 1; + promise = new Promise((resolve, reject) => { + displayAPI.all().then((displays) => { + const display = displays.find((d) => d.index === index); + resolve(display); + }).catch(reject); + }); + } + } + void promise.then((d) => { + copy.display = d; + _placementSettings = copy; + _registry.execute("placementSettingsChanged", resultWindow); + }); + } + function handleDockingChanged(data) { + _registry.execute("docking-changed", resultWindow, { + docked: data.docked, + position: data.position, + claimScreenArea: data.claimScreenArea + }); + } + function handleChannelRestrictionsChanged(data) { + _registry.execute("channel-restrictions-changed", data); + } + function handleGroupChanged(newGroup, oldGroup) { + _group = newGroup; + _groupId = newGroup === null || newGroup === void 0 ? void 0 : newGroup.id; + if (!isUndefinedOrNull(newGroup) && !isUndefinedOrNull(oldGroup)) { + _registry.execute("group-changed", resultWindow, newGroup, oldGroup); + } + } + function getAllTabs() { + const allWindows = windowStore.list; + if (_mode.toLowerCase() !== "tab") { + return []; + } + const tabs = Object.keys(allWindows).reduce((memo, win) => { + const window = allWindows[win]; + if (window + && window.API.tabGroupId + && typeof window.API.tabGroupId !== "undefined" + && typeof resultWindow.tabGroupId !== "undefined" + && window.API.tabGroupId === resultWindow.tabGroupId) { + memo.push(window.API); + } + return memo; + }, []); + return tabs.sort((w1, w2) => { + if (w1.tabIndex !== w2.tabIndex) { + if (w1.tabIndex === -1) { + return Number.MAX_SAFE_INTEGER; + } + if (w2.tabIndex === -1) { + return Number.MIN_SAFE_INTEGER; + } + } + return w1.tabIndex - w2.tabIndex; + }); + } + function mapWindowIdsToWindowObjects(windowIdArr) { + return windowIdArr.reduce((memo, winId) => { + const window = windowStore.get(winId); + if (window) { + memo.push(window.API); + } + return memo; + }, []); + } + function getNeighboursByDirection(direction) { + const windowIds = _neighbours[direction]; + if (typeof windowIds !== "undefined") { + return mapWindowIdsToWindowObjects(windowIds); + } + } + function getApplicationName() { + var _a; + if (_applicationName) { + return _applicationName; + } + if (_context._APPLICATION_NAME) { + return _context._APPLICATION_NAME; + } + if (_context && _context._t42 && _context._t42.application) { + return _context._t42.application; + } + const info = getWindowInfo(); + if (info && info.applicationName) { + return info.applicationName; + } + const appManager = appManagerGetter(); + if (appManager) { + const instance = appManager.instances().find((i) => id === i.id); + if (instance) { + return (_a = instance.application) === null || _a === void 0 ? void 0 : _a.name; + } + } + return undefined; + } + function getWindowInfo() { + if (typeof window !== "undefined" && window.glue42gd && window.glue42gd.getWindowInfo) { + const info = window.glue42gd.getWindowInfo(id); + if (!info) { + return undefined; + } + else { + return info; + } + } + } + const resultWindow = { + get id() { + return _id; + }, + get name() { + return _name; + }, + get application() { + const appManager = appManagerGetter(); + const appName = getApplicationName(); + if (appName && appManager) { + return appManager.application(appName); + } + }, + get hostInstance() { + return executor.hostInstance; + }, + get interopInstance() { + const instance = agm.servers().find((s) => s.windowId === this.id); + if (instance) { + return instance; + } + else { + const appName = getApplicationName(); + if (appName) { + return { application: appName }; + } + } + }, + get agmInstance() { + return resultWindow.interopInstance; + }, + get url() { + return _url; + }, + get title() { + return _title; + }, + get windowStyleAttributes() { + return _settings; + }, + get settings() { + return _settings; + }, + get tabGroupId() { + return _mode.toLowerCase() === "tab" ? _tabGroupId : undefined; + }, + get tabIndex() { + return _mode.toLowerCase() === "tab" ? _tabIndex : undefined; + }, + get frameId() { + return _frameId; + }, + get frameButtons() { + return _frameButtons.sort((b1, b2) => b1.order - b2.order); + }, + get mode() { + return _mode; + }, + get state() { + return _windowState; + }, + get isCollapsed() { + return _isCollapsed; + }, + get isVisible() { + return _isVisible; + }, + get isLocked() { + return _isLocked; + }, + get context() { + return _context; + }, + get bounds() { + return _bounds; + }, + get minHeight() { + return _settings.minHeight; + }, + get maxHeight() { + return _settings.maxHeight; + }, + get minWidth() { + return _settings.minWidth; + }, + get maxWidth() { + return _settings.maxWidth; + }, + get isFocused() { + return _focus; + }, + get frameColor() { + return _frameColor; + }, + get opened() { + return resultWindow.id !== undefined; + }, + get group() { + return _group; + }, + get groupId() { + return _groupId; + }, + get isSticky() { + return _isSticky; + }, + get topNeighbours() { + return getNeighboursByDirection("top"); + }, + get leftNeighbours() { + return getNeighboursByDirection("left"); + }, + get rightNeighbours() { + return getNeighboursByDirection("right"); + }, + get bottomNeighbours() { + return getNeighboursByDirection("bottom"); + }, + get isGroupHeaderVisible() { + return _isGroupHeaderVisible; + }, + get activityId() { + if (_context._t42) { + return _context._t42.activityId; + } + const info = getWindowInfo(); + if (!info) { + return undefined; + } + return info.activityId; + }, + get activityWindowId() { + if (_context._t42) { + return _context._t42.activityWindowId; + } + const info = getWindowInfo(); + if (!info) { + return undefined; + } + return info.activityWindowId; + }, + get windowType() { + return options.windowType || "electron"; + }, + get zoomFactor() { + return _zoomFactor; + }, + get screen() { + if (typeof window !== "undefined" && window.glue42gd) { + return Utils.getMonitor(resultWindow.bounds, window.glue42gd.monitors); + } + return undefined; + }, + get placementSettings() { + return Object.assign({}, _placementSettings); + }, + get jumpList() { + return _jumpList; + }, + get allowWorkspaceDrop() { + return _allowWorkspaceDrop; + }, + get isPinned() { + return _isPinned; + }, + maximize, + restore, + minimize, + maximizeRestore, + collapse, + expand, + toggleCollapse, + focus, + activate, + moveResize, + setTitle, + setStyle, + setOnTop, + resetButtons, + getButtons, + setSizeConstraints, + getSizeConstraints, + navigate, + addFrameButton, + removeFrameButton, + setVisible, + show: () => setVisible(true), + hide: () => setVisible(false), + center, + close, + snap, + showLoader, + hideLoader, + updateContext, + lock, + unlock, + getIcon, + setIcon, + setFrameColor, + setTabTooltip, + getTabTooltip, + attachTab, + detachTab, + setTabHeaderVisible, + showPopup, + createFlydown, + setModalState, + setZoomFactor, + zoomIn, + zoomOut, + showDevTools, + capture, + flash, + flashTab, + setSticky, + setAllowWorkspaceDrop, + pin, + unpin, + print, + printToPDF, + place, + ungroup, + refresh, + goBack, + goForward, + download, + configure, + getConfiguration, + getDockingPlacement, + dock, + clone, + executeCode, + getChannel: async () => { + var _a; + const wins = await getChannels().getWindowsWithChannels({ windowIds: [_id] }); + return (_a = wins[0]) === null || _a === void 0 ? void 0 : _a.channel; + }, + startDrag, + showDialog, + onClose, + onUrlChanged, + onTitleChanged, + onFrameButtonAdded, + onFrameButtonRemoved, + onFrameButtonClicked, + onCollapsed, + onExpanded, + onMinimized, + onMaximized, + onNormal, + onAttached, + onDetached, + onVisibilityChanged, + onContextUpdated, + onLockingChanged, + onBoundsChanged, + onFrameColorChanged, + onFocusChanged, + onStickyChanged, + onGroupChanged, + onWindowAttached, + onWindowDetached, + onTabSelectionChanged, + onTabHeaderVisibilityChanged, + onClosing, + onRefreshing, + onZoomFactorChanged, + onPlacementSettingsChanged, + onNeighboursChanged, + onDockingChanged, + onNavigating, + onChannelRestrictionsChanged, + get tabs() { + return getAllTabs(); + }, + get isTabHeaderVisible() { + return _isTabHeaderVisible; + }, + get isTabSelected() { + return _isTabSelected; + }, + getURL() { + return Promise.resolve(_url); + }, + getTitle() { + return Promise.resolve(_title); + }, + getBounds() { + return Promise.resolve(_bounds); + }, + getContext() { + return Promise.resolve(_context); + }, + setContext(context) { + if (!isObject(context)) { + throw new Error(`"context" must not be null or undefined, set to empty object if you want to clear it out.`); + } + return executor.updateContext(resultWindow, context, true); + }, + getDisplay() { + const displayAPI = displayAPIGetter(); + return displayAPI.getByWindowId(id); + }, + resizeTo(width, height) { + return moveResize({ width, height }); + }, + moveTo(top, left) { + return moveResize({ top, left }); + }, + async getParentWindow() { + var _a; + const myParentId = _settings.parentInstanceId; + if (!myParentId) { + return undefined; + } + return (_a = windowStore.list[myParentId]) === null || _a === void 0 ? void 0 : _a.API; + }, + async getChildWindows() { + return Object.keys(windowStore.list) + .map((key) => windowStore.list[key].API) + .filter((w) => { + const parentId = w.settings.parentInstanceId; + return parentId === id; + }); + }, + joinChannel: (name) => { + return getChannels().join(name, id); + }, + leaveChannel: () => { + return getChannels().leave(id); + } + }; + const events = { + handleUpdate, + handleWindowClose, + handleWindowChangeState, + handleTitleChanged, + handleVisibilityChanged, + handleUrlChanged, + handleWindowSettingsChanged, + handleContextUpdated, + handleFrameIsLockedChanged, + handleBoundsChanged, + handleFocusChanged, + handleFrameButtonAdded, + handleFrameButtonRemoved, + handleFrameButtonClicked, + handleFrameColorChanged, + handleFrameAttached, + handleFrameSelectionChanged, + handleCompositionChanged, + handleAllowWorkspaceDropChanged, + handleIsPinnedChanged, + handleGroupHeaderVisibilityChanged, + handleTabHeaderVisibilityChanged, + handleGroupChanged, + handleAttached, + handleDetached, + handleWindowAttached, + handleWindowDetached, + handleZoomFactorChanged, + handleIsStickyChanged, + handlePlacementSettingsChanged, + handleDockingChanged, + handleChannelRestrictionsChanged + }; + const groupArgs = { + get isGroupHibernated() { + return _isGroupHibernated; + }, + get isGroupVisible() { + return _isGroupVisible; + }, + }; + return { + API: resultWindow, + Events: events, + GroupCreationArgs: groupArgs + }; + }; + + function getWindowsByTabGroupId(windowId, tabGroupId) { + const windows = windowStore.list; + return Object.keys(windows).reduce((memo, id) => { + const win = windows[id]; + if (win.API.tabGroupId === tabGroupId && win.API.id !== windowId) { + memo.push(win); + } + return memo; + }, []); + } + function isEmpty(object) { + if (!object || Object.keys(object).every((value) => object[value] === undefined)) { + return true; + } + return false; + } + + class GDExecutor { + constructor() { + this.GroupMethodName = "T42.Group.Execute"; + this.WndMethodName = "T42.Wnd.Execute"; + this._registry = CallbackRegistryFactory(); + this._finished = Promise.resolve(); + this._configuration = { + windowAvailableOnURLChanged: true + }; + this.unsubCallbacks = {}; + } + get hostInstance() { + return this.agmTarget; + } + get finished() { + return this._finished; + } + get configuration() { + return this._configuration; + } + init(agm, instance) { + this.agm = agm; + this.agmTarget = instance; + this._registry.add("event", (data) => { + if (data.type === "Closed") { + const keys = Object.keys(this.unsubCallbacks); + keys.forEach((key) => { + const isSameWindow = key.startsWith(data.windowId); + if (isSameWindow) { + delete this.unsubCallbacks[key]; + } + }); + } + }); + } + setConfiguration(config) { + this._configuration = { ...this._configuration, ...config }; + } + handleEvent(data) { + this._registry.execute("event", data); + } + async open(options) { + let finishedResolve; + this._finished = new Promise((resolve) => { + finishedResolve = resolve; + }); + try { + const result = await this.agm.invoke("T42.Wnd.Create", options, this.agmTarget, { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_RESPONSE_TIMEOUT_MS + }); + if (result.returned === undefined) { + throw new Error("failed to execute T42.Wnd.Create - unknown reason"); + } + const id = result.returned.id; + const win = await windowStore.waitFor(id); + if (!this.configuration || this.configuration.windowAvailableOnURLChanged) { + setTimeout(() => { + if (win.API.windowType === "electron") { + win.Events.handleUrlChanged(win.API.url); + } + }, 0); + } + return win.API; + } + finally { + finishedResolve(); + } + } + async close(w, options) { + const result = await this.execute("close", { windowId: w.id, options }, `Closed`); + if (options) { + return result.closed; + } + return w; + } + async navigate(w, newUrl, urlLoadOptions) { + let methodResponseTimeoutMs = 120000; + if (typeof urlLoadOptions === "object" && typeof urlLoadOptions.timeout === "number") { + methodResponseTimeoutMs = urlLoadOptions.timeout * 1000; + delete urlLoadOptions.timeout; + } + await this.execute("navigate", { windowId: w.id, options: { url: newUrl, urlLoadOptions }, invocationOptions: { methodResponseTimeoutMs } }, "UrlChanged"); + return w; + } + async setStyle(w, style) { + var _a; + const stylePromises = []; + const wait = (promise) => stylePromises.push(promise); + if (!isUndefinedOrNull(style.focus) && !w.isFocused) { + wait(w.focus()); + } + if (!isUndefinedOrNull(style.hidden)) { + const toBeVisible = !style.hidden; + wait(w.setVisible(toBeVisible)); + } + if (!isUndefinedOrNull(style.onTop)) { + wait(w.setOnTop(style.onTop)); + } + if (!isNullOrWhiteSpace(style.tabTooltip) || !isNullOrWhiteSpace(style.tabToolTip)) { + const toolTip = (_a = style.tabTooltip) !== null && _a !== void 0 ? _a : style.tabToolTip; + wait(w.setTabTooltip(toolTip)); + } + if (!isNullOrWhiteSpace(style.tabTitle)) { + wait(this.execute("setTabTitle", { windowId: w.id, options: { tabTitle: style.tabTitle } })); + } + const constraints = { + minHeight: style.minHeight, + minWidth: style.minWidth, + maxHeight: style.maxHeight, + maxWidth: style.maxWidth, + }; + const hasConstraints = !isEmpty(constraints); + if (hasConstraints) { + wait(w.setSizeConstraints(constraints)); + } + const buttons = { + allowClose: style.allowClose, + allowCollapse: style.allowCollapse, + allowLockUnlock: style.allowLockUnlock, + allowMaximize: style.allowMaximize, + allowMinimize: style.allowMinimize + }; + const hasButtons = !isEmpty(buttons); + if (hasButtons) { + wait(w.resetButtons(buttons)); + } + await Promise.all(stylePromises); + return w; + } + async setSizeConstraints(w, constraints) { + await this.execute("setSizeConstraints", { windowId: w.id, options: constraints }); + return w; + } + async getSizeConstraints(w) { + const sizeConstraint = await this.execute("getSizeConstraints", { windowId: w.id }); + return sizeConstraint; + } + async setTabTooltip(w, tabTooltip) { + await this.execute("setTabTooltip", { windowId: w.id, options: { tabTooltip } }); + return w; + } + async getTabTooltip(w) { + const result = await this.execute("getTabTooltip", { windowId: w.id }); + return result.tabTooltip; + } + async resetButtons(w, buttonsConfig) { + await this.execute("resetButtons", { windowId: w.id, options: buttonsConfig }); + return w; + } + async getButtons(w) { + const buttons = await this.execute("getButtons", { windowId: w.id }); + return buttons; + } + async setOnTop(w, onTop) { + await this.execute("setOnTop", { windowId: w.id, options: { onTop } }); + return w; + } + async setTitle(w, newTitle) { + const options = { + windowId: w.id, + options: { + title: newTitle + } + }; + await this.execute("setTitle", options, "TitleChanged"); + return w; + } + async setSticky(w, isSticky) { + const options = { + windowId: w.id, + options: { + isSticky + } + }; + await this.execute("setSticky", options); + return w; + } + async setAllowWorkspaceDrop(w, allowWorkspaceDrop) { + const options = { + windowId: w.id, + options: { + allowWorkspaceDrop + } + }; + await this.execute("setAllowWorkspaceDrop", options); + return w; + } + async pin(windowToPin) { + const options = { + windowId: windowToPin.id + }; + await this.execute("pinTab", options); + return windowToPin; + } + async unpin(pinnedWindow) { + const options = { + windowId: pinnedWindow.id + }; + await this.execute("unpinTab", options); + return pinnedWindow; + } + async moveResize(w, bounds) { + if (typeof window !== "undefined" && window.glueDesktop.versionNum < 31200) { + return new Promise(async (res, rej) => { + const resolveImmediately = this.areBoundsEqual(bounds, w); + let isDone = false; + const done = () => { + if (isDone) { + return; + } + isDone = true; + if (unsubscribeBoundsChanged) { + unsubscribeBoundsChanged(); + unsubscribeBoundsChanged = undefined; + } + res(w); + if (resolveTimeout) { + clearTimeout(resolveTimeout); + resolveTimeout = undefined; + } + }; + let resolveTimeout; + let unsubscribeBoundsChanged; + if (!resolveImmediately) { + unsubscribeBoundsChanged = w.onBoundsChanged((win) => { + if (!this.areBoundsEqual(bounds, win)) { + return; + } + done(); + }); + } + try { + await this.execute("moveResize", { windowId: w.id, options: { bounds } }); + } + catch (error) { + rej(error); + return; + } + if (resolveImmediately) { + done(); + return; + } + resolveTimeout = setTimeout(() => { + done(); + }, 1000); + }); + } + else { + await this.execute("moveResize", { windowId: w.id, options: { bounds } }); + } + return w; + } + async addFrameButton(w, buttonInfo) { + await this.execute("addButton", { windowId: w.id, options: buttonInfo }, "ButtonAdded"); + return w; + } + async removeFrameButton(w, buttonId) { + await this.execute("removeButton", { windowId: w.id, options: buttonId }, "ButtonRemoved"); + return w; + } + async activate(w) { + await this.execute("activate", { windowId: w.id }); + return w; + } + async focus(w) { + await this.execute("focus", { windowId: w.id }); + return w; + } + async maximizeRestore(w) { + await this.execute("maximizeRestore", { windowId: w.id }, "StateChanged"); + return w; + } + async maximize(w) { + await this.execute("maximize", { windowId: w.id }, "StateChanged"); + return w; + } + async restore(w) { + await this.execute("restore", { windowId: w.id }, "StateChanged"); + return w; + } + async minimize(w) { + await this.execute("minimize", { windowId: w.id }, "StateChanged"); + return w; + } + async collapse(w) { + await this.execute("collapse", { windowId: w.id }, "StateChanged"); + return w; + } + async expand(w) { + await this.execute("expand", { windowId: w.id }, "StateChanged"); + return w; + } + async toggleCollapse(w) { + await this.execute("toggleCollapse", { windowId: w.id }, "StateChanged"); + return w; + } + async snap(w, targetWindow, options) { + const args = { + targetWindowId: targetWindow.id + }; + args.snappingEdge = options.direction; + args.autoAlign = options.autoAlign; + await this.execute("snap", { windowId: w.id, options: args }, "CompositionChanged", `CompositionChanged-${targetWindow.id}`); + return w; + } + async attachTab(w, sourceWindow, options) { + await this.execute("attachTab", { + windowId: w.id, + options: { + index: options, + sourceWindowId: sourceWindow.id, + targetWindowId: w.id, + } + }, `WindowFrameAdded-${sourceWindow.id}`, `WindowFrameRemoved-${sourceWindow.id}`); + return w; + } + async detachTab(w, options) { + const eventKeys = ["WindowFrameRemoved", `WindowFrameAdded`]; + if (!isUndefinedOrNull(options === null || options === void 0 ? void 0 : options.relativeTo)) { + eventKeys.push(`CompositionChanged`); + eventKeys.push(`CompositionChanged-${options.relativeTo}`); + } + else { + eventKeys.push("BoundsChanged"); + } + await this.execute("detachTab", { windowId: w.id, options }, ...eventKeys); + return w; + } + async setVisible(w, toBeVisible = true) { + let command; + if (toBeVisible) { + command = "show"; + } + else { + command = "hide"; + } + await this.execute(command, { windowId: w.id }, "VisibilityChanged"); + return w; + } + async center(w, display) { + await this.execute("center", { windowId: w.id, options: display }); + return w; + } + async showLoader(w, loader) { + await this.execute("showLoadingAnimation", { windowId: w.id, options: loader }); + return w; + } + async hideLoader(w) { + await this.execute("hideLoadingAnimation", { windowId: w.id }); + return w; + } + async updateContext(w, context, replace) { + let un; + try { + const contextWithoutUndefinedValues = this.swapUndefinedToNull(context); + const done = new Promise((resolve, reject) => { + un = w.onContextUpdated(() => { + resolve(); + }); + }); + await Promise.all([this.execute("updateContext", { + windowId: w.id, context: contextWithoutUndefinedValues, replace + }), done]); + return w; + } + finally { + if (un) { + un(); + } + } + } + async lock(w) { + await this.execute("lockUnlock", { windowId: w.id, options: { lock: true } }, "FrameIsLockedChanged"); + return w; + } + async unlock(w) { + await this.execute("lockUnlock", { windowId: w.id, options: { lock: false } }, "FrameIsLockedChanged"); + return w; + } + async getIcon(w) { + const result = await this.execute("getIcon", { + windowId: w.id, + options: {} + }); + return result.icon; + } + async setIcon(w, base64Image) { + await this.execute("setIcon", { + windowId: w.id, + options: { + dataURL: base64Image + } + }); + return w; + } + async setFrameColor(w, frameColor) { + await this.execute("setFrameColor", { windowId: w.id, options: { frameColor } }, "FrameColorChanged"); + return w; + } + async setTabHeaderVisible(w, toBeTabHeaderVisible) { + await this.execute("setTabHeaderVisible", { + windowId: w.id, + options: { + toShow: toBeTabHeaderVisible + } + }, "TabHeaderVisibilityChanged"); + return w; + } + async showGroupPopup(id, options) { + const reformatedOptions = this.showPopupCore(id, options); + await this.executeGroup("showGroupPopup", { + groupId: id, + options: reformatedOptions + }); + } + async showPopup(targetWindow, options) { + const reformatedOptions = this.showPopupCore(targetWindow.id, options); + await this.execute("showPopupWindow", { + windowId: targetWindow.id, + options: reformatedOptions + }); + return targetWindow; + } + async createFlydown(windowId, options) { + if (!options) { + throw new Error("The options object is not valid!"); + } + const optionsCopy = { ...options }; + if (!optionsCopy.horizontalOffset) { + optionsCopy.horizontalOffset = 0; + } + if (!optionsCopy.verticalOffset) { + optionsCopy.verticalOffset = 0; + } + const fullOptions = this.reformatFlydownOptions(windowId, optionsCopy); + return this.execute("setFlydownArea", { windowId, options: fullOptions }).then(() => { + const zoneIds = fullOptions.zones.map((z) => z.id); + fullOptions.zones.forEach((z) => { + let callback = typeof (z.flydownSize) === "function" ? + z.flydownSize : () => z.flydownSize; + if (options.size instanceof Function && z.flydownSize) { + callback = async (data, cancel) => { + let result; + if (options.size instanceof Function) { + result = await options.size(data, cancel); + } + if (z.flydownSize instanceof Function && z.flydownSize !== options.size) { + return await z.flydownSize(data, cancel) || result; + } + return result || z.flydownSize; + }; + } + this._registry.clearKey(`${fullOptions.targetId}_${z.id}`); + this._registry.add(`${fullOptions.targetId}_${z.id}`, callback); + }); + return { + destroy: () => this.clearFlydownArea(fullOptions.targetId, zoneIds), + options: optionsCopy + }; + }); + } + async setModalState(windowId, isModal) { + return this.execute("setModalState", { windowId, options: { isModal } }); + } + async autoArrange(displayId) { + return this.execute("autoArrange", { options: { displayId } }); + } + async handleFlydownBoundsRequested(targetId, data) { + const cancelCallback = () => data.cancel = true; + const callbackData = { + zoneId: data.flydownId, + flydownWindowBounds: data.flydownWindowBounds, + flydownWindowId: data.flydownWindowId, + }; + const responses = await Promise.all(this._registry.execute(`${targetId}_${data.flydownId}`, callbackData, cancelCallback)); + if (responses.length === 1) { + const defaultResponse = { height: 0, width: 0, top: 0, left: 0 }; + const response = typeof (responses[0]) === "object" && !Array.isArray(responses[0]) ? responses[0] : defaultResponse; + const responseOptions = { ...data, flydownWindowBounds: response }; + return responseOptions; + } + } + async handleOnEventRequested(callbackId, args) { + var _a; + const callbacks = (_a = this.unsubCallbacks[callbackId]) !== null && _a !== void 0 ? _a : []; + let prevented = false; + const preventArgs = []; + await Promise.all(callbacks.map((cb) => { + return new Promise((resolve, reject) => { + cb(() => { + resolve(); + }, () => { + reject(); + }, (pArgs) => { + prevented = true; + preventArgs.push(pArgs); + }, args); + }); + })); + return { prevented, preventArgs }; + } + async zoomIn(window) { + await this.execute("zoomIn", { + windowId: window.id, + }); + return window; + } + async zoomOut(window) { + await this.execute("zoomOut", { + windowId: window.id, + }); + return window; + } + async setZoomFactor(window, zoomFactor) { + await this.execute("setZoomFactor", { + windowId: window.id, + options: { + zoomFactor + } + }); + return window; + } + async showDevTools(window) { + await this.execute("showDevTools", { + windowId: window.id, + }); + return window; + } + async capture(window, options) { + const base64screenshot = (await this.execute("captureScreenshot", { windowId: window.id, options: { ...options } })).data; + return base64screenshot; + } + async captureGroup(windowIds, options) { + const base64screenshot = (await this.execute("captureGroupScreenshot", { windowId: windowIds[0], options: { groupWindowIds: windowIds, ...options } })).data; + return base64screenshot; + } + async flash(resultWindow, options) { + await this.execute("flash", { windowId: resultWindow.id, options: { ...options } }); + return resultWindow; + } + async flashTab(resultWindow, options) { + await this.execute("flashTab", { windowId: resultWindow.id, options: { ...options } }); + return resultWindow; + } + async configure(windowId, options) { + return this.execute("configure", { windowId, options: { ...options } }); + } + async print(resultWindow, options) { + await this.execute("print", { windowId: resultWindow.id, options: { ...options } }); + return resultWindow; + } + async printToPDF(resultWindow, options) { + const filePath = (await this.execute("printToPDF", { windowId: resultWindow.id, options: { ...options } })).filePath; + return filePath; + } + async place(window, options) { + const copy = { ...options }; + if (!options.display || options.display === "current") { + copy.display = await window.getDisplay(); + } + if (copy.display && typeof copy.display !== "string" && typeof copy.display !== "number") { + copy.display = copy.display.index + 1; + } + return this.execute("place", { windowId: window.id, options: { ...copy } }); + } + async refresh(resultWindow, ignoreCache) { + await this.execute("refresh", { windowId: resultWindow.id, options: { ignoreCache } }); + return resultWindow; + } + async download(resultWindow, url, options = {}) { + options.enableDownloadBar = !options.silent; + const result = await this.execute("downloadURL", { windowId: resultWindow.id, options: { url, options } }); + return { + url, + path: result.fullPath, + size: result.fileSize, + }; + } + async configureWindow(resultWindow, options) { + await this.execute("configureWindow", { windowId: resultWindow.id, options }); + return resultWindow; + } + async getWindowConfiguration(resultWindow) { + const config = await this.execute("getWindowConfiguration", { windowId: resultWindow.id }); + return config; + } + async startDrag(resultWindow, options) { + await this.execute("startDrag", { windowId: resultWindow.id, options }); + return resultWindow; + } + showDialog(resultWindow, options) { + return new Promise((res, rej) => { + const token = Utils.generateId(); + const un = this._registry.add("event", (args) => { + if (args.type === "DialogResult" && args.windowId === resultWindow.id && args.data.token === token) { + un(); + const data = args.data; + if ("status" in data) { + if (data.status === "failed") { + rej(new Error(data.message)); + } + else if (data.status === "successful") { + res(data.result); + } + } + } + }); + this.execute("showDialog", { windowId: resultWindow.id, options: Object.assign({}, { ...options }, { token }) }); + }); + } + async execute(command, options, ...eventKeys) { + return this.executeCore(this.WndMethodName, command, options, ...eventKeys); + } + async executeGroup(command, options, ...eventKeys) { + return this.executeCore(this.GroupMethodName, command, options, ...eventKeys); + } + async ungroup(w, options) { + const args = { + windowId: w.id, + options + }; + await this.execute("ungroup", args); + return w; + } + async updateJumpList(windowId, options) { + const args = { + windowId, + options + }; + await this.execute("updateJumplist", args); + } + async getJumpList(windowId) { + const args = { + windowId, + }; + const result = await this.execute("getJumplist", args); + return result; + } + onClosing(callback, gdWindow) { + const glue42gd = typeof window !== "undefined" && window.glue42gd; + if (glue42gd && gdWindow.windowType === "electron") { + return glue42gd.addCloseHandler(callback, gdWindow.id); + } + else { + return this.nonWindowHandlers(callback, gdWindow.id, "OnClosing"); + } + } + onGroupClosing(callback, group) { + return this.nonWindowHandlersCore(group.id, "OnClosing", true, callback); + } + onRefreshing(callback, gdWindow) { + const glue42gd = typeof window !== "undefined" && window.glue42gd; + if (glue42gd && gdWindow.windowType === "electron") { + return glue42gd.addRefreshHandler(callback, gdWindow.id); + } + else { + return this.nonWindowHandlers(callback, gdWindow.id, "OnRefreshing"); + } + } + onNavigating(callback, gdWindow) { + const glue42gd = typeof window !== "undefined" && window.glue42gd; + if (glue42gd && gdWindow.windowType === "electron") { + return glue42gd.addWillNavigateHandler(callback, gdWindow.id); + } + else { + return this.nonWindowHandlers(callback, gdWindow.id, "OnNavigating"); + } + } + async clone(window, cloneOptions) { + const args = { + windowId: window.id, + options: cloneOptions + }; + const result = await this.execute("clone", args); + const win = await windowStore.waitFor(result.id); + return win.API; + } + async executeCode(targetWindow, code) { + const args = { + windowId: targetWindow.id, + options: { + code + } + }; + return this.execute("executeCode", args); + } + async goBack(resultWindow) { + await this.execute("goBack", { windowId: resultWindow.id }); + } + async goForward(resultWindow) { + await this.execute("goForward", { windowId: resultWindow.id }); + } + async getDockingPlacement(window) { + return this.execute("getDockingPlacement", { windowId: window.id }); + } + dock(window, options) { + return this.execute("dock", { windowId: window.id, options }); + } + clearCallbacks(id) { + const keys = Object.keys(this.unsubCallbacks); + keys.forEach((key) => { + if (key.startsWith(id)) { + delete this.unsubCallbacks[key]; + } + }); + } + nonWindowHandlers(callback, targetId, type) { + return this.nonWindowHandlersCore(targetId, type, false, callback); + } + nonWindowHandlersCore(targetId, type, isGroup, callback) { + const id = `${targetId}-${type}`; + const unsub = () => { + var _a; + if (this.unsubCallbacks[id]) { + const callbacks = this.unsubCallbacks[id]; + this.unsubCallbacks[id] = callbacks.filter((cb) => cb !== callback); + if (this.unsubCallbacks[id].length === 0) { + delete this.unsubCallbacks[id]; + } + } + const cbs = (_a = this.unsubCallbacks[id]) !== null && _a !== void 0 ? _a : []; + if (cbs.length === 0) { + const options = { + unsubscribe: true + }; + if (isGroup) { + this.executeGroup(type, { + groupId: targetId, + options + }); + } + else { + this.execute(type, { + windowId: targetId, + options + }); + } + } + }; + if (this.unsubCallbacks[id]) { + this.unsubCallbacks[id].push(callback); + return unsub; + } + else { + this.unsubCallbacks[id] = [callback]; + } + if (isGroup) { + this.executeGroup(type, { groupId: targetId }); + } + else { + this.execute(type, { windowId: targetId }); + } + return unsub; + } + reformatFlydownOptions(windowId, options) { + const assignGeneralIfUnassigned = (zone, prop) => { + if (options[prop] && (zone[prop] === undefined || zone[prop] === null)) { + const valueFromOptions = options[prop]; + zone[prop] = valueFromOptions; + } + }; + const zones = options.zones.map((z) => { + assignGeneralIfUnassigned(z, "windowId"); + assignGeneralIfUnassigned(z, "targetLocation"); + if (options.size && (z.flydownSize === undefined || z.flydownSize === null)) { + z.flydownSize = options.size; + } + z.flydownBounds = z.flydownSize; + z.flydownId = z.windowId; + if (!z.targetLocation) { + z.targetLocation = "bottom"; + } + return z; + }); + return { + ...options, + zones, + targetId: windowId, + flydownBounds: options.size, + flydownActiveArea: options.activeArea + }; + } + clearFlydownArea(windowId, areaIds) { + return this.execute("clearFlydownWindowArea", { + windowId, + options: {} + }).then(() => { + areaIds.forEach((id) => { + this._registry.clearKey(`${windowId}_${id}`); + }); + }); + } + executeWithoutToken(params, ...eventKeys) { + const uns = []; + const executed = eventKeys === null || eventKeys === void 0 ? void 0 : eventKeys.filter((k) => !isUndefinedOrNull(k)).map((key) => { + return new Promise((r) => { + const [type, windowId = params.windowId] = key.split("-"); + uns.push(this._registry.add("event", (data) => { + if (data.type === type && data.windowId === windowId) { + r(); + } + })); + }); + }); + const action = new Promise((resolve, reject) => { + this.agm.invoke("T42.Wnd.Execute", params, this.agmTarget, { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_RESPONSE_TIMEOUT_MS + }) + .then((i) => { + if (i.returned && i.returned.errorMsg) { + reject(i); + } + else { + resolve(i.returned); + } + }) + .catch((e) => reject(e)); + }); + return Promise.all([action, ...executed]) + .then((r) => { + return r[0]; + }) + .finally(() => { + uns.forEach((un) => un()); + }); + } + async executeCore(methodName, command, options, ...eventKeys) { + const { invocationOptions, ...invocationArgs } = options; + const params = { + ...invocationArgs, + command, + }; + let finishedResolve; + this._finished = new Promise((resolve) => { + finishedResolve = resolve; + }); + try { + if (typeof window !== "undefined" && window.glueDesktop.versionNum < 31200) { + return await this.executeWithoutToken(params, ...eventKeys); + } + else { + return await this.executeWithToken(methodName, params, invocationOptions); + } + } + finally { + finishedResolve(); + } + } + async executeWithToken(methodName, options, invocationOptions) { + let un; + try { + const token = Utils.generateId(); + const event = new Promise((r) => { + un = this._registry.add("event", (data) => { + if (data.token === token) { + r(); + } + }); + }); + const execute = new Promise((resolve, reject) => { + options.token = token; + if (!invocationOptions) { + invocationOptions = { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_RESPONSE_TIMEOUT_MS + }; + } + else if (!invocationOptions.methodResponseTimeoutMs) { + invocationOptions.methodResponseTimeoutMs = INTEROP_METHOD_RESPONSE_TIMEOUT_MS; + } + else if (!invocationOptions.waitTimeoutMs) { + invocationOptions.waitTimeoutMs = INTEROP_METHOD_WAIT_TIMEOUT_MS; + } + this.agm.invoke(methodName, options, this.agmTarget, invocationOptions) + .then((i) => { + if (i.returned && i.returned.errorMsg) { + reject(new Error(i.returned.errorMsg)); + } + else { + resolve(i.returned); + } + }) + .catch((e) => { + const error = Utils.typedError(e); + reject(error); + }); + }); + const result = await Promise.all([execute, event]); + return result[0]; + } + finally { + if (un) { + un(); + } + } + } + areBoundsEqual(requested, w) { + const current = w.bounds; + const settings = w.settings; + let height = requested.height; + let width = requested.width; + if (requested.height < settings.minHeight) { + height = settings.minHeight; + } + if (requested.height > settings.maxHeight) { + height = settings.maxHeight; + } + if (requested.width < settings.minWidth) { + width = settings.minWidth; + } + if (requested.width > settings.maxWidth) { + width = settings.maxWidth; + } + const areHeightsEqual = height ? current.height === height : true; + const areWidthsEqual = width ? current.width === width : true; + const areLeftsEqual = requested.left ? current.left === requested.left : true; + const areTopsEqual = requested.top ? current.top === requested.top : true; + return areHeightsEqual && areWidthsEqual && areLeftsEqual && areTopsEqual; + } + swapUndefinedToNull(context) { + try { + const copy = {}; + for (const key of Object.keys(context)) { + let value = context[key]; + if (typeof value === "undefined") { + value = null; + } + copy[key] = value; + } + return copy; + } + catch { + return context; + } + } + showPopupCore(id, options) { + if (!options) { + throw new Error("The options object is not valid!"); + } + const optionsCopy = { ...options }; + if (!optionsCopy.targetLocation) { + optionsCopy.targetLocation = "bottom"; + } + const reformatedOptions = { + ...optionsCopy, + popupBounds: optionsCopy.size, + targetId: id, + popupId: optionsCopy.windowId + }; + return reformatedOptions; + } + } + var executor = new GDExecutor(); + + class GDEnvironment { + constructor(agm, logger, appManagerGetter, displayAPIGetter, channelsAPIGetter, wndId, groupId) { + this._registry = CallbackRegistryFactory(); + this._agm = agm; + this._logger = logger.subLogger("gd-env"); + this._windowId = wndId; + this._groupId = groupId; + this._appManagerGetter = appManagerGetter; + this._displayAPIGetter = displayAPIGetter; + this._channelsAPIGetter = channelsAPIGetter; + } + init() { + return new Promise((resolve, reject) => { + this._agm.register("T42.Wnd.OnEventWithResponse", (args, caller) => { + return this.respondToEvent(args); + }); + new Promise((streamResolve, streamReject) => { + this._agm.subscribe("T42.Wnd.OnEvent", { + target: "best", + arguments: { + withConfig: true + }, + onData: (streamData) => { + if (streamData.data.type === "Configuration") { + this._configuration = streamData.data; + executor.setConfiguration(this._configuration); + return; + } + this.updateWindow(streamData.data, resolve); + executor.handleEvent(streamData.data); + }, + onConnected: (instance) => { + this._agmInstance = instance; + executor.init(this._agm, this._agmInstance); + } + }).catch((error) => { + var _a; + const message = `${(_a = error === null || error === void 0 ? void 0 : error.method) === null || _a === void 0 ? void 0 : _a.name} - ${JSON.stringify(error === null || error === void 0 ? void 0 : error.called_with)} - ${error === null || error === void 0 ? void 0 : error.message}`; + reject(new Error(message)); + }); + }); + }); + } + get executor() { + return executor; + } + open(name, url, options) { + options = options || {}; + const copyOptions = { ...options }; + if (copyOptions.relativeTo !== undefined && typeof copyOptions.relativeTo !== "string") { + copyOptions.relativeTo = copyOptions.relativeTo.id || ""; + } + copyOptions.name = name; + copyOptions.url = url; + copyOptions.windowState = options.windowState || options.state; + delete copyOptions.state; + return this.executor.open(copyOptions); + } + createFlydown(windowId, options) { + return this.executor.createFlydown(windowId, options); + } + async showPopup(windowId, options) { + const window = windowStore.get(windowId); + await this.executor.showPopup(window.API, options); + } + tabAttached(callback) { + return this._registry.add("tab-attached", callback); + } + tabDetached(callback) { + return this._registry.add("tab-detached", callback); + } + onWindowFrameColorChanged(callback) { + return this._registry.add("frame-color-changed", callback); + } + onEvent(callback) { + return this._registry.add("window-event", callback); + } + my() { + return this._windowId; + } + myGroup() { + return this._groupId; + } + onCompositionChanged(callback) { + return this._registry.add("composition-changed", callback); + } + onGroupHeaderVisibilityChanged(callback) { + return this._registry.add("group-header-changed", callback); + } + onGroupVisibilityChanged(callback) { + return this._registry.add("group-visibility-changed", callback); + } + onGroupStateChanged(callback) { + return this._registry.add("group-state-changed", callback); + } + onWindowGotFocus(callback) { + return this._registry.add("got-focus", callback); + } + onWindowLostFocus(callback) { + return this._registry.add("lost-focus", callback); + } + onWindowsAutoArrangeChanged(callback) { + return this._registry.add("windows-auto-arranged-changed", callback); + } + respondToEvent(args) { + if (args.type === "ShowFlydownBoundsRequested") { + return this.executor.handleFlydownBoundsRequested(args.data.windowId, args.data); + } + else if (args.type === "OnClosing" || args.type === "OnRefreshing" || args.type === "OnNavigating") { + return this.executor.handleOnEventRequested(args.data.callbackId, args.data.args); + } + return Promise.reject(`There isn't a handler for ${args.type}`); + } + updateWindow(windowInfo, readyResolve) { + const extendedStreamEvent = this.getExtendedStreamEvent(windowInfo); + if (windowInfo.type === "Snapshot") { + const windowInfoFullInfoEvent = windowInfo; + windowInfoFullInfoEvent.windows.forEach((w) => { + const existingWindow = windowStore.get(w.id); + if (existingWindow) { + existingWindow.Events.handleUpdate(this.mapToWindowConstructorOptions(w)); + existingWindow.GroupCreationArgs = this.mapToGroupCreationArgs(w); + } + else { + this.createWindowFromSnapshot(w.id, w); + } + this._registry.execute("window-event", extendedStreamEvent); + }); + readyResolve(this); + return; + } + if (windowInfo.type === "CommandExecuted") { + this._registry.execute("window-event", extendedStreamEvent); + return; + } + if (windowInfo.type === "Created") { + const windowInfoCreatedEvent = (windowInfo); + this.createWindowFromStream(windowInfoCreatedEvent.windowId, windowInfoCreatedEvent.data || {}); + this._registry.execute("window-event", extendedStreamEvent); + return; + } + if (windowInfo.type === "OnGroupVisibilityChanged") { + const info = windowInfo; + this._registry.execute("group-visibility-changed", info.data); + this._registry.execute("window-event", windowInfo); + return; + } + if (windowInfo.type === "OnGroupStateChanged") { + const info = windowInfo; + this._registry.execute("group-state-changed", info.data); + this._registry.execute("window-event", windowInfo); + return; + } + if (windowInfo.type === "OnWindowsAutoArrangeChanged") { + const info = windowInfo; + this._registry.execute("windows-auto-arranged-changed", info.data); + this._registry.execute("window-event", windowInfo); + return; + } + const windowObjectAndEvents = windowStore.get((windowInfo).windowId); + if (!windowObjectAndEvents) { + this._logger.error(`received update for unknown window. Stream:', ${JSON.stringify(windowInfo, null, 4)}`); + return; + } + const theWindow = windowObjectAndEvents.API; + const theWindowEvents = windowObjectAndEvents.Events; + if (windowInfo.type === "BoundsChanged") { + const windowInfoBoundsChangedEvent = windowInfo; + theWindowEvents.handleBoundsChanged(windowInfoBoundsChangedEvent.data); + } + if (windowInfo.type === "UrlChanged") { + const windowInfoUrlChangedEvent = windowInfo; + windowStore.setUrlChangedState(windowInfoUrlChangedEvent.windowId); + theWindowEvents.handleUrlChanged(windowInfoUrlChangedEvent.data); + } + if (windowInfo.type === "TitleChanged") { + const windowInfoTitleChanged = windowInfo; + theWindowEvents.handleTitleChanged(windowInfoTitleChanged.data); + } + if (windowInfo.type === "IsStickyChanged") { + const windowInfoIsStickyChangedChanged = windowInfo; + theWindowEvents.handleIsStickyChanged(windowInfoIsStickyChangedChanged.data); + } + if (windowInfo.type === "VisibilityChanged") { + theWindowEvents.handleVisibilityChanged(windowInfo.data); + } + if (windowInfo.type === "ContextChanged") { + theWindowEvents.handleContextUpdated(windowInfo.data); + } + if (windowInfo.type === "StateChanged") { + theWindowEvents.handleWindowChangeState(windowInfo.data); + } + if (windowInfo.type === "FrameColorChanged") { + theWindowEvents.handleFrameColorChanged(windowInfo.data); + this._registry.execute("frame-color-changed", theWindow); + } + if (windowInfo.type === "CompositionChanged") { + const windowInfoCompositionChanged = windowInfo; + theWindowEvents.handleCompositionChanged(windowInfoCompositionChanged.data); + windowStore.setCompositionChangedState(windowObjectAndEvents); + this._registry.execute("composition-changed", windowInfoCompositionChanged.data); + } + if (windowInfo.type === "GroupHeaderVisibilityChanged") { + const info = windowInfo; + theWindowEvents.handleGroupHeaderVisibilityChanged(info.data.groupHeaderVisible); + this._registry.execute("group-header-changed", info.data); + } + if (windowInfo.type === "FocusChanged") { + const windowInfoFocusChanged = windowInfo; + this.focusChanged(theWindowEvents, theWindow, windowInfoFocusChanged.data); + } + if (windowInfo.type === "WindowFrameChanged") { + theWindowEvents.handleFrameAttached(windowInfo.data.frameId, windowInfo.data.frameId, windowInfo.data.isTabHeaderVisible); + this._registry.execute("frame-changed"); + } + if (windowInfo.type === "WindowFrameAdded") { + const winsToBeNotified = getWindowsByTabGroupId(theWindow.id, windowInfo.data.frameId); + const data = windowInfo.data; + theWindowEvents.handleAttached(data.frameId, data.frameId, data.isTabHeaderVisible, data.isLocked, winsToBeNotified) + .then(async () => { + if (winsToBeNotified.length > 0) { + await executor.finished; + this._registry.execute("tab-attached", theWindow, windowInfo.data.frameId, windowInfo.data.isTabHeaderVisible); + } + }); + } + if (windowInfo.type === "WindowFrameRemoved") { + const oldTabGroupId = theWindow.tabGroupId; + const winsToBeNotified = getWindowsByTabGroupId(theWindow.id, oldTabGroupId); + theWindowEvents.handleDetached(windowInfo.data.isLocked, winsToBeNotified) + .then(async () => { + if (winsToBeNotified.length > 0) { + await executor.finished; + this._registry.execute("tab-detached", theWindow, windowInfo.data.frameId, theWindow.tabGroupId); + } + }); + } + if (windowInfo.type === "TabHeaderVisibilityChanged") { + theWindowEvents.handleTabHeaderVisibilityChanged(windowInfo.data.isTabHeaderVisible); + } + if (windowInfo.type === "FrameSelectionChanged") { + theWindowEvents.handleFrameSelectionChanged(windowInfo.data.newWindowId, windowInfo.data.prevWindowId); + } + if (windowInfo.type === "ButtonClicked") { + theWindowEvents.handleFrameButtonClicked(windowInfo.data); + } + if (windowInfo.type === "ButtonAdded") { + theWindowEvents.handleFrameButtonAdded(windowInfo.data); + } + if (windowInfo.type === "ButtonRemoved") { + theWindowEvents.handleFrameButtonRemoved(windowInfo.data); + } + if (windowInfo.type === "WindowZoomFactorChanged") { + theWindowEvents.handleZoomFactorChanged(windowInfo.data); + } + if (windowInfo.type === "Closed") { + windowStore.remove(windowObjectAndEvents); + theWindowEvents.handleWindowClose(); + } + if (windowInfo.type === "FrameIsLockedChanged") { + theWindowEvents.handleFrameIsLockedChanged(windowInfo.data); + } + if (windowInfo.type === "PlacementSettingsChanged") { + theWindowEvents.handlePlacementSettingsChanged(windowInfo.data); + } + if (windowInfo.type === "DockingChanged") { + theWindowEvents.handleDockingChanged(windowInfo.data); + } + if (windowInfo.type === "AllowWorkspaceDropChanged") { + theWindowEvents.handleAllowWorkspaceDropChanged(windowInfo.data); + } + if (windowInfo.type === "IsPinnedChanged") { + theWindowEvents.handleIsPinnedChanged(windowInfo.data); + } + if (windowInfo.type === "WindowChannelRestrictionsChanged") { + theWindowEvents.handleChannelRestrictionsChanged(windowInfo.data); + } + this._registry.execute("window-event", extendedStreamEvent); + } + createWindowFromSnapshot(windowId, options) { + const windowObjAndEvents = this.createWindowCore(windowId, options); + windowStore.add(windowObjAndEvents, { + ready: true, + urlChanged: true, + compositionChanged: true + }); + } + createWindowFromStream(windowId, options) { + var _a; + const windowObjAndEvents = this.createWindowCore(windowId, options); + const isRemote = windowObjAndEvents.API.windowType === "remote"; + const isFrameless = windowObjAndEvents.API.windowType === "electron" && windowObjAndEvents.API.mode === "frameless"; + const isHidden = windowObjAndEvents.API.isVisible === false; + let urlChanged = false; + let compositionChanged = false; + if (isRemote) { + urlChanged = true; + } + if (isFrameless || isHidden) { + compositionChanged = true; + } + if (!isRemote) { + urlChanged = !((_a = this._configuration) === null || _a === void 0 ? void 0 : _a.windowAvailableOnURLChanged); + } + windowStore.add(windowObjAndEvents, { + ready: true, + urlChanged, + compositionChanged + }); + } + createWindowCore(windowId, options) { + const windowObjAndEvents = windowFactory(windowId, this.mapToWindowConstructorOptions(options), executor, this._logger, this._appManagerGetter, this._displayAPIGetter, this._channelsAPIGetter, this._agm); + windowObjAndEvents.GroupCreationArgs = this.mapToGroupCreationArgs(options); + return windowObjAndEvents; + } + async focusChanged(theWindowEvents, theWindow, focus) { + theWindowEvents.handleFocusChanged(focus); + try { + if (!this._configuration.windowAvailableOnURLChanged) { + await windowStore.waitFor(theWindow.id); + } + } + catch (error) { + return; + } + if (focus) { + this._registry.execute("got-focus", theWindow); + } + else { + this._registry.execute("lost-focus", theWindow); + } + } + mapToWindowConstructorOptions(args) { + return { + name: args.name, + context: args.context, + bounds: args.bounds, + url: args.url, + title: args.title, + isVisible: args.isVisible, + focus: args.isFocused, + state: args.state, + frameColor: args.frameColor, + groupId: args.groupId, + neighbours: args.neighbors, + isFocused: args.isFocused, + isGroupHeaderVisible: args.groupHeaderVisible, + isCollapsed: args.isCollapsed, + tabGroupId: args.frameId, + frameId: args.frameId, + mode: args.mode, + isTabHeaderVisible: args.isTabHeaderVisible, + isTabSelected: args.isActiveTab, + settings: args.settings, + windowType: args.windowType, + zoomFactor: args.zoomFactor, + isLocked: args.isLocked, + placementSettings: args.placementSettings, + isSticky: args.isSticky, + tabIndex: args.tabIndex, + frameButtons: args.frameButtons, + jumpListOptions: args.jumpList, + applicationName: args.applicationName, + allowWorkspaceDrop: args.allowWorkspaceDrop, + isPinned: args.isPinned + }; + } + mapToGroupCreationArgs(args) { + return { + isGroupHibernated: args.isGroupHibernated, + isGroupVisible: args.isGroupVisible + }; + } + getExtendedStreamEvent(streamEvent) { + try { + if (!streamEvent.windowId) { + return streamEvent; + } + const window = windowStore.get(streamEvent.windowId); + if (!window) { + return streamEvent; + } + const result = { + state: streamEvent.type, + windowName: window.API.name, + ...streamEvent + }; + if (result.state === "WindowFrameAdded") { + result.state = "TabAttached"; + } + if (result.state === "StateChanged") { + result.state = result.data.charAt(0).toUpperCase() + result.data.slice(1); + } + if (result.state === "ButtonAdded") { + result.state = "FrameButtonAdded"; + } + if (result.state === "ButtonRemoved") { + result.state = "FrameButtonRemoved"; + } + return result; + } + catch (error) { + return streamEvent; + } + } + } + + var envDetector = (agm, logger, appManagerGetter, displayAPIGetter, channelsAPIGetter, gdMajorVersion) => { + var _a; + const _logger = logger; + if (gdMajorVersion === 2) { + _logger.trace("running in HC"); + throw new Error("GD2 not supported"); + } + else if (gdMajorVersion >= 3) { + _logger.trace("running in GD 3"); + return new GDEnvironment(agm, _logger, appManagerGetter, displayAPIGetter, channelsAPIGetter, window.glue42gd.windowId, (_a = window.webGroupsManager) === null || _a === void 0 ? void 0 : _a.id).init(); + } + else { + _logger.trace("running in Browser or Node"); + return new GDEnvironment(agm, _logger, appManagerGetter, displayAPIGetter, channelsAPIGetter).init(); + } + }; + + var groupFactory = (id, executor) => { + const _registry = CallbackRegistryFactory(); + const _windowsId = []; + let _isHibernatedFlag; + let _isVisible; + async function addWindow(winId) { + var _a, _b, _c, _d; + if (_windowsId.indexOf(winId) === -1) { + _windowsId.push(winId); + const win = windowStore.get(winId); + win.Events.handleGroupChanged(groupObject, undefined); + _isHibernatedFlag = (_b = (_a = win.GroupCreationArgs.isGroupHibernated) !== null && _a !== void 0 ? _a : _isHibernatedFlag) !== null && _b !== void 0 ? _b : false; + _isVisible = (_d = (_c = win.GroupCreationArgs.isGroupVisible) !== null && _c !== void 0 ? _c : _isVisible) !== null && _d !== void 0 ? _d : true; + await executor.finished; + _registry.execute("window-added", groupObject, win.API); + } + } + async function removeWindow(win) { + const index = _windowsId.indexOf(win.API.id); + if (index !== -1) { + _windowsId.splice(index, 1); + win.Events.handleGroupChanged(undefined, groupObject); + await executor.finished; + _registry.execute("window-removed", groupObject, win.API); + } + } + function find(window, success, error) { + let winId; + if (typeof window === "string") { + winId = window; + } + else if (!isUndefinedOrNull(window)) { + winId = window.id; + } + const win = _mapToWindowObject(winId); + if (win) { + if (typeof success === "function") { + success(win); + } + return win; + } + else { + if (typeof error === "function") { + error(`No window with ID: ${winId}`); + } + } + } + function windows(success) { + const mappedWindows = _mapToWindowObjects(); + return mappedWindows; + } + async function execute(command, options, ...keys) { + await executor.execute(command, options, ...keys); + return groupObject; + } + function handleGroupHeaderVisibilityChanged(windowInfo) { + _registry.execute("header-visibility-changed", groupObject); + } + function handleGroupVisibilityChanged(visibile) { + _isVisible = visibile; + _registry.execute("group-visibility-changed", groupObject); + } + function handleGroupHibernateChanged(isHibernatedFlag) { + _isHibernatedFlag = isHibernatedFlag; + } + function _mapToWindowObjects() { + const winObjects = []; + _windowsId.forEach((winId) => { + const windowObject = _mapToWindowObject(winId); + if (typeof windowObject !== "undefined") { + winObjects.push(windowObject); + } + }); + return winObjects; + } + function _mapToWindowObject(windowId) { + return windowStore.get(windowId) ? windowStore.get(windowId).API : undefined; + } + function _getGroupHeaderVisibility() { + const windowWithHiddenHeader = _mapToWindowObjects().find((w) => !w.isGroupHeaderVisible); + const _isGroupHeaderVisible = windowWithHiddenHeader === undefined; + return _isGroupHeaderVisible; + } + function isHibernated() { + return _isHibernatedFlag; + } + function onHeaderVisibilityChanged(callback) { + return _registry.add("header-visibility-changed", callback); + } + function onWindowAdded(callback) { + return _registry.add("window-added", callback); + } + function onWindowRemoved(callback) { + return _registry.add("window-removed", callback); + } + function onVisibilityChanged(callback) { + if (!callback) { + throw new Error("Callback argument is required"); + } + if (callback && typeof callback !== "function") { + throw new Error("Callback argument must be a function"); + } + return _registry.add("group-visibility-changed", callback); + } + function onClosing(callback) { + if (typeof callback !== "function") { + throw new Error("callback must be a function"); + } + const callbackWrap = (success, error, prevent) => { + const promise = callback(prevent); + if (promise === null || promise === void 0 ? void 0 : promise.then) { + promise.then(success).catch(error); + } + else { + success(); + } + }; + return executor.onGroupClosing(callbackWrap, groupObject); + } + const groupObject = { + id, + get windows() { + return windows(); + }, + find, + get isHeaderVisible() { + return _getGroupHeaderVisibility(); + }, + get isHibernated() { + return isHibernated(); + }, + get isVisible() { + return _isVisible; + }, + showHeader: (success, error) => { + return Utils.callbackifyPromise(() => { + return execute("setGroupHeaderVisibility", { windowId: _windowsId[0], options: { toShow: true } }, ..._windowsId.map((w) => `GroupHeaderVisibilityChanged-${w}`)); + }, success, error); + }, + hideHeader: (success, error) => { + return Utils.callbackifyPromise(() => { + return execute("setGroupHeaderVisibility", { windowId: _windowsId[0], options: { toShow: false } }, ..._windowsId.map((w) => `GroupHeaderVisibilityChanged-${w}`)); + }, success, error); + }, + getTitle: async () => { + const r = await executor.execute("getGroupTitle", { windowId: _windowsId[0] }); + return r.title; + }, + setTitle: async (title) => { + if (isNullOrWhiteSpace(title)) { + throw new Error("`title` must not be null or undefined."); + } + return execute("setGroupTitle", { windowId: _windowsId[0], options: { title } }); + }, + capture: (captureOptions) => { + return executor.captureGroup(_windowsId, captureOptions); + }, + maximize: (success, error) => { + return Utils.callbackifyPromise(() => { + return execute("maximizeGroup", { windowId: _windowsId[0] }, ..._windowsId.map((w) => `StateChanged-${w}`)); + }, success, error); + }, + restore: (success, error) => { + return Utils.callbackifyPromise(() => { + return execute("restoreGroup", { windowId: _windowsId[0] }, ..._windowsId.map((w) => `StateChanged-${w}`)); + }, success, error); + }, + show: (activate) => { + if (!isUndefinedOrNull(activate) && !isBoolean(activate)) { + throw new Error("Activate flag must be a boolean!"); + } + activate = !isUndefinedOrNull(activate) ? activate : true; + return executor.executeGroup("showGroup", { + groupId: id, + options: { activate } + }); + }, + hide: () => { + return executor.executeGroup("hideGroup", { + groupId: id + }); + }, + close: () => { + return executor.executeGroup("closeGroup", { + groupId: id + }); + }, + showPopup: (options) => { + return executor.showGroupPopup(id, options); + }, + onHeaderVisibilityChanged, + onWindowAdded, + onWindowRemoved, + onVisibilityChanged, + onClosing, + }; + const internal = { + get windows() { + return _windowsId; + }, + addWindow, + removeWindow, + handleGroupHeaderVisibilityChanged, + handleGroupVisibilityChanged, + handleGroupHibernateChanged + }; + return { + groupAPI: groupObject, + groupInternal: internal, + }; + }; + + var groupsFactory = (environment, logger) => { + const _registry = CallbackRegistryFactory(); + const _groups = {}; + let heardForWindowsCounter = -1; + const windows = windowStore.list; + Object.keys(windows).forEach((k) => { + const win = windows[k]; + const groupId = win.API.groupId; + const winId = win.API.id; + if (!isNullOrWhiteSpace(groupId)) { + addWindow(groupId, winId); + } + }); + windowStore.onRemoved((w) => { + const group = findGroupWrapperByWindow(w.API); + removeWindow(group, w); + }); + environment.onCompositionChanged((windowInfo) => { + handleCompositionChanged(windowInfo); + }); + environment.onGroupHeaderVisibilityChanged((windowInfo) => { + const windowId = windowInfo.windowId; + const group = findGroupByWindow(windowId); + if (typeof group !== "undefined") { + const groupEvents = _groups[group.id]; + if (heardForWindowsCounter === -1) { + heardForWindowsCounter = group.windows.length; + } + heardForWindowsCounter--; + if (heardForWindowsCounter === 0) { + heardForWindowsCounter = -1; + groupEvents.groupInternal.handleGroupHeaderVisibilityChanged(windowInfo); + } + } + }); + environment.onGroupVisibilityChanged((data) => { + const groupEvents = _groups[data.groupId]; + if (groupEvents) { + groupEvents.groupInternal.handleGroupVisibilityChanged(data.visible); + } + }); + environment.onGroupStateChanged((data) => { + const groupWrapper = _groups[data.groupId]; + if (data.state === "hibernated") { + if (groupWrapper === null || groupWrapper === void 0 ? void 0 : groupWrapper.groupAPI) { + groupWrapper.groupInternal.handleGroupHibernateChanged(true); + } + _registry.execute("group-hibernated", data.groupId); + } + else if (data.state === "resumed") { + if (groupWrapper === null || groupWrapper === void 0 ? void 0 : groupWrapper.groupAPI) { + groupWrapper.groupInternal.handleGroupHibernateChanged(false); + } + _registry.execute("group-resumed", groupWrapper.groupAPI); + } + }); + function my() { + var _a; + return findGroupByWindow((_a = environment.myGroup()) !== null && _a !== void 0 ? _a : environment.my()); + } + async function create(options) { + if (isUndefinedOrNull(options)) { + throw new Error(`options must be defined`); + } + if (isUndefinedOrNull(options.groups) || !Array.isArray(options.groups) || options.groups.length === 0) { + throw new Error(`options.groups must be defined`); + } + const { groupIds } = await executor.executeGroup("createGroups", { + options + }); + const groups = groupIds.map((groupId) => { + return waitForGroup(groupId); + }); + return Promise.all(groups); + } + async function close(idOrGroup, options) { + if (isUndefinedOrNull(idOrGroup)) { + throw new Error(`group must be defined`); + } + let groupId = ""; + if (typeof idOrGroup === "string") { + groupId = idOrGroup; + } + else { + groupId = idOrGroup.id; + } + if (isUndefinedOrNull(options)) { + throw new Error(`options must be defined`); + } + await executor.executeGroup("closeGroup", { + groupId, + options + }); + } + function list(success) { + const result = Object.keys(_groups).map((groupId) => { + if (_groups[groupId]) { + return _groups[groupId].groupAPI; + } + }); + if (typeof success === "function") { + success(result); + } + return result; + } + function findGroupByWindow(winId, success, error) { + let windowId; + if (typeof winId === "string") { + windowId = winId; + } + else if (!isUndefinedOrNull(winId)) { + windowId = winId.id; + } + const result = Object.values(_groups).find((groupObj) => { + const group = groupObj.groupAPI; + const wins = group.windows.filter((w) => w.id === windowId); + return wins.length; + }); + if (result) { + if (typeof success === "function") { + success(result.groupAPI); + } + return result.groupAPI; + } + else if (typeof error === "function") { + error(`Cannot find the group of the window.`); + } + } + function waitForGroup(groupId) { + if (!groupId) { + return Promise.reject(new Error(`groupId must be defined`)); + } + return new Promise((res, rej) => { + const groupWrapper = _groups[groupId]; + if (groupWrapper) { + res(groupWrapper.groupAPI); + } + else { + const un = onGroupAdded((group) => { + if (group.id === groupId) { + un(); + res(group); + } + }); + } + }); + } + function getMyGroup() { + var _a; + return waitForGroup((_a = environment.myGroup()) !== null && _a !== void 0 ? _a : environment.my()); + } + async function resume(groupId, activate) { + validateGroupIdArg(groupId); + if (!isUndefinedOrNull(activate) && !isBoolean(activate)) { + throw new Error("Activate flag must be a boolean!"); + } + activate = !isUndefinedOrNull(activate) ? activate : true; + await executor.executeGroup("resumeGroup", { + groupId, + options: { activate } + }); + } + async function hibernate(groupId) { + validateGroupIdArg(groupId); + await executor.executeGroup("hibernateGroup", { + groupId + }); + return groupId; + } + function onGroupAdded(callback) { + return _registry.add("group-added", callback); + } + function onGroupRemoved(callback) { + return _registry.add("group-removed", callback); + } + function onWindowMoved(callback) { + return _registry.add("window-moved", callback); + } + function onHibernated(callback) { + if (!callback) { + throw new Error("Callback argument is required"); + } + if (callback && typeof callback !== "function") { + throw new Error("Callback argument must be a function"); + } + return _registry.add("group-hibernated", callback); + } + function onResumed(callback) { + if (!callback) { + throw new Error("Callback argument is required"); + } + if (callback && typeof callback !== "function") { + throw new Error("Callback argument must be a function"); + } + return _registry.add("group-resumed", callback); + } + function createOrGet(groupId) { + if (!_groups.hasOwnProperty(groupId)) { + const createdGroupWrapper = groupFactory(groupId, environment.executor); + _groups[groupId] = createdGroupWrapper; + const group = createdGroupWrapper.groupAPI; + _registry.execute("group-added", group); + return createdGroupWrapper; + } + else { + return _groups[groupId]; + } + } + function deleteIfEmpty(groupWrapper) { + const group = groupWrapper.groupAPI; + if (group.windows.length === 0) { + delete _groups[group.id]; + executor.clearCallbacks(group.id); + _registry.execute("group-removed", group); + } + } + function addWindow(groupId, winId) { + const group = createOrGet(groupId); + group.groupInternal.addWindow(winId); + return group; + } + function removeWindow(group, win) { + if (!group) { + return; + } + group.groupInternal.removeWindow(win); + deleteIfEmpty(group); + } + function handleCompositionChanged(state) { + const groupId = state.groupId; + const windowId = state.windowId; + const win = windowStore.get(windowId); + if (!win) { + return; + } + const currentGroup = findGroupWrapperByWindow(win.API); + if (isUndefinedOrNull(groupId)) { + removeWindow(currentGroup, win); + return; + } + if (isUndefinedOrNull(currentGroup) && !isUndefinedOrNull(groupId)) { + addWindow(groupId, win.API.id); + return; + } + if (currentGroup.groupAPI.id !== groupId) { + moveWindow(win, currentGroup.groupAPI.id, groupId); + } + } + function moveWindow(win, from, to) { + const winId = win.API.id; + const fromGroup = _groups[from]; + removeWindow(fromGroup, win); + const toGroup = addWindow(to, winId); + win.Events.handleGroupChanged(toGroup.groupAPI, fromGroup.groupAPI); + _registry.execute("window-moved", winId, from, to); + } + function findGroupWrapperByWindow(winId) { + let windowId; + if (typeof winId === "string") { + windowId = winId; + } + else if (!isUndefinedOrNull(winId)) { + windowId = winId.id; + } + return Object.values(_groups).find((groupObj) => { + const groupInternal = groupObj.groupInternal; + const wins = groupInternal.windows.filter((id) => id === windowId); + return wins.length; + }); + } + function validateGroupIdArg(groupId) { + if (!groupId || typeof groupId !== "string") { + throw new Error("Please provide a valid Group ID as a non-empty string!"); + } + } + const groups = { + get my() { + return my(); + }, + create, + close, + list, + findGroupByWindow, + waitForGroup, + getMyGroup, + onGroupAdded, + onGroupRemoved, + hibernate, + resume, + onHibernated, + onResumed + }; + const events = { onWindowMoved }; + return { + groupsAPI: groups, + groupsEvents: events, + }; + }; + + var WindowsFactory = (agm, logger, appManagerGetter, displayAPIGetter, channelsGetter, gdMajorVersion) => { + const _registry = CallbackRegistryFactory(); + const _logger = logger; + let groups; + let environment; + windowStore.init(_logger); + const isReady = new Promise((resolve, reject) => { + envDetector(agm, _logger, appManagerGetter, displayAPIGetter, channelsGetter, gdMajorVersion) + .then((env) => { + environment = env; + groups = groupsFactory(env); + jumpListManager.init(env.executor, agm, _logger); + resolve(); + }) + .catch((e) => { + const err = `Timed out waiting for connection to Glue42 Enterprise: Error: ${e.message}`; + _logger.error(err, e); + reject(new Error(err)); + }); + }); + function ready() { + return isReady; + } + function my() { + const myWindow = windowStore.getIfReady(environment.my()); + return myWindow ? myWindow.API : undefined; + } + function open(name, url, options, success, error) { + return Utils.callbackifyPromise(() => { + if (isNullOrWhiteSpace(name)) { + throw new Error("The window name is missing."); + } + if (isNullOrWhiteSpace(url)) { + throw new Error("The window URL is missing."); + } + if (!isUndefinedOrNull(options)) { + const optionsAsAny = options; + for (const prop of ["minHeight", "maxHeight", "minWidth", "maxWidth", "width", "height", "top", "left"]) { + if (prop in optionsAsAny) { + const value = optionsAsAny[prop]; + if (isUndefinedOrNull(value)) { + delete optionsAsAny[prop]; + continue; + } + if (!isNumber(value)) { + const errMessage = `${prop} must be a number`; + throw new Error(errMessage); + } + if (optionsAsAny[prop] === "width" || optionsAsAny[prop] === "height") { + if (value <= 0) { + const errMessage = `${prop} must be a positive number`; + throw new Error(errMessage); + } + } + } + } + } + return environment.open(name, url, options); + }, success, error); + } + function find(name, success, error) { + const windows = windowStore.list; + const windowsForListing = Object.keys(windows).reduce((memo, winId) => { + var _a; + const window = windows[winId]; + if (((_a = window === null || window === void 0 ? void 0 : window.API) === null || _a === void 0 ? void 0 : _a.name) === name) { + memo.push(window.API); + } + return memo; + }, []); + const win = windowsForListing[0]; + if (win) { + if (typeof success === "function") { + success(windowsForListing[0]); + } + return windowsForListing[0]; + } + else { + if (typeof error === "function") { + error("There is no window with name:" + name); + } + } + } + function findById(id, success, error) { + const windows = windowStore.list; + const windowsForListing = Object.keys(windows).reduce((memo, winId) => { + const window = windows[winId]; + if (typeof window !== "undefined" && window.API.id === id) { + memo.push(window.API); + } + return memo; + }, []); + const win = windowsForListing[0]; + if (win) { + if (typeof success === "function") { + success(windowsForListing[0]); + } + return windowsForListing[0]; + } + else { + if (typeof error === "function") { + error("There is no window with such id:" + id); + } + } + } + function list(success) { + const windows = windowStore.list; + const windowsForListing = Object.keys(windows) + .map((k) => { + return windows[k].API; + }); + if (typeof success !== "function") { + return windowsForListing; + } + success(windowsForListing); + } + function configure(options) { + const win = my(); + const winId = win ? win.id : ""; + return executor.configure(winId, options); + } + function autoArrange(displayId) { + return executor.autoArrange(displayId); + } + function windowAdded(callback) { + return _registry.add("window-added", callback); + } + function windowRemoved(callback) { + return _registry.add("window-removed", callback); + } + function tabAttached(callback) { + let unsubFunc; + let unsubscribed = false; + isReady.then(() => { + if (unsubscribed) { + return; + } + unsubFunc = environment.tabAttached(callback); + }); + return () => { + unsubscribed = true; + if (unsubFunc) { + unsubFunc(); + } + }; + } + function tabDetached(callback) { + let unsubFunc; + let unsubscribed = false; + isReady.then(() => { + if (unsubscribed) { + return; + } + unsubFunc = environment.tabDetached(callback); + }); + return () => { + unsubscribed = true; + if (unsubFunc) { + unsubFunc(); + } + }; + } + function onWindowFrameColorChanged(callback) { + let unsubFunc; + let unsubscribed = false; + isReady.then(() => { + if (unsubscribed) { + return; + } + unsubFunc = environment.onWindowFrameColorChanged(callback); + }); + return () => { + unsubscribed = true; + if (unsubFunc) { + unsubFunc(); + } + }; + } + function onWindowGotFocus(callback) { + let unsubFunc; + let unsubscribed = false; + isReady.then(() => { + if (unsubscribed) { + return; + } + unsubFunc = environment.onWindowGotFocus(callback); + }); + return () => { + unsubscribed = true; + if (unsubFunc) { + unsubFunc(); + } + }; + } + function onWindowLostFocus(callback) { + let unsubFunc; + let unsubscribed = false; + isReady.then(() => { + if (unsubscribed) { + return; + } + unsubFunc = environment.onWindowLostFocus(callback); + }); + return () => { + unsubscribed = true; + if (unsubFunc) { + unsubFunc(); + } + }; + } + function onArrangementChanged(callback) { + return environment.onWindowsAutoArrangeChanged(callback); + } + function onEvent(callback) { + let unsubFunc; + let unsubscribed = false; + isReady.then(() => { + if (unsubscribed) { + return; + } + unsubFunc = environment.onEvent(callback); + }); + return () => { + unsubscribed = true; + if (unsubFunc) { + unsubFunc(); + } + }; + } + function createFlydown(targetId, config) { + return environment.createFlydown(targetId, config); + } + function showPopup(targetId, config) { + return environment.showPopup(targetId, config); + } + function handleWindowAdded(w) { + _registry.execute("window-added", w.API); + } + function handleWindowRemoved(w) { + _registry.execute("window-removed", w.API); + } + windowStore.onReadyWindow(handleWindowAdded); + windowStore.onRemoved(handleWindowRemoved); + return { + my, + open, + find, + findById, + list, + ready, + onWindowAdded: windowAdded, + windowAdded, + onWindowRemoved: windowRemoved, + windowRemoved, + onTabAttached: tabAttached, + onTabDetached: tabDetached, + onWindowFrameColorChanged, + onArrangementChanged, + get groups() { + return groups.groupsAPI; + }, + onWindowGotFocus, + onWindowLostFocus, + onEvent, + createFlydown, + showPopup, + configure, + autoArrange + }; + }; + + class LayoutStore { + constructor() { + this.layouts = []; + } + removeWhere(condition) { + this.layouts = this.layouts.filter(condition); + } + removeAll() { + this.layouts = []; + } + add(item) { + this.layouts.push(item); + } + get all() { + return this.layouts; + } + where(condition) { + return this.layouts.filter(condition); + } + first(condition) { + return this.where(condition)[0]; + } + } + var store = new LayoutStore(); + + const SaveContextMethodName = "T42.HC.GetSaveContext"; + class ContextProvider { + constructor(config, activitiesGetter, callbacks, logger) { + this.config = config; + this.activitiesGetter = activitiesGetter; + this.callbacks = callbacks; + this.logger = logger; + this.interop = config.agm; + this.registerRequestMethods(); + } + onSaveRequested(callback) { + return this.callbacks.add("saveRequested", callback); + } + isActivityOwner() { + if (typeof htmlContainer !== "undefined") { + const context = htmlContainer.getContext(); + return context && context._t42 && context._t42.activityIsOwner; + } + const activities = this.activitiesGetter(); + if (!activities) { + return false; + } + if (!activities.inActivity) { + return false; + } + const myWindow = activities.my.window; + const myActivity = activities.my.activity; + if (!myActivity && !myWindow) { + return false; + } + return myActivity.owner.id === myWindow.id; + } + registerRequestMethods() { + this.interop.register(SaveContextMethodName, (args) => { + const usersCbs = this.callbacks.execute("saveRequested", args); + if ((usersCbs === null || usersCbs === void 0 ? void 0 : usersCbs.length) > 1) { + this.logger.warn(`Multiple subscriptions for "glue.layouts.onSaveRequested" - only the first one will be used`); + } + const requestResult = usersCbs[0]; + const autoSaveWindowContext = this.config.autoSaveWindowContext; + if (typeof autoSaveWindowContext === "boolean" && autoSaveWindowContext) { + return { autoSaveWindowContext }; + } + else if (Array.isArray(autoSaveWindowContext) && autoSaveWindowContext.length > 0) { + return { autoSaveWindowContext }; + } + const result = { windowContext: requestResult === null || requestResult === void 0 ? void 0 : requestResult.windowContext, activityContext: undefined }; + if (this.isActivityOwner()) { + result.activityContext = requestResult === null || requestResult === void 0 ? void 0 : requestResult.activityContext; + } + return result; + }); + } + } + + function transformACSLayout(something) { + if (!something) { + return something; + } + if (Array.isArray(something)) { + return something.map((item) => { + return transformACSLayout(item); + }); + } + if (typeof something === "string" || typeof something === "number" || typeof something === "boolean") { + return something; + } + const initial = {}; + return Object.keys(something).reduce((accumulator, current) => { + var _a; + const value = something[current]; + const convertedValue = transformACSLayout(value); + let key = current; + if (((_a = current[0]) === null || _a === void 0 ? void 0 : _a.toLowerCase()) !== current[0]) { + key = current[0].toLowerCase() + current.substr(1); + } + accumulator[key] = convertedValue; + return accumulator; + }, initial); + } + + class LayoutImpl { + constructor(data) { + this.name = data.name; + this.type = data.type; + this.components = data.components; + this.context = data.context; + this.metadata = data.metadata; + this.version = data.version; + this.displays = data.displays; + } + } + + var main = {}; + + var application = {}; + + /** + * This file was automatically generated by json-schema-to-typescript. + * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file, + * and run json-schema-to-typescript to regenerate this file. + */ + Object.defineProperty(application, "__esModule", { value: true }); + + var system = {}; + + /** + * This file was automatically generated by json-schema-to-typescript. + * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file, + * and run json-schema-to-typescript to regenerate this file. + */ + Object.defineProperty(system, "__esModule", { value: true }); + + var layout = {}; + + Object.defineProperty(layout, "__esModule", { value: true }); + layout.SwimlaneItemType = layout.LayoutType = void 0; + var LayoutType; + (function (LayoutType) { + LayoutType["Global"] = "Global"; + LayoutType["Activity"] = "Activity"; + LayoutType["ApplicationDefault"] = "ApplicationDefault"; + LayoutType["Swimlane"] = "Swimlane"; + LayoutType["Workspaces"] = "Workspace"; + })(LayoutType || (layout.LayoutType = LayoutType = {})); + var SwimlaneItemType; + (function (SwimlaneItemType) { + SwimlaneItemType["Tab"] = "tab"; + SwimlaneItemType["Window"] = "window"; + SwimlaneItemType["Canvas"] = "canvas"; + })(SwimlaneItemType || (layout.SwimlaneItemType = SwimlaneItemType = {})); + + var swTheme = {}; + + /** + * This file was automatically generated by json-schema-to-typescript. + * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file, + * and run json-schema-to-typescript to regenerate this file. + */ + Object.defineProperty(swTheme, "__esModule", { value: true }); + + var swConfiguration = {}; + + /** + * This file was automatically generated by json-schema-to-typescript. + * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file, + * and run json-schema-to-typescript to regenerate this file. + */ + Object.defineProperty(swConfiguration, "__esModule", { value: true }); + + (function (exports) { + var __createBinding = (commonjsGlobal && commonjsGlobal.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; + })); + var __exportStar = (commonjsGlobal && commonjsGlobal.__exportStar) || function(m, exports) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); + }; + Object.defineProperty(exports, "__esModule", { value: true }); + // export { SchemaValidator } from "./validator"; + // export { FileProvider } from "./fileProvider"; + // export { SchemaProvider } from "./provider"; + __exportStar(application, exports); + __exportStar(system, exports); + __exportStar(layout, exports); + __exportStar(swTheme, exports); + __exportStar(swConfiguration, exports); + + } (main)); + + const LayoutsCommandMethod = "T42.ACS.Command"; + class LayoutsAPIImpl { + constructor(config, stream, callbacks, logger) { + this.config = config; + this.stream = stream; + this.callbacks = callbacks; + this.isRegisterMethodForLayoutModified = false; + this.appManager = config.appManager; + this.provider = new ContextProvider(config, config.activityGetter, callbacks, logger); + stream.subscribe(); + } + async setDefaultGlobal(name) { + const methodName = "SelectDefaultLayout"; + await this.invokeMethodCore(methodName, { name }); + return; + } + async clearDefaultGlobal() { + const methodName = "DeselectDefaultLayout"; + await this.invokeMethodCore(methodName); + return; + } + async getDefaultGlobal() { + const methodName = "GetDefaultLayout"; + const result = await this.invokeMethodCore(methodName); + const layout = result.returned; + if (layout === null || layout === undefined || (typeof layout === 'object' && Object.keys(layout).length === 0)) { + return undefined; + } + return objectClone(this.isSlimMode() ? layout : this.list().find((l) => l.name === layout.name && l.type === layout.type)); + } + ready() { + if (this.config.mode === "fullWaitSnapshot") { + return this.stream.gotSnapshot; + } + return this.stream.ready; + } + save(layout) { + return new Promise((resolve, reject) => { + var _a, _b; + this.verifyNotSlimMode(); + if (isUndefinedOrNull(layout)) { + return reject(new Error("layout is required")); + } + if (isNullOrWhiteSpace(layout.name)) { + return reject(new Error("layout.name argument is required")); + } + if (isNullOrWhiteSpace(layout.type)) { + layout.type = "Global"; + } + if (!isNullOrWhiteSpace(layout.activityId)) { + layout.type = "Activity"; + } + const layoutObject = { + name: layout.name, + type: layout.type, + context: (_a = layout.context) !== null && _a !== void 0 ? _a : {}, + metadata: (_b = layout.metadata) !== null && _b !== void 0 ? _b : {}, + options: {}, + }; + if (layout.type === "Activity") { + let actId = layout.activityId; + if (!actId) { + if (!this.appManager.myInstance.inActivity) { + return reject(new Error("Current application is not in activity. Cannot save activity layout for it.")); + } + actId = this.appManager.myInstance.activityId; + } + layoutObject.activityId = actId; + } + else if (layout.type === "Global") { + if (Array.isArray(layout.ignoreInstances)) { + layoutObject.options.ignoreInstances = layout.ignoreInstances; + } + if (Array.isArray(layout.instances)) { + layoutObject.options.instances = layout.instances; + } + if (typeof layout.setAsCurrent === "boolean") { + layoutObject.options.setAsCurrent = layout.setAsCurrent; + } + } + else { + return reject(new Error(`layout type ${layout.type} is not supported`)); + } + this.invokeMethodAndTrack("SaveLayout", layoutObject, resolve, reject); + }); + } + restore(options) { + return new Promise((resolve, reject) => { + var _a, _b, _c; + this.verifyNotSlimMode(); + if (isUndefinedOrNull(options)) { + return reject(new Error("options argument is required")); + } + if (isNullOrWhiteSpace(options.name)) { + return reject(new Error("options.name argument is required")); + } + if (isNullOrWhiteSpace(options.type)) { + options.type = "Global"; + } + if (!isNullOrWhiteSpace(options.activityIdToJoin)) { + options.type = "Activity"; + } + if (options.type === "Activity") { + if (isUndefinedOrNull(options.setActivityContext)) { + options.setActivityContext = true; + } + if (typeof options.setActivityContext !== "boolean") { + return reject(new Error("`setActivityContext` must hold a boolean value.")); + } + options.activityIdToJoin = (_a = options.activityIdToJoin) !== null && _a !== void 0 ? _a : this.appManager.myInstance.activityId; + } + if (!isUndefinedOrNull(options.closeRunningInstance)) { + options.closeRunningInstances = options.closeRunningInstance; + } + if (isUndefinedOrNull(options.closeRunningInstances)) { + options.closeRunningInstances = true; + } + if (!isBoolean(options.closeRunningInstances)) { + return reject(new Error("`closeRunningInstances` must hold a boolean value.")); + } + if (isUndefinedOrNull(options.closeMe)) { + options.closeMe = options.closeRunningInstances; + } + if (!isBoolean(options.closeMe)) { + return reject(new Error("`closeMe` must hold a boolean value.")); + } + if (!isUndefinedOrNull(options.context) && !isObject(options.context)) { + return reject(new Error("`context` must hold an object value.")); + } + if (!isUndefinedOrNull(options.timeout) && typeof options.timeout !== "number") { + return reject(new Error("`timeout` must hold an number value.")); + } + options.context = (_b = options.context) !== null && _b !== void 0 ? _b : {}; + const restoreOptions = { + activityToJoin: options.activityIdToJoin, + setActivityContext: options.setActivityContext, + ignoreActivityWindowTypes: options.ignoreActivityWindowTypes, + reuseExistingWindows: options.reuseWindows, + closeRunningInstances: options.closeRunningInstances, + excludeFromClosing: options.closeMe ? [] : [(_c = this.appManager.myInstance) === null || _c === void 0 ? void 0 : _c.id] + }; + const arg = { + type: options.type, + name: options.name, + context: options.context, + options: restoreOptions + }; + if (options.timeout) { + arg.timeout = options.timeout; + } + this.invokeMethodAndTrack("RestoreLayout", arg, resolve, reject, true); + }); + } + reset(options) { + return new Promise((resolve, reject) => { + this.verifyNotSlimMode(); + if (typeof options !== "object") { + return reject(new Error("options argument is required")); + } + if (isNullOrWhiteSpace(options.layoutId)) { + return reject(new Error("options.layoutId argument is required")); + } + const msg = { + ...options + }; + this.invokeMethodAndTrack("ResetLayout", msg, resolve, reject, true); + }); + } + remove(type, name) { + return new Promise((resolve, reject) => { + this.verifyNotSlimMode(); + if (!name) { + return reject(new Error("name argument is required")); + } + if (!type) { + return reject(new Error("type argument is required")); + } + const msg = { + type, + name, + }; + this.invokeMethodAndTrack("RemoveLayout", msg, resolve, reject); + }); + } + list() { + this.verifyNotSlimMode(); + return objectClone(store.all); + } + import(layouts, mode) { + return new Promise((resolve, reject) => { + this.verifyNotSlimMode(); + if (!isUndefinedOrNull(mode)) { + if (mode !== "merge" && mode !== "replace") { + return reject(new Error(`${mode} is not supported - only "merge" and "replace"`)); + } + } + if (!Array.isArray(layouts)) { + return reject(new Error("layouts arguments is not an array")); + } + const msg = { + mode: mode || "replace", + layouts + }; + this.invokeMethodAndTrack("ImportLayouts", msg, resolve, reject, true); + }); + } + export(layoutType) { + return new Promise((resolve, reject) => { + var _a; + if (!isUndefinedOrNull(layoutType) && !((_a = Object.values(main.LayoutType)) === null || _a === void 0 ? void 0 : _a.includes(layoutType))) { + return reject(new Error(`${layoutType} is not a supported Layout Type`)); + } + const handleResult = (result) => { + let layouts = this.getObjectValues(result.Layouts).map((t) => new LayoutImpl(transformACSLayout(t))); + if (layoutType) { + layouts = layouts.filter((l) => l.type === layoutType); + } + resolve(layouts); + }; + this.invokeMethodAndTrack("ExportLayouts", {}, handleResult, reject, true); + }); + } + rename(layout, newName) { + return new Promise((resolve, reject) => { + this.verifyNotSlimMode(); + if (!layout) { + return reject(new Error("layout argument is required")); + } + if (!layout.name) { + return reject(new Error("name argument is required")); + } + if (!layout.type) { + return reject(new Error("type argument is required")); + } + const msg = { type: layout.type, oldName: layout.name, newName }; + this.invokeMethodAndTrack("RenameLayout", msg, resolve, reject); + }); + } + updateMetadata(layout) { + return new Promise((resolve, reject) => { + if (!layout) { + return reject(new Error("layout argument is required")); + } + if (!layout.name) { + return reject(new Error("name argument is required")); + } + if (!layout.type) { + return reject(new Error("type argument is required")); + } + if (!layout.metadata) { + return reject(new Error("metadata argument is required")); + } + const layoutObject = { + name: layout.name, + type: layout.type, + metadata: layout.metadata + }; + this.invokeMethodAndTrack("UpdateMetadata", layoutObject, resolve, reject, true); + }); + } + hibernate(name, options) { + return new Promise((resolve, reject) => { + if (!name) { + return reject(new Error("name cannot be empty")); + } + options = options || {}; + const request = { + name, + type: "Global", + context: options.context || {}, + metadata: options.metadata || {}, + }; + this.invokeMethodAndTrack("HibernateLayout", request, resolve, reject, true); + }); + } + resume(name, context, options) { + return new Promise((resolve, reject) => { + if (!name) { + return reject(new Error("name cannot be empty")); + } + const request = { + name, + type: "Global", + context, + ...options + }; + this.invokeMethodAndTrack("ResumeLayout", request, resolve, reject, true); + }); + } + async getCurrentLayout() { + const methodName = "GetCurrentLayout"; + const result = await this.invokeMethodCore(methodName); + let layout = result.returned.layout; + if (!layout) { + return undefined; + } + if (!this.isSlimMode()) { + layout = this.list().find((l) => l.name === layout.name && l.type === layout.type); + } + return objectClone(layout); + } + getRestoredLayoutsInfo() { + return new Promise((resolve, reject) => { + const methodName = "GetRestoredLayoutsInfo"; + this.invokeMethodCore(methodName) + .then((result) => { + const restoredLayouts = result.returned; + resolve(restoredLayouts); + }) + .catch(reject); + }); + } + onAdded(callback) { + const result = this.callbacks.add("added", callback); + if (store.all.length > 0) { + store.all.forEach((layout) => { + try { + callback(layout); + } + catch (err) { } + }); + } + return result; + } + onRemoved(callback) { + return this.callbacks.add("removed", callback); + } + onChanged(callback) { + return this.callbacks.add("changed", callback); + } + onRestored(callback) { + return this.callbacks.add("restored", callback); + } + onRenamed(callback) { + return this.callbacks.add("renamed", callback); + } + onEvent(callback) { + return this.stream.onEvent(callback); + } + onSaveRequested(callback) { + return this.provider.onSaveRequested(callback); + } + onLayoutModified(callback) { + if (this.isRegisterMethodForLayoutModified === false) { + this.isRegisterMethodForLayoutModified = true; + this.registerMethodForLayoutModified(); + } + return this.callbacks.add("layout-modified", callback); + } + updateAppContextInCurrent(context) { + return new Promise((resolve, reject) => { + if (context && typeof context !== "object") { + return reject(new Error("Context must be an object")); + } + context = context !== null && context !== void 0 ? context : {}; + const request = { + context + }; + this.invokeMethodAndTrack("UpdateLayoutComponentContext", request, resolve, reject, true); + }); + } + updateDefaultContext(context) { + return new Promise((resolve, reject) => { + if (context && typeof context !== "object") { + return reject(new Error("Context must be an object")); + } + context = context !== null && context !== void 0 ? context : {}; + const request = { + context + }; + this.invokeMethodAndTrack("UpdateDefaultContext", request, resolve, reject, true); + }); + } + async get(name, type) { + const matching = this.list().find((l) => l.name === name && l.type === type); + if (!matching) { + throw new Error(`cannot find layout with name=${name} and type=${type}`); + } + return objectClone(matching); + } + async getAll(type) { + var _a; + if (!isUndefinedOrNull(type) && !((_a = Object.values(main.LayoutType)) === null || _a === void 0 ? void 0 : _a.includes(type))) { + throw new Error((`${type} is not a supported Layout Type`)); + } + const matching = this.list().filter((l) => type === l.type); + return objectClone(matching); + } + async forceRefresh() { + const methodName = "RefreshLayouts"; + await this.invokeMethodCore(methodName); + } + isSlimMode() { + return this.config.mode === "slim"; + } + verifyNotSlimMode() { + if (this.isSlimMode()) { + throw Error("Operation not allowed in slim mode. Run in full mode."); + } + } + async registerMethodForLayoutModified() { + await this.config.agm.register("T42.ACS.LayoutModified", (args, caller) => { + this.callbacks.execute("layout-modified", args); + }); + } + invokeMethodAndTrack(methodName, args, resolve, reject, skipStreamEvent) { + let streamEventReceived = skipStreamEvent; + let agmResult; + const token = Utils.generateId(); + args.token = token; + const handleResult = () => { + if (streamEventReceived && agmResult) { + resolve(agmResult); + } + }; + const methodResponseTimeoutMs = 120 * 1000; + if (!skipStreamEvent) { + this.stream.waitFor(token, methodResponseTimeoutMs) + .then(() => { + streamEventReceived = true; + handleResult(); + }) + .catch((err) => { + reject(err); + }); + } + const responseHandler = (result) => { + if (!result.returned) { + return reject(new Error("No result from method " + methodName)); + } + if (result.returned.status && (result.returned.status !== "Success" && result.returned.status !== "PartialSuccess")) { + if (typeof (result.returned) === "string") { + return reject(new Error(result.returned)); + } + else if (typeof (result.returned) === "object") { + if (result.returned.status && result.returned.failed) { + return reject(new Error(`${result.returned.status}: ${JSON.stringify(result.returned.failed)}`)); + } + else { + return reject(new Error(result.returned)); + } + } + } + agmResult = result.returned; + handleResult(); + }; + this.invokeMethodCore(methodName, args, "best", { methodResponseTimeoutMs }) + .then(responseHandler) + .catch((err) => reject(err)); + } + async invokeMethodCore(methodName, args, target, options) { + options = options !== null && options !== void 0 ? options : {}; + if (typeof options.methodResponseTimeoutMs === "undefined") { + options.methodResponseTimeoutMs = INTEROP_METHOD_WAIT_TIMEOUT_MS; + } + if (typeof options.waitTimeoutMs === "undefined") { + options.waitTimeoutMs = INTEROP_METHOD_WAIT_TIMEOUT_MS; + } + if (this.isCommandMethodPresent()) { + return await this.config.agm.invoke(LayoutsCommandMethod, { command: methodName, data: args }, target, options); + } + else { + return await this.config.agm.invoke(`T42.ACS.${methodName}`, args, target, options); + } + } + getObjectValues(obj) { + if (!obj) { + return []; + } + return Object.keys(obj).map((k) => obj[k]); + } + isCommandMethodPresent() { + return this.config.agm.methods().some((method) => method.name === LayoutsCommandMethod); + } + } + + class ACSStream { + constructor(agm, callbacks) { + this.agm = agm; + this.callbacks = callbacks; + this.StreamName = "T42.ACS.OnLayoutEvent"; + this.ready = new Promise((resolve, reject) => { + this.resolveReady = resolve; + this.rejectReady = reject; + }); + this.gotSnapshot = new Promise((resolve, reject) => { + this.resolveGotSnapshot = resolve; + this.rejectGotSnapshot = reject; + }); + } + subscribe(noRetry) { + const transform = (obj) => { + return this.getObjectValues(obj).map((t) => transformACSLayout(t)); + }; + if (!this.checkForLayoutEventMethod()) { + if (noRetry) { + this.resolveReady(); + } + setTimeout(() => { + this.subscribe(true); + }, 500); + } + else { + this.agm.subscribe(this.StreamName, { waitTimeoutMs: 10000 }) + .then((subs) => { + subs.onData((args) => { + const data = args.data; + if (data.IsSnapshot) { + this.resolveGotSnapshot(); + } + this.addLayouts(transform(data.OnLayoutAdded), data.IsSnapshot); + this.removeLayouts(transform(data.OnLayoutRemoved)); + this.changeLayouts(transform(data.OnLayoutChanged)); + this.renameLayouts(transform(data.OnLayoutRenamed)); + this.restoredLayout(transform(data.OnLayoutRestored)); + this.callbacks.execute("streamEvent", data); + }); + subs.onFailed((err) => { + const msg = `Can not subscribe to "${this.StreamName}" stream - ${JSON.stringify(err)}`; + this.rejectReady(msg); + this.rejectGotSnapshot(msg); + }); + this.resolveReady(); + }) + .catch((err) => { + const msg = `Error subscribing to "${this.StreamName}" stream - ${JSON.stringify(err)}`; + this.rejectReady(msg); + this.rejectGotSnapshot(msg); + }); + } + } + onEvent(callback) { + return this.callbacks.add("streamEvent", callback); + } + waitFor(token, timeout) { + if (!timeout) { + timeout = 30000; + } + return new Promise((resolve, reject) => { + let done = false; + const unsubscribe = this.onEvent((streamEvent) => { + if (streamEvent.Token === token) { + done = true; + unsubscribe(); + resolve(); + } + }); + setTimeout(() => { + if (!done) { + reject("timed out"); + } + }, timeout); + }); + } + checkForLayoutEventMethod() { + try { + return this.agm + .methods() + .map((m) => m.name) + .indexOf(this.StreamName) !== -1; + } + catch (e) { + return false; + } + } + addLayouts(layoutsData, isSnapshot) { + if (!layoutsData) { + return; + } + const createAndNotifyLayout = (layoutData) => { + const layout = new LayoutImpl(layoutData); + store.add(layout); + this.callbacks.execute("added", layout); + }; + layoutsData.forEach((layoutData) => { + if (isSnapshot) { + const found = store.first((existingLayout) => this.compareLayouts(existingLayout, layoutData)); + if (!found) { + createAndNotifyLayout(layoutData); + } + } + else { + createAndNotifyLayout(layoutData); + } + }); + } + removeLayouts(removedLayouts) { + if (!removedLayouts) { + return; + } + removedLayouts.forEach((removedLayout) => { + store.removeWhere((existingLayout) => !this.compareLayouts(existingLayout, removedLayout)); + this.callbacks.execute("removed", removedLayout); + }); + } + changeLayouts(changedLayouts) { + if (!changedLayouts) { + return; + } + changedLayouts.forEach((changedLayout) => { + store.removeWhere((existingLayout) => !this.compareLayouts(existingLayout, changedLayout)); + store.add(new LayoutImpl(changedLayout)); + this.callbacks.execute("changed", changedLayout); + }); + } + renameLayouts(renamedLayouts) { + if (!renamedLayouts) { + return; + } + renamedLayouts.forEach((renamedLayout) => { + const existingLayout = store.first((current) => this.compareLayouts(current, { type: renamedLayout.type, name: renamedLayout.oldName })); + if (!existingLayout) { + throw Error(`received rename event for unknown layout with type ${renamedLayout.type} and name ${renamedLayout.oldName}`); + } + existingLayout.name = renamedLayout.newName; + this.callbacks.execute("renamed", existingLayout); + }); + } + compareLayouts(layout1, layout2) { + return layout1.name === layout2.name && layout1.type === layout2.type; + } + getObjectValues(obj) { + if (!obj) { + return []; + } + return Object.keys(obj).map((k) => obj[k]); + } + restoredLayout(restoredLayouts) { + if (!restoredLayouts) { + return; + } + restoredLayouts.forEach((restoredLayout) => { + const existingLayout = store.first((current) => this.compareLayouts(current, { type: restoredLayout.type, name: restoredLayout.name })); + this.callbacks.execute("restored", existingLayout); + }); + } + } + + function LayoutsFactory (config) { + if (!config.agm) { + throw Error("config.agm is required"); + } + if (!config.logger) { + throw Error("config.logger is required"); + } + config.mode = config.mode || "slim"; + const logger = config.logger; + const callbacks = CallbackRegistryFactory(); + let acsStream; + if (config.mode === "full" || "fullWaitSnapshot") { + acsStream = new ACSStream(config.agm, callbacks); + } + return new LayoutsAPIImpl(config, acsStream, callbacks, logger); + } + + const T42DisplayCommand = "T42.Displays.Command"; + const T42DisplayOnEvent = "T42.Displays.OnEvent"; + class DisplayManager { + constructor(_agm, _logger) { + this._agm = _agm; + this._logger = _logger; + this._registry = CallbackRegistryFactory(); + this._registered = false; + this.all = async () => { + const displays = await this.callGD(DisplayCommand.GetAll, {}); + return displays.map(this.decorateDisplay); + }; + this.get = async (id) => { + const display = await this.callGD(DisplayCommand.Get, { id }); + return this.decorateDisplay(display); + }; + this.getPrimary = async () => { + const primary = (await this.all()).find((d) => d.isPrimary); + return primary; + }; + this.capture = async (options) => { + const screenshot = await this.callGD(DisplayCommand.Capture, { ...options }); + return screenshot; + }; + this.captureAll = async (options) => { + const screenshots = await this.callGD(DisplayCommand.CaptureAll, { ...options }); + return screenshots; + }; + this.getMousePosition = async () => { + const point = await this.callGD(DisplayCommand.GetMousePosition); + return point; + }; + this.callGD = async (command, options) => { + const invocationResult = await this._agm.invoke(T42DisplayCommand, { options: { ...options }, command }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return invocationResult.returned.data; + }; + this.decorateDisplay = (original) => { + const decoratedDisplay = { + ...original, + capture: (size) => this.capture({ id: original.id, size }) + }; + const workAreaAsAny = decoratedDisplay.workArea; + workAreaAsAny.x = workAreaAsAny.left; + workAreaAsAny.y = decoratedDisplay.workArea.top; + return decoratedDisplay; + }; + } + getByWindowId(id) { + const current = this.callGD(DisplayCommand.GetByWindowId, { id }); + return current; + } + onDisplayChanged(cb) { + this.register(); + return this._registry.add("on-display-changed", cb); + } + register() { + if (this._registered) { + return; + } + this._registered = true; + this._agm.register(T42DisplayOnEvent, (args, caller) => { + const event = args.event; + const data = args.data; + switch (event) { + case "display-changed": + this._registry.execute("on-display-changed", data.displays.map(this.decorateDisplay)); + break; + default: + this._logger.warn(`unknown event - ${event}`); + break; + } + }); + } + } + var DisplayCommand; + (function (DisplayCommand) { + DisplayCommand["Capture"] = "capture"; + DisplayCommand["CaptureAll"] = "captureAll"; + DisplayCommand["GetAll"] = "getAll"; + DisplayCommand["Get"] = "get"; + DisplayCommand["GetByWindowId"] = "getByWindowId"; + DisplayCommand["GetMousePosition"] = "getMousePosition"; + })(DisplayCommand || (DisplayCommand = {})); + + class SingleChannelID { + constructor(channel) { + this.channel = channel; + } + get isJoinedToAnyChannel() { + return !!this.channel; + } + isOnChannel(channel) { + return this.channel === channel; + } + leaveChannel(channel) { + if (channel === undefined || this.channel === channel) { + this.channel = undefined; + } + } + joinChannel(channel) { + this.channel = channel; + } + all() { + if (this.channel) { + return [this.channel]; + } + return []; + } + toString() { + return this.channel; + } + equals(other) { + if (other instanceof SingleChannelID) { + return this.channel === other.channel; + } + return false; + } + } + class MultiChannelId { + constructor(channels) { + this.ChannelDelimiter = "+++"; + if (!channels) { + this.channels = []; + } + else if (typeof channels === "string") { + this.channels = channels === null || channels === void 0 ? void 0 : channels.split(this.ChannelDelimiter).filter(Boolean); + } + else { + this.channels = (channels !== null && channels !== void 0 ? channels : []).filter(Boolean); + } + } + get isJoinedToAnyChannel() { + return this.channels.length > 0; + } + isOnChannel(channel) { + return this.channels.includes(channel); + } + joinChannel(channel) { + const newChannels = new MultiChannelId(channel); + newChannels.all().forEach((newChannel) => { + if (!this.channels.includes(newChannel)) { + this.channels.push(newChannel); + } + }); + } + leaveChannel(channel) { + const channelsToLeave = new MultiChannelId(channel !== null && channel !== void 0 ? channel : this.channels); + channelsToLeave.all().forEach((c) => { + this.channels = this.channels.filter((ch) => ch !== c); + }); + } + all() { + return this.channels; + } + toString() { + if (this.channels.length === 0) { + return undefined; + } + return this.channels.join(this.ChannelDelimiter); + } + equals(other) { + if (other instanceof MultiChannelId) { + return this.channels.length === other.channels.length && + this.channels.every((c, i) => c === other.channels[i]); + } + return false; + } + } + + let interop; + let myInstanceId; + let logger; + const T42_ANNOUNCE_METHOD_NAME = "T42.Channels.Announce"; + const T42_COMMAND_METHOD_NAME = "T42.Channels.Command"; + async function setupInterop(interopLib, channels, loggerAPI) { + var _a, _b; + logger = loggerAPI; + interop = interopLib; + if (typeof window !== "undefined") { + if (window.glue42gd) { + myInstanceId = window.glue42gd.windowId; + } + } + if (!myInstanceId) { + myInstanceId = interopLib.instance.instance; + } + await interop.register(T42_COMMAND_METHOD_NAME, (args) => { + const command = args.command; + if (!command) { + throw new Error("missing command argument"); + } + logger.trace(`received command "${command}" with ${JSON.stringify(args)}`); + if (command === "join") { + const id = args.channel; + if (!id) { + throw new Error("missing argument id"); + } + return channels.joinNoSelectorSwitch(id); + } + if (command === "leave") { + return channels.leaveNoSelectorSwitch(); + } + if (command === "get") { + const id = channels.current(); + return { id }; + } + if (command === "restrictions-changed") { + const restrictions = args.restrictions; + const targetWindowId = args.swId; + channels.handleRestrictionsChanged(restrictions, targetWindowId); + return; + } + if (command === "isFdc3DataWrappingSupported") { + return { isSupported: true }; + } + if (command === "join-multi") { + const channelsToJoin = args.channelsToJoin; + if (!channelsToJoin) { + throw new Error("missing argument channelsToJoin"); + } + return channels.joinNoSelectorSwitch(new MultiChannelId(channelsToJoin).toString()); + } + if (command === "leave-multi") { + const channelsToLeave = args.channelsToLeave; + return channels.leaveNoSelectorSwitch(new MultiChannelId(channelsToLeave).toString()); + } + throw new Error(`unknown command ${command}`); + }); + const result = await interop.invoke(T42_ANNOUNCE_METHOD_NAME, { swId: myInstanceId, instance: interop.instance.instance }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_RESPONSE_TIMEOUT_MS + }); + if ((_a = result.returned) === null || _a === void 0 ? void 0 : _a.restrictions) { + channels.handleRestrictionsChanged((_b = result.returned) === null || _b === void 0 ? void 0 : _b.restrictions, myInstanceId); + } + return result.returned; + } + async function sendLeaveChannel(channel, winId) { + var _a; + await invoke("leaveChannel", { channel }, (_a = winId !== null && winId !== void 0 ? winId : winId) !== null && _a !== void 0 ? _a : myInstanceId); + } + async function sendSwitchChannelUI(channel, winId) { + await invoke("switchChannel", { newChannel: channel }, winId !== null && winId !== void 0 ? winId : myInstanceId); + } + async function setRestrictions(restrictions) { + var _a; + await invoke("restrict", restrictions, (_a = restrictions.windowId) !== null && _a !== void 0 ? _a : myInstanceId); + } + async function getRestrictionsByWindow(id) { + try { + const result = await invoke("getRestrictions", {}, id !== null && id !== void 0 ? id : myInstanceId); + return result.returned; + } + catch (e) { + } + } + async function setRestrictionsForAllChannels(restrictions) { + var _a; + await invoke("restrictAll", restrictions, (_a = restrictions.windowId) !== null && _a !== void 0 ? _a : myInstanceId); + } + async function getChannelsInfo(filter) { + const result = await invoke("getChannelsInfo", { filter }); + return result.returned; + } + async function addOrRemoveChannel(command, id, color, label) { + await invoke(command, { id, color, label }); + } + async function getChannelInitInfo(config, i) { + if (typeof config.operationMode !== "boolean" && typeof config.operationMode === "string") { + validateMode(config.operationMode); + return { mode: config.operationMode, initialChannel: undefined }; + } + try { + const result = await i.invoke(T42_ANNOUNCE_METHOD_NAME, { command: "getChannelsMode" }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_RESPONSE_TIMEOUT_MS, + }); + const initialChannel = result.returned.initialChannel; + if (result.returned.mode === "single") { + return { + mode: "single", + initialChannel + }; + } + else if (result.returned.mode === "multi") { + return { + mode: "multi", + initialChannel + }; + } + else { + return { + mode: "single", + initialChannel + }; + } + } + catch (e) { + return { mode: "single", initialChannel: undefined }; + } + } + function invoke(command, data, swId) { + const args = { command, data }; + if (swId) { + args.swId = swId; + } + return interop.invoke(T42_ANNOUNCE_METHOD_NAME, args, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_RESPONSE_TIMEOUT_MS, + }); + } + function validateMode(mode) { + if (mode !== "single" && mode !== "multi") { + throw new Error(`Invalid mode: ${mode}`); + } + } + + const CONTEXT_PREFIX = "___channel___"; + const LATEST_FDC3_TYPE = "latest_fdc3_type"; + class BaseSharedContextSubscriber { + constructor(contexts) { + this.contexts = contexts; + } + subscribe(callback) { + this.callback = callback; + } + subscribeFor(name, callback) { + if (!this.isChannel(name)) { + return Promise.reject(new Error(`Channel with name: ${name} doesn't exist!`)); + } + const contextName = this.createContextName(name); + return this.contexts.subscribe(contextName, (data, _, __, ___, extraData) => { + callback(data.data, data, extraData === null || extraData === void 0 ? void 0 : extraData.updaterId); + }); + } + all() { + const contextNames = this.contexts.all(); + const channelContextNames = contextNames.filter((contextName) => contextName.startsWith(CONTEXT_PREFIX)); + const channelNames = channelContextNames.map((channelContextName) => channelContextName.substr(CONTEXT_PREFIX.length)); + return channelNames; + } + async getContextData(name) { + if (!this.isChannel(name)) { + throw new Error(`A channel with name: ${name} doesn't exist!`); + } + const contextName = this.createContextName(name); + const contextData = await this.contexts.get(contextName); + if (contextData[LATEST_FDC3_TYPE]) { + return this.getContextWithFdc3Data(contextData); + } + else { + delete contextData[LATEST_FDC3_TYPE]; + } + return contextData; + } + updateChannel(name, data) { + const contextName = this.createContextName(name); + return this.contexts.update(contextName, data); + } + updateData(name, data) { + const contextName = this.createContextName(name); + const fdc3Type = this.getFDC3Type(data); + if (this.contexts.setPathSupported) { + const pathValues = Object.keys(data).map((key) => { + return { + path: `data.` + key, + value: data[key] + }; + }); + if (fdc3Type) { + pathValues.push({ path: LATEST_FDC3_TYPE, value: fdc3Type }); + } + return this.contexts.setPaths(contextName, pathValues); + } + else { + if (fdc3Type) { + data[LATEST_FDC3_TYPE] = fdc3Type; + } + return this.contexts.update(contextName, { data }); + } + } + setPaths(name, paths) { + const contextName = this.createContextName(name); + if (this.contexts.setPathSupported) { + const pathValues = paths.map((p) => { + return { + path: `data.` + p.path, + value: p.value + }; + }); + pathValues.map((p) => { + const fdc3Type = this.getFDC3Type(p.value); + if (fdc3Type) { + pathValues.push({ path: LATEST_FDC3_TYPE, value: fdc3Type }); + } + }); + return this.contexts.setPaths(contextName, pathValues); + } + else { + throw new Error("setPaths is not supported!"); + } + } + clearContextData(name) { + const contextName = this.createContextName(name); + return this.contexts.update(contextName, { data: {}, [LATEST_FDC3_TYPE]: undefined }); + } + isChannel(name) { + return this.all().some((channelName) => channelName === name); + } + async remove(name) { + if (!this.isChannel(name)) { + throw new Error(`A channel with name: ${name} doesn't exist!`); + } + const contextName = this.createContextName(name); + await this.contexts.destroy(contextName); + } + createContextName(name) { + return CONTEXT_PREFIX + name; + } + getFDC3Type(data) { + const fdc3PropsArr = Object.keys(data).filter((key) => key.indexOf("fdc3_") === 0); + if (fdc3PropsArr.length === 0) { + return; + } + if (fdc3PropsArr.length > 1) { + throw new Error("FDC3 does not support updating of multiple context keys"); + } + return fdc3PropsArr[0].split("_").slice(1).join("_"); + } + getContextWithFdc3Data(channelContext) { + const { latest_fdc3_type, ...rest } = channelContext; + const parsedType = latest_fdc3_type.split("&").join("."); + const fdc3Context = { type: parsedType, ...rest.data[`fdc3_${latest_fdc3_type}`] }; + delete rest.data[`fdc3_${latest_fdc3_type}`]; + const context = { + name: channelContext.name, + meta: channelContext.meta, + data: { + ...rest.data, + fdc3: fdc3Context + } + }; + return context; + } + } + class MultiSharedContextSubscriber extends BaseSharedContextSubscriber { + constructor() { + super(...arguments); + this.currentlySubscribedChannels = []; + this.unsubscribeMap = {}; + } + async switchChannel(id) { + const newChannels = new MultiChannelId(id).all(); + for (const newChannel of newChannels) { + if (!this.currentlySubscribedChannels.includes(newChannel)) { + await this.subscribeToChannel(newChannel); + } + } + } + async leave(id) { + const channelsToLeave = new MultiChannelId(id).all(); + for (const newChannel of channelsToLeave) { + if (this.currentlySubscribedChannels.includes(newChannel)) { + this.unsubscribeFromChannel(newChannel); + } + } + } + async updateData(id, data) { + const channels = new MultiChannelId(id).all(); + for (const channel of channels) { + await super.updateData(channel, data); + } + } + async setPaths(id, paths) { + const channels = new MultiChannelId(id).all(); + for (const channel of channels) { + await super.setPaths(channel, paths); + } + } + isChannel(name) { + const channels = new MultiChannelId(name).all(); + return channels.every((channel) => super.isChannel(channel)); + } + async subscribeToChannel(name) { + const contextName = this.createContextName(name); + const usub = await this.contexts.subscribe(contextName, (data, _, __, ___, extraData) => { + if (this.callback) { + this.callback(data.data, data, extraData === null || extraData === void 0 ? void 0 : extraData.updaterId); + } + }); + this.currentlySubscribedChannels.push(name); + this.unsubscribeMap[contextName] = usub; + } + async unsubscribeFromChannel(name) { + const contextName = this.createContextName(name); + const unsub = this.unsubscribeMap[contextName]; + if (unsub) { + unsub(); + delete this.unsubscribeMap[contextName]; + } + this.currentlySubscribedChannels = this.currentlySubscribedChannels.filter((channel) => channel !== name); + } + } + class SharedContextSubscriber extends BaseSharedContextSubscriber { + async switchChannel(name) { + this.unsubscribe(); + const contextName = this.createContextName(name); + this.unsubscribeFunc = await this.contexts.subscribe(contextName, (data, _, __, ___, extraData) => { + if (this.callback) { + this.callback(data.data, data, extraData === null || extraData === void 0 ? void 0 : extraData.updaterId); + } + }); + } + async leave() { + if (this.callback) { + this.callback({}, undefined); + } + this.unsubscribe(); + } + unsubscribe() { + if (this.unsubscribeFunc) { + this.unsubscribeFunc(); + this.unsubscribeFunc = undefined; + } + } + } + + const validateFdc3Options = (options) => { + if (typeof options !== "object" || Array.isArray(options)) { + throw new Error(`Provide options as an object`); + } + if (options.contextType && (typeof options.contextType !== "string" || !options.contextType.length)) { + throw new Error(`Provide options.contextType as a non-empty string`); + } + }; + + class ChannelsImpl { + constructor(interop, getWindowsAPI, getAppManagerAPI, logger) { + this.interop = interop; + this.getWindowsAPI = getWindowsAPI; + this.getAppManagerAPI = getAppManagerAPI; + this.logger = logger; + this.subsKey = "subs"; + this.changedKey = "changed"; + this.channelsChangedKey = "channelsChanged"; + this.isInitialJoin = true; + this.registry = CallbackRegistryFactory(); + this.pendingReplays = {}; + this.pendingRestrictionCallbacks = new Map(); + } + async getMyChannels(options) { + if (!this.currentChannelID) { + return Promise.resolve([]); + } + if (this.currentChannelID.all().length === 0) { + return Promise.resolve([]); + } + const result = []; + for (const channel of this.currentChannelID.all()) { + result.push(await this.get(channel, options)); + } + return result; + } + async init(shared, mode, initial) { + this.mode = mode; + this.shared = shared; + this.shared.subscribe(this.handler.bind(this)); + this.subscribeForChannelRestrictionsChange(); + let initialChannel = initial; + if (typeof window !== "undefined" && typeof window.glue42gd !== "undefined") { + initialChannel = window.glue42gd.initialChannel; + } + this.currentChannelID = this.getID(initialChannel); + this.logger.trace(`initialized with mode: "${mode}" and initial channel: "${initialChannel}"`); + if (this.currentChannelID.isJoinedToAnyChannel) { + this.logger.trace(`joining initial channel: "${this.currentChannelID.toString()}"`); + await this.joinNoSelectorSwitch(this.currentChannelID.toString()); + } + } + subscribe(callback, options) { + if (typeof callback !== "function") { + throw new Error("Please provide the callback as a function!"); + } + const id = Utils.generateId(); + this.pendingReplays[id] = true; + const wrappedCallback = (options === null || options === void 0 ? void 0 : options.contextType) + ? this.getWrappedSubscribeCallbackWithFdc3Type(callback, id, options.contextType) + : this.getWrappedSubscribeCallback(callback, id); + if (this.lastUpdate) { + let lastUpdate = Object.assign({}, this.lastUpdate); + setTimeout(async () => { + if (this.pendingReplays[id]) { + if (this.lastUpdate) { + lastUpdate = this.lastUpdate; + } + wrappedCallback(lastUpdate.context.data, lastUpdate.context, lastUpdate.updaterId); + } + delete this.pendingReplays[id]; + }, 0); + } + const unsub = this.registry.add(this.subsKey, wrappedCallback); + return () => { + this.pendingReplays[id] = false; + this.pendingRestrictionCallbacks.delete(id); + unsub(); + }; + } + async subscribeFor(name, callback, options) { + if (typeof name !== "string") { + throw new Error("Please provide the name as a string!"); + } + if (typeof callback !== "function") { + throw new Error("Please provide the callback as a function!"); + } + const id = Utils.generateId(); + const wrappedCallback = (options === null || options === void 0 ? void 0 : options.contextType) + ? this.getWrappedSubscribeCallbackWithFdc3Type(callback, id, options.contextType) + : this.getWrappedSubscribeCallback(callback, id); + const unsub = await this.shared.subscribeFor(name, wrappedCallback); + return () => { + this.pendingRestrictionCallbacks.delete(id); + unsub(); + }; + } + async publish(data, options) { + if (typeof data !== "object") { + throw new Error("Please provide the data as an object!"); + } + if (options) { + this.validatePublishOptions(options); + } + if (typeof options === "object") { + return this.publishWithOptions(data, options); + } + const channelName = typeof options === "string" ? options : this.currentChannelID.toString(); + if (!channelName) { + throw new Error("Not joined to any channel!"); + } + if (!this.shared.isChannel(channelName)) { + return Promise.reject(new Error(`A channel with name: ${channelName} doesn't exist!`)); + } + if (this.mode === "multi") { + const channelsToPublish = new MultiChannelId(channelName).all(); + const restrictedChannels = []; + for (const cn of channelsToPublish) { + const canPublish = (await this.getRestrictionsByChannel(cn)).write; + if (!canPublish) { + restrictedChannels.push(cn); + continue; + } + await this.shared.updateData(cn, data); + } + if (restrictedChannels.length > 0) { + const restrictedChannelsErr = `Unable to publish due to restrictions to the following channels: ${restrictedChannels.join(", ")}`; + if (restrictedChannels.length === channelsToPublish.length) { + throw new Error(restrictedChannelsErr); + } + else { + this.logger.warn(restrictedChannelsErr); + } + } + } + else { + const canPublish = (await this.getRestrictionsByChannel(channelName)).write; + if (!canPublish) { + throw new Error(`Window does not have permission to write to channel ${channelName}`); + } + return this.shared.updateData(channelName, data); + } + } + async setPaths(paths, name) { + if (name) { + if (typeof name !== "string") { + throw new Error("Please provide the name as a string!"); + } + if (!this.shared.isChannel(name)) { + return Promise.reject(new Error(`A channel with name: ${name} doesn't exist!`)); + } + if (!(await this.getRestrictionsByChannel(name)).write) { + throw new Error(`Window does not have permission to write to channel ${name}`); + } + return this.shared.setPaths(name, paths); + } + if (!this.currentChannelID) { + throw new Error("Not joined to any channel!"); + } + if (!(await this.getRestrictionsByChannel(this.currentChannelID.toString())).write) { + throw new Error(`Window does not have permission to write to channel ${this.currentChannelID.toString()}`); + } + if (!Array.isArray(paths)) { + throw new Error("Path Values argument is not a valid array"); + } + paths.forEach((path) => { + this.validatePathArgs(path); + }); + return this.shared.setPaths(this.currentChannelID.toString(), paths); + } + async setPath(path, name) { + if (name) { + if (typeof name !== "string") { + throw new Error("Please provide the name as a string!"); + } + if (!this.shared.isChannel(name)) { + return Promise.reject(new Error(`A channel with name: ${name} doesn't exist!`)); + } + if (!(await this.getRestrictionsByChannel(name)).write) { + throw new Error(`Window does not have permission to write to channel ${name}`); + } + return this.shared.setPaths(name, [path]); + } + if (!this.currentChannelID) { + throw new Error("Not joined to any channel!"); + } + if (!(await this.getRestrictionsByChannel(this.currentChannelID.toString())).write) { + throw new Error(`Window does not have permission to write to channel ${this.currentChannelID.toString()}`); + } + this.validatePathArgs(path); + return this.shared.setPaths(this.currentChannelID.toString(), [path]); + } + all() { + const channelNames = this.shared.all(); + return Promise.resolve(channelNames); + } + async list() { + const channelNames = await this.all(); + const channelContexts = await Promise.all(channelNames.map((channelName) => this.get(channelName))); + return channelContexts; + } + async get(name, options) { + if (typeof name !== "string") { + return Promise.reject(new Error("Please provide the channel name as a string!")); + } + if (!(options === null || options === void 0 ? void 0 : options.contextType)) { + return this.shared.getContextData(name); + } + validateFdc3Options(options); + const context = await this.shared.getContextData(name); + return this.getContextWithFdc3Type(context, options.contextType); + } + getMy(options) { + if (!this.currentChannelID) { + return Promise.resolve(undefined); + } + if (this.currentChannelID.all().length === 0) { + return Promise.resolve(undefined); + } + return this.get(this.currentChannelID.all()[0], options); + } + async join(name, windowId) { + if (windowId !== undefined && windowId !== null) { + this.validateWindowIdArg(windowId); + this.logger.trace(`joining channel ${name} for window: ${windowId}`); + return sendSwitchChannelUI(name, windowId); + } + return this.joinCore(name); + } + async joinNoSelectorSwitch(channelName) { + this.logger.trace(`joining channel "${channelName}" from command`); + return this.joinCore(channelName, false); + } + leave(options) { + this.logger.trace(`leaving channel with options: ${JSON.stringify(options)}`); + let windowId; + let channelName; + if (typeof options === "string") { + windowId = options; + } + else if (typeof options === "object" && !Array.isArray(options) && options !== null && options !== undefined) { + if (options.windowId) { + windowId = options.windowId; + } + if (options.channel) { + channelName = options.channel; + } + } + if (this.mode === "multi") { + return this.leaveWhenMulti(channelName, windowId); + } + else { + return this.leaveWhenSingle(channelName, windowId); + } + } + leaveNoSelectorSwitch(channelName) { + this.logger.trace(`leaving channel "${channelName}" from command`); + return this.leaveCore(false, channelName); + } + current() { + return this.currentChannelID.toString(); + } + my() { + return this.current(); + } + myChannels() { + var _a; + return (_a = this.currentChannelID.all()) !== null && _a !== void 0 ? _a : []; + } + onChannelsChanged(callback) { + if (typeof callback !== "function") { + throw new Error("Please provide the callback as a function!"); + } + let timeoutId; + const current = this.current(); + if (current) { + timeoutId = setTimeout(() => { + callback(this.myChannels()); + }, 0); + } + const un = this.registry.add(this.channelsChangedKey, callback); + return () => { + un(); + clearTimeout(timeoutId); + }; + } + changed(callback) { + if (typeof callback !== "function") { + throw new Error("Please provide the callback as a function!"); + } + const current = this.current(); + if (current) { + setTimeout(() => { + callback(this.current()); + }, 0); + } + return this.registry.add(this.changedKey, () => { + callback(this.current()); + }); + } + onChanged(callback) { + return this.changed(callback); + } + async add(info) { + var _a; + if (typeof info !== "object") { + throw new Error("Please provide the info as an object!"); + } + if (typeof info.name === "undefined") { + throw new Error("info.name is missing!"); + } + if (typeof info.name !== "string") { + throw new Error("Please provide the info.name as a string!"); + } + if (typeof info.meta === "undefined") { + throw new Error("info.meta is missing!"); + } + if (typeof info.meta !== "object") { + throw new Error("Please provide the info.meta as an object!"); + } + if (typeof info.meta.color === "undefined") { + throw new Error("info.meta.color is missing!"); + } + if (typeof info.meta.color !== "string") { + throw new Error("Please provide the info.meta.color as a string!"); + } + const context = { + name: info.name, + meta: info.meta || {}, + data: info.data || {} + }; + this.logger.trace(`adding channel: ${info.name}`); + await addOrRemoveChannel("addChannel", info.name, info.meta.color, (_a = info.meta) === null || _a === void 0 ? void 0 : _a.label); + await this.shared.updateChannel(info.name, context); + return context; + } + async remove(channel) { + if (typeof channel !== "string") { + throw new Error("Please provide the channel name as a string!"); + } + this.logger.trace(`removing channel: ${channel}`); + await this.shared.remove(channel); + await addOrRemoveChannel("removeChannel", channel); + } + async getWindowsOnChannel(channel) { + this.validateChannelArg(channel); + const windowInfos = await this.getWindowsWithChannels({ channels: [channel] }); + return windowInfos.map((w) => w.window); + } + async getWindowsWithChannels(filter) { + this.validateWindowsWithChannelsFilter(filter); + try { + const info = await getChannelsInfo(filter); + const windowsAPI = this.getWindowsAPI(); + if (info === null || info === void 0 ? void 0 : info.windows) { + return info.windows.reduce((memo, windowInfo) => { + const window = windowsAPI.findById(windowInfo.windowId); + memo.push({ + window, + channel: windowInfo.channel, + application: windowInfo.application + }); + return memo; + }, []); + } + } + catch (er) { + this.logger.error(`Error getting all channel enabled windows. This method is available since Glue42 3.12`, er); + } + return []; + } + async restrict(restriction) { + this.validateRestrictionConfig(restriction); + return setRestrictions(restriction); + } + async getRestrictions(windowId) { + if (windowId) { + this.validateWindowIdArg(windowId); + } + return getRestrictionsByWindow(windowId); + } + async restrictAll(restriction) { + this.validateRestrictionConfig(restriction); + return setRestrictionsForAllChannels(restriction); + } + handleRestrictionsChanged(restrictions, windowId) { + this.registry.execute("restrictions-changed", { + restrictions, + windowId + }); + } + async clearChannelData(channel) { + const channelName = typeof channel === "string" ? channel : this.currentChannelID.toString(); + if (!channelName) { + return; + } + if (!this.shared.isChannel(channelName)) { + return; + } + const canPublish = (await this.getRestrictionsByChannel(channelName)).write; + if (!canPublish) { + return; + } + return this.shared.clearContextData(channelName); + } + handler(data, context, updaterId) { + if (!context && !updaterId) { + this.lastUpdate = undefined; + return; + } + this.lastUpdate = { context, updaterId }; + this.pendingReplays = {}; + this.registry.execute(this.subsKey, data, context, updaterId); + } + async joinCore(name, changeSelector = true) { + this.logger.trace(`joining channel "${name}" ${changeSelector ? "" : "from command"}`); + if (typeof name !== "string") { + throw new Error("Please provide the channel name as a string!"); + } + const newId = this.getID(name); + if (!this.isInitialJoin && this.currentChannelID.isOnChannel(newId.toString())) { + this.logger.trace(`already on channel: "${name}" ${changeSelector ? "" : "from command"}`); + return; + } + this.isInitialJoin = false; + await Promise.all(newId.all().map((n) => this.verifyChannelExists(n))); + this.currentChannelID.joinChannel(name); + this.lastUpdate = undefined; + this.logger.trace(`switching channel context to: "${name}" ${changeSelector ? "" : "from command"}`); + await this.shared.switchChannel(this.currentChannelID.toString()); + if (changeSelector) { + this.logger.trace(`switching UI channel to: "${name}" ${changeSelector ? "" : "from command"}`); + await sendSwitchChannelUI(name); + this.logger.trace(`switched UI channel to: "${name}" ${changeSelector ? "" : "from command"}`); + } + this.raiseChannelsChangedEvents(); + this.logger.trace(`joined channel: ${name} ${changeSelector ? "" : "from command"} - current channel/s: ${this.currentChannelID.toString()}`); + } + async verifyChannelExists(name) { + const doesChannelExist = (channelName) => { + const channelNames = this.shared.all(); + return channelNames.includes(channelName); + }; + if (!doesChannelExist(name)) { + const channelExistsPromise = new Promise((resolve, reject) => { + const intervalId = setInterval(() => { + if (doesChannelExist(name)) { + clearTimeout(timeoutId); + clearInterval(intervalId); + resolve(); + } + }, 100); + const timeoutId = setTimeout(() => { + clearInterval(intervalId); + return reject(new Error(`A channel with name: ${name} doesn't exist!`)); + }, 3000); + }); + await channelExistsPromise; + } + } + async leaveCore(changeSelector = true, channelID) { + if (!this.currentChannelID.isJoinedToAnyChannel) { + this.logger.trace(`leave called ${changeSelector ? "" : "from command"} when not joined to any channel change selector`); + return; + } + if (channelID && !this.currentChannelID.isOnChannel(channelID)) { + this.logger.trace(`leave called ${changeSelector ? "" : "from command"} when not joined to channel: "${channelID}"`); + return; + } + this.logger.trace(`leaving context channel: "${channelID}" ${changeSelector ? "" : "from command"}`); + this.currentChannelID.leaveChannel(channelID); + await this.shared.leave(channelID); + this.lastUpdate = undefined; + this.raiseChannelsChangedEvents(); + if (changeSelector) { + this.logger.trace(`switching UI channel to: "${channelID}" ${changeSelector ? "" : "from command"}`); + await sendSwitchChannelUI(this.currentChannelID.toString()); + this.logger.trace(`switched UI channel to: "${channelID}" ${changeSelector ? "" : "from command"}`); + } + this.logger.trace(`left single channel: "${channelID}" ${changeSelector ? "" : "from command"} - current channel/s: "${this.currentChannelID.toString()}"`); + return Promise.resolve(); + } + async leaveCoreMulti(changeSelector = true, channelID) { + this.logger.trace(`leaving multi channel: "${channelID.toString()}" ${changeSelector ? "" : "from command"}`); + const currentChannels = this.currentChannelID.all(); + const isJoinedToChannel = currentChannels.some((c) => channelID.isOnChannel(c)); + if (!isJoinedToChannel || !this.currentChannelID.isJoinedToAnyChannel) { + this.logger.trace(`leave called ${changeSelector ? "" : "from command"} when not joined to any channel`); + return; + } + const channelName = channelID.toString(); + this.currentChannelID.leaveChannel(channelName); + await this.shared.leave(channelName); + this.lastUpdate = undefined; + this.raiseChannelsChangedEvents(); + if (changeSelector) { + this.logger.trace(`switching UI channel to: "${channelName}" ${changeSelector ? "" : "from command"}`); + await sendLeaveChannel(channelName); + this.logger.trace(`switched UI channel to: "${channelName}" ${changeSelector ? "" : "from command"}`); + } + this.logger.trace(`left multi channel: "${channelName}" ${changeSelector ? "" : "from command"} - current channel/s: ${this.currentChannelID.toString()}`); + return Promise.resolve(); + } + raiseChannelsChangedEvents() { + this.registry.execute(this.changedKey, this.currentChannelID.toString()); + this.registry.execute(this.channelsChangedKey, this.currentChannelID.all()); + } + async getRestrictionsByChannel(channelName) { + var _a; + const restrictions = (_a = this.channelRestrictions) !== null && _a !== void 0 ? _a : await getRestrictionsByWindow(); + if (!restrictions || !Array.isArray(restrictions.channels) || !restrictions.channels.find(c => c.name === channelName)) { + return { + read: true, + write: true + }; + } + const byChannel = restrictions.channels.find(c => c.name === channelName); + return byChannel; + } + onRestrictionsChanged(callback, callbackId, currentChannelName) { + this.pendingRestrictionCallbacks.set(callbackId, { + cb: callback, + channelName: currentChannelName + }); + if (this.onRestrictionsChangedSub) { + return; + } + this.onRestrictionsChangedSub = this.registry.add("restrictions-changed", ({ restrictions }) => { + this.logger.trace(`restrictions changed - ${JSON.stringify(restrictions)}`); + this.pendingRestrictionCallbacks.forEach(({ cb, channelName }, id) => { + const currentChannel = restrictions.channels.find((c) => c.name === channelName); + if (!currentChannel) { + this.logger.trace(`channel "${channelName}" not found in restrictions`); + return; + } + if (currentChannel.read) { + this.pendingRestrictionCallbacks.delete(id); + if (this.pendingRestrictionCallbacks.values.length === 0 && this.onRestrictionsChangedSub) { + this.onRestrictionsChangedSub(); + this.onRestrictionsChangedSub = null; + } + cb(); + } + }); + }); + } + subscribeForChannelRestrictionsChange() { + this.registry.add("restrictions-changed", (r) => { + this.logger.trace(`channel restrictions changed - ${JSON.stringify(r.restrictions)}`); + this.channelRestrictions = r.restrictions; + }); + } + validatePathArgs(path) { + if (!path) { + throw new Error("Please provide a valid path value argument"); + } + if (typeof path !== "object") { + throw new Error(`Path Value argument is not a valid object: ${JSON.stringify(path)}`); + } + if (!path.path) { + throw new Error(`path property is missing from Path Value argument: ${JSON.stringify(path)}`); + } + if (!path.value) { + throw new Error(`value property is missing from Path Value argument: ${JSON.stringify(path)}`); + } + if (typeof path.path !== "string") { + throw new Error(`path property is not a valid string from the Path Value argument: ${JSON.stringify(path)}`); + } + } + validatePublishOptions(options) { + if ((typeof options !== "string" && typeof options !== "object") || Array.isArray(options)) { + throw new Error("Provide options as a string or an object"); + } + if (typeof options === "object") { + this.validatePublishOptionsObject(options); + return; + } + if (options === "string" && !options.length) { + throw new Error("Provide options as a non-empty string"); + } + } + validatePublishOptionsObject(options) { + if (typeof options !== "object" || Array.isArray(options)) { + throw new Error("Provide options as an object"); + } + if (options.name && (typeof options.name !== "string" || !options.name.length)) { + throw new Error("Provide options.name as a non-empty string"); + } + if (Object.keys(options).includes("fdc3") && typeof options.fdc3 !== "boolean") { + throw new Error("Provide options.fdc3 as a boolean"); + } + } + async publishWithOptions(data, options) { + const channelName = options.name || this.currentChannelID.toString(); + if (!this.shared.isChannel(channelName)) { + throw new Error(`A channel with name: ${options.name} doesn't exist!`); + } + if (!channelName) { + throw new Error("Cannot publish to channel, because not joined to a channel!"); + } + const canPublish = (await this.getRestrictionsByChannel(channelName)).write; + if (!canPublish) { + throw new Error(`Window does not have permission to write to channel ${this.currentChannelID.toString()}`); + } + if (!options.fdc3) { + return this.shared.updateData(channelName, data); + } + return this.publishFdc3Data(channelName, data); + } + async publishFdc3Data(channelName, data) { + var _a; + if (typeof data.type !== "string" || !((_a = data.type) === null || _a === void 0 ? void 0 : _a.length)) { + throw new Error("Expected a valid FDC3 Context with compulsory 'type' field"); + } + const { type, ...rest } = data; + const parsedType = type.split(".").join("&"); + const fdc3DataToPublish = { [`fdc3_${parsedType}`]: rest }; + return this.shared.updateData(channelName, fdc3DataToPublish); + } + getWrappedSubscribeCallback(callback, id) { + const wrappedCallback = async (_, context, updaterId) => { + const restrictionByChannel = await this.getRestrictionsByChannel(context.name); + const channelData = this.getDataWithFdc3Encoding(context); + if (restrictionByChannel.read) { + callback(channelData, context, updaterId); + } + else { + this.onRestrictionsChanged(() => { + callback(channelData, context, updaterId); + }, id, context.name); + } + }; + return wrappedCallback; + } + getWrappedSubscribeCallbackWithFdc3Type(callback, id, fdc3Type) { + const didReplay = { replayed: false }; + const wrappedCallback = async (_, context, updaterId) => { + const restrictionByChannel = await this.getRestrictionsByChannel(context.name); + const callbackWithTypesChecks = () => { + const { data, latest_fdc3_type } = context; + const searchedType = `fdc3_${fdc3Type.split(".").join("&")}`; + if (!data[searchedType]) { + return; + } + if (didReplay.replayed) { + return this.parseDataAndInvokeSubscribeCallback({ latestFdc3TypeEncoded: latest_fdc3_type, searchedType: fdc3Type, callback, context, updaterId }); + } + const fdc3Data = { type: fdc3Type, ...data[searchedType] }; + callback({ fdc3: fdc3Data }, context, updaterId); + didReplay.replayed = true; + }; + if (restrictionByChannel.read) { + callbackWithTypesChecks(); + return; + } + this.onRestrictionsChanged(callbackWithTypesChecks, id, context.name); + }; + return wrappedCallback; + } + parseDataAndInvokeSubscribeCallback(args) { + const { latestFdc3TypeEncoded, searchedType, callback, context, updaterId } = args; + const latestPublishedType = latestFdc3TypeEncoded.split("&").join("."); + if (latestPublishedType !== searchedType) { + return; + } + const fdc3Data = { type: searchedType, ...context.data[`fdc3_${latestFdc3TypeEncoded}`] }; + callback({ fdc3: fdc3Data }, context, updaterId); + } + getContextWithFdc3Type(context, searchedType) { + var _a, _b; + if (((_b = (_a = context.data) === null || _a === void 0 ? void 0 : _a.fdc3) === null || _b === void 0 ? void 0 : _b.type) === searchedType) { + return { + name: context.name, + meta: context.meta, + data: { fdc3: context.data.fdc3 } + }; + } + const encodedType = `fdc3_${searchedType.split(".").join("&")}`; + if (!context.data[encodedType]) { + return { + name: context.name, + meta: context.meta, + data: {} + }; + } + const fdc3Context = { type: searchedType, ...context.data[encodedType] }; + return { + name: context.name, + meta: context.meta, + data: { fdc3: fdc3Context } + }; + } + getDataWithFdc3Encoding(context) { + const { data, latest_fdc3_type } = context; + if (!latest_fdc3_type) { + return data; + } + const parsedType = latest_fdc3_type.split("&").join("."); + const latestTypePropName = `fdc3_${latest_fdc3_type}`; + const fdc3Data = { type: parsedType, ...data[latestTypePropName] }; + const { [latestTypePropName]: latestFDC3Type, ...rest } = data; + return { ...rest, fdc3: fdc3Data }; + } + getID(id) { + if (this.mode === "multi") { + return new MultiChannelId(id); + } + else { + return new SingleChannelID(id); + } + } + leaveWhenSingle(channelName, windowId) { + if (windowId) { + this.logger.trace(`leaving single channel "${channelName}" for window: "${windowId}"`); + return sendSwitchChannelUI(undefined, windowId); + } + this.logger.trace(`leaving single channel "${channelName}" for our window`); + return this.leaveCore(true, channelName); + } + async leaveWhenMulti(channelName, windowId) { + if (windowId) { + this.logger.trace(`leaving multi channel "${channelName}" for window: "${windowId}"`); + return sendLeaveChannel(channelName, windowId); + } + else { + const channelId = channelName ? new MultiChannelId(channelName) : this.currentChannelID; + this.logger.trace(`leaving multi channel "${channelId.toString()}" for our window`); + return this.leaveCoreMulti(true, channelId); + } + } + validateWindowIdArg(windowId) { + if (typeof windowId !== "string") { + throw new Error("The window ID must be a non-empty string!"); + } + const windows = this.getWindowsAPI(); + if (!windows.findById(windowId)) { + throw new Error(`Window with ID "${windowId}" doesn't exist!`); + } + } + validateChannelArg(channel) { + if (!channel) { + throw new Error("Please provide a valid Channel name as a non-empty string!"); + } + if (typeof channel !== "string") { + throw new Error("The Channel name must be a non-empty string!"); + } + const channelNames = this.shared.all(); + if (channelNames.every((name) => name !== channel)) { + throw new Error(`Channel "${channel}" does not exist!"`); + } + } + validateWindowsWithChannelsFilter(filter) { + if (filter === undefined) { + return; + } + if (filter === null || Array.isArray(filter) || typeof filter !== "object") { + throw new Error("The `filter` argument must be a valid object!"); + } + } + isRestrictions(restriction) { + return 'name' in restriction; + } + validateRestrictionConfig(restriction) { + if (restriction === null || restriction === undefined || Array.isArray(restriction) || typeof restriction !== "object") { + throw new Error("The `restrictions` argument must be a valid object with Channel restrictions!"); + } + if (this.isRestrictions(restriction) && typeof restriction.name !== "string") { + throw new Error("The `name` restriction property must be a non-empty string!"); + } + if (restriction.read !== null && restriction.read !== undefined && typeof restriction.read !== "boolean") { + throw new Error("The `read` restriction property must be a boolean value!"); + } + if (restriction.write !== null && restriction.write !== undefined && typeof restriction.write !== "boolean") { + throw new Error("The `write` restriction property must be a boolean value!"); + } + if ((restriction.read === null || restriction.read === undefined) && (restriction.write === null || restriction.write === undefined)) { + throw new Error("It's required to set either the `read` or the `write` property of the Channel restriction object!"); + } + if (restriction.windowId !== null && restriction.windowId !== undefined) { + this.validateWindowIdArg(restriction.windowId); + } + } + } + + function factory$4(config, contexts, agm, getWindowsAPI, getAppManagerAPI, logger) { + const channelsReadyPromise = getChannelInitInfo(config, agm) + .then(async ({ mode, initialChannel }) => { + const sharedContexts = mode === "single" ? new SharedContextSubscriber(contexts) : new MultiSharedContextSubscriber(contexts); + if (mode === "multi") { + logger.info(`multi-channel mode enabled`); + } + await channels.init(sharedContexts, mode, initialChannel); + await setupInterop(agm, channels, logger); + return true; + }); + const channels = new ChannelsImpl(agm, getWindowsAPI, getAppManagerAPI, logger); + return { + subscribe: channels.subscribe.bind(channels), + subscribeFor: channels.subscribeFor.bind(channels), + publish: channels.publish.bind(channels), + setPath: channels.setPath.bind(channels), + setPaths: channels.setPaths.bind(channels), + all: channels.all.bind(channels), + list: channels.list.bind(channels), + get: channels.get.bind(channels), + join: channels.join.bind(channels), + leave: channels.leave.bind(channels), + restrict: channels.restrict.bind(channels), + getRestrictions: channels.getRestrictions.bind(channels), + clearChannelData: channels.clearChannelData.bind(channels), + restrictAll: channels.restrictAll.bind(channels), + current: channels.current.bind(channels), + my: channels.my.bind(channels), + changed: channels.changed.bind(channels), + onChanged: channels.onChanged.bind(channels), + add: channels.add.bind(channels), + remove: channels.remove.bind(channels), + getWindowsOnChannel: channels.getWindowsOnChannel.bind(channels), + getWindowsWithChannels: channels.getWindowsWithChannels.bind(channels), + getMy: channels.getMy.bind(channels), + ready: async () => { + await Promise.all([contexts.ready(), channelsReadyPromise]); + }, + get mode() { return channels.mode; }, + getMyChannels: channels.getMyChannels.bind(channels), + myChannels: channels.myChannels.bind(channels), + onChannelsChanged: channels.onChannelsChanged.bind(channels), + }; + } + + const CommandMethod = "T42.Hotkeys.Command"; + const InvokeMethod = "T42.Hotkeys.Invoke"; + const RegisterCommand = "register"; + const UnregisterCommand = "unregister"; + const UnregisterAllCommand = "unregisterAll"; + class HotkeysImpl { + constructor(agm) { + this.agm = agm; + this.registry = CallbackRegistryFactory(); + this.firstHotkey = true; + this.hotkeys = new Map(); + } + async register(info, callback) { + if (typeof info === "undefined") { + throw new Error("Hotkey parameter missing"); + } + if (typeof info === "string") { + info = { + hotkey: info + }; + } + else { + if (!info.hotkey) { + throw new Error("Info's hotkey parameter missing"); + } + info = { + hotkey: info.hotkey, + description: info.description + }; + } + const hkToLower = this.formatHotkey(info.hotkey); + if (this.hotkeys.has(hkToLower)) { + throw new Error(`Shortcut for ${hkToLower} already registered`); + } + if (this.firstHotkey) { + this.firstHotkey = false; + await this.registerInvokeAGMMethod(); + } + this.registry.add(hkToLower, callback); + await this.agm.invoke(CommandMethod, { command: RegisterCommand, hotkey: hkToLower, description: info.description }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + this.hotkeys.set(hkToLower, info); + } + async unregister(hotkey) { + if (typeof hotkey === "undefined") { + throw new Error("hotkey parameter missing"); + } + if (typeof hotkey !== "string") { + throw new Error("hotkey parameter must be string"); + } + const hkToLower = this.formatHotkey(hotkey); + await this.agm.invoke(CommandMethod, { command: UnregisterCommand, hotkey: hkToLower }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + this.hotkeys.delete(hkToLower); + this.registry.clearKey(hkToLower); + } + async unregisterAll() { + await this.agm.invoke(CommandMethod, { command: UnregisterAllCommand }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + this.hotkeys.clear(); + this.registry.clear(); + } + isRegistered(hotkey) { + const hkToLower = this.formatHotkey(hotkey); + return this.hotkeys.has(hkToLower); + } + registerInvokeAGMMethod() { + return this.agm.register(InvokeMethod, (args) => { + const hkToLower = args.key.toLowerCase(); + const info = this.hotkeys.get(hkToLower); + this.registry.execute(hkToLower, info); + }); + } + formatHotkey(hotkey) { + if (hotkey) { + return hotkey.replace(/\s/g, "").toLowerCase(); + } + } + } + + function factory$3(agm) { + const hotkeys = new HotkeysImpl(agm); + return { + register: hotkeys.register.bind(hotkeys), + unregister: hotkeys.unregister.bind(hotkeys), + unregisterAll: hotkeys.unregisterAll.bind(hotkeys), + isRegistered: hotkeys.isRegistered.bind(hotkeys), + ready: () => Promise.resolve() + }; + } + + var version = "6.12.0"; + + var prepareConfig = (options) => { + function getLibConfig(value, defaultMode, trueMode) { + if (typeof value === "boolean" && !value) { + return undefined; + } + const mode = getModeAsString(value, defaultMode, trueMode); + if (typeof mode === "undefined") { + return undefined; + } + if (typeof value === "object") { + value.mode = mode; + return value; + } + return { + mode, + }; + } + function getModeAsString(value, defaultMode, trueMode) { + if (typeof value === "object") { + return getModeAsString(value.mode, defaultMode, trueMode).toString(); + } + else if (typeof value === "undefined") { + if (typeof defaultMode === "boolean" && !defaultMode) { + return undefined; + } + else if (typeof defaultMode === "boolean" && defaultMode) { + return typeof trueMode === "undefined" ? defaultMode : trueMode; + } + else if (typeof defaultMode === "undefined") { + return undefined; + } + else { + return defaultMode; + } + } + else if (typeof value === "boolean") { + if (value) { + return (typeof trueMode === "undefined") ? defaultMode : trueMode; + } + else { + return undefined; + } + } + return value; + } + const appDefaultMode = true; + const appDefaultTrueMode = "startOnly"; + const activitiesDefaultMode = Utils.isNode() ? false : "trackMyTypeAndInitiatedFromMe"; + const activitiesTrueMode = "trackMyTypeAndInitiatedFromMe"; + const layoutsDefaultMode = "slim"; + const layoutsTrueMode = layoutsDefaultMode; + const channelsConfig = () => { + if (typeof options.channels === "boolean") { + return options.channels; + } + else if (typeof options.channels === "object" && typeof options.channels.enabled === "boolean" && options.channels.enabled) { + return { mode: true, ...options.channels }; + } + else { + return false; + } + }; + const exposeAPI = typeof options.exposeAPI === "boolean" || typeof options.exposeGlue === "boolean"; + return { + layouts: getLibConfig(options.layouts, layoutsDefaultMode, layoutsTrueMode), + activities: getLibConfig(options.activities, activitiesDefaultMode, activitiesTrueMode), + appManager: getLibConfig(options.appManager, appDefaultMode, appDefaultTrueMode), + windows: getLibConfig(options.windows, true, true), + channels: getLibConfig(channelsConfig(), false, true), + displays: getLibConfig(options.displays, true, true), + exposeAPI: exposeAPI ? exposeAPI : true + }; + }; + + class Glue42Notification { + constructor(options) { + this.options = options; + this.callbacks = CallbackRegistryFactory(); + this.actions = options.actions; + this.body = options.body; + this.badge = options.badge; + this.data = options.data; + this.dir = options.dir; + this.icon = options.icon; + this.image = options.image; + this.lang = options.lang; + this.renotify = options.renotify; + this.requireInteraction = options.requireInteraction; + this.silent = options.silent; + this.tag = options.tag; + this.timestamp = options.timestamp; + this.title = options.title; + } + close() { + throw new Error("Method not implemented."); + } + addEventListener(type, listener, options) { + this.callbacks.add(type, listener); + } + removeEventListener(type, listener, options) { + } + dispatchEvent(event) { + this.callbacks.execute(event.type, event); + return true; + } + } + + class PanelAPI { + constructor(interop, onStreamEvent) { + this.interop = interop; + this.onStreamEvent = onStreamEvent; + } + onVisibilityChanged(callback) { + return this.onStreamEvent("on-panel-visibility-changed", callback); + } + toggle() { + return this.interop.invoke("T42.Notifications.Show", undefined, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + show() { + return this.interop.invoke("T42.Notifications.Show", { show: true }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + hide() { + return this.interop.invoke("T42.Notifications.Hide"); + } + async isVisible() { + const interopResult = await this.interop.invoke("T42.Notifications.Execute", { command: "isPanelVisible" }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return interopResult.returned.panelVisible; + } + toAPI() { + return { + onVisibilityChanged: this.onVisibilityChanged.bind(this), + toggle: this.toggle.bind(this), + show: this.show.bind(this), + hide: this.hide.bind(this), + isVisible: this.isVisible.bind(this) + }; + } + } + + const STARTING_INDEX = 0; + class Notifications { + constructor(interop, logger) { + this.interop = interop; + this.NotificationsSubscribeStream = "T42.GNS.Subscribe.Notifications"; + this.NotificationsCounterStream = "T42.Notifications.Counter"; + this.RaiseNotificationMethodName = "T42.GNS.Publish.RaiseNotification"; + this.NotificationsExecuteMethod = "T42.Notifications.Execute"; + this.NotificationFilterMethodName = "T42.Notifications.Filter"; + this.methodsRegistered = false; + this.NOTIFICATIONS_CONFIGURE_METHOD_NAME = "T42.Notifications.Configure"; + this.methodNameRoot = "T42.Notifications.Handler-" + Utils.generateId(); + this.nextId = 0; + this.notifications = {}; + this.registry = CallbackRegistryFactory(); + this.subscribedForNotifications = false; + this.subscribedCounterStream = false; + this.subscriptionsCountForNotifications = 0; + this.subscriptionsCountForCounter = 0; + this.logger = logger.subLogger("notifications"); + this._panel = new PanelAPI(interop, this.onStreamEventCore.bind(this)); + this._panelAPI = this._panel.toAPI(); + this.subscribeInternalEvents(); + } + get maxActions() { + return 10; + } + get panel() { + return this._panelAPI; + } + async raise(options) { + var _a; + const notification = await this.createNotification(options); + const g42notification = new Glue42Notification(options); + this.notifications[notification.id] = g42notification; + try { + const invocationResult = await this.interop.invoke(this.RaiseNotificationMethodName, { notification }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + g42notification.id = (_a = invocationResult.returned) === null || _a === void 0 ? void 0 : _a.id; + } + catch (err) { + const errorMessage = err.message; + setTimeout(() => { + this.handleNotificationErrorEvent(g42notification, errorMessage); + }, 1); + } + return g42notification; + } + async setFilter(filter) { + const result = await this.interop.invoke(this.NotificationFilterMethodName, filter, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return result.returned; + } + async getFilter() { + const result = await this.interop.invoke(this.NotificationFilterMethodName, undefined, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return result.returned; + } + async configure(options) { + var _a, _b, _c, _d, _e, _f, _g, _h; + if (!options || Array.isArray(options)) { + throw new Error("Invalid options - should be an object."); + } + if (Object.values(options).length === 0) { + throw new Error("The argument must be a non-empty object."); + } + if (typeof options.enable !== "undefined" && typeof options.enable !== "boolean") { + throw new Error("Expected type of enabled - boolean."); + } + if (typeof options.enableToasts !== "undefined" && typeof options.enableToasts !== "boolean") { + throw new Error("Expected type of enableToasts - boolean."); + } + if (typeof options.toastExpiry !== "undefined" && typeof options.toastExpiry !== "number") { + throw new Error("Expected type of toastExpiry - number."); + } + if (options.sourceFilter && typeof options.sourceFilter !== "object") { + throw new Error("Expected type of sourceFilter - object."); + } + if (((_a = options.sourceFilter) === null || _a === void 0 ? void 0 : _a.allowed) && !Array.isArray((_b = options.sourceFilter) === null || _b === void 0 ? void 0 : _b.allowed)) { + throw new Error("Expected type of sourceFilter.allowed - array."); + } + if (((_c = options.sourceFilter) === null || _c === void 0 ? void 0 : _c.blocked) && !Array.isArray((_d = options.sourceFilter) === null || _d === void 0 ? void 0 : _d.blocked)) { + throw new Error("Expected type of sourceFilter.blocked - array."); + } + if (options.toasts && typeof options.toasts !== "object") { + throw new Error("Expected type of (options.toasts - object."); + } + if (((_e = options.toasts) === null || _e === void 0 ? void 0 : _e.mode) && typeof options.toasts.mode !== "string") { + throw new Error("Expected type of (options.toasts.mode - string."); + } + if (((_f = options.toasts) === null || _f === void 0 ? void 0 : _f.stackBy) && typeof options.toasts.stackBy !== "string") { + throw new Error("Expected type of (options.toasts.stackBy - string."); + } + if (options.placement && typeof options.placement !== "object") { + throw new Error("Expected type of (options.placement - object."); + } + if (((_g = options.placement) === null || _g === void 0 ? void 0 : _g.toasts) && typeof options.placement.toasts !== "string") { + throw new Error("Expected type of (options.placement.toasts - string."); + } + if (((_h = options.placement) === null || _h === void 0 ? void 0 : _h.panel) && typeof options.placement.panel !== "string") { + throw new Error("Expected type of (options.placement.panel - string."); + } + if (typeof options.closeNotificationOnClick !== "undefined" && typeof options.closeNotificationOnClick !== "boolean") { + throw new Error("Expected type of closeNotificationOnClick - boolean."); + } + const result = await this.interop.invoke(this.NOTIFICATIONS_CONFIGURE_METHOD_NAME, options, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return result.returned; + } + async getConfiguration() { + const result = await this.interop.invoke(this.NotificationsExecuteMethod, { command: "getConfiguration" }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return result.returned; + } + async list() { + const interopResult = await this.interop.invoke(this.NotificationsExecuteMethod, { + command: "list", + data: { statesVersion2: true } + }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return interopResult.returned.notifications; + } + async updateData(id, data) { + const replacer = (key, value) => typeof value === "undefined" ? null : value; + const attribute = { + key: "data", + value: { + stringValue: JSON.stringify(data, replacer) + } + }; + const interopResult = await this.interop.invoke(this.NotificationsExecuteMethod, { command: "create-or-update-attribute", data: { id, attribute } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return interopResult.returned; + } + onRaised(callback) { + return this.onStreamEventCore("on-notification-raised", callback); + } + onStateChanged(callback) { + return this.onStreamEventCore("on-state-changed", callback); + } + onClosed(callback) { + return this.onStreamEventCore("on-notification-closed", callback); + } + onConfigurationChanged(callback) { + if (typeof callback !== "function") { + throw new Error("Please provide the callback as a function!"); + } + this.subscribe(); + const un = this.registry.add("on-configuration-changed", callback); + return () => { + un(); + this.closeStreamSubscriptionIfNoNeeded(); + }; + } + onCounterChanged(callback) { + if (typeof callback !== "function") { + throw new Error("Please provide the callback as a function!"); + } + this.subscribeForCounterStream(); + const un = this.registry.add("on-counter-changed", callback); + return () => { + un(); + this.closeStreamCounterSubscriptionIfNoNeeded(); + }; + } + onDataChanged(callback) { + if (typeof callback !== "function") { + throw new Error("Please provide the callback as a function!"); + } + this.subscribe(); + const un = this.registry.add("on-notification-data-changed", callback); + return () => { + un(); + this.closeStreamSubscriptionIfNoNeeded(); + }; + } + async clearAll() { + await this.interop.invoke(this.NotificationsExecuteMethod, { command: "clearAll" }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async clearOld() { + await this.interop.invoke(this.NotificationsExecuteMethod, { command: "clearAllOld", data: { statesVersion2: true } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async clear(id) { + if (!id) { + throw new Error("The 'id' argument cannot be null or undefined"); + } + if (typeof (id) !== "string") { + throw new Error("The 'id' argument must be a string"); + } + await this.interop.invoke(this.NotificationsExecuteMethod, { command: "clear", data: { id } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async clearMany(notifications) { + this.validateNotificationsArr(notifications); + await this.interop.invoke(this.NotificationsExecuteMethod, { command: "clearMany", data: { notifications } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async click(id, action, options) { + await this.interop.invoke(this.NotificationsExecuteMethod, { command: "click", data: { id, action, options } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async snooze(id, duration) { + await this.interop.invoke(this.NotificationsExecuteMethod, { command: "snooze", data: { id, duration } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async snoozeMany(notifications, duration) { + if (!duration) { + throw new Error("The 'duration' argument cannot be null or undefined"); + } + if (typeof duration !== "number") { + throw new Error("The 'duration' argument must be a valid number"); + } + this.validateNotificationsArr(notifications); + await this.interop.invoke(this.NotificationsExecuteMethod, { command: "snoozeMany", data: { notifications, duration } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async setState(id, state) { + if (!id) { + throw new Error("The 'id' argument cannot be null or undefined"); + } + if (typeof (id) !== "string") { + throw new Error("The 'id' argument must be a string"); + } + if (!state) { + throw new Error("The 'state' argument cannot be null or undefined"); + } + this.validateState(state); + await this.interop.invoke(this.NotificationsExecuteMethod, { command: "updateState", data: { id, state } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async setStates(notifications, state) { + if (!state) { + throw new Error("The 'state' argument cannot be null or undefined"); + } + if (typeof state !== "string") { + throw new Error("The 'state' argument must be a valid string"); + } + this.validateNotificationsArr(notifications); + await this.interop.invoke(this.NotificationsExecuteMethod, { command: "updateStates", data: { notifications, state } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + toAPI() { + return { + maxActions: this.maxActions, + panel: this._panel.toAPI(), + raise: this.raise.bind(this), + setFilter: this.setFilter.bind(this), + getFilter: this.getFilter.bind(this), + configure: this.configure.bind(this), + getConfiguration: this.getConfiguration.bind(this), + list: this.list.bind(this), + onRaised: this.onRaised.bind(this), + onStateChanged: this.onStateChanged.bind(this), + onClosed: this.onClosed.bind(this), + onConfigurationChanged: this.onConfigurationChanged.bind(this), + onCounterChanged: this.onCounterChanged.bind(this), + onDataChanged: this.onDataChanged.bind(this), + clearAll: this.clearAll.bind(this), + clearOld: this.clearOld.bind(this), + clear: this.clear.bind(this), + click: this.click.bind(this), + setState: this.setState.bind(this), + updateData: this.updateData.bind(this), + snooze: this.snooze.bind(this), + snoozeMany: this.snoozeMany.bind(this), + clearMany: this.clearMany.bind(this), + setStates: this.setStates.bind(this), + import: this.importNotifications.bind(this) + }; + } + async importNotifications(notifications) { + if (!notifications || !Array.isArray(notifications) || notifications.length === 0) { + throw new Error("Notifications argument must be a valid array with notification options"); + } + const notificationsToImport = await Promise.all(notifications.map((notificationOptions) => this.createNotification(notificationOptions, true))); + const invocationResult = await this.interop.invoke(this.NotificationsExecuteMethod, { command: "importNotifications", data: { notificationSettings: notificationsToImport } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return invocationResult.returned.notifications; + } + async createNotification(options, imported) { + var _a, _b, _c, _d; + this.validate(options, imported); + if (!this.methodsRegistered) { + const bunchOfPromises = []; + for (let index = STARTING_INDEX; index < this.maxActions; index++) { + bunchOfPromises.push(this.interop.register(`${this.methodNameRoot}_${index}`, this.handleNotificationEvent.bind(this))); + } + this.methodsRegistered = true; + await Promise.all(bunchOfPromises); + } + const id = (_a = options.id) !== null && _a !== void 0 ? _a : Utils.generateId(); + const type = (_b = options.type) !== null && _b !== void 0 ? _b : "Notification"; + const notification = { + id, + state: (_c = options.state) !== null && _c !== void 0 ? _c : "Active", + title: options.title, + type, + severity: (_d = options.severity) !== null && _d !== void 0 ? _d : "None", + description: options.body, + glueRoutingDetailMethodName: `${this.methodNameRoot}_${STARTING_INDEX}`, + actions: [], + sourceId: id, + source: options.source, + publishExtraEvents: true, + clickInterop: options.clickInterop + }; + if (options.actions) { + this.handleActions(options, id, notification); + } + this.handleOptions(options, notification); + return notification; + } + onStreamEventCore(key, callback) { + if (typeof callback !== "function") { + throw new Error("Please provide the callback as a function!"); + } + this.subscribe(); + const un = this.registry.add(key, callback); + return () => { + un(); + this.closeStreamSubscriptionIfNoNeeded(); + }; + } + handleOptions(options, notification) { + if (options.icon) { + notification.attributes = notification.attributes || []; + notification.attributes.push({ key: "icon", value: { stringValue: options.icon } }); + } + if (options.data) { + notification.attributes = notification.attributes || []; + const dataAsString = JSON.stringify(options.data); + notification.attributes.push({ key: "data", value: { stringValue: dataAsString } }); + } + if (typeof options.panelExpiry === "number") { + notification.attributes = notification.attributes || []; + notification.attributes.push({ key: "panelExpiry", value: { stringValue: options.panelExpiry.toString() } }); + } + if (typeof options.toastExpiry === "number") { + notification.attributes = notification.attributes || []; + notification.attributes.push({ key: "toastExpiry", value: { stringValue: options.toastExpiry.toString() } }); + } + } + handleActions(options, id, notification) { + var _a, _b, _c; + const validActions = options.actions.slice(0, this.maxActions); + let index = STARTING_INDEX; + for (const action of validActions) { + const args = { + g42notificationId: id, + g42action: action.action, + g42interopMethod: (_a = action.interop) === null || _a === void 0 ? void 0 : _a.method, + g42interopTarget: (_b = action.interop) === null || _b === void 0 ? void 0 : _b.target, + g42interopArguments: JSON.stringify((_c = action.interop) === null || _c === void 0 ? void 0 : _c.arguments) + }; + const parameters = Object.keys(args).map((key) => { + const value = args[key]; + return { + name: key, + value: { + stringValue: value + } + }; + }); + const glueAction = { + name: `${this.methodNameRoot}_${index}`, + description: action.title, + displayName: action.title, + displayPath: action.displayPath, + displayId: action.displayId, + parameters + }; + notification.actions.push(glueAction); + index++; + } + } + validate(options, imported) { + if (!options) { + throw new Error("invalid options - should be an object"); + } + if (typeof options !== "object") { + throw new Error("invalid options - should be an object"); + } + if (!options.title) { + throw new Error("invalid options - should have a title"); + } + if (typeof options.title !== "string") { + throw new Error("invalid options - title should be a string"); + } + if (options.severity && typeof options.severity !== "string") { + throw new Error("invalid options - severity should be a string"); + } + if (options.panelExpiry && typeof options.panelExpiry !== "number") { + throw new Error("invalid options - panelExpiry should be a number"); + } + if (options.toastExpiry && typeof options.toastExpiry !== "number") { + throw new Error("invalid options - toastExpiry should be a number"); + } + if (options.state) { + this.validateState(options.state, imported); + } + } + validateState(state, imported) { + if (typeof (state) !== "string") { + throw new Error("The 'state' argument must be a string"); + } + const validStates = [ + "Active", + "Acknowledged", + "Stale" + ]; + if (imported) { + validStates.push("Seen", "Snoozed", "Processing", "Closed"); + } + if (!validStates.includes(state)) { + throw new Error(`The state argument: ${state} is not valid!`); + } + } + subscribe() { + this.subscriptionsCountForNotifications++; + if (!this.subscribedForNotifications) { + this.subscribedForNotifications = true; + this.logger.info(`Attempting to subscribe to "${this.NotificationsSubscribeStream}".`); + this.interop + .subscribe(this.NotificationsSubscribeStream, { + arguments: { + sendDeltaOnly: true, + statesVersion2: true + } + }) + .then((sub) => { + this.subscriptionForNotifications = sub; + this.logger.info(`Successfully subscribed to "${this.NotificationsSubscribeStream}".`); + sub.onData(({ data }) => { + this.handleData(data); + }); + sub.onClosed((...args) => { + this.subscribedForNotifications = false; + this.logger.info(`Stream subscription Closed - ${JSON.stringify(args)}`); + }); + sub.onFailed((...args) => { + this.subscribedForNotifications = false; + this.logger.warn(`Stream subscription Failed - ${JSON.stringify(args)}`); + }); + }) + .catch((e) => { + this.subscribedForNotifications = false; + this.logger.error(`Unable to subscribe to "${this.NotificationsSubscribeStream}"`, e); + }); + } + } + subscribeForCounterStream() { + this.subscriptionsCountForCounter++; + if (!this.subscribedCounterStream) { + this.subscribedCounterStream = true; + this.logger.info(`Attempting to subscribe to "${this.NotificationsCounterStream}".`); + this.interop + .subscribe(this.NotificationsCounterStream, { + arguments: { + sendDeltaOnly: true + } + }) + .then((sub) => { + this.subscriptionForCounter = sub; + this.logger.info(`Successfully subscribed to "${this.NotificationsCounterStream}".`); + sub.onData(({ data }) => { + this.registry.execute("on-counter-changed", { count: data.count }); + }); + sub.onClosed((...args) => { + this.subscribedCounterStream = false; + this.logger.info(`Stream subscription Closed - ${JSON.stringify(args)}`); + }); + sub.onFailed((...args) => { + this.subscribedCounterStream = false; + this.logger.warn(`Stream subscription Failed - ${JSON.stringify(args)}`); + }); + }) + .catch((e) => { + this.subscribedCounterStream = false; + this.logger.error(`Unable to subscribe to "${this.NotificationsCounterStream}"`, e); + }); + } + } + subscribeInternalEvents() { + this.registry.add("on-notification-closed", (id) => { + this.handleOnClosed(id); + }); + this.registry.add("on-notification-raised", (notification) => { + this.handleOnShow(notification.id); + }); + } + handleData(message) { + var _a; + try { + if ("items" in message && Array.isArray(message.items)) { + this.handleItemsData(message); + } + else if ("deltas" in message && Array.isArray(message.deltas)) { + this.handleDeltas(message); + } + if ("configuration" in message && typeof message.configuration === "object") { + this.logger.info(`Received configuration ${JSON.stringify(message.configuration)} from the stream`); + this.registry.execute("on-configuration-changed", message.configuration, message.configuration.allApplications); + } + if ("command" in message && typeof message.command === "string") { + this.logger.info(`Received command "${(_a = message.command) !== null && _a !== void 0 ? _a : JSON.stringify(message)}" from the stream`); + if (message.command === "showPanel" || message.command === "hidePanel") { + this.registry.execute("on-panel-visibility-changed", message.command === "showPanel"); + } + } + } + catch (e) { + this.logger.error(`Failed to parse data from the stream`, e); + } + } + handleItemsData(message) { + const items = message.items; + this.logger.info(`Received ${items.length} notifications from the stream`); + const notifications = items; + if (message.isSnapshot) { + notifications.forEach((n) => { + this.registry.execute("on-notification-raised", n); + }); + } + else { + const notification = notifications[0]; + if (notification.state === "Closed") { + this.registry.execute("on-notification-closed", { id: notification.id }); + } + else { + this.registry.execute("on-notification-raised", notification); + } + } + } + handleDeltas(message) { + const deltas = message.deltas; + deltas.forEach((info) => { + var _a; + const id = info.id; + const delta = (_a = info.delta) !== null && _a !== void 0 ? _a : {}; + if (delta.state === "Closed") { + this.registry.execute("on-notification-closed", { id, ...delta }); + } + else if (delta.state) { + this.registry.execute("on-state-changed", { id }, delta.state); + } + else if (delta.attributes) { + const attributes = delta.attributes; + const dataAttribute = attributes.find((a) => a.key === "data"); + if (dataAttribute) { + this.registry.execute("on-notification-data-changed", { id }, JSON.parse(dataAttribute.value.stringValue)); + } + } + }); + } + handleOnClosed(id) { + const { notification, key } = this.getNotification(id); + if (notification) { + this.handleEvent(notification, "close"); + delete this.notifications[key]; + } + } + handleOnShow(id) { + const { notification } = this.getNotification(id); + if (notification) { + this.handleEvent(notification, "show"); + } + } + getNotification(id) { + let notification; + let key; + for (const k in this.notifications) { + if (this.notifications[k].id === id) { + notification = this.notifications[k]; + key = k; + break; + } + } + return { notification, key }; + } + handleNotificationEvent(args) { + const gnsNotificationArgs = this.getGnsNotificationArgs(args); + if (gnsNotificationArgs.event === "unknown") { + return; + } + const notification = this.notifications[gnsNotificationArgs.notificationId]; + if (!notification) { + return; + } + this.handleNotificationEventCore(notification, gnsNotificationArgs); + } + handleNotificationEventCore(notification, args) { + switch (args.event) { + case "action": { + return this.handleNotificationActionEvent(notification, args.notificationActionPayload); + } + case "click": { + return this.handleNotificationClickEvent(notification); + } + case "close": { + return this.handleEvent(notification, "close"); + } + case "error": { + return this.handleNotificationErrorEvent(notification, args.error); + } + case "show": { + return this.handleEvent(notification, "show"); + } + } + } + handleNotificationActionEvent(notification, payload) { + const event = { + type: "onaction", + action: payload.g42action + }; + if (notification.onaction) { + notification.onaction(event); + } + notification.dispatchEvent(event); + } + handleNotificationClickEvent(notification) { + const event = { type: "onclick" }; + if (notification.onclick) { + notification.onclick(event); + } + notification.dispatchEvent(event); + } + handleEvent(notification, eventType) { + var _a; + const event = { type: eventType }; + const eventName = `on${eventType}`; + (_a = notification[eventName]) === null || _a === void 0 ? void 0 : _a.call(notification, event); + notification.dispatchEvent(event); + } + handleNotificationErrorEvent(notification, error) { + const event = { type: "onerror", error }; + if (notification.onerror) { + notification.onerror(event); + } + notification.dispatchEvent(event); + } + getGnsNotificationArgs(args) { + var _a; + let result; + const event = (_a = args.notification) === null || _a === void 0 ? void 0 : _a.event; + if (!event) { + result = this.getBackwardGnsNotificationArgs(args); + } + else { + result = { + event, + notificationId: args.notification.sourceNotificationId, + notificationActionPayload: args + }; + } + return result; + } + getBackwardGnsNotificationArgs(args) { + var _a; + let result; + if (args.g42notificationId) { + result = { + event: "action", + notificationId: args.g42notificationId, + notificationActionPayload: args + }; + } + else if ((_a = args.notification) === null || _a === void 0 ? void 0 : _a.sourceNotificationId) { + result = { + event: "click", + notificationId: args.notification.sourceNotificationId, + notificationActionPayload: args + }; + } + else { + result = { + event: "unknown", + notificationId: undefined, + notificationActionPayload: args + }; + } + return result; + } + closeStreamSubscriptionIfNoNeeded() { + this.subscriptionsCountForNotifications--; + if (this.subscriptionForNotifications && this.subscriptionsCountForNotifications === 0) { + this.subscriptionForNotifications.close(); + this.subscriptionForNotifications = undefined; + } + } + closeStreamCounterSubscriptionIfNoNeeded() { + this.subscriptionsCountForCounter--; + if (this.subscriptionForCounter && this.subscriptionsCountForCounter === 0) { + this.subscriptionForCounter.close(); + this.subscriptionForCounter = undefined; + } + } + validateNotificationsArr(notifications) { + if (!Array.isArray(notifications)) { + throw new Error("The 'notifications' argument must be an array with valid notification IDs"); + } + if (notifications.some((n) => typeof n !== "string")) { + throw new Error("The 'notifications' argument must contain only valid string notification IDs"); + } + } + } + + const ThemesConfigurationMethodName = "T42.Themes.Configuration"; + class ThemesImpl { + constructor(contexts, interop) { + this.contexts = contexts; + this.interop = interop; + this.registry = CallbackRegistryFactory(); + this.isSubscribed = false; + this.getConfiguration(); + } + async list() { + await this.getConfiguration(); + if (!this.getMethodName) { + throw new Error("not supported"); + } + return (await this.getAll()).returned.all; + } + async getCurrent() { + await this.getConfiguration(); + if (!this.getMethodName) { + throw new Error("not supported"); + } + const all = await this.getAll(); + return all.returned.all.find((t) => t.name === all.returned.selected); + } + async select(theme) { + await this.getConfiguration(); + if (!this.setMethodName) { + throw new Error("not supported"); + } + await this.interop.invoke(this.setMethodName, { theme }); + } + onChanged(callback) { + if (!callback) { + throw new Error("Callback argument is required"); + } + if (callback && typeof callback !== "function") { + throw new Error("Callback argument must be a function"); + } + this.subscribe(); + return this.registry.add("changed", callback); + } + async getConfiguration() { + try { + if (this.sharedContextName) { + return; + } + const config = await this.interop.invoke(ThemesConfigurationMethodName); + this.sharedContextName = config.returned.sharedContextName; + this.getMethodName = config.returned.getThemesMethodName; + this.setMethodName = config.returned.setThemesMethodName; + } + catch (error) { + return; + } + } + async getAll() { + await this.getConfiguration(); + return await this.interop.invoke(this.getMethodName); + } + async subscribe() { + await this.getConfiguration(); + if (this.isSubscribed) { + return; + } + this.isSubscribed = true; + this.contexts.subscribe(this.sharedContextName, (data) => { + if (data && data.all && data.selected) { + this.registry.execute("changed", data.all.find((t) => t.name === data.selected)); + } + }); + } + } + + function factory$2(contexts, interop) { + const themes = new ThemesImpl(contexts, interop); + return { + list: themes.list.bind(themes), + getCurrent: themes.getCurrent.bind(themes), + select: themes.select.bind(themes), + onChanged: themes.onChanged.bind(themes), + ready: () => Promise.resolve(), + }; + } + + const connectBrowserAppProps = ["name", "title", "version", "customProperties", "icon", "caption", "type"]; + const fdc3v2AppProps = ["appId", "name", "type", "details", "version", "title", "tooltip", "lang", "description", "categories", "icons", "screenshots", "contactEmail", "moreInfo", "publisher", "customConfig", "hostManifests", "interop", "localizedVersions"]; + + /** + * Wraps values in an `Ok` type. + * + * Example: `ok(5) // => {ok: true, result: 5}` + */ + var ok = function (result) { return ({ ok: true, result: result }); }; + /** + * Wraps errors in an `Err` type. + * + * Example: `err('on fire') // => {ok: false, error: 'on fire'}` + */ + var err = function (error) { return ({ ok: false, error: error }); }; + /** + * Create a `Promise` that either resolves with the result of `Ok` or rejects + * with the error of `Err`. + */ + var asPromise = function (r) { + return r.ok === true ? Promise.resolve(r.result) : Promise.reject(r.error); + }; + /** + * Unwraps a `Result` and returns either the result of an `Ok`, or + * `defaultValue`. + * + * Example: + * ``` + * Result.withDefault(5, number().run(json)) + * ``` + * + * It would be nice if `Decoder` had an instance method that mirrored this + * function. Such a method would look something like this: + * ``` + * class Decoder
{ + * runWithDefault = (defaultValue: A, json: any): A => + * Result.withDefault(defaultValue, this.run(json)); + * } + * + * number().runWithDefault(5, json) + * ``` + * Unfortunately, the type of `defaultValue: A` on the method causes issues + * with type inference on the `object` decoder in some situations. While these + * inference issues can be solved by providing the optional type argument for + * `object`s, the extra trouble and confusion doesn't seem worth it. + */ + var withDefault = function (defaultValue, r) { + return r.ok === true ? r.result : defaultValue; + }; + /** + * Return the successful result, or throw an error. + */ + var withException = function (r) { + if (r.ok === true) { + return r.result; + } + else { + throw r.error; + } + }; + /** + * Apply `f` to the result of an `Ok`, or pass the error through. + */ + var map = function (f, r) { + return r.ok === true ? ok(f(r.result)) : r; + }; + /** + * Apply `f` to the result of two `Ok`s, or pass an error through. If both + * `Result`s are errors then the first one is returned. + */ + var map2 = function (f, ar, br) { + return ar.ok === false ? ar : + br.ok === false ? br : + ok(f(ar.result, br.result)); + }; + /** + * Apply `f` to the error of an `Err`, or pass the success through. + */ + var mapError = function (f, r) { + return r.ok === true ? r : err(f(r.error)); + }; + /** + * Chain together a sequence of computations that may fail, similar to a + * `Promise`. If the first computation fails then the error will propagate + * through. If it succeeds, then `f` will be applied to the value, returning a + * new `Result`. + */ + var andThen = function (f, r) { + return r.ok === true ? f(r.result) : r; + }; + + /*! ***************************************************************************** + Copyright (c) Microsoft Corporation. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THIS SOFTWARE. + ***************************************************************************** */ + /* global Reflect, Promise */ + + + + var __assign = function() { + __assign = Object.assign || function __assign(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; + } + return t; + }; + return __assign.apply(this, arguments); + }; + + function __rest(s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { + if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) + t[p[i]] = s[p[i]]; + } + return t; + } + + function isEqual(a, b) { + if (a === b) { + return true; + } + if (a === null && b === null) { + return true; + } + if (typeof (a) !== typeof (b)) { + return false; + } + if (typeof (a) === 'object') { + // Array + if (Array.isArray(a)) { + if (!Array.isArray(b)) { + return false; + } + if (a.length !== b.length) { + return false; + } + for (var i = 0; i < a.length; i++) { + if (!isEqual(a[i], b[i])) { + return false; + } + } + return true; + } + // Hash table + var keys = Object.keys(a); + if (keys.length !== Object.keys(b).length) { + return false; + } + for (var i = 0; i < keys.length; i++) { + if (!b.hasOwnProperty(keys[i])) { + return false; + } + if (!isEqual(a[keys[i]], b[keys[i]])) { + return false; + } + } + return true; + } + } + /* + * Helpers + */ + var isJsonArray = function (json) { return Array.isArray(json); }; + var isJsonObject = function (json) { + return typeof json === 'object' && json !== null && !isJsonArray(json); + }; + var typeString = function (json) { + switch (typeof json) { + case 'string': + return 'a string'; + case 'number': + return 'a number'; + case 'boolean': + return 'a boolean'; + case 'undefined': + return 'undefined'; + case 'object': + if (json instanceof Array) { + return 'an array'; + } + else if (json === null) { + return 'null'; + } + else { + return 'an object'; + } + default: + return JSON.stringify(json); + } + }; + var expectedGot = function (expected, got) { + return "expected " + expected + ", got " + typeString(got); + }; + var printPath = function (paths) { + return paths.map(function (path) { return (typeof path === 'string' ? "." + path : "[" + path + "]"); }).join(''); + }; + var prependAt = function (newAt, _a) { + var at = _a.at, rest = __rest(_a, ["at"]); + return (__assign({ at: newAt + (at || '') }, rest)); + }; + /** + * Decoders transform json objects with unknown structure into known and + * verified forms. You can create objects of type `Decoder` with either the + * primitive decoder functions, such as `boolean()` and `string()`, or by + * applying higher-order decoders to the primitives, such as `array(boolean())` + * or `dict(string())`. + * + * Each of the decoder functions are available both as a static method on + * `Decoder` and as a function alias -- for example the string decoder is + * defined at `Decoder.string()`, but is also aliased to `string()`. Using the + * function aliases exported with the library is recommended. + * + * `Decoder` exposes a number of 'run' methods, which all decode json in the + * same way, but communicate success and failure in different ways. The `map` + * and `andThen` methods modify decoders without having to call a 'run' method. + * + * Alternatively, the main decoder `run()` method returns an object of type + * `Result`. This library provides a number of helper + * functions for dealing with the `Result` type, so you can do all the same + * things with a `Result` as with the decoder methods. + */ + var Decoder = /** @class */ (function () { + /** + * The Decoder class constructor is kept private to separate the internal + * `decode` function from the external `run` function. The distinction + * between the two functions is that `decode` returns a + * `Partial` on failure, which contains an unfinished error + * report. When `run` is called on a decoder, the relevant series of `decode` + * calls is made, and then on failure the resulting `Partial` + * is turned into a `DecoderError` by filling in the missing information. + * + * While hiding the constructor may seem restrictive, leveraging the + * provided decoder combinators and helper functions such as + * `andThen` and `map` should be enough to build specialized decoders as + * needed. + */ + function Decoder(decode) { + var _this = this; + this.decode = decode; + /** + * Run the decoder and return a `Result` with either the decoded value or a + * `DecoderError` containing the json input, the location of the error, and + * the error message. + * + * Examples: + * ``` + * number().run(12) + * // => {ok: true, result: 12} + * + * string().run(9001) + * // => + * // { + * // ok: false, + * // error: { + * // kind: 'DecoderError', + * // input: 9001, + * // at: 'input', + * // message: 'expected a string, got 9001' + * // } + * // } + * ``` + */ + this.run = function (json) { + return mapError(function (error) { return ({ + kind: 'DecoderError', + input: json, + at: 'input' + (error.at || ''), + message: error.message || '' + }); }, _this.decode(json)); + }; + /** + * Run the decoder as a `Promise`. + */ + this.runPromise = function (json) { return asPromise(_this.run(json)); }; + /** + * Run the decoder and return the value on success, or throw an exception + * with a formatted error string. + */ + this.runWithException = function (json) { return withException(_this.run(json)); }; + /** + * Construct a new decoder that applies a transformation to the decoded + * result. If the decoder succeeds then `f` will be applied to the value. If + * it fails the error will propagated through. + * + * Example: + * ``` + * number().map(x => x * 5).run(10) + * // => {ok: true, result: 50} + * ``` + */ + this.map = function (f) { + return new Decoder(function (json) { return map(f, _this.decode(json)); }); + }; + /** + * Chain together a sequence of decoders. The first decoder will run, and + * then the function will determine what decoder to run second. If the result + * of the first decoder succeeds then `f` will be applied to the decoded + * value. If it fails the error will propagate through. + * + * This is a very powerful method -- it can act as both the `map` and `where` + * methods, can improve error messages for edge cases, and can be used to + * make a decoder for custom types. + * + * Example of adding an error message: + * ``` + * const versionDecoder = valueAt(['version'], number()); + * const infoDecoder3 = object({a: boolean()}); + * + * const decoder = versionDecoder.andThen(version => { + * switch (version) { + * case 3: + * return infoDecoder3; + * default: + * return fail(`Unable to decode info, version ${version} is not supported.`); + * } + * }); + * + * decoder.run({version: 3, a: true}) + * // => {ok: true, result: {a: true}} + * + * decoder.run({version: 5, x: 'abc'}) + * // => + * // { + * // ok: false, + * // error: {... message: 'Unable to decode info, version 5 is not supported.'} + * // } + * ``` + * + * Example of decoding a custom type: + * ``` + * // nominal type for arrays with a length of at least one + * type NonEmptyArray = T[] & { __nonEmptyArrayBrand__: void }; + * + * const nonEmptyArrayDecoder = (values: Decoder): Decoder> => + * array(values).andThen(arr => + * arr.length > 0 + * ? succeed(createNonEmptyArray(arr)) + * : fail(`expected a non-empty array, got an empty array`) + * ); + * ``` + */ + this.andThen = function (f) { + return new Decoder(function (json) { + return andThen(function (value) { return f(value).decode(json); }, _this.decode(json)); + }); + }; + /** + * Add constraints to a decoder _without_ changing the resulting type. The + * `test` argument is a predicate function which returns true for valid + * inputs. When `test` fails on an input, the decoder fails with the given + * `errorMessage`. + * + * ``` + * const chars = (length: number): Decoder => + * string().where( + * (s: string) => s.length === length, + * `expected a string of length ${length}` + * ); + * + * chars(5).run('12345') + * // => {ok: true, result: '12345'} + * + * chars(2).run('HELLO') + * // => {ok: false, error: {... message: 'expected a string of length 2'}} + * + * chars(12).run(true) + * // => {ok: false, error: {... message: 'expected a string, got a boolean'}} + * ``` + */ + this.where = function (test, errorMessage) { + return _this.andThen(function (value) { return (test(value) ? Decoder.succeed(value) : Decoder.fail(errorMessage)); }); + }; + } + /** + * Decoder primitive that validates strings, and fails on all other input. + */ + Decoder.string = function () { + return new Decoder(function (json) { + return typeof json === 'string' + ? ok(json) + : err({ message: expectedGot('a string', json) }); + }); + }; + /** + * Decoder primitive that validates numbers, and fails on all other input. + */ + Decoder.number = function () { + return new Decoder(function (json) { + return typeof json === 'number' + ? ok(json) + : err({ message: expectedGot('a number', json) }); + }); + }; + /** + * Decoder primitive that validates booleans, and fails on all other input. + */ + Decoder.boolean = function () { + return new Decoder(function (json) { + return typeof json === 'boolean' + ? ok(json) + : err({ message: expectedGot('a boolean', json) }); + }); + }; + Decoder.constant = function (value) { + return new Decoder(function (json) { + return isEqual(json, value) + ? ok(value) + : err({ message: "expected " + JSON.stringify(value) + ", got " + JSON.stringify(json) }); + }); + }; + Decoder.object = function (decoders) { + return new Decoder(function (json) { + if (isJsonObject(json) && decoders) { + var obj = {}; + for (var key in decoders) { + if (decoders.hasOwnProperty(key)) { + var r = decoders[key].decode(json[key]); + if (r.ok === true) { + // tslint:disable-next-line:strict-type-predicates + if (r.result !== undefined) { + obj[key] = r.result; + } + } + else if (json[key] === undefined) { + return err({ message: "the key '" + key + "' is required but was not present" }); + } + else { + return err(prependAt("." + key, r.error)); + } + } + } + return ok(obj); + } + else if (isJsonObject(json)) { + return ok(json); + } + else { + return err({ message: expectedGot('an object', json) }); + } + }); + }; + Decoder.array = function (decoder) { + return new Decoder(function (json) { + if (isJsonArray(json) && decoder) { + var decodeValue_1 = function (v, i) { + return mapError(function (err$$1) { return prependAt("[" + i + "]", err$$1); }, decoder.decode(v)); + }; + return json.reduce(function (acc, v, i) { + return map2(function (arr, result) { return arr.concat([result]); }, acc, decodeValue_1(v, i)); + }, ok([])); + } + else if (isJsonArray(json)) { + return ok(json); + } + else { + return err({ message: expectedGot('an array', json) }); + } + }); + }; + Decoder.tuple = function (decoders) { + return new Decoder(function (json) { + if (isJsonArray(json)) { + if (json.length !== decoders.length) { + return err({ + message: "expected a tuple of length " + decoders.length + ", got one of length " + json.length + }); + } + var result = []; + for (var i = 0; i < decoders.length; i++) { + var nth = decoders[i].decode(json[i]); + if (nth.ok) { + result[i] = nth.result; + } + else { + return err(prependAt("[" + i + "]", nth.error)); + } + } + return ok(result); + } + else { + return err({ message: expectedGot("a tuple of length " + decoders.length, json) }); + } + }); + }; + Decoder.union = function (ad, bd) { + var decoders = []; + for (var _i = 2; _i < arguments.length; _i++) { + decoders[_i - 2] = arguments[_i]; + } + return Decoder.oneOf.apply(Decoder, [ad, bd].concat(decoders)); + }; + Decoder.intersection = function (ad, bd) { + var ds = []; + for (var _i = 2; _i < arguments.length; _i++) { + ds[_i - 2] = arguments[_i]; + } + return new Decoder(function (json) { + return [ad, bd].concat(ds).reduce(function (acc, decoder) { return map2(Object.assign, acc, decoder.decode(json)); }, ok({})); + }); + }; + /** + * Escape hatch to bypass validation. Always succeeds and types the result as + * `any`. Useful for defining decoders incrementally, particularly for + * complex objects. + * + * Example: + * ``` + * interface User { + * name: string; + * complexUserData: ComplexType; + * } + * + * const userDecoder: Decoder = object({ + * name: string(), + * complexUserData: anyJson() + * }); + * ``` + */ + Decoder.anyJson = function () { return new Decoder(function (json) { return ok(json); }); }; + /** + * Decoder identity function which always succeeds and types the result as + * `unknown`. + */ + Decoder.unknownJson = function () { + return new Decoder(function (json) { return ok(json); }); + }; + /** + * Decoder for json objects where the keys are unknown strings, but the values + * should all be of the same type. + * + * Example: + * ``` + * dict(number()).run({chocolate: 12, vanilla: 10, mint: 37}); + * // => {ok: true, result: {chocolate: 12, vanilla: 10, mint: 37}} + * ``` + */ + Decoder.dict = function (decoder) { + return new Decoder(function (json) { + if (isJsonObject(json)) { + var obj = {}; + for (var key in json) { + if (json.hasOwnProperty(key)) { + var r = decoder.decode(json[key]); + if (r.ok === true) { + obj[key] = r.result; + } + else { + return err(prependAt("." + key, r.error)); + } + } + } + return ok(obj); + } + else { + return err({ message: expectedGot('an object', json) }); + } + }); + }; + /** + * Decoder for values that may be `undefined`. This is primarily helpful for + * decoding interfaces with optional fields. + * + * Example: + * ``` + * interface User { + * id: number; + * isOwner?: boolean; + * } + * + * const decoder: Decoder = object({ + * id: number(), + * isOwner: optional(boolean()) + * }); + * ``` + */ + Decoder.optional = function (decoder) { + return new Decoder(function (json) { return (json === undefined || json === null ? ok(undefined) : decoder.decode(json)); }); + }; + /** + * Decoder that attempts to run each decoder in `decoders` and either succeeds + * with the first successful decoder, or fails after all decoders have failed. + * + * Note that `oneOf` expects the decoders to all have the same return type, + * while `union` creates a decoder for the union type of all the input + * decoders. + * + * Examples: + * ``` + * oneOf(string(), number().map(String)) + * oneOf(constant('start'), constant('stop'), succeed('unknown')) + * ``` + */ + Decoder.oneOf = function () { + var decoders = []; + for (var _i = 0; _i < arguments.length; _i++) { + decoders[_i] = arguments[_i]; + } + return new Decoder(function (json) { + var errors = []; + for (var i = 0; i < decoders.length; i++) { + var r = decoders[i].decode(json); + if (r.ok === true) { + return r; + } + else { + errors[i] = r.error; + } + } + var errorsList = errors + .map(function (error) { return "at error" + (error.at || '') + ": " + error.message; }) + .join('", "'); + return err({ + message: "expected a value matching one of the decoders, got the errors [\"" + errorsList + "\"]" + }); + }); + }; + /** + * Decoder that always succeeds with either the decoded value, or a fallback + * default value. + */ + Decoder.withDefault = function (defaultValue, decoder) { + return new Decoder(function (json) { + return ok(withDefault(defaultValue, decoder.decode(json))); + }); + }; + /** + * Decoder that pulls a specific field out of a json structure, instead of + * decoding and returning the full structure. The `paths` array describes the + * object keys and array indices to traverse, so that values can be pulled out + * of a nested structure. + * + * Example: + * ``` + * const decoder = valueAt(['a', 'b', 0], string()); + * + * decoder.run({a: {b: ['surprise!']}}) + * // => {ok: true, result: 'surprise!'} + * + * decoder.run({a: {x: 'cats'}}) + * // => {ok: false, error: {... at: 'input.a.b[0]' message: 'path does not exist'}} + * ``` + * + * Note that the `decoder` is ran on the value found at the last key in the + * path, even if the last key is not found. This allows the `optional` + * decoder to succeed when appropriate. + * ``` + * const optionalDecoder = valueAt(['a', 'b', 'c'], optional(string())); + * + * optionalDecoder.run({a: {b: {c: 'surprise!'}}}) + * // => {ok: true, result: 'surprise!'} + * + * optionalDecoder.run({a: {b: 'cats'}}) + * // => {ok: false, error: {... at: 'input.a.b.c' message: 'expected an object, got "cats"'} + * + * optionalDecoder.run({a: {b: {z: 1}}}) + * // => {ok: true, result: undefined} + * ``` + */ + Decoder.valueAt = function (paths, decoder) { + return new Decoder(function (json) { + var jsonAtPath = json; + for (var i = 0; i < paths.length; i++) { + if (jsonAtPath === undefined) { + return err({ + at: printPath(paths.slice(0, i + 1)), + message: 'path does not exist' + }); + } + else if (typeof paths[i] === 'string' && !isJsonObject(jsonAtPath)) { + return err({ + at: printPath(paths.slice(0, i + 1)), + message: expectedGot('an object', jsonAtPath) + }); + } + else if (typeof paths[i] === 'number' && !isJsonArray(jsonAtPath)) { + return err({ + at: printPath(paths.slice(0, i + 1)), + message: expectedGot('an array', jsonAtPath) + }); + } + else { + jsonAtPath = jsonAtPath[paths[i]]; + } + } + return mapError(function (error) { + return jsonAtPath === undefined + ? { at: printPath(paths), message: 'path does not exist' } + : prependAt(printPath(paths), error); + }, decoder.decode(jsonAtPath)); + }); + }; + /** + * Decoder that ignores the input json and always succeeds with `fixedValue`. + */ + Decoder.succeed = function (fixedValue) { + return new Decoder(function (json) { return ok(fixedValue); }); + }; + /** + * Decoder that ignores the input json and always fails with `errorMessage`. + */ + Decoder.fail = function (errorMessage) { + return new Decoder(function (json) { return err({ message: errorMessage }); }); + }; + /** + * Decoder that allows for validating recursive data structures. Unlike with + * functions, decoders assigned to variables can't reference themselves + * before they are fully defined. We can avoid prematurely referencing the + * decoder by wrapping it in a function that won't be called until use, at + * which point the decoder has been defined. + * + * Example: + * ``` + * interface Comment { + * msg: string; + * replies: Comment[]; + * } + * + * const decoder: Decoder = object({ + * msg: string(), + * replies: lazy(() => array(decoder)) + * }); + * ``` + */ + Decoder.lazy = function (mkDecoder) { + return new Decoder(function (json) { return mkDecoder().decode(json); }); + }; + return Decoder; + }()); + + /* tslint:disable:variable-name */ + /** See `Decoder.string` */ + var string = Decoder.string; + /** See `Decoder.number` */ + var number = Decoder.number; + /** See `Decoder.boolean` */ + var boolean = Decoder.boolean; + /** See `Decoder.anyJson` */ + var anyJson = Decoder.anyJson; + /** See `Decoder.unknownJson` */ + Decoder.unknownJson; + /** See `Decoder.constant` */ + var constant = Decoder.constant; + /** See `Decoder.object` */ + var object = Decoder.object; + /** See `Decoder.array` */ + var array = Decoder.array; + /** See `Decoder.tuple` */ + Decoder.tuple; + /** See `Decoder.dict` */ + var dict = Decoder.dict; + /** See `Decoder.optional` */ + var optional = Decoder.optional; + /** See `Decoder.oneOf` */ + var oneOf = Decoder.oneOf; + /** See `Decoder.union` */ + Decoder.union; + /** See `Decoder.intersection` */ + Decoder.intersection; + /** See `Decoder.withDefault` */ + Decoder.withDefault; + /** See `Decoder.valueAt` */ + Decoder.valueAt; + /** See `Decoder.succeed` */ + Decoder.succeed; + /** See `Decoder.fail` */ + Decoder.fail; + /** See `Decoder.lazy` */ + Decoder.lazy; + + const nonEmptyStringDecoder = string().where((s) => s.length > 0, "Expected a non-empty string"); + const nonNegativeNumberDecoder = number().where((num) => num >= 0, "Expected a non-negative number"); + + const intentDefinitionDecoder = object({ + name: nonEmptyStringDecoder, + displayName: optional(string()), + contexts: optional(array(string())), + customConfig: optional(object()) + }); + const v2TypeDecoder = oneOf(constant("web"), constant("native"), constant("citrix"), constant("onlineNative"), constant("other")); + const v2DetailsDecoder = object({ + url: nonEmptyStringDecoder + }); + const v2IconDecoder = object({ + src: nonEmptyStringDecoder, + size: optional(nonEmptyStringDecoder), + type: optional(nonEmptyStringDecoder) + }); + const v2ScreenshotDecoder = object({ + src: nonEmptyStringDecoder, + size: optional(nonEmptyStringDecoder), + type: optional(nonEmptyStringDecoder), + label: optional(nonEmptyStringDecoder) + }); + const v2ListensForIntentDecoder = object({ + contexts: array(nonEmptyStringDecoder), + displayName: optional(nonEmptyStringDecoder), + resultType: optional(nonEmptyStringDecoder), + customConfig: optional(anyJson()) + }); + const v2IntentsDecoder = object({ + listensFor: optional(dict(v2ListensForIntentDecoder)), + raises: optional(dict(array(nonEmptyStringDecoder))) + }); + const v2UserChannelDecoder = object({ + broadcasts: optional(array(nonEmptyStringDecoder)), + listensFor: optional(array(nonEmptyStringDecoder)) + }); + const v2AppChannelDecoder = object({ + name: nonEmptyStringDecoder, + description: optional(nonEmptyStringDecoder), + broadcasts: optional(array(nonEmptyStringDecoder)), + listensFor: optional(array(nonEmptyStringDecoder)) + }); + const v2InteropDecoder = object({ + intents: optional(v2IntentsDecoder), + userChannels: optional(v2UserChannelDecoder), + appChannels: optional(array(v2AppChannelDecoder)) + }); + const glue42ApplicationDetailsDecoder = object({ + url: optional(nonEmptyStringDecoder), + top: optional(number()), + left: optional(number()), + width: optional(nonNegativeNumberDecoder), + height: optional(nonNegativeNumberDecoder) + }); + const glue42HostManifestsBrowserDecoder = object({ + name: optional(nonEmptyStringDecoder), + type: optional(nonEmptyStringDecoder.where((s) => s === "window", "Expected a value of window")), + title: optional(nonEmptyStringDecoder), + version: optional(nonEmptyStringDecoder), + customProperties: optional(anyJson()), + icon: optional(string()), + caption: optional(string()), + details: optional(glue42ApplicationDetailsDecoder), + intents: optional(array(intentDefinitionDecoder)), + hidden: optional(boolean()) + }); + const v1DefinitionDecoder = object({ + name: nonEmptyStringDecoder, + appId: nonEmptyStringDecoder, + title: optional(nonEmptyStringDecoder), + version: optional(nonEmptyStringDecoder), + manifest: nonEmptyStringDecoder, + manifestType: nonEmptyStringDecoder, + tooltip: optional(nonEmptyStringDecoder), + description: optional(nonEmptyStringDecoder), + contactEmail: optional(nonEmptyStringDecoder), + supportEmail: optional(nonEmptyStringDecoder), + publisher: optional(nonEmptyStringDecoder), + images: optional(array(object({ url: optional(nonEmptyStringDecoder) }))), + icons: optional(array(object({ icon: optional(nonEmptyStringDecoder) }))), + customConfig: anyJson(), + intents: optional(array(intentDefinitionDecoder)) + }); + const v2LocalizedDefinitionDecoder = object({ + appId: optional(nonEmptyStringDecoder), + name: optional(nonEmptyStringDecoder), + details: optional(v2DetailsDecoder), + version: optional(nonEmptyStringDecoder), + title: optional(nonEmptyStringDecoder), + tooltip: optional(nonEmptyStringDecoder), + lang: optional(nonEmptyStringDecoder), + description: optional(nonEmptyStringDecoder), + categories: optional(array(nonEmptyStringDecoder)), + icons: optional(array(v2IconDecoder)), + screenshots: optional(array(v2ScreenshotDecoder)), + contactEmail: optional(nonEmptyStringDecoder), + supportEmail: optional(nonEmptyStringDecoder), + moreInfo: optional(nonEmptyStringDecoder), + publisher: optional(nonEmptyStringDecoder), + customConfig: optional(array(anyJson())), + hostManifests: optional(anyJson()), + interop: optional(v2InteropDecoder) + }); + const v2DefinitionDecoder = object({ + appId: nonEmptyStringDecoder, + name: nonEmptyStringDecoder, + type: v2TypeDecoder, + details: v2DetailsDecoder, + version: optional(nonEmptyStringDecoder), + title: optional(nonEmptyStringDecoder), + tooltip: optional(nonEmptyStringDecoder), + lang: optional(nonEmptyStringDecoder), + description: optional(nonEmptyStringDecoder), + categories: optional(array(nonEmptyStringDecoder)), + icons: optional(array(v2IconDecoder)), + screenshots: optional(array(v2ScreenshotDecoder)), + contactEmail: optional(nonEmptyStringDecoder), + supportEmail: optional(nonEmptyStringDecoder), + moreInfo: optional(nonEmptyStringDecoder), + publisher: optional(nonEmptyStringDecoder), + customConfig: optional(array(anyJson())), + hostManifests: optional(anyJson()), + interop: optional(v2InteropDecoder), + localizedVersions: optional(dict(v2LocalizedDefinitionDecoder)) + }); + const allDefinitionsDecoder = oneOf(v1DefinitionDecoder, v2DefinitionDecoder); + + const parseDecoderErrorToStringMessage = (error) => { + return `${error.kind} at ${error.at}: ${JSON.stringify(error.input)}. Reason - ${error.message}`; + }; + + class FDC3Service { + fdc3ToDesktopDefinitionType = { + web: "window", + native: "exe", + citrix: "citrix", + onlineNative: "clickonce", + other: "window" + }; + toApi() { + return { + isFdc3Definition: this.isFdc3Definition.bind(this), + parseToBrowserBaseAppData: this.parseToBrowserBaseAppData.bind(this), + parseToDesktopAppConfig: this.parseToDesktopAppConfig.bind(this) + }; + } + isFdc3Definition(definition) { + const decodeRes = allDefinitionsDecoder.run(definition); + if (!decodeRes.ok) { + return { isFdc3: false, reason: parseDecoderErrorToStringMessage(decodeRes.error) }; + } + if (definition.appId && definition.details) { + return { isFdc3: true, version: "2.0" }; + } + if (definition.manifest) { + return { isFdc3: true, version: "1.2" }; + } + return { isFdc3: false, reason: "The passed definition is not FDC3" }; + } + parseToBrowserBaseAppData(definition) { + const { isFdc3, version } = this.isFdc3Definition(definition); + if (!isFdc3) { + throw new Error("The passed definition is not FDC3"); + } + const decodeRes = allDefinitionsDecoder.run(definition); + if (!decodeRes.ok) { + throw new Error(`Invalid FDC3 ${version} definition. Error: ${parseDecoderErrorToStringMessage(decodeRes.error)}`); + } + const userProperties = this.getUserPropertiesFromDefinition(definition, version); + const createOptions = { url: this.getUrl(definition, version) }; + const baseApplicationData = { + name: definition.appId, + type: "window", + createOptions, + userProperties: { + ...userProperties, + intents: version === "1.2" + ? userProperties.intents + : this.getIntentsFromV2AppDefinition(definition), + details: createOptions + }, + title: definition.title, + version: definition.version, + icon: this.getIconFromDefinition(definition, version), + caption: definition.description, + fdc3: version === "2.0" ? { ...definition, definitionVersion: "2.0" } : undefined, + }; + const ioConnectDefinition = definition.hostManifests?.ioConnect || definition.hostManifests?.["Glue42"]; + if (!ioConnectDefinition) { + return baseApplicationData; + } + const ioDefinitionDecodeRes = glue42HostManifestsBrowserDecoder.run(ioConnectDefinition); + if (!ioDefinitionDecodeRes.ok) { + throw new Error(`Invalid FDC3 ${version} definition. Error: ${parseDecoderErrorToStringMessage(ioDefinitionDecodeRes.error)}`); + } + if (!Object.keys(ioDefinitionDecodeRes.result).length) { + return baseApplicationData; + } + return this.mergeBaseAppDataWithGlueManifest(baseApplicationData, ioDefinitionDecodeRes.result); + } + parseToDesktopAppConfig(definition) { + const { isFdc3, version } = this.isFdc3Definition(definition); + if (!isFdc3) { + throw new Error("The passed definition is not FDC3"); + } + const decodeRes = allDefinitionsDecoder.run(definition); + if (!decodeRes.ok) { + throw new Error(`Invalid FDC3 ${version} definition. Error: ${parseDecoderErrorToStringMessage(decodeRes.error)}`); + } + if (version === "1.2") { + const fdc3v1Definition = definition; + return { + name: fdc3v1Definition.appId, + type: "window", + details: { + url: this.getUrl(definition, version) + }, + version: fdc3v1Definition.version, + title: fdc3v1Definition.title, + tooltip: fdc3v1Definition.tooltip, + caption: fdc3v1Definition.description, + icon: fdc3v1Definition.icons?.[0].icon, + intents: fdc3v1Definition.intents, + customProperties: { + manifestType: fdc3v1Definition.manifestType, + images: fdc3v1Definition.images, + contactEmail: fdc3v1Definition.contactEmail, + supportEmail: fdc3v1Definition.supportEmail, + publisher: fdc3v1Definition.publisher, + icons: fdc3v1Definition.icons, + customConfig: fdc3v1Definition.customConfig + } + }; + } + const fdc3v2Definition = definition; + const desktopDefinition = { + name: fdc3v2Definition.appId, + type: this.fdc3ToDesktopDefinitionType[fdc3v2Definition.type], + details: fdc3v2Definition.details, + version: fdc3v2Definition.version, + title: fdc3v2Definition.title, + tooltip: fdc3v2Definition.tooltip, + caption: fdc3v2Definition.description, + icon: this.getIconFromDefinition(fdc3v2Definition, "2.0"), + intents: this.getIntentsFromV2AppDefinition(fdc3v2Definition), + fdc3: { ...fdc3v2Definition, definitionVersion: "2.0" } + }; + const ioConnectDefinition = definition.hostManifests?.ioConnect || definition.hostManifests?.["Glue42"]; + if (!ioConnectDefinition) { + return desktopDefinition; + } + if (typeof ioConnectDefinition !== "object" || Array.isArray(ioConnectDefinition)) { + throw new Error(`Invalid '${definition.hostManifests.ioConnect ? "hostManifests.ioConnect" : "hostManifests['Glue42']"}' key`); + } + return this.mergeDesktopConfigWithGlueManifest(desktopDefinition, ioConnectDefinition); + } + getUserPropertiesFromDefinition(definition, version) { + if (version === "1.2") { + return Object.fromEntries(Object.entries(definition).filter(([key]) => !connectBrowserAppProps.includes(key))); + } + return Object.fromEntries(Object.entries(definition).filter(([key]) => !connectBrowserAppProps.includes(key) && !fdc3v2AppProps.includes(key))); + } + getUrl(definition, version) { + let url; + if (version === "1.2") { + const parsedManifest = JSON.parse(definition.manifest); + url = parsedManifest.details?.url || parsedManifest.url; + } + else { + url = definition.details?.url; + } + if (!url || typeof url !== "string") { + throw new Error(`Invalid FDC3 ${version} definition. Provide valid 'url' under '${version === "1.2" ? "manifest" : "details"}' key`); + } + return url; + } + getIntentsFromV2AppDefinition(definition) { + const fdc3Intents = definition.interop?.intents?.listensFor; + if (!fdc3Intents) { + return; + } + const intents = Object.entries(fdc3Intents).map((fdc3Intent) => { + const [intentName, intentData] = fdc3Intent; + return { + name: intentName, + ...intentData + }; + }); + return intents; + } + getIconFromDefinition(definition, version) { + if (version === "1.2") { + return definition.icons?.find((iconDef) => iconDef.icon)?.icon || undefined; + } + return definition.icons?.find((iconDef) => iconDef.src)?.src || undefined; + } + mergeBaseAppDataWithGlueManifest(baseAppData, hostManifestDefinition) { + let baseApplicationDefinition = baseAppData; + if (hostManifestDefinition.details) { + const details = { ...baseAppData.createOptions, ...hostManifestDefinition.details }; + baseApplicationDefinition.createOptions = details; + baseApplicationDefinition.userProperties.details = details; + } + if (Array.isArray(hostManifestDefinition.intents)) { + baseApplicationDefinition.userProperties.intents = (baseApplicationDefinition.userProperties.intents || []).concat(hostManifestDefinition.intents); + } + baseApplicationDefinition = { ...baseApplicationDefinition, ...hostManifestDefinition }; + delete baseApplicationDefinition.details; + delete baseApplicationDefinition.intents; + return baseApplicationDefinition; + } + mergeDesktopConfigWithGlueManifest(config, desktopDefinition) { + const appConfig = Object.assign({}, config, desktopDefinition, { details: { ...config.details, ...desktopDefinition.details } }); + if (Array.isArray(desktopDefinition.intents)) { + appConfig.intents = (config.intents || []).concat(desktopDefinition.intents); + } + return appConfig; + } + } + + const decoders$1 = { + common: { + nonEmptyStringDecoder, + nonNegativeNumberDecoder + }, + fdc3: { + allDefinitionsDecoder, + v1DefinitionDecoder, + v2DefinitionDecoder + } + }; + + var INTENTS_ERRORS; + (function (INTENTS_ERRORS) { + INTENTS_ERRORS["USER_CANCELLED"] = "User Closed Intents Resolver UI without choosing a handler"; + INTENTS_ERRORS["CALLER_NOT_DEFINED"] = "Caller Id is not defined"; + INTENTS_ERRORS["TIMEOUT_HIT"] = "Timeout hit"; + INTENTS_ERRORS["INTENT_NOT_FOUND"] = "Cannot find Intent"; + INTENTS_ERRORS["HANDLER_NOT_FOUND"] = "Cannot find Intent Handler"; + INTENTS_ERRORS["TARGET_INSTANCE_UNAVAILABLE"] = "Cannot start Target Instance"; + INTENTS_ERRORS["INTENT_DELIVERY_FAILED"] = "Target Instance did not add a listener"; + INTENTS_ERRORS["RESOLVER_UNAVAILABLE"] = "Intents Resolver UI unavailable"; + INTENTS_ERRORS["RESOLVER_TIMEOUT"] = "User did not choose a handler"; + INTENTS_ERRORS["INVALID_RESOLVER_RESPONSE"] = "Intents Resolver UI returned invalid response"; + INTENTS_ERRORS["INTENT_HANDLER_REJECTION"] = "Intent Handler function processing the raised intent threw an error or rejected the promise it returned"; + })(INTENTS_ERRORS || (INTENTS_ERRORS = {})); + + class IoC { + _fdc3; + _decoders = decoders$1; + _errors = { + intents: INTENTS_ERRORS + }; + get fdc3() { + if (!this._fdc3) { + this._fdc3 = new FDC3Service().toApi(); + } + return this._fdc3; + } + get decoders() { + return this._decoders; + } + get errors() { + return this._errors; + } + } + + const ioc = new IoC(); + ioc.fdc3; + ioc.decoders; + const errors = ioc.errors; + + const GLUE42_FDC3_INTENTS_METHOD_PREFIX = "Tick42.FDC3.Intents."; + const INTENTS_RESOLVER_INTEROP_PREFIX = "T42.Intents.Resolver.Control"; + const INTENTS_RESOLVER_WIDTH = 400; + const INTENTS_RESOLVER_HEIGHT = 440; + const DEFAULT_RESOLVER_RESPONSE_TIMEOUT = 60 * 1000; + const INTENT_HANDLER_DEFAULT_PROPS = ["applicationName", "type"]; + const INTENTS_RESOLVER_APP_NAME = "intentsResolver"; + const MAX_SET_TIMEOUT_DELAY = 2147483647; + const DEFAULT_METHOD_RESPONSE_TIMEOUT_MS = 60 * 1000; + const DEFAULT_RAISE_TIMEOUT_MS = 90 * 1000; + const DEFAULT_PICK_HANDLER_BY_TIMEOUT_MS = 90 * 1000; + const ERRORS = errors.intents; + + const PromisePlus = (executor, timeoutMilliseconds, timeoutMessage) => { + return new Promise((resolve, reject) => { + const timeout = setTimeout(() => { + const message = timeoutMessage || `Promise timeout hit: ${timeoutMilliseconds}`; + reject(message); + }, timeoutMilliseconds); + const providedPromise = new Promise(executor); + providedPromise + .then((result) => { + clearTimeout(timeout); + resolve(result); + }) + .catch((error) => { + clearTimeout(timeout); + reject(error); + }); + }); + }; + const PromiseWrap = (promise, timeoutMilliseconds, timeoutMessage) => { + return new Promise((resolve, reject) => { + let promiseActive = true; + const timeout = setTimeout(() => { + if (!promiseActive) { + return; + } + promiseActive = false; + const message = timeoutMessage || `Promise timeout hit: ${timeoutMilliseconds}`; + reject(message); + }, timeoutMilliseconds); + promise() + .then((result) => { + if (!promiseActive) { + return; + } + promiseActive = false; + clearTimeout(timeout); + resolve(result); + }) + .catch((error) => { + if (!promiseActive) { + return; + } + promiseActive = false; + clearTimeout(timeout); + reject(error); + }); + }); + }; + + const validateIntentHandlerAsResponse = (handler) => { + if (typeof handler !== "object") { + return { isValid: false, error: `Response object has invalid 'handler' key. Expected an object, got ${typeof handler}` }; + } + const compulsoryKeysExist = INTENT_HANDLER_DEFAULT_PROPS.filter((key) => !(key in handler)); + if (compulsoryKeysExist.length) { + return { isValid: false, error: `Handler in Response object does not provide compulsory keys: ${compulsoryKeysExist.join(", ")}` }; + } + return { isValid: true, ok: handler }; + }; + const validateIntentRequestTarget = (target) => { + if (!target) { + return; + } + if (typeof target !== "string" && typeof target !== "object") { + throw new Error(`Please provide the intent target as one of the valid values: "reuse", "startNew", { app: string }, { instance: string } `); + } + }; + const validateIntentRequestContext = (context) => { + if (!context) { + return; + } + if (typeof context !== "object") { + throw new Error(`Please provide the intent context as an object`); + } + if (context.type && typeof context.type !== "string") { + throw new Error(`Please provide the intent context as an object with 'type' property as string`); + } + if (context.data && typeof context.data !== "object") { + throw new Error(`Please provide the intent context as an object with 'data' property as object`); + } + }; + const validateIntentRequestHandler = (handler) => { + if (!handler.applicationName) { + throw new Error(`Please provide applicationName for handler ${JSON.stringify(handler)}`); + } + if (!handler.type) { + throw new Error(`Please provide type for handler ${JSON.stringify(handler)}`); + } + if (handler.type === "instance" && !handler.instanceId) { + throw new Error(`Please provide instanceId for handler ${JSON.stringify(handler)}`); + } + }; + const validateIntentRequestTimeout = (timeout) => { + if (!timeout) { + return; + } + if (typeof timeout !== "number") { + throw new Error(`Please provide the timeout as a number`); + } + if (timeout <= 0) { + throw new Error(`Please provide the timeout as a positive number`); + } + }; + const validateWaitUserResponseIndefinitely = (waitUserResponseIndefinitely) => { + if (!waitUserResponseIndefinitely) { + return; + } + if (typeof waitUserResponseIndefinitely !== "boolean") { + throw new Error("Please provide waitUserResponseIndefinitely as a boolean"); + } + }; + const validateHandlerFilter = (handlerFilter) => { + if (!handlerFilter) { + throw new Error(`Provide 'handlerFilter' with at least one filter criteria of the following: 'intent' | 'contextTypes' | 'resultType' | 'applicationNames'`); + } + const { title, openResolver, timeout, intent, contextTypes, resultType, applicationNames } = handlerFilter; + if (typeof title !== "undefined" && (typeof title !== "string" || !title.length)) { + throw new Error(`Provide 'title' as a non empty string`); + } + if (typeof openResolver !== "undefined" && typeof openResolver !== "boolean") { + throw new Error(`Provide 'openResolver' prop as a boolean`); + } + if (typeof timeout !== "undefined" && (typeof timeout !== "number" || timeout <= 0)) { + throw new Error(`Provide 'timeout' prop as a positive number`); + } + if (typeof intent !== "undefined" && (typeof intent !== "string" || !intent.length)) { + throw new Error(`Provide 'intent' as a non empty string`); + } + if (typeof contextTypes !== "undefined" && (!Array.isArray(contextTypes) || contextTypes.some(ctx => typeof ctx !== "string"))) { + throw new Error(`Provide 'contextTypes' as an array of non empty strings`); + } + if (typeof resultType !== "undefined" && (typeof resultType !== "string" || !resultType.length)) { + throw new Error(`Provide 'resultType' as a non empty string`); + } + if (typeof applicationNames !== "undefined" && (!Array.isArray(applicationNames) || applicationNames.some(appName => typeof appName !== "string"))) { + throw new Error(`Provide 'applicationNames' as an array of non empty strings`); + } + const errorMsg = "Provide at least one filter criteria of the following: 'intent' | 'contextTypes' | 'resultType' | 'applicationNames'"; + if (!Object.keys(handlerFilter).length) { + throw new Error(errorMsg); + } + if (!intent && !resultType && (!contextTypes || !contextTypes.length) && (!applicationNames || !applicationNames.length)) { + throw new Error(errorMsg); + } + }; + const validateResolverResponse = (responseObj) => { + var _a, _b; + if (typeof responseObj.intent !== "string") { + return { isValid: false, error: `Response object has invalid 'intent' key. Expected a string, got ${typeof responseObj.intent}` }; + } + if (((_a = responseObj.userSettings) === null || _a === void 0 ? void 0 : _a.preserveChoice) && typeof ((_b = responseObj.userSettings) === null || _b === void 0 ? void 0 : _b.preserveChoice) !== "boolean") { + return { isValid: false, error: `Response object has invalid 'userSettings.preserveChoice' key. Expected a boolean, got ${typeof responseObj.userSettings.preserveChoice}` }; + } + const { isValid, error } = validateIntentHandlerAsResponse(responseObj.handler); + return isValid + ? { isValid: true, ok: responseObj } + : { isValid, error }; + }; + const validateIntentRequest = (request) => { + validateIntentRequestContext(request.context); + validateIntentRequestTarget(request.target); + validateIntentRequestTimeout(request.timeout); + validateWaitUserResponseIndefinitely(request.waitUserResponseIndefinitely); + if (typeof request.clearSavedHandler !== "undefined" && typeof request.clearSavedHandler !== "boolean") { + throw new Error("Please provide 'clearSavedHandler' as a boolean"); + } + if (request.handlers) { + request.handlers.forEach((handler) => validateIntentRequestHandler(handler)); + } + }; + const validateIntentHandler = (handler) => { + if (typeof handler !== "object") { + throw new Error("IntentHandler must be an object"); + } + if (typeof handler.applicationName !== "string" || !handler.applicationName.length) { + throw new Error(`Please provide 'applicationName' as a non-empty string`); + } + if (typeof handler.type !== "string" || !["app", "instance"].includes(handler.type)) { + throw new Error(`Invalid 'type' property. Expected 'app' | 'instance' got ${handler.type}`); + } + if (typeof handler.applicationTitle !== "undefined" && typeof handler.applicationTitle !== "string") { + throw new Error(`Provide 'applicationTitle' as a string`); + } + if (typeof handler.applicationDescription !== "undefined" && typeof handler.applicationDescription !== "string") { + throw new Error(`Provide 'applicationDescription' as a string`); + } + if (typeof handler.applicationIcon !== "undefined" && typeof handler.applicationIcon !== "string") { + throw new Error(`Provide 'applicationIcon' as a string`); + } + if (typeof handler.displayName !== "undefined" && typeof handler.displayName !== "string") { + throw new Error(`Provide 'displayName' as a string`); + } + if (typeof handler.contextTypes !== "undefined" && (!Array.isArray(handler.contextTypes) || handler.contextTypes.some(ctx => typeof ctx !== "string"))) { + throw new Error(`Provide 'contextTypes' as an array of non empty strings`); + } + if (typeof handler.instanceId !== "undefined" && typeof handler.instanceId !== "string") { + throw new Error(`Provide 'instanceId' as a string`); + } + if (typeof handler.instanceTitle !== "undefined" && typeof handler.instanceTitle !== "string") { + throw new Error(`Provide 'instanceTitle' as a string`); + } + if (typeof handler.resultType !== "undefined" && typeof handler.resultType !== "string") { + throw new Error(`Provide 'resultType' as a string`); + } + }; + const clearNullUndefined = (obj) => { + Object.keys(obj).forEach(key => { + if (obj[key] === null || obj[key] === undefined) { + delete obj[key]; + } + }); + }; + + class Intents { + constructor(interop, windows, logger, options, prefsController, appManager) { + this.interop = interop; + this.windows = windows; + this.logger = logger; + this.prefsController = prefsController; + this.appManager = appManager; + this.myIntents = new Set(); + this.intentsResolverResponsePromises = {}; + this.useIntentsResolverUI = true; + this.unregisterIntentPromises = []; + this.addedHandlerInfoPerApp = {}; + this.checkIfIntentsResolverIsEnabled(options, appManager); + } + async find(intentFilter) { + await Promise.all(this.unregisterIntentPromises); + let intents = await this.all(); + if (typeof intentFilter === "undefined") { + return intents; + } + if (typeof intentFilter === "string") { + return intents.filter((intent) => intent.name === intentFilter); + } + if (typeof intentFilter !== "object") { + throw new Error("Please provide the intentFilter as a string or an object!"); + } + if (intentFilter.contextType) { + const ctToLower = intentFilter.contextType.toLowerCase(); + intents = intents.filter((intent) => intent.handlers.some((handler) => { var _a; return (_a = handler.contextTypes) === null || _a === void 0 ? void 0 : _a.some((ct) => ct.toLowerCase() === ctToLower); })); + } + if (intentFilter.resultType) { + const resultTypeToLower = intentFilter.resultType.toLowerCase(); + intents = intents.filter((intent) => intent.handlers.some((handler) => { var _a; return ((_a = handler.resultType) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === resultTypeToLower; })); + } + if (intentFilter.name) { + intents = intents.filter((intent) => intent.name === intentFilter.name); + } + return intents; + } + async raise(intentRequest) { + if ((typeof intentRequest !== "string" && typeof intentRequest !== "object") || (typeof intentRequest === "object" && typeof intentRequest.intent !== "string")) { + throw new Error("Please provide the intent as a string or an object with an intent property!"); + } + if (typeof intentRequest === "string") { + intentRequest = { intent: intentRequest }; + } + validateIntentRequest(intentRequest); + await Promise.all(this.unregisterIntentPromises); + if (intentRequest.clearSavedHandler) { + this.logger.trace(`User removes saved handler for intent ${intentRequest.intent}`); + await this.removeRememberedHandler(intentRequest.intent); + } + const resolverInstance = {}; + const timeout = intentRequest.waitUserResponseIndefinitely ? MAX_SET_TIMEOUT_DELAY : intentRequest.timeout || DEFAULT_RAISE_TIMEOUT_MS; + const resultFromRememberedHandler = await this.checkHandleRaiseWithRememberedHandler(intentRequest, resolverInstance, timeout); + if (resultFromRememberedHandler) { + return resultFromRememberedHandler; + } + const coreRaiseIntentFn = this.coreRaiseIntent.bind(this, { request: intentRequest, resolverInstance, timeout }); + if (intentRequest.waitUserResponseIndefinitely) { + return coreRaiseIntentFn(); + } + const resultPromise = PromiseWrap(coreRaiseIntentFn, timeout, `${ERRORS.TIMEOUT_HIT} hit for intent request ${JSON.stringify(intentRequest)}`); + resultPromise.catch(() => this.handleRaiseOnError(resolverInstance.instanceId)); + return resultPromise; + } + async all() { + await Promise.all(this.unregisterIntentPromises); + let apps; + try { + const result = await this.interop.invoke("T42.ACS.GetApplications", { withIntentsInfo: true }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + apps = result.returned.applications; + } + catch (e) { + this.logger.error(`Failed to get the applications!`, e); + return []; + } + const intents = {}; + const appsWithIntents = apps.filter((app) => app.intents && app.intents.length > 0); + for (const app of appsWithIntents) { + for (const intentDef of app.intents) { + let intent = intents[intentDef.name]; + if (!intent) { + intent = { + name: intentDef.name, + handlers: [], + }; + intents[intentDef.name] = intent; + } + const handler = { + applicationName: app.name, + applicationTitle: app.title || "", + applicationDescription: app.caption, + displayName: intentDef.displayName, + contextTypes: intentDef.contexts, + applicationIcon: app.icon, + type: "app", + resultType: intentDef.resultType + }; + intent.handlers.push(handler); + } + } + const servers = this.interop.servers(); + const serverWindowIds = servers.map((server) => server.windowId).filter((serverWindowId) => typeof serverWindowId !== "undefined"); + const T42WndGetInfo = "T42.Wnd.GetInfo"; + const isT42WndGetInfoMethodRegistered = this.interop.methods().some((method) => method.name === T42WndGetInfo); + let windowsInfos; + if (isT42WndGetInfoMethodRegistered) { + try { + const result = await this.interop.invoke(T42WndGetInfo, { ids: serverWindowIds }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + windowsInfos = result.returned.windows; + } + catch (e) { + } + } + for (const server of servers) { + await Promise.all(server.getMethods() + .filter((method) => method.name.startsWith(GLUE42_FDC3_INTENTS_METHOD_PREFIX)) + .map(async (method) => { + const intentName = method.name.replace(GLUE42_FDC3_INTENTS_METHOD_PREFIX, ""); + let intent = intents[intentName]; + if (!intent) { + intent = { + name: intentName, + handlers: [], + }; + intents[intentName] = intent; + } + const title = await this.windowsIdToTitle(server.windowId, windowsInfos); + const handler = this.constructIntentHandler({ method, apps, server, intentName, title }); + intent.handlers.push(handler); + })); + } + return Object.values(intents); + } + addIntentListener(intent, handler) { + if ((typeof intent !== "string" && typeof intent !== "object") || (typeof intent === "object" && typeof intent.intent !== "string")) { + throw new Error("Please provide the intent as a string or an object with an intent property!"); + } + if (typeof handler !== "function") { + throw new Error("Please provide the handler as a function!"); + } + const intentName = typeof intent === "string" ? intent : intent.intent; + const methodName = `${GLUE42_FDC3_INTENTS_METHOD_PREFIX}${intentName}`; + let intentFlag = {}; + let registerPromise; + const alreadyRegistered = this.myIntents.has(intentName); + if (alreadyRegistered) { + throw new Error(`Intent listener for intent ${intentName} already registered!`); + } + this.myIntents.add(intentName); + const result = { + unsubscribe: () => { + this.myIntents.delete(intentName); + registerPromise + .then(() => this.interop.unregister(methodName)) + .catch((err) => this.logger.trace(`Unregistration of a method with name ${methodName} failed with reason: ${JSON.stringify(err)}`)); + } + }; + if (typeof intent === "object") { + const { intent: removed, ...rest } = intent; + intentFlag = rest; + } + registerPromise = this.interop.register({ name: methodName, flags: { intent: intentFlag } }, (args) => { + if (this.myIntents.has(intentName)) { + return handler(args); + } + }); + registerPromise.catch((err) => { + this.myIntents.delete(intentName); + this.logger.warn(`Registration of a method with name ${methodName} failed with reason: ${JSON.stringify(err)}`); + }); + return result; + } + async register(intent, handler) { + if ((typeof intent !== "string" && typeof intent !== "object") || (typeof intent === "object" && typeof intent.intent !== "string")) { + throw new Error("Please provide the intent as a string or an object with an intent property!"); + } + if (typeof handler !== "function") { + throw new Error("Please provide the handler as a function!"); + } + await Promise.all(this.unregisterIntentPromises); + const intentName = typeof intent === "string" ? intent : intent.intent; + const methodName = this.buildInteropMethodName(intentName); + let intentFlag = {}; + const alreadyRegistered = this.myIntents.has(intentName); + if (alreadyRegistered) { + throw new Error(`Intent listener for intent ${intentName} already registered!`); + } + this.myIntents.add(intentName); + if (typeof intent === "object") { + const { intent: removed, ...rest } = intent; + intentFlag = rest; + } + try { + await this.interop.register({ name: methodName, flags: { intent: intentFlag } }, (args, caller) => { + if (this.myIntents.has(intentName)) { + return handler(args, caller); + } + }); + } + catch (err) { + this.myIntents.delete(intentName); + throw new Error(`Registration of a method with name ${methodName} failed with reason: ${JSON.stringify(err)}`); + } + return { + unsubscribe: () => this.unsubscribeIntent(intentName) + }; + } + async filterHandlers(handlerFilter) { + var _a, _b; + validateHandlerFilter(handlerFilter); + if (handlerFilter.openResolver && !this.useIntentsResolverUI) { + throw new Error("Cannot resolve 'filterHandlers' request using Intents Resolver UI because it's globally disabled"); + } + (_a = this.logger) === null || _a === void 0 ? void 0 : _a.trace(`Received 'filterHandlers' command with request: ${JSON.stringify(handlerFilter)}`); + const filteredHandlers = this.filterHandlersBy(await this.all(), handlerFilter); + if (!filteredHandlers || !filteredHandlers.length) { + return { handlers: [] }; + } + const { open, reason } = this.checkIfResolverShouldBeOpenedForFilterHandlers(filteredHandlers, handlerFilter); + if (!open) { + (_b = this.logger) === null || _b === void 0 ? void 0 : _b.trace(`Intent Resolver UI won't be used. Reason: ${reason}`); + return { handlers: filteredHandlers }; + } + const resolverInstance = { instanceId: undefined }; + const timeout = handlerFilter.timeout || DEFAULT_PICK_HANDLER_BY_TIMEOUT_MS; + const handler = await PromiseWrap(() => this.startResolverApp({ request: handlerFilter, resolverInstance, method: 'filterHandlers' }), timeout, `Timeout of ${timeout}ms hit for 'filterHandlers' request with filter: ${JSON.stringify(handlerFilter)}`); + return { handlers: [handler] }; + } + async getIntents(handler) { + var _a; + this.logger.trace(`Received 'getIntents' command with handler ${JSON.stringify(handler)}`); + validateIntentHandler(handler); + const intents = await this.all(); + clearNullUndefined(handler); + (_a = this.logger) === null || _a === void 0 ? void 0 : _a.trace(`Extracting valid intents for the passed handler`); + const intentsWithInfo = this.extractIntentsWithInfoByHandler(intents, handler); + this.logger.trace(`Returning intents for handler ${JSON.stringify(handler)}`); + return { intents: intentsWithInfo }; + } + async clearSavedHandlers() { + this.logger.trace("Removing all saved handlers from prefs storage for current app"); + await this.prefsController.update({ intents: undefined }); + } + onHandlerAdded(callback) { + var _a; + const unAppAdded = (_a = this.appManager) === null || _a === void 0 ? void 0 : _a.onAppAdded(async (app) => { + var _a; + const appName = app.name; + const appDef = await app.getConfiguration(); + const isIntentHandler = (_a = appDef === null || appDef === void 0 ? void 0 : appDef.intents) === null || _a === void 0 ? void 0 : _a.length; + if (!isIntentHandler) { + return; + } + appDef.intents.forEach((intent) => { + const handler = this.constructIntentHandlerFromApp(appDef, intent); + if (!this.addedHandlerInfoPerApp[appName]) { + this.addedHandlerInfoPerApp[appName] = []; + } + const appHandlers = this.addedHandlerInfoPerApp[appName]; + appHandlers.push({ handler, name: intent.name }); + callback(handler, intent.name); + }); + }); + const unServerMethodAdded = this.interop.serverMethodAdded(({ method, server }) => { + if (!method.name.startsWith(GLUE42_FDC3_INTENTS_METHOD_PREFIX)) { + return; + } + const intentName = method.name.replace(GLUE42_FDC3_INTENTS_METHOD_PREFIX, ""); + const intentsInfo = this.constructIntentHandler({ method, apps: [], server, intentName, title: "" }); + callback(intentsInfo, intentName); + }); + return () => { + if (typeof unServerMethodAdded === "function") { + unServerMethodAdded(); + } + if (typeof unAppAdded === "function") { + unAppAdded(); + } + }; + } + onHandlerRemoved(callback) { + var _a; + const unAppRemoved = (_a = this.appManager) === null || _a === void 0 ? void 0 : _a.onAppRemoved(async (app) => { + const appName = app.name; + const handlers = this.addedHandlerInfoPerApp[appName]; + const isIntentHandler = handlers === null || handlers === void 0 ? void 0 : handlers.length; + if (!isIntentHandler) { + return; + } + delete this.addedHandlerInfoPerApp[appName]; + handlers.forEach((addedHandlerInfo) => { + callback(addedHandlerInfo.handler, addedHandlerInfo.name); + }); + }); + const unServerMethodAdded = this.interop.serverMethodRemoved(({ method, server }) => { + if (!method.name.startsWith(GLUE42_FDC3_INTENTS_METHOD_PREFIX)) { + return; + } + const intentName = method.name.replace(GLUE42_FDC3_INTENTS_METHOD_PREFIX, ""); + const intentsInfo = this.constructIntentHandler({ method, apps: [], server, intentName, title: "" }); + callback(intentsInfo, intentName); + }); + return () => { + if (typeof unServerMethodAdded === "function") { + unServerMethodAdded(); + } + if (typeof unAppRemoved === "function") { + unAppRemoved(); + } + }; + } + toAPI() { + return { + all: this.all.bind(this), + find: this.find.bind(this), + raise: this.raise.bind(this), + addIntentListener: this.addIntentListener.bind(this), + register: this.register.bind(this), + filterHandlers: this.filterHandlers.bind(this), + getIntents: this.getIntents.bind(this), + clearSavedHandlers: this.clearSavedHandlers.bind(this), + onHandlerAdded: this.onHandlerAdded.bind(this), + onHandlerRemoved: this.onHandlerRemoved.bind(this) + }; + } + filterHandlersBy(intents, filter) { + const filteredIntentsWithHandlers = intents.filter((intent) => { + if (filter.intent && filter.intent !== intent.name) { + return; + } + if (filter.resultType) { + const filteredHandlers = intent.handlers.filter((handler) => handler.resultType && handler.resultType === filter.resultType); + if (!filteredHandlers.length) + return; + intent.handlers = filteredHandlers; + } + if (filter.contextTypes) { + const filteredHandlers = intent.handlers.filter((handler) => { var _a; return (_a = filter.contextTypes) === null || _a === void 0 ? void 0 : _a.every((contextType) => { var _a; return (_a = handler.contextTypes) === null || _a === void 0 ? void 0 : _a.includes(contextType); }); }); + if (!filteredHandlers.length) + return; + intent.handlers = filteredHandlers; + } + if (filter.applicationNames) { + const filteredHandlers = intent.handlers.filter((handler) => { var _a; return (_a = filter.applicationNames) === null || _a === void 0 ? void 0 : _a.includes(handler.applicationName); }); + if (!filteredHandlers.length) + return; + intent.handlers = filteredHandlers; + } + return intent; + }); + return filteredIntentsWithHandlers.map((intent) => intent.handlers).flat(1); + } + async coreRaiseIntent({ request, resolverInstance, timeout }) { + var _a, _b; + const intentDef = await this.get(request.intent); + if (typeof intentDef === "undefined") { + throw new Error(`${ERRORS.INTENT_NOT_FOUND} with name ${request.intent}`); + } + const { open, reason } = await this.checkIfResolverShouldBeOpenedForRaise(intentDef, request); + if (!open) { + this.logger.trace(`Intent Resolver UI won't be used. Reason: ${reason}`); + return request.waitUserResponseIndefinitely + ? PromiseWrap(() => this.raiseIntent(request, timeout), timeout, `${ERRORS.TIMEOUT_HIT} - waited ${timeout}ms for 'raise' to resolve`) + : this.raiseIntent(request, timeout); + } + const resolverHandler = await this.startResolverApp({ request, method: "raise", resolverInstance }); + (_a = this.logger) === null || _a === void 0 ? void 0 : _a.trace(`Raising intent to target handler: ${JSON.stringify(resolverHandler)} with timeout of ${timeout}`); + if (request.waitUserResponseIndefinitely) { + return PromiseWrap(() => this.raiseIntentToTargetHandler(request, resolverHandler, timeout), timeout, `${ERRORS.TIMEOUT_HIT} - waited ${timeout}ms for 'raise' to resolve`); + } + const result = await this.raiseIntentToTargetHandler(request, resolverHandler, timeout); + (_b = this.logger) === null || _b === void 0 ? void 0 : _b.trace(`Result from raise() method for intent ${JSON.stringify(request.intent)}: ${JSON.stringify(result)}`); + return result; + } + async get(intent) { + return (await this.all()).find((registeredIntent) => registeredIntent.name === intent); + } + async raiseIntent(intentRequest, timeout) { + const intentName = intentRequest.intent; + const intentDef = await this.get(intentName); + if (typeof intentDef === "undefined") { + throw new Error(`${ERRORS.INTENT_NOT_FOUND} with name ${intentRequest.intent}`); + } + const firstFoundAppHandler = intentRequest.handlers ? this.findHandlerByFilter(intentRequest.handlers, { type: "app" }) : this.findHandlerByFilter(intentDef.handlers, { type: "app" }); + const firstFoundInstanceHandler = intentRequest.handlers ? this.findHandlerByFilter(intentRequest.handlers, { type: "instance" }) : this.findHandlerByFilter(intentDef.handlers, { type: "instance" }); + let handler; + if (!intentRequest.target || intentRequest.target === "reuse") { + handler = firstFoundInstanceHandler || firstFoundAppHandler; + } + if (intentRequest.target === "startNew") { + handler = firstFoundAppHandler; + } + if (typeof intentRequest.target === "object" && intentRequest.target.app) { + handler = this.findHandlerByFilter(intentDef.handlers, { app: intentRequest.target.app }); + } + if (typeof intentRequest.target === "object" && intentRequest.target.instance) { + handler = this.findHandlerByFilter(intentDef.handlers, { instance: intentRequest.target.instance, app: intentRequest.target.app }); + } + if (!handler) { + throw new Error(`Can not raise intent for request ${JSON.stringify(intentRequest)} - can not find intent handler!`); + } + const result = await this.raiseIntentToTargetHandler(intentRequest, handler, timeout); + return result; + } + async raiseIntentToTargetHandler(intentRequest, handler, timeout) { + var _a, _b; + (_a = this.logger) === null || _a === void 0 ? void 0 : _a.trace(`Raising intent to target handler:${JSON.stringify(handler)}`); + if (!handler.instanceId) { + const instanceIdPromise = this.invokeStartApp(handler.applicationName, intentRequest.context, intentRequest.options).catch((err) => { + const reasonMsg = typeof err === "string" ? err : JSON.stringify(err); + throw new Error(`${ERRORS.TARGET_INSTANCE_UNAVAILABLE}. Reason: ${reasonMsg}`); + }); + handler.instanceId = await instanceIdPromise; + } + const methodName = `${GLUE42_FDC3_INTENTS_METHOD_PREFIX}${intentRequest.intent}`; + const invokeOptions = { + methodResponseTimeoutMs: timeout ? timeout + 1000 : DEFAULT_METHOD_RESPONSE_TIMEOUT_MS, + waitTimeoutMs: timeout ? timeout + 1000 : DEFAULT_METHOD_RESPONSE_TIMEOUT_MS + }; + const resultPromise = this.interop.invoke(methodName, intentRequest.context, { instance: handler.instanceId }, invokeOptions) + .catch((err) => { + const reasonMsg = typeof err === "string" ? err : JSON.stringify(err); + throw new Error(`${ERRORS.INTENT_HANDLER_REJECTION}. Reason: ${reasonMsg}`); + }); + const result = await resultPromise; + (_b = this.logger) === null || _b === void 0 ? void 0 : _b.trace(`raiseIntent command completed. Returning result: ${JSON.stringify(result)}`); + return { + request: intentRequest, + handler: { ...handler, type: "instance" }, + result: result.returned + }; + } + async startResolverApp({ request, method, resolverInstance }) { + var _a, _b, _c, _d; + (_a = this.logger) === null || _a === void 0 ? void 0 : _a.trace(`Intents Resolver UI with app name ${this.intentsResolverAppName} will be used for request: ${JSON.stringify(request)}`); + const responseMethodName = await this.registerIntentResolverMethod(); + (_b = this.logger) === null || _b === void 0 ? void 0 : _b.trace(`Registered interop method ${responseMethodName}`); + const startContext = this.buildStartContext(method, request, responseMethodName); + const startOptions = await this.buildStartOptions(); + (_c = this.logger) === null || _c === void 0 ? void 0 : _c.trace(`Starting Intents Resolver UI with context: ${JSON.stringify(startContext)} and options: ${JSON.stringify(startOptions)}`); + const instance = await this.appManager.application(this.intentsResolverAppName).start(startContext, startOptions); + resolverInstance.instanceId = instance.id; + (_d = this.logger) === null || _d === void 0 ? void 0 : _d.trace(`Intents Resolver instance with id ${instance.id} opened`); + this.subscribeOnInstanceStopped(instance, method); + const timeout = request.timeout || method === "raise" ? DEFAULT_RAISE_TIMEOUT_MS : DEFAULT_PICK_HANDLER_BY_TIMEOUT_MS; + this.createResponsePromise({ + intent: method === "raise" ? request.intent : undefined, + instanceId: instance.id, + responseMethodName, + timeout, + errorMsg: `Timeout of ${timeout}ms hit waiting for the user to choose a handler ${method === "raise" + ? `for intent ${request.intent}` + : `for '${method}' method with filter ${JSON.stringify(request)}`}` + }); + const handler = await this.handleInstanceResponse({ instanceId: instance.id, caller: startContext.initialCaller, method, request }); + return handler; + } + async windowsIdToTitle(id, windowsInfos) { + var _a, _b; + if (typeof windowsInfos !== "undefined") { + return (_a = windowsInfos.find((windowsInfo) => windowsInfo.id === id)) === null || _a === void 0 ? void 0 : _a.title; + } + const window = (_b = this.windows) === null || _b === void 0 ? void 0 : _b.findById(id); + const title = await (window === null || window === void 0 ? void 0 : window.getTitle()); + return title; + } + async handleInstanceResponse({ instanceId, method, request, caller }) { + var _a, _b, _c; + try { + const response = await this.intentsResolverResponsePromises[instanceId].promise; + const subMessage = method === "raise" ? `for intent ${response.intent} ` : ""; + (_a = this.logger) === null || _a === void 0 ? void 0 : _a.trace(`Intent handler chosen ${subMessage}: ${JSON.stringify(response.handler)}. Stopping resolver instance with id ${instanceId}`); + this.stopResolverInstance(instanceId); + (_b = this.logger) === null || _b === void 0 ? void 0 : _b.trace(`Instance with id ${instanceId} successfully stopped`); + if ((_c = response.userSettings) === null || _c === void 0 ? void 0 : _c.preserveChoice) { + await this.saveUserChoice({ + intent: response.intent, + handler: response.handler, + filter: method === "filterHandlers" + ? { applicationNames: request.applicationNames, contextTypes: request.contextTypes, resultType: request.resultType } + : undefined, + caller + }); + } + return response.handler; + } + catch (error) { + this.stopResolverInstance(instanceId); + throw new Error(error); + } + } + async registerIntentResolverMethod() { + const methodName = INTENTS_RESOLVER_INTEROP_PREFIX + Utils.generateId(); + await this.interop.register(methodName, (args, callerId) => this.resolverResponseHandler(args, callerId)); + return methodName; + } + resolverResponseHandler(args, callerId) { + const { instance } = callerId; + const isValid = validateResolverResponse(args); + if (!isValid) { + this.logger.trace(`Intent Resolver instance with id ${callerId.instance} sent invalid response. Error: ${isValid.error}`); + this.intentsResolverResponsePromises[instance].reject(isValid.error); + this.stopResolverInstance(instance); + return; + } + const validResponse = isValid.ok; + this.intentsResolverResponsePromises[instance].resolve(validResponse); + this.cleanUpIntentResolverPromise(instance); + } + buildStartContext(method, request, methodName) { + var _a; + const myAppName = this.interop.instance.application || this.interop.instance.applicationName; + const myAppTitle = ((_a = this.appManager.application(myAppName)) === null || _a === void 0 ? void 0 : _a.title) || ""; + const baseStartContext = { + callerId: this.interop.instance.instance, + methodName, + initialCaller: { id: this.interop.instance.instance, applicationName: myAppName, applicationTitle: myAppTitle }, + resolverApi: "1.0" + }; + return method === "raise" + ? { ...baseStartContext, intent: request } + : { ...baseStartContext, handlerFilter: request }; + } + async buildStartOptions() { + const win = this.windows.my(); + if (!win) { + return; + } + const bounds = await win.getBounds(); + return { + top: await this.getResolverStartupTopBound(bounds), + left: (bounds.width - INTENTS_RESOLVER_WIDTH) / 2 + bounds.left, + width: INTENTS_RESOLVER_WIDTH, + height: INTENTS_RESOLVER_HEIGHT + }; + } + async getResolverStartupTopBound(bounds) { + const myDisplay = await this.windows.my().getDisplay(); + const minWorkareaHeight = myDisplay.workArea.height; + const top = (bounds.height - INTENTS_RESOLVER_HEIGHT) / 2 + bounds.top; + if (top < 0) { + return 0; + } + if (top + INTENTS_RESOLVER_HEIGHT > minWorkareaHeight) { + return minWorkareaHeight / 2; + } + return top; + } + createResponsePromise({ instanceId, intent, responseMethodName, timeout, errorMsg }) { + let resolve = () => { }; + let reject = () => { }; + const promise = PromisePlus((res, rej) => { + resolve = res; + reject = rej; + }, timeout, errorMsg); + this.intentsResolverResponsePromises[instanceId] = { intent, resolve, reject, promise, methodName: responseMethodName }; + } + async invokeStartApp(application, context, options) { + const result = await this.interop.invoke("T42.ACS.StartApplication", { Name: application, options: { ...options, startedByIntentAPI: true } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return result.returned.Id; + } + subscribeOnInstanceStopped(instance, method) { + const { application } = instance; + const unsub = application.onInstanceStopped((inst) => { + if (inst.id !== instance.id) { + return; + } + const intentPromise = this.intentsResolverResponsePromises[inst.id]; + if (!intentPromise) { + return unsub(); + } + const errorMsg = `Cannot resolve ${method === "raise" ? `raised intent ${intentPromise.intent}` : `'${method}' method`} - User closed ${instance.application.name} app without choosing a handler`; + intentPromise.reject(errorMsg); + this.cleanUpIntentResolverPromise(inst.id); + unsub(); + }); + } + async cleanUpIntentResolverPromise(instanceId) { + const intentPromise = this.intentsResolverResponsePromises[instanceId]; + if (!intentPromise) { + return; + } + const unregisterPromise = this.interop.unregister(intentPromise.methodName); + unregisterPromise.catch((error) => this.logger.warn(error)); + delete this.intentsResolverResponsePromises[instanceId]; + } + handleRaiseOnError(instanceId) { + if (!instanceId) { + return; + } + this.stopResolverInstance(instanceId); + } + stopResolverInstance(instanceId) { + const gdWin = this.windows.findById(instanceId); + gdWin === null || gdWin === void 0 ? void 0 : gdWin.close().catch((err) => this.logger.error(err)); + } + checkIfIntentsResolverIsEnabled(options, appManager) { + var _a, _b, _c, _d, _e; + if (!appManager) { + this.useIntentsResolverUI = false; + return; + } + this.useIntentsResolverUI = typeof ((_a = options.intents) === null || _a === void 0 ? void 0 : _a.enableIntentsResolverUI) === "boolean" + ? options.intents.enableIntentsResolverUI + : true; + this.intentsResolverAppName = (_c = (_b = options.intents) === null || _b === void 0 ? void 0 : _b.intentsResolverAppName) !== null && _c !== void 0 ? _c : INTENTS_RESOLVER_APP_NAME; + this.intentsResolverResponseTimeout = (_e = (_d = options.intents) === null || _d === void 0 ? void 0 : _d.methodResponseTimeoutMs) !== null && _e !== void 0 ? _e : DEFAULT_RESOLVER_RESPONSE_TIMEOUT; + } + async checkIfResolverShouldBeOpenedForRaise(intent, request) { + const checkOpen = this.checkIfIntentsResolverShouldBeOpened(); + if (!checkOpen.open) { + return checkOpen; + } + const hasMoreThanOneHandler = await this.checkIfIntentHasMoreThanOneHandler(intent, request); + if (!hasMoreThanOneHandler) { + return { open: false, reason: `Raised intent ${intent.name} has only one handler` }; + } + return { open: true }; + } + checkIfResolverShouldBeOpenedForFilterHandlers(handlers, filter) { + if (handlers.length === 1) { + return { open: false, reason: `There's only one valid intent handler for filter ${JSON.stringify(filter)}` }; + } + if (typeof (filter === null || filter === void 0 ? void 0 : filter.openResolver) === "boolean" && !filter.openResolver) { + return { open: false, reason: "Intents resolver is disabled by IntentHandler filter" }; + } + return this.checkIfIntentsResolverShouldBeOpened(); + } + checkIfIntentsResolverShouldBeOpened() { + if (!this.useIntentsResolverUI) { + return { open: false, reason: `Intent Resolver is disabled. Resolving to first found handler` }; + } + const intentsResolverApp = this.appManager.application(this.intentsResolverAppName); + if (!intentsResolverApp) { + return { open: false, reason: `Intent Resolver Application with name ${this.intentsResolverAppName} not found.` }; + } + return { open: true }; + } + async checkIfIntentHasMoreThanOneHandler(intent, request) { + const handlers = await this.removeSingletons(request.handlers || intent.handlers); + if (!request.target) { + return handlers.length > 1; + } + if (request.target === "reuse") { + return handlers.filter(handler => handler.type === "instance" && handler.instanceId).length > 1 || intent.handlers.filter(handler => handler.type === "app").length > 1; + } + if (request.target === "startNew") { + return handlers.filter(handler => handler.type === "app").length > 1; + } + if (request.target.instance) { + return false; + } + if (request.target.app) { + const searchedAppName = request.target.app; + const instanceHandlersByAppName = handlers.filter((handler) => handler.applicationName === searchedAppName && handler.instanceId); + return instanceHandlersByAppName.length > 1; + } + return false; + } + async removeSingletons(handlers) { + const handlersWithSingletonProp = await Promise.all(handlers.map(async (handler) => { + if (handler.type === "instance") { + return handler; + } + const appConfig = await this.appManager.application(handler.applicationName).getConfiguration(); + const isSingleton = appConfig.allowMultiple === false; + return { ...handler, isSingleton }; + })); + const filteredSingletonsWithOpenedInstances = handlersWithSingletonProp.filter((handler, _, currentHandlers) => { + if (handler.instanceId || !handler.isSingleton) { + return handler; + } + const openedInstance = currentHandlers.find((h) => h.instanceId && h.applicationName === handler.applicationName); + if (openedInstance) { + return; + } + return handler; + }); + return filteredSingletonsWithOpenedInstances; + } + buildInteropMethodName(intentName) { + return `${GLUE42_FDC3_INTENTS_METHOD_PREFIX}${intentName}`; + } + clearUnregistrationPromise(promiseToRemove) { + this.unregisterIntentPromises = this.unregisterIntentPromises.filter((promise) => promise !== promiseToRemove); + } + unsubscribeIntent(intentName) { + this.myIntents.delete(intentName); + const methodName = this.buildInteropMethodName(intentName); + const unregisterPromise = this.interop.unregister(methodName); + this.unregisterIntentPromises.push(unregisterPromise); + unregisterPromise + .then(() => { + this.clearUnregistrationPromise(unregisterPromise); + }) + .catch((err) => { + this.logger.error(`Unregistration of a method with name ${methodName} failed with reason: `, err); + this.clearUnregistrationPromise(unregisterPromise); + }); + } + findHandlerByFilter(handlers, filter) { + if (filter.type) { + return handlers.find((handler) => handler.type === filter.type); + } + if (filter.instance) { + return handlers.find((handler) => filter.app + ? handler.applicationName === filter.app && handler.instanceId === filter.instance + : handler.instanceId === filter.instance); + } + if (filter.app) { + return handlers.find((handler) => handler.applicationName === filter.app); + } + } + extractIntentsWithInfoByHandler(intents, handler) { + const intentsWithInfo = intents.reduce((validIntentsWithInfo, intent) => { + intent.handlers.forEach((currentHandler) => { + const isValid = Object.keys(handler).every((key) => { + var _a; + return key === "contextTypes" + ? (_a = handler.contextTypes) === null || _a === void 0 ? void 0 : _a.every((contextType) => { var _a; return (_a = currentHandler.contextTypes) === null || _a === void 0 ? void 0 : _a.includes(contextType); }) + : currentHandler[key] === handler[key]; + }); + if (!isValid) { + return; + } + const intentWithInfo = { + intent: intent.name, + contextTypes: currentHandler.contextTypes, + description: currentHandler.applicationDescription, + displayName: currentHandler.displayName, + icon: currentHandler.applicationIcon, + resultType: currentHandler.resultType + }; + validIntentsWithInfo.push(intentWithInfo); + }); + return validIntentsWithInfo; + }, []); + return intentsWithInfo; + } + async removeRememberedHandler(intentName) { + var _a; + this.logger.trace(`Removing saved handler from prefs storage for intent ${intentName}`); + let prefs; + try { + prefs = await this.prefsController.get(); + } + catch (error) { + this.logger.warn(`prefs.get() threw the following error: ${typeof error === "string" ? error : JSON.stringify(error)}`); + return; + } + const intentPrefs = (_a = prefs.data) === null || _a === void 0 ? void 0 : _a.intents; + if (!intentPrefs) { + this.logger.trace("No app prefs found for current app"); + return; + } + delete intentPrefs[intentName]; + const updatedPrefs = { + ...prefs.data, + intents: intentPrefs + }; + try { + await this.prefsController.update(updatedPrefs); + } + catch (error) { + this.logger.warn(`prefs.update() threw the following error: ${typeof error === "string" ? error : JSON.stringify(error)}`); + return; + } + this.logger.trace(`Handler saved choice for intent ${intentName} removed successfully`); + } + async checkForRememberedHandler(intentRequest) { + var _a, _b; + let prefs; + try { + prefs = await this.prefsController.get(); + } + catch (error) { + this.logger.warn(`prefs.get() threw the following error: ${typeof error === "string" ? error : JSON.stringify(error)}`); + return; + } + const prefsForIntent = (_b = (_a = prefs.data) === null || _a === void 0 ? void 0 : _a.intents) === null || _b === void 0 ? void 0 : _b[intentRequest.intent]; + return prefsForIntent === null || prefsForIntent === void 0 ? void 0 : prefsForIntent.handler; + } + async checkHandleRaiseWithRememberedHandler(intentRequest, resolverInstance, timeout) { + if (intentRequest.target) { + return; + } + const rememberedHandler = await this.checkForRememberedHandler(intentRequest); + if (!rememberedHandler) { + return; + } + const request = { + ...intentRequest, + target: { + app: rememberedHandler.applicationName, + instance: rememberedHandler.instanceId + } + }; + try { + const response = await this.coreRaiseIntent({ request, resolverInstance, timeout }); + return response; + } + catch (error) { + this.logger.trace("Could not raise intent to remembered handler. Removing it from Prefs store"); + await this.removeRememberedHandler(intentRequest.intent); + } + } + async saveUserChoice({ intent, handler, filter, caller }) { + var _a, _b; + const prevPrefs = await this.prefsController.get(caller.applicationName); + const prevIntentsPrefs = ((_a = prevPrefs === null || prevPrefs === void 0 ? void 0 : prevPrefs.data) === null || _a === void 0 ? void 0 : _a.intents) || {}; + const prefsToUpdate = { + ...prevPrefs.data, + intents: { + ...prevIntentsPrefs, + [intent]: { handler, filter } + } + }; + await this.prefsController.update(prefsToUpdate, { app: caller.applicationName }); + (_b = this.logger) === null || _b === void 0 ? void 0 : _b.info(`Saved user's choice of handler for '${caller.applicationName}' app`); + } + constructIntentHandler({ apps, intentName, method, server, title }) { + const info = method.flags.intent; + const app = apps.find((appWithIntents) => appWithIntents.name === server.application); + let appIntent; + if (app === null || app === void 0 ? void 0 : app.intents) { + appIntent = app.intents.find((appDefIntent) => appDefIntent.name === intentName); + } + const handler = { + instanceId: server.instance, + applicationName: server.application, + applicationIcon: info.icon || (app === null || app === void 0 ? void 0 : app.icon), + applicationTitle: (app === null || app === void 0 ? void 0 : app.title) || "", + applicationDescription: info.description || (app === null || app === void 0 ? void 0 : app.caption), + displayName: info.displayName || (appIntent === null || appIntent === void 0 ? void 0 : appIntent.displayName), + contextTypes: info.contextTypes || (appIntent === null || appIntent === void 0 ? void 0 : appIntent.contexts), + instanceTitle: title, + type: "instance", + resultType: (appIntent === null || appIntent === void 0 ? void 0 : appIntent.resultType) || info.resultType + }; + return handler; + } + constructIntentHandlerFromApp(app, intent) { + return { + applicationName: app.name, + applicationTitle: app.title || "", + applicationDescription: app.caption, + displayName: intent.displayName, + contextTypes: intent.contexts, + applicationIcon: app.icon, + type: "app", + resultType: intent.resultType + }; + } + } + + class FactoryCallInfo { + constructor() { + this.initialized = false; + this.details = []; + this.reject = () => { }; + this.resolve = () => { }; + } + init(config) { + this.initialized = true; + this.addCall(config); + this.promise = new Promise((resolve, reject) => { + this.resolve = resolve; + this.reject = reject; + }); + } + addCall(config) { + this.details.push({ date: new Date(), config }); + } + done(g) { + this.resolve(g); + } + error(e) { + this.reject(e); + } + } + + class Prefs { + constructor(appName, interop) { + this.appName = appName; + this.interop = interop; + this.registry = CallbackRegistryFactory(); + this.interopMethodRegistered = false; + } + async get(app) { + const data = (await this.interop.invoke(Prefs.T42GetPrefsMethodName, { app: app !== null && app !== void 0 ? app : this.appName }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + })); + return data.returned; + } + async set(data, options) { + var _a; + this.verifyDataObject(data); + await this.interop.invoke(Prefs.T42SetPrefsMethodName, { app: (_a = options === null || options === void 0 ? void 0 : options.app) !== null && _a !== void 0 ? _a : this.appName, data, merge: false }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async setFor(app, data) { + this.verifyApp(app); + this.verifyDataObject(data); + return this.set(data, { app }); + } + async update(data, options) { + var _a; + this.verifyDataObject(data); + await this.interop.invoke(Prefs.T42SetPrefsMethodName, { app: (_a = options === null || options === void 0 ? void 0 : options.app) !== null && _a !== void 0 ? _a : this.appName, data, merge: true }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async updateFor(app, data) { + this.verifyApp(app); + this.verifyDataObject(data); + return this.update(data, { app }); + } + async clear(app) { + await this.interop.invoke(Prefs.T42SetPrefsMethodName, { app: app !== null && app !== void 0 ? app : this.appName, clear: true }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async clearFor(app) { + this.verifyApp(app); + await this.interop.invoke(Prefs.T42SetPrefsMethodName, { app, clear: true }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async getAll() { + const data = (await this.interop.invoke(Prefs.T42GetPrefsMethodName, undefined, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + })); + return data.returned; + } + async clearAll() { + await this.interop.invoke(Prefs.T42SetPrefsMethodName, { clear: true }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + subscribe(callback) { + this.verifyCallback(callback); + return this.subscribeFor(this.appName, callback); + } + subscribeFor(app, callback) { + this.verifyApp(app); + this.verifyCallback(callback); + const unsubscribeFn = this.registry.add(app, callback); + this.registerInteropIfNeeded() + .then(() => { + this.interop.invoke(Prefs.T42GetPrefsMethodName, { app, subscribe: true }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + }); + return () => { + unsubscribeFn(); + }; + } + async registerInteropIfNeeded() { + if (this.interopMethodRegistered) { + return; + } + this.interopMethodRegistered = true; + await this.interop.register(Prefs.T42UpdatePrefsMethodName, (args) => { + this.registry.execute(args.app, args); + }); + } + verifyApp(app) { + if (!app) { + throw new Error(`app should be defined`); + } + if (!isString(app)) { + throw new Error(`app should be a string`); + } + } + verifyDataObject(data) { + if (!data) { + throw new Error(`data should be defined`); + } + if (!isObject(data)) { + throw new Error(`data should be an object`); + } + } + verifyCallback(callback) { + if (!isFunction(callback)) { + throw new Error(`callback should be defined`); + } + } + } + Prefs.T42UpdatePrefsMethodName = "T42.Prefs.Update"; + Prefs.T42GetPrefsMethodName = "T42.Prefs.Get"; + Prefs.T42SetPrefsMethodName = "T42.Prefs.Set"; + + class Cookies { + constructor(methodName, interop) { + this.methodName = methodName; + this.interop = interop; + } + async get(filter) { + const result = await this.invoke("get-cookies", { filter }); + return result.returned.cookies; + } + async set(cookie) { + this.verifyCookieObject(cookie); + await this.invoke("set-cookie", cookie); + } + async remove(url, name) { + if (!isString(url)) { + throw new Error(`url should be a string`); + } + if (!isString(name)) { + throw new Error(`name should be a string`); + } + await this.invoke("remove-cookie", { url, name }); + } + invoke(command, data) { + return this.interop.invoke(this.methodName, { command, args: data }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_RESPONSE_TIMEOUT_MS, + }); + } + verifyCookieObject(cookie) { + if (!cookie) { + throw new Error(`cookie should be defined`); + } + if (!isObject(cookie)) { + throw new Error(`cookie should be an object`); + } + if (Utils.isNullOrUndefined(cookie.url) || !isString(cookie.url)) { + throw new Error(`cookie.url should be a string`); + } + if (Utils.isNullOrUndefined(cookie.name) || !isString(cookie.name)) { + throw new Error(`cookie.name should be a string`); + } + if (!Utils.isNullOrUndefined(cookie.value) && !isString(cookie.value)) { + throw new Error(`cookie.value should be a string`); + } + if (!Utils.isNullOrUndefined(cookie.domain) && !isString(cookie.domain)) { + throw new Error(`cookie.domain should be a string`); + } + if (!Utils.isNullOrUndefined(cookie.path) && !isString(cookie.path)) { + throw new Error(`cookie.path should be a string`); + } + if (!Utils.isNullOrUndefined(cookie.secure) && typeof cookie.secure !== "boolean") { + throw new Error(`cookie.secure should be a boolean`); + } + if (!Utils.isNullOrUndefined(cookie.httpOnly) && typeof cookie.httpOnly !== "boolean") { + throw new Error(`cookie.httpOnly should be a boolean`); + } + if (!Utils.isNullOrUndefined(cookie.expirationDate) && typeof cookie.expirationDate !== "number") { + throw new Error(`cookie.expirationDate should be a number`); + } + } + } + + function factory$1(agm, methodName) { + const cookies = new Cookies(methodName, agm); + return { + get: cookies.get.bind(cookies), + remove: cookies.remove.bind(cookies), + set: cookies.set.bind(cookies), + ready: () => Promise.resolve() + }; + } + + class EventsDispatcher { + constructor(config) { + this.config = config; + this.glue42EventName = "Glue42"; + this.events = { + notifyStarted: { name: "notifyStarted", handle: this.handleNotifyStarted.bind(this) }, + requestGlue: { name: "requestGlue", handle: this.handleRequestGlue.bind(this) } + }; + } + start(glue) { + if (Utils.isNode()) { + return; + } + this.glue = glue; + this.wireCustomEventListener(); + this.announceStarted(); + } + wireCustomEventListener() { + window.addEventListener(this.glue42EventName, (event) => { + const data = event.detail; + if (!data || !data.glue42) { + return; + } + const glue42Event = data.glue42.event; + const foundHandler = this.events[glue42Event]; + if (!foundHandler) { + return; + } + foundHandler.handle(data.glue42.message); + }); + } + announceStarted() { + this.send("start"); + } + handleRequestGlue() { + if (!this.config.exposeAPI) { + this.send("requestGlueResponse", { error: "Will not give access to the underlying Glue API, because it was explicitly denied upon initialization." }); + return; + } + this.send("requestGlueResponse", { glue: this.glue }); + } + handleNotifyStarted() { + this.announceStarted(); + } + send(eventName, message) { + const payload = { glue42: { event: eventName, message } }; + const event = new CustomEvent(this.glue42EventName, { detail: payload }); + window.dispatchEvent(event); + } + } + + class PromiseWrapper { + static delay(time) { + return new Promise((resolve) => setTimeout(resolve, time)); + } + static async delayForever() { + const biggestPossibleDelay = 2147483647; + while (true) { + await this.delay(biggestPossibleDelay); + } + } + get ended() { + return this.rejected || this.resolved; + } + constructor() { + this.promise = new Promise((resolve, reject) => { + this.resolve = (t) => { + this.resolved = true; + resolve(t); + }; + this.reject = (err) => { + this.rejected = true; + reject(err); + }; + }); + } + } + + class Interception { + constructor() { + this.InterceptorMethodName = "T42.GD.Interception.Execute"; + this.InterceptorHandlerMethodName = "T42.GD.Interception.Handler"; + this.interceptions = []; + } + init(interop) { + this.interop = interop; + } + async register(request) { + if (!request || typeof request !== "object" || Array.isArray(request)) { + throw new Error(`Please provide a valid object.`); + } + const handler = request.handler; + if (typeof handler !== "function") { + throw new Error("Please provide a valid handler function."); + } + const interceptions = request.interceptions; + this.validateInterceptions(interceptions); + this.interceptions.push(request); + try { + await this.interop.invoke(this.InterceptorMethodName, { + command: "register", + interceptions + }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + await this.registerMethodIfNotRegistered(); + } + catch (error) { + this.interceptions = this.interceptions.filter((i) => i !== request); + const message = error.message || "Unknown error"; + const newError = new Error(`Failed to register interception: ${message}`); + throw newError; + } + } + async unregister(request) { + if (!request || typeof request !== "object" || Array.isArray(request)) { + throw new Error(`Please provide a valid object.`); + } + const interceptions = request.interceptions; + this.validateInterceptions(interceptions); + try { + await this.interop.invoke(this.InterceptorMethodName, { + command: "unregister", + interceptions + }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + this.interceptions = this.interceptions.filter((config) => { + return !interceptions.some((interception) => { + return config.interceptions.some((i) => { + return i.domain === interception.domain && i.operation === interception.operation; + }); + }); + }); + } + catch (error) { + const message = error.message || "Unknown error"; + const newError = new Error(`Failed to unregister interception: ${message}`); + throw newError; + } + } + async handleInterception(domain, operation, operationArgs, phase) { + if (this.interop.methods(this.InterceptorMethodName).length === 0) { + return {}; + } + const result = await this.interop.invoke(this.InterceptorMethodName, { + command: "raiseInterception", + interceptions: [{ + operationArgs, + domain, + operation, + phase + }] + }, 'best', { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return result.returned; + } + static createProxyObject(apiToIntercept, domain, interception) { + const methods = Interception.OperationsPerDomain[domain] || []; + const handler = { + get(target, propertyKey, receiver) { + const property = Reflect.get(target, propertyKey, receiver); + try { + if (typeof property !== "function") { + return property; + } + const shouldIntercept = methods.includes(propertyKey); + const isAwaitable = Utils.isPromise(property) || Utils.isAsyncFunction(property); + if (!shouldIntercept || !isAwaitable) { + return property; + } + return Interception.interceptMethod(property, propertyKey, target, domain, interception); + } + catch (error) { + return property; + } + } + }; + const proxyAPI = new Proxy(apiToIntercept, handler); + return proxyAPI; + } + static interceptMethod(originalMethod, propertyKey, target, domain, interception) { + return async function (...args) { + const beforeInterceptionResult = await interception.handleInterception(domain, propertyKey, args, "before"); + if (!Utils.isNullOrUndefined(beforeInterceptionResult.operationResult)) { + return beforeInterceptionResult.operationResult; + } + if (!Utils.isNullOrUndefined(beforeInterceptionResult.operationArgs)) { + args = beforeInterceptionResult.operationArgs; + } + const methodResult = await originalMethod.apply(target, args); + const afterInterceptionResult = await interception.handleInterception(domain, propertyKey, [methodResult], "after"); + if (!Utils.isNullOrUndefined(afterInterceptionResult.operationResult)) { + return afterInterceptionResult.operationResult; + } + return methodResult; + }; + } + toAPI() { + return { + register: this.register.bind(this), + unregister: this.unregister.bind(this), + }; + } + async registerMethodIfNotRegistered() { + var _a; + if ((_a = this.whenRegisteredPromise) === null || _a === void 0 ? void 0 : _a.ended) { + return; + } + this.whenRegisteredPromise = new PromiseWrapper(); + this.registerMethod(); + } + async registerMethod() { + await this.interop.register(this.InterceptorHandlerMethodName, async (data) => { + const command = data.command; + if (command === "raiseInterception") { + const raisedInterception = data.interception; + const interceptor = this.interceptions.find((config) => { + return config.interceptions.some((interception) => { + return interception.domain === raisedInterception.domain && interception.operation === raisedInterception.operation; + }); + }); + const result = await interceptor.handler(raisedInterception); + return result; + } + }); + this.whenRegisteredPromise.resolve(); + } + validateInterceptions(interceptions) { + if (!Array.isArray(interceptions)) { + throw new Error("Please provide a valid array of interceptions."); + } + if (interceptions.length === 0) { + throw new Error("Please provide at least one interception."); + } + for (const interception of interceptions) { + if (typeof interception === "undefined" || interception === null || typeof interception !== "object" || Array.isArray(interception)) { + throw new Error("Please provide a valid interception object."); + } + if (typeof interception.domain !== "string" || !interception.domain) { + throw new Error("Please provide a valid domain string."); + } + if (typeof interception.operation !== "string" || !interception.operation) { + throw new Error("Please provide a valid operation string."); + } + this.validateTypeString(interception); + } + } + validateTypeString(interception) { + if (!isUndefinedOrNull(interception.phase)) { + const isValidType = ["all", "before", "after"].includes(interception.phase); + if (typeof interception.phase !== "string" || !isValidType) { + throw new Error("Please provide a valid phase string."); + } + } + } + } + Interception.OperationsPerDomain = { + "intents": ["raise"] + }; + + const callInfo = new FactoryCallInfo(); + const factory = async (options) => { + let firstRun = false; + if (!callInfo.initialized) { + firstRun = true; + callInfo.init(options); + } + const glue42gd = typeof window !== "undefined" && window.glue42gd; + if (glue42gd) { + if (!firstRun) { + callInfo.addCall(options); + return callInfo.promise; + } + } + const g = await factoryCore(options, glue42gd); + callInfo.resolve(g); + return g; + }; + const factoryCore = async (options, glue42gd) => { + const T42GDExecuteMethod = "T42.GD.Execute"; + const gdMajorVersion = Utils.getGDMajorVersion(); + options = options || {}; + const glueConfig = prepareConfig(options); + options.gateway = options.gateway || {}; + let _appManager; + let _activity; + let _windows; + let _displays; + let _channels; + let _prefs; + const _interceptors = new Interception(); + const _browserEventsDispatcher = new EventsDispatcher(glueConfig); + function createWindows(core) { + if (glueConfig.windows) { + const windowsLogger = getLibLogger("windows", core.logger, glueConfig.windows); + _windows = WindowsFactory(core.agm, windowsLogger, () => { + return _appManager; + }, () => { + return _displays; + }, () => { + return _channels; + }, gdMajorVersion); + debugLog(_windows); + return _windows; + } + } + function createActivities(core) { + var _a; + if (glueConfig.activities) { + if (ActivityModule.checkIsUsingGW3Implementation && ActivityModule.checkIsUsingGW3Implementation(core.connection)) { + const activityLogger = getLibLogger("activity", core.logger, glueConfig.activities); + _activity = new ActivityModule({ + connection: core.connection, + contexts: core.contexts, + agm: core.agm, + logger: activityLogger, + logLevel: "info", + disableAutoAnnounce: false, + disposeRequestHandling: "exit", + announcementInfo: null, + windows: _windows, + appManagerGetter: () => { + return _appManager; + }, + mode: glueConfig.activities.mode, + typesToTrack: glueConfig.activities.typesToTrack, + activityId: (_a = glue42gd === null || glue42gd === void 0 ? void 0 : glue42gd.activityInfo) === null || _a === void 0 ? void 0 : _a.activityId, + gdMajorVersion + }).api; + debugLog(_activity); + return _activity; + } + } + } + function createAppManager(core) { + if (!glueConfig.appManager) { + return; + } + const logger = getLibLogger("appManager", core.logger, glueConfig.appManager); + _appManager = AppManagerFactory({ + agm: core.agm, + windows: _windows, + logger, + activities: _activity, + mode: glueConfig.appManager.mode, + gdMajorVersion + }); + debugLog(_appManager); + return _appManager; + } + function createLayouts(core) { + var _a; + if (!glueConfig.layouts) { + return; + } + const logger = getLibLogger("layouts", core.logger, glueConfig.layouts); + const layoutsConfig = glueConfig.layouts; + const lay = LayoutsFactory({ + agm: core.agm, + appManager: _appManager, + activityGetter: () => _activity, + logger, + mode: layoutsConfig.mode, + autoSaveWindowContext: (_a = layoutsConfig.autoSaveWindowContext) !== null && _a !== void 0 ? _a : false, + gdMajorVersion + }); + debugLog(lay); + return lay; + } + function createChannels(core) { + if (!glueConfig.channels) { + return; + } + const logger = getLibLogger("channels", core.logger, glueConfig.channels); + if (!core.contexts) { + logger.error("Channels library requires Contexts library to be initialized."); + return; + } + _channels = factory$4({ operationMode: glueConfig.channels.operationMode }, core.contexts, core.agm, () => _windows, () => _appManager, logger); + debugLog(_channels); + return _channels; + } + function createHotkeys(core) { + const hotkeysAPI = factory$3(core.agm); + debugLog(hotkeysAPI); + return hotkeysAPI; + } + function createIntents(core) { + const domain = "intents"; + const intents = new Intents(core.agm, _windows, core.logger.subLogger(domain), options, _prefs, _appManager); + const intentsAPI = intents.toAPI(); + const proxyIntentsAPI = Interception.createProxyObject(intentsAPI, domain, _interceptors); + debugLog(proxyIntentsAPI); + return proxyIntentsAPI; + } + function createNotifications(core) { + const notificationsAPI = new Notifications(core.interop, core.logger).toAPI(); + debugLog(notificationsAPI); + return notificationsAPI; + } + function createDisplaysApi(core) { + if (glueConfig.displays) { + const displaysLogger = getLibLogger("displays", core.logger, glueConfig.displays); + _displays = new DisplayManager(core.agm, displaysLogger); + debugLog(_displays); + return _displays; + } + } + function createThemes(core) { + if (!core.contexts) { + return; + } + const themesAPI = factory$2(core.contexts, core.interop); + debugLog(themesAPI); + return themesAPI; + } + function createPrefs(core) { + var _a, _b; + const appName = (_b = (_a = options.application) !== null && _a !== void 0 ? _a : glue42gd === null || glue42gd === void 0 ? void 0 : glue42gd.applicationName) !== null && _b !== void 0 ? _b : core.interop.instance.application; + _prefs = new Prefs(appName, core.interop); + debugLog(_prefs); + return _prefs; + } + function createCookies(core) { + const api = factory$1(core.interop, T42GDExecuteMethod); + debugLog(api); + return api; + } + function createInterception(core) { + _interceptors.init(core.interop); + debugLog(_interceptors); + return _interceptors.toAPI(); + } + function getLibLogger(loggerName, logger, config) { + const newLogger = logger.subLogger(loggerName); + if (config && config.logger) { + const loggerConfig = config.logger; + if (loggerConfig.console) { + newLogger.consoleLevel(loggerConfig.console); + } + if (loggerConfig.publish) { + newLogger.publishLevel(loggerConfig.publish); + } + } + return newLogger; + } + const ext = { + libs: [ + { name: "windows", create: createWindows }, + { name: "activities", create: createActivities }, + { name: "appManager", create: createAppManager }, + { name: "layouts", create: createLayouts }, + { name: "channels", create: createChannels }, + { name: "hotkeys", create: createHotkeys }, + { name: "displays", create: createDisplaysApi }, + { name: "prefs", create: createPrefs }, + { name: "intents", create: createIntents }, + { name: "notifications", create: createNotifications }, + { name: "themes", create: createThemes }, + { name: "cookies", create: createCookies }, + { name: "interception", create: createInterception } + ], + version, + enrichGlue: (glue) => { + glue.config.activities = glueConfig.activities; + glue.config.windows = glueConfig.windows; + glue.config.appManager = glueConfig.appManager; + glue.config.layouts = glueConfig.layouts; + glue.config.channels = glueConfig.channels; + glue.config.displays = glueConfig.displays; + }, + }; + const currentLog = []; + if (typeof window !== "undefined") { + if (!window.glueFactoryLog) { + window.glueFactoryLog = []; + } + window.glueFactoryLog.push(currentLog); + } + function debugLog(entry) { + currentLog.push(entry); + } + const glueApi = (await IOConnectCoreFactory(options, ext)); + if (Array.isArray(options === null || options === void 0 ? void 0 : options.libraries) && options.libraries.length) { + await Promise.all(options.libraries.map((lib) => lib(glueApi, options))); + } + _browserEventsDispatcher.start(glueApi); + return glueApi; + }; + factory.coreVersion = IOConnectCoreFactory.version; + factory.version = version; + factory.calls = callInfo; + + var _a, _b; + let whatToExpose = factory; + let shouldSetToWindow = true; + if (typeof window !== "undefined") { + const windowAsAny = window; + const iodesktop = (_a = windowAsAny.iodesktop) !== null && _a !== void 0 ? _a : windowAsAny.glue42gd; + if (iodesktop && iodesktop.autoInjected) { + whatToExpose = (_b = windowAsAny.IODesktop) !== null && _b !== void 0 ? _b : windowAsAny.Glue; + shouldSetToWindow = false; + } + if (shouldSetToWindow) { + windowAsAny.Glue = whatToExpose; + windowAsAny.IODesktop = whatToExpose; + } + delete windowAsAny.IOBrowser; + delete windowAsAny.GlueCore; + } + whatToExpose.default = whatToExpose; + var whatToExpose$1 = whatToExpose; + + return whatToExpose$1; + +})); +//# sourceMappingURL=desktop.umd.js.map diff --git a/typescript/solution/stocks/src/lib/io.applications.css b/typescript/solution/stocks/src/lib/io.applications.css new file mode 100644 index 0000000..98e5910 --- /dev/null +++ b/typescript/solution/stocks/src/lib/io.applications.css @@ -0,0 +1,12 @@ +:root{--bs-blue: #007be5;--bs-indigo: #6610f2;--bs-purple: #6f42c1;--bs-pink: #fd397a;--bs-red: #ff511f;--bs-orange: #fd7e14;--bs-yellow: #f9a825;--bs-green: #43a047;--bs-teal: #616161;--bs-cyan: #469eb9;--bs-white: #fff;--bs-gray: #6c757d;--bs-gray-dark: #343a40;--bs-gray-100: #f8f9fa;--bs-gray-200: #e9ecef;--bs-gray-300: #dee2e6;--bs-gray-400: #ced4da;--bs-gray-500: #adb5bd;--bs-gray-600: #6c757d;--bs-gray-700: #495057;--bs-gray-800: #343a40;--bs-gray-900: #212529;--bs-primary: #007be5;--bs-secondary: #616161;--bs-success: #43a047;--bs-info: #469eb9;--bs-warning: #f9a825;--bs-danger: #ff511f;--bs-light: #616161;--bs-dark: #616161;--bs-primary-rgb: 0,123,229;--bs-secondary-rgb: 97,97,97;--bs-success-rgb: 67,160,71;--bs-info-rgb: 70,158,185;--bs-warning-rgb: 249,168,37;--bs-danger-rgb: 255,81,31;--bs-light-rgb: 97,97,97;--bs-dark-rgb: 97,97,97;--bs-white-rgb: 255,255,255;--bs-black-rgb: 0,0,0;--bs-body-color-rgb: 33,37,41;--bs-body-bg-rgb: 255,255,255;--bs-font-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--bs-gradient: linear-gradient(180deg, rgba(255,255,255,0.15), rgba(255,255,255,0));--bs-body-font-family: Montserrat,Helvetica Neue,Arial,sans-serif;--bs-body-font-size: .75rem;--bs-body-font-weight: 400;--bs-body-line-height: 1.5;--bs-body-color: #212529;--bs-body-bg: #fff}:root{--t42-font-family: "Montserrat", "Helvetica Neue", Arial, sans-serif;--t42-font-size: 0.75rem;--bs-gutter-x: 0.938rem;--primary: #007be5;--secondary: #616161;--success: #43a047;--info: #616161;--warning: #f9a825;--danger: #ff511f;--light: #616161;--dark: #616161;--white: #ffffff}.dark{--t42-bg-light-base: 0, 0%;--t42-bg-light-l: 18%;--t42-bg-light: 45, 45, 45;--t42-bg-mid: 37, 37, 37;--t42-bg-dark: 30, 30, 30;--t42-content-color-base: 0, 0%;--t42-content-color: #bababa;--t42-content-color-l: 73%;--t42-content-color-muted: hsl(var(--t42-content-color-base), 63%);--t42-content-color-disabled: hsl(var(--t42-content-color-base), 43%);--t42-color-opacity-025: hsla(var(--t42-content-color-base), 100%, 0.025);--t42-color-opacity-05: hsla(var(--t42-content-color-base), 100%, 0.05);--t42-color-opacity-10: hsla(var(--t42-content-color-base), 100%, 0.1);--t42-color-opacity-20: hsla(var(--t42-content-color-base), 100%, 0.2);--t42-color-opacity-30: hsla(var(--t42-content-color-base), 100%, 0.3);--t42-link-color: hsl(var(--t42-content-color-base), 100%);--t42-shadow: 0 0 12px 0 hsla(var(--t42-content-color-base), 0%, 0.15);--t42-border: 0.0625rem solid var(--t42-color-opacity-10);--t42-logo-icon: url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 xmlns:xlink=%27http://www.w3.org/1999/xlink%27 x=%270px%27 y=%270px%27 viewBox=%270 0 100.2 121%27 style=%27enable-background:new 0 0 100.2 121;%27%3E%3Cpath fill=%27%233A77BC%27 d=%27M59.4,10.6l-8.3,8.3c-0.5,0.5-1.4,0.5-1.9,0l-8.3-8.3c-0.5-0.5-0.5-1.4,0-1.9l8.3-8.3c0.5-0.5,1.4-0.5,1.9,0 l8.3,8.3C59.9,9.2,59.9,10.1,59.4,10.6z M59.3,110.4l-8.3-8.3c-0.5-0.5-1.4-0.5-1.9,0l-8.3,8.3c-0.5,0.5-0.5,1.4,0,1.9l8.3,8.3 c0.5,0.5,1.4,0.5,1.9,0l8.3-8.3C59.9,111.8,59.9,110.9,59.3,110.4z%27/%3E%3Cpath fill=%27%23FFFFFF%27 d=%27M100.1,60.1c0.3,7.3-2.9,14.3-9.3,20.6l-24.7,24.7c-0.6,0.6-1.5,0.6-2.1,0l-8.1-8.1c-0.6-0.6-0.6-1.5,0-2.1 l24.7-24.7c0.1-0.1,0.2-0.2,0.3-0.3c3.2-3.3,4.7-6.7,4.4-10.2c0-0.4-0.1-0.8-0.2-1.3c-0.6-3.3-2.8-7-6.8-11l-9.9-9.9 c-0.3-0.3-0.7-0.5-1.1-0.5c-0.4,0-0.8,0.2-1.3,0.6L34.5,69.6c-0.6,0.6-1.5,0.6-2.1,0L27.7,65c-3.3-3.3-3.8-5.1-1.3-7.6 c11.1-11.2,22-22.1,33.2-33.2c2.7-2.7,5.1-4.2,7.5-4.3c2.5-0.1,4.7,1.2,6.9,3.5l14.3,14.3C95.9,45.3,99.8,52.8,100.1,60.1 L100.1,60.1z M0,60.9c0.3,7.3,3.7,14.3,11.2,21.9l14.8,14.8c2.3,2.3,4.5,3.6,6.9,3.5c2.4-0.1,4.8-1.6,7.5-4.3 c11.1-11.1,22.1-22,33.2-33.2c2.5-2.5,2-4.3-1.3-7.6l-4.7-4.7c-0.6-0.6-1.5-0.6-2.1,0L34,83c-0.5,0.5-0.9,0.6-1.3,0.6 c-0.4,0-0.7-0.1-1.1-0.5L21.3,72.7c-4-4-5.7-7.2-6.3-10.5c-0.1-0.4-0.1-0.8-0.2-1.3c-0.3-3.5,1.2-6.9,4.4-10.2 c0.1-0.1,0.2-0.2,0.3-0.3l24.7-24.7c0.6-0.6,0.6-1.5,0-2.1l-8.1-8.1c-0.6-0.6-1.5-0.6-2.1,0L9.3,40.3C2.9,46.6-0.3,53.5,0,60.9 L0,60.9z%27/%3E%3C/svg%3E%0A");--t42-icon-color: var(--t42-link-color);--t42-list-group-hover-bg-special: hsla(var(--t42-content-color-base), 100%, 0.065);--backdrop-filter: blur(5px) saturate(200%);--accordion-filter: invert(1) brightness(1);--filter-close: invert(1);--t42-body: rgb(var(--t42-bg-dark));--pink: rgb(0 170 200);--t42-link-hover-color: hsl(var(--t42-bg-light-base), 100%);--t42-link-hover-bg: var(--t42-color-opacity-05);--t42-link-active-bg: var(--t42-color-opacity-10);--t42-input-bg: rgb(var(--t42-bg-dark));--t42-input-disabled-bg: Hsla(var(--t42-content-color-base), 100%, 0.075);--t42-tooltip-bg: rgba(var(--t42-bg-dark), 0.85);--t42-modal-bg: rgba(var(--t42-bg-light), 0.75);--t42-table-active-bg: rgba(255, 255, 255, 0.1);--t42-select-indicator: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9IiNFRUVFRUUiIHZpZXdCb3g9IjAgMCAxNiAxNiI+PHBhdGggZD0iTTIuNSA1LjVjLjQtLjQgMS0uNSAxLjYgMGwzLjkgMy43bDMuOS0zLjdjLjUtLjUgMS4xLS40IDEuNiAwYy40LjQuNCAxLjIgMCAxLjZjLS40LjQtNC43IDQuNS00LjcgNC41Yy0uMi4yLS41LjMtLjguM3MtLjYtLjEtLjgtLjNjMCAwLTQuMy00LjEtNC43LTQuNXMtLjQtMS4yIDAtMS42eiI+PC9wYXRoPjwvc3ZnPg==)}.light{--t42-bg-light-base: 0, 0%;--t42-bg-light-l: 100%;--t42-bg-light: 255, 255, 255;--t42-bg-mid: 250, 250, 250;--t42-bg-dark: 245, 245, 245;--t42-content-color-base: 0, 0%;--t42-content-color: #757575;--t42-content-color-l: 46%;--t42-content-color-muted: hsl(var(--t42-content-color-base), 66%);--t42-color-opacity-025: hsla(var(--t42-content-color-base), 0%, 0.025);--t42-color-opacity-05: hsla(var(--t42-content-color-base), 0%, 0.05);--t42-color-opacity-10: hsla(var(--t42-content-color-base), 0%, 0.075);--t42-color-opacity-30: hsla(var(--t42-content-color-base), 0%, 0.1);--t42-color-opacity-20: hsla(var(--t42-content-color-base), 0%, 0.2);--t42-link-color: hsl(var(--t42-content-color-base), 5%);--t42-shadow: 0 0 12px 0 hsla(var(--t42-content-color-base), 0%, 0.05);--t42-border: 0.0625rem solid var(--t42-color-opacity-10);--t42-logo-icon: url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 xmlns:xlink=%27http://www.w3.org/1999/xlink%27 x=%270px%27 y=%270px%27 viewBox=%270 0 100.2 121%27 style=%27enable-background:new 0 0 100.2 121;%27%3E%3Cpath fill=%27%233A77BC%27 d=%27M59.4,10.6l-8.3,8.3c-0.5,0.5-1.4,0.5-1.9,0l-8.3-8.3c-0.5-0.5-0.5-1.4,0-1.9l8.3-8.3c0.5-0.5,1.4-0.5,1.9,0 l8.3,8.3C59.9,9.2,59.9,10.1,59.4,10.6z M59.3,110.4l-8.3-8.3c-0.5-0.5-1.4-0.5-1.9,0l-8.3,8.3c-0.5,0.5-0.5,1.4,0,1.9l8.3,8.3 c0.5,0.5,1.4,0.5,1.9,0l8.3-8.3C59.9,111.8,59.9,110.9,59.3,110.4z%27/%3E%3Cpath fill=%27%23083044%27 d=%27M100.1,60.1c0.3,7.3-2.9,14.3-9.3,20.6l-24.7,24.7c-0.6,0.6-1.5,0.6-2.1,0l-8.1-8.1c-0.6-0.6-0.6-1.5,0-2.1 l24.7-24.7c0.1-0.1,0.2-0.2,0.3-0.3c3.2-3.3,4.7-6.7,4.4-10.2c0-0.4-0.1-0.8-0.2-1.3c-0.6-3.3-2.8-7-6.8-11l-9.9-9.9 c-0.3-0.3-0.7-0.5-1.1-0.5c-0.4,0-0.8,0.2-1.3,0.6L34.5,69.6c-0.6,0.6-1.5,0.6-2.1,0L27.7,65c-3.3-3.3-3.8-5.1-1.3-7.6 c11.1-11.2,22-22.1,33.2-33.2c2.7-2.7,5.1-4.2,7.5-4.3c2.5-0.1,4.7,1.2,6.9,3.5l14.3,14.3C95.9,45.3,99.8,52.8,100.1,60.1 L100.1,60.1z M0,60.9c0.3,7.3,3.7,14.3,11.2,21.9l14.8,14.8c2.3,2.3,4.5,3.6,6.9,3.5c2.4-0.1,4.8-1.6,7.5-4.3 c11.1-11.1,22.1-22,33.2-33.2c2.5-2.5,2-4.3-1.3-7.6l-4.7-4.7c-0.6-0.6-1.5-0.6-2.1,0L34,83c-0.5,0.5-0.9,0.6-1.3,0.6 c-0.4,0-0.7-0.1-1.1-0.5L21.3,72.7c-4-4-5.7-7.2-6.3-10.5c-0.1-0.4-0.1-0.8-0.2-1.3c-0.3-3.5,1.2-6.9,4.4-10.2 c0.1-0.1,0.2-0.2,0.3-0.3l24.7-24.7c0.6-0.6,0.6-1.5,0-2.1l-8.1-8.1c-0.6-0.6-1.5-0.6-2.1,0L9.3,40.3C2.9,46.6-0.3,53.5,0,60.9 L0,60.9z%27/%3E%3C/svg%3E%0A");--t42-icon-color: Hsl(var(--t42-content-color-base), 38%);--t42-list-group-hover-bg-special: hsla(var(--t42-content-color-base), 95%, 0.065);--backdrop-filter: blur(5px) saturate(200%);--accordion-filter: brightness(0%);--filter-close: invert(0);--t42-body: rgb(var(--t42-bg-mid));--t42-link-hover-color: hsl(var(--t42-bg-light-base), 0%);--t42-link-hover-bg: hsl(var(--t42-content-color-base), 95%);--t42-link-active-bg: hsl(var(--t42-content-color-base), 90%);--t42-input-bg: rgb(var(--t42-bg-light));--t42-input-disabled-bg: var(--t42-color-opacity-10);--t42-tooltip-bg: rgba(var(--t42-bg-light), 0.95);--t42-modal-bg: rgba(var(--t42-bg-light), 0.95);--t42-table-active-bg: rgba(0, 0, 0, 0.025);--t42-select-indicator: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9IiM2MTYxNjEiIHZpZXdCb3g9IjAgMCAxNiAxNiI+PHBhdGggZD0iTTIuNSA1LjVjLjQtLjQgMS0uNSAxLjYgMGwzLjkgMy43bDMuOS0zLjdjLjUtLjUgMS4xLS40IDEuNiAwYy40LjQuNCAxLjIgMCAxLjZjLS40LjQtNC43IDQuNS00LjcgNC41Yy0uMi4yLS41LjMtLjguM3MtLjYtLjEtLjgtLjNjMCAwLTQuMy00LjEtNC43LTQuNXMtLjQtMS4yIDAtMS42eiI+PC9wYXRoPjwvc3ZnPg==)}*,*::before,*::after{box-sizing:border-box}@media (prefers-reduced-motion: no-preference){:root{scroll-behavior:smooth}}body{margin:0;font-family:var(--bs-body-font-family);font-size:var(--bs-body-font-size);font-weight:var(--bs-body-font-weight);line-height:var(--bs-body-line-height);color:var(--bs-body-color);text-align:var(--bs-body-text-align);background-color:var(--bs-body-bg);-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:rgba(0,0,0,0)}hr{margin:1rem 0;color:inherit;background-color:currentColor;border:0;opacity:.25}hr:not([size]){height:1px}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem;font-weight:500;line-height:1.2;color:var(--t42-link-color)}h1{font-size:calc(1.26563rem + .1875vw)}@media (min-width: 1200px){h1{font-size:1.40625rem}}h2{font-size:1.125rem}h3{font-size:.98475rem}h4{font-size:.84375rem}h5{font-size:.75rem}h6{font-size:.7035rem}p{margin-top:0;margin-bottom:1rem}abbr[title],abbr[data-bs-original-title]{text-decoration:underline dotted;cursor:help;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}ol,ul{padding-left:2rem}ol,ul,dl{margin-top:0;margin-bottom:1rem}ol ol,ul ul,ol ul,ul ol{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:.875em}mark{padding:0.2rem 0.2rem 0;background-color:#007be5}sub,sup{position:relative;font-size:.75em;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:var(--t42-link-color);text-decoration:underline}a:hover{color:var(--t42-link-hover-color)}a:not([href]):not([class]),a:not([href]):not([class]):hover{color:inherit;text-decoration:none}pre,code,kbd,samp{font-family:var(--bs-font-monospace);font-size:1em;direction:ltr /* rtl:ignore */;unicode-bidi:bidi-override}pre{display:block;margin-top:0;margin-bottom:1rem;overflow:auto;font-size:inherit;color:var(--t42-content-color)}pre code{font-size:inherit;color:inherit;word-break:normal}code{font-size:inherit;color:#469eb9;word-wrap:break-word}a>code{color:inherit}kbd{padding:.2rem .4rem;font-size:inherit;color:#fff;background-color:#212529;border-radius:.25rem}kbd kbd{padding:0;font-size:1em;font-weight:700}figure{margin:0 0 1rem}img,svg{vertical-align:middle}table{caption-side:bottom;border-collapse:collapse}caption{padding-top:.25rem;padding-bottom:.25rem;color:var(--t42-content-color-muted);text-align:left}th{text-align:inherit;text-align:-webkit-match-parent}thead,tbody,tfoot,tr,td,th{border-color:inherit;border-style:solid;border-width:0}label{display:inline-block}button{border-radius:0}button:focus:not(:focus-visible){outline:0}input,button,select,optgroup,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,select{text-transform:none}[role="button"]{cursor:pointer}select{word-wrap:normal}select:disabled{opacity:1}[list]::-webkit-calendar-picker-indicator{display:none}button,[type="button"],[type="reset"],[type="submit"]{-webkit-appearance:button}button:not(:disabled),[type="button"]:not(:disabled),[type="reset"]:not(:disabled),[type="submit"]:not(:disabled){cursor:pointer}::-moz-focus-inner{padding:0;border-style:none}textarea{resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{float:left;width:100%;padding:0;margin-bottom:.5rem;font-size:calc(1.275rem + .3vw);line-height:inherit}@media (min-width: 1200px){legend{font-size:1.5rem}}legend+*{clear:left}::-webkit-datetime-edit-fields-wrapper,::-webkit-datetime-edit-text,::-webkit-datetime-edit-minute,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-year-field{padding:0}::-webkit-inner-spin-button{height:auto}[type="search"]{outline-offset:-2px;-webkit-appearance:textfield}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-color-swatch-wrapper{padding:0}::file-selector-button{font:inherit}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}iframe{border:0}summary{display:list-item;cursor:pointer}progress{vertical-align:baseline}[hidden]{display:none !important}body{color:var(--t42-content-color);font-family:var(--t42-font-family);background-color:var(--t42-body)}a:focus,button:focus,div:focus,span:focus{outline:0}a{text-decoration:none}dt{font-weight:normal}::selection{color:var(--white);background-color:var(--primary)}::-webkit-scrollbar{width:4px;height:4px}::-webkit-scrollbar-track{border-radius:.25rem;background:transparent}::-webkit-scrollbar-thumb{border-radius:.25rem;background:var(--t42-color-opacity-10)}::-webkit-resizer{background:transparent}::-webkit-scrollbar-corner{background:transparent}::-webkit-scrollbar-thumb:window-inactive{background:transparent}::-webkit-scrollbar-thumb:hover,::-webkit-scrollbar-thumb:active{background:Hsla(var(--t42-content-color-base), 100%, 0.05)}.accordion-button{position:relative;display:flex;align-items:center;width:100%;padding:1rem 1.25rem;font-size:.75rem;color:var(--t42-link-color);text-align:left;background-color:Rgb(var(--t42-bg-mid));border:0;border-radius:0;overflow-anchor:none;transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out,border-radius 0.15s ease}@media (prefers-reduced-motion: reduce){.accordion-button{transition:none}}.accordion-button:not(.collapsed){color:var(--t42-link-color);background-color:Rgb(var(--t42-bg-mid));box-shadow:inset 0 -1px 0 var(--t42-color-opacity-10)}.accordion-button:not(.collapsed)::after{background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 16 16%27 fill=%27var%28--t42-link-color%29%27%3e%3cpath fill-rule=%27evenodd%27 d=%27M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z%27/%3e%3c/svg%3e");transform:rotate(-180deg)}.accordion-button::after{flex-shrink:0;width:1.25rem;height:1.25rem;margin-left:auto;content:"";background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 16 16%27 fill=%27var%28--t42-link-color%29%27%3e%3cpath fill-rule=%27evenodd%27 d=%27M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z%27/%3e%3c/svg%3e");background-repeat:no-repeat;background-size:1.25rem;transition:transform 0.2s ease-in-out}@media (prefers-reduced-motion: reduce){.accordion-button::after{transition:none}}.accordion-button:hover{z-index:2}.accordion-button:focus{z-index:3;border-color:#007be5;outline:0;box-shadow:0 0 0 0 rgba(0,123,229,0.25)}.accordion-header{margin-bottom:0}.accordion-item{background-color:Rgb(var(--t42-bg-mid));border:1px solid var(--t42-color-opacity-10)}.accordion-item:first-of-type{border-top-left-radius:0;border-top-right-radius:0}.accordion-item:first-of-type .accordion-button{border-top-left-radius:0;border-top-right-radius:0}.accordion-item:not(:first-of-type){border-top:0}.accordion-item:last-of-type{border-bottom-right-radius:0;border-bottom-left-radius:0}.accordion-item:last-of-type .accordion-button.collapsed{border-bottom-right-radius:0;border-bottom-left-radius:0}.accordion-item:last-of-type .accordion-collapse{border-bottom-right-radius:0;border-bottom-left-radius:0}.accordion-body{padding:1rem 1.25rem}.accordion-flush .accordion-collapse{border-width:0}.accordion-flush .accordion-item{border-right:0;border-left:0;border-radius:0}.accordion-flush .accordion-item:first-child{border-top:0}.accordion-flush .accordion-item:last-child{border-bottom:0}.accordion-flush .accordion-item .accordion-button{border-radius:0}.accordion-button::after,.accordion-button:not(.collapsed)::after{filter:var(--accordion-filter)}.accordion-button:disabled,.accordion-button.disabled{color:var(--t42-content-color-disabled)}.accordion-button:disabled::after,.accordion-button.disabled::after{opacity:0.25}.alert{position:relative;padding:.75rem .875rem;margin-bottom:.5rem;border:1px solid transparent;border-radius:0}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-right:2.625rem}.alert-dismissible .btn-close{position:absolute;top:0;right:0;z-index:2;padding:.9375rem .875rem}.alert-primary{color:#004a89;background-color:#cce5fa;border-color:#b3d7f7}.alert-primary .alert-link{color:#003b6e}.alert-secondary{color:#3a3a3a;background-color:#dfdfdf;border-color:#d0d0d0}.alert-secondary .alert-link{color:#2e2e2e}.alert-success{color:#28602b;background-color:#d9ecda;border-color:#c7e3c8}.alert-success .alert-link{color:#204d22}.alert-info{color:#2a5f6f;background-color:#daecf1;border-color:#c8e2ea}.alert-info .alert-link{color:#224c59}.alert-warning{color:#64430f;background-color:#feeed3;border-color:#fde5be}.alert-warning .alert-link{color:#50360c}.alert-danger{color:#993113;background-color:#ffdcd2;border-color:#ffcbbc}.alert-danger .alert-link{color:#7a270f}.alert-light{color:#3a3a3a;background-color:#dfdfdf;border-color:#d0d0d0}.alert-light .alert-link{color:#2e2e2e}.alert-dark{color:#3a3a3a;background-color:#dfdfdf;border-color:#d0d0d0}.alert-dark .alert-link{color:#2e2e2e}.alert{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border-color;position:relative;z-index:10000;display:flex;align-items:center;border:0.0625rem solid var(--t42-color-opacity-10);overflow:hidden;color:var(--t42-content-color);background-color:Rgba(var(--t42-bg-light), 0.75);background-repeat:no-repeat;background-size:100%;backdrop-filter:var(--backdrop-filter)}.alert h5{margin-bottom:0;color:var(--t42-content-color)}.alert p{margin-bottom:0}.alert-link{color:var(--t42-link-color);font-weight:normal}.alert-dismissible .close{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border-color;position:absolute;top:50%;right:0.75rem;width:1.5rem;height:1.5rem;padding:0;border:0;border-radius:50%;color:var(--t42-content-color);font-weight:700;font-size:1rem;line-height:1;background-color:var(--t42-color-opacity-05);transform:translateY(-50%);opacity:0.5}.alert-dismissible .close::before{position:relative;top:-1px}.alert-dismissible .close:hover{opacity:1}.alert::before{z-index:1;width:1.25rem;height:1.25rem;margin-right:0.875rem;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-position:center;mask-position:center;background-color:var(--t42-icon-color);content:""}.alert::after{position:absolute;top:0;left:0;z-index:-1;width:1px;height:1px;border-radius:50%;opacity:1;animation:color-pulse 3s infinite;content:""}.alert-primary:hover,.alert-secondary:hover,.alert-info:hover,.alert-light:hover,.alert-dark:hover{border-color:#616161}.alert-primary::after,.alert-secondary::after,.alert-info::after,.alert-light::after,.alert-dark::after{background:#616161;background:radial-gradient(circle, rgba(255,255,255,0.35) 0%, rgba(97,97,97,0.75) 60%, #616161 75%, #616161 100%)}.alert-primary::before,.alert-secondary::before,.alert-info::before,.alert-light::before,.alert-dark::before{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M260.6 484.4q0-4.1-4.6-4.1q-16.9 0-29.2-12.3t-11.8-29.2q0-4.6-4.6-4.6t-4.6 4.6q0 21 14.8 35.8t35.3 14.3q4.6 0 4.6-4.6zM493.6 402.4q0 14.8-10.8 25.6t-25.6 10.8h-128q0 30.2-21.5 51.7t-51.7 21.5t-51.7-21.5t-21.5-51.7h-128q-14.8 0-25.6-10.8t-10.8-25.6q14.3-12.3 26.1-25.1t24.1-34.3t21.5-45.6t13.8-58.9t5.6-74.2q0-43 33.8-80.4t87.6-45.6q-2.6-5.1-2.6-10.8q0-11.8 8.2-19.5t19.5-8.2t19.5 8.2t8.2 19.5q0 5.6-2.6 10.8q54.3 8.2 87.6 45.6t33.8 80.4q0 39.9 5.6 74.2t14.3 58.9t21 45.6t24.6 34.3t25.6 25.1z%27%3E%3C/path%3E%3C/svg%3E")}.alert-success:hover{border-color:#43a047}.alert-success::after{background:#43a047;background:radial-gradient(circle, rgba(255,255,255,0.35) 0%, rgba(67,160,71,0.75) 60%, #43a047 75%, #43a047 100%)}.alert-success::before{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M477.4 152.8q0 11.3-8.2 19.5l-245.8 245.8q-8.2 7.7-19.5 7.7t-19.5-7.7l-142.3-142.3q-7.7-8.2-7.7-19.5t7.7-19.5l38.9-38.9q8.2-8.2 19.5-8.2t19.5 8.2l84 84.5l187.4-187.9q8.2-8.2 19.5-8.2t19.5 8.2l38.9 38.9q8.2 7.7 8.2 19.5z%27%3E%3C/path%3E%3C/svg%3E")}.alert-warning:hover{border-color:#f9a825}.alert-warning::after{background:#f9a825;background:radial-gradient(circle, rgba(255,255,255,0.35) 0%, rgba(249,168,37,0.75) 60%, #f9a825 75%, #f9a825 100%)}.alert-warning::before{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M292.4 410.9v-54.3q0-4.1-2.6-6.7t-6.1-2.6h-55.3q-3.6 0-6.1 2.6t-2.6 6.7v54.3q0 4.1 2.6 6.7t6.1 3.1h55.3q3.6 0 6.1-3.1t2.6-6.7zM291.8 304.4l5.1-131.6q0-3.1-2.6-5.1q-3.6-3.1-7.2-3.1h-62.5q-3.1 0-7.2 3.1q-2.6 2-2.6 6.1l4.6 130.6q0 2.6 3.1 4.6t6.7 1.5h52.7q4.1 0 7.2-1.5t2.6-4.6zM288.3 37.1l219.1 402.4q10.2 17.9-.5 35.8q-4.6 8.7-13.3 13.3t-17.9 5.1h-439.3q-9.2 0-17.9-5.1t-13.3-13.3q-10.8-17.9-.5-35.8l219.6-402.4q4.6-8.7 13.3-13.8t18.4-5.1t18.4 5.1t13.8 13.8z%27%3E%3C/path%3E%3C/svg%3E%0A")}.alert-danger:hover{border-color:#ff511f}.alert-danger::after{background:#ff511f;background:radial-gradient(circle, rgba(255,255,255,0.35) 0%, rgba(255,81,31,0.75) 60%, #ff511f 75%, #ff511f 100%)}.alert-danger::before{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 402 512%27%3E%3Cpath d=%27M370.728 359.68q0 11.264-7.68 19.456l-38.912 38.912q-8.192 7.68-19.456 7.68t-19.456-7.68l-83.968-84.48-83.968 84.48q-8.192 7.68-19.456 7.68t-19.456-7.68l-38.912-38.912q-8.192-8.192-8.192-19.456t8.192-19.456l83.968-83.968-83.968-83.968q-8.192-8.192-8.192-19.456t8.192-19.456l38.912-38.912q8.192-8.192 19.456-8.192t19.456 8.192l83.968 83.968 83.968-83.968q8.192-8.192 19.456-8.192t19.456 8.192l38.912 38.912q7.68 7.68 7.68 19.456t-7.68 19.456l-83.968 83.968 83.968 83.968q7.68 7.68 7.68 19.456z%27%3E%3C/path%3E%3C/svg%3E")}@keyframes color-pulse{0%{transform:scale(1);opacity:1}50%{transform:scale(250);opacity:0}100%{opacity:0}}.badge{display:inline-block;padding:.2rem .5rem;font-size:.75em;font-weight:300;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:1rem}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.badge{border:var(--t42-border);color:var(--t42-link-color);backdrop-filter:var(--backdrop-filter)}.badge.bg-primary{border:0.0625rem solid #007be5;background-color:rgba(0,123,229,0.15) !important}.badge.bg-secondary{border:0.0625rem solid #616161;background-color:rgba(97,97,97,0.15) !important}.badge.bg-success{border:0.0625rem solid #43a047;background-color:rgba(67,160,71,0.15) !important}.badge.bg-info{border:0.0625rem solid #469eb9;background-color:rgba(70,158,185,0.15) !important}.badge.bg-warning{border:0.0625rem solid #f9a825;background-color:rgba(249,168,37,0.15) !important}.badge.bg-danger{border:0.0625rem solid #ff511f;background-color:rgba(255,81,31,0.15) !important}.badge.bg-light{border:0.0625rem solid #616161;background-color:rgba(97,97,97,0.15) !important}.badge.bg-dark{border:0.0625rem solid #616161;background-color:rgba(97,97,97,0.15) !important}button .badge{border:0.0625rem solid var(--t42-color-opacity-30)}button:hover .badge{color:var(--white)}.btn-close{box-sizing:content-box;width:1em;height:1em;padding:0 0;color:var(--t42-content-color);background:transparent url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 16 16%27 fill=%27var%28--t42-content-color%29%27%3e%3cpath d=%27M.293.293a1 1 0 011.414 0L8 6.586 14.293.293a1 1 0 111.414 1.414L9.414 8l6.293 6.293a1 1 0 01-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 01-1.414-1.414L6.586 8 .293 1.707a1 1 0 010-1.414z%27/%3e%3c/svg%3e") center/1em auto no-repeat;border:0;border-radius:.25rem;opacity:.5}.btn-close:hover{color:var(--t42-content-color);text-decoration:none;opacity:.75}.btn-close:focus{outline:0;box-shadow:0 0 0 0 rgba(0,123,229,0.25);opacity:1}.btn-close:disabled,.btn-close.disabled{pointer-events:none;user-select:none;opacity:.25}.btn-close-white{filter:invert(1) grayscale(100%) brightness(200%)}.btn{display:inline-block;font-weight:400;line-height:1.875rem;color:#212529;text-align:center;text-decoration:none;vertical-align:middle;cursor:pointer;user-select:none;background-color:transparent;border:1px solid transparent;padding:0 .875rem;font-size:.75rem;border-radius:0;transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.btn{transition:none}}.btn:hover{color:#212529}.btn-check:focus+.btn,.btn:focus{outline:0;box-shadow:0 0 0 0 rgba(0,123,229,0.25)}.btn:disabled,.btn.disabled,fieldset:disabled .btn{pointer-events:none;opacity:.35}.btn-primary{color:#000;background-color:#007be5;border-color:#007be5}.btn-primary:hover{color:#000;background-color:#268fe9;border-color:#1a88e8}.btn-check:focus+.btn-primary,.btn-primary:focus{color:#000;background-color:#268fe9;border-color:#1a88e8;box-shadow:0 0 0 0 rgba(0,105,195,0.5)}.btn-check:checked+.btn-primary,.btn-check:active+.btn-primary,.btn-primary:active,.btn-primary.active,.show>.btn-primary.dropdown-toggle{color:#000;background-color:#3395ea;border-color:#1a88e8}.btn-check:checked+.btn-primary:focus,.btn-check:active+.btn-primary:focus,.btn-primary:active:focus,.btn-primary.active:focus,.show>.btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(0,105,195,0.5)}.btn-primary:disabled,.btn-primary.disabled{color:#000;background-color:#007be5;border-color:#007be5}.btn-secondary{color:#fff;background-color:#616161;border-color:#616161}.btn-secondary:hover{color:#fff;background-color:#525252;border-color:#4e4e4e}.btn-check:focus+.btn-secondary,.btn-secondary:focus{color:#fff;background-color:#525252;border-color:#4e4e4e;box-shadow:0 0 0 0 rgba(121,121,121,0.5)}.btn-check:checked+.btn-secondary,.btn-check:active+.btn-secondary,.btn-secondary:active,.btn-secondary.active,.show>.btn-secondary.dropdown-toggle{color:#fff;background-color:#4e4e4e;border-color:#494949}.btn-check:checked+.btn-secondary:focus,.btn-check:active+.btn-secondary:focus,.btn-secondary:active:focus,.btn-secondary.active:focus,.show>.btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(121,121,121,0.5)}.btn-secondary:disabled,.btn-secondary.disabled{color:#fff;background-color:#616161;border-color:#616161}.btn-success{color:#000;background-color:#43a047;border-color:#43a047}.btn-success:hover{color:#000;background-color:#5fae63;border-color:#56aa59}.btn-check:focus+.btn-success,.btn-success:focus{color:#000;background-color:#5fae63;border-color:#56aa59;box-shadow:0 0 0 0 rgba(57,136,60,0.5)}.btn-check:checked+.btn-success,.btn-check:active+.btn-success,.btn-success:active,.btn-success.active,.show>.btn-success.dropdown-toggle{color:#000;background-color:#69b36c;border-color:#56aa59}.btn-check:checked+.btn-success:focus,.btn-check:active+.btn-success:focus,.btn-success:active:focus,.btn-success.active:focus,.show>.btn-success.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(57,136,60,0.5)}.btn-success:disabled,.btn-success.disabled{color:#000;background-color:#43a047;border-color:#43a047}.btn-info{color:#000;background-color:#469eb9;border-color:#469eb9}.btn-info:hover{color:#000;background-color:#62adc4;border-color:#59a8c0}.btn-check:focus+.btn-info,.btn-info:focus{color:#000;background-color:#62adc4;border-color:#59a8c0;box-shadow:0 0 0 0 rgba(60,134,157,0.5)}.btn-check:checked+.btn-info,.btn-check:active+.btn-info,.btn-info:active,.btn-info.active,.show>.btn-info.dropdown-toggle{color:#000;background-color:#6bb1c7;border-color:#59a8c0}.btn-check:checked+.btn-info:focus,.btn-check:active+.btn-info:focus,.btn-info:active:focus,.btn-info.active:focus,.show>.btn-info.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(60,134,157,0.5)}.btn-info:disabled,.btn-info.disabled{color:#000;background-color:#469eb9;border-color:#469eb9}.btn-warning{color:#000;background-color:#f9a825;border-color:#f9a825}.btn-warning:hover{color:#000;background-color:#fab546;border-color:#fab13b}.btn-check:focus+.btn-warning,.btn-warning:focus{color:#000;background-color:#fab546;border-color:#fab13b;box-shadow:0 0 0 0 rgba(212,143,31,0.5)}.btn-check:checked+.btn-warning,.btn-check:active+.btn-warning,.btn-warning:active,.btn-warning.active,.show>.btn-warning.dropdown-toggle{color:#000;background-color:#fab951;border-color:#fab13b}.btn-check:checked+.btn-warning:focus,.btn-check:active+.btn-warning:focus,.btn-warning:active:focus,.btn-warning.active:focus,.show>.btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(212,143,31,0.5)}.btn-warning:disabled,.btn-warning.disabled{color:#000;background-color:#f9a825;border-color:#f9a825}.btn-danger{color:#000;background-color:#ff511f;border-color:#ff511f}.btn-danger:hover{color:#000;background-color:#ff6b41;border-color:#ff6235}.btn-check:focus+.btn-danger,.btn-danger:focus{color:#000;background-color:#ff6b41;border-color:#ff6235;box-shadow:0 0 0 0 rgba(217,69,26,0.5)}.btn-check:checked+.btn-danger,.btn-check:active+.btn-danger,.btn-danger:active,.btn-danger.active,.show>.btn-danger.dropdown-toggle{color:#000;background-color:#ff744c;border-color:#ff6235}.btn-check:checked+.btn-danger:focus,.btn-check:active+.btn-danger:focus,.btn-danger:active:focus,.btn-danger.active:focus,.show>.btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(217,69,26,0.5)}.btn-danger:disabled,.btn-danger.disabled{color:#000;background-color:#ff511f;border-color:#ff511f}.btn-light{color:#fff;background-color:#616161;border-color:#616161}.btn-light:hover{color:#fff;background-color:#525252;border-color:#4e4e4e}.btn-check:focus+.btn-light,.btn-light:focus{color:#fff;background-color:#525252;border-color:#4e4e4e;box-shadow:0 0 0 0 rgba(121,121,121,0.5)}.btn-check:checked+.btn-light,.btn-check:active+.btn-light,.btn-light:active,.btn-light.active,.show>.btn-light.dropdown-toggle{color:#fff;background-color:#4e4e4e;border-color:#494949}.btn-check:checked+.btn-light:focus,.btn-check:active+.btn-light:focus,.btn-light:active:focus,.btn-light.active:focus,.show>.btn-light.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(121,121,121,0.5)}.btn-light:disabled,.btn-light.disabled{color:#fff;background-color:#616161;border-color:#616161}.btn-dark{color:#fff;background-color:#616161;border-color:#616161}.btn-dark:hover{color:#fff;background-color:#525252;border-color:#4e4e4e}.btn-check:focus+.btn-dark,.btn-dark:focus{color:#fff;background-color:#525252;border-color:#4e4e4e;box-shadow:0 0 0 0 rgba(121,121,121,0.5)}.btn-check:checked+.btn-dark,.btn-check:active+.btn-dark,.btn-dark:active,.btn-dark.active,.show>.btn-dark.dropdown-toggle{color:#fff;background-color:#4e4e4e;border-color:#494949}.btn-check:checked+.btn-dark:focus,.btn-check:active+.btn-dark:focus,.btn-dark:active:focus,.btn-dark.active:focus,.show>.btn-dark.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(121,121,121,0.5)}.btn-dark:disabled,.btn-dark.disabled{color:#fff;background-color:#616161;border-color:#616161}.btn-outline-primary{color:#007be5;border-color:#007be5}.btn-outline-primary:hover{color:#000;background-color:#007be5;border-color:#007be5}.btn-check:focus+.btn-outline-primary,.btn-outline-primary:focus{box-shadow:0 0 0 0 rgba(0,123,229,0.5)}.btn-check:checked+.btn-outline-primary,.btn-check:active+.btn-outline-primary,.btn-outline-primary:active,.btn-outline-primary.active,.btn-outline-primary.dropdown-toggle.show{color:#000;background-color:#007be5;border-color:#007be5}.btn-check:checked+.btn-outline-primary:focus,.btn-check:active+.btn-outline-primary:focus,.btn-outline-primary:active:focus,.btn-outline-primary.active:focus,.btn-outline-primary.dropdown-toggle.show:focus{box-shadow:0 0 0 0 rgba(0,123,229,0.5)}.btn-outline-primary:disabled,.btn-outline-primary.disabled{color:#007be5;background-color:transparent}.btn-outline-secondary{color:#616161;border-color:#616161}.btn-outline-secondary:hover{color:#fff;background-color:#616161;border-color:#616161}.btn-check:focus+.btn-outline-secondary,.btn-outline-secondary:focus{box-shadow:0 0 0 0 rgba(97,97,97,0.5)}.btn-check:checked+.btn-outline-secondary,.btn-check:active+.btn-outline-secondary,.btn-outline-secondary:active,.btn-outline-secondary.active,.btn-outline-secondary.dropdown-toggle.show{color:#fff;background-color:#616161;border-color:#616161}.btn-check:checked+.btn-outline-secondary:focus,.btn-check:active+.btn-outline-secondary:focus,.btn-outline-secondary:active:focus,.btn-outline-secondary.active:focus,.btn-outline-secondary.dropdown-toggle.show:focus{box-shadow:0 0 0 0 rgba(97,97,97,0.5)}.btn-outline-secondary:disabled,.btn-outline-secondary.disabled{color:#616161;background-color:transparent}.btn-outline-success{color:#43a047;border-color:#43a047}.btn-outline-success:hover{color:#000;background-color:#43a047;border-color:#43a047}.btn-check:focus+.btn-outline-success,.btn-outline-success:focus{box-shadow:0 0 0 0 rgba(67,160,71,0.5)}.btn-check:checked+.btn-outline-success,.btn-check:active+.btn-outline-success,.btn-outline-success:active,.btn-outline-success.active,.btn-outline-success.dropdown-toggle.show{color:#000;background-color:#43a047;border-color:#43a047}.btn-check:checked+.btn-outline-success:focus,.btn-check:active+.btn-outline-success:focus,.btn-outline-success:active:focus,.btn-outline-success.active:focus,.btn-outline-success.dropdown-toggle.show:focus{box-shadow:0 0 0 0 rgba(67,160,71,0.5)}.btn-outline-success:disabled,.btn-outline-success.disabled{color:#43a047;background-color:transparent}.btn-outline-info{color:#469eb9;border-color:#469eb9}.btn-outline-info:hover{color:#000;background-color:#469eb9;border-color:#469eb9}.btn-check:focus+.btn-outline-info,.btn-outline-info:focus{box-shadow:0 0 0 0 rgba(70,158,185,0.5)}.btn-check:checked+.btn-outline-info,.btn-check:active+.btn-outline-info,.btn-outline-info:active,.btn-outline-info.active,.btn-outline-info.dropdown-toggle.show{color:#000;background-color:#469eb9;border-color:#469eb9}.btn-check:checked+.btn-outline-info:focus,.btn-check:active+.btn-outline-info:focus,.btn-outline-info:active:focus,.btn-outline-info.active:focus,.btn-outline-info.dropdown-toggle.show:focus{box-shadow:0 0 0 0 rgba(70,158,185,0.5)}.btn-outline-info:disabled,.btn-outline-info.disabled{color:#469eb9;background-color:transparent}.btn-outline-warning{color:#f9a825;border-color:#f9a825}.btn-outline-warning:hover{color:#000;background-color:#f9a825;border-color:#f9a825}.btn-check:focus+.btn-outline-warning,.btn-outline-warning:focus{box-shadow:0 0 0 0 rgba(249,168,37,0.5)}.btn-check:checked+.btn-outline-warning,.btn-check:active+.btn-outline-warning,.btn-outline-warning:active,.btn-outline-warning.active,.btn-outline-warning.dropdown-toggle.show{color:#000;background-color:#f9a825;border-color:#f9a825}.btn-check:checked+.btn-outline-warning:focus,.btn-check:active+.btn-outline-warning:focus,.btn-outline-warning:active:focus,.btn-outline-warning.active:focus,.btn-outline-warning.dropdown-toggle.show:focus{box-shadow:0 0 0 0 rgba(249,168,37,0.5)}.btn-outline-warning:disabled,.btn-outline-warning.disabled{color:#f9a825;background-color:transparent}.btn-outline-danger{color:#ff511f;border-color:#ff511f}.btn-outline-danger:hover{color:#000;background-color:#ff511f;border-color:#ff511f}.btn-check:focus+.btn-outline-danger,.btn-outline-danger:focus{box-shadow:0 0 0 0 rgba(255,81,31,0.5)}.btn-check:checked+.btn-outline-danger,.btn-check:active+.btn-outline-danger,.btn-outline-danger:active,.btn-outline-danger.active,.btn-outline-danger.dropdown-toggle.show{color:#000;background-color:#ff511f;border-color:#ff511f}.btn-check:checked+.btn-outline-danger:focus,.btn-check:active+.btn-outline-danger:focus,.btn-outline-danger:active:focus,.btn-outline-danger.active:focus,.btn-outline-danger.dropdown-toggle.show:focus{box-shadow:0 0 0 0 rgba(255,81,31,0.5)}.btn-outline-danger:disabled,.btn-outline-danger.disabled{color:#ff511f;background-color:transparent}.btn-outline-light{color:#616161;border-color:#616161}.btn-outline-light:hover{color:#fff;background-color:#616161;border-color:#616161}.btn-check:focus+.btn-outline-light,.btn-outline-light:focus{box-shadow:0 0 0 0 rgba(97,97,97,0.5)}.btn-check:checked+.btn-outline-light,.btn-check:active+.btn-outline-light,.btn-outline-light:active,.btn-outline-light.active,.btn-outline-light.dropdown-toggle.show{color:#fff;background-color:#616161;border-color:#616161}.btn-check:checked+.btn-outline-light:focus,.btn-check:active+.btn-outline-light:focus,.btn-outline-light:active:focus,.btn-outline-light.active:focus,.btn-outline-light.dropdown-toggle.show:focus{box-shadow:0 0 0 0 rgba(97,97,97,0.5)}.btn-outline-light:disabled,.btn-outline-light.disabled{color:#616161;background-color:transparent}.btn-outline-dark{color:#616161;border-color:#616161}.btn-outline-dark:hover{color:#fff;background-color:#616161;border-color:#616161}.btn-check:focus+.btn-outline-dark,.btn-outline-dark:focus{box-shadow:0 0 0 0 rgba(97,97,97,0.5)}.btn-check:checked+.btn-outline-dark,.btn-check:active+.btn-outline-dark,.btn-outline-dark:active,.btn-outline-dark.active,.btn-outline-dark.dropdown-toggle.show{color:#fff;background-color:#616161;border-color:#616161}.btn-check:checked+.btn-outline-dark:focus,.btn-check:active+.btn-outline-dark:focus,.btn-outline-dark:active:focus,.btn-outline-dark.active:focus,.btn-outline-dark.dropdown-toggle.show:focus{box-shadow:0 0 0 0 rgba(97,97,97,0.5)}.btn-outline-dark:disabled,.btn-outline-dark.disabled{color:#616161;background-color:transparent}.btn-link{font-weight:400;color:var(--t42-link-color);text-decoration:underline}.btn-link:hover{color:var(--t42-link-hover-color)}.btn-link:disabled,.btn-link.disabled{color:#6c757d}.btn-lg,.btn-group-lg>.btn{padding:0 .875rem;font-size:.75rem;border-radius:0}.btn-sm,.btn-group-sm>.btn{padding:0 .875rem;font-size:.75rem;border-radius:0}.btn-group,.btn-group-vertical{position:relative;display:inline-flex;vertical-align:middle}.btn-group>.btn,.btn-group-vertical>.btn{position:relative;flex:1 1 auto}.btn-group>.btn-check:checked+.btn,.btn-group>.btn-check:focus+.btn,.btn-group>.btn:hover,.btn-group>.btn:focus,.btn-group>.btn:active,.btn-group>.btn.active,.btn-group-vertical>.btn-check:checked+.btn,.btn-group-vertical>.btn-check:focus+.btn,.btn-group-vertical>.btn:hover,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn.active{z-index:1}.btn-toolbar{display:flex;flex-wrap:wrap;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group>.btn:not(:first-child),.btn-group>.btn-group:not(:first-child){margin-left:-1px}.btn-group>.btn:not(:last-child):not(.dropdown-toggle),.btn-group>.btn-group:not(:last-child)>.btn{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:nth-child(n+3),.btn-group>:not(.btn-check)+.btn,.btn-group>.btn-group:not(:first-child)>.btn{border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.65625rem;padding-left:.65625rem}.dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after,.dropend .dropdown-toggle-split::after{margin-left:0}.dropstart .dropdown-toggle-split::before{margin-right:0}.btn-sm+.dropdown-toggle-split,.btn-group-sm>.btn+.dropdown-toggle-split{padding-right:.65625rem;padding-left:.65625rem}.btn-lg+.dropdown-toggle-split,.btn-group-lg>.btn+.dropdown-toggle-split{padding-right:.65625rem;padding-left:.65625rem}.btn-group-vertical{flex-direction:column;align-items:flex-start;justify-content:center}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn:not(:first-child),.btn-group-vertical>.btn-group:not(:first-child){margin-top:-1px}.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle),.btn-group-vertical>.btn-group:not(:last-child)>.btn{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn ~ .btn,.btn-group-vertical>.btn-group:not(:first-child)>.btn{border-top-left-radius:0;border-top-right-radius:0}button,button:focus{outline:none}.btn{color:var(--t42-link-color);transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, border-color;cursor:default}.btn.disabled,.btn:disabled{color:var(--t42-link-color);cursor:default}.btn:not(.disabled):not(:disabled).active,.btn:not(.disabled):not(:disabled):hover{border-color:var(--t42-color-opacity-30);color:var(--white);backdrop-filter:var(--backdrop-filter)}.btn:focus,.btn:active{color:var(--white)}.btn-primary{background-color:rgba(0,123,229,0.05)}.btn-primary.disabled,.btn-primary:disabled{background-color:rgba(0,123,229,0.05)}.btn-primary:not(.disabled):not(:disabled).active,.btn-primary:not(.disabled):not(:disabled):hover{background-color:#007be5}.btn-primary:not(.disabled):not(:disabled).btn-icon.active,.btn-primary:not(.disabled):not(:disabled).btn-icon:focus,.btn-primary:not(.disabled):not(:disabled).btn-icon:hover{color:var(--white)}.btn-primary.dropdown-toggle.active,.btn-primary.dropdown-toggle:active,.btn-primary.dropdown-toggle:focus{border-color:var(--t42-color-opacity-30);background-color:#007be5}.btn-secondary{background-color:rgba(97,97,97,0.05)}.btn-secondary.disabled,.btn-secondary:disabled{background-color:rgba(97,97,97,0.05)}.btn-secondary:not(.disabled):not(:disabled).active,.btn-secondary:not(.disabled):not(:disabled):hover{background-color:#616161}.btn-secondary:not(.disabled):not(:disabled).btn-icon.active,.btn-secondary:not(.disabled):not(:disabled).btn-icon:focus,.btn-secondary:not(.disabled):not(:disabled).btn-icon:hover{color:var(--white)}.btn-secondary.dropdown-toggle.active,.btn-secondary.dropdown-toggle:active,.btn-secondary.dropdown-toggle:focus{border-color:var(--t42-color-opacity-30);background-color:#616161}.btn-success{background-color:rgba(67,160,71,0.05)}.btn-success.disabled,.btn-success:disabled{background-color:rgba(67,160,71,0.05)}.btn-success:not(.disabled):not(:disabled).active,.btn-success:not(.disabled):not(:disabled):hover{background-color:#43a047}.btn-success:not(.disabled):not(:disabled).btn-icon.active,.btn-success:not(.disabled):not(:disabled).btn-icon:focus,.btn-success:not(.disabled):not(:disabled).btn-icon:hover{color:var(--white)}.btn-success.dropdown-toggle.active,.btn-success.dropdown-toggle:active,.btn-success.dropdown-toggle:focus{border-color:var(--t42-color-opacity-30);background-color:#43a047}.btn-info{background-color:rgba(70,158,185,0.05)}.btn-info.disabled,.btn-info:disabled{background-color:rgba(70,158,185,0.05)}.btn-info:not(.disabled):not(:disabled).active,.btn-info:not(.disabled):not(:disabled):hover{background-color:#469eb9}.btn-info:not(.disabled):not(:disabled).btn-icon.active,.btn-info:not(.disabled):not(:disabled).btn-icon:focus,.btn-info:not(.disabled):not(:disabled).btn-icon:hover{color:var(--white)}.btn-info.dropdown-toggle.active,.btn-info.dropdown-toggle:active,.btn-info.dropdown-toggle:focus{border-color:var(--t42-color-opacity-30);background-color:#469eb9}.btn-warning{background-color:rgba(249,168,37,0.05)}.btn-warning.disabled,.btn-warning:disabled{background-color:rgba(249,168,37,0.05)}.btn-warning:not(.disabled):not(:disabled).active,.btn-warning:not(.disabled):not(:disabled):hover{background-color:#f9a825}.btn-warning:not(.disabled):not(:disabled).btn-icon.active,.btn-warning:not(.disabled):not(:disabled).btn-icon:focus,.btn-warning:not(.disabled):not(:disabled).btn-icon:hover{color:var(--white)}.btn-warning.dropdown-toggle.active,.btn-warning.dropdown-toggle:active,.btn-warning.dropdown-toggle:focus{border-color:var(--t42-color-opacity-30);background-color:#f9a825}.btn-danger{background-color:rgba(255,81,31,0.05)}.btn-danger.disabled,.btn-danger:disabled{background-color:rgba(255,81,31,0.05)}.btn-danger:not(.disabled):not(:disabled).active,.btn-danger:not(.disabled):not(:disabled):hover{background-color:#ff511f}.btn-danger:not(.disabled):not(:disabled).btn-icon.active,.btn-danger:not(.disabled):not(:disabled).btn-icon:focus,.btn-danger:not(.disabled):not(:disabled).btn-icon:hover{color:var(--white)}.btn-danger.dropdown-toggle.active,.btn-danger.dropdown-toggle:active,.btn-danger.dropdown-toggle:focus{border-color:var(--t42-color-opacity-30);background-color:#ff511f}.btn-light{background-color:rgba(97,97,97,0.05)}.btn-light.disabled,.btn-light:disabled{background-color:rgba(97,97,97,0.05)}.btn-light:not(.disabled):not(:disabled).active,.btn-light:not(.disabled):not(:disabled):hover{background-color:#616161}.btn-light:not(.disabled):not(:disabled).btn-icon.active,.btn-light:not(.disabled):not(:disabled).btn-icon:focus,.btn-light:not(.disabled):not(:disabled).btn-icon:hover{color:var(--white)}.btn-light.dropdown-toggle.active,.btn-light.dropdown-toggle:active,.btn-light.dropdown-toggle:focus{border-color:var(--t42-color-opacity-30);background-color:#616161}.btn-dark{background-color:rgba(97,97,97,0.05)}.btn-dark.disabled,.btn-dark:disabled{background-color:rgba(97,97,97,0.05)}.btn-dark:not(.disabled):not(:disabled).active,.btn-dark:not(.disabled):not(:disabled):hover{background-color:#616161}.btn-dark:not(.disabled):not(:disabled).btn-icon.active,.btn-dark:not(.disabled):not(:disabled).btn-icon:focus,.btn-dark:not(.disabled):not(:disabled).btn-icon:hover{color:var(--white)}.btn-dark.dropdown-toggle.active,.btn-dark.dropdown-toggle:active,.btn-dark.dropdown-toggle:focus{border-color:var(--t42-color-opacity-30);background-color:#616161}.btn-link{text-decoration:none;backdrop-filter:none}.btn-link:not(.disabled):not(:disabled).active,.btn-link:not(.disabled):not(:disabled):focus,.btn-link:not(.disabled):not(:disabled):hover{border-color:transparent;color:var(--t42-link-color);text-decoration:underline}.btn-icon:not(.disabled):not(:disabled).active,.btn-icon:not(.disabled):not(:disabled):focus,.btn-icon:not(.disabled):not(:disabled):hover{color:var(--t42-link-color)}.btn-icon-action{display:flex;justify-content:center;width:1rem;height:1rem;padding:0;border-radius:50%;font-size:0.75rem;transition:all .2s ease-in-out}@media (prefers-reduced-motion: reduce){.btn-icon-action{transition:none}}.btn-icon-action:not(.disabled):not(:disabled).active,.btn-icon-action:not(.disabled):not(:disabled):hover,.btn-icon-action:not(.disabled):not(:disabled):focus{border-color:transparent;background-color:Rgb(var(--t42-bg-light));box-shadow:var(--t42-shadow)}.btn-icon-action-right{position:absolute;right:0.25rem}.btn-icon-action-show-hover{transition:all .2s ease-in-out}@media (prefers-reduced-motion: reduce){.btn-icon-action-show-hover{transition:none}}.btn-icon-action-show-hover .btn-icon-action{opacity:0}.btn-icon-action-show-hover:not(.disabled):not(:disabled):hover .btn-icon-action{opacity:1}.btn-close{width:1rem;height:1rem;filter:var(--filter-close)}.breadcrumb{display:flex;flex-wrap:wrap;padding:0 0;margin-bottom:.5rem;list-style:none;background-color:rgba(0,0,0,0)}.breadcrumb-item+.breadcrumb-item{padding-left:.5rem}.breadcrumb-item+.breadcrumb-item::before{float:left;padding-right:.5rem;color:#6c757d;content:var(--bs-breadcrumb-divider, "/") /* rtl: var(--bs-breadcrumb-divider, "/") */}.breadcrumb-item.active{color:var(--t42-link-color)}.breadcrumb-item{font-size:83.3%}.breadcrumb-item.active{text-decoration:underline}.breadcrumb-item+.breadcrumb-item{padding-left:0}.breadcrumb-item+.breadcrumb-item::before{position:relative;top:0.063rem;left:0.063rem;width:0.75rem;height:0.75rem;background-color:var(--t42-content-color);content:"";-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M339.2,256.3c0,2.4-0.9,4.4-2.6,6.1L203,396c-1.7,1.7-3.8,2.6-6.1,2.6c-2.4,0-4.6-0.9-6.7-2.6l-14.3-14.3 c-2-2-3.1-4.3-3.1-6.7s1-4.6,3.1-6.7L288,256.3L175.9,143.6c-2-1.7-3.1-3.8-3.1-6.1s1-4.6,3.1-6.7l14.3-14.3c1.7-2,3.9-3.1,6.7-3.1 s4.8,1,6.1,3.1l133.6,133.1C338.3,251.3,339.2,253.5,339.2,256.3L339.2,256.3z%27/%3E%3C/svg%3E")}mark,.mark{color:var(--white)}pre{background-color:var(--t42-bg-dark)}blockquote,.blockquote{padding:1rem 1rem 0.01rem;border-left:0.25rem solid var(--secondary);background-color:Rgb(var(--t42-bg-dark))}.blockquote-footer{margin-top:-2rem;margin-left:1.25rem;color:var(--t42-content-color-muted);font-size:0.875em}pre{border:0.0625rem solid var(--t42-color-opacity-10)}.card{position:relative;display:flex;flex-direction:column;min-width:0;word-wrap:break-word;background-color:Rgba(var(--t42-bg-light), 0.75);background-clip:border-box;border:1px solid var(--t42-color-opacity-10);border-radius:0}.card>hr{margin-right:0;margin-left:0}.card>.list-group{border-top:inherit;border-bottom:inherit}.card>.list-group:first-child{border-top-width:0;border-top-left-radius:0;border-top-right-radius:0}.card>.list-group:last-child{border-bottom-width:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.card>.card-header+.list-group,.card>.list-group+.card-footer{border-top:0}.card-body{flex:1 1 auto;padding:1.25rem 1.25rem}.card-title{margin-bottom:.5rem}.card-subtitle{margin-top:-.25rem;margin-bottom:0}.card-text:last-child{margin-bottom:0}.card-link+.card-link{margin-left:1.25rem}.card-header{padding:.625rem 1.25rem;margin-bottom:0;color:var(--t42-link-color);background-color:rgba(0,0,0,0);border-bottom:1px solid var(--t42-color-opacity-10)}.card-header:first-child{border-radius:0 0 0 0}.card-footer{padding:.625rem 1.25rem;color:var(--t42-link-color);background-color:rgba(0,0,0,0);border-top:1px solid var(--t42-color-opacity-10)}.card-footer:last-child{border-radius:0 0 0 0}.card-header-tabs{margin-right:-.625rem;margin-bottom:-.625rem;margin-left:-.625rem;border-bottom:0}.card-header-tabs .nav-link.active{background-color:Rgba(var(--t42-bg-light), 0.75);border-bottom-color:Rgba(var(--t42-bg-light), 0.75)}.card-header-pills{margin-right:-.625rem;margin-left:-.625rem}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1rem;border-radius:0}.card-img,.card-img-top,.card-img-bottom{width:100%}.card-img,.card-img-top{border-top-left-radius:0;border-top-right-radius:0}.card-img,.card-img-bottom{border-bottom-right-radius:0;border-bottom-left-radius:0}.card-group>.card{margin-bottom:.75rem}@media (min-width: 576px){.card-group{display:flex;flex-flow:row wrap}.card-group>.card{flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:not(:last-child) .card-img-top,.card-group>.card:not(:last-child) .card-header{border-top-right-radius:0}.card-group>.card:not(:last-child) .card-img-bottom,.card-group>.card:not(:last-child) .card-footer{border-bottom-right-radius:0}.card-group>.card:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:not(:first-child) .card-img-top,.card-group>.card:not(:first-child) .card-header{border-top-left-radius:0}.card-group>.card:not(:first-child) .card-img-bottom,.card-group>.card:not(:first-child) .card-footer{border-bottom-left-radius:0}}.card{box-shadow:var(--t42-shadow);backdrop-filter:var(--backdrop-filter)}.card .card-header{border-bottom-width:0}.card .card-subtitle{margin-bottom:0.5rem;font-size:83.3%}.card.bg-primary{background-color:transparent !important}.card.bg-primary .card-header{background-color:Rgba(var(--t42-bg-mid), 0.75)}.card.bg-primary .card-body{background-color:Rgba(var(--t42-bg-light), 0.75)}.card.bg-secondary{background-color:transparent !important}.card.bg-secondary .card-header{background-color:Rgba(var(--t42-bg-light), 0.75)}.card.bg-secondary .card-body{background-color:Rgba(var(--t42-bg-mid), 0.75)}.card:not(.bg-primary):not(.bg-secondary) .card-header+.card-body{padding-top:0}.card-header-tabs{margin-bottom:0}.accordion .card:first-of-type,.accordion .card:not(:first-of-type):not(:last-of-type){margin-bottom:0.5rem;border-bottom:var(--t42-border)}.accordion .card-header{position:relative;padding:0}.accordion .card-header .btn-link{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;width:100%;padding:0.75rem 2rem;line-height:1.4;text-align:left}.accordion .card-header .btn-link::before{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:transform;position:absolute;display:inline-block;width:0.75rem;height:0.75rem;background-color:var(--t42-content-color);transform:translateX(-1rem) translateY(0.063rem) rotate(-90deg);content:"";-webkit-mask-image:var(--t42-select-indicator)}.accordion .card-header .btn-link:hover{backdrop-filter:none}.accordion .card-header .btn-link.collapsed::before{transform:translateX(-1rem) translateY(0.063rem)}.accordion .card-header .btn-link.disabled::before,.accordion .card-header .btn-link:disabled::before{opacity:.35}.accordion .card-body{padding:0 1.25rem 1.25rem}.accordion .bg-primary .card-body,.accordion .bg-secondary .card-body{padding:1.25rem}.dropup,.dropend,.dropdown,.dropstart{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:0;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{position:absolute;z-index:1000;display:none;min-width:10rem;padding:0 0;margin:0;font-size:.75rem;color:var(--t42-content-color);text-align:left;list-style:none;background-color:Rgba(var(--t42-bg-light), 0.75);background-clip:padding-box;border:1px solid var(--t42-color-opacity-10);border-radius:0}.dropdown-menu[data-bs-popper]{top:100%;left:0;margin-top:.125rem}.dropdown-menu-start{--bs-position: start}.dropdown-menu-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-end{--bs-position: end}.dropdown-menu-end[data-bs-popper]{right:0;left:auto}@media (min-width: 576px){.dropdown-menu-sm-start{--bs-position: start}.dropdown-menu-sm-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-sm-end{--bs-position: end}.dropdown-menu-sm-end[data-bs-popper]{right:0;left:auto}}@media (min-width: 768px){.dropdown-menu-md-start{--bs-position: start}.dropdown-menu-md-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-md-end{--bs-position: end}.dropdown-menu-md-end[data-bs-popper]{right:0;left:auto}}@media (min-width: 992px){.dropdown-menu-lg-start{--bs-position: start}.dropdown-menu-lg-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-lg-end{--bs-position: end}.dropdown-menu-lg-end[data-bs-popper]{right:0;left:auto}}@media (min-width: 1200px){.dropdown-menu-xl-start{--bs-position: start}.dropdown-menu-xl-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-xl-end{--bs-position: end}.dropdown-menu-xl-end[data-bs-popper]{right:0;left:auto}}@media (min-width: 1400px){.dropdown-menu-xxl-start{--bs-position: start}.dropdown-menu-xxl-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-xxl-end{--bs-position: end}.dropdown-menu-xxl-end[data-bs-popper]{right:0;left:auto}}.dropup .dropdown-menu[data-bs-popper]{top:auto;bottom:100%;margin-top:0;margin-bottom:.125rem}.dropup .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:0;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropend .dropdown-menu[data-bs-popper]{top:0;right:auto;left:100%;margin-top:0;margin-left:.125rem}.dropend .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:0;content:"";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid}.dropend .dropdown-toggle:empty::after{margin-left:0}.dropend .dropdown-toggle::after{vertical-align:0}.dropstart .dropdown-menu[data-bs-popper]{top:0;right:100%;left:auto;margin-top:0;margin-right:.125rem}.dropstart .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:0;content:""}.dropstart .dropdown-toggle::after{display:none}.dropstart .dropdown-toggle::before{display:inline-block;margin-right:.255em;vertical-align:0;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropstart .dropdown-toggle:empty::after{margin-left:0}.dropstart .dropdown-toggle::before{vertical-align:0}.dropdown-divider{height:0;margin:0 0;overflow:hidden;border-top:1px solid var(--t42-color-opacity-10)}.dropdown-item{display:block;width:100%;padding:.375rem 1rem;clear:both;font-weight:400;color:var(--t42-content-color);text-align:inherit;text-decoration:none;white-space:nowrap;background-color:transparent;border:0}.dropdown-item:first-child{border-top-left-radius:0;border-top-right-radius:0}.dropdown-item:last-child{border-bottom-right-radius:0;border-bottom-left-radius:0}.dropdown-item:hover,.dropdown-item:focus{color:var(--t42-link-hover-color);background-color:var(--t42-link-hover-bg)}.dropdown-item.active,.dropdown-item:active{color:var(--t42-link-hover-color);text-decoration:none;background-color:var(--t42-link-active-bg)}.dropdown-item.disabled,.dropdown-item:disabled{color:#adb5bd;pointer-events:none;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:0 1rem;margin-bottom:0;font-size:.65625rem;color:shade-color(#616161, 10%);white-space:nowrap}.dropdown-item-text{display:block;padding:.375rem 1rem;color:var(--t42-content-color)}.dropdown-menu-dark{color:#dee2e6;background-color:#343a40;border-color:var(--t42-color-opacity-10)}.dropdown-menu-dark .dropdown-item{color:#dee2e6}.dropdown-menu-dark .dropdown-item:hover,.dropdown-menu-dark .dropdown-item:focus{color:#fff;background-color:rgba(255,255,255,0.15)}.dropdown-menu-dark .dropdown-item.active,.dropdown-menu-dark .dropdown-item:active{color:var(--t42-link-hover-color);background-color:var(--t42-link-active-bg)}.dropdown-menu-dark .dropdown-item.disabled,.dropdown-menu-dark .dropdown-item:disabled{color:#adb5bd}.dropdown-menu-dark .dropdown-divider{border-color:var(--t42-color-opacity-10)}.dropdown-menu-dark .dropdown-item-text{color:#dee2e6}.dropdown-menu-dark .dropdown-header{color:#adb5bd}.dropdown-menu{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:opacity, visability;display:block;visibility:hidden;opacity:0;backdrop-filter:var(--backdrop-filter)}.dropdown-menu.show{visibility:visible;opacity:1}.dropdown-toggle::after{position:relative;width:0.5rem;height:0.5rem;border:0;background-color:var(--t42-link-color);content:"";-webkit-mask-image:url("data:image/svg+xml,%3Csvg version=%271.1%27 xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M480.768 186.88l-211.968 211.456q-5.12 5.632-12.8 5.632t-12.8-5.632l-211.968-211.456q-5.632-5.632-5.632-13.312t5.632-12.8l47.616-47.104q5.12-5.632 12.8-5.632t12.8 5.632l151.552 151.552 151.552-151.552q5.632-5.632 12.8-5.632t13.312 5.632l47.104 47.104q5.632 5.632 5.632 12.8t-5.632 13.312z%27%3E%3C/path%3E%3C/svg%3E")}.dropdown-toggle.show::after{color:var(--white)}.dropup .dropdown-toggle::after{position:relative;top:0.188rem;width:0.5rem;height:0.5rem;border:0;background-color:var(--t42-link-color);content:"";-webkit-mask-image:url("data:image/svg+xml,%3Csvg version=%271.1%27 xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M480.768 351.488l-47.104 47.104q-5.632 5.12-13.312 5.12t-12.8-5.12l-151.552-152.064-151.552 152.064q-5.632 5.12-12.8 5.12t-12.8-5.12l-47.616-47.104q-5.632-5.632-5.632-13.312t5.632-12.8l211.968-211.968q5.632-5.12 12.8-5.12t12.8 5.12l211.968 211.968q5.632 5.632 5.632 12.8t-5.632 13.312z%27%3E%3C/path%3E%3C/svg%3E%0A")}.form-label{margin-bottom:.5rem}.col-form-label{padding-top:1px;padding-bottom:1px;margin-bottom:0;font-size:inherit;line-height:1.875rem}.col-form-label-lg{padding-top:1px;padding-bottom:1px;font-size:.75rem}.col-form-label-sm{padding-top:1px;padding-bottom:1px;font-size:.75rem}.form-text{margin-top:.25rem;font-size:.875em;color:var(--t42-content-color-muted)}.form-control{display:block;width:100%;padding:0 .875rem;font-size:.75rem;font-weight:400;line-height:1.875rem;color:var(--t42-link-color);background-color:var(--t42-input-bg);background-clip:padding-box;border:1px solid var(--t42-color-opacity-10);appearance:none;border-radius:0;transition:border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.form-control{transition:none}}.form-control[type="file"]{overflow:hidden}.form-control[type="file"]:not(:disabled):not([readonly]){cursor:pointer}.form-control:focus{color:var(--t42-link-color);background-color:var(--t42-input-bg);border-color:#007be5;outline:0;box-shadow:0 0 0 0 rgba(0,123,229,0.25)}.form-control::-webkit-date-and-time-value{height:1.875rem}.form-control::placeholder{color:var(--t42-content-color-muted);opacity:1}.form-control:disabled,.form-control[readonly]{background-color:var(--t42-input-disabled-bg);opacity:1}.form-control::file-selector-button{padding:0 .875rem;margin:0 -.875rem;margin-inline-end:.875rem;color:var(--t42-link-color);background-color:#e9ecef;pointer-events:none;border-color:inherit;border-style:solid;border-width:0;border-inline-end-width:1px;border-radius:0;transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.form-control::file-selector-button{transition:none}}.form-control:hover:not(:disabled):not([readonly])::file-selector-button{background-color:#dde0e3}.form-control::-webkit-file-upload-button{padding:0 .875rem;margin:0 -.875rem;margin-inline-end:.875rem;color:var(--t42-link-color);background-color:#e9ecef;pointer-events:none;border-color:inherit;border-style:solid;border-width:0;border-inline-end-width:1px;border-radius:0;transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.form-control::-webkit-file-upload-button{transition:none}}.form-control:hover:not(:disabled):not([readonly])::-webkit-file-upload-button{background-color:#dde0e3}.form-control-plaintext{display:block;width:100%;padding:0 0;margin-bottom:0;line-height:1.875rem;color:var(--t42-content-color);background-color:transparent;border:solid transparent;border-width:1px 0}.form-control-plaintext.form-control-sm,.form-control-plaintext.form-control-lg{padding-right:0;padding-left:0}.form-control-sm{min-height:2rem;padding:0 .875rem;font-size:.75rem;border-radius:0}.form-control-sm::file-selector-button{padding:0 .875rem;margin:0 -.875rem;margin-inline-end:.875rem}.form-control-sm::-webkit-file-upload-button{padding:0 .875rem;margin:0 -.875rem;margin-inline-end:.875rem}.form-control-lg{min-height:2rem;padding:0 .875rem;font-size:.75rem;border-radius:0}.form-control-lg::file-selector-button{padding:0 .875rem;margin:0 -.875rem;margin-inline-end:.875rem}.form-control-lg::-webkit-file-upload-button{padding:0 .875rem;margin:0 -.875rem;margin-inline-end:.875rem}textarea.form-control{min-height:2rem}textarea.form-control-sm{min-height:2rem}textarea.form-control-lg{min-height:2rem}.form-control-color{width:3rem;height:auto;padding:0}.form-control-color:not(:disabled):not([readonly]){cursor:pointer}.form-control-color::-moz-color-swatch{height:1.875rem;border-radius:0}.form-control-color::-webkit-color-swatch{height:1.875rem;border-radius:0}.form-select{display:block;width:100%;padding:0 2.625rem 0 .875rem;-moz-padding-start:calc(.875rem - 3px);font-size:.75rem;font-weight:400;line-height:1.875rem;color:var(--t42-link-color);background-color:var(--t42-input-bg);background-image:var(--t42-select-indicator);background-repeat:no-repeat;background-position:right 0.5rem center;background-size:1rem;border:1px solid var(--t42-color-opacity-10);border-radius:0;transition:border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out;appearance:none}@media (prefers-reduced-motion: reduce){.form-select{transition:none}}.form-select:focus{border-color:#007be5;outline:0;box-shadow:0 0 0 0 rgba(0,123,229,0.25)}.form-select[multiple],.form-select[size]:not([size="1"]){padding-right:.875rem;background-image:none}.form-select:disabled{background-color:#e9ecef}.form-select:-moz-focusring{color:transparent;text-shadow:0 0 0 var(--t42-link-color)}.form-select-sm{padding-top:0;padding-bottom:0;padding-left:.875rem;font-size:.75rem;border-radius:0}.form-select-lg{padding-top:0;padding-bottom:0;padding-left:.875rem;font-size:.75rem;border-radius:0}.form-check{display:block;min-height:1.125rem;padding-left:1.25rem;margin-bottom:0}.form-check .form-check-input{float:left;margin-left:-1.25rem}.form-check-input{width:1em;height:1em;margin-top:.25em;vertical-align:top;background-color:var(--t42-input-bg);background-repeat:no-repeat;background-position:center;background-size:contain;border:1px solid rgba(0,0,0,0.25);appearance:none;color-adjust:exact}.form-check-input[type="checkbox"]{border-radius:.25em}.form-check-input[type="radio"]{border-radius:50%}.form-check-input:active{filter:brightness(90%)}.form-check-input:focus{border-color:#007be5;outline:0;box-shadow:0 0 0 0 rgba(0,123,229,0.25)}.form-check-input:checked{background-color:#007be5;border-color:#007be5}.form-check-input:checked[type="checkbox"]{background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 20 20%27%3e%3cpath fill=%27none%27 stroke=%27%23fff%27 stroke-linecap=%27round%27 stroke-linejoin=%27round%27 stroke-width=%273%27 d=%27M6 10l3 3l6-6%27/%3e%3c/svg%3e")}.form-check-input:checked[type="radio"]{background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%27-4 -4 8 8%27%3e%3ccircle r=%272%27 fill=%27%23fff%27/%3e%3c/svg%3e")}.form-check-input[type="checkbox"]:indeterminate{background-color:#007be5;border-color:#007be5;background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 20 20%27%3e%3cpath fill=%27none%27 stroke=%27%23fff%27 stroke-linecap=%27round%27 stroke-linejoin=%27round%27 stroke-width=%273%27 d=%27M6 10h8%27/%3e%3c/svg%3e")}.form-check-input:disabled{pointer-events:none;filter:none;opacity:.5}.form-check-input[disabled] ~ .form-check-label,.form-check-input:disabled ~ .form-check-label{opacity:.5}.form-switch{padding-left:2.5em}.form-switch .form-check-input{width:2em;margin-left:-2.5em;background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%27-4 -4 8 8%27%3e%3ccircle r=%273%27 fill=%27rgba%280,0,0,0.25%29%27/%3e%3c/svg%3e");background-position:left center;border-radius:2em;transition:background-position 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.form-switch .form-check-input{transition:none}}.form-switch .form-check-input:focus{background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%27-4 -4 8 8%27%3e%3ccircle r=%273%27 fill=%27%23007be5%27/%3e%3c/svg%3e")}.form-switch .form-check-input:checked{background-position:right center;background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%27-4 -4 8 8%27%3e%3ccircle r=%273%27 fill=%27%23fff%27/%3e%3c/svg%3e")}.form-check-inline{display:inline-block;margin-right:1rem}.btn-check{position:absolute;clip:rect(0, 0, 0, 0);pointer-events:none}.btn-check[disabled]+.btn,.btn-check:disabled+.btn{pointer-events:none;filter:none;opacity:.35}.form-range{width:100%;height:1rem;padding:0;background-color:transparent;appearance:none}.form-range:focus{outline:0}.form-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 0 rgba(0,123,229,0.25)}.form-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 0 rgba(0,123,229,0.25)}.form-range::-moz-focus-outer{border:0}.form-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-.25rem;background-color:#007be5;border:0;border-radius:1rem;transition:background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out;appearance:none}@media (prefers-reduced-motion: reduce){.form-range::-webkit-slider-thumb{transition:none}}.form-range::-webkit-slider-thumb:active{background-color:#b3d7f7}.form-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.form-range::-moz-range-thumb{width:1rem;height:1rem;background-color:#007be5;border:0;border-radius:1rem;transition:background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out;appearance:none}@media (prefers-reduced-motion: reduce){.form-range::-moz-range-thumb{transition:none}}.form-range::-moz-range-thumb:active{background-color:#b3d7f7}.form-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.form-range:disabled{pointer-events:none}.form-range:disabled::-webkit-slider-thumb{background-color:#adb5bd}.form-range:disabled::-moz-range-thumb{background-color:#adb5bd}.form-floating{position:relative}.form-floating>.form-control,.form-floating>.form-select{height:calc(3.5rem + 2px);line-height:1.25}.form-floating>label{position:absolute;top:0;left:0;height:100%;padding:1rem .875rem;pointer-events:none;border:1px solid transparent;transform-origin:0 0;transition:opacity 0.1s ease-in-out,transform 0.1s ease-in-out}@media (prefers-reduced-motion: reduce){.form-floating>label{transition:none}}.form-floating>.form-control{padding:1rem .875rem}.form-floating>.form-control::placeholder{color:transparent}.form-floating>.form-control:focus,.form-floating>.form-control:not(:placeholder-shown){padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control:-webkit-autofill{padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-select{padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control:focus ~ label,.form-floating>.form-control:not(:placeholder-shown) ~ label,.form-floating>.form-select ~ label{opacity:.65;transform:scale(0.85) translateY(-0.5rem) translateX(0.15rem)}.form-floating>.form-control:-webkit-autofill ~ label{opacity:.65;transform:scale(0.85) translateY(-0.5rem) translateX(0.15rem)}.input-group{position:relative;display:flex;flex-wrap:wrap;align-items:stretch;width:100%}.input-group>.form-control,.input-group>.form-select{position:relative;flex:1 1 auto;width:1%;min-width:0}.input-group>.form-control:focus,.input-group>.form-select:focus{z-index:3}.input-group .btn{position:relative;z-index:2}.input-group .btn:focus{z-index:3}.input-group-text{display:flex;align-items:center;padding:0 .875rem;font-size:.75rem;font-weight:400;line-height:1.875rem;color:var(--t42-content-color);text-align:center;white-space:nowrap;background-color:#e9ecef;border:1px solid var(--t42-color-opacity-10);border-radius:0}.input-group-lg>.form-control,.input-group-lg>.form-select,.input-group-lg>.input-group-text,.input-group-lg>.btn{padding:0 .875rem;font-size:.75rem;border-radius:0}.input-group-sm>.form-control,.input-group-sm>.form-select,.input-group-sm>.input-group-text,.input-group-sm>.btn{padding:0 .875rem;font-size:.75rem;border-radius:0}.input-group-lg>.form-select,.input-group-sm>.form-select{padding-right:3.5rem}.input-group:not(.has-validation)>:not(:last-child):not(.dropdown-toggle):not(.dropdown-menu),.input-group:not(.has-validation)>.dropdown-toggle:nth-last-child(n+3){border-top-right-radius:0;border-bottom-right-radius:0}.input-group.has-validation>:nth-last-child(n+3):not(.dropdown-toggle):not(.dropdown-menu),.input-group.has-validation>.dropdown-toggle:nth-last-child(n+4){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>:not(:first-child):not(.dropdown-menu):not(.valid-tooltip):not(.valid-feedback):not(.invalid-tooltip):not(.invalid-feedback){margin-left:-1px;border-top-left-radius:0;border-bottom-left-radius:0}.valid-feedback{display:none;width:100%;margin-top:.5rem;font-size:.7rem;color:#43a047}.valid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem 1rem;margin-top:.1rem;font-size:.65625rem;color:#000;background-color:#43a047;border-radius:0}.was-validated :valid ~ .valid-feedback,.was-validated :valid ~ .valid-tooltip,.is-valid ~ .valid-feedback,.is-valid ~ .valid-tooltip{display:block}.was-validated .form-control:valid,.form-control.is-valid{border-color:#43a047;padding-right:2rem;background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 8 8%27%3e%3cpath fill=%27%2343a047%27 d=%27M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z%27/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right .5rem center;background-size:1rem 1rem}.was-validated .form-control:valid:focus,.form-control.is-valid:focus{border-color:#43a047;box-shadow:0 0 0 0 rgba(67,160,71,0.25)}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{padding-right:2rem;background-position:top .5rem right .5rem}.was-validated .form-select:valid,.form-select.is-valid{border-color:#43a047}.was-validated .form-select:valid:not([multiple]):not([size]),.was-validated .form-select:valid:not([multiple])[size="1"],.form-select.is-valid:not([multiple]):not([size]),.form-select.is-valid:not([multiple])[size="1"]{padding-right:3.5rem;background-image:var(--t42-select-indicator),url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 8 8%27%3e%3cpath fill=%27%2343a047%27 d=%27M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z%27/%3e%3c/svg%3e");background-position:right 0.5rem center,right 1.75rem center;background-size:1rem,1rem}.was-validated .form-select:valid:focus,.form-select.is-valid:focus{border-color:#43a047;box-shadow:0 0 0 0 rgba(67,160,71,0.25)}.was-validated .form-check-input:valid,.form-check-input.is-valid{border-color:#43a047}.was-validated .form-check-input:valid:checked,.form-check-input.is-valid:checked{background-color:#43a047}.was-validated .form-check-input:valid:focus,.form-check-input.is-valid:focus{box-shadow:0 0 0 0 rgba(67,160,71,0.25)}.was-validated .form-check-input:valid ~ .form-check-label,.form-check-input.is-valid ~ .form-check-label{color:#43a047}.form-check-inline .form-check-input ~ .valid-feedback{margin-left:.5em}.was-validated .input-group .form-control:valid,.input-group .form-control.is-valid,.was-validated .input-group .form-select:valid,.input-group .form-select.is-valid{z-index:1}.was-validated .input-group .form-control:valid:focus,.input-group .form-control.is-valid:focus,.was-validated .input-group .form-select:valid:focus,.input-group .form-select.is-valid:focus{z-index:3}.invalid-feedback{display:none;width:100%;margin-top:.5rem;font-size:.7rem;color:#ff511f}.invalid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem 1rem;margin-top:.1rem;font-size:.65625rem;color:#000;background-color:#ff511f;border-radius:0}.was-validated :invalid ~ .invalid-feedback,.was-validated :invalid ~ .invalid-tooltip,.is-invalid ~ .invalid-feedback,.is-invalid ~ .invalid-tooltip{display:block}.was-validated .form-control:invalid,.form-control.is-invalid{border-color:#ff511f;padding-right:2rem;background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 12 12%27 width=%2712%27 height=%2712%27 fill=%27none%27 stroke=%27%23ff511f%27%3e%3ccircle cx=%276%27 cy=%276%27 r=%274.5%27/%3e%3cpath stroke-linejoin=%27round%27 d=%27M5.8 3.6h.4L6 6.5z%27/%3e%3ccircle cx=%276%27 cy=%278.2%27 r=%27.6%27 fill=%27%23ff511f%27 stroke=%27none%27/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right .5rem center;background-size:1rem 1rem}.was-validated .form-control:invalid:focus,.form-control.is-invalid:focus{border-color:#ff511f;box-shadow:0 0 0 0 rgba(255,81,31,0.25)}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{padding-right:2rem;background-position:top .5rem right .5rem}.was-validated .form-select:invalid,.form-select.is-invalid{border-color:#ff511f}.was-validated .form-select:invalid:not([multiple]):not([size]),.was-validated .form-select:invalid:not([multiple])[size="1"],.form-select.is-invalid:not([multiple]):not([size]),.form-select.is-invalid:not([multiple])[size="1"]{padding-right:3.5rem;background-image:var(--t42-select-indicator),url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 12 12%27 width=%2712%27 height=%2712%27 fill=%27none%27 stroke=%27%23ff511f%27%3e%3ccircle cx=%276%27 cy=%276%27 r=%274.5%27/%3e%3cpath stroke-linejoin=%27round%27 d=%27M5.8 3.6h.4L6 6.5z%27/%3e%3ccircle cx=%276%27 cy=%278.2%27 r=%27.6%27 fill=%27%23ff511f%27 stroke=%27none%27/%3e%3c/svg%3e");background-position:right 0.5rem center,right 1.75rem center;background-size:1rem,1rem}.was-validated .form-select:invalid:focus,.form-select.is-invalid:focus{border-color:#ff511f;box-shadow:0 0 0 0 rgba(255,81,31,0.25)}.was-validated .form-check-input:invalid,.form-check-input.is-invalid{border-color:#ff511f}.was-validated .form-check-input:invalid:checked,.form-check-input.is-invalid:checked{background-color:#ff511f}.was-validated .form-check-input:invalid:focus,.form-check-input.is-invalid:focus{box-shadow:0 0 0 0 rgba(255,81,31,0.25)}.was-validated .form-check-input:invalid ~ .form-check-label,.form-check-input.is-invalid ~ .form-check-label{color:#ff511f}.form-check-inline .form-check-input ~ .invalid-feedback{margin-left:.5em}.was-validated .input-group .form-control:invalid,.input-group .form-control.is-invalid,.was-validated .input-group .form-select:invalid,.input-group .form-select.is-invalid{z-index:2}.was-validated .input-group .form-control:invalid:focus,.input-group .form-control.is-invalid:focus,.was-validated .input-group .form-select:invalid:focus,.input-group .form-select.is-invalid:focus{z-index:3}input{background-color:var(--t42-input-bg)}input[type="number"]::-webkit-calendar-picker-indicator,input[type="datetime-local"]::-webkit-calendar-picker-indicator,input[type="month"]::-webkit-calendar-picker-indicator,input[type="week"]::-webkit-calendar-picker-indicator,input[type="time"]::-webkit-calendar-picker-indicator,input[type="date"]::-webkit-calendar-picker-indicator{background:transparent}input[type="number"]::-webkit-inner-spin-button,input[type="datetime-local"]::-webkit-inner-spin-button,input[type="month"]::-webkit-inner-spin-button,input[type="week"]::-webkit-inner-spin-button,input[type="time"]::-webkit-inner-spin-button,input[type="date"]::-webkit-inner-spin-button{appearance:none}input[type="color"],input[type="range"]{padding:0;border:0}form div[class^="col"]{position:relative}.form-check-label input[type="checkbox"],.form-check-label input[type="radio"]{margin-top:0.125rem;margin-left:-1.2rem;opacity:1}.form-check .form-check-input:disabled{opacity:0}.form-check-label{margin-bottom:0}.form-check-inline .form-check-label{padding-left:0.25rem}.form-check-inline input[type="radio"]:checked+label::after{left:-1rem}.form-control{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border;background-color:transparent}.form-control:disabled,.form-control.disabled,.form-control[readonly]{cursor:default;opacity:0.65}.form-control.is-valid,.form-control.is-invalid{border-color:var(--t42-color-opacity-10)}.form-control.is-valid:focus,.form-control.is-invalid:focus{border-color:var(--primary);box-shadow:none}.form-control[type="file"]{opacity:0}.form-text{color:var(--secondary)}.form-control-plaintext:focus{outline:0}select{background-image:var(--t42-select-indicator);background-repeat:no-repeat;background-position:right 0.5rem center;background-size:1rem;cursor:pointer;appearance:none}select[multiple]{padding:0;background-image:none}select[multiple] option{padding:0 0.875rem}select[multiple] option:checked{background-color:var(--primary)}select:disabled{border-color:transparent;cursor:default;opacity:0.65}textarea,textarea.form-control{min-height:90px;max-height:180px;padding-top:5px;padding-bottom:5px}textarea:disabled,textarea.form-control:disabled{border-color:transparent}input[type="range"]{width:100%;appearance:none}input[type="range"]:focus{background-color:transparent;outline:none}input[type="range"]:focus::-ms-fill-lower,input[type="range"]:focus::-ms-fill-upper{background:var(--primary)}input[type="range"]::-webkit-slider-runnable-track{width:100%;height:0.0625rem;border:0;border-radius:0;background:var(--t42-color-opacity-10);box-shadow:none;cursor:pointer}input[type="range"]::-webkit-slider-thumb{width:12px;height:12px;margin-top:-5px;border:0;border-radius:50%;background:var(--primary);box-shadow:none;cursor:pointer;appearance:none}input[type="range"]:focus::-webkit-slider-runnable-track{background:var(--t42-color-opacity-10)}input[type="range"]::-moz-range-track{width:100%;height:2px;border:0;border-radius:0;background:var(--t42-color-opacity-10);box-shadow:none;cursor:pointer}input[type="range"]::-moz-range-thumb{width:12px;height:12px;border:0;border-radius:50px;background:var(--primary);box-shadow:none;cursor:pointer}input[type="range"]::-ms-track{width:100%;height:2px;border-color:transparent;color:transparent;background:transparent;cursor:pointer}input[type="range"]::-ms-fill-lower,input[type="range"]::-ms-fill-upper{border:0;border-radius:0;background:var(--primary);box-shadow:none}input[type="range"]::-ms-thumb{width:12px;height:12px;border:0;border-radius:50px;background:var(--primary);box-shadow:none;cursor:pointer}input[type="checkbox"]{opacity:0}input[type="checkbox"]+label{position:relative;color:var(--t42-content-color-muted);cursor:pointer;user-select:none}input[type="checkbox"]+label::before{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, border-color;position:absolute;top:0.0625rem;left:-1.25rem;display:block;width:0.875rem;height:0.875rem;border:0.0625rem solid var(--t42-content-color-muted);border-radius:0;cursor:pointer;content:"";pointer-events:all}input[type="checkbox"]+label::after{position:absolute;top:0.125rem;left:-1.188rem;display:block;width:0.875rem;height:0.875rem;background-image:none;content:"";-webkit-mask-size:0.75rem;-webkit-mask-repeat:no-repeat;content:""}input[type="checkbox"].indeterminate+label::before,input[type="checkbox"]:indeterminate+label::before{border-color:var(--t42-color-opacity-30);background-color:var(--primary)}input[type="checkbox"].indeterminate+label::after,input[type="checkbox"]:indeterminate+label::after{top:0.375rem;left:-1.063rem;width:0.5rem;height:0.188rem;background-color:var(--white)}input[type="checkbox"]:disabled+label,input[type="checkbox"]:disabled+.form-check-label{color:var(--t42-content-color-disabled)}input[type="checkbox"]:checked.disabled+label,input[type="checkbox"]:checked:disabled+label,input[type="checkbox"]:indeterminate.disabled+label,input[type="checkbox"]:indeterminate:disabled+label,input[type="checkbox"].disabled+label,input[type="checkbox"]:disabled+label{color:var(--t42-content-color-disabled)}input[type="checkbox"]:checked.disabled+label::before,input[type="checkbox"]:checked:disabled+label::before,input[type="checkbox"]:indeterminate.disabled+label::before,input[type="checkbox"]:indeterminate:disabled+label::before,input[type="checkbox"].disabled+label::before,input[type="checkbox"]:disabled+label::before{border-color:transparent;background-color:var(--t42-color-opacity-10)}input[type="checkbox"]:checked+label::before{border-color:var(--t42-color-opacity-30);background-color:var(--primary)}input[type="checkbox"]:checked+label::after{background-color:var(--t42-link-color);-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M212.48599,435.14899c-11.60532,0.00003-21.16266-4.77866-28.672-14.336l-92.16-120.832 c-5.46133-8.19202-7.50933-17.06665-6.144-26.62399s5.80267-17.408,13.312-23.552s16.21333-8.53334,26.112-7.168 c9.89867,1.36533,17.92,6.14401,24.064,14.336l60.416,78.84799L360.966,93.13298c5.46133-8.192,12.79999-13.312,22.01599-15.36 s18.26132-0.68267,27.13599,4.096c8.19199,5.46133,13.31198,12.8,15.35999,22.016s0.68265,18.26133-4.09601,27.136l-179.2,286.71997 c-6.82668,10.9227-16.384,16.384-28.672,16.384L212.48599,435.14899z%27/%3E%3C/svg%3E")}input[type="radio"]{opacity:0}input[type="radio"]+label{position:relative;color:var(--t42-content-color-muted);cursor:pointer;user-select:none}input[type="radio"]+label::before{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, border;position:absolute;top:0.0625rem;left:-1.25rem;display:block;width:0.875rem;height:0.875rem;border:0.0625rem solid var(--t42-content-color-muted);border-radius:50%;cursor:pointer;content:"";pointer-events:all}input[type="radio"]+label::after{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, border;position:absolute;top:0.313rem;left:-1rem;display:block;width:0.375rem;height:0.375rem;border-radius:50%;color:var(--white);background-image:none;transform:scale(0);opacity:0;content:""}input[type="radio"]+label:focus{border-color:var(--primary)}input[type="radio"]:disabled+label,input[type="radio"]:disabled+.form-check-label{color:var(--t42-content-color-disabled)}input[type="radio"]:checked.disabled+label,input[type="radio"]:checked:disabled+label,input[type="radio"].disabled+label,input[type="radio"]:disabled+label{color:var(--t42-content-color-disabled)}input[type="radio"]:checked.disabled+label::before,input[type="radio"]:checked:disabled+label::before,input[type="radio"].disabled+label::before,input[type="radio"]:disabled+label::before{border-color:transparent;background-color:var(--t42-color-opacity-10)}input[type="radio"]:checked+label::before{border-color:var(--t42-color-opacity-30);background-color:var(--primary)}input[type="radio"]:checked+label::after{background-color:var(--white);transform:scale(1);opacity:1}.custom-control{padding-left:1.25rem}.custom-control .custom-control-input:checked ~ .custom-control-label::before{border-color:var(--t42-color-opacity-30)}.custom-select,.form-select{max-height:2rem;background-color:transparent;background-image:var(--t42-select-indicator);background-repeat:no-repeat;background-position:right 0.5rem center;background-size:1rem}.custom-select:focus,.custom-select option,.form-select:focus,.form-select option{background-color:var(--t42-input-bg)}.custom-select:disabled option,.form-select:disabled option{background-color:transparent}.custom-radio .custom-control-label{color:var(--t42-content-color-muted);user-select:none}.custom-radio .custom-control-label::after{background:none}.custom-radio .custom-control-input:checked ~ .custom-control-label::after{background-image:none}.custom-checkbox .custom-control-label{color:var(--t42-content-color-muted);user-select:none}.custom-checkbox .custom-control-label::after{background:none}.custom-checkbox .custom-control-input:checked ~ .custom-control-label::after{background-image:none}.custom-checkbox .custom-control-input:disabled .custom-control-label::after,.custom-checkbox .custom-control-input:disabled:checked ~ .custom-control-label::after,.custom-checkbox .custom-control-input:disabled:indeterminate ~ .custom-control-label::after{opacity:0.4}.custom-checkbox .custom-control-input:disabled ~ .custom-control-label::before{border-color:transparent}.switch{position:relative;display:inline-block;align-items:center;height:0.875rem;margin-bottom:0;padding-left:2rem;cursor:pointer}.switch.disabled{color:var(--t42-content-color-disabled)}.switch .slider{position:absolute;top:0;right:0;bottom:0;left:0;width:1.75rem;border:1px solid var(--t42-content-color-muted);cursor:pointer;transition:0.4s}.switch .slider::before{position:absolute;bottom:0.125rem;left:0.125rem;width:0.5rem;height:0.5rem;background-color:var(--t42-content-color-muted);transition:0.4s;content:""}.switch input{width:0;height:0;opacity:0}.switch input:checked+.slider{border:var(--t42-border);background-color:var(--primary)}.switch input:checked+.slider::before{background-color:var(--white);transform:translateX(0.875rem)}.switch input:focus+.slider{box-shadow:0 0 1px #2196f3}.switch input:disabled+.slider{border:var(--t42-border);background-color:var(--t42-color-opacity-10)}.switch input:disabled+.slider::before{background-color:var(--t42-color-opacity-20)}.input-group-prepend .input-group-text{justify-content:center;border-right:0}.input-group-append .input-group-text{justify-content:center;border-left:0}.input-group-append .custom-control,.input-group-prepend .custom-control{margin-bottom:0;padding-left:0.875rem}.input-group-append .custom-control-label,.input-group-prepend .custom-control-label{position:absolute;left:0;min-width:0.875rem;min-height:0.875rem}.input-group-append .custom-control-label::before,.input-group-prepend .custom-control-label::before{left:0}.input-group-append .custom-control-label::after,.input-group-prepend .custom-control-label::after{left:0.25rem}.input-group-append .custom-checkbox .custom-control-label::after,.input-group-prepend .custom-checkbox .custom-control-label::after{left:0.125rem}.custom-file{margin-bottom:1rem}.custom-file-input,.form-control[type="file"]{z-index:1}.custom-file-input:focus ~ .custom-file-label,.form-control[type="file"]:focus ~ .custom-file-label{background-color:var(--t42-input-bg)}.custom-file-label,.input-group-text{background-color:transparent}.custom-file-label::after,.input-group-text::after{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color;background-color:Rgba(--secondary, 0.05);cursor:pointer}.custom-file-label:hover::after,.input-group-text:hover::after{color:var(--white);background-color:var(--secondary)}.form-control[type="file"]+.input-group-text{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color,color;position:absolute;top:0;right:0;left:0;z-index:1;height:2rem;padding:0.375rem 0.875rem;border:var(--t42-border);color:var(--t42-content-color-muted)}.form-control[type="file"]+.input-group-text::after{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color,color;position:absolute;top:0;right:0;bottom:0;z-index:3;display:block;height:100%;padding:0.375rem 0.875rem;border-left:inherit;color:var(--t42-link-color);line-height:1.5;cursor:pointer;content:"Browse"}.form-control[type="file"]+.input-group-text:hover{background-color:var(--t42-input-bg)}.form-control[type="file"]+.input-group-text:hover::after{color:var(--white);background-color:var(--secondary)}.custom-switch{padding-left:2rem}.custom-switch .custom-control-label::before{left:-2rem}.custom-switch .custom-control-label::after{top:0.25rem;left:-1.813rem;width:0.5rem;height:0.5rem}.custom-switch .custom-control-input:checked ~ .custom-control-label::after{background-color:var(--white);content:""}.custom-switch .custom-control-input:not(:disabled):active ~ .custom-control-label::before{border-color:var(--t42-color-opacity-30);background-color:var(--primary)}.valid-feedback,.valid-tooltip,.invalid-feedback,.invalid-tooltip,.warning-feedback,.warning-tooltip{position:absolute;bottom:-1rem;width:calc(100% - 1.875rem);margin-top:0;overflow:hidden;color:var(--t42-content-color);font-size:.7rem;white-space:nowrap;text-overflow:ellipsis}.valid-tooltip,.invalid-tooltip,.warning-tooltip{color:var(--t42-content-color-muted)}.custom-radio label+div,.custom-checkbox label+div,.form-check label+div{width:calc(100% + 1.25rem);transform:translateX(-1.25rem)}.form-group{margin-bottom:1rem}label{margin-bottom:0.5rem}.form-row{display:flex;flex-wrap:wrap;margin-right:-0.5rem;margin-left:-0.5rem}.form-row>.col,.form-row>[class*="col-"]{padding-right:0.5rem;padding-left:0.5rem}.form-inline{display:flex;flex-flow:row wrap;align-items:center}.form-inline .form-check{width:100%}@media (min-width: 576px){.form-inline label{display:flex;align-items:center;justify-content:center;margin-bottom:0}.form-inline .form-group{display:flex;flex:0 0 auto;flex-flow:row wrap;align-items:center;margin-bottom:0}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-plaintext{display:inline-block}.form-inline .input-group,.form-inline .custom-select,.form-inline .form-select{width:auto}.form-inline .form-check{display:flex;align-items:center;justify-content:center;width:auto;padding-left:0}.form-inline .form-check-input{position:relative;flex-shrink:0;margin-top:0;margin-left:0}.form-inline .custom-control{align-items:center;justify-content:center}.form-inline .custom-control-label{margin-bottom:0}}/*! + * Bootstrap Grid v5.1.3 (https://getbootstrap.com/) + * Copyright 2011-2021 The Bootstrap Authors + * Copyright 2011-2021 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) + */:root{--bs-blue: #007be5;--bs-indigo: #6610f2;--bs-purple: #6f42c1;--bs-pink: #fd397a;--bs-red: #ff511f;--bs-orange: #fd7e14;--bs-yellow: #f9a825;--bs-green: #43a047;--bs-teal: #616161;--bs-cyan: #469eb9;--bs-white: #fff;--bs-gray: #6c757d;--bs-gray-dark: #343a40;--bs-gray-100: #f8f9fa;--bs-gray-200: #e9ecef;--bs-gray-300: #dee2e6;--bs-gray-400: #ced4da;--bs-gray-500: #adb5bd;--bs-gray-600: #6c757d;--bs-gray-700: #495057;--bs-gray-800: #343a40;--bs-gray-900: #212529;--bs-primary: #007be5;--bs-secondary: #616161;--bs-success: #43a047;--bs-info: #469eb9;--bs-warning: #f9a825;--bs-danger: #ff511f;--bs-light: #616161;--bs-dark: #616161;--bs-primary-rgb: 0,123,229;--bs-secondary-rgb: 97,97,97;--bs-success-rgb: 67,160,71;--bs-info-rgb: 70,158,185;--bs-warning-rgb: 249,168,37;--bs-danger-rgb: 255,81,31;--bs-light-rgb: 97,97,97;--bs-dark-rgb: 97,97,97;--bs-white-rgb: 255,255,255;--bs-black-rgb: 0,0,0;--bs-body-color-rgb: 33,37,41;--bs-body-bg-rgb: 255,255,255;--bs-font-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--bs-gradient: linear-gradient(180deg, rgba(255,255,255,0.15), rgba(255,255,255,0));--bs-body-font-family: Montserrat,Helvetica Neue,Arial,sans-serif;--bs-body-font-size: .75rem;--bs-body-font-weight: 400;--bs-body-line-height: 1.5;--bs-body-color: #212529;--bs-body-bg: #fff}.container,.container-fluid,.container-sm,.container-md,.container-lg,.container-xl,.container-xxl{width:100%;padding-right:var(--bs-gutter-x, .75rem);padding-left:var(--bs-gutter-x, .75rem);margin-right:auto;margin-left:auto}@media (min-width: 576px){.container,.container-sm{max-width:540px}}@media (min-width: 768px){.container,.container-sm,.container-md{max-width:720px}}@media (min-width: 992px){.container,.container-sm,.container-md,.container-lg{max-width:960px}}@media (min-width: 1200px){.container,.container-sm,.container-md,.container-lg,.container-xl{max-width:1140px}}@media (min-width: 1400px){.container,.container-sm,.container-md,.container-lg,.container-xl,.container-xxl{max-width:1320px}}.row{--bs-gutter-x: 1.5rem;--bs-gutter-y: 0;display:flex;flex-wrap:wrap;margin-top:calc(-1 * var(--bs-gutter-y));margin-right:calc(-.5 * var(--bs-gutter-x));margin-left:calc(-.5 * var(--bs-gutter-x))}.row>*{box-sizing:border-box;flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--bs-gutter-x) * .5);padding-left:calc(var(--bs-gutter-x) * .5);margin-top:var(--bs-gutter-y)}.col{flex:1 0 0%}.row-cols-auto>*{flex:0 0 auto;width:auto}.row-cols-1>*{flex:0 0 auto;width:100%}.row-cols-2>*{flex:0 0 auto;width:50%}.row-cols-3>*{flex:0 0 auto;width:33.33333%}.row-cols-4>*{flex:0 0 auto;width:25%}.row-cols-5>*{flex:0 0 auto;width:20%}.row-cols-6>*{flex:0 0 auto;width:16.66667%}.col-auto{flex:0 0 auto;width:auto}.col-1{flex:0 0 auto;width:8.33333%}.col-2{flex:0 0 auto;width:16.66667%}.col-3{flex:0 0 auto;width:25%}.col-4{flex:0 0 auto;width:33.33333%}.col-5{flex:0 0 auto;width:41.66667%}.col-6{flex:0 0 auto;width:50%}.col-7{flex:0 0 auto;width:58.33333%}.col-8{flex:0 0 auto;width:66.66667%}.col-9{flex:0 0 auto;width:75%}.col-10{flex:0 0 auto;width:83.33333%}.col-11{flex:0 0 auto;width:91.66667%}.col-12{flex:0 0 auto;width:100%}.offset-1{margin-left:8.33333%}.offset-2{margin-left:16.66667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.33333%}.offset-5{margin-left:41.66667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.33333%}.offset-8{margin-left:66.66667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.33333%}.offset-11{margin-left:91.66667%}.g-0,.gx-0{--bs-gutter-x: 0}.g-0,.gy-0{--bs-gutter-y: 0}.g-1,.gx-1{--bs-gutter-x: .25rem}.g-1,.gy-1{--bs-gutter-y: .25rem}.g-2,.gx-2{--bs-gutter-x: .5rem}.g-2,.gy-2{--bs-gutter-y: .5rem}.g-3,.gx-3{--bs-gutter-x: 1rem}.g-3,.gy-3{--bs-gutter-y: 1rem}.g-4,.gx-4{--bs-gutter-x: 1.5rem}.g-4,.gy-4{--bs-gutter-y: 1.5rem}.g-5,.gx-5{--bs-gutter-x: 3rem}.g-5,.gy-5{--bs-gutter-y: 3rem}@media (min-width: 576px){.col-sm{flex:1 0 0%}.row-cols-sm-auto>*{flex:0 0 auto;width:auto}.row-cols-sm-1>*{flex:0 0 auto;width:100%}.row-cols-sm-2>*{flex:0 0 auto;width:50%}.row-cols-sm-3>*{flex:0 0 auto;width:33.33333%}.row-cols-sm-4>*{flex:0 0 auto;width:25%}.row-cols-sm-5>*{flex:0 0 auto;width:20%}.row-cols-sm-6>*{flex:0 0 auto;width:16.66667%}.col-sm-auto{flex:0 0 auto;width:auto}.col-sm-1{flex:0 0 auto;width:8.33333%}.col-sm-2{flex:0 0 auto;width:16.66667%}.col-sm-3{flex:0 0 auto;width:25%}.col-sm-4{flex:0 0 auto;width:33.33333%}.col-sm-5{flex:0 0 auto;width:41.66667%}.col-sm-6{flex:0 0 auto;width:50%}.col-sm-7{flex:0 0 auto;width:58.33333%}.col-sm-8{flex:0 0 auto;width:66.66667%}.col-sm-9{flex:0 0 auto;width:75%}.col-sm-10{flex:0 0 auto;width:83.33333%}.col-sm-11{flex:0 0 auto;width:91.66667%}.col-sm-12{flex:0 0 auto;width:100%}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.33333%}.offset-sm-2{margin-left:16.66667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.33333%}.offset-sm-5{margin-left:41.66667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.33333%}.offset-sm-8{margin-left:66.66667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.33333%}.offset-sm-11{margin-left:91.66667%}.g-sm-0,.gx-sm-0{--bs-gutter-x: 0}.g-sm-0,.gy-sm-0{--bs-gutter-y: 0}.g-sm-1,.gx-sm-1{--bs-gutter-x: .25rem}.g-sm-1,.gy-sm-1{--bs-gutter-y: .25rem}.g-sm-2,.gx-sm-2{--bs-gutter-x: .5rem}.g-sm-2,.gy-sm-2{--bs-gutter-y: .5rem}.g-sm-3,.gx-sm-3{--bs-gutter-x: 1rem}.g-sm-3,.gy-sm-3{--bs-gutter-y: 1rem}.g-sm-4,.gx-sm-4{--bs-gutter-x: 1.5rem}.g-sm-4,.gy-sm-4{--bs-gutter-y: 1.5rem}.g-sm-5,.gx-sm-5{--bs-gutter-x: 3rem}.g-sm-5,.gy-sm-5{--bs-gutter-y: 3rem}}@media (min-width: 768px){.col-md{flex:1 0 0%}.row-cols-md-auto>*{flex:0 0 auto;width:auto}.row-cols-md-1>*{flex:0 0 auto;width:100%}.row-cols-md-2>*{flex:0 0 auto;width:50%}.row-cols-md-3>*{flex:0 0 auto;width:33.33333%}.row-cols-md-4>*{flex:0 0 auto;width:25%}.row-cols-md-5>*{flex:0 0 auto;width:20%}.row-cols-md-6>*{flex:0 0 auto;width:16.66667%}.col-md-auto{flex:0 0 auto;width:auto}.col-md-1{flex:0 0 auto;width:8.33333%}.col-md-2{flex:0 0 auto;width:16.66667%}.col-md-3{flex:0 0 auto;width:25%}.col-md-4{flex:0 0 auto;width:33.33333%}.col-md-5{flex:0 0 auto;width:41.66667%}.col-md-6{flex:0 0 auto;width:50%}.col-md-7{flex:0 0 auto;width:58.33333%}.col-md-8{flex:0 0 auto;width:66.66667%}.col-md-9{flex:0 0 auto;width:75%}.col-md-10{flex:0 0 auto;width:83.33333%}.col-md-11{flex:0 0 auto;width:91.66667%}.col-md-12{flex:0 0 auto;width:100%}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.33333%}.offset-md-2{margin-left:16.66667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.33333%}.offset-md-5{margin-left:41.66667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.33333%}.offset-md-8{margin-left:66.66667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.33333%}.offset-md-11{margin-left:91.66667%}.g-md-0,.gx-md-0{--bs-gutter-x: 0}.g-md-0,.gy-md-0{--bs-gutter-y: 0}.g-md-1,.gx-md-1{--bs-gutter-x: .25rem}.g-md-1,.gy-md-1{--bs-gutter-y: .25rem}.g-md-2,.gx-md-2{--bs-gutter-x: .5rem}.g-md-2,.gy-md-2{--bs-gutter-y: .5rem}.g-md-3,.gx-md-3{--bs-gutter-x: 1rem}.g-md-3,.gy-md-3{--bs-gutter-y: 1rem}.g-md-4,.gx-md-4{--bs-gutter-x: 1.5rem}.g-md-4,.gy-md-4{--bs-gutter-y: 1.5rem}.g-md-5,.gx-md-5{--bs-gutter-x: 3rem}.g-md-5,.gy-md-5{--bs-gutter-y: 3rem}}@media (min-width: 992px){.col-lg{flex:1 0 0%}.row-cols-lg-auto>*{flex:0 0 auto;width:auto}.row-cols-lg-1>*{flex:0 0 auto;width:100%}.row-cols-lg-2>*{flex:0 0 auto;width:50%}.row-cols-lg-3>*{flex:0 0 auto;width:33.33333%}.row-cols-lg-4>*{flex:0 0 auto;width:25%}.row-cols-lg-5>*{flex:0 0 auto;width:20%}.row-cols-lg-6>*{flex:0 0 auto;width:16.66667%}.col-lg-auto{flex:0 0 auto;width:auto}.col-lg-1{flex:0 0 auto;width:8.33333%}.col-lg-2{flex:0 0 auto;width:16.66667%}.col-lg-3{flex:0 0 auto;width:25%}.col-lg-4{flex:0 0 auto;width:33.33333%}.col-lg-5{flex:0 0 auto;width:41.66667%}.col-lg-6{flex:0 0 auto;width:50%}.col-lg-7{flex:0 0 auto;width:58.33333%}.col-lg-8{flex:0 0 auto;width:66.66667%}.col-lg-9{flex:0 0 auto;width:75%}.col-lg-10{flex:0 0 auto;width:83.33333%}.col-lg-11{flex:0 0 auto;width:91.66667%}.col-lg-12{flex:0 0 auto;width:100%}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.33333%}.offset-lg-2{margin-left:16.66667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.33333%}.offset-lg-5{margin-left:41.66667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.33333%}.offset-lg-8{margin-left:66.66667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.33333%}.offset-lg-11{margin-left:91.66667%}.g-lg-0,.gx-lg-0{--bs-gutter-x: 0}.g-lg-0,.gy-lg-0{--bs-gutter-y: 0}.g-lg-1,.gx-lg-1{--bs-gutter-x: .25rem}.g-lg-1,.gy-lg-1{--bs-gutter-y: .25rem}.g-lg-2,.gx-lg-2{--bs-gutter-x: .5rem}.g-lg-2,.gy-lg-2{--bs-gutter-y: .5rem}.g-lg-3,.gx-lg-3{--bs-gutter-x: 1rem}.g-lg-3,.gy-lg-3{--bs-gutter-y: 1rem}.g-lg-4,.gx-lg-4{--bs-gutter-x: 1.5rem}.g-lg-4,.gy-lg-4{--bs-gutter-y: 1.5rem}.g-lg-5,.gx-lg-5{--bs-gutter-x: 3rem}.g-lg-5,.gy-lg-5{--bs-gutter-y: 3rem}}@media (min-width: 1200px){.col-xl{flex:1 0 0%}.row-cols-xl-auto>*{flex:0 0 auto;width:auto}.row-cols-xl-1>*{flex:0 0 auto;width:100%}.row-cols-xl-2>*{flex:0 0 auto;width:50%}.row-cols-xl-3>*{flex:0 0 auto;width:33.33333%}.row-cols-xl-4>*{flex:0 0 auto;width:25%}.row-cols-xl-5>*{flex:0 0 auto;width:20%}.row-cols-xl-6>*{flex:0 0 auto;width:16.66667%}.col-xl-auto{flex:0 0 auto;width:auto}.col-xl-1{flex:0 0 auto;width:8.33333%}.col-xl-2{flex:0 0 auto;width:16.66667%}.col-xl-3{flex:0 0 auto;width:25%}.col-xl-4{flex:0 0 auto;width:33.33333%}.col-xl-5{flex:0 0 auto;width:41.66667%}.col-xl-6{flex:0 0 auto;width:50%}.col-xl-7{flex:0 0 auto;width:58.33333%}.col-xl-8{flex:0 0 auto;width:66.66667%}.col-xl-9{flex:0 0 auto;width:75%}.col-xl-10{flex:0 0 auto;width:83.33333%}.col-xl-11{flex:0 0 auto;width:91.66667%}.col-xl-12{flex:0 0 auto;width:100%}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.33333%}.offset-xl-2{margin-left:16.66667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.33333%}.offset-xl-5{margin-left:41.66667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.33333%}.offset-xl-8{margin-left:66.66667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.33333%}.offset-xl-11{margin-left:91.66667%}.g-xl-0,.gx-xl-0{--bs-gutter-x: 0}.g-xl-0,.gy-xl-0{--bs-gutter-y: 0}.g-xl-1,.gx-xl-1{--bs-gutter-x: .25rem}.g-xl-1,.gy-xl-1{--bs-gutter-y: .25rem}.g-xl-2,.gx-xl-2{--bs-gutter-x: .5rem}.g-xl-2,.gy-xl-2{--bs-gutter-y: .5rem}.g-xl-3,.gx-xl-3{--bs-gutter-x: 1rem}.g-xl-3,.gy-xl-3{--bs-gutter-y: 1rem}.g-xl-4,.gx-xl-4{--bs-gutter-x: 1.5rem}.g-xl-4,.gy-xl-4{--bs-gutter-y: 1.5rem}.g-xl-5,.gx-xl-5{--bs-gutter-x: 3rem}.g-xl-5,.gy-xl-5{--bs-gutter-y: 3rem}}@media (min-width: 1400px){.col-xxl{flex:1 0 0%}.row-cols-xxl-auto>*{flex:0 0 auto;width:auto}.row-cols-xxl-1>*{flex:0 0 auto;width:100%}.row-cols-xxl-2>*{flex:0 0 auto;width:50%}.row-cols-xxl-3>*{flex:0 0 auto;width:33.33333%}.row-cols-xxl-4>*{flex:0 0 auto;width:25%}.row-cols-xxl-5>*{flex:0 0 auto;width:20%}.row-cols-xxl-6>*{flex:0 0 auto;width:16.66667%}.col-xxl-auto{flex:0 0 auto;width:auto}.col-xxl-1{flex:0 0 auto;width:8.33333%}.col-xxl-2{flex:0 0 auto;width:16.66667%}.col-xxl-3{flex:0 0 auto;width:25%}.col-xxl-4{flex:0 0 auto;width:33.33333%}.col-xxl-5{flex:0 0 auto;width:41.66667%}.col-xxl-6{flex:0 0 auto;width:50%}.col-xxl-7{flex:0 0 auto;width:58.33333%}.col-xxl-8{flex:0 0 auto;width:66.66667%}.col-xxl-9{flex:0 0 auto;width:75%}.col-xxl-10{flex:0 0 auto;width:83.33333%}.col-xxl-11{flex:0 0 auto;width:91.66667%}.col-xxl-12{flex:0 0 auto;width:100%}.offset-xxl-0{margin-left:0}.offset-xxl-1{margin-left:8.33333%}.offset-xxl-2{margin-left:16.66667%}.offset-xxl-3{margin-left:25%}.offset-xxl-4{margin-left:33.33333%}.offset-xxl-5{margin-left:41.66667%}.offset-xxl-6{margin-left:50%}.offset-xxl-7{margin-left:58.33333%}.offset-xxl-8{margin-left:66.66667%}.offset-xxl-9{margin-left:75%}.offset-xxl-10{margin-left:83.33333%}.offset-xxl-11{margin-left:91.66667%}.g-xxl-0,.gx-xxl-0{--bs-gutter-x: 0}.g-xxl-0,.gy-xxl-0{--bs-gutter-y: 0}.g-xxl-1,.gx-xxl-1{--bs-gutter-x: .25rem}.g-xxl-1,.gy-xxl-1{--bs-gutter-y: .25rem}.g-xxl-2,.gx-xxl-2{--bs-gutter-x: .5rem}.g-xxl-2,.gy-xxl-2{--bs-gutter-y: .5rem}.g-xxl-3,.gx-xxl-3{--bs-gutter-x: 1rem}.g-xxl-3,.gy-xxl-3{--bs-gutter-y: 1rem}.g-xxl-4,.gx-xxl-4{--bs-gutter-x: 1.5rem}.g-xxl-4,.gy-xxl-4{--bs-gutter-y: 1.5rem}.g-xxl-5,.gx-xxl-5{--bs-gutter-x: 3rem}.g-xxl-5,.gy-xxl-5{--bs-gutter-y: 3rem}}.d-inline{display:inline !important}.d-inline-block{display:inline-block !important}.d-block{display:block !important}.d-grid{display:grid !important}.d-table{display:table !important}.d-table-row{display:table-row !important}.d-table-cell{display:table-cell !important}.d-flex{display:flex !important}.d-inline-flex{display:inline-flex !important}.d-none{display:none !important}.flex-fill{flex:1 1 auto !important}.flex-row{flex-direction:row !important}.flex-column{flex-direction:column !important}.flex-row-reverse{flex-direction:row-reverse !important}.flex-column-reverse{flex-direction:column-reverse !important}.flex-grow-0{flex-grow:0 !important}.flex-grow-1{flex-grow:1 !important}.flex-shrink-0{flex-shrink:0 !important}.flex-shrink-1{flex-shrink:1 !important}.flex-wrap{flex-wrap:wrap !important}.flex-nowrap{flex-wrap:nowrap !important}.flex-wrap-reverse{flex-wrap:wrap-reverse !important}.justify-content-start{justify-content:flex-start !important}.justify-content-end{justify-content:flex-end !important}.justify-content-center{justify-content:center !important}.justify-content-between{justify-content:space-between !important}.justify-content-around{justify-content:space-around !important}.justify-content-evenly{justify-content:space-evenly !important}.align-items-start{align-items:flex-start !important}.align-items-end{align-items:flex-end !important}.align-items-center{align-items:center !important}.align-items-baseline{align-items:baseline !important}.align-items-stretch{align-items:stretch !important}.align-content-start{align-content:flex-start !important}.align-content-end{align-content:flex-end !important}.align-content-center{align-content:center !important}.align-content-between{align-content:space-between !important}.align-content-around{align-content:space-around !important}.align-content-stretch{align-content:stretch !important}.align-self-auto{align-self:auto !important}.align-self-start{align-self:flex-start !important}.align-self-end{align-self:flex-end !important}.align-self-center{align-self:center !important}.align-self-baseline{align-self:baseline !important}.align-self-stretch{align-self:stretch !important}.order-first{order:-1 !important}.order-0{order:0 !important}.order-1{order:1 !important}.order-2{order:2 !important}.order-3{order:3 !important}.order-4{order:4 !important}.order-5{order:5 !important}.order-last{order:6 !important}.m-0{margin:0 !important}.m-1{margin:.25rem !important}.m-2{margin:.5rem !important}.m-3{margin:1rem !important}.m-4{margin:1.5rem !important}.m-5{margin:3rem !important}.m-auto{margin:auto !important}.mx-0{margin-right:0 !important;margin-left:0 !important}.mx-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-3{margin-right:1rem !important;margin-left:1rem !important}.mx-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-5{margin-right:3rem !important;margin-left:3rem !important}.mx-auto{margin-right:auto !important;margin-left:auto !important}.my-0{margin-top:0 !important;margin-bottom:0 !important}.my-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-0{margin-top:0 !important}.mt-1{margin-top:.25rem !important}.mt-2{margin-top:.5rem !important}.mt-3{margin-top:1rem !important}.mt-4{margin-top:1.5rem !important}.mt-5{margin-top:3rem !important}.mt-auto{margin-top:auto !important}.me-0{margin-right:0 !important}.me-1{margin-right:.25rem !important}.me-2{margin-right:.5rem !important}.me-3{margin-right:1rem !important}.me-4{margin-right:1.5rem !important}.me-5{margin-right:3rem !important}.me-auto{margin-right:auto !important}.mb-0{margin-bottom:0 !important}.mb-1{margin-bottom:.25rem !important}.mb-2{margin-bottom:.5rem !important}.mb-3{margin-bottom:1rem !important}.mb-4{margin-bottom:1.5rem !important}.mb-5{margin-bottom:3rem !important}.mb-auto{margin-bottom:auto !important}.ms-0{margin-left:0 !important}.ms-1{margin-left:.25rem !important}.ms-2{margin-left:.5rem !important}.ms-3{margin-left:1rem !important}.ms-4{margin-left:1.5rem !important}.ms-5{margin-left:3rem !important}.ms-auto{margin-left:auto !important}.p-0{padding:0 !important}.p-1{padding:.25rem !important}.p-2{padding:.5rem !important}.p-3{padding:1rem !important}.p-4{padding:1.5rem !important}.p-5{padding:3rem !important}.px-0{padding-right:0 !important;padding-left:0 !important}.px-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-3{padding-right:1rem !important;padding-left:1rem !important}.px-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-5{padding-right:3rem !important;padding-left:3rem !important}.py-0{padding-top:0 !important;padding-bottom:0 !important}.py-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-0{padding-top:0 !important}.pt-1{padding-top:.25rem !important}.pt-2{padding-top:.5rem !important}.pt-3{padding-top:1rem !important}.pt-4{padding-top:1.5rem !important}.pt-5{padding-top:3rem !important}.pe-0{padding-right:0 !important}.pe-1{padding-right:.25rem !important}.pe-2{padding-right:.5rem !important}.pe-3{padding-right:1rem !important}.pe-4{padding-right:1.5rem !important}.pe-5{padding-right:3rem !important}.pb-0{padding-bottom:0 !important}.pb-1{padding-bottom:.25rem !important}.pb-2{padding-bottom:.5rem !important}.pb-3{padding-bottom:1rem !important}.pb-4{padding-bottom:1.5rem !important}.pb-5{padding-bottom:3rem !important}.ps-0{padding-left:0 !important}.ps-1{padding-left:.25rem !important}.ps-2{padding-left:.5rem !important}.ps-3{padding-left:1rem !important}.ps-4{padding-left:1.5rem !important}.ps-5{padding-left:3rem !important}@media (min-width: 576px){.d-sm-inline{display:inline !important}.d-sm-inline-block{display:inline-block !important}.d-sm-block{display:block !important}.d-sm-grid{display:grid !important}.d-sm-table{display:table !important}.d-sm-table-row{display:table-row !important}.d-sm-table-cell{display:table-cell !important}.d-sm-flex{display:flex !important}.d-sm-inline-flex{display:inline-flex !important}.d-sm-none{display:none !important}.flex-sm-fill{flex:1 1 auto !important}.flex-sm-row{flex-direction:row !important}.flex-sm-column{flex-direction:column !important}.flex-sm-row-reverse{flex-direction:row-reverse !important}.flex-sm-column-reverse{flex-direction:column-reverse !important}.flex-sm-grow-0{flex-grow:0 !important}.flex-sm-grow-1{flex-grow:1 !important}.flex-sm-shrink-0{flex-shrink:0 !important}.flex-sm-shrink-1{flex-shrink:1 !important}.flex-sm-wrap{flex-wrap:wrap !important}.flex-sm-nowrap{flex-wrap:nowrap !important}.flex-sm-wrap-reverse{flex-wrap:wrap-reverse !important}.justify-content-sm-start{justify-content:flex-start !important}.justify-content-sm-end{justify-content:flex-end !important}.justify-content-sm-center{justify-content:center !important}.justify-content-sm-between{justify-content:space-between !important}.justify-content-sm-around{justify-content:space-around !important}.justify-content-sm-evenly{justify-content:space-evenly !important}.align-items-sm-start{align-items:flex-start !important}.align-items-sm-end{align-items:flex-end !important}.align-items-sm-center{align-items:center !important}.align-items-sm-baseline{align-items:baseline !important}.align-items-sm-stretch{align-items:stretch !important}.align-content-sm-start{align-content:flex-start !important}.align-content-sm-end{align-content:flex-end !important}.align-content-sm-center{align-content:center !important}.align-content-sm-between{align-content:space-between !important}.align-content-sm-around{align-content:space-around !important}.align-content-sm-stretch{align-content:stretch !important}.align-self-sm-auto{align-self:auto !important}.align-self-sm-start{align-self:flex-start !important}.align-self-sm-end{align-self:flex-end !important}.align-self-sm-center{align-self:center !important}.align-self-sm-baseline{align-self:baseline !important}.align-self-sm-stretch{align-self:stretch !important}.order-sm-first{order:-1 !important}.order-sm-0{order:0 !important}.order-sm-1{order:1 !important}.order-sm-2{order:2 !important}.order-sm-3{order:3 !important}.order-sm-4{order:4 !important}.order-sm-5{order:5 !important}.order-sm-last{order:6 !important}.m-sm-0{margin:0 !important}.m-sm-1{margin:.25rem !important}.m-sm-2{margin:.5rem !important}.m-sm-3{margin:1rem !important}.m-sm-4{margin:1.5rem !important}.m-sm-5{margin:3rem !important}.m-sm-auto{margin:auto !important}.mx-sm-0{margin-right:0 !important;margin-left:0 !important}.mx-sm-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-sm-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-sm-3{margin-right:1rem !important;margin-left:1rem !important}.mx-sm-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-sm-5{margin-right:3rem !important;margin-left:3rem !important}.mx-sm-auto{margin-right:auto !important;margin-left:auto !important}.my-sm-0{margin-top:0 !important;margin-bottom:0 !important}.my-sm-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-sm-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-sm-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-sm-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-sm-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-sm-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-sm-0{margin-top:0 !important}.mt-sm-1{margin-top:.25rem !important}.mt-sm-2{margin-top:.5rem !important}.mt-sm-3{margin-top:1rem !important}.mt-sm-4{margin-top:1.5rem !important}.mt-sm-5{margin-top:3rem !important}.mt-sm-auto{margin-top:auto !important}.me-sm-0{margin-right:0 !important}.me-sm-1{margin-right:.25rem !important}.me-sm-2{margin-right:.5rem !important}.me-sm-3{margin-right:1rem !important}.me-sm-4{margin-right:1.5rem !important}.me-sm-5{margin-right:3rem !important}.me-sm-auto{margin-right:auto !important}.mb-sm-0{margin-bottom:0 !important}.mb-sm-1{margin-bottom:.25rem !important}.mb-sm-2{margin-bottom:.5rem !important}.mb-sm-3{margin-bottom:1rem !important}.mb-sm-4{margin-bottom:1.5rem !important}.mb-sm-5{margin-bottom:3rem !important}.mb-sm-auto{margin-bottom:auto !important}.ms-sm-0{margin-left:0 !important}.ms-sm-1{margin-left:.25rem !important}.ms-sm-2{margin-left:.5rem !important}.ms-sm-3{margin-left:1rem !important}.ms-sm-4{margin-left:1.5rem !important}.ms-sm-5{margin-left:3rem !important}.ms-sm-auto{margin-left:auto !important}.p-sm-0{padding:0 !important}.p-sm-1{padding:.25rem !important}.p-sm-2{padding:.5rem !important}.p-sm-3{padding:1rem !important}.p-sm-4{padding:1.5rem !important}.p-sm-5{padding:3rem !important}.px-sm-0{padding-right:0 !important;padding-left:0 !important}.px-sm-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-sm-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-sm-3{padding-right:1rem !important;padding-left:1rem !important}.px-sm-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-sm-5{padding-right:3rem !important;padding-left:3rem !important}.py-sm-0{padding-top:0 !important;padding-bottom:0 !important}.py-sm-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-sm-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-sm-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-sm-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-sm-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-sm-0{padding-top:0 !important}.pt-sm-1{padding-top:.25rem !important}.pt-sm-2{padding-top:.5rem !important}.pt-sm-3{padding-top:1rem !important}.pt-sm-4{padding-top:1.5rem !important}.pt-sm-5{padding-top:3rem !important}.pe-sm-0{padding-right:0 !important}.pe-sm-1{padding-right:.25rem !important}.pe-sm-2{padding-right:.5rem !important}.pe-sm-3{padding-right:1rem !important}.pe-sm-4{padding-right:1.5rem !important}.pe-sm-5{padding-right:3rem !important}.pb-sm-0{padding-bottom:0 !important}.pb-sm-1{padding-bottom:.25rem !important}.pb-sm-2{padding-bottom:.5rem !important}.pb-sm-3{padding-bottom:1rem !important}.pb-sm-4{padding-bottom:1.5rem !important}.pb-sm-5{padding-bottom:3rem !important}.ps-sm-0{padding-left:0 !important}.ps-sm-1{padding-left:.25rem !important}.ps-sm-2{padding-left:.5rem !important}.ps-sm-3{padding-left:1rem !important}.ps-sm-4{padding-left:1.5rem !important}.ps-sm-5{padding-left:3rem !important}}@media (min-width: 768px){.d-md-inline{display:inline !important}.d-md-inline-block{display:inline-block !important}.d-md-block{display:block !important}.d-md-grid{display:grid !important}.d-md-table{display:table !important}.d-md-table-row{display:table-row !important}.d-md-table-cell{display:table-cell !important}.d-md-flex{display:flex !important}.d-md-inline-flex{display:inline-flex !important}.d-md-none{display:none !important}.flex-md-fill{flex:1 1 auto !important}.flex-md-row{flex-direction:row !important}.flex-md-column{flex-direction:column !important}.flex-md-row-reverse{flex-direction:row-reverse !important}.flex-md-column-reverse{flex-direction:column-reverse !important}.flex-md-grow-0{flex-grow:0 !important}.flex-md-grow-1{flex-grow:1 !important}.flex-md-shrink-0{flex-shrink:0 !important}.flex-md-shrink-1{flex-shrink:1 !important}.flex-md-wrap{flex-wrap:wrap !important}.flex-md-nowrap{flex-wrap:nowrap !important}.flex-md-wrap-reverse{flex-wrap:wrap-reverse !important}.justify-content-md-start{justify-content:flex-start !important}.justify-content-md-end{justify-content:flex-end !important}.justify-content-md-center{justify-content:center !important}.justify-content-md-between{justify-content:space-between !important}.justify-content-md-around{justify-content:space-around !important}.justify-content-md-evenly{justify-content:space-evenly !important}.align-items-md-start{align-items:flex-start !important}.align-items-md-end{align-items:flex-end !important}.align-items-md-center{align-items:center !important}.align-items-md-baseline{align-items:baseline !important}.align-items-md-stretch{align-items:stretch !important}.align-content-md-start{align-content:flex-start !important}.align-content-md-end{align-content:flex-end !important}.align-content-md-center{align-content:center !important}.align-content-md-between{align-content:space-between !important}.align-content-md-around{align-content:space-around !important}.align-content-md-stretch{align-content:stretch !important}.align-self-md-auto{align-self:auto !important}.align-self-md-start{align-self:flex-start !important}.align-self-md-end{align-self:flex-end !important}.align-self-md-center{align-self:center !important}.align-self-md-baseline{align-self:baseline !important}.align-self-md-stretch{align-self:stretch !important}.order-md-first{order:-1 !important}.order-md-0{order:0 !important}.order-md-1{order:1 !important}.order-md-2{order:2 !important}.order-md-3{order:3 !important}.order-md-4{order:4 !important}.order-md-5{order:5 !important}.order-md-last{order:6 !important}.m-md-0{margin:0 !important}.m-md-1{margin:.25rem !important}.m-md-2{margin:.5rem !important}.m-md-3{margin:1rem !important}.m-md-4{margin:1.5rem !important}.m-md-5{margin:3rem !important}.m-md-auto{margin:auto !important}.mx-md-0{margin-right:0 !important;margin-left:0 !important}.mx-md-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-md-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-md-3{margin-right:1rem !important;margin-left:1rem !important}.mx-md-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-md-5{margin-right:3rem !important;margin-left:3rem !important}.mx-md-auto{margin-right:auto !important;margin-left:auto !important}.my-md-0{margin-top:0 !important;margin-bottom:0 !important}.my-md-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-md-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-md-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-md-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-md-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-md-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-md-0{margin-top:0 !important}.mt-md-1{margin-top:.25rem !important}.mt-md-2{margin-top:.5rem !important}.mt-md-3{margin-top:1rem !important}.mt-md-4{margin-top:1.5rem !important}.mt-md-5{margin-top:3rem !important}.mt-md-auto{margin-top:auto !important}.me-md-0{margin-right:0 !important}.me-md-1{margin-right:.25rem !important}.me-md-2{margin-right:.5rem !important}.me-md-3{margin-right:1rem !important}.me-md-4{margin-right:1.5rem !important}.me-md-5{margin-right:3rem !important}.me-md-auto{margin-right:auto !important}.mb-md-0{margin-bottom:0 !important}.mb-md-1{margin-bottom:.25rem !important}.mb-md-2{margin-bottom:.5rem !important}.mb-md-3{margin-bottom:1rem !important}.mb-md-4{margin-bottom:1.5rem !important}.mb-md-5{margin-bottom:3rem !important}.mb-md-auto{margin-bottom:auto !important}.ms-md-0{margin-left:0 !important}.ms-md-1{margin-left:.25rem !important}.ms-md-2{margin-left:.5rem !important}.ms-md-3{margin-left:1rem !important}.ms-md-4{margin-left:1.5rem !important}.ms-md-5{margin-left:3rem !important}.ms-md-auto{margin-left:auto !important}.p-md-0{padding:0 !important}.p-md-1{padding:.25rem !important}.p-md-2{padding:.5rem !important}.p-md-3{padding:1rem !important}.p-md-4{padding:1.5rem !important}.p-md-5{padding:3rem !important}.px-md-0{padding-right:0 !important;padding-left:0 !important}.px-md-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-md-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-md-3{padding-right:1rem !important;padding-left:1rem !important}.px-md-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-md-5{padding-right:3rem !important;padding-left:3rem !important}.py-md-0{padding-top:0 !important;padding-bottom:0 !important}.py-md-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-md-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-md-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-md-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-md-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-md-0{padding-top:0 !important}.pt-md-1{padding-top:.25rem !important}.pt-md-2{padding-top:.5rem !important}.pt-md-3{padding-top:1rem !important}.pt-md-4{padding-top:1.5rem !important}.pt-md-5{padding-top:3rem !important}.pe-md-0{padding-right:0 !important}.pe-md-1{padding-right:.25rem !important}.pe-md-2{padding-right:.5rem !important}.pe-md-3{padding-right:1rem !important}.pe-md-4{padding-right:1.5rem !important}.pe-md-5{padding-right:3rem !important}.pb-md-0{padding-bottom:0 !important}.pb-md-1{padding-bottom:.25rem !important}.pb-md-2{padding-bottom:.5rem !important}.pb-md-3{padding-bottom:1rem !important}.pb-md-4{padding-bottom:1.5rem !important}.pb-md-5{padding-bottom:3rem !important}.ps-md-0{padding-left:0 !important}.ps-md-1{padding-left:.25rem !important}.ps-md-2{padding-left:.5rem !important}.ps-md-3{padding-left:1rem !important}.ps-md-4{padding-left:1.5rem !important}.ps-md-5{padding-left:3rem !important}}@media (min-width: 992px){.d-lg-inline{display:inline !important}.d-lg-inline-block{display:inline-block !important}.d-lg-block{display:block !important}.d-lg-grid{display:grid !important}.d-lg-table{display:table !important}.d-lg-table-row{display:table-row !important}.d-lg-table-cell{display:table-cell !important}.d-lg-flex{display:flex !important}.d-lg-inline-flex{display:inline-flex !important}.d-lg-none{display:none !important}.flex-lg-fill{flex:1 1 auto !important}.flex-lg-row{flex-direction:row !important}.flex-lg-column{flex-direction:column !important}.flex-lg-row-reverse{flex-direction:row-reverse !important}.flex-lg-column-reverse{flex-direction:column-reverse !important}.flex-lg-grow-0{flex-grow:0 !important}.flex-lg-grow-1{flex-grow:1 !important}.flex-lg-shrink-0{flex-shrink:0 !important}.flex-lg-shrink-1{flex-shrink:1 !important}.flex-lg-wrap{flex-wrap:wrap !important}.flex-lg-nowrap{flex-wrap:nowrap !important}.flex-lg-wrap-reverse{flex-wrap:wrap-reverse !important}.justify-content-lg-start{justify-content:flex-start !important}.justify-content-lg-end{justify-content:flex-end !important}.justify-content-lg-center{justify-content:center !important}.justify-content-lg-between{justify-content:space-between !important}.justify-content-lg-around{justify-content:space-around !important}.justify-content-lg-evenly{justify-content:space-evenly !important}.align-items-lg-start{align-items:flex-start !important}.align-items-lg-end{align-items:flex-end !important}.align-items-lg-center{align-items:center !important}.align-items-lg-baseline{align-items:baseline !important}.align-items-lg-stretch{align-items:stretch !important}.align-content-lg-start{align-content:flex-start !important}.align-content-lg-end{align-content:flex-end !important}.align-content-lg-center{align-content:center !important}.align-content-lg-between{align-content:space-between !important}.align-content-lg-around{align-content:space-around !important}.align-content-lg-stretch{align-content:stretch !important}.align-self-lg-auto{align-self:auto !important}.align-self-lg-start{align-self:flex-start !important}.align-self-lg-end{align-self:flex-end !important}.align-self-lg-center{align-self:center !important}.align-self-lg-baseline{align-self:baseline !important}.align-self-lg-stretch{align-self:stretch !important}.order-lg-first{order:-1 !important}.order-lg-0{order:0 !important}.order-lg-1{order:1 !important}.order-lg-2{order:2 !important}.order-lg-3{order:3 !important}.order-lg-4{order:4 !important}.order-lg-5{order:5 !important}.order-lg-last{order:6 !important}.m-lg-0{margin:0 !important}.m-lg-1{margin:.25rem !important}.m-lg-2{margin:.5rem !important}.m-lg-3{margin:1rem !important}.m-lg-4{margin:1.5rem !important}.m-lg-5{margin:3rem !important}.m-lg-auto{margin:auto !important}.mx-lg-0{margin-right:0 !important;margin-left:0 !important}.mx-lg-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-lg-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-lg-3{margin-right:1rem !important;margin-left:1rem !important}.mx-lg-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-lg-5{margin-right:3rem !important;margin-left:3rem !important}.mx-lg-auto{margin-right:auto !important;margin-left:auto !important}.my-lg-0{margin-top:0 !important;margin-bottom:0 !important}.my-lg-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-lg-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-lg-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-lg-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-lg-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-lg-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-lg-0{margin-top:0 !important}.mt-lg-1{margin-top:.25rem !important}.mt-lg-2{margin-top:.5rem !important}.mt-lg-3{margin-top:1rem !important}.mt-lg-4{margin-top:1.5rem !important}.mt-lg-5{margin-top:3rem !important}.mt-lg-auto{margin-top:auto !important}.me-lg-0{margin-right:0 !important}.me-lg-1{margin-right:.25rem !important}.me-lg-2{margin-right:.5rem !important}.me-lg-3{margin-right:1rem !important}.me-lg-4{margin-right:1.5rem !important}.me-lg-5{margin-right:3rem !important}.me-lg-auto{margin-right:auto !important}.mb-lg-0{margin-bottom:0 !important}.mb-lg-1{margin-bottom:.25rem !important}.mb-lg-2{margin-bottom:.5rem !important}.mb-lg-3{margin-bottom:1rem !important}.mb-lg-4{margin-bottom:1.5rem !important}.mb-lg-5{margin-bottom:3rem !important}.mb-lg-auto{margin-bottom:auto !important}.ms-lg-0{margin-left:0 !important}.ms-lg-1{margin-left:.25rem !important}.ms-lg-2{margin-left:.5rem !important}.ms-lg-3{margin-left:1rem !important}.ms-lg-4{margin-left:1.5rem !important}.ms-lg-5{margin-left:3rem !important}.ms-lg-auto{margin-left:auto !important}.p-lg-0{padding:0 !important}.p-lg-1{padding:.25rem !important}.p-lg-2{padding:.5rem !important}.p-lg-3{padding:1rem !important}.p-lg-4{padding:1.5rem !important}.p-lg-5{padding:3rem !important}.px-lg-0{padding-right:0 !important;padding-left:0 !important}.px-lg-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-lg-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-lg-3{padding-right:1rem !important;padding-left:1rem !important}.px-lg-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-lg-5{padding-right:3rem !important;padding-left:3rem !important}.py-lg-0{padding-top:0 !important;padding-bottom:0 !important}.py-lg-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-lg-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-lg-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-lg-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-lg-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-lg-0{padding-top:0 !important}.pt-lg-1{padding-top:.25rem !important}.pt-lg-2{padding-top:.5rem !important}.pt-lg-3{padding-top:1rem !important}.pt-lg-4{padding-top:1.5rem !important}.pt-lg-5{padding-top:3rem !important}.pe-lg-0{padding-right:0 !important}.pe-lg-1{padding-right:.25rem !important}.pe-lg-2{padding-right:.5rem !important}.pe-lg-3{padding-right:1rem !important}.pe-lg-4{padding-right:1.5rem !important}.pe-lg-5{padding-right:3rem !important}.pb-lg-0{padding-bottom:0 !important}.pb-lg-1{padding-bottom:.25rem !important}.pb-lg-2{padding-bottom:.5rem !important}.pb-lg-3{padding-bottom:1rem !important}.pb-lg-4{padding-bottom:1.5rem !important}.pb-lg-5{padding-bottom:3rem !important}.ps-lg-0{padding-left:0 !important}.ps-lg-1{padding-left:.25rem !important}.ps-lg-2{padding-left:.5rem !important}.ps-lg-3{padding-left:1rem !important}.ps-lg-4{padding-left:1.5rem !important}.ps-lg-5{padding-left:3rem !important}}@media (min-width: 1200px){.d-xl-inline{display:inline !important}.d-xl-inline-block{display:inline-block !important}.d-xl-block{display:block !important}.d-xl-grid{display:grid !important}.d-xl-table{display:table !important}.d-xl-table-row{display:table-row !important}.d-xl-table-cell{display:table-cell !important}.d-xl-flex{display:flex !important}.d-xl-inline-flex{display:inline-flex !important}.d-xl-none{display:none !important}.flex-xl-fill{flex:1 1 auto !important}.flex-xl-row{flex-direction:row !important}.flex-xl-column{flex-direction:column !important}.flex-xl-row-reverse{flex-direction:row-reverse !important}.flex-xl-column-reverse{flex-direction:column-reverse !important}.flex-xl-grow-0{flex-grow:0 !important}.flex-xl-grow-1{flex-grow:1 !important}.flex-xl-shrink-0{flex-shrink:0 !important}.flex-xl-shrink-1{flex-shrink:1 !important}.flex-xl-wrap{flex-wrap:wrap !important}.flex-xl-nowrap{flex-wrap:nowrap !important}.flex-xl-wrap-reverse{flex-wrap:wrap-reverse !important}.justify-content-xl-start{justify-content:flex-start !important}.justify-content-xl-end{justify-content:flex-end !important}.justify-content-xl-center{justify-content:center !important}.justify-content-xl-between{justify-content:space-between !important}.justify-content-xl-around{justify-content:space-around !important}.justify-content-xl-evenly{justify-content:space-evenly !important}.align-items-xl-start{align-items:flex-start !important}.align-items-xl-end{align-items:flex-end !important}.align-items-xl-center{align-items:center !important}.align-items-xl-baseline{align-items:baseline !important}.align-items-xl-stretch{align-items:stretch !important}.align-content-xl-start{align-content:flex-start !important}.align-content-xl-end{align-content:flex-end !important}.align-content-xl-center{align-content:center !important}.align-content-xl-between{align-content:space-between !important}.align-content-xl-around{align-content:space-around !important}.align-content-xl-stretch{align-content:stretch !important}.align-self-xl-auto{align-self:auto !important}.align-self-xl-start{align-self:flex-start !important}.align-self-xl-end{align-self:flex-end !important}.align-self-xl-center{align-self:center !important}.align-self-xl-baseline{align-self:baseline !important}.align-self-xl-stretch{align-self:stretch !important}.order-xl-first{order:-1 !important}.order-xl-0{order:0 !important}.order-xl-1{order:1 !important}.order-xl-2{order:2 !important}.order-xl-3{order:3 !important}.order-xl-4{order:4 !important}.order-xl-5{order:5 !important}.order-xl-last{order:6 !important}.m-xl-0{margin:0 !important}.m-xl-1{margin:.25rem !important}.m-xl-2{margin:.5rem !important}.m-xl-3{margin:1rem !important}.m-xl-4{margin:1.5rem !important}.m-xl-5{margin:3rem !important}.m-xl-auto{margin:auto !important}.mx-xl-0{margin-right:0 !important;margin-left:0 !important}.mx-xl-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-xl-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-xl-3{margin-right:1rem !important;margin-left:1rem !important}.mx-xl-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-xl-5{margin-right:3rem !important;margin-left:3rem !important}.mx-xl-auto{margin-right:auto !important;margin-left:auto !important}.my-xl-0{margin-top:0 !important;margin-bottom:0 !important}.my-xl-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-xl-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-xl-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-xl-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-xl-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-xl-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-xl-0{margin-top:0 !important}.mt-xl-1{margin-top:.25rem !important}.mt-xl-2{margin-top:.5rem !important}.mt-xl-3{margin-top:1rem !important}.mt-xl-4{margin-top:1.5rem !important}.mt-xl-5{margin-top:3rem !important}.mt-xl-auto{margin-top:auto !important}.me-xl-0{margin-right:0 !important}.me-xl-1{margin-right:.25rem !important}.me-xl-2{margin-right:.5rem !important}.me-xl-3{margin-right:1rem !important}.me-xl-4{margin-right:1.5rem !important}.me-xl-5{margin-right:3rem !important}.me-xl-auto{margin-right:auto !important}.mb-xl-0{margin-bottom:0 !important}.mb-xl-1{margin-bottom:.25rem !important}.mb-xl-2{margin-bottom:.5rem !important}.mb-xl-3{margin-bottom:1rem !important}.mb-xl-4{margin-bottom:1.5rem !important}.mb-xl-5{margin-bottom:3rem !important}.mb-xl-auto{margin-bottom:auto !important}.ms-xl-0{margin-left:0 !important}.ms-xl-1{margin-left:.25rem !important}.ms-xl-2{margin-left:.5rem !important}.ms-xl-3{margin-left:1rem !important}.ms-xl-4{margin-left:1.5rem !important}.ms-xl-5{margin-left:3rem !important}.ms-xl-auto{margin-left:auto !important}.p-xl-0{padding:0 !important}.p-xl-1{padding:.25rem !important}.p-xl-2{padding:.5rem !important}.p-xl-3{padding:1rem !important}.p-xl-4{padding:1.5rem !important}.p-xl-5{padding:3rem !important}.px-xl-0{padding-right:0 !important;padding-left:0 !important}.px-xl-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-xl-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-xl-3{padding-right:1rem !important;padding-left:1rem !important}.px-xl-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-xl-5{padding-right:3rem !important;padding-left:3rem !important}.py-xl-0{padding-top:0 !important;padding-bottom:0 !important}.py-xl-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-xl-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-xl-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-xl-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-xl-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-xl-0{padding-top:0 !important}.pt-xl-1{padding-top:.25rem !important}.pt-xl-2{padding-top:.5rem !important}.pt-xl-3{padding-top:1rem !important}.pt-xl-4{padding-top:1.5rem !important}.pt-xl-5{padding-top:3rem !important}.pe-xl-0{padding-right:0 !important}.pe-xl-1{padding-right:.25rem !important}.pe-xl-2{padding-right:.5rem !important}.pe-xl-3{padding-right:1rem !important}.pe-xl-4{padding-right:1.5rem !important}.pe-xl-5{padding-right:3rem !important}.pb-xl-0{padding-bottom:0 !important}.pb-xl-1{padding-bottom:.25rem !important}.pb-xl-2{padding-bottom:.5rem !important}.pb-xl-3{padding-bottom:1rem !important}.pb-xl-4{padding-bottom:1.5rem !important}.pb-xl-5{padding-bottom:3rem !important}.ps-xl-0{padding-left:0 !important}.ps-xl-1{padding-left:.25rem !important}.ps-xl-2{padding-left:.5rem !important}.ps-xl-3{padding-left:1rem !important}.ps-xl-4{padding-left:1.5rem !important}.ps-xl-5{padding-left:3rem !important}}@media (min-width: 1400px){.d-xxl-inline{display:inline !important}.d-xxl-inline-block{display:inline-block !important}.d-xxl-block{display:block !important}.d-xxl-grid{display:grid !important}.d-xxl-table{display:table !important}.d-xxl-table-row{display:table-row !important}.d-xxl-table-cell{display:table-cell !important}.d-xxl-flex{display:flex !important}.d-xxl-inline-flex{display:inline-flex !important}.d-xxl-none{display:none !important}.flex-xxl-fill{flex:1 1 auto !important}.flex-xxl-row{flex-direction:row !important}.flex-xxl-column{flex-direction:column !important}.flex-xxl-row-reverse{flex-direction:row-reverse !important}.flex-xxl-column-reverse{flex-direction:column-reverse !important}.flex-xxl-grow-0{flex-grow:0 !important}.flex-xxl-grow-1{flex-grow:1 !important}.flex-xxl-shrink-0{flex-shrink:0 !important}.flex-xxl-shrink-1{flex-shrink:1 !important}.flex-xxl-wrap{flex-wrap:wrap !important}.flex-xxl-nowrap{flex-wrap:nowrap !important}.flex-xxl-wrap-reverse{flex-wrap:wrap-reverse !important}.justify-content-xxl-start{justify-content:flex-start !important}.justify-content-xxl-end{justify-content:flex-end !important}.justify-content-xxl-center{justify-content:center !important}.justify-content-xxl-between{justify-content:space-between !important}.justify-content-xxl-around{justify-content:space-around !important}.justify-content-xxl-evenly{justify-content:space-evenly !important}.align-items-xxl-start{align-items:flex-start !important}.align-items-xxl-end{align-items:flex-end !important}.align-items-xxl-center{align-items:center !important}.align-items-xxl-baseline{align-items:baseline !important}.align-items-xxl-stretch{align-items:stretch !important}.align-content-xxl-start{align-content:flex-start !important}.align-content-xxl-end{align-content:flex-end !important}.align-content-xxl-center{align-content:center !important}.align-content-xxl-between{align-content:space-between !important}.align-content-xxl-around{align-content:space-around !important}.align-content-xxl-stretch{align-content:stretch !important}.align-self-xxl-auto{align-self:auto !important}.align-self-xxl-start{align-self:flex-start !important}.align-self-xxl-end{align-self:flex-end !important}.align-self-xxl-center{align-self:center !important}.align-self-xxl-baseline{align-self:baseline !important}.align-self-xxl-stretch{align-self:stretch !important}.order-xxl-first{order:-1 !important}.order-xxl-0{order:0 !important}.order-xxl-1{order:1 !important}.order-xxl-2{order:2 !important}.order-xxl-3{order:3 !important}.order-xxl-4{order:4 !important}.order-xxl-5{order:5 !important}.order-xxl-last{order:6 !important}.m-xxl-0{margin:0 !important}.m-xxl-1{margin:.25rem !important}.m-xxl-2{margin:.5rem !important}.m-xxl-3{margin:1rem !important}.m-xxl-4{margin:1.5rem !important}.m-xxl-5{margin:3rem !important}.m-xxl-auto{margin:auto !important}.mx-xxl-0{margin-right:0 !important;margin-left:0 !important}.mx-xxl-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-xxl-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-xxl-3{margin-right:1rem !important;margin-left:1rem !important}.mx-xxl-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-xxl-5{margin-right:3rem !important;margin-left:3rem !important}.mx-xxl-auto{margin-right:auto !important;margin-left:auto !important}.my-xxl-0{margin-top:0 !important;margin-bottom:0 !important}.my-xxl-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-xxl-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-xxl-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-xxl-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-xxl-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-xxl-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-xxl-0{margin-top:0 !important}.mt-xxl-1{margin-top:.25rem !important}.mt-xxl-2{margin-top:.5rem !important}.mt-xxl-3{margin-top:1rem !important}.mt-xxl-4{margin-top:1.5rem !important}.mt-xxl-5{margin-top:3rem !important}.mt-xxl-auto{margin-top:auto !important}.me-xxl-0{margin-right:0 !important}.me-xxl-1{margin-right:.25rem !important}.me-xxl-2{margin-right:.5rem !important}.me-xxl-3{margin-right:1rem !important}.me-xxl-4{margin-right:1.5rem !important}.me-xxl-5{margin-right:3rem !important}.me-xxl-auto{margin-right:auto !important}.mb-xxl-0{margin-bottom:0 !important}.mb-xxl-1{margin-bottom:.25rem !important}.mb-xxl-2{margin-bottom:.5rem !important}.mb-xxl-3{margin-bottom:1rem !important}.mb-xxl-4{margin-bottom:1.5rem !important}.mb-xxl-5{margin-bottom:3rem !important}.mb-xxl-auto{margin-bottom:auto !important}.ms-xxl-0{margin-left:0 !important}.ms-xxl-1{margin-left:.25rem !important}.ms-xxl-2{margin-left:.5rem !important}.ms-xxl-3{margin-left:1rem !important}.ms-xxl-4{margin-left:1.5rem !important}.ms-xxl-5{margin-left:3rem !important}.ms-xxl-auto{margin-left:auto !important}.p-xxl-0{padding:0 !important}.p-xxl-1{padding:.25rem !important}.p-xxl-2{padding:.5rem !important}.p-xxl-3{padding:1rem !important}.p-xxl-4{padding:1.5rem !important}.p-xxl-5{padding:3rem !important}.px-xxl-0{padding-right:0 !important;padding-left:0 !important}.px-xxl-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-xxl-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-xxl-3{padding-right:1rem !important;padding-left:1rem !important}.px-xxl-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-xxl-5{padding-right:3rem !important;padding-left:3rem !important}.py-xxl-0{padding-top:0 !important;padding-bottom:0 !important}.py-xxl-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-xxl-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-xxl-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-xxl-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-xxl-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-xxl-0{padding-top:0 !important}.pt-xxl-1{padding-top:.25rem !important}.pt-xxl-2{padding-top:.5rem !important}.pt-xxl-3{padding-top:1rem !important}.pt-xxl-4{padding-top:1.5rem !important}.pt-xxl-5{padding-top:3rem !important}.pe-xxl-0{padding-right:0 !important}.pe-xxl-1{padding-right:.25rem !important}.pe-xxl-2{padding-right:.5rem !important}.pe-xxl-3{padding-right:1rem !important}.pe-xxl-4{padding-right:1.5rem !important}.pe-xxl-5{padding-right:3rem !important}.pb-xxl-0{padding-bottom:0 !important}.pb-xxl-1{padding-bottom:.25rem !important}.pb-xxl-2{padding-bottom:.5rem !important}.pb-xxl-3{padding-bottom:1rem !important}.pb-xxl-4{padding-bottom:1.5rem !important}.pb-xxl-5{padding-bottom:3rem !important}.ps-xxl-0{padding-left:0 !important}.ps-xxl-1{padding-left:.25rem !important}.ps-xxl-2{padding-left:.5rem !important}.ps-xxl-3{padding-left:1rem !important}.ps-xxl-4{padding-left:1.5rem !important}.ps-xxl-5{padding-left:3rem !important}}@media print{.d-print-inline{display:inline !important}.d-print-inline-block{display:inline-block !important}.d-print-block{display:block !important}.d-print-grid{display:grid !important}.d-print-table{display:table !important}.d-print-table-row{display:table-row !important}.d-print-table-cell{display:table-cell !important}.d-print-flex{display:flex !important}.d-print-inline-flex{display:inline-flex !important}.d-print-none{display:none !important}}.row{--bs-gutter-x: 1.875rem}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:#fff;border:1px solid #dee2e6;border-radius:.25rem;max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:.875em;color:#6c757d}.list-group{display:flex;flex-direction:column;padding-left:0;margin-bottom:0;border-radius:0}.list-group-numbered{list-style-type:none;counter-reset:section}.list-group-numbered>li::before{content:counters(section, ".") ". ";counter-increment:section}.list-group-item-action{width:100%;color:var(--t42-content-color);text-align:inherit}.list-group-item-action:hover,.list-group-item-action:focus{z-index:1;color:var(--t42-link-hover-color);text-decoration:none;background-color:var(--t42-link-hover-bg)}.list-group-item-action:active{color:var(--t42-link-hover-color);background-color:var(--t42-link-active-bg)}.list-group-item{position:relative;display:block;padding:.75rem 1.25rem;color:inherit;text-decoration:none;background-color:Rgb(var(--t42-bg-mid));border:1px solid rgba(0,0,0,0)}.list-group-item:first-child{border-top-left-radius:inherit;border-top-right-radius:inherit}.list-group-item:last-child{border-bottom-right-radius:inherit;border-bottom-left-radius:inherit}.list-group-item.disabled,.list-group-item:disabled{color:var(--t42-content-color-disabled);pointer-events:none;background-color:rgba(0,0,0,0)}.list-group-item.active{z-index:2;color:var(--t42-link-hover-color);background-color:var(--t42-link-active-bg);border-color:rgba(0,0,0,0)}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{margin-top:-1px;border-top-width:1px}.list-group-horizontal{flex-direction:row}.list-group-horizontal>.list-group-item:first-child{border-bottom-left-radius:0;border-top-right-radius:0}.list-group-horizontal>.list-group-item:last-child{border-top-right-radius:0;border-bottom-left-radius:0}.list-group-horizontal>.list-group-item.active{margin-top:0}.list-group-horizontal>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}@media (min-width: 576px){.list-group-horizontal-sm{flex-direction:row}.list-group-horizontal-sm>.list-group-item:first-child{border-bottom-left-radius:0;border-top-right-radius:0}.list-group-horizontal-sm>.list-group-item:last-child{border-top-right-radius:0;border-bottom-left-radius:0}.list-group-horizontal-sm>.list-group-item.active{margin-top:0}.list-group-horizontal-sm>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-sm>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width: 768px){.list-group-horizontal-md{flex-direction:row}.list-group-horizontal-md>.list-group-item:first-child{border-bottom-left-radius:0;border-top-right-radius:0}.list-group-horizontal-md>.list-group-item:last-child{border-top-right-radius:0;border-bottom-left-radius:0}.list-group-horizontal-md>.list-group-item.active{margin-top:0}.list-group-horizontal-md>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-md>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width: 992px){.list-group-horizontal-lg{flex-direction:row}.list-group-horizontal-lg>.list-group-item:first-child{border-bottom-left-radius:0;border-top-right-radius:0}.list-group-horizontal-lg>.list-group-item:last-child{border-top-right-radius:0;border-bottom-left-radius:0}.list-group-horizontal-lg>.list-group-item.active{margin-top:0}.list-group-horizontal-lg>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-lg>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width: 1200px){.list-group-horizontal-xl{flex-direction:row}.list-group-horizontal-xl>.list-group-item:first-child{border-bottom-left-radius:0;border-top-right-radius:0}.list-group-horizontal-xl>.list-group-item:last-child{border-top-right-radius:0;border-bottom-left-radius:0}.list-group-horizontal-xl>.list-group-item.active{margin-top:0}.list-group-horizontal-xl>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-xl>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width: 1400px){.list-group-horizontal-xxl{flex-direction:row}.list-group-horizontal-xxl>.list-group-item:first-child{border-bottom-left-radius:0;border-top-right-radius:0}.list-group-horizontal-xxl>.list-group-item:last-child{border-top-right-radius:0;border-bottom-left-radius:0}.list-group-horizontal-xxl>.list-group-item.active{margin-top:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}.list-group-flush{border-radius:0}.list-group-flush>.list-group-item{border-width:0 0 1px}.list-group-flush>.list-group-item:last-child{border-bottom-width:0}.list-group-item-primary{color:#004a89;background-color:#cce5fa}.list-group-item-primary.list-group-item-action:hover,.list-group-item-primary.list-group-item-action:focus{color:#004a89;background-color:#b8cee1}.list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#004a89;border-color:#004a89}.list-group-item-secondary{color:#3a3a3a;background-color:#dfdfdf}.list-group-item-secondary.list-group-item-action:hover,.list-group-item-secondary.list-group-item-action:focus{color:#3a3a3a;background-color:#c9c9c9}.list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#3a3a3a;border-color:#3a3a3a}.list-group-item-success{color:#28602b;background-color:#d9ecda}.list-group-item-success.list-group-item-action:hover,.list-group-item-success.list-group-item-action:focus{color:#28602b;background-color:#c3d4c4}.list-group-item-success.list-group-item-action.active{color:#fff;background-color:#28602b;border-color:#28602b}.list-group-item-info{color:#2a5f6f;background-color:#daecf1}.list-group-item-info.list-group-item-action:hover,.list-group-item-info.list-group-item-action:focus{color:#2a5f6f;background-color:#c4d4d9}.list-group-item-info.list-group-item-action.active{color:#fff;background-color:#2a5f6f;border-color:#2a5f6f}.list-group-item-warning{color:#64430f;background-color:#feeed3}.list-group-item-warning.list-group-item-action:hover,.list-group-item-warning.list-group-item-action:focus{color:#64430f;background-color:#e5d6be}.list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#64430f;border-color:#64430f}.list-group-item-danger{color:#993113;background-color:#ffdcd2}.list-group-item-danger.list-group-item-action:hover,.list-group-item-danger.list-group-item-action:focus{color:#993113;background-color:#e6c6bd}.list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#993113;border-color:#993113}.list-group-item-light{color:#3a3a3a;background-color:#dfdfdf}.list-group-item-light.list-group-item-action:hover,.list-group-item-light.list-group-item-action:focus{color:#3a3a3a;background-color:#c9c9c9}.list-group-item-light.list-group-item-action.active{color:#fff;background-color:#3a3a3a;border-color:#3a3a3a}.list-group-item-dark{color:#3a3a3a;background-color:#dfdfdf}.list-group-item-dark.list-group-item-action:hover,.list-group-item-dark.list-group-item-action:focus{color:#3a3a3a;background-color:#c9c9c9}.list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#3a3a3a;border-color:#3a3a3a}.list-unstyled{padding-left:0;list-style:none}.list-group{box-shadow:var(--t42-shadow)}.list-group-item{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:color;margin-bottom:0;border:0;border-bottom:var(--t42-border);backdrop-filter:var(--backdrop-filter)}.list-group-item:last-child{border-bottom:transparent}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{margin-top:0;border-top-width:0}.list-group-item-action{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background,color;transition-duration:0.25s}.list-group-item-action:hover,.list-group-item-action:focus{background-color:var(--t42-list-group-hover-bg-special)}.list-group-item-action.active:hover{background-color:var(--t42-color-opacity-05)}.modal{position:fixed;top:0;left:0;z-index:1055;display:none;width:100%;height:100%;overflow-x:hidden;overflow-y:auto;outline:0}.modal-dialog{position:relative;width:auto;margin:.5rem;pointer-events:none}.modal.fade .modal-dialog{transition:transform 0.3s ease-out;transform:translate(0, -50px)}@media (prefers-reduced-motion: reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{transform:none}.modal.modal-static .modal-dialog{transform:scale(1.02)}.modal-dialog-scrollable{height:calc(100% - 1rem)}.modal-dialog-scrollable .modal-content{max-height:100%;overflow:hidden}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{display:flex;align-items:center;min-height:calc(100% - 1rem)}.modal-content{position:relative;display:flex;flex-direction:column;width:100%;pointer-events:auto;background-color:var(--t42-modal-bg);background-clip:padding-box;border:.0625rem solid var(--t42-color-opacity-10);border-radius:0;outline:0}.modal-backdrop{position:fixed;top:0;left:0;z-index:1050;width:100vw;height:100vh;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:.5}.modal-header{display:flex;flex-shrink:0;align-items:center;justify-content:space-between;padding:1rem 1rem;border-bottom:.0625rem solid rgba(0,0,0,0);border-top-left-radius:0;border-top-right-radius:0}.modal-header .btn-close{padding:.5rem .5rem;margin:-.5rem -.5rem -.5rem auto}.modal-title{margin-bottom:0;line-height:1.5}.modal-body{position:relative;flex:1 1 auto;padding:1rem}.modal-footer{display:flex;flex-wrap:wrap;flex-shrink:0;align-items:center;justify-content:flex-end;padding:.75rem;border-top:.0625rem solid rgba(0,0,0,0);border-bottom-right-radius:0;border-bottom-left-radius:0}.modal-footer>*{margin:.25rem}@media (min-width: 576px){.modal-dialog{max-width:500px;margin:1.75rem auto}.modal-dialog-scrollable{height:calc(100% - 3.5rem)}.modal-dialog-centered{min-height:calc(100% - 3.5rem)}.modal-sm{max-width:300px}}@media (min-width: 992px){.modal-lg,.modal-xl{max-width:800px}}@media (min-width: 1200px){.modal-xl{max-width:1140px}}.modal-fullscreen{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen .modal-header{border-radius:0}.modal-fullscreen .modal-body{overflow-y:auto}.modal-fullscreen .modal-footer{border-radius:0}@media (max-width: 575.98px){.modal-fullscreen-sm-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-sm-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-sm-down .modal-header{border-radius:0}.modal-fullscreen-sm-down .modal-body{overflow-y:auto}.modal-fullscreen-sm-down .modal-footer{border-radius:0}}@media (max-width: 767.98px){.modal-fullscreen-md-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-md-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-md-down .modal-header{border-radius:0}.modal-fullscreen-md-down .modal-body{overflow-y:auto}.modal-fullscreen-md-down .modal-footer{border-radius:0}}@media (max-width: 991.98px){.modal-fullscreen-lg-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-lg-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-lg-down .modal-header{border-radius:0}.modal-fullscreen-lg-down .modal-body{overflow-y:auto}.modal-fullscreen-lg-down .modal-footer{border-radius:0}}@media (max-width: 1199.98px){.modal-fullscreen-xl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xl-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-xl-down .modal-header{border-radius:0}.modal-fullscreen-xl-down .modal-body{overflow-y:auto}.modal-fullscreen-xl-down .modal-footer{border-radius:0}}@media (max-width: 1399.98px){.modal-fullscreen-xxl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xxl-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-xxl-down .modal-header{border-radius:0}.modal-fullscreen-xxl-down .modal-body{overflow-y:auto}.modal-fullscreen-xxl-down .modal-footer{border-radius:0}}.modal{backdrop-filter:var(--backdrop-filter)}.modal .btn-close{font-size:1.25rem;background-size:0.75rem;filter:var(--filter-close)}.modal-content{border-top:0;background:linear-gradient(to bottom right, Rgba(var(--t42-bg-light), 0.75) 0%, Rgba(var(--t42-bg-dark), 0.75) 100%);box-shadow:var(--t42-shadow)}.modal-content::before{display:block;height:0.0625rem;background:linear-gradient(90deg, #007be5 0%, rgba(0,123,229,0.5) 100%);content:""}.modal-body{padding:0 1rem}.modal-body p:last-child{margin-bottom:0}.modal-sm .modal-footer{flex-direction:column}.modal-sm .modal-footer .btn{width:100%}.modal-sm .modal-footer .btn:not(:last-of-type){margin-bottom:0.5rem}.modal-fill-in{background-color:Rgba(var(--t42-bg-light), 0.75)}.modal-fill-in.modal-dialog{display:flex;flex-flow:column nowrap;align-content:center;align-items:center;justify-content:center;width:auto;max-width:100%;height:100%;margin:0 auto}.modal-fill-in .modal-content{display:flex;max-width:600px;border-color:transparent;background:transparent;background-color:transparent;box-shadow:none;backdrop-filter:none;pointer-events:auto}.modal-fill-in .modal-content::before{display:none}.modal-fill-in::before{position:fixed;top:0;right:0;left:0;display:block;height:0.0625rem;background:linear-gradient(90deg, #007be5 0%, rgba(0,123,229,0.5) 100%);content:""}.modal-fill-in.modal-lg .modal-content{max-width:800px}.modal-fill-in.modal-sm .modal-content{max-width:300px}.nav{display:flex;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:.45rem 1rem;color:var(--t42-link-color);text-decoration:none;transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.nav-link{transition:none}}.nav-link:hover,.nav-link:focus{color:var(--t42-link-hover-color)}.nav-link.disabled{color:var(--t42-content-color-disabled);pointer-events:none;cursor:default}.nav-tabs{border-bottom:.0625rem solid var(--t42-color-opacity-10)}.nav-tabs .nav-link{margin-bottom:-.0625rem;background:none;border:.0625rem solid transparent;border-top-left-radius:0;border-top-right-radius:0}.nav-tabs .nav-link:hover,.nav-tabs .nav-link:focus{border-color:transparent transparent var(--t42-color-opacity-10);isolation:isolate}.nav-tabs .nav-link.disabled{color:var(--t42-content-color-disabled);background-color:transparent;border-color:transparent}.nav-tabs .nav-link.active,.nav-tabs .nav-item.show .nav-link{color:var(--t42-link-hover-color);background-color:var(--t42-link-active-bg);border-color:transparent transparent #007be5}.nav-tabs .dropdown-menu{margin-top:-.0625rem;border-top-left-radius:0;border-top-right-radius:0}.nav-pills .nav-link{background:none;border:0;border-radius:.25rem}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:var(--t42-link-hover-color);background-color:var(--t42-link-active-bg)}.nav-fill>.nav-link,.nav-fill .nav-item{flex:1 1 auto;text-align:center}.nav-justified>.nav-link,.nav-justified .nav-item{flex-basis:0;flex-grow:1;text-align:center}.nav-fill .nav-item .nav-link,.nav-justified .nav-item .nav-link{width:100%}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-link{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, border-color, color;margin-right:3px;border:.0625rem solid transparent}.nav-link:not(.disabled):not(:disabled):focus,.nav-link:not(.disabled):not(:disabled):active,.nav-link:not(.disabled):not(:disabled).active,.nav-link:not(.disabled):not(:disabled):hover{border-color:var(--t42-color-opacity-10);color:var(--t42-link-color);background-color:var(--t42-link-hover-bg)}.nav-link.dropdown-toggle::after{right:-0.125rem}.navbar-nav .nav-item{bottom:-1px}.navbar-nav .nav-item .nav-link{border-bottom:0}.navbar-nav .nav-item:not(.disabled):not(:disabled):focus .nav-link,.navbar-nav .nav-item:not(.disabled):not(:disabled):active .nav-link,.navbar-nav .nav-item:not(.disabled):not(:disabled).active .nav-link,.navbar-nav .nav-item:not(.disabled):not(:disabled):hover .nav-link{border-color:var(--t42-color-opacity-10)}.nav.flex-column .nav-link{margin-bottom:3px}.nav-tabs .nav-link{position:relative;display:flex;align-items:center;height:2rem}.nav-tabs .nav-link::before{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:height;position:absolute;bottom:-2px;left:-1px;width:calc(100% + 2px);height:0;background-color:var(--primary);content:""}.nav-tabs .nav-link.active::before{height:3px}.nav-tabs .nav-link.active:hover::before{height:0}.nav-tabs .nav-link .btn-close{width:0.5rem;height:0.5rem}.nav-tabs .nav-item{margin-right:0}.nav-tabs .dropdown.show .dropdown-toggle{border-color:transparent}.nav-tabs.flex-column .nav-link.active:hover::before{width:0}.nav-tabs.flex-column .nav-link::before{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:width;top:-1px;width:0;height:100%;margin-left:0;background-color:var(--primary);content:""}.nav-tabs.flex-column .nav-link.active::before{width:3px;height:calc(100% + 2px)}.nav-pills .nav-link{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;width:100%;padding:0.25rem 1rem;border:1px solid transparent;border-radius:1rem}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{position:relative;border-color:transparent}.nav-pills .nav-item{margin-right:3px}.nav-pills .nav-item:last-child{margin-right:0}.nav-pills .nav-link.active:not(.dropdown-toggle),.nav-pills .show>.nav-link:not(.dropdown-toggle){padding:0.25rem 1.75rem 0.25rem 1rem}.nav-pills .nav-link.active:not(.dropdown-toggle)::before,.nav-pills .show>.nav-link:not(.dropdown-toggle)::before{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:right;position:absolute;top:50%;right:10px;width:8px;height:8px;border-radius:50%;background-color:var(--primary);transform:translateY(-50%);content:""}.nav-pills .nav-link.active:not(.dropdown-toggle):hover::before,.nav-pills .show>.nav-link:not(.dropdown-toggle):hover::before{right:-10px}.nav-justified .nav-item .nav-link::before{right:1px;left:-1px;margin-left:0}.tab-content{padding-top:0.5rem}.nav-action-buttons .nav-link{position:relative;padding:0.45rem 1.5rem 0.45rem 1rem}.nav-action-buttons .icon-cancel::before{display:block;width:1rem;height:1rem;background-color:var(--t42-content-color);content:"";-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M366.854,336.384c6.14398,6.14398,9.216,13.48267,9.216,22.01599s-3.07202,15.87198-9.216,22.01599 c-6.14398,5.46133-13.48267,8.19202-22.01599,8.19199c-8.53333,0.00003-15.87201-2.73065-22.01602-8.19199l-67.584-77.82401 l-67.584,77.82401c-6.144,5.46133-13.48267,8.19202-22.01601,8.19199c-8.53333,0.00003-15.87199-2.73065-22.01599-8.19199 c-5.46133-6.14401-8.192-13.48267-8.192-22.01599s2.73067-15.87201,8.192-22.01599l70.65599-79.87201l-70.65601-80.896 c-5.46132-6.144-8.19199-13.48268-8.19199-22.01601c0-8.53334,2.73067-15.87201,8.19199-22.01601 c6.14401-5.46133,13.48267-8.19199,22.01601-8.192c8.53334,0.00001,15.87201,2.73067,22.01601,8.192l67.584,77.82401 l67.584-77.82401c6.14401-5.46133,13.4827-8.19199,22.01602-8.192c8.53333,0.00001,15.87201,2.73067,22.01599,8.192 c6.14398,6.144,9.216,13.48267,9.216,22.01601c0,8.53333-3.07202,15.87201-9.216,22.01601l-70.65601,80.896L366.854,336.384z%27/%3E%3C/svg%3E")}.navbar{position:relative;display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;padding-top:0;padding-right:.875rem;padding-bottom:0;padding-left:.875rem}.navbar>.container,.navbar>.container-fluid,.navbar>.container-sm,.navbar>.container-md,.navbar>.container-lg,.navbar>.container-xl,.navbar>.container-xxl{display:flex;flex-wrap:inherit;align-items:center;justify-content:space-between}.navbar-brand{padding-top:.075rem;padding-bottom:.075rem;margin-right:1rem;font-size:1.25rem;text-decoration:none;white-space:nowrap}.navbar-nav{display:flex;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-nav .dropdown-menu{position:static}.navbar-text{padding-top:.45rem;padding-bottom:.45rem}.navbar-collapse{flex-basis:100%;flex-grow:1;align-items:center}.navbar-toggler{padding:0 0;font-size:.9375rem;line-height:1;background-color:transparent;border:1px solid transparent;border-radius:0;transition:box-shadow 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.navbar-toggler{transition:none}}.navbar-toggler:hover{text-decoration:none}.navbar-toggler:focus{text-decoration:none;outline:0;box-shadow:0 0 0 0}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;background-repeat:no-repeat;background-position:center;background-size:100%}.navbar-nav-scroll{max-height:var(--bs-scroll-height, 75vh);overflow-y:auto}@media (min-width: 576px){.navbar-expand-sm{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-sm .navbar-nav{flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm .navbar-nav-scroll{overflow:visible}.navbar-expand-sm .navbar-collapse{display:flex !important;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}.navbar-expand-sm .offcanvas-header{display:none}.navbar-expand-sm .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;visibility:visible !important;background-color:transparent;border-right:0;border-left:0;transition:none;transform:none}.navbar-expand-sm .offcanvas-top,.navbar-expand-sm .offcanvas-bottom{height:auto;border-top:0;border-bottom:0}.navbar-expand-sm .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width: 768px){.navbar-expand-md{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-md .navbar-nav{flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-md .navbar-nav-scroll{overflow:visible}.navbar-expand-md .navbar-collapse{display:flex !important;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}.navbar-expand-md .offcanvas-header{display:none}.navbar-expand-md .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;visibility:visible !important;background-color:transparent;border-right:0;border-left:0;transition:none;transform:none}.navbar-expand-md .offcanvas-top,.navbar-expand-md .offcanvas-bottom{height:auto;border-top:0;border-bottom:0}.navbar-expand-md .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width: 992px){.navbar-expand-lg{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-lg .navbar-nav{flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-lg .navbar-nav-scroll{overflow:visible}.navbar-expand-lg .navbar-collapse{display:flex !important;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}.navbar-expand-lg .offcanvas-header{display:none}.navbar-expand-lg .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;visibility:visible !important;background-color:transparent;border-right:0;border-left:0;transition:none;transform:none}.navbar-expand-lg .offcanvas-top,.navbar-expand-lg .offcanvas-bottom{height:auto;border-top:0;border-bottom:0}.navbar-expand-lg .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width: 1200px){.navbar-expand-xl{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-xl .navbar-nav{flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xl .navbar-nav-scroll{overflow:visible}.navbar-expand-xl .navbar-collapse{display:flex !important;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}.navbar-expand-xl .offcanvas-header{display:none}.navbar-expand-xl .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;visibility:visible !important;background-color:transparent;border-right:0;border-left:0;transition:none;transform:none}.navbar-expand-xl .offcanvas-top,.navbar-expand-xl .offcanvas-bottom{height:auto;border-top:0;border-bottom:0}.navbar-expand-xl .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width: 1400px){.navbar-expand-xxl{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-xxl .navbar-nav{flex-direction:row}.navbar-expand-xxl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xxl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xxl .navbar-nav-scroll{overflow:visible}.navbar-expand-xxl .navbar-collapse{display:flex !important;flex-basis:auto}.navbar-expand-xxl .navbar-toggler{display:none}.navbar-expand-xxl .offcanvas-header{display:none}.navbar-expand-xxl .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;visibility:visible !important;background-color:transparent;border-right:0;border-left:0;transition:none;transform:none}.navbar-expand-xxl .offcanvas-top,.navbar-expand-xxl .offcanvas-bottom{height:auto;border-top:0;border-bottom:0}.navbar-expand-xxl .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}.navbar-expand{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand .navbar-nav{flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand .navbar-nav-scroll{overflow:visible}.navbar-expand .navbar-collapse{display:flex !important;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-expand .offcanvas-header{display:none}.navbar-expand .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;visibility:visible !important;background-color:transparent;border-right:0;border-left:0;transition:none;transform:none}.navbar-expand .offcanvas-top,.navbar-expand .offcanvas-bottom{height:auto;border-top:0;border-bottom:0}.navbar-expand .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}.navbar-light .navbar-brand{color:var(--t42-link-color)}.navbar-light .navbar-brand:hover,.navbar-light .navbar-brand:focus{color:var(--t42-link-hover-color)}.navbar-light .navbar-nav .nav-link{color:var(--t42-link-color)}.navbar-light .navbar-nav .nav-link:hover,.navbar-light .navbar-nav .nav-link:focus{color:var(--t42-link-hover-color)}.navbar-light .navbar-nav .nav-link.disabled{color:var(--t42-content-color-disabled)}.navbar-light .navbar-nav .show>.nav-link,.navbar-light .navbar-nav .nav-link.active{color:var(--t42-link-hover-color)}.navbar-light .navbar-toggler{color:var(--t42-link-color);border-color:rgba(0,0,0,0.1)}.navbar-light .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 30 30%27%3e%3cpath stroke=%27var%28--t42-link-color%29%27 stroke-linecap=%27round%27 stroke-miterlimit=%2710%27 stroke-width=%272%27 d=%27M4 7h22M4 15h22M4 23h22%27/%3e%3c/svg%3e")}.navbar-light .navbar-text{color:var(--t42-link-color)}.navbar-light .navbar-text a,.navbar-light .navbar-text a:hover,.navbar-light .navbar-text a:focus{color:var(--t42-link-hover-color)}.navbar-dark .navbar-brand{color:var(--t42-link-color)}.navbar-dark .navbar-brand:hover,.navbar-dark .navbar-brand:focus{color:var(--t42-link-hover-color)}.navbar-dark .navbar-nav .nav-link{color:var(--t42-link-color)}.navbar-dark .navbar-nav .nav-link:hover,.navbar-dark .navbar-nav .nav-link:focus{color:var(--t42-link-hover-color)}.navbar-dark .navbar-nav .nav-link.disabled{color:var(--t42-content-color-disabled)}.navbar-dark .navbar-nav .show>.nav-link,.navbar-dark .navbar-nav .nav-link.active{color:var(--t42-link-hover-color)}.navbar-dark .navbar-toggler{color:var(--t42-link-color);border-color:rgba(255,255,255,0.1)}.navbar-dark .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 30 30%27%3e%3cpath stroke=%27var%28--t42-link-color%29%27 stroke-linecap=%27round%27 stroke-miterlimit=%2710%27 stroke-width=%272%27 d=%27M4 7h22M4 15h22M4 23h22%27/%3e%3c/svg%3e")}.navbar-dark .navbar-text{color:var(--t42-link-color)}.navbar-dark .navbar-text a,.navbar-dark .navbar-text a:hover,.navbar-dark .navbar-text a:focus{color:var(--t42-link-hover-color)}.navbar{border-bottom:var(--t42-border);background-color:Rgba(var(--t42-bg-mid), 0.75);backdrop-filter:var(--backdrop-filter)}.navbar-dark{background-color:Rgba(var(--t42-bg-dark), 0.75)}.navbar-light{background-color:Rgba(var(--t42-bg-light), 0.75)}.navbar .nav-item{position:relative}.navbar .nav-item.show:focus .nav-link:not(.disabled):not(:disabled),.navbar .nav-item.show:active .nav-link:not(.disabled):not(:disabled),.navbar .nav-item.show.active .nav-link:not(.disabled):not(:disabled),.navbar .nav-item:not(.disabled):not(:disabled):focus .nav-link:not(.disabled):not(:disabled),.navbar .nav-item:not(.disabled):not(:disabled):active .nav-link:not(.disabled):not(:disabled),.navbar .nav-item:not(.disabled):not(:disabled).active .nav-link:not(.disabled):not(:disabled){color:var(--t42-link-color);background-color:var(--t42-color-opacity-10)}.navbar .nav-item.show:hover .nav-link:not(.disabled):not(:disabled),.navbar .nav-item:not(.disabled):not(:disabled):hover .nav-link:not(.disabled):not(:disabled){color:var(--t42-link-color);background-color:var(--t42-color-opacity-05)}.navbar .nav-link{padding-right:.875rem;padding-left:.875rem}.navbar .btn-group{height:100%;padding-left:.875rem;border-left:var(--t42-border)}.pagination{display:flex;padding-left:0;list-style:none}.page-link{position:relative;display:block;color:var(--t42-content-color);text-decoration:none;background-color:rgba(0,0,0,0);border:0 solid rgba(0,0,0,0);transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.page-link{transition:none}}.page-link:hover{z-index:2;color:var(--t42-link-hover-color);background-color:var(--t42-link-hover-bg);border-color:#dee2e6}.page-link:focus{z-index:3;color:var(--t42-link-hover-color);background-color:rgba(0,0,0,0);outline:0;box-shadow:0 0 0 0 rgba(0,123,229,0.25)}.page-item:not(:first-child) .page-link{margin-left:0}.page-item.active .page-link{z-index:3;color:var(--white);background-color:var(--primary);border-color:var(--primary)}.page-item.disabled .page-link{color:var(--t42-content-color-disabled);pointer-events:none;background-color:rgba(0,0,0,0);border-color:#dee2e6}.page-link{padding:.125rem .5rem}.page-item:first-child .page-link{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.page-item:last-child .page-link{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.pagination-lg .page-link{padding:.75rem 1.5rem;font-size:.9375rem}.pagination-lg .page-item:first-child .page-link{border-top-left-radius:1rem;border-bottom-left-radius:1rem}.pagination-lg .page-item:last-child .page-link{border-top-right-radius:1rem;border-bottom-right-radius:1rem}.pagination-sm .page-link{padding:.25rem .5rem;font-size:.65625rem}.pagination-sm .page-item:first-child .page-link{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.pagination-sm .page-item:last-child .page-link{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.page-link{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, color;display:flex;align-items:center;justify-content:center;min-width:1.5rem;min-height:1.5rem;border-radius:0.25rem;overflow:hidden}.page-link[aria-label="Next"],.page-link[aria-label="Previous"]{padding:0}.page-link[aria-label="Next"] span{background:var(--t42-select-indicator) center center/1rem 1rem no-repeat;transform:rotate(-90deg)}.page-link[aria-label="Previous"] span{background:var(--t42-select-indicator) center center/1rem 1rem no-repeat;transform:rotate(90deg)}.page-link>span{width:100%;height:100%;min-height:1rem;font-size:0;clip:initial}.pagination-lg .page-link[aria-label="Next"],.pagination-lg .page-link[aria-label="Previous"]{padding:0.75rem 1.5rem}.page-item{margin-right:8px}.page-item:first-child .page-link>span:not(.sr-only)::before,.page-item:last-child .page-link>span:not(.sr-only)::before{top:-0.125rem}.page-item.active .page-link:hover,.page-item:active .page-link:hover{background-color:var(--t42-color-opacity-05)}.page-item.active.disabled .page-link{background-color:var(--t42-color-opacity-10)}.popover{position:absolute;top:0;left:0 /* rtl:ignore */;z-index:1070;display:block;max-width:276px;font-family:"Montserrat","Helvetica Neue",Arial,sans-serif;font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.65625rem;word-wrap:break-word;background-color:Rgba(var(--t42-bg-dark), 0.75);background-clip:padding-box;border:1px solid var(--t42-color-opacity-10);border-radius:0}.popover .popover-arrow{position:absolute;display:block;width:1rem;height:.5rem}.popover .popover-arrow::before,.popover .popover-arrow::after{position:absolute;display:block;content:"";border-color:transparent;border-style:solid}.bs-popover-top>.popover-arrow,.bs-popover-auto[data-popper-placement^="top"]>.popover-arrow{bottom:calc(-.5rem - 1px)}.bs-popover-top>.popover-arrow::before,.bs-popover-auto[data-popper-placement^="top"]>.popover-arrow::before{bottom:0;border-width:.5rem .5rem 0;border-top-color:var(--t42-color-opacity-10)}.bs-popover-top>.popover-arrow::after,.bs-popover-auto[data-popper-placement^="top"]>.popover-arrow::after{bottom:1px;border-width:.5rem .5rem 0;border-top-color:var(--t42-color-opacity-10)}.bs-popover-end>.popover-arrow,.bs-popover-auto[data-popper-placement^="right"]>.popover-arrow{left:calc(-.5rem - 1px);width:.5rem;height:1rem}.bs-popover-end>.popover-arrow::before,.bs-popover-auto[data-popper-placement^="right"]>.popover-arrow::before{left:0;border-width:.5rem .5rem .5rem 0;border-right-color:var(--t42-color-opacity-10)}.bs-popover-end>.popover-arrow::after,.bs-popover-auto[data-popper-placement^="right"]>.popover-arrow::after{left:1px;border-width:.5rem .5rem .5rem 0;border-right-color:var(--t42-color-opacity-10)}.bs-popover-bottom>.popover-arrow,.bs-popover-auto[data-popper-placement^="bottom"]>.popover-arrow{top:calc(-.5rem - 1px)}.bs-popover-bottom>.popover-arrow::before,.bs-popover-auto[data-popper-placement^="bottom"]>.popover-arrow::before{top:0;border-width:0 .5rem .5rem .5rem;border-bottom-color:var(--t42-color-opacity-10)}.bs-popover-bottom>.popover-arrow::after,.bs-popover-auto[data-popper-placement^="bottom"]>.popover-arrow::after{top:1px;border-width:0 .5rem .5rem .5rem;border-bottom-color:var(--t42-color-opacity-10)}.bs-popover-bottom .popover-header::before,.bs-popover-auto[data-popper-placement^="bottom"] .popover-header::before{position:absolute;top:0;left:50%;display:block;width:1rem;margin-left:-.5rem;content:"";border-bottom:1px solid Rgba(var(--t42-bg-mid), 0.75)}.bs-popover-start>.popover-arrow,.bs-popover-auto[data-popper-placement^="left"]>.popover-arrow{right:calc(-.5rem - 1px);width:.5rem;height:1rem}.bs-popover-start>.popover-arrow::before,.bs-popover-auto[data-popper-placement^="left"]>.popover-arrow::before{right:0;border-width:.5rem 0 .5rem .5rem;border-left-color:var(--t42-color-opacity-10)}.bs-popover-start>.popover-arrow::after,.bs-popover-auto[data-popper-placement^="left"]>.popover-arrow::after{right:1px;border-width:.5rem 0 .5rem .5rem;border-left-color:var(--t42-color-opacity-10)}.popover-header{padding:.55rem 1rem;margin-bottom:0;font-size:.75rem;color:var(--t42-link-color);background-color:Rgba(var(--t42-bg-mid), 0.75);border-bottom:1px solid var(--t42-color-opacity-10);border-top-left-radius:0;border-top-right-radius:0}.popover-header:empty{display:none}.popover-body{padding:1rem 1rem;color:var(--t42-content-color)}.popover{backdrop-filter:var(--backdrop-filter)}@keyframes progress-bar-stripes{0%{background-position-x:1.063rem}}.progress{display:flex;height:1.063rem;overflow:hidden;font-size:.6rem;background-color:Rgb(var(--t42-bg-mid));border-radius:0}.progress-bar{display:flex;flex-direction:column;justify-content:center;overflow:hidden;color:#fff;text-align:center;white-space:nowrap;background-color:#007be5;transition:width 0.6s ease}@media (prefers-reduced-motion: reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-size:1.063rem 1.063rem}.progress-bar-animated{animation:1s linear infinite progress-bar-stripes}@media (prefers-reduced-motion: reduce){.progress-bar-animated{animation:none}}.progress{border:var(--t42-border)}.table{--bs-table-bg: rgba(0,0,0,0);--bs-table-accent-bg: rgba(0,0,0,0);--bs-table-striped-color: var(--t42-content-color);--bs-table-striped-bg: rgba(0,0,0,0.05);--bs-table-active-color: var(--t42-content-color);--bs-table-active-bg: rgba(0,0,0,0.1);--bs-table-hover-color: var(--t42-link-color);--bs-table-hover-bg: rgba(0,0,0,0.075);width:100%;margin-bottom:1rem;color:var(--t42-content-color);vertical-align:top;border-color:var(--t42-color-opacity-10)}.table>:not(caption)>*>*{padding:.25rem .313rem;background-color:var(--bs-table-bg);border-bottom-width:1px;box-shadow:inset 0 0 0 9999px var(--bs-table-accent-bg)}.table>tbody{vertical-align:inherit}.table>thead{vertical-align:bottom}.table>:not(:first-child){border-top:2px solid currentColor}.caption-top{caption-side:top}.table-sm>:not(caption)>*>*{padding:.25rem .25rem}.table-bordered>:not(caption)>*{border-width:1px 0}.table-bordered>:not(caption)>*>*{border-width:0 1px}.table-borderless>:not(caption)>*>*{border-bottom-width:0}.table-borderless>:not(:first-child){border-top-width:0}.table-striped>tbody>tr:nth-of-type(odd)>*{--bs-table-accent-bg: var(--bs-table-striped-bg);color:var(--bs-table-striped-color)}.table-active{--bs-table-accent-bg: var(--bs-table-active-bg);color:var(--bs-table-active-color)}.table-hover>tbody>tr:hover>*{--bs-table-accent-bg: var(--bs-table-hover-bg);color:var(--bs-table-hover-color)}.table-primary{--bs-table-bg: #cce5fa;--bs-table-striped-bg: #c2daee;--bs-table-striped-color: #000;--bs-table-active-bg: #b8cee1;--bs-table-active-color: #000;--bs-table-hover-bg: #bdd4e7;--bs-table-hover-color: #000;color:#000;border-color:#b8cee1}.table-secondary{--bs-table-bg: #dfdfdf;--bs-table-striped-bg: #d4d4d4;--bs-table-striped-color: #000;--bs-table-active-bg: #c9c9c9;--bs-table-active-color: #000;--bs-table-hover-bg: #cecece;--bs-table-hover-color: #000;color:#000;border-color:#c9c9c9}.table-success{--bs-table-bg: #d9ecda;--bs-table-striped-bg: #cee0cf;--bs-table-striped-color: #000;--bs-table-active-bg: #c3d4c4;--bs-table-active-color: #000;--bs-table-hover-bg: #c9daca;--bs-table-hover-color: #000;color:#000;border-color:#c3d4c4}.table-info{--bs-table-bg: #daecf1;--bs-table-striped-bg: #cfe0e5;--bs-table-striped-color: #000;--bs-table-active-bg: #c4d4d9;--bs-table-active-color: #000;--bs-table-hover-bg: #cadadf;--bs-table-hover-color: #000;color:#000;border-color:#c4d4d9}.table-warning{--bs-table-bg: #feeed3;--bs-table-striped-bg: #f1e2c8;--bs-table-striped-color: #000;--bs-table-active-bg: #e5d6be;--bs-table-active-color: #000;--bs-table-hover-bg: #ebdcc3;--bs-table-hover-color: #000;color:#000;border-color:#e5d6be}.table-danger{--bs-table-bg: #ffdcd2;--bs-table-striped-bg: #f2d1c8;--bs-table-striped-color: #000;--bs-table-active-bg: #e6c6bd;--bs-table-active-color: #000;--bs-table-hover-bg: #ecccc2;--bs-table-hover-color: #000;color:#000;border-color:#e6c6bd}.table-light{--bs-table-bg: #616161;--bs-table-striped-bg: dimgray;--bs-table-striped-color: #fff;--bs-table-active-bg: #717171;--bs-table-active-color: #fff;--bs-table-hover-bg: #6d6d6d;--bs-table-hover-color: #fff;color:#fff;border-color:#717171}.table-dark{--bs-table-bg: #616161;--bs-table-striped-bg: dimgray;--bs-table-striped-color: #fff;--bs-table-active-bg: #717171;--bs-table-active-color: #fff;--bs-table-hover-bg: #6d6d6d;--bs-table-hover-color: #fff;color:#fff;border-color:#717171}.table-responsive{overflow-x:auto;-webkit-overflow-scrolling:touch}@media (max-width: 575.98px){.table-responsive-sm{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width: 767.98px){.table-responsive-md{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width: 991.98px){.table-responsive-lg{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width: 1199.98px){.table-responsive-xl{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width: 1399.98px){.table-responsive-xxl{overflow-x:auto;-webkit-overflow-scrolling:touch}}.table>:not(:first-child){border-width:0}.table td,.table th{white-space:nowrap;vertical-align:middle}.table a{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border;border-bottom:0.063rem dashed var(--dark);color:var(--t42-content-color)}.table a:hover{border-bottom-color:var(--t42-content-color);border-bottom-style:solid;color:var(--t42-link-color);text-decoration:none}.table thead th{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;border-width:1px 0;color:Hsl(var(--t42-content-color-base), calc(var(--t42-content-color-l) - 20%));font-weight:normal;font-size:83.3%;text-transform:uppercase}.table td{position:relative}.table td .btn,.table td .btn-sm,.table td .btn-group-sm>.btn,.table td .btn-lg,.table td .btn-group-lg>.btn{line-height:1.25rem}.table td .btn-icon i{position:relative;top:0.0625rem}.table tr th:first-child,.table tr td:first-child{padding-left:0.5rem}.table tr th:last-child,.table tr td:last-child{padding-right:0.5rem}.table-hover tbody tr:hover{background-color:var(--t42-table-active-bg)}.table-hover tbody tr:hover a{border-bottom-color:var(--t42-content-color);color:var(--t42-link-color)}.table-responsive{border:0}.tooltip{position:absolute;z-index:1080;display:block;margin:0;font-family:"Montserrat","Helvetica Neue",Arial,sans-serif;font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.65625rem;word-wrap:break-word;opacity:0}.tooltip.show{opacity:1}.tooltip .tooltip-arrow{position:absolute;display:block;width:.8rem;height:.4rem}.tooltip .tooltip-arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-top,.bs-tooltip-auto[data-popper-placement^="top"]{padding:.4rem 0}.bs-tooltip-top .tooltip-arrow,.bs-tooltip-auto[data-popper-placement^="top"] .tooltip-arrow{bottom:0}.bs-tooltip-top .tooltip-arrow::before,.bs-tooltip-auto[data-popper-placement^="top"] .tooltip-arrow::before{top:-1px;border-width:.4rem .4rem 0;border-top-color:var(--t42-tooltip-bg)}.bs-tooltip-end,.bs-tooltip-auto[data-popper-placement^="right"]{padding:0 .4rem}.bs-tooltip-end .tooltip-arrow,.bs-tooltip-auto[data-popper-placement^="right"] .tooltip-arrow{left:0;width:.4rem;height:.8rem}.bs-tooltip-end .tooltip-arrow::before,.bs-tooltip-auto[data-popper-placement^="right"] .tooltip-arrow::before{right:-1px;border-width:.4rem .4rem .4rem 0;border-right-color:var(--t42-tooltip-bg)}.bs-tooltip-bottom,.bs-tooltip-auto[data-popper-placement^="bottom"]{padding:.4rem 0}.bs-tooltip-bottom .tooltip-arrow,.bs-tooltip-auto[data-popper-placement^="bottom"] .tooltip-arrow{top:0}.bs-tooltip-bottom .tooltip-arrow::before,.bs-tooltip-auto[data-popper-placement^="bottom"] .tooltip-arrow::before{bottom:-1px;border-width:0 .4rem .4rem;border-bottom-color:var(--t42-tooltip-bg)}.bs-tooltip-start,.bs-tooltip-auto[data-popper-placement^="left"]{padding:0 .4rem}.bs-tooltip-start .tooltip-arrow,.bs-tooltip-auto[data-popper-placement^="left"] .tooltip-arrow{right:0;width:.4rem;height:.8rem}.bs-tooltip-start .tooltip-arrow::before,.bs-tooltip-auto[data-popper-placement^="left"] .tooltip-arrow::before{left:-1px;border-width:.4rem 0 .4rem .4rem;border-left-color:var(--t42-tooltip-bg)}.tooltip-inner{max-width:200px;padding:.25rem 1rem;color:var(--t42-content-color);text-align:center;background-color:var(--t42-tooltip-bg);border-radius:0}.tooltip .tooltip-inner{border:var(--t42-border);box-shadow:var(--t42-shadow)}.bs-tooltip-top .arrow,.bs-tooltip-auto[data-popper-placement^="top"] .arrow{bottom:1px}.bs-tooltip-top .arrow::before,.bs-tooltip-auto[data-popper-placement^="top"] .arrow::before{border-top-color:var(--t42-color-opacity-10)}.bs-tooltip-bottom .arrow,.bs-tooltip-auto[data-popper-placement^="bottom"] .arrow{top:1px}.bs-tooltip-bottom .arrow::before,.bs-tooltip-auto[data-popper-placement^="bottom"] .arrow::before{border-bottom-color:var(--t42-color-opacity-10)}.bs-tooltip-right .arrow{left:1px}.bs-tooltip-right .arrow::before{border-right-color:var(--t42-color-opacity-10)}.bs-tooltip-left .arrow{right:1px}.bs-tooltip-left .arrow::before{border-left-color:var(--t42-color-opacity-10)}.fade{transition:opacity 0.15s linear}@media (prefers-reduced-motion: reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{height:0;overflow:hidden;transition:height 0.35s ease}@media (prefers-reduced-motion: reduce){.collapsing{transition:none}}.collapsing.collapse-horizontal{width:0;height:auto;transition:width 0.35s ease}@media (prefers-reduced-motion: reduce){.collapsing.collapse-horizontal{transition:none}}mark,.mark{color:var(--white)}pre{background-color:var(--t42-bg-dark)}blockquote,.blockquote{padding:1rem 1rem 0.01rem;border-left:0.25rem solid var(--secondary);background-color:Rgb(var(--t42-bg-dark))}.blockquote-footer{margin-top:-2rem;margin-left:1.25rem;color:var(--t42-content-color-muted);font-size:0.875em}.clearfix::after{display:block;clear:both;content:""}.link-primary{color:#007be5}.link-primary:hover,.link-primary:focus{color:#3395ea}.link-secondary{color:#616161}.link-secondary:hover,.link-secondary:focus{color:#4e4e4e}.link-success{color:#43a047}.link-success:hover,.link-success:focus{color:#69b36c}.link-info{color:#469eb9}.link-info:hover,.link-info:focus{color:#6bb1c7}.link-warning{color:#f9a825}.link-warning:hover,.link-warning:focus{color:#fab951}.link-danger{color:#ff511f}.link-danger:hover,.link-danger:focus{color:#ff744c}.link-light{color:#616161}.link-light:hover,.link-light:focus{color:#4e4e4e}.link-dark{color:#616161}.link-dark:hover,.link-dark:focus{color:#4e4e4e}.ratio{position:relative;width:100%}.ratio::before{display:block;padding-top:var(--bs-aspect-ratio);content:""}.ratio>*{position:absolute;top:0;left:0;width:100%;height:100%}.ratio-1x1{--bs-aspect-ratio: 100%}.ratio-4x3{--bs-aspect-ratio: calc(3 / 4 * 100%)}.ratio-16x9{--bs-aspect-ratio: calc(9 / 16 * 100%)}.ratio-21x9{--bs-aspect-ratio: calc(9 / 21 * 100%)}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}.sticky-top{position:sticky;top:0;z-index:1020}@media (min-width: 576px){.sticky-sm-top{position:sticky;top:0;z-index:1020}}@media (min-width: 768px){.sticky-md-top{position:sticky;top:0;z-index:1020}}@media (min-width: 992px){.sticky-lg-top{position:sticky;top:0;z-index:1020}}@media (min-width: 1200px){.sticky-xl-top{position:sticky;top:0;z-index:1020}}@media (min-width: 1400px){.sticky-xxl-top{position:sticky;top:0;z-index:1020}}.hstack{display:flex;flex-direction:row;align-items:center;align-self:stretch}.vstack{display:flex;flex:1 1 auto;flex-direction:column;align-self:stretch}.visually-hidden,.visually-hidden-focusable:not(:focus):not(:focus-within){position:absolute !important;width:1px !important;height:1px !important;padding:0 !important;margin:-1px !important;overflow:hidden !important;clip:rect(0, 0, 0, 0) !important;white-space:nowrap !important;border:0 !important}.stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.vr{display:inline-block;align-self:stretch;width:1px;min-height:1em;background-color:currentColor;opacity:.25}.align-baseline{vertical-align:baseline !important}.align-top{vertical-align:top !important}.align-middle{vertical-align:middle !important}.align-bottom{vertical-align:bottom !important}.align-text-bottom{vertical-align:text-bottom !important}.align-text-top{vertical-align:text-top !important}.float-start{float:left !important}.float-end{float:right !important}.float-none{float:none !important}.opacity-0{opacity:0 !important}.opacity-25{opacity:.25 !important}.opacity-50{opacity:.5 !important}.opacity-75{opacity:.75 !important}.opacity-100{opacity:1 !important}.overflow-auto{overflow:auto !important}.overflow-hidden{overflow:hidden !important}.overflow-visible{overflow:visible !important}.overflow-scroll{overflow:scroll !important}.d-inline{display:inline !important}.d-inline-block{display:inline-block !important}.d-block{display:block !important}.d-grid{display:grid !important}.d-table{display:table !important}.d-table-row{display:table-row !important}.d-table-cell{display:table-cell !important}.d-flex{display:flex !important}.d-inline-flex{display:inline-flex !important}.d-none{display:none !important}.shadow{box-shadow:0 0.5rem 1rem rgba(0,0,0,0.15) !important}.shadow-sm{box-shadow:0 0.125rem 0.25rem rgba(0,0,0,0.075) !important}.shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,0.175) !important}.shadow-none{box-shadow:none !important}.position-static{position:static !important}.position-relative{position:relative !important}.position-absolute{position:absolute !important}.position-fixed{position:fixed !important}.position-sticky{position:sticky !important}.top-0{top:0 !important}.top-50{top:50% !important}.top-100{top:100% !important}.bottom-0{bottom:0 !important}.bottom-50{bottom:50% !important}.bottom-100{bottom:100% !important}.start-0{left:0 !important}.start-50{left:50% !important}.start-100{left:100% !important}.end-0{right:0 !important}.end-50{right:50% !important}.end-100{right:100% !important}.translate-middle{transform:translate(-50%, -50%) !important}.translate-middle-x{transform:translateX(-50%) !important}.translate-middle-y{transform:translateY(-50%) !important}.border{border:1px solid #dee2e6 !important}.border-0{border:0 !important}.border-top{border-top:1px solid #dee2e6 !important}.border-top-0{border-top:0 !important}.border-end{border-right:1px solid #dee2e6 !important}.border-end-0{border-right:0 !important}.border-bottom{border-bottom:1px solid #dee2e6 !important}.border-bottom-0{border-bottom:0 !important}.border-start{border-left:1px solid #dee2e6 !important}.border-start-0{border-left:0 !important}.border-primary{border-color:#007be5 !important}.border-secondary{border-color:#616161 !important}.border-success{border-color:#43a047 !important}.border-info{border-color:#469eb9 !important}.border-warning{border-color:#f9a825 !important}.border-danger{border-color:#ff511f !important}.border-light{border-color:#616161 !important}.border-dark{border-color:#616161 !important}.border-white{border-color:#fff !important}.border-1{border-width:1px !important}.border-2{border-width:2px !important}.border-3{border-width:3px !important}.border-4{border-width:4px !important}.border-5{border-width:5px !important}.w-25{width:25% !important}.w-50{width:50% !important}.w-75{width:75% !important}.w-100{width:100% !important}.w-auto{width:auto !important}.mw-100{max-width:100% !important}.vw-100{width:100vw !important}.min-vw-100{min-width:100vw !important}.h-25{height:25% !important}.h-50{height:50% !important}.h-75{height:75% !important}.h-100{height:100% !important}.h-auto{height:auto !important}.mh-100{max-height:100% !important}.vh-100{height:100vh !important}.min-vh-100{min-height:100vh !important}.flex-fill{flex:1 1 auto !important}.flex-row{flex-direction:row !important}.flex-column{flex-direction:column !important}.flex-row-reverse{flex-direction:row-reverse !important}.flex-column-reverse{flex-direction:column-reverse !important}.flex-grow-0{flex-grow:0 !important}.flex-grow-1{flex-grow:1 !important}.flex-shrink-0{flex-shrink:0 !important}.flex-shrink-1{flex-shrink:1 !important}.flex-wrap{flex-wrap:wrap !important}.flex-nowrap{flex-wrap:nowrap !important}.flex-wrap-reverse{flex-wrap:wrap-reverse !important}.gap-0{gap:0 !important}.gap-1{gap:.25rem !important}.gap-2{gap:.5rem !important}.gap-3{gap:1rem !important}.gap-4{gap:1.5rem !important}.gap-5{gap:3rem !important}.justify-content-start{justify-content:flex-start !important}.justify-content-end{justify-content:flex-end !important}.justify-content-center{justify-content:center !important}.justify-content-between{justify-content:space-between !important}.justify-content-around{justify-content:space-around !important}.justify-content-evenly{justify-content:space-evenly !important}.align-items-start{align-items:flex-start !important}.align-items-end{align-items:flex-end !important}.align-items-center{align-items:center !important}.align-items-baseline{align-items:baseline !important}.align-items-stretch{align-items:stretch !important}.align-content-start{align-content:flex-start !important}.align-content-end{align-content:flex-end !important}.align-content-center{align-content:center !important}.align-content-between{align-content:space-between !important}.align-content-around{align-content:space-around !important}.align-content-stretch{align-content:stretch !important}.align-self-auto{align-self:auto !important}.align-self-start{align-self:flex-start !important}.align-self-end{align-self:flex-end !important}.align-self-center{align-self:center !important}.align-self-baseline{align-self:baseline !important}.align-self-stretch{align-self:stretch !important}.order-first{order:-1 !important}.order-0{order:0 !important}.order-1{order:1 !important}.order-2{order:2 !important}.order-3{order:3 !important}.order-4{order:4 !important}.order-5{order:5 !important}.order-last{order:6 !important}.m-0{margin:0 !important}.m-1{margin:.25rem !important}.m-2{margin:.5rem !important}.m-3{margin:1rem !important}.m-4{margin:1.5rem !important}.m-5{margin:3rem !important}.m-auto{margin:auto !important}.mx-0{margin-right:0 !important;margin-left:0 !important}.mx-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-3{margin-right:1rem !important;margin-left:1rem !important}.mx-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-5{margin-right:3rem !important;margin-left:3rem !important}.mx-auto{margin-right:auto !important;margin-left:auto !important}.my-0{margin-top:0 !important;margin-bottom:0 !important}.my-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-0{margin-top:0 !important}.mt-1{margin-top:.25rem !important}.mt-2{margin-top:.5rem !important}.mt-3{margin-top:1rem !important}.mt-4{margin-top:1.5rem !important}.mt-5{margin-top:3rem !important}.mt-auto{margin-top:auto !important}.me-0{margin-right:0 !important}.me-1{margin-right:.25rem !important}.me-2{margin-right:.5rem !important}.me-3{margin-right:1rem !important}.me-4{margin-right:1.5rem !important}.me-5{margin-right:3rem !important}.me-auto{margin-right:auto !important}.mb-0{margin-bottom:0 !important}.mb-1{margin-bottom:.25rem !important}.mb-2{margin-bottom:.5rem !important}.mb-3{margin-bottom:1rem !important}.mb-4{margin-bottom:1.5rem !important}.mb-5{margin-bottom:3rem !important}.mb-auto{margin-bottom:auto !important}.ms-0{margin-left:0 !important}.ms-1{margin-left:.25rem !important}.ms-2{margin-left:.5rem !important}.ms-3{margin-left:1rem !important}.ms-4{margin-left:1.5rem !important}.ms-5{margin-left:3rem !important}.ms-auto{margin-left:auto !important}.p-0{padding:0 !important}.p-1{padding:.25rem !important}.p-2{padding:.5rem !important}.p-3{padding:1rem !important}.p-4{padding:1.5rem !important}.p-5{padding:3rem !important}.px-0{padding-right:0 !important;padding-left:0 !important}.px-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-3{padding-right:1rem !important;padding-left:1rem !important}.px-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-5{padding-right:3rem !important;padding-left:3rem !important}.py-0{padding-top:0 !important;padding-bottom:0 !important}.py-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-0{padding-top:0 !important}.pt-1{padding-top:.25rem !important}.pt-2{padding-top:.5rem !important}.pt-3{padding-top:1rem !important}.pt-4{padding-top:1.5rem !important}.pt-5{padding-top:3rem !important}.pe-0{padding-right:0 !important}.pe-1{padding-right:.25rem !important}.pe-2{padding-right:.5rem !important}.pe-3{padding-right:1rem !important}.pe-4{padding-right:1.5rem !important}.pe-5{padding-right:3rem !important}.pb-0{padding-bottom:0 !important}.pb-1{padding-bottom:.25rem !important}.pb-2{padding-bottom:.5rem !important}.pb-3{padding-bottom:1rem !important}.pb-4{padding-bottom:1.5rem !important}.pb-5{padding-bottom:3rem !important}.ps-0{padding-left:0 !important}.ps-1{padding-left:.25rem !important}.ps-2{padding-left:.5rem !important}.ps-3{padding-left:1rem !important}.ps-4{padding-left:1.5rem !important}.ps-5{padding-left:3rem !important}.font-monospace{font-family:var(--bs-font-monospace) !important}.fs-1{font-size:calc(1.26563rem + .1875vw) !important}.fs-2{font-size:1.125rem !important}.fs-3{font-size:.98475rem !important}.fs-4{font-size:.84375rem !important}.fs-5{font-size:.75rem !important}.fs-6{font-size:.7035rem !important}.fst-italic{font-style:italic !important}.fst-normal{font-style:normal !important}.fw-light{font-weight:300 !important}.fw-lighter{font-weight:lighter !important}.fw-normal{font-weight:400 !important}.fw-bold{font-weight:700 !important}.fw-bolder{font-weight:bolder !important}.lh-1{line-height:1 !important}.lh-sm{line-height:1.25 !important}.lh-base{line-height:1.5 !important}.lh-lg{line-height:2 !important}.text-start{text-align:left !important}.text-end{text-align:right !important}.text-center{text-align:center !important}.text-decoration-none{text-decoration:none !important}.text-decoration-underline{text-decoration:underline !important}.text-decoration-line-through{text-decoration:line-through !important}.text-lowercase{text-transform:lowercase !important}.text-uppercase{text-transform:uppercase !important}.text-capitalize{text-transform:capitalize !important}.text-wrap{white-space:normal !important}.text-nowrap{white-space:nowrap !important}.text-break{word-wrap:break-word !important;word-break:break-word !important}.text-primary{--bs-text-opacity: 1;color:rgba(var(--bs-primary-rgb), var(--bs-text-opacity)) !important}.text-secondary{--bs-text-opacity: 1;color:rgba(var(--bs-secondary-rgb), var(--bs-text-opacity)) !important}.text-success{--bs-text-opacity: 1;color:rgba(var(--bs-success-rgb), var(--bs-text-opacity)) !important}.text-info{--bs-text-opacity: 1;color:rgba(var(--bs-info-rgb), var(--bs-text-opacity)) !important}.text-warning{--bs-text-opacity: 1;color:rgba(var(--bs-warning-rgb), var(--bs-text-opacity)) !important}.text-danger{--bs-text-opacity: 1;color:rgba(var(--bs-danger-rgb), var(--bs-text-opacity)) !important}.text-light{--bs-text-opacity: 1;color:rgba(var(--bs-light-rgb), var(--bs-text-opacity)) !important}.text-dark{--bs-text-opacity: 1;color:rgba(var(--bs-dark-rgb), var(--bs-text-opacity)) !important}.text-black{--bs-text-opacity: 1;color:rgba(var(--bs-black-rgb), var(--bs-text-opacity)) !important}.text-white{--bs-text-opacity: 1;color:rgba(var(--bs-white-rgb), var(--bs-text-opacity)) !important}.text-body{--bs-text-opacity: 1;color:rgba(var(--bs-body-color-rgb), var(--bs-text-opacity)) !important}.text-muted{--bs-text-opacity: 1;color:var(--t42-content-color-muted) !important}.text-black-50{--bs-text-opacity: 1;color:rgba(0,0,0,0.5) !important}.text-white-50{--bs-text-opacity: 1;color:rgba(255,255,255,0.5) !important}.text-reset{--bs-text-opacity: 1;color:inherit !important}.text-opacity-25{--bs-text-opacity: .25}.text-opacity-50{--bs-text-opacity: .5}.text-opacity-75{--bs-text-opacity: .75}.text-opacity-100{--bs-text-opacity: 1}.bg-primary{--bs-bg-opacity: 1;background-color:rgba(var(--bs-primary-rgb), var(--bs-bg-opacity)) !important}.bg-secondary{--bs-bg-opacity: 1;background-color:rgba(var(--bs-secondary-rgb), var(--bs-bg-opacity)) !important}.bg-success{--bs-bg-opacity: 1;background-color:rgba(var(--bs-success-rgb), var(--bs-bg-opacity)) !important}.bg-info{--bs-bg-opacity: 1;background-color:rgba(var(--bs-info-rgb), var(--bs-bg-opacity)) !important}.bg-warning{--bs-bg-opacity: 1;background-color:rgba(var(--bs-warning-rgb), var(--bs-bg-opacity)) !important}.bg-danger{--bs-bg-opacity: 1;background-color:rgba(var(--bs-danger-rgb), var(--bs-bg-opacity)) !important}.bg-light{--bs-bg-opacity: 1;background-color:rgba(var(--bs-light-rgb), var(--bs-bg-opacity)) !important}.bg-dark{--bs-bg-opacity: 1;background-color:rgba(var(--bs-dark-rgb), var(--bs-bg-opacity)) !important}.bg-black{--bs-bg-opacity: 1;background-color:rgba(var(--bs-black-rgb), var(--bs-bg-opacity)) !important}.bg-white{--bs-bg-opacity: 1;background-color:rgba(var(--bs-white-rgb), var(--bs-bg-opacity)) !important}.bg-body{--bs-bg-opacity: 1;background-color:rgba(var(--bs-body-bg-rgb), var(--bs-bg-opacity)) !important}.bg-transparent{--bs-bg-opacity: 1;background-color:rgba(0,0,0,0) !important}.bg-opacity-10{--bs-bg-opacity: .1}.bg-opacity-25{--bs-bg-opacity: .25}.bg-opacity-50{--bs-bg-opacity: .5}.bg-opacity-75{--bs-bg-opacity: .75}.bg-opacity-100{--bs-bg-opacity: 1}.bg-gradient{background-image:var(--bs-gradient) !important}.user-select-all{user-select:all !important}.user-select-auto{user-select:auto !important}.user-select-none{user-select:none !important}.pe-none{pointer-events:none !important}.pe-auto{pointer-events:auto !important}.rounded{border-radius:.25rem !important}.rounded-0{border-radius:0 !important}.rounded-1{border-radius:.25rem !important}.rounded-2{border-radius:.25rem !important}.rounded-3{border-radius:1rem !important}.rounded-circle{border-radius:50% !important}.rounded-pill{border-radius:50rem !important}.rounded-top{border-top-left-radius:.25rem !important;border-top-right-radius:.25rem !important}.rounded-end{border-top-right-radius:.25rem !important;border-bottom-right-radius:.25rem !important}.rounded-bottom{border-bottom-right-radius:.25rem !important;border-bottom-left-radius:.25rem !important}.rounded-start{border-bottom-left-radius:.25rem !important;border-top-left-radius:.25rem !important}.visible{visibility:visible !important}.invisible{visibility:hidden !important}@media (min-width: 576px){.float-sm-start{float:left !important}.float-sm-end{float:right !important}.float-sm-none{float:none !important}.d-sm-inline{display:inline !important}.d-sm-inline-block{display:inline-block !important}.d-sm-block{display:block !important}.d-sm-grid{display:grid !important}.d-sm-table{display:table !important}.d-sm-table-row{display:table-row !important}.d-sm-table-cell{display:table-cell !important}.d-sm-flex{display:flex !important}.d-sm-inline-flex{display:inline-flex !important}.d-sm-none{display:none !important}.flex-sm-fill{flex:1 1 auto !important}.flex-sm-row{flex-direction:row !important}.flex-sm-column{flex-direction:column !important}.flex-sm-row-reverse{flex-direction:row-reverse !important}.flex-sm-column-reverse{flex-direction:column-reverse !important}.flex-sm-grow-0{flex-grow:0 !important}.flex-sm-grow-1{flex-grow:1 !important}.flex-sm-shrink-0{flex-shrink:0 !important}.flex-sm-shrink-1{flex-shrink:1 !important}.flex-sm-wrap{flex-wrap:wrap !important}.flex-sm-nowrap{flex-wrap:nowrap !important}.flex-sm-wrap-reverse{flex-wrap:wrap-reverse !important}.gap-sm-0{gap:0 !important}.gap-sm-1{gap:.25rem !important}.gap-sm-2{gap:.5rem !important}.gap-sm-3{gap:1rem !important}.gap-sm-4{gap:1.5rem !important}.gap-sm-5{gap:3rem !important}.justify-content-sm-start{justify-content:flex-start !important}.justify-content-sm-end{justify-content:flex-end !important}.justify-content-sm-center{justify-content:center !important}.justify-content-sm-between{justify-content:space-between !important}.justify-content-sm-around{justify-content:space-around !important}.justify-content-sm-evenly{justify-content:space-evenly !important}.align-items-sm-start{align-items:flex-start !important}.align-items-sm-end{align-items:flex-end !important}.align-items-sm-center{align-items:center !important}.align-items-sm-baseline{align-items:baseline !important}.align-items-sm-stretch{align-items:stretch !important}.align-content-sm-start{align-content:flex-start !important}.align-content-sm-end{align-content:flex-end !important}.align-content-sm-center{align-content:center !important}.align-content-sm-between{align-content:space-between !important}.align-content-sm-around{align-content:space-around !important}.align-content-sm-stretch{align-content:stretch !important}.align-self-sm-auto{align-self:auto !important}.align-self-sm-start{align-self:flex-start !important}.align-self-sm-end{align-self:flex-end !important}.align-self-sm-center{align-self:center !important}.align-self-sm-baseline{align-self:baseline !important}.align-self-sm-stretch{align-self:stretch !important}.order-sm-first{order:-1 !important}.order-sm-0{order:0 !important}.order-sm-1{order:1 !important}.order-sm-2{order:2 !important}.order-sm-3{order:3 !important}.order-sm-4{order:4 !important}.order-sm-5{order:5 !important}.order-sm-last{order:6 !important}.m-sm-0{margin:0 !important}.m-sm-1{margin:.25rem !important}.m-sm-2{margin:.5rem !important}.m-sm-3{margin:1rem !important}.m-sm-4{margin:1.5rem !important}.m-sm-5{margin:3rem !important}.m-sm-auto{margin:auto !important}.mx-sm-0{margin-right:0 !important;margin-left:0 !important}.mx-sm-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-sm-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-sm-3{margin-right:1rem !important;margin-left:1rem !important}.mx-sm-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-sm-5{margin-right:3rem !important;margin-left:3rem !important}.mx-sm-auto{margin-right:auto !important;margin-left:auto !important}.my-sm-0{margin-top:0 !important;margin-bottom:0 !important}.my-sm-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-sm-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-sm-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-sm-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-sm-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-sm-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-sm-0{margin-top:0 !important}.mt-sm-1{margin-top:.25rem !important}.mt-sm-2{margin-top:.5rem !important}.mt-sm-3{margin-top:1rem !important}.mt-sm-4{margin-top:1.5rem !important}.mt-sm-5{margin-top:3rem !important}.mt-sm-auto{margin-top:auto !important}.me-sm-0{margin-right:0 !important}.me-sm-1{margin-right:.25rem !important}.me-sm-2{margin-right:.5rem !important}.me-sm-3{margin-right:1rem !important}.me-sm-4{margin-right:1.5rem !important}.me-sm-5{margin-right:3rem !important}.me-sm-auto{margin-right:auto !important}.mb-sm-0{margin-bottom:0 !important}.mb-sm-1{margin-bottom:.25rem !important}.mb-sm-2{margin-bottom:.5rem !important}.mb-sm-3{margin-bottom:1rem !important}.mb-sm-4{margin-bottom:1.5rem !important}.mb-sm-5{margin-bottom:3rem !important}.mb-sm-auto{margin-bottom:auto !important}.ms-sm-0{margin-left:0 !important}.ms-sm-1{margin-left:.25rem !important}.ms-sm-2{margin-left:.5rem !important}.ms-sm-3{margin-left:1rem !important}.ms-sm-4{margin-left:1.5rem !important}.ms-sm-5{margin-left:3rem !important}.ms-sm-auto{margin-left:auto !important}.p-sm-0{padding:0 !important}.p-sm-1{padding:.25rem !important}.p-sm-2{padding:.5rem !important}.p-sm-3{padding:1rem !important}.p-sm-4{padding:1.5rem !important}.p-sm-5{padding:3rem !important}.px-sm-0{padding-right:0 !important;padding-left:0 !important}.px-sm-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-sm-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-sm-3{padding-right:1rem !important;padding-left:1rem !important}.px-sm-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-sm-5{padding-right:3rem !important;padding-left:3rem !important}.py-sm-0{padding-top:0 !important;padding-bottom:0 !important}.py-sm-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-sm-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-sm-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-sm-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-sm-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-sm-0{padding-top:0 !important}.pt-sm-1{padding-top:.25rem !important}.pt-sm-2{padding-top:.5rem !important}.pt-sm-3{padding-top:1rem !important}.pt-sm-4{padding-top:1.5rem !important}.pt-sm-5{padding-top:3rem !important}.pe-sm-0{padding-right:0 !important}.pe-sm-1{padding-right:.25rem !important}.pe-sm-2{padding-right:.5rem !important}.pe-sm-3{padding-right:1rem !important}.pe-sm-4{padding-right:1.5rem !important}.pe-sm-5{padding-right:3rem !important}.pb-sm-0{padding-bottom:0 !important}.pb-sm-1{padding-bottom:.25rem !important}.pb-sm-2{padding-bottom:.5rem !important}.pb-sm-3{padding-bottom:1rem !important}.pb-sm-4{padding-bottom:1.5rem !important}.pb-sm-5{padding-bottom:3rem !important}.ps-sm-0{padding-left:0 !important}.ps-sm-1{padding-left:.25rem !important}.ps-sm-2{padding-left:.5rem !important}.ps-sm-3{padding-left:1rem !important}.ps-sm-4{padding-left:1.5rem !important}.ps-sm-5{padding-left:3rem !important}.text-sm-start{text-align:left !important}.text-sm-end{text-align:right !important}.text-sm-center{text-align:center !important}}@media (min-width: 768px){.float-md-start{float:left !important}.float-md-end{float:right !important}.float-md-none{float:none !important}.d-md-inline{display:inline !important}.d-md-inline-block{display:inline-block !important}.d-md-block{display:block !important}.d-md-grid{display:grid !important}.d-md-table{display:table !important}.d-md-table-row{display:table-row !important}.d-md-table-cell{display:table-cell !important}.d-md-flex{display:flex !important}.d-md-inline-flex{display:inline-flex !important}.d-md-none{display:none !important}.flex-md-fill{flex:1 1 auto !important}.flex-md-row{flex-direction:row !important}.flex-md-column{flex-direction:column !important}.flex-md-row-reverse{flex-direction:row-reverse !important}.flex-md-column-reverse{flex-direction:column-reverse !important}.flex-md-grow-0{flex-grow:0 !important}.flex-md-grow-1{flex-grow:1 !important}.flex-md-shrink-0{flex-shrink:0 !important}.flex-md-shrink-1{flex-shrink:1 !important}.flex-md-wrap{flex-wrap:wrap !important}.flex-md-nowrap{flex-wrap:nowrap !important}.flex-md-wrap-reverse{flex-wrap:wrap-reverse !important}.gap-md-0{gap:0 !important}.gap-md-1{gap:.25rem !important}.gap-md-2{gap:.5rem !important}.gap-md-3{gap:1rem !important}.gap-md-4{gap:1.5rem !important}.gap-md-5{gap:3rem !important}.justify-content-md-start{justify-content:flex-start !important}.justify-content-md-end{justify-content:flex-end !important}.justify-content-md-center{justify-content:center !important}.justify-content-md-between{justify-content:space-between !important}.justify-content-md-around{justify-content:space-around !important}.justify-content-md-evenly{justify-content:space-evenly !important}.align-items-md-start{align-items:flex-start !important}.align-items-md-end{align-items:flex-end !important}.align-items-md-center{align-items:center !important}.align-items-md-baseline{align-items:baseline !important}.align-items-md-stretch{align-items:stretch !important}.align-content-md-start{align-content:flex-start !important}.align-content-md-end{align-content:flex-end !important}.align-content-md-center{align-content:center !important}.align-content-md-between{align-content:space-between !important}.align-content-md-around{align-content:space-around !important}.align-content-md-stretch{align-content:stretch !important}.align-self-md-auto{align-self:auto !important}.align-self-md-start{align-self:flex-start !important}.align-self-md-end{align-self:flex-end !important}.align-self-md-center{align-self:center !important}.align-self-md-baseline{align-self:baseline !important}.align-self-md-stretch{align-self:stretch !important}.order-md-first{order:-1 !important}.order-md-0{order:0 !important}.order-md-1{order:1 !important}.order-md-2{order:2 !important}.order-md-3{order:3 !important}.order-md-4{order:4 !important}.order-md-5{order:5 !important}.order-md-last{order:6 !important}.m-md-0{margin:0 !important}.m-md-1{margin:.25rem !important}.m-md-2{margin:.5rem !important}.m-md-3{margin:1rem !important}.m-md-4{margin:1.5rem !important}.m-md-5{margin:3rem !important}.m-md-auto{margin:auto !important}.mx-md-0{margin-right:0 !important;margin-left:0 !important}.mx-md-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-md-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-md-3{margin-right:1rem !important;margin-left:1rem !important}.mx-md-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-md-5{margin-right:3rem !important;margin-left:3rem !important}.mx-md-auto{margin-right:auto !important;margin-left:auto !important}.my-md-0{margin-top:0 !important;margin-bottom:0 !important}.my-md-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-md-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-md-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-md-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-md-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-md-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-md-0{margin-top:0 !important}.mt-md-1{margin-top:.25rem !important}.mt-md-2{margin-top:.5rem !important}.mt-md-3{margin-top:1rem !important}.mt-md-4{margin-top:1.5rem !important}.mt-md-5{margin-top:3rem !important}.mt-md-auto{margin-top:auto !important}.me-md-0{margin-right:0 !important}.me-md-1{margin-right:.25rem !important}.me-md-2{margin-right:.5rem !important}.me-md-3{margin-right:1rem !important}.me-md-4{margin-right:1.5rem !important}.me-md-5{margin-right:3rem !important}.me-md-auto{margin-right:auto !important}.mb-md-0{margin-bottom:0 !important}.mb-md-1{margin-bottom:.25rem !important}.mb-md-2{margin-bottom:.5rem !important}.mb-md-3{margin-bottom:1rem !important}.mb-md-4{margin-bottom:1.5rem !important}.mb-md-5{margin-bottom:3rem !important}.mb-md-auto{margin-bottom:auto !important}.ms-md-0{margin-left:0 !important}.ms-md-1{margin-left:.25rem !important}.ms-md-2{margin-left:.5rem !important}.ms-md-3{margin-left:1rem !important}.ms-md-4{margin-left:1.5rem !important}.ms-md-5{margin-left:3rem !important}.ms-md-auto{margin-left:auto !important}.p-md-0{padding:0 !important}.p-md-1{padding:.25rem !important}.p-md-2{padding:.5rem !important}.p-md-3{padding:1rem !important}.p-md-4{padding:1.5rem !important}.p-md-5{padding:3rem !important}.px-md-0{padding-right:0 !important;padding-left:0 !important}.px-md-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-md-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-md-3{padding-right:1rem !important;padding-left:1rem !important}.px-md-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-md-5{padding-right:3rem !important;padding-left:3rem !important}.py-md-0{padding-top:0 !important;padding-bottom:0 !important}.py-md-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-md-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-md-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-md-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-md-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-md-0{padding-top:0 !important}.pt-md-1{padding-top:.25rem !important}.pt-md-2{padding-top:.5rem !important}.pt-md-3{padding-top:1rem !important}.pt-md-4{padding-top:1.5rem !important}.pt-md-5{padding-top:3rem !important}.pe-md-0{padding-right:0 !important}.pe-md-1{padding-right:.25rem !important}.pe-md-2{padding-right:.5rem !important}.pe-md-3{padding-right:1rem !important}.pe-md-4{padding-right:1.5rem !important}.pe-md-5{padding-right:3rem !important}.pb-md-0{padding-bottom:0 !important}.pb-md-1{padding-bottom:.25rem !important}.pb-md-2{padding-bottom:.5rem !important}.pb-md-3{padding-bottom:1rem !important}.pb-md-4{padding-bottom:1.5rem !important}.pb-md-5{padding-bottom:3rem !important}.ps-md-0{padding-left:0 !important}.ps-md-1{padding-left:.25rem !important}.ps-md-2{padding-left:.5rem !important}.ps-md-3{padding-left:1rem !important}.ps-md-4{padding-left:1.5rem !important}.ps-md-5{padding-left:3rem !important}.text-md-start{text-align:left !important}.text-md-end{text-align:right !important}.text-md-center{text-align:center !important}}@media (min-width: 992px){.float-lg-start{float:left !important}.float-lg-end{float:right !important}.float-lg-none{float:none !important}.d-lg-inline{display:inline !important}.d-lg-inline-block{display:inline-block !important}.d-lg-block{display:block !important}.d-lg-grid{display:grid !important}.d-lg-table{display:table !important}.d-lg-table-row{display:table-row !important}.d-lg-table-cell{display:table-cell !important}.d-lg-flex{display:flex !important}.d-lg-inline-flex{display:inline-flex !important}.d-lg-none{display:none !important}.flex-lg-fill{flex:1 1 auto !important}.flex-lg-row{flex-direction:row !important}.flex-lg-column{flex-direction:column !important}.flex-lg-row-reverse{flex-direction:row-reverse !important}.flex-lg-column-reverse{flex-direction:column-reverse !important}.flex-lg-grow-0{flex-grow:0 !important}.flex-lg-grow-1{flex-grow:1 !important}.flex-lg-shrink-0{flex-shrink:0 !important}.flex-lg-shrink-1{flex-shrink:1 !important}.flex-lg-wrap{flex-wrap:wrap !important}.flex-lg-nowrap{flex-wrap:nowrap !important}.flex-lg-wrap-reverse{flex-wrap:wrap-reverse !important}.gap-lg-0{gap:0 !important}.gap-lg-1{gap:.25rem !important}.gap-lg-2{gap:.5rem !important}.gap-lg-3{gap:1rem !important}.gap-lg-4{gap:1.5rem !important}.gap-lg-5{gap:3rem !important}.justify-content-lg-start{justify-content:flex-start !important}.justify-content-lg-end{justify-content:flex-end !important}.justify-content-lg-center{justify-content:center !important}.justify-content-lg-between{justify-content:space-between !important}.justify-content-lg-around{justify-content:space-around !important}.justify-content-lg-evenly{justify-content:space-evenly !important}.align-items-lg-start{align-items:flex-start !important}.align-items-lg-end{align-items:flex-end !important}.align-items-lg-center{align-items:center !important}.align-items-lg-baseline{align-items:baseline !important}.align-items-lg-stretch{align-items:stretch !important}.align-content-lg-start{align-content:flex-start !important}.align-content-lg-end{align-content:flex-end !important}.align-content-lg-center{align-content:center !important}.align-content-lg-between{align-content:space-between !important}.align-content-lg-around{align-content:space-around !important}.align-content-lg-stretch{align-content:stretch !important}.align-self-lg-auto{align-self:auto !important}.align-self-lg-start{align-self:flex-start !important}.align-self-lg-end{align-self:flex-end !important}.align-self-lg-center{align-self:center !important}.align-self-lg-baseline{align-self:baseline !important}.align-self-lg-stretch{align-self:stretch !important}.order-lg-first{order:-1 !important}.order-lg-0{order:0 !important}.order-lg-1{order:1 !important}.order-lg-2{order:2 !important}.order-lg-3{order:3 !important}.order-lg-4{order:4 !important}.order-lg-5{order:5 !important}.order-lg-last{order:6 !important}.m-lg-0{margin:0 !important}.m-lg-1{margin:.25rem !important}.m-lg-2{margin:.5rem !important}.m-lg-3{margin:1rem !important}.m-lg-4{margin:1.5rem !important}.m-lg-5{margin:3rem !important}.m-lg-auto{margin:auto !important}.mx-lg-0{margin-right:0 !important;margin-left:0 !important}.mx-lg-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-lg-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-lg-3{margin-right:1rem !important;margin-left:1rem !important}.mx-lg-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-lg-5{margin-right:3rem !important;margin-left:3rem !important}.mx-lg-auto{margin-right:auto !important;margin-left:auto !important}.my-lg-0{margin-top:0 !important;margin-bottom:0 !important}.my-lg-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-lg-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-lg-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-lg-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-lg-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-lg-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-lg-0{margin-top:0 !important}.mt-lg-1{margin-top:.25rem !important}.mt-lg-2{margin-top:.5rem !important}.mt-lg-3{margin-top:1rem !important}.mt-lg-4{margin-top:1.5rem !important}.mt-lg-5{margin-top:3rem !important}.mt-lg-auto{margin-top:auto !important}.me-lg-0{margin-right:0 !important}.me-lg-1{margin-right:.25rem !important}.me-lg-2{margin-right:.5rem !important}.me-lg-3{margin-right:1rem !important}.me-lg-4{margin-right:1.5rem !important}.me-lg-5{margin-right:3rem !important}.me-lg-auto{margin-right:auto !important}.mb-lg-0{margin-bottom:0 !important}.mb-lg-1{margin-bottom:.25rem !important}.mb-lg-2{margin-bottom:.5rem !important}.mb-lg-3{margin-bottom:1rem !important}.mb-lg-4{margin-bottom:1.5rem !important}.mb-lg-5{margin-bottom:3rem !important}.mb-lg-auto{margin-bottom:auto !important}.ms-lg-0{margin-left:0 !important}.ms-lg-1{margin-left:.25rem !important}.ms-lg-2{margin-left:.5rem !important}.ms-lg-3{margin-left:1rem !important}.ms-lg-4{margin-left:1.5rem !important}.ms-lg-5{margin-left:3rem !important}.ms-lg-auto{margin-left:auto !important}.p-lg-0{padding:0 !important}.p-lg-1{padding:.25rem !important}.p-lg-2{padding:.5rem !important}.p-lg-3{padding:1rem !important}.p-lg-4{padding:1.5rem !important}.p-lg-5{padding:3rem !important}.px-lg-0{padding-right:0 !important;padding-left:0 !important}.px-lg-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-lg-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-lg-3{padding-right:1rem !important;padding-left:1rem !important}.px-lg-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-lg-5{padding-right:3rem !important;padding-left:3rem !important}.py-lg-0{padding-top:0 !important;padding-bottom:0 !important}.py-lg-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-lg-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-lg-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-lg-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-lg-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-lg-0{padding-top:0 !important}.pt-lg-1{padding-top:.25rem !important}.pt-lg-2{padding-top:.5rem !important}.pt-lg-3{padding-top:1rem !important}.pt-lg-4{padding-top:1.5rem !important}.pt-lg-5{padding-top:3rem !important}.pe-lg-0{padding-right:0 !important}.pe-lg-1{padding-right:.25rem !important}.pe-lg-2{padding-right:.5rem !important}.pe-lg-3{padding-right:1rem !important}.pe-lg-4{padding-right:1.5rem !important}.pe-lg-5{padding-right:3rem !important}.pb-lg-0{padding-bottom:0 !important}.pb-lg-1{padding-bottom:.25rem !important}.pb-lg-2{padding-bottom:.5rem !important}.pb-lg-3{padding-bottom:1rem !important}.pb-lg-4{padding-bottom:1.5rem !important}.pb-lg-5{padding-bottom:3rem !important}.ps-lg-0{padding-left:0 !important}.ps-lg-1{padding-left:.25rem !important}.ps-lg-2{padding-left:.5rem !important}.ps-lg-3{padding-left:1rem !important}.ps-lg-4{padding-left:1.5rem !important}.ps-lg-5{padding-left:3rem !important}.text-lg-start{text-align:left !important}.text-lg-end{text-align:right !important}.text-lg-center{text-align:center !important}}@media (min-width: 1200px){.float-xl-start{float:left !important}.float-xl-end{float:right !important}.float-xl-none{float:none !important}.d-xl-inline{display:inline !important}.d-xl-inline-block{display:inline-block !important}.d-xl-block{display:block !important}.d-xl-grid{display:grid !important}.d-xl-table{display:table !important}.d-xl-table-row{display:table-row !important}.d-xl-table-cell{display:table-cell !important}.d-xl-flex{display:flex !important}.d-xl-inline-flex{display:inline-flex !important}.d-xl-none{display:none !important}.flex-xl-fill{flex:1 1 auto !important}.flex-xl-row{flex-direction:row !important}.flex-xl-column{flex-direction:column !important}.flex-xl-row-reverse{flex-direction:row-reverse !important}.flex-xl-column-reverse{flex-direction:column-reverse !important}.flex-xl-grow-0{flex-grow:0 !important}.flex-xl-grow-1{flex-grow:1 !important}.flex-xl-shrink-0{flex-shrink:0 !important}.flex-xl-shrink-1{flex-shrink:1 !important}.flex-xl-wrap{flex-wrap:wrap !important}.flex-xl-nowrap{flex-wrap:nowrap !important}.flex-xl-wrap-reverse{flex-wrap:wrap-reverse !important}.gap-xl-0{gap:0 !important}.gap-xl-1{gap:.25rem !important}.gap-xl-2{gap:.5rem !important}.gap-xl-3{gap:1rem !important}.gap-xl-4{gap:1.5rem !important}.gap-xl-5{gap:3rem !important}.justify-content-xl-start{justify-content:flex-start !important}.justify-content-xl-end{justify-content:flex-end !important}.justify-content-xl-center{justify-content:center !important}.justify-content-xl-between{justify-content:space-between !important}.justify-content-xl-around{justify-content:space-around !important}.justify-content-xl-evenly{justify-content:space-evenly !important}.align-items-xl-start{align-items:flex-start !important}.align-items-xl-end{align-items:flex-end !important}.align-items-xl-center{align-items:center !important}.align-items-xl-baseline{align-items:baseline !important}.align-items-xl-stretch{align-items:stretch !important}.align-content-xl-start{align-content:flex-start !important}.align-content-xl-end{align-content:flex-end !important}.align-content-xl-center{align-content:center !important}.align-content-xl-between{align-content:space-between !important}.align-content-xl-around{align-content:space-around !important}.align-content-xl-stretch{align-content:stretch !important}.align-self-xl-auto{align-self:auto !important}.align-self-xl-start{align-self:flex-start !important}.align-self-xl-end{align-self:flex-end !important}.align-self-xl-center{align-self:center !important}.align-self-xl-baseline{align-self:baseline !important}.align-self-xl-stretch{align-self:stretch !important}.order-xl-first{order:-1 !important}.order-xl-0{order:0 !important}.order-xl-1{order:1 !important}.order-xl-2{order:2 !important}.order-xl-3{order:3 !important}.order-xl-4{order:4 !important}.order-xl-5{order:5 !important}.order-xl-last{order:6 !important}.m-xl-0{margin:0 !important}.m-xl-1{margin:.25rem !important}.m-xl-2{margin:.5rem !important}.m-xl-3{margin:1rem !important}.m-xl-4{margin:1.5rem !important}.m-xl-5{margin:3rem !important}.m-xl-auto{margin:auto !important}.mx-xl-0{margin-right:0 !important;margin-left:0 !important}.mx-xl-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-xl-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-xl-3{margin-right:1rem !important;margin-left:1rem !important}.mx-xl-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-xl-5{margin-right:3rem !important;margin-left:3rem !important}.mx-xl-auto{margin-right:auto !important;margin-left:auto !important}.my-xl-0{margin-top:0 !important;margin-bottom:0 !important}.my-xl-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-xl-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-xl-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-xl-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-xl-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-xl-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-xl-0{margin-top:0 !important}.mt-xl-1{margin-top:.25rem !important}.mt-xl-2{margin-top:.5rem !important}.mt-xl-3{margin-top:1rem !important}.mt-xl-4{margin-top:1.5rem !important}.mt-xl-5{margin-top:3rem !important}.mt-xl-auto{margin-top:auto !important}.me-xl-0{margin-right:0 !important}.me-xl-1{margin-right:.25rem !important}.me-xl-2{margin-right:.5rem !important}.me-xl-3{margin-right:1rem !important}.me-xl-4{margin-right:1.5rem !important}.me-xl-5{margin-right:3rem !important}.me-xl-auto{margin-right:auto !important}.mb-xl-0{margin-bottom:0 !important}.mb-xl-1{margin-bottom:.25rem !important}.mb-xl-2{margin-bottom:.5rem !important}.mb-xl-3{margin-bottom:1rem !important}.mb-xl-4{margin-bottom:1.5rem !important}.mb-xl-5{margin-bottom:3rem !important}.mb-xl-auto{margin-bottom:auto !important}.ms-xl-0{margin-left:0 !important}.ms-xl-1{margin-left:.25rem !important}.ms-xl-2{margin-left:.5rem !important}.ms-xl-3{margin-left:1rem !important}.ms-xl-4{margin-left:1.5rem !important}.ms-xl-5{margin-left:3rem !important}.ms-xl-auto{margin-left:auto !important}.p-xl-0{padding:0 !important}.p-xl-1{padding:.25rem !important}.p-xl-2{padding:.5rem !important}.p-xl-3{padding:1rem !important}.p-xl-4{padding:1.5rem !important}.p-xl-5{padding:3rem !important}.px-xl-0{padding-right:0 !important;padding-left:0 !important}.px-xl-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-xl-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-xl-3{padding-right:1rem !important;padding-left:1rem !important}.px-xl-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-xl-5{padding-right:3rem !important;padding-left:3rem !important}.py-xl-0{padding-top:0 !important;padding-bottom:0 !important}.py-xl-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-xl-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-xl-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-xl-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-xl-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-xl-0{padding-top:0 !important}.pt-xl-1{padding-top:.25rem !important}.pt-xl-2{padding-top:.5rem !important}.pt-xl-3{padding-top:1rem !important}.pt-xl-4{padding-top:1.5rem !important}.pt-xl-5{padding-top:3rem !important}.pe-xl-0{padding-right:0 !important}.pe-xl-1{padding-right:.25rem !important}.pe-xl-2{padding-right:.5rem !important}.pe-xl-3{padding-right:1rem !important}.pe-xl-4{padding-right:1.5rem !important}.pe-xl-5{padding-right:3rem !important}.pb-xl-0{padding-bottom:0 !important}.pb-xl-1{padding-bottom:.25rem !important}.pb-xl-2{padding-bottom:.5rem !important}.pb-xl-3{padding-bottom:1rem !important}.pb-xl-4{padding-bottom:1.5rem !important}.pb-xl-5{padding-bottom:3rem !important}.ps-xl-0{padding-left:0 !important}.ps-xl-1{padding-left:.25rem !important}.ps-xl-2{padding-left:.5rem !important}.ps-xl-3{padding-left:1rem !important}.ps-xl-4{padding-left:1.5rem !important}.ps-xl-5{padding-left:3rem !important}.text-xl-start{text-align:left !important}.text-xl-end{text-align:right !important}.text-xl-center{text-align:center !important}}@media (min-width: 1400px){.float-xxl-start{float:left !important}.float-xxl-end{float:right !important}.float-xxl-none{float:none !important}.d-xxl-inline{display:inline !important}.d-xxl-inline-block{display:inline-block !important}.d-xxl-block{display:block !important}.d-xxl-grid{display:grid !important}.d-xxl-table{display:table !important}.d-xxl-table-row{display:table-row !important}.d-xxl-table-cell{display:table-cell !important}.d-xxl-flex{display:flex !important}.d-xxl-inline-flex{display:inline-flex !important}.d-xxl-none{display:none !important}.flex-xxl-fill{flex:1 1 auto !important}.flex-xxl-row{flex-direction:row !important}.flex-xxl-column{flex-direction:column !important}.flex-xxl-row-reverse{flex-direction:row-reverse !important}.flex-xxl-column-reverse{flex-direction:column-reverse !important}.flex-xxl-grow-0{flex-grow:0 !important}.flex-xxl-grow-1{flex-grow:1 !important}.flex-xxl-shrink-0{flex-shrink:0 !important}.flex-xxl-shrink-1{flex-shrink:1 !important}.flex-xxl-wrap{flex-wrap:wrap !important}.flex-xxl-nowrap{flex-wrap:nowrap !important}.flex-xxl-wrap-reverse{flex-wrap:wrap-reverse !important}.gap-xxl-0{gap:0 !important}.gap-xxl-1{gap:.25rem !important}.gap-xxl-2{gap:.5rem !important}.gap-xxl-3{gap:1rem !important}.gap-xxl-4{gap:1.5rem !important}.gap-xxl-5{gap:3rem !important}.justify-content-xxl-start{justify-content:flex-start !important}.justify-content-xxl-end{justify-content:flex-end !important}.justify-content-xxl-center{justify-content:center !important}.justify-content-xxl-between{justify-content:space-between !important}.justify-content-xxl-around{justify-content:space-around !important}.justify-content-xxl-evenly{justify-content:space-evenly !important}.align-items-xxl-start{align-items:flex-start !important}.align-items-xxl-end{align-items:flex-end !important}.align-items-xxl-center{align-items:center !important}.align-items-xxl-baseline{align-items:baseline !important}.align-items-xxl-stretch{align-items:stretch !important}.align-content-xxl-start{align-content:flex-start !important}.align-content-xxl-end{align-content:flex-end !important}.align-content-xxl-center{align-content:center !important}.align-content-xxl-between{align-content:space-between !important}.align-content-xxl-around{align-content:space-around !important}.align-content-xxl-stretch{align-content:stretch !important}.align-self-xxl-auto{align-self:auto !important}.align-self-xxl-start{align-self:flex-start !important}.align-self-xxl-end{align-self:flex-end !important}.align-self-xxl-center{align-self:center !important}.align-self-xxl-baseline{align-self:baseline !important}.align-self-xxl-stretch{align-self:stretch !important}.order-xxl-first{order:-1 !important}.order-xxl-0{order:0 !important}.order-xxl-1{order:1 !important}.order-xxl-2{order:2 !important}.order-xxl-3{order:3 !important}.order-xxl-4{order:4 !important}.order-xxl-5{order:5 !important}.order-xxl-last{order:6 !important}.m-xxl-0{margin:0 !important}.m-xxl-1{margin:.25rem !important}.m-xxl-2{margin:.5rem !important}.m-xxl-3{margin:1rem !important}.m-xxl-4{margin:1.5rem !important}.m-xxl-5{margin:3rem !important}.m-xxl-auto{margin:auto !important}.mx-xxl-0{margin-right:0 !important;margin-left:0 !important}.mx-xxl-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-xxl-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-xxl-3{margin-right:1rem !important;margin-left:1rem !important}.mx-xxl-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-xxl-5{margin-right:3rem !important;margin-left:3rem !important}.mx-xxl-auto{margin-right:auto !important;margin-left:auto !important}.my-xxl-0{margin-top:0 !important;margin-bottom:0 !important}.my-xxl-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-xxl-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-xxl-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-xxl-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-xxl-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-xxl-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-xxl-0{margin-top:0 !important}.mt-xxl-1{margin-top:.25rem !important}.mt-xxl-2{margin-top:.5rem !important}.mt-xxl-3{margin-top:1rem !important}.mt-xxl-4{margin-top:1.5rem !important}.mt-xxl-5{margin-top:3rem !important}.mt-xxl-auto{margin-top:auto !important}.me-xxl-0{margin-right:0 !important}.me-xxl-1{margin-right:.25rem !important}.me-xxl-2{margin-right:.5rem !important}.me-xxl-3{margin-right:1rem !important}.me-xxl-4{margin-right:1.5rem !important}.me-xxl-5{margin-right:3rem !important}.me-xxl-auto{margin-right:auto !important}.mb-xxl-0{margin-bottom:0 !important}.mb-xxl-1{margin-bottom:.25rem !important}.mb-xxl-2{margin-bottom:.5rem !important}.mb-xxl-3{margin-bottom:1rem !important}.mb-xxl-4{margin-bottom:1.5rem !important}.mb-xxl-5{margin-bottom:3rem !important}.mb-xxl-auto{margin-bottom:auto !important}.ms-xxl-0{margin-left:0 !important}.ms-xxl-1{margin-left:.25rem !important}.ms-xxl-2{margin-left:.5rem !important}.ms-xxl-3{margin-left:1rem !important}.ms-xxl-4{margin-left:1.5rem !important}.ms-xxl-5{margin-left:3rem !important}.ms-xxl-auto{margin-left:auto !important}.p-xxl-0{padding:0 !important}.p-xxl-1{padding:.25rem !important}.p-xxl-2{padding:.5rem !important}.p-xxl-3{padding:1rem !important}.p-xxl-4{padding:1.5rem !important}.p-xxl-5{padding:3rem !important}.px-xxl-0{padding-right:0 !important;padding-left:0 !important}.px-xxl-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-xxl-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-xxl-3{padding-right:1rem !important;padding-left:1rem !important}.px-xxl-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-xxl-5{padding-right:3rem !important;padding-left:3rem !important}.py-xxl-0{padding-top:0 !important;padding-bottom:0 !important}.py-xxl-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-xxl-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-xxl-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-xxl-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-xxl-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-xxl-0{padding-top:0 !important}.pt-xxl-1{padding-top:.25rem !important}.pt-xxl-2{padding-top:.5rem !important}.pt-xxl-3{padding-top:1rem !important}.pt-xxl-4{padding-top:1.5rem !important}.pt-xxl-5{padding-top:3rem !important}.pe-xxl-0{padding-right:0 !important}.pe-xxl-1{padding-right:.25rem !important}.pe-xxl-2{padding-right:.5rem !important}.pe-xxl-3{padding-right:1rem !important}.pe-xxl-4{padding-right:1.5rem !important}.pe-xxl-5{padding-right:3rem !important}.pb-xxl-0{padding-bottom:0 !important}.pb-xxl-1{padding-bottom:.25rem !important}.pb-xxl-2{padding-bottom:.5rem !important}.pb-xxl-3{padding-bottom:1rem !important}.pb-xxl-4{padding-bottom:1.5rem !important}.pb-xxl-5{padding-bottom:3rem !important}.ps-xxl-0{padding-left:0 !important}.ps-xxl-1{padding-left:.25rem !important}.ps-xxl-2{padding-left:.5rem !important}.ps-xxl-3{padding-left:1rem !important}.ps-xxl-4{padding-left:1.5rem !important}.ps-xxl-5{padding-left:3rem !important}.text-xxl-start{text-align:left !important}.text-xxl-end{text-align:right !important}.text-xxl-center{text-align:center !important}}@media (min-width: 1200px){.fs-1{font-size:1.40625rem !important}}@media print{.d-print-inline{display:inline !important}.d-print-inline-block{display:inline-block !important}.d-print-block{display:block !important}.d-print-grid{display:grid !important}.d-print-table{display:table !important}.d-print-table-row{display:table-row !important}.d-print-table-cell{display:table-cell !important}.d-print-flex{display:flex !important}.d-print-inline-flex{display:inline-flex !important}.d-print-none{display:none !important}}body{background-size:cover}.bg-light{background-color:Rgb(var(--t42-bg-light)) !important}.bg-dark{background-color:Rgb(var(--t42-bg-dark)) !important}.bg-base{background-color:Rgb(var(--t42-bg-mid)) !important}.border{border:0.0625rem solid var(--t42-color-opacity-10) !important}.border-primary{border-color:#007be5 !important}.border-secondary,.border-info,.border-light,.border-dark,.border-white{border-color:var(--t42-color-opacity-10) !important}.border-success{border-color:#43a047 !important}.border-danger{border-color:#ff511f !important}.border-warning{border-color:#f9a825 !important}.pl-0{padding-left:0}.pl-1{padding-left:0.25rem}.pl-2{padding-left:0.5rem}.pl-3{padding-left:1rem}.pl-4{padding-left:1.5rem}.pl-5{padding-left:3rem}.pl-auto{padding-left:auto}.pr-0{padding-right:0}.pr-1{padding-right:0.25rem}.pr-2{padding-right:0.5rem}.pr-3{padding-right:1rem}.pr-4{padding-right:1.5rem}.pr-5{padding-right:3rem}.pr-auto{padding-right:auto}.ml-0{margin-left:0}.ml-1{margin-left:0.25rem}.ml-2{margin-left:0.5rem}.ml-3{margin-left:1rem}.ml-4{margin-left:1.5rem}.ml-5{margin-left:3rem}.ml-auto{margin-left:auto}.mr-0{margin-right:0}.mr-1{margin-right:0.25rem}.mr-2{margin-right:0.5rem}.mr-3{margin-right:1rem}.mr-4{margin-right:1.5rem}.mr-5{margin-right:3rem}.mr-auto{margin-right:auto}@keyframes spinner-border{to{transform:rotate(360deg) /* rtl:ignore */}}.spinner-border{display:inline-block;width:2rem;height:2rem;vertical-align:-.125em;border:.25em solid currentColor;border-right-color:transparent;border-radius:50%;animation:.75s linear infinite spinner-border}.spinner-border-sm{width:1rem;height:1rem;border-width:.2em}@keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1;transform:none}}.spinner-grow{display:inline-block;width:2rem;height:2rem;vertical-align:-.125em;background-color:currentColor;border-radius:50%;opacity:0;animation:.75s linear infinite spinner-grow}.spinner-grow-sm{width:1rem;height:1rem}@media (prefers-reduced-motion: reduce){.spinner-border,.spinner-grow{animation-duration:1.5s}}.loader-wrapper{display:flex;flex-direction:column;flex-grow:1;gap:1rem;align-items:center;justify-content:center}.loader-wrapper .loader{width:2rem;height:2rem;border-radius:50%;background:radial-gradient(farthest-side, #999d9e 94%, rgba(0,0,0,0)) center top/4px 4px no-repeat,conic-gradient(rgba(0,0,0,0) 15%, #999d9e);-webkit-mask:radial-gradient(farthest-side, rgba(0,0,0,0) calc(100% - 4px), #000 0)}.loader-wrapper.active .loader{animation:s3 1.5s infinite linear}@keyframes s3{to{transform:rotate(1turn)}}.loader-wrapper .loader-text{margin:0 auto;padding:0 0.833rem;overflow:hidden;color:var(--t42-content-color-muted);text-align:center;text-overflow:ellipsis}@keyframes clipMe{0%,100%{clip:rect(0, 220px, 2px, 0)}25%{clip:rect(0, 2px, 220px, 0)}50%{clip:rect(218px, 220px, 220px, 0)}75%{clip:rect(0, 220px, 220px, 218px)}}@keyframes spin{from{transform:rotate(0deg)}to{transform:rotate(360deg)}}.spinner{display:inline-block;animation-name:spin;animation-duration:3000ms;animation-timing-function:linear;animation-iteration-count:infinite}@font-face{font-weight:400;font-family:"Montserrat";font-style:normal;src:url(data:font/ttf;base64,AAEAAAARAQAABAAQR0RFRrFss1wAAmssAAACfkdQT1N2Wb7+AAJtrAABFy5HU1VCjJZZRgADhNwAAC8mT1MvMlYMpE4AAfmwAAAAYGNtYXBfILVpAAH6EAAACuRjdnQgMKUWggACEzwAAADkZnBnbU0kjnwAAgT0AAANbWdhc3AAAAAQAAJrJAAAAAhnbHlmzhsdpQAAARwAAct0aGVhZA5QtXgAAduUAAAANmhoZWEG0AwiAAH5jAAAACRobXR4v8HBsgAB28wAAB3AbG9jYfsbiDIAAcywAAAO4m1heHAIxQ5XAAHMkAAAACBuYW1lKqFFSQACFCAAAAHucG9zdFa6PIcAAhYQAABVE3ByZXDNS6zAAAISZAAAANUAAgAoAAACIwK8AAMABwApQCYAAAACAwACZQQBAwEBA1UEAQMDAV0AAQMBTQQEBAcEBxIREAUNFysTIREhJREhESgB+/4FAav+pQK8/URGAjD90AAAAv//AAAC3QK8AAcACgArQCgJAQQCAUoFAQQAAAEEAGYAAgJCSwMBAQFDAUwICAgKCAoREREQBgoYKyUhByMBMwEjJwMDAif+jE1nAT1jAT5pcJeXr68CvP1E/wFX/qn/////AAAC3QN3ACIABAAAAAMHEgKaAAD/////AAAC3QN3ACIABAAAAAMHGQKaAAD/////AAAC3QPhACIABAAAACcHMQKaAJYBBwcuApoBEQARsQIBsJawMyuxAwG4ARGwMysA//////88At0DdwAiAAQAAAAjBv8CmgAAAAMHGQKaAAD/////AAAC3QPhACIABAAAACcHMQKaAJYBBwctApoBEQARsQIBsJawMyuxAwG4ARGwMysA/////wAAAt0D7QAiAAQAAAAnBzECmgCWAQcHNAKaAP4AELECAbCWsDMrsQMBsP6wMyv/////AAAC3QPgACIABAAAACcHMQKaAJYBBwcyApoBEQARsQIBsJawMyuxAwG4ARGwMysA/////wAAAt0DdwAiAAQAAAADBxcCmgAA/////wAAAt0DdwAiAAQAAAADBxYCmgAA/////wAAAt0DvgAiAAQAAAAnBy8CmgCWAQcHLgNCAO4AELECAbCWsDMrsQMBsO6wMyv//////zwC3QN3ACIABAAAACMG/wKaAAAAAwcWApoAAP////8AAALdA74AIgAEAAAAJwcvApoAlgEHBy0DQgDuABCxAgGwlrAzK7EDAbDusDMr/////wAAAt0D0wAiAAQAAAAnBy8CmgCWAQcHNAMcAOQAELECAbCWsDMrsQMBsOSwMyv/////AAAC3QPmACIABAAAACcHLwKaAJYBBwcyApoBFwARsQIBsJawMyuxAwG4ARewMysA/////wAAAt0DdwAiAAQAAAADByMCmgAA/////wAAAt0DbQAiAAQAAAADBwoCmgAA//////88At0CvAAiAAQAAAADBv8CmgAA/////wAAAt0DdwAiAAQAAAADBxACmgAA/////wAAAt0DuwAiAAQAAAADByICmgAA/////wAAAt0DfQAiAAQAAAADByQCmgAA/////wAAAt0DVAAiAAQAAAADBx4CmgAA//////8gAvMCvAAiAAQAAAADBwMECAAA/////wAAAt0D1gAiAAQAAAEHBvACmgCqAAixAgKwqrAzK/////8AAALdBB0AIgAEAAABBwbxApoAqgAIsQICsKqwMyv/////AAAC3QN3ACIABAAAAAMHGgKaAAAAAv//AAAD3wK8AA8AEwBEQEEABQAGCQUGZQsBCQABBwkBZQgBBAQDXQADA0JLCgEHBwBdAgEAAEMATBAQAAAQExATEhEADwAPEREREREREQwKGyslFSE1IQcjASEVIRUhFSEVJxEjAwPf/gT+6mdnAaECMf51AV/+oWMU01dXr68CvFfXVeKoAWb+mv////8AAAPfA3cAIgAeAAAAAwcSA0AAAAADAGkAAALDArwADgAXAB8APEA5DgEEAgFKAAIABAUCBGUGAQMDAV0AAQFCSwcBBQUAXQAAAEMATBgYDw8YHxgeHRsPFw8WJyEkCAoXKwAWFRQGIyERITIWFRQGBwEVMzI2NTQmIxI2NTQjIxUzAn1GiYP+sgE6eIMzK/6NzU1TU01uVqvm5gFaWURbYgK8YFU3UBUBAOA5Nzc5/eY4PHXpAAABADD/+AKtAsQAGwAuQCsYFwsKBAIBAUoAAQEAXwAAAEhLAAICA18EAQMDSQNMAAAAGwAaJiQmBQoXKwQmJjU0NjYzMhYXByYjIgYGFRQWFjMyNxcGBiMBOalgYKppUogwQU92Tn5HR35OdVBBMIlSCF2jZmajXTc2P1NGe0xMe0ZUPzY4//8AMP/4Aq0DdwAiACEAAAADBxICxwAA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BwcDUQBzAAixAQGwc7AzK///AGn/LwLDArwAIgBSAAAAAwcEAsEAAP//AGkAAALDA3cAIgBSAAAAAwcXAsEAAP//AGkAAALDA3cAIgBSAAAAAwcWAsEAAP//AGn/PALDArwAIgBSAAAAAwb/AsEAAAABAGkAAADNArwAAwATQBAAAABCSwABAUMBTBEQAgoWKxMzESNpZGQCvP1EAAIAV//4Am0CvAAPABMAM0AwAwEABAIBAgACSgAEBAFdAwEBAUJLAAAAAl8FAQICSQJMAAATEhEQAA8ADhMlBgoWKwQmJzcWFjMyNjURMxEUBiMDMxEjAQN8MCcsaDdeYmSeiORkZAgmIVAeIG5vAY7+d5miAsT+eQD//wBQAAABUgN3ACIAWAAAAAMHEgHHAAD////5AAABPQN3ACIAWAAAAAMHGQHHAAD////oAAABTgN3ACIAWAAAAAMHFgHHAAD///+uAAABGwN3ACIAWAAAAAMHIwHHAAD//wALAAABKwNtACIAWAAAAAMHCgHHAAD//wAPAAABOQP0ACIAWAAAACcHKwHHAJYBBwcuAccBJAARsQECsJawMyuxAwG4ASSwMysA//8AYAAAANYDfQAiAFgAAAADBw4BxwAA//8AaP88AM4CvAAiAFgAAAADBv8BxwAA////5AAAAOYDdwAiAFgAAAADBxABxwAA//8APwAAAQADuwAiAFgAAAADByIBxwAA////+QAAAT0DfQAiAFgAAAADByQBxwAA//8AFgAAASADVAAiAFgAAAADBygBxwAA//8ATv8gAPECvAAiAFgAAAADByoB+AAA////8wAAAUMDdwAiAFgAAAADBxoBxwAAAAH/9//4AZ4CvAAQACxAKQMCAgABAUoAAQECXQACAkJLAAAAA18EAQMDSQNMAAAAEAAPERMkBQoXKxYmJzcWMzI2NREjNSERFAYjhGwhOjpYOz39AWBvbAg1MERTSEYBiVf+JXR1////9//4AaIDdwAiAGgAAAADBxYCGwAAAAEAaQAAAs4CvAALAB9AHAkGAQMAAQFKAgEBAUJLAwEAAEMATBISERIEChgrAQcVIxEzEQEzAQEjAU2AZGQBfHL+1QE+dQE3grUCvP55AYf+xf5///8AaQAAAs4DdwAiAGoAAAADBxcCowAA//8Aaf75As4CvAAiAGoAAAADBwECowAA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KAcKGSsBERQGBwYVFBYzMjY3FwYjIiY1NDcmJjURMxEUMzI2NRECs15XkCIcECEMEygyOEBFf41kxWBmArz+cnaSHjNJGBwJCDEYNy5DMQifjgGO/nbhb3IBigD//wBj//gCswPWACIAxwAAAQcG8AK4AKoACLEBArCqsDMr//8AY//4ArMDdwAiAMcAAAADBxoCuAAA//8AY//4ArMD9AAiAMcAAAAnBzICuACWAQcHLgK4ASQAEbEBAbCWsDMrsQIBuAEksDMrAAAB//8AAALJArwABgAhQB4FAQABAUoDAgIBAUJLAAAAQwBMAAAABgAGEREEChYrAQEjATMTEwLJ/s1j/sxs/P4CvP1EArz9wQI/AAEAIAAABEYCvAAMACdAJAsIAwMAAgFKBQQDAwICQksBAQAAQwBMAAAADAAMEhESEQYKGCsBAyMDAyMDMxMTMxMTBEbqab+/a+pnvcVcwcECvP1EAi/90QK8/ccCOf3EAjz//wAgAAAERgN3ACIA4AAAAAMHEgNgAAD//wAgAAAERgN3ACIA4AAAAAMHFgNgAAD//wAgAAAERgNtACIA4AAAAAMHCgNgAAD//wAgAAAERgN3ACIA4AAAAAMHEANgAAAAAQANAAAClAK8AAsAJkAjCgcEAQQAAQFKAgEBAUJLBAMCAABDAEwAAAALAAsSEhIFChcrIQMDIwEDMxMTMwMBAiHSz3MBB/dyxMJt9wEJASH+3wFnAVX+8wEN/q7+lgAAAf/8AAACiwK8AAgAHUAaBgMAAwABAUoCAQEBQksAAABDAEwSEhEDChcrJRUjNQEzExMzAXVj/upr4OFj8vL0Acj+jwFx/////AAAAosDdwAiAOYAAAADBxICcAAA/////AAAAosDdwAiAOYAAAADBxYCcAAA/////AAAAosDbQAiAOYAAAADBwoCcAAA/////AAAAosDfQAiAOYAAAADBw4CcAAA/////P88AosCvAAiAOYAAAADBv8CcAAA/////AAAAosDdwAiAOYAAAADBxACcAAA/////AAAAosDuwAiAOYAAAADByICcAAA/////AAAAosDVAAiAOYAAAADBx4CcAAA/////AAAAosDdwAiAOYAAAADBxoCcAAAAAEAKwAAAnQCvAAJAC9ALAgBAQIDAQADAkoAAQECXQACAkJLBAEDAwBdAAAAQwBM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AfIAxAAIsQEBsMSwMyv//wBb/y8CUgLmACIB2AAAAAMHBAKDAAD////YAAACUgO1ACIB2AAAAQcG7QG3ANQACLEBAbDUsDMr////2AAAAlIDoQAiAdgAAAEHBxYBtwAqAAixAQGwKrAzK///AFv/PAJSAuYAIgHYAAAAAwb/AoMAAP//AEoAAADMAvUAIgHfAAAAAwcpAbcAAAABAFsAAAC7AhIAAwATQBAAAABFSwABAUMBTBEQAgoWKxMzESNbYGACEv3u//8AQAAAAUIC4QAiAd8AAAADBucBtwAA//8AAgAAARQC4QAiAd8AAAADBzcBtwAA////8QAAASUC4QAiAd8AAAADBzYBtwAA////ngAAAQsC4QAiAd8AAAADBvsBtwAA//8AEgAAAQQC1gAiAd8AAAADBzUBtwAA/////wAAASkDXgAiAd8AAAAjBysBtwAAAQcHLgG3AI4ACLEDAbCOsDMr//8AUAAAAMYC5wAiAd8AAAADBuMBtwAA//8ASv88AMwC9QAiAd8AAAAjBykBtwAAAAMG/wG3AAD////UAAAA1gLhACIB3wAAAAMG5QG3AAD//wAvAAAA8AMlACIB3wAAAAMG+gG3AAD//wACAAABFALnACIB3wAAAAMHOgG3AAD//wBK/zgB6AL1ACIB3wAAACMHKQG3AAAAIwHwARcAAAADBykC0wAA//8ABgAAARACvgAiAd8AAAADBzkBtwAA//8APP8gAN8C9QAiAd8AAAAjBykBtwAAAAMHKgHmAAD////8AAABGgLhACIB3wAAAAMHOAG3AAD///+k/zgA0QL1ACIB8AAAAAMHKQG8AAAAAf+k/zgAwAISAA4AKUAmAwEAAQIBAgACSgABAUVLAAAAAmADAQICTQJMAAAADgANEyQEChYrBiYnNxYzMjY1ETMRFAYjDDwUHx4wJilgWFHIEBBKGS8uAiz91lJe////pP84ASoC4QAiAfAAAAADBzYBvAAAAAEAWwAAAmYC5gALACNAIAkGAQMAAgFKAAEBREsAAgJFSwMBAABDAEwSEhESBAoYKyUHFSMRMxEBMwcTIwEpbmBgASF03/V292aRAub+JAEI2/7J////2AAAAmYDtQAiAfIAAAEHBu0BtwDUAAixAQGw1LAzK///AFv++QJmAuYAIgHyAAAAAwcBAmUAAAABAFsAAAJm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yNQBDP70/////wAAAmgDBwAiAt8AAAEHBucCXwAmAAixAgGwJrAzK/////8AAAJoAwcAIgLfAAABBwbvAl8AJgAIsQIBsCawMyv/////AAACaANxACIC3wAAACcHMQJfACYBBwcuAl8AoQAQsQIBsCawMyuxAwGwobAzK///////PAJoAwcAIgLfAAAAIwb/Al8AAAEHBu8CXwAmAAixAwGwJrAzK/////8AAAJoA3EAIgLfAAAAJwcxAl8AJgEHBy0CXwChABCxAgGwJrAzK7EDAbChsDMr/////wAAAmgDfQAiAt8AAAAnBzECXwAmAQcHNAJfAI4AELECAbAmsDMrsQMBsI6wMyv/////AAACaANwACIC3wAAACcHMQJfACYBBwcyAl8AoQAQsQIBsCawMyuxAwGwobAzK/////8AAAJoAwcAIgLfAAABBwbtAl8AJgAIsQIBsCawMyv/////AAACaAMHACIC3wAAAQcG7AJfACYACLECAbAmsDMr/////wAAAnkDTgAiAt8AAAAnBy8CXwAmAQcHLgMHAH4AELECAbAmsDMrsQMBsH6wMyv//////zwCaAMHACIC3wAAACMG/wJfAAABBwbsAl8AJgAIsQMBsCawMyv/////AAACaANOACIC3wAAACcHLwJfACYBBwctAwcAfgAQsQIBsCawMyuxAwGwfrAzK/////8AAAJoA2MAIgLfAAAAJwcvAl8AJgEHBzQC4QB0ABCxAgGwJrAzK7EDAbB0sDMr/////wAAAmgDdgAiAt8AAAAnBy8CXwAmAQcHMgJfAKcAELECAbAmsDMrsQMBsKewMyv/////AAACaAMHACIC3wAAAQcG+wJfACYACLECArAmsDMr/////wAAAmgC/QAiAt8AAAEHBt8CXwAmAAixAgKwJrAzK///////PAJoAjgAIgLfAAAAAwb/Al8AAP////8AAAJoAwcAIgLfAAABBwblAl8AJgAIsQIBsCawMyv/////AAACaANLACIC3wAAAQcG+gJfACYACLECAbAmsDMr/////wAAAmgDDQAiAt8AAAEHBvwCXwAmAAixAgGwJrAzK/////8AAAJoAuQAIgLfAAABBwb2Al8AJgAIsQIBsCawMyv//////yACfgI4ACIC3wAAAAMHAwOTAAD/////AAACaANSACIC3wAAAQcG8AJf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VAD////w/zgCNgISAAICbwYA////8P84AjYC4QAiAm8GAAADB1gB8AAAAAMAK/8+AvoC5gARABgAHgA3QDQeAQAGAUoABAMEgwgBBwcDXwUBAwMiSwAGBgBfAgEAACFLAAEBJAFMFhEUEREUERERCQcdKyQGBxUjNSYmNTQ2NzUzFRYWFQQWFxEGBhUENTQmJxEC+qSVXpWjopZelaT9kG1sbWwCEW5sj44Iu7sIjXx7igjPzwiLelVgBwF0B15TrKxUXQf+iwD//wAJAAACFQISAAICbvsAAAEAKgAAAgQCEgARAC9ALBABAwIDAQEDAkoAAwABAAMBZwUEAgICIksAAAAhAEwAAAARABEjEyIRBgcYKwERIzUGIyImNTUzFRQWMzI3NQIEYFZVY2xgRT5GUQIS/e7WKFxcrKY3OCPyAAABAF3/gQKTAhIACwApQCYAAAMAUgQBAgIiSwYFAgMDAV4AAQEhAUwAAAALAAsREREREQcHGSslFSM1IREzESERMxECk1v+JWABImBU038CEv5CAb7+QgAAAQBdAAADUAISAAsAJUAiBgUDAwEBIksEAQICAF4AAAAhAEwAAAALAAsREREREQcHGSsBESERMxEzETMRMxEDUP0NYOpg6QIS/e4CEv5CAb7+QgG+AP//AF3/jwOfAhIAIgUmAAAAAwdaArIAAAABAF3/gQIoAhIACwBGS7AKUFhAGAABAAABbwUBAwMiSwAEBABeAgEAACEATBtAFwABAAGEBQEDAyJLAAQEAF4CAQAAIQBMWUAJEREREREQBgcaKyEjFSM1IxEzESERMwIot1u5YAELYH9/AhL+QgG+AAACAF3//gIhAhIACgATADBALQUBAgADBAIDZQABASJLBgEEBABeAAAAIQBMCwsAAAsTCxIRDwAKAAkRJAcHFisAFhUUBicnETMVFxI2NTQmJycVFwG3anNr5mCVKkNBQ35+AV1aUlZdAQECErMB/uk2NTQwAQLQAQACAAQAAAJhAhIADAAVADZAMwYBAwAEBQMEZQABAQJdAAICIksHAQUFAF0AAAAhAEwNDQAADRUNFBMRAAwACxERJAgHFysAFhUUBiMjESM1IRUzEjY1NCYjIxUzAfhpc2nfogECkCpAPz98fAFfW1JVXQG+VLP+6jY1MzHPAAADAF3//gLJAhIACgAOABcANkAz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hAMBAgIBXQABASEBTAAAAAUABRERBAcWKzcVIzUjNfpccVfwmVcAAQA6/2cA2wBXAAUAH0AcAAABAIQDAQICAV0AAQEhAUwAAAAFAAUREQQHFis3FSM1IzXbXURX8JlXAAEAQP+PANoAUgAFADxLsApQWEASAAABAQBvAwECAgFdAAEBIQFMG0ARAAABAIQDAQICAV0AAQEhAUxZQAsAAAAFAAUREQQHFis3FSM1IzXaV0NSw3FSAP///jICWf92A0sAIgcxAAABBgcuAHsACLEBAbB7sDMr///+MgJZ/3YDSwAiBzEAAAEGBy0AewAIsQEBsHuwMyv///4yAln/dgNXACIHMQAAAQYHNABoAAixAQGwaLAzK////i8CWf95A0oAIgcxAAABBgcyAHsACLEBAbB7sDMr///+IQJfABoDKAAiBy8AAAEHBy4AqABYAAixAQGwWLAzK////iECX//BAygAIgcvAAABBwctAKgAWAAIsQEBsFiwMyv///4hAl//pAM9ACIHLwAAAQcHNACCAE4ACLEBAbBOsDMr///+IQJf/4cDUAAiBy8AAAEHBzIAAACBAAixAQGwgbAzK////jIC7/92A+EAJwcxAAAAlgEHBy4AAAERABGxAAGwlrAzK7EBAbgBEbAzKwD///4yAu//dgPhACcHMQAAAJYBBwctAAABEQARsQABsJawMyuxAQG4ARGwMysA///+MgLv/3YD7QAnBzEAAACWAQcHNAAAAP4AELEAAbCWsDMrsQEBsP6wMyv///4vAu//eQPgACcHMQAAAJYBBwcyAAABEQARsQABsJawMyuxAQG4ARGwMysA///+IQL1ABoDvgAnBy8AAACWAQcHLgCoAO4AELEAAbCWsDMrsQEBsO6wMyv///4hAvX/wQO+ACcHLwAAAJYBBwctAKgA7gAQsQABsJawMyuxAQGw7rAzK////iEC9f+kA9MAJwcvAAAAlgEHBzQAggDkABCxAAGwlrAzK7EBAbDksDMr///+IQL1/4cD5gAnBy8AAACWAQcHMgAAARcAEbEAAbCWsDMrsQEBuAEXsDMrAAABAF//ZwC8ABcAAwAYQBUAAQAAAVUAAQEAXQAAAQBNERACBxYrFyM1M7xdXZmwAAABAF7/jwC5ABUAAwAYQBUAAQAAAVUAAQEAXQAAAQBNERACBxYrFyM1M7lb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UXdRg1GUUaVRtlHHUdhR6VICUhtSgFKLUp9SsFLJUuJS+1NDU3xTuVQOVFFUYlRzVH9UkFScVK1UuVUPVSBVOVVBVVJVa1V3VYhVlFWlVbFVxlZEVmNWdFaFVpFWnVauVrpWxlb0VwVXFlcnVzhXSVdaV2ZXd1eIV5lXslfHV+BX+VgSWCNYNFhFWF5YrFi9WM5Y51kLWTxZTVleWW9ZgFmtWdBZ4VnyWgNaFFogWjFaQlpTWmRaklqjWrRaxVrRWw1bHlsvW0hbXVt2W49bqFu5W8pb41v4XBFcKlxDXFRcZVxxXIJck1ykXLVcwVzSXONc9F1ZXWpdf13WXedd+F4JXh5eL15IXl1edl6PXqheuV7KXtte5174XwlfGl8rX0RfXV/pX/pgSGCBYOJg82EEYRVhJmE3YUhhXGGGYY5hn2HtYf5iD2IgYjFiSmJWYmdieGKJYsVi1mLiYvNjKGM5Y0VjpmOyY/dkCGQZZCVkNmRCZKJkrmS6ZMtlFmVAZVFlYmVuZXpli2WXZaNl7WX+Zg9mIGYxZkJmU2ZfZnBmgWaSZqtmwGbZZvJnC2ccZy1nPmdXZ2NndGeFZ55n5mf3aAhoGWgqaHVohmiXaKhouWjKaNto7Gj9aQ5pSWlaaWtpfGmIad9qH2onamJqr2rNatlq+ms7a0NrT2tba5tr+WwfbCtsN2yNbLtsx20hbVVtXW1lbYltkW2Zbblt8m3+blBugG62buJvDm8ab0Fvem+4b8Rv0HAxcDlwSXCYcK5wunDCcQBxc3G1ciRybXK4csxzGXNJc5hzpHOwc7xz+nQ3dGt0d3SDdNZ04nWZdaV1sXW5dc112XYNdhl2XXaTdp93B3cTdxt3J3dud6x34XggeF54anh2eH54injheO14+XkFeVF5XXlpeXV5iXmhea15uXnFedF53Xnoefh6RnqQesh7I3txe3l7qnvzfEF8f3yLfMJ85n05fWN9b317fYd9j33Ufdx96H30ffx+CH6nfrN+6380fzx/RH9Qf5p/5IA1gKOBM4GugbaCDoIagiaCMoI6gkaCUoJegmqCdoKCgo6CloLvgveDXYOng8SD1oQHhEeET4RbhGeEo4T+hSSFMIU8hZKFvYXJhhiGS4ZxhnmGnYalhq2GzYbVhuGHMIc4h22HmYfEh9CICYhFiISIyYjViTKJOolKiZaJoomuibqKAYqKisiLJouKi9uL44wxjF+MrYy5jRaNIo1djZ6Nz43bjeeN845FjtOO347rjw6PIo8uj2KPbo+vj7eP95BZkGWQbZB5kL6ROJF6ka2R6pImkjKSPpJGklKSpJKwkrySyJMRkx2TKZM1k4eTk5Ofk6uTt5PDk8+T2pPmlDWUepSylQqVXJVklZWV35ZXlpmWpZcDl1qXYpell/6YBpgSmB6YT5hymHqYgpiKmL+Yy5ktmTmZgZnPmkaabpp6moaamJrymv6bBpsSmyabLps2mz6bSptWm16bapvom/ScRJxMnFScYJyonPadXp3GnkCemJ6knrCeuJ7EnxOfH58rnzefQ59Pn1ufZ5+/n+agMqB0oLCgwaDJoQqhKaFpobKh5aItoo+izaM4o5mj36P9pD2kiKS+pQelD6VSpVqlaKV3pYallaWkpbOlwqXRpeCl76X+pkCmaKaopvCnI6drp82oC6h2qNipHqlFqYWpzqoDqkyqVKqXqp+rA6sRqx+rLas7q0mrV6tlq3OrgauPq8mr76wtrHOso6zlrTytd63Xri+uPq5krqKu6K73rzqvSa+Fr5Svo6+yr8Gv0K/fr+6v/bAMsBuwKrA5sFGwYbBxsIGwkbChsLGwwbDRsOGxFrExsVaxe7GNsbqxyrH5siiylLK2swuzZLNws4ezmbOws8yz57QMtBm0PrRVtHq0vrUFtSW1SLVrtZG1nrWrtbi1xbXStd+1+LYRtiq2MrZLtlO2W7ZotnW2graOtpq2ubbbtue287b/tya3Ubd+t5O3qLe1t8K38bgiuC64OrhZuHu4nbjxuUi5VLlguWy5eLmfucq597oNuiq6Oro6ujq6Oro6ujq6OrqWuuG7c7vfvFG8371Jvbq98r5UvsO+/79Xv6C/28BIwFjA5cErwXzBwsHswizCuML4wwDDRcNNw3XDjsOrw/XEJ8SBxJfErsTYxQTFOsW+xjLGUMayxybHacdxx3nHnMfVyATIDMhvyR7J/sodyjXKW8p0ypPKq8rUyuzLHss8y1vLfsuly8vL3sv6zBTMKsxUzGbMdsyOzJ7MxMzczQLNGs3KzjjOY87iz2TP6tAx0HnQj9Cx0QbRK9Fi0cvSU9J60pHSsdK+03fT5dQk1DXURtRX1IHUktSs1L3U1tTn1PjVHtU11VrVf9WP1cHWA9ZI1rzWzdbe1u/XDdce1y/XQNd115vXydf22CLYS9iJ2LnY+dkx2WHZftmc2brZzNnm2iHaONpP2mbajNqj2rna0Nrl2vzbE9s121bbd9uO27zcLNxD3FrccdyL3KLcudzQ3QHdI91N3Wfded2P3andzN4L3lPehN6k3sTe5t8I3zLfld+53+rgMuBU4Hzg8uEJ4S/hU+Ft4Yrhl+Gj4cDh2eH24ibiVOJu4oripuKv4rjiweLK4tPi3OLl4u7i9+MA4wnjEuMb4zTjTeNk45LjwOPs5AnkJuRS5GLkcuSC5JLko+S05MXk1uTt5QTlGuUx5UflXeVz5YrlouW6AAAAAQAAAAczM3QVnhxfDzz1AAcD6AAAAADWC/5GAAAAANYeQAX8uP75Bk0EHQAAAAcAAgAAAAAAAAJLACgAAAAAAQ0AAAENAAAC3P//Atz//wLc//8C3P//Atz//wLc//8C3P//Atz//wLc//8C3P//Atz//wLc//8C3P//Atz//wLc//8C3P//Atz//wLc//8C3P//Atz//wLc//8C3P//Atz//wLc//8C3P//Atz//wQX//8EF///AvUAaQLTADAC0wAwAtMAMALTADAC0wAwAtMAMALTADADOgBpBa4AaQNCAAsDOgBpA0IACwM6AGkDOgBpBUMAaQKeAGkCngBpAp4AaQKeAGkCngBpAp4AaQKeAGkCngBpAp4AaQKeAGkCngBpAp4AaQKeAGkCngBpAp4AaQKeAGkCngBpAp4AaQKeAGkCngBpAp4AaQKeAGkCngBpAm8AHwJvAB8CewBpAwQAMAMEADADBAAwAwQAMAMEADADBAAwAwQAMAMnADADLABpAzwACQMsAGkDLABpAywAaQMsAGkBNgBpAtAAVwE2AFABNv/5ATb/6AE2/64BNgALATYADwE2AGABNgBoATb/5AE2AD8BNv/5ATYAFgE2AE4BNv/zAgH/9wIB//cCzwBpAs8AaQLPAGkCUgBpBFMAaQJSAFACUgBpAlIAaQJSAGkCUgBpA24AaQJSAGkCWgAJA7sAaQO7AGkDLABpBS0AaQMsAGkDLABpAywAaQMsAGkDLABpAywAaQRIAGkDLABpAywAaQNIADADSAAwA0gAMANIADADSAAwA0gAMANIADADSAAwA0gAMANIADADSAAwA0gAMANIADADSAAwA0gAMANIADADSAAwA0gAMANIADADSAAwA0gAMANIADADSAAwA0gAMANIADADSAAwA0gAMANIADADSAAwA0gAMANIADADSAAwA0gAMANIADAEZgAwAtIAaQLSAGkDSAAwAtcAaQLXAGkC1wBpAtcAaQLXAGkC1wBpAtcAaQLXAGkCbQApAm0AKQJtACkBAgBQAm0AKQJtACkCbQApAm0AKQJtACkCbQApAm0AKQJtACkC+wBjAzEAMAJLAAQCSwAEAksABAJLAAQCSwAEAksABAJLAAQDFwBjAxcAYwMXAGMDFwBjAxcAYwMXAGMDFwBjAxcAYwMXAGMDFwBjAx8AYwMfAGMDHwBjAx8AYwMfAGMDHwBjAxcAYwMXAGMDFwBjAxcAYwMXAGMDFwBjAxcAYwMXAGMCyP//BGYAIARmACAEZgAgBGYAIARmACACoQANAof//AKH//wCh//8Aof//AKH//wCh//8Aof//AKH//wCh//8Aof//AKRACsCkQArApEAKwKRACsCkQArAtAAVwMgAGMDIABjAyAAYwMgAGMDIABjAyAAYwMgAGMDIABjAyAAYwMgAGMDIABjAyAAYwMgAGMDIABjAyAAYwMgAGMDIABjAyAAYwMgAGMDIABjAyAAYwMgAGMDIABjAyAAYwMgAGMDIABjBDIAWgQyAFoFrgBpBU0AaQKEADMChAAzAoQAMwKEADMChAAzAoQAMwKEADMChAAzAoQAMwKEADMChAAzAoQAMwKEADMChAAzAoQAMwKEADMChAAzAoQAMwKEADMChAAzAoQAMwKEADMChAAzAl4AYwMEADADBAAwAwQAMAMEADADBAAwAwQAMAMEADADLAAwAcgAKwLQAFcByAArAtAAVwHIACsByAArAcj/+AHIACsByAArAcgAKwHIACsByAArAcgAKwHIACsByAArAcgAKwHIACsB///3Af//9wRvAGkEywBpBMsAaQMeAGkFHQBpAx4AaQMeAGkDHgBpAx4AaQMeAGkDHgBpBDoAaQMeAGkDHgBpA0gAMAMxAEUCVv/8Alb//AJW//wCVv/8Alb//AJW//wCVv/8AxoAYwMaAGMDGgBjAxoAYwMaAGMDGgBjAxoAYwMaAGMDGgBjAxoAYwMaAGMDGgBjAxoAYwMaAGMDGgBjAxoAYwMaAGMDGgBjAxoAYwMaAGMDGgBjAxoAYwMaAGMDGgBjBKYAYwSmAGMEpgBjBKYAYwSmAGMDEwBeAxMAXgMTAF4DEwBeAxMAXgMTAF4DEwBeAxMAXgMTAF4DEwBeApsAMAKbADACmwAwApsAMAKbADACVgAyAlYAMgJWADICVgAyAlYAMgJWADICVgAyAlYAMgJWADICVgAyAlYAMgJWADICVgAyAlYAMgJWADICVgAyAlYAMgJWADICVgAyAlYAMgJWADICVgAyAlYAMgJWADICVgAyAlYAMgPdADID3QAyAqoAWwI7ACoCOwAqAjsAKgI7ACoCOwAqAjsAKgI7ACoCqgAqAoAAKgKqACoCqgAqAqoAKgKqACoEuwAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAg//7AIP/+wBYQAPArIAKgKyACoCsgAqArIAKgKyACoCsgAqArIAKgK6ACoCqQBbAqkAAAKpAFsCqf/YAqn/2AKpAFsBFwBKARcAWwEXAEABFwACARf/8QEX/54BFwASARf//wEXAFABFwBKARf/1AEXAC8BFwACAjMASgEXAAYBFwA8ARf//AEc/6QBHP+kARz/pAJoAFsCaP/YAmgAWwJeAFsBFwBbARcAQAEXAFsBFwBYAVoAWwEXAFgCMwBbARf/6AEn//kEIQBbBCEAWwKpAFsCqQBbAwIANQKpAFsCqQBbAqkAWwKpAFsCqQBbA8UAWwKpAFsCqQBbAnsAKgJ7ACoCewAqAnsAKgJ7ACoCewAqAnsAKgJ7ACoCewAqAnsAKgJ7ACoCewAqAnsAKgJ7ACoCewAqAnsAKgJ7ACoCewAqAnsAKgJ7ACoCewAqAn8AKgJ7ACoCewAqAnsAKgJ7ACoCewAqAnsAKgJ7ACoCewAqAnsAKgJ7ACoCewAqAnsAKgQrACoCqgBbAqoAWwKqACoBmgBbAZoAWwGaADcBmgBYAZr//QGaAFgBmgBIAZr/6AH1ABgB9QAYAfUAGAD/AFAB9QAYAfUAGAH1ABgB9QAYAfUAGAH1ABgB9QAYAfUAGAKkAFsBMgAZAZ4ADwGoABQBngAPAZ4ADwGeAA8BngAJAZ4ADwGeAA8CpQBWAqUAVgKlAFYCpQBWAqUAVgKlAFYCpQBWAqUAVgKlAFYCpQBWAq0AVgKtAFYCrQBWAq0AVgKtAFYCrQBWAqUAVgKlAFYCpQBWAqUAVgKlAFYCpQBWAqUAVgKlAFYCL//+A4MABgODAAYDgwAGA4MABgODAAYCKAAOAi//6gIv/+oCL//qAi//6gIv/+oCL//qAi//6gIv/+oCL//qAi//6gIJACgCCQAoAgkAKAIJACgCCQAoAjIASAKqACoCqgAqAqoAKgKqACoCqgAqAqoAKgKqACoCqgAqAqoAKgKqACoCqgAqAqoAKgKqACoCqgAqAqoAKgKqACoCqgAqAqoAKgKqACoCqgAqAqoAKgKqACoCqgAqAqoAKgKqACoCqgAqA90AMgPdADIEvQAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAArAVMAWwFBAFsBQQBAAUEAWwFBAFsBbQBbAUEAWwI1AFsBQQApAUH/8QQ6ACoBiwBWAZUADAGLAFYBiwBWAYsAVgGL//YBiwBWAYsASAPZAFYD2QBWA9kAVgPZAFYD2QBWAqUAVAKlAFQCpQBUAqUAVAKlAFQCpQBUAqUAVAKlAFQCpQBUAhMALQITAC0CEwAtAhMALQITAC0EsQAEAsgADwJ4AA8CugBbAosADwJn//8CZ///Amf//wJn//8CZ///Amf//wJn//8CZ///Amf//wJn//8CZ///Amf//wJn//8CZ///Amf//wJn//8CZ///Amf//wJn//8CZ///Amf//wJn//8CZ///Amf//wJn//8CZ///A2z//wNs//8ChABhAmEALAJhACwCYQAsAmEALAJhACwCYQAsAmEALAK+AGEC0gAgAr4AYQLSACACvgBhAr4AYQTOAGECOgBhAjoAYQI6AGECOgBhAjoAYQI6AGECOgBhAjoAYQI6AGECOgBhAjoAYQI6AEMCOgBhAjoAYQI6AGECOgBhAjoAYQI6AGECOgBhAjoAYQI6AGECOgBhAjoAYQKcACwCMAAlAjAAJQIgAGECjgAsAo4ALAKOACwCjgAsAo4ALAKOACwCjgAsAq8ALAK7AGEC4wAiArsAYQK7AGECuwBhArsAYQEiAGEBIgBhASIARgJQAEEBIgAIASL/9wEi/6QBIgAYASIABQEiAFYBIgBeASL/2gEiADUBIgAIAm8ATAEiAAwBIgBDASIAAgHB//wBwf/8AmwAYQJsAGECbABhAmwAYQH7AGEB+wBHAfsAYQH7AGEB+wBhAfsAYQO8AGEB+wBhAfv/+AMyAGEDMgBhArsAYQK7AGECuwBhArsAYQK7AGECuwBhArsAYQR8AGECuwBhArsAYQLCACwCwgAsAsIALALCACwCwgAsAsIALALCACwCwgAsAsIALALCACwCwgAsAsIALALCACwCwgAsAsIALALCACwCwgAsAsIALALCACwCwgAsAsIALALCACwCwgAsAsIALALCACwCwgAsAsIALALCACwCwgAsAsIALALCACwCwgAsAsIALALCACwDqwAsAm8AYQJvAGECwgAsAnYAYQJ2AGECdgBhAnYAYQJ2AFQCdgBhAnYAYQJ2AGECEwAlAhMAJQITACUA/wBQAhMAJQITACUCEwAlAhMAJQITACUCEwAlAhMAJQITACUCigBbAe0ABAHtAAQB7QAEAe0ABAHtAAQB7QAEAe0ABAHtAAQCqABbAqgAWwKoAFsCqABbAqgAWwKoAFsCqABbAqgAWwKoAFsCqABbArAAWwKwAFsCsABbArAAWwKwAFsCsABbAqgAWwKoAFsCqABbAqgAWwKoAFsCqABbAqgAWwKoAFsCaQAIA70AIgO9ACIDvQAiA70AIgO9ACICPAAMAjkAAgI5AAICOQACAjkAAgI5AAICOQACAjkAAgI5AAICOQACAjkAAgIrACkCKwApAisAKQIrACkCKwApAq8AWwKvAFsCrwBbAq8AWwKvAFsCrwBbAq8AWwKvAFsCrwBbAq8AWwKvAFsCrwBbAq8AWwKvAFsCrwBbAq8AWwKvAFsCrwBbAq8AWwKvAFsCrwBbAq8AWwKvAFsCrwBbAq8AWwKvAFsDmQBVA5kAVQToAGECJwAqAicAKgInACoCJwAqAicAKgInACoCJwAqAicAKgInACoCJwAqAicAKgInACoCJwAqAicAKgInACoCJwAqAicAKgInACoCJwAqAicAKgInACoCJwAqAicAKgKcADkCCABbAo4ALAKOACwCjgAsAo4ALAKOACwCjgAsAo4ALAK0ACwBqgA5AaoAOQGqADkCbwBBAaoAOQGqADkBqv/pAaoAOQGqADkBqgA5AaoAHwGqADkBqgA5Am8ATAGqADkBqgA5AaoAOQHB//wBwf/8A7wAYQQAAGEEAABhAq4AYQKuAGECrgBhAq4AYQKuAGECrgBhAq4AYQRvAGECrgBhAq4AYQLCACwB9//8Aff//AH3//wB9//8Aff//AH3//wB9//8Aff//AKuAFsCrgBbAq4AWwKuAFsCrgBbAq4AWwKuAFsCrgBbAq4AWwKuAFsCtgBbArYAWwK2AFsCtgBbArYAWwK2AFsCrgBbAq4AWwKuAFsCrgBbAq4AWwKuAFsCrgBbAq4AWwP/AFsD/wBbA/8AWwP/AFsD/wBbAqMAVgKjAFYCowBWAqMAVgKjAFYCowBWAqMAVgKjAFYCowBWAqMAVgIrACkCKwApAisAKQIrACkCKwApAZQAJQGiACAC9gAMAtsAbQLrAG0CQgBtAkIAbQJFAG0DJAANApkAbQKZAG0CmQBtBAUAEwKCACADNwBtAzcAbQM3AG0DUwBtAscAbQLHAG0DFgANA8MAbQM0AG0DUAAzAzUAbQLKAG0CzgA0AlsADQKzABACswAQA54ALQKcABEC4AA2Az0AbQRHAG0EYABtAycAbQLJAG0DPAANA+EAbQSjAA0EnABtAnwAMQLEADUCwwAdAT0AbQE2AAsCHAASA0oADQRLAG0C2wA6A0EADgMrABMDhAASA1AAMwL5AA4CagAeAr8AbQQsABMCggAgAvMAbQLkAG0C3QAjAzsADQNPAG0EPwBtBKwAbQNQAG0DzgA5As4ANAJbAA0CmwAGAof//ALBABEDzgAOAvsANgLgADUC4ABtAyUAbQPdACAD3QAgAT4AbQQFABMCygBtAy8AbQNQAG0C3AAzA+gAbQL2AAwC9gAMBBYABwKZAG0DNwApAzcAKQQFABMCggAgAm8AHwM3AG0DNwBtA1AAMwNQADMDUAAzAsMAHQKzABACswAQArMAEALgADYCQgBtA+EAbQJrAB0CoAAOAqwAGgKCADkDFwAMA1YAMwQ9ABUC4wAfAt0AbQMw/7QDMQANAxkADgLlAA0DnQAxAk8AbQKCACACzgA0As4ANAMgAGMDRAAeAoQAMwKEADMChAAzAxoAYwMaAGMDGgBjAxoAYwMWACACzQBcAncADQMTAF4DEwBeA58AMgLMAF8DaAAOA+EAXwSfAAwEjABtAf//9wM7ABMCdwANAyAAYwMgAGMEMgBaAoQAMwMaAGMDGgBjAxMAXgMTAF4DEwBeA+EAXwNIADAC7wAaAk0AMAKWAD4CZgBdAegAXQHoAF0B0gBdApgACAJ0ACwCdAAsAnQALANRAA0CIAAcArYAXQK2AF0CtgBdAswAXQJWAF0CVgBdAoEABQMeAF0CqQBdAoEALAKlAF0CsABdAjsALAHtAAQCO//wAjv/8AMlACsCHQAJAmEAKgKyAF0DrQBdA60AXQKGAF0CPwBdAn8ABAMnAF0DpgAFA7gAXQIYACsCQQAsAj8AGAEbAEwBFwASARz/ogKi/9wDbABdAmQAMAKj//YCZQAAAsAADwKKACwCVAAFAgQAKwJZAF0DcgANAiAAHAJWAF0CZgBbAlUAAAKeAAQCvgBdA3YAXQKlAF0D0ABdAyYALwI7ACwB7QAEAj4ABgI+AAYCHQAJAwMABQJ6ACoCYQApAqIAXQK8AF0DAwAVAwMAFQEbAF0DUQANAlYAXQKXAAUCrwBdAr8AXQJeACcDPQBdAk0AMAJNADAD4wAwAnQALAJzADgCcwA4A1EADQIgABwCD//sArYAXQK2AF0CgQAsAooALAKKACwCPwAYAjv/8AI7//ACO//wAmEAKgHoAF0DJwBdAewADQIdAAsCOQAWAiAANQKBAAUCsAAuA6oACQJeABYCuwBeAqn/pQKWAAUCfgBMAiEALgKzACkDUQANAe7/9wKeAE0CngBNAp4ATQJVAF4CPAAFAqkAXQKiAF0EGwBdAmMALAK3AE0EGwBOBDQATgJAAFACnAAFA1cAXgH0AF0CIAAcAjsALAHoAF0CbgAnARcABgKzACcCpQBWBBsATgKqACoCswApAmQAKgJkACoCZAAqAp4ATQKeAE0CngBNAp4ATQKWAEYEGwBdAqUAVAKlAFQCSQBQAqUABQMoAFADrQAIA7IAXQJ6//wCqgAqAqoAKgPdADICZAAqAmQAKwJkACsCngBNAp4ATQKlAFQCpQBUAqUAVAMoAFACawARAtz//wOCAAkCqgBbAtT/+ALc//8CzwBpApsAMAFyAAgCPgAOAjwABQKdACYCPgARAmkAMAJWAB4ChAAsAmkAHAKsADIBcgAIAj4ABgI8AAYCnQAmAj4AEQJpADACVgAeAoQALAJpABwBrgAcAa4AUQGuABwBrgAbAa4AFgGuABsBrgAlAa4AJAGuABwBrgAgArwAPQK8AJACvAA8ArwAPgK8ADUCvABBArwASgK8AEkCvAA7ArwAQQK8ADwCvACQArwARwK8AD4CvAA1ArwAQQK8AEoCvABJArwAOwK8AEEBrgAcAa4AUQGuABwBrgAbAa4AFgGuABsBrgAlAa4AJAGuABwBrgAgAa4AHAGuAFEBrgAcAa4AGwGuABYBrgAbAa4AJQGuACQBrgAcAa4AIAGuABwBrgBRAa4AHAGuABsBrgAWAa4AGwGuACUBrgAkAa4AHAGuACABrgAcAa4AUQGuABwBrgAbAa4AFgGuABsBrgAlAa4AJAGuABwBrgAgAK7/QgQKAFEECgBRBAoAHAQKAFEECgAbBAoAUQQKABsECgAbBAoAJAGQABMBYP/aAQsAQgE6AEIA4wAuAOMAMAKzAC4BDABFAQwARQK/ABsA4wAuAj0ACQI9AEUBhwA/ANIAPwDjAC4BYP/kAfQAAAFg/9oBHwBMAU4ATAFYAH4BYP/kAIEALQFfADkBXwATAU0AaQFNABMBUQBfAVIAIAFzAEMBcwAdAWEAcwFhAB0BZQBpAWYAKgPoAAAB9AAAArwALwPoAAABfwA5AX8AOQF/ADkD6AAAAfQAAAGTAEMB+AAuAfgAIgE4AC4BOAAiAaAAMAGgAC4BoAAwAOMALgDjADAA4wAwAgwAOAIMACwBTAA4AUwALAEMAEUBDABFAdwALgHdACIBIgAuASMAIgDnADMCCgAIAgkARQGHAD8BnwAwAZ8ALgGfADAA4gAuAOIAMADjADAA0gA/AUkAJAFJACsCvAAAAGQAAADjAAABDQAAAIYAAAAAAAAC0wAwAjsAKgLTADACvAAfAm0AKQKqACoDJwAeAcH/pAKXAB4DBAAwAzgAVwKUAB4ChgAeAsgAHgOUAGkDcAAeBmoAaQNLAB4C7gAeAtAAHQKGAB4C0QBMAqoAMwSqAB4Cw//8AR8ATAIaAEwBYP/kAkYAQwJGAEMCRgBrAkYAQwJGAEMCRgBDAkYAQwJGAEMCRgBDAkYAQwJGAEMCRgA6AkYAOgJGAEMCRgAlA5sAKgGP/90DggAJAtz//wMsAGkCkQArAyMAQwKqAFsCvABIA0sAJQS6ACUCWABgAlgAeAJYAEMCWAB5AlgAagJYAG4CWABgAlgAbwLZADICWABfAlgAYAJYAEMCWABq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Bz4HPQdEB0MHTAdKB0cHQAdFB0EHRgdJB04HUwdSB1QHUAblBucG7AbyBvYG7wbjBt8G+gbwBuoG7QRuBG8ElwRqBI8EjgSRBJIEkwSMBI0ElAR3BHQEgQSIBGYEZwRoBGkEbARtBHAEcQRyBHMEdgSCBIMEhQSEBIYEhwSKBIsEiQSQBJUElgUGBQcFCAUJBQwFDQUQBREFEgUTBRYFIgUjBSUFJAUmBScFKgUrBSkFMAU1BTYFDgUPBTcFCgUvBS4FMQUyBTMFLAUtBTQFFwUUBSEFKASYBTgEmQU5BJoFOgSbBTsEdQUVBNgFeQTZBXoEawULBJwFPASdBT0EngU+BJ8FPwSgBUAEoQVBBKIFQgSjBUMEpAVEBKUFRQSmBUcEqAVIBKkFSQSqBUoEqwVLBKwFTAStBU0ErgVOBK8FTwSwBVAEsQVRBLMFUwS0BVQEtQS2BVYEtwVXBVgEuAVZBLkFWgS6BVsEuwVcBVUEvAVdBL0FXgS+BV8EvwVgBMAFYQTBBWIEwgVjBMMFZATEBWUExQVmBMYFZwTHBWgEyAVpBMkFagTKBWsEywVsBMwFbQTNBW4EzgVvBM8FcATQBXEE0QVyBNIFcwTTBXQE1AV1BNUFdgTWBXcE1wV4BKcFRgSyBVIE2gV7BNsFfAAlAasALQGyAC4BswBEAckAQwHIADQBuQBQAdYAVwHdAFQB2gBfAeUAcwH7AHUB/QB4AgAAfgIGAH8CBwCCAgoAowIrAKQCLACeAiYAnQIlAK8CNwCxAjkAuwJDALwCRAC0AjwAtwI/AL0CRQDFAk4AxgJPAN4CZwDaAmMA5AJtAOECagDjAmwA6gJzAPQCfQAVAZsAFwGdAA4BlAAQAZYAEQGXABIBmAAPAZUABwGNAAkBjwAKAZAACwGRAAgBjgA+AcMAQAHFAEYBywA2AbsAOAG9ADkBvgA6Ab8ANwG8AGMB6QBhAecAkQIZAJMCGwCIAhAAigISAIsCEwCMAhQAiQIRAJUCHQCXAh8AmAIgAJkCIQCWAh4AzgJXANACWQDSAlsA1AJdANUCXgDWAl8A0wJcAOwCdQDrAnQA7QJ2AO8CeAZzBnUGdwZ0BngGSgZJBkgGSwZXBlgGVgbVBtYGJwaBBoUGfgZ/BoQGjwaKBoIGgwZ5Bo4GjAaGBocGiwW/Bb4GtQavBrEGswa3BrgGtgaw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AREBEgETARQAYwEVAK4AkAEWACUAJgD9AP8AZAEXARgBGQAnARoA6QEbARwBHQEeAR8AKABlASABIQEiAMgBIwEkASUBJgEnASgAygEpASoAywErASwBLQEuAS8BMAExATIBMwApACoA+AE0ATUBNgE3ATgBOQArAToBOwE8AT0BPgAsAT8AzAFAAM0BQQDOAUIA+gFDAM8BRAFFAUYBRwFIAC0BSQAuAUoBSwAvAUwBTQFOAU8BUAFRAVIBUwDiADABVAAxAVUBVgFXAVgBWQFaAVsBXAFdAGYAMgDQAV4A0QFfAWABYQFiAWMBZABnAWUBZgFnANMBaAFpAWoBawFsAW0BbgFvAXABcQFyAXMBdACRAXUArwF2AXcBeACwADMA7QA0ADUBeQF6AXsBfAF9AX4BfwA2AYABgQGCAOQBgwD7AYQBhQGGAYcBiAGJAYoANwGLAYwBjQGOAY8BkAA4ANQBkQGSANUBkwBoAZQA1gGVAZYBlwGYAZkBmgGbAZwBnQGeAZ8BoAGhAaIBowA5ADoBpAGlAaYBpwA7ADwA6wGoALsBqQGqAasBrAGtAa4APQGvAOYBsAGxAbIBswG0AbUBtgG3AbgBuQG6AbsBvAG9Ab4BvwHAAcEBwgHDAcQBxQHGAccByAHJAcoBywHMAc0BzgHPAdAB0QHSAdMB1AHVAdYB1wHYAdkB2gHbAdwB3QHeAd8B4AHhAeIB4wHkAeUB5gHnAegB6QHqAesB7AHtAe4B7wHwAfEB8gHzAfQB9QH2AfcB+AH5AfoB+wH8Af0B/gH/AgACAQICAgMCBAIFAgYCBwIIAgkCCgILAgwCDQIOAg8CEAIRAhICEwIUAhUCFgIXAhgCGQIaAhsCHAIdAh4CHwIgAiECIgIjAiQCJQImAicCKAIpAioCKwIsAi0CLgIvAjACMQIyAjMCNAI1AjYCNwI4AjkCOgI7AjwCPQI+Aj8CQAJBAkICQwJEAkUCRgBEAGkCRwJIAkkCSgJLAkwCTQBrAk4CTwJQAlECUgJTAGwCVABqAlUCVgJXAlgAbgJZAG0AoAJaAEUARgD+AQAAbwJbAlwCXQBHAOoCXgEBAl8CYAJhAEgAcAJiAmMCZAByAmUCZgJnAmgCaQJqAHMCawJsAHECbQJuAm8CcAJxAnICcwJ0AnUCdgBJAEoA+QJ3AngCeQJ6AnsCfABLAn0CfgJ/AoACgQBMANcAdAKCAHYCgwB3AoQChQKGAHUChwKIAokCigKLAowATQKNAo4ATgKPApACkQBPApICkwKUApUClgKXApgA4wBQApkAUQKaApsCnAKdAp4CnwKgAqECogB4AFIAeQKjAHsCpAKlAqYCpwKoAqkAfAKqAqsCrAB6Aq0CrgKvArACsQKyArMCtAK1ArYCtwK4ArkAoQK6AH0CuwK8Ar0AsQBTAO4AVABVAr4CvwLAAsECwgLDAsQAVgLFAsYCxwDlAsgA/ALJAsoCywLMAs0AiQLOAFcCzwLQAtEC0gLTAtQC1QBYAH4C1gLXAIAC2ACBAtkAfwLaAtsC3ALdAt4C3wLgAuEC4gLjAuQC5QLmAucC6ABZAFoC6QLqAusC7ABbAFwA7ALtALoC7gLvAvAC8QLyAvMAXQL0AOcC9QL2AvcC+AL5AvoC+wL8Av0C/gL/AwADAQMCAwMDBAMFAwYDBwMIAwkDCgMLAwwDDQMOAw8DEAMRAxIDEwMUAxUDFgMXAxgDGQMaAxsDHAMdAx4DHwMgAyEDIgMjAyQDJQMmAycDKAMpAyoDKwMsAy0DLgMvAzADMQMyAzMDNAM1AzYDNwM4AzkDOgM7AzwDPQM+Az8DQANBA0IDQwNEA0UDRgNHA0gDSQNKA0sDTANNA04DTwNQA1EDUgNTAMAAwQNUA1UDVgNXA1gDWQNaA1sDXANdA14DXwNgA2EDYgNjA2QDZQNmA2cDaANpA2oDawNsA20DbgNvA3ADcQNyA3MDdAN1A3YDdwN4A3kDegN7A3wDfQN+A38DgAOBA4IDgwOEA4UDhgOHA4gDiQOKA4sDjAONA44DjwOQA5EDkgOTA5QDlQOWA5cDmAOZA5oDmwOcA50DngOfA6ADoQOiA6MDpAOlA6YDpwOoA6kDqgOrA6wDrQOuA68DsAOxA7IDswO0A7UDtgO3A7gDuQO6A7sDvAO9A74DvwPAA8EDwgPDA8QDxQPGA8cDyAPJA8oDywPMA80DzgPPA9AD0QPSA9MD1APVA9YD1wPYA9kD2gPbA9wD3QPeA98D4APhA+ID4wPkA+UD5gPnA+gD6QPqA+sD7APtA+4D7wPwA/ED8gPzA/QD9QP2A/cD+AP5A/oD+wP8A/0D/gP/BAAEAQQCBAMEBAQFBAYEBwQIBAkECgQLBAwEDQQOBA8EEAQRBBIEEwQUBBUEFgQXBBgEGQQaBBsEHAQdBB4EHwQgBCEEIgQjBCQEJQQmBCcEKAQpBCoEKwQsBC0ELgQvBDAEMQQyBDMENAQ1BDYENwQ4BDkEOgQ7BDwEPQQ+BD8EQARBBEIEQwREBEUERgRHBEgESQRKBEsETARNBE4ETwRQBFEEUgRTBFQEVQRWBFcEWARZBFoEWwRcBF0EXgRfBGAEYQRiBGMEZARlBGYEZwRoBGkEagRrBGwEbQRuBG8EcARxBHIEcwR0BHUEdgR3BHgEeQR6BHsEfAR9BH4EfwSABIEEggSDBIQEhQSGBIcEiASJBIoEiwSMBI0EjgSPBJAEkQSSBJMElASVBJYElwSYBJkEmgSbBJwEnQSeBJ8EoAShBKIEowSkBKUEpgSnBKgEqQSqBKsErAStBK4ErwSwBLEEsgSzBLQEtQS2BLcEuAS5BLoEuwS8BL0EvgS/BMAEwQTCBMMExATFBMYExwTIBMkEygTLBMwEzQTOBM8E0ATRBNIE0wTUBNUE1gTXBNgE2QTaAJ0AngTbBNwE3QTeBN8E4AThBOIE4wTkBOUE5gTnBOgE6QTqBOsE7ATtBO4E7wTwBPEE8gTzBPQE9QT2BPcE+AT5BPoE+wT8BP0E/gT/BQAFAQUCBQMFBAUFBQYFBwUIBQkFCgULBQwFDQUOBQ8FEAURBRIFEwUUBRUFFgUXBRgFGQUaBRsFHAUdBR4FHwUgBSEFIgUjBSQFJQUmBScFKAUpBSoFKwUsBS0FLgUvBTAFMQUyBTMFNAU1BTYFNwU4BTkFOgU7BTwFPQU+BT8FQAVBBUIFQwVEBUUFRgVHBUgFSQVKBUsFTAVNBU4FTwVQBVEFUgVTBVQFVQVWBVcFWAVZBVoFWwVcBV0FXgVfBWAFYQViBWMFZAVlBWYFZwVoBWkFagVrBWwFbQVuBW8FcAVxBXIFcwV0BXUFdgV3BXgFeQV6BXsFfAV9BX4FfwWABYEFggWDBYQFhQWGBYcFiAWJBYoFiwWMBY0FjgWPBZAFkQWSBZMFlAWVBZYFlwWYBZkFmgWbBZwFnQWeBZ8FoAWhBaIFowWkBaUFpgWnBagFqQWqBasFrAWtBa4FrwWwBbEFsgWzBbQFtQW2BbcFuAW5BboFuwW8Bb0FvgW/BcAFwQXCBcMFxAXFBcYFxwXIBckFygXLBcwFzQXOBc8F0AXRBdIF0wXUBdUF1gXXBdgF2QXaBdsF3AXdBd4F3wXgBeEF4gXjBeQF5QXmBecF6AXpBeoF6wXsBe0F7gXvBfAF8QXyBfMF9AX1BfYF9wX4BfkF+gX7BfwF/QX+Bf8GAAYBBgIGAwYEBgUGBgYHBggGCQYKBgsGDAYNBg4GDwYQBhEGEgYTBhQGFQYWBhcGGAYZBhoGGwYcBh0GHgYfBiAGIQYiBiMGJAYlBiYGJwYoBikGKgYrBiwGLQYuBi8GMAYxAJsGMgYzABMAFAAVABYAFwAYABkAGgAbABwGNAY1BjYGNwY4BjkGOgY7BjwGPQY+Bj8GQAZBBkIGQwZEBkUGRgZHBkgGSQZKBksGTAZNBk4GTwZQBlEGUgZTBlQGVQZWBlcGWAZZBloGWwZcBl0GXgZfBmAGYQZiBmMGZAZlBmYGZwZoBmkGagZrBmwGbQZuBm8GcAZxBnIGcwZ0BnUGdgZ3BngGeQZ6BnsGfAZ9Bn4GfwaABoEGggaDALwA9AaEBoUA9QD2BoYGhwaIBokADQA/AMMAhwAdAA8AqwAEAKMABgARACIAogAFAAoAHgASAEIGigaLBowGjQaOBo8AXgBgAD4AQAALAAwGkAaRBpIGkwaUBpUAswCyBpYGlwAQBpgGmQaaBpsGnACpAKoAvgC/AMUAtAC1ALYAtwDEBp0GngafBqAGoQaiBqMGpAalBqYGpwaoBqkGqgarBqwGrQauBq8GsAaxBrIGswa0BrUGtga3BrgGuQa6AIQGuwC9AAcGvAa9AKYA9wa+Br8GwAbBBsIGwwbEBsUGxgbHBsgAhQbJBsoGywCWBswGzQbOAA4A7wDwALgAIACPACEAHwCVAJQAkwCnAGEApAbPAJIAnAbQBtEAmgCZAKUG0gCYAAgAxgbTBtQG1QbWBtcG2AbZBtoG2wbcBt0G3gbfBuAG4QbiALkG4wbkBuUG5gbnBugG6QbqBusG7AAjAAkAiACGAIsAigCMAIMAXwDoBu0AggDCBu4G7wBBBvAG8QbyBvMG9Ab1BvYG9wb4BvkG+gb7BvwG/Qb+Bv8HAAcBBwIHAwcEBwUHBgcHBwgHCQcKBwsHDAcNBw4HDwcQBxEHEgcTBxQHFQcWBxcHGAcZBxoHGwccBx0HHgcfByAHIQciByMHJAclByYHJwcoBykHKgcrBywHLQcuBy8HMAcxBzIHMwc0BzUHNgc3BzgHOQc6BzsHPAc9Bz4HPwdAB0EHQgdDB0QHRQdGB0cHSAdJB0oHSwdMB00HTgdPB1AHUQdSB1MHVAdVB1YHVwdYB1kHWgdbB1wHXQCNANsA4QDeANgAjgDcAEMA3wDaAOAA3QDZB14HXwdgB2EHYgdjB2QHZQdmB2cHaAdpB2oHawdsB20HbgdvB3AHcQdyB3MHdAd1B3YHdwd4BE5VTEwGQWJyZXZlB3VuaTFFQUUHdW5pMUVCNgd1bmkxRUIwB3VuaTFFQjIHdW5pMUVCNAd1bmkwMUNEB3VuaTFFQTQHdW5pMUVBQwd1bmkxRUE2B3VuaTFFQTgHdW5pMUVBQQd1bmkwMjAwB3VuaTFFQTAHdW5pMUVBMgd1bmkwMjAyB0FtYWNyb24HQW9nb25lawpBcmluZ2FjdXRlB0FFYWN1dGUHdW5pMUUwOAtDY2lyY3VtZmxleApDZG90YWNjZW50B3VuaTAxQzQGRGNhcm9uBkRjcm9hdAd1bmkxRTBDB3VuaTFFMEUHdW5pMDFDNQZFYnJldmUGRWNhcm9uB3VuaTFFMUMHdW5pMUVCRQd1bmkxRUM2B3VuaTFFQzAHdW5pMUVDMgd1bmkxRUM0B3VuaTAyMDQKRWRvdGFjY2VudAd1bmkxRUI4B3VuaTFFQkEHdW5pMDIwNgdFbWFjcm9uB3VuaTFFMTYHdW5pMUUxNAdFb2dvbmVrB3VuaTFFQkMHdW5pMDFCNwd1bmkwMUVFBkdjYXJvbgtHY2lyY3VtZmxleAxHY29tbWFhY2NlbnQKR2RvdGFjY2VudAd1bmkxRTIwB3VuaTAxRTQESGJhcgd1bmkxRTJBB3VuaTAyMUULSGNpcmN1bWZsZXgHdW5pMUUyNAJJSgZJYnJldmUHdW5pMDIwOAd1bmkxRTJFB3VuaTFFQ0EHdW5pMUVDOAd1bmkwMjBBB0ltYWNyb24HSW9nb25lawZJdGlsZGULSmNpcmN1bWZsZXgHdW5pMDFFOAxLY29tbWFhY2NlbnQHdW5pMDFDNwZMYWN1dGUGTGNhcm9uDExjb21tYWFjY2VudARMZG90B3VuaTFFMzYHdW5pMDFDOAd1bmkxRTNBB3VuaTFFNDIHdW5pMDFDQQZOYWN1dGUGTmNhcm9uDE5jb21tYWFjY2VudAd1bmkxRTQ0B3VuaTFFNDYDRW5nB3VuaTAxQ0IHdW5pMUU0OAZPYnJldmUHdW5pMUVEMAd1bmkxRUQ4B3VuaTFFRDIHdW5pMUVENAd1bmkxRUQ2B3VuaTAyMEMHdW5pMDIyQQd1bmkwMjMwB3VuaTFFQ0MHdW5pMUVDRQVPaG9ybgd1bmkxRURBB3VuaTFFRTIHdW5pMUVEQwd1bmkxRURFB3VuaTFFRTANT2h1bmdhcnVtbGF1dAd1bmkwMjBFB09tYWNyb24HdW5pMUU1Mgd1bmkxRTUwB3VuaTAxRUELT3NsYXNoYWN1dGUHdW5pMUU0Qwd1bmkxRTRFB3VuaTAyMkMGUmFjdXRlBlJjYXJvbgxSY29tbWFhY2NlbnQHdW5pMDIxMAd1bmkxRTVBB3VuaTAyMTIHdW5pMUU1RQZTYWN1dGUHdW5pMUU2NAd1bmlBNzhCB3VuaTFFNjYLU2NpcmN1bWZsZXgMU2NvbW1hYWNjZW50B3VuaTFFNjAHdW5pMUU2Mgd1bmkxRTY4B3VuaTFFOUUHdW5pMDE4RgRUYmFyBlRjYXJvbgd1bmkwMTYyB3VuaTAyMUEHdW5pMUU2Qwd1bmkxRTZFBlVicmV2ZQd1bmkwMUQzB3VuaTAyMTQHdW5pMUVFNAd1bmkxRUU2BVVob3JuB3VuaTFFRTgHdW5pMUVGMAd1bmkxRUVBB3VuaTFFRUMHdW5pMUVFRQ1VaHVuZ2FydW1sYXV0B3VuaTAyMTYHVW1hY3Jvbgd1bmkxRTdBB1VvZ29uZWsFVXJpbmcGVXRpbGRlB3VuaTFFNzgGV2FjdXRlC1djaXJjdW1mbGV4CVdkaWVyZXNpcwZXZ3JhdmULWWNpcmN1bWZsZXgHdW5pMUU4RQd1bmkxRUY0BllncmF2ZQd1bmkxRUY2B3VuaTAyMzIHdW5pMUVGOAZaYWN1dGUKWmRvdGFjY2VudAd1bmkxRTkyEElhY3V0ZV9KLmxvY2xOTEQGQS5zczAxC0FhY3V0ZS5zczAxC0FicmV2ZS5zczAxDHVuaTFFQUUuc3MwMQx1bmkxRUI2LnNzMDEMdW5pMUVCMC5zczAxDHVuaTFFQjIuc3MwMQx1bmkxRUI0LnNzMDEMdW5pMDFDRC5zczAxEEFjaXJjdW1mbGV4LnNzMDEMdW5pMUVBNC5zczAxDHVuaTFFQUMuc3MwMQx1bmkxRUE2LnNzMDEMdW5pMUVBOC5zczAxDHVuaTFFQUEuc3MwMQx1bmkwMjAwLnNzMDEOQWRpZXJlc2lzLnNzMDEMdW5pMUVBMC5zczAxC0FncmF2ZS5zczAxDHVuaTFFQTIuc3MwMQx1bmkwMjAyLnNzMDEMQW1hY3Jvbi5zczAxDEFvZ29uZWsuc3MwMQpBcmluZy5zczAxD0FyaW5nYWN1dGUuc3MwMQtBdGlsZGUuc3MwMQdBRS5zczAxDEFFYWN1dGUuc3MwMQx1bmkwMUM0LnNzMDEMdW5pMDFDNS5zczAxBkUuc3MwMQtFYWN1dGUuc3MwMQtFYnJldmUuc3MwMQtFY2Fyb24uc3MwMQx1bmkxRTFDLnNzMDEQRWNpcmN1bWZsZXguc3MwMQx1bmkxRUJFLnNzMDEMdW5pMUVDNi5zczAxDHVuaTFFQzAuc3MwMQx1bmkxRUMyLnNzMDEMdW5pMUVDNC5zczAxDHVuaTAyMDQuc3MwMQ5FZGllcmVzaXMuc3MwMQ9FZG90YWNjZW50LnNzMDEMdW5pMUVCOC5zczAxC0VncmF2ZS5zczAxDHVuaTFFQkEuc3MwMQx1bmkwMjA2LnNzMDEMRW1hY3Jvbi5zczAxDHVuaTFFMTYuc3MwMQx1bmkxRTE0LnNzMDEMRW9nb25lay5zczAxDHVuaTFFQkMuc3MwMQZGLnNzMDEGRy5zczAxC0dicmV2ZS5zczAxC0djYXJvbi5zczAxEEdjaXJjdW1mbGV4LnNzMDERR2NvbW1hYWNjZW50LnNzMDEPR2RvdGFjY2VudC5zczAxDHVuaTFFMjAuc3MwMQx1bmkwMUU0LnNzMDEGSS5zczAxB0lKLnNzMDELSWFjdXRlLnNzMDEVSWFjdXRlX0oubG9jbE5MRC5zczAxC0licmV2ZS5zczAxEEljaXJjdW1mbGV4LnNzMDEMdW5pMDIwOC5zczAxDklkaWVyZXNpcy5zczAxDHVuaTFFMkUuc3MwMQ9JZG90YWNjZW50LnNzMDEMdW5pMUVDQS5zczAxC0lncmF2ZS5zczAxDHVuaTFFQzguc3MwMQx1bmkwMjBBLnNzMDEMSW1hY3Jvbi5zczAxDElvZ29uZWsuc3MwMQtJdGlsZGUuc3MwMQZKLnNzMDEQSmNpcmN1bWZsZXguc3MwMQx1bmkwMUM3LnNzMDEGTS5zczAxDHVuaTFFNDIuc3MwMQZOLnNzMDEMdW5pMDFDQS5zczAxC05hY3V0ZS5zczAxC05jYXJvbi5zczAxEU5jb21tYWFjY2VudC5zczAxDHVuaTFFNDQuc3MwMQx1bmkxRTQ2LnNzMDEIRW5nLnNzMDEMdW5pMDFDQi5zczAxDHVuaTFFNDguc3MwMQtOdGlsZGUuc3MwMQZRLnNzMDEMdW5pMDE4Ri5zczAxBlQuc3MwMQlUYmFyLnNzMDELVGNhcm9uLnNzMDEMdW5pMDE2Mi5zczAxDHVuaTAyMUEuc3MwMQx1bmkxRTZDLnNzMDEMdW5pMUU2RS5zczAxBlUuc3MwMQtVYWN1dGUuc3MwMQtVYnJldmUuc3MwMQx1bmkwMUQzLnNzMDEQVWNpcmN1bWZsZXguc3MwMQx1bmkwMjE0LnNzMDEOVWRpZXJlc2lzLnNzMDEMdW5pMUVFNC5zczAxC1VncmF2ZS5zczAxDHVuaTFFRTYuc3MwMQpVaG9ybi5zczAxDHVuaTFFRTguc3MwMQx1bmkxRUYwLnNzMDEMdW5pMUVFQS5zczAxDHVuaTFFRUMuc3MwMQx1bmkxRUVFLnNzMDESVWh1bmdhcnVtbGF1dC5zczAxDHVuaTAyMTYuc3MwMQxVbWFjcm9uLnNzMDEMdW5pMUU3QS5zczAxDFVvZ29uZWsuc3MwMQpVcmluZy5zczAxC1V0aWxkZS5zczAxDHVuaTFFNzguc3MwMQZXLnNzMDELV2FjdXRlLnNzMDEQV2NpcmN1bWZsZXguc3MwMQ5XZGllcmVzaXMuc3MwMQtXZ3JhdmUuc3MwMQZZLnNzMDELWWFjdXRlLnNzMDEQWWNpcmN1bWZsZXguc3MwMQ5ZZGllcmVzaXMuc3MwMQx1bmkxRThFLnNzMDEMdW5pMUVGNC5zczAxC1lncmF2ZS5zczAxDHVuaTFFRjYuc3MwMQx1bmkwMjMyLnNzMDEMdW5pMUVGOC5zczAxBlouc3MwMQtaYWN1dGUuc3MwMQtaY2Fyb24uc3MwMQ9aZG90YWNjZW50LnNzMDEMdW5pMUU5Mi5zczAxBmFicmV2ZQd1bmkxRUFGB3VuaTFFQjcHdW5pMUVCMQd1bmkxRUIzB3VuaTFFQjUHdW5pMDFDRQd1bmkxRUE1B3VuaTFFQUQHdW5pMUVBNwd1bmkxRUE5B3VuaTFFQUIHdW5pMDIwMQd1bmkxRUExB3VuaTFFQTMHdW5pMDIwMwdhbWFjcm9uB2FvZ29uZWsKYXJpbmdhY3V0ZQdhZWFjdXRlB3VuaTFFMDkLY2NpcmN1bWZsZXgKY2RvdGFjY2VudAZkY2Fyb24HdW5pMUUwRAd1bmkxRTBGB3VuaTAxQzYGZWJyZXZlBmVjYXJvbgd1bmkxRTFEB3VuaTFFQkYHdW5pMUVDNwd1bmkxRUMxB3VuaTFFQzMHdW5pMUVDNQd1bmkwMjA1CmVkb3RhY2NlbnQHdW5pMUVCOQd1bmkxRUJCB3VuaTAyMDcHZW1hY3Jvbgd1bmkxRTE3B3VuaTFFMTUHZW9nb25lawd1bmkxRUJEB3VuaTAyNTkHdW5pMDI5Mgd1bmkwMUVGBmdjYXJvbgtnY2lyY3VtZmxleAxnY29tbWFhY2NlbnQKZ2RvdGFjY2VudAd1bmkxRTIxB3VuaTAxRTUEaGJhcgd1bmkxRTJCB3VuaTAyMUYLaGNpcmN1bWZsZXgHdW5pMUUyNQZpYnJldmUHdW5pMDIwOQd1bmkxRTJGCWkubG9jbFRSSwd1bmkxRUNCB3VuaTFFQzkHdW5pMDIwQgJpagdpbWFjcm9uB2lvZ29uZWsGaXRpbGRlB3VuaTAyMzcLamNpcmN1bWZsZXgHdW5pMDFFOQxrY29tbWFhY2NlbnQMa2dyZWVubGFuZGljBmxhY3V0ZQZsY2Fyb24MbGNvbW1hYWNjZW50BGxkb3QHdW5pMUUzNwd1bmkwMUM5B3VuaTFFM0IHdW5pMUU0MwZuYWN1dGULbmFwb3N0cm9waGUGbmNhcm9uDG5jb21tYWFjY2VudAd1bmkxRTQ1B3VuaTFFNDcDZW5nB3VuaTAxQ0MHdW5pMUU0OQZvYnJldmUHdW5pMUVEMQd1bmkxRUQ5B3VuaTFFRDMHdW5pMUVENQd1bmkxRUQ3B3VuaTAyMEQHdW5pMDIyQgd1bmkwMjMxB3VuaTFFQ0QHdW5pMUVDRgVvaG9ybgd1bmkxRURCB3VuaTFFRTMHdW5pMUVERAd1bmkxRURGB3VuaTFFRTENb2h1bmdhcnVtbGF1dAd1bmkwMjBGB29tYWNyb24HdW5pMUU1Mwd1bmkxRTUxB3VuaTAxRUILb3NsYXNoYWN1dGUHdW5pMUU0RAd1bmkxRTRGB3VuaTAyMkQGcmFjdXRlBnJjYXJvbgxyY29tbWFhY2NlbnQHdW5pMDIxMQd1bmkxRTVCB3VuaTAyMTMHdW5pMUU1RgZzYWN1dGUHdW5pMUU2NQd1bmlBNzhDB3VuaTFFNjcLc2NpcmN1bWZsZXgMc2NvbW1hYWNjZW50B3VuaTFFNjEHdW5pMUU2Mwd1bmkxRTY5BWxvbmdzBHRiYXIGdGNhcm9uB3VuaTAxNjMHdW5pMDIxQgd1bmkxRTk3B3VuaTFFNkQHdW5pMUU2RgZ1YnJldmUHdW5pMDFENAd1bmkwMjE1B3VuaTFFRTUHdW5pMUVFNwV1aG9ybgd1bmkxRUU5B3VuaTFFRjEHdW5pMUVFQgd1bmkxRUVEB3VuaTFFRUYNdWh1bmdhcnVtbGF1dAd1bmkwMjE3B3VtYWNyb24HdW5pMUU3Qgd1b2dvbmVrBXVyaW5nBnV0aWxkZQd1bmkxRTc5BndhY3V0ZQt3Y2lyY3VtZmxleAl3ZGllcmVzaXMGd2dyYXZlC3ljaXJjdW1mbGV4B3VuaTFFOEYHdW5pMUVGNQZ5Z3JhdmUHdW5pMUVGNwd1bmkwMjMzB3VuaTFFRjkGemFjdXRlCnpkb3RhY2NlbnQHdW5pMUU5MxBpYWN1dGVfai5sb2NsTkxEBmEuc3MwMQthYWN1dGUuc3MwMQthYnJldmUuc3MwMQx1bmkxRUFGLnNzMDEMdW5pMUVCNy5zczAxDHVuaTFFQjEuc3MwMQx1bmkxRUIzLnNzMDEMdW5pMUVCNS5zczAxDHVuaTAxQ0Uuc3MwMRBhY2lyY3VtZmxleC5zczAxDHVuaTFFQTUuc3MwMQx1bmkxRUFELnNzMDEMdW5pMUVBNy5zczAxDHVuaTFFQTkuc3MwMQx1bmkxRUFCLnNzMDEMdW5pMDIwMS5zczAxDmFkaWVyZXNpcy5zczAxDHVuaTFFQTEuc3MwMQthZ3JhdmUuc3MwMQx1bmkxRUEzLnNzMDEMdW5pMDIwMy5zczAxDGFtYWNyb24uc3MwMQxhb2dvbmVrLnNzMDEKYXJpbmcuc3MwMQ9hcmluZ2FjdXRlLnNzMDELYXRpbGRlLnNzMDEHYWUuc3MwMQxhZWFjdXRlLnNzMDEMdW5pMDFDNi5zczAxBmUuc3MwMQtlYWN1dGUuc3MwMQtlYnJldmUuc3MwMQtlY2Fyb24uc3MwMQx1bmkxRTFELnNzMDEQZWNpcmN1bWZsZXguc3MwMQx1bmkxRUJGLnNzMDEMdW5pMUVDNy5zczAxDHVuaTFFQzEuc3MwMQx1bmkxRUMzLnNzMDEMdW5pMUVDNS5zczAxDHVuaTAyMDUuc3MwMQ5lZGllcmVzaXMuc3MwMQ9lZG90YWNjZW50LnNzMDEMdW5pMUVCOS5zczAxC2VncmF2ZS5zczAxDHVuaTFFQkIuc3MwMQx1bmkwMjA3LnNzMDEMZW1hY3Jvbi5zczAxDHVuaTFFMTcuc3MwMQx1bmkxRTE1LnNzMDEMZW9nb25lay5zczAxDHVuaTFFQkQuc3MwMQx1bmkwMjU5LnNzMDEGZi5zczAxBmwuc3MwMQtsYWN1dGUuc3MwMQtsY2Fyb24uc3MwMRFsY29tbWFhY2NlbnQuc3MwMQlsZG90LnNzMDEMdW5pMUUzNy5zczAxDHVuaTAxQzkuc3MwMQx1bmkxRTNCLnNzMDELbHNsYXNoLnNzMDEHb2Uuc3MwMQZ0LnNzMDEJdGJhci5zczAxC3RjYXJvbi5zczAxDHVuaTAxNjMuc3MwMQx1bmkwMjFCLnNzMDEMdW5pMUU5Ny5zczAxDHVuaTFFNkQuc3MwMQx1bmkxRTZGLnNzMDEGdy5zczAxC3dhY3V0ZS5zczAxEHdjaXJjdW1mbGV4LnNzMDEOd2RpZXJlc2lzLnNzMDELd2dyYXZlLnNzMDEGeS5zczAxC3lhY3V0ZS5zczAxEHljaXJjdW1mbGV4LnNzMDEOeWRpZXJlc2lzLnNzMDEMdW5pMUVGNS5zczAxC3lncmF2ZS5zczAxDHVuaTFFRjcuc3MwMQx1bmkwMjMzLnNzMDEMdW5pMUVGOS5zczAxBnouc3MwMQt6YWN1dGUuc3MwMQt6Y2Fyb24uc3MwMQ96ZG90YWNjZW50LnNzMDEMdW5pMUU5My5zczAxA1RfaAdmaS5zczAxB2ZsLnNzMDEEYS5zYwlhYWN1dGUuc2MJYWJyZXZlLnNjCnVuaTFFQUYuc2MKdW5pMUVCNy5zYwp1bmkxRUIxLnNjCnVuaTFFQjMuc2MKdW5pMUVCNS5zYwp1bmkwMUNFLnNjDmFjaXJjdW1mbGV4LnNjCnVuaTFFQTUuc2MKdW5pMUVBRC5zYwp1bmkxRUE3LnNjCnVuaTFFQTkuc2MKdW5pMUVBQi5zYwp1bmkwMjAxLnNjDGFkaWVyZXNpcy5zYwp1bmkxRUExLnNjCWFncmF2ZS5zYwp1bmkxRUEzLnNjCnVuaTAyMDMuc2MKYW1hY3Jvbi5zYwphb2dvbmVrLnNjCGFyaW5nLnNjDWFyaW5nYWN1dGUuc2MJYXRpbGRlLnNjBWFlLnNjCmFlYWN1dGUuc2MEYi5zYwRjLnNjCWNhY3V0ZS5zYwljY2Fyb24uc2MLY2NlZGlsbGEuc2MKdW5pMUUwOS5zYw5jY2lyY3VtZmxleC5zYw1jZG90YWNjZW50LnNjBGQuc2MGZXRoLnNjCWRjYXJvbi5zYwlkY3JvYXQuc2MKdW5pMUUwRC5zYwp1bmkxRTBGLnNjCnVuaTAxQzYuc2MEZS5zYwllYWN1dGUuc2MJZWJyZXZlLnNjCWVjYXJvbi5zYwp1bmkxRTFELnNjDmVjaXJjdW1mbGV4LnNjCnVuaTFFQkYuc2MKdW5pMUVDNy5zYwp1bmkxRUMxLnNjCnVuaTFFQzMuc2MKdW5pMUVDNS5zYwp1bmkwMjA1LnNjDGVkaWVyZXNpcy5zYw1lZG90YWNjZW50LnNjCnVuaTFFQjkuc2MJZWdyYXZlLnNjCnVuaTFFQkIuc2MKdW5pMDIwNy5zYwplbWFjcm9uLnNjCnVuaTFFMTcuc2MKdW5pMUUxNS5zYwplb2dvbmVrLnNjCnVuaTFFQkQuc2MKdW5pMDI1OS5zYwp1bmkwMjkyLnNjCnVuaTAxRUYuc2MEZi5zYwRnLnNjCWdicmV2ZS5zYwlnY2Fyb24uc2MOZ2NpcmN1bWZsZXguc2MPZ2NvbW1hYWNjZW50LnNjDWdkb3RhY2NlbnQuc2MKdW5pMUUyMS5zYwp1bmkwMUU1LnNjBGguc2MHaGJhci5zYwp1bmkxRTJCLnNjCnVuaTAyMUYuc2MOaGNpcmN1bWZsZXguc2MKdW5pMUUyNS5zYwRpLnNjC2RvdGxlc3NpLnNjCWlhY3V0ZS5zYxNpYWN1dGVfai5sb2NsTkxELnNjCWlicmV2ZS5zYw5pY2lyY3VtZmxleC5zYwp1bmkwMjA5LnNjDGlkaWVyZXNpcy5zYwp1bmkxRTJGLnNjDGkuc2MubG9jbFRSSwp1bmkxRUNCLnNjCWlncmF2ZS5zYwp1bmkxRUM5LnNjCnVuaTAyMEIuc2MFaWouc2MKaW1hY3Jvbi5zYwppb2dvbmVrLnNjCWl0aWxkZS5zYwRqLnNjDmpjaXJjdW1mbGV4LnNjBGsuc2MKdW5pMDFFOS5zYw9rY29tbWFhY2NlbnQuc2MPa2dyZWVubGFuZGljLnNjBGwuc2MJbGFjdXRlLnNjCWxjYXJvbi5zYw9sY29tbWFhY2NlbnQuc2MHbGRvdC5zYwp1bmkxRTM3LnNjCnVuaTAxQzkuc2MKdW5pMUUzQi5zYwlsc2xhc2guc2MEbS5zYwp1bmkxRTQzLnNjBG4uc2MJbmFjdXRlLnNjCW5jYXJvbi5zYw9uY29tbWFhY2NlbnQuc2MKdW5pMUU0NS5zYwp1bmkxRTQ3LnNjBmVuZy5zYwp1bmkwMUNDLnNjCnVuaTFFNDkuc2MJbnRpbGRlLnNjBG8uc2MJb2FjdXRlLnNjCW9icmV2ZS5zYw5vY2lyY3VtZmxleC5zYwp1bmkxRUQxLnNjCnVuaTFFRDkuc2MKdW5pMUVEMy5zYwp1bmkxRUQ1LnNjCnVuaTFFRDcuc2MKdW5pMDIwRC5zYwxvZGllcmVzaXMuc2MKdW5pMDIyQi5zYwp1bmkwMjMxLnNjCnVuaTFFQ0Quc2MJb2dyYXZlLnNjCnVuaTFFQ0Yuc2MIb2hvcm4uc2MKdW5pMUVEQi5zYwp1bmkxRUUzLnNjCnVuaTFFREQuc2MKdW5pMUVERi5zYwp1bmkxRUUxLnNjEG9odW5nYXJ1bWxhdXQuc2MKdW5pMDIwRi5zYwpvbWFjcm9uLnNjCnVuaTFFNTMuc2MKdW5pMUU1MS5zYwp1bmkwMUVCLnNjCW9zbGFzaC5zYw5vc2xhc2hhY3V0ZS5zYwlvdGlsZGUuc2MKdW5pMUU0RC5zYwp1bmkxRTRGLnNjCnVuaTAyMkQuc2MFb2Uuc2MEcC5zYwh0aG9ybi5zYwRxLnNjBHIuc2MJcmFjdXRlLnNjCXJjYXJvbi5zYw9yY29tbWFhY2NlbnQuc2MKdW5pMDIxMS5zYwp1bmkxRTVCLnNjCnVuaTAyMTMuc2MKdW5pMUU1Ri5zYwRzLnNjCXNhY3V0ZS5zYwp1bmkxRTY1LnNjCnVuaUE3OEMuc2MJc2Nhcm9uLnNjCnVuaTFFNjcuc2MLc2NlZGlsbGEuc2MOc2NpcmN1bWZsZXguc2MPc2NvbW1hYWNjZW50LnNjCnVuaTFFNjEuc2MKdW5pMUU2My5zYwp1bmkxRTY5LnNjDWdlcm1hbmRibHMuc2MEdC5zYwd0YmFyLnNjCXRjYXJvbi5zYwp1bmkwMTYzLnNjCnVuaTAyMUIuc2MKdW5pMUU5Ny5zYwp1bmkxRTZELnNjCnVuaTFFNkYuc2MEdS5zYwl1YWN1dGUuc2MJdWJyZXZlLnNjCnVuaTAxRDQuc2MOdWNpcmN1bWZsZXguc2MKdW5pMDIxNS5zYwx1ZGllcmVzaXMuc2MKdW5pMUVFNS5zYwl1Z3JhdmUuc2MKdW5pMUVFNy5zYwh1aG9ybi5zYwp1bmkxRUU5LnNjCnVuaTFFRjEuc2MKdW5pMUVFQi5zYwp1bmkxRUVELnNjCnVuaTFFRUYuc2MQdWh1bmdhcnVtbGF1dC5zYwp1bmkwMjE3LnNjCnVtYWNyb24uc2MKdW5pMUU3Qi5zYwp1b2dvbmVrLnNjCHVyaW5nLnNjCXV0aWxkZS5zYwp1bmkxRTc5LnNjBHYuc2MEdy5zYwl3YWN1dGUuc2MOd2NpcmN1bWZsZXguc2MMd2RpZXJlc2lzLnNjCXdncmF2ZS5zYwR4LnNjBHkuc2MJeWFjdXRlLnNjDnljaXJjdW1mbGV4LnNjDHlkaWVyZXNpcy5zYwp1bmkxRThGLnNjCnVuaTFFRjUuc2MJeWdyYXZlLnNjCnVuaTFFRjcuc2MKdW5pMDIzMy5zYwp1bmkxRUY5LnNjBHouc2MJemFjdXRlLnNjCXpjYXJvbi5zYw16ZG90YWNjZW50LnNjCnVuaTFFOTMuc2MJYS5zYy5zczAxDmFhY3V0ZS5zYy5zczAxDmFicmV2ZS5zYy5zczAxD3VuaTFFQUYuc2Muc3MwMQ91bmkxRUI3LnNjLnNzMDEPdW5pMUVCMS5zYy5zczAxD3VuaTFFQjMuc2Muc3MwMQ91bmkxRUI1LnNjLnNzMDEPdW5pMDFDRS5zYy5zczAxE2FjaXJjdW1mbGV4LnNjLnNzMDEPdW5pMUVBNS5zYy5zczAxD3VuaTFFQUQuc2Muc3MwMQ91bmkxRUE3LnNjLnNzMDEPdW5pMUVBOS5zYy5zczAxD3VuaTFFQUIuc2Muc3MwMQ91bmkwMjAxLnNjLnNzMDERYWRpZXJlc2lzLnNjLnNzMDEPdW5pMUVBMS5zYy5zczAxDmFncmF2ZS5zYy5zczAxD3VuaTFFQTMuc2Muc3MwMQ91bmkwMjAzLnNjLnNzMDEPYW1hY3Jvbi5zYy5zczAxD2FvZ29uZWsuc2Muc3MwMQ1hcmluZy5zYy5zczAxEmFyaW5nYWN1dGUuc2Muc3MwMQ5hdGlsZGUuc2Muc3MwMQphZS5zYy5zczAxD2FlYWN1dGUuc2Muc3MwMQ91bmkwMUM2LnNjLnNzMDEJZS5zYy5zczAxDmVhY3V0ZS5zYy5zczAxDmVicmV2ZS5zYy5zczAxDmVjYXJvbi5zYy5zczAxD3VuaTFFMUQuc2Muc3MwMRNlY2lyY3VtZmxleC5zYy5zczAxD3VuaTFFQkYuc2Muc3MwMQ91bmkxRUM3LnNjLnNzMDEPdW5pMUVDMS5zYy5zczAxD3VuaTFFQzMuc2Muc3MwMQ91bmkxRUM1LnNjLnNzMDEPdW5pMDIwNS5zYy5zczAxEWVkaWVyZXNpcy5zYy5zczAxEmVkb3RhY2NlbnQuc2Muc3MwMQ91bmkxRUI5LnNjLnNzMDEOZWdyYXZlLnNjLnNzMDEPdW5pMUVCQi5zYy5zczAxD3VuaTAyMDcuc2Muc3MwMQ9lbWFjcm9uLnNjLnNzMDEPdW5pMUUxNy5zYy5zczAxD3VuaTFFMTUuc2Muc3MwMQ9lb2dvbmVrLnNjLnNzMDEPdW5pMUVCRC5zYy5zczAxD3VuaTAyNTkuc2Muc3MwMQlmLnNjLnNzMDEJZy5zYy5zczAxDmdicmV2ZS5zYy5zczAxDmdjYXJvbi5zYy5zczAxE2djaXJjdW1mbGV4LnNjLnNzMDEUZ2NvbW1hYWNjZW50LnNjLnNzMDESZ2RvdGFjY2VudC5zYy5zczAxD3VuaTFFMjEuc2Muc3MwMQ91bmkwMUU1LnNjLnNzMDEJaS5zYy5zczAxEGRvdGxlc3NpLnNjLnNzMDEOaWFjdXRlLnNjLnNzMDEYaWFjdXRlX2oubG9jbE5MRC5zYy5zczAxDmlicmV2ZS5zYy5zczAxE2ljaXJjdW1mbGV4LnNjLnNzMDEPdW5pMDIwOS5zYy5zczAxEWlkaWVyZXNpcy5zYy5zczAxD3VuaTFFMkYuc2Muc3MwMQ91bmkxRUNCLnNjLnNzMDEOaWdyYXZlLnNjLnNzMDEPdW5pMUVDOS5zYy5zczAxD3VuaTAyMEIuc2Muc3MwMQppai5zYy5zczAxD2ltYWNyb24uc2Muc3MwMQ9pb2dvbmVrLnNjLnNzMDEOaXRpbGRlLnNjLnNzMDEJai5zYy5zczAxE2pjaXJjdW1mbGV4LnNjLnNzMDEPdW5pMDFDOS5zYy5zczAxCW0uc2Muc3MwMQ91bmkxRTQzLnNjLnNzMDEJbi5zYy5zczAxDm5hY3V0ZS5zYy5zczAxDm5jYXJvbi5zYy5zczAxFG5jb21tYWFjY2VudC5zYy5zczAxD3VuaTFFNDUuc2Muc3MwMQ91bmkxRTQ3LnNjLnNzMDELZW5nLnNjLnNzMDEPdW5pMDFDQy5zYy5zczAxD3VuaTFFNDkuc2Muc3MwMQ5udGlsZGUuc2Muc3MwMQlxLnNjLnNzMDEJdC5zYy5zczAxDHRiYXIuc2Muc3MwMQ50Y2Fyb24uc2Muc3MwMQ91bmkwMTYzLnNjLnNzMDEPdW5pMDIxQi5zYy5zczAxD3VuaTFFOTcuc2Muc3MwMQ91bmkxRTZELnNjLnNzMDEPdW5pMUU2Ri5zYy5zczAxCXUuc2Muc3MwMQ51YWN1dGUuc2Muc3MwMQ51YnJldmUuc2Muc3MwMQ91bmkwMUQ0LnNjLnNzMDETdWNpcmN1bWZsZXguc2Muc3MwMQ91bmkwMjE1LnNjLnNzMDERdWRpZXJlc2lzLnNjLnNzMDEPdW5pMUVFNS5zYy5zczAxDnVncmF2ZS5zYy5zczAxD3VuaTFFRTcuc2Muc3MwMQ11aG9ybi5zYy5zczAxD3VuaTFFRTkuc2Muc3MwMQ91bmkxRUYxLnNjLnNzMDEPdW5pMUVFQi5zYy5zczAxD3VuaTFFRUQuc2Muc3MwMQ91bmkxRUVGLnNjLnNzMDEVdWh1bmdhcnVtbGF1dC5zYy5zczAxD3VuaTAyMTcuc2Muc3MwMQ91bWFjcm9uLnNjLnNzMDEPdW5pMUU3Qi5zYy5zczAxD3VvZ29uZWsuc2Muc3MwMQ11cmluZy5zYy5zczAxDnV0aWxkZS5zYy5zczAxD3VuaTFFNzkuc2Muc3MwMQl3LnNjLnNzMDEOd2FjdXRlLnNjLnNzMDETd2NpcmN1bWZsZXguc2Muc3MwMRF3ZGllcmVzaXMuc2Muc3MwMQ53Z3JhdmUuc2Muc3MwMQl5LnNjLnNzMDEOeWFjdXRlLnNjLnNzMDETeWNpcmN1bWZsZXguc2Muc3MwMRF5ZGllcmVzaXMuc2Muc3MwMQ91bmkxRThGLnNjLnNzMDEPdW5pMUVGNS5zYy5zczAxDnlncmF2ZS5zYy5zczAxD3VuaTFFRjcuc2Muc3MwMQ91bmkwMjMzLnNjLnNzMDEPdW5pMUVGOS5zYy5zczAxCXouc2Muc3MwMQ56YWN1dGUuc2Muc3MwMQ56Y2Fyb24uc2Muc3MwMRJ6ZG90YWNjZW50LnNjLnNzMDEPdW5pMUU5My5zYy5zczAxB3VuaTA0MTAHdW5pMDQxMQd1bmkwNDEyB3VuaTA0MTMHdW5pMDQwMwd1bmkwNDkwB3VuaTA0MTQHdW5pMDQxNQd1bmkwNDAwB3VuaTA0MDEHdW5pMDQxNgd1bmkwNDE3B3VuaTA0MTgHdW5pMDQxOQd1bmkwNDBEB3VuaTA0OEEHdW5pMDQxQQd1bmkwNDBDB3VuaTA0MUIHdW5pMDQxQwd1bmkwNDFEB3VuaTA0MUUHdW5pMDQxRgd1bmkwNDIwB3VuaTA0MjEHdW5pMDQyMgd1bmkwNDIzB3VuaTA0MEUHdW5pMDQyNAd1bmkwNDI1B3VuaTA0MjcHdW5pMDQyNgd1bmkwNDI4B3VuaTA0MjkHdW5pMDQwRgd1bmkwNDJDB3VuaTA0MkEHdW5pMDQyQgd1bmkwNDA5B3VuaTA0MEEHdW5pMDQwNQd1bmkwNDA0B3VuaTA0MkQHdW5pMDQwNgd1bmkwNDA3B3VuaTA0MDgHdW5pMDQwQgd1bmkwNDJFB3VuaTA0MkYHdW5pMDQwMgd1bmkwNDYyB3VuaTA0NkEHdW5pMDQ3Mgd1bmkwNDc0B3VuaTA0OTIHdW5pMDQ5NAd1bmkwNDk2B3VuaTA0OTgHdW5pMDQ5QQd1bmkwNDlDB3VuaTA0OUUHdW5pMDRBMAd1bmkwNEEyB3VuaTA0QTQHdW5pMDRBNgd1bmkwNTI0B3VuaTA0QTgHdW5pMDRBQQd1bmkwNEFDB3VuaTA0QUUHdW5pMDRCMAd1bmkwNEIyB3VuaTA0QjQHdW5pMDRCNgd1bmkwNEI4B3VuaTA0QkEHdW5pMDUyNgd1bmkwNEJDB3VuaTA0QkUHdW5pMDRDMAd1bmkwNEMxB3VuaTA0QzMHdW5pMDRDNwd1bmkwNEM5B3VuaTA0Q0IHdW5pMDRDRAd1bmkwNEQwB3VuaTA0RDIHdW5pMDRENAd1bmkwNEQ2B3VuaTA0RDgHdW5pMDREQQd1bmkwNERDB3VuaTA0REUHdW5pMDRFMAd1bmkwNEUyB3VuaTA0RTQHdW5pMDRFNgd1bmkwNEU4B3VuaTA0RUEHdW5pMDRFQwd1bmkwNEVFB3VuaTA0RjAHdW5pMDRGMgd1bmkwNEY0B3VuaTA0RjYHdW5pMDRGOAd1bmkwNEZBB3VuaTA0RkMHdW5pMDRGRQd1bmkwNTEwB3VuaTA1MTIHdW5pMDUxQQd1bmkwNTFDB3VuaTA0OEMHdW5pMDQ4RQd1bmkwNTI4B3VuaTA1MkUPdW5pMDQxNC5sb2NsQkdSD3VuaTA0MUIubG9jbEJHUg91bmkwNDI0LmxvY2xCR1IPdW5pMDQ5Mi5sb2NsQlNID3VuaTA0OTgubG9jbEJTSA91bmkwNEFBLmxvY2xCU0gPdW5pMDRBQS5sb2NsQ0hVDHVuaTA0MTAuc3MwMQx1bmkwNDE0LnNzMDEMdW5pMDQxNS5zczAxDHVuaTA0MDAuc3MwMQx1bmkwNDAxLnNzMDEMdW5pMDQxOC5zczAxDHVuaTA0MTkuc3MwMQx1bmkwNDhBLnNzMDEMdW5pMDQwRC5zczAxDHVuaTA0MUIuc3MwMQx1bmkwNDIwLnNzMDEMdW5pMDQyMi5zczAxDHVuaTA0MjMuc3MwMQx1bmkwNDBFLnNzMDEMdW5pMDQyNC5zczAxDHVuaTA0MkMuc3MwMQx1bmkwNDJBLnNzMDEMdW5pMDQyQi5zczAxDHVuaTA0MDkuc3MwMQx1bmkwNDBBLnNzMDEMdW5pMDQwOC5zczAxDHVuaTA0NjIuc3MwMQx1bmkwNEFDLnNzMDEMdW5pMDREMC5zczAxDHVuaTA0RDIuc3MwMQx1bmkwNEQ0LnNzMDEMdW5pMDRENi5zczAxDHVuaTA0RTIuc3MwMQx1bmkwNEU0LnNzMDEMdW5pMDRFRS5zczAxDHVuaTA0RjAuc3MwMQx1bmkwNEYyLnNzMDEMdW5pMDRGOC5zczAxDHVuaTA1MUEuc3MwMQx1bmkwNDhDLnNzMDEHdW5pMDQzMAd1bmkwNDMxB3VuaTA0MzIHdW5pMDQzMwd1bmkwNDUzB3VuaTA0OTEHdW5pMDQzNAd1bmkwNDM1B3VuaTA0NTAHdW5pMDQ1MQd1bmkwNDM2B3VuaTA0MzcHdW5pMDQzOAd1bmkwNDM5B3VuaTA0NUQHdW5pMDQ4Qgd1bmkwNDNBB3VuaTA0NUMHdW5pMDQzQgd1bmkwNDNDB3VuaTA0M0QHdW5pMDQzRQd1bmkwNDNGB3VuaTA0NDAHdW5pMDQ0MQd1bmkwNDQyB3VuaTA0NDMHdW5pMDQ1RQd1bmkwNDQ0B3VuaTA0NDUHdW5pMDQ0Nwd1bmkwNDQ2B3VuaTA0NDgHdW5pMDQ0OQd1bmkwNDVGB3VuaTA0NEMHdW5pMDQ0QQd1bmkwNDRCB3VuaTA0NTkHdW5pMDQ1QQd1bmkwNDU1B3VuaTA0NTQHdW5pMDQ0RAd1bmkwNDU2B3VuaTA0NTcHdW5pMDQ1OAd1bmkwNDVCB3VuaTA0NEUHdW5pMDQ0Rgd1bmkwNDUyB3VuaTA0NjMHdW5pMDQ2Qgd1bmkwNDczB3VuaTA0NzUHdW5pMDQ5Mwd1bmkwNDk1B3VuaTA0OTcHdW5pMDQ5OQd1bmkwNDlCB3VuaTA0OUQHdW5pMDQ5Rgd1bmkwNEExB3VuaTA0QTMHdW5pMDRBNQd1bmkwNTI1B3VuaTA0QTcHdW5pMDRBOQd1bmkwNEFCB3VuaTA0QUQHdW5pMDRBRgd1bmkwNEIxB3VuaTA0QjMHdW5pMDRCNQd1bmkwNEI3B3VuaTA0QjkHdW5pMDRCQgd1bmkwNTI3B3VuaTA0QkQHdW5pMDRCRgd1bmkwNENGB3VuaTA0QzIHdW5pMDRDNAd1bmkwNEM2B3VuaTA0QzgHdW5pMDRDQQd1bmkwNENDB3VuaTA0Q0UHdW5pMDREMQd1bmkwNEQzB3VuaTA0RDUHdW5pMDRENwd1bmkwNEQ5B3VuaTA0REIHdW5pMDRERAd1bmkwNERGB3VuaTA0RTEHdW5pMDRFMwd1bmkwNEU1B3VuaTA0RTcHdW5pMDRFOQd1bmkwNEVCB3VuaTA0RUQHdW5pMDRFRgd1bmkwNEYxB3VuaTA0RjMHdW5pMDRGNQd1bmkwNEY3B3VuaTA0RjkHdW5pMDRGQgd1bmkwNEZEB3VuaTA0RkYHdW5pMDUxMQd1bmkwNTEzB3VuaTA1MUIHdW5pMDUxRAd1bmkwNDhEB3VuaTA0OEYHdW5pMDUyOQd1bmkwNTJGD3VuaTA0MzIubG9jbEJHUg91bmkwNDMzLmxvY2xCR1IPdW5pMDQzNC5sb2NsQkdSD3VuaTA0MzYubG9jbEJHUg91bmkwNDM3LmxvY2xCR1IPdW5pMDQzOC5sb2NsQkdSD3VuaTA0MzkubG9jbEJHUg91bmkwNDVELmxvY2xCR1IPdW5pMDQzQS5sb2NsQkdSD3VuaTA0M0IubG9jbEJHUg91bmkwNDNELmxvY2xCR1IPdW5pMDQzRi5sb2NsQkdSD3VuaTA0NDIubG9jbEJHUg91bmkwNDQ3LmxvY2xCR1IPdW5pMDQ0Ni5sb2NsQkdSD3VuaTA0NDgubG9jbEJHUg91bmkwNDQ5LmxvY2xCR1IPdW5pMDQ0Qy5sb2NsQkdSD3VuaTA0NEEubG9jbEJHUg91bmkwNDRFLmxvY2xCR1IPdW5pMDQ5My5sb2NsQlNID3VuaTA0OTkubG9jbEJTSA91bmkwNEFCLmxvY2xDSFUPdW5pMDQ1My5sb2NsTUtED3VuaTA0MzEubG9jbFNSQg91bmkwNDMzLmxvY2xTUkIPdW5pMDQzNC5sb2NsU1JCD3VuaTA0M0YubG9jbFNSQg91bmkwNDQyLmxvY2xTUkIMdW5pMDQzMC5zczAxDHVuaTA0MzQuc3MwMQx1bmkwNDM1LnNzMDEMdW5pMDQ1MC5zczAxDHVuaTA0NTEuc3MwMQx1bmkwNDM4LnNzMDEMdW5pMDQzOS5zczAxDHVuaTA0OEIuc3MwMQx1bmkwNDVELnNzMDEMdW5pMDQ0MC5zczAxDHVuaTA0NDIuc3MwMQx1bmkwNDQzLnNzMDEMdW5pMDQ1RS5zczAxDHVuaTA0NEMuc3MwMQx1bmkwNDRBLnNzMDEMdW5pMDQ0Qi5zczAxDHVuaTA0NTkuc3MwMQx1bmkwNDVBLnNzMDEMdW5pMDQ2My5zczAxDHVuaTA0RDEuc3MwMQx1bmkwNEQzLnNzMDEMdW5pMDRENS5zczAxDHVuaTA0RDcuc3MwMQx1bmkwNEQ5LnNzMDEMdW5pMDREQi5zczAxDHVuaTA0RTMuc3MwMQx1bmkwNEU1LnNzMDEMdW5pMDRFRi5zczAxDHVuaTA0RjEuc3MwMQx1bmkwNEYzLnNzMDEMdW5pMDRGOS5zczAxDHVuaTA0OEQuc3MwMQd1bmkwMzk0B3VuaTAzQTkHdW5pMDNCQwd1bmkyMTJCB3VuaTIxMkEIemVyby5vc2YHb25lLm9zZgd0d28ub3NmCXRocmVlLm9zZghmb3VyLm9zZghmaXZlLm9zZgdzaXgub3NmCXNldmVuLm9zZgllaWdodC5vc2YIbmluZS5vc2YJemVyby5zaW5mCG9uZS5zaW5mCHR3by5zaW5mCnRocmVlLnNpbmYJZm91ci5zaW5mCWZpdmUuc2luZghzaXguc2luZgpzZXZlbi5zaW5mCmVpZ2h0LnNpbmYJbmluZS5zaW5mB3plcm8udGYGb25lLnRmBnR3by50Zgh0aHJlZS50Zgdmb3VyLnRmB2ZpdmUudGYGc2l4LnRmCHNldmVuLnRmCGVpZ2h0LnRmB25pbmUudGYJemVyby50b3NmCG9uZS50b3NmCHR3by50b3NmCnRocmVlLnRvc2YJZm91ci50b3NmCWZpdmUudG9zZghzaXgudG9zZgpzZXZlbi50b3NmCmVpZ2h0LnRvc2YJbmluZS50b3NmB3VuaTIwODAHdW5pMjA4MQd1bmkyMDgyB3VuaTIwODMHdW5pMjA4NAd1bmkyMDg1B3VuaTIwODYHdW5pMjA4Nwd1bmkyMDg4B3VuaTIwODkJemVyby5kbm9tCG9uZS5kbm9tCHR3by5kbm9tCnRocmVlLmRub20JZm91ci5kbm9tCWZpdmUuZG5vbQhzaXguZG5vbQpzZXZlbi5kbm9tCmVpZ2h0LmRub20JbmluZS5kbm9tCXplcm8ubnVtcghvbmUubnVtcgh0d28ubnVtcgp0aHJlZS5udW1yCWZvdXIubnVtcglmaXZlLm51bXIIc2l4Lm51bXIKc2V2ZW4ubnVtcgplaWdodC5udW1yCW5pbmUubnVtcgd1bmkyMDcwB3VuaTAwQjkHdW5pMDBCMgd1bmkwMEIzB3VuaTIwNzQHdW5pMjA3NQd1bmkyMDc2B3VuaTIwNzcHdW5pMjA3OAd1bmkyMDc5B3VuaTIxNTMHdW5pMjE1NAlvbmVlaWdodGgMdGhyZWVlaWdodGhzC2ZpdmVlaWdodGhzDHNldmVuZWlnaHRocw5iYWNrc2xhc2guY2FzZRNwZXJpb2RjZW50ZXJlZC5jYXNlC2J1bGxldC5jYXNlG3BlcmlvZGNlbnRlcmVkLmxvY2xDQVQuY2FzZQpzbGFzaC5jYXNlFnBlcmlvZGNlbnRlcmVkLmxvY2xDQVQOYnJhY2VsZWZ0LmNhc2UPYnJhY2VyaWdodC5jYXNlEGJyYWNrZXRsZWZ0LmNhc2URYnJhY2tldHJpZ2h0LmNhc2UOcGFyZW5sZWZ0LmNhc2UPcGFyZW5yaWdodC5jYXNlCmZpZ3VyZWRhc2gHdW5pMjAxNQd1bmkyMDEwB3VuaTAwQUQLZW1kYXNoLmNhc2ULZW5kYXNoLmNhc2ULaHlwaGVuLmNhc2USZ3VpbGxlbW90bGVmdC5jYXNlE2d1aWxsZW1vdHJpZ2h0LmNhc2USZ3VpbHNpbmdsbGVmdC5jYXNlE2d1aWxzaW5nbHJpZ2h0LmNhc2UJZXhjbGFtLnNjDWV4Y2xhbWRvd24uc2MQZ3VpbGxlbW90bGVmdC5zYxFndWlsbGVtb3RyaWdodC5zYxBndWlsc2luZ2xsZWZ0LnNjEWd1aWxzaW5nbHJpZ2h0LnNjCXBlcmlvZC5zYwtxdWVzdGlvbi5zYw9xdWVzdGlvbmRvd24uc2MLcXVvdGVkYmwuc2MPcXVvdGVkYmxiYXNlLnNjD3F1b3RlZGJsbGVmdC5zYxBxdW90ZWRibHJpZ2h0LnNjDHF1b3RlbGVmdC5zYw1xdW90ZXJpZ2h0LnNjEXF1b3Rlc2luZ2xiYXNlLnNjDnF1b3Rlc2luZ2xlLnNjB3VuaTI3RTgHdW5pMjdFOQd1bmkyMDA3B3VuaTIwMEEHdW5pMjAwOAd1bmkwMEEwB3VuaTIwMDkHdW5pMjAwQgd1bmkyMEI1DWNvbG9ubW9uZXRhcnkEZG9uZwRFdXJvB3VuaTIwQjIHdW5pMjBCNAd1bmkyMEFEBGxpcmEHdW5pMjBCQQd1bmkyMEJDB3VuaTIwQTYGcGVzZXRhB3VuaTIwQjEHdW5pMjBCRAd1bmkyMEI5B3VuaTIwQjgHdW5pMjBBRQd1bmkyMEE5B3VuaTIyMTkHdW5pMjA1Mgd1bmkyMjE1CGVtcHR5c2V0B3VuaTIxMjYHdW5pMjIwNgd1bmkwMEI1B2Fycm93dXAHdW5pMjE5NwphcnJvd3JpZ2h0B3VuaTIxOTgJYXJyb3dkb3duB3VuaTIxOTkJYXJyb3dsZWZ0B3VuaTIxOTYJYXJyb3dib3RoCWFycm93dXBkbgxhcnJvd3VwLmNhc2UPYXJyb3dyaWdodC5jYXNlDmFycm93ZG93bi5jYXNlDmFycm93bGVmdC5jYXNlB3VuaTI1QzYHdW5pMjVDNwlmaWxsZWRib3gHdW5pMjVBMQd0cmlhZ3VwB3VuaTI1QjYHdHJpYWdkbgd1bmkyNUMwB3VuaTI1QjMHdW5pMjVCNwd1bmkyNUJEB3VuaTI1QzEHdW5pMjExMwllc3RpbWF0ZWQHdW5pMjExNgZtaW51dGUGc2Vjb25kB2F0LmNhc2UMdW5pMjExNi5zczAxDGFtcGVyc2FuZC5zYwd1bmkwMzA4C3VuaTAzMDgwMzAwC3VuaTAzMDgwMzAxC3VuaTAzMDgwMzA0B3VuaTAzMDcLdW5pMDMwNzAzMDQJZ3JhdmVjb21iC3VuaTAzMDAwMzA0CWFjdXRlY29tYgt1bmkwMzAxMDMwNwt1bmkwMzAxMDMwNAd1bmkwMzBCDWNhcm9uY29tYi5hbHQHdW5pMDMwMgd1bmkwMzBDC3VuaTAzMEMwMzA3B3VuaTAzMDYHdW5pMDMwQQt1bmkwMzBBMDMwMQl0aWxkZWNvbWILdW5pMDMwMzAzMDgTdGlsZGVjb21iX2FjdXRlY29tYgt1bmkwMzAzMDMwNAd1bmkwMzA0C3VuaTAzMDQwMzA4C3VuaTAzMDQwMzAwC3VuaTAzMDQwMzAxDWhvb2thYm92ZWNvbWIHdW5pMDMwRgd1bmkwMzExB3VuaTAzMTIHdW5pMDMxQgxkb3RiZWxvd2NvbWIHdW5pMDMyNAd1bmkwMzI2B3VuaTAzMjcHdW5pMDMyOAd1bmkwMzJFB3VuaTAzMzEHdW5pMDMzNQd1bmkwMzM2B3VuaTAzMzcHdW5pMDMzOAx1bmkwMzA4LmNhc2UQdW5pMDMwODAzMDAuY2FzZRB1bmkwMzA4MDMwMS5jYXNlEHVuaTAzMDgwMzA0LmNhc2UMdW5pMDMwNy5jYXNlEHVuaTAzMDcwMzA0LmNhc2UOZ3JhdmVjb21iLmNhc2UQdW5pMDMwMDAzMDQuY2FzZQ5hY3V0ZWNvbWIuY2FzZRB1bmkwMzAxMDMwNy5jYXNlEHVuaTAzMDEwMzA0LmNhc2UMdW5pMDMwQi5jYXNlDHVuaTAzMDIuY2FzZQx1bmkwMzBDLmNhc2UQdW5pMDMwQzAzMDcuY2FzZQx1bmkwMzA2LmNhc2UOdGlsZGVjb21iLmNhc2UQdW5pMDMwMzAzMDguY2FzZRh0aWxkZWNvbWJfYWN1dGVjb21iLmNhc2UQdW5pMDMwMzAzMDQuY2FzZQx1bmkwMzA0LmNhc2UQdW5pMDMwNDAzMDguY2FzZRB1bmkwMzA0MDMwMC5jYXNlEHVuaTAzMDQwMzAxLmNhc2USaG9va2Fib3ZlY29tYi5jYXNlDHVuaTAzMEYuY2FzZQx1bmkwMzExLmNhc2UMdW5pMDMzNS5jYXNlDHVuaTAzMzcuY2FzZQx1bmkwMzM4LmNhc2UTdW5pMDMwNC5uYXJyb3cuY2FzZQl1bmkwMzA3LmkJdW5pMDMyOC5pEHVuaTAzMDgubG9jbFZJRVQQdW5pMDMwNy5sb2NsVklFVBJncmF2ZWNvbWIubG9jbFZJRVQSYWN1dGVjb21iLmxvY2xWSUVUEHVuaTAzMDIubG9jbFZJRVQQdW5pMDMwQy5sb2NsVklFVBB1bmkwMzA2LmxvY2xWSUVUEnRpbGRlY29tYi5sb2NsVklFVBB1bmkwMzA0LmxvY2xWSUVUFmhvb2thYm92ZWNvbWIubG9jbFZJRVQOdW5pMDMwOC5uYXJyb3cOdW5pMDMwMi5uYXJyb3cOdW5pMDMwNi5uYXJyb3cQdGlsZGVjb21iLm5hcnJvdw51bmkwMzA0Lm5hcnJvdw51bmkwMzExLm5hcnJvdxNjYXJvbmNvbWIuYWx0LnNob3J0CXVuaTAzMzUudAd1bmkwMkJDB3VuaTAyQkIHdW5pMDJCQQd1bmkwMkM5B3VuaTAyQ0IHdW5pMDJCOQd1bmkwMkJGB3VuaTAyQkUHdW5pMDJDQQd1bmkwMkNDB3VuaTAyQzgKdW5pMDMzNS5zYwp1bmkwMzM2LnNjCnVuaTAzMzguc2MLYnJldmVjb21iY3kQYnJldmVjb21iY3kuY2FzZQtkZXNjZW5kZXJjeRBkZXNjZW5kZXJjeS5jYXNlFmRlc2NlbmRlcmN5LmNhc2Uuc2hvcnQRZGVzY2VuZGVyY3kuc2hvcnQLdW5pMDMwNjAzMDELdW5pMDMwNjAzMDALdW5pMDMwNjAzMDkLdW5pMDMwNjAzMDMLdW5pMDMwMjAzMDELdW5pMDMwMjAzMDALdW5pMDMwMjAzMDkLdW5pMDMwMjAzMDMQdW5pMDMwNjAzMDEuY2FzZRB1bmkwMzA2MDMwMC5jYXNlEHVuaTAzMDYwMzA5LmNhc2UQdW5pMDMwNjAzMDMuY2FzZRB1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AAMAAAAAAAMAAwADAAMACAADAAAAAAAAAAAAGwAAAAD/9gAAAAAACAAAAAAAAAAA/+wAAAAAAAAAAAAAAAAAAAAAAAAAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/+QAAAAAAAAAAAAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/2AAAAAAAHAAAAAP/2AAD/9AAAAAAAAAAAAAAAAAAAAAAAAAAA/8cAAAAAAAAAAAAAAAAAAAAHAAAABwAAAAAAAAAAAAD//QAAAAAAAAAAAAP/9gAIAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkAAP/2AAAAAAAKAAoAAAAA//YAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/7QAAAAAAAwAAAAoAAAAKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//bAAoAAAAAAAMAAwADAAMAAwADAAAAAAAAAAAAEwAAAAD/9gAAAAAAAAAAAAD/9gAA/+wAAAAAAAAAAAAAAAAAAAAAAAAAAP+/AAAAAAAAAAAAAAAAAAAAAAAAAAcAAP/2//YAAAAN/+7/qQAAAAD/2//5/9j/3gAA//kAAAADAAAAAwAAAAMAAAAK//YACAAA/+z/9v/s//P//QAAAAcAAAADAAD/6QAAAAf/9gAHAAAAAAAAAAAAAAAA/9YAAAAAAAAAAAAAAAAAAAAAAAcAAP/2AAAAAAAAAAD/8QAAAAAAAAAA//H/2AAA/+b/9AAAAAAAAAAAAAAAAAAAAAD//QAAAAD/5wAAAAD/4gAAAAAAAAAAAAAAAAAAAAAAAP/5AAcAAAAAAAAAAAAAAAAAJgAIAAgAAAAAAAAAAAAAAAAAAP/s/+8AAAAAAAAAAAAKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIQAAAAAAHAAAAAAAAwAAAAAAAAAAAA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAsAAAAAAAAAAAAAAADAAAAAAAA/+//9wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAmAAAAAAAAAAAAAAAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/58AAAAAAAD/wQADAAMAAwAA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BiUADAYmBicANQYoBigAMQYpBioAEAYrBisAQQYsBiwAQgYuBi4AEAYvBi8AEQYwBjAAEgYxBjIAFAYzBjMAMQY0BjQAKwY1BjUALQY2BjYADAY3BjgAUQY6BjoAKwY9Bj0ATQY/Bj8ATQZDBkMATgZFBkUATgZHBkcAUwZMBk4ANQZRBlEAUQZSBlIANQZTBlMARQZUBlQANQZVBlUARQZWBlYAEAZXBlcAEwZYBlgAOwZZBlkAEwZaBloAOwZbBlsAEAZcBlwAUQZdBl0AUAZeBl4AUQZfBl8AUAZiBmIANQZkBmQANQZmBmYAEAZqBmoAEAZvBm8AEAZ5BnkAJQZ6BnoAOAZ7BnsAJQZ8BnwAMgZ9Bn0AJgZ+Bn4AOAZ/Bn8AMgaABoAAKAaBBoEAMgaCBoIAJQaEBoQAMgaFBoUANgaGBoYAMgaIBogAMgaKBosAMgaMBowAFQaNBo0ANgaQBpAAMgaRBpEAGwaUBpQAKwaVBpYANQaYBpgANQahBqIANQanBqcAAQaqBqoANQarBqsAUgatBq4ADwbKBsoAJQbLBssAMAbMBswAOgbNBs0AFgbOBs8AJQbQBtAAPQbRBtEAHgbXBtcAJQbaBtsAFAbcBtwAJQc+Bz4AEwACAAgACgAaBJgFCjDQQfBOrlTMbU6FfI8WAAEAsgAEAAAAVAQKAV4BaAGGAYYBhgGGAYYBhgGGAbQBtAG0AbQBtAG0Af4B/gH+Af4B/gH+Af4B/gH+Af4ENAIoAigCKAIoAigCKAIoA44ClgJCA6oCjAJQAmICcAJ+AowClgKgAs4C3AOOA5wDqgPcBF4EXgReBFgEWAPuBE4D9AROA/4D/gQEBFgEWARYBFgEWARwBHAEWARYBAoENAQ0BE4EWARYBFgEWAReBF4EcAABAFQASQCUAKkAwADBAMIAwwDEAMUAxgDfAOAA4QDiAOMA5ADmAOcA6ADpAOoA6wDsAO0A7gDvASsBVwFYAVkBWgFbAVwBXQGgAbABygHPAd4B4gHjAeoB7QHvAfgB/gIxAkoCTAJkArQDhQRkBGUGJAYmBicGMAY0BjUGOgY8Bj4GQAZMBk0GTgZTBlUGVwZZBmMGZQaBBoUGjQaUBpUGlgaYBqEG2AbdBz4AAgYlAAYGNgAGAAcGNAApBjUAKAY6ACkGPQAIBj8ACAZHAAMGlAApAAsB4QAZ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//YAAAAAAAAAAAAAAAAAAAAAAAD/7wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAAAAAAoAAAAA//YAAAAAAAAAAAAAAAAAAAAA//YAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/s//cAAAAAAAAAAAAAAAD/+QAAAAAAAAAAAAD/9QAA//cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//kAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//0AAP/2AAAAAAAAAAAAAAAA//sAAAAA//0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//kAAAAAAAAAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/j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ACMCmQKaAE0CmwKzACMCtAK9AG8CvgK+ACMCvwLGAG8CxwLUADoC1QLZAEMC2gLaAAYC2wLcADMC3gLeADMC3wL6AE4C+wL7AFUC/AMCACQDAwMgAFUDIQMhACQDJAMkAFUDJQMsACQDLQNEAFUDRQNGAB8DRwNfAFUDYAOCACQDgwOEAFUDhQOFACQDhgONAFUDjgOQAFcDkgOZAFcDmwOiADQDowO6ADsDuwPAAD4DwQPBAEADwgPLAEEDzAPQAFoD0QPqAE8D7QPtAFUD7gQEABQEBQQFACQEBgQGAFIEBwQOACQEDwQRAFsEEgQSAFUEEwQbAFsEHAQcAFUEHQQfAFsEIAQhACAEIgQuAFUELwQvACQEMAQ3ADQEOARUADsEVQReAEIEXwRjAFoEZARlAA0EZgRmAEYEZwRrAGsEbARsAEcEbQRvAGsEcARwAAoEcQRxAEsEcgR3AGsEeAR4AEcEeQR6AGsEewR7AAUEfAR9AGsEfgR+AAUEfwR/AAYEgASBAAoEggSCAAUEgwSDAAoEhASEAAEEhQSJAGsEigSKAAYEiwSLAGsEjASMAEcEjQSNAGsEjgSOAEwEjwSPAAUEkASQAEsEkQSSAGsEkwSTAAMElASUAAYElQSVAGsElgSWAAoElwSYAAYEmQSZAAoEmgSaAAUEmwSbAAkEnQSdAGsEngSeAAoEnwSfAEsEoASiAGsEowSjAAYEpASnAGsEqASpAAUEqgSqAAYEqwSsAAsErQStAAoErgSuAAYErwSwAAEEsQSyAGsEswS0AAIEtQS1AGsEtgS2AAoEtwS5AGsEugS6AAEEuwS7AGsEvAS+AEYEvwS/AGsEwATBAAUEwgTCAAoEwwTEAEsExQTGAGsExwTJAAUEygTKAEsEywTNAAoEzgTOAAEEzwTRAGsE0gTTAAoE1ATUAEoE1QTVAEcE1gTWAAUE1wTXAAkE2ATaAGsE2wTcAEcE3QTdAEYE3gTeAAUE3wTfAGsE4QTiAAUE4wTjAFwE5ATkAF4E5QTnAEoE6ATrAGsE7ATsAEkE7QTtAFwE7gTuAAcE7wTwAAwE8QTxAAUE8gTyAAgE8wTzAAYE9AT0AAgE9QT1AEcE9gT2AGsE9wT3AAQE+QT5AAcE+gT7AFwE/AT8AEYE/QT9AEoE/gT/AGsFAAUCAAwFBAUEAAUFBQUFAAgFBgUGAE0FBwUHAAUFCAULAGUFDAUMAEgFDQUPACMFEAUQAD8FEQURAFEFEgUXAGUFGAUYAEgFGQUaAGUFGwUbACMFHAUdAGUFHgUeACMFHwUfADUFIAUhAD0FIgUiACMFIwUjAD8FJAUkADoFJQUpAGUFKgUqADUFKwUrAGUFLAUsAEgFLQUtAGUFLgUuAC4FLwUvACMFMAUwAFEFMQUyAGUFMwUzAGQFNAU0AG0FNQU1AGUFNgU2AD8FNwU3AG8FOAU4ADUFOQU5AD8FOgU6ACMFOwU7AD0FPAU8ABkFPQU9AGUFPgU+AD8FPwU/AFEFQAVBAGUFQgVCAG8FQwVDADUFRAVHAGUFSAVJACMFSgVKADUFSwVMAD0FTQVNAD8FTgVOADUFTwVQADoFUQVSAG8FUwVUABEFVQVVAG8FVgVWAD8FVwVXAGUFWAVYAEgFWQVaAGUFWwVbADoFXAVcAGUFXQVfAE0FYAViACMFYwVjAD8FZAVlAFEFZgVnAGUFaAVqACMFawVrAFEFbAVuAD0FbwVvADoFcAVyAGUFcwV0AD8FdQV1AFYFdgV2AEgFdwV3ACMFeAV4AD0FeQV5AC8FegV6AGUFewV7AGQFfAV8AEgFfQV9ACMFfgV+AC4FfwV/ACMFgAWAAD8FgQWBAFEFggWEADoFhQWFAG8FhgWGAEgFhwWJAGUFigWOADoFjwWPADUFkAWQAG8FkQWRAGUFkgWSAFEFkwWTACMFlAWUAGUFlQWVAA8FlgWWAGUFlwWXACMFmAWZADoFmgWeACMFnwWiADoFowWjAG4FpQWnADoFqAWoABwFqQWpADoFqgWqAEgFqwWrAGUFrQWuACMFrwWvAE0FsAWxACMFswW4ADoFuQW5AC8FugW6AEYFvgW+AEYFvwW/AGsFwAXAAEQFwQXBACUFwgXCAFkFwwXDADYFxAXEABcFxQXFAFMFxgXGAEQFxwXHADAFyAXIABUFyQXJACEFygXKAEUFywXLACYFzAXMADkFzQXNADcFzgXOABgFzwXPAFQF0AXQAEQF0QXRADEF0gXSABUF0wXTACIGJAYkAA0GJQYlAA4GJgYnAB0GKAYoABIGKQYqACgGKwYrAGAGLAYsABYGLgYuACgGLwYvACkGMAYwACoGMQYyAC0GMwYzABIGNAY0ADIGNQY1ADwGNgY2AA4GNwY4AB4GOgY6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BSMAEwUkBSQAQAUlBSkAPwUrBSsAPwUtBS0APwUuBS4AGwUvBS8AGQUxBTIAPwUzBTMAPQU1BTUAPwU2BTYAEwU3BTcAPgU5BTkAEwU6BToAGQU7BTsAEQU9BT0APwU+BT4AEwVABUEAPwVCBUIAPgVEBUcAPwVIBUkAGQVLBUwAEQVNBU0AEwVPBVAAQAVRBVIAPgVVBVUAPgVWBVYAEwVXBVcAPwVZBVoAPwVbBVsAQAVcBVwAPwVdBV8ACgVgBWIAGQVjBWMAEwVmBWcAPwVoBWoAGQVsBW4AEQVvBW8AQAVwBXIAPwVzBXQAEwV3BXcAGQV4BXgAEQV6BXoAPwV7BXsAPQV9BX0AGQV+BX4AGwV/BX8AGQWABYAAEwWCBYQAQAWFBYUAPgWHBYkAPwWKBY4AQAWQBZAAPgWRBZEAPwWTBZMAGQWUBZQAPwWWBZYAPwWXBZcAGQWYBZkAQAWaBZ4AGQWfBaIAQAWlBacAQAWpBakAQAWrBasAPwWtBa4AGQWvBa8ACgWwBbEAGQWzBbgAQAW6BboAAQW+Bb4AAQXBBcEAKwXCBcIAOQXDBcMAOAXEBcQAJwXHBccANQXKBcoAPAXLBcsALAXMBcwAOgXOBc4AKAXPBc8AJgXRBdEANgYkBiQADAYlBiUAHwYmBicAKgYoBigAIgYpBioALwYrBisAIwYuBi4ALwYvBi8AMAYwBjAAMQYxBjIANAYzBjMAIgY0BjQANwY1BjUAOwY2BjYAHwY6BjoANwY9Bj0AIAY/Bj8AIAZBBkEALQZDBkMAIQZFBkUAIQZHBkcALgZMBk4AKgZSBlIAKgZUBlQAKgZWBlYALwZYBlgAMwZaBloAMwZbBlsALwZgBmAAJAZhBmEAJQZiBmIAKgZjBmMAKQZkBmQAKgZlBmUAKQZmBmYALwZoBmgAMgZqBmoALwZvBm8ALwZ5BnkAFQZ6BnoAGQZ7BnsAFQZ9Bn0AFgZ+Bn4AGQaCBoIAFQaUBpQANwaVBpYAKgaYBpgAKgahBqIAKganBqcAAQaqBqoAKgarBqsAPwbKBsoAFQbOBs8AFQbXBtcAFQbaBtsANAbcBtwAFQACAJ4ABAAAAKwAsAABAEcAAP+j//n/9AAKAB4AKAAh//YAFAAK/6j/9v/2ABQAAwAHAB4ABwAUABH/7P/5//P/2QARAA0AEf/2//0AUAAg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AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9AAA//D/8AAAAAD/7f/3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/8f/q//f/9AAA/+0AAP/s//P/9//w//cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKACUABwAA//b/9gAA/+n/+f/bAAAAAAAAAAAAHgAAAAAAFAAAAAcAAP/9//kAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwAAAAAACP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABf/9AAAABQAFAAAAAoAAAAUAAoABwAAAAAADf/2AAAAFAAAAAAAAwAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAACP/2AAAACAAAAAAAAwAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKAAoAFAAA/+z/7AAA/+L/9v/YAAoAAABkAEQAFAAKAAAACAAAAAD/9gAA//YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAEQAAAAAACAADAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/zAAD/6QAA//T/7wAA/9//1v/WAAAAEf/0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//kAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAB4AAAAA//P/8wAA//P/+P/uAAcADQAAAAAAHv/2AAAADQAAAAD/9v/2//EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//YAEQAAAAAACv/2AAAACgAAAAD/9v/s/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/u/+z/3QAH/9//3wAA/+n/7v/g//H/9gAAAAD/7P/iABH//QAA//P/7v/u/+7/6f/p/+z/9P/5/+oAAP/3//f/8P/hAAD/8P/tAAAACv/pAAD/9P/vAAr/8wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/b/+D/2gAH/+//2wAA/9X/0f/bAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9wAA//QAAAAAAAAAAAAAAAAAAABMAFkAAAAAAAAAAAAAAAAAAAAAAAD/9P/m//n/9wAA//QAAP/W//P/6gAA/+r/5v/lAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/9sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/3wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAhADkAB//s/+D/4P/4/9sAAP/bABT/3wAAAAoANAAA//v/8P/0/9//6QAA/+X/zP+8ABgAAP/2AAAACv/mABQAAAAAAAAAAP/XAAD/+QAAABEAAAAK//QAAAAA//QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/V/+T/0//9AAAAAAAA//P/7v/z/+wADAAAAAD//QAAAAAAHgAAAAoALwAUAC8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//YAAAAA//YAAAAAAAD/9v/2AAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/84AAAAAAAD/9v/2//YACAAAAAAACP/sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/5AAD/+QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAAAAPP/L/8b/xv/d/7wACP+yAA7/rQBaAEYAEQA8/9j/1f/i/9D/2AAI/8YAAAAAAAAAAP/2AAD/7wAAAAAAAAAAAAAAAAAAAAD/9AAIAAAAAAAA/98AAAAA/84AAAAAAAAAAP/p//T/+QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB7/ugAAAAAAMgAA//n/4gAAAAD/2AAA/84AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoAAAAAAAAAAAAKAAoAAAAAAAAAAAAAAAAAAP/f//3/+AAAABsAIAAAABP//wAM/98AHgAAAAAAAAAA//kAKgAAACEAGwAAABQAAAAD/9QAAAAAAAD/+v/u/+YAAAAA/+8AAwADAAYAEgAAAAD/7gAK//QAAAAAAAD/9P/0AAoAAAAAAB4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/98AEQAAAAAAAAAAAAcAIAAAAAAAB//zAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/5AAoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/f//7//QAAABsAJQAAACAABwAb/98AHgAAAAAAAAAA//kAJQAAABEAGwAHAB4ABv/0/80AAAAAAAD/9v/t/8b/8AAA/+0AAAAAABcAAwAAAAD/9AAK/+UAAAAAAAD/9P/0AAD/9gAAAAD/7wAAAAD/9//3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/98AEQAAAAAAAAAAAAcAKwAAAAAAFwACAA0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/0AAoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/VAAAAAAAAAAgADAAAAAAAAAAAAAAAFP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/9QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAAAAD/9AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/Y//b/9v/sAB4AHgAAAB4AAAAe/7gAAAAAAAP/5f/Y/8L/9v/M/+L/9P/l//kAAAAAAAAAAAAAAAD/vQAAAAAAAAAAAAAAAAAAAAD/5f/FAAAAAP/s/73/vQAA/73/9v/C/8L/wv/s/73/vf/H/8wAAAAA/8z/0//YAAAAAAA5AFIAV//iAAD/+f/2//YAL//5ADL/9gBkAGwAMgBD//YAAP/2//P/9gAv//kAAAAAAAAAAAADAAD/9gAAAAAAAAAAAAAAAAAAAAD/7AAlABQAAAAU/+UAGgAA/+UAAAAAAB4AAP/sAAAACv/2ABQAAAAAAAAAAAAAAB4AAgAPBiUGLAAABi4GOAAIBjoGOgATBjwGPAAUBj4GQgAVBkQGRAAaBkYGRgAbBkwGTgAcBlEGcAAfBpQGlgA/BpgGmABCBqEGoQBDBtQG1ABEBtoG2wBFBz4HPgBHAAIAPgYmBicADAYoBigABAYpBioAEQYrBisABQYsBiwABwYuBi4AEQYvBi8AEgYwBjAAFAYxBjIAGgYzBjMABAY0BjQAHAY1BjUAHQY3BjgADQY6BjoAHAY8BjwAAQY+Bj4AAQY/Bj8AAwZABkAADgZBBkEAEAZCBkIAAgZEBkQAAgZGBkYADwZMBk4ADAZRBlEADQZSBlIACgZTBlMADAZUBlQACgZVBlUADAZWBlYAEQZXBlcAFgZYBlgAGAZZBlkAFgZaBloAGAZbBlsAEQZcBlwACQZdBl0ADQZeBl4ACQZfBl8ADQZgBmAABgZhBmEACAZiBmIACwZjBmMADAZkBmQACwZlBmUADAZmBmYAEQZnBmcAEwZoBmgAFQZpBmkAGwZqBmoAEQZrBmsAFwZsBmwAGQZtBm0AFwZuBm4AGQZvBm8AEQZwBnAAGwaUBpQAHAaVBpYADAaYBpgADAahBqEADAbUBtQAEAbaBtsAGgc+Bz4AFgACAU4ABAAfAAEAIAAgAD4AIQAnAAQAKABGAD4ARwBIABsASQBJAD4ASgBRAAQAUgBnAD4AaABpAAIAagCDAD4AhACmAAQApwCoAD4AqQCpAAQAqgCxAD4AsgC0ACsAtgC9ACsAvwC/AAQAwADGAAUAxwDeAAcA3wDkAAgA5QDlAAkA5gDvAAoA8AD0ACkA9QD1AD4A9gEPADABEAERAAEBEgETAD4BFAEqADQBKwErADABLAEzAAQBNAE0AC4BNQE1AD4BNgFEAC4BRQFGAAMBRwFIAD4BSgFUAD4BVQFWAAQBVwFdAAYBXgF6AAcBewGEABwBhQGJACkBigGlAB4BpwHMACwBzgHOACEB0AHXACwB3gHuADUB7wHxAA4B9QH1ADUB/wILADUCDAIuACwCLwIvADUCMQIxACwCMgI5ADUCOgI8ADYCPgJFADYCSAJPACcCUAJnAC8CaAJtABQCbgJuACgCbwJ4ABQCeQJ9AC0CfwKYACwCmQKaAB4CmwKzACwCvgK+ACwCxwLUAC8C1QLZAC0C2gLaAAUC2wLcACcC3gLeACcC3wL6AAsC+wL7ADsC/AMCABEDAwMgADsDIQMhABEDJAMkADsDJQMsABEDLQNEADsDRQNGAA8DRwNfADsDYAOCABEDgwOEADsDhQOFABEDhgONADsDjgOQADIDkgOZADIDmwOiABIDowO6ABMDuwPAABUDwQPBABYDwgPLABcDzAPQADgD0QPqADED7QPtADsD7gQEADcEBQQFABEEBgQGADMEBwQOABEEDwQRADwEEgQSADsEEwQbADwEHAQcADsEHQQfADwEIAQhABAEIgQuADsELwQvABEEMAQ3ABIEOARUABMEVQReAD0EXwRjADgEZARlAAwEZgRmAAEEZwRrAD4EbARsABoEbQRvAD4EcARwAAkEcQRxABsEcgR3AD4EeAR4ABoEeQR6AD4EewR7AAQEfAR9AD4EfgR+AAQEfwR/AAUEgASBAAkEggSCAAQEgwSDAAkEhASEABgEhQSJAD4EigSKAAUEiwSLAD4EjASMABoEjQSNAD4EjgSOACsEjwSPAAQEkASQABsEkQSSAD4EkwSTAAIElASUAAUElQSVAD4ElgSWAAkElwSYAAUEmQSZAAkEmgSaAAQEmwSbAAgEnAScADoEnQSdAD4EngSeAAkEnwSfABsEoASiAD4EowSjAAUEpASnAD4EqASpAAQEqgSqAAUEqwSsAAoErQStAAkErgSuAAUErwSwABgEsQSyAD4EswS0ABkEtQS1AD4EtgS2AAkEtwS5AD4EugS6ABgEuwS7AD4EvAS+AAEEvwS/AD4EwATBAAQEwgTCAAkEwwTEABsExQTGAD4ExwTJAAQEygTKABsEywTNAAkEzgTOABgEzwTRAD4E0gTTAAkE1ATUADQE1QTVABoE1gTWAAQE1wTXAAgE2ATaAD4E2wTcABoE3QTdAAEE3gTeAAQE3wTfAD4E4QTiAAQE4wTjADAE5ATkACoE5QTnADQE6ATrAD4E7ATsADkE7QTtADAE7gTuAAYE7wTwABwE8QTxAAQE8gTyAAcE8wTzAAUE9AT0AAcE9QT1ABoE9gT2AD4E9wT3AAME+AT4AB0E+QT5AAYE+gT7ADAE/AT8AAEE/QT9ADQE/gT/AD4FAAUCABwFBAUEAAQFBQUFAAcFBgUGAB4FBwUHAAQFCAULADUFDAUMACAFDQUPACwFEAUQACgFEQURACEFEgUXADUFGAUYACAFGQUaADUFGwUbACwFHAUdADUFHgUeACwFHwUfACUFIAUhABQFIgUiACwFIwUjACgFJAUkAC8FJQUpADUFKgUqACUFKwUrADUFLAUsACAFLQUtADUFLgUuADYFLwUvACwFMAUwACEFMQUyADUFMwUzAA4FNAU0ACYFNQU1ADUFNgU2ACgFOAU4ACUFOQU5ACgFOgU6ACwFOwU7ABQFPQU9ADUFPgU+ACgFPwU/ACEFQAVBADUFQwVDACUFRAVHADUFSAVJACwFSgVKACUFSwVMABQFTQVNACgFTgVOACUFTwVQAC8FUwVUAB8FVgVWACgFVwVXADUFWAVYACAFWQVaADUFWwVbAC8FXAVcADUFXQVfAB4FYAViACwFYwVjACgFZAVlACEFZgVnADUFaAVqACwFawVrACEFbAVuABQFbwVvAC8FcAVyADUFcwV0ACgFdQV1ACMFdgV2ACAFdwV3ACwFeAV4ABQFeQV5ACQFegV6ADUFewV7AA4FfAV8ACAFfQV9ACwFfgV+ADYFfwV/ACwFgAWAACgFgQWBACEFggWEAC8FhgWGACAFhwWJADUFigWOAC8FjwWPACUFkQWRADUFkgWSACEFkwWTACwFlAWUADUFlgWWADUFlwWXACwFmAWZAC8FmgWeACwFnwWiAC8FpQWnAC8FqAWoACIFqQWpAC8FqgWqACAFqwWrADUFrQWuACwFrwWvAB4FsAWxACwFswW4AC8FuQW5ACQFugW6AAEFvgW+AAEFvwW/AD4GJAYkAAwGeQZ5AAQGegZ6ACwGewZ7AAQGfQZ9ACsGfgZ+ACwGgAaAAA0GggaCAAQGhwaHAD4GiQaJAD4GpwanAAEGqAaoAD4GqwarADUGygbKAAQGzgbPAAQG1wbXAAQG2AbYAD4G3AbcAAQAAgwWAAQAAA06D6gAEwBRAAD/8/+o/+oADf/R/+z/9//5/+MABwAUABH/+//w/+7/7f/5ABT/+f/5AAP/+P/pAAX/6gAU/+X/+QASABf/9//w//QACgAH//n/7//v//P/+f/5/+//+f/5//b//f/4//3/+P/y/+r/9QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP+fAAD/7P+9AAAAAAAA//YAAAAA//EAAP/3//QAAP/2AAAAAP/2AAAAAP/l//sAAAAA/9H/9v/0//4AAP/u/+QAAAAA/+r/7P/s/+L/9v/2//H/+wAAAAD/6v/sAAAAAP/s/84ACv/w/9v/8f/s//n/6v/5//kAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACv/2AAAAAAAAAAAAAAAUABQAAAAAAAAAAP/2AAAAAAAAABsAAAAAAAAAAP/u//n/+QAAAAoAAAAAAAAABwAAAAD/+QAAABsAAAAAAAAAAAAHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+wABwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//MAMQA/AAAALwAAAAAAFgAUACUADAAAAAD/5f/sAAAAAAAdAB7/+AAxAC8AH//2ABv/8wAwAEcAAAAAACoAKgAAAAAAFgAKAEwAEQAKAAAAAAAMAAAAAAAAAAAAAAAAAAD/9gAAAAD/9gAqABEAAAAW/+4ACQADAAz//QArAFD/4gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/n//gAAP/Y/+oAAP/3/9UAAAAAAAD/+AAH/+n/4gAAAAAAAAAK//b/6gAIABQAAAAKAAgAAAADAAAAAP/t//4ABwAAAAAACgANAAAAEv/k/+z/9P/2//P/8P/0AAAAAP/3/+z/6QAD//n/9gAAAAAAAAARAD4ABQAAAAAAAAAA//kAAP/h/+//9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//oAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/5P/VAAAAAAAAAAAAEQAA/+wABwAAAAAAAAAUAAAAAAAAAAD/9v/s/+8AAAAb/+wAB//2//YAAAAA//H/+P/7AAAACgAHAAAAEf/nAAcAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/4AAAAAAAMAD0AEQAAAAMAAAAAAAAAGgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsAAAAAAAAAAAAAAAIAAgACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/5f+9//kAAAAA//oAAAAA/+0AAAAAAAAAAAAAAAAAAP/0AAAAA//q//YAAAAA/9EAAP/0//kAAP/0/+oAAAAA//MAAP/v/+X/+//2AAAAAAAAAAD/zP/MAAAAAAAAAAAAAAAAAAAAAP/q/+QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP+vAAD/7/+9AAAAAAAA/+0AAAAA/+8AAP/8//oAAAAAAAAAAP/2AAAAAP/l//sAAP/0/9H/9v/0//4AAP/v/+UAAAAA/+z/6f/s/+L/9v/x/+7/+AAAAAD/5f/bAAD/7f/Y/9wACv/5//X/+//p/+X/8f/4/+UAAAAAAAAAAAAAAAAAAP/3AAAAAP/5/+n/4P/J/+D/9QAAAAAAAAAAAAAAAAAAAAAAKAAAAAAACwAAAAAAAAAAAB4AAAAAAAAAAAAAAAAAAAADAAAAAAAIAAsAAP/0ACj/+QAUAB4AAAAAABQACAADAAD/8P/0AB4AAf/3//T/+AAAAAAAAAAAAAAAAAAAAAAACgAAAAAAAAAeAAAAAP/9/+UAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9P/a/+AAHv/s/+X/9P/w/+IAAwAeAB8AAv/c/+r/5f/bAAD/+QAIABb/9P/6ABL/9//2AAj/2wAhACEACv/0ABYAHgAPAAD/+f/+AAAAAwAP//kAAAAD//f/8P/0/+j/7f/l/9n/9//Z/9b/+AAeAAAAAAAK//MABQAAAAIAAwAA//n/2P/d//0AAP/W/+0AAAAAAAD/2P/0//D/9AAAAAAAAAAAAAAAAP/EAAAAAAAA//UAAAAA//MAAAAAAAAAAAAAAAAAAP/7//sAAP/5AAAAAAAA/+8AAAAAAAAAAP/6/+UAAAAAAAD/9v/u/+//9v/2//YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/pAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//j/7/+9AAAAAAAAAAAAAAAA//v/+QAAAAD/4wAAAAAAAP/0//n/7v/t//kAAAAK/+8AAP/5AAD/9wAA/+oAAP/zAAAAAP/q/+X/+f/2AAAAAP/v/+8AAAAAAAAAAAAAAAD/9gAAAAAAAP/sAAAAAAAAACAAAAAA//kAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPwAmAAAAFgAAAAAAAwAUACz/+gAAAAD/7P/sAAD/+gAW//r/7AAgACAADv/sAFD/7AArADUACwAAADAAFgAOAAAACgAJADQAHf/0//T/9P/3//QAAAAAAAAAAAAAAAD/7AAAAAD/8gAnAAAAAAAI/+z/9AAW//n/9//3//T/7AAA//T/9AAAAAAAAAAAAAAAAAAAAAAAAP/5AAD/+v/Y/+kAKv/s//EAAAAA/+UABwAUACUAB//k//P/5P/VAAAAAAAeAAn/8QALAB4AAP/fACH/3wAhABEAAP/5AA8AFAAPAAP//v/5AAAAC//4/+L/9gAH//7/9P/0//kAAAAA/+X/8//n/+L/7wAeAAAAAAAK//MACQAAAAcAAP/xAAD/4f/z//kAAP/zAAAAAAAAAAD/5QAA//kAAAAAAAAAAAAAAAAAAP/OAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/5AAAAAP/0AAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAAAAD/+QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+UAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/X/+wADf/R/+oAAAAA/9//9v/2AAr//QAA/+T/3wAAAAAAAAAA//n/7gAIAA0AAAAAAAsAAAAAAAAAAP/x//kAAwAA//cAAAAAAAAAAf/iAAD/9v/2//n/6v/u//j/9P/q/+L/6QAAAAD/9gADAAAAAAAAACUAAAAAAAAAAAAGAAAACv/l//b/9gAA//gAAAAAAAAAAAAA//cAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAMAGKAbMAAAG1AcwAKgHOAc8AQgHYAd0ARAHyAfsASgH9AjAAVAIyAjwAiAI+AkYAkwJIAk8AnAJaAl8ApAJoAngAqgKZApoAuwKcArYAvQK4AroA2AK8ArwA2wK+AssA3ALaAtoA6gLcAtwA6wLeAt4A7ASoBKgA7QUHBQgA7gUNBREA8AUWBRcA9QUbBRsA9wUdBR4A+AUgBSMA+gUuBTAA/gU0BTUBAQU5BTsBAwU+BUMBBgVIBU0BDAVRBVcBEgVdBWUBGQVoBW4BIgVyBXUBKQV4BXgBLQV6BXoBLgV9BX4BLwWABYEBMQWFBYUBMwWHBYkBNAWQBZABNwWSBZUBOAWcBZ4BPAWjBaMBPwWvBbEBQAZ6BnoBQwaJBokBRAACAGcBigGjAAgBpAGlAAEBpgGmAAkBrgGuAAUBrwGvAAIBsAGwAAcBsQGzAAUBtQHLAAEBzAHMAAkBzgHOABIBzwHPAAMB2AHdAAgB8gH1AAQB9gH3AAUB+AH4AAcB+QH7AAUB/QH+AAUB/wILAAgCDAIbAAkCHAIhAAoCIgItAAkCLgIuAAECLwIwAAkCMgI5AAsCOgI8AAwCPgJFAAwCRgJGAAkCSAJPAA0CWgJfAA4CaAJtAA8CbgJuABECbwJ4AA8CmQKaAAECnAKyAAECswKzAAkCtAK0AAMCtQK2AAYCuAK6AAYCvAK8AAYCvgK+AAECvwLGAA0CxwLLABAC2gLaAAgC3ALcAAUC3gLeAAUEqASoAAkFBwUHAAkFCAUIABIFDQUPAAEFEAUQABEFEQURABIFFgUXABEFGwUbAAkFHQUdAAkFIAUhAA8FIgUiAAkFIwUjABEFLgUuAAwFMAUwAAkFNAU0AAgFNQU1AAkFOQU5ABEFOgU6AAkFOwU7AA8FPgU+ABEFPwU/ABIFQAVBABEFQgVCAAQFQwVDABEFSAVIAAkFSgVKAAsFSwVMAA8FTQVNABEFUQVSAAgFUwVUAAEFVQVVAAUFVgVXABEFXQVeAAgFXwVgAAEFYQViAAkFYwVjABEFZAVlABIFaAVrAAkFbAVuAA8FcgVyAAsFcwV0ABEFeAV4AA8FegV6AAkFfQV9ABIFfgV+AAwFgAWAABEFgQWBABIFhQWFAAQFhwWJAAgFkAWQAAkFkgWSABIFlAWUAAsFlQWVAAkFnAWeAAEFowWjAAkFrwWwAAEFsQWxAAkGiQaJAAwAAgFrAAQAHwBMACAAIABNACEAJwAwACgARgBNAEcASABIAEkASQBNAEoAUQAwAFIAZwBNAGoAgwBNAIQApgAwAKcAqABNAKkAqQAwAKoAsQBNALIAtABOALYAvQBOAL8AvwAwAMAAxgACAMcA3gAxAN8A5AAyAOUA5QA2AOYA7wAzAPUA9QBNAPYBDwABARABEQBMARIBEwBNASsBKwABASwBMwAwATUBNQBNAUUBRgBJAUcBSABNAUoBVABNAVUBVgAwAVcBXQBKAV4BegAxAYoBpQA3AaYBpgATAacBzAAWAc4BzgAPAdAB1wAWAdgB3QATAd4B7gBCAe8B8QBBAfIB9AATAfUB9QBCAfYB/gATAf8CCwBCAgwCLgAWAi8CLwBCAjACMAATAjECMQAWAjICOQBCAjoCPABFAj4CRQBFAkYCRgATAkgCTwAjAlACZwBGAmgCbQApAm4CbgAqAm8CeAApAnkCfQArAn8CmAAWApkCmgA3ApsCswAWArQCvQATAr4CvgAWAr8CxgATAscC1ABGAtUC2QArAtoC2gACAtsC3AAjAt4C3gAjBGQEZQAEBGYEZgBMBGcEawBNBGwEbAA1BG0EbwBNBHAEcAA2BHEEcQBIBHIEdwBNBHgEeAA1BHkEegBNBHsEewAwBHwEfQBNBH4EfgAwBH8EfwACBIAEgQA2BIIEggAwBIMEgwA2BIQEhAAuBIUEiQBNBIoEigACBIsEiwBNBIwEjAA1BI0EjQBNBI4EjgBOBI8EjwAwBJAEkABIBJEEkgBNBJQElAACBJUElQBNBJYElgA2BJcEmAACBJkEmQA2BJoEmgAwBJsEmwAyBJ0EnQBNBJ4EngA2BJ8EnwBIBKAEogBNBKMEowACBKQEpwBNBKgEqQAwBKoEqgACBKsErAAzBK0ErQA2BK4ErgACBK8EsAAuBLEEsgBNBLMEtAAvBLUEtQBNBLYEtgA2BLcEuQBNBLoEugAuBLsEuwBNBLwEvgBMBL8EvwBNBMAEwQAwBMIEwgA2BMMExABIBMUExgBNBMcEyQAwBMoEygBIBMsEzQA2BM4EzgAuBM8E0QBNBNIE0wA2BNUE1QA1BNYE1gAwBNcE1wAyBNgE2gBNBNsE3AA1BN0E3QBMBN4E3gAwBN8E3wBNBOEE4gAwBOME4wABBOQE5ABHBOgE6wBNBO0E7QABBO4E7gBKBPEE8QAwBPIE8gAxBPME8wACBPQE9AAxBPUE9QA1BPYE9gBNBPcE9wBJBPkE+QBKBPoE+wABBPwE/ABMBP4E/wBNBQQFBAAwBQUFBQAxBQYFBgA3BQcFBwAwBQgFCwBCBQwFDAAOBQ0FDwAWBRAFEAAqBREFEQAPBRIFFwBCBRgFGAAOBRkFGgBCBRsFGwAWBRwFHQBCBR4FHgAWBR8FHwAkBSAFIQApBSIFIgAWBSMFIwAqBSQFJABGBSUFKQBCBSoFKgAkBSsFKwBCBSwFLAAOBS0FLQBCBS4FLgBFBS8FLwAWBTAFMAAPBTEFMgBCBTMFMwBBBTUFNQBCBTYFNgAqBTcFNwATBTgFOAAkBTkFOQAqBToFOgAWBTsFOwApBT0FPQBCBT4FPgAqBT8FPwAPBUAFQQBCBUIFQgATBUMFQwAkBUQFRwBCBUgFSQAWBUoFSgAkBUsFTAApBU0FTQAqBU4FTgAkBU8FUABGBVEFUgATBVMFVAAJBVUFVQATBVYFVgAqBVcFVwBCBVgFWAAOBVkFWgBCBVsFWwBGBVwFXABCBV0FXwA3BWAFYgAWBWMFYwAqBWQFZQAPBWYFZwBCBWgFagAWBWsFawAPBWwFbgApBW8FbwBGBXAFcgBCBXMFdAAqBXUFdQBEBXYFdgAOBXcFdwAWBXgFeAApBXkFeQAgBXoFegBCBXsFewBBBXwFfAAOBX0FfQAWBX4FfgBFBX8FfwAWBYAFgAAqBYEFgQAPBYIFhABGBYUFhQATBYYFhgAOBYcFiQBCBYoFjgBGBY8FjwAkBZAFkAATBZEFkQBCBZIFkgAPBZMFkwAWBZQFlABCBZUFlQAGBZYFlgBCBZcFlwAWBZgFmQBGBZoFngAWBZ8FogBGBaUFpwBGBagFqABLBakFqQBGBaoFqgAOBasFqwBCBa0FrgAWBa8FrwA3BbAFsQAWBbMFuABGBbkFuQAgBboFugBMBb4FvgBMBb8FvwBNBcAFwAAsBcEFwQAXBcIFwgAoBcMFwwAlBcQFxAAQBcUFxQA/BcYFxgAsBccFxwAhBcgFyAANBckFyQAUBcoFygAtBcsFywAYBcwFzAA7Bc0FzQAm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D4oPig+KCrAPig+KD4oPig+KD4oPig+KD4oKqg+KD4oPig+KD4oPig+KD4oPig+KD4oPig+KD4oPigugD4oLjguUCg4LoA+KD4oPig+KChQPigoaD4oLuA+KD4oKIA+KD4oPig+KD4oPigomD4oPigrCCiwKzg+KD4oKMgo4Cj4Pig+KD4oPigpED4oPig+KD4oPigv0D4oLUgtYC6wLZAtqD4oPigsoD4oPig+KD4oK1A+KD4oOOg+KC74Pig+KD4oPigpKD4oPig+KD4oKUA+KD4oKVg+KClwPig+KCtoPigrgCuYPigraD4oKYgrmD4oPig+KD4oPig+KD4oPig+KD4oPigvED4oLyg+KD4oOOg+KCmgKbg+KCnQPigp6CoAPigqGD4oKjAqSD4oPig+KD4oPig+KCpgPigqeCqQPig+KD4oKqg+KD4oPig+KCrAPig+KD4oPig+KD4oPig+KD4oPig+KD4oKtg+KCrwPig+KCrYPigq8D4oPigrCCsgKzg+KD4oPig+KCtQPig+KCtoPigrgCuYPigrsD4oK8g+KD4oK/gsECvgPig+KCv4LBAsKD4oPigsQD4oLFg+KD4oLHAsiCygPig+KD4oPigsuD4oPig+KD4oLNA+KD4oPig+KCzoPig+KDjoPigtAD4oPig+KD4oLRg+KD4oPig+KC0wPig+KC1ILWAteC2QLagtSC1gLrAtkC2oLUgtYC14LZAtqD4oPigtwD4oPig+KD4oLdg+KD4oPig+KC3wPig+KD4oPiguCD4oPig+KD4oLiA+KD4oPig+KC7gPig+KC44LlAuaC6APig+KD4oLpg+KD4oPig+KC6wPig+KD4oPig+KC7IPig+KD4oPig+KD4oPig+KC7gPig+KDjoPigu+D4oPigvED4oLyg+KD4oLxA+KC8oPig+KDXoMEgwMD4oPigweDCQMKg+KD4oMHgwkC9APig+KDB4MJAvWD4oPigw2DDwMDA+KDEgMNgw8DAwPigxIDDYMPAwMD4oMSAw2DDwL3A+KDEgPig+KD4oPig+KC/oPigwADAYPigxaD4oL4g+KD4oMWg+KC+IPig+KD4oPigvoD4oPig+KD4oL7g+KD4oPig+KD4oL9A+KC/oPigwADAYPig16DBIMDA+KD4oNegwSDEIPig+KDvQPigwYD4oPigweDCQMKg+KD4oMNgw8DDAPigxIDDYMPAxCD4oMSAxaD4oMTg+KD4oMWg+KDFQPig+KDFoPigxgD4oPig+KD4oMZg+KD4oPig+KD4oMbA+KDYwNkg2GD4oPigxyD4oMeA+KD4oPig+KDigPig+KD4oPig6UD4oPig2qDbANtg+KD4oNqg2wDH4Pig+KDaoNsAyED4oPig+KD4oNdA+KD4oOfA+KDoIPig+KD4oPigyKD4oPig+KD4oMig+KD4oPig+KDJAPig+KD4oPigyWD4oPig+KD4oPNg+KD4oPig+KDJwPig+KD4oPig+KD4oPig16D4oNgA+KD4oOWA+KDl4OZA+KDdoN4A28DewN8g+KD4oPig+KD4oMog+KDKgPig+KDogPig6OD4oPig0gD4oNJg0sD4oOFg+KDK4Pig+KDhYPigyuD4oPig+KD4oPig+KD4oPig+KDTgPig+KD4oPig+KD4oPig+KD4oPig+KD4oPig+KD4oONA+KD4oPigy0DjQPig+KD4oPigy6D4oMwA+KDMYPig+KDMwPig+KD4oPig+KD4oOgg+KD4oNXAzSDNgPig+KDpoOoAzeD4oPig+KD4oM5A+KD4oM6g+KDPAM9g6CD4oPig34D4oPig+KD4oM/A+KD4oPig+KDXQPig+KDnwPig6CD4oPig+KD4oPNg+KD4oNAg+KDQgPig+KDQ4Pig0UD4oPig5YD4oOXg5kD4oOWA+KDRoOZA+KD4oPig+KD4oPig6ID4oOjg+KD4oNIA+KDSYNLA+KD4oPig+KDTIPig+KD4oPig0yD4oPig+KD4oPig+KD4oPig04D4oPig+KD4oNPg+KD4oOag+KDWINRA1KDVAPig1WD4oPig1QD4oNVg+KD4oNXA+KDWINaA1uD4oPig10D4oPig+KD4oPig+KD4oOWA+KDl4OZA+KDXoPig2AD4oPig2MDZINhg+KD4oNjA2SDZgPig+KDZ4Pig2kD4oPig2qDbANtg+KD4oN2g3CDbwPig+KDdoNwg3mD4oPig+KD4oNyA+KD4oOfA+KDgQPig+KD4oPig3OD4oPig+KD4oN1A+KD4oN2g3gDeYN7A3yD4oPig34D4oPig+KD4oN/g+KD4oPig+KDgQPig+KDhYPig4KD4oPig4WD4oOEA+KD4oOFg+KDhwPig+KD4oPig4iD4oPig+KD4oOKA+KD4oPig+KDi4ONA+KD4oPig+KD4oPig46D4oOQA+KD4oORg+KDkwPig+KD4oPig+KD4oPig+KD4oOxA+KD4oPVA9aDtYPig9mD1QPWg7WD4oPZg9UD1oO4g+KD2YPig+KDlIPig+KDlgPig5eDmQPig5qD4oOcA+KD4oO9A+KD4oPig+KD4oPig+KD4oPig9UD1oO1g+KD2YPig+KDnYPig+KD4oPig52D4oPig58D4oOgg+KD4oOiA+KDo4Pig+KD4oPig6UD4oPig6aDqAOpg+KD4oPig+KDtYPig+KDqwOsg9sD4oOuA+KD4oOvg+KD4oPDA8SDwYPig+KD4oPig7ED4oPig8kDyoPMA+KD4oPJA8qDsoPig+KDyQPKg7QD4oPig9UD1oO1g+KD2YPVA9aDtYPig9mD1QPWg7cD4oPZg9UD1oO4g+KD2YO6A+KDu4Pig+KDvQPig+KD4oPig94D4oO+g+KD4oPeA+KDvoPig+KD4oPig8AD4oPig8MDxIPBg+KD4oPDA8SDxgPig+KD4oPig8eD4oPig8kDyoPMA+KD4oPPA9CDzYPig+KDzwPQg9ID4oPig9UD1oPTg+KD2YPVA9aD2APig9mD3gPig9sD4oPig94D4oPcg+KD4oPeA+KD34Pig+KD4oPig+ED4oPigABAX0AAAABAUoDUwABAWUDUwABAWUDOQABAZoDUwABAZoCvAABAWcDUwABAfICvAABAogCSgABAUoAAAABAYMAAAABAUACvAABANAAAAABAJsAAAABAM0AAAABAJsDOQABAQoCvAABAWcCvAABAX0CvAABAfAAAAABAfACvQABA0QCvAABAS8CvAABAS8BUwABAU4AAAABAU4CvAABAUsA+QABAUQAAAABAUQCvAABAUEA+QABAS4AAAABAS4CvAABAS4BUwABAVUCvAABAVQCvAABAlUAAAABAk8CvwABAJ8AAAABANEAAAABAJ8CvAABAgQCvAABAZkAAAABAZkCvAABAZkCKQABAeEAAAABAeECvAABAXsCvAABAXsAAAABAuoAAAABAXsDOQABAhwAAAABAhwCvAABAW8AAAABAmkAAAABAWUCvAABAZ0CvAABAZ0DOQABAgQDOQABAT8DOQABAZoDNQABAZoDOQABAagAAAABAfUAAAABAagDOQABAagBXgABAoECvAABAUADOQABAVQDNQABAVQDOQABAVQDUwABAVUDOQABA0MAAAABA3QAAAABAfIDOQABAK4CSgABAWYCvAABAagCvAABAMcCSgABAUoCvAABAT8CvAABAZYAAAABAZ8CvAABAV4DUwABAV4DOQABAY8DUwABAYoCvAABAfECvAABAOwCvAABAQ4CSgABATwAAAABAT4CvAABATsBSgABAY8CvAABAr0AAAABAhQCvAABAV4AAAABAlEAAAABAV4CvAABAY8DNQABAYgAAAABArEAAAABAY8DOQABAo4CvAABAYoDNQABAYoDOQABApcAAAABAYoDUwABAfEDOQABAMMCSgABATgAAAABATgCEwABATUCvQABATUCowABAVUCEgABAVUCvQABAVUCswABATQCvQABAYIAAAABAW4CEgABARACEgABAaACEgABAgEBugABAQsAAAABAQsCEgABATkAAAABAL0AAAABAI0CxQABAIsCowABAI4CxQABAVsAAAABAJAC5gABAMMCeQABATMCEAABAUEAAAABAUECEgABAYoAAAABAYoCEgABArECEAABAPgAAAABAPgCEgABAPgA/AABAR4ABQABARQCEgABARMCEgABAMgCegABAQQCEgABAdAAAAABAcoCEAABAI0AAAABAI0C5gABAI0BZgABARYC5gABAagCEgABAY8AAAABAY8CEgABASECEgABAR8AAAABAf0AAAABASECowABAdkAAAABAc0CEgABATUAAAABAgkAAAABATUCEgABAT8CEgABAGsCEgABAagCowABAVUCnwABAVUCowABAT8AAAABAaIAAAABAT8CowABAT8BCQABAcgCEgABAUUCEgABAUUCowABAQcCowABARACnwABARACowABAaAAAAABARACvQABARQCowABASMCEAABAaACowABAJoBugABAS8AAAABAUICEgABAdQAAAABAdQCEgABATECEgABAVIAAAABAVICEgABAVIBpgABAVkAAAABAVkCEgABAgYCEAABAPsAAAABAQcCEgABAToAAAABAS4CEgABASMCuwABAIsAAAABALsAAAABAIsCnwABAVAAAAABAkkAAAABAhoCEgABAgYCnQABAUgCEgABATACvQABATACowABAUYCEgABAUYCswABAUYCvQABAWkAAAABAVYCEgABAhQAAAABAVACEgABAZUCEgABAU8CEgABAU8AAAABAk8AAAABAU8CowABAeUCEgABATAAAAABAb0AAAABATACEgABATQCEgABATQAAAABAKcCEgABATQCowABAUYCnwABAUcAAAABAkAAAAABAUYCowABAhECEgABAVACnwABAVACowABApUAAAABAVACvQABAZUCowABAAAAAAAJAAAAAQAIAAEABAAAA7wABgEAAAEACAABAAwAHAABACoASgABAAYG/wcABwEHAgcEBwUAAQAFBv8HAAcBBwQHBQAGAAAAGgAAABoAAAAaAAAAGgAAABoAAAAaAAH+1AAAAAUAEgAMABIAGAAeAAH+1P9qAAH+1P9vAAH+1P9jAAH+1P9yAAYCAAABAAgAAQF6AAwAAQGgAEAAAgAIBt8G6gAABuwG/QAMBwoHJAAeB0AHQQA5B0UHRQA7B0gHSgA8B0wHUQA/B1MHVABFAEcAkACuAK4ArgKSAJYAugCuALoAnACuALoAwADAAsAAwACiAKIAwACuAK4ArgCoAK4ArgCuALQAugDAAMYAzADqAOoA6gDSANgA9gDqAPYA3gDqAPYA/AD8At4A/AD8AOoA6gDqAOQA6gDqAOoA8AD2APwBFAEOAQ4BDgEgASABIAECAQgBDgEOARQBGgEgAAH+1AKjAAH+1AMwAAH+1AMxAAH+1AL9AAH+1AKfAAH+1AMtAAH+1AMDAAH+1AK9AAH+1AKzAAH+1ALfAAH+1AM5AAH+1ANSAAH+1APGAAH+1APHAAH+1AM1AAH+1APDAAH+1AOZAAH+1ANTAAH+1ANJAAEBLAKjAAEBLAK8AAEBLAK9AAEBLAKfAAEBLAL9AAEBLAKzAAYCAAABAAgAAQAMACgAAQAyAWoAAgAEBt8G6gAABuwG/QAMBwoHJAAeB14HbQA5AAIAAQdeB20AAABJAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABMgAAATIAAAEyAAABMgAAATIAAAEyAAABMgAAATIAAAEyAAABMgAAATIAAAEyAAABMgAAATIAAAEyAAABMgAAATIAAAEyAAABMgAAATIAAAEyAAABJgAAATIAAAEyAAABMgAAATIAAAEyAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEyAAABMgAAATIAAAEyAAABMgAAATIAAAEyAAABMgAB/tQCuwAB/tQCEgAB/tQCvAAQACgAKAAiACgALgAuADQAOgBGAEYAQABGAEwATABSAFgAAf7UAyUAAf7UAxoAAf98AvcAAf9WAwsAAf7UAyAAAf7UA7sAAf7UA7AAAf98A40AAf9WA6EAAf7UA7YAAQAMACIABQEKAq4AAgADBt8G6gAABuwHJwAMB14HbQBIAAIAJgAEAEgAAABKAH8ARQCBAKYAewCpALQAoQC2AL0ArQC/ANoAtQDcAN4A0QDgAOQA1ADmAPQA2QD2ASoA6AEsATYBHQE4AVABKAFSAVQBQQFWAaUBRAGnAa4BlAGwAc4BnAHQAdYBuwHYAgcBwgIJAjwB8gI+AkUCJgJIAm0CLgJvAn0CVAJ/ArMCYwK1AtkCmALfAyMCvQMlAzUDAgM3A1sDEwNdA4IDOAOFA5ADXgOSA5kDagObA7YDcgO4A7oDjgO8A8ADkQPCBAUDlgQHBBED2gQTBCoD5QQsBC4D/QQwBGMEAABYAAIBmAACAZgAAgGYAAIBmAACAZgAAgGYAAIBmAACAZgAAgGYAAIBmAACAZgAAgGYAAIBmAACAZgAAgGYAAIBmAACAZgAAgGYAAIBmAACAZgAAgGYAAIBmAACAZgAAgGYAAIBmAACAZgAAgGYAAIBmAACAZgAAgGYAAQBmAAAAWgAAAFoAAABaAAAAWgAAQFiAAABaAAAAWgAAwFuAAMBdAADAYwAAwF6AAIBngACAZ4AAgGeAAIBngACAZ4AAgGeAAIBngACAZ4AAgGeAAIBngACAZ4AAgGeAAIBngACAZ4AAgGeAAIBngACAZ4AAgGeAAIBngACAZ4AAgGeAAIBgAACAZ4AAgGeAAIBngACAZ4AAgGeAAMBhgADAYwAAwGSAAIBmAACAZgAAgGYAAIBmAACAZgAAgGYAAIBmAACAZgAAgGeAAIBngACAZ4AAgGeAAIBngACAZ4AAgGeAAIBngAB/tUAAAAB/tQAAAAB/tQBtgAB/kwBtgAB/soBCgAB/tQCuwAB/tQBZAAB/ycBggAB/mMBXgAB/tQCEgAB/tQCvAQ0KlIqWCpGPJQ8lCpSKlgqNDyUPJQqUipYKl48lDyUKlIqWCoQPJQ8lCouKlgqXjyUPJQqUipYKhA8lDyUKlIqWCoKPJQ8lCpSKlgqEDyUPJQqUipYKl48lDyUKlIqWCpePJQ8lCpSKlgqFjyUPJQqLipYKl48lDyUKlIqWCoWPJQ8lCpSKlgqHDyUPJQqUipYKiI8lDyUKlIqWCo0PJQ8lCpSKlgqKDyUPJQqLipYKkY8lDyUKlIqWCo0PJQ8lCpSKlgqOjyUPJQqUipYKl48lDyUKlIqWCpAPJQ8lCpSKlgqRjyUPJQqUipYKkw8lDyUKlIqWCpMPJQ8lCpSKlgqXjyUPJQuWjyULlQ8lDyULlo8lC5gPJQ8lCpkPJQqajyUPJQqgjyUKnA8lDyUKoI8lCp2PJQ8lCqCPJQqfDyUPJQqgjyUKnA8lDyUKoI8lCp2PJQ8lCqCPJQqfDyUPJQqgjyUKog8lDyUM0w8lCrQLn48lCqOPJQqlC5+PJQqmjyUKqAqpjyUM0w8lCqsLn48lCqyPJQquCq+PJQqxDyUKtAufjyUKso8lCrQLn48lCrWPJQq3C5+PJQrHiskKxg8lDyUKx4rJDjaPJQ8lCseKyQrKjyUPJQrHiskKyo8lDyUKx4rJCsqPJQ8lCseKyQrKjyUPJQrHiskKuI8lDyUKwArJCsqPJQ8lCseKyQq4jyUPJQrHiskKug8lDyUKx4rJCruPJQ8lCseKyQ42jyUPJQrHiskKvQ8lDyUKx4rJCr6PJQ8lCsAKyQrGDyUPJQrHiskONo8lDyUKx4rJCsGPJQ8lCseKyQrKjyUPJQrHiskKww8lDyUKx4rJCsSPJQ8lCseKyQrEjyUPJQrHiskKxg8lDyUKx4rJCsqPJQ8lCs2PJQrMDyUPJQrNjyUKzw8lDyULDg8lC72PJQ8lCw4PJQu2DyUPJQsODyULtg8lDyULDg8lC7YPJQ8lCwgPJQu9jyUPJQsODyULuQ8lDyULDg8lC7qPJQ8lCw4PJQu9jyUPJQsODyULDIrWjyUK0I8lCtIK048lCtUPJQsMitaPJQsODyULD4rWjyULDg8lCw+K1o8lCwgPJQsMitaPJQriiuQK948lDyUPJQ8lCtgPJQ8lCuKK5ArxjyUPJQriiuQK5Y8lDyUK4orkCuWPJQ8lCuKK5ArxjyUPJQriiuQK2Y8lDyUK4orkCtsPJQ8lCuKK5ArcjyUPJQreCuQK948lDyUK4orkCvGPJQ8lCuKK5ArfjyUPJQriiuQK5Y8lDyUK4orkCuEPJQ8lCuKK5Ar3jyUPJQriiuQK5Y8lDyUPJQ8lCucPJQ8lDyUPJQrojyUPJQrqDyUK7o8lDyUK6g8lCuuPJQ8lCu0PJQrujyUPJQvUDyUK94vXC9iL1A8lCvAL1wvYi9QPJQrxi9cL2IvUDyUK94vXC9iK8w8lCveL1wvYi9QPJQr3i9cL2IrzDyUK94vXC9iL1A8lCvSL1wvYivYPJQr3i9cL2Ir5DyUK+or8Cv2K/w8lCwIPJQ8lCwCPJQsCDyUPJQsODyULDI8lDyULDg8lCwOPJQ8lCw4PJQsFDyUPJQsODyULD48lDyULCA8lCwyPJQ8lCw4PJQsGjyUPJQsIDyULDI8lDyULDg8lCwmPJQ8lCwsPJQsMjyUPJQsODyULD48lDyULIAshiyqLJIsmCyALIYsdCySLJgsgCyGLHoskiyYLIAshix6LJIsmCyALIYsRCySLJgsYiyGLHoskiyYLIAshixELJIsmCyALIYsSiySLJgsgCyGLFAskiyYLIAshix0LJIsmCyALIYsViySLJgsgCyGLIwskiyYLIAshixcLJIsmCxiLIYsqiySLJgsgCyGLHQskiyYLIAshixoLJIsmCyAPJQsqjyUPJQsgDyULHQ8lDyULGI8lCyqPJQ8lCyAPJQsdDyUPJQsgDyULGg8lDyULIA8lCx6PJQ8lCyALIYsdCySLJgsgCyGLHoskiyYLIAshixuLJIsmCyALIYsjCySLJgsgCyGLIwskiyYPJQ8lCyqPJQ8lCyALIYsqiySLJgsgCyGLHQskiyYLIAshix6LJIsmCyALIYsjCySLJgsgCyGLIwskiyYLIAshiyMLJIsmCyePJQspDyUPJQ8lDyULKo8lDyULLw8lCzOPJQ8lCy8PJQssDyUPJQsvDyULMI8lDyULLY8lCzOPJQ8lCy8PJQssDyUPJQstjyULM48lDyULLw8lCzCPJQ8lCzIPJQszjyUPJQs7DyULPI8lDyULOw8lCzUPJQ8lCzsPJQs2jyUPJQs7DyULOY8lDyULOw8lCzgPJQ8lCzsPJQs8jyUPJQs7DyULOY8lDyULPg8lCzyPJQ8lCzsPJQs/jyUPJQs+DyULPI8lDyULPg8lCz+PJQ8lDhEPJQtBDyUPJQtEDyULSItKDyULRA8lC0iLSg8lC0QPJQtCi0oPJQtEDyULSItKDyULRY8lC0iLSg8lC0WPJQtIi0oPJQtHDyULSItKDyULWQtai06PJQtdi1kLWotRjyULXYtZC1qLV48lC12LWQtai1ePJQtdi1kLWotXjyULXYtZC1qLUY8lC12LWQtai0uPJQtdi00LWotOjyULXYtZC1qLUY8lC12LWQtai1APJQtdi1kLWotOjyULXYtZC1qLUY8lC12LTQtai06PJQtdi1kLWotRjyULXYtZC1qLUA8lC12LWQtai1ePJQtdi1kLWotRjyULXYtZC1qLV48lC12LWQtai1MPJQtdi1kLWotUjyULXYtZC1qLVg8lC12LWQtai1ePJQtdi1kLWotcDyULXYtjjyULXw8lDyULY48lC2UPJQ8lC2OPJQtgjyUPJQtjjyULYg8lDyULY48lC2UPJQ8lC3EPJQtrC3QPJQtxDyULbIt0DyULcQ8lC3KLdA8lC3EPJQtmi3QPJQtxDyULaAt0DyULaY8lC2sLdA8lC3EPJQtsi3QPJQtxDyULbgt0DyULcQ8lC2+LdA8lC3EPJQtyi3QPJQt4jyULfQ8lDyULeI8lC3WPJQ8lC3iPJQt3DyUPJQt4jyULeg8lDyULe48lC30PJQ8lC5CLkguNjyUPJQuQi5ILiQ8lDyULkIuSC5OPJQ8lC5CLkguADyUPJQuHi5ILk48lDyULkIuSC4APJQ8lC5CLkgt+jyUPJQuQi5ILgA8lDyULkIuSC5OPJQ8lC5CLkguTjyUPJQuQi5ILgY8lDyULh4uSC5OPJQ8lC5CLkguBjyUPJQuQi5ILgw8lDyULkIuSC4SPJQ8lC5CLkguJDyUPJQuQi5ILhg8lDyULh4uSC42PJQ8lC5CLkguJDyUPJQuQi5ILio8lDyULkIuSC5OPJQ8lC5CLkguMDyUPJQuQi5ILjY8lDyULkIuSC48PJQ8lC5CLkguPDyUPJQuQi5ILk48lDyULlo8lC5UPJQ8lC5aPJQuYDyUPJQuZjyULmwufjyULnI8lC54Ln48lC7GLswuwDyUPJQuxi7MLqg8lDyULsYuzC7SPJQ8lC7GLswu0jyUPJQuxi7MLtI8lDyULsYuzC7SPJQ8lC7GLswuhDyUPJQuoi7MLtI8lDyULsYuzC6EPJQ8lC7GLswuijyUPJQuxi7MLpA8lDyULsYuzC6oPJQ8lC7GLswuljyUPJQuxi7MLpw8lDyULqIuzC7APJQ8lC7GLswuqDyUPJQuxi7MLq48lDyULsYuzC7SPJQ8lC7GLswutDyUPJQuxi7MLro8lDyULsYuzC66PJQ8lC7GPJQuwDyUPJQuxi7MLtI8lDyULvA8lC72PJQ8lC7wPJQu2DyUPJQu8DyULtg8lDyULvA8lC7YPJQ8lC7ePJQu9jyUPJQu8DyULuQ8lDyULvA8lC7qPJQ8lC7wPJQu9jyUPJQvMi84Lyw8lDyUPJQ8lC78PJQ8lC8yLzgvGjyUPJQvMi84Lz48lDyULzIvOC8+PJQ8lC8yLzgvGjyUPJQvMi84LwI8lDyULzIvOC8IPJQ8lC8yLzgvDjyUPJQvFC84Lyw8lDyULzIvOC8aPJQ8lC8yLzgvIDyUPJQvMi84Lz48lDyULzIvOC8mPJQ8lC8yLzgvLDyUPJQvMi84Lz48lDyUPJQ8lC9EPJQ8lDyUPJQvSjyUPJQvUDyUL1YvXC9iL2g8lC90PJQ8lC9uPJQvdDyUPJQvpDyUL548lDyUL6Q8lC96PJQ8lC+kPJQvgDyUPJQvpDyUL6o8lDyUL4w8lC+ePJQ8lC+kPJQvhjyUPJQvjDyUL548lDyUL6Q8lC+SPJQ8lC+YPJQvnjyUPJQvpDyUL6o8lDyUL7A8lC+2PJQ8lDNYPJQvzi/UPJQzWDyUL84v1DyUM1g8lC+8L9Q8lDNYPJQvzi/UPJQvwjyUL84v1DyUL8I8lC/OL9Q8lC/IPJQvzi/UPJQwEDAWL/48lDAiMBAwFi/sPJQwIjAQMBYwCjyUMCIwEDAWMAo8lDAiMBAwFjAKPJQwIjAQMBYv7DyUMCIwEDAWL9o8lDAiL+AwFi/+PJQwIjAQMBYv7DyUMCIwEDAWL+Y8lDAiMBAwFi/+PJQwIjAQMBYv7DyUMCIv4DAWL/48lDAiMBAwFi/sPJQwIjAQMBYv5jyUMCIwEDAWMAo8lDAiMBAwFi/sPJQwIjAQMBYwCjyUMCIwEDAWL/I8lDAiMBAwFi/4PJQwIjAQMBYv/jyUMCIwEDAWMAQ8lDAiMBAwFjAKPJQwIjAQMBYwHDyUMCIwOjyUMCg8lDyUMDo8lDBAPJQ8lDA6PJQwLjyUPJQwOjyUMDQ8lDyUMDo8lDBAPJQ8lDBwPJQwWDyUPJQwcDyUMF48lDyUMHA8lDB2PJQ8lDBwPJQwRjyUPJQwcDyUMEw8lDyUMFI8lDBYPJQ8lDBwPJQwXjyUPJQwcDyUMGQ8lDyUMHA8lDBqPJQ8lDBwPJQwdjyUPJQ6SDyUMI48lDyUOkg8lDB8PJQ8lDpIPJQwgjyUPJQ6SDyUMIg8lDyUOiQ8lDCOPJQ8lDnoMNYwyjyUPJQ56DDWMLg8lDyUOegw1jDcPJQ8lDnoMNYwmjyUPJQ59DDWMNw8lDyUOegw1jCaPJQ8lDnoMNYwlDyUPJQ56DDWMJo8lDyUOegw1jDcPJQ8lDnoMNYw3DyUPJQ56DDWMKA8lDyUOfQw1jDcPJQ8lDnoMNYwoDyUPJQ56DDWMKY8lDyUOegw1jCsPJQ8lDnoMNYwuDyUPJQ56DDWMLI8lDyUOfQw1jDKPJQ8lDnoMNYwuDyUPJQ56DDWML48lDyUOegw1jDcPJQ8lDnoMNYwxDyUPJQ56DDWMMo8lDyUOegw1jDQPJQ8lDnoMNYw0DyUPJQ56DDWMNw8lDyUMOg8lDDiPJQ8lDDoPJQw7jyUPJQxBjyUMPQ8lDyUMQY8lDD6PJQ8lDEGPJQxADyUPJQxBjyUMPQ8lDyUMQY8lDD6PJQ8lDEGPJQxADyUPJQxBjyUMQw8lDyUMRI8lDyUNQ41FDESPJQ8lDUONRQxEjyUPJQ1DjUUMRg8lDyUNQ41FDEePJQ8lDUONRQxJDyUMSo1DjUUO1AxeDFOPJQ8lDtQMXgxVDyUPJQ7UDF4MX48lDyUO1AxeDF+PJQ8lDtQMXgxfjyUPJQ7UDF4MX48lDyUO1AxeDEwPJQ8lDgUMXgxfjyUPJQ7UDF4MTA8lDyUO1AxeDE2PJQ8lDtQMXgxPDyUPJQ7UDF4MVQ8lDyUO1AxeDFCPJQ8lDtQMXgxSDyUPJQ4FDF4MU48lDyUO1AxeDFUPJQ8lDtQMXgxWjyUPJQ7UDF4MX48lDyUO1AxeDFgPJQ8lDtQMXgxZjyUPJQ7UDF4MWY8lDyUMWw8lDFyPJQ8lDtQMXgxfjyUPJQxhDGKMZA8lDyUMZw8lDGWPJQ8lDGcPJQxojyUPJQ8lDyUMag8lDyUPJQ8lDGuPJQ8lDyUPJQxrjyUPJQ8lDyUMa48lDyUPJQ8lDG0PJQ8lDyUPJQxujyUPJQ8lDyUMcA8lDyUOkg8lDWkMdIx2DpIPJQ1pDHSMdgxxjyUNaQx0jHYOkg8lDIyMdIx2DpIPJQxzDHSMdg6JDyUNaQx0jHYM3AyDjIIPJQ8lDNwMg4x3jyUPJQzcDIOMfY8lDyUM3AyDjIUPJQ8lDNwMg4yFDyUPJQzcDIOMfY8lDyUM3AyDjHkPJQ8lDNwMg4x6jyUPJQzcDIOMfA8lDyUM2oyDjIIPJQ8lDNwMg4x9jyUPJQzcDIOMfw8lDyUM3AyDjIUPJQ8lDNwMg4ySjyUPJQzcDIOMgI8lDyUM3AyDjIIPJQ8lDNwMg4yFDyUPJQ8lDyUMho8lDyUPJQ8lDIgPJQ8lDyUPJQyJjyUPJQyLDyUNaQ8lDI+Miw8lDIyPJQyPjI4PJQ1pDyUMj44LDyUMkQ8lDyUM3A8lDWkNaoyUDNwPJQ1hjWqMlAzcDyUNaQ1qjJQM2o8lDWkNaoyUDNwPJQ1pDWqMlAzajyUNaQ1qjJQM3A8lDJKNaoyUDN8PJQ1pDWqMlAyVjyUMlwyYjJoMm48lDyUPJQ8lDJ0PJQ8lDyUPJQ6SDyUMp48lDyUOkg8lDJ6PJQ8lDKAPJQyhjyUPJQ6SDyUMqQ8lDyUOiQ8lDKePJQ8lDpIPJQyjDyUPJQ6JDyUMp48lDyUOkg8lDKSPJQ8lDKYPJQynjyUPJQ6SDyUMqQ8lDyUMxYzHDL4MygzLjMWMxwy7DMoMy4zFjMcMxAzKDMuMxYzHDMQMygzLjMWMxwyqjMoMy4yyDMcMxAzKDMuMxYzHDKqMygzLjMWMxwysDMoMy4zFjMcMrYzKDMuMxYzHDLsMygzLjMWMxwyvDMoMy4zFjMcMyIzKDMuMxYzHDLCMygzLjLIMxwy+DMoMy4zFjMcMuwzKDMuMxYzHDLOMygzLjLmPJQzXjyUPJQy5jyUMto8lDyUMtQ8lDNePJQ8lDLmPJQy2jyUPJQy5jyUMuA8lDyUMuY8lDMQPJQ8lDMWMxwy7DMoMy4zFjMcMxAzKDMuMxYzHDLyMygzLjMWMxwzIjMoMy4zFjMcMyIzKDMuMxY8lDL4Mygy/jMWMxwzBDMoMy4zFjMcMwozKDMuMxYzHDMQMygzLjMWMxwzIjMoMy4zFjMcMyIzKDMuMxYzHDMiMygzLjM0PJQzOjyUPJQzQDyUM0Y8lDyUM0w8lDNSPJQ8lDNYPJQzXjyUPJQzcDyUM4I8lDyUM3A8lDNkPJQ8lDNwPJQzdjyUPJQzajyUM4I8lDyUM3A8lDNkPJQ8lDNqPJQzgjyUPJQzcDyUM3Y8lDyUM3w8lDOCPJQ8lDOgPJQzpjyUPJQzoDyUM4g8lDyUM6A8lDOOPJQ8lDOgPJQzmjyUPJQzoDyUM5Q8lDyUM6A8lDOmPJQ8lDOgPJQzmjyUPJQzrDyUM6Y8lDyUM6A8lDOyPJQ8lDOsPJQzpjyUPJQzrDyUM7I8lDyUM9A8lDPoM+4z9DO4PJQzvjPEM8oz0DyUM+gz7jP0M9A8lDPoM+4z9DPcPJQz6DPuM/Qz0DyUM9Yz7jP0M9w8lDPoM+4z9DPiPJQz6DPuM/Q23DQGNig8lDQSNtw0BjYuPJQ0EjbcNAY2RjyUNBI23DQGNkY8lDQSNtw0BjZGPJQ0EjbcNAY2LjyUNBI23DQGNhw8lDQSM/o0BjYoPJQ0EjbcNAY2LjyUNBI23DQGNjQ8lDQSNtw0BjYoPJQ0EjbcNAY2LjyUNBIz+jQGNig8lDQSNtw0BjYuPJQ0EjbcNAY2NDyUNBI23DQGNkY8lDQSNtw0BjYuPJQ0EjbcNAY2RjyUNBI23DQGNjo8lDQSNtw0BjQMPJQ0EjbcNAY2KDyUNBI23DQGNAA8lDQSNtw0BjZGPJQ0EjbcNAY0DDyUNBI0GDyUNB48lDyUNDY8lDQkPJQ8lDQ2PJQ0PDyUPJQ0NjyUNCo8lDyUNDY8lDQwPJQ8lDQ2PJQ0PDyUPJQ0bDyUNFQ8lDyUNGw8lDRaPJQ8lDRsPJQ0cjyUPJQ0bDyUNEI8lDyUNGw8lDRIPJQ8lDROPJQ0VDyUPJQ0bDyUNFo8lDyUNGw8lDRgPJQ8lDRsPJQ0ZjyUPJQ0bDyUNHI8lDyUNIQ8lDSWPJQ8lDSEPJQ0eDyUPJQ0hDyUNH48lDyUNIQ8lDSKPJQ8lDSQPJQ0ljyUPJQ05DTqNNg8lDyUNOQ06jTGPJQ8lDTkNOo08DyUPJQ05DTqNKI8lDyUNMA06jTwPJQ8lDTkNOo0ojyUPJQ05DTqNJw8lDyUNOQ06jSiPJQ8lDTkNOo08DyUPJQ05DTqNPA8lDyUNOQ06jSoPJQ8lDTANOo08DyUPJQ05DTqNKg8lDyUNOQ06jSuPJQ8lDTkNOo0tDyUPJQ05DTqNMY8lDyUNOQ06jS6PJQ8lDTANOo02DyUPJQ05DTqNMY8lDyUNOQ06jTMPJQ8lDTkNOo08DyUPJQ05DTqNNI8lDyUNOQ06jTYPJQ8lDTkNOo03jyUPJQ05DTqNN48lDyUNOQ06jTwPJQ8lDyUPJQ09jyUPJQ8lDyUNPw8lDyUNQI8lDUINQ41FDViNWg1PjyUPJQ1YjVoNUQ8lDyUNWI1aDVuPJQ8lDViNWg1bjyUPJQ1YjVoNW48lDyUNWI1aDVuPJQ8lDViNWg1GjyUPJQ1ODVoNW48lDyUNWI1aDUaPJQ8lDViNWg1IDyUPJQ1YjVoNSY8lDyUNWI1aDVEPJQ8lDViNWg1LDyUPJQ1YjVoNTI8lDyUNTg1aDU+PJQ8lDViNWg1RDyUPJQ1YjVoNUo8lDyUNWI1aDVuPJQ8lDViNWg1UDyUPJQ1YjVoNVY8lDyUNWI1aDVWPJQ8lDdmPJQ1XDyUPJQ1YjVoNW48lDyUNXQ1ejWAPJQ8lDWePJQ1pDWqNc41njyUNYY1qjXONZ48lDWkNao1zjWMPJQ1pDWqNc41njyUNaQ1qjXONYw8lDWkNao1zjWePJQ1kjWqNc41mDyUNaQ1qjXONZ48lDWkNao1zjWwPJQ1tjyUPJQ11DyUNew18jX4Nbw8lDXCNcg1zjXUPJQ17DXyNfg11DyUNew18jX4NeA8lDXsNfI1+DXUPJQ12jXyNfg14DyUNew18jX4NeY8lDXsNfI1+DYQPJQ1/jyUPJQ2EDyUNhY8lDyUNhA8lDYEPJQ8lDYQPJQ2CjyUPJQ2EDyUNhY8lDyUNkA8lDYoPJQ8lDZAPJQ2LjyUPJQ2QDyUNkY8lDyUNkA8lDYcPJQ8lDYiPJQ2KDyUPJQ2QDyUNi48lDyUNkA8lDY0PJQ8lDZAPJQ2OjyUPJQ2QDyUNkY8lDyUNlg8lDZqPJQ8lDZYPJQ2TDyUPJQ2WDyUNlI8lDyUNlg8lDZePJQ8lDZkPJQ2ajyUPJQ7UDayNqY8lDyUO1A2sjaUPJQ8lDtQNrI2uDyUPJQ7UDayNnY8lDyUOBQ2sja4PJQ8lDtQNrI2djyUPJQ7UDayNnA8lDyUO1A2sjZ2PJQ8lDtQNrI2uDyUPJQ7UDayNrg8lDyUO1A2sjZ8PJQ8lDgUNrI2uDyUPJQ7UDayNnw8lDyUO1A2sjaCPJQ8lDtQNrI2iDyUPJQ7UDayNpQ8lDyUO1A2sjaOPJQ8lDgUNrI2pjyUPJQ7UDayNpQ8lDyUO1A2sjaaPJQ8lDtQNrI2uDyUPJQ7UDayNqA8lDyUO1A2sjamPJQ8lDtQNrI2rDyUPJQ7UDayNqw8lDyUO1A2sja4PJQ8lDbEPJQ2vjyUPJQ2xDyUNso8lDyUNvQ8lDbQPJQ8lDbcPJQ6/DyUPJQ23DyUNtY8lDyUNtw8lDrePJQ8lDbcPJQ6/DyUPJQ23DyUNtY8lDyUNtw8lDrePJQ8lDbcPJQ66jyUPJQ29DyUOAg6eDyUNuI8lDboNu48lDb0PJQ39jp4PJQ2+jyUNwA3BjyUNww8lDgIOng8lDcSPJQ4CDp4PJQ3GDyUNx46eDyUN2Y3bDdgPJQ8lDdmN2w3SDyUPJQ3ZjdsN3I8lDyUN2Y3bDdyPJQ8lDdmN2w3cjyUPJQ3ZjdsN3I8lDyUN2Y3bDckPJQ8lDdCN2w3cjyUPJQ3ZjdsNyQ8lDyUN2Y3bDcqPJQ8lDdmN2w3MDyUPJQ3ZjdsN0g8lDyUN2Y3bDc2PJQ8lDdmN2w3PDyUPJQ3QjdsN2A8lDyUN2Y3bDdIPJQ8lDdmN2w3TjyUPJQ3ZjdsN3I8lDyUN2Y3bDdUPJQ8lDdmN2w3WjyUPJQ3ZjdsN1o8lDyUN2Y3bDdgPJQ8lDdmN2w3cjyUPJQ60jyUOtg8lDyUN348lDd4PJQ8lDd+PJQ3hDyUPJQ8BDyUOvw8lDyUPAQ8lDrePJQ8lDwEPJQ63jyUPJQ8BDyUOt48lDyUO9o8lDr8PJQ8lDwEPJQ66jyUPJQ8BDyUOvA8lDyUPAQ8lDr8PJQ8lDh6PJQ4dDeiPJQ3ijyUN5A3ljyUN5w8lDh0N6I8lDh6PJQ4gDeiPJQ4ejyUOIA3ojyUOGI8lDh0N6I8lDfYN9430jyUPJQ32DfeN9I8lDyUN9g33jfAPJQ8lDfYN9435DyUPJQ32DfeN+Q8lDyUN9g33jfAPJQ8lDfYN943qDyUPJQ32DfeN648lDyUN9g33je0PJQ8lDe6N9430jyUPJQ32DfeN8A8lDyUN9g33jfGPJQ8lDfYN9435DyUPJQ8lDyUOyA8lDyUN9g33jfMPJQ8lDfYN9430jyUPJQ32DfeN+Q8lDyUPJQ8lDfqPJQ8lDyUPJQ38DyUPJQ4AjyUOAg8lDyUOAI8lDf2PJQ8lDf8PJQ4CDyUPJQ4AjyUOAg8lDyUO1A8lDgmO1w7YjtQPJQ4DjtcO2I7UDyUOCY7XDtiOBQ8lDgmO1w7YjtQPJQ4JjtcO2I4FDyUOCY7XDtiO1A8lDgaO1w7YjggPJQ4JjtcO2I4LDyUODI4ODg+OEQ8lDhQPJQ8lDhKPJQ4UDyUPJQ4ejyUOHQ8lDyUOHo8lDhWPJQ8lDh6PJQ4gDyUPJQ4YjyUOHQ8lDyUOHo8lDhcPJQ8lDhiPJQ4dDyUPJQ4ejyUOGg8lDyUOG48lDh0PJQ8lDh6PJQ4gDyUPJQ4zjjUOLw44DjmOM441DiwOOA45jjOONQ4yDjgOOY4zjjUOMg44DjmOM441DiGOOA45jikONQ4yDjgOOY4zjjUOIY44DjmOM441DiMOOA45jjOONQ4kjjgOOY4zjjUOLA44DjmOM441DiYOOA45jjOONQ42jjgOOY4zjjUOJ444DjmOKQ41Di8OOA45jjOONQ4sDjgOOY4zjjUOKo44DjmOM48lDi8PJQ8lDjOPJQ4sDyUPJQ4pDyUOLw8lDyUOM48lDiwPJQ8lDjOPJQ4qjyUPJQ4zjyUOMg8lDyUOM441DiwOOA45jjOONQ4yDjgOOY4zjjUOLY44DjmOM441DjaOOA45jjOONQ42jjgOOY8lDyUOLw8lDyUOMI41DuYOOA45jjCONQ7ejjgOOY4zjjUOMg44DjmOM441DjaOOA45jjOONQ42jjgOOY4zjjUONo44DjmOOw8lDjyPJQ8lDyUPJQ4+DyUPJQ5CjyUORw8lDyUOQo8lDj+PJQ8lDkKPJQ5EDyUPJQ5BDyUORw8lDyUOQo8lDj+PJQ8lDkEPJQ5HDyUPJQ5CjyUORA8lDyUORY8lDkcPJQ8lDk6PJQ5QDyUPJQ5OjyUOSI8lDyUOTo8lDkoPJQ8lDk6PJQ5NDyUPJQ5OjyUOS48lDyUOTo8lDlAPJQ8lDk6PJQ5NDyUPJQ5RjyUOUA8lDyUOTo8lDlMPJQ8lDlGPJQ5QDyUPJQ5RjyUOUw8lDyUOVg8lDlwOXY8lDlYPJQ5cDl2PJQ5WDyUOVI5djyUOVg8lDlwOXY8lDlkPJQ5cDl2PJQ5WDyUOV45djyUOWQ8lDlwOXY8lDlqPJQ5cDl2PJQ8BDl8O/I8lDmCPAQ5fDvmPJQ5gjwEOXw7/jyUOYI8BDl8O/48lDmCPAQ5fDv+PJQ5gjwEOXw75jyUOYI8BDl8O9Q8lDmCO9o5fDvyPJQ5gjwEOXw75jyUOYI8BDl8O+A8lDmCPAQ5fDvyPJQ5gjwEOXw75jyUOYI72jl8O/I8lDmCPAQ5fDvmPJQ5gjwEOXw74DyUOYI8BDl8O/48lDmCPAQ5fDvmPJQ5gjwEOXw7/jyUOYI8BDl8O+w8lDmCPAQ5fDwQPJQ5gjwEOXw7+DyUOYI8BDl8O/48lDmCPAQ5fDwQPJQ5gjmaPJQ5iDyUPJQ5mjyUOaA8lDyUOZo8lDmOPJQ8lDmaPJQ5lDyUPJQ5mjyUOaA8lDyUOdA8lDm4PJQ8lDnQPJQ5vjyUPJQ50DyUOdY8lDyUOdA8lDmmPJQ8lDnQPJQ5rDyUPJQ5sjyUObg8lDyUOdA8lDm+PJQ8lDnQPJQ5xDyUPJQ50DyUOco8lDyUOdA8lDnWPJQ8lDnoPJQ5+jyUPJQ56DyUOdw8lDyUOeg8lDniPJQ8lDnoPJQ57jyUPJQ59DyUOfo8lDyUOkg6Tjo8PJQ8lDpIOk46KjyUPJQ6SDpOOlQ8lDyUOkg6TjoGPJQ8lDokOk46VDyUPJQ6SDpOOgY8lDyUOkg6TjoAPJQ8lDpIOk46BjyUPJQ6SDpOOlQ8lDyUOkg6TjpUPJQ8lDpIOk46DDyUPJQ6JDpOOlQ8lDyUOkg6TjoMPJQ8lDpIOk46EjyUPJQ6SDpOOhg8lDyUOkg6TjoqPJQ8lDpIOk46HjyUPJQ6JDpOOjw8lDyUOkg6TjoqPJQ8lDpIOk46MDyUPJQ6SDpOOlQ8lDyUOkg6Tjo2PJQ8lDpIOk46PDyUPJQ6SDpOOkI8lDyUOkg6TjpCPJQ8lDpIOk46VDyUPJQ6YDyUOlo8lDyUOmA8lDpmPJQ8lDpsPJQ6cjp4PJQ6wDrGOro8lDyUOsA6xjqiPJQ8lDrAOsY6zDyUPJQ6wDrGOsw8lDyUOsA6xjrMPJQ8lDrAOsY6zDyUPJQ6wDrGOn48lDyUOpw6xjrMPJQ8lDrAOsY6fjyUPJQ6wDrGOoQ8lDyUOsA6xjqKPJQ8lDrAOsY6ojyUPJQ6wDrGOpA8lDyUOsA6xjqWPJQ8lDqcOsY6ujyUPJQ6wDrGOqI8lDyUOsA6xjqoPJQ8lDrAOsY6zDyUPJQ6wDrGOq48lDyUOsA6xjq0PJQ8lDrAOsY6tDyUPJQ8lDyUOro8lDyUOsA6xjrMPJQ8lDrSPJQ62DyUPJQ69jyUOvw8lDyUOvY8lDrePJQ8lDr2PJQ63jyUPJQ69jyUOt48lDyUOuQ8lDr8PJQ8lDr2PJQ66jyUPJQ69jyUOvA8lDyUOvY8lDr8PJQ8lDsyOzg7LDyUPJQ7Mjs4Oyw8lDyUOzI7ODsUPJQ8lDsyOzg7PjyUPJQ7Mjs4Oz48lDyUOzI7ODsUPJQ8lDsyOzg7AjyUPJQ7Mjs4Owg8lDyUOw47ODssPJQ8lDsyOzg7FDyUPJQ7Mjs4Oxo8lDyUOzI7ODs+PJQ8lDyUPJQ7IDyUPJQ7Mjs4OyY8lDyUOzI7ODssPJQ8lDsyOzg7PjyUPJQ8lDyUO0Q8lDyUPJQ8lDtKPJQ8lDtQPJQ7VjtcO2I7aDyUO3Q8lDyUO248lDt0PJQ8lDuePJQ7mDyUPJQ7njyUO3o8lDyUO548lDukPJQ8lDuGPJQ7mDyUPJQ7njyUO4A8lDyUO4Y8lDuYPJQ8lDuePJQ7jDyUPJQ7kjyUO5g8lDyUO548lDukPJQ8lDuwPJQ7yDvOPJQ7sDyUO8g7zjyUO7A8lDuqO848lDuwPJQ7yDvOPJQ7vDyUO8g7zjyUO7A8lDu2O848lDu8PJQ7yDvOPJQ7wjyUO8g7zjyUPAQ8CjvyPJQ8FjwEPAo75jyUPBY8BDwKO/48lDwWPAQ8Cjv+PJQ8FjwEPAo7/jyUPBY8BDwKO+Y8lDwWPAQ8CjvUPJQ8FjvaPAo78jyUPBY8BDwKO+Y8lDwWPAQ8CjvgPJQ8FjwEPAo78jyUPBY8BDwKO+Y8lDwWO9o8CjvyPJQ8FjwEPAo75jyUPBY8BDwKO+A8lDwWPAQ8Cjv+PJQ8FjwEPAo75jyUPBY8BDwKO/48lDwWPAQ8CjvsPJQ8FjwEPAo8EDyUPBY8BDwKO/I8lDwWPAQ8Cjv4PJQ8FjwEPAo7/jyUPBY8BDwKPBA8lDwWPC48lDwcPJQ8lDwuPJQ8NDyUPJQ8LjyUPCI8lDyUPC48lDwoPJQ8lDwuPJQ8NDyUPJQ8ZDyUPEw8lDyUPGQ8lDxSPJQ8lDxkPJQ8ajyUPJQ8ZDyUPDo8lDyUPGQ8lDxAPJQ8lDxGPJQ8TDyUPJQ8ZDyUPFI8lDyUPGQ8lDxYPJQ8lDxkPJQ8XjyUPJQ8ZDyUPGo8lDyUPHw8lDyOPJQ8lDx8PJQ8cDyUPJQ8fDyUPHY8lDyUPHw8lDyCPJQ8lDyIPJQ8jjyUPJQAAQFuA7sAAQFuA7AAAQIWA40AAQHwA6EAAQFuA7YAAQFu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AFYAZQB0AIMAkQCgAK8AvgDNANwA6wD6AQkBGAEnATYAAP//ABUADAAbACoAOQBIAFcAZgB1AIQAkgChALAAvwDOAN0A7AD7AQoBGQEoATcAAP//ABUADQAcACsAOgBJAFgAZwB2AIUAkwCiALEAwADPAN4A7QD8AQsBGgEpATgAAP//ABUADgAdACwAOwBKAFkAaAB3AIYAlACjALIAwQDQAN8A7gD9AQwBGwEqATkBOmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNjbXAHgmNjbXAHgmNjbXAHgmNjbXAHgmNjbXAHgmNjbXAHcmNjbXAHgmNjbXAHgmNjbXAHgmNjbXAHgmNjbXAHgmNjbXAHgmNjbXAHgmNjbXAHgmNjbXAHgmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxvY2wHsGxvY2wHtmxvY2wHvGxvY2wHwmxvY2wHyGxvY2wHzmxvY2wH1GxvY2wH2mxvY2wH4GxvY2wH5mxvY2wH7GxvY2wH8mxvY2wH+GxvY2wH/m51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQgAAAAIAAAABAAAAAQAkAAAAAQAmAAAABgACAAMABAAFAAYABwAAAAQAAgADAAQABQAAAAEAJwAAAAEAGgAAAAMAGwAcAB0AAAABACgAAAABACAAAAABABEAAAABABUAAAABABQAAAABABIAAAABABMAAAABABAAAAABAAkAAAABAA8AAAABAAwAAAABAAsAAAABAAgAAAABAAoAAAABAA0AAAABAA4AAAABABkAAAABACMAAAACAB4AHwAAAAEAIQAAAAEAKQAAAAEAFwAAAAEAJQAAAAEAKgAAAAEAFgAAAAEAGAAAAAEAIgAtAFwG3hGaEkgSrhKuFAIUAhSsFNoVHhUeFUAVQBVAFUAVQBVUFcIV1hX8FhYWPBZKFlgWiBZmFnQWiBaWFt4XJhdIF2AXeBeQF64Z+BxUHUYdZh2OHY4iniM4AAEAAAABAAgAAgRCAh4C+wL8Av0C/gL/AwADAQMCAwMDBAMFAwYDBwMIAyIDIwMtAy4DLwMwAzEDMgNHA0gDSQNLA0wDTQNOA08DUANRA1IDUwNhA2IDYwNkA2UDZgNnA2gDaQNqA2sDbANtA24DbwNwA3EDcgNzA3QDdQN2A3cDeAN5A3oDewN8A30DfgN/A4ADgQOCA4MDhAOGA4cDiAOJA4oDiwOMA40DjgOPA5ADkQOSA5MDlQOWA5cDmAOZA5oDuwPBAvsC/AL9Av4C/wMAAwEDAgMDAwQDBQMGAwcDCAMiAyMDJQMmAycDKAMpAyoDKwMsAy0DLgMvAzADMQMyAzQDNQM3AzgDOQM6AzsDPAM9Az4DPwNAA0EDQgNDA0QDRgNHA0gDSQNKA1QDVQNWA1cDWANZA1oDWwNcA10DXgNfA2EDYgNjA2QDZQNmA2cDaANpA2oDawNsA20DbgNvA3ADcQNyA3MDdAN1A3YDdwN4A3kDegN7A3wDfQN+A38DgAOBA4MDhAOFA4YDhwOIA4kDigOLA4wDjQOOA48DkAORA5IDkwOVA5YDlwOYA5kDmgOjA6QDpQOmA6cDqAOpA6oDqwOsA60DrgOvA7ADsQOyA7MDtAO1A7YDtwO4A7kDugO7A8EDxgM2At0C3gPRA9ID0wPUA9UD1gPXA9gD2QPaA9sD3APdA94D3wPgA+ED4gPjA+QD5QPmA+cD6APpA+oD6wPsA+0D7gPvA/AD8QPyA/MD9AP1A/YD9wP4A/kD+gP7A/wD/QP+A/8EAAQBBAIEAwQEBAUEBgQHBAgECQQKBAsEDAQNBA4EDwQQBBEEEgQTBBQEFQQWBBcEGAQZBBoEGwQcBB0EHgQfBCAEIQQiBCMEJAQlBCYEJwQoBCkEKgQrBCwELQQuBC8EMAQxBDIEMwQ0BDUENgQ3BDgEOQQ6BDsEPAQ9BD4EPwRABEEEQgRDBEQERQRGBEcESARJBEoESwRMBE0ETgRPBFAEUQRSBFMEVARVBFYEVwRYBFkEWgRbBFwEXQReBF8EYARhBGIEYwTjBOUE5gTnBOgE6QTrBOoE7QTuBO8E8ATyBPME9AT1BPYE9wT4BN8E4AT5BPoE+wT8BP0E/gT/BQAFAQUCBQMFBAUFBZoFlQV9BZQFnAWdBZ4FgAWBBaEFhQWGBYcFowWlBaYFigWLBYwFjQWpBaoFqwWQBawFkQWSBZMFrQWuBa8FsAWxBbIFswW0BbUFtgW3BbgFuQX8Bf0F/gX/BgAGAQYCBgMGBAYFBjYGOAZgBmEGZgZnBmgGaQZwBjkGQgZDBkQGRQZGBkcGTwZQBlEGagZrBmwGbQZuBm8GuQa6BrsGvAbcBt4G3QcKBwsHDAcNBw4HDwcQBxEHEgcTBxQHFQcWBxcHGAcZBxoHGwccBx0HHgcfByAHIQciByMHJAdWByYHZgdnB2gHaQdqB2sHbAdtAAIAXgAgACgAAAAqAC4ACQBHAEgADgBSAFcAEABqAG0AFgBvAHYAGgCFAKgAIgCqALcARgC5AL4AVADfAN8AWgDlAOUAWwGmAbMAXAHNAc4AagHQAd0AbAHfAe4AegHxAfUAigH/AgIAjwIEAgsAkwINAi0AmwIvAj8AvAJBAkYAzQJQAmgA0wJuAm4A7AJzAnMA7QJ+An4A7gLbAtwA7wLfAvoA8QMJAyEBDQMkAywBJgMzAzsBLwM9A0YBOANRA1EBQgNUA18BQwOFA4UBTwObA7oBUAO8A8ABcAPCA9ABdQRmBGYBhARtBG8BhQRyBHUBiAR9BH0BjAR/BIEBjQSJBI0BkASTBJMBlQSYBJgBlgScBJwBlwSfBJ8BmASqBKoBmQS8BL8BmgTFBMYBngTLBM0BoATQBNABowTWBNYBpATYBNgBpQUGBQgBpgUKBQoBqQUNBREBqgUVBRYBrwUYBRgBsQUaBRoBsgUdBR0BswUgBSEBtAUkBScBtgUrBS0BugU1BTUBvQU4BTgBvgU8BTwBvwU/BT8BwAVJBUkBwQVdBWIBwgVmBWcByAVsBW4BygVxBXEBzQV5BXkBzgYGBg8BzwYlBiUB2QYnBicB2gYrBiwB2wYuBjIB3QY7BkEB4gZIBkkB6QZMBkwB6wZWBlsB7AavBq8B8gaxBrEB8wazBrMB9Aa1BrUB9QbKBssB9gbYBtgB+AbfBuoB+QbsBu8CBQbyBvwCCQcHBwgCFAdeB2UCFgADAAAAAQAIAAEJtAEyAmoCcgJ4An4ChAKKApAClgKcAqICqAKuArQCugLAAsYCzALSAtgC3gLkAuoC8AL2AvwDAgMIAw4DFAMaAyADJgMsAzIDOAM+A0QDSgNQA1YDXANiA2gDbgN0A3oDgAOGA4wDkgOYA54DpAOqA7ADtgO8A8IDyAPOA9QD2gPgA+YD7APyA/gD/gQEBAoEEAQWBBwEIgQoBC4ENAQ6BEAERgRMBFIEWAReBGQEagRwBHYEfASCBIgEjgSUBJoHdgSgBKYErASyBLgEvgTEBMwE0gTYBN4E5ATqBPAE9gT8BQIFCAUOBRQFGgUgBSYFLAUyBTgFPgVEBUoFUAVWBVwFYgVoBW4FdAV6BYAFhgWMBZIFmAWeBaQFqgWwBbYFvAXCBcgFzgXUBdoF4AXmBewF9AX6BgAGBgYMBhIGGAYeBiQGKgYwBjYGPAZCBkgGTgZUBloGYAZmBmwGcgZ4Bn4GhAaKBpAGlgacBqIGqAauBrQGugbABsYGzAbSBtgG3gbkBuoG8Ab2BvwHAgcIBw4HFAcaByAHJgcsBzIHOgdAB0YHTAdSB1gHXgdkB2oHcAd2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AQIBAwEEAQUBBgEHAQgBCQEKAQsBDAENAQ4BDwEQAREBEgETARQBFQEWARcBGAEZARoBGwEcAR0BHgEfASABIQEiASMBJAElASYBJwEoASkBKgErASwBLQEuAS8BMAExATIBMwE0ATUBNgE4ATkBOgE7ATwBPQE+AT8BQAFBAUIBQwFEAUUBRgFHAUgBSQFKAUsBTAFNAU4BTwFQAVEBUgFTAVQBVQFWAVcBWAFZAVoBWwFcAV0BXgFfAWABYQFiAWMBZAFlAWYBZwFoAWkBagFrAWwBbQFuAW8BcAFxAXIBcwF0AXUBdgF3AXgBeQF6AXsBfAF9AX4BfwGAAYEBggGDAYQBhQGGAYcBiAGJATcCfwKAAoECggKDAoQChQKGAocCiAKJAooCiwKMAo0CjgKPApACkQKSApMClAKVApYClwKYApkCmgKbApwCnQKeAp8CoAKhAqICowKkAqUCpgKnAqgCqQKqAqsCrAKtAq4CrwKwArECsgKzArQCtQK2ArcCuAK5AroCuwK8Ar0CvgK/AsACwQLCAsMCxALFAsYCxwLIAskCygLLAswCzQLOAs8C0ALRAtIC0wLUAtUC1gLXAtgC2QLdAt4D0QPSA9MD1APVA9YD1wPYA9kD2gPbA9wD3QPeA98D4APhA+ID4wPkA+UD5gPnA+gD6QPqA+sD7APtA+4D7wPwA/ED8gPzA/QD9QP2A/cD+AP5A/oD+wP8A/0D/gP/BAAEAQQCBAMEBAQFBAYEBwQIBAkECgQLBAwEDQQOBA8EEAQRBBIEEwQUBBUEFgQXBBgEGQQaBBsEHAQdBB4EHwQgBCEEIgQjBCQEJQQmBCcEKAQpBCoEKwQsBC0ELgQvBDAEMQQyBDMENAQ1BDYENwQ4BDkEOgQ7BDwEPQQ+BD8EQARBBEIEQwREBEUERgRHBEgESQRKBEsETARNBE4ETwRQBFEEUgRTBFQEVQRWBFcEWARZBFoEWwRcBF0EXgRfBGAEYQRiBGME4wTkBOUE5gTnBOgE6QTrBOoE7ATtBO4E7wTwBPEE8gTzBPQE9QT2BPcE+AT5BPoE+wT8BP0E/gT/BQAFAQUCBQMFBAUFBZoFmwWcBZ0FngWfBaAFogWhBaMFpAWlBaYFpwWoBakFqgWrBawFrQWuBa8FsAWxBbIFswW0BbUFtgW3BbgFuQbdAAIAPQAEAB8AAAApACkAHAAvAEYAHQBJAFEANQBYAGkAPgBuAG4AUAB3AIMAUQCpAKkAXgC/AN4AXwDgAOQAfwDmAPUAhAGKAaUAlAG0AcwAsAHPAc8AyQH2Af4AygIuAi4A0wJIAk8A1AJpAm0A3AJvAnIA4QJ0An0A5QLbAtwA7wLfAvoA8QMJAyEBDQMkAywBJgMzAzsBLwM9A0YBOANRA1EBQgNUA18BQwOFA4UBTwObA7oBUAO8A8ABcAPCA9ABdQRmBGYBhARsBG8BhQRyBHUBiQR4BHgBjQR9BH0BjgR/BIIBjwSJBI0BkwSTBJMBmASYBJgBmQSqBKoBmgS8BL8BmwTFBMYBnwTLBM0BoQTQBNABpATWBNYBpQTYBNgBpgUGBQYBpwUMBQ8BqAUSBRUBrAUdBR0BsAUfBSEBsQUpBS0BtAU4BTgBuQVdBWIBugVmBWcBwAVsBW4BwgVxBXEBxQV5BXkBxgbYBtgBxwABAAAAAQAIAAIAWAApAd8B8AY7BwoHCwcMBw0HDgcPBxAHEQcSBxMHFAcVBxYHFwcYBxkHGgcbBxwHHQceBx8HIAchByIHIwckByUHJgcnB2YHZwdoB2kHagdrB2wHbQACAAkB3gHeAAAB7wHvAAEGJgYmAAIG3wbqAAMG7AbvAA8G8gb8ABMHBgcGAB4HCAcJAB8HXgdlACEAAQAAAAEACAACACQADwRkBGUEZARlBfwF/QX+Bf8GAAYBBgIGAwYEBgUGOQABAA8ABACEAYoCDAYGBgcGCAYJBgoGCwYMBg0GDgYPBiYAAA==) format("truetype")}@font-face{font-weight:normal;font-family:"tick42-icons";font-style:normal;src:url(data:font/ttf;base64,AAEAAAALAIAAAwAwT1MvMg8SD3sAAAC8AAAAYGNtYXA/nv/uAAABHAAAAlRnYXNwAAAAEAAAA3AAAAAIZ2x5ZkklW9MAAAN4AADaJGhlYWQmySqNAADdnAAAADZoaGVhCMAF2QAA3dQAAAAkaG10eFcJ/90AAN34AAAD3GxvY2EHgjxgAADh1AAAAfBtYXhwAQcC0AAA48QAAAAgbmFtZTlR2rEAAOPkAAABwnBvc3QAAwAAAADlqAAAACAAAwN9AZAABQAAApkCzAAAAI8CmQLMAAAB6wAzAQkAAAAAAAAAAAAAAAAAAAABEAAAAAAAAAAAAAAAAAAAAABAAADy1APA/8AAQAPAAEAAAAABAAAAAAAAAAAAAAAgAAAAAAADAAAAAwAAABwAAQADAAAAHAADAAEAAAAcAAQCOAAAAIoAgAAGAAoAAQAg6CroOehF6FDoYuiL6QjwR/CO8JfwsPCy8MXwyfDO8N7w4PDo8Orw7vDz8Pbw/vEH8QnxDvES8RXxIvEk8SrxMfEz8T7xQvFG8UrxTPFT8VXxW/Fe8WPxePGz8cnx2/He8eDx6/H38fnx/vIB8gXyNfJN8lPydPKS8qjyt/K68sDy1P/9//8AAAAAACDoAOg56DvoR+hW6GTpAPBH8I7wlvCw8LLwxfDJ8M7w2/Dg8Ojw6vDs8PLw9vD+8QDxCfEM8RDxFPEg8STxJvEw8TPxPvFB8UbxSvFM8VLxVfFb8V3xYPF18bLxwPHb8d7x4PHr8fbx+fH+8gHyBPI08k3yUPJx8pLyqPK38rrywPLQ//3//wAB/+MYBBf2F/UX9BfvF+4XehA8D/YP7w/XD9YPxA/BD70PsQ+wD6kPqA+nD6QPog+bD5oPmQ+XD5YPlQ+LD4oPiQ+ED4MPeQ93D3QPcQ9wD2sPag9lD2QPYw9SDxkPDQ78DvoO+Q7vDuUO5A7gDt4O3A6uDpcOlQ54DlsORg44DjYOMQ4iAAMAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAH//wAPAAEAAP/AAAADwAACAAA3OQEAAAAAAQAA/8AAAAPAAAIAADc5AQAAAAABAAD/wAAAA8AAAgAANzkBAAAAAAMAAP/ABAADwAA8AIEAuAAAJREOAQcjBgcOAQcOAQ8BDgEjKgEjMSMiJicXLgEnMS4BJyYnLgEnMREUFhcxHgEzMDI5ASEyNjcxPgE9ARE1JzAmIwYmIyEiBgcxDgEHMR4BFxUeARceARcjHwEeARceATM6ATcxMjY3Iz4BNzE3PgE3MT4BNzE+ATc+AT8BPgE1MTcRFDAxFAYHMQ4BIzEhIiYnMS4BNTA0NTERMDQxNDY3MT4BMzoBOQEhMDIzMhYXMR4BFTAUOQEDtwkUCgGYWw8XCQsYDAIMGw8BAwEBEB4NAQ4ZCwgXD1qaCxUJAwMCBgMBA0oEBgIDAwMBBAQBA/y0BAYCAgMBAS0mOHE6BgoFARoaCA4GBQsGAQQBBwwGAQkOBhoHDQUFDAc8cjcRHAwBCw1JDg0MIRP8thMhDA0ODg0MIBIBAQNKAQESIAwNDooBtgoSCXVLDRIHBw4HAQYHBwcBBg8ICBMLS3UIEwr+SgQHAwIDAwIDBwMBAlgdBQQBAQQCAwYEMlMbAStZMAQJBBUSBQgDAwMBAgMDCAUSBAsGBQkDMFkrDiARAREnFhX9kwETIAwNDw8NCyESAQECbQESIQwMDw8MDCESAQAAAAMAAP/AA/cDwAATACcAPwAAJTU0JyYrASIHBh0BFBcWFzMyNzYnEzQnJisBIgcGFRMUFxY3MzI3NgMBFgcGBwYHISInJicmNwE2NzYzMhcWFwJJBQYHbgcGBQUGB24HBgUBCgUHCHwHCAUJBgcHaQgHBggBthQVCRIRE/ySExESCRUUAbgJERITExIRC4ptCAUFBQUIbQgFBQEGBtwBBwcEBgYECf77BQQEAQMDAh382yQkEQkKAQsKECQkAyURCgsLChEAAAAABP///8ADtwPAAAQADwAfAFAAADchNSEVESE1IyInJj0BIREFNCcmJyYHBgcGFxY3Njc2NxUUBwYHIxUUBwYjISInJic1IyInJjc1NDc2FzMRNDc2MyEyFxYfARYXFgcVMzIXFtsCAP4AAgBcFhAR/pMCkgoKERAJCgEBDAsODg0MSAYHBoAQEBf92xYQDwGABwYHASEhLCUQERUBgBgbHA9XEAwMASQuICBSk5MBbtsREBZc/pIlDwsKAQEMDQ0NDA0CAgkIEe0IBQUBWxcQEBAQF1sGBgftLSEhAQE3FxAQDAwPVxAcGxeSICAAAAAABAAA/8AESQPAABAAFwAsAEEAAAEUBwYHBicmNTQ3NhcWFxYVBREhNTcXASUhIgcGBxEUFxY3ITI3NicRNCcmIxcRFAcGByEiJyY3ETQ3NjchMhcWFQFuICAuLiAfHyAuLiAgAkn83LZcASQBJfxtBwUFAQYGBgOTBwYGAQUFCFsbGib8bSUbHAEbGiYDkyYaGwJ3LiAfAQEhIiwsIiICAh4eMNz/AG63WwEkpQYFCP1KBwYHAQYFCAK2CAUGE/1KJhsaARscJQK2JhsaARscJQAAAAADAAD/wANuA8AADwBZAJMAADc0JyYnJgcGFRQXFjc2NzYBNCcmJyM0NzYnNCcmJwYHBgcGBwYHBgcGBwYHBgcGBwYHBicjETMyFxYXFhcWFxYXFhcWOwEyNTQnNjc2NTQnNjU0JyYnNjc2NTcUBxYVFAcWFRQHFAcGKwEiJyYnJisBIicmNRE0NzY7ATY3Njc2NzY3Njc2MzIXFhcWFRQHMzIXFgeTDAsODwsLCwsPDgsMApIWFx3IGxwBERI4DwcHCgoYDR8CCwwHBwwMCwoMDQoKChMTBwsLCAcODgcGDg4CeUtFbQIRCgoKHgYFCRINDEkcBRUBIjExUEo3NTZGQwylHhUWFhUenRQ6IR0NBgYMCxkWHTAmJhQVHGQ8LCwBnA8KCgIBDQwNDgwMAQEKCgFYHhYVASE6OyA5GhsBDyIiJiYYDicDDQ0LCg4ODAsICAgHAf6TAQEDAwMEBAQCAgQqXxAQCRYVFRQTHCgPEREKARkaFAEzKhIVLCcMDDosTy8uDg0YFxYVHgFtHxYVDUsrHw4jIyUlGBYTEigoQzQ5Kys8AAAAAwAA/8ADbgPAAA8AWwCYAAATNCcmJyYHBhUUFxY3Njc2ATQnJiM2NzYnNCc2NTQnJic2NTQnJisBIgcGBwYHBgcGBwYHBicjETMyFxYXFhcWFxYXFhcWFxYXFhcWFxYXMjc2JzQnJiczMjc2NRcUBwYnIxYVFAcGBwYjIicmJyYnJicmJyYnJicjIicmNRE0NzY7ATI3Njc2NzMyFxYdARYVFAcWFRQHFhWTDAsODwsLCwsPDgsMApIMDBMIBgcBHgoKChECGxwySUt5Aw0NBwgNDQgJCgoIExMJCwwLCwsMCwsICAsKAx8NGAoKBwcPNxMSARsaAcgdFxZJKys9ZBwVEycnLx0WFAsLAwQHBwocIjoUnR4VFhYVHqUMQ0k3NjtBUDExIgEVBRwC5BAKCgEBDAwODQwNAQIKCv7HExsaCxERDyccEhUWFBUKEBAwFxgqAQQEAwMFBAICAgIB/pMFBgoKCgsPDwkKDQ0EJw4YJiYiIg8cGzghOjkiFhcdATssLAE4NUQnKBITFhIcHBgZFxgNHSxLDRUWHwFtHhUWFxkMDQEtLU8DLDoMDCcrFhIqMwAAAAAC////wAKSA8AACwAqAAATITU0JyYHBgcGFxUFERQHBgchIicmJxE0NzYXMzU0NzYzMhcWBxUzMhcWtwEjKys8PCsrAQHbERAX/d0YDxABERAXEUxMaGhNTQISGA8QAeRuPSsrAQEpKT9uNv62Fw8PARAQFgFKFhARAW5pTEtLTGluEA8AAAAAAwAA/8ADbgPAABgCcwLNAAABMhcWFxYVFAcGBwYjIicmJyYnJjc2NzYzEwYHBgcyNzY3NjU2NzY3NhcmNzY3Njc2PwEGJyY1FAc0JyYHBjUmJyYnJjUmJyYnJicmNTQnJjEwBwYVFAcmIyIVFCMiFQYjIgc2JyYjNicmJzMmJyYnJicmJyYHBhUUFxYVFgcGFxQXFgcGBwYHBhcWFxYVFAcGIyIPAQYnJicmJyYHJicmBzInJgc2NzYjNjc2NzY3NicWNzY3Njc2MzIXFjMWNTQnMicmJyYHBhciBwYHBicwJyYnIgc2JyYjNicmIyIHBgcGFxYXFjMyFxYHIgcGIyIHBhcWByYnJicWJyMiBwYjIicmNzQXJicmJwYHMjc2NzYxNhc3FhcmBwYHFgcmJyYnJiciBwYHFjMWFxYVFDcWBzIXFhcWByYnJgcGFxYzIgcGBwYfAQYXFjcGFxYXFhcWFxYXFhcWFwYXFgciBwY1FhcWFxYVFBcWNzYnJicmJyY1MjMyFxYXFjEGFxYXFhcWMxYXFgcyFxYXFhcWFxYXFh8BMRcWFxYXFjMyNzY3NhcWFxY3IhcWFxYXFhUWFxYXNjUGFxYzNjUGJzAnJjU0JyY3NhcyNzYnJjUmJyYnBicmJxQHBhUiIzY1NDc2NzY3NicmJyYHIgcGBwYHBgcGJyYnJicmNTQ3Njc2JzY3Njc2MzIzMjU0NzQnJiMWNzYXFjc0JyY3FjcWFxYzFhcWFxY3NjcWFxYXFjc2NzYnJjUnNSYnJjc2NzQ3Njc2NzYnMjcwJyYjIjc2JzY3NjMWNzYnNjc2NxY3NicmNzY3NhU3NiMWNzYnNicmJzIzMjU2JyYHAzY3JiMiJyYnNicmJyYnJicmJyYnJicmJyYPASIHBgcGMTAVJiciJyYnJgcGBwYHBhUmNzYnJgcGBwYHBjc2BwYVBgcGFSYnJjcWFxYXFgcGBwYXFAcGFxQXAbh2ZmU6Ozs6ZWZ2d2dmODkDAz8+YGF9nAIEBAMBAQECAgMJCRUUCgEGBgICBgYEAQgDAwQCAgUFBQMDAwIBBAQBAQEBAwMEBAICAgIDBAEDAwIICQUEBgEBBAMBBAQGBgEGDg4EAwICAQQEAQcHAQIHCAIDAgIFAQIDAQEDAQcFBQIEBQ4DAxQPEwQEBAYBAQEBAgUBAwMCAgEUCQIEBAIFAwMFBgMIBAcFAgMGCgQGAQUFBAQFAwMCBgQBBwcHCw8ECAkDAgEBBAQCAgUEAQgDAQQEAgMCAQEBAgMCAgIEEgUDBgcGBgEDAwICBAQCGhsDAwMFBRMGAwcEBA0MAQQCAgQEBAQECQVSNAQDAwEBBgUDARgLAQIHAgQEAQICAgQEAQEBAQEBAgUFCAgTAwECBQUEBAEDBAQEAgcHAQEBAQIHBwEBAwICAhAIAQICAgECAgMDAQEBAgIFBgUFAQQEBAQFBgYFAwEBAgEEBAMJBwMIBwUGAwMFBQMJCAgEFQoBAgICAgMDAwcIAwQBBQUFCBEKAgIBAgIBAQUBAQICAQYFAgMGBgMBAQcBAQIBAgIDAwEBAgIHDAQBAQEBAQQECgoECAUFAQEBAQQCAwMCAgEBAgIBAgEBBA0MAwkDAQEBAw4CBwcCAgICAQECAgQFAgYEBAICAQEBAQEIAgICAgcEBAUGAgwEBAICAgMDAQUEAwEBAwUHBQQCCgkBBAEBAQEDAgcHCgICCggFCQIDAwYCBQUJDAoPXXZSAQYHAQoDAQICAwMEBAIBAwQBAQMDAgIDAgIBAQICDAkDAwMDAwMDAwMBAQQEBAMBBQYBAQYGAQEFBQICAgEGBwIBAQECBAwPAQIJBQUBAgN3OztlZHh4ZGU7Ozs7ZWR4eGRlOzv+1gEEBAIDAwMDAQQFBAMFCwEGBgEBAgICDAEFBgcCAwQBAQICAQIDAwYGAgMDAwQBAgICAgEBAwMCAgEBAQICAgEDBAICBAQEAgMDAgIBAwICAQQCAgYGAQMEBAMFBQUHBAUFAQUHBgMBAQECAgIBAwYGCQ8DBAUHCAUDCAoCAwcHCAUBBAQEAwEDCQMGBgQDAwMBBwcFCgQBAgUCAgYHBAQHCAcBCQUEBAcIAwIEAwMBAQICAgYCAgICBAUFAwMHCAIGAwIBBgQHAgECAwMCCA8BAQMDBwMCCQUDAgMFBgQCBAQCAwEBL1AFAQQEAgIDBAYPCwIGBAEEBAIDBwcJCgsLAgEGDg0CARcFAQEDAwMDAgMKCwMDCAgFAQEBBAQEBAIEBAICAQsZDQMCBwYCAgIBAQUGBgQEBwcECAcBBQUGBQsKAwQEBAEFAwIEBQMCAQEBAQkJAwoEBAQGBQMDAgMFBQMCAwUGBwMQCBIDAwICAgIEAwICAgUFAwQHBwEFAQEEAQICAgIJCAUCBAQFBQICAwQCDAIEBAICAgIBAQIEDA0IBgkJBQYJAQQEAgEBAQIBAQEBAgIDBgcBBQYCEAoBAgIBAgIBAQEBAwgFGAICAQEEBQQEAwUOAgUGBQUFAQEBAwMBCwoFAgICAgYCBQUGBQYEBAICAwECAgUFAgIDAwEIAgEHBgUEAQEDAQUEAwr+CxVXAgIEAQQDBAICAwMBAQICAQEBAQEBAgEBAQEBAgoDAwMBAQEBAgMGBgEDBwcDAwEBAQEEBAEBBAQBAgQEAgIBAQIFDw4IEgkOCQ0CBAgIBAMGAAAAD////8ADtwPAAAQACAANABEAFgAaAB4AIgAmADoAPgBCAEYAWgCHAAA3MzUjFTsBNSMnMzUjFTsBNSMnMzUjFQEzNSMDMzUjATM1IyczNSMDNTQnJicjIgcGBxUUFxY3MzI3NgEzNSMnMzUjFzM1Izc1NCcmJyMiBwYXFRQXFjczMjc2NxEUBwYjISInJjURNDc2OwE1NDc2OwEyFxYdATM1NDc2OwEyFxYHFTMyFxYXSKWlyra2yqWlyra2yqWlAaW3t9u2tgG2paXbt7fJBgYGJQcFBQIHBgYlBwUFAaWlpdu3t9ulpRIFBQgkBwYGAQUFCCQIBQXdFxYd/NseFRYWFR5KGhsmJSYaG9scGyUkJhwbAUkeFRYBCaWlpSS3t7clpKT+W6UBAKT9t6UktwE3pQcFBQEGBgalBwYGAQUF/hq3JaSkpG6lBwUFAQYGBqUHBgYBBQUt/SQeFRYWFR4C3B4VFjcmGhsbGiY3NyYaGxsaJjcWFR4AAAACAAD/wAJJA8AAEAAmAAABNCcmIyIHBhUUFxYzMjc2NTMUBwMGBwYjIicmJwMmNTQ3NjMyFxYBtysrPDwrKysrPDwrK5ITzwoSExMTFBMI0BNWVnl5VlYCUj0rKysrPTwrKysrPD4o/kYTCwsLCxMBuig+eVZWVlYAAAAABAAA/8AEAAPAAAQAHQAhADkAAAEhNSEVAREUBwYjISInJjcRIRUUFxYXMzI3Njc1ISEVIzUBFSE1NDc2OwE1NDc2NyEyFxYHFTMyFxYBbgEk/twCkhsaJvy2JRscAQGACwwOthAKCgEBgP5JkgJJ/AAbGibKDxAXAUoWERAByiYaGwLkSkr+k/7tJhobGxomARNbEAoKAQsLD1tJSQES29smGxpbGA8QAREQF1saGwAC////wAO3A8AAMgBuAAABFRQHBiMhIicmNRE0NzY3MzIXFgcUBwYHBisBIgcGBxEUFxYXITI3Nj0BNDc2NzYXFhUTBwYjIicmPQEjIgcGFxYHBiMiJyYnJicmJyYnJic0NzY3Njc2NzY3Njc2NzY3NjczNTQ3NjMyHwEWFRQDJDAwRf4lRDEwMDFEkgcGBgEPLCAFBEAmGhsBHBslAdsmGxoLEA8JCwyH2woPCAcWW7pBRBoCDQYCCQUGBgYREAwNCQkBAgIGBgkKEhIVFCEhJyc0ND1bFgcIDgvbDAFClEUwMDAwRQHbRDAwAQYGBhADDxQCGhsm/iUmGhsBHBslegsFBw8JBQULARvbCwMJGW1LTsANBgEHCAkJHx8ZGigoHhsZGBsbFxgWFxQVDg4ODQQEAm4YCgML3AoPEAAAAAEAAP/AAgADwAAOAAABFhUUBwEGJyY1ETQ3NhcB8g4O/kkYEhEREhgB2gsQDgv+8BAKCh8CDh8KChAAAAEAAP/AAmYDwAANAAABMhURFCMhIjURNDc2MwIaTEz+NE4SEykC80H+HkNDAeIlDg4AAAABAAD/wALNA8AADwAAATIXFhUUBwYjIicmNTQ3NgFmlmhpaWiVlmhpaWgDJmholpNqaWlqk5ZoaAAAAAACAAD/wAIfA8AACgAVAAABMhURFCMiNRE0MyEyFREUIyI1ETQzAcNcXFxc/plcXFxcAyZB/bhDQwJIQUH9uENDAkhBAAIAAP/AAmYDwAAOABkAAAEWFRQHBQYnJjURNDc2FyUyFREUIyI1ETQzAaYODv6NFw4ODg4XAedMTE1NAdgLDgwL6Q4JCRsBxBsJCQ4pO/4iOzsB3jsAAAACAAD/wAJmA8AADgAZAAATNDclNhcWFREUBwYnJSYnNDMyFREUIyI1EbIOAXUVDg4ODhX+iw6yTktLTgG/DgvpDgkJG/48GwkJDukL/Ds7/iI7OwHeAAAAAQAA/8ACqQPAABgAADciLwEmNzY3NhcWHwEBNjc2FxYXFgcBBiP/Ixa5EAQEFxYeHhJ5AS8QHBwaGQYGDv6ZFCVaHPIZHB0SEwQEGZ4B5hgGBw8QHBsb/cMhAAABAAD/wAHhA8AAJwAAARYVFAcGIyIvAQcGIyInJjU0PwEnJjU0NzYzMh8BNzYzMhcWFRQPAQHPEhITGRoSiIcSGhkTEBCOjhAQExkaEoeIEhoZExISjgEfEhoZExAQnJwQEBMZGhKgohIaGRMQEJycEBATGRoSogACAAD/wAOFA8AADgAdAAABFhUUBwUGJyY1ETQ3NhcHFhUUBwUGJyY1ETQ3NhcDdw4O/oMXDw8PDxdUDg7+jxQREBARFAHYCw4OCf4OCAkcAe4cCQgO/gsODgn+DggJHAHuHAkIDgAAAAIAAP/AA4UDwAAPAB8AABM0NyU2FxYVERQHBiclJjUhNDclNhcWFREUBwYnJSY1AA4BfxUQEBAQFf6BDgHRDgFxFBEQEBEU/o8OAb8OC/4OCAkc/hIcCQgO/gkODgv+DggJHP4SHAkIDv4JDgAAAAADAAD/wANuA8AAGAAsAEAAAAEyFxYXFhUUBwYHBiMiJyYnJicmNzY3NjMTNTQnJisBIgcGBxUUFxYXMzI3NicTNCcmKwEiBwYVExQXFjsBMjc2Abd3ZWY6Ozs6ZmV3dmdmOTgDAz4/YGB9SQUFB24IBQUBBgYHbgcFBQEKBgUIfggGBgsFBQlqCAUFA3c7O2VkeHhkZTs7OztlZHh4ZGU7O/04bAgFBgYFCGwJBQUBBgbMAWMHAwUFAwf+nQYEBAQEAAAAAwAA/8AD2wPAABAAJgBhAAAFNCMiJyY3NCMiFRQXFjcyNSUhJhE0JyYnJicmIyIHBgcGBwYVEAchFAcGIyEUBwYjIicmNSEiJyY1Njc2NzY3Njc2NzQ3NjcmNTQ3Njc2FxYVFAcWFxYXFBcWFxYXFhcWFwIJCSIYGQEJCR0eKQn+gwLomQ0NGxsqKjc3KiobGw0NmQNPFRYe/wArKzw8Kyv/AB4WFR0XGBgZEhMJCQJEQ2wFEBAXFxAQBW1CQwELCxIRGRgZGRoJCBkZIQoKKh0eAQmkrAEwHR8eHR0REhIRHR0eHx3+0KweFRY8KysrKzwWFR4ZGRorKzAwRkVPVktLEAoMFxAPAQEREhUMChBLS1ZQREUxMSoqGxoYAAAABf///8AEkgPAAAMABwANABEAFQAAAREjEQERIxEBFSERMxEBESMRJREjEQFtkwFukQLb+21JAtySAW2SAcD+2wElASX9tgJK/W1JA2782wIA/kkBt9z9bQKTAAABAAD/wAMlA8AAcAAAJRQHBgcGBwYjIicmJyYnJicmJyYnJicmJyYnJicmJyYnJicmNzQ3Njc2NzYzMhcWFxYXFhcWFxYXFhcWFRQHBgcGBwYHFBcWFxYXFjUWFxYXMhcWFxYXFjcyNzY3Njc2FzIXFhcWFxYXFhcWFxYXFhUDJQcGBgs7NTQPEA8REgkJFxYHNyxJTk8sHBMCCQgEBAQEAwMBHSAdDhkYEAgEChUGCgoLCgcCCAgEBREQFBMPEAEDAwEBBwgrODhOAQkKBQUGBgcLDw8QDxARDAcICQwMAg8QEBUUCycEAtcQGBkOHSEcAgIFBQMDCAgCFRwtTU5KLDcFGBgICBITDg8PNTU7CwYGBgIDKAsUFQ8QDwIMDQgICAsREBAPDxAKBQgIAwMMCwFPODgrBwYCAgMDARAREhMREQEEBAgIAggKCQsLBhQKBAgABAAA/8ADVgPAACcAPABEAFsAAAEyFxYXFgcGByMVFAcGIyInJj0BIyInJjU0NzYXMzU0NzYzMhcWHQElFhURFAcGIyEiJyYnETQ3NjchMhcXJxUUFxY7AQMyNzY1ESMiJyY3NSEiBwYXERQXFjMhAksVEA8BARESE2sQERUWDw9sFRAPDxAVbA8PFhUREAFmEC8vQv3qQy4uAS8vQgGrFhBkihcYITofFg8PTzcoKAH+ixYQEQEQDxcCFgHADxAWFw4OAWwXDw8PDxdsDw8WFREQAWoWEBEREBZq+xEU/etDLy8vL0MCgEIuLgEP+4k5IRcY/bQREBYB4CcnN1AQDxb9gBYQEQAABAAA/8ACZgPAAAsAFwAjAC8AABMyHQEUKwEiPQE0MyEyHQEUKwEiPQE0MwEyHQEUKwEiPQE0MyEyHQEUKwEiPQE0M65SUlxSUgHCUlJcUlL+9lJSXFJSAcJSUlxSUgLzUlxSUlxSUlxSUlxS/ppSXFJSXFJSXFJSXFIAAAEAAP/AAOEDwAAQAAATMhcWFRQHBiMiJyY1NDc2M3AwICEhIC8wICEhIDACMSEhLy0iIiIiLS8hIQAAAAIAAP/AAkgDwAAQACEAABMyFxYVFAcGIyInJjU0NzYzITIXFhUUBwYjIicmNTQ3NjNxLyEgICEvLyEhISEvAWYvISEiIi0vISAgIS8CMSEhLy0iIiEhLy8hISEhLy0iIiEhLy8hIQAAAwAA/8ADrgPAABAAIQAyAAATMhcWFRQHBiMiJyY1NDc2MyEyFxYVFAcGIyInJjU0NzYzITIXFhUUBwYjIicmNTQ3NjNxLyAhISAvMCAhISAwAWYvISEiIi0tIiIhIS8BZjAgISEgMC8gISEgLwIxISEvLSIiIiItLyEhISEvLSIiIiItLyEhISEvLSIiIiItLyEhAAIAAP/AAysDwAAGAA0AAAEhEScHJzcBFwcXIREXAecBRGaWZpv+mGabff68ZgNU/r1/nGeV/p5nlWYBQ30AAAACAAD/wAOaA8AABgANAAA3JyERJwcnAQcXIREXN6BtATBnlWcDmp5r/tNmk+9n/tBtoGcCzJNmAS1rngACAAD/wAQAA8AAEAAiAAABMhYVERQGIyEiJjURNDYzITUhIgYVERQWMyEyNjURNCYjMQNVJjAwJv1WJjAwJgKq/VZHZGRHAqpHZGRHA2swJv1WJjAwJgKqJjBVZEf9VkdkZEcCqkdkAAIAAP/AA24DwAAsAEQAAAE0LwE3NjU0LwEmIyIPAScmIyIPAQYVFB8BBwYVFB8BFjMyPwEXFjMyPwE2NTcUBwYHBiMiJyYnJicmNzY3NjMyFxYXFgKQCmdnCgo0ChAPCmhnCw8QCjQLC2hoCws0ChAPC2doCg8QCjQK3js6ZmV3dmdmOTgDAz4/YGB9fV9gQEEBPw4MZ2cMDg8MMwsLaGgLCzMMDw4MZ2cMDg8MMwsLaGgLCzMMD4F4ZGU7Ozs7ZWR4eGRlOzs7O2VkAAQAAP/ABAADwAAQABQAGAAcAAABISIGFREUFjMhMjY1ETQmIwERIREpAREhNSE1IQPT/FoTGhoTA6YTGhoT/G4BnwHh/oABgPyAA4ADwBoT/FoTGhoTA6YTGvw/AoL9fgKCP8EAAAAAAgAA/8AEAAPAAAUAMQAAEyEBEQEjJTQ/AScmNTQ/ATYzMh8BNzYzMh8BFhUUDwEXFhUUDwEGIyIvAQcGIyIvASYAATgBYv6e6gKMAk5OAgI2AgQDA05OBAMCAzgCAk5OAgI4AgMEA05OAgMDBDYCAo0BIfwkAR58BAJNTgIEBQI2AgJOTgICNgIFBAJOTQQEAwI3AgJQUAICNwIAAwAA/8AEAAPAAAUADwAZAAA3ETMBEQElNjU0JzcWFxQHFzY1NCc3FhUUBwDyAWr+lgGqSkpIbAJuMH5+Tp6e6wGqASj8BgEoJExoaU1MbJiUaDB6tLR+TJ7f354AAAAAAwAA/8AEAAPAACAANQBKAAA3ETQ3Njc2FxYHEQYHBicmNxE0JyYnJgcGFREGBwYnJjcXETQ3NjczMhcWFREUBwYrASInJjchETQ3NjczMhcWFREUBwYrASInJjcAl5bT05eYAgQgIB4fAXBvoaFvcAQgIB4fAcEICA9ADgkKCgkOQA4JCgICAAgID0AOCQoKCQ5ADgkKAqABANSWlQEBl5jS/wAqDQ0SEx8BAKBwbwEBcXKe/wAqDQ0SEx+hAUEOCQgBCQoN/r8NCQkJCQ0BQQ4JCAEJCg3+vw0JCQkJDQAJ//3/vgQDA8IAEwA5AE0AcAB9AIoAmQCnALUAAAEhIgYVERQWMyE1IREhETMRNCYjAzc+AScuASclJgYHDgEXEx4BFxY2PwEXHgEzMjY/AT4BNTQmLwEXJy4BIyIGDwEnFwcOARUUFh8BBwEOARUUFx4BFxYzMjY3NiYnJgYHDgEjIiY1NDY3PgEnLgEHBxQWMzI2NTQmIyIGFTcyFhUUBiMiJjU0NjM3ITI2NTQmIyEiBhUUFjMXMzI2NTQmKwEiBhUUFgEzMjY1NCYrASIGFRQWA9P8VxMaGhMByv5JA4Q/HBFtNwcFAgIOB/7zBxEFBAcCBgMKCgcSBzmQBQsHBwsEagQFBQSUDo4HCwcFDAYmA7onBQQEBY05/bxNYBMUQiwsM0BxIgcIDAwaBxdWL0toRjoNDgUDGAwdOCkoNzcoKThhCxQRDg0UFA22ATAOEhIO/tAPEREPYNAOEhIO0A4TE/430A8SEg/QDhISA8IaFPxbFBk8A4T+BgIMFBr9IjQHDwoKCgMVAwQFBBIG/vIJCwUDBAYzjQUFBQVmBQ0FBA4EidaKBQUFBSO5EiQFDAYHCgWDOgMKGIBSMiwtQRQTQzcMGQcICAwpMWlKPF4TBRcODAwF7SY6NykpNzcpIBEPDxERDw8RhBEPDhERDg8RkRIODxERDw4S/koRDw8REQ8PEQAAAgAA/8ADbgPAABMAJwAAAREUBwYjISInJicRNDc2MyEyFxYFERQHBiMhIicmJxE0NzYzITIXFgNuCgsQ/twPCwoBCwwOASQPDAv9/woLEP7cDwsKAQsMDgEkDwwLA1L83A8LCwsLDwMkDwsLCwsP/NwPCwsLCw8DJA8LCwsLAAAEAAD/wAQAA8AABQAPABkAJwAAExEzARElJTY1NCc3FhcUBxc2NTQnNxYVFAcXNjU0JzcWFxYVFAcGBwDQATr+xgFxPz89XAJeKmxsRIaGIpaWQFQvLy8vVAEHAXABAPyS/iFBWlpCQlyEgFoqa5ubbUCIv76LIpbU1JZCVG5venpwcVIAAAAAAgAA/8ADWAPAAAYAEAAANxEzAREBIyU2NTQnNxYXFAcA8gFu/pLyAqBLS0pqBG7qAawBKvwAASomTGZrTUxsmpNpAAAGAAD/wAMkA8AAEwAnADsASwBTAH8AAAERFAcGKwEiJyY1ETQ3NjsBMhcWFxEUBwYrASInJjURNDc2OwEyFxYXERQHBisBIicmNRE0NzY7ATIXFhMRIREUFxYXFjMhMjc2NzYBIScmJyMGBwUVFAcGKwERFAcGIyEiJyYnESMiJyY9ATQ3NjsBNzY3NjczMhcWHwEzMhcWASQFBQglCAUFBQUIJQgFBZMFBQkkCQUFBQUJJAkFBZEFBQclCAUFBQUIJQcFBUr+AAQEBAQCAdwCBAQEBP6AAQAcBAW1BgQB9gUFCDcbGyX+JCUbGwE2CAUFBQUIsCgJFxYXthgVFgkosQgFBQIb/rcIBQUFBQgBSQgFBgYFCP63CAUFBQUIAUkIBQYGBQj+twgFBQUFCAFJCAUGBgX+WgIe/eIMCgoFBgYFCgoCdEIGAQEGVSQJBQX94i8iIyEiLwIgBQUJJAkFBV8WDg4BDw8VXwUFAAAAAAIAAP/AA2cDwAAfAD8AAAERFAcGJyYvAQcGIyIvASY1ND8BJyY1NDc2MyEyFxYVARQPARcWFRQHBiMhIicmNxE0NzYXFh8BNzYzMh8BFhUBuAwLDg8LU70FCQgEQQcHvVILCwsPAQAOCwwBrwe9UgsLCw//AA4LDAIKCg8QClO9BggHBkAHAZv/AA4LDAEBClK+BQVCBgcHBr5SCw4ODAsLDA4BgAcFv1ILDg4MCwsMDgEADgsMAQEKUb0FBUIFCAAAAAACAAD/wANuA8AAHwA+AAABFA8BFxYVFAcGByEiJyYnETQ3Njc2HwE3NjMyHwEWFQERFAcGBwYvAQcGIyIvASY1ND8BJyY1NDc2NyEyFxYBrwW9UgoKCw//AA8LCgELDA4ODFK+BQcHB0EFAb8KCxARCVK9BgcIBkEFBb5TCgoLDwEADwwLAWUHBr5TCg8QCgoBCwsPAQAPCgoBAQxSvgYGQQYHAe3/AA8KCgEBDFK+BgZCBQcHBr5TCg8QCgoBCwsAAAAAAwAA/8ADbgPAABgAHwAqAAABFhcWFREUBwYHISInJicRNDc2NyEyFxYXBxUzJi8BJhMRIyInJic1IREhA0cQDAsQDxf9ABgPEAEREBcCABYcGxBM1wUHtAbL7RgPEAH+SQLcAucQGxsY/W4XEA8BEBEWA5IXEA8BCwwQJ9cSBrMH/JwCSREQFu78kgACAAD/vgQAA8IAOAEiAAABMDQ1NCYnMS4BIyIGIzEiJiMiBgcxDgEVOAE5ARwBFRQWFzEeATMwMjkBMDIzMjY3MT4BNTwBNTElFRQGBzEOAQcxBw4BBzceARceARUxFAYHMQ4BBzEOASciJicxJw4BByMOAQcOASMqATkBIzgBMSImJzEuATUxJy4BJxcHDgEjOAE5ASIwMSImJzEuAS8BLgE1NDA5ATQ2NzE+ATc+ATcuAS8CLgEnMS4BJz0BNDY3MT4BNzE3PgE3By4BJy4BNTE0NjcxPgE3MT4BMzIWFzEXPgE3Mz4BNwc+ATM6ATkBMzIWFzEeARcxFx4BFyc3PgEzOAEzMTIWFzEeAR8BHgEVMBQ5ATgBMRQGBzUHDgEHHgEXFRceARcxHgEVHAEVNQKqGhcWPSIBAgEBAgEjPBYXGhoYFj4jAQEBIz0WFxsBVgMCAgcEfAYMCAELIxgDBAMCECAQGCAIBQkDXAweEAIGCgQBDQgBAZYFCAMDBBQRHg4CXwMIBQEFCAMeNhgCAgMEAwUQDAwSBggOBQF5BAcDAgMBAwMDBgN9BQ4IAQ4jFwMEAwMQHxEXIAkFCQRdDB0QAgMLCAEBDAgBAZQFCAMDBAESEiAOA14DBwUBBAkDHjYZAQIDAwIiDBIGCA0GegQIAgMDAcIBASI9FxccAQEcFxc+IwEDASI8FhcbGxcVOyICAwJJlAUIAwQEARMSIQ8CEC4dAwkEBQgDFCQRFxgBBAJIBwwGMDwQCQsDAwMHBXsFDQgBRQIEBAMaNx4BBAcEAQQIAwcWDw8XCQ4fEQIUAQQDAwgEAZMFCAMDBQETEiEPAhEsGwQIBQQIAxMkEBgYBAJIBw0FI0EfBwkLBAIDBwV7BQ0HAkYDAwMDGjgeAQMHBAEECAQBLQ4YCQ4fEAMTAQQDAwcEAQEBAQAAAAMAAP/AA7ADwAAPAB8AQwAANzQnJgcGBwYHBhcWFxY3NiUBBiMiLwEmNTQ3ARYXFhclFAcGBwYnIicmNTQ3NjcyFxYXFhUUDwEVFzY3Njc2MzIXFhXVCgsPDwsKAQEMDQ0NDQwBbv56FR4eFjwWFgGFFisrOAFrDRxDQlFqS0tLS2ohJCMaCQmnbwIrKyIhCAgFBZYOCwsBAQkJEBEJCQICDQ38/noVFT4VHx0XAYU4KysX+RclTTAxAkpLa2pKSQMLChAHCQkHYIA+AhoZFRQFBQkAAQAA/8ABkgPAACoAAAEUBwYnIxEzMhcWFxYPAQYjIi8BJjU0NzY7AREjIicmNzY/ATYzMh8BFhUBkgsMDklJDwsKAQEMkwoQDwqTCgoLD0pKDgwLAQEJkwsODwuTCwMJDwsLAf22CgoQDwqTCwuTCg8QCgoCSgoKEA8LkgsLkgsPAAAAAQAA/8AEAAPAACkAAAEUDwEGIyInJj0BIRUUBwYjIi8BJjU0PwE2MzIXFh0BITU0NzYzMh8BFgQAC5ILDxAKCv22CgoQDwqTCwuTCg8QCgoCSgoKEA8LkgsBwA4MkgsLCw9JSQ8LCwuSDA4ODJILCwsPSUkPCwsLkgsAAAUAAP/AA/4DwAAGABEARABJAFUAACU3JwcVMxUBJg8BBhcWPwE2JxMVFAcGIyEiJyY1ETQ3NjchMhcWFxYPAQYnJiMhIgcGBxEUFxYXITI3Nj0BND8BNhcWBwMXASM1AQcnNzYzMh8BFhUUAf5BV0E2ARwJCsgKCgkJyQkJLjAwRf4lRTAwMDBFAdskHwkBAgccCAoODP4lJhsaARscJQHbJhsaBSUIDQwBN6T+gKQCfjWlNRAXFhFXEPZDV0MfOAGcCQnJCQkJCcgKCf6tbUQwMDAwRAHcQzAwAQ4ECQoHHAgEAxsbJf4kJRsbARwcJEgHBSUIBAQMAaWk/oCkATU1pTUPD1cQFxcAAAAEAAD/wANoA8AABwAVABoAJwAAPwEnBxUzFTMBNCMiBwEGFRQzMjcBNicXASM1ARQPASc3NjMyHwEWFdYzhjRKPQEqDAUE/skEDgUEATYDH+7+Je4DYhVf7mAUHx0XhhVZNIY0PkgCEgwE/ssEBg0FATUEdO7+JO4BpB0WX+5fFRWGFx4AAAAAAQAA/8ADbgPAAEcAAAERFAcGIyEiJyY/ASYjIgcGBwYHBhUUFxYXFhcWMzI3Njc2NzIfARYXFgcGBwYHIicmJyYnJjc2NzY3Njc2MzIXFhc3NhcWFQNuCgsQ/wAYCQoRT1RyPDY2JycYFxcYJyc2NjxDPTwqBAkIB00GAQEHPVlZYVpRUjo5JSUCAiEhPT5OTV5UTU4/SRIWFwMu/wAPCwsXFxBPTxgXJyc2Nzs7NzYnJxcYHh42BgEFTwQHBwdLKSkBIyI8O1FRWVlRUTs8IiMfIDtKEwsJGAAAAAEAAP/AA24DwABIAAABFAcGBwYHBiMiJyYnJjU0PwE2MxYXFhcWMzI3Njc2NzY3NicmJyYnJiMiBwYHFxYHBiMhIicmJxE0NzYfATY3NjMyFxYXFhcWA24jIzo7UlFYY1lZPQUGTQcICQQqPD1FOzU1KSkWFQEBFxgnJzc3OTkzMylPEQkKGP8ADwsKARcWEkk+T09UWVBRPDsiIgHAWVFROzwiIyoqSgcHBwRPBQEGNh4eGBcnJzY3Ozs3NicnFxgVFCZPEBcXCwsPAQAYCQsTSjsgHyMiPDtRUQACAAD/wANuA8AALwBbAAABFBUGBwYjIicmJwcGIyInJjURNDc2MyEyFxYHBg8BFhcWNzI3Njc2NzY7ATIXFhUTERQHBiMhIicmNzY/ASYjIgcGBwYHBisBIicmNzU2NzYzMhcWFzc2MzIXFgNfJXR1nVNNTj5JDA4ODAsLDA4BAA4MCwEBCU8pMzM4TENCKAYZBAxuCAUFDwsKEP8ADwsLAQEJT1RzTENDJwcXBQ1xBwcGASV2dpxTT089SgsPDgwNAWUDAZpfXx8gO0oLCwsOAQAPCwsLCw8OC08lFRYBJiY/CzkNBgYGAcn/AA8LCwsLDw4LT08mJj8LOQ0GBgYEml9fHyA7SgsLCwAABAAA/8AEAAPAADEAXAB8AKkAAAEVOAExFAYHMQ4BIyE4ASMiJicxLgE1MDQ5ATU0NjcxPgEzMjAxITgBMTIWFzEeARcxERUUBgcxDgEjMSE4ATEiJicxLgE1MTU4ATU0NjcxPgEzMSEyFhcxHgEXMQEVOAExFAYHMQ4BIyEiJj0BNDYzITgBMTIWFzEeARUxERU4ATEUBgcxDgEHMSEuAScxLgE9ATgBNTQ2NzE+ATMxITgBMTIWFzEeARUxAdkNCwscEP7EARAcCgsMDAsKHBABATwQHAoLDQEOCwscEP7FEB0KCg0MCwscEAE8EBwKCw0BAicNCwscEP7EIC4uIAE8EBwLCw0NCwscEP7EEBsKCwwMCwodEAE8EBwLCgwBSu0RHAoLDAwLChwQAe0QHAoLDAwLChwQAdjsEBwKCw0NCwocEOwBEBwKCw0NCwscEP4o7REcCgsMLiDtIC4MCwocEQHY7BEcCgsNAQEOCwscEOsBEBwKCw0NCwscEAAACQAA/8AEAAPAABMAKAA8AFAAZQB5AI0AogC2AAAlFRQHBgcjIicmJzU0NzYXMzIXFhMVFAcGJyMiJyYnNTQ3NjczMhcWFwEVFAcGByMiJyYnNTQ3NhczMhcWARUUBwYrASInJic1NDc2OwEyFxYBFRQHBicjIicmJzU0NzY3MzIXFhcBFRQHBgcjIicmPQE0NzYXMzIXFgEVFAcGKwEiJyYnNTQ3NjsBMhcWARUUBwYnIyInJj0BNDc2NzMyFxYXERUUBwYrASInJj0BNDc2OwEyFxYBJREQFrcXEA8BEBEWtxcPEAEREBa3FxAPARARFrcXDxABAW0QEBe2GA8PARAQF7YYDw/+lBEQFrcXEA8BEBEWtxcPEAFuEBAXthgPDwEQEBe2GA8PAQFuEBEWtxYQEREQFrcXEA/+kxAQF7YYDw8BEBAXthgPDwFvEBEWtxYQEREQFrcXEA8BEBEWtxYQEREQFrcXEA/SbhcPDwEQEBZuFxARARAPAQxtFxARARAPGG0YDxABERAX/txuFw8PARAQFm4XEBEBEA8CMW0XEBEREBdtFxAQEBD+xG0XEBEBEA8YbRgPEAEREBf+3G4XDw8BEBAWbhcQEQEQDwIxbRcQEREQF20XEBAQEP7EbRcQEQEQDxhtGA8QAREQFwElbRcQEREQF20XEBAQEAAMAAD/wAQAA8AAFQAsAEYAXwB1AIwApAC7ANQA7gEEARoAAAEiBh0BFBY7ATIwMTI2PQE0JisBOAEXJgYPAQYWHwEUMDEWNj8BNiYvASYiIwUiBg8BDgEfATgBMR4BPwE+AS8BMDQxLgEjBSoBDwE4ATEOAR8BHgE/ATAyMT4BLwEuAQUiBg8BBhYfARY2PwE4ATE2Ji8BLgEFMSIGHQEUMDEUFjsBMjY9ATgBNTQmIwUxIgYdATgBFRQWOwEyNj0BNDAxNCYrAQUiBg8BIjAxBhYfARY2PwE2Ji8BJiIjBSoBDwEwIjEOAR8BHgE/ATgBMT4BLwEuAQUqAQ8BDgEfATAUMR4BPwE+AS8BOAExLgEjBSIGDwEGFh8BFjY/ATYmLwE4ATEuARciBh0BFBY7ATgBMzI2PQE0JisBIjAB2QUGBgVHAQUHBwVH/wMGAV0DAgU9BQkDXQICBD8BAgL+SgIDAT8EAgJdAwkFPgQDA10BBgMCewIDAaEFAwMkAwkEoQEEAgIkAgX8vwQFAiQCAgSiBQkCJAMDBKIBAwLYBAcHBLwEBwcE/BcFBwcFuwQHBwS7AxcDBgEjAQMDBKIECgIkAgIEogIDAf28AQICoQEEAgIkAgoEoQUDAyQCBgHcAQMCPgQDA10CCgQ/BAICXQIFBP6JAwYCXQICBD8ECQJeAwMFPQIDlwUHBwVHAQUGBgVHAQPABwS8BAcHBLwEBzABBAKiBQkCIwEDAwSiBAoCJAECAQEkAgoEoQUDAyQDCQShAQMDpwFdAwkFPgQDA10CCgQ/AwMFAwM/BAkCXQMCBT0FCQNdAQHxBgVHAQUHBwVHAQUGBQcFRwEFBgYFRwEFB50DAz0FCQNdAgIEPwQJAl4BBQFdAgoEPwQCAl0DCQU+AgR9ASQDCQShAQQCAiQCCgShAwMCAwOiBAoCJAICBKIFCQIkAQE7BwS8BAcHBLwEBwAAAAEAAP/AA/0DwABHAAAlBgcGJicmJyYnLgE3Njc+ATc2FhceAQcOAQcGBw4BFxYXFhcWNjc2NzY3PgEnJicmJy4BJyYHNTYXHgEXFhcWFxYGBwYHDgEDa0hfYMdeXkdJJyYHHx9CCBELG0QZFwcOBAcFNhwcAhkaNDtLSplHRzQpGxsVBgYZIDg4jFBPT1tbXKJAQSUbCAcUGxsqCBNkSSIiBicmR0lbXMBdXk0KEgcRBxgYPxsHCwU6RkaPQ0Q0OxgZDSMjOy84OHg+PjtMNzc9AwQaAR8DBEU/P1dBQ0OCPj01DBUAAAACAAD/wAP/A8AALQBXAAABIgcOAQcGBzE2NzYWFxYXFhceAQcGBwYWFx4BNz4BNzY3NiYnJicmJy4BJyYjASIGBw4BBwYHBhYXFhcWFx4BNzY3MQYHBiYnJicmJy4BNzY3NiYnLgEHAf4sKyxTJyckQ09Pok1NPTQfIBcJCRwIBw0QNBICCwIcBgYdIyM3JiwrXTExMf5dCxUIAgwBGwcGHCMkOEdYWbpbW0xDT0+iTU0+NB8fFwkIHQgHDggYDQPACAceFhYeNhkZCCEhPjM+PoVERD4XIQ4PAxICEAZGSUqRQ0M4JhwcJgoJ/ucICAIQB0VKSZFDQzlHJSYHHR4/NhkZCCEhPTQ+P4VDRD4XIQ4ICQEAAAAAAgAA/8AEAAPAACwAWQAAASIHDgEHBgcGFjEzMjY1Njc+ATc2MzIWFwcGFh8BFjYvAS4BDwEmJy4BJyYjASIGFQYHDgEHBiMiJic3NiYvASYGHwEeAT8BFhceARcWMzI3PgE3Njc2JjEjAfpmW1qIKikEAQ5WDQcEHyBpRUROUpE0OwgBDP0QHQc7AhIKQyIpKFwyMjUBow0HBB8gaURFTVOQNTwIAgv+EB0HOwISC0IiKShcMjM1ZlpaiCopBAEOVgPAJiaDWFhkDwYMB0xDQ2MdHEE4OgkUAzMEGBnpBg4HPiMcHCgKC/34DAdMQ0NjHRxBODoJFAMzBBgZ6QYOBz4jHBwoCgsmJoNYWGUOBgAFAAD/wAP/A8AALQBbAIkAtwDlAAA3MTAiMS4BJy4BJyY2Nz4BFzAyFTEXHgEHDgEHDgEHBhYXFgYHMQcGJicwJjUxEzEwNDE+ATc+ATc+ARceARUUBhUxBw4BJyoBIw4BBw4BBwYiJzEnLgE3MDYzMSUxMDIxHgEXHgEXHgEXFgYHIjAjMSciJicuAScuAScuAScuATcxNz4BFzIWOQETMTgBMQ4BBw4BBw4BBwYmJzAmOQEnJjY3PgE3PgE3PgE3PgEzMRcyFhUcARUxATE4ATEOASMiJicuAScmNDcwNjkBNzYWFx4BFx4BFx4BNzIWFzEXFgYHBiI5AS8BBgsEBQcEDhEhAwkEAlIDAgEEBgMDBAIIDBQBAgNSBAoDAXsMFwwNGg5Em1EEBgEgAQgEChUKCxQKNGIpAwgDUQQBAwEBAloBDRoNDBcMOE8QAgYFAQFmBAcBAgcDBAgFGEcuBAIBIAEKBAEB+gMIBAYLBiFrRgQKAgEfAQQDCRAICQ8HJjQNAgYEZAUG/kAQHhAPHw5PkDwEBAFTBAkEBxAJCREJMGg1BQYBHgEEBAEC7Q4cDg8dEEycSQQDAgE9AggECRQJChQLM2kyAwgCOQMCBAEBAkwBChIKCBAHJyAJAQcFAQEBYAQEAQECAQkrIgICOwMKBAFCBxEIChMKNYlPBAgBAQUEChQJCRQIL04dAgcEXgUEAgH93A8dDg8bDkd0KAIDBAJgBAkBBgwGBw0HJVw0AwUBBwQBAgH+bAIBAgIJQDcDCgMBPAIBAwYMBgULBBgVAwUDXwQIAgEAAwAA/8AEAAPAAFkAsQEIAAABOAEjIgcOAQcGDwEOAQ8BDgEPATgBMRQWMzEzMDIxMjY3MTY3PgE3Nj8BPgE3Mz4BMzgBOQE6ATMyFhcjMxc6ATMyNjcxNzgBMTY0NTQmJzEuAScrAS4BKwEFOAEjIgYHMQcOARUUFhcxHgEfAR4BFx4BFTEwFDEUBgc3DgEHMQ4BBzEOARUUFhcxFx4BMzI2NzE+AT8BPgE/AT4BNTEwNDE0Jy4BJyYnFy4BJzEuAScxATEiBhUUMBUxFhceARcWHwEeAR8BHgE7ATI2NyMyNjcjNz4BNTQmJzEnLgEjMCIjMQ4BByMqASMqASMxDgEjMSoBIyInLgEnJi8BLgEvAS4BJzUuASMxAfwBQz4/bi4uIwENFwoBCQ8FAQYFaQEDBgIMFBU4IiInAw4fEQIWMRoBAgETJRICDg4BAQEDBgI0AQQDDR8RAw0ULBYBAU8BAwYCMwEBAQEXJQ4BAwUEDhAiHwEGDAcHDgcCAQECNAIEAgMEAitFFwIEBwMBCwwGBxgSEhYBCRMKChUL/LoFBw4cHE8xMjoDFC8YBBc0GwEgPR4DBgsGARQDBAEBMwIGBAEBCBQKAQECAgECAQwcDgEBATEtLlEiIxoBCRIIAQcMBQEGBQPAEBE8Kis0AhMrFwMULRgEBQcEAiwmJ0EaGhEBBwwFBQYEAwUEA1kBAwIEBgEFCAQFBXQEA1kBBAICBAIVMxwDBQsGIk8qATxsLgEJEQgIEAgBBAICAwJZAQICASdgNgMKFgwCIEonASooKEsjIyACDRgKCxUK/iQIBQEBPzk5YCYlGQEIDwUBBAYIBwMCBwEGAwIDAlgDBAMGAgECCwwqHh8kAg0fEQMNIBADBAYAAAL////AApIDwAARAD8AAAERNCcmIyIHBhURFBcWMzI3NgUUBwYnIwMGBwYHIyInAyMiJyYnNDc2MxEiJyYnJjc2NyEyFxYVFAcGJxEyFxYBEgUGCAgFBQUFCAgGBQGADAsO9R4BBQUGAQ8CLOcPCgsBLS05HhUWAQEYFxwBbR4VFhYVHjktLQH3AQAIBQUFBQj/AAgGBQUGwg4MCwH+7AcFBAEQARUKCw9HODgBJRYVHh4VFgEXFh0dFhcB/ts4OAAAAAAI//3/wAQDA8AAFQAXABwAOABiAHMAhACeAAABIyImPQE0NjMyFx4BFxYVFAYHDgEjNTEjMy4BJwMiJjU0Njc+ATc+ATU0NjMyFhUUBgcOAQc4ATEnIiYnLgEnLgE1NDc+ATc2NzIWFRQGIwYHDgEHBhUUFhceARceAQcOASMDIyImNTQ2OwEBPgEXHgEHASEjJyY0Nz4BHwEzMhYVFAYjAyImJyY2PwE+ATMwMjMyFhUUBiMwIiMHDgEDCqETGRkTJSQlOhMSBwUFEgmNgAVQK1kKFwwOME0cExQRDw8RGxkhZj7NBQoEChIEIiUVFEgxMTkPEhIPKyUlOA8QGxgFEAQPAgkGCwluzA4SEg6zAVoJGgoJAgX+jAL0zacJCQoaCpmzDxEXD/oEEQQJBgl6BAwJcAoJFxAKIVF0BRACEyAToRMgEBA4JycuCRIFCQpAMEwE/c0QCg4TBQU1Jh1BIg8REQ8rUyI1Qgk6AQUKDQorXzU6MjJNGBgFEQ8PEQITEz0oKCsmTCEFEAUJGgkFCP7mEQ8OEQGUCgIFChoJ/lOnCRoJCQEKmhEODwsDYAgFChkKYAQCEQ8KFVsEAgAABgAA/70EAAPDAFwAaAB0AIAAjACYAAAlIgYHJz4BNTQmJzceATMyNjU0JiMiBhUUFhcHLgEjIgYHJzwBMTQmIyIGFRQWMzI2NxccARUUFhcHLgEjIgYVFBYzMjY1NCY1Nx4BMzI2NxcOARUUFjMyNjU0JiMlIiY1NDYzMhYVFAYTIiY1NDYzMhYVFAYBMhYVFAYjIiY1NDYBIiY1NDYzMhYVFAYBIiY1NDYzMhYVFAYDYBgvE2wTFBEJoA4cDzVLSzU1SwkKmRhAIjpgE1NLNTVLSzUiNg5bIxwzDxQKJzg4JyY6Bj8PJRMdOBhtCg9cQ0NdXUP9IBwxMRwdMDCDExkZExMaGgJNHSoqHRwrK/6cNUtLNTVLSwErJjo6Jic6Ov0QCWwYORwdMBOzBAlMNDVLSzUTJQ6tFBlDMCcECDVLSzU1SxsYJgUDBStFHEEFCDknJjo6JgkUCUcFCBIObA8tGENdXUNDXfkrHBwxKh0dMP56GhMTGhoTExoDGiodHTArHBwx/bNLNTVLSzU1S/6/OicmOjomJzoAAAf//f/AA/0DwgAhAEAAaQCTALkA1QDsAAABDgEHBhQXHgEXHgEzPgE3PgE3NjQnLgEnLgEnLgEHDgEHJR4BMzI2Nz4BNzY0Jy4BJy4BBw4BBw4BBwYUFx4BFwEOAQcOAQcGBwYiJyYnLgEnHAEVFBYXHgEXHgEXFjY3PgE3PgE1PAE1ARYXHgE3Njc+ATc+ATU8ATUOAQcOAQcGBw4BJyYnLgEnHAEVFBYXHgEXAQ4BBwYmJy4BJxwBFRQWFx4BFxYXHgE3Njc+ATc+ATU8ATUOAQclLgEnLgEnHAEVFBYXHgEXHgEXOgEzJjY3KgEjBy4BJxwBFRQWFx4BFx4BFzUqASMiJicB3hgtDhkZDh4TPoE1PmUwGC4TGRkFCQQZPh01azkxVib+hjVtPitYMCI5GB0dGD4dOXo5MVYmFCYTExMTKBgDmQkTCQ8lEzU1NWs2NjciPhMTEwoNCSxXMER+PiI7HQ4L/HQrLC1aLS4uIUgdExoPFw0PJhguLi1cLS4uL1MeCw8TKh0DQCdOK0iPQyZIGAsPEzAcLi0uWy4uLiFBHg0YDicX/UYrVSccKA8LDw8eFCZbKw4dDwUKDRMuGGArVxgiGCZPLBwzHQUDBStPJgH1CRcTGDUTDhUJHRAEDQ8KFhMYNhgFCgUTFgoOCgUFEw/hFBMLDgoYGRw6HBQbBRMLBQQUDgoWExgwGBMXCf25CRoKCRQJEwoJCQoTCSgiDxwOGSYOBgkFFxcFCgoUCRgYDx0TFB4PAaAOCQgFBAQJChYTDiAYDyMPChkKChMJDwcIAQYGDAorKw8jDhMdChMWCv7AExUFCQkUDiQnDiMPEx8OExsFDwcHAwUFCQkXEwoeGBMiGBgfCecEFRQJIBwTHg4PIQoJGQQYEAUYLhSOCicwFB4OHSgPGBYFBQMEWQsOAAYAAP/AA/8DwAAbADgAZAByAJgAsAAAASInLgEnJjU0Nz4BNzYzMhceARcWFRQHDgEHBgMiBw4BBwYVFBceARcWMzI3PgE3NjU0Jy4BJyYjAzUiJic3HgEzMjY1NCYnLgE1NDY3NTMVMhYXBy4BIyIGFRQWFx4BFRQGBxUBIiY1ETQ2MzIWFREUBiEiJi8BJSImJyUuAT8BPgEXBTcuAT0BNDY7ATIWHwEWFA8BDgEjAQ0BOgEzFzcnIxUzMhYVFAYjByImJyUHAf81Li9GFBQUFEYvLjU0Ly9FFRQUFEYuLzUpJCQ2EBAQEDYkJCkpJCQ2EBAQEDYkJCkMDyAFBwkbDxMaFBMiHhsZEg8ZBQYFEw8TExUYGBsdHQHaDhISDg8REf73BBEEWf7TChMK/wAYCQ4TDjIUAQYzBQEnGLoOFQqNExNNBRgK/VoBAAE0BAMFYE2NwG0OEQ8K2QUKBf7tEwHAFBVFLy41NS4vRRUUFBRGLi81NS8uRhQUAccQEDYkJCkpJCQ2EBAQEDYkJCkpJCQ2EBD+syYIBRoFCRMODhUJChgZFx0FICAIBRoFCBYJDw4KCh4YEyIFJv2GEQ8BgA4TEw7+gA8RAgQnQAcGsw8yGBoYCwqSBgUSCSAdIwkKjRM0E5kPCwFgs0Aum5MgEQ8PEScCBZMgAAACAAD/wAQAA8AAEAAkAAABISIGFREUFjMhMjY1ETQmIwMBBiIvASY0NzYyHwEBNjIXFhQHA1X9VkdkZEcCqkdkZEcI/lUMIw2zDQ0NIg2ZAYkNIg0NDQPAZEf9VkdkZEcCqkdk/rP+Xg0NtAwiDQ0NmgGJDQ0NIg0AAAAAAgAA/8AEAAPAABAAHgAAASEiBhURFBYzITI2NRE0JiMDISImNTQ2MyEyFhUUBgNV/VZHZGRHAqpHZGRHKv2qExcXEwJWExcXA8BkR/1WR2RkRwKqR2T91RgTExgYExMYAAAAAAIAAP/ABAADwAAbADwAAAEyFx4BFxYVFAcOAQcGIyInLgEnJjU0Nz4BNzY3MSIHDgEHBhUxFBceARcWMzEyNz4BNzY1MTQnLgEnJiMCAFlOTnQhISEhdE5OWVlOTnQhISEhdE5OWWpdXYspKCgpi11dampdXYspKCgpi11dagNrISF0Tk5ZWU5OdCEhISF0Tk5ZWU5OdCEhVSgpi11dampdXYspKCgpi11dampdXYspKAAAAAMAAP/ABAADwAAbADwAXAAAATIXHgEXFhUUBw4BBwYjIicuAScmNTQ3PgE3NjcxIgcOAQcGFTEUFx4BFxYzMTI3PgE3NjUxNCcuAScmIxExIicuAScmNTE0Nz4BNzYzMTIXHgEXFhUxFAcOAQcGAgBZTk50ISEhIXROTllZTk50ISEhIXROTllqXV2LKSgoKYtdXWpqXV2LKSgoKYtdXWo3Li9FExQUE0UvLjc3Li9FExQUE0UvLgNrISF0Tk5ZWU5OdCEhISF0Tk5ZWU5OdCEhVSgpi11dampdXYspKCgpi11dampdXYspKP0AFBNFLy43Ny4vRRMUFBNFLy43Ny4vRRMUAAAAAAIAAP/AA1oDwAATACYAAAEmIgcJASYiBw4BFwEWMjcBNjQnJRYyNwkBFjI3NjQnASYiBwEGFANaDyMP/uf+5g8jDQ4BDwE5DyMNATsODv1NDSMPARoBGQ8jDw4O/sUNIw/+xw8BRg8P/ucBGQ8PDiMO/sUODgE7DiMO9A8PARn+5w8PDiQNATsODv7FDSQAAAIAAP/AArkDwAAFAAsAAAEXIyc3Mx8BIyc3MwGNhkaGhkYghkWHh0UBwLm5ubm5ubkAAAACAAD/wAK5A8AABQALAAABMxcHIzclMxcHIzcB7UaGhkaH/tNGhoZGhgJ5ubm5ubm5uQAABAAA/8ADbgPAAAQAKQA9AFcAADchNSEVITMRNCcmLwEmJyYHFRQHBiMhIicmJzUjETM1NDc2MyEyFxYHFQM1NCcmKwEiBwYXFRQXFjczMjc2BREUBwYjISInJicRNDc2MyEyFxYfARYXFhXbAbj+SAIASgYGBaEFDw4IDxAX/rYXDw8BSkoQEBYB3BcQEAHbBQUIbgcGBgEFBQhuBwYGAW0QDxf9ABgPEAEREBcCERccHA+gEAwLUtzcAgAJDQ0HoAYGBwHuFxAQEBAX7v0k7hcQEBAQF+4CE7YIBQYGBQi2BwYHAQYFC/3uFxAQEBAXAwAXEBAMDA+gEBscFwAAAAIAAP/AA5sDwAA4AFgAACUUFxYHBgcGBwYHIyInJjURNDc2OwEyFxYVFBcWBwYHBgcGJyMiBwYHERQXFhczMTMyFxYXFhcWFQEUBwEGIyInJj0BISInJj0BNDc2NyE1NDc2FxYXARYVAYkBAQEBAQEFBAi2RTAwMDBFtggFBgEBAQEBAQUECLYmGxoBGxwlsgYGAQEDBAEBAhIL/skLDg4MC/8ADgwLCwwOAQALDA4OCwE3C4kCCgkFBQkJAgMBMTBEAZJEMDEGBQgCCQkGBwcHBAQBGxon/m4mGhsBAgIBAQQEBAE3Dgz+yQoKChClCwsO3A8KCgGlDwsLAQEJ/skLDwAAAwAA/8AEAAPAACAAUABkAAAlEQYHBgcGBwYHBicjIicmJyYnJicmJxEUFxY3ITI3NjcRNTEnJjEwJyYHBichIgcGBxQXFhcWFxYXFhcWFxY3MzI3Njc2NzY3Njc2NzY3NjU3ERQHBgchIicmNxE0NzYzITIXFgO3EhaYWx0SEx8eHAIbHyASER5amRYSBgYGA0oHBQUBAQEDAwICBvy2BwUFAVVtdwQREAkJERAMDQwCCw4NDxAKCg8QBXduHxsaSRsaJvy2JRscARsaJgNKJhobigG2FBF2SxkNDg8PAg0NEA8XS3YRFP5KBwcGAQUGCAJYDgcHBgUBAQMGBwZgQ1ZeAw4OCAcKCgYHAQYFCwsGBhAPAl5WGSoqIRX9kyYbGgEbHCUCbSYbGhobAAAAAAL////AA7cDwAAPADYAAAE0JyYnJgcGFRQXFjc2NzYBFAcGIyIvAQYjIicmJyYnJjc2NzY3Njc2NzYXFhcWFxYXFAcXFhUCkktLamtKS0tKa2pLSwElFxYdHxTEZn5SS0s1NSEhAQEfHzc3SUlUVEhJNzgeHwFGwxYCCWpKSwEBTUxoZ05OAwNISP6RHhUWFsNGHyA2N0lKU1NJSTg4Hh4CAiIiNDRNTU9+ZsQVHwAAAQAA/8ADJAPAACwAAAEVFAcGJyMVFAcGByMiJyY3NSMiJyYnNTQ3NjczNTQ3NjsBMhcWFxUzMhcWFwMkEBAX7REQF20XEBEB7RgPDwEQEBftEA8YbRgPEAHtGA8PAQH2bRcQEQHuFw8PARAQFu4QDxhtGA8QAe0XEBAQEBftERAXAAAAAQAA/8ADJAPAABMAAAEVFAcGJyEiJyYnNTQ3NjchMhcWAyQQEBf9ShgPDwEQEBcCthgPDwH2bRcQEQEQDxhtGA8QAREQAAAAAQAA/8AC5QPAACsAACUUDwEGIyIvAQcGIyIvASY1ND8BJyY1ND8BNjMyHwE3NjMyHwEWFRQPARcWAuUPThAXFhGnqBEWFxBOEBCoqBAQThAXFhGopxEWFxBODw+oqA/xFxBODw+pqQ8PThAXFhGnqBEWFxBOEBCoqBAQTg8YFxCopxAAAQAA/8ADuwPAABoAAAEUBwEGIyInASY1ND8BNjMyHwEBNjMyHwEWFQO7Ef4VEBcWEf7jDw9OERYXEKgBdxAXFhFNEQKOFhH+FQ8PAR0QFhcQThERqQF4EBBODxgAAAAABgAA/8AEAAPAABMAKAA8AFAAZQB5AAAlFRQHBgcjIicmJzU0NzYXMzIXFhMVFAcGJyMiJyYnNTQ3NjczMhcWFwEVFAcGByEiJyYnNTQ3NhchMhcWARUUBwYrASInJic1NDc2OwEyFxYBFRQHBichIicmJzU0NzY3ITIXFhcRFRQHBiMhIicmJzU0NzYzITIXFgElERAWtxcQDwEQERa3Fw8QAREQFrcXEA8BEBEWtxcPEAEC2xARFv3cGA8PARAQFwIkFxAP/SYREBa3FxAPARARFrcXDxAC3BARFv3cGA8PARAQFwIkFxAPARARFv3cGA8PARAQFwIkFxAP0m4XDw8BEBAWbhcQEQEQDwEMbRcQEQEQDxhtGA8QAREQF/7cbhcPDwEQEBZuFxARARAPAjFtFxARERAXbRcQEBAQ/sRtFxARARAPGG0YDxABERAXASVtFxARERAXbRcQEBAQAAMAAP/AA24DwAATAEsAYwAAJTU0JyYrASIHBh0BFBcWOwEyNzYTNCcmJyYjIgcGHwEWMzI3Njc2MzIXFhUUBwYHBgcGFxUUFxY7ATI3NjU0NzY3Njc2NzY3Njc2NxcUBwYHBiMiJyYnJicmNzY3NjMyFxYXFgIABQUIbggFBQUFCG4IBQWSHyAvLzKMSAoOSwUGCQUfEhQdHBYVCwwbJB8eAQUFCG4IBQUMDRISCwoPEAoKBgYB3Ds6ZmV3dmdmOTgDAz4/YGB9fV9gQEGubQgFBgYFCG0JBQUFBQGJMisrFxh6DQw4BAcnDQ8QDxIWDQ4MDyIiJhQIBQYGBQgKEhELCgcGDQ0PDhQVGm54ZGU7Ozs7ZWR4eGRlOzs7O2VkAAMAAP/AA24DwAAlADkAUQAAJTU0JyYrARE0JyYrASIHBh0BFBcWOwEVIyIHBh0BFBcWMyEyNzYDNTQnJisBIgcGHQEUFxY7ATI3NgUUBwYHBiMiJyYnJicmNzY3NjMyFxYXFgJJBQYHNwUFCLcIBQUFBQg3NwgFBQUFCAEABwYFSQUFCG4IBQUFBQhuCAUFAW47OmZld3ZnZjk4AwM+P2BgfX1fYEBBrlsIBQUBJQgFBQUFCFsIBQa3BQUIWwkFBQUFAglbCAUFBQUIWwkFBQUF5XhkZTs7OztlZHh4ZGU7Ozs7ZWQAAAACAAD/wAOnA8AAFgA9AAABERQHBgcjNSMVIyInJicRNDU0NQkBFjcHBgcjIicJAQYnJi8BJjc2NwE2MzIfATU0NzY7ATIXFh0BFxYVFAMkCwsP25LbEAoKAQFJAUgBfyMFBwIHBf51/nQHBgcFJAQBAQUBmxIZGBSLBQUIbggFBX0GAYj+7g8KCwHc3AwLDgESAQEBAQEO/vIBJSoFAgQBSf63BQECBSoGBwcFAVYQEHNuCAUGBgUI6GkECAgAAAADAAD/wAOtA8AAKwBWAH8AACU0LwEmIyIHFhcWFxYXFhcWFxQHBgciJyYnJicmJyYnBhUUHwEWMzI/ATY1ATQvASYjIg8BBhUUHwEWMzI3JicmJyYnJicmNTQ3NhcyFxYXFhcWFxYXNgEUDwEGIyIvASY1NDcnBiMiLwEmNTQ/ATYzMh8BFhUUBxc2MzIfARYVA0ARdhEWGRABCQkDAwcGAQEBERAXCAcHBwcEBQgIAhMQdg8YFhFTEf5tD3YQFxYRUxERdhAXGBECCQkDAwYFAgIQDxcKBwcHBwQFCAgCEgIAMVQvREYvdi8yMjFGRDF2MDBUMERFMHYvMjIxRkQxdjDkGA93EBIBCQkEAwgIBgYJGA8QAQICBQYEBAgIAhEYFxB2EBBSERUBlBYRdREPVBAWFxB3DxECCQkEAwcHBwcKFhARAQICBQYDAwkJAhH+hUMwUzAxdTFERjEyMjB3MEVEL1QvMHYwREcxMjIwdzBFAAABAAD/wAMiA8AASAAAJRQHBiMiJwEmNTQ3NjcyFwEWFRQHBiMiJwEmIyIHBhcUFwEWMzI3Njc0JwEmIyIHBhUUHwEWFRQHBiMiLwEmNTQ3NjMyFwEWFQMiLi5BTTn+Q0A/QFpaQQFaBhIRCQgF/qUtOj0qKgErAbwkLyUXGAEk/rMOFBALDA/qBhITCAYG6yMgIS4yJAFMOahCLS04Ab1BWVs/PgFA/qYGBwkREgUBXCwrKz07LP5EJRkZIzAjAUwPDAsQEw/qBgcJEhEF6yIzLyAhJP60OE8AAAAAAf///8ADtwPAADIAAAEVFAcGByMiJyY9ATQnJgcGBwYHFTMyFxYXERQHBgchIicmJxE0NzYXITU0NzY3NhcWFwO3DAsOJQ4MCyoqPT4qKgE2GA8QAREQF/3dGA8QAREQFwGASktrakpKAgJSkg8LCgELDA6SPSsrAQEpKT9uEA8X/rYXDw8BEBAWAUoWEBEBbmpLSgEBTE1oAAAAAwAA/8AEAAPAABgAMABIAAABJicWFRQHBicmJyY1NDcGBxYXFjMyNzY3JTQnJgciBwYVFBcWMzI3NjU0NzYzMjc2BRQHBgcGIyInJicmNTQ3Njc2NzYXFhcWA7dXgyNLS2pqS0sjg1dNcnOFhXR0Sv5lCQgLSDMzCAgMCwgIIyMxCwgJAeQLUIeHl5eHh1ALC1CHh5eXh4dQCwG/iEI7RWlMTAEBSkprRTtCiHRGRkZGdN0LCAgBMzNHCwgICAgLMSMjCAjRExOFTk9PToUTExQUg09PAQFRUYEUAAUAAP/ABAADwAALACMAUABXAG4AACU3JicmNzQ3BgcWFxM0JyYHIgcGFRQXFjMyNzY1NDc2MzI3NjcUFQYHBg8BBiMiJyY1NDcmJyYnJjU0NzY3NjMyFzc2MzIXFhcWFxYXFgcWFRcUBwYHExYFFAcGBwYHBiM3Njc2NyYnNxYXFhcWFQE9LDEcHQEjg1dglN8JCAtIMzMICAwLCAgjIzELCAnOPHh4PB0FCgdGCRpSRUUzCwtYgYGbMzMgBQsDBwcLCwgHCwsBCRYtLUuhBAEACxcoVnBxfyp6ZmdGQl8jNzIyIQvqUSQ2Nj9EPEOHk0MBsgsJCAEzNEYMCAgICAwxIyMICHgEAWzY2GwzCSgGCgcrJT49TxEWFhKGTk4LOAkDAwYGBQQGBgEFCv9QQkEcAR8aYBMUJS5iNjdMCkRDbGZCQCQzMjcUFAAAAgAA/8ADaAPAAA8AKQAAATQnJgcGBwYXFhcWFxY3NgEUBwEGIyInASYnJj0BNDc2NzMyFxYXARYVAQYVFh0eFxYBARQVIB8UEwJkFf7oFx4eFf5oFg8QFhUe7x0lJRYBmBUCuh8VFgEBFBMhIRITAwMZGP7SHxX+5xUVAZkVJSUe7R4WFQEPEBX+ZxUeAAAAAwAA/8AEQwPAAA8AKQBFAAABNCcmBwYHBhcWFxYXFjc2ARQHAQYjIicBJicmPQE0NzY3MzIXFhcBFhUzFAcBBiMiJyYnATY1NCcBJicmIzMyFxYXARYVAQYWFR4eFhcBARUUICATFAJjFP7nFx0fFP5nFg8PFRYd7x4lJBYBmRTcFf7nFh4VDQ0RAQ0VFf5nFSUlHoAeJSUVAZkVArofFRYBARQTISESEwMDGRj+0h8V/ucVFQGZFSUlHu0eFhUBDxAV/mcVHh8V/ucVCAgSAQwVHx4VAZkVEA8PEBX+ZxUeAAAAAQAA/8AC2wPAACEAAAEyFxYXFhcRFAcGBwYjIi8BBwYjIicmJyY1ETQ3Njc2MyECmgwMFAoKAQsLEwoOHBX7/BUbDQwTCwsLCxMMDQJYA3EFCQ8PFf0gFBAQCAQT8fEUBQgQEBQC4BQQEAgFAAAAAAT////AA7cDwAAPAB8AOwBWAAAlNCcmJyYHBgcGFxY3Njc2NzQnJicmBwYHBhcWNzY3NjcVFAcGByEiJyYnNTQ3NjMhFxYzMj8BITIXFhUDFgcBBiMiJwEmNzY7ARE0NzY3MzIXFgcRMzIC2goKDxAKCgEBDAwODQwNkAoLEBAKCQEBCwwODg0MSBEQF/y4GA8QAREQFwEJTSEsLSFOAQkXEBG7CxP/AAoQDwr/ABIKCheTCwsPkg8LCwGSGXcPCgsBAQ0MDQ4MDAEBCgoQDwoLAQENDA0ODAwBAQoKkLgWDxABERAVuBYREE4hIU4QERYBRRcR/wALCwEAERcWAQAPCwoBCwwO/wAAAAAE////wAO3A8AADwAfAD4AWQAAJTQnJgcGBwYHBhcWFxY3Njc0JyYHBgcGBwYXFhcWNzY3FRQHBiMhIicmJzU0NzYXMxYXFjsBMjc2NzMyFxYVAwYrAREUBwYHIyInJicRIyInJjcBNjMyFwEWAtoKCg8QCgoBAQwMDg0MDZAKCxAQCgkBAQsMDg4NDEgREBf8uBgPEAEREBfzDRscJJIjHBsO8xcQEbsJGZIKChCSEAoKAZMXCgoSAQAKDxAKAQATZQ8LCwEBCQkREAkJAgMODQwPCwsBAQkJERAJCQIDDg2MtxYREBARFrcXEBEBIBUUFBUgEA8YAXIW/wAQCgoBCwsPAQAWFxEBAAoK/wARAAEAAP/ABAADwAA7AAABFAcBBiMiJyY9ASMiBwYHBgcGBwYHBgcGFRQXFBcWBxQHBiMiJyYnJicmJyY1NDc2ITM1NDc2FxYXARYEAAv+3AsPDgsMgDgsLCwsICAcHRESCgoDAgIBBQUICgYEBAQDAwNJH1wBl4AMCw4PCwEkCwJADwr+2wsLCw+SAwMJCg8PGRghIS4uOSAnBAkKBggGBgoFBwcLCgOjX3JN5pIPCwsBAQn+2wsAAAABAAD/wAJJA8AAEgAAARQHAQYjIicBJjU0NzYzITIXFgJJCv8ADA4ODP8ACwsMDgIADgwLAkAODP8ACwsBAAwODgwLCwwAAAABAAD/wAJJA8AAEgAAARQHBichIicmJyY3ATYzMhcBFgJJCgsP/gAPCwoBAQwBAAsPDwsBAAoBQA8LCwEKChAPCwEACgr/AAsAAAAAAQAA/8ABWwPAABIAAAERFAcGIyInASY1NDcBNjMyFxYBWwoKERAJ/wAKCgEACw4PDAwCwP4ADgwLCwEADA4ODAEACwsMAAAAAQAA/8ABWwPAABIAAAEUBwEGIyInJjURNDc2NzYXARYBWwr/AAsODwsLCwsPDgsBAAoBwA4M/wALCwwOAgAPCwoBAQz/AAsAAQAA/8AClQPAABoAAAkCFhUUDwEGIyInASY1NDcBNjMyHwEWFRQHAov+0AEwCgpfCw8OC/5YCwsBqAoPEApfCgoC7/7R/tAKEA8KYAoKAakLDw8LAagLC2AKDxAKAAAAAQAA/8ADzQPAABoAAAkBBiMiJwEmNTQ/ATYzMhcJATYzMh8BFhUUBwPC/lgLDw8L/lgLC2AKDxAKAS8BLwsPDgxfCwsCSv5ZCwsBpwwPDwpfCwv+0QEvCwtfCw4ODQAAAQAA/8AClQPAABkAAAkBBiMiLwEmNTQ3CQEmNTQ/ATYzMhcBFhUUAov+WAsODwtfCwsBL/7RCwtfChAPCgGoCgGm/lcKCmALDg8LATABLwsPDgtgCwv+WAwODgABAAD/wAPNA8AAGgAAAQcGIyInCQEGIyIvASY1NDcBNjMyFwEWFRQHA8JfCw8QCv7R/tELDw4LYAsLAagMDg4MAagLCwEBXgoKATD+0AoKXgsQDwoBqAoK/lgLDg8MAAABAAD/wAOYA8AAJQAAARQHAQYjIicBJjU0PwE2MzIfARE0NzY3MzIXFhURNzYzMh8BFhUDmBb+jRceHRb+jRYWKhYeHRaoFRYfSB4WFakUHx4WKhYB1h8V/owWFgF0FR8dFyoVFagBkh4VFgEXFh3+bqgVFSoXHQABAAD/wANbA8AAJQAAARUUBwYjIRcWFRQPAQYjIicBJjU0NwE2MzIfARYVFA8BITIXFhUDWxITHf5tqBYWKxUfHhX+ixQUAXUVHh4WKxYWqAGTHRMSAeRIHxYVqBQfHxQsFRUBdBYdHhcBcxYWKhYeHReoFBUgAAABAAD/wANbA8AAJQAAARQHAQYjIi8BJjU0PwEhIicmPQE0NzYXIScmNTQ/ATYzMhcBFhUDWxT+jBYeHhUrFxen/m0dExISEx0Bk6cXFysVHh4WAXQUAb8eFf6MFRUrFR8fFacVFh9IHxYVAakUHx8UKxYW/o0VIAABAAD/wAOYA8AAJQAAARQPAQYjIi8BERQHBgcjIicmNREHBiMiLwEmNTQ3ATYzMhcBFhUDmBYqFh4fFKkUFSBIHxYVqBQfHxQrFhYBcxUeHxYBcxYBpxwXKxUVqP5uHhITARQTHQGSqBUVKxYdHxYBcxYW/o0XHgABAAD/wANxA8AAQQAAARYXFg8BBgcGLwEVFAcGByMiJyY3NQcGJyYvASY3Nj8BJyYnJj8BNjc2HwE1NDc2NzMyFxYdATc2FxYfARYHBg8BA08aCAcPJA8eHRqYFhUeSR4WFwGXGx0eDiUPBwgbmJgaCQgQJQ8dHByXFhUfSR4VFpgbHB0QJBAICRmYAWgOHh4aPxsHBw5YsB0WFQEWFxywWA8ICRk/Gh4eDlhYDh4eGj8bBwcOWLAdFhUBFhccsFgPCAkZPxoeHg5YAAACAAD/wAO2A8AANgBRAAABFRQHBiMhIicmNRE0NzY3ITIXFhcWDwEGIyInJiMhIgcGBxEUFxYXITI3Nj0BND8BNjMyFxYVEwEGIyIvASY1ND8BNjMyHwEBNjMyHwEWFRQHAyUwMUT+JUUwMDAwRQHbJB4KAQIHHAYHAQUNDP4lJhsaARscJQHbJhobBSUGBwMEDIT+Lg0TEg/1Dw8+DhMSD5YBcg0TEg5ADQ0BiLZEMDAwMEQB3EMwMAEOBAkKBxwFAQMbGyX+JCUbGwEcHCSRCAUkBgIEDAEX/i8ODvYNExIPPw0NlgFxDg4+DxISDwADAAD/wANEA8AAHQAhACYAAAElBREXBRE3NQc1JxUnNSclDQEVNxUHESU1LwE3EQEVLwEFBzU3FwNE/lz+YwMBl+Dgl4xmAYwBk/53398BmgM4O/3C8gMDIqZtOQLg4OD+h7ftAT54PnTHU8pKwDrZ2dCtc116/srwhwMPHgF5/e2kjqMqVjA5EwAAAAUAAP/ABAADwAAiACcAKwAvAEYAAAEhIgYVERQWMyEVIyIGFRQWMyEyNjU0JisBNSEyNjURNCYjBxEhESEBIzUzJSE1ISUzNwE3MzI2NTQmKwEHAQcjIgYVFBYzA9P8WhMaGhMBU4APEREPAgAPEREPgAFTExoaExL8gAOA/oCAgAGA/IADgPy/rZQBAIwzDxERD01y/wCukw8REQ8DwBoT/ToTGqERDg8REQ8OEaEaEwLGExo//h8B4fx+oUCA4JP/AI0SDw4RcwEArBMODxEAAAAACgAA/8AEAAPAABAAFAAYABwAIAAkACgALAAwADQAAAEhIgYVERQWMyEyNjURNCYjAREhESkBESE1ITUhATMVIxUzFSMVMxUjATMVIxUzFSMVMxUjA9P8WhMaGhMDphMaGhP8bgGfAeH+gAGA/IADgPzfwMDAwMDAAgDAwICAwMADwBoT/FoTGhoTA6YTGvw/AoL9fgKCP8H+gEFgQGA/AYBBYEBgPwAABwAA/74EAAPCABYAHAAsADAANAA4ADwAAAEhIgYVERQWMyE1IREhFRQWOwEVMzUnFSImPQEXAwcVMzU3MxcVBxUzNTc1JwMzFSMBIRUhFSEVIRUhFSEDNvz3ExoaEwLA/VQCpSwkiz/KBwiAh0BAGWchgD+AR3g/P/2iAXr+hgF6/oYBev6GA8IaFPxbFBlDA32TIi6d3+HkCQiAkf7TQl5EHR1XX00sYJQ//mBTAudBokChPwAAAAIAAP/AA9wDwAAJAC4AAAE3LwEPARcHNxcBFA8BExQVFCMiJyUFBiMiJyY1NDcTJyY1NDclEzYzMhcTBRYVAq+u8W1r8q8q2NkBBBDPMhgKDP7+/wAMCwsGBwEy0A8gAR+BCxARDIABHyEBW6oi29siqvFycgG8DA/K/uIECB0Ih4cICgkKBAgBHsoPDBYFKQEEGBj+/CkFFgAAAAUAAP++BAIDwAATADoASABWAH4AAAEhIgYVERQWMyE1IREhETMRNCYjBQYHDgEHBhUUFx4BFxYzMjY3NiYnJgYHDgEjIiY1NDY3PgEnNCYHFyEyNjU0JiMhIgYVFBYXITI2NTQmIyEiBhUUFgEXBzUHFTMVFBYXHgEzMjY/AT4BNTQmLwEuASMxIgYHDgEdAQcVJTUD0vxcExkZEwHF/k4Dfj8eDv1iJiAgLQ0MExNBLSwyPnMiBAgJChkKGFgvSGtGOg4KBRcJ6QE8DhUTEP7EDxQUDwE8DhUTEP7EDxQUAQSzs6xzEhEFDQgJFgeyCgoJB7MKFAsFDQURFdMBDAO+GRP8XBMZOQOE/ggCCxMZpQwYFz4lJikyLCxCExNAOQoZCgUICiYtZUc/WxMFEw4OEAQ6Eg4OEhIODhJ/EQ4PEREPDhH+6raZcwM6NhEeBwMECQeZCBYMDBcKtQoKAQMHHhE5Az0DcwAAAAAJAAD/wAQAA8AADQAbACkANwBFAF0AbADkAPMAAAEhIgYVFBYzITI2NTQmByEiBhUUFjMhMjY1NCYHISIGFRQWMyEyNjU0JgcjIgYVFBY7ATI2NTQmAyMiBhUUFjsBMjY1NCYTMjY/ATYmJy4BDwEOARUUFhceATM4ATMnNDY/AQcOASMiJic0JjUTNTMyNjU0JisBIgYVFBY7ARUOAQcXPgE3FRQWMzI2PQEeARcHBhYXFjY/AR4BFwcOARceAT8BHgEXIyIGFRQWOwEOAQcnJgYHBhYfAQ4BBycuAQcOAR8BDgEHNTQmIyIGHQEuAScHHgEzMjc+ATc2NTQnLgEnJicnNDY7ATIWFRQGKwEiJjUBZv7eBwoKBwEiCAkJCP6rCAkJCAFVCAkJCP7eBwoKBwEiCAkJCKAICQkIoAgJCQiZCAkJCJkICQnkDRgHfwIBBQUKBbwKDgcKCBgNAyIFBYVjAgsHBQ0DAzZSFR8dF78UHyAXRyZMJA4hQyQKBwgJLFEkGAMFBQUOBRghPBcpBQUDAg4IKRcZA08HCgoHTwMUEiwGDQUFBActFTMfHgUOBQUEBR8rXTQJCAcKLlYmES5pNVlNTnQhIiAgbktLVnoJCL8HCg0IvwUIAgQJCAcKCgcICYgKBwgJCQgHCokJCAgJCQgICYgKBwgJCQgHCgIiCgcICQkIBwr+pA0LuwUNAwUBA34IGA0MGQoICT0FCgZjhgUFBAMDCQUBp0UeFRQfHxQVHkUCEBAfDRACSwgJCQVOAhUSLAUNAwICBykUOCEYAw0ICAECGCZbMAoHCAksUSQYAwIIBwwFGCE4FywFBAUGDQUpFx0DWQgJCQhZAxYXHxkaIiF0Tk1ZVUxMdCMiBHgHCgoHCAkJCAAAAAABAAD/wAPcA8AAMgAAARQGDwETHAEVFAYjIiYnJQUOASMiJicuATU0NjUTJy4BNTQ2NyUTPgEzMhYXEwUeARUxA9wICM8yDAwFCwf+//8ABgsGBgkDAwMBMc8IBxAQAR+BBg0ICA8GgAEfEBECJgYOB8r+4gIGBA4OAwSHhwQDBAUECgUCBgQBHsoHDgYLDQMpAQQMDAwM/vwpAw0LAAAAAgAA/8ADggPAABAAIQAAEwE2MhcBFhQHAQYiJwEmNDcXBhQXARYyNwE2NCcBJiIHAX4BMyFcIQEzISH+zSFcIf7NISE1CwsBMwseCwEzCwv+zQseC/7NAg8BMyEh/s0hXCH+zSEhATMhXCE1Cx4L/s0LCwEzCx4LATMLC/7NAAACAAD/wAQAA8AACAAMAAAlAScHESMRJwcDIRUhAgABOmCagKBmugQA/ADAATNgkwIA/gCaZ/5NgAAAAAAEAAD/wANzA8AADwAfAFkAkwAAAScmIg8BBhQfARYyPwE2NAMnJiIPAQYUHwEWMj8BNjQBLgEvAS4BIw4BBwYHDgEHBgcGFh8BFjI/AT4BMzIWHwEeARcUFhUWBgcUBiMHBhQfARYyPwE+AScxBR4BHwEeATcyNjc2Nz4BNzY3NiYvASYiDwEOASMiJi8BLgEnNCY1JjY3NDYzNzY0LwEmIg8BDgEXMQJFPgMIAz0DAz0DCAM+AwQ9AwgDPgICPgMIAz0DASwCKypqDRkODRsPHx8fPR8eHw4FEyIDCQTqAgUCAgQCShYYBAEBEBIBAbYEAz0DCQO3IyMB/RoCKCluDRkODRsPHx8fPR4fHw4FEyIDCQTqAgUCAgQCTRcUBAEBEBIBAbYEAz0DCQO3IyMBA0A9AwM9AwkCPgMDPgIJ/RE+AwM+AgkDPQMDPQMJAXcpUypqDA4BEQ4fHx4+Hh8fDhgSIwMD6gMCAQJKFikSAwQDEyYSAQG3AwkEPAMDtyNNKQYoUCptDQ4BEQ8eHx89Hx4fDhgSIwMD6gMCAQJNFyUSAwQDEyYSAQG3AwkEPAMDtyNNKQAAAAUAAP/AA8ADwAAfACQAJwBLAE8AAAEmIg8BISIGFREUFjsBFRQWFxY2PwEhMjY1ETc2NC8BAyc3FwcnFwcXFAYjISIGFQc1NCYrASImNRE0NjMhDwIjIgYVFBY7AT8BERMnNxcDRgQYCsD+Mx02LSYaCQoKEQWTATMdN8YFBXrsR9pG2Wc6Z/QMDv7GBA9zCw8zDgsLDgGTTAdNhg4MDA6mulqmRiZGA3MFBcYtJv6THTaHBRAEBQYFoC0mASfGBRgJbf5gR9lG2hM5J5kPCwEFc2YODAsOAW0ODFQHnxYKEw1TWv8AAeZHLEYAAwAA/8AEAAPAAAYAPwBgAAAJARsBNy0BBSInLgEnJjU0Nz4BNzYzMhceARcWFRQGBxc+ATU0Jy4BJyYjIgcOAQcGFRQXHgEXFjMyNjcnDgEjNSImNTQ2MzIWFRQGBxc+ATU0JiMiBhUUFjMyNjMnDgEjAWABAEDzU/8AARr9TTw2NVEXGBgXUTU2PDw1NlAYFwkKIAoJGhlZPDtDQz08WxsbGhpaPTxGHTgYDRgwGDpNTTo5TQEFGQUCY0RDXWRDDhsKDQkUCQJg/WABIP7tTflNDRgXUTU2PDw1NlAXGBcYUDY1PBg3GA0dNSJDOzxYGhoaGlg8O0NEOztZGhoKCSAJCqBNOjRMTDQKFQ4NDhcOQ2RdQ0RjByAFAgAEAAD/wAQAA8AAQQBFAEkATQAAEzQ3PgE3NjMhMhceARcWFREUBw4BBwYjISInLgEnJjUzFBceARcWMyEyNz4BNzY1ETQnLgEnJiMhIgcOAQcGFREjAREzEQEhFSEFFSE1ABobTiwtJAIAPC8wQhESERJCLzA8/gA8LzBCERJAEBE2IiMkAgAkIiM2EBEQETYiIyT+ACQiIzYQEUABgED+gAFA/sABgAIAAsA8LzBCERIREkIvMDz+ADwvMEIREhESQi8wPCQiIzYQERARNiIjJAIAJCIjNhAREBE2IiMk/gACwPyAA4D+wEDAQEAAAAABAAD/wAQAA8AAWAAAARQPAQYjIicmPQEjFTMyFxYVFA8BBiMiLwEmNTQ3NjsBNSMVFAcGIyIvASY1ND8BNjMyFxYdATM1IyInJjU0PwE2MzIfARYVFAcGKwEVMzU0NzYzMh8BFhUEAAuSCw8QCgrcSQ8LCwuSCw8PC5ILCwsPSdwKChAPCpMLC5MKDxAKCtxJDwsLC5IMDg4MkgsLCw9J3AoKEA8LkgsBwA4MkgsLCw9J3AoKEA8KkwsLkwoPEAoK3EkPCwsLkgwODgySCwsLD0ncCgoQDwuSCwuSCw8QCgrcSQ8LCwuSCw8AAAIAAP/ABAADwAAyAFIAAAEVFAcGIyEiJyY1ETQ3NjchMhcWHQEUBwYjISIHBgcRFBcWFyEyNzY9ATQ3NjsBMhcWFRMRFAcGBwYvAQEGIyIvASY1NDcBJyY1NDc2MyEyFxYXAyUwMEX+JUUwMDAwRQGSBwYFBQYH/m4mGxoBGxwlAdsmGxoFBQkkCQUF2wsMDg4LZf6LBQgIBEIGBgF1ZAwMCw4BJA8LCgEBZLZFMDAwMEUB20QwMAEFBQglCAYFGhsm/iUmGhsBHBsltgkFBQUFCQHu/twPCwoBAQxl/osGBkIFBwcGAXVkDA4ODAsLDA4AAAACAAD/wAMkA8AAFAAoAAABISIHBgcRFBcWFyEyNzY1ETQnJiMXERQHBiMhIicmNRE0NzY3ITIXFgKA/iQlGxsBHBwkAdwlGxsbGyWkMDBE/iREMDAwMEQB3EMxMQMJGxsl/iQlGxsBHBwkAdwlGxtb/iREMDAwMEQB3EMwMAExMQAAAAACAAD/wALbA8AABQAnAAABIREBHwETMhcWFxYXERQHBgcGIyIvAQcGIyInJicmNRE0NzY3NjMhApL9twElM/EIDAwUCgoBCwsTCg4cFfv8FRsNDBMLCwsLEwwNAlgDJ/06ARkw6QMQBQkPDxX9IBQQEAgEE/HxFAUIEBAUAuAUEBAIBQABAAD/wAMiA8AAFgAAARYHAREUBwYjIi8BJjURASY3NjMhMhcDIgkS/ucXBwcPC5IK/uYSCgkZAtsXCwM8FxH+5v5YFwoDC5IMDgEVARoRFxYWAAABAAD/wANuA8AASwAAAQcXNzYXFhURFAcGIyEiJyY/AScHFxYHBiMhIicmJxE0NzYfATcnBwYjIicmNRE0NzYzITIXFg8BFzcnJjc2MyEyFxYHERQHBiMiJwLdyspSEhYXCgsQ/wAYCQoRU8vKUhEJChj/AA8LCgEXFhJSyspSDA4HBxcLDA4BABgKCRFSystTEQoJGAEADwwLARcHBw4MAovLy1ITCwkY/wAPCwsXFhFTy8tTERYXCwsPAQAYCQsTUsvLUgsDCRgBAA8LCxcWEVPLy1MRFhcLCw//ABgJAwsAAAAFAAD/wAQAA8AAJwAqAC0APgBIAAABMhcWFxEUBwYHISInJic1ISInJicRNDc2PwE2NzY7ATIXFhcVNjsBBQczAQczFzc1IxUUBwYHIxEhNTQ3NjcBESMVFAcGJyMRA8kXEA8BEBEW/dwYDw8B/skXEA8BCwwQ6RAbHBftGA8PASci7v7Jq6v+k6urb7XbEA8Y7gElCwsQAiPcDxAX7gLlERAW/UkXEA8BEBEWpBEQFgGAFxwbEOkQDAsQERa8GHqrAYarx7Xu7hcPEAH+k5IXGxwP/jUCku0XEBEB/pIAAAMAAP/AA24DwAATACgAPAAAJRUUBwYHISInJic1NDc2NyEyFxYDFRQHBichIicmJzU0NzYXITIXFgcRFRQHBiMhIicmJzU0NzYXITIXFgNuCgsQ/NwPCwoBCwwOAyQPDAsBCgsQ/NwPCwoBCwwOAyQPDAsBCgsQ/NwPCwoBCwwOAyQPDAvASQ8KCwEMCw5JDwsKAQsMARdKDgwLAQoLD0oOCwwBCwoPASRJDgwLCwwOSQ8LDAELCgAK////wAO3A8AAEwAnADsATwBjAHgAjAChALYAygAAJTU0JyYrASIHBgcVFBcWOwEyNzY9ATQnJisBIgcGBxUUFxY7ATI3NgU1NCcmKwEiBwYdARQXFjsBMjc2ATU0JyYrASIHBgcVFBcWOwEyNzYFNTQnJisBIgcGHQEUFxY7ATI3NgU1NCcmKwEiBwYdARQXFjsBMjc2NQE1NCcmKwEiBwYdARQXFjsBMjc2BTU0JyYrASIHBh0BFBcWOwEyNzY1PQE0JyYrASIHBh0BFBcWOwEyNzY1NxEUBwYjISInJjcRNDc2NyEyFxYBJAUFCLcIBQUBBgYHtwgFBQUFCLcIBQUBBgYHtwgFBQEkBQUHuAgFBQUFCLgHBQX+3AUFCLcIBQUBBgYHtwgFBQEkBQUHuAgFBQUFCLgHBQUBJQUFCLcIBQUFBQi3CAUF/tsFBQe4CAUFBQUIuAcFBQElBQUItwgFBQUFCLcIBQUFBQi3CAUFBQUItwgFBUocHCT9ACUcHAEbGyYDACUbG4ltCAYFBQYIbQgGBQUG424IBQUFBQhuBwUGBgXUbQgGBQUGCG0IBgUFBgG/bggFBQUFCG4IBQUFBdRuCAUFBQUIbgcFBgYF1G0IBgUFBghtCAYFBQYIAbduCAUFBQUIbggFBQUF1G4IBQUFBQhuBwUGBgUH3G4IBQUFBQhuCAUFBQUItv2TJhsaGhsmAm0mGxoBGxwAA////8ADtwPAAAgAEQAmAAA3IREhERQXFjclESERITI3NjUTERQHBgchIicmNxE0NzY3ITIXFhdbAVz+kQYGBwMS/pIBXAgFBUocHCT9ACUcHAEbGyYDACUbGwFSApP9gAcGBwETAoD9bQYFCAK2/UomGxoBGxwlArYmGxoBGxwlAAAAAgAA/8ACSQPAABIAJQAAARQHAQYjIicBJjU0NzY3ITIXFicUBwYjISInJicmNwE2MzIXARYCSQr/AAwODgz/AAsLDA4CAA4MCwEKCw/+AA8LCgEBDAEACw8PCwEACgFSDwr/AAsLAQAKDxAKCgELC80PCwsLCw8OCwEACwv/AAoAAAAAAQAA/8ACSQPAABIAAAEUBwEGIyInASY1NDc2NyEyFxYCSQr/AAwODgz/AAsLDA4CAA4MCwJADwv/AAsLAQALDw8LCgELDAAAAQAA/8ACSQPAABIAAAEUBwYjISInJicmNwE2MzIXARYCSQoLD/4ADwsKAQEMAQALDw8LAQAKAUAODAsLDA4ODAEACwv/AAsAAgAA/8AEAAPAACAATQAAAREUBwYHISInJjcRFhcWFxYXFhcWNzMyNzY3Njc2NzY3NRQHBgcGBwYHBgcGBwYHBicjIicmJyYnJicmJyYnJicmJyYnNDc2MyEyFxYHBAAbGib8tiUbHAEaH89OIRMUIyIcAh0hIhUUIGG8IBkcGyrXNgUSEwwMEhEPEA0CDBAPERINDRIRBjViYhMkHh8BGBcsA0olGxwBAk/+OyYbGgEbHCUBxRsXjDgZDQ4ODgENDQ8OGEV/FxuoLSkpHZYkBA0NCgkJCQYHAQYFCgoICQ4OAyREQw8XKiolLB4dGhsmAAAAAAEAAP/ABAADwABnAAAlFRQHBisBIicmPQE0NzYXMzUhFTMyFxYXFRQHBisBIicmJzU0NzYXMzUhFTMyFxYXFRQHBisBIicmJzU0NzYXMzU0NzYXITUjIicmJzU0NzY7ATIXFhcVFAcGByMVITIXFgcVMzIXFgQAEBEWtxYQEREQFjf+3DYYDw8BEBAXthgPDwEQEBc2/tw3Fw8QAREQFrcXEA8BEBEWNxUWHgEkNhgPDwEQEBe2GA8PARAQFzYBJB0XFgE3FxAP97cXEBAQEBe3FxARAW1tEA8YtxcQEBAQF7cXEBEBbW0QDxi3FxAQEBAXtxcQEQFtHhYXAW0REBa3FxAQEBAXtxcPEAFtFhUfbRAPAAQAAP/ABAADwAAKAB4AIQBEAAAlIREjIicmJzUjERM1NCcmJyEiBwYXFRQXFjchMjc2EzMnBREUBwYHISInJic1ISInJicRNDc2NyEyFxYHFRYfARYXFhUBtwIA7hcPEAHbkgUGB/5uBwYHAQYFCAGSBwYFkqurASUQERb93BgPDwH+yRcQDwEQERYCbhYREAEMCekQDAsJAW4QDxjt/W4DNyUHBQUBBgYGJQcGBgEFBf6Iq/T+gBcQDwEQERZbERAWAwAXEA8BEBEWvAcI6g8cGxcAAgAA/8AEAAPAAB4APQAAARUUBwYHIRUUBwYHIi8BJjU0PwE2MzIXFh0BITIXFgMUDwEGIyInJj0BISInJjc1NDc2MyE1NDc2MzIfARYEAAUFCPztBQUIBgi2BQW3BgcIBQUDEwcGBgEFtwYHCAUF/O0HBgYBBQUIAxMFBQgGCLYFAUBuBwUFAW4HBQUBBrYHBwgFtgUFBQhuBQUBLwgFtgYGBgZuBgYGbggFBW4IBQUFtgYAAgAA/8AESQPAAB8AQgAAATQnJisBNTQnJisBIgcGHQEjIgcGFRQfARYzMj8BNjUFFAcGByEiJyY3NDc2NyY1NDc2MzIXFhc2MzIXFhUUBxYXFgLbBQUIgAUFCG4HBQaACAUFBckFCAgFyQUBbkA/XP2SaUxMASgoRAFWVnhaSUoiKTY8KysXSjAwAYkIBQXJCAUFBQUIyQUFCAgGyAUFyAcHgFtAPwFKS2tJQD8fEQh4VlYyMlIkKys8LCMSPD0AAgAA/8AESQPAAB4AQQAAATQvASYjIg8BBhUUFxY7ARUUFxY7ATI3Nj0BMzI3NgUUBwYHISInJjc0NzY3JjU0NzYzMhcWFzYzMhcWFRQHFhcWAtsFyQUICAXJBQUFCIAGBQduCAUFgAgFBQFuQD9c/ZJpTEwBKChEAVZWeFpJSiIpNjwrKxdKMDABrggFyQUFyQYHCQUFyQgFBQUFCMkFBZxbQD8BSktrSUA/HxEIeFZWMjJSJCsrPCwjEjw9AAAABAAA/8AEAAPAAAQAEQAhAC4AAAEhNSEVIxEjIicmNRE0NzY7ASERIREzNTQ3NjMhMhcWBxUFERQHBisBETMyFxYVAW4BJP7cySU0JiYmJjQlAoD9tkoPEBcBShYREAEBJSYmNCUlNCYmAuVJSf0kJiU1Adw0Jib9JALcWxcQEBAQF1uA/iQ1JSYC3CYmNAAAAgAA/8AD2wPAABAASwAABTQjIicmNzQjIhUUFxY3MjUlFAcGIyEUBwYjIicmNSEiJyY1Njc2NzY3Njc2NzQ3NjcmNTQ3Njc2FxYVFAcWFxYXFBcWFxYXFhcWFwIJCSIYGQEJCR0eKQkB0hUWHv8AKys8PCsr/wAeFhUdFxgYGRITCQkCRENsBRAQFxcQEAVtQkMBCwsSERkYGRkaCQgZGSEKCiodHgEJpB4VFjwrKysrPBYVHhkZGisrMDBGRU9WS0sQCgwXEA8BARESFQwKEEtLVlBERTExKiobGhgAAAAGAAD/wANuA8AAGAAfACoAPwBTAGcAAAEWFxYVERQHBgchIicmJxE0NzY3ITIXFhcHFTMmLwEmExEjIicmJzUhESEBNDc2MyEyFxYdARQHBiMhIicmPQEFMhcWHQEUBwYjISInJj0BNDc2MwUyFxYdARQHBiMhIicmPQE0NzYzA0cQDAsQDxf9ABgPEAEREBcCABYcGxBM1wUHtAbL7RgPEAH+SQLc/bYFBggBkggGBQUGCP5uCAYFAaUIBgUFBgj+bggGBQUGCAGSCAYFBQYI/m4IBgUFBggC5xAbGxj9bhcQDwEQERYDkhcQDwELDBAn1xIGswf8nAJJERAW7vySAe4HBgUFBgclCAUFBQUIJYAFBQglCAUFBQUIJQgFBZIFBQkkCQUFBQUJJAkFBQAAAgAA/8ADbgPAACwAQAAAATU0JyYHIzU0JyYnIyIHBgcVIyIHBgcVFBcWNzMVFBcWOwEyNzY3NTMyNzYnExEUBwYHISInJjURNDc2NyEyFxYC2woKD7gLCw9IEAoKAbYQCgoBCwsPtgsLD0gQCgoBuA4LCwGTMDBF/dxFMDAwMEUCJEUwMAGbSg4LDAG3DwsKAQsMDrcLCg9KDgsMAbcODAsLDA63CwoPATf93EQwMAExMUMCJEQwMAExMQACAAD/wAI4A8AAGQAzAAAlFA8BBiMiJwEmNTQ3ATYzMh8BFhUUDwEXFhcUDwEGIyInASY1NDcBNjMyHwEWFRQPARcWAV0GHAYHBwb+9gYGAQoFCAgFHAYG4OAG2wUcBggHBv72BgYBCgYHCAYcBQXh4QXSBwYdBQUBCwUHCAYBCgYGHQUICATi4AYHBwYdBQUBCwUHCAYBCgYGHQUICATi4AYAAAIAAP/AAjgDwAAZADMAAAEUBwEGIyIvASY1ND8BJyY1ND8BNjMyFwEWFxQHAQYjIi8BJjU0PwEnJjU0PwE2MzIXARYBXQX+9QUHCAYcBgbg4AYGHAUJCAQBCwXbBf72BgcHBxwFBeDgBQUcBwcHBgEKBQG/BwX+9QUFHQYHBwbg4gUHBwYdBgb+9gUJBwX+9QUFHQYHBwbg4gUHBwYdBgb+9gUAAgAA/8ACZgPAABkAMwAAJRQPAQYjIi8BBwYjIi8BJjU0NwE2MzIXARY1FA8BBiMiLwEHBiMiLwEmNTQ3ATYzMhcBFgJmBh0FBwgG4eAFCQgEHQYGAQsFBwcGAQsGBh0FBwgG4eAFCQgEHQYGAQsFBwcGAQsG2wcGHQUF4OAFBR0GBwcGAQsFBf71BtQHBh0FBeLiBQUdBgcHBwEKBgb+9gcAAAACAAD/wAJmA8AAGQAzAAABFAcBBiMiJwEmNTQ/ATYzMh8BNzYzMh8BFjUUBwEGIyInASY1ND8BNjMyHwE3NjMyHwEWAmYG/vUFCAgE/vUGBh0FBwgG4OEFCQgEHQYG/vUFCAgE/vUGBh0FBwgG4OEFCQgEHQYByQcG/vYGBgEKBgcHBxwFBeHhBQUcB9QHBv72BQUBCgYHCAYcBgbg4AYGHAYAAAEAAP/AAV0DwAAaAAABFA8BFxYVFA8BBiMiJwEmNTQ3ATYzMh8BFhUBXQbg4AYGHAYHBwb+9gYGAQoFCAgFHAYCrQcF4uAGBwcGHQUFAQsFBwgGAQoGBh0FCAAAAQAA/8ABXQPAABkAAAEUBwEGIyIvASY1ND8BJyY1ND8BNjMyFwEWAV0F/vUFBwcHHAYG4OAGBhwGCAgEAQsFAb8HBf71BQUdBgcHBuDiBQcHBh0GBv72BQAAAAABAAD/wAJmA8AAGQAAARQPAQYjIi8BBwYjIi8BJjU0NwE2MzIXARYCZgYdBQcIBuHgBQkIBB0GBgELBQcHBgELBgFJBwYcBgbg4AYGHAYHBwYBCgYG/vYFAAAAAAEAAP/AAmYDwAAaAAABFAcBBiMiJwEmNTQ/ATYzMh8BNzYzMh8BFhUCZgb+9QUICAT+9QYGHQUHCAbg4QUJCAQdBgI2BwX+9QUFAQsFBwcHHAYG4OAGBhwGCAAABAAA/8AESQPAABQAKQA3AEEAADciJyY1ETQ3NjMhMhcWFxEUBwYjIQMRFBcWNyEyNzY1ETQnJichIgcGBwEzFRQHBgchIicmNzUhBTI1NCsBIhUUM+4mGxoaGyYCbSYbGgEbHCX9kxMGBwYCbQgGBQUGCP2TBwYFAQMTWxsaJvxtJRscAQPu/mQJCVsJCeUaGyYBkiYbGxsbJv5uJhsaAe3+bgcGBgEFBQgBkggFBQEGBgf97jcXDxABERAWNzcJCQkJAAIAAP/AA24DwAAXAC8AAAEiBwYHBgcGFxYXFjMyNzY3NicmJyYnJgEUBwYHBiMiJyYnJicmNzY3NjMyFxYXFgG3VUdIKSkBASsrRkVXV0VFLCwCAigoSUkBZDs6ZmV3dmdmOTgDAz4/YGB9fV9gQEEC9yoqR0hUVEhHKioqKkdIVFRIRyoq/sl4ZGU7Ozs7ZWR4eGRlOzs7O2VkAAL////AA7cDwAAsAFkAAAEVFAcGKwEiJyY3ETQ3Njc2NzY7ATIXFgcVFAcGJyMiBwYdARQXFjsBMhcWFyEVFAcGKwEiJyY3ETQ3Njc2NzY7ATIXFgcVFAcGJyMiBwYdARQXFjsBMhcWFwG3ISEt2y0hIQEYFycnNzY7JA8MCwEKCxAkPCsrEBEVgC4gIAECACEhLdstISEBGBcnJzc2OyQPDAsBCgsQJDwrKxARFYAuICABAXbbLiAfHyAuAZM7NjcmJxgXCwsOSg4MCwErKzwTFhEQICAu2y4gHx8gLgGTOzY3JicYFwsLDkoODAsBKys8ExYRECAgLgAAAAL////AA7cDwAAsAFkAAAERFAcGBwYHBisBIicmPQE0NzY3MzI3Nj0BNCcmJyMiJyY3NTQ3NjczMhcWFyERFAcGBwYHBisBIicmPQE0NzY3MzI3Nj0BNCcmJyMiJyY3NTQ3NjczMhcWFwG3GBcnJzc2OyUODAsLDA4lPCsrEBEWgC0hIQEgIC7bLiAgAQIAGBcnJzc2OyUODAsLDA4lPCsrEBEWgC0hIQEgIC7bLiAgAQLk/m47NjcmJxgXCwsOSQ8LCgErKzwSFxAPASAgLtsuIB8BICEt/m47NjcmJxgXCwsOSQ8LCgErKzwSFxAPASAgLtsuIB8BICEtAAgAAP/AA9sDwAAPAB8ALwA/AE8AXwBvAH8AACUUBwYjIicmNTQ3NjMyFxYFFAcGIyInJicmNzYXFhcWARQHBgcGJyYnJjc2FxYXFgEUBwYjIicmNzY3NhcWFxYBFAcGIyInJjU0NzYzMhcWARQHBgcGJyY3Njc2FxYXFgEUBwYjIicmNTQ3NjMyFxYFFAcGByInJic0NzYzMhcWAS0VFh8dFhUVFh0eFxYBGxUUICATFAICGBccHBgZ/moVFh4fFRQBARYXHRwYFwKsFRYdHxYVAQETFCEgExL93BobJiYaGxsaJiYbGgKdFRYeHRcWAQEUFR8gFBP+lSAgLi4gICAgLi4gIAEvJiY0NiQlASYlNTQmJpEeFRYWFR4fFRYWFZUeFRYWFR4eFhcBARUUAXMfFRQBARYXHRwYFwMDERL+wR4VFhYVHh4WFwEBFRQCGSYaGxsaJiYbGhob/r4fFRQBARYXHRwYFwMDERIBcC4gICAgLi4gICAgpDUlJQEmJjQ0JiYmJgAAAQAA/8ADbgPAABcAAAEUBwYHBiMiJyYnJicmNzY3NjMyFxYXFgNuOzpmZXd2Z2Y5OAMDPj9gYH19X2BAQQHAeGRlOzs7O2VkeHhkZTs7OztlZAAAAQAA/8AEAAPAADwAAAEUBwYHBgcGBwYjIicmNTQ3Njc2NTQnJicmJyYnJicmJyYrARUUBwYjIicBJjU0NwE2MzIXFgcVMyAXFhUEAEkBBQUCAgUHCggFBQEBAQMKChIRHRwgICwsLCw4gAsKEBEJ/twLCwEkCw8ODA0CgAGXXB8BLl+jBAkJCQgECgYGCAULCgMnIDkuLiEhGBkPEAkJAwOSDwsLCwElChAPCgElCgoKEJLmTXIAAAL////AA7cDwAAdADgAACURNCcmByEiJyYnNTQnJgcjIgcGFREUFxYzITI3NhMRFAcGIyEiJyY1ETQ3NjsBMhcWHQEhMhcWFQNtDxAX/m0XEA8BDxAXuBYREBARFgK4FhEQSSYmNP1INCYmJiY0uDQmJgGANCYmrgGSFxAQAREQFyQXEBEBEA8Y/dwXEBEREAGp/m41JiUlJjUCJDUmJSUmNRImJjQAAAMAAP/ABEYDwAAUADAAVQAAATQjISIHBg8BBhUUMyEyNzY/ATY1JSE1NCcmByEiJyYnNTQnJgcjIgcGFRE3Njc2MwUUDwEGBwYjISInJjURNDc2OwEyFxYdASEyFxYXFTMyFxYXFhUD/R/9kxcaGw2oCx4CbhcaGg+oCv10AbcQERb+txcQDwEQDxe4FhEQkhopKScC1RqpGCoqJv2SNCYmJiY0uDQmJgE2NSUlAW0fGxoMCAGIEwwMEtANCRUODRDQDAtcXBcQEAEREBckFxARARAPGP4Zsx8TFFwkIdAfExMlJjUCJDUmJSUmNRImJjRcDQ4bEhQAAgAA/8ADswPAABkALQAACQEGIyIvASY1ND8BJyY1ND8BNjMyFwEWFRQBFRQHBiMhIicmPQE0NzYzITIXFgFL/vQFBwcGHQYG4OAGBh0FCAgEAQwFAmMFBQj92wgGBQUGCAIlCAUFAcn+9QUFHQYHBwbh4QUHBwYdBgb+9gUICf72JAgFBQUFCCQIBQYGBQAAAwAA/8AELwPAABkALQBHAAAlBwYjIicBJjU0NwE2MzIfARYVFA8BFxYVFAEDBgcGLwEmJyY3EzY3Nh8BFhcWCQEGIyIvASY1ND8BJyY1ND8BNjMyFwEWFRQBYBwFCAcG/vYGBgEKBQgJBBwHB+DgBwFL1QIHBwYjCAMDAdYCBgYHJAcEBAF1/vYGBwgGHAYG4OAGBhwGCAcGAQoFxR0FBQEMBQcHBgELBgYdBQgJBOHgBggHAlz9HgcEBAMJAwYGCQLhCAMDAQoCBwf+hv70BQUdBgcIBuDhBQgHBh0GBv71BQgIAAAAAAIAAP/ABAADwAAXAEMAAAEVFAcGIyInASY1NDcBNhcWHQEHBhUUFwUUBwYHBgcGDwEGIyInJjc2JyYnJicVFAcGIyInASY1NDcBNhcWHQEWFxYVAW4XBwcQCv7cCwsBJBIWF+MLCwN1CQkODQ4PCAsFDAMCDgEZVSU9PF0WCAYPC/7bCwsBJREXFutsYAFDKBcLAwsBJQsPDwsBJBIJCxco4wwODgz4ISsrJCQkJBAXCgEEEOReKRcWB48XCwMLASULDw8LASQSCQsXlw9vYsAAAAAAAQAA/8ADJAPAABwAAAkBBiMiJyYnJicRISInJicmNzY3ATYzMhcWFxYHAyH+kgoWAwUOBwcB/rcNCQoEBAYHCwLbBwkQCgkBAQQDHf0lFAEDCgoMAUoHBw4NCgsHAW0ECggMDQoAAAAEAAD/wAJJA8AADwAgADAAeQAANzQnJgcGBwYXFhcWFxY3NhM0JyYnJgcGFxYXFjMyNzY3BTQnJiMiBwYXFhcWMzI3NjcUBwYHBgcGBwYHBh0BFhcWBxQHBgcGJyY1NDc2NxEmJyYnNDc2NzYXFhUUBwYHETY3Njc2NzY3Njc2NzYnJicmJzQ3NjMyFxalEBEWFxARAQEPDhkYDw4CEBEWFxARAQEPDhkYDw4CAW4REBcWERABAQ4PGBkODzgODxkBgCdNShcYGQ8PAR8gLi4gIBAPGBkODwEgIC4uIB8ODhofOR8TFBQVDQ0KCQcHAhoODgEfIC4uICB3FxARAQEPDhkYDw4CAhITAqYXEA8BARESFRYQEREQFkkXEBAQEBcXEBAQEBceGRoOpEkVGRYSESgPDxkaHS4gHwEBISIsHhkYEAHUDxkaHS4gHwEBISIsHhkYEP7lDhIKBwcKCwwMEhEWFR8OGhkeLiAgICAAAAj////AA7cDwAASACUANwBUAHEAhACWAKgAADcHBiMiJyY1ND8BNjMyFxYVFAcXFRQHBiMiJyYnNTQ3NjMyFxYHJxQHBisBIicmNTQ3NjsBMhcWBRQPAQYjIi8BJic3FxYzMj8BNjU0LwE3Fh8BFhUBBycmIyIPAQYVFB8BByYvASY1ND8BNjMyHwEWFwUUBwYrASInJjU0NzY3MzIXFhUBFRQHBiMiJyY9ATQ3NjMyFxYXBwYjIicmNTQ/ATYzMhcWFRT6kgYIBwUGBpIGBwcGBQVgBQUICAQEAQUFBwcGBwKABQUItggGBQUGCLYIBQUC0zFUL0RGL78MDImcDxgXEFMREZwKFQvAMP6fiJwQFxYRUxERnAoVDL8wMFQwREUwvwwLAWsFBgi3CAUGBgUItwgGBf7IBQUICAUGBgUICAUF6ZMGBwcFBQWSBQcIBgXGkwUFBggHBpEFBQUHBwYYtwgGBQUGCLcIBQYGBQiACAUFBQUICAUGBgVSQzBTMDG/DBQKnBAQUhEVGA+eiAsMwTFEAZ4KnBEPVBAWFxCdiQwMwDFERC9ULzC/DBUvCAUFBQUICAQEAQUFBwE2tggFBQUFCLYIBgUFBl6SBQUGBwcGkwUFBgcIAAAAAgAA/8ACLAPAABMATwAAJRUUBwYHIyInJj0BNDc2FzMyFxYTFAcGBwYHBgcGBwYHBhUUBwYHIyInJj0BNDc2NzY3NjU0JyYnIgcGBwYjIi8BJicmNzYzMhcWFxYXFhUBeAcHCIoJBwcHBwmKCQYGtQgIDA0TFA0NFhcQDwcHCokIBgYmJishDw4bGiMlGBUpBwoIB10IAQEEW64uLi4lJRgX8okJBgcBCAcIiQkIBwEGBwFNHxobERIQEAoJCg0ZGA4KCAgBCwsJGy8qKhMREBEaGRESAREOMwkERwYJCAiYEhEeHiwsLgAAAAACAAD/wAFuA8AAJgA6AAAlFRQHBgchIicmJzU0NzY3MzUjIicmJzU0NzY3MzIXFhcRMzIXFgcDFRQHBgcjIicmPQE0NzY7ATIXFgFuCgsQ/twPCwoBCwwOJCQPCwoBCwwO2xAKCgEkDwwLAUkLCw+SDwsLCwsPkhAKCptJDwoKAQsLDkkPCwoB2wsMDkkPCgsBDAsO/rcLDA4Ck24PCwoBCwwObg4LCwsLAAAAAgAA/8ABNgPAABMAJwAAJRUUBwYHIyInJj0BNDc2FzMyFxYTAwYHBicjIicmJwMmNzY7ATIXFgElDAsOkw4LDAwLDpMPCgsSEAEMCw6TDgsMAQ8BCwwNtw4MC9KADwoKAQsLDoAPCwsBCgoCTP5IDgsMAQsKDwG4DgsLCwsAAAAC////wAKSA8AAOQBMAAABFRQHBgcVMzIXFhcWBwYjISInJicmNzY7ATUmJyY3NTQ3Njc2FxYHFRQXFjc2NzYnNTQ3Njc2FxYVJxEUBwYHBicmJxE0NzYXFhcWBwKSVFR9khAKCgEBDAwO/pMQCgoBAQwMDpJ8VVUBDAsODgwLAUxMaGhNTQILDA4OCwyTNTVNTTQ0ATU1TEw2NgECCUh/Xl0NTAsLDw4LDAwLDg8LC0wNXV5/SBAKCgEBDAwOSGpMTAIBSUpsSBAKCgEBDAwO2/7dTDY1AQE3OEoBI0w2NwEBNTROAAAAAwAA/8ADHQPAAA8AWABiAAATByY9ATQ3Njc2FxYdARQXAQcVFAcGByInBxYzMjc2JzU0NzY3NhcWBxUUBwYHFTMyFxYHBgcGIyEiJyY3Njc2OwE1JicHBiMiLwEmNTQ3ATYzMh8BFhUUBycBETQ3NhcyFxaaORkMCw4ODAsIAn3PNTVMIB43OD1pTEwBCwwODgsMAVRUfJEQCwsBAQkJEv6TDwsLAQEJCRGSSD6RBggIBC8GBgLBBgcHBi8GBtn+nTY2SzovMAGAOjtASBAKCgEBDAwOSB8iAVjPSEw2NQELNxxKS2tIEAoKAQEMDA5If15dDUwLCw8OCwwMCw4PCwtMByeRBwcvBQgIBALCBgYvBQkIBEv+ngEjTDY3ASIiAAAAAAT////AA7cDwAAEABgALABZAAA3IREhERM1NCcmKwEiBwYdARQXFjsBMjc2JTU0JyYrASIHBh0BFBcWOwEyNzY3ERQHBiMhIicmNRE0NzY7ATU0NzY7ATIXFh0BMzU0NzY7ATIXFgcVMzIXFhdIAyX829wFBQglCAUGBgUIJQgFBQG2BQUIJAgFBQUFCCQIBQXdFxYd/NseFRYWFR5KGhsmJSYaG9scGyUkJhwbAUkeFRYBCQJJ/bcCt6UIBQUFBQilCAUFBQUIpQgFBQUFCKUIBQUFBS39JB4VFhYVHgLcHhUWNyYaGxsaJjc3JhobGxomNxYVHgAAAf///8ACkgPAADAAAAEyFxYXERQHBgchIicmJxE0NzYXMzU0NzYXFhcWBxQHBisBIicmNTQnJiMiBwYXFSECWhgPEAEREBf93RgPEAEREBcRTExoaE1NAgoKECUOCwwrKzw8KysBAaMBvw8PGP62Fg8QAREQFQFKFxARArhpTEwBAUpKaw8LCwsLDzwrKysrPLgAAAMAAP/AAyQDwAATACcAOwAAExUUBwYnIyInJic1NDc2NzMyFxYFFRQHBicjIicmNzU0NzY3MzIXFgUVFAcGJyMiJyY9ATQ3NjczMhcW2xAPGG0YDw8BEBAXbRcQEQEkERAXbRcQEQEQDxhtGA8QASUQEBdtFxARERAXbRgPDwH2bRcQEQEQDxhtGA8QAREQF20XEBEBEA8YbRgPEAEREBdtFxARARAPGG0YDxABERAAAwAA/8AA2wPAABMAKAA8AAA3FRQHBgcjIicmJzU0NzYXMzIXFgMVFAcGJyMiJyYnNTQ3NjczMhcWBxEVFAcGKwEiJyYnNTQ3NjsBMhcW2w8QF24XEA8BEBEWbhYREAEPEBduFxAPARARFm4WERABDxAXbhcQDwEQERZuFhEQ0m4XDw8BEBAWbhcQEQEQDwEMbRcQEQEQDxhtGA8QAREQFwElbRcQEREQF20XEBAQEAACAAD/wANuA8AAEwAnAAABNTQnJgchIgcGBxUUFxY3ITI3NhMRFAcGByEiJyY1ETQ3NjchMhcWAtsKCg/+ABAKCgELCw8CAA4LC5IwMEX93EUwMDAwRQIkRTAwAZtKDgsMAQsKD0oOCwwBCwoBRv3cRDAwATExQwIkRDAwATExAAIAAP/AA24DwAAaAC4AACUBNjU0LwEmIyIHAScmIyIPAQYVFB8BFjMyNwERFAcGByEiJyY1ETQ3NjchMhcWAYcBYAsLOwsODwv+9XkKEA8KOwoKzQsPDgsB5zAwRf3cRTAwMDBFAiRFMDDaAV8KDxAKOgwM/vV5Cws6Cw8PC8wLCwH4/dxEMDABMTFDAiREMDABMTEAAAAAAgAA/8ADbgPAAB0AMQAAARE0JyYnISIHBh8BAQYVFB8BFjMyNwEXFjMyNzY1ExEUBwYHISInJjURNDc2NyEyFxYC2woKD/7tGAoKElL+zwsLOwsODwsBMVMKEAYIFZMwMEX93EUwMDAwRQIkRTAwAa4BEg8LCgEXFxFS/s8LDxAKOgsLATFSCwMKGAEk/dxEMDABMTFDAiREMDABMTEAAAMAAP/AA24DwAAPACMANwAAARQHBQYnJjURNDc2FwUWFRMRNCcmIyEiBwYVERQXFjMhMjc2ExEUBwYHISInJjURNDc2NyEyFxYCbhD/ABEUFBQUEQEAEG0FBQj93AgFBQUFCAIkCAUFkzAwRf3cRTAwMDBFAiRFMDABwBIMtwwKCRcBbhcJCgy3DBL+7gIkCQUFBQUJ/dwJBQUFBQIt/dxEMDABMTFDAiREMDABMTEAAQAA/8ACRQPAAHsAACUXFgcGByMGBwYHBgcGBwYjIgcGJyYHIicmJyMiJyY3NTQ3NjczJjcjIicmPQE0NzY7ATY3NjcyFxYXFg8BBgcGLwEiLwExJyYjIicmIyIHBgchMhcWDwEGIyEGFyEyFxYPAQYHBisBFhcWNzI3Njc2NzY3Nj8CNhcWFwIxFAIDAwcDAgUEBQUHBwcICQkKCgwLCoZkYyU2BwYHAQYFCCYBASYIBQYGBQg4JmRlgTo0BgYEAhkCBgYHAgQECgwMBAMNDQNJODkdAQsJBQYCDQMP/ugBAQEHCAYFAQ8BBQUG3Rs7OkgKCgsJCQcHBwgDBwMHBwcCsVsIBgYCAQEBAgIBAQICAwMBAQFKS34FBQlABwUGAR8cBQUIQggFBXhJSQEOAgcGB1sIBAQDAQECAgICASUlQAcHCEEPFSYIBwhBBgQEQigoAQEBAQEBAQICAQECAgQDCAABAAD/wAIvA8AAjQAAARQHBgcVFAcGKwEiJyY3NSYnJicmJyYnJicmPwE2NzYfARYXFjMyNzY3NCcmJyYnJicmJyYnJicmJyYnJicmJyYnJicmNTQ3Njc1NDc2FzMyFxYdARYXFhcWFxYXFhcWDwEGIwYnJicmJyYnJicmIyIHBhcUFxYXFhcWFxYXFhcWFxYXFhcWFxYXFhcWBwIvOTpaBQUITQcGBgEmIyMXGBITCAgCCgk7AwkKBQFAShUWLiMjAQoJCQkZGA4NIRUODRUWDg8SEgwLDg8GBgUFODlZBQUITQgFBSEfHhMSExIDAwYKBjAECAgHAgcIDg4UExgXGTYjIwEEBA4NCQoWFwwMHB8PDx0dDg4VFAoLCAgBARtYPj8QZAgFBQUFCGQFDQ0NDA4PBwcDDAxNBgEBBwE4DwQYGS0QDw4JCQ0MBgYNCQUFCgoIBw0NDAsQERAQFhYXTzs8EWYIBgYBBQUJZAMKCgoJCwsHBgELC1MJAgYCBQUJCQoJBgYYGScODg0KCgkICgoFBQsLBgYPDgoKExISERsaGwACAAD/wANuA8AABgAdAAABERYfARYXBRQXFhchERQHBgchIicmJxE0NzY3IRECSQ0I6QgI/qkREBcBNhAPF/0AGA8QAREQFwHIApsBDggI6QgNEhcPEAH9pRcQDwEQERYDkhcQDwH+yQAAAAAEAAD/wAOtA8AACwAoAEgAWAAAATMvASY1IwcwBwYHARQPAQYjIi8BJjc2OwERNDc2OwEyFxYVETMyFxYFFSE1EzY/ATUiIyIjBisBFSM1IRUDBg8BFTc2OwE1MxMVIzUzJyMHMxUjNTMTMxMCoGUpBgMCAQICA/7TBrYFCQYGtwgEBA1uBQUIbggFBW4IBQUB3f6z0ggFBgECAgMGC4VEAUTTBAgGCAULj0Q0pSsbixsrpCiDXoMC13wbCQILCgoH/TYGCLYFBbcKCgsDEwgFBQUFCPztBQVMhTMBLgwFBQECQoMz/tEECggBAQNDAgE9PVJSPT0Bev6GAAAEAAD/wAOtA8AACwAoADkAWQAAJTMvASY1IwcUBwYHBRQPAQYjIi8BJjc2OwERNDc2OwEyFxYVETMyFxYFFSM1MycjBzMVIzUzEzMTMwMVITUTNj8BNSIHBicGKwEVIzUhFQMGDwEVNzI7ATUzAqBlKQYDAgECAgP+0wa2BQkGBrcIBAQNbgUFCG4IBQVuCAUFAhGlKxuLGyukKINegyg0/rPSCAUGAQICAwYLhUQBRNMECAYIBQuPRI59GgoCDAEJCQeCBgi2BQW3CgoLAxMIBQUFBQj87QUFlTw8UlI8PAF7/oUCk4Y0AS4KBQUDAQICA0GDM/7SBQsFAgJFAAAABQAA/8AD9wPAABwAMQBFAFkAbQAAJRQPAQYjIi8BJjc2OwERNDc2OwEyFxYVETMyFxYFFRQHBiMhIicmPQE0NzYzITIXFhUDFRQHBiMhIicmPQE0NzYzITIXFgMVFAcGByEiJyY9ATQ3NjMhMhcWAxUUBwYrASInJj0BNDc2OwEyFxYBnAa3BQgGBrcJBAUNbQYFCG0JBQVtCQUFAlsFBQj+JAgFBQUFCAHcCAUFbgUFCP6SCAUFBQUIAW4IBQVtBQUJ/wAIBQUFBQgBAAkFBW4FBQiTCAUFBQUIkwgFBYkGCLYFBbcKCgsDEwgFBQUFCPztBQVRbggFBQUFCG4IBQUFBQgBJW4IBQUFBQhuCAUFBQUBHG4HBQUBBgYGbggFBQUFAR1uCAUFBQUIbggFBQUFAAAFAAD/wAP3A8AAEwAwAEQAWABtAAAlFRQHBisBIicmPQE0NzY7ATIXFiUUDwEGIyIvASY3NjsBETQ3NjsBMhcWFREzMhcWJRUUBwYjISInJj0BNDc2MyEyFxYTFRQHBgchIicmPQE0NzYzITIXFhMVFAcGIyEiJyY9ATQ3NjMhMhcWFQKuBQUIkwgFBQUFCJMIBQX+7ga3BQgGBrcJBAUNbQYFCG0JBQVtCQUFAYAFBQn/AAgFBQUFCAEACQUFbQUFCP6SCAUFBQUIAW4IBQVuBQUI/iQIBQUFBQgB3AgFBUBuCAUFBQUIbggFBQUFQQYItgUFtwoKCwMTCAUFBQUI/O0FBdRuCAUFBQUIbggFBQUFARxuBwUFAQYGBm4IBQUFBQEdbggFBQUFCG4IBQUFBQgAAAQAAP/AA1YDwAAPACwAVABpAAAlNCcmJyIHBhUUFxYzMjc2BRQPAQYjIi8BJjc2OwERNDc2OwEyFxYVETMyFxYlFAcGBwYHBgcGIyInJic3FhcWMzI3NjcjBgcGIyInJjc0NzYzMhcWAxUhNTM1NDU0NzUjBwYPASc3MxEzAwcZGSIeEhEVFCcdFBX+oga2BQgHBrcIBAQNbgUFCG4IBQVuCAUFAawHBxARFhciISckGg4KFgkJFRYwHB0JAQsXGBk8JycBKSk/Ri8vEf70XwECAwULIy5tRl/RJR4eARYVICAWFw8QMQYItgUFtwoKCwMTCAUFBQUI/O0FBSAkIiIgHxcWDw4JBARBBAIHISIxDQgIKSk6OyoqNjYBP0FB9wQHBwMJBwgKITJp/ooAAAAEAAD/wANWA8AADwAsAEEAaQAAATQnJgciBwYVFBcWNzI3NgEUDwEGIyIvASY3NjsBETQ3NjsBMhcWFREzMhcWBRUhNTM1NDU0NzUjBwYPASc3MxEzExQHBgcGBwYHBiciJyYnNxYXFjMyNzY3IwYHBgciJyY3NDc2NzIXFgMHGRkiHhIRFRQnHRQV/qIGtgUIBwa3CAQEDW4FBQhuCAUFbggFBQGc/vRfAQIDBQsjLm1GXxAHBxARFhciISckGg4KFgkJFRYwHB0JAQsXGBk8JycBKSk/Ri8vAxskHx4BFRYfIBcWAQ8Q/YUGCLYFBbcKCgsDEwgFBQUFCPztBQWPQkL2BAcGBAkHBwshMWr+iwL3IiIiICAWFw8PAQkFBEEEAgkiIjENBwgBKSk6PCkpATY3AAEAAP/AAbUDwAAaAAAlFg8BBiMiLwEmNzY7ARE0NzY7ATIXFhURMzIBtQQHyAYHCAbKCAUFC4AFBQhuCAUFgAzHCgncBgbcCQoLAskIBQYGBQj9NwAAAAABAAD/wAG1A8AAGgAAAQYrAREUBwYrASInJjURIyInJj8BNjMyHwEWAbUGC4AFBQhuCAUFgA0EBAfIBQgIBssHArkL/TcIBQYGBQgCyQsLCNwGBtwIAAAAAQAA/8AD7gPAABsAAAEVFAcGIyEVFAcGLwEmNTQ/ATYXFh0BITIXFhUD7gYFCP03CwsI3AYG3AkKCwLJCAUGAfhvBwUFgA0FBQjJBQcIB8kJBQUMgAUFBwAAAAABAAD/wAPuA8AAGwAAARQPAQYnJj0BISInJj0BNDc2MyE1NDc2HwEWFQPuBtwICwv9NwgFBgYFCALJCwsI3AYBwggHyQkFBQyABQUHbwcFBYANBQUIyAYHAAAAAAMAAP/AA9wDwAAEAAgAJgAALQERBREDLQEFBREUBwYHBQYjIiclJicmNRE0NzY3JTYzMhcFFhcWAiQBbv6SJQGQ/nD+cgNrCwoS/m0PFBMP/m0RCgsODRUBkwwMDQ0BkxUNDkLHAWyF/lIB7pGRkQL+ShQSEQnbCgrbChARFQG2GBITCJMFBZMIExIABwAA/8AFAAPAAAQACAANABEAFQAZAE0AACU3NQcVAzcnBwE3NQcVAzcnByc3NQcnNycHARUUBwYHBQYjIiclJicGBwUGIyInJSYnJic1NDc2PwE1NDc2NyU2MzIXBRYXFh0BFxYXFgGS29sl6OjmA1Xb2yXm5ugY29sl/Pz8A2oLChP/AA8SEw7/AAICAQP/AA4TEg7/ABMKCwENDBT4DQwTAQAODw8OAQAUDA33FQwNG260XsQBBGNjY/6ZbrRexAEEY2NjRF6ZXkBsbGz+bO4VERIJgAgIgAEBAQGACAiACRIRFe4WEhMIauUWExIIbgYGbgkREhflaggTEgAAAAQAAP/AA24DwAAWAC0ARABfAAABMjc2NxUUBwYHBiMiJyYnJic1FhcWMxEyNzY3FRQHBgcGIyInJicmJzUWFxYzNTI3NjcVFAcGBwYHBicmJyYnNRYXFjMRMhcWFxYHFRQHBgcGIyInJicmJzU0NzY3NjMBt4h1dkQ7OmZndXRoZzg5A0R2dYiIdXZEOzpmZ3V0aGc4OQNEdnWIiHV2RDs6Zmd1dGhnODkDRHZ1iHdlZDw9Ajs6Zmd1dGhnODkDPDtkZXcCCRgZMGEnIiITFBQTIiInYTAZGP5JGRkwYighIhQTExQiIShiMBkZ3BgZMGEnIiITFAEBFhUgIClhMBkYApITFCIhKEkoIiITFBQTIiIoSSghIhQTAAAACAAA/8ADbgPAABgAHwAqAGcAbgCAAI0AlgAAARYXFhURFAcGByEiJyYnETQ3NjchMhcWFwcVMyYvASYTESMiJyYnNSERIQEWFzYzMhcWBxQjBwYjIicmJwYHBiMiLwEwJyY3Njc2NzYXFhU2NzY3JicmNzY7ATIXFgcGBxQdAQYHFhcFNjcGBwYHEwYXNjc0NzY3IjUmNTQnFDEVAzY3IicmJyYnBgcGByUmIxYzMjcwJwNHEAwLEA8X/QAYDxABERAXAgAWHBsQTNcFB7QGy+0YDxAB/kkC3P7aEx0iIVQRCQgBAQMlGyYmJX5iVzMJBw4DBgIFGxwvCAUCHSAnFA0EBAgGEgwNBwsGAQEBByA0/rceMB0VFAjkCQcBAwQBAgEBB0hOVQEGBgMsHQ8gEgkBcg5CKxwIAgEC5xAbGxj9bhcQDwEQERYDkhcQDwELDBAn1xIGswf8nAJJERAW7vySAVMPEQQcDRABAhYLDBINIpYFBwIGDhgcHRsFCAEBMEBOSC8sLB0WCAwbAwECAxJFKF0r6w1NFhoZEQINFzMEFAIXAwIBAQEMCQED/ogeEAUFAyY+MT8gDwkNEAECAAQAAP/AA24DwAAYAB8AKgBhAAABFhcWFREUBwYHISInJicRNDc2NyEyFxYXBxUzJi8BJhMRIyInJic1IREhARUzEzMTNjc2NTMXFhcWFxMzEzM1IxUzBwYPASM0NTQnJjcmJyYnAyMDBgcGDwEjJyYvATM1IwNHEAwLEA8X/QAYDxABERAXAgAWHBsQTNcFB7QGy+0YDxAB/kkC3P1gKF5bSQQBAgMBAQEBAklcXSirMzgEAQEDAQEBAQEBAlNAUwEBAQECAgIBAzkzqwLnEBsbGP1uFxAPARARFgOSFxAPAQsMECfXEgazB/ycAkkREBbu/JICAD3+hgEWCw8JBQ4BCwoE/uoBej09+wsODAICAgICAgIJCQUBOP7IBQgIBAwMDgv7PQAABAAA/8ADbgPAABgAHwAqAGAAAAEWFxYVERQHBgchIicmJxE0NzY3ITIXFhcHFTMmLwEmExEjIicmJzUhESElFTM1Izc2NzY3NgczFBcWFxYXFh8BIxUzNSMnNzM1IxUzBwYHBg8BIzQnJi8BMzUjFTMXByMDRxAMCxAPF/0AGA8QAREQFwIAFhwbEEzXBQe0BsvtGA8QAf5JAtz90KErOwMCAgMDAQEDAgEBAgICPSynJ21uJ6AqOgIEBAEBAQMEBjwrpidsbycC5xAbGxj9bhcQDwEQERYDkhcQDwELDBAn1xIGswf8nAJJERAW7vyShj09XAQFBQMDAQIEAgICAgIDXD09m6I9PVsEBQUDAQIDBgdbPT2bogAAAAAFAAD/wANuA8AAGAAfACoAQgBNAAABFhcWFREUBwYHISInJicRNDc2NyEyFxYXBxUzJi8BJhMRIyInJic1IREhJRUzNSM1MzI3Njc2JzQnJicmKwEVMxEjNyM1MzIXFhUUBwYDRxAMCxAPF/0AGA8QAREQFwIAFhwbEEzXBQe0BsvtGA8QAf5JAtz9ybs1TiwXJhgXARUWJBsu0zU1ykRFHRIfIhMC5xAbGxj9bhcQDwEQERYDkhcQDwELDBAn1xIGswf8nAJJERAW7vyShj09XwkNJCUvLiIiEAs9/sOgmQoULjMRCQAABQAA/8ADbgPAABgAHwAqADEAQgAAARYXFhURFAcGByEiJyYnETQ3NjchMhcWFwcVMyYvASYTESMiJyYnNSERIQMVITU3FzcFIicmNTQ3NjMyFxYVFAcGIwNHEAwLEA8X/QAYDxABERAXAgAWHBsQTNcFB7QGy+0YDxAB/kkC3Er9uG1J3P7bLiAfHyAuLiAgICAuAucQGxsY/W4XEA8BEBEWA5IXEA8BCwwQJ9cSBrMH/JwCSREQFu78kgEAt25uSdtJICAuLiAfHyAuLiAgAAkAAP/AA24DwAADAAcACwAPACgALwA+AFYAZgAAATUjFRc1IxUVNSMVFzUjFSUWFxYVERQHBgchIicmJxE0NzY3ITIXFhcHFTMmLwEmExEjIicmJzUjFSM1IREhARcWFRQHBicmJyYnNDc2NzUzFTMyFxYXAzI3NjU0JyYjIgcGBwYXFgFuSZNKSZNKAdkQDAsQDxf9ABgPEAEREBcCABYcGxBM1wUHtAbL7RgPEAFISv7bAtz+mj0EKSlAQSgoAgUNOEktDQkKBFEfFRYWFR8fFBUBARcWAuVJSUpKSklJSUlJSd4QGxsY/W4XEA8BEBEWA5IXEA8BCwwQJ9cSBrMH/JwCSREQFu5JSfySAZzHEA4vICABAR4eMQ4QJL5JSQcHDf72CwwODgwLCwwODgwLAAAABgAA/8ADbgPAABgAHwAqAEIAWwB0AAABFhcWFREUBwYHISInJicRNDc2NyEyFxYXBxUzJi8BJhMRIyInJic1IREhARYVERQHBiMiLwEjIicmPQE0NzY7ATc2EzI3NjU0JyYnJgcGBwYXFhUUBwYXFhcWMycyNzY1NCcmJyYHBhUUFxYVFAcGFRQXFjMDRxAMCxAPF/0AGA8QAREQFwIAFhwbEEzXBQe0BsvtGA8QAf5JAtz+PgsLBQMGBl9LCAUFBQUIS18I+hILSkoJEA8MDAICCjo6CQEBDQoNeRALMjIKEA8LDAsdHQsMDA0C5xAbGxj9bhcQDwEQERYDkhcQDwELDBAn1xIGswf8nAJJERAW7vySAdIFDf7JDAQBBV8FBQhuCAUFYAj+cQ9adXRbDAICCgoPDwxGW1xFDBAPCApVDDVIRzUMAQELDA4ODSAqKiELEA8KCgAFAAD/wANuA8AAGAAfACoAPwBPAAABFhcWFREUBwYHISInJicRNDc2NyEyFxYXBxUzJi8BJhMRIyInJic1IREhATIXFh0BFAcGByMiJyY9ATQ3NjsBBRYVERQHBiMiLwE1NzYzMgNHEAwLEA8X/QAYDxABERAXAgAWHBsQTNcFB7QGy+0YDxAB/kkC3P6THRYVFRYd3R0WFRUWHd0BGAsLBAMHBZiYBQcDAucQGxsY/W4XEA8BEBEWA5IXEA8BCwwQJ9cSBrMH/JwCSREQFu78kgIAFhUe2x4VFgEXFh3bHhUWAQQN/rcNBQEFmTOYBQAGAAD/wANuA8AAGAAfACoAQgBaAG4AAAEWFxYVERQHBgchIicmJxE0NzY3ITIXFhcHFTMmLwEmExEjIicmJzUhESEBNjMyHwEWFRQPARcWBwYPAQYjIi8BJjchFg8BBgcGLwEmJyY/AScmNzY/ATYXFhcDJicmNxM2NzYfARYXFgcDBgcGJwNHEAwLEA8X/QAYDxABERAXAgAWHBsQTNcFB7QGy+0YDxAB/kkC3P3uBAgIBR0HA2hoBAEBBh0GBwcFgQkJAkoJCYEEBwcHHQYBAQRoaAQBAQYdBggIA+EHBAQBTwEGBggkBwQEAU8BBgYHAucQGxsY/W4XEA8BEBEWA5IXEA8BCwwQJ9cSBrMH/JwCSREQFu78kgIABwMWBQcHBoyLBgcHBRYEB6wLDAwLrAYBAQUWBQcHBouMBgcHBRYEAQEG/k0BBwcGAdsHBAUCBQIGBgf+JQcFBAEAAAAAAgAA/8ADbgPAAB8ANwAAASIHBgcGBwYHBhcWFxYXFjc2NzY3Njc2NTQnJicmJyYBFAcGBwYjIicmJyYnJjc2NzYzMhcWFxYBt0pERDExHRwBAR4fLy9GRkhJRUQwMB4eHh4wMERFAW47OmZld3ZnZjk4AwM+P2BgfX1fYEBBAy4dHTExRENLS0NEMDAfHwICGxs0NEA/T08/QDU1GRj+l3hkZTs7OztlZHh4ZGU7Ozs7ZWQACQAA/8ADbgPAAAMAFwAcACAAJAA4AEwAUQBVAAA3FSM1JTIXFh0BFAcGKwEiJyY9ATQ3Njc3FSE1IQEVIzUBFSE1AzIXFgcVFAcGByMiJyYnNTQ3NhcBMhcWBxUUBwYHIyInJic1NDc2FwUVIzUzERUhNcnJAZMOCwwMCw6TDgsMDAsO7v4SAe7+koADbv5bgA8MCwEKCxCREAoKAQsLDwIADgsLAQoKD5MPCwoBCwwOAUmAgP4SwElJSgwLDpMOCwsLCw6TDwoLAdtJSQElSkr9tklJApIKChCSDwoLAQwLDpIPCwsB/twLCg+TDwoLAQwLDpMOCwwBSUlJASVKSgAAAAABAAD/wANuA8AAMwAAATIXFhUUBwYjIicmNzQ3JwYjIicmNTQ3NjMyFzcmNTQ3Njc2FxYXFgcGJyInBxYVFAcXNgK4SzY1NTZLTDc2AQHONEdNNjU1Nk1HNM4BNTZNTDU0AQE2N0pJNM4BAc40AXc2NktLNjY2NksHDGcxNjZLSzY2MWcMB0w1NQEBNzdKSjc3ATFnDAcHDGcxAAAEAAD/wAR6A8AADwAwAFUAdQAAJSInJic0NzY3NhcWBxQHBjciJyYnJiMiBwYHBjEiJyY1NDc2NzY3NhcWFxYVFAcGIzciJyYnJgciBwYHBgcGBwYjIicmNTQ3Njc2FxYXFhcWFRQHBiM3IicmJyYnJgcGBwYjIicmJzQ3Njc2MzIXFhcWFRQHBgJICykpASQkFhclJQEqKo8BFRYlJSQlJCQXFgorKwUtQkNCQ0RDLAUrKwqcBgdNQ0JXMTExJCQcHRARAgkrKwZMamtub2xrSwYrKwqbBgdlb26Cg21uZgcGCisrAQZrk5SamZWUagUrKzEqKgsTDAwBAQ4OEQsqKpsODg8ODg8ODisrCgcGLBkZAQEbGyoGBworK5sGOx0cAQwMEhETEgwNKysLBwVMKioBASgoTgUHCysrmwVaLS0BAS8vWAUrKwoHB2o6Ozs6agcHCisrAAMAAP/ABIoDwAAPACAAVQAAARYXFAcGIyEUBwYjIicmJxcyNTQHIicmNTQjIhUUFxY3ARYVFAcBBicmLwEmNTQ/ASY1Njc2NzY3Njc2NzQ3NjcmNTQ3Njc2FxYHFAcWFxYXNzYXFhcDeSSHFRYf/wArKzw8KioBkQkJIRgZCQkdHikCPQUH+9IFCAgEMAUHagsdFxgYGRITCgoBQ0JtBBAQFhUSEQEERzY2HvAFCAgEAdrMcx4VFjwrKysrO2MJCQEZGSEKCiodHgEDkgYICAT8YQUBAQU2BwgIBFwSExkZGisrMDBGRU9WS0sQCgwXEA8BARESFQwKCiUlNc8FAQEFAAAABAAA/8AEigPAABAAIAA1AGsAAAU0IyInJjU0IyIVFBcWNzI1CQEmJyYHIgcGBwYHBgcUBwUUBwYjIRQHBiMiJyYnNyEmJzcWFxMXFhUUBwEGJyYvASY1ND8BJjU2NzY3Njc2NzY3NDc2NyY1NDc2NzYXFgcUBxYXFhc3NhcWFwJRCSEYGQkJHR4pCf7OAfUYNDRMNCwsGhkODQFOAwUVFh//ACsrPDwqKgFVAbBfIj4khzEwBQf70gUICAQwBQdqCx0XGBgZEhMKCgFDQm0EEBAWFRIRAQRHNjYe8AUICAQJCBkZIQoKKh0eAQkBEAGyMiIiARIRHR0eHx3clGweFRY8KysrKztKbJo5zHMDHDcGCAgE/GEFAQEFNgcICARcEhMZGRorKzAwRkVPVktLEAoMFxAPAQEREhUMCgolJTXPBQEBBQAAAAMAAP/AA24DwAA8AFwAdAAAARUUBwYHBgcGIyInJjc0NzYzMhcWFxYXFhcWBxUUKwEiPQE0JyYHIgcGFRQXFjMyNzY9ATQ3NjczMhcWFQMiBwYHBgcGBwYXFhcWFxY3Njc2NzY3NjU0JyYnJicmARQHBgcGIyInJicmJyY3Njc2MzIXFhcWApEVFh8gJCQedk9PAU5OcxQXGB4dFxYSEQEJRAkmJidRMzI1NFEnJygDBAJEAwMD2kpERDExHRwBAR4fLy9GRkhJRUQwMB4eHh4wMERFAW47OmZld3ZnZjk4AwM+P2BgfX1fYEBBAVs/HRYXDAwGBk9QdnROTQMDBwcMDRMUGj8JCSgZDg8BNTRTVzg5Dw4YKAQCAgEDAwMB0x0dMTFEQ0tLQ0QwMB8fAgIbGzQ0QD9PTz9ANTUZGP6XeGRlOzs7O2VkeHhkZTs7OztlZAAC////wASSA8AABQALAAAlFSERMxEBEyERCQEEkvttSQNvkfxKAQABSFJJA2782wJJ/gABSgFJ/rcAAAAC////wASSA8AABQAlAAAlFSERMxEBFRQHBi8BAQYjIi8BBycBNjMyHwEBJyY3NjsBMhcWFQSS+21JBAAKCgtF/pYGBwcGhu1uAU8FBwgGhQEJRQkEBA75BwUFUkkDbvzbAsn4DAUFCUb+lgYGhe5uAU4GBoUBCUYICwwGBQgAAAP////ABJIDwAAgADsAXQAAATQnJicmJyYjIgcGBwYHBhUUFxYXFhcWMzI3Njc2NzY1ITQnJicmJyYrARYXFgcGBwYHMzI3Njc2NzYnMxQHBgcGBwYnISInJicmJyYnJjc2NzY3NjchMhcWFxYXFgKSGBcnJzY3Ozw2NicnFxgYFycnNjY8Ozc2JycXGAG2FxYoKDU1Pd1FKCcBASUmR908NjYnJxcYAUoeHjAwRURJ/klKQ0QxMR0dAQEfHy8vRkVIAbdKQ0QxMR0dAcA8NjYnJxcYGBcnJzY2PDs3NicnFxgYFycnNjc7PDY2JycXGDNNTVhYTU0zGBcnJzY3O0pERS8vICAEHB0yMkJBTU1BQjMzGxsCHR0xMURDAAAAAAL////ABJIDwAAiAEMAAAM0NzY3Njc2MyEyFxYXFhcWFxYHBgcGBwYnISInJicmJyYnATI3Njc2NzYnJicmJyYnJiMiBwYHBgcGBwYXFhcWFxYzAR4eMDBFREkBt0pDRDExHR0BAR8fLy9GRUj+SUpDRDExHR0BAyU8NjYnJxcYAQEWFSkpNDQ+PTU0KSkVFgICGhklJTg5OQHAS0NEMTEdHR0dMTFEQ0tLQ0QwMB8fAh0dMjJCQU3+2xgXJyc2Nzs7NzYnJxcYGBcnJzY3Ozs3NicnFxgAAAP////ABJIDwAAQAD0AbAAAASInJjc2NzYXFhcWFxYHBgcFMzIXFgcVFAcGKwEVFAcGByMiJyY9ASMiJyYnNTQ3NjczNTQ3NhczMhcWFxUFFBcWNzMVBiMhIicmNTQ3Njc2NzY3Njc2NzYXMhcWFxYzMjc2NzYzMhcjIgcGFQGSW0FBAgE+Pl5dPT4DA0RDVwIlyAcHBgEFBgjIBwYGbQkFBcoHBQUBBgYGygUFCW0HBQUC/lsVFh2TJzv+DUUqKgICBgcJCQ8QExQdHiILCy0rKzQzKystCwtLMYAdFhUBwEFAWlpCQQEBP0BcXD4/AkkGBgZuCAUFygcFBQEGBgbKBQUIbgcFBQHJBwYGAQUFCMmAHRcWAYkcKChEHx0cIiIbHB0cEhEODQIKIxIRERIjCjcWFR4AAAMAAP/ABI8DwAAQADwAaAAAASInJjc2NzYXFhcWFxYHBgcFFxYVFA8BBiMiLwEHBiMiLwEmNTQ/AScmNTQ/ATYzMh8BNzYzMh8BFhUUBwUHBhUUHwEGIyEiJyY1NDc2NzY3Njc2NzY3NhcyFxYzMjc2MzIXBgcGBxQXAZRbQEEBAT8+XV0+PQMDQ0RXAmiOBQVOBQcIBY+OBQgIBU0GBo6OBgZNBQgIBY6PBQgHBU4FBf5VZxYWLwwN/gxEKioCAgYGCQoPDxQTHh4hDAtYXl5ZCwsPERAHBwEWAcBBQFpaQkEBAT9AXFw+PwK3jgUICAVOBQWOjgUFTgUICAWOjgUICQVMBgaOjgYGTAUJCAWOaBQfHxUvAigoRB8dHCIiGxwdHBIRDg0CCkZGCgQQDAwVHhYAAwAA/8AEAAPAABMAJwBKAAAlETQnJiMhIgcGFREUFxYXITI3NhMRFAcGIyEiJyYnETQ3NhchMhcWJxUjNTQnJichIgcGBxEUFxY7ARUjIicmNxE0NzYzITIXFgcDtwYGBv2SCAUFBQUIAm4HBQVKGxom/ZImGhsBHBslAm4mGhvbSgUFCP2SBwUFAQYGBlxcJRscARsaJgJuJhscARsCbggFBQUFCP2SBwUFAQYGAnT9kiYaGxsaJgJuJhscARsatVxcBwUFAQYGBv2SCAUFShwbJQJuJhobGxomAAIAAP/AA24DwAA6AG0AAAEUBwYHFhcWFzMyFxYdARQHBiMhIicmPQE0NzY7ATQ3NjcmJyYnIyInJj0BNDc2MyEyFxYdARQHBisBATY3Njc2NzYnIRQXFhcWFxYXFhcWFxYHBgcGBwYHBgcGFyE0JyYnJicmJyYnJicmNzY3AyU9PlpbPTwBNgkFBQUFCfy4CQUFBQUJNj0+W1w9PAE2CQUFBQUJA0gJBQUFBQk2/s8sKSkhIBUUAf24ExQhIigoLQsGBwEBCQgJKyoqIB8WFQICSBMUISIoKC0LBgcBAQkICQN3lXNzPDxzc5UFBgclCAUFBQUIJQcGBZVzczw8c3OVBQYHJQgFBQUFCCUHBgX+bBAkJDMzRURNS0ZGMjIlJQ8ECwoKCgoLAxEkJDMzRURNS0ZGMjIlJRADCwoKCgoLBAAAAAMAAP/AA24DwAA6AEEAVAAAARQHBgcWFxYXMzIXFh0BFAcGIyEiJyY9ATQ3NjsBNDc2NyYnJicjIicmPQE0NzYzITIXFh0BFAcGKwEjIRQXITY1ETQnJicmJyYnIwYHBgcGBwYHIQMlPT5aWz08ATYJBQUFBQn8uAkFBQUFCTY9PltcPTwBNgkFBQUFCQNICQUFBQUJNkr9uAUCPgUTFB8gKSkqhCsoKCEgExIBAkgDd5Vzczw8c3OVBQYHJQgFBQUFCCUHBgWVc3M8PHNzlQUGByUIBQUFBQglBwYFJiMiJ/ySSkVFMjIlJRARJCQzM0RESwADAAD/wANuA8AAOgBAAEoAAAEUBwYHFhcWFzMyFxYdARQHBiMhIicmPQE0NzY7ATQ3NjcmJyYnIyInJj0BNDc2MyEyFxYdARQHBisBIyEUFyE2AyYnJicjBgcGBwMlPT5aWz08ATYJBQUFBQn8uAkFBQUFCTY9PltcPTwBNgkFBQUFCQNICQUFBQUJNkr9uDAB6DAfIDQ1OoQ6NTQfA3eVc3M8PHNzlQUGByUIBQUFBQglBwYFlXNzPDxzc5UFBgclCAUFBQUIJQcGBXVnZ/2+UTk6Fxc6OVEAAAAAAgAA/8ADbgPAADoAYQAAARQHBgcWFxYXMzIXFh0BFAcGIyEiJyY9ATQ3NjsBNDc2NyYnJicjIicmPQE0NzYzITIXFh0BFAcGKwEBNjc2NzY3NichFBcWFxYXFhcWFxYXFgcGBwYHISYnJicmJyY3NjcDJT0+Wls9PAE2CQUFBQUJ/LgJBQUFBQk2PT5bXD08ATYJBQUFBQkDSAkFBQUFCTb+zywpKSEgFRQB/bgTFCEiKCgtCwYHAQEJCAlOPQGQPU4LBgcBAQkICQN3lXNzPDxzc5UFBgclCAUFBQUIJQcGBZVzczw8c3OVBQYHJQgFBQUFCCUHBgX+bBAkJDMzRURNS0ZGMjIlJQ8ECwoKCgoLAx1TUx0DCwoKCgoLBAAABQAA/8AD3APAACwAQABUAFgAhAAAATIXFhcRFAcGIyEiJyY1ETQ3NjsBNTQ3NjsBMhcWHQEzNTQ3NjsBMhcWBxUzJxUUFxY7ATI3Nj0BNCcmKwEiBwYFFRQXFjsBMjc2PQE0JyYrASIHBgERIREBMzIXFh0BFAcGByMVFAcGKwEiJyY9ASMiJyY9ATQ3NjsBNTQ3NjsBMhcWFQOSHhUWARcWHfzbHhUWFhUeShobJiUmGhvbHBslJCYcGwFJ2wUFCCQIBQUFBQgkCAUF/kgGBQglCAUFBQUIJQgFBgKT/NsBt4AJBQUFBQmABQUIJQcFBYAJBQUFBQmABQUHJQgFBQMuFhUe/SQeFRYWFR4C3B4VFjcmGhsbGiY3NyYaGxsaJjc3pQgFBQUFCKUIBQUFBQilCAUFBQUIpQgFBQUF/JwCSf23AUkFBQglBwUFAYAHBgUFBgeABgYGJQgFBYAJBQUFBQkAAAAABQAA/8AD3APAABMAGAAsAEAAbQAAARUUBwYHISInJj0BNDc2MyEyFxYBIREhERM1NCcmKwEiBwYdARQXFjsBMjc2JTU0JyYrASIHBh0BFBcWOwEyNzY3ERQHBiMhIicmNRE0NzY7ATU0NzY7ATIXFh0BMzU0NzY7ATIXFgcVMzIXFhcCtwUFCf64CQUFBQUJAUgJBQX9tgMl/NvcBQUIJQgFBgYFCCUIBQUBtgUFCCQIBQUFBQgkCAUF3RcWHfzbHhUWFhUeShobJiUmGhvbHBslJCYcGwFJHhUWAQFAJQcFBQEGBgYlCAUFBQX+wQJJ/bcCt6UIBQUFBQilCAUFBQUIpQgFBQUFCKUIBQUFBS39JB4VFhYVHgLcHhUWNyYaGxsaJjc3JhobGxomNxYVHgAAAAAFAAD/wAPcA8AAKwAwAEQAWACFAAAlBwYjIi8BBwYjIi8BJjU0PwEnJjU0PwE2MzIfATc2MzIfARYVFA8BFxYVFAUhESEREzU0JyYrASIHBh0BFBcWOwEyNzYlNTQnJisBIgcGHQEUFxY7ATI3NjcRFAcGIyEiJyY1ETQ3NjsBNTQ3NjsBMhcWHQEzNTQ3NjsBMhcWBxUzMhcWFwKfGgYHBwZsawUHBwcZBQVrawUFGQUJCARrbAYHBwYaBQVrawX9yQMl/NvcBQUIJQgFBgYFCCUIBQUBtgUFCCQIBQUFBQgkCAUF3RcWHfzbHhUWFhUeShobJiUmGhvbHBslJCYcGwFJHhUWAagZBgZrawYGGQYHBwZsawYHCAUaBQVrawUFGgUIBwZrbAUICKQCSf23ArelCAUFBQUIpQgFBQUFCKUIBQUFBQilCAUFBQUt/SQeFRYWFR4C3B4VFjcmGhsbGiY3NyYaGxsaJjcWFR4AAAUAAP/AA9wDwAAaAB8AMwBHAHQAAAkBBiMiLwEmNTQ/ATYzMh8BNzYzMh8BFhUUBwEhESEREzU0JyYrASIHBh0BFBcWOwEyNzYlNTQnJisBIgcGHQEUFxY7ATI3NjcRFAcGIyEiJyY1ETQ3NjsBNTQ3NjsBMhcWHQEzNTQ3NjsBMhcWBxUzMhcWFwMN/tsFBwgGpQUFGwUHCAZ+/QYHBwYaBQX9YAMl/NvcBQUIJQgFBgYFCCUIBQUBtgUFCCQIBQUFBQgkCAUF3RcWHfzbHhUWFhUeShobJiUmGhvbHBslJCYcGwFJHhUWAQGZ/tsFBaUGBwgFGgUFfv4FBRoFCAcG/nACSf23ArelCAUFBQUIpQgFBQUFCKUIBQUFBQilCAUFBQUt/SQeFRYWFR4C3B4VFjcmGhsbGiY3NyYaGxsaJjcWFR4AAAACAAD/wAPuA8AAAwBQAAABNyMHAQcGKwEHMzIXFg8BBisBBwYrASInJj8BIwcGKwEiJyY/ASMiJyY/ATY7ATcjIicmPwE2OwE3NjsBMhcWDwEzNzY7ATIXFg8BMzIXFgcCNiWRJQJJIQQOuiWxCgUGAiECD7suBA6ACgUFAS2RLgQOgQgGBQIssQkFBgEhBA66JbEKBQYCIQIPuy8DDoAKBQUBLZEuBA+ACAYFAiyxCQUGAQF3kpIBIIAOkgcICIAOuw4HBwmyuw4HBwmyCAYJgA6SBwgIgA67DgcHCbK7DgcHCbIIBgkABAAA/8AEAAPAAGMAcQCKAI0AADciJyYnJicmNTQ3Njc2NzY3Njc2NzY3NjU2NyY1NDc2MzIfATYzMhcWFxYVFAcGBwYHFhUUBwYjIi8CAzcGBxYXFhcWIxQHBiMiJwEGBxYXFhUUIyInJi8CBgcWFxYfARQjJRc2NyYnFhcWFRQHBgcDFBcWMzIXFhUUFxYzMjc2NTQnJiMiBwYVNycXvwECMS8vIQwBAQEBAwMCAgQFAQEGBmmaQAtBBwsGRjU5mIWFUwsLNElJVj8LQQYMBkYl/QQiFwJGR0RFAQUHIiEB/vsWGQ5tbAYIJycDPIAaEwIJCQNmBwHbHJxlZ6AnFRQbGjG2CQgLMSMjCAgLDAgIMzNICwgJ0gYE3QEhMjI2ERUGBgYEBAYGAwQGBgMDBQUEkEByBwsFJQmDC09OhREXFhBRQUAkcQcMBSQJg0QB1QMODQOCgn9/BAIBBAHgEBcYyMgDBgwNBHDsHh8BDQ0GuwY7NUCcn0AkMDA2PDY3IwFfCwkIIyIyCwgICAgLSDMzCAgLJQIDAAAAAAMAAP/ABAADwABEAG0AmAAAARcWBwYHBgcGBwYHBgcGBwYHBgcjIicmJyYnJicmJyYnJicmNTQ/ATY3NhcWFxYXFhcWFxY3MzI3Njc2NzY3Njc2MzIXExEmJyYnJicmJyYnJicjIgcGBwYHBgcGBwYHBgcGBxEUFxYXITI3NjcTERQHBiMhIicmNxE0NzY3Njc2NzY3Njc2OwEyFxYXFhcWFxYXFhcWFxYVA0sVBQEBBRgwMSMkAhcMDBYVFxcTAhQWFRYWDQ0WAyEiMDEVBwMVBAkIBjV5AxcWCwwVFgsCDRQTDg0VFgOTHwcHCAVsNCc0qgIXFgwNExQOAg0UEw4NFRYDezk6EBAfCAQGBgYDSgcFBQFJGxom/LYlGxwBGEaBgQQVDQ0XFxQUFgIVFRYWFwwMFhhBQEFAMhgBtx4GBwcEFCUlGxwCEgoJDg8GBgEHBw4NCgsRAhsaJSURBQcHBh4GAQEEKl0CExIICQoKAQkJCgkREgNwGgQH/mQCEzAfKoMDEhIKCQkJAQoKCAkTEwJeLi4NDR0HBP3tBwUFAQYGBgIT/e0mGhsbGiYCEx8XQGZlAhIKCg0OBwcHBw4NCgoSFDEyNDQuFx8AAAAABP///8ADtwPAAA8ASACBAJUAAAEUBwYHBicmNzQ3Njc2FxYHMhcWFxYXFhcWFxYXFAcGIyEiJyY1NDc2NzY3Njc2OwEWFxYXFhcWFxYXFhcWNzY3Njc2NzY3NjMlFAcGJyMVMzIXFhcVFAcGKwEVMzIXFhcVFAcGByMVFAcGIyEiJyY3ETQ3NjMhMhcWHQEzMhcWFxUDETQnJichIgcGBxEUFxYXITI3NgJLLCw8PS0tAisrPz4qKhobFRQNDgkJBQUBAQEWFyX+tyYXFgMDBwcODRYXIAIEDg8GBgwMCgkLCwwLCwsJCA0NBgUPDwMBiAYHBjc3BwYFAQYHBjc3BwYFAQYHBjcbGib9SSUcHAEbGyYCtyYaGzcHBgUBkwYGBv1JCAUFAQYGBwK3BwUFAlA9KysBAS0tOz4rKwEBLS26CgoQERUWGRoWFRglHh4eHiUcGhkfHxUWDw8CCQkDAwYGBAMCAgEBBAQBAQkIAQELC5MHBgcBSQUGB24HBgVJBgUIbQgFBQGAJhobGxomA0omGhsbGiaABgYHbf22A0oHBQUBBgYG/LYHBQUBBgYAAwAA/8ADbgPAADAAQQBXAAABFhcWFxYXFhcWBxQHBiMhIicmNTQ3Njc2NzY3NjcmNTQ3Njc2NzYzMhcWFxYXFhcUASIHBhUUFxYXFjc2NzYnJgcTMjc2NTQnJicGIyInBgcGFRQXFjMhAq4bGBkbGhMSDQ4BOjlQ/hhQOToMDRMUGRoZGhotFxgnJzY2Ozw1NSkpFhUB/txbQEFBQFtcP0ABAUJBWvQyJCQtLVRTbWxUVC0tJCQyAegCAQkODhsbKCc7Ok1YPz4+P1hLPD0lJh0dDAwLRlQ8NjYnJxcYGBcnJzY2PFQBMEBBW1s/QAEBQkFZWUNCAvySKSk6iU9PA0hIA09PiTopKQAAAAIAAP/ABAADwAAEABkAADchESERAREUBwYHISInJjcRNDc2NyEyFxYVkgLc/SQDbhsaJvy2JRscARsaJgNKJhobmwG3/kkCgP1KJhsaARscJQK2JhsaARscJQAAAQAA/8AEAAPAABQAAAEVFAcGByEiJyY3NTQ3NjMhMhcWFQQAGxom/LYlGxwBGxomA0omGhsB920mGxoBGxwlbSYbGhobJgAAA////8AEkgPAAAQADwAvAAA3IREhEQEhESEVMzIXFh0BAREUBwYjIRUUBwYjISInJjcRNDc2MyE1NDc2MyEyFxaSAbb+SgJIASX+STcmGxoBuBsbJf6jGhsm/dskHBwBGxslAV0aGyYCJSQcHFIBJf7bASUBt5MaGybJAe792yYbGsomGhsbGiYCJSYbGsomGhsbGgAAAAACAAD/wAQAA8AAKwBAAAAlNzY1NC8BNzY1NC8BJiMiDwEnJiMiDwEGFRQfAQcGFRQfARYzMj8BFxYzMgERFAcGByEiJyY3ETQ3NjchMhcWFQKgUwYGhYUGBlMGCAcGhYUGBwgGUwYGhYUGBlMGCAcGhYUGBwgBZhsaJvy2JRscARsaJgNKJhobzVMGCAcGhYUGBwgGUwYGhYUGBlMGCAcGhYUGBwgGUwYGhYUGAlT9SiYbGgEbHCUCtiYbGgEbHCUAAAAAAwAA/8AEAAPAACwAMQBGAAABBwYjIi8BBwYjIi8BJjU0PwEnJjU0PwE2MzIfATc2MzIfARYVFA8BFxYVFAcFIREhEQERFAcGByEiJyY3ETQ3NjchMhcWFQLPVAYHCAZgYAYIBwZTBgZgYAYGUwYHCAZgYAYIBwZUBQVhYQUF/cMC3P0kA24bGib8tiUbHAEbGiYDSiYaGwFFUwYGYGAGBlMGBwgGYGAGCAcGVAUFYWEFBVQGBwgGYGAGCAcGqgJK/bYCgP1KJhsaARscJQK2JhsaARscJQAAAQAAAAEAAH2fuHdfDzz1AAsEAAAAAADhVnMIAAAAAOFWcwj//f+9BQADwwAAAAgAAgAAAAAAAAABAAADwP/AAAAFJP/9//0FAAABAAAAAAAAAAAAAAAAAAAA9wQAAAAAAAAAAAAAAAIAAAAEAAAABAAAAAO2//8ESQAAA24AAANuAAACkf//A24AAAO2//8CSQAABAAAAAO2//8CAAAAAmYAAALNAAACHwAAAmYAAAJmAAACqwAAAeEAAAOFAAADhQAAA24AAAQAAAAEkf//AyQAAANWAAACZgAAAOEAAAJIAAADrgAAAysAAAOaAAAEAAAAA24AAAQAAAAEAAAABAAAAAQAAAAEAP/9A24AAAQAAAADWAAAAyQAAANuAAADbgAAA24AAAQAAAADtgAAAbYAAAQAAAAEAAAAA24AAANuAAADbgAAA24AAAQAAAAEAAAABAAAAAQAAAAEAQAABAAAAAQAAAAEAAAAApH//wQA//0EAAAABAD//QQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAAA24AAAO2AAAEAAAAA7b//wMkAAADJAAAAyQAAAQAAAAEAAAAA24AAANuAAADtgAAA7YAAAMkAAADtv//BAAAAAQAAAADbgAABEkAAALbAAADtv//A7b//wQAAAACSQAAAkkAAAFuAAABbgAAAtsAAAQAAAAC2wAABAAAAAO2AAADbgAAA24AAAO2AAADtgAAA7YAAANHAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAADJAAAAtsAAAMkAAADbgAABAAAAANuAAADtv//A7b//wJJAAACSQAAAkkAAAQAAAAEAAAABAAAAAQAAAAESQAABEkAAAQAAAAEAAAAA24AAANuAAACSQAAAkkAAAKRAAACkQAAAW4AAAFuAAACkQAAApEAAARJAAADbgAAA7b//wO2//8EAAAAA24AAAQAAAADtv//BEkAAAO2AAAESQAABAAAAAMkAAACSQAAA7b//wJJAAABbgAAAW4AAAKR//8DJAAAA7b//wKR//8DJAAAANsAAANuAAADbgAAA24AAANuAAACSQAAAkkAAANuAAADtgAAA7YAAAQAAAAEAAAAA24AAANuAAABtgAAAbYAAAQAAAAEAAAABAAAAAUkAAADbgAAA24AAANuAAADbgAAA24AAANuAAADbgAAA24AAANuAAADbgAAA24AAANuAAADbgAABJEAAASRAAAEkQAAA24AAASR//8Ekf//BJH//wSR//8Ekf//BJEAAAQAAAADbgAAA24AAANuAAADbgAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAO2//8DbgAABAAAAAQAAAAEkf//BAAAAAQAAAAAAAAAAAoAFAAeAQgBbAHkAk4DIgP+BEIIOAj2CTQJjAosCkoKZAqCCqQK0Ar8CyoLZguaC9IMNAzEDPINnA4gDl4OfA6wDvoPGg84D2wP0hAGEFQQhBD0EfgSOBJ8Ep4TVhO4FBoUYBXAFioWbBaqFzAXdBfiGFAY1hmWGpYcAhx2HQIdih64IAQgZiFGIhQjcCRuJKwk3iU4JbwmBCYeJjgmuCc6J9IoKihsKJAo0ikCKbIqQiq2KxYr0Cw+LIws+i2gLeguWi6SLxgvoC/8MCAwRjBqMI4wvjDuMRwxTDGIMcQyADI8MqIzGjNgM8o0HjR6NMg1fjbONx43Xjd8OFg4zjlcOdQ6SjrEOwY7SDtyO+Q8VDywPcA+Aj5EPmg+jD8GP5A/+kBUQLRBFEFcQcxCZELCQxRDZkO4RApEOERmRJREwkUkRXJF8EZuRzJHXEe4SAxIiEjQSURJrkniSppLiEv+TFRMlE0ITZpOFk5gTrhPEE9QT5xP7FBEUPZRyFH+UnxS/FOWVDBUyFViVY5VulXoVhZWXFbcV2pYSljeWWxZ4FpIWuJbjlwGXLZdEF2SXeBejF8OX7JgXGB6YLphSmG2YlJi7GNaY/xkdmTkZXRmKGbCZ3poHmiSaWBqSGsga6Zr1Gv4bERspm0SAAEAAAD3As4ADwAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAOAK4AAQAAAAAAAQAMAAAAAQAAAAAAAgAHAI0AAQAAAAAAAwAMAEUAAQAAAAAABAAMAKIAAQAAAAAABQALACQAAQAAAAAABgAMAGkAAQAAAAAACgAaAMYAAwABBAkAAQAYAAwAAwABBAkAAgAOAJQAAwABBAkAAwAYAFEAAwABBAkABAAYAK4AAwABBAkABQAWAC8AAwABBAkABgAYAHUAAwABBAkACgA0AOB0aWNrNDItaWNvbnMAdABpAGMAawA0ADIALQBpAGMAbwBuAHNWZXJzaW9uIDEuMABWAGUAcgBzAGkAbwBuACAAMQAuADB0aWNrNDItaWNvbnMAdABpAGMAawA0ADIALQBpAGMAbwBuAHN0aWNrNDItaWNvbnMAdABpAGMAawA0ADIALQBpAGMAbwBuAHNSZWd1bGFyAFIAZQBnAHUAbABhAHJ0aWNrNDItaWNvbnMAdABpAGMAawA0ADIALQBpAGMAbwBuAHNGb250IGdlbmVyYXRlZCBieSBJY29Nb29uLgBGAG8AbgB0ACAAZwBlAG4AZQByAGEAdABlAGQAIABiAHkAIABJAGMAbwBNAG8AbwBuAC4AAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA) format("truetype")}[class^="icon-"],[class*=" icon-"]{font-weight:normal;font-family:"tick42-icons";font-style:normal;font-variant:normal;line-height:1;text-transform:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.tick42-custom-icon i{color:var(--t42-link-color)}.tick42-custom-icon img{display:block}.tick42-custom-icon.disabled i,.tick42-custom-icon:disabled i{color:var(--t42-content-color-disabled)}i.disabled,.disabled i{color:var(--t42-content-color-disabled)}.icon-size-12 i{font-size:0.75rem}.icon-size-12 i,.icon-size-12 img{width:0.75rem;height:0.75rem}.icon-size-14 i{font-size:0.875rem}.icon-size-14 i,.icon-size-14 img{width:0.875rem;height:0.875rem}.icon-size-24 i{font-size:1.5rem}.icon-size-24 i,.icon-size-24 img{width:1.5rem;height:1.5rem}.icon-size-16 i,.icon-size-16 img{width:1rem;height:1rem}.icon-size-16 i{font-size:1rem}.icon-size-32 i,.icon-size-32 img{width:2rem;height:2rem}.icon-size-32 i{font-size:2rem}.icon-size-48 i,.icon-size-48 img{width:3rem;height:3rem}.icon-size-48 i{font-size:3rem}.icon-size-64 i,.icon-size-64 img{width:4rem;height:4rem}.icon-size-64 i{font-size:4rem}.icon-size-80 i,.icon-size-80 img{width:5rem;height:5rem}.icon-size-80 i{font-size:5rem}.icon-size-96 i,.icon-size-96 img{width:6rem;height:6rem}.icon-size-96 i{font-size:6rem}.icon-size-112 i,.icon-size-112 img{width:7rem;height:7rem}.icon-size-112 i{font-size:7rem}.icon-size-128 i,.icon-size-128 img{width:8rem;height:8rem}.icon-size-128 i{font-size:8rem}.icon-primary i::before{color:#007be5}.icon-secondary i::before{color:#616161}.icon-success i::before{color:#43a047}.icon-info i::before{color:#469eb9}.icon-warning i::before{color:#f9a825}.icon-danger i::before{color:#ff511f}.icon-light i::before{color:#616161}.icon-dark i::before{color:#616161}.icon-dev-tools::before{content:"\e901"}.icon-interop::before{content:"\e900"}.icon-mail::before{content:"\e800"}.icon-attention::before{content:"\e801"}.icon-print::before{content:"\e802"}.icon-picture::before{content:"\e803"}.icon-thumbs-up::before{content:"\e804"}.icon-thumbs-down::before{content:"\e805"}.icon-lock::before{content:"\e806"}.icon-globe::before{content:"\e807"}.icon-calendar::before{content:"\e808"}.icon-location::before{content:"\e809"}.icon-briefcase::before{content:"\e80a"}.icon-export::before{content:"\e80b"}.icon-play::before{content:"\e80c"}.icon-stop::before{content:"\e80d"}.icon-record::before{content:"\e80e"}.icon-pause::before{content:"\e80f"}.icon-to-end::before{content:"\e810"}.icon-to-start::before{content:"\e811"}.icon-check::before{content:"\e812"}.icon-cancel::before{content:"\e813"}.icon-fast-forward::before{content:"\e814"}.icon-fast-backward::before{content:"\e815"}.icon-attention-circled::before{content:"\e816"}.icon-bell::before{content:"\e817"}.icon-chart-bar::before{content:"\e818"}.icon-phone::before{content:"\e819"}.icon-doc-add::before{content:"\e81a"}.icon-layout::before{content:"\e81b"}.icon-dot::before{content:"\e81c"}.icon-dot-2::before{content:"\e81d"}.icon-dot-3::before{content:"\e81e"}.icon-resize-full-1::before{content:"\e81f"}.icon-resize-small-1::before{content:"\e820"}.icon-checkbox::before{content:"\e821"}.icon-cancel-circled::before{content:"\e822"}.icon-03-context-viewer::before{content:"\e823"}.icon-volume-off-1::before{content:"\e824"}.icon-volume::before{content:"\e825"}.icon-headphones-1::before{content:"\e826"}.icon-performance-report::before{content:"\e827"}.icon-pause-1::before{content:"\e828"}.icon-volume-up-1::before{content:"\e829"}.icon-volume-down-1::before{content:"\e82a"}.icon-trash-empty::before{content:"\e839"}.icon-resize-small::before{content:"\e83b"}.icon-resize-full::before{content:"\e83c"}.icon-doc::before{content:"\e83d"}.icon-cog::before{content:"\e83e"}.icon-wrench::before{content:"\e83f"}.icon-resize-vertical::before{content:"\e840"}.icon-resize-horizontal::before{content:"\e841"}.icon-edit::before{content:"\e842"}.icon-pencil-1::before{content:"\e843"}.icon-cw-2::before{content:"\e844"}.icon-ccw-1::before{content:"\e845"}.icon-arrows-cw-1::before{content:"\e847"}.icon-th-large::before{content:"\e848"}.icon-th::before{content:"\e849"}.icon-spin5::before{content:"\e84a"}.icon-spin6::before{content:"\e84b"}.icon-spin4::before{content:"\e84c"}.icon-spin3::before{content:"\e84d"}.icon-spin2::before{content:"\e84e"}.icon-spin1::before{content:"\e84f"}.icon-pin::before{content:"\e850"}.icon-trading-controls::before{content:"\e856"}.icon-icon-coverage::before{content:"\e857"}.icon-taxes::before{content:"\e858"}.icon-credit::before{content:"\e859"}.icon-checkbox-checked::before{content:"\e85a"}.icon-checkbox-indeterminate::before{content:"\e85b"}.icon-radio::before{content:"\e85c"}.icon-radio-choose::before{content:"\e85d"}.icon-arrow-up-down::before{content:"\e85e"}.icon-arrow-double-left::before{content:"\e85f"}.icon-arrow-double-right::before{content:"\e860"}.icon-floppy::before{content:"\e861"}.icon-logout::before{content:"\e862"}.icon-mail-1::before{content:"\e864"}.icon-search-1::before{content:"\e865"}.icon-plus-1::before{content:"\e866"}.icon-minus-1::before{content:"\e867"}.icon-cancel-1::before{content:"\e868"}.icon-ok::before{content:"\e869"}.icon-th-list::before{content:"\e86a"}.icon-help-circled::before{content:"\e86b"}.icon-info-circled::before{content:"\e86c"}.icon-home::before{content:"\e86d"}.icon-link-1::before{content:"\e86e"}.icon-attach-1::before{content:"\e86f"}.icon-lock-open-1::before{content:"\e870"}.icon-eye::before{content:"\e871"}.icon-eye-off::before{content:"\e872"}.icon-tag::before{content:"\e873"}.icon-tags::before{content:"\e874"}.icon-bookmark::before{content:"\e875"}.icon-download-1::before{content:"\e876"}.icon-upload-1::before{content:"\e877"}.icon-forward-1::before{content:"\e878"}.icon-down-dir::before{content:"\e879"}.icon-up-dir::before{content:"\e87a"}.icon-left-dir::before{content:"\e87b"}.icon-right-dir::before{content:"\e87c"}.icon-left-open-1::before{content:"\e87d"}.icon-down-open-1::before{content:"\e87e"}.icon-right-open-1::before{content:"\e87f"}.icon-up-open-1::before{content:"\e880"}.icon-down-big::before{content:"\e881"}.icon-left-big::before{content:"\e882"}.icon-right-big::before{content:"\e883"}.icon-up-big::before{content:"\e884"}.icon-asterisk::before{content:"\e885"}.icon-check-1::before{content:"\e886"}.icon-tick42-icon-monochrome::before{content:"\e887"}.icon-task-manager::before{content:"\e888"}.icon-context-viewer::before{content:"\e889"}.icon-help-2::before{content:"\e88a"}.icon-star-empty-1::before{content:"\e88b"}.icon-star-full::before{content:"\e902"}.icon-move::before{content:"\f047"}.icon-link-ext::before{content:"\f08e"}.icon-check-empty::before{content:"\f096"}.icon-bookmark-empty::before{content:"\f097"}.icon-filter::before{content:"\f0b0"}.icon-resize-full-alt::before{content:"\f0b2"}.icon-docs::before{content:"\f0c5"}.icon-menu-1::before{content:"\f0c9"}.icon-table::before{content:"\f0ce"}.icon-columns::before{content:"\f0db"}.icon-sort::before{content:"\f0dc"}.icon-sort-down::before{content:"\f0dd"}.icon-sort-up::before{content:"\f0de"}.icon-mail-alt::before{content:"\f0e0"}.icon-sitemap::before{content:"\f0e8"}.icon-paste::before{content:"\f0ea"}.icon-exchange::before{content:"\f0ec"}.icon-download-cloud::before{content:"\f0ed"}.icon-upload-cloud::before{content:"\f0ee"}.icon-suitcase-1::before{content:"\f0f2"}.icon-bell-alt::before{content:"\f0f3"}.icon-doc-text-1::before{content:"\f0f6"}.icon-plus-squared::before{content:"\f0fe"}.icon-angle-double-left::before{content:"\f100"}.icon-angle-double-right::before{content:"\f101"}.icon-angle-double-up::before{content:"\f102"}.icon-angle-double-down::before{content:"\f103"}.icon-angle-left::before{content:"\f104"}.icon-angle-right::before{content:"\f105"}.icon-angle-up::before{content:"\f106"}.icon-angle-down::before{content:"\f107"}.icon-laptop::before{content:"\f109"}.icon-circle-empty::before{content:"\f10c"}.icon-quote-left::before{content:"\f10d"}.icon-quote-right::before{content:"\f10e"}.icon-spinner::before{content:"\f110"}.icon-circle::before{content:"\f111"}.icon-reply-1::before{content:"\f112"}.icon-folder-empty::before{content:"\f114"}.icon-folder-open-empty::before{content:"\f115"}.icon-terminal::before{content:"\f120"}.icon-code::before{content:"\f121"}.icon-reply-all-1::before{content:"\f122"}.icon-direction::before{content:"\f124"}.icon-fork::before{content:"\f126"}.icon-unlink::before{content:"\f127"}.icon-help::before{content:"\f128"}.icon-info::before{content:"\f129"}.icon-attention-alt::before{content:"\f12a"}.icon-mic::before{content:"\f130"}.icon-mute::before{content:"\f131"}.icon-calendar-empty::before{content:"\f133"}.icon-lock-open-alt::before{content:"\f13e"}.icon-ellipsis::before{content:"\f141"}.icon-ellipsis-vert::before{content:"\f142"}.icon-minus-squared::before{content:"\f146"}.icon-ok-squared::before{content:"\f14a"}.icon-link-ext-alt::before{content:"\f14c"}.icon-expand-right::before{content:"\f152"}.icon-euro::before{content:"\f153"}.icon-dollar::before{content:"\f155"}.icon-doc-inv::before{content:"\f15b"}.icon-sort-name-up::before{content:"\f15d"}.icon-sort-name-down::before{content:"\f15e"}.icon-sort-alt-up::before{content:"\f160"}.icon-sort-alt-down::before{content:"\f161"}.icon-sort-number-up::before{content:"\f162"}.icon-sort-number-down::before{content:"\f163"}.icon-down::before{content:"\f175"}.icon-up::before{content:"\f176"}.icon-left::before{content:"\f177"}.icon-right::before{content:"\f178"}.icon-cube::before{content:"\f1b2"}.icon-cubes::before{content:"\f1b3"}.icon-database::before{content:"\f1c0"}.icon-file-pdf::before{content:"\f1c1"}.icon-file-word::before{content:"\f1c2"}.icon-file-excel::before{content:"\f1c3"}.icon-file-powerpoint::before{content:"\f1c4"}.icon-file-image::before{content:"\f1c5"}.icon-file-archive::before{content:"\f1c6"}.icon-file-audio::before{content:"\f1c7"}.icon-file-video::before{content:"\f1c8"}.icon-file-code::before{content:"\f1c9"}.icon-circle-thin::before{content:"\f1db"}.icon-sliders::before{content:"\f1de"}.icon-share::before{content:"\f1e0"}.icon-wifi::before{content:"\f1eb"}.icon-bell-off::before{content:"\f1f6"}.icon-bell-off-empty::before{content:"\f1f7"}.icon-copyright::before{content:"\f1f9"}.icon-chart-area::before{content:"\f1fe"}.icon-chart-line::before{content:"\f201"}.icon-toggle-off::before{content:"\f204"}.icon-toggle-on::before{content:"\f205"}.icon-user-plus::before{content:"\f234"}.icon-user-times::before{content:"\f235"}.icon-clone::before{content:"\f24d"}.icon-hourglass-o::before{content:"\f250"}.icon-hourglass-1::before{content:"\f251"}.icon-hourglass-2::before{content:"\f252"}.icon-hourglass-3::before{content:"\f253"}.icon-calendar-plus-o::before{content:"\f271"}.icon-calendar-minus-o::before{content:"\f272"}.icon-calendar-times-o::before{content:"\f273"}.icon-calendar-check-o::before{content:"\f274"}.icon-hashtag::before{content:"\f292"}.icon-low-vision::before{content:"\f2a8"}.icon-envelope-open-o::before{content:"\f2b7"}.icon-address-book-o::before{content:"\f2ba"}.icon-user-o::before{content:"\f2c0"}.icon-window-maximize::before{content:"\f2d0"}.icon-window-minimize::before{content:"\f2d1"}.icon-window-restore::before{content:"\f2d2"}.icon-window-close::before{content:"\f2d3"}.icon-window-close-o::before{content:"\f2d4"}.icon-app::before{content:"\e903"}.icon-download-arrow::before{content:"\e904"}.icon-logo::before{content:"\e905"}.icon-feedback::before{content:"\e906"}.icon-action::before{content:"\e907"}.icon-swimlane::before{content:"\e908"}div.ag-dnd-ghost{border-color:transparent;border-radius:0.25rem;color:var(--white);font-size:0.75rem;font-family:inherit;line-height:inherit;background-color:var(--primary);cursor:default}div .ag-dnd-ghost-icon{display:flex;float:none;padding:0 0.25rem 0 0}div .ag-dnd-ghost-icon .ag-icon{background-color:var(--white)}.ag-tick42{padding-top:0}.ag-tick42 a{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border;border-bottom:0.063rem dashed var(--dark);color:var(--t42-content-color)}.ag-tick42 a:hover{text-decoration:none}.ag-tick42 .ag-filter-body{margin:0}.ag-tick42 input{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border;padding:0 0.5rem;border:var(--t42-border);color:var(--t42-content-color);line-height:2rem;background-color:var(--t42-input-bg)}.ag-tick42 input:focus{border-color:var(--primary);outline:0}.ag-tick42 input.ag-column-name-filter{margin-left:0.5rem}.ag-tick42 .ag-input-wrapper{padding:0.25rem}.ag-tick42 .ag-input-wrapper.ag-checkbox-input-wrapper{padding:0}.ag-tick42 .ag-cell-wrapper.ag-row-group{align-items:center}.ag-tick42 .ag-cell{padding:0 0.25rem;border-bottom:var(--t42-border);line-height:1.875rem;white-space:nowrap;text-overflow:ellipsis}.ag-tick42 .ag-cell .btn,.ag-tick42 .ag-cell .btn-sm,.ag-tick42 .ag-cell .btn-group-sm>.btn,.ag-tick42 .ag-cell .btn-lg,.ag-tick42 .ag-cell .btn-group-lg>.btn{line-height:1.25rem}.ag-tick42 .ag-cell .btn-icon i{position:relative;top:0.0625rem}.ag-tick42 .ag-cell:focus{outline:1px solid var(--primary)}.ag-tick42 .ag-cell .dropdown-toggle{width:20px;height:20px;margin-top:-3px;padding:0;border:0;line-height:22px}.ag-tick42 .ag-cell .dropdown-toggle::after{background-color:transparent;content:""}.ag-tick42 .ag-row::before{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:width;position:absolute;top:0;bottom:0;left:0;z-index:1;width:0;background-color:var(--primary);content:""}.ag-tick42 .ag-row.ag-row-selected{color:var(--t42-link-color);background-color:var(--t42-color-opacity-10)}.ag-tick42 .ag-row.ag-row-selected .ag-icon{color:var(--t42-link-color)}.ag-tick42 .ag-pinned-left-header,.ag-tick42 .ag-pinned-left-cols-container,.ag-tick42 .ag-pinned-right-header,.ag-tick42 .ag-pinned-right-cols-container{background-color:Rgb(var(--t42-bg-mid))}.ag-tick42 .ag-pinned-left-cols-container .ag-row-selected::before,.ag-tick42 .ag-pinned-left-cols-container.ag-hidden+.ag-center-cols-clipper .ag-row-selected::before{width:2px}.ag-tick42 .ag-row-hover{background-color:var(--t42-color-opacity-10)}.ag-tick42 .ag-row-hover .ag-cell{color:var(--t42-link-color)}.ag-tick42 .ag-row-hover .ag-loading .ag-icon-loading::after{background:Rgb(var(--t42-bg-light))}.ag-tick42 .ag-row-hover a{border-bottom-color:var(--t42-content-color);color:var(--t42-link-color)}.ag-tick42 .ag-row-hover a:hover{border-bottom-style:solid}.ag-tick42 .ag-header-row:last-of-type{border-bottom:var(--t42-border)}.ag-tick42 .ag-header-cell,.ag-tick42 .ag-header-group-cell{padding:0 0.25rem;border-top:var(--t42-border);border-left:var(--t42-border);color:Hsl(var(--t42-content-color-base), calc(var(--t42-content-color-l) - 20%))}.ag-tick42 .ag-header-cell:first-of-type,.ag-tick42 .ag-header-group-cell:first-of-type{border-left:0}.ag-tick42 .ag-header-cell .ag-header-cell-label,.ag-tick42 .ag-header-cell .ag-header-group-cell-label,.ag-tick42 .ag-header-group-cell .ag-header-cell-label,.ag-tick42 .ag-header-group-cell .ag-header-group-cell-label{font-weight:normal;font-size:83.3%;line-height:1.875rem;text-transform:uppercase}.ag-tick42 .ag-header-cell .ag-header-select-all,.ag-tick42 .ag-header-group-cell .ag-header-select-all{margin-right:0.5rem}.ag-tick42 .ag-header-cell-moving{background-color:Hsl(var(--t42-bg-light-base), calc(var(--t42-bg-light-l) + 5%))}.ag-tick42 .ag-cell-inline-editing{padding-top:0}.ag-tick42 .ag-cell-edit-input{border-top:0;border-bottom:0;border-radius:0}.ag-tick42 .ag-icon{font-family:inherit}.ag-tick42 .ag-icon::before{content:""}.ag-tick42 .ag-react-container .btn-icon{margin-bottom:0.125rem;padding:0 0.5rem}.ag-tick42 .ag-tabs-header{display:flex;height:1.875rem;border-bottom:var(--t42-border);border-bottom-width:0.063rem}.ag-tick42 .ag-tabs-header .ag-tab{display:flex;align-items:center;justify-content:center;width:1.875rem;height:1.875rem;color:var(--primary);cursor:pointer}.ag-tick42 .ag-tabs-header .ag-tab.ag-tab-selected{background-color:var(--primary)}.ag-tick42 .ag-tabs-header .ag-tab.ag-tab-selected .ag-icon{background-color:var(--white)}.ag-tick42 .ag-tabs-body{max-height:280px;overflow:auto}.ag-tick42 .ag-menu,.ag-tick42 .ag-tool-panel{z-index:1040;border:var(--t42-border);border-radius:0;overflow:initial;background-color:rgba(var(--t42-bg-light), 0.75);box-shadow:var(--t42-shadow);backdrop-filter:var(--backdrop-filter)}.ag-tick42 .ag-menu .ag-column-select-column,.ag-tick42 .ag-menu .ag-column-select-column-group,.ag-tick42 .ag-tool-panel .ag-column-select-column,.ag-tick42 .ag-tool-panel .ag-column-select-column-group{display:flex;align-items:center;margin-left:0;line-height:2rem;cursor:pointer}.ag-tick42 .ag-menu .ag-column-select-column .ag-column-select-checkbox:hover,.ag-tick42 .ag-menu .ag-column-select-column-group .ag-column-select-checkbox:hover,.ag-tick42 .ag-tool-panel .ag-column-select-column .ag-column-select-checkbox:hover,.ag-tick42 .ag-tool-panel .ag-column-select-column-group .ag-column-select-checkbox:hover{color:var(--t42-link-color)}.ag-tick42 .ag-menu .ag-column-select-column:hover,.ag-tick42 .ag-menu .ag-column-select-column-group:hover,.ag-tick42 .ag-tool-panel .ag-column-select-column:hover,.ag-tick42 .ag-tool-panel .ag-column-select-column-group:hover{color:Hsl(var(--t42-content--base), 100%);background-color:var(--t42-color-opacity-10)}.ag-tick42 .ag-menu .ag-column-select-header,.ag-tick42 .ag-tool-panel .ag-column-select-header{padding:0.5rem}.ag-tick42 .ag-menu .ag-column-select-column-label,.ag-tick42 .ag-tool-panel .ag-column-select-column-label{margin-left:0.25rem}.ag-tick42 .ag-tab-body{max-height:220px;overflow:auto}.ag-tick42 .ag-tab-body .ag-set-filter-list{height:9rem}.ag-tick42 .ag-tab-body input{border:var(--t42-border)}.ag-tick42 .ag-tab-body input:focus{border-color:var(--primary)}.ag-tick42 .ag-menu-option{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:color;line-height:2rem;cursor:pointer}.ag-tick42 .ag-menu-option .ag-menu-option-icon{color:var(--t42-content-color)}.ag-tick42 .ag-menu-option .ag-menu-option-icon,.ag-tick42 .ag-menu-option .ag-menu-option-popup-pointer{width:2rem;color:var(--t42-content-color);text-align:center}.ag-tick42 .ag-menu-option .ag-menu-option-icon.ag-menu-option-popup-pointer,.ag-tick42 .ag-menu-option .ag-menu-option-icon:hover,.ag-tick42 .ag-menu-option .ag-menu-option-popup-pointer.ag-menu-option-popup-pointer,.ag-tick42 .ag-menu-option .ag-menu-option-popup-pointer:hover{color:var(--t42-content-color)}.ag-tick42 .ag-menu-option .ag-menu-option-icon.ag-menu-option-popup-pointer .ag-icon,.ag-tick42 .ag-menu-option .ag-menu-option-icon:hover .ag-icon,.ag-tick42 .ag-menu-option .ag-menu-option-popup-pointer.ag-menu-option-popup-pointer .ag-icon,.ag-tick42 .ag-menu-option .ag-menu-option-popup-pointer:hover .ag-icon{color:var(--t42-content-color)}.ag-tick42 .ag-menu-option.ag-menu-option-active{color:var(--t42-link-color);background-color:var(--t42-color-opacity-10)}.ag-tick42 .ag-menu-option.ag-menu-option-active .ag-icon{color:var(--t42-content-color)}.ag-tick42 .ag-menu-separator{border-bottom:var(--t42-border);border-bottom-color:var(--t42-color-opacity-10)}.ag-tick42 .ag-menu-column-select-wrapper,.ag-tick42 .ag-primary-cols-list-panel{height:auto}.ag-tick42 .ag-tool-panel .ag-pivot-mode{padding-top:0.5rem}.ag-tick42 .ag-column-tool-panel-column{padding:0 0.25rem}.ag-tick42 .ag-column-tool-panel-column .ag-icon{margin:0 0.25rem}.ag-tick42 .ag-column-tool-panel-column-label,.ag-tick42 span.ag-column-tool-panel-column-group{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;padding-left:0.25rem}.ag-tick42 .ag-column-tool-panel-column-group .ag-icon{margin:0 0.25rem 0 0}.ag-tick42 .ag-root+.ag-tool-panel{box-shadow:none}.ag-tick42 .ag-row-group-leaf-indent{margin-left:24px}.ag-tick42 .ag-group-expanded,.ag-tick42 .ag-group-contracted{display:flex;align-items:center;min-width:0.75rem;height:100%;margin-right:0.5rem}.ag-tick42 .ag-group-value .ag-react-container{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;display:inline;font-size:87.5%}.ag-tick42 .ag-popup-editor{box-shadow:var(--t42-shadow)}.ag-tick42 .ag-rich-select{border:var(--t42-border);border-radius:0;overflow-y:auto;background-color:Rgb(var(--t42-bg-light), 1)}.ag-tick42 .ag-rich-select-row{padding-left:0.75rem}.ag-tick42 .ag-rich-select-row-selected{background:var(--t42-color-opacity-10)}.ag-tick42 .ag-rich-select-value{position:relative;height:2rem;padding-left:0.75rem;border-bottom:var(--t42-border);line-height:2rem}.ag-tick42 .ag-rich-select-value::before{position:absolute;top:0;bottom:0;left:0;width:3px;background-color:var(--primary);content:""}.ag-tick42 .icon-window-maximize::before,.ag-tick42 .icon-window-minimize::before,.ag-tick42 .icon-window-ok::before{font-size:0.813rem}.ag-tick42 .ag-column-drop{border-top:var(--t42-border)}.ag-tick42 .ag-column-drop.ag-column-drop-horizontal{display:flex;height:1.875rem}.ag-tick42 .ag-column-drop.ag-column-drop-horizontal div{display:flex;align-items:center}.ag-tick42 .ag-column-drop.ag-column-drop-horizontal div:first-of-type{margin-right:0.25rem}.ag-tick42 .ag-column-drop .ag-column-drop-empty-message{align-self:center}.ag-tick42 .ag-column-drop .ag-column-drop-cell{display:flex;height:1.125rem;margin:0.125rem 0.25rem;padding:0 0.125rem 0 0.25rem;border-radius:0.25rem;background-color:Rgb(var(--t42-bg-light))}.ag-tick42 .ag-column-drop .ag-column-drop-cell .ag-column-drop-cell-text{padding:0 0.25rem;line-height:1.125rem}.ag-tick42 .ag-column-drop.ag-column-drop-vertical div{justify-content:start}.ag-tick42 .ag-column-drop.ag-column-drop-vertical .ag-icon-group{margin:0 0.25rem}.ag-tick42 .ag-right-arrow{width:1.5rem;padding:0 0.25rem;overflow:hidden;text-indent:-999px;background-color:var(--t42-content-color);transform:rotate(-90deg);-webkit-mask-image:var(--t42-select-indicator)}.ag-tick42 .ag-right-arrow::before{position:absolute;text-indent:999px}.ag-tick42 .ag-group-checkbox{display:flex;align-items:center;width:1rem;height:100%;margin-right:0.5rem}.ag-tick42 .ag-group-checkbox .ag-icon{width:0.875rem;height:0.875rem}.ag-tick42 .ag-group-checkbox:empty{width:initial}.ag-tick42 .ag-ltr .ag-toolpanel-indent-1{padding-left:1rem}.ag-tick42 .ag-ltr .ag-toolpanel-indent-2{padding-left:2rem}.ag-tick42 .ag-ltr .ag-toolpanel-indent-3{padding-left:3rem}.ag-tick42 .ag-ltr .ag-row-group-indent-1{padding-left:calc(1 * 1.45rem)}.ag-tick42 .ag-ltr .ag-row-group-indent-2{padding-left:calc(2 * 1.45rem)}.ag-tick42 .ag-ltr .ag-row-group-indent-3{padding-left:calc(3 * 1.45rem)}.ag-menu .ag-filter-checkbox{min-width:2rem}.ag-menu .ag-icon-checkbox-checked::after{width:0.625rem;height:0.625rem}.ag-menu .ag-column-group-icons{width:1.5rem}.ag-menu .ag-labeled.ag-label-align-right>div{margin-left:0.25rem}.ag-filter-panel{width:100%}.loading-filter{background-color:rgba(var(--t42-bg-light), 0.75);backdrop-filter:var(--backdrop-filter)}#selectAllContainer,.ag-set-filter-item{display:flex;align-items:center;cursor:pointer}#selectAllContainer .ag-filter-value,#selectAllContainer .ag-set-filter-item-value,.ag-set-filter-item .ag-filter-value,.ag-set-filter-item .ag-set-filter-item-value{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}#selectAllContainer .ag-set-filter-item-value,.ag-set-filter-item .ag-set-filter-item-value{margin-left:0.25rem}.ag-filter-checkbox{justify-content:center;min-width:2rem;color:var(--primary)}.ag-set-filter-item:hover,.ag-filter-header-container:hover label{color:var(--t42-link-color);background-color:var(--t42-color-opacity-10)}.ag-set-filter-item:hover .ag-icon,.ag-filter-header-container:hover label .ag-icon{color:var(--t42-link-color)}.ag-input-text-wrapper{padding:0.25rem 0.25rem 0}.ag-primary-cols-header-panel{align-items:center;padding:0.25rem 0.25rem 0.25rem 0}.ag-primary-cols-header-panel div:nth-child(1){width:1.25rem}.ag-primary-cols-header-panel div:nth-child(2){width:1rem;margin-right:0.25rem}.ag-filter-toolpanel-header{display:flex}.ag-filter-toolpanel-header .ag-header-cell-text{padding:0 0.25rem}.ag-filter-condition{justify-content:space-evenly;padding:0.5rem 0}.ag-filter-condition .ag-labeled.ag-label-align-right div{margin-left:0}.ag-radio-button-label{position:relative;color:var(--t42-content-color-muted);cursor:pointer;user-select:none}.ag-radio-button-input-wrapper::before{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, border;position:absolute;left:-1.125rem;display:block;width:0.875rem;height:0.875rem;border:0.0625rem solid var(--t42-content-color-muted);border-radius:50%;cursor:pointer;content:"";pointer-events:all}.ag-radio-button-input-wrapper::after{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, border;position:absolute;left:-0.875rem;display:block;width:0.375rem;height:0.375rem;border-radius:50%;color:var(--white);background-image:none;transform:scale(0);opacity:0;content:""}.ag-radio-button-input-wrapper:focus{border-color:var(--primary)}.ag-radio-button-input-wrapper.ag-checked::before{border-color:var(--t42-color-opacity-30);background-color:var(--primary)}.ag-radio-button-input-wrapper.ag-checked::after{background-color:var(--white);transform:scale(1);opacity:1}.ag-list{z-index:1100;background-color:rgba(var(--t42-bg-mid), 0.7);backdrop-filter:var(--backdrop-filter)}.ag-list .ag-list-item{padding:0 0.5rem;line-height:2rem;cursor:pointer}.ag-list .ag-list-item:hover{background-color:Rgb(var(--t42-bg-light))}.ag-picker-field-wrapper{height:2rem;padding:0 0.5rem;line-height:2rem;cursor:pointer}.ag-column-select-header-icon{display:flex;align-items:center}.ag-column-select-header .ag-text-field-input{height:1.875rem;line-height:1.875rem}.ag-filter-list-panel .ag-filter-toolpanel-expand{margin:0 0.25rem}.ag-filter-list-panel .ag-filter-toolpanel-group-container,.ag-filter-list-panel .ag-filter-toolpanel-instance-filter{padding-left:0.25rem}.ag-side-bar{position:relative}.ag-side-bar .ag-side-bar-right .ag-tool-panel-horizontal-resize{left:-0.375rem}.ag-side-bar>div:first-child{border:var(--t42-border);background-color:var(--t42-color-opacity-10)}.ag-side-bar .ag-pivot-mode-select{display:flex;padding:0.25rem;border-bottom:var(--t42-border)}.ag-side-bar .ag-pivot-mode-select label{margin:0 0 0 0.5rem}.ag-side-bar .ag-pivot-mode-select .ag-checkbox-label{padding-left:0.25rem}.ag-side-bar .ag-side-buttons div.ag-side-button button{width:1rem;height:1rem;padding:0;border:0.0625rem solid transparent;color:Hsl(var(--t42-content-color-base), 100%);background-color:transparent}.ag-side-bar .ag-side-buttons div.ag-side-button button:hover{color:Hsl(var(--t42-content-color-base), 100%);background-color:Rgb(var(--t42-bg-dark))}.ag-side-bar .ag-side-buttons div.ag-side-button button>span{display:none}.ag-side-bar .ag-side-buttons div.ag-side-button.ag-selected button{border-color:var(--t42-color-opacity-30);background-color:var(--primary)}.ag-side-bar .ag-side-buttons div.ag-side-button.ag-selected button [class*="ag-icon-"]{background-color:var(--white)}.ag-side-bar .ag-icon-checkbox-checked::after{width:0.625rem;height:0.625rem}.ag-side-bar .ag-column-panel,.ag-side-bar .ag-filter-panel{padding-left:0.25rem}.ag-side-bar .ag-filter-checkbox{margin-right:0.25rem}.ag-tool-panel-wrapper{border-top:var(--t42-border);border-bottom:var(--t42-border)}.ag-tool-panel-wrapper .ag-set-filter-list{width:100%;height:auto}.ag-tool-panel-wrapper .ag-column-select-checkbox,.ag-tool-panel-wrapper .ag-column-select-header-checkbox{margin:0 0.25rem}.ag-tool-panel-horizontal-resize{top:initial;width:0.188rem;background-color:var(--t42-color-opacity-10)}.ag-column-panel,.ag-column-select-panel,.ag-column-drop-vertical,.ag-column-drop-list{display:block;min-height:initial;max-height:initial;overflow:visible}.ag-column-panel input,.ag-column-select-panel input,.ag-column-drop-vertical input,.ag-column-drop-list input{border:var(--t42-border)}.ag-column-panel input:focus,.ag-column-select-panel input:focus,.ag-column-drop-vertical input:focus,.ag-column-drop-list input:focus{border-color:var(--primary)}[class*="ag-icon-"],.icon-check-1,.icon-check-empty,.icon-resize-horizontal{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:color, transform;display:block;width:0.75rem;height:0.75rem;margin:0 auto;background-color:var(--t42-content-color);background-image:none;mask-repeat:no-repeat;mask-position:center;cursor:pointer}[class*="ag-icon-"]:hover,.icon-check-1:hover,.icon-check-empty:hover,.icon-resize-horizontal:hover{background-color:var(--t42-link-color)}.ag-menu-option-disabled{color:var(--t42-content-color-disabled)}.ag-menu-option-disabled .ag-icon{background-color:var(--t42-content-color-disabled)}.ag-icon-menu{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M475.4,384v36.4c0,5.1-1.7,9.4-5.1,12.8s-7.9,5.3-13.3,5.6H55c-5.1,0-9.4-1.9-12.8-5.6c-3.4-3.8-5.3-8-5.6-12.8V384 c0-5.1,1.9-9.4,5.6-12.8c3.8-3.4,8-5.3,12.8-5.6h401.9c5.1,0,9.6,1.9,13.3,5.6C474,375,475.7,379.2,475.4,384z M475.4,237.6v36.9 c0,4.8-1.7,9-5.1,12.8s-7.9,5.5-13.3,5.1H55c-5.1,0-9.4-1.7-12.8-5.1s-5.3-7.7-5.6-12.8v-36.9c0-4.8,1.9-9,5.6-12.8 c3.8-3.8,8-5.5,12.8-5.1h401.9c5.1,0,9.6,1.7,13.3,5.1S475.7,232.5,475.4,237.6z M475.4,91.7V128c0,4.8-1.7,9-5.1,12.8 s-7.9,5.6-13.3,5.6H55c-5.1,0-9.4-1.9-12.8-5.6s-5.3-8-5.6-12.8V91.7c0-5.1,1.9-9.6,5.6-13.3c3.8-3.8,8-5.5,12.8-5.1h401.9 c5.1,0,9.6,1.7,13.3,5.1S475.7,86.2,475.4,91.7z%27/%3E%3C/svg%3E%0A")}.ag-header-icon{margin-left:0.125rem}.ag-header-icon .ag-icon-menu{line-height:1.875rem}.ag-icon-asc{-webkit-mask-image:var(--t42-select-indicator);transform:rotate(180deg)}.ag-icon-desc{-webkit-mask-image:var(--t42-select-indicator);margin-bottom:2px}.ag-icon-filter{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 16 16%27%3E%3Cpath d=%27M14.9,1.4c0.1,0.3,0.1,0.5-0.1,0.7L9.9,7v7.4c0,0.3-0.1,0.5-0.4,0.6C9.4,15,9.4,15,9.3,15c-0.2,0-0.3-0.1-0.4-0.2l-2.5-2.5 c-0.1-0.1-0.2-0.3-0.2-0.4V7L1.2,2.1C1,1.9,0.9,1.7,1.1,1.4C1.2,1.1,1.4,1,1.7,1h12.7C14.6,1,14.8,1.1,14.9,1.4L14.9,1.4z%27/%3E%3C/svg%3E")}.ag-icon-none{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 16 16%27%3E%3Cpath d=%27M1 6L5 2Q6 1 7 2L11 6Q11 7 10 7L2 7Q1 7 1 6M2 8Q1 8 1 9L5 13Q6 14 7 13L11 9Q11 8 10 8L2 8%27/%3E%3C/svg%3E%0A")}.ag-icon-indeterminate,.ag-icon-checkbox-indeterminate,.ag-icon-checkbox-indeterminate-readonly,.ag-icon-checkbox-unchecked,.ag-icon-checkbox-unchecked-readonly,.ag-icon-checkbox-checked-readonly,.ag-icon-checkbox-checked,.icon-check-1,.icon-check-empty,.ag-checkbox-input-wrapper,.ag-toggle-button-input-wrapper{position:relative;padding:0;color:var(--t42-content-color-muted);background-color:transparent;cursor:pointer;user-select:none}.ag-icon-indeterminate::before,.ag-icon-checkbox-indeterminate::before,.ag-icon-checkbox-indeterminate-readonly::before,.ag-icon-checkbox-unchecked::before,.ag-icon-checkbox-unchecked-readonly::before,.ag-icon-checkbox-checked-readonly::before,.ag-icon-checkbox-checked::before,.icon-check-1::before,.icon-check-empty::before,.ag-checkbox-input-wrapper::before,.ag-toggle-button-input-wrapper::before{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, border-color;display:block;width:100%;height:100%;border:var(--t42-border);border-color:var(--t42-content-color);cursor:pointer;content:"";pointer-events:all}.ag-icon-indeterminate:focus,.ag-icon-checkbox-indeterminate:focus,.ag-icon-checkbox-indeterminate-readonly:focus,.ag-icon-checkbox-unchecked:focus,.ag-icon-checkbox-unchecked-readonly:focus,.ag-icon-checkbox-checked-readonly:focus,.ag-icon-checkbox-checked:focus,.icon-check-1:focus,.icon-check-empty:focus,.ag-checkbox-input-wrapper:focus,.ag-toggle-button-input-wrapper:focus{border-color:var(--primary)}.ag-icon-indeterminate:hover,.ag-icon-checkbox-indeterminate:hover,.ag-icon-checkbox-indeterminate-readonly:hover,.ag-icon-checkbox-unchecked:hover,.ag-icon-checkbox-unchecked-readonly:hover,.ag-icon-checkbox-checked-readonly:hover,.ag-icon-checkbox-checked:hover,.icon-check-1:hover,.icon-check-empty:hover,.ag-checkbox-input-wrapper:hover,.ag-toggle-button-input-wrapper:hover{background-color:transparent}.ag-icon-checkbox-indeterminate,.ag-icon-checkbox-indeterminate-readonly,.ag-icon-checkbox-checked,.ag-icon-checkbox-checked-readonly,.icon-check-empty,.ag-checkbox-input-wrapper.ag-indeterminate,.ag-checkbox-input-wrapper.ag-checked,.ag-toggle-button-input-wrapper.ag-checked{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background, color}.ag-icon-checkbox-indeterminate::before,.ag-icon-checkbox-indeterminate-readonly::before,.ag-icon-checkbox-checked::before,.ag-icon-checkbox-checked-readonly::before,.icon-check-empty::before,.ag-checkbox-input-wrapper.ag-indeterminate::before,.ag-checkbox-input-wrapper.ag-checked::before,.ag-toggle-button-input-wrapper.ag-checked::before{border:0.0625rem solid var(--t42-color-opacity-30);background:var(--primary)}.ag-icon-checkbox-indeterminate::after,.ag-icon-checkbox-indeterminate-readonly::after,.ag-icon-checkbox-checked::after,.ag-icon-checkbox-checked-readonly::after,.icon-check-empty::after,.ag-checkbox-input-wrapper.ag-indeterminate::after,.ag-checkbox-input-wrapper.ag-checked::after,.ag-toggle-button-input-wrapper.ag-checked::after{position:absolute;top:0.063rem;left:0.063rem;display:block;width:0.75rem;height:0.75rem;background:var(--white);content:""}.ag-icon-checkbox-checked::after,.ag-icon-checkbox-checked-readonly::after,.icon-check-empty::after,.ag-checkbox-input-wrapper.ag-checked::after,.ag-toggle-button-input-wrapper.ag-checked::after{-webkit-mask-image:url("data:image/svg+xml,%3Csvg version=%271.1%27 xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M477.44 152.832q0 11.264-8.192 19.456l-245.76 245.76q-8.192 7.68-19.456 7.68t-19.456-7.68l-142.336-142.336q-7.68-8.192-7.68-19.456t7.68-19.456l38.912-38.912q8.192-8.192 19.456-8.192t19.456 8.192l83.968 84.48 187.392-187.904q8.192-8.192 19.456-8.192t19.456 8.192l38.912 38.912q8.192 7.68 8.192 19.456z%27%3E%3C/path%3E%3C/svg%3E%0A")}.ag-icon-checkbox-indeterminate::after,.ag-icon-checkbox-indeterminate-readonly::after,.ag-checkbox-input-wrapper.ag-indeterminate::after{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 -1 5 6%27%3E%3Cpath d=%27M 1 1 A 1 1 0 0 0 1 2 L 4 2 A 1 1 0 0 0 4 1 L 1 1%27/%3E%3C/svg%3E%0A")}.ag-checkbox-input-wrapper.ag-indeterminate::after{top:0.125rem;left:0.125rem}.ag-checkbox-input-wrapper::before,.ag-toggle-button-input-wrapper::before{width:0.875rem;height:0.875rem}.ag-checkbox-input-wrapper .ag-checkbox-input,.ag-checkbox-input-wrapper .ag-toggle-button-input,.ag-toggle-button-input-wrapper .ag-checkbox-input,.ag-toggle-button-input-wrapper .ag-toggle-button-input{position:absolute;z-index:2;width:0.875rem;height:0.875rem}.ag-icon-columns{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M146.432 374.784v55.296q0 11.264-8.192 18.944t-19.456 8.192h-91.136q-11.776 0-19.456-8.192t-8.192-18.944v-55.296q0-11.264 8.192-19.456t19.456-7.68h91.136q11.776 0 19.456 7.68t8.192 19.456zM146.432 228.864v54.784q0 11.264-8.192 19.456t-19.456 7.68h-91.136q-11.776 0-19.456-7.68t-8.192-19.456v-54.784q0-11.776 8.192-19.456t19.456-8.192h91.136q11.776 0 19.456 8.192t8.192 19.456zM329.216 374.784v55.296q0 11.264-8.192 18.944t-19.456 8.192h-91.136q-11.776 0-19.456-8.192t-8.192-18.944v-55.296q0-11.264 8.192-19.456t19.456-7.68h91.136q11.776 0 19.456 7.68t8.192 19.456zM146.432 82.432v54.784q0 11.264-8.192 19.456t-19.456 8.192h-91.136q-11.776 0-19.456-8.192t-8.192-19.456v-54.784q0-11.264 8.192-19.456t19.456-8.192h91.136q11.776 0 19.456 8.192t8.192 19.456zM329.216 228.864v54.784q0 11.264-8.192 19.456t-19.456 7.68h-91.136q-11.776 0-19.456-7.68t-8.192-19.456v-54.784q0-11.776 8.192-19.456t19.456-8.192h91.136q11.776 0 19.456 8.192t8.192 19.456zM512 374.784v55.296q0 11.264-8.192 18.944t-19.456 8.192h-91.136q-11.264 0-19.456-8.192t-8.192-18.944v-55.296q0-11.264 8.192-19.456t19.456-7.68h91.136q11.776 0 19.456 7.68t8.192 19.456zM329.216 82.432v54.784q0 11.264-8.192 19.456t-19.456 8.192h-91.136q-11.776 0-19.456-8.192t-8.192-19.456v-54.784q0-11.264 8.192-19.456t19.456-8.192h91.136q11.776 0 19.456 8.192t8.192 19.456zM512 228.864v54.784q0 11.264-8.192 19.456t-19.456 7.68h-91.136q-11.264 0-19.456-7.68t-8.192-19.456v-54.784q0-11.776 8.192-19.456t19.456-8.192h91.136q11.776 0 19.456 8.192t8.192 19.456zM512 82.432v54.784q0 11.264-8.192 19.456t-19.456 8.192h-91.136q-11.264 0-19.456-8.192t-8.192-19.456v-54.784q0-11.264 8.192-19.456t19.456-8.192h91.136q11.776 0 19.456 8.192t8.192 19.456z%27%3E%3C/path%3E%3C/svg%3E")}.ag-icon-pin{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M228.4,228.6v-128c0-2.7-0.9-4.9-2.6-6.7s-3.9-2.6-6.7-2.6c-2.7,0-4.9,0.9-6.7,2.6c-1.7,1.7-2.6,3.9-2.6,6.7v128 c0,2.7,0.9,4.9,2.6,6.7c1.7,1.7,3.9,2.6,6.7,2.6c2.7,0,4.9-0.9,6.7-2.6S228.4,231.3,228.4,228.6z M420.4,329.5c0,4.8-1.9,9-5.6,12.8 c-3.8,3.8-8,5.5-12.8,5.1H279.6l-14.8,138.2c-0.3,2.4-1.4,4.3-3.1,5.6c-1.7,1.4-3.6,2.2-5.6,2.6h-0.5c-5.1,0-8-2.6-8.7-7.7 l-22-138.8H109.6c-5.1,0-9.4-1.7-12.8-5.1c-3.4-3.4-5.3-7.7-5.6-12.8c0-23.6,7.5-44.7,22.5-63.5s31.9-28.2,50.7-28.2V91.4 c-9.9,0-18.4-3.6-25.6-10.8c-7.2-7.2-10.9-15.7-11.3-25.6s3.4-18.4,11.3-25.6c7.9-7.2,16.4-10.9,25.6-11.3h182.8 c9.9,0,18.4,3.8,25.6,11.3s10.8,16,10.8,25.6s-3.6,18.1-10.8,25.6S357,91.7,347.1,91.4v146.4c18.8,0,35.7,9.4,50.7,28.2 C412.8,284.8,420.4,305.9,420.4,329.5L420.4,329.5z%27/%3E%3C/svg%3E")}.ag-icon-small-right,.ag-icon-small-down{width:0.65rem;height:0.65rem;-webkit-mask-image:var(--t42-select-indicator);transform:rotate(-90deg)}.ag-icon-small-down{transform:rotate(0)}.ag-icon-tick{-webkit-mask-image:url("data:image/svg+xml,%3Csvg version=%271.1%27 xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M477.44 152.832q0 11.264-8.192 19.456l-245.76 245.76q-8.192 7.68-19.456 7.68t-19.456-7.68l-142.336-142.336q-7.68-8.192-7.68-19.456t7.68-19.456l38.912-38.912q8.192-8.192 19.456-8.192t19.456 8.192l83.968 84.48 187.392-187.904q8.192-8.192 19.456-8.192t19.456 8.192l38.912 38.912q8.192 7.68 8.192 19.456z%27%3E%3C/path%3E%3C/svg%3E%0A")}.ag-icon-copy{-webkit-mask-image:url("data:image/svg+xml,")}.ag-icon-csv,.ag-icon-excel{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M0 0zq0-7.7-5.1-12.8zM475.3 356.6v91.6q0 11.3-8.2 18.9t-19.5 8.2h-420.4q-11.8 0-19.5-8.2t-8.2-18.9v-91.6q0-11.3 8.2-19.5t19.5-8.2h132.6l38.4 38.9q16.9 16.4 38.9 16.4t38.9-16.4l38.9-38.9h132.6q11.3 0 19.5 8.2t8.2 19.5zM382.1 193.8q5.1 11.8-4.1 20l-128 128q-5.1 5.6-12.8 5.6t-12.8-5.6l-128-128q-8.7-8.2-4.1-20q5.1-10.8 16.9-10.8h73.2v-128q0-7.7 5.6-12.8t12.8-5.6h73.2q7.2 0 12.8 5.6t5.1 12.8v128h73.2q12.3 0 16.9 10.8M347 439A1 1 0 00347 402A1 1 0 00347 439M420 439A1 1 0 00420 402A1 1 0 00420 439zz%27/%3E%3C/svg%3E%0A")}.ag-icon-expanded{-webkit-mask-image:var(--t42-select-indicator);transform:rotate(-90deg)}.ag-icon-contracted{-webkit-mask-image:var(--t42-select-indicator);transform:rotate(90deg)}.ag-header-expand-icon-collapsed .ag-icon-contracted{margin-bottom:1px;transform:rotate(90deg);-webkit-mask-image:var(--t42-select-indicator)}.ag-icon-paste{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M219.648 475.648h256v-183.296h-119.296q-11.264 0-18.944-7.68t-8.192-19.456v-118.784h-109.568v329.216zM292.352 64v-18.432q0-3.584-2.56-6.144t-6.144-3.072h-201.216q-3.584 0-6.656 3.072t-2.56 6.144v18.432q0 3.584 2.56 6.656t6.656 2.56h201.216q3.584 0 6.144-2.56t2.56-6.656zM365.568 256h85.504l-85.504-85.504v85.504zM512 292.352v192q0 11.776-8.192 19.456t-19.456 8.192h-273.92q-11.776 0-19.456-8.192t-8.192-19.456v-45.568h-155.136q-11.776 0-19.456-8.192t-8.192-18.944v-384q0-11.776 8.192-19.456t19.456-8.192h310.784q11.264 0 19.456 8.192t7.68 19.456v93.696q6.144 3.584 10.24 7.68l116.736 116.736q8.192 7.68 13.824 21.504t5.632 25.088z%27%3E%3C/path%3E%3C/svg%3E%0A")}.ag-icon-arrows{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M512 256q0 7.168-5.632 12.8l-72.704 73.216q-5.632 5.632-13.312 5.632t-12.8-5.632-5.12-12.8v-36.864h-110.080v110.080h36.864q7.168 0 12.8 5.12t5.632 12.8-5.632 12.8l-73.216 73.216q-5.12 5.632-12.8 5.632t-12.8-5.632l-73.216-73.216q-5.632-5.12-5.632-12.8t5.632-12.8 12.8-5.12h36.864v-110.080h-110.080v36.864q0 7.168-5.12 12.8t-12.8 5.632-12.8-5.632l-73.216-73.216q-5.632-5.632-5.632-12.8t5.632-12.8l73.216-73.216q5.12-5.632 12.8-5.632t12.8 5.632 5.12 12.8v36.864h110.080v-110.080h-36.864q-7.168 0-12.8-5.12t-5.632-12.8 5.632-13.312l73.216-72.704q5.632-5.632 12.8-5.632t12.8 5.632l73.216 72.704q5.632 5.632 5.632 13.312t-5.632 12.8-12.8 5.12h-36.864v110.080h110.080v-36.864q0-7.168 5.12-12.8t12.8-5.632 13.312 5.632l72.704 73.216q5.632 5.12 5.632 12.8z%27%3E%3C/path%3E%3C/svg%3E%0A")}.ag-icon-not-allowed{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27m 182.8 238.1 h 145.9 v -55.3 c 0 -20.1 -7.2 -37.4 -21.5 -51.7 s -31.6 -21.3 -51.7 -21 c -20.1 0.3 -37.4 7.3 -51.7 21 s -21.3 30.9 -21 51.7 l -0 55.3 l 0 0 z m 237.6 27.1 v 164.9 c 0 7.5 -2.7 13.8 -8.2 18.9 s -11.9 7.9 -19.5 8.2 h -273.9 c -7.9 0 -14.3 -2.7 -19.5 -8.2 c -5.1 -5.5 -7.9 -11.8 -8.2 -18.9 v -164.9 c 0 -7.5 2.7 -14 8.2 -19.5 s 11.9 -8 19.5 -7.7 h 8.7 v -55.3 c 0 -34.8 12.6 -64.9 37.9 -90.1 s 55.3 -37.9 90.1 -37.9 s 65 12.6 90.6 37.9 s 38.1 55.3 37.4 90.1 v 55.3 h 9.2 c 7.9 0 14.3 2.6 19.5 7.7 s 7.8 11.7 8.2 19.5 z%27/%3E%3C/svg%3E")}.ag-icon-eye-slash{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M 475.6 256.3 q -43.5 -67.6 -109.1 -100.9 q 17.4 29.7 17.4 64 q 0 52.7 -37.4 90.6 t -90.6 37.4 t -90.6 -37.4 t -37.4 -90.6 q 0 -34.3 17.4 -64 q -65.5 33.3 -109.1 100.9 q 38.4 58.4 95.7 93.2 t 123.9 34.8 t 124.4 -34.8 t 95.2 -93.2 z M 269.8 146.2 q 0 -5.6 -4.1 -9.7 t -9.7 -3.6 q -35.8 0 -61.4 25.6 t -25.6 60.9 q 0 5.6 4.1 9.7 t 9.7 4.1 t 9.7 -4.1 t 4.1 -9.7 q 0 -24.6 17.4 -42 t 42 -17.4 q 5.6 0 9.7 -4.1 t 4.1 -9.7 z M 512 256.3 q 0 9.7 -5.6 19.5 q -39.9 66 -107.5 105.5 t -142.8 39.4 t -142.8 -39.4 t -107.5 -105.5 q -5.6 -9.7 -5.6 -19.5 t 5.6 -20 q 39.9 -65.5 107.5 -105 t 142.8 -39.9 t 142.8 39.9 t 107.5 105 q 5.6 10.2 5.6 20 z%27%3E%3C/path%3E%3C/svg%3E%0A")}.ag-icon-group{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M146.4 374.8v55.3q0 11.3-8.2 18.9t-19.5 8.2h-91.1q-11.8 0-19.5-8.2t-8.2-18.9v-55.3q0-11.3 8.2-19.5t19.5-7.7h91.1q11.8 0 19.5 7.7t8.2 19.5zM146.4 228.9v54.8q0 11.3-8.2 19.5t-19.5 7.7h-91.1q-11.8 0-19.5-7.7t-8.2-19.5v-54.8q0-11.8 8.2-19.5t19.5-8.2h91.1q11.8 0 19.5 8.2t8.2 19.5zM512 374.8v55.3q0 11.3-8.2 18.9t-19.5 8.2h-273.9q-11.8 0-19.5-8.2t-8.2-18.9v-55.3q0-11.3 8.2-19.5t19.5-7.7h273.9q11.8 0 19.5 7.7t8.2 19.5zM146.4 82.4v54.8q0 11.3-8.2 19.5t-19.5 8.2h-91.1q-11.8 0-19.5-8.2t-8.2-19.5v-54.8q0-11.3 8.2-19.5t19.5-8.2h91.1q11.8 0 19.5 8.2t8.2 19.5zM512 228.9v54.8q0 11.3-8.2 19.5t-19.5 7.7h-273.9q-11.8 0-19.5-7.7t-8.2-19.5v-54.8q0-11.8 8.2-19.5t19.5-8.2h273.9q11.8 0 19.5 8.2t8.2 19.5zM512 82.4v54.8q0 11.3-8.2 19.5t-19.5 8.2h-273.9q-11.8 0-19.5-8.2t-8.2-19.5v-54.8q0-11.3 8.2-19.5t19.5-8.2h273.9q11.8 0 19.5 8.2t8.2 19.5z%27%3E%3C/path%3E%3C/svg%3E%0A")}.ag-icon-grip{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 16 16%27%3E%3Cpath d=%27M4 3L6 3L6 5L4 5L4 3M4 7L6 7L6 9L4 9L4 7M4 11L6 11L6 13L4 13L4 11M8 3L10 3L10 5L8 5L8 3M8 7L10 7L10 9L8 9L8 7M8 11L10 11L10 13L8 13L8 11%27/%3E%3C/svg%3E%0A");margin:0}.ag-icon-tree-open{-webkit-mask-image:var(--t42-select-indicator);transform:rotate(180deg)}.ag-icon-tree-closed{-webkit-mask-image:var(--t42-select-indicator);transform:rotate(270deg)}.ag-icon-tree-indeterminate{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 -1 5 6%27%3E%3Cpath d=%27M 1 1 A 1 1 0 0 0 1 2 L 4 2 A 1 1 0 0 0 4 1 L 1 1%27/%3E%3C/svg%3E%0A")}.ag-icon-save{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M 420.6 319.2 V 393 c 0 22.9 -8 42.3 -24.1 58.4 s -35.5 24.1 -58.4 24.1 H 100.6 c -22.9 0 -42.3 -8 -58.4 -24.1 S 18.2 415.8 18.2 393 V 155.4 c 0 -22.5 8 -41.8 24.1 -57.9 S 77.7 73.3 100.6 73 h 72.7 c 2.4 0 4.6 1 6.7 3.1 c 2 2 2.9 4.1 2.6 6.1 c 0 5.1 -2.6 8.2 -7.7 9.2 c -14.7 5.1 -27.3 10.9 -37.9 17.4 c -1.7 0.7 -3.2 1 -4.6 1 h -31.7 c -12.6 0 -23.4 4.4 -32.3 13.3 s -13.5 19.6 -13.8 32.3 V 393 c 0 12.6 4.6 23.4 13.8 32.3 c 9.2 8.9 20 13.5 32.3 13.8 h 237.6 c 12.6 0 23.4 -4.6 32.3 -13.8 c 8.9 -9.2 13.3 -20 13.3 -32.3 V 332 c 0 -3.8 1.7 -6.5 5.1 -8.2 c 5.5 -2.4 10.8 -6 15.9 -10.8 c 2.7 -3.1 6 -3.8 9.7 -2 C 418.6 312.7 420.6 315.5 420.6 319.2 L 420.6 319.2 z M 488.2 177.4 L 378.6 287 c -3.4 3.8 -7.7 5.6 -12.8 5.6 c -2.4 0 -4.8 -0.5 -7.2 -1.5 c -7.5 -3.1 -11.3 -8.7 -11.3 -16.9 v -54.8 h -45.6 c -61.8 0 -103.6 12.5 -125.4 37.4 c -22.5 26.3 -29.5 71.3 -21 135.2 c 0.7 4.4 -1.2 7.7 -5.6 9.7 c -1.7 0.3 -2.9 0.5 -3.6 0.5 c -3.1 0 -5.5 -1.2 -7.2 -3.6 c -2 -2.7 -4.1 -5.6 -6.1 -8.7 c -2 -3.1 -5.8 -9.7 -11.3 -20 c -5.5 -10.2 -10.2 -19.6 -14.3 -28.2 c -4.1 -8.5 -7.7 -19.5 -10.8 -32.8 c -3.1 -13.3 -4.8 -24.9 -5.1 -34.8 c 0 -9.2 0.3 -17.9 1 -26.1 c 0.7 -8.2 2 -16.7 4.1 -25.6 c 2 -8.9 4.6 -17.2 7.7 -25.1 c 3.1 -7.9 7.7 -15.5 13.8 -23 c 6.1 -7.5 12.6 -14.7 19.5 -21.5 s 15.7 -12.6 26.6 -17.4 c 10.9 -4.8 22.9 -9.4 35.8 -13.8 c 13 -4.4 28.2 -7.3 45.6 -8.7 s 36.2 -2.4 56.3 -3.1 h 45.6 V 55 c 0 -8.2 3.8 -13.8 11.3 -16.9 c 2.4 -1 4.8 -1.5 7.2 -1.5 c 4.8 0 9 1.9 12.8 5.6 l 109.6 109.6 c 3.8 3.4 5.6 7.7 5.6 12.8 S 491.9 174 488.2 177.4 L 488.2 177.4 z%27/%3E%3C/svg%3E")}.ag-tooltip{padding:0.125rem 0.5rem;border:0.0625rem solid var(--t42-color-opacity-10);border-radius:0.25rem;background:Rgb(var(--t42-bg-light));box-shadow:var(--t42-shadow)}.ag-icon-cancel{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M366.9 336.4c6.1 6.1 9.2 13.5 9.2 22s-3.1 15.9-9.2 22c-6.1 5.5-13.5 8.2-22 8.2c-8.5 0-15.9-2.7-22-8.2l-67.6-77.8l-67.6 77.8c-6.1 5.5-13.5 8.2-22 8.2c-8.5 0-15.9-2.7-22-8.2c-5.5-6.1-8.2-13.5-8.2-22s2.7-15.9 8.2-22l70.7-79.9l-70.7-80.9c-5.5-6.1-8.2-13.5-8.2-22c0-8.5 2.7-15.9 8.2-22c6.1-5.5 13.5-8.2 22-8.2c8.5 0 15.9 2.7 22 8.2l67.6 77.8l67.6-77.8c6.1-5.5 13.5-8.2 22-8.2c8.5 0 15.9 2.7 22 8.2c6.1 6.1 9.2 13.5 9.2 22c0 8.5-3.1 15.9-9.2 22l-70.7 80.9L366.9 336.4z%27/%3E%3C/svg%3E")}.icon-check-empty::after{width:0.65rem;height:0.65rem}.icon-resize-horizontal{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M512 256q0 7.2-5.6 12.8l-72.7 73.2q-5.6 5.6-13.3 5.6t-12.8-5.6t-5.1-12.8v-36.9h-292.9v36.9q0 7.2-5.1 12.8t-12.8 5.6t-12.8-5.6l-73.2-73.2q-5.6-5.6-5.6-12.8t5.6-12.8l73.2-73.2q5.1-5.6 12.8-5.6t12.8 5.6t5.1 12.8v36.9h292.9v-36.9q0-7.2 5.1-12.8t12.8-5.6t13.3 5.6l72.7 73.2q5.6 5.1 5.6 12.8z%27%3E%3C/path%3E%3C/svg%3E%0A")}.ag-icon-aggregation{margin:0 0.25rem;-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 16 16%27%3E%3Cpath d=%27M3.6,1.7c-0.2,0.7-0.9,1.1-1.5,1C1.5,2.6,1,2,1,1.3C1,0.7,1.5,0.1,2.1,0c0.4-0.1,0.7,0,1,0.2C3.4,0.4,3.6,0.7,3.7,1 c0.3,0,0.5,0.1,0.8,0.3C4.7,1.5,5,1.8,5.2,2.1c0.2,0.3,0.4,0.7,0.6,1c0.1,0.2,0.3,0.5,0.5,0.7c0.2,0.2,0.5,0.5,0.8,0.6 c0.1,0.1,0.3,0.1,0.5,0.1c0.6,0,2.3,0,2.9,0c0.4,0,0.7,0,1.1,0c0,0,0,0,0.1,0c0,0,0,0,0-0.1c0-0.1,0-0.2,0-0.3c0,0,0-0.1,0-0.1 c0-0.1,0.1-0.1,0.2-0.1c0.1,0,0.1,0,0.1,0.1c0.1,0,0.1,0.1,0.2,0.2c0.2,0.2,0.3,0.3,0.5,0.5C12.8,4.8,13,5,13.1,5.1c0,0,0,0,0,0 c0,0,0,0-0.1,0c-1.5,0-4.1,0-5.7,0C7.2,5.2,7,5.1,6.8,5C6.6,4.9,6.3,4.8,6.1,4.6C5.7,4.3,5.5,4,5.2,3.5C5,3.2,4.8,2.8,4.6,2.4 C4.4,2.2,4.3,2.1,4.1,1.9C4,1.8,3.9,1.7,3.8,1.7C3.7,1.7,3.7,1.7,3.6,1.7z%27/%3E%3Cpath d=%27M3.6,7.7c1,0,10.6,0,11,0c0.1,0,0.1,0,0.1,0.1C14.8,7.8,14.9,7.9,15,8c-0.1,0.1-0.2,0.2-0.3,0.3c0,0,0,0-0.1,0 c0,0,0,0-0.1,0c-3.3,0-7.7,0-10.9,0C3.5,8.8,3.2,9.1,2.8,9.3C2.5,9.4,2.2,9.4,2,9.3C1.4,9.1,1,8.6,1,8c0-0.7,0.5-1.2,1.1-1.3 c0.3-0.1,0.7,0,1,0.2C3.4,7.1,3.6,7.3,3.6,7.7z%27/%3E%3Cpath d=%27M13.1,10.9C13.1,10.9,13.1,10.9,13.1,10.9c-0.3,0.3-0.6,0.6-0.8,0.8c-0.1,0.1-0.2,0.2-0.3,0.3c0,0-0.1,0.1-0.1,0.1 c0,0-0.1,0-0.1,0c-0.1,0-0.1,0-0.2-0.1c0,0,0-0.1,0-0.1c0-0.1,0-0.2,0-0.3c0,0,0,0,0-0.1c-1,0-3.1,0-4.1,0c-0.1,0-0.3,0-0.4,0.1 c-0.3,0.1-0.5,0.2-0.7,0.4c-0.2,0.2-0.4,0.5-0.6,0.8c-0.2,0.4-0.4,0.7-0.7,1.1c-0.2,0.2-0.4,0.4-0.6,0.6c-0.1,0.1-0.3,0.2-0.4,0.3 c-0.1,0.1-0.3,0.2-0.4,0.2c0,0-0.1,0-0.1,0c-0.1,0.4-0.3,0.7-0.7,0.9C2.7,16,2.4,16,2.1,16C1.5,15.9,1,15.3,1,14.7 c0-0.7,0.5-1.2,1-1.3c0.3-0.1,0.7,0,1,0.2c0.3,0.2,0.5,0.5,0.6,0.8c0.1,0,0.2,0,0.2,0C4,14.2,4.1,14.1,4.2,14 c0.2-0.2,0.3-0.4,0.5-0.6c0.2-0.3,0.4-0.6,0.6-1c0.2-0.3,0.4-0.6,0.6-0.9c0.3-0.2,0.5-0.5,0.9-0.6c0.2-0.1,0.4-0.1,0.6-0.1 c0,0,0.1,0,0.1,0c0.6,0,2.4,0,3,0c0.8,0,1.7,0,2.5,0C13.1,10.9,13.1,10.9,13.1,10.9C13.1,10.9,13.1,10.9,13.1,10.9z%27/%3E%3Cpath d=%27M3.6,11.7c-0.1,0.4-0.3,0.7-0.7,0.9c-0.3,0.2-0.6,0.2-0.9,0.1C1.5,12.6,1,12.1,1,11.4c0-0.7,0.5-1.2,1.1-1.3 c0.3-0.1,0.7,0,1,0.2c0.3,0.2,0.5,0.5,0.6,0.8c0.1,0,0.1,0,0.2,0c0.2,0,0.3-0.1,0.4-0.2c0.2-0.1,0.4-0.3,0.5-0.4 C4.9,10.3,5,10.2,5,10.2C5.3,9.9,5.6,9.7,6,9.6c0.3-0.1,0.6-0.2,0.8-0.2c0.1,0,0.1,0,0.2,0c1.1,0,3.4,0,4.5,0c0.9,0,1.8,0,2.6,0 c0,0,0,0,0.1,0c0,0,0,0,0,0C14,9.6,13.8,9.8,13.6,10c-1.8,0-4.8,0-6.6,0c-0.3,0-0.6,0.1-0.9,0.2c-0.2,0.1-0.5,0.3-0.6,0.5 c-0.3,0.3-0.5,0.5-0.8,0.7c-0.2,0.1-0.4,0.2-0.6,0.3C3.9,11.7,3.8,11.7,3.6,11.7C3.7,11.7,3.7,11.7,3.6,11.7z%27/%3E%3Cpath d=%27M3.6,4.9C3.5,5.3,3.3,5.6,2.9,5.8C2.6,5.9,2.3,6,2,5.9C1.4,5.7,1,5.2,1,4.5c0-0.6,0.5-1.2,1.1-1.3c0.7-0.1,1.4,0.3,1.5,1 c0,0,0.1,0,0.1,0c0.3,0,0.5,0.1,0.7,0.3C4.7,4.7,5,4.9,5.2,5c0.1,0.1,0.2,0.2,0.4,0.4c0.3,0.3,0.6,0.5,1,0.5C6.7,6,6.9,6,7,6 c1.8,0,4.8,0,6.6,0c0.1,0.1,0.3,0.3,0.6,0.6c0,0,0,0,0,0c0,0,0,0,0,0c0,0,0,0-0.1,0c-2,0-5.1,0-7.1,0c-0.3,0-0.5,0-0.8-0.1 C6,6.5,5.7,6.4,5.5,6.2C5.3,6.1,5.1,5.9,5,5.8C4.8,5.5,4.5,5.3,4.2,5.1C4.1,5,3.9,4.9,3.6,4.9z%27/%3E%3C/svg%3E%0A")}.ag-icon-loading{position:relative;width:1rem;height:1rem;border-radius:50%;background:linear-gradient(to right, var(--t42-icon-color), Rgba(var(--t42-bg-dark) 42%));transform:translateZ(0);animation:icon-loading 1.4s infinite linear}.ag-icon-loading::before{position:absolute;top:0;left:0;width:50%;height:50%;border-radius:100% 0 0;background:var(--t42-icon-color);content:""}.ag-icon-loading::after{position:absolute;top:0;right:0;bottom:0;left:0;width:75%;height:75%;margin:auto;border-radius:50%;background:Rgb(var(--t42-bg-dark));content:""}.ag-loading{display:flex;padding-left:0.5rem}@keyframes icon-loading{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.search{position:relative}.search i{position:absolute;top:0.625rem;right:0.75rem;width:.75rem;height:.75rem;background-color:var(--t42-content-color);-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M328.9 219.4q0-52.7-37.4-90.1t-90.6-37.9t-90.6 37.9t-37.4 90.1t37.4 90.6t90.6 37.4t90.6-37.4t37.4-90.6zM475.3 457.5q0 14.8-11.3 25.6t-25.6 10.8q-15.4 0-25.6-10.8l-97.8-97.8q-51.2 35.3-114.2 35.3q-41 0-78.3-15.9t-64-43t-43-64t-15.9-78.3t15.9-77.8t43-64.5t64-43t78.3-15.9t78.3 15.9t64 43t43 64.5t15.9 77.8q0 63-35.3 114.2l97.8 97.8q10.8 10.8 10.8 26.1z%27%3E%3C/path%3E%3C/svg%3E%0A")}.search-results{position:absolute;top:33px;max-height:215px;overflow-y:auto}.search-results .list-group-item{white-space:nowrap}.select{position:relative;z-index:12;display:flex;align-items:center;justify-content:center;width:100%;height:2rem;list-style:none;cursor:pointer}.select input[type="radio"]{opacity:1}.select_expand{position:absolute;top:0;right:0;width:0;height:2rem}.select_expand::after{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:transform;position:absolute;top:50%;right:0;z-index:2;width:1rem;height:1rem;background:var(--t42-select-indicator) center center/1rem 1rem no-repeat;transform:translate(-65%, -55%);content:"";pointer-events:none}.select_expand:checked+.select_close_label+.select_options .select_label:hover{color:var(--t42-link-hover-color);background-color:var(--t42-link-active-bg)}.select_expand:checked::after{transform:translate(-65%, -55%) rotate(-180deg)}.select_expand_label{position:absolute;top:0;left:0;display:block;width:100%;height:2rem;margin-bottom:0;cursor:pointer}.select_close{display:none}.select_close_label{position:fixed;top:0;left:0;display:none;margin-bottom:0}.select_items{position:absolute;top:0;left:0;width:100%;min-height:2rem;border-color:var(--t42-color-opacity-10);border-style:solid;border-width:1px}.select_items:hover{border-color:var(--primary)}.select_input{display:none}.select_label{display:block;height:0;margin-bottom:0;padding-left:0.875rem;overflow:hidden;line-height:2rem;cursor:pointer;transition:all 200ms cubic-bezier(0.4, 0.25, 0.3, 1)}.select_label-placeholder{position:absolute;top:0;left:0;height:2rem;vertical-align:middle;background-color:transparent}.select_expand:checked+.select_close_label{display:block}.select_expand:checked+.select_close_label::before,.select_expand:checked+.select_close_label::after{display:none}.select_expand:checked+.select_close_label+.select_options .select_label{height:2rem}.select_expand:checked+.select_close_label+.select_options+.select_expand_label{display:none}.select_input:checked+.select_label{height:2rem}.select_option label{color:var(--t42-content-color)}.select_options{max-height:10rem;padding-left:0;overflow:auto;list-style:none}.dark{--t42-json-icons: url("data:image/svg+xml,%3C%3Fxml version=%271.0%27 encoding=%27UTF-8%27 standalone=%27no%27%3F%3E%3Csvg xmlns:dc=%27http://purl.org/dc/elements/1.1/%27 xmlns:cc=%27http://creativecommons.org/ns%23%27 xmlns:rdf=%27http://www.w3.org/1999/02/22-rdf-syntax-ns%23%27 xmlns:svg=%27http://www.w3.org/2000/svg%27 xmlns=%27http://www.w3.org/2000/svg%27 xmlns:sodipodi=%27http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd%27 xmlns:inkscape=%27http://www.inkscape.org/namespaces/inkscape%27 width=%27240%27 height=%27144%27 id=%27svg4136%27 version=%271.1%27 inkscape:version=%270.91 r13725%27 sodipodi:docname=%27jsoneditor-icons.svg%27%3E%3Ctitle id=%27title6512%27%3EJSON Editor Icons%3C/title%3E%3Crect id=%27svg_1-7%27 height=%2716%27 width=%2716%27 y=%273.999995%27 x=%2728.000006%27 style=%27fill:%23ff511f;%27 /%3E%3Crect x=%277%27 y=%2711%27 width=%2710%27 height=%272%27 id=%27svg_1-1%27 style=%27fill:%23ffffff;%27 /%3E%3Crect x=%2711%27 y=%277%27 width=%272%27 height=%2710%27 id=%27svg_1-1-1%27 style=%27fill:%23ffffff;%27 /%3E%3Cg id=%27g4299-3%27 transform=%27matrix%280.70710678,-0.70710678,0.70710678,0.70710678,19.029435,12.000001%29%27 style=%27%27%3E%3Crect x=%277%27 y=%2711%27 width=%2710%27 height=%272%27 id=%27svg_1-1-0%27 style=%27fill:%23ffffff;%27 /%3E%3Crect x=%2711%27 y=%277%27 width=%272%27 height=%2710%27 id=%27svg_1-1-1-9%27 style=%27fill:%23ffffff;%27 /%3E%3C/g%3E%3Crect height=%277%27 width=%277%27 y=%277%27 x=%2755%27 style=%27fill:%23ffffff;stroke-width:1;stroke:%23ffffff%27 /%3E%3Crect id=%27svg_1-7-5-7%27 height=%277%27 width=%277%27 y=%2710%27 x=%2758%27 style=%27fill:%23ffffff;stroke-width:1;stroke:%231d1d1d%27 /%3E%3Cg id=%27g4378%27%3E%3Crect style=%27fill:%23ffffff;%27 x=%27198%27 y=%2711%27 width=%278%27 height=%272%27 id=%27svg_1-7-5-3%27 /%3E%3Crect id=%27rect4374%27 height=%272%27 width=%2712%27 y=%277%27 x=%27198%27 style=%27fill:%23ffffff;%27 /%3E%3Crect id=%27rect4376%27 height=%272%27 width=%274%27 y=%2715%27 x=%27198%27 style=%27fill:%23ffffff;%27 /%3E%3C/g%3E%3Cg transform=%27matrix%281,0,0,-1,-23.999995,23.999995%29%27 id=%27g4383%27%3E%3Crect id=%27rect4385%27 height=%272%27 width=%278%27 y=%2711%27 x=%27198%27 style=%27fill:%23ffffff;%27 /%3E%3Crect style=%27fill:%23ffffff;%27 x=%27198%27 y=%277%27 width=%2712%27 height=%272%27 id=%27rect4387%27 /%3E%3Crect style=%27fill:%23ffffff;%27 x=%27198%27 y=%2715%27 width=%274%27 height=%272%27 id=%27rect4389%27 /%3E%3C/g%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 85.10447,6.0157384 -0.0156,1.4063 c 3.02669,-0.2402 0.33008,3.6507996 2.48438,4.5780996 -2.18694,1.0938 0.49191,4.9069 -2.45313,4.5781 l -0.0156,1.4219 c 5.70828,0.559 1.03264,-5.1005 4.70313,-5.2656 l 0,-1.4063 c -3.61303,-0.027 1.11893,-5.7069996 -4.70313,-5.3124996 z%27 id=%27path4351%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 82.78125,5.9984384 0.0156,1.4063 c -3.02668,-0.2402 -0.33007,3.6506996 -2.48437,4.5780996 2.18694,1.0938 -0.49192,4.9069 2.45312,4.5781 l 0.0156,1.4219 c -5.70827,0.559 -1.03263,-5.1004 -4.70312,-5.2656 l 0,-1.4063 c 3.61303,-0.027 -1.11894,-5.7070996 4.70312,-5.3124996 z%27 id=%27path4351-9%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 103.719,5.6719384 0,12.7187996 3.03125,0 0,-1.5313 -1.34375,0 0,-9.6249996 1.375,0 0,-1.5625 z%27 id=%27path2987%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 112.2185,5.6721984 0,12.7187996 -3.03125,0 0,-1.5313 1.34375,0 0,-9.6249996 -1.375,0 0,-1.5625 z%27 id=%27path2987-1%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27M133,6.4h-1.9l-4.8,11.2h1.8l1.1-2.9h5.7l1.1,2.9h1.8L133,6.4z M129.7,13.5l2.3-5.5l2.3,5.5L129.7,13.5z%27 id=%27path3780%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 156.47655,5.8917384 0,2.1797 0.46093,2.3983996 1.82813,0 0.39844,-2.3983996 0,-2.1797 z%27 id=%27path5008-2%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 152.51561,5.8906384 0,2.1797 0.46094,2.3983996 1.82812,0 0.39844,-2.3983996 0,-2.1797 z%27 id=%27path5008-2-8%27 /%3E%3Crect id=%27svg_1-7-2%27 height=%272%27 width=%2712%27 y=%2764%27 x=%2754%27 style=%27fill:%236e6e6e;%27 /%3E%3Crect id=%27svg_1-7-2-2%27 height=%273%27 width=%273%27 y=%2752%27 x=%2780%27 style=%27fill:%236e6e6e;%27 /%3E%3Crect style=%27fill:%236e6e6e;%27 x=%2785%27 y=%2752%27 width=%273%27 height=%273%27 id=%27rect4561%27 /%3E%3Crect style=%27fill:%236e6e6e;%27 x=%2780%27 y=%2758%27 width=%273%27 height=%273%27 id=%27rect4563%27 /%3E%3Crect id=%27rect4565%27 height=%273%27 width=%273%27 y=%2758%27 x=%2785%27 style=%27fill:%236e6e6e;%27 /%3E%3Crect id=%27rect4567%27 height=%273%27 width=%273%27 y=%2764%27 x=%2780%27 style=%27fill:%236e6e6e;%27 /%3E%3Crect style=%27fill:%236e6e6e;%27 x=%2785%27 y=%2764%27 width=%273%27 height=%273%27 id=%27rect4569%27 /%3E%3Ccircle style=%27opacity:1;fill:none;stroke:%236e6e6e;stroke-width:2;%27 id=%27path4571%27 cx=%27110.06081%27 cy=%2757.939209%27 r=%274.7438836%27 /%3E%3Crect style=%27fill:%236e6e6e;%27 x=%27116.64566%27 y=%27-31.79752%27 width=%274.229713%27 height=%276.4053884%27 id=%27rect4563-2%27 transform=%27matrix%280.70710678,0.70710678,-0.70710678,0.70710678,0,0%29%27 /%3E%3Cpath style=%27fill:%236e6e6e;fill-rule:evenodd;%27 d=%27M 125,56 138.77027,56.095 132,64 Z%27 id=%27path4613%27 /%3E%3Cpath id=%27path4615%27 d=%27M 149,64 162.77027,63.905 156,56 Z%27 style=%27fill:%236e6e6e;fill-rule:evenodd;%27 /%3E%3Crect style=%27fill:%236e6e6e;%27 x=%2754%27 y=%2753%27 width=%2712%27 height=%272%27 id=%27rect4638%27 /%3E%3Crect id=%27svg_1-7-2-24%27 height=%272%27 width=%2713%27 y=%27-56%27 x=%2753%27 style=%27fill:%236e6e6e;%27 transform=%27matrix%280,1,-1,0,0,0%29%27 /%3E%3Crect transform=%27matrix%280,1,-1,0,0,0%29%27 style=%27fill:%236e6e6e;%27 x=%2753%27 y=%27-66%27 width=%2713%27 height=%272%27 id=%27rect4657%27 /%3E%3Crect id=%27rect4659%27 height=%271%27 width=%2712%27 y=%2757%27 x=%2754%27 style=%27fill:%236e6e6e;%27 /%3E%3Crect style=%27fill:%23ffffff;%27 x=%2754%27 y=%2788%27 width=%2712%27 height=%272%27 id=%27rect4661%27 /%3E%3Crect style=%27fill:%23ffffff;%27 x=%2780%27 y=%2776%27 width=%273%27 height=%273%27 id=%27rect4663%27 /%3E%3Crect id=%27rect4665%27 height=%273%27 width=%273%27 y=%2776%27 x=%2785%27 style=%27fill:%23ffffff;%27 /%3E%3Crect id=%27rect4667%27 height=%273%27 width=%273%27 y=%2782%27 x=%2780%27 style=%27fill:%23ffffff;%27 /%3E%3Crect style=%27fill:%23ffffff;%27 x=%2785%27 y=%2782%27 width=%273%27 height=%273%27 id=%27rect4669%27 /%3E%3Crect style=%27fill:%23ffffff;%27 x=%2780%27 y=%2788%27 width=%273%27 height=%273%27 id=%27rect4671%27 /%3E%3Crect id=%27rect4673%27 height=%273%27 width=%273%27 y=%2788%27 x=%2785%27 style=%27fill:%23ffffff;%27 /%3E%3Ccircle r=%274.7438836%27 cy=%2781.939331%27 cx=%27110.06081%27 id=%27circle4675%27 style=%27opacity:1;fill:none;stroke:%23ffffff;stroke-width:2;%27 /%3E%3Crect transform=%27matrix%280.70710678,0.70710678,-0.70710678,0.70710678,0,0%29%27 id=%27rect4677%27 height=%276.4053884%27 width=%274.229713%27 y=%27-14.826816%27 x=%27133.6163%27 style=%27fill:%23ffffff;%27 /%3E%3Cpath id=%27path4679%27 d=%27m 125,80.000005 13.77027,0.09499 L 132,87.999992 Z%27 style=%27fill:%23ffffff;%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27M 149,88.0002 162.77027,87.9052 156,80.0002 Z%27 id=%27path4681%27 /%3E%3Crect id=%27rect4683%27 height=%272%27 width=%2712%27 y=%2777%27 x=%2754%27 style=%27fill:%23ffffff;%27 /%3E%3Crect transform=%27matrix%280,1,-1,0,0,0%29%27 style=%27fill:%23ffffff;%27 x=%2777%27 y=%27-56%27 width=%2713%27 height=%272%27 id=%27rect4685%27 /%3E%3Crect id=%27rect4687%27 height=%272%27 width=%2713%27 y=%27-66%27 x=%2777%27 style=%27fill:%23ffffff;%27 transform=%27matrix%280,1,-1,0,0,0%29%27 /%3E%3Crect style=%27fill:%23ffffff;%27 x=%2754%27 y=%2781%27 width=%2712%27 height=%271%27 id=%27rect4689%27 /%3E%3Crect id=%27rect4761-1%27 height=%272%27 width=%2716%27 y=%27101%27 x=%2776%27 style=%27fill:%23ffffff;%27 /%3E%3Crect id=%27rect4761-0%27 height=%272%27 width=%2716%27 y=%27105%27 x=%2776%27 style=%27fill:%23ffffff;%27 /%3E%3Crect id=%27rect4761-7%27 height=%272%27 width=%279%27 y=%27109%27 x=%2776%27 style=%27fill:%23ffffff;%27 /%3E%3Crect id=%27rect4761-1-1%27 height=%272%27 width=%2712%27 y=%27125%27 x=%2776%27 style=%27fill:%23ffffff;%27 /%3E%3Crect id=%27rect4761-1-1-4%27 height=%272%27 width=%2710%27 y=%27137%27 x=%2776%27 style=%27fill:%23ffffff;%27 /%3E%3Crect id=%27rect4761-1-1-4-4%27 height=%272%27 width=%2710%27 y=%27129%27 x=%2782%27 style=%27fill:%23ffffff;%27 /%3E%3Crect id=%27rect4761-1-1-4-4-3%27 height=%272%27 width=%279%27 y=%27133%27 x=%2782%27 style=%27fill:%23ffffff;%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 36.398438,100.0254 c -0.423362,-0.013 -0.846847,0.01 -1.265626,0.062 -1.656562,0.2196 -3.244567,0.9739 -4.507812,2.2266 L 29,100.5991 l -2.324219,7.7129 7.826172,-1.9062 -1.804687,-1.9063 c 1.597702,-1.5308 4.048706,-1.8453 5.984375,-0.7207 1.971162,1.1452 2.881954,3.3975 2.308593,5.5508 -0.573361,2.1533 -2.533865,3.6953 -4.830078,3.6953 l 0,3.0742 c 3.550756,0 6.710442,-2.4113 7.650391,-5.9414 0.939949,-3.5301 -0.618463,-7.2736 -3.710938,-9.0703 -1.159678,-0.6738 -2.431087,-1.0231 -3.701171,-1.0625 z%27 id=%27path4138%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 59.722656,99.9629 c -1.270084,0.039 -2.541493,0.3887 -3.701172,1.0625 -3.092475,1.7967 -4.650886,5.5402 -3.710937,9.0703 0.939949,3.5301 4.09768,5.9414 7.648437,5.9414 l 0,-3.0742 c -2.296214,0 -4.256717,-1.542 -4.830078,-3.6953 -0.573361,-2.1533 0.337432,-4.4056 2.308594,-5.5508 1.935731,-1.1246 4.38863,-0.8102 5.986326,0.7207 l -1.806638,1.9063 7.828128,1.9062 -2.32422,-7.7129 -1.62696,1.7168 c -1.26338,-1.2531 -2.848917,-2.0088 -4.505855,-2.2285 -0.418778,-0.055 -0.842263,-0.076 -1.265625,-0.062 z%27 id=%27path4138-1%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 10.5,100 0,2 -2.4999996,0 L 12,107 l 4,-5 -2.5,0 0,-2 -3,0 z%27 id=%27path3055-0-77%27 /%3E%3Cpath style=%27fill:none;stroke:%23ffffff;%27 d=%27m 4.9850574,108.015 14.0298856,-0.03%27 id=%27path5244-5-0-5%27 /%3E%3Cpath style=%27fill:none;stroke:%23ffffff;%27 d=%27m 4.9849874,132.015 14.0298866,-0.03%27 id=%27path5244-5-0-5-8%27 /%3E%3Cpath style=%27color:%23000000;fill:%236e6e6e;%27 d=%27m 36.398438,123.9629 c -0.423362,-0.013 -0.846847,0.01 -1.265626,0.062 -1.656562,0.2196 -3.244567,0.9739 -4.507812,2.2266 L 29,124.5366 l -2.324219,7.7129 7.826172,-1.9062 -1.804687,-1.9063 c 1.597702,-1.5308 4.048706,-1.8453 5.984375,-0.7207 1.971162,1.1453 2.881954,3.3975 2.308593,5.5508 -0.573361,2.1533 -2.533864,3.6953 -4.830078,3.6953 l 0,3.0742 c 3.550757,0 6.710442,-2.4093 7.650391,-5.9394 0.939949,-3.5301 -0.618463,-7.2756 -3.710938,-9.0723 -1.159678,-0.6737 -2.431087,-1.0231 -3.701171,-1.0625 z%27 id=%27path4138-12%27 /%3E%3Cpath style=%27color:%23000000;fill:%236e6e6e;%27 d=%27m 59.722656,123.9629 c -1.270084,0.039 -2.541493,0.3888 -3.701172,1.0625 -3.092475,1.7967 -4.650886,5.5422 -3.710937,9.0723 0.939949,3.5301 4.09768,5.9394 7.648437,5.9394 l 0,-3.0742 c -2.296214,0 -4.256717,-1.542 -4.830078,-3.6953 -0.573361,-2.1533 0.337432,-4.4055 2.308594,-5.5508 1.935731,-1.1246 4.38863,-0.8102 5.986326,0.7207 l -1.806638,1.9063 7.828128,1.9062 -2.32422,-7.7129 -1.62696,1.7168 c -1.26338,-1.2531 -2.848917,-2.0088 -4.505855,-2.2285 -0.418778,-0.055 -0.842263,-0.076 -1.265625,-0.062 z%27 id=%27path4138-1-3%27 /%3E%3Cpath id=%27path6191%27 d=%27m 10.5,116 0,-2 -2.4999996,0 L 12,109 l 4,5 -2.5,0 0,2 -3,0 z%27 style=%27fill:%23ffffff;stroke-width:1.96599996;%27 /%3E%3Cpath style=%27fill:%23ffffff;stroke-width:1.96599996;%27 d=%27m 10.5,129 0,-2 -2.4999996,0 L 12,122 l 4,5 -2.5,0 0,2 -3,0 z%27 id=%27path6193%27 /%3E%3Cpath id=%27path6195%27 d=%27m 10.5,135 0,2 -2.4999996,0 L 12,142 l 4,-5 -2.5,0 0,-2 -3,0 z%27 style=%27fill:%23ffffff;stroke-width:1.96599996;%27 /%3E%3Cpath sodipodi:type=%27star%27 style=%27fill:%236e6e6e;%27 id=%27path4500%27 sodipodi:sides=%273%27 sodipodi:cx=%2711.55581%27 sodipodi:cy=%2760.073242%27 sodipodi:r1=%275.1116104%27 sodipodi:r2=%272.5558052%27 sodipodi:arg1=%270%27 sodipodi:arg2=%271.0471976%27 inkscape:flatsided=%27false%27 inkscape:rounded=%270%27 inkscape:randomized=%270%27 d=%27m 16.66742,60.073242 -3.833708,2.213392 -3.8337072,2.213393 0,-4.426785 0,-4.426784 3.8337082,2.213392 z%27 inkscape:transform-center-x=%27-1.2779026%27 /%3E%3Cpath inkscape:transform-center-x=%271.277902%27 d=%27m -31.500004,60.073242 -3.833708,2.213392 -3.833707,2.213393 0,-4.426785 0,-4.426784 3.833707,2.213392 z%27 inkscape:randomized=%270%27 inkscape:rounded=%270%27 inkscape:flatsided=%27false%27 sodipodi:arg2=%271.0471976%27 sodipodi:arg1=%270%27 sodipodi:r2=%272.5558052%27 sodipodi:r1=%275.1116104%27 sodipodi:cy=%2760.073242%27 sodipodi:cx=%27-36.611614%27 sodipodi:sides=%273%27 id=%27path4502%27 style=%27fill:%236e6e6e;%27 sodipodi:type=%27star%27 transform=%27scale%28-1,1%29%27 /%3E%3Cpath d=%27m 16.66742,60.073212 -3.833708,2.213392 -3.8337072,2.213392 0,-4.426784 0,-4.426785 3.8337082,2.213392 z%27 inkscape:randomized=%270%27 inkscape:rounded=%270%27 inkscape:flatsided=%27false%27 sodipodi:arg2=%271.0471976%27 sodipodi:arg1=%270%27 sodipodi:r2=%272.5558052%27 sodipodi:r1=%275.1116104%27 sodipodi:cy=%2760.073212%27 sodipodi:cx=%2711.55581%27 sodipodi:sides=%273%27 id=%27path4504%27 style=%27fill:%236e6e6e;%27 sodipodi:type=%27star%27 transform=%27matrix%280,1,-1,0,72.0074,71.7877%29%27 inkscape:transform-center-y=%271.2779029%27 /%3E%3Cpath inkscape:transform-center-y=%27-1.2779026%27 transform=%27matrix%280,-1,-1,0,96,96%29%27 sodipodi:type=%27star%27 style=%27fill:%236e6e6e;%27 id=%27path4506%27 sodipodi:sides=%273%27 sodipodi:cx=%2711.55581%27 sodipodi:cy=%2760.073212%27 sodipodi:r1=%275.1116104%27 sodipodi:r2=%272.5558052%27 sodipodi:arg1=%270%27 sodipodi:arg2=%271.0471976%27 inkscape:flatsided=%27false%27 inkscape:rounded=%270%27 inkscape:randomized=%270%27 d=%27m 16.66742,60.073212 -3.833708,2.213392 -3.8337072,2.213392 0,-4.426784 0,-4.426785 3.8337082,2.213392 z%27 /%3E%3Cpath id=%27path4615-5%27 d=%27m 171.82574,65.174193 16.34854,0 -8.17427,-13.348454 z%27 style=%27fill:%23f9a825;fill-rule:evenodd;stroke:%23f9a825;stroke-width:2;%27 /%3E%3Cpath style=%27opacity:1;fill:%23ffffff;%27 d=%27m 179,55 0,6 2,0 0,-6%27 id=%27path4300%27 /%3E%3Cpath style=%27opacity:1;fill:%23ffffff;%27 d=%27m 179,62 0,2 2,0 0,-2%27 id=%27path4300-6%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27M 99.994369,113.0221 102,114.98353 l 7,-6.9558 3,0.97227 2,-1 1,-2 0,-3 -3,3 -3,-3 3,-3 -3,0 -2,1 -1,2 0.99437,3.0221 z%27 id=%27path4268%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 234,6 0,2 -5,5 0,5 -2,0 0,-5 -5,-5 0,-2%27 id=%27path3546%27 /%3E%3Cg transform=%27matrix%281.3333328,0,0,-1.5999992,-139.9999,127.19999%29%27 id=%27g4383-6%27%3E%3Crect id=%27rect4385-2%27 height=%271%27 width=%276%27 y=%2712.625005%27 x=%27198%27 style=%27fill:%23ffffff;stroke:%23000000;stroke-width:0%27 /%3E%3Crect style=%27fill:%23ffffff;stroke:%23000000;stroke-width:0%27 x=%27198%27 y=%2715.125007%27 width=%278%27 height=%271%27 id=%27rect4387-9%27 /%3E%3Crect style=%27fill:%23ffffff;stroke:%23000000;stroke-width:0%27 x=%27198%27 y=%277.6250024%27 width=%273%27 height=%271%27 id=%27rect4389-1-0%27 /%3E%3Crect style=%27fill:%23ffffff;stroke:%23000000;stroke-width:0%27 x=%27198%27 y=%2710.125004%27 width=%274%27 height=%271%27 id=%27rect4389-1-9%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 207.00001,16.375004 0,-5.625005 -2.25,0 3,-3.1250014 3,3.1250014 -2.25,0 0,5.625005 -1.5,0%27 id=%27path4402%27 /%3E%3C/g%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 164,100 0,3 -6,6 0,7 -4,0 0,-7 -6,-6 0,-3%27 id=%27path3546-2-2%27 /%3E%3Cpath id=%27path4402-5-7%27 d=%27m 15,41 0,-7 -4,0 0,3 -5,-4 5,-4 0,3 6,0 0,9%27 style=%27fill:%23ffffff;%27 /%3E%3C/svg%3E%0A")}.light{--t42-json-icons: url("data:image/svg+xml,%3C%3Fxml version=%271.0%27 encoding=%27UTF-8%27 standalone=%27no%27%3F%3E%3Csvg xmlns:dc=%27http://purl.org/dc/elements/1.1/%27 xmlns:cc=%27http://creativecommons.org/ns%23%27 xmlns:rdf=%27http://www.w3.org/1999/02/22-rdf-syntax-ns%23%27 xmlns:svg=%27http://www.w3.org/2000/svg%27 xmlns=%27http://www.w3.org/2000/svg%27 xmlns:sodipodi=%27http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd%27 xmlns:inkscape=%27http://www.inkscape.org/namespaces/inkscape%27 width=%27240%27 height=%27144%27 id=%27svg4136%27 version=%271.1%27 inkscape:version=%270.91 r13725%27 sodipodi:docname=%27jsoneditor-icons.svg%27%3E%3Ctitle id=%27title6512%27%3EJSON Editor Icons%3C/title%3E%3Crect id=%27svg_1-7%27 height=%2716%27 width=%2716%27 y=%273.999995%27 x=%2728.000006%27 style=%27fill:%23ff511f;%27 /%3E%3Crect x=%277%27 y=%2711%27 width=%2710%27 height=%272%27 id=%27svg_1-1%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect x=%2711%27 y=%277%27 width=%272%27 height=%2710%27 id=%27svg_1-1-1%27 style=%27fill:%230d0d0d;%27 /%3E%3Cg id=%27g4299-3%27 transform=%27matrix%280.70710678,-0.70710678,0.70710678,0.70710678,19.029435,12.000001%29%27 style=%27%27%3E%3Crect x=%277%27 y=%2711%27 width=%2710%27 height=%272%27 id=%27svg_1-1-0%27 style=%27fill:%23ffffff;%27 /%3E%3Crect x=%2711%27 y=%277%27 width=%272%27 height=%2710%27 id=%27svg_1-1-1-9%27 style=%27fill:%23ffffff;%27 /%3E%3C/g%3E%3Crect height=%277%27 width=%277%27 y=%277%27 x=%2755%27 style=%27fill:%230d0d0d;stroke-width:1;stroke:%230d0d0d%27 /%3E%3Crect id=%27svg_1-7-5-7%27 height=%277%27 width=%277%27 y=%2710%27 x=%2758%27 style=%27fill:%230d0d0d;stroke-width:1;stroke:%23ffffff%27 /%3E%3Cg id=%27g4378%27%3E%3Crect style=%27fill:%230d0d0d;%27 x=%27198%27 y=%2711%27 width=%278%27 height=%272%27 id=%27svg_1-7-5-3%27 /%3E%3Crect id=%27rect4374%27 height=%272%27 width=%2712%27 y=%277%27 x=%27198%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect id=%27rect4376%27 height=%272%27 width=%274%27 y=%2715%27 x=%27198%27 style=%27fill:%230d0d0d;%27 /%3E%3C/g%3E%3Cg transform=%27matrix%281,0,0,-1,-23.999995,23.999995%29%27 id=%27g4383%27%3E%3Crect id=%27rect4385%27 height=%272%27 width=%278%27 y=%2711%27 x=%27198%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect style=%27fill:%230d0d0d;%27 x=%27198%27 y=%277%27 width=%2712%27 height=%272%27 id=%27rect4387%27 /%3E%3Crect style=%27fill:%230d0d0d;%27 x=%27198%27 y=%2715%27 width=%274%27 height=%272%27 id=%27rect4389%27 /%3E%3C/g%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 85.10447,6.0157384 -0.0156,1.4063 c 3.02669,-0.2402 0.33008,3.6507996 2.48438,4.5780996 -2.18694,1.0938 0.49191,4.9069 -2.45313,4.5781 l -0.0156,1.4219 c 5.70828,0.559 1.03264,-5.1005 4.70313,-5.2656 l 0,-1.4063 c -3.61303,-0.027 1.11893,-5.7069996 -4.70313,-5.3124996 z%27 id=%27path4351%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 82.78125,5.9984384 0.0156,1.4063 c -3.02668,-0.2402 -0.33007,3.6506996 -2.48437,4.5780996 2.18694,1.0938 -0.49192,4.9069 2.45312,4.5781 l 0.0156,1.4219 c -5.70827,0.559 -1.03263,-5.1004 -4.70312,-5.2656 l 0,-1.4063 c 3.61303,-0.027 -1.11894,-5.7070996 4.70312,-5.3124996 z%27 id=%27path4351-9%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 103.719,5.6719384 0,12.7187996 3.03125,0 0,-1.5313 -1.34375,0 0,-9.6249996 1.375,0 0,-1.5625 z%27 id=%27path2987%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 112.2185,5.6721984 0,12.7187996 -3.03125,0 0,-1.5313 1.34375,0 0,-9.6249996 -1.375,0 0,-1.5625 z%27 id=%27path2987-1%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27M133,6.4h-1.9l-4.8,11.2h1.8l1.1-2.9h5.7l1.1,2.9h1.8L133,6.4z M129.7,13.5l2.3-5.5l2.3,5.5L129.7,13.5z%27 id=%27path3780%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 156.47655,5.8917384 0,2.1797 0.46093,2.3983996 1.82813,0 0.39844,-2.3983996 0,-2.1797 z%27 id=%27path5008-2%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 152.51561,5.8906384 0,2.1797 0.46094,2.3983996 1.82812,0 0.39844,-2.3983996 0,-2.1797 z%27 id=%27path5008-2-8%27 /%3E%3Crect id=%27svg_1-7-2%27 height=%272%27 width=%2712%27 y=%2764%27 x=%2754%27 style=%27fill:%236e6e6e;%27 /%3E%3Crect id=%27svg_1-7-2-2%27 height=%273%27 width=%273%27 y=%2752%27 x=%2780%27 style=%27fill:%236e6e6e;%27 /%3E%3Crect style=%27fill:%236e6e6e;%27 x=%2785%27 y=%2752%27 width=%273%27 height=%273%27 id=%27rect4561%27 /%3E%3Crect style=%27fill:%236e6e6e;%27 x=%2780%27 y=%2758%27 width=%273%27 height=%273%27 id=%27rect4563%27 /%3E%3Crect id=%27rect4565%27 height=%273%27 width=%273%27 y=%2758%27 x=%2785%27 style=%27fill:%236e6e6e;%27 /%3E%3Crect id=%27rect4567%27 height=%273%27 width=%273%27 y=%2764%27 x=%2780%27 style=%27fill:%236e6e6e;%27 /%3E%3Crect style=%27fill:%236e6e6e;%27 x=%2785%27 y=%2764%27 width=%273%27 height=%273%27 id=%27rect4569%27 /%3E%3Ccircle style=%27opacity:1;fill:none;stroke:%236e6e6e;stroke-width:2;%27 id=%27path4571%27 cx=%27110.06081%27 cy=%2757.939209%27 r=%274.7438836%27 /%3E%3Crect style=%27fill:%236e6e6e;%27 x=%27116.64566%27 y=%27-31.79752%27 width=%274.229713%27 height=%276.4053884%27 id=%27rect4563-2%27 transform=%27matrix%280.70710678,0.70710678,-0.70710678,0.70710678,0,0%29%27 /%3E%3Cpath style=%27fill:%236e6e6e;fill-rule:evenodd;%27 d=%27M 125,56 138.77027,56.095 132,64 Z%27 id=%27path4613%27 /%3E%3Cpath id=%27path4615%27 d=%27M 149,64 162.77027,63.905 156,56 Z%27 style=%27fill:%236e6e6e;fill-rule:evenodd;%27 /%3E%3Crect style=%27fill:%236e6e6e;%27 x=%2754%27 y=%2753%27 width=%2712%27 height=%272%27 id=%27rect4638%27 /%3E%3Crect id=%27svg_1-7-2-24%27 height=%272%27 width=%2713%27 y=%27-56%27 x=%2753%27 style=%27fill:%236e6e6e;%27 transform=%27matrix%280,1,-1,0,0,0%29%27 /%3E%3Crect transform=%27matrix%280,1,-1,0,0,0%29%27 style=%27fill:%236e6e6e;%27 x=%2753%27 y=%27-66%27 width=%2713%27 height=%272%27 id=%27rect4657%27 /%3E%3Crect id=%27rect4659%27 height=%271%27 width=%2712%27 y=%2757%27 x=%2754%27 style=%27fill:%236e6e6e;%27 /%3E%3Crect style=%27fill:%230d0d0d;%27 x=%2754%27 y=%2788%27 width=%2712%27 height=%272%27 id=%27rect4661%27 /%3E%3Crect style=%27fill:%230d0d0d;%27 x=%2780%27 y=%2776%27 width=%273%27 height=%273%27 id=%27rect4663%27 /%3E%3Crect id=%27rect4665%27 height=%273%27 width=%273%27 y=%2776%27 x=%2785%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect id=%27rect4667%27 height=%273%27 width=%273%27 y=%2782%27 x=%2780%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect style=%27fill:%230d0d0d;%27 x=%2785%27 y=%2782%27 width=%273%27 height=%273%27 id=%27rect4669%27 /%3E%3Crect style=%27fill:%230d0d0d;%27 x=%2780%27 y=%2788%27 width=%273%27 height=%273%27 id=%27rect4671%27 /%3E%3Crect id=%27rect4673%27 height=%273%27 width=%273%27 y=%2788%27 x=%2785%27 style=%27fill:%230d0d0d;%27 /%3E%3Ccircle r=%274.7438836%27 cy=%2781.939331%27 cx=%27110.06081%27 id=%27circle4675%27 style=%27opacity:1;fill:none;stroke:%230d0d0d;stroke-width:2;%27 /%3E%3Crect transform=%27matrix%280.70710678,0.70710678,-0.70710678,0.70710678,0,0%29%27 id=%27rect4677%27 height=%276.4053884%27 width=%274.229713%27 y=%27-14.826816%27 x=%27133.6163%27 style=%27fill:%230d0d0d;%27 /%3E%3Cpath id=%27path4679%27 d=%27m 125,80.000005 13.77027,0.09499 L 132,87.999992 Z%27 style=%27fill:%230d0d0d;%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27M 149,88.0002 162.77027,87.9052 156,80.0002 Z%27 id=%27path4681%27 /%3E%3Crect id=%27rect4683%27 height=%272%27 width=%2712%27 y=%2777%27 x=%2754%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect transform=%27matrix%280,1,-1,0,0,0%29%27 style=%27fill:%230d0d0d;%27 x=%2777%27 y=%27-56%27 width=%2713%27 height=%272%27 id=%27rect4685%27 /%3E%3Crect id=%27rect4687%27 height=%272%27 width=%2713%27 y=%27-66%27 x=%2777%27 style=%27fill:%230d0d0d;%27 transform=%27matrix%280,1,-1,0,0,0%29%27 /%3E%3Crect style=%27fill:%230d0d0d;%27 x=%2754%27 y=%2781%27 width=%2712%27 height=%271%27 id=%27rect4689%27 /%3E%3Crect id=%27rect4761-1%27 height=%272%27 width=%2716%27 y=%27101%27 x=%2776%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect id=%27rect4761-0%27 height=%272%27 width=%2716%27 y=%27105%27 x=%2776%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect id=%27rect4761-7%27 height=%272%27 width=%279%27 y=%27109%27 x=%2776%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect id=%27rect4761-1-1%27 height=%272%27 width=%2712%27 y=%27125%27 x=%2776%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect id=%27rect4761-1-1-4%27 height=%272%27 width=%2710%27 y=%27137%27 x=%2776%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect id=%27rect4761-1-1-4-4%27 height=%272%27 width=%2710%27 y=%27129%27 x=%2782%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect id=%27rect4761-1-1-4-4-3%27 height=%272%27 width=%279%27 y=%27133%27 x=%2782%27 style=%27fill:%230d0d0d;%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 36.398438,100.0254 c -0.423362,-0.013 -0.846847,0.01 -1.265626,0.062 -1.656562,0.2196 -3.244567,0.9739 -4.507812,2.2266 L 29,100.5991 l -2.324219,7.7129 7.826172,-1.9062 -1.804687,-1.9063 c 1.597702,-1.5308 4.048706,-1.8453 5.984375,-0.7207 1.971162,1.1452 2.881954,3.3975 2.308593,5.5508 -0.573361,2.1533 -2.533865,3.6953 -4.830078,3.6953 l 0,3.0742 c 3.550756,0 6.710442,-2.4113 7.650391,-5.9414 0.939949,-3.5301 -0.618463,-7.2736 -3.710938,-9.0703 -1.159678,-0.6738 -2.431087,-1.0231 -3.701171,-1.0625 z%27 id=%27path4138%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 59.722656,99.9629 c -1.270084,0.039 -2.541493,0.3887 -3.701172,1.0625 -3.092475,1.7967 -4.650886,5.5402 -3.710937,9.0703 0.939949,3.5301 4.09768,5.9414 7.648437,5.9414 l 0,-3.0742 c -2.296214,0 -4.256717,-1.542 -4.830078,-3.6953 -0.573361,-2.1533 0.337432,-4.4056 2.308594,-5.5508 1.935731,-1.1246 4.38863,-0.8102 5.986326,0.7207 l -1.806638,1.9063 7.828128,1.9062 -2.32422,-7.7129 -1.62696,1.7168 c -1.26338,-1.2531 -2.848917,-2.0088 -4.505855,-2.2285 -0.418778,-0.055 -0.842263,-0.076 -1.265625,-0.062 z%27 id=%27path4138-1%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 10.5,100 0,2 -2.4999996,0 L 12,107 l 4,-5 -2.5,0 0,-2 -3,0 z%27 id=%27path3055-0-77%27 /%3E%3Cpath style=%27fill:none;stroke:%230d0d0d;%27 d=%27m 4.9850574,108.015 14.0298856,-0.03%27 id=%27path5244-5-0-5%27 /%3E%3Cpath style=%27fill:none;stroke:%230d0d0d;%27 d=%27m 4.9849874,132.015 14.0298866,-0.03%27 id=%27path5244-5-0-5-8%27 /%3E%3Cpath style=%27color:%23000000;fill:%236e6e6e;%27 d=%27m 36.398438,123.9629 c -0.423362,-0.013 -0.846847,0.01 -1.265626,0.062 -1.656562,0.2196 -3.244567,0.9739 -4.507812,2.2266 L 29,124.5366 l -2.324219,7.7129 7.826172,-1.9062 -1.804687,-1.9063 c 1.597702,-1.5308 4.048706,-1.8453 5.984375,-0.7207 1.971162,1.1453 2.881954,3.3975 2.308593,5.5508 -0.573361,2.1533 -2.533864,3.6953 -4.830078,3.6953 l 0,3.0742 c 3.550757,0 6.710442,-2.4093 7.650391,-5.9394 0.939949,-3.5301 -0.618463,-7.2756 -3.710938,-9.0723 -1.159678,-0.6737 -2.431087,-1.0231 -3.701171,-1.0625 z%27 id=%27path4138-12%27 /%3E%3Cpath style=%27color:%23000000;fill:%236e6e6e;%27 d=%27m 59.722656,123.9629 c -1.270084,0.039 -2.541493,0.3888 -3.701172,1.0625 -3.092475,1.7967 -4.650886,5.5422 -3.710937,9.0723 0.939949,3.5301 4.09768,5.9394 7.648437,5.9394 l 0,-3.0742 c -2.296214,0 -4.256717,-1.542 -4.830078,-3.6953 -0.573361,-2.1533 0.337432,-4.4055 2.308594,-5.5508 1.935731,-1.1246 4.38863,-0.8102 5.986326,0.7207 l -1.806638,1.9063 7.828128,1.9062 -2.32422,-7.7129 -1.62696,1.7168 c -1.26338,-1.2531 -2.848917,-2.0088 -4.505855,-2.2285 -0.418778,-0.055 -0.842263,-0.076 -1.265625,-0.062 z%27 id=%27path4138-1-3%27 /%3E%3Cpath id=%27path6191%27 d=%27m 10.5,116 0,-2 -2.4999996,0 L 12,109 l 4,5 -2.5,0 0,2 -3,0 z%27 style=%27fill:%230d0d0d;stroke-width:2;%27 /%3E%3Cpath style=%27fill:%230d0d0d;stroke-width:2;%27 d=%27m 10.5,129 0,-2 -2.4999996,0 L 12,122 l 4,5 -2.5,0 0,2 -3,0 z%27 id=%27path6193%27 /%3E%3Cpath id=%27path6195%27 d=%27m 10.5,135 0,2 -2.4999996,0 L 12,142 l 4,-5 -2.5,0 0,-2 -3,0 z%27 style=%27fill:%230d0d0d;stroke-width:2;%27 /%3E%3Cpath sodipodi:type=%27star%27 style=%27fill:%236e6e6e;%27 id=%27path4500%27 sodipodi:sides=%273%27 sodipodi:cx=%2711.55581%27 sodipodi:cy=%2760.073242%27 sodipodi:r1=%275.1116104%27 sodipodi:r2=%272.5558052%27 sodipodi:arg1=%270%27 sodipodi:arg2=%271.0471976%27 inkscape:flatsided=%27false%27 inkscape:rounded=%270%27 inkscape:randomized=%270%27 d=%27m 16.66742,60.073242 -3.833708,2.213392 -3.8337072,2.213393 0,-4.426785 0,-4.426784 3.8337082,2.213392 z%27 inkscape:transform-center-x=%27-1.2779026%27 /%3E%3Cpath inkscape:transform-center-x=%271.277902%27 d=%27m -31.500004,60.073242 -3.833708,2.213392 -3.833707,2.213393 0,-4.426785 0,-4.426784 3.833707,2.213392 z%27 inkscape:randomized=%270%27 inkscape:rounded=%270%27 inkscape:flatsided=%27false%27 sodipodi:arg2=%271.0471976%27 sodipodi:arg1=%270%27 sodipodi:r2=%272.5558052%27 sodipodi:r1=%275.1116104%27 sodipodi:cy=%2760.073242%27 sodipodi:cx=%27-36.611614%27 sodipodi:sides=%273%27 id=%27path4502%27 style=%27fill:%236e6e6e;%27 sodipodi:type=%27star%27 transform=%27scale%28-1,1%29%27 /%3E%3Cpath d=%27m 16.66742,60.073212 -3.833708,2.213392 -3.8337072,2.213392 0,-4.426784 0,-4.426785 3.8337082,2.213392 z%27 inkscape:randomized=%270%27 inkscape:rounded=%270%27 inkscape:flatsided=%27false%27 sodipodi:arg2=%271.0471976%27 sodipodi:arg1=%270%27 sodipodi:r2=%272.5558052%27 sodipodi:r1=%275.1116104%27 sodipodi:cy=%2760.073212%27 sodipodi:cx=%2711.55581%27 sodipodi:sides=%273%27 id=%27path4504%27 style=%27fill:%236e6e6e;%27 sodipodi:type=%27star%27 transform=%27matrix%280,1,-1,0,72.0074,71.7877%29%27 inkscape:transform-center-y=%271.2779029%27 /%3E%3Cpath inkscape:transform-center-y=%27-1.2779026%27 transform=%27matrix%280,-1,-1,0,96,96%29%27 sodipodi:type=%27star%27 style=%27fill:%236e6e6e;%27 id=%27path4506%27 sodipodi:sides=%273%27 sodipodi:cx=%2711.55581%27 sodipodi:cy=%2760.073212%27 sodipodi:r1=%275.1116104%27 sodipodi:r2=%272.5558052%27 sodipodi:arg1=%270%27 sodipodi:arg2=%271.0471976%27 inkscape:flatsided=%27false%27 inkscape:rounded=%270%27 inkscape:randomized=%270%27 d=%27m 16.66742,60.073212 -3.833708,2.213392 -3.8337072,2.213392 0,-4.426784 0,-4.426785 3.8337082,2.213392 z%27 /%3E%3Cpath id=%27path4615-5%27 d=%27m 171.82574,65.174193 16.34854,0 -8.17427,-13.348454 z%27 style=%27fill:%23f9a825;fill-rule:evenodd;stroke:%23f9a825;stroke-width:2;%27 /%3E%3Cpath style=%27opacity:1;fill:%23ffffff;%27 d=%27m 179,55 0,6 2,0 0,-6%27 id=%27path4300%27 /%3E%3Cpath style=%27opacity:1;fill:%23ffffff;%27 d=%27m 179,62 0,2 2,0 0,-2%27 id=%27path4300-6%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27M 99.994369,113.0221 102,114.98353 l 7,-6.9558 3,0.97227 2,-1 1,-2 0,-3 -3,3 -3,-3 3,-3 -3,0 -2,1 -1,2 0.99437,3.0221 z%27 id=%27path4268%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 234,6 0,2 -5,5 0,5 -2,0 0,-5 -5,-5 0,-2%27 id=%27path3546%27 /%3E%3Cg transform=%27matrix%281.3333328,0,0,-1.5999992,-139.9999,127.19999%29%27 id=%27g4383-6%27%3E%3Crect id=%27rect4385-2%27 height=%271%27 width=%276%27 y=%2712.625005%27 x=%27198%27 style=%27fill:%230d0d0d;stroke:%23000000;stroke-width:0%27 /%3E%3Crect style=%27fill:%230d0d0d;stroke:%23000000;stroke-width:0%27 x=%27198%27 y=%2715.125007%27 width=%278%27 height=%271%27 id=%27rect4387-9%27 /%3E%3Crect style=%27fill:%230d0d0d;stroke:%23000000;stroke-width:0%27 x=%27198%27 y=%277.6250024%27 width=%273%27 height=%271%27 id=%27rect4389-1-0%27 /%3E%3Crect style=%27fill:%230d0d0d;stroke:%23000000;stroke-width:0%27 x=%27198%27 y=%2710.125004%27 width=%274%27 height=%271%27 id=%27rect4389-1-9%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 207.00001,16.375004 0,-5.625005 -2.25,0 3,-3.1250014 3,3.1250014 -2.25,0 0,5.625005 -1.5,0%27 id=%27path4402%27 /%3E%3C/g%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 164,100 0,3 -6,6 0,7 -4,0 0,-7 -6,-6 0,-3%27 id=%27path3546-2-2%27 /%3E%3Cpath id=%27path4402-5-7%27 d=%27m 15,41 0,-7 -4,0 0,3 -5,-4 5,-4 0,3 6,0 0,9%27 style=%27fill:%230d0d0d;%27 /%3E%3C/svg%3E%0A")}body{/*! + * Selectr 2.4.13 + * http://mobius.ovh/docs/selectr + * + * Released under the MIT license + */}body .jsoneditor,body .jsoneditor-modal{-webkit-text-size-adjust:none;text-size-adjust:none}body .jsoneditor input,body .jsoneditor input:not([type]),body .jsoneditor input[type="text"],body .jsoneditor input[type="search"],body .jsoneditor-modal input,body .jsoneditor-modal input:not([type]),body .jsoneditor-modal input[type="text"],body .jsoneditor-modal input[type="search"]{height:auto;border:inherit;box-shadow:none;font-size:inherit;box-sizing:inherit;padding:inherit;font-family:inherit;transition:none;line-height:inherit}body .jsoneditor input:focus,body .jsoneditor input:not([type]):focus,body .jsoneditor input[type="text"]:focus,body .jsoneditor input[type="search"]:focus,body .jsoneditor-modal input:focus,body .jsoneditor-modal input:not([type]):focus,body .jsoneditor-modal input[type="text"]:focus,body .jsoneditor-modal input[type="search"]:focus{border:inherit;box-shadow:inherit}body .jsoneditor textarea,body .jsoneditor-modal textarea{height:inherit}body .jsoneditor select,body .jsoneditor-modal select{display:inherit;height:inherit}body .jsoneditor label,body .jsoneditor-modal label{font-size:inherit;font-weight:inherit;color:inherit}body .jsoneditor table,body .jsoneditor-modal table{border-collapse:collapse;width:auto}body .jsoneditor td,body .jsoneditor th,body .jsoneditor-modal td,body .jsoneditor-modal th{padding:0;display:table-cell;text-align:left;vertical-align:inherit;border-radius:inherit}body .jsoneditor .autocomplete.dropdown{position:absolute;background:var(--t42-content-color);box-shadow:var(--t42-shadow);border:1px solid var(--t42-color-opacity-10);overflow-x:hidden;overflow-y:auto;cursor:default;margin:0;padding:5px;text-align:left;outline:0;font-family:var(--bs-font-monospace);font-size:var(--t42-font-size)}body .jsoneditor .autocomplete.dropdown .item{color:var(--t42-content-color)}body .jsoneditor .autocomplete.dropdown .item.hover{background-color:Rgb(var(--t42-bg-mid))}body .jsoneditor .autocomplete.hint{color:var(--t42-content-color);top:4px;left:4px}body .jsoneditor-contextmenu-root{position:relative;width:0;height:0}body .jsoneditor-contextmenu{position:absolute;box-sizing:content-box;z-index:2}body .jsoneditor-contextmenu .jsoneditor-menu{position:relative;left:0;top:0;width:128px;height:auto;background:var(--t42-content-color);border:1px solid var(--t42-color-opacity-10);box-shadow:var(--t42-shadow);list-style:none;margin:0;padding:0}body .jsoneditor-contextmenu .jsoneditor-menu button{position:relative;padding:0 8px 0 0;margin:0;width:128px;height:auto;border:none;cursor:pointer;color:var(--t42-content-color);background:transparent;font-size:var(--t42-font-size);font-family:var(--t42-font-family);box-sizing:border-box;text-align:left}body .jsoneditor-contextmenu .jsoneditor-menu button::-moz-focus-inner{padding:0;border:0}body .jsoneditor-contextmenu .jsoneditor-menu button.jsoneditor-default{width:96px}body .jsoneditor-contextmenu .jsoneditor-menu button.jsoneditor-expand{float:right;width:32px;height:24px;border-left:1px solid var(--t42-color-opacity-10)}body .jsoneditor-contextmenu .jsoneditor-menu li{overflow:hidden}body .jsoneditor-contextmenu .jsoneditor-menu li ul{display:none;position:relative;left:-10px;top:0;border:none;box-shadow:inset var(--t42-shadow);padding:0 10px;-webkit-transition:all 0.3s ease-out;-moz-transition:all 0.3s ease-out;-o-transition:all 0.3s ease-out;transition:all 0.3s ease-out}body .jsoneditor-contextmenu .jsoneditor-menu li ul .jsoneditor-icon{margin-left:24px}body .jsoneditor-contextmenu .jsoneditor-menu li ul li button{padding-left:24px;animation:all ease-in-out 1s}body .jsoneditor-contextmenu .jsoneditor-menu li button .jsoneditor-expand{position:absolute;top:0;right:0;width:24px;height:24px;padding:0;margin:0 4px 0 0;background-image:"/";background-position:0 -72px}body .jsoneditor-contextmenu .jsoneditor-icon{position:absolute;top:0;left:0;width:24px;height:24px;border:none;padding:0;margin:0;background-image:"/"}body .jsoneditor-contextmenu .jsoneditor-text{padding:4px 0 4px 24px;word-wrap:break-word}body .jsoneditor-contextmenu .jsoneditor-text.jsoneditor-right-margin{padding-right:24px}body .jsoneditor-contextmenu .jsoneditor-separator{height:0;border-top:1px solid var(--t42-color-opacity-10);padding-top:5px;margin-top:5px}body .jsoneditor-contextmenu button.jsoneditor-remove .jsoneditor-icon{background-position:-24px 0}body .jsoneditor-contextmenu button.jsoneditor-append .jsoneditor-icon{background-position:0 0}body .jsoneditor-contextmenu button.jsoneditor-insert .jsoneditor-icon{background-position:0 0}body .jsoneditor-contextmenu button.jsoneditor-duplicate .jsoneditor-icon{background-position:-48px 0}body .jsoneditor-contextmenu button.jsoneditor-sort-asc .jsoneditor-icon{background-position:-168px 0}body .jsoneditor-contextmenu button.jsoneditor-sort-desc .jsoneditor-icon{background-position:-192px 0}body .jsoneditor-contextmenu button.jsoneditor-transform .jsoneditor-icon{background-position:-216px 0}body .jsoneditor-contextmenu button.jsoneditor-extract .jsoneditor-icon{background-position:0 -24px}body .jsoneditor-contextmenu button.jsoneditor-type-string .jsoneditor-icon{background-position:-144px 0}body .jsoneditor-contextmenu button.jsoneditor-type-auto .jsoneditor-icon{background-position:-120px 0}body .jsoneditor-contextmenu button.jsoneditor-type-object .jsoneditor-icon{background-position:-72px 0}body .jsoneditor-contextmenu button.jsoneditor-type-array .jsoneditor-icon{background-position:-96px 0}body .jsoneditor-contextmenu button.jsoneditor-type-modes .jsoneditor-icon{background-image:none;width:6px}body .jsoneditor-contextmenu ul,body .jsoneditor-contextmenu li{box-sizing:content-box;position:relative}body .jsoneditor-contextmenu .jsoneditor-menu button:hover,body .jsoneditor-contextmenu .jsoneditor-menu button:focus{color:var(--t42-content-color);background-color:var(--t42-color-opacity-10);outline:none}body .jsoneditor-contextmenu .jsoneditor-menu li button.jsoneditor-selected,body .jsoneditor-contextmenu .jsoneditor-menu li button.jsoneditor-selected:hover,body .jsoneditor-contextmenu .jsoneditor-menu li button.jsoneditor-selected:focus{color:var(--t42-content-color);background-color:var(--red)}body .jsoneditor-contextmenu .jsoneditor-menu li ul li button:hover,body .jsoneditor-contextmenu .jsoneditor-menu li ul li button:focus{background-color:var(--t42-color-opacity-10)}body .jsoneditor-modal{max-width:95%;border-radius:2px !important;padding:45px 15px 15px 15px !important;box-shadow:var(--t42-shadow);color:var(--t42-content-color);line-height:1.3em}body .jsoneditor-modal.jsoneditor-modal-transform{width:600px !important}body .jsoneditor-modal .pico-modal-header{position:absolute;box-sizing:border-box;top:0;left:0;width:100%;padding:0 10px;height:30px;line-height:30px;font-family:var(--t42-font-family);font-size:11pt;background:var(--primary);color:var(--t42-content-color)}body .jsoneditor-modal table{width:100%}body .jsoneditor-modal table td{padding:3px 0}body .jsoneditor-modal table td.jsoneditor-modal-input{text-align:right;padding-right:0;white-space:nowrap}body .jsoneditor-modal table td.jsoneditor-modal-actions{padding-top:15px}body .jsoneditor-modal table th{vertical-align:middle}body .jsoneditor-modal p:first-child{margin-top:0}body .jsoneditor-modal a{color:var(--primary)}body .jsoneditor-modal .jsoneditor-jmespath-block{margin-bottom:10px}body .jsoneditor-modal .pico-close{background:none !important;font-size:24px !important;top:7px !important;right:7px !important;color:var(--t42-content-color)}body .jsoneditor-modal input{padding:4px}body .jsoneditor-modal input[type="text"]{cursor:inherit}body .jsoneditor-modal input[disabled]{background:var(--t42-content-color-muted);color:var(--t42-content-color-muted)}body .jsoneditor-modal .jsoneditor-select-wrapper{position:relative;display:inline-block}body .jsoneditor-modal .jsoneditor-select-wrapper:after{content:"";width:0;height:0;border-left:5px solid transparent;border-right:5px solid transparent;border-top:6px solid #666;position:absolute;right:8px;top:14px;pointer-events:none}body .jsoneditor-modal select{padding:3px 24px 3px 10px;min-width:180px;max-width:350px;-webkit-appearance:none;-moz-appearance:none;appearance:none;text-indent:0;text-overflow:"";font-size:var(--t42-font-size);line-height:1.5em}body .jsoneditor-modal select::-ms-expand{display:none}body .jsoneditor-modal .jsoneditor-button-group input{padding:4px 10px;margin:0;border-radius:0;border-left-style:none}body .jsoneditor-modal .jsoneditor-button-group input.jsoneditor-button-first{border-top-left-radius:3px;border-bottom-left-radius:3px;border-left-style:solid}body .jsoneditor-modal .jsoneditor-button-group input.jsoneditor-button-last{border-top-right-radius:3px;border-bottom-right-radius:3px}body .jsoneditor-modal .jsoneditor-transform-preview{background:var(--t42-color-opacity-10);height:200px}body .jsoneditor-modal .jsoneditor-transform-preview.jsoneditor-error{color:var(--red)}body .jsoneditor-modal .jsoneditor-jmespath-wizard{line-height:1.2em;width:100%;padding:0;border-radius:3px}body .jsoneditor-modal .jsoneditor-jmespath-label{font-weight:bold;color:dodgerblue;margin-top:20px;margin-bottom:5px}body .jsoneditor-modal .jsoneditor-jmespath-wizard-table{width:100%;border-collapse:collapse}body .jsoneditor-modal .jsoneditor-jmespath-wizard-label{font-style:italic;margin:4px 0 2px 0}body .jsoneditor-modal .jsoneditor-inline{position:relative;display:inline-block;width:100%;padding-top:2px;padding-bottom:2px}body .jsoneditor-modal .jsoneditor-inline:not(:last-child){padding-right:2px}body .jsoneditor-modal .jsoneditor-jmespath-filter{display:flex;flex-wrap:wrap}body .jsoneditor-modal .jsoneditor-jmespath-filter-field{width:180px}body .jsoneditor-modal .jsoneditor-jmespath-filter-relation{width:100px}body .jsoneditor-modal .jsoneditor-jmespath-filter-value{min-width:180px;flex:1}body .jsoneditor-modal .jsoneditor-jmespath-sort-field{width:170px}body .jsoneditor-modal .jsoneditor-jmespath-sort-order{width:150px}body .jsoneditor-modal .jsoneditor-jmespath-select-fields{width:100%}body .jsoneditor-modal .selectr-selected{border-color:var(--t42-color-opacity-10);padding:4px 28px 4px 8px}body .jsoneditor-modal .selectr-selected .selectr-tag{background-color:var(--primary);border-radius:5px}body .jsoneditor-modal table th,body .jsoneditor-modal table td{text-align:left;vertical-align:middle;font-weight:normal;color:var(--t42-content-color);border-spacing:0;border-collapse:collapse}body .jsoneditor-modal select,body .jsoneditor-modal textarea,body .jsoneditor-modal input,body .jsoneditor-modal input[type="text"],body .jsoneditor-modal input[type="text"]:focus,body .jsoneditor-modal #query{background:#ffffff;border:1px solid var(--t42-color-opacity-10);color:var(--t42-content-color);border-radius:3px;padding:4px}body .jsoneditor-modal textarea,body .jsoneditor-modal #query{border-radius:unset}body .jsoneditor-modal,body .jsoneditor-modal table td,body .jsoneditor-modal table th,body .jsoneditor-modal select,body .jsoneditor-modal option,body .jsoneditor-modal textarea,body .jsoneditor-modal input,body .jsoneditor-modal input[type="text"],body .jsoneditor-modal #query{font-size:10.5pt;font-family:var(--t42-font-family)}body .jsoneditor-modal #query,body .jsoneditor-modal .jsoneditor-transform-preview{font-family:var(--bs-font-monospace);font-size:var(--t42-font-size);width:100%;box-sizing:border-box}body .jsoneditor-modal input[type="button"],body .jsoneditor-modal input[type="submit"]{background:var(--t42-color-opacity-10);padding:4px 20px}body .jsoneditor-modal select,body .jsoneditor-modal input{cursor:pointer}body .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-asc input.jsoneditor-button-asc,body .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-desc input.jsoneditor-button-desc{background:var(--primary);border-color:var(--primary);color:var(--t42-content-color)}body .jsoneditor{color:var(--t42-content-color);border:thin solid var(--primary);-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;width:100%;height:100%;position:relative;padding:0;line-height:100%}body div.jsoneditor-field,body div.jsoneditor-value,body a.jsoneditor-value,body div.jsoneditor-readonly,body div.jsoneditor-default{border:1px solid transparent;min-height:16px;min-width:32px;line-height:16px;padding:2px;margin:1px;word-wrap:break-word;word-break:break-word;overflow-wrap:break-word;float:left}body div.jsoneditor-field p,body div.jsoneditor-value p{margin:0}body div.jsoneditor-value.jsoneditor-empty::after{content:"value"}body div.jsoneditor-value.jsoneditor-string{color:var(--green)}body div.jsoneditor-value.jsoneditor-number{color:var(--red)}body div.jsoneditor-value.jsoneditor-boolean{color:var(--yellow)}body div.jsoneditor-value.jsoneditor-null{color:var(--primary)}body div.jsoneditor-value.jsoneditor-color-value{color:var(--t42-content-color)}body div.jsoneditor-value.jsoneditor-invalid{color:var(--white)}body div.jsoneditor-readonly{min-width:16px;color:var(--t42-content-color-muted)}body div.jsoneditor-empty{border-color:var(--t42-color-opacity-10);border-style:dashed;border-radius:2px}body div.jsoneditor-field.jsoneditor-empty::after{content:"field"}body div.jsoneditor td{vertical-align:top}body div.jsoneditor td.jsoneditor-separator{padding:3px 0;vertical-align:top;color:var(--t42-content-color-muted)}body div.jsoneditor td.jsoneditor-tree{vertical-align:top}body div.jsoneditor.busy pre.jsoneditor-preview{background:var(--t42-color-opacity-10);color:var(--t42-content-color-muted)}body div.jsoneditor.busy div.jsoneditor-busy{display:inherit}body div.jsoneditor code.jsoneditor-preview{background:none}body div.jsoneditor.jsoneditor-mode-preview pre.jsoneditor-preview{width:100%;height:100%;box-sizing:border-box;overflow:auto;padding:2px;margin:0;white-space:pre-wrap;word-break:break-all}body div.jsoneditor-default{color:var(--t42-content-color-muted);padding-left:10px}body div.jsoneditor-tree{width:100%;height:100%;position:relative;overflow:auto;background:var(--t42-content-color)}body div.jsoneditor-tree button.jsoneditor-button{width:24px;height:24px;padding:0;margin:0;border:none;cursor:pointer;background-color:transparent;background-image:"/"}body div.jsoneditor-tree button.jsoneditor-button:focus{background-color:var(--t42-color-opacity-10);outline:#e5e5e5 solid 1px}body div.jsoneditor-tree button.jsoneditor-collapsed{background-position:0 -48px}body div.jsoneditor-tree button.jsoneditor-expanded{background-position:0 -72px}body div.jsoneditor-tree button.jsoneditor-contextmenu-button{background-position:-48px -72px}body div.jsoneditor-tree button.jsoneditor-invisible{visibility:hidden;background:none}body div.jsoneditor-tree button.jsoneditor-dragarea{background-image:"/";background-position:-72px -72px;cursor:move}body div.jsoneditor-tree *:focus{outline:none}body div.jsoneditor-tree div.jsoneditor-show-more{display:inline-block;padding:3px 4px;margin:2px 0;background-color:var(--t42-color-opacity-10);border-radius:3px;color:var(--t42-content-color-muted);font-family:var(--t42-font-family);font-size:var(--t42-font-size)}body div.jsoneditor-tree div.jsoneditor-show-more a{display:inline-block;color:var(--t42-content-color-muted)}body div.jsoneditor-tree div.jsoneditor-color{display:inline-block;width:12px;height:12px;margin:4px;border:1px solid var(--t42-content-color-muted);cursor:pointer}body div.jsoneditor-tree div.jsoneditor-color.jsoneditor-color-readonly{cursor:inherit}body div.jsoneditor-tree div.jsoneditor-date{background:var(--t42-content-color);color:var(--t42-content-color);font-family:var(--t42-font-family);border-radius:3px;display:inline-block;padding:3px;margin:0 3px}body div.jsoneditor-tree table.jsoneditor-tree{border-collapse:collapse;border-spacing:0;width:100%}body div.jsoneditor-tree .jsoneditor-button{display:block}body div.jsoneditor-tree .jsoneditor-button.jsoneditor-schema-error{width:24px;height:24px;padding:0;margin:0 4px 0 0;background-image:"/";background-position:-168px -48px;background-color:transparent}body div.jsoneditor-outer{position:static;width:100%;height:100%;margin:0;padding:0;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}body div.jsoneditor-outer.has-nav-bar{margin-top:-26px;padding-top:26px}body div.jsoneditor-outer.has-nav-bar.has-main-menu-bar{margin-top:-61px;padding-top:61px}body div.jsoneditor-outer.has-status-bar{margin-bottom:-26px;padding-bottom:26px}body div.jsoneditor-outer.has-main-menu-bar{margin-top:-35px;padding-top:35px}body div.jsoneditor-busy{position:absolute;top:15%;left:0;box-sizing:border-box;width:100%;text-align:center;display:none}body div.jsoneditor-busy span{background-color:var(--t42-color-opacity-10);border:1px solid var(--t42-color-opacity-10);border-radius:3px;padding:5px 15px;box-shadow:var(--t42-shadow)}body div.jsoneditor-field.jsoneditor-empty::after,body div.jsoneditor-value.jsoneditor-empty::after{pointer-events:none;color:var(--t42-content-color-muted);font-size:8pt}body div.jsoneditor-value.jsoneditor-url,body a.jsoneditor-value.jsoneditor-url{color:var(--green);text-decoration:underline}body a.jsoneditor-value.jsoneditor-url{display:inline-block;padding:2px;margin:2px}body a.jsoneditor-value.jsoneditor-url:hover,body a.jsoneditor-value.jsoneditor-url:focus{color:var(--red)}body div.jsoneditor-field[contenteditable="true"]:focus,body div.jsoneditor-field[contenteditable="true"]:hover,body div.jsoneditor-value[contenteditable="true"]:focus,body div.jsoneditor-value[contenteditable="true"]:hover,body div.jsoneditor-field.jsoneditor-highlight,body div.jsoneditor-value.jsoneditor-highlight{background-color:var(--t42-color-opacity-10);border:1px solid var(--t42-color-opacity-10);border-radius:2px}body div.jsoneditor-field.jsoneditor-highlight-active,body div.jsoneditor-field.jsoneditor-highlight-active:focus,body div.jsoneditor-field.jsoneditor-highlight-active:hover,body div.jsoneditor-value.jsoneditor-highlight-active,body div.jsoneditor-value.jsoneditor-highlight-active:focus,body div.jsoneditor-value.jsoneditor-highlight-active:hover{background-color:#fe0;border:1px solid #ffc700;border-radius:2px}body div.jsoneditor-value.jsoneditor-object,body div.jsoneditor-value.jsoneditor-array{min-width:16px}body div.jsoneditor-tree button.jsoneditor-contextmenu-button:hover,body div.jsoneditor-tree button.jsoneditor-contextmenu-button:focus,body div.jsoneditor-tree button.jsoneditor-contextmenu-button.jsoneditor-selected,body tr.jsoneditor-selected.jsoneditor-first button.jsoneditor-contextmenu-button{background-position:-48px -48px}body div.jsoneditor-tree div.jsoneditor-show-more a:hover,body div.jsoneditor-tree div.jsoneditor-show-more a:focus{color:var(--red)}body textarea.jsoneditor-text,body .ace-jsoneditor{min-height:150px}body textarea.jsoneditor-text.ace_editor,body .ace-jsoneditor.ace_editor{font-family:var(--bs-font-monospace)}body textarea.jsoneditor-text{width:100%;height:100%;margin:0;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;outline-width:0;border:none;background-color:var(--t42-content-color);resize:none}body tr.jsoneditor-highlight,body tr.jsoneditor-selected{background-color:var(--t42-content-color-muted)}body tr.jsoneditor-selected button.jsoneditor-dragarea,body tr.jsoneditor-selected button.jsoneditor-contextmenu-button{visibility:hidden}body tr.jsoneditor-selected.jsoneditor-first button.jsoneditor-dragarea,body tr.jsoneditor-selected.jsoneditor-first button.jsoneditor-contextmenu-button{visibility:visible}body div.jsoneditor-tree button.jsoneditor-dragarea:hover,body div.jsoneditor-tree button.jsoneditor-dragarea:focus,body tr.jsoneditor-selected.jsoneditor-first button.jsoneditor-dragarea{background-position:-72px -48px}body div.jsoneditor tr,body div.jsoneditor th,body div.jsoneditor td{padding:0;margin:0}body div.jsoneditor-field,body div.jsoneditor-value,body div.jsoneditor td,body div.jsoneditor th,body div.jsoneditor textarea,body pre.jsoneditor-preview,body .jsoneditor-schema-error,body .jsoneditor-popover{font-family:var(--bs-font-monospace);font-size:var(--t42-font-size);color:var(--t42-content-color)}body .jsoneditor-schema-error{cursor:default;display:inline-block;height:24px;line-height:24px;position:relative;text-align:center;width:24px}body .jsoneditor-popover{background-color:Rgb(var(--t42-bg-light));border-radius:3px;box-shadow:var(--t42-shadow);color:var(--t42-content-color);padding:7px 10px;position:absolute;cursor:auto;width:200px}body .jsoneditor-popover.jsoneditor-above{bottom:32px;left:-98px}body .jsoneditor-popover.jsoneditor-above:before{border-top:7px solid Rgb(var(--t42-bg-light));bottom:-7px}body .jsoneditor-popover.jsoneditor-below{top:32px;left:-98px}body .jsoneditor-popover.jsoneditor-below:before{border-bottom:7px solid Rgb(var(--t42-bg-light));top:-7px}body .jsoneditor-popover.jsoneditor-left{top:-7px;right:32px}body .jsoneditor-popover.jsoneditor-left:before{border-left:7px solid Rgb(var(--t42-bg-light));border-top:7px solid transparent;border-bottom:7px solid transparent;content:"";top:19px;right:-14px;left:inherit;margin-left:inherit;margin-top:-7px;position:absolute}body .jsoneditor-popover.jsoneditor-right{top:-7px;left:32px}body .jsoneditor-popover.jsoneditor-right:before{border-right:7px solid Rgb(var(--t42-bg-light));border-top:7px solid transparent;border-bottom:7px solid transparent;content:"";top:19px;left:-14px;margin-left:inherit;margin-top:-7px;position:absolute}body .jsoneditor-popover:before{border-right:7px solid transparent;border-left:7px solid transparent;content:"";display:block;left:50%;margin-left:-7px;position:absolute}body .jsoneditor-text-errors tr.jump-to-line:hover{text-decoration:underline;cursor:pointer}body .jsoneditor-schema-error:hover .jsoneditor-popover,body .jsoneditor-schema-error:focus .jsoneditor-popover{display:block;animation:fade-in 0.3s linear 1, move-up 0.3s linear 1}@keyframes fade-in{from{opacity:0}to{opacity:1}}body .jsoneditor .jsoneditor-validation-errors-container{max-height:130px;overflow-y:auto}body .jsoneditor .jsoneditor-validation-errors{width:100%;overflow:hidden}body .jsoneditor .jsoneditor-additional-errors{position:absolute;margin:auto;bottom:31px;left:calc(50% - 92px);color:var(--t42-content-color-muted);background-color:Rgb(var(--t42-bg-mid));padding:7px 15px;border-radius:8px}body .jsoneditor .jsoneditor-additional-errors.visible{visibility:visible;opacity:1;transition:opacity 2s linear}body .jsoneditor .jsoneditor-additional-errors.hidden{visibility:hidden;opacity:0;transition:visibility 0s 2s, opacity 2s linear}body .jsoneditor .jsoneditor-text-errors{width:100%;border-collapse:collapse;border-top:1px solid #ffc700}body .jsoneditor .jsoneditor-text-errors td{padding:3px 6px;vertical-align:middle}body .jsoneditor .jsoneditor-text-errors td pre{margin:0;white-space:pre-wrap}body .jsoneditor .jsoneditor-text-errors tr{background-color:var(--t42-color-opacity-10)}body .jsoneditor .jsoneditor-text-errors tr.parse-error{background-color:var(--red)}body .jsoneditor-text-errors .jsoneditor-schema-error{border:none;width:24px;height:24px;padding:0;margin:0 4px 0 0;cursor:pointer}body .jsoneditor-text-errors tr .jsoneditor-schema-error{background-image:"/";background-position:-168px -48px;background-color:transparent}body .jsoneditor-text-errors tr.parse-error .jsoneditor-schema-error{background-image:"/";background-position:-25px 0px;background-color:transparent}body .jsoneditor-anchor{cursor:pointer}body .jsoneditor-anchor .picker_wrapper.popup.popup_bottom{top:28px;left:-10px}body .fadein{-webkit-animation:fadein 0.3s;animation:fadein 0.3s;-moz-animation:fadein 0.3s;-o-animation:fadein 0.3s}@keyframes fadein{0%{opacity:0}100%{opacity:1}}body .jsoneditor-modal input[type="search"].selectr-input{border:1px solid #d3d3d3;width:calc(100% - 4px);margin:2px;padding:4px;box-sizing:border-box}body .jsoneditor-modal button.selectr-input-clear{right:8px}body .jsoneditor-menu{width:100%;height:35px;padding:2px;margin:0;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;color:var(--t42-content-color);background-color:var(--primary);border-bottom:1px solid var(--primary)}body .jsoneditor-menu>button,body .jsoneditor-menu>.jsoneditor-modes>button{width:26px;height:26px;margin:2px;padding:0;border-radius:2px;border:1px solid transparent;background-color:transparent;background-image:"/";color:var(--t42-content-color);opacity:0.8;font-family:var(--t42-font-family);font-size:var(--t42-font-size);float:left}body .jsoneditor-menu>button:hover,body .jsoneditor-menu>.jsoneditor-modes>button:hover{background-color:rgba(255,255,255,0.2);border:1px solid rgba(255,255,255,0.4)}body .jsoneditor-menu>button:focus,body .jsoneditor-menu>button:active,body .jsoneditor-menu>.jsoneditor-modes>button:focus,body .jsoneditor-menu>.jsoneditor-modes>button:active{background-color:rgba(255,255,255,0.3)}body .jsoneditor-menu>button:disabled,body .jsoneditor-menu>.jsoneditor-modes>button:disabled{opacity:0.5;background-color:transparent;border:none}body .jsoneditor-menu>button.jsoneditor-collapse-all{background-position:0 -96px}body .jsoneditor-menu>button.jsoneditor-expand-all{background-position:0 -120px}body .jsoneditor-menu>button.jsoneditor-sort{background-position:-120px -96px}body .jsoneditor-menu>button.jsoneditor-transform{background-position:-144px -96px}body .jsoneditor.jsoneditor-mode-view>.jsoneditor-menu>button.jsoneditor-sort,body .jsoneditor.jsoneditor-mode-form>.jsoneditor-menu>button.jsoneditor-sort,body .jsoneditor.jsoneditor-mode-view>.jsoneditor-menu>button.jsoneditor-transform,body .jsoneditor.jsoneditor-mode-form>.jsoneditor-menu>button.jsoneditor-transform{display:none}body .jsoneditor-menu>button.jsoneditor-undo{background-position:-24px -96px}body .jsoneditor-menu>button.jsoneditor-undo:disabled{background-position:-24px -120px}body .jsoneditor-menu>button.jsoneditor-redo{background-position:-48px -96px}body .jsoneditor-menu>button.jsoneditor-redo:disabled{background-position:-48px -120px}body .jsoneditor-menu>button.jsoneditor-compact{background-position:-72px -96px}body .jsoneditor-menu>button.jsoneditor-format{background-position:-72px -120px}body .jsoneditor-menu>button.jsoneditor-repair{background-position:-96px -96px}body .jsoneditor-menu>.jsoneditor-modes{display:inline-block;float:left}body .jsoneditor-menu>.jsoneditor-modes>button{background-image:none;width:auto;padding-left:6px;padding-right:6px}body .jsoneditor-menu>button.jsoneditor-separator,body .jsoneditor-menu>.jsoneditor-modes>button.jsoneditor-separator{margin-left:10px}body .jsoneditor-menu a{font-family:var(--t42-font-family);font-size:var(--t42-font-size);color:var(--t42-content-color);opacity:0.8;vertical-align:middle}body .jsoneditor-menu a:hover{opacity:1}body .jsoneditor-menu a.jsoneditor-poweredBy{font-size:8pt;position:absolute;right:0;top:0;padding:10px}body .jsoneditor-navigation-bar{width:100%;height:26px;line-height:26px;padding:0;margin:0;border-bottom:1px solid var(--t42-color-opacity-10);-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;color:var(--t42-content-color-muted);background-color:Rgb(var(--t42-bg-mid));overflow:hidden;font-family:var(--t42-font-family);font-size:var(--t42-font-size)}body .jsoneditor-search{font-family:var(--t42-font-family);position:absolute;right:4px;top:4px;border-collapse:collapse;border-spacing:0;display:flex}body .jsoneditor-search input{color:var(--t42-content-color);width:120px;border:none;outline:none;margin:1px;line-height:20px;font-family:var(--t42-font-family)}body .jsoneditor-search button{width:16px;height:24px;padding:0;margin:0;border:none;background:"/";vertical-align:top}body .jsoneditor-search button:hover{background-color:transparent}body .jsoneditor-search button.jsoneditor-refresh{width:18px;background-position:-99px -73px}body .jsoneditor-search button.jsoneditor-next{cursor:pointer;background-position:-124px -73px}body .jsoneditor-search button.jsoneditor-next:hover{background-position:-124px -49px}body .jsoneditor-search button.jsoneditor-previous{cursor:pointer;background-position:-148px -73px;margin-right:2px}body .jsoneditor-search button.jsoneditor-previous:hover{background-position:-148px -49px}body .jsoneditor-results{font-family:var(--t42-font-family);color:var(--t42-content-color);padding-right:5px;line-height:26px}body .jsoneditor-frame{border:1px solid transparent;background-color:var(--t42-content-color);padding:0 2px;margin:0}body .jsoneditor-statusbar{line-height:26px;height:26px;color:var(--t42-content-color-muted);background-color:Rgb(var(--t42-bg-mid));border-top:1px solid var(--t42-color-opacity-10);-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;font-size:var(--t42-font-size)}body .jsoneditor-statusbar>.jsoneditor-curserinfo-val{margin-right:12px}body .jsoneditor-statusbar>.jsoneditor-curserinfo-count{margin-left:4px}body .jsoneditor-statusbar>.jsoneditor-validation-error-icon{float:right;width:24px;height:24px;padding:0;margin-top:1px;background-image:"/";background-position:-168px -48px;cursor:pointer}body .jsoneditor-statusbar>.jsoneditor-validation-error-count{float:right;margin:0 4px 0 0;cursor:pointer}body .jsoneditor-statusbar>.jsoneditor-parse-error-icon{float:right;width:24px;height:24px;padding:0;margin:1px;background-image:"/";background-position:-25px 0px}body .jsoneditor-statusbar .jsoneditor-array-info a{color:inherit}body div.jsoneditor-statusbar>.jsoneditor-curserinfo-label,body div.jsoneditor-statusbar>.jsoneditor-size-info{margin:0 4px}body .jsoneditor-treepath{padding:0 5px;overflow:hidden;white-space:nowrap;outline:none}body .jsoneditor-treepath.show-all{word-wrap:break-word;white-space:normal;position:absolute;background-color:Rgb(var(--t42-bg-mid));z-index:1;box-shadow:var(--t42-shadow)}body .jsoneditor-treepath.show-all span.jsoneditor-treepath-show-all-btn{display:none}body .jsoneditor-treepath div.jsoneditor-contextmenu-root{position:absolute;left:0}body .jsoneditor-treepath .jsoneditor-treepath-show-all-btn{position:absolute;background-color:Rgb(var(--t42-bg-mid));left:0;height:20px;padding:0 3px;cursor:pointer}body .jsoneditor-treepath .jsoneditor-treepath-element{margin:1px;font-family:var(--t42-font-family);font-size:var(--t42-font-size)}body .jsoneditor-treepath .jsoneditor-treepath-seperator{margin:2px;font-size:9pt;font-family:var(--t42-font-family)}body .jsoneditor-treepath span.jsoneditor-treepath-element:hover,body .jsoneditor-treepath span.jsoneditor-treepath-seperator:hover{cursor:pointer;text-decoration:underline}body .selectr-container{position:relative}body .selectr-container li{list-style:none}body .selectr-hidden{position:absolute;overflow:hidden;clip:rect(0px, 0px, 0px, 0px);width:1px;height:1px;margin:-1px;padding:0;border:0 none}body .selectr-visible{position:absolute;left:0;top:0;width:100%;height:100%;opacity:0;z-index:11}body .selectr-desktop.multiple .selectr-visible{display:none}body .selectr-desktop.multiple.native-open .selectr-visible{top:100%;min-height:200px !important;height:auto;opacity:1;display:block}body .selectr-container.multiple.selectr-mobile .selectr-selected{z-index:0}body .selectr-selected{position:relative;z-index:1;box-sizing:border-box;width:100%;padding:7px 28px 7px 14px;cursor:pointer;border:1px solid Rgb(var(--t42-bg-mid));border-radius:3px;background-color:var(--t42-content-color)}body .selectr-selected::before{position:absolute;top:50%;right:10px;width:0;height:0;content:'';-o-transform:rotate(0deg) translate3d(0px, -50%, 0px);-ms-transform:rotate(0deg) translate3d(0px, -50%, 0px);-moz-transform:rotate(0deg) translate3d(0px, -50%, 0px);-webkit-transform:rotate(0deg) translate3d(0px, -50%, 0px);transform:rotate(0deg) translate3d(0px, -50%, 0px);border-width:4px 4px 0 4px;border-style:solid;border-color:#6c7a86 transparent transparent}body .selectr-container.open .selectr-selected::before,body .selectr-container.native-open .selectr-selected::before{border-width:0 4px 4px 4px;border-style:solid;border-color:transparent transparent #6c7a86}body .selectr-label{display:none;overflow:hidden;width:100%;white-space:nowrap;text-overflow:ellipsis}body .selectr-placeholder{color:#6c7a86}body .selectr-tags{margin:0;padding:0;white-space:normal}body .has-selected .selectr-tags{margin:0 0 -2px}body .selectr-tag{list-style:none;position:relative;float:left;padding:2px 25px 2px 8px;margin:0 2px 2px 0;cursor:default;color:var(--t42-content-color);border:medium none;border-radius:10px;background:#acb7bf none repeat scroll 0 0}body .selectr-container.multiple.has-selected .selectr-selected{padding:5px 28px 5px 5px}body .selectr-options-container{position:absolute;z-index:10000;top:calc(100% - 1px);left:0;display:none;box-sizing:border-box;width:100%;border-width:0 1px 1px;border-style:solid;border-color:transparent Rgb(var(--t42-bg-mid)) Rgb(var(--t42-bg-mid));border-radius:0 0 3px 3px;background-color:var(--t42-content-color)}body .selectr-container.open .selectr-options-container{display:block}body .selectr-input-container{position:relative;display:none}body .selectr-clear,body .selectr-input-clear,body .selectr-tag-remove{position:absolute;top:50%;right:22px;width:20px;height:20px;padding:0;cursor:pointer;-o-transform:translate3d(0px, -50%, 0px);-ms-transform:translate3d(0px, -50%, 0px);-moz-transform:translate3d(0px, -50%, 0px);-webkit-transform:translate3d(0px, -50%, 0px);transform:translate3d(0px, -50%, 0px);border:medium none;background-color:transparent;z-index:11}body .selectr-clear,body .selectr-input-clear{display:none}body .selectr-container.has-selected .selectr-clear,body .selectr-input-container.active .selectr-input-clear{display:block}body .selectr-selected .selectr-tag-remove{right:2px}body .selectr-clear::before,body .selectr-clear::after,body .selectr-input-clear::before,body .selectr-input-clear::after,body .selectr-tag-remove::before,body .selectr-tag-remove::after{position:absolute;top:5px;left:9px;width:2px;height:10px;content:' ';background-color:#6c7a86}body .selectr-tag-remove::before,body .selectr-tag-remove::after{top:4px;width:3px;height:12px;background-color:var(--t42-content-color)}body .selectr-clear:before,body .selectr-input-clear::before,body .selectr-tag-remove::before{-o-transform:rotate(45deg);-ms-transform:rotate(45deg);-moz-transform:rotate(45deg);-webkit-transform:rotate(45deg);transform:rotate(45deg)}body .selectr-clear:after,body .selectr-input-clear::after,body .selectr-tag-remove::after{-o-transform:rotate(-45deg);-ms-transform:rotate(-45deg);-moz-transform:rotate(-45deg);-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}body .selectr-input-container.active,body .selectr-input-container.active .selectr-clear{display:block}body .selectr-input{top:5px;left:5px;box-sizing:border-box;width:calc(100% - 30px);margin:10px 15px;padding:7px 30px 7px 9px;border:1px solid Rgb(var(--t42-bg-mid));border-radius:3px}body .selectr-notice{display:none;box-sizing:border-box;width:100%;padding:8px 16px;border-top:1px solid Rgb(var(--t42-bg-mid));border-radius:0 0 3px 3px;background-color:var(--t42-content-color)}body .selectr-container.notice .selectr-notice{display:block}body .selectr-container.notice .selectr-selected{border-radius:3px 3px 0 0}body .selectr-options{position:relative;top:calc(100% + 2px);display:none;overflow-x:auto;overflow-y:scroll;max-height:200px;margin:0;padding:0}body .selectr-container.open .selectr-options,body .selectr-container.open .selectr-input-container,body .selectr-container.notice .selectr-options-container{display:block}body .selectr-option{position:relative;display:block;padding:5px 20px;list-style:outside none none;cursor:pointer;font-weight:normal}body .selectr-options.optgroups>.selectr-option{padding-left:25px}body .selectr-optgroup{font-weight:bold;padding:0}body .selectr-optgroup--label{font-weight:bold;margin-top:10px;padding:5px 15px}body .selectr-match{text-decoration:underline}body .selectr-option.selected{background-color:#ddd}body .selectr-option.active{color:var(--t42-content-color);background-color:#5897fb}body .selectr-option.disabled{opacity:0.4}body .selectr-option.excluded{display:none}body .selectr-container.open .selectr-selected{border-color:Rgb(var(--t42-bg-mid)) Rgb(var(--t42-bg-mid)) transparent Rgb(var(--t42-bg-mid));border-radius:3px 3px 0 0}body .selectr-container.open .selectr-selected::after{-o-transform:rotate(180deg) translate3d(0px, 50%, 0px);-ms-transform:rotate(180deg) translate3d(0px, 50%, 0px);-moz-transform:rotate(180deg) translate3d(0px, 50%, 0px);-webkit-transform:rotate(180deg) translate3d(0px, 50%, 0px);transform:rotate(180deg) translate3d(0px, 50%, 0px)}body .selectr-disabled{opacity:.6}body .selectr-empty,body .has-selected .selectr-placeholder{display:none}body .has-selected .selectr-label{display:block}body .taggable .selectr-selected{padding:4px 28px 4px 4px}body .taggable .selectr-selected::after{display:table;content:" ";clear:both}body .taggable .selectr-label{width:auto}body .taggable .selectr-tags{float:left;display:block}body .taggable .selectr-placeholder{display:none}body .input-tag{float:left;min-width:90px;width:auto}body .selectr-tag-input{border:medium none;padding:3px 10px;width:100%;font-family:inherit;font-weight:inherit;font-size:inherit}body .selectr-input-container.loading::after{position:absolute;top:50%;right:20px;width:20px;height:20px;content:'';-o-transform:translate3d(0px, -50%, 0px);-ms-transform:translate3d(0px, -50%, 0px);-moz-transform:translate3d(0px, -50%, 0px);-webkit-transform:translate3d(0px, -50%, 0px);transform:translate3d(0px, -50%, 0px);-o-transform-origin:50% 0 0;-ms-transform-origin:50% 0 0;-moz-transform-origin:50% 0 0;-webkit-transform-origin:50% 0 0;transform-origin:50% 0 0;-moz-animation:500ms linear 0s normal forwards infinite running selectr-spin;-webkit-animation:500ms linear 0s normal forwards infinite running selectr-spin;animation:500ms linear 0s normal forwards infinite running selectr-spin;border-width:3px;border-style:solid;border-color:#aaa #ddd #ddd;border-radius:50%}@-webkit-keyframes selectr-spin{0%{-webkit-transform:rotate(0deg) translate3d(0px, -50%, 0px);transform:rotate(0deg) translate3d(0px, -50%, 0px)}100%{-webkit-transform:rotate(360deg) translate3d(0px, -50%, 0px);transform:rotate(360deg) translate3d(0px, -50%, 0px)}}@keyframes selectr-spin{0%{-webkit-transform:rotate(0deg) translate3d(0px, -50%, 0px);transform:rotate(0deg) translate3d(0px, -50%, 0px)}100%{-webkit-transform:rotate(360deg) translate3d(0px, -50%, 0px);transform:rotate(360deg) translate3d(0px, -50%, 0px)}}body .selectr-container.open.inverted .selectr-selected{border-color:transparent Rgb(var(--t42-bg-mid)) Rgb(var(--t42-bg-mid));border-radius:0 0 3px 3px}body .selectr-container.inverted .selectr-options-container{border-width:1px 1px 0;border-color:Rgb(var(--t42-bg-mid)) Rgb(var(--t42-bg-mid)) transparent;border-radius:3px 3px 0 0;background-color:var(--t42-content-color)}body .selectr-container.inverted .selectr-options-container{top:auto;bottom:calc(100% - 1px)}body .selectr-container ::-webkit-input-placeholder{color:#6c7a86;opacity:1}body .selectr-container ::-moz-placeholder{color:#6c7a86;opacity:1}body .selectr-container :-ms-input-placeholder{color:#6c7a86;opacity:1}body .selectr-container ::placeholder{color:#6c7a86;opacity:1}body #jsoneditor{height:100%}body .jsoneditor{border-color:var(--t42-color-opacity-10)}body .jsoneditor textarea{line-height:1.5;background-color:Rgb(var(--t42-bg-dark));min-height:100%}body .jsoneditor input{outline:0}body .jsoneditor input:focus{outline:0}body .jsoneditor-button:focus{outline:none}body .jsoneditor-menu{border-bottom-color:var(--t42-color-opacity-10);background-color:Rgb(var(--t42-bg-light))}body .jsoneditor-menu button{background-image:var(--t42-json-icons);background-color:transparent}body .jsoneditor-menu button:hover,body .jsoneditor-menu button:focus{color:var(--t42-link-hover-color)}body .jsoneditor-menu>button,body .jsoneditor-menu>.jsoneditor-modes>button{border-radius:0;font-size:.75rem;backdrop-filter:var(--backdrop-filter);transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, color}body .jsoneditor-menu>button:hover:not(.disabled):not(:disabled),body .jsoneditor-menu>button:active,body .jsoneditor-menu>.jsoneditor-modes>button:hover:not(.disabled):not(:disabled),body .jsoneditor-menu>.jsoneditor-modes>button:active{border-color:transparent;color:var(--t42-link-hover-color);background-color:var(--t42-color-opacity-10)}body .jsoneditor-menu li button.jsoneditor-selected{background-color:var(--t42-color-opacity-10)}body .jsoneditor-menu .jsoneditor-poweredBy{display:none}body .jsoneditor-frame{padding:0 .875rem;border-color:var(--t42-color-opacity-10);background-color:transparent;display:flex;transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border-color}body .jsoneditor-frame:focus-within{border-color:var(--primary);background-color:var(--t42-input-bg);outline:0}body .jsoneditor-frame table td{vertical-align:middle}body .jsoneditor-search input[type="text"]{border:0}body .jsoneditor-search input[type="text"]:focus{border:0}body .jsoneditor-search input{background-color:transparent}body .jsoneditor-contextmenu{z-index:2}body .jsoneditor-contextmenu .jsoneditor-menu{border-color:var(--t42-color-opacity-10);background:linear-gradient(to bottom right, rgba(var(--t42-bg-light), 0.75) 0%, rgba(var(--t42-bg-dark), 0.75) 100%);box-shadow:var(--t42-shadow);backdrop-filter:var(--backdrop-filter)}body .jsoneditor-contextmenu .jsoneditor-menu button button .jsoneditor-expand,body .jsoneditor-contextmenu .jsoneditor-menu li button .jsoneditor-expand{background-image:var(--t42-json-icons);z-index:1}body .jsoneditor-contextmenu .jsoneditor-menu button button.jsoneditor-selected,body .jsoneditor-contextmenu .jsoneditor-menu li button.jsoneditor-selected{background-color:var(--t42-color-opacity-10);transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, color}body .jsoneditor-contextmenu .jsoneditor-menu button button.jsoneditor-selected:hover,body .jsoneditor-contextmenu .jsoneditor-menu button button.jsoneditor-selected:focus,body .jsoneditor-contextmenu .jsoneditor-menu li button.jsoneditor-selected:hover,body .jsoneditor-contextmenu .jsoneditor-menu li button.jsoneditor-selected:focus{color:var(--t42-link-hover-color);background-color:var(--t42-color-opacity-10)}body .jsoneditor-contextmenu .jsoneditor-menu button{display:flex;justify-content:start}body .jsoneditor-contextmenu .jsoneditor-menu button.jsoneditor-default{float:left;z-index:1}body .jsoneditor-contextmenu .jsoneditor-menu li ul{padding:0 !important;left:0}body .jsoneditor-contextmenu .jsoneditor-menu li ul li button{padding-left:1rem}body .jsoneditor-contextmenu .jsoneditor-menu li ul .jsoneditor-icon{position:relative;margin-left:0}body .jsoneditor-contextmenu .jsoneditor-menu .jsoneditor-text{padding:0;line-height:1.5rem}body .jsoneditor-contextmenu .jsoneditor-icon{position:relative;background-image:var(--t42-json-icons)}body .jsoneditor-contextmenu .jsoneditor-separator{margin-top:0;padding-top:0}body .jsoneditor-mode-preview pre.jsoneditor-preview{border:0;line-height:1.5}body .jsoneditor-modal{border-top:0;background:linear-gradient(to bottom right, rgba(var(--t42-bg-light), 0.75) 0%, rgba(var(--t42-bg-dark), 0.75) 100%) !important;box-shadow:var(--t42-shadow) !important;backdrop-filter:var(--backdrop-filter)}body .jsoneditor-modal::before{position:absolute;top:0;right:0;left:0;display:block;width:100%;height:0.0625rem;background:linear-gradient(90deg, #007be5 0%, rgba(0,123,229,0.5) 100%);content:""}body .jsoneditor-modal .pico-modal-header{padding:0.5rem 0.988rem;background:transparent;font-size:0.75rem}body .jsoneditor-modal .pico-close{top:1rem !important;right:1rem !important;color:var(--t42-content-color-muted);transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:color}body .jsoneditor-modal .pico-close:not(.disabled):not(:disabled).active,body .jsoneditor-modal .pico-close:not(.disabled):not(:disabled):focus,body .jsoneditor-modal .pico-close:not(.disabled):not(:disabled):hover{color:var(--t42-link-color)}body .jsoneditor-modal table td{font-size:0.75rem;padding:0 0.25rem}body .jsoneditor-modal table td.jsoneditor-modal-input{padding-top:0.25rem;padding-bottom:0.25rem;text-align:left}body .jsoneditor-modal table td.jsoneditor-modal-input.jsoneditor-modal-actions{text-align:right}body .jsoneditor-modal table th{font-size:0.75rem}body .jsoneditor-modal label,body .jsoneditor-modal p{font-size:0.75rem}body .jsoneditor-modal select{min-width:12.375rem}body .jsoneditor-modal .selectr-selected{padding:0 0.857rem}body .jsoneditor-modal select,body .jsoneditor-modal textarea,body .jsoneditor-modal input,body .jsoneditor-modal input[type="text"],body .jsoneditor-modal input[type="search"],body .jsoneditor-modal #query{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border;border-color:var(--t42-color-opacity-10);border-radius:0;font-size:0.75rem;background-color:var(--t42-input-bg)}body .jsoneditor-modal select:focus,body .jsoneditor-modal textarea:focus,body .jsoneditor-modal input:focus,body .jsoneditor-modal input[type="text"]:focus,body .jsoneditor-modal input[type="search"]:focus,body .jsoneditor-modal #query:focus{border-color:var(--primary);box-shadow:none;outline:0;padding:0 0 0 .875rem;border-radius:0}body .jsoneditor-modal select:disabled,body .jsoneditor-modal select.disabled,body .jsoneditor-modal select[readonly],body .jsoneditor-modal textarea:disabled,body .jsoneditor-modal textarea.disabled,body .jsoneditor-modal textarea[readonly],body .jsoneditor-modal input:disabled,body .jsoneditor-modal input.disabled,body .jsoneditor-modal input[readonly],body .jsoneditor-modal input[type="text"]:disabled,body .jsoneditor-modal input[type="text"].disabled,body .jsoneditor-modal input[type="text"][readonly],body .jsoneditor-modal input[type="search"]:disabled,body .jsoneditor-modal input[type="search"].disabled,body .jsoneditor-modal input[type="search"][readonly],body .jsoneditor-modal #query:disabled,body .jsoneditor-modal #query.disabled,body .jsoneditor-modal #query[readonly]{cursor:default;opacity:0.65}body .jsoneditor-modal input[type="search"].selectr-input{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border-color;border:var(--t42-border);background-color:var(--t42-input-bg);margin:0;line-height:1.5rem;width:100%;padding:0 0.5rem}body .jsoneditor-modal input[type="search"].selectr-input:hover{border-color:var(--primary)}body .jsoneditor-modal .jsoneditor-select-wrapper::after{border-top:var(--t42-color-opacity-10)}body .jsoneditor-modal input[type="button"],body .jsoneditor-modal input[type="submit"]{padding:0 .875rem;border-radius:0;color:var(--t42-link-color);line-height:1.875rem;background:transparent;transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, border-color}body .jsoneditor-modal input[type="button"]:not(.disabled):not(:disabled).active,body .jsoneditor-modal input[type="button"]:not(.disabled):not(:disabled):hover,body .jsoneditor-modal input[type="submit"]:not(.disabled):not(:disabled).active,body .jsoneditor-modal input[type="submit"]:not(.disabled):not(:disabled):hover{border-color:var(--t42-color-opacity-30);color:var(--white);background:var(--primary)}body .jsoneditor-modal .jsoneditor-button-group input.jsoneditor-button-first{border-left-style:solid;border-top-left-radius:0;border-bottom-left-radius:0}body .jsoneditor-modal .jsoneditor-button-group input.jsoneditor-button-last{border-top-right-radius:0;border-bottom-right-radius:0}body .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-asc input.jsoneditor-button-asc,body .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-desc input.jsoneditor-button-desc{color:var(--white);background:var(--primary)}body .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-asc input.jsoneditor-button-asc:hover,body .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-asc input.jsoneditor-button-asc:focus,body .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-asc input.jsoneditor-button-asc:active,body .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-desc input.jsoneditor-button-desc:hover,body .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-desc input.jsoneditor-button-desc:focus,body .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-desc input.jsoneditor-button-desc:active{border-color:var(--t42-color-opacity-30);color:var(--white)}body .jsoneditor-modal .jsoneditor-jmespath-label{color:var(--t42-content-color);font-weight:400}body .jsoneditor-modal .jsoneditor-jmespath-filter-value input{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border-color;line-height:1.875rem;padding:0 0 0 .875rem;font-size:0.75rem;background-color:var(--t42-input-bg)}body .jsoneditor-modal .jsoneditor-jmespath-filter-value input:focus,body .jsoneditor-modal .jsoneditor-jmespath-filter-value input:hover{background-color:var(--t42-input-bg);border-color:var(--primary)}body .jsoneditor-jmespath-block .jsoneditor-modal-actions{text-align:right}body div.jsoneditor td.jsoneditor-tree{vertical-align:middle}body div.jsoneditor td.jsoneditor-separator{vertical-align:middle}body div.jsoneditor-tree{background:transparent}body div.jsoneditor-tree button.jsoneditor-button{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, outline-color;background-image:var(--t42-json-icons)}body div.jsoneditor-tree button.jsoneditor-button:focus{background-color:transparent;outline-color:var(--t42-color-opacity-10)}body tr.jsoneditor-selected,body tr.jsoneditor-highlight{background-color:var(--t42-color-opacity-10)}body .selectr-selected{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border-color;height:2rem;font-size:0.75rem;font-weight:400;line-height:1.875rem;background-color:var(--t42-input-bg);border-radius:0}body .selectr-selected::before{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:transform;right:0.5rem;border:0;width:0.75rem;height:0.75rem;background:var(--t42-select-indicator) center center/1rem 1rem no-repeat;transform:translateY(-50%)}body .selectr-placeholder{color:var(--t42-content-color-muted)}body .selectr-container.open .selectr-selected{border-radius:0;border-color:var(--primary)}body .selectr-container.open .selectr-selected::before{border:0;transform:rotate(180deg) translateY(50%)}body .selectr-container.open .selectr-options-container{border-left-color:var(--primary);border-right-color:var(--primary);border-bottom-color:var(--primary)}body .selectr-options{overflow-y:auto}body .selectr-options-container{min-height:2rem;border-color:var(--t42-color-opacity-10);border-style:solid;border-width:1px;background-color:Rgb(var(--t42-bg-dark))}body .selectr-options .active{color:var(--t42-link-hover-color);background-color:var(--t42-color-opacity-10)}body .selectr-options .selected{color:var(--t42-link-hover-color);background-color:var(--primary)}body .selectr-option{padding:0 0 0 0.875rem;line-height:2rem;font-size:0.75rem}body .selectr-input{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border-color;border:var(--t42-border);background-color:var(--t42-input-bg)}body .selectr-input:hover{border-color:var(--primary)}body .selectr-input-container{padding:0.25rem}body .selectr-clear::before,body .selectr-clear::after{background-color:var(--t42-content-color)}body .jsoneditor .ace-jsoneditor .ace_text-input{min-height:auto}body .jsoneditor .ace-jsoneditor.ace_editor,body .jsoneditor .ace-jsoneditor .ace_scroller{background-color:Rgb(var(--t42-bg-dark))}body .jsoneditor .ace-jsoneditor .ace_gutter{color:var(--t42-content-color-muted);background-color:Rgb(var(--t42-bg-mid))}body .jsoneditor .ace-jsoneditor .ace_gutter-active-line{background-color:Rgb(var(--t42-bg-light))}body .jsoneditor .ace-jsoneditor .ace_cursor{border-color:Rgb(var(--t42-content-color))}body .jsoneditor .ace-jsoneditor .ace_marker-layer .ace_active-line{background-color:rgba(var(--secondary), 0.25)}body .jsoneditor .ace-jsoneditor .ace_marker-layer .ace_selection{background-color:var(--t42-color-opacity-10)}body .jsoneditor .ace-jsoneditor .ace_marker-layer .ace_selected-word{border-color:var(--t42-color-opacity-10);background-color:var(--t42-color-opacity-10)}body .jsoneditor .ace-jsoneditor .ace_marker-layer .ace_bracket{border:var(--t42-border)}body .jsoneditor .ace-jsoneditor .ace_variable{color:var(--t42-content-color)}body .jsoneditor .ace-jsoneditor .ace_constant.ace_numeric{color:#ff511f}body .jsoneditor .ace-jsoneditor .ace_constant.ace_language{color:#f9a825}body .jsoneditor .ace-jsoneditor .ace_string{color:#43a047}body .jsoneditor .ace-jsoneditor .ace_fold{border-color:var(--t42-color-opacity-10);background-color:Rgb(var(--t42-bg-light));transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-image}body .jsoneditor .ace-jsoneditor .ace_fold-widget:hover,body .jsoneditor .ace-jsoneditor .ace_fold-widget:active{border-color:var(--t42-color-opacity-30);background-color:var(--t42-color-opacity-10);box-shadow:none}body .pico-modal-contents{display:block} + diff --git a/typescript/solution/stocks/src/lib/workspaces.umd.js b/typescript/solution/stocks/src/lib/workspaces.umd.js new file mode 100644 index 0000000..53ca1d8 --- /dev/null +++ b/typescript/solution/stocks/src/lib/workspaces.umd.js @@ -0,0 +1,5302 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define(factory) : + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.workspaces = factory()); +})(this, (function () { 'use strict'; + + function getDefaultExportFromCjs (x) { + return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; + } + + function createRegistry(options) { + if (options && options.errorHandling + && typeof options.errorHandling !== "function" + && options.errorHandling !== "log" + && options.errorHandling !== "silent" + && options.errorHandling !== "throw") { + throw new Error("Invalid options passed to createRegistry. Prop errorHandling should be [\"log\" | \"silent\" | \"throw\" | (err) => void], but " + typeof options.errorHandling + " was passed"); + } + var _userErrorHandler = options && typeof options.errorHandling === "function" && options.errorHandling; + var callbacks = {}; + function add(key, callback, replayArgumentsArr) { + var callbacksForKey = callbacks[key]; + if (!callbacksForKey) { + callbacksForKey = []; + callbacks[key] = callbacksForKey; + } + callbacksForKey.push(callback); + if (replayArgumentsArr) { + setTimeout(function () { + replayArgumentsArr.forEach(function (replayArgument) { + var _a; + if ((_a = callbacks[key]) === null || _a === void 0 ? void 0 : _a.includes(callback)) { + try { + if (Array.isArray(replayArgument)) { + callback.apply(undefined, replayArgument); + } + else { + callback.apply(undefined, [replayArgument]); + } + } + catch (err) { + _handleError(err, key); + } + } + }); + }, 0); + } + return function () { + var allForKey = callbacks[key]; + if (!allForKey) { + return; + } + allForKey = allForKey.reduce(function (acc, element, index) { + if (!(element === callback && acc.length === index)) { + acc.push(element); + } + return acc; + }, []); + if (allForKey.length === 0) { + delete callbacks[key]; + } + else { + callbacks[key] = allForKey; + } + }; + } + function execute(key) { + var argumentsArr = []; + for (var _i = 1; _i < arguments.length; _i++) { + argumentsArr[_i - 1] = arguments[_i]; + } + var callbacksForKey = callbacks[key]; + if (!callbacksForKey || callbacksForKey.length === 0) { + return []; + } + var results = []; + callbacksForKey.forEach(function (callback) { + try { + var result = callback.apply(undefined, argumentsArr); + results.push(result); + } + catch (err) { + results.push(undefined); + _handleError(err, key); + } + }); + return results; + } + function _handleError(exceptionArtifact, key) { + var errParam = exceptionArtifact instanceof Error ? exceptionArtifact : new Error(exceptionArtifact); + if (_userErrorHandler) { + _userErrorHandler(errParam); + return; + } + var msg = "[ERROR] callback-registry: User callback for key \"" + key + "\" failed: " + errParam.stack; + if (options) { + switch (options.errorHandling) { + case "log": + return console.error(msg); + case "silent": + return; + case "throw": + throw new Error(msg); + } + } + console.error(msg); + } + function clear() { + callbacks = {}; + } + function clearKey(key) { + var callbacksForKey = callbacks[key]; + if (!callbacksForKey) { + return; + } + delete callbacks[key]; + } + return { + add: add, + execute: execute, + clear: clear, + clearKey: clearKey + }; + } + createRegistry.default = createRegistry; + var lib = createRegistry; + + + var CallbackFactory = /*@__PURE__*/getDefaultExportFromCjs(lib); + + /** + * Wraps values in an `Ok` type. + * + * Example: `ok(5) // => {ok: true, result: 5}` + */ + var ok = function (result) { return ({ ok: true, result: result }); }; + /** + * Wraps errors in an `Err` type. + * + * Example: `err('on fire') // => {ok: false, error: 'on fire'}` + */ + var err = function (error) { return ({ ok: false, error: error }); }; + /** + * Create a `Promise` that either resolves with the result of `Ok` or rejects + * with the error of `Err`. + */ + var asPromise = function (r) { + return r.ok === true ? Promise.resolve(r.result) : Promise.reject(r.error); + }; + /** + * Unwraps a `Result` and returns either the result of an `Ok`, or + * `defaultValue`. + * + * Example: + * ``` + * Result.withDefault(5, number().run(json)) + * ``` + * + * It would be nice if `Decoder` had an instance method that mirrored this + * function. Such a method would look something like this: + * ``` + * class Decoder { + * runWithDefault = (defaultValue: A, json: any): A => + * Result.withDefault(defaultValue, this.run(json)); + * } + * + * number().runWithDefault(5, json) + * ``` + * Unfortunately, the type of `defaultValue: A` on the method causes issues + * with type inference on the `object` decoder in some situations. While these + * inference issues can be solved by providing the optional type argument for + * `object`s, the extra trouble and confusion doesn't seem worth it. + */ + var withDefault = function (defaultValue, r) { + return r.ok === true ? r.result : defaultValue; + }; + /** + * Return the successful result, or throw an error. + */ + var withException = function (r) { + if (r.ok === true) { + return r.result; + } + else { + throw r.error; + } + }; + /** + * Apply `f` to the result of an `Ok`, or pass the error through. + */ + var map = function (f, r) { + return r.ok === true ? ok(f(r.result)) : r; + }; + /** + * Apply `f` to the result of two `Ok`s, or pass an error through. If both + * `Result`s are errors then the first one is returned. + */ + var map2 = function (f, ar, br) { + return ar.ok === false ? ar : + br.ok === false ? br : + ok(f(ar.result, br.result)); + }; + /** + * Apply `f` to the error of an `Err`, or pass the success through. + */ + var mapError = function (f, r) { + return r.ok === true ? r : err(f(r.error)); + }; + /** + * Chain together a sequence of computations that may fail, similar to a + * `Promise`. If the first computation fails then the error will propagate + * through. If it succeeds, then `f` will be applied to the value, returning a + * new `Result`. + */ + var andThen = function (f, r) { + return r.ok === true ? f(r.result) : r; + }; + + /*! ***************************************************************************** + Copyright (c) Microsoft Corporation. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THIS SOFTWARE. + ***************************************************************************** */ + /* global Reflect, Promise */ + + + + var __assign = function() { + __assign = Object.assign || function __assign(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; + } + return t; + }; + return __assign.apply(this, arguments); + }; + + function __rest(s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { + if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) + t[p[i]] = s[p[i]]; + } + return t; + } + + function isEqual(a, b) { + if (a === b) { + return true; + } + if (a === null && b === null) { + return true; + } + if (typeof (a) !== typeof (b)) { + return false; + } + if (typeof (a) === 'object') { + // Array + if (Array.isArray(a)) { + if (!Array.isArray(b)) { + return false; + } + if (a.length !== b.length) { + return false; + } + for (var i = 0; i < a.length; i++) { + if (!isEqual(a[i], b[i])) { + return false; + } + } + return true; + } + // Hash table + var keys = Object.keys(a); + if (keys.length !== Object.keys(b).length) { + return false; + } + for (var i = 0; i < keys.length; i++) { + if (!b.hasOwnProperty(keys[i])) { + return false; + } + if (!isEqual(a[keys[i]], b[keys[i]])) { + return false; + } + } + return true; + } + } + /* + * Helpers + */ + var isJsonArray = function (json) { return Array.isArray(json); }; + var isJsonObject = function (json) { + return typeof json === 'object' && json !== null && !isJsonArray(json); + }; + var typeString = function (json) { + switch (typeof json) { + case 'string': + return 'a string'; + case 'number': + return 'a number'; + case 'boolean': + return 'a boolean'; + case 'undefined': + return 'undefined'; + case 'object': + if (json instanceof Array) { + return 'an array'; + } + else if (json === null) { + return 'null'; + } + else { + return 'an object'; + } + default: + return JSON.stringify(json); + } + }; + var expectedGot = function (expected, got) { + return "expected " + expected + ", got " + typeString(got); + }; + var printPath = function (paths) { + return paths.map(function (path) { return (typeof path === 'string' ? "." + path : "[" + path + "]"); }).join(''); + }; + var prependAt = function (newAt, _a) { + var at = _a.at, rest = __rest(_a, ["at"]); + return (__assign({ at: newAt + (at || '') }, rest)); + }; + /** + * Decoders transform json objects with unknown structure into known and + * verified forms. You can create objects of type `Decoder` with either the + * primitive decoder functions, such as `boolean()` and `string()`, or by + * applying higher-order decoders to the primitives, such as `array(boolean())` + * or `dict(string())`. + * + * Each of the decoder functions are available both as a static method on + * `Decoder` and as a function alias -- for example the string decoder is + * defined at `Decoder.string()`, but is also aliased to `string()`. Using the + * function aliases exported with the library is recommended. + * + * `Decoder` exposes a number of 'run' methods, which all decode json in the + * same way, but communicate success and failure in different ways. The `map` + * and `andThen` methods modify decoders without having to call a 'run' method. + * + * Alternatively, the main decoder `run()` method returns an object of type + * `Result`. This library provides a number of helper + * functions for dealing with the `Result` type, so you can do all the same + * things with a `Result` as with the decoder methods. + */ + var Decoder = /** @class */ (function () { + /** + * The Decoder class constructor is kept private to separate the internal + * `decode` function from the external `run` function. The distinction + * between the two functions is that `decode` returns a + * `Partial` on failure, which contains an unfinished error + * report. When `run` is called on a decoder, the relevant series of `decode` + * calls is made, and then on failure the resulting `Partial` + * is turned into a `DecoderError` by filling in the missing information. + * + * While hiding the constructor may seem restrictive, leveraging the + * provided decoder combinators and helper functions such as + * `andThen` and `map` should be enough to build specialized decoders as + * needed. + */ + function Decoder(decode) { + var _this = this; + this.decode = decode; + /** + * Run the decoder and return a `Result` with either the decoded value or a + * `DecoderError` containing the json input, the location of the error, and + * the error message. + * + * Examples: + * ``` + * number().run(12) + * // => {ok: true, result: 12} + * + * string().run(9001) + * // => + * // { + * // ok: false, + * // error: { + * // kind: 'DecoderError', + * // input: 9001, + * // at: 'input', + * // message: 'expected a string, got 9001' + * // } + * // } + * ``` + */ + this.run = function (json) { + return mapError(function (error) { return ({ + kind: 'DecoderError', + input: json, + at: 'input' + (error.at || ''), + message: error.message || '' + }); }, _this.decode(json)); + }; + /** + * Run the decoder as a `Promise`. + */ + this.runPromise = function (json) { return asPromise(_this.run(json)); }; + /** + * Run the decoder and return the value on success, or throw an exception + * with a formatted error string. + */ + this.runWithException = function (json) { return withException(_this.run(json)); }; + /** + * Construct a new decoder that applies a transformation to the decoded + * result. If the decoder succeeds then `f` will be applied to the value. If + * it fails the error will propagated through. + * + * Example: + * ``` + * number().map(x => x * 5).run(10) + * // => {ok: true, result: 50} + * ``` + */ + this.map = function (f) { + return new Decoder(function (json) { return map(f, _this.decode(json)); }); + }; + /** + * Chain together a sequence of decoders. The first decoder will run, and + * then the function will determine what decoder to run second. If the result + * of the first decoder succeeds then `f` will be applied to the decoded + * value. If it fails the error will propagate through. + * + * This is a very powerful method -- it can act as both the `map` and `where` + * methods, can improve error messages for edge cases, and can be used to + * make a decoder for custom types. + * + * Example of adding an error message: + * ``` + * const versionDecoder = valueAt(['version'], number()); + * const infoDecoder3 = object({a: boolean()}); + * + * const decoder = versionDecoder.andThen(version => { + * switch (version) { + * case 3: + * return infoDecoder3; + * default: + * return fail(`Unable to decode info, version ${version} is not supported.`); + * } + * }); + * + * decoder.run({version: 3, a: true}) + * // => {ok: true, result: {a: true}} + * + * decoder.run({version: 5, x: 'abc'}) + * // => + * // { + * // ok: false, + * // error: {... message: 'Unable to decode info, version 5 is not supported.'} + * // } + * ``` + * + * Example of decoding a custom type: + * ``` + * // nominal type for arrays with a length of at least one + * type NonEmptyArray = T[] & { __nonEmptyArrayBrand__: void }; + * + * const nonEmptyArrayDecoder = (values: Decoder): Decoder> => + * array(values).andThen(arr => + * arr.length > 0 + * ? succeed(createNonEmptyArray(arr)) + * : fail(`expected a non-empty array, got an empty array`) + * ); + * ``` + */ + this.andThen = function (f) { + return new Decoder(function (json) { + return andThen(function (value) { return f(value).decode(json); }, _this.decode(json)); + }); + }; + /** + * Add constraints to a decoder _without_ changing the resulting type. The + * `test` argument is a predicate function which returns true for valid + * inputs. When `test` fails on an input, the decoder fails with the given + * `errorMessage`. + * + * ``` + * const chars = (length: number): Decoder => + * string().where( + * (s: string) => s.length === length, + * `expected a string of length ${length}` + * ); + * + * chars(5).run('12345') + * // => {ok: true, result: '12345'} + * + * chars(2).run('HELLO') + * // => {ok: false, error: {... message: 'expected a string of length 2'}} + * + * chars(12).run(true) + * // => {ok: false, error: {... message: 'expected a string, got a boolean'}} + * ``` + */ + this.where = function (test, errorMessage) { + return _this.andThen(function (value) { return (test(value) ? Decoder.succeed(value) : Decoder.fail(errorMessage)); }); + }; + } + /** + * Decoder primitive that validates strings, and fails on all other input. + */ + Decoder.string = function () { + return new Decoder(function (json) { + return typeof json === 'string' + ? ok(json) + : err({ message: expectedGot('a string', json) }); + }); + }; + /** + * Decoder primitive that validates numbers, and fails on all other input. + */ + Decoder.number = function () { + return new Decoder(function (json) { + return typeof json === 'number' + ? ok(json) + : err({ message: expectedGot('a number', json) }); + }); + }; + /** + * Decoder primitive that validates booleans, and fails on all other input. + */ + Decoder.boolean = function () { + return new Decoder(function (json) { + return typeof json === 'boolean' + ? ok(json) + : err({ message: expectedGot('a boolean', json) }); + }); + }; + Decoder.constant = function (value) { + return new Decoder(function (json) { + return isEqual(json, value) + ? ok(value) + : err({ message: "expected " + JSON.stringify(value) + ", got " + JSON.stringify(json) }); + }); + }; + Decoder.object = function (decoders) { + return new Decoder(function (json) { + if (isJsonObject(json) && decoders) { + var obj = {}; + for (var key in decoders) { + if (decoders.hasOwnProperty(key)) { + var r = decoders[key].decode(json[key]); + if (r.ok === true) { + // tslint:disable-next-line:strict-type-predicates + if (r.result !== undefined) { + obj[key] = r.result; + } + } + else if (json[key] === undefined) { + return err({ message: "the key '" + key + "' is required but was not present" }); + } + else { + return err(prependAt("." + key, r.error)); + } + } + } + return ok(obj); + } + else if (isJsonObject(json)) { + return ok(json); + } + else { + return err({ message: expectedGot('an object', json) }); + } + }); + }; + Decoder.array = function (decoder) { + return new Decoder(function (json) { + if (isJsonArray(json) && decoder) { + var decodeValue_1 = function (v, i) { + return mapError(function (err$$1) { return prependAt("[" + i + "]", err$$1); }, decoder.decode(v)); + }; + return json.reduce(function (acc, v, i) { + return map2(function (arr, result) { return arr.concat([result]); }, acc, decodeValue_1(v, i)); + }, ok([])); + } + else if (isJsonArray(json)) { + return ok(json); + } + else { + return err({ message: expectedGot('an array', json) }); + } + }); + }; + Decoder.tuple = function (decoders) { + return new Decoder(function (json) { + if (isJsonArray(json)) { + if (json.length !== decoders.length) { + return err({ + message: "expected a tuple of length " + decoders.length + ", got one of length " + json.length + }); + } + var result = []; + for (var i = 0; i < decoders.length; i++) { + var nth = decoders[i].decode(json[i]); + if (nth.ok) { + result[i] = nth.result; + } + else { + return err(prependAt("[" + i + "]", nth.error)); + } + } + return ok(result); + } + else { + return err({ message: expectedGot("a tuple of length " + decoders.length, json) }); + } + }); + }; + Decoder.union = function (ad, bd) { + var decoders = []; + for (var _i = 2; _i < arguments.length; _i++) { + decoders[_i - 2] = arguments[_i]; + } + return Decoder.oneOf.apply(Decoder, [ad, bd].concat(decoders)); + }; + Decoder.intersection = function (ad, bd) { + var ds = []; + for (var _i = 2; _i < arguments.length; _i++) { + ds[_i - 2] = arguments[_i]; + } + return new Decoder(function (json) { + return [ad, bd].concat(ds).reduce(function (acc, decoder) { return map2(Object.assign, acc, decoder.decode(json)); }, ok({})); + }); + }; + /** + * Escape hatch to bypass validation. Always succeeds and types the result as + * `any`. Useful for defining decoders incrementally, particularly for + * complex objects. + * + * Example: + * ``` + * interface User { + * name: string; + * complexUserData: ComplexType; + * } + * + * const userDecoder: Decoder = object({ + * name: string(), + * complexUserData: anyJson() + * }); + * ``` + */ + Decoder.anyJson = function () { return new Decoder(function (json) { return ok(json); }); }; + /** + * Decoder identity function which always succeeds and types the result as + * `unknown`. + */ + Decoder.unknownJson = function () { + return new Decoder(function (json) { return ok(json); }); + }; + /** + * Decoder for json objects where the keys are unknown strings, but the values + * should all be of the same type. + * + * Example: + * ``` + * dict(number()).run({chocolate: 12, vanilla: 10, mint: 37}); + * // => {ok: true, result: {chocolate: 12, vanilla: 10, mint: 37}} + * ``` + */ + Decoder.dict = function (decoder) { + return new Decoder(function (json) { + if (isJsonObject(json)) { + var obj = {}; + for (var key in json) { + if (json.hasOwnProperty(key)) { + var r = decoder.decode(json[key]); + if (r.ok === true) { + obj[key] = r.result; + } + else { + return err(prependAt("." + key, r.error)); + } + } + } + return ok(obj); + } + else { + return err({ message: expectedGot('an object', json) }); + } + }); + }; + /** + * Decoder for values that may be `undefined`. This is primarily helpful for + * decoding interfaces with optional fields. + * + * Example: + * ``` + * interface User { + * id: number; + * isOwner?: boolean; + * } + * + * const decoder: Decoder = object({ + * id: number(), + * isOwner: optional(boolean()) + * }); + * ``` + */ + Decoder.optional = function (decoder) { + return new Decoder(function (json) { return (json === undefined || json === null ? ok(undefined) : decoder.decode(json)); }); + }; + /** + * Decoder that attempts to run each decoder in `decoders` and either succeeds + * with the first successful decoder, or fails after all decoders have failed. + * + * Note that `oneOf` expects the decoders to all have the same return type, + * while `union` creates a decoder for the union type of all the input + * decoders. + * + * Examples: + * ``` + * oneOf(string(), number().map(String)) + * oneOf(constant('start'), constant('stop'), succeed('unknown')) + * ``` + */ + Decoder.oneOf = function () { + var decoders = []; + for (var _i = 0; _i < arguments.length; _i++) { + decoders[_i] = arguments[_i]; + } + return new Decoder(function (json) { + var errors = []; + for (var i = 0; i < decoders.length; i++) { + var r = decoders[i].decode(json); + if (r.ok === true) { + return r; + } + else { + errors[i] = r.error; + } + } + var errorsList = errors + .map(function (error) { return "at error" + (error.at || '') + ": " + error.message; }) + .join('", "'); + return err({ + message: "expected a value matching one of the decoders, got the errors [\"" + errorsList + "\"]" + }); + }); + }; + /** + * Decoder that always succeeds with either the decoded value, or a fallback + * default value. + */ + Decoder.withDefault = function (defaultValue, decoder) { + return new Decoder(function (json) { + return ok(withDefault(defaultValue, decoder.decode(json))); + }); + }; + /** + * Decoder that pulls a specific field out of a json structure, instead of + * decoding and returning the full structure. The `paths` array describes the + * object keys and array indices to traverse, so that values can be pulled out + * of a nested structure. + * + * Example: + * ``` + * const decoder = valueAt(['a', 'b', 0], string()); + * + * decoder.run({a: {b: ['surprise!']}}) + * // => {ok: true, result: 'surprise!'} + * + * decoder.run({a: {x: 'cats'}}) + * // => {ok: false, error: {... at: 'input.a.b[0]' message: 'path does not exist'}} + * ``` + * + * Note that the `decoder` is ran on the value found at the last key in the + * path, even if the last key is not found. This allows the `optional` + * decoder to succeed when appropriate. + * ``` + * const optionalDecoder = valueAt(['a', 'b', 'c'], optional(string())); + * + * optionalDecoder.run({a: {b: {c: 'surprise!'}}}) + * // => {ok: true, result: 'surprise!'} + * + * optionalDecoder.run({a: {b: 'cats'}}) + * // => {ok: false, error: {... at: 'input.a.b.c' message: 'expected an object, got "cats"'} + * + * optionalDecoder.run({a: {b: {z: 1}}}) + * // => {ok: true, result: undefined} + * ``` + */ + Decoder.valueAt = function (paths, decoder) { + return new Decoder(function (json) { + var jsonAtPath = json; + for (var i = 0; i < paths.length; i++) { + if (jsonAtPath === undefined) { + return err({ + at: printPath(paths.slice(0, i + 1)), + message: 'path does not exist' + }); + } + else if (typeof paths[i] === 'string' && !isJsonObject(jsonAtPath)) { + return err({ + at: printPath(paths.slice(0, i + 1)), + message: expectedGot('an object', jsonAtPath) + }); + } + else if (typeof paths[i] === 'number' && !isJsonArray(jsonAtPath)) { + return err({ + at: printPath(paths.slice(0, i + 1)), + message: expectedGot('an array', jsonAtPath) + }); + } + else { + jsonAtPath = jsonAtPath[paths[i]]; + } + } + return mapError(function (error) { + return jsonAtPath === undefined + ? { at: printPath(paths), message: 'path does not exist' } + : prependAt(printPath(paths), error); + }, decoder.decode(jsonAtPath)); + }); + }; + /** + * Decoder that ignores the input json and always succeeds with `fixedValue`. + */ + Decoder.succeed = function (fixedValue) { + return new Decoder(function (json) { return ok(fixedValue); }); + }; + /** + * Decoder that ignores the input json and always fails with `errorMessage`. + */ + Decoder.fail = function (errorMessage) { + return new Decoder(function (json) { return err({ message: errorMessage }); }); + }; + /** + * Decoder that allows for validating recursive data structures. Unlike with + * functions, decoders assigned to variables can't reference themselves + * before they are fully defined. We can avoid prematurely referencing the + * decoder by wrapping it in a function that won't be called until use, at + * which point the decoder has been defined. + * + * Example: + * ``` + * interface Comment { + * msg: string; + * replies: Comment[]; + * } + * + * const decoder: Decoder = object({ + * msg: string(), + * replies: lazy(() => array(decoder)) + * }); + * ``` + */ + Decoder.lazy = function (mkDecoder) { + return new Decoder(function (json) { return mkDecoder().decode(json); }); + }; + return Decoder; + }()); + + /* tslint:disable:variable-name */ + /** See `Decoder.string` */ + var string = Decoder.string; + /** See `Decoder.number` */ + var number = Decoder.number; + /** See `Decoder.boolean` */ + var boolean = Decoder.boolean; + /** See `Decoder.anyJson` */ + var anyJson = Decoder.anyJson; + /** See `Decoder.unknownJson` */ + Decoder.unknownJson; + /** See `Decoder.constant` */ + var constant = Decoder.constant; + /** See `Decoder.object` */ + var object = Decoder.object; + /** See `Decoder.array` */ + var array = Decoder.array; + /** See `Decoder.tuple` */ + Decoder.tuple; + /** See `Decoder.dict` */ + Decoder.dict; + /** See `Decoder.optional` */ + var optional = Decoder.optional; + /** See `Decoder.oneOf` */ + var oneOf = Decoder.oneOf; + /** See `Decoder.union` */ + Decoder.union; + /** See `Decoder.intersection` */ + var intersection = Decoder.intersection; + /** See `Decoder.withDefault` */ + Decoder.withDefault; + /** See `Decoder.valueAt` */ + Decoder.valueAt; + /** See `Decoder.succeed` */ + Decoder.succeed; + /** See `Decoder.fail` */ + Decoder.fail; + /** See `Decoder.lazy` */ + var lazy = Decoder.lazy; + + const nonEmptyStringDecoder = string().where((s) => s.length > 0, "Expected a non-empty string"); + const nonNegativeNumberDecoder = number().where((num) => num >= 0, "Expected a non-negative number"); + const positiveNumberDecoder = number().where((num) => num > 0, "Expected a positive number"); + const windowDragModeDecoder = oneOf(constant("keepInside"), constant("autoEject")); + const isWindowInSwimlaneResultDecoder = object({ + inWorkspace: boolean() + }); + const allParentDecoder = oneOf(constant("workspace"), constant("row"), constant("column"), constant("group")); + const subParentDecoder = oneOf(constant("row"), constant("column"), constant("group")); + const frameStateDecoder = oneOf(constant("maximized"), constant("minimized"), constant("normal")); + const loadingAnimationTypeDecoder = oneOf(constant("workspace")); + const checkThrowCallback = (callback, allowUndefined) => { + const argumentType = typeof callback; + if (allowUndefined && argumentType !== "function" && argumentType !== "undefined") { + throw new Error(`Provided argument must be either undefined or of type function, provided: ${argumentType}`); + } + if (!allowUndefined && argumentType !== "function") { + throw new Error(`Provided argument must be of type function, provided: ${argumentType}`); + } + }; + const workspaceBuilderCreateConfigDecoder = optional(object({ + saveLayout: optional(boolean()) + })); + const deleteLayoutConfigDecoder = object({ + name: nonEmptyStringDecoder + }); + const windowDefinitionConfigDecoder = object({ + minWidth: optional(number()), + maxWidth: optional(number()), + minHeight: optional(number()), + maxHeight: optional(number()), + allowExtract: optional(boolean()), + allowReorder: optional(boolean()), + showCloseButton: optional(boolean()) + }); + const groupDefinitionConfigDecoder = object({ + minWidth: optional(number()), + maxWidth: optional(number()), + minHeight: optional(number()), + maxHeight: optional(number()), + allowExtract: optional(boolean()), + allowReorder: optional(boolean()), + allowDrop: optional(boolean()), + allowDropHeader: optional(boolean()), + allowDropLeft: optional(boolean()), + allowDropRight: optional(boolean()), + allowDropTop: optional(boolean()), + allowDropBottom: optional(boolean()), + showMaximizeButton: optional(boolean()), + showEjectButton: optional(boolean()), + showAddWindowButton: optional(boolean()) + }); + const rowDefinitionConfigDecoder = object({ + minHeight: optional(number()), + maxHeight: optional(number()), + allowDrop: optional(boolean()), + allowSplitters: optional(boolean()), + isPinned: optional(boolean()), + maximizationBoundary: optional(boolean()) + }); + const columnDefinitionConfigDecoder = object({ + minWidth: optional(number()), + maxWidth: optional(number()), + allowDrop: optional(boolean()), + allowSplitters: optional(boolean()), + isPinned: optional(boolean()), + maximizationBoundary: optional(boolean()) + }); + const swimlaneWindowDefinitionDecoder = object({ + type: optional(constant("window")), + appName: optional(nonEmptyStringDecoder), + windowId: optional(nonEmptyStringDecoder), + context: optional(anyJson()), + config: optional(windowDefinitionConfigDecoder) + }); + const strictSwimlaneWindowDefinitionDecoder = object({ + type: constant("window"), + appName: optional(nonEmptyStringDecoder), + windowId: optional(nonEmptyStringDecoder), + context: optional(anyJson()), + config: optional(windowDefinitionConfigDecoder) + }); + const parentDefinitionDecoder = optional(object({ + type: optional(subParentDecoder), + children: optional(lazy(() => array(oneOf(swimlaneWindowDefinitionDecoder, parentDefinitionDecoder)))), + config: optional(anyJson()) + })); + const strictColumnDefinitionDecoder = object({ + type: constant("column"), + children: optional(lazy(() => array(oneOf(strictSwimlaneWindowDefinitionDecoder, strictParentDefinitionDecoder)))), + config: optional(columnDefinitionConfigDecoder) + }); + const strictRowDefinitionDecoder = object({ + type: constant("row"), + children: optional(lazy(() => array(oneOf(strictSwimlaneWindowDefinitionDecoder, strictParentDefinitionDecoder)))), + config: optional(rowDefinitionConfigDecoder) + }); + const strictGroupDefinitionDecoder = object({ + type: constant("group"), + children: optional(lazy(() => array(oneOf(strictSwimlaneWindowDefinitionDecoder, strictParentDefinitionDecoder)))), + config: optional(groupDefinitionConfigDecoder) + }); + const strictParentDefinitionDecoder = oneOf(strictGroupDefinitionDecoder, strictColumnDefinitionDecoder, strictRowDefinitionDecoder); + oneOf(string().where((s) => s.toLowerCase() === "maximized", "Expected a case insensitive variation of 'maximized'"), string().where((s) => s.toLowerCase() === "normal", "Expected a case insensitive variation of 'normal'")); + const newFrameConfigDecoder = object({ + bounds: optional(object({ + left: optional(number()), + top: optional(number()), + width: optional(nonNegativeNumberDecoder), + height: optional(nonNegativeNumberDecoder) + })), + frameId: optional(nonEmptyStringDecoder) + }); + const loadingStrategyDecoder = oneOf(constant("direct"), constant("delayed"), constant("lazy")); + const restoreWorkspaceConfigDecoder = optional(object({ + app: optional(nonEmptyStringDecoder), + context: optional(anyJson()), + loadingStrategy: optional(loadingStrategyDecoder), + title: optional(nonEmptyStringDecoder), + reuseWorkspaceId: optional(nonEmptyStringDecoder), + frameId: optional(nonEmptyStringDecoder), + applicationName: optional(nonEmptyStringDecoder), + lockdown: optional(boolean()), + activateFrame: optional(boolean()), + newFrame: optional(oneOf(newFrameConfigDecoder, boolean())), + noTabHeader: optional(boolean()), + inMemoryLayout: optional(boolean()), + icon: optional(nonEmptyStringDecoder), + isPinned: optional(boolean()), + isSelected: optional(boolean()), + positionIndex: optional(nonNegativeNumberDecoder), + allowSystemHibernation: optional(boolean()) + })); + const openWorkspaceConfigDecoder = object({ + name: nonEmptyStringDecoder, + restoreOptions: optional(restoreWorkspaceConfigDecoder) + }); + const workspaceDefinitionDecoder = object({ + children: optional(array(oneOf(swimlaneWindowDefinitionDecoder, strictParentDefinitionDecoder))), + context: optional(anyJson()), + config: optional(object({ + title: optional(nonEmptyStringDecoder), + position: optional(nonNegativeNumberDecoder), + isFocused: optional(boolean()), + noTabHeader: optional(boolean()), + reuseWorkspaceId: optional(nonEmptyStringDecoder), + loadingStrategy: optional(loadingStrategyDecoder), + allowDrop: optional(boolean()), + allowDropLeft: optional(boolean()), + allowDropTop: optional(boolean()), + allowDropRight: optional(boolean()), + allowDropBottom: optional(boolean()), + allowSystemHibernation: optional(boolean()), + allowExtract: optional(boolean()), + allowWindowReorder: optional(boolean()), + showSaveButton: optional(boolean()), + allowWorkspaceTabReorder: optional(boolean()), + allowWorkspaceTabExtract: optional(boolean()), + showCloseButton: optional(boolean()), + allowSplitters: optional(boolean()), + showWindowCloseButtons: optional(boolean()), + showEjectButtons: optional(boolean()), + showAddWindowButtons: optional(boolean()), + icon: optional(nonEmptyStringDecoder), + isPinned: optional(boolean()), + isSelected: optional(boolean()), + positionIndex: optional(nonNegativeNumberDecoder), + windowDragMode: optional(windowDragModeDecoder) + })), + frame: optional(object({ + activate: optional(boolean()), + reuseFrameId: optional(nonEmptyStringDecoder), + applicationName: optional(nonEmptyStringDecoder), + newFrame: optional(oneOf(boolean(), newFrameConfigDecoder)) + })) + }); + const workspaceSelectorDecoder = object({ + workspaceId: nonEmptyStringDecoder + }); + const restoreWorkspaceDefinitionDecoder = object({ + name: nonEmptyStringDecoder, + restoreOptions: optional(restoreWorkspaceConfigDecoder) + }); + const emptyFrameDefinitionDecoder = optional(object({ + applicationName: optional(string()), + frameConfig: optional(newFrameConfigDecoder), + context: optional(object()), + layoutComponentId: optional(nonEmptyStringDecoder) + })); + const frameInitConfigDecoder = object({ + workspaces: array(oneOf(optional(workspaceDefinitionDecoder), optional(restoreWorkspaceDefinitionDecoder))) + }); + const frameInitProtocolConfigDecoder = object({ + frameId: nonEmptyStringDecoder, + workspaces: array(oneOf(workspaceDefinitionDecoder, restoreWorkspaceDefinitionDecoder)) + }); + const builderConfigDecoder = object({ + type: allParentDecoder, + definition: optional(oneOf(workspaceDefinitionDecoder, parentDefinitionDecoder)) + }); + const workspaceCreateConfigDecoder = intersection(workspaceDefinitionDecoder, object({ + saveConfig: optional(object({ + saveLayout: optional(boolean()) + })) + })); + const getFrameSummaryConfigDecoder = object({ + itemId: nonEmptyStringDecoder + }); + const frameInitializationContextDecoder = object({ + context: optional(object()) + }); + const frameSummaryDecoder = object({ + id: nonEmptyStringDecoder, + isFocused: optional(boolean()), + isInitialized: optional(boolean()), + initializationContext: optional(frameInitializationContextDecoder) + }); + object({ + type: subParentDecoder, + id: nonEmptyStringDecoder, + frameId: nonEmptyStringDecoder, + workspaceId: nonEmptyStringDecoder, + positionIndex: number() + }); + const eventTypeDecoder = oneOf(constant("frame"), constant("workspace"), constant("container"), constant("window")); + const streamRequestArgumentsDecoder = object({ + type: eventTypeDecoder, + branch: nonEmptyStringDecoder + }); + const workspaceEventActionDecoder = oneOf(constant("opened"), constant("closing"), constant("closed"), constant("focus"), constant("added"), constant("loaded"), constant("removed"), constant("childrenUpdate"), constant("containerChange"), constant("maximized"), constant("restored"), constant("minimized"), constant("normal"), constant("selected"), constant("lock-configuration-changed"), constant("hibernated"), constant("resumed")); + const workspaceConfigResultDecoder = object({ + frameId: nonEmptyStringDecoder, + title: nonEmptyStringDecoder, + positionIndex: nonNegativeNumberDecoder, + name: nonEmptyStringDecoder, + layoutName: optional(nonEmptyStringDecoder), + isHibernated: optional(boolean()), + isSelected: optional(boolean()), + allowDrop: optional(boolean()), + allowSystemHibernation: optional(boolean()), + allowExtract: optional(boolean()), + allowWindowReorder: optional(boolean()), + allowSplitters: optional(boolean()), + showCloseButton: optional(boolean()), + showSaveButton: optional(boolean()), + allowWorkspaceTabReorder: optional(boolean()), + allowWorkspaceTabExtract: optional(boolean()), + allowDropLeft: optional(boolean()), + allowDropTop: optional(boolean()), + allowDropRight: optional(boolean()), + allowDropBottom: optional(boolean()), + minWidth: optional(number()), + maxWidth: optional(number()), + minHeight: optional(number()), + maxHeight: optional(number()), + showAddWindowButtons: optional(boolean()), + showEjectButtons: optional(boolean()), + showWindowCloseButtons: optional(boolean()), + widthInPx: optional(number()), + heightInPx: optional(number()), + isPinned: optional(boolean()), + windowDragMode: optional(windowDragModeDecoder), + loadingStrategy: optional(loadingStrategyDecoder) + }); + const baseChildSnapshotConfigDecoder = object({ + frameId: nonEmptyStringDecoder, + workspaceId: nonEmptyStringDecoder, + positionIndex: number(), + minWidth: optional(number()), + maxWidth: optional(number()), + minHeight: optional(number()), + maxHeight: optional(number()) + }); + const parentSnapshotConfigDecoder = anyJson(); + const swimlaneWindowSnapshotConfigDecoder = intersection(baseChildSnapshotConfigDecoder, object({ + windowId: optional(nonEmptyStringDecoder), + isMaximized: optional(boolean()), + isFocused: boolean(), + isSelected: optional(boolean()), + title: optional(string()), + appName: optional(nonEmptyStringDecoder), + allowExtract: optional(boolean()), + allowReorder: optional(boolean()), + showCloseButton: optional(boolean()), + minWidth: optional(number()), + minHeight: optional(number()), + maxWidth: optional(number()), + maxHeight: optional(number()), + widthInPx: optional(number()), + heightInPx: optional(number()), + context: optional(anyJson()) + })); + const customWorkspaceSubParentSnapshotDecoder = object({ + id: optional(nonEmptyStringDecoder), + config: parentSnapshotConfigDecoder, + children: optional(lazy(() => array(customWorkspaceChildSnapshotDecoder))), + type: oneOf(constant("row"), constant("column"), constant("group")) + }); + const customWorkspaceWindowSnapshotDecoder = object({ + id: optional(nonEmptyStringDecoder), + config: swimlaneWindowSnapshotConfigDecoder, + type: constant("window") + }); + const customWorkspaceChildSnapshotDecoder = oneOf(customWorkspaceWindowSnapshotDecoder, customWorkspaceSubParentSnapshotDecoder); + const childSnapshotResultDecoder = customWorkspaceChildSnapshotDecoder; + const workspaceSnapshotResultDecoder = object({ + id: nonEmptyStringDecoder, + config: workspaceConfigResultDecoder, + children: array(childSnapshotResultDecoder), + frameSummary: frameSummaryDecoder, + context: optional(anyJson()) + }); + const windowLayoutItemDecoder = object({ + type: constant("window"), + config: object({ + appName: nonEmptyStringDecoder, + windowId: optional(nonEmptyStringDecoder), + context: optional(anyJson()), + url: optional(nonEmptyStringDecoder), + title: optional(string()), + allowExtract: optional(boolean()), + allowReorder: optional(boolean()), + showCloseButton: optional(boolean()), + minWidth: optional(number()), + minHeight: optional(number()), + maxWidth: optional(number()), + maxHeight: optional(number()), + isMaximized: optional(boolean()) + }) + }); + const groupLayoutItemDecoder = object({ + type: constant("group"), + config: anyJson(), + children: array(oneOf(windowLayoutItemDecoder)) + }); + const columnLayoutItemDecoder = object({ + type: constant("column"), + config: anyJson(), + children: array(oneOf(groupLayoutItemDecoder, windowLayoutItemDecoder, lazy(() => columnLayoutItemDecoder), lazy(() => rowLayoutItemDecoder))) + }); + const rowLayoutItemDecoder = object({ + type: constant("row"), + config: anyJson(), + children: array(oneOf(columnLayoutItemDecoder, groupLayoutItemDecoder, windowLayoutItemDecoder, lazy(() => rowLayoutItemDecoder))) + }); + const workspaceLayoutDecoder = object({ + name: nonEmptyStringDecoder, + type: constant("Workspace"), + metadata: optional(anyJson()), + components: array(object({ + type: constant("Workspace"), + application: optional(string()), + state: object({ + config: anyJson(), + context: anyJson(), + children: array(oneOf(rowLayoutItemDecoder, columnLayoutItemDecoder, groupLayoutItemDecoder, windowLayoutItemDecoder)) + }) + })) + }); + const workspacesImportLayoutDecoder = object({ + layout: workspaceLayoutDecoder, + mode: oneOf(constant("replace"), constant("merge")) + }); + const workspacesImportLayoutsDecoder = object({ + layouts: array(workspaceLayoutDecoder), + mode: oneOf(constant("replace"), constant("merge")) + }); + const exportedLayoutsResultDecoder = object({ + layouts: array(workspaceLayoutDecoder) + }); + const frameSummaryResultDecoder = object({ + id: nonEmptyStringDecoder, + isFocused: optional(boolean()), + isInitialized: optional(boolean()), + initializationContext: optional(frameInitializationContextDecoder) + }); + const frameSummariesResultDecoder = object({ + summaries: array(frameSummaryResultDecoder) + }); + const workspaceSummaryResultDecoder = object({ + id: nonEmptyStringDecoder, + config: workspaceConfigResultDecoder + }); + const workspaceSummariesResultDecoder = object({ + summaries: array(workspaceSummaryResultDecoder) + }); + const frameSnapshotResultDecoder = object({ + id: nonEmptyStringDecoder, + config: anyJson(), + workspaces: array(workspaceSnapshotResultDecoder) + }); + const layoutSummaryDecoder = object({ + name: nonEmptyStringDecoder, + applicationName: optional(string()) + }); + const layoutSummariesDecoder = object({ + summaries: array(layoutSummaryDecoder) + }); + const simpleWindowOperationSuccessResultDecoder = object({ + windowId: nonEmptyStringDecoder + }); + const voidResultDecoder = anyJson(); + const frameStateResultDecoder = object({ + state: frameStateDecoder + }); + const frameBoundsDecoder = object({ + top: number(), + left: number(), + width: nonNegativeNumberDecoder, + height: nonNegativeNumberDecoder + }); + const frameBoundsResultDecoder = object({ + bounds: frameBoundsDecoder + }); + const getWorkspaceIconResultDecoder = object({ + icon: optional(nonEmptyStringDecoder) + }); + const getPlatformFrameIdResultDecoder = object({ + id: optional(nonEmptyStringDecoder) + }); + const operationCheckResultDecoder = object({ + isSupported: boolean() + }); + const resizeConfigDecoder = object({ + width: optional(positiveNumberDecoder), + height: optional(positiveNumberDecoder), + relative: optional(boolean()) + }); + const moveConfigDecoder = object({ + top: optional(number()), + left: optional(number()), + relative: optional(boolean()) + }); + const simpleItemConfigDecoder = object({ + itemId: nonEmptyStringDecoder + }); + const frameSnapshotConfigDecoder = object({ + itemId: nonEmptyStringDecoder, + excludeIds: optional(boolean()) + }); + const frameStateConfigDecoder = object({ + frameId: nonEmptyStringDecoder, + requestedState: frameStateDecoder + }); + const setItemTitleConfigDecoder = object({ + itemId: nonEmptyStringDecoder, + title: nonEmptyStringDecoder + }); + const moveWindowConfigDecoder = object({ + itemId: nonEmptyStringDecoder, + containerId: nonEmptyStringDecoder + }); + const resizeItemConfigDecoder = intersection(simpleItemConfigDecoder, resizeConfigDecoder); + const setMaximizationBoundaryConfigDecoder = object({ + itemId: nonEmptyStringDecoder, + enabled: boolean() + }); + const moveFrameConfigDecoder = intersection(simpleItemConfigDecoder, moveConfigDecoder); + object({ + id: nonEmptyStringDecoder, + type: subParentDecoder + }); + const addWindowConfigDecoder = object({ + definition: swimlaneWindowDefinitionDecoder, + parentId: nonEmptyStringDecoder, + parentType: allParentDecoder + }); + const addContainerConfigDecoder = object({ + definition: strictParentDefinitionDecoder, + parentId: nonEmptyStringDecoder, + parentType: allParentDecoder + }); + const addItemResultDecoder = object({ + itemId: nonEmptyStringDecoder, + windowId: optional(nonEmptyStringDecoder) + }); + const pingResultDecoder = object({ + live: boolean() + }); + const bundleWorkspaceConfigDecoder = object({ + type: oneOf(constant("row"), constant("column")), + workspaceId: nonEmptyStringDecoder + }); + const bundleItemConfigDecoder = object({ + type: oneOf(constant("row"), constant("column")), + itemId: nonEmptyStringDecoder + }); + const containerSummaryResultDecoder = object({ + itemId: nonEmptyStringDecoder, + config: parentSnapshotConfigDecoder + }); + const frameStreamDataDecoder = object({ + frameSummary: frameSummaryDecoder, + frameBounds: optional(frameBoundsDecoder) + }); + const workspaceStreamDataDecoder = object({ + workspaceSummary: workspaceSummaryResultDecoder, + frameSummary: frameSummaryDecoder, + workspaceSnapshot: optional(workspaceSnapshotResultDecoder), + frameBounds: optional(frameBoundsDecoder) + }); + const containerStreamDataDecoder = object({ + containerSummary: containerSummaryResultDecoder + }); + const windowStreamDataDecoder = object({ + windowSummary: object({ + itemId: nonEmptyStringDecoder, + parentId: nonEmptyStringDecoder, + config: swimlaneWindowSnapshotConfigDecoder + }) + }); + const workspaceLayoutSaveConfigDecoder = object({ + name: nonEmptyStringDecoder, + workspaceId: nonEmptyStringDecoder, + saveContext: optional(boolean()), + allowMultiple: optional(boolean()), + metadata: optional(object()) + }); + const workspaceLockConfigDecoder = object({ + allowDrop: optional(boolean()), + allowDropLeft: optional(boolean()), + allowDropTop: optional(boolean()), + allowDropRight: optional(boolean()), + allowDropBottom: optional(boolean()), + allowSystemHibernation: optional(boolean()), + allowExtract: optional(boolean()), + allowWindowReorder: optional(boolean()), + allowSplitters: optional(boolean()), + showCloseButton: optional(boolean()), + showSaveButton: optional(boolean()), + allowWorkspaceTabReorder: optional(boolean()), + allowWorkspaceTabExtract: optional(boolean()), + showWindowCloseButtons: optional(boolean()), + showAddWindowButtons: optional(boolean()), + showEjectButtons: optional(boolean()), + }); + const lockWorkspaceDecoder = object({ + workspaceId: nonEmptyStringDecoder, + config: optional(workspaceLockConfigDecoder) + }); + const windowLockConfigDecoder = object({ + allowExtract: optional(boolean()), + allowReorder: optional(boolean()), + showCloseButton: optional(boolean()) + }); + const elementResizeConfigDecoder = object({ + width: optional(nonNegativeNumberDecoder), + height: optional(nonNegativeNumberDecoder) + }); + const lockWindowDecoder = object({ + windowPlacementId: nonEmptyStringDecoder, + config: optional(windowLockConfigDecoder) + }); + const rowLockConfigDecoder = object({ + allowDrop: optional(boolean()), + allowSplitters: optional(boolean()), + }); + const columnLockConfigDecoder = object({ + allowDrop: optional(boolean()), + allowSplitters: optional(boolean()), + }); + const groupLockConfigDecoder = object({ + allowExtract: optional(boolean()), + allowReorder: optional(boolean()), + allowDrop: optional(boolean()), + allowDropLeft: optional(boolean()), + allowDropRight: optional(boolean()), + allowDropTop: optional(boolean()), + allowDropBottom: optional(boolean()), + allowDropHeader: optional(boolean()), + showMaximizeButton: optional(boolean()), + showEjectButton: optional(boolean()), + showAddWindowButton: optional(boolean()), + }); + const lockRowDecoder = object({ + itemId: nonEmptyStringDecoder, + type: constant("row"), + config: optional(rowLockConfigDecoder) + }); + const lockColumnDecoder = object({ + itemId: nonEmptyStringDecoder, + type: constant("column"), + config: optional(columnLockConfigDecoder) + }); + const lockGroupDecoder = object({ + itemId: nonEmptyStringDecoder, + type: constant("group"), + config: optional(groupLockConfigDecoder) + }); + const lockContainerDecoder = oneOf(lockRowDecoder, lockColumnDecoder, lockGroupDecoder); + const pinWorkspaceDecoder = object({ + workspaceId: nonEmptyStringDecoder, + icon: optional(nonEmptyStringDecoder) + }); + const setWorkspaceIconDecoder = object({ + workspaceId: nonEmptyStringDecoder, + icon: optional(nonEmptyStringDecoder) + }); + const workspacePinOptionsDecoder = optional(object({ + icon: optional(nonEmptyStringDecoder) + })); + const shortcutConfigDecoder = object({ + shortcut: nonEmptyStringDecoder, + frameId: nonEmptyStringDecoder + }); + const shortcutClickedDataDecoder = object({ + shortcut: nonEmptyStringDecoder, + frameId: nonEmptyStringDecoder + }); + const setMaximizationBoundaryAPIConfigDecoder = object({ + enabled: boolean() + }); + const loadingAnimationConfigDecoder = object({ + itemId: nonEmptyStringDecoder, + type: loadingAnimationTypeDecoder + }); + const operationCheckConfigDecoder = object({ + operation: nonEmptyStringDecoder + }); + const setWindowDragModeDecoder = object({ + itemId: nonEmptyStringDecoder, + dragMode: windowDragModeDecoder + }); + const setLoadingStrategyDecoder = object({ + itemId: nonEmptyStringDecoder, + strategy: loadingStrategyDecoder + }); + + const webPlatformMethodName = "T42.Web.Platform.Control"; + const webPlatformWspStreamName = "T42.Web.Platform.WSP.Stream"; + const OUTGOING_METHODS = { + control: { name: "T42.Workspaces.Control", isStream: false }, + frameStream: { name: "T42.Workspaces.Stream.Frame", isStream: true }, + workspaceStream: { name: "T42.Workspaces.Stream.Workspace", isStream: true }, + containerStream: { name: "T42.Workspaces.Stream.Container", isStream: true }, + windowStream: { name: "T42.Workspaces.Stream.Window", isStream: true } + }; + const INCOMING_METHODS = { + control: { name: "T42.Workspaces.Client.Control", isStream: false }, + }; + const STREAMS = { + frame: { name: "T42.Workspaces.Stream.Frame", payloadDecoder: frameStreamDataDecoder }, + workspace: { name: "T42.Workspaces.Stream.Workspace", payloadDecoder: workspaceStreamDataDecoder }, + container: { name: "T42.Workspaces.Stream.Container", payloadDecoder: containerStreamDataDecoder }, + window: { name: "T42.Workspaces.Stream.Window", payloadDecoder: windowStreamDataDecoder } + }; + const CLIENT_OPERATIONS = { + shortcutClicked: { name: "shortcutClicked", argsDecoder: shortcutClickedDataDecoder, resultDecoder: voidResultDecoder }, + }; + const OPERATIONS = { + ping: { name: "ping", resultDecoder: pingResultDecoder }, + isWindowInWorkspace: { name: "isWindowInWorkspace", argsDecoder: simpleItemConfigDecoder, resultDecoder: isWindowInSwimlaneResultDecoder }, + createWorkspace: { name: "createWorkspace", resultDecoder: workspaceSnapshotResultDecoder, argsDecoder: workspaceCreateConfigDecoder }, + createFrame: { name: "createFrame", resultDecoder: frameSummaryResultDecoder, argsDecoder: emptyFrameDefinitionDecoder }, + initFrame: { name: "initFrame", resultDecoder: voidResultDecoder, argsDecoder: frameInitProtocolConfigDecoder }, + getAllFramesSummaries: { name: "getAllFramesSummaries", resultDecoder: frameSummariesResultDecoder }, + getFrameSummary: { name: "getFrameSummary", resultDecoder: frameSummaryDecoder, argsDecoder: getFrameSummaryConfigDecoder }, + getAllWorkspacesSummaries: { name: "getAllWorkspacesSummaries", resultDecoder: workspaceSummariesResultDecoder }, + getWorkspaceSnapshot: { name: "getWorkspaceSnapshot", resultDecoder: workspaceSnapshotResultDecoder, argsDecoder: simpleItemConfigDecoder }, + getAllLayoutsSummaries: { name: "getAllLayoutsSummaries", resultDecoder: layoutSummariesDecoder }, + openWorkspace: { name: "openWorkspace", argsDecoder: openWorkspaceConfigDecoder, resultDecoder: workspaceSnapshotResultDecoder }, + deleteLayout: { name: "deleteLayout", resultDecoder: voidResultDecoder, argsDecoder: deleteLayoutConfigDecoder }, + saveLayout: { name: "saveLayout", resultDecoder: workspaceLayoutDecoder, argsDecoder: workspaceLayoutSaveConfigDecoder }, + importLayout: { name: "importLayout", resultDecoder: voidResultDecoder, argsDecoder: workspacesImportLayoutDecoder }, + importLayouts: { name: "importLayouts", resultDecoder: voidResultDecoder, argsDecoder: workspacesImportLayoutsDecoder }, + exportAllLayouts: { name: "exportAllLayouts", resultDecoder: exportedLayoutsResultDecoder }, + restoreItem: { name: "restoreItem", argsDecoder: simpleItemConfigDecoder, resultDecoder: voidResultDecoder }, + maximizeItem: { name: "maximizeItem", argsDecoder: simpleItemConfigDecoder, resultDecoder: voidResultDecoder }, + focusItem: { name: "focusItem", argsDecoder: simpleItemConfigDecoder, resultDecoder: voidResultDecoder }, + closeItem: { name: "closeItem", argsDecoder: simpleItemConfigDecoder, resultDecoder: voidResultDecoder }, + resizeItem: { name: "resizeItem", argsDecoder: resizeItemConfigDecoder, resultDecoder: voidResultDecoder }, + setMaximizationBoundary: { name: "setMaximizationBoundary", argsDecoder: setMaximizationBoundaryConfigDecoder, resultDecoder: voidResultDecoder }, + changeFrameState: { name: "changeFrameState", argsDecoder: frameStateConfigDecoder, resultDecoder: voidResultDecoder }, + getFrameState: { name: "getFrameState", argsDecoder: simpleItemConfigDecoder, resultDecoder: frameStateResultDecoder }, + getFrameBounds: { name: "getFrameBounds", argsDecoder: simpleItemConfigDecoder, resultDecoder: frameBoundsResultDecoder }, + moveFrame: { name: "moveFrame", argsDecoder: moveFrameConfigDecoder, resultDecoder: voidResultDecoder }, + getFrameSnapshot: { name: "getFrameSnapshot", argsDecoder: frameSnapshotConfigDecoder, resultDecoder: frameSnapshotResultDecoder }, + forceLoadWindow: { name: "forceLoadWindow", argsDecoder: simpleItemConfigDecoder, resultDecoder: simpleWindowOperationSuccessResultDecoder }, + ejectWindow: { name: "ejectWindow", argsDecoder: simpleItemConfigDecoder, resultDecoder: simpleWindowOperationSuccessResultDecoder }, + setItemTitle: { name: "setItemTitle", argsDecoder: setItemTitleConfigDecoder, resultDecoder: voidResultDecoder }, + moveWindowTo: { name: "moveWindowTo", argsDecoder: moveWindowConfigDecoder, resultDecoder: voidResultDecoder }, + addWindow: { name: "addWindow", argsDecoder: addWindowConfigDecoder, resultDecoder: addItemResultDecoder }, + addContainer: { name: "addContainer", argsDecoder: addContainerConfigDecoder, resultDecoder: addItemResultDecoder }, + bundleWorkspace: { name: "bundleWorkspace", argsDecoder: bundleWorkspaceConfigDecoder, resultDecoder: voidResultDecoder }, + bundleItem: { name: "bundleItem", argsDecoder: bundleItemConfigDecoder, resultDecoder: voidResultDecoder }, + hibernateWorkspace: { name: "hibernateWorkspace", argsDecoder: workspaceSelectorDecoder, resultDecoder: voidResultDecoder }, + resumeWorkspace: { name: "resumeWorkspace", argsDecoder: workspaceSelectorDecoder, resultDecoder: voidResultDecoder }, + lockWorkspace: { name: "lockWorkspace", argsDecoder: lockWorkspaceDecoder, resultDecoder: voidResultDecoder }, + lockWindow: { name: "lockWindow", argsDecoder: lockWindowDecoder, resultDecoder: voidResultDecoder }, + lockContainer: { name: "lockContainer", argsDecoder: lockContainerDecoder, resultDecoder: voidResultDecoder }, + pinWorkspace: { name: "pinWorkspace", argsDecoder: pinWorkspaceDecoder, resultDecoder: voidResultDecoder }, + unpinWorkspace: { name: "unpinWorkspace", argsDecoder: workspaceSelectorDecoder, resultDecoder: voidResultDecoder }, + getWorkspaceIcon: { name: "getWorkspaceIcon", argsDecoder: workspaceSelectorDecoder, resultDecoder: getWorkspaceIconResultDecoder }, + setWorkspaceIcon: { name: "setWorkspaceIcon", argsDecoder: setWorkspaceIconDecoder, resultDecoder: voidResultDecoder }, + registerShortcut: { name: "registerShortcut", argsDecoder: shortcutConfigDecoder, resultDecoder: voidResultDecoder }, + unregisterShortcut: { name: "unregisterShortcut", argsDecoder: shortcutConfigDecoder, resultDecoder: voidResultDecoder }, + showLoadingAnimation: { name: "showLoadingAnimation", argsDecoder: loadingAnimationConfigDecoder, resultDecoder: voidResultDecoder }, + hideLoadingAnimation: { name: "hideLoadingAnimation", argsDecoder: loadingAnimationConfigDecoder, resultDecoder: voidResultDecoder }, + getPlatformFrameId: { name: "getPlatformFrameId", resultDecoder: getPlatformFrameIdResultDecoder }, + operationCheck: { name: "operationCheck", argsDecoder: operationCheckConfigDecoder, resultDecoder: operationCheckResultDecoder }, + setWindowDragMode: { name: "setWindowDragMode", argsDecoder: setWindowDragModeDecoder, resultDecoder: voidResultDecoder }, + setLoadingStrategy: { name: "setLoadingStrategy", argsDecoder: setLoadingStrategyDecoder, resultDecoder: voidResultDecoder } + }; + + class PromiseWrapper { + resolve; + reject; + promise; + constructor() { + this.promise = new Promise((res, rej) => { + this.resolve = res; + this.reject = rej; + }); + } + } + + class Bridge { + transport; + registry; + activeSubscriptions = []; + pendingSubScriptions = []; + constructor(transport, registry) { + this.transport = transport; + this.registry = registry; + } + async createCoreEventSubscription() { + await this.transport.coreSubscriptionReady(this.handleCoreEvent.bind(this)); + } + handleCoreSubscription(config) { + const registryKey = `${config.eventType}-${config.action}`; + const scope = config.scope; + const scopeId = config.scopeId; + return this.registry.add(registryKey, (args) => { + const scopeConfig = { + type: scope, + id: scopeId + }; + const receivedIds = { + frame: args.frameSummary?.id || args.windowSummary?.config.frameId, + workspace: args.workspaceSummary?.id || args.windowSummary?.config.workspaceId, + container: args.containerSummary?.itemId, + window: args.windowSummary?.itemId + }; + const shouldInvokeCallback = this.checkScopeMatch(scopeConfig, receivedIds); + if (!shouldInvokeCallback) { + return; + } + config.callback(args); + }); + } + async send(operationName, operationArgs) { + const operationDefinition = Object.values(OPERATIONS).find((operation) => operation.name === operationName); + if (!operationDefinition) { + throw new Error(`Cannot find definition for operation name: ${operationName}`); + } + if (operationDefinition.argsDecoder) { + try { + operationDefinition.argsDecoder.runWithException(operationArgs); + } + catch (error) { + throw new Error(`Unexpected internal outgoing validation error: ${error.message}, for input: ${JSON.stringify(error.input)}, for operation ${operationName}`); + } + } + try { + const operationResult = await this.transport.transmitControl(operationDefinition.name, operationArgs); + operationDefinition.resultDecoder.runWithException(operationResult); + return operationResult; + } + catch (error) { + if (error.kind) { + throw new Error(`Unexpected internal incoming validation error: ${error.message}, for input: ${JSON.stringify(error.input)}, for operation ${operationName}`); + } + throw new Error(error.message); + } + } + async subscribe(config) { + const pendingSub = this.getPendingSubscription(config); + if (pendingSub) { + await pendingSub.promise; + } + let activeSub = this.getActiveSubscription(config); + const registryKey = this.getRegistryKey(config); + if (!activeSub) { + const pendingPromise = new PromiseWrapper(); + const pendingSubscription = { + streamType: config.eventType, + level: config.scope, + levelId: config.scopeId, + promise: pendingPromise.promise + }; + this.pendingSubScriptions.push(pendingSubscription); + try { + const stream = STREAMS[config.eventType]; + const gdSub = await this.transport.subscribe(stream.name, this.getBranchKey(config), config.eventType); + gdSub.onData((streamData) => { + const data = streamData.data; + const requestedArgumentsResult = streamRequestArgumentsDecoder.run(streamData.requestArguments); + const actionResult = workspaceEventActionDecoder.run(data.action); + if (!requestedArgumentsResult.ok || !actionResult.ok) { + return; + } + const streamType = requestedArgumentsResult.result.type; + const branch = requestedArgumentsResult.result.branch; + const keyToExecute = `${streamType}-${branch}-${actionResult.result}`; + const validatedPayload = STREAMS[streamType].payloadDecoder.run(data.payload); + if (!validatedPayload.ok) { + return; + } + this.registry.execute(keyToExecute, validatedPayload.result); + }); + activeSub = { + streamType: config.eventType, + level: config.scope, + levelId: config.scopeId, + callbacksCount: 0, + gdSub + }; + this.activeSubscriptions.push(activeSub); + pendingPromise.resolve(); + } + catch (error) { + pendingPromise.reject(error); + throw error; + } + finally { + this.removePendingSubscription(pendingSubscription); + } + } + const unsubscribe = this.registry.add(registryKey, config.callback); + ++activeSub.callbacksCount; + return () => { + unsubscribe(); + --activeSub.callbacksCount; + if (activeSub.callbacksCount === 0) { + activeSub.gdSub.close(); + this.activeSubscriptions.splice(this.activeSubscriptions.indexOf(activeSub), 1); + } + }; + } + onOperation(callback) { + const wrappedCallback = (payload, caller) => { + const operationName = payload.operation; + const operationArgs = payload.data; + const operationDefinition = Object.values(CLIENT_OPERATIONS).find((operation) => operation.name === operationName); + if (!operationDefinition) { + throw new Error(`Cannot find definition for operation name: ${operationName}`); + } + if (operationDefinition.argsDecoder) { + try { + operationDefinition.argsDecoder.runWithException(operationArgs); + } + catch (error) { + throw new Error(`Unexpected internal outgoing validation error: ${error.message}, for input: ${JSON.stringify(error.input)}, for operation ${operationName}`); + } + } + callback(payload, caller); + }; + return this.transport.onInternalMethodInvoked("control", wrappedCallback); + } + checkScopeMatch(scope, receivedIds) { + if (scope.type === "global") { + return true; + } + if (scope.type === "frame" && scope.id === receivedIds.frame) { + return true; + } + if (scope.type === "workspace" && scope.id === receivedIds.workspace) { + return true; + } + if (scope.type === "container" && scope.id === receivedIds.container) { + return true; + } + if (scope.type === "window" && scope.id === receivedIds.window) { + return true; + } + return false; + } + handleCoreEvent(args) { + const data = args.data; + try { + const verifiedAction = workspaceEventActionDecoder.runWithException(data.action); + const verifiedType = eventTypeDecoder.runWithException(data.type); + const verifiedPayload = STREAMS[verifiedType].payloadDecoder.runWithException(data.payload); + const registryKey = `${verifiedType}-${verifiedAction}`; + this.registry.execute(registryKey, verifiedPayload); + } + catch (error) { + console.warn(`Cannot handle event with data ${JSON.stringify(data)}, because of validation error: ${error.message}`); + } + } + getBranchKey(config) { + return config.scope === "global" ? config.scope : `${config.scope}_${config.scopeId}`; + } + getRegistryKey(config) { + return `${config.eventType}-${this.getBranchKey(config)}-${config.action}`; + } + getActiveSubscription(config) { + return this.activeSubscriptions + .find((activeSub) => activeSub.streamType === config.eventType && + activeSub.level === config.scope && + activeSub.levelId === config.scopeId); + } + getPendingSubscription(config) { + return this.pendingSubScriptions + .find((activeSub) => activeSub.streamType === config.eventType && + activeSub.level === config.scope && + activeSub.levelId === config.scopeId); + } + removePendingSubscription(pendingSubscription) { + const index = this.pendingSubScriptions.indexOf(pendingSubscription); + if (index >= 0) { + this.pendingSubScriptions.splice(index, 1); + } + } + } + + const promisePlus = (promise, timeoutMilliseconds, timeoutMessage) => { + return new Promise((resolve, reject) => { + let promiseActive = true; + const timeout = setTimeout(() => { + if (!promiseActive) { + return; + } + promiseActive = false; + const message = timeoutMessage; + reject(message); + }, timeoutMilliseconds); + promise() + .then((result) => { + if (!promiseActive) { + return; + } + promiseActive = false; + clearTimeout(timeout); + resolve(result); + }) + .catch((error) => { + if (!promiseActive) { + return; + } + promiseActive = false; + clearTimeout(timeout); + reject(error); + }); + }); + }; + + const isDesktop = () => { + return typeof window === "undefined" ? + true : + window.glue42gd || window.iodesktop; + }; + const browserGlobal = () => { + return typeof window === "undefined" ? null : + window.glue42core || window.iobrowser; + }; + + class InteropTransport { + agm; + registry; + defaultTransportTimeout = 120000; + coreEventMethodInitiated = false; + corePlatformSubPromise; + constructor(agm, registry) { + this.agm = agm; + this.registry = registry; + } + async initiate(actualWindowId) { + if (isDesktop()) { + await Promise.all(Object.values(OUTGOING_METHODS).map((method) => { + return this.verifyMethodLive(method.name); + })); + await Promise.all(Object.keys(INCOMING_METHODS).map((method) => { + return this.registerMethod(method); + })); + return; + } + const systemId = browserGlobal().communicationId; + await Promise.all([ + this.verifyMethodLive(webPlatformMethodName, systemId), + this.verifyMethodLive(webPlatformWspStreamName, systemId) + ]); + await this.transmitControl("frameHello", { windowId: actualWindowId }); + } + coreSubscriptionReady(eventCallback) { + if (!this.coreEventMethodInitiated) { + this.subscribePlatform(eventCallback); + } + return this.corePlatformSubPromise; + } + subscribePlatform(eventCallback) { + this.coreEventMethodInitiated = true; + const systemId = browserGlobal().communicationId; + this.corePlatformSubPromise = this.agm.subscribe(webPlatformWspStreamName, systemId ? { target: { instance: systemId } } : undefined); + this.corePlatformSubPromise + .then((sub) => { + sub.onData((data) => eventCallback(data.data)); + }); + } + async subscribe(streamName, streamBranch, streamType) { + const subscriptionArgs = { + branch: streamBranch, + type: streamType + }; + let subscription; + try { + subscription = await this.agm.subscribe(streamName, { arguments: subscriptionArgs }); + } + catch (error) { + const message = `Internal subscription error! Error details: stream - ${streamName}, branch: ${streamBranch}. Internal message: ${error.message}`; + throw new Error(message); + } + return subscription; + } + async transmitControl(operation, operationArguments) { + const invocationArguments = isDesktop() ? { operation, operationArguments } : { operation, domain: "workspaces", data: operationArguments }; + const methodName = isDesktop() ? OUTGOING_METHODS.control.name : webPlatformMethodName; + const platformTarget = isDesktop() ? undefined : browserGlobal().communicationId; + let invocationResult; + const baseErrorMessage = `Internal Workspaces Communication Error. Attempted operation: ${JSON.stringify(invocationArguments)}. `; + try { + invocationResult = await this.agm.invoke(methodName, invocationArguments, platformTarget ? { instance: platformTarget } : "best", { methodResponseTimeoutMs: this.defaultTransportTimeout }); + if (!invocationResult) { + throw new Error("Received unsupported result from GD - empty result"); + } + if (!Array.isArray(invocationResult.all_return_values) || invocationResult.all_return_values.length === 0) { + throw new Error("Received unsupported result from GD - empty values collection"); + } + } + catch (error) { + if (error && error.all_errors && error.all_errors.length) { + const invocationErrorMessage = error.all_errors[0].message; + throw new Error(`${baseErrorMessage} -> Inner message: ${invocationErrorMessage}`); + } + throw new Error(`${baseErrorMessage} -> Inner message: ${error.message}`); + } + return invocationResult.all_return_values[0].returned; + } + onInternalMethodInvoked(key, callback) { + return this.registry.add(key, callback); + } + verifyMethodLive(name, systemId) { + return promisePlus(() => { + return new Promise((resolve) => { + const hasMethod = this.agm.methods().some((method) => { + const nameMatch = method.name === name; + const serverMatch = systemId ? + method.getServers().some((server) => server.instance === systemId) : + true; + return nameMatch && serverMatch; + }); + if (hasMethod) { + resolve(); + return; + } + const unSub = this.agm.serverMethodAdded((data) => { + const method = data.method; + const server = data.server; + const serverMatch = systemId ? + server.instance === systemId : + true; + if (method.name === name && serverMatch) { + unSub(); + resolve(); + } + }); + }); + }, 15000, "Timeout waiting for the Workspaces communication channels"); + } + registerMethod(key) { + const method = INCOMING_METHODS[key]; + return this.agm.register(method.name, (args, caller) => { + this.registry.execute(key, args, caller); + }); + } + } + + const privateData$4 = new WeakMap(); + class ParentBuilder { + constructor(definition, base) { + const children = base.wrapChildren(definition.children); + delete definition.children; + privateData$4.set(this, { base, children, definition }); + } + get type() { + return privateData$4.get(this).definition.type; + } + addColumn(definition) { + const base = privateData$4.get(this).base; + return base.add("column", privateData$4.get(this).children, definition); + } + addRow(definition) { + const base = privateData$4.get(this).base; + return base.add("row", privateData$4.get(this).children, definition); + } + addGroup(definition) { + const base = privateData$4.get(this).base; + return base.add("group", privateData$4.get(this).children, definition); + } + addWindow(definition) { + const base = privateData$4.get(this).base; + base.addWindow(privateData$4.get(this).children, definition); + return this; + } + serialize() { + const definition = privateData$4.get(this).definition; + definition.children = privateData$4.get(this).base.serializeChildren(privateData$4.get(this).children); + return definition; + } + } + + class BaseBuilder { + getBuilder; + constructor(getBuilder) { + this.getBuilder = getBuilder; + } + wrapChildren(children) { + return children.map((child) => { + if (child.type === "window") { + return child; + } + return this.getBuilder({ type: child.type, definition: child }); + }); + } + add(type, children, definition) { + const validatedDefinition = parentDefinitionDecoder.runWithException(definition); + const childBuilder = this.getBuilder({ type, definition: validatedDefinition }); + children.push(childBuilder); + return childBuilder; + } + addWindow(children, definition) { + const validatedDefinition = swimlaneWindowDefinitionDecoder.runWithException(definition); + validatedDefinition.type = "window"; + children.push(validatedDefinition); + } + serializeChildren(children) { + return children.map((child) => { + if (child instanceof ParentBuilder) { + return child.serialize(); + } + else { + return child; + } + }); + } + } + + const privateData$3 = new WeakMap(); + class WorkspaceBuilder { + constructor(definition, base, controller) { + const children = base.wrapChildren(definition.children); + delete definition.children; + privateData$3.set(this, { base, children, definition, controller }); + } + addColumn(definition) { + const children = privateData$3.get(this).children; + const areAllColumns = children.every((child) => child instanceof ParentBuilder && child.type === "column"); + if (!areAllColumns) { + throw new Error("Cannot add a column to this workspace, because there are already children of another type"); + } + const base = privateData$3.get(this).base; + return base.add("column", children, definition); + } + addRow(definition) { + const children = privateData$3.get(this).children; + const areAllRows = children.every((child) => child instanceof ParentBuilder && child.type === "row"); + if (!areAllRows) { + throw new Error("Cannot add a row to this workspace, because there are already children of another type"); + } + const base = privateData$3.get(this).base; + return base.add("row", children, definition); + } + addGroup(definition) { + const children = privateData$3.get(this).children; + if (children.length !== 0) { + throw new Error("Cannot add a group to this workspace, because there are already defined children."); + } + const base = privateData$3.get(this).base; + return base.add("group", children, definition); + } + addWindow(definition) { + const children = privateData$3.get(this).children; + if (children.length !== 0) { + throw new Error("Cannot add a window to this workspace, because there are already defined children."); + } + const base = privateData$3.get(this).base; + base.addWindow(children, definition); + return this; + } + getChildAt(index) { + nonNegativeNumberDecoder.runWithException(index); + const data = privateData$3.get(this).children; + return data[index]; + } + async create(config) { + const saveConfig = workspaceBuilderCreateConfigDecoder.runWithException(config); + const definition = privateData$3.get(this).definition; + definition.children = privateData$3.get(this).base.serializeChildren(privateData$3.get(this).children); + const controller = privateData$3.get(this).controller; + return controller.createWorkspace(definition, saveConfig); + } + } + + const privateData$2 = new WeakMap(); + const getBase$2 = (model) => { + return privateData$2.get(model).base; + }; + class Row { + constructor(base) { + privateData$2.set(this, { base }); + } + get type() { + return "row"; + } + get id() { + return getBase$2(this).getId(this); + } + get frameId() { + return getBase$2(this).getFrameId(this); + } + get workspaceId() { + return getBase$2(this).getWorkspaceId(this); + } + get positionIndex() { + return getBase$2(this).getPositionIndex(this); + } + get children() { + return getBase$2(this).getAllChildren(this); + } + get parent() { + return getBase$2(this).getMyParent(this); + } + get frame() { + return getBase$2(this).getMyFrame(this); + } + get workspace() { + return getBase$2(this).getMyWorkspace(this); + } + get allowDrop() { + return getBase$2(this).getAllowDrop(this); + } + get allowSplitters() { + return getBase$2(this).getAllowSplitters(this); + } + get minWidth() { + return getBase$2(this).getMinWidth(this); + } + get minHeight() { + return getBase$2(this).getMinHeight(this); + } + get maxWidth() { + return getBase$2(this).getMaxWidth(this); + } + get maxHeight() { + return getBase$2(this).getMaxHeight(this); + } + get width() { + return getBase$2(this).getWidthInPx(this); + } + get height() { + return getBase$2(this).getHeightInPx(this); + } + get isPinned() { + return getBase$2(this).getIsPinned(this); + } + get isMaximized() { + return getBase$2(this).getIsMaximized(this); + } + get maximizationBoundary() { + return getBase$2(this).getMaximizationBoundary(this); + } + addWindow(definition) { + return getBase$2(this).addWindow(this, definition, "row"); + } + async addGroup(definition) { + if (definition?.type && definition.type !== "group") { + throw new Error(`Expected a group definition, but received ${definition.type}`); + } + return getBase$2(this).addParent(this, "group", "row", definition); + } + async addColumn(definition) { + if (definition?.type && definition.type !== "column") { + throw new Error(`Expected a column definition, but received ${definition.type}`); + } + return getBase$2(this).addParent(this, "column", "row", definition); + } + async addRow() { + throw new Error("Adding rows as row children is not supported"); + } + removeChild(predicate) { + return getBase$2(this).removeChild(this, predicate); + } + maximize() { + return getBase$2(this).maximize(this); + } + restore() { + return getBase$2(this).restore(this); + } + close() { + return getBase$2(this).close(this); + } + lock(config) { + let lockConfigResult = undefined; + if (typeof config === "function") { + const currentLockConfig = { + allowDrop: this.allowDrop, + allowSplitters: this.allowSplitters + }; + lockConfigResult = config(currentLockConfig); + } + else { + lockConfigResult = config; + } + const verifiedConfig = lockConfigResult === undefined ? undefined : rowLockConfigDecoder.runWithException(lockConfigResult); + return getBase$2(this).lockContainer(this, verifiedConfig); + } + async setHeight(height) { + nonNegativeNumberDecoder.runWithException(height); + return getBase$2(this).setHeight(this, height); + } + async onLockConfigurationChanged(callback) { + checkThrowCallback(callback); + const wrappedCallback = async () => { + await this.workspace.refreshReference(); + callback({ + allowDrop: this.allowDrop, + allowSplitters: this.allowSplitters + }); + }; + const config = { + callback: wrappedCallback, + action: "lock-configuration-changed", + eventType: "container", + scope: "container" + }; + const unsubscribe = await getBase$2(this).processLocalSubscription(this, config); + return unsubscribe; + } + async setMaximizationBoundary(config) { + const validatedConfig = setMaximizationBoundaryAPIConfigDecoder.runWithException(config); + return getBase$2(this).setMaximizationBoundary(this, validatedConfig); + } + } + + const privateData$1 = new WeakMap(); + const getBase$1 = (model) => { + return privateData$1.get(model).base; + }; + class Column { + constructor(base) { + privateData$1.set(this, { base }); + } + get type() { + return "column"; + } + get id() { + return getBase$1(this).getId(this); + } + get frameId() { + return getBase$1(this).getFrameId(this); + } + get workspaceId() { + return getBase$1(this).getWorkspaceId(this); + } + get positionIndex() { + return getBase$1(this).getPositionIndex(this); + } + get children() { + return getBase$1(this).getAllChildren(this); + } + get parent() { + return getBase$1(this).getMyParent(this); + } + get frame() { + return getBase$1(this).getMyFrame(this); + } + get workspace() { + return getBase$1(this).getMyWorkspace(this); + } + get allowDrop() { + return getBase$1(this).getAllowDrop(this); + } + get allowSplitters() { + return getBase$1(this).getAllowSplitters(this); + } + get minWidth() { + return getBase$1(this).getMinWidth(this); + } + get minHeight() { + return getBase$1(this).getMinHeight(this); + } + get maxWidth() { + return getBase$1(this).getMaxWidth(this); + } + get maxHeight() { + return getBase$1(this).getMaxHeight(this); + } + get width() { + return getBase$1(this).getWidthInPx(this); + } + get height() { + return getBase$1(this).getHeightInPx(this); + } + get isPinned() { + return getBase$1(this).getIsPinned(this); + } + get isMaximized() { + return getBase$1(this).getIsMaximized(this); + } + get maximizationBoundary() { + return getBase$1(this).getMaximizationBoundary(this); + } + addWindow(definition) { + return getBase$1(this).addWindow(this, definition, "column"); + } + async addGroup(definition) { + if (definition?.type && definition.type !== "group") { + throw new Error(`Expected a group definition, but received ${definition.type}`); + } + return getBase$1(this).addParent(this, "group", "column", definition); + } + async addColumn() { + throw new Error("Adding columns as column children is not supported"); + } + async addRow(definition) { + if (definition?.type && definition.type !== "row") { + throw new Error(`Expected a row definition, but received ${definition.type}`); + } + return getBase$1(this).addParent(this, "row", "column", definition); + } + removeChild(predicate) { + return getBase$1(this).removeChild(this, predicate); + } + maximize() { + return getBase$1(this).maximize(this); + } + restore() { + return getBase$1(this).restore(this); + } + close() { + return getBase$1(this).close(this); + } + lock(config) { + let lockConfigResult = undefined; + if (typeof config === "function") { + const currentLockConfig = { + allowDrop: this.allowDrop, + allowSplitters: this.allowSplitters + }; + lockConfigResult = config(currentLockConfig); + } + else { + lockConfigResult = config; + } + const verifiedConfig = lockConfigResult === undefined ? undefined : columnLockConfigDecoder.runWithException(lockConfigResult); + return getBase$1(this).lockContainer(this, verifiedConfig); + } + async setWidth(width) { + nonNegativeNumberDecoder.runWithException(width); + return getBase$1(this).setWidth(this, width); + } + async onLockConfigurationChanged(callback) { + checkThrowCallback(callback); + const wrappedCallback = async () => { + await this.workspace.refreshReference(); + callback({ + allowDrop: this.allowDrop, + allowSplitters: this.allowSplitters + }); + }; + const config = { + callback: wrappedCallback, + action: "lock-configuration-changed", + eventType: "container", + scope: "container" + }; + const unsubscribe = await getBase$1(this).processLocalSubscription(this, config); + return unsubscribe; + } + async setMaximizationBoundary(config) { + const validatedConfig = setMaximizationBoundaryAPIConfigDecoder.runWithException(config); + return getBase$1(this).setMaximizationBoundary(this, validatedConfig); + } + } + + const privateData = new WeakMap(); + const getBase = (model) => { + return privateData.get(model).base; + }; + class Group { + constructor(base) { + privateData.set(this, { base }); + } + get type() { + return "group"; + } + get id() { + return getBase(this).getId(this); + } + get frameId() { + return getBase(this).getFrameId(this); + } + get workspaceId() { + return getBase(this).getWorkspaceId(this); + } + get positionIndex() { + return getBase(this).getPositionIndex(this); + } + get children() { + return getBase(this).getAllChildren(this); + } + get parent() { + return getBase(this).getMyParent(this); + } + get frame() { + return getBase(this).getMyFrame(this); + } + get workspace() { + return getBase(this).getMyWorkspace(this); + } + get allowExtract() { + return getBase(this).getAllowExtract(this); + } + get allowReorder() { + return getBase(this).getAllowReorder(this); + } + get allowDropLeft() { + return getBase(this).getAllowDropLeft(this); + } + get allowDropRight() { + return getBase(this).getAllowDropRight(this); + } + get allowDropTop() { + return getBase(this).getAllowDropTop(this); + } + get allowDropBottom() { + return getBase(this).getAllowDropBottom(this); + } + get allowDropHeader() { + return getBase(this).getAllowDropHeader(this); + } + get allowDrop() { + return getBase(this).getAllowDrop(this); + } + get showMaximizeButton() { + return getBase(this).getShowMaximizeButton(this); + } + get showEjectButton() { + return getBase(this).getShowEjectButton(this); + } + get showAddWindowButton() { + return getBase(this).getShowAddWindowButton(this); + } + get minWidth() { + return getBase(this).getMinWidth(this); + } + get minHeight() { + return getBase(this).getMinHeight(this); + } + get maxWidth() { + return getBase(this).getMaxWidth(this); + } + get maxHeight() { + return getBase(this).getMaxHeight(this); + } + get width() { + return getBase(this).getWidthInPx(this); + } + get height() { + return getBase(this).getHeightInPx(this); + } + get isMaximized() { + return getBase(this).getIsMaximized(this); + } + addWindow(definition) { + return getBase(this).addWindow(this, definition, "group"); + } + async addGroup() { + throw new Error("Adding groups as group child is not supported"); + } + async addColumn() { + throw new Error("Adding columns as group child is not supported"); + } + async addRow() { + throw new Error("Adding rows as group child is not supported"); + } + removeChild(predicate) { + return getBase(this).removeChild(this, predicate); + } + maximize() { + return getBase(this).maximize(this); + } + restore() { + return getBase(this).restore(this); + } + close() { + return getBase(this).close(this); + } + lock(config) { + let lockConfigResult = undefined; + if (typeof config === "function") { + const currentLockConfig = { + allowDrop: this.allowDrop, + allowDropHeader: this.allowDropHeader, + allowDropLeft: this.allowDropLeft, + allowDropRight: this.allowDropRight, + allowDropTop: this.allowDropTop, + allowDropBottom: this.allowDropBottom, + allowExtract: this.allowExtract, + allowReorder: this.allowReorder, + showAddWindowButton: this.showAddWindowButton, + showEjectButton: this.showEjectButton, + showMaximizeButton: this.showMaximizeButton + }; + lockConfigResult = config(currentLockConfig); + } + else { + lockConfigResult = config; + } + const verifiedConfig = lockConfigResult === undefined ? undefined : groupLockConfigDecoder.runWithException(lockConfigResult); + return getBase(this).lockContainer(this, verifiedConfig); + } + async setSize(config) { + const verifiedConfig = elementResizeConfigDecoder.runWithException(config); + if (!verifiedConfig.width && !verifiedConfig.height) { + throw new Error("Expected either width or height to be passed."); + } + return getBase(this).setSize(this, config.width, config.height); + } + async bundleToRow() { + await getBase(this).bundleTo(this, "row"); + await this.workspace.refreshReference(); + } + async bundleToColumn() { + await getBase(this).bundleTo(this, "column"); + await this.workspace.refreshReference(); + } + async onLockConfigurationChanged(callback) { + checkThrowCallback(callback); + const wrappedCallback = async () => { + await this.workspace.refreshReference(); + callback({ + allowDrop: this.allowDrop, + allowDropHeader: this.allowDropHeader, + allowDropLeft: this.allowDropLeft, + allowDropTop: this.allowDropTop, + allowDropRight: this.allowDropRight, + allowDropBottom: this.allowDropBottom, + allowExtract: this.allowExtract, + allowReorder: this.allowReorder, + showAddWindowButton: this.showAddWindowButton, + showEjectButton: this.showEjectButton, + showMaximizeButton: this.showMaximizeButton + }); + }; + const config = { + callback: wrappedCallback, + action: "lock-configuration-changed", + eventType: "container", + scope: "container" + }; + const unsubscribe = await getBase(this).processLocalSubscription(this, config); + return unsubscribe; + } + } + + const DEFAULT_WINDOW_DRAG_MODE = "keepInside"; + + const data$3 = new WeakMap(); + const getData$3 = (model) => { + return data$3.get(model).manager.getWorkspaceData(model); + }; + const getDataManager = (model) => { + return data$3.get(model).manager; + }; + class Workspace { + constructor(dataManager) { + data$3.set(this, { manager: dataManager }); + } + get id() { + return getData$3(this).id; + } + get frameId() { + return getData$3(this).config.frameId; + } + get positionIndex() { + return getData$3(this).config.positionIndex; + } + get title() { + return getData$3(this).config.title; + } + get layoutName() { + return getData$3(this).config.layoutName; + } + get isHibernated() { + return getData$3(this).config.isHibernated; + } + get isSelected() { + return getData$3(this).config.isSelected; + } + get children() { + return getData$3(this).children; + } + get frame() { + return getData$3(this).frame; + } + get allowSplitters() { + return getData$3(this).config.allowSplitters; + } + get allowSystemHibernation() { + return getData$3(this).config.allowSystemHibernation; + } + get allowDrop() { + return getData$3(this).config.allowDrop; + } + get allowDropLeft() { + return getData$3(this).config.allowDropLeft; + } + get allowDropTop() { + return getData$3(this).config.allowDropTop; + } + get allowDropRight() { + return getData$3(this).config.allowDropRight; + } + get allowDropBottom() { + return getData$3(this).config.allowDropBottom; + } + get allowExtract() { + return getData$3(this).config.allowExtract; + } + get allowWindowReorder() { + return getData$3(this).config.allowWindowReorder; + } + get showCloseButton() { + return getData$3(this).config.showCloseButton; + } + get showSaveButton() { + return getData$3(this).config.showSaveButton; + } + get allowWorkspaceTabReorder() { + return getData$3(this).config.allowWorkspaceTabReorder; + } + get allowWorkspaceTabExtract() { + return getData$3(this).config.allowWorkspaceTabExtract; + } + get minWidth() { + return getData$3(this).config.minWidth; + } + get minHeight() { + return getData$3(this).config.minHeight; + } + get maxWidth() { + return getData$3(this).config.maxWidth; + } + get maxHeight() { + return getData$3(this).config.maxHeight; + } + get width() { + return getData$3(this).config.widthInPx; + } + get height() { + return getData$3(this).config.heightInPx; + } + get showWindowCloseButtons() { + return getData$3(this).config.showWindowCloseButtons; + } + get showEjectButtons() { + return getData$3(this).config.showEjectButtons; + } + get showAddWindowButtons() { + return getData$3(this).config.showAddWindowButtons; + } + get isPinned() { + return getData$3(this).config.isPinned; + } + get windowDragMode() { + const desktopGlobal = isDesktop(); + if (!desktopGlobal) { + return DEFAULT_WINDOW_DRAG_MODE; + } + return getData$3(this).config.windowDragMode; + } + get loadingStrategy() { + if (!isDesktop()) { + console.warn("The workspace.loadingStrategy property is not supported in IO Connect Browser"); + } + return getData$3(this).config.loadingStrategy; + } + async setLoadingStrategy(strategy) { + if (!isDesktop()) { + throw new Error("Not supported in IO Connect Browser"); + } + const controller = getData$3(this).controller; + await controller.setLoadingStrategy(this.id, strategy); + await this.refreshReference(); + } + async removeChild(predicate) { + checkThrowCallback(predicate); + const child = this.children.find(predicate); + if (!child) { + return; + } + await child.close(); + await this.refreshReference(); + } + async remove(predicate) { + checkThrowCallback(predicate); + const controller = getData$3(this).controller; + const child = controller.iterateFindChild(this.children, predicate); + await child.close(); + await this.refreshReference(); + } + async focus() { + await getData$3(this).controller.focusItem(this.id); + await this.refreshReference(); + } + async close() { + const controller = getData$3(this).controller; + const workspaces = await getData$3(this).frame.workspaces(); + const platformFrameId = (await controller.getPlatformFrameId()).id; + const shouldCloseFrame = workspaces.length === 1 && + workspaces.every((wsp) => wsp.id === this.id) && + platformFrameId !== this.frame.id; + if (shouldCloseFrame) { + return this.frame.close(); + } + await controller.closeItem(this.id); + } + snapshot() { + return getData$3(this).controller.getSnapshot(this.id, "workspace"); + } + async saveLayout(name, config) { + nonEmptyStringDecoder.runWithException(name); + await getData$3(this).controller.saveLayout({ name, workspaceId: this.id, saveContext: config?.saveContext, metadata: config?.metadata, allowMultiple: config?.allowMultiple }); + } + async setTitle(title) { + nonEmptyStringDecoder.runWithException(title); + const controller = getData$3(this).controller; + await controller.setItemTitle(this.id, title); + await this.refreshReference(); + } + getContext() { + const controller = getData$3(this).controller; + return controller.getWorkspaceContext(this.id); + } + setContext(data) { + const controller = getData$3(this).controller; + return controller.setWorkspaceContext(this.id, data); + } + updateContext(data) { + const controller = getData$3(this).controller; + return controller.updateWorkspaceContext(this.id, data); + } + onContextUpdated(callback) { + const controller = getData$3(this).controller; + return controller.subscribeWorkspaceContextUpdated(this.id, callback); + } + async refreshReference() { + const newSnapshot = (await getData$3(this).controller.getSnapshot(this.id, "workspace")); + const currentChildrenFlat = getData$3(this).controller.flatChildren(getData$3(this).children); + const newChildren = getData$3(this).controller.refreshChildren({ + existingChildren: currentChildrenFlat, + workspace: this, + parent: this, + children: newSnapshot.children + }); + const currentFrame = this.frame; + let actualFrame; + if (currentFrame.id === newSnapshot.config.frameId) { + getDataManager(this).remapFrame(currentFrame, newSnapshot.frameSummary); + actualFrame = currentFrame; + } + else { + const frameCreateConfig = { + summary: newSnapshot.frameSummary + }; + const newFrame = getData$3(this).ioc.getModel("frame", frameCreateConfig); + actualFrame = newFrame; + } + getDataManager(this).remapWorkspace(this, { + config: newSnapshot.config, + children: newChildren, + frame: actualFrame + }); + } + async getIcon() { + const controller = getData$3(this).controller; + return controller.getWorkspaceIcon(this.id); + } + async setIcon(icon) { + const controller = getData$3(this).controller; + return controller.setWorkspaceIcon(this.id, icon); + } + getBox(predicate) { + checkThrowCallback(predicate); + const children = getData$3(this).children; + const controller = getData$3(this).controller; + return controller.iterateFindChild(children, (child) => child.type !== "window" && predicate(child)); + } + getAllBoxes(predicate) { + checkThrowCallback(predicate, true); + const children = getData$3(this).children; + const controller = getData$3(this).controller; + const allParents = controller.iterateFilterChildren(children, (child) => child.type !== "window"); + if (!predicate) { + return allParents; + } + return allParents.filter(predicate); + } + getRow(predicate) { + checkThrowCallback(predicate); + return this.getBox((parent) => parent.type === "row" && predicate(parent)); + } + getAllRows(predicate) { + checkThrowCallback(predicate, true); + if (predicate) { + return this.getAllBoxes((parent) => parent.type === "row" && predicate(parent)); + } + return this.getAllBoxes((parent) => parent.type === "row"); + } + getColumn(predicate) { + checkThrowCallback(predicate); + return this.getBox((parent) => parent.type === "column" && predicate(parent)); + } + getAllColumns(predicate) { + checkThrowCallback(predicate, true); + if (predicate) { + return this.getAllBoxes((parent) => parent.type === "column" && predicate(parent)); + } + return this.getAllBoxes((parent) => parent.type === "column"); + } + getGroup(predicate) { + checkThrowCallback(predicate); + return this.getBox((parent) => parent.type === "group" && predicate(parent)); + } + getAllGroups(predicate) { + checkThrowCallback(predicate, true); + if (predicate) { + return this.getAllBoxes((parent) => parent.type === "group" && predicate(parent)); + } + return this.getAllBoxes((parent) => parent.type === "group"); + } + getWindow(predicate) { + checkThrowCallback(predicate); + const children = getData$3(this).children; + const controller = getData$3(this).controller; + return controller.iterateFindChild(children, (child) => child.type === "window" && predicate(child)); + } + getAllWindows(predicate) { + checkThrowCallback(predicate, true); + const children = getData$3(this).children; + const controller = getData$3(this).controller; + const allWindows = controller.iterateFilterChildren(children, (child) => child.type === "window"); + if (!predicate) { + return allWindows; + } + return allWindows.filter(predicate); + } + addRow(definition) { + return getData$3(this).base.addParent(this, "row", "workspace", definition); + } + addColumn(definition) { + return getData$3(this).base.addParent(this, "column", "workspace", definition); + } + addGroup(definition) { + return getData$3(this).base.addParent(this, "group", "workspace", definition); + } + addWindow(definition) { + return getData$3(this).base.addWindow(this, definition, "workspace"); + } + async bundleToRow() { + await getData$3(this).controller.bundleWorkspaceTo("row", this.id); + await this.refreshReference(); + } + async bundleToColumn() { + await getData$3(this).controller.bundleWorkspaceTo("column", this.id); + await this.refreshReference(); + } + async hibernate() { + await getData$3(this).controller.hibernateWorkspace(this.id); + await this.refreshReference(); + } + async resume() { + await getData$3(this).controller.resumeWorkspace(this.id); + await this.refreshReference(); + } + async lock(config) { + let lockConfigResult = undefined; + if (typeof config === "function") { + const currentLockConfig = { + allowDrop: this.allowDrop, + allowDropLeft: this.allowDropLeft, + allowDropTop: this.allowDropTop, + allowDropRight: this.allowDropRight, + allowDropBottom: this.allowDropBottom, + allowSystemHibernation: this.allowSystemHibernation, + allowExtract: this.allowExtract, + allowWindowReorder: this.allowWindowReorder, + allowSplitters: this.allowSplitters, + showCloseButton: this.showCloseButton, + showSaveButton: this.showSaveButton, + allowWorkspaceTabReorder: this.allowWorkspaceTabReorder, + allowWorkspaceTabExtract: this.allowWorkspaceTabExtract, + showAddWindowButtons: this.showAddWindowButtons, + showEjectButtons: this.showEjectButtons, + showWindowCloseButtons: this.showWindowCloseButtons + }; + lockConfigResult = config(currentLockConfig); + } + else { + lockConfigResult = config; + } + const verifiedConfig = lockConfigResult === undefined ? undefined : workspaceLockConfigDecoder.runWithException(lockConfigResult); + await getData$3(this).controller.lockWorkspace(this.id, verifiedConfig); + await this.refreshReference(); + } + async pin(options) { + workspacePinOptionsDecoder.runWithException(options); + await getData$3(this).controller.pinWorkspace(this.id, options?.icon); + await this.refreshReference(); + } + async unpin() { + await getData$3(this).controller.unpinWorkspace(this.id); + await this.refreshReference(); + } + async showLoadingAnimation() { + if (!isDesktop()) { + throw new Error("Not supported in IO Connect Browser"); + } + await getData$3(this).controller.showWorkspaceLoadingAnimation(this.id); + } + async hideLoadingAnimation() { + if (!isDesktop()) { + throw new Error("Not supported in IO Connect Browser"); + } + await getData$3(this).controller.hideWorkspaceLoadingAnimation(this.id); + } + async setWindowDragMode(mode) { + const desktopGlobal = isDesktop(); + if (!desktopGlobal) { + throw new Error("Not supported in IO Connect Browser"); + } + windowDragModeDecoder.runWithException(mode); + await getData$3(this).controller.setWindowDragMode(this.id, mode); + await this.refreshReference(); + } + async onClosed(callback) { + checkThrowCallback(callback); + const id = getData$3(this).id; + const wrappedCallback = async (payload) => { + callback({ frameId: payload.frameSummary.id, workspaceId: payload.workspaceSummary.id, frameBounds: payload.frameBounds }); + }; + const config = { + action: "closed", + eventType: "workspace", + scope: "workspace", + scopeId: id, + callback: wrappedCallback + }; + const unsubscribe = await getData$3(this).controller.processLocalSubscription(config, id); + return unsubscribe; + } + async onHibernated(callback) { + checkThrowCallback(callback); + const id = getData$3(this).id; + const wrappedCallback = async () => { + await this.refreshReference(); + callback(); + }; + const config = { + action: "hibernated", + eventType: "workspace", + scope: "workspace", + scopeId: id, + callback: wrappedCallback + }; + const unsubscribe = await getData$3(this).controller.processLocalSubscription(config, id); + return unsubscribe; + } + async onResumed(callback) { + checkThrowCallback(callback); + const id = getData$3(this).id; + const wrappedCallback = async () => { + await this.refreshReference(); + callback(); + }; + const config = { + action: "resumed", + eventType: "workspace", + scope: "workspace", + scopeId: id, + callback: wrappedCallback + }; + const unsubscribe = await getData$3(this).controller.processLocalSubscription(config, id); + return unsubscribe; + } + async onWindowAdded(callback) { + checkThrowCallback(callback); + const id = getData$3(this).id; + const wrappedCallback = async (payload) => { + await this.refreshReference(); + const windowParent = this.getBox((parent) => parent.id === payload.windowSummary.parentId); + const foundWindow = windowParent.children.find((child) => { + return child.type === "window" && child.elementId === payload.windowSummary.itemId; + }); + callback(foundWindow); + }; + const config = { + action: "added", + eventType: "window", + scope: "workspace", + scopeId: id, + callback: wrappedCallback + }; + const unsubscribe = await getData$3(this).controller.processLocalSubscription(config, id); + return unsubscribe; + } + async onWindowRemoved(callback) { + checkThrowCallback(callback); + const id = getData$3(this).id; + const wrappedCallback = async (payload) => { + await this.refreshReference(); + const { windowId, workspaceId, frameId } = payload.windowSummary.config; + callback({ windowId, workspaceId, frameId }); + }; + const config = { + action: "removed", + eventType: "window", + scope: "workspace", + scopeId: id, + callback: wrappedCallback + }; + const unsubscribe = await getData$3(this).controller.processLocalSubscription(config, id); + return unsubscribe; + } + async onWindowLoaded(callback) { + checkThrowCallback(callback); + const id = getData$3(this).id; + const wrappedCallback = async (payload) => { + await this.refreshReference(); + const foundWindow = this.getWindow((win) => { + return win.id && win.id === payload.windowSummary.config.windowId; + }); + callback(foundWindow); + }; + const config = { + action: "loaded", + eventType: "window", + scope: "workspace", + scopeId: id, + callback: wrappedCallback + }; + const unsubscribe = await getData$3(this).controller.processLocalSubscription(config, id); + return unsubscribe; + } + async onWindowMaximized(callback) { + checkThrowCallback(callback); + const id = getData$3(this).id; + const wrappedCallback = async (payload) => { + await this.refreshReference(); + const windowParent = this.getBox((parent) => parent.id === payload.windowSummary.parentId); + const foundWindow = windowParent.children.find((child) => { + return child.type === "window" && child.elementId === payload.windowSummary.itemId; + }); + callback(foundWindow); + }; + const config = { + action: "maximized", + eventType: "window", + scope: "workspace", + scopeId: id, + callback: wrappedCallback + }; + const unsubscribe = await getData$3(this).controller.processLocalSubscription(config, id); + return unsubscribe; + } + async onWindowRestored(callback) { + checkThrowCallback(callback); + const id = getData$3(this).id; + const wrappedCallback = async (payload) => { + await this.refreshReference(); + const windowParent = this.getBox((parent) => parent.id === payload.windowSummary.parentId); + const foundWindow = windowParent.children.find((child) => { + return child.type === "window" && child.elementId === payload.windowSummary.itemId; + }); + callback(foundWindow); + }; + const config = { + action: "restored", + eventType: "window", + scope: "workspace", + scopeId: id, + callback: wrappedCallback + }; + const unsubscribe = await getData$3(this).controller.processLocalSubscription(config, id); + return unsubscribe; + } + async onWindowSelected(callback) { + checkThrowCallback(callback); + const id = getData$3(this).id; + const wrappedCallback = async (payload) => { + await this.refreshReference(); + const windowParent = this.getBox((parent) => parent.id === payload.windowSummary.parentId); + const foundWindow = windowParent.children.find((child) => { + return child.type === "window" && child.elementId === payload.windowSummary.itemId; + }); + callback(foundWindow); + }; + const config = { + action: "selected", + eventType: "window", + scope: "workspace", + scopeId: id, + callback: wrappedCallback + }; + const unsubscribe = await getData$3(this).controller.processLocalSubscription(config, id); + return unsubscribe; + } + async onLockConfigurationChanged(callback) { + checkThrowCallback(callback); + const id = getData$3(this).id; + const wrappedCallback = async () => { + await this.refreshReference(); + callback({ + allowDrop: this.allowDrop, + allowDropLeft: this.allowDropLeft, + allowDropTop: this.allowDropTop, + allowDropRight: this.allowDropRight, + allowDropBottom: this.allowDropBottom, + allowSystemHibernation: this.allowSystemHibernation, + allowExtract: this.allowExtract, + allowSplitters: this.allowSplitters, + allowWindowReorder: this.allowWindowReorder, + allowWorkspaceTabExtract: this.allowWorkspaceTabExtract, + allowWorkspaceTabReorder: this.allowWorkspaceTabReorder, + showAddWindowButtons: this.showAddWindowButtons, + showCloseButton: this.showCloseButton, + showEjectButtons: this.showEjectButtons, + showSaveButton: this.showSaveButton, + showWindowCloseButtons: this.showWindowCloseButtons + }); + }; + const config = { + action: "lock-configuration-changed", + eventType: "workspace", + scope: "workspace", + scopeId: id, + callback: wrappedCallback + }; + const unsubscribe = await getData$3(this).controller.processLocalSubscription(config, id); + return unsubscribe; + } + } + + const data$2 = new WeakMap(); + const getData$2 = (model) => { + return data$2.get(model).manager.getWindowData(model); + }; + class Window { + constructor(dataManager) { + data$2.set(this, { manager: dataManager }); + } + get id() { + return getData$2(this).config.windowId; + } + get elementId() { + return getData$2(this).id; + } + get type() { + return "window"; + } + get frameId() { + return getData$2(this).frame.id; + } + get workspaceId() { + return getData$2(this).workspace.id; + } + get positionIndex() { + return getData$2(this).config.positionIndex; + } + get isMaximized() { + return getData$2(this).config.isMaximized; + } + get isLoaded() { + return getData$2(this).controller.checkIsWindowLoaded(this.id); + } + get isSelected() { + return getData$2(this).config.isSelected; + } + get focused() { + return this.getGdWindow().isFocused; + } + get title() { + return getData$2(this).config.title; + } + get allowExtract() { + return getData$2(this).config.allowExtract; + } + get allowReorder() { + return getData$2(this).config.allowReorder; + } + get showCloseButton() { + return getData$2(this).config.showCloseButton; + } + get width() { + return getData$2(this).config.widthInPx; + } + get height() { + return getData$2(this).config.heightInPx; + } + get minWidth() { + return getData$2(this).config.minWidth; + } + get minHeight() { + return getData$2(this).config.minHeight; + } + get maxWidth() { + return getData$2(this).config.maxWidth; + } + get maxHeight() { + return getData$2(this).config.maxHeight; + } + get workspace() { + return getData$2(this).workspace; + } + get frame() { + return getData$2(this).frame; + } + get parent() { + return getData$2(this).parent; + } + get appName() { + return getData$2(this).config.appName; + } + async forceLoad() { + if (this.isLoaded) { + return; + } + const controller = getData$2(this).controller; + const itemId = getData$2(this).id; + const windowId = await controller.forceLoadWindow(itemId); + getData$2(this).config.windowId = windowId; + await this.workspace.refreshReference(); + } + async focus() { + const id = getData$2(this).id; + const controller = getData$2(this).controller; + await controller.focusItem(id); + await this.workspace.refreshReference(); + } + async close() { + const id = getData$2(this).id; + const controller = getData$2(this).controller; + await controller.closeItem(id); + await getData$2(this) + .parent + .removeChild((child) => child.id === id); + await this.workspace.refreshReference(); + } + async setTitle(title) { + nonEmptyStringDecoder.runWithException(title); + const itemId = getData$2(this).id; + const controller = getData$2(this).controller; + await controller.setItemTitle(itemId, title); + await this.workspace.refreshReference(); + } + async maximize() { + const id = getData$2(this).id; + const controller = getData$2(this).controller; + await controller.maximizeItem(id); + await this.workspace.refreshReference(); + } + async restore() { + const id = getData$2(this).id; + const controller = getData$2(this).controller; + await controller.restoreItem(id); + await this.workspace.refreshReference(); + } + async eject() { + if (!this.isLoaded) { + throw new Error("Cannot eject this window, because it is not loaded yet"); + } + const itemId = getData$2(this).id; + const newWindowId = await getData$2(this).controller.ejectWindow(itemId); + getData$2(this).config.windowId = newWindowId; + await this.workspace.refreshReference(); + return this.getGdWindow(); + } + getGdWindow() { + if (!this.isLoaded) { + throw new Error("Cannot fetch this GD window, because the window is not yet loaded"); + } + const myId = getData$2(this).config.windowId; + const controller = getData$2(this).controller; + return controller.getGDWindow(myId); + } + async moveTo(parent) { + if (!(parent instanceof Row || parent instanceof Column || parent instanceof Group)) { + throw new Error("Cannot add to the provided parent, because the provided parent is not an instance of Row, Column or Group"); + } + const myId = getData$2(this).id; + const controller = getData$2(this).controller; + const foundParent = await controller.getParent((p) => p.id === parent.id); + if (!foundParent) { + throw new Error("Cannot move the window to the selected parent, because this parent does not exist."); + } + await controller.moveWindowTo(myId, parent.id); + await this.workspace.refreshReference(); + } + async lock(config) { + let lockConfigResult = undefined; + if (typeof config === "function") { + const currentLockConfig = { + allowExtract: this.allowExtract, + allowReorder: this.allowReorder, + showCloseButton: this.showCloseButton + }; + lockConfigResult = config(currentLockConfig); + } + else { + lockConfigResult = config; + } + const verifiedConfig = lockConfigResult === undefined ? undefined : windowLockConfigDecoder.runWithException(lockConfigResult); + const windowPlacementId = getData$2(this).id; + await getData$2(this).controller.lockWindow(windowPlacementId, verifiedConfig); + await this.workspace.refreshReference(); + } + async setSize(config) { + const verifiedConfig = elementResizeConfigDecoder.runWithException(config); + if (!verifiedConfig.width && !verifiedConfig.height) { + throw new Error("Expected either width or height to be passed."); + } + const myId = getData$2(this).id; + const controller = getData$2(this).controller; + await controller.resizeItem(myId, { + height: verifiedConfig.height, + width: verifiedConfig.width, + relative: false + }); + await this.workspace.refreshReference(); + } + async onRemoved(callback) { + checkThrowCallback(callback); + const id = getData$2(this).id; + const wrappedCallback = async () => { + await this.workspace.refreshReference(); + callback(); + }; + const config = { + callback: wrappedCallback, + action: "removed", + eventType: "window", + scope: "window" + }; + const unsubscribe = await getData$2(this).controller.processLocalSubscription(config, id); + return unsubscribe; + } + async onLockConfigurationChanged(callback) { + checkThrowCallback(callback); + const id = getData$2(this).id; + const wrappedCallback = async () => { + await this.workspace.refreshReference(); + callback({ + allowExtract: this.allowExtract, + allowReorder: this.allowReorder, + showCloseButton: this.showCloseButton + }); + }; + const config = { + callback: wrappedCallback, + action: "lock-configuration-changed", + eventType: "window", + scope: "window" + }; + const unsubscribe = await getData$2(this).controller.processLocalSubscription(config, id); + return unsubscribe; + } + } + + const data$1 = new WeakMap(); + const getData$1 = (model) => { + return data$1.get(model).manager.getFrameData(model); + }; + class Frame { + constructor(dataManager) { + data$1.set(this, { manager: dataManager }); + } + async registerShortcut(shortcut, callback) { + nonEmptyStringDecoder.runWithException(shortcut); + checkThrowCallback(callback); + const myId = getData$1(this).summary.id; + const unsubscribe = await getData$1(this).controller.registerShortcut(shortcut, myId, callback); + return unsubscribe; + } + get id() { + return getData$1(this).summary.id; + } + get isInitialized() { + return getData$1(this).summary.isInitialized; + } + getBounds() { + const myId = getData$1(this).summary.id; + return getData$1(this).controller.getFrameBounds(myId); + } + async resize(config) { + const validatedConfig = resizeConfigDecoder.runWithException(config); + const myId = getData$1(this).summary.id; + return getData$1(this).controller.resizeItem(myId, validatedConfig); + } + async move(config) { + const validatedConfig = moveConfigDecoder.runWithException(config); + const myId = getData$1(this).summary.id; + return getData$1(this).controller.moveFrame(myId, validatedConfig); + } + focus() { + const myId = getData$1(this).summary.id; + return getData$1(this).controller.focusItem(myId); + } + async state() { + if (!isDesktop()) { + throw new Error("State operations are not supported in IO Connect Browser"); + } + const myId = getData$1(this).summary.id; + return getData$1(this).controller.getFrameState(myId); + } + async minimize() { + if (!isDesktop()) { + throw new Error("State operations are not supported in IO Connect Browser"); + } + const myId = getData$1(this).summary.id; + return getData$1(this).controller.changeFrameState(myId, "minimized"); + } + async maximize() { + if (!isDesktop()) { + throw new Error("State operations are not supported in IO Connect Browser"); + } + const myId = getData$1(this).summary.id; + return getData$1(this).controller.changeFrameState(myId, "maximized"); + } + async restore() { + if (!isDesktop()) { + throw new Error("State operations are not supported in IO Connect Browser"); + } + const myId = getData$1(this).summary.id; + return getData$1(this).controller.changeFrameState(myId, "normal"); + } + close() { + const myId = getData$1(this).summary.id; + return getData$1(this).controller.closeItem(myId); + } + snapshot() { + const myId = getData$1(this).summary.id; + return getData$1(this).controller.getSnapshot(myId, "frame"); + } + async workspaces() { + const controller = getData$1(this).controller; + return controller.getWorkspacesByFrameId(this.id); + } + async getConstraints() { + const controller = getData$1(this).controller; + const myId = getData$1(this).summary.id; + return controller.getFrameConstraints(myId); + } + async restoreWorkspace(name, options) { + nonEmptyStringDecoder.runWithException(name); + const validatedOptions = restoreWorkspaceConfigDecoder.runWithException(options); + return getData$1(this).controller.restoreWorkspace(name, validatedOptions); + } + createWorkspace(definition, config) { + const validatedDefinition = workspaceDefinitionDecoder.runWithException(definition); + const validatedConfig = workspaceBuilderCreateConfigDecoder.runWithException(config); + return getData$1(this).controller.createWorkspace(validatedDefinition, validatedConfig); + } + async init(config) { + frameInitConfigDecoder.runWithException(config); + if (getData$1(this).summary.isInitialized) { + throw new Error("The frame has already been initialized"); + } + return getData$1(this).controller.initFrame(this.id, config); + } + async onClosed(callback) { + checkThrowCallback(callback); + const myId = getData$1(this).summary.id; + const wrappedCallback = (payload) => { + callback({ frameId: payload.frameSummary.id, frameBounds: payload.frameBounds }); + }; + const config = { + callback: wrappedCallback, + action: "closed", + eventType: "frame", + scope: "frame" + }; + const unsubscribe = await getData$1(this).controller.processLocalSubscription(config, myId); + return unsubscribe; + } + async onMaximized(callback) { + checkThrowCallback(callback); + const myId = getData$1(this).summary.id; + const wrappedCallback = () => { + callback(); + }; + const config = { + callback: wrappedCallback, + action: "maximized", + eventType: "frame", + scope: "frame" + }; + const unsubscribe = await getData$1(this).controller.processLocalSubscription(config, myId); + return unsubscribe; + } + async onMinimized(callback) { + checkThrowCallback(callback); + const myId = getData$1(this).summary.id; + const wrappedCallback = () => { + callback(); + }; + const config = { + callback: wrappedCallback, + action: "minimized", + eventType: "frame", + scope: "frame" + }; + const unsubscribe = await getData$1(this).controller.processLocalSubscription(config, myId); + return unsubscribe; + } + async onNormal(callback) { + checkThrowCallback(callback); + const myId = getData$1(this).summary.id; + const wrappedCallback = () => { + callback(); + }; + const config = { + callback: wrappedCallback, + action: "normal", + eventType: "frame", + scope: "frame" + }; + const unsubscribe = await getData$1(this).controller.processLocalSubscription(config, myId); + return unsubscribe; + } + async onWorkspaceOpened(callback) { + checkThrowCallback(callback); + const myId = getData$1(this).summary.id; + const wrappedCallback = async (payload) => { + const workspace = await getData$1(this).controller.transformStreamPayloadToWorkspace(payload); + callback(workspace); + }; + const config = { + callback: wrappedCallback, + action: "opened", + eventType: "workspace", + scope: "frame" + }; + const unsubscribe = await getData$1(this).controller.processLocalSubscription(config, myId); + return unsubscribe; + } + async onWorkspaceSelected(callback) { + checkThrowCallback(callback); + const myId = getData$1(this).summary.id; + const wrappedCallback = async (payload) => { + const workspace = await getData$1(this).controller.getWorkspaceById(payload.workspaceSummary.id); + callback(workspace); + }; + const config = { + callback: wrappedCallback, + action: "selected", + eventType: "workspace", + scope: "frame" + }; + const unsubscribe = await getData$1(this).controller.processLocalSubscription(config, myId); + return unsubscribe; + } + async onWorkspaceClosed(callback) { + checkThrowCallback(callback); + const myId = getData$1(this).summary.id; + const wrappedCallback = (payload) => { + callback({ frameId: payload.frameSummary.id, workspaceId: payload.workspaceSummary.id, frameBounds: payload.frameBounds }); + }; + const config = { + callback: wrappedCallback, + action: "closed", + eventType: "workspace", + scope: "frame" + }; + const unsubscribe = await getData$1(this).controller.processLocalSubscription(config, myId); + return unsubscribe; + } + async onWindowAdded(callback) { + checkThrowCallback(callback); + const myId = getData$1(this).summary.id; + const wrappedCallback = async (payload) => { + const foundParent = await getData$1(this).controller.getParent((parent) => parent.id === payload.windowSummary.parentId); + const foundWindow = foundParent.children.find((child) => child.type === "window" && child.positionIndex === payload.windowSummary.config.positionIndex); + callback(foundWindow); + }; + const config = { + callback: wrappedCallback, + action: "added", + eventType: "window", + scope: "frame" + }; + const unsubscribe = await getData$1(this).controller.processLocalSubscription(config, myId); + return unsubscribe; + } + async onWindowRemoved(callback) { + checkThrowCallback(callback); + const myId = getData$1(this).summary.id; + const wrappedCallback = (payload) => { + const { windowId, workspaceId, frameId } = payload.windowSummary.config; + callback({ windowId, workspaceId, frameId }); + }; + const config = { + callback: wrappedCallback, + action: "removed", + eventType: "window", + scope: "frame" + }; + const unsubscribe = await getData$1(this).controller.processLocalSubscription(config, myId); + return unsubscribe; + } + async onWindowLoaded(callback) { + checkThrowCallback(callback); + const myId = getData$1(this).summary.id; + const wrappedCallback = async (payload) => { + const foundParent = await getData$1(this).controller.getParent((parent) => { + return parent.id === payload.windowSummary.parentId; + }); + const foundWindow = foundParent.children.find((child) => child.type === "window" && child.positionIndex === payload.windowSummary.config.positionIndex); + callback(foundWindow); + }; + const config = { + callback: wrappedCallback, + action: "loaded", + eventType: "window", + scope: "frame" + }; + const unsubscribe = await getData$1(this).controller.processLocalSubscription(config, myId); + return unsubscribe; + } + async onInitializationRequested(callback) { + checkThrowCallback(callback); + if (!this.isInitialized) { + callback(getData$1(this).summary.initializationContext); + } + return () => { }; + } + async onFocusChanged(callback) { + checkThrowCallback(callback); + const myData = getData$1(this); + const { id } = myData.summary; + const wrappedCallback = (args) => { + callback({ isFocused: args.frameSummary.isFocused }); + }; + const config = { + callback: wrappedCallback, + action: "focus", + eventType: "frame", + scope: "frame" + }; + const unsubscribe = await myData.controller.processLocalSubscription(config, id); + return unsubscribe; + } + } + + class PrivateDataManager { + parentsData = new WeakMap(); + workspacesData = new WeakMap(); + windowsData = new WeakMap(); + framesData = new WeakMap(); + deleteData(model) { + if (model instanceof Window) { + this.windowsData.delete(model); + } + if (model instanceof Workspace) { + this.workspacesData.delete(model); + } + if (model instanceof Row || model instanceof Column || model instanceof Group) { + this.parentsData.delete(model); + } + if (model instanceof Frame) { + this.framesData.delete(model); + } + } + setWindowData(model, data) { + this.windowsData.set(model, data); + } + setWorkspaceData(model, data) { + this.workspacesData.set(model, data); + } + setParentData(model, data) { + this.parentsData.set(model, data); + } + setFrameData(model, data) { + this.framesData.set(model, data); + } + getWindowData(model) { + return this.windowsData.get(model); + } + getWorkspaceData(model) { + return this.workspacesData.get(model); + } + getParentData(model) { + return this.parentsData.get(model); + } + getFrameData(model) { + return this.framesData.get(model); + } + remapChild(model, newData) { + if (model instanceof Window) { + const data = this.windowsData.get(model); + data.parent = newData.parent || data.parent; + data.config = newData.config || data.config; + } + if (model instanceof Row || model instanceof Column || model instanceof Group) { + const data = this.parentsData.get(model); + data.parent = newData.parent || data.parent; + data.config = newData.config || data.config; + data.children = newData.children || data.children; + } + } + remapFrame(model, newData) { + const data = this.framesData.get(model); + data.summary = newData; + } + remapWorkspace(model, newData) { + const data = this.workspacesData.get(model); + data.frame = newData.frame || data.frame; + data.config = newData.config || data.config; + data.children = newData.children || data.children; + } + } + + const data = new WeakMap(); + const getData = (base, model) => { + const manager = data.get(base).manager; + if (model instanceof Workspace) { + return manager.getWorkspaceData(model); + } + return data.get(base).manager.getParentData(model); + }; + class Base { + frameId; + workspaceId; + positionIndex; + constructor(dataManager) { + data.set(this, { manager: dataManager }); + } + getId(model) { + return getData(this, model).id; + } + getPositionIndex(model) { + return getData(this, model).config.positionIndex; + } + getWorkspaceId(model) { + const privateData = getData(this, model); + return privateData.config.workspaceId || privateData.workspace.id; + } + getFrameId(model) { + return getData(this, model).frame.id; + } + getAllChildren(model, predicate) { + checkThrowCallback(predicate, true); + const children = getData(this, model).children; + if (typeof predicate === "undefined") { + return children; + } + return children.filter(predicate); + } + getMyParent(model) { + if (model instanceof Workspace) { + return model; + } + return getData(this, model).parent; + } + getMyFrame(model) { + return getData(this, model).frame; + } + getMyWorkspace(model) { + if (model instanceof Workspace) { + return model; + } + return getData(this, model).workspace; + } + async addWindow(model, definition, parentType) { + if (!definition.appName && !definition.windowId) { + throw new Error("The window definition should contain either an appName or a windowId"); + } + const validatedDefinition = swimlaneWindowDefinitionDecoder.runWithException(definition); + const controller = getData(this, model).controller; + const operationResult = await controller.add("window", getData(this, model).id, parentType, validatedDefinition); + if (model instanceof Workspace) { + await model.refreshReference(); + return model.getWindow(w => w.elementId === operationResult.itemId); + } + const myWorkspace = this.getMyWorkspace(model); + await myWorkspace.refreshReference(); + return myWorkspace.getWindow(w => w.elementId === operationResult.itemId); + } + async addParent(model, typeToAdd, parentType, definition) { + const parentDefinition = this.transformDefinition(typeToAdd, definition); + const controller = getData(this, model).controller; + const newParentId = (await controller.add("container", getData(this, model).id, parentType, parentDefinition)).itemId; + if (model instanceof Workspace) { + await model.refreshReference(); + return model.getBox((parent) => parent.id === newParentId); + } + const myWorkspace = this.getMyWorkspace(model); + await myWorkspace.refreshReference(); + return myWorkspace.getBox((parent) => parent.id === newParentId); + } + async removeChild(model, predicate) { + checkThrowCallback(predicate); + const child = this.getAllChildren(model).find(predicate); + if (!child) { + return; + } + await child.close(); + if (model instanceof Workspace) { + await model.refreshReference(); + return; + } + await this.getMyWorkspace(model).refreshReference(); + } + async maximize(model) { + const { controller, id } = getData(this, model); + await controller.maximizeItem(id); + await this.getMyWorkspace(model.parent).refreshReference(); + } + async restore(model) { + const { controller, id } = getData(this, model); + await controller.restoreItem(id); + await this.getMyWorkspace(model.parent).refreshReference(); + } + async close(model) { + const modelData = getData(this, model); + const controller = getData(this, model).controller; + await controller.closeItem(modelData.id); + await this.getMyWorkspace(modelData.parent).refreshReference(); + } + async lockContainer(model, config) { + const modelData = getData(this, model); + const controller = getData(this, model).controller; + await controller.lockContainer(modelData.id, model.type, config); + await this.getMyWorkspace(modelData.parent).refreshReference(); + } + getAllowDrop(model) { + return getData(this, model).config.allowDrop; + } + getAllowDropLeft(model) { + const privateData = getData(this, model); + if (privateData.type !== "group") { + throw new Error(`Property allowDropLeft is available only for groups and not on ${model.type} ${model.id}`); + } + return privateData.config.allowDropLeft; + } + getAllowDropRight(model) { + const privateData = getData(this, model); + if (privateData.type !== "group") { + throw new Error(`Property allowDropRight is available only for groups and not on ${model.type} ${model.id}`); + } + return privateData.config.allowDropRight; + } + getAllowDropTop(model) { + const privateData = getData(this, model); + if (privateData.type !== "group") { + throw new Error(`Property allowDropTop is available only for groups and not on ${model.type} ${model.id}`); + } + return privateData.config.allowDropTop; + } + getAllowDropBottom(model) { + const privateData = getData(this, model); + if (privateData.type !== "group") { + throw new Error(`Property allowDropBottom is available only for groups and not on ${model.type} ${model.id}`); + } + return privateData.config.allowDropBottom; + } + getAllowDropHeader(model) { + const privateData = getData(this, model); + if (privateData.type !== "group") { + throw new Error(`Property allowDropHeader is available only for groups and not on ${model.type} ${model.id}`); + } + return privateData.config.allowDropHeader; + } + getAllowSplitters(model) { + const privateData = getData(this, model); + if (privateData.type === "group") { + throw new Error(`Cannot get allow splitters from private data ${privateData.type}`); + } + return privateData.config.allowSplitters; + } + getAllowExtract(model) { + const privateData = getData(this, model); + if (privateData.type !== "group") { + throw new Error(`Cannot get allow extract from private data ${privateData.type} with config ${privateData.type !== "workspace" ? privateData.config.type : ""}`); + } + return privateData.config.allowExtract; + } + getAllowReorder(model) { + const privateData = getData(this, model); + if (privateData.type !== "group") { + throw new Error(`Cannot get allow extract from private data ${privateData.type} with config ${privateData.type !== "workspace" ? privateData.config.type : ""}`); + } + return privateData.config.allowReorder; + } + getShowMaximizeButton(model) { + const privateData = getData(this, model); + if (privateData.type !== "group") { + throw new Error(`Cannot get show maximize button from private data${privateData.type} with config ${privateData.type !== "workspace" ? privateData.config.type : ""}`); + } + return privateData.config.showMaximizeButton; + } + getShowEjectButton(model) { + const privateData = getData(this, model); + if (privateData.type !== "group") { + throw new Error(`Cannot get show eject button from private data${privateData.type} with config ${privateData.type !== "workspace" ? privateData.config.type : ""}`); + } + return privateData.config.showEjectButton; + } + getShowAddWindowButton(model) { + const privateData = getData(this, model); + if (privateData.type !== "group") { + throw new Error(`Cannot get add window button from private data${privateData.type} with config ${privateData.type !== "workspace" ? privateData.config.type : ""}`); + } + return privateData.config.showAddWindowButton; + } + getMinWidth(model) { + const privateData = getData(this, model); + return privateData.config.minWidth; + } + getMaxWidth(model) { + const privateData = getData(this, model); + return privateData.config.maxWidth; + } + getMinHeight(model) { + const privateData = getData(this, model); + return privateData.config.minHeight; + } + getMaxHeight(model) { + const privateData = getData(this, model); + return privateData.config.maxHeight; + } + getWidthInPx(model) { + const privateData = getData(this, model); + return privateData.config.widthInPx; + } + getHeightInPx(model) { + const privateData = getData(this, model); + return privateData.config.heightInPx; + } + getIsPinned(model) { + const privateData = getData(this, model); + return privateData.config.isPinned; + } + getIsMaximized(model) { + const privateData = getData(this, model); + return privateData.config.isMaximized; + } + getMaximizationBoundary(model) { + const privateData = getData(this, model); + return privateData.config.maximizationBoundary; + } + async setHeight(model, height) { + const modelData = getData(this, model); + const { controller, id } = modelData; + await controller.resizeItem(id, { + height + }); + await this.getMyWorkspace(modelData.parent).refreshReference(); + } + async setWidth(model, width) { + const modelData = getData(this, model); + const { controller, id } = modelData; + await controller.resizeItem(id, { + width + }); + await this.getMyWorkspace(modelData.parent).refreshReference(); + } + async setSize(model, width, height) { + const modelData = getData(this, model); + const { controller, id } = modelData; + await controller.resizeItem(id, { + width, + height + }); + await this.getMyWorkspace(modelData.parent).refreshReference(); + } + async setMaximizationBoundary(model, config) { + const modelData = getData(this, model); + const { controller, id } = modelData; + await controller.setMaximizationBoundary(id, config); + await this.getMyWorkspace(modelData.parent).refreshReference(); + } + async bundleTo(model, type) { + const modelData = getData(this, model); + const { controller, id } = modelData; + await controller.bundleItemTo(type, id); + } + async processLocalSubscription(model, subscriptionConfig) { + return getData(this, model).controller.processLocalSubscription(subscriptionConfig, this.getId(model)); + } + transformDefinition(type, definition) { + let parentDefinition; + if (typeof definition === "undefined") { + parentDefinition = { type, children: [] }; + } + else if (definition instanceof ParentBuilder) { + parentDefinition = definition.serialize(); + } + else { + if (typeof definition.type === "undefined") { + definition.type = type; + } + parentDefinition = strictParentDefinitionDecoder.runWithException(definition); + parentDefinition.children = parentDefinition.children || []; + } + return parentDefinition; + } + } + + class BaseController { + ioc; + windows; + contexts; + layouts; + constructor(ioc, windows, contexts, layouts) { + this.ioc = ioc; + this.windows = windows; + this.contexts = contexts; + this.layouts = layouts; + } + get bridge() { + return this.ioc.bridge; + } + get privateDataManager() { + return this.ioc.privateDataManager; + } + checkIsWindowLoaded(windowId) { + return (!!windowId) && this.windows.list().some((win) => win.id === windowId); + } + async createWorkspace(createConfig) { + const snapshot = await this.bridge.send(OPERATIONS.createWorkspace.name, createConfig); + const frameConfig = { + summary: snapshot.frameSummary + }; + const frame = this.ioc.getModel("frame", frameConfig); + const workspaceConfig = { frame, snapshot }; + return this.ioc.getModel("workspace", workspaceConfig); + } + async createEmptyFrame(definition) { + const frameSummary = await this.bridge.send(OPERATIONS.createFrame.name, definition); + const frameConfig = { + summary: frameSummary + }; + return this.ioc.getModel("frame", frameConfig); + } + async initFrame(frameId, config) { + await this.bridge.send(OPERATIONS.initFrame.name, { frameId, ...config }); + } + async restoreWorkspace(name, options) { + const snapshot = await this.bridge.send(OPERATIONS.openWorkspace.name, { name, restoreOptions: options }); + const frameSummary = await this.bridge.send(OPERATIONS.getFrameSummary.name, { itemId: snapshot.config.frameId }); + const frameConfig = { + summary: frameSummary + }; + const frame = this.ioc.getModel("frame", frameConfig); + const workspaceConfig = { frame, snapshot }; + return this.ioc.getModel("workspace", workspaceConfig); + } + async add(type, parentId, parentType, definition) { + let operationName; + const operationArgs = { definition, parentId, parentType }; + if (type === "window") { + operationName = OPERATIONS.addWindow.name; + } + else if (type === "container") { + operationName = OPERATIONS.addContainer.name; + } + else { + throw new Error(`Unrecognized add type: ${type}`); + } + return await this.bridge.send(operationName, operationArgs); + } + async getFrame(windowId) { + const frameSummary = await this.bridge.send(OPERATIONS.getFrameSummary.name, { itemId: windowId }); + const frameConfig = { + summary: frameSummary + }; + return this.ioc.getModel("frame", frameConfig); + } + getFrames(allFrameSummaries, predicate) { + return allFrameSummaries.reduce((frames, frameSummary) => { + const frameConfig = { + summary: frameSummary + }; + const frameToCheck = this.ioc.getModel("frame", frameConfig); + if (!predicate || predicate(frameToCheck)) { + frames.push(frameToCheck); + } + return frames; + }, []); + } + getAllWorkspaceSummaries(...bridgeResults) { + const allSummaries = bridgeResults.reduce((summaries, summaryResult) => { + summaries.push(...summaryResult.summaries); + return summaries; + }, []); + return allSummaries.map((summary) => { + return Object.assign({}, { id: summary.id, width: summary.config.widthInPx, height: summary.config.heightInPx }, summary.config); + }); + } + handleOnSaved(callback) { + const wrappedCallback = (layout) => { + if (layout.type !== "Workspace") { + return; + } + callback(layout); + }; + const addedUnSub = this.layouts.onAdded(wrappedCallback); + const changedUnSub = this.layouts.onChanged(wrappedCallback); + return () => { + addedUnSub(); + changedUnSub(); + }; + } + handleOnRemoved(callback) { + const wrappedCallback = (layout) => { + if (layout.type !== "Workspace") { + return; + } + callback(layout); + }; + return this.layouts.onRemoved(wrappedCallback); + } + async importLayouts(layouts, mode) { + await this.layouts.import(layouts, mode); + } + async transformStreamPayloadToWorkspace(payload) { + const frameConfig = { + summary: payload.frameSummary + }; + const frame = this.ioc.getModel("frame", frameConfig); + const snapshot = payload.workspaceSnapshot || (await this.bridge.send(OPERATIONS.getWorkspaceSnapshot.name, { itemId: payload.workspaceSummary.id })); + const workspaceConfig = { frame, snapshot }; + const workspace = this.ioc.getModel("workspace", workspaceConfig); + return workspace; + } + async fetchWorkspace(itemId) { + const snapshot = await this.bridge.send(OPERATIONS.getWorkspaceSnapshot.name, { itemId }); + const frameConfig = { + summary: snapshot.frameSummary + }; + const frame = this.ioc.getModel("frame", frameConfig); + const workspaceConfig = { frame, snapshot }; + return this.ioc.getModel("workspace", workspaceConfig); + } + async bundleWorkspaceTo(type, workspaceId) { + await this.bridge.send(OPERATIONS.bundleWorkspace.name, { type, workspaceId }); + } + async bundleItemTo(type, itemId) { + const isSupported = await this.isOperationSupported(OPERATIONS.bundleItem.name); + if (!isSupported) { + throw new Error(`Operation ${OPERATIONS.bundleItem.name} is not supported. Ensure that you are running the latest version of all packages`); + } + await this.bridge.send(OPERATIONS.bundleItem.name, { type, itemId }); + } + getWorkspaceContext(workspaceId) { + const contextName = `___workspace___${workspaceId}`; + return this.contexts.get(contextName); + } + setWorkspaceContext(workspaceId, data) { + const contextName = `___workspace___${workspaceId}`; + return this.contexts.set(contextName, data); + } + updateWorkspaceContext(workspaceId, data) { + const contextName = `___workspace___${workspaceId}`; + return this.contexts.update(contextName, data); + } + subscribeWorkspaceContextUpdated(workspaceId, callback) { + const contextName = `___workspace___${workspaceId}`; + return this.contexts.subscribe(contextName, callback); + } + async restoreItem(itemId) { + await this.bridge.send(OPERATIONS.restoreItem.name, { itemId }); + } + async maximizeItem(itemId) { + await this.bridge.send(OPERATIONS.maximizeItem.name, { itemId }); + } + async focusItem(itemId) { + await this.bridge.send(OPERATIONS.focusItem.name, { itemId }); + } + async closeItem(itemId) { + await this.bridge.send(OPERATIONS.closeItem.name, { itemId }); + } + async resizeItem(itemId, config) { + await this.bridge.send(OPERATIONS.resizeItem.name, Object.assign({}, { itemId }, config)); + } + async setMaximizationBoundary(itemId, config) { + await this.bridge.send(OPERATIONS.setMaximizationBoundary.name, Object.assign({}, { itemId }, config)); + } + async showWorkspaceLoadingAnimation(workspaceId) { + await this.bridge.send(OPERATIONS.showLoadingAnimation.name, { itemId: workspaceId, type: "workspace" }); + } + async hideWorkspaceLoadingAnimation(workspaceId) { + await this.bridge.send(OPERATIONS.hideLoadingAnimation.name, { itemId: workspaceId, type: "workspace" }); + } + async setWindowDragMode(workspaceId, dragMode) { + await this.bridge.send(OPERATIONS.setWindowDragMode.name, { itemId: workspaceId, dragMode }); + } + async moveFrame(itemId, config) { + await this.bridge.send(OPERATIONS.moveFrame.name, Object.assign({}, { itemId }, config)); + } + getGDWindow(itemId) { + return this.windows.list().find((gdWindow) => gdWindow.id === itemId); + } + async forceLoadWindow(itemId) { + const controlResult = await this.bridge.send(OPERATIONS.forceLoadWindow.name, { itemId }); + return controlResult.windowId; + } + async ejectWindow(itemId) { + return await this.bridge.send(OPERATIONS.ejectWindow.name, { itemId }); + } + async moveWindowTo(itemId, newParentId) { + await this.bridge.send(OPERATIONS.moveWindowTo.name, { itemId, containerId: newParentId }); + } + async getSnapshot(itemId, type) { + let result; + if (type === "workspace") { + result = await this.bridge.send(OPERATIONS.getWorkspaceSnapshot.name, { itemId }); + } + else if (type === "frame") { + result = await this.bridge.send(OPERATIONS.getFrameSnapshot.name, { itemId }); + } + return result; + } + async setItemTitle(itemId, title) { + await this.bridge.send(OPERATIONS.setItemTitle.name, { itemId, title }); + } + refreshChildren(config) { + const { parent, children, existingChildren, workspace } = config; + if (parent instanceof Window || parent.type === "window") { + return; + } + const newChildren = children.map((newChildSnapshot) => { + let childToAdd = existingChildren.find((child) => { + return child.type === "window" ? child.elementId === newChildSnapshot.id : child.id === newChildSnapshot.id; + }); + if (childToAdd) { + this.privateDataManager.remapChild(childToAdd, { + parent: parent, + children: [], + config: newChildSnapshot.config + }); + } + else { + let createConfig; + if (newChildSnapshot.type === "window") { + createConfig = { + id: newChildSnapshot.id, + parent: parent, + frame: workspace.frame, + workspace, + config: newChildSnapshot.config, + }; + } + else { + createConfig = { + id: newChildSnapshot.id, + parent: parent, + frame: workspace.frame, + workspace, + config: newChildSnapshot.config, + children: [] + }; + } + childToAdd = this.ioc.getModel(newChildSnapshot.type, createConfig); + } + if (newChildSnapshot.type !== "window") { + this.refreshChildren({ + workspace, existingChildren, + children: newChildSnapshot.children, + parent: childToAdd + }); + } + return childToAdd; + }); + if (parent instanceof Workspace) { + return newChildren; + } + else { + this.privateDataManager.remapChild(parent, { children: newChildren }); + return newChildren; + } + } + iterateFindChild(children, predicate) { + let foundChild = children.find((child) => predicate(child)); + if (foundChild) { + return foundChild; + } + children.some((child) => { + if (child instanceof Window) { + return false; + } + foundChild = this.iterateFindChild(child.children, predicate); + if (foundChild) { + return true; + } + }); + return foundChild; + } + iterateFilterChildren(children, predicate) { + const foundChildren = children.filter((child) => predicate(child)); + const grandChildren = children.reduce((innerFound, child) => { + if (child instanceof Window) { + return innerFound; + } + innerFound.push(...this.iterateFilterChildren(child.children, predicate)); + return innerFound; + }, []); + foundChildren.push(...grandChildren); + return foundChildren; + } + notifyWindowAdded(windowId) { + return new Promise((resolve) => { + const alreadyPresent = this.windows.list().some((win) => win.id === windowId); + if (alreadyPresent) { + return resolve(); + } + const unsubscribe = this.windows.onWindowAdded((win) => { + if (win.id !== windowId) { + return; + } + if (unsubscribe) { + unsubscribe(); + } + resolve(); + }); + }); + } + async hibernateWorkspace(workspaceId) { + await this.bridge.send(OPERATIONS.hibernateWorkspace.name, { workspaceId }); + } + async resumeWorkspace(workspaceId) { + await this.bridge.send(OPERATIONS.resumeWorkspace.name, { workspaceId }); + } + async lockWorkspace(workspaceId, config) { + await this.bridge.send(OPERATIONS.lockWorkspace.name, { workspaceId, config }); + } + async lockWindow(windowPlacementId, config) { + await this.bridge.send(OPERATIONS.lockWindow.name, { windowPlacementId, config }); + } + async lockContainer(itemId, type, config) { + await this.bridge.send(OPERATIONS.lockContainer.name, { itemId, type, config }); + } + async pinWorkspace(workspaceId, icon) { + await this.bridge.send(OPERATIONS.pinWorkspace.name, { workspaceId, icon }); + } + async unpinWorkspace(workspaceId) { + await this.bridge.send(OPERATIONS.unpinWorkspace.name, { workspaceId }); + } + async getWorkspaceIcon(workspaceId) { + const result = await this.bridge.send(OPERATIONS.getWorkspaceIcon.name, { workspaceId }); + return result.icon; + } + setWorkspaceIcon(workspaceId, icon) { + return this.bridge.send(OPERATIONS.setWorkspaceIcon.name, { workspaceId, icon }); + } + async getPlatformFrameId() { + try { + const result = await this.bridge.send(OPERATIONS.getPlatformFrameId.name, {}); + return result; + } + catch (error) { + return {}; + } + } + async setLoadingStrategy(workspaceId, strategy) { + await this.isOperationSupported(OPERATIONS.setLoadingStrategy.name); + return this.bridge.send(OPERATIONS.setLoadingStrategy.name, { itemId: workspaceId, strategy }); + } + async isOperationSupported(operation) { + if (isDesktop()) { + return { isSupported: true }; + } + return await this.bridge.send(OPERATIONS.operationCheck.name, { operation }); + } + } + + class MainController { + bridge; + base; + shortcutsController; + constructor(bridge, base, shortcutsController) { + this.bridge = bridge; + this.base = base; + this.shortcutsController = shortcutsController; + } + checkIsWindowLoaded(windowId) { + return this.base.checkIsWindowLoaded(windowId); + } + async checkIsInSwimlane(windowId) { + const controlResult = await this.bridge.send(OPERATIONS.isWindowInWorkspace.name, { itemId: windowId }); + return controlResult.inWorkspace; + } + async createWorkspace(definition, saveConfig) { + const createConfig = Object.assign({}, definition, { saveConfig }); + return await this.base.createWorkspace(createConfig); + } + async createEmptyFrame(definition) { + return await this.base.createEmptyFrame(definition); + } + async initFrame(frameId, config) { + return this.base.initFrame(frameId, config); + } + async restoreWorkspace(name, options) { + const allLayouts = await this.getLayoutSummaries(); + const layoutExists = allLayouts.some((summary) => summary.name === name); + if (!layoutExists) { + throw new Error(`This layout: ${name} cannot be restored, because it doesn't exist.`); + } + if (options?.frameId) { + const allFrameSummaries = await this.bridge.send(OPERATIONS.getAllFramesSummaries.name); + const foundMatchingFrame = allFrameSummaries.summaries.some((summary) => summary.id === options.frameId); + if (!foundMatchingFrame) { + throw new Error(`Cannot reuse the frame with id: ${options.frameId}, because there is no frame with that ID found`); + } + } + return await this.base.restoreWorkspace(name, options); + } + async add(type, parentId, parentType, definition) { + return await this.base.add(type, parentId, parentType, definition); + } + processLocalSubscription(config, levelId) { + return isDesktop() ? + this.handleEnterpriseLocalSubscription(config, levelId) : + this.handleCoreLocalSubscription(config, levelId); + } + processGlobalSubscription(callback, eventType, action) { + return isDesktop() ? + this.handleEnterpriseGlobalSubscription(callback, eventType, action) : + this.handleCoreGlobalSubscription(callback, eventType, action); + } + async getFrame(selector) { + if (selector.windowId) { + return await this.base.getFrame(selector.windowId); + } + if (selector.predicate) { + return (await this.getFrames(selector.predicate))[0]; + } + throw new Error(`The provided selector is not valid: ${JSON.stringify(selector)}`); + } + async getFrames(predicate) { + const allFrameSummaries = await this.bridge.send(OPERATIONS.getAllFramesSummaries.name); + return this.base.getFrames(allFrameSummaries.summaries, predicate); + } + getWorkspaceById(workspaceId) { + return this.base.fetchWorkspace(workspaceId); + } + async getWorkspaceByWindowId(itemId) { + if (!isDesktop()) { + return (await this.getWorkspaces((wsp) => !!wsp.getWindow((w) => w.id === itemId)))[0]; + } + return this.base.fetchWorkspace(itemId); + } + transformStreamPayloadToWorkspace(payload) { + return this.base.transformStreamPayloadToWorkspace(payload); + } + async getWorkspace(predicate) { + let foundWorkspace; + await this.iterateWorkspaces((wsp, end) => { + if (predicate(wsp)) { + foundWorkspace = wsp; + end(); + } + }); + return foundWorkspace; + } + async getWorkspaces(predicate) { + const matchingWorkspaces = []; + await this.iterateWorkspaces((wsp) => { + if (!predicate || predicate(wsp)) { + matchingWorkspaces.push(wsp); + } + }); + return matchingWorkspaces; + } + async getWorkspacesByFrameId(frameId) { + const workspaceSummaries = await this.getAllWorkspaceSummaries(); + const summariesForFrame = workspaceSummaries.filter((s) => s.frameId === frameId); + const workspacesForFrame = await Promise.all(summariesForFrame.map((summary) => { + return this.base.fetchWorkspace(summary.id); + })); + return workspacesForFrame; + } + async getAllWorkspaceSummaries() { + const allSummariesResult = await this.bridge.send(OPERATIONS.getAllWorkspacesSummaries.name, {}); + return this.base.getAllWorkspaceSummaries(allSummariesResult); + } + async getWindow(predicate) { + let resultWindow; + await this.iterateWorkspaces((wsp, end) => { + const foundWindow = wsp.getWindow(predicate); + if (foundWindow) { + resultWindow = foundWindow; + end(); + } + }); + return resultWindow; + } + async getParent(predicate) { + let resultParent; + await this.iterateWorkspaces((wsp, end) => { + const foundParent = wsp.getBox(predicate); + if (foundParent) { + resultParent = foundParent; + end(); + } + }); + return resultParent; + } + async getLayoutSummaries() { + const allLayouts = await this.bridge.send(OPERATIONS.getAllLayoutsSummaries.name); + return allLayouts.summaries; + } + async deleteLayout(name) { + await this.bridge.send(OPERATIONS.deleteLayout.name, { name }); + } + async exportLayout(predicate) { + const allLayoutsResult = await this.bridge.send(OPERATIONS.exportAllLayouts.name); + return allLayoutsResult.layouts.reduce((matchingLayouts, layout) => { + if (!predicate || predicate(layout)) { + matchingLayouts.push(layout); + } + return matchingLayouts; + }, []); + } + async saveLayout(config) { + return await this.bridge.send(OPERATIONS.saveLayout.name, config); + } + async importLayouts(layouts, mode) { + if (isDesktop()) { + try { + await this.bridge.send(OPERATIONS.importLayouts.name, { layouts, mode }); + } + catch (error) { + await Promise.all(layouts.map((layout) => this.bridge.send(OPERATIONS.importLayout.name, { layout, mode }))); + } + return; + } + await this.base.importLayouts(layouts, mode); + } + handleOnSaved(callback) { + return this.base.handleOnSaved(callback); + } + handleOnRemoved(callback) { + return this.base.handleOnRemoved(callback); + } + async bundleWorkspaceTo(type, workspaceId) { + return await this.base.bundleWorkspaceTo(type, workspaceId); + } + async bundleItemTo(type, id) { + return await this.base.bundleItemTo(type, id); + } + getWorkspaceContext(workspaceId) { + return this.base.getWorkspaceContext(workspaceId); + } + setWorkspaceContext(workspaceId, data) { + return this.base.setWorkspaceContext(workspaceId, data); + } + updateWorkspaceContext(workspaceId, data) { + return this.base.updateWorkspaceContext(workspaceId, data); + } + subscribeWorkspaceContextUpdated(workspaceId, callback) { + return this.base.subscribeWorkspaceContextUpdated(workspaceId, callback); + } + async restoreItem(itemId) { + return await this.base.restoreItem(itemId); + } + async maximizeItem(itemId) { + return await this.base.maximizeItem(itemId); + } + async focusItem(itemId) { + return await this.base.focusItem(itemId); + } + async changeFrameState(frameId, state) { + await this.bridge.send(OPERATIONS.changeFrameState.name, { frameId, requestedState: state }); + } + async getFrameBounds(frameId) { + const frameResult = await this.bridge.send(OPERATIONS.getFrameBounds.name, { itemId: frameId }); + return frameResult.bounds; + } + async getFrameState(frameId) { + const frameResult = await this.bridge.send(OPERATIONS.getFrameState.name, { itemId: frameId }); + return frameResult.state; + } + async closeItem(itemId) { + return await this.base.closeItem(itemId); + } + async resizeItem(itemId, config) { + return await this.base.resizeItem(itemId, config); + } + async setMaximizationBoundary(itemId, config) { + return await this.base.setMaximizationBoundary(itemId, config); + } + async showWorkspaceLoadingAnimation(workspaceId) { + return await this.base.showWorkspaceLoadingAnimation(workspaceId); + } + async hideWorkspaceLoadingAnimation(workspaceId) { + return await this.base.hideWorkspaceLoadingAnimation(workspaceId); + } + async setWindowDragMode(workspaceId, dragMode) { + return await this.base.setWindowDragMode(workspaceId, dragMode); + } + async moveFrame(itemId, config) { + return await this.base.moveFrame(itemId, config); + } + getGDWindow(itemId) { + return this.base.getGDWindow(itemId); + } + async forceLoadWindow(itemId) { + const windowId = await this.base.forceLoadWindow(itemId); + await this.base.notifyWindowAdded(windowId); + return windowId; + } + async ejectWindow(itemId) { + const windowId = (await this.base.ejectWindow(itemId)).windowId; + await this.base.notifyWindowAdded(windowId); + return windowId; + } + async moveWindowTo(itemId, newParentId) { + return await this.base.moveWindowTo(itemId, newParentId); + } + async getSnapshot(itemId, type) { + return await this.base.getSnapshot(itemId, type); + } + async setItemTitle(itemId, title) { + return await this.base.setItemTitle(itemId, title); + } + flatChildren(children) { + return children.reduce((soFar, child) => { + soFar.push(child); + if (child.type !== "window") { + soFar.push(...this.flatChildren(child.children)); + } + return soFar; + }, []); + } + refreshChildren(config) { + return this.base.refreshChildren(config); + } + iterateFindChild(children, predicate) { + return this.base.iterateFindChild(children, predicate); + } + iterateFilterChildren(children, predicate) { + return this.base.iterateFilterChildren(children, predicate); + } + hibernateWorkspace(workspaceId) { + return this.base.hibernateWorkspace(workspaceId); + } + resumeWorkspace(workspaceId) { + return this.base.resumeWorkspace(workspaceId); + } + lockWorkspace(workspaceId, config) { + return this.base.lockWorkspace(workspaceId, config); + } + lockWindow(windowPlacementId, config) { + return this.base.lockWindow(windowPlacementId, config); + } + lockContainer(itemId, type, config) { + return this.base.lockContainer(itemId, type, config); + } + pinWorkspace(workspaceId, icon) { + return this.base.pinWorkspace(workspaceId, icon); + } + unpinWorkspace(workspaceId) { + return this.base.unpinWorkspace(workspaceId); + } + getWorkspaceIcon(workspaceId) { + return this.base.getWorkspaceIcon(workspaceId); + } + setWorkspaceIcon(workspaceId, icon) { + return this.base.setWorkspaceIcon(workspaceId, icon); + } + async getFrameConstraints(frameId) { + const frameSnapshot = await this.getSnapshot(frameId, "frame"); + return { + minWidth: frameSnapshot.config.minWidth, + maxWidth: frameSnapshot.config.maxWidth, + minHeight: frameSnapshot.config.minHeight, + maxHeight: frameSnapshot.config.maxHeight, + }; + } + registerShortcut(shortcut, frameId, callback) { + return this.shortcutsController.registerShortcut(shortcut, frameId, callback); + } + getPlatformFrameId() { + return this.base.getPlatformFrameId(); + } + setLoadingStrategy(workspaceId, strategy) { + return this.base.setLoadingStrategy(workspaceId, strategy); + } + async handleCoreLocalSubscription(config, levelId) { + await this.bridge.createCoreEventSubscription(); + config.scopeId = config.scopeId || levelId; + if (config.eventType === "window" && config.action === "loaded") { + const originalCB = config.callback; + const wrappedCB = async (callbackData) => { + await this.base.notifyWindowAdded(callbackData.windowSummary.config.windowId); + originalCB(callbackData); + }; + config.callback = wrappedCB; + } + return this.bridge.handleCoreSubscription(config); + } + handleEnterpriseLocalSubscription(config, levelId) { + config.scopeId = config.scopeId || levelId; + if (config.eventType === "window" && config.action === "loaded") { + const originalCB = config.callback; + const wrappedCB = async (callbackData) => { + await this.base.notifyWindowAdded(callbackData.windowSummary.config.windowId); + originalCB(callbackData); + }; + config.callback = wrappedCB; + } + return this.bridge.subscribe(config); + } + async handleCoreGlobalSubscription(callback, eventType, action) { + await this.bridge.createCoreEventSubscription(); + const config = { + eventType, callback, action, + scope: "global", + }; + if (eventType === "window" && action === "loaded") { + const wrappedCB = async (callbackData) => { + await this.base.notifyWindowAdded(callbackData.windowSummary.config.windowId); + callback(callbackData); + }; + config.callback = wrappedCB; + } + return this.bridge.handleCoreSubscription(config); + } + handleEnterpriseGlobalSubscription(callback, eventType, action) { + const config = { + eventType, callback, action, + scope: "global", + }; + if (eventType === "window" && action === "loaded") { + const wrappedCB = async (callbackData) => { + await this.base.notifyWindowAdded(callbackData.windowSummary.config.windowId); + callback(callbackData); + }; + config.callback = wrappedCB; + } + return this.bridge.subscribe(config); + } + async iterateWorkspaces(callback) { + let ended = false; + const end = () => { ended = true; }; + const workspaceSummaries = await this.getAllWorkspaceSummaries(); + for (const summary of workspaceSummaries) { + if (ended) { + return; + } + const wsp = await this.base.fetchWorkspace(summary.id); + callback(wsp, end); + } + } + } + + class ShortcutsController { + bridge; + _shortcuts = CallbackFactory(); + constructor(bridge) { + this.bridge = bridge; + this.bridge.onOperation((payload, caller) => { + if (payload.operation === CLIENT_OPERATIONS.shortcutClicked.name) { + const data = payload.data; + this._shortcuts.execute(`${data.frameId}-${data.shortcut}`); + } + }); + } + async registerShortcut(shortcut, frameId, callback) { + await this.bridge.send(OPERATIONS.registerShortcut.name, { shortcut, frameId }); + const un = this._shortcuts.add(`${frameId}-${shortcut}`, callback); + return () => { + un(); + this.bridge.send(OPERATIONS.unregisterShortcut.name, { shortcut, frameId }); + }; + } + } + + class IoC { + agm; + windows; + layouts; + contexts; + _controllerInstance; + _bridgeInstance; + _transportInstance; + _privateDataManagerInstance; + _parentBaseInstance; + _baseController; + _shortcutsController; + constructor(agm, windows, layouts, contexts) { + this.agm = agm; + this.windows = windows; + this.layouts = layouts; + this.contexts = contexts; + } + get baseController() { + if (!this._baseController) { + this._baseController = new BaseController(this, this.windows, this.contexts, this.layouts); + } + return this._baseController; + } + get controller() { + if (!this._controllerInstance) { + this._controllerInstance = new MainController(this.bridge, this.baseController, this.shortcutsController); + } + return this._controllerInstance; + } + get shortcutsController() { + if (!this._shortcutsController) { + this._shortcutsController = new ShortcutsController(this.bridge); + } + return this._shortcutsController; + } + get bridge() { + if (!this._bridgeInstance) { + this._bridgeInstance = new Bridge(this.transport, CallbackFactory()); + } + return this._bridgeInstance; + } + get transport() { + if (!this._transportInstance) { + this._transportInstance = new InteropTransport(this.agm, CallbackFactory()); + } + return this._transportInstance; + } + get privateDataManager() { + if (!this._privateDataManagerInstance) { + this._privateDataManagerInstance = new PrivateDataManager(); + } + return this._privateDataManagerInstance; + } + get parentBase() { + if (!this._parentBaseInstance) { + this._parentBaseInstance = new Base(this.privateDataManager); + } + return this._parentBaseInstance; + } + async initiate(actualWindowId) { + await this.transport.initiate(actualWindowId); + } + getModel(type, createConfig) { + switch (type) { + case "frame": { + const newFrame = new Frame(this.privateDataManager); + const { summary } = createConfig; + const frameData = { summary, controller: this.controller }; + this.privateDataManager.setFrameData(newFrame, frameData); + return newFrame; + } + case "window": { + const { id, parent, frame, workspace, config } = createConfig; + const windowPrivateData = { + type: "window", + controller: this.controller, + config, id, parent, frame, workspace + }; + const newWindow = new Window(this.privateDataManager); + this.privateDataManager.setWindowData(newWindow, windowPrivateData); + return newWindow; + } + case "row": + case "column": + case "group": { + const { id, children, parent, frame, workspace, config } = createConfig; + const newParent = type === "column" ? new Column(this.parentBase) : + type === "row" ? new Row(this.parentBase) : new Group(this.parentBase); + const builtChildren = this.buildChildren(children, frame, workspace, newParent); + const parentPrivateData = { + id, parent, frame, workspace, + config, + type, + controller: this.controller, + children: builtChildren, + }; + this.privateDataManager.setParentData(newParent, parentPrivateData); + return newParent; + } + case "workspace": { + const { snapshot, frame } = createConfig; + const newWorkspace = new Workspace(this.privateDataManager); + const children = this.buildChildren(snapshot.children, frame, newWorkspace, newWorkspace); + const workspacePrivateData = { + id: snapshot.id, + type: "workspace", + config: snapshot.config, + base: this.parentBase, + controller: this.controller, + children, frame, ioc: this + }; + this.privateDataManager.setWorkspaceData(newWorkspace, workspacePrivateData); + return newWorkspace; + } + default: throw new Error(`Unrecognized type: ${type}`); + } + } + getBuilder(config) { + config.definition = config.definition || {}; + if (!Array.isArray(config.definition.children)) { + config.definition.children = []; + } + const baseBuilder = new BaseBuilder(this.getBuilder.bind(this)); + switch (config.type) { + case "workspace": { + return new WorkspaceBuilder(config.definition, baseBuilder, this.controller); + } + case "row": + case "column": + case "group": { + config.definition.type = config.type; + return new ParentBuilder(config.definition, baseBuilder); + } + default: throw new Error(`Unexpected Builder creation error, provided config: ${JSON.stringify(config)}`); + } + } + buildChildren(children, frame, workspace, parent) { + return children.map((child) => { + switch (child.type) { + case "window": return this.getModel("window", { + id: child.id, + config: child.config, + frame, workspace, parent + }); + case "column": return this.getModel(child.type, { + id: child.id, + config: child.config, + children: child.children, + frame, workspace, parent + }); + case "row": return this.getModel(child.type, { + id: child.id, + config: child.config, + children: child.children, + frame, workspace, parent + }); + case "group": return this.getModel(child.type, { + id: child.id, + config: child.config, + children: child.children, + frame, workspace, parent + }); + default: throw new Error(`Unsupported child type: ${child.type}`); + } + }); + } + } + + var version = "3.5.6"; + + const composeAPI = (glue, ioc) => { + const controller = ioc.controller; + const inWorkspace = () => { + const myId = glue.windows.my().id; + if (!myId) { + throw new Error("Cannot get my frame, because my id is undefined."); + } + return controller.checkIsInSwimlane(myId); + }; + const getBuilder = (config) => { + const validatedConfig = builderConfigDecoder.runWithException(config); + return ioc.getBuilder(validatedConfig); + }; + const getMyFrame = async () => { + const windowId = glue.windows.my().id; + if (!windowId) { + throw new Error("Cannot get my frame, because my id is undefined."); + } + const isInSwimlane = await controller.checkIsInSwimlane(windowId); + if (!isInSwimlane) { + throw new Error("Cannot fetch your frame, because this window is not in a workspace"); + } + return controller.getFrame({ windowId }); + }; + const getFrame = async (predicate) => { + checkThrowCallback(predicate); + return controller.getFrame({ predicate }); + }; + const getAllFrames = async (predicate) => { + checkThrowCallback(predicate, true); + return controller.getFrames(predicate); + }; + const getAllWorkspacesSummaries = () => { + return controller.getAllWorkspaceSummaries(); + }; + const getMyWorkspace = async () => { + const myId = glue.windows.my().id; + if (!myId) { + throw new Error("Cannot get my workspace, because my id is undefined."); + } + const isInSwimlane = await controller.checkIsInSwimlane(myId); + if (!isInSwimlane) { + throw new Error("Cannot fetch your workspace, because this window is not in a workspace"); + } + return await controller.getWorkspaceByWindowId(myId); + }; + const getWorkspace = async (predicate) => { + checkThrowCallback(predicate); + return (await controller.getWorkspaces(predicate))[0]; + }; + const getWorkspaceById = async (workspaceId) => { + nonEmptyStringDecoder.runWithException(workspaceId); + return controller.getWorkspaceById(workspaceId); + }; + const getAllWorkspaces = (predicate) => { + checkThrowCallback(predicate, true); + return controller.getWorkspaces(predicate); + }; + const getWindow = async (predicate) => { + checkThrowCallback(predicate); + return controller.getWindow(predicate); + }; + const getParent = async (predicate) => { + checkThrowCallback(predicate); + return controller.getParent(predicate); + }; + const restoreWorkspace = async (name, options) => { + nonEmptyStringDecoder.runWithException(name); + const validatedOptions = restoreWorkspaceConfigDecoder.runWithException(options); + return controller.restoreWorkspace(name, validatedOptions); + }; + const createWorkspace = async (definition, saveConfig) => { + const validatedDefinition = workspaceDefinitionDecoder.runWithException(definition); + const validatedConfig = workspaceBuilderCreateConfigDecoder.runWithException(saveConfig); + return controller.createWorkspace(validatedDefinition, validatedConfig); + }; + const createEmptyFrame = async (definition) => { + const validatedDefinition = emptyFrameDefinitionDecoder.runWithException(definition); + return controller.createEmptyFrame(validatedDefinition ?? {}); + }; + const layouts = { + getSummaries: () => { + return controller.getLayoutSummaries(); + }, + delete: async (name) => { + nonEmptyStringDecoder.runWithException(name); + return controller.deleteLayout(name); + }, + export: async (predicate) => { + checkThrowCallback(predicate, true); + return controller.exportLayout(predicate); + }, + import: async (layouts, mode = "replace") => { + if (!Array.isArray(layouts)) { + throw new Error(`The provided layouts argument is not an array: ${JSON.stringify(layouts)}`); + } + layouts.forEach((layout) => workspaceLayoutDecoder.runWithException(layout)); + return controller.importLayouts(layouts, mode); + }, + save: async (config) => { + const verifiedConfig = workspaceLayoutSaveConfigDecoder.runWithException(config); + return controller.saveLayout(verifiedConfig); + }, + onSaved: async (callback) => { + checkThrowCallback(callback); + return controller.handleOnSaved(callback); + }, + onRemoved: async (callback) => { + checkThrowCallback(callback); + return controller.handleOnRemoved(callback); + } + }; + const onFrameOpened = async (callback) => { + checkThrowCallback(callback); + const wrappedCallback = (payload) => { + const frameConfig = { + summary: payload.frameSummary + }; + const frame = ioc.getModel("frame", frameConfig); + callback(frame); + }; + const unsubscribe = await controller.processGlobalSubscription(wrappedCallback, "frame", "opened"); + return unsubscribe; + }; + const onFrameClosed = async (callback) => { + checkThrowCallback(callback); + const wrappedCallback = (payload) => { + callback({ frameId: payload.frameSummary.id, frameBounds: payload.frameBounds }); + }; + const unsubscribe = await controller.processGlobalSubscription(wrappedCallback, "frame", "closed"); + return unsubscribe; + }; + const onWorkspaceOpened = async (callback) => { + checkThrowCallback(callback); + const wrappedCallback = async (payload) => { + const workspace = await controller.transformStreamPayloadToWorkspace(payload); + callback(workspace); + }; + const unsubscribe = await controller.processGlobalSubscription(wrappedCallback, "workspace", "opened"); + return unsubscribe; + }; + const onWorkspaceClosed = async (callback) => { + checkThrowCallback(callback); + const wrappedCallback = (payload) => { + callback({ frameId: payload.frameSummary.id, workspaceId: payload.workspaceSummary.id, frameBounds: payload.frameBounds }); + }; + const unsubscribe = await controller.processGlobalSubscription(wrappedCallback, "workspace", "closed"); + return unsubscribe; + }; + const onWorkspaceHibernated = async (callback) => { + checkThrowCallback(callback); + const wrappedCallback = async (payload) => { + const workspace = await controller.transformStreamPayloadToWorkspace(payload); + callback(workspace); + }; + const unsubscribe = await controller.processGlobalSubscription(wrappedCallback, "workspace", "hibernated"); + return unsubscribe; + }; + const onWorkspaceResumed = async (callback) => { + checkThrowCallback(callback); + const wrappedCallback = async (payload) => { + const workspace = await controller.transformStreamPayloadToWorkspace(payload); + callback(workspace); + }; + const unsubscribe = await controller.processGlobalSubscription(wrappedCallback, "workspace", "resumed"); + return unsubscribe; + }; + const onWindowAdded = async (callback) => { + checkThrowCallback(callback); + const wrappedCallback = async (payload) => { + const snapshot = (await controller.getSnapshot(payload.windowSummary.config.workspaceId, "workspace")); + const frameConfig = { + summary: snapshot.frameSummary + }; + const frame = ioc.getModel("frame", frameConfig); + const workspaceConfig = { frame, snapshot }; + const workspace = ioc.getModel("workspace", workspaceConfig); + const windowParent = workspace.getBox((parent) => parent.id === payload.windowSummary.parentId); + const foundWindow = windowParent.children.find((child) => child.type === "window" && child.elementId === payload.windowSummary.itemId); + callback(foundWindow); + }; + const unsubscribe = await controller.processGlobalSubscription(wrappedCallback, "window", "added"); + return unsubscribe; + }; + const onWindowLoaded = async (callback) => { + checkThrowCallback(callback); + const wrappedCallback = async (payload) => { + const snapshot = (await controller.getSnapshot(payload.windowSummary.config.workspaceId, "workspace")); + const frameConfig = { + summary: snapshot.frameSummary + }; + const frame = ioc.getModel("frame", frameConfig); + const workspaceConfig = { frame, snapshot }; + const workspace = ioc.getModel("workspace", workspaceConfig); + const foundWindow = workspace.getWindow((win) => win.id && win.id === payload.windowSummary.config.windowId); + callback(foundWindow); + }; + const unsubscribe = await controller.processGlobalSubscription(wrappedCallback, "window", "loaded"); + return unsubscribe; + }; + const onWindowRemoved = async (callback) => { + checkThrowCallback(callback); + const wrappedCallback = (payload) => { + const { windowId, workspaceId, frameId } = payload.windowSummary.config; + callback({ windowId, workspaceId, frameId }); + }; + const unsubscribe = await controller.processGlobalSubscription(wrappedCallback, "window", "removed"); + return unsubscribe; + }; + const onWindowMaximized = async (callback) => { + checkThrowCallback(callback); + const wrappedCallback = async (payload) => { + const snapshot = (await controller.getSnapshot(payload.windowSummary.config.workspaceId, "workspace")); + const frameConfig = { + summary: snapshot.frameSummary + }; + const frame = ioc.getModel("frame", frameConfig); + const workspaceConfig = { frame, snapshot }; + const workspace = ioc.getModel("workspace", workspaceConfig); + const windowParent = workspace.getBox((parent) => parent.id === payload.windowSummary.parentId); + const foundWindow = windowParent.children.find((child) => child.type === "window" && child.elementId === payload.windowSummary.itemId); + callback(foundWindow); + }; + const unsubscribe = await controller.processGlobalSubscription(wrappedCallback, "window", "maximized"); + return unsubscribe; + }; + const onWindowRestored = async (callback) => { + checkThrowCallback(callback); + const wrappedCallback = async (payload) => { + const snapshot = (await controller.getSnapshot(payload.windowSummary.config.workspaceId, "workspace")); + const frameConfig = { + summary: snapshot.frameSummary + }; + const frame = ioc.getModel("frame", frameConfig); + const workspaceConfig = { frame, snapshot }; + const workspace = ioc.getModel("workspace", workspaceConfig); + const windowParent = workspace.getBox((parent) => parent.id === payload.windowSummary.parentId); + const foundWindow = windowParent.children.find((child) => child.type === "window" && child.elementId === payload.windowSummary.itemId); + callback(foundWindow); + }; + const unsubscribe = await controller.processGlobalSubscription(wrappedCallback, "window", "restored"); + return unsubscribe; + }; + const onWindowSelected = async (callback) => { + checkThrowCallback(callback); + const wrappedCallback = async (payload) => { + const snapshot = (await controller.getSnapshot(payload.windowSummary.config.workspaceId, "workspace")); + const frameConfig = { + summary: snapshot.frameSummary + }; + const frame = ioc.getModel("frame", frameConfig); + const workspaceConfig = { frame, snapshot }; + const workspace = ioc.getModel("workspace", workspaceConfig); + const windowParent = workspace.getBox((parent) => parent.id === payload.windowSummary.parentId); + const foundWindow = windowParent.children.find((child) => child.type === "window" && child.elementId === payload.windowSummary.itemId); + callback(foundWindow); + }; + const unsubscribe = await controller.processGlobalSubscription(wrappedCallback, "window", "selected"); + return unsubscribe; + }; + const waitForFrame = async (id) => { + nonEmptyStringDecoder.runWithException(id); + return new Promise((res, rej) => { + let unsub = () => { + }; + onFrameOpened((f) => { + if (f.id === id) { + res(f); + unsub(); + } + }).then((u) => { + unsub = u; + return getAllFrames(); + }).then((frames) => { + const myFrame = frames.find((f) => f.id === id); + if (myFrame) { + res(myFrame); + unsub(); + } + }).catch(rej); + }); + }; + return { + inWorkspace, + getBuilder, + getMyFrame, + getFrame, + getAllFrames, + getAllWorkspacesSummaries, + getMyWorkspace, + getWorkspace, + getWorkspaceById, + getAllWorkspaces, + getWindow, + getBox: getParent, + restoreWorkspace, + createWorkspace, + createEmptyFrame, + waitForFrame, + layouts, + onFrameOpened, + onFrameClosed, + onWorkspaceOpened, + onWorkspaceClosed, + onWorkspaceHibernated, + onWorkspaceResumed, + onWindowAdded, + onWindowLoaded, + onWindowRemoved, + onWindowMaximized, + onWindowRestored, + onWindowSelected, + version + }; + }; + + const factoryFunction = async (io) => { + const ioc = new IoC(io.agm, io.windows, io.layouts, io.contexts); + const actualWindowId = io.interop.instance.windowId; + await ioc.initiate(actualWindowId); + io.workspaces = composeAPI(io, ioc); + }; + if (typeof window !== "undefined") { + window.IOWorkspaces = factoryFunction; + } + + return factoryFunction; + +})); +//# sourceMappingURL=workspaces.umd.js.map diff --git a/typescript/solution/stocks/tsconfig.json b/typescript/solution/stocks/tsconfig.json new file mode 100644 index 0000000..11ec879 --- /dev/null +++ b/typescript/solution/stocks/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "./dist", + "rootDir": "./src" + }, + "include": ["./src", "../../types"] +} \ No newline at end of file diff --git a/typescript/solution/stocks/webpack.config.js b/typescript/solution/stocks/webpack.config.js new file mode 100644 index 0000000..cf31d79 --- /dev/null +++ b/typescript/solution/stocks/webpack.config.js @@ -0,0 +1,31 @@ +const path = require('path'); +const CopyWebpackPlugin = require('copy-webpack-plugin'); + +module.exports = { + mode: 'development', + entry: './src/index.ts', + module: { + rules: [ + { + test: /\.tsx?$/, + use: 'ts-loader', + exclude: /node_modules/, + }, + ], + }, + resolve: { + extensions: ['.tsx', '.ts', '.js'], + }, + output: { + filename: 'index.js', + path: path.resolve(__dirname, 'dist'), + }, + plugins: [ + new CopyWebpackPlugin({ + patterns: [ + { from: 'src/index.html', to: 'index.html' }, + { from: 'src/lib', to: 'lib' } + ], + }), + ], +}; \ No newline at end of file diff --git a/typescript/start/app-definitions/client-details.json b/typescript/start/app-definitions/client-details.json new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/typescript/start/app-definitions/client-details.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/typescript/start/app-definitions/clients.json b/typescript/start/app-definitions/clients.json new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/typescript/start/app-definitions/clients.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/typescript/start/app-definitions/portfolio-downloader.json b/typescript/start/app-definitions/portfolio-downloader.json new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/typescript/start/app-definitions/portfolio-downloader.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/typescript/start/app-definitions/stocks.json b/typescript/start/app-definitions/stocks.json new file mode 100644 index 0000000..8e4ca86 --- /dev/null +++ b/typescript/start/app-definitions/stocks.json @@ -0,0 +1,4 @@ +[ + {}, + {} +] \ No newline at end of file diff --git a/typescript/start/client-details/esbuild.js b/typescript/start/client-details/esbuild.js new file mode 100644 index 0000000..27c80dc --- /dev/null +++ b/typescript/start/client-details/esbuild.js @@ -0,0 +1,48 @@ +const fs = require('fs'); +const path = require('path'); +const { build } = require('esbuild'); + +// Directory paths +const srcDir = path.join(__dirname, 'src'); +const distDir = path.join(__dirname, 'dist'); + +// Ensure dist directory exists +if (!fs.existsSync(distDir)) { + fs.mkdirSync(distDir, { recursive: true }); +} + +// Copy HTML file +fs.copyFileSync( + path.join(srcDir, 'index.html'), + path.join(distDir, 'index.html') +); + +// Copy lib directory +const libSrcDir = path.join(srcDir, 'lib'); +const libDistDir = path.join(distDir, 'lib'); + +if (!fs.existsSync(libDistDir)) { + fs.mkdirSync(libDistDir, { recursive: true }); +} + +fs.readdirSync(libSrcDir).forEach(file => { + fs.copyFileSync( + path.join(libSrcDir, file), + path.join(libDistDir, file) + ); +}); + +// Build with esbuild +build({ + entryPoints: [path.join(srcDir, 'index.ts')], + bundle: true, + outfile: path.join(distDir, 'index.js'), + platform: 'browser', + format: 'iife', + sourcemap: true, + target: ['es2020'], + tsconfig: path.join(__dirname, 'tsconfig.json'), +}).catch((error) => { + console.error(error); + process.exit(1); +}); \ No newline at end of file diff --git a/typescript/start/client-details/src/index.html b/typescript/start/client-details/src/index.html new file mode 100644 index 0000000..8b2577f --- /dev/null +++ b/typescript/start/client-details/src/index.html @@ -0,0 +1,70 @@ + + + + + + + + + + + + Client Details + + + + + + + + + + + +
+
+
+
+ io.Connect is unavailable +
+
+
+

Client Details

+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DetailValue
Full Name
Address
Phone Number
Email
Account Manager
+
+
+ + + \ No newline at end of file diff --git a/typescript/start/client-details/src/index.ts b/typescript/start/client-details/src/index.ts new file mode 100644 index 0000000..57a4ae6 --- /dev/null +++ b/typescript/start/client-details/src/index.ts @@ -0,0 +1,43 @@ +const setFields = (client: Client): void => { + const elementName = document.querySelectorAll("[data-name]")[0] as HTMLElement; + if (elementName) elementName.innerText = client.name; + + const elementAddress = document.querySelectorAll("[data-address]")[0] as HTMLElement; + if (elementAddress) elementAddress.innerText = client.address || ''; + + const elementPhone = document.querySelectorAll("[data-phone]")[0] as HTMLElement; + if (elementPhone) elementPhone.innerText = client.contactNumbers || ''; + + const elementOccupation = document.querySelectorAll("[data-email]")[0] as HTMLElement; + if (elementOccupation) elementOccupation.innerText = client.email || ''; + + const elementManager = document.querySelectorAll("[data-manager]")[0] as HTMLElement; + if (elementManager) elementManager.innerText = client.accountManager || ''; +}; + +// TODO: Chapter 3 +// const toggleIOAvailable = (): void => { +// const span = document.getElementById("ioConnectSpan"); +// if (!span) return; + +// span.classList.remove("bg-danger"); +// span.classList.add("bg-success"); +// span.textContent = "io.Connect is available"; +// }; + +const start = async (): Promise => { + // TODO: Chapter 3 + + // TODO: Chapter 12.1 + + // TODO: Chapter 9.4 +}; + +// Add window properties when needed +declare global { + interface Window { + io?: IODesktopAPI; + } +} + +start().catch(console.error); \ No newline at end of file diff --git a/typescript/start/client-details/src/lib/desktop.umd.js b/typescript/start/client-details/src/lib/desktop.umd.js new file mode 100644 index 0000000..6cea2c9 --- /dev/null +++ b/typescript/start/client-details/src/lib/desktop.umd.js @@ -0,0 +1,23144 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define(factory) : + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.desktop = factory()); +})(this, (function () { 'use strict'; + + var MetricTypes = { + STRING: 1, + NUMBER: 2, + TIMESTAMP: 3, + OBJECT: 4 + }; + + function getMetricTypeByValue(metric) { + if (metric.type === MetricTypes.TIMESTAMP) { + return "timestamp"; + } + else if (metric.type === MetricTypes.NUMBER) { + return "number"; + } + else if (metric.type === MetricTypes.STRING) { + return "string"; + } + else if (metric.type === MetricTypes.OBJECT) { + return "object"; + } + return "unknown"; + } + function getTypeByValue(value) { + if (value.constructor === Date) { + return "timestamp"; + } + else if (typeof value === "number") { + return "number"; + } + else if (typeof value === "string") { + return "string"; + } + else if (typeof value === "object") { + return "object"; + } + else { + return "string"; + } + } + function serializeMetric(metric) { + const serializedMetrics = {}; + const type = getMetricTypeByValue(metric); + if (type === "object") { + const values = Object.keys(metric.value).reduce((memo, key) => { + const innerType = getTypeByValue(metric.value[key]); + if (innerType === "object") { + const composite = defineNestedComposite(metric.value[key]); + memo[key] = { + type: "object", + description: "", + context: {}, + composite, + }; + } + else { + memo[key] = { + type: innerType, + description: "", + context: {}, + }; + } + return memo; + }, {}); + serializedMetrics.composite = values; + } + serializedMetrics.name = normalizeMetricName(metric.path.join("/") + "/" + metric.name); + serializedMetrics.type = type; + serializedMetrics.description = metric.description; + serializedMetrics.context = {}; + return serializedMetrics; + } + function defineNestedComposite(values) { + return Object.keys(values).reduce((memo, key) => { + const type = getTypeByValue(values[key]); + if (type === "object") { + memo[key] = { + type: "object", + description: "", + context: {}, + composite: defineNestedComposite(values[key]), + }; + } + else { + memo[key] = { + type, + description: "", + context: {}, + }; + } + return memo; + }, {}); + } + function normalizeMetricName(name) { + if (typeof name !== "undefined" && name.length > 0 && name[0] !== "/") { + return "/" + name; + } + else { + return name; + } + } + function getMetricValueByType(metric) { + const type = getMetricTypeByValue(metric); + if (type === "timestamp") { + return Date.now(); + } + else { + return publishNestedComposite(metric.value); + } + } + function publishNestedComposite(values) { + if (typeof values !== "object") { + return values; + } + return Object.keys(values).reduce((memo, key) => { + const value = values[key]; + if (typeof value === "object" && value.constructor !== Date) { + memo[key] = publishNestedComposite(value); + } + else if (value.constructor === Date) { + memo[key] = new Date(value).getTime(); + } + else if (value.constructor === Boolean) { + memo[key] = value.toString(); + } + else { + memo[key] = value; + } + return memo; + }, {}); + } + function flatten(arr) { + return arr.reduce((flat, toFlatten) => { + return flat.concat(Array.isArray(toFlatten) ? flatten(toFlatten) : toFlatten); + }, []); + } + function getHighestState(arr) { + return arr.sort((a, b) => { + if (!a.state) { + return 1; + } + if (!b.state) { + return -1; + } + return b.state - a.state; + })[0]; + } + function aggregateDescription(arr) { + let msg = ""; + arr.forEach((m, idx, a) => { + const path = m.path.join("."); + if (idx === a.length - 1) { + msg += path + "." + m.name + ": " + m.description; + } + else { + msg += path + "." + m.name + ": " + m.description + ","; + } + }); + if (msg.length > 100) { + return msg.slice(0, 100) + "..."; + } + else { + return msg; + } + } + function composeMsgForRootStateMetric(system) { + const aggregatedState = system.root.getAggregateState(); + const merged = flatten(aggregatedState); + const highestState = getHighestState(merged); + const aggregateDesc = aggregateDescription(merged); + return { + description: aggregateDesc, + value: highestState.state, + }; + } + + function gw3 (connection, config) { + if (!connection || typeof connection !== "object") { + throw new Error("Connection is required parameter"); + } + let joinPromise; + let session; + const init = (repo) => { + let resolveReadyPromise; + joinPromise = new Promise((resolve) => { + resolveReadyPromise = resolve; + }); + session = connection.domain("metrics"); + session.onJoined((reconnect) => { + if (!reconnect && resolveReadyPromise) { + resolveReadyPromise(); + resolveReadyPromise = undefined; + } + const rootStateMetric = { + name: "/State", + type: "object", + composite: { + Description: { + type: "string", + description: "", + }, + Value: { + type: "number", + description: "", + }, + }, + description: "System state", + context: {}, + }; + const defineRootMetricsMsg = { + type: "define", + metrics: [rootStateMetric], + }; + session.send(defineRootMetricsMsg); + if (reconnect) { + replayRepo(repo); + } + }); + session.join({ + system: config.system, + service: config.service, + instance: config.instance + }); + }; + const replayRepo = (repo) => { + replaySystem(repo.root); + }; + const replaySystem = (system) => { + createSystem(system); + system.metrics.forEach((m) => { + createMetric(m); + }); + system.subSystems.forEach((ss) => { + replaySystem(ss); + }); + }; + const createSystem = async (system) => { + if (system.parent === undefined) { + return; + } + await joinPromise; + const metric = { + name: normalizeMetricName(system.path.join("/") + "/" + system.name + "/State"), + type: "object", + composite: { + Description: { + type: "string", + description: "", + }, + Value: { + type: "number", + description: "", + }, + }, + description: "System state", + context: {}, + }; + const createMetricsMsg = { + type: "define", + metrics: [metric], + }; + session.send(createMetricsMsg); + }; + const updateSystem = async (system, state) => { + await joinPromise; + const shadowedUpdateMetric = { + type: "publish", + values: [{ + name: normalizeMetricName(system.path.join("/") + "/" + system.name + "/State"), + value: { + Description: state.description, + Value: state.state, + }, + timestamp: Date.now(), + }], + }; + session.send(shadowedUpdateMetric); + const stateObj = composeMsgForRootStateMetric(system); + const rootMetric = { + type: "publish", + peer_id: connection.peerId, + values: [{ + name: "/State", + value: { + Description: stateObj.description, + Value: stateObj.value, + }, + timestamp: Date.now(), + }], + }; + session.send(rootMetric); + }; + const createMetric = async (metric) => { + const metricClone = cloneMetric(metric); + await joinPromise; + const m = serializeMetric(metricClone); + const createMetricsMsg = { + type: "define", + metrics: [m], + }; + session.send(createMetricsMsg); + if (typeof metricClone.value !== "undefined") { + updateMetricCore(metricClone); + } + }; + const updateMetric = async (metric) => { + const metricClone = cloneMetric(metric); + await joinPromise; + updateMetricCore(metricClone); + }; + const updateMetricCore = (metric) => { + if (canUpdate()) { + const value = getMetricValueByType(metric); + const publishMetricsMsg = { + type: "publish", + values: [{ + name: normalizeMetricName(metric.path.join("/") + "/" + metric.name), + value, + timestamp: Date.now(), + }], + }; + return session.sendFireAndForget(publishMetricsMsg); + } + return Promise.resolve(); + }; + const cloneMetric = (metric) => { + const metricClone = { ...metric }; + if (typeof metric.value === "object" && metric.value !== null) { + metricClone.value = { ...metric.value }; + } + return metricClone; + }; + const canUpdate = () => { + try { + const func = config.canUpdateMetric ?? (() => true); + return func(); + } + catch { + return true; + } + }; + return { + init, + createSystem, + updateSystem, + createMetric, + updateMetric, + }; + } + + var Helpers = { + validate: (definition, parent, transport) => { + if (definition === null || typeof definition !== "object") { + throw new Error("Missing definition"); + } + if (parent === null || typeof parent !== "object") { + throw new Error("Missing parent"); + } + if (transport === null || typeof transport !== "object") { + throw new Error("Missing transport"); + } + }, + }; + + class BaseMetric { + definition; + system; + transport; + value; + type; + path = []; + name; + description; + get repo() { + return this.system?.repo; + } + get id() { return `${this.system.path}/${name}`; } + constructor(definition, system, transport, value, type) { + this.definition = definition; + this.system = system; + this.transport = transport; + this.value = value; + this.type = type; + Helpers.validate(definition, system, transport); + this.path = system.path.slice(0); + this.path.push(system.name); + this.name = definition.name; + this.description = definition.description; + transport.createMetric(this); + } + update(newValue) { + this.value = newValue; + return this.transport.updateMetric(this); + } + } + + class NumberMetric extends BaseMetric { + constructor(definition, system, transport, value) { + super(definition, system, transport, value, MetricTypes.NUMBER); + } + incrementBy(num) { + this.update(this.value + num); + } + increment() { + this.incrementBy(1); + } + decrement() { + this.incrementBy(-1); + } + decrementBy(num) { + this.incrementBy(num * -1); + } + } + + class ObjectMetric extends BaseMetric { + constructor(definition, system, transport, value) { + super(definition, system, transport, value, MetricTypes.OBJECT); + } + update(newValue) { + this.mergeValues(newValue); + return this.transport.updateMetric(this); + } + mergeValues(values) { + return Object.keys(this.value).forEach((k) => { + if (typeof values[k] !== "undefined") { + this.value[k] = values[k]; + } + }); + } + } + + class StringMetric extends BaseMetric { + constructor(definition, system, transport, value) { + super(definition, system, transport, value, MetricTypes.STRING); + } + } + + class TimestampMetric extends BaseMetric { + constructor(definition, system, transport, value) { + super(definition, system, transport, value, MetricTypes.TIMESTAMP); + } + now() { + this.update(new Date()); + } + } + + function system$1(name, repo, protocol, parent, description) { + if (!repo) { + throw new Error("Repository is required"); + } + if (!protocol) { + throw new Error("Transport is required"); + } + const _transport = protocol; + const _name = name; + const _description = description || ""; + const _repo = repo; + const _parent = parent; + const _path = _buildPath(parent); + let _state = {}; + const id = _arrayToString(_path, "/") + name; + const root = repo.root; + const _subSystems = []; + const _metrics = []; + function subSystem(nameSystem, descriptionSystem) { + if (!nameSystem || nameSystem.length === 0) { + throw new Error("name is required"); + } + const match = _subSystems.filter((s) => s.name === nameSystem); + if (match.length > 0) { + return match[0]; + } + const _system = system$1(nameSystem, _repo, _transport, me, descriptionSystem); + _subSystems.push(_system); + return _system; + } + function setState(state, stateDescription) { + _state = { state, description: stateDescription }; + _transport.updateSystem(me, _state); + } + function stringMetric(definition, value) { + return _getOrCreateMetric(definition, MetricTypes.STRING, value, (metricDef) => new StringMetric(metricDef, me, _transport, value)); + } + function numberMetric(definition, value) { + return _getOrCreateMetric(definition, MetricTypes.NUMBER, value, (metricDef) => new NumberMetric(metricDef, me, _transport, value)); + } + function objectMetric(definition, value) { + return _getOrCreateMetric(definition, MetricTypes.OBJECT, value, (metricDef) => new ObjectMetric(metricDef, me, _transport, value)); + } + function timestampMetric(definition, value) { + return _getOrCreateMetric(definition, MetricTypes.TIMESTAMP, value, (metricDef) => new TimestampMetric(metricDef, me, _transport, value)); + } + function _getOrCreateMetric(metricObject, expectedType, value, createMetric) { + let metricDef = { name: "" }; + if (typeof metricObject === "string") { + metricDef = { name: metricObject }; + } + else { + metricDef = metricObject; + } + const matching = _metrics.filter((shadowedMetric) => shadowedMetric.name === metricDef.name); + if (matching.length > 0) { + const existing = matching[0]; + if (existing.type !== expectedType) { + throw new Error(`A metric named ${metricDef.name} is already defined with different type.`); + } + if (typeof value !== "undefined") { + existing + .update(value) + .catch(() => { }); + } + return existing; + } + const metric = createMetric(metricDef); + _metrics.push(metric); + return metric; + } + function _buildPath(shadowedSystem) { + if (!shadowedSystem || !shadowedSystem.parent) { + return []; + } + const path = _buildPath(shadowedSystem.parent); + path.push(shadowedSystem.name); + return path; + } + function _arrayToString(path, separator) { + return ((path && path.length > 0) ? path.join(separator) : ""); + } + function getAggregateState() { + const aggState = []; + if (Object.keys(_state).length > 0) { + aggState.push({ + name: _name, + path: _path, + state: _state.state, + description: _state.description, + }); + } + _subSystems.forEach((shadowedSubSystem) => { + const result = shadowedSubSystem.getAggregateState(); + if (result.length > 0) { + aggState.push(...result); + } + }); + return aggState; + } + const me = { + get name() { + return _name; + }, + get description() { + return _description; + }, + get repo() { + return _repo; + }, + get parent() { + return _parent; + }, + path: _path, + id, + root, + get subSystems() { + return _subSystems; + }, + get metrics() { + return _metrics; + }, + subSystem, + getState: () => { + return _state; + }, + setState, + stringMetric, + timestampMetric, + objectMetric, + numberMetric, + getAggregateState, + }; + _transport.createSystem(me); + return me; + } + + class Repository { + root; + constructor(options, protocol) { + protocol.init(this); + this.root = system$1("", this, protocol); + this.addSystemMetrics(this.root, options.clickStream || options.clickStream === undefined); + } + addSystemMetrics(rootSystem, useClickStream) { + if (typeof navigator !== "undefined") { + rootSystem.stringMetric("UserAgent", navigator.userAgent); + } + if (useClickStream && typeof document !== "undefined") { + const clickStream = rootSystem.subSystem("ClickStream"); + const documentClickHandler = (e) => { + if (!e.target) { + return; + } + const target = e.target; + const className = target ? target.getAttribute("class") ?? "" : ""; + clickStream.objectMetric("LastBrowserEvent", { + type: "click", + timestamp: new Date(), + target: { + className, + id: target.id, + type: "<" + target.tagName.toLowerCase() + ">", + href: target.href || "", + }, + }); + }; + clickStream.objectMetric("Page", { + title: document.title, + page: window.location.href, + }); + if (document.addEventListener) { + document.addEventListener("click", documentClickHandler); + } + else { + document.attachEvent("onclick", documentClickHandler); + } + } + rootSystem.stringMetric("StartTime", (new Date()).toString()); + const urlMetric = rootSystem.stringMetric("StartURL", ""); + const appNameMetric = rootSystem.stringMetric("AppName", ""); + if (typeof window !== "undefined") { + if (typeof window.location !== "undefined") { + const startUrl = window.location.href; + urlMetric.update(startUrl); + } + if (typeof window.glue42gd !== "undefined") { + appNameMetric.update(window.glue42gd.appName); + } + } + } + } + + class NullProtocol { + init(repo) { + } + createSystem(system) { + return Promise.resolve(); + } + updateSystem(metric, state) { + return Promise.resolve(); + } + createMetric(metric) { + return Promise.resolve(); + } + updateMetric(metric) { + return Promise.resolve(); + } + } + + class PerfTracker { + api; + lastCount = 0; + initialPublishTimeout = 10 * 1000; + publishInterval = 60 * 1000; + system; + constructor(api, initialPublishTimeout, publishInterval) { + this.api = api; + this.initialPublishTimeout = initialPublishTimeout ?? this.initialPublishTimeout; + this.publishInterval = publishInterval ?? this.publishInterval; + this.scheduleCollection(); + this.system = this.api.subSystem("performance", "Performance data published by the web application"); + } + scheduleCollection() { + setTimeout(() => { + this.collect(); + setInterval(() => { + this.collect(); + }, this.publishInterval); + }, this.initialPublishTimeout); + } + collect() { + try { + this.collectMemory(); + this.collectEntries(); + } + catch { + } + } + collectMemory() { + const memory = window.performance.memory; + this.system.stringMetric("memory", JSON.stringify({ + totalJSHeapSize: memory.totalJSHeapSize, + usedJSHeapSize: memory.usedJSHeapSize + })); + } + collectEntries() { + const allEntries = window.performance.getEntries(); + if (allEntries.length <= this.lastCount) { + return; + } + this.lastCount = allEntries.length; + const jsonfiedEntries = allEntries.map((i) => i.toJSON()); + this.system.stringMetric("entries", JSON.stringify(jsonfiedEntries)); + } + } + + var metrics = (options) => { + let protocol; + if (!options.connection || typeof options.connection !== "object") { + protocol = new NullProtocol(); + } + else { + protocol = gw3(options.connection, options); + } + const repo = new Repository(options, protocol); + let rootSystem = repo.root; + if (!options.disableAutoAppSystem) { + rootSystem = rootSystem.subSystem("App"); + } + const api = addFAVSupport(rootSystem); + initPerf(api, options.pagePerformanceMetrics); + return api; + }; + function initPerf(api, config) { + if (typeof window === "undefined") { + return; + } + const perfConfig = window?.glue42gd?.metrics?.pagePerformanceMetrics; + if (perfConfig) { + config = perfConfig; + } + if (config?.enabled) { + new PerfTracker(api, config.initialPublishTimeout, config.publishInterval); + } + } + function addFAVSupport(system) { + const reportingSystem = system.subSystem("reporting"); + const def = { + name: "features" + }; + let featureMetric; + const featureMetricFunc = (name, action, payload) => { + if (typeof name === "undefined" || name === "") { + throw new Error("name is mandatory"); + } + else if (typeof action === "undefined" || action === "") { + throw new Error("action is mandatory"); + } + else if (typeof payload === "undefined" || payload === "") { + throw new Error("payload is mandatory"); + } + if (!featureMetric) { + featureMetric = reportingSystem.objectMetric(def, { name, action, payload }); + } + else { + featureMetric.update({ + name, + action, + payload + }); + } + }; + system.featureMetric = featureMetricFunc; + return system; + } + + var commonjsGlobal$1 = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; + + function getDefaultExportFromCjs$1 (x) { + return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; + } + + function createRegistry$1(options) { + if (options && options.errorHandling + && typeof options.errorHandling !== "function" + && options.errorHandling !== "log" + && options.errorHandling !== "silent" + && options.errorHandling !== "throw") { + throw new Error("Invalid options passed to createRegistry. Prop errorHandling should be [\"log\" | \"silent\" | \"throw\" | (err) => void], but " + typeof options.errorHandling + " was passed"); + } + var _userErrorHandler = options && typeof options.errorHandling === "function" && options.errorHandling; + var callbacks = {}; + function add(key, callback, replayArgumentsArr) { + var callbacksForKey = callbacks[key]; + if (!callbacksForKey) { + callbacksForKey = []; + callbacks[key] = callbacksForKey; + } + callbacksForKey.push(callback); + if (replayArgumentsArr) { + setTimeout(function () { + replayArgumentsArr.forEach(function (replayArgument) { + var _a; + if ((_a = callbacks[key]) === null || _a === void 0 ? void 0 : _a.includes(callback)) { + try { + if (Array.isArray(replayArgument)) { + callback.apply(undefined, replayArgument); + } + else { + callback.apply(undefined, [replayArgument]); + } + } + catch (err) { + _handleError(err, key); + } + } + }); + }, 0); + } + return function () { + var allForKey = callbacks[key]; + if (!allForKey) { + return; + } + allForKey = allForKey.reduce(function (acc, element, index) { + if (!(element === callback && acc.length === index)) { + acc.push(element); + } + return acc; + }, []); + if (allForKey.length === 0) { + delete callbacks[key]; + } + else { + callbacks[key] = allForKey; + } + }; + } + function execute(key) { + var argumentsArr = []; + for (var _i = 1; _i < arguments.length; _i++) { + argumentsArr[_i - 1] = arguments[_i]; + } + var callbacksForKey = callbacks[key]; + if (!callbacksForKey || callbacksForKey.length === 0) { + return []; + } + var results = []; + callbacksForKey.forEach(function (callback) { + try { + var result = callback.apply(undefined, argumentsArr); + results.push(result); + } + catch (err) { + results.push(undefined); + _handleError(err, key); + } + }); + return results; + } + function _handleError(exceptionArtifact, key) { + var errParam = exceptionArtifact instanceof Error ? exceptionArtifact : new Error(exceptionArtifact); + if (_userErrorHandler) { + _userErrorHandler(errParam); + return; + } + var msg = "[ERROR] callback-registry: User callback for key \"" + key + "\" failed: " + errParam.stack; + if (options) { + switch (options.errorHandling) { + case "log": + return console.error(msg); + case "silent": + return; + case "throw": + throw new Error(msg); + } + } + console.error(msg); + } + function clear() { + callbacks = {}; + } + function clearKey(key) { + var callbacksForKey = callbacks[key]; + if (!callbacksForKey) { + return; + } + delete callbacks[key]; + } + return { + add: add, + execute: execute, + clear: clear, + clearKey: clearKey + }; + } + createRegistry$1.default = createRegistry$1; + var lib$1 = createRegistry$1; + + + var CallbackRegistryFactory$1 = /*@__PURE__*/getDefaultExportFromCjs$1(lib$1); + + class InProcTransport { + gw; + registry = CallbackRegistryFactory$1(); + client; + constructor(settings, logger) { + this.gw = settings.facade; + this.gw.connect((_client, message) => { + this.messageHandler(message); + }).then((client) => { + this.client = client; + }); + } + get isObjectBasedTransport() { + return true; + } + sendObject(msg) { + if (this.client) { + this.client.send(msg); + return Promise.resolve(undefined); + } + else { + return Promise.reject(`not connected`); + } + } + send(_msg) { + return Promise.reject("not supported"); + } + onMessage(callback) { + return this.registry.add("onMessage", callback); + } + onConnectedChanged(callback) { + callback(true); + return () => { }; + } + close() { + return Promise.resolve(); + } + open() { + return Promise.resolve(); + } + name() { + return "in-memory"; + } + reconnect() { + return Promise.resolve(); + } + messageHandler(msg) { + this.registry.execute("onMessage", msg); + } + } + + class SharedWorkerTransport { + logger; + worker; + registry = CallbackRegistryFactory$1(); + constructor(workerFile, logger) { + this.logger = logger; + this.worker = new SharedWorker(workerFile); + this.worker.port.onmessage = (e) => { + this.messageHandler(e.data); + }; + } + get isObjectBasedTransport() { + return true; + } + sendObject(msg) { + this.worker.port.postMessage(msg); + return Promise.resolve(); + } + send(_msg) { + return Promise.reject("not supported"); + } + onMessage(callback) { + return this.registry.add("onMessage", callback); + } + onConnectedChanged(callback) { + callback(true); + return () => { }; + } + close() { + return Promise.resolve(); + } + open() { + return Promise.resolve(); + } + name() { + return "shared-worker"; + } + reconnect() { + return Promise.resolve(); + } + messageHandler(msg) { + this.registry.execute("onMessage", msg); + } + } + + let Utils$1 = class Utils { + static isNode() { + if (typeof Utils._isNode !== "undefined") { + return Utils._isNode; + } + if (typeof window !== "undefined") { + Utils._isNode = false; + return false; + } + try { + Utils._isNode = Object.prototype.toString.call(global.process) === "[object process]"; + } + catch (e) { + Utils._isNode = false; + } + return Utils._isNode; + } + static _isNode; + }; + + let PromiseWrapper$1 = class PromiseWrapper { + static delay(time) { + return new Promise((resolve) => setTimeout(resolve, time)); + } + resolve; + reject; + promise; + rejected = false; + resolved = false; + get ended() { + return this.rejected || this.resolved; + } + constructor() { + this.promise = new Promise((resolve, reject) => { + this.resolve = (t) => { + this.resolved = true; + resolve(t); + }; + this.reject = (err) => { + this.rejected = true; + reject(err); + }; + }); + } + }; + + const timers = {}; + function getAllTimers() { + return timers; + } + function timer (timerName) { + const existing = timers[timerName]; + if (existing) { + return existing; + } + const marks = []; + function now() { + return new Date().getTime(); + } + const startTime = now(); + mark("start", startTime); + let endTime; + let period; + function stop() { + endTime = now(); + mark("end", endTime); + period = endTime - startTime; + return period; + } + function mark(name, time) { + const currentTime = time ?? now(); + let diff = 0; + if (marks.length > 0) { + diff = currentTime - marks[marks.length - 1].time; + } + marks.push({ name, time: currentTime, diff }); + } + const timerObj = { + get startTime() { + return startTime; + }, + get endTime() { + return endTime; + }, + get period() { + return period; + }, + stop, + mark, + marks + }; + timers[timerName] = timerObj; + return timerObj; + } + + const WebSocketConstructor = Utils$1.isNode() ? require("ws") : window.WebSocket; + class WS { + ws; + logger; + settings; + startupTimer = timer("connection"); + _running = true; + _registry = CallbackRegistryFactory$1(); + wsRequests = []; + constructor(settings, logger) { + this.settings = settings; + this.logger = logger; + if (!this.settings.ws) { + throw new Error("ws is missing"); + } + } + onMessage(callback) { + return this._registry.add("onMessage", callback); + } + send(msg, options) { + return new Promise((resolve, reject) => { + this.waitForSocketConnection(() => { + try { + this.ws?.send(msg); + resolve(); + } + catch (e) { + reject(e); + } + }, reject); + }); + } + open() { + this.logger.info("opening ws..."); + this._running = true; + return new Promise((resolve, reject) => { + this.waitForSocketConnection(resolve, reject); + }); + } + close() { + this._running = false; + if (this.ws) { + this.ws.close(); + } + return Promise.resolve(); + } + onConnectedChanged(callback) { + return this._registry.add("onConnectedChanged", callback); + } + name() { + return this.settings.ws; + } + reconnect() { + this.ws?.close(); + const pw = new PromiseWrapper$1(); + this.waitForSocketConnection(() => { + pw.resolve(); + }); + return pw.promise; + } + waitForSocketConnection(callback, failed) { + failed = failed ?? (() => { }); + if (!this._running) { + failed(`wait for socket on ${this.settings.ws} failed - socket closed by user`); + return; + } + if (this.ws?.readyState === 1) { + callback(); + return; + } + this.wsRequests.push({ callback, failed }); + if (this.wsRequests.length > 1) { + return; + } + this.openSocket(); + } + async openSocket(retryInterval, retriesLeft) { + this.logger.info(`opening ws to ${this.settings.ws}, retryInterval: ${retryInterval}, retriesLeft: ${retriesLeft}...`); + this.startupTimer.mark("opening-socket"); + if (retryInterval === undefined) { + retryInterval = this.settings.reconnectInterval; + } + if (typeof retriesLeft === "undefined") { + retriesLeft = this.settings.reconnectAttempts; + } + if (retriesLeft !== undefined) { + if (retriesLeft === 0) { + this.notifyForSocketState(`wait for socket on ${this.settings.ws} failed - no more retries left`); + return; + } + this.logger.debug(`will retry ${retriesLeft} more times (every ${retryInterval} ms)`); + } + try { + await this.initiateSocket(); + this.startupTimer.mark("socket-initiated"); + this.notifyForSocketState(); + } + catch { + setTimeout(() => { + const retries = retriesLeft === undefined ? undefined : retriesLeft - 1; + this.openSocket(retryInterval, retries); + }, retryInterval); + } + } + initiateSocket() { + const pw = new PromiseWrapper$1(); + this.logger.debug(`initiating ws to ${this.settings.ws}...`); + this.ws = new WebSocketConstructor(this.settings.ws ?? ""); + this.ws.onerror = (err) => { + let reason = ""; + try { + reason = JSON.stringify(err); + } + catch (error) { + const seen = new WeakSet(); + const replacer = (key, value) => { + if (typeof value === "object" && value !== null) { + if (seen.has(value)) { + return; + } + seen.add(value); + } + return value; + }; + reason = JSON.stringify(err, replacer); + } + this.logger.info(`ws error - reason: ${reason}`); + pw.reject("error"); + this.notifyStatusChanged(false, reason); + }; + this.ws.onclose = (err) => { + this.logger.info(`ws closed - code: ${err?.code} reason: ${err?.reason}`); + pw.reject("closed"); + this.notifyStatusChanged(false); + }; + this.ws.onopen = () => { + this.startupTimer.mark("ws-opened"); + this.logger.info(`ws opened ${this.settings.identity?.application}`); + pw.resolve(); + this.notifyStatusChanged(true); + }; + this.ws.onmessage = (message) => { + this._registry.execute("onMessage", message.data); + }; + return pw.promise; + } + notifyForSocketState(error) { + this.wsRequests.forEach((wsRequest) => { + if (error) { + if (wsRequest.failed) { + wsRequest.failed(error); + } + } + else { + wsRequest.callback(); + } + }); + this.wsRequests = []; + } + notifyStatusChanged(status, reason) { + this._registry.execute("onConnectedChanged", status, reason); + } + } + + class MessageReplayerImpl { + specs; + specsNames = []; + messages = {}; + isDone; + subs = {}; + subsRefCount = {}; + connection; + constructor(specs) { + this.specs = {}; + for (const spec of specs) { + this.specs[spec.name] = spec; + this.specsNames.push(spec.name); + } + } + init(connection) { + this.connection = connection; + for (const name of this.specsNames) { + for (const type of this.specs[name].types) { + let refCount = this.subsRefCount[type]; + if (!refCount) { + refCount = 0; + } + refCount += 1; + this.subsRefCount[type] = refCount; + if (refCount > 1) { + continue; + } + const sub = connection.on(type, (msg) => this.processMessage(type, msg)); + this.subs[type] = sub; + } + } + } + processMessage(type, msg) { + if (this.isDone || !msg) { + return; + } + for (const name of this.specsNames) { + if (this.specs[name].types.indexOf(type) !== -1) { + const messages = this.messages[name] || []; + this.messages[name] = messages; + messages.push(msg); + } + } + } + drain(name, callback) { + if (callback) { + (this.messages[name] || []).forEach(callback); + } + delete this.messages[name]; + for (const type of this.specs[name].types) { + this.subsRefCount[type] -= 1; + if (this.subsRefCount[type] <= 0) { + this.connection?.off(this.subs[type]); + delete this.subs[type]; + delete this.subsRefCount[type]; + } + } + delete this.specs[name]; + if (!this.specs.length) { + this.isDone = true; + } + } + } + + let urlAlphabet$1 = + 'useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict'; + let nanoid$1 = (size = 21) => { + let id = ''; + let i = size; + while (i--) { + id += urlAlphabet$1[(Math.random() * 64) | 0]; + } + return id + }; + + const PromisePlus$1 = (executor, timeoutMilliseconds, timeoutMessage) => { + return new Promise((resolve, reject) => { + const timeout = setTimeout(() => { + const message = timeoutMessage || `Promise timeout hit: ${timeoutMilliseconds}`; + reject(message); + }, timeoutMilliseconds); + const providedPromise = new Promise(executor); + providedPromise + .then((result) => { + clearTimeout(timeout); + resolve(result); + }) + .catch((error) => { + clearTimeout(timeout); + reject(error); + }); + }); + }; + + class WebPlatformTransport { + settings; + logger; + identity; + isPreferredActivated; + _communicationId; + publicWindowId; + selfAssignedWindowId; + iAmConnected = false; + parentReady = false; + rejected = false; + parentPingResolve; + parentPingInterval; + connectionResolve; + extConnectionResolve; + extConnectionReject; + connectionReject; + port; + myClientId; + children = []; + extContentAvailable = false; + extContentConnecting = false; + extContentConnected = false; + parentWindowId; + parentInExtMode = false; + webNamespace = "g42_core_web"; + parent; + parentType; + parentPingTimeout = 5000; + connectionRequestTimeout = 7000; + defaultTargetString = "*"; + registry = CallbackRegistryFactory$1(); + messages = { + connectionAccepted: { name: "connectionAccepted", handle: this.handleConnectionAccepted.bind(this) }, + connectionRejected: { name: "connectionRejected", handle: this.handleConnectionRejected.bind(this) }, + connectionRequest: { name: "connectionRequest", handle: this.handleConnectionRequest.bind(this) }, + parentReady: { + name: "parentReady", handle: () => { + } + }, + parentPing: { name: "parentPing", handle: this.handleParentPing.bind(this) }, + platformPing: { name: "platformPing", handle: this.handlePlatformPing.bind(this) }, + platformReady: { name: "platformReady", handle: this.handlePlatformReady.bind(this) }, + clientUnload: { name: "clientUnload", handle: this.handleClientUnload.bind(this) }, + manualUnload: { name: "manualUnload", handle: this.handleManualUnload.bind(this) }, + extConnectionResponse: { name: "extConnectionResponse", handle: this.handleExtConnectionResponse.bind(this) }, + extSetupRequest: { name: "extSetupRequest", handle: this.handleExtSetupRequest.bind(this) }, + gatewayDisconnect: { name: "gatewayDisconnect", handle: this.handleGatewayDisconnect.bind(this) }, + gatewayInternalConnect: { name: "gatewayInternalConnect", handle: this.handleGatewayInternalConnect.bind(this) } + }; + constructor(settings, logger, identity) { + this.settings = settings; + this.logger = logger; + this.identity = identity; + this.extContentAvailable = !!window.glue42ext; + this.setUpMessageListener(); + this.setUpUnload(); + this.setupPlatformUnloadListener(); + this.parentType = window.name.includes("#wsp") ? "workspace" : undefined; + } + manualSetReadyState() { + this.iAmConnected = true; + this.parentReady = true; + } + get transportWindowId() { + return this.publicWindowId; + } + get communicationId() { + return this._communicationId; + } + async sendObject(msg) { + if (this.extContentConnected) { + return window.postMessage({ glue42ExtOut: msg }, this.defaultTargetString); + } + if (!this.port) { + throw new Error("Cannot send message, because the port was not opened yet"); + } + this.port.postMessage(msg); + } + get isObjectBasedTransport() { + return true; + } + onMessage(callback) { + return this.registry.add("onMessage", callback); + } + send() { + return Promise.reject("not supported"); + } + onConnectedChanged(callback) { + return this.registry.add("onConnectedChanged", callback); + } + async open() { + this.logger.debug("opening a connection to the web platform gateway."); + await this.connect(); + this.notifyStatusChanged(true); + } + close() { + const message = { + glue42core: { + type: this.messages.gatewayDisconnect.name, + data: { + clientId: this.myClientId, + ownWindowId: this.identity?.windowId + } + } + }; + this.port?.postMessage(message); + this.parentReady = false; + this.notifyStatusChanged(false, "manual reconnection"); + return Promise.resolve(); + } + name() { + return "web-platform"; + } + async reconnect() { + await this.close(); + return Promise.resolve(); + } + initiateInternalConnection() { + return new Promise((resolve, reject) => { + this.logger.debug("opening an internal web platform connection"); + this.port = this.settings.port; + if (this.iAmConnected) { + this.logger.warn("cannot open a new connection, because this client is currently connected"); + return; + } + this.port.onmessage = (event) => { + if (this.iAmConnected && !event.data?.glue42core) { + this.registry.execute("onMessage", event.data); + return; + } + const data = event.data?.glue42core; + if (!data) { + return; + } + if (data.type === this.messages.gatewayInternalConnect.name && data.success) { + this.publicWindowId = this.settings.windowId; + if (this.identity && this.publicWindowId) { + this.identity.windowId = this.publicWindowId; + this.identity.instance = this.publicWindowId; + } + resolve(); + } + if (data.type === this.messages.gatewayInternalConnect.name && data.error) { + reject(data.error); + } + }; + this.port.postMessage({ + glue42core: { + type: this.messages.gatewayInternalConnect.name + } + }); + }); + } + initiateRemoteConnection(target) { + return PromisePlus$1((resolve, reject) => { + this.connectionResolve = resolve; + this.connectionReject = reject; + this.myClientId = this.myClientId ?? nanoid$1(10); + const bridgeInstanceId = this.getMyWindowId() || nanoid$1(10); + const request = { + glue42core: { + type: this.messages.connectionRequest.name, + clientId: this.myClientId, + clientType: "child", + bridgeInstanceId, + selfAssignedWindowId: this.selfAssignedWindowId + } + }; + this.logger.debug("sending connection request"); + if (this.extContentConnecting) { + request.glue42core.clientType = "child"; + request.glue42core.bridgeInstanceId = this.myClientId; + request.glue42core.parentWindowId = this.parentWindowId; + return window.postMessage(request, this.defaultTargetString); + } + if (!target) { + throw new Error("Cannot send a connection request, because no glue target was specified!"); + } + target.postMessage(request, this.defaultTargetString); + }, this.connectionRequestTimeout, "The connection to the target glue window timed out"); + } + async isParentCheckSuccess(parentCheck) { + try { + await parentCheck; + return { success: true }; + } + catch (error) { + return { success: false }; + } + } + setUpMessageListener() { + if (this.settings.port) { + this.logger.debug("skipping generic message listener, because this is an internal client"); + return; + } + window.addEventListener("message", (event) => { + const data = event.data?.glue42core; + if (!data || this.rejected) { + return; + } + const allowedOrigins = this.settings.allowedOrigins || []; + if (allowedOrigins.length && !allowedOrigins.includes(event.origin)) { + this.logger.warn(`received a message from an origin which is not in the allowed list: ${event.origin}`); + return; + } + if (!this.checkMessageTypeValid(data.type)) { + this.logger.error(`cannot handle the incoming glue42 core message, because the type is invalid: ${data.type}`); + return; + } + const messageType = data.type; + this.logger.debug(`received valid glue42core message of type: ${messageType}`); + this.messages[messageType].handle(event); + }); + } + setUpUnload() { + if (this.settings.port) { + this.logger.debug("skipping unload event listener, because this is an internal client"); + return; + } + window.addEventListener("beforeunload", () => { + if (this.extContentConnected) { + return; + } + const message = { + glue42core: { + type: this.messages.clientUnload.name, + data: { + clientId: this.myClientId, + ownWindowId: this.identity?.windowId + } + } + }; + if (this.parent) { + this.parent.postMessage(message, this.defaultTargetString); + } + this.port?.postMessage(message); + }); + } + handlePlatformReady(event) { + this.logger.debug("the web platform gave the ready signal"); + this.parentReady = true; + if (this.parentPingResolve) { + this.parentPingResolve(); + delete this.parentPingResolve; + } + if (this.parentPingInterval) { + clearInterval(this.parentPingInterval); + delete this.parentPingInterval; + } + this.parent = event.source; + this.parentType = window.name.includes("#wsp") ? "workspace" : "window"; + } + handleConnectionAccepted(event) { + const data = event.data?.glue42core; + if (this.myClientId === data.clientId) { + return this.handleAcceptanceOfMyRequest(data); + } + return this.handleAcceptanceOfGrandChildRequest(data, event); + } + handleAcceptanceOfMyRequest(data) { + this.logger.debug("handling a connection accepted signal targeted at me."); + this.isPreferredActivated = data.isPreferredActivated; + if (this.extContentConnecting) { + return this.processExtContentConnection(data); + } + if (!data.port) { + this.logger.error("cannot set up my connection, because I was not provided with a port"); + return; + } + this.publicWindowId = this.getMyWindowId(); + if (this.identity) { + this.identity.windowId = this.publicWindowId; + this.identity.instance = this.identity.instance ? this.identity.instance : this.publicWindowId || nanoid$1(10); + } + if (this.identity && data.appName) { + this.identity.application = data.appName; + this.identity.applicationName = data.appName; + } + this._communicationId = data.communicationId; + this.port = data.port; + this.port.onmessage = (e) => this.registry.execute("onMessage", e.data); + if (this.connectionResolve) { + this.logger.debug("my connection is set up, calling the connection resolve."); + this.connectionResolve(); + delete this.connectionResolve; + return; + } + this.logger.error("unable to call the connection resolve, because no connection promise was found"); + } + processExtContentConnection(data) { + this.logger.debug("handling a connection accepted signal targeted at me for extension content connection."); + this.extContentConnecting = false; + this.extContentConnected = true; + this.publicWindowId = this.parentWindowId || this.myClientId; + if (this.extContentConnecting && this.identity) { + this.identity.windowId = this.publicWindowId; + } + if (this.identity && data.appName) { + this.identity.application = data.appName; + this.identity.applicationName = data.appName; + } + window.addEventListener("message", (event) => { + const extData = event.data?.glue42ExtInc; + if (!extData) { + return; + } + const allowedOrigins = this.settings.allowedOrigins || []; + if (allowedOrigins.length && !allowedOrigins.includes(event.origin)) { + this.logger.warn(`received a message from an origin which is not in the allowed list: ${event.origin}`); + return; + } + this.registry.execute("onMessage", extData); + }); + if (this.connectionResolve) { + this.logger.debug("my connection is set up, calling the connection resolve."); + this.connectionResolve(); + delete this.connectionResolve; + return; + } + } + handleAcceptanceOfGrandChildRequest(data, event) { + if (this.extContentConnecting || this.extContentConnected) { + this.logger.debug("cannot process acceptance of a grandchild, because I am connected to a content script"); + return; + } + this.logger.debug(`handling a connection accepted signal targeted at a grandchild: ${data.clientId}`); + const child = this.children.find((c) => c.grandChildId === data.clientId); + if (!child) { + this.logger.error(`cannot handle connection accepted for grandchild: ${data.clientId}, because there is no grandchild with this id`); + return; + } + child.connected = true; + this.logger.debug(`the grandchild connection for ${data.clientId} is set up, forwarding the success message and the gateway port`); + data.parentWindowId = this.publicWindowId; + child.source.postMessage(event.data, child.origin, [data.port]); + return; + } + handleConnectionRejected(event) { + this.logger.debug("handling a connection rejection. Most likely the reason is that this window was not created by a glue API call"); + if (!this.connectionReject) { + return; + } + const errorMsg = typeof event.data.glue42core?.error === "string" + ? `Connection was rejected. ${event.data.glue42core?.error}` + : "The platform connection was rejected. Most likely because this window was not created by a glue API call"; + this.connectionReject(errorMsg); + delete this.connectionReject; + } + handleConnectionRequest(event) { + if (this.extContentConnecting) { + this.logger.debug("This connection request event is targeted at the extension content"); + return; + } + const source = event.source; + const data = event.data.glue42core; + if (!data.clientType || data.clientType !== "grandChild") { + return this.rejectConnectionRequest(source, event.origin, "rejecting a connection request, because the source was not opened by a glue API call"); + } + if (!data.clientId) { + return this.rejectConnectionRequest(source, event.origin, "rejecting a connection request, because the source did not provide a valid id"); + } + if (!this.parent) { + return this.rejectConnectionRequest(source, event.origin, "Cannot forward the connection request, because no direct connection to the platform was found"); + } + this.logger.debug(`handling a connection request for a grandchild: ${data.clientId}`); + this.children.push({ grandChildId: data.clientId, source, connected: false, origin: event.origin }); + this.logger.debug(`grandchild: ${data.clientId} is prepared, forwarding connection request to the platform`); + this.parent.postMessage(event.data, this.defaultTargetString); + } + handleParentPing(event) { + if (!this.parentReady) { + this.logger.debug("my parent is not ready, I am ignoring the parent ping"); + return; + } + if (!this.iAmConnected) { + this.logger.debug("i am not fully connected yet, I am ignoring the parent ping"); + return; + } + const message = { + glue42core: { + type: this.messages.parentReady.name + } + }; + if (this.extContentConnected) { + message.glue42core.extMode = { windowId: this.myClientId }; + } + const source = event.source; + this.logger.debug("responding to a parent ping with a ready message"); + source.postMessage(message, event.origin); + } + setupPlatformUnloadListener() { + this.onMessage((msg) => { + if (msg.type === "platformUnload") { + this.logger.debug("detected a web platform unload"); + this.parentReady = false; + this.notifyStatusChanged(false, "Gateway unloaded"); + } + }); + } + handleManualUnload() { + const message = { + glue42core: { + type: this.messages.clientUnload.name, + data: { + clientId: this.myClientId, + ownWindowId: this.identity?.windowId + } + } + }; + if (this.extContentConnected) { + return window.postMessage({ glue42ExtOut: message }, this.defaultTargetString); + } + this.port?.postMessage(message); + } + handleClientUnload(event) { + const data = event.data.glue42core; + const clientId = data?.data.clientId; + if (!clientId) { + this.logger.warn("cannot process grand child unload, because the provided id was not valid"); + return; + } + const foundChild = this.children.find((child) => child.grandChildId === clientId); + if (!foundChild) { + this.logger.warn("cannot process grand child unload, because this client is unaware of this grandchild"); + return; + } + this.logger.debug(`handling grandchild unload for id: ${clientId}`); + this.children = this.children.filter((child) => child.grandChildId !== clientId); + } + handlePlatformPing() { + return; + } + notifyStatusChanged(status, reason) { + this.iAmConnected = status; + this.registry.execute("onConnectedChanged", status, reason); + } + checkMessageTypeValid(typeToValidate) { + return typeof typeToValidate === "string" && !!this.messages[typeToValidate]; + } + rejectConnectionRequest(source, origin, reason) { + this.rejected = true; + this.logger.error(reason); + const rejection = { + glue42core: { + type: this.messages.connectionRejected.name + } + }; + source.postMessage(rejection, origin); + } + requestConnectionPermissionFromExt() { + return this.waitForContentScript() + .then(() => PromisePlus$1((resolve, reject) => { + this.extConnectionResolve = resolve; + this.extConnectionReject = reject; + const message = { + glue42core: { + type: "extSetupRequest" + } + }; + this.logger.debug("permission request to the extension content script was sent"); + window.postMessage(message, this.defaultTargetString); + }, this.parentPingTimeout, "Cannot initialize glue, because this app was not opened or created by a Glue Client and the request for extension connection timed out")); + } + handleExtConnectionResponse(event) { + const data = event.data?.glue42core; + if (!data.approved) { + return this.extConnectionReject ? this.extConnectionReject("Cannot initialize glue, because this app was not opened or created by a Glue Client and the request for extension connection was rejected") : undefined; + } + if (this.extConnectionResolve) { + this.extConnectionResolve(); + delete this.extConnectionResolve; + } + this.extContentConnecting = true; + this.parentType = "extension"; + this.logger.debug("The extension connection was approved, proceeding."); + } + handleExtSetupRequest() { + return; + } + handleGatewayDisconnect() { + return; + } + handleGatewayInternalConnect() { + return; + } + waitForContentScript() { + const contentReady = !!window.glue42ext?.content; + if (contentReady) { + return Promise.resolve(); + } + return PromisePlus$1((resolve) => { + window.addEventListener("Glue42EXTReady", () => { + resolve(); + }); + }, this.connectionRequestTimeout, "The content script was available, but was never heard to be ready"); + } + async connect() { + if (this.settings.port) { + await this.initiateInternalConnection(); + this.logger.debug("internal web platform connection completed"); + return; + } + this.logger.debug("opening a client web platform connection"); + await this.findParent(); + await this.initiateRemoteConnection(this.parent); + this.logger.debug("the client is connected"); + } + async findParent() { + const connectionNotPossibleMsg = "Cannot initiate glue, because this window was not opened or created by a glue client"; + const myInsideParents = this.getPossibleParentsInWindow(window); + const myOutsideParents = this.getPossibleParentsOutsideWindow(window.top?.opener, window.top); + const uniqueParents = new Set([...myInsideParents, ...myOutsideParents]); + if (!uniqueParents.size && !this.extContentAvailable) { + throw new Error(connectionNotPossibleMsg); + } + if (!uniqueParents.size && this.extContentAvailable) { + await this.requestConnectionPermissionFromExt(); + return; + } + const defaultParentCheck = await this.isParentCheckSuccess(this.confirmParent(Array.from(uniqueParents))); + if (defaultParentCheck.success) { + this.logger.debug("The default parent was found!"); + return; + } + if (!this.extContentAvailable) { + throw new Error(connectionNotPossibleMsg); + } + await this.requestConnectionPermissionFromExt(); + } + getPossibleParentsInWindow(currentWindow) { + return (!currentWindow?.parent || currentWindow === currentWindow.parent) ? [] : [currentWindow.parent, ...this.getPossibleParentsInWindow(currentWindow.parent)]; + } + getPossibleParentsOutsideWindow(opener, current) { + return (!opener || !current || opener === current) ? [] : [opener, ...this.getPossibleParentsInWindow(opener), ...this.getPossibleParentsOutsideWindow(opener.opener, opener)]; + } + confirmParent(targets) { + const connectionNotPossibleMsg = "Cannot initiate glue, because this window was not opened or created by a glue client"; + const parentCheck = PromisePlus$1((resolve) => { + this.parentPingResolve = resolve; + const message = { + glue42core: { + type: this.messages.platformPing.name + } + }; + this.parentPingInterval = setInterval(() => { + targets.forEach((target) => { + target.postMessage(message, this.defaultTargetString); + }); + }, 1000); + }, this.parentPingTimeout, connectionNotPossibleMsg); + parentCheck.catch(() => { + if (this.parentPingInterval) { + clearInterval(this.parentPingInterval); + delete this.parentPingInterval; + } + }); + return parentCheck; + } + getMyWindowId() { + if (this.parentType === "workspace") { + return window.name.substring(0, window.name.indexOf("#wsp")); + } + if (window !== window.top) { + return; + } + if (window.name?.includes("g42")) { + return window.name; + } + this.selfAssignedWindowId = this.selfAssignedWindowId || `g42-${nanoid$1(10)}`; + return this.selfAssignedWindowId; + } + } + + const waitForInvocations = (invocations, callback) => { + let left = invocations; + return () => { + left--; + if (left === 0) { + callback(); + } + }; + }; + + class AsyncSequelizer { + minSequenceInterval; + queue = []; + isExecutingQueue = false; + constructor(minSequenceInterval = 0) { + this.minSequenceInterval = minSequenceInterval; + } + enqueue(action) { + return new Promise((resolve, reject) => { + this.queue.push({ action, resolve, reject }); + this.executeQueue(); + }); + } + async executeQueue() { + if (this.isExecutingQueue) { + return; + } + this.isExecutingQueue = true; + while (this.queue.length) { + const operation = this.queue.shift(); + if (!operation) { + this.isExecutingQueue = false; + return; + } + try { + const actionResult = await operation.action(); + operation.resolve(actionResult); + } + catch (error) { + operation.reject(error); + } + await this.intervalBreak(); + } + this.isExecutingQueue = false; + } + intervalBreak() { + return new Promise((res) => setTimeout(res, this.minSequenceInterval)); + } + } + + function domainSession (domain, connection, logger, successMessages, errorMessages) { + if (domain == null) { + domain = "global"; + } + successMessages = successMessages ?? ["success"]; + errorMessages = errorMessages ?? ["error"]; + let isJoined = domain === "global"; + let tryReconnecting = false; + let _latestOptions; + let _connectionOn = false; + const callbacks = CallbackRegistryFactory$1(); + connection.disconnected(handleConnectionDisconnected); + connection.loggedIn(handleConnectionLoggedIn); + connection.on("success", (msg) => handleSuccessMessage(msg)); + connection.on("error", (msg) => handleErrorMessage(msg)); + connection.on("result", (msg) => handleSuccessMessage(msg)); + if (successMessages) { + successMessages.forEach((sm) => { + connection.on(sm, (msg) => handleSuccessMessage(msg)); + }); + } + if (errorMessages) { + errorMessages.forEach((sm) => { + connection.on(sm, (msg) => handleErrorMessage(msg)); + }); + } + const requestsMap = {}; + function join(options) { + _latestOptions = options; + return new Promise((resolve, reject) => { + if (isJoined) { + resolve({}); + return; + } + let joinPromise; + if (domain === "global") { + joinPromise = _connectionOn ? Promise.resolve({}) : Promise.reject("not connected to gateway"); + } + else { + logger.debug(`joining domain ${domain}`); + const joinMsg = { + type: "join", + destination: domain, + domain: "global", + options, + }; + joinPromise = send(joinMsg); + } + joinPromise + .then(() => { + handleJoined(); + resolve({}); + }) + .catch((err) => { + logger.debug("error joining " + domain + " domain: " + JSON.stringify(err)); + reject(err); + }); + }); + } + function leave() { + if (domain === "global") { + return Promise.resolve(); + } + logger.debug("stopping session " + domain + "..."); + const leaveMsg = { + type: "leave", + destination: domain, + domain: "global", + }; + tryReconnecting = false; + return send(leaveMsg) + .then(() => { + isJoined = false; + callbacks.execute("onLeft"); + }) + .catch(() => { + isJoined = false; + callbacks.execute("onLeft"); + }); + } + function handleJoined() { + logger.debug("did join " + domain); + isJoined = true; + const wasReconnect = tryReconnecting; + tryReconnecting = false; + callbacks.execute("onJoined", wasReconnect); + } + function handleConnectionDisconnected() { + _connectionOn = false; + logger.debug("connection is down"); + isJoined = false; + tryReconnecting = true; + callbacks.execute("onLeft", { disconnected: true }); + } + function handleConnectionLoggedIn() { + _connectionOn = true; + if (tryReconnecting) { + logger.debug("connection is now up - trying to reconnect..."); + join(_latestOptions); + } + } + function onJoined(callback) { + if (isJoined) { + callback(false); + } + return callbacks.add("onJoined", callback); + } + function onLeft(callback) { + if (!isJoined) { + callback(); + } + return callbacks.add("onLeft", callback); + } + function handleErrorMessage(msg) { + if (domain !== msg.domain) { + return; + } + const requestId = msg.request_id; + if (!requestId) { + return; + } + const entry = requestsMap[requestId]; + if (!entry) { + return; + } + entry.error(msg); + } + function handleSuccessMessage(msg) { + if (msg.domain !== domain) { + return; + } + const requestId = msg.request_id; + if (!requestId) { + return; + } + const entry = requestsMap[requestId]; + if (!entry) { + return; + } + entry.success(msg); + } + function getNextRequestId() { + return nanoid$1(10); + } + let queuedCalls = []; + function send(msg, tag, options) { + const ignore = ["hello", "join"]; + if (msg.type && ignore.indexOf(msg.type) === -1) { + if (!isJoined) { + console.warn(`trying to send a message (${msg.domain} ${msg.type}) but not connected, will queue`); + const pw = new PromiseWrapper$1(); + queuedCalls.push({ msg, tag, options, pw }); + if (queuedCalls.length === 1) { + const unsubscribe = onJoined(() => { + logger.info(`joined - will now send queued messages (${queuedCalls.length} -> [${queuedCalls.map((m) => m.msg.type)}])`); + queuedCalls.forEach((qm) => { + send(qm.msg, qm.tag, qm.options) + .then((t) => qm.pw.resolve(t)) + .catch((e) => qm.pw.reject(e)); + }); + queuedCalls = []; + unsubscribe(); + }); + } + return pw.promise; + } + } + options = options ?? {}; + msg.request_id = msg.request_id ?? getNextRequestId(); + msg.domain = msg.domain ?? domain; + if (!options.skipPeerId) { + msg.peer_id = connection.peerId; + } + const requestId = msg.request_id; + return new Promise((resolve, reject) => { + requestsMap[requestId] = { + success: (successMsg) => { + delete requestsMap[requestId]; + successMsg._tag = tag; + resolve(successMsg); + }, + error: (errorMsg) => { + logger.warn(`Gateway error - ${JSON.stringify(errorMsg)}`); + delete requestsMap[requestId]; + errorMsg._tag = tag; + reject(errorMsg); + }, + }; + connection + .send(msg, options) + .catch((err) => { + requestsMap[requestId].error({ err }); + }); + }); + } + function sendFireAndForget(msg) { + msg.request_id = msg.request_id ? msg.request_id : getNextRequestId(); + msg.domain = msg.domain ?? domain; + msg.peer_id = connection.peerId; + return connection.send(msg); + } + return { + join, + leave, + onJoined, + onLeft, + send, + sendFireAndForget, + on: (type, callback) => { + connection.on(type, (msg) => { + if (msg.domain !== domain) { + return; + } + try { + callback(msg); + } + catch (e) { + logger.error(`Callback failed: ${e} \n ${e.stack} \n msg was: ${JSON.stringify(msg)}`, e); + } + }); + }, + loggedIn: (callback) => connection.loggedIn(callback), + connected: (callback) => connection.connected(callback), + disconnected: (callback) => connection.disconnected(callback), + get peerId() { + return connection.peerId; + }, + get domain() { + return domain; + }, + }; + } + + class Connection { + settings; + logger; + protocolVersion = 3; + peerId; + token; + info; + resolvedIdentity; + availableDomains; + gatewayToken; + replayer; + messageHandlers = {}; + ids = 1; + registry = CallbackRegistryFactory$1(); + _connected = false; + isTrace = false; + transport; + _defaultTransport; + _defaultAuth; + _targetTransport; + _targetAuth; + _swapTransport = false; + _switchInProgress = false; + _transportSubscriptions = []; + datePrefix = "#T42_DATE#"; + datePrefixLen = this.datePrefix.length; + dateMinLen = this.datePrefixLen + 1; + datePrefixFirstChar = this.datePrefix[0]; + _sequelizer = new AsyncSequelizer(); + _isLoggedIn = false; + shouldTryLogin = true; + pingTimer; + sessions = []; + globalDomain; + initialLogin = true; + initialLoginAttempts = 3; + loginConfig; + constructor(settings, logger) { + this.settings = settings; + this.logger = logger; + settings = settings || {}; + settings.reconnectAttempts = settings.reconnectAttempts ?? 10; + settings.reconnectInterval = settings.reconnectInterval ?? 1000; + if (settings.inproc) { + this.transport = new InProcTransport(settings.inproc, logger.subLogger("inMemory")); + } + else if (settings.sharedWorker) { + this.transport = new SharedWorkerTransport(settings.sharedWorker, logger.subLogger("shared-worker")); + } + else if (settings.webPlatform) { + this.transport = new WebPlatformTransport(settings.webPlatform, logger.subLogger("web-platform"), settings.identity); + } + else if (settings.ws !== undefined) { + this.transport = new WS(settings, logger.subLogger("ws")); + } + else { + throw new Error("No connection information specified"); + } + this.isTrace = logger.canPublish("trace"); + logger.debug(`starting with ${this.transport.name()} transport`); + const unsubConnectionChanged = this.transport.onConnectedChanged(this.handleConnectionChanged.bind(this)); + const unsubOnMessage = this.transport.onMessage(this.handleTransportMessage.bind(this)); + this._transportSubscriptions.push(unsubConnectionChanged); + this._transportSubscriptions.push(unsubOnMessage); + this._defaultTransport = this.transport; + this.ping(); + } + async switchTransport(settings) { + return this._sequelizer.enqueue(async () => { + if (!settings || typeof settings !== "object") { + throw new Error("Cannot switch transports, because the settings are missing or invalid."); + } + if (typeof settings.type === "undefined") { + throw new Error("Cannot switch the transport, because the type is not defined"); + } + this.logger.trace(`Starting transport switch with settings: ${JSON.stringify(settings)}`); + const switchTargetTransport = settings.type === "secondary" ? this.getNewSecondaryTransport(settings) : this._defaultTransport; + this._targetTransport = switchTargetTransport; + this._targetAuth = settings.type === "secondary" ? this.getNewSecondaryAuth(settings) : this._defaultAuth; + const verifyPromise = this.verifyConnection(); + this._swapTransport = true; + this._switchInProgress = true; + this.logger.trace("The new transport has been set, closing the current transport"); + await this.transport.close(); + try { + await verifyPromise; + const isSwitchSuccess = this.transport === switchTargetTransport; + this.logger.info(`The reconnection after the switch was completed. Was the switch a success: ${isSwitchSuccess}`); + this._switchInProgress = false; + return { success: isSwitchSuccess }; + } + catch (error) { + this.logger.info("The reconnection after the switch timed out, reverting back to the default transport."); + this.switchTransport({ type: "default" }); + this._switchInProgress = false; + return { success: false }; + } + }); + } + onLibReAnnounced(callback) { + return this.registry.add("libReAnnounced", callback); + } + setLibReAnnounced(lib) { + this.registry.execute("libReAnnounced", lib); + } + send(message, options) { + if (this.transport.sendObject && + this.transport.isObjectBasedTransport) { + const msg = this.createObjectMessage(message); + if (this.isTrace) { + this.logger.trace(`>> ${JSON.stringify(msg)}`); + } + return this.transport.sendObject(msg, options); + } + else { + const strMessage = this.createStringMessage(message); + if (this.isTrace) { + this.logger.trace(`>> ${strMessage}`); + } + return this.transport.send(strMessage, options); + } + } + on(type, messageHandler) { + type = type.toLowerCase(); + if (this.messageHandlers[type] === undefined) { + this.messageHandlers[type] = {}; + } + const id = this.ids++; + this.messageHandlers[type][id] = messageHandler; + return { + type, + id, + }; + } + off(info) { + delete this.messageHandlers[info.type.toLowerCase()][info.id]; + } + get isConnected() { + return this._isLoggedIn; + } + connected(callback) { + return this.loggedIn(() => { + const currentServer = this.transport.name(); + callback(currentServer); + }); + } + disconnected(callback) { + return this.registry.add("disconnected", callback); + } + async login(authRequest, reconnect) { + if (!this._defaultAuth) { + this._defaultAuth = authRequest; + } + if (this._swapTransport) { + this.logger.trace("Detected a transport swap, swapping transports"); + const newAuth = this.transportSwap(); + authRequest = newAuth ?? authRequest; + } + this.logger.trace(`Starting login for transport: ${this.transport.name()} and auth ${JSON.stringify(authRequest)}`); + try { + await this.transport.open(); + this.logger.trace(`Transport: ${this.transport.name()} opened, logging in`); + timer("connection").mark("transport-opened"); + const identity = await this.loginCore(authRequest, reconnect); + this.logger.trace(`Logged in with identity: ${JSON.stringify(identity)}`); + timer("connection").mark("protocol-logged-in"); + return identity; + } + catch (error) { + if (this._switchInProgress) { + this.logger.trace("An error while logging in after a transport swap, preparing a default swap."); + this.prepareDefaultSwap(); + } + throw new Error(error); + } + } + async logout() { + await this.logoutCore(); + await this.transport.close(); + } + loggedIn(callback) { + if (this._isLoggedIn) { + callback(); + } + return this.registry.add("onLoggedIn", callback); + } + domain(domain, successMessages, errorMessages) { + let session = this.sessions.find((s) => s.domain === domain); + if (!session) { + session = domainSession(domain, this, this.logger.subLogger(`domain=${domain}`), successMessages, errorMessages); + this.sessions.push(session); + } + return session; + } + authToken() { + const createTokenReq = { + domain: "global", + type: "create-token" + }; + if (!this.globalDomain) { + return Promise.reject(new Error("no global domain session")); + } + return this.globalDomain.send(createTokenReq) + .then((res) => { + return res.token; + }); + } + reconnect() { + return this.transport.reconnect(); + } + setLoggedIn(value) { + this._isLoggedIn = value; + if (this._isLoggedIn) { + this.registry.execute("onLoggedIn"); + } + } + distributeMessage(message, type) { + const handlers = this.messageHandlers[type.toLowerCase()]; + if (handlers !== undefined) { + Object.keys(handlers).forEach((handlerId) => { + const handler = handlers[handlerId]; + if (handler !== undefined) { + try { + handler(message); + } + catch (error) { + try { + this.logger.error(`Message handler failed with ${error.stack}`, error); + } + catch (loggerError) { + console.log("Message handler failed", error); + } + } + } + }); + } + } + handleConnectionChanged(connected) { + if (this._connected === connected) { + return; + } + this._connected = connected; + if (connected) { + if (this.settings?.replaySpecs?.length) { + this.replayer = new MessageReplayerImpl(this.settings.replaySpecs); + this.replayer.init(this); + } + this.registry.execute("connected"); + } + else { + this.handleDisconnected(); + this.registry.execute("disconnected"); + } + } + handleDisconnected() { + this.setLoggedIn(false); + const tryToLogin = this.shouldTryLogin; + if (tryToLogin && this.initialLogin) { + if (this.initialLoginAttempts <= 0) { + return; + } + this.initialLoginAttempts--; + } + this.logger.debug("disconnected - will try new login?" + this.shouldTryLogin); + if (this.shouldTryLogin) { + if (!this.loginConfig) { + throw new Error("no login info"); + } + this.login(this.loginConfig, true) + .catch(() => { + setTimeout(this.handleDisconnected.bind(this), this.settings.reconnectInterval || 1000); + }); + } + } + handleTransportMessage(msg) { + let msgObj; + if (typeof msg === "string") { + msgObj = this.processStringMessage(msg); + } + else { + msgObj = this.processObjectMessage(msg); + } + if (this.isTrace) { + this.logger.trace(`<< ${JSON.stringify(msgObj)}`); + } + this.distributeMessage(msgObj.msg, msgObj.msgType); + } + verifyConnection() { + return PromisePlus$1((resolve) => { + let unsub; + const ready = waitForInvocations(2, () => { + if (unsub) { + unsub(); + } + resolve(); + }); + unsub = this.onLibReAnnounced((lib) => { + if (lib.name === "interop") { + return ready(); + } + if (lib.name === "contexts") { + return ready(); + } + }); + }, 10000, "Transport switch timed out waiting for all libraries to be re-announced"); + } + getNewSecondaryTransport(settings) { + if (!settings.transportConfig?.url) { + throw new Error("Missing secondary transport URL."); + } + return new WS(Object.assign({}, this.settings, { ws: settings.transportConfig.url, reconnectAttempts: 1 }), this.logger.subLogger("ws-secondary")); + } + getNewSecondaryAuth(settings) { + if (!settings.transportConfig?.auth) { + throw new Error("Missing secondary transport auth information."); + } + return settings.transportConfig.auth; + } + transportSwap() { + this._swapTransport = false; + if (!this._targetTransport || !this._targetAuth) { + this.logger.warn(`Error while switching transports - either the target transport or auth is not defined: transport defined -> ${!!this._defaultTransport}, auth defined -> ${!!this._targetAuth}. Staying on the current one.`); + return; + } + this._transportSubscriptions.forEach((unsub) => unsub()); + this._transportSubscriptions = []; + this.transport = this._targetTransport; + const unsubConnectionChanged = this.transport.onConnectedChanged(this.handleConnectionChanged.bind(this)); + const unsubOnMessage = this.transport.onMessage(this.handleTransportMessage.bind(this)); + this._transportSubscriptions.push(unsubConnectionChanged); + this._transportSubscriptions.push(unsubOnMessage); + return this._targetAuth; + } + prepareDefaultSwap() { + this._transportSubscriptions.forEach((unsub) => unsub()); + this._transportSubscriptions = []; + this.transport.close().catch((error) => this.logger.warn(`Error closing the ${this.transport.name()} transport after a failed connection attempt: ${JSON.stringify(error)}`)); + this._targetTransport = this._defaultTransport; + this._targetAuth = this._defaultAuth; + this._swapTransport = true; + } + processStringMessage(message) { + const msg = JSON.parse(message, (key, value) => { + if (typeof value !== "string") { + return value; + } + if (value.length < this.dateMinLen) { + return value; + } + if (!value.startsWith(this.datePrefixFirstChar)) { + return value; + } + if (value.substring(0, this.datePrefixLen) !== this.datePrefix) { + return value; + } + try { + const milliseconds = parseInt(value.substring(this.datePrefixLen, value.length), 10); + if (isNaN(milliseconds)) { + return value; + } + return new Date(milliseconds); + } + catch (ex) { + return value; + } + }); + return { + msg, + msgType: msg.type, + }; + } + createStringMessage(message) { + const oldToJson = Date.prototype.toJSON; + try { + const datePrefix = this.datePrefix; + Date.prototype.toJSON = function () { + return datePrefix + this.getTime(); + }; + const result = JSON.stringify(message); + return result; + } + finally { + Date.prototype.toJSON = oldToJson; + } + } + processObjectMessage(message) { + if (!message.type) { + throw new Error("Object should have type property"); + } + return { + msg: message, + msgType: message.type, + }; + } + createObjectMessage(message) { + return message; + } + async loginCore(config, reconnect) { + this.logger.info("logging in..."); + this.loginConfig = config; + if (!this.loginConfig) { + this.loginConfig = { username: "", password: "" }; + } + this.shouldTryLogin = true; + const authentication = await this.setupAuthConfig(config, reconnect); + const helloMsg = { + type: "hello", + identity: this.settings.identity, + authentication + }; + if (config.sessionId) { + helloMsg.request_id = config.sessionId; + } + this.globalDomain = domainSession("global", this, this.logger.subLogger("global-domain"), [ + "welcome", + "token", + "authentication-request" + ]); + const sendOptions = { skipPeerId: true }; + if (this.initialLogin) { + sendOptions.retryInterval = this.settings.reconnectInterval; + sendOptions.maxRetries = this.settings.reconnectAttempts; + } + try { + const welcomeMsg = await this.tryAuthenticate(this.globalDomain, helloMsg, sendOptions, config); + this.initialLogin = false; + this.logger.info("login successful with peerId " + welcomeMsg.peer_id); + this.peerId = welcomeMsg.peer_id; + this.resolvedIdentity = welcomeMsg.resolved_identity; + this.availableDomains = welcomeMsg.available_domains; + if (welcomeMsg.options) { + this.token = welcomeMsg.options.access_token; + this.info = welcomeMsg.options.info; + } + this.setLoggedIn(true); + return welcomeMsg.resolved_identity; + } + catch (err) { + this.logger.error("error sending hello message - " + (err.message || err.msg || err.reason || err), err); + throw err; + } + finally { + if (config?.flowCallback && config.sessionId) { + config.flowCallback(config.sessionId, null); + } + } + } + async tryAuthenticate(globalDomain, helloMsg, sendOptions, config) { + let welcomeMsg; + while (true) { + const msg = await globalDomain.send(helloMsg, undefined, sendOptions); + if (msg.type === "authentication-request") { + const token = Buffer.from(msg.authentication.token, "base64"); + if (config.flowCallback && config.sessionId) { + helloMsg.authentication.token = + (await config.flowCallback(config.sessionId, token)) + .data + .toString("base64"); + } + helloMsg.request_id = config.sessionId; + } + else if (msg.type === "welcome") { + welcomeMsg = msg; + break; + } + else if (msg.type === "error") { + throw new Error("Authentication failed: " + msg.reason); + } + else { + throw new Error("Unexpected message type during authentication: " + msg.type); + } + } + return welcomeMsg; + } + async setupAuthConfig(config, reconnect) { + const authentication = {}; + this.gatewayToken = config.gatewayToken; + if (config.gatewayToken) { + if (reconnect) { + try { + config.gatewayToken = await this.getNewGWToken(); + } + catch (e) { + this.logger.warn(`failed to get GW token when reconnecting ${e?.message || e}`); + } + } + authentication.method = "gateway-token"; + authentication.token = config.gatewayToken; + this.gatewayToken = config.gatewayToken; + } + else if (config.flowName === "sspi") { + authentication.provider = "win"; + authentication.method = "access-token"; + if (config.flowCallback && config.sessionId) { + authentication.token = + (await config.flowCallback(config.sessionId, null)) + .data + .toString("base64"); + } + else { + throw new Error("Invalid SSPI config"); + } + } + else if (config.token) { + authentication.method = "access-token"; + authentication.token = config.token; + } + else if (config.username) { + authentication.method = "secret"; + authentication.login = config.username; + authentication.secret = config.password; + } + else if (config.provider) { + authentication.provider = config.provider; + authentication.providerContext = config.providerContext; + } + else { + throw new Error("invalid auth message" + JSON.stringify(config)); + } + return authentication; + } + async logoutCore() { + this.logger.debug("logging out..."); + this.shouldTryLogin = false; + if (this.pingTimer) { + clearTimeout(this.pingTimer); + } + const promises = this.sessions.map((session) => { + session.leave(); + }); + await Promise.all(promises); + } + getNewGWToken() { + if (typeof window !== "undefined") { + const glue42gd = window.glue42gd; + if (glue42gd) { + return glue42gd.getGWToken(); + } + } + return Promise.reject(new Error("not running in GD")); + } + ping() { + if (!this.shouldTryLogin) { + return; + } + if (this._isLoggedIn) { + this.send({ type: "ping" }); + } + this.pingTimer = setTimeout(() => { + this.ping(); + }, 30 * 1000); + } + } + + const order = ["trace", "debug", "info", "warn", "error", "off"]; + let Logger$1 = class Logger { + name; + parent; + static Interop; + static InteropMethodName = "T42.AppLogger.Log"; + static Instance; + path; + subLoggers = []; + _consoleLevel; + _publishLevel; + loggerFullName; + includeTimeAndLevel; + logFn = console; + customLogFn = false; + constructor(name, parent, logFn) { + this.name = name; + this.parent = parent; + this.name = name; + if (parent) { + this.path = `${parent.path}.${name}`; + } + else { + this.path = name; + } + this.loggerFullName = `[${this.path}]`; + this.includeTimeAndLevel = !logFn; + if (logFn) { + this.logFn = logFn; + this.customLogFn = true; + } + } + subLogger(name) { + const existingSub = this.subLoggers.filter((subLogger) => { + return subLogger.name === name; + })[0]; + if (existingSub !== undefined) { + return existingSub; + } + Object.keys(this).forEach((key) => { + if (key === name) { + throw new Error("This sub logger name is not allowed."); + } + }); + const sub = new Logger(name, this, this.customLogFn ? this.logFn : undefined); + this.subLoggers.push(sub); + return sub; + } + publishLevel(level) { + if (level) { + this._publishLevel = level; + } + return this._publishLevel || this.parent?.publishLevel(); + } + consoleLevel(level) { + if (level) { + this._consoleLevel = level; + } + return this._consoleLevel || this.parent?.consoleLevel(); + } + log(message, level, error) { + this.publishMessage(level || "info", message, error); + } + trace(message) { + this.log(message, "trace"); + } + debug(message) { + this.log(message, "debug"); + } + info(message) { + this.log(message, "info"); + } + warn(message) { + this.log(message, "warn"); + } + error(message, err) { + this.log(message, "error", err); + } + canPublish(level, compareWith) { + const levelIdx = order.indexOf(level); + const restrictionIdx = order.indexOf(compareWith || this.consoleLevel() || "trace"); + return levelIdx >= restrictionIdx; + } + publishMessage(level, message, error) { + const loggerName = this.loggerFullName; + if (level === "error" && !error) { + const e = new Error(); + if (e.stack) { + message = + message + + "\n" + + e.stack + .split("\n") + .slice(4) + .join("\n"); + } + } + if (this.canPublish(level, this.publishLevel())) { + const interop = Logger.Interop; + if (interop) { + try { + if (interop.methods({ name: Logger.InteropMethodName }).length > 0) { + const args = { + msg: message, + logger: loggerName, + level + }; + if (error && error instanceof Error) { + args.error = { + message: error.message, + stack: error.stack ?? "" + }; + } + interop.invoke(Logger.InteropMethodName, args); + } + } + catch { + } + } + } + if (this.canPublish(level)) { + let prefix = ""; + if (this.includeTimeAndLevel) { + const date = new Date(); + const time = `${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}:${date.getMilliseconds()}`; + prefix = `[${time}] [${level}] `; + } + const toPrint = `${prefix}${loggerName}: ${message}`; + switch (level) { + case "trace": + this.logFn.debug(toPrint); + break; + case "debug": + if (this.logFn.debug) { + this.logFn.debug(toPrint); + } + else { + this.logFn.log(toPrint); + } + break; + case "info": + this.logFn.info(toPrint); + break; + case "warn": + this.logFn.warn(toPrint); + break; + case "error": + this.logFn.error(toPrint, error); + break; + } + } + } + }; + + const GW_MESSAGE_CREATE_CONTEXT = "create-context"; + const GW_MESSAGE_ACTIVITY_CREATED = "created"; + const GW_MESSAGE_ACTIVITY_DESTROYED = "destroyed"; + const GW_MESSAGE_CONTEXT_CREATED = "context-created"; + const GW_MESSAGE_CONTEXT_ADDED = "context-added"; + const GW_MESSAGE_SUBSCRIBE_CONTEXT = "subscribe-context"; + const GW_MESSAGE_SUBSCRIBED_CONTEXT = "subscribed-context"; + const GW_MESSAGE_UNSUBSCRIBE_CONTEXT = "unsubscribe-context"; + const GW_MESSAGE_DESTROY_CONTEXT = "destroy-context"; + const GW_MESSAGE_CONTEXT_DESTROYED = "context-destroyed"; + const GW_MESSAGE_UPDATE_CONTEXT = "update-context"; + const GW_MESSAGE_CONTEXT_UPDATED = "context-updated"; + const GW_MESSAGE_JOINED_ACTIVITY = "joined"; + + const ContextMessageReplaySpec = { + get name() { + return "context"; + }, + get types() { + return [ + GW_MESSAGE_CREATE_CONTEXT, + GW_MESSAGE_ACTIVITY_CREATED, + GW_MESSAGE_ACTIVITY_DESTROYED, + GW_MESSAGE_CONTEXT_CREATED, + GW_MESSAGE_CONTEXT_ADDED, + GW_MESSAGE_SUBSCRIBE_CONTEXT, + GW_MESSAGE_SUBSCRIBED_CONTEXT, + GW_MESSAGE_UNSUBSCRIBE_CONTEXT, + GW_MESSAGE_DESTROY_CONTEXT, + GW_MESSAGE_CONTEXT_DESTROYED, + GW_MESSAGE_UPDATE_CONTEXT, + GW_MESSAGE_CONTEXT_UPDATED, + GW_MESSAGE_JOINED_ACTIVITY + ]; + } + }; + + var version$1 = "6.5.2-fmr-beta"; + + function prepareConfig$1 (configuration, ext, glue42gd) { + let nodeStartingContext; + if (Utils$1.isNode()) { + const startingContextString = process.env._GD_STARTING_CONTEXT_; + if (startingContextString) { + try { + nodeStartingContext = JSON.parse(startingContextString); + } + catch { + } + } + } + function getConnection() { + const gwConfig = configuration.gateway; + const protocolVersion = gwConfig?.protocolVersion ?? 3; + const reconnectInterval = gwConfig?.reconnectInterval; + const reconnectAttempts = gwConfig?.reconnectAttempts; + const defaultWs = "ws://localhost:8385"; + let ws = gwConfig?.ws; + const sharedWorker = gwConfig?.sharedWorker; + const inproc = gwConfig?.inproc; + const webPlatform = gwConfig?.webPlatform ?? undefined; + if (glue42gd) { + ws = glue42gd.gwURL; + } + if (Utils$1.isNode() && nodeStartingContext && nodeStartingContext.gwURL) { + ws = nodeStartingContext.gwURL; + } + if (!ws && !sharedWorker && !inproc) { + ws = defaultWs; + } + let instanceId; + let windowId; + let pid; + let environment; + let region; + const appName = getApplication(); + let uniqueAppName = appName; + if (typeof glue42gd !== "undefined") { + windowId = glue42gd.windowId; + pid = glue42gd.pid; + if (glue42gd.env) { + environment = glue42gd.env.env; + region = glue42gd.env.region; + } + uniqueAppName = glue42gd.application ?? "glue-app"; + instanceId = glue42gd.appInstanceId; + } + else if (Utils$1.isNode()) { + pid = process.pid; + if (nodeStartingContext) { + environment = nodeStartingContext.env; + region = nodeStartingContext.region; + instanceId = nodeStartingContext.instanceId; + } + } + else if (typeof window?.glue42electron !== "undefined") { + windowId = window?.glue42electron.instanceId; + pid = window?.glue42electron.pid; + environment = window?.glue42electron.env; + region = window?.glue42electron.region; + uniqueAppName = window?.glue42electron.application ?? "glue-app"; + instanceId = window?.glue42electron.instanceId; + } + else ; + const replaySpecs = configuration.gateway?.replaySpecs ?? []; + replaySpecs.push(ContextMessageReplaySpec); + let identity = { + application: uniqueAppName, + applicationName: appName, + windowId, + instance: instanceId, + process: pid, + region, + environment, + api: ext.version || version$1 + }; + if (configuration.identity) { + identity = Object.assign(identity, configuration.identity); + } + return { + identity, + reconnectInterval, + ws, + sharedWorker, + webPlatform, + inproc, + protocolVersion, + reconnectAttempts, + replaySpecs, + }; + } + function getContexts() { + if (typeof configuration.contexts === "undefined") { + return { reAnnounceKnownContexts: true }; + } + if (typeof configuration.contexts === "boolean" && configuration.contexts) { + return { reAnnounceKnownContexts: true }; + } + if (typeof configuration.contexts === "object") { + return Object.assign({}, { reAnnounceKnownContexts: true }, configuration.contexts); + } + return false; + } + function getApplication() { + if (configuration.application) { + return configuration.application; + } + if (glue42gd) { + return glue42gd.applicationName; + } + if (typeof window !== "undefined" && typeof window.glue42electron !== "undefined") { + return window.glue42electron.application; + } + const uid = nanoid$1(10); + if (Utils$1.isNode()) { + if (nodeStartingContext) { + return nodeStartingContext.applicationConfig.name; + } + return "NodeJS" + uid; + } + if (typeof window !== "undefined" && typeof document !== "undefined") { + return document.title + ` (${uid})`; + } + return uid; + } + function getAuth() { + if (typeof configuration.auth === "string") { + return { + token: configuration.auth + }; + } + if (configuration.auth) { + return configuration.auth; + } + if (Utils$1.isNode() && nodeStartingContext && nodeStartingContext.gwToken) { + return { + gatewayToken: nodeStartingContext.gwToken + }; + } + if (configuration.gateway?.webPlatform || configuration.gateway?.inproc || configuration.gateway?.sharedWorker) { + return { + username: "glue42", password: "glue42" + }; + } + } + function getLogger() { + let config = configuration.logger; + const defaultLevel = "warn"; + if (!config) { + config = defaultLevel; + } + let gdConsoleLevel; + if (glue42gd) { + gdConsoleLevel = glue42gd.consoleLogLevel; + } + if (typeof config === "string") { + return { console: gdConsoleLevel ?? config, publish: defaultLevel }; + } + return { + console: gdConsoleLevel ?? config.console ?? defaultLevel, + publish: config.publish ?? defaultLevel + }; + } + const connection = getConnection(); + let application = getApplication(); + if (typeof window !== "undefined") { + const windowAsAny = window; + const containerApplication = windowAsAny.htmlContainer ? + `${windowAsAny.htmlContainer.containerName}.${windowAsAny.htmlContainer.application}` : + windowAsAny?.glue42gd?.application; + if (containerApplication) { + application = containerApplication; + } + } + return { + bus: configuration.bus ?? false, + application, + auth: getAuth(), + logger: getLogger(), + connection, + metrics: configuration.metrics ?? true, + contexts: getContexts(), + version: ext.version || version$1, + libs: ext.libs ?? [], + customLogger: configuration.customLogger + }; + } + + class GW3ContextData { + name; + contextId; + context; + isAnnounced; + joinedActivity; + updateCallbacks = {}; + activityId; + sentExplicitSubscription; + hasReceivedSnapshot; + constructor(contextId, name, isAnnounced, activityId) { + this.contextId = contextId; + this.name = name; + this.isAnnounced = isAnnounced; + this.activityId = activityId; + this.context = {}; + } + hasCallbacks() { + return Object.keys(this.updateCallbacks).length > 0; + } + getState() { + if (this.isAnnounced && this.hasCallbacks()) { + return 3; + } + if (this.isAnnounced) { + return 2; + } + if (this.hasCallbacks()) { + return 1; + } + return 0; + } + } + + var lodash_clonedeep = {exports: {}}; + + /** + * lodash (Custom Build) + * Build: `lodash modularize exports="npm" -o ./` + * Copyright jQuery Foundation and other contributors + * Released under MIT license + * Based on Underscore.js 1.8.3 + * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + */ + lodash_clonedeep.exports; + + (function (module, exports) { + /** Used as the size to enable large array optimizations. */ + var LARGE_ARRAY_SIZE = 200; + + /** Used to stand-in for `undefined` hash values. */ + var HASH_UNDEFINED = '__lodash_hash_undefined__'; + + /** Used as references for various `Number` constants. */ + var MAX_SAFE_INTEGER = 9007199254740991; + + /** `Object#toString` result references. */ + var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + boolTag = '[object Boolean]', + dateTag = '[object Date]', + errorTag = '[object Error]', + funcTag = '[object Function]', + genTag = '[object GeneratorFunction]', + mapTag = '[object Map]', + numberTag = '[object Number]', + objectTag = '[object Object]', + promiseTag = '[object Promise]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + symbolTag = '[object Symbol]', + weakMapTag = '[object WeakMap]'; + + var arrayBufferTag = '[object ArrayBuffer]', + dataViewTag = '[object DataView]', + float32Tag = '[object Float32Array]', + float64Tag = '[object Float64Array]', + int8Tag = '[object Int8Array]', + int16Tag = '[object Int16Array]', + int32Tag = '[object Int32Array]', + uint8Tag = '[object Uint8Array]', + uint8ClampedTag = '[object Uint8ClampedArray]', + uint16Tag = '[object Uint16Array]', + uint32Tag = '[object Uint32Array]'; + + /** + * Used to match `RegExp` + * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns). + */ + var reRegExpChar = /[\\^$.*+?()[\]{}|]/g; + + /** Used to match `RegExp` flags from their coerced string values. */ + var reFlags = /\w*$/; + + /** Used to detect host constructors (Safari). */ + var reIsHostCtor = /^\[object .+?Constructor\]$/; + + /** Used to detect unsigned integer values. */ + var reIsUint = /^(?:0|[1-9]\d*)$/; + + /** Used to identify `toStringTag` values supported by `_.clone`. */ + var cloneableTags = {}; + cloneableTags[argsTag] = cloneableTags[arrayTag] = + cloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] = + cloneableTags[boolTag] = cloneableTags[dateTag] = + cloneableTags[float32Tag] = cloneableTags[float64Tag] = + cloneableTags[int8Tag] = cloneableTags[int16Tag] = + cloneableTags[int32Tag] = cloneableTags[mapTag] = + cloneableTags[numberTag] = cloneableTags[objectTag] = + cloneableTags[regexpTag] = cloneableTags[setTag] = + cloneableTags[stringTag] = cloneableTags[symbolTag] = + cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] = + cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true; + cloneableTags[errorTag] = cloneableTags[funcTag] = + cloneableTags[weakMapTag] = false; + + /** Detect free variable `global` from Node.js. */ + var freeGlobal = typeof commonjsGlobal$1 == 'object' && commonjsGlobal$1 && commonjsGlobal$1.Object === Object && commonjsGlobal$1; + + /** Detect free variable `self`. */ + var freeSelf = typeof self == 'object' && self && self.Object === Object && self; + + /** Used as a reference to the global object. */ + var root = freeGlobal || freeSelf || Function('return this')(); + + /** Detect free variable `exports`. */ + var freeExports = exports && !exports.nodeType && exports; + + /** Detect free variable `module`. */ + var freeModule = freeExports && 'object' == 'object' && module && !module.nodeType && module; + + /** Detect the popular CommonJS extension `module.exports`. */ + var moduleExports = freeModule && freeModule.exports === freeExports; + + /** + * Adds the key-value `pair` to `map`. + * + * @private + * @param {Object} map The map to modify. + * @param {Array} pair The key-value pair to add. + * @returns {Object} Returns `map`. + */ + function addMapEntry(map, pair) { + // Don't return `map.set` because it's not chainable in IE 11. + map.set(pair[0], pair[1]); + return map; + } + + /** + * Adds `value` to `set`. + * + * @private + * @param {Object} set The set to modify. + * @param {*} value The value to add. + * @returns {Object} Returns `set`. + */ + function addSetEntry(set, value) { + // Don't return `set.add` because it's not chainable in IE 11. + set.add(value); + return set; + } + + /** + * A specialized version of `_.forEach` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns `array`. + */ + function arrayEach(array, iteratee) { + var index = -1, + length = array ? array.length : 0; + + while (++index < length) { + if (iteratee(array[index], index, array) === false) { + break; + } + } + return array; + } + + /** + * Appends the elements of `values` to `array`. + * + * @private + * @param {Array} array The array to modify. + * @param {Array} values The values to append. + * @returns {Array} Returns `array`. + */ + function arrayPush(array, values) { + var index = -1, + length = values.length, + offset = array.length; + + while (++index < length) { + array[offset + index] = values[index]; + } + return array; + } + + /** + * A specialized version of `_.reduce` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {boolean} [initAccum] Specify using the first element of `array` as + * the initial value. + * @returns {*} Returns the accumulated value. + */ + function arrayReduce(array, iteratee, accumulator, initAccum) { + var index = -1, + length = array ? array.length : 0; + while (++index < length) { + accumulator = iteratee(accumulator, array[index], index, array); + } + return accumulator; + } + + /** + * The base implementation of `_.times` without support for iteratee shorthands + * or max array length checks. + * + * @private + * @param {number} n The number of times to invoke `iteratee`. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the array of results. + */ + function baseTimes(n, iteratee) { + var index = -1, + result = Array(n); + + while (++index < n) { + result[index] = iteratee(index); + } + return result; + } + + /** + * Gets the value at `key` of `object`. + * + * @private + * @param {Object} [object] The object to query. + * @param {string} key The key of the property to get. + * @returns {*} Returns the property value. + */ + function getValue(object, key) { + return object == null ? undefined : object[key]; + } + + /** + * Checks if `value` is a host object in IE < 9. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a host object, else `false`. + */ + function isHostObject(value) { + // Many host objects are `Object` objects that can coerce to strings + // despite having improperly defined `toString` methods. + var result = false; + if (value != null && typeof value.toString != 'function') { + try { + result = !!(value + ''); + } catch (e) {} + } + return result; + } + + /** + * Converts `map` to its key-value pairs. + * + * @private + * @param {Object} map The map to convert. + * @returns {Array} Returns the key-value pairs. + */ + function mapToArray(map) { + var index = -1, + result = Array(map.size); + + map.forEach(function(value, key) { + result[++index] = [key, value]; + }); + return result; + } + + /** + * Creates a unary function that invokes `func` with its argument transformed. + * + * @private + * @param {Function} func The function to wrap. + * @param {Function} transform The argument transform. + * @returns {Function} Returns the new function. + */ + function overArg(func, transform) { + return function(arg) { + return func(transform(arg)); + }; + } + + /** + * Converts `set` to an array of its values. + * + * @private + * @param {Object} set The set to convert. + * @returns {Array} Returns the values. + */ + function setToArray(set) { + var index = -1, + result = Array(set.size); + + set.forEach(function(value) { + result[++index] = value; + }); + return result; + } + + /** Used for built-in method references. */ + var arrayProto = Array.prototype, + funcProto = Function.prototype, + objectProto = Object.prototype; + + /** Used to detect overreaching core-js shims. */ + var coreJsData = root['__core-js_shared__']; + + /** Used to detect methods masquerading as native. */ + var maskSrcKey = (function() { + var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || ''); + return uid ? ('Symbol(src)_1.' + uid) : ''; + }()); + + /** Used to resolve the decompiled source of functions. */ + var funcToString = funcProto.toString; + + /** Used to check objects for own properties. */ + var hasOwnProperty = objectProto.hasOwnProperty; + + /** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ + var objectToString = objectProto.toString; + + /** Used to detect if a method is native. */ + var reIsNative = RegExp('^' + + funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&') + .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' + ); + + /** Built-in value references. */ + var Buffer = moduleExports ? root.Buffer : undefined, + Symbol = root.Symbol, + Uint8Array = root.Uint8Array, + getPrototype = overArg(Object.getPrototypeOf, Object), + objectCreate = Object.create, + propertyIsEnumerable = objectProto.propertyIsEnumerable, + splice = arrayProto.splice; + + /* Built-in method references for those with the same name as other `lodash` methods. */ + var nativeGetSymbols = Object.getOwnPropertySymbols, + nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined, + nativeKeys = overArg(Object.keys, Object); + + /* Built-in method references that are verified to be native. */ + var DataView = getNative(root, 'DataView'), + Map = getNative(root, 'Map'), + Promise = getNative(root, 'Promise'), + Set = getNative(root, 'Set'), + WeakMap = getNative(root, 'WeakMap'), + nativeCreate = getNative(Object, 'create'); + + /** Used to detect maps, sets, and weakmaps. */ + var dataViewCtorString = toSource(DataView), + mapCtorString = toSource(Map), + promiseCtorString = toSource(Promise), + setCtorString = toSource(Set), + weakMapCtorString = toSource(WeakMap); + + /** Used to convert symbols to primitives and strings. */ + var symbolProto = Symbol ? Symbol.prototype : undefined, + symbolValueOf = symbolProto ? symbolProto.valueOf : undefined; + + /** + * Creates a hash object. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + function Hash(entries) { + var index = -1, + length = entries ? entries.length : 0; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } + } + + /** + * Removes all key-value entries from the hash. + * + * @private + * @name clear + * @memberOf Hash + */ + function hashClear() { + this.__data__ = nativeCreate ? nativeCreate(null) : {}; + } + + /** + * Removes `key` and its value from the hash. + * + * @private + * @name delete + * @memberOf Hash + * @param {Object} hash The hash to modify. + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function hashDelete(key) { + return this.has(key) && delete this.__data__[key]; + } + + /** + * Gets the hash value for `key`. + * + * @private + * @name get + * @memberOf Hash + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function hashGet(key) { + var data = this.__data__; + if (nativeCreate) { + var result = data[key]; + return result === HASH_UNDEFINED ? undefined : result; + } + return hasOwnProperty.call(data, key) ? data[key] : undefined; + } + + /** + * Checks if a hash value for `key` exists. + * + * @private + * @name has + * @memberOf Hash + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function hashHas(key) { + var data = this.__data__; + return nativeCreate ? data[key] !== undefined : hasOwnProperty.call(data, key); + } + + /** + * Sets the hash `key` to `value`. + * + * @private + * @name set + * @memberOf Hash + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the hash instance. + */ + function hashSet(key, value) { + var data = this.__data__; + data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value; + return this; + } + + // Add methods to `Hash`. + Hash.prototype.clear = hashClear; + Hash.prototype['delete'] = hashDelete; + Hash.prototype.get = hashGet; + Hash.prototype.has = hashHas; + Hash.prototype.set = hashSet; + + /** + * Creates an list cache object. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + function ListCache(entries) { + var index = -1, + length = entries ? entries.length : 0; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } + } + + /** + * Removes all key-value entries from the list cache. + * + * @private + * @name clear + * @memberOf ListCache + */ + function listCacheClear() { + this.__data__ = []; + } + + /** + * Removes `key` and its value from the list cache. + * + * @private + * @name delete + * @memberOf ListCache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function listCacheDelete(key) { + var data = this.__data__, + index = assocIndexOf(data, key); + + if (index < 0) { + return false; + } + var lastIndex = data.length - 1; + if (index == lastIndex) { + data.pop(); + } else { + splice.call(data, index, 1); + } + return true; + } + + /** + * Gets the list cache value for `key`. + * + * @private + * @name get + * @memberOf ListCache + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function listCacheGet(key) { + var data = this.__data__, + index = assocIndexOf(data, key); + + return index < 0 ? undefined : data[index][1]; + } + + /** + * Checks if a list cache value for `key` exists. + * + * @private + * @name has + * @memberOf ListCache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function listCacheHas(key) { + return assocIndexOf(this.__data__, key) > -1; + } + + /** + * Sets the list cache `key` to `value`. + * + * @private + * @name set + * @memberOf ListCache + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the list cache instance. + */ + function listCacheSet(key, value) { + var data = this.__data__, + index = assocIndexOf(data, key); + + if (index < 0) { + data.push([key, value]); + } else { + data[index][1] = value; + } + return this; + } + + // Add methods to `ListCache`. + ListCache.prototype.clear = listCacheClear; + ListCache.prototype['delete'] = listCacheDelete; + ListCache.prototype.get = listCacheGet; + ListCache.prototype.has = listCacheHas; + ListCache.prototype.set = listCacheSet; + + /** + * Creates a map cache object to store key-value pairs. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + function MapCache(entries) { + var index = -1, + length = entries ? entries.length : 0; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } + } + + /** + * Removes all key-value entries from the map. + * + * @private + * @name clear + * @memberOf MapCache + */ + function mapCacheClear() { + this.__data__ = { + 'hash': new Hash, + 'map': new (Map || ListCache), + 'string': new Hash + }; + } + + /** + * Removes `key` and its value from the map. + * + * @private + * @name delete + * @memberOf MapCache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function mapCacheDelete(key) { + return getMapData(this, key)['delete'](key); + } + + /** + * Gets the map value for `key`. + * + * @private + * @name get + * @memberOf MapCache + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function mapCacheGet(key) { + return getMapData(this, key).get(key); + } + + /** + * Checks if a map value for `key` exists. + * + * @private + * @name has + * @memberOf MapCache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function mapCacheHas(key) { + return getMapData(this, key).has(key); + } + + /** + * Sets the map `key` to `value`. + * + * @private + * @name set + * @memberOf MapCache + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the map cache instance. + */ + function mapCacheSet(key, value) { + getMapData(this, key).set(key, value); + return this; + } + + // Add methods to `MapCache`. + MapCache.prototype.clear = mapCacheClear; + MapCache.prototype['delete'] = mapCacheDelete; + MapCache.prototype.get = mapCacheGet; + MapCache.prototype.has = mapCacheHas; + MapCache.prototype.set = mapCacheSet; + + /** + * Creates a stack cache object to store key-value pairs. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + function Stack(entries) { + this.__data__ = new ListCache(entries); + } + + /** + * Removes all key-value entries from the stack. + * + * @private + * @name clear + * @memberOf Stack + */ + function stackClear() { + this.__data__ = new ListCache; + } + + /** + * Removes `key` and its value from the stack. + * + * @private + * @name delete + * @memberOf Stack + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function stackDelete(key) { + return this.__data__['delete'](key); + } + + /** + * Gets the stack value for `key`. + * + * @private + * @name get + * @memberOf Stack + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function stackGet(key) { + return this.__data__.get(key); + } + + /** + * Checks if a stack value for `key` exists. + * + * @private + * @name has + * @memberOf Stack + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function stackHas(key) { + return this.__data__.has(key); + } + + /** + * Sets the stack `key` to `value`. + * + * @private + * @name set + * @memberOf Stack + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the stack cache instance. + */ + function stackSet(key, value) { + var cache = this.__data__; + if (cache instanceof ListCache) { + var pairs = cache.__data__; + if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) { + pairs.push([key, value]); + return this; + } + cache = this.__data__ = new MapCache(pairs); + } + cache.set(key, value); + return this; + } + + // Add methods to `Stack`. + Stack.prototype.clear = stackClear; + Stack.prototype['delete'] = stackDelete; + Stack.prototype.get = stackGet; + Stack.prototype.has = stackHas; + Stack.prototype.set = stackSet; + + /** + * Creates an array of the enumerable property names of the array-like `value`. + * + * @private + * @param {*} value The value to query. + * @param {boolean} inherited Specify returning inherited property names. + * @returns {Array} Returns the array of property names. + */ + function arrayLikeKeys(value, inherited) { + // Safari 8.1 makes `arguments.callee` enumerable in strict mode. + // Safari 9 makes `arguments.length` enumerable in strict mode. + var result = (isArray(value) || isArguments(value)) + ? baseTimes(value.length, String) + : []; + + var length = result.length, + skipIndexes = !!length; + + for (var key in value) { + if ((hasOwnProperty.call(value, key)) && + !(skipIndexes && (key == 'length' || isIndex(key, length)))) { + result.push(key); + } + } + return result; + } + + /** + * Assigns `value` to `key` of `object` if the existing value is not equivalent + * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. + * + * @private + * @param {Object} object The object to modify. + * @param {string} key The key of the property to assign. + * @param {*} value The value to assign. + */ + function assignValue(object, key, value) { + var objValue = object[key]; + if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) || + (value === undefined && !(key in object))) { + object[key] = value; + } + } + + /** + * Gets the index at which the `key` is found in `array` of key-value pairs. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} key The key to search for. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function assocIndexOf(array, key) { + var length = array.length; + while (length--) { + if (eq(array[length][0], key)) { + return length; + } + } + return -1; + } + + /** + * The base implementation of `_.assign` without support for multiple sources + * or `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @returns {Object} Returns `object`. + */ + function baseAssign(object, source) { + return object && copyObject(source, keys(source), object); + } + + /** + * The base implementation of `_.clone` and `_.cloneDeep` which tracks + * traversed objects. + * + * @private + * @param {*} value The value to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @param {boolean} [isFull] Specify a clone including symbols. + * @param {Function} [customizer] The function to customize cloning. + * @param {string} [key] The key of `value`. + * @param {Object} [object] The parent object of `value`. + * @param {Object} [stack] Tracks traversed objects and their clone counterparts. + * @returns {*} Returns the cloned value. + */ + function baseClone(value, isDeep, isFull, customizer, key, object, stack) { + var result; + if (customizer) { + result = object ? customizer(value, key, object, stack) : customizer(value); + } + if (result !== undefined) { + return result; + } + if (!isObject(value)) { + return value; + } + var isArr = isArray(value); + if (isArr) { + result = initCloneArray(value); + if (!isDeep) { + return copyArray(value, result); + } + } else { + var tag = getTag(value), + isFunc = tag == funcTag || tag == genTag; + + if (isBuffer(value)) { + return cloneBuffer(value, isDeep); + } + if (tag == objectTag || tag == argsTag || (isFunc && !object)) { + if (isHostObject(value)) { + return object ? value : {}; + } + result = initCloneObject(isFunc ? {} : value); + if (!isDeep) { + return copySymbols(value, baseAssign(result, value)); + } + } else { + if (!cloneableTags[tag]) { + return object ? value : {}; + } + result = initCloneByTag(value, tag, baseClone, isDeep); + } + } + // Check for circular references and return its corresponding clone. + stack || (stack = new Stack); + var stacked = stack.get(value); + if (stacked) { + return stacked; + } + stack.set(value, result); + + if (!isArr) { + var props = isFull ? getAllKeys(value) : keys(value); + } + arrayEach(props || value, function(subValue, key) { + if (props) { + key = subValue; + subValue = value[key]; + } + // Recursively populate clone (susceptible to call stack limits). + assignValue(result, key, baseClone(subValue, isDeep, isFull, customizer, key, value, stack)); + }); + return result; + } + + /** + * The base implementation of `_.create` without support for assigning + * properties to the created object. + * + * @private + * @param {Object} prototype The object to inherit from. + * @returns {Object} Returns the new object. + */ + function baseCreate(proto) { + return isObject(proto) ? objectCreate(proto) : {}; + } + + /** + * The base implementation of `getAllKeys` and `getAllKeysIn` which uses + * `keysFunc` and `symbolsFunc` to get the enumerable property names and + * symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Function} keysFunc The function to get the keys of `object`. + * @param {Function} symbolsFunc The function to get the symbols of `object`. + * @returns {Array} Returns the array of property names and symbols. + */ + function baseGetAllKeys(object, keysFunc, symbolsFunc) { + var result = keysFunc(object); + return isArray(object) ? result : arrayPush(result, symbolsFunc(object)); + } + + /** + * The base implementation of `getTag`. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the `toStringTag`. + */ + function baseGetTag(value) { + return objectToString.call(value); + } + + /** + * The base implementation of `_.isNative` without bad shim checks. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a native function, + * else `false`. + */ + function baseIsNative(value) { + if (!isObject(value) || isMasked(value)) { + return false; + } + var pattern = (isFunction(value) || isHostObject(value)) ? reIsNative : reIsHostCtor; + return pattern.test(toSource(value)); + } + + /** + * The base implementation of `_.keys` which doesn't treat sparse arrays as dense. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ + function baseKeys(object) { + if (!isPrototype(object)) { + return nativeKeys(object); + } + var result = []; + for (var key in Object(object)) { + if (hasOwnProperty.call(object, key) && key != 'constructor') { + result.push(key); + } + } + return result; + } + + /** + * Creates a clone of `buffer`. + * + * @private + * @param {Buffer} buffer The buffer to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Buffer} Returns the cloned buffer. + */ + function cloneBuffer(buffer, isDeep) { + if (isDeep) { + return buffer.slice(); + } + var result = new buffer.constructor(buffer.length); + buffer.copy(result); + return result; + } + + /** + * Creates a clone of `arrayBuffer`. + * + * @private + * @param {ArrayBuffer} arrayBuffer The array buffer to clone. + * @returns {ArrayBuffer} Returns the cloned array buffer. + */ + function cloneArrayBuffer(arrayBuffer) { + var result = new arrayBuffer.constructor(arrayBuffer.byteLength); + new Uint8Array(result).set(new Uint8Array(arrayBuffer)); + return result; + } + + /** + * Creates a clone of `dataView`. + * + * @private + * @param {Object} dataView The data view to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned data view. + */ + function cloneDataView(dataView, isDeep) { + var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer; + return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength); + } + + /** + * Creates a clone of `map`. + * + * @private + * @param {Object} map The map to clone. + * @param {Function} cloneFunc The function to clone values. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned map. + */ + function cloneMap(map, isDeep, cloneFunc) { + var array = isDeep ? cloneFunc(mapToArray(map), true) : mapToArray(map); + return arrayReduce(array, addMapEntry, new map.constructor); + } + + /** + * Creates a clone of `regexp`. + * + * @private + * @param {Object} regexp The regexp to clone. + * @returns {Object} Returns the cloned regexp. + */ + function cloneRegExp(regexp) { + var result = new regexp.constructor(regexp.source, reFlags.exec(regexp)); + result.lastIndex = regexp.lastIndex; + return result; + } + + /** + * Creates a clone of `set`. + * + * @private + * @param {Object} set The set to clone. + * @param {Function} cloneFunc The function to clone values. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned set. + */ + function cloneSet(set, isDeep, cloneFunc) { + var array = isDeep ? cloneFunc(setToArray(set), true) : setToArray(set); + return arrayReduce(array, addSetEntry, new set.constructor); + } + + /** + * Creates a clone of the `symbol` object. + * + * @private + * @param {Object} symbol The symbol object to clone. + * @returns {Object} Returns the cloned symbol object. + */ + function cloneSymbol(symbol) { + return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {}; + } + + /** + * Creates a clone of `typedArray`. + * + * @private + * @param {Object} typedArray The typed array to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned typed array. + */ + function cloneTypedArray(typedArray, isDeep) { + var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer; + return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length); + } + + /** + * Copies the values of `source` to `array`. + * + * @private + * @param {Array} source The array to copy values from. + * @param {Array} [array=[]] The array to copy values to. + * @returns {Array} Returns `array`. + */ + function copyArray(source, array) { + var index = -1, + length = source.length; + + array || (array = Array(length)); + while (++index < length) { + array[index] = source[index]; + } + return array; + } + + /** + * Copies properties of `source` to `object`. + * + * @private + * @param {Object} source The object to copy properties from. + * @param {Array} props The property identifiers to copy. + * @param {Object} [object={}] The object to copy properties to. + * @param {Function} [customizer] The function to customize copied values. + * @returns {Object} Returns `object`. + */ + function copyObject(source, props, object, customizer) { + object || (object = {}); + + var index = -1, + length = props.length; + + while (++index < length) { + var key = props[index]; + + var newValue = undefined; + + assignValue(object, key, newValue === undefined ? source[key] : newValue); + } + return object; + } + + /** + * Copies own symbol properties of `source` to `object`. + * + * @private + * @param {Object} source The object to copy symbols from. + * @param {Object} [object={}] The object to copy symbols to. + * @returns {Object} Returns `object`. + */ + function copySymbols(source, object) { + return copyObject(source, getSymbols(source), object); + } + + /** + * Creates an array of own enumerable property names and symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names and symbols. + */ + function getAllKeys(object) { + return baseGetAllKeys(object, keys, getSymbols); + } + + /** + * Gets the data for `map`. + * + * @private + * @param {Object} map The map to query. + * @param {string} key The reference key. + * @returns {*} Returns the map data. + */ + function getMapData(map, key) { + var data = map.__data__; + return isKeyable(key) + ? data[typeof key == 'string' ? 'string' : 'hash'] + : data.map; + } + + /** + * Gets the native function at `key` of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {string} key The key of the method to get. + * @returns {*} Returns the function if it's native, else `undefined`. + */ + function getNative(object, key) { + var value = getValue(object, key); + return baseIsNative(value) ? value : undefined; + } + + /** + * Creates an array of the own enumerable symbol properties of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. + */ + var getSymbols = nativeGetSymbols ? overArg(nativeGetSymbols, Object) : stubArray; + + /** + * Gets the `toStringTag` of `value`. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the `toStringTag`. + */ + var getTag = baseGetTag; + + // Fallback for data views, maps, sets, and weak maps in IE 11, + // for data views in Edge < 14, and promises in Node.js. + if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) || + (Map && getTag(new Map) != mapTag) || + (Promise && getTag(Promise.resolve()) != promiseTag) || + (Set && getTag(new Set) != setTag) || + (WeakMap && getTag(new WeakMap) != weakMapTag)) { + getTag = function(value) { + var result = objectToString.call(value), + Ctor = result == objectTag ? value.constructor : undefined, + ctorString = Ctor ? toSource(Ctor) : undefined; + + if (ctorString) { + switch (ctorString) { + case dataViewCtorString: return dataViewTag; + case mapCtorString: return mapTag; + case promiseCtorString: return promiseTag; + case setCtorString: return setTag; + case weakMapCtorString: return weakMapTag; + } + } + return result; + }; + } + + /** + * Initializes an array clone. + * + * @private + * @param {Array} array The array to clone. + * @returns {Array} Returns the initialized clone. + */ + function initCloneArray(array) { + var length = array.length, + result = array.constructor(length); + + // Add properties assigned by `RegExp#exec`. + if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) { + result.index = array.index; + result.input = array.input; + } + return result; + } + + /** + * Initializes an object clone. + * + * @private + * @param {Object} object The object to clone. + * @returns {Object} Returns the initialized clone. + */ + function initCloneObject(object) { + return (typeof object.constructor == 'function' && !isPrototype(object)) + ? baseCreate(getPrototype(object)) + : {}; + } + + /** + * Initializes an object clone based on its `toStringTag`. + * + * **Note:** This function only supports cloning values with tags of + * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. + * + * @private + * @param {Object} object The object to clone. + * @param {string} tag The `toStringTag` of the object to clone. + * @param {Function} cloneFunc The function to clone values. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the initialized clone. + */ + function initCloneByTag(object, tag, cloneFunc, isDeep) { + var Ctor = object.constructor; + switch (tag) { + case arrayBufferTag: + return cloneArrayBuffer(object); + + case boolTag: + case dateTag: + return new Ctor(+object); + + case dataViewTag: + return cloneDataView(object, isDeep); + + case float32Tag: case float64Tag: + case int8Tag: case int16Tag: case int32Tag: + case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag: + return cloneTypedArray(object, isDeep); + + case mapTag: + return cloneMap(object, isDeep, cloneFunc); + + case numberTag: + case stringTag: + return new Ctor(object); + + case regexpTag: + return cloneRegExp(object); + + case setTag: + return cloneSet(object, isDeep, cloneFunc); + + case symbolTag: + return cloneSymbol(object); + } + } + + /** + * Checks if `value` is a valid array-like index. + * + * @private + * @param {*} value The value to check. + * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. + * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. + */ + function isIndex(value, length) { + length = length == null ? MAX_SAFE_INTEGER : length; + return !!length && + (typeof value == 'number' || reIsUint.test(value)) && + (value > -1 && value % 1 == 0 && value < length); + } + + /** + * Checks if `value` is suitable for use as unique object key. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is suitable, else `false`. + */ + function isKeyable(value) { + var type = typeof value; + return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean') + ? (value !== '__proto__') + : (value === null); + } + + /** + * Checks if `func` has its source masked. + * + * @private + * @param {Function} func The function to check. + * @returns {boolean} Returns `true` if `func` is masked, else `false`. + */ + function isMasked(func) { + return !!maskSrcKey && (maskSrcKey in func); + } + + /** + * Checks if `value` is likely a prototype object. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a prototype, else `false`. + */ + function isPrototype(value) { + var Ctor = value && value.constructor, + proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto; + + return value === proto; + } + + /** + * Converts `func` to its source code. + * + * @private + * @param {Function} func The function to process. + * @returns {string} Returns the source code. + */ + function toSource(func) { + if (func != null) { + try { + return funcToString.call(func); + } catch (e) {} + try { + return (func + ''); + } catch (e) {} + } + return ''; + } + + /** + * This method is like `_.clone` except that it recursively clones `value`. + * + * @static + * @memberOf _ + * @since 1.0.0 + * @category Lang + * @param {*} value The value to recursively clone. + * @returns {*} Returns the deep cloned value. + * @see _.clone + * @example + * + * var objects = [{ 'a': 1 }, { 'b': 2 }]; + * + * var deep = _.cloneDeep(objects); + * console.log(deep[0] === objects[0]); + * // => false + */ + function cloneDeep(value) { + return baseClone(value, true, true); + } + + /** + * Performs a + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * comparison between two values to determine if they are equivalent. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'a': 1 }; + * var other = { 'a': 1 }; + * + * _.eq(object, object); + * // => true + * + * _.eq(object, other); + * // => false + * + * _.eq('a', 'a'); + * // => true + * + * _.eq('a', Object('a')); + * // => false + * + * _.eq(NaN, NaN); + * // => true + */ + function eq(value, other) { + return value === other || (value !== value && other !== other); + } + + /** + * Checks if `value` is likely an `arguments` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an `arguments` object, + * else `false`. + * @example + * + * _.isArguments(function() { return arguments; }()); + * // => true + * + * _.isArguments([1, 2, 3]); + * // => false + */ + function isArguments(value) { + // Safari 8.1 makes `arguments.callee` enumerable in strict mode. + return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') && + (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag); + } + + /** + * Checks if `value` is classified as an `Array` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array, else `false`. + * @example + * + * _.isArray([1, 2, 3]); + * // => true + * + * _.isArray(document.body.children); + * // => false + * + * _.isArray('abc'); + * // => false + * + * _.isArray(_.noop); + * // => false + */ + var isArray = Array.isArray; + + /** + * Checks if `value` is array-like. A value is considered array-like if it's + * not a function and has a `value.length` that's an integer greater than or + * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is array-like, else `false`. + * @example + * + * _.isArrayLike([1, 2, 3]); + * // => true + * + * _.isArrayLike(document.body.children); + * // => true + * + * _.isArrayLike('abc'); + * // => true + * + * _.isArrayLike(_.noop); + * // => false + */ + function isArrayLike(value) { + return value != null && isLength(value.length) && !isFunction(value); + } + + /** + * This method is like `_.isArrayLike` except that it also checks if `value` + * is an object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array-like object, + * else `false`. + * @example + * + * _.isArrayLikeObject([1, 2, 3]); + * // => true + * + * _.isArrayLikeObject(document.body.children); + * // => true + * + * _.isArrayLikeObject('abc'); + * // => false + * + * _.isArrayLikeObject(_.noop); + * // => false + */ + function isArrayLikeObject(value) { + return isObjectLike(value) && isArrayLike(value); + } + + /** + * Checks if `value` is a buffer. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a buffer, else `false`. + * @example + * + * _.isBuffer(new Buffer(2)); + * // => true + * + * _.isBuffer(new Uint8Array(2)); + * // => false + */ + var isBuffer = nativeIsBuffer || stubFalse; + + /** + * Checks if `value` is classified as a `Function` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a function, else `false`. + * @example + * + * _.isFunction(_); + * // => true + * + * _.isFunction(/abc/); + * // => false + */ + function isFunction(value) { + // The use of `Object#toString` avoids issues with the `typeof` operator + // in Safari 8-9 which returns 'object' for typed array and other constructors. + var tag = isObject(value) ? objectToString.call(value) : ''; + return tag == funcTag || tag == genTag; + } + + /** + * Checks if `value` is a valid array-like length. + * + * **Note:** This method is loosely based on + * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. + * @example + * + * _.isLength(3); + * // => true + * + * _.isLength(Number.MIN_VALUE); + * // => false + * + * _.isLength(Infinity); + * // => false + * + * _.isLength('3'); + * // => false + */ + function isLength(value) { + return typeof value == 'number' && + value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; + } + + /** + * Checks if `value` is the + * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) + * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(_.noop); + * // => true + * + * _.isObject(null); + * // => false + */ + function isObject(value) { + var type = typeof value; + return !!value && (type == 'object' || type == 'function'); + } + + /** + * Checks if `value` is object-like. A value is object-like if it's not `null` + * and has a `typeof` result of "object". + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @example + * + * _.isObjectLike({}); + * // => true + * + * _.isObjectLike([1, 2, 3]); + * // => true + * + * _.isObjectLike(_.noop); + * // => false + * + * _.isObjectLike(null); + * // => false + */ + function isObjectLike(value) { + return !!value && typeof value == 'object'; + } + + /** + * Creates an array of the own enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. See the + * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) + * for more details. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keys(new Foo); + * // => ['a', 'b'] (iteration order is not guaranteed) + * + * _.keys('hi'); + * // => ['0', '1'] + */ + function keys(object) { + return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object); + } + + /** + * This method returns a new empty array. + * + * @static + * @memberOf _ + * @since 4.13.0 + * @category Util + * @returns {Array} Returns the new empty array. + * @example + * + * var arrays = _.times(2, _.stubArray); + * + * console.log(arrays); + * // => [[], []] + * + * console.log(arrays[0] === arrays[1]); + * // => false + */ + function stubArray() { + return []; + } + + /** + * This method returns `false`. + * + * @static + * @memberOf _ + * @since 4.13.0 + * @category Util + * @returns {boolean} Returns `false`. + * @example + * + * _.times(2, _.stubFalse); + * // => [false, false] + */ + function stubFalse() { + return false; + } + + module.exports = cloneDeep; + } (lodash_clonedeep, lodash_clonedeep.exports)); + + var lodash_clonedeepExports = lodash_clonedeep.exports; + var cloneDeep = /*@__PURE__*/getDefaultExportFromCjs$1(lodash_clonedeepExports); + + function applyContextDelta(context, delta, logger) { + try { + if (logger?.canPublish("trace")) { + logger?.trace(`applying context delta ${JSON.stringify(delta)} on context ${JSON.stringify(context)}`); + } + if (!delta) { + return context; + } + if (delta.reset) { + context = { ...delta.reset }; + return context; + } + context = deepClone(context, undefined); + if (delta.commands) { + for (const command of delta.commands) { + if (command.type === "remove") { + deletePath(context, command.path); + } + else if (command.type === "set") { + setValueToPath(context, command.value, command.path); + } + } + return context; + } + const added = delta.added; + const updated = delta.updated; + const removed = delta.removed; + if (added) { + Object.keys(added).forEach((key) => { + context[key] = added[key]; + }); + } + if (updated) { + Object.keys(updated).forEach((key) => { + mergeObjectsProperties(key, context, updated); + }); + } + if (removed) { + removed.forEach((key) => { + delete context[key]; + }); + } + return context; + } + catch (e) { + logger?.error(`error applying context delta ${JSON.stringify(delta)} on context ${JSON.stringify(context)}`, e); + return context; + } + } + function deepClone(obj, hash) { + return cloneDeep(obj); + } + const mergeObjectsProperties = (key, what, withWhat) => { + const right = withWhat[key]; + if (right === undefined) { + return what; + } + const left = what[key]; + if (!left || !right) { + what[key] = right; + return what; + } + if (typeof left === "string" || + typeof left === "number" || + typeof left === "boolean" || + typeof right === "string" || + typeof right === "number" || + typeof right === "boolean" || + Array.isArray(left) || + Array.isArray(right)) { + what[key] = right; + return what; + } + what[key] = Object.assign({}, left, right); + return what; + }; + function deepEqual(x, y) { + if (x === y) { + return true; + } + if (!(x instanceof Object) || !(y instanceof Object)) { + return false; + } + if (x.constructor !== y.constructor) { + return false; + } + for (const p in x) { + if (!x.hasOwnProperty(p)) { + continue; + } + if (!y.hasOwnProperty(p)) { + return false; + } + if (x[p] === y[p]) { + continue; + } + if (typeof (x[p]) !== "object") { + return false; + } + if (!deepEqual(x[p], y[p])) { + return false; + } + } + for (const p in y) { + if (y.hasOwnProperty(p) && !x.hasOwnProperty(p)) { + return false; + } + } + return true; + } + function setValueToPath(obj, value, path) { + const pathArr = path.split("."); + let i; + for (i = 0; i < pathArr.length - 1; i++) { + if (!obj[pathArr[i]]) { + obj[pathArr[i]] = {}; + } + if (typeof obj[pathArr[i]] !== "object") { + obj[pathArr[i]] = {}; + } + obj = obj[pathArr[i]]; + } + obj[pathArr[i]] = value; + } + function isSubset(superObj, subObj) { + return Object.keys(subObj).every((ele) => { + if (typeof subObj[ele] === "object") { + return isSubset(superObj?.[ele] || {}, subObj[ele] || {}); + } + return subObj[ele] === superObj?.[ele]; + }); + } + function deletePath(obj, path) { + const pathArr = path.split("."); + let i; + for (i = 0; i < pathArr.length - 1; i++) { + if (!obj[pathArr[i]]) { + return; + } + obj = obj[pathArr[i]]; + } + delete obj[pathArr[i]]; + } + + let GW3Bridge$1 = class GW3Bridge { + _logger; + _connection; + _trackAllContexts; + _reAnnounceKnownContexts; + _gw3Session; + _contextNameToData = {}; + _gw3Subscriptions = []; + _nextCallbackSubscriptionNumber = 0; + _creationPromises = {}; + _contextNameToId = {}; + _contextIdToName = {}; + _protocolVersion = undefined; + _contextsTempCache = {}; + _contextsSubscriptionsCache = []; + _systemContextsSubKey; + get protocolVersion() { + if (!this._protocolVersion) { + const contextsDomainInfo = this._connection.availableDomains.find((d) => d.uri === "context"); + this._protocolVersion = contextsDomainInfo?.version ?? 1; + } + return this._protocolVersion; + } + get setPathSupported() { + return this.protocolVersion >= 2; + } + constructor(config) { + this._connection = config.connection; + this._logger = config.logger; + this._trackAllContexts = config.trackAllContexts; + this._reAnnounceKnownContexts = config.reAnnounceKnownContexts; + this._gw3Session = this._connection.domain("global", [ + GW_MESSAGE_CONTEXT_CREATED, + GW_MESSAGE_SUBSCRIBED_CONTEXT, + GW_MESSAGE_CONTEXT_DESTROYED, + GW_MESSAGE_CONTEXT_UPDATED, + ]); + this._gw3Session.disconnected(this.resetState.bind(this)); + this._gw3Session.onJoined((wasReconnect) => { + if (!wasReconnect) { + return; + } + if (!this._reAnnounceKnownContexts) { + return this._connection.setLibReAnnounced({ name: "contexts" }); + } + this.reInitiateState().then(() => this._connection.setLibReAnnounced({ name: "contexts" })); + }); + this.subscribeToContextCreatedMessages(); + this.subscribeToContextUpdatedMessages(); + this.subscribeToContextDestroyedMessages(); + this._connection.replayer?.drain(ContextMessageReplaySpec.name, (message) => { + const type = message.type; + if (!type) { + return; + } + if (type === GW_MESSAGE_CONTEXT_CREATED || + type === GW_MESSAGE_CONTEXT_ADDED || + type === GW_MESSAGE_ACTIVITY_CREATED) { + this.handleContextCreatedMessage(message); + } + else if (type === GW_MESSAGE_SUBSCRIBED_CONTEXT || + type === GW_MESSAGE_CONTEXT_UPDATED || + type === GW_MESSAGE_JOINED_ACTIVITY) { + this.handleContextUpdatedMessage(message); + } + else if (type === GW_MESSAGE_CONTEXT_DESTROYED || + type === GW_MESSAGE_ACTIVITY_DESTROYED) { + this.handleContextDestroyedMessage(message); + } + }); + } + dispose() { + for (const sub of this._gw3Subscriptions) { + this._connection.off(sub); + } + this._gw3Subscriptions.length = 0; + for (const contextName in this._contextNameToData) { + if (this._contextNameToId.hasOwnProperty(contextName)) { + delete this._contextNameToData[contextName]; + } + } + } + createContext(name, data) { + if (name in this._creationPromises) { + return this._creationPromises[name]; + } + this._creationPromises[name] = + this._gw3Session + .send({ + type: GW_MESSAGE_CREATE_CONTEXT, + domain: "global", + name, + data, + lifetime: "retained", + }) + .then((createContextMsg) => { + this._contextNameToId[name] = createContextMsg.context_id; + this._contextIdToName[createContextMsg.context_id] = name; + const contextData = this._contextNameToData[name] || new GW3ContextData(createContextMsg.context_id, name, true, undefined); + contextData.isAnnounced = true; + contextData.name = name; + contextData.contextId = createContextMsg.context_id; + contextData.context = createContextMsg.data || deepClone(data); + contextData.hasReceivedSnapshot = true; + this._contextNameToData[name] = contextData; + delete this._creationPromises[name]; + return createContextMsg.context_id; + }); + return this._creationPromises[name]; + } + all() { + return Object.keys(this._contextNameToData) + .filter((name) => this._contextNameToData[name].isAnnounced); + } + async update(name, delta) { + if (delta) { + delta = deepClone(delta); + } + if (name in this._creationPromises) { + await this._creationPromises[name]; + } + const contextData = this._contextNameToData[name]; + if (!contextData || !contextData.isAnnounced) { + return this.createContext(name, delta); + } + let currentContext = contextData.context; + if (!contextData.hasCallbacks()) { + currentContext = await this.get(contextData.name); + } + const calculatedDelta = this.setPathSupported ? + this.calculateContextDeltaV2(currentContext, delta) : + this.calculateContextDeltaV1(currentContext, delta); + if (!Object.keys(calculatedDelta.added).length + && !Object.keys(calculatedDelta.updated).length + && !calculatedDelta.removed.length + && !calculatedDelta.commands?.length) { + return Promise.resolve(); + } + return this._gw3Session + .send({ + type: GW_MESSAGE_UPDATE_CONTEXT, + domain: "global", + context_id: contextData.contextId, + delta: calculatedDelta, + }, {}, { skipPeerId: false }) + .then((gwResponse) => { + this.handleUpdated(contextData, calculatedDelta, { + updaterId: gwResponse.peer_id + }); + }); + } + async set(name, data) { + if (data) { + data = deepClone(data); + } + if (name in this._creationPromises) { + await this._creationPromises[name]; + } + const contextData = this._contextNameToData[name]; + if (!contextData || !contextData.isAnnounced) { + return this.createContext(name, data); + } + return this._gw3Session + .send({ + type: GW_MESSAGE_UPDATE_CONTEXT, + domain: "global", + context_id: contextData.contextId, + delta: { reset: data }, + }, {}, { skipPeerId: false }) + .then((gwResponse) => { + this.handleUpdated(contextData, { + reset: data, + added: {}, + removed: [], + updated: {} + }, { + updaterId: gwResponse.peer_id + }); + }); + } + setPath(name, path, value) { + if (!this.setPathSupported) { + return Promise.reject("glue.contexts.setPath operation is not supported, use Glue42 3.10 or later"); + } + return this.setPaths(name, [{ path, value }]); + } + async setPaths(name, pathValues) { + if (!this.setPathSupported) { + return Promise.reject("glue.contexts.setPaths operation is not supported, use Glue42 3.10 or later"); + } + if (pathValues) { + pathValues = deepClone(pathValues); + } + if (name in this._creationPromises) { + await this._creationPromises[name]; + } + const contextData = this._contextNameToData[name]; + if (!contextData || !contextData.isAnnounced) { + const obj = {}; + for (const pathValue of pathValues) { + setValueToPath(obj, pathValue.value, pathValue.path); + } + return this.createContext(name, obj); + } + const commands = []; + for (const pathValue of pathValues) { + if (pathValue.value === null) { + commands.push({ type: "remove", path: pathValue.path }); + } + else { + commands.push({ type: "set", path: pathValue.path, value: pathValue.value }); + } + } + return this._gw3Session + .send({ + type: GW_MESSAGE_UPDATE_CONTEXT, + domain: "global", + context_id: contextData.contextId, + delta: { commands } + }, {}, { skipPeerId: false }) + .then((gwResponse) => { + this.handleUpdated(contextData, { + added: {}, + removed: [], + updated: {}, + commands + }, { + updaterId: gwResponse.peer_id + }); + }); + } + async get(name) { + if (name in this._creationPromises) { + await this._creationPromises[name]; + } + const contextData = this._contextNameToData[name]; + if (!contextData || !contextData.isAnnounced) { + return Promise.resolve({}); + } + if (contextData && (!contextData.hasCallbacks() || !contextData.hasReceivedSnapshot)) { + return new Promise((resolve) => { + this.subscribe(name, (data, _d, _r, un) => { + this.unsubscribe(un); + resolve(data); + }); + }); + } + const context = contextData?.context ?? {}; + return Promise.resolve(deepClone(context)); + } + async subscribe(name, callback, subscriptionKey) { + if (name in this._creationPromises) { + await this._creationPromises[name]; + } + const thisCallbackSubscriptionNumber = typeof subscriptionKey === "undefined" ? this._nextCallbackSubscriptionNumber : subscriptionKey; + if (typeof subscriptionKey === "undefined") { + this._nextCallbackSubscriptionNumber += 1; + } + if (this._contextsSubscriptionsCache.every((subscription) => subscription.subKey !== this._nextCallbackSubscriptionNumber)) { + this._contextsSubscriptionsCache.push({ contextName: name, subKey: thisCallbackSubscriptionNumber, callback }); + } + let contextData = this._contextNameToData[name]; + if (!contextData || + !contextData.isAnnounced) { + contextData = contextData || new GW3ContextData(undefined, name, false, undefined); + this._contextNameToData[name] = contextData; + contextData.updateCallbacks[thisCallbackSubscriptionNumber] = callback; + return Promise.resolve(thisCallbackSubscriptionNumber); + } + const hadCallbacks = contextData.hasCallbacks(); + contextData.updateCallbacks[thisCallbackSubscriptionNumber] = callback; + if (!hadCallbacks) { + if (!contextData.joinedActivity) { + if (contextData.context && contextData.sentExplicitSubscription) { + if (contextData.hasReceivedSnapshot) { + const clone = deepClone(contextData.context); + callback(clone, clone, [], thisCallbackSubscriptionNumber); + } + return Promise.resolve(thisCallbackSubscriptionNumber); + } + return this.sendSubscribe(contextData) + .then(() => thisCallbackSubscriptionNumber); + } + else { + if (contextData.hasReceivedSnapshot) { + const clone = deepClone(contextData.context); + callback(clone, clone, [], thisCallbackSubscriptionNumber); + } + return Promise.resolve(thisCallbackSubscriptionNumber); + } + } + else { + if (contextData.hasReceivedSnapshot) { + const clone = deepClone(contextData.context); + callback(clone, clone, [], thisCallbackSubscriptionNumber); + } + return Promise.resolve(thisCallbackSubscriptionNumber); + } + } + unsubscribe(subscriptionKey) { + this._contextsSubscriptionsCache = this._contextsSubscriptionsCache.filter((subscription) => subscription.subKey !== subscriptionKey); + for (const name of Object.keys(this._contextNameToData)) { + const contextData = this._contextNameToData[name]; + if (!contextData) { + return; + } + const hadCallbacks = contextData.hasCallbacks(); + delete contextData.updateCallbacks[subscriptionKey]; + if (contextData.isAnnounced && + hadCallbacks && + !contextData.hasCallbacks() && + contextData.sentExplicitSubscription) { + this.sendUnsubscribe(contextData).catch(() => { }); + } + if (!contextData.isAnnounced && + !contextData.hasCallbacks()) { + delete this._contextNameToData[name]; + } + } + } + async destroy(name) { + if (name in this._creationPromises) { + await this._creationPromises[name]; + } + const contextData = this._contextNameToData[name]; + if (!contextData) { + return Promise.reject(`context with ${name} does not exist`); + } + return this._gw3Session + .send({ + type: GW_MESSAGE_DESTROY_CONTEXT, + domain: "global", + context_id: contextData.contextId, + }).then((_) => undefined); + } + handleUpdated(contextData, delta, extraData) { + const oldContext = contextData.context; + contextData.context = applyContextDelta(contextData.context, delta, this._logger); + contextData.hasReceivedSnapshot = true; + if (this._contextNameToData[contextData.name] === contextData && + !deepEqual(oldContext, contextData.context)) { + this.invokeUpdateCallbacks(contextData, delta, extraData); + } + } + subscribeToContextCreatedMessages() { + const createdMessageTypes = [ + GW_MESSAGE_CONTEXT_ADDED, + GW_MESSAGE_CONTEXT_CREATED, + GW_MESSAGE_ACTIVITY_CREATED, + ]; + for (const createdMessageType of createdMessageTypes) { + const sub = this._connection.on(createdMessageType, this.handleContextCreatedMessage.bind(this)); + this._gw3Subscriptions.push(sub); + } + } + handleContextCreatedMessage(contextCreatedMsg) { + const createdMessageType = contextCreatedMsg.type; + if (createdMessageType === GW_MESSAGE_ACTIVITY_CREATED) { + this._contextNameToId[contextCreatedMsg.activity_id] = contextCreatedMsg.context_id; + this._contextIdToName[contextCreatedMsg.context_id] = contextCreatedMsg.activity_id; + } + else if (createdMessageType === GW_MESSAGE_CONTEXT_ADDED) { + this._contextNameToId[contextCreatedMsg.name] = contextCreatedMsg.context_id; + this._contextIdToName[contextCreatedMsg.context_id] = contextCreatedMsg.name; + } + else ; + const name = this._contextIdToName[contextCreatedMsg.context_id]; + if (!name) { + throw new Error("Received created event for context with unknown name: " + contextCreatedMsg.context_id); + } + if (!this._contextNameToId[name]) { + throw new Error("Received created event for context with unknown id: " + contextCreatedMsg.context_id); + } + let contextData = this._contextNameToData[name]; + if (contextData) { + if (contextData.isAnnounced) { + return; + } + else { + if (!contextData.hasCallbacks()) { + throw new Error("Assertion failure: contextData.hasCallbacks()"); + } + contextData.isAnnounced = true; + contextData.contextId = contextCreatedMsg.context_id; + contextData.activityId = contextCreatedMsg.activity_id; + if (!contextData.sentExplicitSubscription) { + this.sendSubscribe(contextData); + } + } + } + else { + this._contextNameToData[name] = contextData = + new GW3ContextData(contextCreatedMsg.context_id, name, true, contextCreatedMsg.activity_id); + if (this._trackAllContexts) { + this.subscribe(name, () => { }).then((subKey) => this._systemContextsSubKey = subKey); + } + } + } + subscribeToContextUpdatedMessages() { + const updatedMessageTypes = [ + GW_MESSAGE_CONTEXT_UPDATED, + GW_MESSAGE_SUBSCRIBED_CONTEXT, + GW_MESSAGE_JOINED_ACTIVITY, + ]; + for (const updatedMessageType of updatedMessageTypes) { + const sub = this._connection.on(updatedMessageType, this.handleContextUpdatedMessage.bind(this)); + this._gw3Subscriptions.push(sub); + } + } + handleContextUpdatedMessage(contextUpdatedMsg) { + const updatedMessageType = contextUpdatedMsg.type; + const contextId = contextUpdatedMsg.context_id; + let contextData = this._contextNameToData[this._contextIdToName[contextId]]; + const justSeen = !contextData || !contextData.isAnnounced; + if (updatedMessageType === GW_MESSAGE_JOINED_ACTIVITY) { + if (!contextData) { + contextData = + this._contextNameToData[contextUpdatedMsg.activity_id] || + new GW3ContextData(contextId, contextUpdatedMsg.activity_id, true, contextUpdatedMsg.activity_id); + } + this._contextNameToData[contextUpdatedMsg.activity_id] = contextData; + this._contextIdToName[contextId] = contextUpdatedMsg.activity_id; + this._contextNameToId[contextUpdatedMsg.activity_id] = contextId; + contextData.contextId = contextId; + contextData.isAnnounced = true; + contextData.activityId = contextUpdatedMsg.activity_id; + contextData.joinedActivity = true; + } + else { + if (!contextData || !contextData.isAnnounced) { + if (updatedMessageType === GW_MESSAGE_SUBSCRIBED_CONTEXT) { + contextData = contextData || new GW3ContextData(contextId, contextUpdatedMsg.name, true, undefined); + contextData.sentExplicitSubscription = true; + this._contextNameToData[contextUpdatedMsg.name] = contextData; + this._contextIdToName[contextId] = contextUpdatedMsg.name; + this._contextNameToId[contextUpdatedMsg.name] = contextId; + } + else { + this._logger.error(`Received 'update' for unknown context: ${contextId}`); + } + return; + } + } + const oldContext = contextData.context; + contextData.hasReceivedSnapshot = true; + if (updatedMessageType === GW_MESSAGE_SUBSCRIBED_CONTEXT) { + contextData.context = contextUpdatedMsg.data || {}; + } + else if (updatedMessageType === GW_MESSAGE_JOINED_ACTIVITY) { + contextData.context = contextUpdatedMsg.context_snapshot || {}; + } + else if (updatedMessageType === GW_MESSAGE_CONTEXT_UPDATED) { + contextData.context = applyContextDelta(contextData.context, contextUpdatedMsg.delta, this._logger); + } + else { + throw new Error("Unrecognized context update message " + updatedMessageType); + } + if (justSeen || + !deepEqual(contextData.context, oldContext) || + updatedMessageType === GW_MESSAGE_SUBSCRIBED_CONTEXT) { + this.invokeUpdateCallbacks(contextData, contextUpdatedMsg.delta, { updaterId: contextUpdatedMsg.updater_id }); + } + } + invokeUpdateCallbacks(contextData, delta, extraData) { + delta = delta || { added: {}, updated: {}, reset: {}, removed: [] }; + if (delta.commands) { + delta.added = delta.updated = delta.reset = {}; + delta.removed = []; + for (const command of delta.commands) { + if (command.type === "remove") { + if (command.path.indexOf(".") === -1) { + delta.removed.push(command.path); + } + setValueToPath(delta.updated, null, command.path); + } + else if (command.type === "set") { + setValueToPath(delta.updated, command.value, command.path); + } + } + } + for (const updateCallbackIndex in contextData.updateCallbacks) { + if (contextData.updateCallbacks.hasOwnProperty(updateCallbackIndex)) { + try { + const updateCallback = contextData.updateCallbacks[updateCallbackIndex]; + updateCallback(deepClone(contextData.context), deepClone(Object.assign({}, delta.added || {}, delta.updated || {}, delta.reset || {})), delta.removed, parseInt(updateCallbackIndex, 10), extraData); + } + catch (err) { + this._logger.debug("callback error: " + JSON.stringify(err)); + } + } + } + } + subscribeToContextDestroyedMessages() { + const destroyedMessageTypes = [ + GW_MESSAGE_CONTEXT_DESTROYED, + GW_MESSAGE_ACTIVITY_DESTROYED, + ]; + for (const destroyedMessageType of destroyedMessageTypes) { + const sub = this._connection.on(destroyedMessageType, this.handleContextDestroyedMessage.bind(this)); + this._gw3Subscriptions.push(sub); + } + } + handleContextDestroyedMessage(destroyedMsg) { + const destroyedMessageType = destroyedMsg.type; + let contextId; + let name; + if (destroyedMessageType === GW_MESSAGE_ACTIVITY_DESTROYED) { + name = destroyedMsg.activity_id; + contextId = this._contextNameToId[name]; + if (!contextId) { + this._logger.error(`Received 'destroyed' for unknown activity: ${destroyedMsg.activity_id}`); + return; + } + } + else { + contextId = destroyedMsg.context_id; + name = this._contextIdToName[contextId]; + if (!name) { + this._logger.error(`Received 'destroyed' for unknown context: ${destroyedMsg.context_id}`); + return; + } + } + delete this._contextIdToName[contextId]; + delete this._contextNameToId[name]; + const contextData = this._contextNameToData[name]; + delete this._contextNameToData[name]; + if (!contextData || !contextData.isAnnounced) { + this._logger.error(`Received 'destroyed' for unknown context: ${contextId}`); + return; + } + } + sendSubscribe(contextData) { + contextData.sentExplicitSubscription = true; + return this._gw3Session + .send({ + type: GW_MESSAGE_SUBSCRIBE_CONTEXT, + domain: "global", + context_id: contextData.contextId, + }).then((_) => undefined); + } + sendUnsubscribe(contextData) { + contextData.sentExplicitSubscription = false; + return this._gw3Session + .send({ + type: GW_MESSAGE_UNSUBSCRIBE_CONTEXT, + domain: "global", + context_id: contextData.contextId, + }).then((_) => undefined); + } + calculateContextDeltaV1(from, to) { + const delta = { added: {}, updated: {}, removed: [], reset: undefined }; + if (from) { + for (const x of Object.keys(from)) { + if (Object.keys(to).indexOf(x) !== -1 + && to[x] !== null + && !deepEqual(from[x], to[x])) { + delta.updated[x] = to[x]; + } + } + } + for (const x of Object.keys(to)) { + if (!from || (Object.keys(from).indexOf(x) === -1)) { + if (to[x] !== null) { + delta.added[x] = to[x]; + } + } + else if (to[x] === null) { + delta.removed.push(x); + } + } + return delta; + } + calculateContextDeltaV2(from, to) { + const delta = { added: {}, updated: {}, removed: [], reset: undefined, commands: [] }; + for (const x of Object.keys(to)) { + if (to[x] !== null) { + const fromX = from ? from[x] : null; + if (!deepEqual(fromX, to[x])) { + delta.commands?.push({ type: "set", path: x, value: to[x] }); + } + } + else { + delta.commands?.push({ type: "remove", path: x }); + } + } + return delta; + } + resetState() { + for (const sub of this._gw3Subscriptions) { + this._connection.off(sub); + } + if (this._systemContextsSubKey) { + this.unsubscribe(this._systemContextsSubKey); + delete this._systemContextsSubKey; + } + this._gw3Subscriptions = []; + this._contextNameToId = {}; + this._contextIdToName = {}; + delete this._protocolVersion; + this._contextsTempCache = Object.keys(this._contextNameToData).reduce((cacheSoFar, ctxName) => { + const contextData = this._contextNameToData[ctxName]; + if (contextData.isAnnounced && (contextData.activityId || contextData.sentExplicitSubscription)) { + cacheSoFar[ctxName] = this._contextNameToData[ctxName].context; + } + return cacheSoFar; + }, {}); + this._contextNameToData = {}; + } + async reInitiateState() { + this.subscribeToContextCreatedMessages(); + this.subscribeToContextUpdatedMessages(); + this.subscribeToContextDestroyedMessages(); + this._connection.replayer?.drain(ContextMessageReplaySpec.name, (message) => { + const type = message.type; + if (!type) { + return; + } + if (type === GW_MESSAGE_CONTEXT_CREATED || + type === GW_MESSAGE_CONTEXT_ADDED || + type === GW_MESSAGE_ACTIVITY_CREATED) { + this.handleContextCreatedMessage(message); + } + else if (type === GW_MESSAGE_SUBSCRIBED_CONTEXT || + type === GW_MESSAGE_CONTEXT_UPDATED || + type === GW_MESSAGE_JOINED_ACTIVITY) { + this.handleContextUpdatedMessage(message); + } + else if (type === GW_MESSAGE_CONTEXT_DESTROYED || + type === GW_MESSAGE_ACTIVITY_DESTROYED) { + this.handleContextDestroyedMessage(message); + } + }); + await Promise.all(this._contextsSubscriptionsCache.map((subscription) => this.subscribe(subscription.contextName, subscription.callback, subscription.subKey))); + await this.flushQueue(); + for (const ctxName in this._contextsTempCache) { + if (typeof this._contextsTempCache[ctxName] !== "object" || Object.keys(this._contextsTempCache[ctxName]).length === 0) { + continue; + } + const lastKnownData = this._contextsTempCache[ctxName]; + this._logger.info(`Re-announcing known context: ${ctxName}`); + await this.flushQueue(); + await this.update(ctxName, lastKnownData); + } + this._contextsTempCache = {}; + this._logger.info("Contexts are re-announced"); + } + flushQueue() { + return new Promise((resolve) => setTimeout(() => resolve(), 0)); + } + }; + + class ContextsModule { + initTime; + initStartTime; + initEndTime; + _bridge; + constructor(config) { + this._bridge = new GW3Bridge$1(config); + } + all() { + return this._bridge.all(); + } + update(name, data) { + this.checkName(name); + this.checkData(data); + return this._bridge.update(name, data); + } + set(name, data) { + this.checkName(name); + this.checkData(data); + return this._bridge.set(name, data); + } + setPath(name, path, data) { + this.checkName(name); + this.checkPath(path); + const isTopLevelPath = path === ""; + if (isTopLevelPath) { + this.checkData(data); + return this.set(name, data); + } + return this._bridge.setPath(name, path, data); + } + setPaths(name, paths) { + this.checkName(name); + if (!Array.isArray(paths)) { + throw new Error("Please provide the paths as an array of PathValues!"); + } + for (const { path, value } of paths) { + this.checkPath(path); + const isTopLevelPath = path === ""; + if (isTopLevelPath) { + this.checkData(value); + } + } + return this._bridge.setPaths(name, paths); + } + subscribe(name, callback) { + this.checkName(name); + if (typeof callback !== "function") { + throw new Error("Please provide the callback as a function!"); + } + return this._bridge + .subscribe(name, (data, delta, removed, key, extraData) => callback(data, delta, removed, () => this._bridge.unsubscribe(key), extraData)) + .then((key) => () => { + this._bridge.unsubscribe(key); + }); + } + get(name) { + this.checkName(name); + return this._bridge.get(name); + } + ready() { + return Promise.resolve(this); + } + destroy(name) { + this.checkName(name); + return this._bridge.destroy(name); + } + get setPathSupported() { + return this._bridge.setPathSupported; + } + checkName(name) { + if (typeof name !== "string" || name === "") { + throw new Error("Please provide the name as a non-empty string!"); + } + } + checkPath(path) { + if (typeof path !== "string") { + throw new Error("Please provide the path as a dot delimited string!"); + } + } + checkData(data) { + if (typeof data !== "object") { + throw new Error("Please provide the data as an object!"); + } + } + } + + function promisify$2 (promise, successCallback, errorCallback) { + if (typeof successCallback !== "function" && typeof errorCallback !== "function") { + return promise; + } + if (typeof successCallback !== "function") { + successCallback = () => { }; + } + else if (typeof errorCallback !== "function") { + errorCallback = () => { }; + } + return promise.then(successCallback, errorCallback); + } + + function rejectAfter(ms = 0, promise, error) { + let timeout; + const clearTimeoutIfThere = () => { + if (timeout) { + clearTimeout(timeout); + } + }; + promise + .then(() => { + clearTimeoutIfThere(); + }) + .catch(() => { + clearTimeoutIfThere(); + }); + return new Promise((resolve, reject) => { + timeout = setTimeout(() => reject(error), ms); + }); + } + + var InvokeStatus; + (function (InvokeStatus) { + InvokeStatus[InvokeStatus["Success"] = 0] = "Success"; + InvokeStatus[InvokeStatus["Error"] = 1] = "Error"; + })(InvokeStatus || (InvokeStatus = {})); + class Client { + protocol; + repo; + instance; + configuration; + constructor(protocol, repo, instance, configuration) { + this.protocol = protocol; + this.repo = repo; + this.instance = instance; + this.configuration = configuration; + } + subscribe(method, options, successCallback, errorCallback, existingSub) { + const callProtocolSubscribe = (targetServers, stream, successProxy, errorProxy) => { + options.methodResponseTimeout = options.methodResponseTimeout ?? options.waitTimeoutMs; + this.protocol.client.subscribe(stream, options, targetServers, successProxy, errorProxy, existingSub); + }; + const promise = new Promise((resolve, reject) => { + const successProxy = (sub) => { + resolve(sub); + }; + const errorProxy = (err) => { + reject(err); + }; + if (!method) { + reject(`Method definition is required. Please, provide either a unique string for a method name or a “methodDefinition” object with a required “name” property.`); + return; + } + let methodDef; + if (typeof method === "string") { + methodDef = { name: method }; + } + else { + methodDef = method; + } + if (!methodDef.name) { + reject(`Method definition is required. Please, provide either a unique string for a method name or a “methodDefinition” object with a required “name” property.`); + return; + } + if (options === undefined) { + options = {}; + } + let target = options.target; + if (target === undefined) { + target = "best"; + } + if (typeof target === "string" && target !== "all" && target !== "best") { + reject(new Error(`"${target}" is not a valid target. Valid targets are "all", "best", or an instance.`)); + return; + } + if (options.methodResponseTimeout === undefined) { + options.methodResponseTimeout = options.method_response_timeout; + if (options.methodResponseTimeout === undefined) { + options.methodResponseTimeout = this.configuration.methodResponseTimeout; + } + } + if (options.waitTimeoutMs === undefined) { + options.waitTimeoutMs = options.wait_for_method_timeout; + if (options.waitTimeoutMs === undefined) { + options.waitTimeoutMs = this.configuration.waitTimeoutMs; + } + } + const delayStep = 500; + let delayTillNow = 0; + let currentServers = this.getServerMethodsByFilterAndTarget(methodDef, target); + if (currentServers.length > 0) { + callProtocolSubscribe(currentServers, currentServers[0].methods[0], successProxy, errorProxy); + } + else { + const retry = () => { + if (!target || !(options.waitTimeoutMs)) { + return; + } + delayTillNow += delayStep; + currentServers = this.getServerMethodsByFilterAndTarget(methodDef, target); + if (currentServers.length > 0) { + const streamInfo = currentServers[0].methods[0]; + callProtocolSubscribe(currentServers, streamInfo, successProxy, errorProxy); + } + else if (delayTillNow >= options.waitTimeoutMs) { + const def = typeof method === "string" ? { name: method } : method; + callProtocolSubscribe(currentServers, def, successProxy, errorProxy); + } + else { + setTimeout(retry, delayStep); + } + }; + setTimeout(retry, delayStep); + } + }); + return promisify$2(promise, successCallback, errorCallback); + } + servers(methodFilter) { + const filterCopy = methodFilter === undefined + ? undefined + : { ...methodFilter }; + return this.getServers(filterCopy).map((serverMethodMap) => { + return serverMethodMap.server.instance; + }); + } + methods(methodFilter) { + if (typeof methodFilter === "string") { + methodFilter = { name: methodFilter }; + } + else { + methodFilter = { ...methodFilter }; + } + return this.getMethods(methodFilter); + } + methodsForInstance(instance) { + return this.getMethodsForInstance(instance); + } + methodAdded(callback) { + return this.repo.onMethodAdded(callback); + } + methodRemoved(callback) { + return this.repo.onMethodRemoved(callback); + } + serverAdded(callback) { + return this.repo.onServerAdded(callback); + } + serverRemoved(callback) { + return this.repo.onServerRemoved((server, reason) => { + callback(server, reason); + }); + } + serverMethodAdded(callback) { + return this.repo.onServerMethodAdded((server, method) => { + callback({ server, method }); + }); + } + serverMethodRemoved(callback) { + return this.repo.onServerMethodRemoved((server, method) => { + callback({ server, method }); + }); + } + async invoke(methodFilter, argumentObj, target, additionalOptions, success, error) { + const getInvokePromise = async () => { + let methodDefinition; + if (typeof methodFilter === "string") { + methodDefinition = { name: methodFilter }; + } + else { + methodDefinition = { ...methodFilter }; + } + if (!methodDefinition.name) { + return Promise.reject(`Method definition is required. Please, provide either a unique string for a method name or a “methodDefinition” object with a required “name” property.`); + } + if (!argumentObj) { + argumentObj = {}; + } + if (!target) { + target = "best"; + } + if (typeof target === "string" && target !== "all" && target !== "best" && target !== "skipMine") { + return Promise.reject(new Error(`"${target}" is not a valid target. Valid targets are "all" and "best".`)); + } + if (!additionalOptions) { + additionalOptions = {}; + } + if (additionalOptions.methodResponseTimeoutMs === undefined) { + additionalOptions.methodResponseTimeoutMs = additionalOptions.method_response_timeout; + if (additionalOptions.methodResponseTimeoutMs === undefined) { + additionalOptions.methodResponseTimeoutMs = this.configuration.methodResponseTimeout; + } + } + if (additionalOptions.waitTimeoutMs === undefined) { + additionalOptions.waitTimeoutMs = additionalOptions.wait_for_method_timeout; + if (additionalOptions.waitTimeoutMs === undefined) { + additionalOptions.waitTimeoutMs = this.configuration.waitTimeoutMs; + } + } + if (additionalOptions.waitTimeoutMs !== undefined && typeof additionalOptions.waitTimeoutMs !== "number") { + return Promise.reject(new Error(`"${additionalOptions.waitTimeoutMs}" is not a valid number for "waitTimeoutMs" `)); + } + if (typeof argumentObj !== "object") { + return Promise.reject(new Error(`The method arguments must be an object. method: ${methodDefinition.name}`)); + } + let serversMethodMap = this.getServerMethodsByFilterAndTarget(methodDefinition, target); + if (serversMethodMap.length === 0) { + try { + serversMethodMap = await this.tryToAwaitForMethods(methodDefinition, target, additionalOptions); + } + catch (err) { + const method = { + ...methodDefinition, + getServers: () => [], + supportsStreaming: false, + objectTypes: methodDefinition.objectTypes ?? [], + flags: methodDefinition.flags?.metadata ?? {} + }; + const errorObj = { + method, + called_with: argumentObj, + message: `Can not find a method matching ${JSON.stringify(methodFilter)} with server filter ${JSON.stringify(target)}`, + executed_by: undefined, + returned: undefined, + status: undefined, + }; + return Promise.reject(errorObj); + } + } + const timeout = additionalOptions.methodResponseTimeoutMs; + const additionalOptionsCopy = additionalOptions; + const invokePromises = serversMethodMap.map((serversMethodPair) => { + const invId = nanoid$1(10); + const method = serversMethodPair.methods[0]; + const server = serversMethodPair.server; + const invokePromise = this.protocol.client.invoke(invId, method, argumentObj, server, additionalOptionsCopy); + return Promise.race([ + invokePromise, + rejectAfter(timeout, invokePromise, { + invocationId: invId, + message: `Invocation timeout (${timeout} ms) reached for method name: ${method?.name}, target instance: ${JSON.stringify(server.instance)}, options: ${JSON.stringify(additionalOptionsCopy)}`, + status: InvokeStatus.Error, + }) + ]); + }); + const invocationMessages = await Promise.all(invokePromises); + const results = this.getInvocationResultObj(invocationMessages, methodDefinition, argumentObj); + const allRejected = invocationMessages.every((result) => result.status === InvokeStatus.Error); + if (allRejected) { + return Promise.reject(results); + } + return results; + }; + return promisify$2(getInvokePromise(), success, error); + } + getInvocationResultObj(invocationResults, method, calledWith) { + const all_return_values = invocationResults + .filter((invokeMessage) => invokeMessage.status === InvokeStatus.Success) + .reduce((allValues, currentValue) => { + allValues = [ + ...allValues, + { + executed_by: currentValue.instance, + returned: currentValue.result, + called_with: calledWith, + method, + message: currentValue.message, + status: currentValue.status, + } + ]; + return allValues; + }, []); + const all_errors = invocationResults + .filter((invokeMessage) => invokeMessage.status === InvokeStatus.Error) + .reduce((allErrors, currError) => { + allErrors = [ + ...allErrors, + { + executed_by: currError.instance, + called_with: calledWith, + name: method.name, + message: currError.message, + } + ]; + return allErrors; + }, []); + const invResult = invocationResults[0]; + const result = { + method, + called_with: calledWith, + returned: invResult.result, + executed_by: invResult.instance, + all_return_values, + all_errors, + message: invResult.message, + status: invResult.status + }; + return result; + } + tryToAwaitForMethods(methodDefinition, target, additionalOptions) { + return new Promise((resolve, reject) => { + if (additionalOptions.waitTimeoutMs === 0) { + reject(); + return; + } + const delayStep = 500; + let delayTillNow = 0; + const retry = () => { + delayTillNow += delayStep; + const serversMethodMap = this.getServerMethodsByFilterAndTarget(methodDefinition, target); + if (serversMethodMap.length > 0) { + clearInterval(interval); + resolve(serversMethodMap); + } + else if (delayTillNow >= (additionalOptions.waitTimeoutMs || 10000)) { + clearInterval(interval); + reject(); + return; + } + }; + const interval = setInterval(retry, delayStep); + }); + } + filterByTarget(target, serverMethodMap) { + if (typeof target === "string") { + if (target === "all") { + return [...serverMethodMap]; + } + else if (target === "best") { + const localMachine = serverMethodMap + .find((s) => s.server.instance.isLocal); + if (localMachine) { + return [localMachine]; + } + if (serverMethodMap[0] !== undefined) { + return [serverMethodMap[0]]; + } + } + else if (target === "skipMine") { + return serverMethodMap.filter(({ server }) => server.instance.peerId !== this.instance.peerId); + } + } + else { + let targetArray; + if (!Array.isArray(target)) { + targetArray = [target]; + } + else { + targetArray = target; + } + const allServersMatching = targetArray.reduce((matches, filter) => { + const myMatches = serverMethodMap.filter((serverMethodPair) => { + return this.instanceMatch(filter, serverMethodPair.server.instance); + }); + return matches.concat(myMatches); + }, []); + return allServersMatching; + } + return []; + } + instanceMatch(instanceFilter, instanceDefinition) { + if (instanceFilter?.peerId && instanceFilter?.instance) { + instanceFilter = { ...instanceFilter }; + delete instanceFilter.peerId; + } + return this.containsProps(instanceFilter, instanceDefinition); + } + methodMatch(methodFilter, methodDefinition) { + return this.containsProps(methodFilter, methodDefinition); + } + containsProps(filter, repoMethod) { + const filterProps = Object.keys(filter) + .filter((prop) => { + return filter[prop] !== undefined + && filter[prop] !== null + && typeof filter[prop] !== "function" + && prop !== "object_types" + && prop !== "display_name" + && prop !== "id" + && prop !== "gatewayId" + && prop !== "identifier" + && prop[0] !== "_"; + }); + return filterProps.every((prop) => { + let isMatch; + const filterValue = filter[prop]; + const repoMethodValue = repoMethod[prop]; + switch (prop) { + case "objectTypes": + isMatch = (filterValue || []).every((filterValueEl) => { + return (repoMethodValue || []).includes(filterValueEl); + }); + break; + case "flags": + isMatch = isSubset(repoMethodValue || {}, filterValue || {}); + break; + default: + isMatch = String(filterValue).toLowerCase() === String(repoMethodValue).toLowerCase(); + } + return isMatch; + }); + } + getMethods(methodFilter) { + if (methodFilter === undefined) { + return this.repo.getMethods(); + } + const methods = this.repo.getMethods().filter((method) => { + return this.methodMatch(methodFilter, method); + }); + return methods; + } + getMethodsForInstance(instanceFilter) { + const allServers = this.repo.getServers(); + const matchingServers = allServers.filter((server) => { + return this.instanceMatch(instanceFilter, server.instance); + }); + if (matchingServers.length === 0) { + return []; + } + let resultMethodsObject = {}; + if (matchingServers.length === 1) { + resultMethodsObject = matchingServers[0].methods; + } + else { + matchingServers.forEach((server) => { + Object.keys(server.methods).forEach((methodKey) => { + const method = server.methods[methodKey]; + resultMethodsObject[method.identifier] = method; + }); + }); + } + return Object.keys(resultMethodsObject) + .map((key) => { + return resultMethodsObject[key]; + }); + } + getServers(methodFilter) { + const servers = this.repo.getServers(); + if (methodFilter === undefined) { + return servers.map((server) => { + return { server, methods: [] }; + }); + } + return servers.reduce((prev, current) => { + const methodsForServer = Object.values(current.methods); + const matchingMethods = methodsForServer.filter((method) => { + return this.methodMatch(methodFilter, method); + }); + if (matchingMethods.length > 0) { + prev.push({ server: current, methods: matchingMethods }); + } + return prev; + }, []); + } + getServerMethodsByFilterAndTarget(methodFilter, target) { + const serversMethodMap = this.getServers(methodFilter); + return this.filterByTarget(target, serversMethodMap); + } + } + + class ServerSubscription { + protocol; + repoMethod; + subscription; + constructor(protocol, repoMethod, subscription) { + this.protocol = protocol; + this.repoMethod = repoMethod; + this.subscription = subscription; + } + get stream() { + if (!this.repoMethod.stream) { + throw new Error("no stream"); + } + return this.repoMethod.stream; + } + get arguments() { return this.subscription.arguments || {}; } + get branchKey() { return this.subscription.branchKey; } + get instance() { + if (!this.subscription.instance) { + throw new Error("no instance"); + } + return this.subscription.instance; + } + close() { + this.protocol.server.closeSingleSubscription(this.repoMethod, this.subscription); + } + push(data) { + this.protocol.server.pushDataToSingle(this.repoMethod, this.subscription, data); + } + } + + class Request { + protocol; + repoMethod; + requestContext; + arguments; + instance; + constructor(protocol, repoMethod, requestContext) { + this.protocol = protocol; + this.repoMethod = repoMethod; + this.requestContext = requestContext; + this.arguments = requestContext.arguments; + this.instance = requestContext.instance; + } + accept() { + this.protocol.server.acceptRequestOnBranch(this.requestContext, this.repoMethod, ""); + } + acceptOnBranch(branch) { + this.protocol.server.acceptRequestOnBranch(this.requestContext, this.repoMethod, branch); + } + reject(reason) { + this.protocol.server.rejectRequest(this.requestContext, this.repoMethod, reason); + } + } + + let ServerStreaming$1 = class ServerStreaming { + protocol; + server; + constructor(protocol, server) { + this.protocol = protocol; + this.server = server; + protocol.server.onSubRequest((rc, rm) => this.handleSubRequest(rc, rm)); + protocol.server.onSubAdded((sub, rm) => this.handleSubAdded(sub, rm)); + protocol.server.onSubRemoved((sub, rm) => this.handleSubRemoved(sub, rm)); + } + handleSubRequest(requestContext, repoMethod) { + if (!(repoMethod && + repoMethod.streamCallbacks && + typeof repoMethod.streamCallbacks.subscriptionRequestHandler === "function")) { + return; + } + const request = new Request(this.protocol, repoMethod, requestContext); + repoMethod.streamCallbacks.subscriptionRequestHandler(request); + } + handleSubAdded(subscription, repoMethod) { + if (!(repoMethod && + repoMethod.streamCallbacks && + typeof repoMethod.streamCallbacks.subscriptionAddedHandler === "function")) { + return; + } + const sub = new ServerSubscription(this.protocol, repoMethod, subscription); + repoMethod.streamCallbacks.subscriptionAddedHandler(sub); + } + handleSubRemoved(subscription, repoMethod) { + if (!(repoMethod && + repoMethod.streamCallbacks && + typeof repoMethod.streamCallbacks.subscriptionRemovedHandler === "function")) { + return; + } + const sub = new ServerSubscription(this.protocol, repoMethod, subscription); + repoMethod.streamCallbacks.subscriptionRemovedHandler(sub); + } + }; + + class ServerBranch { + key; + protocol; + repoMethod; + constructor(key, protocol, repoMethod) { + this.key = key; + this.protocol = protocol; + this.repoMethod = repoMethod; + } + subscriptions() { + const subList = this.protocol.server.getSubscriptionList(this.repoMethod, this.key); + return subList.map((sub) => { + return new ServerSubscription(this.protocol, this.repoMethod, sub); + }); + } + close() { + this.protocol.server.closeAllSubscriptions(this.repoMethod, this.key); + } + push(data) { + this.protocol.server.pushData(this.repoMethod, data, [this.key]); + } + } + + class ServerStream { + _protocol; + _repoMethod; + _server; + name; + constructor(_protocol, _repoMethod, _server) { + this._protocol = _protocol; + this._repoMethod = _repoMethod; + this._server = _server; + this.name = this._repoMethod.definition.name; + } + branches(key) { + const bList = this._protocol.server.getBranchList(this._repoMethod); + if (key) { + if (bList.indexOf(key) > -1) { + return new ServerBranch(key, this._protocol, this._repoMethod); + } + return undefined; + } + else { + return bList.map((branchKey) => { + return new ServerBranch(branchKey, this._protocol, this._repoMethod); + }); + } + } + branch(key) { + return this.branches(key); + } + subscriptions() { + const subList = this._protocol.server.getSubscriptionList(this._repoMethod); + return subList.map((sub) => { + return new ServerSubscription(this._protocol, this._repoMethod, sub); + }); + } + get definition() { + const def2 = this._repoMethod.definition; + return { + accepts: def2.accepts, + description: def2.description, + displayName: def2.displayName, + name: def2.name, + objectTypes: def2.objectTypes, + returns: def2.returns, + supportsStreaming: def2.supportsStreaming, + flags: def2.flags?.metadata, + }; + } + close() { + this._protocol.server.closeAllSubscriptions(this._repoMethod); + this._server.unregister(this._repoMethod.definition, true); + } + push(data, branches) { + if (typeof branches !== "string" && !Array.isArray(branches) && branches !== undefined) { + throw new Error("invalid branches should be string or string array"); + } + if (typeof data !== "object") { + throw new Error("Invalid arguments. Data must be an object."); + } + this._protocol.server.pushData(this._repoMethod, data, branches); + } + updateRepoMethod(repoMethod) { + this._repoMethod = repoMethod; + } + } + + class Server { + protocol; + serverRepository; + streaming; + invocations = 0; + currentlyUnregistering = {}; + constructor(protocol, serverRepository) { + this.protocol = protocol; + this.serverRepository = serverRepository; + this.streaming = new ServerStreaming$1(protocol, this); + this.protocol.server.onInvoked(this.onMethodInvoked.bind(this)); + } + createStream(streamDef, callbacks, successCallback, errorCallback, existingStream) { + const promise = new Promise((resolve, reject) => { + if (!streamDef) { + reject("The stream name must be unique! Please, provide either a unique string for a stream name to “glue.interop.createStream()” or a “methodDefinition” object with a unique “name” property for the stream."); + return; + } + let streamMethodDefinition; + if (typeof streamDef === "string") { + streamMethodDefinition = { name: "" + streamDef }; + } + else { + streamMethodDefinition = { ...streamDef }; + } + if (!streamMethodDefinition.name) { + return reject(`The “name” property is required for the “streamDefinition” object and must be unique. Stream definition: ${JSON.stringify(streamMethodDefinition)}`); + } + const nameAlreadyExists = this.serverRepository.getList() + .some((serverMethod) => serverMethod.definition.name === streamMethodDefinition.name); + if (nameAlreadyExists) { + return reject(`A stream with the name "${streamMethodDefinition.name}" already exists! Please, provide a unique name for the stream.`); + } + streamMethodDefinition.supportsStreaming = true; + if (!callbacks) { + callbacks = {}; + } + if (typeof callbacks.subscriptionRequestHandler !== "function") { + callbacks.subscriptionRequestHandler = (request) => { + request.accept(); + }; + } + const repoMethod = this.serverRepository.add({ + definition: streamMethodDefinition, + streamCallbacks: callbacks, + protocolState: {}, + }); + this.protocol.server.createStream(repoMethod) + .then(() => { + let streamUserObject; + if (existingStream) { + streamUserObject = existingStream; + existingStream.updateRepoMethod(repoMethod); + } + else { + streamUserObject = new ServerStream(this.protocol, repoMethod, this); + } + repoMethod.stream = streamUserObject; + resolve(streamUserObject); + }) + .catch((err) => { + if (repoMethod.repoId) { + this.serverRepository.remove(repoMethod.repoId); + } + reject(err); + }); + }); + return promisify$2(promise, successCallback, errorCallback); + } + register(methodDefinition, callback) { + if (!methodDefinition) { + return Promise.reject("Method definition is required. Please, provide either a unique string for a method name or a “methodDefinition” object with a required “name” property."); + } + if (typeof callback !== "function") { + return Promise.reject(`The second parameter must be a callback function. Method: ${typeof methodDefinition === "string" ? methodDefinition : methodDefinition.name}`); + } + const wrappedCallbackFunction = async (context, resultCallback) => { + try { + const result = callback(context.args, context.instance); + if (result && typeof result.then === "function") { + const resultValue = await result; + resultCallback(undefined, resultValue); + } + else { + resultCallback(undefined, result); + } + } + catch (e) { + resultCallback(e ?? "", e ?? ""); + } + }; + wrappedCallbackFunction.userCallback = callback; + return this.registerCore(methodDefinition, wrappedCallbackFunction); + } + registerAsync(methodDefinition, callback) { + if (!methodDefinition) { + return Promise.reject("Method definition is required. Please, provide either a unique string for a method name or a “methodDefinition” object with a required “name” property."); + } + if (typeof callback !== "function") { + return Promise.reject(`The second parameter must be a callback function. Method: ${typeof methodDefinition === "string" ? methodDefinition : methodDefinition.name}`); + } + const wrappedCallback = async (context, resultCallback) => { + try { + let resultCalled = false; + const success = (result) => { + if (!resultCalled) { + resultCallback(undefined, result); + } + resultCalled = true; + }; + const error = (e) => { + if (!resultCalled) { + if (!e) { + e = ""; + } + resultCallback(e, e); + } + resultCalled = true; + }; + const methodResult = callback(context.args, context.instance, success, error); + if (methodResult && typeof methodResult.then === "function") { + methodResult + .then(success) + .catch(error); + } + } + catch (e) { + resultCallback(e, undefined); + } + }; + wrappedCallback.userCallbackAsync = callback; + return this.registerCore(methodDefinition, wrappedCallback); + } + async unregister(methodFilter, forStream = false) { + if (methodFilter === undefined) { + return Promise.reject("Please, provide either a unique string for a name or an object containing a “name” property."); + } + if (typeof methodFilter === "function") { + await this.unregisterWithPredicate(methodFilter, forStream); + return; + } + let methodDefinition; + if (typeof methodFilter === "string") { + methodDefinition = { name: methodFilter }; + } + else { + methodDefinition = methodFilter; + } + if (methodDefinition.name === undefined) { + return Promise.reject("Method name is required. Cannot find a method if the method name is undefined!"); + } + const methodToBeRemoved = this.serverRepository.getList().find((serverMethod) => { + return serverMethod.definition.name === methodDefinition.name + && (serverMethod.definition.supportsStreaming || false) === forStream; + }); + if (!methodToBeRemoved) { + return Promise.reject(`Method with a name "${methodDefinition.name}" does not exist or is not registered by your application!`); + } + await this.removeMethodsOrStreams([methodToBeRemoved]); + } + async unregisterWithPredicate(filterPredicate, forStream) { + const methodsOrStreamsToRemove = this.serverRepository.getList() + .filter((sm) => filterPredicate(sm.definition)) + .filter((serverMethod) => (serverMethod.definition.supportsStreaming || false) === forStream); + if (!methodsOrStreamsToRemove || methodsOrStreamsToRemove.length === 0) { + return Promise.reject(`Could not find a ${forStream ? "stream" : "method"} matching the specified condition!`); + } + await this.removeMethodsOrStreams(methodsOrStreamsToRemove); + } + removeMethodsOrStreams(methodsToRemove) { + const methodUnregPromises = []; + methodsToRemove.forEach((method) => { + const promise = this.protocol.server.unregister(method) + .then(() => { + if (method.repoId) { + this.serverRepository.remove(method.repoId); + } + }); + methodUnregPromises.push(promise); + this.addAsCurrentlyUnregistering(method.definition.name, promise); + }); + return Promise.all(methodUnregPromises); + } + async addAsCurrentlyUnregistering(methodName, promise) { + const timeout = new Promise((resolve) => setTimeout(resolve, 5000)); + this.currentlyUnregistering[methodName] = Promise.race([promise, timeout]).then(() => { + delete this.currentlyUnregistering[methodName]; + }); + } + async registerCore(method, theFunction) { + let methodDefinition; + if (typeof method === "string") { + methodDefinition = { name: "" + method }; + } + else { + methodDefinition = { ...method }; + } + if (!methodDefinition.name) { + return Promise.reject(`Please, provide a (unique) string value for the “name” property in the “methodDefinition” object: ${JSON.stringify(method)}`); + } + const unregisterInProgress = this.currentlyUnregistering[methodDefinition.name]; + if (typeof unregisterInProgress !== "undefined") { + await unregisterInProgress; + } + const nameAlreadyExists = this.serverRepository.getList() + .some((serverMethod) => serverMethod.definition.name === methodDefinition.name); + if (nameAlreadyExists) { + return Promise.reject(`A method with the name "${methodDefinition.name}" already exists! Please, provide a unique name for the method.`); + } + if (methodDefinition.supportsStreaming) { + return Promise.reject(`When you create methods with “glue.interop.register()” or “glue.interop.registerAsync()” the property “supportsStreaming” cannot be “true”. If you want “${methodDefinition.name}” to be a stream, please use the “glue.interop.createStream()” method.`); + } + const repoMethod = this.serverRepository.add({ + definition: methodDefinition, + theFunction, + protocolState: {}, + }); + return this.protocol.server.register(repoMethod) + .catch((err) => { + if (repoMethod?.repoId) { + this.serverRepository.remove(repoMethod.repoId); + } + throw err; + }); + } + onMethodInvoked(methodToExecute, invocationId, invocationArgs) { + if (!methodToExecute || !methodToExecute.theFunction) { + return; + } + methodToExecute.theFunction(invocationArgs, (err, result) => { + if (err !== undefined && err !== null) { + if (err.message && typeof err.message === "string") { + err = err.message; + } + else if (typeof err !== "string") { + try { + err = JSON.stringify(err); + } + catch (unStrException) { + err = `un-stringifyable error in onMethodInvoked! Top level prop names: ${Object.keys(err)}`; + } + } + } + if (!result) { + result = {}; + } + else if (typeof result !== "object" || Array.isArray(result)) { + result = { _value: result }; + } + this.protocol.server.methodInvocationResult(methodToExecute, invocationId, err, result); + }); + } + } + + class InstanceWrapper { + wrapped = {}; + constructor(API, instance, connection) { + this.wrapped.getMethods = function () { + return API.methodsForInstance(this); + }; + this.wrapped.getStreams = function () { + return API.methodsForInstance(this).filter((m) => m.supportsStreaming); + }; + if (instance) { + this.refreshWrappedObject(instance); + } + if (connection) { + connection.loggedIn(() => { + this.refresh(connection); + }); + this.refresh(connection); + } + } + unwrap() { + return this.wrapped; + } + refresh(connection) { + if (!connection) { + return; + } + const resolvedIdentity = connection?.resolvedIdentity; + const instance = Object.assign({}, resolvedIdentity ?? {}, { peerId: connection?.peerId }); + this.refreshWrappedObject(instance); + } + refreshWrappedObject(resolvedIdentity) { + Object.keys(resolvedIdentity).forEach((key) => { + this.wrapped[key] = resolvedIdentity[key]; + }); + this.wrapped.user = resolvedIdentity.user; + this.wrapped.instance = resolvedIdentity.instance; + this.wrapped.application = resolvedIdentity.application ?? nanoid$1(10); + this.wrapped.applicationName = resolvedIdentity.applicationName; + this.wrapped.pid = resolvedIdentity.pid ?? resolvedIdentity.process ?? Math.floor(Math.random() * 10000000000); + this.wrapped.machine = resolvedIdentity.machine; + this.wrapped.environment = resolvedIdentity.environment; + this.wrapped.region = resolvedIdentity.region; + this.wrapped.windowId = resolvedIdentity.windowId; + this.wrapped.isLocal = resolvedIdentity.isLocal ?? true; + this.wrapped.api = resolvedIdentity.api; + this.wrapped.service = resolvedIdentity.service; + this.wrapped.peerId = resolvedIdentity.peerId; + } + } + + const hideMethodSystemFlags = (method) => { + return { + ...method, + flags: method.flags.metadata || {} + }; + }; + class ClientRepository { + logger; + API; + servers = {}; + myServer; + methodsCount = {}; + callbacks = CallbackRegistryFactory$1(); + constructor(logger, API) { + this.logger = logger; + this.API = API; + const peerId = this.API.instance.peerId; + this.myServer = { + id: peerId, + methods: {}, + instance: this.API.instance, + wrapper: this.API.unwrappedInstance, + }; + this.servers[peerId] = this.myServer; + } + addServer(info, serverId) { + this.logger.debug(`adding server ${serverId}`); + const current = this.servers[serverId]; + if (current) { + return current.id; + } + const wrapper = new InstanceWrapper(this.API, info); + const serverEntry = { + id: serverId, + methods: {}, + instance: wrapper.unwrap(), + wrapper, + }; + this.servers[serverId] = serverEntry; + this.callbacks.execute("onServerAdded", serverEntry.instance); + return serverId; + } + removeServerById(id, reason) { + const server = this.servers[id]; + if (!server) { + this.logger.warn(`not aware of server ${id}, my state ${JSON.stringify(Object.keys(this.servers))}`); + return; + } + else { + this.logger.debug(`removing server ${id}`); + } + Object.keys(server.methods).forEach((methodId) => { + this.removeServerMethod(id, methodId); + }); + delete this.servers[id]; + this.callbacks.execute("onServerRemoved", server.instance, reason); + } + addServerMethod(serverId, method) { + const server = this.servers[serverId]; + if (!server) { + throw new Error("server does not exists"); + } + if (server.methods[method.id]) { + return; + } + const identifier = this.createMethodIdentifier(method); + const that = this; + const methodDefinition = { + identifier, + gatewayId: method.id, + name: method.name, + displayName: method.display_name, + description: method.description, + version: method.version, + objectTypes: method.object_types || [], + accepts: method.input_signature, + returns: method.result_signature, + supportsStreaming: typeof method.flags !== "undefined" ? method.flags.streaming : false, + flags: method.flags ?? {}, + getServers: () => { + return that.getServersByMethod(identifier); + } + }; + methodDefinition.object_types = methodDefinition.objectTypes; + methodDefinition.display_name = methodDefinition.displayName; + methodDefinition.version = methodDefinition.version; + server.methods[method.id] = methodDefinition; + const clientMethodDefinition = hideMethodSystemFlags(methodDefinition); + if (!this.methodsCount[identifier]) { + this.methodsCount[identifier] = 0; + this.callbacks.execute("onMethodAdded", clientMethodDefinition); + } + this.methodsCount[identifier] = this.methodsCount[identifier] + 1; + this.callbacks.execute("onServerMethodAdded", server.instance, clientMethodDefinition); + return methodDefinition; + } + removeServerMethod(serverId, methodId) { + const server = this.servers[serverId]; + if (!server) { + throw new Error("server does not exists"); + } + const method = server.methods[methodId]; + delete server.methods[methodId]; + const clientMethodDefinition = hideMethodSystemFlags(method); + this.methodsCount[method.identifier] = this.methodsCount[method.identifier] - 1; + if (this.methodsCount[method.identifier] === 0) { + this.callbacks.execute("onMethodRemoved", clientMethodDefinition); + } + this.callbacks.execute("onServerMethodRemoved", server.instance, clientMethodDefinition); + } + getMethods() { + return this.extractMethodsFromServers(Object.values(this.servers)).map(hideMethodSystemFlags); + } + getServers() { + return Object.values(this.servers).map(this.hideServerMethodSystemFlags); + } + onServerAdded(callback) { + const unsubscribeFunc = this.callbacks.add("onServerAdded", callback); + const serversWithMethodsToReplay = this.getServers().map((s) => s.instance); + return this.returnUnsubWithDelayedReplay(unsubscribeFunc, serversWithMethodsToReplay, callback); + } + onMethodAdded(callback) { + const unsubscribeFunc = this.callbacks.add("onMethodAdded", callback); + const methodsToReplay = this.getMethods(); + return this.returnUnsubWithDelayedReplay(unsubscribeFunc, methodsToReplay, callback); + } + onServerMethodAdded(callback) { + const unsubscribeFunc = this.callbacks.add("onServerMethodAdded", callback); + let unsubCalled = false; + const servers = this.getServers(); + setTimeout(() => { + servers.forEach((server) => { + const methods = server.methods; + Object.keys(methods).forEach((methodId) => { + if (!unsubCalled) { + callback(server.instance, methods[methodId]); + } + }); + }); + }, 0); + return () => { + unsubCalled = true; + unsubscribeFunc(); + }; + } + onMethodRemoved(callback) { + const unsubscribeFunc = this.callbacks.add("onMethodRemoved", callback); + return unsubscribeFunc; + } + onServerRemoved(callback) { + const unsubscribeFunc = this.callbacks.add("onServerRemoved", callback); + return unsubscribeFunc; + } + onServerMethodRemoved(callback) { + const unsubscribeFunc = this.callbacks.add("onServerMethodRemoved", callback); + return unsubscribeFunc; + } + getServerById(id) { + const server = this.servers[id]; + if (!server) { + return undefined; + } + return this.hideServerMethodSystemFlags(this.servers[id]); + } + reset() { + Object.keys(this.servers).forEach((key) => { + this.removeServerById(key, "reset"); + }); + this.servers = { + [this.myServer.id]: this.myServer + }; + this.methodsCount = {}; + } + createMethodIdentifier(methodInfo) { + const accepts = methodInfo.input_signature ?? ""; + const returns = methodInfo.result_signature ?? ""; + return (methodInfo.name + accepts + returns).toLowerCase(); + } + getServersByMethod(identifier) { + const allServers = []; + Object.values(this.servers).forEach((server) => { + Object.values(server.methods).forEach((method) => { + if (method.identifier === identifier) { + allServers.push(server.instance); + } + }); + }); + return allServers; + } + returnUnsubWithDelayedReplay(unsubscribeFunc, collectionToReplay, callback) { + let unsubCalled = false; + setTimeout(() => { + collectionToReplay.forEach((item) => { + if (!unsubCalled) { + callback(item); + } + }); + }, 0); + return () => { + unsubCalled = true; + unsubscribeFunc(); + }; + } + hideServerMethodSystemFlags(server) { + const clientMethods = {}; + Object.entries(server.methods).forEach(([name, method]) => { + clientMethods[name] = hideMethodSystemFlags(method); + }); + return { + ...server, + methods: clientMethods + }; + } + extractMethodsFromServers(servers) { + const methods = Object.values(servers).reduce((clientMethods, server) => { + return [...clientMethods, ...Object.values(server.methods)]; + }, []); + return methods; + } + } + + class ServerRepository { + nextId = 0; + methods = []; + add(method) { + method.repoId = String(this.nextId); + this.nextId += 1; + this.methods.push(method); + return method; + } + remove(repoId) { + if (typeof repoId !== "string") { + return new TypeError("Expecting a string"); + } + this.methods = this.methods.filter((m) => { + return m.repoId !== repoId; + }); + } + getById(id) { + if (typeof id !== "string") { + return undefined; + } + return this.methods.find((m) => { + return m.repoId === id; + }); + } + getList() { + return this.methods.map((m) => m); + } + length() { + return this.methods.length; + } + reset() { + this.methods = []; + } + } + + const SUBSCRIPTION_REQUEST = "onSubscriptionRequest"; + const SUBSCRIPTION_ADDED = "onSubscriptionAdded"; + const SUBSCRIPTION_REMOVED = "onSubscriptionRemoved"; + class ServerStreaming { + session; + repository; + serverRepository; + ERR_URI_SUBSCRIPTION_FAILED = "com.tick42.agm.errors.subscription.failure"; + callbacks = CallbackRegistryFactory$1(); + nextStreamId = 0; + constructor(session, repository, serverRepository) { + this.session = session; + this.repository = repository; + this.serverRepository = serverRepository; + session.on("add-interest", (msg) => { + this.handleAddInterest(msg); + }); + session.on("remove-interest", (msg) => { + this.handleRemoveInterest(msg); + }); + } + acceptRequestOnBranch(requestContext, streamingMethod, branch) { + if (typeof branch !== "string") { + branch = ""; + } + if (typeof streamingMethod.protocolState.subscriptionsMap !== "object") { + throw new TypeError("The streaming method is missing its subscriptions."); + } + if (!Array.isArray(streamingMethod.protocolState.branchKeyToStreamIdMap)) { + throw new TypeError("The streaming method is missing its branches."); + } + const streamId = this.getStreamId(streamingMethod, branch); + const key = requestContext.msg.subscription_id; + const subscription = { + id: key, + arguments: requestContext.arguments, + instance: requestContext.instance, + branchKey: branch, + streamId, + subscribeMsg: requestContext.msg, + }; + streamingMethod.protocolState.subscriptionsMap[key] = subscription; + this.session.sendFireAndForget({ + type: "accepted", + subscription_id: key, + stream_id: streamId, + }); + this.callbacks.execute(SUBSCRIPTION_ADDED, subscription, streamingMethod); + } + rejectRequest(requestContext, streamingMethod, reason) { + if (typeof reason !== "string") { + reason = ""; + } + this.sendSubscriptionFailed("Subscription rejected by user. " + reason, requestContext.msg.subscription_id); + } + pushData(streamingMethod, data, branches) { + if (typeof streamingMethod !== "object" || !Array.isArray(streamingMethod.protocolState.branchKeyToStreamIdMap)) { + return; + } + if (typeof data !== "object") { + throw new Error("Invalid arguments. Data must be an object."); + } + if (typeof branches === "string") { + branches = [branches]; + } + else if (!Array.isArray(branches) || branches.length <= 0) { + branches = []; + } + const streamIdList = streamingMethod.protocolState.branchKeyToStreamIdMap + .filter((br) => { + if (!branches || branches.length === 0) { + return true; + } + return branches.indexOf(br.key) >= 0; + }).map((br) => { + return br.streamId; + }); + streamIdList.forEach((streamId) => { + const publishMessage = { + type: "publish", + stream_id: streamId, + data, + }; + this.session.sendFireAndForget(publishMessage); + }); + } + pushDataToSingle(method, subscription, data) { + if (typeof data !== "object") { + throw new Error("Invalid arguments. Data must be an object."); + } + const postMessage = { + type: "post", + subscription_id: subscription.id, + data, + }; + this.session.sendFireAndForget(postMessage); + } + closeSingleSubscription(streamingMethod, subscription) { + if (streamingMethod.protocolState.subscriptionsMap) { + delete streamingMethod.protocolState.subscriptionsMap[subscription.id]; + } + const dropSubscriptionMessage = { + type: "drop-subscription", + subscription_id: subscription.id, + reason: "Server dropping a single subscription", + }; + this.session.sendFireAndForget(dropSubscriptionMessage); + subscription.instance; + this.callbacks.execute(SUBSCRIPTION_REMOVED, subscription, streamingMethod); + } + closeMultipleSubscriptions(streamingMethod, branchKey) { + if (typeof streamingMethod !== "object" || typeof streamingMethod.protocolState.subscriptionsMap !== "object") { + return; + } + if (!streamingMethod.protocolState.subscriptionsMap) { + return; + } + const subscriptionsMap = streamingMethod.protocolState.subscriptionsMap; + let subscriptionsToClose = Object.keys(subscriptionsMap) + .map((key) => { + return subscriptionsMap[key]; + }); + if (typeof branchKey === "string") { + subscriptionsToClose = subscriptionsToClose.filter((sub) => { + return sub.branchKey === branchKey; + }); + } + subscriptionsToClose.forEach((subscription) => { + delete subscriptionsMap[subscription.id]; + const drop = { + type: "drop-subscription", + subscription_id: subscription.id, + reason: "Server dropping all subscriptions on stream_id: " + subscription.streamId, + }; + this.session.sendFireAndForget(drop); + }); + } + getSubscriptionList(streamingMethod, branchKey) { + if (typeof streamingMethod !== "object") { + return []; + } + let subscriptions = []; + if (!streamingMethod.protocolState.subscriptionsMap) { + return []; + } + const subscriptionsMap = streamingMethod.protocolState.subscriptionsMap; + const allSubscriptions = Object.keys(subscriptionsMap) + .map((key) => { + return subscriptionsMap[key]; + }); + if (typeof branchKey !== "string") { + subscriptions = allSubscriptions; + } + else { + subscriptions = allSubscriptions.filter((sub) => { + return sub.branchKey === branchKey; + }); + } + return subscriptions; + } + getBranchList(streamingMethod) { + if (typeof streamingMethod !== "object") { + return []; + } + if (!streamingMethod.protocolState.subscriptionsMap) { + return []; + } + const subscriptionsMap = streamingMethod.protocolState.subscriptionsMap; + const allSubscriptions = Object.keys(subscriptionsMap) + .map((key) => { + return subscriptionsMap[key]; + }); + const result = []; + allSubscriptions.forEach((sub) => { + let branch = ""; + if (typeof sub === "object" && typeof sub.branchKey === "string") { + branch = sub.branchKey; + } + if (result.indexOf(branch) === -1) { + result.push(branch); + } + }); + return result; + } + onSubAdded(callback) { + this.onSubscriptionLifetimeEvent(SUBSCRIPTION_ADDED, callback); + } + onSubRequest(callback) { + this.onSubscriptionLifetimeEvent(SUBSCRIPTION_REQUEST, callback); + } + onSubRemoved(callback) { + this.onSubscriptionLifetimeEvent(SUBSCRIPTION_REMOVED, callback); + } + handleRemoveInterest(msg) { + const streamingMethod = this.serverRepository.getById(msg.method_id); + if (typeof msg.subscription_id !== "string" || + typeof streamingMethod !== "object") { + return; + } + if (!streamingMethod.protocolState.subscriptionsMap) { + return; + } + if (typeof streamingMethod.protocolState.subscriptionsMap[msg.subscription_id] !== "object") { + return; + } + const subscription = streamingMethod.protocolState.subscriptionsMap[msg.subscription_id]; + delete streamingMethod.protocolState.subscriptionsMap[msg.subscription_id]; + this.callbacks.execute(SUBSCRIPTION_REMOVED, subscription, streamingMethod); + } + onSubscriptionLifetimeEvent(eventName, handlerFunc) { + this.callbacks.add(eventName, handlerFunc); + } + getNextStreamId() { + return this.nextStreamId++ + ""; + } + handleAddInterest(msg) { + const caller = this.repository.getServerById(msg.caller_id); + const instance = caller?.instance ?? {}; + const requestContext = { + msg, + arguments: msg.arguments_kv || {}, + instance, + }; + const streamingMethod = this.serverRepository.getById(msg.method_id); + if (streamingMethod === undefined) { + const errorMsg = "No method with id " + msg.method_id + " on this server."; + this.sendSubscriptionFailed(errorMsg, msg.subscription_id); + return; + } + if (streamingMethod.protocolState.subscriptionsMap && + streamingMethod.protocolState.subscriptionsMap[msg.subscription_id]) { + this.sendSubscriptionFailed("A subscription with id " + msg.subscription_id + " already exists.", msg.subscription_id); + return; + } + this.callbacks.execute(SUBSCRIPTION_REQUEST, requestContext, streamingMethod); + } + sendSubscriptionFailed(reason, subscriptionId) { + const errorMessage = { + type: "error", + reason_uri: this.ERR_URI_SUBSCRIPTION_FAILED, + reason, + request_id: subscriptionId, + }; + this.session.sendFireAndForget(errorMessage); + } + getStreamId(streamingMethod, branchKey) { + if (typeof branchKey !== "string") { + branchKey = ""; + } + if (!streamingMethod.protocolState.branchKeyToStreamIdMap) { + throw new Error(`streaming ${streamingMethod.definition.name} method without protocol state`); + } + const needleBranch = streamingMethod.protocolState.branchKeyToStreamIdMap.filter((branch) => { + return branch.key === branchKey; + })[0]; + let streamId = (needleBranch ? needleBranch.streamId : undefined); + if (typeof streamId !== "string" || streamId === "") { + streamId = this.getNextStreamId(); + streamingMethod.protocolState.branchKeyToStreamIdMap.push({ key: branchKey, streamId }); + } + return streamId; + } + } + + class ServerProtocol { + session; + clientRepository; + serverRepository; + logger; + callbacks = CallbackRegistryFactory$1(); + streaming; + constructor(session, clientRepository, serverRepository, logger) { + this.session = session; + this.clientRepository = clientRepository; + this.serverRepository = serverRepository; + this.logger = logger; + this.streaming = new ServerStreaming(session, clientRepository, serverRepository); + this.session.on("invoke", (msg) => this.handleInvokeMessage(msg)); + } + createStream(repoMethod) { + repoMethod.protocolState.subscriptionsMap = {}; + repoMethod.protocolState.branchKeyToStreamIdMap = []; + return this.register(repoMethod, true); + } + register(repoMethod, isStreaming) { + const methodDef = repoMethod.definition; + const flags = Object.assign({}, { metadata: methodDef.flags ?? {} }, { streaming: isStreaming || false }); + const registerMsg = { + type: "register", + methods: [{ + id: repoMethod.repoId, + name: methodDef.name, + display_name: methodDef.displayName, + description: methodDef.description, + version: methodDef.version, + flags, + object_types: methodDef.objectTypes || methodDef.object_types, + input_signature: methodDef.accepts, + result_signature: methodDef.returns, + restrictions: undefined, + }], + }; + return this.session.send(registerMsg, { methodId: repoMethod.repoId }) + .then(() => { + this.logger.debug("registered method " + repoMethod.definition.name + " with id " + repoMethod.repoId); + }) + .catch((msg) => { + this.logger.warn(`failed to register method ${repoMethod.definition.name} with id ${repoMethod.repoId} - ${JSON.stringify(msg)}`); + throw msg; + }); + } + onInvoked(callback) { + this.callbacks.add("onInvoked", callback); + } + methodInvocationResult(method, invocationId, err, result) { + let msg; + if (err || err === "") { + msg = { + type: "error", + request_id: invocationId, + reason_uri: "agm.errors.client_error", + reason: err, + context: result, + peer_id: undefined, + }; + } + else { + msg = { + type: "yield", + invocation_id: invocationId, + peer_id: this.session.peerId, + result, + request_id: undefined, + }; + } + this.session.sendFireAndForget(msg); + } + async unregister(method) { + const msg = { + type: "unregister", + methods: [method.repoId], + }; + await this.session.send(msg); + } + getBranchList(method) { + return this.streaming.getBranchList(method); + } + getSubscriptionList(method, branchKey) { + return this.streaming.getSubscriptionList(method, branchKey); + } + closeAllSubscriptions(method, branchKey) { + this.streaming.closeMultipleSubscriptions(method, branchKey); + } + pushData(method, data, branches) { + this.streaming.pushData(method, data, branches); + } + pushDataToSingle(method, subscription, data) { + this.streaming.pushDataToSingle(method, subscription, data); + } + closeSingleSubscription(method, subscription) { + this.streaming.closeSingleSubscription(method, subscription); + } + acceptRequestOnBranch(requestContext, method, branch) { + this.streaming.acceptRequestOnBranch(requestContext, method, branch); + } + rejectRequest(requestContext, method, reason) { + this.streaming.rejectRequest(requestContext, method, reason); + } + onSubRequest(callback) { + this.streaming.onSubRequest(callback); + } + onSubAdded(callback) { + this.streaming.onSubAdded(callback); + } + onSubRemoved(callback) { + this.streaming.onSubRemoved(callback); + } + handleInvokeMessage(msg) { + const invocationId = msg.invocation_id; + const callerId = msg.caller_id; + const methodId = msg.method_id; + const args = msg.arguments_kv; + const methodList = this.serverRepository.getList(); + const method = methodList.filter((m) => { + return m.repoId === methodId; + })[0]; + if (method === undefined) { + return; + } + const client = this.clientRepository.getServerById(callerId)?.instance; + const invocationArgs = { args, instance: client }; + this.callbacks.execute("onInvoked", method, invocationId, invocationArgs); + } + } + + class UserSubscription { + repository; + subscriptionData; + get requestArguments() { + return this.subscriptionData.params.arguments || {}; + } + get servers() { + return this.subscriptionData.trackedServers.reduce((servers, pair) => { + if (pair.subscriptionId) { + const server = this.repository.getServerById(pair.serverId)?.instance; + if (server) { + servers.push(server); + } + } + return servers; + }, []); + } + get serverInstance() { + return this.servers[0]; + } + get stream() { + return this.subscriptionData.method; + } + constructor(repository, subscriptionData) { + this.repository = repository; + this.subscriptionData = subscriptionData; + } + onData(dataCallback) { + if (typeof dataCallback !== "function") { + throw new TypeError("The data callback must be a function."); + } + this.subscriptionData.handlers.onData.push(dataCallback); + if (this.subscriptionData.handlers.onData.length === 1 && this.subscriptionData.queued.data.length > 0) { + this.subscriptionData.queued.data.forEach((dataItem) => { + dataCallback(dataItem); + }); + } + } + onClosed(closedCallback) { + if (typeof closedCallback !== "function") { + throw new TypeError("The callback must be a function."); + } + this.subscriptionData.handlers.onClosed.push(closedCallback); + } + onFailed(callback) { + } + onConnected(callback) { + if (typeof callback !== "function") { + throw new TypeError("The callback must be a function."); + } + this.subscriptionData.handlers.onConnected.push(callback); + } + close() { + this.subscriptionData.close(); + } + setNewSubscription(newSub) { + this.subscriptionData = newSub; + } + } + + class TimedCache { + config; + cache = []; + timeoutIds = []; + constructor(config) { + this.config = config; + } + add(element) { + const id = nanoid$1(10); + this.cache.push({ id, element }); + const timeoutId = setTimeout(() => { + const elementIdx = this.cache.findIndex((entry) => entry.id === id); + if (elementIdx < 0) { + return; + } + this.cache.splice(elementIdx, 1); + }, this.config.ELEMENT_TTL_MS); + this.timeoutIds.push(timeoutId); + } + flush() { + const elements = this.cache.map((entry) => entry.element); + this.timeoutIds.forEach((id) => clearInterval(id)); + this.cache = []; + this.timeoutIds = []; + return elements; + } + } + + const STATUS_AWAITING_ACCEPT = "awaitingAccept"; + const STATUS_SUBSCRIBED = "subscribed"; + const ERR_MSG_SUB_FAILED = "Subscription failed."; + const ERR_MSG_SUB_REJECTED = "Subscription rejected."; + const ON_CLOSE_MSG_SERVER_INIT = "ServerInitiated"; + const ON_CLOSE_MSG_CLIENT_INIT = "ClientInitiated"; + class ClientStreaming { + session; + repository; + logger; + subscriptionsList = {}; + timedCache = new TimedCache({ ELEMENT_TTL_MS: 10000 }); + subscriptionIdToLocalKeyMap = {}; + nextSubLocalKey = 0; + constructor(session, repository, logger) { + this.session = session; + this.repository = repository; + this.logger = logger; + session.on("subscribed", this.handleSubscribed); + session.on("event", this.handleEventData); + session.on("subscription-cancelled", this.handleSubscriptionCancelled); + } + subscribe(streamingMethod, params, targetServers, success, error, existingSub) { + if (targetServers.length === 0) { + error({ + method: streamingMethod, + called_with: params.arguments, + message: ERR_MSG_SUB_FAILED + " No available servers matched the target params.", + }); + return; + } + const subLocalKey = this.getNextSubscriptionLocalKey(); + const pendingSub = this.registerSubscription(subLocalKey, streamingMethod, params, success, error, params.methodResponseTimeout || 10000, existingSub); + if (typeof pendingSub !== "object") { + error({ + method: streamingMethod, + called_with: params.arguments, + message: ERR_MSG_SUB_FAILED + " Unable to register the user callbacks.", + }); + return; + } + targetServers.forEach((target) => { + const serverId = target.server.id; + const method = target.methods.find((m) => m.name === streamingMethod.name); + if (!method) { + this.logger.error(`can not find method ${streamingMethod.name} for target ${target.server.id}`); + return; + } + pendingSub.trackedServers.push({ + serverId, + subscriptionId: undefined, + }); + const msg = { + type: "subscribe", + server_id: serverId, + method_id: method.gatewayId, + arguments_kv: params.arguments, + }; + this.session.send(msg, { serverId, subLocalKey }) + .then((m) => this.handleSubscribed(m)) + .catch((err) => this.handleErrorSubscribing(err)); + }); + } + drainSubscriptions() { + const existing = Object.values(this.subscriptionsList); + this.subscriptionsList = {}; + this.subscriptionIdToLocalKeyMap = {}; + return existing; + } + drainSubscriptionsCache() { + return this.timedCache.flush(); + } + getNextSubscriptionLocalKey() { + const current = this.nextSubLocalKey; + this.nextSubLocalKey += 1; + return current; + } + registerSubscription(subLocalKey, method, params, success, error, timeout, existingSub) { + const subsInfo = { + localKey: subLocalKey, + status: STATUS_AWAITING_ACCEPT, + method, + params, + success, + error, + trackedServers: [], + handlers: { + onData: existingSub?.handlers.onData || [], + onClosed: existingSub?.handlers.onClosed || [], + onConnected: existingSub?.handlers.onConnected || [], + }, + queued: { + data: [], + closers: [], + }, + timeoutId: undefined, + close: () => this.closeSubscription(subLocalKey), + subscription: existingSub?.subscription + }; + if (!existingSub) { + if (params.onData) { + subsInfo.handlers.onData.push(params.onData); + } + if (params.onClosed) { + subsInfo.handlers.onClosed.push(params.onClosed); + } + if (params.onConnected) { + subsInfo.handlers.onConnected.push(params.onConnected); + } + } + this.subscriptionsList[subLocalKey] = subsInfo; + subsInfo.timeoutId = setTimeout(() => { + if (this.subscriptionsList[subLocalKey] === undefined) { + return; + } + const pendingSub = this.subscriptionsList[subLocalKey]; + if (pendingSub.status === STATUS_AWAITING_ACCEPT) { + error({ + method, + called_with: params.arguments, + message: ERR_MSG_SUB_FAILED + " Subscription attempt timed out after " + timeout + " ms.", + }); + delete this.subscriptionsList[subLocalKey]; + } + else if (pendingSub.status === STATUS_SUBSCRIBED && pendingSub.trackedServers.length > 0) { + pendingSub.trackedServers = pendingSub.trackedServers.filter((server) => { + return (typeof server.subscriptionId !== "undefined"); + }); + delete pendingSub.timeoutId; + if (pendingSub.trackedServers.length <= 0) { + this.callOnClosedHandlers(pendingSub); + delete this.subscriptionsList[subLocalKey]; + } + } + }, timeout); + return subsInfo; + } + handleErrorSubscribing = (errorResponse) => { + const tag = errorResponse._tag; + const subLocalKey = tag.subLocalKey; + const pendingSub = this.subscriptionsList[subLocalKey]; + if (typeof pendingSub !== "object") { + return; + } + pendingSub.trackedServers = pendingSub.trackedServers.filter((server) => { + return server.serverId !== tag.serverId; + }); + if (pendingSub.trackedServers.length <= 0) { + clearTimeout(pendingSub.timeoutId); + if (pendingSub.status === STATUS_AWAITING_ACCEPT) { + const reason = (typeof errorResponse.reason === "string" && errorResponse.reason !== "") ? + ' Publisher said "' + errorResponse.reason + '".' : + " No reason given."; + const callArgs = typeof pendingSub.params.arguments === "object" ? + JSON.stringify(pendingSub.params.arguments) : + "{}"; + pendingSub.error({ + message: ERR_MSG_SUB_REJECTED + reason + " Called with:" + callArgs, + called_with: pendingSub.params.arguments, + method: pendingSub.method, + }); + } + else if (pendingSub.status === STATUS_SUBSCRIBED) { + this.callOnClosedHandlers(pendingSub); + } + delete this.subscriptionsList[subLocalKey]; + } + }; + handleSubscribed = (msg) => { + const subLocalKey = msg._tag.subLocalKey; + const pendingSub = this.subscriptionsList[subLocalKey]; + if (typeof pendingSub !== "object") { + return; + } + const serverId = msg._tag.serverId; + const acceptingServer = pendingSub.trackedServers + .filter((server) => { + return server.serverId === serverId; + })[0]; + if (typeof acceptingServer !== "object") { + return; + } + acceptingServer.subscriptionId = msg.subscription_id; + this.subscriptionIdToLocalKeyMap[msg.subscription_id] = subLocalKey; + const isFirstResponse = (pendingSub.status === STATUS_AWAITING_ACCEPT); + pendingSub.status = STATUS_SUBSCRIBED; + if (isFirstResponse) { + let reconnect = false; + let sub = pendingSub.subscription; + if (sub) { + sub.setNewSubscription(pendingSub); + pendingSub.success(sub); + reconnect = true; + } + else { + sub = new UserSubscription(this.repository, pendingSub); + pendingSub.subscription = sub; + pendingSub.success(sub); + } + for (const handler of pendingSub.handlers.onConnected) { + try { + handler(sub.serverInstance, reconnect); + } + catch (e) { + } + } + } + }; + handleEventData = (msg) => { + const subLocalKey = this.subscriptionIdToLocalKeyMap[msg.subscription_id]; + if (typeof subLocalKey === "undefined") { + return; + } + const subscription = this.subscriptionsList[subLocalKey]; + if (typeof subscription !== "object") { + return; + } + const trackedServersFound = subscription.trackedServers.filter((s) => { + return s.subscriptionId === msg.subscription_id; + }); + if (trackedServersFound.length !== 1) { + return; + } + const isPrivateData = msg.oob; + const sendingServerId = trackedServersFound[0].serverId; + const server = this.repository.getServerById(sendingServerId); + const receivedStreamData = () => { + return { + data: msg.data, + server: server?.instance ?? {}, + requestArguments: subscription.params.arguments, + message: undefined, + private: isPrivateData, + }; + }; + const onDataHandlers = subscription.handlers.onData; + const queuedData = subscription.queued.data; + if (onDataHandlers.length > 0) { + onDataHandlers.forEach((callback) => { + if (typeof callback === "function") { + callback(receivedStreamData()); + } + }); + } + else { + queuedData.push(receivedStreamData()); + } + }; + handleSubscriptionCancelled = (msg) => { + const subLocalKey = this.subscriptionIdToLocalKeyMap[msg.subscription_id]; + if (typeof subLocalKey === "undefined") { + return; + } + const subscription = this.subscriptionsList[subLocalKey]; + if (typeof subscription !== "object") { + return; + } + const expectedNewLength = subscription.trackedServers.length - 1; + subscription.trackedServers = subscription.trackedServers.filter((server) => { + if (server.subscriptionId === msg.subscription_id) { + subscription.queued.closers.push(server.serverId); + return false; + } + else { + return true; + } + }); + if (subscription.trackedServers.length !== expectedNewLength) { + return; + } + if (subscription.trackedServers.length <= 0) { + this.timedCache.add(subscription); + clearTimeout(subscription.timeoutId); + this.callOnClosedHandlers(subscription); + delete this.subscriptionsList[subLocalKey]; + } + delete this.subscriptionIdToLocalKeyMap[msg.subscription_id]; + }; + callOnClosedHandlers(subscription, reason) { + const closersCount = subscription.queued.closers.length; + const closingServerId = (closersCount > 0) ? subscription.queued.closers[closersCount - 1] : null; + let closingServer; + if (closingServerId !== undefined && typeof closingServerId === "string") { + closingServer = this.repository.getServerById(closingServerId)?.instance ?? {}; + } + subscription.handlers.onClosed.forEach((callback) => { + if (typeof callback !== "function") { + return; + } + callback({ + message: reason || ON_CLOSE_MSG_SERVER_INIT, + requestArguments: subscription.params.arguments || {}, + server: closingServer, + stream: subscription.method, + }); + }); + } + closeSubscription(subLocalKey) { + const subscription = this.subscriptionsList[subLocalKey]; + if (typeof subscription !== "object") { + return; + } + subscription.trackedServers.forEach((server) => { + if (typeof server.subscriptionId === "undefined") { + return; + } + subscription.queued.closers.push(server.serverId); + this.session.sendFireAndForget({ + type: "unsubscribe", + subscription_id: server.subscriptionId, + reason_uri: "", + reason: ON_CLOSE_MSG_CLIENT_INIT, + }); + delete this.subscriptionIdToLocalKeyMap[server.subscriptionId]; + }); + subscription.trackedServers = []; + this.callOnClosedHandlers(subscription, ON_CLOSE_MSG_CLIENT_INIT); + delete this.subscriptionsList[subLocalKey]; + } + } + + class ClientProtocol { + session; + repository; + logger; + streaming; + constructor(session, repository, logger) { + this.session = session; + this.repository = repository; + this.logger = logger; + session.on("peer-added", (msg) => this.handlePeerAdded(msg)); + session.on("peer-removed", (msg) => this.handlePeerRemoved(msg)); + session.on("methods-added", (msg) => this.handleMethodsAddedMessage(msg)); + session.on("methods-removed", (msg) => this.handleMethodsRemovedMessage(msg)); + this.streaming = new ClientStreaming(session, repository, logger); + } + subscribe(stream, options, targetServers, success, error, existingSub) { + this.streaming.subscribe(stream, options, targetServers, success, error, existingSub); + } + invoke(id, method, args, target) { + const serverId = target.id; + const methodId = method.gatewayId; + const msg = { + type: "call", + server_id: serverId, + method_id: methodId, + arguments_kv: args, + }; + return this.session.send(msg, { invocationId: id, serverId }) + .then((m) => this.handleResultMessage(m)) + .catch((err) => this.handleInvocationError(err)); + } + drainSubscriptions() { + return this.streaming.drainSubscriptions(); + } + drainSubscriptionsCache() { + return this.streaming.drainSubscriptionsCache(); + } + handlePeerAdded(msg) { + const newPeerId = msg.new_peer_id; + const remoteId = msg.identity; + const isLocal = msg.meta ? msg.meta.local : true; + const pid = Number(remoteId.process); + const serverInfo = { + machine: remoteId.machine, + pid: isNaN(pid) ? remoteId.process : pid, + instance: remoteId.instance, + application: remoteId.application, + applicationName: remoteId.applicationName, + environment: remoteId.environment, + region: remoteId.region, + user: remoteId.user, + windowId: remoteId.windowId, + peerId: newPeerId, + api: remoteId.api, + isLocal + }; + this.repository.addServer(serverInfo, newPeerId); + } + handlePeerRemoved(msg) { + const removedPeerId = msg.removed_id; + const reason = msg.reason; + this.repository.removeServerById(removedPeerId, reason); + } + handleMethodsAddedMessage(msg) { + const serverId = msg.server_id; + const methods = msg.methods; + methods.forEach((method) => { + this.repository.addServerMethod(serverId, method); + }); + } + handleMethodsRemovedMessage(msg) { + const serverId = msg.server_id; + const methodIdList = msg.methods; + const server = this.repository.getServerById(serverId); + if (server) { + const serverMethodKeys = Object.keys(server.methods); + serverMethodKeys.forEach((methodKey) => { + const method = server.methods[methodKey]; + if (methodIdList.indexOf(method.gatewayId) > -1) { + this.repository.removeServerMethod(serverId, methodKey); + } + }); + } + } + handleResultMessage(msg) { + const invocationId = msg._tag.invocationId; + const result = msg.result; + const serverId = msg._tag.serverId; + const server = this.repository.getServerById(serverId); + return { + invocationId, + result, + instance: server?.instance, + status: InvokeStatus.Success, + message: "" + }; + } + handleInvocationError(msg) { + this.logger.debug(`handle invocation error ${JSON.stringify(msg)}`); + if ("_tag" in msg) { + const invocationId = msg._tag.invocationId; + const serverId = msg._tag.serverId; + const server = this.repository.getServerById(serverId); + const message = msg.reason; + const context = msg.context; + return { + invocationId, + result: context, + instance: server?.instance, + status: InvokeStatus.Error, + message + }; + } + else { + return { + invocationId: "", + message: msg.message, + status: InvokeStatus.Error, + error: msg + }; + } + } + } + + function gW3ProtocolFactory (instance, connection, clientRepository, serverRepository, libConfig, interop) { + const logger = libConfig.logger.subLogger("gw3-protocol"); + let resolveReadyPromise; + const readyPromise = new Promise((resolve) => { + resolveReadyPromise = resolve; + }); + const session = connection.domain("agm", ["subscribed"]); + const server = new ServerProtocol(session, clientRepository, serverRepository, logger.subLogger("server")); + const client = new ClientProtocol(session, clientRepository, logger.subLogger("client")); + async function handleReconnect() { + logger.info("reconnected - will replay registered methods and subscriptions"); + client.drainSubscriptionsCache().forEach((sub) => { + const methodInfo = sub.method; + const params = Object.assign({}, sub.params); + logger.info(`trying to soft-re-subscribe to method ${methodInfo.name}, with params: ${JSON.stringify(params)}`); + interop.client.subscribe(methodInfo, params, undefined, undefined, sub).then(() => logger.info(`soft-subscribing to method ${methodInfo.name} DONE`)).catch((error) => logger.warn(`subscribing to method ${methodInfo.name} failed: ${JSON.stringify(error)}}`)); + }); + const reconnectionPromises = []; + const existingSubscriptions = client.drainSubscriptions(); + for (const sub of existingSubscriptions) { + const methodInfo = sub.method; + const params = Object.assign({}, sub.params); + logger.info(`trying to re-subscribe to method ${methodInfo.name}, with params: ${JSON.stringify(params)}`); + reconnectionPromises.push(interop.client.subscribe(methodInfo, params, undefined, undefined, sub).then(() => logger.info(`subscribing to method ${methodInfo.name} DONE`))); + } + const registeredMethods = serverRepository.getList(); + serverRepository.reset(); + for (const method of registeredMethods) { + const def = method.definition; + if (method.stream) { + reconnectionPromises.push(interop.server.createStream(def, method.streamCallbacks, undefined, undefined, method.stream) + .then(() => logger.info(`subscribing to method ${def.name} DONE`)) + .catch(() => logger.warn(`subscribing to method ${def.name} FAILED`))); + } + else if (method?.theFunction?.userCallback) { + reconnectionPromises.push(interop.register(def, method.theFunction.userCallback) + .then(() => logger.info(`registering method ${def.name} DONE`)) + .catch(() => logger.warn(`registering method ${def.name} FAILED`))); + } + else if (method?.theFunction?.userCallbackAsync) { + reconnectionPromises.push(interop.registerAsync(def, method.theFunction.userCallbackAsync) + .then(() => logger.info(`registering method ${def.name} DONE`)) + .catch(() => logger.warn(`registering method ${def.name} FAILED`))); + } + } + await Promise.all(reconnectionPromises); + logger.info("Interop is re-announced"); + } + function handleInitialJoin() { + if (resolveReadyPromise) { + resolveReadyPromise({ + client, + server, + }); + resolveReadyPromise = undefined; + } + } + session.onJoined((reconnect) => { + clientRepository.addServer(instance, connection.peerId); + if (reconnect) { + handleReconnect().then(() => connection.setLibReAnnounced({ name: "interop" })).catch((error) => logger.warn(`Error while re-announcing interop: ${JSON.stringify(error)}`)); + } + else { + handleInitialJoin(); + } + }); + session.onLeft(() => { + clientRepository.reset(); + }); + session.join(); + return readyPromise; + } + + class Interop { + instance; + readyPromise; + client; + server; + unwrappedInstance; + protocol; + clientRepository; + serverRepository; + constructor(configuration) { + if (typeof configuration === "undefined") { + throw new Error("configuration is required"); + } + if (typeof configuration.connection === "undefined") { + throw new Error("configuration.connections is required"); + } + const connection = configuration.connection; + if (typeof configuration.methodResponseTimeout !== "number") { + configuration.methodResponseTimeout = 30 * 1000; + } + if (typeof configuration.waitTimeoutMs !== "number") { + configuration.waitTimeoutMs = 30 * 1000; + } + this.unwrappedInstance = new InstanceWrapper(this, undefined, connection); + this.instance = this.unwrappedInstance.unwrap(); + this.clientRepository = new ClientRepository(configuration.logger.subLogger("cRep"), this); + this.serverRepository = new ServerRepository(); + let protocolPromise; + if (connection.protocolVersion === 3) { + protocolPromise = gW3ProtocolFactory(this.instance, connection, this.clientRepository, this.serverRepository, configuration, this); + } + else { + throw new Error(`protocol ${connection.protocolVersion} not supported`); + } + this.readyPromise = protocolPromise.then((protocol) => { + this.protocol = protocol; + this.client = new Client(this.protocol, this.clientRepository, this.instance, configuration); + this.server = new Server(this.protocol, this.serverRepository); + return this; + }); + } + ready() { + return this.readyPromise; + } + serverRemoved(callback) { + return this.client.serverRemoved(callback); + } + serverAdded(callback) { + return this.client.serverAdded(callback); + } + serverMethodRemoved(callback) { + return this.client.serverMethodRemoved(callback); + } + serverMethodAdded(callback) { + return this.client.serverMethodAdded(callback); + } + methodRemoved(callback) { + return this.client.methodRemoved(callback); + } + methodAdded(callback) { + return this.client.methodAdded(callback); + } + methodsForInstance(instance) { + return this.client.methodsForInstance(instance); + } + methods(methodFilter) { + return this.client.methods(methodFilter); + } + servers(methodFilter) { + return this.client.servers(methodFilter); + } + subscribe(method, options, successCallback, errorCallback) { + return this.client.subscribe(method, options, successCallback, errorCallback); + } + createStream(streamDef, callbacks, successCallback, errorCallback) { + return this.server.createStream(streamDef, callbacks, successCallback, errorCallback); + } + unregister(methodFilter) { + return this.server.unregister(methodFilter); + } + registerAsync(methodDefinition, callback) { + return this.server.registerAsync(methodDefinition, callback); + } + register(methodDefinition, callback) { + return this.server.register(methodDefinition, callback); + } + invoke(methodFilter, argumentObj, target, additionalOptions, success, error) { + return this.client.invoke(methodFilter, argumentObj, target, additionalOptions, success, error); + } + waitForMethod(name) { + const pw = new PromiseWrapper$1(); + const unsubscribe = this.client.methodAdded((m) => { + if (m.name === name) { + unsubscribe(); + pw.resolve(m); + } + }); + return pw.promise; + } + } + + const successMessages = ["subscribed", "success"]; + class MessageBus { + connection; + logger; + peerId; + session; + subscriptions; + readyPromise; + constructor(connection, logger) { + this.connection = connection; + this.logger = logger; + this.peerId = connection.peerId; + this.subscriptions = []; + this.session = connection.domain("bus", successMessages); + this.readyPromise = this.session.join(); + this.readyPromise.then(() => { + this.watchOnEvent(); + }); + } + ready() { + return this.readyPromise; + } + publish = (topic, data, options) => { + const { routingKey, target } = options || {}; + const args = this.removeEmptyValues({ + type: "publish", + topic, + data, + peer_id: this.peerId, + routing_key: routingKey, + target_identity: target + }); + this.session.send(args); + }; + subscribe = (topic, callback, options) => { + return new Promise((resolve, reject) => { + const { routingKey, target } = options || {}; + const args = this.removeEmptyValues({ + type: "subscribe", + topic, + peer_id: this.peerId, + routing_key: routingKey, + source: target + }); + this.session.send(args) + .then((response) => { + const { subscription_id } = response; + this.subscriptions.push({ subscription_id, topic, callback, source: target }); + resolve({ + unsubscribe: () => { + this.session.send({ type: "unsubscribe", subscription_id, peer_id: this.peerId }); + this.subscriptions = this.subscriptions.filter((s) => s.subscription_id !== subscription_id); + return Promise.resolve(); + } + }); + }) + .catch((error) => reject(error)); + }); + }; + watchOnEvent = () => { + this.session.on("event", (args) => { + const { data, subscription_id } = args; + const source = args["publisher-identity"]; + const subscription = this.subscriptions.find((s) => s.subscription_id === subscription_id); + if (subscription) { + if (!subscription.source) { + subscription.callback(data, subscription.topic, source); + } + else { + if (this.keysMatch(subscription.source, source)) { + subscription.callback(data, subscription.topic, source); + } + } + } + }); + }; + removeEmptyValues(obj) { + const cleaned = {}; + Object.keys(obj).forEach((key) => { + if (obj[key] !== undefined && obj[key] !== null) { + cleaned[key] = obj[key]; + } + }); + return cleaned; + } + keysMatch(obj1, obj2) { + const keysObj1 = Object.keys(obj1); + let allMatch = true; + keysObj1.forEach((key) => { + if (obj1[key] !== obj2[key]) { + allMatch = false; + } + }); + return allMatch; + } + } + + const IOConnectCoreFactory = (userConfig, ext) => { + const iodesktop = typeof window === "object" ? (window.iodesktop ?? window.glue42gd) : undefined; + const preloadPromise = typeof window === "object" ? (window.gdPreloadPromise ?? Promise.resolve()) : Promise.resolve(); + const glueInitTimer = timer("glue"); + userConfig = userConfig || {}; + ext = ext || {}; + const internalConfig = prepareConfig$1(userConfig, ext, iodesktop); + let _connection; + let _interop; + let _logger; + let _metrics; + let _contexts; + let _bus; + let _allowTrace; + const libs = {}; + function registerLib(name, inner, t) { + _allowTrace = _logger.canPublish("trace"); + if (_allowTrace) { + _logger.trace(`registering ${name} module`); + } + const done = (e) => { + inner.initTime = t.stop(); + inner.initEndTime = t.endTime; + inner.marks = t.marks; + if (!_allowTrace) { + return; + } + const traceMessage = e ? + `${name} failed - ${e.message}` : + `${name} is ready - ${t.endTime - t.startTime}`; + _logger.trace(traceMessage); + }; + inner.initStartTime = t.startTime; + if (inner.ready) { + inner.ready() + .then(() => { + done(); + }) + .catch((e) => { + const error = typeof e === "string" ? new Error(e) : e; + done(error); + }); + } + else { + done(); + } + if (!Array.isArray(name)) { + name = [name]; + } + name.forEach((n) => { + libs[n] = inner; + IOConnectCoreFactory[n] = inner; + }); + } + function setupConnection() { + const initTimer = timer("connection"); + _connection = new Connection(internalConfig.connection, _logger.subLogger("connection")); + let authPromise = Promise.resolve(internalConfig.auth); + if (internalConfig.connection && !internalConfig.auth) { + if (iodesktop) { + authPromise = iodesktop.getGWToken() + .then((token) => { + return { + gatewayToken: token + }; + }); + } + else if (typeof window !== "undefined" && window?.glue42electron) { + if (typeof window.glue42electron.gwToken === "string") { + authPromise = Promise.resolve({ + gatewayToken: window.glue42electron.gwToken + }); + } + } + else { + authPromise = Promise.reject("You need to provide auth information"); + } + } + return authPromise + .then((authConfig) => { + initTimer.mark("auth-promise-resolved"); + let authRequest; + if (Object.prototype.toString.call(authConfig) === "[object Object]") { + authRequest = authConfig; + } + else { + throw new Error("Invalid auth object - " + JSON.stringify(authConfig)); + } + return _connection.login(authRequest); + }) + .then(() => { + registerLib("connection", _connection, initTimer); + return internalConfig; + }) + .catch((e) => { + if (_connection) { + _connection.logout(); + } + throw e; + }); + } + function setupLogger() { + const initTimer = timer("logger"); + _logger = new Logger$1(`${internalConfig.connection.identity?.application}`, undefined, internalConfig.customLogger); + _logger.consoleLevel(internalConfig.logger.console); + _logger.publishLevel(internalConfig.logger.publish); + if (_logger.canPublish("debug")) { + _logger.debug("initializing glue..."); + } + registerLib("logger", _logger, initTimer); + return Promise.resolve(undefined); + } + function setupMetrics() { + const initTimer = timer("metrics"); + const config = internalConfig.metrics; + const metricsPublishingEnabledFunc = iodesktop?.getMetricsPublishingEnabled; + const identity = internalConfig.connection.identity; + const canUpdateMetric = metricsPublishingEnabledFunc ? metricsPublishingEnabledFunc : () => true; + const disableAutoAppSystem = (typeof config !== "boolean" && config.disableAutoAppSystem) ?? false; + _metrics = metrics({ + connection: config ? _connection : undefined, + logger: _logger.subLogger("metrics"), + canUpdateMetric, + system: "Glue42", + service: identity?.service ?? iodesktop?.applicationName ?? internalConfig.application, + instance: identity?.instance ?? identity?.windowId ?? nanoid$1(10), + disableAutoAppSystem, + pagePerformanceMetrics: typeof config !== "boolean" ? config?.pagePerformanceMetrics : undefined + }); + registerLib("metrics", _metrics, initTimer); + return Promise.resolve(); + } + function setupInterop() { + const initTimer = timer("interop"); + const agmConfig = { + connection: _connection, + logger: _logger.subLogger("interop"), + }; + _interop = new Interop(agmConfig); + Logger$1.Interop = _interop; + registerLib(["interop", "agm"], _interop, initTimer); + return Promise.resolve(); + } + function setupContexts() { + const hasActivities = (internalConfig.activities && _connection.protocolVersion === 3); + const needsContexts = internalConfig.contexts || hasActivities; + if (needsContexts) { + const initTimer = timer("contexts"); + _contexts = new ContextsModule({ + connection: _connection, + logger: _logger.subLogger("contexts"), + trackAllContexts: typeof internalConfig.contexts === "object" ? internalConfig.contexts.trackAllContexts : false, + reAnnounceKnownContexts: typeof internalConfig.contexts === "object" ? internalConfig.contexts.reAnnounceKnownContexts : false + }); + registerLib("contexts", _contexts, initTimer); + return _contexts; + } + else { + const replayer = _connection.replayer; + if (replayer) { + replayer.drain(ContextMessageReplaySpec.name); + } + } + } + async function setupBus() { + if (!internalConfig.bus) { + return Promise.resolve(); + } + const initTimer = timer("bus"); + _bus = new MessageBus(_connection, _logger.subLogger("bus")); + registerLib("bus", _bus, initTimer); + return Promise.resolve(); + } + function setupExternalLibs(externalLibs) { + try { + externalLibs.forEach((lib) => { + setupExternalLib(lib.name, lib.create); + }); + return Promise.resolve(); + } + catch (e) { + return Promise.reject(e); + } + } + function setupExternalLib(name, createCallback) { + const initTimer = timer(name); + const lib = createCallback(libs); + if (lib) { + registerLib(name, lib, initTimer); + } + } + function waitForLibs() { + const libsReadyPromises = Object.keys(libs).map((key) => { + const lib = libs[key]; + return lib.ready ? + lib.ready() : Promise.resolve(); + }); + return Promise.all(libsReadyPromises); + } + function constructGlueObject() { + const feedbackFunc = (feedbackInfo) => { + if (!_interop) { + return; + } + _interop.invoke("T42.ACS.Feedback", feedbackInfo, "best"); + }; + const info = { + coreVersion: version$1, + version: internalConfig.version + }; + glueInitTimer.stop(); + const glue = { + feedback: feedbackFunc, + info, + logger: _logger, + interop: _interop, + agm: _interop, + connection: _connection, + metrics: _metrics, + contexts: _contexts, + bus: _bus, + version: internalConfig.version, + userConfig, + done: () => { + _logger?.info("done called by user..."); + return _connection.logout(); + } + }; + glue.performance = { + get glueVer() { + return internalConfig.version; + }, + get glueConfig() { + return JSON.stringify(userConfig); + }, + get browser() { + return window.performance.timing.toJSON(); + }, + get memory() { + return window.performance.memory; + }, + get initTimes() { + const all = getAllTimers(); + return Object.keys(all).map((key) => { + const t = all[key]; + return { + name: key, + duration: t.endTime - t.startTime, + marks: t.marks, + startTime: t.startTime, + endTime: t.endTime + }; + }); + } + }; + Object.keys(libs).forEach((key) => { + const lib = libs[key]; + glue[key] = lib; + }); + glue.config = {}; + Object.keys(internalConfig).forEach((k) => { + glue.config[k] = internalConfig[k]; + }); + if (ext && ext.extOptions) { + Object.keys(ext.extOptions).forEach((k) => { + glue.config[k] = ext?.extOptions[k]; + }); + } + if (ext?.enrichGlue) { + ext.enrichGlue(glue); + } + if (iodesktop && iodesktop.updatePerfData) { + iodesktop.updatePerfData(glue.performance); + } + if (glue.agm) { + const deprecatedDecorator = (fn, wrong, proper) => { + return function () { + glue.logger.warn(`glue.js - 'glue.agm.${wrong}' method is deprecated, use 'glue.interop.${proper}' instead.`); + return fn.apply(glue.agm, arguments); + }; + }; + const agmAny = glue.agm; + agmAny.method_added = deprecatedDecorator(glue.agm.methodAdded, "method_added", "methodAdded"); + agmAny.method_removed = deprecatedDecorator(glue.agm.methodRemoved, "method_removed", "methodRemoved"); + agmAny.server_added = deprecatedDecorator(glue.agm.serverAdded, "server_added", "serverAdded"); + agmAny.server_method_aded = deprecatedDecorator(glue.agm.serverMethodAdded, "server_method_aded", "serverMethodAdded"); + agmAny.server_method_removed = deprecatedDecorator(glue.agm.serverMethodRemoved, "server_method_removed", "serverMethodRemoved"); + } + return glue; + } + async function registerInstanceIfNeeded() { + const RegisterInstanceMethodName = "T42.ACS.RegisterInstance"; + if (Utils$1.isNode() && typeof process.env._GD_STARTING_CONTEXT_ === "undefined" && typeof userConfig?.application !== "undefined") { + const isMethodAvailable = _interop.methods({ name: RegisterInstanceMethodName }).length > 0; + if (isMethodAvailable) { + try { + await _interop.invoke(RegisterInstanceMethodName, { appName: userConfig?.application, pid: process.pid }); + } + catch (error) { + const typedError = error; + _logger.error(`Cannot register as an instance: ${JSON.stringify(typedError.message)}`); + } + } + } + } + return preloadPromise + .then(setupLogger) + .then(setupConnection) + .then(() => Promise.all([setupMetrics(), setupInterop(), setupContexts(), setupBus()])) + .then(() => _interop.readyPromise) + .then(() => registerInstanceIfNeeded()) + .then(() => { + return setupExternalLibs(internalConfig.libs || []); + }) + .then(waitForLibs) + .then(constructGlueObject) + .catch((err) => { + return Promise.reject({ + err, + libs + }); + }); + }; + if (typeof window !== "undefined") { + window.IOConnectCore = IOConnectCoreFactory; + } + IOConnectCoreFactory.version = version$1; + IOConnectCoreFactory.default = IOConnectCoreFactory; + + class ActivityEntity { + constructor(id) { + this._id = id; + } + get id() { + return this._id; + } + _update(other) { + if (other._id !== this._id) { + throw Error("Can not update from entity with different id."); + } + this._updateCore(other); + } + _updateCore(other) { + return; + } + _beforeDelete(other) { + return; + } + } + + function isNumber(arg) { + return typeof arg === "number"; + } + function isString(arg) { + return typeof arg === "string"; + } + function isObject(arg) { + return typeof arg === "object" && !Array.isArray(arg) && arg !== null; + } + function isArray(arg) { + if (Array.isArray) { + return Array.isArray(arg); + } + return toString.call(arg) === "[object Array]"; + } + function isUndefined(arg) { + return typeof arg === "undefined"; + } + function isUndefinedOrNull(arg) { + return arg === null || typeof arg === "undefined"; + } + function isNullOrWhiteSpace(str) { + return (typeof str !== "string" || !str || str.length === 0 || /^\s*$/.test(str)); + } + function isBoolean(obj) { + return obj === true || obj === false || toString.call(obj) === "[object Boolean]"; + } + function isFunction(arg) { + return !!(arg && arg.constructor && arg.call && arg.apply); + } + function some(array, predicate) { + for (let index = 0; index < array.length; index++) { + if (predicate(array[index], index)) { + return true; + } + } + return false; + } + function ifNotUndefined(what, doWithIt) { + if (typeof what !== "undefined") { + doWithIt(what); + } + } + function promisify$1(promise, successCallback, errorCallback) { + if (typeof successCallback !== "function" && typeof errorCallback !== "function") { + return promise; + } + if (typeof successCallback !== "function") { + successCallback = () => { return; }; + } + else if (typeof errorCallback !== "function") { + errorCallback = () => { return; }; + } + promise.then(successCallback, errorCallback); + } + + class ActivityType extends ActivityEntity { + constructor(name, ownerWindow, helperWindows, description) { + super(name); + this._name = name; + this._description = description; + this._ownerWindow = ownerWindow; + this._helperWindows = helperWindows || []; + } + get name() { + return this._name; + } + get description() { + return this._description; + } + get helperWindows() { + return this._helperWindows.map((hw) => this.covertToWindowDef(hw)); + } + get ownerWindow() { + return this.covertToWindowDef(this._ownerWindow); + } + initiate(context, callback, configuration) { + return this._manager.initiate(this._name, context, callback, configuration); + } + _updateCore(other) { + super._updateCore(other); + ifNotUndefined(other._description, (x) => this._description = x); + ifNotUndefined(other._ownerWindow, (x) => this._ownerWindow = x); + ifNotUndefined(other._helperWindows, (x) => this._helperWindows = x); + } + covertToWindowDef(windowType) { + var _a, _b; + return { + type: (_a = windowType === null || windowType === void 0 ? void 0 : windowType.id) === null || _a === void 0 ? void 0 : _a.type, + name: (_b = windowType === null || windowType === void 0 ? void 0 : windowType.id) === null || _b === void 0 ? void 0 : _b.name + }; + } + } + + class WindowType extends ActivityEntity { + constructor(name, appByWindowTypeGetter) { + super(name); + this._name = name; + this._appByWindowTypeGetter = appByWindowTypeGetter; + } + get name() { + return this._name; + } + get config() { + return this._appByWindowTypeGetter(this._name); + } + get windows() { + return this._manager.getWindows({ type: this._name }); + } + create(activity, configuration) { + const definition = Object.assign({ type: this.name, name: this.name, isIndependent: false }, configuration); + return this._manager.createWindow(activity, definition); + } + } + + class EntityEvent { + constructor(entitiy, context) { + this.entity = entitiy; + this.context = context; + } + } + class EntityEventContext { + constructor(eventType) { + this.type = eventType; + } + } + class ActivityStatusChangeEventContext extends EntityEventContext { + constructor(newStatus, oldStatus) { + super(EntityEventType.StatusChange); + this.newStatus = newStatus; + this.oldStatus = oldStatus; + } + } + class ActivityContextChangedEventContext extends EntityEventContext { + constructor(context, updated, removed) { + super(EntityEventType.ActivityContextChange); + this.context = typeof context === "string" ? JSON.parse(context) : context; + this.updated = updated; + this.removed = removed; + } + } + class EntityEventType { + } + EntityEventType.Added = "added"; + EntityEventType.Removed = "removed"; + EntityEventType.Updated = "updated"; + EntityEventType.Closed = "closed"; + EntityEventType.StatusChange = "statusChange"; + EntityEventType.ActivityContextChange = "activityContextUpdate"; + EntityEventType.ActivityWindowEvent = "activityWindowEvent"; + EntityEventType.ActivityWindowJoinedActivity = "joined"; + EntityEventType.ActivityWindowLeftActivity = "left"; + class ActivityState { + } + ActivityState.Created = "created"; + ActivityState.Started = "started"; + ActivityState.Destroyed = "destroyed"; + + class ActivityAGM { + constructor(activity) { + this._activity = activity; + } + register(definition, handler) { + this._ensureHasAgm(); + ActivityAGM.AGM.register(definition, handler); + } + servers() { + this._ensureHasAgm(); + if (isUndefinedOrNull(this._activity)) { + return []; + } + return this._activity.windows.map((w) => { + return w.instance; + }); + } + methods() { + this._ensureHasAgm(); + if (isUndefinedOrNull(this._activity)) { + return []; + } + const windows = this._activity.windows; + const methodNames = []; + const methods = []; + windows.forEach((window) => { + const windowMethods = this.methodsForWindow(window); + windowMethods.forEach((currentWindowMethod) => { + if (methodNames.indexOf(currentWindowMethod.name) === -1) { + methodNames.push(currentWindowMethod.name); + methods.push(currentWindowMethod); + } + }); + }); + return methods; + } + methodsForWindow(window) { + this._ensureHasAgm(); + if (!window.instance) { + return []; + } + return ActivityAGM.AGM.methodsForInstance(window.instance); + } + invoke(methodName, arg, target, options, success, error) { + this._ensureHasAgm(); + const activityServers = this.servers(); + if (isUndefinedOrNull(target)) { + target = "activity.all"; + } + if (isString(target)) { + if (target === "activity.all") ; + else if (target === "activity.best") { + const potentialTargets = activityServers.filter((server) => { + const methods = ActivityAGM.AGM.methodsForInstance(server); + return methods.filter((m) => { + return m.name === methodName; + }).length > 0; + }); + if (potentialTargets.length > 0) { + [potentialTargets[0]]; + } + } + else if (target === "all" || target === "best") { + return promisify$1(ActivityAGM.AGM.invoke(methodName, arg, target, options), success, error); + } + else { + throw new Error("Invalid invoke target " + target); + } + } + else if (isArray(target)) { + if (target.length >= 0) { + const firstElem = target[0]; + if (this._isInstance(firstElem)) { + target.map((instance) => instance); + } + else if (this._isActivityWindow(firstElem)) { + target.map((win) => win.instance); + } + else { + throw new Error("Unknown target object"); + } + } + } + else { + if (this._isInstance(target)) ; + else if (this._isActivityWindow(target)) { + [target.instance]; + } + else { + throw new Error("Unknown target object"); + } + } + throw new Error("Not implemented"); + } + unregister(definition) { + this._ensureHasAgm(); + return ActivityAGM.AGM.unregister(definition); + } + createStream(methodDefinition, subscriptionAddedHandler, subscriptionRemovedHandler) { + this._ensureHasAgm(); + ActivityAGM.AGM.createStream(methodDefinition, { + subscriptionAddedHandler, + subscriptionRemovedHandler, + subscriptionRequestHandler: undefined + }); + } + subscribe(methodDefinition, parameters, target) { + this._ensureHasAgm(); + return ActivityAGM.AGM.subscribe(methodDefinition, parameters); + } + _ensureHasAgm() { + if (isUndefinedOrNull(ActivityAGM.AGM)) { + throw new Error("Agm should be configured to be used in activity"); + } + } + _isInstance(obj) { + return obj.application !== undefined; + } + _isActivityWindow(obj) { + return obj.instance !== undefined; + } + } + + class AttachedActivityDescriptor { + constructor(manager, ownerActivityId, state) { + this._manager = manager; + this._ownerActivityId = ownerActivityId; + this._state = state; + } + get ownerId() { + return this._state.ownerId; + } + get windowIds() { + return this._state.windowIds; + } + get frameColor() { + return this._state.frameColor; + } + get context() { + return this._state.context; + } + get tag() { + return this._state.tag; + } + detach(descriptor) { + descriptor = descriptor || {}; + const merged = {}; + Object.keys(this._state).forEach((prop) => { + merged[prop] = this._state[prop]; + }); + merged.context = descriptor.context || merged.context; + merged.frameColor = descriptor.frameColor || merged.frameColor; + return this._manager.detachActivities(this._ownerActivityId, merged); + } + } + + const nextTick = (cb) => { + setTimeout(cb, 0); + }; + function nodeify(promise, callback) { + if (!isFunction(callback)) { + return promise; + } + promise.then((resp) => { + nextTick(() => { + callback(null, resp); + }); + }, (err) => { + nextTick(() => { + callback(err, null); + }); + }); + } + + class Activity extends ActivityEntity { + constructor(id, actType, status, context, ownerId) { + super(id); + this._id = id; + this._actType = actType; + this._status = status; + this._context = context; + this._ownerId = ownerId; + this._agm = new ActivityAGM(this); + } + get type() { + if (this._manager) { + return this._manager.getActivityType(this._actType); + } + return undefined; + } + get context() { + return this._context; + } + get status() { + return this._status; + } + get owner() { + if (!this._ownerId) { + return null; + } + return this._manager.getWindows({ id: this._ownerId })[0]; + } + get windows() { + return this._manager.getWindows({ activityId: this._id }); + } + get agm() { + return this._agm; + } + addWindow(window, callback) { + return this._manager.addWindowToActivity(this, window, callback); + } + createWindow(windowType, callback) { + return this._manager.createWindow(this, windowType, callback); + } + createStackedWindows(windowTypes, timeout, callback) { + return this._manager.createStackedWindows(this, windowTypes, timeout, callback); + } + leave(window, callback) { + return this._manager.leaveWindowFromActivity(this, window, callback); + } + getWindowsByType(windowType) { + const filter = { activityId: this._id, type: windowType }; + return this._manager.getWindows(filter); + } + setContext(context, callback) { + return this._manager.setActivityContext(this, context, callback); + } + updateContext(context, callback) { + return this._manager.updateActivityContext(this, context, callback); + } + onStatusChange(handler) { + return this._manager.subscribeActivityEvents((a, ns, os) => { + if (a.id === this.id) { + handler(a, ns, os); + } + }); + } + onWindowEvent(handler) { + return this._manager.subscribeWindowEvents((a, w, e) => { + if (a.id === this.id) { + handler(a, w, e); + } + }); + } + onContextChanged(handler) { + this._manager.subscribeActivityContextChanged((act, context, updated, removed) => { + if (act.id === this.id) { + handler(context, updated, removed, act); + } + }); + try { + handler(this.context, this.context, [], this); + } + catch (e) { + return; + } + } + stop() { + this._manager.stopActivity(this); + } + clone(options) { + return this._manager.clone(this, options); + } + attach(activity, tag) { + let activityId; + if (typeof activity === "string") { + activityId = activity; + } + else { + activityId = activity.id; + } + return this._manager.attachActivities(activityId, this.id, tag); + } + onActivityAttached(callback) { + this._manager.subscribeActivitiesAttached((newActId, oldActId, descriptor) => { + if (newActId !== this._id) { + return; + } + callback(descriptor); + }); + } + onDetached(callback) { + this._manager.subscribeActivitiesDetached((newAct, originalActivity, state) => { + if (originalActivity.id !== this._id) { + return; + } + callback(newAct, state); + }); + } + _updateCore(other) { + super._updateCore(other); + ifNotUndefined(other._actType, (x) => this._actType = x); + ifNotUndefined(other._context, (x) => this._context = x); + ifNotUndefined(other._ownerId, (x) => this._ownerId = x); + if (other._status && (!this._status || (this._status.state !== other._status.state))) { + this._status = other._status; + } + } + _updateDescriptors(allStates) { + this._attached = allStates.map((s) => { + return new AttachedActivityDescriptor(this._manager, this._id, s); + }); + } + get attached() { + return this._attached; + } + setFrameColor(color, callback) { + const promise = new Promise((resolve, reject) => { + let callbacksToWait = this.windows.length; + if (callbacksToWait === 0) { + resolve(this); + } + this.windows.forEach((w) => { + w.underlyingWindow.setFrameColor(color, () => { + callbacksToWait--; + if (callbacksToWait <= 0) { + resolve(this); + } + }); + }); + setTimeout(() => { + if (callbacksToWait > 0) { + reject(this.id + " - timed out waiting for setFrameColor with" + color); + } + }, 5000); + }); + return nodeify(promise, callback); + } + getFrameColor() { + if (!this.windows || this.windows.length === 0) { + return ""; + } + return this.windows[0].underlyingWindow.frameColor; + } + } + + class LogLevel { + } + LogLevel.Trace = "trace"; + LogLevel.Debug = "debug"; + LogLevel.Info = "info"; + LogLevel.Warn = "warn"; + LogLevel.Error = "error"; + class Logger { + static GetNamed(name) { + return new Logger(name); + } + static Get(owner) { + return new Logger(Logger.GetTypeName(owner)); + } + constructor(name) { + this._name = name; + if (!isUndefinedOrNull(Logger.GlueLogger)) { + this._glueLogger = Logger.GlueLogger.subLogger(name); + } + } + trace(message) { + if (!isUndefinedOrNull(this._glueLogger)) { + this._glueLogger.trace(message); + } + else { + if (Logger.Level === LogLevel.Trace) { + console.info(this._getMessage(message, LogLevel.Trace)); + } + } + } + debug(message) { + if (!isUndefinedOrNull(this._glueLogger)) { + this._glueLogger.debug(message); + } + else { + if (Logger.Level === LogLevel.Debug || + Logger.Level === LogLevel.Trace) { + console.info(this._getMessage(message, LogLevel.Debug)); + } + } + } + info(message) { + if (!isUndefinedOrNull(this._glueLogger)) { + this._glueLogger.info(message); + } + else { + if (Logger.Level === LogLevel.Debug || + Logger.Level === LogLevel.Trace || + Logger.Level === LogLevel.Info) { + console.info(this._getMessage(message, LogLevel.Info)); + } + } + } + warn(message) { + if (!isUndefinedOrNull(this._glueLogger)) { + this._glueLogger.warn(message); + } + else { + if (Logger.Level === LogLevel.Debug || + Logger.Level === LogLevel.Trace || + Logger.Level === LogLevel.Info || + Logger.Level === LogLevel.Warn) { + console.info(this._getMessage(message, LogLevel.Info)); + } + } + } + error(message) { + if (!isUndefinedOrNull(this._glueLogger)) { + this._glueLogger.error(message); + } + else { + console.error(this._getMessage(message, LogLevel.Error)); + console.trace(); + } + } + _getMessage(message, level) { + return "[" + level + "] " + this._name + " - " + message; + } + static GetTypeName(object) { + const funcNameRegex = /function (.{1,})\(/; + const results = (funcNameRegex).exec(object.constructor.toString()); + return (results && results.length > 1) ? results[1] : ""; + } + } + Logger.Level = LogLevel.Info; + + class ActivityWindow extends ActivityEntity { + constructor(id, name, type, activityId, instance, isIndependent, windowGetter, hcWindowId) { + super(id); + this._logger = Logger.Get("window"); + this._type = type; + this._activityId = activityId; + this._name = name; + this._instance = instance; + this._isIndependent = isIndependent; + this._windowGetter = windowGetter; + this._hcWindowId = hcWindowId; + } + getBounds() { + return this._manager.getWindowBounds(this.id); + } + get name() { + return this._name; + } + get isIndependent() { + return this._isIndependent; + } + get type() { + if (this._manager) { + return this._manager.getWindowType(this._type); + } + return undefined; + } + get activity() { + if (isUndefined(this._activityId)) { + return undefined; + } + return this._manager.getActivityById(this._activityId); + } + get isOwner() { + const act = this.activity; + if (isUndefined(act)) { + return false; + } + return act.owner.id === this.id; + } + setVisible(isVisible, callback) { + return this._manager.setWindowVisibility(this.id, isVisible); + } + activate(focus) { + return this._manager.activateWindow(this.id, focus); + } + setBounds(bounds, callback) { + return this._manager.setWindowBounds(this.id, bounds, callback); + } + close() { + return this._manager.closeWindow(this.id); + } + get instance() { + return this._instance; + } + get underlyingWindow() { + const window = this._windowGetter(); + if (!window) { + return { + id: this._hcWindowId + }; + } + return window; + } + onActivityJoined(callback) { + this._subscribeForActivityWindowEvent(EntityEventType.ActivityWindowJoinedActivity, callback); + } + onActivityRemoved(callback) { + this._subscribeForActivityWindowEvent(EntityEventType.ActivityWindowLeftActivity, callback); + } + _updateCore(other) { + ifNotUndefined(other._activityId, (x) => this._activityId = x); + ifNotUndefined(other._isIndependent, (x) => this._isIndependent = x); + ifNotUndefined(other._hcWindowId, (x) => this._hcWindowId = x); + ifNotUndefined(other._type, (x) => this._type = x); + ifNotUndefined(other._name, (x) => this._name = x); + if (!isUndefinedOrNull(other._instance)) { + this._instance = other._instance; + } + } + _subscribeForActivityWindowEvent(eventName, callback) { + this._manager.subscribeWindowEvents((activity, window, event) => { + if (window.id !== this.id) { + return; + } + if (event === eventName) { + callback(activity); + } + }); + } + _beforeDelete(other) { + this._hcWindowId = other._hcWindowId; + } + } + + class ActivityStatus { + constructor(state, message, time) { + this.state = state; + this.message = message; + this.time = time; + } + getState() { + return this.state; + } + getMessage() { + return this.message; + } + getTime() { + return this.time; + } + } + + const gwMmessageError = "error"; + const gwMessageAddActivityTypes = "add-types"; + const gwMmessageActivityTypesAdded = "types-added"; + const gwMessageRemoveActivityTypes = "remove-types"; + const gwMessageActivityTypesRemoved = "types-removed"; + const gwMessageActivityCreated = "created"; + const gwMessageActivityDestroyed = "destroyed"; + const gwMessageActivityInitiated = "initiated"; + const gwMmessageJoinActivity = "join-activity"; + const gwMessageJoinedActivity = "joined"; + const gwMessageActivityJoined = "activity-joined"; + const gwMessageLeaveActivity = "leave-activity"; + const gwMessageActivityLeft = "left"; + const gwNmessageMergeActivities = "merge"; + const gwMessageSplitActivities = "split"; + const gwMessageOwnerChanged = "owner-changed"; + const gwMessageAddPeerFactories = "add-peer-factories"; + const gwMessagePeerFactoriesAdded = "peer-factories-added"; + const gwMessageRemovePeerFactories = "remove-peer-factories"; + const gwMessagePeerFactoriesRemoved = "peer-factories-removed"; + const gwMessageCreateActivity = "create"; + const gwMessageCreatePeer = "create-peer"; + const gwMessagePeerRequested = "peer-requested"; + const gwMessageReady = "ready"; + const gwMessagePeerCreated = "peer-created"; + const gwMessageDestroyActivity = "destroy"; + const gwMessageDisposePeer = "dispose-peer"; + const gwMessageDestroyPeer = "destroy-peer"; + class GW3Bridge { + static activityTypeGwMessageEntityToActivityType(entity, description) { + const nameToWindowType = (windowName) => new WindowType(windowName, undefined); + return new ActivityType(entity.name, entity.owner_type && nameToWindowType(entity.owner_type), entity.helper_types && entity.helper_types.map(nameToWindowType), description); + } + static peerFactoryGwMessageEntityToWindowType(entity) { + return new WindowType(entity.peer_type, (_) => undefined); + } + static activityGwMessageToActivity(msg, status) { + const ownerId = msg.owner !== undefined ? msg.owner.peer_id : msg.owner_id; + return new Activity(msg.activity_id, msg.activity_type, status, msg.context_snapshot, ownerId); + } + static activityToActivityStatusChangeEvent(act) { + return new EntityEvent(act, new ActivityStatusChangeEventContext(act.status, undefined)); + } + constructor(config) { + this._activityChangeCallbacks = []; + this._activityTypeStatusChangeCallbacks = []; + this._activityWindowChangeCallbacks = []; + this._windowTypeStatusChangeCallbacks = []; + this._peerIdAndFactoryIdToPeerType = {}; + this._peerFactoriesRegisteredByUs = {}; + this._gw3Subscriptions = []; + this._contextSubscriptions = {}; + this._activityTypesInitiatedFromMe = {}; + this._config = config; + this._connection = config.connection; + this._logger = config.logger; + this._contexts = config.contexts; + this._windows = config.windows; + this._sessionJoinedPromise = new Promise((resolve) => { + this._sessionJoinedPromiseResolve = resolve; + }); + this._activityJoinedPromise = new Promise((resolve) => { + this._activityJoinedPromiseResolve = resolve; + }); + if (!this._config.activityId) { + this._activityJoinedPromiseResolve({}); + } + this._gw3Session = this._connection.domain("activity", ["joined", "initiated", "peer-created", "token"]); + if (typeof window !== "undefined") { + const glue42gd = (window).glue42gd; + if (glue42gd && glue42gd.activityInfo) { + if (typeof glue42gd.addRefreshHandler === "function") { + glue42gd.addRefreshHandler((success, error) => { + this._gw3Session + .send({ + type: "reload" + }) + .then((msg) => { + if (!msg.token) { + error("Expected gateway token for refreshing."); + return; + } + try { + glue42gd.setGWToken(msg.token); + } + catch (e) { + error(e.message || e); + return; + } + success(); + }, error); + }); + } + if (glue42gd && typeof glue42gd.addWillNavigateHandler === "function") { + glue42gd.addWillNavigateHandler((success, error) => { + this._gw3Session + .send({ + type: "reload" + }) + .then((msg) => { + if (!msg.token) { + error("Expected gateway token for refreshing."); + return; + } + try { + glue42gd.setGWToken(msg.token); + } + catch (e) { + error(e.message || e); + return; + } + success(); + }, error); + }); + } + } + } + } + get bridgeType() { + return "GW3"; + } + init() { + this.forwardActivityTypeMessagesToStatusEventHandlers(); + this.subscribe(gwMessageActivityCreated, this.handleActivityCreatedMessage); + this.subscribe(gwMessageActivityDestroyed, this.handleActivityDestroyedMessage); + this.forwardActivityMessagesToStatusEventHandlers(); + this.forwardActivityCreatedAndJoinedActivityToActivityWindowEventHandlers(); + this.forwardPeerFactoryMessagesToStatusEventHandlers(); + this.forwardPeerFactoryMessagesToPeerFactoryRequests(); + this.subscribe(gwMessagePeerFactoriesAdded, this.handlePeerFactoriesAdded); + this.subscribe(gwMessagePeerFactoriesRemoved, this.handlePeerFactoriesRemoved); + this.forwardActivityWindowMessagesToEventHandlers(); + this.subscribe(gwMessageDisposePeer, () => { + if (this._config.disposeRequestHandling === "dispose") { + this.dispose(); + return; + } + if (this._config.disposeRequestHandling === "exit") { + if (this._windows && typeof this._windows.my() !== "undefined") { + this._windows.my().close(); + return; + } + if (typeof window !== "undefined" && typeof (window).close === "function") { + window.close(); + return; + } + if (typeof process !== "undefined" && typeof (process).exit === "function") { + process.exit(); + return; + } + } + }); + this._gw3Session.onJoined(() => { + if (this._config.mode === "trackMyOnly" || + this._config.mode === "trackMyTypeAndInitiatedFromMe") { + this._sessionJoinedPromiseResolve(this); + } + else { + this._gw3Session + .send({ + type: "subscribe", + activity_types: (this._config.mode === "trackAll" ? [] : + this._config.mode === "trackTypes" ? this._config.typesToTrack : []) + }) + .then(() => { + this._sessionJoinedPromiseResolve(this); + }); + } + }); + this._gw3Session.join(); + } + dispose() { + this._gw3Subscriptions.forEach((sub) => sub && this._connection.off(sub)); + this._gw3Subscriptions.length = 0; + } + ready() { + return Promise.all([this._sessionJoinedPromise, this._activityJoinedPromise]); + } + initReady() { + return this._sessionJoinedPromise; + } + onActivityTypeStatusChange(callback) { + this._activityTypeStatusChangeCallbacks.push(callback); + } + registerActivityType(activityTypeName, ownerWindow, helperWindows, config, description) { + const entity = {}; + entity.name = activityTypeName; + const toActivityPeerConfig = (windowDefinition) => ({ type: windowDefinition.type, name: windowDefinition.name, configuration: windowDefinition }); + entity.owner_type = toActivityPeerConfig(ownerWindow); + entity.helper_types = helperWindows.map(toActivityPeerConfig); + return this._gw3Session + .send({ + type: gwMessageAddActivityTypes, + types: [entity] + }) + .then(() => { + const activityType = GW3Bridge.activityTypeGwMessageEntityToActivityType(entity, description); + this.invokeCallbacks(this._activityTypeStatusChangeCallbacks, new EntityEvent(activityType, new EntityEventContext(EntityEventType.Added)), gwMessageAddActivityTypes); + return activityType; + }); + } + unregisterActivityType(activityTypeName) { + return this._gw3Session + .send({ + type: gwMessageRemoveActivityTypes, + types: [activityTypeName] + }) + .then(() => { + const activityType = new ActivityType(activityTypeName, undefined, undefined, undefined); + this.invokeCallbacks(this._activityTypeStatusChangeCallbacks, new EntityEvent(activityType, new EntityEventContext(EntityEventType.Removed)), gwMessageAddActivityTypes); + }); + } + onWindowTypeStatusChange(callback) { + this._windowTypeStatusChangeCallbacks.push(callback); + } + registerWindowFactory(windowType, factory, parameters) { + if (this._peerFactoriesRegisteredByUs[windowType]) { + return Promise.reject(new Error(`Factory for windowType ${windowType} already registered.`)); + } + this._peerFactoriesRegisteredByUs[windowType] = factory; + const entity = { + id: windowType, + peer_type: windowType, + configuration: parameters + }; + return this._gw3Session.send({ + type: gwMessageAddPeerFactories, + factories: [entity] + }) + .then(() => { + this.invokeCallbacks(this._windowTypeStatusChangeCallbacks, new EntityEvent(GW3Bridge.peerFactoryGwMessageEntityToWindowType(entity), new EntityEventContext(EntityEventType.Added)), gwMessageAddPeerFactories); + }) + .catch(() => { + delete this._peerFactoriesRegisteredByUs[windowType]; + }); + } + unregisterWindowFactory(windowType) { + const factory = this._peerFactoriesRegisteredByUs[windowType]; + if (!factory) { + return Promise.reject(new Error(`Factory for windowType ${windowType} not registered.`)); + } + delete this._peerFactoriesRegisteredByUs[windowType]; + return this._gw3Session.send({ + type: gwMessageRemovePeerFactories, + factory_ids: [windowType] + }).then(() => { + this.invokeCallbacks(this._windowTypeStatusChangeCallbacks, new EntityEvent(new WindowType(windowType, undefined), new EntityEventContext(EntityEventType.Removed)), gwMessageAddPeerFactories); + }); + } + onActivityStatusChange(callback) { + this._activityChangeCallbacks.push(callback); + } + initiateActivity(activityType, context, configuration) { + const initiateMsg = { + type: gwMessageCreateActivity, + activity_type: activityType, + initial_context: context, + }; + if (this.isOverrideTypeDefinition(configuration)) { + initiateMsg.types_override = { + owner_type: { type: configuration.owner.type, name: configuration.owner.name, configuration: configuration.owner }, + helper_types: configuration.helpers && configuration.helpers.map((wd) => ({ type: wd.type, name: wd.name, configuration: wd })) + }; + } + else { + initiateMsg.configuration = configuration && configuration.map((wd) => ({ type: wd.type, name: wd.name, configuration: wd })); + } + return this.sendCreateAndMapResultingMessagesToPromise(initiateMsg, gwMessageActivityInitiated, (msg, requestId) => msg.request_id === requestId, gwMessageActivityCreated, (msg, requestId, initMsg) => msg.activity_id === initMsg.activity_id, gwMessageActivityDestroyed, (msg, requestId, initMsg) => msg.activity_id === initMsg.activity_id, (msg) => msg.activity_id, null).then((id) => { + if (this._config.mode === "trackMyTypeAndInitiatedFromMe") { + if (!this._activityTypesInitiatedFromMe[activityType]) { + this._activityTypesInitiatedFromMe[activityType] = true; + return this._gw3Session + .send({ + type: "subscribe", + activity_types: [activityType] + }) + .then(() => { + return id; + }); + } + } + return id; + }); + } + stopActivity(activity) { + return this._gw3Session.send({ + type: gwMessageDestroyActivity, + activity_id: activity.id, + reason_uri: "com.tick42.glue.activity.constants.destroyReason.general", + reason: "Destroying activity" + }).then((_) => true); + } + updateActivityContext(activity, context, fullReplace, removedKeys) { + if (fullReplace) { + return this._contexts.set(activity.id, context); + } + else { + removedKeys = removedKeys || []; + for (const x of removedKeys) { + context[x] = null; + } + return this._contexts.update(activity.id, context); + } + } + announceWindow(windowType, activityWindowId) { + throw new Error("Invalid operation 'announceWindow' for GW3 protocol"); + } + registerWindow(type, name, independent) { + let shouldSendReady = typeof this._connection.gatewayToken !== "undefined"; + const peerId = this._connection.peerId; + if (typeof window !== "undefined") { + const glue42gd = window.glue42gd; + if (glue42gd) { + shouldSendReady = typeof glue42gd.activityInfo !== "undefined"; + } + } + if (shouldSendReady) { + this._gw3Session.send({ + type: gwMessageReady, + }); + } + this.invokeCallbacks(this._activityWindowChangeCallbacks, new EntityEvent(new ActivityWindow(peerId, name, type, undefined, this.getAgmInstance(peerId), independent, this.generateWindowGetter(peerId), undefined), new EntityEventContext(EntityEventType.Added)), "register window"); + return Promise.resolve(peerId); + } + onActivityWindowChange(callback) { + this._activityWindowChangeCallbacks.push(callback); + } + createWindow(activityId, windowDefinition) { + if (!windowDefinition.layout) { + if (windowDefinition.left || windowDefinition.width || windowDefinition.height || windowDefinition.top) { + windowDefinition.layout = { + mode: "pixels", + cellSize: 1, + }; + } + } + const joinPeer = (id) => { + if (!activityId) { + return; + } + return this.joinActivity(activityId, id, windowDefinition.name) + .then(() => { + return id; + }); + }; + return this.sendCreateAndMapResultingMessagesToPromise({ + type: gwMessageCreatePeer, + peer_type: windowDefinition.type, + peer_name: windowDefinition.name || windowDefinition.type, + configuration: windowDefinition, + activity_id: activityId, + }, undefined, undefined, gwMessagePeerCreated, (msg, requestId) => msg.request_id === requestId, undefined, undefined, (msg) => msg.created_id, joinPeer) + .then(joinPeer); + } + async closeWindow(id) { + await this._gw3Session.send({ + type: gwMessageDestroyPeer, + destroy_peer_id: id + }); + } + getAnnouncementInfo() { + let activityId = this._config.activityId || (this._config.announcementInfo && this._config.announcementInfo.activityId); + let activityWindowType = (this._config.announcementInfo && this._config.announcementInfo.activityWindowType); + let activityWindowIndependent = (this._config.announcementInfo && this._config.announcementInfo.activityWindowIndependent); + let activityWindowName = (this._config.announcementInfo && this._config.announcementInfo.activityWindowName); + if (typeof window !== "undefined" && + typeof window.location !== "undefined" && + window.location.search && + typeof URLSearchParams === "function") { + const searchParams = new URLSearchParams(location.search.slice(1)); + activityWindowType = activityWindowType || searchParams.get("t42PeerType"); + activityWindowType = activityWindowType || searchParams.get("t42ActivityWindowType"); + if (typeof activityWindowIndependent === "undefined") { + activityWindowIndependent = searchParams.get("t42ActivityWindowIndependent"); + } + activityWindowName = activityWindowName || searchParams.get("t42ActivityWindowName"); + activityId = activityId || searchParams.get("t42ActivityId"); + } + activityWindowType = activityWindowType || "unknown"; + activityWindowIndependent = activityWindowIndependent || false; + activityWindowName = activityWindowName || this._connection.peerId; + return { + activityWindowId: undefined, + activityId, + activityWindowType, + activityWindowIndependent, + activityWindowName, + }; + } + joinActivity(activityId, windowId, name) { + const maybeName = (name && { name }) || {}; + return this._gw3Session.send({ + type: gwMmessageJoinActivity, + target_id: windowId, + activity_id: activityId, + ...maybeName + }).then(() => { + this.invokeCallbacks(this._activityWindowChangeCallbacks, new EntityEvent(new ActivityWindow(windowId, undefined, undefined, activityId, this.getAgmInstance(windowId), undefined, this.generateWindowGetter(windowId), undefined), new EntityEventContext(EntityEventType.ActivityWindowJoinedActivity)), "activity joined - ActivityWindow"); + this.invokeCallbacks(this._activityChangeCallbacks, new EntityEvent(new Activity(activityId, undefined, new ActivityStatus("created", undefined, undefined), undefined, undefined), new EntityEventContext(EntityEventType.Updated)), "activity joined - Activity"); + }); + } + leaveActivity(activityId, windowId) { + return this._gw3Session.send({ + type: gwMessageLeaveActivity, + target_id: windowId, + activity_id: activityId + }).then(() => { + this.invokeCallbacks(this._activityWindowChangeCallbacks, new EntityEvent(new ActivityWindow(windowId, undefined, undefined, null, this.getAgmInstance(windowId), undefined, this.generateWindowGetter(windowId), undefined), new EntityEventContext(EntityEventType.ActivityWindowLeftActivity)), "activity left - ActivityWindow"); + this.invokeCallbacks(this._activityChangeCallbacks, new EntityEvent(new Activity(activityId, undefined, new ActivityStatus("created", undefined, undefined), undefined, undefined), new EntityEventContext(EntityEventType.Updated)), "activity left - Activity"); + }); + } + getActivityTypes() { + return Promise.resolve([]); + } + getWindowTypes() { + return Promise.resolve([]); + } + getActivities() { + return Promise.resolve([]); + } + getActivityWindows() { + return Promise.resolve([]); + } + createStackedWindows(id, windowDefinitions, timeout) { + return undefined; + } + getWindowBounds(id) { + return undefined; + } + setWindowBounds(id, bounds) { + return undefined; + } + activateWindow(id, focus) { + return undefined; + } + setWindowVisibility(id, visible) { + return undefined; + } + cloneActivity(id, cloneOptions) { + return undefined; + } + attachActivities(from, to, tag) { + return this._gw3Session.send({ + type: gwNmessageMergeActivities, + into: to, + merge: from + }); + } + detachActivities(activityId, newActivityInfo) { + return this._gw3Session.send({ + type: gwMessageSplitActivities, + from: activityId, + }).then(() => ""); + } + onActivitiesAttached(callback) { + } + onActivitiesDetached(callback) { + } + onActivityAttachedDescriptorsRefreshed(callback) { + } + getAttachedDescriptors() { + return Promise.resolve([]); + } + getRandomRequestId() { + return this._connection.peerId + ":" + Math.floor(Math.random() * 1e9) + ""; + } + forwardAddedAndRemovedMessagesToEventHandler(addedMessageType, removedMessageType, mapper, handlers) { + const getGetEntityEvent = (isAdded) => (entity) => new EntityEvent(entity, new EntityEventContext(isAdded ? + EntityEventType.Added : + EntityEventType.Removed)); + const sub1 = addedMessageType && this.forwardMessageToEventHandler(addedMessageType, (msg) => mapper(msg, true), getGetEntityEvent(true), handlers); + const sub2 = removedMessageType && this.forwardMessageToEventHandler(removedMessageType, (msg) => mapper(msg, false), getGetEntityEvent(false), handlers); + return [sub1, sub2].filter((x) => x); + } + forwardMessageToEventHandler(messageType, mapper, getEntityEvent, handler) { + return this.subscribe(messageType, (msg) => { + mapper(msg) + .forEach((ent) => handler.forEach((h) => h(getEntityEvent(ent, msg)))); + }); + } + sendCreateAndMapResultingMessagesToPromise(msg, initiatedMessageType, initiatedMessageFilter, createdMessageType, createdMessageFilter, cancelledMessageType, cancelledMessageFilter, createdMessageToPromiseResolution, listenForRecreates) { + const reqId = this.getRandomRequestId(); + let resolveCreatedPromise; + let rejectCreatedPromise; + const createdPromise = new Promise((resolve, reject) => { + resolveCreatedPromise = resolve; + rejectCreatedPromise = reject; + }); + let initiatedMessageAck = null; + let initiatedSubscription; + let createdSubscription; + let cancelledSubscription; + let errorSubscription; + const dropSubscriptions = () => { + this.dropSubscription(initiatedSubscription); + if (!listenForRecreates) { + this.dropSubscription(createdSubscription); + } + this.dropSubscription(cancelledSubscription); + this.dropSubscription(errorSubscription); + }; + initiatedSubscription = initiatedMessageType && + this.subscribe(initiatedMessageType, (msg4) => { + if (!initiatedMessageFilter(msg4, reqId)) { + return; + } + initiatedMessageAck = msg4; + this.dropSubscription(initiatedSubscription); + }); + let recreated = false; + createdSubscription = + this.subscribe(createdMessageType, (msg1) => { + if (!createdMessageFilter(msg1, reqId, initiatedMessageAck)) { + return; + } + if (recreated) { + if (listenForRecreates) { + listenForRecreates(createdMessageToPromiseResolution(msg1)); + } + } + else { + recreated = true; + resolveCreatedPromise(createdMessageToPromiseResolution(msg1)); + } + }); + cancelledSubscription = cancelledMessageType && + this.subscribe(cancelledMessageType, (msg2) => { + if (!cancelledMessageFilter(msg2, reqId, initiatedMessageAck)) { + return; + } + rejectCreatedPromise(msg2); + }); + errorSubscription = cancelledMessageType && + this.subscribe(gwMmessageError, (msg3) => { + if (msg3.request_id !== reqId) { + return; + } + rejectCreatedPromise(msg3); + }); + msg.request_id = reqId; + const toReturn = this._gw3Session + .send(msg) + .then(() => { + return createdPromise; + }); + toReturn.then(dropSubscriptions, dropSubscriptions); + return toReturn; + } + peerFactoryIdAndOwnerIdToWindowType(factoryId, ownerId) { + const peerType = this._peerIdAndFactoryIdToPeerType[ownerId + ":" + factoryId]; + if (!peerType) { + return null; + } + else { + return new WindowType(peerType, undefined); + } + } + subscribe(messageType, handler) { + const sub = this._connection.on(messageType, (msg) => handler.bind(this)(msg)); + this._gw3Subscriptions.push(sub); + return sub; + } + dropSubscription(subscription) { + if (subscription) { + this._connection.off(subscription); + delete this._gw3Subscriptions[this._gw3Subscriptions.indexOf(subscription)]; + } + } + invokeCallbacks(callbacks, event, description) { + callbacks.forEach((cb) => { + try { + cb(event); + } + catch (err) { + this._logger.error(`Error in ${description || event.context.type} callback: ` + JSON.stringify(err)); + } + }); + } + handleActivityCreatedMessage(msg) { + if (!msg.context_id) { + this._logger.error("Activity created with unknown context_id: " + msg.activity_id); + } + else { + if (!this._contextSubscriptions[msg.activity_id]) { + this.subscribeToContext(msg); + } + } + } + async subscribeToContext(msg) { + const activityId = msg.activity_id; + this._contextSubscriptions[activityId] = + await this._contexts.subscribe(activityId, (data, updated, removed) => { + const event = new EntityEvent(new Activity(activityId, undefined, undefined, data, undefined), new ActivityContextChangedEventContext(data, updated, removed)); + this.invokeCallbacks(this._activityChangeCallbacks, event, "context updated"); + }); + } + handleActivityDestroyedMessage(msg) { + const unsubscribeContext = this._contextSubscriptions[msg.activity_id]; + if (typeof unsubscribeContext === "function") { + unsubscribeContext(); + } + delete this._contextSubscriptions[msg.activity_id]; + } + handlePeerFactoriesAdded(msg) { + msg.factories.forEach((entity) => { + this._peerIdAndFactoryIdToPeerType[msg.owner_id + ":" + entity.id] = entity.peer_type; + }); + } + handlePeerFactoriesRemoved(msg) { + msg.factory_ids.forEach((factoryId) => { + delete this._peerIdAndFactoryIdToPeerType[msg.owner_id + ":" + factoryId]; + }); + } + forwardActivityTypeMessagesToStatusEventHandlers() { + this.forwardAddedAndRemovedMessagesToEventHandler(gwMmessageActivityTypesAdded, gwMessageActivityTypesRemoved, (msg, isAdded) => isAdded + ? msg.types.map((t) => GW3Bridge.activityTypeGwMessageEntityToActivityType(t, undefined)) + : msg.types.map((t) => new ActivityType(t.name, undefined, undefined, undefined)), this._activityTypeStatusChangeCallbacks); + } + forwardActivityCreatedAndJoinedActivityToActivityWindowEventHandlers() { + for (const activityCreatedMessage of [gwMessageActivityCreated, gwMessageJoinedActivity, gwMessageOwnerChanged]) { + this.forwardMessageToEventHandler(activityCreatedMessage, (msg) => ([msg.owner || { ...msg, type: msg.peer_type, name: msg.peer_name, peer_id: msg.owner_id }]) + .concat(msg.participants || []) + .map((info) => new ActivityWindow(info.peer_id, info.name, info.type, msg.activity_id, this.getAgmInstance(info.peer_id), undefined, this.generateWindowGetter(info.peer_id), undefined)), (ent, msg) => new EntityEvent(ent, new EntityEventContext(EntityEventType.ActivityWindowJoinedActivity)), this._activityWindowChangeCallbacks); + } + } + forwardActivityMessagesToStatusEventHandlers() { + for (const createdMessage of [gwMessageActivityCreated, gwMessageJoinedActivity]) { + this.forwardMessageToEventHandler(createdMessage, (msg) => [GW3Bridge.activityGwMessageToActivity(msg, new ActivityStatus("started", "", new Date()))], (ent, msg) => GW3Bridge.activityToActivityStatusChangeEvent(ent), this._activityChangeCallbacks); + } + this.forwardMessageToEventHandler(gwMessageActivityDestroyed, (msg) => [GW3Bridge.activityGwMessageToActivity(msg, new ActivityStatus("destroyed", msg.reason, new Date()))], (ent, msg) => GW3Bridge.activityToActivityStatusChangeEvent(ent), this._activityChangeCallbacks); + this.forwardMessageToEventHandler(gwMessageActivityInitiated, (msg) => [GW3Bridge.activityGwMessageToActivity(msg, new ActivityStatus("created", "", new Date()))], (ent, msg) => GW3Bridge.activityToActivityStatusChangeEvent(ent), this._activityChangeCallbacks); + this.forwardMessageToEventHandler(gwMessageOwnerChanged, (msg) => [GW3Bridge.activityGwMessageToActivity(msg, new ActivityStatus("created", "", new Date()))], (ent, msg) => GW3Bridge.activityToActivityStatusChangeEvent(ent), this._activityChangeCallbacks); + } + forwardPeerFactoryMessagesToStatusEventHandlers() { + this.forwardAddedAndRemovedMessagesToEventHandler(gwMessagePeerFactoriesAdded, gwMessagePeerFactoriesRemoved, (msg, isAdded) => isAdded + ? msg.factories.map(GW3Bridge.peerFactoryGwMessageEntityToWindowType) + : msg.factory_ids.map((id) => this.peerFactoryIdAndOwnerIdToWindowType(id, msg.owner_id)).filter((x) => x != null), this._windowTypeStatusChangeCallbacks); + } + forwardPeerFactoryMessagesToPeerFactoryRequests() { + this.subscribe(gwMessagePeerRequested, (msg) => { + const factory = this._peerFactoriesRegisteredByUs[msg.peer_factory]; + if (!factory) { + this._gw3Session.send({ + type: gwMmessageError, + request_id: msg.request_id, + reason: `Unknown peer factory ${msg.peer_factory}` + }); + return; + } + try { + const configuration = msg.configuration || {}; + configuration.gateway_token = configuration.gateway_token || msg.gateway_token; + configuration.peer_factory = configuration.peer_factory || msg.peer_factory; + const promise = factory({ + activityId: msg.activity && msg.activity.id, + activityType: msg.activity && msg.activity.type, + type: msg.configuration && msg.configuration.type, + gwToken: configuration.gateway_token, + configuration + }); + if (promise && promise.then && promise.catch) { + promise.catch((err) => this._gw3Session.send({ + type: gwMmessageError, + request_id: msg.request_id, + reason: err && (err.message || JSON.stringify(err)) + })); + } + } + catch (err) { + this._gw3Session.send({ + type: gwMmessageError, + request_id: msg.request_id, + reason: err && (err.message || JSON.stringify(err)) + }); + } + }); + } + forwardActivityWindowMessagesToEventHandlers() { + for (const joinedMessage of [gwMessageActivityJoined, gwMessageJoinedActivity]) { + this.subscribe(joinedMessage, (msg) => { + const joinedId = (joinedMessage === gwMessageActivityJoined) ? msg.joined_id : msg.peer_id; + const joinedType = (joinedMessage === gwMessageActivityJoined) ? msg.joined_type : msg.peer_type; + const joinedName = (joinedMessage === gwMessageActivityJoined) ? msg.joined_name : msg.peer_name; + const entity = new ActivityWindow(joinedId, joinedName, joinedType, msg.activity_id, this.getAgmInstance(joinedId), undefined, this.generateWindowGetter(joinedId), undefined); + if (!this._contextSubscriptions[msg.activity_id]) { + this.subscribeToContext(msg).then(() => { + if (joinedMessage === gwMessageJoinedActivity) { + this._activityJoinedPromiseResolve({}); + } + }); + } + else if (joinedMessage === gwMessageJoinedActivity) { + this._activityJoinedPromiseResolve({}); + } + this.invokeCallbacks(this._activityWindowChangeCallbacks, new EntityEvent(entity, new EntityEventContext(EntityEventType.ActivityWindowJoinedActivity)), joinedMessage); + }); + } + this.subscribe(gwMessageActivityLeft, (msg) => { + const entity = new ActivityWindow(msg.left_id, undefined, undefined, null, this.getAgmInstance(msg.left_id), undefined, this.generateWindowGetter(msg.left_id), undefined); + this.invokeCallbacks(this._activityWindowChangeCallbacks, new EntityEvent(entity, new EntityEventContext(EntityEventType.ActivityWindowLeftActivity)), gwMessageActivityLeft); + }); + this.forwardAddedAndRemovedMessagesToEventHandler(gwMessagePeerCreated, undefined, (msg) => [ + new ActivityWindow(msg.created_id, undefined, undefined, undefined, undefined, undefined, this.generateWindowGetter(msg.created_id), undefined) + ], this._activityWindowChangeCallbacks); + } + getAgmInstance(id) { + return this._config.agm.servers().find((s) => s.peerId === id || s.windowId === id); + } + generateWindowGetter(peerId) { + return () => { + const server = this.getAgmInstance(peerId); + if (!server) { + return; + } + const windowId = server.windowId; + return this._config.windows.list().filter((w) => w.id === windowId)[0]; + }; + } + isOverrideTypeDefinition(value) { + if (typeof value === "undefined") { + return false; + } + if (value.owner) { + return true; + } + return false; + } + } + + class ActivityMy { + constructor(manager, windows) { + this._myAttached = []; + this._myDetached = []; + this._myAttachedTo = []; + this._myDetachedFrom = []; + this._myActivityFrameColorChanged = []; + this._myActivityJoinedCallbacks = []; + this._myActivityRemovedCallbacks = []; + this._myContextUpdateCallbacks = []; + this._logger = Logger.Get(this); + this._m = manager; + manager.ready() + .then((am) => { + am.subscribeActivityContextChanged(this._subscribeMyContextChanged.bind(this)); + am.subscribeWindowEvents(this._subscribeMyWindowEvent.bind(this)); + am.subscribeActivitiesAttached(this._subscribeActivitiesAttached.bind(this)); + am.subscribeActivitiesDetached(this._subscribeActivitiesDetached.bind(this)); + if (windows) { + windows.onWindowFrameColorChanged(this._subscribeWindowFrameColorChanged.bind(this)); + } + }); + } + get window() { + if (isUndefinedOrNull(this._w)) { + const announcedWindows = this._m.announcedWindows; + if (announcedWindows.length > 0) { + this._w = announcedWindows[0]; + } + } + return this._w; + } + get activity() { + const myWin = this.window; + if (isUndefinedOrNull(myWin)) { + return undefined; + } + return myWin.activity; + } + createWindow(windowType) { + return this._m.createWindow(this.activity, windowType); + } + createStackedWindows(windowTypes, timeout) { + return this._m.createStackedWindows(this.activity, windowTypes, timeout); + } + get context() { + const activity = this.activity; + if (isUndefined(activity)) { + return {}; + } + return activity.context; + } + updateContext(context, callback) { + const activity = this.activity; + if (isUndefined(activity)) { + return new Promise((resolve, reject) => { + reject("Not in activity"); + }); + } + return activity.updateContext(context, callback); + } + setContext(context, callback) { + const activity = this.activity; + if (isUndefined(activity)) { + return new Promise((resolve, reject) => { + reject("Not in activity"); + }); + } + return activity.setContext(context, callback); + } + onActivityJoined(callback) { + this._myActivityJoinedCallbacks.push(callback); + const myWin = this.window; + if (!isUndefinedOrNull(myWin) && !isUndefinedOrNull(myWin.activity)) { + callback(myWin.activity); + } + } + onActivityLeft(callback) { + this._myActivityRemovedCallbacks.push(callback); + } + onContextChanged(callback) { + this._myContextUpdateCallbacks.push(callback); + const myWin = this.window; + if (isUndefinedOrNull(myWin)) { + return; + } + const activity = myWin.activity; + if (isUndefinedOrNull(activity)) { + return; + } + callback(activity.context, activity.context, [], activity); + } + clone(options, callback) { + const act = this.activity; + return this._m.clone(act, options, callback); + } + attach(activity, tag) { + let activityId; + if (typeof activity === "string") { + activityId = activity; + } + else { + activityId = activity.id; + } + return this._m.attachActivities(activityId, this.activity.id, tag); + } + onActivityAttached(callback) { + this._myAttached.push(callback); + } + onActivityDetached(callback) { + this._myDetached.push(callback); + } + onAttachedToActivity(callback) { + this._myAttachedTo.push(callback); + } + onDetachedFromActivity(callback) { + this._myDetachedFrom.push(callback); + } + get attached() { + if (!this.activity) { + return []; + } + return this.activity.attached; + } + setFrameColor(color, callback) { + if (this.activity) { + return this.activity.setFrameColor(color, callback); + } + else { + return Promise.resolve(null); + } + } + getFrameColor() { + if (this.activity) { + return this.activity.getFrameColor(); + } + return ""; + } + onFrameColorChanged(callback) { + this._myActivityFrameColorChanged.push(callback); + } + _subscribeMyContextChanged(activity, context, delta, removed) { + const myWin = this.window; + if (isUndefinedOrNull(myWin)) { + return; + } + const myActivity = myWin.activity; + if (isUndefinedOrNull(myActivity)) { + return; + } + if (activity.id !== myActivity.id) { + return; + } + this._notifyMyContextChanged(activity, context, delta, removed); + } + _subscribeMyWindowEvent(activity, window, event) { + if (isUndefinedOrNull(this.window)) { + return; + } + if (this.window.id !== window.id) { + return; + } + if (event === EntityEventType.ActivityWindowJoinedActivity) { + this._notifyMyWindowEvent(activity, this._myActivityJoinedCallbacks); + this._notifyMyContextChanged(activity, activity.context, null, null); + } + else if (event === EntityEventType.ActivityWindowLeftActivity) { + this._notifyMyWindowEvent(activity, this._myActivityRemovedCallbacks); + } + } + _notifyMyWindowEvent(activity, callbackStore) { + callbackStore.forEach((element) => { + try { + element(activity, event); + } + catch (e) { + this._logger.warn("error in user callback " + e); + } + }); + } + _notifyMyContextChanged(activity, context, delta, removed) { + delta = delta || {}; + removed = removed || []; + this._myContextUpdateCallbacks.forEach((element) => { + try { + element(context, delta, removed, activity); + } + catch (e) { + this._logger.warn("error in user callback " + e); + } + }); + } + _notifyAttached(state) { + this._myAttached.forEach((cb) => { + try { + cb(state); + } + catch (e) { + this._logger.warn("error in user callback " + e); + } + }); + } + _notifyDetached(state) { + this._myDetached.forEach((cb) => { + try { + cb(state); + } + catch (e) { + this._logger.warn("error in user callback " + e); + } + }); + } + _notifyAttachedTo(state) { + this._myAttachedTo.forEach((cb) => { + try { + cb(this.activity, state); + } + catch (e) { + this._logger.warn("error in user callback " + e); + } + }); + } + _notifyDetachedFrom(detached, existing, state) { + this._myDetachedFrom.forEach((cb) => { + try { + cb(detached, existing, state); + } + catch (e) { + this._logger.warn("error in user callback " + e); + } + }); + } + _subscribeActivitiesAttached(newAct, state) { + const myWin = this.window; + if (isUndefinedOrNull(myWin)) { + return; + } + const myActivity = myWin.activity; + if (isUndefinedOrNull(myActivity)) { + return; + } + if (newAct.id !== myActivity.id) { + return; + } + if (state.windowIds.indexOf(myWin.id) >= 0) { + this._notifyAttachedTo(state); + return; + } + this._notifyAttached(state); + } + _subscribeActivitiesDetached(newAct, oldAct, state) { + const myWin = this.window; + if (isUndefinedOrNull(myWin)) { + return; + } + const myActivity = myWin.activity; + if (isUndefinedOrNull(myActivity)) { + return; + } + if (oldAct.id === myActivity.id) { + this._notifyDetached(state); + } + if (newAct.id === myActivity.id) { + this._notifyDetachedFrom(newAct, oldAct, state); + } + } + _subscribeWindowFrameColorChanged(window) { + const act = this.activity; + if (!act) { + return; + } + if (!act.owner) { + return; + } + if (act.owner.underlyingWindow.id === window.id) { + this._myActivityFrameColorChanged.forEach((callback) => { + callback(window.frameColor); + }); + } + } + } + + class ReadyMarker { + constructor(name, signalsToWait) { + this._logger = Logger.Get("ReadyMarker [" + name + "]"); + this._logger.debug("Initializing ready marker for '" + name + "' with " + signalsToWait + " signals to wait"); + if (signalsToWait <= 0) { + throw new Error("Invalid signal number. Should be > 0"); + } + this._signals = signalsToWait; + this._callbacks = []; + this._name = name; + } + setCallback(callback) { + if (this.isSet()) { + callback(undefined); + return; + } + else if (this.isError()) { + callback(this._error); + return; + } + this._callbacks.push(callback); + } + signal(message) { + this._logger.debug("Signaled - " + message + " - signals left " + (this._signals - 1)); + this._signals--; + if (this._signals < 0) { + throw new Error("Error in ready marker '" + this._name + " - signals are " + this._signals); + } + if (this.isSet()) { + this._callbacks.forEach((callback) => { + callback(undefined); + }); + } + } + error(error) { + this._error = error; + this._callbacks.forEach((errorCallback) => { + errorCallback(error); + }); + } + isSet() { + if (this.isError()) { + return false; + } + return this._signals === 0; + } + isError() { + return !isUndefined(this._error); + } + getError() { + return this._error; + } + } + + class EntityObservableCollection { + constructor(processNew) { + this._items = {}; + this._listeners = []; + this._processNew = processNew; + } + addOne(item) { + this.add([item]); + } + add(items) { + items.forEach((element) => { + this.process(new EntityEvent(element, new EntityEventContext(EntityEventType.Added))); + }); + } + process(event) { + const context = event.context; + const type = context.type; + const entity = event.entity; + if (type === EntityEventType.StatusChange && + !context.oldStatus) { + const act = this._items[entity.id]; + if (act) { + context.oldStatus = act.status; + } + } + if (type === EntityEventType.StatusChange && + context.oldStatus && + context.newStatus && + context.oldStatus.state === + context.newStatus.state) { + context.type = EntityEventType.Updated; + } + if (typeof htmlContainer === "undefined") { + if (type === EntityEventType.ActivityWindowJoinedActivity && + this._items[entity.id] && + this._items[entity.id].activity) { + context.type = EntityEventType.Updated; + } + if (type === EntityEventType.ActivityWindowLeftActivity && + this._items[entity.id] && + !this._items[entity.id].activity) { + context.type = EntityEventType.Updated; + } + } + const internalEntity = this._updateInternalCollections(entity, type, context); + this._notifyListeners(internalEntity, context); + return internalEntity; + } + get() { + const result = []; + for (const key in this._items) { + if (this._items.hasOwnProperty(key)) { + const element = this._items[key]; + result.push(element); + } + } + return result; + } + getByName(name) { + for (const key in this._items) { + if (key === name) { + return this._items[key]; + } + } + return undefined; + } + getOrWait(name) { + return new Promise((resolve) => { + const entityAddedHandler = (entity) => { + if (entity.id !== name) { + return; + } + resolve(entity); + this.unsubscribe(entityAddedHandler); + }; + this.subscribe(entityAddedHandler); + const window = this.getByName(name); + if (window) { + this.unsubscribe(entityAddedHandler); + resolve(window); + return; + } + }); + } + subscribe(handler) { + this._listeners.push(handler); + Object.keys(this._items).forEach((key) => { + const element = this._items[key]; + handler(element, new EntityEventContext(EntityEventType.Added.toString())); + }); + return () => { + this.unsubscribe(handler); + }; + } + unsubscribe(handler) { + const index = this._listeners.indexOf(handler); + if (index !== -1) { + this._listeners.splice(index, 1); + } + } + _notifyListeners(entity, context) { + this._listeners.forEach((listener) => { + try { + listener(entity, context); + } + catch (e) { + return; + } + }); + } + _updateInternalCollections(entity, type, context) { + const entityAsAny = entity; + const isActivityDestroy = (type === EntityEventType.StatusChange && + entityAsAny.status && + entityAsAny.status.state === ActivityState.Destroyed) || + (type === EntityEventType.StatusChange && + context && + context.newStatus && + context.newStatus.state === ActivityState.Destroyed); + const isWindowClose = type === EntityEventType.Closed; + const isTypeRemove = type === EntityEventType.Removed && typeof entityAsAny.isIndependent === "undefined"; + if (isTypeRemove || isWindowClose || isActivityDestroy) { + const oldEntity = this._items[entity.id]; + delete this._items[entity.id]; + this._processNew(entity); + if (oldEntity) { + entity._beforeDelete(oldEntity); + } + return entity; + } + else { + const key = entity.id; + if (!this._items.hasOwnProperty(key)) { + this._processNew(entity); + this._items[entity.id] = entity; + } + else { + this._items[entity.id]._update(entity); + } + } + return this._items[entity.id]; + } + } + + class ActivityManager { + get usingHc() { + return this._bridge.bridgeType === "HC"; + } + get announcedWindows() { + return this._announcedWindows; + } + set announcedWindows(v) { + throw new Error("not allowed"); + } + constructor(bridge, autoAnnounce, windows) { + this._logger = Logger.Get("activityManager"); + this._announcedWindows = []; + this._attachedCallbacks = []; + this._detachedCallbacks = []; + this._frameColorChangesCallbacks = []; + this._windowHandlers = []; + this._bridge = bridge; + this._activityTypes = new EntityObservableCollection((e) => this._grabEntity(e)); + this._windowTypes = new EntityObservableCollection((e) => this._grabEntity(e)); + this._activities = new EntityObservableCollection((e) => this._grabEntity(e)); + this._windows = new EntityObservableCollection((e) => this._grabEntity(e)); + this._dataReadyMarker = new ReadyMarker("Activity Manager Data", ["GetActivityTypes", "GetWindowTypes", "GetActivities", "GetWindows"].length); + this._descriptorsMarker = new ReadyMarker("Attached Activities Descriptors", ["GetDescriptors"].length); + if (autoAnnounce) { + this._readyMarker = new ReadyMarker("Activity Manager Announce", ["Announcement"].length); + this._dataReadyMarker.setCallback((dataErr) => { + if (dataErr) { + this._readyMarker.error(dataErr); + } + this._descriptorsMarker.setCallback((err) => { + if (err) { + this._readyMarker.error(err); + } + this._logger.debug("Auto announcing window"); + this.announceWindow() + .then((w) => { + this._announcedWindows.push(w); + this._readyMarker.signal("Successfully announced window with id '" + w.id + "'"); + }) + .catch((errCatch) => { + this._logger.debug("Will not announce window - " + errCatch); + this._readyMarker.signal(); + }); + }); + this.refreshDescriptors(); + }); + } + else { + this._readyMarker = this._dataReadyMarker; + } + this._bridge.onActivitiesAttached((e) => { + this._handleActivitiesAttached(e); + }); + this._bridge.onActivitiesDetached((e) => { + this._handleActivitiesDetached(e); + }); + this._bridge.onActivityAttachedDescriptorsRefreshed((e) => { + this._handleActivityDescriptorsRefreshed(e); + }); + if (windows) { + windows.onWindowFrameColorChanged(this._handleWindowFrameColorChanged.bind(this)); + } + this._bridge.init(); + this._subscribeForData(); + this._bridge + .initReady() + .then((aw) => { + this._getInitialData(); + }) + .catch((error) => { + console.log(error); + }); + } + ready(callback) { + const promise = new Promise((resolve, reject) => { + this._readyMarker.setCallback((err) => { + if (!err) { + resolve(this); + } + else { + reject(this._readyMarker.getError()); + } + }); + }); + return nodeify(Promise.all([this._bridge.ready(), promise]).then(() => this), callback); + } + getActivityTypes() { + return this._activityTypes.get(); + } + getActivityType(name) { + return this._activityTypes.getByName(name); + } + registerActivityType(activityTypeName, ownerWindowType, helperWindowTypes, config, description, callback) { + const promise = new Promise((resolve, reject) => { + if (isUndefinedOrNull(activityTypeName)) { + reject("activityTypeName argument can not be undefined"); + return; + } + if (!isString(activityTypeName)) { + reject("activityTypeName should be string"); + return; + } + const actType = this.getActivityType(activityTypeName); + if (!isUndefinedOrNull(actType)) { + reject("Activity type '" + activityTypeName + "' already exists"); + return; + } + let ownerDefinition; + if (isUndefined(ownerWindowType)) { + reject("Owner window type can not be undefined"); + return; + } + if (isString(ownerWindowType)) { + ownerDefinition = { type: (ownerWindowType), name: "", isIndependent: false, arguments: {} }; + } + else { + ownerDefinition = (ownerWindowType); + } + const helperDefinitions = []; + if (!isUndefined(helperWindowTypes) && isArray(helperWindowTypes)) { + for (const index in helperWindowTypes) { + const item = helperWindowTypes[index]; + if (isString(item)) { + const definition = { + type: (item), + name: "", + isIndependent: false, + arguments: {}, + relativeTo: "", + relativeDirection: "", + windowStyleAttributes: {} + }; + helperDefinitions.push(definition); + } + else { + helperDefinitions.push(item); + } + } + } + this._bridge + .registerActivityType(activityTypeName, ownerDefinition, helperDefinitions, config, description) + .then((activityType) => { + this._grabEntity(activityType); + resolve(activityType); + }) + .catch((error) => { + reject(error); + }); + }); + return nodeify(promise, callback); + } + unregisterActivityType(type, callback) { + const promise = new Promise((resolve, reject) => { + const actType = this.getActivityType(type); + if (isUndefined(actType)) { + reject("Activity type '" + type + "' does not exists"); + return; + } + this._bridge.unregisterActivityType(type).then(() => resolve(actType), reject); + }); + return nodeify(promise, callback); + } + initiate(activityType, context, callback, configuration) { + const promise = new Promise((resolve, reject) => { + const actType = this.getActivityType(activityType); + if (isUndefined(actType)) { + reject("Activity type '" + activityType + "' does not exists"); + return; + } + this._bridge + .initiateActivity(activityType, context, configuration) + .then((actId) => { + this._activities + .getOrWait(actId) + .then((act) => { + resolve(act); + }) + .catch((err) => reject(err)); + }) + .catch((err) => { + reject(err); + }); + }); + return nodeify(promise, callback); + } + subscribeActivityTypeEvents(handler) { + this._activityTypes.subscribe((at, context) => { + handler(at, context.type); + }); + } + getWindowTypes() { + return this._windowTypes.get(); + } + getWindowType(name) { + return this._windowTypes.getByName(name); + } + registerWindowFactory(windowType, factoryMethod, callback) { + const promise = new Promise((resolve, reject) => { + if (isUndefinedOrNull(windowType)) { + reject("no windowType specified"); + return; + } + if (isObject(windowType)) { + windowType = windowType.getName(); + } + else if (!isString(windowType)) { + reject("windowType should be string or object that has getName method"); + return; + } + this._bridge + .registerWindowFactory(windowType, factoryMethod) + .then((v) => { + resolve(v); + }) + .catch((err) => { + reject(err); + }); + }); + return nodeify(promise, callback); + } + unregisterWindowFactory(windowType, callback) { + const promise = new Promise((resolve, reject) => { + if (isUndefinedOrNull(windowType)) { + reject("no windowType specified"); + return; + } + if (!isString(windowType)) { + reject("windowType should be a string"); + return; + } + this._bridge + .unregisterWindowFactory(windowType) + .then((v) => { + resolve(v); + }) + .catch((err) => { + reject(err); + }); + }); + return nodeify(promise, callback); + } + getActivities(activityType) { + let act = this._activities.get(); + act = act.filter((a) => a._ownerId); + if (!activityType) { + return act; + } + let types = activityType; + if (isString(activityType)) { + types = [activityType]; + } + else if (activityType instanceof ActivityType) { + types = [activityType.name]; + } + else if (activityType instanceof Array) ; + else { + throw new Error("Invalid input argument 'activityType' = " + activityType); + } + return act.filter((at) => { + const type = at.type; + return some(types, (t) => { + return type.id === t.id; + }); + }); + } + getActivityById(id) { + return this._activities.getByName(id); + } + announceWindow(activityWindowId, windowType) { + const promise = new Promise((resolve, reject) => { + const announcementInfo = this._bridge.getAnnouncementInfo(); + if (isUndefined(activityWindowId)) { + activityWindowId = announcementInfo.activityWindowId; + } + if (isUndefined(windowType)) { + windowType = announcementInfo.activityWindowType; + } + if (isUndefinedOrNull(windowType)) { + throw new Error("Can not announce - unknown windowType"); + } + const activityId = announcementInfo && announcementInfo.activityId; + if (isUndefinedOrNull(activityWindowId)) { + this._logger.debug("Registering window with type:'" + windowType + "', name:'" + announcementInfo.activityWindowName + "', ind.:'" + announcementInfo.activityWindowIndependent + "'"); + this._bridge.registerWindow(windowType, announcementInfo.activityWindowName, announcementInfo.activityWindowIndependent) + .then(this._windows.getOrWait.bind(this._windows)) + .then((w) => { + if (activityId) { + return this._activities.getOrWait(activityId).then((_) => w); + } + else { + return w; + } + }) + .then((w) => { + resolve(w); + }) + .catch((err) => { + this._logger.error(err); + }); + } + else { + this._logger.debug("Announcing window with id '" + activityWindowId + "' and type '" + windowType + "'"); + const currentWindow = this._windows.getByName(activityWindowId); + if (!isUndefinedOrNull(currentWindow)) { + this._logger.debug("Window with id '" + activityWindowId + "' already announced - reusing the window"); + resolve(currentWindow); + return; + } + const windowEventHandler = (a, w, e) => { + if (activityWindowId === w.id) { + if (e === EntityEventType.ActivityWindowJoinedActivity) { + const activity = w.activity; + if (isUndefined(activity)) { + reject("UNDEFINED ACTIVITY"); + } + this._logger.trace("Got joined event for id '" + activityWindowId + "'"); + resolve(w); + this.unsubscribeWindowEvents(windowEventHandler); + } + } + }; + this.subscribeWindowEvents(windowEventHandler); + this._logger.trace("Waiting for joined event for id '" + activityWindowId + "'"); + this._bridge.announceWindow(windowType, activityWindowId); + } + }); + return promise; + } + subscribeWindowTypeEvents(handler) { + this._windowTypes.subscribe((wt, context) => { + handler(wt, context.type); + }); + } + subscribeActivityEvents(handler) { + return this._activities.subscribe((act, context) => { + if (context.type === EntityEventType.StatusChange) { + const p = context; + handler(act, p.newStatus, p.oldStatus); + } + if (context.type === EntityEventType.Removed || + (context.type === EntityEventType.StatusChange && + context.newStatus.getState() === ActivityState.Destroyed)) { + for (const window of this._windows.get()) { + if (window.activity && window.activity.id === act.id) { + this._windows.process(new EntityEvent(window, new EntityEventContext(EntityEventType.ActivityWindowLeftActivity))); + } + } + } + }); + } + subscribeWindowEvents(handler) { + const wrappingHandler = (window, context) => { + let eventType = context.type; + if (eventType === EntityEventType.Added) { + eventType = "opened"; + } + handler(window.activity, window, eventType); + }; + this._windowHandlers.push([handler, wrappingHandler]); + return this._windows.subscribe(wrappingHandler); + } + unsubscribeWindowEvents(handler) { + const found = this._windowHandlers.find((pair) => pair[0] === handler); + if (found) { + this._windowHandlers.splice(this._windowHandlers.indexOf(found), 1); + this._windows.unsubscribe(found[1]); + } + } + createWindow(activity, windowTypeOrConfiguration, callback) { + const promise = new Promise((resolve, reject) => { + if (isUndefinedOrNull(windowTypeOrConfiguration)) { + reject("windowType is undefined"); + } + let windowDefinition; + if (isString(windowTypeOrConfiguration)) { + windowDefinition = { type: (windowTypeOrConfiguration), name: "", isIndependent: false, arguments: {} }; + } + else if (windowTypeOrConfiguration instanceof WindowType) { + windowDefinition = { + type: windowTypeOrConfiguration.type || windowTypeOrConfiguration.id, + name: windowTypeOrConfiguration.name || windowTypeOrConfiguration.type || windowTypeOrConfiguration.id, + isIndependent: false + }; + } + else { + const invalidKeys = ["url"]; + const filteredWindowTypeOrConfiguration = {}; + Object.keys(windowTypeOrConfiguration).forEach((key) => { + if (invalidKeys.indexOf(key) === -1) { + filteredWindowTypeOrConfiguration[key] = windowTypeOrConfiguration[key]; + } + }); + windowDefinition = filteredWindowTypeOrConfiguration; + } + let relativeToWindow; + if (!isUndefinedOrNull(windowDefinition.relativeTo)) { + relativeToWindow = windowDefinition.relativeTo; + if (typeof relativeToWindow === "string") { + const windows = this.getWindows({ type: relativeToWindow }); + if (!isUndefinedOrNull(windows) && windows.length > 0) { + windowDefinition.relativeTo = windows[0].id; + } + } + else if (!isUndefinedOrNull(relativeToWindow.type)) { + const windows = this.getWindows({ type: relativeToWindow.type }); + if (!isUndefinedOrNull(windows) && windows.length > 0) { + windowDefinition.relativeTo = windows[0].id; + } + } + else if (!isUndefinedOrNull(relativeToWindow.windowId)) { + windowDefinition.relativeTo = relativeToWindow.windowId; + } + } + this._bridge.createWindow(activity && activity.id, windowDefinition) + .then((wid) => { + this._logger.debug("Window created, waiting for window entity with id " + wid); + const handler = (window, context) => { + if (window.id === wid && (!activity || window.activity)) { + this._logger.debug("Got entity window with id " + wid); + resolve(window); + this._windows.unsubscribe(handler); + } + }; + this._windows.subscribe(handler); + }) + .catch((err) => { + reject(err); + }); + }); + return nodeify(promise, callback); + } + createStackedWindows(activity, relativeWindowTypes, timeout, callback) { + const promise = new Promise((resolve, reject) => { + if (isUndefinedOrNull(activity)) { + reject("activity is undefined"); + } + if (isUndefinedOrNull(relativeWindowTypes)) { + reject("relativeWindowTypes is undefined"); + } + if (!Array.isArray(relativeWindowTypes)) { + reject("relativeWindowTypes has to be an array"); + } + if (isUndefinedOrNull(timeout)) { + timeout = 20000; + } + const windowDefinitions = []; + relativeWindowTypes.forEach((element) => { + let windowDefinition; + if (isString(element)) { + windowDefinition = { type: (element), name: "", isIndependent: false, arguments: {} }; + } + else { + windowDefinition = (element); + } + windowDefinition.stackedWindow = true; + windowDefinition.timeout = timeout; + let relativeToWindow; + if (!isUndefinedOrNull(windowDefinition.relativeTo)) { + relativeToWindow = windowDefinition.relativeTo; + if (!isUndefinedOrNull(relativeToWindow.type)) { + windowDefinition.relativeTo = relativeToWindow.type; + } + else if (!isUndefinedOrNull(relativeToWindow.windowId)) { + const windows = this.getWindows({ id: relativeToWindow.windowId }); + if (!isUndefinedOrNull(windows) && windows.length > 0) { + windowDefinition.relativeTo = windows[0].type.name; + } + } + } + windowDefinitions.push(windowDefinition); + }); + const tasks = []; + windowDefinitions.forEach((wd) => tasks.push(this.createWindow(activity, wd))); + Promise.all(tasks).then(resolve).catch(reject); + }); + return nodeify(promise, callback); + } + addWindowToActivity(activity, window, callback) { + const toReturn = this._bridge.joinActivity(activity.id, window.id) + .then(() => window); + nodeify(toReturn, callback); + return toReturn; + } + leaveWindowFromActivity(activity, window, callback) { + const toReturn = this._bridge.leaveActivity(activity.id, window.id) + .then(() => window); + nodeify(toReturn, callback); + return toReturn; + } + setActivityContext(activity, context, callback) { + const promise = new Promise((resolve, reject) => { + if (isUndefinedOrNull(activity)) { + reject("activity can not be null"); + } + this._bridge + .updateActivityContext(activity, context, true) + .then((_) => { + resolve(activity); + }) + .catch((err) => { + reject(err); + }); + }); + return nodeify(promise, callback); + } + updateActivityContext(activity, context, callback) { + const promise = new Promise((resolve, reject) => { + if (isUndefinedOrNull(activity)) { + reject("activity can not be null"); + } + const removedKeys = []; + for (const key in context) { + if (context.hasOwnProperty(key) && context[key] === null) { + removedKeys.push(key); + } + } + for (const removedKey of removedKeys) { + delete context[removedKey]; + } + this._bridge + .updateActivityContext(activity, context, false, removedKeys) + .then((_) => { + resolve(activity); + }) + .catch((err) => { + reject(err); + }); + }); + return nodeify(promise, callback); + } + subscribeActivityContextChanged(handler) { + this._activities.subscribe((act, context) => { + if (context.type === EntityEventType.ActivityContextChange) { + const updateContext = context; + handler(act, updateContext.context, updateContext.updated, updateContext.removed); + } + }); + } + stopActivity(activity, callback) { + const promise = this._bridge.stopActivity(activity); + return nodeify(promise, callback); + } + getWindows(filter) { + if (isUndefined(filter)) { + return this._windows.get(); + } + if (!isUndefined(filter.id)) { + return [this._windows.getByName(filter.id)]; + } + const allWindows = this._windows.get(); + return allWindows.filter((w) => { + if (!isUndefined(filter.type) && w.type.id !== filter.type) { + return false; + } + if (!isUndefined(filter.name) && w.name !== filter.name) { + return false; + } + if (!isUndefined(filter.activityId)) { + if (isUndefinedOrNull(w.activity)) { + return false; + } + if (w.activity.id !== filter.activityId) { + return false; + } + } + return true; + }); + } + getWindowBounds(id) { + return this._bridge.getWindowBounds(id); + } + setWindowBounds(id, bounds, callback) { + const promise = new Promise((resolve, reject) => { + this._bridge.setWindowBounds(id, bounds) + .then(() => resolve()) + .catch((err) => reject(err)); + }); + return nodeify(promise, callback); + } + closeWindow(id) { + return this._bridge.closeWindow(id); + } + activateWindow(id, focus) { + return this._bridge.activateWindow(id, focus); + } + setWindowVisibility(id, visible) { + return this._bridge.setWindowVisibility(id, visible); + } + clone(activity, cloneOptions, callback) { + const promise = new Promise((resolve, reject) => { + if (!activity) { + reject("activity can not be null"); + } + this._bridge.cloneActivity(activity.id, cloneOptions) + .then((activityId) => { + this._activities + .getOrWait(activityId) + .then((act) => { + resolve(act); + }) + .catch((err) => reject(err)); + }) + .catch((err) => reject(err)); + }); + return nodeify(promise, callback); + } + attachActivities(from, to, tag, callback) { + tag = tag || {}; + const promise = new Promise((resolve, reject) => { + const fromActivity = this._activities.getByName(from); + if (!fromActivity) { + reject("can not find activity with id " + from); + return; + } + const toActivity = this._activities.getByName(to); + if (!toActivity) { + reject("can not find activity with id " + to); + return; + } + return this._bridge.attachActivities(from, to, tag) + .then((data) => { + const newActId = data.to; + const state = data.descriptor; + const allStates = data.descriptors; + this._activities.getOrWait(newActId).then((act) => { + act._updateDescriptors(allStates); + const stateWrapped = act.attached.filter((u) => u.ownerId === state.ownerId)[0]; + resolve(stateWrapped); + }); + }) + .catch((err) => { + reject(err); + }); + }); + return nodeify(promise, callback); + } + detachActivities(activityId, descriptor, callback) { + const promise = new Promise((resolve, reject) => { + return this._bridge.detachActivities(activityId, descriptor) + .then(() => { + const oldActId = undefined; + const newActId = undefined; + const descriptors = undefined; + this._activities + .getOrWait(oldActId) + .then((oldAct) => { + oldAct._updateDescriptors(descriptors); + this._activities + .getOrWait(newActId) + .then((newAct) => { + resolve(newAct); + }); + }) + .catch((err) => reject(err)); + }) + .catch((err) => { + reject(err); + }); + }); + return nodeify(promise, callback); + } + subscribeActivitiesAttached(callback) { + this._attachedCallbacks.push(callback); + } + subscribeActivitiesDetached(callback) { + this._detachedCallbacks.push(callback); + } + subscribeActivityFrameColorChanged(callback) { + this._frameColorChangesCallbacks.push(callback); + } + _grabEntity(entity) { + entity._manager = this; + } + _getInitialData() { + this._logger.debug("Request initial data..."); + this._bridge.getActivityTypes() + .then((at) => { + this._activityTypes.add(at); + this._dataReadyMarker.signal("Got act types"); + }) + .catch((error) => { + this._logger.error(error); + this._dataReadyMarker.error("Can not initialize ActivityManager - error getting activity types -" + error); + }); + this._bridge.getWindowTypes() + .then((wt) => { + this._windowTypes.add(wt); + this._dataReadyMarker.signal("Got window types"); + }) + .catch((error) => { + this._logger.error(error); + this._dataReadyMarker.error("Can not initialize ActivityManager - error getting window types " + error); + }); + this._bridge.getActivities() + .then((ac) => { + this._activities.add(ac); + this._dataReadyMarker.signal("Got activities"); + }) + .catch((error) => { + this._logger.error(error); + this._dataReadyMarker.error("Can not initialize ActivityManager - error getting activity instances -" + error); + }); + this._bridge.getActivityWindows() + .then((aw) => { + this._windows.add(aw); + this._dataReadyMarker.signal("Got windows"); + }) + .catch((error) => { + this._logger.error(error); + this._dataReadyMarker.error("Can not initialize ActivityManager - error getting activity windows -" + error); + }); + } + _subscribeForData() { + this._logger.debug("Subscribe for data..."); + this._bridge.onActivityTypeStatusChange((event) => { + this._activityTypes.process(event); + }); + this._bridge.onWindowTypeStatusChange((event) => { + this._windowTypes.process(event); + }); + this._bridge.onActivityWindowChange((event) => { + this._windows.process(event); + }); + this._bridge.onActivityStatusChange((event) => { + this._activities.process(event); + }); + } + _handleActivitiesAttached(data) { + const newActId = data.to; + const descriptor = data.descriptor; + const descriptors = data.descriptors; + this._activities.getOrWait(newActId).then((act) => { + act._updateDescriptors(descriptors); + const descriptorAsObjectFromAPI = act.attached.filter((u) => u.ownerId === descriptor.ownerId)[0]; + this._attachedCallbacks.forEach((callback) => { + try { + callback(act, descriptorAsObjectFromAPI); + } + catch (err) { + return; + } + }); + }); + } + _handleActivitiesDetached(data) { + const oldActId = data.oldActivityId; + const newActId = data.newActivityId; + const descriptors = data.descriptors; + const descriptor = data.descriptor; + this._activities.getOrWait(oldActId).then((oldAct) => { + oldAct._updateDescriptors(descriptors); + this._activities.getOrWait(newActId).then((newAct) => { + this._detachedCallbacks.forEach((callback) => { + try { + callback(newAct, oldAct, descriptor); + } + catch (err) { + return; + } + }); + }); + }); + } + _handleActivityDescriptorsRefreshed(data) { + const id = data.id; + const descriptors = data.descriptors; + const act = this._activities.getByName(id); + if (act) { + act._updateDescriptors(descriptors); + } + } + refreshDescriptors() { + this._bridge.getAttachedDescriptors() + .then((map) => { + if (map) { + Object.keys(map).forEach((key) => { + const actId = key; + const descriptors = map[key]; + const act = this._activities.getByName(actId); + if (act) { + act._updateDescriptors(descriptors); + } + }); + } + this._descriptorsMarker.signal("Successfully got descriptors"); + }) + .catch((err) => { + this._descriptorsMarker.error("failed to get descriptors - " + err); + }); + } + _handleWindowFrameColorChanged(win) { + if (!win.activityId) { + return; + } + const act = this._activities.getByName(win.activityId); + if (!act) { + return; + } + if (!act.owner) { + return; + } + if (act.owner.underlyingWindow.id !== win.id) { + return; + } + this._frameColorChangesCallbacks.forEach((callback) => { + try { + callback(act, win.frameColor); + } + catch (e) { + return; + } + }); + } + } + + class ActivityManagementAPI { + constructor(manager, my) { + this._m = manager; + this._my = my; + this.activityTypes = { + get: this._getActivityTypesWrapper.bind(this), + register: this._m.registerActivityType.bind(this._m), + unregister: this._m.unregisterActivityType.bind(this._m), + subscribe: this._m.subscribeActivityTypeEvents.bind(this._m), + unsubscribe: undefined, + initiate: this._m.initiate.bind(this._m) + }; + this.windowTypes = { + get: this._getWindowTypesWrapper.bind(this), + registerFactory: this._m.registerWindowFactory.bind(this._m), + unregisterFactory: this._m.unregisterWindowFactory.bind(this._m), + subscribe: this._m.subscribeWindowTypeEvents.bind(this._m), + unsubscribe: undefined + }; + this.windows = { + get: this._m.getWindows.bind(this._m), + subscribe: this._m.subscribeWindowEvents.bind(this._m), + announce: this._m.announceWindow.bind(this._m), + unsubscribe: undefined, + create: this._m.createWindow.bind(this._m) + }; + this.instances = { + get: this._m.getActivities.bind(this._m), + subscribe: this._m.subscribeActivityEvents.bind(this._m), + unsubscribe: undefined + }; + } + onAttached(callback) { + this._m.subscribeActivitiesAttached(callback); + } + onDetached(callback) { + this._m.subscribeActivitiesDetached(callback); + } + onActivityFrameColorChanged(callback) { + this._m.subscribeActivityFrameColorChanged(callback); + } + _getActivityTypesWrapper(name) { + if (isUndefined(name)) { + return this._m.getActivityTypes(); + } + return this._m.getActivityType(name); + } + _getWindowTypesWrapper(name) { + if (isUndefined(name)) { + return this._m.getWindowTypes(); + } + return this._m.getWindowType(name); + } + } + + class ActivityAPI { + constructor(manager, my) { + this._mgr = manager; + this._my = my; + this.all = new ActivityManagementAPI(manager, my); + } + ready(callback) { + const promise = new Promise((resolve, reject) => { + this._mgr.ready() + .then(() => { + resolve(this); + }) + .catch((err) => { + reject(err); + }); + }); + return nodeify(promise, callback); + } + get my() { + return this._my; + } + get aware() { + return this._my.window !== undefined; + } + get inActivity() { + return this.aware && this._my.activity !== undefined; + } + get agm() { + if (!this.aware) { + return undefined; + } + if (!this.inActivity) { + return new ActivityAGM(null); + } + return this._my.activity.agm; + } + getAvailableFrameColors() { + return []; + } + } + + class ActivityModule { + static checkIsUsingGW3Implementation(connection) { + return connection.protocolVersion === 3; + } + get api() { + return this._api; + } + set api(value) { + this._api = value; + } + constructor(config) { + if (!config) { + throw new Error("config can not be null"); + } + if (!isUndefined(config.logLevel)) { + Logger.Level = config.logLevel; + } + if (!isUndefinedOrNull(config.logger)) { + Logger.GlueLogger = config.logger; + } + let bridge; + this._isUsingHCImplementation = config.gdMajorVersion === 2; + this._isUsingGW3Implementation = ActivityModule.checkIsUsingGW3Implementation(config.connection); + if (this._isUsingHCImplementation) { + throw new Error("GD2 not supported"); + } + else if (this._isUsingGW3Implementation) { + bridge = new GW3Bridge(config); + } + else { + throw new Error("Unable to instantiate activity bridge implementation"); + } + if (!bridge) { + throw new Error("A bridge to native activity is needed to create activity lib."); + } + ActivityAGM.AGM = config.agm; + const activityManager = new ActivityManager(bridge, !config.disableAutoAnnounce, config.windows); + const my = new ActivityMy(activityManager, config.windows); + this._api = new ActivityAPI(activityManager, my); + this._readyPromise = activityManager.ready().then((_) => this); + } + get isUsingHCImplementation() { + return this._isUsingHCImplementation; + } + get isUsingGW3Implementation() { + return this._isUsingGW3Implementation; + } + ready(callback) { + return nodeify(this._readyPromise, callback); + } + } + + const ShutdownMethodName = "T42.ACS.Shutdown"; + const OnGDShutdownMethodName = "T42.ACS.OnGDShutdown"; + const RestartMethodName = "T42.ACS.Restart"; + const GetConfigurationRegionMethodName = "T42.ACS.GetConfigurationRegion"; + const SetConfigurationRegionMethodName = "T42.ACS.SetConfigurationRegion"; + const GetUserMethodName = "T42.ACS.GetUser"; + const GetBranchesMethodName = "T42.ACS.GetBranches"; + const GetCurrentBranchMethodName = "T42.ACS.GetCurrentBranch"; + const SetCurrentBranchMethodName = "T42.ACS.SetCurrentBranch"; + const GetFunctionalEntitlementMethodName = "T42.ACS.GetFunctionalEntitlement"; + const CanIMethodName = "T42.ACS.CanI"; + const StartApplicationMethodName = "T42.ACS.StartApplication"; + const StopApplicationMethodName = "T42.ACS.StopApplication"; + const ActivateApplicationMethodName = "T42.ACS.ActivateApplication"; + const ACSExecute = "T42.ACS.Execute"; + const OnEventMethodName = "T42.ACS.OnEvent"; + const GetApplicationsMethodName = "T42.ACS.GetApplications"; + + var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; + + function getDefaultExportFromCjs (x) { + return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; + } + + function createRegistry(options) { + if (options && options.errorHandling + && typeof options.errorHandling !== "function" + && options.errorHandling !== "log" + && options.errorHandling !== "silent" + && options.errorHandling !== "throw") { + throw new Error("Invalid options passed to createRegistry. Prop errorHandling should be [\"log\" | \"silent\" | \"throw\" | (err) => void], but " + typeof options.errorHandling + " was passed"); + } + var _userErrorHandler = options && typeof options.errorHandling === "function" && options.errorHandling; + var callbacks = {}; + function add(key, callback, replayArgumentsArr) { + var callbacksForKey = callbacks[key]; + if (!callbacksForKey) { + callbacksForKey = []; + callbacks[key] = callbacksForKey; + } + callbacksForKey.push(callback); + if (replayArgumentsArr) { + setTimeout(function () { + replayArgumentsArr.forEach(function (replayArgument) { + var _a; + if ((_a = callbacks[key]) === null || _a === void 0 ? void 0 : _a.includes(callback)) { + try { + if (Array.isArray(replayArgument)) { + callback.apply(undefined, replayArgument); + } + else { + callback.apply(undefined, [replayArgument]); + } + } + catch (err) { + _handleError(err, key); + } + } + }); + }, 0); + } + return function () { + var allForKey = callbacks[key]; + if (!allForKey) { + return; + } + allForKey = allForKey.reduce(function (acc, element, index) { + if (!(element === callback && acc.length === index)) { + acc.push(element); + } + return acc; + }, []); + if (allForKey.length === 0) { + delete callbacks[key]; + } + else { + callbacks[key] = allForKey; + } + }; + } + function execute(key) { + var argumentsArr = []; + for (var _i = 1; _i < arguments.length; _i++) { + argumentsArr[_i - 1] = arguments[_i]; + } + var callbacksForKey = callbacks[key]; + if (!callbacksForKey || callbacksForKey.length === 0) { + return []; + } + var results = []; + callbacksForKey.forEach(function (callback) { + try { + var result = callback.apply(undefined, argumentsArr); + results.push(result); + } + catch (err) { + results.push(undefined); + _handleError(err, key); + } + }); + return results; + } + function _handleError(exceptionArtifact, key) { + var errParam = exceptionArtifact instanceof Error ? exceptionArtifact : new Error(exceptionArtifact); + if (_userErrorHandler) { + _userErrorHandler(errParam); + return; + } + var msg = "[ERROR] callback-registry: User callback for key \"" + key + "\" failed: " + errParam.stack; + if (options) { + switch (options.errorHandling) { + case "log": + return console.error(msg); + case "silent": + return; + case "throw": + throw new Error(msg); + } + } + console.error(msg); + } + function clear() { + callbacks = {}; + } + function clearKey(key) { + var callbacksForKey = callbacks[key]; + if (!callbacksForKey) { + return; + } + delete callbacks[key]; + } + return { + add: add, + execute: execute, + clear: clear, + clearKey: clearKey + }; + } + createRegistry.default = createRegistry; + var lib = createRegistry; + + + var CallbackRegistryFactory = /*@__PURE__*/getDefaultExportFromCjs(lib); + + function objectValues(source) { + if (!source) { + return []; + } + return Object.keys(source).map((key) => source[key]); + } + function objectClone(obj) { + let result; + try { + result = JSON.parse(JSON.stringify(obj || {})); + } + catch (error) { + result = {}; + } + return result; + } + function validate(callback, configuration) { + if (configuration.throwErrors) { + if (typeof callback !== "function") { + throw new Error("Please provide the callback as a function!"); + } + } + } + + const INTEROP_METHOD_RESPONSE_TIMEOUT_MS = 90000; + const INTEROP_METHOD_WAIT_TIMEOUT_MS = 90000; + + let urlAlphabet = + 'useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict'; + let nanoid = (size = 21) => { + let id = ''; + let i = size | 0; + while (i--) { + id += urlAlphabet[(Math.random() * 64) | 0]; + } + return id + }; + + class Utils { + static getGDMajorVersion() { + if (typeof window === "undefined") { + return -1; + } + if (!window.glueDesktop) { + return -1; + } + if (!window.glueDesktop.version) { + return -1; + } + const parsed = window.glueDesktop.version.split("."); + const major = Number(parsed[0]); + return isNaN(major) ? -1 : major; + } + static typedError(error) { + let err; + if (error instanceof Error) { + err = error; + } + else if (typeof error === "string") { + err = new Error(error); + } + else if ("message" in error && typeof error.message === "string" && error.message.length > 0) { + err = new Error(error.message); + } + else if ("returned" in error + && typeof error.returned === "object" + && "errorMsg" in error.returned + && typeof error.returned.errorMsg === "string" + && error.returned.errorMsg.length > 0) { + err = new Error(error.returned.errorMsg); + } + else { + err = new Error("Unknown error"); + } + return err; + } + static async callbackifyPromise(action, successCallback, errorCallback) { + const success = (result) => { + if (typeof successCallback === "function") { + successCallback(result); + } + return Promise.resolve(result); + }; + const fail = (error) => { + const err = Utils.typedError(error); + if (typeof errorCallback === "function") { + errorCallback(err.message); + return; + } + return Promise.reject(err); + }; + try { + const result = await action(); + return success(result); + } + catch (error) { + return fail(error); + } + } + static getMonitor(bounds, displays) { + const monitorsSortedByOverlap = displays.map((m) => { + const { left, top, workingAreaWidth: width, workingAreaHeight: height } = m; + const overlap = this.calculateTotalOverlap({ left, top, width, height }, bounds); + return { + monitor: m, + totalOverlap: overlap + }; + }).sort((a, b) => b.totalOverlap - a.totalOverlap); + return monitorsSortedByOverlap[0].monitor; + } + static getDisplayCenterOfScreen(a, currentDisplay, primaryDisplay) { + const physicalWidth = a.width / currentDisplay.scaleFactor; + const physicalHeight = a.height / currentDisplay.scaleFactor; + const physicalDisplayLeft = currentDisplay.workArea.left / primaryDisplay.scaleFactor; + const physicalDisplayTop = currentDisplay.workArea.top / primaryDisplay.scaleFactor; + const physicalDisplayWidth = currentDisplay.workArea.width / currentDisplay.scaleFactor; + const physicalDisplayHeight = currentDisplay.workArea.height / currentDisplay.scaleFactor; + const physicalHOffset = Math.max((physicalDisplayWidth - physicalWidth) / 2, 0); + const physicalVOffset = Math.max((physicalDisplayHeight - physicalHeight) / 2, 0); + const centeredPhysicalLeft = Math.floor(physicalDisplayLeft + physicalHOffset); + const centeredPhysicalTop = Math.floor(physicalDisplayTop + physicalVOffset); + const left = centeredPhysicalLeft * primaryDisplay.scaleFactor; + const top = centeredPhysicalTop * primaryDisplay.scaleFactor; + return { + left, + top, + width: a.width, + height: a.height + }; + } + static isNode() { + if (typeof Utils._isNode !== "undefined") { + return Utils._isNode; + } + if (typeof window !== "undefined") { + Utils._isNode = false; + return false; + } + try { + Utils._isNode = Object.prototype.toString.call(global.process) === "[object process]"; + } + catch (e) { + Utils._isNode = false; + } + return Utils._isNode; + } + static generateId() { + return nanoid(10); + } + static isPromise(value) { + return Boolean(value && typeof value.then === 'function'); + } + static isAsyncFunction(value) { + return value && {}.toString.call(value) === '[object AsyncFunction]'; + } + static isNullOrUndefined(value) { + return value === null || value === undefined; + } + static calculateTotalOverlap(r1, r2) { + const r1x = r1.left; + const r1y = r1.top; + const r1xMax = r1x + r1.width; + const r1yMax = r1y + r1.height; + const r2x = r2.left; + const r2y = r2.top; + const r2xMax = r2x + r2.width; + const r2yMax = r2y + r2.height; + const xOverlap = Math.max(0, Math.min(r1xMax, r2xMax) - Math.max(r1x, r2x)); + const yOverlap = Math.max(0, Math.min(r1yMax, r2yMax) - Math.max(r1y, r2y)); + return xOverlap * yOverlap; + } + } + + class ApplicationImpl { + constructor(_appManager, _name, _agm, _logger, _configuration) { + this._appManager = _appManager; + this._name = _name; + this._agm = _agm; + this._logger = _logger; + this._configuration = _configuration; + this._registry = CallbackRegistryFactory(); + _appManager.onInstanceStarted((instance) => { + if (instance.application && instance.application.name !== this._name) { + return; + } + this._registry.execute("instanceStarted", instance); + }); + _appManager.onInstanceStopped((instance) => { + if (instance.application && instance.application.name !== this._name) { + return; + } + this._registry.execute("instanceStopped", instance); + }); + _appManager.onAppRemoved((app) => { + if (app.name !== this._name) { + return; + } + this._registry.execute("appRemoved", app); + }); + _appManager.onAppChanged((app) => { + if (app.name !== this._name) { + return; + } + this._registry.execute("appChanged", app); + }); + _appManager.onAppAvailable((app) => { + if (app.name !== this._name) { + return; + } + this._props.IsReady = true; + this._registry.execute("appAvailable", app); + }); + _appManager.onAppUnavailable((app) => { + if (app.name !== this._name) { + return; + } + this._props.IsReady = false; + this._registry.execute("appUnavailable", app); + }); + } + get name() { return this._name; } + get title() { return this._props.Title; } + get version() { return this._props.Version; } + get autoStart() { return this._props.AutoStart; } + get isShell() { return this._props.IsShell; } + get caption() { return this._props.Caption; } + get hidden() { return this._props.IsHidden; } + get container() { return this._props.ApplicationName; } + get activityType() { return this._props.ActivityType; } + get activityWindowType() { return this._props.ActivityWindowType; } + get windowSettings() { + if (!this._props.Arguments) { + return {}; + } + return objectClone(this._props.Arguments); + } + get allowMultiple() { return this._props.AllowMultiple; } + get available() { return this._props.IsReady || true; } + get icon() { return this._props.Icon; } + get iconURL() { return this._props.IconUrl; } + get sortOrder() { return this._props.SortOrder; } + get userProperties() { + if (!this._props.UserProperties) { + return {}; + } + return objectClone(this._props.UserProperties); + } + get keywords() { + if (!this._props.Keywords) { + return []; + } + return this._props.Keywords; + } + get isActivity() { + return this._props.ActivityType !== undefined && this._props.ActivityType !== ""; + } + get configuration() { + return { + autoStart: this._props.AutoStart, + caption: this._props.Caption, + hidden: this._props.IsHidden, + container: this._props.ApplicationName, + activityType: this._props.ActivityType, + allowMultiple: this._props.AllowMultiple + }; + } + get instances() { + return this._appManager.instances().filter((instance) => instance.application.name === this._name); + } + get type() { + return this._props.Type; + } + get mode() { + if (!this._props) { + return "unknown"; + } + if (this._props.Mode && typeof this._props.Mode === "string") { + return this._props.Mode.toLowerCase(); + } + if (this.isActivity) { + return "unknown"; + } + if (this._props.Arguments && this._props.Arguments.mode && typeof this._props.Arguments.mode === "string") { + return this._props.Arguments.mode.toLowerCase(); + } + let styleAttributes = this._props.WindowStyleAttributes; + if (styleAttributes) { + styleAttributes = styleAttributes.split(" ").join(""); + const searchFor = "mode:\""; + const modeIndex = styleAttributes.indexOf(searchFor); + if (modeIndex !== -1) { + const startModeIndex = modeIndex + searchFor.length; + const stopModeIndex = styleAttributes.indexOf("\"", startModeIndex); + const style = styleAttributes.substr(startModeIndex, stopModeIndex - startModeIndex); + if (style && typeof style === "string") { + return style.toLowerCase(); + } + } + } + return "flat"; + } + async getConfiguration() { + const result = await this._agm.invoke(GetApplicationsMethodName, { v2: { apps: [this._name] } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + const config = result.returned.applications[0]; + return config; + } + updateFromProps(props) { + if (!this._props) { + this._props = { Name: props.Name }; + } + Object.keys(props).forEach((key) => { + this._props[key] = props[key]; + }); + } + start(context, options) { + return new Promise(async (resolve, reject) => { + var _a, _b, _c, _d; + if (isUndefinedOrNull(context)) { + context = {}; + } + else if (((_a = this._configuration()) === null || _a === void 0 ? void 0 : _a.throwErrors) && typeof context !== "object" || Array.isArray(context)) { + return reject(new Error(`Invalid "context" parameter - must be an object.`)); + } + if (isUndefinedOrNull(options)) { + options = {}; + } + else if (((_b = this._configuration()) === null || _b === void 0 ? void 0 : _b.throwErrors) && typeof options !== "object") { + return reject(new Error(`Invalid "options" parameter - must be an object.`)); + } + const name = this._name; + let waitForAGMInstance = (_d = ((_c = options.awaitInterop) !== null && _c !== void 0 ? _c : options.waitForAGMReady)) !== null && _d !== void 0 ? _d : true; + let startTimeout = 60000; + if (typeof options.timeout === "number") { + startTimeout = options.timeout * 1000; + } + if (options.relativeTo !== undefined && typeof options.relativeTo !== "string") { + options.relativeTo = options.relativeTo.id || ""; + } + const waitForApplicationInstance = (id) => { + let unsub; + const timeout = setTimeout(() => { + if (unsub) { + unsub(); + } + const errMsg = `timed out while waiting for instance id ${id} for app ${this.name}`; + this._logger.error(errMsg); + reject(new Error(errMsg)); + }, startTimeout); + const waitFunc = (i) => { + if (i.id !== id) { + return; + } + if (unsub) { + unsub(); + unsub = undefined; + } + clearTimeout(timeout); + resolve(i); + }; + if (waitForAGMInstance) { + const instance = this._appManager.instances().find((i) => i.id === id); + if (instance) { + unsub = instance.onAgmReady(waitFunc); + } + else { + unsub = this._appManager.onInstanceAgmServerReady(waitFunc); + } + } + else { + unsub = this._appManager.onInstanceStarted(waitFunc); + } + }; + try { + this._logger.trace(`starting application ${name} with options: ${JSON.stringify(options)}`); + const result = await this._agm.invoke(StartApplicationMethodName, { + Name: name, + Context: context, + Options: options + }, "best", { + methodResponseTimeoutMs: startTimeout, + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + const acsResult = result.returned; + if (typeof acsResult.timeout !== "undefined" && typeof options.timeout === "undefined") { + startTimeout = acsResult.timeout * 1000; + } + if (typeof acsResult.waitForInterop !== "undefined" && (typeof options.waitForAGMReady === "undefined" && typeof options.awaitInterop === "undefined")) { + waitForAGMInstance = acsResult.waitForInterop; + } + if (acsResult && acsResult.Id) { + if (this._appManager.mode === "startOnly") { + const instance = this._appManager.handleInstanceStarted({ + ActivityId: undefined, + IsActivityOwner: undefined, + Context: undefined, + Title: undefined, + AgmServers: undefined, + Id: acsResult.Id, + Name: acsResult.Name, + }); + resolve(instance); + } + else { + waitForApplicationInstance(acsResult.Id); + } + } + else { + resolve(undefined); + } + } + catch (error) { + const err = Utils.typedError(error); + reject(err); + } + }); + } + onInstanceStarted(callback) { + validate(callback, this._configuration()); + return this._registry.add("instanceStarted", callback); + } + onInstanceStopped(callback) { + validate(callback, this._configuration()); + return this._registry.add("instanceStopped", callback); + } + onAvailable(callback) { + validate(callback, this._configuration()); + if (this._props.IsReady) { + setTimeout(() => { + this._registry.execute("appAvailable", this); + }, 0); + } + return this._registry.add("appAvailable", callback); + } + onUnavailable(callback) { + validate(callback, this._configuration()); + if (this._props.IsReady === false) { + setTimeout(() => { + this._registry.execute("appUnavailable", this); + }, 0); + } + return this._registry.add("appUnavailable", callback); + } + onChanged(callback) { + validate(callback, this._configuration()); + this._registry.add("appChanged", callback); + } + onRemoved(callback) { + validate(callback, this._configuration()); + this._registry.add("appRemoved", callback); + } + } + + class InstanceImpl { + constructor(_id, _appName, _appManager, _agm, _activities, _windows, _logger, startFailed, _configuration) { + this._id = _id; + this._appName = _appName; + this._appManager = _appManager; + this._agm = _agm; + this._activities = _activities; + this._windows = _windows; + this._logger = _logger; + this._configuration = _configuration; + this._registry = CallbackRegistryFactory(); + if (startFailed) { + return; + } + this._unsubscribeInstanceStopped = this._appManager.onInstanceStopped((instance) => { + if (instance.id !== this._id) { + return; + } + this._registry.execute("stopped", instance); + }); + this._unsubscribeInstanceAgmServerReady = this._appManager.onInstanceAgmServerReady((instance) => { + if (instance.id !== this._id) { + return; + } + this._registry.execute("agmReady", instance); + }); + } + get id() { return this._id; } + get application() { return this._appManager.application(this._appName); } + get activity() { + if (!this._activities) { + throw new Error("This method requires glue.activities library to be enabled."); + } + return this._activities.all.instances.get() + .filter((activityInstance) => activityInstance.id === this._activityId)[0]; + } + get isActivityOwner() { return this._isActivityOwner; } + get activityInstances() { + return this._appManager.instances().filter((i) => i.application.type !== "activity" && + i.activityId && + i.activityId === this._activityId); + } + get activityOwnerInstance() { + if (!this._activityId) { + return undefined; + } + return this.activityInstances.filter((inst) => inst === null || inst === void 0 ? void 0 : inst.isActivityOwner)[0]; + } + get window() { + if (!this._windows) { + throw new Error("This method requires glue.windows library to be enabled."); + } + let win = this._windows.list().find((w) => w.id === this._id); + if (!win && this._activities && this.activity && this.activityOwnerInstance) { + win = this.activityOwnerInstance.window; + } + return win; + } + get context() { + var _a, _b, _c; + return (_c = (_a = this._startUpContext) !== null && _a !== void 0 ? _a : (_b = this.window) === null || _b === void 0 ? void 0 : _b.context) !== null && _c !== void 0 ? _c : {}; + } + get title() { return this._title; } + get isActivityInstance() { return this._isActivityInstance; } + get activityId() { return this._activityId; } + get inActivity() { return this._inActivity; } + get isSingleWindowApp() { return !this._inActivity; } + get agm() { + return this._agmInstance; + } + get interopInstance() { + return this._agmInstance; + } + onInteropReady(callback) { + validate(callback, this._configuration()); + if (this._agmInstance) { + setTimeout(() => { + this._registry.execute("agmReady", this); + }, 0); + } + return this._registry.add("agmReady", callback); + } + onAgmReady(callback) { + return this.onInteropReady(callback); + } + onStopped(callback) { + validate(callback, this._configuration()); + return this._registry.add("stopped", callback); + } + getWindow() { + return new Promise((resolve, reject) => { + const result = this.window; + if (result) { + resolve(result); + return; + } + const done = (error, window) => { + if (error) { + reject(error); + } + if (window) { + resolve(window); + } + setTimeout(() => { + clearTimeout(timeout); + unsub(); + }, 0); + }; + this._logger.trace(`waiting for window with id ${this._id} to appear`); + const timeoutInSeconds = 60; + const timeout = setTimeout(() => { + this._logger.trace(`window with id ${this._id} did not appear in ${timeoutInSeconds} sec`); + done(new Error(`can not find a window with id ${this._id}`)); + }, timeoutInSeconds * 1000); + const unsub = this._windows.onWindowAdded((w) => { + if (w.id === this._id) { + this._logger.trace(`window with id ${this._id} appeared`); + done(undefined, w); + } + }); + }); + } + updateFromProps(props) { + this._startUpContext = props.Context; + this._title = props.Title; + this._isActivityInstance = false; + if (props.ActivityId && props.ActivityId !== "") { + this._activityId = props.ActivityId; + this._isActivityInstance = true; + } + this._isActivityOwner = props.IsActivityOwner; + if (!this._activityId && this._startUpContext && this._startUpContext.activityId) { + this._activityId = this._startUpContext.activityId; + } + this._inActivity = Boolean(this._activityId); + this.updateAgmInstanceFromProps(props); + } + updateAgmInstanceFromProps(props) { + if (!props.AgmServers) { + return; + } + const agmInstances = props.AgmServers; + if (agmInstances && agmInstances.length > 0 && !isUndefinedOrNull(agmInstances[0])) { + this._agmInstance = agmInstances[0]; + } + } + stop() { + return new Promise((resolve, reject) => { + let idToResolve = this._id; + if (this.isActivityOwner) { + idToResolve = this.activityId; + } + const unsubscribe = this._appManager.onInstanceStopped((instance) => { + if (instance.id === idToResolve) { + this._logger.trace(`instance with id ${idToResolve} stopped`); + unsubscribe(); + resolve(); + } + }); + this._logger.trace(`stopping instance with id ${this._id}`); + this._agm.invoke(StopApplicationMethodName, { + Name: this._appName, + Id: this._id + }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }) + .then(() => { + if (this._appManager.mode === "startOnly") { + this._appManager.handleInstanceStopped({ + Name: this._appName, + Id: this.id + }); + resolve(); + } + }) + .catch((err) => reject(err)); + }); + } + activate() { + return this._agm.invoke(ActivateApplicationMethodName, { Name: this._appName, Id: this._id }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + done() { + this._registry.clear(); + this._unsubscribeInstanceAgmServerReady(); + this._unsubscribeInstanceStopped(); + } + getContext() { + return Promise.resolve(this.context); + } + async startedBy() { + const result = await this._agm.invoke(ACSExecute, { command: "getStartedBy", Name: this._appName, Id: this._id }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return result.returned; + } + } + + class AppManagerImpl { + constructor(mode, _agm, _activities, _windows, _logger, _gdMajorVersion, _configuration) { + this.mode = mode; + this._agm = _agm; + this._activities = _activities; + this._windows = _windows; + this._logger = _logger; + this._gdMajorVersion = _gdMajorVersion; + this._configuration = _configuration; + this._apps = {}; + this._instances = []; + this._registry = CallbackRegistryFactory(); + this.getConfigurations = async (apps) => { + const args = { + v2: { + apps: undefined + } + }; + if (Array.isArray(apps)) { + args.v2 = { + apps + }; + } + const result = await this._agm.invoke(GetApplicationsMethodName, args, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return result.returned.applications; + }; + this.application = (name) => { + var _a; + if (((_a = this._configuration()) === null || _a === void 0 ? void 0 : _a.throwErrors) && typeof name !== "string" || isNullOrWhiteSpace(name)) { + throw new Error(`"name" must be string`); + } + return this._apps[name]; + }; + this.applications = () => { + return Object.keys(this._apps).map((k) => this._apps[k]); + }; + this.instances = () => { + return this._instances.map((i) => i); + }; + this.getMyInstance = () => { + const glue42gd = typeof window !== "undefined" && window.glue42gd; + if (glue42gd) { + if (this._gdMajorVersion >= 3) { + const instanceId = glue42gd.appInstanceId; + return this._instances.find((i) => i.id === instanceId); + } + } + else { + const instanceId = this._agm.instance.instance; + return this._instances.find((i) => i.id === instanceId); + } + return undefined; + }; + this.getMyApplication = () => { + var _a; + if (this._agm.instance) { + return (_a = this.application(this._agm.instance.applicationName)) !== null && _a !== void 0 ? _a : this.application(this._agm.instance.application); + } + }; + this.handleSnapshotAppsAdded = (newApps) => { + const currentApps = this.applications(); + if (currentApps.length > 0) { + currentApps.forEach((item) => { + const name = item.name; + const alreadyExists = newApps.find((i) => i.Name === item.name); + if (!alreadyExists) { + this.handleAppRemoved({ Name: name }); + } + }); + } + newApps.forEach((item) => { + const alreadyExists = currentApps.find((i) => i.name === item.Name); + if (!alreadyExists) { + this.handleAppAdded(item); + } + }); + }; + this.handleSnapshotInstanceStarted = (newInstances) => { + const currentInstances = this.instances(); + if (currentInstances.length > 0) { + currentInstances.forEach((item) => { + const id = item.id; + const alreadyExists = newInstances.find((i) => i.Id === id); + if (!alreadyExists) { + this.handleInstanceStopped({ Name: item.application.name, Id: id }); + } + }); + } + newInstances.forEach((item) => { + const alreadyExists = currentInstances.find((i) => i.id === item.Id); + if (!alreadyExists) { + this.handleInstanceStarted(item); + } + }); + }; + this.handleAppAdded = (props) => { + const id = this._getAppId(props); + this._logger.trace(`adding app ${id}`); + this._apps[id] = new ApplicationImpl(this, id, this._agm, this._logger, this._configuration); + const app = this._updateAppFromProps(props); + this._registry.execute("appAdded", app); + this._registry.execute("appAvailable", app); + }; + this.handleAppUpdated = (props) => { + const app = this._updateAppFromProps(props); + this._registry.execute("appChanged", app); + }; + this.handleAppRemoved = (props) => { + const id = this._getAppId(props); + this._logger.trace(`removing app ${id}`); + const app = this.application(id); + this._instances = this._instances.filter((i) => i.application.name !== app.name); + delete this._apps[id]; + this._registry.execute("appRemoved", app); + }; + this.handleAppReady = (props) => { + const id = this._getAppId(props); + const app = this._getAppOrThrow(id); + app.updateFromProps(props); + if (app.available) { + this._registry.execute("appAvailable", app); + } + else { + this._registry.execute("appUnavailable", app); + } + }; + this.handleInstanceStarted = (props) => { + this._logger.trace(`started app ${props.Name} ${props.Id}`); + const id = this._getInstanceId(props); + const appName = this._getInstanceAppName(props); + const instance = new InstanceImpl(id, appName, this, this._agm, this._activities, this._windows, this._logger, false, this._configuration); + this._updateInstanceFromProps(instance, props); + this._instances.push(instance); + this._registry.execute("instanceStarted", instance); + return instance; + }; + this.handleInstanceStopped = (props) => { + this._logger.trace(`instance stopped ${props.Name} ${props.Id}`); + const id = this._getInstanceId(props); + const appName = this._getInstanceAppName(props); + const instance = this._getInstanceOrThrow(id, appName); + this._instances = this._instances.filter((i) => !this._matchInstance(i, id, appName)); + this._registry.execute("instanceStopped", instance); + instance.done(); + }; + this.handleInstanceAgmServerReady = (props) => { + this._logger.trace(`instance interop server ready ${props.Name} ${props.Id}`); + const id = this._getInstanceId(props); + const appName = this._getInstanceAppName(props); + const instance = this._getInstanceOrThrow(id, appName); + instance.updateAgmInstanceFromProps(props); + this._registry.execute("instanceAgmServerReady", instance); + }; + this.handleInstanceStartFailed = (props) => { + const id = this._getInstanceId(props); + const appName = this._getInstanceAppName(props); + const startFailed = true; + const instance = new InstanceImpl(id, appName, undefined, undefined, undefined, undefined, this._logger, startFailed, this._configuration); + this._updateInstanceFromProps(instance, props); + this._registry.execute("instanceStartFailed", instance); + }; + this.handleInstanceUpdated = (props) => { + const id = this._getInstanceId(props); + const app = this._getInstanceAppName(props); + const instance = this._getInstanceOrThrow(id, app); + this._updateInstanceFromProps(instance, props); + }; + this.onInstanceStarted = (callback) => { + validate(callback, this._configuration()); + return this._registry.add("instanceStarted", callback, this._instances); + }; + this.onInstanceStartFailed = (callback) => { + validate(callback, this._configuration()); + return this._registry.add("instanceStartFailed", callback); + }; + this.onInstanceStopped = (callback) => { + validate(callback, this._configuration()); + return this._registry.add("instanceStopped", callback); + }; + this.onInstanceUpdated = (callback) => { + validate(callback, this._configuration()); + return this._registry.add("instanceChanged", callback); + }; + this.onInstanceAgmServerReady = (callback) => { + validate(callback, this._configuration()); + return this._registry.add("instanceAgmServerReady", callback); + }; + this.onAppAdded = (callback) => { + validate(callback, this._configuration()); + return this._registry.add("appAdded", callback, Object.values(this._apps)); + }; + this.onAppRemoved = (callback) => { + validate(callback, this._configuration()); + return this._registry.add("appRemoved", callback); + }; + this.onAppAvailable = (callback) => { + validate(callback, this._configuration()); + return this._registry.add("appAvailable", callback); + }; + this.onAppUnavailable = (callback) => { + validate(callback, this._configuration()); + return this._registry.add("appUnavailable", callback); + }; + this.onAppChanged = (callback) => { + validate(callback, this._configuration()); + return this._registry.add("appChanged", callback); + }; + } + _getAppOrThrow(id) { + const result = this.application(id); + if (!result) { + throw Error(`app with id ${id} not found`); + } + return result; + } + _getAppId(props) { + return props.Name; + } + _matchInstance(instance, id, appName) { + return instance.id === id && instance.application.name === appName; + } + _getInstanceByIdAndName(id, appName) { + return this._instances.filter((i) => this._matchInstance(i, id, appName))[0]; + } + _getInstanceOrThrow(id, appName) { + const result = this._getInstanceByIdAndName(id, appName); + if (!result) { + throw Error(`instance with id ${id} not found`); + } + return result; + } + _getInstanceId(props) { + return props.Id; + } + _getInstanceAppName(props) { + return props.Name; + } + _updateAppFromProps(props) { + const id = this._getAppId(props); + this._logger.trace(`updating app with + ${id}, ${JSON.stringify(props)}`); + const app = this._getAppOrThrow(id); + app.updateFromProps(props); + return app; + } + _updateInstanceFromProps(instance, props) { + this._logger.trace("updating instance with " + this._getInstanceId(props) + " for app " + this._getInstanceAppName(props)); + instance.updateFromProps(props); + } + } + + function promisify(promise, successCallback, errorCallback) { + const isFunction = (arg) => { + return !!(arg && arg.constructor && arg.call && arg.apply); + }; + if (!isFunction(successCallback) && !isFunction(errorCallback)) { + return promise; + } + if (!isFunction(successCallback)) { + successCallback = () => { + }; + } + else if (!isFunction(errorCallback)) { + errorCallback = () => { + }; + } + return promise.then(successCallback, errorCallback); + } + class EntitlementsImpl { + constructor(_agm) { + this._agm = _agm; + this._registry = CallbackRegistryFactory(); + this._isMethodRegistered = false; + this.handleBranchModified = (branch) => { + this._registry.execute("branchChanged", branch); + }; + this.handleBranchesModified = (branches) => { + this._registry.execute("branchesChanged", branches); + }; + this.getRegion = (success, error) => { + return promisify(this._agmInvoke(GetConfigurationRegionMethodName, (e) => e.returned.Region), success, error); + }; + this.getBranches = (success, error) => { + const promise = this._agmInvoke(GetBranchesMethodName, (e) => { + const obj = e.returned.Branches; + return Object.keys(obj).map((key) => obj[key]); + }); + return promisify(promise, success, error); + }; + this.getCurrentBranch = (success, error) => { + const promise = this._agmInvoke(GetCurrentBranchMethodName, (e) => e.returned.Branch, undefined); + return promisify(promise, success, error); + }; + this.setRegion = (region, success, error) => { + const promise = this._agmInvoke(SetConfigurationRegionMethodName, (e) => e.returned.ResultMessage, { Region: region }); + return promisify(promise, success, error); + }; + this.setCurrentBranch = (branch, success, error) => { + const promise = this._agmInvoke(SetCurrentBranchMethodName, (e) => e.returned.ResultMessage, { Branch: branch }); + return promisify(promise, success, error); + }; + this.currentUser = (success, error) => { + const promise = this._agmInvoke(GetUserMethodName); + return promisify(promise, success, error); + }; + this.getFunctionalEntitlement = (funct, success, error) => { + const promise = this._agmInvoke(GetFunctionalEntitlementMethodName, (e) => e.returned.Entitlement, { Function: funct }); + return promisify(promise, success, error); + }; + this.getFunctionalEntitlementBranch = (funct, branch, success, error) => { + const promise = this._agmInvoke(GetFunctionalEntitlementMethodName, (e) => e.returned.Entitlement, { Function: funct, Branch: branch }); + return promisify(promise, success, error); + }; + this.canI = (func, success, error) => { + const promise = this._agmInvoke(CanIMethodName, (e) => e.returned.Result, { Function: func }); + return promisify(promise, success, error); + }; + this.canIBranch = (func, branch, success, error) => { + const promise = this._agmInvoke(CanIMethodName, (e) => e.returned.Result, { Function: func, Branch: branch }); + return promisify(promise, success, error); + }; + this.onBranchesChanged = (callback) => { + return this._registry.add("branchesChanged", callback); + }; + this.onBranchChanged = (callback) => { + return this._registry.add("branchChanged", callback); + }; + this.exit = (options) => { + return this._agmInvoke(ShutdownMethodName, null, options); + }; + this.onShuttingDown = (callback) => { + this.registerMethod(); + return this._registry.add("onShuttingDown", callback); + }; + this.restart = (options) => { + return this._agmInvoke(RestartMethodName, null, options); + }; + this._agmInvoke = (method, transformFunction, args) => { + args = args || {}; + return new Promise((resolve, reject) => { + const errHandler = (error) => reject(error); + this._agm.invoke(method, args, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }) + .then((result) => { + if (!transformFunction) { + transformFunction = (d) => d.returned; + } + resolve(transformFunction(result)); + }) + .catch(errHandler); + }); + }; + } + registerMethod() { + if (!this._isMethodRegistered) { + this._agm.register(OnGDShutdownMethodName, async (args) => { + try { + const results = await Promise.all(this._registry.execute("onShuttingDown", args)); + const prevent = results.some((r) => r.prevent); + return { prevent }; + } + catch (error) { + } + }); + this._isMethodRegistered = true; + } + } + } + + function snapshot(interop, appManager) { + return new Promise((resolve, reject) => { + interop.invoke(GetApplicationsMethodName, { skipIcon: true }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }) + .then((response) => { + var _a; + const data = response.returned; + const configuration = (_a = response.returned.configuration) !== null && _a !== void 0 ? _a : {}; + if (!data) { + resolve(configuration); + } + const applications = data.applications; + if (!applications) { + resolve(configuration); + } + objectValues(applications).map((item) => appManager.handleAppAdded(item)); + resolve(configuration); + }) + .catch((err) => reject(new Error(`Error getting application snapshot: ${err.message}`))); + }); + } + + const OnBranchChangedEvent = "OnBranchChanged"; + const OnBranchesModifiedEvent = "OnBranchesModified"; + const OnApplicationAddedEvent = "OnApplicationAdded"; + const OnApplicationRemovedEvent = "OnApplicationRemoved"; + const OnApplicationChangedEvent = "OnApplicationChanged"; + const OnApplicationReadyEvent = "OnApplicationReady"; + const OnApplicationStartedEvent = "OnApplicationStarted"; + const OnApplicationAgmServerReadyEvent = "OnApplicationAgmServerReady"; + const OnApplicationUpdatedEvent = "OnApplicationUpdated"; + const OnApplicationStoppedEvent = "OnApplicationStopped"; + const OnApplicationStartFailedEvent = "OnApplicationStartFailed"; + + function createDataSubscription(agm, applications, entitlements, skipIcons) { + let subscription; + let initiated = false; + const start = () => { + let resolveFunc; + let rejectFunc; + const resultPromise = new Promise((resolve, reject) => { + resolveFunc = resolve; + rejectFunc = reject; + }); + agm.subscribe(OnEventMethodName, { arguments: { skipIcon: skipIcons }, waitTimeoutMs: 10000 }) + .then((s) => { + subscription = s; + subscription.onData((streamData) => { + var _a; + const events = streamData.data; + const configuration = (_a = events.configuration) !== null && _a !== void 0 ? _a : {}; + const onApplicationAddedEventArgs = objectValues(events[OnApplicationAddedEvent]); + if (streamData.data.isSnapshot) { + applications.handleSnapshotAppsAdded(onApplicationAddedEventArgs); + } + else { + onApplicationAddedEventArgs.forEach((item) => applications.handleAppAdded(item)); + } + objectValues(events[OnApplicationChangedEvent]) + .forEach((item) => applications.handleAppUpdated(item)); + objectValues(events[OnApplicationRemovedEvent]) + .forEach((item) => applications.handleAppRemoved(item)); + objectValues(events[OnApplicationReadyEvent]) + .forEach((item) => applications.handleAppReady(item)); + const onApplicationStartedEventArgs = objectValues(events[OnApplicationStartedEvent]); + if (streamData.data.isSnapshot) { + applications.handleSnapshotInstanceStarted(onApplicationStartedEventArgs); + } + else { + onApplicationStartedEventArgs.forEach((item) => applications.handleInstanceStarted(item)); + } + objectValues(events[OnApplicationStartFailedEvent]) + .forEach((item) => applications.handleInstanceStartFailed(item)); + objectValues(events[OnApplicationStoppedEvent]) + .forEach((item) => applications.handleInstanceStopped(item)); + objectValues(events[OnApplicationUpdatedEvent]) + .forEach((item) => applications.handleInstanceUpdated(item)); + objectValues(events[OnApplicationAgmServerReadyEvent]) + .forEach((item) => applications.handleInstanceAgmServerReady(item)); + objectValues(events[OnBranchChangedEvent]) + .forEach((item) => entitlements.handleBranchModified(item)); + objectValues(events[OnBranchesModifiedEvent]) + .forEach((item) => entitlements.handleBranchesModified(item)); + if (!initiated) { + initiated = true; + const hasMyAppInSnapShot = onApplicationAddedEventArgs.some((a) => a.Name === agm.instance.application); + const hasMyInstanceInSnapShot = onApplicationStartedEventArgs.some((i) => i.Id === agm.instance.instance); + if (hasMyAppInSnapShot) { + if (hasMyInstanceInSnapShot) { + resolveFunc(configuration); + } + else { + const un = applications.onInstanceStarted((i) => { + if (i.id === agm.instance.instance) { + un(); + resolveFunc(configuration); + } + }); + } + } + else { + resolveFunc(configuration); + } + } + }); + subscription.onFailed((err) => rejectFunc(err)); + }) + .catch((err) => { var _a; return rejectFunc(`Error subscribing for ${OnEventMethodName} stream. Err: ${(_a = err.message) !== null && _a !== void 0 ? _a : JSON.stringify(err)}`); }); + return resultPromise; + }; + const stop = () => { + if (subscription) { + subscription.close(); + } + }; + return { + start, + stop + }; + } + + const InMemoryStoreCommandMethodName = "T42.ACS.InMemoryStoreCommand"; + class InMemoryStore { + constructor(interop) { + this.interop = interop; + } + import(apps, mode) { + if (!apps || !Array.isArray(apps)) { + return Promise.reject(new Error("invalid apps argument - should be an array of application definitions")); + } + if (mode && mode !== "replace" && mode !== "merge") { + return Promise.reject(new Error("invalid mode argument - should be 'replace' or 'merge'")); + } + mode = mode !== null && mode !== void 0 ? mode : "replace"; + const command = { + command: "import", + args: { + apps, + mode + } + }; + return this.interop.invoke(InMemoryStoreCommandMethodName, command, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }) + .then((r) => r.returned); + } + export() { + return this.interop.invoke(InMemoryStoreCommandMethodName, { command: "export" }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }) + .then((r) => r.returned.apps); + } + remove(app) { + if (!app || typeof app !== "string") { + return Promise.reject(new Error("invalid app name, should be a string value")); + } + const command = { + command: "remove", + args: { + apps: [app] + } + }; + return this.interop.invoke(InMemoryStoreCommandMethodName, command, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }).then((r) => r.returned); + } + clear() { + const command = { + command: "clear" + }; + return this.interop.invoke(InMemoryStoreCommandMethodName, command, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }).then((r) => r.returned); + } + createAppDef(name, url) { + if (!url) { + url = "https://google.com"; + } + return { + name, + type: "window", + title: name, + details: { + url + } + }; + } + } + + var AppManagerFactory = (config) => { + if (!config) { + throw Error("config not set"); + } + if (!config.agm) { + throw Error("config.agm is missing"); + } + const START_ONLY = "startOnly"; + const SKIP_ICONS = "skipIcons"; + const FULL = "full"; + const mode = config.mode || START_ONLY; + if (mode !== START_ONLY && mode !== SKIP_ICONS && mode !== FULL) { + throw new Error(`Invalid mode for appManager lib - ${mode} is not supported`); + } + const activities = config.activities; + const agm = config.agm; + const logger = config.logger; + const windows = config.windows; + let configuration = {}; + const appManager = new AppManagerImpl(mode, agm, activities, windows, logger.subLogger("applications"), config.gdMajorVersion, () => configuration); + const entitlements = new EntitlementsImpl(agm); + let readyPromise; + if (mode === START_ONLY) { + readyPromise = snapshot(agm, appManager); + } + else { + const subscription = createDataSubscription(agm, appManager, entitlements, mode === SKIP_ICONS); + readyPromise = subscription.start(); + } + const api = { + ready: () => readyPromise.then((c) => { configuration = c; }), + applications: appManager.applications, + application: appManager.application, + getConfigurations: appManager.getConfigurations, + onAppAdded: appManager.onAppAdded, + onAppRemoved: appManager.onAppRemoved, + onAppChanged: appManager.onAppChanged, + onAppAvailable: appManager.onAppAvailable, + onAppUnavailable: appManager.onAppUnavailable, + instances: appManager.instances, + get myInstance() { + return appManager.getMyInstance(); + }, + get myApplication() { + return appManager.getMyApplication(); + }, + onInstanceStarted: appManager.onInstanceStarted, + onInstanceStopped: appManager.onInstanceStopped, + onInstanceUpdated: appManager.onInstanceUpdated, + onInstanceStartFailed: appManager.onInstanceStartFailed, + getRegion: entitlements.getRegion, + getBranches: entitlements.getBranches, + getCurrentBranch: entitlements.getCurrentBranch, + getFunctionalEntitlement: entitlements.getFunctionalEntitlement, + getFunctionalEntitlementBranch: entitlements.getFunctionalEntitlementBranch, + setCurrentBranch: entitlements.setCurrentBranch, + setRegion: entitlements.setRegion, + currentUser: entitlements.currentUser, + canI: entitlements.canI, + canIBranch: entitlements.canIBranch, + onBranchesChanged: entitlements.onBranchesChanged, + exit: entitlements.exit, + restart: entitlements.restart, + onShuttingDown: entitlements.onShuttingDown, + inMemory: new InMemoryStore(agm) + }; + return api; + }; + + const T42JumpListAction = "T42.JumpList.Action"; + class JumpListManager { + constructor() { + this._groupActionCallbacks = new Map(); + this._registered = false; + } + init(executor, agm, logger) { + this._executor = executor; + this._agm = agm; + this._logger = logger; + this.registerCallbackMethod(); + } + setEnabled(windowId, enabled) { + const settings = { + enabled + }; + return this._executor.updateJumpList(windowId, settings); + } + createCategory(windowId, title, actions) { + this.validateActions(title, actions); + const settings = { + category: { + title, + operation: "create", + actions: this.toUpdateActions(windowId, "create", title, actions) + } + }; + return this._executor.updateJumpList(windowId, settings); + } + removeCategory(windowId, title) { + const settings = { + category: { + title, + operation: "remove", + actions: [] + } + }; + this.manageActionCallback(windowId, settings.category.operation, title); + return this._executor.updateJumpList(windowId, settings); + } + createActions(windowId, categoryTitle, actions) { + this.validateActions(categoryTitle, actions); + const settings = { + category: { + title: categoryTitle, + operation: "update", + actions: this.toUpdateActions(windowId, "create", categoryTitle, actions) + } + }; + return this._executor.updateJumpList(windowId, settings); + } + removeActions(windowId, categoryTitle, actions) { + const settings = { + category: { + title: categoryTitle, + operation: "update", + actions: this.toUpdateActions(windowId, "remove", categoryTitle, actions) + } + }; + return this._executor.updateJumpList(windowId, settings); + } + async getActions(windowId, catgoryTitle) { + const actions = []; + const configuration = await this.getJumpListSettings(windowId); + const currentCategory = configuration.categories.find((category) => category.title === catgoryTitle); + if (currentCategory) { + currentCategory.actions.forEach((action) => { + const actionCallback = this.getActionCallback(action.callbackId); + if (actionCallback) { + action.callback = actionCallback.callback; + } + actions.push({ + icon: action.icon, + callback: action.callback, + singleInstanceTitle: action.singleInstanceTitle, + multiInstanceTitle: action.multiInstanceTitle + }); + }); + } + return Promise.resolve(actions); + } + getJumpListSettings(windowId) { + return this._executor.getJumpList(windowId); + } + toUpdateActions(windowId, operation, categoryTitle, actions) { + return actions.map((action) => { + const updateAction = { + icon: action.icon, + callback: action.callback, + callbackId: Utils.generateId(), + singleInstanceTitle: action.singleInstanceTitle, + multiInstanceTitle: action.multiInstanceTitle, + operation + }; + this.manageActionCallback(windowId, operation, categoryTitle, updateAction); + return updateAction; + }); + } + manageActionCallback(windowId, operation, categoryTitle, updateAction) { + var _a; + const groupCallbacksKey = `${categoryTitle}-${windowId}`; + if (operation === "create") { + if (!this._groupActionCallbacks.has(groupCallbacksKey)) { + this._groupActionCallbacks.set(groupCallbacksKey, []); + } + const categoryActionCallbacks = this._groupActionCallbacks.get(groupCallbacksKey); + categoryActionCallbacks.push({ + callbackId: updateAction.callbackId, + callback: updateAction.callback + }); + } + else if (operation === "remove") { + if (updateAction) { + let categoryActionCallbacks = (_a = this._groupActionCallbacks.get(groupCallbacksKey)) !== null && _a !== void 0 ? _a : []; + categoryActionCallbacks = categoryActionCallbacks.filter((accCal) => accCal.callbackId !== updateAction.callbackId); + if (categoryActionCallbacks.length === 0) { + this._groupActionCallbacks.delete(groupCallbacksKey); + } + else { + this._groupActionCallbacks.set(groupCallbacksKey, categoryActionCallbacks); + } + } + else { + this._groupActionCallbacks.delete(groupCallbacksKey); + } + } + } + registerCallbackMethod() { + if (this._registered) { + return; + } + this._registered = true; + try { + this._agm.register(T42JumpListAction, (args, caller) => { + const actionCallback = this.getActionCallback(args.callbackId); + if (actionCallback) { + try { + actionCallback.callback(); + } + catch (e) { + this._logger.error("Unable to execute user callback for jump list action!", e); + } + } + }); + } + catch (e) { + this._logger.error(`Unable to register method ${T42JumpListAction} for invoking jump list action callbacks!`, e); + return Promise.reject(e); + } + } + getActionCallback(callbackId) { + let callbackAction; + [...this._groupActionCallbacks.values()].forEach((callbacks) => { + const callback = callbacks.find((cal) => cal.callbackId === callbackId); + if (callback) { + callbackAction = callback; + } + }); + return callbackAction; + } + validateActions(category, actions) { + if (!(actions && actions.length > 0)) { + throw new Error(`Category '${category}' doesn't contain any actions!`); + } + actions.forEach((action) => { + if (!action.singleInstanceTitle) { + throw new Error(`Category '${category}' contains an action with undefined singleInstanceTitle!`); + } + if (!action.multiInstanceTitle) { + throw new Error(`Category '${category}' contains an action with undefined multiInstanceTitle!`); + } + if (!action.callback) { + throw new Error(`Category '${category}' contains an action with undefined callback function!`); + } + }); + } + } + var jumpListManager = new JumpListManager(); + + class WindowStore { + constructor() { + this.waitForTimeoutInMilliseconds = 60000; + this._windows = {}; + this._pendingWindows = {}; + this._pendingWindowsStates = {}; + this._registry = CallbackRegistryFactory(); + } + init(logger) { + this._logger = logger; + } + get(id) { + return this._windows[id] || this._pendingWindows[id]; + } + getIfReady(id) { + return this._windows[id]; + } + get list() { + return this._windows; + } + add(window, state) { + const isExist = typeof this._pendingWindows[window.API.id] !== "undefined"; + if (isExist) { + this._logger.error(`trying to add window with id ${window.API.id} from windowStore, which already exists`); + return; + } + this._pendingWindows[window.API.id] = window; + this._pendingWindowsStates[window.API.id] = state; + this._registry.execute("on-added", window); + if (this.shouldMarkReadyToShow(state)) { + this.markReadyToShow(window.API.id); + } + } + remove(window) { + delete this._windows[window.API.id]; + delete this._pendingWindows[window.API.id]; + delete this._pendingWindowsStates[window.API.id]; + this._registry.execute("on-removed", window); + } + setUrlChangedState(windowId) { + const targetWindowState = this._pendingWindowsStates[windowId]; + if (typeof targetWindowState === "undefined") { + return; + } + targetWindowState.urlChanged = true; + if (this.shouldMarkReadyToShow(targetWindowState)) { + this.markReadyToShow(windowId); + } + } + setCompositionChangedState(wrapper) { + const windowId = wrapper.API.id; + const targetWindowState = this._pendingWindowsStates[windowId]; + if (typeof targetWindowState === "undefined") { + return; + } + targetWindowState.compositionChanged = true; + if (this.shouldMarkReadyToShow(targetWindowState)) { + this.markReadyToShow(windowId); + } + } + waitFor(id) { + return new Promise((resolve, reject) => { + let unReady; + let unRemoved; + const timeout = setTimeout(() => { + unReady(); + unRemoved(); + reject(new Error(`Window with id "${id}" was not ready within ${this.waitForTimeoutInMilliseconds} milliseconds.`)); + }, this.waitForTimeoutInMilliseconds); + const win = this._windows[id]; + if (win) { + clearTimeout(timeout); + resolve(win); + } + else { + const cleanup = () => { + clearTimeout(timeout); + unReady(); + unRemoved(); + }; + unReady = this.onReadyWindow((w) => { + if (w.API.id !== id) { + return; + } + cleanup(); + resolve(w); + }); + unRemoved = this.onRemoved((w) => { + if (w.API.id !== id) { + return; + } + cleanup(); + reject(new Error(`Window with id "${id}" was closed before it became ready.`)); + }); + } + }); + } + onReadyWindow(callback) { + return this._registry.add("on-ready", callback); + } + onAdded(callback) { + return this._registry.add("on-added", callback); + } + onRemoved(callback) { + return this._registry.add("on-removed", callback); + } + markReadyToShow(windowId) { + if (this._pendingWindows[windowId]) { + this._windows[windowId] = this._pendingWindows[windowId]; + delete this._pendingWindows[windowId]; + delete this._pendingWindowsStates[windowId]; + } + this._registry.execute("on-ready", this._windows[windowId]); + } + shouldMarkReadyToShow(targetWindowState) { + return targetWindowState && targetWindowState.urlChanged && targetWindowState.ready && targetWindowState.compositionChanged; + } + } + var windowStore = new WindowStore(); + + class JumpListActions { + constructor(windowId, configuration) { + this.windowId = windowId; + this._categoryTitle = configuration.title; + } + list() { + return jumpListManager.getActions(this.windowId, this._categoryTitle); + } + create(actions) { + return jumpListManager.createActions(this.windowId, this._categoryTitle, actions); + } + remove(actions) { + return jumpListManager.removeActions(this.windowId, this._categoryTitle, actions); + } + } + + class JumpListCategories { + constructor(windowId) { + this.windowId = windowId; + } + list() { + return this.getCategories(); + } + create(title, actions) { + return jumpListManager.createCategory(this.windowId, title, actions); + } + remove(title) { + return jumpListManager.removeCategory(this.windowId, title); + } + async find(title) { + const categories = await this.getCategories(); + return categories.find((cat) => cat.title === title); + } + async getCategories() { + const result = []; + const configuration = await jumpListManager.getJumpListSettings(this.windowId); + configuration.categories.forEach((category) => { + result.push({ + title: category.title, + actions: new JumpListActions(this.windowId, category) + }); + }); + return result; + } + } + + class JumpList { + constructor(windowId) { + this.windowId = windowId; + this._categories = new JumpListCategories(windowId); + } + get categories() { + return this._categories; + } + async isEnabled() { + const configuration = await jumpListManager.getJumpListSettings(this.windowId); + return configuration.enabled; + } + setEnabled(enabled) { + return jumpListManager.setEnabled(this.windowId, enabled); + } + } + + var windowFactory = (id, options, executor, logger, appManagerGetter, displayAPIGetter, channelsAPIGetter, agm) => { + var _a, _b, _c, _d; + const _registry = CallbackRegistryFactory(); + const getChannels = () => { + const channels = channelsAPIGetter(); + if (!channels) { + throw new Error(`To use this method you need to enable channels API - set the channels property to true when initializing the Glue42 library`); + } + return channels; + }; + const _id = id; + const _name = options.name; + const _mode = options.mode; + let _bounds = options.bounds; + let _url = options.url; + let _title = options.title; + let _context = (_a = options.context) !== null && _a !== void 0 ? _a : {}; + let _frameColor = options.frameColor; + let _focus = options.focus; + let _neighbours = (_b = options.neighbours) !== null && _b !== void 0 ? _b : {}; + let _groupId = options.groupId; + let _isGroupHeaderVisible = options.isGroupHeaderVisible; + let _isTabHeaderVisible = options.isTabHeaderVisible; + let _isGroupHibernated = options.isGroupHibernated; + let _isGroupVisible = options.isGroupVisible; + let _isTabSelected = (_c = options.isTabSelected) !== null && _c !== void 0 ? _c : false; + let _settings = options.settings; + const _applicationName = options.applicationName; + let _isVisible = options.isVisible; + let _isSticky = options.isSticky; + let _isCollapsed = options.isCollapsed; + let _windowState = options.state; + let _tabGroupId = options.tabGroupId; + let _tabIndex = options.tabIndex; + let _frameId = options.frameId; + let _isLocked = options.isLocked; + let _allowWorkspaceDrop = options.allowWorkspaceDrop; + let _isPinned = options.isPinned; + let _group; + let _frameButtons = (_d = options.frameButtons) !== null && _d !== void 0 ? _d : []; + let _zoomFactor = options.zoomFactor; + let _placementSettings = options.placementSettings; + const _jumpList = new JumpList(id); + function close(cbOrOptions, error) { + if (typeof cbOrOptions === "undefined" || typeof cbOrOptions === "function") { + return Utils.callbackifyPromise(() => { + if (!id) { + throw new Error("The window is already closed."); + } + return executor.close(resultWindow); + }, cbOrOptions, error); + } + else { + return executor.close(resultWindow, cbOrOptions); + } + } + function navigate(newUrl, optionsOrCallback, error) { + if (typeof optionsOrCallback === "function") { + return Utils.callbackifyPromise(() => { + if (isNullOrWhiteSpace(newUrl)) { + throw new Error("The new URL must be a non-empty string."); + } + return executor.navigate(resultWindow, newUrl); + }, optionsOrCallback, error); + } + if (isNullOrWhiteSpace(newUrl)) { + throw new Error("The new URL must be a non-empty string."); + } + if ((optionsOrCallback === null || optionsOrCallback === void 0 ? void 0 : optionsOrCallback.timeout) && typeof optionsOrCallback.timeout !== "number") { + throw new Error("Timeout argument must be a valid number"); + } + return executor.navigate(resultWindow, newUrl, optionsOrCallback); + } + function setStyle(style, success, error) { + return Utils.callbackifyPromise(() => { + if (!style || Object.keys(style).length === 0 || Object.keys(style).every((key) => !key)) { + throw new Error("Invalid style arguments: " + JSON.stringify(style)); + } + if (style && style.focus !== undefined) { + if (typeof style.focus !== "boolean") { + throw new Error("Focus must be a boolean value. Currently, only `focus: true` is supported."); + } + else if (style.focus === false) { + console.warn("`focus: false` is not supported!"); + } + } + if (style && style.hidden !== undefined && typeof style.hidden !== "boolean") { + throw new Error("The `hidden` property must hold a boolean value."); + } + for (const prop of ["minHeight", "maxHeight", "minWidth", "maxWidth"]) { + const styleAsAny = style; + const value = styleAsAny[prop]; + if (prop in style) { + if (isUndefinedOrNull(value)) { + delete styleAsAny[prop]; + continue; + } + if (!isNumber(styleAsAny[prop])) { + throw new Error(`"${prop}" must be a number`); + } + } + } + return executor.setStyle(resultWindow, style); + }, success, error); + } + function resetButtons(buttons, success, error) { + return Utils.callbackifyPromise(() => executor.resetButtons(resultWindow, buttons), success, error); + } + function getButtons() { + return executor.getButtons(resultWindow); + } + function setOnTop(onTop, success, error) { + return Utils.callbackifyPromise(() => { + if (typeof onTop === "string") { + if (onTop !== "always") { + throw new Error("`onTop` must hold a `always` value."); + } + } + else if (typeof onTop !== "boolean") { + throw new Error("`onTop` must hold a boolean or `always` value."); + } + return executor.setOnTop(resultWindow, onTop); + }, success, error); + } + function setSizeConstraints(constraints, success, error) { + return Utils.callbackifyPromise(() => { + if (!constraints || Object.keys(constraints).every((value) => value === undefined)) { + throw new Error("The properties of `constraints` cannot be null or undefined."); + } + return executor.setSizeConstraints(resultWindow, constraints); + }, success, error); + } + function getSizeConstraints() { + return executor.getSizeConstraints(resultWindow); + } + function setTitle(newTitle, success, error) { + return Utils.callbackifyPromise(() => { + if (isUndefinedOrNull(newTitle)) { + throw new Error("`newTitle` must not be null or undefined."); + } + if (newTitle === _title) { + return Promise.resolve(resultWindow); + } + return executor.setTitle(resultWindow, newTitle); + }, success, error); + } + function setSticky(isSticky, success, error) { + return Utils.callbackifyPromise(() => { + if (typeof isSticky !== "boolean") { + throw new Error("`isSticky` must hold a boolean value."); + } + return executor.setSticky(resultWindow, isSticky); + }, success, error); + } + function setAllowWorkspaceDrop(allowWorkspaceDrop) { + if (typeof allowWorkspaceDrop !== "boolean") { + throw new Error("`allowWorkspaceDrop` must hold a boolean value."); + } + return executor.setAllowWorkspaceDrop(resultWindow, allowWorkspaceDrop); + } + function pin() { + return executor.pin(resultWindow); + } + function unpin() { + return executor.unpin(resultWindow); + } + function moveResize(bounds, success, error) { + return Utils.callbackifyPromise(() => { + if (isUndefinedOrNull(bounds)) { + throw new Error("The properties of `bounds` cannot be null or undefined."); + } + return executor.moveResize(resultWindow, bounds); + }, success, error); + } + function addFrameButton(buttonInfo, success, error) { + return Utils.callbackifyPromise(() => { + if (typeof buttonInfo === "undefined" || Object.keys(buttonInfo).length === 0) { + throw new Error("Button info is not available."); + } + if (isNullOrWhiteSpace(buttonInfo.buttonId)) { + throw new Error("`buttonId` must not be null or undefined."); + } + if (isNullOrWhiteSpace(buttonInfo.imageBase64)) { + throw new Error("`imageBase64` must not be null or undefined."); + } + return executor.addFrameButton(resultWindow, buttonInfo); + }, success, error); + } + function removeFrameButton(buttonId, success, error) { + return Utils.callbackifyPromise(() => { + if (isNullOrWhiteSpace(buttonId)) { + throw new Error("`buttonId` must not be null or undefined."); + } + return executor.removeFrameButton(resultWindow, buttonId); + }, success, error); + } + function activate(success, error) { + return Utils.callbackifyPromise(() => { + if (_focus) { + return Promise.resolve(resultWindow); + } + return executor.activate(resultWindow); + }, success, error); + } + function focus(success, error) { + return Utils.callbackifyPromise(() => { + if (_focus) { + return Promise.resolve(resultWindow); + } + return executor.focus(resultWindow); + }, success, error); + } + function maximizeRestore(success, error) { + return Utils.callbackifyPromise(() => { + return executor.maximizeRestore(resultWindow); + }, success, error); + } + function maximize(success, error) { + return Utils.callbackifyPromise(() => { + if (_windowState === "maximized") { + return Promise.resolve(resultWindow); + } + return executor.maximize(resultWindow); + }, success, error); + } + function restore(success, error) { + return Utils.callbackifyPromise(() => { + if (_windowState === "normal") { + return Promise.resolve(resultWindow); + } + return executor.restore(resultWindow); + }, success, error); + } + function minimize(success, error) { + return Utils.callbackifyPromise(() => { + if (_windowState === "minimized") { + return Promise.resolve(resultWindow); + } + return executor.minimize(resultWindow); + }, success, error); + } + function collapse(success, error) { + return Utils.callbackifyPromise(() => { + if (_isCollapsed) { + return Promise.resolve(resultWindow); + } + return executor.collapse(resultWindow); + }, success, error); + } + function expand(success, error) { + return Utils.callbackifyPromise(() => { + if (!_isCollapsed) { + return Promise.resolve(resultWindow); + } + return executor.expand(resultWindow); + }, success, error); + } + function toggleCollapse(success, error) { + return Utils.callbackifyPromise(() => { + return executor.toggleCollapse(resultWindow); + }, success, error); + } + function snap(target, direction, success, error) { + return Utils.callbackifyPromise(() => { + if (isUndefinedOrNull(target)) { + throw new Error(`A target window is not specified - ${typeof target === "string" ? target : JSON.stringify(target)}`); + } + if (typeof target === "string") { + const win = windowStore.get(target); + if (!win) { + throw new Error(`Invalid "target" parameter or no such window. Invoked with: ${target}`); + } + target = win.API; + } + if (typeof direction === "string") { + direction = { + direction, + autoAlign: true + }; + } + return executor.snap(resultWindow, target, direction); + }, success, error); + } + function attachTab(tab, opt, success, error) { + return Utils.callbackifyPromise(() => { + var _a; + const errorMessage = `Invalid "tab" parameter - must be an object with an "id" property or a string. Invoked for source window with ID:`; + if (isUndefinedOrNull(tab)) { + const errMsg = `${errorMessage} ${typeof tab === "string" ? tab : JSON.stringify(tab)}`; + throw new Error(errMsg); + } + let sourceWindow; + if (typeof tab === "string") { + sourceWindow = (_a = windowStore.get(tab)) === null || _a === void 0 ? void 0 : _a.API; + if (isUndefinedOrNull(sourceWindow)) { + const errMsg = `${errorMessage} ${typeof sourceWindow === "string" ? sourceWindow : JSON.stringify(sourceWindow)}`; + throw new Error(errMsg); + } + } + else if (!isUndefinedOrNull(tab.id)) { + sourceWindow = tab; + } + else { + throw new Error(errorMessage); + } + const attachOptions = {}; + if (!isUndefinedOrNull(opt)) { + if (typeof opt === "number") { + attachOptions.index = opt; + } + else { + attachOptions.selected = opt.selected; + attachOptions.index = opt.index; + } + } + return executor.attachTab(resultWindow, sourceWindow, attachOptions); + }, success, error); + } + function detachTab(opt = {}, success, error) { + return Utils.callbackifyPromise(() => { + const argsForSend = {}; + function isDetachRelative(o) { + return o.relativeTo !== undefined; + } + if (isDetachRelative(opt)) { + if (typeof opt.relativeTo === "string") { + argsForSend.relativeTo = opt.relativeTo; + } + else if (!isUndefinedOrNull(opt.relativeTo.id)) { + argsForSend.relativeTo = opt.relativeTo.id; + } + if (!isUndefinedOrNull(opt.relativeDirection)) { + argsForSend.relativeDirection = opt.relativeDirection; + } + if (!isUndefinedOrNull(opt.width)) { + argsForSend.width = opt.width; + } + if (!isUndefinedOrNull(opt.height)) { + argsForSend.height = opt.height; + } + } + else { + if (!isUndefinedOrNull(opt.bounds)) { + argsForSend.bounds = opt.bounds; + } + } + if (!isUndefinedOrNull(opt.hideTabHeader)) { + argsForSend.hideTabHeader = opt.hideTabHeader; + } + return executor.detachTab(resultWindow, argsForSend); + }, success, error); + } + function setVisible(toBeVisible, success, error) { + return Utils.callbackifyPromise(() => { + return executor.setVisible(resultWindow, toBeVisible); + }, success, error); + } + async function center(display) { + if (display) { + validateCenterArguments(display); + } + return executor.center(resultWindow, display); + } + function validateCenterArguments(display) { + if (typeof display !== "object") { + throw Error("display argument must be a valid display object"); + } + if (!display.workArea || !display.scaleFactor) { + throw Error("display argument is not a valid display object"); + } + } + function showLoader(loader) { + return executor.showLoader(resultWindow, loader); + } + function hideLoader() { + return executor.hideLoader(resultWindow); + } + function updateContext(context, success, error) { + return Utils.callbackifyPromise(() => { + if (!isObject(context)) { + throw new Error(`"context" must not be null or undefined.`); + } + return executor.updateContext(resultWindow, context, false); + }, success, error); + } + function lock(success, error) { + return Utils.callbackifyPromise(() => { + return executor.lock(resultWindow); + }, success, error); + } + function unlock(success, error) { + return Utils.callbackifyPromise(() => { + return executor.unlock(resultWindow); + }, success, error); + } + function getIcon(success, error) { + return Utils.callbackifyPromise(() => { + return executor.getIcon(resultWindow); + }, success, error); + } + function setIcon(base64Image, success, error) { + return Utils.callbackifyPromise(() => { + if (isNullOrWhiteSpace(base64Image)) { + throw new Error(`"base64Image" must be a non-empty string.`); + } + return executor.setIcon(resultWindow, base64Image); + }, success, error); + } + function setFrameColor(frameColor, success, error) { + return Utils.callbackifyPromise(() => { + if (isNullOrWhiteSpace(frameColor)) { + throw new Error(`"frameColor" must be a non-empty string`); + } + return executor.setFrameColor(resultWindow, frameColor); + }, success, error); + } + function setTabHeaderVisible(toBeTabHeaderVisible, success, error) { + return Utils.callbackifyPromise(() => { + if (typeof toBeTabHeaderVisible !== "boolean") { + throw new Error(`"toBeTabHeaderVisible" must hold a boolean value.`); + } + return executor.setTabHeaderVisible(resultWindow, toBeTabHeaderVisible); + }, success, error); + } + async function setTabTooltip(tooltip) { + if (isNullOrWhiteSpace(tooltip)) { + throw new Error(`"${tooltip}" must not be null or undefined`); + } + return executor.setTabTooltip(resultWindow, tooltip); + } + async function getTabTooltip() { + return executor.getTabTooltip(resultWindow); + } + function showPopup(config) { + return executor.showPopup(resultWindow, config); + } + function createFlydown(config) { + return executor.createFlydown(resultWindow.id, config); + } + function setModalState(isModal) { + return executor.setModalState(resultWindow.id, isModal || false); + } + function zoomIn(success, error) { + return Utils.callbackifyPromise(() => { + return executor.zoomIn(resultWindow); + }, success, error); + } + function zoomOut(success, error) { + return Utils.callbackifyPromise(() => { + return executor.zoomOut(resultWindow); + }, success, error); + } + function setZoomFactor(zoomFactor, success, error) { + return Utils.callbackifyPromise(() => { + if (isNaN(zoomFactor)) { + throw new Error(`zoomFactor is not a number`); + } + return executor.setZoomFactor(resultWindow, zoomFactor); + }, success, error); + } + function showDevTools() { + return executor.showDevTools(resultWindow); + } + function capture(captureOptions) { + return executor.capture(resultWindow, captureOptions); + } + function flash(suppliedOptions, mode) { + const flashOptions = { + shouldFlash: true, + mode: "auto" + }; + if (typeof suppliedOptions === "boolean") { + flashOptions.shouldFlash = suppliedOptions; + } + if (typeof mode !== "undefined") { + flashOptions.mode = mode; + } + return executor.flash(resultWindow, flashOptions); + } + function flashTab(suppliedOptions) { + const flashOptions = { + shouldFlash: true, + }; + if (typeof suppliedOptions === "boolean") { + flashOptions.shouldFlash = suppliedOptions; + } + return executor.flashTab(resultWindow, flashOptions); + } + function print(printOptions) { + return executor.print(resultWindow, printOptions); + } + function printToPDF(printToPDFOptions) { + return executor.printToPDF(resultWindow, printToPDFOptions); + } + function ungroup(ungroupOptions) { + return new Promise((resolve, reject) => { + const unGroupChanged = onGroupChanged((win, newGroup, oldGroup) => { + if (id === win.id) { + unGroupChanged(); + resolve(resultWindow); + } + }); + executor.ungroup(resultWindow, ungroupOptions) + .catch((e) => { + unGroupChanged(); + reject(e); + }); + }); + } + function place(placementSettings) { + return executor.place(resultWindow, placementSettings); + } + function refresh(ignoreCache) { + return executor.refresh(resultWindow, ignoreCache); + } + function download(url, opts) { + return executor.download(resultWindow, url, opts); + } + function configure(settings) { + return executor.configureWindow(resultWindow, settings); + } + function getConfiguration() { + return executor.getWindowConfiguration(resultWindow); + } + function getDockingPlacement() { + return executor.getDockingPlacement(resultWindow); + } + function dock(opts) { + return executor.dock(resultWindow, opts); + } + async function clone(cloneOptions) { + return executor.clone(resultWindow, cloneOptions); + } + async function executeCode(code) { + if (!code) { + throw new Error("Code argument is missing"); + } + if (typeof code !== "string") { + throw new Error("Code argument must be a valid string"); + } + const response = await executor.executeCode(resultWindow, code); + return response.result; + } + function onTitleChanged(callback) { + if (!isFunction(callback)) { + throw new Error("callback should be a function"); + } + callback(resultWindow.title, resultWindow); + return onEventCore("onTitleChanged", callback); + } + function onClose(callback) { + if (!isFunction(callback)) { + throw new Error("callback should be a function"); + } + if (id === undefined) { + callback(resultWindow); + } + return _registry.add("onClose", callback); + } + function onUrlChanged(callback) { + return onEventCore("onUrlChanged", callback); + } + function onFrameButtonAdded(callback) { + return onEventCore("onFrameButtonAdded", callback); + } + function onFrameButtonRemoved(callback) { + return onEventCore("onFrameButtonRemoved", callback); + } + function onFrameButtonClicked(callback) { + return onEventCore("onFrameButtonClicked", callback); + } + function onCollapsed(callback) { + if (!isFunction(callback)) { + throw new Error("callback should be a function"); + } + if (_isCollapsed) { + callback(resultWindow); + } + return _registry.add("collapsed", callback); + } + function onExpanded(callback) { + if (!isFunction(callback)) { + throw new Error("callback should be a function"); + } + if (!_isCollapsed) { + callback(resultWindow); + } + return _registry.add("expanded", callback); + } + function onMaximized(callback) { + if (_windowState === "maximized") { + return onEventCore("maximized", callback, [resultWindow]); + } + else { + return onEventCore("maximized", callback); + } + } + function onMinimized(callback) { + if (_windowState === "minimized") { + return onEventCore("minimized", callback, [resultWindow]); + } + else { + return onEventCore("minimized", callback); + } + } + function onNormal(callback) { + if (_windowState === "normal") { + return onEventCore("normal", callback, [resultWindow]); + } + else { + return onEventCore("normal", callback); + } + } + function onAttached(callback) { + return onEventCore("attached", callback); + } + function onDetached(callback) { + return onEventCore("detached", callback); + } + function onVisibilityChanged(callback) { + return onEventCore("visibility-changed", callback); + } + function onContextUpdated(callback) { + return onEventCore("context-updated", callback); + } + function onLockingChanged(callback) { + return onEventCore("lock-changed", callback); + } + function onBoundsChanged(callback) { + return onEventCore("bounds-changed", callback); + } + function onFocusChanged(callback) { + return onEventCore("focus-changed", callback); + } + function onStickyChanged(callback) { + return onEventCore("sticky-changed", callback); + } + function onFrameColorChanged(callback) { + return onEventCore("frame-color-changed", callback); + } + function onTabHeaderVisibilityChanged(callback) { + return onEventCore("tab-header-visibility-changed", callback); + } + function onWindowAttached(callback) { + return onEventCore("window-attached", callback); + } + function onWindowDetached(callback) { + return onEventCore("window-detached", callback); + } + function onGroupChanged(callback) { + return onEventCore("group-changed", callback); + } + function onTabSelectionChanged(callback) { + return onEventCore("tab-selection-changed", callback); + } + function onChannelRestrictionsChanged(callback) { + if (!isFunction(callback)) { + throw new Error("callback must be a function"); + } + return onEventCore("channel-restrictions-changed", callback); + } + function onClosing(callback) { + if (!isFunction(callback)) { + throw new Error("callback must be a function"); + } + const callbackWrap = (success, error, prevent) => { + const promise = callback(prevent); + if (promise === null || promise === void 0 ? void 0 : promise.then) { + promise.then(success).catch(error); + } + else { + success(); + } + }; + return executor.onClosing(callbackWrap, resultWindow); + } + function onRefreshing(callback) { + if (!isFunction(callback)) { + throw new Error("callback must be a function"); + } + const callbackWrap = (success, error, prevent) => { + const promise = callback(prevent); + if (promise === null || promise === void 0 ? void 0 : promise.then) { + promise.then(success).catch(error); + } + else { + success(); + } + }; + return executor.onRefreshing(callbackWrap, resultWindow); + } + function onNavigating(callback) { + if (!isFunction(callback)) { + throw new Error("callback must be a function"); + } + const callbackWrap = (success, error, prevent, args) => { + const promise = callback(args); + if (promise === null || promise === void 0 ? void 0 : promise.then) { + promise.then(success).catch(error); + } + else { + success(); + } + }; + return executor.onNavigating(callbackWrap, resultWindow); + } + function onZoomFactorChanged(callback) { + return onEventCore("zoom-factor-changed", callback); + } + function onPlacementSettingsChanged(callback) { + return onEventCore("placementSettingsChanged", callback); + } + function onNeighboursChanged(callback) { + return onEventCore("neighbours-changed", callback); + } + function onDockingChanged(callback) { + return onEventCore("docking-changed", callback); + } + function onEventCore(key, callback, replayArguments) { + if (!isFunction(callback)) { + throw new Error("callback must be a function"); + } + return _registry.add(key, callback, replayArguments); + } + function goBack() { + return executor.goBack(resultWindow); + } + function goForward() { + return executor.goForward(resultWindow); + } + function startDrag(option) { + return executor.startDrag(resultWindow, option); + } + function showDialog(dialogOptions) { + if ((dialogOptions === null || dialogOptions === void 0 ? void 0 : dialogOptions.timerDuration) && isNaN(dialogOptions === null || dialogOptions === void 0 ? void 0 : dialogOptions.timerDuration)) { + throw new Error("timerDuration must be a number"); + } + if ((dialogOptions === null || dialogOptions === void 0 ? void 0 : dialogOptions.showTimer) && typeof (dialogOptions === null || dialogOptions === void 0 ? void 0 : dialogOptions.showTimer) !== "boolean") { + throw new Error("showTimer must be a boolean"); + } + return executor.showDialog(resultWindow, dialogOptions); + } + function handleUpdate(updated) { + _url = updated.url; + _title = updated.title; + _context = updated.context || {}; + _bounds = updated.bounds; + _frameColor = updated.frameColor; + _focus = updated.focus; + _neighbours = updated.neighbours || {}; + _groupId = updated.groupId; + _isGroupHeaderVisible = updated.isGroupHeaderVisible; + _isTabHeaderVisible = updated.isTabHeaderVisible; + _isGroupHibernated = updated.isGroupHibernated; + _isGroupVisible = updated.isGroupVisible; + _isTabSelected = updated.isTabSelected; + _settings = updated.settings; + _isVisible = updated.isVisible; + _isSticky = updated.isSticky; + _isCollapsed = updated.isCollapsed; + _windowState = updated.state; + _tabGroupId = updated.tabGroupId; + _frameId = updated.frameId; + _isLocked = updated.isLocked; + _allowWorkspaceDrop = updated.allowWorkspaceDrop; + _isPinned = updated.isPinned; + _zoomFactor = updated.zoomFactor; + _placementSettings = updated.placementSettings; + } + function handleTitleChanged(newTitle) { + _title = newTitle; + executor.finished + .finally(() => { + _registry.execute("onTitleChanged", newTitle, resultWindow); + }); + } + function handleUrlChanged(newUrl) { + _url = newUrl; + _registry.execute("onUrlChanged", newUrl, resultWindow); + } + function handleVisibilityChanged(isVisible) { + if (isVisible === _isVisible) { + return; + } + _isVisible = isVisible; + _registry.execute("visibility-changed", resultWindow); + } + function handleWindowSettingsChanged(settings) { + _settings = settings; + _registry.execute("settings-changed", resultWindow); + } + function handleContextUpdated(context) { + _context = context; + _registry.execute("context-updated", _context, resultWindow); + } + function handleWindowClose() { + if (id === undefined) { + return; + } + _registry.execute("onClose", resultWindow); + id = undefined; + } + function handleFrameButtonAdded(frameButton) { + const buttonObj = ["buttonId", "imageBase64", "order", "tooltip"].reduce((memo, k) => { + memo[k] = frameButton[k]; + return memo; + }, {}); + const frameButtonsIds = _frameButtons.map((btn) => { + return btn.buttonId; + }); + if (frameButtonsIds.indexOf(frameButton.buttonId) === -1) { + _frameButtons.push(buttonObj); + } + _registry.execute("onFrameButtonAdded", buttonObj, resultWindow); + } + function handleFrameButtonRemoved(frameButtonId) { + let button; + _frameButtons = _frameButtons.reduce((memo, btn) => { + if (btn.buttonId === frameButtonId) { + button = btn; + } + else { + memo.push(btn); + } + return memo; + }, []); + if (button !== undefined) { + _registry.execute("onFrameButtonRemoved", button, resultWindow); + } + } + function handleFrameButtonClicked(frameButton) { + const button = _frameButtons.filter((btn) => { + return btn.buttonId === frameButton.buttonId; + }); + if (button.length > 0) { + _registry.execute("onFrameButtonClicked", button[0], resultWindow); + } + } + async function handleWindowChangeState(state) { + if (state === "collapsed") { + _isCollapsed = true; + } + else if (state === "expanded") { + _isCollapsed = false; + } + else { + _windowState = state; + } + await executor.finished; + _registry.execute(state, resultWindow); + } + function handleFrameIsLockedChanged(isLocked) { + _isLocked = isLocked; + _registry.execute("lock-changed", resultWindow); + } + function handleBoundsChanged(bounds) { + if (_bounds.top === bounds.top && _bounds.left === bounds.left && _bounds.width === bounds.width && _bounds.height === bounds.height) { + return; + } + _bounds = bounds; + _registry.execute("bounds-changed", resultWindow); + } + function handleFocusChanged(isFocused) { + _focus = isFocused; + _registry.execute("focus-changed", resultWindow); + } + function handleIsStickyChanged(isSticky) { + _isSticky = isSticky; + _registry.execute("sticky-changed", isSticky, resultWindow); + } + function handleFrameColorChanged(frameColor) { + _frameColor = frameColor; + _registry.execute("frame-color-changed", resultWindow); + } + function handleFrameAttached(tabGroupId, frameId, isTabHeaderVisible) { + _tabGroupId = tabGroupId; + _frameId = frameId; + _isTabHeaderVisible = isTabHeaderVisible; + _registry.execute("frame-attached", resultWindow); + } + function handleCompositionChanged(state) { + _neighbours = state.neighbors || {}; + _tabIndex = state.index; + _registry.execute("neighbours-changed", _neighbours, resultWindow); + } + function handleAllowWorkspaceDropChanged(allowWorkspaceDrop) { + _allowWorkspaceDrop = allowWorkspaceDrop; + _registry.execute("allow-workspace-drop-changed", resultWindow); + } + function handleIsPinnedChanged(isPinned) { + _isPinned = isPinned; + _registry.execute("is-pinned-changed", resultWindow); + } + function handleGroupHeaderVisibilityChanged(isGroupHeaderVisible) { + _isGroupHeaderVisible = isGroupHeaderVisible; + } + function handleTabHeaderVisibilityChanged(isTabHeaderVisible) { + if (_isTabHeaderVisible !== isTabHeaderVisible) { + _isTabHeaderVisible = isTabHeaderVisible; + _registry.execute("tab-header-visibility-changed", resultWindow); + } + } + async function handleFrameSelectionChanged(newWindow, prevWindow) { + let selectedWindow; + if (newWindow === id) { + _isTabSelected = true; + selectedWindow = resultWindow; + } + else { + _isTabSelected = false; + selectedWindow = windowStore.get(newWindow) ? windowStore.get(newWindow).API : undefined; + } + const previousWindow = windowStore.get(prevWindow) ? windowStore.get(prevWindow).API : undefined; + await executor.finished; + _registry.execute("tab-selection-changed", selectedWindow, previousWindow, resultWindow); + } + async function handleAttached(newTabGroupId, newFrameId, tabHeaderVisible, isLocked, winsToBeNotified) { + _tabGroupId = newTabGroupId; + _isTabHeaderVisible = tabHeaderVisible; + _frameId = newFrameId; + if (typeof isLocked !== "undefined") { + _isLocked = isLocked; + } + await executor.finished; + winsToBeNotified.forEach((w) => { + w.Events.handleWindowAttached(resultWindow); + }); + _registry.execute("attached", resultWindow); + } + function handleWindowAttached(win) { + _registry.execute("window-attached", win); + } + async function handleDetached(isLocked, winsToBeNotified) { + _tabGroupId = undefined; + _isTabSelected = false; + if (typeof isLocked !== "undefined") { + _isLocked = isLocked; + } + await executor.finished; + winsToBeNotified.forEach((w) => { + w.Events.handleWindowDetached(resultWindow); + }); + _registry.execute("detached", resultWindow); + } + function handleWindowDetached(win) { + _registry.execute("window-detached", win); + } + function handleZoomFactorChanged(zoomFactor) { + _zoomFactor = zoomFactor; + _registry.execute("zoom-factor-changed", resultWindow); + } + function handlePlacementSettingsChanged(placementSettings) { + let promise; + const copy = placementSettings; + if (!copy.display) { + promise = Promise.resolve(undefined); + } + else { + const displayAPI = displayAPIGetter(); + if (!displayAPI) { + promise = Promise.resolve(undefined); + } + else { + const index = copy.display - 1; + promise = new Promise((resolve, reject) => { + displayAPI.all().then((displays) => { + const display = displays.find((d) => d.index === index); + resolve(display); + }).catch(reject); + }); + } + } + void promise.then((d) => { + copy.display = d; + _placementSettings = copy; + _registry.execute("placementSettingsChanged", resultWindow); + }); + } + function handleDockingChanged(data) { + _registry.execute("docking-changed", resultWindow, { + docked: data.docked, + position: data.position, + claimScreenArea: data.claimScreenArea + }); + } + function handleChannelRestrictionsChanged(data) { + _registry.execute("channel-restrictions-changed", data); + } + function handleGroupChanged(newGroup, oldGroup) { + _group = newGroup; + _groupId = newGroup === null || newGroup === void 0 ? void 0 : newGroup.id; + if (!isUndefinedOrNull(newGroup) && !isUndefinedOrNull(oldGroup)) { + _registry.execute("group-changed", resultWindow, newGroup, oldGroup); + } + } + function getAllTabs() { + const allWindows = windowStore.list; + if (_mode.toLowerCase() !== "tab") { + return []; + } + const tabs = Object.keys(allWindows).reduce((memo, win) => { + const window = allWindows[win]; + if (window + && window.API.tabGroupId + && typeof window.API.tabGroupId !== "undefined" + && typeof resultWindow.tabGroupId !== "undefined" + && window.API.tabGroupId === resultWindow.tabGroupId) { + memo.push(window.API); + } + return memo; + }, []); + return tabs.sort((w1, w2) => { + if (w1.tabIndex !== w2.tabIndex) { + if (w1.tabIndex === -1) { + return Number.MAX_SAFE_INTEGER; + } + if (w2.tabIndex === -1) { + return Number.MIN_SAFE_INTEGER; + } + } + return w1.tabIndex - w2.tabIndex; + }); + } + function mapWindowIdsToWindowObjects(windowIdArr) { + return windowIdArr.reduce((memo, winId) => { + const window = windowStore.get(winId); + if (window) { + memo.push(window.API); + } + return memo; + }, []); + } + function getNeighboursByDirection(direction) { + const windowIds = _neighbours[direction]; + if (typeof windowIds !== "undefined") { + return mapWindowIdsToWindowObjects(windowIds); + } + } + function getApplicationName() { + var _a; + if (_applicationName) { + return _applicationName; + } + if (_context._APPLICATION_NAME) { + return _context._APPLICATION_NAME; + } + if (_context && _context._t42 && _context._t42.application) { + return _context._t42.application; + } + const info = getWindowInfo(); + if (info && info.applicationName) { + return info.applicationName; + } + const appManager = appManagerGetter(); + if (appManager) { + const instance = appManager.instances().find((i) => id === i.id); + if (instance) { + return (_a = instance.application) === null || _a === void 0 ? void 0 : _a.name; + } + } + return undefined; + } + function getWindowInfo() { + if (typeof window !== "undefined" && window.glue42gd && window.glue42gd.getWindowInfo) { + const info = window.glue42gd.getWindowInfo(id); + if (!info) { + return undefined; + } + else { + return info; + } + } + } + const resultWindow = { + get id() { + return _id; + }, + get name() { + return _name; + }, + get application() { + const appManager = appManagerGetter(); + const appName = getApplicationName(); + if (appName && appManager) { + return appManager.application(appName); + } + }, + get hostInstance() { + return executor.hostInstance; + }, + get interopInstance() { + const instance = agm.servers().find((s) => s.windowId === this.id); + if (instance) { + return instance; + } + else { + const appName = getApplicationName(); + if (appName) { + return { application: appName }; + } + } + }, + get agmInstance() { + return resultWindow.interopInstance; + }, + get url() { + return _url; + }, + get title() { + return _title; + }, + get windowStyleAttributes() { + return _settings; + }, + get settings() { + return _settings; + }, + get tabGroupId() { + return _mode.toLowerCase() === "tab" ? _tabGroupId : undefined; + }, + get tabIndex() { + return _mode.toLowerCase() === "tab" ? _tabIndex : undefined; + }, + get frameId() { + return _frameId; + }, + get frameButtons() { + return _frameButtons.sort((b1, b2) => b1.order - b2.order); + }, + get mode() { + return _mode; + }, + get state() { + return _windowState; + }, + get isCollapsed() { + return _isCollapsed; + }, + get isVisible() { + return _isVisible; + }, + get isLocked() { + return _isLocked; + }, + get context() { + return _context; + }, + get bounds() { + return _bounds; + }, + get minHeight() { + return _settings.minHeight; + }, + get maxHeight() { + return _settings.maxHeight; + }, + get minWidth() { + return _settings.minWidth; + }, + get maxWidth() { + return _settings.maxWidth; + }, + get isFocused() { + return _focus; + }, + get frameColor() { + return _frameColor; + }, + get opened() { + return resultWindow.id !== undefined; + }, + get group() { + return _group; + }, + get groupId() { + return _groupId; + }, + get isSticky() { + return _isSticky; + }, + get topNeighbours() { + return getNeighboursByDirection("top"); + }, + get leftNeighbours() { + return getNeighboursByDirection("left"); + }, + get rightNeighbours() { + return getNeighboursByDirection("right"); + }, + get bottomNeighbours() { + return getNeighboursByDirection("bottom"); + }, + get isGroupHeaderVisible() { + return _isGroupHeaderVisible; + }, + get activityId() { + if (_context._t42) { + return _context._t42.activityId; + } + const info = getWindowInfo(); + if (!info) { + return undefined; + } + return info.activityId; + }, + get activityWindowId() { + if (_context._t42) { + return _context._t42.activityWindowId; + } + const info = getWindowInfo(); + if (!info) { + return undefined; + } + return info.activityWindowId; + }, + get windowType() { + return options.windowType || "electron"; + }, + get zoomFactor() { + return _zoomFactor; + }, + get screen() { + if (typeof window !== "undefined" && window.glue42gd) { + return Utils.getMonitor(resultWindow.bounds, window.glue42gd.monitors); + } + return undefined; + }, + get placementSettings() { + return Object.assign({}, _placementSettings); + }, + get jumpList() { + return _jumpList; + }, + get allowWorkspaceDrop() { + return _allowWorkspaceDrop; + }, + get isPinned() { + return _isPinned; + }, + maximize, + restore, + minimize, + maximizeRestore, + collapse, + expand, + toggleCollapse, + focus, + activate, + moveResize, + setTitle, + setStyle, + setOnTop, + resetButtons, + getButtons, + setSizeConstraints, + getSizeConstraints, + navigate, + addFrameButton, + removeFrameButton, + setVisible, + show: () => setVisible(true), + hide: () => setVisible(false), + center, + close, + snap, + showLoader, + hideLoader, + updateContext, + lock, + unlock, + getIcon, + setIcon, + setFrameColor, + setTabTooltip, + getTabTooltip, + attachTab, + detachTab, + setTabHeaderVisible, + showPopup, + createFlydown, + setModalState, + setZoomFactor, + zoomIn, + zoomOut, + showDevTools, + capture, + flash, + flashTab, + setSticky, + setAllowWorkspaceDrop, + pin, + unpin, + print, + printToPDF, + place, + ungroup, + refresh, + goBack, + goForward, + download, + configure, + getConfiguration, + getDockingPlacement, + dock, + clone, + executeCode, + getChannel: async () => { + var _a; + const wins = await getChannels().getWindowsWithChannels({ windowIds: [_id] }); + return (_a = wins[0]) === null || _a === void 0 ? void 0 : _a.channel; + }, + startDrag, + showDialog, + onClose, + onUrlChanged, + onTitleChanged, + onFrameButtonAdded, + onFrameButtonRemoved, + onFrameButtonClicked, + onCollapsed, + onExpanded, + onMinimized, + onMaximized, + onNormal, + onAttached, + onDetached, + onVisibilityChanged, + onContextUpdated, + onLockingChanged, + onBoundsChanged, + onFrameColorChanged, + onFocusChanged, + onStickyChanged, + onGroupChanged, + onWindowAttached, + onWindowDetached, + onTabSelectionChanged, + onTabHeaderVisibilityChanged, + onClosing, + onRefreshing, + onZoomFactorChanged, + onPlacementSettingsChanged, + onNeighboursChanged, + onDockingChanged, + onNavigating, + onChannelRestrictionsChanged, + get tabs() { + return getAllTabs(); + }, + get isTabHeaderVisible() { + return _isTabHeaderVisible; + }, + get isTabSelected() { + return _isTabSelected; + }, + getURL() { + return Promise.resolve(_url); + }, + getTitle() { + return Promise.resolve(_title); + }, + getBounds() { + return Promise.resolve(_bounds); + }, + getContext() { + return Promise.resolve(_context); + }, + setContext(context) { + if (!isObject(context)) { + throw new Error(`"context" must not be null or undefined, set to empty object if you want to clear it out.`); + } + return executor.updateContext(resultWindow, context, true); + }, + getDisplay() { + const displayAPI = displayAPIGetter(); + return displayAPI.getByWindowId(id); + }, + resizeTo(width, height) { + return moveResize({ width, height }); + }, + moveTo(top, left) { + return moveResize({ top, left }); + }, + async getParentWindow() { + var _a; + const myParentId = _settings.parentInstanceId; + if (!myParentId) { + return undefined; + } + return (_a = windowStore.list[myParentId]) === null || _a === void 0 ? void 0 : _a.API; + }, + async getChildWindows() { + return Object.keys(windowStore.list) + .map((key) => windowStore.list[key].API) + .filter((w) => { + const parentId = w.settings.parentInstanceId; + return parentId === id; + }); + }, + joinChannel: (name) => { + return getChannels().join(name, id); + }, + leaveChannel: () => { + return getChannels().leave(id); + } + }; + const events = { + handleUpdate, + handleWindowClose, + handleWindowChangeState, + handleTitleChanged, + handleVisibilityChanged, + handleUrlChanged, + handleWindowSettingsChanged, + handleContextUpdated, + handleFrameIsLockedChanged, + handleBoundsChanged, + handleFocusChanged, + handleFrameButtonAdded, + handleFrameButtonRemoved, + handleFrameButtonClicked, + handleFrameColorChanged, + handleFrameAttached, + handleFrameSelectionChanged, + handleCompositionChanged, + handleAllowWorkspaceDropChanged, + handleIsPinnedChanged, + handleGroupHeaderVisibilityChanged, + handleTabHeaderVisibilityChanged, + handleGroupChanged, + handleAttached, + handleDetached, + handleWindowAttached, + handleWindowDetached, + handleZoomFactorChanged, + handleIsStickyChanged, + handlePlacementSettingsChanged, + handleDockingChanged, + handleChannelRestrictionsChanged + }; + const groupArgs = { + get isGroupHibernated() { + return _isGroupHibernated; + }, + get isGroupVisible() { + return _isGroupVisible; + }, + }; + return { + API: resultWindow, + Events: events, + GroupCreationArgs: groupArgs + }; + }; + + function getWindowsByTabGroupId(windowId, tabGroupId) { + const windows = windowStore.list; + return Object.keys(windows).reduce((memo, id) => { + const win = windows[id]; + if (win.API.tabGroupId === tabGroupId && win.API.id !== windowId) { + memo.push(win); + } + return memo; + }, []); + } + function isEmpty(object) { + if (!object || Object.keys(object).every((value) => object[value] === undefined)) { + return true; + } + return false; + } + + class GDExecutor { + constructor() { + this.GroupMethodName = "T42.Group.Execute"; + this.WndMethodName = "T42.Wnd.Execute"; + this._registry = CallbackRegistryFactory(); + this._finished = Promise.resolve(); + this._configuration = { + windowAvailableOnURLChanged: true + }; + this.unsubCallbacks = {}; + } + get hostInstance() { + return this.agmTarget; + } + get finished() { + return this._finished; + } + get configuration() { + return this._configuration; + } + init(agm, instance) { + this.agm = agm; + this.agmTarget = instance; + this._registry.add("event", (data) => { + if (data.type === "Closed") { + const keys = Object.keys(this.unsubCallbacks); + keys.forEach((key) => { + const isSameWindow = key.startsWith(data.windowId); + if (isSameWindow) { + delete this.unsubCallbacks[key]; + } + }); + } + }); + } + setConfiguration(config) { + this._configuration = { ...this._configuration, ...config }; + } + handleEvent(data) { + this._registry.execute("event", data); + } + async open(options) { + let finishedResolve; + this._finished = new Promise((resolve) => { + finishedResolve = resolve; + }); + try { + const result = await this.agm.invoke("T42.Wnd.Create", options, this.agmTarget, { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_RESPONSE_TIMEOUT_MS + }); + if (result.returned === undefined) { + throw new Error("failed to execute T42.Wnd.Create - unknown reason"); + } + const id = result.returned.id; + const win = await windowStore.waitFor(id); + if (!this.configuration || this.configuration.windowAvailableOnURLChanged) { + setTimeout(() => { + if (win.API.windowType === "electron") { + win.Events.handleUrlChanged(win.API.url); + } + }, 0); + } + return win.API; + } + finally { + finishedResolve(); + } + } + async close(w, options) { + const result = await this.execute("close", { windowId: w.id, options }, `Closed`); + if (options) { + return result.closed; + } + return w; + } + async navigate(w, newUrl, urlLoadOptions) { + let methodResponseTimeoutMs = 120000; + if (typeof urlLoadOptions === "object" && typeof urlLoadOptions.timeout === "number") { + methodResponseTimeoutMs = urlLoadOptions.timeout * 1000; + delete urlLoadOptions.timeout; + } + await this.execute("navigate", { windowId: w.id, options: { url: newUrl, urlLoadOptions }, invocationOptions: { methodResponseTimeoutMs } }, "UrlChanged"); + return w; + } + async setStyle(w, style) { + var _a; + const stylePromises = []; + const wait = (promise) => stylePromises.push(promise); + if (!isUndefinedOrNull(style.focus) && !w.isFocused) { + wait(w.focus()); + } + if (!isUndefinedOrNull(style.hidden)) { + const toBeVisible = !style.hidden; + wait(w.setVisible(toBeVisible)); + } + if (!isUndefinedOrNull(style.onTop)) { + wait(w.setOnTop(style.onTop)); + } + if (!isNullOrWhiteSpace(style.tabTooltip) || !isNullOrWhiteSpace(style.tabToolTip)) { + const toolTip = (_a = style.tabTooltip) !== null && _a !== void 0 ? _a : style.tabToolTip; + wait(w.setTabTooltip(toolTip)); + } + if (!isNullOrWhiteSpace(style.tabTitle)) { + wait(this.execute("setTabTitle", { windowId: w.id, options: { tabTitle: style.tabTitle } })); + } + const constraints = { + minHeight: style.minHeight, + minWidth: style.minWidth, + maxHeight: style.maxHeight, + maxWidth: style.maxWidth, + }; + const hasConstraints = !isEmpty(constraints); + if (hasConstraints) { + wait(w.setSizeConstraints(constraints)); + } + const buttons = { + allowClose: style.allowClose, + allowCollapse: style.allowCollapse, + allowLockUnlock: style.allowLockUnlock, + allowMaximize: style.allowMaximize, + allowMinimize: style.allowMinimize + }; + const hasButtons = !isEmpty(buttons); + if (hasButtons) { + wait(w.resetButtons(buttons)); + } + await Promise.all(stylePromises); + return w; + } + async setSizeConstraints(w, constraints) { + await this.execute("setSizeConstraints", { windowId: w.id, options: constraints }); + return w; + } + async getSizeConstraints(w) { + const sizeConstraint = await this.execute("getSizeConstraints", { windowId: w.id }); + return sizeConstraint; + } + async setTabTooltip(w, tabTooltip) { + await this.execute("setTabTooltip", { windowId: w.id, options: { tabTooltip } }); + return w; + } + async getTabTooltip(w) { + const result = await this.execute("getTabTooltip", { windowId: w.id }); + return result.tabTooltip; + } + async resetButtons(w, buttonsConfig) { + await this.execute("resetButtons", { windowId: w.id, options: buttonsConfig }); + return w; + } + async getButtons(w) { + const buttons = await this.execute("getButtons", { windowId: w.id }); + return buttons; + } + async setOnTop(w, onTop) { + await this.execute("setOnTop", { windowId: w.id, options: { onTop } }); + return w; + } + async setTitle(w, newTitle) { + const options = { + windowId: w.id, + options: { + title: newTitle + } + }; + await this.execute("setTitle", options, "TitleChanged"); + return w; + } + async setSticky(w, isSticky) { + const options = { + windowId: w.id, + options: { + isSticky + } + }; + await this.execute("setSticky", options); + return w; + } + async setAllowWorkspaceDrop(w, allowWorkspaceDrop) { + const options = { + windowId: w.id, + options: { + allowWorkspaceDrop + } + }; + await this.execute("setAllowWorkspaceDrop", options); + return w; + } + async pin(windowToPin) { + const options = { + windowId: windowToPin.id + }; + await this.execute("pinTab", options); + return windowToPin; + } + async unpin(pinnedWindow) { + const options = { + windowId: pinnedWindow.id + }; + await this.execute("unpinTab", options); + return pinnedWindow; + } + async moveResize(w, bounds) { + if (typeof window !== "undefined" && window.glueDesktop.versionNum < 31200) { + return new Promise(async (res, rej) => { + const resolveImmediately = this.areBoundsEqual(bounds, w); + let isDone = false; + const done = () => { + if (isDone) { + return; + } + isDone = true; + if (unsubscribeBoundsChanged) { + unsubscribeBoundsChanged(); + unsubscribeBoundsChanged = undefined; + } + res(w); + if (resolveTimeout) { + clearTimeout(resolveTimeout); + resolveTimeout = undefined; + } + }; + let resolveTimeout; + let unsubscribeBoundsChanged; + if (!resolveImmediately) { + unsubscribeBoundsChanged = w.onBoundsChanged((win) => { + if (!this.areBoundsEqual(bounds, win)) { + return; + } + done(); + }); + } + try { + await this.execute("moveResize", { windowId: w.id, options: { bounds } }); + } + catch (error) { + rej(error); + return; + } + if (resolveImmediately) { + done(); + return; + } + resolveTimeout = setTimeout(() => { + done(); + }, 1000); + }); + } + else { + await this.execute("moveResize", { windowId: w.id, options: { bounds } }); + } + return w; + } + async addFrameButton(w, buttonInfo) { + await this.execute("addButton", { windowId: w.id, options: buttonInfo }, "ButtonAdded"); + return w; + } + async removeFrameButton(w, buttonId) { + await this.execute("removeButton", { windowId: w.id, options: buttonId }, "ButtonRemoved"); + return w; + } + async activate(w) { + await this.execute("activate", { windowId: w.id }); + return w; + } + async focus(w) { + await this.execute("focus", { windowId: w.id }); + return w; + } + async maximizeRestore(w) { + await this.execute("maximizeRestore", { windowId: w.id }, "StateChanged"); + return w; + } + async maximize(w) { + await this.execute("maximize", { windowId: w.id }, "StateChanged"); + return w; + } + async restore(w) { + await this.execute("restore", { windowId: w.id }, "StateChanged"); + return w; + } + async minimize(w) { + await this.execute("minimize", { windowId: w.id }, "StateChanged"); + return w; + } + async collapse(w) { + await this.execute("collapse", { windowId: w.id }, "StateChanged"); + return w; + } + async expand(w) { + await this.execute("expand", { windowId: w.id }, "StateChanged"); + return w; + } + async toggleCollapse(w) { + await this.execute("toggleCollapse", { windowId: w.id }, "StateChanged"); + return w; + } + async snap(w, targetWindow, options) { + const args = { + targetWindowId: targetWindow.id + }; + args.snappingEdge = options.direction; + args.autoAlign = options.autoAlign; + await this.execute("snap", { windowId: w.id, options: args }, "CompositionChanged", `CompositionChanged-${targetWindow.id}`); + return w; + } + async attachTab(w, sourceWindow, options) { + await this.execute("attachTab", { + windowId: w.id, + options: { + index: options, + sourceWindowId: sourceWindow.id, + targetWindowId: w.id, + } + }, `WindowFrameAdded-${sourceWindow.id}`, `WindowFrameRemoved-${sourceWindow.id}`); + return w; + } + async detachTab(w, options) { + const eventKeys = ["WindowFrameRemoved", `WindowFrameAdded`]; + if (!isUndefinedOrNull(options === null || options === void 0 ? void 0 : options.relativeTo)) { + eventKeys.push(`CompositionChanged`); + eventKeys.push(`CompositionChanged-${options.relativeTo}`); + } + else { + eventKeys.push("BoundsChanged"); + } + await this.execute("detachTab", { windowId: w.id, options }, ...eventKeys); + return w; + } + async setVisible(w, toBeVisible = true) { + let command; + if (toBeVisible) { + command = "show"; + } + else { + command = "hide"; + } + await this.execute(command, { windowId: w.id }, "VisibilityChanged"); + return w; + } + async center(w, display) { + await this.execute("center", { windowId: w.id, options: display }); + return w; + } + async showLoader(w, loader) { + await this.execute("showLoadingAnimation", { windowId: w.id, options: loader }); + return w; + } + async hideLoader(w) { + await this.execute("hideLoadingAnimation", { windowId: w.id }); + return w; + } + async updateContext(w, context, replace) { + let un; + try { + const contextWithoutUndefinedValues = this.swapUndefinedToNull(context); + const done = new Promise((resolve, reject) => { + un = w.onContextUpdated(() => { + resolve(); + }); + }); + await Promise.all([this.execute("updateContext", { + windowId: w.id, context: contextWithoutUndefinedValues, replace + }), done]); + return w; + } + finally { + if (un) { + un(); + } + } + } + async lock(w) { + await this.execute("lockUnlock", { windowId: w.id, options: { lock: true } }, "FrameIsLockedChanged"); + return w; + } + async unlock(w) { + await this.execute("lockUnlock", { windowId: w.id, options: { lock: false } }, "FrameIsLockedChanged"); + return w; + } + async getIcon(w) { + const result = await this.execute("getIcon", { + windowId: w.id, + options: {} + }); + return result.icon; + } + async setIcon(w, base64Image) { + await this.execute("setIcon", { + windowId: w.id, + options: { + dataURL: base64Image + } + }); + return w; + } + async setFrameColor(w, frameColor) { + await this.execute("setFrameColor", { windowId: w.id, options: { frameColor } }, "FrameColorChanged"); + return w; + } + async setTabHeaderVisible(w, toBeTabHeaderVisible) { + await this.execute("setTabHeaderVisible", { + windowId: w.id, + options: { + toShow: toBeTabHeaderVisible + } + }, "TabHeaderVisibilityChanged"); + return w; + } + async showGroupPopup(id, options) { + const reformatedOptions = this.showPopupCore(id, options); + await this.executeGroup("showGroupPopup", { + groupId: id, + options: reformatedOptions + }); + } + async showPopup(targetWindow, options) { + const reformatedOptions = this.showPopupCore(targetWindow.id, options); + await this.execute("showPopupWindow", { + windowId: targetWindow.id, + options: reformatedOptions + }); + return targetWindow; + } + async createFlydown(windowId, options) { + if (!options) { + throw new Error("The options object is not valid!"); + } + const optionsCopy = { ...options }; + if (!optionsCopy.horizontalOffset) { + optionsCopy.horizontalOffset = 0; + } + if (!optionsCopy.verticalOffset) { + optionsCopy.verticalOffset = 0; + } + const fullOptions = this.reformatFlydownOptions(windowId, optionsCopy); + return this.execute("setFlydownArea", { windowId, options: fullOptions }).then(() => { + const zoneIds = fullOptions.zones.map((z) => z.id); + fullOptions.zones.forEach((z) => { + let callback = typeof (z.flydownSize) === "function" ? + z.flydownSize : () => z.flydownSize; + if (options.size instanceof Function && z.flydownSize) { + callback = async (data, cancel) => { + let result; + if (options.size instanceof Function) { + result = await options.size(data, cancel); + } + if (z.flydownSize instanceof Function && z.flydownSize !== options.size) { + return await z.flydownSize(data, cancel) || result; + } + return result || z.flydownSize; + }; + } + this._registry.clearKey(`${fullOptions.targetId}_${z.id}`); + this._registry.add(`${fullOptions.targetId}_${z.id}`, callback); + }); + return { + destroy: () => this.clearFlydownArea(fullOptions.targetId, zoneIds), + options: optionsCopy + }; + }); + } + async setModalState(windowId, isModal) { + return this.execute("setModalState", { windowId, options: { isModal } }); + } + async autoArrange(displayId) { + return this.execute("autoArrange", { options: { displayId } }); + } + async handleFlydownBoundsRequested(targetId, data) { + const cancelCallback = () => data.cancel = true; + const callbackData = { + zoneId: data.flydownId, + flydownWindowBounds: data.flydownWindowBounds, + flydownWindowId: data.flydownWindowId, + }; + const responses = await Promise.all(this._registry.execute(`${targetId}_${data.flydownId}`, callbackData, cancelCallback)); + if (responses.length === 1) { + const defaultResponse = { height: 0, width: 0, top: 0, left: 0 }; + const response = typeof (responses[0]) === "object" && !Array.isArray(responses[0]) ? responses[0] : defaultResponse; + const responseOptions = { ...data, flydownWindowBounds: response }; + return responseOptions; + } + } + async handleOnEventRequested(callbackId, args) { + var _a; + const callbacks = (_a = this.unsubCallbacks[callbackId]) !== null && _a !== void 0 ? _a : []; + let prevented = false; + const preventArgs = []; + await Promise.all(callbacks.map((cb) => { + return new Promise((resolve, reject) => { + cb(() => { + resolve(); + }, () => { + reject(); + }, (pArgs) => { + prevented = true; + preventArgs.push(pArgs); + }, args); + }); + })); + return { prevented, preventArgs }; + } + async zoomIn(window) { + await this.execute("zoomIn", { + windowId: window.id, + }); + return window; + } + async zoomOut(window) { + await this.execute("zoomOut", { + windowId: window.id, + }); + return window; + } + async setZoomFactor(window, zoomFactor) { + await this.execute("setZoomFactor", { + windowId: window.id, + options: { + zoomFactor + } + }); + return window; + } + async showDevTools(window) { + await this.execute("showDevTools", { + windowId: window.id, + }); + return window; + } + async capture(window, options) { + const base64screenshot = (await this.execute("captureScreenshot", { windowId: window.id, options: { ...options } })).data; + return base64screenshot; + } + async captureGroup(windowIds, options) { + const base64screenshot = (await this.execute("captureGroupScreenshot", { windowId: windowIds[0], options: { groupWindowIds: windowIds, ...options } })).data; + return base64screenshot; + } + async flash(resultWindow, options) { + await this.execute("flash", { windowId: resultWindow.id, options: { ...options } }); + return resultWindow; + } + async flashTab(resultWindow, options) { + await this.execute("flashTab", { windowId: resultWindow.id, options: { ...options } }); + return resultWindow; + } + async configure(windowId, options) { + return this.execute("configure", { windowId, options: { ...options } }); + } + async print(resultWindow, options) { + await this.execute("print", { windowId: resultWindow.id, options: { ...options } }); + return resultWindow; + } + async printToPDF(resultWindow, options) { + const filePath = (await this.execute("printToPDF", { windowId: resultWindow.id, options: { ...options } })).filePath; + return filePath; + } + async place(window, options) { + const copy = { ...options }; + if (!options.display || options.display === "current") { + copy.display = await window.getDisplay(); + } + if (copy.display && typeof copy.display !== "string" && typeof copy.display !== "number") { + copy.display = copy.display.index + 1; + } + return this.execute("place", { windowId: window.id, options: { ...copy } }); + } + async refresh(resultWindow, ignoreCache) { + await this.execute("refresh", { windowId: resultWindow.id, options: { ignoreCache } }); + return resultWindow; + } + async download(resultWindow, url, options = {}) { + options.enableDownloadBar = !options.silent; + const result = await this.execute("downloadURL", { windowId: resultWindow.id, options: { url, options } }); + return { + url, + path: result.fullPath, + size: result.fileSize, + }; + } + async configureWindow(resultWindow, options) { + await this.execute("configureWindow", { windowId: resultWindow.id, options }); + return resultWindow; + } + async getWindowConfiguration(resultWindow) { + const config = await this.execute("getWindowConfiguration", { windowId: resultWindow.id }); + return config; + } + async startDrag(resultWindow, options) { + await this.execute("startDrag", { windowId: resultWindow.id, options }); + return resultWindow; + } + showDialog(resultWindow, options) { + return new Promise((res, rej) => { + const token = Utils.generateId(); + const un = this._registry.add("event", (args) => { + if (args.type === "DialogResult" && args.windowId === resultWindow.id && args.data.token === token) { + un(); + const data = args.data; + if ("status" in data) { + if (data.status === "failed") { + rej(new Error(data.message)); + } + else if (data.status === "successful") { + res(data.result); + } + } + } + }); + this.execute("showDialog", { windowId: resultWindow.id, options: Object.assign({}, { ...options }, { token }) }); + }); + } + async execute(command, options, ...eventKeys) { + return this.executeCore(this.WndMethodName, command, options, ...eventKeys); + } + async executeGroup(command, options, ...eventKeys) { + return this.executeCore(this.GroupMethodName, command, options, ...eventKeys); + } + async ungroup(w, options) { + const args = { + windowId: w.id, + options + }; + await this.execute("ungroup", args); + return w; + } + async updateJumpList(windowId, options) { + const args = { + windowId, + options + }; + await this.execute("updateJumplist", args); + } + async getJumpList(windowId) { + const args = { + windowId, + }; + const result = await this.execute("getJumplist", args); + return result; + } + onClosing(callback, gdWindow) { + const glue42gd = typeof window !== "undefined" && window.glue42gd; + if (glue42gd && gdWindow.windowType === "electron") { + return glue42gd.addCloseHandler(callback, gdWindow.id); + } + else { + return this.nonWindowHandlers(callback, gdWindow.id, "OnClosing"); + } + } + onGroupClosing(callback, group) { + return this.nonWindowHandlersCore(group.id, "OnClosing", true, callback); + } + onRefreshing(callback, gdWindow) { + const glue42gd = typeof window !== "undefined" && window.glue42gd; + if (glue42gd && gdWindow.windowType === "electron") { + return glue42gd.addRefreshHandler(callback, gdWindow.id); + } + else { + return this.nonWindowHandlers(callback, gdWindow.id, "OnRefreshing"); + } + } + onNavigating(callback, gdWindow) { + const glue42gd = typeof window !== "undefined" && window.glue42gd; + if (glue42gd && gdWindow.windowType === "electron") { + return glue42gd.addWillNavigateHandler(callback, gdWindow.id); + } + else { + return this.nonWindowHandlers(callback, gdWindow.id, "OnNavigating"); + } + } + async clone(window, cloneOptions) { + const args = { + windowId: window.id, + options: cloneOptions + }; + const result = await this.execute("clone", args); + const win = await windowStore.waitFor(result.id); + return win.API; + } + async executeCode(targetWindow, code) { + const args = { + windowId: targetWindow.id, + options: { + code + } + }; + return this.execute("executeCode", args); + } + async goBack(resultWindow) { + await this.execute("goBack", { windowId: resultWindow.id }); + } + async goForward(resultWindow) { + await this.execute("goForward", { windowId: resultWindow.id }); + } + async getDockingPlacement(window) { + return this.execute("getDockingPlacement", { windowId: window.id }); + } + dock(window, options) { + return this.execute("dock", { windowId: window.id, options }); + } + clearCallbacks(id) { + const keys = Object.keys(this.unsubCallbacks); + keys.forEach((key) => { + if (key.startsWith(id)) { + delete this.unsubCallbacks[key]; + } + }); + } + nonWindowHandlers(callback, targetId, type) { + return this.nonWindowHandlersCore(targetId, type, false, callback); + } + nonWindowHandlersCore(targetId, type, isGroup, callback) { + const id = `${targetId}-${type}`; + const unsub = () => { + var _a; + if (this.unsubCallbacks[id]) { + const callbacks = this.unsubCallbacks[id]; + this.unsubCallbacks[id] = callbacks.filter((cb) => cb !== callback); + if (this.unsubCallbacks[id].length === 0) { + delete this.unsubCallbacks[id]; + } + } + const cbs = (_a = this.unsubCallbacks[id]) !== null && _a !== void 0 ? _a : []; + if (cbs.length === 0) { + const options = { + unsubscribe: true + }; + if (isGroup) { + this.executeGroup(type, { + groupId: targetId, + options + }); + } + else { + this.execute(type, { + windowId: targetId, + options + }); + } + } + }; + if (this.unsubCallbacks[id]) { + this.unsubCallbacks[id].push(callback); + return unsub; + } + else { + this.unsubCallbacks[id] = [callback]; + } + if (isGroup) { + this.executeGroup(type, { groupId: targetId }); + } + else { + this.execute(type, { windowId: targetId }); + } + return unsub; + } + reformatFlydownOptions(windowId, options) { + const assignGeneralIfUnassigned = (zone, prop) => { + if (options[prop] && (zone[prop] === undefined || zone[prop] === null)) { + const valueFromOptions = options[prop]; + zone[prop] = valueFromOptions; + } + }; + const zones = options.zones.map((z) => { + assignGeneralIfUnassigned(z, "windowId"); + assignGeneralIfUnassigned(z, "targetLocation"); + if (options.size && (z.flydownSize === undefined || z.flydownSize === null)) { + z.flydownSize = options.size; + } + z.flydownBounds = z.flydownSize; + z.flydownId = z.windowId; + if (!z.targetLocation) { + z.targetLocation = "bottom"; + } + return z; + }); + return { + ...options, + zones, + targetId: windowId, + flydownBounds: options.size, + flydownActiveArea: options.activeArea + }; + } + clearFlydownArea(windowId, areaIds) { + return this.execute("clearFlydownWindowArea", { + windowId, + options: {} + }).then(() => { + areaIds.forEach((id) => { + this._registry.clearKey(`${windowId}_${id}`); + }); + }); + } + executeWithoutToken(params, ...eventKeys) { + const uns = []; + const executed = eventKeys === null || eventKeys === void 0 ? void 0 : eventKeys.filter((k) => !isUndefinedOrNull(k)).map((key) => { + return new Promise((r) => { + const [type, windowId = params.windowId] = key.split("-"); + uns.push(this._registry.add("event", (data) => { + if (data.type === type && data.windowId === windowId) { + r(); + } + })); + }); + }); + const action = new Promise((resolve, reject) => { + this.agm.invoke("T42.Wnd.Execute", params, this.agmTarget, { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_RESPONSE_TIMEOUT_MS + }) + .then((i) => { + if (i.returned && i.returned.errorMsg) { + reject(i); + } + else { + resolve(i.returned); + } + }) + .catch((e) => reject(e)); + }); + return Promise.all([action, ...executed]) + .then((r) => { + return r[0]; + }) + .finally(() => { + uns.forEach((un) => un()); + }); + } + async executeCore(methodName, command, options, ...eventKeys) { + const { invocationOptions, ...invocationArgs } = options; + const params = { + ...invocationArgs, + command, + }; + let finishedResolve; + this._finished = new Promise((resolve) => { + finishedResolve = resolve; + }); + try { + if (typeof window !== "undefined" && window.glueDesktop.versionNum < 31200) { + return await this.executeWithoutToken(params, ...eventKeys); + } + else { + return await this.executeWithToken(methodName, params, invocationOptions); + } + } + finally { + finishedResolve(); + } + } + async executeWithToken(methodName, options, invocationOptions) { + let un; + try { + const token = Utils.generateId(); + const event = new Promise((r) => { + un = this._registry.add("event", (data) => { + if (data.token === token) { + r(); + } + }); + }); + const execute = new Promise((resolve, reject) => { + options.token = token; + if (!invocationOptions) { + invocationOptions = { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_RESPONSE_TIMEOUT_MS + }; + } + else if (!invocationOptions.methodResponseTimeoutMs) { + invocationOptions.methodResponseTimeoutMs = INTEROP_METHOD_RESPONSE_TIMEOUT_MS; + } + else if (!invocationOptions.waitTimeoutMs) { + invocationOptions.waitTimeoutMs = INTEROP_METHOD_WAIT_TIMEOUT_MS; + } + this.agm.invoke(methodName, options, this.agmTarget, invocationOptions) + .then((i) => { + if (i.returned && i.returned.errorMsg) { + reject(new Error(i.returned.errorMsg)); + } + else { + resolve(i.returned); + } + }) + .catch((e) => { + const error = Utils.typedError(e); + reject(error); + }); + }); + const result = await Promise.all([execute, event]); + return result[0]; + } + finally { + if (un) { + un(); + } + } + } + areBoundsEqual(requested, w) { + const current = w.bounds; + const settings = w.settings; + let height = requested.height; + let width = requested.width; + if (requested.height < settings.minHeight) { + height = settings.minHeight; + } + if (requested.height > settings.maxHeight) { + height = settings.maxHeight; + } + if (requested.width < settings.minWidth) { + width = settings.minWidth; + } + if (requested.width > settings.maxWidth) { + width = settings.maxWidth; + } + const areHeightsEqual = height ? current.height === height : true; + const areWidthsEqual = width ? current.width === width : true; + const areLeftsEqual = requested.left ? current.left === requested.left : true; + const areTopsEqual = requested.top ? current.top === requested.top : true; + return areHeightsEqual && areWidthsEqual && areLeftsEqual && areTopsEqual; + } + swapUndefinedToNull(context) { + try { + const copy = {}; + for (const key of Object.keys(context)) { + let value = context[key]; + if (typeof value === "undefined") { + value = null; + } + copy[key] = value; + } + return copy; + } + catch { + return context; + } + } + showPopupCore(id, options) { + if (!options) { + throw new Error("The options object is not valid!"); + } + const optionsCopy = { ...options }; + if (!optionsCopy.targetLocation) { + optionsCopy.targetLocation = "bottom"; + } + const reformatedOptions = { + ...optionsCopy, + popupBounds: optionsCopy.size, + targetId: id, + popupId: optionsCopy.windowId + }; + return reformatedOptions; + } + } + var executor = new GDExecutor(); + + class GDEnvironment { + constructor(agm, logger, appManagerGetter, displayAPIGetter, channelsAPIGetter, wndId, groupId) { + this._registry = CallbackRegistryFactory(); + this._agm = agm; + this._logger = logger.subLogger("gd-env"); + this._windowId = wndId; + this._groupId = groupId; + this._appManagerGetter = appManagerGetter; + this._displayAPIGetter = displayAPIGetter; + this._channelsAPIGetter = channelsAPIGetter; + } + init() { + return new Promise((resolve, reject) => { + this._agm.register("T42.Wnd.OnEventWithResponse", (args, caller) => { + return this.respondToEvent(args); + }); + new Promise((streamResolve, streamReject) => { + this._agm.subscribe("T42.Wnd.OnEvent", { + target: "best", + arguments: { + withConfig: true + }, + onData: (streamData) => { + if (streamData.data.type === "Configuration") { + this._configuration = streamData.data; + executor.setConfiguration(this._configuration); + return; + } + this.updateWindow(streamData.data, resolve); + executor.handleEvent(streamData.data); + }, + onConnected: (instance) => { + this._agmInstance = instance; + executor.init(this._agm, this._agmInstance); + } + }).catch((error) => { + var _a; + const message = `${(_a = error === null || error === void 0 ? void 0 : error.method) === null || _a === void 0 ? void 0 : _a.name} - ${JSON.stringify(error === null || error === void 0 ? void 0 : error.called_with)} - ${error === null || error === void 0 ? void 0 : error.message}`; + reject(new Error(message)); + }); + }); + }); + } + get executor() { + return executor; + } + open(name, url, options) { + options = options || {}; + const copyOptions = { ...options }; + if (copyOptions.relativeTo !== undefined && typeof copyOptions.relativeTo !== "string") { + copyOptions.relativeTo = copyOptions.relativeTo.id || ""; + } + copyOptions.name = name; + copyOptions.url = url; + copyOptions.windowState = options.windowState || options.state; + delete copyOptions.state; + return this.executor.open(copyOptions); + } + createFlydown(windowId, options) { + return this.executor.createFlydown(windowId, options); + } + async showPopup(windowId, options) { + const window = windowStore.get(windowId); + await this.executor.showPopup(window.API, options); + } + tabAttached(callback) { + return this._registry.add("tab-attached", callback); + } + tabDetached(callback) { + return this._registry.add("tab-detached", callback); + } + onWindowFrameColorChanged(callback) { + return this._registry.add("frame-color-changed", callback); + } + onEvent(callback) { + return this._registry.add("window-event", callback); + } + my() { + return this._windowId; + } + myGroup() { + return this._groupId; + } + onCompositionChanged(callback) { + return this._registry.add("composition-changed", callback); + } + onGroupHeaderVisibilityChanged(callback) { + return this._registry.add("group-header-changed", callback); + } + onGroupVisibilityChanged(callback) { + return this._registry.add("group-visibility-changed", callback); + } + onGroupStateChanged(callback) { + return this._registry.add("group-state-changed", callback); + } + onWindowGotFocus(callback) { + return this._registry.add("got-focus", callback); + } + onWindowLostFocus(callback) { + return this._registry.add("lost-focus", callback); + } + onWindowsAutoArrangeChanged(callback) { + return this._registry.add("windows-auto-arranged-changed", callback); + } + respondToEvent(args) { + if (args.type === "ShowFlydownBoundsRequested") { + return this.executor.handleFlydownBoundsRequested(args.data.windowId, args.data); + } + else if (args.type === "OnClosing" || args.type === "OnRefreshing" || args.type === "OnNavigating") { + return this.executor.handleOnEventRequested(args.data.callbackId, args.data.args); + } + return Promise.reject(`There isn't a handler for ${args.type}`); + } + updateWindow(windowInfo, readyResolve) { + const extendedStreamEvent = this.getExtendedStreamEvent(windowInfo); + if (windowInfo.type === "Snapshot") { + const windowInfoFullInfoEvent = windowInfo; + windowInfoFullInfoEvent.windows.forEach((w) => { + const existingWindow = windowStore.get(w.id); + if (existingWindow) { + existingWindow.Events.handleUpdate(this.mapToWindowConstructorOptions(w)); + existingWindow.GroupCreationArgs = this.mapToGroupCreationArgs(w); + } + else { + this.createWindowFromSnapshot(w.id, w); + } + this._registry.execute("window-event", extendedStreamEvent); + }); + readyResolve(this); + return; + } + if (windowInfo.type === "CommandExecuted") { + this._registry.execute("window-event", extendedStreamEvent); + return; + } + if (windowInfo.type === "Created") { + const windowInfoCreatedEvent = (windowInfo); + this.createWindowFromStream(windowInfoCreatedEvent.windowId, windowInfoCreatedEvent.data || {}); + this._registry.execute("window-event", extendedStreamEvent); + return; + } + if (windowInfo.type === "OnGroupVisibilityChanged") { + const info = windowInfo; + this._registry.execute("group-visibility-changed", info.data); + this._registry.execute("window-event", windowInfo); + return; + } + if (windowInfo.type === "OnGroupStateChanged") { + const info = windowInfo; + this._registry.execute("group-state-changed", info.data); + this._registry.execute("window-event", windowInfo); + return; + } + if (windowInfo.type === "OnWindowsAutoArrangeChanged") { + const info = windowInfo; + this._registry.execute("windows-auto-arranged-changed", info.data); + this._registry.execute("window-event", windowInfo); + return; + } + const windowObjectAndEvents = windowStore.get((windowInfo).windowId); + if (!windowObjectAndEvents) { + this._logger.error(`received update for unknown window. Stream:', ${JSON.stringify(windowInfo, null, 4)}`); + return; + } + const theWindow = windowObjectAndEvents.API; + const theWindowEvents = windowObjectAndEvents.Events; + if (windowInfo.type === "BoundsChanged") { + const windowInfoBoundsChangedEvent = windowInfo; + theWindowEvents.handleBoundsChanged(windowInfoBoundsChangedEvent.data); + } + if (windowInfo.type === "UrlChanged") { + const windowInfoUrlChangedEvent = windowInfo; + windowStore.setUrlChangedState(windowInfoUrlChangedEvent.windowId); + theWindowEvents.handleUrlChanged(windowInfoUrlChangedEvent.data); + } + if (windowInfo.type === "TitleChanged") { + const windowInfoTitleChanged = windowInfo; + theWindowEvents.handleTitleChanged(windowInfoTitleChanged.data); + } + if (windowInfo.type === "IsStickyChanged") { + const windowInfoIsStickyChangedChanged = windowInfo; + theWindowEvents.handleIsStickyChanged(windowInfoIsStickyChangedChanged.data); + } + if (windowInfo.type === "VisibilityChanged") { + theWindowEvents.handleVisibilityChanged(windowInfo.data); + } + if (windowInfo.type === "ContextChanged") { + theWindowEvents.handleContextUpdated(windowInfo.data); + } + if (windowInfo.type === "StateChanged") { + theWindowEvents.handleWindowChangeState(windowInfo.data); + } + if (windowInfo.type === "FrameColorChanged") { + theWindowEvents.handleFrameColorChanged(windowInfo.data); + this._registry.execute("frame-color-changed", theWindow); + } + if (windowInfo.type === "CompositionChanged") { + const windowInfoCompositionChanged = windowInfo; + theWindowEvents.handleCompositionChanged(windowInfoCompositionChanged.data); + windowStore.setCompositionChangedState(windowObjectAndEvents); + this._registry.execute("composition-changed", windowInfoCompositionChanged.data); + } + if (windowInfo.type === "GroupHeaderVisibilityChanged") { + const info = windowInfo; + theWindowEvents.handleGroupHeaderVisibilityChanged(info.data.groupHeaderVisible); + this._registry.execute("group-header-changed", info.data); + } + if (windowInfo.type === "FocusChanged") { + const windowInfoFocusChanged = windowInfo; + this.focusChanged(theWindowEvents, theWindow, windowInfoFocusChanged.data); + } + if (windowInfo.type === "WindowFrameChanged") { + theWindowEvents.handleFrameAttached(windowInfo.data.frameId, windowInfo.data.frameId, windowInfo.data.isTabHeaderVisible); + this._registry.execute("frame-changed"); + } + if (windowInfo.type === "WindowFrameAdded") { + const winsToBeNotified = getWindowsByTabGroupId(theWindow.id, windowInfo.data.frameId); + const data = windowInfo.data; + theWindowEvents.handleAttached(data.frameId, data.frameId, data.isTabHeaderVisible, data.isLocked, winsToBeNotified) + .then(async () => { + if (winsToBeNotified.length > 0) { + await executor.finished; + this._registry.execute("tab-attached", theWindow, windowInfo.data.frameId, windowInfo.data.isTabHeaderVisible); + } + }); + } + if (windowInfo.type === "WindowFrameRemoved") { + const oldTabGroupId = theWindow.tabGroupId; + const winsToBeNotified = getWindowsByTabGroupId(theWindow.id, oldTabGroupId); + theWindowEvents.handleDetached(windowInfo.data.isLocked, winsToBeNotified) + .then(async () => { + if (winsToBeNotified.length > 0) { + await executor.finished; + this._registry.execute("tab-detached", theWindow, windowInfo.data.frameId, theWindow.tabGroupId); + } + }); + } + if (windowInfo.type === "TabHeaderVisibilityChanged") { + theWindowEvents.handleTabHeaderVisibilityChanged(windowInfo.data.isTabHeaderVisible); + } + if (windowInfo.type === "FrameSelectionChanged") { + theWindowEvents.handleFrameSelectionChanged(windowInfo.data.newWindowId, windowInfo.data.prevWindowId); + } + if (windowInfo.type === "ButtonClicked") { + theWindowEvents.handleFrameButtonClicked(windowInfo.data); + } + if (windowInfo.type === "ButtonAdded") { + theWindowEvents.handleFrameButtonAdded(windowInfo.data); + } + if (windowInfo.type === "ButtonRemoved") { + theWindowEvents.handleFrameButtonRemoved(windowInfo.data); + } + if (windowInfo.type === "WindowZoomFactorChanged") { + theWindowEvents.handleZoomFactorChanged(windowInfo.data); + } + if (windowInfo.type === "Closed") { + windowStore.remove(windowObjectAndEvents); + theWindowEvents.handleWindowClose(); + } + if (windowInfo.type === "FrameIsLockedChanged") { + theWindowEvents.handleFrameIsLockedChanged(windowInfo.data); + } + if (windowInfo.type === "PlacementSettingsChanged") { + theWindowEvents.handlePlacementSettingsChanged(windowInfo.data); + } + if (windowInfo.type === "DockingChanged") { + theWindowEvents.handleDockingChanged(windowInfo.data); + } + if (windowInfo.type === "AllowWorkspaceDropChanged") { + theWindowEvents.handleAllowWorkspaceDropChanged(windowInfo.data); + } + if (windowInfo.type === "IsPinnedChanged") { + theWindowEvents.handleIsPinnedChanged(windowInfo.data); + } + if (windowInfo.type === "WindowChannelRestrictionsChanged") { + theWindowEvents.handleChannelRestrictionsChanged(windowInfo.data); + } + this._registry.execute("window-event", extendedStreamEvent); + } + createWindowFromSnapshot(windowId, options) { + const windowObjAndEvents = this.createWindowCore(windowId, options); + windowStore.add(windowObjAndEvents, { + ready: true, + urlChanged: true, + compositionChanged: true + }); + } + createWindowFromStream(windowId, options) { + var _a; + const windowObjAndEvents = this.createWindowCore(windowId, options); + const isRemote = windowObjAndEvents.API.windowType === "remote"; + const isFrameless = windowObjAndEvents.API.windowType === "electron" && windowObjAndEvents.API.mode === "frameless"; + const isHidden = windowObjAndEvents.API.isVisible === false; + let urlChanged = false; + let compositionChanged = false; + if (isRemote) { + urlChanged = true; + } + if (isFrameless || isHidden) { + compositionChanged = true; + } + if (!isRemote) { + urlChanged = !((_a = this._configuration) === null || _a === void 0 ? void 0 : _a.windowAvailableOnURLChanged); + } + windowStore.add(windowObjAndEvents, { + ready: true, + urlChanged, + compositionChanged + }); + } + createWindowCore(windowId, options) { + const windowObjAndEvents = windowFactory(windowId, this.mapToWindowConstructorOptions(options), executor, this._logger, this._appManagerGetter, this._displayAPIGetter, this._channelsAPIGetter, this._agm); + windowObjAndEvents.GroupCreationArgs = this.mapToGroupCreationArgs(options); + return windowObjAndEvents; + } + async focusChanged(theWindowEvents, theWindow, focus) { + theWindowEvents.handleFocusChanged(focus); + try { + if (!this._configuration.windowAvailableOnURLChanged) { + await windowStore.waitFor(theWindow.id); + } + } + catch (error) { + return; + } + if (focus) { + this._registry.execute("got-focus", theWindow); + } + else { + this._registry.execute("lost-focus", theWindow); + } + } + mapToWindowConstructorOptions(args) { + return { + name: args.name, + context: args.context, + bounds: args.bounds, + url: args.url, + title: args.title, + isVisible: args.isVisible, + focus: args.isFocused, + state: args.state, + frameColor: args.frameColor, + groupId: args.groupId, + neighbours: args.neighbors, + isFocused: args.isFocused, + isGroupHeaderVisible: args.groupHeaderVisible, + isCollapsed: args.isCollapsed, + tabGroupId: args.frameId, + frameId: args.frameId, + mode: args.mode, + isTabHeaderVisible: args.isTabHeaderVisible, + isTabSelected: args.isActiveTab, + settings: args.settings, + windowType: args.windowType, + zoomFactor: args.zoomFactor, + isLocked: args.isLocked, + placementSettings: args.placementSettings, + isSticky: args.isSticky, + tabIndex: args.tabIndex, + frameButtons: args.frameButtons, + jumpListOptions: args.jumpList, + applicationName: args.applicationName, + allowWorkspaceDrop: args.allowWorkspaceDrop, + isPinned: args.isPinned + }; + } + mapToGroupCreationArgs(args) { + return { + isGroupHibernated: args.isGroupHibernated, + isGroupVisible: args.isGroupVisible + }; + } + getExtendedStreamEvent(streamEvent) { + try { + if (!streamEvent.windowId) { + return streamEvent; + } + const window = windowStore.get(streamEvent.windowId); + if (!window) { + return streamEvent; + } + const result = { + state: streamEvent.type, + windowName: window.API.name, + ...streamEvent + }; + if (result.state === "WindowFrameAdded") { + result.state = "TabAttached"; + } + if (result.state === "StateChanged") { + result.state = result.data.charAt(0).toUpperCase() + result.data.slice(1); + } + if (result.state === "ButtonAdded") { + result.state = "FrameButtonAdded"; + } + if (result.state === "ButtonRemoved") { + result.state = "FrameButtonRemoved"; + } + return result; + } + catch (error) { + return streamEvent; + } + } + } + + var envDetector = (agm, logger, appManagerGetter, displayAPIGetter, channelsAPIGetter, gdMajorVersion) => { + var _a; + const _logger = logger; + if (gdMajorVersion === 2) { + _logger.trace("running in HC"); + throw new Error("GD2 not supported"); + } + else if (gdMajorVersion >= 3) { + _logger.trace("running in GD 3"); + return new GDEnvironment(agm, _logger, appManagerGetter, displayAPIGetter, channelsAPIGetter, window.glue42gd.windowId, (_a = window.webGroupsManager) === null || _a === void 0 ? void 0 : _a.id).init(); + } + else { + _logger.trace("running in Browser or Node"); + return new GDEnvironment(agm, _logger, appManagerGetter, displayAPIGetter, channelsAPIGetter).init(); + } + }; + + var groupFactory = (id, executor) => { + const _registry = CallbackRegistryFactory(); + const _windowsId = []; + let _isHibernatedFlag; + let _isVisible; + async function addWindow(winId) { + var _a, _b, _c, _d; + if (_windowsId.indexOf(winId) === -1) { + _windowsId.push(winId); + const win = windowStore.get(winId); + win.Events.handleGroupChanged(groupObject, undefined); + _isHibernatedFlag = (_b = (_a = win.GroupCreationArgs.isGroupHibernated) !== null && _a !== void 0 ? _a : _isHibernatedFlag) !== null && _b !== void 0 ? _b : false; + _isVisible = (_d = (_c = win.GroupCreationArgs.isGroupVisible) !== null && _c !== void 0 ? _c : _isVisible) !== null && _d !== void 0 ? _d : true; + await executor.finished; + _registry.execute("window-added", groupObject, win.API); + } + } + async function removeWindow(win) { + const index = _windowsId.indexOf(win.API.id); + if (index !== -1) { + _windowsId.splice(index, 1); + win.Events.handleGroupChanged(undefined, groupObject); + await executor.finished; + _registry.execute("window-removed", groupObject, win.API); + } + } + function find(window, success, error) { + let winId; + if (typeof window === "string") { + winId = window; + } + else if (!isUndefinedOrNull(window)) { + winId = window.id; + } + const win = _mapToWindowObject(winId); + if (win) { + if (typeof success === "function") { + success(win); + } + return win; + } + else { + if (typeof error === "function") { + error(`No window with ID: ${winId}`); + } + } + } + function windows(success) { + const mappedWindows = _mapToWindowObjects(); + return mappedWindows; + } + async function execute(command, options, ...keys) { + await executor.execute(command, options, ...keys); + return groupObject; + } + function handleGroupHeaderVisibilityChanged(windowInfo) { + _registry.execute("header-visibility-changed", groupObject); + } + function handleGroupVisibilityChanged(visibile) { + _isVisible = visibile; + _registry.execute("group-visibility-changed", groupObject); + } + function handleGroupHibernateChanged(isHibernatedFlag) { + _isHibernatedFlag = isHibernatedFlag; + } + function _mapToWindowObjects() { + const winObjects = []; + _windowsId.forEach((winId) => { + const windowObject = _mapToWindowObject(winId); + if (typeof windowObject !== "undefined") { + winObjects.push(windowObject); + } + }); + return winObjects; + } + function _mapToWindowObject(windowId) { + return windowStore.get(windowId) ? windowStore.get(windowId).API : undefined; + } + function _getGroupHeaderVisibility() { + const windowWithHiddenHeader = _mapToWindowObjects().find((w) => !w.isGroupHeaderVisible); + const _isGroupHeaderVisible = windowWithHiddenHeader === undefined; + return _isGroupHeaderVisible; + } + function isHibernated() { + return _isHibernatedFlag; + } + function onHeaderVisibilityChanged(callback) { + return _registry.add("header-visibility-changed", callback); + } + function onWindowAdded(callback) { + return _registry.add("window-added", callback); + } + function onWindowRemoved(callback) { + return _registry.add("window-removed", callback); + } + function onVisibilityChanged(callback) { + if (!callback) { + throw new Error("Callback argument is required"); + } + if (callback && typeof callback !== "function") { + throw new Error("Callback argument must be a function"); + } + return _registry.add("group-visibility-changed", callback); + } + function onClosing(callback) { + if (typeof callback !== "function") { + throw new Error("callback must be a function"); + } + const callbackWrap = (success, error, prevent) => { + const promise = callback(prevent); + if (promise === null || promise === void 0 ? void 0 : promise.then) { + promise.then(success).catch(error); + } + else { + success(); + } + }; + return executor.onGroupClosing(callbackWrap, groupObject); + } + const groupObject = { + id, + get windows() { + return windows(); + }, + find, + get isHeaderVisible() { + return _getGroupHeaderVisibility(); + }, + get isHibernated() { + return isHibernated(); + }, + get isVisible() { + return _isVisible; + }, + showHeader: (success, error) => { + return Utils.callbackifyPromise(() => { + return execute("setGroupHeaderVisibility", { windowId: _windowsId[0], options: { toShow: true } }, ..._windowsId.map((w) => `GroupHeaderVisibilityChanged-${w}`)); + }, success, error); + }, + hideHeader: (success, error) => { + return Utils.callbackifyPromise(() => { + return execute("setGroupHeaderVisibility", { windowId: _windowsId[0], options: { toShow: false } }, ..._windowsId.map((w) => `GroupHeaderVisibilityChanged-${w}`)); + }, success, error); + }, + getTitle: async () => { + const r = await executor.execute("getGroupTitle", { windowId: _windowsId[0] }); + return r.title; + }, + setTitle: async (title) => { + if (isNullOrWhiteSpace(title)) { + throw new Error("`title` must not be null or undefined."); + } + return execute("setGroupTitle", { windowId: _windowsId[0], options: { title } }); + }, + capture: (captureOptions) => { + return executor.captureGroup(_windowsId, captureOptions); + }, + maximize: (success, error) => { + return Utils.callbackifyPromise(() => { + return execute("maximizeGroup", { windowId: _windowsId[0] }, ..._windowsId.map((w) => `StateChanged-${w}`)); + }, success, error); + }, + restore: (success, error) => { + return Utils.callbackifyPromise(() => { + return execute("restoreGroup", { windowId: _windowsId[0] }, ..._windowsId.map((w) => `StateChanged-${w}`)); + }, success, error); + }, + show: (activate) => { + if (!isUndefinedOrNull(activate) && !isBoolean(activate)) { + throw new Error("Activate flag must be a boolean!"); + } + activate = !isUndefinedOrNull(activate) ? activate : true; + return executor.executeGroup("showGroup", { + groupId: id, + options: { activate } + }); + }, + hide: () => { + return executor.executeGroup("hideGroup", { + groupId: id + }); + }, + close: () => { + return executor.executeGroup("closeGroup", { + groupId: id + }); + }, + showPopup: (options) => { + return executor.showGroupPopup(id, options); + }, + onHeaderVisibilityChanged, + onWindowAdded, + onWindowRemoved, + onVisibilityChanged, + onClosing, + }; + const internal = { + get windows() { + return _windowsId; + }, + addWindow, + removeWindow, + handleGroupHeaderVisibilityChanged, + handleGroupVisibilityChanged, + handleGroupHibernateChanged + }; + return { + groupAPI: groupObject, + groupInternal: internal, + }; + }; + + var groupsFactory = (environment, logger) => { + const _registry = CallbackRegistryFactory(); + const _groups = {}; + let heardForWindowsCounter = -1; + const windows = windowStore.list; + Object.keys(windows).forEach((k) => { + const win = windows[k]; + const groupId = win.API.groupId; + const winId = win.API.id; + if (!isNullOrWhiteSpace(groupId)) { + addWindow(groupId, winId); + } + }); + windowStore.onRemoved((w) => { + const group = findGroupWrapperByWindow(w.API); + removeWindow(group, w); + }); + environment.onCompositionChanged((windowInfo) => { + handleCompositionChanged(windowInfo); + }); + environment.onGroupHeaderVisibilityChanged((windowInfo) => { + const windowId = windowInfo.windowId; + const group = findGroupByWindow(windowId); + if (typeof group !== "undefined") { + const groupEvents = _groups[group.id]; + if (heardForWindowsCounter === -1) { + heardForWindowsCounter = group.windows.length; + } + heardForWindowsCounter--; + if (heardForWindowsCounter === 0) { + heardForWindowsCounter = -1; + groupEvents.groupInternal.handleGroupHeaderVisibilityChanged(windowInfo); + } + } + }); + environment.onGroupVisibilityChanged((data) => { + const groupEvents = _groups[data.groupId]; + if (groupEvents) { + groupEvents.groupInternal.handleGroupVisibilityChanged(data.visible); + } + }); + environment.onGroupStateChanged((data) => { + const groupWrapper = _groups[data.groupId]; + if (data.state === "hibernated") { + if (groupWrapper === null || groupWrapper === void 0 ? void 0 : groupWrapper.groupAPI) { + groupWrapper.groupInternal.handleGroupHibernateChanged(true); + } + _registry.execute("group-hibernated", data.groupId); + } + else if (data.state === "resumed") { + if (groupWrapper === null || groupWrapper === void 0 ? void 0 : groupWrapper.groupAPI) { + groupWrapper.groupInternal.handleGroupHibernateChanged(false); + } + _registry.execute("group-resumed", groupWrapper.groupAPI); + } + }); + function my() { + var _a; + return findGroupByWindow((_a = environment.myGroup()) !== null && _a !== void 0 ? _a : environment.my()); + } + async function create(options) { + if (isUndefinedOrNull(options)) { + throw new Error(`options must be defined`); + } + if (isUndefinedOrNull(options.groups) || !Array.isArray(options.groups) || options.groups.length === 0) { + throw new Error(`options.groups must be defined`); + } + const { groupIds } = await executor.executeGroup("createGroups", { + options + }); + const groups = groupIds.map((groupId) => { + return waitForGroup(groupId); + }); + return Promise.all(groups); + } + async function close(idOrGroup, options) { + if (isUndefinedOrNull(idOrGroup)) { + throw new Error(`group must be defined`); + } + let groupId = ""; + if (typeof idOrGroup === "string") { + groupId = idOrGroup; + } + else { + groupId = idOrGroup.id; + } + if (isUndefinedOrNull(options)) { + throw new Error(`options must be defined`); + } + await executor.executeGroup("closeGroup", { + groupId, + options + }); + } + function list(success) { + const result = Object.keys(_groups).map((groupId) => { + if (_groups[groupId]) { + return _groups[groupId].groupAPI; + } + }); + if (typeof success === "function") { + success(result); + } + return result; + } + function findGroupByWindow(winId, success, error) { + let windowId; + if (typeof winId === "string") { + windowId = winId; + } + else if (!isUndefinedOrNull(winId)) { + windowId = winId.id; + } + const result = Object.values(_groups).find((groupObj) => { + const group = groupObj.groupAPI; + const wins = group.windows.filter((w) => w.id === windowId); + return wins.length; + }); + if (result) { + if (typeof success === "function") { + success(result.groupAPI); + } + return result.groupAPI; + } + else if (typeof error === "function") { + error(`Cannot find the group of the window.`); + } + } + function waitForGroup(groupId) { + if (!groupId) { + return Promise.reject(new Error(`groupId must be defined`)); + } + return new Promise((res, rej) => { + const groupWrapper = _groups[groupId]; + if (groupWrapper) { + res(groupWrapper.groupAPI); + } + else { + const un = onGroupAdded((group) => { + if (group.id === groupId) { + un(); + res(group); + } + }); + } + }); + } + function getMyGroup() { + var _a; + return waitForGroup((_a = environment.myGroup()) !== null && _a !== void 0 ? _a : environment.my()); + } + async function resume(groupId, activate) { + validateGroupIdArg(groupId); + if (!isUndefinedOrNull(activate) && !isBoolean(activate)) { + throw new Error("Activate flag must be a boolean!"); + } + activate = !isUndefinedOrNull(activate) ? activate : true; + await executor.executeGroup("resumeGroup", { + groupId, + options: { activate } + }); + } + async function hibernate(groupId) { + validateGroupIdArg(groupId); + await executor.executeGroup("hibernateGroup", { + groupId + }); + return groupId; + } + function onGroupAdded(callback) { + return _registry.add("group-added", callback); + } + function onGroupRemoved(callback) { + return _registry.add("group-removed", callback); + } + function onWindowMoved(callback) { + return _registry.add("window-moved", callback); + } + function onHibernated(callback) { + if (!callback) { + throw new Error("Callback argument is required"); + } + if (callback && typeof callback !== "function") { + throw new Error("Callback argument must be a function"); + } + return _registry.add("group-hibernated", callback); + } + function onResumed(callback) { + if (!callback) { + throw new Error("Callback argument is required"); + } + if (callback && typeof callback !== "function") { + throw new Error("Callback argument must be a function"); + } + return _registry.add("group-resumed", callback); + } + function createOrGet(groupId) { + if (!_groups.hasOwnProperty(groupId)) { + const createdGroupWrapper = groupFactory(groupId, environment.executor); + _groups[groupId] = createdGroupWrapper; + const group = createdGroupWrapper.groupAPI; + _registry.execute("group-added", group); + return createdGroupWrapper; + } + else { + return _groups[groupId]; + } + } + function deleteIfEmpty(groupWrapper) { + const group = groupWrapper.groupAPI; + if (group.windows.length === 0) { + delete _groups[group.id]; + executor.clearCallbacks(group.id); + _registry.execute("group-removed", group); + } + } + function addWindow(groupId, winId) { + const group = createOrGet(groupId); + group.groupInternal.addWindow(winId); + return group; + } + function removeWindow(group, win) { + if (!group) { + return; + } + group.groupInternal.removeWindow(win); + deleteIfEmpty(group); + } + function handleCompositionChanged(state) { + const groupId = state.groupId; + const windowId = state.windowId; + const win = windowStore.get(windowId); + if (!win) { + return; + } + const currentGroup = findGroupWrapperByWindow(win.API); + if (isUndefinedOrNull(groupId)) { + removeWindow(currentGroup, win); + return; + } + if (isUndefinedOrNull(currentGroup) && !isUndefinedOrNull(groupId)) { + addWindow(groupId, win.API.id); + return; + } + if (currentGroup.groupAPI.id !== groupId) { + moveWindow(win, currentGroup.groupAPI.id, groupId); + } + } + function moveWindow(win, from, to) { + const winId = win.API.id; + const fromGroup = _groups[from]; + removeWindow(fromGroup, win); + const toGroup = addWindow(to, winId); + win.Events.handleGroupChanged(toGroup.groupAPI, fromGroup.groupAPI); + _registry.execute("window-moved", winId, from, to); + } + function findGroupWrapperByWindow(winId) { + let windowId; + if (typeof winId === "string") { + windowId = winId; + } + else if (!isUndefinedOrNull(winId)) { + windowId = winId.id; + } + return Object.values(_groups).find((groupObj) => { + const groupInternal = groupObj.groupInternal; + const wins = groupInternal.windows.filter((id) => id === windowId); + return wins.length; + }); + } + function validateGroupIdArg(groupId) { + if (!groupId || typeof groupId !== "string") { + throw new Error("Please provide a valid Group ID as a non-empty string!"); + } + } + const groups = { + get my() { + return my(); + }, + create, + close, + list, + findGroupByWindow, + waitForGroup, + getMyGroup, + onGroupAdded, + onGroupRemoved, + hibernate, + resume, + onHibernated, + onResumed + }; + const events = { onWindowMoved }; + return { + groupsAPI: groups, + groupsEvents: events, + }; + }; + + var WindowsFactory = (agm, logger, appManagerGetter, displayAPIGetter, channelsGetter, gdMajorVersion) => { + const _registry = CallbackRegistryFactory(); + const _logger = logger; + let groups; + let environment; + windowStore.init(_logger); + const isReady = new Promise((resolve, reject) => { + envDetector(agm, _logger, appManagerGetter, displayAPIGetter, channelsGetter, gdMajorVersion) + .then((env) => { + environment = env; + groups = groupsFactory(env); + jumpListManager.init(env.executor, agm, _logger); + resolve(); + }) + .catch((e) => { + const err = `Timed out waiting for connection to Glue42 Enterprise: Error: ${e.message}`; + _logger.error(err, e); + reject(new Error(err)); + }); + }); + function ready() { + return isReady; + } + function my() { + const myWindow = windowStore.getIfReady(environment.my()); + return myWindow ? myWindow.API : undefined; + } + function open(name, url, options, success, error) { + return Utils.callbackifyPromise(() => { + if (isNullOrWhiteSpace(name)) { + throw new Error("The window name is missing."); + } + if (isNullOrWhiteSpace(url)) { + throw new Error("The window URL is missing."); + } + if (!isUndefinedOrNull(options)) { + const optionsAsAny = options; + for (const prop of ["minHeight", "maxHeight", "minWidth", "maxWidth", "width", "height", "top", "left"]) { + if (prop in optionsAsAny) { + const value = optionsAsAny[prop]; + if (isUndefinedOrNull(value)) { + delete optionsAsAny[prop]; + continue; + } + if (!isNumber(value)) { + const errMessage = `${prop} must be a number`; + throw new Error(errMessage); + } + if (optionsAsAny[prop] === "width" || optionsAsAny[prop] === "height") { + if (value <= 0) { + const errMessage = `${prop} must be a positive number`; + throw new Error(errMessage); + } + } + } + } + } + return environment.open(name, url, options); + }, success, error); + } + function find(name, success, error) { + const windows = windowStore.list; + const windowsForListing = Object.keys(windows).reduce((memo, winId) => { + var _a; + const window = windows[winId]; + if (((_a = window === null || window === void 0 ? void 0 : window.API) === null || _a === void 0 ? void 0 : _a.name) === name) { + memo.push(window.API); + } + return memo; + }, []); + const win = windowsForListing[0]; + if (win) { + if (typeof success === "function") { + success(windowsForListing[0]); + } + return windowsForListing[0]; + } + else { + if (typeof error === "function") { + error("There is no window with name:" + name); + } + } + } + function findById(id, success, error) { + const windows = windowStore.list; + const windowsForListing = Object.keys(windows).reduce((memo, winId) => { + const window = windows[winId]; + if (typeof window !== "undefined" && window.API.id === id) { + memo.push(window.API); + } + return memo; + }, []); + const win = windowsForListing[0]; + if (win) { + if (typeof success === "function") { + success(windowsForListing[0]); + } + return windowsForListing[0]; + } + else { + if (typeof error === "function") { + error("There is no window with such id:" + id); + } + } + } + function list(success) { + const windows = windowStore.list; + const windowsForListing = Object.keys(windows) + .map((k) => { + return windows[k].API; + }); + if (typeof success !== "function") { + return windowsForListing; + } + success(windowsForListing); + } + function configure(options) { + const win = my(); + const winId = win ? win.id : ""; + return executor.configure(winId, options); + } + function autoArrange(displayId) { + return executor.autoArrange(displayId); + } + function windowAdded(callback) { + return _registry.add("window-added", callback); + } + function windowRemoved(callback) { + return _registry.add("window-removed", callback); + } + function tabAttached(callback) { + let unsubFunc; + let unsubscribed = false; + isReady.then(() => { + if (unsubscribed) { + return; + } + unsubFunc = environment.tabAttached(callback); + }); + return () => { + unsubscribed = true; + if (unsubFunc) { + unsubFunc(); + } + }; + } + function tabDetached(callback) { + let unsubFunc; + let unsubscribed = false; + isReady.then(() => { + if (unsubscribed) { + return; + } + unsubFunc = environment.tabDetached(callback); + }); + return () => { + unsubscribed = true; + if (unsubFunc) { + unsubFunc(); + } + }; + } + function onWindowFrameColorChanged(callback) { + let unsubFunc; + let unsubscribed = false; + isReady.then(() => { + if (unsubscribed) { + return; + } + unsubFunc = environment.onWindowFrameColorChanged(callback); + }); + return () => { + unsubscribed = true; + if (unsubFunc) { + unsubFunc(); + } + }; + } + function onWindowGotFocus(callback) { + let unsubFunc; + let unsubscribed = false; + isReady.then(() => { + if (unsubscribed) { + return; + } + unsubFunc = environment.onWindowGotFocus(callback); + }); + return () => { + unsubscribed = true; + if (unsubFunc) { + unsubFunc(); + } + }; + } + function onWindowLostFocus(callback) { + let unsubFunc; + let unsubscribed = false; + isReady.then(() => { + if (unsubscribed) { + return; + } + unsubFunc = environment.onWindowLostFocus(callback); + }); + return () => { + unsubscribed = true; + if (unsubFunc) { + unsubFunc(); + } + }; + } + function onArrangementChanged(callback) { + return environment.onWindowsAutoArrangeChanged(callback); + } + function onEvent(callback) { + let unsubFunc; + let unsubscribed = false; + isReady.then(() => { + if (unsubscribed) { + return; + } + unsubFunc = environment.onEvent(callback); + }); + return () => { + unsubscribed = true; + if (unsubFunc) { + unsubFunc(); + } + }; + } + function createFlydown(targetId, config) { + return environment.createFlydown(targetId, config); + } + function showPopup(targetId, config) { + return environment.showPopup(targetId, config); + } + function handleWindowAdded(w) { + _registry.execute("window-added", w.API); + } + function handleWindowRemoved(w) { + _registry.execute("window-removed", w.API); + } + windowStore.onReadyWindow(handleWindowAdded); + windowStore.onRemoved(handleWindowRemoved); + return { + my, + open, + find, + findById, + list, + ready, + onWindowAdded: windowAdded, + windowAdded, + onWindowRemoved: windowRemoved, + windowRemoved, + onTabAttached: tabAttached, + onTabDetached: tabDetached, + onWindowFrameColorChanged, + onArrangementChanged, + get groups() { + return groups.groupsAPI; + }, + onWindowGotFocus, + onWindowLostFocus, + onEvent, + createFlydown, + showPopup, + configure, + autoArrange + }; + }; + + class LayoutStore { + constructor() { + this.layouts = []; + } + removeWhere(condition) { + this.layouts = this.layouts.filter(condition); + } + removeAll() { + this.layouts = []; + } + add(item) { + this.layouts.push(item); + } + get all() { + return this.layouts; + } + where(condition) { + return this.layouts.filter(condition); + } + first(condition) { + return this.where(condition)[0]; + } + } + var store = new LayoutStore(); + + const SaveContextMethodName = "T42.HC.GetSaveContext"; + class ContextProvider { + constructor(config, activitiesGetter, callbacks, logger) { + this.config = config; + this.activitiesGetter = activitiesGetter; + this.callbacks = callbacks; + this.logger = logger; + this.interop = config.agm; + this.registerRequestMethods(); + } + onSaveRequested(callback) { + return this.callbacks.add("saveRequested", callback); + } + isActivityOwner() { + if (typeof htmlContainer !== "undefined") { + const context = htmlContainer.getContext(); + return context && context._t42 && context._t42.activityIsOwner; + } + const activities = this.activitiesGetter(); + if (!activities) { + return false; + } + if (!activities.inActivity) { + return false; + } + const myWindow = activities.my.window; + const myActivity = activities.my.activity; + if (!myActivity && !myWindow) { + return false; + } + return myActivity.owner.id === myWindow.id; + } + registerRequestMethods() { + this.interop.register(SaveContextMethodName, (args) => { + const usersCbs = this.callbacks.execute("saveRequested", args); + if ((usersCbs === null || usersCbs === void 0 ? void 0 : usersCbs.length) > 1) { + this.logger.warn(`Multiple subscriptions for "glue.layouts.onSaveRequested" - only the first one will be used`); + } + const requestResult = usersCbs[0]; + const autoSaveWindowContext = this.config.autoSaveWindowContext; + if (typeof autoSaveWindowContext === "boolean" && autoSaveWindowContext) { + return { autoSaveWindowContext }; + } + else if (Array.isArray(autoSaveWindowContext) && autoSaveWindowContext.length > 0) { + return { autoSaveWindowContext }; + } + const result = { windowContext: requestResult === null || requestResult === void 0 ? void 0 : requestResult.windowContext, activityContext: undefined }; + if (this.isActivityOwner()) { + result.activityContext = requestResult === null || requestResult === void 0 ? void 0 : requestResult.activityContext; + } + return result; + }); + } + } + + function transformACSLayout(something) { + if (!something) { + return something; + } + if (Array.isArray(something)) { + return something.map((item) => { + return transformACSLayout(item); + }); + } + if (typeof something === "string" || typeof something === "number" || typeof something === "boolean") { + return something; + } + const initial = {}; + return Object.keys(something).reduce((accumulator, current) => { + var _a; + const value = something[current]; + const convertedValue = transformACSLayout(value); + let key = current; + if (((_a = current[0]) === null || _a === void 0 ? void 0 : _a.toLowerCase()) !== current[0]) { + key = current[0].toLowerCase() + current.substr(1); + } + accumulator[key] = convertedValue; + return accumulator; + }, initial); + } + + class LayoutImpl { + constructor(data) { + this.name = data.name; + this.type = data.type; + this.components = data.components; + this.context = data.context; + this.metadata = data.metadata; + this.version = data.version; + this.displays = data.displays; + } + } + + var main = {}; + + var application = {}; + + /** + * This file was automatically generated by json-schema-to-typescript. + * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file, + * and run json-schema-to-typescript to regenerate this file. + */ + Object.defineProperty(application, "__esModule", { value: true }); + + var system = {}; + + /** + * This file was automatically generated by json-schema-to-typescript. + * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file, + * and run json-schema-to-typescript to regenerate this file. + */ + Object.defineProperty(system, "__esModule", { value: true }); + + var layout = {}; + + Object.defineProperty(layout, "__esModule", { value: true }); + layout.SwimlaneItemType = layout.LayoutType = void 0; + var LayoutType; + (function (LayoutType) { + LayoutType["Global"] = "Global"; + LayoutType["Activity"] = "Activity"; + LayoutType["ApplicationDefault"] = "ApplicationDefault"; + LayoutType["Swimlane"] = "Swimlane"; + LayoutType["Workspaces"] = "Workspace"; + })(LayoutType || (layout.LayoutType = LayoutType = {})); + var SwimlaneItemType; + (function (SwimlaneItemType) { + SwimlaneItemType["Tab"] = "tab"; + SwimlaneItemType["Window"] = "window"; + SwimlaneItemType["Canvas"] = "canvas"; + })(SwimlaneItemType || (layout.SwimlaneItemType = SwimlaneItemType = {})); + + var swTheme = {}; + + /** + * This file was automatically generated by json-schema-to-typescript. + * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file, + * and run json-schema-to-typescript to regenerate this file. + */ + Object.defineProperty(swTheme, "__esModule", { value: true }); + + var swConfiguration = {}; + + /** + * This file was automatically generated by json-schema-to-typescript. + * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file, + * and run json-schema-to-typescript to regenerate this file. + */ + Object.defineProperty(swConfiguration, "__esModule", { value: true }); + + (function (exports) { + var __createBinding = (commonjsGlobal && commonjsGlobal.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; + })); + var __exportStar = (commonjsGlobal && commonjsGlobal.__exportStar) || function(m, exports) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); + }; + Object.defineProperty(exports, "__esModule", { value: true }); + // export { SchemaValidator } from "./validator"; + // export { FileProvider } from "./fileProvider"; + // export { SchemaProvider } from "./provider"; + __exportStar(application, exports); + __exportStar(system, exports); + __exportStar(layout, exports); + __exportStar(swTheme, exports); + __exportStar(swConfiguration, exports); + + } (main)); + + const LayoutsCommandMethod = "T42.ACS.Command"; + class LayoutsAPIImpl { + constructor(config, stream, callbacks, logger) { + this.config = config; + this.stream = stream; + this.callbacks = callbacks; + this.isRegisterMethodForLayoutModified = false; + this.appManager = config.appManager; + this.provider = new ContextProvider(config, config.activityGetter, callbacks, logger); + stream.subscribe(); + } + async setDefaultGlobal(name) { + const methodName = "SelectDefaultLayout"; + await this.invokeMethodCore(methodName, { name }); + return; + } + async clearDefaultGlobal() { + const methodName = "DeselectDefaultLayout"; + await this.invokeMethodCore(methodName); + return; + } + async getDefaultGlobal() { + const methodName = "GetDefaultLayout"; + const result = await this.invokeMethodCore(methodName); + const layout = result.returned; + if (layout === null || layout === undefined || (typeof layout === 'object' && Object.keys(layout).length === 0)) { + return undefined; + } + return objectClone(this.isSlimMode() ? layout : this.list().find((l) => l.name === layout.name && l.type === layout.type)); + } + ready() { + if (this.config.mode === "fullWaitSnapshot") { + return this.stream.gotSnapshot; + } + return this.stream.ready; + } + save(layout) { + return new Promise((resolve, reject) => { + var _a, _b; + this.verifyNotSlimMode(); + if (isUndefinedOrNull(layout)) { + return reject(new Error("layout is required")); + } + if (isNullOrWhiteSpace(layout.name)) { + return reject(new Error("layout.name argument is required")); + } + if (isNullOrWhiteSpace(layout.type)) { + layout.type = "Global"; + } + if (!isNullOrWhiteSpace(layout.activityId)) { + layout.type = "Activity"; + } + const layoutObject = { + name: layout.name, + type: layout.type, + context: (_a = layout.context) !== null && _a !== void 0 ? _a : {}, + metadata: (_b = layout.metadata) !== null && _b !== void 0 ? _b : {}, + options: {}, + }; + if (layout.type === "Activity") { + let actId = layout.activityId; + if (!actId) { + if (!this.appManager.myInstance.inActivity) { + return reject(new Error("Current application is not in activity. Cannot save activity layout for it.")); + } + actId = this.appManager.myInstance.activityId; + } + layoutObject.activityId = actId; + } + else if (layout.type === "Global") { + if (Array.isArray(layout.ignoreInstances)) { + layoutObject.options.ignoreInstances = layout.ignoreInstances; + } + if (Array.isArray(layout.instances)) { + layoutObject.options.instances = layout.instances; + } + if (typeof layout.setAsCurrent === "boolean") { + layoutObject.options.setAsCurrent = layout.setAsCurrent; + } + } + else { + return reject(new Error(`layout type ${layout.type} is not supported`)); + } + this.invokeMethodAndTrack("SaveLayout", layoutObject, resolve, reject); + }); + } + restore(options) { + return new Promise((resolve, reject) => { + var _a, _b, _c; + this.verifyNotSlimMode(); + if (isUndefinedOrNull(options)) { + return reject(new Error("options argument is required")); + } + if (isNullOrWhiteSpace(options.name)) { + return reject(new Error("options.name argument is required")); + } + if (isNullOrWhiteSpace(options.type)) { + options.type = "Global"; + } + if (!isNullOrWhiteSpace(options.activityIdToJoin)) { + options.type = "Activity"; + } + if (options.type === "Activity") { + if (isUndefinedOrNull(options.setActivityContext)) { + options.setActivityContext = true; + } + if (typeof options.setActivityContext !== "boolean") { + return reject(new Error("`setActivityContext` must hold a boolean value.")); + } + options.activityIdToJoin = (_a = options.activityIdToJoin) !== null && _a !== void 0 ? _a : this.appManager.myInstance.activityId; + } + if (!isUndefinedOrNull(options.closeRunningInstance)) { + options.closeRunningInstances = options.closeRunningInstance; + } + if (isUndefinedOrNull(options.closeRunningInstances)) { + options.closeRunningInstances = true; + } + if (!isBoolean(options.closeRunningInstances)) { + return reject(new Error("`closeRunningInstances` must hold a boolean value.")); + } + if (isUndefinedOrNull(options.closeMe)) { + options.closeMe = options.closeRunningInstances; + } + if (!isBoolean(options.closeMe)) { + return reject(new Error("`closeMe` must hold a boolean value.")); + } + if (!isUndefinedOrNull(options.context) && !isObject(options.context)) { + return reject(new Error("`context` must hold an object value.")); + } + if (!isUndefinedOrNull(options.timeout) && typeof options.timeout !== "number") { + return reject(new Error("`timeout` must hold an number value.")); + } + options.context = (_b = options.context) !== null && _b !== void 0 ? _b : {}; + const restoreOptions = { + activityToJoin: options.activityIdToJoin, + setActivityContext: options.setActivityContext, + ignoreActivityWindowTypes: options.ignoreActivityWindowTypes, + reuseExistingWindows: options.reuseWindows, + closeRunningInstances: options.closeRunningInstances, + excludeFromClosing: options.closeMe ? [] : [(_c = this.appManager.myInstance) === null || _c === void 0 ? void 0 : _c.id] + }; + const arg = { + type: options.type, + name: options.name, + context: options.context, + options: restoreOptions + }; + if (options.timeout) { + arg.timeout = options.timeout; + } + this.invokeMethodAndTrack("RestoreLayout", arg, resolve, reject, true); + }); + } + reset(options) { + return new Promise((resolve, reject) => { + this.verifyNotSlimMode(); + if (typeof options !== "object") { + return reject(new Error("options argument is required")); + } + if (isNullOrWhiteSpace(options.layoutId)) { + return reject(new Error("options.layoutId argument is required")); + } + const msg = { + ...options + }; + this.invokeMethodAndTrack("ResetLayout", msg, resolve, reject, true); + }); + } + remove(type, name) { + return new Promise((resolve, reject) => { + this.verifyNotSlimMode(); + if (!name) { + return reject(new Error("name argument is required")); + } + if (!type) { + return reject(new Error("type argument is required")); + } + const msg = { + type, + name, + }; + this.invokeMethodAndTrack("RemoveLayout", msg, resolve, reject); + }); + } + list() { + this.verifyNotSlimMode(); + return objectClone(store.all); + } + import(layouts, mode) { + return new Promise((resolve, reject) => { + this.verifyNotSlimMode(); + if (!isUndefinedOrNull(mode)) { + if (mode !== "merge" && mode !== "replace") { + return reject(new Error(`${mode} is not supported - only "merge" and "replace"`)); + } + } + if (!Array.isArray(layouts)) { + return reject(new Error("layouts arguments is not an array")); + } + const msg = { + mode: mode || "replace", + layouts + }; + this.invokeMethodAndTrack("ImportLayouts", msg, resolve, reject, true); + }); + } + export(layoutType) { + return new Promise((resolve, reject) => { + var _a; + if (!isUndefinedOrNull(layoutType) && !((_a = Object.values(main.LayoutType)) === null || _a === void 0 ? void 0 : _a.includes(layoutType))) { + return reject(new Error(`${layoutType} is not a supported Layout Type`)); + } + const handleResult = (result) => { + let layouts = this.getObjectValues(result.Layouts).map((t) => new LayoutImpl(transformACSLayout(t))); + if (layoutType) { + layouts = layouts.filter((l) => l.type === layoutType); + } + resolve(layouts); + }; + this.invokeMethodAndTrack("ExportLayouts", {}, handleResult, reject, true); + }); + } + rename(layout, newName) { + return new Promise((resolve, reject) => { + this.verifyNotSlimMode(); + if (!layout) { + return reject(new Error("layout argument is required")); + } + if (!layout.name) { + return reject(new Error("name argument is required")); + } + if (!layout.type) { + return reject(new Error("type argument is required")); + } + const msg = { type: layout.type, oldName: layout.name, newName }; + this.invokeMethodAndTrack("RenameLayout", msg, resolve, reject); + }); + } + updateMetadata(layout) { + return new Promise((resolve, reject) => { + if (!layout) { + return reject(new Error("layout argument is required")); + } + if (!layout.name) { + return reject(new Error("name argument is required")); + } + if (!layout.type) { + return reject(new Error("type argument is required")); + } + if (!layout.metadata) { + return reject(new Error("metadata argument is required")); + } + const layoutObject = { + name: layout.name, + type: layout.type, + metadata: layout.metadata + }; + this.invokeMethodAndTrack("UpdateMetadata", layoutObject, resolve, reject, true); + }); + } + hibernate(name, options) { + return new Promise((resolve, reject) => { + if (!name) { + return reject(new Error("name cannot be empty")); + } + options = options || {}; + const request = { + name, + type: "Global", + context: options.context || {}, + metadata: options.metadata || {}, + }; + this.invokeMethodAndTrack("HibernateLayout", request, resolve, reject, true); + }); + } + resume(name, context, options) { + return new Promise((resolve, reject) => { + if (!name) { + return reject(new Error("name cannot be empty")); + } + const request = { + name, + type: "Global", + context, + ...options + }; + this.invokeMethodAndTrack("ResumeLayout", request, resolve, reject, true); + }); + } + async getCurrentLayout() { + const methodName = "GetCurrentLayout"; + const result = await this.invokeMethodCore(methodName); + let layout = result.returned.layout; + if (!layout) { + return undefined; + } + if (!this.isSlimMode()) { + layout = this.list().find((l) => l.name === layout.name && l.type === layout.type); + } + return objectClone(layout); + } + getRestoredLayoutsInfo() { + return new Promise((resolve, reject) => { + const methodName = "GetRestoredLayoutsInfo"; + this.invokeMethodCore(methodName) + .then((result) => { + const restoredLayouts = result.returned; + resolve(restoredLayouts); + }) + .catch(reject); + }); + } + onAdded(callback) { + const result = this.callbacks.add("added", callback); + if (store.all.length > 0) { + store.all.forEach((layout) => { + try { + callback(layout); + } + catch (err) { } + }); + } + return result; + } + onRemoved(callback) { + return this.callbacks.add("removed", callback); + } + onChanged(callback) { + return this.callbacks.add("changed", callback); + } + onRestored(callback) { + return this.callbacks.add("restored", callback); + } + onRenamed(callback) { + return this.callbacks.add("renamed", callback); + } + onEvent(callback) { + return this.stream.onEvent(callback); + } + onSaveRequested(callback) { + return this.provider.onSaveRequested(callback); + } + onLayoutModified(callback) { + if (this.isRegisterMethodForLayoutModified === false) { + this.isRegisterMethodForLayoutModified = true; + this.registerMethodForLayoutModified(); + } + return this.callbacks.add("layout-modified", callback); + } + updateAppContextInCurrent(context) { + return new Promise((resolve, reject) => { + if (context && typeof context !== "object") { + return reject(new Error("Context must be an object")); + } + context = context !== null && context !== void 0 ? context : {}; + const request = { + context + }; + this.invokeMethodAndTrack("UpdateLayoutComponentContext", request, resolve, reject, true); + }); + } + updateDefaultContext(context) { + return new Promise((resolve, reject) => { + if (context && typeof context !== "object") { + return reject(new Error("Context must be an object")); + } + context = context !== null && context !== void 0 ? context : {}; + const request = { + context + }; + this.invokeMethodAndTrack("UpdateDefaultContext", request, resolve, reject, true); + }); + } + async get(name, type) { + const matching = this.list().find((l) => l.name === name && l.type === type); + if (!matching) { + throw new Error(`cannot find layout with name=${name} and type=${type}`); + } + return objectClone(matching); + } + async getAll(type) { + var _a; + if (!isUndefinedOrNull(type) && !((_a = Object.values(main.LayoutType)) === null || _a === void 0 ? void 0 : _a.includes(type))) { + throw new Error((`${type} is not a supported Layout Type`)); + } + const matching = this.list().filter((l) => type === l.type); + return objectClone(matching); + } + async forceRefresh() { + const methodName = "RefreshLayouts"; + await this.invokeMethodCore(methodName); + } + isSlimMode() { + return this.config.mode === "slim"; + } + verifyNotSlimMode() { + if (this.isSlimMode()) { + throw Error("Operation not allowed in slim mode. Run in full mode."); + } + } + async registerMethodForLayoutModified() { + await this.config.agm.register("T42.ACS.LayoutModified", (args, caller) => { + this.callbacks.execute("layout-modified", args); + }); + } + invokeMethodAndTrack(methodName, args, resolve, reject, skipStreamEvent) { + let streamEventReceived = skipStreamEvent; + let agmResult; + const token = Utils.generateId(); + args.token = token; + const handleResult = () => { + if (streamEventReceived && agmResult) { + resolve(agmResult); + } + }; + const methodResponseTimeoutMs = 120 * 1000; + if (!skipStreamEvent) { + this.stream.waitFor(token, methodResponseTimeoutMs) + .then(() => { + streamEventReceived = true; + handleResult(); + }) + .catch((err) => { + reject(err); + }); + } + const responseHandler = (result) => { + if (!result.returned) { + return reject(new Error("No result from method " + methodName)); + } + if (result.returned.status && (result.returned.status !== "Success" && result.returned.status !== "PartialSuccess")) { + if (typeof (result.returned) === "string") { + return reject(new Error(result.returned)); + } + else if (typeof (result.returned) === "object") { + if (result.returned.status && result.returned.failed) { + return reject(new Error(`${result.returned.status}: ${JSON.stringify(result.returned.failed)}`)); + } + else { + return reject(new Error(result.returned)); + } + } + } + agmResult = result.returned; + handleResult(); + }; + this.invokeMethodCore(methodName, args, "best", { methodResponseTimeoutMs }) + .then(responseHandler) + .catch((err) => reject(err)); + } + async invokeMethodCore(methodName, args, target, options) { + options = options !== null && options !== void 0 ? options : {}; + if (typeof options.methodResponseTimeoutMs === "undefined") { + options.methodResponseTimeoutMs = INTEROP_METHOD_WAIT_TIMEOUT_MS; + } + if (typeof options.waitTimeoutMs === "undefined") { + options.waitTimeoutMs = INTEROP_METHOD_WAIT_TIMEOUT_MS; + } + if (this.isCommandMethodPresent()) { + return await this.config.agm.invoke(LayoutsCommandMethod, { command: methodName, data: args }, target, options); + } + else { + return await this.config.agm.invoke(`T42.ACS.${methodName}`, args, target, options); + } + } + getObjectValues(obj) { + if (!obj) { + return []; + } + return Object.keys(obj).map((k) => obj[k]); + } + isCommandMethodPresent() { + return this.config.agm.methods().some((method) => method.name === LayoutsCommandMethod); + } + } + + class ACSStream { + constructor(agm, callbacks) { + this.agm = agm; + this.callbacks = callbacks; + this.StreamName = "T42.ACS.OnLayoutEvent"; + this.ready = new Promise((resolve, reject) => { + this.resolveReady = resolve; + this.rejectReady = reject; + }); + this.gotSnapshot = new Promise((resolve, reject) => { + this.resolveGotSnapshot = resolve; + this.rejectGotSnapshot = reject; + }); + } + subscribe(noRetry) { + const transform = (obj) => { + return this.getObjectValues(obj).map((t) => transformACSLayout(t)); + }; + if (!this.checkForLayoutEventMethod()) { + if (noRetry) { + this.resolveReady(); + } + setTimeout(() => { + this.subscribe(true); + }, 500); + } + else { + this.agm.subscribe(this.StreamName, { waitTimeoutMs: 10000 }) + .then((subs) => { + subs.onData((args) => { + const data = args.data; + if (data.IsSnapshot) { + this.resolveGotSnapshot(); + } + this.addLayouts(transform(data.OnLayoutAdded), data.IsSnapshot); + this.removeLayouts(transform(data.OnLayoutRemoved)); + this.changeLayouts(transform(data.OnLayoutChanged)); + this.renameLayouts(transform(data.OnLayoutRenamed)); + this.restoredLayout(transform(data.OnLayoutRestored)); + this.callbacks.execute("streamEvent", data); + }); + subs.onFailed((err) => { + const msg = `Can not subscribe to "${this.StreamName}" stream - ${JSON.stringify(err)}`; + this.rejectReady(msg); + this.rejectGotSnapshot(msg); + }); + this.resolveReady(); + }) + .catch((err) => { + const msg = `Error subscribing to "${this.StreamName}" stream - ${JSON.stringify(err)}`; + this.rejectReady(msg); + this.rejectGotSnapshot(msg); + }); + } + } + onEvent(callback) { + return this.callbacks.add("streamEvent", callback); + } + waitFor(token, timeout) { + if (!timeout) { + timeout = 30000; + } + return new Promise((resolve, reject) => { + let done = false; + const unsubscribe = this.onEvent((streamEvent) => { + if (streamEvent.Token === token) { + done = true; + unsubscribe(); + resolve(); + } + }); + setTimeout(() => { + if (!done) { + reject("timed out"); + } + }, timeout); + }); + } + checkForLayoutEventMethod() { + try { + return this.agm + .methods() + .map((m) => m.name) + .indexOf(this.StreamName) !== -1; + } + catch (e) { + return false; + } + } + addLayouts(layoutsData, isSnapshot) { + if (!layoutsData) { + return; + } + const createAndNotifyLayout = (layoutData) => { + const layout = new LayoutImpl(layoutData); + store.add(layout); + this.callbacks.execute("added", layout); + }; + layoutsData.forEach((layoutData) => { + if (isSnapshot) { + const found = store.first((existingLayout) => this.compareLayouts(existingLayout, layoutData)); + if (!found) { + createAndNotifyLayout(layoutData); + } + } + else { + createAndNotifyLayout(layoutData); + } + }); + } + removeLayouts(removedLayouts) { + if (!removedLayouts) { + return; + } + removedLayouts.forEach((removedLayout) => { + store.removeWhere((existingLayout) => !this.compareLayouts(existingLayout, removedLayout)); + this.callbacks.execute("removed", removedLayout); + }); + } + changeLayouts(changedLayouts) { + if (!changedLayouts) { + return; + } + changedLayouts.forEach((changedLayout) => { + store.removeWhere((existingLayout) => !this.compareLayouts(existingLayout, changedLayout)); + store.add(new LayoutImpl(changedLayout)); + this.callbacks.execute("changed", changedLayout); + }); + } + renameLayouts(renamedLayouts) { + if (!renamedLayouts) { + return; + } + renamedLayouts.forEach((renamedLayout) => { + const existingLayout = store.first((current) => this.compareLayouts(current, { type: renamedLayout.type, name: renamedLayout.oldName })); + if (!existingLayout) { + throw Error(`received rename event for unknown layout with type ${renamedLayout.type} and name ${renamedLayout.oldName}`); + } + existingLayout.name = renamedLayout.newName; + this.callbacks.execute("renamed", existingLayout); + }); + } + compareLayouts(layout1, layout2) { + return layout1.name === layout2.name && layout1.type === layout2.type; + } + getObjectValues(obj) { + if (!obj) { + return []; + } + return Object.keys(obj).map((k) => obj[k]); + } + restoredLayout(restoredLayouts) { + if (!restoredLayouts) { + return; + } + restoredLayouts.forEach((restoredLayout) => { + const existingLayout = store.first((current) => this.compareLayouts(current, { type: restoredLayout.type, name: restoredLayout.name })); + this.callbacks.execute("restored", existingLayout); + }); + } + } + + function LayoutsFactory (config) { + if (!config.agm) { + throw Error("config.agm is required"); + } + if (!config.logger) { + throw Error("config.logger is required"); + } + config.mode = config.mode || "slim"; + const logger = config.logger; + const callbacks = CallbackRegistryFactory(); + let acsStream; + if (config.mode === "full" || "fullWaitSnapshot") { + acsStream = new ACSStream(config.agm, callbacks); + } + return new LayoutsAPIImpl(config, acsStream, callbacks, logger); + } + + const T42DisplayCommand = "T42.Displays.Command"; + const T42DisplayOnEvent = "T42.Displays.OnEvent"; + class DisplayManager { + constructor(_agm, _logger) { + this._agm = _agm; + this._logger = _logger; + this._registry = CallbackRegistryFactory(); + this._registered = false; + this.all = async () => { + const displays = await this.callGD(DisplayCommand.GetAll, {}); + return displays.map(this.decorateDisplay); + }; + this.get = async (id) => { + const display = await this.callGD(DisplayCommand.Get, { id }); + return this.decorateDisplay(display); + }; + this.getPrimary = async () => { + const primary = (await this.all()).find((d) => d.isPrimary); + return primary; + }; + this.capture = async (options) => { + const screenshot = await this.callGD(DisplayCommand.Capture, { ...options }); + return screenshot; + }; + this.captureAll = async (options) => { + const screenshots = await this.callGD(DisplayCommand.CaptureAll, { ...options }); + return screenshots; + }; + this.getMousePosition = async () => { + const point = await this.callGD(DisplayCommand.GetMousePosition); + return point; + }; + this.callGD = async (command, options) => { + const invocationResult = await this._agm.invoke(T42DisplayCommand, { options: { ...options }, command }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return invocationResult.returned.data; + }; + this.decorateDisplay = (original) => { + const decoratedDisplay = { + ...original, + capture: (size) => this.capture({ id: original.id, size }) + }; + const workAreaAsAny = decoratedDisplay.workArea; + workAreaAsAny.x = workAreaAsAny.left; + workAreaAsAny.y = decoratedDisplay.workArea.top; + return decoratedDisplay; + }; + } + getByWindowId(id) { + const current = this.callGD(DisplayCommand.GetByWindowId, { id }); + return current; + } + onDisplayChanged(cb) { + this.register(); + return this._registry.add("on-display-changed", cb); + } + register() { + if (this._registered) { + return; + } + this._registered = true; + this._agm.register(T42DisplayOnEvent, (args, caller) => { + const event = args.event; + const data = args.data; + switch (event) { + case "display-changed": + this._registry.execute("on-display-changed", data.displays.map(this.decorateDisplay)); + break; + default: + this._logger.warn(`unknown event - ${event}`); + break; + } + }); + } + } + var DisplayCommand; + (function (DisplayCommand) { + DisplayCommand["Capture"] = "capture"; + DisplayCommand["CaptureAll"] = "captureAll"; + DisplayCommand["GetAll"] = "getAll"; + DisplayCommand["Get"] = "get"; + DisplayCommand["GetByWindowId"] = "getByWindowId"; + DisplayCommand["GetMousePosition"] = "getMousePosition"; + })(DisplayCommand || (DisplayCommand = {})); + + class SingleChannelID { + constructor(channel) { + this.channel = channel; + } + get isJoinedToAnyChannel() { + return !!this.channel; + } + isOnChannel(channel) { + return this.channel === channel; + } + leaveChannel(channel) { + if (channel === undefined || this.channel === channel) { + this.channel = undefined; + } + } + joinChannel(channel) { + this.channel = channel; + } + all() { + if (this.channel) { + return [this.channel]; + } + return []; + } + toString() { + return this.channel; + } + equals(other) { + if (other instanceof SingleChannelID) { + return this.channel === other.channel; + } + return false; + } + } + class MultiChannelId { + constructor(channels) { + this.ChannelDelimiter = "+++"; + if (!channels) { + this.channels = []; + } + else if (typeof channels === "string") { + this.channels = channels === null || channels === void 0 ? void 0 : channels.split(this.ChannelDelimiter).filter(Boolean); + } + else { + this.channels = (channels !== null && channels !== void 0 ? channels : []).filter(Boolean); + } + } + get isJoinedToAnyChannel() { + return this.channels.length > 0; + } + isOnChannel(channel) { + return this.channels.includes(channel); + } + joinChannel(channel) { + const newChannels = new MultiChannelId(channel); + newChannels.all().forEach((newChannel) => { + if (!this.channels.includes(newChannel)) { + this.channels.push(newChannel); + } + }); + } + leaveChannel(channel) { + const channelsToLeave = new MultiChannelId(channel !== null && channel !== void 0 ? channel : this.channels); + channelsToLeave.all().forEach((c) => { + this.channels = this.channels.filter((ch) => ch !== c); + }); + } + all() { + return this.channels; + } + toString() { + if (this.channels.length === 0) { + return undefined; + } + return this.channels.join(this.ChannelDelimiter); + } + equals(other) { + if (other instanceof MultiChannelId) { + return this.channels.length === other.channels.length && + this.channels.every((c, i) => c === other.channels[i]); + } + return false; + } + } + + let interop; + let myInstanceId; + let logger; + const T42_ANNOUNCE_METHOD_NAME = "T42.Channels.Announce"; + const T42_COMMAND_METHOD_NAME = "T42.Channels.Command"; + async function setupInterop(interopLib, channels, loggerAPI) { + var _a, _b; + logger = loggerAPI; + interop = interopLib; + if (typeof window !== "undefined") { + if (window.glue42gd) { + myInstanceId = window.glue42gd.windowId; + } + } + if (!myInstanceId) { + myInstanceId = interopLib.instance.instance; + } + await interop.register(T42_COMMAND_METHOD_NAME, (args) => { + const command = args.command; + if (!command) { + throw new Error("missing command argument"); + } + logger.trace(`received command "${command}" with ${JSON.stringify(args)}`); + if (command === "join") { + const id = args.channel; + if (!id) { + throw new Error("missing argument id"); + } + return channels.joinNoSelectorSwitch(id); + } + if (command === "leave") { + return channels.leaveNoSelectorSwitch(); + } + if (command === "get") { + const id = channels.current(); + return { id }; + } + if (command === "restrictions-changed") { + const restrictions = args.restrictions; + const targetWindowId = args.swId; + channels.handleRestrictionsChanged(restrictions, targetWindowId); + return; + } + if (command === "isFdc3DataWrappingSupported") { + return { isSupported: true }; + } + if (command === "join-multi") { + const channelsToJoin = args.channelsToJoin; + if (!channelsToJoin) { + throw new Error("missing argument channelsToJoin"); + } + return channels.joinNoSelectorSwitch(new MultiChannelId(channelsToJoin).toString()); + } + if (command === "leave-multi") { + const channelsToLeave = args.channelsToLeave; + return channels.leaveNoSelectorSwitch(new MultiChannelId(channelsToLeave).toString()); + } + throw new Error(`unknown command ${command}`); + }); + const result = await interop.invoke(T42_ANNOUNCE_METHOD_NAME, { swId: myInstanceId, instance: interop.instance.instance }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_RESPONSE_TIMEOUT_MS + }); + if ((_a = result.returned) === null || _a === void 0 ? void 0 : _a.restrictions) { + channels.handleRestrictionsChanged((_b = result.returned) === null || _b === void 0 ? void 0 : _b.restrictions, myInstanceId); + } + return result.returned; + } + async function sendLeaveChannel(channel, winId) { + var _a; + await invoke("leaveChannel", { channel }, (_a = winId !== null && winId !== void 0 ? winId : winId) !== null && _a !== void 0 ? _a : myInstanceId); + } + async function sendSwitchChannelUI(channel, winId) { + await invoke("switchChannel", { newChannel: channel }, winId !== null && winId !== void 0 ? winId : myInstanceId); + } + async function setRestrictions(restrictions) { + var _a; + await invoke("restrict", restrictions, (_a = restrictions.windowId) !== null && _a !== void 0 ? _a : myInstanceId); + } + async function getRestrictionsByWindow(id) { + try { + const result = await invoke("getRestrictions", {}, id !== null && id !== void 0 ? id : myInstanceId); + return result.returned; + } + catch (e) { + } + } + async function setRestrictionsForAllChannels(restrictions) { + var _a; + await invoke("restrictAll", restrictions, (_a = restrictions.windowId) !== null && _a !== void 0 ? _a : myInstanceId); + } + async function getChannelsInfo(filter) { + const result = await invoke("getChannelsInfo", { filter }); + return result.returned; + } + async function addOrRemoveChannel(command, id, color, label) { + await invoke(command, { id, color, label }); + } + async function getChannelInitInfo(config, i) { + if (typeof config.operationMode !== "boolean" && typeof config.operationMode === "string") { + validateMode(config.operationMode); + return { mode: config.operationMode, initialChannel: undefined }; + } + try { + const result = await i.invoke(T42_ANNOUNCE_METHOD_NAME, { command: "getChannelsMode" }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_RESPONSE_TIMEOUT_MS, + }); + const initialChannel = result.returned.initialChannel; + if (result.returned.mode === "single") { + return { + mode: "single", + initialChannel + }; + } + else if (result.returned.mode === "multi") { + return { + mode: "multi", + initialChannel + }; + } + else { + return { + mode: "single", + initialChannel + }; + } + } + catch (e) { + return { mode: "single", initialChannel: undefined }; + } + } + function invoke(command, data, swId) { + const args = { command, data }; + if (swId) { + args.swId = swId; + } + return interop.invoke(T42_ANNOUNCE_METHOD_NAME, args, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_RESPONSE_TIMEOUT_MS, + }); + } + function validateMode(mode) { + if (mode !== "single" && mode !== "multi") { + throw new Error(`Invalid mode: ${mode}`); + } + } + + const CONTEXT_PREFIX = "___channel___"; + const LATEST_FDC3_TYPE = "latest_fdc3_type"; + class BaseSharedContextSubscriber { + constructor(contexts) { + this.contexts = contexts; + } + subscribe(callback) { + this.callback = callback; + } + subscribeFor(name, callback) { + if (!this.isChannel(name)) { + return Promise.reject(new Error(`Channel with name: ${name} doesn't exist!`)); + } + const contextName = this.createContextName(name); + return this.contexts.subscribe(contextName, (data, _, __, ___, extraData) => { + callback(data.data, data, extraData === null || extraData === void 0 ? void 0 : extraData.updaterId); + }); + } + all() { + const contextNames = this.contexts.all(); + const channelContextNames = contextNames.filter((contextName) => contextName.startsWith(CONTEXT_PREFIX)); + const channelNames = channelContextNames.map((channelContextName) => channelContextName.substr(CONTEXT_PREFIX.length)); + return channelNames; + } + async getContextData(name) { + if (!this.isChannel(name)) { + throw new Error(`A channel with name: ${name} doesn't exist!`); + } + const contextName = this.createContextName(name); + const contextData = await this.contexts.get(contextName); + if (contextData[LATEST_FDC3_TYPE]) { + return this.getContextWithFdc3Data(contextData); + } + else { + delete contextData[LATEST_FDC3_TYPE]; + } + return contextData; + } + updateChannel(name, data) { + const contextName = this.createContextName(name); + return this.contexts.update(contextName, data); + } + updateData(name, data) { + const contextName = this.createContextName(name); + const fdc3Type = this.getFDC3Type(data); + if (this.contexts.setPathSupported) { + const pathValues = Object.keys(data).map((key) => { + return { + path: `data.` + key, + value: data[key] + }; + }); + if (fdc3Type) { + pathValues.push({ path: LATEST_FDC3_TYPE, value: fdc3Type }); + } + return this.contexts.setPaths(contextName, pathValues); + } + else { + if (fdc3Type) { + data[LATEST_FDC3_TYPE] = fdc3Type; + } + return this.contexts.update(contextName, { data }); + } + } + setPaths(name, paths) { + const contextName = this.createContextName(name); + if (this.contexts.setPathSupported) { + const pathValues = paths.map((p) => { + return { + path: `data.` + p.path, + value: p.value + }; + }); + pathValues.map((p) => { + const fdc3Type = this.getFDC3Type(p.value); + if (fdc3Type) { + pathValues.push({ path: LATEST_FDC3_TYPE, value: fdc3Type }); + } + }); + return this.contexts.setPaths(contextName, pathValues); + } + else { + throw new Error("setPaths is not supported!"); + } + } + clearContextData(name) { + const contextName = this.createContextName(name); + return this.contexts.update(contextName, { data: {}, [LATEST_FDC3_TYPE]: undefined }); + } + isChannel(name) { + return this.all().some((channelName) => channelName === name); + } + async remove(name) { + if (!this.isChannel(name)) { + throw new Error(`A channel with name: ${name} doesn't exist!`); + } + const contextName = this.createContextName(name); + await this.contexts.destroy(contextName); + } + createContextName(name) { + return CONTEXT_PREFIX + name; + } + getFDC3Type(data) { + const fdc3PropsArr = Object.keys(data).filter((key) => key.indexOf("fdc3_") === 0); + if (fdc3PropsArr.length === 0) { + return; + } + if (fdc3PropsArr.length > 1) { + throw new Error("FDC3 does not support updating of multiple context keys"); + } + return fdc3PropsArr[0].split("_").slice(1).join("_"); + } + getContextWithFdc3Data(channelContext) { + const { latest_fdc3_type, ...rest } = channelContext; + const parsedType = latest_fdc3_type.split("&").join("."); + const fdc3Context = { type: parsedType, ...rest.data[`fdc3_${latest_fdc3_type}`] }; + delete rest.data[`fdc3_${latest_fdc3_type}`]; + const context = { + name: channelContext.name, + meta: channelContext.meta, + data: { + ...rest.data, + fdc3: fdc3Context + } + }; + return context; + } + } + class MultiSharedContextSubscriber extends BaseSharedContextSubscriber { + constructor() { + super(...arguments); + this.currentlySubscribedChannels = []; + this.unsubscribeMap = {}; + } + async switchChannel(id) { + const newChannels = new MultiChannelId(id).all(); + for (const newChannel of newChannels) { + if (!this.currentlySubscribedChannels.includes(newChannel)) { + await this.subscribeToChannel(newChannel); + } + } + } + async leave(id) { + const channelsToLeave = new MultiChannelId(id).all(); + for (const newChannel of channelsToLeave) { + if (this.currentlySubscribedChannels.includes(newChannel)) { + this.unsubscribeFromChannel(newChannel); + } + } + } + async updateData(id, data) { + const channels = new MultiChannelId(id).all(); + for (const channel of channels) { + await super.updateData(channel, data); + } + } + async setPaths(id, paths) { + const channels = new MultiChannelId(id).all(); + for (const channel of channels) { + await super.setPaths(channel, paths); + } + } + isChannel(name) { + const channels = new MultiChannelId(name).all(); + return channels.every((channel) => super.isChannel(channel)); + } + async subscribeToChannel(name) { + const contextName = this.createContextName(name); + const usub = await this.contexts.subscribe(contextName, (data, _, __, ___, extraData) => { + if (this.callback) { + this.callback(data.data, data, extraData === null || extraData === void 0 ? void 0 : extraData.updaterId); + } + }); + this.currentlySubscribedChannels.push(name); + this.unsubscribeMap[contextName] = usub; + } + async unsubscribeFromChannel(name) { + const contextName = this.createContextName(name); + const unsub = this.unsubscribeMap[contextName]; + if (unsub) { + unsub(); + delete this.unsubscribeMap[contextName]; + } + this.currentlySubscribedChannels = this.currentlySubscribedChannels.filter((channel) => channel !== name); + } + } + class SharedContextSubscriber extends BaseSharedContextSubscriber { + async switchChannel(name) { + this.unsubscribe(); + const contextName = this.createContextName(name); + this.unsubscribeFunc = await this.contexts.subscribe(contextName, (data, _, __, ___, extraData) => { + if (this.callback) { + this.callback(data.data, data, extraData === null || extraData === void 0 ? void 0 : extraData.updaterId); + } + }); + } + async leave() { + if (this.callback) { + this.callback({}, undefined); + } + this.unsubscribe(); + } + unsubscribe() { + if (this.unsubscribeFunc) { + this.unsubscribeFunc(); + this.unsubscribeFunc = undefined; + } + } + } + + const validateFdc3Options = (options) => { + if (typeof options !== "object" || Array.isArray(options)) { + throw new Error(`Provide options as an object`); + } + if (options.contextType && (typeof options.contextType !== "string" || !options.contextType.length)) { + throw new Error(`Provide options.contextType as a non-empty string`); + } + }; + + class ChannelsImpl { + constructor(interop, getWindowsAPI, getAppManagerAPI, logger) { + this.interop = interop; + this.getWindowsAPI = getWindowsAPI; + this.getAppManagerAPI = getAppManagerAPI; + this.logger = logger; + this.subsKey = "subs"; + this.changedKey = "changed"; + this.channelsChangedKey = "channelsChanged"; + this.isInitialJoin = true; + this.registry = CallbackRegistryFactory(); + this.pendingReplays = {}; + this.pendingRestrictionCallbacks = new Map(); + } + async getMyChannels(options) { + if (!this.currentChannelID) { + return Promise.resolve([]); + } + if (this.currentChannelID.all().length === 0) { + return Promise.resolve([]); + } + const result = []; + for (const channel of this.currentChannelID.all()) { + result.push(await this.get(channel, options)); + } + return result; + } + async init(shared, mode, initial) { + this.mode = mode; + this.shared = shared; + this.shared.subscribe(this.handler.bind(this)); + this.subscribeForChannelRestrictionsChange(); + let initialChannel = initial; + if (typeof window !== "undefined" && typeof window.glue42gd !== "undefined") { + initialChannel = window.glue42gd.initialChannel; + } + this.currentChannelID = this.getID(initialChannel); + this.logger.trace(`initialized with mode: "${mode}" and initial channel: "${initialChannel}"`); + if (this.currentChannelID.isJoinedToAnyChannel) { + this.logger.trace(`joining initial channel: "${this.currentChannelID.toString()}"`); + await this.joinNoSelectorSwitch(this.currentChannelID.toString()); + } + } + subscribe(callback, options) { + if (typeof callback !== "function") { + throw new Error("Please provide the callback as a function!"); + } + const id = Utils.generateId(); + this.pendingReplays[id] = true; + const wrappedCallback = (options === null || options === void 0 ? void 0 : options.contextType) + ? this.getWrappedSubscribeCallbackWithFdc3Type(callback, id, options.contextType) + : this.getWrappedSubscribeCallback(callback, id); + if (this.lastUpdate) { + let lastUpdate = Object.assign({}, this.lastUpdate); + setTimeout(async () => { + if (this.pendingReplays[id]) { + if (this.lastUpdate) { + lastUpdate = this.lastUpdate; + } + wrappedCallback(lastUpdate.context.data, lastUpdate.context, lastUpdate.updaterId); + } + delete this.pendingReplays[id]; + }, 0); + } + const unsub = this.registry.add(this.subsKey, wrappedCallback); + return () => { + this.pendingReplays[id] = false; + this.pendingRestrictionCallbacks.delete(id); + unsub(); + }; + } + async subscribeFor(name, callback, options) { + if (typeof name !== "string") { + throw new Error("Please provide the name as a string!"); + } + if (typeof callback !== "function") { + throw new Error("Please provide the callback as a function!"); + } + const id = Utils.generateId(); + const wrappedCallback = (options === null || options === void 0 ? void 0 : options.contextType) + ? this.getWrappedSubscribeCallbackWithFdc3Type(callback, id, options.contextType) + : this.getWrappedSubscribeCallback(callback, id); + const unsub = await this.shared.subscribeFor(name, wrappedCallback); + return () => { + this.pendingRestrictionCallbacks.delete(id); + unsub(); + }; + } + async publish(data, options) { + if (typeof data !== "object") { + throw new Error("Please provide the data as an object!"); + } + if (options) { + this.validatePublishOptions(options); + } + if (typeof options === "object") { + return this.publishWithOptions(data, options); + } + const channelName = typeof options === "string" ? options : this.currentChannelID.toString(); + if (!channelName) { + throw new Error("Not joined to any channel!"); + } + if (!this.shared.isChannel(channelName)) { + return Promise.reject(new Error(`A channel with name: ${channelName} doesn't exist!`)); + } + if (this.mode === "multi") { + const channelsToPublish = new MultiChannelId(channelName).all(); + const restrictedChannels = []; + for (const cn of channelsToPublish) { + const canPublish = (await this.getRestrictionsByChannel(cn)).write; + if (!canPublish) { + restrictedChannels.push(cn); + continue; + } + await this.shared.updateData(cn, data); + } + if (restrictedChannels.length > 0) { + const restrictedChannelsErr = `Unable to publish due to restrictions to the following channels: ${restrictedChannels.join(", ")}`; + if (restrictedChannels.length === channelsToPublish.length) { + throw new Error(restrictedChannelsErr); + } + else { + this.logger.warn(restrictedChannelsErr); + } + } + } + else { + const canPublish = (await this.getRestrictionsByChannel(channelName)).write; + if (!canPublish) { + throw new Error(`Window does not have permission to write to channel ${channelName}`); + } + return this.shared.updateData(channelName, data); + } + } + async setPaths(paths, name) { + if (name) { + if (typeof name !== "string") { + throw new Error("Please provide the name as a string!"); + } + if (!this.shared.isChannel(name)) { + return Promise.reject(new Error(`A channel with name: ${name} doesn't exist!`)); + } + if (!(await this.getRestrictionsByChannel(name)).write) { + throw new Error(`Window does not have permission to write to channel ${name}`); + } + return this.shared.setPaths(name, paths); + } + if (!this.currentChannelID) { + throw new Error("Not joined to any channel!"); + } + if (!(await this.getRestrictionsByChannel(this.currentChannelID.toString())).write) { + throw new Error(`Window does not have permission to write to channel ${this.currentChannelID.toString()}`); + } + if (!Array.isArray(paths)) { + throw new Error("Path Values argument is not a valid array"); + } + paths.forEach((path) => { + this.validatePathArgs(path); + }); + return this.shared.setPaths(this.currentChannelID.toString(), paths); + } + async setPath(path, name) { + if (name) { + if (typeof name !== "string") { + throw new Error("Please provide the name as a string!"); + } + if (!this.shared.isChannel(name)) { + return Promise.reject(new Error(`A channel with name: ${name} doesn't exist!`)); + } + if (!(await this.getRestrictionsByChannel(name)).write) { + throw new Error(`Window does not have permission to write to channel ${name}`); + } + return this.shared.setPaths(name, [path]); + } + if (!this.currentChannelID) { + throw new Error("Not joined to any channel!"); + } + if (!(await this.getRestrictionsByChannel(this.currentChannelID.toString())).write) { + throw new Error(`Window does not have permission to write to channel ${this.currentChannelID.toString()}`); + } + this.validatePathArgs(path); + return this.shared.setPaths(this.currentChannelID.toString(), [path]); + } + all() { + const channelNames = this.shared.all(); + return Promise.resolve(channelNames); + } + async list() { + const channelNames = await this.all(); + const channelContexts = await Promise.all(channelNames.map((channelName) => this.get(channelName))); + return channelContexts; + } + async get(name, options) { + if (typeof name !== "string") { + return Promise.reject(new Error("Please provide the channel name as a string!")); + } + if (!(options === null || options === void 0 ? void 0 : options.contextType)) { + return this.shared.getContextData(name); + } + validateFdc3Options(options); + const context = await this.shared.getContextData(name); + return this.getContextWithFdc3Type(context, options.contextType); + } + getMy(options) { + if (!this.currentChannelID) { + return Promise.resolve(undefined); + } + if (this.currentChannelID.all().length === 0) { + return Promise.resolve(undefined); + } + return this.get(this.currentChannelID.all()[0], options); + } + async join(name, windowId) { + if (windowId !== undefined && windowId !== null) { + this.validateWindowIdArg(windowId); + this.logger.trace(`joining channel ${name} for window: ${windowId}`); + return sendSwitchChannelUI(name, windowId); + } + return this.joinCore(name); + } + async joinNoSelectorSwitch(channelName) { + this.logger.trace(`joining channel "${channelName}" from command`); + return this.joinCore(channelName, false); + } + leave(options) { + this.logger.trace(`leaving channel with options: ${JSON.stringify(options)}`); + let windowId; + let channelName; + if (typeof options === "string") { + windowId = options; + } + else if (typeof options === "object" && !Array.isArray(options) && options !== null && options !== undefined) { + if (options.windowId) { + windowId = options.windowId; + } + if (options.channel) { + channelName = options.channel; + } + } + if (this.mode === "multi") { + return this.leaveWhenMulti(channelName, windowId); + } + else { + return this.leaveWhenSingle(channelName, windowId); + } + } + leaveNoSelectorSwitch(channelName) { + this.logger.trace(`leaving channel "${channelName}" from command`); + return this.leaveCore(false, channelName); + } + current() { + return this.currentChannelID.toString(); + } + my() { + return this.current(); + } + myChannels() { + var _a; + return (_a = this.currentChannelID.all()) !== null && _a !== void 0 ? _a : []; + } + onChannelsChanged(callback) { + if (typeof callback !== "function") { + throw new Error("Please provide the callback as a function!"); + } + let timeoutId; + const current = this.current(); + if (current) { + timeoutId = setTimeout(() => { + callback(this.myChannels()); + }, 0); + } + const un = this.registry.add(this.channelsChangedKey, callback); + return () => { + un(); + clearTimeout(timeoutId); + }; + } + changed(callback) { + if (typeof callback !== "function") { + throw new Error("Please provide the callback as a function!"); + } + const current = this.current(); + if (current) { + setTimeout(() => { + callback(this.current()); + }, 0); + } + return this.registry.add(this.changedKey, () => { + callback(this.current()); + }); + } + onChanged(callback) { + return this.changed(callback); + } + async add(info) { + var _a; + if (typeof info !== "object") { + throw new Error("Please provide the info as an object!"); + } + if (typeof info.name === "undefined") { + throw new Error("info.name is missing!"); + } + if (typeof info.name !== "string") { + throw new Error("Please provide the info.name as a string!"); + } + if (typeof info.meta === "undefined") { + throw new Error("info.meta is missing!"); + } + if (typeof info.meta !== "object") { + throw new Error("Please provide the info.meta as an object!"); + } + if (typeof info.meta.color === "undefined") { + throw new Error("info.meta.color is missing!"); + } + if (typeof info.meta.color !== "string") { + throw new Error("Please provide the info.meta.color as a string!"); + } + const context = { + name: info.name, + meta: info.meta || {}, + data: info.data || {} + }; + this.logger.trace(`adding channel: ${info.name}`); + await addOrRemoveChannel("addChannel", info.name, info.meta.color, (_a = info.meta) === null || _a === void 0 ? void 0 : _a.label); + await this.shared.updateChannel(info.name, context); + return context; + } + async remove(channel) { + if (typeof channel !== "string") { + throw new Error("Please provide the channel name as a string!"); + } + this.logger.trace(`removing channel: ${channel}`); + await this.shared.remove(channel); + await addOrRemoveChannel("removeChannel", channel); + } + async getWindowsOnChannel(channel) { + this.validateChannelArg(channel); + const windowInfos = await this.getWindowsWithChannels({ channels: [channel] }); + return windowInfos.map((w) => w.window); + } + async getWindowsWithChannels(filter) { + this.validateWindowsWithChannelsFilter(filter); + try { + const info = await getChannelsInfo(filter); + const windowsAPI = this.getWindowsAPI(); + if (info === null || info === void 0 ? void 0 : info.windows) { + return info.windows.reduce((memo, windowInfo) => { + const window = windowsAPI.findById(windowInfo.windowId); + memo.push({ + window, + channel: windowInfo.channel, + application: windowInfo.application + }); + return memo; + }, []); + } + } + catch (er) { + this.logger.error(`Error getting all channel enabled windows. This method is available since Glue42 3.12`, er); + } + return []; + } + async restrict(restriction) { + this.validateRestrictionConfig(restriction); + return setRestrictions(restriction); + } + async getRestrictions(windowId) { + if (windowId) { + this.validateWindowIdArg(windowId); + } + return getRestrictionsByWindow(windowId); + } + async restrictAll(restriction) { + this.validateRestrictionConfig(restriction); + return setRestrictionsForAllChannels(restriction); + } + handleRestrictionsChanged(restrictions, windowId) { + this.registry.execute("restrictions-changed", { + restrictions, + windowId + }); + } + async clearChannelData(channel) { + const channelName = typeof channel === "string" ? channel : this.currentChannelID.toString(); + if (!channelName) { + return; + } + if (!this.shared.isChannel(channelName)) { + return; + } + const canPublish = (await this.getRestrictionsByChannel(channelName)).write; + if (!canPublish) { + return; + } + return this.shared.clearContextData(channelName); + } + handler(data, context, updaterId) { + if (!context && !updaterId) { + this.lastUpdate = undefined; + return; + } + this.lastUpdate = { context, updaterId }; + this.pendingReplays = {}; + this.registry.execute(this.subsKey, data, context, updaterId); + } + async joinCore(name, changeSelector = true) { + this.logger.trace(`joining channel "${name}" ${changeSelector ? "" : "from command"}`); + if (typeof name !== "string") { + throw new Error("Please provide the channel name as a string!"); + } + const newId = this.getID(name); + if (!this.isInitialJoin && this.currentChannelID.isOnChannel(newId.toString())) { + this.logger.trace(`already on channel: "${name}" ${changeSelector ? "" : "from command"}`); + return; + } + this.isInitialJoin = false; + await Promise.all(newId.all().map((n) => this.verifyChannelExists(n))); + this.currentChannelID.joinChannel(name); + this.lastUpdate = undefined; + this.logger.trace(`switching channel context to: "${name}" ${changeSelector ? "" : "from command"}`); + await this.shared.switchChannel(this.currentChannelID.toString()); + if (changeSelector) { + this.logger.trace(`switching UI channel to: "${name}" ${changeSelector ? "" : "from command"}`); + await sendSwitchChannelUI(name); + this.logger.trace(`switched UI channel to: "${name}" ${changeSelector ? "" : "from command"}`); + } + this.raiseChannelsChangedEvents(); + this.logger.trace(`joined channel: ${name} ${changeSelector ? "" : "from command"} - current channel/s: ${this.currentChannelID.toString()}`); + } + async verifyChannelExists(name) { + const doesChannelExist = (channelName) => { + const channelNames = this.shared.all(); + return channelNames.includes(channelName); + }; + if (!doesChannelExist(name)) { + const channelExistsPromise = new Promise((resolve, reject) => { + const intervalId = setInterval(() => { + if (doesChannelExist(name)) { + clearTimeout(timeoutId); + clearInterval(intervalId); + resolve(); + } + }, 100); + const timeoutId = setTimeout(() => { + clearInterval(intervalId); + return reject(new Error(`A channel with name: ${name} doesn't exist!`)); + }, 3000); + }); + await channelExistsPromise; + } + } + async leaveCore(changeSelector = true, channelID) { + if (!this.currentChannelID.isJoinedToAnyChannel) { + this.logger.trace(`leave called ${changeSelector ? "" : "from command"} when not joined to any channel change selector`); + return; + } + if (channelID && !this.currentChannelID.isOnChannel(channelID)) { + this.logger.trace(`leave called ${changeSelector ? "" : "from command"} when not joined to channel: "${channelID}"`); + return; + } + this.logger.trace(`leaving context channel: "${channelID}" ${changeSelector ? "" : "from command"}`); + this.currentChannelID.leaveChannel(channelID); + await this.shared.leave(channelID); + this.lastUpdate = undefined; + this.raiseChannelsChangedEvents(); + if (changeSelector) { + this.logger.trace(`switching UI channel to: "${channelID}" ${changeSelector ? "" : "from command"}`); + await sendSwitchChannelUI(this.currentChannelID.toString()); + this.logger.trace(`switched UI channel to: "${channelID}" ${changeSelector ? "" : "from command"}`); + } + this.logger.trace(`left single channel: "${channelID}" ${changeSelector ? "" : "from command"} - current channel/s: "${this.currentChannelID.toString()}"`); + return Promise.resolve(); + } + async leaveCoreMulti(changeSelector = true, channelID) { + this.logger.trace(`leaving multi channel: "${channelID.toString()}" ${changeSelector ? "" : "from command"}`); + const currentChannels = this.currentChannelID.all(); + const isJoinedToChannel = currentChannels.some((c) => channelID.isOnChannel(c)); + if (!isJoinedToChannel || !this.currentChannelID.isJoinedToAnyChannel) { + this.logger.trace(`leave called ${changeSelector ? "" : "from command"} when not joined to any channel`); + return; + } + const channelName = channelID.toString(); + this.currentChannelID.leaveChannel(channelName); + await this.shared.leave(channelName); + this.lastUpdate = undefined; + this.raiseChannelsChangedEvents(); + if (changeSelector) { + this.logger.trace(`switching UI channel to: "${channelName}" ${changeSelector ? "" : "from command"}`); + await sendLeaveChannel(channelName); + this.logger.trace(`switched UI channel to: "${channelName}" ${changeSelector ? "" : "from command"}`); + } + this.logger.trace(`left multi channel: "${channelName}" ${changeSelector ? "" : "from command"} - current channel/s: ${this.currentChannelID.toString()}`); + return Promise.resolve(); + } + raiseChannelsChangedEvents() { + this.registry.execute(this.changedKey, this.currentChannelID.toString()); + this.registry.execute(this.channelsChangedKey, this.currentChannelID.all()); + } + async getRestrictionsByChannel(channelName) { + var _a; + const restrictions = (_a = this.channelRestrictions) !== null && _a !== void 0 ? _a : await getRestrictionsByWindow(); + if (!restrictions || !Array.isArray(restrictions.channels) || !restrictions.channels.find(c => c.name === channelName)) { + return { + read: true, + write: true + }; + } + const byChannel = restrictions.channels.find(c => c.name === channelName); + return byChannel; + } + onRestrictionsChanged(callback, callbackId, currentChannelName) { + this.pendingRestrictionCallbacks.set(callbackId, { + cb: callback, + channelName: currentChannelName + }); + if (this.onRestrictionsChangedSub) { + return; + } + this.onRestrictionsChangedSub = this.registry.add("restrictions-changed", ({ restrictions }) => { + this.logger.trace(`restrictions changed - ${JSON.stringify(restrictions)}`); + this.pendingRestrictionCallbacks.forEach(({ cb, channelName }, id) => { + const currentChannel = restrictions.channels.find((c) => c.name === channelName); + if (!currentChannel) { + this.logger.trace(`channel "${channelName}" not found in restrictions`); + return; + } + if (currentChannel.read) { + this.pendingRestrictionCallbacks.delete(id); + if (this.pendingRestrictionCallbacks.values.length === 0 && this.onRestrictionsChangedSub) { + this.onRestrictionsChangedSub(); + this.onRestrictionsChangedSub = null; + } + cb(); + } + }); + }); + } + subscribeForChannelRestrictionsChange() { + this.registry.add("restrictions-changed", (r) => { + this.logger.trace(`channel restrictions changed - ${JSON.stringify(r.restrictions)}`); + this.channelRestrictions = r.restrictions; + }); + } + validatePathArgs(path) { + if (!path) { + throw new Error("Please provide a valid path value argument"); + } + if (typeof path !== "object") { + throw new Error(`Path Value argument is not a valid object: ${JSON.stringify(path)}`); + } + if (!path.path) { + throw new Error(`path property is missing from Path Value argument: ${JSON.stringify(path)}`); + } + if (!path.value) { + throw new Error(`value property is missing from Path Value argument: ${JSON.stringify(path)}`); + } + if (typeof path.path !== "string") { + throw new Error(`path property is not a valid string from the Path Value argument: ${JSON.stringify(path)}`); + } + } + validatePublishOptions(options) { + if ((typeof options !== "string" && typeof options !== "object") || Array.isArray(options)) { + throw new Error("Provide options as a string or an object"); + } + if (typeof options === "object") { + this.validatePublishOptionsObject(options); + return; + } + if (options === "string" && !options.length) { + throw new Error("Provide options as a non-empty string"); + } + } + validatePublishOptionsObject(options) { + if (typeof options !== "object" || Array.isArray(options)) { + throw new Error("Provide options as an object"); + } + if (options.name && (typeof options.name !== "string" || !options.name.length)) { + throw new Error("Provide options.name as a non-empty string"); + } + if (Object.keys(options).includes("fdc3") && typeof options.fdc3 !== "boolean") { + throw new Error("Provide options.fdc3 as a boolean"); + } + } + async publishWithOptions(data, options) { + const channelName = options.name || this.currentChannelID.toString(); + if (!this.shared.isChannel(channelName)) { + throw new Error(`A channel with name: ${options.name} doesn't exist!`); + } + if (!channelName) { + throw new Error("Cannot publish to channel, because not joined to a channel!"); + } + const canPublish = (await this.getRestrictionsByChannel(channelName)).write; + if (!canPublish) { + throw new Error(`Window does not have permission to write to channel ${this.currentChannelID.toString()}`); + } + if (!options.fdc3) { + return this.shared.updateData(channelName, data); + } + return this.publishFdc3Data(channelName, data); + } + async publishFdc3Data(channelName, data) { + var _a; + if (typeof data.type !== "string" || !((_a = data.type) === null || _a === void 0 ? void 0 : _a.length)) { + throw new Error("Expected a valid FDC3 Context with compulsory 'type' field"); + } + const { type, ...rest } = data; + const parsedType = type.split(".").join("&"); + const fdc3DataToPublish = { [`fdc3_${parsedType}`]: rest }; + return this.shared.updateData(channelName, fdc3DataToPublish); + } + getWrappedSubscribeCallback(callback, id) { + const wrappedCallback = async (_, context, updaterId) => { + const restrictionByChannel = await this.getRestrictionsByChannel(context.name); + const channelData = this.getDataWithFdc3Encoding(context); + if (restrictionByChannel.read) { + callback(channelData, context, updaterId); + } + else { + this.onRestrictionsChanged(() => { + callback(channelData, context, updaterId); + }, id, context.name); + } + }; + return wrappedCallback; + } + getWrappedSubscribeCallbackWithFdc3Type(callback, id, fdc3Type) { + const didReplay = { replayed: false }; + const wrappedCallback = async (_, context, updaterId) => { + const restrictionByChannel = await this.getRestrictionsByChannel(context.name); + const callbackWithTypesChecks = () => { + const { data, latest_fdc3_type } = context; + const searchedType = `fdc3_${fdc3Type.split(".").join("&")}`; + if (!data[searchedType]) { + return; + } + if (didReplay.replayed) { + return this.parseDataAndInvokeSubscribeCallback({ latestFdc3TypeEncoded: latest_fdc3_type, searchedType: fdc3Type, callback, context, updaterId }); + } + const fdc3Data = { type: fdc3Type, ...data[searchedType] }; + callback({ fdc3: fdc3Data }, context, updaterId); + didReplay.replayed = true; + }; + if (restrictionByChannel.read) { + callbackWithTypesChecks(); + return; + } + this.onRestrictionsChanged(callbackWithTypesChecks, id, context.name); + }; + return wrappedCallback; + } + parseDataAndInvokeSubscribeCallback(args) { + const { latestFdc3TypeEncoded, searchedType, callback, context, updaterId } = args; + const latestPublishedType = latestFdc3TypeEncoded.split("&").join("."); + if (latestPublishedType !== searchedType) { + return; + } + const fdc3Data = { type: searchedType, ...context.data[`fdc3_${latestFdc3TypeEncoded}`] }; + callback({ fdc3: fdc3Data }, context, updaterId); + } + getContextWithFdc3Type(context, searchedType) { + var _a, _b; + if (((_b = (_a = context.data) === null || _a === void 0 ? void 0 : _a.fdc3) === null || _b === void 0 ? void 0 : _b.type) === searchedType) { + return { + name: context.name, + meta: context.meta, + data: { fdc3: context.data.fdc3 } + }; + } + const encodedType = `fdc3_${searchedType.split(".").join("&")}`; + if (!context.data[encodedType]) { + return { + name: context.name, + meta: context.meta, + data: {} + }; + } + const fdc3Context = { type: searchedType, ...context.data[encodedType] }; + return { + name: context.name, + meta: context.meta, + data: { fdc3: fdc3Context } + }; + } + getDataWithFdc3Encoding(context) { + const { data, latest_fdc3_type } = context; + if (!latest_fdc3_type) { + return data; + } + const parsedType = latest_fdc3_type.split("&").join("."); + const latestTypePropName = `fdc3_${latest_fdc3_type}`; + const fdc3Data = { type: parsedType, ...data[latestTypePropName] }; + const { [latestTypePropName]: latestFDC3Type, ...rest } = data; + return { ...rest, fdc3: fdc3Data }; + } + getID(id) { + if (this.mode === "multi") { + return new MultiChannelId(id); + } + else { + return new SingleChannelID(id); + } + } + leaveWhenSingle(channelName, windowId) { + if (windowId) { + this.logger.trace(`leaving single channel "${channelName}" for window: "${windowId}"`); + return sendSwitchChannelUI(undefined, windowId); + } + this.logger.trace(`leaving single channel "${channelName}" for our window`); + return this.leaveCore(true, channelName); + } + async leaveWhenMulti(channelName, windowId) { + if (windowId) { + this.logger.trace(`leaving multi channel "${channelName}" for window: "${windowId}"`); + return sendLeaveChannel(channelName, windowId); + } + else { + const channelId = channelName ? new MultiChannelId(channelName) : this.currentChannelID; + this.logger.trace(`leaving multi channel "${channelId.toString()}" for our window`); + return this.leaveCoreMulti(true, channelId); + } + } + validateWindowIdArg(windowId) { + if (typeof windowId !== "string") { + throw new Error("The window ID must be a non-empty string!"); + } + const windows = this.getWindowsAPI(); + if (!windows.findById(windowId)) { + throw new Error(`Window with ID "${windowId}" doesn't exist!`); + } + } + validateChannelArg(channel) { + if (!channel) { + throw new Error("Please provide a valid Channel name as a non-empty string!"); + } + if (typeof channel !== "string") { + throw new Error("The Channel name must be a non-empty string!"); + } + const channelNames = this.shared.all(); + if (channelNames.every((name) => name !== channel)) { + throw new Error(`Channel "${channel}" does not exist!"`); + } + } + validateWindowsWithChannelsFilter(filter) { + if (filter === undefined) { + return; + } + if (filter === null || Array.isArray(filter) || typeof filter !== "object") { + throw new Error("The `filter` argument must be a valid object!"); + } + } + isRestrictions(restriction) { + return 'name' in restriction; + } + validateRestrictionConfig(restriction) { + if (restriction === null || restriction === undefined || Array.isArray(restriction) || typeof restriction !== "object") { + throw new Error("The `restrictions` argument must be a valid object with Channel restrictions!"); + } + if (this.isRestrictions(restriction) && typeof restriction.name !== "string") { + throw new Error("The `name` restriction property must be a non-empty string!"); + } + if (restriction.read !== null && restriction.read !== undefined && typeof restriction.read !== "boolean") { + throw new Error("The `read` restriction property must be a boolean value!"); + } + if (restriction.write !== null && restriction.write !== undefined && typeof restriction.write !== "boolean") { + throw new Error("The `write` restriction property must be a boolean value!"); + } + if ((restriction.read === null || restriction.read === undefined) && (restriction.write === null || restriction.write === undefined)) { + throw new Error("It's required to set either the `read` or the `write` property of the Channel restriction object!"); + } + if (restriction.windowId !== null && restriction.windowId !== undefined) { + this.validateWindowIdArg(restriction.windowId); + } + } + } + + function factory$4(config, contexts, agm, getWindowsAPI, getAppManagerAPI, logger) { + const channelsReadyPromise = getChannelInitInfo(config, agm) + .then(async ({ mode, initialChannel }) => { + const sharedContexts = mode === "single" ? new SharedContextSubscriber(contexts) : new MultiSharedContextSubscriber(contexts); + if (mode === "multi") { + logger.info(`multi-channel mode enabled`); + } + await channels.init(sharedContexts, mode, initialChannel); + await setupInterop(agm, channels, logger); + return true; + }); + const channels = new ChannelsImpl(agm, getWindowsAPI, getAppManagerAPI, logger); + return { + subscribe: channels.subscribe.bind(channels), + subscribeFor: channels.subscribeFor.bind(channels), + publish: channels.publish.bind(channels), + setPath: channels.setPath.bind(channels), + setPaths: channels.setPaths.bind(channels), + all: channels.all.bind(channels), + list: channels.list.bind(channels), + get: channels.get.bind(channels), + join: channels.join.bind(channels), + leave: channels.leave.bind(channels), + restrict: channels.restrict.bind(channels), + getRestrictions: channels.getRestrictions.bind(channels), + clearChannelData: channels.clearChannelData.bind(channels), + restrictAll: channels.restrictAll.bind(channels), + current: channels.current.bind(channels), + my: channels.my.bind(channels), + changed: channels.changed.bind(channels), + onChanged: channels.onChanged.bind(channels), + add: channels.add.bind(channels), + remove: channels.remove.bind(channels), + getWindowsOnChannel: channels.getWindowsOnChannel.bind(channels), + getWindowsWithChannels: channels.getWindowsWithChannels.bind(channels), + getMy: channels.getMy.bind(channels), + ready: async () => { + await Promise.all([contexts.ready(), channelsReadyPromise]); + }, + get mode() { return channels.mode; }, + getMyChannels: channels.getMyChannels.bind(channels), + myChannels: channels.myChannels.bind(channels), + onChannelsChanged: channels.onChannelsChanged.bind(channels), + }; + } + + const CommandMethod = "T42.Hotkeys.Command"; + const InvokeMethod = "T42.Hotkeys.Invoke"; + const RegisterCommand = "register"; + const UnregisterCommand = "unregister"; + const UnregisterAllCommand = "unregisterAll"; + class HotkeysImpl { + constructor(agm) { + this.agm = agm; + this.registry = CallbackRegistryFactory(); + this.firstHotkey = true; + this.hotkeys = new Map(); + } + async register(info, callback) { + if (typeof info === "undefined") { + throw new Error("Hotkey parameter missing"); + } + if (typeof info === "string") { + info = { + hotkey: info + }; + } + else { + if (!info.hotkey) { + throw new Error("Info's hotkey parameter missing"); + } + info = { + hotkey: info.hotkey, + description: info.description + }; + } + const hkToLower = this.formatHotkey(info.hotkey); + if (this.hotkeys.has(hkToLower)) { + throw new Error(`Shortcut for ${hkToLower} already registered`); + } + if (this.firstHotkey) { + this.firstHotkey = false; + await this.registerInvokeAGMMethod(); + } + this.registry.add(hkToLower, callback); + await this.agm.invoke(CommandMethod, { command: RegisterCommand, hotkey: hkToLower, description: info.description }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + this.hotkeys.set(hkToLower, info); + } + async unregister(hotkey) { + if (typeof hotkey === "undefined") { + throw new Error("hotkey parameter missing"); + } + if (typeof hotkey !== "string") { + throw new Error("hotkey parameter must be string"); + } + const hkToLower = this.formatHotkey(hotkey); + await this.agm.invoke(CommandMethod, { command: UnregisterCommand, hotkey: hkToLower }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + this.hotkeys.delete(hkToLower); + this.registry.clearKey(hkToLower); + } + async unregisterAll() { + await this.agm.invoke(CommandMethod, { command: UnregisterAllCommand }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + this.hotkeys.clear(); + this.registry.clear(); + } + isRegistered(hotkey) { + const hkToLower = this.formatHotkey(hotkey); + return this.hotkeys.has(hkToLower); + } + registerInvokeAGMMethod() { + return this.agm.register(InvokeMethod, (args) => { + const hkToLower = args.key.toLowerCase(); + const info = this.hotkeys.get(hkToLower); + this.registry.execute(hkToLower, info); + }); + } + formatHotkey(hotkey) { + if (hotkey) { + return hotkey.replace(/\s/g, "").toLowerCase(); + } + } + } + + function factory$3(agm) { + const hotkeys = new HotkeysImpl(agm); + return { + register: hotkeys.register.bind(hotkeys), + unregister: hotkeys.unregister.bind(hotkeys), + unregisterAll: hotkeys.unregisterAll.bind(hotkeys), + isRegistered: hotkeys.isRegistered.bind(hotkeys), + ready: () => Promise.resolve() + }; + } + + var version = "6.12.0"; + + var prepareConfig = (options) => { + function getLibConfig(value, defaultMode, trueMode) { + if (typeof value === "boolean" && !value) { + return undefined; + } + const mode = getModeAsString(value, defaultMode, trueMode); + if (typeof mode === "undefined") { + return undefined; + } + if (typeof value === "object") { + value.mode = mode; + return value; + } + return { + mode, + }; + } + function getModeAsString(value, defaultMode, trueMode) { + if (typeof value === "object") { + return getModeAsString(value.mode, defaultMode, trueMode).toString(); + } + else if (typeof value === "undefined") { + if (typeof defaultMode === "boolean" && !defaultMode) { + return undefined; + } + else if (typeof defaultMode === "boolean" && defaultMode) { + return typeof trueMode === "undefined" ? defaultMode : trueMode; + } + else if (typeof defaultMode === "undefined") { + return undefined; + } + else { + return defaultMode; + } + } + else if (typeof value === "boolean") { + if (value) { + return (typeof trueMode === "undefined") ? defaultMode : trueMode; + } + else { + return undefined; + } + } + return value; + } + const appDefaultMode = true; + const appDefaultTrueMode = "startOnly"; + const activitiesDefaultMode = Utils.isNode() ? false : "trackMyTypeAndInitiatedFromMe"; + const activitiesTrueMode = "trackMyTypeAndInitiatedFromMe"; + const layoutsDefaultMode = "slim"; + const layoutsTrueMode = layoutsDefaultMode; + const channelsConfig = () => { + if (typeof options.channels === "boolean") { + return options.channels; + } + else if (typeof options.channels === "object" && typeof options.channels.enabled === "boolean" && options.channels.enabled) { + return { mode: true, ...options.channels }; + } + else { + return false; + } + }; + const exposeAPI = typeof options.exposeAPI === "boolean" || typeof options.exposeGlue === "boolean"; + return { + layouts: getLibConfig(options.layouts, layoutsDefaultMode, layoutsTrueMode), + activities: getLibConfig(options.activities, activitiesDefaultMode, activitiesTrueMode), + appManager: getLibConfig(options.appManager, appDefaultMode, appDefaultTrueMode), + windows: getLibConfig(options.windows, true, true), + channels: getLibConfig(channelsConfig(), false, true), + displays: getLibConfig(options.displays, true, true), + exposeAPI: exposeAPI ? exposeAPI : true + }; + }; + + class Glue42Notification { + constructor(options) { + this.options = options; + this.callbacks = CallbackRegistryFactory(); + this.actions = options.actions; + this.body = options.body; + this.badge = options.badge; + this.data = options.data; + this.dir = options.dir; + this.icon = options.icon; + this.image = options.image; + this.lang = options.lang; + this.renotify = options.renotify; + this.requireInteraction = options.requireInteraction; + this.silent = options.silent; + this.tag = options.tag; + this.timestamp = options.timestamp; + this.title = options.title; + } + close() { + throw new Error("Method not implemented."); + } + addEventListener(type, listener, options) { + this.callbacks.add(type, listener); + } + removeEventListener(type, listener, options) { + } + dispatchEvent(event) { + this.callbacks.execute(event.type, event); + return true; + } + } + + class PanelAPI { + constructor(interop, onStreamEvent) { + this.interop = interop; + this.onStreamEvent = onStreamEvent; + } + onVisibilityChanged(callback) { + return this.onStreamEvent("on-panel-visibility-changed", callback); + } + toggle() { + return this.interop.invoke("T42.Notifications.Show", undefined, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + show() { + return this.interop.invoke("T42.Notifications.Show", { show: true }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + hide() { + return this.interop.invoke("T42.Notifications.Hide"); + } + async isVisible() { + const interopResult = await this.interop.invoke("T42.Notifications.Execute", { command: "isPanelVisible" }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return interopResult.returned.panelVisible; + } + toAPI() { + return { + onVisibilityChanged: this.onVisibilityChanged.bind(this), + toggle: this.toggle.bind(this), + show: this.show.bind(this), + hide: this.hide.bind(this), + isVisible: this.isVisible.bind(this) + }; + } + } + + const STARTING_INDEX = 0; + class Notifications { + constructor(interop, logger) { + this.interop = interop; + this.NotificationsSubscribeStream = "T42.GNS.Subscribe.Notifications"; + this.NotificationsCounterStream = "T42.Notifications.Counter"; + this.RaiseNotificationMethodName = "T42.GNS.Publish.RaiseNotification"; + this.NotificationsExecuteMethod = "T42.Notifications.Execute"; + this.NotificationFilterMethodName = "T42.Notifications.Filter"; + this.methodsRegistered = false; + this.NOTIFICATIONS_CONFIGURE_METHOD_NAME = "T42.Notifications.Configure"; + this.methodNameRoot = "T42.Notifications.Handler-" + Utils.generateId(); + this.nextId = 0; + this.notifications = {}; + this.registry = CallbackRegistryFactory(); + this.subscribedForNotifications = false; + this.subscribedCounterStream = false; + this.subscriptionsCountForNotifications = 0; + this.subscriptionsCountForCounter = 0; + this.logger = logger.subLogger("notifications"); + this._panel = new PanelAPI(interop, this.onStreamEventCore.bind(this)); + this._panelAPI = this._panel.toAPI(); + this.subscribeInternalEvents(); + } + get maxActions() { + return 10; + } + get panel() { + return this._panelAPI; + } + async raise(options) { + var _a; + const notification = await this.createNotification(options); + const g42notification = new Glue42Notification(options); + this.notifications[notification.id] = g42notification; + try { + const invocationResult = await this.interop.invoke(this.RaiseNotificationMethodName, { notification }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + g42notification.id = (_a = invocationResult.returned) === null || _a === void 0 ? void 0 : _a.id; + } + catch (err) { + const errorMessage = err.message; + setTimeout(() => { + this.handleNotificationErrorEvent(g42notification, errorMessage); + }, 1); + } + return g42notification; + } + async setFilter(filter) { + const result = await this.interop.invoke(this.NotificationFilterMethodName, filter, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return result.returned; + } + async getFilter() { + const result = await this.interop.invoke(this.NotificationFilterMethodName, undefined, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return result.returned; + } + async configure(options) { + var _a, _b, _c, _d, _e, _f, _g, _h; + if (!options || Array.isArray(options)) { + throw new Error("Invalid options - should be an object."); + } + if (Object.values(options).length === 0) { + throw new Error("The argument must be a non-empty object."); + } + if (typeof options.enable !== "undefined" && typeof options.enable !== "boolean") { + throw new Error("Expected type of enabled - boolean."); + } + if (typeof options.enableToasts !== "undefined" && typeof options.enableToasts !== "boolean") { + throw new Error("Expected type of enableToasts - boolean."); + } + if (typeof options.toastExpiry !== "undefined" && typeof options.toastExpiry !== "number") { + throw new Error("Expected type of toastExpiry - number."); + } + if (options.sourceFilter && typeof options.sourceFilter !== "object") { + throw new Error("Expected type of sourceFilter - object."); + } + if (((_a = options.sourceFilter) === null || _a === void 0 ? void 0 : _a.allowed) && !Array.isArray((_b = options.sourceFilter) === null || _b === void 0 ? void 0 : _b.allowed)) { + throw new Error("Expected type of sourceFilter.allowed - array."); + } + if (((_c = options.sourceFilter) === null || _c === void 0 ? void 0 : _c.blocked) && !Array.isArray((_d = options.sourceFilter) === null || _d === void 0 ? void 0 : _d.blocked)) { + throw new Error("Expected type of sourceFilter.blocked - array."); + } + if (options.toasts && typeof options.toasts !== "object") { + throw new Error("Expected type of (options.toasts - object."); + } + if (((_e = options.toasts) === null || _e === void 0 ? void 0 : _e.mode) && typeof options.toasts.mode !== "string") { + throw new Error("Expected type of (options.toasts.mode - string."); + } + if (((_f = options.toasts) === null || _f === void 0 ? void 0 : _f.stackBy) && typeof options.toasts.stackBy !== "string") { + throw new Error("Expected type of (options.toasts.stackBy - string."); + } + if (options.placement && typeof options.placement !== "object") { + throw new Error("Expected type of (options.placement - object."); + } + if (((_g = options.placement) === null || _g === void 0 ? void 0 : _g.toasts) && typeof options.placement.toasts !== "string") { + throw new Error("Expected type of (options.placement.toasts - string."); + } + if (((_h = options.placement) === null || _h === void 0 ? void 0 : _h.panel) && typeof options.placement.panel !== "string") { + throw new Error("Expected type of (options.placement.panel - string."); + } + if (typeof options.closeNotificationOnClick !== "undefined" && typeof options.closeNotificationOnClick !== "boolean") { + throw new Error("Expected type of closeNotificationOnClick - boolean."); + } + const result = await this.interop.invoke(this.NOTIFICATIONS_CONFIGURE_METHOD_NAME, options, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return result.returned; + } + async getConfiguration() { + const result = await this.interop.invoke(this.NotificationsExecuteMethod, { command: "getConfiguration" }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return result.returned; + } + async list() { + const interopResult = await this.interop.invoke(this.NotificationsExecuteMethod, { + command: "list", + data: { statesVersion2: true } + }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return interopResult.returned.notifications; + } + async updateData(id, data) { + const replacer = (key, value) => typeof value === "undefined" ? null : value; + const attribute = { + key: "data", + value: { + stringValue: JSON.stringify(data, replacer) + } + }; + const interopResult = await this.interop.invoke(this.NotificationsExecuteMethod, { command: "create-or-update-attribute", data: { id, attribute } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return interopResult.returned; + } + onRaised(callback) { + return this.onStreamEventCore("on-notification-raised", callback); + } + onStateChanged(callback) { + return this.onStreamEventCore("on-state-changed", callback); + } + onClosed(callback) { + return this.onStreamEventCore("on-notification-closed", callback); + } + onConfigurationChanged(callback) { + if (typeof callback !== "function") { + throw new Error("Please provide the callback as a function!"); + } + this.subscribe(); + const un = this.registry.add("on-configuration-changed", callback); + return () => { + un(); + this.closeStreamSubscriptionIfNoNeeded(); + }; + } + onCounterChanged(callback) { + if (typeof callback !== "function") { + throw new Error("Please provide the callback as a function!"); + } + this.subscribeForCounterStream(); + const un = this.registry.add("on-counter-changed", callback); + return () => { + un(); + this.closeStreamCounterSubscriptionIfNoNeeded(); + }; + } + onDataChanged(callback) { + if (typeof callback !== "function") { + throw new Error("Please provide the callback as a function!"); + } + this.subscribe(); + const un = this.registry.add("on-notification-data-changed", callback); + return () => { + un(); + this.closeStreamSubscriptionIfNoNeeded(); + }; + } + async clearAll() { + await this.interop.invoke(this.NotificationsExecuteMethod, { command: "clearAll" }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async clearOld() { + await this.interop.invoke(this.NotificationsExecuteMethod, { command: "clearAllOld", data: { statesVersion2: true } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async clear(id) { + if (!id) { + throw new Error("The 'id' argument cannot be null or undefined"); + } + if (typeof (id) !== "string") { + throw new Error("The 'id' argument must be a string"); + } + await this.interop.invoke(this.NotificationsExecuteMethod, { command: "clear", data: { id } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async clearMany(notifications) { + this.validateNotificationsArr(notifications); + await this.interop.invoke(this.NotificationsExecuteMethod, { command: "clearMany", data: { notifications } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async click(id, action, options) { + await this.interop.invoke(this.NotificationsExecuteMethod, { command: "click", data: { id, action, options } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async snooze(id, duration) { + await this.interop.invoke(this.NotificationsExecuteMethod, { command: "snooze", data: { id, duration } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async snoozeMany(notifications, duration) { + if (!duration) { + throw new Error("The 'duration' argument cannot be null or undefined"); + } + if (typeof duration !== "number") { + throw new Error("The 'duration' argument must be a valid number"); + } + this.validateNotificationsArr(notifications); + await this.interop.invoke(this.NotificationsExecuteMethod, { command: "snoozeMany", data: { notifications, duration } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async setState(id, state) { + if (!id) { + throw new Error("The 'id' argument cannot be null or undefined"); + } + if (typeof (id) !== "string") { + throw new Error("The 'id' argument must be a string"); + } + if (!state) { + throw new Error("The 'state' argument cannot be null or undefined"); + } + this.validateState(state); + await this.interop.invoke(this.NotificationsExecuteMethod, { command: "updateState", data: { id, state } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async setStates(notifications, state) { + if (!state) { + throw new Error("The 'state' argument cannot be null or undefined"); + } + if (typeof state !== "string") { + throw new Error("The 'state' argument must be a valid string"); + } + this.validateNotificationsArr(notifications); + await this.interop.invoke(this.NotificationsExecuteMethod, { command: "updateStates", data: { notifications, state } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + toAPI() { + return { + maxActions: this.maxActions, + panel: this._panel.toAPI(), + raise: this.raise.bind(this), + setFilter: this.setFilter.bind(this), + getFilter: this.getFilter.bind(this), + configure: this.configure.bind(this), + getConfiguration: this.getConfiguration.bind(this), + list: this.list.bind(this), + onRaised: this.onRaised.bind(this), + onStateChanged: this.onStateChanged.bind(this), + onClosed: this.onClosed.bind(this), + onConfigurationChanged: this.onConfigurationChanged.bind(this), + onCounterChanged: this.onCounterChanged.bind(this), + onDataChanged: this.onDataChanged.bind(this), + clearAll: this.clearAll.bind(this), + clearOld: this.clearOld.bind(this), + clear: this.clear.bind(this), + click: this.click.bind(this), + setState: this.setState.bind(this), + updateData: this.updateData.bind(this), + snooze: this.snooze.bind(this), + snoozeMany: this.snoozeMany.bind(this), + clearMany: this.clearMany.bind(this), + setStates: this.setStates.bind(this), + import: this.importNotifications.bind(this) + }; + } + async importNotifications(notifications) { + if (!notifications || !Array.isArray(notifications) || notifications.length === 0) { + throw new Error("Notifications argument must be a valid array with notification options"); + } + const notificationsToImport = await Promise.all(notifications.map((notificationOptions) => this.createNotification(notificationOptions, true))); + const invocationResult = await this.interop.invoke(this.NotificationsExecuteMethod, { command: "importNotifications", data: { notificationSettings: notificationsToImport } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return invocationResult.returned.notifications; + } + async createNotification(options, imported) { + var _a, _b, _c, _d; + this.validate(options, imported); + if (!this.methodsRegistered) { + const bunchOfPromises = []; + for (let index = STARTING_INDEX; index < this.maxActions; index++) { + bunchOfPromises.push(this.interop.register(`${this.methodNameRoot}_${index}`, this.handleNotificationEvent.bind(this))); + } + this.methodsRegistered = true; + await Promise.all(bunchOfPromises); + } + const id = (_a = options.id) !== null && _a !== void 0 ? _a : Utils.generateId(); + const type = (_b = options.type) !== null && _b !== void 0 ? _b : "Notification"; + const notification = { + id, + state: (_c = options.state) !== null && _c !== void 0 ? _c : "Active", + title: options.title, + type, + severity: (_d = options.severity) !== null && _d !== void 0 ? _d : "None", + description: options.body, + glueRoutingDetailMethodName: `${this.methodNameRoot}_${STARTING_INDEX}`, + actions: [], + sourceId: id, + source: options.source, + publishExtraEvents: true, + clickInterop: options.clickInterop + }; + if (options.actions) { + this.handleActions(options, id, notification); + } + this.handleOptions(options, notification); + return notification; + } + onStreamEventCore(key, callback) { + if (typeof callback !== "function") { + throw new Error("Please provide the callback as a function!"); + } + this.subscribe(); + const un = this.registry.add(key, callback); + return () => { + un(); + this.closeStreamSubscriptionIfNoNeeded(); + }; + } + handleOptions(options, notification) { + if (options.icon) { + notification.attributes = notification.attributes || []; + notification.attributes.push({ key: "icon", value: { stringValue: options.icon } }); + } + if (options.data) { + notification.attributes = notification.attributes || []; + const dataAsString = JSON.stringify(options.data); + notification.attributes.push({ key: "data", value: { stringValue: dataAsString } }); + } + if (typeof options.panelExpiry === "number") { + notification.attributes = notification.attributes || []; + notification.attributes.push({ key: "panelExpiry", value: { stringValue: options.panelExpiry.toString() } }); + } + if (typeof options.toastExpiry === "number") { + notification.attributes = notification.attributes || []; + notification.attributes.push({ key: "toastExpiry", value: { stringValue: options.toastExpiry.toString() } }); + } + } + handleActions(options, id, notification) { + var _a, _b, _c; + const validActions = options.actions.slice(0, this.maxActions); + let index = STARTING_INDEX; + for (const action of validActions) { + const args = { + g42notificationId: id, + g42action: action.action, + g42interopMethod: (_a = action.interop) === null || _a === void 0 ? void 0 : _a.method, + g42interopTarget: (_b = action.interop) === null || _b === void 0 ? void 0 : _b.target, + g42interopArguments: JSON.stringify((_c = action.interop) === null || _c === void 0 ? void 0 : _c.arguments) + }; + const parameters = Object.keys(args).map((key) => { + const value = args[key]; + return { + name: key, + value: { + stringValue: value + } + }; + }); + const glueAction = { + name: `${this.methodNameRoot}_${index}`, + description: action.title, + displayName: action.title, + displayPath: action.displayPath, + displayId: action.displayId, + parameters + }; + notification.actions.push(glueAction); + index++; + } + } + validate(options, imported) { + if (!options) { + throw new Error("invalid options - should be an object"); + } + if (typeof options !== "object") { + throw new Error("invalid options - should be an object"); + } + if (!options.title) { + throw new Error("invalid options - should have a title"); + } + if (typeof options.title !== "string") { + throw new Error("invalid options - title should be a string"); + } + if (options.severity && typeof options.severity !== "string") { + throw new Error("invalid options - severity should be a string"); + } + if (options.panelExpiry && typeof options.panelExpiry !== "number") { + throw new Error("invalid options - panelExpiry should be a number"); + } + if (options.toastExpiry && typeof options.toastExpiry !== "number") { + throw new Error("invalid options - toastExpiry should be a number"); + } + if (options.state) { + this.validateState(options.state, imported); + } + } + validateState(state, imported) { + if (typeof (state) !== "string") { + throw new Error("The 'state' argument must be a string"); + } + const validStates = [ + "Active", + "Acknowledged", + "Stale" + ]; + if (imported) { + validStates.push("Seen", "Snoozed", "Processing", "Closed"); + } + if (!validStates.includes(state)) { + throw new Error(`The state argument: ${state} is not valid!`); + } + } + subscribe() { + this.subscriptionsCountForNotifications++; + if (!this.subscribedForNotifications) { + this.subscribedForNotifications = true; + this.logger.info(`Attempting to subscribe to "${this.NotificationsSubscribeStream}".`); + this.interop + .subscribe(this.NotificationsSubscribeStream, { + arguments: { + sendDeltaOnly: true, + statesVersion2: true + } + }) + .then((sub) => { + this.subscriptionForNotifications = sub; + this.logger.info(`Successfully subscribed to "${this.NotificationsSubscribeStream}".`); + sub.onData(({ data }) => { + this.handleData(data); + }); + sub.onClosed((...args) => { + this.subscribedForNotifications = false; + this.logger.info(`Stream subscription Closed - ${JSON.stringify(args)}`); + }); + sub.onFailed((...args) => { + this.subscribedForNotifications = false; + this.logger.warn(`Stream subscription Failed - ${JSON.stringify(args)}`); + }); + }) + .catch((e) => { + this.subscribedForNotifications = false; + this.logger.error(`Unable to subscribe to "${this.NotificationsSubscribeStream}"`, e); + }); + } + } + subscribeForCounterStream() { + this.subscriptionsCountForCounter++; + if (!this.subscribedCounterStream) { + this.subscribedCounterStream = true; + this.logger.info(`Attempting to subscribe to "${this.NotificationsCounterStream}".`); + this.interop + .subscribe(this.NotificationsCounterStream, { + arguments: { + sendDeltaOnly: true + } + }) + .then((sub) => { + this.subscriptionForCounter = sub; + this.logger.info(`Successfully subscribed to "${this.NotificationsCounterStream}".`); + sub.onData(({ data }) => { + this.registry.execute("on-counter-changed", { count: data.count }); + }); + sub.onClosed((...args) => { + this.subscribedCounterStream = false; + this.logger.info(`Stream subscription Closed - ${JSON.stringify(args)}`); + }); + sub.onFailed((...args) => { + this.subscribedCounterStream = false; + this.logger.warn(`Stream subscription Failed - ${JSON.stringify(args)}`); + }); + }) + .catch((e) => { + this.subscribedCounterStream = false; + this.logger.error(`Unable to subscribe to "${this.NotificationsCounterStream}"`, e); + }); + } + } + subscribeInternalEvents() { + this.registry.add("on-notification-closed", (id) => { + this.handleOnClosed(id); + }); + this.registry.add("on-notification-raised", (notification) => { + this.handleOnShow(notification.id); + }); + } + handleData(message) { + var _a; + try { + if ("items" in message && Array.isArray(message.items)) { + this.handleItemsData(message); + } + else if ("deltas" in message && Array.isArray(message.deltas)) { + this.handleDeltas(message); + } + if ("configuration" in message && typeof message.configuration === "object") { + this.logger.info(`Received configuration ${JSON.stringify(message.configuration)} from the stream`); + this.registry.execute("on-configuration-changed", message.configuration, message.configuration.allApplications); + } + if ("command" in message && typeof message.command === "string") { + this.logger.info(`Received command "${(_a = message.command) !== null && _a !== void 0 ? _a : JSON.stringify(message)}" from the stream`); + if (message.command === "showPanel" || message.command === "hidePanel") { + this.registry.execute("on-panel-visibility-changed", message.command === "showPanel"); + } + } + } + catch (e) { + this.logger.error(`Failed to parse data from the stream`, e); + } + } + handleItemsData(message) { + const items = message.items; + this.logger.info(`Received ${items.length} notifications from the stream`); + const notifications = items; + if (message.isSnapshot) { + notifications.forEach((n) => { + this.registry.execute("on-notification-raised", n); + }); + } + else { + const notification = notifications[0]; + if (notification.state === "Closed") { + this.registry.execute("on-notification-closed", { id: notification.id }); + } + else { + this.registry.execute("on-notification-raised", notification); + } + } + } + handleDeltas(message) { + const deltas = message.deltas; + deltas.forEach((info) => { + var _a; + const id = info.id; + const delta = (_a = info.delta) !== null && _a !== void 0 ? _a : {}; + if (delta.state === "Closed") { + this.registry.execute("on-notification-closed", { id, ...delta }); + } + else if (delta.state) { + this.registry.execute("on-state-changed", { id }, delta.state); + } + else if (delta.attributes) { + const attributes = delta.attributes; + const dataAttribute = attributes.find((a) => a.key === "data"); + if (dataAttribute) { + this.registry.execute("on-notification-data-changed", { id }, JSON.parse(dataAttribute.value.stringValue)); + } + } + }); + } + handleOnClosed(id) { + const { notification, key } = this.getNotification(id); + if (notification) { + this.handleEvent(notification, "close"); + delete this.notifications[key]; + } + } + handleOnShow(id) { + const { notification } = this.getNotification(id); + if (notification) { + this.handleEvent(notification, "show"); + } + } + getNotification(id) { + let notification; + let key; + for (const k in this.notifications) { + if (this.notifications[k].id === id) { + notification = this.notifications[k]; + key = k; + break; + } + } + return { notification, key }; + } + handleNotificationEvent(args) { + const gnsNotificationArgs = this.getGnsNotificationArgs(args); + if (gnsNotificationArgs.event === "unknown") { + return; + } + const notification = this.notifications[gnsNotificationArgs.notificationId]; + if (!notification) { + return; + } + this.handleNotificationEventCore(notification, gnsNotificationArgs); + } + handleNotificationEventCore(notification, args) { + switch (args.event) { + case "action": { + return this.handleNotificationActionEvent(notification, args.notificationActionPayload); + } + case "click": { + return this.handleNotificationClickEvent(notification); + } + case "close": { + return this.handleEvent(notification, "close"); + } + case "error": { + return this.handleNotificationErrorEvent(notification, args.error); + } + case "show": { + return this.handleEvent(notification, "show"); + } + } + } + handleNotificationActionEvent(notification, payload) { + const event = { + type: "onaction", + action: payload.g42action + }; + if (notification.onaction) { + notification.onaction(event); + } + notification.dispatchEvent(event); + } + handleNotificationClickEvent(notification) { + const event = { type: "onclick" }; + if (notification.onclick) { + notification.onclick(event); + } + notification.dispatchEvent(event); + } + handleEvent(notification, eventType) { + var _a; + const event = { type: eventType }; + const eventName = `on${eventType}`; + (_a = notification[eventName]) === null || _a === void 0 ? void 0 : _a.call(notification, event); + notification.dispatchEvent(event); + } + handleNotificationErrorEvent(notification, error) { + const event = { type: "onerror", error }; + if (notification.onerror) { + notification.onerror(event); + } + notification.dispatchEvent(event); + } + getGnsNotificationArgs(args) { + var _a; + let result; + const event = (_a = args.notification) === null || _a === void 0 ? void 0 : _a.event; + if (!event) { + result = this.getBackwardGnsNotificationArgs(args); + } + else { + result = { + event, + notificationId: args.notification.sourceNotificationId, + notificationActionPayload: args + }; + } + return result; + } + getBackwardGnsNotificationArgs(args) { + var _a; + let result; + if (args.g42notificationId) { + result = { + event: "action", + notificationId: args.g42notificationId, + notificationActionPayload: args + }; + } + else if ((_a = args.notification) === null || _a === void 0 ? void 0 : _a.sourceNotificationId) { + result = { + event: "click", + notificationId: args.notification.sourceNotificationId, + notificationActionPayload: args + }; + } + else { + result = { + event: "unknown", + notificationId: undefined, + notificationActionPayload: args + }; + } + return result; + } + closeStreamSubscriptionIfNoNeeded() { + this.subscriptionsCountForNotifications--; + if (this.subscriptionForNotifications && this.subscriptionsCountForNotifications === 0) { + this.subscriptionForNotifications.close(); + this.subscriptionForNotifications = undefined; + } + } + closeStreamCounterSubscriptionIfNoNeeded() { + this.subscriptionsCountForCounter--; + if (this.subscriptionForCounter && this.subscriptionsCountForCounter === 0) { + this.subscriptionForCounter.close(); + this.subscriptionForCounter = undefined; + } + } + validateNotificationsArr(notifications) { + if (!Array.isArray(notifications)) { + throw new Error("The 'notifications' argument must be an array with valid notification IDs"); + } + if (notifications.some((n) => typeof n !== "string")) { + throw new Error("The 'notifications' argument must contain only valid string notification IDs"); + } + } + } + + const ThemesConfigurationMethodName = "T42.Themes.Configuration"; + class ThemesImpl { + constructor(contexts, interop) { + this.contexts = contexts; + this.interop = interop; + this.registry = CallbackRegistryFactory(); + this.isSubscribed = false; + this.getConfiguration(); + } + async list() { + await this.getConfiguration(); + if (!this.getMethodName) { + throw new Error("not supported"); + } + return (await this.getAll()).returned.all; + } + async getCurrent() { + await this.getConfiguration(); + if (!this.getMethodName) { + throw new Error("not supported"); + } + const all = await this.getAll(); + return all.returned.all.find((t) => t.name === all.returned.selected); + } + async select(theme) { + await this.getConfiguration(); + if (!this.setMethodName) { + throw new Error("not supported"); + } + await this.interop.invoke(this.setMethodName, { theme }); + } + onChanged(callback) { + if (!callback) { + throw new Error("Callback argument is required"); + } + if (callback && typeof callback !== "function") { + throw new Error("Callback argument must be a function"); + } + this.subscribe(); + return this.registry.add("changed", callback); + } + async getConfiguration() { + try { + if (this.sharedContextName) { + return; + } + const config = await this.interop.invoke(ThemesConfigurationMethodName); + this.sharedContextName = config.returned.sharedContextName; + this.getMethodName = config.returned.getThemesMethodName; + this.setMethodName = config.returned.setThemesMethodName; + } + catch (error) { + return; + } + } + async getAll() { + await this.getConfiguration(); + return await this.interop.invoke(this.getMethodName); + } + async subscribe() { + await this.getConfiguration(); + if (this.isSubscribed) { + return; + } + this.isSubscribed = true; + this.contexts.subscribe(this.sharedContextName, (data) => { + if (data && data.all && data.selected) { + this.registry.execute("changed", data.all.find((t) => t.name === data.selected)); + } + }); + } + } + + function factory$2(contexts, interop) { + const themes = new ThemesImpl(contexts, interop); + return { + list: themes.list.bind(themes), + getCurrent: themes.getCurrent.bind(themes), + select: themes.select.bind(themes), + onChanged: themes.onChanged.bind(themes), + ready: () => Promise.resolve(), + }; + } + + const connectBrowserAppProps = ["name", "title", "version", "customProperties", "icon", "caption", "type"]; + const fdc3v2AppProps = ["appId", "name", "type", "details", "version", "title", "tooltip", "lang", "description", "categories", "icons", "screenshots", "contactEmail", "moreInfo", "publisher", "customConfig", "hostManifests", "interop", "localizedVersions"]; + + /** + * Wraps values in an `Ok` type. + * + * Example: `ok(5) // => {ok: true, result: 5}` + */ + var ok = function (result) { return ({ ok: true, result: result }); }; + /** + * Wraps errors in an `Err` type. + * + * Example: `err('on fire') // => {ok: false, error: 'on fire'}` + */ + var err = function (error) { return ({ ok: false, error: error }); }; + /** + * Create a `Promise` that either resolves with the result of `Ok` or rejects + * with the error of `Err`. + */ + var asPromise = function (r) { + return r.ok === true ? Promise.resolve(r.result) : Promise.reject(r.error); + }; + /** + * Unwraps a `Result` and returns either the result of an `Ok`, or + * `defaultValue`. + * + * Example: + * ``` + * Result.withDefault(5, number().run(json)) + * ``` + * + * It would be nice if `Decoder` had an instance method that mirrored this + * function. Such a method would look something like this: + * ``` + * class Decoder
{ + * runWithDefault = (defaultValue: A, json: any): A => + * Result.withDefault(defaultValue, this.run(json)); + * } + * + * number().runWithDefault(5, json) + * ``` + * Unfortunately, the type of `defaultValue: A` on the method causes issues + * with type inference on the `object` decoder in some situations. While these + * inference issues can be solved by providing the optional type argument for + * `object`s, the extra trouble and confusion doesn't seem worth it. + */ + var withDefault = function (defaultValue, r) { + return r.ok === true ? r.result : defaultValue; + }; + /** + * Return the successful result, or throw an error. + */ + var withException = function (r) { + if (r.ok === true) { + return r.result; + } + else { + throw r.error; + } + }; + /** + * Apply `f` to the result of an `Ok`, or pass the error through. + */ + var map = function (f, r) { + return r.ok === true ? ok(f(r.result)) : r; + }; + /** + * Apply `f` to the result of two `Ok`s, or pass an error through. If both + * `Result`s are errors then the first one is returned. + */ + var map2 = function (f, ar, br) { + return ar.ok === false ? ar : + br.ok === false ? br : + ok(f(ar.result, br.result)); + }; + /** + * Apply `f` to the error of an `Err`, or pass the success through. + */ + var mapError = function (f, r) { + return r.ok === true ? r : err(f(r.error)); + }; + /** + * Chain together a sequence of computations that may fail, similar to a + * `Promise`. If the first computation fails then the error will propagate + * through. If it succeeds, then `f` will be applied to the value, returning a + * new `Result`. + */ + var andThen = function (f, r) { + return r.ok === true ? f(r.result) : r; + }; + + /*! ***************************************************************************** + Copyright (c) Microsoft Corporation. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THIS SOFTWARE. + ***************************************************************************** */ + /* global Reflect, Promise */ + + + + var __assign = function() { + __assign = Object.assign || function __assign(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; + } + return t; + }; + return __assign.apply(this, arguments); + }; + + function __rest(s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { + if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) + t[p[i]] = s[p[i]]; + } + return t; + } + + function isEqual(a, b) { + if (a === b) { + return true; + } + if (a === null && b === null) { + return true; + } + if (typeof (a) !== typeof (b)) { + return false; + } + if (typeof (a) === 'object') { + // Array + if (Array.isArray(a)) { + if (!Array.isArray(b)) { + return false; + } + if (a.length !== b.length) { + return false; + } + for (var i = 0; i < a.length; i++) { + if (!isEqual(a[i], b[i])) { + return false; + } + } + return true; + } + // Hash table + var keys = Object.keys(a); + if (keys.length !== Object.keys(b).length) { + return false; + } + for (var i = 0; i < keys.length; i++) { + if (!b.hasOwnProperty(keys[i])) { + return false; + } + if (!isEqual(a[keys[i]], b[keys[i]])) { + return false; + } + } + return true; + } + } + /* + * Helpers + */ + var isJsonArray = function (json) { return Array.isArray(json); }; + var isJsonObject = function (json) { + return typeof json === 'object' && json !== null && !isJsonArray(json); + }; + var typeString = function (json) { + switch (typeof json) { + case 'string': + return 'a string'; + case 'number': + return 'a number'; + case 'boolean': + return 'a boolean'; + case 'undefined': + return 'undefined'; + case 'object': + if (json instanceof Array) { + return 'an array'; + } + else if (json === null) { + return 'null'; + } + else { + return 'an object'; + } + default: + return JSON.stringify(json); + } + }; + var expectedGot = function (expected, got) { + return "expected " + expected + ", got " + typeString(got); + }; + var printPath = function (paths) { + return paths.map(function (path) { return (typeof path === 'string' ? "." + path : "[" + path + "]"); }).join(''); + }; + var prependAt = function (newAt, _a) { + var at = _a.at, rest = __rest(_a, ["at"]); + return (__assign({ at: newAt + (at || '') }, rest)); + }; + /** + * Decoders transform json objects with unknown structure into known and + * verified forms. You can create objects of type `Decoder` with either the + * primitive decoder functions, such as `boolean()` and `string()`, or by + * applying higher-order decoders to the primitives, such as `array(boolean())` + * or `dict(string())`. + * + * Each of the decoder functions are available both as a static method on + * `Decoder` and as a function alias -- for example the string decoder is + * defined at `Decoder.string()`, but is also aliased to `string()`. Using the + * function aliases exported with the library is recommended. + * + * `Decoder` exposes a number of 'run' methods, which all decode json in the + * same way, but communicate success and failure in different ways. The `map` + * and `andThen` methods modify decoders without having to call a 'run' method. + * + * Alternatively, the main decoder `run()` method returns an object of type + * `Result`. This library provides a number of helper + * functions for dealing with the `Result` type, so you can do all the same + * things with a `Result` as with the decoder methods. + */ + var Decoder = /** @class */ (function () { + /** + * The Decoder class constructor is kept private to separate the internal + * `decode` function from the external `run` function. The distinction + * between the two functions is that `decode` returns a + * `Partial` on failure, which contains an unfinished error + * report. When `run` is called on a decoder, the relevant series of `decode` + * calls is made, and then on failure the resulting `Partial` + * is turned into a `DecoderError` by filling in the missing information. + * + * While hiding the constructor may seem restrictive, leveraging the + * provided decoder combinators and helper functions such as + * `andThen` and `map` should be enough to build specialized decoders as + * needed. + */ + function Decoder(decode) { + var _this = this; + this.decode = decode; + /** + * Run the decoder and return a `Result` with either the decoded value or a + * `DecoderError` containing the json input, the location of the error, and + * the error message. + * + * Examples: + * ``` + * number().run(12) + * // => {ok: true, result: 12} + * + * string().run(9001) + * // => + * // { + * // ok: false, + * // error: { + * // kind: 'DecoderError', + * // input: 9001, + * // at: 'input', + * // message: 'expected a string, got 9001' + * // } + * // } + * ``` + */ + this.run = function (json) { + return mapError(function (error) { return ({ + kind: 'DecoderError', + input: json, + at: 'input' + (error.at || ''), + message: error.message || '' + }); }, _this.decode(json)); + }; + /** + * Run the decoder as a `Promise`. + */ + this.runPromise = function (json) { return asPromise(_this.run(json)); }; + /** + * Run the decoder and return the value on success, or throw an exception + * with a formatted error string. + */ + this.runWithException = function (json) { return withException(_this.run(json)); }; + /** + * Construct a new decoder that applies a transformation to the decoded + * result. If the decoder succeeds then `f` will be applied to the value. If + * it fails the error will propagated through. + * + * Example: + * ``` + * number().map(x => x * 5).run(10) + * // => {ok: true, result: 50} + * ``` + */ + this.map = function (f) { + return new Decoder(function (json) { return map(f, _this.decode(json)); }); + }; + /** + * Chain together a sequence of decoders. The first decoder will run, and + * then the function will determine what decoder to run second. If the result + * of the first decoder succeeds then `f` will be applied to the decoded + * value. If it fails the error will propagate through. + * + * This is a very powerful method -- it can act as both the `map` and `where` + * methods, can improve error messages for edge cases, and can be used to + * make a decoder for custom types. + * + * Example of adding an error message: + * ``` + * const versionDecoder = valueAt(['version'], number()); + * const infoDecoder3 = object({a: boolean()}); + * + * const decoder = versionDecoder.andThen(version => { + * switch (version) { + * case 3: + * return infoDecoder3; + * default: + * return fail(`Unable to decode info, version ${version} is not supported.`); + * } + * }); + * + * decoder.run({version: 3, a: true}) + * // => {ok: true, result: {a: true}} + * + * decoder.run({version: 5, x: 'abc'}) + * // => + * // { + * // ok: false, + * // error: {... message: 'Unable to decode info, version 5 is not supported.'} + * // } + * ``` + * + * Example of decoding a custom type: + * ``` + * // nominal type for arrays with a length of at least one + * type NonEmptyArray = T[] & { __nonEmptyArrayBrand__: void }; + * + * const nonEmptyArrayDecoder = (values: Decoder): Decoder> => + * array(values).andThen(arr => + * arr.length > 0 + * ? succeed(createNonEmptyArray(arr)) + * : fail(`expected a non-empty array, got an empty array`) + * ); + * ``` + */ + this.andThen = function (f) { + return new Decoder(function (json) { + return andThen(function (value) { return f(value).decode(json); }, _this.decode(json)); + }); + }; + /** + * Add constraints to a decoder _without_ changing the resulting type. The + * `test` argument is a predicate function which returns true for valid + * inputs. When `test` fails on an input, the decoder fails with the given + * `errorMessage`. + * + * ``` + * const chars = (length: number): Decoder => + * string().where( + * (s: string) => s.length === length, + * `expected a string of length ${length}` + * ); + * + * chars(5).run('12345') + * // => {ok: true, result: '12345'} + * + * chars(2).run('HELLO') + * // => {ok: false, error: {... message: 'expected a string of length 2'}} + * + * chars(12).run(true) + * // => {ok: false, error: {... message: 'expected a string, got a boolean'}} + * ``` + */ + this.where = function (test, errorMessage) { + return _this.andThen(function (value) { return (test(value) ? Decoder.succeed(value) : Decoder.fail(errorMessage)); }); + }; + } + /** + * Decoder primitive that validates strings, and fails on all other input. + */ + Decoder.string = function () { + return new Decoder(function (json) { + return typeof json === 'string' + ? ok(json) + : err({ message: expectedGot('a string', json) }); + }); + }; + /** + * Decoder primitive that validates numbers, and fails on all other input. + */ + Decoder.number = function () { + return new Decoder(function (json) { + return typeof json === 'number' + ? ok(json) + : err({ message: expectedGot('a number', json) }); + }); + }; + /** + * Decoder primitive that validates booleans, and fails on all other input. + */ + Decoder.boolean = function () { + return new Decoder(function (json) { + return typeof json === 'boolean' + ? ok(json) + : err({ message: expectedGot('a boolean', json) }); + }); + }; + Decoder.constant = function (value) { + return new Decoder(function (json) { + return isEqual(json, value) + ? ok(value) + : err({ message: "expected " + JSON.stringify(value) + ", got " + JSON.stringify(json) }); + }); + }; + Decoder.object = function (decoders) { + return new Decoder(function (json) { + if (isJsonObject(json) && decoders) { + var obj = {}; + for (var key in decoders) { + if (decoders.hasOwnProperty(key)) { + var r = decoders[key].decode(json[key]); + if (r.ok === true) { + // tslint:disable-next-line:strict-type-predicates + if (r.result !== undefined) { + obj[key] = r.result; + } + } + else if (json[key] === undefined) { + return err({ message: "the key '" + key + "' is required but was not present" }); + } + else { + return err(prependAt("." + key, r.error)); + } + } + } + return ok(obj); + } + else if (isJsonObject(json)) { + return ok(json); + } + else { + return err({ message: expectedGot('an object', json) }); + } + }); + }; + Decoder.array = function (decoder) { + return new Decoder(function (json) { + if (isJsonArray(json) && decoder) { + var decodeValue_1 = function (v, i) { + return mapError(function (err$$1) { return prependAt("[" + i + "]", err$$1); }, decoder.decode(v)); + }; + return json.reduce(function (acc, v, i) { + return map2(function (arr, result) { return arr.concat([result]); }, acc, decodeValue_1(v, i)); + }, ok([])); + } + else if (isJsonArray(json)) { + return ok(json); + } + else { + return err({ message: expectedGot('an array', json) }); + } + }); + }; + Decoder.tuple = function (decoders) { + return new Decoder(function (json) { + if (isJsonArray(json)) { + if (json.length !== decoders.length) { + return err({ + message: "expected a tuple of length " + decoders.length + ", got one of length " + json.length + }); + } + var result = []; + for (var i = 0; i < decoders.length; i++) { + var nth = decoders[i].decode(json[i]); + if (nth.ok) { + result[i] = nth.result; + } + else { + return err(prependAt("[" + i + "]", nth.error)); + } + } + return ok(result); + } + else { + return err({ message: expectedGot("a tuple of length " + decoders.length, json) }); + } + }); + }; + Decoder.union = function (ad, bd) { + var decoders = []; + for (var _i = 2; _i < arguments.length; _i++) { + decoders[_i - 2] = arguments[_i]; + } + return Decoder.oneOf.apply(Decoder, [ad, bd].concat(decoders)); + }; + Decoder.intersection = function (ad, bd) { + var ds = []; + for (var _i = 2; _i < arguments.length; _i++) { + ds[_i - 2] = arguments[_i]; + } + return new Decoder(function (json) { + return [ad, bd].concat(ds).reduce(function (acc, decoder) { return map2(Object.assign, acc, decoder.decode(json)); }, ok({})); + }); + }; + /** + * Escape hatch to bypass validation. Always succeeds and types the result as + * `any`. Useful for defining decoders incrementally, particularly for + * complex objects. + * + * Example: + * ``` + * interface User { + * name: string; + * complexUserData: ComplexType; + * } + * + * const userDecoder: Decoder = object({ + * name: string(), + * complexUserData: anyJson() + * }); + * ``` + */ + Decoder.anyJson = function () { return new Decoder(function (json) { return ok(json); }); }; + /** + * Decoder identity function which always succeeds and types the result as + * `unknown`. + */ + Decoder.unknownJson = function () { + return new Decoder(function (json) { return ok(json); }); + }; + /** + * Decoder for json objects where the keys are unknown strings, but the values + * should all be of the same type. + * + * Example: + * ``` + * dict(number()).run({chocolate: 12, vanilla: 10, mint: 37}); + * // => {ok: true, result: {chocolate: 12, vanilla: 10, mint: 37}} + * ``` + */ + Decoder.dict = function (decoder) { + return new Decoder(function (json) { + if (isJsonObject(json)) { + var obj = {}; + for (var key in json) { + if (json.hasOwnProperty(key)) { + var r = decoder.decode(json[key]); + if (r.ok === true) { + obj[key] = r.result; + } + else { + return err(prependAt("." + key, r.error)); + } + } + } + return ok(obj); + } + else { + return err({ message: expectedGot('an object', json) }); + } + }); + }; + /** + * Decoder for values that may be `undefined`. This is primarily helpful for + * decoding interfaces with optional fields. + * + * Example: + * ``` + * interface User { + * id: number; + * isOwner?: boolean; + * } + * + * const decoder: Decoder = object({ + * id: number(), + * isOwner: optional(boolean()) + * }); + * ``` + */ + Decoder.optional = function (decoder) { + return new Decoder(function (json) { return (json === undefined || json === null ? ok(undefined) : decoder.decode(json)); }); + }; + /** + * Decoder that attempts to run each decoder in `decoders` and either succeeds + * with the first successful decoder, or fails after all decoders have failed. + * + * Note that `oneOf` expects the decoders to all have the same return type, + * while `union` creates a decoder for the union type of all the input + * decoders. + * + * Examples: + * ``` + * oneOf(string(), number().map(String)) + * oneOf(constant('start'), constant('stop'), succeed('unknown')) + * ``` + */ + Decoder.oneOf = function () { + var decoders = []; + for (var _i = 0; _i < arguments.length; _i++) { + decoders[_i] = arguments[_i]; + } + return new Decoder(function (json) { + var errors = []; + for (var i = 0; i < decoders.length; i++) { + var r = decoders[i].decode(json); + if (r.ok === true) { + return r; + } + else { + errors[i] = r.error; + } + } + var errorsList = errors + .map(function (error) { return "at error" + (error.at || '') + ": " + error.message; }) + .join('", "'); + return err({ + message: "expected a value matching one of the decoders, got the errors [\"" + errorsList + "\"]" + }); + }); + }; + /** + * Decoder that always succeeds with either the decoded value, or a fallback + * default value. + */ + Decoder.withDefault = function (defaultValue, decoder) { + return new Decoder(function (json) { + return ok(withDefault(defaultValue, decoder.decode(json))); + }); + }; + /** + * Decoder that pulls a specific field out of a json structure, instead of + * decoding and returning the full structure. The `paths` array describes the + * object keys and array indices to traverse, so that values can be pulled out + * of a nested structure. + * + * Example: + * ``` + * const decoder = valueAt(['a', 'b', 0], string()); + * + * decoder.run({a: {b: ['surprise!']}}) + * // => {ok: true, result: 'surprise!'} + * + * decoder.run({a: {x: 'cats'}}) + * // => {ok: false, error: {... at: 'input.a.b[0]' message: 'path does not exist'}} + * ``` + * + * Note that the `decoder` is ran on the value found at the last key in the + * path, even if the last key is not found. This allows the `optional` + * decoder to succeed when appropriate. + * ``` + * const optionalDecoder = valueAt(['a', 'b', 'c'], optional(string())); + * + * optionalDecoder.run({a: {b: {c: 'surprise!'}}}) + * // => {ok: true, result: 'surprise!'} + * + * optionalDecoder.run({a: {b: 'cats'}}) + * // => {ok: false, error: {... at: 'input.a.b.c' message: 'expected an object, got "cats"'} + * + * optionalDecoder.run({a: {b: {z: 1}}}) + * // => {ok: true, result: undefined} + * ``` + */ + Decoder.valueAt = function (paths, decoder) { + return new Decoder(function (json) { + var jsonAtPath = json; + for (var i = 0; i < paths.length; i++) { + if (jsonAtPath === undefined) { + return err({ + at: printPath(paths.slice(0, i + 1)), + message: 'path does not exist' + }); + } + else if (typeof paths[i] === 'string' && !isJsonObject(jsonAtPath)) { + return err({ + at: printPath(paths.slice(0, i + 1)), + message: expectedGot('an object', jsonAtPath) + }); + } + else if (typeof paths[i] === 'number' && !isJsonArray(jsonAtPath)) { + return err({ + at: printPath(paths.slice(0, i + 1)), + message: expectedGot('an array', jsonAtPath) + }); + } + else { + jsonAtPath = jsonAtPath[paths[i]]; + } + } + return mapError(function (error) { + return jsonAtPath === undefined + ? { at: printPath(paths), message: 'path does not exist' } + : prependAt(printPath(paths), error); + }, decoder.decode(jsonAtPath)); + }); + }; + /** + * Decoder that ignores the input json and always succeeds with `fixedValue`. + */ + Decoder.succeed = function (fixedValue) { + return new Decoder(function (json) { return ok(fixedValue); }); + }; + /** + * Decoder that ignores the input json and always fails with `errorMessage`. + */ + Decoder.fail = function (errorMessage) { + return new Decoder(function (json) { return err({ message: errorMessage }); }); + }; + /** + * Decoder that allows for validating recursive data structures. Unlike with + * functions, decoders assigned to variables can't reference themselves + * before they are fully defined. We can avoid prematurely referencing the + * decoder by wrapping it in a function that won't be called until use, at + * which point the decoder has been defined. + * + * Example: + * ``` + * interface Comment { + * msg: string; + * replies: Comment[]; + * } + * + * const decoder: Decoder = object({ + * msg: string(), + * replies: lazy(() => array(decoder)) + * }); + * ``` + */ + Decoder.lazy = function (mkDecoder) { + return new Decoder(function (json) { return mkDecoder().decode(json); }); + }; + return Decoder; + }()); + + /* tslint:disable:variable-name */ + /** See `Decoder.string` */ + var string = Decoder.string; + /** See `Decoder.number` */ + var number = Decoder.number; + /** See `Decoder.boolean` */ + var boolean = Decoder.boolean; + /** See `Decoder.anyJson` */ + var anyJson = Decoder.anyJson; + /** See `Decoder.unknownJson` */ + Decoder.unknownJson; + /** See `Decoder.constant` */ + var constant = Decoder.constant; + /** See `Decoder.object` */ + var object = Decoder.object; + /** See `Decoder.array` */ + var array = Decoder.array; + /** See `Decoder.tuple` */ + Decoder.tuple; + /** See `Decoder.dict` */ + var dict = Decoder.dict; + /** See `Decoder.optional` */ + var optional = Decoder.optional; + /** See `Decoder.oneOf` */ + var oneOf = Decoder.oneOf; + /** See `Decoder.union` */ + Decoder.union; + /** See `Decoder.intersection` */ + Decoder.intersection; + /** See `Decoder.withDefault` */ + Decoder.withDefault; + /** See `Decoder.valueAt` */ + Decoder.valueAt; + /** See `Decoder.succeed` */ + Decoder.succeed; + /** See `Decoder.fail` */ + Decoder.fail; + /** See `Decoder.lazy` */ + Decoder.lazy; + + const nonEmptyStringDecoder = string().where((s) => s.length > 0, "Expected a non-empty string"); + const nonNegativeNumberDecoder = number().where((num) => num >= 0, "Expected a non-negative number"); + + const intentDefinitionDecoder = object({ + name: nonEmptyStringDecoder, + displayName: optional(string()), + contexts: optional(array(string())), + customConfig: optional(object()) + }); + const v2TypeDecoder = oneOf(constant("web"), constant("native"), constant("citrix"), constant("onlineNative"), constant("other")); + const v2DetailsDecoder = object({ + url: nonEmptyStringDecoder + }); + const v2IconDecoder = object({ + src: nonEmptyStringDecoder, + size: optional(nonEmptyStringDecoder), + type: optional(nonEmptyStringDecoder) + }); + const v2ScreenshotDecoder = object({ + src: nonEmptyStringDecoder, + size: optional(nonEmptyStringDecoder), + type: optional(nonEmptyStringDecoder), + label: optional(nonEmptyStringDecoder) + }); + const v2ListensForIntentDecoder = object({ + contexts: array(nonEmptyStringDecoder), + displayName: optional(nonEmptyStringDecoder), + resultType: optional(nonEmptyStringDecoder), + customConfig: optional(anyJson()) + }); + const v2IntentsDecoder = object({ + listensFor: optional(dict(v2ListensForIntentDecoder)), + raises: optional(dict(array(nonEmptyStringDecoder))) + }); + const v2UserChannelDecoder = object({ + broadcasts: optional(array(nonEmptyStringDecoder)), + listensFor: optional(array(nonEmptyStringDecoder)) + }); + const v2AppChannelDecoder = object({ + name: nonEmptyStringDecoder, + description: optional(nonEmptyStringDecoder), + broadcasts: optional(array(nonEmptyStringDecoder)), + listensFor: optional(array(nonEmptyStringDecoder)) + }); + const v2InteropDecoder = object({ + intents: optional(v2IntentsDecoder), + userChannels: optional(v2UserChannelDecoder), + appChannels: optional(array(v2AppChannelDecoder)) + }); + const glue42ApplicationDetailsDecoder = object({ + url: optional(nonEmptyStringDecoder), + top: optional(number()), + left: optional(number()), + width: optional(nonNegativeNumberDecoder), + height: optional(nonNegativeNumberDecoder) + }); + const glue42HostManifestsBrowserDecoder = object({ + name: optional(nonEmptyStringDecoder), + type: optional(nonEmptyStringDecoder.where((s) => s === "window", "Expected a value of window")), + title: optional(nonEmptyStringDecoder), + version: optional(nonEmptyStringDecoder), + customProperties: optional(anyJson()), + icon: optional(string()), + caption: optional(string()), + details: optional(glue42ApplicationDetailsDecoder), + intents: optional(array(intentDefinitionDecoder)), + hidden: optional(boolean()) + }); + const v1DefinitionDecoder = object({ + name: nonEmptyStringDecoder, + appId: nonEmptyStringDecoder, + title: optional(nonEmptyStringDecoder), + version: optional(nonEmptyStringDecoder), + manifest: nonEmptyStringDecoder, + manifestType: nonEmptyStringDecoder, + tooltip: optional(nonEmptyStringDecoder), + description: optional(nonEmptyStringDecoder), + contactEmail: optional(nonEmptyStringDecoder), + supportEmail: optional(nonEmptyStringDecoder), + publisher: optional(nonEmptyStringDecoder), + images: optional(array(object({ url: optional(nonEmptyStringDecoder) }))), + icons: optional(array(object({ icon: optional(nonEmptyStringDecoder) }))), + customConfig: anyJson(), + intents: optional(array(intentDefinitionDecoder)) + }); + const v2LocalizedDefinitionDecoder = object({ + appId: optional(nonEmptyStringDecoder), + name: optional(nonEmptyStringDecoder), + details: optional(v2DetailsDecoder), + version: optional(nonEmptyStringDecoder), + title: optional(nonEmptyStringDecoder), + tooltip: optional(nonEmptyStringDecoder), + lang: optional(nonEmptyStringDecoder), + description: optional(nonEmptyStringDecoder), + categories: optional(array(nonEmptyStringDecoder)), + icons: optional(array(v2IconDecoder)), + screenshots: optional(array(v2ScreenshotDecoder)), + contactEmail: optional(nonEmptyStringDecoder), + supportEmail: optional(nonEmptyStringDecoder), + moreInfo: optional(nonEmptyStringDecoder), + publisher: optional(nonEmptyStringDecoder), + customConfig: optional(array(anyJson())), + hostManifests: optional(anyJson()), + interop: optional(v2InteropDecoder) + }); + const v2DefinitionDecoder = object({ + appId: nonEmptyStringDecoder, + name: nonEmptyStringDecoder, + type: v2TypeDecoder, + details: v2DetailsDecoder, + version: optional(nonEmptyStringDecoder), + title: optional(nonEmptyStringDecoder), + tooltip: optional(nonEmptyStringDecoder), + lang: optional(nonEmptyStringDecoder), + description: optional(nonEmptyStringDecoder), + categories: optional(array(nonEmptyStringDecoder)), + icons: optional(array(v2IconDecoder)), + screenshots: optional(array(v2ScreenshotDecoder)), + contactEmail: optional(nonEmptyStringDecoder), + supportEmail: optional(nonEmptyStringDecoder), + moreInfo: optional(nonEmptyStringDecoder), + publisher: optional(nonEmptyStringDecoder), + customConfig: optional(array(anyJson())), + hostManifests: optional(anyJson()), + interop: optional(v2InteropDecoder), + localizedVersions: optional(dict(v2LocalizedDefinitionDecoder)) + }); + const allDefinitionsDecoder = oneOf(v1DefinitionDecoder, v2DefinitionDecoder); + + const parseDecoderErrorToStringMessage = (error) => { + return `${error.kind} at ${error.at}: ${JSON.stringify(error.input)}. Reason - ${error.message}`; + }; + + class FDC3Service { + fdc3ToDesktopDefinitionType = { + web: "window", + native: "exe", + citrix: "citrix", + onlineNative: "clickonce", + other: "window" + }; + toApi() { + return { + isFdc3Definition: this.isFdc3Definition.bind(this), + parseToBrowserBaseAppData: this.parseToBrowserBaseAppData.bind(this), + parseToDesktopAppConfig: this.parseToDesktopAppConfig.bind(this) + }; + } + isFdc3Definition(definition) { + const decodeRes = allDefinitionsDecoder.run(definition); + if (!decodeRes.ok) { + return { isFdc3: false, reason: parseDecoderErrorToStringMessage(decodeRes.error) }; + } + if (definition.appId && definition.details) { + return { isFdc3: true, version: "2.0" }; + } + if (definition.manifest) { + return { isFdc3: true, version: "1.2" }; + } + return { isFdc3: false, reason: "The passed definition is not FDC3" }; + } + parseToBrowserBaseAppData(definition) { + const { isFdc3, version } = this.isFdc3Definition(definition); + if (!isFdc3) { + throw new Error("The passed definition is not FDC3"); + } + const decodeRes = allDefinitionsDecoder.run(definition); + if (!decodeRes.ok) { + throw new Error(`Invalid FDC3 ${version} definition. Error: ${parseDecoderErrorToStringMessage(decodeRes.error)}`); + } + const userProperties = this.getUserPropertiesFromDefinition(definition, version); + const createOptions = { url: this.getUrl(definition, version) }; + const baseApplicationData = { + name: definition.appId, + type: "window", + createOptions, + userProperties: { + ...userProperties, + intents: version === "1.2" + ? userProperties.intents + : this.getIntentsFromV2AppDefinition(definition), + details: createOptions + }, + title: definition.title, + version: definition.version, + icon: this.getIconFromDefinition(definition, version), + caption: definition.description, + fdc3: version === "2.0" ? { ...definition, definitionVersion: "2.0" } : undefined, + }; + const ioConnectDefinition = definition.hostManifests?.ioConnect || definition.hostManifests?.["Glue42"]; + if (!ioConnectDefinition) { + return baseApplicationData; + } + const ioDefinitionDecodeRes = glue42HostManifestsBrowserDecoder.run(ioConnectDefinition); + if (!ioDefinitionDecodeRes.ok) { + throw new Error(`Invalid FDC3 ${version} definition. Error: ${parseDecoderErrorToStringMessage(ioDefinitionDecodeRes.error)}`); + } + if (!Object.keys(ioDefinitionDecodeRes.result).length) { + return baseApplicationData; + } + return this.mergeBaseAppDataWithGlueManifest(baseApplicationData, ioDefinitionDecodeRes.result); + } + parseToDesktopAppConfig(definition) { + const { isFdc3, version } = this.isFdc3Definition(definition); + if (!isFdc3) { + throw new Error("The passed definition is not FDC3"); + } + const decodeRes = allDefinitionsDecoder.run(definition); + if (!decodeRes.ok) { + throw new Error(`Invalid FDC3 ${version} definition. Error: ${parseDecoderErrorToStringMessage(decodeRes.error)}`); + } + if (version === "1.2") { + const fdc3v1Definition = definition; + return { + name: fdc3v1Definition.appId, + type: "window", + details: { + url: this.getUrl(definition, version) + }, + version: fdc3v1Definition.version, + title: fdc3v1Definition.title, + tooltip: fdc3v1Definition.tooltip, + caption: fdc3v1Definition.description, + icon: fdc3v1Definition.icons?.[0].icon, + intents: fdc3v1Definition.intents, + customProperties: { + manifestType: fdc3v1Definition.manifestType, + images: fdc3v1Definition.images, + contactEmail: fdc3v1Definition.contactEmail, + supportEmail: fdc3v1Definition.supportEmail, + publisher: fdc3v1Definition.publisher, + icons: fdc3v1Definition.icons, + customConfig: fdc3v1Definition.customConfig + } + }; + } + const fdc3v2Definition = definition; + const desktopDefinition = { + name: fdc3v2Definition.appId, + type: this.fdc3ToDesktopDefinitionType[fdc3v2Definition.type], + details: fdc3v2Definition.details, + version: fdc3v2Definition.version, + title: fdc3v2Definition.title, + tooltip: fdc3v2Definition.tooltip, + caption: fdc3v2Definition.description, + icon: this.getIconFromDefinition(fdc3v2Definition, "2.0"), + intents: this.getIntentsFromV2AppDefinition(fdc3v2Definition), + fdc3: { ...fdc3v2Definition, definitionVersion: "2.0" } + }; + const ioConnectDefinition = definition.hostManifests?.ioConnect || definition.hostManifests?.["Glue42"]; + if (!ioConnectDefinition) { + return desktopDefinition; + } + if (typeof ioConnectDefinition !== "object" || Array.isArray(ioConnectDefinition)) { + throw new Error(`Invalid '${definition.hostManifests.ioConnect ? "hostManifests.ioConnect" : "hostManifests['Glue42']"}' key`); + } + return this.mergeDesktopConfigWithGlueManifest(desktopDefinition, ioConnectDefinition); + } + getUserPropertiesFromDefinition(definition, version) { + if (version === "1.2") { + return Object.fromEntries(Object.entries(definition).filter(([key]) => !connectBrowserAppProps.includes(key))); + } + return Object.fromEntries(Object.entries(definition).filter(([key]) => !connectBrowserAppProps.includes(key) && !fdc3v2AppProps.includes(key))); + } + getUrl(definition, version) { + let url; + if (version === "1.2") { + const parsedManifest = JSON.parse(definition.manifest); + url = parsedManifest.details?.url || parsedManifest.url; + } + else { + url = definition.details?.url; + } + if (!url || typeof url !== "string") { + throw new Error(`Invalid FDC3 ${version} definition. Provide valid 'url' under '${version === "1.2" ? "manifest" : "details"}' key`); + } + return url; + } + getIntentsFromV2AppDefinition(definition) { + const fdc3Intents = definition.interop?.intents?.listensFor; + if (!fdc3Intents) { + return; + } + const intents = Object.entries(fdc3Intents).map((fdc3Intent) => { + const [intentName, intentData] = fdc3Intent; + return { + name: intentName, + ...intentData + }; + }); + return intents; + } + getIconFromDefinition(definition, version) { + if (version === "1.2") { + return definition.icons?.find((iconDef) => iconDef.icon)?.icon || undefined; + } + return definition.icons?.find((iconDef) => iconDef.src)?.src || undefined; + } + mergeBaseAppDataWithGlueManifest(baseAppData, hostManifestDefinition) { + let baseApplicationDefinition = baseAppData; + if (hostManifestDefinition.details) { + const details = { ...baseAppData.createOptions, ...hostManifestDefinition.details }; + baseApplicationDefinition.createOptions = details; + baseApplicationDefinition.userProperties.details = details; + } + if (Array.isArray(hostManifestDefinition.intents)) { + baseApplicationDefinition.userProperties.intents = (baseApplicationDefinition.userProperties.intents || []).concat(hostManifestDefinition.intents); + } + baseApplicationDefinition = { ...baseApplicationDefinition, ...hostManifestDefinition }; + delete baseApplicationDefinition.details; + delete baseApplicationDefinition.intents; + return baseApplicationDefinition; + } + mergeDesktopConfigWithGlueManifest(config, desktopDefinition) { + const appConfig = Object.assign({}, config, desktopDefinition, { details: { ...config.details, ...desktopDefinition.details } }); + if (Array.isArray(desktopDefinition.intents)) { + appConfig.intents = (config.intents || []).concat(desktopDefinition.intents); + } + return appConfig; + } + } + + const decoders$1 = { + common: { + nonEmptyStringDecoder, + nonNegativeNumberDecoder + }, + fdc3: { + allDefinitionsDecoder, + v1DefinitionDecoder, + v2DefinitionDecoder + } + }; + + var INTENTS_ERRORS; + (function (INTENTS_ERRORS) { + INTENTS_ERRORS["USER_CANCELLED"] = "User Closed Intents Resolver UI without choosing a handler"; + INTENTS_ERRORS["CALLER_NOT_DEFINED"] = "Caller Id is not defined"; + INTENTS_ERRORS["TIMEOUT_HIT"] = "Timeout hit"; + INTENTS_ERRORS["INTENT_NOT_FOUND"] = "Cannot find Intent"; + INTENTS_ERRORS["HANDLER_NOT_FOUND"] = "Cannot find Intent Handler"; + INTENTS_ERRORS["TARGET_INSTANCE_UNAVAILABLE"] = "Cannot start Target Instance"; + INTENTS_ERRORS["INTENT_DELIVERY_FAILED"] = "Target Instance did not add a listener"; + INTENTS_ERRORS["RESOLVER_UNAVAILABLE"] = "Intents Resolver UI unavailable"; + INTENTS_ERRORS["RESOLVER_TIMEOUT"] = "User did not choose a handler"; + INTENTS_ERRORS["INVALID_RESOLVER_RESPONSE"] = "Intents Resolver UI returned invalid response"; + INTENTS_ERRORS["INTENT_HANDLER_REJECTION"] = "Intent Handler function processing the raised intent threw an error or rejected the promise it returned"; + })(INTENTS_ERRORS || (INTENTS_ERRORS = {})); + + class IoC { + _fdc3; + _decoders = decoders$1; + _errors = { + intents: INTENTS_ERRORS + }; + get fdc3() { + if (!this._fdc3) { + this._fdc3 = new FDC3Service().toApi(); + } + return this._fdc3; + } + get decoders() { + return this._decoders; + } + get errors() { + return this._errors; + } + } + + const ioc = new IoC(); + ioc.fdc3; + ioc.decoders; + const errors = ioc.errors; + + const GLUE42_FDC3_INTENTS_METHOD_PREFIX = "Tick42.FDC3.Intents."; + const INTENTS_RESOLVER_INTEROP_PREFIX = "T42.Intents.Resolver.Control"; + const INTENTS_RESOLVER_WIDTH = 400; + const INTENTS_RESOLVER_HEIGHT = 440; + const DEFAULT_RESOLVER_RESPONSE_TIMEOUT = 60 * 1000; + const INTENT_HANDLER_DEFAULT_PROPS = ["applicationName", "type"]; + const INTENTS_RESOLVER_APP_NAME = "intentsResolver"; + const MAX_SET_TIMEOUT_DELAY = 2147483647; + const DEFAULT_METHOD_RESPONSE_TIMEOUT_MS = 60 * 1000; + const DEFAULT_RAISE_TIMEOUT_MS = 90 * 1000; + const DEFAULT_PICK_HANDLER_BY_TIMEOUT_MS = 90 * 1000; + const ERRORS = errors.intents; + + const PromisePlus = (executor, timeoutMilliseconds, timeoutMessage) => { + return new Promise((resolve, reject) => { + const timeout = setTimeout(() => { + const message = timeoutMessage || `Promise timeout hit: ${timeoutMilliseconds}`; + reject(message); + }, timeoutMilliseconds); + const providedPromise = new Promise(executor); + providedPromise + .then((result) => { + clearTimeout(timeout); + resolve(result); + }) + .catch((error) => { + clearTimeout(timeout); + reject(error); + }); + }); + }; + const PromiseWrap = (promise, timeoutMilliseconds, timeoutMessage) => { + return new Promise((resolve, reject) => { + let promiseActive = true; + const timeout = setTimeout(() => { + if (!promiseActive) { + return; + } + promiseActive = false; + const message = timeoutMessage || `Promise timeout hit: ${timeoutMilliseconds}`; + reject(message); + }, timeoutMilliseconds); + promise() + .then((result) => { + if (!promiseActive) { + return; + } + promiseActive = false; + clearTimeout(timeout); + resolve(result); + }) + .catch((error) => { + if (!promiseActive) { + return; + } + promiseActive = false; + clearTimeout(timeout); + reject(error); + }); + }); + }; + + const validateIntentHandlerAsResponse = (handler) => { + if (typeof handler !== "object") { + return { isValid: false, error: `Response object has invalid 'handler' key. Expected an object, got ${typeof handler}` }; + } + const compulsoryKeysExist = INTENT_HANDLER_DEFAULT_PROPS.filter((key) => !(key in handler)); + if (compulsoryKeysExist.length) { + return { isValid: false, error: `Handler in Response object does not provide compulsory keys: ${compulsoryKeysExist.join(", ")}` }; + } + return { isValid: true, ok: handler }; + }; + const validateIntentRequestTarget = (target) => { + if (!target) { + return; + } + if (typeof target !== "string" && typeof target !== "object") { + throw new Error(`Please provide the intent target as one of the valid values: "reuse", "startNew", { app: string }, { instance: string } `); + } + }; + const validateIntentRequestContext = (context) => { + if (!context) { + return; + } + if (typeof context !== "object") { + throw new Error(`Please provide the intent context as an object`); + } + if (context.type && typeof context.type !== "string") { + throw new Error(`Please provide the intent context as an object with 'type' property as string`); + } + if (context.data && typeof context.data !== "object") { + throw new Error(`Please provide the intent context as an object with 'data' property as object`); + } + }; + const validateIntentRequestHandler = (handler) => { + if (!handler.applicationName) { + throw new Error(`Please provide applicationName for handler ${JSON.stringify(handler)}`); + } + if (!handler.type) { + throw new Error(`Please provide type for handler ${JSON.stringify(handler)}`); + } + if (handler.type === "instance" && !handler.instanceId) { + throw new Error(`Please provide instanceId for handler ${JSON.stringify(handler)}`); + } + }; + const validateIntentRequestTimeout = (timeout) => { + if (!timeout) { + return; + } + if (typeof timeout !== "number") { + throw new Error(`Please provide the timeout as a number`); + } + if (timeout <= 0) { + throw new Error(`Please provide the timeout as a positive number`); + } + }; + const validateWaitUserResponseIndefinitely = (waitUserResponseIndefinitely) => { + if (!waitUserResponseIndefinitely) { + return; + } + if (typeof waitUserResponseIndefinitely !== "boolean") { + throw new Error("Please provide waitUserResponseIndefinitely as a boolean"); + } + }; + const validateHandlerFilter = (handlerFilter) => { + if (!handlerFilter) { + throw new Error(`Provide 'handlerFilter' with at least one filter criteria of the following: 'intent' | 'contextTypes' | 'resultType' | 'applicationNames'`); + } + const { title, openResolver, timeout, intent, contextTypes, resultType, applicationNames } = handlerFilter; + if (typeof title !== "undefined" && (typeof title !== "string" || !title.length)) { + throw new Error(`Provide 'title' as a non empty string`); + } + if (typeof openResolver !== "undefined" && typeof openResolver !== "boolean") { + throw new Error(`Provide 'openResolver' prop as a boolean`); + } + if (typeof timeout !== "undefined" && (typeof timeout !== "number" || timeout <= 0)) { + throw new Error(`Provide 'timeout' prop as a positive number`); + } + if (typeof intent !== "undefined" && (typeof intent !== "string" || !intent.length)) { + throw new Error(`Provide 'intent' as a non empty string`); + } + if (typeof contextTypes !== "undefined" && (!Array.isArray(contextTypes) || contextTypes.some(ctx => typeof ctx !== "string"))) { + throw new Error(`Provide 'contextTypes' as an array of non empty strings`); + } + if (typeof resultType !== "undefined" && (typeof resultType !== "string" || !resultType.length)) { + throw new Error(`Provide 'resultType' as a non empty string`); + } + if (typeof applicationNames !== "undefined" && (!Array.isArray(applicationNames) || applicationNames.some(appName => typeof appName !== "string"))) { + throw new Error(`Provide 'applicationNames' as an array of non empty strings`); + } + const errorMsg = "Provide at least one filter criteria of the following: 'intent' | 'contextTypes' | 'resultType' | 'applicationNames'"; + if (!Object.keys(handlerFilter).length) { + throw new Error(errorMsg); + } + if (!intent && !resultType && (!contextTypes || !contextTypes.length) && (!applicationNames || !applicationNames.length)) { + throw new Error(errorMsg); + } + }; + const validateResolverResponse = (responseObj) => { + var _a, _b; + if (typeof responseObj.intent !== "string") { + return { isValid: false, error: `Response object has invalid 'intent' key. Expected a string, got ${typeof responseObj.intent}` }; + } + if (((_a = responseObj.userSettings) === null || _a === void 0 ? void 0 : _a.preserveChoice) && typeof ((_b = responseObj.userSettings) === null || _b === void 0 ? void 0 : _b.preserveChoice) !== "boolean") { + return { isValid: false, error: `Response object has invalid 'userSettings.preserveChoice' key. Expected a boolean, got ${typeof responseObj.userSettings.preserveChoice}` }; + } + const { isValid, error } = validateIntentHandlerAsResponse(responseObj.handler); + return isValid + ? { isValid: true, ok: responseObj } + : { isValid, error }; + }; + const validateIntentRequest = (request) => { + validateIntentRequestContext(request.context); + validateIntentRequestTarget(request.target); + validateIntentRequestTimeout(request.timeout); + validateWaitUserResponseIndefinitely(request.waitUserResponseIndefinitely); + if (typeof request.clearSavedHandler !== "undefined" && typeof request.clearSavedHandler !== "boolean") { + throw new Error("Please provide 'clearSavedHandler' as a boolean"); + } + if (request.handlers) { + request.handlers.forEach((handler) => validateIntentRequestHandler(handler)); + } + }; + const validateIntentHandler = (handler) => { + if (typeof handler !== "object") { + throw new Error("IntentHandler must be an object"); + } + if (typeof handler.applicationName !== "string" || !handler.applicationName.length) { + throw new Error(`Please provide 'applicationName' as a non-empty string`); + } + if (typeof handler.type !== "string" || !["app", "instance"].includes(handler.type)) { + throw new Error(`Invalid 'type' property. Expected 'app' | 'instance' got ${handler.type}`); + } + if (typeof handler.applicationTitle !== "undefined" && typeof handler.applicationTitle !== "string") { + throw new Error(`Provide 'applicationTitle' as a string`); + } + if (typeof handler.applicationDescription !== "undefined" && typeof handler.applicationDescription !== "string") { + throw new Error(`Provide 'applicationDescription' as a string`); + } + if (typeof handler.applicationIcon !== "undefined" && typeof handler.applicationIcon !== "string") { + throw new Error(`Provide 'applicationIcon' as a string`); + } + if (typeof handler.displayName !== "undefined" && typeof handler.displayName !== "string") { + throw new Error(`Provide 'displayName' as a string`); + } + if (typeof handler.contextTypes !== "undefined" && (!Array.isArray(handler.contextTypes) || handler.contextTypes.some(ctx => typeof ctx !== "string"))) { + throw new Error(`Provide 'contextTypes' as an array of non empty strings`); + } + if (typeof handler.instanceId !== "undefined" && typeof handler.instanceId !== "string") { + throw new Error(`Provide 'instanceId' as a string`); + } + if (typeof handler.instanceTitle !== "undefined" && typeof handler.instanceTitle !== "string") { + throw new Error(`Provide 'instanceTitle' as a string`); + } + if (typeof handler.resultType !== "undefined" && typeof handler.resultType !== "string") { + throw new Error(`Provide 'resultType' as a string`); + } + }; + const clearNullUndefined = (obj) => { + Object.keys(obj).forEach(key => { + if (obj[key] === null || obj[key] === undefined) { + delete obj[key]; + } + }); + }; + + class Intents { + constructor(interop, windows, logger, options, prefsController, appManager) { + this.interop = interop; + this.windows = windows; + this.logger = logger; + this.prefsController = prefsController; + this.appManager = appManager; + this.myIntents = new Set(); + this.intentsResolverResponsePromises = {}; + this.useIntentsResolverUI = true; + this.unregisterIntentPromises = []; + this.addedHandlerInfoPerApp = {}; + this.checkIfIntentsResolverIsEnabled(options, appManager); + } + async find(intentFilter) { + await Promise.all(this.unregisterIntentPromises); + let intents = await this.all(); + if (typeof intentFilter === "undefined") { + return intents; + } + if (typeof intentFilter === "string") { + return intents.filter((intent) => intent.name === intentFilter); + } + if (typeof intentFilter !== "object") { + throw new Error("Please provide the intentFilter as a string or an object!"); + } + if (intentFilter.contextType) { + const ctToLower = intentFilter.contextType.toLowerCase(); + intents = intents.filter((intent) => intent.handlers.some((handler) => { var _a; return (_a = handler.contextTypes) === null || _a === void 0 ? void 0 : _a.some((ct) => ct.toLowerCase() === ctToLower); })); + } + if (intentFilter.resultType) { + const resultTypeToLower = intentFilter.resultType.toLowerCase(); + intents = intents.filter((intent) => intent.handlers.some((handler) => { var _a; return ((_a = handler.resultType) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === resultTypeToLower; })); + } + if (intentFilter.name) { + intents = intents.filter((intent) => intent.name === intentFilter.name); + } + return intents; + } + async raise(intentRequest) { + if ((typeof intentRequest !== "string" && typeof intentRequest !== "object") || (typeof intentRequest === "object" && typeof intentRequest.intent !== "string")) { + throw new Error("Please provide the intent as a string or an object with an intent property!"); + } + if (typeof intentRequest === "string") { + intentRequest = { intent: intentRequest }; + } + validateIntentRequest(intentRequest); + await Promise.all(this.unregisterIntentPromises); + if (intentRequest.clearSavedHandler) { + this.logger.trace(`User removes saved handler for intent ${intentRequest.intent}`); + await this.removeRememberedHandler(intentRequest.intent); + } + const resolverInstance = {}; + const timeout = intentRequest.waitUserResponseIndefinitely ? MAX_SET_TIMEOUT_DELAY : intentRequest.timeout || DEFAULT_RAISE_TIMEOUT_MS; + const resultFromRememberedHandler = await this.checkHandleRaiseWithRememberedHandler(intentRequest, resolverInstance, timeout); + if (resultFromRememberedHandler) { + return resultFromRememberedHandler; + } + const coreRaiseIntentFn = this.coreRaiseIntent.bind(this, { request: intentRequest, resolverInstance, timeout }); + if (intentRequest.waitUserResponseIndefinitely) { + return coreRaiseIntentFn(); + } + const resultPromise = PromiseWrap(coreRaiseIntentFn, timeout, `${ERRORS.TIMEOUT_HIT} hit for intent request ${JSON.stringify(intentRequest)}`); + resultPromise.catch(() => this.handleRaiseOnError(resolverInstance.instanceId)); + return resultPromise; + } + async all() { + await Promise.all(this.unregisterIntentPromises); + let apps; + try { + const result = await this.interop.invoke("T42.ACS.GetApplications", { withIntentsInfo: true }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + apps = result.returned.applications; + } + catch (e) { + this.logger.error(`Failed to get the applications!`, e); + return []; + } + const intents = {}; + const appsWithIntents = apps.filter((app) => app.intents && app.intents.length > 0); + for (const app of appsWithIntents) { + for (const intentDef of app.intents) { + let intent = intents[intentDef.name]; + if (!intent) { + intent = { + name: intentDef.name, + handlers: [], + }; + intents[intentDef.name] = intent; + } + const handler = { + applicationName: app.name, + applicationTitle: app.title || "", + applicationDescription: app.caption, + displayName: intentDef.displayName, + contextTypes: intentDef.contexts, + applicationIcon: app.icon, + type: "app", + resultType: intentDef.resultType + }; + intent.handlers.push(handler); + } + } + const servers = this.interop.servers(); + const serverWindowIds = servers.map((server) => server.windowId).filter((serverWindowId) => typeof serverWindowId !== "undefined"); + const T42WndGetInfo = "T42.Wnd.GetInfo"; + const isT42WndGetInfoMethodRegistered = this.interop.methods().some((method) => method.name === T42WndGetInfo); + let windowsInfos; + if (isT42WndGetInfoMethodRegistered) { + try { + const result = await this.interop.invoke(T42WndGetInfo, { ids: serverWindowIds }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + windowsInfos = result.returned.windows; + } + catch (e) { + } + } + for (const server of servers) { + await Promise.all(server.getMethods() + .filter((method) => method.name.startsWith(GLUE42_FDC3_INTENTS_METHOD_PREFIX)) + .map(async (method) => { + const intentName = method.name.replace(GLUE42_FDC3_INTENTS_METHOD_PREFIX, ""); + let intent = intents[intentName]; + if (!intent) { + intent = { + name: intentName, + handlers: [], + }; + intents[intentName] = intent; + } + const title = await this.windowsIdToTitle(server.windowId, windowsInfos); + const handler = this.constructIntentHandler({ method, apps, server, intentName, title }); + intent.handlers.push(handler); + })); + } + return Object.values(intents); + } + addIntentListener(intent, handler) { + if ((typeof intent !== "string" && typeof intent !== "object") || (typeof intent === "object" && typeof intent.intent !== "string")) { + throw new Error("Please provide the intent as a string or an object with an intent property!"); + } + if (typeof handler !== "function") { + throw new Error("Please provide the handler as a function!"); + } + const intentName = typeof intent === "string" ? intent : intent.intent; + const methodName = `${GLUE42_FDC3_INTENTS_METHOD_PREFIX}${intentName}`; + let intentFlag = {}; + let registerPromise; + const alreadyRegistered = this.myIntents.has(intentName); + if (alreadyRegistered) { + throw new Error(`Intent listener for intent ${intentName} already registered!`); + } + this.myIntents.add(intentName); + const result = { + unsubscribe: () => { + this.myIntents.delete(intentName); + registerPromise + .then(() => this.interop.unregister(methodName)) + .catch((err) => this.logger.trace(`Unregistration of a method with name ${methodName} failed with reason: ${JSON.stringify(err)}`)); + } + }; + if (typeof intent === "object") { + const { intent: removed, ...rest } = intent; + intentFlag = rest; + } + registerPromise = this.interop.register({ name: methodName, flags: { intent: intentFlag } }, (args) => { + if (this.myIntents.has(intentName)) { + return handler(args); + } + }); + registerPromise.catch((err) => { + this.myIntents.delete(intentName); + this.logger.warn(`Registration of a method with name ${methodName} failed with reason: ${JSON.stringify(err)}`); + }); + return result; + } + async register(intent, handler) { + if ((typeof intent !== "string" && typeof intent !== "object") || (typeof intent === "object" && typeof intent.intent !== "string")) { + throw new Error("Please provide the intent as a string or an object with an intent property!"); + } + if (typeof handler !== "function") { + throw new Error("Please provide the handler as a function!"); + } + await Promise.all(this.unregisterIntentPromises); + const intentName = typeof intent === "string" ? intent : intent.intent; + const methodName = this.buildInteropMethodName(intentName); + let intentFlag = {}; + const alreadyRegistered = this.myIntents.has(intentName); + if (alreadyRegistered) { + throw new Error(`Intent listener for intent ${intentName} already registered!`); + } + this.myIntents.add(intentName); + if (typeof intent === "object") { + const { intent: removed, ...rest } = intent; + intentFlag = rest; + } + try { + await this.interop.register({ name: methodName, flags: { intent: intentFlag } }, (args, caller) => { + if (this.myIntents.has(intentName)) { + return handler(args, caller); + } + }); + } + catch (err) { + this.myIntents.delete(intentName); + throw new Error(`Registration of a method with name ${methodName} failed with reason: ${JSON.stringify(err)}`); + } + return { + unsubscribe: () => this.unsubscribeIntent(intentName) + }; + } + async filterHandlers(handlerFilter) { + var _a, _b; + validateHandlerFilter(handlerFilter); + if (handlerFilter.openResolver && !this.useIntentsResolverUI) { + throw new Error("Cannot resolve 'filterHandlers' request using Intents Resolver UI because it's globally disabled"); + } + (_a = this.logger) === null || _a === void 0 ? void 0 : _a.trace(`Received 'filterHandlers' command with request: ${JSON.stringify(handlerFilter)}`); + const filteredHandlers = this.filterHandlersBy(await this.all(), handlerFilter); + if (!filteredHandlers || !filteredHandlers.length) { + return { handlers: [] }; + } + const { open, reason } = this.checkIfResolverShouldBeOpenedForFilterHandlers(filteredHandlers, handlerFilter); + if (!open) { + (_b = this.logger) === null || _b === void 0 ? void 0 : _b.trace(`Intent Resolver UI won't be used. Reason: ${reason}`); + return { handlers: filteredHandlers }; + } + const resolverInstance = { instanceId: undefined }; + const timeout = handlerFilter.timeout || DEFAULT_PICK_HANDLER_BY_TIMEOUT_MS; + const handler = await PromiseWrap(() => this.startResolverApp({ request: handlerFilter, resolverInstance, method: 'filterHandlers' }), timeout, `Timeout of ${timeout}ms hit for 'filterHandlers' request with filter: ${JSON.stringify(handlerFilter)}`); + return { handlers: [handler] }; + } + async getIntents(handler) { + var _a; + this.logger.trace(`Received 'getIntents' command with handler ${JSON.stringify(handler)}`); + validateIntentHandler(handler); + const intents = await this.all(); + clearNullUndefined(handler); + (_a = this.logger) === null || _a === void 0 ? void 0 : _a.trace(`Extracting valid intents for the passed handler`); + const intentsWithInfo = this.extractIntentsWithInfoByHandler(intents, handler); + this.logger.trace(`Returning intents for handler ${JSON.stringify(handler)}`); + return { intents: intentsWithInfo }; + } + async clearSavedHandlers() { + this.logger.trace("Removing all saved handlers from prefs storage for current app"); + await this.prefsController.update({ intents: undefined }); + } + onHandlerAdded(callback) { + var _a; + const unAppAdded = (_a = this.appManager) === null || _a === void 0 ? void 0 : _a.onAppAdded(async (app) => { + var _a; + const appName = app.name; + const appDef = await app.getConfiguration(); + const isIntentHandler = (_a = appDef === null || appDef === void 0 ? void 0 : appDef.intents) === null || _a === void 0 ? void 0 : _a.length; + if (!isIntentHandler) { + return; + } + appDef.intents.forEach((intent) => { + const handler = this.constructIntentHandlerFromApp(appDef, intent); + if (!this.addedHandlerInfoPerApp[appName]) { + this.addedHandlerInfoPerApp[appName] = []; + } + const appHandlers = this.addedHandlerInfoPerApp[appName]; + appHandlers.push({ handler, name: intent.name }); + callback(handler, intent.name); + }); + }); + const unServerMethodAdded = this.interop.serverMethodAdded(({ method, server }) => { + if (!method.name.startsWith(GLUE42_FDC3_INTENTS_METHOD_PREFIX)) { + return; + } + const intentName = method.name.replace(GLUE42_FDC3_INTENTS_METHOD_PREFIX, ""); + const intentsInfo = this.constructIntentHandler({ method, apps: [], server, intentName, title: "" }); + callback(intentsInfo, intentName); + }); + return () => { + if (typeof unServerMethodAdded === "function") { + unServerMethodAdded(); + } + if (typeof unAppAdded === "function") { + unAppAdded(); + } + }; + } + onHandlerRemoved(callback) { + var _a; + const unAppRemoved = (_a = this.appManager) === null || _a === void 0 ? void 0 : _a.onAppRemoved(async (app) => { + const appName = app.name; + const handlers = this.addedHandlerInfoPerApp[appName]; + const isIntentHandler = handlers === null || handlers === void 0 ? void 0 : handlers.length; + if (!isIntentHandler) { + return; + } + delete this.addedHandlerInfoPerApp[appName]; + handlers.forEach((addedHandlerInfo) => { + callback(addedHandlerInfo.handler, addedHandlerInfo.name); + }); + }); + const unServerMethodAdded = this.interop.serverMethodRemoved(({ method, server }) => { + if (!method.name.startsWith(GLUE42_FDC3_INTENTS_METHOD_PREFIX)) { + return; + } + const intentName = method.name.replace(GLUE42_FDC3_INTENTS_METHOD_PREFIX, ""); + const intentsInfo = this.constructIntentHandler({ method, apps: [], server, intentName, title: "" }); + callback(intentsInfo, intentName); + }); + return () => { + if (typeof unServerMethodAdded === "function") { + unServerMethodAdded(); + } + if (typeof unAppRemoved === "function") { + unAppRemoved(); + } + }; + } + toAPI() { + return { + all: this.all.bind(this), + find: this.find.bind(this), + raise: this.raise.bind(this), + addIntentListener: this.addIntentListener.bind(this), + register: this.register.bind(this), + filterHandlers: this.filterHandlers.bind(this), + getIntents: this.getIntents.bind(this), + clearSavedHandlers: this.clearSavedHandlers.bind(this), + onHandlerAdded: this.onHandlerAdded.bind(this), + onHandlerRemoved: this.onHandlerRemoved.bind(this) + }; + } + filterHandlersBy(intents, filter) { + const filteredIntentsWithHandlers = intents.filter((intent) => { + if (filter.intent && filter.intent !== intent.name) { + return; + } + if (filter.resultType) { + const filteredHandlers = intent.handlers.filter((handler) => handler.resultType && handler.resultType === filter.resultType); + if (!filteredHandlers.length) + return; + intent.handlers = filteredHandlers; + } + if (filter.contextTypes) { + const filteredHandlers = intent.handlers.filter((handler) => { var _a; return (_a = filter.contextTypes) === null || _a === void 0 ? void 0 : _a.every((contextType) => { var _a; return (_a = handler.contextTypes) === null || _a === void 0 ? void 0 : _a.includes(contextType); }); }); + if (!filteredHandlers.length) + return; + intent.handlers = filteredHandlers; + } + if (filter.applicationNames) { + const filteredHandlers = intent.handlers.filter((handler) => { var _a; return (_a = filter.applicationNames) === null || _a === void 0 ? void 0 : _a.includes(handler.applicationName); }); + if (!filteredHandlers.length) + return; + intent.handlers = filteredHandlers; + } + return intent; + }); + return filteredIntentsWithHandlers.map((intent) => intent.handlers).flat(1); + } + async coreRaiseIntent({ request, resolverInstance, timeout }) { + var _a, _b; + const intentDef = await this.get(request.intent); + if (typeof intentDef === "undefined") { + throw new Error(`${ERRORS.INTENT_NOT_FOUND} with name ${request.intent}`); + } + const { open, reason } = await this.checkIfResolverShouldBeOpenedForRaise(intentDef, request); + if (!open) { + this.logger.trace(`Intent Resolver UI won't be used. Reason: ${reason}`); + return request.waitUserResponseIndefinitely + ? PromiseWrap(() => this.raiseIntent(request, timeout), timeout, `${ERRORS.TIMEOUT_HIT} - waited ${timeout}ms for 'raise' to resolve`) + : this.raiseIntent(request, timeout); + } + const resolverHandler = await this.startResolverApp({ request, method: "raise", resolverInstance }); + (_a = this.logger) === null || _a === void 0 ? void 0 : _a.trace(`Raising intent to target handler: ${JSON.stringify(resolverHandler)} with timeout of ${timeout}`); + if (request.waitUserResponseIndefinitely) { + return PromiseWrap(() => this.raiseIntentToTargetHandler(request, resolverHandler, timeout), timeout, `${ERRORS.TIMEOUT_HIT} - waited ${timeout}ms for 'raise' to resolve`); + } + const result = await this.raiseIntentToTargetHandler(request, resolverHandler, timeout); + (_b = this.logger) === null || _b === void 0 ? void 0 : _b.trace(`Result from raise() method for intent ${JSON.stringify(request.intent)}: ${JSON.stringify(result)}`); + return result; + } + async get(intent) { + return (await this.all()).find((registeredIntent) => registeredIntent.name === intent); + } + async raiseIntent(intentRequest, timeout) { + const intentName = intentRequest.intent; + const intentDef = await this.get(intentName); + if (typeof intentDef === "undefined") { + throw new Error(`${ERRORS.INTENT_NOT_FOUND} with name ${intentRequest.intent}`); + } + const firstFoundAppHandler = intentRequest.handlers ? this.findHandlerByFilter(intentRequest.handlers, { type: "app" }) : this.findHandlerByFilter(intentDef.handlers, { type: "app" }); + const firstFoundInstanceHandler = intentRequest.handlers ? this.findHandlerByFilter(intentRequest.handlers, { type: "instance" }) : this.findHandlerByFilter(intentDef.handlers, { type: "instance" }); + let handler; + if (!intentRequest.target || intentRequest.target === "reuse") { + handler = firstFoundInstanceHandler || firstFoundAppHandler; + } + if (intentRequest.target === "startNew") { + handler = firstFoundAppHandler; + } + if (typeof intentRequest.target === "object" && intentRequest.target.app) { + handler = this.findHandlerByFilter(intentDef.handlers, { app: intentRequest.target.app }); + } + if (typeof intentRequest.target === "object" && intentRequest.target.instance) { + handler = this.findHandlerByFilter(intentDef.handlers, { instance: intentRequest.target.instance, app: intentRequest.target.app }); + } + if (!handler) { + throw new Error(`Can not raise intent for request ${JSON.stringify(intentRequest)} - can not find intent handler!`); + } + const result = await this.raiseIntentToTargetHandler(intentRequest, handler, timeout); + return result; + } + async raiseIntentToTargetHandler(intentRequest, handler, timeout) { + var _a, _b; + (_a = this.logger) === null || _a === void 0 ? void 0 : _a.trace(`Raising intent to target handler:${JSON.stringify(handler)}`); + if (!handler.instanceId) { + const instanceIdPromise = this.invokeStartApp(handler.applicationName, intentRequest.context, intentRequest.options).catch((err) => { + const reasonMsg = typeof err === "string" ? err : JSON.stringify(err); + throw new Error(`${ERRORS.TARGET_INSTANCE_UNAVAILABLE}. Reason: ${reasonMsg}`); + }); + handler.instanceId = await instanceIdPromise; + } + const methodName = `${GLUE42_FDC3_INTENTS_METHOD_PREFIX}${intentRequest.intent}`; + const invokeOptions = { + methodResponseTimeoutMs: timeout ? timeout + 1000 : DEFAULT_METHOD_RESPONSE_TIMEOUT_MS, + waitTimeoutMs: timeout ? timeout + 1000 : DEFAULT_METHOD_RESPONSE_TIMEOUT_MS + }; + const resultPromise = this.interop.invoke(methodName, intentRequest.context, { instance: handler.instanceId }, invokeOptions) + .catch((err) => { + const reasonMsg = typeof err === "string" ? err : JSON.stringify(err); + throw new Error(`${ERRORS.INTENT_HANDLER_REJECTION}. Reason: ${reasonMsg}`); + }); + const result = await resultPromise; + (_b = this.logger) === null || _b === void 0 ? void 0 : _b.trace(`raiseIntent command completed. Returning result: ${JSON.stringify(result)}`); + return { + request: intentRequest, + handler: { ...handler, type: "instance" }, + result: result.returned + }; + } + async startResolverApp({ request, method, resolverInstance }) { + var _a, _b, _c, _d; + (_a = this.logger) === null || _a === void 0 ? void 0 : _a.trace(`Intents Resolver UI with app name ${this.intentsResolverAppName} will be used for request: ${JSON.stringify(request)}`); + const responseMethodName = await this.registerIntentResolverMethod(); + (_b = this.logger) === null || _b === void 0 ? void 0 : _b.trace(`Registered interop method ${responseMethodName}`); + const startContext = this.buildStartContext(method, request, responseMethodName); + const startOptions = await this.buildStartOptions(); + (_c = this.logger) === null || _c === void 0 ? void 0 : _c.trace(`Starting Intents Resolver UI with context: ${JSON.stringify(startContext)} and options: ${JSON.stringify(startOptions)}`); + const instance = await this.appManager.application(this.intentsResolverAppName).start(startContext, startOptions); + resolverInstance.instanceId = instance.id; + (_d = this.logger) === null || _d === void 0 ? void 0 : _d.trace(`Intents Resolver instance with id ${instance.id} opened`); + this.subscribeOnInstanceStopped(instance, method); + const timeout = request.timeout || method === "raise" ? DEFAULT_RAISE_TIMEOUT_MS : DEFAULT_PICK_HANDLER_BY_TIMEOUT_MS; + this.createResponsePromise({ + intent: method === "raise" ? request.intent : undefined, + instanceId: instance.id, + responseMethodName, + timeout, + errorMsg: `Timeout of ${timeout}ms hit waiting for the user to choose a handler ${method === "raise" + ? `for intent ${request.intent}` + : `for '${method}' method with filter ${JSON.stringify(request)}`}` + }); + const handler = await this.handleInstanceResponse({ instanceId: instance.id, caller: startContext.initialCaller, method, request }); + return handler; + } + async windowsIdToTitle(id, windowsInfos) { + var _a, _b; + if (typeof windowsInfos !== "undefined") { + return (_a = windowsInfos.find((windowsInfo) => windowsInfo.id === id)) === null || _a === void 0 ? void 0 : _a.title; + } + const window = (_b = this.windows) === null || _b === void 0 ? void 0 : _b.findById(id); + const title = await (window === null || window === void 0 ? void 0 : window.getTitle()); + return title; + } + async handleInstanceResponse({ instanceId, method, request, caller }) { + var _a, _b, _c; + try { + const response = await this.intentsResolverResponsePromises[instanceId].promise; + const subMessage = method === "raise" ? `for intent ${response.intent} ` : ""; + (_a = this.logger) === null || _a === void 0 ? void 0 : _a.trace(`Intent handler chosen ${subMessage}: ${JSON.stringify(response.handler)}. Stopping resolver instance with id ${instanceId}`); + this.stopResolverInstance(instanceId); + (_b = this.logger) === null || _b === void 0 ? void 0 : _b.trace(`Instance with id ${instanceId} successfully stopped`); + if ((_c = response.userSettings) === null || _c === void 0 ? void 0 : _c.preserveChoice) { + await this.saveUserChoice({ + intent: response.intent, + handler: response.handler, + filter: method === "filterHandlers" + ? { applicationNames: request.applicationNames, contextTypes: request.contextTypes, resultType: request.resultType } + : undefined, + caller + }); + } + return response.handler; + } + catch (error) { + this.stopResolverInstance(instanceId); + throw new Error(error); + } + } + async registerIntentResolverMethod() { + const methodName = INTENTS_RESOLVER_INTEROP_PREFIX + Utils.generateId(); + await this.interop.register(methodName, (args, callerId) => this.resolverResponseHandler(args, callerId)); + return methodName; + } + resolverResponseHandler(args, callerId) { + const { instance } = callerId; + const isValid = validateResolverResponse(args); + if (!isValid) { + this.logger.trace(`Intent Resolver instance with id ${callerId.instance} sent invalid response. Error: ${isValid.error}`); + this.intentsResolverResponsePromises[instance].reject(isValid.error); + this.stopResolverInstance(instance); + return; + } + const validResponse = isValid.ok; + this.intentsResolverResponsePromises[instance].resolve(validResponse); + this.cleanUpIntentResolverPromise(instance); + } + buildStartContext(method, request, methodName) { + var _a; + const myAppName = this.interop.instance.application || this.interop.instance.applicationName; + const myAppTitle = ((_a = this.appManager.application(myAppName)) === null || _a === void 0 ? void 0 : _a.title) || ""; + const baseStartContext = { + callerId: this.interop.instance.instance, + methodName, + initialCaller: { id: this.interop.instance.instance, applicationName: myAppName, applicationTitle: myAppTitle }, + resolverApi: "1.0" + }; + return method === "raise" + ? { ...baseStartContext, intent: request } + : { ...baseStartContext, handlerFilter: request }; + } + async buildStartOptions() { + const win = this.windows.my(); + if (!win) { + return; + } + const bounds = await win.getBounds(); + return { + top: await this.getResolverStartupTopBound(bounds), + left: (bounds.width - INTENTS_RESOLVER_WIDTH) / 2 + bounds.left, + width: INTENTS_RESOLVER_WIDTH, + height: INTENTS_RESOLVER_HEIGHT + }; + } + async getResolverStartupTopBound(bounds) { + const myDisplay = await this.windows.my().getDisplay(); + const minWorkareaHeight = myDisplay.workArea.height; + const top = (bounds.height - INTENTS_RESOLVER_HEIGHT) / 2 + bounds.top; + if (top < 0) { + return 0; + } + if (top + INTENTS_RESOLVER_HEIGHT > minWorkareaHeight) { + return minWorkareaHeight / 2; + } + return top; + } + createResponsePromise({ instanceId, intent, responseMethodName, timeout, errorMsg }) { + let resolve = () => { }; + let reject = () => { }; + const promise = PromisePlus((res, rej) => { + resolve = res; + reject = rej; + }, timeout, errorMsg); + this.intentsResolverResponsePromises[instanceId] = { intent, resolve, reject, promise, methodName: responseMethodName }; + } + async invokeStartApp(application, context, options) { + const result = await this.interop.invoke("T42.ACS.StartApplication", { Name: application, options: { ...options, startedByIntentAPI: true } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return result.returned.Id; + } + subscribeOnInstanceStopped(instance, method) { + const { application } = instance; + const unsub = application.onInstanceStopped((inst) => { + if (inst.id !== instance.id) { + return; + } + const intentPromise = this.intentsResolverResponsePromises[inst.id]; + if (!intentPromise) { + return unsub(); + } + const errorMsg = `Cannot resolve ${method === "raise" ? `raised intent ${intentPromise.intent}` : `'${method}' method`} - User closed ${instance.application.name} app without choosing a handler`; + intentPromise.reject(errorMsg); + this.cleanUpIntentResolverPromise(inst.id); + unsub(); + }); + } + async cleanUpIntentResolverPromise(instanceId) { + const intentPromise = this.intentsResolverResponsePromises[instanceId]; + if (!intentPromise) { + return; + } + const unregisterPromise = this.interop.unregister(intentPromise.methodName); + unregisterPromise.catch((error) => this.logger.warn(error)); + delete this.intentsResolverResponsePromises[instanceId]; + } + handleRaiseOnError(instanceId) { + if (!instanceId) { + return; + } + this.stopResolverInstance(instanceId); + } + stopResolverInstance(instanceId) { + const gdWin = this.windows.findById(instanceId); + gdWin === null || gdWin === void 0 ? void 0 : gdWin.close().catch((err) => this.logger.error(err)); + } + checkIfIntentsResolverIsEnabled(options, appManager) { + var _a, _b, _c, _d, _e; + if (!appManager) { + this.useIntentsResolverUI = false; + return; + } + this.useIntentsResolverUI = typeof ((_a = options.intents) === null || _a === void 0 ? void 0 : _a.enableIntentsResolverUI) === "boolean" + ? options.intents.enableIntentsResolverUI + : true; + this.intentsResolverAppName = (_c = (_b = options.intents) === null || _b === void 0 ? void 0 : _b.intentsResolverAppName) !== null && _c !== void 0 ? _c : INTENTS_RESOLVER_APP_NAME; + this.intentsResolverResponseTimeout = (_e = (_d = options.intents) === null || _d === void 0 ? void 0 : _d.methodResponseTimeoutMs) !== null && _e !== void 0 ? _e : DEFAULT_RESOLVER_RESPONSE_TIMEOUT; + } + async checkIfResolverShouldBeOpenedForRaise(intent, request) { + const checkOpen = this.checkIfIntentsResolverShouldBeOpened(); + if (!checkOpen.open) { + return checkOpen; + } + const hasMoreThanOneHandler = await this.checkIfIntentHasMoreThanOneHandler(intent, request); + if (!hasMoreThanOneHandler) { + return { open: false, reason: `Raised intent ${intent.name} has only one handler` }; + } + return { open: true }; + } + checkIfResolverShouldBeOpenedForFilterHandlers(handlers, filter) { + if (handlers.length === 1) { + return { open: false, reason: `There's only one valid intent handler for filter ${JSON.stringify(filter)}` }; + } + if (typeof (filter === null || filter === void 0 ? void 0 : filter.openResolver) === "boolean" && !filter.openResolver) { + return { open: false, reason: "Intents resolver is disabled by IntentHandler filter" }; + } + return this.checkIfIntentsResolverShouldBeOpened(); + } + checkIfIntentsResolverShouldBeOpened() { + if (!this.useIntentsResolverUI) { + return { open: false, reason: `Intent Resolver is disabled. Resolving to first found handler` }; + } + const intentsResolverApp = this.appManager.application(this.intentsResolverAppName); + if (!intentsResolverApp) { + return { open: false, reason: `Intent Resolver Application with name ${this.intentsResolverAppName} not found.` }; + } + return { open: true }; + } + async checkIfIntentHasMoreThanOneHandler(intent, request) { + const handlers = await this.removeSingletons(request.handlers || intent.handlers); + if (!request.target) { + return handlers.length > 1; + } + if (request.target === "reuse") { + return handlers.filter(handler => handler.type === "instance" && handler.instanceId).length > 1 || intent.handlers.filter(handler => handler.type === "app").length > 1; + } + if (request.target === "startNew") { + return handlers.filter(handler => handler.type === "app").length > 1; + } + if (request.target.instance) { + return false; + } + if (request.target.app) { + const searchedAppName = request.target.app; + const instanceHandlersByAppName = handlers.filter((handler) => handler.applicationName === searchedAppName && handler.instanceId); + return instanceHandlersByAppName.length > 1; + } + return false; + } + async removeSingletons(handlers) { + const handlersWithSingletonProp = await Promise.all(handlers.map(async (handler) => { + if (handler.type === "instance") { + return handler; + } + const appConfig = await this.appManager.application(handler.applicationName).getConfiguration(); + const isSingleton = appConfig.allowMultiple === false; + return { ...handler, isSingleton }; + })); + const filteredSingletonsWithOpenedInstances = handlersWithSingletonProp.filter((handler, _, currentHandlers) => { + if (handler.instanceId || !handler.isSingleton) { + return handler; + } + const openedInstance = currentHandlers.find((h) => h.instanceId && h.applicationName === handler.applicationName); + if (openedInstance) { + return; + } + return handler; + }); + return filteredSingletonsWithOpenedInstances; + } + buildInteropMethodName(intentName) { + return `${GLUE42_FDC3_INTENTS_METHOD_PREFIX}${intentName}`; + } + clearUnregistrationPromise(promiseToRemove) { + this.unregisterIntentPromises = this.unregisterIntentPromises.filter((promise) => promise !== promiseToRemove); + } + unsubscribeIntent(intentName) { + this.myIntents.delete(intentName); + const methodName = this.buildInteropMethodName(intentName); + const unregisterPromise = this.interop.unregister(methodName); + this.unregisterIntentPromises.push(unregisterPromise); + unregisterPromise + .then(() => { + this.clearUnregistrationPromise(unregisterPromise); + }) + .catch((err) => { + this.logger.error(`Unregistration of a method with name ${methodName} failed with reason: `, err); + this.clearUnregistrationPromise(unregisterPromise); + }); + } + findHandlerByFilter(handlers, filter) { + if (filter.type) { + return handlers.find((handler) => handler.type === filter.type); + } + if (filter.instance) { + return handlers.find((handler) => filter.app + ? handler.applicationName === filter.app && handler.instanceId === filter.instance + : handler.instanceId === filter.instance); + } + if (filter.app) { + return handlers.find((handler) => handler.applicationName === filter.app); + } + } + extractIntentsWithInfoByHandler(intents, handler) { + const intentsWithInfo = intents.reduce((validIntentsWithInfo, intent) => { + intent.handlers.forEach((currentHandler) => { + const isValid = Object.keys(handler).every((key) => { + var _a; + return key === "contextTypes" + ? (_a = handler.contextTypes) === null || _a === void 0 ? void 0 : _a.every((contextType) => { var _a; return (_a = currentHandler.contextTypes) === null || _a === void 0 ? void 0 : _a.includes(contextType); }) + : currentHandler[key] === handler[key]; + }); + if (!isValid) { + return; + } + const intentWithInfo = { + intent: intent.name, + contextTypes: currentHandler.contextTypes, + description: currentHandler.applicationDescription, + displayName: currentHandler.displayName, + icon: currentHandler.applicationIcon, + resultType: currentHandler.resultType + }; + validIntentsWithInfo.push(intentWithInfo); + }); + return validIntentsWithInfo; + }, []); + return intentsWithInfo; + } + async removeRememberedHandler(intentName) { + var _a; + this.logger.trace(`Removing saved handler from prefs storage for intent ${intentName}`); + let prefs; + try { + prefs = await this.prefsController.get(); + } + catch (error) { + this.logger.warn(`prefs.get() threw the following error: ${typeof error === "string" ? error : JSON.stringify(error)}`); + return; + } + const intentPrefs = (_a = prefs.data) === null || _a === void 0 ? void 0 : _a.intents; + if (!intentPrefs) { + this.logger.trace("No app prefs found for current app"); + return; + } + delete intentPrefs[intentName]; + const updatedPrefs = { + ...prefs.data, + intents: intentPrefs + }; + try { + await this.prefsController.update(updatedPrefs); + } + catch (error) { + this.logger.warn(`prefs.update() threw the following error: ${typeof error === "string" ? error : JSON.stringify(error)}`); + return; + } + this.logger.trace(`Handler saved choice for intent ${intentName} removed successfully`); + } + async checkForRememberedHandler(intentRequest) { + var _a, _b; + let prefs; + try { + prefs = await this.prefsController.get(); + } + catch (error) { + this.logger.warn(`prefs.get() threw the following error: ${typeof error === "string" ? error : JSON.stringify(error)}`); + return; + } + const prefsForIntent = (_b = (_a = prefs.data) === null || _a === void 0 ? void 0 : _a.intents) === null || _b === void 0 ? void 0 : _b[intentRequest.intent]; + return prefsForIntent === null || prefsForIntent === void 0 ? void 0 : prefsForIntent.handler; + } + async checkHandleRaiseWithRememberedHandler(intentRequest, resolverInstance, timeout) { + if (intentRequest.target) { + return; + } + const rememberedHandler = await this.checkForRememberedHandler(intentRequest); + if (!rememberedHandler) { + return; + } + const request = { + ...intentRequest, + target: { + app: rememberedHandler.applicationName, + instance: rememberedHandler.instanceId + } + }; + try { + const response = await this.coreRaiseIntent({ request, resolverInstance, timeout }); + return response; + } + catch (error) { + this.logger.trace("Could not raise intent to remembered handler. Removing it from Prefs store"); + await this.removeRememberedHandler(intentRequest.intent); + } + } + async saveUserChoice({ intent, handler, filter, caller }) { + var _a, _b; + const prevPrefs = await this.prefsController.get(caller.applicationName); + const prevIntentsPrefs = ((_a = prevPrefs === null || prevPrefs === void 0 ? void 0 : prevPrefs.data) === null || _a === void 0 ? void 0 : _a.intents) || {}; + const prefsToUpdate = { + ...prevPrefs.data, + intents: { + ...prevIntentsPrefs, + [intent]: { handler, filter } + } + }; + await this.prefsController.update(prefsToUpdate, { app: caller.applicationName }); + (_b = this.logger) === null || _b === void 0 ? void 0 : _b.info(`Saved user's choice of handler for '${caller.applicationName}' app`); + } + constructIntentHandler({ apps, intentName, method, server, title }) { + const info = method.flags.intent; + const app = apps.find((appWithIntents) => appWithIntents.name === server.application); + let appIntent; + if (app === null || app === void 0 ? void 0 : app.intents) { + appIntent = app.intents.find((appDefIntent) => appDefIntent.name === intentName); + } + const handler = { + instanceId: server.instance, + applicationName: server.application, + applicationIcon: info.icon || (app === null || app === void 0 ? void 0 : app.icon), + applicationTitle: (app === null || app === void 0 ? void 0 : app.title) || "", + applicationDescription: info.description || (app === null || app === void 0 ? void 0 : app.caption), + displayName: info.displayName || (appIntent === null || appIntent === void 0 ? void 0 : appIntent.displayName), + contextTypes: info.contextTypes || (appIntent === null || appIntent === void 0 ? void 0 : appIntent.contexts), + instanceTitle: title, + type: "instance", + resultType: (appIntent === null || appIntent === void 0 ? void 0 : appIntent.resultType) || info.resultType + }; + return handler; + } + constructIntentHandlerFromApp(app, intent) { + return { + applicationName: app.name, + applicationTitle: app.title || "", + applicationDescription: app.caption, + displayName: intent.displayName, + contextTypes: intent.contexts, + applicationIcon: app.icon, + type: "app", + resultType: intent.resultType + }; + } + } + + class FactoryCallInfo { + constructor() { + this.initialized = false; + this.details = []; + this.reject = () => { }; + this.resolve = () => { }; + } + init(config) { + this.initialized = true; + this.addCall(config); + this.promise = new Promise((resolve, reject) => { + this.resolve = resolve; + this.reject = reject; + }); + } + addCall(config) { + this.details.push({ date: new Date(), config }); + } + done(g) { + this.resolve(g); + } + error(e) { + this.reject(e); + } + } + + class Prefs { + constructor(appName, interop) { + this.appName = appName; + this.interop = interop; + this.registry = CallbackRegistryFactory(); + this.interopMethodRegistered = false; + } + async get(app) { + const data = (await this.interop.invoke(Prefs.T42GetPrefsMethodName, { app: app !== null && app !== void 0 ? app : this.appName }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + })); + return data.returned; + } + async set(data, options) { + var _a; + this.verifyDataObject(data); + await this.interop.invoke(Prefs.T42SetPrefsMethodName, { app: (_a = options === null || options === void 0 ? void 0 : options.app) !== null && _a !== void 0 ? _a : this.appName, data, merge: false }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async setFor(app, data) { + this.verifyApp(app); + this.verifyDataObject(data); + return this.set(data, { app }); + } + async update(data, options) { + var _a; + this.verifyDataObject(data); + await this.interop.invoke(Prefs.T42SetPrefsMethodName, { app: (_a = options === null || options === void 0 ? void 0 : options.app) !== null && _a !== void 0 ? _a : this.appName, data, merge: true }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async updateFor(app, data) { + this.verifyApp(app); + this.verifyDataObject(data); + return this.update(data, { app }); + } + async clear(app) { + await this.interop.invoke(Prefs.T42SetPrefsMethodName, { app: app !== null && app !== void 0 ? app : this.appName, clear: true }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async clearFor(app) { + this.verifyApp(app); + await this.interop.invoke(Prefs.T42SetPrefsMethodName, { app, clear: true }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async getAll() { + const data = (await this.interop.invoke(Prefs.T42GetPrefsMethodName, undefined, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + })); + return data.returned; + } + async clearAll() { + await this.interop.invoke(Prefs.T42SetPrefsMethodName, { clear: true }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + subscribe(callback) { + this.verifyCallback(callback); + return this.subscribeFor(this.appName, callback); + } + subscribeFor(app, callback) { + this.verifyApp(app); + this.verifyCallback(callback); + const unsubscribeFn = this.registry.add(app, callback); + this.registerInteropIfNeeded() + .then(() => { + this.interop.invoke(Prefs.T42GetPrefsMethodName, { app, subscribe: true }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + }); + return () => { + unsubscribeFn(); + }; + } + async registerInteropIfNeeded() { + if (this.interopMethodRegistered) { + return; + } + this.interopMethodRegistered = true; + await this.interop.register(Prefs.T42UpdatePrefsMethodName, (args) => { + this.registry.execute(args.app, args); + }); + } + verifyApp(app) { + if (!app) { + throw new Error(`app should be defined`); + } + if (!isString(app)) { + throw new Error(`app should be a string`); + } + } + verifyDataObject(data) { + if (!data) { + throw new Error(`data should be defined`); + } + if (!isObject(data)) { + throw new Error(`data should be an object`); + } + } + verifyCallback(callback) { + if (!isFunction(callback)) { + throw new Error(`callback should be defined`); + } + } + } + Prefs.T42UpdatePrefsMethodName = "T42.Prefs.Update"; + Prefs.T42GetPrefsMethodName = "T42.Prefs.Get"; + Prefs.T42SetPrefsMethodName = "T42.Prefs.Set"; + + class Cookies { + constructor(methodName, interop) { + this.methodName = methodName; + this.interop = interop; + } + async get(filter) { + const result = await this.invoke("get-cookies", { filter }); + return result.returned.cookies; + } + async set(cookie) { + this.verifyCookieObject(cookie); + await this.invoke("set-cookie", cookie); + } + async remove(url, name) { + if (!isString(url)) { + throw new Error(`url should be a string`); + } + if (!isString(name)) { + throw new Error(`name should be a string`); + } + await this.invoke("remove-cookie", { url, name }); + } + invoke(command, data) { + return this.interop.invoke(this.methodName, { command, args: data }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_RESPONSE_TIMEOUT_MS, + }); + } + verifyCookieObject(cookie) { + if (!cookie) { + throw new Error(`cookie should be defined`); + } + if (!isObject(cookie)) { + throw new Error(`cookie should be an object`); + } + if (Utils.isNullOrUndefined(cookie.url) || !isString(cookie.url)) { + throw new Error(`cookie.url should be a string`); + } + if (Utils.isNullOrUndefined(cookie.name) || !isString(cookie.name)) { + throw new Error(`cookie.name should be a string`); + } + if (!Utils.isNullOrUndefined(cookie.value) && !isString(cookie.value)) { + throw new Error(`cookie.value should be a string`); + } + if (!Utils.isNullOrUndefined(cookie.domain) && !isString(cookie.domain)) { + throw new Error(`cookie.domain should be a string`); + } + if (!Utils.isNullOrUndefined(cookie.path) && !isString(cookie.path)) { + throw new Error(`cookie.path should be a string`); + } + if (!Utils.isNullOrUndefined(cookie.secure) && typeof cookie.secure !== "boolean") { + throw new Error(`cookie.secure should be a boolean`); + } + if (!Utils.isNullOrUndefined(cookie.httpOnly) && typeof cookie.httpOnly !== "boolean") { + throw new Error(`cookie.httpOnly should be a boolean`); + } + if (!Utils.isNullOrUndefined(cookie.expirationDate) && typeof cookie.expirationDate !== "number") { + throw new Error(`cookie.expirationDate should be a number`); + } + } + } + + function factory$1(agm, methodName) { + const cookies = new Cookies(methodName, agm); + return { + get: cookies.get.bind(cookies), + remove: cookies.remove.bind(cookies), + set: cookies.set.bind(cookies), + ready: () => Promise.resolve() + }; + } + + class EventsDispatcher { + constructor(config) { + this.config = config; + this.glue42EventName = "Glue42"; + this.events = { + notifyStarted: { name: "notifyStarted", handle: this.handleNotifyStarted.bind(this) }, + requestGlue: { name: "requestGlue", handle: this.handleRequestGlue.bind(this) } + }; + } + start(glue) { + if (Utils.isNode()) { + return; + } + this.glue = glue; + this.wireCustomEventListener(); + this.announceStarted(); + } + wireCustomEventListener() { + window.addEventListener(this.glue42EventName, (event) => { + const data = event.detail; + if (!data || !data.glue42) { + return; + } + const glue42Event = data.glue42.event; + const foundHandler = this.events[glue42Event]; + if (!foundHandler) { + return; + } + foundHandler.handle(data.glue42.message); + }); + } + announceStarted() { + this.send("start"); + } + handleRequestGlue() { + if (!this.config.exposeAPI) { + this.send("requestGlueResponse", { error: "Will not give access to the underlying Glue API, because it was explicitly denied upon initialization." }); + return; + } + this.send("requestGlueResponse", { glue: this.glue }); + } + handleNotifyStarted() { + this.announceStarted(); + } + send(eventName, message) { + const payload = { glue42: { event: eventName, message } }; + const event = new CustomEvent(this.glue42EventName, { detail: payload }); + window.dispatchEvent(event); + } + } + + class PromiseWrapper { + static delay(time) { + return new Promise((resolve) => setTimeout(resolve, time)); + } + static async delayForever() { + const biggestPossibleDelay = 2147483647; + while (true) { + await this.delay(biggestPossibleDelay); + } + } + get ended() { + return this.rejected || this.resolved; + } + constructor() { + this.promise = new Promise((resolve, reject) => { + this.resolve = (t) => { + this.resolved = true; + resolve(t); + }; + this.reject = (err) => { + this.rejected = true; + reject(err); + }; + }); + } + } + + class Interception { + constructor() { + this.InterceptorMethodName = "T42.GD.Interception.Execute"; + this.InterceptorHandlerMethodName = "T42.GD.Interception.Handler"; + this.interceptions = []; + } + init(interop) { + this.interop = interop; + } + async register(request) { + if (!request || typeof request !== "object" || Array.isArray(request)) { + throw new Error(`Please provide a valid object.`); + } + const handler = request.handler; + if (typeof handler !== "function") { + throw new Error("Please provide a valid handler function."); + } + const interceptions = request.interceptions; + this.validateInterceptions(interceptions); + this.interceptions.push(request); + try { + await this.interop.invoke(this.InterceptorMethodName, { + command: "register", + interceptions + }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + await this.registerMethodIfNotRegistered(); + } + catch (error) { + this.interceptions = this.interceptions.filter((i) => i !== request); + const message = error.message || "Unknown error"; + const newError = new Error(`Failed to register interception: ${message}`); + throw newError; + } + } + async unregister(request) { + if (!request || typeof request !== "object" || Array.isArray(request)) { + throw new Error(`Please provide a valid object.`); + } + const interceptions = request.interceptions; + this.validateInterceptions(interceptions); + try { + await this.interop.invoke(this.InterceptorMethodName, { + command: "unregister", + interceptions + }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + this.interceptions = this.interceptions.filter((config) => { + return !interceptions.some((interception) => { + return config.interceptions.some((i) => { + return i.domain === interception.domain && i.operation === interception.operation; + }); + }); + }); + } + catch (error) { + const message = error.message || "Unknown error"; + const newError = new Error(`Failed to unregister interception: ${message}`); + throw newError; + } + } + async handleInterception(domain, operation, operationArgs, phase) { + if (this.interop.methods(this.InterceptorMethodName).length === 0) { + return {}; + } + const result = await this.interop.invoke(this.InterceptorMethodName, { + command: "raiseInterception", + interceptions: [{ + operationArgs, + domain, + operation, + phase + }] + }, 'best', { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return result.returned; + } + static createProxyObject(apiToIntercept, domain, interception) { + const methods = Interception.OperationsPerDomain[domain] || []; + const handler = { + get(target, propertyKey, receiver) { + const property = Reflect.get(target, propertyKey, receiver); + try { + if (typeof property !== "function") { + return property; + } + const shouldIntercept = methods.includes(propertyKey); + const isAwaitable = Utils.isPromise(property) || Utils.isAsyncFunction(property); + if (!shouldIntercept || !isAwaitable) { + return property; + } + return Interception.interceptMethod(property, propertyKey, target, domain, interception); + } + catch (error) { + return property; + } + } + }; + const proxyAPI = new Proxy(apiToIntercept, handler); + return proxyAPI; + } + static interceptMethod(originalMethod, propertyKey, target, domain, interception) { + return async function (...args) { + const beforeInterceptionResult = await interception.handleInterception(domain, propertyKey, args, "before"); + if (!Utils.isNullOrUndefined(beforeInterceptionResult.operationResult)) { + return beforeInterceptionResult.operationResult; + } + if (!Utils.isNullOrUndefined(beforeInterceptionResult.operationArgs)) { + args = beforeInterceptionResult.operationArgs; + } + const methodResult = await originalMethod.apply(target, args); + const afterInterceptionResult = await interception.handleInterception(domain, propertyKey, [methodResult], "after"); + if (!Utils.isNullOrUndefined(afterInterceptionResult.operationResult)) { + return afterInterceptionResult.operationResult; + } + return methodResult; + }; + } + toAPI() { + return { + register: this.register.bind(this), + unregister: this.unregister.bind(this), + }; + } + async registerMethodIfNotRegistered() { + var _a; + if ((_a = this.whenRegisteredPromise) === null || _a === void 0 ? void 0 : _a.ended) { + return; + } + this.whenRegisteredPromise = new PromiseWrapper(); + this.registerMethod(); + } + async registerMethod() { + await this.interop.register(this.InterceptorHandlerMethodName, async (data) => { + const command = data.command; + if (command === "raiseInterception") { + const raisedInterception = data.interception; + const interceptor = this.interceptions.find((config) => { + return config.interceptions.some((interception) => { + return interception.domain === raisedInterception.domain && interception.operation === raisedInterception.operation; + }); + }); + const result = await interceptor.handler(raisedInterception); + return result; + } + }); + this.whenRegisteredPromise.resolve(); + } + validateInterceptions(interceptions) { + if (!Array.isArray(interceptions)) { + throw new Error("Please provide a valid array of interceptions."); + } + if (interceptions.length === 0) { + throw new Error("Please provide at least one interception."); + } + for (const interception of interceptions) { + if (typeof interception === "undefined" || interception === null || typeof interception !== "object" || Array.isArray(interception)) { + throw new Error("Please provide a valid interception object."); + } + if (typeof interception.domain !== "string" || !interception.domain) { + throw new Error("Please provide a valid domain string."); + } + if (typeof interception.operation !== "string" || !interception.operation) { + throw new Error("Please provide a valid operation string."); + } + this.validateTypeString(interception); + } + } + validateTypeString(interception) { + if (!isUndefinedOrNull(interception.phase)) { + const isValidType = ["all", "before", "after"].includes(interception.phase); + if (typeof interception.phase !== "string" || !isValidType) { + throw new Error("Please provide a valid phase string."); + } + } + } + } + Interception.OperationsPerDomain = { + "intents": ["raise"] + }; + + const callInfo = new FactoryCallInfo(); + const factory = async (options) => { + let firstRun = false; + if (!callInfo.initialized) { + firstRun = true; + callInfo.init(options); + } + const glue42gd = typeof window !== "undefined" && window.glue42gd; + if (glue42gd) { + if (!firstRun) { + callInfo.addCall(options); + return callInfo.promise; + } + } + const g = await factoryCore(options, glue42gd); + callInfo.resolve(g); + return g; + }; + const factoryCore = async (options, glue42gd) => { + const T42GDExecuteMethod = "T42.GD.Execute"; + const gdMajorVersion = Utils.getGDMajorVersion(); + options = options || {}; + const glueConfig = prepareConfig(options); + options.gateway = options.gateway || {}; + let _appManager; + let _activity; + let _windows; + let _displays; + let _channels; + let _prefs; + const _interceptors = new Interception(); + const _browserEventsDispatcher = new EventsDispatcher(glueConfig); + function createWindows(core) { + if (glueConfig.windows) { + const windowsLogger = getLibLogger("windows", core.logger, glueConfig.windows); + _windows = WindowsFactory(core.agm, windowsLogger, () => { + return _appManager; + }, () => { + return _displays; + }, () => { + return _channels; + }, gdMajorVersion); + debugLog(_windows); + return _windows; + } + } + function createActivities(core) { + var _a; + if (glueConfig.activities) { + if (ActivityModule.checkIsUsingGW3Implementation && ActivityModule.checkIsUsingGW3Implementation(core.connection)) { + const activityLogger = getLibLogger("activity", core.logger, glueConfig.activities); + _activity = new ActivityModule({ + connection: core.connection, + contexts: core.contexts, + agm: core.agm, + logger: activityLogger, + logLevel: "info", + disableAutoAnnounce: false, + disposeRequestHandling: "exit", + announcementInfo: null, + windows: _windows, + appManagerGetter: () => { + return _appManager; + }, + mode: glueConfig.activities.mode, + typesToTrack: glueConfig.activities.typesToTrack, + activityId: (_a = glue42gd === null || glue42gd === void 0 ? void 0 : glue42gd.activityInfo) === null || _a === void 0 ? void 0 : _a.activityId, + gdMajorVersion + }).api; + debugLog(_activity); + return _activity; + } + } + } + function createAppManager(core) { + if (!glueConfig.appManager) { + return; + } + const logger = getLibLogger("appManager", core.logger, glueConfig.appManager); + _appManager = AppManagerFactory({ + agm: core.agm, + windows: _windows, + logger, + activities: _activity, + mode: glueConfig.appManager.mode, + gdMajorVersion + }); + debugLog(_appManager); + return _appManager; + } + function createLayouts(core) { + var _a; + if (!glueConfig.layouts) { + return; + } + const logger = getLibLogger("layouts", core.logger, glueConfig.layouts); + const layoutsConfig = glueConfig.layouts; + const lay = LayoutsFactory({ + agm: core.agm, + appManager: _appManager, + activityGetter: () => _activity, + logger, + mode: layoutsConfig.mode, + autoSaveWindowContext: (_a = layoutsConfig.autoSaveWindowContext) !== null && _a !== void 0 ? _a : false, + gdMajorVersion + }); + debugLog(lay); + return lay; + } + function createChannels(core) { + if (!glueConfig.channels) { + return; + } + const logger = getLibLogger("channels", core.logger, glueConfig.channels); + if (!core.contexts) { + logger.error("Channels library requires Contexts library to be initialized."); + return; + } + _channels = factory$4({ operationMode: glueConfig.channels.operationMode }, core.contexts, core.agm, () => _windows, () => _appManager, logger); + debugLog(_channels); + return _channels; + } + function createHotkeys(core) { + const hotkeysAPI = factory$3(core.agm); + debugLog(hotkeysAPI); + return hotkeysAPI; + } + function createIntents(core) { + const domain = "intents"; + const intents = new Intents(core.agm, _windows, core.logger.subLogger(domain), options, _prefs, _appManager); + const intentsAPI = intents.toAPI(); + const proxyIntentsAPI = Interception.createProxyObject(intentsAPI, domain, _interceptors); + debugLog(proxyIntentsAPI); + return proxyIntentsAPI; + } + function createNotifications(core) { + const notificationsAPI = new Notifications(core.interop, core.logger).toAPI(); + debugLog(notificationsAPI); + return notificationsAPI; + } + function createDisplaysApi(core) { + if (glueConfig.displays) { + const displaysLogger = getLibLogger("displays", core.logger, glueConfig.displays); + _displays = new DisplayManager(core.agm, displaysLogger); + debugLog(_displays); + return _displays; + } + } + function createThemes(core) { + if (!core.contexts) { + return; + } + const themesAPI = factory$2(core.contexts, core.interop); + debugLog(themesAPI); + return themesAPI; + } + function createPrefs(core) { + var _a, _b; + const appName = (_b = (_a = options.application) !== null && _a !== void 0 ? _a : glue42gd === null || glue42gd === void 0 ? void 0 : glue42gd.applicationName) !== null && _b !== void 0 ? _b : core.interop.instance.application; + _prefs = new Prefs(appName, core.interop); + debugLog(_prefs); + return _prefs; + } + function createCookies(core) { + const api = factory$1(core.interop, T42GDExecuteMethod); + debugLog(api); + return api; + } + function createInterception(core) { + _interceptors.init(core.interop); + debugLog(_interceptors); + return _interceptors.toAPI(); + } + function getLibLogger(loggerName, logger, config) { + const newLogger = logger.subLogger(loggerName); + if (config && config.logger) { + const loggerConfig = config.logger; + if (loggerConfig.console) { + newLogger.consoleLevel(loggerConfig.console); + } + if (loggerConfig.publish) { + newLogger.publishLevel(loggerConfig.publish); + } + } + return newLogger; + } + const ext = { + libs: [ + { name: "windows", create: createWindows }, + { name: "activities", create: createActivities }, + { name: "appManager", create: createAppManager }, + { name: "layouts", create: createLayouts }, + { name: "channels", create: createChannels }, + { name: "hotkeys", create: createHotkeys }, + { name: "displays", create: createDisplaysApi }, + { name: "prefs", create: createPrefs }, + { name: "intents", create: createIntents }, + { name: "notifications", create: createNotifications }, + { name: "themes", create: createThemes }, + { name: "cookies", create: createCookies }, + { name: "interception", create: createInterception } + ], + version, + enrichGlue: (glue) => { + glue.config.activities = glueConfig.activities; + glue.config.windows = glueConfig.windows; + glue.config.appManager = glueConfig.appManager; + glue.config.layouts = glueConfig.layouts; + glue.config.channels = glueConfig.channels; + glue.config.displays = glueConfig.displays; + }, + }; + const currentLog = []; + if (typeof window !== "undefined") { + if (!window.glueFactoryLog) { + window.glueFactoryLog = []; + } + window.glueFactoryLog.push(currentLog); + } + function debugLog(entry) { + currentLog.push(entry); + } + const glueApi = (await IOConnectCoreFactory(options, ext)); + if (Array.isArray(options === null || options === void 0 ? void 0 : options.libraries) && options.libraries.length) { + await Promise.all(options.libraries.map((lib) => lib(glueApi, options))); + } + _browserEventsDispatcher.start(glueApi); + return glueApi; + }; + factory.coreVersion = IOConnectCoreFactory.version; + factory.version = version; + factory.calls = callInfo; + + var _a, _b; + let whatToExpose = factory; + let shouldSetToWindow = true; + if (typeof window !== "undefined") { + const windowAsAny = window; + const iodesktop = (_a = windowAsAny.iodesktop) !== null && _a !== void 0 ? _a : windowAsAny.glue42gd; + if (iodesktop && iodesktop.autoInjected) { + whatToExpose = (_b = windowAsAny.IODesktop) !== null && _b !== void 0 ? _b : windowAsAny.Glue; + shouldSetToWindow = false; + } + if (shouldSetToWindow) { + windowAsAny.Glue = whatToExpose; + windowAsAny.IODesktop = whatToExpose; + } + delete windowAsAny.IOBrowser; + delete windowAsAny.GlueCore; + } + whatToExpose.default = whatToExpose; + var whatToExpose$1 = whatToExpose; + + return whatToExpose$1; + +})); +//# sourceMappingURL=desktop.umd.js.map diff --git a/typescript/start/client-details/src/lib/io.applications.css b/typescript/start/client-details/src/lib/io.applications.css new file mode 100644 index 0000000..98e5910 --- /dev/null +++ b/typescript/start/client-details/src/lib/io.applications.css @@ -0,0 +1,12 @@ +:root{--bs-blue: #007be5;--bs-indigo: #6610f2;--bs-purple: #6f42c1;--bs-pink: #fd397a;--bs-red: #ff511f;--bs-orange: #fd7e14;--bs-yellow: #f9a825;--bs-green: #43a047;--bs-teal: #616161;--bs-cyan: #469eb9;--bs-white: #fff;--bs-gray: #6c757d;--bs-gray-dark: #343a40;--bs-gray-100: #f8f9fa;--bs-gray-200: #e9ecef;--bs-gray-300: #dee2e6;--bs-gray-400: #ced4da;--bs-gray-500: #adb5bd;--bs-gray-600: #6c757d;--bs-gray-700: #495057;--bs-gray-800: #343a40;--bs-gray-900: #212529;--bs-primary: #007be5;--bs-secondary: #616161;--bs-success: #43a047;--bs-info: #469eb9;--bs-warning: #f9a825;--bs-danger: #ff511f;--bs-light: #616161;--bs-dark: #616161;--bs-primary-rgb: 0,123,229;--bs-secondary-rgb: 97,97,97;--bs-success-rgb: 67,160,71;--bs-info-rgb: 70,158,185;--bs-warning-rgb: 249,168,37;--bs-danger-rgb: 255,81,31;--bs-light-rgb: 97,97,97;--bs-dark-rgb: 97,97,97;--bs-white-rgb: 255,255,255;--bs-black-rgb: 0,0,0;--bs-body-color-rgb: 33,37,41;--bs-body-bg-rgb: 255,255,255;--bs-font-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--bs-gradient: linear-gradient(180deg, rgba(255,255,255,0.15), rgba(255,255,255,0));--bs-body-font-family: Montserrat,Helvetica Neue,Arial,sans-serif;--bs-body-font-size: .75rem;--bs-body-font-weight: 400;--bs-body-line-height: 1.5;--bs-body-color: #212529;--bs-body-bg: #fff}:root{--t42-font-family: "Montserrat", "Helvetica Neue", Arial, sans-serif;--t42-font-size: 0.75rem;--bs-gutter-x: 0.938rem;--primary: #007be5;--secondary: #616161;--success: #43a047;--info: #616161;--warning: #f9a825;--danger: #ff511f;--light: #616161;--dark: #616161;--white: #ffffff}.dark{--t42-bg-light-base: 0, 0%;--t42-bg-light-l: 18%;--t42-bg-light: 45, 45, 45;--t42-bg-mid: 37, 37, 37;--t42-bg-dark: 30, 30, 30;--t42-content-color-base: 0, 0%;--t42-content-color: #bababa;--t42-content-color-l: 73%;--t42-content-color-muted: hsl(var(--t42-content-color-base), 63%);--t42-content-color-disabled: hsl(var(--t42-content-color-base), 43%);--t42-color-opacity-025: hsla(var(--t42-content-color-base), 100%, 0.025);--t42-color-opacity-05: hsla(var(--t42-content-color-base), 100%, 0.05);--t42-color-opacity-10: hsla(var(--t42-content-color-base), 100%, 0.1);--t42-color-opacity-20: hsla(var(--t42-content-color-base), 100%, 0.2);--t42-color-opacity-30: hsla(var(--t42-content-color-base), 100%, 0.3);--t42-link-color: hsl(var(--t42-content-color-base), 100%);--t42-shadow: 0 0 12px 0 hsla(var(--t42-content-color-base), 0%, 0.15);--t42-border: 0.0625rem solid var(--t42-color-opacity-10);--t42-logo-icon: url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 xmlns:xlink=%27http://www.w3.org/1999/xlink%27 x=%270px%27 y=%270px%27 viewBox=%270 0 100.2 121%27 style=%27enable-background:new 0 0 100.2 121;%27%3E%3Cpath fill=%27%233A77BC%27 d=%27M59.4,10.6l-8.3,8.3c-0.5,0.5-1.4,0.5-1.9,0l-8.3-8.3c-0.5-0.5-0.5-1.4,0-1.9l8.3-8.3c0.5-0.5,1.4-0.5,1.9,0 l8.3,8.3C59.9,9.2,59.9,10.1,59.4,10.6z M59.3,110.4l-8.3-8.3c-0.5-0.5-1.4-0.5-1.9,0l-8.3,8.3c-0.5,0.5-0.5,1.4,0,1.9l8.3,8.3 c0.5,0.5,1.4,0.5,1.9,0l8.3-8.3C59.9,111.8,59.9,110.9,59.3,110.4z%27/%3E%3Cpath fill=%27%23FFFFFF%27 d=%27M100.1,60.1c0.3,7.3-2.9,14.3-9.3,20.6l-24.7,24.7c-0.6,0.6-1.5,0.6-2.1,0l-8.1-8.1c-0.6-0.6-0.6-1.5,0-2.1 l24.7-24.7c0.1-0.1,0.2-0.2,0.3-0.3c3.2-3.3,4.7-6.7,4.4-10.2c0-0.4-0.1-0.8-0.2-1.3c-0.6-3.3-2.8-7-6.8-11l-9.9-9.9 c-0.3-0.3-0.7-0.5-1.1-0.5c-0.4,0-0.8,0.2-1.3,0.6L34.5,69.6c-0.6,0.6-1.5,0.6-2.1,0L27.7,65c-3.3-3.3-3.8-5.1-1.3-7.6 c11.1-11.2,22-22.1,33.2-33.2c2.7-2.7,5.1-4.2,7.5-4.3c2.5-0.1,4.7,1.2,6.9,3.5l14.3,14.3C95.9,45.3,99.8,52.8,100.1,60.1 L100.1,60.1z M0,60.9c0.3,7.3,3.7,14.3,11.2,21.9l14.8,14.8c2.3,2.3,4.5,3.6,6.9,3.5c2.4-0.1,4.8-1.6,7.5-4.3 c11.1-11.1,22.1-22,33.2-33.2c2.5-2.5,2-4.3-1.3-7.6l-4.7-4.7c-0.6-0.6-1.5-0.6-2.1,0L34,83c-0.5,0.5-0.9,0.6-1.3,0.6 c-0.4,0-0.7-0.1-1.1-0.5L21.3,72.7c-4-4-5.7-7.2-6.3-10.5c-0.1-0.4-0.1-0.8-0.2-1.3c-0.3-3.5,1.2-6.9,4.4-10.2 c0.1-0.1,0.2-0.2,0.3-0.3l24.7-24.7c0.6-0.6,0.6-1.5,0-2.1l-8.1-8.1c-0.6-0.6-1.5-0.6-2.1,0L9.3,40.3C2.9,46.6-0.3,53.5,0,60.9 L0,60.9z%27/%3E%3C/svg%3E%0A");--t42-icon-color: var(--t42-link-color);--t42-list-group-hover-bg-special: hsla(var(--t42-content-color-base), 100%, 0.065);--backdrop-filter: blur(5px) saturate(200%);--accordion-filter: invert(1) brightness(1);--filter-close: invert(1);--t42-body: rgb(var(--t42-bg-dark));--pink: rgb(0 170 200);--t42-link-hover-color: hsl(var(--t42-bg-light-base), 100%);--t42-link-hover-bg: var(--t42-color-opacity-05);--t42-link-active-bg: var(--t42-color-opacity-10);--t42-input-bg: rgb(var(--t42-bg-dark));--t42-input-disabled-bg: Hsla(var(--t42-content-color-base), 100%, 0.075);--t42-tooltip-bg: rgba(var(--t42-bg-dark), 0.85);--t42-modal-bg: rgba(var(--t42-bg-light), 0.75);--t42-table-active-bg: rgba(255, 255, 255, 0.1);--t42-select-indicator: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9IiNFRUVFRUUiIHZpZXdCb3g9IjAgMCAxNiAxNiI+PHBhdGggZD0iTTIuNSA1LjVjLjQtLjQgMS0uNSAxLjYgMGwzLjkgMy43bDMuOS0zLjdjLjUtLjUgMS4xLS40IDEuNiAwYy40LjQuNCAxLjIgMCAxLjZjLS40LjQtNC43IDQuNS00LjcgNC41Yy0uMi4yLS41LjMtLjguM3MtLjYtLjEtLjgtLjNjMCAwLTQuMy00LjEtNC43LTQuNXMtLjQtMS4yIDAtMS42eiI+PC9wYXRoPjwvc3ZnPg==)}.light{--t42-bg-light-base: 0, 0%;--t42-bg-light-l: 100%;--t42-bg-light: 255, 255, 255;--t42-bg-mid: 250, 250, 250;--t42-bg-dark: 245, 245, 245;--t42-content-color-base: 0, 0%;--t42-content-color: #757575;--t42-content-color-l: 46%;--t42-content-color-muted: hsl(var(--t42-content-color-base), 66%);--t42-color-opacity-025: hsla(var(--t42-content-color-base), 0%, 0.025);--t42-color-opacity-05: hsla(var(--t42-content-color-base), 0%, 0.05);--t42-color-opacity-10: hsla(var(--t42-content-color-base), 0%, 0.075);--t42-color-opacity-30: hsla(var(--t42-content-color-base), 0%, 0.1);--t42-color-opacity-20: hsla(var(--t42-content-color-base), 0%, 0.2);--t42-link-color: hsl(var(--t42-content-color-base), 5%);--t42-shadow: 0 0 12px 0 hsla(var(--t42-content-color-base), 0%, 0.05);--t42-border: 0.0625rem solid var(--t42-color-opacity-10);--t42-logo-icon: url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 xmlns:xlink=%27http://www.w3.org/1999/xlink%27 x=%270px%27 y=%270px%27 viewBox=%270 0 100.2 121%27 style=%27enable-background:new 0 0 100.2 121;%27%3E%3Cpath fill=%27%233A77BC%27 d=%27M59.4,10.6l-8.3,8.3c-0.5,0.5-1.4,0.5-1.9,0l-8.3-8.3c-0.5-0.5-0.5-1.4,0-1.9l8.3-8.3c0.5-0.5,1.4-0.5,1.9,0 l8.3,8.3C59.9,9.2,59.9,10.1,59.4,10.6z M59.3,110.4l-8.3-8.3c-0.5-0.5-1.4-0.5-1.9,0l-8.3,8.3c-0.5,0.5-0.5,1.4,0,1.9l8.3,8.3 c0.5,0.5,1.4,0.5,1.9,0l8.3-8.3C59.9,111.8,59.9,110.9,59.3,110.4z%27/%3E%3Cpath fill=%27%23083044%27 d=%27M100.1,60.1c0.3,7.3-2.9,14.3-9.3,20.6l-24.7,24.7c-0.6,0.6-1.5,0.6-2.1,0l-8.1-8.1c-0.6-0.6-0.6-1.5,0-2.1 l24.7-24.7c0.1-0.1,0.2-0.2,0.3-0.3c3.2-3.3,4.7-6.7,4.4-10.2c0-0.4-0.1-0.8-0.2-1.3c-0.6-3.3-2.8-7-6.8-11l-9.9-9.9 c-0.3-0.3-0.7-0.5-1.1-0.5c-0.4,0-0.8,0.2-1.3,0.6L34.5,69.6c-0.6,0.6-1.5,0.6-2.1,0L27.7,65c-3.3-3.3-3.8-5.1-1.3-7.6 c11.1-11.2,22-22.1,33.2-33.2c2.7-2.7,5.1-4.2,7.5-4.3c2.5-0.1,4.7,1.2,6.9,3.5l14.3,14.3C95.9,45.3,99.8,52.8,100.1,60.1 L100.1,60.1z M0,60.9c0.3,7.3,3.7,14.3,11.2,21.9l14.8,14.8c2.3,2.3,4.5,3.6,6.9,3.5c2.4-0.1,4.8-1.6,7.5-4.3 c11.1-11.1,22.1-22,33.2-33.2c2.5-2.5,2-4.3-1.3-7.6l-4.7-4.7c-0.6-0.6-1.5-0.6-2.1,0L34,83c-0.5,0.5-0.9,0.6-1.3,0.6 c-0.4,0-0.7-0.1-1.1-0.5L21.3,72.7c-4-4-5.7-7.2-6.3-10.5c-0.1-0.4-0.1-0.8-0.2-1.3c-0.3-3.5,1.2-6.9,4.4-10.2 c0.1-0.1,0.2-0.2,0.3-0.3l24.7-24.7c0.6-0.6,0.6-1.5,0-2.1l-8.1-8.1c-0.6-0.6-1.5-0.6-2.1,0L9.3,40.3C2.9,46.6-0.3,53.5,0,60.9 L0,60.9z%27/%3E%3C/svg%3E%0A");--t42-icon-color: Hsl(var(--t42-content-color-base), 38%);--t42-list-group-hover-bg-special: hsla(var(--t42-content-color-base), 95%, 0.065);--backdrop-filter: blur(5px) saturate(200%);--accordion-filter: brightness(0%);--filter-close: invert(0);--t42-body: rgb(var(--t42-bg-mid));--t42-link-hover-color: hsl(var(--t42-bg-light-base), 0%);--t42-link-hover-bg: hsl(var(--t42-content-color-base), 95%);--t42-link-active-bg: hsl(var(--t42-content-color-base), 90%);--t42-input-bg: rgb(var(--t42-bg-light));--t42-input-disabled-bg: var(--t42-color-opacity-10);--t42-tooltip-bg: rgba(var(--t42-bg-light), 0.95);--t42-modal-bg: rgba(var(--t42-bg-light), 0.95);--t42-table-active-bg: rgba(0, 0, 0, 0.025);--t42-select-indicator: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9IiM2MTYxNjEiIHZpZXdCb3g9IjAgMCAxNiAxNiI+PHBhdGggZD0iTTIuNSA1LjVjLjQtLjQgMS0uNSAxLjYgMGwzLjkgMy43bDMuOS0zLjdjLjUtLjUgMS4xLS40IDEuNiAwYy40LjQuNCAxLjIgMCAxLjZjLS40LjQtNC43IDQuNS00LjcgNC41Yy0uMi4yLS41LjMtLjguM3MtLjYtLjEtLjgtLjNjMCAwLTQuMy00LjEtNC43LTQuNXMtLjQtMS4yIDAtMS42eiI+PC9wYXRoPjwvc3ZnPg==)}*,*::before,*::after{box-sizing:border-box}@media (prefers-reduced-motion: no-preference){:root{scroll-behavior:smooth}}body{margin:0;font-family:var(--bs-body-font-family);font-size:var(--bs-body-font-size);font-weight:var(--bs-body-font-weight);line-height:var(--bs-body-line-height);color:var(--bs-body-color);text-align:var(--bs-body-text-align);background-color:var(--bs-body-bg);-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:rgba(0,0,0,0)}hr{margin:1rem 0;color:inherit;background-color:currentColor;border:0;opacity:.25}hr:not([size]){height:1px}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem;font-weight:500;line-height:1.2;color:var(--t42-link-color)}h1{font-size:calc(1.26563rem + .1875vw)}@media (min-width: 1200px){h1{font-size:1.40625rem}}h2{font-size:1.125rem}h3{font-size:.98475rem}h4{font-size:.84375rem}h5{font-size:.75rem}h6{font-size:.7035rem}p{margin-top:0;margin-bottom:1rem}abbr[title],abbr[data-bs-original-title]{text-decoration:underline dotted;cursor:help;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}ol,ul{padding-left:2rem}ol,ul,dl{margin-top:0;margin-bottom:1rem}ol ol,ul ul,ol ul,ul ol{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:.875em}mark{padding:0.2rem 0.2rem 0;background-color:#007be5}sub,sup{position:relative;font-size:.75em;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:var(--t42-link-color);text-decoration:underline}a:hover{color:var(--t42-link-hover-color)}a:not([href]):not([class]),a:not([href]):not([class]):hover{color:inherit;text-decoration:none}pre,code,kbd,samp{font-family:var(--bs-font-monospace);font-size:1em;direction:ltr /* rtl:ignore */;unicode-bidi:bidi-override}pre{display:block;margin-top:0;margin-bottom:1rem;overflow:auto;font-size:inherit;color:var(--t42-content-color)}pre code{font-size:inherit;color:inherit;word-break:normal}code{font-size:inherit;color:#469eb9;word-wrap:break-word}a>code{color:inherit}kbd{padding:.2rem .4rem;font-size:inherit;color:#fff;background-color:#212529;border-radius:.25rem}kbd kbd{padding:0;font-size:1em;font-weight:700}figure{margin:0 0 1rem}img,svg{vertical-align:middle}table{caption-side:bottom;border-collapse:collapse}caption{padding-top:.25rem;padding-bottom:.25rem;color:var(--t42-content-color-muted);text-align:left}th{text-align:inherit;text-align:-webkit-match-parent}thead,tbody,tfoot,tr,td,th{border-color:inherit;border-style:solid;border-width:0}label{display:inline-block}button{border-radius:0}button:focus:not(:focus-visible){outline:0}input,button,select,optgroup,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,select{text-transform:none}[role="button"]{cursor:pointer}select{word-wrap:normal}select:disabled{opacity:1}[list]::-webkit-calendar-picker-indicator{display:none}button,[type="button"],[type="reset"],[type="submit"]{-webkit-appearance:button}button:not(:disabled),[type="button"]:not(:disabled),[type="reset"]:not(:disabled),[type="submit"]:not(:disabled){cursor:pointer}::-moz-focus-inner{padding:0;border-style:none}textarea{resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{float:left;width:100%;padding:0;margin-bottom:.5rem;font-size:calc(1.275rem + .3vw);line-height:inherit}@media (min-width: 1200px){legend{font-size:1.5rem}}legend+*{clear:left}::-webkit-datetime-edit-fields-wrapper,::-webkit-datetime-edit-text,::-webkit-datetime-edit-minute,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-year-field{padding:0}::-webkit-inner-spin-button{height:auto}[type="search"]{outline-offset:-2px;-webkit-appearance:textfield}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-color-swatch-wrapper{padding:0}::file-selector-button{font:inherit}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}iframe{border:0}summary{display:list-item;cursor:pointer}progress{vertical-align:baseline}[hidden]{display:none !important}body{color:var(--t42-content-color);font-family:var(--t42-font-family);background-color:var(--t42-body)}a:focus,button:focus,div:focus,span:focus{outline:0}a{text-decoration:none}dt{font-weight:normal}::selection{color:var(--white);background-color:var(--primary)}::-webkit-scrollbar{width:4px;height:4px}::-webkit-scrollbar-track{border-radius:.25rem;background:transparent}::-webkit-scrollbar-thumb{border-radius:.25rem;background:var(--t42-color-opacity-10)}::-webkit-resizer{background:transparent}::-webkit-scrollbar-corner{background:transparent}::-webkit-scrollbar-thumb:window-inactive{background:transparent}::-webkit-scrollbar-thumb:hover,::-webkit-scrollbar-thumb:active{background:Hsla(var(--t42-content-color-base), 100%, 0.05)}.accordion-button{position:relative;display:flex;align-items:center;width:100%;padding:1rem 1.25rem;font-size:.75rem;color:var(--t42-link-color);text-align:left;background-color:Rgb(var(--t42-bg-mid));border:0;border-radius:0;overflow-anchor:none;transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out,border-radius 0.15s ease}@media (prefers-reduced-motion: reduce){.accordion-button{transition:none}}.accordion-button:not(.collapsed){color:var(--t42-link-color);background-color:Rgb(var(--t42-bg-mid));box-shadow:inset 0 -1px 0 var(--t42-color-opacity-10)}.accordion-button:not(.collapsed)::after{background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 16 16%27 fill=%27var%28--t42-link-color%29%27%3e%3cpath fill-rule=%27evenodd%27 d=%27M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z%27/%3e%3c/svg%3e");transform:rotate(-180deg)}.accordion-button::after{flex-shrink:0;width:1.25rem;height:1.25rem;margin-left:auto;content:"";background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 16 16%27 fill=%27var%28--t42-link-color%29%27%3e%3cpath fill-rule=%27evenodd%27 d=%27M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z%27/%3e%3c/svg%3e");background-repeat:no-repeat;background-size:1.25rem;transition:transform 0.2s ease-in-out}@media (prefers-reduced-motion: reduce){.accordion-button::after{transition:none}}.accordion-button:hover{z-index:2}.accordion-button:focus{z-index:3;border-color:#007be5;outline:0;box-shadow:0 0 0 0 rgba(0,123,229,0.25)}.accordion-header{margin-bottom:0}.accordion-item{background-color:Rgb(var(--t42-bg-mid));border:1px solid var(--t42-color-opacity-10)}.accordion-item:first-of-type{border-top-left-radius:0;border-top-right-radius:0}.accordion-item:first-of-type .accordion-button{border-top-left-radius:0;border-top-right-radius:0}.accordion-item:not(:first-of-type){border-top:0}.accordion-item:last-of-type{border-bottom-right-radius:0;border-bottom-left-radius:0}.accordion-item:last-of-type .accordion-button.collapsed{border-bottom-right-radius:0;border-bottom-left-radius:0}.accordion-item:last-of-type .accordion-collapse{border-bottom-right-radius:0;border-bottom-left-radius:0}.accordion-body{padding:1rem 1.25rem}.accordion-flush .accordion-collapse{border-width:0}.accordion-flush .accordion-item{border-right:0;border-left:0;border-radius:0}.accordion-flush .accordion-item:first-child{border-top:0}.accordion-flush .accordion-item:last-child{border-bottom:0}.accordion-flush .accordion-item .accordion-button{border-radius:0}.accordion-button::after,.accordion-button:not(.collapsed)::after{filter:var(--accordion-filter)}.accordion-button:disabled,.accordion-button.disabled{color:var(--t42-content-color-disabled)}.accordion-button:disabled::after,.accordion-button.disabled::after{opacity:0.25}.alert{position:relative;padding:.75rem .875rem;margin-bottom:.5rem;border:1px solid transparent;border-radius:0}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-right:2.625rem}.alert-dismissible .btn-close{position:absolute;top:0;right:0;z-index:2;padding:.9375rem .875rem}.alert-primary{color:#004a89;background-color:#cce5fa;border-color:#b3d7f7}.alert-primary .alert-link{color:#003b6e}.alert-secondary{color:#3a3a3a;background-color:#dfdfdf;border-color:#d0d0d0}.alert-secondary .alert-link{color:#2e2e2e}.alert-success{color:#28602b;background-color:#d9ecda;border-color:#c7e3c8}.alert-success .alert-link{color:#204d22}.alert-info{color:#2a5f6f;background-color:#daecf1;border-color:#c8e2ea}.alert-info .alert-link{color:#224c59}.alert-warning{color:#64430f;background-color:#feeed3;border-color:#fde5be}.alert-warning .alert-link{color:#50360c}.alert-danger{color:#993113;background-color:#ffdcd2;border-color:#ffcbbc}.alert-danger .alert-link{color:#7a270f}.alert-light{color:#3a3a3a;background-color:#dfdfdf;border-color:#d0d0d0}.alert-light .alert-link{color:#2e2e2e}.alert-dark{color:#3a3a3a;background-color:#dfdfdf;border-color:#d0d0d0}.alert-dark .alert-link{color:#2e2e2e}.alert{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border-color;position:relative;z-index:10000;display:flex;align-items:center;border:0.0625rem solid var(--t42-color-opacity-10);overflow:hidden;color:var(--t42-content-color);background-color:Rgba(var(--t42-bg-light), 0.75);background-repeat:no-repeat;background-size:100%;backdrop-filter:var(--backdrop-filter)}.alert h5{margin-bottom:0;color:var(--t42-content-color)}.alert p{margin-bottom:0}.alert-link{color:var(--t42-link-color);font-weight:normal}.alert-dismissible .close{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border-color;position:absolute;top:50%;right:0.75rem;width:1.5rem;height:1.5rem;padding:0;border:0;border-radius:50%;color:var(--t42-content-color);font-weight:700;font-size:1rem;line-height:1;background-color:var(--t42-color-opacity-05);transform:translateY(-50%);opacity:0.5}.alert-dismissible .close::before{position:relative;top:-1px}.alert-dismissible .close:hover{opacity:1}.alert::before{z-index:1;width:1.25rem;height:1.25rem;margin-right:0.875rem;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-position:center;mask-position:center;background-color:var(--t42-icon-color);content:""}.alert::after{position:absolute;top:0;left:0;z-index:-1;width:1px;height:1px;border-radius:50%;opacity:1;animation:color-pulse 3s infinite;content:""}.alert-primary:hover,.alert-secondary:hover,.alert-info:hover,.alert-light:hover,.alert-dark:hover{border-color:#616161}.alert-primary::after,.alert-secondary::after,.alert-info::after,.alert-light::after,.alert-dark::after{background:#616161;background:radial-gradient(circle, rgba(255,255,255,0.35) 0%, rgba(97,97,97,0.75) 60%, #616161 75%, #616161 100%)}.alert-primary::before,.alert-secondary::before,.alert-info::before,.alert-light::before,.alert-dark::before{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M260.6 484.4q0-4.1-4.6-4.1q-16.9 0-29.2-12.3t-11.8-29.2q0-4.6-4.6-4.6t-4.6 4.6q0 21 14.8 35.8t35.3 14.3q4.6 0 4.6-4.6zM493.6 402.4q0 14.8-10.8 25.6t-25.6 10.8h-128q0 30.2-21.5 51.7t-51.7 21.5t-51.7-21.5t-21.5-51.7h-128q-14.8 0-25.6-10.8t-10.8-25.6q14.3-12.3 26.1-25.1t24.1-34.3t21.5-45.6t13.8-58.9t5.6-74.2q0-43 33.8-80.4t87.6-45.6q-2.6-5.1-2.6-10.8q0-11.8 8.2-19.5t19.5-8.2t19.5 8.2t8.2 19.5q0 5.6-2.6 10.8q54.3 8.2 87.6 45.6t33.8 80.4q0 39.9 5.6 74.2t14.3 58.9t21 45.6t24.6 34.3t25.6 25.1z%27%3E%3C/path%3E%3C/svg%3E")}.alert-success:hover{border-color:#43a047}.alert-success::after{background:#43a047;background:radial-gradient(circle, rgba(255,255,255,0.35) 0%, rgba(67,160,71,0.75) 60%, #43a047 75%, #43a047 100%)}.alert-success::before{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M477.4 152.8q0 11.3-8.2 19.5l-245.8 245.8q-8.2 7.7-19.5 7.7t-19.5-7.7l-142.3-142.3q-7.7-8.2-7.7-19.5t7.7-19.5l38.9-38.9q8.2-8.2 19.5-8.2t19.5 8.2l84 84.5l187.4-187.9q8.2-8.2 19.5-8.2t19.5 8.2l38.9 38.9q8.2 7.7 8.2 19.5z%27%3E%3C/path%3E%3C/svg%3E")}.alert-warning:hover{border-color:#f9a825}.alert-warning::after{background:#f9a825;background:radial-gradient(circle, rgba(255,255,255,0.35) 0%, rgba(249,168,37,0.75) 60%, #f9a825 75%, #f9a825 100%)}.alert-warning::before{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M292.4 410.9v-54.3q0-4.1-2.6-6.7t-6.1-2.6h-55.3q-3.6 0-6.1 2.6t-2.6 6.7v54.3q0 4.1 2.6 6.7t6.1 3.1h55.3q3.6 0 6.1-3.1t2.6-6.7zM291.8 304.4l5.1-131.6q0-3.1-2.6-5.1q-3.6-3.1-7.2-3.1h-62.5q-3.1 0-7.2 3.1q-2.6 2-2.6 6.1l4.6 130.6q0 2.6 3.1 4.6t6.7 1.5h52.7q4.1 0 7.2-1.5t2.6-4.6zM288.3 37.1l219.1 402.4q10.2 17.9-.5 35.8q-4.6 8.7-13.3 13.3t-17.9 5.1h-439.3q-9.2 0-17.9-5.1t-13.3-13.3q-10.8-17.9-.5-35.8l219.6-402.4q4.6-8.7 13.3-13.8t18.4-5.1t18.4 5.1t13.8 13.8z%27%3E%3C/path%3E%3C/svg%3E%0A")}.alert-danger:hover{border-color:#ff511f}.alert-danger::after{background:#ff511f;background:radial-gradient(circle, rgba(255,255,255,0.35) 0%, rgba(255,81,31,0.75) 60%, #ff511f 75%, #ff511f 100%)}.alert-danger::before{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 402 512%27%3E%3Cpath d=%27M370.728 359.68q0 11.264-7.68 19.456l-38.912 38.912q-8.192 7.68-19.456 7.68t-19.456-7.68l-83.968-84.48-83.968 84.48q-8.192 7.68-19.456 7.68t-19.456-7.68l-38.912-38.912q-8.192-8.192-8.192-19.456t8.192-19.456l83.968-83.968-83.968-83.968q-8.192-8.192-8.192-19.456t8.192-19.456l38.912-38.912q8.192-8.192 19.456-8.192t19.456 8.192l83.968 83.968 83.968-83.968q8.192-8.192 19.456-8.192t19.456 8.192l38.912 38.912q7.68 7.68 7.68 19.456t-7.68 19.456l-83.968 83.968 83.968 83.968q7.68 7.68 7.68 19.456z%27%3E%3C/path%3E%3C/svg%3E")}@keyframes color-pulse{0%{transform:scale(1);opacity:1}50%{transform:scale(250);opacity:0}100%{opacity:0}}.badge{display:inline-block;padding:.2rem .5rem;font-size:.75em;font-weight:300;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:1rem}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.badge{border:var(--t42-border);color:var(--t42-link-color);backdrop-filter:var(--backdrop-filter)}.badge.bg-primary{border:0.0625rem solid #007be5;background-color:rgba(0,123,229,0.15) !important}.badge.bg-secondary{border:0.0625rem solid #616161;background-color:rgba(97,97,97,0.15) !important}.badge.bg-success{border:0.0625rem solid #43a047;background-color:rgba(67,160,71,0.15) !important}.badge.bg-info{border:0.0625rem solid #469eb9;background-color:rgba(70,158,185,0.15) !important}.badge.bg-warning{border:0.0625rem solid #f9a825;background-color:rgba(249,168,37,0.15) !important}.badge.bg-danger{border:0.0625rem solid #ff511f;background-color:rgba(255,81,31,0.15) !important}.badge.bg-light{border:0.0625rem solid #616161;background-color:rgba(97,97,97,0.15) !important}.badge.bg-dark{border:0.0625rem solid #616161;background-color:rgba(97,97,97,0.15) !important}button .badge{border:0.0625rem solid var(--t42-color-opacity-30)}button:hover .badge{color:var(--white)}.btn-close{box-sizing:content-box;width:1em;height:1em;padding:0 0;color:var(--t42-content-color);background:transparent url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 16 16%27 fill=%27var%28--t42-content-color%29%27%3e%3cpath d=%27M.293.293a1 1 0 011.414 0L8 6.586 14.293.293a1 1 0 111.414 1.414L9.414 8l6.293 6.293a1 1 0 01-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 01-1.414-1.414L6.586 8 .293 1.707a1 1 0 010-1.414z%27/%3e%3c/svg%3e") center/1em auto no-repeat;border:0;border-radius:.25rem;opacity:.5}.btn-close:hover{color:var(--t42-content-color);text-decoration:none;opacity:.75}.btn-close:focus{outline:0;box-shadow:0 0 0 0 rgba(0,123,229,0.25);opacity:1}.btn-close:disabled,.btn-close.disabled{pointer-events:none;user-select:none;opacity:.25}.btn-close-white{filter:invert(1) grayscale(100%) brightness(200%)}.btn{display:inline-block;font-weight:400;line-height:1.875rem;color:#212529;text-align:center;text-decoration:none;vertical-align:middle;cursor:pointer;user-select:none;background-color:transparent;border:1px solid transparent;padding:0 .875rem;font-size:.75rem;border-radius:0;transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.btn{transition:none}}.btn:hover{color:#212529}.btn-check:focus+.btn,.btn:focus{outline:0;box-shadow:0 0 0 0 rgba(0,123,229,0.25)}.btn:disabled,.btn.disabled,fieldset:disabled .btn{pointer-events:none;opacity:.35}.btn-primary{color:#000;background-color:#007be5;border-color:#007be5}.btn-primary:hover{color:#000;background-color:#268fe9;border-color:#1a88e8}.btn-check:focus+.btn-primary,.btn-primary:focus{color:#000;background-color:#268fe9;border-color:#1a88e8;box-shadow:0 0 0 0 rgba(0,105,195,0.5)}.btn-check:checked+.btn-primary,.btn-check:active+.btn-primary,.btn-primary:active,.btn-primary.active,.show>.btn-primary.dropdown-toggle{color:#000;background-color:#3395ea;border-color:#1a88e8}.btn-check:checked+.btn-primary:focus,.btn-check:active+.btn-primary:focus,.btn-primary:active:focus,.btn-primary.active:focus,.show>.btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(0,105,195,0.5)}.btn-primary:disabled,.btn-primary.disabled{color:#000;background-color:#007be5;border-color:#007be5}.btn-secondary{color:#fff;background-color:#616161;border-color:#616161}.btn-secondary:hover{color:#fff;background-color:#525252;border-color:#4e4e4e}.btn-check:focus+.btn-secondary,.btn-secondary:focus{color:#fff;background-color:#525252;border-color:#4e4e4e;box-shadow:0 0 0 0 rgba(121,121,121,0.5)}.btn-check:checked+.btn-secondary,.btn-check:active+.btn-secondary,.btn-secondary:active,.btn-secondary.active,.show>.btn-secondary.dropdown-toggle{color:#fff;background-color:#4e4e4e;border-color:#494949}.btn-check:checked+.btn-secondary:focus,.btn-check:active+.btn-secondary:focus,.btn-secondary:active:focus,.btn-secondary.active:focus,.show>.btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(121,121,121,0.5)}.btn-secondary:disabled,.btn-secondary.disabled{color:#fff;background-color:#616161;border-color:#616161}.btn-success{color:#000;background-color:#43a047;border-color:#43a047}.btn-success:hover{color:#000;background-color:#5fae63;border-color:#56aa59}.btn-check:focus+.btn-success,.btn-success:focus{color:#000;background-color:#5fae63;border-color:#56aa59;box-shadow:0 0 0 0 rgba(57,136,60,0.5)}.btn-check:checked+.btn-success,.btn-check:active+.btn-success,.btn-success:active,.btn-success.active,.show>.btn-success.dropdown-toggle{color:#000;background-color:#69b36c;border-color:#56aa59}.btn-check:checked+.btn-success:focus,.btn-check:active+.btn-success:focus,.btn-success:active:focus,.btn-success.active:focus,.show>.btn-success.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(57,136,60,0.5)}.btn-success:disabled,.btn-success.disabled{color:#000;background-color:#43a047;border-color:#43a047}.btn-info{color:#000;background-color:#469eb9;border-color:#469eb9}.btn-info:hover{color:#000;background-color:#62adc4;border-color:#59a8c0}.btn-check:focus+.btn-info,.btn-info:focus{color:#000;background-color:#62adc4;border-color:#59a8c0;box-shadow:0 0 0 0 rgba(60,134,157,0.5)}.btn-check:checked+.btn-info,.btn-check:active+.btn-info,.btn-info:active,.btn-info.active,.show>.btn-info.dropdown-toggle{color:#000;background-color:#6bb1c7;border-color:#59a8c0}.btn-check:checked+.btn-info:focus,.btn-check:active+.btn-info:focus,.btn-info:active:focus,.btn-info.active:focus,.show>.btn-info.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(60,134,157,0.5)}.btn-info:disabled,.btn-info.disabled{color:#000;background-color:#469eb9;border-color:#469eb9}.btn-warning{color:#000;background-color:#f9a825;border-color:#f9a825}.btn-warning:hover{color:#000;background-color:#fab546;border-color:#fab13b}.btn-check:focus+.btn-warning,.btn-warning:focus{color:#000;background-color:#fab546;border-color:#fab13b;box-shadow:0 0 0 0 rgba(212,143,31,0.5)}.btn-check:checked+.btn-warning,.btn-check:active+.btn-warning,.btn-warning:active,.btn-warning.active,.show>.btn-warning.dropdown-toggle{color:#000;background-color:#fab951;border-color:#fab13b}.btn-check:checked+.btn-warning:focus,.btn-check:active+.btn-warning:focus,.btn-warning:active:focus,.btn-warning.active:focus,.show>.btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(212,143,31,0.5)}.btn-warning:disabled,.btn-warning.disabled{color:#000;background-color:#f9a825;border-color:#f9a825}.btn-danger{color:#000;background-color:#ff511f;border-color:#ff511f}.btn-danger:hover{color:#000;background-color:#ff6b41;border-color:#ff6235}.btn-check:focus+.btn-danger,.btn-danger:focus{color:#000;background-color:#ff6b41;border-color:#ff6235;box-shadow:0 0 0 0 rgba(217,69,26,0.5)}.btn-check:checked+.btn-danger,.btn-check:active+.btn-danger,.btn-danger:active,.btn-danger.active,.show>.btn-danger.dropdown-toggle{color:#000;background-color:#ff744c;border-color:#ff6235}.btn-check:checked+.btn-danger:focus,.btn-check:active+.btn-danger:focus,.btn-danger:active:focus,.btn-danger.active:focus,.show>.btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(217,69,26,0.5)}.btn-danger:disabled,.btn-danger.disabled{color:#000;background-color:#ff511f;border-color:#ff511f}.btn-light{color:#fff;background-color:#616161;border-color:#616161}.btn-light:hover{color:#fff;background-color:#525252;border-color:#4e4e4e}.btn-check:focus+.btn-light,.btn-light:focus{color:#fff;background-color:#525252;border-color:#4e4e4e;box-shadow:0 0 0 0 rgba(121,121,121,0.5)}.btn-check:checked+.btn-light,.btn-check:active+.btn-light,.btn-light:active,.btn-light.active,.show>.btn-light.dropdown-toggle{color:#fff;background-color:#4e4e4e;border-color:#494949}.btn-check:checked+.btn-light:focus,.btn-check:active+.btn-light:focus,.btn-light:active:focus,.btn-light.active:focus,.show>.btn-light.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(121,121,121,0.5)}.btn-light:disabled,.btn-light.disabled{color:#fff;background-color:#616161;border-color:#616161}.btn-dark{color:#fff;background-color:#616161;border-color:#616161}.btn-dark:hover{color:#fff;background-color:#525252;border-color:#4e4e4e}.btn-check:focus+.btn-dark,.btn-dark:focus{color:#fff;background-color:#525252;border-color:#4e4e4e;box-shadow:0 0 0 0 rgba(121,121,121,0.5)}.btn-check:checked+.btn-dark,.btn-check:active+.btn-dark,.btn-dark:active,.btn-dark.active,.show>.btn-dark.dropdown-toggle{color:#fff;background-color:#4e4e4e;border-color:#494949}.btn-check:checked+.btn-dark:focus,.btn-check:active+.btn-dark:focus,.btn-dark:active:focus,.btn-dark.active:focus,.show>.btn-dark.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(121,121,121,0.5)}.btn-dark:disabled,.btn-dark.disabled{color:#fff;background-color:#616161;border-color:#616161}.btn-outline-primary{color:#007be5;border-color:#007be5}.btn-outline-primary:hover{color:#000;background-color:#007be5;border-color:#007be5}.btn-check:focus+.btn-outline-primary,.btn-outline-primary:focus{box-shadow:0 0 0 0 rgba(0,123,229,0.5)}.btn-check:checked+.btn-outline-primary,.btn-check:active+.btn-outline-primary,.btn-outline-primary:active,.btn-outline-primary.active,.btn-outline-primary.dropdown-toggle.show{color:#000;background-color:#007be5;border-color:#007be5}.btn-check:checked+.btn-outline-primary:focus,.btn-check:active+.btn-outline-primary:focus,.btn-outline-primary:active:focus,.btn-outline-primary.active:focus,.btn-outline-primary.dropdown-toggle.show:focus{box-shadow:0 0 0 0 rgba(0,123,229,0.5)}.btn-outline-primary:disabled,.btn-outline-primary.disabled{color:#007be5;background-color:transparent}.btn-outline-secondary{color:#616161;border-color:#616161}.btn-outline-secondary:hover{color:#fff;background-color:#616161;border-color:#616161}.btn-check:focus+.btn-outline-secondary,.btn-outline-secondary:focus{box-shadow:0 0 0 0 rgba(97,97,97,0.5)}.btn-check:checked+.btn-outline-secondary,.btn-check:active+.btn-outline-secondary,.btn-outline-secondary:active,.btn-outline-secondary.active,.btn-outline-secondary.dropdown-toggle.show{color:#fff;background-color:#616161;border-color:#616161}.btn-check:checked+.btn-outline-secondary:focus,.btn-check:active+.btn-outline-secondary:focus,.btn-outline-secondary:active:focus,.btn-outline-secondary.active:focus,.btn-outline-secondary.dropdown-toggle.show:focus{box-shadow:0 0 0 0 rgba(97,97,97,0.5)}.btn-outline-secondary:disabled,.btn-outline-secondary.disabled{color:#616161;background-color:transparent}.btn-outline-success{color:#43a047;border-color:#43a047}.btn-outline-success:hover{color:#000;background-color:#43a047;border-color:#43a047}.btn-check:focus+.btn-outline-success,.btn-outline-success:focus{box-shadow:0 0 0 0 rgba(67,160,71,0.5)}.btn-check:checked+.btn-outline-success,.btn-check:active+.btn-outline-success,.btn-outline-success:active,.btn-outline-success.active,.btn-outline-success.dropdown-toggle.show{color:#000;background-color:#43a047;border-color:#43a047}.btn-check:checked+.btn-outline-success:focus,.btn-check:active+.btn-outline-success:focus,.btn-outline-success:active:focus,.btn-outline-success.active:focus,.btn-outline-success.dropdown-toggle.show:focus{box-shadow:0 0 0 0 rgba(67,160,71,0.5)}.btn-outline-success:disabled,.btn-outline-success.disabled{color:#43a047;background-color:transparent}.btn-outline-info{color:#469eb9;border-color:#469eb9}.btn-outline-info:hover{color:#000;background-color:#469eb9;border-color:#469eb9}.btn-check:focus+.btn-outline-info,.btn-outline-info:focus{box-shadow:0 0 0 0 rgba(70,158,185,0.5)}.btn-check:checked+.btn-outline-info,.btn-check:active+.btn-outline-info,.btn-outline-info:active,.btn-outline-info.active,.btn-outline-info.dropdown-toggle.show{color:#000;background-color:#469eb9;border-color:#469eb9}.btn-check:checked+.btn-outline-info:focus,.btn-check:active+.btn-outline-info:focus,.btn-outline-info:active:focus,.btn-outline-info.active:focus,.btn-outline-info.dropdown-toggle.show:focus{box-shadow:0 0 0 0 rgba(70,158,185,0.5)}.btn-outline-info:disabled,.btn-outline-info.disabled{color:#469eb9;background-color:transparent}.btn-outline-warning{color:#f9a825;border-color:#f9a825}.btn-outline-warning:hover{color:#000;background-color:#f9a825;border-color:#f9a825}.btn-check:focus+.btn-outline-warning,.btn-outline-warning:focus{box-shadow:0 0 0 0 rgba(249,168,37,0.5)}.btn-check:checked+.btn-outline-warning,.btn-check:active+.btn-outline-warning,.btn-outline-warning:active,.btn-outline-warning.active,.btn-outline-warning.dropdown-toggle.show{color:#000;background-color:#f9a825;border-color:#f9a825}.btn-check:checked+.btn-outline-warning:focus,.btn-check:active+.btn-outline-warning:focus,.btn-outline-warning:active:focus,.btn-outline-warning.active:focus,.btn-outline-warning.dropdown-toggle.show:focus{box-shadow:0 0 0 0 rgba(249,168,37,0.5)}.btn-outline-warning:disabled,.btn-outline-warning.disabled{color:#f9a825;background-color:transparent}.btn-outline-danger{color:#ff511f;border-color:#ff511f}.btn-outline-danger:hover{color:#000;background-color:#ff511f;border-color:#ff511f}.btn-check:focus+.btn-outline-danger,.btn-outline-danger:focus{box-shadow:0 0 0 0 rgba(255,81,31,0.5)}.btn-check:checked+.btn-outline-danger,.btn-check:active+.btn-outline-danger,.btn-outline-danger:active,.btn-outline-danger.active,.btn-outline-danger.dropdown-toggle.show{color:#000;background-color:#ff511f;border-color:#ff511f}.btn-check:checked+.btn-outline-danger:focus,.btn-check:active+.btn-outline-danger:focus,.btn-outline-danger:active:focus,.btn-outline-danger.active:focus,.btn-outline-danger.dropdown-toggle.show:focus{box-shadow:0 0 0 0 rgba(255,81,31,0.5)}.btn-outline-danger:disabled,.btn-outline-danger.disabled{color:#ff511f;background-color:transparent}.btn-outline-light{color:#616161;border-color:#616161}.btn-outline-light:hover{color:#fff;background-color:#616161;border-color:#616161}.btn-check:focus+.btn-outline-light,.btn-outline-light:focus{box-shadow:0 0 0 0 rgba(97,97,97,0.5)}.btn-check:checked+.btn-outline-light,.btn-check:active+.btn-outline-light,.btn-outline-light:active,.btn-outline-light.active,.btn-outline-light.dropdown-toggle.show{color:#fff;background-color:#616161;border-color:#616161}.btn-check:checked+.btn-outline-light:focus,.btn-check:active+.btn-outline-light:focus,.btn-outline-light:active:focus,.btn-outline-light.active:focus,.btn-outline-light.dropdown-toggle.show:focus{box-shadow:0 0 0 0 rgba(97,97,97,0.5)}.btn-outline-light:disabled,.btn-outline-light.disabled{color:#616161;background-color:transparent}.btn-outline-dark{color:#616161;border-color:#616161}.btn-outline-dark:hover{color:#fff;background-color:#616161;border-color:#616161}.btn-check:focus+.btn-outline-dark,.btn-outline-dark:focus{box-shadow:0 0 0 0 rgba(97,97,97,0.5)}.btn-check:checked+.btn-outline-dark,.btn-check:active+.btn-outline-dark,.btn-outline-dark:active,.btn-outline-dark.active,.btn-outline-dark.dropdown-toggle.show{color:#fff;background-color:#616161;border-color:#616161}.btn-check:checked+.btn-outline-dark:focus,.btn-check:active+.btn-outline-dark:focus,.btn-outline-dark:active:focus,.btn-outline-dark.active:focus,.btn-outline-dark.dropdown-toggle.show:focus{box-shadow:0 0 0 0 rgba(97,97,97,0.5)}.btn-outline-dark:disabled,.btn-outline-dark.disabled{color:#616161;background-color:transparent}.btn-link{font-weight:400;color:var(--t42-link-color);text-decoration:underline}.btn-link:hover{color:var(--t42-link-hover-color)}.btn-link:disabled,.btn-link.disabled{color:#6c757d}.btn-lg,.btn-group-lg>.btn{padding:0 .875rem;font-size:.75rem;border-radius:0}.btn-sm,.btn-group-sm>.btn{padding:0 .875rem;font-size:.75rem;border-radius:0}.btn-group,.btn-group-vertical{position:relative;display:inline-flex;vertical-align:middle}.btn-group>.btn,.btn-group-vertical>.btn{position:relative;flex:1 1 auto}.btn-group>.btn-check:checked+.btn,.btn-group>.btn-check:focus+.btn,.btn-group>.btn:hover,.btn-group>.btn:focus,.btn-group>.btn:active,.btn-group>.btn.active,.btn-group-vertical>.btn-check:checked+.btn,.btn-group-vertical>.btn-check:focus+.btn,.btn-group-vertical>.btn:hover,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn.active{z-index:1}.btn-toolbar{display:flex;flex-wrap:wrap;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group>.btn:not(:first-child),.btn-group>.btn-group:not(:first-child){margin-left:-1px}.btn-group>.btn:not(:last-child):not(.dropdown-toggle),.btn-group>.btn-group:not(:last-child)>.btn{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:nth-child(n+3),.btn-group>:not(.btn-check)+.btn,.btn-group>.btn-group:not(:first-child)>.btn{border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.65625rem;padding-left:.65625rem}.dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after,.dropend .dropdown-toggle-split::after{margin-left:0}.dropstart .dropdown-toggle-split::before{margin-right:0}.btn-sm+.dropdown-toggle-split,.btn-group-sm>.btn+.dropdown-toggle-split{padding-right:.65625rem;padding-left:.65625rem}.btn-lg+.dropdown-toggle-split,.btn-group-lg>.btn+.dropdown-toggle-split{padding-right:.65625rem;padding-left:.65625rem}.btn-group-vertical{flex-direction:column;align-items:flex-start;justify-content:center}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn:not(:first-child),.btn-group-vertical>.btn-group:not(:first-child){margin-top:-1px}.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle),.btn-group-vertical>.btn-group:not(:last-child)>.btn{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn ~ .btn,.btn-group-vertical>.btn-group:not(:first-child)>.btn{border-top-left-radius:0;border-top-right-radius:0}button,button:focus{outline:none}.btn{color:var(--t42-link-color);transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, border-color;cursor:default}.btn.disabled,.btn:disabled{color:var(--t42-link-color);cursor:default}.btn:not(.disabled):not(:disabled).active,.btn:not(.disabled):not(:disabled):hover{border-color:var(--t42-color-opacity-30);color:var(--white);backdrop-filter:var(--backdrop-filter)}.btn:focus,.btn:active{color:var(--white)}.btn-primary{background-color:rgba(0,123,229,0.05)}.btn-primary.disabled,.btn-primary:disabled{background-color:rgba(0,123,229,0.05)}.btn-primary:not(.disabled):not(:disabled).active,.btn-primary:not(.disabled):not(:disabled):hover{background-color:#007be5}.btn-primary:not(.disabled):not(:disabled).btn-icon.active,.btn-primary:not(.disabled):not(:disabled).btn-icon:focus,.btn-primary:not(.disabled):not(:disabled).btn-icon:hover{color:var(--white)}.btn-primary.dropdown-toggle.active,.btn-primary.dropdown-toggle:active,.btn-primary.dropdown-toggle:focus{border-color:var(--t42-color-opacity-30);background-color:#007be5}.btn-secondary{background-color:rgba(97,97,97,0.05)}.btn-secondary.disabled,.btn-secondary:disabled{background-color:rgba(97,97,97,0.05)}.btn-secondary:not(.disabled):not(:disabled).active,.btn-secondary:not(.disabled):not(:disabled):hover{background-color:#616161}.btn-secondary:not(.disabled):not(:disabled).btn-icon.active,.btn-secondary:not(.disabled):not(:disabled).btn-icon:focus,.btn-secondary:not(.disabled):not(:disabled).btn-icon:hover{color:var(--white)}.btn-secondary.dropdown-toggle.active,.btn-secondary.dropdown-toggle:active,.btn-secondary.dropdown-toggle:focus{border-color:var(--t42-color-opacity-30);background-color:#616161}.btn-success{background-color:rgba(67,160,71,0.05)}.btn-success.disabled,.btn-success:disabled{background-color:rgba(67,160,71,0.05)}.btn-success:not(.disabled):not(:disabled).active,.btn-success:not(.disabled):not(:disabled):hover{background-color:#43a047}.btn-success:not(.disabled):not(:disabled).btn-icon.active,.btn-success:not(.disabled):not(:disabled).btn-icon:focus,.btn-success:not(.disabled):not(:disabled).btn-icon:hover{color:var(--white)}.btn-success.dropdown-toggle.active,.btn-success.dropdown-toggle:active,.btn-success.dropdown-toggle:focus{border-color:var(--t42-color-opacity-30);background-color:#43a047}.btn-info{background-color:rgba(70,158,185,0.05)}.btn-info.disabled,.btn-info:disabled{background-color:rgba(70,158,185,0.05)}.btn-info:not(.disabled):not(:disabled).active,.btn-info:not(.disabled):not(:disabled):hover{background-color:#469eb9}.btn-info:not(.disabled):not(:disabled).btn-icon.active,.btn-info:not(.disabled):not(:disabled).btn-icon:focus,.btn-info:not(.disabled):not(:disabled).btn-icon:hover{color:var(--white)}.btn-info.dropdown-toggle.active,.btn-info.dropdown-toggle:active,.btn-info.dropdown-toggle:focus{border-color:var(--t42-color-opacity-30);background-color:#469eb9}.btn-warning{background-color:rgba(249,168,37,0.05)}.btn-warning.disabled,.btn-warning:disabled{background-color:rgba(249,168,37,0.05)}.btn-warning:not(.disabled):not(:disabled).active,.btn-warning:not(.disabled):not(:disabled):hover{background-color:#f9a825}.btn-warning:not(.disabled):not(:disabled).btn-icon.active,.btn-warning:not(.disabled):not(:disabled).btn-icon:focus,.btn-warning:not(.disabled):not(:disabled).btn-icon:hover{color:var(--white)}.btn-warning.dropdown-toggle.active,.btn-warning.dropdown-toggle:active,.btn-warning.dropdown-toggle:focus{border-color:var(--t42-color-opacity-30);background-color:#f9a825}.btn-danger{background-color:rgba(255,81,31,0.05)}.btn-danger.disabled,.btn-danger:disabled{background-color:rgba(255,81,31,0.05)}.btn-danger:not(.disabled):not(:disabled).active,.btn-danger:not(.disabled):not(:disabled):hover{background-color:#ff511f}.btn-danger:not(.disabled):not(:disabled).btn-icon.active,.btn-danger:not(.disabled):not(:disabled).btn-icon:focus,.btn-danger:not(.disabled):not(:disabled).btn-icon:hover{color:var(--white)}.btn-danger.dropdown-toggle.active,.btn-danger.dropdown-toggle:active,.btn-danger.dropdown-toggle:focus{border-color:var(--t42-color-opacity-30);background-color:#ff511f}.btn-light{background-color:rgba(97,97,97,0.05)}.btn-light.disabled,.btn-light:disabled{background-color:rgba(97,97,97,0.05)}.btn-light:not(.disabled):not(:disabled).active,.btn-light:not(.disabled):not(:disabled):hover{background-color:#616161}.btn-light:not(.disabled):not(:disabled).btn-icon.active,.btn-light:not(.disabled):not(:disabled).btn-icon:focus,.btn-light:not(.disabled):not(:disabled).btn-icon:hover{color:var(--white)}.btn-light.dropdown-toggle.active,.btn-light.dropdown-toggle:active,.btn-light.dropdown-toggle:focus{border-color:var(--t42-color-opacity-30);background-color:#616161}.btn-dark{background-color:rgba(97,97,97,0.05)}.btn-dark.disabled,.btn-dark:disabled{background-color:rgba(97,97,97,0.05)}.btn-dark:not(.disabled):not(:disabled).active,.btn-dark:not(.disabled):not(:disabled):hover{background-color:#616161}.btn-dark:not(.disabled):not(:disabled).btn-icon.active,.btn-dark:not(.disabled):not(:disabled).btn-icon:focus,.btn-dark:not(.disabled):not(:disabled).btn-icon:hover{color:var(--white)}.btn-dark.dropdown-toggle.active,.btn-dark.dropdown-toggle:active,.btn-dark.dropdown-toggle:focus{border-color:var(--t42-color-opacity-30);background-color:#616161}.btn-link{text-decoration:none;backdrop-filter:none}.btn-link:not(.disabled):not(:disabled).active,.btn-link:not(.disabled):not(:disabled):focus,.btn-link:not(.disabled):not(:disabled):hover{border-color:transparent;color:var(--t42-link-color);text-decoration:underline}.btn-icon:not(.disabled):not(:disabled).active,.btn-icon:not(.disabled):not(:disabled):focus,.btn-icon:not(.disabled):not(:disabled):hover{color:var(--t42-link-color)}.btn-icon-action{display:flex;justify-content:center;width:1rem;height:1rem;padding:0;border-radius:50%;font-size:0.75rem;transition:all .2s ease-in-out}@media (prefers-reduced-motion: reduce){.btn-icon-action{transition:none}}.btn-icon-action:not(.disabled):not(:disabled).active,.btn-icon-action:not(.disabled):not(:disabled):hover,.btn-icon-action:not(.disabled):not(:disabled):focus{border-color:transparent;background-color:Rgb(var(--t42-bg-light));box-shadow:var(--t42-shadow)}.btn-icon-action-right{position:absolute;right:0.25rem}.btn-icon-action-show-hover{transition:all .2s ease-in-out}@media (prefers-reduced-motion: reduce){.btn-icon-action-show-hover{transition:none}}.btn-icon-action-show-hover .btn-icon-action{opacity:0}.btn-icon-action-show-hover:not(.disabled):not(:disabled):hover .btn-icon-action{opacity:1}.btn-close{width:1rem;height:1rem;filter:var(--filter-close)}.breadcrumb{display:flex;flex-wrap:wrap;padding:0 0;margin-bottom:.5rem;list-style:none;background-color:rgba(0,0,0,0)}.breadcrumb-item+.breadcrumb-item{padding-left:.5rem}.breadcrumb-item+.breadcrumb-item::before{float:left;padding-right:.5rem;color:#6c757d;content:var(--bs-breadcrumb-divider, "/") /* rtl: var(--bs-breadcrumb-divider, "/") */}.breadcrumb-item.active{color:var(--t42-link-color)}.breadcrumb-item{font-size:83.3%}.breadcrumb-item.active{text-decoration:underline}.breadcrumb-item+.breadcrumb-item{padding-left:0}.breadcrumb-item+.breadcrumb-item::before{position:relative;top:0.063rem;left:0.063rem;width:0.75rem;height:0.75rem;background-color:var(--t42-content-color);content:"";-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M339.2,256.3c0,2.4-0.9,4.4-2.6,6.1L203,396c-1.7,1.7-3.8,2.6-6.1,2.6c-2.4,0-4.6-0.9-6.7-2.6l-14.3-14.3 c-2-2-3.1-4.3-3.1-6.7s1-4.6,3.1-6.7L288,256.3L175.9,143.6c-2-1.7-3.1-3.8-3.1-6.1s1-4.6,3.1-6.7l14.3-14.3c1.7-2,3.9-3.1,6.7-3.1 s4.8,1,6.1,3.1l133.6,133.1C338.3,251.3,339.2,253.5,339.2,256.3L339.2,256.3z%27/%3E%3C/svg%3E")}mark,.mark{color:var(--white)}pre{background-color:var(--t42-bg-dark)}blockquote,.blockquote{padding:1rem 1rem 0.01rem;border-left:0.25rem solid var(--secondary);background-color:Rgb(var(--t42-bg-dark))}.blockquote-footer{margin-top:-2rem;margin-left:1.25rem;color:var(--t42-content-color-muted);font-size:0.875em}pre{border:0.0625rem solid var(--t42-color-opacity-10)}.card{position:relative;display:flex;flex-direction:column;min-width:0;word-wrap:break-word;background-color:Rgba(var(--t42-bg-light), 0.75);background-clip:border-box;border:1px solid var(--t42-color-opacity-10);border-radius:0}.card>hr{margin-right:0;margin-left:0}.card>.list-group{border-top:inherit;border-bottom:inherit}.card>.list-group:first-child{border-top-width:0;border-top-left-radius:0;border-top-right-radius:0}.card>.list-group:last-child{border-bottom-width:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.card>.card-header+.list-group,.card>.list-group+.card-footer{border-top:0}.card-body{flex:1 1 auto;padding:1.25rem 1.25rem}.card-title{margin-bottom:.5rem}.card-subtitle{margin-top:-.25rem;margin-bottom:0}.card-text:last-child{margin-bottom:0}.card-link+.card-link{margin-left:1.25rem}.card-header{padding:.625rem 1.25rem;margin-bottom:0;color:var(--t42-link-color);background-color:rgba(0,0,0,0);border-bottom:1px solid var(--t42-color-opacity-10)}.card-header:first-child{border-radius:0 0 0 0}.card-footer{padding:.625rem 1.25rem;color:var(--t42-link-color);background-color:rgba(0,0,0,0);border-top:1px solid var(--t42-color-opacity-10)}.card-footer:last-child{border-radius:0 0 0 0}.card-header-tabs{margin-right:-.625rem;margin-bottom:-.625rem;margin-left:-.625rem;border-bottom:0}.card-header-tabs .nav-link.active{background-color:Rgba(var(--t42-bg-light), 0.75);border-bottom-color:Rgba(var(--t42-bg-light), 0.75)}.card-header-pills{margin-right:-.625rem;margin-left:-.625rem}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1rem;border-radius:0}.card-img,.card-img-top,.card-img-bottom{width:100%}.card-img,.card-img-top{border-top-left-radius:0;border-top-right-radius:0}.card-img,.card-img-bottom{border-bottom-right-radius:0;border-bottom-left-radius:0}.card-group>.card{margin-bottom:.75rem}@media (min-width: 576px){.card-group{display:flex;flex-flow:row wrap}.card-group>.card{flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:not(:last-child) .card-img-top,.card-group>.card:not(:last-child) .card-header{border-top-right-radius:0}.card-group>.card:not(:last-child) .card-img-bottom,.card-group>.card:not(:last-child) .card-footer{border-bottom-right-radius:0}.card-group>.card:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:not(:first-child) .card-img-top,.card-group>.card:not(:first-child) .card-header{border-top-left-radius:0}.card-group>.card:not(:first-child) .card-img-bottom,.card-group>.card:not(:first-child) .card-footer{border-bottom-left-radius:0}}.card{box-shadow:var(--t42-shadow);backdrop-filter:var(--backdrop-filter)}.card .card-header{border-bottom-width:0}.card .card-subtitle{margin-bottom:0.5rem;font-size:83.3%}.card.bg-primary{background-color:transparent !important}.card.bg-primary .card-header{background-color:Rgba(var(--t42-bg-mid), 0.75)}.card.bg-primary .card-body{background-color:Rgba(var(--t42-bg-light), 0.75)}.card.bg-secondary{background-color:transparent !important}.card.bg-secondary .card-header{background-color:Rgba(var(--t42-bg-light), 0.75)}.card.bg-secondary .card-body{background-color:Rgba(var(--t42-bg-mid), 0.75)}.card:not(.bg-primary):not(.bg-secondary) .card-header+.card-body{padding-top:0}.card-header-tabs{margin-bottom:0}.accordion .card:first-of-type,.accordion .card:not(:first-of-type):not(:last-of-type){margin-bottom:0.5rem;border-bottom:var(--t42-border)}.accordion .card-header{position:relative;padding:0}.accordion .card-header .btn-link{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;width:100%;padding:0.75rem 2rem;line-height:1.4;text-align:left}.accordion .card-header .btn-link::before{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:transform;position:absolute;display:inline-block;width:0.75rem;height:0.75rem;background-color:var(--t42-content-color);transform:translateX(-1rem) translateY(0.063rem) rotate(-90deg);content:"";-webkit-mask-image:var(--t42-select-indicator)}.accordion .card-header .btn-link:hover{backdrop-filter:none}.accordion .card-header .btn-link.collapsed::before{transform:translateX(-1rem) translateY(0.063rem)}.accordion .card-header .btn-link.disabled::before,.accordion .card-header .btn-link:disabled::before{opacity:.35}.accordion .card-body{padding:0 1.25rem 1.25rem}.accordion .bg-primary .card-body,.accordion .bg-secondary .card-body{padding:1.25rem}.dropup,.dropend,.dropdown,.dropstart{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:0;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{position:absolute;z-index:1000;display:none;min-width:10rem;padding:0 0;margin:0;font-size:.75rem;color:var(--t42-content-color);text-align:left;list-style:none;background-color:Rgba(var(--t42-bg-light), 0.75);background-clip:padding-box;border:1px solid var(--t42-color-opacity-10);border-radius:0}.dropdown-menu[data-bs-popper]{top:100%;left:0;margin-top:.125rem}.dropdown-menu-start{--bs-position: start}.dropdown-menu-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-end{--bs-position: end}.dropdown-menu-end[data-bs-popper]{right:0;left:auto}@media (min-width: 576px){.dropdown-menu-sm-start{--bs-position: start}.dropdown-menu-sm-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-sm-end{--bs-position: end}.dropdown-menu-sm-end[data-bs-popper]{right:0;left:auto}}@media (min-width: 768px){.dropdown-menu-md-start{--bs-position: start}.dropdown-menu-md-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-md-end{--bs-position: end}.dropdown-menu-md-end[data-bs-popper]{right:0;left:auto}}@media (min-width: 992px){.dropdown-menu-lg-start{--bs-position: start}.dropdown-menu-lg-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-lg-end{--bs-position: end}.dropdown-menu-lg-end[data-bs-popper]{right:0;left:auto}}@media (min-width: 1200px){.dropdown-menu-xl-start{--bs-position: start}.dropdown-menu-xl-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-xl-end{--bs-position: end}.dropdown-menu-xl-end[data-bs-popper]{right:0;left:auto}}@media (min-width: 1400px){.dropdown-menu-xxl-start{--bs-position: start}.dropdown-menu-xxl-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-xxl-end{--bs-position: end}.dropdown-menu-xxl-end[data-bs-popper]{right:0;left:auto}}.dropup .dropdown-menu[data-bs-popper]{top:auto;bottom:100%;margin-top:0;margin-bottom:.125rem}.dropup .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:0;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropend .dropdown-menu[data-bs-popper]{top:0;right:auto;left:100%;margin-top:0;margin-left:.125rem}.dropend .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:0;content:"";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid}.dropend .dropdown-toggle:empty::after{margin-left:0}.dropend .dropdown-toggle::after{vertical-align:0}.dropstart .dropdown-menu[data-bs-popper]{top:0;right:100%;left:auto;margin-top:0;margin-right:.125rem}.dropstart .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:0;content:""}.dropstart .dropdown-toggle::after{display:none}.dropstart .dropdown-toggle::before{display:inline-block;margin-right:.255em;vertical-align:0;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropstart .dropdown-toggle:empty::after{margin-left:0}.dropstart .dropdown-toggle::before{vertical-align:0}.dropdown-divider{height:0;margin:0 0;overflow:hidden;border-top:1px solid var(--t42-color-opacity-10)}.dropdown-item{display:block;width:100%;padding:.375rem 1rem;clear:both;font-weight:400;color:var(--t42-content-color);text-align:inherit;text-decoration:none;white-space:nowrap;background-color:transparent;border:0}.dropdown-item:first-child{border-top-left-radius:0;border-top-right-radius:0}.dropdown-item:last-child{border-bottom-right-radius:0;border-bottom-left-radius:0}.dropdown-item:hover,.dropdown-item:focus{color:var(--t42-link-hover-color);background-color:var(--t42-link-hover-bg)}.dropdown-item.active,.dropdown-item:active{color:var(--t42-link-hover-color);text-decoration:none;background-color:var(--t42-link-active-bg)}.dropdown-item.disabled,.dropdown-item:disabled{color:#adb5bd;pointer-events:none;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:0 1rem;margin-bottom:0;font-size:.65625rem;color:shade-color(#616161, 10%);white-space:nowrap}.dropdown-item-text{display:block;padding:.375rem 1rem;color:var(--t42-content-color)}.dropdown-menu-dark{color:#dee2e6;background-color:#343a40;border-color:var(--t42-color-opacity-10)}.dropdown-menu-dark .dropdown-item{color:#dee2e6}.dropdown-menu-dark .dropdown-item:hover,.dropdown-menu-dark .dropdown-item:focus{color:#fff;background-color:rgba(255,255,255,0.15)}.dropdown-menu-dark .dropdown-item.active,.dropdown-menu-dark .dropdown-item:active{color:var(--t42-link-hover-color);background-color:var(--t42-link-active-bg)}.dropdown-menu-dark .dropdown-item.disabled,.dropdown-menu-dark .dropdown-item:disabled{color:#adb5bd}.dropdown-menu-dark .dropdown-divider{border-color:var(--t42-color-opacity-10)}.dropdown-menu-dark .dropdown-item-text{color:#dee2e6}.dropdown-menu-dark .dropdown-header{color:#adb5bd}.dropdown-menu{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:opacity, visability;display:block;visibility:hidden;opacity:0;backdrop-filter:var(--backdrop-filter)}.dropdown-menu.show{visibility:visible;opacity:1}.dropdown-toggle::after{position:relative;width:0.5rem;height:0.5rem;border:0;background-color:var(--t42-link-color);content:"";-webkit-mask-image:url("data:image/svg+xml,%3Csvg version=%271.1%27 xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M480.768 186.88l-211.968 211.456q-5.12 5.632-12.8 5.632t-12.8-5.632l-211.968-211.456q-5.632-5.632-5.632-13.312t5.632-12.8l47.616-47.104q5.12-5.632 12.8-5.632t12.8 5.632l151.552 151.552 151.552-151.552q5.632-5.632 12.8-5.632t13.312 5.632l47.104 47.104q5.632 5.632 5.632 12.8t-5.632 13.312z%27%3E%3C/path%3E%3C/svg%3E")}.dropdown-toggle.show::after{color:var(--white)}.dropup .dropdown-toggle::after{position:relative;top:0.188rem;width:0.5rem;height:0.5rem;border:0;background-color:var(--t42-link-color);content:"";-webkit-mask-image:url("data:image/svg+xml,%3Csvg version=%271.1%27 xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M480.768 351.488l-47.104 47.104q-5.632 5.12-13.312 5.12t-12.8-5.12l-151.552-152.064-151.552 152.064q-5.632 5.12-12.8 5.12t-12.8-5.12l-47.616-47.104q-5.632-5.632-5.632-13.312t5.632-12.8l211.968-211.968q5.632-5.12 12.8-5.12t12.8 5.12l211.968 211.968q5.632 5.632 5.632 12.8t-5.632 13.312z%27%3E%3C/path%3E%3C/svg%3E%0A")}.form-label{margin-bottom:.5rem}.col-form-label{padding-top:1px;padding-bottom:1px;margin-bottom:0;font-size:inherit;line-height:1.875rem}.col-form-label-lg{padding-top:1px;padding-bottom:1px;font-size:.75rem}.col-form-label-sm{padding-top:1px;padding-bottom:1px;font-size:.75rem}.form-text{margin-top:.25rem;font-size:.875em;color:var(--t42-content-color-muted)}.form-control{display:block;width:100%;padding:0 .875rem;font-size:.75rem;font-weight:400;line-height:1.875rem;color:var(--t42-link-color);background-color:var(--t42-input-bg);background-clip:padding-box;border:1px solid var(--t42-color-opacity-10);appearance:none;border-radius:0;transition:border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.form-control{transition:none}}.form-control[type="file"]{overflow:hidden}.form-control[type="file"]:not(:disabled):not([readonly]){cursor:pointer}.form-control:focus{color:var(--t42-link-color);background-color:var(--t42-input-bg);border-color:#007be5;outline:0;box-shadow:0 0 0 0 rgba(0,123,229,0.25)}.form-control::-webkit-date-and-time-value{height:1.875rem}.form-control::placeholder{color:var(--t42-content-color-muted);opacity:1}.form-control:disabled,.form-control[readonly]{background-color:var(--t42-input-disabled-bg);opacity:1}.form-control::file-selector-button{padding:0 .875rem;margin:0 -.875rem;margin-inline-end:.875rem;color:var(--t42-link-color);background-color:#e9ecef;pointer-events:none;border-color:inherit;border-style:solid;border-width:0;border-inline-end-width:1px;border-radius:0;transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.form-control::file-selector-button{transition:none}}.form-control:hover:not(:disabled):not([readonly])::file-selector-button{background-color:#dde0e3}.form-control::-webkit-file-upload-button{padding:0 .875rem;margin:0 -.875rem;margin-inline-end:.875rem;color:var(--t42-link-color);background-color:#e9ecef;pointer-events:none;border-color:inherit;border-style:solid;border-width:0;border-inline-end-width:1px;border-radius:0;transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.form-control::-webkit-file-upload-button{transition:none}}.form-control:hover:not(:disabled):not([readonly])::-webkit-file-upload-button{background-color:#dde0e3}.form-control-plaintext{display:block;width:100%;padding:0 0;margin-bottom:0;line-height:1.875rem;color:var(--t42-content-color);background-color:transparent;border:solid transparent;border-width:1px 0}.form-control-plaintext.form-control-sm,.form-control-plaintext.form-control-lg{padding-right:0;padding-left:0}.form-control-sm{min-height:2rem;padding:0 .875rem;font-size:.75rem;border-radius:0}.form-control-sm::file-selector-button{padding:0 .875rem;margin:0 -.875rem;margin-inline-end:.875rem}.form-control-sm::-webkit-file-upload-button{padding:0 .875rem;margin:0 -.875rem;margin-inline-end:.875rem}.form-control-lg{min-height:2rem;padding:0 .875rem;font-size:.75rem;border-radius:0}.form-control-lg::file-selector-button{padding:0 .875rem;margin:0 -.875rem;margin-inline-end:.875rem}.form-control-lg::-webkit-file-upload-button{padding:0 .875rem;margin:0 -.875rem;margin-inline-end:.875rem}textarea.form-control{min-height:2rem}textarea.form-control-sm{min-height:2rem}textarea.form-control-lg{min-height:2rem}.form-control-color{width:3rem;height:auto;padding:0}.form-control-color:not(:disabled):not([readonly]){cursor:pointer}.form-control-color::-moz-color-swatch{height:1.875rem;border-radius:0}.form-control-color::-webkit-color-swatch{height:1.875rem;border-radius:0}.form-select{display:block;width:100%;padding:0 2.625rem 0 .875rem;-moz-padding-start:calc(.875rem - 3px);font-size:.75rem;font-weight:400;line-height:1.875rem;color:var(--t42-link-color);background-color:var(--t42-input-bg);background-image:var(--t42-select-indicator);background-repeat:no-repeat;background-position:right 0.5rem center;background-size:1rem;border:1px solid var(--t42-color-opacity-10);border-radius:0;transition:border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out;appearance:none}@media (prefers-reduced-motion: reduce){.form-select{transition:none}}.form-select:focus{border-color:#007be5;outline:0;box-shadow:0 0 0 0 rgba(0,123,229,0.25)}.form-select[multiple],.form-select[size]:not([size="1"]){padding-right:.875rem;background-image:none}.form-select:disabled{background-color:#e9ecef}.form-select:-moz-focusring{color:transparent;text-shadow:0 0 0 var(--t42-link-color)}.form-select-sm{padding-top:0;padding-bottom:0;padding-left:.875rem;font-size:.75rem;border-radius:0}.form-select-lg{padding-top:0;padding-bottom:0;padding-left:.875rem;font-size:.75rem;border-radius:0}.form-check{display:block;min-height:1.125rem;padding-left:1.25rem;margin-bottom:0}.form-check .form-check-input{float:left;margin-left:-1.25rem}.form-check-input{width:1em;height:1em;margin-top:.25em;vertical-align:top;background-color:var(--t42-input-bg);background-repeat:no-repeat;background-position:center;background-size:contain;border:1px solid rgba(0,0,0,0.25);appearance:none;color-adjust:exact}.form-check-input[type="checkbox"]{border-radius:.25em}.form-check-input[type="radio"]{border-radius:50%}.form-check-input:active{filter:brightness(90%)}.form-check-input:focus{border-color:#007be5;outline:0;box-shadow:0 0 0 0 rgba(0,123,229,0.25)}.form-check-input:checked{background-color:#007be5;border-color:#007be5}.form-check-input:checked[type="checkbox"]{background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 20 20%27%3e%3cpath fill=%27none%27 stroke=%27%23fff%27 stroke-linecap=%27round%27 stroke-linejoin=%27round%27 stroke-width=%273%27 d=%27M6 10l3 3l6-6%27/%3e%3c/svg%3e")}.form-check-input:checked[type="radio"]{background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%27-4 -4 8 8%27%3e%3ccircle r=%272%27 fill=%27%23fff%27/%3e%3c/svg%3e")}.form-check-input[type="checkbox"]:indeterminate{background-color:#007be5;border-color:#007be5;background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 20 20%27%3e%3cpath fill=%27none%27 stroke=%27%23fff%27 stroke-linecap=%27round%27 stroke-linejoin=%27round%27 stroke-width=%273%27 d=%27M6 10h8%27/%3e%3c/svg%3e")}.form-check-input:disabled{pointer-events:none;filter:none;opacity:.5}.form-check-input[disabled] ~ .form-check-label,.form-check-input:disabled ~ .form-check-label{opacity:.5}.form-switch{padding-left:2.5em}.form-switch .form-check-input{width:2em;margin-left:-2.5em;background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%27-4 -4 8 8%27%3e%3ccircle r=%273%27 fill=%27rgba%280,0,0,0.25%29%27/%3e%3c/svg%3e");background-position:left center;border-radius:2em;transition:background-position 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.form-switch .form-check-input{transition:none}}.form-switch .form-check-input:focus{background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%27-4 -4 8 8%27%3e%3ccircle r=%273%27 fill=%27%23007be5%27/%3e%3c/svg%3e")}.form-switch .form-check-input:checked{background-position:right center;background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%27-4 -4 8 8%27%3e%3ccircle r=%273%27 fill=%27%23fff%27/%3e%3c/svg%3e")}.form-check-inline{display:inline-block;margin-right:1rem}.btn-check{position:absolute;clip:rect(0, 0, 0, 0);pointer-events:none}.btn-check[disabled]+.btn,.btn-check:disabled+.btn{pointer-events:none;filter:none;opacity:.35}.form-range{width:100%;height:1rem;padding:0;background-color:transparent;appearance:none}.form-range:focus{outline:0}.form-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 0 rgba(0,123,229,0.25)}.form-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 0 rgba(0,123,229,0.25)}.form-range::-moz-focus-outer{border:0}.form-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-.25rem;background-color:#007be5;border:0;border-radius:1rem;transition:background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out;appearance:none}@media (prefers-reduced-motion: reduce){.form-range::-webkit-slider-thumb{transition:none}}.form-range::-webkit-slider-thumb:active{background-color:#b3d7f7}.form-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.form-range::-moz-range-thumb{width:1rem;height:1rem;background-color:#007be5;border:0;border-radius:1rem;transition:background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out;appearance:none}@media (prefers-reduced-motion: reduce){.form-range::-moz-range-thumb{transition:none}}.form-range::-moz-range-thumb:active{background-color:#b3d7f7}.form-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.form-range:disabled{pointer-events:none}.form-range:disabled::-webkit-slider-thumb{background-color:#adb5bd}.form-range:disabled::-moz-range-thumb{background-color:#adb5bd}.form-floating{position:relative}.form-floating>.form-control,.form-floating>.form-select{height:calc(3.5rem + 2px);line-height:1.25}.form-floating>label{position:absolute;top:0;left:0;height:100%;padding:1rem .875rem;pointer-events:none;border:1px solid transparent;transform-origin:0 0;transition:opacity 0.1s ease-in-out,transform 0.1s ease-in-out}@media (prefers-reduced-motion: reduce){.form-floating>label{transition:none}}.form-floating>.form-control{padding:1rem .875rem}.form-floating>.form-control::placeholder{color:transparent}.form-floating>.form-control:focus,.form-floating>.form-control:not(:placeholder-shown){padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control:-webkit-autofill{padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-select{padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control:focus ~ label,.form-floating>.form-control:not(:placeholder-shown) ~ label,.form-floating>.form-select ~ label{opacity:.65;transform:scale(0.85) translateY(-0.5rem) translateX(0.15rem)}.form-floating>.form-control:-webkit-autofill ~ label{opacity:.65;transform:scale(0.85) translateY(-0.5rem) translateX(0.15rem)}.input-group{position:relative;display:flex;flex-wrap:wrap;align-items:stretch;width:100%}.input-group>.form-control,.input-group>.form-select{position:relative;flex:1 1 auto;width:1%;min-width:0}.input-group>.form-control:focus,.input-group>.form-select:focus{z-index:3}.input-group .btn{position:relative;z-index:2}.input-group .btn:focus{z-index:3}.input-group-text{display:flex;align-items:center;padding:0 .875rem;font-size:.75rem;font-weight:400;line-height:1.875rem;color:var(--t42-content-color);text-align:center;white-space:nowrap;background-color:#e9ecef;border:1px solid var(--t42-color-opacity-10);border-radius:0}.input-group-lg>.form-control,.input-group-lg>.form-select,.input-group-lg>.input-group-text,.input-group-lg>.btn{padding:0 .875rem;font-size:.75rem;border-radius:0}.input-group-sm>.form-control,.input-group-sm>.form-select,.input-group-sm>.input-group-text,.input-group-sm>.btn{padding:0 .875rem;font-size:.75rem;border-radius:0}.input-group-lg>.form-select,.input-group-sm>.form-select{padding-right:3.5rem}.input-group:not(.has-validation)>:not(:last-child):not(.dropdown-toggle):not(.dropdown-menu),.input-group:not(.has-validation)>.dropdown-toggle:nth-last-child(n+3){border-top-right-radius:0;border-bottom-right-radius:0}.input-group.has-validation>:nth-last-child(n+3):not(.dropdown-toggle):not(.dropdown-menu),.input-group.has-validation>.dropdown-toggle:nth-last-child(n+4){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>:not(:first-child):not(.dropdown-menu):not(.valid-tooltip):not(.valid-feedback):not(.invalid-tooltip):not(.invalid-feedback){margin-left:-1px;border-top-left-radius:0;border-bottom-left-radius:0}.valid-feedback{display:none;width:100%;margin-top:.5rem;font-size:.7rem;color:#43a047}.valid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem 1rem;margin-top:.1rem;font-size:.65625rem;color:#000;background-color:#43a047;border-radius:0}.was-validated :valid ~ .valid-feedback,.was-validated :valid ~ .valid-tooltip,.is-valid ~ .valid-feedback,.is-valid ~ .valid-tooltip{display:block}.was-validated .form-control:valid,.form-control.is-valid{border-color:#43a047;padding-right:2rem;background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 8 8%27%3e%3cpath fill=%27%2343a047%27 d=%27M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z%27/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right .5rem center;background-size:1rem 1rem}.was-validated .form-control:valid:focus,.form-control.is-valid:focus{border-color:#43a047;box-shadow:0 0 0 0 rgba(67,160,71,0.25)}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{padding-right:2rem;background-position:top .5rem right .5rem}.was-validated .form-select:valid,.form-select.is-valid{border-color:#43a047}.was-validated .form-select:valid:not([multiple]):not([size]),.was-validated .form-select:valid:not([multiple])[size="1"],.form-select.is-valid:not([multiple]):not([size]),.form-select.is-valid:not([multiple])[size="1"]{padding-right:3.5rem;background-image:var(--t42-select-indicator),url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 8 8%27%3e%3cpath fill=%27%2343a047%27 d=%27M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z%27/%3e%3c/svg%3e");background-position:right 0.5rem center,right 1.75rem center;background-size:1rem,1rem}.was-validated .form-select:valid:focus,.form-select.is-valid:focus{border-color:#43a047;box-shadow:0 0 0 0 rgba(67,160,71,0.25)}.was-validated .form-check-input:valid,.form-check-input.is-valid{border-color:#43a047}.was-validated .form-check-input:valid:checked,.form-check-input.is-valid:checked{background-color:#43a047}.was-validated .form-check-input:valid:focus,.form-check-input.is-valid:focus{box-shadow:0 0 0 0 rgba(67,160,71,0.25)}.was-validated .form-check-input:valid ~ .form-check-label,.form-check-input.is-valid ~ .form-check-label{color:#43a047}.form-check-inline .form-check-input ~ .valid-feedback{margin-left:.5em}.was-validated .input-group .form-control:valid,.input-group .form-control.is-valid,.was-validated .input-group .form-select:valid,.input-group .form-select.is-valid{z-index:1}.was-validated .input-group .form-control:valid:focus,.input-group .form-control.is-valid:focus,.was-validated .input-group .form-select:valid:focus,.input-group .form-select.is-valid:focus{z-index:3}.invalid-feedback{display:none;width:100%;margin-top:.5rem;font-size:.7rem;color:#ff511f}.invalid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem 1rem;margin-top:.1rem;font-size:.65625rem;color:#000;background-color:#ff511f;border-radius:0}.was-validated :invalid ~ .invalid-feedback,.was-validated :invalid ~ .invalid-tooltip,.is-invalid ~ .invalid-feedback,.is-invalid ~ .invalid-tooltip{display:block}.was-validated .form-control:invalid,.form-control.is-invalid{border-color:#ff511f;padding-right:2rem;background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 12 12%27 width=%2712%27 height=%2712%27 fill=%27none%27 stroke=%27%23ff511f%27%3e%3ccircle cx=%276%27 cy=%276%27 r=%274.5%27/%3e%3cpath stroke-linejoin=%27round%27 d=%27M5.8 3.6h.4L6 6.5z%27/%3e%3ccircle cx=%276%27 cy=%278.2%27 r=%27.6%27 fill=%27%23ff511f%27 stroke=%27none%27/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right .5rem center;background-size:1rem 1rem}.was-validated .form-control:invalid:focus,.form-control.is-invalid:focus{border-color:#ff511f;box-shadow:0 0 0 0 rgba(255,81,31,0.25)}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{padding-right:2rem;background-position:top .5rem right .5rem}.was-validated .form-select:invalid,.form-select.is-invalid{border-color:#ff511f}.was-validated .form-select:invalid:not([multiple]):not([size]),.was-validated .form-select:invalid:not([multiple])[size="1"],.form-select.is-invalid:not([multiple]):not([size]),.form-select.is-invalid:not([multiple])[size="1"]{padding-right:3.5rem;background-image:var(--t42-select-indicator),url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 12 12%27 width=%2712%27 height=%2712%27 fill=%27none%27 stroke=%27%23ff511f%27%3e%3ccircle cx=%276%27 cy=%276%27 r=%274.5%27/%3e%3cpath stroke-linejoin=%27round%27 d=%27M5.8 3.6h.4L6 6.5z%27/%3e%3ccircle cx=%276%27 cy=%278.2%27 r=%27.6%27 fill=%27%23ff511f%27 stroke=%27none%27/%3e%3c/svg%3e");background-position:right 0.5rem center,right 1.75rem center;background-size:1rem,1rem}.was-validated .form-select:invalid:focus,.form-select.is-invalid:focus{border-color:#ff511f;box-shadow:0 0 0 0 rgba(255,81,31,0.25)}.was-validated .form-check-input:invalid,.form-check-input.is-invalid{border-color:#ff511f}.was-validated .form-check-input:invalid:checked,.form-check-input.is-invalid:checked{background-color:#ff511f}.was-validated .form-check-input:invalid:focus,.form-check-input.is-invalid:focus{box-shadow:0 0 0 0 rgba(255,81,31,0.25)}.was-validated .form-check-input:invalid ~ .form-check-label,.form-check-input.is-invalid ~ .form-check-label{color:#ff511f}.form-check-inline .form-check-input ~ .invalid-feedback{margin-left:.5em}.was-validated .input-group .form-control:invalid,.input-group .form-control.is-invalid,.was-validated .input-group .form-select:invalid,.input-group .form-select.is-invalid{z-index:2}.was-validated .input-group .form-control:invalid:focus,.input-group .form-control.is-invalid:focus,.was-validated .input-group .form-select:invalid:focus,.input-group .form-select.is-invalid:focus{z-index:3}input{background-color:var(--t42-input-bg)}input[type="number"]::-webkit-calendar-picker-indicator,input[type="datetime-local"]::-webkit-calendar-picker-indicator,input[type="month"]::-webkit-calendar-picker-indicator,input[type="week"]::-webkit-calendar-picker-indicator,input[type="time"]::-webkit-calendar-picker-indicator,input[type="date"]::-webkit-calendar-picker-indicator{background:transparent}input[type="number"]::-webkit-inner-spin-button,input[type="datetime-local"]::-webkit-inner-spin-button,input[type="month"]::-webkit-inner-spin-button,input[type="week"]::-webkit-inner-spin-button,input[type="time"]::-webkit-inner-spin-button,input[type="date"]::-webkit-inner-spin-button{appearance:none}input[type="color"],input[type="range"]{padding:0;border:0}form div[class^="col"]{position:relative}.form-check-label input[type="checkbox"],.form-check-label input[type="radio"]{margin-top:0.125rem;margin-left:-1.2rem;opacity:1}.form-check .form-check-input:disabled{opacity:0}.form-check-label{margin-bottom:0}.form-check-inline .form-check-label{padding-left:0.25rem}.form-check-inline input[type="radio"]:checked+label::after{left:-1rem}.form-control{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border;background-color:transparent}.form-control:disabled,.form-control.disabled,.form-control[readonly]{cursor:default;opacity:0.65}.form-control.is-valid,.form-control.is-invalid{border-color:var(--t42-color-opacity-10)}.form-control.is-valid:focus,.form-control.is-invalid:focus{border-color:var(--primary);box-shadow:none}.form-control[type="file"]{opacity:0}.form-text{color:var(--secondary)}.form-control-plaintext:focus{outline:0}select{background-image:var(--t42-select-indicator);background-repeat:no-repeat;background-position:right 0.5rem center;background-size:1rem;cursor:pointer;appearance:none}select[multiple]{padding:0;background-image:none}select[multiple] option{padding:0 0.875rem}select[multiple] option:checked{background-color:var(--primary)}select:disabled{border-color:transparent;cursor:default;opacity:0.65}textarea,textarea.form-control{min-height:90px;max-height:180px;padding-top:5px;padding-bottom:5px}textarea:disabled,textarea.form-control:disabled{border-color:transparent}input[type="range"]{width:100%;appearance:none}input[type="range"]:focus{background-color:transparent;outline:none}input[type="range"]:focus::-ms-fill-lower,input[type="range"]:focus::-ms-fill-upper{background:var(--primary)}input[type="range"]::-webkit-slider-runnable-track{width:100%;height:0.0625rem;border:0;border-radius:0;background:var(--t42-color-opacity-10);box-shadow:none;cursor:pointer}input[type="range"]::-webkit-slider-thumb{width:12px;height:12px;margin-top:-5px;border:0;border-radius:50%;background:var(--primary);box-shadow:none;cursor:pointer;appearance:none}input[type="range"]:focus::-webkit-slider-runnable-track{background:var(--t42-color-opacity-10)}input[type="range"]::-moz-range-track{width:100%;height:2px;border:0;border-radius:0;background:var(--t42-color-opacity-10);box-shadow:none;cursor:pointer}input[type="range"]::-moz-range-thumb{width:12px;height:12px;border:0;border-radius:50px;background:var(--primary);box-shadow:none;cursor:pointer}input[type="range"]::-ms-track{width:100%;height:2px;border-color:transparent;color:transparent;background:transparent;cursor:pointer}input[type="range"]::-ms-fill-lower,input[type="range"]::-ms-fill-upper{border:0;border-radius:0;background:var(--primary);box-shadow:none}input[type="range"]::-ms-thumb{width:12px;height:12px;border:0;border-radius:50px;background:var(--primary);box-shadow:none;cursor:pointer}input[type="checkbox"]{opacity:0}input[type="checkbox"]+label{position:relative;color:var(--t42-content-color-muted);cursor:pointer;user-select:none}input[type="checkbox"]+label::before{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, border-color;position:absolute;top:0.0625rem;left:-1.25rem;display:block;width:0.875rem;height:0.875rem;border:0.0625rem solid var(--t42-content-color-muted);border-radius:0;cursor:pointer;content:"";pointer-events:all}input[type="checkbox"]+label::after{position:absolute;top:0.125rem;left:-1.188rem;display:block;width:0.875rem;height:0.875rem;background-image:none;content:"";-webkit-mask-size:0.75rem;-webkit-mask-repeat:no-repeat;content:""}input[type="checkbox"].indeterminate+label::before,input[type="checkbox"]:indeterminate+label::before{border-color:var(--t42-color-opacity-30);background-color:var(--primary)}input[type="checkbox"].indeterminate+label::after,input[type="checkbox"]:indeterminate+label::after{top:0.375rem;left:-1.063rem;width:0.5rem;height:0.188rem;background-color:var(--white)}input[type="checkbox"]:disabled+label,input[type="checkbox"]:disabled+.form-check-label{color:var(--t42-content-color-disabled)}input[type="checkbox"]:checked.disabled+label,input[type="checkbox"]:checked:disabled+label,input[type="checkbox"]:indeterminate.disabled+label,input[type="checkbox"]:indeterminate:disabled+label,input[type="checkbox"].disabled+label,input[type="checkbox"]:disabled+label{color:var(--t42-content-color-disabled)}input[type="checkbox"]:checked.disabled+label::before,input[type="checkbox"]:checked:disabled+label::before,input[type="checkbox"]:indeterminate.disabled+label::before,input[type="checkbox"]:indeterminate:disabled+label::before,input[type="checkbox"].disabled+label::before,input[type="checkbox"]:disabled+label::before{border-color:transparent;background-color:var(--t42-color-opacity-10)}input[type="checkbox"]:checked+label::before{border-color:var(--t42-color-opacity-30);background-color:var(--primary)}input[type="checkbox"]:checked+label::after{background-color:var(--t42-link-color);-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M212.48599,435.14899c-11.60532,0.00003-21.16266-4.77866-28.672-14.336l-92.16-120.832 c-5.46133-8.19202-7.50933-17.06665-6.144-26.62399s5.80267-17.408,13.312-23.552s16.21333-8.53334,26.112-7.168 c9.89867,1.36533,17.92,6.14401,24.064,14.336l60.416,78.84799L360.966,93.13298c5.46133-8.192,12.79999-13.312,22.01599-15.36 s18.26132-0.68267,27.13599,4.096c8.19199,5.46133,13.31198,12.8,15.35999,22.016s0.68265,18.26133-4.09601,27.136l-179.2,286.71997 c-6.82668,10.9227-16.384,16.384-28.672,16.384L212.48599,435.14899z%27/%3E%3C/svg%3E")}input[type="radio"]{opacity:0}input[type="radio"]+label{position:relative;color:var(--t42-content-color-muted);cursor:pointer;user-select:none}input[type="radio"]+label::before{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, border;position:absolute;top:0.0625rem;left:-1.25rem;display:block;width:0.875rem;height:0.875rem;border:0.0625rem solid var(--t42-content-color-muted);border-radius:50%;cursor:pointer;content:"";pointer-events:all}input[type="radio"]+label::after{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, border;position:absolute;top:0.313rem;left:-1rem;display:block;width:0.375rem;height:0.375rem;border-radius:50%;color:var(--white);background-image:none;transform:scale(0);opacity:0;content:""}input[type="radio"]+label:focus{border-color:var(--primary)}input[type="radio"]:disabled+label,input[type="radio"]:disabled+.form-check-label{color:var(--t42-content-color-disabled)}input[type="radio"]:checked.disabled+label,input[type="radio"]:checked:disabled+label,input[type="radio"].disabled+label,input[type="radio"]:disabled+label{color:var(--t42-content-color-disabled)}input[type="radio"]:checked.disabled+label::before,input[type="radio"]:checked:disabled+label::before,input[type="radio"].disabled+label::before,input[type="radio"]:disabled+label::before{border-color:transparent;background-color:var(--t42-color-opacity-10)}input[type="radio"]:checked+label::before{border-color:var(--t42-color-opacity-30);background-color:var(--primary)}input[type="radio"]:checked+label::after{background-color:var(--white);transform:scale(1);opacity:1}.custom-control{padding-left:1.25rem}.custom-control .custom-control-input:checked ~ .custom-control-label::before{border-color:var(--t42-color-opacity-30)}.custom-select,.form-select{max-height:2rem;background-color:transparent;background-image:var(--t42-select-indicator);background-repeat:no-repeat;background-position:right 0.5rem center;background-size:1rem}.custom-select:focus,.custom-select option,.form-select:focus,.form-select option{background-color:var(--t42-input-bg)}.custom-select:disabled option,.form-select:disabled option{background-color:transparent}.custom-radio .custom-control-label{color:var(--t42-content-color-muted);user-select:none}.custom-radio .custom-control-label::after{background:none}.custom-radio .custom-control-input:checked ~ .custom-control-label::after{background-image:none}.custom-checkbox .custom-control-label{color:var(--t42-content-color-muted);user-select:none}.custom-checkbox .custom-control-label::after{background:none}.custom-checkbox .custom-control-input:checked ~ .custom-control-label::after{background-image:none}.custom-checkbox .custom-control-input:disabled .custom-control-label::after,.custom-checkbox .custom-control-input:disabled:checked ~ .custom-control-label::after,.custom-checkbox .custom-control-input:disabled:indeterminate ~ .custom-control-label::after{opacity:0.4}.custom-checkbox .custom-control-input:disabled ~ .custom-control-label::before{border-color:transparent}.switch{position:relative;display:inline-block;align-items:center;height:0.875rem;margin-bottom:0;padding-left:2rem;cursor:pointer}.switch.disabled{color:var(--t42-content-color-disabled)}.switch .slider{position:absolute;top:0;right:0;bottom:0;left:0;width:1.75rem;border:1px solid var(--t42-content-color-muted);cursor:pointer;transition:0.4s}.switch .slider::before{position:absolute;bottom:0.125rem;left:0.125rem;width:0.5rem;height:0.5rem;background-color:var(--t42-content-color-muted);transition:0.4s;content:""}.switch input{width:0;height:0;opacity:0}.switch input:checked+.slider{border:var(--t42-border);background-color:var(--primary)}.switch input:checked+.slider::before{background-color:var(--white);transform:translateX(0.875rem)}.switch input:focus+.slider{box-shadow:0 0 1px #2196f3}.switch input:disabled+.slider{border:var(--t42-border);background-color:var(--t42-color-opacity-10)}.switch input:disabled+.slider::before{background-color:var(--t42-color-opacity-20)}.input-group-prepend .input-group-text{justify-content:center;border-right:0}.input-group-append .input-group-text{justify-content:center;border-left:0}.input-group-append .custom-control,.input-group-prepend .custom-control{margin-bottom:0;padding-left:0.875rem}.input-group-append .custom-control-label,.input-group-prepend .custom-control-label{position:absolute;left:0;min-width:0.875rem;min-height:0.875rem}.input-group-append .custom-control-label::before,.input-group-prepend .custom-control-label::before{left:0}.input-group-append .custom-control-label::after,.input-group-prepend .custom-control-label::after{left:0.25rem}.input-group-append .custom-checkbox .custom-control-label::after,.input-group-prepend .custom-checkbox .custom-control-label::after{left:0.125rem}.custom-file{margin-bottom:1rem}.custom-file-input,.form-control[type="file"]{z-index:1}.custom-file-input:focus ~ .custom-file-label,.form-control[type="file"]:focus ~ .custom-file-label{background-color:var(--t42-input-bg)}.custom-file-label,.input-group-text{background-color:transparent}.custom-file-label::after,.input-group-text::after{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color;background-color:Rgba(--secondary, 0.05);cursor:pointer}.custom-file-label:hover::after,.input-group-text:hover::after{color:var(--white);background-color:var(--secondary)}.form-control[type="file"]+.input-group-text{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color,color;position:absolute;top:0;right:0;left:0;z-index:1;height:2rem;padding:0.375rem 0.875rem;border:var(--t42-border);color:var(--t42-content-color-muted)}.form-control[type="file"]+.input-group-text::after{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color,color;position:absolute;top:0;right:0;bottom:0;z-index:3;display:block;height:100%;padding:0.375rem 0.875rem;border-left:inherit;color:var(--t42-link-color);line-height:1.5;cursor:pointer;content:"Browse"}.form-control[type="file"]+.input-group-text:hover{background-color:var(--t42-input-bg)}.form-control[type="file"]+.input-group-text:hover::after{color:var(--white);background-color:var(--secondary)}.custom-switch{padding-left:2rem}.custom-switch .custom-control-label::before{left:-2rem}.custom-switch .custom-control-label::after{top:0.25rem;left:-1.813rem;width:0.5rem;height:0.5rem}.custom-switch .custom-control-input:checked ~ .custom-control-label::after{background-color:var(--white);content:""}.custom-switch .custom-control-input:not(:disabled):active ~ .custom-control-label::before{border-color:var(--t42-color-opacity-30);background-color:var(--primary)}.valid-feedback,.valid-tooltip,.invalid-feedback,.invalid-tooltip,.warning-feedback,.warning-tooltip{position:absolute;bottom:-1rem;width:calc(100% - 1.875rem);margin-top:0;overflow:hidden;color:var(--t42-content-color);font-size:.7rem;white-space:nowrap;text-overflow:ellipsis}.valid-tooltip,.invalid-tooltip,.warning-tooltip{color:var(--t42-content-color-muted)}.custom-radio label+div,.custom-checkbox label+div,.form-check label+div{width:calc(100% + 1.25rem);transform:translateX(-1.25rem)}.form-group{margin-bottom:1rem}label{margin-bottom:0.5rem}.form-row{display:flex;flex-wrap:wrap;margin-right:-0.5rem;margin-left:-0.5rem}.form-row>.col,.form-row>[class*="col-"]{padding-right:0.5rem;padding-left:0.5rem}.form-inline{display:flex;flex-flow:row wrap;align-items:center}.form-inline .form-check{width:100%}@media (min-width: 576px){.form-inline label{display:flex;align-items:center;justify-content:center;margin-bottom:0}.form-inline .form-group{display:flex;flex:0 0 auto;flex-flow:row wrap;align-items:center;margin-bottom:0}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-plaintext{display:inline-block}.form-inline .input-group,.form-inline .custom-select,.form-inline .form-select{width:auto}.form-inline .form-check{display:flex;align-items:center;justify-content:center;width:auto;padding-left:0}.form-inline .form-check-input{position:relative;flex-shrink:0;margin-top:0;margin-left:0}.form-inline .custom-control{align-items:center;justify-content:center}.form-inline .custom-control-label{margin-bottom:0}}/*! + * Bootstrap Grid v5.1.3 (https://getbootstrap.com/) + * Copyright 2011-2021 The Bootstrap Authors + * Copyright 2011-2021 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) + */:root{--bs-blue: #007be5;--bs-indigo: #6610f2;--bs-purple: #6f42c1;--bs-pink: #fd397a;--bs-red: #ff511f;--bs-orange: #fd7e14;--bs-yellow: #f9a825;--bs-green: #43a047;--bs-teal: #616161;--bs-cyan: #469eb9;--bs-white: #fff;--bs-gray: #6c757d;--bs-gray-dark: #343a40;--bs-gray-100: #f8f9fa;--bs-gray-200: #e9ecef;--bs-gray-300: #dee2e6;--bs-gray-400: #ced4da;--bs-gray-500: #adb5bd;--bs-gray-600: #6c757d;--bs-gray-700: #495057;--bs-gray-800: #343a40;--bs-gray-900: #212529;--bs-primary: #007be5;--bs-secondary: #616161;--bs-success: #43a047;--bs-info: #469eb9;--bs-warning: #f9a825;--bs-danger: #ff511f;--bs-light: #616161;--bs-dark: #616161;--bs-primary-rgb: 0,123,229;--bs-secondary-rgb: 97,97,97;--bs-success-rgb: 67,160,71;--bs-info-rgb: 70,158,185;--bs-warning-rgb: 249,168,37;--bs-danger-rgb: 255,81,31;--bs-light-rgb: 97,97,97;--bs-dark-rgb: 97,97,97;--bs-white-rgb: 255,255,255;--bs-black-rgb: 0,0,0;--bs-body-color-rgb: 33,37,41;--bs-body-bg-rgb: 255,255,255;--bs-font-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--bs-gradient: linear-gradient(180deg, rgba(255,255,255,0.15), rgba(255,255,255,0));--bs-body-font-family: Montserrat,Helvetica Neue,Arial,sans-serif;--bs-body-font-size: .75rem;--bs-body-font-weight: 400;--bs-body-line-height: 1.5;--bs-body-color: #212529;--bs-body-bg: #fff}.container,.container-fluid,.container-sm,.container-md,.container-lg,.container-xl,.container-xxl{width:100%;padding-right:var(--bs-gutter-x, .75rem);padding-left:var(--bs-gutter-x, .75rem);margin-right:auto;margin-left:auto}@media (min-width: 576px){.container,.container-sm{max-width:540px}}@media (min-width: 768px){.container,.container-sm,.container-md{max-width:720px}}@media (min-width: 992px){.container,.container-sm,.container-md,.container-lg{max-width:960px}}@media (min-width: 1200px){.container,.container-sm,.container-md,.container-lg,.container-xl{max-width:1140px}}@media (min-width: 1400px){.container,.container-sm,.container-md,.container-lg,.container-xl,.container-xxl{max-width:1320px}}.row{--bs-gutter-x: 1.5rem;--bs-gutter-y: 0;display:flex;flex-wrap:wrap;margin-top:calc(-1 * var(--bs-gutter-y));margin-right:calc(-.5 * var(--bs-gutter-x));margin-left:calc(-.5 * var(--bs-gutter-x))}.row>*{box-sizing:border-box;flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--bs-gutter-x) * .5);padding-left:calc(var(--bs-gutter-x) * .5);margin-top:var(--bs-gutter-y)}.col{flex:1 0 0%}.row-cols-auto>*{flex:0 0 auto;width:auto}.row-cols-1>*{flex:0 0 auto;width:100%}.row-cols-2>*{flex:0 0 auto;width:50%}.row-cols-3>*{flex:0 0 auto;width:33.33333%}.row-cols-4>*{flex:0 0 auto;width:25%}.row-cols-5>*{flex:0 0 auto;width:20%}.row-cols-6>*{flex:0 0 auto;width:16.66667%}.col-auto{flex:0 0 auto;width:auto}.col-1{flex:0 0 auto;width:8.33333%}.col-2{flex:0 0 auto;width:16.66667%}.col-3{flex:0 0 auto;width:25%}.col-4{flex:0 0 auto;width:33.33333%}.col-5{flex:0 0 auto;width:41.66667%}.col-6{flex:0 0 auto;width:50%}.col-7{flex:0 0 auto;width:58.33333%}.col-8{flex:0 0 auto;width:66.66667%}.col-9{flex:0 0 auto;width:75%}.col-10{flex:0 0 auto;width:83.33333%}.col-11{flex:0 0 auto;width:91.66667%}.col-12{flex:0 0 auto;width:100%}.offset-1{margin-left:8.33333%}.offset-2{margin-left:16.66667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.33333%}.offset-5{margin-left:41.66667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.33333%}.offset-8{margin-left:66.66667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.33333%}.offset-11{margin-left:91.66667%}.g-0,.gx-0{--bs-gutter-x: 0}.g-0,.gy-0{--bs-gutter-y: 0}.g-1,.gx-1{--bs-gutter-x: .25rem}.g-1,.gy-1{--bs-gutter-y: .25rem}.g-2,.gx-2{--bs-gutter-x: .5rem}.g-2,.gy-2{--bs-gutter-y: .5rem}.g-3,.gx-3{--bs-gutter-x: 1rem}.g-3,.gy-3{--bs-gutter-y: 1rem}.g-4,.gx-4{--bs-gutter-x: 1.5rem}.g-4,.gy-4{--bs-gutter-y: 1.5rem}.g-5,.gx-5{--bs-gutter-x: 3rem}.g-5,.gy-5{--bs-gutter-y: 3rem}@media (min-width: 576px){.col-sm{flex:1 0 0%}.row-cols-sm-auto>*{flex:0 0 auto;width:auto}.row-cols-sm-1>*{flex:0 0 auto;width:100%}.row-cols-sm-2>*{flex:0 0 auto;width:50%}.row-cols-sm-3>*{flex:0 0 auto;width:33.33333%}.row-cols-sm-4>*{flex:0 0 auto;width:25%}.row-cols-sm-5>*{flex:0 0 auto;width:20%}.row-cols-sm-6>*{flex:0 0 auto;width:16.66667%}.col-sm-auto{flex:0 0 auto;width:auto}.col-sm-1{flex:0 0 auto;width:8.33333%}.col-sm-2{flex:0 0 auto;width:16.66667%}.col-sm-3{flex:0 0 auto;width:25%}.col-sm-4{flex:0 0 auto;width:33.33333%}.col-sm-5{flex:0 0 auto;width:41.66667%}.col-sm-6{flex:0 0 auto;width:50%}.col-sm-7{flex:0 0 auto;width:58.33333%}.col-sm-8{flex:0 0 auto;width:66.66667%}.col-sm-9{flex:0 0 auto;width:75%}.col-sm-10{flex:0 0 auto;width:83.33333%}.col-sm-11{flex:0 0 auto;width:91.66667%}.col-sm-12{flex:0 0 auto;width:100%}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.33333%}.offset-sm-2{margin-left:16.66667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.33333%}.offset-sm-5{margin-left:41.66667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.33333%}.offset-sm-8{margin-left:66.66667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.33333%}.offset-sm-11{margin-left:91.66667%}.g-sm-0,.gx-sm-0{--bs-gutter-x: 0}.g-sm-0,.gy-sm-0{--bs-gutter-y: 0}.g-sm-1,.gx-sm-1{--bs-gutter-x: .25rem}.g-sm-1,.gy-sm-1{--bs-gutter-y: .25rem}.g-sm-2,.gx-sm-2{--bs-gutter-x: .5rem}.g-sm-2,.gy-sm-2{--bs-gutter-y: .5rem}.g-sm-3,.gx-sm-3{--bs-gutter-x: 1rem}.g-sm-3,.gy-sm-3{--bs-gutter-y: 1rem}.g-sm-4,.gx-sm-4{--bs-gutter-x: 1.5rem}.g-sm-4,.gy-sm-4{--bs-gutter-y: 1.5rem}.g-sm-5,.gx-sm-5{--bs-gutter-x: 3rem}.g-sm-5,.gy-sm-5{--bs-gutter-y: 3rem}}@media (min-width: 768px){.col-md{flex:1 0 0%}.row-cols-md-auto>*{flex:0 0 auto;width:auto}.row-cols-md-1>*{flex:0 0 auto;width:100%}.row-cols-md-2>*{flex:0 0 auto;width:50%}.row-cols-md-3>*{flex:0 0 auto;width:33.33333%}.row-cols-md-4>*{flex:0 0 auto;width:25%}.row-cols-md-5>*{flex:0 0 auto;width:20%}.row-cols-md-6>*{flex:0 0 auto;width:16.66667%}.col-md-auto{flex:0 0 auto;width:auto}.col-md-1{flex:0 0 auto;width:8.33333%}.col-md-2{flex:0 0 auto;width:16.66667%}.col-md-3{flex:0 0 auto;width:25%}.col-md-4{flex:0 0 auto;width:33.33333%}.col-md-5{flex:0 0 auto;width:41.66667%}.col-md-6{flex:0 0 auto;width:50%}.col-md-7{flex:0 0 auto;width:58.33333%}.col-md-8{flex:0 0 auto;width:66.66667%}.col-md-9{flex:0 0 auto;width:75%}.col-md-10{flex:0 0 auto;width:83.33333%}.col-md-11{flex:0 0 auto;width:91.66667%}.col-md-12{flex:0 0 auto;width:100%}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.33333%}.offset-md-2{margin-left:16.66667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.33333%}.offset-md-5{margin-left:41.66667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.33333%}.offset-md-8{margin-left:66.66667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.33333%}.offset-md-11{margin-left:91.66667%}.g-md-0,.gx-md-0{--bs-gutter-x: 0}.g-md-0,.gy-md-0{--bs-gutter-y: 0}.g-md-1,.gx-md-1{--bs-gutter-x: .25rem}.g-md-1,.gy-md-1{--bs-gutter-y: .25rem}.g-md-2,.gx-md-2{--bs-gutter-x: .5rem}.g-md-2,.gy-md-2{--bs-gutter-y: .5rem}.g-md-3,.gx-md-3{--bs-gutter-x: 1rem}.g-md-3,.gy-md-3{--bs-gutter-y: 1rem}.g-md-4,.gx-md-4{--bs-gutter-x: 1.5rem}.g-md-4,.gy-md-4{--bs-gutter-y: 1.5rem}.g-md-5,.gx-md-5{--bs-gutter-x: 3rem}.g-md-5,.gy-md-5{--bs-gutter-y: 3rem}}@media (min-width: 992px){.col-lg{flex:1 0 0%}.row-cols-lg-auto>*{flex:0 0 auto;width:auto}.row-cols-lg-1>*{flex:0 0 auto;width:100%}.row-cols-lg-2>*{flex:0 0 auto;width:50%}.row-cols-lg-3>*{flex:0 0 auto;width:33.33333%}.row-cols-lg-4>*{flex:0 0 auto;width:25%}.row-cols-lg-5>*{flex:0 0 auto;width:20%}.row-cols-lg-6>*{flex:0 0 auto;width:16.66667%}.col-lg-auto{flex:0 0 auto;width:auto}.col-lg-1{flex:0 0 auto;width:8.33333%}.col-lg-2{flex:0 0 auto;width:16.66667%}.col-lg-3{flex:0 0 auto;width:25%}.col-lg-4{flex:0 0 auto;width:33.33333%}.col-lg-5{flex:0 0 auto;width:41.66667%}.col-lg-6{flex:0 0 auto;width:50%}.col-lg-7{flex:0 0 auto;width:58.33333%}.col-lg-8{flex:0 0 auto;width:66.66667%}.col-lg-9{flex:0 0 auto;width:75%}.col-lg-10{flex:0 0 auto;width:83.33333%}.col-lg-11{flex:0 0 auto;width:91.66667%}.col-lg-12{flex:0 0 auto;width:100%}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.33333%}.offset-lg-2{margin-left:16.66667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.33333%}.offset-lg-5{margin-left:41.66667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.33333%}.offset-lg-8{margin-left:66.66667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.33333%}.offset-lg-11{margin-left:91.66667%}.g-lg-0,.gx-lg-0{--bs-gutter-x: 0}.g-lg-0,.gy-lg-0{--bs-gutter-y: 0}.g-lg-1,.gx-lg-1{--bs-gutter-x: .25rem}.g-lg-1,.gy-lg-1{--bs-gutter-y: .25rem}.g-lg-2,.gx-lg-2{--bs-gutter-x: .5rem}.g-lg-2,.gy-lg-2{--bs-gutter-y: .5rem}.g-lg-3,.gx-lg-3{--bs-gutter-x: 1rem}.g-lg-3,.gy-lg-3{--bs-gutter-y: 1rem}.g-lg-4,.gx-lg-4{--bs-gutter-x: 1.5rem}.g-lg-4,.gy-lg-4{--bs-gutter-y: 1.5rem}.g-lg-5,.gx-lg-5{--bs-gutter-x: 3rem}.g-lg-5,.gy-lg-5{--bs-gutter-y: 3rem}}@media (min-width: 1200px){.col-xl{flex:1 0 0%}.row-cols-xl-auto>*{flex:0 0 auto;width:auto}.row-cols-xl-1>*{flex:0 0 auto;width:100%}.row-cols-xl-2>*{flex:0 0 auto;width:50%}.row-cols-xl-3>*{flex:0 0 auto;width:33.33333%}.row-cols-xl-4>*{flex:0 0 auto;width:25%}.row-cols-xl-5>*{flex:0 0 auto;width:20%}.row-cols-xl-6>*{flex:0 0 auto;width:16.66667%}.col-xl-auto{flex:0 0 auto;width:auto}.col-xl-1{flex:0 0 auto;width:8.33333%}.col-xl-2{flex:0 0 auto;width:16.66667%}.col-xl-3{flex:0 0 auto;width:25%}.col-xl-4{flex:0 0 auto;width:33.33333%}.col-xl-5{flex:0 0 auto;width:41.66667%}.col-xl-6{flex:0 0 auto;width:50%}.col-xl-7{flex:0 0 auto;width:58.33333%}.col-xl-8{flex:0 0 auto;width:66.66667%}.col-xl-9{flex:0 0 auto;width:75%}.col-xl-10{flex:0 0 auto;width:83.33333%}.col-xl-11{flex:0 0 auto;width:91.66667%}.col-xl-12{flex:0 0 auto;width:100%}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.33333%}.offset-xl-2{margin-left:16.66667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.33333%}.offset-xl-5{margin-left:41.66667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.33333%}.offset-xl-8{margin-left:66.66667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.33333%}.offset-xl-11{margin-left:91.66667%}.g-xl-0,.gx-xl-0{--bs-gutter-x: 0}.g-xl-0,.gy-xl-0{--bs-gutter-y: 0}.g-xl-1,.gx-xl-1{--bs-gutter-x: .25rem}.g-xl-1,.gy-xl-1{--bs-gutter-y: .25rem}.g-xl-2,.gx-xl-2{--bs-gutter-x: .5rem}.g-xl-2,.gy-xl-2{--bs-gutter-y: .5rem}.g-xl-3,.gx-xl-3{--bs-gutter-x: 1rem}.g-xl-3,.gy-xl-3{--bs-gutter-y: 1rem}.g-xl-4,.gx-xl-4{--bs-gutter-x: 1.5rem}.g-xl-4,.gy-xl-4{--bs-gutter-y: 1.5rem}.g-xl-5,.gx-xl-5{--bs-gutter-x: 3rem}.g-xl-5,.gy-xl-5{--bs-gutter-y: 3rem}}@media (min-width: 1400px){.col-xxl{flex:1 0 0%}.row-cols-xxl-auto>*{flex:0 0 auto;width:auto}.row-cols-xxl-1>*{flex:0 0 auto;width:100%}.row-cols-xxl-2>*{flex:0 0 auto;width:50%}.row-cols-xxl-3>*{flex:0 0 auto;width:33.33333%}.row-cols-xxl-4>*{flex:0 0 auto;width:25%}.row-cols-xxl-5>*{flex:0 0 auto;width:20%}.row-cols-xxl-6>*{flex:0 0 auto;width:16.66667%}.col-xxl-auto{flex:0 0 auto;width:auto}.col-xxl-1{flex:0 0 auto;width:8.33333%}.col-xxl-2{flex:0 0 auto;width:16.66667%}.col-xxl-3{flex:0 0 auto;width:25%}.col-xxl-4{flex:0 0 auto;width:33.33333%}.col-xxl-5{flex:0 0 auto;width:41.66667%}.col-xxl-6{flex:0 0 auto;width:50%}.col-xxl-7{flex:0 0 auto;width:58.33333%}.col-xxl-8{flex:0 0 auto;width:66.66667%}.col-xxl-9{flex:0 0 auto;width:75%}.col-xxl-10{flex:0 0 auto;width:83.33333%}.col-xxl-11{flex:0 0 auto;width:91.66667%}.col-xxl-12{flex:0 0 auto;width:100%}.offset-xxl-0{margin-left:0}.offset-xxl-1{margin-left:8.33333%}.offset-xxl-2{margin-left:16.66667%}.offset-xxl-3{margin-left:25%}.offset-xxl-4{margin-left:33.33333%}.offset-xxl-5{margin-left:41.66667%}.offset-xxl-6{margin-left:50%}.offset-xxl-7{margin-left:58.33333%}.offset-xxl-8{margin-left:66.66667%}.offset-xxl-9{margin-left:75%}.offset-xxl-10{margin-left:83.33333%}.offset-xxl-11{margin-left:91.66667%}.g-xxl-0,.gx-xxl-0{--bs-gutter-x: 0}.g-xxl-0,.gy-xxl-0{--bs-gutter-y: 0}.g-xxl-1,.gx-xxl-1{--bs-gutter-x: .25rem}.g-xxl-1,.gy-xxl-1{--bs-gutter-y: .25rem}.g-xxl-2,.gx-xxl-2{--bs-gutter-x: .5rem}.g-xxl-2,.gy-xxl-2{--bs-gutter-y: .5rem}.g-xxl-3,.gx-xxl-3{--bs-gutter-x: 1rem}.g-xxl-3,.gy-xxl-3{--bs-gutter-y: 1rem}.g-xxl-4,.gx-xxl-4{--bs-gutter-x: 1.5rem}.g-xxl-4,.gy-xxl-4{--bs-gutter-y: 1.5rem}.g-xxl-5,.gx-xxl-5{--bs-gutter-x: 3rem}.g-xxl-5,.gy-xxl-5{--bs-gutter-y: 3rem}}.d-inline{display:inline !important}.d-inline-block{display:inline-block !important}.d-block{display:block !important}.d-grid{display:grid !important}.d-table{display:table !important}.d-table-row{display:table-row !important}.d-table-cell{display:table-cell !important}.d-flex{display:flex !important}.d-inline-flex{display:inline-flex !important}.d-none{display:none !important}.flex-fill{flex:1 1 auto !important}.flex-row{flex-direction:row !important}.flex-column{flex-direction:column !important}.flex-row-reverse{flex-direction:row-reverse !important}.flex-column-reverse{flex-direction:column-reverse !important}.flex-grow-0{flex-grow:0 !important}.flex-grow-1{flex-grow:1 !important}.flex-shrink-0{flex-shrink:0 !important}.flex-shrink-1{flex-shrink:1 !important}.flex-wrap{flex-wrap:wrap !important}.flex-nowrap{flex-wrap:nowrap !important}.flex-wrap-reverse{flex-wrap:wrap-reverse !important}.justify-content-start{justify-content:flex-start !important}.justify-content-end{justify-content:flex-end !important}.justify-content-center{justify-content:center !important}.justify-content-between{justify-content:space-between !important}.justify-content-around{justify-content:space-around !important}.justify-content-evenly{justify-content:space-evenly !important}.align-items-start{align-items:flex-start !important}.align-items-end{align-items:flex-end !important}.align-items-center{align-items:center !important}.align-items-baseline{align-items:baseline !important}.align-items-stretch{align-items:stretch !important}.align-content-start{align-content:flex-start !important}.align-content-end{align-content:flex-end !important}.align-content-center{align-content:center !important}.align-content-between{align-content:space-between !important}.align-content-around{align-content:space-around !important}.align-content-stretch{align-content:stretch !important}.align-self-auto{align-self:auto !important}.align-self-start{align-self:flex-start !important}.align-self-end{align-self:flex-end !important}.align-self-center{align-self:center !important}.align-self-baseline{align-self:baseline !important}.align-self-stretch{align-self:stretch !important}.order-first{order:-1 !important}.order-0{order:0 !important}.order-1{order:1 !important}.order-2{order:2 !important}.order-3{order:3 !important}.order-4{order:4 !important}.order-5{order:5 !important}.order-last{order:6 !important}.m-0{margin:0 !important}.m-1{margin:.25rem !important}.m-2{margin:.5rem !important}.m-3{margin:1rem !important}.m-4{margin:1.5rem !important}.m-5{margin:3rem !important}.m-auto{margin:auto !important}.mx-0{margin-right:0 !important;margin-left:0 !important}.mx-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-3{margin-right:1rem !important;margin-left:1rem !important}.mx-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-5{margin-right:3rem !important;margin-left:3rem !important}.mx-auto{margin-right:auto !important;margin-left:auto !important}.my-0{margin-top:0 !important;margin-bottom:0 !important}.my-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-0{margin-top:0 !important}.mt-1{margin-top:.25rem !important}.mt-2{margin-top:.5rem !important}.mt-3{margin-top:1rem !important}.mt-4{margin-top:1.5rem !important}.mt-5{margin-top:3rem !important}.mt-auto{margin-top:auto !important}.me-0{margin-right:0 !important}.me-1{margin-right:.25rem !important}.me-2{margin-right:.5rem !important}.me-3{margin-right:1rem !important}.me-4{margin-right:1.5rem !important}.me-5{margin-right:3rem !important}.me-auto{margin-right:auto !important}.mb-0{margin-bottom:0 !important}.mb-1{margin-bottom:.25rem !important}.mb-2{margin-bottom:.5rem !important}.mb-3{margin-bottom:1rem !important}.mb-4{margin-bottom:1.5rem !important}.mb-5{margin-bottom:3rem !important}.mb-auto{margin-bottom:auto !important}.ms-0{margin-left:0 !important}.ms-1{margin-left:.25rem !important}.ms-2{margin-left:.5rem !important}.ms-3{margin-left:1rem !important}.ms-4{margin-left:1.5rem !important}.ms-5{margin-left:3rem !important}.ms-auto{margin-left:auto !important}.p-0{padding:0 !important}.p-1{padding:.25rem !important}.p-2{padding:.5rem !important}.p-3{padding:1rem !important}.p-4{padding:1.5rem !important}.p-5{padding:3rem !important}.px-0{padding-right:0 !important;padding-left:0 !important}.px-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-3{padding-right:1rem !important;padding-left:1rem !important}.px-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-5{padding-right:3rem !important;padding-left:3rem !important}.py-0{padding-top:0 !important;padding-bottom:0 !important}.py-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-0{padding-top:0 !important}.pt-1{padding-top:.25rem !important}.pt-2{padding-top:.5rem !important}.pt-3{padding-top:1rem !important}.pt-4{padding-top:1.5rem !important}.pt-5{padding-top:3rem !important}.pe-0{padding-right:0 !important}.pe-1{padding-right:.25rem !important}.pe-2{padding-right:.5rem !important}.pe-3{padding-right:1rem !important}.pe-4{padding-right:1.5rem !important}.pe-5{padding-right:3rem !important}.pb-0{padding-bottom:0 !important}.pb-1{padding-bottom:.25rem !important}.pb-2{padding-bottom:.5rem !important}.pb-3{padding-bottom:1rem !important}.pb-4{padding-bottom:1.5rem !important}.pb-5{padding-bottom:3rem !important}.ps-0{padding-left:0 !important}.ps-1{padding-left:.25rem !important}.ps-2{padding-left:.5rem !important}.ps-3{padding-left:1rem !important}.ps-4{padding-left:1.5rem !important}.ps-5{padding-left:3rem !important}@media (min-width: 576px){.d-sm-inline{display:inline !important}.d-sm-inline-block{display:inline-block !important}.d-sm-block{display:block !important}.d-sm-grid{display:grid !important}.d-sm-table{display:table !important}.d-sm-table-row{display:table-row !important}.d-sm-table-cell{display:table-cell !important}.d-sm-flex{display:flex !important}.d-sm-inline-flex{display:inline-flex !important}.d-sm-none{display:none !important}.flex-sm-fill{flex:1 1 auto !important}.flex-sm-row{flex-direction:row !important}.flex-sm-column{flex-direction:column !important}.flex-sm-row-reverse{flex-direction:row-reverse !important}.flex-sm-column-reverse{flex-direction:column-reverse !important}.flex-sm-grow-0{flex-grow:0 !important}.flex-sm-grow-1{flex-grow:1 !important}.flex-sm-shrink-0{flex-shrink:0 !important}.flex-sm-shrink-1{flex-shrink:1 !important}.flex-sm-wrap{flex-wrap:wrap !important}.flex-sm-nowrap{flex-wrap:nowrap !important}.flex-sm-wrap-reverse{flex-wrap:wrap-reverse !important}.justify-content-sm-start{justify-content:flex-start !important}.justify-content-sm-end{justify-content:flex-end !important}.justify-content-sm-center{justify-content:center !important}.justify-content-sm-between{justify-content:space-between !important}.justify-content-sm-around{justify-content:space-around !important}.justify-content-sm-evenly{justify-content:space-evenly !important}.align-items-sm-start{align-items:flex-start !important}.align-items-sm-end{align-items:flex-end !important}.align-items-sm-center{align-items:center !important}.align-items-sm-baseline{align-items:baseline !important}.align-items-sm-stretch{align-items:stretch !important}.align-content-sm-start{align-content:flex-start !important}.align-content-sm-end{align-content:flex-end !important}.align-content-sm-center{align-content:center !important}.align-content-sm-between{align-content:space-between !important}.align-content-sm-around{align-content:space-around !important}.align-content-sm-stretch{align-content:stretch !important}.align-self-sm-auto{align-self:auto !important}.align-self-sm-start{align-self:flex-start !important}.align-self-sm-end{align-self:flex-end !important}.align-self-sm-center{align-self:center !important}.align-self-sm-baseline{align-self:baseline !important}.align-self-sm-stretch{align-self:stretch !important}.order-sm-first{order:-1 !important}.order-sm-0{order:0 !important}.order-sm-1{order:1 !important}.order-sm-2{order:2 !important}.order-sm-3{order:3 !important}.order-sm-4{order:4 !important}.order-sm-5{order:5 !important}.order-sm-last{order:6 !important}.m-sm-0{margin:0 !important}.m-sm-1{margin:.25rem !important}.m-sm-2{margin:.5rem !important}.m-sm-3{margin:1rem !important}.m-sm-4{margin:1.5rem !important}.m-sm-5{margin:3rem !important}.m-sm-auto{margin:auto !important}.mx-sm-0{margin-right:0 !important;margin-left:0 !important}.mx-sm-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-sm-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-sm-3{margin-right:1rem !important;margin-left:1rem !important}.mx-sm-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-sm-5{margin-right:3rem !important;margin-left:3rem !important}.mx-sm-auto{margin-right:auto !important;margin-left:auto !important}.my-sm-0{margin-top:0 !important;margin-bottom:0 !important}.my-sm-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-sm-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-sm-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-sm-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-sm-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-sm-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-sm-0{margin-top:0 !important}.mt-sm-1{margin-top:.25rem !important}.mt-sm-2{margin-top:.5rem !important}.mt-sm-3{margin-top:1rem !important}.mt-sm-4{margin-top:1.5rem !important}.mt-sm-5{margin-top:3rem !important}.mt-sm-auto{margin-top:auto !important}.me-sm-0{margin-right:0 !important}.me-sm-1{margin-right:.25rem !important}.me-sm-2{margin-right:.5rem !important}.me-sm-3{margin-right:1rem !important}.me-sm-4{margin-right:1.5rem !important}.me-sm-5{margin-right:3rem !important}.me-sm-auto{margin-right:auto !important}.mb-sm-0{margin-bottom:0 !important}.mb-sm-1{margin-bottom:.25rem !important}.mb-sm-2{margin-bottom:.5rem !important}.mb-sm-3{margin-bottom:1rem !important}.mb-sm-4{margin-bottom:1.5rem !important}.mb-sm-5{margin-bottom:3rem !important}.mb-sm-auto{margin-bottom:auto !important}.ms-sm-0{margin-left:0 !important}.ms-sm-1{margin-left:.25rem !important}.ms-sm-2{margin-left:.5rem !important}.ms-sm-3{margin-left:1rem !important}.ms-sm-4{margin-left:1.5rem !important}.ms-sm-5{margin-left:3rem !important}.ms-sm-auto{margin-left:auto !important}.p-sm-0{padding:0 !important}.p-sm-1{padding:.25rem !important}.p-sm-2{padding:.5rem !important}.p-sm-3{padding:1rem !important}.p-sm-4{padding:1.5rem !important}.p-sm-5{padding:3rem !important}.px-sm-0{padding-right:0 !important;padding-left:0 !important}.px-sm-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-sm-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-sm-3{padding-right:1rem !important;padding-left:1rem !important}.px-sm-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-sm-5{padding-right:3rem !important;padding-left:3rem !important}.py-sm-0{padding-top:0 !important;padding-bottom:0 !important}.py-sm-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-sm-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-sm-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-sm-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-sm-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-sm-0{padding-top:0 !important}.pt-sm-1{padding-top:.25rem !important}.pt-sm-2{padding-top:.5rem !important}.pt-sm-3{padding-top:1rem !important}.pt-sm-4{padding-top:1.5rem !important}.pt-sm-5{padding-top:3rem !important}.pe-sm-0{padding-right:0 !important}.pe-sm-1{padding-right:.25rem !important}.pe-sm-2{padding-right:.5rem !important}.pe-sm-3{padding-right:1rem !important}.pe-sm-4{padding-right:1.5rem !important}.pe-sm-5{padding-right:3rem !important}.pb-sm-0{padding-bottom:0 !important}.pb-sm-1{padding-bottom:.25rem !important}.pb-sm-2{padding-bottom:.5rem !important}.pb-sm-3{padding-bottom:1rem !important}.pb-sm-4{padding-bottom:1.5rem !important}.pb-sm-5{padding-bottom:3rem !important}.ps-sm-0{padding-left:0 !important}.ps-sm-1{padding-left:.25rem !important}.ps-sm-2{padding-left:.5rem !important}.ps-sm-3{padding-left:1rem !important}.ps-sm-4{padding-left:1.5rem !important}.ps-sm-5{padding-left:3rem !important}}@media (min-width: 768px){.d-md-inline{display:inline !important}.d-md-inline-block{display:inline-block !important}.d-md-block{display:block !important}.d-md-grid{display:grid !important}.d-md-table{display:table !important}.d-md-table-row{display:table-row !important}.d-md-table-cell{display:table-cell !important}.d-md-flex{display:flex !important}.d-md-inline-flex{display:inline-flex !important}.d-md-none{display:none !important}.flex-md-fill{flex:1 1 auto !important}.flex-md-row{flex-direction:row !important}.flex-md-column{flex-direction:column !important}.flex-md-row-reverse{flex-direction:row-reverse !important}.flex-md-column-reverse{flex-direction:column-reverse !important}.flex-md-grow-0{flex-grow:0 !important}.flex-md-grow-1{flex-grow:1 !important}.flex-md-shrink-0{flex-shrink:0 !important}.flex-md-shrink-1{flex-shrink:1 !important}.flex-md-wrap{flex-wrap:wrap !important}.flex-md-nowrap{flex-wrap:nowrap !important}.flex-md-wrap-reverse{flex-wrap:wrap-reverse !important}.justify-content-md-start{justify-content:flex-start !important}.justify-content-md-end{justify-content:flex-end !important}.justify-content-md-center{justify-content:center !important}.justify-content-md-between{justify-content:space-between !important}.justify-content-md-around{justify-content:space-around !important}.justify-content-md-evenly{justify-content:space-evenly !important}.align-items-md-start{align-items:flex-start !important}.align-items-md-end{align-items:flex-end !important}.align-items-md-center{align-items:center !important}.align-items-md-baseline{align-items:baseline !important}.align-items-md-stretch{align-items:stretch !important}.align-content-md-start{align-content:flex-start !important}.align-content-md-end{align-content:flex-end !important}.align-content-md-center{align-content:center !important}.align-content-md-between{align-content:space-between !important}.align-content-md-around{align-content:space-around !important}.align-content-md-stretch{align-content:stretch !important}.align-self-md-auto{align-self:auto !important}.align-self-md-start{align-self:flex-start !important}.align-self-md-end{align-self:flex-end !important}.align-self-md-center{align-self:center !important}.align-self-md-baseline{align-self:baseline !important}.align-self-md-stretch{align-self:stretch !important}.order-md-first{order:-1 !important}.order-md-0{order:0 !important}.order-md-1{order:1 !important}.order-md-2{order:2 !important}.order-md-3{order:3 !important}.order-md-4{order:4 !important}.order-md-5{order:5 !important}.order-md-last{order:6 !important}.m-md-0{margin:0 !important}.m-md-1{margin:.25rem !important}.m-md-2{margin:.5rem !important}.m-md-3{margin:1rem !important}.m-md-4{margin:1.5rem !important}.m-md-5{margin:3rem !important}.m-md-auto{margin:auto !important}.mx-md-0{margin-right:0 !important;margin-left:0 !important}.mx-md-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-md-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-md-3{margin-right:1rem !important;margin-left:1rem !important}.mx-md-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-md-5{margin-right:3rem !important;margin-left:3rem !important}.mx-md-auto{margin-right:auto !important;margin-left:auto !important}.my-md-0{margin-top:0 !important;margin-bottom:0 !important}.my-md-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-md-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-md-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-md-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-md-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-md-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-md-0{margin-top:0 !important}.mt-md-1{margin-top:.25rem !important}.mt-md-2{margin-top:.5rem !important}.mt-md-3{margin-top:1rem !important}.mt-md-4{margin-top:1.5rem !important}.mt-md-5{margin-top:3rem !important}.mt-md-auto{margin-top:auto !important}.me-md-0{margin-right:0 !important}.me-md-1{margin-right:.25rem !important}.me-md-2{margin-right:.5rem !important}.me-md-3{margin-right:1rem !important}.me-md-4{margin-right:1.5rem !important}.me-md-5{margin-right:3rem !important}.me-md-auto{margin-right:auto !important}.mb-md-0{margin-bottom:0 !important}.mb-md-1{margin-bottom:.25rem !important}.mb-md-2{margin-bottom:.5rem !important}.mb-md-3{margin-bottom:1rem !important}.mb-md-4{margin-bottom:1.5rem !important}.mb-md-5{margin-bottom:3rem !important}.mb-md-auto{margin-bottom:auto !important}.ms-md-0{margin-left:0 !important}.ms-md-1{margin-left:.25rem !important}.ms-md-2{margin-left:.5rem !important}.ms-md-3{margin-left:1rem !important}.ms-md-4{margin-left:1.5rem !important}.ms-md-5{margin-left:3rem !important}.ms-md-auto{margin-left:auto !important}.p-md-0{padding:0 !important}.p-md-1{padding:.25rem !important}.p-md-2{padding:.5rem !important}.p-md-3{padding:1rem !important}.p-md-4{padding:1.5rem !important}.p-md-5{padding:3rem !important}.px-md-0{padding-right:0 !important;padding-left:0 !important}.px-md-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-md-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-md-3{padding-right:1rem !important;padding-left:1rem !important}.px-md-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-md-5{padding-right:3rem !important;padding-left:3rem !important}.py-md-0{padding-top:0 !important;padding-bottom:0 !important}.py-md-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-md-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-md-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-md-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-md-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-md-0{padding-top:0 !important}.pt-md-1{padding-top:.25rem !important}.pt-md-2{padding-top:.5rem !important}.pt-md-3{padding-top:1rem !important}.pt-md-4{padding-top:1.5rem !important}.pt-md-5{padding-top:3rem !important}.pe-md-0{padding-right:0 !important}.pe-md-1{padding-right:.25rem !important}.pe-md-2{padding-right:.5rem !important}.pe-md-3{padding-right:1rem !important}.pe-md-4{padding-right:1.5rem !important}.pe-md-5{padding-right:3rem !important}.pb-md-0{padding-bottom:0 !important}.pb-md-1{padding-bottom:.25rem !important}.pb-md-2{padding-bottom:.5rem !important}.pb-md-3{padding-bottom:1rem !important}.pb-md-4{padding-bottom:1.5rem !important}.pb-md-5{padding-bottom:3rem !important}.ps-md-0{padding-left:0 !important}.ps-md-1{padding-left:.25rem !important}.ps-md-2{padding-left:.5rem !important}.ps-md-3{padding-left:1rem !important}.ps-md-4{padding-left:1.5rem !important}.ps-md-5{padding-left:3rem !important}}@media (min-width: 992px){.d-lg-inline{display:inline !important}.d-lg-inline-block{display:inline-block !important}.d-lg-block{display:block !important}.d-lg-grid{display:grid !important}.d-lg-table{display:table !important}.d-lg-table-row{display:table-row !important}.d-lg-table-cell{display:table-cell !important}.d-lg-flex{display:flex !important}.d-lg-inline-flex{display:inline-flex !important}.d-lg-none{display:none !important}.flex-lg-fill{flex:1 1 auto !important}.flex-lg-row{flex-direction:row !important}.flex-lg-column{flex-direction:column !important}.flex-lg-row-reverse{flex-direction:row-reverse !important}.flex-lg-column-reverse{flex-direction:column-reverse !important}.flex-lg-grow-0{flex-grow:0 !important}.flex-lg-grow-1{flex-grow:1 !important}.flex-lg-shrink-0{flex-shrink:0 !important}.flex-lg-shrink-1{flex-shrink:1 !important}.flex-lg-wrap{flex-wrap:wrap !important}.flex-lg-nowrap{flex-wrap:nowrap !important}.flex-lg-wrap-reverse{flex-wrap:wrap-reverse !important}.justify-content-lg-start{justify-content:flex-start !important}.justify-content-lg-end{justify-content:flex-end !important}.justify-content-lg-center{justify-content:center !important}.justify-content-lg-between{justify-content:space-between !important}.justify-content-lg-around{justify-content:space-around !important}.justify-content-lg-evenly{justify-content:space-evenly !important}.align-items-lg-start{align-items:flex-start !important}.align-items-lg-end{align-items:flex-end !important}.align-items-lg-center{align-items:center !important}.align-items-lg-baseline{align-items:baseline !important}.align-items-lg-stretch{align-items:stretch !important}.align-content-lg-start{align-content:flex-start !important}.align-content-lg-end{align-content:flex-end !important}.align-content-lg-center{align-content:center !important}.align-content-lg-between{align-content:space-between !important}.align-content-lg-around{align-content:space-around !important}.align-content-lg-stretch{align-content:stretch !important}.align-self-lg-auto{align-self:auto !important}.align-self-lg-start{align-self:flex-start !important}.align-self-lg-end{align-self:flex-end !important}.align-self-lg-center{align-self:center !important}.align-self-lg-baseline{align-self:baseline !important}.align-self-lg-stretch{align-self:stretch !important}.order-lg-first{order:-1 !important}.order-lg-0{order:0 !important}.order-lg-1{order:1 !important}.order-lg-2{order:2 !important}.order-lg-3{order:3 !important}.order-lg-4{order:4 !important}.order-lg-5{order:5 !important}.order-lg-last{order:6 !important}.m-lg-0{margin:0 !important}.m-lg-1{margin:.25rem !important}.m-lg-2{margin:.5rem !important}.m-lg-3{margin:1rem !important}.m-lg-4{margin:1.5rem !important}.m-lg-5{margin:3rem !important}.m-lg-auto{margin:auto !important}.mx-lg-0{margin-right:0 !important;margin-left:0 !important}.mx-lg-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-lg-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-lg-3{margin-right:1rem !important;margin-left:1rem !important}.mx-lg-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-lg-5{margin-right:3rem !important;margin-left:3rem !important}.mx-lg-auto{margin-right:auto !important;margin-left:auto !important}.my-lg-0{margin-top:0 !important;margin-bottom:0 !important}.my-lg-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-lg-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-lg-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-lg-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-lg-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-lg-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-lg-0{margin-top:0 !important}.mt-lg-1{margin-top:.25rem !important}.mt-lg-2{margin-top:.5rem !important}.mt-lg-3{margin-top:1rem !important}.mt-lg-4{margin-top:1.5rem !important}.mt-lg-5{margin-top:3rem !important}.mt-lg-auto{margin-top:auto !important}.me-lg-0{margin-right:0 !important}.me-lg-1{margin-right:.25rem !important}.me-lg-2{margin-right:.5rem !important}.me-lg-3{margin-right:1rem !important}.me-lg-4{margin-right:1.5rem !important}.me-lg-5{margin-right:3rem !important}.me-lg-auto{margin-right:auto !important}.mb-lg-0{margin-bottom:0 !important}.mb-lg-1{margin-bottom:.25rem !important}.mb-lg-2{margin-bottom:.5rem !important}.mb-lg-3{margin-bottom:1rem !important}.mb-lg-4{margin-bottom:1.5rem !important}.mb-lg-5{margin-bottom:3rem !important}.mb-lg-auto{margin-bottom:auto !important}.ms-lg-0{margin-left:0 !important}.ms-lg-1{margin-left:.25rem !important}.ms-lg-2{margin-left:.5rem !important}.ms-lg-3{margin-left:1rem !important}.ms-lg-4{margin-left:1.5rem !important}.ms-lg-5{margin-left:3rem !important}.ms-lg-auto{margin-left:auto !important}.p-lg-0{padding:0 !important}.p-lg-1{padding:.25rem !important}.p-lg-2{padding:.5rem !important}.p-lg-3{padding:1rem !important}.p-lg-4{padding:1.5rem !important}.p-lg-5{padding:3rem !important}.px-lg-0{padding-right:0 !important;padding-left:0 !important}.px-lg-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-lg-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-lg-3{padding-right:1rem !important;padding-left:1rem !important}.px-lg-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-lg-5{padding-right:3rem !important;padding-left:3rem !important}.py-lg-0{padding-top:0 !important;padding-bottom:0 !important}.py-lg-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-lg-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-lg-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-lg-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-lg-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-lg-0{padding-top:0 !important}.pt-lg-1{padding-top:.25rem !important}.pt-lg-2{padding-top:.5rem !important}.pt-lg-3{padding-top:1rem !important}.pt-lg-4{padding-top:1.5rem !important}.pt-lg-5{padding-top:3rem !important}.pe-lg-0{padding-right:0 !important}.pe-lg-1{padding-right:.25rem !important}.pe-lg-2{padding-right:.5rem !important}.pe-lg-3{padding-right:1rem !important}.pe-lg-4{padding-right:1.5rem !important}.pe-lg-5{padding-right:3rem !important}.pb-lg-0{padding-bottom:0 !important}.pb-lg-1{padding-bottom:.25rem !important}.pb-lg-2{padding-bottom:.5rem !important}.pb-lg-3{padding-bottom:1rem !important}.pb-lg-4{padding-bottom:1.5rem !important}.pb-lg-5{padding-bottom:3rem !important}.ps-lg-0{padding-left:0 !important}.ps-lg-1{padding-left:.25rem !important}.ps-lg-2{padding-left:.5rem !important}.ps-lg-3{padding-left:1rem !important}.ps-lg-4{padding-left:1.5rem !important}.ps-lg-5{padding-left:3rem !important}}@media (min-width: 1200px){.d-xl-inline{display:inline !important}.d-xl-inline-block{display:inline-block !important}.d-xl-block{display:block !important}.d-xl-grid{display:grid !important}.d-xl-table{display:table !important}.d-xl-table-row{display:table-row !important}.d-xl-table-cell{display:table-cell !important}.d-xl-flex{display:flex !important}.d-xl-inline-flex{display:inline-flex !important}.d-xl-none{display:none !important}.flex-xl-fill{flex:1 1 auto !important}.flex-xl-row{flex-direction:row !important}.flex-xl-column{flex-direction:column !important}.flex-xl-row-reverse{flex-direction:row-reverse !important}.flex-xl-column-reverse{flex-direction:column-reverse !important}.flex-xl-grow-0{flex-grow:0 !important}.flex-xl-grow-1{flex-grow:1 !important}.flex-xl-shrink-0{flex-shrink:0 !important}.flex-xl-shrink-1{flex-shrink:1 !important}.flex-xl-wrap{flex-wrap:wrap !important}.flex-xl-nowrap{flex-wrap:nowrap !important}.flex-xl-wrap-reverse{flex-wrap:wrap-reverse !important}.justify-content-xl-start{justify-content:flex-start !important}.justify-content-xl-end{justify-content:flex-end !important}.justify-content-xl-center{justify-content:center !important}.justify-content-xl-between{justify-content:space-between !important}.justify-content-xl-around{justify-content:space-around !important}.justify-content-xl-evenly{justify-content:space-evenly !important}.align-items-xl-start{align-items:flex-start !important}.align-items-xl-end{align-items:flex-end !important}.align-items-xl-center{align-items:center !important}.align-items-xl-baseline{align-items:baseline !important}.align-items-xl-stretch{align-items:stretch !important}.align-content-xl-start{align-content:flex-start !important}.align-content-xl-end{align-content:flex-end !important}.align-content-xl-center{align-content:center !important}.align-content-xl-between{align-content:space-between !important}.align-content-xl-around{align-content:space-around !important}.align-content-xl-stretch{align-content:stretch !important}.align-self-xl-auto{align-self:auto !important}.align-self-xl-start{align-self:flex-start !important}.align-self-xl-end{align-self:flex-end !important}.align-self-xl-center{align-self:center !important}.align-self-xl-baseline{align-self:baseline !important}.align-self-xl-stretch{align-self:stretch !important}.order-xl-first{order:-1 !important}.order-xl-0{order:0 !important}.order-xl-1{order:1 !important}.order-xl-2{order:2 !important}.order-xl-3{order:3 !important}.order-xl-4{order:4 !important}.order-xl-5{order:5 !important}.order-xl-last{order:6 !important}.m-xl-0{margin:0 !important}.m-xl-1{margin:.25rem !important}.m-xl-2{margin:.5rem !important}.m-xl-3{margin:1rem !important}.m-xl-4{margin:1.5rem !important}.m-xl-5{margin:3rem !important}.m-xl-auto{margin:auto !important}.mx-xl-0{margin-right:0 !important;margin-left:0 !important}.mx-xl-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-xl-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-xl-3{margin-right:1rem !important;margin-left:1rem !important}.mx-xl-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-xl-5{margin-right:3rem !important;margin-left:3rem !important}.mx-xl-auto{margin-right:auto !important;margin-left:auto !important}.my-xl-0{margin-top:0 !important;margin-bottom:0 !important}.my-xl-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-xl-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-xl-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-xl-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-xl-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-xl-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-xl-0{margin-top:0 !important}.mt-xl-1{margin-top:.25rem !important}.mt-xl-2{margin-top:.5rem !important}.mt-xl-3{margin-top:1rem !important}.mt-xl-4{margin-top:1.5rem !important}.mt-xl-5{margin-top:3rem !important}.mt-xl-auto{margin-top:auto !important}.me-xl-0{margin-right:0 !important}.me-xl-1{margin-right:.25rem !important}.me-xl-2{margin-right:.5rem !important}.me-xl-3{margin-right:1rem !important}.me-xl-4{margin-right:1.5rem !important}.me-xl-5{margin-right:3rem !important}.me-xl-auto{margin-right:auto !important}.mb-xl-0{margin-bottom:0 !important}.mb-xl-1{margin-bottom:.25rem !important}.mb-xl-2{margin-bottom:.5rem !important}.mb-xl-3{margin-bottom:1rem !important}.mb-xl-4{margin-bottom:1.5rem !important}.mb-xl-5{margin-bottom:3rem !important}.mb-xl-auto{margin-bottom:auto !important}.ms-xl-0{margin-left:0 !important}.ms-xl-1{margin-left:.25rem !important}.ms-xl-2{margin-left:.5rem !important}.ms-xl-3{margin-left:1rem !important}.ms-xl-4{margin-left:1.5rem !important}.ms-xl-5{margin-left:3rem !important}.ms-xl-auto{margin-left:auto !important}.p-xl-0{padding:0 !important}.p-xl-1{padding:.25rem !important}.p-xl-2{padding:.5rem !important}.p-xl-3{padding:1rem !important}.p-xl-4{padding:1.5rem !important}.p-xl-5{padding:3rem !important}.px-xl-0{padding-right:0 !important;padding-left:0 !important}.px-xl-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-xl-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-xl-3{padding-right:1rem !important;padding-left:1rem !important}.px-xl-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-xl-5{padding-right:3rem !important;padding-left:3rem !important}.py-xl-0{padding-top:0 !important;padding-bottom:0 !important}.py-xl-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-xl-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-xl-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-xl-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-xl-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-xl-0{padding-top:0 !important}.pt-xl-1{padding-top:.25rem !important}.pt-xl-2{padding-top:.5rem !important}.pt-xl-3{padding-top:1rem !important}.pt-xl-4{padding-top:1.5rem !important}.pt-xl-5{padding-top:3rem !important}.pe-xl-0{padding-right:0 !important}.pe-xl-1{padding-right:.25rem !important}.pe-xl-2{padding-right:.5rem !important}.pe-xl-3{padding-right:1rem !important}.pe-xl-4{padding-right:1.5rem !important}.pe-xl-5{padding-right:3rem !important}.pb-xl-0{padding-bottom:0 !important}.pb-xl-1{padding-bottom:.25rem !important}.pb-xl-2{padding-bottom:.5rem !important}.pb-xl-3{padding-bottom:1rem !important}.pb-xl-4{padding-bottom:1.5rem !important}.pb-xl-5{padding-bottom:3rem !important}.ps-xl-0{padding-left:0 !important}.ps-xl-1{padding-left:.25rem !important}.ps-xl-2{padding-left:.5rem !important}.ps-xl-3{padding-left:1rem !important}.ps-xl-4{padding-left:1.5rem !important}.ps-xl-5{padding-left:3rem !important}}@media (min-width: 1400px){.d-xxl-inline{display:inline !important}.d-xxl-inline-block{display:inline-block !important}.d-xxl-block{display:block !important}.d-xxl-grid{display:grid !important}.d-xxl-table{display:table !important}.d-xxl-table-row{display:table-row !important}.d-xxl-table-cell{display:table-cell !important}.d-xxl-flex{display:flex !important}.d-xxl-inline-flex{display:inline-flex !important}.d-xxl-none{display:none !important}.flex-xxl-fill{flex:1 1 auto !important}.flex-xxl-row{flex-direction:row !important}.flex-xxl-column{flex-direction:column !important}.flex-xxl-row-reverse{flex-direction:row-reverse !important}.flex-xxl-column-reverse{flex-direction:column-reverse !important}.flex-xxl-grow-0{flex-grow:0 !important}.flex-xxl-grow-1{flex-grow:1 !important}.flex-xxl-shrink-0{flex-shrink:0 !important}.flex-xxl-shrink-1{flex-shrink:1 !important}.flex-xxl-wrap{flex-wrap:wrap !important}.flex-xxl-nowrap{flex-wrap:nowrap !important}.flex-xxl-wrap-reverse{flex-wrap:wrap-reverse !important}.justify-content-xxl-start{justify-content:flex-start !important}.justify-content-xxl-end{justify-content:flex-end !important}.justify-content-xxl-center{justify-content:center !important}.justify-content-xxl-between{justify-content:space-between !important}.justify-content-xxl-around{justify-content:space-around !important}.justify-content-xxl-evenly{justify-content:space-evenly !important}.align-items-xxl-start{align-items:flex-start !important}.align-items-xxl-end{align-items:flex-end !important}.align-items-xxl-center{align-items:center !important}.align-items-xxl-baseline{align-items:baseline !important}.align-items-xxl-stretch{align-items:stretch !important}.align-content-xxl-start{align-content:flex-start !important}.align-content-xxl-end{align-content:flex-end !important}.align-content-xxl-center{align-content:center !important}.align-content-xxl-between{align-content:space-between !important}.align-content-xxl-around{align-content:space-around !important}.align-content-xxl-stretch{align-content:stretch !important}.align-self-xxl-auto{align-self:auto !important}.align-self-xxl-start{align-self:flex-start !important}.align-self-xxl-end{align-self:flex-end !important}.align-self-xxl-center{align-self:center !important}.align-self-xxl-baseline{align-self:baseline !important}.align-self-xxl-stretch{align-self:stretch !important}.order-xxl-first{order:-1 !important}.order-xxl-0{order:0 !important}.order-xxl-1{order:1 !important}.order-xxl-2{order:2 !important}.order-xxl-3{order:3 !important}.order-xxl-4{order:4 !important}.order-xxl-5{order:5 !important}.order-xxl-last{order:6 !important}.m-xxl-0{margin:0 !important}.m-xxl-1{margin:.25rem !important}.m-xxl-2{margin:.5rem !important}.m-xxl-3{margin:1rem !important}.m-xxl-4{margin:1.5rem !important}.m-xxl-5{margin:3rem !important}.m-xxl-auto{margin:auto !important}.mx-xxl-0{margin-right:0 !important;margin-left:0 !important}.mx-xxl-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-xxl-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-xxl-3{margin-right:1rem !important;margin-left:1rem !important}.mx-xxl-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-xxl-5{margin-right:3rem !important;margin-left:3rem !important}.mx-xxl-auto{margin-right:auto !important;margin-left:auto !important}.my-xxl-0{margin-top:0 !important;margin-bottom:0 !important}.my-xxl-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-xxl-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-xxl-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-xxl-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-xxl-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-xxl-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-xxl-0{margin-top:0 !important}.mt-xxl-1{margin-top:.25rem !important}.mt-xxl-2{margin-top:.5rem !important}.mt-xxl-3{margin-top:1rem !important}.mt-xxl-4{margin-top:1.5rem !important}.mt-xxl-5{margin-top:3rem !important}.mt-xxl-auto{margin-top:auto !important}.me-xxl-0{margin-right:0 !important}.me-xxl-1{margin-right:.25rem !important}.me-xxl-2{margin-right:.5rem !important}.me-xxl-3{margin-right:1rem !important}.me-xxl-4{margin-right:1.5rem !important}.me-xxl-5{margin-right:3rem !important}.me-xxl-auto{margin-right:auto !important}.mb-xxl-0{margin-bottom:0 !important}.mb-xxl-1{margin-bottom:.25rem !important}.mb-xxl-2{margin-bottom:.5rem !important}.mb-xxl-3{margin-bottom:1rem !important}.mb-xxl-4{margin-bottom:1.5rem !important}.mb-xxl-5{margin-bottom:3rem !important}.mb-xxl-auto{margin-bottom:auto !important}.ms-xxl-0{margin-left:0 !important}.ms-xxl-1{margin-left:.25rem !important}.ms-xxl-2{margin-left:.5rem !important}.ms-xxl-3{margin-left:1rem !important}.ms-xxl-4{margin-left:1.5rem !important}.ms-xxl-5{margin-left:3rem !important}.ms-xxl-auto{margin-left:auto !important}.p-xxl-0{padding:0 !important}.p-xxl-1{padding:.25rem !important}.p-xxl-2{padding:.5rem !important}.p-xxl-3{padding:1rem !important}.p-xxl-4{padding:1.5rem !important}.p-xxl-5{padding:3rem !important}.px-xxl-0{padding-right:0 !important;padding-left:0 !important}.px-xxl-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-xxl-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-xxl-3{padding-right:1rem !important;padding-left:1rem !important}.px-xxl-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-xxl-5{padding-right:3rem !important;padding-left:3rem !important}.py-xxl-0{padding-top:0 !important;padding-bottom:0 !important}.py-xxl-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-xxl-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-xxl-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-xxl-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-xxl-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-xxl-0{padding-top:0 !important}.pt-xxl-1{padding-top:.25rem !important}.pt-xxl-2{padding-top:.5rem !important}.pt-xxl-3{padding-top:1rem !important}.pt-xxl-4{padding-top:1.5rem !important}.pt-xxl-5{padding-top:3rem !important}.pe-xxl-0{padding-right:0 !important}.pe-xxl-1{padding-right:.25rem !important}.pe-xxl-2{padding-right:.5rem !important}.pe-xxl-3{padding-right:1rem !important}.pe-xxl-4{padding-right:1.5rem !important}.pe-xxl-5{padding-right:3rem !important}.pb-xxl-0{padding-bottom:0 !important}.pb-xxl-1{padding-bottom:.25rem !important}.pb-xxl-2{padding-bottom:.5rem !important}.pb-xxl-3{padding-bottom:1rem !important}.pb-xxl-4{padding-bottom:1.5rem !important}.pb-xxl-5{padding-bottom:3rem !important}.ps-xxl-0{padding-left:0 !important}.ps-xxl-1{padding-left:.25rem !important}.ps-xxl-2{padding-left:.5rem !important}.ps-xxl-3{padding-left:1rem !important}.ps-xxl-4{padding-left:1.5rem !important}.ps-xxl-5{padding-left:3rem !important}}@media print{.d-print-inline{display:inline !important}.d-print-inline-block{display:inline-block !important}.d-print-block{display:block !important}.d-print-grid{display:grid !important}.d-print-table{display:table !important}.d-print-table-row{display:table-row !important}.d-print-table-cell{display:table-cell !important}.d-print-flex{display:flex !important}.d-print-inline-flex{display:inline-flex !important}.d-print-none{display:none !important}}.row{--bs-gutter-x: 1.875rem}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:#fff;border:1px solid #dee2e6;border-radius:.25rem;max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:.875em;color:#6c757d}.list-group{display:flex;flex-direction:column;padding-left:0;margin-bottom:0;border-radius:0}.list-group-numbered{list-style-type:none;counter-reset:section}.list-group-numbered>li::before{content:counters(section, ".") ". ";counter-increment:section}.list-group-item-action{width:100%;color:var(--t42-content-color);text-align:inherit}.list-group-item-action:hover,.list-group-item-action:focus{z-index:1;color:var(--t42-link-hover-color);text-decoration:none;background-color:var(--t42-link-hover-bg)}.list-group-item-action:active{color:var(--t42-link-hover-color);background-color:var(--t42-link-active-bg)}.list-group-item{position:relative;display:block;padding:.75rem 1.25rem;color:inherit;text-decoration:none;background-color:Rgb(var(--t42-bg-mid));border:1px solid rgba(0,0,0,0)}.list-group-item:first-child{border-top-left-radius:inherit;border-top-right-radius:inherit}.list-group-item:last-child{border-bottom-right-radius:inherit;border-bottom-left-radius:inherit}.list-group-item.disabled,.list-group-item:disabled{color:var(--t42-content-color-disabled);pointer-events:none;background-color:rgba(0,0,0,0)}.list-group-item.active{z-index:2;color:var(--t42-link-hover-color);background-color:var(--t42-link-active-bg);border-color:rgba(0,0,0,0)}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{margin-top:-1px;border-top-width:1px}.list-group-horizontal{flex-direction:row}.list-group-horizontal>.list-group-item:first-child{border-bottom-left-radius:0;border-top-right-radius:0}.list-group-horizontal>.list-group-item:last-child{border-top-right-radius:0;border-bottom-left-radius:0}.list-group-horizontal>.list-group-item.active{margin-top:0}.list-group-horizontal>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}@media (min-width: 576px){.list-group-horizontal-sm{flex-direction:row}.list-group-horizontal-sm>.list-group-item:first-child{border-bottom-left-radius:0;border-top-right-radius:0}.list-group-horizontal-sm>.list-group-item:last-child{border-top-right-radius:0;border-bottom-left-radius:0}.list-group-horizontal-sm>.list-group-item.active{margin-top:0}.list-group-horizontal-sm>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-sm>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width: 768px){.list-group-horizontal-md{flex-direction:row}.list-group-horizontal-md>.list-group-item:first-child{border-bottom-left-radius:0;border-top-right-radius:0}.list-group-horizontal-md>.list-group-item:last-child{border-top-right-radius:0;border-bottom-left-radius:0}.list-group-horizontal-md>.list-group-item.active{margin-top:0}.list-group-horizontal-md>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-md>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width: 992px){.list-group-horizontal-lg{flex-direction:row}.list-group-horizontal-lg>.list-group-item:first-child{border-bottom-left-radius:0;border-top-right-radius:0}.list-group-horizontal-lg>.list-group-item:last-child{border-top-right-radius:0;border-bottom-left-radius:0}.list-group-horizontal-lg>.list-group-item.active{margin-top:0}.list-group-horizontal-lg>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-lg>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width: 1200px){.list-group-horizontal-xl{flex-direction:row}.list-group-horizontal-xl>.list-group-item:first-child{border-bottom-left-radius:0;border-top-right-radius:0}.list-group-horizontal-xl>.list-group-item:last-child{border-top-right-radius:0;border-bottom-left-radius:0}.list-group-horizontal-xl>.list-group-item.active{margin-top:0}.list-group-horizontal-xl>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-xl>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width: 1400px){.list-group-horizontal-xxl{flex-direction:row}.list-group-horizontal-xxl>.list-group-item:first-child{border-bottom-left-radius:0;border-top-right-radius:0}.list-group-horizontal-xxl>.list-group-item:last-child{border-top-right-radius:0;border-bottom-left-radius:0}.list-group-horizontal-xxl>.list-group-item.active{margin-top:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}.list-group-flush{border-radius:0}.list-group-flush>.list-group-item{border-width:0 0 1px}.list-group-flush>.list-group-item:last-child{border-bottom-width:0}.list-group-item-primary{color:#004a89;background-color:#cce5fa}.list-group-item-primary.list-group-item-action:hover,.list-group-item-primary.list-group-item-action:focus{color:#004a89;background-color:#b8cee1}.list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#004a89;border-color:#004a89}.list-group-item-secondary{color:#3a3a3a;background-color:#dfdfdf}.list-group-item-secondary.list-group-item-action:hover,.list-group-item-secondary.list-group-item-action:focus{color:#3a3a3a;background-color:#c9c9c9}.list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#3a3a3a;border-color:#3a3a3a}.list-group-item-success{color:#28602b;background-color:#d9ecda}.list-group-item-success.list-group-item-action:hover,.list-group-item-success.list-group-item-action:focus{color:#28602b;background-color:#c3d4c4}.list-group-item-success.list-group-item-action.active{color:#fff;background-color:#28602b;border-color:#28602b}.list-group-item-info{color:#2a5f6f;background-color:#daecf1}.list-group-item-info.list-group-item-action:hover,.list-group-item-info.list-group-item-action:focus{color:#2a5f6f;background-color:#c4d4d9}.list-group-item-info.list-group-item-action.active{color:#fff;background-color:#2a5f6f;border-color:#2a5f6f}.list-group-item-warning{color:#64430f;background-color:#feeed3}.list-group-item-warning.list-group-item-action:hover,.list-group-item-warning.list-group-item-action:focus{color:#64430f;background-color:#e5d6be}.list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#64430f;border-color:#64430f}.list-group-item-danger{color:#993113;background-color:#ffdcd2}.list-group-item-danger.list-group-item-action:hover,.list-group-item-danger.list-group-item-action:focus{color:#993113;background-color:#e6c6bd}.list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#993113;border-color:#993113}.list-group-item-light{color:#3a3a3a;background-color:#dfdfdf}.list-group-item-light.list-group-item-action:hover,.list-group-item-light.list-group-item-action:focus{color:#3a3a3a;background-color:#c9c9c9}.list-group-item-light.list-group-item-action.active{color:#fff;background-color:#3a3a3a;border-color:#3a3a3a}.list-group-item-dark{color:#3a3a3a;background-color:#dfdfdf}.list-group-item-dark.list-group-item-action:hover,.list-group-item-dark.list-group-item-action:focus{color:#3a3a3a;background-color:#c9c9c9}.list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#3a3a3a;border-color:#3a3a3a}.list-unstyled{padding-left:0;list-style:none}.list-group{box-shadow:var(--t42-shadow)}.list-group-item{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:color;margin-bottom:0;border:0;border-bottom:var(--t42-border);backdrop-filter:var(--backdrop-filter)}.list-group-item:last-child{border-bottom:transparent}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{margin-top:0;border-top-width:0}.list-group-item-action{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background,color;transition-duration:0.25s}.list-group-item-action:hover,.list-group-item-action:focus{background-color:var(--t42-list-group-hover-bg-special)}.list-group-item-action.active:hover{background-color:var(--t42-color-opacity-05)}.modal{position:fixed;top:0;left:0;z-index:1055;display:none;width:100%;height:100%;overflow-x:hidden;overflow-y:auto;outline:0}.modal-dialog{position:relative;width:auto;margin:.5rem;pointer-events:none}.modal.fade .modal-dialog{transition:transform 0.3s ease-out;transform:translate(0, -50px)}@media (prefers-reduced-motion: reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{transform:none}.modal.modal-static .modal-dialog{transform:scale(1.02)}.modal-dialog-scrollable{height:calc(100% - 1rem)}.modal-dialog-scrollable .modal-content{max-height:100%;overflow:hidden}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{display:flex;align-items:center;min-height:calc(100% - 1rem)}.modal-content{position:relative;display:flex;flex-direction:column;width:100%;pointer-events:auto;background-color:var(--t42-modal-bg);background-clip:padding-box;border:.0625rem solid var(--t42-color-opacity-10);border-radius:0;outline:0}.modal-backdrop{position:fixed;top:0;left:0;z-index:1050;width:100vw;height:100vh;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:.5}.modal-header{display:flex;flex-shrink:0;align-items:center;justify-content:space-between;padding:1rem 1rem;border-bottom:.0625rem solid rgba(0,0,0,0);border-top-left-radius:0;border-top-right-radius:0}.modal-header .btn-close{padding:.5rem .5rem;margin:-.5rem -.5rem -.5rem auto}.modal-title{margin-bottom:0;line-height:1.5}.modal-body{position:relative;flex:1 1 auto;padding:1rem}.modal-footer{display:flex;flex-wrap:wrap;flex-shrink:0;align-items:center;justify-content:flex-end;padding:.75rem;border-top:.0625rem solid rgba(0,0,0,0);border-bottom-right-radius:0;border-bottom-left-radius:0}.modal-footer>*{margin:.25rem}@media (min-width: 576px){.modal-dialog{max-width:500px;margin:1.75rem auto}.modal-dialog-scrollable{height:calc(100% - 3.5rem)}.modal-dialog-centered{min-height:calc(100% - 3.5rem)}.modal-sm{max-width:300px}}@media (min-width: 992px){.modal-lg,.modal-xl{max-width:800px}}@media (min-width: 1200px){.modal-xl{max-width:1140px}}.modal-fullscreen{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen .modal-header{border-radius:0}.modal-fullscreen .modal-body{overflow-y:auto}.modal-fullscreen .modal-footer{border-radius:0}@media (max-width: 575.98px){.modal-fullscreen-sm-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-sm-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-sm-down .modal-header{border-radius:0}.modal-fullscreen-sm-down .modal-body{overflow-y:auto}.modal-fullscreen-sm-down .modal-footer{border-radius:0}}@media (max-width: 767.98px){.modal-fullscreen-md-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-md-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-md-down .modal-header{border-radius:0}.modal-fullscreen-md-down .modal-body{overflow-y:auto}.modal-fullscreen-md-down .modal-footer{border-radius:0}}@media (max-width: 991.98px){.modal-fullscreen-lg-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-lg-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-lg-down .modal-header{border-radius:0}.modal-fullscreen-lg-down .modal-body{overflow-y:auto}.modal-fullscreen-lg-down .modal-footer{border-radius:0}}@media (max-width: 1199.98px){.modal-fullscreen-xl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xl-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-xl-down .modal-header{border-radius:0}.modal-fullscreen-xl-down .modal-body{overflow-y:auto}.modal-fullscreen-xl-down .modal-footer{border-radius:0}}@media (max-width: 1399.98px){.modal-fullscreen-xxl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xxl-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-xxl-down .modal-header{border-radius:0}.modal-fullscreen-xxl-down .modal-body{overflow-y:auto}.modal-fullscreen-xxl-down .modal-footer{border-radius:0}}.modal{backdrop-filter:var(--backdrop-filter)}.modal .btn-close{font-size:1.25rem;background-size:0.75rem;filter:var(--filter-close)}.modal-content{border-top:0;background:linear-gradient(to bottom right, Rgba(var(--t42-bg-light), 0.75) 0%, Rgba(var(--t42-bg-dark), 0.75) 100%);box-shadow:var(--t42-shadow)}.modal-content::before{display:block;height:0.0625rem;background:linear-gradient(90deg, #007be5 0%, rgba(0,123,229,0.5) 100%);content:""}.modal-body{padding:0 1rem}.modal-body p:last-child{margin-bottom:0}.modal-sm .modal-footer{flex-direction:column}.modal-sm .modal-footer .btn{width:100%}.modal-sm .modal-footer .btn:not(:last-of-type){margin-bottom:0.5rem}.modal-fill-in{background-color:Rgba(var(--t42-bg-light), 0.75)}.modal-fill-in.modal-dialog{display:flex;flex-flow:column nowrap;align-content:center;align-items:center;justify-content:center;width:auto;max-width:100%;height:100%;margin:0 auto}.modal-fill-in .modal-content{display:flex;max-width:600px;border-color:transparent;background:transparent;background-color:transparent;box-shadow:none;backdrop-filter:none;pointer-events:auto}.modal-fill-in .modal-content::before{display:none}.modal-fill-in::before{position:fixed;top:0;right:0;left:0;display:block;height:0.0625rem;background:linear-gradient(90deg, #007be5 0%, rgba(0,123,229,0.5) 100%);content:""}.modal-fill-in.modal-lg .modal-content{max-width:800px}.modal-fill-in.modal-sm .modal-content{max-width:300px}.nav{display:flex;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:.45rem 1rem;color:var(--t42-link-color);text-decoration:none;transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.nav-link{transition:none}}.nav-link:hover,.nav-link:focus{color:var(--t42-link-hover-color)}.nav-link.disabled{color:var(--t42-content-color-disabled);pointer-events:none;cursor:default}.nav-tabs{border-bottom:.0625rem solid var(--t42-color-opacity-10)}.nav-tabs .nav-link{margin-bottom:-.0625rem;background:none;border:.0625rem solid transparent;border-top-left-radius:0;border-top-right-radius:0}.nav-tabs .nav-link:hover,.nav-tabs .nav-link:focus{border-color:transparent transparent var(--t42-color-opacity-10);isolation:isolate}.nav-tabs .nav-link.disabled{color:var(--t42-content-color-disabled);background-color:transparent;border-color:transparent}.nav-tabs .nav-link.active,.nav-tabs .nav-item.show .nav-link{color:var(--t42-link-hover-color);background-color:var(--t42-link-active-bg);border-color:transparent transparent #007be5}.nav-tabs .dropdown-menu{margin-top:-.0625rem;border-top-left-radius:0;border-top-right-radius:0}.nav-pills .nav-link{background:none;border:0;border-radius:.25rem}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:var(--t42-link-hover-color);background-color:var(--t42-link-active-bg)}.nav-fill>.nav-link,.nav-fill .nav-item{flex:1 1 auto;text-align:center}.nav-justified>.nav-link,.nav-justified .nav-item{flex-basis:0;flex-grow:1;text-align:center}.nav-fill .nav-item .nav-link,.nav-justified .nav-item .nav-link{width:100%}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-link{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, border-color, color;margin-right:3px;border:.0625rem solid transparent}.nav-link:not(.disabled):not(:disabled):focus,.nav-link:not(.disabled):not(:disabled):active,.nav-link:not(.disabled):not(:disabled).active,.nav-link:not(.disabled):not(:disabled):hover{border-color:var(--t42-color-opacity-10);color:var(--t42-link-color);background-color:var(--t42-link-hover-bg)}.nav-link.dropdown-toggle::after{right:-0.125rem}.navbar-nav .nav-item{bottom:-1px}.navbar-nav .nav-item .nav-link{border-bottom:0}.navbar-nav .nav-item:not(.disabled):not(:disabled):focus .nav-link,.navbar-nav .nav-item:not(.disabled):not(:disabled):active .nav-link,.navbar-nav .nav-item:not(.disabled):not(:disabled).active .nav-link,.navbar-nav .nav-item:not(.disabled):not(:disabled):hover .nav-link{border-color:var(--t42-color-opacity-10)}.nav.flex-column .nav-link{margin-bottom:3px}.nav-tabs .nav-link{position:relative;display:flex;align-items:center;height:2rem}.nav-tabs .nav-link::before{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:height;position:absolute;bottom:-2px;left:-1px;width:calc(100% + 2px);height:0;background-color:var(--primary);content:""}.nav-tabs .nav-link.active::before{height:3px}.nav-tabs .nav-link.active:hover::before{height:0}.nav-tabs .nav-link .btn-close{width:0.5rem;height:0.5rem}.nav-tabs .nav-item{margin-right:0}.nav-tabs .dropdown.show .dropdown-toggle{border-color:transparent}.nav-tabs.flex-column .nav-link.active:hover::before{width:0}.nav-tabs.flex-column .nav-link::before{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:width;top:-1px;width:0;height:100%;margin-left:0;background-color:var(--primary);content:""}.nav-tabs.flex-column .nav-link.active::before{width:3px;height:calc(100% + 2px)}.nav-pills .nav-link{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;width:100%;padding:0.25rem 1rem;border:1px solid transparent;border-radius:1rem}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{position:relative;border-color:transparent}.nav-pills .nav-item{margin-right:3px}.nav-pills .nav-item:last-child{margin-right:0}.nav-pills .nav-link.active:not(.dropdown-toggle),.nav-pills .show>.nav-link:not(.dropdown-toggle){padding:0.25rem 1.75rem 0.25rem 1rem}.nav-pills .nav-link.active:not(.dropdown-toggle)::before,.nav-pills .show>.nav-link:not(.dropdown-toggle)::before{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:right;position:absolute;top:50%;right:10px;width:8px;height:8px;border-radius:50%;background-color:var(--primary);transform:translateY(-50%);content:""}.nav-pills .nav-link.active:not(.dropdown-toggle):hover::before,.nav-pills .show>.nav-link:not(.dropdown-toggle):hover::before{right:-10px}.nav-justified .nav-item .nav-link::before{right:1px;left:-1px;margin-left:0}.tab-content{padding-top:0.5rem}.nav-action-buttons .nav-link{position:relative;padding:0.45rem 1.5rem 0.45rem 1rem}.nav-action-buttons .icon-cancel::before{display:block;width:1rem;height:1rem;background-color:var(--t42-content-color);content:"";-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M366.854,336.384c6.14398,6.14398,9.216,13.48267,9.216,22.01599s-3.07202,15.87198-9.216,22.01599 c-6.14398,5.46133-13.48267,8.19202-22.01599,8.19199c-8.53333,0.00003-15.87201-2.73065-22.01602-8.19199l-67.584-77.82401 l-67.584,77.82401c-6.144,5.46133-13.48267,8.19202-22.01601,8.19199c-8.53333,0.00003-15.87199-2.73065-22.01599-8.19199 c-5.46133-6.14401-8.192-13.48267-8.192-22.01599s2.73067-15.87201,8.192-22.01599l70.65599-79.87201l-70.65601-80.896 c-5.46132-6.144-8.19199-13.48268-8.19199-22.01601c0-8.53334,2.73067-15.87201,8.19199-22.01601 c6.14401-5.46133,13.48267-8.19199,22.01601-8.192c8.53334,0.00001,15.87201,2.73067,22.01601,8.192l67.584,77.82401 l67.584-77.82401c6.14401-5.46133,13.4827-8.19199,22.01602-8.192c8.53333,0.00001,15.87201,2.73067,22.01599,8.192 c6.14398,6.144,9.216,13.48267,9.216,22.01601c0,8.53333-3.07202,15.87201-9.216,22.01601l-70.65601,80.896L366.854,336.384z%27/%3E%3C/svg%3E")}.navbar{position:relative;display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;padding-top:0;padding-right:.875rem;padding-bottom:0;padding-left:.875rem}.navbar>.container,.navbar>.container-fluid,.navbar>.container-sm,.navbar>.container-md,.navbar>.container-lg,.navbar>.container-xl,.navbar>.container-xxl{display:flex;flex-wrap:inherit;align-items:center;justify-content:space-between}.navbar-brand{padding-top:.075rem;padding-bottom:.075rem;margin-right:1rem;font-size:1.25rem;text-decoration:none;white-space:nowrap}.navbar-nav{display:flex;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-nav .dropdown-menu{position:static}.navbar-text{padding-top:.45rem;padding-bottom:.45rem}.navbar-collapse{flex-basis:100%;flex-grow:1;align-items:center}.navbar-toggler{padding:0 0;font-size:.9375rem;line-height:1;background-color:transparent;border:1px solid transparent;border-radius:0;transition:box-shadow 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.navbar-toggler{transition:none}}.navbar-toggler:hover{text-decoration:none}.navbar-toggler:focus{text-decoration:none;outline:0;box-shadow:0 0 0 0}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;background-repeat:no-repeat;background-position:center;background-size:100%}.navbar-nav-scroll{max-height:var(--bs-scroll-height, 75vh);overflow-y:auto}@media (min-width: 576px){.navbar-expand-sm{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-sm .navbar-nav{flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm .navbar-nav-scroll{overflow:visible}.navbar-expand-sm .navbar-collapse{display:flex !important;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}.navbar-expand-sm .offcanvas-header{display:none}.navbar-expand-sm .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;visibility:visible !important;background-color:transparent;border-right:0;border-left:0;transition:none;transform:none}.navbar-expand-sm .offcanvas-top,.navbar-expand-sm .offcanvas-bottom{height:auto;border-top:0;border-bottom:0}.navbar-expand-sm .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width: 768px){.navbar-expand-md{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-md .navbar-nav{flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-md .navbar-nav-scroll{overflow:visible}.navbar-expand-md .navbar-collapse{display:flex !important;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}.navbar-expand-md .offcanvas-header{display:none}.navbar-expand-md .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;visibility:visible !important;background-color:transparent;border-right:0;border-left:0;transition:none;transform:none}.navbar-expand-md .offcanvas-top,.navbar-expand-md .offcanvas-bottom{height:auto;border-top:0;border-bottom:0}.navbar-expand-md .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width: 992px){.navbar-expand-lg{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-lg .navbar-nav{flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-lg .navbar-nav-scroll{overflow:visible}.navbar-expand-lg .navbar-collapse{display:flex !important;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}.navbar-expand-lg .offcanvas-header{display:none}.navbar-expand-lg .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;visibility:visible !important;background-color:transparent;border-right:0;border-left:0;transition:none;transform:none}.navbar-expand-lg .offcanvas-top,.navbar-expand-lg .offcanvas-bottom{height:auto;border-top:0;border-bottom:0}.navbar-expand-lg .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width: 1200px){.navbar-expand-xl{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-xl .navbar-nav{flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xl .navbar-nav-scroll{overflow:visible}.navbar-expand-xl .navbar-collapse{display:flex !important;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}.navbar-expand-xl .offcanvas-header{display:none}.navbar-expand-xl .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;visibility:visible !important;background-color:transparent;border-right:0;border-left:0;transition:none;transform:none}.navbar-expand-xl .offcanvas-top,.navbar-expand-xl .offcanvas-bottom{height:auto;border-top:0;border-bottom:0}.navbar-expand-xl .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width: 1400px){.navbar-expand-xxl{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-xxl .navbar-nav{flex-direction:row}.navbar-expand-xxl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xxl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xxl .navbar-nav-scroll{overflow:visible}.navbar-expand-xxl .navbar-collapse{display:flex !important;flex-basis:auto}.navbar-expand-xxl .navbar-toggler{display:none}.navbar-expand-xxl .offcanvas-header{display:none}.navbar-expand-xxl .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;visibility:visible !important;background-color:transparent;border-right:0;border-left:0;transition:none;transform:none}.navbar-expand-xxl .offcanvas-top,.navbar-expand-xxl .offcanvas-bottom{height:auto;border-top:0;border-bottom:0}.navbar-expand-xxl .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}.navbar-expand{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand .navbar-nav{flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand .navbar-nav-scroll{overflow:visible}.navbar-expand .navbar-collapse{display:flex !important;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-expand .offcanvas-header{display:none}.navbar-expand .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;visibility:visible !important;background-color:transparent;border-right:0;border-left:0;transition:none;transform:none}.navbar-expand .offcanvas-top,.navbar-expand .offcanvas-bottom{height:auto;border-top:0;border-bottom:0}.navbar-expand .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}.navbar-light .navbar-brand{color:var(--t42-link-color)}.navbar-light .navbar-brand:hover,.navbar-light .navbar-brand:focus{color:var(--t42-link-hover-color)}.navbar-light .navbar-nav .nav-link{color:var(--t42-link-color)}.navbar-light .navbar-nav .nav-link:hover,.navbar-light .navbar-nav .nav-link:focus{color:var(--t42-link-hover-color)}.navbar-light .navbar-nav .nav-link.disabled{color:var(--t42-content-color-disabled)}.navbar-light .navbar-nav .show>.nav-link,.navbar-light .navbar-nav .nav-link.active{color:var(--t42-link-hover-color)}.navbar-light .navbar-toggler{color:var(--t42-link-color);border-color:rgba(0,0,0,0.1)}.navbar-light .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 30 30%27%3e%3cpath stroke=%27var%28--t42-link-color%29%27 stroke-linecap=%27round%27 stroke-miterlimit=%2710%27 stroke-width=%272%27 d=%27M4 7h22M4 15h22M4 23h22%27/%3e%3c/svg%3e")}.navbar-light .navbar-text{color:var(--t42-link-color)}.navbar-light .navbar-text a,.navbar-light .navbar-text a:hover,.navbar-light .navbar-text a:focus{color:var(--t42-link-hover-color)}.navbar-dark .navbar-brand{color:var(--t42-link-color)}.navbar-dark .navbar-brand:hover,.navbar-dark .navbar-brand:focus{color:var(--t42-link-hover-color)}.navbar-dark .navbar-nav .nav-link{color:var(--t42-link-color)}.navbar-dark .navbar-nav .nav-link:hover,.navbar-dark .navbar-nav .nav-link:focus{color:var(--t42-link-hover-color)}.navbar-dark .navbar-nav .nav-link.disabled{color:var(--t42-content-color-disabled)}.navbar-dark .navbar-nav .show>.nav-link,.navbar-dark .navbar-nav .nav-link.active{color:var(--t42-link-hover-color)}.navbar-dark .navbar-toggler{color:var(--t42-link-color);border-color:rgba(255,255,255,0.1)}.navbar-dark .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 30 30%27%3e%3cpath stroke=%27var%28--t42-link-color%29%27 stroke-linecap=%27round%27 stroke-miterlimit=%2710%27 stroke-width=%272%27 d=%27M4 7h22M4 15h22M4 23h22%27/%3e%3c/svg%3e")}.navbar-dark .navbar-text{color:var(--t42-link-color)}.navbar-dark .navbar-text a,.navbar-dark .navbar-text a:hover,.navbar-dark .navbar-text a:focus{color:var(--t42-link-hover-color)}.navbar{border-bottom:var(--t42-border);background-color:Rgba(var(--t42-bg-mid), 0.75);backdrop-filter:var(--backdrop-filter)}.navbar-dark{background-color:Rgba(var(--t42-bg-dark), 0.75)}.navbar-light{background-color:Rgba(var(--t42-bg-light), 0.75)}.navbar .nav-item{position:relative}.navbar .nav-item.show:focus .nav-link:not(.disabled):not(:disabled),.navbar .nav-item.show:active .nav-link:not(.disabled):not(:disabled),.navbar .nav-item.show.active .nav-link:not(.disabled):not(:disabled),.navbar .nav-item:not(.disabled):not(:disabled):focus .nav-link:not(.disabled):not(:disabled),.navbar .nav-item:not(.disabled):not(:disabled):active .nav-link:not(.disabled):not(:disabled),.navbar .nav-item:not(.disabled):not(:disabled).active .nav-link:not(.disabled):not(:disabled){color:var(--t42-link-color);background-color:var(--t42-color-opacity-10)}.navbar .nav-item.show:hover .nav-link:not(.disabled):not(:disabled),.navbar .nav-item:not(.disabled):not(:disabled):hover .nav-link:not(.disabled):not(:disabled){color:var(--t42-link-color);background-color:var(--t42-color-opacity-05)}.navbar .nav-link{padding-right:.875rem;padding-left:.875rem}.navbar .btn-group{height:100%;padding-left:.875rem;border-left:var(--t42-border)}.pagination{display:flex;padding-left:0;list-style:none}.page-link{position:relative;display:block;color:var(--t42-content-color);text-decoration:none;background-color:rgba(0,0,0,0);border:0 solid rgba(0,0,0,0);transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.page-link{transition:none}}.page-link:hover{z-index:2;color:var(--t42-link-hover-color);background-color:var(--t42-link-hover-bg);border-color:#dee2e6}.page-link:focus{z-index:3;color:var(--t42-link-hover-color);background-color:rgba(0,0,0,0);outline:0;box-shadow:0 0 0 0 rgba(0,123,229,0.25)}.page-item:not(:first-child) .page-link{margin-left:0}.page-item.active .page-link{z-index:3;color:var(--white);background-color:var(--primary);border-color:var(--primary)}.page-item.disabled .page-link{color:var(--t42-content-color-disabled);pointer-events:none;background-color:rgba(0,0,0,0);border-color:#dee2e6}.page-link{padding:.125rem .5rem}.page-item:first-child .page-link{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.page-item:last-child .page-link{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.pagination-lg .page-link{padding:.75rem 1.5rem;font-size:.9375rem}.pagination-lg .page-item:first-child .page-link{border-top-left-radius:1rem;border-bottom-left-radius:1rem}.pagination-lg .page-item:last-child .page-link{border-top-right-radius:1rem;border-bottom-right-radius:1rem}.pagination-sm .page-link{padding:.25rem .5rem;font-size:.65625rem}.pagination-sm .page-item:first-child .page-link{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.pagination-sm .page-item:last-child .page-link{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.page-link{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, color;display:flex;align-items:center;justify-content:center;min-width:1.5rem;min-height:1.5rem;border-radius:0.25rem;overflow:hidden}.page-link[aria-label="Next"],.page-link[aria-label="Previous"]{padding:0}.page-link[aria-label="Next"] span{background:var(--t42-select-indicator) center center/1rem 1rem no-repeat;transform:rotate(-90deg)}.page-link[aria-label="Previous"] span{background:var(--t42-select-indicator) center center/1rem 1rem no-repeat;transform:rotate(90deg)}.page-link>span{width:100%;height:100%;min-height:1rem;font-size:0;clip:initial}.pagination-lg .page-link[aria-label="Next"],.pagination-lg .page-link[aria-label="Previous"]{padding:0.75rem 1.5rem}.page-item{margin-right:8px}.page-item:first-child .page-link>span:not(.sr-only)::before,.page-item:last-child .page-link>span:not(.sr-only)::before{top:-0.125rem}.page-item.active .page-link:hover,.page-item:active .page-link:hover{background-color:var(--t42-color-opacity-05)}.page-item.active.disabled .page-link{background-color:var(--t42-color-opacity-10)}.popover{position:absolute;top:0;left:0 /* rtl:ignore */;z-index:1070;display:block;max-width:276px;font-family:"Montserrat","Helvetica Neue",Arial,sans-serif;font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.65625rem;word-wrap:break-word;background-color:Rgba(var(--t42-bg-dark), 0.75);background-clip:padding-box;border:1px solid var(--t42-color-opacity-10);border-radius:0}.popover .popover-arrow{position:absolute;display:block;width:1rem;height:.5rem}.popover .popover-arrow::before,.popover .popover-arrow::after{position:absolute;display:block;content:"";border-color:transparent;border-style:solid}.bs-popover-top>.popover-arrow,.bs-popover-auto[data-popper-placement^="top"]>.popover-arrow{bottom:calc(-.5rem - 1px)}.bs-popover-top>.popover-arrow::before,.bs-popover-auto[data-popper-placement^="top"]>.popover-arrow::before{bottom:0;border-width:.5rem .5rem 0;border-top-color:var(--t42-color-opacity-10)}.bs-popover-top>.popover-arrow::after,.bs-popover-auto[data-popper-placement^="top"]>.popover-arrow::after{bottom:1px;border-width:.5rem .5rem 0;border-top-color:var(--t42-color-opacity-10)}.bs-popover-end>.popover-arrow,.bs-popover-auto[data-popper-placement^="right"]>.popover-arrow{left:calc(-.5rem - 1px);width:.5rem;height:1rem}.bs-popover-end>.popover-arrow::before,.bs-popover-auto[data-popper-placement^="right"]>.popover-arrow::before{left:0;border-width:.5rem .5rem .5rem 0;border-right-color:var(--t42-color-opacity-10)}.bs-popover-end>.popover-arrow::after,.bs-popover-auto[data-popper-placement^="right"]>.popover-arrow::after{left:1px;border-width:.5rem .5rem .5rem 0;border-right-color:var(--t42-color-opacity-10)}.bs-popover-bottom>.popover-arrow,.bs-popover-auto[data-popper-placement^="bottom"]>.popover-arrow{top:calc(-.5rem - 1px)}.bs-popover-bottom>.popover-arrow::before,.bs-popover-auto[data-popper-placement^="bottom"]>.popover-arrow::before{top:0;border-width:0 .5rem .5rem .5rem;border-bottom-color:var(--t42-color-opacity-10)}.bs-popover-bottom>.popover-arrow::after,.bs-popover-auto[data-popper-placement^="bottom"]>.popover-arrow::after{top:1px;border-width:0 .5rem .5rem .5rem;border-bottom-color:var(--t42-color-opacity-10)}.bs-popover-bottom .popover-header::before,.bs-popover-auto[data-popper-placement^="bottom"] .popover-header::before{position:absolute;top:0;left:50%;display:block;width:1rem;margin-left:-.5rem;content:"";border-bottom:1px solid Rgba(var(--t42-bg-mid), 0.75)}.bs-popover-start>.popover-arrow,.bs-popover-auto[data-popper-placement^="left"]>.popover-arrow{right:calc(-.5rem - 1px);width:.5rem;height:1rem}.bs-popover-start>.popover-arrow::before,.bs-popover-auto[data-popper-placement^="left"]>.popover-arrow::before{right:0;border-width:.5rem 0 .5rem .5rem;border-left-color:var(--t42-color-opacity-10)}.bs-popover-start>.popover-arrow::after,.bs-popover-auto[data-popper-placement^="left"]>.popover-arrow::after{right:1px;border-width:.5rem 0 .5rem .5rem;border-left-color:var(--t42-color-opacity-10)}.popover-header{padding:.55rem 1rem;margin-bottom:0;font-size:.75rem;color:var(--t42-link-color);background-color:Rgba(var(--t42-bg-mid), 0.75);border-bottom:1px solid var(--t42-color-opacity-10);border-top-left-radius:0;border-top-right-radius:0}.popover-header:empty{display:none}.popover-body{padding:1rem 1rem;color:var(--t42-content-color)}.popover{backdrop-filter:var(--backdrop-filter)}@keyframes progress-bar-stripes{0%{background-position-x:1.063rem}}.progress{display:flex;height:1.063rem;overflow:hidden;font-size:.6rem;background-color:Rgb(var(--t42-bg-mid));border-radius:0}.progress-bar{display:flex;flex-direction:column;justify-content:center;overflow:hidden;color:#fff;text-align:center;white-space:nowrap;background-color:#007be5;transition:width 0.6s ease}@media (prefers-reduced-motion: reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-size:1.063rem 1.063rem}.progress-bar-animated{animation:1s linear infinite progress-bar-stripes}@media (prefers-reduced-motion: reduce){.progress-bar-animated{animation:none}}.progress{border:var(--t42-border)}.table{--bs-table-bg: rgba(0,0,0,0);--bs-table-accent-bg: rgba(0,0,0,0);--bs-table-striped-color: var(--t42-content-color);--bs-table-striped-bg: rgba(0,0,0,0.05);--bs-table-active-color: var(--t42-content-color);--bs-table-active-bg: rgba(0,0,0,0.1);--bs-table-hover-color: var(--t42-link-color);--bs-table-hover-bg: rgba(0,0,0,0.075);width:100%;margin-bottom:1rem;color:var(--t42-content-color);vertical-align:top;border-color:var(--t42-color-opacity-10)}.table>:not(caption)>*>*{padding:.25rem .313rem;background-color:var(--bs-table-bg);border-bottom-width:1px;box-shadow:inset 0 0 0 9999px var(--bs-table-accent-bg)}.table>tbody{vertical-align:inherit}.table>thead{vertical-align:bottom}.table>:not(:first-child){border-top:2px solid currentColor}.caption-top{caption-side:top}.table-sm>:not(caption)>*>*{padding:.25rem .25rem}.table-bordered>:not(caption)>*{border-width:1px 0}.table-bordered>:not(caption)>*>*{border-width:0 1px}.table-borderless>:not(caption)>*>*{border-bottom-width:0}.table-borderless>:not(:first-child){border-top-width:0}.table-striped>tbody>tr:nth-of-type(odd)>*{--bs-table-accent-bg: var(--bs-table-striped-bg);color:var(--bs-table-striped-color)}.table-active{--bs-table-accent-bg: var(--bs-table-active-bg);color:var(--bs-table-active-color)}.table-hover>tbody>tr:hover>*{--bs-table-accent-bg: var(--bs-table-hover-bg);color:var(--bs-table-hover-color)}.table-primary{--bs-table-bg: #cce5fa;--bs-table-striped-bg: #c2daee;--bs-table-striped-color: #000;--bs-table-active-bg: #b8cee1;--bs-table-active-color: #000;--bs-table-hover-bg: #bdd4e7;--bs-table-hover-color: #000;color:#000;border-color:#b8cee1}.table-secondary{--bs-table-bg: #dfdfdf;--bs-table-striped-bg: #d4d4d4;--bs-table-striped-color: #000;--bs-table-active-bg: #c9c9c9;--bs-table-active-color: #000;--bs-table-hover-bg: #cecece;--bs-table-hover-color: #000;color:#000;border-color:#c9c9c9}.table-success{--bs-table-bg: #d9ecda;--bs-table-striped-bg: #cee0cf;--bs-table-striped-color: #000;--bs-table-active-bg: #c3d4c4;--bs-table-active-color: #000;--bs-table-hover-bg: #c9daca;--bs-table-hover-color: #000;color:#000;border-color:#c3d4c4}.table-info{--bs-table-bg: #daecf1;--bs-table-striped-bg: #cfe0e5;--bs-table-striped-color: #000;--bs-table-active-bg: #c4d4d9;--bs-table-active-color: #000;--bs-table-hover-bg: #cadadf;--bs-table-hover-color: #000;color:#000;border-color:#c4d4d9}.table-warning{--bs-table-bg: #feeed3;--bs-table-striped-bg: #f1e2c8;--bs-table-striped-color: #000;--bs-table-active-bg: #e5d6be;--bs-table-active-color: #000;--bs-table-hover-bg: #ebdcc3;--bs-table-hover-color: #000;color:#000;border-color:#e5d6be}.table-danger{--bs-table-bg: #ffdcd2;--bs-table-striped-bg: #f2d1c8;--bs-table-striped-color: #000;--bs-table-active-bg: #e6c6bd;--bs-table-active-color: #000;--bs-table-hover-bg: #ecccc2;--bs-table-hover-color: #000;color:#000;border-color:#e6c6bd}.table-light{--bs-table-bg: #616161;--bs-table-striped-bg: dimgray;--bs-table-striped-color: #fff;--bs-table-active-bg: #717171;--bs-table-active-color: #fff;--bs-table-hover-bg: #6d6d6d;--bs-table-hover-color: #fff;color:#fff;border-color:#717171}.table-dark{--bs-table-bg: #616161;--bs-table-striped-bg: dimgray;--bs-table-striped-color: #fff;--bs-table-active-bg: #717171;--bs-table-active-color: #fff;--bs-table-hover-bg: #6d6d6d;--bs-table-hover-color: #fff;color:#fff;border-color:#717171}.table-responsive{overflow-x:auto;-webkit-overflow-scrolling:touch}@media (max-width: 575.98px){.table-responsive-sm{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width: 767.98px){.table-responsive-md{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width: 991.98px){.table-responsive-lg{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width: 1199.98px){.table-responsive-xl{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width: 1399.98px){.table-responsive-xxl{overflow-x:auto;-webkit-overflow-scrolling:touch}}.table>:not(:first-child){border-width:0}.table td,.table th{white-space:nowrap;vertical-align:middle}.table a{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border;border-bottom:0.063rem dashed var(--dark);color:var(--t42-content-color)}.table a:hover{border-bottom-color:var(--t42-content-color);border-bottom-style:solid;color:var(--t42-link-color);text-decoration:none}.table thead th{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;border-width:1px 0;color:Hsl(var(--t42-content-color-base), calc(var(--t42-content-color-l) - 20%));font-weight:normal;font-size:83.3%;text-transform:uppercase}.table td{position:relative}.table td .btn,.table td .btn-sm,.table td .btn-group-sm>.btn,.table td .btn-lg,.table td .btn-group-lg>.btn{line-height:1.25rem}.table td .btn-icon i{position:relative;top:0.0625rem}.table tr th:first-child,.table tr td:first-child{padding-left:0.5rem}.table tr th:last-child,.table tr td:last-child{padding-right:0.5rem}.table-hover tbody tr:hover{background-color:var(--t42-table-active-bg)}.table-hover tbody tr:hover a{border-bottom-color:var(--t42-content-color);color:var(--t42-link-color)}.table-responsive{border:0}.tooltip{position:absolute;z-index:1080;display:block;margin:0;font-family:"Montserrat","Helvetica Neue",Arial,sans-serif;font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.65625rem;word-wrap:break-word;opacity:0}.tooltip.show{opacity:1}.tooltip .tooltip-arrow{position:absolute;display:block;width:.8rem;height:.4rem}.tooltip .tooltip-arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-top,.bs-tooltip-auto[data-popper-placement^="top"]{padding:.4rem 0}.bs-tooltip-top .tooltip-arrow,.bs-tooltip-auto[data-popper-placement^="top"] .tooltip-arrow{bottom:0}.bs-tooltip-top .tooltip-arrow::before,.bs-tooltip-auto[data-popper-placement^="top"] .tooltip-arrow::before{top:-1px;border-width:.4rem .4rem 0;border-top-color:var(--t42-tooltip-bg)}.bs-tooltip-end,.bs-tooltip-auto[data-popper-placement^="right"]{padding:0 .4rem}.bs-tooltip-end .tooltip-arrow,.bs-tooltip-auto[data-popper-placement^="right"] .tooltip-arrow{left:0;width:.4rem;height:.8rem}.bs-tooltip-end .tooltip-arrow::before,.bs-tooltip-auto[data-popper-placement^="right"] .tooltip-arrow::before{right:-1px;border-width:.4rem .4rem .4rem 0;border-right-color:var(--t42-tooltip-bg)}.bs-tooltip-bottom,.bs-tooltip-auto[data-popper-placement^="bottom"]{padding:.4rem 0}.bs-tooltip-bottom .tooltip-arrow,.bs-tooltip-auto[data-popper-placement^="bottom"] .tooltip-arrow{top:0}.bs-tooltip-bottom .tooltip-arrow::before,.bs-tooltip-auto[data-popper-placement^="bottom"] .tooltip-arrow::before{bottom:-1px;border-width:0 .4rem .4rem;border-bottom-color:var(--t42-tooltip-bg)}.bs-tooltip-start,.bs-tooltip-auto[data-popper-placement^="left"]{padding:0 .4rem}.bs-tooltip-start .tooltip-arrow,.bs-tooltip-auto[data-popper-placement^="left"] .tooltip-arrow{right:0;width:.4rem;height:.8rem}.bs-tooltip-start .tooltip-arrow::before,.bs-tooltip-auto[data-popper-placement^="left"] .tooltip-arrow::before{left:-1px;border-width:.4rem 0 .4rem .4rem;border-left-color:var(--t42-tooltip-bg)}.tooltip-inner{max-width:200px;padding:.25rem 1rem;color:var(--t42-content-color);text-align:center;background-color:var(--t42-tooltip-bg);border-radius:0}.tooltip .tooltip-inner{border:var(--t42-border);box-shadow:var(--t42-shadow)}.bs-tooltip-top .arrow,.bs-tooltip-auto[data-popper-placement^="top"] .arrow{bottom:1px}.bs-tooltip-top .arrow::before,.bs-tooltip-auto[data-popper-placement^="top"] .arrow::before{border-top-color:var(--t42-color-opacity-10)}.bs-tooltip-bottom .arrow,.bs-tooltip-auto[data-popper-placement^="bottom"] .arrow{top:1px}.bs-tooltip-bottom .arrow::before,.bs-tooltip-auto[data-popper-placement^="bottom"] .arrow::before{border-bottom-color:var(--t42-color-opacity-10)}.bs-tooltip-right .arrow{left:1px}.bs-tooltip-right .arrow::before{border-right-color:var(--t42-color-opacity-10)}.bs-tooltip-left .arrow{right:1px}.bs-tooltip-left .arrow::before{border-left-color:var(--t42-color-opacity-10)}.fade{transition:opacity 0.15s linear}@media (prefers-reduced-motion: reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{height:0;overflow:hidden;transition:height 0.35s ease}@media (prefers-reduced-motion: reduce){.collapsing{transition:none}}.collapsing.collapse-horizontal{width:0;height:auto;transition:width 0.35s ease}@media (prefers-reduced-motion: reduce){.collapsing.collapse-horizontal{transition:none}}mark,.mark{color:var(--white)}pre{background-color:var(--t42-bg-dark)}blockquote,.blockquote{padding:1rem 1rem 0.01rem;border-left:0.25rem solid var(--secondary);background-color:Rgb(var(--t42-bg-dark))}.blockquote-footer{margin-top:-2rem;margin-left:1.25rem;color:var(--t42-content-color-muted);font-size:0.875em}.clearfix::after{display:block;clear:both;content:""}.link-primary{color:#007be5}.link-primary:hover,.link-primary:focus{color:#3395ea}.link-secondary{color:#616161}.link-secondary:hover,.link-secondary:focus{color:#4e4e4e}.link-success{color:#43a047}.link-success:hover,.link-success:focus{color:#69b36c}.link-info{color:#469eb9}.link-info:hover,.link-info:focus{color:#6bb1c7}.link-warning{color:#f9a825}.link-warning:hover,.link-warning:focus{color:#fab951}.link-danger{color:#ff511f}.link-danger:hover,.link-danger:focus{color:#ff744c}.link-light{color:#616161}.link-light:hover,.link-light:focus{color:#4e4e4e}.link-dark{color:#616161}.link-dark:hover,.link-dark:focus{color:#4e4e4e}.ratio{position:relative;width:100%}.ratio::before{display:block;padding-top:var(--bs-aspect-ratio);content:""}.ratio>*{position:absolute;top:0;left:0;width:100%;height:100%}.ratio-1x1{--bs-aspect-ratio: 100%}.ratio-4x3{--bs-aspect-ratio: calc(3 / 4 * 100%)}.ratio-16x9{--bs-aspect-ratio: calc(9 / 16 * 100%)}.ratio-21x9{--bs-aspect-ratio: calc(9 / 21 * 100%)}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}.sticky-top{position:sticky;top:0;z-index:1020}@media (min-width: 576px){.sticky-sm-top{position:sticky;top:0;z-index:1020}}@media (min-width: 768px){.sticky-md-top{position:sticky;top:0;z-index:1020}}@media (min-width: 992px){.sticky-lg-top{position:sticky;top:0;z-index:1020}}@media (min-width: 1200px){.sticky-xl-top{position:sticky;top:0;z-index:1020}}@media (min-width: 1400px){.sticky-xxl-top{position:sticky;top:0;z-index:1020}}.hstack{display:flex;flex-direction:row;align-items:center;align-self:stretch}.vstack{display:flex;flex:1 1 auto;flex-direction:column;align-self:stretch}.visually-hidden,.visually-hidden-focusable:not(:focus):not(:focus-within){position:absolute !important;width:1px !important;height:1px !important;padding:0 !important;margin:-1px !important;overflow:hidden !important;clip:rect(0, 0, 0, 0) !important;white-space:nowrap !important;border:0 !important}.stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.vr{display:inline-block;align-self:stretch;width:1px;min-height:1em;background-color:currentColor;opacity:.25}.align-baseline{vertical-align:baseline !important}.align-top{vertical-align:top !important}.align-middle{vertical-align:middle !important}.align-bottom{vertical-align:bottom !important}.align-text-bottom{vertical-align:text-bottom !important}.align-text-top{vertical-align:text-top !important}.float-start{float:left !important}.float-end{float:right !important}.float-none{float:none !important}.opacity-0{opacity:0 !important}.opacity-25{opacity:.25 !important}.opacity-50{opacity:.5 !important}.opacity-75{opacity:.75 !important}.opacity-100{opacity:1 !important}.overflow-auto{overflow:auto !important}.overflow-hidden{overflow:hidden !important}.overflow-visible{overflow:visible !important}.overflow-scroll{overflow:scroll !important}.d-inline{display:inline !important}.d-inline-block{display:inline-block !important}.d-block{display:block !important}.d-grid{display:grid !important}.d-table{display:table !important}.d-table-row{display:table-row !important}.d-table-cell{display:table-cell !important}.d-flex{display:flex !important}.d-inline-flex{display:inline-flex !important}.d-none{display:none !important}.shadow{box-shadow:0 0.5rem 1rem rgba(0,0,0,0.15) !important}.shadow-sm{box-shadow:0 0.125rem 0.25rem rgba(0,0,0,0.075) !important}.shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,0.175) !important}.shadow-none{box-shadow:none !important}.position-static{position:static !important}.position-relative{position:relative !important}.position-absolute{position:absolute !important}.position-fixed{position:fixed !important}.position-sticky{position:sticky !important}.top-0{top:0 !important}.top-50{top:50% !important}.top-100{top:100% !important}.bottom-0{bottom:0 !important}.bottom-50{bottom:50% !important}.bottom-100{bottom:100% !important}.start-0{left:0 !important}.start-50{left:50% !important}.start-100{left:100% !important}.end-0{right:0 !important}.end-50{right:50% !important}.end-100{right:100% !important}.translate-middle{transform:translate(-50%, -50%) !important}.translate-middle-x{transform:translateX(-50%) !important}.translate-middle-y{transform:translateY(-50%) !important}.border{border:1px solid #dee2e6 !important}.border-0{border:0 !important}.border-top{border-top:1px solid #dee2e6 !important}.border-top-0{border-top:0 !important}.border-end{border-right:1px solid #dee2e6 !important}.border-end-0{border-right:0 !important}.border-bottom{border-bottom:1px solid #dee2e6 !important}.border-bottom-0{border-bottom:0 !important}.border-start{border-left:1px solid #dee2e6 !important}.border-start-0{border-left:0 !important}.border-primary{border-color:#007be5 !important}.border-secondary{border-color:#616161 !important}.border-success{border-color:#43a047 !important}.border-info{border-color:#469eb9 !important}.border-warning{border-color:#f9a825 !important}.border-danger{border-color:#ff511f !important}.border-light{border-color:#616161 !important}.border-dark{border-color:#616161 !important}.border-white{border-color:#fff !important}.border-1{border-width:1px !important}.border-2{border-width:2px !important}.border-3{border-width:3px !important}.border-4{border-width:4px !important}.border-5{border-width:5px !important}.w-25{width:25% !important}.w-50{width:50% !important}.w-75{width:75% !important}.w-100{width:100% !important}.w-auto{width:auto !important}.mw-100{max-width:100% !important}.vw-100{width:100vw !important}.min-vw-100{min-width:100vw !important}.h-25{height:25% !important}.h-50{height:50% !important}.h-75{height:75% !important}.h-100{height:100% !important}.h-auto{height:auto !important}.mh-100{max-height:100% !important}.vh-100{height:100vh !important}.min-vh-100{min-height:100vh !important}.flex-fill{flex:1 1 auto !important}.flex-row{flex-direction:row !important}.flex-column{flex-direction:column !important}.flex-row-reverse{flex-direction:row-reverse !important}.flex-column-reverse{flex-direction:column-reverse !important}.flex-grow-0{flex-grow:0 !important}.flex-grow-1{flex-grow:1 !important}.flex-shrink-0{flex-shrink:0 !important}.flex-shrink-1{flex-shrink:1 !important}.flex-wrap{flex-wrap:wrap !important}.flex-nowrap{flex-wrap:nowrap !important}.flex-wrap-reverse{flex-wrap:wrap-reverse !important}.gap-0{gap:0 !important}.gap-1{gap:.25rem !important}.gap-2{gap:.5rem !important}.gap-3{gap:1rem !important}.gap-4{gap:1.5rem !important}.gap-5{gap:3rem !important}.justify-content-start{justify-content:flex-start !important}.justify-content-end{justify-content:flex-end !important}.justify-content-center{justify-content:center !important}.justify-content-between{justify-content:space-between !important}.justify-content-around{justify-content:space-around !important}.justify-content-evenly{justify-content:space-evenly !important}.align-items-start{align-items:flex-start !important}.align-items-end{align-items:flex-end !important}.align-items-center{align-items:center !important}.align-items-baseline{align-items:baseline !important}.align-items-stretch{align-items:stretch !important}.align-content-start{align-content:flex-start !important}.align-content-end{align-content:flex-end !important}.align-content-center{align-content:center !important}.align-content-between{align-content:space-between !important}.align-content-around{align-content:space-around !important}.align-content-stretch{align-content:stretch !important}.align-self-auto{align-self:auto !important}.align-self-start{align-self:flex-start !important}.align-self-end{align-self:flex-end !important}.align-self-center{align-self:center !important}.align-self-baseline{align-self:baseline !important}.align-self-stretch{align-self:stretch !important}.order-first{order:-1 !important}.order-0{order:0 !important}.order-1{order:1 !important}.order-2{order:2 !important}.order-3{order:3 !important}.order-4{order:4 !important}.order-5{order:5 !important}.order-last{order:6 !important}.m-0{margin:0 !important}.m-1{margin:.25rem !important}.m-2{margin:.5rem !important}.m-3{margin:1rem !important}.m-4{margin:1.5rem !important}.m-5{margin:3rem !important}.m-auto{margin:auto !important}.mx-0{margin-right:0 !important;margin-left:0 !important}.mx-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-3{margin-right:1rem !important;margin-left:1rem !important}.mx-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-5{margin-right:3rem !important;margin-left:3rem !important}.mx-auto{margin-right:auto !important;margin-left:auto !important}.my-0{margin-top:0 !important;margin-bottom:0 !important}.my-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-0{margin-top:0 !important}.mt-1{margin-top:.25rem !important}.mt-2{margin-top:.5rem !important}.mt-3{margin-top:1rem !important}.mt-4{margin-top:1.5rem !important}.mt-5{margin-top:3rem !important}.mt-auto{margin-top:auto !important}.me-0{margin-right:0 !important}.me-1{margin-right:.25rem !important}.me-2{margin-right:.5rem !important}.me-3{margin-right:1rem !important}.me-4{margin-right:1.5rem !important}.me-5{margin-right:3rem !important}.me-auto{margin-right:auto !important}.mb-0{margin-bottom:0 !important}.mb-1{margin-bottom:.25rem !important}.mb-2{margin-bottom:.5rem !important}.mb-3{margin-bottom:1rem !important}.mb-4{margin-bottom:1.5rem !important}.mb-5{margin-bottom:3rem !important}.mb-auto{margin-bottom:auto !important}.ms-0{margin-left:0 !important}.ms-1{margin-left:.25rem !important}.ms-2{margin-left:.5rem !important}.ms-3{margin-left:1rem !important}.ms-4{margin-left:1.5rem !important}.ms-5{margin-left:3rem !important}.ms-auto{margin-left:auto !important}.p-0{padding:0 !important}.p-1{padding:.25rem !important}.p-2{padding:.5rem !important}.p-3{padding:1rem !important}.p-4{padding:1.5rem !important}.p-5{padding:3rem !important}.px-0{padding-right:0 !important;padding-left:0 !important}.px-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-3{padding-right:1rem !important;padding-left:1rem !important}.px-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-5{padding-right:3rem !important;padding-left:3rem !important}.py-0{padding-top:0 !important;padding-bottom:0 !important}.py-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-0{padding-top:0 !important}.pt-1{padding-top:.25rem !important}.pt-2{padding-top:.5rem !important}.pt-3{padding-top:1rem !important}.pt-4{padding-top:1.5rem !important}.pt-5{padding-top:3rem !important}.pe-0{padding-right:0 !important}.pe-1{padding-right:.25rem !important}.pe-2{padding-right:.5rem !important}.pe-3{padding-right:1rem !important}.pe-4{padding-right:1.5rem !important}.pe-5{padding-right:3rem !important}.pb-0{padding-bottom:0 !important}.pb-1{padding-bottom:.25rem !important}.pb-2{padding-bottom:.5rem !important}.pb-3{padding-bottom:1rem !important}.pb-4{padding-bottom:1.5rem !important}.pb-5{padding-bottom:3rem !important}.ps-0{padding-left:0 !important}.ps-1{padding-left:.25rem !important}.ps-2{padding-left:.5rem !important}.ps-3{padding-left:1rem !important}.ps-4{padding-left:1.5rem !important}.ps-5{padding-left:3rem !important}.font-monospace{font-family:var(--bs-font-monospace) !important}.fs-1{font-size:calc(1.26563rem + .1875vw) !important}.fs-2{font-size:1.125rem !important}.fs-3{font-size:.98475rem !important}.fs-4{font-size:.84375rem !important}.fs-5{font-size:.75rem !important}.fs-6{font-size:.7035rem !important}.fst-italic{font-style:italic !important}.fst-normal{font-style:normal !important}.fw-light{font-weight:300 !important}.fw-lighter{font-weight:lighter !important}.fw-normal{font-weight:400 !important}.fw-bold{font-weight:700 !important}.fw-bolder{font-weight:bolder !important}.lh-1{line-height:1 !important}.lh-sm{line-height:1.25 !important}.lh-base{line-height:1.5 !important}.lh-lg{line-height:2 !important}.text-start{text-align:left !important}.text-end{text-align:right !important}.text-center{text-align:center !important}.text-decoration-none{text-decoration:none !important}.text-decoration-underline{text-decoration:underline !important}.text-decoration-line-through{text-decoration:line-through !important}.text-lowercase{text-transform:lowercase !important}.text-uppercase{text-transform:uppercase !important}.text-capitalize{text-transform:capitalize !important}.text-wrap{white-space:normal !important}.text-nowrap{white-space:nowrap !important}.text-break{word-wrap:break-word !important;word-break:break-word !important}.text-primary{--bs-text-opacity: 1;color:rgba(var(--bs-primary-rgb), var(--bs-text-opacity)) !important}.text-secondary{--bs-text-opacity: 1;color:rgba(var(--bs-secondary-rgb), var(--bs-text-opacity)) !important}.text-success{--bs-text-opacity: 1;color:rgba(var(--bs-success-rgb), var(--bs-text-opacity)) !important}.text-info{--bs-text-opacity: 1;color:rgba(var(--bs-info-rgb), var(--bs-text-opacity)) !important}.text-warning{--bs-text-opacity: 1;color:rgba(var(--bs-warning-rgb), var(--bs-text-opacity)) !important}.text-danger{--bs-text-opacity: 1;color:rgba(var(--bs-danger-rgb), var(--bs-text-opacity)) !important}.text-light{--bs-text-opacity: 1;color:rgba(var(--bs-light-rgb), var(--bs-text-opacity)) !important}.text-dark{--bs-text-opacity: 1;color:rgba(var(--bs-dark-rgb), var(--bs-text-opacity)) !important}.text-black{--bs-text-opacity: 1;color:rgba(var(--bs-black-rgb), var(--bs-text-opacity)) !important}.text-white{--bs-text-opacity: 1;color:rgba(var(--bs-white-rgb), var(--bs-text-opacity)) !important}.text-body{--bs-text-opacity: 1;color:rgba(var(--bs-body-color-rgb), var(--bs-text-opacity)) !important}.text-muted{--bs-text-opacity: 1;color:var(--t42-content-color-muted) !important}.text-black-50{--bs-text-opacity: 1;color:rgba(0,0,0,0.5) !important}.text-white-50{--bs-text-opacity: 1;color:rgba(255,255,255,0.5) !important}.text-reset{--bs-text-opacity: 1;color:inherit !important}.text-opacity-25{--bs-text-opacity: .25}.text-opacity-50{--bs-text-opacity: .5}.text-opacity-75{--bs-text-opacity: .75}.text-opacity-100{--bs-text-opacity: 1}.bg-primary{--bs-bg-opacity: 1;background-color:rgba(var(--bs-primary-rgb), var(--bs-bg-opacity)) !important}.bg-secondary{--bs-bg-opacity: 1;background-color:rgba(var(--bs-secondary-rgb), var(--bs-bg-opacity)) !important}.bg-success{--bs-bg-opacity: 1;background-color:rgba(var(--bs-success-rgb), var(--bs-bg-opacity)) !important}.bg-info{--bs-bg-opacity: 1;background-color:rgba(var(--bs-info-rgb), var(--bs-bg-opacity)) !important}.bg-warning{--bs-bg-opacity: 1;background-color:rgba(var(--bs-warning-rgb), var(--bs-bg-opacity)) !important}.bg-danger{--bs-bg-opacity: 1;background-color:rgba(var(--bs-danger-rgb), var(--bs-bg-opacity)) !important}.bg-light{--bs-bg-opacity: 1;background-color:rgba(var(--bs-light-rgb), var(--bs-bg-opacity)) !important}.bg-dark{--bs-bg-opacity: 1;background-color:rgba(var(--bs-dark-rgb), var(--bs-bg-opacity)) !important}.bg-black{--bs-bg-opacity: 1;background-color:rgba(var(--bs-black-rgb), var(--bs-bg-opacity)) !important}.bg-white{--bs-bg-opacity: 1;background-color:rgba(var(--bs-white-rgb), var(--bs-bg-opacity)) !important}.bg-body{--bs-bg-opacity: 1;background-color:rgba(var(--bs-body-bg-rgb), var(--bs-bg-opacity)) !important}.bg-transparent{--bs-bg-opacity: 1;background-color:rgba(0,0,0,0) !important}.bg-opacity-10{--bs-bg-opacity: .1}.bg-opacity-25{--bs-bg-opacity: .25}.bg-opacity-50{--bs-bg-opacity: .5}.bg-opacity-75{--bs-bg-opacity: .75}.bg-opacity-100{--bs-bg-opacity: 1}.bg-gradient{background-image:var(--bs-gradient) !important}.user-select-all{user-select:all !important}.user-select-auto{user-select:auto !important}.user-select-none{user-select:none !important}.pe-none{pointer-events:none !important}.pe-auto{pointer-events:auto !important}.rounded{border-radius:.25rem !important}.rounded-0{border-radius:0 !important}.rounded-1{border-radius:.25rem !important}.rounded-2{border-radius:.25rem !important}.rounded-3{border-radius:1rem !important}.rounded-circle{border-radius:50% !important}.rounded-pill{border-radius:50rem !important}.rounded-top{border-top-left-radius:.25rem !important;border-top-right-radius:.25rem !important}.rounded-end{border-top-right-radius:.25rem !important;border-bottom-right-radius:.25rem !important}.rounded-bottom{border-bottom-right-radius:.25rem !important;border-bottom-left-radius:.25rem !important}.rounded-start{border-bottom-left-radius:.25rem !important;border-top-left-radius:.25rem !important}.visible{visibility:visible !important}.invisible{visibility:hidden !important}@media (min-width: 576px){.float-sm-start{float:left !important}.float-sm-end{float:right !important}.float-sm-none{float:none !important}.d-sm-inline{display:inline !important}.d-sm-inline-block{display:inline-block !important}.d-sm-block{display:block !important}.d-sm-grid{display:grid !important}.d-sm-table{display:table !important}.d-sm-table-row{display:table-row !important}.d-sm-table-cell{display:table-cell !important}.d-sm-flex{display:flex !important}.d-sm-inline-flex{display:inline-flex !important}.d-sm-none{display:none !important}.flex-sm-fill{flex:1 1 auto !important}.flex-sm-row{flex-direction:row !important}.flex-sm-column{flex-direction:column !important}.flex-sm-row-reverse{flex-direction:row-reverse !important}.flex-sm-column-reverse{flex-direction:column-reverse !important}.flex-sm-grow-0{flex-grow:0 !important}.flex-sm-grow-1{flex-grow:1 !important}.flex-sm-shrink-0{flex-shrink:0 !important}.flex-sm-shrink-1{flex-shrink:1 !important}.flex-sm-wrap{flex-wrap:wrap !important}.flex-sm-nowrap{flex-wrap:nowrap !important}.flex-sm-wrap-reverse{flex-wrap:wrap-reverse !important}.gap-sm-0{gap:0 !important}.gap-sm-1{gap:.25rem !important}.gap-sm-2{gap:.5rem !important}.gap-sm-3{gap:1rem !important}.gap-sm-4{gap:1.5rem !important}.gap-sm-5{gap:3rem !important}.justify-content-sm-start{justify-content:flex-start !important}.justify-content-sm-end{justify-content:flex-end !important}.justify-content-sm-center{justify-content:center !important}.justify-content-sm-between{justify-content:space-between !important}.justify-content-sm-around{justify-content:space-around !important}.justify-content-sm-evenly{justify-content:space-evenly !important}.align-items-sm-start{align-items:flex-start !important}.align-items-sm-end{align-items:flex-end !important}.align-items-sm-center{align-items:center !important}.align-items-sm-baseline{align-items:baseline !important}.align-items-sm-stretch{align-items:stretch !important}.align-content-sm-start{align-content:flex-start !important}.align-content-sm-end{align-content:flex-end !important}.align-content-sm-center{align-content:center !important}.align-content-sm-between{align-content:space-between !important}.align-content-sm-around{align-content:space-around !important}.align-content-sm-stretch{align-content:stretch !important}.align-self-sm-auto{align-self:auto !important}.align-self-sm-start{align-self:flex-start !important}.align-self-sm-end{align-self:flex-end !important}.align-self-sm-center{align-self:center !important}.align-self-sm-baseline{align-self:baseline !important}.align-self-sm-stretch{align-self:stretch !important}.order-sm-first{order:-1 !important}.order-sm-0{order:0 !important}.order-sm-1{order:1 !important}.order-sm-2{order:2 !important}.order-sm-3{order:3 !important}.order-sm-4{order:4 !important}.order-sm-5{order:5 !important}.order-sm-last{order:6 !important}.m-sm-0{margin:0 !important}.m-sm-1{margin:.25rem !important}.m-sm-2{margin:.5rem !important}.m-sm-3{margin:1rem !important}.m-sm-4{margin:1.5rem !important}.m-sm-5{margin:3rem !important}.m-sm-auto{margin:auto !important}.mx-sm-0{margin-right:0 !important;margin-left:0 !important}.mx-sm-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-sm-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-sm-3{margin-right:1rem !important;margin-left:1rem !important}.mx-sm-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-sm-5{margin-right:3rem !important;margin-left:3rem !important}.mx-sm-auto{margin-right:auto !important;margin-left:auto !important}.my-sm-0{margin-top:0 !important;margin-bottom:0 !important}.my-sm-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-sm-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-sm-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-sm-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-sm-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-sm-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-sm-0{margin-top:0 !important}.mt-sm-1{margin-top:.25rem !important}.mt-sm-2{margin-top:.5rem !important}.mt-sm-3{margin-top:1rem !important}.mt-sm-4{margin-top:1.5rem !important}.mt-sm-5{margin-top:3rem !important}.mt-sm-auto{margin-top:auto !important}.me-sm-0{margin-right:0 !important}.me-sm-1{margin-right:.25rem !important}.me-sm-2{margin-right:.5rem !important}.me-sm-3{margin-right:1rem !important}.me-sm-4{margin-right:1.5rem !important}.me-sm-5{margin-right:3rem !important}.me-sm-auto{margin-right:auto !important}.mb-sm-0{margin-bottom:0 !important}.mb-sm-1{margin-bottom:.25rem !important}.mb-sm-2{margin-bottom:.5rem !important}.mb-sm-3{margin-bottom:1rem !important}.mb-sm-4{margin-bottom:1.5rem !important}.mb-sm-5{margin-bottom:3rem !important}.mb-sm-auto{margin-bottom:auto !important}.ms-sm-0{margin-left:0 !important}.ms-sm-1{margin-left:.25rem !important}.ms-sm-2{margin-left:.5rem !important}.ms-sm-3{margin-left:1rem !important}.ms-sm-4{margin-left:1.5rem !important}.ms-sm-5{margin-left:3rem !important}.ms-sm-auto{margin-left:auto !important}.p-sm-0{padding:0 !important}.p-sm-1{padding:.25rem !important}.p-sm-2{padding:.5rem !important}.p-sm-3{padding:1rem !important}.p-sm-4{padding:1.5rem !important}.p-sm-5{padding:3rem !important}.px-sm-0{padding-right:0 !important;padding-left:0 !important}.px-sm-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-sm-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-sm-3{padding-right:1rem !important;padding-left:1rem !important}.px-sm-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-sm-5{padding-right:3rem !important;padding-left:3rem !important}.py-sm-0{padding-top:0 !important;padding-bottom:0 !important}.py-sm-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-sm-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-sm-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-sm-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-sm-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-sm-0{padding-top:0 !important}.pt-sm-1{padding-top:.25rem !important}.pt-sm-2{padding-top:.5rem !important}.pt-sm-3{padding-top:1rem !important}.pt-sm-4{padding-top:1.5rem !important}.pt-sm-5{padding-top:3rem !important}.pe-sm-0{padding-right:0 !important}.pe-sm-1{padding-right:.25rem !important}.pe-sm-2{padding-right:.5rem !important}.pe-sm-3{padding-right:1rem !important}.pe-sm-4{padding-right:1.5rem !important}.pe-sm-5{padding-right:3rem !important}.pb-sm-0{padding-bottom:0 !important}.pb-sm-1{padding-bottom:.25rem !important}.pb-sm-2{padding-bottom:.5rem !important}.pb-sm-3{padding-bottom:1rem !important}.pb-sm-4{padding-bottom:1.5rem !important}.pb-sm-5{padding-bottom:3rem !important}.ps-sm-0{padding-left:0 !important}.ps-sm-1{padding-left:.25rem !important}.ps-sm-2{padding-left:.5rem !important}.ps-sm-3{padding-left:1rem !important}.ps-sm-4{padding-left:1.5rem !important}.ps-sm-5{padding-left:3rem !important}.text-sm-start{text-align:left !important}.text-sm-end{text-align:right !important}.text-sm-center{text-align:center !important}}@media (min-width: 768px){.float-md-start{float:left !important}.float-md-end{float:right !important}.float-md-none{float:none !important}.d-md-inline{display:inline !important}.d-md-inline-block{display:inline-block !important}.d-md-block{display:block !important}.d-md-grid{display:grid !important}.d-md-table{display:table !important}.d-md-table-row{display:table-row !important}.d-md-table-cell{display:table-cell !important}.d-md-flex{display:flex !important}.d-md-inline-flex{display:inline-flex !important}.d-md-none{display:none !important}.flex-md-fill{flex:1 1 auto !important}.flex-md-row{flex-direction:row !important}.flex-md-column{flex-direction:column !important}.flex-md-row-reverse{flex-direction:row-reverse !important}.flex-md-column-reverse{flex-direction:column-reverse !important}.flex-md-grow-0{flex-grow:0 !important}.flex-md-grow-1{flex-grow:1 !important}.flex-md-shrink-0{flex-shrink:0 !important}.flex-md-shrink-1{flex-shrink:1 !important}.flex-md-wrap{flex-wrap:wrap !important}.flex-md-nowrap{flex-wrap:nowrap !important}.flex-md-wrap-reverse{flex-wrap:wrap-reverse !important}.gap-md-0{gap:0 !important}.gap-md-1{gap:.25rem !important}.gap-md-2{gap:.5rem !important}.gap-md-3{gap:1rem !important}.gap-md-4{gap:1.5rem !important}.gap-md-5{gap:3rem !important}.justify-content-md-start{justify-content:flex-start !important}.justify-content-md-end{justify-content:flex-end !important}.justify-content-md-center{justify-content:center !important}.justify-content-md-between{justify-content:space-between !important}.justify-content-md-around{justify-content:space-around !important}.justify-content-md-evenly{justify-content:space-evenly !important}.align-items-md-start{align-items:flex-start !important}.align-items-md-end{align-items:flex-end !important}.align-items-md-center{align-items:center !important}.align-items-md-baseline{align-items:baseline !important}.align-items-md-stretch{align-items:stretch !important}.align-content-md-start{align-content:flex-start !important}.align-content-md-end{align-content:flex-end !important}.align-content-md-center{align-content:center !important}.align-content-md-between{align-content:space-between !important}.align-content-md-around{align-content:space-around !important}.align-content-md-stretch{align-content:stretch !important}.align-self-md-auto{align-self:auto !important}.align-self-md-start{align-self:flex-start !important}.align-self-md-end{align-self:flex-end !important}.align-self-md-center{align-self:center !important}.align-self-md-baseline{align-self:baseline !important}.align-self-md-stretch{align-self:stretch !important}.order-md-first{order:-1 !important}.order-md-0{order:0 !important}.order-md-1{order:1 !important}.order-md-2{order:2 !important}.order-md-3{order:3 !important}.order-md-4{order:4 !important}.order-md-5{order:5 !important}.order-md-last{order:6 !important}.m-md-0{margin:0 !important}.m-md-1{margin:.25rem !important}.m-md-2{margin:.5rem !important}.m-md-3{margin:1rem !important}.m-md-4{margin:1.5rem !important}.m-md-5{margin:3rem !important}.m-md-auto{margin:auto !important}.mx-md-0{margin-right:0 !important;margin-left:0 !important}.mx-md-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-md-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-md-3{margin-right:1rem !important;margin-left:1rem !important}.mx-md-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-md-5{margin-right:3rem !important;margin-left:3rem !important}.mx-md-auto{margin-right:auto !important;margin-left:auto !important}.my-md-0{margin-top:0 !important;margin-bottom:0 !important}.my-md-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-md-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-md-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-md-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-md-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-md-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-md-0{margin-top:0 !important}.mt-md-1{margin-top:.25rem !important}.mt-md-2{margin-top:.5rem !important}.mt-md-3{margin-top:1rem !important}.mt-md-4{margin-top:1.5rem !important}.mt-md-5{margin-top:3rem !important}.mt-md-auto{margin-top:auto !important}.me-md-0{margin-right:0 !important}.me-md-1{margin-right:.25rem !important}.me-md-2{margin-right:.5rem !important}.me-md-3{margin-right:1rem !important}.me-md-4{margin-right:1.5rem !important}.me-md-5{margin-right:3rem !important}.me-md-auto{margin-right:auto !important}.mb-md-0{margin-bottom:0 !important}.mb-md-1{margin-bottom:.25rem !important}.mb-md-2{margin-bottom:.5rem !important}.mb-md-3{margin-bottom:1rem !important}.mb-md-4{margin-bottom:1.5rem !important}.mb-md-5{margin-bottom:3rem !important}.mb-md-auto{margin-bottom:auto !important}.ms-md-0{margin-left:0 !important}.ms-md-1{margin-left:.25rem !important}.ms-md-2{margin-left:.5rem !important}.ms-md-3{margin-left:1rem !important}.ms-md-4{margin-left:1.5rem !important}.ms-md-5{margin-left:3rem !important}.ms-md-auto{margin-left:auto !important}.p-md-0{padding:0 !important}.p-md-1{padding:.25rem !important}.p-md-2{padding:.5rem !important}.p-md-3{padding:1rem !important}.p-md-4{padding:1.5rem !important}.p-md-5{padding:3rem !important}.px-md-0{padding-right:0 !important;padding-left:0 !important}.px-md-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-md-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-md-3{padding-right:1rem !important;padding-left:1rem !important}.px-md-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-md-5{padding-right:3rem !important;padding-left:3rem !important}.py-md-0{padding-top:0 !important;padding-bottom:0 !important}.py-md-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-md-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-md-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-md-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-md-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-md-0{padding-top:0 !important}.pt-md-1{padding-top:.25rem !important}.pt-md-2{padding-top:.5rem !important}.pt-md-3{padding-top:1rem !important}.pt-md-4{padding-top:1.5rem !important}.pt-md-5{padding-top:3rem !important}.pe-md-0{padding-right:0 !important}.pe-md-1{padding-right:.25rem !important}.pe-md-2{padding-right:.5rem !important}.pe-md-3{padding-right:1rem !important}.pe-md-4{padding-right:1.5rem !important}.pe-md-5{padding-right:3rem !important}.pb-md-0{padding-bottom:0 !important}.pb-md-1{padding-bottom:.25rem !important}.pb-md-2{padding-bottom:.5rem !important}.pb-md-3{padding-bottom:1rem !important}.pb-md-4{padding-bottom:1.5rem !important}.pb-md-5{padding-bottom:3rem !important}.ps-md-0{padding-left:0 !important}.ps-md-1{padding-left:.25rem !important}.ps-md-2{padding-left:.5rem !important}.ps-md-3{padding-left:1rem !important}.ps-md-4{padding-left:1.5rem !important}.ps-md-5{padding-left:3rem !important}.text-md-start{text-align:left !important}.text-md-end{text-align:right !important}.text-md-center{text-align:center !important}}@media (min-width: 992px){.float-lg-start{float:left !important}.float-lg-end{float:right !important}.float-lg-none{float:none !important}.d-lg-inline{display:inline !important}.d-lg-inline-block{display:inline-block !important}.d-lg-block{display:block !important}.d-lg-grid{display:grid !important}.d-lg-table{display:table !important}.d-lg-table-row{display:table-row !important}.d-lg-table-cell{display:table-cell !important}.d-lg-flex{display:flex !important}.d-lg-inline-flex{display:inline-flex !important}.d-lg-none{display:none !important}.flex-lg-fill{flex:1 1 auto !important}.flex-lg-row{flex-direction:row !important}.flex-lg-column{flex-direction:column !important}.flex-lg-row-reverse{flex-direction:row-reverse !important}.flex-lg-column-reverse{flex-direction:column-reverse !important}.flex-lg-grow-0{flex-grow:0 !important}.flex-lg-grow-1{flex-grow:1 !important}.flex-lg-shrink-0{flex-shrink:0 !important}.flex-lg-shrink-1{flex-shrink:1 !important}.flex-lg-wrap{flex-wrap:wrap !important}.flex-lg-nowrap{flex-wrap:nowrap !important}.flex-lg-wrap-reverse{flex-wrap:wrap-reverse !important}.gap-lg-0{gap:0 !important}.gap-lg-1{gap:.25rem !important}.gap-lg-2{gap:.5rem !important}.gap-lg-3{gap:1rem !important}.gap-lg-4{gap:1.5rem !important}.gap-lg-5{gap:3rem !important}.justify-content-lg-start{justify-content:flex-start !important}.justify-content-lg-end{justify-content:flex-end !important}.justify-content-lg-center{justify-content:center !important}.justify-content-lg-between{justify-content:space-between !important}.justify-content-lg-around{justify-content:space-around !important}.justify-content-lg-evenly{justify-content:space-evenly !important}.align-items-lg-start{align-items:flex-start !important}.align-items-lg-end{align-items:flex-end !important}.align-items-lg-center{align-items:center !important}.align-items-lg-baseline{align-items:baseline !important}.align-items-lg-stretch{align-items:stretch !important}.align-content-lg-start{align-content:flex-start !important}.align-content-lg-end{align-content:flex-end !important}.align-content-lg-center{align-content:center !important}.align-content-lg-between{align-content:space-between !important}.align-content-lg-around{align-content:space-around !important}.align-content-lg-stretch{align-content:stretch !important}.align-self-lg-auto{align-self:auto !important}.align-self-lg-start{align-self:flex-start !important}.align-self-lg-end{align-self:flex-end !important}.align-self-lg-center{align-self:center !important}.align-self-lg-baseline{align-self:baseline !important}.align-self-lg-stretch{align-self:stretch !important}.order-lg-first{order:-1 !important}.order-lg-0{order:0 !important}.order-lg-1{order:1 !important}.order-lg-2{order:2 !important}.order-lg-3{order:3 !important}.order-lg-4{order:4 !important}.order-lg-5{order:5 !important}.order-lg-last{order:6 !important}.m-lg-0{margin:0 !important}.m-lg-1{margin:.25rem !important}.m-lg-2{margin:.5rem !important}.m-lg-3{margin:1rem !important}.m-lg-4{margin:1.5rem !important}.m-lg-5{margin:3rem !important}.m-lg-auto{margin:auto !important}.mx-lg-0{margin-right:0 !important;margin-left:0 !important}.mx-lg-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-lg-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-lg-3{margin-right:1rem !important;margin-left:1rem !important}.mx-lg-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-lg-5{margin-right:3rem !important;margin-left:3rem !important}.mx-lg-auto{margin-right:auto !important;margin-left:auto !important}.my-lg-0{margin-top:0 !important;margin-bottom:0 !important}.my-lg-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-lg-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-lg-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-lg-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-lg-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-lg-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-lg-0{margin-top:0 !important}.mt-lg-1{margin-top:.25rem !important}.mt-lg-2{margin-top:.5rem !important}.mt-lg-3{margin-top:1rem !important}.mt-lg-4{margin-top:1.5rem !important}.mt-lg-5{margin-top:3rem !important}.mt-lg-auto{margin-top:auto !important}.me-lg-0{margin-right:0 !important}.me-lg-1{margin-right:.25rem !important}.me-lg-2{margin-right:.5rem !important}.me-lg-3{margin-right:1rem !important}.me-lg-4{margin-right:1.5rem !important}.me-lg-5{margin-right:3rem !important}.me-lg-auto{margin-right:auto !important}.mb-lg-0{margin-bottom:0 !important}.mb-lg-1{margin-bottom:.25rem !important}.mb-lg-2{margin-bottom:.5rem !important}.mb-lg-3{margin-bottom:1rem !important}.mb-lg-4{margin-bottom:1.5rem !important}.mb-lg-5{margin-bottom:3rem !important}.mb-lg-auto{margin-bottom:auto !important}.ms-lg-0{margin-left:0 !important}.ms-lg-1{margin-left:.25rem !important}.ms-lg-2{margin-left:.5rem !important}.ms-lg-3{margin-left:1rem !important}.ms-lg-4{margin-left:1.5rem !important}.ms-lg-5{margin-left:3rem !important}.ms-lg-auto{margin-left:auto !important}.p-lg-0{padding:0 !important}.p-lg-1{padding:.25rem !important}.p-lg-2{padding:.5rem !important}.p-lg-3{padding:1rem !important}.p-lg-4{padding:1.5rem !important}.p-lg-5{padding:3rem !important}.px-lg-0{padding-right:0 !important;padding-left:0 !important}.px-lg-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-lg-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-lg-3{padding-right:1rem !important;padding-left:1rem !important}.px-lg-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-lg-5{padding-right:3rem !important;padding-left:3rem !important}.py-lg-0{padding-top:0 !important;padding-bottom:0 !important}.py-lg-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-lg-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-lg-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-lg-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-lg-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-lg-0{padding-top:0 !important}.pt-lg-1{padding-top:.25rem !important}.pt-lg-2{padding-top:.5rem !important}.pt-lg-3{padding-top:1rem !important}.pt-lg-4{padding-top:1.5rem !important}.pt-lg-5{padding-top:3rem !important}.pe-lg-0{padding-right:0 !important}.pe-lg-1{padding-right:.25rem !important}.pe-lg-2{padding-right:.5rem !important}.pe-lg-3{padding-right:1rem !important}.pe-lg-4{padding-right:1.5rem !important}.pe-lg-5{padding-right:3rem !important}.pb-lg-0{padding-bottom:0 !important}.pb-lg-1{padding-bottom:.25rem !important}.pb-lg-2{padding-bottom:.5rem !important}.pb-lg-3{padding-bottom:1rem !important}.pb-lg-4{padding-bottom:1.5rem !important}.pb-lg-5{padding-bottom:3rem !important}.ps-lg-0{padding-left:0 !important}.ps-lg-1{padding-left:.25rem !important}.ps-lg-2{padding-left:.5rem !important}.ps-lg-3{padding-left:1rem !important}.ps-lg-4{padding-left:1.5rem !important}.ps-lg-5{padding-left:3rem !important}.text-lg-start{text-align:left !important}.text-lg-end{text-align:right !important}.text-lg-center{text-align:center !important}}@media (min-width: 1200px){.float-xl-start{float:left !important}.float-xl-end{float:right !important}.float-xl-none{float:none !important}.d-xl-inline{display:inline !important}.d-xl-inline-block{display:inline-block !important}.d-xl-block{display:block !important}.d-xl-grid{display:grid !important}.d-xl-table{display:table !important}.d-xl-table-row{display:table-row !important}.d-xl-table-cell{display:table-cell !important}.d-xl-flex{display:flex !important}.d-xl-inline-flex{display:inline-flex !important}.d-xl-none{display:none !important}.flex-xl-fill{flex:1 1 auto !important}.flex-xl-row{flex-direction:row !important}.flex-xl-column{flex-direction:column !important}.flex-xl-row-reverse{flex-direction:row-reverse !important}.flex-xl-column-reverse{flex-direction:column-reverse !important}.flex-xl-grow-0{flex-grow:0 !important}.flex-xl-grow-1{flex-grow:1 !important}.flex-xl-shrink-0{flex-shrink:0 !important}.flex-xl-shrink-1{flex-shrink:1 !important}.flex-xl-wrap{flex-wrap:wrap !important}.flex-xl-nowrap{flex-wrap:nowrap !important}.flex-xl-wrap-reverse{flex-wrap:wrap-reverse !important}.gap-xl-0{gap:0 !important}.gap-xl-1{gap:.25rem !important}.gap-xl-2{gap:.5rem !important}.gap-xl-3{gap:1rem !important}.gap-xl-4{gap:1.5rem !important}.gap-xl-5{gap:3rem !important}.justify-content-xl-start{justify-content:flex-start !important}.justify-content-xl-end{justify-content:flex-end !important}.justify-content-xl-center{justify-content:center !important}.justify-content-xl-between{justify-content:space-between !important}.justify-content-xl-around{justify-content:space-around !important}.justify-content-xl-evenly{justify-content:space-evenly !important}.align-items-xl-start{align-items:flex-start !important}.align-items-xl-end{align-items:flex-end !important}.align-items-xl-center{align-items:center !important}.align-items-xl-baseline{align-items:baseline !important}.align-items-xl-stretch{align-items:stretch !important}.align-content-xl-start{align-content:flex-start !important}.align-content-xl-end{align-content:flex-end !important}.align-content-xl-center{align-content:center !important}.align-content-xl-between{align-content:space-between !important}.align-content-xl-around{align-content:space-around !important}.align-content-xl-stretch{align-content:stretch !important}.align-self-xl-auto{align-self:auto !important}.align-self-xl-start{align-self:flex-start !important}.align-self-xl-end{align-self:flex-end !important}.align-self-xl-center{align-self:center !important}.align-self-xl-baseline{align-self:baseline !important}.align-self-xl-stretch{align-self:stretch !important}.order-xl-first{order:-1 !important}.order-xl-0{order:0 !important}.order-xl-1{order:1 !important}.order-xl-2{order:2 !important}.order-xl-3{order:3 !important}.order-xl-4{order:4 !important}.order-xl-5{order:5 !important}.order-xl-last{order:6 !important}.m-xl-0{margin:0 !important}.m-xl-1{margin:.25rem !important}.m-xl-2{margin:.5rem !important}.m-xl-3{margin:1rem !important}.m-xl-4{margin:1.5rem !important}.m-xl-5{margin:3rem !important}.m-xl-auto{margin:auto !important}.mx-xl-0{margin-right:0 !important;margin-left:0 !important}.mx-xl-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-xl-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-xl-3{margin-right:1rem !important;margin-left:1rem !important}.mx-xl-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-xl-5{margin-right:3rem !important;margin-left:3rem !important}.mx-xl-auto{margin-right:auto !important;margin-left:auto !important}.my-xl-0{margin-top:0 !important;margin-bottom:0 !important}.my-xl-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-xl-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-xl-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-xl-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-xl-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-xl-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-xl-0{margin-top:0 !important}.mt-xl-1{margin-top:.25rem !important}.mt-xl-2{margin-top:.5rem !important}.mt-xl-3{margin-top:1rem !important}.mt-xl-4{margin-top:1.5rem !important}.mt-xl-5{margin-top:3rem !important}.mt-xl-auto{margin-top:auto !important}.me-xl-0{margin-right:0 !important}.me-xl-1{margin-right:.25rem !important}.me-xl-2{margin-right:.5rem !important}.me-xl-3{margin-right:1rem !important}.me-xl-4{margin-right:1.5rem !important}.me-xl-5{margin-right:3rem !important}.me-xl-auto{margin-right:auto !important}.mb-xl-0{margin-bottom:0 !important}.mb-xl-1{margin-bottom:.25rem !important}.mb-xl-2{margin-bottom:.5rem !important}.mb-xl-3{margin-bottom:1rem !important}.mb-xl-4{margin-bottom:1.5rem !important}.mb-xl-5{margin-bottom:3rem !important}.mb-xl-auto{margin-bottom:auto !important}.ms-xl-0{margin-left:0 !important}.ms-xl-1{margin-left:.25rem !important}.ms-xl-2{margin-left:.5rem !important}.ms-xl-3{margin-left:1rem !important}.ms-xl-4{margin-left:1.5rem !important}.ms-xl-5{margin-left:3rem !important}.ms-xl-auto{margin-left:auto !important}.p-xl-0{padding:0 !important}.p-xl-1{padding:.25rem !important}.p-xl-2{padding:.5rem !important}.p-xl-3{padding:1rem !important}.p-xl-4{padding:1.5rem !important}.p-xl-5{padding:3rem !important}.px-xl-0{padding-right:0 !important;padding-left:0 !important}.px-xl-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-xl-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-xl-3{padding-right:1rem !important;padding-left:1rem !important}.px-xl-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-xl-5{padding-right:3rem !important;padding-left:3rem !important}.py-xl-0{padding-top:0 !important;padding-bottom:0 !important}.py-xl-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-xl-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-xl-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-xl-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-xl-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-xl-0{padding-top:0 !important}.pt-xl-1{padding-top:.25rem !important}.pt-xl-2{padding-top:.5rem !important}.pt-xl-3{padding-top:1rem !important}.pt-xl-4{padding-top:1.5rem !important}.pt-xl-5{padding-top:3rem !important}.pe-xl-0{padding-right:0 !important}.pe-xl-1{padding-right:.25rem !important}.pe-xl-2{padding-right:.5rem !important}.pe-xl-3{padding-right:1rem !important}.pe-xl-4{padding-right:1.5rem !important}.pe-xl-5{padding-right:3rem !important}.pb-xl-0{padding-bottom:0 !important}.pb-xl-1{padding-bottom:.25rem !important}.pb-xl-2{padding-bottom:.5rem !important}.pb-xl-3{padding-bottom:1rem !important}.pb-xl-4{padding-bottom:1.5rem !important}.pb-xl-5{padding-bottom:3rem !important}.ps-xl-0{padding-left:0 !important}.ps-xl-1{padding-left:.25rem !important}.ps-xl-2{padding-left:.5rem !important}.ps-xl-3{padding-left:1rem !important}.ps-xl-4{padding-left:1.5rem !important}.ps-xl-5{padding-left:3rem !important}.text-xl-start{text-align:left !important}.text-xl-end{text-align:right !important}.text-xl-center{text-align:center !important}}@media (min-width: 1400px){.float-xxl-start{float:left !important}.float-xxl-end{float:right !important}.float-xxl-none{float:none !important}.d-xxl-inline{display:inline !important}.d-xxl-inline-block{display:inline-block !important}.d-xxl-block{display:block !important}.d-xxl-grid{display:grid !important}.d-xxl-table{display:table !important}.d-xxl-table-row{display:table-row !important}.d-xxl-table-cell{display:table-cell !important}.d-xxl-flex{display:flex !important}.d-xxl-inline-flex{display:inline-flex !important}.d-xxl-none{display:none !important}.flex-xxl-fill{flex:1 1 auto !important}.flex-xxl-row{flex-direction:row !important}.flex-xxl-column{flex-direction:column !important}.flex-xxl-row-reverse{flex-direction:row-reverse !important}.flex-xxl-column-reverse{flex-direction:column-reverse !important}.flex-xxl-grow-0{flex-grow:0 !important}.flex-xxl-grow-1{flex-grow:1 !important}.flex-xxl-shrink-0{flex-shrink:0 !important}.flex-xxl-shrink-1{flex-shrink:1 !important}.flex-xxl-wrap{flex-wrap:wrap !important}.flex-xxl-nowrap{flex-wrap:nowrap !important}.flex-xxl-wrap-reverse{flex-wrap:wrap-reverse !important}.gap-xxl-0{gap:0 !important}.gap-xxl-1{gap:.25rem !important}.gap-xxl-2{gap:.5rem !important}.gap-xxl-3{gap:1rem !important}.gap-xxl-4{gap:1.5rem !important}.gap-xxl-5{gap:3rem !important}.justify-content-xxl-start{justify-content:flex-start !important}.justify-content-xxl-end{justify-content:flex-end !important}.justify-content-xxl-center{justify-content:center !important}.justify-content-xxl-between{justify-content:space-between !important}.justify-content-xxl-around{justify-content:space-around !important}.justify-content-xxl-evenly{justify-content:space-evenly !important}.align-items-xxl-start{align-items:flex-start !important}.align-items-xxl-end{align-items:flex-end !important}.align-items-xxl-center{align-items:center !important}.align-items-xxl-baseline{align-items:baseline !important}.align-items-xxl-stretch{align-items:stretch !important}.align-content-xxl-start{align-content:flex-start !important}.align-content-xxl-end{align-content:flex-end !important}.align-content-xxl-center{align-content:center !important}.align-content-xxl-between{align-content:space-between !important}.align-content-xxl-around{align-content:space-around !important}.align-content-xxl-stretch{align-content:stretch !important}.align-self-xxl-auto{align-self:auto !important}.align-self-xxl-start{align-self:flex-start !important}.align-self-xxl-end{align-self:flex-end !important}.align-self-xxl-center{align-self:center !important}.align-self-xxl-baseline{align-self:baseline !important}.align-self-xxl-stretch{align-self:stretch !important}.order-xxl-first{order:-1 !important}.order-xxl-0{order:0 !important}.order-xxl-1{order:1 !important}.order-xxl-2{order:2 !important}.order-xxl-3{order:3 !important}.order-xxl-4{order:4 !important}.order-xxl-5{order:5 !important}.order-xxl-last{order:6 !important}.m-xxl-0{margin:0 !important}.m-xxl-1{margin:.25rem !important}.m-xxl-2{margin:.5rem !important}.m-xxl-3{margin:1rem !important}.m-xxl-4{margin:1.5rem !important}.m-xxl-5{margin:3rem !important}.m-xxl-auto{margin:auto !important}.mx-xxl-0{margin-right:0 !important;margin-left:0 !important}.mx-xxl-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-xxl-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-xxl-3{margin-right:1rem !important;margin-left:1rem !important}.mx-xxl-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-xxl-5{margin-right:3rem !important;margin-left:3rem !important}.mx-xxl-auto{margin-right:auto !important;margin-left:auto !important}.my-xxl-0{margin-top:0 !important;margin-bottom:0 !important}.my-xxl-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-xxl-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-xxl-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-xxl-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-xxl-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-xxl-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-xxl-0{margin-top:0 !important}.mt-xxl-1{margin-top:.25rem !important}.mt-xxl-2{margin-top:.5rem !important}.mt-xxl-3{margin-top:1rem !important}.mt-xxl-4{margin-top:1.5rem !important}.mt-xxl-5{margin-top:3rem !important}.mt-xxl-auto{margin-top:auto !important}.me-xxl-0{margin-right:0 !important}.me-xxl-1{margin-right:.25rem !important}.me-xxl-2{margin-right:.5rem !important}.me-xxl-3{margin-right:1rem !important}.me-xxl-4{margin-right:1.5rem !important}.me-xxl-5{margin-right:3rem !important}.me-xxl-auto{margin-right:auto !important}.mb-xxl-0{margin-bottom:0 !important}.mb-xxl-1{margin-bottom:.25rem !important}.mb-xxl-2{margin-bottom:.5rem !important}.mb-xxl-3{margin-bottom:1rem !important}.mb-xxl-4{margin-bottom:1.5rem !important}.mb-xxl-5{margin-bottom:3rem !important}.mb-xxl-auto{margin-bottom:auto !important}.ms-xxl-0{margin-left:0 !important}.ms-xxl-1{margin-left:.25rem !important}.ms-xxl-2{margin-left:.5rem !important}.ms-xxl-3{margin-left:1rem !important}.ms-xxl-4{margin-left:1.5rem !important}.ms-xxl-5{margin-left:3rem !important}.ms-xxl-auto{margin-left:auto !important}.p-xxl-0{padding:0 !important}.p-xxl-1{padding:.25rem !important}.p-xxl-2{padding:.5rem !important}.p-xxl-3{padding:1rem !important}.p-xxl-4{padding:1.5rem !important}.p-xxl-5{padding:3rem !important}.px-xxl-0{padding-right:0 !important;padding-left:0 !important}.px-xxl-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-xxl-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-xxl-3{padding-right:1rem !important;padding-left:1rem !important}.px-xxl-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-xxl-5{padding-right:3rem !important;padding-left:3rem !important}.py-xxl-0{padding-top:0 !important;padding-bottom:0 !important}.py-xxl-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-xxl-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-xxl-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-xxl-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-xxl-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-xxl-0{padding-top:0 !important}.pt-xxl-1{padding-top:.25rem !important}.pt-xxl-2{padding-top:.5rem !important}.pt-xxl-3{padding-top:1rem !important}.pt-xxl-4{padding-top:1.5rem !important}.pt-xxl-5{padding-top:3rem !important}.pe-xxl-0{padding-right:0 !important}.pe-xxl-1{padding-right:.25rem !important}.pe-xxl-2{padding-right:.5rem !important}.pe-xxl-3{padding-right:1rem !important}.pe-xxl-4{padding-right:1.5rem !important}.pe-xxl-5{padding-right:3rem !important}.pb-xxl-0{padding-bottom:0 !important}.pb-xxl-1{padding-bottom:.25rem !important}.pb-xxl-2{padding-bottom:.5rem !important}.pb-xxl-3{padding-bottom:1rem !important}.pb-xxl-4{padding-bottom:1.5rem !important}.pb-xxl-5{padding-bottom:3rem !important}.ps-xxl-0{padding-left:0 !important}.ps-xxl-1{padding-left:.25rem !important}.ps-xxl-2{padding-left:.5rem !important}.ps-xxl-3{padding-left:1rem !important}.ps-xxl-4{padding-left:1.5rem !important}.ps-xxl-5{padding-left:3rem !important}.text-xxl-start{text-align:left !important}.text-xxl-end{text-align:right !important}.text-xxl-center{text-align:center !important}}@media (min-width: 1200px){.fs-1{font-size:1.40625rem !important}}@media print{.d-print-inline{display:inline !important}.d-print-inline-block{display:inline-block !important}.d-print-block{display:block !important}.d-print-grid{display:grid !important}.d-print-table{display:table !important}.d-print-table-row{display:table-row !important}.d-print-table-cell{display:table-cell !important}.d-print-flex{display:flex !important}.d-print-inline-flex{display:inline-flex !important}.d-print-none{display:none !important}}body{background-size:cover}.bg-light{background-color:Rgb(var(--t42-bg-light)) !important}.bg-dark{background-color:Rgb(var(--t42-bg-dark)) !important}.bg-base{background-color:Rgb(var(--t42-bg-mid)) !important}.border{border:0.0625rem solid var(--t42-color-opacity-10) !important}.border-primary{border-color:#007be5 !important}.border-secondary,.border-info,.border-light,.border-dark,.border-white{border-color:var(--t42-color-opacity-10) !important}.border-success{border-color:#43a047 !important}.border-danger{border-color:#ff511f !important}.border-warning{border-color:#f9a825 !important}.pl-0{padding-left:0}.pl-1{padding-left:0.25rem}.pl-2{padding-left:0.5rem}.pl-3{padding-left:1rem}.pl-4{padding-left:1.5rem}.pl-5{padding-left:3rem}.pl-auto{padding-left:auto}.pr-0{padding-right:0}.pr-1{padding-right:0.25rem}.pr-2{padding-right:0.5rem}.pr-3{padding-right:1rem}.pr-4{padding-right:1.5rem}.pr-5{padding-right:3rem}.pr-auto{padding-right:auto}.ml-0{margin-left:0}.ml-1{margin-left:0.25rem}.ml-2{margin-left:0.5rem}.ml-3{margin-left:1rem}.ml-4{margin-left:1.5rem}.ml-5{margin-left:3rem}.ml-auto{margin-left:auto}.mr-0{margin-right:0}.mr-1{margin-right:0.25rem}.mr-2{margin-right:0.5rem}.mr-3{margin-right:1rem}.mr-4{margin-right:1.5rem}.mr-5{margin-right:3rem}.mr-auto{margin-right:auto}@keyframes spinner-border{to{transform:rotate(360deg) /* rtl:ignore */}}.spinner-border{display:inline-block;width:2rem;height:2rem;vertical-align:-.125em;border:.25em solid currentColor;border-right-color:transparent;border-radius:50%;animation:.75s linear infinite spinner-border}.spinner-border-sm{width:1rem;height:1rem;border-width:.2em}@keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1;transform:none}}.spinner-grow{display:inline-block;width:2rem;height:2rem;vertical-align:-.125em;background-color:currentColor;border-radius:50%;opacity:0;animation:.75s linear infinite spinner-grow}.spinner-grow-sm{width:1rem;height:1rem}@media (prefers-reduced-motion: reduce){.spinner-border,.spinner-grow{animation-duration:1.5s}}.loader-wrapper{display:flex;flex-direction:column;flex-grow:1;gap:1rem;align-items:center;justify-content:center}.loader-wrapper .loader{width:2rem;height:2rem;border-radius:50%;background:radial-gradient(farthest-side, #999d9e 94%, rgba(0,0,0,0)) center top/4px 4px no-repeat,conic-gradient(rgba(0,0,0,0) 15%, #999d9e);-webkit-mask:radial-gradient(farthest-side, rgba(0,0,0,0) calc(100% - 4px), #000 0)}.loader-wrapper.active .loader{animation:s3 1.5s infinite linear}@keyframes s3{to{transform:rotate(1turn)}}.loader-wrapper .loader-text{margin:0 auto;padding:0 0.833rem;overflow:hidden;color:var(--t42-content-color-muted);text-align:center;text-overflow:ellipsis}@keyframes clipMe{0%,100%{clip:rect(0, 220px, 2px, 0)}25%{clip:rect(0, 2px, 220px, 0)}50%{clip:rect(218px, 220px, 220px, 0)}75%{clip:rect(0, 220px, 220px, 218px)}}@keyframes spin{from{transform:rotate(0deg)}to{transform:rotate(360deg)}}.spinner{display:inline-block;animation-name:spin;animation-duration:3000ms;animation-timing-function:linear;animation-iteration-count:infinite}@font-face{font-weight:400;font-family:"Montserrat";font-style:normal;src:url(data:font/ttf;base64,AAEAAAARAQAABAAQR0RFRrFss1wAAmssAAACfkdQT1N2Wb7+AAJtrAABFy5HU1VCjJZZRgADhNwAAC8mT1MvMlYMpE4AAfmwAAAAYGNtYXBfILVpAAH6EAAACuRjdnQgMKUWggACEzwAAADkZnBnbU0kjnwAAgT0AAANbWdhc3AAAAAQAAJrJAAAAAhnbHlmzhsdpQAAARwAAct0aGVhZA5QtXgAAduUAAAANmhoZWEG0AwiAAH5jAAAACRobXR4v8HBsgAB28wAAB3AbG9jYfsbiDIAAcywAAAO4m1heHAIxQ5XAAHMkAAAACBuYW1lKqFFSQACFCAAAAHucG9zdFa6PIcAAhYQAABVE3ByZXDNS6zAAAISZAAAANUAAgAoAAACIwK8AAMABwApQCYAAAACAwACZQQBAwEBA1UEAQMDAV0AAQMBTQQEBAcEBxIREAUNFysTIREhJREhESgB+/4FAav+pQK8/URGAjD90AAAAv//AAAC3QK8AAcACgArQCgJAQQCAUoFAQQAAAEEAGYAAgJCSwMBAQFDAUwICAgKCAoREREQBgoYKyUhByMBMwEjJwMDAif+jE1nAT1jAT5pcJeXr68CvP1E/wFX/qn/////AAAC3QN3ACIABAAAAAMHEgKaAAD/////AAAC3QN3ACIABAAAAAMHGQKaAAD/////AAAC3QPhACIABAAAACcHMQKaAJYBBwcuApoBEQARsQIBsJawMyuxAwG4ARGwMysA//////88At0DdwAiAAQAAAAjBv8CmgAAAAMHGQKaAAD/////AAAC3QPhACIABAAAACcHMQKaAJYBBwctApoBEQARsQIBsJawMyuxAwG4ARGwMysA/////wAAAt0D7QAiAAQAAAAnBzECmgCWAQcHNAKaAP4AELECAbCWsDMrsQMBsP6wMyv/////AAAC3QPgACIABAAAACcHMQKaAJYBBwcyApoBEQARsQIBsJawMyuxAwG4ARGwMysA/////wAAAt0DdwAiAAQAAAADBxcCmgAA/////wAAAt0DdwAiAAQAAAADBxYCmgAA/////wAAAt0DvgAiAAQAAAAnBy8CmgCWAQcHLgNCAO4AELECAbCWsDMrsQMBsO6wMyv//////zwC3QN3ACIABAAAACMG/wKaAAAAAwcWApoAAP////8AAALdA74AIgAEAAAAJwcvApoAlgEHBy0DQgDuABCxAgGwlrAzK7EDAbDusDMr/////wAAAt0D0wAiAAQAAAAnBy8CmgCWAQcHNAMcAOQAELECAbCWsDMrsQMBsOSwMyv/////AAAC3QPmACIABAAAACcHLwKaAJYBBwcyApoBFwARsQIBsJawMyuxAwG4ARewMysA/////wAAAt0DdwAiAAQAAAADByMCmgAA/////wAAAt0DbQAiAAQAAAADBwoCmgAA//////88At0CvAAiAAQAAAADBv8CmgAA/////wAAAt0DdwAiAAQAAAADBxACmgAA/////wAAAt0DuwAiAAQAAAADByICmgAA/////wAAAt0DfQAiAAQAAAADByQCmgAA/////wAAAt0DVAAiAAQAAAADBx4CmgAA//////8gAvMCvAAiAAQAAAADBwMECAAA/////wAAAt0D1gAiAAQAAAEHBvACmgCqAAixAgKwqrAzK/////8AAALdBB0AIgAEAAABBwbxApoAqgAIsQICsKqwMyv/////AAAC3QN3ACIABAAAAAMHGgKaAAAAAv//AAAD3wK8AA8AEwBEQEEABQAGCQUGZQsBCQABBwkBZQgBBAQDXQADA0JLCgEHBwBdAgEAAEMATBAQAAAQExATEhEADwAPEREREREREQwKGyslFSE1IQcjASEVIRUhFSEVJxEjAwPf/gT+6mdnAaECMf51AV/+oWMU01dXr68CvFfXVeKoAWb+mv////8AAAPfA3cAIgAeAAAAAwcSA0AAAAADAGkAAALDArwADgAXAB8APEA5DgEEAgFKAAIABAUCBGUGAQMDAV0AAQFCSwcBBQUAXQAAAEMATBgYDw8YHxgeHRsPFw8WJyEkCAoXKwAWFRQGIyERITIWFRQGBwEVMzI2NTQmIxI2NTQjIxUzAn1GiYP+sgE6eIMzK/6NzU1TU01uVqvm5gFaWURbYgK8YFU3UBUBAOA5Nzc5/eY4PHXpAAABADD/+AKtAsQAGwAuQCsYFwsKBAIBAUoAAQEAXwAAAEhLAAICA18EAQMDSQNMAAAAGwAaJiQmBQoXKwQmJjU0NjYzMhYXByYjIgYGFRQWFjMyNxcGBiMBOalgYKppUogwQU92Tn5HR35OdVBBMIlSCF2jZmajXTc2P1NGe0xMe0ZUPzY4//8AMP/4Aq0DdwAiACEAAAADBxICxwAA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BwcDUQBzAAixAQGwc7AzK///AGn/LwLDArwAIgBSAAAAAwcEAsEAAP//AGkAAALDA3cAIgBSAAAAAwcXAsEAAP//AGkAAALDA3cAIgBSAAAAAwcWAsEAAP//AGn/PALDArwAIgBSAAAAAwb/AsEAAAABAGkAAADNArwAAwATQBAAAABCSwABAUMBTBEQAgoWKxMzESNpZGQCvP1EAAIAV//4Am0CvAAPABMAM0AwAwEABAIBAgACSgAEBAFdAwEBAUJLAAAAAl8FAQICSQJMAAATEhEQAA8ADhMlBgoWKwQmJzcWFjMyNjURMxEUBiMDMxEjAQN8MCcsaDdeYmSeiORkZAgmIVAeIG5vAY7+d5miAsT+eQD//wBQAAABUgN3ACIAWAAAAAMHEgHHAAD////5AAABPQN3ACIAWAAAAAMHGQHHAAD////oAAABTgN3ACIAWAAAAAMHFgHHAAD///+uAAABGwN3ACIAWAAAAAMHIwHHAAD//wALAAABKwNtACIAWAAAAAMHCgHHAAD//wAPAAABOQP0ACIAWAAAACcHKwHHAJYBBwcuAccBJAARsQECsJawMyuxAwG4ASSwMysA//8AYAAAANYDfQAiAFgAAAADBw4BxwAA//8AaP88AM4CvAAiAFgAAAADBv8BxwAA////5AAAAOYDdwAiAFgAAAADBxABxwAA//8APwAAAQADuwAiAFgAAAADByIBxwAA////+QAAAT0DfQAiAFgAAAADByQBxwAA//8AFgAAASADVAAiAFgAAAADBygBxwAA//8ATv8gAPECvAAiAFgAAAADByoB+AAA////8wAAAUMDdwAiAFgAAAADBxoBxwAAAAH/9//4AZ4CvAAQACxAKQMCAgABAUoAAQECXQACAkJLAAAAA18EAQMDSQNMAAAAEAAPERMkBQoXKxYmJzcWMzI2NREjNSERFAYjhGwhOjpYOz39AWBvbAg1MERTSEYBiVf+JXR1////9//4AaIDdwAiAGgAAAADBxYCGwAAAAEAaQAAAs4CvAALAB9AHAkGAQMAAQFKAgEBAUJLAwEAAEMATBISERIEChgrAQcVIxEzEQEzAQEjAU2AZGQBfHL+1QE+dQE3grUCvP55AYf+xf5///8AaQAAAs4DdwAiAGoAAAADBxcCowAA//8Aaf75As4CvAAiAGoAAAADBwECowAA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KAcKGSsBERQGBwYVFBYzMjY3FwYjIiY1NDcmJjURMxEUMzI2NRECs15XkCIcECEMEygyOEBFf41kxWBmArz+cnaSHjNJGBwJCDEYNy5DMQifjgGO/nbhb3IBigD//wBj//gCswPWACIAxwAAAQcG8AK4AKoACLEBArCqsDMr//8AY//4ArMDdwAiAMcAAAADBxoCuAAA//8AY//4ArMD9AAiAMcAAAAnBzICuACWAQcHLgK4ASQAEbEBAbCWsDMrsQIBuAEksDMrAAAB//8AAALJArwABgAhQB4FAQABAUoDAgIBAUJLAAAAQwBMAAAABgAGEREEChYrAQEjATMTEwLJ/s1j/sxs/P4CvP1EArz9wQI/AAEAIAAABEYCvAAMACdAJAsIAwMAAgFKBQQDAwICQksBAQAAQwBMAAAADAAMEhESEQYKGCsBAyMDAyMDMxMTMxMTBEbqab+/a+pnvcVcwcECvP1EAi/90QK8/ccCOf3EAjz//wAgAAAERgN3ACIA4AAAAAMHEgNgAAD//wAgAAAERgN3ACIA4AAAAAMHFgNgAAD//wAgAAAERgNtACIA4AAAAAMHCgNgAAD//wAgAAAERgN3ACIA4AAAAAMHEANgAAAAAQANAAAClAK8AAsAJkAjCgcEAQQAAQFKAgEBAUJLBAMCAABDAEwAAAALAAsSEhIFChcrIQMDIwEDMxMTMwMBAiHSz3MBB/dyxMJt9wEJASH+3wFnAVX+8wEN/q7+lgAAAf/8AAACiwK8AAgAHUAaBgMAAwABAUoCAQEBQksAAABDAEwSEhEDChcrJRUjNQEzExMzAXVj/upr4OFj8vL0Acj+jwFx/////AAAAosDdwAiAOYAAAADBxICcAAA/////AAAAosDdwAiAOYAAAADBxYCcAAA/////AAAAosDbQAiAOYAAAADBwoCcAAA/////AAAAosDfQAiAOYAAAADBw4CcAAA/////P88AosCvAAiAOYAAAADBv8CcAAA/////AAAAosDdwAiAOYAAAADBxACcAAA/////AAAAosDuwAiAOYAAAADByICcAAA/////AAAAosDVAAiAOYAAAADBx4CcAAA/////AAAAosDdwAiAOYAAAADBxoCcAAAAAEAKwAAAnQCvAAJAC9ALAgBAQIDAQADAkoAAQECXQACAkJLBAEDAwBdAAAAQwBMAAAACQAJERIRBQoXKyUVITUBITUhFQECdP23Abj+TwI1/kpXV0QCIVdE/d///wArAAACdAN3ACIA8AAAAAMHEgJ8AAD//wArAAACdAN3ACIA8AAAAAMHFwJ8AAD//wArAAACdAN9ACIA8AAAAAMHDgJ8AAD//wAr/zwCdAK8ACIA8AAAAAMG/wKCAAAABABX//oC/QN3AAMABwAXABsAQ0BACwEECAoBBgQCSgIBAAEAgwMBAQUBgwAICAVdBwEFBUJLAAQEBl8JAQYGTAZMCAgbGhkYCBcIFhMmEREREAoKGisTMwcjJTMHIwAmJzcWFjMyNjURMxEUBiMDMxEj7mmoSgIvaahK/vh8MCcrZzRgZWSeiORkZAN3goKC/QUnIk8fIG5vAYz+eJejAsL+eQACAGMAAAK9AsQADAAVADJALwcBBQABAAUBZQAEBANfBgEDAyVLAgEAACEATA0NAAANFQ0VEhAADAALERETCAcXKwAWFREjNSEVIxE0NjMTNTQmIyIGFRUCG6Jk/mxioorKa19fawLEo5j+d8HBAYmYo/5Uemtubmt6//8AYwAAAr0DdwAiAPYAAAADBxICuwAA//8AYwAAAr0DdwAiAPYAAAADBxkCuwAA//8AYwAAAr0D4QAiAPYAAAAnBzECuwCWAQcHLgK7AREAEbECAbCWsDMrsQMBuAERsDMrAP//AGP/PAK9A3cAIgD2AAAAIwb/ArsAAAADBxkCuwAA//8AYwAAAr0D4QAiAPYAAAAnBzECuwCWAQcHLQK7AREAEbECAbCWsDMrsQMBuAERsDMrAP//AGMAAAK9A+0AIgD2AAAAJwcxArsAlgEHBzQCuwD+ABCxAgGwlrAzK7EDAbD+sDMr//8AYwAAAr0D4AAiAPYAAAAnBzECuwCWAQcHMgK7AREAEbECAbCWsDMrsQMBuAERsDMrAP//AGMAAAK9A3cAIgD2AAAAAwcXArsAAP//AGMAAAK9A3cAIgD2AAAAAwcWArsAAP//AGMAAALVA74AIgD2AAAAJwcvArsAlgEHBy4DYwDuABCxAgGwlrAzK7EDAbDusDMr//8AY/88Ar0DdwAiAPYAAAAjBv8CuwAAAAMHFgK7AAD//wBjAAACvQO+ACIA9gAAACcHLwK7AJYBBwctA2MA7gAQsQIBsJawMyuxAwGw7rAzK///AGMAAAK9A9MAIgD2AAAAJwcvArsAlgEHBzQDPQDkABCxAgGwlrAzK7EDAbDksDMr//8AYwAAAr0D5gAiAPYAAAAnBy8CuwCWAQcHMgK7ARcAEbECAbCWsDMrsQMBuAEXsDMrAP//AGMAAAK9A3cAIgD2AAAAAwcjArsAAP//AGMAAAK9A20AIgD2AAAAAwcKArsAAP//AGP/PAK9AsQAIgD2AAAAAwb/ArsAAP//AGMAAAK9A3cAIgD2AAAAAwcQArsAAP//AGMAAAK9A7sAIgD2AAAAAwciArsAAP//AGMAAAK9A30AIgD2AAAAAwckArsAAP//AGMAAAK9A1QAIgD2AAAAAwceArsAAP//AGP/IALTAsQAIgD2AAAAAwcDA+gAAP//AGMAAAK9A9YAIgD2AAABBwbwArsAqgAIsQICsKqwMyv//wBjAAACvQQdACIA9gAAAQcG8QK7AKoACLECArCqsDMr//8AYwAAAr0DdwAiAPYAAAADBxoCuwAAAAIAWgAABAsCvAASABkAfkuwLlBYQCkABQAGCQUGZQsBCQABBwkBZQgBBAQDXQADAyBLCgEHBwBdAgEAACEATBtALwAIBAUECHAABQAGCQUGZQsBCQABBwkBZQAEBANdAAMDIEsKAQcHAF0CAQAAIQBMWUAYExMAABMZExkWFAASABIREREjERERDAcbKyUVITUhFSMRNDYzIRUhFSEVIRUnESMiBhUVBAv+A/6wZJiNAn7+cwFh/p9iiGNlVVXLywGJk6BV21HmygFDb2xoAP//AFoAAAQLA3cAIgEQAAAAAwcSA0AAAP//AGkAAAWRA3cAIgAoAAAAIwGFAxgAAAADBxcFlgAA//8AaQAABSMC4QAiACgAAAAjAtUDOgAAAAMG7QVuAAAAAQAz//gCcgLEACkAO0A4FAECARUBAwIKAQQDKQEFBARKAAMABAUDBGUAAgIBXwABASVLAAUFAF8AAAAmAEwkISQkLCIGBxorJQYGIyImJjU0NjcmJjU0NjYzMhYXByYjIgYVFBYzMxUjIgYVFBYzMjY3AnItklZghkRFNywyP4BcQXstHVpuW2BKRbS4T1pmZUZ/KUkmKzNaOzxXExRRNTdYNRwaUDBBNDQ4Vjg4OUAnIgD//wAz//gCcgN3ACIBFAAAAAMHEgKKAAD//wAz//gCcgN3ACIBFAAAAAMHGQKKAAD//wAz//gCcgN3ACIBFAAAAAMHFwKKAAD//wAz/yACcgN3ACIBFAAAACMHAgKKAAAAAwcZAooAAP//ADP/+AJyA3cAIgEUAAAAAwcWAooAAP//ADP/+AKkA74AIgEUAAAAJwcvAooAlgEHBy4DMgDuABCxAQGwlrAzK7ECAbDusDMr//8AM/88AnIDdwAiARQAAAAjBv8CigAAAAMHFgKKAAD//wAz//gCcgO+ACIBFAAAACcHLwKKAJYBBwctAzIA7gAQsQEBsJawMyuxAgGw7rAzK///ADP/+AJyA9MAIgEUAAAAJwcvAooAlgEHBzQDDADkABCxAQGwlrAzK7ECAbDksDMr//8AM//4AnID5gAiARQAAAAnBy8CigCWAQcHMgKKARcAEbEBAbCWsDMrsQIBuAEXsDMrAP//ADP/+AJyA3cAIgEUAAAAAwcjAooAAP//ADP/+AJyA20AIgEUAAAAAwcKAooAAP//ADP/+AJyA30AIgEUAAAAAwcOAooAAP//ADP/PAJyAsQAIgEUAAAAAwb/AooAAP//ADP/+AJyA3cAIgEUAAAAAwcQAooAAP//ADP/+AJyA7sAIgEUAAAAAwciAooAAP//ADP/+AJyA30AIgEUAAAAAwckAooAAP//ADP/+AJyA1QAIgEUAAAAAwceAooAAP//ADP/+AJyA/QAIgEUAAAAJwczAooAlgEHBy4CigEkABGxAQGwlrAzK7ECAbgBJLAzKwD//wAz//gCcgP0ACIBFAAAACcHMwKKAJYBBwctAooBJAARsQEBsJawMyuxAgG4ASSwMysAAAEAM/8gAnICxAA5AIxAHx0BAwIeAQQDEwEFBDIBBgUzCgIBBgIBBwEDAQAHB0pLsBRQWEAoAAQABQYEBWUAAwMCXwACAiVLAAYGAV8AAQEmSwgBBwcAXwAAACkATBtAJQAEAAUGBAVlCAEHAAAHAGMAAwMCXwACAiVLAAYGAV8AAQEmAUxZQBAAAAA5ADgkISQkLCUkCQcbKwQ2NxcGIyImNTQ3BiMiJiY1NDY3JiY1NDY2MzIWFwcmIyIGFRQWMzMVIyIGFRQWMzI2NxcGBhUUFjMCJyEMEygyOEA2NTlghkRFNywyP4BcQXstHVpuW2BKRbS4T1pmZUV/KiJWQyIcqAkIMRg3LkU5CzNaOzxXExRRNTdYNRwaUDBBNDQ4Vjg4OUAoIU86WiYaHAD//wAz//gCcgN3ACIBFAAAAAMHGgKKAAAAAQBjAAACTwLEABIAM0AwDwEEAxABAAQCSgAAAAECAAFlBQEEBANfAAMDJUsAAgIhAkwAAAASABEjERETBgcYKwAGFRUhFSERIxE0NjMyFhcHJiMBKGEBQP7AZJmJPGgmIUNjAmtXU1BW/uUBwnmJGxpTLwABADD/+AK0AsQAHwBoQA8SEQIABB8BBQAEAQEFA0pLsB1QWEAhAAQEA18AAwMlSwAAAAFfAgEBASFLAAUFAV8CAQEBIQFMG0AfAAQEA18AAwMlSwAAAAFdAAEBIUsABQUCXwACAiYCTFlACSYkJiIREAYHGisBMxEjNQYjIiYmNTQ2NjMyFhcHJiMiBgYVFBYWMzI2NwJOYFhNdl+jYWGra1SJMD5Ud1B/SEl4RjFdJQFi/p4vN1ShbmikXTc1PlFGfE5Tej8hIAD//wAw//gCtAN3ACIBLAAAAAMHGQLGAAD//wAw//gCtAN3ACIBLAAAAAMHFwLGAAD//wAw//gCtAN3ACIBLAAAAAMHFgLGAAD//wAw/voCtALEACIBLAAAAQcHAQLBAAEACLEBAbABsDMr//8AMP/4ArQDfQAiASwAAAADBw4CxgAA//8AMP/4ArQDVAAiASwAAAADBx4CxgAA//8AMP/4AxECxAAiASwAAAFHByUDcf+JPUxAAAAJsQEBuP+JsDMrAAABACsAAAGdArwACwApQCYGBQIDAwRdAAQEIEsCAQAAAV0AAQEhAUwAAAALAAsREREREQcHGSsBETMVITUzESM1IRUBFof+joeHAXICZf3yV1cCDldXAAIAV/+UAm0CvAAPABMAMEAtAwEABAIBAgACSgAABQECAAJjAAQEAV0DAQEBIARMAAATEhEQAA8ADhMlBgcWKwQmJzcWFjMyNjURMxEUBiMDMxEjAQN8MCcsaDdeYmSeiORkZGwmIVAeIG5vAfL+E5miAyj+Ff//ACsAAAGdA3cAIgE0AAAAAwcSAhEAAAAEAFf/lgL9A3cAAwAHABcAGwBAQD0LAQQICgEGBAJKAgEAAQCDAwEBBQGDAAQJAQYEBmMACAgFXQcBBQUgCEwICBsaGRgIFwgWEyYREREQCgcaKxMzByMlMwcjACYnNxYWMzI2NREzERQGIwMzESPuaahKAi9pqEr++HwwJytnNGBlZJ6I5GRkA3eCgoL8oSciTx8gbm8B8P4Ul6MDJv4VAP//ACsAAAGdA3cAIgE0AAAAAwcZAhEAAP//ACsAAAGdA3cAIgE0AAAAAwcWAhEAAP////gAAAGdA3cAIgE0AAAAAwcjAhEAAP//ACsAAAGdA20AIgE0AAAAAwcKAhEAAP//ACsAAAGdA/QAIgE0AAAAJwcrAhEAlgEHBy4CEQEkABGxAQKwlrAzK7EDAbgBJLAzKwD//wArAAABnQN9ACIBNAAAAAMHDgIRAAD//wAr/zwBnQK8ACIBNAAAAAMG/wIRAAD//wArAAABnQN3ACIBNAAAAAMHEAIRAAD//wArAAABnQO7ACIBNAAAAAMHIgIRAAD//wArAAABnQN9ACIBNAAAAAMHJAIRAAD//wArAAABnQNUACIBNAAAAAMHHgIRAAD//wAr/yABnQK8ACIBNAAAAAMHKgJBAAD//wArAAABnQN3ACIBNAAAAAMHGgIRAAAAAf/3/5QBnAK8AA8AKUAmAwICAAEBSgAABAEDAANjAAEBAl0AAgIgAUwAAAAPAA4REiQFBxcrFiYnNxYzMjURIzUhERQGI4JpIjg6Vnn8AWBvbWw1MERTjgHtV/3BdHX////3/5QBnwN3ACIBRQAAAAMHFgIYAAD//wBp/5QEDAK8ACIAbQAAAAMBRQJwAAAAAQBpAAAEZwLEACIAVrYfGQIAAQFKS7AdUFhAFgMBAQEFXwgHBgMFBSBLBAICAAAhAEwbQBoABQUgSwMBAQEGXwgHAgYGJUsEAgIAACEATFlAEAAAACIAISMREyMTIxMJBxsrABYVESMRNCYjIgYVESMRNCYjIgYVESMRMxU2NjMyFhc2NjMD34hjYE9XZWNbT1hnZGAfcUtOcRsheU4CxIyF/k0BsFxfY2b+XgGwXV5kZf5eArxmNDo+Nzg9//8Aaf88BGcCxAAiAUgAAAADBv8DlQAAAAEAaQAAArsCxAASAEy1EAEAAQFKS7AdUFhAEwABAQNfBQQCAwMgSwIBAAAhAEwbQBcAAwMgSwABAQRfBQEEBCVLAgEAACEATFlADQAAABIAERETIxMGBxgrABYVESMRNCYjIgYVESMRMxU2MwItjmNkWWBuZGBHnwLEmI3+YQGcZmlwbv5zArxjawD//wBp/5QEugLEACIBSgAAAAMBRQMeAAD//wBpAAACuwN3ACIBSgAAAAMHEgK+AAD//wBpAAACuwN3ACIBSgAAAAMHFwK+AAD//wBp/vkCuwLEACIBSgAAAAMHAQK9AAD//wBpAAACuwN9ACIBSgAAAAMHDgK+AAD//wBp/zwCuwLEACIBSgAAAAMG/wK9AAAAAQBp/zgCuwLEABwAaEAOGgEDAgoBAQMJAQABA0pLsB1QWEAcAAICBF8GBQIEBCBLAAMDIUsAAQEAXwAAACkATBtAIAAEBCBLAAICBV8GAQUFJUsAAwMhSwABAQBfAAAAKQBMWUAOAAAAHAAbERMkJCUHBxkrABYVERQGIyImJzcWMzI1ETQmIyIGFREjETMVNjMCLY5uazZfITE1T3dkWWBuZGBHnwLEmI3+g3V1KSZLQ5ABfWZpcG7+cwK8Y2v//wBp/zgD7wL1ACIBSgAAACMB8AMeAAAAAwcpBNoAAP//AGn/UgK7AsQAIgFKAAAAAwcFAr0AAP//AGkAAAK7A3cAIgFKAAAAAwcaAr4AAAACADD/eQMYAsQAEgAlACVAIiUiBgMEAAMBSgADAAADAGEAAgIBXwABASUCTBgqKBQEBxgrAAYGBxUjNS4CNTQ2NjMyFhYVADY2NTQmJiMiBgYVFBYWFzUzFQMYUpNdZF6SUmGqammqYP78ZjpHfExNfUc5ZkJdAQCaYQqCggthml1lpF1do2b/AElzREx7RkZ7TERxSgqlpgAAAgBF//gDAQLEABUAIAAwQC0ZEhELCgUDAQFKAAEBAl8EAQICJUsAAwMAXwAAACYATAAAHRsAFQAUJSYFBxYrABYWFRQGBiMiJiclJiYjIgYHJzY2MwE0JwUWFjMyNjY1AfunX16kZni1JwJBH4NSQHIqPDKSVQEKAf4oH25ITHZCAsRdo2VmpF1+b+pHVSkpRTA2/p4TCcE1OkR5TgAB//wAAAJaAsQADAAdQBoMCAcFAgUAAQFKAAEBJUsAAAAhAEwlEwIHFisBJicRIxEGByc2MzIXAjdmdGN1ZiOGqKqGAiU6C/2WAmoLOk9QUAD////8AAACWgLEACIBVwAAAQcHJQJW/+YACbEBAbj/5rAzKwD////8AAACWgN3ACIBVwAAAAMHFwJZAAD////8/yACWgLEACIBVwAAAAMHAgJXAAD////8/vkCWgLEACIBVwAAAAMHAQJXAAD////8/zwCWgLEACIBVwAAAAMG/wJXAAD////8/1ICWgLEACIBVwAAAAMHBQJXAAAAAQBj//gCsQK8ABIATLUDAQMCAUpLsB1QWEATBQQCAgIgSwADAwBfAQEAACEATBtAFwUEAgICIEsAAAAhSwADAwFfAAEBJgFMWUANAAAAEgASIxMiEQYHGCsBESM1BiMiJjURMxEUFjMyNjURArFgR519jWRkV15uArz9RGNrmI0Bn/5kZWpwbgGNAP//AGP/+AKxA3cAIgFeAAAAAwcSArQAAP//AGP/+AKxA3cAIgFeAAAAAwcZArQAAP//AGP/+AKxA3cAIgFeAAAAAwcXArQAAP//AGP/+AKxA3cAIgFeAAAAAwcWArQAAP//AGP/+AKxA3cAIgFeAAAAAwcjArQAAP//AGP/+AKxA20AIgFeAAAAAwcKArQAAP//AGP/PAKxArwAIgFeAAAAAwb/ArQAAP//AGP/+AKxA3cAIgFeAAAAAwcQArQAAP//AGP/+AKxA7sAIgFeAAAAAwciArQAAP//AGP/+AMTA1MAIgFeAAABBwb+A7oAqgAIsQEBsKqwMyv//wBj//gDEwN3ACIBXgAAACcG/gO6AKoBAwcSArQAAAAIsQEBsKqwMyv//wBj/zwDEwNTACIBXgAAACcG/gO6AKoBAwb/ArQAAAAIsQEBsKqwMyv//wBj//gDEwN3ACIBXgAAACcG/gO6AKoBAwcQArQAAAAIsQEBsKqwMyv//wBj//gDEwO7ACIBXgAAACcG/gO6AKoBAwciArQAAAAIsQEBsKqwMyv//wBj//gDEwN3ACIBXgAAACcG/gO6AKoBAwcaArQAAAAIsQEBsKqwMyv//wBj//gCsQN3ACIBXgAAAAMHFQK0AAD//wBj//gCsQN9ACIBXgAAAAMHJAK0AAD//wBj//gCsQNUACIBXgAAAAMHHgK0AAD//wBj//gCsQP4ACIBXgAAACcHMwK0AJcBBwcrArQBJQARsQEBsJewMyuxAgK4ASWwMysA//8AY/8gAscCvAAiAV4AAAADBwMD3AAA//8AY//4ArED1gAiAV4AAAEHBvACtACqAAixAQKwqrAzK///AGP/+AKxA3cAIgFeAAAAAwcaArQAAP//AGP/+AKxA/QAIgFeAAAAJwcyArQAlgEHBy4CtAEkABGxAQGwlrAzK7ECAbgBJLAzKwAAAQBj//gEQwK8AB4ALUAqBwEDAgFKBwYEAwICIEsFAQMDAF8BAQAAJgBMAAAAHgAeIxMiEyQjCAcaKwERFAYjIiYnBgYjIiY1ETMRFDMyNjURMxEUFjMyNREEQ42DTXUfIHJOg4xkq1NcZFtTrAK8/luOkTcwMDeRjgGl/l7JYmcBov5eZ2LJAaL//wBj//gEQwN3ACIBdgAAAAMHEgN+AAD//wBj//gEQwN3ACIBdgAAAAMHFgN+AAD//wBj//gEQwNtACIBdgAAAAMHCgN+AAD//wBj//gEQwN3ACIBdgAAAAMHEAN+AAAAAQBe/5YCsAK8ABwAM0AwDQEEAwgHAgECAkoABAACAQQCZwABAAABAGMGBQIDAyADTAAAABwAHCMTIyQjBwcZKwERFAYjIiYnNxYzMjU1BiMiJjU1MxUUFjMyNjU1ArCij1aNMCtcjM5Gk4SSZGRZYG4CvP4UmKI1MU5a3EdmmI3q5mZqcG/X//8AXv+WArADdwAiAXsAAAADBxICswAA//8AXv+WArADdwAiAXsAAAADBxYCswAA//8AXv+WArADbQAiAXsAAAADBwoCswAA//8AXv+WArADfQAiAXsAAAADBw4CswAA//8AXv88AsoCvAAiAXsAAAADBv8DwwAA//8AXv+WArADdwAiAXsAAAADBxACswAA//8AXv+WArADuwAiAXsAAAADByICswAA//8AXv+WArADVAAiAXsAAAADBx4CswAA//8AXv+WArADdwAiAXsAAAADBxoCswAAAAEAMAAAAnkCvAARAD1AOgwBAwQDAQAHAkoFAQIGAQEHAgFlAAMDBF0ABAQgSwgBBwcAXQAAACEATAAAABEAERESEREREhEJBxsrJRUhNTcjNTM3ITUhFQczFSMHAnn9t8mNz6r+TwI2wILEsldXPv1T11c981Pi//8AMAAAAnkDdwAiAYUAAAADBxICfgAA//8AMAAAAnkDdwAiAYUAAAADBxcCfgAA//8AMAAAAnkDfQAiAYUAAAADBw4CfgAA//8AMP88AnkCvAAiAYUAAAADBv8CgwAAAAIAMv/6Af8CFwAaACQAeEAPFwEDBBYBAgMdBQIGBQNKS7AnUFhAIAACAAUGAgVlAAMDBF8HAQQES0sIAQYGAF8BAQAAQwBMG0AkAAIABQYCBWUAAwMEXwcBBARLSwAAAENLCAEGBgFfAAEBTAFMWUAVGxsAABskGyMgHgAaABkjJCMTCQoYKwAWFREjNQYGIyImNTQ2MzM1NCYjIgYHJzY2MxI2NzUjIhUUFjMBinVbGFk9WWtmb5hIRi9aHygpckAhUBKUej43Ahdsa/7ARiUnVkZGVRM+Qh8aSCEj/i0xLUpSKC7//wAy//oB/wLhACIBigAAAAMG5wJPAAD//wAy//oB/wLhACIBigAAAAMG7wJPAAD//wAy//oB/wNLACIBigAAACMHMQJPAAABBwcuAk8AewAIsQMBsHuwMyv//wAy/zwB/wLhACIBigAAACMG/wJNAAAAAwbvAk8AAP//ADL/+gH/A0sAIgGKAAAAIwcxAk8AAAEHBy0CTwB7AAixAwGwe7AzK///ADL/+gH/A1cAIgGKAAAAIwcxAk8AAAEHBzQCTwBoAAixAwGwaLAzK///ADL/+gH/A0oAIgGKAAAAIwcxAk8AAAEHBzICTwB7AAixAwGwe7AzK///ADL/+gH/AuEAIgGKAAAAAwbtAk8AAP//ADL/+gH/AuEAIgGKAAAAAwbsAk8AAP//ADL/+gJpAygAIgGKAAAAIwcvAk8AAAEHBy4C9wBYAAixAwGwWLAzK///ADL/PAH/AuEAIgGKAAAAIwb/Ak0AAAADBuwCTwAA//8AMv/6AhADKAAiAYoAAAAjBy8CTwAAAQcHLQL3AFgACLEDAbBYsDMr//8AMv/6Af8DPQAiAYoAAAAjBy8CTwAAAQcHNALRAE4ACLEDAbBOsDMr//8AMv/6Af8DUAAiAYoAAAAjBy8CTwAAAQcHMgJPAIEACLEDAbCBsDMr//8AMv/6Af8C4QAiAYoAAAADBvsCTwAA//8AMv/6Af8C1wAiAYoAAAADBt8CTwAA//8AMv88Af8CFwAiAYoAAAADBv8CTQAA//8AMv/6Af8C4QAiAYoAAAADBuUCTwAA//8AMv/6Af8DJQAiAYoAAAADBvoCTwAA//8AMv/6Af8C5wAiAYoAAAADBvwCTwAA//8AMv/6Af8CvgAiAYoAAAADBvYCTwAA//8AMv8gAhUCFwAiAYoAAAADBwMDKgAA//8AMv/6Af8DLAAiAYoAAAADBvACTwAA//8AMv/6Af8DcwAiAYoAAAADBvECTwAA//8AMv/6Af8C4QAiAYoAAAADBvICTwAAAAMAMv/6A7MCFwAsADMAPQCPQBEgAQUGJR8CBAUOCAcDAQADSkuwGFBYQCUIAQQKAQABBABlDAkCBQUGXwcBBgZLSw0LAgEBAl8DAQICTAJMG0AvCAEECgEAAQQAZQwJAgUFBl8HAQYGS0sAAQECXwMBAgJMSw0BCwsCXwMBAgJMAkxZQBo0NC0tND00PDk3LTMtMhYjJSMkJCQiEQ4KHSskByEWFjMyNxcGBiMiJicGBiMiJjU0NjMzNTQmIyIGByc2NjMyFzY2MzIWFhUkBgchJiYjADY1NSMiFRQWMwOzA/5QCGhQXTw2JWtCSngnH3BFYG5mb5hHRjBaHygpcj+TMiNpP0t5RP63YAkBUwhhQf6kUZR6Pzj5DkdWQD4qLDU2ODNYSEJUFD5CHxpIISNeLDJFeky6UEZGUP5+SD0iTyou//8AMv/6A7MC4QAiAaQAAAADBucC+wAAAAIAW//6AoAC5gASACIAaLYPCgIFBAFKS7AnUFhAHQACAkRLAAQEA18GAQMDS0sHAQUFAF8BAQAATABMG0AhAAICREsABAQDXwYBAwNLSwABAUNLBwEFBQBfAAAATABMWUAUExMAABMiEyEbGQASABEREyYIChcrABYWFRQGBiMiJicVIxEzETY2MxI2NjU0JiYjIgYGFRQWFjMBwXpFRXpNO2IgXGAgYDkrUS8vUTMyUi4uUjICF0R6UFB7RC4sVALm/twqK/43L1U3N1UuLlU3N1UvAAABACr/+gIaAhcAHQAuQCsaGQsKBAIBAUoAAQEAXwAAAEtLAAICA18EAQMDTANMAAAAHQAcJiUmBQoXKxYmJjU0NjYzMhYXByYmIyIGBhUUFhYzMjY3FwYGI/F/SEh/UUhxH0kZSi00Uy8vUzQtShlJH3FIBkZ7Tk57RTo3LyYmLlU3OFUuJiYuNzsA//8AKv/6AhoC4QAiAacAAAADBucCWwAA//8AKv/6AhoC4QAiAacAAAADBu0CWwAA//8AKv8gAhoCFwAiAacAAAADBwICWAAA//8AKv8gAhoC4QAiAacAAAAjBwICWAAAAAMG5wJbAAD//wAq//oCGgLhACIBpwAAAAMG7AJbAAD//wAq//oCGgLnACIBpwAAAAMG4wJbAAAAAgAq//oCTwLmABIAIgBothEDAgUEAUpLsCdQWEAdBgEDA0RLAAQEAl8AAgJLSwcBBQUAXwEBAABDAEwbQCEGAQMDREsABAQCXwACAktLAAAAQ0sHAQUFAV8AAQFMAUxZQBQTEwAAEyITIRsZABIAEiYjEQgKFysBESM1BgYjIiYmNTQ2NjMyFhcRAjY2NTQmJiMiBgYVFBYWMwJPXCBiO016RUV6TTlgIH9SLi5SMjNRLy9RMwLm/RpULC5Ee1BQekQrKgEk/WgvVTc3VS4uVTc3VS8AAAIAKv/4AlYC1gAjADEAckAaISAcAwIDIxsXFhUUBgECEAEFBANKIgECAUlLsB9QWEAeAAEABAUBBGcAAgIDXwADA0RLBgEFBQBfAAAASQBMG0AcAAMAAgEDAmcAAQAEBQEEZwYBBQUAXwAAAEkATFlADiQkJDEkMCsjKiYkBwoZKwAVFAYGIyImJjU0NjYzMhYXNjU0JwUnNyYjIgcnNjMyFzcXBwI2NjU0JiYjIgYVFBYzAlZHiWBHc0JCdElEaR4BUP71GtksMk5DEElYdVJZGjicTykrSzBOWlpIAguybJ9WN2ZDQ2U3NzQMFpVIaz9YDhdSFjUkQBb92ihBJihBJU5AQE8A//8AKv/6AvcDBwAiAa4AAAEHBusD1AAqAAixAgGwKrAzK///ACr/+gKqAuYAIgGuAAABBwcGAxAAxAAIsQIBsMSwMyv//wAq/zwCTwLmACIBrgAAAAMG/wKHAAD//wAq/1ICTwLmACIBrgAAAAMHBQKHAAD//wAq//oEiwLmACIBrgAAACMCeQKnAAAAAwbtBNkAAAACACr/+gI6AhcAFwAeADZAMwgHAgEAAUoABAAAAQQAZQYBBQUDXwADA0tLAAEBAl8AAgJMAkwYGBgeGB0WJiQiEQcKGSskByEWFjMyNxcGBiMiJiY1NDY2MzIWFhUkBgchJiYjAjoC/lIJaU5fOjUka0JUgkdFeUxMd0P+tV0IAVQIXUX7EkZVQD4qLEV8Tk18RUV8UMBURENVAP//ACr/+gI6AuEAIgG1AAAAAwbnAl8AAP//ACr/+gI6AuEAIgG1AAAAAwbvAl8AAP//ACr/+gI6AuEAIgG1AAAAAwbtAl8AAP//ACr/IAI6AuEAIgG1AAAAIwcCAl8AAAADBu8CXwAA//8AKv/6AjoC4QAiAbUAAAADBuwCXwAA//8AKv/6AnkDKAAiAbUAAAAjBy8CXwAAAQcHLgMHAFgACLEDAbBYsDMr//8AKv88AjoC4QAiAbUAAAAjBv8CXwAAAAMG7AJfAAD//wAq//oCOgMoACIBtQAAACMHLwJfAAABBwctAwcAWAAIsQMBsFiwMyv//wAq//oCOgM9ACIBtQAAACMHLwJfAAABBwc0AuEATgAIsQMBsE6wMyv//wAq//oCOgNQACIBtQAAACMHLwJfAAABBwcyAl8AgQAIsQMBsIGwMyv//wAq//oCOgLhACIBtQAAAAMG+wJfAAD//wAq//oCOgLXACIBtQAAAAMG3wJfAAD//wAq//oCOgLnACIBtQAAAAMG4wJfAAD//wAq/zwCOgIXACIBtQAAAAMG/wJfAAD//wAq//oCOgLhACIBtQAAAAMG5QJfAAD//wAq//oCOgMlACIBtQAAAAMG+gJfAAD//wAq//oCOgLnACIBtQAAAAMG/AJfAAD//wAq//oCOgK+ACIBtQAAAAMG9gJfAAD//wAq//oCOgNeACIBtQAAACMHMwJfAAABBwcuAl8AjgAIsQMBsI6wMyv//wAq//oCOgNeACIBtQAAACMHMwJfAAABBwctAl8AjgAIsQMBsI6wMysAAgAq/yACOgIXACoAMQCAQBMIBwIBABwBBAEUAQIEFQEDAgRKS7AUUFhAKAAGAAABBgBlCAEHBwVfAAUFS0sAAQEEXwAEBExLAAICA18AAwNNA0wbQCUABgAAAQYAZQACAAMCA2MIAQcHBV8ABQVLSwABAQRfAAQETARMWUAQKysrMSswFiYlJCoiEQkKGyskByEWFjMyNxcGBgcGBhUUFjMyNjcXBiMiJjU0NwYjIiYmNTQ2NjMyFhYVJAYHISYmIwI6Av5SCWlOXzo1CRkFPzIiHBAhDBMoMjdBMRgOVIJHRXlMTHdD/rVdCAFUCF1F+xJGVUA+ChYENUkfGxwJCDEYOTA+NQJFfE5NfEVFfFDAVERDVf//ACr/+gI6AuEAIgG1AAAAAwbyAl8AAP//ACr/+wI6AhgBDwG1AmQCEsAAAAmxAAK4AhKwMysA////7P83Ae4CEgACBWUAAP///+z/NwHuAuEAIgVlAAAAAwbtAg4AAAABAA8AAAGEAuwAFQA5QDYSAQYFEwEABgJKBwEGBgVfAAUFREsDAQEBAF0EAQAARUsAAgJDAkwAAAAVABQjERERERIIChorEhUVMxUjESMRIzUzNTQ2MzIWFwcmI8eamGBaWlxTIDgUHSEpAp1dLk/+PQHDTy9PXBAPSRkAAgAq/zgCVgIXAB4ALACmQBIdAQYFDwECBggBAQIHAQABBEpLsBZQWEAiAAUFA18HBAIDA0tLCAEGBgJfAAICQ0sAAQEAXwAAAE0ATBtLsC5QWEAgCAEGAAIBBgJnAAUFA18HBAIDA0tLAAEBAF8AAABNAEwbQCQIAQYAAgEGAmcHAQQERUsABQUDXwADA0tLAAEBAF8AAABNAExZWUAVHx8AAB8sHysmJAAeAB4mJSUjCQoYKwERFAYjIiYnNxYWMzI2NTUGBiMiJiY1NDY2MzIWFzUCNjY1NCYjIgYVFBYWMwJWiolLiCouJW06XVkiYzpMe0ZGe0w8ZyGFUy9mUFFmL1M1AhL+NouFKSZKICVYWiopKUF1S0t1QCwrUv5YLE8yTV9fTTJPLAD//wAq/zgCVgLhACIB0AAAAAMG7wJ1AAD//wAq/zgCVgLhACIB0AAAAAMG7QJ1AAD//wAq/zgCVgLhACIB0AAAAAMG7AJ1AAD//wAq/zgCVgMXACIB0AAAAAMG/QJ1AAD//wAq/zgCVgLnACIB0AAAAAMG4wJ1AAD//wAq/zgCVgK+ACIB0AAAAAMG9gJ1AAAAAgAq/zgClgIXACYANACMQBIgAQoJEgEFCgcBAAQGAQECBEpLsC5QWEApCwEKAAUECgVnCAEEAwEAAgQAZgAJCQZfBwEGBktLAAICAV8AAQFNAUwbQC0LAQoABQQKBWcIAQQDAQACBABmAAcHRUsACQkGXwAGBktLAAICAV8AAQFNAUxZQBQnJyc0JzMuLBMTJiURESUhEAwKHSsFIwYjIiYnNxYWMzI3IzU3NjU1BgYjIiYmNTQ2NjMyFhc1MxEUBzMkNjU0JiYjIgYGFRQWMwKWVTbIS4gqLiVtOmsrutUFImM6THtGRntMPWYhWwRE/vxmL1I1NVMvZlE6jikmSiAlOkEBGxs8Jyg+cUhIbz4qKU7+NiUbdFxKMEsqKkswSlwAAAEAWwAAAlIC5gATAC1AKhABAQQBSgADA0RLAAEBBF8FAQQES0sCAQAAQwBMAAAAEwASERMjEwYKGCsAFhURIxE0JiMiBhURIxEzETY2MwHbd2BKRU5aYGAeYTwCF3Vx/s8BJk1OW1X+7wLm/uEmKv//AAAAAAJSAuYAIgHYAAABBwcGAfIAxAAIsQEBsMSwMyv//wBb/y8CUgLmACIB2AAAAAMHBAKDAAD////YAAACUgO1ACIB2AAAAQcG7QG3ANQACLEBAbDUsDMr////2AAAAlIDoQAiAdgAAAEHBxYBtwAqAAixAQGwKrAzK///AFv/PAJSAuYAIgHYAAAAAwb/AoMAAP//AEoAAADMAvUAIgHfAAAAAwcpAbcAAAABAFsAAAC7AhIAAwATQBAAAABFSwABAUMBTBEQAgoWKxMzESNbYGACEv3u//8AQAAAAUIC4QAiAd8AAAADBucBtwAA//8AAgAAARQC4QAiAd8AAAADBzcBtwAA////8QAAASUC4QAiAd8AAAADBzYBtwAA////ngAAAQsC4QAiAd8AAAADBvsBtwAA//8AEgAAAQQC1gAiAd8AAAADBzUBtwAA/////wAAASkDXgAiAd8AAAAjBysBtwAAAQcHLgG3AI4ACLEDAbCOsDMr//8AUAAAAMYC5wAiAd8AAAADBuMBtwAA//8ASv88AMwC9QAiAd8AAAAjBykBtwAAAAMG/wG3AAD////UAAAA1gLhACIB3wAAAAMG5QG3AAD//wAvAAAA8AMlACIB3wAAAAMG+gG3AAD//wACAAABFALnACIB3wAAAAMHOgG3AAD//wBK/zgB6AL1ACIB3wAAACMHKQG3AAAAIwHwARcAAAADBykC0wAA//8ABgAAARACvgAiAd8AAAADBzkBtwAA//8APP8gAN8C9QAiAd8AAAAjBykBtwAAAAMHKgHmAAD////8AAABGgLhACIB3wAAAAMHOAG3AAD///+k/zgA0QL1ACIB8AAAAAMHKQG8AAAAAf+k/zgAwAISAA4AKUAmAwEAAQIBAgACSgABAUVLAAAAAmADAQICTQJMAAAADgANEyQEChYrBiYnNxYzMjY1ETMRFAYjDDwUHx4wJilgWFHIEBBKGS8uAiz91lJe////pP84ASoC4QAiAfAAAAADBzYBvAAAAAEAWwAAAmYC5gALACNAIAkGAQMAAgFKAAEBREsAAgJFSwMBAABDAEwSEhESBAoYKyUHFSMRMxEBMwcTIwEpbmBgASF03/V292aRAub+JAEI2/7J////2AAAAmYDtQAiAfIAAAEHBu0BtwDUAAixAQGw1LAzK///AFv++QJmAuYAIgHyAAAAAwcBAmUAAAABAFsAAAJm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yNQBDP70/////wAAAmgDBwAiAt8AAAEHBucCXwAmAAixAgGwJrAzK/////8AAAJoAwcAIgLfAAABBwbvAl8AJgAIsQIBsCawMyv/////AAACaANxACIC3wAAACcHMQJfACYBBwcuAl8AoQAQsQIBsCawMyuxAwGwobAzK///////PAJoAwcAIgLfAAAAIwb/Al8AAAEHBu8CXwAmAAixAwGwJrAzK/////8AAAJoA3EAIgLfAAAAJwcxAl8AJgEHBy0CXwChABCxAgGwJrAzK7EDAbChsDMr/////wAAAmgDfQAiAt8AAAAnBzECXwAmAQcHNAJfAI4AELECAbAmsDMrsQMBsI6wMyv/////AAACaANwACIC3wAAACcHMQJfACYBBwcyAl8AoQAQsQIBsCawMyuxAwGwobAzK/////8AAAJoAwcAIgLfAAABBwbtAl8AJgAIsQIBsCawMyv/////AAACaAMHACIC3wAAAQcG7AJfACYACLECAbAmsDMr/////wAAAnkDTgAiAt8AAAAnBy8CXwAmAQcHLgMHAH4AELECAbAmsDMrsQMBsH6wMyv//////zwCaAMHACIC3wAAACMG/wJfAAABBwbsAl8AJgAIsQMBsCawMyv/////AAACaANOACIC3wAAACcHLwJfACYBBwctAwcAfgAQsQIBsCawMyuxAwGwfrAzK/////8AAAJoA2MAIgLfAAAAJwcvAl8AJgEHBzQC4QB0ABCxAgGwJrAzK7EDAbB0sDMr/////wAAAmgDdgAiAt8AAAAnBy8CXwAmAQcHMgJfAKcAELECAbAmsDMrsQMBsKewMyv/////AAACaAMHACIC3wAAAQcG+wJfACYACLECArAmsDMr/////wAAAmgC/QAiAt8AAAEHBt8CXwAmAAixAgKwJrAzK///////PAJoAjgAIgLfAAAAAwb/Al8AAP////8AAAJoAwcAIgLfAAABBwblAl8AJgAIsQIBsCawMyv/////AAACaANLACIC3wAAAQcG+gJfACYACLECAbAmsDMr/////wAAAmgDDQAiAt8AAAEHBvwCXwAmAAixAgGwJrAzK/////8AAAJoAuQAIgLfAAABBwb2Al8AJgAIsQIBsCawMyv//////yACfgI4ACIC3wAAAAMHAwOTAAD/////AAACaANSACIC3wAAAQcG8AJf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VAD////w/zgCNgISAAICbwYA////8P84AjYC4QAiAm8GAAADB1gB8AAAAAMAK/8+AvoC5gARABgAHgA3QDQeAQAGAUoABAMEgwgBBwcDXwUBAwMiSwAGBgBfAgEAACFLAAEBJAFMFhEUEREUERERCQcdKyQGBxUjNSYmNTQ2NzUzFRYWFQQWFxEGBhUENTQmJxEC+qSVXpWjopZelaT9kG1sbWwCEW5sj44Iu7sIjXx7igjPzwiLelVgBwF0B15TrKxUXQf+iwD//wAJAAACFQISAAICbvsAAAEAKgAAAgQCEgARAC9ALBABAwIDAQEDAkoAAwABAAMBZwUEAgICIksAAAAhAEwAAAARABEjEyIRBgcYKwERIzUGIyImNTUzFRQWMzI3NQIEYFZVY2xgRT5GUQIS/e7WKFxcrKY3OCPyAAABAF3/gQKTAhIACwApQCYAAAMAUgQBAgIiSwYFAgMDAV4AAQEhAUwAAAALAAsREREREQcHGSslFSM1IREzESERMxECk1v+JWABImBU038CEv5CAb7+QgAAAQBdAAADUAISAAsAJUAiBgUDAwEBIksEAQICAF4AAAAhAEwAAAALAAsREREREQcHGSsBESERMxEzETMRMxEDUP0NYOpg6QIS/e4CEv5CAb7+QgG+AP//AF3/jwOfAhIAIgUmAAAAAwdaArIAAAABAF3/gQIoAhIACwBGS7AKUFhAGAABAAABbwUBAwMiSwAEBABeAgEAACEATBtAFwABAAGEBQEDAyJLAAQEAF4CAQAAIQBMWUAJEREREREQBgcaKyEjFSM1IxEzESERMwIot1u5YAELYH9/AhL+QgG+AAACAF3//gIhAhIACgATADBALQUBAgADBAIDZQABASJLBgEEBABeAAAAIQBMCwsAAAsTCxIRDwAKAAkRJAcHFisAFhUUBicnETMVFxI2NTQmJycVFwG3anNr5mCVKkNBQ35+AV1aUlZdAQECErMB/uk2NTQwAQLQAQACAAQAAAJhAhIADAAVADZAMwYBAwAEBQMEZQABAQJdAAICIksHAQUFAF0AAAAhAEwNDQAADRUNFBMRAAwACxERJAgHFysAFhUUBiMjESM1IRUzEjY1NCYjIxUzAfhpc2nfogECkCpAPz98fAFfW1JVXQG+VLP+6jY1MzHPAAADAF3//gLJAhIACgAOABcANkAzBwECAAUGAgVlAwEBASJLCAEGBgBeBAEAACEATA8PAAAPFw8WFRMODQwLAAoACREkCQcWKwAWFRQGJycRMxUXJTMRIyY2NTQmJycVFwGwanNr32CPAR1gYPNDQkJ4eAFdWlJWXQEBAhKzAbT97kc2NTQwAQLQAf//AAX/+AOIAhIAIgUYAAAAAwUpAWcAAAACAF0AAAOeAhIAEgAbAGZLsC5QWEAeCQYCBAcBAQgEAWUFAQMDIksKAQgIAF4CAQAAIQBMG0AjAAcBBAdVCQYCBAABCAQBZQUBAwMiSwoBCAgAXgIBAAAhAExZQBcTEwAAExsTGhkXABIAERERERERJAsHGisAFhUUBiMjNSEVIxEzFSE1MxUzFjY1NCYjIxUzAzhmcWTo/txgYAEkYJglPj06hIQBRFFLT1nx8QISzs7O/TArKSuvAP//ACv/+gHrAhcAAgI6EwD//wAs//oCKAIZAQ8FMAJAAhLAAAAJsQABuAISsDMrAAABABj/+QIUAhgAHAA7QDgZGAIDBAsKAgECAkoAAwACAQMCZQAEBAVfBgEFBSdLAAEBAF8AAAAmAEwAAAAcABsiERIkJgcHGSsAFhYVFAYGIyImJzcWMzI2NyE1ISYmIyIHJzY2MwFHg0pKg1FGcSc4QGJObgv+9gEIDWxMYUE4J3JFAhhGfE1OfEYsKjg/WUhHRVVANyss//8ATAAAAM4C9QAiAd8CAAADBykBuQAA//8AEgAAAQQC1gAiAd8AAAADBzUBtwAA////ov84AM8C9QAiAfD+AAADBykBugAAAAH/3AAAAlUC5gAbADtAOBgBAQgBSgYBBAcBAwgEA2UAAQEIXwkBCAgnSwAFBQBdAgEAACEATAAAABsAGhEREREREyMTCgccKwAWFREjETQmIyIGFREjESM1MzUzFTMVIxU2NjMB3XhgS0VOWWCCgmDu7h5gPAIXdXH+zwEmTU5bVf7vAl05UFA5lCYoAAACAF3/+gM/AhcAFgAmAJxLsCdQWEAhAAQAAQcEAWUABgYDXwgFAgMDIksJAQcHAF8CAQAAKABMG0uwLlBYQCUABAABBwQBZQAGBgNfCAUCAwMiSwACAiFLCQEHBwBfAAAAKABMG0ApAAQAAQcEAWUAAwMiSwAGBgVfCAEFBSdLAAICIUsJAQcHAF8AAAAoAExZWUAWFxcAABcmFyUfHQAWABURERETJgoHGSsAFhYVFAYGIyImJicjFSMRMxUzPgIzEjY2NTQmJiMiBgYVFBYWMwJ/ekZGek1GckkJa2BgbApJcUUxTy4uTzExUC0tUDECF0V7Tk57RjppQ+ACEtlCZTf+Ny5VODdVLi5VNzhVLgAAAgAwAAACBgISAA4AFgAzQDAIAQEEAUoABAABAAQBZQAFBQNdBgEDAyJLAgEAACEATAAAFRMSEAAOAA0RIREHBxcrAREjNSMjByM3JiY1NDYzBhYzMzUjIhUCBlaaC3RngTxAfG2HQ0OTj4oCEv3uqKi1ElM+W1/yM9FpAAH/9v84AlUC5gAmAE1ASiMBAgkKAQEDCQEAAQNKAAYFBoMHAQUIAQQJBQRlAAICCV8KAQkJJ0sAAwMhSwABAQBfAAAAKQBMAAAAJgAlERERERETJSQlCwcdKwAWFREUBiMiJic3FjMyNjURNCYjIgYVESMRIzUzNTMVMxUjFTY2MwHdeFlRIj0UHx8vJylLRU5ZYGhoW/DwHWM/Ahd1cf63Ul4QEEoZMC0BQE1OW1X+7wJZRElJRJcpLAAAAgAA//4CRwLmABIAGwBvS7AWUFhAJgADAgODCQEGAAcIBgdlBQEBAQJdBAECAiJLCgEICABeAAAAIQBMG0AkAAMCA4MEAQIFAQEGAgFlCQEGAAcIBgdlCgEICABeAAAAIQBMWUAXExMAABMbExoZFwASABERERERESQLBxorABYVFAYnJxEjNTM1MxUzFSMVFxI2NTQmJycVFwHdanRr5YODYMTElSpDQkJ+fgFdWlJWXQEBAeNGvb1GhAH+6TY1NDABAtABAAACAA8AAAKxAhIAGwAfADxAORcUAggGHQEFCAJKBwEFAwEBAAUBZwkBCAgGXQAGBiJLBAICAAAhAEwcHBwfHB8SEhMTIREjEAoHHCshIycmJiMjFSM1IyIGBwcjNzY2Nyc1IRUHFhYXARczNwKxXicWQTAdUxowQhYlXzEiW0GxAiKyRF0i/jKrAqxfQTra2jtAX3RWUgK3PT23AVFYAVuxsf//ACz/+gJeAhcAAgVpAAAAAQAFAAACUAIaABAAW0uwHVBYQAsEAQEADwUCAgECShtACwQBAQMPBQICAQJKWUuwHVBYQBEAAQEAXwMBAAAnSwACAiECTBtAFQADAyJLAAEBAF8AAAAnSwACAiECTFm2ERMjIQQHGCsANjMyFwcmIyIGBwMjAzMTEwGkPi8cIwoVEBgdFItg6GqucAHjNwlfBiUx/p4CEv5pASkAAQArAAAB8wISAA0ALUAqBAEAAwEBAgABZQcBBgYFXQAFBSJLAAICIQJMAAAADQANERERERERCAcaKxMVMxUjFSM1IzUzESEVzeLiYEJCAYYBvrdEw8NEAQtUAAABAF3/OAJCAhIAHQBBQD4dAQMAFgEEAwwBAgQLAQECBEoAAAADBAADZwAGBgVdAAUFIksABAQhSwACAgFfAAEBKQFMERESJCMmIAcHGysAMzIWFhUUBgYjIic3FjMyNjU0JiMiBxUjESEVIRUBCktDbD5AdEwhKhQcFUxYWERHQGABe/7lAR03akhKcz8IUwVYSk1PJqYCElTDAP//AA3/jwNsAhIAIgUQAAAAAwddApIAAAABABz/jwHrAhkAKgA+QDseAQQFHQEDBCcBAgMJAQECCAUCAwABBUoAAwACAQMCZQABAAABAGEABAQFXwAFBScETCMkISQnEwYHGiskBgcVIzUmJic3FhYzMjY1NCYjIzUzMjY1NCYjIgcnNjMyFhYVFAYHFhYVAetrV1sxXCUdJmIyRFFBO2FaNj5JPk9YGmFqQGY6NCw1OlxWCm1sBB4YSRgbLyglKEUmISQoKUoxJEIqJz4QDj4uAP//AF3/jwJ3AhIAIgUWAAAAAwddAZ0AAAABAFsAAAJaAhIAFAA2QDMSAQAFAUoHAQUCAQABBQBlAAYAAQMGAWUIAQQEIksJAQMDIQNMFBMRERERERERERAKBx0rJSMVIzUjFSMRMxUzNTMVMzczAxMjAVEeRjJgYDJGH5Rlrr1w4GJi4AIS4GRk4P8A/u4AAQAAAAACTgLmABQAQEA9EgEABwFKBQEDBgECCAMCZQAHAAABBwBlAAQEAV0JAQEBIUsACAgiSwkBAQEhAUwUExEREREREREREAoHHSslIxUjESM1MzUzFTMVIxEzNzMDEyMBKmxgXl5gmJhurWfJ13Lg4AJZRUhJRP7Z4P8A/u4AAAEABAAAApcCEgAOAC1AKgwBAAQBSgAEAAABBABlAAICA10FAQMDIksGAQEBIQFMEhEREREREAcHGyslIxUjESM1IRUzNzMHEyMBdG5gogECb6xoyddx4OABv1Pg4P/+7QD//wBd/48CngISACIFGgAAAAMHWgGxAAD//wBdAAADcQISACIFGgAAAAMFCQGOAAD//wBd/48CmwISACIFHAAAAAMHWgGuAAAAAQBd/zgDvAISAB8AQ0BAHwEDABYBBAMMAQIECwEBAgRKAAAAAwQAA2cABQUHXQAHByJLBgEEBCFLAAICAV8AAQEpAUwRERESJCMmIAgHHCsAMzIWFhUUBgYjIic3FjMyNjU0JiMiBxUjESERIxEhEQKHSUNrPkB1TCEqFBwWTFhZREU+YP7jYAHdAR03akhKcz8IUwVYSk1PJKgBvv5CAhL+6gACAC//8QLoAh0AKQA1AH9LsCFQWEASDQwCBQMsKAICBSkkAwMAAgNKG0AVDQwCBQMsKAICBSQBBAIpAwIBBARKWUuwIVBYQBcABQUDXwADAydLBAECAgBfAQEAACYATBtAHwAFBQNfAAMDJ0sAAgIBXwABASZLAAQEAF8AAAAmAExZQAkqJyctIiAGBxorBCMiJwYjIiYmNTQ2NxcGBhUUFhYzMjcmJjU0NjYzMhYWFRQGBxYzMjcXJBYXNjY1NCYjIgYVArQ5SkI/QV+RUElCSzk9O21HDgc1OzhnREJjN0pCFRcvMQb+mUI5QElHOTxIDxoTSYRWUIgpKilwQUFiNQErekhHbTs4ZkJOhi0DDEbpbx8dc01DUlVH//8ALP+PAhwCFwAiAacCAAADB28ArwAA//8ABP+PAegCEgAiBR8AAAADB1oAjAAAAAEABv8+AjgCEgAIAB1AGgYDAAMAAQFKAgEBASJLAAAAJABMEhIRAwcXKwUVIzUDMxMTMwFPYehltrpdAsDAAhT+WAGoAP//AAb/PgI4AhIAIgVLAAABRwcGAmT+T0WQQAAACbEBAbj+T7AzKwD//wAJ/48CQQISACICbvsAAAMHXQFnAAAAAQAF/48C3wISAA8AMUAuAAAFAFIEAQICA10GAQMDIksIBwIFBQFeAAEBIQFMAAAADwAPEREREREREQkHGyslFSM1IREjNSEVIxEhETMRAt9a/kLCAb2bAQxgVMVxAb5UVP6WAb7+Qv//ACr/jwJXAhIAIgUkAAAAAwdaAWoAAAABACkAAAIDAhIAFwA4QDUWFBEFAwUCBAFKAAIEAQQCAX4ABAABAAQBZQYFAgMDIksAAAAhAEwAAAAXABcVExEUEQcHGSsBESM1BgcVIzUmJjU1MxUUFhc1MxU2NzUCA2A2NkdfaGA2MUc1NwIS/e7WGQpoYwJcWqymMTcFaGcIGPL//wBdAAACVALmAAIB2AIAAAEAXf+PAqMC5gAXADZAMxABBgIBSgcBBgAABgBhAAICBV8ABQUnSwAEBAFdAwEBASEBTAAAABcAFyMREyMREQgHGislFSM1IxE0JiMiBhURIxEzETY2MzIWFRUCo1pVSkROW2BgHmVAYnJUxXEBI01OXVL+8QLm/tAvMnNw4AAAAgAV//oC2gIXACQAKwA/QDwWFQIEBwgHAgEAAkoGAQQDAQABBABnCAEHBwVfAAUFJ0sAAQECXwACAigCTCUlJSslKhYjKSMkIhEJBxsrJAchFhYzMjcXBgYjIiYmJyMiJjU0NxcGFRQWMzM+AjMyFhYVJAYHISYmIwLaA/5ECWxRYzw2JW5EUX9NBxZFSxdQEyUjCghLdUhOfEX+qmEIAWAIYUf3DkZVQD4qLDxtRj0zJzARHxsZHkRqO0V8UMBURENV//8AFf+PAtoCFwAiBVMAAAADB28BRQAA//8AXQAAAL0C5gACAfYCAP//AA0AAANEAuEAIgUQAAAAAwdYAogAAAABAF3/OAJAAhIAGgA5QDYaAQIFCAEBAwcBAAEDSgAFAAIDBQJlBgEEBCJLAAMDIUsAAQEAYAAAACkATBEREREVIyQHBxsrJBYVFAYjIic3FjMyNjU0JicjFSMRMxUzNzMHAdhkWUo5OhsoISYsWEl+YGBxq2fDyKdJSVcdSBUtKDaMQeACEt/f+AABAAX/jwJ4AhIAFwClS7AuUFhACg4BBAINAQEEAkobQAoOAQQGDQEBBAJKWUuwHVBYQB0AAAQAUQACAgVdAAUFIksHBgIEBAFfAwEBASEBTBtLsC5QWEAhAAAEAFEAAgIFXQAFBSJLAAEBIUsHBgIEBANfAAMDJgNMG0AiBwEGAAAGAGEAAgIFXQAFBSJLAAEBIUsABAQDXwADAyYDTFlZQA8AAAAXABcUIyQREREIBxorJQcjNyMRIwcOAiMiJzcWMzI2Njc3IRECeDpOHUnkBgUcQDkaIQYNCygoDAUJAZdUxXEBvnZrj1YJUQNGYFnE/kIAAQBd/zgCUQISABYAO0A4AwEAAgIBBgACSgAEAAECBAFlBQEDAyJLAAICIUsAAAAGYAcBBgYpBkwAAAAWABUREREREyQIBxorBCYnNxYzMjY1NSEVIxEzFSE1MxEUBiMBij4VHh4sJyv+zGBgATRgV07IERBJGTAt+N4CEuHh/dFPXAAAAQBd/48CnwISAA8AMEAtAAUAAgcFAmUIAQcAAAcAYQYBBAQiSwMBAQEhAUwAAAAPAA8RERERERERCQcbKyUHIzcjNSEVIxEzFSE1MxECnzpOHUn+0mBgAS5gVMVx3t4CEuHh/kIAAQAn/48CAQISABUAOEA1FAEFBAcBAwUCSgAFAAMCBQNnAAIAAQIBYQcGAgQEIksAAAAhAEwAAAAVABUjEyIREREIBxorAREjFSM1MzUGIyImNTUzFRQWMzI3NQIBYVtcVFdjbGBFPkhPAhL97nHBlidbXJyWNjgj4QABAF3/jwMdAhIAEAA3QDQNCAUDBgQBSgACBgEGAgF+BwEGAAAGAGEFAQQEIksDAQEBIQFMAAAAEAAQEhESEhERCAcaKyUHIzcjEQMjAxEjETMTEzMRAx06Th1JxirEWGPQ1lpUxXEBg/65AUj+fAIS/poBZv5CAP//ADD/+gH9AuEAIgGK/gAAAwdYAgEAAP//ADD/+gH9AtcAIgGK/gAAAwbfAk0AAP//ADD/+gOxAhcAAgGk/gD//wAs//oCPALhACIBtQIAAAMHWAIVAAAAAgA4//sCSAIYABcAHgA9QDoUEwIBAgFKAAEABAUBBGUAAgIDXwYBAwMnSwcBBQUAXwAAACgATBgYAAAYHhgdGxoAFwAWIhUmCAcXKwAWFhUUBgYjIiYmNTQ3ISYmIyIHJzY2MxI2NyEWFjMBf4JHRXlMTHdDAgGuCWlOXzo1JGtCWF0I/qwIXUUCGEV8Tk18RUV8UAsSRlVAPios/jRURENVAP//ADj/+wJIAtcAIgVhAAAAAwbfAmsAAP//AA0AAANEAtcAIgUQAAAAAwbfAtQAAP//ABz/+QHrAtcAIgURAAAAAwbfAjMAAAAB/+z/NwHuAhIAGwA7QDgaAQMEGxUCAgMKAQECCQEAAQRKAAIDAQMCAX4AAwMEXQAEBCJLAAEBAF8AAAApAEwREiQlJQUHGSskFhUUBgYjIiYnNxYWMzI2NTQmIyM1NyE1IRUHAX9vO3ZVTIcpJSNxP1BXVVY5tv6oAcu82W5YPmQ6MChQJCtFPj1EROVVRewA//8AXQAAAlkCvgAiBRIAAAADBvYCgQAA//8AXQAAAlkC1wAiBRIAAAADBt8CgQAA//8ALP/6AlMC1wAiAgwCAAADBt8CawAAAAMALP/6Al4CFwAPABYAHQA9QDoAAgAEBQIEZQcBAwMBXwYBAQEnSwgBBQUAXwAAACgATBcXEBAAABcdFxwaGRAWEBUTEgAPAA4mCQcVKwAWFhUUBgYjIiYmNTQ2NjMGBgchJiYjEjY3IRYWMwGVgElJgFBQgElJgFBLZgoBdgpmS0tmCv6KCmdKAhdFe05Oe0ZGe05Oe0VMV0lJV/58V0lJVwD//wAs//oCXgLXACIFaQAAAAMG3wJxAAD//wAY//kCFALXACIFMAAAAAMG3wIzAAD////w/zgCNgK+ACICbwYAAAMG9gI8AAD////w/zgCNgLXACICbwYAAAMG3wI8AAD////w/zgCNgLhACICbwYAAAMG6gI8AAD//wAqAAACBALXACIFJAAAAAMG3wJAAAD//wBd/48B4wISACIFCQAAAAIHWiMA//8AXf//AskC1wAiBSsAAAADBt8CzAAAAAEADf84AdMCEgAcAExASQ4BBAUNAQMEAkoAAgEFAQIFfgcBAAYBAQIAAWUKAQkJCF0ACAgiSwAFBSFLAAQEA18AAwMpA0wAAAAcABwRERETJCMRERELBx0rExUzFSMVMxUUBiMiJic3FjMyNjU1IzUjNTM1IRXV09NSV04jPRUcIyonKlJUVAFeAb6gRIZ2TFoSEEcaMS8Z2kT0VAAAAQAL/zgCEwISABoAMkAvGhcUEQQCAwkBAQIIAQABA0oEAQMDIksAAgIhSwABAQBgAAAAKQBMEhIWIyUFBxkrJBYWFRQGIyInNxYzMjY1NCYnByMTAzMXNzMHAZhRKlxHOzkcJiQkLUZam23PxWyQkGrCtmpXKURQH0gXKiEmamjLAQ8BA729/gAAAQAWAAACIgISABEANUAyCgECAwEBAAECSgUBAgYBAQACAWYEAQMDIksIBwIAACEATAAAABEAEREREhERERIJBxsrIScHIzcjNTMnMxc3MwczFSMXAbKWm2uycXWsb4+SZ697cK/KyuhE5sDA5kToAAEANf/5AgQCGQAoADtAOBMBAgEUAQMCCgEEAygBBQQESgADAAQFAwRlAAICAV8AAQEnSwAFBQBfAAAAJgBMJCEkIywiBgcaKyUGBiMiJiY1NDY3JiY1NDY2MzIXByYjIgYVFBYzMxUjIgYVFBYzMjY3AgQscTtGcUA6NSw0OmZAamEaWE8+ST42WmE7QVFEMmImNR0fKUkvLj4OED4nKkIkMUopKCQhJkUoJSgvGxgAAQAF/zgCJAISAB4AQ0BAFwEEAhYBAwQIAQEDBwEAAQRKAAICBV0GAQUFIksABAQDXwADAyZLAAEBAF8AAAApAEwAAAAeAB4jJBMkIwcHGSsBERQGIyImJzcWMzI2NREjBw4CIyInNxYzMjY2NzcCJFdPIj4UHR4sKCvkBgUcQDkaIQYNCygoDQQJAhL90U9cERBJGTAtAdh2a49WCVEDRmNWxP//AC7/PgJTAhcAAgIxBAAAAQAJAAADnwISAAwAJ0AkCwgDAwACAUoFBAMDAgIiSwEBAAAhAEwAAAAMAAwSERIRBgcYKwEDIwMDIwMzExMzExMDn8tjnJxjzWOdolmfoAIS/e4Bk/5tAhL+XgGi/l4BogACABb//gJBAhIAEgAaAD5AOwQBAgUBAQYCAWUJAQYABwgGB2UAAwMiSwoBCAgAXgAAACEATBMTAAATGhMZGBYAEgAREREREREkCwcaKwAWFRQGJycRIzUzNTMVMxUjFRcSNTQmJycVFwHYaXNs5WdnYMTElW1ARH5+AVBSUVZZAQEBjkc9PUc8Af71aDIqAQHDAQAAAgBe/z4ChAIXABYAKQBvQBUbGhkYDwoGBQQFAgIABQQDAgEAA0pLsC5QWEAcAAQEAl8DAQICIksGAQUFAF8AAAAoSwABASQBTBtAIAACAiJLAAQEA18AAwMnSwYBBQUAXwAAAChLAAEBJAFMWUAOFxcXKRcoLSMREyYHBxkrJAYHFwcnBiMiJicRIxEzFTY2MzIWFhUGNyc3FzY1NCYmIyIGBhUUFhYzAoQpJUM2RTdDQ2YdYFwdZkdIdUPkJEk3SSovUjMzUi8vUjPLZyRVKlYdOTX+1gLUbzk7RHtQuhJcK1wySzdVLy9VNzhULgAAAf+l/zgCTAISABYAO0A4DAEDAAsBAgMCSgAFAAEABQFlBwYCBAQiSwAAACFLAAMDAmAAAgIpAkwAAAAWABYREyQjEREIBxorAREjNSEVFAYjIiYnNxYzMjY1ETMVITUCTGD+0lZOIz0VHR4sJytgAS4CEv3u3/xOXREQSRkwLQIs39///wAF/48CdwISACIFGAAAAAMHWgGKAAAAAwBM//cCTwLxABYAIQAtADNAMBYBBAIBSgABAAMCAQNnAAIABAUCBGUGAQUFAF8AAAAmAEwiIiItIiwoJCcnJQcHGSsAFhUUBgYjIiYmNRE0NjYzMhYWFRQGByUzMjY1NCYjIgYVEjY2NTQmIyMVFBYzAgBPSXdEQnVIRnE/PmtBPTf+9IpGT1M5PFfJSS5TTaBeQQFzX0RGYjEwYEUBSEdkMi1ZPztWFR4+PjxCSUX+NyFALkFChURJAAABAC7/+gH2AhsAKAA0QDERAQABJBACAgAlAQMCA0oAAAABXwABASdLAAICA18EAQMDKANMAAAAKAAnKyUsBQcXKxYmNTQ2Njc+AjU0JiMiBgcnNjYzMhYVFAYGBwYGFRQWMzI2NxcGBiOugDhOQTA2JUE7LFsgIStqM2V6OVJARkNHPDdoJSAudj8GUkszOxoNCRAfGSUnGRNIGB5UTTQ8GwwOHiIlJiAXRh4jAP//ACn/OAJVAhcAAgHQ/wAAAQANAAADRALmABUAPEA5EwgCAAUBSgcBBQIBAAEFAGUABgYBXQkDAgEBIUsIAQQEIksJAwIBASEBTBUUERERERIREREQCgcdKyUjFSM1IwcjEwMzFzMRMxEzNzMDEyMCP2dgZ5Jytqhmj2hgaI9nqLZy4ODg4AESAQDgAbT+TOD+//7vAAAB//f/OQG9AhoAJwA/QDweAQQFHQEDBCcBAgMKAQECCQEAAQVKAAMAAgEDAmUABAQFXwAFBSdLAAEBAF8AAAApAEwjJCEkJCUGBxorJBYVFAYGIyImJzcWMzI2NTQmIyM1MzI2NTQmIyIHJzYzMhYWFRQGBwF2R0N0RzVmLR1UUUlbSD1xajVATEBEVBxlWkNmODsxp1tAPWA2Hx5HM0s8OEFMQTU4QyJJLDBWOTtYEQD//wBN//oCQAISAAICUPcA//8ATf/6AkAC4QAiAlD3AAADB1gCJgAA//8ATf/6AkAC4QAiAlD3AAADBuUCcgAAAAEAXgAAAk4C5gAMADFALgoBAAMBSgADAAABAwBlAAICAV0FAQEBIUsABAQiSwUBAQEhAUwSERERERAGBxorJSMVIxEzETM3MwMTIwEqbGBgbq1nyddy4OAC5v5M4P8A/u4AAQAFAAACNwISAAYAIUAeAQEAAQFKAAEBIksDAgIAACEATAAAAAYABhESBAcWKyEDAyMTMxMB0ra5Xudk5wGn/lkCEv3u//8AXQAAAksCEgACBRoAAP//AF0AAAJUAhcAAgIBAgD//wBdAAADzQIXAAIB/wIAAAEALAAAAgUCEgATACtAKAMBAwIBSgADAAEAAwFnBQQCAgIiSwAAACEATAAAABMAEyMTIxEGBxgrAREjNQYGIyImNTUzFRQWMzI2NTUCBWATW0FgamBGPkFUAhL97vUlKVxcs7A2ODg0sv//AE3/jwKXAhIAIgJQ9wAAAwdaAaoAAAABAE7/+QO9AhAAIgBbQAsJAQQDAUoDAQQBSUuwLlBYQBYIBwUDAwMiSwYBBAQAXwIBAgAAIQBMG0AaCAcFAwMDIksAAAAhSwYBBAQBXwIBAQEmAUxZQBAAAAAiACIjEyMTJCMRCQcbKwERIzUGBiMiJicGBiMiJjURMxEUFjMyNjURMxEUFjMyNjURA71bHGA8Pl8aHmxCZHVgR0JJVmBHQklVAhD97lApLDExLjR0cgEx/tpNT1xVARH+2k1PXFUBEQD//wBO/48EFQIQACIFjAAAAAMHWgMoAAAAAgBQ//QCHgISAA4AGwA6QDcFAQMBFwEEAwJKAAEAAwQBA2cAAAAiSwYBBAQCXwUBAgImAkwPDwAADxsPGhUTAA4ADSMTBwcWKxYmNREzFTY2MzIWFRQGIzY2NTQmIyIGBxUUFjPHd2AWUzdibHtqP0RFQDBFEkdDDG1mAUvVHCNjWV5uSUk5NUImIi89RQAAAgAF//QCegISABAAHQBAQD0NAQQDGQEFBAJKBgEDAAQFAwRnAAEBAl0AAgIiSwcBBQUAXwAAACYATBERAAARHREcFxUAEAAPERMkCAcXKwAWFRQGIyImNTUjNSEVNjYzEjY1NCYjIgYHFRQWMwIObHtqcnenAQcWUzcoREVAMEUSR0MBfGNZXm5tZvdU1Rwj/sFJOTVCJiIvPUUAAgBe//oDKgLmABYAJgB4S7AnUFhAKwAEAAEHBAFlAAMDAF8CAQAAKEsABgYFXwgBBQUnSwkBBwcAXwIBAAAoAEwbQCkABAABBwQBZQAGBgVfCAEFBSdLAAMDAl0AAgIhSwkBBwcAXwAAACgATFlAFhcXAAAXJhclHx0AFgAVEREREyYKBxkrABYWFRQGBiMiJiYnIxUjETMRMz4CMxI2NjU0JiYjIgYGFRQWFjMCantFRXtNRnJJCFZgYFcKSHFFMVAtLVAxMU8tLU8xAhdFe05Oe0Y6aUPgAub+U0JlN/43LlU4N1UuLlU3OFUuAAEAXQAAAewCEgAJAClAJgAAAAECAAFlBQEEBANdAAMDIksAAgIhAkwAAAAJAAkRERERBgcYKxMVMxUjFSMRIRW9x8dgAY8BvqtEzwISVAD//wAc/yAB6wIZACIFEQAAAAMHAgInAAD//wAs/yACHAIXACIBpwIAAAMHAgJmAAD//wBdAAAB4wLfACIFCQAAAQcG5wJP//4ACbEBAbj//rAzKwAAAgAn//gCRgLmAB0ALAAtQCoAAgADAQIDZQABAAQFAQRnBgEFBQBfAAAAJgBMHh4eLB4rLCElFiUHBxkrABYVFAYGIyImJjU0NjYXJiY1NDYzIRUhIgYVFBYXAjY2NTQmJiMiBhUUFhYzAfdPRn1OTntFPm5EYFlBOAE//uEbHm98QVEuLlEzTWItTzMBtXJLSnVBQHJHQ2k5ASxWLiw1UhQRHkI2/nArTTAxTSteSzBNKwD//wAGAAABEAK+ACIB3wAAAAMHOQG3AAD//wAn/zgCUwIXAAIB0P0A//8AVv/6AkkCvgAiAlAAAAADBvYCfAAA//8ATv/5A70CvAAiBYwAAAFHBvYEXv/+f/9AAAAJsQEBuP/+sDMrAP//ACr/+gJPAhcAAgJ/AAD//wAp/zgCVQIXAAIB0P8A//8AKv/6AjkCFwACApwAAP//ACr/+gI5AuEAIgKcAAAAAwblAlwAAP//ACr/+gI5AtcAIgKcAAAAAwbfAlwAAP//AE3/+gJAAhIAAgJQ9wD//wBN//oCQALhACICUPcAAAMHWAImAAAAAgBN/48CmALhAA0AJQCHtRMBBQgBSkuwJ1BYQCgCAQABAIMAAQsBAwcBA2cABAgEUgkBBwciSwwKAggIBWAGAQUFIQVMG0AsAgEAAQCDAAELAQMHAQNnAAQIBFIJAQcHIksABQUhSwwKAggIBmAABgYoBkxZQB4ODgAADiUOJSQjIB4bGhcVEhEQDwANAAwSIhINBxcrACYnMxYWMzI2NzMGBiMBByM3IzUGBiMiJjURMxEUFjMyNjURMxEBAVsCQQE3KSk3AUECW0UBUjpOHUkdXjhqemBKRUxYYAJZSj4kLCwkPkr9+8VxTigsdXIBMf7aTU9cVAES/kL//wBN//oCQALhACICUPcAAAMG5QJyAAAAAgBG/z4CZwIXABEAIAA3QDQKAQQBSQADAwJfBQECAidLBgEEBABfAAAAKEsAAQEkAUwSEgAAEiASHxoYABEAEBMmBwcWKwAWFhUUBgYjIiYnESMRNDY2MxI2NjU0JiYjIgYVFBYWMwGpe0NCdkw8YCBhRX1RMFItLVE0T2ItUDQCF0R7UE97RCsp/vAByVB8RP43L1U2NlUwZ1M3VS8A//8AXQAAA80CFwACAf8CAP//AFT/OAJJAhIAAgLMAAD//wBU/zgCSQLhACICzAAAAAMHWAIwAAAAAgBQ//QCKAISAA4AGwA6QDcFAQMBFwEEAwJKAAEAAwQBA2cAAAAiSwYBBAQCXwUBAgImAkwPDwAADxsPGhUTAA4ADSMTBwcWKxYmNREzFTY2MzIWFRQGIzY2NTQmIyIGBxUUFjPJeWAaWTRjbn5wQkpIQTBKE0pBDG5lAUvNGh1kWF9tSUY7OEAmIi89RQAAAgAF//QCgwISABAAHQBAQD0NAQQDGQEFBAJKBgEDAAQFAwRnAAEBAl0AAgIiSwcBBQUAXwAAACYATBERAAARHREcFxUAEAAPERMkCAcXKwAWFRQGIyImNTUjNSEVNjYzEjY1NCYjIgYHFRQWMwIYa3pqc3ewARAWUzgnRUVBMEQTR0MBfGNZXm5tZvdU1R0i/sFJOTVCJiIvPUUAAwBQ//QCywISAA4AEgAfAG1ACgUBBQEbAQYFAkpLsBRQWEAcAAEABQYBBWcDAQAAIksIAQYGAl8EBwICAiYCTBtAIAABAAUGAQVnAwEAACJLAAQEIUsIAQYGAl8HAQICJgJMWUAXExMAABMfEx4ZFxIREA8ADgANIxMJBxYrFiY1ETMVNjYzMhYVFAYjATMRIyY2NTQmIyIGBxUUFjPHd2AXUzZhbXxpATJgYPNFRkEvRRJHQwxtZgFLzRcgY1lebgIe/e49STk1QiYiLz1FAAIACP/0A4wCEgAcACkAU0BQGQEGBSURAgMGEAEABwNKCAEFAAYDBQZnAAEBBF0ABAQiSwADAwBfAgEAACZLCQEHBwBfAgEAACYATB0dAAAdKR0oIyEAHAAbEyMjEyQKBxkrABYVFAYjIiY1NSMHBgYjIicnFjMyNjc3IRU2NjMSNjU0JiMiBgcVFBYzAx5ufnBxedIHCENMKBMBDRYrKQYJAYYbVzUkS0hBMUkTSkEBfGRYX21uZfd4qaUJVwR6fsbNGh3+wUY7OEAmIi89RQACAF3/9AOXAhIAFAAfAJVLsBRQWEAeCQYCBAcBAQgEAWUFAQMDIksKAQgIAF8CAQAAJgBMG0uwLlBYQCIJBgIEBwEBCAQBZQUBAwMiSwACAiFLCgEICABfAAAAJgBMG0AnAAcBBAdVCQYCBAABCAQBZQUBAwMiSwACAiFLCgEICABfAAAAJgBMWVlAFxUVAAAVHxUeGxkAFAATERERERMkCwcaKwAWFRQGIyImNTUhFSMRMxUhNTMVMxI2NTQmIyMVFBYzAzBnfm1tbv7sYGABFGChHUY5P4xBPwFEU0tTX2FfPfECEs7Ozv73NzIrJ0U5PQAAAv/8//ICWQLmABYAIwBIQEUTAQcGHwEIBwJKAAMCA4MEAQIFAQEGAgFlCQEGAAcIBgdnCgEICABfAAAAJgBMFxcAABcjFyIdGwAWABUREREREyQLBxorABYVFAYjIiY1ESM1MzUzFTMVIxU2NjMSNjU0JiMiBgcVFBYzAepvf29xeoSEYMTEHFgzJUtJQTFIFEtBAXtkWF9ubmUBJke0tEenGR7+wEc6OEAlIy89Rf//ACr/+gJPAuEAIgJ/AAAAAwdYAi8AAP//ACr/+gJPAtcAIgJ/AAAAAwbfAnsAAP//ADL/+gOzAhcAAgKZAAD//wAq//oCOQLhACICnAAAAAMHWAIQAAAAAgAr//sCOgIYABUAHgA2QDMbGhIRDAsGAwEBSgABAQJfBAECAidLBQEDAwBfAAAAKABMFhYAABYeFh0AFQAUJiYGBxYrABYWFRQGBiMiJiYnJSYmIyIHJzY2MxI2NjU1BRYWMwFxgkdFeUxIdkYBAaUUX0NfOjQja0JFTyz+rQ1aPwIYRXxOTXxFQXZNUjc8QD4qLP40LlM3CkA6SP//ACv/+wI6AtcAIgWxAAAAAwbfAmAAAP//AE3/+gJAAr4AIgJQ9wAAAwb2AnIAAP//AE3/+gJAAtcAIgJQ9wAAAwbfAnIAAP//AFT/OAJJAr4AIgLMAAAAAwb2AnwAAP//AFT/OAJJAtcAIgLMAAAAAwbfAnwAAP//AFT/OAJJAuEAIgLMAAAAAwbqAnwAAP//AFD/9ALLAtcAIgWpAAAAAwbfAsEAAAACABH/9AJOAhIAFgAjAEhARRMBBwYfAQgHAkoEAQIFAQEGAgFlCQEGAAcIBgdnAAMDIksKAQgIAF8AAAAmAEwXFwAAFyMXIh0bABYAFRERERETJAsHGisAFhUUBiMiJjU1IzUzNTMVMxUjFTY2MxI2NTQmIyIGBxUUFjMB4G59bHR5Z2dgxMQWVTkrRkhDL0gTSkUBWFpRVmNjXdxHOztHbxke/uU9MC04IBwpMzoAAAL//wAAAt0CvAADAAYAJEAhBgECAQFKAAECAYMAAgAAAlUAAgIAXQAAAgBNEREQAw0XKyEhATMBIQMC3f0iAT1j/u0BweACvP2bAgAAAAEACQAAA3kCxAAjAC5AKyETAgMAAUoAAQAEAAEEZwIBAAMDAFUCAQAAA10FAQMAA00XJxEWJhAGDRorNzMmJjU0NjYzMhYWFRQGBzMVITU2NjU0JiYjIgYGFRQWFxUhCcQ9QmGpaWmpYUI9xP6mVltFfE5OfEVcVf6mVzGMU2WfWVmfZVOMMVdRK5BWTXlDQ3lNV5AqUQAAAQBb/z4CTgISABQAP0A8AwEEAwgBAAQCSgYFAgMEA4MAAAQBBAABfgACAQKEAAQAAQRXAAQEAV8AAQQBTwAAABQAFCMREiMRBw0ZKwERIzUGBiMiJxUjETMRFBYzMjY1EQJOWxtZM2AxYGBLRExYAhL97lItKz35AtT+2k1PXFQBEgAAAf/4AAACywISABYAK0AoDg0CAQABSgMBAQABhAAFAAAFVQAFBQBdBAICAAUATSohEREREAYNGisBIxEjESMDIxMjIhUUFwcmJjU0NjYzIQLKk2CVNGA0LGkdSRQVLFI1AiABw/49AcP+PQHDWCMtFhZAHytGJwD/////AAAC3QPWACIABAAAAQcG8AKaAKoACLECArCqsDMr//8AaQAAAs4CvAACAGoAAAACADD/+AJrAsQADwAbACxAKQACAgBfAAAASEsFAQMDAV8EAQEBSQFMEBAAABAbEBoWFAAPAA4mBgoVKxYmJjU0NjYzMhYWFRQGBiM2NjU0JiMiBhUUFjP7gUpKgVNSgUpKgVJUZWVUVWVlVQhVom9volVVom9volVZioODioqDg4oAAQAIAAABCQK8AAUAH0AcAAEBAl0DAQICQksAAABDAEwAAAAFAAUREQQKFisBESMRIzUBCWOeArz9RAJlVwABAA4AAAIcAsQAFwAwQC0NDAIDAQMBAAMCSgABAQJfAAICSEsEAQMDAF0AAABDAEwAAAAXABckJxEFChcrJRUhNQE2NjU0JiMiByc2NjMyFhUUBgcHAhz+CQEdNCRNSHQ/RCmFUm6CMEPWV1dEARMySSU3PUw7MjhpWjhkQM4AAAEABf/4Ag8CvAAbADtAOBoBAwQbFQICAwoBAQIJAQABBEoAAgMBAwIBfgADAwRdAAQEQksAAQEAXwAAAEkATBESJCUlBQoZKwAWFRQGBiMiJic3FhYzMjY1NCYjIzU3ITUhFQcBo2w8d1ZLiiwuJHA/TldWVziw/q8BzrcBjGtTPGE5LShPIilCOjpARthXROIAAQAmAAACkQK8AA4AMEAtBgEABAFKAAUDBAMFBH4GAQQCAQABBABmAAMDQksAAQFDAUwRERESEREQBwobKyUjFSM1ITUBMwEhNTMVMwKRhWH+ewFmbP6pAQ1ehaysrEYByv5GmJgAAQAR//gCGwK8ABoAOUA2CgEBAgkBAAECSgYBBQACAQUCZQAEBANdAAMDQksAAQEAXwAAAEkATAAAABoAGRERJCUlBwoZKwAWFRQGBiMiJic3FhYzMjY1NCYjIxMhFSEHMwGOjTt3V0qKLS4kcD5PV2B0nyUBi/7JE04BpXFiPmM5LShPIilDOj9BAW5XwAAAAgAw//gCTgLEABwAKgBEQEERAQIBEgEDAhkBBQQDSgYBAwAEBQMEZwACAgFfAAEBSEsHAQUFAF8AAABJAEwdHQAAHSodKSMhABwAGyQlJggKFysAFhYVFAYGIyImNTQ2NjMyFhcHJiMiBhUUFzY2MxI2NTQmIyIGBhUUFhYzAaNtPkFxRo2ZU5VjM1ohJjJUbXwBHmlCOVZXSS9JKSdLNAGpNGE/QmQ3tqd1pVUVFE4hh4EQCS0v/qBKPj5JJD4mJT0lAAEAHgAAAi4CvAAIAFK1AQEBAwFKS7AKUFhAGAACAQABAnAAAQEDXQQBAwNCSwAAAEMATBtAGQACAQABAgB+AAEBA10EAQMDQksAAABDAExZQAwAAAAIAAgRERIFChcrARUBIwEhFSM1Ai7+5WoBFf7AYAK8RP2IAmV91AADACz/+AJYAsQAGwAnADMAPUA6Gw0CBAIBSgACAAQFAgRnBgEDAwFfAAEBSEsHAQUFAF8AAABJAEwoKBwcKDMoMi4sHCccJissJQgKFysAFhUUBgYjIiYmNTQ2NyYmNTQ2NjMyFhYVFAYHAgYVFBYzMjY1NCYjEjY1NCYjIgYVFBYzAhhARH5VVH1EPzwwMj9yS0xzPzMw4lJRSElTVUdTYGBTU15eUwFYVjw/XTIyXT88VhcXTDQ6Vi4uVjozTRcBBD00NDw8NDQ9/dZFOzpDQzo7RQAAAgAc//gCOQLEABsAKQBEQEEQAQUECgEBAgkBAAEDSgcBBQACAQUCZwAEBANfBgEDA0hLAAEBAF8AAABJAEwcHAAAHCkcKCQiABsAGiUkJQgKFysAFhUUBgYjIiYnNxYzMjY1NQYGIyImJjU0NjYzEjY2NTQmJiMiBhUUFjMBoJlTlWMzWiEmM1Rtex5qQkVtPUFwRjhKKSdLNUVVVkkCxLandaVVFRROIYeBGS0vNGE/QmQ3/qAkPiYlPSVKPj5JAAACADL/+AJ6AmAADwAfACpAJwAAAAIDAAJnBQEDAwFfBAEBASYBTBAQAAAQHxAeGBYADwAOJgYHFSsEJiY1NDY2MzIWFhUUBgYjPgI1NCYmIyIGBhUUFhYzAQGES0uEVVSFS0uFVDhXMTFXODhXMTFXOAhOjVlZjU5PjFlZjE9ZNGNERGM0NGNERGM0AAEACAAAAQkCWAAFAB1AGgMBAgABAAIBZQAAACEATAAAAAUABRERBAcWKwERIxEjNQEJY54CWP2oAgFXAAEABgAAAhcCYAAYAC5AKw0MAgMBAwEAAwJKAAIAAQMCAWcEAQMDAF0AAAAhAEwAAAAYABgkJxEFBxcrJRUhNSU2NjU0JiMiByc2NjMyFhYVFAYHBwIX/gkBHTMlTEd0PUsqhFVJbTs0Q7dXVzvnKjohLDZOMzg6LlIzNVc2lAAAAQAG/5QCEQJYABsAPkA7GgEDBBsVAgIDCgEBAgkBAAEESgACAwEDAgF+AAQAAwIEA2UAAQAAAVcAAQEAXwAAAQBPERIkJSUFBxkrABYVFAYGIyImJzcWFjMyNjU0JiMjNTchNSEVBwGlbDx3VkuKLS4lcD5OV1VXOK/+rwHPtwEpbFM8YTktKE8iKUI6OUFG2FdE4gAAAQAm/5wCkQJYAA4ANUAyBgEABAFKAAMFA4MABQQFgwABAAGEBgEEAAAEVQYBBAQAXgIBAAQAThERERIRERAHBxsrJSMVIzUhNQEzASE1MxUzApGFYf57AWZs/qkBDV6FSKysRgHK/kaYmAAAAQAR/5QCGwJYABoAPEA5CgEBAgkBAAECSgADAAQFAwRlBgEFAAIBBQJlAAEAAAFXAAEBAF8AAAEATwAAABoAGRERJCUlBwcZKwAWFRQGBiMiJic3FhYzMjY1NCYjIxMhFSEHMwGOjTt3V0qKLS4kcD5PV2B0nyUBi/7JE04BQXFiPmM5LShPIilDOj9BAW5XwP//ADD/+AJOAsQAAgXGAAAAAQAe/5wCLgJYAAgAXLUBAQEDAUpLsApQWEAdAAIBAAECcAAAAIIEAQMBAQNVBAEDAwFdAAEDAU0bQB4AAgEAAQIAfgAAAIIEAQMBAQNVBAEDAwFdAAEDAU1ZQAwAAAAIAAgRERIFBxcrARUBIwEhFSM1Ai7+5WoBFf7AYAJYRP2IAmV91P//ACz/+AJYAsQAAgXIAAD//wAc/5QCOQJgAQYFyQCcAAmxAAK4/5ywMysA//8AHP85AZIA4gEHBfwAAP8+AAmxAAK4/z6wMysA//8AUf8+AXIA3QEHBf0AAP8+AAmxAAG4/z6wMysA//8AHP8+AXwA4gEHBf4AAP8+AAmxAAG4/z6wMysA//8AG/85AX0A3QEHBf8AAP8+AAmxAAG4/z6wMysA//8AFv8+AZMA3QEHBgAAAP8+AAmxAAG4/z6wMysA//8AG/85AX4A3QEHBgEAAP8+AAmxAAG4/z6wMysA//8AJf85AY4A4gEHBgIAAP8+AAmxAAK4/z6wMysA//8AJP8+AY8A3QEHBgMAAP8+AAmxAAG4/z6wMysA//8AHP85AZIA4gEHBgQAAP8+AAmxAAO4/z6wMysA//8AIP85AYkA4gEHBgUAAP8+AAmxAAK4/z6wMysAAAIAPf/4An8CxAAPABsALEApAAICAF8AAAAlSwUBAwMBXwQBAQEmAUwQEAAAEBsQGhYUAA8ADiYGBxUrBCYmNTQ2NjMyFhYVFAYGIzY2NTQmIyIGFRQWMwEJg0lJg1VVg0lJg1VVaGhVVWhoVQhXom1toldXom1toldZjYCAjY2AgI0AAAEAkAAAAk8CvAAJACdAJAACAgNdAAMDIEsFBAIBAQBdAAAAIQBMAAAACQAJEREREQYHGCslFSE1MxEjNSERAk/+QbesARBXV1cCDlf9mwAAAQA8AAACXQLEABcAMEAtDQwCAwEDAQADAkoAAQECXwACAiVLBAEDAwBdAAAAIQBMAAAAFwAXJCcRBQcXKyUVITUBNjY1NCYjIgcnNjYzMhYVFAYHBwJd/fsBJzYmUk17QUQriVR0hzNG3FdXRAETMkklNj5LOjM3alk3ZEHOAAABAD7/+AJdArwAGgA7QDgZAQMEGhQCAgMKAQECCQEAAQRKAAIDAQMCAX4AAwMEXQAEBCBLAAEBAF8AAAAmAEwREiQkJQUHGSsAFhUUBgYjIiYnNxYzMjY1NCYjIzU3ITUhFQcB6XQ+fVlUiywzVYNTXV5aObr+jQHywwGMa1M8YTktKE9LQzk5QUbYV0TiAAABADUAAAKBArwADgAwQC0GAQAEAUoABQMEAwUEfgYBBAIBAAEEAGYAAwMgSwABASEBTBERERIRERAHBxsrJSMVIzUhNQEzATM1MxUzAoGEX/6XAT1t/s71W4SsrKxGAcr+RpSUAAABAEH/+AJhArwAGgA5QDYKAQECCQEAAQJKBgEFAAIBBQJlAAQEA10AAwMgSwABAQBfAAAAJgBMAAAAGgAZEREkJSUHBxkrABYVFAYGIyImJzcWFjMyNjU0JiMjEyEVIQczAc6TPX1aT44vLih1QlNbZHmqJQGb/rkTVwGlcGI+YzotJ08iKEQ6PkEBblfAAAACAEr/+AJ7AsQAHQAqAERAQREBAgESAQMCGgEFBANKBgEDAAQFAwRnAAICAV8AAQElSwcBBQUAXwAAACYATB4eAAAeKh4pJCIAHQAcJCUmCAcXKwAWFhUUBgYjIiY1NDY2MzIWFwcmIyIGBhUUFzY2MxI2NTQmIyIGFRQWFjMBynFAQ3VKj6BWn2oxWyImNFRLckABHHNHOltcS0lhKk82Aak1YT5BZDi0qG+nWhUUUCM+eFQSCi00/qBMPDxLTDsiPycAAQBJAAACfAK8AAgAUrUBAQEDAUpLsApQWEAYAAIBAAECcAABAQNdBAEDAyBLAAAAIQBMG0AZAAIBAAECAH4AAQEDXQQBAwMgSwAAACEATFlADAAAAAgACBEREgUHFysBFQEjASEVIzUCfP7MaAEp/qBgArxE/YgCZX3UAAMAO//4AoECxAAbACcAMwA9QDobDQIEAgFKAAIABAUCBGcGAQMDAV8AAQElSwcBBQUAXwAAACYATCgoHBwoMygyLiwcJxwmKywlCAcXKwAWFRQGBiMiJiY1NDY3JiY1NDY2MzIWFhUUBgcCBhUUFjMyNjU0JiMSNjU0JiMiBhUUFjMCP0JHhFlZg0ZBPjI0QnhPUHhDNTPwWllOTltcTVlnZ1laZGVZAVhWPD9dMjJdPzxWFxdMNDpWLi5WOjNNFwEEPTQzPT0zND391kQ7O0NDOztEAAACAEH/+AJyAsQAHQAqAERAQRIBBQQKAQECCQEAAQNKBwEFAAIBBQJnAAQEA18GAQMDJUsAAQEAXwAAACYATB4eAAAeKh4pJSMAHQAcJyQlCAcXKwAWFRQGBiMiJic3FjMyNjY1NCcGBiMiJiY1NDY2MxI2NTQmJiMiBhUUFjMB0qBWn2oxWyImNFRLckABHHNHR3FAQ3VKUWEqTzZHW1xLAsS0qG+nWhUUUCM+eFQSCi00NWE+QWQ4/qBMOyI/J0w8PEsAAgA8//gCgAJgAA8AHwAqQCcAAAACAwACZwUBAwMBXwQBAQEmAUwQEAAAEB8QHhgWAA8ADiYGBxUrBCYmNTQ2NjMyFhYVFAYGIz4CNTQmJiMiBgYVFBYWMwELhEtLhFNThEtLhFM4VjAwVjg4VjAwVjgIToxaWoxOToxaWoxOVzVkRERkNTVkRERkNQABAJAAAAJPAlgACQAlQCIAAwACAQMCZQUEAgEBAF0AAAAhAEwAAAAJAAkRERERBgcYKyUVITUzESM1IRECT/5Bt6oBDVdXVwGqV/3/AAABAEcAAAJpAmAAGAAuQCsNDAIDAQMBAAMCSgACAAEDAgFnBAEDAwBdAAAAIQBMAAAAGAAYJCcRBQcXKyUVITUlNjY1NCYjIgcnNjYzMhYWFRQGBwcCaf34ASo3Ik9KeT9MKohYTG88N0TAV1c75ys3Iyw2TjM4Oi1SNTRYNZQAAAEAPv+UAl0CWAAaAD5AOxkBAwQaFAICAwoBAQIJAQABBEoAAgMBAwIBfgAEAAMCBANlAAEAAAFXAAEBAF8AAAEATxESJCQlBQcZKwAWFRQGBiMiJic3FjMyNjU0JiMjNTchNSEVBwHpdD59WVSLLDNVflZfXlo5uv6NAfLDAShrUzxhOS0oT0tCOjlBRthXROIAAQA1/5wCgQJYAA4ANUAyBgEABAFKAAMFA4MABQQFgwABAAGEBgEEAAAEVQYBBAQAXgIBAAQAThERERIRERAHBxsrJSMVIzUhNQEzATM1MxUzAoGEX/6XAT1t/s71W4RIrKxGAcr+RpSUAAEAQf+UAmECWAAaADxAOQoBAQIJAQABAkoAAwAEBQMEZQYBBQACAQUCZQABAAABVwABAQBfAAABAE8AAAAaABkRESQlJQcHGSsAFhUUBgYjIiYnNxYWMzI2NTQmIyMTIRUhBzMBzpM9fVpPji8uKHVCU1tkeaolAZv+uRNXAUFwYj5jOi0nTyIoRDo+QQFuV8D//wBK//gCewLEAAIF5AAAAAEASf+cAnwCWAAIAFy1AQEBAwFKS7AKUFhAHQACAQABAnAAAACCBAEDAQEDVQQBAwMBXQABAwFNG0AeAAIBAAECAH4AAACCBAEDAQEDVQQBAwMBXQABAwFNWUAMAAAACAAIERESBQcXKwEVASMBIRUjNQJ8/sxoASn+oGACWET9iAJlfdT//wA7//gCgQLEAAIF5gAAAAIAQf+UAnICYAAdACoAR0BEEgEFBAoBAQIJAQABA0oGAQMABAUDBGcHAQUAAgEFAmcAAQAAAVcAAQEAXwAAAQBPHh4AAB4qHiklIwAdABwnJCUIBxcrABYVFAYGIyImJzcWMzI2NjU0JwYGIyImJjU0NjYzEjY1NCYmIyIGFRQWMwHSoFafajFbIiY0VEtyQAEcc0dHcUBDdUpRYSpPNkdbXEsCYLSob6daFRRQIz54VBIKLTQ1YT5BZDj+oEw7Ij8nTDw8SwD//wAc/5cBkgFAAQYF/ACcAAmxAAK4/5ywMysA//8AUf+cAXIBOwEGBf0AnAAJsQABuP+csDMrAP//ABz/nAF8AUABBgX+AJwACbEAAbj/nLAzKwD//wAb/5cBfQE7AQYF/wCcAAmxAAG4/5ywMysA//8AFv+cAZMBOwEGBgAAnAAJsQABuP+csDMrAP//ABv/lwF+ATsBBgYBAJwACbEAAbj/nLAzKwD//wAl/5cBjgFAAQYGAgCcAAmxAAK4/5ywMysA//8AJP+cAY8BOwEGBgMAnAAJsQABuP+csDMrAP//ABz/lwGSAUABBgYEAJwACbEAA7j/nLAzKwD//wAg/5cBiQFAAQYGBQCcAAmxAAK4/5ywMysAAAIAHP/7AZIBpAALABcAKkAnAAAAAgMAAmcFAQMDAV8EAQEBKAFMDAwAAAwXDBYSEAALAAokBgcVKxYmNTQ2MzIWFRQGIzY2NTQmIyIGFRQWM4NnZ1RUZ2dUNUBANTVAQDUFc2Jhc3NhYnM8UElJT09JSVAAAQBRAAABcgGfAAkAJUAiAAMAAgEDAmUFBAIBAQBdAAAAIQBMAAAACQAJEREREQYHGCslFSE1MxEjNTMRAXL+33Rsszo6OgErOv6bAAEAHAAAAXwBpAAXAC5AKw4NAgMBAwEAAwJKAAIAAQMCAWcEAQMDAF0AAAAhAEwAAAAXABckJxEFBxcrJRUhNTc2NjU0JiMiBgcnNjMyFhUUBgcHAXz+srkjGTIyJToTMTVzT1YgLYQ6Oi2iHycUHCMXFiZDQjQgOCh0AAABABv/+wF9AZ8AGgA5QDYZAQMEGhQCAgMJAQECCAEAAQRKAAIDAQMCAX4ABAADAgQDZQABAQBfAAAAKABMERIkJSQFBxkrJBYVFAYjIiYnNxYWMzI2NTQmIyM1NyM1IRUHATZHXlY2XxkcGU0sNjg1NS9w5gFBdu5BMjdJHBc1FBgkICAjL3g6LX8AAAEAFgAAAZMBnwAOAC1AKgYBAAQBSgADBQODAAUEBYMGAQQCAQABBABmAAEBIQFMEREREhEREAcHGyslIxUjNSM1EzMDMzUzFTMBk1FF58lOwpg/UWNjYy8BDf7+U1MAAAEAG//7AX4BnwAYADdANAgBAQIHAQABAkoAAwAEBQMEZQYBBQACAQUCZQABAQBfAAAAKABMAAAAGAAXEREkJSMHBxkrJBUUBiMiJic3FhYzMjY1NCYjIzchFSMHMwF+XlY3XhocGU4sNjc6SHUZAQnQDDn1ezdIHBc1FBgkHyEh4zpwAAIAJf/7AY4BpAAYACQAQkA/DgECAQ8BAwIVAQUEA0oAAQACAwECZwYBAwAEBQMEZwcBBQUAXwAAACgATBkZAAAZJBkjHx0AGAAXJCQkCAcXKyQWFRQGIyImNTQ2MzIWFwcmIyIGFRU2NjMWNjU0JiMiBhUUFjMBNVlcSV5me2kfPBUZJjJIVRJGLSM0NDAuOjc1/kY4PElrYmZ2DAw3E09FDBkdzSkiIyorIh4tAAEAJAAAAY8BnwAIAE61AQEBAwFKS7ASUFhAFgACAQABAnAEAQMAAQIDAWUAAAAhAEwbQBcAAgEAAQIAfgQBAwABAgMBZQAAACEATFlADAAAAAgACBEREgUHFysBFQMjEyMVIzUBj8JOu9c/AZ8t/o4BZUiCAAADABz/+wGSAaQAFQAhAC0AO0A4FQsCBAIBSgABBgEDAgEDZwACAAQFAgRnBwEFBQBfAAAAKABMIiIWFiItIiwoJhYhFiApKSQIBxcrJBYVFAYjIiY1NDY3JjU0NjMyFhUUByYGFRQWMzI2NTQmIxI2NTQmIyIGFRQWMwFqKGVXVmQoJkBeTk9fQJ42NjAxNzcxNz8+ODY+PTfLNCQ2QkE3JDQOGz8yPz8zPhuWIhwcIyMbHSL+wScgICYmICAnAAACACD/+wGJAaQAGAAkAEJAPw8BBQQJAQECCAEAAQNKBgEDAAQFAwRnBwEFAAIBBQJnAAEBAF8AAAAoAEwZGQAAGSQZIx8dABgAFyUkJAgHFysAFhUUBiMiJic3FjMyNjU1BgYjIiY1NDYzFjY1NCYjIgYVFBYzASNme2kfPBUZJjJIVRJGLUVZXEk0Ojc1LTU2LwGka2JmdgwMNxNPRQwZHUY4PEnOKyIeLSkiIisA//8AHAEYAZICwQEHBfwAAAEdAAmxAAK4AR2wMysAAAEAUQEdAXICvAAJACRAIQUEAgEAAAEAYQACAgNdAAMDIAJMAAAACQAJEREREQYHGCsBFSE1MxEjNTMRAXL+33RsswFXOjoBKzr+mwABABwBHQF8AsEAFwAtQCoODQIDAQMBAAMCSgQBAwAAAwBhAAEBAl8AAgIlAUwAAAAXABckJxEFBxcrARUhNTc2NjU0JiMiBgcnNjMyFhUUBgcHAXz+srkjGTIyJToTMTVzT1YgLYQBVzotoh8nFBwjFxYmQ0I0IDgodAAAAQAbARgBfQK8ABoAOEA1GQEDBBoUAgIDCQEBAggBAAEESgACAwEDAgF+AAEAAAEAYwADAwRdAAQEIANMERIkJSQFBxkrABYVFAYjIiYnNxYWMzI2NTQmIyM1NyM1IRUHATZHXlY2XxkcGU0sNjg1NS9w5gFBdgILQTI3SRwXNRQYJCAgIy94Oi1/AP//ABYBHQGTArwBBwYAAAABHQAJsQABuAEdsDMrAAABABsBGAF+ArwAGAA4QDUIAQECBwEAAQJKAAEAAAEAYwAEBANdAAMDIEsAAgIFXwYBBQUiAkwAAAAYABcRESQlIwcHGSsAFRQGIyImJzcWFjMyNjU0JiMjNyEVIwczAX5eVjdeGhwZTiw2NzpIdRkBCdAMOQISezdIHBc1FBgkHyEh4zpw//8AJQEYAY4CwQEHBgIAAAEdAAmxAAK4AR2wMysAAAEAJAEdAY8CvAAIAFC1AQEBAwFKS7ASUFhAFwACAQABAnAAAACCAAEBA10EAQMDIAFMG0AYAAIBAAECAH4AAACCAAEBA10EAQMDIAFMWUAMAAAACAAIERESBQcXKwEVAyMTIxUjNQGPwk671z8CvC3+jgFlSIIA//8AHAEYAZICwQEHBgQAAAEdAAmxAAO4AR2wMysA//8AIAEYAYkCwQEHBgUAAAEdAAmxAAK4AR2wMysA//8AHAFCAZIC6wEHBfwAAAFHAAmxAAK4AUewMysA//8AUQFHAXIC5gEHBf0AAAFHAAmxAAG4AUewMysA//8AHAFHAXwC6wEHBf4AAAFHAAmxAAG4AUewMysA//8AGwFCAX0C5gEHBf8AAAFHAAmxAAG4AUewMysA//8AFgFHAZMC5gEHBgAAAAFHAAmxAAG4AUewMysA//8AGwFCAX4C5gEHBgEAAAFHAAmxAAG4AUewMysA//8AJQFCAY4C6wEHBgIAAAFHAAmxAAK4AUewMysA//8AJAFHAY8C5gEHBgMAAAFHAAmxAAG4AUewMysA//8AHAFCAZIC6wEHBgQAAAFHAAmxAAO4AUewMysA//8AIAFCAYkC6wEHBgUAAAFHAAmxAAK4AUewMysAAAH/QgAAAWwCvAADABNAEAAAAEJLAAEBQwFMERACChYrATMBIwEgTP4iTAK8/UQA//8AUQAAA9gCvAAiBgcAAAAjBhoBrgAAAAMF/gJcAAD//wBR//sD2QK8ACIGBwAAACMGGgGuAAAAAwX/AlwAAP//ABz/+wPZAsEAIgYIAAAAIwYaAa4AAAADBf8CXAAA//8AUQAAA+8CvAAiBgcAAAAjBhoBrgAAAAMGAAJcAAD//wAbAAAD7wK8ACIGCQAAACMGGgGuAAAAAwYAAlwAAP//AFH/+wPuArwAIgYHAAAAIwYaAa4AAAADBgQCXAAA//8AG//7A+4CvAAiBgkAAAAjBhoBrgAAAAMGBAJcAAD//wAb//sD7gK8ACIGCwAAACMGGgGuAAAAAwYEAlwAAP//ACT/+wPuArwAIgYNAAAAIwYaAa4AAAADBgQCXAAAAAEAEwFxAX0C5gARACVAIhEQDwwLCgkIBwYDAgENAAEBSgAAAAFdAAEBRABMGBQCChYrARcHJxcjNwcnNyc3FyczBzcXAQZ3H3kBPAF5H3h4H3kBPAF5HwIsQzdHiIhHN0NCOEeHh0c4AAAB/9r/nAF7A0oAAwAXQBQAAAEAgwIBAQF0AAAAAwADEQMKFSsFATMBAST+tlcBSmQDrvxSAAABAEIAzgDIAVcACwAeQBsAAAEBAFcAAAABXwIBAQABTwAAAAsACiQDChUrNiY1NDYzMhYVFAYjaScnHRwmJhzOJx4eJiYeHicAAAEAQgC4APcBbwALAB5AGwAAAQEAVwAAAAFfAgEBAAFPAAAACwAKJAMKFSs2JjU0NjMyFhUUBiN3NTYlJTU1Jbg0KCY1NSYoNAD//wAu//oAtAIXACcGLgAAAZQBAgYuAAAACbEAAbgBlLAzKwAAAQAw/2wAtACDAA4AJUAiCAEAAQFKAgEBAAABVwIBAQEAXQAAAQBNAAAADgANFgMKFSs2FhUUBgcHIzcmJjU0NjOPJQcKLz8lExcmHYMnHQ8cHYuVByEWHib//wAu//oChACDACIGLgAAACMGLgDoAAAAAwYuAdAAAAACAEX/+gDHArwAAwAPACVAIgABAQBdAAAAQksAAgIDXwQBAwNMA0wEBAQPBA4lERAFChcrEzMDIxYmNTQ2MzIWFRQGI05xE0wLJiYcHCQlGwK8/iHjJRsbJSUbGyUAAgBF/2YAxwIXAAsADwAkQCEAAwACAwJhAAAAAV8EAQEBSwBMAAAPDg0MAAsACiQFChUrEhYVFAYjIiY1NDYzEyMTM6IlJBwcJiYcOHESTAIXJhsaJSUaGyb9TwHPAAIAGwAAAqQCvAAbAB8AekuwMlBYQCgPBgIABQMCAQIAAWULAQkJQksOEA0DBwcIXQwKAggIRUsEAQICQwJMG0AmDAoCCA4QDQMHAAgHZg8GAgAFAwIBAgABZQsBCQlCSwQBAgJDAkxZQB4AAB8eHRwAGwAbGhkYFxYVFBMRERERERERERERCh0rAQczFSMHIzcjByM3IzUzNyM1MzczBzM3MwczFSMjBzMCERiLlBZHFr0WRxaKkxmMlRZHFrwWRxaK2rwZvQG/wkm0tLS0ScJJtLS0tEnCAAEALv/6ALQAgwALABlAFgAAAAFfAgEBAUwBTAAAAAsACiQDChUrFiY1NDYzMhYVFAYjVigoHBwmJxsGJx4dJyYeHicAAgAJ//oB+QLEABoAJgA1QDIMCwICAAFKAAIAAwACA34AAAABXwABAUhLAAMDBF8FAQQETARMGxsbJhslJRkkKAYKGCsSNjY3NjY1NCYjIgcnNjYzMhYVFAYGBwYGFSMWJjU0NjMyFhUUBiPkGycgKCZMQ3U+SSqDVm2AGyYgKSdkFyUlHBwkJRsBBT0qHSMzJDE7TzQ2Ol9TKT8qHSU4KeMlGxslJRsbJQACAEX/XgI0AhcACwAmADpANyMiAgMCAUoAAgEDAQIDfgADBgEEAwRkBQEBAQBfAAAASwFMDAwAAAwmDCUhHxYVAAsACiQHChUrACY1NDYzMhYVFAYjAiY1NDY2NzY2NTMUBgYHBgYVFBYzMjcXBgYjAQslJRwcJSUcYYEbJh8oKGQbJyAoJk5BdT5JKoJWAZckGxsmJhsaJf3HXU4oPiocIjcnJjspHCQyIyo5TzQ2OgD//wA/Aa4BSAK8ACIGMgAAAAMGMgC1AAAAAQA/Aa4AkwK8AAMAE0AQAAEBAF0AAABCAUwREAIKFisTMwMjP1QHRwK8/vIA//8ALv9sALQCFwAnBi4AAAGUAQIGKQAAAAmxAAG4AZSwMysAAAH/5P+cAYUDSgADABFADgAAAQCDAAEBdBEQAgoWKwEzASMBLlf+tlcDSvxSAAABAAD/wgH0AAAAAwAgsQZkREAVAAABAQBVAAAAAV0AAQABTREQAgoWK7EGAEQxIRUhAfT+DD4AAAH/2v+cAXsDSgADABdAFAAAAQCDAgEBAXQAAAADAAMRAwcVKwUBMwEBJP62VwFKZAOu/FIAAAEATAEaANIBowALAB5AGwAAAQEAVwAAAAFfAgEBAAFPAAAACwAKJAMHFSsSJjU0NjMyFhUUBiNzJycdHCYmHAEaJx4eJiYeHif//wBMAQQBAQG7AQYGJwpMAAixAAGwTLAzKwABAH4BbQD3AekACwAeQBsAAAEBAFcAAAABXwIBAQABTwAAAAsACiQDBxUrEiY1NDYzMhYVFAYjoiQkGRkjIxkBbSMbGyMjGxsjAAH/5P+cAYUDSgADABFADgAAAQCDAAEBdBEQAgcWKwEzASMBLlf+tlcDSvxSAAABAC0A3QCgAU8ACwAeQBsAAAEBAFcAAAABXwIBAQABTwAAAAsACiQDBxUrNiY1NDYzMhYVFAYjTiEhGRghIRjdIRgYISEYGCEAAAEAOf8+AUwC5gAgAC9ALAIBAgMBSgADAAIAAwJnAAUFBF8ABARESwAAAAFfAAEBRwFMISQhJCEnBgoaKxIGBxYWFRUUMzMVIyImNTU0IyM1MzI1NTQ2MzMVIyIVFekaHR0aShksS0wtIyMtTEssGUoBRSoJCSop205PS0nmMlAy5klLT07bAAABABP/PgElAuYAIAA1QDIRAQAFAUoGAQUAAAIFAGcAAwMEXwAEBERLAAICAV8AAQFHAUwAAAAgAB8hKiEkIQcKGSsBFSMiFRUUBiMjNTMyNTU0NjcmJjU1NCMjNTMyFhUVFDMBJSIsTUssGEwZHR0ZTBgsS00sATpQMuZJS09O2yopCQkpKttOT0tJ5jIAAQBp/z4BOgLmAAcAH0AcAAEBAF0AAABESwACAgNdAAMDRwNMEREREAQKGCsTMxUjETMVI2nRcXHRAuZP/PZPAAEAE/8+AOQC5gAHACVAIgABAQJdAAICREsAAAADXQQBAwNHA0wAAAAHAAcREREFChcrFzUzESM1MxETcXHRwk8DCk/8WAABAF//PgExAuYADQATQBAAAABESwABAUcBTBYVAgoWKxYmNTQ2NzMGBhUUFhcjnT4+OVs8ODg8W2bviYnxWmnmhYXmaQAAAQAg/z4A8wLmAA0AGUAWAAAAREsCAQEBRwFMAAAADQANFgMKFSsXNjY1NCYnMxYWFRQGByA8OTk8Wzo+PjrCaeaFheZpWvCKifBb//8AQ/+BAVYDKQEGBjwKQwAIsQABsEOwMyv//wAd/4EBLwMpAQYGPQpDAAixAAGwQ7AzK///AHP/gQFEAykBBgY+CkMACLEAAbBDsDMr//8AHf+BAO4DKQEGBj8KQwAIsQABsEOwMyv//wBp/4EBOwMpAQYGQApDAAixAAGwQ7AzK///ACr/gQD9AykBBgZBCkMACLEAAbBDsDMrAAEAAADxA+gBNAADABhAFQAAAQEAVQAAAAFdAAEAAU0REAIKFisRIRUhA+j8GAE0QwAAAQAAAPEB9AE0AAMAGEAVAAABAQBVAAAAAV0AAQABTREQAgoWKxEhFSEB9P4MATRDAAABAC8BQgKNAYUAAwAYQBUAAAEBAFUAAAABXQABAAFNERACChYrEyEVIS8CXv2iAYVD//8AAADxA+gBNAACBkgAAAABADkA6QFGATwAAwAYQBUAAAEBAFUAAAABXQABAAFNERACChYrEyEVITkBDf7zATxT//8AOQDpAUYBPAACBkwAAP//ADkA6QFGATwAAgZMAAD//wAAAUAD6AGDAQYGSABPAAixAAGwT7AzK///AAABQAH0AYMBBgZJAE8ACLEAAbBPsDMr//8AQwE4AVABiwEGBkwKTwAIsQABsE+wMyv//wAuAEoB1gHJACIGVAAAAAMGVADAAAD//wAiAEoBygHJACIGVQAAAAMGVQDAAAAAAQAuAEoBFgHJAAUAHkAbAwEBAAFKAAABAQBVAAAAAV0AAQABTRIRAgoWKxM3MwcXIy6QWI2NWAEJwMC/AAABACIASgEKAckABQAlQCIEAQIBAAFKAAABAQBVAAAAAV0CAQEAAU0AAAAFAAUSAwoVKzc3JzMXByKNjViQkEq/wMC///8AMP9sAXEAgwAiBlsAAAADBlsAvQAA//8ALgHPAXAC5gAiBlkAAAADBlkAvQAA//8AMAHVAXEC7AAiBloAAAADBloAvQAAAAEALgHPALMC5gAOABlAFg4BAAEBSgAAAAFdAAEBRABMFiQCChYrEhYVFAYjIiY1NDY3NzMHnRYmHB0mBwsvPyUCSiAXHiYnHQ4dHIyVAAEAMAHVALQC7AAOAB9AHAgBAAEBSgAAAAFfAgEBAUQATAAAAA4ADRYDChUrEhYVFAYHByM3JiY1NDYzjyUGCjA/JRMXJh0C7CcdDx0bjJUHIRYeJgAAAQAw/2wAtACDAA4AJUAiCAEAAQFKAgEBAAABVwIBAQEAXQAAAQBNAAAADgANFgMKFSs2FhUUBgcHIzcmJjU0NjOPJQcKLz8lExcmHYMnHQ8cHYuVByEWHib//wA4AJkB4AIYACYGVApPAQcGVADKAE8AELEAAbBPsDMrsQEBsE+wMyv//wAsAJkB1AIYACYGVQpPAQcGVQDKAE8AELEAAbBPsDMrsQEBsE+wMyv//wA4AJkBIAIYAQYGVApPAAixAAGwT7AzK///ACwAmQEUAhgBBgZVCk8ACLEAAbBPsDMrAAIARf/6AMcCOAADAA8AJUAiAAEBAF0AAAAuSwACAgNfBAEDAzEDTAQEBA8EDiUREAUIFysTMwMjFiY1NDYzMhYVFAYjUG0RTAkkJB4cJCQcAjj+kc8kGBkjIxkYJAACAEUAAADHAj8ACwAPACdAJAAAAAFfBAEBATBLAAMDAl0AAgIvAkwAAA8ODQwACwAKJAUIFSsSFhUUBiMiJjU0NjMTIxMzoyQkHB4kJR02bRBMAj8lGBkjIxkZJP3BAW8A//8ALgBwAbkByAAiBmQAAAADBmQAuQAA//8AIgBwAa4ByAAiBmUAAAADBmUAuQAAAAEALgBwAQAByAAFAB5AGwMBAQABSgAAAQEAVQAAAAFdAAEAAU0SEQIIFisTNzMHFyMuglCAgFABHKysrAAAAQAiAHAA9QHIAAUAJUAiBAECAQABSgAAAQEAVQAAAAFdAgEBAAFNAAAABQAFEgMIFSs3NyczFwcigIBQg4NwrKysrAABADP/+gC0AHoACwAZQBYAAAABXwIBAQExAUwAAAALAAokAwgVKxYmNTQ2MzIWFRQGI1glJBwcJSUcBiUbGyUlGxslAAIACP/6AcUCPwAYACQAOUA2CgECAAFKCwEAAUkAAgADAAIDfgAAAAFfAAEBMEsAAwMEXwUBBAQxBEwZGRkkGSMlGCQnBggYKzY2NzY2NTQmIyIHJzY2MzIWFRQGBwYGFSMWJjU0NjMyFhUUBiPLKyohIUE8YzdDJ3ZLYHUsKyQkWxMkJB0dJCQd9TcgGSYaISc3NyYsSkEtOCEbKx/PJBgZIyMZGCQAAAIARf/6AgICPwALACQAPUA6ISACAwIBSgACAQMBAgN+BQEBAQBfAAAAMEsAAwMEYAYBBAQxBEwMDAAADCQMIx8dFRQACwAKJAcIFSsSJjU0NjMyFhUUBiMCJjU0Njc2NjUzFAYHBgYVFBYzMjcXBgYj8iQlHB0kJB1VdS0qJSNbKyohIUE8YjlCJ3ZKAcYjGRglJRgZI/40SkAtOiAcKR8sNyAZJhohJzc2JiwA//8APwFSAUgCOAAiBnAAAAADBnAAtQAA//8AMP+GAXEAfwAiBm8AAAADBm8AvQAA//8ALgFAAXACOAAiBm0AAAADBm0AvQAA//8AMAFGAXECPwAiBm4AAAADBm4AvQAAAAEALgFAALMCOAAOABlAFg4BAAEBSgAAAAFdAAEBLgBMFiQCCBYrEhYVFAYjIiY1NDY3NzMHnBcmHB0mBwooPx0BtyAVHCYlHQ4cG3F6AAEAMAFGALQCPwAOAB9AHAgBAAEBSgAAAAFfAgEBATAATAAAAA4ADRYDCBUrEhYVFAYHByM3JiY1NDYzjiYGCik/HhMXJRwCPyYdDhsccXoGIBYdJgAAAQAw/4YAtAB/AA4AJUAiCAEAAQFKAgEBAAABVwIBAQEAXQAAAQBNAAAADgANFgMIFSs2FhUUBgcHIzcmJjU0NjOPJQYKKD8dExcmHX8lHQ8cHHB6ByEVHCYAAQA/AVIAkwI4AAMAE0AQAAEBAF0AAAAuAUwREAIIFisTMwcjP1QHRwI45gABACT/PgEeAuYABQAXQBQDAQEAAUoAAAEAgwABAXQSEQINFisTEzMDEyMko1ecnFcBEgHU/iz+LAD//wAr/z4BJQLmAQ8GcQFJAiTAAAAJsQABuAIksDMrAAACADD/iAKtAzQAGgAjAERAQRABBAMfHhcWAgEGBQQIAQAFA0oAAgMCgwABAAGEAAQEA18AAwNISwYBBQUAXwAAAEkATAAAABoAGhQRGhEUBwoZKyQ3FwYGBxUjNS4CNTQ2Njc1MxUWFhcHJicRJBYWFxEOAhUCIUtBLYBMQV2TU1OTXUFMgC1BSm7+4DllQUFlOVZPPzM4A3BzCmCbXl6bYApzcAM3Mz9OBf3myXBKCwISC0pwRAAAAgAq/4gCGgKKABoAIQApQCYeHRoZFxYTEAgFAgEMAAEBSgABAAABVQABAQBdAAABAE0aFgIKFiskNxcGBgcVIzUuAjU0NjY3NTMVFhYXByYnESYWFxEGBhUBpypJHGRAQEZtPT1sR0BAZBxJKk3PT0BAT1pALjI6BXN0CEl0SEhzSQh1dAU5Mi9ACv6Pb2ILAW0MYkgAAwAw/4gCrQM0ACMAKgAyAH9AGR0aAgcELi0qJiIgHwIBCQYHDgsJAwAGA0pLsApQWEAjBQEDBAQDbgIBAQABhAAHBwRfAAQESEsIAQYGAF8AAABJAEwbQCIFAQMEA4MCAQEAAYQABwcEXwAEBEhLCAEGBgBfAAAASQBMWUARAAAoJwAjACMSERkUEhQJChorJDcXBgYjIwcjNyYnByM3JiY1NDY2NzczBxYXNzMHFhcHJicDJhcTJiMjAyYWFxMOAhUCIUtBMIlSBRw9HigtIz0qTllWmWAdPR0tKiA9JTgqQRwdf2gshSktAYGRMCx3PmA1Vk8/NjhwdQURi6Yvn2JgnWAIcXEBDX+TGy8/HRH+CwoHAgsM/gOxaSUB0w1KbkEAAAIAH//+Ap0CfQAdAC0ASkBHGhgUEgQCARsRDAEEAwILCQQCBAADA0oZEwIBSAoDAgBHAAEAAgMBAmcEAQMAAANXBAEDAwBfAAADAE8eHh4tHiwtLiUFChcrJAcXBycGIyImJwcnNyYmNTQ3JzcXNjMyFzcXBxYVBjY2NTQmJiMiBgYVFBYWMwJuOGc4akhVK1EhazdnGh01ZTdpSFdWSWg4ZTbcWjU1WjQ0WDQ0WDTnSGY7aTAZGGo7ZyJSK1ZIZTtoMzJnO2RHWLkyVTIyVjIyVjIyVTIAAAMAKf+IAkQDNAAiACkAMABLQEgmGgIFBC8lHhsNCQYCBTABAQICAQABBEoUAQQIAQICSQADBAODAAABAIQABQUEXwAEBEhLAAICAV8AAQFMAUwUERkVERMGChorJAYHFSM1JiYnNxYWFzUuAjU0Njc1MxUWFhcHJicVHgIVABYXNQYGFQA2NTQmJxUCRHdxQEmDJyUkbjxGXT9zb0A5aychUVlJXkH+WEI+QEABA0NFQXBuCXFxBC8kTiErBOgRKE4/T24JcnECIBtQMwXpEidNQAEWMBDYCDsq/lU5KywvEtcAAAMAKv97AqoC5gAaACoALgCSthMFAgkIAUpLsCdQWEAuDAcCBQQBAAMFAGUACgALCgthAAYGREsACAgDXwADA0tLDQEJCQFfAgEBAUMBTBtAMgwHAgUEAQADBQBlAAoACwoLYQAGBkRLAAgIA18AAwNLSwABAUNLDQEJCQJfAAICTAJMWUAcGxsAAC4tLCsbKhspIyEAGgAaERETJiMREQ4KGysBFSMRIzUGBiMiJiY1NDY2MzIWFzUjNTM1MxUCNjY1NCYmIyIGBhUUFhYzBSEVIQKqW1wgYjtNekVFek05YCDS0mDfUi4uUjIzUS8vUTP/AQIR/e8Clzj9oVQsLkR7UFB6RCsqnThPT/23L1U3N1UuLlU3N1UvmzgAAQAe//gDAQLEAC0AT0BMGxoCBAYCAQILAQJKBwEECAEDAgQDZQkBAgoBAQsCAWUABgYFXwAFBUhLDAELCwBfAAAASQBMAAAALQAsKikoJxESJCMRFBETJA0KHSskNxcGBiMiJiYnIzUzJjU0NyM1Mz4CMzIWFwcmIyIGByEVIQYVFBchFSEWFjMCcVBAL4pSV5RmFXJoAgJochVmlFdTiS9AT3dbihwBPf61AwMBS/7DHIpbUVQ/NjhBdk44Gg8PGjhOdkE4NT9TXk44ExYVFDhOXgAB/6T/OAHkAuwAIQB0QBIeAQcGHwEABw4BAwENAQIDBEpLsCdQWEAiCAEHBwZfAAYGREsEAQEBAF0FAQAARUsAAwMCXwACAk0CTBtAIAUBAAQBAQMAAWUIAQcHBl8ABgZESwADAwJfAAICTQJMWUAQAAAAIQAgIxETJCMREwkKGysABgcHMwcjAwYGIyImJzcWMzI2NxMjNzM3NjYzMhYXByYjAU4yBgeaCZg6CWJOIzwSJB4rJzEFOlsKWwcJZVAgOxIlHCoCmy8uOU/+LU5dERBJGTAtAdBPPE5dERBJGQAAAQAeAAACcwK8ABEAN0A0AAAAAQIAAWUGAQIFAQMEAgNlCQEICAddAAcHQksABARDBEwAAAARABEREREREREREQoKHCsTFSEVIRUzFSMVIzUjNTMRIRXpAV/+od7eZGdnAe4CZfRWbTl1dTkCDlcAAAIAMP+IArQDNAAcACUASkBHEAEFBCEXFgMABSAcAgYACAICAQYESgADBAODAAAFBgUABn4AAgEChAAFBQRfAAQESEsABgYBXwABAUkBTBEUERoRExAHChsrATMRBgYHFSM1LgI1NDY2NzUzFRYWFwcmJxE2NyQWFhcRDgIVAk5gMYJHQV6TUlKTXkFPhC0+UXFZQf5GOGVCQmU4AWL+7ykuAnBzCmGaXl6ZYQtzcAI3Mz5OA/3mAyqdcEoLAhALSm9EAAACAFf/9wLbAsUAFgAtAFRAUQ0BAgMMAQECIgEHBiMBCAcESgoEAgEAAAUBAGUABQkBBgcFBmUAAgIDXwADA0hLAAcHCF8ACAhJCEwAAC0sJyUgHhoZGBcAFgAWJSQREQsKGCsBFSE1ITY1NCYjIgYHJzY2MzIWFhUUBwUhFSEGFRQWMzI2NxcGBiMiJiY1NDcjAtv9fAG2LVVUMWYtGjFyOFV7Pwv9xQKE/kwxVVZDfyodM4tIV3tAD0oBwTg4GyQxPhkYUBodNFs6IBuKOB0pMTspIE4mKzNaOyQcAAABAB4AAAKTArwAEwAvQCwIBgIECgkDAwEABAFmBwEFBUJLAgEAAEMATAAAABMAExEREREREREREQsKHSsBASMBIxEjESM1MxEzETMBMwEzFQF5ARp2/uUbY2ZmYxsBG3b+5s8BPf7DAT3+wwE9QgE9/sMBPf7DQgABAB4AAAJ3AsQAIwBLQEgVAQgHFgEGCAJKCQEGCgEFBAYFZQsBBAwBAwAEA2UACAgHXwAHB0hLAgEAAAFdAAEBQwFMIyIhIB8eHRskJBERERERERANCh0rNyEVITUzNSM1MzUjNTM1NDY2MzIWFwcmIyIGFRUhFSEVIRUh7gF6/bZtbW1tbUWFXT1fKSFBbFxfAQr+9gEK/vZXV1emOFI4AU91QBgaUyxYUgI4UjgAAAEAHgAAAp4CvAAbADpANxQTEhEQDw4LCggKAwEVCQcGBQQGAgMCSgADAQIBAwJ+AAEBQksAAgIAXgAAAEMATBIpGSEEChgrJAYjIxEHNTc1BzU3NTMVJRUFFSUVBRUzMjY1MwKezsZ/bW1tbWMBCv72AQr+9jGMj2O5uQEJOTw5Ujk8Oem1jDuMUow8jOiLgAAAAQBpAAADKwM0ABkAIkAfGRYMCQQBAwFKAAMAAQADAWUCAQAAQwBMFhUVFAQKGCsAFhYVESMRNCYnESMRBgYVESMRNDY2NzUzFQJKkVBcdW9Ab3ZdUZFgQAK7Yaty/sMBO42aCv4MAfQKm4z+xQE9cqtiB3FxAAUAHgAAA1ICvAAbAB4AIgAmACkAYkBfHgEICSkBAgECSg4MCgMIEQ8UDQQHAAgHZRIVEAYEABMFAwMBAgABZQsBCQlCSwQBAgJDAkwfHwAAKCcmJSQjHyIfIiEgHRwAGwAbGhkYFxYVFBMREREREREREREWCh0rARUzFSMVIycjFSM1IzUzNSM1MzUzFzM1MxUzFSUzJxcnIxUlIxczFSMXAuVtbVLM2WNtbW1tUsvZZG39nD09rEJqAZOsQmo9PQGHUjj9/f39OFI4/f39/Tg4TNZSUlJSOEz//wBp//oGTQK8ACIApwAAACMCSALXAAAAAwI6BHUAAAAEAB4AAAMtArwAHAAhACgALQCSS7AWUFhAMw4GAgEPBQICEAECZREBEAADBBADZQAMDAldAAkJQksNBwIAAAhdCwoCCAhFSwAEBEMETBtAMQsKAggNBwIAAQgAZQ4GAgEPBQICEAECZREBEAADBBADZQAMDAldAAkJQksABARDBExZQCApKSktKSwrKiYlJCMhHx4dHBsZFxERERERIhEUEBIKHSsBIxYVFAczFSMGBiMjFSMRIzUzNSM1MzUhMhYXMyEhJiMjBCchFSE2NQY3IRUzAy1wAwNwfx2NaK5jbW1tbQERaI0df/3BAU8wdKsBbgT+lgFqBE8w/rGrAfETFhUUOEZN1AFnOFI4k01GPIURUhEYnTw8AAACAB4AAAK6ArwAEgAbADlANgAICQEGAAgGZQQBAAMBAQIAAWUABwcFXQAFBUJLAAICQwJMAAAZFxYUABIAESEREREREQoKGis3FTMVIxUjNSM1MxEhMhYVFAYjEiYjIxEzMjY16d7eZWZmAROJmpqJvmJcrq5bY+k7OXV1OQIOeXBxeQEwTP7XT0cAAAEAHQAAAp4CvAAgAD9APAsBBAUBSgADBAOEAAkIAQABCQBlBwEBBgECBQECZQAFBAQFVQAFBQRdAAQFBE0gHyERFCEiFhESEAoNHSsBIxYXMxUjFhUUBgcTIycGIyM1MzI2NTQnITUhJgcjNSECnrMsE3RnAlNMrG2fDBitqmJgAv5KAaQuiO4CgQKDHzM5ChRPbhn+/PIBVlFEChI5UwE5AAEAHgAAAncCxAAbADlANhEBBgUSAQQGAkoHAQQIAQMABANlAAYGBV8ABQVISwIBAAABXQABAUMBTBETJCQREREREAkKHSs3IRUhNTM1IzUzNTQ2NjMyFhcHJiMiBhUVIRUh7gF6/bZtbW1FhV09XykhQWxcXwEK/vZXV1fmQkFPdUAYGlMsWFJCQgAAAgBMAAACjgK8AAMACwAlQCIAAwQBAgUDAmUAAQEAXQAAAEJLAAUFQwVMEREREREQBgoaKxMhFSEXIzUhFSMRI0wCQv2+7+8CQvBjArw6iDo6/gYAAQAzAAACdwK8ABcANkAzEhEQDw4NDAsIBwYFBAMCARAAAQFKBAMCAQECXQACAkJLAAAAQwBMAAAAFwAXERkZBQoXKwEVNxUHFTcVBxUjNQc1NzUHNTc1IzUhFQGHpaWlpWSkpKSk8AJEAmWvUjxSUlI8Uuy6UjxSUlI8UuFXVwAHAB4AAASMArwAHwAiACYAKgAuADEANAByQG8iAQgJNDECAgECShAODAoECBUTEhkPBQcACAdmFhoUEQYFABgXBQMEAQIAAWUNCwIJCUJLBAECAkMCTCcnAAAzMjAvLi0sKycqJyopKCYlJCMhIAAfAB8eHRwbGhkYFxYVFBMREREREREREREbCh0rAQczFSMHIycjByMnIzUzJyM1MyczFzM3MxczNzMHMxUlMycFMzcjBScjByUjFzMFIxclIxcEEByYrFhqW9xbalmrmB17aFloWN9bX1nhWWNYaP2gUin+yH4duAGvHXodAbG5HYD99lYqAiJYLAGHUjj9/f39OFI4/f39/f39ODhx+1JSUlJSUjh6en0AAf/8AAACxwK8ABYAOUA2FAEACQFKCAEABwEBAgABZgYBAgUBAwQCA2UKAQkJQksABARDBEwWFRMSEREREREREREQCwodKwEzFSMVMxUjFSM1IzUzNSM1MwEzExMzAbK009PTY9PT07X+6mr9/mYBODlROXV1OVE5AYT+ngFiAP//AEwBGgDSAaMAAgY3AAAAAwBMAAABzQK8AAsADwAbADJALwYBAQEAXwIBAABCSwAEBANgBwUCAwNDA0wQEAAAEBsQGhYUDw4NDAALAAokCAoVKxImNTQ2MzIWFRQGIzczAyMgJjU0NjMyFhUUBiNvIyMZGCMjGN5K/UkBDyMjGBkjIxkCRyIYGSIiGRgidf1EIhkYIiEZGSL////k/5wBhQNKAAIGNAAAAAEAQwCDAgMCOQALACZAIwAEAwEEVQUBAwIBAAEDAGUABAQBXQABBAFNEREREREQBgoaKwEjFSM1IzUzNTMVMwIDtlS2tlS2ATazs0+0tAAAAQBDATYCAwGFAAMAGEAVAAABAQBVAAAAAV0AAQABTREQAg0WKxMhFSFDAcD+QAGFTwABAGsAogHcAhoACwAGswgCATArARcHJwcnNyc3FzcXAVuBNoODNYGBNYODNgFegjqEhDqCgjqEhDoAAwBDAF0CAwJfAAsADwAbADtAOAAABgEBAgABZwACAAMEAgNlAAQFBQRXAAQEBV8HAQUEBU8QEAAAEBsQGhYUDw4NDAALAAokCAoVKwAmNTQ2MzIWFRQGIwchFSEWJjU0NjMyFhUUBiMBCyEhGBkhIRngAcD+QMghIRgZISEZAecjGRoiIhoaImJP2SMaGSIiGRojAAIAQwDAAgMB/AADAAcAPkuwFlBYQBIAAgADAgNhAAEBAF0AAABFAUwbQBgAAAABAgABZQACAwMCVQACAgNdAAMCA01ZthERERAEChgrEyEVIRUhFSFDAcD+QAHA/kAB/E+eTwABAEMASQIDAnMAEwByS7ALUFhAKgAHBgYHbgACAQECbwgBBgoJAgUABgVmBAEAAQEAVQQBAAABXQMBAQABTRtAKAAHBgeDAAIBAoQIAQYKCQIFAAYFZgQBAAEBAFUEAQAAAV0DAQEAAU1ZQBIAAAATABMRERERERERERELDR0rAQczFSEHIzcjNTM3IzUhNzMHMxUBdlXi/vNAUUBijVbjAQ5AUEBiAa2eT3d3T55Pd3dPAAABAEMAggIDAjoABgAGswYCATArARUFNSUlNQID/kABZP6cAYlWsVOJiVMAAAEAQwCCAgMCOgAGAAazBgMBMCsBBQUVJTUlAgP+nQFj/kABwAHniYlTsVaxAAACAEMAAAIDAlsABgAKACJAHwYFBAMCAQAHAEgAAAEBAFUAAAABXQABAAFNERcCDRYrARUFNSUlNREhFSECA/5AAVn+pwHA/kABsVSqUoKCUv30TwACAEMAAAIDAlsABgAKACJAHwYFBAMCAQAHAEgAAAEBAFUAAAABXQABAAFNERcCDRYrAQUFFSU1JQEhFSECA/6oAVj+QAHA/kABwP5AAgmCglKqVKr99E8AAgBDAAACAwJkAAsADwAzQDAIBQIDAgEAAQMAZQAEAAEGBAFlAAYGB10ABwdDB0wAAA8ODQwACwALEREREREJChkrARUjFSM1IzUzNTMVASEVIQIDtlS2tlT+9gHA/kABtk+urk+urv6ZTwAAAgA6AJMCDAIpABkAMwBrQGgABAIAAgQAfgABAwUDAQV+AAoIBggKBn4ABwkLCQcLfgACAAADAgBnAAMMAQUIAwVnAAgABgkIBmcACQcLCVcACQkLXw0BCwkLTxoaAAAaMxoyMC8tKyclIyIgHgAZABgSJCISJA4NGSsAJicmJiMiBgcjNjYzMhYXFhYzMjY3MwYGIwYmJyYmIyIGByM2NjMyFhcWFjMyNjczBgYjAWU3IBkhEyAmAj8CRzskNSEZIRMhJQI/Akc7IzYhGSETICYCPwJHOyQ1IRkhEyElAj8CRzsBfR4bFRQxKVFTHRwVFDEqUlPqHRsVFDEpUVMdHBUUMSpRUwAAAQA6AQkCDAG0ABkAk7EGZERLsCFQWEAbBAECAAADAgBnAAMBAQNXAAMDAV8GBQIBAwFPG0uwJ1BYQCIAAQMFAwEFfgQBAgAAAwIAZwADAQUDVwADAwVfBgEFAwVPG0ApAAQCAAIEAH4AAQMFAwEFfgACAAADAgBnAAMBBQNXAAMDBV8GAQUDBU9ZWUAOAAAAGQAYEiQiEiQHChkrsQYARAAmJyYmIyIGByM2NjMyFhcWFjMyNjczBgYjAWU2IRkhEyAmAj8CRzskNSEaIBMhJQI/Akc7AQkdGxUUMSlRUx0cFRMxKlJTAAEAQwCFAgMBhgAFAB5AGwAAAQCEAAIBAQJVAAICAV0AAQIBTREREAMKFyslIzUhNSECA1X+lQHAhbJPAAMAJQBaAiECPAAXACAAKQA+QDsXFQICASMiGhkMBQMCCwkCAAMDShYBAUgKAQBHAAEAAgMBAmcAAwAAA1cAAwMAXwAAAwBPJygqJQQNGCsBFhUUBgYjIiYnByc3JjU0NjYzMhYXNxcEFzcmIyIGBhUkJwcWMzI2NjUB0Sw6ZDsoSB1UHlMtOmQ7KUkdUR3+bRvZJzcpRSgBLRraKjMpRigB0DlJO2Q7HBlPIU47SjtiOhwZTCH+JsshKEUoLSfMIClGKQADACoAmQNxAiMAGwAnADMASkBHMB4YCgQFBAFKCAMCAgYBBAUCBGcKBwkDBQAABVcKBwkDBQUAXwEBAAUATygoHBwAACgzKDIuLBwnHCYiIAAbABomJCYLDRcrABYWFRQGBiMiJicGBiMiJiY1NDY2MzIWFzY2MwA2NyYmIyIGFRQWMyA2NTQmIyIGBxYWMwLiWzQ0WzhQYykoZFA4XDQ0XDhQZCgpY1D+iksmJks8N0lJNwHjSEg3PEsmJks8AiMzWTg4WzNFPj5FM1o4OFozRT4+Rf7BPjw8PkU1NUVGNTRFPjw8PgAAAf/d/zgBsgLuABgAN0A0DgECAQ8DAgACAgEDAANKAAEAAgABAmcAAAMDAFcAAAADXwQBAwADTwAAABgAFyMlJAUNFysWJic3FjMyNjURNDYzMhcHJiMiBhURFAYjLz0VHR4tJytXTkwqHh4sKCtXTsgREEkZMC0CXk5cIUgYLy39ok9cAP//AAkAAAN5AsQAAgW7AAD/////AAAC3QK8AAIFugAAAAEAaf8+AsMCvAAHACBAHQMBAQIBhAAAAgIAVQAAAAJdAAIAAk0REREQBA0YKxMhESMRIREjaQJaZP5uZAK8/IIDI/zdAAABACv/PgJ0ArwADAA5QDYFAQIBCwoEAwMCAwEAAwNKAAEAAgMBAmUEAQMAAANVBAEDAwBdAAADAE0AAAAMAAwRFBEFDRcrBRUhNQEBNSEVIQEVAQJ0/bcBSf7EAjX+UgET/t9rV0QBfAF6RFf+u0X+ugABAEP/PgMkAuYACAAwQC0HAQABAUoEAQMCA4MAAAEAhAACAQECVQACAgFdAAECAU0AAAAIAAgREREFDRcrAQEjAyM1MxMBAyT+v2O6g8qkARgC5vxYAflP/jQDLAD//wBb/z4CTgISAAIFvAAAAAIASP/4AnQC1gAbACkASEBFGQECAxgBAQIRAQUEA0oGAQMAAgEDAmcAAQAEBQEEZwcBBQAABVcHAQUFAF8AAAUATxwcAAAcKRwoJCIAGwAaJiYlCA0XKwAWFRQGBiMiJiY1NDY2MzIWFzY1NCYjIgcnNjMSNjY1NCYmIyIGFRQWMwG+tkeJX0d0QkJ0SURpHgGFd01ED0pXZ08pK0swTlpaSALWyLVsn1Y3ZkNDZTc3NAwWg5EVUhf9cyhBJihBJU5AQE8AAAUAJf/6AyYCwgALAA8AGwAnADMAwkuwJ1BYQCUGCwIFCAoCAQkFAWgABAQAXwIBAABISw0BCQkDXwwHAgMDQwNMG0uwLlBYQC0GCwIFCAoCAQkFAWgAAgJCSwAEBABfAAAASEsAAwNDSw0BCQkHXwwBBwdMB0wbQDMLAQUKAQEIBQFnAAYACAkGCGgAAgJCSwAEBABfAAAASEsAAwNDSw0BCQkHXwwBBwdMB0xZWUAmKCgcHBAQAAAoMygyLiwcJxwmIiAQGxAaFhQPDg0MAAsACiQOChUrEiY1NDYzMhYVFAYjATMBIxI2NTQmIyIGFRQWMwAmNTQ2MzIWFRQGIzY2NTQmIyIGFRQWM39aWklJWVlJAaZN/iJNZjQ0Li01NS0BcllZSUlaWkktNTUtLjQ0LgFEalVVamlWVmkBeP1EAX1HPz9HSD4+SP59aVZWaWpVVWo5SD4+SEc/P0cABwAl//oElALCAAsADwAbACcAMwA/AEsA5EuwJ1BYQCsIBg8DBQwKDgMBCwUBaAAEBABfAgEAAEhLEw0SAwsLA18RCRAHBAMDQwNMG0uwLlBYQDMIBg8DBQwKDgMBCwUBaAACAkJLAAQEAF8AAABISwADA0NLEw0SAwsLB18RCRADBwdMB0wbQDkPAQUOAQEKBQFnCAEGDAEKCwYKaAACAkJLAAQEAF8AAABISwADA0NLEw0SAwsLB18RCRADBwdMB0xZWUA2QEA0NCgoHBwQEAAAQEtASkZEND80Pjo4KDMoMi4sHCccJiIgEBsQGhYUDw4NDAALAAokFAoVKxImNTQ2MzIWFRQGIwEzASMSNjU0JiMiBhUUFjMAJjU0NjMyFhUUBiMgJjU0NjMyFhUUBiMkNjU0JiMiBhUUFjMgNjU0JiMiBhUUFjN/WlpJSVlZSQGmTf4iTWY0NC4tNTUtAXJZWUlJWlpJASZaWklJWVlJ/r41NS0uNDQuAZw1NS0uNDQuAURqVVVqaVZWaQF4/UQBfUc/P0dIPj5I/n1pVlZpalVVamlWVmlpVlZpOUg+PkhHPz9HSD4+SEc/P0cAAAEAYAA3AfgB8QAIABVAEggHBgUEAQAHAEgAAAB0EgENFSsBJxEjEQc1NxcB+KZNpcvNARNr/rkBR2tTi4sAAQB4AFkB+AHfAAgABrMGAgEwKyUnByc3JzcXFwHAKug25r428jCAweg75io7L/UAAQBDAEMB+AHfAAgAJEAhAAMCA4MAAAEAhAACAQECVQACAgFeAAECAU4RERERBA0YKwEHIzchNSEnMwH4i1ds/sEBP2xXARLPqkmpAAEAeQBPAfcB1QAIAAazBgIBMCsBBwcnNyc3FzcB9y7zNr/mNukoAXP0MDsq5jvpwQAAAQBqADICAgHsAAgAFUASCAUEAwIBAAcARwAAAHQWAQ0VKwEVByc1FxEzEQICy82mTQERU4yMU2sBRv66AAABAG4AVQHuAdsACAAGswcCATArJRcHJyc3FzcXAQi+NvIwOCroNroqOy/1O8HoOwABAGAARAIVAeAACAAqQCcEAQADAUoAAgMCgwABAAGEAAMAAANVAAMDAF4AAAMAThESERAEDRgrJSEXIyc3MwchAhX+wWxXi4tXbAE/7anNz6oAAQBvAF8B7QHlAAgABrMFAAEwKyUnByc3NxcHFwG36Sg3LvM2v+Zf6cE69DA7KuYAAQAyAEQCpwHgAA0ALkArBwEBBAFKBQEDBAODAgEAAQCEAAQBAQRVAAQEAV4AAQQBThEREhEREQYNGisBByM3IRcjJzczByEnMwKnilds/nVtV4uLV2wBimxXARHNqanNz6qqAAEAXwAnAfgCigANAAazCwQBMCsBETcVByc1FxEHNTcXFQFSpMrNpqXLzQIV/oZrUo2NUmsBempSjY1SAAEAYABpAfgCIwAIABVAEggHBgUEAQAHAEgAAAB0EgEHFSsBJxEjEQc1NxcB+KZNpcvNAUVr/rkBR2tTi4sAAQBDAHUB+AIRAAgAHUAaAAABAIQAAgABAAIBZgADAyIDTBEREREEBxgrAQcjNyE1ISczAfiLV2z+wQE/bFcBRM+qSakAAAEAagBkAgICHgAIACVACggFBAMCAQAHAEdLsChQWLUAAAAiAEwbswAAAHRZsxYBBxUrARUHJzUXETMRAgLLzaZNAUNTjIxTawFG/roAAAEAYAB2AhUCEgAIACNAIAQBAAMBSgABAAGEAAMAAAEDAGYAAgIiAkwREhEQBAcYKwEhFyMnNzMHIQIV/sFsV4uLV2wBPwEfqc3PqgABABn/9wI+AhwAAwAGswIAATArCQMBLAES/u7+7QIc/u3+7gESAAIAGf/3Aj4CHAADAAcACLUGBAIAAjArCQMFNycHASwBEv7u/u0BE8bGxwIc/u3+7gESwcHBwQAAAgAqABAByQKBAAMABwAItQcFAwECMCsbAgMTJwcXKtDP0I2MjIsBSgE3/sn+xgE6y8vMAAEAagBHAe4BywADABFADgAAAQCDAAEBdBEQAg0WKxMhESFqAYT+fAHL/nwAAgBqAEcB7gHLAAMABwApQCYAAAACAwACZQQBAwEBA1UEAQMDAV0AAQMBTQQEBAcEBxIREAUNFysTIREhJREhEWoBhP58AU7+6AHL/nw6ARD+8AAAAQBXADQCAQHeAAIACrcAAAB0EQENFSsBEyEBLNX+VgHe/lYAAQBzADUCHQHfAAIABrMCAQEwKwEFEQId/lYBCtUBqgABAFcANAIBAd4AAgAVQBIBAQBHAQEAAHQAAAACAAICDRQrAQMDAgHV1QHe/lYBqgABADoANAHkAd4AAgAGswIBATArEyUROgGqAQnV/lYAAAIAVwA0AgEB3gACAAUAI0AgBAEBSAIBAQAAAVUCAQEBAF0AAAEATQMDAwUDBREDDRUrARMhJQMDASzV/lYBYYyMAd7+VjABD/7xAAACAHMANQIdAd8AAgAFAAi1BQMCAQIwKwEFERMlJQId/lYtARj+6AEK1QGq/qOIiAACAFcANAIBAd4AAgAFACRAIQEBAUcCAQABAQBVAgEAAAFdAAEAAU0AAAUEAAIAAgMNFCsBAwMTEyECAdXV1Yz+6AHe/lYBqv7BAQ8AAgA6ADQB5AHeAAIABQAItQUDAgECMCsTJREDBQU6Aaot/ugBGAEJ1f5WAV2IiAAAAgAw/zYD2gLDADsASQCSQA8XCQIECS8BBgAwAQcGA0pLsBRQWEAuAAUFCF8LAQgISEsACQkCXwMBAgJFSwwKAgQEAGABAQAATEsABgYHXwAHB00HTBtALAMBAgAJBAIJZwAFBQhfCwEICEhLDAoCBAQAYAEBAABMSwAGBgdfAAcHTQdMWUAZPDwAADxJPEhEQgA7ADolJiUjEyYkJQ0KHCsAFhYVFAYjIiYnBgYjIiYmNTQ2NjMyFhc1MxEUFjMyNjU0JiYjIgYGFRQWFjMyNjcXBgYjIiYmNTQ2NjMSNjY1NCYmIyIGFRQWMwKP1HdeVDA/CR5hP0ZwPz9wRjpeH1cgGSwxZLV1drVkY7N1MWYqFix0N4nVdnfXiilNLS1NMUxeX0sCw2/IgICSMS4uMUJ1Skl1QSsqUf6YJSNnXm+pXmKwcXKwYxYWQBcYddCDg850/YUsUTY2USthUVFiAAMALf/1Ap8CwgAdACkAMgA+QDssKyMcGhkXFgoBCgMCHQEAAwJKBAECAgFfAAEBSEsFAQMDAF8AAABJAEwqKh4eKjIqMR4pHigrIgYKFisFJwYjIiYmNTQ2NyYmNTQ2MzIWFRQGBxc2NxcGBxcABhUUFhc2NjU0JiMSNycGBhUUFjMCaV1djUZwP09bLiZnVlBeRVCtHg1NEite/nI1HSpFNTEsUEPHSDlXRgtdWi5TNUBjNC5KKEdWTkQ1VC6sOUYZXEReAkcvJhsyKyc4ISMq/cxCxihFKzI+AAABABP/nAIfAuYADQAjQCAAAAMCAwACfgQBAgKCAAMDAV0AAQFEA0wREREkEAUKGSsTJiY1NDYzIREjESMRI+Ndc3llAS5QnFABgAFhUVJh/LYC//0BAAIAGv+WAdgCwgAzAEUAMUAuJQEDAkI5Jh0MAgYBAwsBAAEDSgABAAABAGMAAwMCXwACAkgDTCknIyElJwQKFiskBgcWFRQGBiMiJic3FhYzMjY1NCYmJy4CNTQ2NyY1NDYzMhYXByYjIgYVFBYWFx4CFQQWFhcWFzY2NTQmJicmJwYGFQHRKCI1NWA/OnQgHyFgMjlBIzYuPEo1KCM1e2owah8fQl9CRiIyLz1LNv6nJDcwJwshJyQ2LyIQISn7QRUmRzBKKCQcSRoiKygcIhMLDx4+NSpDFSRHSlkbF0kuKygbIRIMDx5BNwokEwwKAwovIB0kEwwIBQouIAAAAwAw//0C8gK/AA8AHwA5AF6xBmREQFM2NSsqBAYFAUoAAAACBAACZwAEAAUGBAVnAAYKAQcDBgdnCQEDAQEDVwkBAwMBXwgBAQMBTyAgEBAAACA5IDg0Mi4sKCYQHxAeGBYADwAOJgsKFSuxBgBEBCYmNTQ2NjMyFhYVFAYGIz4CNTQmJiMiBgYVFBYWMy4CNTQ2NjMyFhcHJiMiBhUUFjMyNxcGBiMBLqFdXaJjY6FcXqJiVoxRT4tXVo1QUIxVMmA2NmA9NFYYOSRGOkxMOkYkORhWNANeomFhol5coWJio14tUo5WVoxQUo1VVY1SZjRePDxeNCwlKTZMPj5MNigmLAAEADD//QLyAr8ADwAfAC4ANwBosQZkREBdIgEFCQFKBgEEBQMFBAN+CgEBAAIHAQJnAAcACAkHCGUMAQkABQQJBWULAQMAAANXCwEDAwBfAAADAE8vLxAQAAAvNy82NTMsKikoJyUkIxAfEB4YFgAPAA4mDQoVK7EGAEQAFhYVFAYGIyImJjU0NjYzEjY2NTQmJiMiBgYVFBYWMxIGBxcjJyMjFSMRMzIWFQY2NTQmIyMVMwH1oVxeomJioV1domNUjFFPi1dWjVBQjFW1LChbRVMRXESgS1d3NTUwWFgCv1yhYmKjXl6iYWGiXv1rUo5WVoxQUo1VVY1SAUdADo2AgAGQSj5QKiYmKZ8AAgAEAR0DnAK8AAcAFABAQD0RDAkDBAEBSgAEAQIBBAJ+CQgFAwICggcGAgABAQBVBwYCAAABXQMBAQABTQgICBQIFBIREhMREREQCg0cKxMhFSMRIxEjAQMHIycRIxEzExMzEwQBdpdIlwNTAZwhnUU7ubU7AQK8O/6cAWT+nAEj8u3+4gGf/uQBHP5hAAIALQF9AXYCwgAPABsAOLEGZERALQAAAAIDAAJnBQEDAQEDVwUBAwMBXwQBAQMBTxAQAAAQGxAaFhQADwAOJgYKFSuxBgBEEiYmNTQ2NjMyFhYVFAYGIzY2NTQmIyIGFRQWM6RLLCxLLS1MLCxMLS4+Pi4uPj4uAX0rSy0sSysrSywtSys2Py4uPz4vLz4AAAEAaf8+AMIC5gADABNAEAAAAERLAAEBRwFMERACChYrEzMRI2lZWQLm/FgAAgBp/z4AwgLmAAMABwAfQBwAAQEAXQAAAERLAAICA10AAwNHA0wREREQBAoYKxMzESMVMxEjaVlZWVkC5v6i7P6iAAACAB///QGvAsAAGwAlADNAMCUZGAQDBQEDAUoAAAADAQADZwABAgIBVwABAQJfBAECAQJPAAAiIAAbABopKQUNFisWJjU3Byc3EzY2MzIWFRQGBwYVFBYzMjY3FwYjEjY1NCYjIgYHB6I6ATgSUy8SWDowOop1BiQoKUkkIFdxL2UeFyAzCygDTUkZKCw8ARhdXz45WbpcJBwtLC8qJXgBcJw/ICE/QOIAAAEAHv8+AhICvAALACFAHgMBAQQBAAUBAGUAAgJCSwAFBUcFTBEREREREAYKGisTIzUzNTMVMxUjESPnyclgy8tgAXhU8PBU/cYAAQAe/z4CEgK8ABMANUAyCAEGCgkCBQAGBWUEAQADAQECAAFlAAcHQksAAgJHAkwAAAATABMRERERERERERELCh0rARUzFSMVIzUjNTM1IzUzNTMVMxUBR8vLYMnJyclgywF49lTw8FT2VPDwVAACADD//QNAAr8AHAAtAE1ASisfAgYFDwEDAQJKAAMBAgEDAn4AAAAFBgAFZwgBBgABAwYBZQACBAQCVwACAgRfBwEEAgRPHR0AAB0tHS0mJAAcABsSJyMmCQ0YKwQmJjU0NjYzMhYWFRUhIhUVFBcWFjMyNjczBgYjEzI1NTQnJiYjIgYHBhUVFDMBTrRqarRqa7Rp/YUGCSiASUqELjk2pFz0Bgsve0REfDAKBgNfol9go19fo2AIBMAJDjI2PjY/SgFrBsEOCS81NzAMDL0GAAAEAGkAAASBAsIADwAZACUAKQCGQAoUAQYHGQEDCQJKS7AnUFhAJQAGCgEBCAYBZwAIAAkDCAllCwEHBwBdBQICAAAgSwQBAwMhA0wbQCkABgoBAQgGAWcACAAJAwgJZQUBAgIgSwsBBwcAXwAAACVLBAEDAyEDTFlAHhoaAAApKCcmGiUaJCAeGBcWFRMSERAADwAOJgwHFSsAJiY1NDY2MzIWFhUUBgYjATMRIwERIxEzAQAGFRQWMzI2NTQmIwMhFSEDnVEuLlEzM1EtLVEz/o9kUv5cZFIBpAE/PT4xMT09MZ4BPP7EAX8qSi4uSikpSi4uSioBPf1EAgr99gK8/fYB1zouLjo6Li46/qdBAAEASwCOAfwCLgAGACexBmREQBwBAQABAUoAAQABgwMCAgAAdAAAAAYABhESBAoWK7EGAEQlAwMjEzMTAa+LjE2xULCOAVH+rwGg/mAAAAEAPwGuAJMCvAADABNAEAABAQBdAAAAQgFMERACChYrEzMDIz9UB0cCvP7yAAACAD8BrgFIArwAAwAHABdAFAMBAQEAXQIBAABCAUwREREQBAoYKxMzAyMTMwMjP1QHR7BTB0YCvP7yAQ7+8gD//wAw/3kD2gMGAQYGygBDAAixAAKwQ7AzKwAEAGkAAAR5AsQAEgAiAC4AMgDXtRABBwEBSkuwHVBYQDMABwwBBgkHBmcACQAKAAkKZQ0BCAgDXwULBAMDAyBLAAEBA18FCwQDAwMgSwIBAAAhAEwbS7AnUFhALwAHDAEGCQcGZwAJAAoACQplDQEICANfBQEDAyBLAAEBBF8LAQQEJUsCAQAAIQBMG0A2AAcMAQYJBwZnAAkACgAJCmUAAwMgSw0BCAgEXwULAgQEJUsAAQEEXwULAgQEJUsCAQAAIQBMWVlAISMjExMAADIxMC8jLiMtKScTIhMhGxkAEgARERMjEw4HGCsAFhURIxE0JiMiBhURIxEzFTYzACYmNTQ2NjMyFhYVFAYGIwIGFRQWMzI2NTQmIwMhFSECLY5jZFlgbmRgR58B51EuLlEyM1EtLVEzMT09MTE9PTGdATv+xQLEmI3+YQGcZmlwbv5zArxja/67KkouLkopKUouLkoqAQo6Li46Oi4uOv6nQQAAAwAl//YCMgI/AB0AKQAyAD5AOywrIxwaGRcWCgkDAh0BAgADAkoEAQICAV8AAQEwSwUBAwMAXwAAADEATCoqHh4qMioxHikeKCsiBggWKwUnBiMiJiY1NDY3JiY1NDYzMhYVFAYHFzY3FwYHFwAGFRQWFzY2NTQmIxI3JwYGFRQWMwH+S05vO2A2PkYiHVhJQ1I4P4UZC0sSJEv+tioWIDQqJSE6Np41K0Q5CkhGKEgtMVEmJDogO0lDOCxGIn8tNRVNN0gBySQbFSQgHCoYGiD+RzCYHjIhJjEAAAL+RAJw/2QC1wALABcAMrEGZERAJwIBAAEBAFcCAQAAAV8FAwQDAQABTwwMAAAMFwwWEhAACwAKJAYKFSuxBgBEACY1NDYzMhYVFAYjMiY1NDYzMhYVFAYj/mIeHhUVHh4VpR4eFRUeHhUCcB0WFh4eFhYdHRYWHh4WFh0A///+NwJw/2EDXgAiBysAAAEHBy0AAACOAAixAgGwjrAzK////kgCcP9yA14AIgcrAAABBwcuAAAAjgAIsQIBsI6wMyv///4xAnD/dwM8ACIHKwAAAQcHMwAAAI4ACLECAbCOsDMrAAH+mQJx/w8C5wALACaxBmREQBsAAAEBAFcAAAABXwIBAQABTwAAAAsACiQDChUrsQYARAAmNTQ2MzIWFRQGI/67IiIZGSIiGQJxIhkZIiIZGSIA///+MQJv/3cDPwAiBywAAAEHBzMAAACRAAixAQGwkbAzKwAB/h0CX/8fAuEAAwAZsQZkREAOAAABAIMAAQF0ERACChYrsQYARAEzFyP+HXqIWgLhggD///4xAl//dwM8ACIHLQAAAQcHMwAAAI4ACLEBAbCOsDMrAAH+iQJf/4sC4QADABmxBmREQA4AAAEAgwABAXQREAIKFiuxBgBEAzMHI+96qFoC4YL///6PAl//cgNkACIHLgAAAQcHLAAAAI4ACLEBAbCOsDMr///+MQJf/3cDPAAiBy4AAAEHBzMAAACOAAixAQGwjrAzKwAC/lQCX//BAuEAAwAHACWxBmREQBoCAQABAQBVAgEAAAFdAwEBAAFNEREREAQKGCuxBgBEATMHIyUzByP+rmZvUQEIZW1RAuGCgoIAAf7UAhz/IwLdAAMAE0AQAAEBAF0AAABEAUwREAIKFisBMwcj/tRPDEMC3cEAAAH+IQJf/4cC4QAGACexBmREQBwBAQABAUoAAQABgwMCAgAAdAAAAAYABhESBAoWK7EGAEQDJwcjNzMX0FxcV4VchQJfTU2CggAAAf4hAl//hwLhAAYAJ7EGZERAHAUBAAEBSgMCAgEAAYMAAAB0AAAABgAGEREEChYrsQYARAMHIyczFzd5hVyFV1xcAuGCgkxMAP///iECX/+HA00AIgcwAAABBgcsAHcACLEBAbB3sDMrAAH+MgJZ/3YC4QANAC6xBmREQCMCAQABAIMAAQMDAVcAAQEDXwQBAwEDTwAAAA0ADBIiEgUKFyuxBgBEACYnMxYWMzI2NzMGBiP+j1sCQQE3KSk3AUECW0UCWUo+JCwsJD5KAAAC/mUCUv9CAywACwAXADixBmREQC0AAAACAwACZwUBAwEBA1cFAQMDAV8EAQEDAU8MDAAADBcMFhIQAAsACiQGChUrsQYARAAmNTQ2MzIWFRQGIzY2NTQmIyIGFRQWM/6lQEAuL0BALx0lJhwcJSUcAlI/LS1BQS0tPyomHB0mJh0cJgAC/mUCUv+PA3MADwAbADRAMQ0BAgEBSg8OAgFIAAEAAgMBAmcEAQMAAANXBAEDAwBfAAADAE8QEBAbEBooJCQFBxcrAxYVFAYjIiY1NDYzMhc3FwY2NTQmIyIGFRQWM9ETQC8uQEAuHRlUMp8lJhwcJSUcAv0cIy0/Py0tQQ5VKc4mHB0mJh0cJgAB/iwCYv98AuEAGQCTsQZkREuwHVBYQBsEAQIAAAMCAGcAAwEBA1cAAwMBXwYFAgEDAU8bS7AuUFhAIgAEAgACBAB+AAIAAAMCAGcAAwEBA1cAAwMBXwYFAgEDAU8bQCkABAIAAgQAfgABAwUDAQV+AAIAAAMCAGcAAwEFA1cAAwMFXwYBBQMFT1lZQA4AAAAZABgSJCISJAcKGSuxBgBEAiYnJiYjIgYHIzY2MzIWFxYWMzI2NzMGBiP+IxoPFgsWHAE2AjUrGCUYERQLFhwBNgI1KwJiFBQODSEdOEIVFA4NIBw2QQD///4vAmT/eQNhACIHMgAAAQcHKwAAAI4ACLEBArCOsDMr///+LwJk/3kDXgAiBzIAAAEHBy4AAACOAAixAQGwjrAzK////i8CZP95AzwAIgcyAAABBwczAAAAjgAIsQEBsI6wMysAAf4xAoL/dwK+AAMAILEGZERAFQAAAQEAVQAAAAFdAAEAAU0REAIKFiuxBgBEASEVIf4xAUb+ugK+PAD///4xAnX/dwNhACIHMwAAAQcHKwAAAI4ACLEBArCOsDMr///+MQJ1/3cDXgAiBzMAAAEHBy0AAACOAAixAQGwjrAzK////jECdf93A14AIgczAAABBwcuAAAAjgAIsQEBsI6wMysAAf54Alb/OQMlABEAK7EGZERAIAkBAAEBShEIAgBHAAEAAAFXAAEBAF8AAAEATyQlAgoWK7EGAEQBNjY1NCYjIgcnNjYzMhYVFAf+xh0bHRcfHRYSMBktOVICfQ0hFRQbEy0ODjMqTCYAAAL95wJf/1QC4QADAAcAJbEGZERAGgIBAAEBAFUCAQAAAV0DAQEAAU0REREQBAoYK7EGAEQBMxcjNzMXI/3nZVlRQGZaUQLhgoKCAAAB/jICX/92AucADQAosQZkREAdAwEBAgGEAAACAgBXAAAAAl8AAgACTxIiEiEEChgrsQYARAA2MzIWFyMmJiMiBgcj/jRbRUVbAkEBNykpNwFBAp1KSj4lKyslAAH+nAJZ/wwDFwANACaxBmREQBsNAQABAUoAAQAAAVUAAQEAXwAAAQBPFSQCChYrsQYARAAWFRQGIyImNTQ3NzMH/voSHhoaHg8lNx0CrBUQFRkaFBQeXmYAAAH+wgHJ/1kCqQANACWxBmREQBoHBgIASAAAAQEAVwAAAAFfAAEAAU8pIAIKFiuxBgBEATMyNjU0JzcWFRQGIyP+whIgIBQ9HEc+EgISJB0kGxcmMz5JAAAB/qH/PP8H/6IACwAmsQZkREAbAAABAQBXAAAAAV8CAQEAAU8AAAALAAokAwoVK7EGAEQEJjU0NjMyFhUUBiP+vx4eFRUeHhXEHBYWHh4WFhwAAv5M/z//XP+iAAsAFwAysQZkREAnAgEAAQEAVwIBAAABXwUDBAMBAAFPDAwAAAwXDBYSEAALAAokBgoVK7EGAEQEJjU0NjMyFhUUBiMyJjU0NjMyFhUUBiP+aR0dFBUeHhWZHR0VFB0dFMEdFRUcHBUVHRwWFRwcFRUdAAH+of75/wf/ogANAC2xBmREQCIHAQABAUoCAQEAAAFXAgEBAQBdAAABAE0AAAANAAwVAwoVK7EGAEQEFhUUBwcjNyYmNTQ2M/7rHA0eMhcPERwXXhoUGBtIUAUWEBQaAAH+Yv8g/zcABwATAD6xBmREQDMNAQECAgEAAQEBAwADSgACAAEAAgFnAAADAwBXAAAAA18EAQMAA08AAAATABIRIyMFChcrsQYARAQnNxYzMjU0JiMjNzMHFhYVFAYj/oclFR4mOBwdGxk3DyotRDjgFjERKBIVYjkELSIqMQAAAf4Z/yD+6wAgABEAMrEGZERAJw8BAQABSg4GBQMASAAAAQEAVwAAAAFfAgEBAAFPAAAAEQAQKwMKFSuxBgBEBCY1NDY3FwYGFRQWMzI3FwYj/llAREstQDciGyUZEiY04DcuLFEeIBw5HxgcETEYAAH+Mv8v/3b/rwANAC6xBmREQCMCAQABAIMAAQMDAVcAAQEDXwQBAwEDTwAAAA0ADBIiEgUKFyuxBgBEBCYnMxQWMzI2NTMGBiP+j1sCPzgrKzg/AltF0UY6IikpIjpGAAH+Mf9S/3f/jwADACCxBmREQBUAAAEBAFUAAAABXQABAAFNERACChYrsQYARAUhFSH+MQFG/rpxPQAB/g4BlP+aAdgAAwAgsQZkREAVAAABAQBVAAAAAV0AAQABTREQAgoWK7EGAEQBIRUh/g4BjP50AdhEAAAB/LgBjv/fAd0AAwAgsQZkREAVAAABAQBVAAAAAV0AAQABTREQAgoWK7EGAEQBIRUh/LgDJ/zZAd1PAAAB/o0BAf/BAgQAAwAGswMBATArASUXBf6NAQkr/vcBOso6yQAB/dD/uv/EAlcAAwAZsQZkREAOAAABAIMAAQF0ERACChYrsQYARAMzASN3O/5IPAJX/WMAAv5EAwb/ZANtAAsAFwAqQCcCAQABAQBXAgEAAAFfBQMEAwEAAU8MDAAADBcMFhIQAAsACiQGBxUrACY1NDYzMhYVFAYjMiY1NDYzMhYVFAYj/mIeHhUVHh4VpR4eFRUeHhUDBh0WFh4eFhYdHRYWHh4WFh0A///+NwMG/2ED9AAnBysAAACWAQcHLQAAASQAEbEAArCWsDMrsQIBuAEksDMrAP///kgDBv9yA/QAJwcrAAAAlgEHBy4AAAEkABGxAAKwlrAzK7ECAbgBJLAzKwD///4xAwb/dwPSACcHKwAAAJYBBwczAAABJAARsQACsJawMyuxAgG4ASSwMysAAAH+mQMH/w8DfQALAB5AGwAAAQEAVwAAAAFfAgEBAAFPAAAACwAKJAMHFSsAJjU0NjMyFhUUBiP+uyIiGRkiIhkDByIZGSIiGRkiAP///jEDBf93A9UAJwcsAAAAlgEHBzMAAAEnABGxAAGwlrAzK7EBAbgBJ7AzKwAAAf4dAvX/HwN3AAMAEUAOAAABAIMAAQF0ERACBxYrATMXI/4deohaA3eCAP///jEC9f93A9IAJwctAAAAlgEHBzMAAAEkABGxAAGwlrAzK7EBAbgBJLAzKwAAAf6JAvX/iwN3AAMAEUAOAAABAIMAAQF0ERACBxYrAzMHI+96qFoDd4L///6PAvX/cgP6ACcHLgAAAJYBBwcsAAABJAARsQABsJawMyuxAQG4ASSwMysA///+MQL1/3cD0gAnBy4AAACWAQcHMwAAASQAEbEAAbCWsDMrsQEBuAEksDMrAAAC/lQC9f/BA3cAAwAHAB1AGgIBAAEBAFUCAQAAAV0DAQEAAU0REREQBAcYKwEzByMlMwcj/q5mb1EBCGVtUQN3goKCAAH+IQL1/4cDdwAGAB9AHAEBAAEBSgABAAGDAwICAAB0AAAABgAGERIEBxYrAycHIzczF9BcXFeFXIUC9U1NgoIAAAH+IQL1/4cDdwAGAB9AHAUBAAEBSgMCAgEAAYMAAAB0AAAABgAGEREEBxYrAwcjJzMXN3mFXIVXXFwDd4KCTEwA///+IQL1/4cD4wAnBzAAAACWAQcHLAAAAQ0AEbEAAbCWsDMrsQEBuAENsDMrAAAB/jIC7/92A3cADQAmQCMCAQABAIMAAQMDAVcAAQEDXwQBAwEDTwAAAA0ADBIiEgUHFysAJiczFhYzMjY3MwYGI/6PWwJBATcpKTcBQQJbRQLvSj4kLCwkPkoAAAH+LAL4/3wDdwAZAItLsB1QWEAbBAECAAADAgBnAAMBAQNXAAMDAV8GBQIBAwFPG0uwLlBYQCIABAIAAgQAfgACAAADAgBnAAMBAQNXAAMDAV8GBQIBAwFPG0ApAAQCAAIEAH4AAQMFAwEFfgACAAADAgBnAAMBBQNXAAMDBV8GAQUDBU9ZWUAOAAAAGQAYEiQiEiQHBxkrAiYnJiYjIgYHIzY2MzIWFxYWMzI2NzMGBiP+IxoPFgsWHAE2AjUrGCUYERQLFhwBNgI1KwL4FBQODSEdOEIVFA4NIBw2QQD///4vAvr/eQP3ACcHMgAAAJYBBwcrAAABJAARsQABsJawMyuxAQK4ASSwMysA///+LwL6/3kD9AAnBzIAAACWAQcHLgAAASQAEbEAAbCWsDMrsQEBuAEksDMrAP///i8C+v95A9IAJwcyAAAAlgEHBzMAAAEkABGxAAGwlrAzK7EBAbgBJLAzKwAAAf4xAxj/dwNUAAMAGEAVAAABAQBVAAAAAV0AAQABTREQAgcWKwEhFSH+MQFG/roDVDwA///+MQML/3cD9wAnBzMAAACWAQcHKwAAASQAEbEAAbCWsDMrsQECuAEksDMrAP///jEDC/93A/QAJwczAAAAlgEHBy0AAAEkABGxAAGwlrAzK7EBAbgBJLAzKwD///4xAwv/dwP0ACcHMwAAAJYBBwcuAAABJAARsQABsJawMyuxAQG4ASSwMysAAAH+eALs/zkDuwARACNAIAkBAAEBShEIAgBHAAEAAAFXAAEBAF8AAAEATyQlAgcWKwE2NjU0JiMiByc2NjMyFhUUB/7GHRsdFx8dFhIwGS05UgMTDSEVFBsTLQ4OMypMJgAAAv3nAvX/VAN3AAMABwAdQBoCAQABAQBVAgEAAAFdAwEBAAFNEREREAQHGCsBMxcjNzMXI/3nZVlRQGZaUQN3goKCAAAB/jIC9f92A30ADQAgQB0DAQECAYQAAAICAFcAAAACXwACAAJPEiISIQQHGCsANjMyFhcjJiYjIgYHI/40W0VFWwJBATcpKTcBQQMzSko+JSsrJQAB/gwBPf+cAYwAAwAYQBUAAAEBAFUAAAABXQABAAFNERACBxYrASEVIf4MAZD+cAGMTwAAAf6NAQH/9QIpAAMABrMDAQEwKwElFwX+jQE8LP7EATnwOPAAAf0P/7r/twMCAAMAEUAOAAABAIMAAQF0ERACBxYrAzMBI5dO/aZOAwL8uAAB/k8DGP9ZA1QAAwAYQBUAAAEBAFUAAAABXQABAAFNERACBxYrASEVIf5PAQr+9gNUPAAAAf6TAnj/FQL1AAsAGUAWAgEBAQBfAAAASgFMAAAACwAKJAMKFSsAJjU0NjMyFhUUBiP+uCUlHBwlJRwCeCQaGiUjGhslAAH+Vv8g/vkAHwAQAENADA4BAQABSg0FBAMASEuwFFBYQAwAAAABXwIBAQFNAUwbQBEAAAEBAFcAAAABXwIBAQABT1lACgAAABAADyoDChUrBCY1NDcXBgYVFBYzMjcXBiP+jTdcIyIZGRMREREXKOA1LFdHHyA5GxgcDDAUAAL+SAJw/2EC0wALABcAREuwIVBYQA8FAwQDAQEAXwIBAABIAUwbQBUCAQABAQBXAgEAAAFfBQMEAwEAAU9ZQBIMDAAADBcMFhIQAAsACiQGChUrACY1NDYzMhYVFAYjMiY1NDYzMhYVFAYj/mUdHRUUHR0UoR0dFBUdHRUCcBwWFRwcFRUdHRUVHBwVFR0AAAH+oQJv/wcC1gALADVLsB9QWEAMAgEBAQBfAAAARAFMG0ARAAABAQBXAAAAAV8CAQEAAU9ZQAoAAAALAAokAwoVKwAmNTQ2MzIWFRQGI/6/Hh4VFR4eFQJvHhYWHR0WFh4AAf43Al//GQLQAAMAJkuwGVBYQAsAAQABhAAAACAATBtACQAAAQCDAAEBdFm0ERACBxYrATMXI/43bXVOAtBxAAH+jwJf/3IC0AADACZLsBlQWEALAAEAAYQAAABCAEwbQAkAAAEAgwABAXRZtBEQAgoWKwMzByP7bZRPAtBxAAAB/iECX/+HAsMABgAhQB4BAQABAUoDAgIAAQCEAAEBQgFMAAAABgAGERIEChYrAycHIzczF9FbW1iGWoYCXzg4ZGQAAAH+IQJf/4cCwwAGACFAHgUBAAEBSgAAAQCEAwICAQFCAUwAAAAGAAYREQQKFisDByMnMxc3eYZahlhbWwLDZGQ4OAAAAf4yAln/dgLDAA0AHkAbAAEEAQMBA2MCAQAAQgBMAAAADQAMEiISBQoXKwAmJzMWFjMyNjczBgYj/pFZBkAENigoNgRABllDAlk5MRgdHRgxOQAAAf4vAmT/eQLPABcAd0uwLFBYQBUAAwYFAgEDAWMAAAACXwQBAgJIAEwbS7AuUFhAGwQBAgAAAwIAZwADAQEDVwADAwFfBgUCAQMBTxtAIgAEAgACBAB+AAIAAAMCAGcAAwEBA1cAAwMBXwYFAgEDAU9ZWUAOAAAAFwAWEiQiESMHChkrACYnJiMiByM2NjMyFhcWFjMyNjczBgYj/wElGB8SLAI2ATMsFyUYERYMFhcBNQEzKwJkEBAWMjA3EBALCxoXLzcAAf4xAnX/dwKuAAMALUuwI1BYQAsAAQEAXQAAAEIBTBtAEAAAAQEAVQAAAAFdAAEAAU1ZtBEQAgoWKwEhFSH+MQFG/roCrjkAAf6PAlf/IgLvABEAI0AgCQEAAQFKEQgCAEcAAQAAAVcAAQEAXwAAAQBPIyUCDRYrATY2NTQmIyIHJzYzMhYVFAYH/soUFBURFhUSHickKiIcAnQJGg0OEQwlEycfGysMAAAC/lsCcf9NAtYACwAXAERLsB9QWEAPBQMEAwEBAF8CAQAARAFMG0AVAgEAAQEAVwIBAAABXwUDBAMBAAFPWUASDAwAAAwXDBYSEAALAAokBgoVKwAmNTQ2MzIWFRQGIzImNTQ2MzIWFRQGI/53HBwWFRwcFXkcHBUWHBwWAnEdFRYdHRYWHB0VFh0dFhYcAAAB/joCX/9uAuEABgAhQB4BAQABAUoDAgIAAQCEAAEBRAFMAAAABgAGERIEChYrAycHIzczF+RISFJtWm0CX0pKgoIAAAH+SwJZ/10C4QANAB5AGwABBAEDAQNjAgEAAEQATAAAAA0ADBIiEgUKFysAJjUzFBYzMjY1MxQGI/6YTT4pIiIpPk08AllKPiUrKyU+SgAAAf5FAmL/YwLhABkAm0uwHVBYQBUAAwYFAgEDAWQAAAACXwQBAgJEAEwbS7AnUFhAGQADBgUCAQMBZAAEBERLAAAAAl8AAgJEAEwbS7AuUFhAHAAEAgACBAB+AAMGBQIBAwFkAAAAAl8AAgJEAEwbQCMABAIAAgQAfgABAwUDAQV+AAMGAQUDBWQAAAACXwACAkQATFlZWUAOAAAAGQAYEiQiEiQHChkrACYnJiYjIgYVIzQ2MzIWFxYWMzI2NTMUBiP++SAUDhEJEBI2LCcXIBQNEgkQEjYsJwJiFRQODCEdOkAVFA0NIBs4PwAB/k8Cgv9ZAr4AAwATQBAAAQEAXQAAAEIBTBEQAgoWKwEhFSH+TwEK/vYCvjwAAf5LAl//XQLnAA0AG0AYAwEBAgGEAAICAF8AAABEAkwSIhIhBAoYKwA2MzIWFSM0JiMiBhUj/ktNPDxNPigjIyg+Ap1KSj4lKyslAAH+1AJU/yAC/QADAC1LsBZQWEALAAEBAF0AAABEAUwbQBAAAAEBAFUAAAABXQABAAFNWbQREAIKFisBMwcj/tRMC0EC/akAAAH+NgGT/3EB1gADABhAFQAAAQEAVQAAAAFdAAEAAU0REAINFisBIRUh/jYBO/7FAdZDAAABADUBtwB6ArwAAwAgsQZkREAVAAABAQBVAAAAAV0AAQABTREQAgoWK7EGAEQTMwMjOEIQNQK8/vv//wBBAkYAxgNdAQYGWRN3AAixAAGwd7AzK///AD8BrgFIArwAIgYyAAAAAwYyALUAAAABAIkCggHPAr4AAwAgsQZkREAVAAABAQBVAAAAAV0AAQABTREQAgoWK7EGAEQTIRUhiQFG/roCvjwAAQB1Al8BdwLhAAMAGbEGZERADgAAAQCDAAEBdBEQAgoWK7EGAEQTMxcjdXqIWgLhggABAD8BrgCTArwAAwAgsQZkREAVAAABAQBVAAAAAV0AAQABTREQAgoWK7EGAEQTMwMjP1QHRwK8/vIAAQC7AlIBKwMsAA0AMLEGZERAJQAAAAECAAFnAAIDAwJXAAICA18EAQMCA08AAAANAA0UERQFChcrsQYARBImNTQ2MxUiBhUUFjMV+0BAMBwlJRwCUj8tLkAsJhwbJSwAAQErAlIBmwMsAA0AKrEGZERAHwACAAEAAgFnAAADAwBXAAAAA18AAwADTxQRFBAEChgrsQYARAEyNjU0JiM1MhYVFAYjASsdJSUdMT8/MQJ+JRsdJSxALi4+AAABAOECXwHjAuEAAwAZsQZkREAOAAABAIMAAQF0ERACChYrsQYARAEzByMBaXqoWgLhggAAAQA1/yQAeP/iAAMAILEGZERAFQAAAQEAVQAAAAFdAAEAAU0REAIKFiuxBgBEFzMVIzVDQx6+AAABADUB/gB3ArwAAwAgsQZkREAVAAABAQBVAAAAAV0AAQABTREQAgoWK7EGAEQTMxUjNUJCAry+//8A4QJfAeMC4QADBucCWAAA//8AigJZAc4C4QADBu8CWAAA//8AeQJfAd8C4QADBu0CWAAA//8Auv8gAY8ABwADBwICWAAA//8AeQJfAd8C4QADBuwCWAAA//8AnAJwAbwC1wADBt8CWAAA//8A8QJxAWcC5wADBuMCWAAA//8AdQJfAXcC4QADBuUCWAAA//8ArAJfAhkC4QADBuoCWAAA//8AiQKCAc8CvgADBvYCWAAA//8Acf8gAUMAIAADBwMCWAAA//8AvQJSAZoDLAADBvACWAAA//8AhAJiAdQC4QADBvICWAAAAAEATQD9AZ8BRgADABhAFQAAAQEAVQAAAAFdAAEAAU0REAIIFisTIRUhTQFS/q4BRkkAAQAfAT8CvgGIAAMAGEAVAAABAQBVAAAAAV0AAQABTREQAggWKxMhFSEfAp/9YQGISQABADH/xwJpAnEAAwARQA4AAAEAgwABAXQREAIIFisBMwEjAh9K/hFJAnH9VgAAAf6DAlf/vgLhAA0AJkAjAgEAAQCDAAEDAwFXAAEBA18EAQMBA08AAAANAAwSIhIFBxcrACYnMxYWMzI2NzMGBiP+1lIBQQExKSkyAUMBVEkCV0dDJS0tJUNHAAAB/mkC7f/AA3YADQAmQCMCAQABAIMAAQMDAVcAAQEDXwQBAwEDTwAAAA0ADBIiEgUHFysAJiczFhYzMjY3MwYGI/7DWQFHATUvLTcBRgFZUQLtR0InKysnQUgAAAEAOv+PAO0AVAAFADxLsApQWEASAAABAQBvAwECAgFdAAEBIQFMG0ARAAABAIQDAQICAV0AAQEhAUxZQAsAAAAFAAUREQQHFis3FSM1IzXtWllUxXFUAAABAC3/ZwD6AFcABQAfQBwAAAEAhAMBAgIBXQABASEBTAAAAAUABRERBAcWKzcVIzUjNfpccVfwmVcAAQA6/2cA2wBXAAUAH0AcAAABAIQDAQICAV0AAQEhAUwAAAAFAAUREQQHFis3FSM1IzXbXURX8JlXAAEAQP+PANoAUgAFADxLsApQWEASAAABAQBvAwECAgFdAAEBIQFMG0ARAAABAIQDAQICAV0AAQEhAUxZQAsAAAAFAAUREQQHFis3FSM1IzXaV0NSw3FSAP///jICWf92A0sAIgcxAAABBgcuAHsACLEBAbB7sDMr///+MgJZ/3YDSwAiBzEAAAEGBy0AewAIsQEBsHuwMyv///4yAln/dgNXACIHMQAAAQYHNABoAAixAQGwaLAzK////i8CWf95A0oAIgcxAAABBgcyAHsACLEBAbB7sDMr///+IQJfABoDKAAiBy8AAAEHBy4AqABYAAixAQGwWLAzK////iECX//BAygAIgcvAAABBwctAKgAWAAIsQEBsFiwMyv///4hAl//pAM9ACIHLwAAAQcHNACCAE4ACLEBAbBOsDMr///+IQJf/4cDUAAiBy8AAAEHBzIAAACBAAixAQGwgbAzK////jIC7/92A+EAJwcxAAAAlgEHBy4AAAERABGxAAGwlrAzK7EBAbgBEbAzKwD///4yAu//dgPhACcHMQAAAJYBBwctAAABEQARsQABsJawMyuxAQG4ARGwMysA///+MgLv/3YD7QAnBzEAAACWAQcHNAAAAP4AELEAAbCWsDMrsQEBsP6wMyv///4vAu//eQPgACcHMQAAAJYBBwcyAAABEQARsQABsJawMyuxAQG4ARGwMysA///+IQL1ABoDvgAnBy8AAACWAQcHLgCoAO4AELEAAbCWsDMrsQEBsO6wMyv///4hAvX/wQO+ACcHLwAAAJYBBwctAKgA7gAQsQABsJawMyuxAQGw7rAzK////iEC9f+kA9MAJwcvAAAAlgEHBzQAggDkABCxAAGwlrAzK7EBAbDksDMr///+IQL1/4cD5gAnBy8AAACWAQcHMgAAARcAEbEAAbCWsDMrsQEBuAEXsDMrAAABAF//ZwC8ABcAAwAYQBUAAQAAAVUAAQEAXQAAAQBNERACBxYrFyM1M7xdXZmwAAABAF7/jwC5ABUAAwAYQBUAAQAAAVUAAQEAXQAAAQBNERACBxYrFyM1M7lb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UXdRg1GUUaVRtlHHUdhR6VICUhtSgFKLUp9SsFLJUuJS+1NDU3xTuVQOVFFUYlRzVH9UkFScVK1UuVUPVSBVOVVBVVJVa1V3VYhVlFWlVbFVxlZEVmNWdFaFVpFWnVauVrpWxlb0VwVXFlcnVzhXSVdaV2ZXd1eIV5lXslfHV+BX+VgSWCNYNFhFWF5YrFi9WM5Y51kLWTxZTVleWW9ZgFmtWdBZ4VnyWgNaFFogWjFaQlpTWmRaklqjWrRaxVrRWw1bHlsvW0hbXVt2W49bqFu5W8pb41v4XBFcKlxDXFRcZVxxXIJck1ykXLVcwVzSXONc9F1ZXWpdf13WXedd+F4JXh5eL15IXl1edl6PXqheuV7KXtte5174XwlfGl8rX0RfXV/pX/pgSGCBYOJg82EEYRVhJmE3YUhhXGGGYY5hn2HtYf5iD2IgYjFiSmJWYmdieGKJYsVi1mLiYvNjKGM5Y0VjpmOyY/dkCGQZZCVkNmRCZKJkrmS6ZMtlFmVAZVFlYmVuZXpli2WXZaNl7WX+Zg9mIGYxZkJmU2ZfZnBmgWaSZqtmwGbZZvJnC2ccZy1nPmdXZ2NndGeFZ55n5mf3aAhoGWgqaHVohmiXaKhouWjKaNto7Gj9aQ5pSWlaaWtpfGmIad9qH2onamJqr2rNatlq+ms7a0NrT2tba5tr+WwfbCtsN2yNbLtsx20hbVVtXW1lbYltkW2Zbblt8m3+blBugG62buJvDm8ab0Fvem+4b8Rv0HAxcDlwSXCYcK5wunDCcQBxc3G1ciRybXK4csxzGXNJc5hzpHOwc7xz+nQ3dGt0d3SDdNZ04nWZdaV1sXW5dc112XYNdhl2XXaTdp93B3cTdxt3J3dud6x34XggeF54anh2eH54injheO14+XkFeVF5XXlpeXV5iXmhea15uXnFedF53Xnoefh6RnqQesh7I3txe3l7qnvzfEF8f3yLfMJ85n05fWN9b317fYd9j33Ufdx96H30ffx+CH6nfrN+6380fzx/RH9Qf5p/5IA1gKOBM4GugbaCDoIagiaCMoI6gkaCUoJegmqCdoKCgo6CloLvgveDXYOng8SD1oQHhEeET4RbhGeEo4T+hSSFMIU8hZKFvYXJhhiGS4ZxhnmGnYalhq2GzYbVhuGHMIc4h22HmYfEh9CICYhFiISIyYjViTKJOolKiZaJoomuibqKAYqKisiLJouKi9uL44wxjF+MrYy5jRaNIo1djZ6Nz43bjeeN845FjtOO347rjw6PIo8uj2KPbo+vj7eP95BZkGWQbZB5kL6ROJF6ka2R6pImkjKSPpJGklKSpJKwkrySyJMRkx2TKZM1k4eTk5Ofk6uTt5PDk8+T2pPmlDWUepSylQqVXJVklZWV35ZXlpmWpZcDl1qXYpell/6YBpgSmB6YT5hymHqYgpiKmL+Yy5ktmTmZgZnPmkaabpp6moaamJrymv6bBpsSmyabLps2mz6bSptWm16bapvom/ScRJxMnFScYJyonPadXp3GnkCemJ6knrCeuJ7EnxOfH58rnzefQ59Pn1ufZ5+/n+agMqB0oLCgwaDJoQqhKaFpobKh5aItoo+izaM4o5mj36P9pD2kiKS+pQelD6VSpVqlaKV3pYallaWkpbOlwqXRpeCl76X+pkCmaKaopvCnI6drp82oC6h2qNipHqlFqYWpzqoDqkyqVKqXqp+rA6sRqx+rLas7q0mrV6tlq3OrgauPq8mr76wtrHOso6zlrTytd63Xri+uPq5krqKu6K73rzqvSa+Fr5Svo6+yr8Gv0K/fr+6v/bAMsBuwKrA5sFGwYbBxsIGwkbChsLGwwbDRsOGxFrExsVaxe7GNsbqxyrH5siiylLK2swuzZLNws4ezmbOws8yz57QMtBm0PrRVtHq0vrUFtSW1SLVrtZG1nrWrtbi1xbXStd+1+LYRtiq2MrZLtlO2W7ZotnW2graOtpq2ubbbtue287b/tya3Ubd+t5O3qLe1t8K38bgiuC64OrhZuHu4nbjxuUi5VLlguWy5eLmfucq597oNuiq6Oro6ujq6Oro6ujq6OrqWuuG7c7vfvFG8371Jvbq98r5UvsO+/79Xv6C/28BIwFjA5cErwXzBwsHswizCuML4wwDDRcNNw3XDjsOrw/XEJ8SBxJfErsTYxQTFOsW+xjLGUMayxybHacdxx3nHnMfVyATIDMhvyR7J/sodyjXKW8p0ypPKq8rUyuzLHss8y1vLfsuly8vL3sv6zBTMKsxUzGbMdsyOzJ7MxMzczQLNGs3KzjjOY87iz2TP6tAx0HnQj9Cx0QbRK9Fi0cvSU9J60pHSsdK+03fT5dQk1DXURtRX1IHUktSs1L3U1tTn1PjVHtU11VrVf9WP1cHWA9ZI1rzWzdbe1u/XDdce1y/XQNd115vXydf22CLYS9iJ2LnY+dkx2WHZftmc2brZzNnm2iHaONpP2mbajNqj2rna0Nrl2vzbE9s121bbd9uO27zcLNxD3FrccdyL3KLcudzQ3QHdI91N3Wfded2P3andzN4L3lPehN6k3sTe5t8I3zLfld+53+rgMuBU4Hzg8uEJ4S/hU+Ft4Yrhl+Gj4cDh2eH24ibiVOJu4oripuKv4rjiweLK4tPi3OLl4u7i9+MA4wnjEuMb4zTjTeNk45LjwOPs5AnkJuRS5GLkcuSC5JLko+S05MXk1uTt5QTlGuUx5UflXeVz5YrlouW6AAAAAQAAAAczM3QVnhxfDzz1AAcD6AAAAADWC/5GAAAAANYeQAX8uP75Bk0EHQAAAAcAAgAAAAAAAAJLACgAAAAAAQ0AAAENAAAC3P//Atz//wLc//8C3P//Atz//wLc//8C3P//Atz//wLc//8C3P//Atz//wLc//8C3P//Atz//wLc//8C3P//Atz//wLc//8C3P//Atz//wLc//8C3P//Atz//wLc//8C3P//Atz//wQX//8EF///AvUAaQLTADAC0wAwAtMAMALTADAC0wAwAtMAMALTADADOgBpBa4AaQNCAAsDOgBpA0IACwM6AGkDOgBpBUMAaQKeAGkCngBpAp4AaQKeAGkCngBpAp4AaQKeAGkCngBpAp4AaQKeAGkCngBpAp4AaQKeAGkCngBpAp4AaQKeAGkCngBpAp4AaQKeAGkCngBpAp4AaQKeAGkCngBpAm8AHwJvAB8CewBpAwQAMAMEADADBAAwAwQAMAMEADADBAAwAwQAMAMnADADLABpAzwACQMsAGkDLABpAywAaQMsAGkBNgBpAtAAVwE2AFABNv/5ATb/6AE2/64BNgALATYADwE2AGABNgBoATb/5AE2AD8BNv/5ATYAFgE2AE4BNv/zAgH/9wIB//cCzwBpAs8AaQLPAGkCUgBpBFMAaQJSAFACUgBpAlIAaQJSAGkCUgBpA24AaQJSAGkCWgAJA7sAaQO7AGkDLABpBS0AaQMsAGkDLABpAywAaQMsAGkDLABpAywAaQRIAGkDLABpAywAaQNIADADSAAwA0gAMANIADADSAAwA0gAMANIADADSAAwA0gAMANIADADSAAwA0gAMANIADADSAAwA0gAMANIADADSAAwA0gAMANIADADSAAwA0gAMANIADADSAAwA0gAMANIADADSAAwA0gAMANIADADSAAwA0gAMANIADADSAAwA0gAMANIADAEZgAwAtIAaQLSAGkDSAAwAtcAaQLXAGkC1wBpAtcAaQLXAGkC1wBpAtcAaQLXAGkCbQApAm0AKQJtACkBAgBQAm0AKQJtACkCbQApAm0AKQJtACkCbQApAm0AKQJtACkC+wBjAzEAMAJLAAQCSwAEAksABAJLAAQCSwAEAksABAJLAAQDFwBjAxcAYwMXAGMDFwBjAxcAYwMXAGMDFwBjAxcAYwMXAGMDFwBjAx8AYwMfAGMDHwBjAx8AYwMfAGMDHwBjAxcAYwMXAGMDFwBjAxcAYwMXAGMDFwBjAxcAYwMXAGMCyP//BGYAIARmACAEZgAgBGYAIARmACACoQANAof//AKH//wCh//8Aof//AKH//wCh//8Aof//AKH//wCh//8Aof//AKRACsCkQArApEAKwKRACsCkQArAtAAVwMgAGMDIABjAyAAYwMgAGMDIABjAyAAYwMgAGMDIABjAyAAYwMgAGMDIABjAyAAYwMgAGMDIABjAyAAYwMgAGMDIABjAyAAYwMgAGMDIABjAyAAYwMgAGMDIABjAyAAYwMgAGMDIABjBDIAWgQyAFoFrgBpBU0AaQKEADMChAAzAoQAMwKEADMChAAzAoQAMwKEADMChAAzAoQAMwKEADMChAAzAoQAMwKEADMChAAzAoQAMwKEADMChAAzAoQAMwKEADMChAAzAoQAMwKEADMChAAzAl4AYwMEADADBAAwAwQAMAMEADADBAAwAwQAMAMEADADLAAwAcgAKwLQAFcByAArAtAAVwHIACsByAArAcj/+AHIACsByAArAcgAKwHIACsByAArAcgAKwHIACsByAArAcgAKwHIACsB///3Af//9wRvAGkEywBpBMsAaQMeAGkFHQBpAx4AaQMeAGkDHgBpAx4AaQMeAGkDHgBpBDoAaQMeAGkDHgBpA0gAMAMxAEUCVv/8Alb//AJW//wCVv/8Alb//AJW//wCVv/8AxoAYwMaAGMDGgBjAxoAYwMaAGMDGgBjAxoAYwMaAGMDGgBjAxoAYwMaAGMDGgBjAxoAYwMaAGMDGgBjAxoAYwMaAGMDGgBjAxoAYwMaAGMDGgBjAxoAYwMaAGMDGgBjBKYAYwSmAGMEpgBjBKYAYwSmAGMDEwBeAxMAXgMTAF4DEwBeAxMAXgMTAF4DEwBeAxMAXgMTAF4DEwBeApsAMAKbADACmwAwApsAMAKbADACVgAyAlYAMgJWADICVgAyAlYAMgJWADICVgAyAlYAMgJWADICVgAyAlYAMgJWADICVgAyAlYAMgJWADICVgAyAlYAMgJWADICVgAyAlYAMgJWADICVgAyAlYAMgJWADICVgAyAlYAMgPdADID3QAyAqoAWwI7ACoCOwAqAjsAKgI7ACoCOwAqAjsAKgI7ACoCqgAqAoAAKgKqACoCqgAqAqoAKgKqACoEuwAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAg//7AIP/+wBYQAPArIAKgKyACoCsgAqArIAKgKyACoCsgAqArIAKgK6ACoCqQBbAqkAAAKpAFsCqf/YAqn/2AKpAFsBFwBKARcAWwEXAEABFwACARf/8QEX/54BFwASARf//wEXAFABFwBKARf/1AEXAC8BFwACAjMASgEXAAYBFwA8ARf//AEc/6QBHP+kARz/pAJoAFsCaP/YAmgAWwJeAFsBFwBbARcAQAEXAFsBFwBYAVoAWwEXAFgCMwBbARf/6AEn//kEIQBbBCEAWwKpAFsCqQBbAwIANQKpAFsCqQBbAqkAWwKpAFsCqQBbA8UAWwKpAFsCqQBbAnsAKgJ7ACoCewAqAnsAKgJ7ACoCewAqAnsAKgJ7ACoCewAqAnsAKgJ7ACoCewAqAnsAKgJ7ACoCewAqAnsAKgJ7ACoCewAqAnsAKgJ7ACoCewAqAn8AKgJ7ACoCewAqAnsAKgJ7ACoCewAqAnsAKgJ7ACoCewAqAnsAKgJ7ACoCewAqAnsAKgQrACoCqgBbAqoAWwKqACoBmgBbAZoAWwGaADcBmgBYAZr//QGaAFgBmgBIAZr/6AH1ABgB9QAYAfUAGAD/AFAB9QAYAfUAGAH1ABgB9QAYAfUAGAH1ABgB9QAYAfUAGAKkAFsBMgAZAZ4ADwGoABQBngAPAZ4ADwGeAA8BngAJAZ4ADwGeAA8CpQBWAqUAVgKlAFYCpQBWAqUAVgKlAFYCpQBWAqUAVgKlAFYCpQBWAq0AVgKtAFYCrQBWAq0AVgKtAFYCrQBWAqUAVgKlAFYCpQBWAqUAVgKlAFYCpQBWAqUAVgKlAFYCL//+A4MABgODAAYDgwAGA4MABgODAAYCKAAOAi//6gIv/+oCL//qAi//6gIv/+oCL//qAi//6gIv/+oCL//qAi//6gIJACgCCQAoAgkAKAIJACgCCQAoAjIASAKqACoCqgAqAqoAKgKqACoCqgAqAqoAKgKqACoCqgAqAqoAKgKqACoCqgAqAqoAKgKqACoCqgAqAqoAKgKqACoCqgAqAqoAKgKqACoCqgAqAqoAKgKqACoCqgAqAqoAKgKqACoCqgAqA90AMgPdADIEvQAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAArAVMAWwFBAFsBQQBAAUEAWwFBAFsBbQBbAUEAWwI1AFsBQQApAUH/8QQ6ACoBiwBWAZUADAGLAFYBiwBWAYsAVgGL//YBiwBWAYsASAPZAFYD2QBWA9kAVgPZAFYD2QBWAqUAVAKlAFQCpQBUAqUAVAKlAFQCpQBUAqUAVAKlAFQCpQBUAhMALQITAC0CEwAtAhMALQITAC0EsQAEAsgADwJ4AA8CugBbAosADwJn//8CZ///Amf//wJn//8CZ///Amf//wJn//8CZ///Amf//wJn//8CZ///Amf//wJn//8CZ///Amf//wJn//8CZ///Amf//wJn//8CZ///Amf//wJn//8CZ///Amf//wJn//8CZ///A2z//wNs//8ChABhAmEALAJhACwCYQAsAmEALAJhACwCYQAsAmEALAK+AGEC0gAgAr4AYQLSACACvgBhAr4AYQTOAGECOgBhAjoAYQI6AGECOgBhAjoAYQI6AGECOgBhAjoAYQI6AGECOgBhAjoAYQI6AEMCOgBhAjoAYQI6AGECOgBhAjoAYQI6AGECOgBhAjoAYQI6AGECOgBhAjoAYQKcACwCMAAlAjAAJQIgAGECjgAsAo4ALAKOACwCjgAsAo4ALAKOACwCjgAsAq8ALAK7AGEC4wAiArsAYQK7AGECuwBhArsAYQEiAGEBIgBhASIARgJQAEEBIgAIASL/9wEi/6QBIgAYASIABQEiAFYBIgBeASL/2gEiADUBIgAIAm8ATAEiAAwBIgBDASIAAgHB//wBwf/8AmwAYQJsAGECbABhAmwAYQH7AGEB+wBHAfsAYQH7AGEB+wBhAfsAYQO8AGEB+wBhAfv/+AMyAGEDMgBhArsAYQK7AGECuwBhArsAYQK7AGECuwBhArsAYQR8AGECuwBhArsAYQLCACwCwgAsAsIALALCACwCwgAsAsIALALCACwCwgAsAsIALALCACwCwgAsAsIALALCACwCwgAsAsIALALCACwCwgAsAsIALALCACwCwgAsAsIALALCACwCwgAsAsIALALCACwCwgAsAsIALALCACwCwgAsAsIALALCACwCwgAsAsIALALCACwDqwAsAm8AYQJvAGECwgAsAnYAYQJ2AGECdgBhAnYAYQJ2AFQCdgBhAnYAYQJ2AGECEwAlAhMAJQITACUA/wBQAhMAJQITACUCEwAlAhMAJQITACUCEwAlAhMAJQITACUCigBbAe0ABAHtAAQB7QAEAe0ABAHtAAQB7QAEAe0ABAHtAAQCqABbAqgAWwKoAFsCqABbAqgAWwKoAFsCqABbAqgAWwKoAFsCqABbArAAWwKwAFsCsABbArAAWwKwAFsCsABbAqgAWwKoAFsCqABbAqgAWwKoAFsCqABbAqgAWwKoAFsCaQAIA70AIgO9ACIDvQAiA70AIgO9ACICPAAMAjkAAgI5AAICOQACAjkAAgI5AAICOQACAjkAAgI5AAICOQACAjkAAgIrACkCKwApAisAKQIrACkCKwApAq8AWwKvAFsCrwBbAq8AWwKvAFsCrwBbAq8AWwKvAFsCrwBbAq8AWwKvAFsCrwBbAq8AWwKvAFsCrwBbAq8AWwKvAFsCrwBbAq8AWwKvAFsCrwBbAq8AWwKvAFsCrwBbAq8AWwKvAFsDmQBVA5kAVQToAGECJwAqAicAKgInACoCJwAqAicAKgInACoCJwAqAicAKgInACoCJwAqAicAKgInACoCJwAqAicAKgInACoCJwAqAicAKgInACoCJwAqAicAKgInACoCJwAqAicAKgKcADkCCABbAo4ALAKOACwCjgAsAo4ALAKOACwCjgAsAo4ALAK0ACwBqgA5AaoAOQGqADkCbwBBAaoAOQGqADkBqv/pAaoAOQGqADkBqgA5AaoAHwGqADkBqgA5Am8ATAGqADkBqgA5AaoAOQHB//wBwf/8A7wAYQQAAGEEAABhAq4AYQKuAGECrgBhAq4AYQKuAGECrgBhAq4AYQRvAGECrgBhAq4AYQLCACwB9//8Aff//AH3//wB9//8Aff//AH3//wB9//8Aff//AKuAFsCrgBbAq4AWwKuAFsCrgBbAq4AWwKuAFsCrgBbAq4AWwKuAFsCtgBbArYAWwK2AFsCtgBbArYAWwK2AFsCrgBbAq4AWwKuAFsCrgBbAq4AWwKuAFsCrgBbAq4AWwP/AFsD/wBbA/8AWwP/AFsD/wBbAqMAVgKjAFYCowBWAqMAVgKjAFYCowBWAqMAVgKjAFYCowBWAqMAVgIrACkCKwApAisAKQIrACkCKwApAZQAJQGiACAC9gAMAtsAbQLrAG0CQgBtAkIAbQJFAG0DJAANApkAbQKZAG0CmQBtBAUAEwKCACADNwBtAzcAbQM3AG0DUwBtAscAbQLHAG0DFgANA8MAbQM0AG0DUAAzAzUAbQLKAG0CzgA0AlsADQKzABACswAQA54ALQKcABEC4AA2Az0AbQRHAG0EYABtAycAbQLJAG0DPAANA+EAbQSjAA0EnABtAnwAMQLEADUCwwAdAT0AbQE2AAsCHAASA0oADQRLAG0C2wA6A0EADgMrABMDhAASA1AAMwL5AA4CagAeAr8AbQQsABMCggAgAvMAbQLkAG0C3QAjAzsADQNPAG0EPwBtBKwAbQNQAG0DzgA5As4ANAJbAA0CmwAGAof//ALBABEDzgAOAvsANgLgADUC4ABtAyUAbQPdACAD3QAgAT4AbQQFABMCygBtAy8AbQNQAG0C3AAzA+gAbQL2AAwC9gAMBBYABwKZAG0DNwApAzcAKQQFABMCggAgAm8AHwM3AG0DNwBtA1AAMwNQADMDUAAzAsMAHQKzABACswAQArMAEALgADYCQgBtA+EAbQJrAB0CoAAOAqwAGgKCADkDFwAMA1YAMwQ9ABUC4wAfAt0AbQMw/7QDMQANAxkADgLlAA0DnQAxAk8AbQKCACACzgA0As4ANAMgAGMDRAAeAoQAMwKEADMChAAzAxoAYwMaAGMDGgBjAxoAYwMWACACzQBcAncADQMTAF4DEwBeA58AMgLMAF8DaAAOA+EAXwSfAAwEjABtAf//9wM7ABMCdwANAyAAYwMgAGMEMgBaAoQAMwMaAGMDGgBjAxMAXgMTAF4DEwBeA+EAXwNIADAC7wAaAk0AMAKWAD4CZgBdAegAXQHoAF0B0gBdApgACAJ0ACwCdAAsAnQALANRAA0CIAAcArYAXQK2AF0CtgBdAswAXQJWAF0CVgBdAoEABQMeAF0CqQBdAoEALAKlAF0CsABdAjsALAHtAAQCO//wAjv/8AMlACsCHQAJAmEAKgKyAF0DrQBdA60AXQKGAF0CPwBdAn8ABAMnAF0DpgAFA7gAXQIYACsCQQAsAj8AGAEbAEwBFwASARz/ogKi/9wDbABdAmQAMAKj//YCZQAAAsAADwKKACwCVAAFAgQAKwJZAF0DcgANAiAAHAJWAF0CZgBbAlUAAAKeAAQCvgBdA3YAXQKlAF0D0ABdAyYALwI7ACwB7QAEAj4ABgI+AAYCHQAJAwMABQJ6ACoCYQApAqIAXQK8AF0DAwAVAwMAFQEbAF0DUQANAlYAXQKXAAUCrwBdAr8AXQJeACcDPQBdAk0AMAJNADAD4wAwAnQALAJzADgCcwA4A1EADQIgABwCD//sArYAXQK2AF0CgQAsAooALAKKACwCPwAYAjv/8AI7//ACO//wAmEAKgHoAF0DJwBdAewADQIdAAsCOQAWAiAANQKBAAUCsAAuA6oACQJeABYCuwBeAqn/pQKWAAUCfgBMAiEALgKzACkDUQANAe7/9wKeAE0CngBNAp4ATQJVAF4CPAAFAqkAXQKiAF0EGwBdAmMALAK3AE0EGwBOBDQATgJAAFACnAAFA1cAXgH0AF0CIAAcAjsALAHoAF0CbgAnARcABgKzACcCpQBWBBsATgKqACoCswApAmQAKgJkACoCZAAqAp4ATQKeAE0CngBNAp4ATQKWAEYEGwBdAqUAVAKlAFQCSQBQAqUABQMoAFADrQAIA7IAXQJ6//wCqgAqAqoAKgPdADICZAAqAmQAKwJkACsCngBNAp4ATQKlAFQCpQBUAqUAVAMoAFACawARAtz//wOCAAkCqgBbAtT/+ALc//8CzwBpApsAMAFyAAgCPgAOAjwABQKdACYCPgARAmkAMAJWAB4ChAAsAmkAHAKsADIBcgAIAj4ABgI8AAYCnQAmAj4AEQJpADACVgAeAoQALAJpABwBrgAcAa4AUQGuABwBrgAbAa4AFgGuABsBrgAlAa4AJAGuABwBrgAgArwAPQK8AJACvAA8ArwAPgK8ADUCvABBArwASgK8AEkCvAA7ArwAQQK8ADwCvACQArwARwK8AD4CvAA1ArwAQQK8AEoCvABJArwAOwK8AEEBrgAcAa4AUQGuABwBrgAbAa4AFgGuABsBrgAlAa4AJAGuABwBrgAgAa4AHAGuAFEBrgAcAa4AGwGuABYBrgAbAa4AJQGuACQBrgAcAa4AIAGuABwBrgBRAa4AHAGuABsBrgAWAa4AGwGuACUBrgAkAa4AHAGuACABrgAcAa4AUQGuABwBrgAbAa4AFgGuABsBrgAlAa4AJAGuABwBrgAgAK7/QgQKAFEECgBRBAoAHAQKAFEECgAbBAoAUQQKABsECgAbBAoAJAGQABMBYP/aAQsAQgE6AEIA4wAuAOMAMAKzAC4BDABFAQwARQK/ABsA4wAuAj0ACQI9AEUBhwA/ANIAPwDjAC4BYP/kAfQAAAFg/9oBHwBMAU4ATAFYAH4BYP/kAIEALQFfADkBXwATAU0AaQFNABMBUQBfAVIAIAFzAEMBcwAdAWEAcwFhAB0BZQBpAWYAKgPoAAAB9AAAArwALwPoAAABfwA5AX8AOQF/ADkD6AAAAfQAAAGTAEMB+AAuAfgAIgE4AC4BOAAiAaAAMAGgAC4BoAAwAOMALgDjADAA4wAwAgwAOAIMACwBTAA4AUwALAEMAEUBDABFAdwALgHdACIBIgAuASMAIgDnADMCCgAIAgkARQGHAD8BnwAwAZ8ALgGfADAA4gAuAOIAMADjADAA0gA/AUkAJAFJACsCvAAAAGQAAADjAAABDQAAAIYAAAAAAAAC0wAwAjsAKgLTADACvAAfAm0AKQKqACoDJwAeAcH/pAKXAB4DBAAwAzgAVwKUAB4ChgAeAsgAHgOUAGkDcAAeBmoAaQNLAB4C7gAeAtAAHQKGAB4C0QBMAqoAMwSqAB4Cw//8AR8ATAIaAEwBYP/kAkYAQwJGAEMCRgBrAkYAQwJGAEMCRgBDAkYAQwJGAEMCRgBDAkYAQwJGAEMCRgA6AkYAOgJGAEMCRgAlA5sAKgGP/90DggAJAtz//wMsAGkCkQArAyMAQwKqAFsCvABIA0sAJQS6ACUCWABgAlgAeAJYAEMCWAB5AlgAagJYAG4CWABgAlgAbwLZADICWABfAlgAYAJYAEMCWABq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Bz4HPQdEB0MHTAdKB0cHQAdFB0EHRgdJB04HUwdSB1QHUAblBucG7AbyBvYG7wbjBt8G+gbwBuoG7QRuBG8ElwRqBI8EjgSRBJIEkwSMBI0ElAR3BHQEgQSIBGYEZwRoBGkEbARtBHAEcQRyBHMEdgSCBIMEhQSEBIYEhwSKBIsEiQSQBJUElgUGBQcFCAUJBQwFDQUQBREFEgUTBRYFIgUjBSUFJAUmBScFKgUrBSkFMAU1BTYFDgUPBTcFCgUvBS4FMQUyBTMFLAUtBTQFFwUUBSEFKASYBTgEmQU5BJoFOgSbBTsEdQUVBNgFeQTZBXoEawULBJwFPASdBT0EngU+BJ8FPwSgBUAEoQVBBKIFQgSjBUMEpAVEBKUFRQSmBUcEqAVIBKkFSQSqBUoEqwVLBKwFTAStBU0ErgVOBK8FTwSwBVAEsQVRBLMFUwS0BVQEtQS2BVYEtwVXBVgEuAVZBLkFWgS6BVsEuwVcBVUEvAVdBL0FXgS+BV8EvwVgBMAFYQTBBWIEwgVjBMMFZATEBWUExQVmBMYFZwTHBWgEyAVpBMkFagTKBWsEywVsBMwFbQTNBW4EzgVvBM8FcATQBXEE0QVyBNIFcwTTBXQE1AV1BNUFdgTWBXcE1wV4BKcFRgSyBVIE2gV7BNsFfAAlAasALQGyAC4BswBEAckAQwHIADQBuQBQAdYAVwHdAFQB2gBfAeUAcwH7AHUB/QB4AgAAfgIGAH8CBwCCAgoAowIrAKQCLACeAiYAnQIlAK8CNwCxAjkAuwJDALwCRAC0AjwAtwI/AL0CRQDFAk4AxgJPAN4CZwDaAmMA5AJtAOECagDjAmwA6gJzAPQCfQAVAZsAFwGdAA4BlAAQAZYAEQGXABIBmAAPAZUABwGNAAkBjwAKAZAACwGRAAgBjgA+AcMAQAHFAEYBywA2AbsAOAG9ADkBvgA6Ab8ANwG8AGMB6QBhAecAkQIZAJMCGwCIAhAAigISAIsCEwCMAhQAiQIRAJUCHQCXAh8AmAIgAJkCIQCWAh4AzgJXANACWQDSAlsA1AJdANUCXgDWAl8A0wJcAOwCdQDrAnQA7QJ2AO8CeAZzBnUGdwZ0BngGSgZJBkgGSwZXBlgGVgbVBtYGJwaBBoUGfgZ/BoQGjwaKBoIGgwZ5Bo4GjAaGBocGiwW/Bb4GtQavBrEGswa3BrgGtgaw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AREBEgETARQAYwEVAK4AkAEWACUAJgD9AP8AZAEXARgBGQAnARoA6QEbARwBHQEeAR8AKABlASABIQEiAMgBIwEkASUBJgEnASgAygEpASoAywErASwBLQEuAS8BMAExATIBMwApACoA+AE0ATUBNgE3ATgBOQArAToBOwE8AT0BPgAsAT8AzAFAAM0BQQDOAUIA+gFDAM8BRAFFAUYBRwFIAC0BSQAuAUoBSwAvAUwBTQFOAU8BUAFRAVIBUwDiADABVAAxAVUBVgFXAVgBWQFaAVsBXAFdAGYAMgDQAV4A0QFfAWABYQFiAWMBZABnAWUBZgFnANMBaAFpAWoBawFsAW0BbgFvAXABcQFyAXMBdACRAXUArwF2AXcBeACwADMA7QA0ADUBeQF6AXsBfAF9AX4BfwA2AYABgQGCAOQBgwD7AYQBhQGGAYcBiAGJAYoANwGLAYwBjQGOAY8BkAA4ANQBkQGSANUBkwBoAZQA1gGVAZYBlwGYAZkBmgGbAZwBnQGeAZ8BoAGhAaIBowA5ADoBpAGlAaYBpwA7ADwA6wGoALsBqQGqAasBrAGtAa4APQGvAOYBsAGxAbIBswG0AbUBtgG3AbgBuQG6AbsBvAG9Ab4BvwHAAcEBwgHDAcQBxQHGAccByAHJAcoBywHMAc0BzgHPAdAB0QHSAdMB1AHVAdYB1wHYAdkB2gHbAdwB3QHeAd8B4AHhAeIB4wHkAeUB5gHnAegB6QHqAesB7AHtAe4B7wHwAfEB8gHzAfQB9QH2AfcB+AH5AfoB+wH8Af0B/gH/AgACAQICAgMCBAIFAgYCBwIIAgkCCgILAgwCDQIOAg8CEAIRAhICEwIUAhUCFgIXAhgCGQIaAhsCHAIdAh4CHwIgAiECIgIjAiQCJQImAicCKAIpAioCKwIsAi0CLgIvAjACMQIyAjMCNAI1AjYCNwI4AjkCOgI7AjwCPQI+Aj8CQAJBAkICQwJEAkUCRgBEAGkCRwJIAkkCSgJLAkwCTQBrAk4CTwJQAlECUgJTAGwCVABqAlUCVgJXAlgAbgJZAG0AoAJaAEUARgD+AQAAbwJbAlwCXQBHAOoCXgEBAl8CYAJhAEgAcAJiAmMCZAByAmUCZgJnAmgCaQJqAHMCawJsAHECbQJuAm8CcAJxAnICcwJ0AnUCdgBJAEoA+QJ3AngCeQJ6AnsCfABLAn0CfgJ/AoACgQBMANcAdAKCAHYCgwB3AoQChQKGAHUChwKIAokCigKLAowATQKNAo4ATgKPApACkQBPApICkwKUApUClgKXApgA4wBQApkAUQKaApsCnAKdAp4CnwKgAqECogB4AFIAeQKjAHsCpAKlAqYCpwKoAqkAfAKqAqsCrAB6Aq0CrgKvArACsQKyArMCtAK1ArYCtwK4ArkAoQK6AH0CuwK8Ar0AsQBTAO4AVABVAr4CvwLAAsECwgLDAsQAVgLFAsYCxwDlAsgA/ALJAsoCywLMAs0AiQLOAFcCzwLQAtEC0gLTAtQC1QBYAH4C1gLXAIAC2ACBAtkAfwLaAtsC3ALdAt4C3wLgAuEC4gLjAuQC5QLmAucC6ABZAFoC6QLqAusC7ABbAFwA7ALtALoC7gLvAvAC8QLyAvMAXQL0AOcC9QL2AvcC+AL5AvoC+wL8Av0C/gL/AwADAQMCAwMDBAMFAwYDBwMIAwkDCgMLAwwDDQMOAw8DEAMRAxIDEwMUAxUDFgMXAxgDGQMaAxsDHAMdAx4DHwMgAyEDIgMjAyQDJQMmAycDKAMpAyoDKwMsAy0DLgMvAzADMQMyAzMDNAM1AzYDNwM4AzkDOgM7AzwDPQM+Az8DQANBA0IDQwNEA0UDRgNHA0gDSQNKA0sDTANNA04DTwNQA1EDUgNTAMAAwQNUA1UDVgNXA1gDWQNaA1sDXANdA14DXwNgA2EDYgNjA2QDZQNmA2cDaANpA2oDawNsA20DbgNvA3ADcQNyA3MDdAN1A3YDdwN4A3kDegN7A3wDfQN+A38DgAOBA4IDgwOEA4UDhgOHA4gDiQOKA4sDjAONA44DjwOQA5EDkgOTA5QDlQOWA5cDmAOZA5oDmwOcA50DngOfA6ADoQOiA6MDpAOlA6YDpwOoA6kDqgOrA6wDrQOuA68DsAOxA7IDswO0A7UDtgO3A7gDuQO6A7sDvAO9A74DvwPAA8EDwgPDA8QDxQPGA8cDyAPJA8oDywPMA80DzgPPA9AD0QPSA9MD1APVA9YD1wPYA9kD2gPbA9wD3QPeA98D4APhA+ID4wPkA+UD5gPnA+gD6QPqA+sD7APtA+4D7wPwA/ED8gPzA/QD9QP2A/cD+AP5A/oD+wP8A/0D/gP/BAAEAQQCBAMEBAQFBAYEBwQIBAkECgQLBAwEDQQOBA8EEAQRBBIEEwQUBBUEFgQXBBgEGQQaBBsEHAQdBB4EHwQgBCEEIgQjBCQEJQQmBCcEKAQpBCoEKwQsBC0ELgQvBDAEMQQyBDMENAQ1BDYENwQ4BDkEOgQ7BDwEPQQ+BD8EQARBBEIEQwREBEUERgRHBEgESQRKBEsETARNBE4ETwRQBFEEUgRTBFQEVQRWBFcEWARZBFoEWwRcBF0EXgRfBGAEYQRiBGMEZARlBGYEZwRoBGkEagRrBGwEbQRuBG8EcARxBHIEcwR0BHUEdgR3BHgEeQR6BHsEfAR9BH4EfwSABIEEggSDBIQEhQSGBIcEiASJBIoEiwSMBI0EjgSPBJAEkQSSBJMElASVBJYElwSYBJkEmgSbBJwEnQSeBJ8EoAShBKIEowSkBKUEpgSnBKgEqQSqBKsErAStBK4ErwSwBLEEsgSzBLQEtQS2BLcEuAS5BLoEuwS8BL0EvgS/BMAEwQTCBMMExATFBMYExwTIBMkEygTLBMwEzQTOBM8E0ATRBNIE0wTUBNUE1gTXBNgE2QTaAJ0AngTbBNwE3QTeBN8E4AThBOIE4wTkBOUE5gTnBOgE6QTqBOsE7ATtBO4E7wTwBPEE8gTzBPQE9QT2BPcE+AT5BPoE+wT8BP0E/gT/BQAFAQUCBQMFBAUFBQYFBwUIBQkFCgULBQwFDQUOBQ8FEAURBRIFEwUUBRUFFgUXBRgFGQUaBRsFHAUdBR4FHwUgBSEFIgUjBSQFJQUmBScFKAUpBSoFKwUsBS0FLgUvBTAFMQUyBTMFNAU1BTYFNwU4BTkFOgU7BTwFPQU+BT8FQAVBBUIFQwVEBUUFRgVHBUgFSQVKBUsFTAVNBU4FTwVQBVEFUgVTBVQFVQVWBVcFWAVZBVoFWwVcBV0FXgVfBWAFYQViBWMFZAVlBWYFZwVoBWkFagVrBWwFbQVuBW8FcAVxBXIFcwV0BXUFdgV3BXgFeQV6BXsFfAV9BX4FfwWABYEFggWDBYQFhQWGBYcFiAWJBYoFiwWMBY0FjgWPBZAFkQWSBZMFlAWVBZYFlwWYBZkFmgWbBZwFnQWeBZ8FoAWhBaIFowWkBaUFpgWnBagFqQWqBasFrAWtBa4FrwWwBbEFsgWzBbQFtQW2BbcFuAW5BboFuwW8Bb0FvgW/BcAFwQXCBcMFxAXFBcYFxwXIBckFygXLBcwFzQXOBc8F0AXRBdIF0wXUBdUF1gXXBdgF2QXaBdsF3AXdBd4F3wXgBeEF4gXjBeQF5QXmBecF6AXpBeoF6wXsBe0F7gXvBfAF8QXyBfMF9AX1BfYF9wX4BfkF+gX7BfwF/QX+Bf8GAAYBBgIGAwYEBgUGBgYHBggGCQYKBgsGDAYNBg4GDwYQBhEGEgYTBhQGFQYWBhcGGAYZBhoGGwYcBh0GHgYfBiAGIQYiBiMGJAYlBiYGJwYoBikGKgYrBiwGLQYuBi8GMAYxAJsGMgYzABMAFAAVABYAFwAYABkAGgAbABwGNAY1BjYGNwY4BjkGOgY7BjwGPQY+Bj8GQAZBBkIGQwZEBkUGRgZHBkgGSQZKBksGTAZNBk4GTwZQBlEGUgZTBlQGVQZWBlcGWAZZBloGWwZcBl0GXgZfBmAGYQZiBmMGZAZlBmYGZwZoBmkGagZrBmwGbQZuBm8GcAZxBnIGcwZ0BnUGdgZ3BngGeQZ6BnsGfAZ9Bn4GfwaABoEGggaDALwA9AaEBoUA9QD2BoYGhwaIBokADQA/AMMAhwAdAA8AqwAEAKMABgARACIAogAFAAoAHgASAEIGigaLBowGjQaOBo8AXgBgAD4AQAALAAwGkAaRBpIGkwaUBpUAswCyBpYGlwAQBpgGmQaaBpsGnACpAKoAvgC/AMUAtAC1ALYAtwDEBp0GngafBqAGoQaiBqMGpAalBqYGpwaoBqkGqgarBqwGrQauBq8GsAaxBrIGswa0BrUGtga3BrgGuQa6AIQGuwC9AAcGvAa9AKYA9wa+Br8GwAbBBsIGwwbEBsUGxgbHBsgAhQbJBsoGywCWBswGzQbOAA4A7wDwALgAIACPACEAHwCVAJQAkwCnAGEApAbPAJIAnAbQBtEAmgCZAKUG0gCYAAgAxgbTBtQG1QbWBtcG2AbZBtoG2wbcBt0G3gbfBuAG4QbiALkG4wbkBuUG5gbnBugG6QbqBusG7AAjAAkAiACGAIsAigCMAIMAXwDoBu0AggDCBu4G7wBBBvAG8QbyBvMG9Ab1BvYG9wb4BvkG+gb7BvwG/Qb+Bv8HAAcBBwIHAwcEBwUHBgcHBwgHCQcKBwsHDAcNBw4HDwcQBxEHEgcTBxQHFQcWBxcHGAcZBxoHGwccBx0HHgcfByAHIQciByMHJAclByYHJwcoBykHKgcrBywHLQcuBy8HMAcxBzIHMwc0BzUHNgc3BzgHOQc6BzsHPAc9Bz4HPwdAB0EHQgdDB0QHRQdGB0cHSAdJB0oHSwdMB00HTgdPB1AHUQdSB1MHVAdVB1YHVwdYB1kHWgdbB1wHXQCNANsA4QDeANgAjgDcAEMA3wDaAOAA3QDZB14HXwdgB2EHYgdjB2QHZQdmB2cHaAdpB2oHawdsB20HbgdvB3AHcQdyB3MHdAd1B3YHdwd4BE5VTEwGQWJyZXZlB3VuaTFFQUUHdW5pMUVCNgd1bmkxRUIwB3VuaTFFQjIHdW5pMUVCNAd1bmkwMUNEB3VuaTFFQTQHdW5pMUVBQwd1bmkxRUE2B3VuaTFFQTgHdW5pMUVBQQd1bmkwMjAwB3VuaTFFQTAHdW5pMUVBMgd1bmkwMjAyB0FtYWNyb24HQW9nb25lawpBcmluZ2FjdXRlB0FFYWN1dGUHdW5pMUUwOAtDY2lyY3VtZmxleApDZG90YWNjZW50B3VuaTAxQzQGRGNhcm9uBkRjcm9hdAd1bmkxRTBDB3VuaTFFMEUHdW5pMDFDNQZFYnJldmUGRWNhcm9uB3VuaTFFMUMHdW5pMUVCRQd1bmkxRUM2B3VuaTFFQzAHdW5pMUVDMgd1bmkxRUM0B3VuaTAyMDQKRWRvdGFjY2VudAd1bmkxRUI4B3VuaTFFQkEHdW5pMDIwNgdFbWFjcm9uB3VuaTFFMTYHdW5pMUUxNAdFb2dvbmVrB3VuaTFFQkMHdW5pMDFCNwd1bmkwMUVFBkdjYXJvbgtHY2lyY3VtZmxleAxHY29tbWFhY2NlbnQKR2RvdGFjY2VudAd1bmkxRTIwB3VuaTAxRTQESGJhcgd1bmkxRTJBB3VuaTAyMUULSGNpcmN1bWZsZXgHdW5pMUUyNAJJSgZJYnJldmUHdW5pMDIwOAd1bmkxRTJFB3VuaTFFQ0EHdW5pMUVDOAd1bmkwMjBBB0ltYWNyb24HSW9nb25lawZJdGlsZGULSmNpcmN1bWZsZXgHdW5pMDFFOAxLY29tbWFhY2NlbnQHdW5pMDFDNwZMYWN1dGUGTGNhcm9uDExjb21tYWFjY2VudARMZG90B3VuaTFFMzYHdW5pMDFDOAd1bmkxRTNBB3VuaTFFNDIHdW5pMDFDQQZOYWN1dGUGTmNhcm9uDE5jb21tYWFjY2VudAd1bmkxRTQ0B3VuaTFFNDYDRW5nB3VuaTAxQ0IHdW5pMUU0OAZPYnJldmUHdW5pMUVEMAd1bmkxRUQ4B3VuaTFFRDIHdW5pMUVENAd1bmkxRUQ2B3VuaTAyMEMHdW5pMDIyQQd1bmkwMjMwB3VuaTFFQ0MHdW5pMUVDRQVPaG9ybgd1bmkxRURBB3VuaTFFRTIHdW5pMUVEQwd1bmkxRURFB3VuaTFFRTANT2h1bmdhcnVtbGF1dAd1bmkwMjBFB09tYWNyb24HdW5pMUU1Mgd1bmkxRTUwB3VuaTAxRUELT3NsYXNoYWN1dGUHdW5pMUU0Qwd1bmkxRTRFB3VuaTAyMkMGUmFjdXRlBlJjYXJvbgxSY29tbWFhY2NlbnQHdW5pMDIxMAd1bmkxRTVBB3VuaTAyMTIHdW5pMUU1RQZTYWN1dGUHdW5pMUU2NAd1bmlBNzhCB3VuaTFFNjYLU2NpcmN1bWZsZXgMU2NvbW1hYWNjZW50B3VuaTFFNjAHdW5pMUU2Mgd1bmkxRTY4B3VuaTFFOUUHdW5pMDE4RgRUYmFyBlRjYXJvbgd1bmkwMTYyB3VuaTAyMUEHdW5pMUU2Qwd1bmkxRTZFBlVicmV2ZQd1bmkwMUQzB3VuaTAyMTQHdW5pMUVFNAd1bmkxRUU2BVVob3JuB3VuaTFFRTgHdW5pMUVGMAd1bmkxRUVBB3VuaTFFRUMHdW5pMUVFRQ1VaHVuZ2FydW1sYXV0B3VuaTAyMTYHVW1hY3Jvbgd1bmkxRTdBB1VvZ29uZWsFVXJpbmcGVXRpbGRlB3VuaTFFNzgGV2FjdXRlC1djaXJjdW1mbGV4CVdkaWVyZXNpcwZXZ3JhdmULWWNpcmN1bWZsZXgHdW5pMUU4RQd1bmkxRUY0BllncmF2ZQd1bmkxRUY2B3VuaTAyMzIHdW5pMUVGOAZaYWN1dGUKWmRvdGFjY2VudAd1bmkxRTkyEElhY3V0ZV9KLmxvY2xOTEQGQS5zczAxC0FhY3V0ZS5zczAxC0FicmV2ZS5zczAxDHVuaTFFQUUuc3MwMQx1bmkxRUI2LnNzMDEMdW5pMUVCMC5zczAxDHVuaTFFQjIuc3MwMQx1bmkxRUI0LnNzMDEMdW5pMDFDRC5zczAxEEFjaXJjdW1mbGV4LnNzMDEMdW5pMUVBNC5zczAxDHVuaTFFQUMuc3MwMQx1bmkxRUE2LnNzMDEMdW5pMUVBOC5zczAxDHVuaTFFQUEuc3MwMQx1bmkwMjAwLnNzMDEOQWRpZXJlc2lzLnNzMDEMdW5pMUVBMC5zczAxC0FncmF2ZS5zczAxDHVuaTFFQTIuc3MwMQx1bmkwMjAyLnNzMDEMQW1hY3Jvbi5zczAxDEFvZ29uZWsuc3MwMQpBcmluZy5zczAxD0FyaW5nYWN1dGUuc3MwMQtBdGlsZGUuc3MwMQdBRS5zczAxDEFFYWN1dGUuc3MwMQx1bmkwMUM0LnNzMDEMdW5pMDFDNS5zczAxBkUuc3MwMQtFYWN1dGUuc3MwMQtFYnJldmUuc3MwMQtFY2Fyb24uc3MwMQx1bmkxRTFDLnNzMDEQRWNpcmN1bWZsZXguc3MwMQx1bmkxRUJFLnNzMDEMdW5pMUVDNi5zczAxDHVuaTFFQzAuc3MwMQx1bmkxRUMyLnNzMDEMdW5pMUVDNC5zczAxDHVuaTAyMDQuc3MwMQ5FZGllcmVzaXMuc3MwMQ9FZG90YWNjZW50LnNzMDEMdW5pMUVCOC5zczAxC0VncmF2ZS5zczAxDHVuaTFFQkEuc3MwMQx1bmkwMjA2LnNzMDEMRW1hY3Jvbi5zczAxDHVuaTFFMTYuc3MwMQx1bmkxRTE0LnNzMDEMRW9nb25lay5zczAxDHVuaTFFQkMuc3MwMQZGLnNzMDEGRy5zczAxC0dicmV2ZS5zczAxC0djYXJvbi5zczAxEEdjaXJjdW1mbGV4LnNzMDERR2NvbW1hYWNjZW50LnNzMDEPR2RvdGFjY2VudC5zczAxDHVuaTFFMjAuc3MwMQx1bmkwMUU0LnNzMDEGSS5zczAxB0lKLnNzMDELSWFjdXRlLnNzMDEVSWFjdXRlX0oubG9jbE5MRC5zczAxC0licmV2ZS5zczAxEEljaXJjdW1mbGV4LnNzMDEMdW5pMDIwOC5zczAxDklkaWVyZXNpcy5zczAxDHVuaTFFMkUuc3MwMQ9JZG90YWNjZW50LnNzMDEMdW5pMUVDQS5zczAxC0lncmF2ZS5zczAxDHVuaTFFQzguc3MwMQx1bmkwMjBBLnNzMDEMSW1hY3Jvbi5zczAxDElvZ29uZWsuc3MwMQtJdGlsZGUuc3MwMQZKLnNzMDEQSmNpcmN1bWZsZXguc3MwMQx1bmkwMUM3LnNzMDEGTS5zczAxDHVuaTFFNDIuc3MwMQZOLnNzMDEMdW5pMDFDQS5zczAxC05hY3V0ZS5zczAxC05jYXJvbi5zczAxEU5jb21tYWFjY2VudC5zczAxDHVuaTFFNDQuc3MwMQx1bmkxRTQ2LnNzMDEIRW5nLnNzMDEMdW5pMDFDQi5zczAxDHVuaTFFNDguc3MwMQtOdGlsZGUuc3MwMQZRLnNzMDEMdW5pMDE4Ri5zczAxBlQuc3MwMQlUYmFyLnNzMDELVGNhcm9uLnNzMDEMdW5pMDE2Mi5zczAxDHVuaTAyMUEuc3MwMQx1bmkxRTZDLnNzMDEMdW5pMUU2RS5zczAxBlUuc3MwMQtVYWN1dGUuc3MwMQtVYnJldmUuc3MwMQx1bmkwMUQzLnNzMDEQVWNpcmN1bWZsZXguc3MwMQx1bmkwMjE0LnNzMDEOVWRpZXJlc2lzLnNzMDEMdW5pMUVFNC5zczAxC1VncmF2ZS5zczAxDHVuaTFFRTYuc3MwMQpVaG9ybi5zczAxDHVuaTFFRTguc3MwMQx1bmkxRUYwLnNzMDEMdW5pMUVFQS5zczAxDHVuaTFFRUMuc3MwMQx1bmkxRUVFLnNzMDESVWh1bmdhcnVtbGF1dC5zczAxDHVuaTAyMTYuc3MwMQxVbWFjcm9uLnNzMDEMdW5pMUU3QS5zczAxDFVvZ29uZWsuc3MwMQpVcmluZy5zczAxC1V0aWxkZS5zczAxDHVuaTFFNzguc3MwMQZXLnNzMDELV2FjdXRlLnNzMDEQV2NpcmN1bWZsZXguc3MwMQ5XZGllcmVzaXMuc3MwMQtXZ3JhdmUuc3MwMQZZLnNzMDELWWFjdXRlLnNzMDEQWWNpcmN1bWZsZXguc3MwMQ5ZZGllcmVzaXMuc3MwMQx1bmkxRThFLnNzMDEMdW5pMUVGNC5zczAxC1lncmF2ZS5zczAxDHVuaTFFRjYuc3MwMQx1bmkwMjMyLnNzMDEMdW5pMUVGOC5zczAxBlouc3MwMQtaYWN1dGUuc3MwMQtaY2Fyb24uc3MwMQ9aZG90YWNjZW50LnNzMDEMdW5pMUU5Mi5zczAxBmFicmV2ZQd1bmkxRUFGB3VuaTFFQjcHdW5pMUVCMQd1bmkxRUIzB3VuaTFFQjUHdW5pMDFDRQd1bmkxRUE1B3VuaTFFQUQHdW5pMUVBNwd1bmkxRUE5B3VuaTFFQUIHdW5pMDIwMQd1bmkxRUExB3VuaTFFQTMHdW5pMDIwMwdhbWFjcm9uB2FvZ29uZWsKYXJpbmdhY3V0ZQdhZWFjdXRlB3VuaTFFMDkLY2NpcmN1bWZsZXgKY2RvdGFjY2VudAZkY2Fyb24HdW5pMUUwRAd1bmkxRTBGB3VuaTAxQzYGZWJyZXZlBmVjYXJvbgd1bmkxRTFEB3VuaTFFQkYHdW5pMUVDNwd1bmkxRUMxB3VuaTFFQzMHdW5pMUVDNQd1bmkwMjA1CmVkb3RhY2NlbnQHdW5pMUVCOQd1bmkxRUJCB3VuaTAyMDcHZW1hY3Jvbgd1bmkxRTE3B3VuaTFFMTUHZW9nb25lawd1bmkxRUJEB3VuaTAyNTkHdW5pMDI5Mgd1bmkwMUVGBmdjYXJvbgtnY2lyY3VtZmxleAxnY29tbWFhY2NlbnQKZ2RvdGFjY2VudAd1bmkxRTIxB3VuaTAxRTUEaGJhcgd1bmkxRTJCB3VuaTAyMUYLaGNpcmN1bWZsZXgHdW5pMUUyNQZpYnJldmUHdW5pMDIwOQd1bmkxRTJGCWkubG9jbFRSSwd1bmkxRUNCB3VuaTFFQzkHdW5pMDIwQgJpagdpbWFjcm9uB2lvZ29uZWsGaXRpbGRlB3VuaTAyMzcLamNpcmN1bWZsZXgHdW5pMDFFOQxrY29tbWFhY2NlbnQMa2dyZWVubGFuZGljBmxhY3V0ZQZsY2Fyb24MbGNvbW1hYWNjZW50BGxkb3QHdW5pMUUzNwd1bmkwMUM5B3VuaTFFM0IHdW5pMUU0MwZuYWN1dGULbmFwb3N0cm9waGUGbmNhcm9uDG5jb21tYWFjY2VudAd1bmkxRTQ1B3VuaTFFNDcDZW5nB3VuaTAxQ0MHdW5pMUU0OQZvYnJldmUHdW5pMUVEMQd1bmkxRUQ5B3VuaTFFRDMHdW5pMUVENQd1bmkxRUQ3B3VuaTAyMEQHdW5pMDIyQgd1bmkwMjMxB3VuaTFFQ0QHdW5pMUVDRgVvaG9ybgd1bmkxRURCB3VuaTFFRTMHdW5pMUVERAd1bmkxRURGB3VuaTFFRTENb2h1bmdhcnVtbGF1dAd1bmkwMjBGB29tYWNyb24HdW5pMUU1Mwd1bmkxRTUxB3VuaTAxRUILb3NsYXNoYWN1dGUHdW5pMUU0RAd1bmkxRTRGB3VuaTAyMkQGcmFjdXRlBnJjYXJvbgxyY29tbWFhY2NlbnQHdW5pMDIxMQd1bmkxRTVCB3VuaTAyMTMHdW5pMUU1RgZzYWN1dGUHdW5pMUU2NQd1bmlBNzhDB3VuaTFFNjcLc2NpcmN1bWZsZXgMc2NvbW1hYWNjZW50B3VuaTFFNjEHdW5pMUU2Mwd1bmkxRTY5BWxvbmdzBHRiYXIGdGNhcm9uB3VuaTAxNjMHdW5pMDIxQgd1bmkxRTk3B3VuaTFFNkQHdW5pMUU2RgZ1YnJldmUHdW5pMDFENAd1bmkwMjE1B3VuaTFFRTUHdW5pMUVFNwV1aG9ybgd1bmkxRUU5B3VuaTFFRjEHdW5pMUVFQgd1bmkxRUVEB3VuaTFFRUYNdWh1bmdhcnVtbGF1dAd1bmkwMjE3B3VtYWNyb24HdW5pMUU3Qgd1b2dvbmVrBXVyaW5nBnV0aWxkZQd1bmkxRTc5BndhY3V0ZQt3Y2lyY3VtZmxleAl3ZGllcmVzaXMGd2dyYXZlC3ljaXJjdW1mbGV4B3VuaTFFOEYHdW5pMUVGNQZ5Z3JhdmUHdW5pMUVGNwd1bmkwMjMzB3VuaTFFRjkGemFjdXRlCnpkb3RhY2NlbnQHdW5pMUU5MxBpYWN1dGVfai5sb2NsTkxEBmEuc3MwMQthYWN1dGUuc3MwMQthYnJldmUuc3MwMQx1bmkxRUFGLnNzMDEMdW5pMUVCNy5zczAxDHVuaTFFQjEuc3MwMQx1bmkxRUIzLnNzMDEMdW5pMUVCNS5zczAxDHVuaTAxQ0Uuc3MwMRBhY2lyY3VtZmxleC5zczAxDHVuaTFFQTUuc3MwMQx1bmkxRUFELnNzMDEMdW5pMUVBNy5zczAxDHVuaTFFQTkuc3MwMQx1bmkxRUFCLnNzMDEMdW5pMDIwMS5zczAxDmFkaWVyZXNpcy5zczAxDHVuaTFFQTEuc3MwMQthZ3JhdmUuc3MwMQx1bmkxRUEzLnNzMDEMdW5pMDIwMy5zczAxDGFtYWNyb24uc3MwMQxhb2dvbmVrLnNzMDEKYXJpbmcuc3MwMQ9hcmluZ2FjdXRlLnNzMDELYXRpbGRlLnNzMDEHYWUuc3MwMQxhZWFjdXRlLnNzMDEMdW5pMDFDNi5zczAxBmUuc3MwMQtlYWN1dGUuc3MwMQtlYnJldmUuc3MwMQtlY2Fyb24uc3MwMQx1bmkxRTFELnNzMDEQZWNpcmN1bWZsZXguc3MwMQx1bmkxRUJGLnNzMDEMdW5pMUVDNy5zczAxDHVuaTFFQzEuc3MwMQx1bmkxRUMzLnNzMDEMdW5pMUVDNS5zczAxDHVuaTAyMDUuc3MwMQ5lZGllcmVzaXMuc3MwMQ9lZG90YWNjZW50LnNzMDEMdW5pMUVCOS5zczAxC2VncmF2ZS5zczAxDHVuaTFFQkIuc3MwMQx1bmkwMjA3LnNzMDEMZW1hY3Jvbi5zczAxDHVuaTFFMTcuc3MwMQx1bmkxRTE1LnNzMDEMZW9nb25lay5zczAxDHVuaTFFQkQuc3MwMQx1bmkwMjU5LnNzMDEGZi5zczAxBmwuc3MwMQtsYWN1dGUuc3MwMQtsY2Fyb24uc3MwMRFsY29tbWFhY2NlbnQuc3MwMQlsZG90LnNzMDEMdW5pMUUzNy5zczAxDHVuaTAxQzkuc3MwMQx1bmkxRTNCLnNzMDELbHNsYXNoLnNzMDEHb2Uuc3MwMQZ0LnNzMDEJdGJhci5zczAxC3RjYXJvbi5zczAxDHVuaTAxNjMuc3MwMQx1bmkwMjFCLnNzMDEMdW5pMUU5Ny5zczAxDHVuaTFFNkQuc3MwMQx1bmkxRTZGLnNzMDEGdy5zczAxC3dhY3V0ZS5zczAxEHdjaXJjdW1mbGV4LnNzMDEOd2RpZXJlc2lzLnNzMDELd2dyYXZlLnNzMDEGeS5zczAxC3lhY3V0ZS5zczAxEHljaXJjdW1mbGV4LnNzMDEOeWRpZXJlc2lzLnNzMDEMdW5pMUVGNS5zczAxC3lncmF2ZS5zczAxDHVuaTFFRjcuc3MwMQx1bmkwMjMzLnNzMDEMdW5pMUVGOS5zczAxBnouc3MwMQt6YWN1dGUuc3MwMQt6Y2Fyb24uc3MwMQ96ZG90YWNjZW50LnNzMDEMdW5pMUU5My5zczAxA1RfaAdmaS5zczAxB2ZsLnNzMDEEYS5zYwlhYWN1dGUuc2MJYWJyZXZlLnNjCnVuaTFFQUYuc2MKdW5pMUVCNy5zYwp1bmkxRUIxLnNjCnVuaTFFQjMuc2MKdW5pMUVCNS5zYwp1bmkwMUNFLnNjDmFjaXJjdW1mbGV4LnNjCnVuaTFFQTUuc2MKdW5pMUVBRC5zYwp1bmkxRUE3LnNjCnVuaTFFQTkuc2MKdW5pMUVBQi5zYwp1bmkwMjAxLnNjDGFkaWVyZXNpcy5zYwp1bmkxRUExLnNjCWFncmF2ZS5zYwp1bmkxRUEzLnNjCnVuaTAyMDMuc2MKYW1hY3Jvbi5zYwphb2dvbmVrLnNjCGFyaW5nLnNjDWFyaW5nYWN1dGUuc2MJYXRpbGRlLnNjBWFlLnNjCmFlYWN1dGUuc2MEYi5zYwRjLnNjCWNhY3V0ZS5zYwljY2Fyb24uc2MLY2NlZGlsbGEuc2MKdW5pMUUwOS5zYw5jY2lyY3VtZmxleC5zYw1jZG90YWNjZW50LnNjBGQuc2MGZXRoLnNjCWRjYXJvbi5zYwlkY3JvYXQuc2MKdW5pMUUwRC5zYwp1bmkxRTBGLnNjCnVuaTAxQzYuc2MEZS5zYwllYWN1dGUuc2MJZWJyZXZlLnNjCWVjYXJvbi5zYwp1bmkxRTFELnNjDmVjaXJjdW1mbGV4LnNjCnVuaTFFQkYuc2MKdW5pMUVDNy5zYwp1bmkxRUMxLnNjCnVuaTFFQzMuc2MKdW5pMUVDNS5zYwp1bmkwMjA1LnNjDGVkaWVyZXNpcy5zYw1lZG90YWNjZW50LnNjCnVuaTFFQjkuc2MJZWdyYXZlLnNjCnVuaTFFQkIuc2MKdW5pMDIwNy5zYwplbWFjcm9uLnNjCnVuaTFFMTcuc2MKdW5pMUUxNS5zYwplb2dvbmVrLnNjCnVuaTFFQkQuc2MKdW5pMDI1OS5zYwp1bmkwMjkyLnNjCnVuaTAxRUYuc2MEZi5zYwRnLnNjCWdicmV2ZS5zYwlnY2Fyb24uc2MOZ2NpcmN1bWZsZXguc2MPZ2NvbW1hYWNjZW50LnNjDWdkb3RhY2NlbnQuc2MKdW5pMUUyMS5zYwp1bmkwMUU1LnNjBGguc2MHaGJhci5zYwp1bmkxRTJCLnNjCnVuaTAyMUYuc2MOaGNpcmN1bWZsZXguc2MKdW5pMUUyNS5zYwRpLnNjC2RvdGxlc3NpLnNjCWlhY3V0ZS5zYxNpYWN1dGVfai5sb2NsTkxELnNjCWlicmV2ZS5zYw5pY2lyY3VtZmxleC5zYwp1bmkwMjA5LnNjDGlkaWVyZXNpcy5zYwp1bmkxRTJGLnNjDGkuc2MubG9jbFRSSwp1bmkxRUNCLnNjCWlncmF2ZS5zYwp1bmkxRUM5LnNjCnVuaTAyMEIuc2MFaWouc2MKaW1hY3Jvbi5zYwppb2dvbmVrLnNjCWl0aWxkZS5zYwRqLnNjDmpjaXJjdW1mbGV4LnNjBGsuc2MKdW5pMDFFOS5zYw9rY29tbWFhY2NlbnQuc2MPa2dyZWVubGFuZGljLnNjBGwuc2MJbGFjdXRlLnNjCWxjYXJvbi5zYw9sY29tbWFhY2NlbnQuc2MHbGRvdC5zYwp1bmkxRTM3LnNjCnVuaTAxQzkuc2MKdW5pMUUzQi5zYwlsc2xhc2guc2MEbS5zYwp1bmkxRTQzLnNjBG4uc2MJbmFjdXRlLnNjCW5jYXJvbi5zYw9uY29tbWFhY2NlbnQuc2MKdW5pMUU0NS5zYwp1bmkxRTQ3LnNjBmVuZy5zYwp1bmkwMUNDLnNjCnVuaTFFNDkuc2MJbnRpbGRlLnNjBG8uc2MJb2FjdXRlLnNjCW9icmV2ZS5zYw5vY2lyY3VtZmxleC5zYwp1bmkxRUQxLnNjCnVuaTFFRDkuc2MKdW5pMUVEMy5zYwp1bmkxRUQ1LnNjCnVuaTFFRDcuc2MKdW5pMDIwRC5zYwxvZGllcmVzaXMuc2MKdW5pMDIyQi5zYwp1bmkwMjMxLnNjCnVuaTFFQ0Quc2MJb2dyYXZlLnNjCnVuaTFFQ0Yuc2MIb2hvcm4uc2MKdW5pMUVEQi5zYwp1bmkxRUUzLnNjCnVuaTFFREQuc2MKdW5pMUVERi5zYwp1bmkxRUUxLnNjEG9odW5nYXJ1bWxhdXQuc2MKdW5pMDIwRi5zYwpvbWFjcm9uLnNjCnVuaTFFNTMuc2MKdW5pMUU1MS5zYwp1bmkwMUVCLnNjCW9zbGFzaC5zYw5vc2xhc2hhY3V0ZS5zYwlvdGlsZGUuc2MKdW5pMUU0RC5zYwp1bmkxRTRGLnNjCnVuaTAyMkQuc2MFb2Uuc2MEcC5zYwh0aG9ybi5zYwRxLnNjBHIuc2MJcmFjdXRlLnNjCXJjYXJvbi5zYw9yY29tbWFhY2NlbnQuc2MKdW5pMDIxMS5zYwp1bmkxRTVCLnNjCnVuaTAyMTMuc2MKdW5pMUU1Ri5zYwRzLnNjCXNhY3V0ZS5zYwp1bmkxRTY1LnNjCnVuaUE3OEMuc2MJc2Nhcm9uLnNjCnVuaTFFNjcuc2MLc2NlZGlsbGEuc2MOc2NpcmN1bWZsZXguc2MPc2NvbW1hYWNjZW50LnNjCnVuaTFFNjEuc2MKdW5pMUU2My5zYwp1bmkxRTY5LnNjDWdlcm1hbmRibHMuc2MEdC5zYwd0YmFyLnNjCXRjYXJvbi5zYwp1bmkwMTYzLnNjCnVuaTAyMUIuc2MKdW5pMUU5Ny5zYwp1bmkxRTZELnNjCnVuaTFFNkYuc2MEdS5zYwl1YWN1dGUuc2MJdWJyZXZlLnNjCnVuaTAxRDQuc2MOdWNpcmN1bWZsZXguc2MKdW5pMDIxNS5zYwx1ZGllcmVzaXMuc2MKdW5pMUVFNS5zYwl1Z3JhdmUuc2MKdW5pMUVFNy5zYwh1aG9ybi5zYwp1bmkxRUU5LnNjCnVuaTFFRjEuc2MKdW5pMUVFQi5zYwp1bmkxRUVELnNjCnVuaTFFRUYuc2MQdWh1bmdhcnVtbGF1dC5zYwp1bmkwMjE3LnNjCnVtYWNyb24uc2MKdW5pMUU3Qi5zYwp1b2dvbmVrLnNjCHVyaW5nLnNjCXV0aWxkZS5zYwp1bmkxRTc5LnNjBHYuc2MEdy5zYwl3YWN1dGUuc2MOd2NpcmN1bWZsZXguc2MMd2RpZXJlc2lzLnNjCXdncmF2ZS5zYwR4LnNjBHkuc2MJeWFjdXRlLnNjDnljaXJjdW1mbGV4LnNjDHlkaWVyZXNpcy5zYwp1bmkxRThGLnNjCnVuaTFFRjUuc2MJeWdyYXZlLnNjCnVuaTFFRjcuc2MKdW5pMDIzMy5zYwp1bmkxRUY5LnNjBHouc2MJemFjdXRlLnNjCXpjYXJvbi5zYw16ZG90YWNjZW50LnNjCnVuaTFFOTMuc2MJYS5zYy5zczAxDmFhY3V0ZS5zYy5zczAxDmFicmV2ZS5zYy5zczAxD3VuaTFFQUYuc2Muc3MwMQ91bmkxRUI3LnNjLnNzMDEPdW5pMUVCMS5zYy5zczAxD3VuaTFFQjMuc2Muc3MwMQ91bmkxRUI1LnNjLnNzMDEPdW5pMDFDRS5zYy5zczAxE2FjaXJjdW1mbGV4LnNjLnNzMDEPdW5pMUVBNS5zYy5zczAxD3VuaTFFQUQuc2Muc3MwMQ91bmkxRUE3LnNjLnNzMDEPdW5pMUVBOS5zYy5zczAxD3VuaTFFQUIuc2Muc3MwMQ91bmkwMjAxLnNjLnNzMDERYWRpZXJlc2lzLnNjLnNzMDEPdW5pMUVBMS5zYy5zczAxDmFncmF2ZS5zYy5zczAxD3VuaTFFQTMuc2Muc3MwMQ91bmkwMjAzLnNjLnNzMDEPYW1hY3Jvbi5zYy5zczAxD2FvZ29uZWsuc2Muc3MwMQ1hcmluZy5zYy5zczAxEmFyaW5nYWN1dGUuc2Muc3MwMQ5hdGlsZGUuc2Muc3MwMQphZS5zYy5zczAxD2FlYWN1dGUuc2Muc3MwMQ91bmkwMUM2LnNjLnNzMDEJZS5zYy5zczAxDmVhY3V0ZS5zYy5zczAxDmVicmV2ZS5zYy5zczAxDmVjYXJvbi5zYy5zczAxD3VuaTFFMUQuc2Muc3MwMRNlY2lyY3VtZmxleC5zYy5zczAxD3VuaTFFQkYuc2Muc3MwMQ91bmkxRUM3LnNjLnNzMDEPdW5pMUVDMS5zYy5zczAxD3VuaTFFQzMuc2Muc3MwMQ91bmkxRUM1LnNjLnNzMDEPdW5pMDIwNS5zYy5zczAxEWVkaWVyZXNpcy5zYy5zczAxEmVkb3RhY2NlbnQuc2Muc3MwMQ91bmkxRUI5LnNjLnNzMDEOZWdyYXZlLnNjLnNzMDEPdW5pMUVCQi5zYy5zczAxD3VuaTAyMDcuc2Muc3MwMQ9lbWFjcm9uLnNjLnNzMDEPdW5pMUUxNy5zYy5zczAxD3VuaTFFMTUuc2Muc3MwMQ9lb2dvbmVrLnNjLnNzMDEPdW5pMUVCRC5zYy5zczAxD3VuaTAyNTkuc2Muc3MwMQlmLnNjLnNzMDEJZy5zYy5zczAxDmdicmV2ZS5zYy5zczAxDmdjYXJvbi5zYy5zczAxE2djaXJjdW1mbGV4LnNjLnNzMDEUZ2NvbW1hYWNjZW50LnNjLnNzMDESZ2RvdGFjY2VudC5zYy5zczAxD3VuaTFFMjEuc2Muc3MwMQ91bmkwMUU1LnNjLnNzMDEJaS5zYy5zczAxEGRvdGxlc3NpLnNjLnNzMDEOaWFjdXRlLnNjLnNzMDEYaWFjdXRlX2oubG9jbE5MRC5zYy5zczAxDmlicmV2ZS5zYy5zczAxE2ljaXJjdW1mbGV4LnNjLnNzMDEPdW5pMDIwOS5zYy5zczAxEWlkaWVyZXNpcy5zYy5zczAxD3VuaTFFMkYuc2Muc3MwMQ91bmkxRUNCLnNjLnNzMDEOaWdyYXZlLnNjLnNzMDEPdW5pMUVDOS5zYy5zczAxD3VuaTAyMEIuc2Muc3MwMQppai5zYy5zczAxD2ltYWNyb24uc2Muc3MwMQ9pb2dvbmVrLnNjLnNzMDEOaXRpbGRlLnNjLnNzMDEJai5zYy5zczAxE2pjaXJjdW1mbGV4LnNjLnNzMDEPdW5pMDFDOS5zYy5zczAxCW0uc2Muc3MwMQ91bmkxRTQzLnNjLnNzMDEJbi5zYy5zczAxDm5hY3V0ZS5zYy5zczAxDm5jYXJvbi5zYy5zczAxFG5jb21tYWFjY2VudC5zYy5zczAxD3VuaTFFNDUuc2Muc3MwMQ91bmkxRTQ3LnNjLnNzMDELZW5nLnNjLnNzMDEPdW5pMDFDQy5zYy5zczAxD3VuaTFFNDkuc2Muc3MwMQ5udGlsZGUuc2Muc3MwMQlxLnNjLnNzMDEJdC5zYy5zczAxDHRiYXIuc2Muc3MwMQ50Y2Fyb24uc2Muc3MwMQ91bmkwMTYzLnNjLnNzMDEPdW5pMDIxQi5zYy5zczAxD3VuaTFFOTcuc2Muc3MwMQ91bmkxRTZELnNjLnNzMDEPdW5pMUU2Ri5zYy5zczAxCXUuc2Muc3MwMQ51YWN1dGUuc2Muc3MwMQ51YnJldmUuc2Muc3MwMQ91bmkwMUQ0LnNjLnNzMDETdWNpcmN1bWZsZXguc2Muc3MwMQ91bmkwMjE1LnNjLnNzMDERdWRpZXJlc2lzLnNjLnNzMDEPdW5pMUVFNS5zYy5zczAxDnVncmF2ZS5zYy5zczAxD3VuaTFFRTcuc2Muc3MwMQ11aG9ybi5zYy5zczAxD3VuaTFFRTkuc2Muc3MwMQ91bmkxRUYxLnNjLnNzMDEPdW5pMUVFQi5zYy5zczAxD3VuaTFFRUQuc2Muc3MwMQ91bmkxRUVGLnNjLnNzMDEVdWh1bmdhcnVtbGF1dC5zYy5zczAxD3VuaTAyMTcuc2Muc3MwMQ91bWFjcm9uLnNjLnNzMDEPdW5pMUU3Qi5zYy5zczAxD3VvZ29uZWsuc2Muc3MwMQ11cmluZy5zYy5zczAxDnV0aWxkZS5zYy5zczAxD3VuaTFFNzkuc2Muc3MwMQl3LnNjLnNzMDEOd2FjdXRlLnNjLnNzMDETd2NpcmN1bWZsZXguc2Muc3MwMRF3ZGllcmVzaXMuc2Muc3MwMQ53Z3JhdmUuc2Muc3MwMQl5LnNjLnNzMDEOeWFjdXRlLnNjLnNzMDETeWNpcmN1bWZsZXguc2Muc3MwMRF5ZGllcmVzaXMuc2Muc3MwMQ91bmkxRThGLnNjLnNzMDEPdW5pMUVGNS5zYy5zczAxDnlncmF2ZS5zYy5zczAxD3VuaTFFRjcuc2Muc3MwMQ91bmkwMjMzLnNjLnNzMDEPdW5pMUVGOS5zYy5zczAxCXouc2Muc3MwMQ56YWN1dGUuc2Muc3MwMQ56Y2Fyb24uc2Muc3MwMRJ6ZG90YWNjZW50LnNjLnNzMDEPdW5pMUU5My5zYy5zczAxB3VuaTA0MTAHdW5pMDQxMQd1bmkwNDEyB3VuaTA0MTMHdW5pMDQwMwd1bmkwNDkwB3VuaTA0MTQHdW5pMDQxNQd1bmkwNDAwB3VuaTA0MDEHdW5pMDQxNgd1bmkwNDE3B3VuaTA0MTgHdW5pMDQxOQd1bmkwNDBEB3VuaTA0OEEHdW5pMDQxQQd1bmkwNDBDB3VuaTA0MUIHdW5pMDQxQwd1bmkwNDFEB3VuaTA0MUUHdW5pMDQxRgd1bmkwNDIwB3VuaTA0MjEHdW5pMDQyMgd1bmkwNDIzB3VuaTA0MEUHdW5pMDQyNAd1bmkwNDI1B3VuaTA0MjcHdW5pMDQyNgd1bmkwNDI4B3VuaTA0MjkHdW5pMDQwRgd1bmkwNDJDB3VuaTA0MkEHdW5pMDQyQgd1bmkwNDA5B3VuaTA0MEEHdW5pMDQwNQd1bmkwNDA0B3VuaTA0MkQHdW5pMDQwNgd1bmkwNDA3B3VuaTA0MDgHdW5pMDQwQgd1bmkwNDJFB3VuaTA0MkYHdW5pMDQwMgd1bmkwNDYyB3VuaTA0NkEHdW5pMDQ3Mgd1bmkwNDc0B3VuaTA0OTIHdW5pMDQ5NAd1bmkwNDk2B3VuaTA0OTgHdW5pMDQ5QQd1bmkwNDlDB3VuaTA0OUUHdW5pMDRBMAd1bmkwNEEyB3VuaTA0QTQHdW5pMDRBNgd1bmkwNTI0B3VuaTA0QTgHdW5pMDRBQQd1bmkwNEFDB3VuaTA0QUUHdW5pMDRCMAd1bmkwNEIyB3VuaTA0QjQHdW5pMDRCNgd1bmkwNEI4B3VuaTA0QkEHdW5pMDUyNgd1bmkwNEJDB3VuaTA0QkUHdW5pMDRDMAd1bmkwNEMxB3VuaTA0QzMHdW5pMDRDNwd1bmkwNEM5B3VuaTA0Q0IHdW5pMDRDRAd1bmkwNEQwB3VuaTA0RDIHdW5pMDRENAd1bmkwNEQ2B3VuaTA0RDgHdW5pMDREQQd1bmkwNERDB3VuaTA0REUHdW5pMDRFMAd1bmkwNEUyB3VuaTA0RTQHdW5pMDRFNgd1bmkwNEU4B3VuaTA0RUEHdW5pMDRFQwd1bmkwNEVFB3VuaTA0RjAHdW5pMDRGMgd1bmkwNEY0B3VuaTA0RjYHdW5pMDRGOAd1bmkwNEZBB3VuaTA0RkMHdW5pMDRGRQd1bmkwNTEwB3VuaTA1MTIHdW5pMDUxQQd1bmkwNTFDB3VuaTA0OEMHdW5pMDQ4RQd1bmkwNTI4B3VuaTA1MkUPdW5pMDQxNC5sb2NsQkdSD3VuaTA0MUIubG9jbEJHUg91bmkwNDI0LmxvY2xCR1IPdW5pMDQ5Mi5sb2NsQlNID3VuaTA0OTgubG9jbEJTSA91bmkwNEFBLmxvY2xCU0gPdW5pMDRBQS5sb2NsQ0hVDHVuaTA0MTAuc3MwMQx1bmkwNDE0LnNzMDEMdW5pMDQxNS5zczAxDHVuaTA0MDAuc3MwMQx1bmkwNDAxLnNzMDEMdW5pMDQxOC5zczAxDHVuaTA0MTkuc3MwMQx1bmkwNDhBLnNzMDEMdW5pMDQwRC5zczAxDHVuaTA0MUIuc3MwMQx1bmkwNDIwLnNzMDEMdW5pMDQyMi5zczAxDHVuaTA0MjMuc3MwMQx1bmkwNDBFLnNzMDEMdW5pMDQyNC5zczAxDHVuaTA0MkMuc3MwMQx1bmkwNDJBLnNzMDEMdW5pMDQyQi5zczAxDHVuaTA0MDkuc3MwMQx1bmkwNDBBLnNzMDEMdW5pMDQwOC5zczAxDHVuaTA0NjIuc3MwMQx1bmkwNEFDLnNzMDEMdW5pMDREMC5zczAxDHVuaTA0RDIuc3MwMQx1bmkwNEQ0LnNzMDEMdW5pMDRENi5zczAxDHVuaTA0RTIuc3MwMQx1bmkwNEU0LnNzMDEMdW5pMDRFRS5zczAxDHVuaTA0RjAuc3MwMQx1bmkwNEYyLnNzMDEMdW5pMDRGOC5zczAxDHVuaTA1MUEuc3MwMQx1bmkwNDhDLnNzMDEHdW5pMDQzMAd1bmkwNDMxB3VuaTA0MzIHdW5pMDQzMwd1bmkwNDUzB3VuaTA0OTEHdW5pMDQzNAd1bmkwNDM1B3VuaTA0NTAHdW5pMDQ1MQd1bmkwNDM2B3VuaTA0MzcHdW5pMDQzOAd1bmkwNDM5B3VuaTA0NUQHdW5pMDQ4Qgd1bmkwNDNBB3VuaTA0NUMHdW5pMDQzQgd1bmkwNDNDB3VuaTA0M0QHdW5pMDQzRQd1bmkwNDNGB3VuaTA0NDAHdW5pMDQ0MQd1bmkwNDQyB3VuaTA0NDMHdW5pMDQ1RQd1bmkwNDQ0B3VuaTA0NDUHdW5pMDQ0Nwd1bmkwNDQ2B3VuaTA0NDgHdW5pMDQ0OQd1bmkwNDVGB3VuaTA0NEMHdW5pMDQ0QQd1bmkwNDRCB3VuaTA0NTkHdW5pMDQ1QQd1bmkwNDU1B3VuaTA0NTQHdW5pMDQ0RAd1bmkwNDU2B3VuaTA0NTcHdW5pMDQ1OAd1bmkwNDVCB3VuaTA0NEUHdW5pMDQ0Rgd1bmkwNDUyB3VuaTA0NjMHdW5pMDQ2Qgd1bmkwNDczB3VuaTA0NzUHdW5pMDQ5Mwd1bmkwNDk1B3VuaTA0OTcHdW5pMDQ5OQd1bmkwNDlCB3VuaTA0OUQHdW5pMDQ5Rgd1bmkwNEExB3VuaTA0QTMHdW5pMDRBNQd1bmkwNTI1B3VuaTA0QTcHdW5pMDRBOQd1bmkwNEFCB3VuaTA0QUQHdW5pMDRBRgd1bmkwNEIxB3VuaTA0QjMHdW5pMDRCNQd1bmkwNEI3B3VuaTA0QjkHdW5pMDRCQgd1bmkwNTI3B3VuaTA0QkQHdW5pMDRCRgd1bmkwNENGB3VuaTA0QzIHdW5pMDRDNAd1bmkwNEM2B3VuaTA0QzgHdW5pMDRDQQd1bmkwNENDB3VuaTA0Q0UHdW5pMDREMQd1bmkwNEQzB3VuaTA0RDUHdW5pMDRENwd1bmkwNEQ5B3VuaTA0REIHdW5pMDRERAd1bmkwNERGB3VuaTA0RTEHdW5pMDRFMwd1bmkwNEU1B3VuaTA0RTcHdW5pMDRFOQd1bmkwNEVCB3VuaTA0RUQHdW5pMDRFRgd1bmkwNEYxB3VuaTA0RjMHdW5pMDRGNQd1bmkwNEY3B3VuaTA0RjkHdW5pMDRGQgd1bmkwNEZEB3VuaTA0RkYHdW5pMDUxMQd1bmkwNTEzB3VuaTA1MUIHdW5pMDUxRAd1bmkwNDhEB3VuaTA0OEYHdW5pMDUyOQd1bmkwNTJGD3VuaTA0MzIubG9jbEJHUg91bmkwNDMzLmxvY2xCR1IPdW5pMDQzNC5sb2NsQkdSD3VuaTA0MzYubG9jbEJHUg91bmkwNDM3LmxvY2xCR1IPdW5pMDQzOC5sb2NsQkdSD3VuaTA0MzkubG9jbEJHUg91bmkwNDVELmxvY2xCR1IPdW5pMDQzQS5sb2NsQkdSD3VuaTA0M0IubG9jbEJHUg91bmkwNDNELmxvY2xCR1IPdW5pMDQzRi5sb2NsQkdSD3VuaTA0NDIubG9jbEJHUg91bmkwNDQ3LmxvY2xCR1IPdW5pMDQ0Ni5sb2NsQkdSD3VuaTA0NDgubG9jbEJHUg91bmkwNDQ5LmxvY2xCR1IPdW5pMDQ0Qy5sb2NsQkdSD3VuaTA0NEEubG9jbEJHUg91bmkwNDRFLmxvY2xCR1IPdW5pMDQ5My5sb2NsQlNID3VuaTA0OTkubG9jbEJTSA91bmkwNEFCLmxvY2xDSFUPdW5pMDQ1My5sb2NsTUtED3VuaTA0MzEubG9jbFNSQg91bmkwNDMzLmxvY2xTUkIPdW5pMDQzNC5sb2NsU1JCD3VuaTA0M0YubG9jbFNSQg91bmkwNDQyLmxvY2xTUkIMdW5pMDQzMC5zczAxDHVuaTA0MzQuc3MwMQx1bmkwNDM1LnNzMDEMdW5pMDQ1MC5zczAxDHVuaTA0NTEuc3MwMQx1bmkwNDM4LnNzMDEMdW5pMDQzOS5zczAxDHVuaTA0OEIuc3MwMQx1bmkwNDVELnNzMDEMdW5pMDQ0MC5zczAxDHVuaTA0NDIuc3MwMQx1bmkwNDQzLnNzMDEMdW5pMDQ1RS5zczAxDHVuaTA0NEMuc3MwMQx1bmkwNDRBLnNzMDEMdW5pMDQ0Qi5zczAxDHVuaTA0NTkuc3MwMQx1bmkwNDVBLnNzMDEMdW5pMDQ2My5zczAxDHVuaTA0RDEuc3MwMQx1bmkwNEQzLnNzMDEMdW5pMDRENS5zczAxDHVuaTA0RDcuc3MwMQx1bmkwNEQ5LnNzMDEMdW5pMDREQi5zczAxDHVuaTA0RTMuc3MwMQx1bmkwNEU1LnNzMDEMdW5pMDRFRi5zczAxDHVuaTA0RjEuc3MwMQx1bmkwNEYzLnNzMDEMdW5pMDRGOS5zczAxDHVuaTA0OEQuc3MwMQd1bmkwMzk0B3VuaTAzQTkHdW5pMDNCQwd1bmkyMTJCB3VuaTIxMkEIemVyby5vc2YHb25lLm9zZgd0d28ub3NmCXRocmVlLm9zZghmb3VyLm9zZghmaXZlLm9zZgdzaXgub3NmCXNldmVuLm9zZgllaWdodC5vc2YIbmluZS5vc2YJemVyby5zaW5mCG9uZS5zaW5mCHR3by5zaW5mCnRocmVlLnNpbmYJZm91ci5zaW5mCWZpdmUuc2luZghzaXguc2luZgpzZXZlbi5zaW5mCmVpZ2h0LnNpbmYJbmluZS5zaW5mB3plcm8udGYGb25lLnRmBnR3by50Zgh0aHJlZS50Zgdmb3VyLnRmB2ZpdmUudGYGc2l4LnRmCHNldmVuLnRmCGVpZ2h0LnRmB25pbmUudGYJemVyby50b3NmCG9uZS50b3NmCHR3by50b3NmCnRocmVlLnRvc2YJZm91ci50b3NmCWZpdmUudG9zZghzaXgudG9zZgpzZXZlbi50b3NmCmVpZ2h0LnRvc2YJbmluZS50b3NmB3VuaTIwODAHdW5pMjA4MQd1bmkyMDgyB3VuaTIwODMHdW5pMjA4NAd1bmkyMDg1B3VuaTIwODYHdW5pMjA4Nwd1bmkyMDg4B3VuaTIwODkJemVyby5kbm9tCG9uZS5kbm9tCHR3by5kbm9tCnRocmVlLmRub20JZm91ci5kbm9tCWZpdmUuZG5vbQhzaXguZG5vbQpzZXZlbi5kbm9tCmVpZ2h0LmRub20JbmluZS5kbm9tCXplcm8ubnVtcghvbmUubnVtcgh0d28ubnVtcgp0aHJlZS5udW1yCWZvdXIubnVtcglmaXZlLm51bXIIc2l4Lm51bXIKc2V2ZW4ubnVtcgplaWdodC5udW1yCW5pbmUubnVtcgd1bmkyMDcwB3VuaTAwQjkHdW5pMDBCMgd1bmkwMEIzB3VuaTIwNzQHdW5pMjA3NQd1bmkyMDc2B3VuaTIwNzcHdW5pMjA3OAd1bmkyMDc5B3VuaTIxNTMHdW5pMjE1NAlvbmVlaWdodGgMdGhyZWVlaWdodGhzC2ZpdmVlaWdodGhzDHNldmVuZWlnaHRocw5iYWNrc2xhc2guY2FzZRNwZXJpb2RjZW50ZXJlZC5jYXNlC2J1bGxldC5jYXNlG3BlcmlvZGNlbnRlcmVkLmxvY2xDQVQuY2FzZQpzbGFzaC5jYXNlFnBlcmlvZGNlbnRlcmVkLmxvY2xDQVQOYnJhY2VsZWZ0LmNhc2UPYnJhY2VyaWdodC5jYXNlEGJyYWNrZXRsZWZ0LmNhc2URYnJhY2tldHJpZ2h0LmNhc2UOcGFyZW5sZWZ0LmNhc2UPcGFyZW5yaWdodC5jYXNlCmZpZ3VyZWRhc2gHdW5pMjAxNQd1bmkyMDEwB3VuaTAwQUQLZW1kYXNoLmNhc2ULZW5kYXNoLmNhc2ULaHlwaGVuLmNhc2USZ3VpbGxlbW90bGVmdC5jYXNlE2d1aWxsZW1vdHJpZ2h0LmNhc2USZ3VpbHNpbmdsbGVmdC5jYXNlE2d1aWxzaW5nbHJpZ2h0LmNhc2UJZXhjbGFtLnNjDWV4Y2xhbWRvd24uc2MQZ3VpbGxlbW90bGVmdC5zYxFndWlsbGVtb3RyaWdodC5zYxBndWlsc2luZ2xsZWZ0LnNjEWd1aWxzaW5nbHJpZ2h0LnNjCXBlcmlvZC5zYwtxdWVzdGlvbi5zYw9xdWVzdGlvbmRvd24uc2MLcXVvdGVkYmwuc2MPcXVvdGVkYmxiYXNlLnNjD3F1b3RlZGJsbGVmdC5zYxBxdW90ZWRibHJpZ2h0LnNjDHF1b3RlbGVmdC5zYw1xdW90ZXJpZ2h0LnNjEXF1b3Rlc2luZ2xiYXNlLnNjDnF1b3Rlc2luZ2xlLnNjB3VuaTI3RTgHdW5pMjdFOQd1bmkyMDA3B3VuaTIwMEEHdW5pMjAwOAd1bmkwMEEwB3VuaTIwMDkHdW5pMjAwQgd1bmkyMEI1DWNvbG9ubW9uZXRhcnkEZG9uZwRFdXJvB3VuaTIwQjIHdW5pMjBCNAd1bmkyMEFEBGxpcmEHdW5pMjBCQQd1bmkyMEJDB3VuaTIwQTYGcGVzZXRhB3VuaTIwQjEHdW5pMjBCRAd1bmkyMEI5B3VuaTIwQjgHdW5pMjBBRQd1bmkyMEE5B3VuaTIyMTkHdW5pMjA1Mgd1bmkyMjE1CGVtcHR5c2V0B3VuaTIxMjYHdW5pMjIwNgd1bmkwMEI1B2Fycm93dXAHdW5pMjE5NwphcnJvd3JpZ2h0B3VuaTIxOTgJYXJyb3dkb3duB3VuaTIxOTkJYXJyb3dsZWZ0B3VuaTIxOTYJYXJyb3dib3RoCWFycm93dXBkbgxhcnJvd3VwLmNhc2UPYXJyb3dyaWdodC5jYXNlDmFycm93ZG93bi5jYXNlDmFycm93bGVmdC5jYXNlB3VuaTI1QzYHdW5pMjVDNwlmaWxsZWRib3gHdW5pMjVBMQd0cmlhZ3VwB3VuaTI1QjYHdHJpYWdkbgd1bmkyNUMwB3VuaTI1QjMHdW5pMjVCNwd1bmkyNUJEB3VuaTI1QzEHdW5pMjExMwllc3RpbWF0ZWQHdW5pMjExNgZtaW51dGUGc2Vjb25kB2F0LmNhc2UMdW5pMjExNi5zczAxDGFtcGVyc2FuZC5zYwd1bmkwMzA4C3VuaTAzMDgwMzAwC3VuaTAzMDgwMzAxC3VuaTAzMDgwMzA0B3VuaTAzMDcLdW5pMDMwNzAzMDQJZ3JhdmVjb21iC3VuaTAzMDAwMzA0CWFjdXRlY29tYgt1bmkwMzAxMDMwNwt1bmkwMzAxMDMwNAd1bmkwMzBCDWNhcm9uY29tYi5hbHQHdW5pMDMwMgd1bmkwMzBDC3VuaTAzMEMwMzA3B3VuaTAzMDYHdW5pMDMwQQt1bmkwMzBBMDMwMQl0aWxkZWNvbWILdW5pMDMwMzAzMDgTdGlsZGVjb21iX2FjdXRlY29tYgt1bmkwMzAzMDMwNAd1bmkwMzA0C3VuaTAzMDQwMzA4C3VuaTAzMDQwMzAwC3VuaTAzMDQwMzAxDWhvb2thYm92ZWNvbWIHdW5pMDMwRgd1bmkwMzExB3VuaTAzMTIHdW5pMDMxQgxkb3RiZWxvd2NvbWIHdW5pMDMyNAd1bmkwMzI2B3VuaTAzMjcHdW5pMDMyOAd1bmkwMzJFB3VuaTAzMzEHdW5pMDMzNQd1bmkwMzM2B3VuaTAzMzcHdW5pMDMzOAx1bmkwMzA4LmNhc2UQdW5pMDMwODAzMDAuY2FzZRB1bmkwMzA4MDMwMS5jYXNlEHVuaTAzMDgwMzA0LmNhc2UMdW5pMDMwNy5jYXNlEHVuaTAzMDcwMzA0LmNhc2UOZ3JhdmVjb21iLmNhc2UQdW5pMDMwMDAzMDQuY2FzZQ5hY3V0ZWNvbWIuY2FzZRB1bmkwMzAxMDMwNy5jYXNlEHVuaTAzMDEwMzA0LmNhc2UMdW5pMDMwQi5jYXNlDHVuaTAzMDIuY2FzZQx1bmkwMzBDLmNhc2UQdW5pMDMwQzAzMDcuY2FzZQx1bmkwMzA2LmNhc2UOdGlsZGVjb21iLmNhc2UQdW5pMDMwMzAzMDguY2FzZRh0aWxkZWNvbWJfYWN1dGVjb21iLmNhc2UQdW5pMDMwMzAzMDQuY2FzZQx1bmkwMzA0LmNhc2UQdW5pMDMwNDAzMDguY2FzZRB1bmkwMzA0MDMwMC5jYXNlEHVuaTAzMDQwMzAxLmNhc2USaG9va2Fib3ZlY29tYi5jYXNlDHVuaTAzMEYuY2FzZQx1bmkwMzExLmNhc2UMdW5pMDMzNS5jYXNlDHVuaTAzMzcuY2FzZQx1bmkwMzM4LmNhc2UTdW5pMDMwNC5uYXJyb3cuY2FzZQl1bmkwMzA3LmkJdW5pMDMyOC5pEHVuaTAzMDgubG9jbFZJRVQQdW5pMDMwNy5sb2NsVklFVBJncmF2ZWNvbWIubG9jbFZJRVQSYWN1dGVjb21iLmxvY2xWSUVUEHVuaTAzMDIubG9jbFZJRVQQdW5pMDMwQy5sb2NsVklFVBB1bmkwMzA2LmxvY2xWSUVUEnRpbGRlY29tYi5sb2NsVklFVBB1bmkwMzA0LmxvY2xWSUVUFmhvb2thYm92ZWNvbWIubG9jbFZJRVQOdW5pMDMwOC5uYXJyb3cOdW5pMDMwMi5uYXJyb3cOdW5pMDMwNi5uYXJyb3cQdGlsZGVjb21iLm5hcnJvdw51bmkwMzA0Lm5hcnJvdw51bmkwMzExLm5hcnJvdxNjYXJvbmNvbWIuYWx0LnNob3J0CXVuaTAzMzUudAd1bmkwMkJDB3VuaTAyQkIHdW5pMDJCQQd1bmkwMkM5B3VuaTAyQ0IHdW5pMDJCOQd1bmkwMkJGB3VuaTAyQkUHdW5pMDJDQQd1bmkwMkNDB3VuaTAyQzgKdW5pMDMzNS5zYwp1bmkwMzM2LnNjCnVuaTAzMzguc2MLYnJldmVjb21iY3kQYnJldmVjb21iY3kuY2FzZQtkZXNjZW5kZXJjeRBkZXNjZW5kZXJjeS5jYXNlFmRlc2NlbmRlcmN5LmNhc2Uuc2hvcnQRZGVzY2VuZGVyY3kuc2hvcnQLdW5pMDMwNjAzMDELdW5pMDMwNjAzMDALdW5pMDMwNjAzMDkLdW5pMDMwNjAzMDMLdW5pMDMwMjAzMDELdW5pMDMwMjAzMDALdW5pMDMwMjAzMDkLdW5pMDMwMjAzMDMQdW5pMDMwNjAzMDEuY2FzZRB1bmkwMzA2MDMwMC5jYXNlEHVuaTAzMDYwMzA5LmNhc2UQdW5pMDMwNjAzMDMuY2FzZRB1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AAMAAAAAAAMAAwADAAMACAADAAAAAAAAAAAAGwAAAAD/9gAAAAAACAAAAAAAAAAA/+wAAAAAAAAAAAAAAAAAAAAAAAAAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/+QAAAAAAAAAAAAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/2AAAAAAAHAAAAAP/2AAD/9AAAAAAAAAAAAAAAAAAAAAAAAAAA/8cAAAAAAAAAAAAAAAAAAAAHAAAABwAAAAAAAAAAAAD//QAAAAAAAAAAAAP/9gAIAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkAAP/2AAAAAAAKAAoAAAAA//YAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/7QAAAAAAAwAAAAoAAAAKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//bAAoAAAAAAAMAAwADAAMAAwADAAAAAAAAAAAAEwAAAAD/9gAAAAAAAAAAAAD/9gAA/+wAAAAAAAAAAAAAAAAAAAAAAAAAAP+/AAAAAAAAAAAAAAAAAAAAAAAAAAcAAP/2//YAAAAN/+7/qQAAAAD/2//5/9j/3gAA//kAAAADAAAAAwAAAAMAAAAK//YACAAA/+z/9v/s//P//QAAAAcAAAADAAD/6QAAAAf/9gAHAAAAAAAAAAAAAAAA/9YAAAAAAAAAAAAAAAAAAAAAAAcAAP/2AAAAAAAAAAD/8QAAAAAAAAAA//H/2AAA/+b/9AAAAAAAAAAAAAAAAAAAAAD//QAAAAD/5wAAAAD/4gAAAAAAAAAAAAAAAAAAAAAAAP/5AAcAAAAAAAAAAAAAAAAAJgAIAAgAAAAAAAAAAAAAAAAAAP/s/+8AAAAAAAAAAAAKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIQAAAAAAHAAAAAAAAwAAAAAAAAAAAA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAsAAAAAAAAAAAAAAADAAAAAAAA/+//9wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAmAAAAAAAAAAAAAAAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/58AAAAAAAD/wQADAAMAAwAA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BiUADAYmBicANQYoBigAMQYpBioAEAYrBisAQQYsBiwAQgYuBi4AEAYvBi8AEQYwBjAAEgYxBjIAFAYzBjMAMQY0BjQAKwY1BjUALQY2BjYADAY3BjgAUQY6BjoAKwY9Bj0ATQY/Bj8ATQZDBkMATgZFBkUATgZHBkcAUwZMBk4ANQZRBlEAUQZSBlIANQZTBlMARQZUBlQANQZVBlUARQZWBlYAEAZXBlcAEwZYBlgAOwZZBlkAEwZaBloAOwZbBlsAEAZcBlwAUQZdBl0AUAZeBl4AUQZfBl8AUAZiBmIANQZkBmQANQZmBmYAEAZqBmoAEAZvBm8AEAZ5BnkAJQZ6BnoAOAZ7BnsAJQZ8BnwAMgZ9Bn0AJgZ+Bn4AOAZ/Bn8AMgaABoAAKAaBBoEAMgaCBoIAJQaEBoQAMgaFBoUANgaGBoYAMgaIBogAMgaKBosAMgaMBowAFQaNBo0ANgaQBpAAMgaRBpEAGwaUBpQAKwaVBpYANQaYBpgANQahBqIANQanBqcAAQaqBqoANQarBqsAUgatBq4ADwbKBsoAJQbLBssAMAbMBswAOgbNBs0AFgbOBs8AJQbQBtAAPQbRBtEAHgbXBtcAJQbaBtsAFAbcBtwAJQc+Bz4AEwACAAgACgAaBJgFCjDQQfBOrlTMbU6FfI8WAAEAsgAEAAAAVAQKAV4BaAGGAYYBhgGGAYYBhgGGAbQBtAG0AbQBtAG0Af4B/gH+Af4B/gH+Af4B/gH+Af4ENAIoAigCKAIoAigCKAIoA44ClgJCA6oCjAJQAmICcAJ+AowClgKgAs4C3AOOA5wDqgPcBF4EXgReBFgEWAPuBE4D9AROA/4D/gQEBFgEWARYBFgEWARwBHAEWARYBAoENAQ0BE4EWARYBFgEWAReBF4EcAABAFQASQCUAKkAwADBAMIAwwDEAMUAxgDfAOAA4QDiAOMA5ADmAOcA6ADpAOoA6wDsAO0A7gDvASsBVwFYAVkBWgFbAVwBXQGgAbABygHPAd4B4gHjAeoB7QHvAfgB/gIxAkoCTAJkArQDhQRkBGUGJAYmBicGMAY0BjUGOgY8Bj4GQAZMBk0GTgZTBlUGVwZZBmMGZQaBBoUGjQaUBpUGlgaYBqEG2AbdBz4AAgYlAAYGNgAGAAcGNAApBjUAKAY6ACkGPQAIBj8ACAZHAAMGlAApAAsB4QAZ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//YAAAAAAAAAAAAAAAAAAAAAAAD/7wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAAAAAAoAAAAA//YAAAAAAAAAAAAAAAAAAAAA//YAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/s//cAAAAAAAAAAAAAAAD/+QAAAAAAAAAAAAD/9QAA//cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//kAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//0AAP/2AAAAAAAAAAAAAAAA//sAAAAA//0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//kAAAAAAAAAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/j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ACMCmQKaAE0CmwKzACMCtAK9AG8CvgK+ACMCvwLGAG8CxwLUADoC1QLZAEMC2gLaAAYC2wLcADMC3gLeADMC3wL6AE4C+wL7AFUC/AMCACQDAwMgAFUDIQMhACQDJAMkAFUDJQMsACQDLQNEAFUDRQNGAB8DRwNfAFUDYAOCACQDgwOEAFUDhQOFACQDhgONAFUDjgOQAFcDkgOZAFcDmwOiADQDowO6ADsDuwPAAD4DwQPBAEADwgPLAEEDzAPQAFoD0QPqAE8D7QPtAFUD7gQEABQEBQQFACQEBgQGAFIEBwQOACQEDwQRAFsEEgQSAFUEEwQbAFsEHAQcAFUEHQQfAFsEIAQhACAEIgQuAFUELwQvACQEMAQ3ADQEOARUADsEVQReAEIEXwRjAFoEZARlAA0EZgRmAEYEZwRrAGsEbARsAEcEbQRvAGsEcARwAAoEcQRxAEsEcgR3AGsEeAR4AEcEeQR6AGsEewR7AAUEfAR9AGsEfgR+AAUEfwR/AAYEgASBAAoEggSCAAUEgwSDAAoEhASEAAEEhQSJAGsEigSKAAYEiwSLAGsEjASMAEcEjQSNAGsEjgSOAEwEjwSPAAUEkASQAEsEkQSSAGsEkwSTAAMElASUAAYElQSVAGsElgSWAAoElwSYAAYEmQSZAAoEmgSaAAUEmwSbAAkEnQSdAGsEngSeAAoEnwSfAEsEoASiAGsEowSjAAYEpASnAGsEqASpAAUEqgSqAAYEqwSsAAsErQStAAoErgSuAAYErwSwAAEEsQSyAGsEswS0AAIEtQS1AGsEtgS2AAoEtwS5AGsEugS6AAEEuwS7AGsEvAS+AEYEvwS/AGsEwATBAAUEwgTCAAoEwwTEAEsExQTGAGsExwTJAAUEygTKAEsEywTNAAoEzgTOAAEEzwTRAGsE0gTTAAoE1ATUAEoE1QTVAEcE1gTWAAUE1wTXAAkE2ATaAGsE2wTcAEcE3QTdAEYE3gTeAAUE3wTfAGsE4QTiAAUE4wTjAFwE5ATkAF4E5QTnAEoE6ATrAGsE7ATsAEkE7QTtAFwE7gTuAAcE7wTwAAwE8QTxAAUE8gTyAAgE8wTzAAYE9AT0AAgE9QT1AEcE9gT2AGsE9wT3AAQE+QT5AAcE+gT7AFwE/AT8AEYE/QT9AEoE/gT/AGsFAAUCAAwFBAUEAAUFBQUFAAgFBgUGAE0FBwUHAAUFCAULAGUFDAUMAEgFDQUPACMFEAUQAD8FEQURAFEFEgUXAGUFGAUYAEgFGQUaAGUFGwUbACMFHAUdAGUFHgUeACMFHwUfADUFIAUhAD0FIgUiACMFIwUjAD8FJAUkADoFJQUpAGUFKgUqADUFKwUrAGUFLAUsAEgFLQUtAGUFLgUuAC4FLwUvACMFMAUwAFEFMQUyAGUFMwUzAGQFNAU0AG0FNQU1AGUFNgU2AD8FNwU3AG8FOAU4ADUFOQU5AD8FOgU6ACMFOwU7AD0FPAU8ABkFPQU9AGUFPgU+AD8FPwU/AFEFQAVBAGUFQgVCAG8FQwVDADUFRAVHAGUFSAVJACMFSgVKADUFSwVMAD0FTQVNAD8FTgVOADUFTwVQADoFUQVSAG8FUwVUABEFVQVVAG8FVgVWAD8FVwVXAGUFWAVYAEgFWQVaAGUFWwVbADoFXAVcAGUFXQVfAE0FYAViACMFYwVjAD8FZAVlAFEFZgVnAGUFaAVqACMFawVrAFEFbAVuAD0FbwVvADoFcAVyAGUFcwV0AD8FdQV1AFYFdgV2AEgFdwV3ACMFeAV4AD0FeQV5AC8FegV6AGUFewV7AGQFfAV8AEgFfQV9ACMFfgV+AC4FfwV/ACMFgAWAAD8FgQWBAFEFggWEADoFhQWFAG8FhgWGAEgFhwWJAGUFigWOADoFjwWPADUFkAWQAG8FkQWRAGUFkgWSAFEFkwWTACMFlAWUAGUFlQWVAA8FlgWWAGUFlwWXACMFmAWZADoFmgWeACMFnwWiADoFowWjAG4FpQWnADoFqAWoABwFqQWpADoFqgWqAEgFqwWrAGUFrQWuACMFrwWvAE0FsAWxACMFswW4ADoFuQW5AC8FugW6AEYFvgW+AEYFvwW/AGsFwAXAAEQFwQXBACUFwgXCAFkFwwXDADYFxAXEABcFxQXFAFMFxgXGAEQFxwXHADAFyAXIABUFyQXJACEFygXKAEUFywXLACYFzAXMADkFzQXNADcFzgXOABgFzwXPAFQF0AXQAEQF0QXRADEF0gXSABUF0wXTACIGJAYkAA0GJQYlAA4GJgYnAB0GKAYoABIGKQYqACgGKwYrAGAGLAYsABYGLgYuACgGLwYvACkGMAYwACoGMQYyAC0GMwYzABIGNAY0ADIGNQY1ADwGNgY2AA4GNwY4AB4GOgY6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BSMAEwUkBSQAQAUlBSkAPwUrBSsAPwUtBS0APwUuBS4AGwUvBS8AGQUxBTIAPwUzBTMAPQU1BTUAPwU2BTYAEwU3BTcAPgU5BTkAEwU6BToAGQU7BTsAEQU9BT0APwU+BT4AEwVABUEAPwVCBUIAPgVEBUcAPwVIBUkAGQVLBUwAEQVNBU0AEwVPBVAAQAVRBVIAPgVVBVUAPgVWBVYAEwVXBVcAPwVZBVoAPwVbBVsAQAVcBVwAPwVdBV8ACgVgBWIAGQVjBWMAEwVmBWcAPwVoBWoAGQVsBW4AEQVvBW8AQAVwBXIAPwVzBXQAEwV3BXcAGQV4BXgAEQV6BXoAPwV7BXsAPQV9BX0AGQV+BX4AGwV/BX8AGQWABYAAEwWCBYQAQAWFBYUAPgWHBYkAPwWKBY4AQAWQBZAAPgWRBZEAPwWTBZMAGQWUBZQAPwWWBZYAPwWXBZcAGQWYBZkAQAWaBZ4AGQWfBaIAQAWlBacAQAWpBakAQAWrBasAPwWtBa4AGQWvBa8ACgWwBbEAGQWzBbgAQAW6BboAAQW+Bb4AAQXBBcEAKwXCBcIAOQXDBcMAOAXEBcQAJwXHBccANQXKBcoAPAXLBcsALAXMBcwAOgXOBc4AKAXPBc8AJgXRBdEANgYkBiQADAYlBiUAHwYmBicAKgYoBigAIgYpBioALwYrBisAIwYuBi4ALwYvBi8AMAYwBjAAMQYxBjIANAYzBjMAIgY0BjQANwY1BjUAOwY2BjYAHwY6BjoANwY9Bj0AIAY/Bj8AIAZBBkEALQZDBkMAIQZFBkUAIQZHBkcALgZMBk4AKgZSBlIAKgZUBlQAKgZWBlYALwZYBlgAMwZaBloAMwZbBlsALwZgBmAAJAZhBmEAJQZiBmIAKgZjBmMAKQZkBmQAKgZlBmUAKQZmBmYALwZoBmgAMgZqBmoALwZvBm8ALwZ5BnkAFQZ6BnoAGQZ7BnsAFQZ9Bn0AFgZ+Bn4AGQaCBoIAFQaUBpQANwaVBpYAKgaYBpgAKgahBqIAKganBqcAAQaqBqoAKgarBqsAPwbKBsoAFQbOBs8AFQbXBtcAFQbaBtsANAbcBtwAFQACAJ4ABAAAAKwAsAABAEcAAP+j//n/9AAKAB4AKAAh//YAFAAK/6j/9v/2ABQAAwAHAB4ABwAUABH/7P/5//P/2QARAA0AEf/2//0AUAAg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AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9AAA//D/8AAAAAD/7f/3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/8f/q//f/9AAA/+0AAP/s//P/9//w//cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKACUABwAA//b/9gAA/+n/+f/bAAAAAAAAAAAAHgAAAAAAFAAAAAcAAP/9//kAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwAAAAAACP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABf/9AAAABQAFAAAAAoAAAAUAAoABwAAAAAADf/2AAAAFAAAAAAAAwAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAACP/2AAAACAAAAAAAAwAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKAAoAFAAA/+z/7AAA/+L/9v/YAAoAAABkAEQAFAAKAAAACAAAAAD/9gAA//YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAEQAAAAAACAADAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/zAAD/6QAA//T/7wAA/9//1v/WAAAAEf/0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA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ABIFhQWFAAQFhwWJAAgFkAWQAAkFkgWSABIFlAWUAAsFlQWVAAkFnAWeAAEFowWjAAkFrwWwAAEFsQWxAAkGiQaJAAwAAgFrAAQAHwBMACAAIABNACEAJwAwACgARgBNAEcASABIAEkASQBNAEoAUQAwAFIAZwBNAGoAgwBNAIQApgAwAKcAqABNAKkAqQAwAKoAsQBNALIAtABOALYAvQBOAL8AvwAwAMAAxgACAMcA3gAxAN8A5AAyAOUA5QA2AOYA7wAzAPUA9QBNAPYBDwABARABEQBMARIBEwBNASsBKwABASwBMwAwATUBNQBNAUUBRgBJAUcBSABNAUoBVABNAVUBVgAwAVcBXQBKAV4BegAxAYoBpQA3AaYBpgATAacBzAAWAc4BzgAPAdAB1wAWAdgB3QATAd4B7gBCAe8B8QBBAfIB9AATAfUB9QBCAfYB/gATAf8CCwBCAgwCLgAWAi8CLwBCAjACMAATAjECMQAWAjICOQBCAjoCPABFAj4CRQBFAkYCRgATAkgCTwAjAlACZwBGAmgCbQApAm4CbgAqAm8CeAApAnkCfQArAn8CmAAWApkCmgA3ApsCswAWArQCvQATAr4CvgAWAr8CxgATAscC1ABGAtUC2QArAtoC2gACAtsC3AAjAt4C3gAjBGQEZQAEBGYEZgBMBGcEawBNBGwEbAA1BG0EbwBNBHAEcAA2BHEEcQBIBHIEdwBNBHgEeAA1BHkEegBNBHsEewAwBHwEfQBNBH4EfgAwBH8EfwACBIAEgQA2BIIEggAwBIMEgwA2BIQEhAAuBIUEiQBNBIoEigACBIsEiwBNBIwEjAA1BI0EjQBNBI4EjgBOBI8EjwAwBJAEkABIBJEEkgBNBJQElAACBJUElQBNBJYElgA2BJcEmAACBJkEmQA2BJoEmgAwBJsEmwAyBJ0EnQBNBJ4EngA2BJ8EnwBIBKAEogBNBKMEowACBKQEpwBNBKgEqQAwBKoEqgACBKsErAAzBK0ErQA2BK4ErgACBK8EsAAuBLEEsgBNBLMEtAAvBLUEtQBNBLYEtgA2BLcEuQBNBLoEugAuBLsEuwBNBLwEvgBMBL8EvwBNBMAEwQAwBMIEwgA2BMMExABIBMUExgBNBMcEyQAwBMoEygBIBMsEzQA2BM4EzgAuBM8E0QBNBNIE0wA2BNUE1QA1BNYE1gAwBNcE1wAyBNgE2gBNBNsE3AA1BN0E3QBMBN4E3gAwBN8E3wBNBOEE4gAwBOME4wABBOQE5ABHBOgE6wBNBO0E7QABBO4E7gBKBPEE8QAwBPIE8gAxBPME8wACBPQE9AAxBPUE9QA1BPYE9gBNBPcE9wBJBPkE+QBKBPoE+wABBPwE/ABMBP4E/wBNBQQFBAAwBQUFBQAxBQYFBgA3BQcFBwAwBQgFCwBCBQwFDAAOBQ0FDwAWBRAFEAAqBREFEQAPBRIFFwBCBRgFGAAOBRkFGgBCBRsFGwAWBRwFHQBCBR4FHgAWBR8FHwAkBSAFIQApBSIFIgAWBSMFIwAqBSQFJABGBSUFKQBCBSoFKgAkBSsFKwBCBSwFLAAOBS0FLQBCBS4FLgBFBS8FLwAWBTAFMAAPBTEFMgBCBTMFMwBBBTUFNQBCBTYFNgAqBTcFNwATBTgFOAAkBTkFOQAqBToFOgAWBTsFOwApBT0FPQBCBT4FPgAqBT8FPwAPBUAFQQBCBUIFQgATBUMFQwAkBUQFRwBCBUgFSQAWBUoFSgAkBUsFTAApBU0FTQAqBU4FTgAkBU8FUABGBVEFUgATBVMFVAAJBVUFVQATBVYFVgAqBVcFVwBCBVgFWAAOBVkFWgBCBVsFWwBGBVwFXABCBV0FXwA3BWAFYgAWBWMFYwAqBWQFZQAPBWYFZwBCBWgFagAWBWsFawAPBWwFbgApBW8FbwBGBXAFcgBCBXMFdAAqBXUFdQBEBXYFdgAOBXcFdwAWBXgFeAApBXkFeQAgBXoFegBCBXsFewBBBXwFfAAOBX0FfQAWBX4FfgBFBX8FfwAWBYAFgAAqBYEFgQAPBYIFhABGBYUFhQATBYYFhgAOBYcFiQBCBYoFjgBGBY8FjwAkBZAFkAATBZEFkQBCBZIFkgAPBZMFkwAWBZQFlABCBZUFlQAGBZYFlgBCBZcFlwAWBZgFmQBGBZoFngAWBZ8FogBGBaUFpwBGBagFqABLBakFqQBGBaoFqgAOBasFqwBCBa0FrgAWBa8FrwA3BbAFsQAWBbMFuABGBbkFuQAgBboFugBMBb4FvgBMBb8FvwBNBcAFwAAsBcEFwQAXBcIFwgAoBcMFwwAlBcQFxAAQBcUFxQA/BcYFxgAsBccFxwAhBcgFyAANBckFyQAUBcoFygAtBcsFywAYBcwFzAA7Bc0FzQAmBc4FzgARBc8FzwA9BdAF0AAsBdEF0QAiBdIF0gANBdMF0wAVBiQGJAAEBiUGJQAFBiYGJwA0BigGKAAKBikGKgAaBisGKwA+BiwGLABQBi4GLgAaBi8GLwAbBjAGMAAcBjEGMgA6BjMGMwAKBjQGNABDBjUGNQA8BjYGNgAFBjoGOgBDBj0GPQAHBj4GPgAIBj8GPwAHBkAGQABPBkEGQQAZBkwGTgA0BlIGUgA0BlMGUwBABlQGVAA0BlUGVQBABlYGVgAaBlcGVwAdBlgGWAAeBlkGWQAdBloGWgAeBlsGWwAaBmIGYgA0BmMGYwASBmQGZAA0BmUGZQASBmYGZgAaBmoGagAaBm8GbwAaBnkGeQAwBnoGegAWBnsGewAwBn0GfQBOBn4GfgAWBoIGggAwBocGhwBNBokGiQBNBpQGlABDBpUGlgA0BpgGmAA0BqEGogA0BqcGpwBMBqgGqABNBqoGqgA0BqsGqwBCBq0GrgA5BsoGygAwBssGywADBswGzAA4Bs0GzQAfBs4GzwAwBtAG0AAnBtEG0QAMBtUG1gALBtcG1wAwBtgG2ABNBtoG2wA6BtwG3AAwBz4HPgAdAAICsAAEAAAC/AOiAAgAKgAA//n/5P/V/+7/2f/0/93/6f/f/+z/8//v//n/7P/q/+r/7P/3/+7/5P/y/+n//f/1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/6v/VAAD/5gAA/+YAAP/h/9AAAP/wAAD/0f/s/+z/7P/0AAD/3//f/+0AAwAA/+n/9AAGAAYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/3//JAAD/1//5/+0AAP/t/+sAAAAAAAAAAP/w/+n/9AAA//P/6f/zAAAAAP/h//T/+QAAAAD/3wAmAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/7P+W/6gAAAAAAAAAAAAA/y7/ZP96AAAAAAAAAAAAAP9mAAD/ov+b/5n/ewAA/zX/awAA/0kAAAAA/9r/qP/5/5sAAAAAAAAAAAAAAAAAAAAA//f/2v/f/+7/rf/s/+r/5v/m/+cAAAAAAAD/vf/b/9j/4AAA//P/6QAA//EAAP/mAAAAAP/3AAAAAAAAAAD/5wAAAAD/6f/u//kAAAAAAAAAAAAA//n/9f/g/+j/vAAA/97/1v/V//H/8f/xAAD/2v/q/+X/5AAA/+//6f/s/+7/+P/VAAAAAAAA/+oAAAAAAAAAAAAAAAD/7P/uAAD/9P/9//UAAAAAAAD/6P/SAAD/wv/Y/97/5v/Q/+7/9wAAAAD/1//V/9b/3AAA//f/7v/qAAAAAP/hAAAAAAAAAAAAAAAAAAD/7AAAAAAAAP/3AAAAAAAAAAD//QAAAAD/+AAAAAD/wQAA/+EAAP/j//oAAAAAAAAAAP/t/+UAAAAA/+8AAAAAAAAAAP/WAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABACQEZwRpBGoEawRsBHUEhQSHBIkEigSMBI0ElASXBJgEnQSkBKUEpgSuBK8EsQSyBLkEuwTPBNgE2wTcBOQE8gTzBPUE9gT4BQUAAgAbBGkEawADBGwEbAABBHUEdQABBIUEhQABBIcEhwABBIkEigAFBIwEjQAFBJQElAAGBJcElwAGBJgEmAAHBJ0EnQAHBKQEpAABBKUEpQADBKYEpgAEBK4ErwABBLEEsQAEBLIEsgAGBLkEuQABBLsEuwABBM8EzwADBNgE2AAFBNsE3AABBOQE5AACBPIE8wAFBPUE9gAFBPgE+AAHBQUFBQAHAAIA/gAEAB8AFwAhACcAIABHAEgAIwBKAFEAIABoAGkAJwCEAKYAIACpAKkAIACyALQAJAC2AL0AJAC/AL8AIADAAMYABQDHAN4ABgDfAOQABwDlAOUACADmAO8ACQD2AQ8AAQEQAREAFwErASsAAQEsATMAIAFFAUYAKAFVAVYAIAFXAV0AGAFeAXoABgF7AYQAJQGmAaYAIQGnAcwAGgHOAc4ADAHQAdcAGgHYAd0AIQHeAe4AIgHvAfEAHgHyAfQAIQH1AfUAIgH2Af4AIQH/AgsAIgIMAi4AGgIvAi8AIgIwAjAAIQIxAjEAGgIyAjkAIgJGAkYAIQJoAm0AFQJuAm4AFgJvAngAFQJ/ApgAGgKbArMAGgK0Ar0AIQK+Ar4AGgK/AsYAIQLaAtoABQRmBGYAFwRsBGwABARwBHAACARxBHEAIwR4BHgABAR7BHsAIAR+BH4AIAR/BH8ABQSABIEACASCBIIAIASDBIMACASEBIQAAgSKBIoABQSMBIwABASOBI4AJASPBI8AIASQBJAAIwSTBJMAJwSUBJQABQSWBJYACASXBJgABQSZBJkACASaBJoAIASbBJsABwSeBJ4ACASfBJ8AIwSjBKMABQSoBKkAIASqBKoABQSrBKwACQStBK0ACASuBK4ABQSvBLAAAgSzBLQAAwS2BLYACAS6BLoAAgS8BL4AFwTABMEAIATCBMIACATDBMQAIwTHBMkAIATKBMoAIwTLBM0ACATOBM4AAgTSBNMACATVBNUABATWBNYAIATXBNcABwTbBNwABATdBN0AFwTeBN4AIAThBOIAIATjBOMAAQTkBOQAHwTtBO0AAQTuBO4AGATvBPAAJQTxBPEAIATyBPIABgTzBPMABQT0BPQABgT1BPUABAT3BPcAKAT5BPkAGAT6BPsAAQT8BPwAFwUABQIAJQUEBQQAIAUFBQUABgUHBQcAIAUIBQsAIgUMBQwACwUNBQ8AGgUQBRAAFgURBREADAUSBRcAIgUYBRgACwUZBRoAIgUbBRsAGgUcBR0AIgUeBR4AGgUfBR8AFAUgBSEAFQUiBSIAGgUjBSMAFgUlBSkAIgUqBSoAFAUrBSsAIgUsBSwACwUtBS0AIgUvBS8AGgUwBTAADAUxBTIAIgUzBTMAHgU1BTUAIgU2BTYAFgU3BTcAIQU4BTgAFAU5BTkAFgU6BToAGgU7BTsAFQU9BT0AIgU+BT4AFgU/BT8ADAVABUEAIgVCBUIAIQVDBUMAFAVEBUcAIgVIBUkAGgVKBUoAFAVLBUwAFQVNBU0AFgVOBU4AFAVRBVIAIQVTBVQACgVVBVUAIQVWBVYAFgVXBVcAIgVYBVgACwVZBVoAIgVcBVwAIgVgBWIAGgVjBWMAFgVkBWUADAVmBWcAIgVoBWoAGgVrBWsADAVsBW4AFQVwBXIAIgVzBXQAFgV1BXUAEgV2BXYACwV3BXcAGgV4BXgAFQV5BXkAEwV6BXoAIgV7BXsAHgV8BXwACwV9BX0AGgV/BX8AGgWABYAAFgWBBYEADAWFBYUAIQWGBYYACwWHBYkAIgWPBY8AFAWQBZAAIQWRBZEAIgWSBZIADAWTBZMAGgWUBZQAIgWVBZUAKQWWBZYAIgWXBZcAGgWaBZ4AGgWoBagAHQWqBaoACwWrBasAIgWtBa4AGgWwBbEAGgW5BbkAEwW6BboAFwW+Bb4AFwYmBicAGQYpBioAHAYrBisADQYuBi4AHAYvBi8ADgYxBjIAEQY9Bj0AGwY/Bj8AGwZBBkEAJgZMBk4AGQZSBlIAGQZUBlQAGQZWBlYAHAZXBlcADwZYBlgAEAZZBlkADwZaBloAEAZbBlsAHAZiBmIAGQZkBmQAGQZmBmYAHAZqBmoAHAZvBm8AHAZ5BnkAIAZ6BnoAGgZ7BnsAIAZ9Bn0AJAZ+Bn4AGgaCBoIAIAaVBpYAGQaYBpgAGQahBqIAGQanBqcAFwaqBqoAGQarBqsAIgbKBsoAIAbOBs8AIAbXBtcAIAbaBtsAEQbcBtwAIAc+Bz4ADwACANwABAAAAQYBQAADACIAAP+5/83/9P+S/9r/4v/f//D/3v/w//n/1f/Q/9T/9P/w/8z/3//a//gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//YAAP/WAAD/+P/c/+oAAP/t/97/0AAAAAAAEf/l//cACgAD//f/9P/X/+n/6v/t/+n//f/4AAAAAAAAAAAAAAAAAAAAAAAAAAD/6AAAAAAAAAAA/+n/+QAA/8b/2//jAAD/3P/Y/+P/5v/9AAAAAAADAAD/+QAAAAD/+f/X//T/7P/6//0AAQATBQkFHwUpBSoFLAUtBTgFPAU9BUUFeQWOBY8FpwWoBaoFqwWsBbkAAgAJBQkFCQABBR8FHwABBTgFOAACBTwFPAABBT0FPQACBUUFRQABBXkFeQACBawFrAACBbkFuQACAAIAsAAEAB8AFQBHAEgAGgDAAMYABADfAOQABQDlAOUABgDmAO8ABwD2AQ8AIAEQAREAFQErASsAIAGnAcwAGQHOAc4AFAHQAdcAGQIMAi4AGQIxAjEAGQJQAmcAIQJoAm0AEgJuAm4AEwJvAngAEgJ/ApgAGQKbArMAGQK+Ar4AGQLHAtQAIQLaAtoABARmBGYAFQRsBGwAAwRwBHAABgRxBHEAGgR4BHgAAwR/BH8ABASABIEABgSDBIMABgSEBIQAAQSKBIoABASMBIwAAwSQBJAAGgSUBJQABASWBJYABgSXBJgABASZBJkABgSbBJsABQSeBJ4ABgSfBJ8AGgSjBKMABASqBKoABASrBKwABwStBK0ABgSuBK4ABASvBLAAAQSzBLQAAgS2BLYABgS6BLoAAQS8BL4AFQTCBMIABgTDBMQAGgTKBMoAGgTLBM0ABgTOBM4AAQTSBNMABgTVBNUAAwTXBNcABQTbBNwAAwTdBN0AFQTjBOMAIATkBOQAFgTtBO0AIATzBPMABAT1BPUAAwT6BPsAIAT8BPwAFQUMBQwACgUNBQ8AGQUQBRAAEwURBREAFAUYBRgACgUbBRsAGQUeBR4AGQUfBR8AEQUgBSEAEgUiBSIAGQUjBSMAEwUkBSQAIQUqBSoAEQUsBSwACgUvBS8AGQUwBTAAFAU2BTYAEwU4BTgAEQU5BTkAEwU6BToAGQU7BTsAEgU+BT4AEwU/BT8AFAVDBUMAEQVIBUkAGQVKBUoAEQVLBUwAEgVNBU0AEwVOBU4AEQVPBVAAIQVTBVQACQVWBVYAEwVYBVgACgVbBVsAIQVgBWIAGQVjBWMAEwVkBWUAFAVoBWoAGQVrBWsAFAVsBW4AEgVvBW8AIQVzBXQAEwV1BXUADwV2BXYACgV3BXcAGQV4BXgAEgV5BXkAEAV8BXwACgV9BX0AGQV/BX8AGQWABYAAEwWBBYEAFAWCBYQAIQWGBYYACgWKBY4AIQWPBY8AEQWSBZIAFAWTBZMAGQWVBZUAFwWXBZcAGQWYBZkAIQWaBZ4AGQWfBaIAIQWlBacAIQWoBagAHQWpBakAIQWqBaoACgWtBa4AGQWwBbEAGQWzBbgAIQW5BbkAEAW6BboAFQW+Bb4AFQYmBicAGAYoBigAHAYpBioACwYuBi4ACwYvBi8ADAYxBjIAHwYzBjMAHAY9Bj0ACAY/Bj8ACAZABkAAHgZBBkEAGwZMBk4AGAZSBlIAGAZUBlQAGAZWBlYACwZXBlcADQZYBlgADgZZBlkADQZaBloADgZbBlsACwZiBmIAGAZkBmQAGAZmBmYACwZqBmoACwZvBm8ACwZ6BnoAGQZ+Bn4AGQaVBpYAGAaYBpgAGAahBqIAGAanBqcAFQaqBqoAGAbaBtsAHwc+Bz4ADQAEAAAAAQAIAAEAgAAMAAUB3gAWAAEAAwW+Bb8GiQADACAAJgAsEt4S3gAyEt4AOBLeEt4APhLeAEQASgBQAAEBbgAAAAEC3QAAAAEBbgOnAAEBdwAAAAEBdwK8AAEFbQAAAAEFbQISAAEDkAEgAAED9ALmAAQAAAABAAgAAQAMACIABQFqAvYAAgADBt8G6gAABuwHJwAMB14HbQBIAAIANgRmBGYAAARoBGoAAQRtBHwABAR+BIEAFASDBIQAGASGBIcAGgSJBIkAHASLBIwAHQSOBJMAHwSYBJgAJQSaBJoAJgScBJwAJwSeBKAAKASiBKcAKwSpBLYAMQS5BLkAPwS7BMMAQATFBNEASQTWBNYAVgTYBNgAVwTbBNsAWATfBOMAWQTlBOwAXgTuBPAAZgT0BPQAaQT3BQMAagUFBQYAdwUIBQoAeQUNBSEAfAUjBSQAkQUmBScAkwUpBSkAlQUrBSwAlgUuBTQAmAU6BToAnwU8BTwAoAU+BUAAoQVCBUYApAVJBU0AqQVPBVEArgVTBVYAsQVYBVgAtQVaBVoAtgVcBWQAtwVmBXEAwAV2BXgAzAV8BXwAzwV/BX8A0AWCBYUA0QWHBY0A1QWSBZQA3AWWBaYA3wWpBakA8AWtBbgA8QBYAAIUdgACFHYAAhR2AAIUdgACFHYAAhR2AAIUdgACFHYAAhR2AAIUdgACFHYAAhR2AAIUdgACFHYAAhR2AAIUdgACFHYAAhR2AAIUdgACFHYAAhR2AAIUdgACFHYAAhR2AAIUdgACFHYAAhR2AAIUdgACFHYAAhR2AAQUdgAAEXgAABF4AAAReAAAEXgAAQFiAAAReAAAEXgAAwFoAAMBbgADAYAAAwF0AAIUfAACFHwAAhR8AAIUfAACFHwAAhR8AAIUfAACFHwAAhR8AAIUfAACFHwAAhR8AAIUfAACFHwAAhR8AAIUfAACFHwAAhR8AAIUfAACFHwAAhR8AAIUcAACFHwAAhR8AAIUfAACFHwAAhR8AAMBegADAYAAAwGGAAIUdgACFHYAAhR2AAIUdgACFHYAAhR2AAIUdgACFHYAAhR8AAIUfAACFHwAAhR8AAIUfAACFHwAAhR8AAIUfAAB/tUAAAAB/tQBtgAB/kwBtgAB/soBCgAB/tQBZAAB/ycBggAB/mMBXgD9Cv4LBAr4D4oPignkD4oKUA+KD4oPig+KC7gPig+KD4oPignqD4oPigscCyILKA+KD4oLHAsiCfAPig+KCxwLIgn2D4oPig+KD4oK1A+KD4oOOg+KC74Pig+KD4oPigoCD4oPig+KD4oKAg+KD4oPig+KCfwPig+KD4oPigoCD4oPig+KD4oKSg+KD4oPig+KCggPig+KD4oPig+KD4oPigrsD4oK8g+KD4oK2g+KCuAK5g+KC1ILWAusC2QLag+KD4oPig+KD4oLxA+KC8oPig+KDjoPigpoCm4Pig+KD4oKsA+KD4oPig+KCrAPig+KD4oPig+KD4oPig+KD4oKqg+KD4oPig+KD4oPig+KD4oPig+KD4oPig+KD4oPigugD4oLjguUCg4LoA+KD4oPig+KChQPigoaD4oLuA+KD4oKIA+KD4oPig+KD4oPigomD4oPigrCCiwKzg+KD4oKMgo4Cj4Pig+KD4oPigpED4oPig+KD4oPigv0D4oLUgtYC6wLZAtqD4oPigsoD4oPig+KD4oK1A+KD4oOOg+KC74Pig+KD4oPigpKD4oPig+KD4oKUA+KD4oKVg+KClwPig+KCtoPigrgCuYPigraD4oKYgrmD4oPig+KD4oPig+KD4oPig+KD4oPigvED4oLyg+KD4oOOg+KCmgKbg+KCnQPigp6CoAPigqGD4oKjAqSD4oPig+KD4oPig+KCpgPigqeCqQPig+KD4oKqg+KD4oPig+KCrAPig+KD4oPig+KD4oPig+KD4oPig+KD4oKtg+KCrwPig+KCrYPigq8D4oPigrCCsgKzg+KD4oPig+KCtQPig+KCtoPigrgCuYPigrsD4oK8g+KD4oK/gsECvgPig+KCv4LBAsKD4oPigsQD4oLFg+KD4oLHAsiCygPig+KD4oPigsuD4oPig+KD4oLNA+KD4oPig+KCzoPig+KDjoPigtAD4oPig+KD4oLRg+KD4oPig+KC0wPig+KC1ILWAteC2QLagtSC1gLrAtkC2oLUgtYC14LZAtqD4oPigtwD4oPig+KD4oLdg+KD4oPig+KC3wPig+KD4oPiguCD4oPig+KD4oLiA+KD4oPig+KC7gPig+KC44LlAuaC6APig+KD4oLpg+KD4oPig+KC6wPig+KD4oPig+KC7IPig+KD4oPig+KD4oPig+KC7gPig+KDjoPigu+D4oPigvED4oLyg+KD4oLxA+KC8oPig+KDXoMEgwMD4oPigweDCQMKg+KD4oMHgwkC9APig+KDB4MJAvWD4oPigw2DDwMDA+KDEgMNgw8DAwPigxIDDYMPAwMD4oMSAw2DDwL3A+KDEgPig+KD4oPig+KC/oPigwADAYPigxaD4oL4g+KD4oMWg+KC+IPig+KD4oPigvoD4oPig+KD4oL7g+KD4oPig+KD4oL9A+KC/oPigwADAYPig16DBIMDA+KD4oNegwSDEIPig+KDvQPigwYD4oPigweDCQMKg+KD4oMNgw8DDAPigxIDDYMPAxCD4oMSAxaD4oMTg+KD4oMWg+KDFQPig+KDFoPigxgD4oPig+KD4oMZg+KD4oPig+KD4oMbA+KDYwNkg2GD4oPigxyD4oMeA+KD4oPig+KDigPig+KD4oPig6UD4oPig2qDbANtg+KD4oNqg2wDH4Pig+KDaoNsAyED4oPig+KD4oNdA+KD4oOfA+KDoIPig+KD4oPigyKD4oPig+KD4oMig+KD4oPig+KDJAPig+KD4oPigyWD4oPig+KD4oPNg+KD4oPig+KDJwPig+KD4oPig+KD4oPig16D4oNgA+KD4oOWA+KDl4OZA+KDdoN4A28DewN8g+KD4oPig+KD4oMog+KDKgPig+KDogPig6OD4oPig0gD4oNJg0sD4oOFg+KDK4Pig+KDhYPigyuD4oPig+KD4oPig+KD4oPig+KDTgPig+KD4oPig+KD4oPig+KD4oPig+KD4oPig+KD4oONA+KD4oPigy0DjQPig+KD4oPigy6D4oMwA+KDMYPig+KDMwPig+KD4oPig+KD4oOgg+KD4oNXAzSDNgPig+KDpoOoAzeD4oPig+KD4oM5A+KD4oM6g+KDPAM9g6CD4oPig34D4oPig+KD4oM/A+KD4oPig+KDXQPig+KDnwPig6CD4oPig+KD4oPNg+KD4oNAg+KDQgPig+KDQ4Pig0UD4oPig5YD4oOXg5kD4oOWA+KDRoOZA+KD4oPig+KD4oPig6ID4oOjg+KD4oNIA+KDSYNLA+KD4oPig+KDTIPig+KD4oPig0yD4oPig+KD4oPig+KD4oPig04D4oPig+KD4oNPg+KD4oOag+KDWINRA1KDVAPig1WD4oPig1QD4oNVg+KD4oNXA+KDWINaA1uD4oPig10D4oPig+KD4oPig+KD4oOWA+KDl4OZA+KDXoPig2AD4oPig2MDZINhg+KD4oNjA2SDZgPig+KDZ4Pig2kD4oPig2qDbANtg+KD4oN2g3CDbwPig+KDdoNwg3mD4oPig+KD4oNyA+KD4oOfA+KDgQPig+KD4oPig3OD4oPig+KD4oN1A+KD4oN2g3gDeYN7A3yD4oPig34D4oPig+KD4oN/g+KD4oPig+KDgQPig+KDhYPig4KD4oPig4WD4oOEA+KD4oOFg+KDhwPig+KD4oPig4iD4oPig+KD4oOKA+KD4oPig+KDi4ONA+KD4oPig+KD4oPig46D4oOQA+KD4oORg+KDkwPig+KD4oPig+KD4oPig+KD4oOxA+KD4oPVA9aDtYPig9mD1QPWg7WD4oPZg9UD1oO4g+KD2YPig+KDlIPig+KDlgPig5eDmQPig5qD4oOcA+KD4oO9A+KD4oPig+KD4oPig+KD4oPig9UD1oO1g+KD2YPig+KDnYPig+KD4oPig52D4oPig58D4oOgg+KD4oOiA+KDo4Pig+KD4oPig6UD4oPig6aDqAOpg+KD4oPig+KDtYPig+KDqwOsg9sD4oOuA+KD4oOvg+KD4oPDA8SDwYPig+KD4oPig7ED4oPig8kDyoPMA+KD4oPJA8qDsoPig+KDyQPKg7QD4oPig9UD1oO1g+KD2YPVA9aDtYPig9mD1QPWg7cD4oPZg9UD1oO4g+KD2YO6A+KDu4Pig+KDvQPig+KD4oPig94D4oO+g+KD4oPeA+KDvoPig+KD4oPig8AD4oPig8MDxIPBg+KD4oPDA8SDxgPig+KD4oPig8eD4oPig8kDyoPMA+KD4oPPA9CDzYPig+KDzwPQg9ID4oPig9UD1oPTg+KD2YPVA9aD2APig9mD3gPig9sD4oPig94D4oPcg+KD4oPeA+KD34Pig+KD4oPig+ED4oPigABAX0AAAABAUoDUwABAWUDUwABAWUDOQABAZoDUwABAZoCvAABAWcDUwABAfICvAABAogCSgABAUoAAAABAYMAAAABAUACvAABANAAAAABAJsAAAABAM0AAAABAJsDOQABAQoCvAABAWcCvAABAX0CvAABAfAAAAABAfACvQABA0QCvAABAS8CvAABAS8BUwABAU4AAAABAU4CvAABAUsA+QABAUQAAAABAUQCvAABAUEA+QABAS4AAAABAS4CvAABAS4BUwABAVUCvAABAVQCvAABAlUAAAABAk8CvwABAJ8AAAABANEAAAABAJ8CvAABAgQCvAABAZkAAAABAZkCvAABAZkCKQABAeEAAAABAeECvAABAXsCvAABAXsAAAABAuoAAAABAXsDOQABAhwAAAABAhwCvAABAW8AAAABAmkAAAABAWUCvAABAZ0CvAABAZ0DOQABAgQDOQABAT8DOQABAZoDNQABAZoDOQABAagAAAABAfUAAAABAagDOQABAagBXgABAoECvAABAUADOQABAVQDNQABAVQDOQABAVQDUwABAVUDOQABA0MAAAABA3QAAAABAfIDOQABAK4CSgABAWYCvAABAagCvAABAMcCSgABAUoCvAABAT8CvAABAZYAAAABAZ8CvAABAV4DUwABAV4DOQABAY8DUwABAYoCvAABAfECvAABAOwCvAABAQ4CSgABATwAAAABAT4CvAABATsBSgABAY8CvAABAr0AAAABAhQCvAABAV4AAAABAlEAAAABAV4CvAABAY8DNQABAYgAAAABArEAAAABAY8DOQABAo4CvAABAYoDNQABAYoDOQABApcAAAABAYoDUwABAfEDOQABAMMCSgABATgAAAABATgCEwABATUCvQABATUCowABAVUCEgABAVUCvQABAVUCswABATQCvQABAYIAAAABAW4CEgABARACEgABAaACEgABAgEBugABAQsAAAABAQsCEgABATkAAAABAL0AAAABAI0CxQABAIsCowABAI4CxQABAVsAAAABAJAC5gABAMMCeQABATMCEAABAUEAAAABAUECEgABAYoAAAABAYoCEgABArECEAABAPgAAAABAPgCEgABAPgA/AABAR4ABQABARQCEgABARMCEgABAMgCegABAQQCEgABAdAAAAABAcoCEAABAI0AAAABAI0C5gABAI0BZgABARYC5gABAagCEgABAY8AAAABAY8CEgABASECEgABAR8AAAABAf0AAAABASECowABAdkAAAABAc0CEgABATUAAAABAgkAAAABATUCEgABAT8CEgABAGsCEgABAagCowABAVUCnwABAVUCowABAT8AAAABAaIAAAABAT8CowABAT8BCQABAcgCEgABAUUCEgABAUUCowABAQcCowABARACnwABARACowABAaAAAAABARACvQABARQCowABASMCEAABAaACowABAJoBugABAS8AAAABAUICEgABAdQAAAABAdQCEgABATECEgABAVIAAAABAVICEgABAVIBpgABAVkAAAABAVkCEgABAgYCEAABAPsAAAABAQcCEgABAToAAAABAS4CEgABASMCuwABAIsAAAABALsAAAABAIsCnwABAVAAAAABAkkAAAABAhoCEgABAgYCnQABAUgCEgABATACvQABATACowABAUYCEgABAUYCswABAUYCvQABAWkAAAABAVYCEgABAhQAAAABAVACEgABAZUCEgABAU8CEgABAU8AAAABAk8AAAABAU8CowABAeUCEgABATAAAAABAb0AAAABATACEgABATQCEgABATQAAAABAKcCEgABATQCowABAUYCnwABAUcAAAABAkAAAAABAUYCowABAhECEgABAVACnwABAVACowABApUAAAABAVACvQABAZUCowABAAAAAAAJAAAAAQAIAAEABAAAA7wABgEAAAEACAABAAwAHAABACoASgABAAYG/wcABwEHAgcEBwUAAQAFBv8HAAcBBwQHBQAGAAAAGgAAABoAAAAaAAAAGgAAABoAAAAaAAH+1AAAAAUAEgAMABIAGAAeAAH+1P9qAAH+1P9vAAH+1P9jAAH+1P9yAAYCAAABAAgAAQF6AAwAAQGgAEAAAgAIBt8G6gAABuwG/QAMBwoHJAAeB0AHQQA5B0UHRQA7B0gHSgA8B0wHUQA/B1MHVABFAEcAkACuAK4ArgKSAJYAugCuALoAnACuALoAwADAAsAAwACiAKIAwACuAK4ArgCoAK4ArgCuALQAugDAAMYAzADqAOoA6gDSANgA9gDqAPYA3gDqAPYA/AD8At4A/AD8AOoA6gDqAOQA6gDqAOoA8AD2APwBFAEOAQ4BDgEgASABIAECAQgBDgEOARQBGgEgAAH+1AKjAAH+1AMwAAH+1AMxAAH+1AL9AAH+1AKfAAH+1AMtAAH+1AMDAAH+1AK9AAH+1AKzAAH+1ALfAAH+1AM5AAH+1ANSAAH+1APGAAH+1APHAAH+1AM1AAH+1APDAAH+1AOZAAH+1ANTAAH+1ANJAAEBLAKjAAEBLAK8AAEBLAK9AAEBLAKfAAEBLAL9AAEBLAKzAAYCAAABAAgAAQAMACgAAQAyAWoAAgAEBt8G6gAABuwG/QAMBwoHJAAeB14HbQA5AAIAAQdeB20AAABJAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABMgAAATIAAAEyAAABMgAAATIAAAEyAAABMgAAATIAAAEyAAABMgAAATIAAAEyAAABMgAAATIAAAEyAAABMgAAATIAAAEyAAABMgAAATIAAAEyAAABJgAAATIAAAEyAAABMgAAATIAAAEyAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEyAAABMgAAATIAAAEyAAABMgAAATIAAAEyAAABMgAB/tQCuwAB/tQCEgAB/tQCvAAQACgAKAAiACgALgAuADQAOgBGAEYAQABGAEwATABSAFgAAf7UAyUAAf7UAxoAAf98AvcAAf9WAwsAAf7UAyAAAf7UA7sAAf7UA7AAAf98A40AAf9WA6EAAf7UA7YAAQAMACIABQEKAq4AAgADBt8G6gAABuwHJwAMB14HbQBIAAIAJgAEAEgAAABKAH8ARQCBAKYAewCpALQAoQC2AL0ArQC/ANoAtQDcAN4A0QDgAOQA1ADmAPQA2QD2ASoA6AEsATYBHQE4AVABKAFSAVQBQQFWAaUBRAGnAa4BlAGwAc4BnAHQAdYBuwHYAgcBwgIJAjwB8gI+AkUCJgJIAm0CLgJvAn0CVAJ/ArMCYwK1AtkCmALfAyMCvQMlAzUDAgM3A1sDEwNdA4IDOAOFA5ADXgOSA5kDagObA7YDcgO4A7oDjgO8A8ADkQPCBAUDlgQHBBED2gQTBCoD5QQsBC4D/QQwBGMEAABYAAIBmAACAZgAAgGYAAIBmAACAZgAAgGYAAIBmAACAZgAAgGYAAIBmAACAZgAAgGYAAIBmAACAZgAAgGYAAIBmAACAZgAAgGYAAIBmAACAZgAAgGYAAIBmAACAZgAAgGYAAIBmAACAZgAAgGYAAIBmAACAZgAAgGYAAQBmAAAAWgAAAFoAAABaAAAAWgAAQFiAAABaAAAAWgAAwFuAAMBdAADAYwAAwF6AAIBngACAZ4AAgGeAAIBngACAZ4AAgGeAAIBngACAZ4AAgGeAAIBngACAZ4AAgGeAAIBngACAZ4AAgGeAAIBngACAZ4AAgGeAAIBngACAZ4AAgGeAAIBgAACAZ4AAgGeAAIBngACAZ4AAgGeAAMBhgADAYwAAwGSAAIBmAACAZgAAgGYAAIBmAACAZgAAgGYAAIBmAACAZgAAgGeAAIBngACAZ4AAgGeAAIBngACAZ4AAgGeAAIBngAB/tUAAAAB/tQAAAAB/tQBtgAB/kwBtgAB/soBCgAB/tQCuwAB/tQBZAAB/ycBggAB/mMBXgAB/tQCEgAB/tQCvAQ0KlIqWCpGPJQ8lCpSKlgqNDyUPJQqUipYKl48lDyUKlIqWCoQPJQ8lCouKlgqXjyUPJQqUipYKhA8lDyUKlIqWCoKPJQ8lCpSKlgqEDyUPJQqUipYKl48lDyUKlIqWCpePJQ8lCpSKlgqFjyUPJQqLipYKl48lDyUKlIqWCoWPJQ8lCpSKlgqHDyUPJQqUipYKiI8lDyUKlIqWCo0PJQ8lCpSKlgqKDyUPJQqLipYKkY8lDyUKlIqWCo0PJQ8lCpSKlgqOjyUPJQqUipYKl48lDyUKlIqWCpAPJQ8lCpSKlgqRjyUPJQqUipYKkw8lDyUKlIqWCpMPJQ8lCpSKlgqXjyUPJQuWjyULlQ8lDyULlo8lC5gPJQ8lCpkPJQqajyUPJQqgjyUKnA8lDyUKoI8lCp2PJQ8lCqCPJQqfDyUPJQqgjyUKnA8lDyUKoI8lCp2PJQ8lCqCPJQqfDyUPJQqgjyUKog8lDyUM0w8lCrQLn48lCqOPJQqlC5+PJQqmjyUKqAqpjyUM0w8lCqsLn48lCqyPJQquCq+PJQqxDyUKtAufjyUKso8lCrQLn48lCrWPJQq3C5+PJQrHiskKxg8lDyUKx4rJDjaPJQ8lCseKyQrKjyUPJQrHiskKyo8lDyUKx4rJCsqPJQ8lCseKyQrKjyUPJQrHiskKuI8lDyUKwArJCsqPJQ8lCseKyQq4jyUPJQrHiskKug8lDyUKx4rJCruPJQ8lCseKyQ42jyUPJQrHiskKvQ8lDyUKx4rJCr6PJQ8lCsAKyQrGDyUPJQrHiskONo8lDyUKx4rJCsGPJQ8lCseKyQrKjyUPJQrHiskKww8lDyUKx4rJCsSPJQ8lCseKyQrEjyUPJQrHiskKxg8lDyUKx4rJCsqPJQ8lCs2PJQrMDyUPJQrNjyUKzw8lDyULDg8lC72PJQ8lCw4PJQu2DyUPJQsODyULtg8lDyULDg8lC7YPJQ8lCwgPJQu9jyUPJQsODyULuQ8lDyULDg8lC7qPJQ8lCw4PJQu9jyUPJQsODyULDIrWjyUK0I8lCtIK048lCtUPJQsMitaPJQsODyULD4rWjyULDg8lCw+K1o8lCwgPJQsMitaPJQriiuQK948lDyUPJQ8lCtgPJQ8lCuKK5ArxjyUPJQriiuQK5Y8lDyUK4orkCuWPJQ8lCuKK5ArxjyUPJQriiuQK2Y8lDyUK4orkCtsPJQ8lCuKK5ArcjyUPJQreCuQK948lDyUK4orkCvGPJQ8lCuKK5ArfjyUPJQriiuQK5Y8lDyUK4orkCuEPJQ8lCuKK5Ar3jyUPJQriiuQK5Y8lDyUPJQ8lCucPJQ8lDyUPJQrojyUPJQrqDyUK7o8lDyUK6g8lCuuPJQ8lCu0PJQrujyUPJQvUDyUK94vXC9iL1A8lCvAL1wvYi9QPJQrxi9cL2IvUDyUK94vXC9iK8w8lCveL1wvYi9QPJQr3i9cL2IrzDyUK94vXC9iL1A8lCvSL1wvYivYPJQr3i9cL2Ir5DyUK+or8Cv2K/w8lCwIPJQ8lCwCPJQsCDyUPJQsODyULDI8lDyULDg8lCwOPJQ8lCw4PJQsFDyUPJQsODyULD48lDyULCA8lCwyPJQ8lCw4PJQsGjyUPJQsIDyULDI8lDyULDg8lCwmPJQ8lCwsPJQsMjyUPJQsODyULD48lDyULIAshiyqLJIsmCyALIYsdCySLJgsgCyGLHoskiyYLIAshix6LJIsmCyALIYsRCySLJgsYiyGLHoskiyYLIAshixELJIsmCyALIYsSiySLJgsgCyGLFAskiyYLIAshix0LJIsmCyALIYsViySLJgsgCyGLIwskiyYLIAshixcLJIsmCxiLIYsqiySLJgsgCyGLHQskiyYLIAshixoLJIsmCyAPJQsqjyUPJQsgDyULHQ8lDyULGI8lCyqPJQ8lCyAPJQsdDyUPJQsgDyULGg8lDyULIA8lCx6PJQ8lCyALIYsdCySLJgsgCyGLHoskiyYLIAshixuLJIsmCyALIYsjCySLJgsgCyGLIwskiyYPJQ8lCyqPJQ8lCyALIYsqiySLJgsgCyGLHQskiyYLIAshix6LJIsmCyALIYsjCySLJgsgCyGLIwskiyYLIAshiyMLJIsmCyePJQspDyUPJQ8lDyULKo8lDyULLw8lCzOPJQ8lCy8PJQssDyUPJQsvDyULMI8lDyULLY8lCzOPJQ8lCy8PJQssDyUPJQstjyULM48lDyULLw8lCzCPJQ8lCzIPJQszjyUPJQs7DyULPI8lDyULOw8lCzUPJQ8lCzsPJQs2jyUPJQs7DyULOY8lDyULOw8lCzgPJQ8lCzsPJQs8jyUPJQs7DyULOY8lDyULPg8lCzyPJQ8lCzsPJQs/jyUPJQs+DyULPI8lDyULPg8lCz+PJQ8lDhEPJQtBDyUPJQtEDyULSItKDyULRA8lC0iLSg8lC0QPJQtCi0oPJQtEDyULSItKDyULRY8lC0iLSg8lC0WPJQtIi0oPJQtHDyULSItKDyULWQtai06PJQtdi1kLWotRjyULXYtZC1qLV48lC12LWQtai1ePJQtdi1kLWotXjyULXYtZC1qLUY8lC12LWQtai0uPJQtdi00LWotOjyULXYtZC1qLUY8lC12LWQtai1APJQtdi1kLWotOjyULXYtZC1qLUY8lC12LTQtai06PJQtdi1kLWotRjyULXYtZC1qLUA8lC12LWQtai1ePJQtdi1kLWotRjyULXYtZC1qLV48lC12LWQtai1MPJQtdi1kLWotUjyULXYtZC1qLVg8lC12LWQtai1ePJQtdi1kLWotcDyULXYtjjyULXw8lDyULY48lC2UPJQ8lC2OPJQtgjyUPJQtjjyULYg8lDyULY48lC2UPJQ8lC3EPJQtrC3QPJQtxDyULbIt0DyULcQ8lC3KLdA8lC3EPJQtmi3QPJQtxDyULaAt0DyULaY8lC2sLdA8lC3EPJQtsi3QPJQtxDyULbgt0DyULcQ8lC2+LdA8lC3EPJQtyi3QPJQt4jyULfQ8lDyULeI8lC3WPJQ8lC3iPJQt3DyUPJQt4jyULeg8lDyULe48lC30PJQ8lC5CLkguNjyUPJQuQi5ILiQ8lDyULkIuSC5OPJQ8lC5CLkguADyUPJQuHi5ILk48lDyULkIuSC4APJQ8lC5CLkgt+jyUPJQuQi5ILgA8lDyULkIuSC5OPJQ8lC5CLkguTjyUPJQuQi5ILgY8lDyULh4uSC5OPJQ8lC5CLkguBjyUPJQuQi5ILgw8lDyULkIuSC4SPJQ8lC5CLkguJDyUPJQuQi5ILhg8lDyULh4uSC42PJQ8lC5CLkguJDyUPJQuQi5ILio8lDyULkIuSC5OPJQ8lC5CLkguMDyUPJQuQi5ILjY8lDyULkIuSC48PJQ8lC5CLkguPDyUPJQuQi5ILk48lDyULlo8lC5UPJQ8lC5aPJQuYDyUPJQuZjyULmwufjyULnI8lC54Ln48lC7GLswuwDyUPJQuxi7MLqg8lDyULsYuzC7SPJQ8lC7GLswu0jyUPJQuxi7MLtI8lDyULsYuzC7SPJQ8lC7GLswuhDyUPJQuoi7MLtI8lDyULsYuzC6EPJQ8lC7GLswuijyUPJQuxi7MLpA8lDyULsYuzC6oPJQ8lC7GLswuljyUPJQuxi7MLpw8lDyULqIuzC7APJQ8lC7GLswuqDyUPJQuxi7MLq48lDyULsYuzC7SPJQ8lC7GLswutDyUPJQuxi7MLro8lDyULsYuzC66PJQ8lC7GPJQuwDyUPJQuxi7MLtI8lDyULvA8lC72PJQ8lC7wPJQu2DyUPJQu8DyULtg8lDyULvA8lC7YPJQ8lC7ePJQu9jyUPJQu8DyULuQ8lDyULvA8lC7qPJQ8lC7wPJQu9jyUPJQvMi84Lyw8lDyUPJQ8lC78PJQ8lC8yLzgvGjyUPJQvMi84Lz48lDyULzIvOC8+PJQ8lC8yLzgvGjyUPJQvMi84LwI8lDyULzIvOC8IPJQ8lC8yLzgvDjyUPJQvFC84Lyw8lDyULzIvOC8aPJQ8lC8yLzgvIDyUPJQvMi84Lz48lDyULzIvOC8mPJQ8lC8yLzgvLDyUPJQvMi84Lz48lDyUPJQ8lC9EPJQ8lDyUPJQvSjyUPJQvUDyUL1YvXC9iL2g8lC90PJQ8lC9uPJQvdDyUPJQvpDyUL548lDyUL6Q8lC96PJQ8lC+kPJQvgDyUPJQvpDyUL6o8lDyUL4w8lC+ePJQ8lC+kPJQvhjyUPJQvjDyUL548lDyUL6Q8lC+SPJQ8lC+YPJQvnjyUPJQvpDyUL6o8lDyUL7A8lC+2PJQ8lDNYPJQvzi/UPJQzWDyUL84v1DyUM1g8lC+8L9Q8lDNYPJQvzi/UPJQvwjyUL84v1DyUL8I8lC/OL9Q8lC/IPJQvzi/UPJQwEDAWL/48lDAiMBAwFi/sPJQwIjAQMBYwCjyUMCIwEDAWMAo8lDAiMBAwFjAKPJQwIjAQMBYv7DyUMCIwEDAWL9o8lDAiL+AwFi/+PJQwIjAQMBYv7DyUMCIwEDAWL+Y8lDAiMBAwFi/+PJQwIjAQMBYv7DyUMCIv4DAWL/48lDAiMBAwFi/sPJQwIjAQMBYv5jyUMCIwEDAWMAo8lDAiMBAwFi/sPJQwIjAQMBYwCjyUMCIwEDAWL/I8lDAiMBAwFi/4PJQwIjAQMBYv/jyUMCIwEDAWMAQ8lDAiMBAwFjAKPJQwIjAQMBYwHDyUMCIwOjyUMCg8lDyUMDo8lDBAPJQ8lDA6PJQwLjyUPJQwOjyUMDQ8lDyUMDo8lDBAPJQ8lDBwPJQwWDyUPJQwcDyUMF48lDyUMHA8lDB2PJQ8lDBwPJQwRjyUPJQwcDyUMEw8lDyUMFI8lDBYPJQ8lDBwPJQwXjyUPJQwcDyUMGQ8lDyUMHA8lDBqPJQ8lDBwPJQwdjyUPJQ6SDyUMI48lDyUOkg8lDB8PJQ8lDpIPJQwgjyUPJQ6SDyUMIg8lDyUOiQ8lDCOPJQ8lDnoMNYwyjyUPJQ56DDWMLg8lDyUOegw1jDcPJQ8lDnoMNYwmjyUPJQ59DDWMNw8lDyUOegw1jCaPJQ8lDnoMNYwlDyUPJQ56DDWMJo8lDyUOegw1jDcPJQ8lDnoMNYw3DyUPJQ56DDWMKA8lDyUOfQw1jDcPJQ8lDnoMNYwoDyUPJQ56DDWMKY8lDyUOegw1jCsPJQ8lDnoMNYwuDyUPJQ56DDWMLI8lDyUOfQw1jDKPJQ8lDnoMNYwuDyUPJQ56DDWML48lDyUOegw1jDcPJQ8lDnoMNYwxDyUPJQ56DDWMMo8lDyUOegw1jDQPJQ8lDnoMNYw0DyUPJQ56DDWMNw8lDyUMOg8lDDiPJQ8lDDoPJQw7jyUPJQxBjyUMPQ8lDyUMQY8lDD6PJQ8lDEGPJQxADyUPJQxBjyUMPQ8lDyUMQY8lDD6PJQ8lDEGPJQxADyUPJQxBjyUMQw8lDyUMRI8lDyUNQ41FDESPJQ8lDUONRQxEjyUPJQ1DjUUMRg8lDyUNQ41FDEePJQ8lDUONRQxJDyUMSo1DjUUO1AxeDFOPJQ8lDtQMXgxVDyUPJQ7UDF4MX48lDyUO1AxeDF+PJQ8lDtQMXgxfjyUPJQ7UDF4MX48lDyUO1AxeDEwPJQ8lDgUMXgxfjyUPJQ7UDF4MTA8lDyUO1AxeDE2PJQ8lDtQMXgxPDyUPJQ7UDF4MVQ8lDyUO1AxeDFCPJQ8lDtQMXgxSDyUPJQ4FDF4MU48lDyUO1AxeDFUPJQ8lDtQMXgxWjyUPJQ7UDF4MX48lDyUO1AxeDFgPJQ8lDtQMXgxZjyUPJQ7UDF4MWY8lDyUMWw8lDFyPJQ8lDtQMXgxfjyUPJQxhDGKMZA8lDyUMZw8lDGWPJQ8lDGcPJQxojyUPJQ8lDyUMag8lDyUPJQ8lDGuPJQ8lDyUPJQxrjyUPJQ8lDyUMa48lDyUPJQ8lDG0PJQ8lDyUPJQxujyUPJQ8lDyUMcA8lDyUOkg8lDWkMdIx2DpIPJQ1pDHSMdgxxjyUNaQx0jHYOkg8lDIyMdIx2DpIPJQxzDHSMdg6JDyUNaQx0jHYM3AyDjIIPJQ8lDNwMg4x3jyUPJQzcDIOMfY8lDyUM3AyDjIUPJQ8lDNwMg4yFDyUPJQzcDIOMfY8lDyUM3AyDjHkPJQ8lDNwMg4x6jyUPJQzcDIOMfA8lDyUM2oyDjIIPJQ8lDNwMg4x9jyUPJQzcDIOMfw8lDyUM3AyDjIUPJQ8lDNwMg4ySjyUPJQzcDIOMgI8lDyUM3AyDjIIPJQ8lDNwMg4yFDyUPJQ8lDyUMho8lDyUPJQ8lDIgPJQ8lDyUPJQyJjyUPJQyLDyUNaQ8lDI+Miw8lDIyPJQyPjI4PJQ1pDyUMj44LDyUMkQ8lDyUM3A8lDWkNaoyUDNwPJQ1hjWqMlAzcDyUNaQ1qjJQM2o8lDWkNaoyUDNwPJQ1pDWqMlAzajyUNaQ1qjJQM3A8lDJKNaoyUDN8PJQ1pDWqMlAyVjyUMlwyYjJoMm48lDyUPJQ8lDJ0PJQ8lDyUPJQ6SDyUMp48lDyUOkg8lDJ6PJQ8lDKAPJQyhjyUPJQ6SDyUMqQ8lDyUOiQ8lDKePJQ8lDpIPJQyjDyUPJQ6JDyUMp48lDyUOkg8lDKSPJQ8lDKYPJQynjyUPJQ6SDyUMqQ8lDyUMxYzHDL4MygzLjMWMxwy7DMoMy4zFjMcMxAzKDMuMxYzHDMQMygzLjMWMxwyqjMoMy4yyDMcMxAzKDMuMxYzHDKqMygzLjMWMxwysDMoMy4zFjMcMrYzKDMuMxYzHDLsMygzLjMWMxwyvDMoMy4zFjMcMyIzKDMuMxYzHDLCMygzLjLIMxwy+DMoMy4zFjMcMuwzKDMuMxYzHDLOMygzLjLmPJQzXjyUPJQy5jyUMto8lDyUMtQ8lDNePJQ8lDLmPJQy2jyUPJQy5jyUMuA8lDyUMuY8lDMQPJQ8lDMWMxwy7DMoMy4zFjMcMxAzKDMuMxYzHDLyMygzLjMWMxwzIjMoMy4zFjMcMyIzKDMuMxY8lDL4Mygy/jMWMxwzBDMoMy4zFjMcMwozKDMuMxYzHDMQMygzLjMWMxwzIjMoMy4zFjMcMyIzKDMuMxYzHDMiMygzLjM0PJQzOjyUPJQzQDyUM0Y8lDyUM0w8lDNSPJQ8lDNYPJQzXjyUPJQzcDyUM4I8lDyUM3A8lDNkPJQ8lDNwPJQzdjyUPJQzajyUM4I8lDyUM3A8lDNkPJQ8lDNqPJQzgjyUPJQzcDyUM3Y8lDyUM3w8lDOCPJQ8lDOgPJQzpjyUPJQzoDyUM4g8lDyUM6A8lDOOPJQ8lDOgPJQzmjyUPJQzoDyUM5Q8lDyUM6A8lDOmPJQ8lDOgPJQzmjyUPJQzrDyUM6Y8lDyUM6A8lDOyPJQ8lDOsPJQzpjyUPJQzrDyUM7I8lDyUM9A8lDPoM+4z9DO4PJQzvjPEM8oz0DyUM+gz7jP0M9A8lDPoM+4z9DPcPJQz6DPuM/Qz0DyUM9Yz7jP0M9w8lDPoM+4z9DPiPJQz6DPuM/Q23DQGNig8lDQSNtw0BjYuPJQ0EjbcNAY2RjyUNBI23DQGNkY8lDQSNtw0BjZGPJQ0EjbcNAY2LjyUNBI23DQGNhw8lDQSM/o0BjYoPJQ0EjbcNAY2LjyUNBI23DQGNjQ8lDQSNtw0BjYoPJQ0EjbcNAY2LjyUNBIz+jQGNig8lDQSNtw0BjYuPJQ0EjbcNAY2NDyUNBI23DQGNkY8lDQSNtw0BjYuPJQ0EjbcNAY2RjyUNBI23DQGNjo8lDQSNtw0BjQMPJQ0EjbcNAY2KDyUNBI23DQGNAA8lDQSNtw0BjZGPJQ0EjbcNAY0DDyUNBI0GDyUNB48lDyUNDY8lDQkPJQ8lDQ2PJQ0PDyUPJQ0NjyUNCo8lDyUNDY8lDQwPJQ8lDQ2PJQ0PDyUPJQ0bDyUNFQ8lDyUNGw8lDRaPJQ8lDRsPJQ0cjyUPJQ0bDyUNEI8lDyUNGw8lDRIPJQ8lDROPJQ0VDyUPJQ0bDyUNFo8lDyUNGw8lDRgPJQ8lDRsPJQ0ZjyUPJQ0bDyUNHI8lDyUNIQ8lDSWPJQ8lDSEPJQ0eDyUPJQ0hDyUNH48lDyUNIQ8lDSKPJQ8lDSQPJQ0ljyUPJQ05DTqNNg8lDyUNOQ06jTGPJQ8lDTkNOo08DyUPJQ05DTqNKI8lDyUNMA06jTwPJQ8lDTkNOo0ojyUPJQ05DTqNJw8lDyUNOQ06jSiPJQ8lDTkNOo08DyUPJQ05DTqNPA8lDyUNOQ06jSoPJQ8lDTANOo08DyUPJQ05DTqNKg8lDyUNOQ06jSuPJQ8lDTkNOo0tDyUPJQ05DTqNMY8lDyUNOQ06jS6PJQ8lDTANOo02DyUPJQ05DTqNMY8lDyUNOQ06jTMPJQ8lDTkNOo08DyUPJQ05DTqNNI8lDyUNOQ06jTYPJQ8lDTkNOo03jyUPJQ05DTqNN48lDyUNOQ06jTwPJQ8lDyUPJQ09jyUPJQ8lDyUNPw8lDyUNQI8lDUINQ41FDViNWg1PjyUPJQ1YjVoNUQ8lDyUNWI1aDVuPJQ8lDViNWg1bjyUPJQ1YjVoNW48lDyUNWI1aDVuPJQ8lDViNWg1GjyUPJQ1ODVoNW48lDyUNWI1aDUaPJQ8lDViNWg1IDyUPJQ1YjVoNSY8lDyUNWI1aDVEPJQ8lDViNWg1LDyUPJQ1YjVoNTI8lDyUNTg1aDU+PJQ8lDViNWg1RDyUPJQ1YjVoNUo8lDyUNWI1aDVuPJQ8lDViNWg1UDyUPJQ1YjVoNVY8lDyUNWI1aDVWPJQ8lDdmPJQ1XDyUPJQ1YjVoNW48lDyUNXQ1ejWAPJQ8lDWePJQ1pDWqNc41njyUNYY1qjXONZ48lDWkNao1zjWMPJQ1pDWqNc41njyUNaQ1qjXONYw8lDWkNao1zjWePJQ1kjWqNc41mDyUNaQ1qjXONZ48lDWkNao1zjWwPJQ1tjyUPJQ11DyUNew18jX4Nbw8lDXCNcg1zjXUPJQ17DXyNfg11DyUNew18jX4NeA8lDXsNfI1+DXUPJQ12jXyNfg14DyUNew18jX4NeY8lDXsNfI1+DYQPJQ1/jyUPJQ2EDyUNhY8lDyUNhA8lDYEPJQ8lDYQPJQ2CjyUPJQ2EDyUNhY8lDyUNkA8lDYoPJQ8lDZAPJQ2LjyUPJQ2QDyUNkY8lDyUNkA8lDYcPJQ8lDYiPJQ2KDyUPJQ2QDyUNi48lDyUNkA8lDY0PJQ8lDZAPJQ2OjyUPJQ2QDyUNkY8lDyUNlg8lDZqPJQ8lDZYPJQ2TDyUPJQ2WDyUNlI8lDyUNlg8lDZePJQ8lDZkPJQ2ajyUPJQ7UDayNqY8lDyUO1A2sjaUPJQ8lDtQNrI2uDyUPJQ7UDayNnY8lDyUOBQ2sja4PJQ8lDtQNrI2djyUPJQ7UDayNnA8lDyUO1A2sjZ2PJQ8lDtQNrI2uDyUPJQ7UDayNrg8lDyUO1A2sjZ8PJQ8lDgUNrI2uDyUPJQ7UDayNnw8lDyUO1A2sjaCPJQ8lDtQNrI2iDyUPJQ7UDayNpQ8lDyUO1A2sjaOPJQ8lDgUNrI2pjyUPJQ7UDayNpQ8lDyUO1A2sjaaPJQ8lDtQNrI2uDyUPJQ7UDayNqA8lDyUO1A2sjamPJQ8lDtQNrI2rDyUPJQ7UDayNqw8lDyUO1A2sja4PJQ8lDbEPJQ2vjyUPJQ2xDyUNso8lDyUNvQ8lDbQPJQ8lDbcPJQ6/DyUPJQ23DyUNtY8lDyUNtw8lDrePJQ8lDbcPJQ6/DyUPJQ23DyUNtY8lDyUNtw8lDrePJQ8lDbcPJQ66jyUPJQ29DyUOAg6eDyUNuI8lDboNu48lDb0PJQ39jp4PJQ2+jyUNwA3BjyUNww8lDgIOng8lDcSPJQ4CDp4PJQ3GDyUNx46eDyUN2Y3bDdgPJQ8lDdmN2w3SDyUPJQ3ZjdsN3I8lDyUN2Y3bDdyPJQ8lDdmN2w3cjyUPJQ3ZjdsN3I8lDyUN2Y3bDckPJQ8lDdCN2w3cjyUPJQ3ZjdsNyQ8lDyUN2Y3bDcqPJQ8lDdmN2w3MDyUPJQ3ZjdsN0g8lDyUN2Y3bDc2PJQ8lDdmN2w3PDyUPJQ3QjdsN2A8lDyUN2Y3bDdIPJQ8lDdmN2w3TjyUPJQ3ZjdsN3I8lDyUN2Y3bDdUPJQ8lDdmN2w3WjyUPJQ3ZjdsN1o8lDyUN2Y3bDdgPJQ8lDdmN2w3cjyUPJQ60jyUOtg8lDyUN348lDd4PJQ8lDd+PJQ3hDyUPJQ8BDyUOvw8lDyUPAQ8lDrePJQ8lDwEPJQ63jyUPJQ8BDyUOt48lDyUO9o8lDr8PJQ8lDwEPJQ66jyUPJQ8BDyUOvA8lDyUPAQ8lDr8PJQ8lDh6PJQ4dDeiPJQ3ijyUN5A3ljyUN5w8lDh0N6I8lDh6PJQ4gDeiPJQ4ejyUOIA3ojyUOGI8lDh0N6I8lDfYN9430jyUPJQ32DfeN9I8lDyUN9g33jfAPJQ8lDfYN9435DyUPJQ32DfeN+Q8lDyUN9g33jfAPJQ8lDfYN943qDyUPJQ32DfeN648lDyUN9g33je0PJQ8lDe6N9430jyUPJQ32DfeN8A8lDyUN9g33jfGPJQ8lDfYN9435DyUPJQ8lDyUOyA8lDyUN9g33jfMPJQ8lDfYN9430jyUPJQ32DfeN+Q8lDyUPJQ8lDfqPJQ8lDyUPJQ38DyUPJQ4AjyUOAg8lDyUOAI8lDf2PJQ8lDf8PJQ4CDyUPJQ4AjyUOAg8lDyUO1A8lDgmO1w7YjtQPJQ4DjtcO2I7UDyUOCY7XDtiOBQ8lDgmO1w7YjtQPJQ4JjtcO2I4FDyUOCY7XDtiO1A8lDgaO1w7YjggPJQ4JjtcO2I4LDyUODI4ODg+OEQ8lDhQPJQ8lDhKPJQ4UDyUPJQ4ejyUOHQ8lDyUOHo8lDhWPJQ8lDh6PJQ4gDyUPJQ4YjyUOHQ8lDyUOHo8lDhcPJQ8lDhiPJQ4dDyUPJQ4ejyUOGg8lDyUOG48lDh0PJQ8lDh6PJQ4gDyUPJQ4zjjUOLw44DjmOM441DiwOOA45jjOONQ4yDjgOOY4zjjUOMg44DjmOM441DiGOOA45jikONQ4yDjgOOY4zjjUOIY44DjmOM441DiMOOA45jjOONQ4kjjgOOY4zjjUOLA44DjmOM441DiYOOA45jjOONQ42jjgOOY4zjjUOJ444DjmOKQ41Di8OOA45jjOONQ4sDjgOOY4zjjUOKo44DjmOM48lDi8PJQ8lDjOPJQ4sDyUPJQ4pDyUOLw8lDyUOM48lDiwPJQ8lDjOPJQ4qjyUPJQ4zjyUOMg8lDyUOM441DiwOOA45jjOONQ4yDjgOOY4zjjUOLY44DjmOM441DjaOOA45jjOONQ42jjgOOY8lDyUOLw8lDyUOMI41DuYOOA45jjCONQ7ejjgOOY4zjjUOMg44DjmOM441DjaOOA45jjOONQ42jjgOOY4zjjUONo44DjmOOw8lDjyPJQ8lDyUPJQ4+DyUPJQ5CjyUORw8lDyUOQo8lDj+PJQ8lDkKPJQ5EDyUPJQ5BDyUORw8lDyUOQo8lDj+PJQ8lDkEPJQ5HDyUPJQ5CjyUORA8lDyUORY8lDkcPJQ8lDk6PJQ5QDyUPJQ5OjyUOSI8lDyUOTo8lDkoPJQ8lDk6PJQ5NDyUPJQ5OjyUOS48lDyUOTo8lDlAPJQ8lDk6PJQ5NDyUPJQ5RjyUOUA8lDyUOTo8lDlMPJQ8lDlGPJQ5QDyUPJQ5RjyUOUw8lDyUOVg8lDlwOXY8lDlYPJQ5cDl2PJQ5WDyUOVI5djyUOVg8lDlwOXY8lDlkPJQ5cDl2PJQ5WDyUOV45djyUOWQ8lDlwOXY8lDlqPJQ5cDl2PJQ8BDl8O/I8lDmCPAQ5fDvmPJQ5gjwEOXw7/jyUOYI8BDl8O/48lDmCPAQ5fDv+PJQ5gjwEOXw75jyUOYI8BDl8O9Q8lDmCO9o5fDvyPJQ5gjwEOXw75jyUOYI8BDl8O+A8lDmCPAQ5fDvyPJQ5gjwEOXw75jyUOYI72jl8O/I8lDmCPAQ5fDvmPJQ5gjwEOXw74DyUOYI8BDl8O/48lDmCPAQ5fDvmPJQ5gjwEOXw7/jyUOYI8BDl8O+w8lDmCPAQ5fDwQPJQ5gjwEOXw7+DyUOYI8BDl8O/48lDmCPAQ5fDwQPJQ5gjmaPJQ5iDyUPJQ5mjyUOaA8lDyUOZo8lDmOPJQ8lDmaPJQ5lDyUPJQ5mjyUOaA8lDyUOdA8lDm4PJQ8lDnQPJQ5vjyUPJQ50DyUOdY8lDyUOdA8lDmmPJQ8lDnQPJQ5rDyUPJQ5sjyUObg8lDyUOdA8lDm+PJQ8lDnQPJQ5xDyUPJQ50DyUOco8lDyUOdA8lDnWPJQ8lDnoPJQ5+jyUPJQ56DyUOdw8lDyUOeg8lDniPJQ8lDnoPJQ57jyUPJQ59DyUOfo8lDyUOkg6Tjo8PJQ8lDpIOk46KjyUPJQ6SDpOOlQ8lDyUOkg6TjoGPJQ8lDokOk46VDyUPJQ6SDpOOgY8lDyUOkg6TjoAPJQ8lDpIOk46BjyUPJQ6SDpOOlQ8lDyUOkg6TjpUPJQ8lDpIOk46DDyUPJQ6JDpOOlQ8lDyUOkg6TjoMPJQ8lDpIOk46EjyUPJQ6SDpOOhg8lDyUOkg6TjoqPJQ8lDpIOk46HjyUPJQ6JDpOOjw8lDyUOkg6TjoqPJQ8lDpIOk46MDyUPJQ6SDpOOlQ8lDyUOkg6Tjo2PJQ8lDpIOk46PDyUPJQ6SDpOOkI8lDyUOkg6TjpCPJQ8lDpIOk46VDyUPJQ6YDyUOlo8lDyUOmA8lDpmPJQ8lDpsPJQ6cjp4PJQ6wDrGOro8lDyUOsA6xjqiPJQ8lDrAOsY6zDyUPJQ6wDrGOsw8lDyUOsA6xjrMPJQ8lDrAOsY6zDyUPJQ6wDrGOn48lDyUOpw6xjrMPJQ8lDrAOsY6fjyUPJQ6wDrGOoQ8lDyUOsA6xjqKPJQ8lDrAOsY6ojyUPJQ6wDrGOpA8lDyUOsA6xjqWPJQ8lDqcOsY6ujyUPJQ6wDrGOqI8lDyUOsA6xjqoPJQ8lDrAOsY6zDyUPJQ6wDrGOq48lDyUOsA6xjq0PJQ8lDrAOsY6tDyUPJQ8lDyUOro8lDyUOsA6xjrMPJQ8lDrSPJQ62DyUPJQ69jyUOvw8lDyUOvY8lDrePJQ8lDr2PJQ63jyUPJQ69jyUOt48lDyUOuQ8lDr8PJQ8lDr2PJQ66jyUPJQ69jyUOvA8lDyUOvY8lDr8PJQ8lDsyOzg7LDyUPJQ7Mjs4Oyw8lDyUOzI7ODsUPJQ8lDsyOzg7PjyUPJQ7Mjs4Oz48lDyUOzI7ODsUPJQ8lDsyOzg7AjyUPJQ7Mjs4Owg8lDyUOw47ODssPJQ8lDsyOzg7FDyUPJQ7Mjs4Oxo8lDyUOzI7ODs+PJQ8lDyUPJQ7IDyUPJQ7Mjs4OyY8lDyUOzI7ODssPJQ8lDsyOzg7PjyUPJQ8lDyUO0Q8lDyUPJQ8lDtKPJQ8lDtQPJQ7VjtcO2I7aDyUO3Q8lDyUO248lDt0PJQ8lDuePJQ7mDyUPJQ7njyUO3o8lDyUO548lDukPJQ8lDuGPJQ7mDyUPJQ7njyUO4A8lDyUO4Y8lDuYPJQ8lDuePJQ7jDyUPJQ7kjyUO5g8lDyUO548lDukPJQ8lDuwPJQ7yDvOPJQ7sDyUO8g7zjyUO7A8lDuqO848lDuwPJQ7yDvOPJQ7vDyUO8g7zjyUO7A8lDu2O848lDu8PJQ7yDvOPJQ7wjyUO8g7zjyUPAQ8CjvyPJQ8FjwEPAo75jyUPBY8BDwKO/48lDwWPAQ8Cjv+PJQ8FjwEPAo7/jyUPBY8BDwKO+Y8lDwWPAQ8CjvUPJQ8FjvaPAo78jyUPBY8BDwKO+Y8lDwWPAQ8CjvgPJQ8FjwEPAo78jyUPBY8BDwKO+Y8lDwWO9o8CjvyPJQ8FjwEPAo75jyUPBY8BDwKO+A8lDwWPAQ8Cjv+PJQ8FjwEPAo75jyUPBY8BDwKO/48lDwWPAQ8CjvsPJQ8FjwEPAo8EDyUPBY8BDwKO/I8lDwWPAQ8Cjv4PJQ8FjwEPAo7/jyUPBY8BDwKPBA8lDwWPC48lDwcPJQ8lDwuPJQ8NDyUPJQ8LjyUPCI8lDyUPC48lDwoPJQ8lDwuPJQ8NDyUPJQ8ZDyUPEw8lDyUPGQ8lDxSPJQ8lDxkPJQ8ajyUPJQ8ZDyUPDo8lDyUPGQ8lDxAPJQ8lDxGPJQ8TDyUPJQ8ZDyUPFI8lDyUPGQ8lDxYPJQ8lDxkPJQ8XjyUPJQ8ZDyUPGo8lDyUPHw8lDyOPJQ8lDx8PJQ8cDyUPJQ8fDyUPHY8lDyUPHw8lDyCPJQ8lDyIPJQ8jjyUPJQAAQFuA7sAAQFuA7AAAQIWA40AAQHwA6EAAQFuA7YAAQFu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AFYAZQB0AIMAkQCgAK8AvgDNANwA6wD6AQkBGAEnATYAAP//ABUADAAbACoAOQBIAFcAZgB1AIQAkgChALAAvwDOAN0A7AD7AQoBGQEoATcAAP//ABUADQAcACsAOgBJAFgAZwB2AIUAkwCiALEAwADPAN4A7QD8AQsBGgEpATgAAP//ABUADgAdACwAOwBKAFkAaAB3AIYAlACjALIAwQDQAN8A7gD9AQwBGwEqATkBOmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNjbXAHgmNjbXAHgmNjbXAHgmNjbXAHgmNjbXAHgmNjbXAHcmNjbXAHgmNjbXAHgmNjbXAHgmNjbXAHgmNjbXAHgmNjbXAHgmNjbXAHgmNjbXAHgmNjbXAHgmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxvY2wHsGxvY2wHtmxvY2wHvGxvY2wHwmxvY2wHyGxvY2wHzmxvY2wH1GxvY2wH2mxvY2wH4GxvY2wH5mxvY2wH7GxvY2wH8mxvY2wH+GxvY2wH/m51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQgAAAAIAAAABAAAAAQAkAAAAAQAmAAAABgACAAMABAAFAAYABwAAAAQAAgADAAQABQAAAAEAJwAAAAEAGgAAAAMAGwAcAB0AAAABACgAAAABACAAAAABABEAAAABABUAAAABABQAAAABABIAAAABABMAAAABABAAAAABAAkAAAABAA8AAAABAAwAAAABAAsAAAABAAgAAAABAAoAAAABAA0AAAABAA4AAAABABkAAAABACMAAAACAB4AHwAAAAEAIQAAAAEAKQAAAAEAFwAAAAEAJQAAAAEAKgAAAAEAFgAAAAEAGAAAAAEAIgAtAFwG3hGaEkgSrhKuFAIUAhSsFNoVHhUeFUAVQBVAFUAVQBVUFcIV1hX8FhYWPBZKFlgWiBZmFnQWiBaWFt4XJhdIF2AXeBeQF64Z+BxUHUYdZh2OHY4iniM4AAEAAAABAAgAAgRCAh4C+wL8Av0C/gL/AwADAQMCAwMDBAMFAwYDBwMIAyIDIwMtAy4DLwMwAzEDMgNHA0gDSQNLA0wDTQNOA08DUANRA1IDUwNhA2IDYwNkA2UDZgNnA2gDaQNqA2sDbANtA24DbwNwA3EDcgNzA3QDdQN2A3cDeAN5A3oDewN8A30DfgN/A4ADgQOCA4MDhAOGA4cDiAOJA4oDiwOMA40DjgOPA5ADkQOSA5MDlQOWA5cDmAOZA5oDuwPBAvsC/AL9Av4C/wMAAwEDAgMDAwQDBQMGAwcDCAMiAyMDJQMmAycDKAMpAyoDKwMsAy0DLgMvAzADMQMyAzQDNQM3AzgDOQM6AzsDPAM9Az4DPwNAA0EDQgNDA0QDRgNHA0gDSQNKA1QDVQNWA1cDWANZA1oDWwNcA10DXgNfA2EDYgNjA2QDZQNmA2cDaANpA2oDawNsA20DbgNvA3ADcQNyA3MDdAN1A3YDdwN4A3kDegN7A3wDfQN+A38DgAOBA4MDhAOFA4YDhwOIA4kDigOLA4wDjQOOA48DkAORA5IDkwOVA5YDlwOYA5kDmgOjA6QDpQOmA6cDqAOpA6oDqwOsA60DrgOvA7ADsQOyA7MDtAO1A7YDtwO4A7kDugO7A8EDxgM2At0C3gPRA9ID0wPUA9UD1gPXA9gD2QPaA9sD3APdA94D3wPgA+ED4gPjA+QD5QPmA+cD6APpA+oD6wPsA+0D7gPvA/AD8QPyA/MD9AP1A/YD9wP4A/kD+gP7A/wD/QP+A/8EAAQBBAIEAwQEBAUEBgQHBAgECQQKBAsEDAQNBA4EDwQQBBEEEgQTBBQEFQQWBBcEGAQZBBoEGwQcBB0EHgQfBCAEIQQiBCMEJAQlBCYEJwQoBCkEKgQrBCwELQQuBC8EMAQxBDIEMwQ0BDUENgQ3BDgEOQQ6BDsEPAQ9BD4EPwRABEEEQgRDBEQERQRGBEcESARJBEoESwRMBE0ETgRPBFAEUQRSBFMEVARVBFYEVwRYBFkEWgRbBFwEXQReBF8EYARhBGIEYwTjBOUE5gTnBOgE6QTrBOoE7QTuBO8E8ATyBPME9AT1BPYE9wT4BN8E4AT5BPoE+wT8BP0E/gT/BQAFAQUCBQMFBAUFBZoFlQV9BZQFnAWdBZ4FgAWBBaEFhQWGBYcFowWlBaYFigWLBYwFjQWpBaoFqwWQBawFkQWSBZMFrQWuBa8FsAWxBbIFswW0BbUFtgW3BbgFuQX8Bf0F/gX/BgAGAQYCBgMGBAYFBjYGOAZgBmEGZgZnBmgGaQZwBjkGQgZDBkQGRQZGBkcGTwZQBlEGagZrBmwGbQZuBm8GuQa6BrsGvAbcBt4G3QcKBwsHDAcNBw4HDwcQBxEHEgcTBxQHFQcWBxcHGAcZBxoHGwccBx0HHgcfByAHIQciByMHJAdWByYHZgdnB2gHaQdqB2sHbAdtAAIAXgAgACgAAAAqAC4ACQBHAEgADgBSAFcAEABqAG0AFgBvAHYAGgCFAKgAIgCqALcARgC5AL4AVADfAN8AWgDlAOUAWwGmAbMAXAHNAc4AagHQAd0AbAHfAe4AegHxAfUAigH/AgIAjwIEAgsAkwINAi0AmwIvAj8AvAJBAkYAzQJQAmgA0wJuAm4A7AJzAnMA7QJ+An4A7gLbAtwA7wLfAvoA8QMJAyEBDQMkAywBJgMzAzsBLwM9A0YBOANRA1EBQgNUA18BQwOFA4UBTwObA7oBUAO8A8ABcAPCA9ABdQRmBGYBhARtBG8BhQRyBHUBiAR9BH0BjAR/BIEBjQSJBI0BkASTBJMBlQSYBJgBlgScBJwBlwSfBJ8BmASqBKoBmQS8BL8BmgTFBMYBngTLBM0BoATQBNABowTWBNYBpATYBNgBpQUGBQgBpgUKBQoBqQUNBREBqgUVBRYBrwUYBRgBsQUaBRoBsgUdBR0BswUgBSEBtAUkBScBtgUrBS0BugU1BTUBvQU4BTgBvgU8BTwBvwU/BT8BwAVJBUkBwQVdBWIBwgVmBWcByAVsBW4BygVxBXEBzQV5BXkBzgYGBg8BzwYlBiUB2QYnBicB2gYrBiwB2wYuBjIB3QY7BkEB4gZIBkkB6QZMBkwB6wZWBlsB7AavBq8B8gaxBrEB8wazBrMB9Aa1BrUB9QbKBssB9gbYBtgB+AbfBuoB+QbsBu8CBQbyBvwCCQcHBwgCFAdeB2UCFgADAAAAAQAIAAEJtAEyAmoCcgJ4An4ChAKKApAClgKcAqICqAKuArQCugLAAsYCzALSAtgC3gLkAuoC8AL2AvwDAgMIAw4DFAMaAyADJgMsAzIDOAM+A0QDSgNQA1YDXANiA2gDbgN0A3oDgAOGA4wDkgOYA54DpAOqA7ADtgO8A8IDyAPOA9QD2gPgA+YD7APyA/gD/gQEBAoEEAQWBBwEIgQoBC4ENAQ6BEAERgRMBFIEWAReBGQEagRwBHYEfASCBIgEjgSUBJoHdgSgBKYErASyBLgEvgTEBMwE0gTYBN4E5ATqBPAE9gT8BQIFCAUOBRQFGgUgBSYFLAUyBTgFPgVEBUoFUAVWBVwFYgVoBW4FdAV6BYAFhgWMBZIFmAWeBaQFqgWwBbYFvAXCBcgFzgXUBdoF4AXmBewF9AX6BgAGBgYMBhIGGAYeBiQGKgYwBjYGPAZCBkgGTgZUBloGYAZmBmwGcgZ4Bn4GhAaKBpAGlgacBqIGqAauBrQGugbABsYGzAbSBtgG3gbkBuoG8Ab2BvwHAgcIBw4HFAcaByAHJgcsBzIHOgdAB0YHTAdSB1gHXgdkB2oHcAd2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AQIBAwEEAQUBBgEHAQgBCQEKAQsBDAENAQ4BDwEQAREBEgETARQBFQEWARcBGAEZARoBGwEcAR0BHgEfASABIQEiASMBJAElASYBJwEoASkBKgErASwBLQEuAS8BMAExATIBMwE0ATUBNgE4ATkBOgE7ATwBPQE+AT8BQAFBAUIBQwFEAUUBRgFHAUgBSQFKAUsBTAFNAU4BTwFQAVEBUgFTAVQBVQFWAVcBWAFZAVoBWwFcAV0BXgFfAWABYQFiAWMBZAFlAWYBZwFoAWkBagFrAWwBbQFuAW8BcAFxAXIBcwF0AXUBdgF3AXgBeQF6AXsBfAF9AX4BfwGAAYEBggGDAYQBhQGGAYcBiAGJATcCfwKAAoECggKDAoQChQKGAocCiAKJAooCiwKMAo0CjgKPApACkQKSApMClAKVApYClwKYApkCmgKbApwCnQKeAp8CoAKhAqICowKkAqUCpgKnAqgCqQKqAqsCrAKtAq4CrwKwArECsgKzArQCtQK2ArcCuAK5AroCuwK8Ar0CvgK/AsACwQLCAsMCxALFAsYCxwLIAskCygLLAswCzQLOAs8C0ALRAtIC0wLUAtUC1gLXAtgC2QLdAt4D0QPSA9MD1APVA9YD1wPYA9kD2gPbA9wD3QPeA98D4APhA+ID4wPkA+UD5gPnA+gD6QPqA+sD7APtA+4D7wPwA/ED8gPzA/QD9QP2A/cD+AP5A/oD+wP8A/0D/gP/BAAEAQQCBAMEBAQFBAYEBwQIBAkECgQLBAwEDQQOBA8EEAQRBBIEEwQUBBUEFgQXBBgEGQQaBBsEHAQdBB4EHwQgBCEEIgQjBCQEJQQmBCcEKAQpBCoEKwQsBC0ELgQvBDAEMQQyBDMENAQ1BDYENwQ4BDkEOgQ7BDwEPQQ+BD8EQARBBEIEQwREBEUERgRHBEgESQRKBEsETARNBE4ETwRQBFEEUgRTBFQEVQRWBFcEWARZBFoEWwRcBF0EXgRfBGAEYQRiBGME4wTkBOUE5gTnBOgE6QTrBOoE7ATtBO4E7wTwBPEE8gTzBPQE9QT2BPcE+AT5BPoE+wT8BP0E/gT/BQAFAQUCBQMFBAUFBZoFmwWcBZ0FngWfBaAFogWhBaMFpAWlBaYFpwWoBakFqgWrBawFrQWuBa8FsAWxBbIFswW0BbUFtgW3BbgFuQbdAAIAPQAEAB8AAAApACkAHAAvAEYAHQBJAFEANQBYAGkAPgBuAG4AUAB3AIMAUQCpAKkAXgC/AN4AXwDgAOQAfwDmAPUAhAGKAaUAlAG0AcwAsAHPAc8AyQH2Af4AygIuAi4A0wJIAk8A1AJpAm0A3AJvAnIA4QJ0An0A5QLbAtwA7wLfAvoA8QMJAyEBDQMkAywBJgMzAzsBLwM9A0YBOANRA1EBQgNUA18BQwOFA4UBTwObA7oBUAO8A8ABcAPCA9ABdQRmBGYBhARsBG8BhQRyBHUBiQR4BHgBjQR9BH0BjgR/BIIBjwSJBI0BkwSTBJMBmASYBJgBmQSqBKoBmgS8BL8BmwTFBMYBnwTLBM0BoQTQBNABpATWBNYBpQTYBNgBpgUGBQYBpwUMBQ8BqAUSBRUBrAUdBR0BsAUfBSEBsQUpBS0BtAU4BTgBuQVdBWIBugVmBWcBwAVsBW4BwgVxBXEBxQV5BXkBxgbYBtgBxwABAAAAAQAIAAIAWAApAd8B8AY7BwoHCwcMBw0HDgcPBxAHEQcSBxMHFAcVBxYHFwcYBxkHGgcbBxwHHQceBx8HIAchByIHIwckByUHJgcnB2YHZwdoB2kHagdrB2wHbQACAAkB3gHeAAAB7wHvAAEGJgYmAAIG3wbqAAMG7AbvAA8G8gb8ABMHBgcGAB4HCAcJAB8HXgdlACEAAQAAAAEACAACACQADwRkBGUEZARlBfwF/QX+Bf8GAAYBBgIGAwYEBgUGOQABAA8ABACEAYoCDAYGBgcGCAYJBgoGCwYMBg0GDgYPBiYAAA==) format("truetype")}@font-face{font-weight:normal;font-family:"tick42-icons";font-style:normal;src:url(data:font/ttf;base64,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YGAGCAcGqgJK/bYCgP1KJhsaARscJQK2JhsaARscJQAAAQAAAAEAAH2fuHdfDzz1AAsEAAAAAADhVnMIAAAAAOFWcwj//f+9BQADwwAAAAgAAgAAAAAAAAABAAADwP/AAAAFJP/9//0FAAABAAAAAAAAAAAAAAAAAAAA9wQAAAAAAAAAAAAAAAIAAAAEAAAABAAAAAO2//8ESQAAA24AAANuAAACkf//A24AAAO2//8CSQAABAAAAAO2//8CAAAAAmYAAALNAAACHwAAAmYAAAJmAAACqwAAAeEAAAOFAAADhQAAA24AAAQAAAAEkf//AyQAAANWAAACZgAAAOEAAAJIAAADrgAAAysAAAOaAAAEAAAAA24AAAQAAAAEAAAABAAAAAQAAAAEAP/9A24AAAQAAAADWAAAAyQAAANuAAADbgAAA24AAAQAAAADtgAAAbYAAAQAAAAEAAAAA24AAANuAAADbgAAA24AAAQAAAAEAAAABAAAAAQAAAAEAQAABAAAAAQAAAAEAAAAApH//wQA//0EAAAABAD//QQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAAA24AAAO2AAAEAAAAA7b//wMkAAADJAAAAyQAAAQAAAAEAAAAA24AAANuAAADtgAAA7YAAAMkAAADtv//BAAAAAQAAAADbgAABEkAAALbAAADtv//A7b//wQAAAACSQAAAkkAAAFuAAABbgAAAtsAAAQAAAAC2wAABAAAAAO2AAADbgAAA24AAAO2AAADtgAAA7YAAANHAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAADJAAAAtsAAAMkAAADbgAABAAAAANuAAADtv//A7b//wJJAAACSQAAAkkAAAQAAAAEAAAABAAAAAQAAAAESQAABEkAAAQAAAAEAAAAA24AAANuAAACSQAAAkkAAAKRAAACkQAAAW4AAAFuAAACkQAAApEAAARJAAADbgAAA7b//wO2//8EAAAAA24AAAQAAAADtv//BEkAAAO2AAAESQAABAAAAAMkAAACSQAAA7b//wJJAAABbgAAAW4AAAKR//8DJAAAA7b//wKR//8DJAAAANsAAANuAAADbgAAA24AAANuAAACSQAAAkkAAANuAAADtgAAA7YAAAQAAAAEAAAAA24AAANuAAABtgAAAbYAAAQAAAAEAAAABAAAAAUkAAADbgAAA24AAANuAAADbgAAA24AAANuAAADbgAAA24AAANuAAADbgAAA24AAANuAAADbgAABJEAAASRAAAEkQAAA24AAASR//8Ekf//BJH//wSR//8Ekf//BJEAAAQAAAADbgAAA24AAANuAAADbgAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAO2//8DbgAABAAAAAQAAAAEkf//BAAAAAQAAAAAAAAAAAoAFAAeAQgBbAHkAk4DIgP+BEIIOAj2CTQJjAosCkoKZAqCCqQK0Ar8CyoLZguaC9IMNAzEDPINnA4gDl4OfA6wDvoPGg84D2wP0hAGEFQQhBD0EfgSOBJ8Ep4TVhO4FBoUYBXAFioWbBaqFzAXdBfiGFAY1hmWGpYcAhx2HQIdih64IAQgZiFGIhQjcCRuJKwk3iU4JbwmBCYeJjgmuCc6J9IoKihsKJAo0ikCKbIqQiq2KxYr0Cw+LIws+i2gLeguWi6SLxgvoC/8MCAwRjBqMI4wvjDuMRwxTDGIMcQyADI8MqIzGjNgM8o0HjR6NMg1fjbONx43Xjd8OFg4zjlcOdQ6SjrEOwY7SDtyO+Q8VDywPcA+Aj5EPmg+jD8GP5A/+kBUQLRBFEFcQcxCZELCQxRDZkO4RApEOERmRJREwkUkRXJF8EZuRzJHXEe4SAxIiEjQSURJrkniSppLiEv+TFRMlE0ITZpOFk5gTrhPEE9QT5xP7FBEUPZRyFH+UnxS/FOWVDBUyFViVY5VulXoVhZWXFbcV2pYSljeWWxZ4FpIWuJbjlwGXLZdEF2SXeBejF8OX7JgXGB6YLphSmG2YlJi7GNaY/xkdmTkZXRmKGbCZ3poHmiSaWBqSGsga6Zr1Gv4bERspm0SAAEAAAD3As4ADwAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAOAK4AAQAAAAAAAQAMAAAAAQAAAAAAAgAHAI0AAQAAAAAAAwAMAEUAAQAAAAAABAAMAKIAAQAAAAAABQALACQAAQAAAAAABgAMAGkAAQAAAAAACgAaAMYAAwABBAkAAQAYAAwAAwABBAkAAgAOAJQAAwABBAkAAwAYAFEAAwABBAkABAAYAK4AAwABBAkABQAWAC8AAwABBAkABgAYAHUAAwABBAkACgA0AOB0aWNrNDItaWNvbnMAdABpAGMAawA0ADIALQBpAGMAbwBuAHNWZXJzaW9uIDEuMABWAGUAcgBzAGkAbwBuACAAMQAuADB0aWNrNDItaWNvbnMAdABpAGMAawA0ADIALQBpAGMAbwBuAHN0aWNrNDItaWNvbnMAdABpAGMAawA0ADIALQBpAGMAbwBuAHNSZWd1bGFyAFIAZQBnAHUAbABhAHJ0aWNrNDItaWNvbnMAdABpAGMAawA0ADIALQBpAGMAbwBuAHNGb250IGdlbmVyYXRlZCBieSBJY29Nb29uLgBGAG8AbgB0ACAAZwBlAG4AZQByAGEAdABlAGQAIABiAHkAIABJAGMAbwBNAG8AbwBuAC4AAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA) format("truetype")}[class^="icon-"],[class*=" icon-"]{font-weight:normal;font-family:"tick42-icons";font-style:normal;font-variant:normal;line-height:1;text-transform:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.tick42-custom-icon i{color:var(--t42-link-color)}.tick42-custom-icon img{display:block}.tick42-custom-icon.disabled i,.tick42-custom-icon:disabled i{color:var(--t42-content-color-disabled)}i.disabled,.disabled i{color:var(--t42-content-color-disabled)}.icon-size-12 i{font-size:0.75rem}.icon-size-12 i,.icon-size-12 img{width:0.75rem;height:0.75rem}.icon-size-14 i{font-size:0.875rem}.icon-size-14 i,.icon-size-14 img{width:0.875rem;height:0.875rem}.icon-size-24 i{font-size:1.5rem}.icon-size-24 i,.icon-size-24 img{width:1.5rem;height:1.5rem}.icon-size-16 i,.icon-size-16 img{width:1rem;height:1rem}.icon-size-16 i{font-size:1rem}.icon-size-32 i,.icon-size-32 img{width:2rem;height:2rem}.icon-size-32 i{font-size:2rem}.icon-size-48 i,.icon-size-48 img{width:3rem;height:3rem}.icon-size-48 i{font-size:3rem}.icon-size-64 i,.icon-size-64 img{width:4rem;height:4rem}.icon-size-64 i{font-size:4rem}.icon-size-80 i,.icon-size-80 img{width:5rem;height:5rem}.icon-size-80 i{font-size:5rem}.icon-size-96 i,.icon-size-96 img{width:6rem;height:6rem}.icon-size-96 i{font-size:6rem}.icon-size-112 i,.icon-size-112 img{width:7rem;height:7rem}.icon-size-112 i{font-size:7rem}.icon-size-128 i,.icon-size-128 img{width:8rem;height:8rem}.icon-size-128 i{font-size:8rem}.icon-primary i::before{color:#007be5}.icon-secondary i::before{color:#616161}.icon-success i::before{color:#43a047}.icon-info i::before{color:#469eb9}.icon-warning i::before{color:#f9a825}.icon-danger i::before{color:#ff511f}.icon-light i::before{color:#616161}.icon-dark i::before{color:#616161}.icon-dev-tools::before{content:"\e901"}.icon-interop::before{content:"\e900"}.icon-mail::before{content:"\e800"}.icon-attention::before{content:"\e801"}.icon-print::before{content:"\e802"}.icon-picture::before{content:"\e803"}.icon-thumbs-up::before{content:"\e804"}.icon-thumbs-down::before{content:"\e805"}.icon-lock::before{content:"\e806"}.icon-globe::before{content:"\e807"}.icon-calendar::before{content:"\e808"}.icon-location::before{content:"\e809"}.icon-briefcase::before{content:"\e80a"}.icon-export::before{content:"\e80b"}.icon-play::before{content:"\e80c"}.icon-stop::before{content:"\e80d"}.icon-record::before{content:"\e80e"}.icon-pause::before{content:"\e80f"}.icon-to-end::before{content:"\e810"}.icon-to-start::before{content:"\e811"}.icon-check::before{content:"\e812"}.icon-cancel::before{content:"\e813"}.icon-fast-forward::before{content:"\e814"}.icon-fast-backward::before{content:"\e815"}.icon-attention-circled::before{content:"\e816"}.icon-bell::before{content:"\e817"}.icon-chart-bar::before{content:"\e818"}.icon-phone::before{content:"\e819"}.icon-doc-add::before{content:"\e81a"}.icon-layout::before{content:"\e81b"}.icon-dot::before{content:"\e81c"}.icon-dot-2::before{content:"\e81d"}.icon-dot-3::before{content:"\e81e"}.icon-resize-full-1::before{content:"\e81f"}.icon-resize-small-1::before{content:"\e820"}.icon-checkbox::before{content:"\e821"}.icon-cancel-circled::before{content:"\e822"}.icon-03-context-viewer::before{content:"\e823"}.icon-volume-off-1::before{content:"\e824"}.icon-volume::before{content:"\e825"}.icon-headphones-1::before{content:"\e826"}.icon-performance-report::before{content:"\e827"}.icon-pause-1::before{content:"\e828"}.icon-volume-up-1::before{content:"\e829"}.icon-volume-down-1::before{content:"\e82a"}.icon-trash-empty::before{content:"\e839"}.icon-resize-small::before{content:"\e83b"}.icon-resize-full::before{content:"\e83c"}.icon-doc::before{content:"\e83d"}.icon-cog::before{content:"\e83e"}.icon-wrench::before{content:"\e83f"}.icon-resize-vertical::before{content:"\e840"}.icon-resize-horizontal::before{content:"\e841"}.icon-edit::before{content:"\e842"}.icon-pencil-1::before{content:"\e843"}.icon-cw-2::before{content:"\e844"}.icon-ccw-1::before{content:"\e845"}.icon-arrows-cw-1::before{content:"\e847"}.icon-th-large::before{content:"\e848"}.icon-th::before{content:"\e849"}.icon-spin5::before{content:"\e84a"}.icon-spin6::before{content:"\e84b"}.icon-spin4::before{content:"\e84c"}.icon-spin3::before{content:"\e84d"}.icon-spin2::before{content:"\e84e"}.icon-spin1::before{content:"\e84f"}.icon-pin::before{content:"\e850"}.icon-trading-controls::before{content:"\e856"}.icon-icon-coverage::before{content:"\e857"}.icon-taxes::before{content:"\e858"}.icon-credit::before{content:"\e859"}.icon-checkbox-checked::before{content:"\e85a"}.icon-checkbox-indeterminate::before{content:"\e85b"}.icon-radio::before{content:"\e85c"}.icon-radio-choose::before{content:"\e85d"}.icon-arrow-up-down::before{content:"\e85e"}.icon-arrow-double-left::before{content:"\e85f"}.icon-arrow-double-right::before{content:"\e860"}.icon-floppy::before{content:"\e861"}.icon-logout::before{content:"\e862"}.icon-mail-1::before{content:"\e864"}.icon-search-1::before{content:"\e865"}.icon-plus-1::before{content:"\e866"}.icon-minus-1::before{content:"\e867"}.icon-cancel-1::before{content:"\e868"}.icon-ok::before{content:"\e869"}.icon-th-list::before{content:"\e86a"}.icon-help-circled::before{content:"\e86b"}.icon-info-circled::before{content:"\e86c"}.icon-home::before{content:"\e86d"}.icon-link-1::before{content:"\e86e"}.icon-attach-1::before{content:"\e86f"}.icon-lock-open-1::before{content:"\e870"}.icon-eye::before{content:"\e871"}.icon-eye-off::before{content:"\e872"}.icon-tag::before{content:"\e873"}.icon-tags::before{content:"\e874"}.icon-bookmark::before{content:"\e875"}.icon-download-1::before{content:"\e876"}.icon-upload-1::before{content:"\e877"}.icon-forward-1::before{content:"\e878"}.icon-down-dir::before{content:"\e879"}.icon-up-dir::before{content:"\e87a"}.icon-left-dir::before{content:"\e87b"}.icon-right-dir::before{content:"\e87c"}.icon-left-open-1::before{content:"\e87d"}.icon-down-open-1::before{content:"\e87e"}.icon-right-open-1::before{content:"\e87f"}.icon-up-open-1::before{content:"\e880"}.icon-down-big::before{content:"\e881"}.icon-left-big::before{content:"\e882"}.icon-right-big::before{content:"\e883"}.icon-up-big::before{content:"\e884"}.icon-asterisk::before{content:"\e885"}.icon-check-1::before{content:"\e886"}.icon-tick42-icon-monochrome::before{content:"\e887"}.icon-task-manager::before{content:"\e888"}.icon-context-viewer::before{content:"\e889"}.icon-help-2::before{content:"\e88a"}.icon-star-empty-1::before{content:"\e88b"}.icon-star-full::before{content:"\e902"}.icon-move::before{content:"\f047"}.icon-link-ext::before{content:"\f08e"}.icon-check-empty::before{content:"\f096"}.icon-bookmark-empty::before{content:"\f097"}.icon-filter::before{content:"\f0b0"}.icon-resize-full-alt::before{content:"\f0b2"}.icon-docs::before{content:"\f0c5"}.icon-menu-1::before{content:"\f0c9"}.icon-table::before{content:"\f0ce"}.icon-columns::before{content:"\f0db"}.icon-sort::before{content:"\f0dc"}.icon-sort-down::before{content:"\f0dd"}.icon-sort-up::before{content:"\f0de"}.icon-mail-alt::before{content:"\f0e0"}.icon-sitemap::before{content:"\f0e8"}.icon-paste::before{content:"\f0ea"}.icon-exchange::before{content:"\f0ec"}.icon-download-cloud::before{content:"\f0ed"}.icon-upload-cloud::before{content:"\f0ee"}.icon-suitcase-1::before{content:"\f0f2"}.icon-bell-alt::before{content:"\f0f3"}.icon-doc-text-1::before{content:"\f0f6"}.icon-plus-squared::before{content:"\f0fe"}.icon-angle-double-left::before{content:"\f100"}.icon-angle-double-right::before{content:"\f101"}.icon-angle-double-up::before{content:"\f102"}.icon-angle-double-down::before{content:"\f103"}.icon-angle-left::before{content:"\f104"}.icon-angle-right::before{content:"\f105"}.icon-angle-up::before{content:"\f106"}.icon-angle-down::before{content:"\f107"}.icon-laptop::before{content:"\f109"}.icon-circle-empty::before{content:"\f10c"}.icon-quote-left::before{content:"\f10d"}.icon-quote-right::before{content:"\f10e"}.icon-spinner::before{content:"\f110"}.icon-circle::before{content:"\f111"}.icon-reply-1::before{content:"\f112"}.icon-folder-empty::before{content:"\f114"}.icon-folder-open-empty::before{content:"\f115"}.icon-terminal::before{content:"\f120"}.icon-code::before{content:"\f121"}.icon-reply-all-1::before{content:"\f122"}.icon-direction::before{content:"\f124"}.icon-fork::before{content:"\f126"}.icon-unlink::before{content:"\f127"}.icon-help::before{content:"\f128"}.icon-info::before{content:"\f129"}.icon-attention-alt::before{content:"\f12a"}.icon-mic::before{content:"\f130"}.icon-mute::before{content:"\f131"}.icon-calendar-empty::before{content:"\f133"}.icon-lock-open-alt::before{content:"\f13e"}.icon-ellipsis::before{content:"\f141"}.icon-ellipsis-vert::before{content:"\f142"}.icon-minus-squared::before{content:"\f146"}.icon-ok-squared::before{content:"\f14a"}.icon-link-ext-alt::before{content:"\f14c"}.icon-expand-right::before{content:"\f152"}.icon-euro::before{content:"\f153"}.icon-dollar::before{content:"\f155"}.icon-doc-inv::before{content:"\f15b"}.icon-sort-name-up::before{content:"\f15d"}.icon-sort-name-down::before{content:"\f15e"}.icon-sort-alt-up::before{content:"\f160"}.icon-sort-alt-down::before{content:"\f161"}.icon-sort-number-up::before{content:"\f162"}.icon-sort-number-down::before{content:"\f163"}.icon-down::before{content:"\f175"}.icon-up::before{content:"\f176"}.icon-left::before{content:"\f177"}.icon-right::before{content:"\f178"}.icon-cube::before{content:"\f1b2"}.icon-cubes::before{content:"\f1b3"}.icon-database::before{content:"\f1c0"}.icon-file-pdf::before{content:"\f1c1"}.icon-file-word::before{content:"\f1c2"}.icon-file-excel::before{content:"\f1c3"}.icon-file-powerpoint::before{content:"\f1c4"}.icon-file-image::before{content:"\f1c5"}.icon-file-archive::before{content:"\f1c6"}.icon-file-audio::before{content:"\f1c7"}.icon-file-video::before{content:"\f1c8"}.icon-file-code::before{content:"\f1c9"}.icon-circle-thin::before{content:"\f1db"}.icon-sliders::before{content:"\f1de"}.icon-share::before{content:"\f1e0"}.icon-wifi::before{content:"\f1eb"}.icon-bell-off::before{content:"\f1f6"}.icon-bell-off-empty::before{content:"\f1f7"}.icon-copyright::before{content:"\f1f9"}.icon-chart-area::before{content:"\f1fe"}.icon-chart-line::before{content:"\f201"}.icon-toggle-off::before{content:"\f204"}.icon-toggle-on::before{content:"\f205"}.icon-user-plus::before{content:"\f234"}.icon-user-times::before{content:"\f235"}.icon-clone::before{content:"\f24d"}.icon-hourglass-o::before{content:"\f250"}.icon-hourglass-1::before{content:"\f251"}.icon-hourglass-2::before{content:"\f252"}.icon-hourglass-3::before{content:"\f253"}.icon-calendar-plus-o::before{content:"\f271"}.icon-calendar-minus-o::before{content:"\f272"}.icon-calendar-times-o::before{content:"\f273"}.icon-calendar-check-o::before{content:"\f274"}.icon-hashtag::before{content:"\f292"}.icon-low-vision::before{content:"\f2a8"}.icon-envelope-open-o::before{content:"\f2b7"}.icon-address-book-o::before{content:"\f2ba"}.icon-user-o::before{content:"\f2c0"}.icon-window-maximize::before{content:"\f2d0"}.icon-window-minimize::before{content:"\f2d1"}.icon-window-restore::before{content:"\f2d2"}.icon-window-close::before{content:"\f2d3"}.icon-window-close-o::before{content:"\f2d4"}.icon-app::before{content:"\e903"}.icon-download-arrow::before{content:"\e904"}.icon-logo::before{content:"\e905"}.icon-feedback::before{content:"\e906"}.icon-action::before{content:"\e907"}.icon-swimlane::before{content:"\e908"}div.ag-dnd-ghost{border-color:transparent;border-radius:0.25rem;color:var(--white);font-size:0.75rem;font-family:inherit;line-height:inherit;background-color:var(--primary);cursor:default}div .ag-dnd-ghost-icon{display:flex;float:none;padding:0 0.25rem 0 0}div .ag-dnd-ghost-icon .ag-icon{background-color:var(--white)}.ag-tick42{padding-top:0}.ag-tick42 a{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border;border-bottom:0.063rem dashed var(--dark);color:var(--t42-content-color)}.ag-tick42 a:hover{text-decoration:none}.ag-tick42 .ag-filter-body{margin:0}.ag-tick42 input{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border;padding:0 0.5rem;border:var(--t42-border);color:var(--t42-content-color);line-height:2rem;background-color:var(--t42-input-bg)}.ag-tick42 input:focus{border-color:var(--primary);outline:0}.ag-tick42 input.ag-column-name-filter{margin-left:0.5rem}.ag-tick42 .ag-input-wrapper{padding:0.25rem}.ag-tick42 .ag-input-wrapper.ag-checkbox-input-wrapper{padding:0}.ag-tick42 .ag-cell-wrapper.ag-row-group{align-items:center}.ag-tick42 .ag-cell{padding:0 0.25rem;border-bottom:var(--t42-border);line-height:1.875rem;white-space:nowrap;text-overflow:ellipsis}.ag-tick42 .ag-cell .btn,.ag-tick42 .ag-cell .btn-sm,.ag-tick42 .ag-cell .btn-group-sm>.btn,.ag-tick42 .ag-cell .btn-lg,.ag-tick42 .ag-cell .btn-group-lg>.btn{line-height:1.25rem}.ag-tick42 .ag-cell .btn-icon i{position:relative;top:0.0625rem}.ag-tick42 .ag-cell:focus{outline:1px solid var(--primary)}.ag-tick42 .ag-cell .dropdown-toggle{width:20px;height:20px;margin-top:-3px;padding:0;border:0;line-height:22px}.ag-tick42 .ag-cell .dropdown-toggle::after{background-color:transparent;content:""}.ag-tick42 .ag-row::before{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:width;position:absolute;top:0;bottom:0;left:0;z-index:1;width:0;background-color:var(--primary);content:""}.ag-tick42 .ag-row.ag-row-selected{color:var(--t42-link-color);background-color:var(--t42-color-opacity-10)}.ag-tick42 .ag-row.ag-row-selected .ag-icon{color:var(--t42-link-color)}.ag-tick42 .ag-pinned-left-header,.ag-tick42 .ag-pinned-left-cols-container,.ag-tick42 .ag-pinned-right-header,.ag-tick42 .ag-pinned-right-cols-container{background-color:Rgb(var(--t42-bg-mid))}.ag-tick42 .ag-pinned-left-cols-container .ag-row-selected::before,.ag-tick42 .ag-pinned-left-cols-container.ag-hidden+.ag-center-cols-clipper .ag-row-selected::before{width:2px}.ag-tick42 .ag-row-hover{background-color:var(--t42-color-opacity-10)}.ag-tick42 .ag-row-hover .ag-cell{color:var(--t42-link-color)}.ag-tick42 .ag-row-hover .ag-loading .ag-icon-loading::after{background:Rgb(var(--t42-bg-light))}.ag-tick42 .ag-row-hover a{border-bottom-color:var(--t42-content-color);color:var(--t42-link-color)}.ag-tick42 .ag-row-hover a:hover{border-bottom-style:solid}.ag-tick42 .ag-header-row:last-of-type{border-bottom:var(--t42-border)}.ag-tick42 .ag-header-cell,.ag-tick42 .ag-header-group-cell{padding:0 0.25rem;border-top:var(--t42-border);border-left:var(--t42-border);color:Hsl(var(--t42-content-color-base), calc(var(--t42-content-color-l) - 20%))}.ag-tick42 .ag-header-cell:first-of-type,.ag-tick42 .ag-header-group-cell:first-of-type{border-left:0}.ag-tick42 .ag-header-cell .ag-header-cell-label,.ag-tick42 .ag-header-cell .ag-header-group-cell-label,.ag-tick42 .ag-header-group-cell .ag-header-cell-label,.ag-tick42 .ag-header-group-cell .ag-header-group-cell-label{font-weight:normal;font-size:83.3%;line-height:1.875rem;text-transform:uppercase}.ag-tick42 .ag-header-cell .ag-header-select-all,.ag-tick42 .ag-header-group-cell .ag-header-select-all{margin-right:0.5rem}.ag-tick42 .ag-header-cell-moving{background-color:Hsl(var(--t42-bg-light-base), calc(var(--t42-bg-light-l) + 5%))}.ag-tick42 .ag-cell-inline-editing{padding-top:0}.ag-tick42 .ag-cell-edit-input{border-top:0;border-bottom:0;border-radius:0}.ag-tick42 .ag-icon{font-family:inherit}.ag-tick42 .ag-icon::before{content:""}.ag-tick42 .ag-react-container .btn-icon{margin-bottom:0.125rem;padding:0 0.5rem}.ag-tick42 .ag-tabs-header{display:flex;height:1.875rem;border-bottom:var(--t42-border);border-bottom-width:0.063rem}.ag-tick42 .ag-tabs-header .ag-tab{display:flex;align-items:center;justify-content:center;width:1.875rem;height:1.875rem;color:var(--primary);cursor:pointer}.ag-tick42 .ag-tabs-header .ag-tab.ag-tab-selected{background-color:var(--primary)}.ag-tick42 .ag-tabs-header .ag-tab.ag-tab-selected .ag-icon{background-color:var(--white)}.ag-tick42 .ag-tabs-body{max-height:280px;overflow:auto}.ag-tick42 .ag-menu,.ag-tick42 .ag-tool-panel{z-index:1040;border:var(--t42-border);border-radius:0;overflow:initial;background-color:rgba(var(--t42-bg-light), 0.75);box-shadow:var(--t42-shadow);backdrop-filter:var(--backdrop-filter)}.ag-tick42 .ag-menu .ag-column-select-column,.ag-tick42 .ag-menu .ag-column-select-column-group,.ag-tick42 .ag-tool-panel .ag-column-select-column,.ag-tick42 .ag-tool-panel .ag-column-select-column-group{display:flex;align-items:center;margin-left:0;line-height:2rem;cursor:pointer}.ag-tick42 .ag-menu .ag-column-select-column .ag-column-select-checkbox:hover,.ag-tick42 .ag-menu .ag-column-select-column-group .ag-column-select-checkbox:hover,.ag-tick42 .ag-tool-panel .ag-column-select-column .ag-column-select-checkbox:hover,.ag-tick42 .ag-tool-panel .ag-column-select-column-group .ag-column-select-checkbox:hover{color:var(--t42-link-color)}.ag-tick42 .ag-menu .ag-column-select-column:hover,.ag-tick42 .ag-menu .ag-column-select-column-group:hover,.ag-tick42 .ag-tool-panel .ag-column-select-column:hover,.ag-tick42 .ag-tool-panel .ag-column-select-column-group:hover{color:Hsl(var(--t42-content--base), 100%);background-color:var(--t42-color-opacity-10)}.ag-tick42 .ag-menu .ag-column-select-header,.ag-tick42 .ag-tool-panel .ag-column-select-header{padding:0.5rem}.ag-tick42 .ag-menu .ag-column-select-column-label,.ag-tick42 .ag-tool-panel .ag-column-select-column-label{margin-left:0.25rem}.ag-tick42 .ag-tab-body{max-height:220px;overflow:auto}.ag-tick42 .ag-tab-body .ag-set-filter-list{height:9rem}.ag-tick42 .ag-tab-body input{border:var(--t42-border)}.ag-tick42 .ag-tab-body input:focus{border-color:var(--primary)}.ag-tick42 .ag-menu-option{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:color;line-height:2rem;cursor:pointer}.ag-tick42 .ag-menu-option .ag-menu-option-icon{color:var(--t42-content-color)}.ag-tick42 .ag-menu-option .ag-menu-option-icon,.ag-tick42 .ag-menu-option .ag-menu-option-popup-pointer{width:2rem;color:var(--t42-content-color);text-align:center}.ag-tick42 .ag-menu-option .ag-menu-option-icon.ag-menu-option-popup-pointer,.ag-tick42 .ag-menu-option .ag-menu-option-icon:hover,.ag-tick42 .ag-menu-option .ag-menu-option-popup-pointer.ag-menu-option-popup-pointer,.ag-tick42 .ag-menu-option .ag-menu-option-popup-pointer:hover{color:var(--t42-content-color)}.ag-tick42 .ag-menu-option .ag-menu-option-icon.ag-menu-option-popup-pointer .ag-icon,.ag-tick42 .ag-menu-option .ag-menu-option-icon:hover .ag-icon,.ag-tick42 .ag-menu-option .ag-menu-option-popup-pointer.ag-menu-option-popup-pointer .ag-icon,.ag-tick42 .ag-menu-option .ag-menu-option-popup-pointer:hover .ag-icon{color:var(--t42-content-color)}.ag-tick42 .ag-menu-option.ag-menu-option-active{color:var(--t42-link-color);background-color:var(--t42-color-opacity-10)}.ag-tick42 .ag-menu-option.ag-menu-option-active .ag-icon{color:var(--t42-content-color)}.ag-tick42 .ag-menu-separator{border-bottom:var(--t42-border);border-bottom-color:var(--t42-color-opacity-10)}.ag-tick42 .ag-menu-column-select-wrapper,.ag-tick42 .ag-primary-cols-list-panel{height:auto}.ag-tick42 .ag-tool-panel .ag-pivot-mode{padding-top:0.5rem}.ag-tick42 .ag-column-tool-panel-column{padding:0 0.25rem}.ag-tick42 .ag-column-tool-panel-column .ag-icon{margin:0 0.25rem}.ag-tick42 .ag-column-tool-panel-column-label,.ag-tick42 span.ag-column-tool-panel-column-group{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;padding-left:0.25rem}.ag-tick42 .ag-column-tool-panel-column-group .ag-icon{margin:0 0.25rem 0 0}.ag-tick42 .ag-root+.ag-tool-panel{box-shadow:none}.ag-tick42 .ag-row-group-leaf-indent{margin-left:24px}.ag-tick42 .ag-group-expanded,.ag-tick42 .ag-group-contracted{display:flex;align-items:center;min-width:0.75rem;height:100%;margin-right:0.5rem}.ag-tick42 .ag-group-value .ag-react-container{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;display:inline;font-size:87.5%}.ag-tick42 .ag-popup-editor{box-shadow:var(--t42-shadow)}.ag-tick42 .ag-rich-select{border:var(--t42-border);border-radius:0;overflow-y:auto;background-color:Rgb(var(--t42-bg-light), 1)}.ag-tick42 .ag-rich-select-row{padding-left:0.75rem}.ag-tick42 .ag-rich-select-row-selected{background:var(--t42-color-opacity-10)}.ag-tick42 .ag-rich-select-value{position:relative;height:2rem;padding-left:0.75rem;border-bottom:var(--t42-border);line-height:2rem}.ag-tick42 .ag-rich-select-value::before{position:absolute;top:0;bottom:0;left:0;width:3px;background-color:var(--primary);content:""}.ag-tick42 .icon-window-maximize::before,.ag-tick42 .icon-window-minimize::before,.ag-tick42 .icon-window-ok::before{font-size:0.813rem}.ag-tick42 .ag-column-drop{border-top:var(--t42-border)}.ag-tick42 .ag-column-drop.ag-column-drop-horizontal{display:flex;height:1.875rem}.ag-tick42 .ag-column-drop.ag-column-drop-horizontal div{display:flex;align-items:center}.ag-tick42 .ag-column-drop.ag-column-drop-horizontal div:first-of-type{margin-right:0.25rem}.ag-tick42 .ag-column-drop .ag-column-drop-empty-message{align-self:center}.ag-tick42 .ag-column-drop .ag-column-drop-cell{display:flex;height:1.125rem;margin:0.125rem 0.25rem;padding:0 0.125rem 0 0.25rem;border-radius:0.25rem;background-color:Rgb(var(--t42-bg-light))}.ag-tick42 .ag-column-drop .ag-column-drop-cell .ag-column-drop-cell-text{padding:0 0.25rem;line-height:1.125rem}.ag-tick42 .ag-column-drop.ag-column-drop-vertical div{justify-content:start}.ag-tick42 .ag-column-drop.ag-column-drop-vertical .ag-icon-group{margin:0 0.25rem}.ag-tick42 .ag-right-arrow{width:1.5rem;padding:0 0.25rem;overflow:hidden;text-indent:-999px;background-color:var(--t42-content-color);transform:rotate(-90deg);-webkit-mask-image:var(--t42-select-indicator)}.ag-tick42 .ag-right-arrow::before{position:absolute;text-indent:999px}.ag-tick42 .ag-group-checkbox{display:flex;align-items:center;width:1rem;height:100%;margin-right:0.5rem}.ag-tick42 .ag-group-checkbox .ag-icon{width:0.875rem;height:0.875rem}.ag-tick42 .ag-group-checkbox:empty{width:initial}.ag-tick42 .ag-ltr .ag-toolpanel-indent-1{padding-left:1rem}.ag-tick42 .ag-ltr .ag-toolpanel-indent-2{padding-left:2rem}.ag-tick42 .ag-ltr .ag-toolpanel-indent-3{padding-left:3rem}.ag-tick42 .ag-ltr .ag-row-group-indent-1{padding-left:calc(1 * 1.45rem)}.ag-tick42 .ag-ltr .ag-row-group-indent-2{padding-left:calc(2 * 1.45rem)}.ag-tick42 .ag-ltr .ag-row-group-indent-3{padding-left:calc(3 * 1.45rem)}.ag-menu .ag-filter-checkbox{min-width:2rem}.ag-menu .ag-icon-checkbox-checked::after{width:0.625rem;height:0.625rem}.ag-menu .ag-column-group-icons{width:1.5rem}.ag-menu .ag-labeled.ag-label-align-right>div{margin-left:0.25rem}.ag-filter-panel{width:100%}.loading-filter{background-color:rgba(var(--t42-bg-light), 0.75);backdrop-filter:var(--backdrop-filter)}#selectAllContainer,.ag-set-filter-item{display:flex;align-items:center;cursor:pointer}#selectAllContainer .ag-filter-value,#selectAllContainer .ag-set-filter-item-value,.ag-set-filter-item .ag-filter-value,.ag-set-filter-item .ag-set-filter-item-value{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}#selectAllContainer .ag-set-filter-item-value,.ag-set-filter-item .ag-set-filter-item-value{margin-left:0.25rem}.ag-filter-checkbox{justify-content:center;min-width:2rem;color:var(--primary)}.ag-set-filter-item:hover,.ag-filter-header-container:hover label{color:var(--t42-link-color);background-color:var(--t42-color-opacity-10)}.ag-set-filter-item:hover .ag-icon,.ag-filter-header-container:hover label .ag-icon{color:var(--t42-link-color)}.ag-input-text-wrapper{padding:0.25rem 0.25rem 0}.ag-primary-cols-header-panel{align-items:center;padding:0.25rem 0.25rem 0.25rem 0}.ag-primary-cols-header-panel div:nth-child(1){width:1.25rem}.ag-primary-cols-header-panel div:nth-child(2){width:1rem;margin-right:0.25rem}.ag-filter-toolpanel-header{display:flex}.ag-filter-toolpanel-header .ag-header-cell-text{padding:0 0.25rem}.ag-filter-condition{justify-content:space-evenly;padding:0.5rem 0}.ag-filter-condition .ag-labeled.ag-label-align-right div{margin-left:0}.ag-radio-button-label{position:relative;color:var(--t42-content-color-muted);cursor:pointer;user-select:none}.ag-radio-button-input-wrapper::before{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, border;position:absolute;left:-1.125rem;display:block;width:0.875rem;height:0.875rem;border:0.0625rem solid var(--t42-content-color-muted);border-radius:50%;cursor:pointer;content:"";pointer-events:all}.ag-radio-button-input-wrapper::after{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, border;position:absolute;left:-0.875rem;display:block;width:0.375rem;height:0.375rem;border-radius:50%;color:var(--white);background-image:none;transform:scale(0);opacity:0;content:""}.ag-radio-button-input-wrapper:focus{border-color:var(--primary)}.ag-radio-button-input-wrapper.ag-checked::before{border-color:var(--t42-color-opacity-30);background-color:var(--primary)}.ag-radio-button-input-wrapper.ag-checked::after{background-color:var(--white);transform:scale(1);opacity:1}.ag-list{z-index:1100;background-color:rgba(var(--t42-bg-mid), 0.7);backdrop-filter:var(--backdrop-filter)}.ag-list .ag-list-item{padding:0 0.5rem;line-height:2rem;cursor:pointer}.ag-list .ag-list-item:hover{background-color:Rgb(var(--t42-bg-light))}.ag-picker-field-wrapper{height:2rem;padding:0 0.5rem;line-height:2rem;cursor:pointer}.ag-column-select-header-icon{display:flex;align-items:center}.ag-column-select-header .ag-text-field-input{height:1.875rem;line-height:1.875rem}.ag-filter-list-panel .ag-filter-toolpanel-expand{margin:0 0.25rem}.ag-filter-list-panel .ag-filter-toolpanel-group-container,.ag-filter-list-panel .ag-filter-toolpanel-instance-filter{padding-left:0.25rem}.ag-side-bar{position:relative}.ag-side-bar .ag-side-bar-right .ag-tool-panel-horizontal-resize{left:-0.375rem}.ag-side-bar>div:first-child{border:var(--t42-border);background-color:var(--t42-color-opacity-10)}.ag-side-bar .ag-pivot-mode-select{display:flex;padding:0.25rem;border-bottom:var(--t42-border)}.ag-side-bar .ag-pivot-mode-select label{margin:0 0 0 0.5rem}.ag-side-bar .ag-pivot-mode-select .ag-checkbox-label{padding-left:0.25rem}.ag-side-bar .ag-side-buttons div.ag-side-button button{width:1rem;height:1rem;padding:0;border:0.0625rem solid transparent;color:Hsl(var(--t42-content-color-base), 100%);background-color:transparent}.ag-side-bar .ag-side-buttons div.ag-side-button button:hover{color:Hsl(var(--t42-content-color-base), 100%);background-color:Rgb(var(--t42-bg-dark))}.ag-side-bar .ag-side-buttons div.ag-side-button button>span{display:none}.ag-side-bar .ag-side-buttons div.ag-side-button.ag-selected button{border-color:var(--t42-color-opacity-30);background-color:var(--primary)}.ag-side-bar .ag-side-buttons div.ag-side-button.ag-selected button [class*="ag-icon-"]{background-color:var(--white)}.ag-side-bar .ag-icon-checkbox-checked::after{width:0.625rem;height:0.625rem}.ag-side-bar .ag-column-panel,.ag-side-bar .ag-filter-panel{padding-left:0.25rem}.ag-side-bar .ag-filter-checkbox{margin-right:0.25rem}.ag-tool-panel-wrapper{border-top:var(--t42-border);border-bottom:var(--t42-border)}.ag-tool-panel-wrapper .ag-set-filter-list{width:100%;height:auto}.ag-tool-panel-wrapper .ag-column-select-checkbox,.ag-tool-panel-wrapper .ag-column-select-header-checkbox{margin:0 0.25rem}.ag-tool-panel-horizontal-resize{top:initial;width:0.188rem;background-color:var(--t42-color-opacity-10)}.ag-column-panel,.ag-column-select-panel,.ag-column-drop-vertical,.ag-column-drop-list{display:block;min-height:initial;max-height:initial;overflow:visible}.ag-column-panel input,.ag-column-select-panel input,.ag-column-drop-vertical input,.ag-column-drop-list input{border:var(--t42-border)}.ag-column-panel input:focus,.ag-column-select-panel input:focus,.ag-column-drop-vertical input:focus,.ag-column-drop-list input:focus{border-color:var(--primary)}[class*="ag-icon-"],.icon-check-1,.icon-check-empty,.icon-resize-horizontal{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:color, transform;display:block;width:0.75rem;height:0.75rem;margin:0 auto;background-color:var(--t42-content-color);background-image:none;mask-repeat:no-repeat;mask-position:center;cursor:pointer}[class*="ag-icon-"]:hover,.icon-check-1:hover,.icon-check-empty:hover,.icon-resize-horizontal:hover{background-color:var(--t42-link-color)}.ag-menu-option-disabled{color:var(--t42-content-color-disabled)}.ag-menu-option-disabled .ag-icon{background-color:var(--t42-content-color-disabled)}.ag-icon-menu{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M475.4,384v36.4c0,5.1-1.7,9.4-5.1,12.8s-7.9,5.3-13.3,5.6H55c-5.1,0-9.4-1.9-12.8-5.6c-3.4-3.8-5.3-8-5.6-12.8V384 c0-5.1,1.9-9.4,5.6-12.8c3.8-3.4,8-5.3,12.8-5.6h401.9c5.1,0,9.6,1.9,13.3,5.6C474,375,475.7,379.2,475.4,384z M475.4,237.6v36.9 c0,4.8-1.7,9-5.1,12.8s-7.9,5.5-13.3,5.1H55c-5.1,0-9.4-1.7-12.8-5.1s-5.3-7.7-5.6-12.8v-36.9c0-4.8,1.9-9,5.6-12.8 c3.8-3.8,8-5.5,12.8-5.1h401.9c5.1,0,9.6,1.7,13.3,5.1S475.7,232.5,475.4,237.6z M475.4,91.7V128c0,4.8-1.7,9-5.1,12.8 s-7.9,5.6-13.3,5.6H55c-5.1,0-9.4-1.9-12.8-5.6s-5.3-8-5.6-12.8V91.7c0-5.1,1.9-9.6,5.6-13.3c3.8-3.8,8-5.5,12.8-5.1h401.9 c5.1,0,9.6,1.7,13.3,5.1S475.7,86.2,475.4,91.7z%27/%3E%3C/svg%3E%0A")}.ag-header-icon{margin-left:0.125rem}.ag-header-icon .ag-icon-menu{line-height:1.875rem}.ag-icon-asc{-webkit-mask-image:var(--t42-select-indicator);transform:rotate(180deg)}.ag-icon-desc{-webkit-mask-image:var(--t42-select-indicator);margin-bottom:2px}.ag-icon-filter{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 16 16%27%3E%3Cpath d=%27M14.9,1.4c0.1,0.3,0.1,0.5-0.1,0.7L9.9,7v7.4c0,0.3-0.1,0.5-0.4,0.6C9.4,15,9.4,15,9.3,15c-0.2,0-0.3-0.1-0.4-0.2l-2.5-2.5 c-0.1-0.1-0.2-0.3-0.2-0.4V7L1.2,2.1C1,1.9,0.9,1.7,1.1,1.4C1.2,1.1,1.4,1,1.7,1h12.7C14.6,1,14.8,1.1,14.9,1.4L14.9,1.4z%27/%3E%3C/svg%3E")}.ag-icon-none{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 16 16%27%3E%3Cpath d=%27M1 6L5 2Q6 1 7 2L11 6Q11 7 10 7L2 7Q1 7 1 6M2 8Q1 8 1 9L5 13Q6 14 7 13L11 9Q11 8 10 8L2 8%27/%3E%3C/svg%3E%0A")}.ag-icon-indeterminate,.ag-icon-checkbox-indeterminate,.ag-icon-checkbox-indeterminate-readonly,.ag-icon-checkbox-unchecked,.ag-icon-checkbox-unchecked-readonly,.ag-icon-checkbox-checked-readonly,.ag-icon-checkbox-checked,.icon-check-1,.icon-check-empty,.ag-checkbox-input-wrapper,.ag-toggle-button-input-wrapper{position:relative;padding:0;color:var(--t42-content-color-muted);background-color:transparent;cursor:pointer;user-select:none}.ag-icon-indeterminate::before,.ag-icon-checkbox-indeterminate::before,.ag-icon-checkbox-indeterminate-readonly::before,.ag-icon-checkbox-unchecked::before,.ag-icon-checkbox-unchecked-readonly::before,.ag-icon-checkbox-checked-readonly::before,.ag-icon-checkbox-checked::before,.icon-check-1::before,.icon-check-empty::before,.ag-checkbox-input-wrapper::before,.ag-toggle-button-input-wrapper::before{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, border-color;display:block;width:100%;height:100%;border:var(--t42-border);border-color:var(--t42-content-color);cursor:pointer;content:"";pointer-events:all}.ag-icon-indeterminate:focus,.ag-icon-checkbox-indeterminate:focus,.ag-icon-checkbox-indeterminate-readonly:focus,.ag-icon-checkbox-unchecked:focus,.ag-icon-checkbox-unchecked-readonly:focus,.ag-icon-checkbox-checked-readonly:focus,.ag-icon-checkbox-checked:focus,.icon-check-1:focus,.icon-check-empty:focus,.ag-checkbox-input-wrapper:focus,.ag-toggle-button-input-wrapper:focus{border-color:var(--primary)}.ag-icon-indeterminate:hover,.ag-icon-checkbox-indeterminate:hover,.ag-icon-checkbox-indeterminate-readonly:hover,.ag-icon-checkbox-unchecked:hover,.ag-icon-checkbox-unchecked-readonly:hover,.ag-icon-checkbox-checked-readonly:hover,.ag-icon-checkbox-checked:hover,.icon-check-1:hover,.icon-check-empty:hover,.ag-checkbox-input-wrapper:hover,.ag-toggle-button-input-wrapper:hover{background-color:transparent}.ag-icon-checkbox-indeterminate,.ag-icon-checkbox-indeterminate-readonly,.ag-icon-checkbox-checked,.ag-icon-checkbox-checked-readonly,.icon-check-empty,.ag-checkbox-input-wrapper.ag-indeterminate,.ag-checkbox-input-wrapper.ag-checked,.ag-toggle-button-input-wrapper.ag-checked{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background, color}.ag-icon-checkbox-indeterminate::before,.ag-icon-checkbox-indeterminate-readonly::before,.ag-icon-checkbox-checked::before,.ag-icon-checkbox-checked-readonly::before,.icon-check-empty::before,.ag-checkbox-input-wrapper.ag-indeterminate::before,.ag-checkbox-input-wrapper.ag-checked::before,.ag-toggle-button-input-wrapper.ag-checked::before{border:0.0625rem solid var(--t42-color-opacity-30);background:var(--primary)}.ag-icon-checkbox-indeterminate::after,.ag-icon-checkbox-indeterminate-readonly::after,.ag-icon-checkbox-checked::after,.ag-icon-checkbox-checked-readonly::after,.icon-check-empty::after,.ag-checkbox-input-wrapper.ag-indeterminate::after,.ag-checkbox-input-wrapper.ag-checked::after,.ag-toggle-button-input-wrapper.ag-checked::after{position:absolute;top:0.063rem;left:0.063rem;display:block;width:0.75rem;height:0.75rem;background:var(--white);content:""}.ag-icon-checkbox-checked::after,.ag-icon-checkbox-checked-readonly::after,.icon-check-empty::after,.ag-checkbox-input-wrapper.ag-checked::after,.ag-toggle-button-input-wrapper.ag-checked::after{-webkit-mask-image:url("data:image/svg+xml,%3Csvg version=%271.1%27 xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M477.44 152.832q0 11.264-8.192 19.456l-245.76 245.76q-8.192 7.68-19.456 7.68t-19.456-7.68l-142.336-142.336q-7.68-8.192-7.68-19.456t7.68-19.456l38.912-38.912q8.192-8.192 19.456-8.192t19.456 8.192l83.968 84.48 187.392-187.904q8.192-8.192 19.456-8.192t19.456 8.192l38.912 38.912q8.192 7.68 8.192 19.456z%27%3E%3C/path%3E%3C/svg%3E%0A")}.ag-icon-checkbox-indeterminate::after,.ag-icon-checkbox-indeterminate-readonly::after,.ag-checkbox-input-wrapper.ag-indeterminate::after{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 -1 5 6%27%3E%3Cpath d=%27M 1 1 A 1 1 0 0 0 1 2 L 4 2 A 1 1 0 0 0 4 1 L 1 1%27/%3E%3C/svg%3E%0A")}.ag-checkbox-input-wrapper.ag-indeterminate::after{top:0.125rem;left:0.125rem}.ag-checkbox-input-wrapper::before,.ag-toggle-button-input-wrapper::before{width:0.875rem;height:0.875rem}.ag-checkbox-input-wrapper .ag-checkbox-input,.ag-checkbox-input-wrapper .ag-toggle-button-input,.ag-toggle-button-input-wrapper .ag-checkbox-input,.ag-toggle-button-input-wrapper .ag-toggle-button-input{position:absolute;z-index:2;width:0.875rem;height:0.875rem}.ag-icon-columns{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M146.432 374.784v55.296q0 11.264-8.192 18.944t-19.456 8.192h-91.136q-11.776 0-19.456-8.192t-8.192-18.944v-55.296q0-11.264 8.192-19.456t19.456-7.68h91.136q11.776 0 19.456 7.68t8.192 19.456zM146.432 228.864v54.784q0 11.264-8.192 19.456t-19.456 7.68h-91.136q-11.776 0-19.456-7.68t-8.192-19.456v-54.784q0-11.776 8.192-19.456t19.456-8.192h91.136q11.776 0 19.456 8.192t8.192 19.456zM329.216 374.784v55.296q0 11.264-8.192 18.944t-19.456 8.192h-91.136q-11.776 0-19.456-8.192t-8.192-18.944v-55.296q0-11.264 8.192-19.456t19.456-7.68h91.136q11.776 0 19.456 7.68t8.192 19.456zM146.432 82.432v54.784q0 11.264-8.192 19.456t-19.456 8.192h-91.136q-11.776 0-19.456-8.192t-8.192-19.456v-54.784q0-11.264 8.192-19.456t19.456-8.192h91.136q11.776 0 19.456 8.192t8.192 19.456zM329.216 228.864v54.784q0 11.264-8.192 19.456t-19.456 7.68h-91.136q-11.776 0-19.456-7.68t-8.192-19.456v-54.784q0-11.776 8.192-19.456t19.456-8.192h91.136q11.776 0 19.456 8.192t8.192 19.456zM512 374.784v55.296q0 11.264-8.192 18.944t-19.456 8.192h-91.136q-11.264 0-19.456-8.192t-8.192-18.944v-55.296q0-11.264 8.192-19.456t19.456-7.68h91.136q11.776 0 19.456 7.68t8.192 19.456zM329.216 82.432v54.784q0 11.264-8.192 19.456t-19.456 8.192h-91.136q-11.776 0-19.456-8.192t-8.192-19.456v-54.784q0-11.264 8.192-19.456t19.456-8.192h91.136q11.776 0 19.456 8.192t8.192 19.456zM512 228.864v54.784q0 11.264-8.192 19.456t-19.456 7.68h-91.136q-11.264 0-19.456-7.68t-8.192-19.456v-54.784q0-11.776 8.192-19.456t19.456-8.192h91.136q11.776 0 19.456 8.192t8.192 19.456zM512 82.432v54.784q0 11.264-8.192 19.456t-19.456 8.192h-91.136q-11.264 0-19.456-8.192t-8.192-19.456v-54.784q0-11.264 8.192-19.456t19.456-8.192h91.136q11.776 0 19.456 8.192t8.192 19.456z%27%3E%3C/path%3E%3C/svg%3E")}.ag-icon-pin{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M228.4,228.6v-128c0-2.7-0.9-4.9-2.6-6.7s-3.9-2.6-6.7-2.6c-2.7,0-4.9,0.9-6.7,2.6c-1.7,1.7-2.6,3.9-2.6,6.7v128 c0,2.7,0.9,4.9,2.6,6.7c1.7,1.7,3.9,2.6,6.7,2.6c2.7,0,4.9-0.9,6.7-2.6S228.4,231.3,228.4,228.6z M420.4,329.5c0,4.8-1.9,9-5.6,12.8 c-3.8,3.8-8,5.5-12.8,5.1H279.6l-14.8,138.2c-0.3,2.4-1.4,4.3-3.1,5.6c-1.7,1.4-3.6,2.2-5.6,2.6h-0.5c-5.1,0-8-2.6-8.7-7.7 l-22-138.8H109.6c-5.1,0-9.4-1.7-12.8-5.1c-3.4-3.4-5.3-7.7-5.6-12.8c0-23.6,7.5-44.7,22.5-63.5s31.9-28.2,50.7-28.2V91.4 c-9.9,0-18.4-3.6-25.6-10.8c-7.2-7.2-10.9-15.7-11.3-25.6s3.4-18.4,11.3-25.6c7.9-7.2,16.4-10.9,25.6-11.3h182.8 c9.9,0,18.4,3.8,25.6,11.3s10.8,16,10.8,25.6s-3.6,18.1-10.8,25.6S357,91.7,347.1,91.4v146.4c18.8,0,35.7,9.4,50.7,28.2 C412.8,284.8,420.4,305.9,420.4,329.5L420.4,329.5z%27/%3E%3C/svg%3E")}.ag-icon-small-right,.ag-icon-small-down{width:0.65rem;height:0.65rem;-webkit-mask-image:var(--t42-select-indicator);transform:rotate(-90deg)}.ag-icon-small-down{transform:rotate(0)}.ag-icon-tick{-webkit-mask-image:url("data:image/svg+xml,%3Csvg version=%271.1%27 xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M477.44 152.832q0 11.264-8.192 19.456l-245.76 245.76q-8.192 7.68-19.456 7.68t-19.456-7.68l-142.336-142.336q-7.68-8.192-7.68-19.456t7.68-19.456l38.912-38.912q8.192-8.192 19.456-8.192t19.456 8.192l83.968 84.48 187.392-187.904q8.192-8.192 19.456-8.192t19.456 8.192l38.912 38.912q8.192 7.68 8.192 19.456z%27%3E%3C/path%3E%3C/svg%3E%0A")}.ag-icon-copy{-webkit-mask-image:url("data:image/svg+xml,")}.ag-icon-csv,.ag-icon-excel{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M0 0zq0-7.7-5.1-12.8zM475.3 356.6v91.6q0 11.3-8.2 18.9t-19.5 8.2h-420.4q-11.8 0-19.5-8.2t-8.2-18.9v-91.6q0-11.3 8.2-19.5t19.5-8.2h132.6l38.4 38.9q16.9 16.4 38.9 16.4t38.9-16.4l38.9-38.9h132.6q11.3 0 19.5 8.2t8.2 19.5zM382.1 193.8q5.1 11.8-4.1 20l-128 128q-5.1 5.6-12.8 5.6t-12.8-5.6l-128-128q-8.7-8.2-4.1-20q5.1-10.8 16.9-10.8h73.2v-128q0-7.7 5.6-12.8t12.8-5.6h73.2q7.2 0 12.8 5.6t5.1 12.8v128h73.2q12.3 0 16.9 10.8M347 439A1 1 0 00347 402A1 1 0 00347 439M420 439A1 1 0 00420 402A1 1 0 00420 439zz%27/%3E%3C/svg%3E%0A")}.ag-icon-expanded{-webkit-mask-image:var(--t42-select-indicator);transform:rotate(-90deg)}.ag-icon-contracted{-webkit-mask-image:var(--t42-select-indicator);transform:rotate(90deg)}.ag-header-expand-icon-collapsed .ag-icon-contracted{margin-bottom:1px;transform:rotate(90deg);-webkit-mask-image:var(--t42-select-indicator)}.ag-icon-paste{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M219.648 475.648h256v-183.296h-119.296q-11.264 0-18.944-7.68t-8.192-19.456v-118.784h-109.568v329.216zM292.352 64v-18.432q0-3.584-2.56-6.144t-6.144-3.072h-201.216q-3.584 0-6.656 3.072t-2.56 6.144v18.432q0 3.584 2.56 6.656t6.656 2.56h201.216q3.584 0 6.144-2.56t2.56-6.656zM365.568 256h85.504l-85.504-85.504v85.504zM512 292.352v192q0 11.776-8.192 19.456t-19.456 8.192h-273.92q-11.776 0-19.456-8.192t-8.192-19.456v-45.568h-155.136q-11.776 0-19.456-8.192t-8.192-18.944v-384q0-11.776 8.192-19.456t19.456-8.192h310.784q11.264 0 19.456 8.192t7.68 19.456v93.696q6.144 3.584 10.24 7.68l116.736 116.736q8.192 7.68 13.824 21.504t5.632 25.088z%27%3E%3C/path%3E%3C/svg%3E%0A")}.ag-icon-arrows{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M512 256q0 7.168-5.632 12.8l-72.704 73.216q-5.632 5.632-13.312 5.632t-12.8-5.632-5.12-12.8v-36.864h-110.080v110.080h36.864q7.168 0 12.8 5.12t5.632 12.8-5.632 12.8l-73.216 73.216q-5.12 5.632-12.8 5.632t-12.8-5.632l-73.216-73.216q-5.632-5.12-5.632-12.8t5.632-12.8 12.8-5.12h36.864v-110.080h-110.080v36.864q0 7.168-5.12 12.8t-12.8 5.632-12.8-5.632l-73.216-73.216q-5.632-5.632-5.632-12.8t5.632-12.8l73.216-73.216q5.12-5.632 12.8-5.632t12.8 5.632 5.12 12.8v36.864h110.080v-110.080h-36.864q-7.168 0-12.8-5.12t-5.632-12.8 5.632-13.312l73.216-72.704q5.632-5.632 12.8-5.632t12.8 5.632l73.216 72.704q5.632 5.632 5.632 13.312t-5.632 12.8-12.8 5.12h-36.864v110.080h110.080v-36.864q0-7.168 5.12-12.8t12.8-5.632 13.312 5.632l72.704 73.216q5.632 5.12 5.632 12.8z%27%3E%3C/path%3E%3C/svg%3E%0A")}.ag-icon-not-allowed{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27m 182.8 238.1 h 145.9 v -55.3 c 0 -20.1 -7.2 -37.4 -21.5 -51.7 s -31.6 -21.3 -51.7 -21 c -20.1 0.3 -37.4 7.3 -51.7 21 s -21.3 30.9 -21 51.7 l -0 55.3 l 0 0 z m 237.6 27.1 v 164.9 c 0 7.5 -2.7 13.8 -8.2 18.9 s -11.9 7.9 -19.5 8.2 h -273.9 c -7.9 0 -14.3 -2.7 -19.5 -8.2 c -5.1 -5.5 -7.9 -11.8 -8.2 -18.9 v -164.9 c 0 -7.5 2.7 -14 8.2 -19.5 s 11.9 -8 19.5 -7.7 h 8.7 v -55.3 c 0 -34.8 12.6 -64.9 37.9 -90.1 s 55.3 -37.9 90.1 -37.9 s 65 12.6 90.6 37.9 s 38.1 55.3 37.4 90.1 v 55.3 h 9.2 c 7.9 0 14.3 2.6 19.5 7.7 s 7.8 11.7 8.2 19.5 z%27/%3E%3C/svg%3E")}.ag-icon-eye-slash{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M 475.6 256.3 q -43.5 -67.6 -109.1 -100.9 q 17.4 29.7 17.4 64 q 0 52.7 -37.4 90.6 t -90.6 37.4 t -90.6 -37.4 t -37.4 -90.6 q 0 -34.3 17.4 -64 q -65.5 33.3 -109.1 100.9 q 38.4 58.4 95.7 93.2 t 123.9 34.8 t 124.4 -34.8 t 95.2 -93.2 z M 269.8 146.2 q 0 -5.6 -4.1 -9.7 t -9.7 -3.6 q -35.8 0 -61.4 25.6 t -25.6 60.9 q 0 5.6 4.1 9.7 t 9.7 4.1 t 9.7 -4.1 t 4.1 -9.7 q 0 -24.6 17.4 -42 t 42 -17.4 q 5.6 0 9.7 -4.1 t 4.1 -9.7 z M 512 256.3 q 0 9.7 -5.6 19.5 q -39.9 66 -107.5 105.5 t -142.8 39.4 t -142.8 -39.4 t -107.5 -105.5 q -5.6 -9.7 -5.6 -19.5 t 5.6 -20 q 39.9 -65.5 107.5 -105 t 142.8 -39.9 t 142.8 39.9 t 107.5 105 q 5.6 10.2 5.6 20 z%27%3E%3C/path%3E%3C/svg%3E%0A")}.ag-icon-group{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M146.4 374.8v55.3q0 11.3-8.2 18.9t-19.5 8.2h-91.1q-11.8 0-19.5-8.2t-8.2-18.9v-55.3q0-11.3 8.2-19.5t19.5-7.7h91.1q11.8 0 19.5 7.7t8.2 19.5zM146.4 228.9v54.8q0 11.3-8.2 19.5t-19.5 7.7h-91.1q-11.8 0-19.5-7.7t-8.2-19.5v-54.8q0-11.8 8.2-19.5t19.5-8.2h91.1q11.8 0 19.5 8.2t8.2 19.5zM512 374.8v55.3q0 11.3-8.2 18.9t-19.5 8.2h-273.9q-11.8 0-19.5-8.2t-8.2-18.9v-55.3q0-11.3 8.2-19.5t19.5-7.7h273.9q11.8 0 19.5 7.7t8.2 19.5zM146.4 82.4v54.8q0 11.3-8.2 19.5t-19.5 8.2h-91.1q-11.8 0-19.5-8.2t-8.2-19.5v-54.8q0-11.3 8.2-19.5t19.5-8.2h91.1q11.8 0 19.5 8.2t8.2 19.5zM512 228.9v54.8q0 11.3-8.2 19.5t-19.5 7.7h-273.9q-11.8 0-19.5-7.7t-8.2-19.5v-54.8q0-11.8 8.2-19.5t19.5-8.2h273.9q11.8 0 19.5 8.2t8.2 19.5zM512 82.4v54.8q0 11.3-8.2 19.5t-19.5 8.2h-273.9q-11.8 0-19.5-8.2t-8.2-19.5v-54.8q0-11.3 8.2-19.5t19.5-8.2h273.9q11.8 0 19.5 8.2t8.2 19.5z%27%3E%3C/path%3E%3C/svg%3E%0A")}.ag-icon-grip{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 16 16%27%3E%3Cpath d=%27M4 3L6 3L6 5L4 5L4 3M4 7L6 7L6 9L4 9L4 7M4 11L6 11L6 13L4 13L4 11M8 3L10 3L10 5L8 5L8 3M8 7L10 7L10 9L8 9L8 7M8 11L10 11L10 13L8 13L8 11%27/%3E%3C/svg%3E%0A");margin:0}.ag-icon-tree-open{-webkit-mask-image:var(--t42-select-indicator);transform:rotate(180deg)}.ag-icon-tree-closed{-webkit-mask-image:var(--t42-select-indicator);transform:rotate(270deg)}.ag-icon-tree-indeterminate{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 -1 5 6%27%3E%3Cpath d=%27M 1 1 A 1 1 0 0 0 1 2 L 4 2 A 1 1 0 0 0 4 1 L 1 1%27/%3E%3C/svg%3E%0A")}.ag-icon-save{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M 420.6 319.2 V 393 c 0 22.9 -8 42.3 -24.1 58.4 s -35.5 24.1 -58.4 24.1 H 100.6 c -22.9 0 -42.3 -8 -58.4 -24.1 S 18.2 415.8 18.2 393 V 155.4 c 0 -22.5 8 -41.8 24.1 -57.9 S 77.7 73.3 100.6 73 h 72.7 c 2.4 0 4.6 1 6.7 3.1 c 2 2 2.9 4.1 2.6 6.1 c 0 5.1 -2.6 8.2 -7.7 9.2 c -14.7 5.1 -27.3 10.9 -37.9 17.4 c -1.7 0.7 -3.2 1 -4.6 1 h -31.7 c -12.6 0 -23.4 4.4 -32.3 13.3 s -13.5 19.6 -13.8 32.3 V 393 c 0 12.6 4.6 23.4 13.8 32.3 c 9.2 8.9 20 13.5 32.3 13.8 h 237.6 c 12.6 0 23.4 -4.6 32.3 -13.8 c 8.9 -9.2 13.3 -20 13.3 -32.3 V 332 c 0 -3.8 1.7 -6.5 5.1 -8.2 c 5.5 -2.4 10.8 -6 15.9 -10.8 c 2.7 -3.1 6 -3.8 9.7 -2 C 418.6 312.7 420.6 315.5 420.6 319.2 L 420.6 319.2 z M 488.2 177.4 L 378.6 287 c -3.4 3.8 -7.7 5.6 -12.8 5.6 c -2.4 0 -4.8 -0.5 -7.2 -1.5 c -7.5 -3.1 -11.3 -8.7 -11.3 -16.9 v -54.8 h -45.6 c -61.8 0 -103.6 12.5 -125.4 37.4 c -22.5 26.3 -29.5 71.3 -21 135.2 c 0.7 4.4 -1.2 7.7 -5.6 9.7 c -1.7 0.3 -2.9 0.5 -3.6 0.5 c -3.1 0 -5.5 -1.2 -7.2 -3.6 c -2 -2.7 -4.1 -5.6 -6.1 -8.7 c -2 -3.1 -5.8 -9.7 -11.3 -20 c -5.5 -10.2 -10.2 -19.6 -14.3 -28.2 c -4.1 -8.5 -7.7 -19.5 -10.8 -32.8 c -3.1 -13.3 -4.8 -24.9 -5.1 -34.8 c 0 -9.2 0.3 -17.9 1 -26.1 c 0.7 -8.2 2 -16.7 4.1 -25.6 c 2 -8.9 4.6 -17.2 7.7 -25.1 c 3.1 -7.9 7.7 -15.5 13.8 -23 c 6.1 -7.5 12.6 -14.7 19.5 -21.5 s 15.7 -12.6 26.6 -17.4 c 10.9 -4.8 22.9 -9.4 35.8 -13.8 c 13 -4.4 28.2 -7.3 45.6 -8.7 s 36.2 -2.4 56.3 -3.1 h 45.6 V 55 c 0 -8.2 3.8 -13.8 11.3 -16.9 c 2.4 -1 4.8 -1.5 7.2 -1.5 c 4.8 0 9 1.9 12.8 5.6 l 109.6 109.6 c 3.8 3.4 5.6 7.7 5.6 12.8 S 491.9 174 488.2 177.4 L 488.2 177.4 z%27/%3E%3C/svg%3E")}.ag-tooltip{padding:0.125rem 0.5rem;border:0.0625rem solid var(--t42-color-opacity-10);border-radius:0.25rem;background:Rgb(var(--t42-bg-light));box-shadow:var(--t42-shadow)}.ag-icon-cancel{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M366.9 336.4c6.1 6.1 9.2 13.5 9.2 22s-3.1 15.9-9.2 22c-6.1 5.5-13.5 8.2-22 8.2c-8.5 0-15.9-2.7-22-8.2l-67.6-77.8l-67.6 77.8c-6.1 5.5-13.5 8.2-22 8.2c-8.5 0-15.9-2.7-22-8.2c-5.5-6.1-8.2-13.5-8.2-22s2.7-15.9 8.2-22l70.7-79.9l-70.7-80.9c-5.5-6.1-8.2-13.5-8.2-22c0-8.5 2.7-15.9 8.2-22c6.1-5.5 13.5-8.2 22-8.2c8.5 0 15.9 2.7 22 8.2l67.6 77.8l67.6-77.8c6.1-5.5 13.5-8.2 22-8.2c8.5 0 15.9 2.7 22 8.2c6.1 6.1 9.2 13.5 9.2 22c0 8.5-3.1 15.9-9.2 22l-70.7 80.9L366.9 336.4z%27/%3E%3C/svg%3E")}.icon-check-empty::after{width:0.65rem;height:0.65rem}.icon-resize-horizontal{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M512 256q0 7.2-5.6 12.8l-72.7 73.2q-5.6 5.6-13.3 5.6t-12.8-5.6t-5.1-12.8v-36.9h-292.9v36.9q0 7.2-5.1 12.8t-12.8 5.6t-12.8-5.6l-73.2-73.2q-5.6-5.6-5.6-12.8t5.6-12.8l73.2-73.2q5.1-5.6 12.8-5.6t12.8 5.6t5.1 12.8v36.9h292.9v-36.9q0-7.2 5.1-12.8t12.8-5.6t13.3 5.6l72.7 73.2q5.6 5.1 5.6 12.8z%27%3E%3C/path%3E%3C/svg%3E%0A")}.ag-icon-aggregation{margin:0 0.25rem;-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 16 16%27%3E%3Cpath d=%27M3.6,1.7c-0.2,0.7-0.9,1.1-1.5,1C1.5,2.6,1,2,1,1.3C1,0.7,1.5,0.1,2.1,0c0.4-0.1,0.7,0,1,0.2C3.4,0.4,3.6,0.7,3.7,1 c0.3,0,0.5,0.1,0.8,0.3C4.7,1.5,5,1.8,5.2,2.1c0.2,0.3,0.4,0.7,0.6,1c0.1,0.2,0.3,0.5,0.5,0.7c0.2,0.2,0.5,0.5,0.8,0.6 c0.1,0.1,0.3,0.1,0.5,0.1c0.6,0,2.3,0,2.9,0c0.4,0,0.7,0,1.1,0c0,0,0,0,0.1,0c0,0,0,0,0-0.1c0-0.1,0-0.2,0-0.3c0,0,0-0.1,0-0.1 c0-0.1,0.1-0.1,0.2-0.1c0.1,0,0.1,0,0.1,0.1c0.1,0,0.1,0.1,0.2,0.2c0.2,0.2,0.3,0.3,0.5,0.5C12.8,4.8,13,5,13.1,5.1c0,0,0,0,0,0 c0,0,0,0-0.1,0c-1.5,0-4.1,0-5.7,0C7.2,5.2,7,5.1,6.8,5C6.6,4.9,6.3,4.8,6.1,4.6C5.7,4.3,5.5,4,5.2,3.5C5,3.2,4.8,2.8,4.6,2.4 C4.4,2.2,4.3,2.1,4.1,1.9C4,1.8,3.9,1.7,3.8,1.7C3.7,1.7,3.7,1.7,3.6,1.7z%27/%3E%3Cpath d=%27M3.6,7.7c1,0,10.6,0,11,0c0.1,0,0.1,0,0.1,0.1C14.8,7.8,14.9,7.9,15,8c-0.1,0.1-0.2,0.2-0.3,0.3c0,0,0,0-0.1,0 c0,0,0,0-0.1,0c-3.3,0-7.7,0-10.9,0C3.5,8.8,3.2,9.1,2.8,9.3C2.5,9.4,2.2,9.4,2,9.3C1.4,9.1,1,8.6,1,8c0-0.7,0.5-1.2,1.1-1.3 c0.3-0.1,0.7,0,1,0.2C3.4,7.1,3.6,7.3,3.6,7.7z%27/%3E%3Cpath d=%27M13.1,10.9C13.1,10.9,13.1,10.9,13.1,10.9c-0.3,0.3-0.6,0.6-0.8,0.8c-0.1,0.1-0.2,0.2-0.3,0.3c0,0-0.1,0.1-0.1,0.1 c0,0-0.1,0-0.1,0c-0.1,0-0.1,0-0.2-0.1c0,0,0-0.1,0-0.1c0-0.1,0-0.2,0-0.3c0,0,0,0,0-0.1c-1,0-3.1,0-4.1,0c-0.1,0-0.3,0-0.4,0.1 c-0.3,0.1-0.5,0.2-0.7,0.4c-0.2,0.2-0.4,0.5-0.6,0.8c-0.2,0.4-0.4,0.7-0.7,1.1c-0.2,0.2-0.4,0.4-0.6,0.6c-0.1,0.1-0.3,0.2-0.4,0.3 c-0.1,0.1-0.3,0.2-0.4,0.2c0,0-0.1,0-0.1,0c-0.1,0.4-0.3,0.7-0.7,0.9C2.7,16,2.4,16,2.1,16C1.5,15.9,1,15.3,1,14.7 c0-0.7,0.5-1.2,1-1.3c0.3-0.1,0.7,0,1,0.2c0.3,0.2,0.5,0.5,0.6,0.8c0.1,0,0.2,0,0.2,0C4,14.2,4.1,14.1,4.2,14 c0.2-0.2,0.3-0.4,0.5-0.6c0.2-0.3,0.4-0.6,0.6-1c0.2-0.3,0.4-0.6,0.6-0.9c0.3-0.2,0.5-0.5,0.9-0.6c0.2-0.1,0.4-0.1,0.6-0.1 c0,0,0.1,0,0.1,0c0.6,0,2.4,0,3,0c0.8,0,1.7,0,2.5,0C13.1,10.9,13.1,10.9,13.1,10.9C13.1,10.9,13.1,10.9,13.1,10.9z%27/%3E%3Cpath d=%27M3.6,11.7c-0.1,0.4-0.3,0.7-0.7,0.9c-0.3,0.2-0.6,0.2-0.9,0.1C1.5,12.6,1,12.1,1,11.4c0-0.7,0.5-1.2,1.1-1.3 c0.3-0.1,0.7,0,1,0.2c0.3,0.2,0.5,0.5,0.6,0.8c0.1,0,0.1,0,0.2,0c0.2,0,0.3-0.1,0.4-0.2c0.2-0.1,0.4-0.3,0.5-0.4 C4.9,10.3,5,10.2,5,10.2C5.3,9.9,5.6,9.7,6,9.6c0.3-0.1,0.6-0.2,0.8-0.2c0.1,0,0.1,0,0.2,0c1.1,0,3.4,0,4.5,0c0.9,0,1.8,0,2.6,0 c0,0,0,0,0.1,0c0,0,0,0,0,0C14,9.6,13.8,9.8,13.6,10c-1.8,0-4.8,0-6.6,0c-0.3,0-0.6,0.1-0.9,0.2c-0.2,0.1-0.5,0.3-0.6,0.5 c-0.3,0.3-0.5,0.5-0.8,0.7c-0.2,0.1-0.4,0.2-0.6,0.3C3.9,11.7,3.8,11.7,3.6,11.7C3.7,11.7,3.7,11.7,3.6,11.7z%27/%3E%3Cpath d=%27M3.6,4.9C3.5,5.3,3.3,5.6,2.9,5.8C2.6,5.9,2.3,6,2,5.9C1.4,5.7,1,5.2,1,4.5c0-0.6,0.5-1.2,1.1-1.3c0.7-0.1,1.4,0.3,1.5,1 c0,0,0.1,0,0.1,0c0.3,0,0.5,0.1,0.7,0.3C4.7,4.7,5,4.9,5.2,5c0.1,0.1,0.2,0.2,0.4,0.4c0.3,0.3,0.6,0.5,1,0.5C6.7,6,6.9,6,7,6 c1.8,0,4.8,0,6.6,0c0.1,0.1,0.3,0.3,0.6,0.6c0,0,0,0,0,0c0,0,0,0,0,0c0,0,0,0-0.1,0c-2,0-5.1,0-7.1,0c-0.3,0-0.5,0-0.8-0.1 C6,6.5,5.7,6.4,5.5,6.2C5.3,6.1,5.1,5.9,5,5.8C4.8,5.5,4.5,5.3,4.2,5.1C4.1,5,3.9,4.9,3.6,4.9z%27/%3E%3C/svg%3E%0A")}.ag-icon-loading{position:relative;width:1rem;height:1rem;border-radius:50%;background:linear-gradient(to right, var(--t42-icon-color), Rgba(var(--t42-bg-dark) 42%));transform:translateZ(0);animation:icon-loading 1.4s infinite linear}.ag-icon-loading::before{position:absolute;top:0;left:0;width:50%;height:50%;border-radius:100% 0 0;background:var(--t42-icon-color);content:""}.ag-icon-loading::after{position:absolute;top:0;right:0;bottom:0;left:0;width:75%;height:75%;margin:auto;border-radius:50%;background:Rgb(var(--t42-bg-dark));content:""}.ag-loading{display:flex;padding-left:0.5rem}@keyframes icon-loading{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.search{position:relative}.search i{position:absolute;top:0.625rem;right:0.75rem;width:.75rem;height:.75rem;background-color:var(--t42-content-color);-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M328.9 219.4q0-52.7-37.4-90.1t-90.6-37.9t-90.6 37.9t-37.4 90.1t37.4 90.6t90.6 37.4t90.6-37.4t37.4-90.6zM475.3 457.5q0 14.8-11.3 25.6t-25.6 10.8q-15.4 0-25.6-10.8l-97.8-97.8q-51.2 35.3-114.2 35.3q-41 0-78.3-15.9t-64-43t-43-64t-15.9-78.3t15.9-77.8t43-64.5t64-43t78.3-15.9t78.3 15.9t64 43t43 64.5t15.9 77.8q0 63-35.3 114.2l97.8 97.8q10.8 10.8 10.8 26.1z%27%3E%3C/path%3E%3C/svg%3E%0A")}.search-results{position:absolute;top:33px;max-height:215px;overflow-y:auto}.search-results .list-group-item{white-space:nowrap}.select{position:relative;z-index:12;display:flex;align-items:center;justify-content:center;width:100%;height:2rem;list-style:none;cursor:pointer}.select input[type="radio"]{opacity:1}.select_expand{position:absolute;top:0;right:0;width:0;height:2rem}.select_expand::after{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:transform;position:absolute;top:50%;right:0;z-index:2;width:1rem;height:1rem;background:var(--t42-select-indicator) center center/1rem 1rem no-repeat;transform:translate(-65%, -55%);content:"";pointer-events:none}.select_expand:checked+.select_close_label+.select_options .select_label:hover{color:var(--t42-link-hover-color);background-color:var(--t42-link-active-bg)}.select_expand:checked::after{transform:translate(-65%, -55%) rotate(-180deg)}.select_expand_label{position:absolute;top:0;left:0;display:block;width:100%;height:2rem;margin-bottom:0;cursor:pointer}.select_close{display:none}.select_close_label{position:fixed;top:0;left:0;display:none;margin-bottom:0}.select_items{position:absolute;top:0;left:0;width:100%;min-height:2rem;border-color:var(--t42-color-opacity-10);border-style:solid;border-width:1px}.select_items:hover{border-color:var(--primary)}.select_input{display:none}.select_label{display:block;height:0;margin-bottom:0;padding-left:0.875rem;overflow:hidden;line-height:2rem;cursor:pointer;transition:all 200ms cubic-bezier(0.4, 0.25, 0.3, 1)}.select_label-placeholder{position:absolute;top:0;left:0;height:2rem;vertical-align:middle;background-color:transparent}.select_expand:checked+.select_close_label{display:block}.select_expand:checked+.select_close_label::before,.select_expand:checked+.select_close_label::after{display:none}.select_expand:checked+.select_close_label+.select_options .select_label{height:2rem}.select_expand:checked+.select_close_label+.select_options+.select_expand_label{display:none}.select_input:checked+.select_label{height:2rem}.select_option label{color:var(--t42-content-color)}.select_options{max-height:10rem;padding-left:0;overflow:auto;list-style:none}.dark{--t42-json-icons: url("data:image/svg+xml,%3C%3Fxml version=%271.0%27 encoding=%27UTF-8%27 standalone=%27no%27%3F%3E%3Csvg xmlns:dc=%27http://purl.org/dc/elements/1.1/%27 xmlns:cc=%27http://creativecommons.org/ns%23%27 xmlns:rdf=%27http://www.w3.org/1999/02/22-rdf-syntax-ns%23%27 xmlns:svg=%27http://www.w3.org/2000/svg%27 xmlns=%27http://www.w3.org/2000/svg%27 xmlns:sodipodi=%27http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd%27 xmlns:inkscape=%27http://www.inkscape.org/namespaces/inkscape%27 width=%27240%27 height=%27144%27 id=%27svg4136%27 version=%271.1%27 inkscape:version=%270.91 r13725%27 sodipodi:docname=%27jsoneditor-icons.svg%27%3E%3Ctitle id=%27title6512%27%3EJSON Editor Icons%3C/title%3E%3Crect id=%27svg_1-7%27 height=%2716%27 width=%2716%27 y=%273.999995%27 x=%2728.000006%27 style=%27fill:%23ff511f;%27 /%3E%3Crect x=%277%27 y=%2711%27 width=%2710%27 height=%272%27 id=%27svg_1-1%27 style=%27fill:%23ffffff;%27 /%3E%3Crect x=%2711%27 y=%277%27 width=%272%27 height=%2710%27 id=%27svg_1-1-1%27 style=%27fill:%23ffffff;%27 /%3E%3Cg id=%27g4299-3%27 transform=%27matrix%280.70710678,-0.70710678,0.70710678,0.70710678,19.029435,12.000001%29%27 style=%27%27%3E%3Crect x=%277%27 y=%2711%27 width=%2710%27 height=%272%27 id=%27svg_1-1-0%27 style=%27fill:%23ffffff;%27 /%3E%3Crect x=%2711%27 y=%277%27 width=%272%27 height=%2710%27 id=%27svg_1-1-1-9%27 style=%27fill:%23ffffff;%27 /%3E%3C/g%3E%3Crect height=%277%27 width=%277%27 y=%277%27 x=%2755%27 style=%27fill:%23ffffff;stroke-width:1;stroke:%23ffffff%27 /%3E%3Crect id=%27svg_1-7-5-7%27 height=%277%27 width=%277%27 y=%2710%27 x=%2758%27 style=%27fill:%23ffffff;stroke-width:1;stroke:%231d1d1d%27 /%3E%3Cg id=%27g4378%27%3E%3Crect style=%27fill:%23ffffff;%27 x=%27198%27 y=%2711%27 width=%278%27 height=%272%27 id=%27svg_1-7-5-3%27 /%3E%3Crect id=%27rect4374%27 height=%272%27 width=%2712%27 y=%277%27 x=%27198%27 style=%27fill:%23ffffff;%27 /%3E%3Crect id=%27rect4376%27 height=%272%27 width=%274%27 y=%2715%27 x=%27198%27 style=%27fill:%23ffffff;%27 /%3E%3C/g%3E%3Cg transform=%27matrix%281,0,0,-1,-23.999995,23.999995%29%27 id=%27g4383%27%3E%3Crect id=%27rect4385%27 height=%272%27 width=%278%27 y=%2711%27 x=%27198%27 style=%27fill:%23ffffff;%27 /%3E%3Crect style=%27fill:%23ffffff;%27 x=%27198%27 y=%277%27 width=%2712%27 height=%272%27 id=%27rect4387%27 /%3E%3Crect style=%27fill:%23ffffff;%27 x=%27198%27 y=%2715%27 width=%274%27 height=%272%27 id=%27rect4389%27 /%3E%3C/g%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 85.10447,6.0157384 -0.0156,1.4063 c 3.02669,-0.2402 0.33008,3.6507996 2.48438,4.5780996 -2.18694,1.0938 0.49191,4.9069 -2.45313,4.5781 l -0.0156,1.4219 c 5.70828,0.559 1.03264,-5.1005 4.70313,-5.2656 l 0,-1.4063 c -3.61303,-0.027 1.11893,-5.7069996 -4.70313,-5.3124996 z%27 id=%27path4351%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 82.78125,5.9984384 0.0156,1.4063 c -3.02668,-0.2402 -0.33007,3.6506996 -2.48437,4.5780996 2.18694,1.0938 -0.49192,4.9069 2.45312,4.5781 l 0.0156,1.4219 c -5.70827,0.559 -1.03263,-5.1004 -4.70312,-5.2656 l 0,-1.4063 c 3.61303,-0.027 -1.11894,-5.7070996 4.70312,-5.3124996 z%27 id=%27path4351-9%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 103.719,5.6719384 0,12.7187996 3.03125,0 0,-1.5313 -1.34375,0 0,-9.6249996 1.375,0 0,-1.5625 z%27 id=%27path2987%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 112.2185,5.6721984 0,12.7187996 -3.03125,0 0,-1.5313 1.34375,0 0,-9.6249996 -1.375,0 0,-1.5625 z%27 id=%27path2987-1%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27M133,6.4h-1.9l-4.8,11.2h1.8l1.1-2.9h5.7l1.1,2.9h1.8L133,6.4z M129.7,13.5l2.3-5.5l2.3,5.5L129.7,13.5z%27 id=%27path3780%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 156.47655,5.8917384 0,2.1797 0.46093,2.3983996 1.82813,0 0.39844,-2.3983996 0,-2.1797 z%27 id=%27path5008-2%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 152.51561,5.8906384 0,2.1797 0.46094,2.3983996 1.82812,0 0.39844,-2.3983996 0,-2.1797 z%27 id=%27path5008-2-8%27 /%3E%3Crect id=%27svg_1-7-2%27 height=%272%27 width=%2712%27 y=%2764%27 x=%2754%27 style=%27fill:%236e6e6e;%27 /%3E%3Crect id=%27svg_1-7-2-2%27 height=%273%27 width=%273%27 y=%2752%27 x=%2780%27 style=%27fill:%236e6e6e;%27 /%3E%3Crect style=%27fill:%236e6e6e;%27 x=%2785%27 y=%2752%27 width=%273%27 height=%273%27 id=%27rect4561%27 /%3E%3Crect style=%27fill:%236e6e6e;%27 x=%2780%27 y=%2758%27 width=%273%27 height=%273%27 id=%27rect4563%27 /%3E%3Crect id=%27rect4565%27 height=%273%27 width=%273%27 y=%2758%27 x=%2785%27 style=%27fill:%236e6e6e;%27 /%3E%3Crect id=%27rect4567%27 height=%273%27 width=%273%27 y=%2764%27 x=%2780%27 style=%27fill:%236e6e6e;%27 /%3E%3Crect style=%27fill:%236e6e6e;%27 x=%2785%27 y=%2764%27 width=%273%27 height=%273%27 id=%27rect4569%27 /%3E%3Ccircle style=%27opacity:1;fill:none;stroke:%236e6e6e;stroke-width:2;%27 id=%27path4571%27 cx=%27110.06081%27 cy=%2757.939209%27 r=%274.7438836%27 /%3E%3Crect style=%27fill:%236e6e6e;%27 x=%27116.64566%27 y=%27-31.79752%27 width=%274.229713%27 height=%276.4053884%27 id=%27rect4563-2%27 transform=%27matrix%280.70710678,0.70710678,-0.70710678,0.70710678,0,0%29%27 /%3E%3Cpath style=%27fill:%236e6e6e;fill-rule:evenodd;%27 d=%27M 125,56 138.77027,56.095 132,64 Z%27 id=%27path4613%27 /%3E%3Cpath id=%27path4615%27 d=%27M 149,64 162.77027,63.905 156,56 Z%27 style=%27fill:%236e6e6e;fill-rule:evenodd;%27 /%3E%3Crect style=%27fill:%236e6e6e;%27 x=%2754%27 y=%2753%27 width=%2712%27 height=%272%27 id=%27rect4638%27 /%3E%3Crect id=%27svg_1-7-2-24%27 height=%272%27 width=%2713%27 y=%27-56%27 x=%2753%27 style=%27fill:%236e6e6e;%27 transform=%27matrix%280,1,-1,0,0,0%29%27 /%3E%3Crect transform=%27matrix%280,1,-1,0,0,0%29%27 style=%27fill:%236e6e6e;%27 x=%2753%27 y=%27-66%27 width=%2713%27 height=%272%27 id=%27rect4657%27 /%3E%3Crect id=%27rect4659%27 height=%271%27 width=%2712%27 y=%2757%27 x=%2754%27 style=%27fill:%236e6e6e;%27 /%3E%3Crect style=%27fill:%23ffffff;%27 x=%2754%27 y=%2788%27 width=%2712%27 height=%272%27 id=%27rect4661%27 /%3E%3Crect style=%27fill:%23ffffff;%27 x=%2780%27 y=%2776%27 width=%273%27 height=%273%27 id=%27rect4663%27 /%3E%3Crect id=%27rect4665%27 height=%273%27 width=%273%27 y=%2776%27 x=%2785%27 style=%27fill:%23ffffff;%27 /%3E%3Crect id=%27rect4667%27 height=%273%27 width=%273%27 y=%2782%27 x=%2780%27 style=%27fill:%23ffffff;%27 /%3E%3Crect style=%27fill:%23ffffff;%27 x=%2785%27 y=%2782%27 width=%273%27 height=%273%27 id=%27rect4669%27 /%3E%3Crect style=%27fill:%23ffffff;%27 x=%2780%27 y=%2788%27 width=%273%27 height=%273%27 id=%27rect4671%27 /%3E%3Crect id=%27rect4673%27 height=%273%27 width=%273%27 y=%2788%27 x=%2785%27 style=%27fill:%23ffffff;%27 /%3E%3Ccircle r=%274.7438836%27 cy=%2781.939331%27 cx=%27110.06081%27 id=%27circle4675%27 style=%27opacity:1;fill:none;stroke:%23ffffff;stroke-width:2;%27 /%3E%3Crect transform=%27matrix%280.70710678,0.70710678,-0.70710678,0.70710678,0,0%29%27 id=%27rect4677%27 height=%276.4053884%27 width=%274.229713%27 y=%27-14.826816%27 x=%27133.6163%27 style=%27fill:%23ffffff;%27 /%3E%3Cpath id=%27path4679%27 d=%27m 125,80.000005 13.77027,0.09499 L 132,87.999992 Z%27 style=%27fill:%23ffffff;%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27M 149,88.0002 162.77027,87.9052 156,80.0002 Z%27 id=%27path4681%27 /%3E%3Crect id=%27rect4683%27 height=%272%27 width=%2712%27 y=%2777%27 x=%2754%27 style=%27fill:%23ffffff;%27 /%3E%3Crect transform=%27matrix%280,1,-1,0,0,0%29%27 style=%27fill:%23ffffff;%27 x=%2777%27 y=%27-56%27 width=%2713%27 height=%272%27 id=%27rect4685%27 /%3E%3Crect id=%27rect4687%27 height=%272%27 width=%2713%27 y=%27-66%27 x=%2777%27 style=%27fill:%23ffffff;%27 transform=%27matrix%280,1,-1,0,0,0%29%27 /%3E%3Crect style=%27fill:%23ffffff;%27 x=%2754%27 y=%2781%27 width=%2712%27 height=%271%27 id=%27rect4689%27 /%3E%3Crect id=%27rect4761-1%27 height=%272%27 width=%2716%27 y=%27101%27 x=%2776%27 style=%27fill:%23ffffff;%27 /%3E%3Crect id=%27rect4761-0%27 height=%272%27 width=%2716%27 y=%27105%27 x=%2776%27 style=%27fill:%23ffffff;%27 /%3E%3Crect id=%27rect4761-7%27 height=%272%27 width=%279%27 y=%27109%27 x=%2776%27 style=%27fill:%23ffffff;%27 /%3E%3Crect id=%27rect4761-1-1%27 height=%272%27 width=%2712%27 y=%27125%27 x=%2776%27 style=%27fill:%23ffffff;%27 /%3E%3Crect id=%27rect4761-1-1-4%27 height=%272%27 width=%2710%27 y=%27137%27 x=%2776%27 style=%27fill:%23ffffff;%27 /%3E%3Crect id=%27rect4761-1-1-4-4%27 height=%272%27 width=%2710%27 y=%27129%27 x=%2782%27 style=%27fill:%23ffffff;%27 /%3E%3Crect id=%27rect4761-1-1-4-4-3%27 height=%272%27 width=%279%27 y=%27133%27 x=%2782%27 style=%27fill:%23ffffff;%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 36.398438,100.0254 c -0.423362,-0.013 -0.846847,0.01 -1.265626,0.062 -1.656562,0.2196 -3.244567,0.9739 -4.507812,2.2266 L 29,100.5991 l -2.324219,7.7129 7.826172,-1.9062 -1.804687,-1.9063 c 1.597702,-1.5308 4.048706,-1.8453 5.984375,-0.7207 1.971162,1.1452 2.881954,3.3975 2.308593,5.5508 -0.573361,2.1533 -2.533865,3.6953 -4.830078,3.6953 l 0,3.0742 c 3.550756,0 6.710442,-2.4113 7.650391,-5.9414 0.939949,-3.5301 -0.618463,-7.2736 -3.710938,-9.0703 -1.159678,-0.6738 -2.431087,-1.0231 -3.701171,-1.0625 z%27 id=%27path4138%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 59.722656,99.9629 c -1.270084,0.039 -2.541493,0.3887 -3.701172,1.0625 -3.092475,1.7967 -4.650886,5.5402 -3.710937,9.0703 0.939949,3.5301 4.09768,5.9414 7.648437,5.9414 l 0,-3.0742 c -2.296214,0 -4.256717,-1.542 -4.830078,-3.6953 -0.573361,-2.1533 0.337432,-4.4056 2.308594,-5.5508 1.935731,-1.1246 4.38863,-0.8102 5.986326,0.7207 l -1.806638,1.9063 7.828128,1.9062 -2.32422,-7.7129 -1.62696,1.7168 c -1.26338,-1.2531 -2.848917,-2.0088 -4.505855,-2.2285 -0.418778,-0.055 -0.842263,-0.076 -1.265625,-0.062 z%27 id=%27path4138-1%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 10.5,100 0,2 -2.4999996,0 L 12,107 l 4,-5 -2.5,0 0,-2 -3,0 z%27 id=%27path3055-0-77%27 /%3E%3Cpath style=%27fill:none;stroke:%23ffffff;%27 d=%27m 4.9850574,108.015 14.0298856,-0.03%27 id=%27path5244-5-0-5%27 /%3E%3Cpath style=%27fill:none;stroke:%23ffffff;%27 d=%27m 4.9849874,132.015 14.0298866,-0.03%27 id=%27path5244-5-0-5-8%27 /%3E%3Cpath style=%27color:%23000000;fill:%236e6e6e;%27 d=%27m 36.398438,123.9629 c -0.423362,-0.013 -0.846847,0.01 -1.265626,0.062 -1.656562,0.2196 -3.244567,0.9739 -4.507812,2.2266 L 29,124.5366 l -2.324219,7.7129 7.826172,-1.9062 -1.804687,-1.9063 c 1.597702,-1.5308 4.048706,-1.8453 5.984375,-0.7207 1.971162,1.1453 2.881954,3.3975 2.308593,5.5508 -0.573361,2.1533 -2.533864,3.6953 -4.830078,3.6953 l 0,3.0742 c 3.550757,0 6.710442,-2.4093 7.650391,-5.9394 0.939949,-3.5301 -0.618463,-7.2756 -3.710938,-9.0723 -1.159678,-0.6737 -2.431087,-1.0231 -3.701171,-1.0625 z%27 id=%27path4138-12%27 /%3E%3Cpath style=%27color:%23000000;fill:%236e6e6e;%27 d=%27m 59.722656,123.9629 c -1.270084,0.039 -2.541493,0.3888 -3.701172,1.0625 -3.092475,1.7967 -4.650886,5.5422 -3.710937,9.0723 0.939949,3.5301 4.09768,5.9394 7.648437,5.9394 l 0,-3.0742 c -2.296214,0 -4.256717,-1.542 -4.830078,-3.6953 -0.573361,-2.1533 0.337432,-4.4055 2.308594,-5.5508 1.935731,-1.1246 4.38863,-0.8102 5.986326,0.7207 l -1.806638,1.9063 7.828128,1.9062 -2.32422,-7.7129 -1.62696,1.7168 c -1.26338,-1.2531 -2.848917,-2.0088 -4.505855,-2.2285 -0.418778,-0.055 -0.842263,-0.076 -1.265625,-0.062 z%27 id=%27path4138-1-3%27 /%3E%3Cpath id=%27path6191%27 d=%27m 10.5,116 0,-2 -2.4999996,0 L 12,109 l 4,5 -2.5,0 0,2 -3,0 z%27 style=%27fill:%23ffffff;stroke-width:1.96599996;%27 /%3E%3Cpath style=%27fill:%23ffffff;stroke-width:1.96599996;%27 d=%27m 10.5,129 0,-2 -2.4999996,0 L 12,122 l 4,5 -2.5,0 0,2 -3,0 z%27 id=%27path6193%27 /%3E%3Cpath id=%27path6195%27 d=%27m 10.5,135 0,2 -2.4999996,0 L 12,142 l 4,-5 -2.5,0 0,-2 -3,0 z%27 style=%27fill:%23ffffff;stroke-width:1.96599996;%27 /%3E%3Cpath sodipodi:type=%27star%27 style=%27fill:%236e6e6e;%27 id=%27path4500%27 sodipodi:sides=%273%27 sodipodi:cx=%2711.55581%27 sodipodi:cy=%2760.073242%27 sodipodi:r1=%275.1116104%27 sodipodi:r2=%272.5558052%27 sodipodi:arg1=%270%27 sodipodi:arg2=%271.0471976%27 inkscape:flatsided=%27false%27 inkscape:rounded=%270%27 inkscape:randomized=%270%27 d=%27m 16.66742,60.073242 -3.833708,2.213392 -3.8337072,2.213393 0,-4.426785 0,-4.426784 3.8337082,2.213392 z%27 inkscape:transform-center-x=%27-1.2779026%27 /%3E%3Cpath inkscape:transform-center-x=%271.277902%27 d=%27m -31.500004,60.073242 -3.833708,2.213392 -3.833707,2.213393 0,-4.426785 0,-4.426784 3.833707,2.213392 z%27 inkscape:randomized=%270%27 inkscape:rounded=%270%27 inkscape:flatsided=%27false%27 sodipodi:arg2=%271.0471976%27 sodipodi:arg1=%270%27 sodipodi:r2=%272.5558052%27 sodipodi:r1=%275.1116104%27 sodipodi:cy=%2760.073242%27 sodipodi:cx=%27-36.611614%27 sodipodi:sides=%273%27 id=%27path4502%27 style=%27fill:%236e6e6e;%27 sodipodi:type=%27star%27 transform=%27scale%28-1,1%29%27 /%3E%3Cpath d=%27m 16.66742,60.073212 -3.833708,2.213392 -3.8337072,2.213392 0,-4.426784 0,-4.426785 3.8337082,2.213392 z%27 inkscape:randomized=%270%27 inkscape:rounded=%270%27 inkscape:flatsided=%27false%27 sodipodi:arg2=%271.0471976%27 sodipodi:arg1=%270%27 sodipodi:r2=%272.5558052%27 sodipodi:r1=%275.1116104%27 sodipodi:cy=%2760.073212%27 sodipodi:cx=%2711.55581%27 sodipodi:sides=%273%27 id=%27path4504%27 style=%27fill:%236e6e6e;%27 sodipodi:type=%27star%27 transform=%27matrix%280,1,-1,0,72.0074,71.7877%29%27 inkscape:transform-center-y=%271.2779029%27 /%3E%3Cpath inkscape:transform-center-y=%27-1.2779026%27 transform=%27matrix%280,-1,-1,0,96,96%29%27 sodipodi:type=%27star%27 style=%27fill:%236e6e6e;%27 id=%27path4506%27 sodipodi:sides=%273%27 sodipodi:cx=%2711.55581%27 sodipodi:cy=%2760.073212%27 sodipodi:r1=%275.1116104%27 sodipodi:r2=%272.5558052%27 sodipodi:arg1=%270%27 sodipodi:arg2=%271.0471976%27 inkscape:flatsided=%27false%27 inkscape:rounded=%270%27 inkscape:randomized=%270%27 d=%27m 16.66742,60.073212 -3.833708,2.213392 -3.8337072,2.213392 0,-4.426784 0,-4.426785 3.8337082,2.213392 z%27 /%3E%3Cpath id=%27path4615-5%27 d=%27m 171.82574,65.174193 16.34854,0 -8.17427,-13.348454 z%27 style=%27fill:%23f9a825;fill-rule:evenodd;stroke:%23f9a825;stroke-width:2;%27 /%3E%3Cpath style=%27opacity:1;fill:%23ffffff;%27 d=%27m 179,55 0,6 2,0 0,-6%27 id=%27path4300%27 /%3E%3Cpath style=%27opacity:1;fill:%23ffffff;%27 d=%27m 179,62 0,2 2,0 0,-2%27 id=%27path4300-6%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27M 99.994369,113.0221 102,114.98353 l 7,-6.9558 3,0.97227 2,-1 1,-2 0,-3 -3,3 -3,-3 3,-3 -3,0 -2,1 -1,2 0.99437,3.0221 z%27 id=%27path4268%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 234,6 0,2 -5,5 0,5 -2,0 0,-5 -5,-5 0,-2%27 id=%27path3546%27 /%3E%3Cg transform=%27matrix%281.3333328,0,0,-1.5999992,-139.9999,127.19999%29%27 id=%27g4383-6%27%3E%3Crect id=%27rect4385-2%27 height=%271%27 width=%276%27 y=%2712.625005%27 x=%27198%27 style=%27fill:%23ffffff;stroke:%23000000;stroke-width:0%27 /%3E%3Crect style=%27fill:%23ffffff;stroke:%23000000;stroke-width:0%27 x=%27198%27 y=%2715.125007%27 width=%278%27 height=%271%27 id=%27rect4387-9%27 /%3E%3Crect style=%27fill:%23ffffff;stroke:%23000000;stroke-width:0%27 x=%27198%27 y=%277.6250024%27 width=%273%27 height=%271%27 id=%27rect4389-1-0%27 /%3E%3Crect style=%27fill:%23ffffff;stroke:%23000000;stroke-width:0%27 x=%27198%27 y=%2710.125004%27 width=%274%27 height=%271%27 id=%27rect4389-1-9%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 207.00001,16.375004 0,-5.625005 -2.25,0 3,-3.1250014 3,3.1250014 -2.25,0 0,5.625005 -1.5,0%27 id=%27path4402%27 /%3E%3C/g%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 164,100 0,3 -6,6 0,7 -4,0 0,-7 -6,-6 0,-3%27 id=%27path3546-2-2%27 /%3E%3Cpath id=%27path4402-5-7%27 d=%27m 15,41 0,-7 -4,0 0,3 -5,-4 5,-4 0,3 6,0 0,9%27 style=%27fill:%23ffffff;%27 /%3E%3C/svg%3E%0A")}.light{--t42-json-icons: url("data:image/svg+xml,%3C%3Fxml version=%271.0%27 encoding=%27UTF-8%27 standalone=%27no%27%3F%3E%3Csvg xmlns:dc=%27http://purl.org/dc/elements/1.1/%27 xmlns:cc=%27http://creativecommons.org/ns%23%27 xmlns:rdf=%27http://www.w3.org/1999/02/22-rdf-syntax-ns%23%27 xmlns:svg=%27http://www.w3.org/2000/svg%27 xmlns=%27http://www.w3.org/2000/svg%27 xmlns:sodipodi=%27http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd%27 xmlns:inkscape=%27http://www.inkscape.org/namespaces/inkscape%27 width=%27240%27 height=%27144%27 id=%27svg4136%27 version=%271.1%27 inkscape:version=%270.91 r13725%27 sodipodi:docname=%27jsoneditor-icons.svg%27%3E%3Ctitle id=%27title6512%27%3EJSON Editor Icons%3C/title%3E%3Crect id=%27svg_1-7%27 height=%2716%27 width=%2716%27 y=%273.999995%27 x=%2728.000006%27 style=%27fill:%23ff511f;%27 /%3E%3Crect x=%277%27 y=%2711%27 width=%2710%27 height=%272%27 id=%27svg_1-1%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect x=%2711%27 y=%277%27 width=%272%27 height=%2710%27 id=%27svg_1-1-1%27 style=%27fill:%230d0d0d;%27 /%3E%3Cg id=%27g4299-3%27 transform=%27matrix%280.70710678,-0.70710678,0.70710678,0.70710678,19.029435,12.000001%29%27 style=%27%27%3E%3Crect x=%277%27 y=%2711%27 width=%2710%27 height=%272%27 id=%27svg_1-1-0%27 style=%27fill:%23ffffff;%27 /%3E%3Crect x=%2711%27 y=%277%27 width=%272%27 height=%2710%27 id=%27svg_1-1-1-9%27 style=%27fill:%23ffffff;%27 /%3E%3C/g%3E%3Crect height=%277%27 width=%277%27 y=%277%27 x=%2755%27 style=%27fill:%230d0d0d;stroke-width:1;stroke:%230d0d0d%27 /%3E%3Crect id=%27svg_1-7-5-7%27 height=%277%27 width=%277%27 y=%2710%27 x=%2758%27 style=%27fill:%230d0d0d;stroke-width:1;stroke:%23ffffff%27 /%3E%3Cg id=%27g4378%27%3E%3Crect style=%27fill:%230d0d0d;%27 x=%27198%27 y=%2711%27 width=%278%27 height=%272%27 id=%27svg_1-7-5-3%27 /%3E%3Crect id=%27rect4374%27 height=%272%27 width=%2712%27 y=%277%27 x=%27198%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect id=%27rect4376%27 height=%272%27 width=%274%27 y=%2715%27 x=%27198%27 style=%27fill:%230d0d0d;%27 /%3E%3C/g%3E%3Cg transform=%27matrix%281,0,0,-1,-23.999995,23.999995%29%27 id=%27g4383%27%3E%3Crect id=%27rect4385%27 height=%272%27 width=%278%27 y=%2711%27 x=%27198%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect style=%27fill:%230d0d0d;%27 x=%27198%27 y=%277%27 width=%2712%27 height=%272%27 id=%27rect4387%27 /%3E%3Crect style=%27fill:%230d0d0d;%27 x=%27198%27 y=%2715%27 width=%274%27 height=%272%27 id=%27rect4389%27 /%3E%3C/g%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 85.10447,6.0157384 -0.0156,1.4063 c 3.02669,-0.2402 0.33008,3.6507996 2.48438,4.5780996 -2.18694,1.0938 0.49191,4.9069 -2.45313,4.5781 l -0.0156,1.4219 c 5.70828,0.559 1.03264,-5.1005 4.70313,-5.2656 l 0,-1.4063 c -3.61303,-0.027 1.11893,-5.7069996 -4.70313,-5.3124996 z%27 id=%27path4351%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 82.78125,5.9984384 0.0156,1.4063 c -3.02668,-0.2402 -0.33007,3.6506996 -2.48437,4.5780996 2.18694,1.0938 -0.49192,4.9069 2.45312,4.5781 l 0.0156,1.4219 c -5.70827,0.559 -1.03263,-5.1004 -4.70312,-5.2656 l 0,-1.4063 c 3.61303,-0.027 -1.11894,-5.7070996 4.70312,-5.3124996 z%27 id=%27path4351-9%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 103.719,5.6719384 0,12.7187996 3.03125,0 0,-1.5313 -1.34375,0 0,-9.6249996 1.375,0 0,-1.5625 z%27 id=%27path2987%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 112.2185,5.6721984 0,12.7187996 -3.03125,0 0,-1.5313 1.34375,0 0,-9.6249996 -1.375,0 0,-1.5625 z%27 id=%27path2987-1%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27M133,6.4h-1.9l-4.8,11.2h1.8l1.1-2.9h5.7l1.1,2.9h1.8L133,6.4z M129.7,13.5l2.3-5.5l2.3,5.5L129.7,13.5z%27 id=%27path3780%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 156.47655,5.8917384 0,2.1797 0.46093,2.3983996 1.82813,0 0.39844,-2.3983996 0,-2.1797 z%27 id=%27path5008-2%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 152.51561,5.8906384 0,2.1797 0.46094,2.3983996 1.82812,0 0.39844,-2.3983996 0,-2.1797 z%27 id=%27path5008-2-8%27 /%3E%3Crect id=%27svg_1-7-2%27 height=%272%27 width=%2712%27 y=%2764%27 x=%2754%27 style=%27fill:%236e6e6e;%27 /%3E%3Crect id=%27svg_1-7-2-2%27 height=%273%27 width=%273%27 y=%2752%27 x=%2780%27 style=%27fill:%236e6e6e;%27 /%3E%3Crect style=%27fill:%236e6e6e;%27 x=%2785%27 y=%2752%27 width=%273%27 height=%273%27 id=%27rect4561%27 /%3E%3Crect style=%27fill:%236e6e6e;%27 x=%2780%27 y=%2758%27 width=%273%27 height=%273%27 id=%27rect4563%27 /%3E%3Crect id=%27rect4565%27 height=%273%27 width=%273%27 y=%2758%27 x=%2785%27 style=%27fill:%236e6e6e;%27 /%3E%3Crect id=%27rect4567%27 height=%273%27 width=%273%27 y=%2764%27 x=%2780%27 style=%27fill:%236e6e6e;%27 /%3E%3Crect style=%27fill:%236e6e6e;%27 x=%2785%27 y=%2764%27 width=%273%27 height=%273%27 id=%27rect4569%27 /%3E%3Ccircle style=%27opacity:1;fill:none;stroke:%236e6e6e;stroke-width:2;%27 id=%27path4571%27 cx=%27110.06081%27 cy=%2757.939209%27 r=%274.7438836%27 /%3E%3Crect style=%27fill:%236e6e6e;%27 x=%27116.64566%27 y=%27-31.79752%27 width=%274.229713%27 height=%276.4053884%27 id=%27rect4563-2%27 transform=%27matrix%280.70710678,0.70710678,-0.70710678,0.70710678,0,0%29%27 /%3E%3Cpath style=%27fill:%236e6e6e;fill-rule:evenodd;%27 d=%27M 125,56 138.77027,56.095 132,64 Z%27 id=%27path4613%27 /%3E%3Cpath id=%27path4615%27 d=%27M 149,64 162.77027,63.905 156,56 Z%27 style=%27fill:%236e6e6e;fill-rule:evenodd;%27 /%3E%3Crect style=%27fill:%236e6e6e;%27 x=%2754%27 y=%2753%27 width=%2712%27 height=%272%27 id=%27rect4638%27 /%3E%3Crect id=%27svg_1-7-2-24%27 height=%272%27 width=%2713%27 y=%27-56%27 x=%2753%27 style=%27fill:%236e6e6e;%27 transform=%27matrix%280,1,-1,0,0,0%29%27 /%3E%3Crect transform=%27matrix%280,1,-1,0,0,0%29%27 style=%27fill:%236e6e6e;%27 x=%2753%27 y=%27-66%27 width=%2713%27 height=%272%27 id=%27rect4657%27 /%3E%3Crect id=%27rect4659%27 height=%271%27 width=%2712%27 y=%2757%27 x=%2754%27 style=%27fill:%236e6e6e;%27 /%3E%3Crect style=%27fill:%230d0d0d;%27 x=%2754%27 y=%2788%27 width=%2712%27 height=%272%27 id=%27rect4661%27 /%3E%3Crect style=%27fill:%230d0d0d;%27 x=%2780%27 y=%2776%27 width=%273%27 height=%273%27 id=%27rect4663%27 /%3E%3Crect id=%27rect4665%27 height=%273%27 width=%273%27 y=%2776%27 x=%2785%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect id=%27rect4667%27 height=%273%27 width=%273%27 y=%2782%27 x=%2780%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect style=%27fill:%230d0d0d;%27 x=%2785%27 y=%2782%27 width=%273%27 height=%273%27 id=%27rect4669%27 /%3E%3Crect style=%27fill:%230d0d0d;%27 x=%2780%27 y=%2788%27 width=%273%27 height=%273%27 id=%27rect4671%27 /%3E%3Crect id=%27rect4673%27 height=%273%27 width=%273%27 y=%2788%27 x=%2785%27 style=%27fill:%230d0d0d;%27 /%3E%3Ccircle r=%274.7438836%27 cy=%2781.939331%27 cx=%27110.06081%27 id=%27circle4675%27 style=%27opacity:1;fill:none;stroke:%230d0d0d;stroke-width:2;%27 /%3E%3Crect transform=%27matrix%280.70710678,0.70710678,-0.70710678,0.70710678,0,0%29%27 id=%27rect4677%27 height=%276.4053884%27 width=%274.229713%27 y=%27-14.826816%27 x=%27133.6163%27 style=%27fill:%230d0d0d;%27 /%3E%3Cpath id=%27path4679%27 d=%27m 125,80.000005 13.77027,0.09499 L 132,87.999992 Z%27 style=%27fill:%230d0d0d;%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27M 149,88.0002 162.77027,87.9052 156,80.0002 Z%27 id=%27path4681%27 /%3E%3Crect id=%27rect4683%27 height=%272%27 width=%2712%27 y=%2777%27 x=%2754%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect transform=%27matrix%280,1,-1,0,0,0%29%27 style=%27fill:%230d0d0d;%27 x=%2777%27 y=%27-56%27 width=%2713%27 height=%272%27 id=%27rect4685%27 /%3E%3Crect id=%27rect4687%27 height=%272%27 width=%2713%27 y=%27-66%27 x=%2777%27 style=%27fill:%230d0d0d;%27 transform=%27matrix%280,1,-1,0,0,0%29%27 /%3E%3Crect style=%27fill:%230d0d0d;%27 x=%2754%27 y=%2781%27 width=%2712%27 height=%271%27 id=%27rect4689%27 /%3E%3Crect id=%27rect4761-1%27 height=%272%27 width=%2716%27 y=%27101%27 x=%2776%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect id=%27rect4761-0%27 height=%272%27 width=%2716%27 y=%27105%27 x=%2776%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect id=%27rect4761-7%27 height=%272%27 width=%279%27 y=%27109%27 x=%2776%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect id=%27rect4761-1-1%27 height=%272%27 width=%2712%27 y=%27125%27 x=%2776%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect id=%27rect4761-1-1-4%27 height=%272%27 width=%2710%27 y=%27137%27 x=%2776%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect id=%27rect4761-1-1-4-4%27 height=%272%27 width=%2710%27 y=%27129%27 x=%2782%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect id=%27rect4761-1-1-4-4-3%27 height=%272%27 width=%279%27 y=%27133%27 x=%2782%27 style=%27fill:%230d0d0d;%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 36.398438,100.0254 c -0.423362,-0.013 -0.846847,0.01 -1.265626,0.062 -1.656562,0.2196 -3.244567,0.9739 -4.507812,2.2266 L 29,100.5991 l -2.324219,7.7129 7.826172,-1.9062 -1.804687,-1.9063 c 1.597702,-1.5308 4.048706,-1.8453 5.984375,-0.7207 1.971162,1.1452 2.881954,3.3975 2.308593,5.5508 -0.573361,2.1533 -2.533865,3.6953 -4.830078,3.6953 l 0,3.0742 c 3.550756,0 6.710442,-2.4113 7.650391,-5.9414 0.939949,-3.5301 -0.618463,-7.2736 -3.710938,-9.0703 -1.159678,-0.6738 -2.431087,-1.0231 -3.701171,-1.0625 z%27 id=%27path4138%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 59.722656,99.9629 c -1.270084,0.039 -2.541493,0.3887 -3.701172,1.0625 -3.092475,1.7967 -4.650886,5.5402 -3.710937,9.0703 0.939949,3.5301 4.09768,5.9414 7.648437,5.9414 l 0,-3.0742 c -2.296214,0 -4.256717,-1.542 -4.830078,-3.6953 -0.573361,-2.1533 0.337432,-4.4056 2.308594,-5.5508 1.935731,-1.1246 4.38863,-0.8102 5.986326,0.7207 l -1.806638,1.9063 7.828128,1.9062 -2.32422,-7.7129 -1.62696,1.7168 c -1.26338,-1.2531 -2.848917,-2.0088 -4.505855,-2.2285 -0.418778,-0.055 -0.842263,-0.076 -1.265625,-0.062 z%27 id=%27path4138-1%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 10.5,100 0,2 -2.4999996,0 L 12,107 l 4,-5 -2.5,0 0,-2 -3,0 z%27 id=%27path3055-0-77%27 /%3E%3Cpath style=%27fill:none;stroke:%230d0d0d;%27 d=%27m 4.9850574,108.015 14.0298856,-0.03%27 id=%27path5244-5-0-5%27 /%3E%3Cpath style=%27fill:none;stroke:%230d0d0d;%27 d=%27m 4.9849874,132.015 14.0298866,-0.03%27 id=%27path5244-5-0-5-8%27 /%3E%3Cpath style=%27color:%23000000;fill:%236e6e6e;%27 d=%27m 36.398438,123.9629 c -0.423362,-0.013 -0.846847,0.01 -1.265626,0.062 -1.656562,0.2196 -3.244567,0.9739 -4.507812,2.2266 L 29,124.5366 l -2.324219,7.7129 7.826172,-1.9062 -1.804687,-1.9063 c 1.597702,-1.5308 4.048706,-1.8453 5.984375,-0.7207 1.971162,1.1453 2.881954,3.3975 2.308593,5.5508 -0.573361,2.1533 -2.533864,3.6953 -4.830078,3.6953 l 0,3.0742 c 3.550757,0 6.710442,-2.4093 7.650391,-5.9394 0.939949,-3.5301 -0.618463,-7.2756 -3.710938,-9.0723 -1.159678,-0.6737 -2.431087,-1.0231 -3.701171,-1.0625 z%27 id=%27path4138-12%27 /%3E%3Cpath style=%27color:%23000000;fill:%236e6e6e;%27 d=%27m 59.722656,123.9629 c -1.270084,0.039 -2.541493,0.3888 -3.701172,1.0625 -3.092475,1.7967 -4.650886,5.5422 -3.710937,9.0723 0.939949,3.5301 4.09768,5.9394 7.648437,5.9394 l 0,-3.0742 c -2.296214,0 -4.256717,-1.542 -4.830078,-3.6953 -0.573361,-2.1533 0.337432,-4.4055 2.308594,-5.5508 1.935731,-1.1246 4.38863,-0.8102 5.986326,0.7207 l -1.806638,1.9063 7.828128,1.9062 -2.32422,-7.7129 -1.62696,1.7168 c -1.26338,-1.2531 -2.848917,-2.0088 -4.505855,-2.2285 -0.418778,-0.055 -0.842263,-0.076 -1.265625,-0.062 z%27 id=%27path4138-1-3%27 /%3E%3Cpath id=%27path6191%27 d=%27m 10.5,116 0,-2 -2.4999996,0 L 12,109 l 4,5 -2.5,0 0,2 -3,0 z%27 style=%27fill:%230d0d0d;stroke-width:2;%27 /%3E%3Cpath style=%27fill:%230d0d0d;stroke-width:2;%27 d=%27m 10.5,129 0,-2 -2.4999996,0 L 12,122 l 4,5 -2.5,0 0,2 -3,0 z%27 id=%27path6193%27 /%3E%3Cpath id=%27path6195%27 d=%27m 10.5,135 0,2 -2.4999996,0 L 12,142 l 4,-5 -2.5,0 0,-2 -3,0 z%27 style=%27fill:%230d0d0d;stroke-width:2;%27 /%3E%3Cpath sodipodi:type=%27star%27 style=%27fill:%236e6e6e;%27 id=%27path4500%27 sodipodi:sides=%273%27 sodipodi:cx=%2711.55581%27 sodipodi:cy=%2760.073242%27 sodipodi:r1=%275.1116104%27 sodipodi:r2=%272.5558052%27 sodipodi:arg1=%270%27 sodipodi:arg2=%271.0471976%27 inkscape:flatsided=%27false%27 inkscape:rounded=%270%27 inkscape:randomized=%270%27 d=%27m 16.66742,60.073242 -3.833708,2.213392 -3.8337072,2.213393 0,-4.426785 0,-4.426784 3.8337082,2.213392 z%27 inkscape:transform-center-x=%27-1.2779026%27 /%3E%3Cpath inkscape:transform-center-x=%271.277902%27 d=%27m -31.500004,60.073242 -3.833708,2.213392 -3.833707,2.213393 0,-4.426785 0,-4.426784 3.833707,2.213392 z%27 inkscape:randomized=%270%27 inkscape:rounded=%270%27 inkscape:flatsided=%27false%27 sodipodi:arg2=%271.0471976%27 sodipodi:arg1=%270%27 sodipodi:r2=%272.5558052%27 sodipodi:r1=%275.1116104%27 sodipodi:cy=%2760.073242%27 sodipodi:cx=%27-36.611614%27 sodipodi:sides=%273%27 id=%27path4502%27 style=%27fill:%236e6e6e;%27 sodipodi:type=%27star%27 transform=%27scale%28-1,1%29%27 /%3E%3Cpath d=%27m 16.66742,60.073212 -3.833708,2.213392 -3.8337072,2.213392 0,-4.426784 0,-4.426785 3.8337082,2.213392 z%27 inkscape:randomized=%270%27 inkscape:rounded=%270%27 inkscape:flatsided=%27false%27 sodipodi:arg2=%271.0471976%27 sodipodi:arg1=%270%27 sodipodi:r2=%272.5558052%27 sodipodi:r1=%275.1116104%27 sodipodi:cy=%2760.073212%27 sodipodi:cx=%2711.55581%27 sodipodi:sides=%273%27 id=%27path4504%27 style=%27fill:%236e6e6e;%27 sodipodi:type=%27star%27 transform=%27matrix%280,1,-1,0,72.0074,71.7877%29%27 inkscape:transform-center-y=%271.2779029%27 /%3E%3Cpath inkscape:transform-center-y=%27-1.2779026%27 transform=%27matrix%280,-1,-1,0,96,96%29%27 sodipodi:type=%27star%27 style=%27fill:%236e6e6e;%27 id=%27path4506%27 sodipodi:sides=%273%27 sodipodi:cx=%2711.55581%27 sodipodi:cy=%2760.073212%27 sodipodi:r1=%275.1116104%27 sodipodi:r2=%272.5558052%27 sodipodi:arg1=%270%27 sodipodi:arg2=%271.0471976%27 inkscape:flatsided=%27false%27 inkscape:rounded=%270%27 inkscape:randomized=%270%27 d=%27m 16.66742,60.073212 -3.833708,2.213392 -3.8337072,2.213392 0,-4.426784 0,-4.426785 3.8337082,2.213392 z%27 /%3E%3Cpath id=%27path4615-5%27 d=%27m 171.82574,65.174193 16.34854,0 -8.17427,-13.348454 z%27 style=%27fill:%23f9a825;fill-rule:evenodd;stroke:%23f9a825;stroke-width:2;%27 /%3E%3Cpath style=%27opacity:1;fill:%23ffffff;%27 d=%27m 179,55 0,6 2,0 0,-6%27 id=%27path4300%27 /%3E%3Cpath style=%27opacity:1;fill:%23ffffff;%27 d=%27m 179,62 0,2 2,0 0,-2%27 id=%27path4300-6%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27M 99.994369,113.0221 102,114.98353 l 7,-6.9558 3,0.97227 2,-1 1,-2 0,-3 -3,3 -3,-3 3,-3 -3,0 -2,1 -1,2 0.99437,3.0221 z%27 id=%27path4268%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 234,6 0,2 -5,5 0,5 -2,0 0,-5 -5,-5 0,-2%27 id=%27path3546%27 /%3E%3Cg transform=%27matrix%281.3333328,0,0,-1.5999992,-139.9999,127.19999%29%27 id=%27g4383-6%27%3E%3Crect id=%27rect4385-2%27 height=%271%27 width=%276%27 y=%2712.625005%27 x=%27198%27 style=%27fill:%230d0d0d;stroke:%23000000;stroke-width:0%27 /%3E%3Crect style=%27fill:%230d0d0d;stroke:%23000000;stroke-width:0%27 x=%27198%27 y=%2715.125007%27 width=%278%27 height=%271%27 id=%27rect4387-9%27 /%3E%3Crect style=%27fill:%230d0d0d;stroke:%23000000;stroke-width:0%27 x=%27198%27 y=%277.6250024%27 width=%273%27 height=%271%27 id=%27rect4389-1-0%27 /%3E%3Crect style=%27fill:%230d0d0d;stroke:%23000000;stroke-width:0%27 x=%27198%27 y=%2710.125004%27 width=%274%27 height=%271%27 id=%27rect4389-1-9%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 207.00001,16.375004 0,-5.625005 -2.25,0 3,-3.1250014 3,3.1250014 -2.25,0 0,5.625005 -1.5,0%27 id=%27path4402%27 /%3E%3C/g%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 164,100 0,3 -6,6 0,7 -4,0 0,-7 -6,-6 0,-3%27 id=%27path3546-2-2%27 /%3E%3Cpath id=%27path4402-5-7%27 d=%27m 15,41 0,-7 -4,0 0,3 -5,-4 5,-4 0,3 6,0 0,9%27 style=%27fill:%230d0d0d;%27 /%3E%3C/svg%3E%0A")}body{/*! + * Selectr 2.4.13 + * http://mobius.ovh/docs/selectr + * + * Released under the MIT license + */}body .jsoneditor,body .jsoneditor-modal{-webkit-text-size-adjust:none;text-size-adjust:none}body .jsoneditor input,body .jsoneditor input:not([type]),body .jsoneditor input[type="text"],body .jsoneditor input[type="search"],body .jsoneditor-modal input,body .jsoneditor-modal input:not([type]),body .jsoneditor-modal input[type="text"],body .jsoneditor-modal input[type="search"]{height:auto;border:inherit;box-shadow:none;font-size:inherit;box-sizing:inherit;padding:inherit;font-family:inherit;transition:none;line-height:inherit}body .jsoneditor input:focus,body .jsoneditor input:not([type]):focus,body .jsoneditor input[type="text"]:focus,body .jsoneditor input[type="search"]:focus,body .jsoneditor-modal input:focus,body .jsoneditor-modal input:not([type]):focus,body .jsoneditor-modal input[type="text"]:focus,body .jsoneditor-modal input[type="search"]:focus{border:inherit;box-shadow:inherit}body .jsoneditor textarea,body .jsoneditor-modal textarea{height:inherit}body .jsoneditor select,body .jsoneditor-modal select{display:inherit;height:inherit}body .jsoneditor label,body .jsoneditor-modal label{font-size:inherit;font-weight:inherit;color:inherit}body .jsoneditor table,body .jsoneditor-modal table{border-collapse:collapse;width:auto}body .jsoneditor td,body .jsoneditor th,body .jsoneditor-modal td,body .jsoneditor-modal th{padding:0;display:table-cell;text-align:left;vertical-align:inherit;border-radius:inherit}body .jsoneditor .autocomplete.dropdown{position:absolute;background:var(--t42-content-color);box-shadow:var(--t42-shadow);border:1px solid var(--t42-color-opacity-10);overflow-x:hidden;overflow-y:auto;cursor:default;margin:0;padding:5px;text-align:left;outline:0;font-family:var(--bs-font-monospace);font-size:var(--t42-font-size)}body .jsoneditor .autocomplete.dropdown .item{color:var(--t42-content-color)}body .jsoneditor .autocomplete.dropdown .item.hover{background-color:Rgb(var(--t42-bg-mid))}body .jsoneditor .autocomplete.hint{color:var(--t42-content-color);top:4px;left:4px}body .jsoneditor-contextmenu-root{position:relative;width:0;height:0}body .jsoneditor-contextmenu{position:absolute;box-sizing:content-box;z-index:2}body .jsoneditor-contextmenu .jsoneditor-menu{position:relative;left:0;top:0;width:128px;height:auto;background:var(--t42-content-color);border:1px solid var(--t42-color-opacity-10);box-shadow:var(--t42-shadow);list-style:none;margin:0;padding:0}body .jsoneditor-contextmenu .jsoneditor-menu button{position:relative;padding:0 8px 0 0;margin:0;width:128px;height:auto;border:none;cursor:pointer;color:var(--t42-content-color);background:transparent;font-size:var(--t42-font-size);font-family:var(--t42-font-family);box-sizing:border-box;text-align:left}body .jsoneditor-contextmenu .jsoneditor-menu button::-moz-focus-inner{padding:0;border:0}body .jsoneditor-contextmenu .jsoneditor-menu button.jsoneditor-default{width:96px}body .jsoneditor-contextmenu .jsoneditor-menu button.jsoneditor-expand{float:right;width:32px;height:24px;border-left:1px solid var(--t42-color-opacity-10)}body .jsoneditor-contextmenu .jsoneditor-menu li{overflow:hidden}body .jsoneditor-contextmenu .jsoneditor-menu li ul{display:none;position:relative;left:-10px;top:0;border:none;box-shadow:inset var(--t42-shadow);padding:0 10px;-webkit-transition:all 0.3s ease-out;-moz-transition:all 0.3s ease-out;-o-transition:all 0.3s ease-out;transition:all 0.3s ease-out}body .jsoneditor-contextmenu .jsoneditor-menu li ul .jsoneditor-icon{margin-left:24px}body .jsoneditor-contextmenu .jsoneditor-menu li ul li button{padding-left:24px;animation:all ease-in-out 1s}body .jsoneditor-contextmenu .jsoneditor-menu li button .jsoneditor-expand{position:absolute;top:0;right:0;width:24px;height:24px;padding:0;margin:0 4px 0 0;background-image:"/";background-position:0 -72px}body .jsoneditor-contextmenu .jsoneditor-icon{position:absolute;top:0;left:0;width:24px;height:24px;border:none;padding:0;margin:0;background-image:"/"}body .jsoneditor-contextmenu .jsoneditor-text{padding:4px 0 4px 24px;word-wrap:break-word}body .jsoneditor-contextmenu .jsoneditor-text.jsoneditor-right-margin{padding-right:24px}body .jsoneditor-contextmenu .jsoneditor-separator{height:0;border-top:1px solid var(--t42-color-opacity-10);padding-top:5px;margin-top:5px}body .jsoneditor-contextmenu button.jsoneditor-remove .jsoneditor-icon{background-position:-24px 0}body .jsoneditor-contextmenu button.jsoneditor-append .jsoneditor-icon{background-position:0 0}body .jsoneditor-contextmenu button.jsoneditor-insert .jsoneditor-icon{background-position:0 0}body .jsoneditor-contextmenu button.jsoneditor-duplicate .jsoneditor-icon{background-position:-48px 0}body .jsoneditor-contextmenu button.jsoneditor-sort-asc .jsoneditor-icon{background-position:-168px 0}body .jsoneditor-contextmenu button.jsoneditor-sort-desc .jsoneditor-icon{background-position:-192px 0}body .jsoneditor-contextmenu button.jsoneditor-transform .jsoneditor-icon{background-position:-216px 0}body .jsoneditor-contextmenu button.jsoneditor-extract .jsoneditor-icon{background-position:0 -24px}body .jsoneditor-contextmenu button.jsoneditor-type-string .jsoneditor-icon{background-position:-144px 0}body .jsoneditor-contextmenu button.jsoneditor-type-auto .jsoneditor-icon{background-position:-120px 0}body .jsoneditor-contextmenu button.jsoneditor-type-object .jsoneditor-icon{background-position:-72px 0}body .jsoneditor-contextmenu button.jsoneditor-type-array .jsoneditor-icon{background-position:-96px 0}body .jsoneditor-contextmenu button.jsoneditor-type-modes .jsoneditor-icon{background-image:none;width:6px}body .jsoneditor-contextmenu ul,body .jsoneditor-contextmenu li{box-sizing:content-box;position:relative}body .jsoneditor-contextmenu .jsoneditor-menu button:hover,body .jsoneditor-contextmenu .jsoneditor-menu button:focus{color:var(--t42-content-color);background-color:var(--t42-color-opacity-10);outline:none}body .jsoneditor-contextmenu .jsoneditor-menu li button.jsoneditor-selected,body .jsoneditor-contextmenu .jsoneditor-menu li button.jsoneditor-selected:hover,body .jsoneditor-contextmenu .jsoneditor-menu li button.jsoneditor-selected:focus{color:var(--t42-content-color);background-color:var(--red)}body .jsoneditor-contextmenu .jsoneditor-menu li ul li button:hover,body .jsoneditor-contextmenu .jsoneditor-menu li ul li button:focus{background-color:var(--t42-color-opacity-10)}body .jsoneditor-modal{max-width:95%;border-radius:2px !important;padding:45px 15px 15px 15px !important;box-shadow:var(--t42-shadow);color:var(--t42-content-color);line-height:1.3em}body .jsoneditor-modal.jsoneditor-modal-transform{width:600px !important}body .jsoneditor-modal .pico-modal-header{position:absolute;box-sizing:border-box;top:0;left:0;width:100%;padding:0 10px;height:30px;line-height:30px;font-family:var(--t42-font-family);font-size:11pt;background:var(--primary);color:var(--t42-content-color)}body .jsoneditor-modal table{width:100%}body .jsoneditor-modal table td{padding:3px 0}body .jsoneditor-modal table td.jsoneditor-modal-input{text-align:right;padding-right:0;white-space:nowrap}body .jsoneditor-modal table td.jsoneditor-modal-actions{padding-top:15px}body .jsoneditor-modal table th{vertical-align:middle}body .jsoneditor-modal p:first-child{margin-top:0}body .jsoneditor-modal a{color:var(--primary)}body .jsoneditor-modal .jsoneditor-jmespath-block{margin-bottom:10px}body .jsoneditor-modal .pico-close{background:none !important;font-size:24px !important;top:7px !important;right:7px !important;color:var(--t42-content-color)}body .jsoneditor-modal input{padding:4px}body .jsoneditor-modal input[type="text"]{cursor:inherit}body .jsoneditor-modal input[disabled]{background:var(--t42-content-color-muted);color:var(--t42-content-color-muted)}body .jsoneditor-modal .jsoneditor-select-wrapper{position:relative;display:inline-block}body .jsoneditor-modal .jsoneditor-select-wrapper:after{content:"";width:0;height:0;border-left:5px solid transparent;border-right:5px solid transparent;border-top:6px solid #666;position:absolute;right:8px;top:14px;pointer-events:none}body .jsoneditor-modal select{padding:3px 24px 3px 10px;min-width:180px;max-width:350px;-webkit-appearance:none;-moz-appearance:none;appearance:none;text-indent:0;text-overflow:"";font-size:var(--t42-font-size);line-height:1.5em}body .jsoneditor-modal select::-ms-expand{display:none}body .jsoneditor-modal .jsoneditor-button-group input{padding:4px 10px;margin:0;border-radius:0;border-left-style:none}body .jsoneditor-modal .jsoneditor-button-group input.jsoneditor-button-first{border-top-left-radius:3px;border-bottom-left-radius:3px;border-left-style:solid}body .jsoneditor-modal .jsoneditor-button-group input.jsoneditor-button-last{border-top-right-radius:3px;border-bottom-right-radius:3px}body .jsoneditor-modal .jsoneditor-transform-preview{background:var(--t42-color-opacity-10);height:200px}body .jsoneditor-modal .jsoneditor-transform-preview.jsoneditor-error{color:var(--red)}body .jsoneditor-modal .jsoneditor-jmespath-wizard{line-height:1.2em;width:100%;padding:0;border-radius:3px}body .jsoneditor-modal .jsoneditor-jmespath-label{font-weight:bold;color:dodgerblue;margin-top:20px;margin-bottom:5px}body .jsoneditor-modal .jsoneditor-jmespath-wizard-table{width:100%;border-collapse:collapse}body .jsoneditor-modal .jsoneditor-jmespath-wizard-label{font-style:italic;margin:4px 0 2px 0}body .jsoneditor-modal .jsoneditor-inline{position:relative;display:inline-block;width:100%;padding-top:2px;padding-bottom:2px}body .jsoneditor-modal .jsoneditor-inline:not(:last-child){padding-right:2px}body .jsoneditor-modal .jsoneditor-jmespath-filter{display:flex;flex-wrap:wrap}body .jsoneditor-modal .jsoneditor-jmespath-filter-field{width:180px}body .jsoneditor-modal .jsoneditor-jmespath-filter-relation{width:100px}body .jsoneditor-modal .jsoneditor-jmespath-filter-value{min-width:180px;flex:1}body .jsoneditor-modal .jsoneditor-jmespath-sort-field{width:170px}body .jsoneditor-modal .jsoneditor-jmespath-sort-order{width:150px}body .jsoneditor-modal .jsoneditor-jmespath-select-fields{width:100%}body .jsoneditor-modal .selectr-selected{border-color:var(--t42-color-opacity-10);padding:4px 28px 4px 8px}body .jsoneditor-modal .selectr-selected .selectr-tag{background-color:var(--primary);border-radius:5px}body .jsoneditor-modal table th,body .jsoneditor-modal table td{text-align:left;vertical-align:middle;font-weight:normal;color:var(--t42-content-color);border-spacing:0;border-collapse:collapse}body .jsoneditor-modal select,body .jsoneditor-modal textarea,body .jsoneditor-modal input,body .jsoneditor-modal input[type="text"],body .jsoneditor-modal input[type="text"]:focus,body .jsoneditor-modal #query{background:#ffffff;border:1px solid var(--t42-color-opacity-10);color:var(--t42-content-color);border-radius:3px;padding:4px}body .jsoneditor-modal textarea,body .jsoneditor-modal #query{border-radius:unset}body .jsoneditor-modal,body .jsoneditor-modal table td,body .jsoneditor-modal table th,body .jsoneditor-modal select,body .jsoneditor-modal option,body .jsoneditor-modal textarea,body .jsoneditor-modal input,body .jsoneditor-modal input[type="text"],body .jsoneditor-modal #query{font-size:10.5pt;font-family:var(--t42-font-family)}body .jsoneditor-modal #query,body .jsoneditor-modal .jsoneditor-transform-preview{font-family:var(--bs-font-monospace);font-size:var(--t42-font-size);width:100%;box-sizing:border-box}body .jsoneditor-modal input[type="button"],body .jsoneditor-modal input[type="submit"]{background:var(--t42-color-opacity-10);padding:4px 20px}body .jsoneditor-modal select,body .jsoneditor-modal input{cursor:pointer}body .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-asc input.jsoneditor-button-asc,body .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-desc input.jsoneditor-button-desc{background:var(--primary);border-color:var(--primary);color:var(--t42-content-color)}body .jsoneditor{color:var(--t42-content-color);border:thin solid var(--primary);-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;width:100%;height:100%;position:relative;padding:0;line-height:100%}body div.jsoneditor-field,body div.jsoneditor-value,body a.jsoneditor-value,body div.jsoneditor-readonly,body div.jsoneditor-default{border:1px solid transparent;min-height:16px;min-width:32px;line-height:16px;padding:2px;margin:1px;word-wrap:break-word;word-break:break-word;overflow-wrap:break-word;float:left}body div.jsoneditor-field p,body div.jsoneditor-value p{margin:0}body div.jsoneditor-value.jsoneditor-empty::after{content:"value"}body div.jsoneditor-value.jsoneditor-string{color:var(--green)}body div.jsoneditor-value.jsoneditor-number{color:var(--red)}body div.jsoneditor-value.jsoneditor-boolean{color:var(--yellow)}body div.jsoneditor-value.jsoneditor-null{color:var(--primary)}body div.jsoneditor-value.jsoneditor-color-value{color:var(--t42-content-color)}body div.jsoneditor-value.jsoneditor-invalid{color:var(--white)}body div.jsoneditor-readonly{min-width:16px;color:var(--t42-content-color-muted)}body div.jsoneditor-empty{border-color:var(--t42-color-opacity-10);border-style:dashed;border-radius:2px}body div.jsoneditor-field.jsoneditor-empty::after{content:"field"}body div.jsoneditor td{vertical-align:top}body div.jsoneditor td.jsoneditor-separator{padding:3px 0;vertical-align:top;color:var(--t42-content-color-muted)}body div.jsoneditor td.jsoneditor-tree{vertical-align:top}body div.jsoneditor.busy pre.jsoneditor-preview{background:var(--t42-color-opacity-10);color:var(--t42-content-color-muted)}body div.jsoneditor.busy div.jsoneditor-busy{display:inherit}body div.jsoneditor code.jsoneditor-preview{background:none}body div.jsoneditor.jsoneditor-mode-preview pre.jsoneditor-preview{width:100%;height:100%;box-sizing:border-box;overflow:auto;padding:2px;margin:0;white-space:pre-wrap;word-break:break-all}body div.jsoneditor-default{color:var(--t42-content-color-muted);padding-left:10px}body div.jsoneditor-tree{width:100%;height:100%;position:relative;overflow:auto;background:var(--t42-content-color)}body div.jsoneditor-tree button.jsoneditor-button{width:24px;height:24px;padding:0;margin:0;border:none;cursor:pointer;background-color:transparent;background-image:"/"}body div.jsoneditor-tree button.jsoneditor-button:focus{background-color:var(--t42-color-opacity-10);outline:#e5e5e5 solid 1px}body div.jsoneditor-tree button.jsoneditor-collapsed{background-position:0 -48px}body div.jsoneditor-tree button.jsoneditor-expanded{background-position:0 -72px}body div.jsoneditor-tree button.jsoneditor-contextmenu-button{background-position:-48px -72px}body div.jsoneditor-tree button.jsoneditor-invisible{visibility:hidden;background:none}body div.jsoneditor-tree button.jsoneditor-dragarea{background-image:"/";background-position:-72px -72px;cursor:move}body div.jsoneditor-tree *:focus{outline:none}body div.jsoneditor-tree div.jsoneditor-show-more{display:inline-block;padding:3px 4px;margin:2px 0;background-color:var(--t42-color-opacity-10);border-radius:3px;color:var(--t42-content-color-muted);font-family:var(--t42-font-family);font-size:var(--t42-font-size)}body div.jsoneditor-tree div.jsoneditor-show-more a{display:inline-block;color:var(--t42-content-color-muted)}body div.jsoneditor-tree div.jsoneditor-color{display:inline-block;width:12px;height:12px;margin:4px;border:1px solid var(--t42-content-color-muted);cursor:pointer}body div.jsoneditor-tree div.jsoneditor-color.jsoneditor-color-readonly{cursor:inherit}body div.jsoneditor-tree div.jsoneditor-date{background:var(--t42-content-color);color:var(--t42-content-color);font-family:var(--t42-font-family);border-radius:3px;display:inline-block;padding:3px;margin:0 3px}body div.jsoneditor-tree table.jsoneditor-tree{border-collapse:collapse;border-spacing:0;width:100%}body div.jsoneditor-tree .jsoneditor-button{display:block}body div.jsoneditor-tree .jsoneditor-button.jsoneditor-schema-error{width:24px;height:24px;padding:0;margin:0 4px 0 0;background-image:"/";background-position:-168px -48px;background-color:transparent}body div.jsoneditor-outer{position:static;width:100%;height:100%;margin:0;padding:0;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}body div.jsoneditor-outer.has-nav-bar{margin-top:-26px;padding-top:26px}body div.jsoneditor-outer.has-nav-bar.has-main-menu-bar{margin-top:-61px;padding-top:61px}body div.jsoneditor-outer.has-status-bar{margin-bottom:-26px;padding-bottom:26px}body div.jsoneditor-outer.has-main-menu-bar{margin-top:-35px;padding-top:35px}body div.jsoneditor-busy{position:absolute;top:15%;left:0;box-sizing:border-box;width:100%;text-align:center;display:none}body div.jsoneditor-busy span{background-color:var(--t42-color-opacity-10);border:1px solid var(--t42-color-opacity-10);border-radius:3px;padding:5px 15px;box-shadow:var(--t42-shadow)}body div.jsoneditor-field.jsoneditor-empty::after,body div.jsoneditor-value.jsoneditor-empty::after{pointer-events:none;color:var(--t42-content-color-muted);font-size:8pt}body div.jsoneditor-value.jsoneditor-url,body a.jsoneditor-value.jsoneditor-url{color:var(--green);text-decoration:underline}body a.jsoneditor-value.jsoneditor-url{display:inline-block;padding:2px;margin:2px}body a.jsoneditor-value.jsoneditor-url:hover,body a.jsoneditor-value.jsoneditor-url:focus{color:var(--red)}body div.jsoneditor-field[contenteditable="true"]:focus,body div.jsoneditor-field[contenteditable="true"]:hover,body div.jsoneditor-value[contenteditable="true"]:focus,body div.jsoneditor-value[contenteditable="true"]:hover,body div.jsoneditor-field.jsoneditor-highlight,body div.jsoneditor-value.jsoneditor-highlight{background-color:var(--t42-color-opacity-10);border:1px solid var(--t42-color-opacity-10);border-radius:2px}body div.jsoneditor-field.jsoneditor-highlight-active,body div.jsoneditor-field.jsoneditor-highlight-active:focus,body div.jsoneditor-field.jsoneditor-highlight-active:hover,body div.jsoneditor-value.jsoneditor-highlight-active,body div.jsoneditor-value.jsoneditor-highlight-active:focus,body div.jsoneditor-value.jsoneditor-highlight-active:hover{background-color:#fe0;border:1px solid #ffc700;border-radius:2px}body div.jsoneditor-value.jsoneditor-object,body div.jsoneditor-value.jsoneditor-array{min-width:16px}body div.jsoneditor-tree button.jsoneditor-contextmenu-button:hover,body div.jsoneditor-tree button.jsoneditor-contextmenu-button:focus,body div.jsoneditor-tree button.jsoneditor-contextmenu-button.jsoneditor-selected,body tr.jsoneditor-selected.jsoneditor-first button.jsoneditor-contextmenu-button{background-position:-48px -48px}body div.jsoneditor-tree div.jsoneditor-show-more a:hover,body div.jsoneditor-tree div.jsoneditor-show-more a:focus{color:var(--red)}body textarea.jsoneditor-text,body .ace-jsoneditor{min-height:150px}body textarea.jsoneditor-text.ace_editor,body .ace-jsoneditor.ace_editor{font-family:var(--bs-font-monospace)}body textarea.jsoneditor-text{width:100%;height:100%;margin:0;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;outline-width:0;border:none;background-color:var(--t42-content-color);resize:none}body tr.jsoneditor-highlight,body tr.jsoneditor-selected{background-color:var(--t42-content-color-muted)}body tr.jsoneditor-selected button.jsoneditor-dragarea,body tr.jsoneditor-selected button.jsoneditor-contextmenu-button{visibility:hidden}body tr.jsoneditor-selected.jsoneditor-first button.jsoneditor-dragarea,body tr.jsoneditor-selected.jsoneditor-first button.jsoneditor-contextmenu-button{visibility:visible}body div.jsoneditor-tree button.jsoneditor-dragarea:hover,body div.jsoneditor-tree button.jsoneditor-dragarea:focus,body tr.jsoneditor-selected.jsoneditor-first button.jsoneditor-dragarea{background-position:-72px -48px}body div.jsoneditor tr,body div.jsoneditor th,body div.jsoneditor td{padding:0;margin:0}body div.jsoneditor-field,body div.jsoneditor-value,body div.jsoneditor td,body div.jsoneditor th,body div.jsoneditor textarea,body pre.jsoneditor-preview,body .jsoneditor-schema-error,body .jsoneditor-popover{font-family:var(--bs-font-monospace);font-size:var(--t42-font-size);color:var(--t42-content-color)}body .jsoneditor-schema-error{cursor:default;display:inline-block;height:24px;line-height:24px;position:relative;text-align:center;width:24px}body .jsoneditor-popover{background-color:Rgb(var(--t42-bg-light));border-radius:3px;box-shadow:var(--t42-shadow);color:var(--t42-content-color);padding:7px 10px;position:absolute;cursor:auto;width:200px}body .jsoneditor-popover.jsoneditor-above{bottom:32px;left:-98px}body .jsoneditor-popover.jsoneditor-above:before{border-top:7px solid Rgb(var(--t42-bg-light));bottom:-7px}body .jsoneditor-popover.jsoneditor-below{top:32px;left:-98px}body .jsoneditor-popover.jsoneditor-below:before{border-bottom:7px solid Rgb(var(--t42-bg-light));top:-7px}body .jsoneditor-popover.jsoneditor-left{top:-7px;right:32px}body .jsoneditor-popover.jsoneditor-left:before{border-left:7px solid Rgb(var(--t42-bg-light));border-top:7px solid transparent;border-bottom:7px solid transparent;content:"";top:19px;right:-14px;left:inherit;margin-left:inherit;margin-top:-7px;position:absolute}body .jsoneditor-popover.jsoneditor-right{top:-7px;left:32px}body .jsoneditor-popover.jsoneditor-right:before{border-right:7px solid Rgb(var(--t42-bg-light));border-top:7px solid transparent;border-bottom:7px solid transparent;content:"";top:19px;left:-14px;margin-left:inherit;margin-top:-7px;position:absolute}body .jsoneditor-popover:before{border-right:7px solid transparent;border-left:7px solid transparent;content:"";display:block;left:50%;margin-left:-7px;position:absolute}body .jsoneditor-text-errors tr.jump-to-line:hover{text-decoration:underline;cursor:pointer}body .jsoneditor-schema-error:hover .jsoneditor-popover,body .jsoneditor-schema-error:focus .jsoneditor-popover{display:block;animation:fade-in 0.3s linear 1, move-up 0.3s linear 1}@keyframes fade-in{from{opacity:0}to{opacity:1}}body .jsoneditor .jsoneditor-validation-errors-container{max-height:130px;overflow-y:auto}body .jsoneditor .jsoneditor-validation-errors{width:100%;overflow:hidden}body .jsoneditor .jsoneditor-additional-errors{position:absolute;margin:auto;bottom:31px;left:calc(50% - 92px);color:var(--t42-content-color-muted);background-color:Rgb(var(--t42-bg-mid));padding:7px 15px;border-radius:8px}body .jsoneditor .jsoneditor-additional-errors.visible{visibility:visible;opacity:1;transition:opacity 2s linear}body .jsoneditor .jsoneditor-additional-errors.hidden{visibility:hidden;opacity:0;transition:visibility 0s 2s, opacity 2s linear}body .jsoneditor .jsoneditor-text-errors{width:100%;border-collapse:collapse;border-top:1px solid #ffc700}body .jsoneditor .jsoneditor-text-errors td{padding:3px 6px;vertical-align:middle}body .jsoneditor .jsoneditor-text-errors td pre{margin:0;white-space:pre-wrap}body .jsoneditor .jsoneditor-text-errors tr{background-color:var(--t42-color-opacity-10)}body .jsoneditor .jsoneditor-text-errors tr.parse-error{background-color:var(--red)}body .jsoneditor-text-errors .jsoneditor-schema-error{border:none;width:24px;height:24px;padding:0;margin:0 4px 0 0;cursor:pointer}body .jsoneditor-text-errors tr .jsoneditor-schema-error{background-image:"/";background-position:-168px -48px;background-color:transparent}body .jsoneditor-text-errors tr.parse-error .jsoneditor-schema-error{background-image:"/";background-position:-25px 0px;background-color:transparent}body .jsoneditor-anchor{cursor:pointer}body .jsoneditor-anchor .picker_wrapper.popup.popup_bottom{top:28px;left:-10px}body .fadein{-webkit-animation:fadein 0.3s;animation:fadein 0.3s;-moz-animation:fadein 0.3s;-o-animation:fadein 0.3s}@keyframes fadein{0%{opacity:0}100%{opacity:1}}body .jsoneditor-modal input[type="search"].selectr-input{border:1px solid #d3d3d3;width:calc(100% - 4px);margin:2px;padding:4px;box-sizing:border-box}body .jsoneditor-modal button.selectr-input-clear{right:8px}body .jsoneditor-menu{width:100%;height:35px;padding:2px;margin:0;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;color:var(--t42-content-color);background-color:var(--primary);border-bottom:1px solid var(--primary)}body .jsoneditor-menu>button,body .jsoneditor-menu>.jsoneditor-modes>button{width:26px;height:26px;margin:2px;padding:0;border-radius:2px;border:1px solid transparent;background-color:transparent;background-image:"/";color:var(--t42-content-color);opacity:0.8;font-family:var(--t42-font-family);font-size:var(--t42-font-size);float:left}body .jsoneditor-menu>button:hover,body .jsoneditor-menu>.jsoneditor-modes>button:hover{background-color:rgba(255,255,255,0.2);border:1px solid rgba(255,255,255,0.4)}body .jsoneditor-menu>button:focus,body .jsoneditor-menu>button:active,body .jsoneditor-menu>.jsoneditor-modes>button:focus,body .jsoneditor-menu>.jsoneditor-modes>button:active{background-color:rgba(255,255,255,0.3)}body .jsoneditor-menu>button:disabled,body .jsoneditor-menu>.jsoneditor-modes>button:disabled{opacity:0.5;background-color:transparent;border:none}body .jsoneditor-menu>button.jsoneditor-collapse-all{background-position:0 -96px}body .jsoneditor-menu>button.jsoneditor-expand-all{background-position:0 -120px}body .jsoneditor-menu>button.jsoneditor-sort{background-position:-120px -96px}body .jsoneditor-menu>button.jsoneditor-transform{background-position:-144px -96px}body .jsoneditor.jsoneditor-mode-view>.jsoneditor-menu>button.jsoneditor-sort,body .jsoneditor.jsoneditor-mode-form>.jsoneditor-menu>button.jsoneditor-sort,body .jsoneditor.jsoneditor-mode-view>.jsoneditor-menu>button.jsoneditor-transform,body .jsoneditor.jsoneditor-mode-form>.jsoneditor-menu>button.jsoneditor-transform{display:none}body .jsoneditor-menu>button.jsoneditor-undo{background-position:-24px -96px}body .jsoneditor-menu>button.jsoneditor-undo:disabled{background-position:-24px -120px}body .jsoneditor-menu>button.jsoneditor-redo{background-position:-48px -96px}body .jsoneditor-menu>button.jsoneditor-redo:disabled{background-position:-48px -120px}body .jsoneditor-menu>button.jsoneditor-compact{background-position:-72px -96px}body .jsoneditor-menu>button.jsoneditor-format{background-position:-72px -120px}body .jsoneditor-menu>button.jsoneditor-repair{background-position:-96px -96px}body .jsoneditor-menu>.jsoneditor-modes{display:inline-block;float:left}body .jsoneditor-menu>.jsoneditor-modes>button{background-image:none;width:auto;padding-left:6px;padding-right:6px}body .jsoneditor-menu>button.jsoneditor-separator,body .jsoneditor-menu>.jsoneditor-modes>button.jsoneditor-separator{margin-left:10px}body .jsoneditor-menu a{font-family:var(--t42-font-family);font-size:var(--t42-font-size);color:var(--t42-content-color);opacity:0.8;vertical-align:middle}body .jsoneditor-menu a:hover{opacity:1}body .jsoneditor-menu a.jsoneditor-poweredBy{font-size:8pt;position:absolute;right:0;top:0;padding:10px}body .jsoneditor-navigation-bar{width:100%;height:26px;line-height:26px;padding:0;margin:0;border-bottom:1px solid var(--t42-color-opacity-10);-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;color:var(--t42-content-color-muted);background-color:Rgb(var(--t42-bg-mid));overflow:hidden;font-family:var(--t42-font-family);font-size:var(--t42-font-size)}body .jsoneditor-search{font-family:var(--t42-font-family);position:absolute;right:4px;top:4px;border-collapse:collapse;border-spacing:0;display:flex}body .jsoneditor-search input{color:var(--t42-content-color);width:120px;border:none;outline:none;margin:1px;line-height:20px;font-family:var(--t42-font-family)}body .jsoneditor-search button{width:16px;height:24px;padding:0;margin:0;border:none;background:"/";vertical-align:top}body .jsoneditor-search button:hover{background-color:transparent}body .jsoneditor-search button.jsoneditor-refresh{width:18px;background-position:-99px -73px}body .jsoneditor-search button.jsoneditor-next{cursor:pointer;background-position:-124px -73px}body .jsoneditor-search button.jsoneditor-next:hover{background-position:-124px -49px}body .jsoneditor-search button.jsoneditor-previous{cursor:pointer;background-position:-148px -73px;margin-right:2px}body .jsoneditor-search button.jsoneditor-previous:hover{background-position:-148px -49px}body .jsoneditor-results{font-family:var(--t42-font-family);color:var(--t42-content-color);padding-right:5px;line-height:26px}body .jsoneditor-frame{border:1px solid transparent;background-color:var(--t42-content-color);padding:0 2px;margin:0}body .jsoneditor-statusbar{line-height:26px;height:26px;color:var(--t42-content-color-muted);background-color:Rgb(var(--t42-bg-mid));border-top:1px solid var(--t42-color-opacity-10);-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;font-size:var(--t42-font-size)}body .jsoneditor-statusbar>.jsoneditor-curserinfo-val{margin-right:12px}body .jsoneditor-statusbar>.jsoneditor-curserinfo-count{margin-left:4px}body .jsoneditor-statusbar>.jsoneditor-validation-error-icon{float:right;width:24px;height:24px;padding:0;margin-top:1px;background-image:"/";background-position:-168px -48px;cursor:pointer}body .jsoneditor-statusbar>.jsoneditor-validation-error-count{float:right;margin:0 4px 0 0;cursor:pointer}body .jsoneditor-statusbar>.jsoneditor-parse-error-icon{float:right;width:24px;height:24px;padding:0;margin:1px;background-image:"/";background-position:-25px 0px}body .jsoneditor-statusbar .jsoneditor-array-info a{color:inherit}body div.jsoneditor-statusbar>.jsoneditor-curserinfo-label,body div.jsoneditor-statusbar>.jsoneditor-size-info{margin:0 4px}body .jsoneditor-treepath{padding:0 5px;overflow:hidden;white-space:nowrap;outline:none}body .jsoneditor-treepath.show-all{word-wrap:break-word;white-space:normal;position:absolute;background-color:Rgb(var(--t42-bg-mid));z-index:1;box-shadow:var(--t42-shadow)}body .jsoneditor-treepath.show-all span.jsoneditor-treepath-show-all-btn{display:none}body .jsoneditor-treepath div.jsoneditor-contextmenu-root{position:absolute;left:0}body .jsoneditor-treepath .jsoneditor-treepath-show-all-btn{position:absolute;background-color:Rgb(var(--t42-bg-mid));left:0;height:20px;padding:0 3px;cursor:pointer}body .jsoneditor-treepath .jsoneditor-treepath-element{margin:1px;font-family:var(--t42-font-family);font-size:var(--t42-font-size)}body .jsoneditor-treepath .jsoneditor-treepath-seperator{margin:2px;font-size:9pt;font-family:var(--t42-font-family)}body .jsoneditor-treepath span.jsoneditor-treepath-element:hover,body .jsoneditor-treepath span.jsoneditor-treepath-seperator:hover{cursor:pointer;text-decoration:underline}body .selectr-container{position:relative}body .selectr-container li{list-style:none}body .selectr-hidden{position:absolute;overflow:hidden;clip:rect(0px, 0px, 0px, 0px);width:1px;height:1px;margin:-1px;padding:0;border:0 none}body .selectr-visible{position:absolute;left:0;top:0;width:100%;height:100%;opacity:0;z-index:11}body .selectr-desktop.multiple .selectr-visible{display:none}body .selectr-desktop.multiple.native-open .selectr-visible{top:100%;min-height:200px !important;height:auto;opacity:1;display:block}body .selectr-container.multiple.selectr-mobile .selectr-selected{z-index:0}body .selectr-selected{position:relative;z-index:1;box-sizing:border-box;width:100%;padding:7px 28px 7px 14px;cursor:pointer;border:1px solid Rgb(var(--t42-bg-mid));border-radius:3px;background-color:var(--t42-content-color)}body .selectr-selected::before{position:absolute;top:50%;right:10px;width:0;height:0;content:'';-o-transform:rotate(0deg) translate3d(0px, -50%, 0px);-ms-transform:rotate(0deg) translate3d(0px, -50%, 0px);-moz-transform:rotate(0deg) translate3d(0px, -50%, 0px);-webkit-transform:rotate(0deg) translate3d(0px, -50%, 0px);transform:rotate(0deg) translate3d(0px, -50%, 0px);border-width:4px 4px 0 4px;border-style:solid;border-color:#6c7a86 transparent transparent}body .selectr-container.open .selectr-selected::before,body .selectr-container.native-open .selectr-selected::before{border-width:0 4px 4px 4px;border-style:solid;border-color:transparent transparent #6c7a86}body .selectr-label{display:none;overflow:hidden;width:100%;white-space:nowrap;text-overflow:ellipsis}body .selectr-placeholder{color:#6c7a86}body .selectr-tags{margin:0;padding:0;white-space:normal}body .has-selected .selectr-tags{margin:0 0 -2px}body .selectr-tag{list-style:none;position:relative;float:left;padding:2px 25px 2px 8px;margin:0 2px 2px 0;cursor:default;color:var(--t42-content-color);border:medium none;border-radius:10px;background:#acb7bf none repeat scroll 0 0}body .selectr-container.multiple.has-selected .selectr-selected{padding:5px 28px 5px 5px}body .selectr-options-container{position:absolute;z-index:10000;top:calc(100% - 1px);left:0;display:none;box-sizing:border-box;width:100%;border-width:0 1px 1px;border-style:solid;border-color:transparent Rgb(var(--t42-bg-mid)) Rgb(var(--t42-bg-mid));border-radius:0 0 3px 3px;background-color:var(--t42-content-color)}body .selectr-container.open .selectr-options-container{display:block}body .selectr-input-container{position:relative;display:none}body .selectr-clear,body .selectr-input-clear,body .selectr-tag-remove{position:absolute;top:50%;right:22px;width:20px;height:20px;padding:0;cursor:pointer;-o-transform:translate3d(0px, -50%, 0px);-ms-transform:translate3d(0px, -50%, 0px);-moz-transform:translate3d(0px, -50%, 0px);-webkit-transform:translate3d(0px, -50%, 0px);transform:translate3d(0px, -50%, 0px);border:medium none;background-color:transparent;z-index:11}body .selectr-clear,body .selectr-input-clear{display:none}body .selectr-container.has-selected .selectr-clear,body .selectr-input-container.active .selectr-input-clear{display:block}body .selectr-selected .selectr-tag-remove{right:2px}body .selectr-clear::before,body .selectr-clear::after,body .selectr-input-clear::before,body .selectr-input-clear::after,body .selectr-tag-remove::before,body .selectr-tag-remove::after{position:absolute;top:5px;left:9px;width:2px;height:10px;content:' ';background-color:#6c7a86}body .selectr-tag-remove::before,body .selectr-tag-remove::after{top:4px;width:3px;height:12px;background-color:var(--t42-content-color)}body .selectr-clear:before,body .selectr-input-clear::before,body .selectr-tag-remove::before{-o-transform:rotate(45deg);-ms-transform:rotate(45deg);-moz-transform:rotate(45deg);-webkit-transform:rotate(45deg);transform:rotate(45deg)}body .selectr-clear:after,body .selectr-input-clear::after,body .selectr-tag-remove::after{-o-transform:rotate(-45deg);-ms-transform:rotate(-45deg);-moz-transform:rotate(-45deg);-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}body .selectr-input-container.active,body .selectr-input-container.active .selectr-clear{display:block}body .selectr-input{top:5px;left:5px;box-sizing:border-box;width:calc(100% - 30px);margin:10px 15px;padding:7px 30px 7px 9px;border:1px solid Rgb(var(--t42-bg-mid));border-radius:3px}body .selectr-notice{display:none;box-sizing:border-box;width:100%;padding:8px 16px;border-top:1px solid Rgb(var(--t42-bg-mid));border-radius:0 0 3px 3px;background-color:var(--t42-content-color)}body .selectr-container.notice .selectr-notice{display:block}body .selectr-container.notice .selectr-selected{border-radius:3px 3px 0 0}body .selectr-options{position:relative;top:calc(100% + 2px);display:none;overflow-x:auto;overflow-y:scroll;max-height:200px;margin:0;padding:0}body .selectr-container.open .selectr-options,body .selectr-container.open .selectr-input-container,body .selectr-container.notice .selectr-options-container{display:block}body .selectr-option{position:relative;display:block;padding:5px 20px;list-style:outside none none;cursor:pointer;font-weight:normal}body .selectr-options.optgroups>.selectr-option{padding-left:25px}body .selectr-optgroup{font-weight:bold;padding:0}body .selectr-optgroup--label{font-weight:bold;margin-top:10px;padding:5px 15px}body .selectr-match{text-decoration:underline}body .selectr-option.selected{background-color:#ddd}body .selectr-option.active{color:var(--t42-content-color);background-color:#5897fb}body .selectr-option.disabled{opacity:0.4}body .selectr-option.excluded{display:none}body .selectr-container.open .selectr-selected{border-color:Rgb(var(--t42-bg-mid)) Rgb(var(--t42-bg-mid)) transparent Rgb(var(--t42-bg-mid));border-radius:3px 3px 0 0}body .selectr-container.open .selectr-selected::after{-o-transform:rotate(180deg) translate3d(0px, 50%, 0px);-ms-transform:rotate(180deg) translate3d(0px, 50%, 0px);-moz-transform:rotate(180deg) translate3d(0px, 50%, 0px);-webkit-transform:rotate(180deg) translate3d(0px, 50%, 0px);transform:rotate(180deg) translate3d(0px, 50%, 0px)}body .selectr-disabled{opacity:.6}body .selectr-empty,body .has-selected .selectr-placeholder{display:none}body .has-selected .selectr-label{display:block}body .taggable .selectr-selected{padding:4px 28px 4px 4px}body .taggable .selectr-selected::after{display:table;content:" ";clear:both}body .taggable .selectr-label{width:auto}body .taggable .selectr-tags{float:left;display:block}body .taggable .selectr-placeholder{display:none}body .input-tag{float:left;min-width:90px;width:auto}body .selectr-tag-input{border:medium none;padding:3px 10px;width:100%;font-family:inherit;font-weight:inherit;font-size:inherit}body .selectr-input-container.loading::after{position:absolute;top:50%;right:20px;width:20px;height:20px;content:'';-o-transform:translate3d(0px, -50%, 0px);-ms-transform:translate3d(0px, -50%, 0px);-moz-transform:translate3d(0px, -50%, 0px);-webkit-transform:translate3d(0px, -50%, 0px);transform:translate3d(0px, -50%, 0px);-o-transform-origin:50% 0 0;-ms-transform-origin:50% 0 0;-moz-transform-origin:50% 0 0;-webkit-transform-origin:50% 0 0;transform-origin:50% 0 0;-moz-animation:500ms linear 0s normal forwards infinite running selectr-spin;-webkit-animation:500ms linear 0s normal forwards infinite running selectr-spin;animation:500ms linear 0s normal forwards infinite running selectr-spin;border-width:3px;border-style:solid;border-color:#aaa #ddd #ddd;border-radius:50%}@-webkit-keyframes selectr-spin{0%{-webkit-transform:rotate(0deg) translate3d(0px, -50%, 0px);transform:rotate(0deg) translate3d(0px, -50%, 0px)}100%{-webkit-transform:rotate(360deg) translate3d(0px, -50%, 0px);transform:rotate(360deg) translate3d(0px, -50%, 0px)}}@keyframes selectr-spin{0%{-webkit-transform:rotate(0deg) translate3d(0px, -50%, 0px);transform:rotate(0deg) translate3d(0px, -50%, 0px)}100%{-webkit-transform:rotate(360deg) translate3d(0px, -50%, 0px);transform:rotate(360deg) translate3d(0px, -50%, 0px)}}body .selectr-container.open.inverted .selectr-selected{border-color:transparent Rgb(var(--t42-bg-mid)) Rgb(var(--t42-bg-mid));border-radius:0 0 3px 3px}body .selectr-container.inverted .selectr-options-container{border-width:1px 1px 0;border-color:Rgb(var(--t42-bg-mid)) Rgb(var(--t42-bg-mid)) transparent;border-radius:3px 3px 0 0;background-color:var(--t42-content-color)}body .selectr-container.inverted .selectr-options-container{top:auto;bottom:calc(100% - 1px)}body .selectr-container ::-webkit-input-placeholder{color:#6c7a86;opacity:1}body .selectr-container ::-moz-placeholder{color:#6c7a86;opacity:1}body .selectr-container :-ms-input-placeholder{color:#6c7a86;opacity:1}body .selectr-container ::placeholder{color:#6c7a86;opacity:1}body #jsoneditor{height:100%}body .jsoneditor{border-color:var(--t42-color-opacity-10)}body .jsoneditor textarea{line-height:1.5;background-color:Rgb(var(--t42-bg-dark));min-height:100%}body .jsoneditor input{outline:0}body .jsoneditor input:focus{outline:0}body .jsoneditor-button:focus{outline:none}body .jsoneditor-menu{border-bottom-color:var(--t42-color-opacity-10);background-color:Rgb(var(--t42-bg-light))}body .jsoneditor-menu button{background-image:var(--t42-json-icons);background-color:transparent}body .jsoneditor-menu button:hover,body .jsoneditor-menu button:focus{color:var(--t42-link-hover-color)}body .jsoneditor-menu>button,body .jsoneditor-menu>.jsoneditor-modes>button{border-radius:0;font-size:.75rem;backdrop-filter:var(--backdrop-filter);transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, color}body .jsoneditor-menu>button:hover:not(.disabled):not(:disabled),body .jsoneditor-menu>button:active,body .jsoneditor-menu>.jsoneditor-modes>button:hover:not(.disabled):not(:disabled),body .jsoneditor-menu>.jsoneditor-modes>button:active{border-color:transparent;color:var(--t42-link-hover-color);background-color:var(--t42-color-opacity-10)}body .jsoneditor-menu li button.jsoneditor-selected{background-color:var(--t42-color-opacity-10)}body .jsoneditor-menu .jsoneditor-poweredBy{display:none}body .jsoneditor-frame{padding:0 .875rem;border-color:var(--t42-color-opacity-10);background-color:transparent;display:flex;transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border-color}body .jsoneditor-frame:focus-within{border-color:var(--primary);background-color:var(--t42-input-bg);outline:0}body .jsoneditor-frame table td{vertical-align:middle}body .jsoneditor-search input[type="text"]{border:0}body .jsoneditor-search input[type="text"]:focus{border:0}body .jsoneditor-search input{background-color:transparent}body .jsoneditor-contextmenu{z-index:2}body .jsoneditor-contextmenu .jsoneditor-menu{border-color:var(--t42-color-opacity-10);background:linear-gradient(to bottom right, rgba(var(--t42-bg-light), 0.75) 0%, rgba(var(--t42-bg-dark), 0.75) 100%);box-shadow:var(--t42-shadow);backdrop-filter:var(--backdrop-filter)}body .jsoneditor-contextmenu .jsoneditor-menu button button .jsoneditor-expand,body .jsoneditor-contextmenu .jsoneditor-menu li button .jsoneditor-expand{background-image:var(--t42-json-icons);z-index:1}body .jsoneditor-contextmenu .jsoneditor-menu button button.jsoneditor-selected,body .jsoneditor-contextmenu .jsoneditor-menu li button.jsoneditor-selected{background-color:var(--t42-color-opacity-10);transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, color}body .jsoneditor-contextmenu .jsoneditor-menu button button.jsoneditor-selected:hover,body .jsoneditor-contextmenu .jsoneditor-menu button button.jsoneditor-selected:focus,body .jsoneditor-contextmenu .jsoneditor-menu li button.jsoneditor-selected:hover,body .jsoneditor-contextmenu .jsoneditor-menu li button.jsoneditor-selected:focus{color:var(--t42-link-hover-color);background-color:var(--t42-color-opacity-10)}body .jsoneditor-contextmenu .jsoneditor-menu button{display:flex;justify-content:start}body .jsoneditor-contextmenu .jsoneditor-menu button.jsoneditor-default{float:left;z-index:1}body .jsoneditor-contextmenu .jsoneditor-menu li ul{padding:0 !important;left:0}body .jsoneditor-contextmenu .jsoneditor-menu li ul li button{padding-left:1rem}body .jsoneditor-contextmenu .jsoneditor-menu li ul .jsoneditor-icon{position:relative;margin-left:0}body .jsoneditor-contextmenu .jsoneditor-menu .jsoneditor-text{padding:0;line-height:1.5rem}body .jsoneditor-contextmenu .jsoneditor-icon{position:relative;background-image:var(--t42-json-icons)}body .jsoneditor-contextmenu .jsoneditor-separator{margin-top:0;padding-top:0}body .jsoneditor-mode-preview pre.jsoneditor-preview{border:0;line-height:1.5}body .jsoneditor-modal{border-top:0;background:linear-gradient(to bottom right, rgba(var(--t42-bg-light), 0.75) 0%, rgba(var(--t42-bg-dark), 0.75) 100%) !important;box-shadow:var(--t42-shadow) !important;backdrop-filter:var(--backdrop-filter)}body .jsoneditor-modal::before{position:absolute;top:0;right:0;left:0;display:block;width:100%;height:0.0625rem;background:linear-gradient(90deg, #007be5 0%, rgba(0,123,229,0.5) 100%);content:""}body .jsoneditor-modal .pico-modal-header{padding:0.5rem 0.988rem;background:transparent;font-size:0.75rem}body .jsoneditor-modal .pico-close{top:1rem !important;right:1rem !important;color:var(--t42-content-color-muted);transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:color}body .jsoneditor-modal .pico-close:not(.disabled):not(:disabled).active,body .jsoneditor-modal .pico-close:not(.disabled):not(:disabled):focus,body .jsoneditor-modal .pico-close:not(.disabled):not(:disabled):hover{color:var(--t42-link-color)}body .jsoneditor-modal table td{font-size:0.75rem;padding:0 0.25rem}body .jsoneditor-modal table td.jsoneditor-modal-input{padding-top:0.25rem;padding-bottom:0.25rem;text-align:left}body .jsoneditor-modal table td.jsoneditor-modal-input.jsoneditor-modal-actions{text-align:right}body .jsoneditor-modal table th{font-size:0.75rem}body .jsoneditor-modal label,body .jsoneditor-modal p{font-size:0.75rem}body .jsoneditor-modal select{min-width:12.375rem}body .jsoneditor-modal .selectr-selected{padding:0 0.857rem}body .jsoneditor-modal select,body .jsoneditor-modal textarea,body .jsoneditor-modal input,body .jsoneditor-modal input[type="text"],body .jsoneditor-modal input[type="search"],body .jsoneditor-modal #query{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border;border-color:var(--t42-color-opacity-10);border-radius:0;font-size:0.75rem;background-color:var(--t42-input-bg)}body .jsoneditor-modal select:focus,body .jsoneditor-modal textarea:focus,body .jsoneditor-modal input:focus,body .jsoneditor-modal input[type="text"]:focus,body .jsoneditor-modal input[type="search"]:focus,body .jsoneditor-modal #query:focus{border-color:var(--primary);box-shadow:none;outline:0;padding:0 0 0 .875rem;border-radius:0}body .jsoneditor-modal select:disabled,body .jsoneditor-modal select.disabled,body .jsoneditor-modal select[readonly],body .jsoneditor-modal textarea:disabled,body .jsoneditor-modal textarea.disabled,body .jsoneditor-modal textarea[readonly],body .jsoneditor-modal input:disabled,body .jsoneditor-modal input.disabled,body .jsoneditor-modal input[readonly],body .jsoneditor-modal input[type="text"]:disabled,body .jsoneditor-modal input[type="text"].disabled,body .jsoneditor-modal input[type="text"][readonly],body .jsoneditor-modal input[type="search"]:disabled,body .jsoneditor-modal input[type="search"].disabled,body .jsoneditor-modal input[type="search"][readonly],body .jsoneditor-modal #query:disabled,body .jsoneditor-modal #query.disabled,body .jsoneditor-modal #query[readonly]{cursor:default;opacity:0.65}body .jsoneditor-modal input[type="search"].selectr-input{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border-color;border:var(--t42-border);background-color:var(--t42-input-bg);margin:0;line-height:1.5rem;width:100%;padding:0 0.5rem}body .jsoneditor-modal input[type="search"].selectr-input:hover{border-color:var(--primary)}body .jsoneditor-modal .jsoneditor-select-wrapper::after{border-top:var(--t42-color-opacity-10)}body .jsoneditor-modal input[type="button"],body .jsoneditor-modal input[type="submit"]{padding:0 .875rem;border-radius:0;color:var(--t42-link-color);line-height:1.875rem;background:transparent;transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, border-color}body .jsoneditor-modal input[type="button"]:not(.disabled):not(:disabled).active,body .jsoneditor-modal input[type="button"]:not(.disabled):not(:disabled):hover,body .jsoneditor-modal input[type="submit"]:not(.disabled):not(:disabled).active,body .jsoneditor-modal input[type="submit"]:not(.disabled):not(:disabled):hover{border-color:var(--t42-color-opacity-30);color:var(--white);background:var(--primary)}body .jsoneditor-modal .jsoneditor-button-group input.jsoneditor-button-first{border-left-style:solid;border-top-left-radius:0;border-bottom-left-radius:0}body .jsoneditor-modal .jsoneditor-button-group input.jsoneditor-button-last{border-top-right-radius:0;border-bottom-right-radius:0}body .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-asc input.jsoneditor-button-asc,body .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-desc input.jsoneditor-button-desc{color:var(--white);background:var(--primary)}body .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-asc input.jsoneditor-button-asc:hover,body .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-asc input.jsoneditor-button-asc:focus,body .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-asc input.jsoneditor-button-asc:active,body .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-desc input.jsoneditor-button-desc:hover,body .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-desc input.jsoneditor-button-desc:focus,body .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-desc input.jsoneditor-button-desc:active{border-color:var(--t42-color-opacity-30);color:var(--white)}body .jsoneditor-modal .jsoneditor-jmespath-label{color:var(--t42-content-color);font-weight:400}body .jsoneditor-modal .jsoneditor-jmespath-filter-value input{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border-color;line-height:1.875rem;padding:0 0 0 .875rem;font-size:0.75rem;background-color:var(--t42-input-bg)}body .jsoneditor-modal .jsoneditor-jmespath-filter-value input:focus,body .jsoneditor-modal .jsoneditor-jmespath-filter-value input:hover{background-color:var(--t42-input-bg);border-color:var(--primary)}body .jsoneditor-jmespath-block .jsoneditor-modal-actions{text-align:right}body div.jsoneditor td.jsoneditor-tree{vertical-align:middle}body div.jsoneditor td.jsoneditor-separator{vertical-align:middle}body div.jsoneditor-tree{background:transparent}body div.jsoneditor-tree button.jsoneditor-button{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, outline-color;background-image:var(--t42-json-icons)}body div.jsoneditor-tree button.jsoneditor-button:focus{background-color:transparent;outline-color:var(--t42-color-opacity-10)}body tr.jsoneditor-selected,body tr.jsoneditor-highlight{background-color:var(--t42-color-opacity-10)}body .selectr-selected{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border-color;height:2rem;font-size:0.75rem;font-weight:400;line-height:1.875rem;background-color:var(--t42-input-bg);border-radius:0}body .selectr-selected::before{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:transform;right:0.5rem;border:0;width:0.75rem;height:0.75rem;background:var(--t42-select-indicator) center center/1rem 1rem no-repeat;transform:translateY(-50%)}body .selectr-placeholder{color:var(--t42-content-color-muted)}body .selectr-container.open .selectr-selected{border-radius:0;border-color:var(--primary)}body .selectr-container.open .selectr-selected::before{border:0;transform:rotate(180deg) translateY(50%)}body .selectr-container.open .selectr-options-container{border-left-color:var(--primary);border-right-color:var(--primary);border-bottom-color:var(--primary)}body .selectr-options{overflow-y:auto}body .selectr-options-container{min-height:2rem;border-color:var(--t42-color-opacity-10);border-style:solid;border-width:1px;background-color:Rgb(var(--t42-bg-dark))}body .selectr-options .active{color:var(--t42-link-hover-color);background-color:var(--t42-color-opacity-10)}body .selectr-options .selected{color:var(--t42-link-hover-color);background-color:var(--primary)}body .selectr-option{padding:0 0 0 0.875rem;line-height:2rem;font-size:0.75rem}body .selectr-input{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border-color;border:var(--t42-border);background-color:var(--t42-input-bg)}body .selectr-input:hover{border-color:var(--primary)}body .selectr-input-container{padding:0.25rem}body .selectr-clear::before,body .selectr-clear::after{background-color:var(--t42-content-color)}body .jsoneditor .ace-jsoneditor .ace_text-input{min-height:auto}body .jsoneditor .ace-jsoneditor.ace_editor,body .jsoneditor .ace-jsoneditor .ace_scroller{background-color:Rgb(var(--t42-bg-dark))}body .jsoneditor .ace-jsoneditor .ace_gutter{color:var(--t42-content-color-muted);background-color:Rgb(var(--t42-bg-mid))}body .jsoneditor .ace-jsoneditor .ace_gutter-active-line{background-color:Rgb(var(--t42-bg-light))}body .jsoneditor .ace-jsoneditor .ace_cursor{border-color:Rgb(var(--t42-content-color))}body .jsoneditor .ace-jsoneditor .ace_marker-layer .ace_active-line{background-color:rgba(var(--secondary), 0.25)}body .jsoneditor .ace-jsoneditor .ace_marker-layer .ace_selection{background-color:var(--t42-color-opacity-10)}body .jsoneditor .ace-jsoneditor .ace_marker-layer .ace_selected-word{border-color:var(--t42-color-opacity-10);background-color:var(--t42-color-opacity-10)}body .jsoneditor .ace-jsoneditor .ace_marker-layer .ace_bracket{border:var(--t42-border)}body .jsoneditor .ace-jsoneditor .ace_variable{color:var(--t42-content-color)}body .jsoneditor .ace-jsoneditor .ace_constant.ace_numeric{color:#ff511f}body .jsoneditor .ace-jsoneditor .ace_constant.ace_language{color:#f9a825}body .jsoneditor .ace-jsoneditor .ace_string{color:#43a047}body .jsoneditor .ace-jsoneditor .ace_fold{border-color:var(--t42-color-opacity-10);background-color:Rgb(var(--t42-bg-light));transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-image}body .jsoneditor .ace-jsoneditor .ace_fold-widget:hover,body .jsoneditor .ace-jsoneditor .ace_fold-widget:active{border-color:var(--t42-color-opacity-30);background-color:var(--t42-color-opacity-10);box-shadow:none}body .pico-modal-contents{display:block} + diff --git a/typescript/start/client-details/src/lib/workspaces.umd.js b/typescript/start/client-details/src/lib/workspaces.umd.js new file mode 100644 index 0000000..53ca1d8 --- /dev/null +++ b/typescript/start/client-details/src/lib/workspaces.umd.js @@ -0,0 +1,5302 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define(factory) : + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.workspaces = factory()); +})(this, (function () { 'use strict'; + + function getDefaultExportFromCjs (x) { + return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; + } + + function createRegistry(options) { + if (options && options.errorHandling + && typeof options.errorHandling !== "function" + && options.errorHandling !== "log" + && options.errorHandling !== "silent" + && options.errorHandling !== "throw") { + throw new Error("Invalid options passed to createRegistry. Prop errorHandling should be [\"log\" | \"silent\" | \"throw\" | (err) => void], but " + typeof options.errorHandling + " was passed"); + } + var _userErrorHandler = options && typeof options.errorHandling === "function" && options.errorHandling; + var callbacks = {}; + function add(key, callback, replayArgumentsArr) { + var callbacksForKey = callbacks[key]; + if (!callbacksForKey) { + callbacksForKey = []; + callbacks[key] = callbacksForKey; + } + callbacksForKey.push(callback); + if (replayArgumentsArr) { + setTimeout(function () { + replayArgumentsArr.forEach(function (replayArgument) { + var _a; + if ((_a = callbacks[key]) === null || _a === void 0 ? void 0 : _a.includes(callback)) { + try { + if (Array.isArray(replayArgument)) { + callback.apply(undefined, replayArgument); + } + else { + callback.apply(undefined, [replayArgument]); + } + } + catch (err) { + _handleError(err, key); + } + } + }); + }, 0); + } + return function () { + var allForKey = callbacks[key]; + if (!allForKey) { + return; + } + allForKey = allForKey.reduce(function (acc, element, index) { + if (!(element === callback && acc.length === index)) { + acc.push(element); + } + return acc; + }, []); + if (allForKey.length === 0) { + delete callbacks[key]; + } + else { + callbacks[key] = allForKey; + } + }; + } + function execute(key) { + var argumentsArr = []; + for (var _i = 1; _i < arguments.length; _i++) { + argumentsArr[_i - 1] = arguments[_i]; + } + var callbacksForKey = callbacks[key]; + if (!callbacksForKey || callbacksForKey.length === 0) { + return []; + } + var results = []; + callbacksForKey.forEach(function (callback) { + try { + var result = callback.apply(undefined, argumentsArr); + results.push(result); + } + catch (err) { + results.push(undefined); + _handleError(err, key); + } + }); + return results; + } + function _handleError(exceptionArtifact, key) { + var errParam = exceptionArtifact instanceof Error ? exceptionArtifact : new Error(exceptionArtifact); + if (_userErrorHandler) { + _userErrorHandler(errParam); + return; + } + var msg = "[ERROR] callback-registry: User callback for key \"" + key + "\" failed: " + errParam.stack; + if (options) { + switch (options.errorHandling) { + case "log": + return console.error(msg); + case "silent": + return; + case "throw": + throw new Error(msg); + } + } + console.error(msg); + } + function clear() { + callbacks = {}; + } + function clearKey(key) { + var callbacksForKey = callbacks[key]; + if (!callbacksForKey) { + return; + } + delete callbacks[key]; + } + return { + add: add, + execute: execute, + clear: clear, + clearKey: clearKey + }; + } + createRegistry.default = createRegistry; + var lib = createRegistry; + + + var CallbackFactory = /*@__PURE__*/getDefaultExportFromCjs(lib); + + /** + * Wraps values in an `Ok` type. + * + * Example: `ok(5) // => {ok: true, result: 5}` + */ + var ok = function (result) { return ({ ok: true, result: result }); }; + /** + * Wraps errors in an `Err` type. + * + * Example: `err('on fire') // => {ok: false, error: 'on fire'}` + */ + var err = function (error) { return ({ ok: false, error: error }); }; + /** + * Create a `Promise` that either resolves with the result of `Ok` or rejects + * with the error of `Err`. + */ + var asPromise = function (r) { + return r.ok === true ? Promise.resolve(r.result) : Promise.reject(r.error); + }; + /** + * Unwraps a `Result` and returns either the result of an `Ok`, or + * `defaultValue`. + * + * Example: + * ``` + * Result.withDefault(5, number().run(json)) + * ``` + * + * It would be nice if `Decoder` had an instance method that mirrored this + * function. Such a method would look something like this: + * ``` + * class Decoder { + * runWithDefault = (defaultValue: A, json: any): A => + * Result.withDefault(defaultValue, this.run(json)); + * } + * + * number().runWithDefault(5, json) + * ``` + * Unfortunately, the type of `defaultValue: A` on the method causes issues + * with type inference on the `object` decoder in some situations. While these + * inference issues can be solved by providing the optional type argument for + * `object`s, the extra trouble and confusion doesn't seem worth it. + */ + var withDefault = function (defaultValue, r) { + return r.ok === true ? r.result : defaultValue; + }; + /** + * Return the successful result, or throw an error. + */ + var withException = function (r) { + if (r.ok === true) { + return r.result; + } + else { + throw r.error; + } + }; + /** + * Apply `f` to the result of an `Ok`, or pass the error through. + */ + var map = function (f, r) { + return r.ok === true ? ok(f(r.result)) : r; + }; + /** + * Apply `f` to the result of two `Ok`s, or pass an error through. If both + * `Result`s are errors then the first one is returned. + */ + var map2 = function (f, ar, br) { + return ar.ok === false ? ar : + br.ok === false ? br : + ok(f(ar.result, br.result)); + }; + /** + * Apply `f` to the error of an `Err`, or pass the success through. + */ + var mapError = function (f, r) { + return r.ok === true ? r : err(f(r.error)); + }; + /** + * Chain together a sequence of computations that may fail, similar to a + * `Promise`. If the first computation fails then the error will propagate + * through. If it succeeds, then `f` will be applied to the value, returning a + * new `Result`. + */ + var andThen = function (f, r) { + return r.ok === true ? f(r.result) : r; + }; + + /*! ***************************************************************************** + Copyright (c) Microsoft Corporation. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THIS SOFTWARE. + ***************************************************************************** */ + /* global Reflect, Promise */ + + + + var __assign = function() { + __assign = Object.assign || function __assign(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; + } + return t; + }; + return __assign.apply(this, arguments); + }; + + function __rest(s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { + if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) + t[p[i]] = s[p[i]]; + } + return t; + } + + function isEqual(a, b) { + if (a === b) { + return true; + } + if (a === null && b === null) { + return true; + } + if (typeof (a) !== typeof (b)) { + return false; + } + if (typeof (a) === 'object') { + // Array + if (Array.isArray(a)) { + if (!Array.isArray(b)) { + return false; + } + if (a.length !== b.length) { + return false; + } + for (var i = 0; i < a.length; i++) { + if (!isEqual(a[i], b[i])) { + return false; + } + } + return true; + } + // Hash table + var keys = Object.keys(a); + if (keys.length !== Object.keys(b).length) { + return false; + } + for (var i = 0; i < keys.length; i++) { + if (!b.hasOwnProperty(keys[i])) { + return false; + } + if (!isEqual(a[keys[i]], b[keys[i]])) { + return false; + } + } + return true; + } + } + /* + * Helpers + */ + var isJsonArray = function (json) { return Array.isArray(json); }; + var isJsonObject = function (json) { + return typeof json === 'object' && json !== null && !isJsonArray(json); + }; + var typeString = function (json) { + switch (typeof json) { + case 'string': + return 'a string'; + case 'number': + return 'a number'; + case 'boolean': + return 'a boolean'; + case 'undefined': + return 'undefined'; + case 'object': + if (json instanceof Array) { + return 'an array'; + } + else if (json === null) { + return 'null'; + } + else { + return 'an object'; + } + default: + return JSON.stringify(json); + } + }; + var expectedGot = function (expected, got) { + return "expected " + expected + ", got " + typeString(got); + }; + var printPath = function (paths) { + return paths.map(function (path) { return (typeof path === 'string' ? "." + path : "[" + path + "]"); }).join(''); + }; + var prependAt = function (newAt, _a) { + var at = _a.at, rest = __rest(_a, ["at"]); + return (__assign({ at: newAt + (at || '') }, rest)); + }; + /** + * Decoders transform json objects with unknown structure into known and + * verified forms. You can create objects of type `Decoder` with either the + * primitive decoder functions, such as `boolean()` and `string()`, or by + * applying higher-order decoders to the primitives, such as `array(boolean())` + * or `dict(string())`. + * + * Each of the decoder functions are available both as a static method on + * `Decoder` and as a function alias -- for example the string decoder is + * defined at `Decoder.string()`, but is also aliased to `string()`. Using the + * function aliases exported with the library is recommended. + * + * `Decoder` exposes a number of 'run' methods, which all decode json in the + * same way, but communicate success and failure in different ways. The `map` + * and `andThen` methods modify decoders without having to call a 'run' method. + * + * Alternatively, the main decoder `run()` method returns an object of type + * `Result`. This library provides a number of helper + * functions for dealing with the `Result` type, so you can do all the same + * things with a `Result` as with the decoder methods. + */ + var Decoder = /** @class */ (function () { + /** + * The Decoder class constructor is kept private to separate the internal + * `decode` function from the external `run` function. The distinction + * between the two functions is that `decode` returns a + * `Partial` on failure, which contains an unfinished error + * report. When `run` is called on a decoder, the relevant series of `decode` + * calls is made, and then on failure the resulting `Partial` + * is turned into a `DecoderError` by filling in the missing information. + * + * While hiding the constructor may seem restrictive, leveraging the + * provided decoder combinators and helper functions such as + * `andThen` and `map` should be enough to build specialized decoders as + * needed. + */ + function Decoder(decode) { + var _this = this; + this.decode = decode; + /** + * Run the decoder and return a `Result` with either the decoded value or a + * `DecoderError` containing the json input, the location of the error, and + * the error message. + * + * Examples: + * ``` + * number().run(12) + * // => {ok: true, result: 12} + * + * string().run(9001) + * // => + * // { + * // ok: false, + * // error: { + * // kind: 'DecoderError', + * // input: 9001, + * // at: 'input', + * // message: 'expected a string, got 9001' + * // } + * // } + * ``` + */ + this.run = function (json) { + return mapError(function (error) { return ({ + kind: 'DecoderError', + input: json, + at: 'input' + (error.at || ''), + message: error.message || '' + }); }, _this.decode(json)); + }; + /** + * Run the decoder as a `Promise`. + */ + this.runPromise = function (json) { return asPromise(_this.run(json)); }; + /** + * Run the decoder and return the value on success, or throw an exception + * with a formatted error string. + */ + this.runWithException = function (json) { return withException(_this.run(json)); }; + /** + * Construct a new decoder that applies a transformation to the decoded + * result. If the decoder succeeds then `f` will be applied to the value. If + * it fails the error will propagated through. + * + * Example: + * ``` + * number().map(x => x * 5).run(10) + * // => {ok: true, result: 50} + * ``` + */ + this.map = function (f) { + return new Decoder(function (json) { return map(f, _this.decode(json)); }); + }; + /** + * Chain together a sequence of decoders. The first decoder will run, and + * then the function will determine what decoder to run second. If the result + * of the first decoder succeeds then `f` will be applied to the decoded + * value. If it fails the error will propagate through. + * + * This is a very powerful method -- it can act as both the `map` and `where` + * methods, can improve error messages for edge cases, and can be used to + * make a decoder for custom types. + * + * Example of adding an error message: + * ``` + * const versionDecoder = valueAt(['version'], number()); + * const infoDecoder3 = object({a: boolean()}); + * + * const decoder = versionDecoder.andThen(version => { + * switch (version) { + * case 3: + * return infoDecoder3; + * default: + * return fail(`Unable to decode info, version ${version} is not supported.`); + * } + * }); + * + * decoder.run({version: 3, a: true}) + * // => {ok: true, result: {a: true}} + * + * decoder.run({version: 5, x: 'abc'}) + * // => + * // { + * // ok: false, + * // error: {... message: 'Unable to decode info, version 5 is not supported.'} + * // } + * ``` + * + * Example of decoding a custom type: + * ``` + * // nominal type for arrays with a length of at least one + * type NonEmptyArray = T[] & { __nonEmptyArrayBrand__: void }; + * + * const nonEmptyArrayDecoder = (values: Decoder): Decoder> => + * array(values).andThen(arr => + * arr.length > 0 + * ? succeed(createNonEmptyArray(arr)) + * : fail(`expected a non-empty array, got an empty array`) + * ); + * ``` + */ + this.andThen = function (f) { + return new Decoder(function (json) { + return andThen(function (value) { return f(value).decode(json); }, _this.decode(json)); + }); + }; + /** + * Add constraints to a decoder _without_ changing the resulting type. The + * `test` argument is a predicate function which returns true for valid + * inputs. When `test` fails on an input, the decoder fails with the given + * `errorMessage`. + * + * ``` + * const chars = (length: number): Decoder => + * string().where( + * (s: string) => s.length === length, + * `expected a string of length ${length}` + * ); + * + * chars(5).run('12345') + * // => {ok: true, result: '12345'} + * + * chars(2).run('HELLO') + * // => {ok: false, error: {... message: 'expected a string of length 2'}} + * + * chars(12).run(true) + * // => {ok: false, error: {... message: 'expected a string, got a boolean'}} + * ``` + */ + this.where = function (test, errorMessage) { + return _this.andThen(function (value) { return (test(value) ? Decoder.succeed(value) : Decoder.fail(errorMessage)); }); + }; + } + /** + * Decoder primitive that validates strings, and fails on all other input. + */ + Decoder.string = function () { + return new Decoder(function (json) { + return typeof json === 'string' + ? ok(json) + : err({ message: expectedGot('a string', json) }); + }); + }; + /** + * Decoder primitive that validates numbers, and fails on all other input. + */ + Decoder.number = function () { + return new Decoder(function (json) { + return typeof json === 'number' + ? ok(json) + : err({ message: expectedGot('a number', json) }); + }); + }; + /** + * Decoder primitive that validates booleans, and fails on all other input. + */ + Decoder.boolean = function () { + return new Decoder(function (json) { + return typeof json === 'boolean' + ? ok(json) + : err({ message: expectedGot('a boolean', json) }); + }); + }; + Decoder.constant = function (value) { + return new Decoder(function (json) { + return isEqual(json, value) + ? ok(value) + : err({ message: "expected " + JSON.stringify(value) + ", got " + JSON.stringify(json) }); + }); + }; + Decoder.object = function (decoders) { + return new Decoder(function (json) { + if (isJsonObject(json) && decoders) { + var obj = {}; + for (var key in decoders) { + if (decoders.hasOwnProperty(key)) { + var r = decoders[key].decode(json[key]); + if (r.ok === true) { + // tslint:disable-next-line:strict-type-predicates + if (r.result !== undefined) { + obj[key] = r.result; + } + } + else if (json[key] === undefined) { + return err({ message: "the key '" + key + "' is required but was not present" }); + } + else { + return err(prependAt("." + key, r.error)); + } + } + } + return ok(obj); + } + else if (isJsonObject(json)) { + return ok(json); + } + else { + return err({ message: expectedGot('an object', json) }); + } + }); + }; + Decoder.array = function (decoder) { + return new Decoder(function (json) { + if (isJsonArray(json) && decoder) { + var decodeValue_1 = function (v, i) { + return mapError(function (err$$1) { return prependAt("[" + i + "]", err$$1); }, decoder.decode(v)); + }; + return json.reduce(function (acc, v, i) { + return map2(function (arr, result) { return arr.concat([result]); }, acc, decodeValue_1(v, i)); + }, ok([])); + } + else if (isJsonArray(json)) { + return ok(json); + } + else { + return err({ message: expectedGot('an array', json) }); + } + }); + }; + Decoder.tuple = function (decoders) { + return new Decoder(function (json) { + if (isJsonArray(json)) { + if (json.length !== decoders.length) { + return err({ + message: "expected a tuple of length " + decoders.length + ", got one of length " + json.length + }); + } + var result = []; + for (var i = 0; i < decoders.length; i++) { + var nth = decoders[i].decode(json[i]); + if (nth.ok) { + result[i] = nth.result; + } + else { + return err(prependAt("[" + i + "]", nth.error)); + } + } + return ok(result); + } + else { + return err({ message: expectedGot("a tuple of length " + decoders.length, json) }); + } + }); + }; + Decoder.union = function (ad, bd) { + var decoders = []; + for (var _i = 2; _i < arguments.length; _i++) { + decoders[_i - 2] = arguments[_i]; + } + return Decoder.oneOf.apply(Decoder, [ad, bd].concat(decoders)); + }; + Decoder.intersection = function (ad, bd) { + var ds = []; + for (var _i = 2; _i < arguments.length; _i++) { + ds[_i - 2] = arguments[_i]; + } + return new Decoder(function (json) { + return [ad, bd].concat(ds).reduce(function (acc, decoder) { return map2(Object.assign, acc, decoder.decode(json)); }, ok({})); + }); + }; + /** + * Escape hatch to bypass validation. Always succeeds and types the result as + * `any`. Useful for defining decoders incrementally, particularly for + * complex objects. + * + * Example: + * ``` + * interface User { + * name: string; + * complexUserData: ComplexType; + * } + * + * const userDecoder: Decoder = object({ + * name: string(), + * complexUserData: anyJson() + * }); + * ``` + */ + Decoder.anyJson = function () { return new Decoder(function (json) { return ok(json); }); }; + /** + * Decoder identity function which always succeeds and types the result as + * `unknown`. + */ + Decoder.unknownJson = function () { + return new Decoder(function (json) { return ok(json); }); + }; + /** + * Decoder for json objects where the keys are unknown strings, but the values + * should all be of the same type. + * + * Example: + * ``` + * dict(number()).run({chocolate: 12, vanilla: 10, mint: 37}); + * // => {ok: true, result: {chocolate: 12, vanilla: 10, mint: 37}} + * ``` + */ + Decoder.dict = function (decoder) { + return new Decoder(function (json) { + if (isJsonObject(json)) { + var obj = {}; + for (var key in json) { + if (json.hasOwnProperty(key)) { + var r = decoder.decode(json[key]); + if (r.ok === true) { + obj[key] = r.result; + } + else { + return err(prependAt("." + key, r.error)); + } + } + } + return ok(obj); + } + else { + return err({ message: expectedGot('an object', json) }); + } + }); + }; + /** + * Decoder for values that may be `undefined`. This is primarily helpful for + * decoding interfaces with optional fields. + * + * Example: + * ``` + * interface User { + * id: number; + * isOwner?: boolean; + * } + * + * const decoder: Decoder = object({ + * id: number(), + * isOwner: optional(boolean()) + * }); + * ``` + */ + Decoder.optional = function (decoder) { + return new Decoder(function (json) { return (json === undefined || json === null ? ok(undefined) : decoder.decode(json)); }); + }; + /** + * Decoder that attempts to run each decoder in `decoders` and either succeeds + * with the first successful decoder, or fails after all decoders have failed. + * + * Note that `oneOf` expects the decoders to all have the same return type, + * while `union` creates a decoder for the union type of all the input + * decoders. + * + * Examples: + * ``` + * oneOf(string(), number().map(String)) + * oneOf(constant('start'), constant('stop'), succeed('unknown')) + * ``` + */ + Decoder.oneOf = function () { + var decoders = []; + for (var _i = 0; _i < arguments.length; _i++) { + decoders[_i] = arguments[_i]; + } + return new Decoder(function (json) { + var errors = []; + for (var i = 0; i < decoders.length; i++) { + var r = decoders[i].decode(json); + if (r.ok === true) { + return r; + } + else { + errors[i] = r.error; + } + } + var errorsList = errors + .map(function (error) { return "at error" + (error.at || '') + ": " + error.message; }) + .join('", "'); + return err({ + message: "expected a value matching one of the decoders, got the errors [\"" + errorsList + "\"]" + }); + }); + }; + /** + * Decoder that always succeeds with either the decoded value, or a fallback + * default value. + */ + Decoder.withDefault = function (defaultValue, decoder) { + return new Decoder(function (json) { + return ok(withDefault(defaultValue, decoder.decode(json))); + }); + }; + /** + * Decoder that pulls a specific field out of a json structure, instead of + * decoding and returning the full structure. The `paths` array describes the + * object keys and array indices to traverse, so that values can be pulled out + * of a nested structure. + * + * Example: + * ``` + * const decoder = valueAt(['a', 'b', 0], string()); + * + * decoder.run({a: {b: ['surprise!']}}) + * // => {ok: true, result: 'surprise!'} + * + * decoder.run({a: {x: 'cats'}}) + * // => {ok: false, error: {... at: 'input.a.b[0]' message: 'path does not exist'}} + * ``` + * + * Note that the `decoder` is ran on the value found at the last key in the + * path, even if the last key is not found. This allows the `optional` + * decoder to succeed when appropriate. + * ``` + * const optionalDecoder = valueAt(['a', 'b', 'c'], optional(string())); + * + * optionalDecoder.run({a: {b: {c: 'surprise!'}}}) + * // => {ok: true, result: 'surprise!'} + * + * optionalDecoder.run({a: {b: 'cats'}}) + * // => {ok: false, error: {... at: 'input.a.b.c' message: 'expected an object, got "cats"'} + * + * optionalDecoder.run({a: {b: {z: 1}}}) + * // => {ok: true, result: undefined} + * ``` + */ + Decoder.valueAt = function (paths, decoder) { + return new Decoder(function (json) { + var jsonAtPath = json; + for (var i = 0; i < paths.length; i++) { + if (jsonAtPath === undefined) { + return err({ + at: printPath(paths.slice(0, i + 1)), + message: 'path does not exist' + }); + } + else if (typeof paths[i] === 'string' && !isJsonObject(jsonAtPath)) { + return err({ + at: printPath(paths.slice(0, i + 1)), + message: expectedGot('an object', jsonAtPath) + }); + } + else if (typeof paths[i] === 'number' && !isJsonArray(jsonAtPath)) { + return err({ + at: printPath(paths.slice(0, i + 1)), + message: expectedGot('an array', jsonAtPath) + }); + } + else { + jsonAtPath = jsonAtPath[paths[i]]; + } + } + return mapError(function (error) { + return jsonAtPath === undefined + ? { at: printPath(paths), message: 'path does not exist' } + : prependAt(printPath(paths), error); + }, decoder.decode(jsonAtPath)); + }); + }; + /** + * Decoder that ignores the input json and always succeeds with `fixedValue`. + */ + Decoder.succeed = function (fixedValue) { + return new Decoder(function (json) { return ok(fixedValue); }); + }; + /** + * Decoder that ignores the input json and always fails with `errorMessage`. + */ + Decoder.fail = function (errorMessage) { + return new Decoder(function (json) { return err({ message: errorMessage }); }); + }; + /** + * Decoder that allows for validating recursive data structures. Unlike with + * functions, decoders assigned to variables can't reference themselves + * before they are fully defined. We can avoid prematurely referencing the + * decoder by wrapping it in a function that won't be called until use, at + * which point the decoder has been defined. + * + * Example: + * ``` + * interface Comment { + * msg: string; + * replies: Comment[]; + * } + * + * const decoder: Decoder = object({ + * msg: string(), + * replies: lazy(() => array(decoder)) + * }); + * ``` + */ + Decoder.lazy = function (mkDecoder) { + return new Decoder(function (json) { return mkDecoder().decode(json); }); + }; + return Decoder; + }()); + + /* tslint:disable:variable-name */ + /** See `Decoder.string` */ + var string = Decoder.string; + /** See `Decoder.number` */ + var number = Decoder.number; + /** See `Decoder.boolean` */ + var boolean = Decoder.boolean; + /** See `Decoder.anyJson` */ + var anyJson = Decoder.anyJson; + /** See `Decoder.unknownJson` */ + Decoder.unknownJson; + /** See `Decoder.constant` */ + var constant = Decoder.constant; + /** See `Decoder.object` */ + var object = Decoder.object; + /** See `Decoder.array` */ + var array = Decoder.array; + /** See `Decoder.tuple` */ + Decoder.tuple; + /** See `Decoder.dict` */ + Decoder.dict; + /** See `Decoder.optional` */ + var optional = Decoder.optional; + /** See `Decoder.oneOf` */ + var oneOf = Decoder.oneOf; + /** See `Decoder.union` */ + Decoder.union; + /** See `Decoder.intersection` */ + var intersection = Decoder.intersection; + /** See `Decoder.withDefault` */ + Decoder.withDefault; + /** See `Decoder.valueAt` */ + Decoder.valueAt; + /** See `Decoder.succeed` */ + Decoder.succeed; + /** See `Decoder.fail` */ + Decoder.fail; + /** See `Decoder.lazy` */ + var lazy = Decoder.lazy; + + const nonEmptyStringDecoder = string().where((s) => s.length > 0, "Expected a non-empty string"); + const nonNegativeNumberDecoder = number().where((num) => num >= 0, "Expected a non-negative number"); + const positiveNumberDecoder = number().where((num) => num > 0, "Expected a positive number"); + const windowDragModeDecoder = oneOf(constant("keepInside"), constant("autoEject")); + const isWindowInSwimlaneResultDecoder = object({ + inWorkspace: boolean() + }); + const allParentDecoder = oneOf(constant("workspace"), constant("row"), constant("column"), constant("group")); + const subParentDecoder = oneOf(constant("row"), constant("column"), constant("group")); + const frameStateDecoder = oneOf(constant("maximized"), constant("minimized"), constant("normal")); + const loadingAnimationTypeDecoder = oneOf(constant("workspace")); + const checkThrowCallback = (callback, allowUndefined) => { + const argumentType = typeof callback; + if (allowUndefined && argumentType !== "function" && argumentType !== "undefined") { + throw new Error(`Provided argument must be either undefined or of type function, provided: ${argumentType}`); + } + if (!allowUndefined && argumentType !== "function") { + throw new Error(`Provided argument must be of type function, provided: ${argumentType}`); + } + }; + const workspaceBuilderCreateConfigDecoder = optional(object({ + saveLayout: optional(boolean()) + })); + const deleteLayoutConfigDecoder = object({ + name: nonEmptyStringDecoder + }); + const windowDefinitionConfigDecoder = object({ + minWidth: optional(number()), + maxWidth: optional(number()), + minHeight: optional(number()), + maxHeight: optional(number()), + allowExtract: optional(boolean()), + allowReorder: optional(boolean()), + showCloseButton: optional(boolean()) + }); + const groupDefinitionConfigDecoder = object({ + minWidth: optional(number()), + maxWidth: optional(number()), + minHeight: optional(number()), + maxHeight: optional(number()), + allowExtract: optional(boolean()), + allowReorder: optional(boolean()), + allowDrop: optional(boolean()), + allowDropHeader: optional(boolean()), + allowDropLeft: optional(boolean()), + allowDropRight: optional(boolean()), + allowDropTop: optional(boolean()), + allowDropBottom: optional(boolean()), + showMaximizeButton: optional(boolean()), + showEjectButton: optional(boolean()), + showAddWindowButton: optional(boolean()) + }); + const rowDefinitionConfigDecoder = object({ + minHeight: optional(number()), + maxHeight: optional(number()), + allowDrop: optional(boolean()), + allowSplitters: optional(boolean()), + isPinned: optional(boolean()), + maximizationBoundary: optional(boolean()) + }); + const columnDefinitionConfigDecoder = object({ + minWidth: optional(number()), + maxWidth: optional(number()), + allowDrop: optional(boolean()), + allowSplitters: optional(boolean()), + isPinned: optional(boolean()), + maximizationBoundary: optional(boolean()) + }); + const swimlaneWindowDefinitionDecoder = object({ + type: optional(constant("window")), + appName: optional(nonEmptyStringDecoder), + windowId: optional(nonEmptyStringDecoder), + context: optional(anyJson()), + config: optional(windowDefinitionConfigDecoder) + }); + const strictSwimlaneWindowDefinitionDecoder = object({ + type: constant("window"), + appName: optional(nonEmptyStringDecoder), + windowId: optional(nonEmptyStringDecoder), + context: optional(anyJson()), + config: optional(windowDefinitionConfigDecoder) + }); + const parentDefinitionDecoder = optional(object({ + type: optional(subParentDecoder), + children: optional(lazy(() => array(oneOf(swimlaneWindowDefinitionDecoder, parentDefinitionDecoder)))), + config: optional(anyJson()) + })); + const strictColumnDefinitionDecoder = object({ + type: constant("column"), + children: optional(lazy(() => array(oneOf(strictSwimlaneWindowDefinitionDecoder, strictParentDefinitionDecoder)))), + config: optional(columnDefinitionConfigDecoder) + }); + const strictRowDefinitionDecoder = object({ + type: constant("row"), + children: optional(lazy(() => array(oneOf(strictSwimlaneWindowDefinitionDecoder, strictParentDefinitionDecoder)))), + config: optional(rowDefinitionConfigDecoder) + }); + const strictGroupDefinitionDecoder = object({ + type: constant("group"), + children: optional(lazy(() => array(oneOf(strictSwimlaneWindowDefinitionDecoder, strictParentDefinitionDecoder)))), + config: optional(groupDefinitionConfigDecoder) + }); + const strictParentDefinitionDecoder = oneOf(strictGroupDefinitionDecoder, strictColumnDefinitionDecoder, strictRowDefinitionDecoder); + oneOf(string().where((s) => s.toLowerCase() === "maximized", "Expected a case insensitive variation of 'maximized'"), string().where((s) => s.toLowerCase() === "normal", "Expected a case insensitive variation of 'normal'")); + const newFrameConfigDecoder = object({ + bounds: optional(object({ + left: optional(number()), + top: optional(number()), + width: optional(nonNegativeNumberDecoder), + height: optional(nonNegativeNumberDecoder) + })), + frameId: optional(nonEmptyStringDecoder) + }); + const loadingStrategyDecoder = oneOf(constant("direct"), constant("delayed"), constant("lazy")); + const restoreWorkspaceConfigDecoder = optional(object({ + app: optional(nonEmptyStringDecoder), + context: optional(anyJson()), + loadingStrategy: optional(loadingStrategyDecoder), + title: optional(nonEmptyStringDecoder), + reuseWorkspaceId: optional(nonEmptyStringDecoder), + frameId: optional(nonEmptyStringDecoder), + applicationName: optional(nonEmptyStringDecoder), + lockdown: optional(boolean()), + activateFrame: optional(boolean()), + newFrame: optional(oneOf(newFrameConfigDecoder, boolean())), + noTabHeader: optional(boolean()), + inMemoryLayout: optional(boolean()), + icon: optional(nonEmptyStringDecoder), + isPinned: optional(boolean()), + isSelected: optional(boolean()), + positionIndex: optional(nonNegativeNumberDecoder), + allowSystemHibernation: optional(boolean()) + })); + const openWorkspaceConfigDecoder = object({ + name: nonEmptyStringDecoder, + restoreOptions: optional(restoreWorkspaceConfigDecoder) + }); + const workspaceDefinitionDecoder = object({ + children: optional(array(oneOf(swimlaneWindowDefinitionDecoder, strictParentDefinitionDecoder))), + context: optional(anyJson()), + config: optional(object({ + title: optional(nonEmptyStringDecoder), + position: optional(nonNegativeNumberDecoder), + isFocused: optional(boolean()), + noTabHeader: optional(boolean()), + reuseWorkspaceId: optional(nonEmptyStringDecoder), + loadingStrategy: optional(loadingStrategyDecoder), + allowDrop: optional(boolean()), + allowDropLeft: optional(boolean()), + allowDropTop: optional(boolean()), + allowDropRight: optional(boolean()), + allowDropBottom: optional(boolean()), + allowSystemHibernation: optional(boolean()), + allowExtract: optional(boolean()), + allowWindowReorder: optional(boolean()), + showSaveButton: optional(boolean()), + allowWorkspaceTabReorder: optional(boolean()), + allowWorkspaceTabExtract: optional(boolean()), + showCloseButton: optional(boolean()), + allowSplitters: optional(boolean()), + showWindowCloseButtons: optional(boolean()), + showEjectButtons: optional(boolean()), + showAddWindowButtons: optional(boolean()), + icon: optional(nonEmptyStringDecoder), + isPinned: optional(boolean()), + isSelected: optional(boolean()), + positionIndex: optional(nonNegativeNumberDecoder), + windowDragMode: optional(windowDragModeDecoder) + })), + frame: optional(object({ + activate: optional(boolean()), + reuseFrameId: optional(nonEmptyStringDecoder), + applicationName: optional(nonEmptyStringDecoder), + newFrame: optional(oneOf(boolean(), newFrameConfigDecoder)) + })) + }); + const workspaceSelectorDecoder = object({ + workspaceId: nonEmptyStringDecoder + }); + const restoreWorkspaceDefinitionDecoder = object({ + name: nonEmptyStringDecoder, + restoreOptions: optional(restoreWorkspaceConfigDecoder) + }); + const emptyFrameDefinitionDecoder = optional(object({ + applicationName: optional(string()), + frameConfig: optional(newFrameConfigDecoder), + context: optional(object()), + layoutComponentId: optional(nonEmptyStringDecoder) + })); + const frameInitConfigDecoder = object({ + workspaces: array(oneOf(optional(workspaceDefinitionDecoder), optional(restoreWorkspaceDefinitionDecoder))) + }); + const frameInitProtocolConfigDecoder = object({ + frameId: nonEmptyStringDecoder, + workspaces: array(oneOf(workspaceDefinitionDecoder, restoreWorkspaceDefinitionDecoder)) + }); + const builderConfigDecoder = object({ + type: allParentDecoder, + definition: optional(oneOf(workspaceDefinitionDecoder, parentDefinitionDecoder)) + }); + const workspaceCreateConfigDecoder = intersection(workspaceDefinitionDecoder, object({ + saveConfig: optional(object({ + saveLayout: optional(boolean()) + })) + })); + const getFrameSummaryConfigDecoder = object({ + itemId: nonEmptyStringDecoder + }); + const frameInitializationContextDecoder = object({ + context: optional(object()) + }); + const frameSummaryDecoder = object({ + id: nonEmptyStringDecoder, + isFocused: optional(boolean()), + isInitialized: optional(boolean()), + initializationContext: optional(frameInitializationContextDecoder) + }); + object({ + type: subParentDecoder, + id: nonEmptyStringDecoder, + frameId: nonEmptyStringDecoder, + workspaceId: nonEmptyStringDecoder, + positionIndex: number() + }); + const eventTypeDecoder = oneOf(constant("frame"), constant("workspace"), constant("container"), constant("window")); + const streamRequestArgumentsDecoder = object({ + type: eventTypeDecoder, + branch: nonEmptyStringDecoder + }); + const workspaceEventActionDecoder = oneOf(constant("opened"), constant("closing"), constant("closed"), constant("focus"), constant("added"), constant("loaded"), constant("removed"), constant("childrenUpdate"), constant("containerChange"), constant("maximized"), constant("restored"), constant("minimized"), constant("normal"), constant("selected"), constant("lock-configuration-changed"), constant("hibernated"), constant("resumed")); + const workspaceConfigResultDecoder = object({ + frameId: nonEmptyStringDecoder, + title: nonEmptyStringDecoder, + positionIndex: nonNegativeNumberDecoder, + name: nonEmptyStringDecoder, + layoutName: optional(nonEmptyStringDecoder), + isHibernated: optional(boolean()), + isSelected: optional(boolean()), + allowDrop: optional(boolean()), + allowSystemHibernation: optional(boolean()), + allowExtract: optional(boolean()), + allowWindowReorder: optional(boolean()), + allowSplitters: optional(boolean()), + showCloseButton: optional(boolean()), + showSaveButton: optional(boolean()), + allowWorkspaceTabReorder: optional(boolean()), + allowWorkspaceTabExtract: optional(boolean()), + allowDropLeft: optional(boolean()), + allowDropTop: optional(boolean()), + allowDropRight: optional(boolean()), + allowDropBottom: optional(boolean()), + minWidth: optional(number()), + maxWidth: optional(number()), + minHeight: optional(number()), + maxHeight: optional(number()), + showAddWindowButtons: optional(boolean()), + showEjectButtons: optional(boolean()), + showWindowCloseButtons: optional(boolean()), + widthInPx: optional(number()), + heightInPx: optional(number()), + isPinned: optional(boolean()), + windowDragMode: optional(windowDragModeDecoder), + loadingStrategy: optional(loadingStrategyDecoder) + }); + const baseChildSnapshotConfigDecoder = object({ + frameId: nonEmptyStringDecoder, + workspaceId: nonEmptyStringDecoder, + positionIndex: number(), + minWidth: optional(number()), + maxWidth: optional(number()), + minHeight: optional(number()), + maxHeight: optional(number()) + }); + const parentSnapshotConfigDecoder = anyJson(); + const swimlaneWindowSnapshotConfigDecoder = intersection(baseChildSnapshotConfigDecoder, object({ + windowId: optional(nonEmptyStringDecoder), + isMaximized: optional(boolean()), + isFocused: boolean(), + isSelected: optional(boolean()), + title: optional(string()), + appName: optional(nonEmptyStringDecoder), + allowExtract: optional(boolean()), + allowReorder: optional(boolean()), + showCloseButton: optional(boolean()), + minWidth: optional(number()), + minHeight: optional(number()), + maxWidth: optional(number()), + maxHeight: optional(number()), + widthInPx: optional(number()), + heightInPx: optional(number()), + context: optional(anyJson()) + })); + const customWorkspaceSubParentSnapshotDecoder = object({ + id: optional(nonEmptyStringDecoder), + config: parentSnapshotConfigDecoder, + children: optional(lazy(() => array(customWorkspaceChildSnapshotDecoder))), + type: oneOf(constant("row"), constant("column"), constant("group")) + }); + const customWorkspaceWindowSnapshotDecoder = object({ + id: optional(nonEmptyStringDecoder), + config: swimlaneWindowSnapshotConfigDecoder, + type: constant("window") + }); + const customWorkspaceChildSnapshotDecoder = oneOf(customWorkspaceWindowSnapshotDecoder, customWorkspaceSubParentSnapshotDecoder); + const childSnapshotResultDecoder = customWorkspaceChildSnapshotDecoder; + const workspaceSnapshotResultDecoder = object({ + id: nonEmptyStringDecoder, + config: workspaceConfigResultDecoder, + children: array(childSnapshotResultDecoder), + frameSummary: frameSummaryDecoder, + context: optional(anyJson()) + }); + const windowLayoutItemDecoder = object({ + type: constant("window"), + config: object({ + appName: nonEmptyStringDecoder, + windowId: optional(nonEmptyStringDecoder), + context: optional(anyJson()), + url: optional(nonEmptyStringDecoder), + title: optional(string()), + allowExtract: optional(boolean()), + allowReorder: optional(boolean()), + showCloseButton: optional(boolean()), + minWidth: optional(number()), + minHeight: optional(number()), + maxWidth: optional(number()), + maxHeight: optional(number()), + isMaximized: optional(boolean()) + }) + }); + const groupLayoutItemDecoder = object({ + type: constant("group"), + config: anyJson(), + children: array(oneOf(windowLayoutItemDecoder)) + }); + const columnLayoutItemDecoder = object({ + type: constant("column"), + config: anyJson(), + children: array(oneOf(groupLayoutItemDecoder, windowLayoutItemDecoder, lazy(() => columnLayoutItemDecoder), lazy(() => rowLayoutItemDecoder))) + }); + const rowLayoutItemDecoder = object({ + type: constant("row"), + config: anyJson(), + children: array(oneOf(columnLayoutItemDecoder, groupLayoutItemDecoder, windowLayoutItemDecoder, lazy(() => rowLayoutItemDecoder))) + }); + const workspaceLayoutDecoder = object({ + name: nonEmptyStringDecoder, + type: constant("Workspace"), + metadata: optional(anyJson()), + components: array(object({ + type: constant("Workspace"), + application: optional(string()), + state: object({ + config: anyJson(), + context: anyJson(), + children: array(oneOf(rowLayoutItemDecoder, columnLayoutItemDecoder, groupLayoutItemDecoder, windowLayoutItemDecoder)) + }) + })) + }); + const workspacesImportLayoutDecoder = object({ + layout: workspaceLayoutDecoder, + mode: oneOf(constant("replace"), constant("merge")) + }); + const workspacesImportLayoutsDecoder = object({ + layouts: array(workspaceLayoutDecoder), + mode: oneOf(constant("replace"), constant("merge")) + }); + const exportedLayoutsResultDecoder = object({ + layouts: array(workspaceLayoutDecoder) + }); + const frameSummaryResultDecoder = object({ + id: nonEmptyStringDecoder, + isFocused: optional(boolean()), + isInitialized: optional(boolean()), + initializationContext: optional(frameInitializationContextDecoder) + }); + const frameSummariesResultDecoder = object({ + summaries: array(frameSummaryResultDecoder) + }); + const workspaceSummaryResultDecoder = object({ + id: nonEmptyStringDecoder, + config: workspaceConfigResultDecoder + }); + const workspaceSummariesResultDecoder = object({ + summaries: array(workspaceSummaryResultDecoder) + }); + const frameSnapshotResultDecoder = object({ + id: nonEmptyStringDecoder, + config: anyJson(), + workspaces: array(workspaceSnapshotResultDecoder) + }); + const layoutSummaryDecoder = object({ + name: nonEmptyStringDecoder, + applicationName: optional(string()) + }); + const layoutSummariesDecoder = object({ + summaries: array(layoutSummaryDecoder) + }); + const simpleWindowOperationSuccessResultDecoder = object({ + windowId: nonEmptyStringDecoder + }); + const voidResultDecoder = anyJson(); + const frameStateResultDecoder = object({ + state: frameStateDecoder + }); + const frameBoundsDecoder = object({ + top: number(), + left: number(), + width: nonNegativeNumberDecoder, + height: nonNegativeNumberDecoder + }); + const frameBoundsResultDecoder = object({ + bounds: frameBoundsDecoder + }); + const getWorkspaceIconResultDecoder = object({ + icon: optional(nonEmptyStringDecoder) + }); + const getPlatformFrameIdResultDecoder = object({ + id: optional(nonEmptyStringDecoder) + }); + const operationCheckResultDecoder = object({ + isSupported: boolean() + }); + const resizeConfigDecoder = object({ + width: optional(positiveNumberDecoder), + height: optional(positiveNumberDecoder), + relative: optional(boolean()) + }); + const moveConfigDecoder = object({ + top: optional(number()), + left: optional(number()), + relative: optional(boolean()) + }); + const simpleItemConfigDecoder = object({ + itemId: nonEmptyStringDecoder + }); + const frameSnapshotConfigDecoder = object({ + itemId: nonEmptyStringDecoder, + excludeIds: optional(boolean()) + }); + const frameStateConfigDecoder = object({ + frameId: nonEmptyStringDecoder, + requestedState: frameStateDecoder + }); + const setItemTitleConfigDecoder = object({ + itemId: nonEmptyStringDecoder, + title: nonEmptyStringDecoder + }); + const moveWindowConfigDecoder = object({ + itemId: nonEmptyStringDecoder, + containerId: nonEmptyStringDecoder + }); + const resizeItemConfigDecoder = intersection(simpleItemConfigDecoder, resizeConfigDecoder); + const setMaximizationBoundaryConfigDecoder = object({ + itemId: nonEmptyStringDecoder, + enabled: boolean() + }); + const moveFrameConfigDecoder = intersection(simpleItemConfigDecoder, moveConfigDecoder); + object({ + id: nonEmptyStringDecoder, + type: subParentDecoder + }); + const addWindowConfigDecoder = object({ + definition: swimlaneWindowDefinitionDecoder, + parentId: nonEmptyStringDecoder, + parentType: allParentDecoder + }); + const addContainerConfigDecoder = object({ + definition: strictParentDefinitionDecoder, + parentId: nonEmptyStringDecoder, + parentType: allParentDecoder + }); + const addItemResultDecoder = object({ + itemId: nonEmptyStringDecoder, + windowId: optional(nonEmptyStringDecoder) + }); + const pingResultDecoder = object({ + live: boolean() + }); + const bundleWorkspaceConfigDecoder = object({ + type: oneOf(constant("row"), constant("column")), + workspaceId: nonEmptyStringDecoder + }); + const bundleItemConfigDecoder = object({ + type: oneOf(constant("row"), constant("column")), + itemId: nonEmptyStringDecoder + }); + const containerSummaryResultDecoder = object({ + itemId: nonEmptyStringDecoder, + config: parentSnapshotConfigDecoder + }); + const frameStreamDataDecoder = object({ + frameSummary: frameSummaryDecoder, + frameBounds: optional(frameBoundsDecoder) + }); + const workspaceStreamDataDecoder = object({ + workspaceSummary: workspaceSummaryResultDecoder, + frameSummary: frameSummaryDecoder, + workspaceSnapshot: optional(workspaceSnapshotResultDecoder), + frameBounds: optional(frameBoundsDecoder) + }); + const containerStreamDataDecoder = object({ + containerSummary: containerSummaryResultDecoder + }); + const windowStreamDataDecoder = object({ + windowSummary: object({ + itemId: nonEmptyStringDecoder, + parentId: nonEmptyStringDecoder, + config: swimlaneWindowSnapshotConfigDecoder + }) + }); + const workspaceLayoutSaveConfigDecoder = object({ + name: nonEmptyStringDecoder, + workspaceId: nonEmptyStringDecoder, + saveContext: optional(boolean()), + allowMultiple: optional(boolean()), + metadata: optional(object()) + }); + const workspaceLockConfigDecoder = object({ + allowDrop: optional(boolean()), + allowDropLeft: optional(boolean()), + allowDropTop: optional(boolean()), + allowDropRight: optional(boolean()), + allowDropBottom: optional(boolean()), + allowSystemHibernation: optional(boolean()), + allowExtract: optional(boolean()), + allowWindowReorder: optional(boolean()), + allowSplitters: optional(boolean()), + showCloseButton: optional(boolean()), + showSaveButton: optional(boolean()), + allowWorkspaceTabReorder: optional(boolean()), + allowWorkspaceTabExtract: optional(boolean()), + showWindowCloseButtons: optional(boolean()), + showAddWindowButtons: optional(boolean()), + showEjectButtons: optional(boolean()), + }); + const lockWorkspaceDecoder = object({ + workspaceId: nonEmptyStringDecoder, + config: optional(workspaceLockConfigDecoder) + }); + const windowLockConfigDecoder = object({ + allowExtract: optional(boolean()), + allowReorder: optional(boolean()), + showCloseButton: optional(boolean()) + }); + const elementResizeConfigDecoder = object({ + width: optional(nonNegativeNumberDecoder), + height: optional(nonNegativeNumberDecoder) + }); + const lockWindowDecoder = object({ + windowPlacementId: nonEmptyStringDecoder, + config: optional(windowLockConfigDecoder) + }); + const rowLockConfigDecoder = object({ + allowDrop: optional(boolean()), + allowSplitters: optional(boolean()), + }); + const columnLockConfigDecoder = object({ + allowDrop: optional(boolean()), + allowSplitters: optional(boolean()), + }); + const groupLockConfigDecoder = object({ + allowExtract: optional(boolean()), + allowReorder: optional(boolean()), + allowDrop: optional(boolean()), + allowDropLeft: optional(boolean()), + allowDropRight: optional(boolean()), + allowDropTop: optional(boolean()), + allowDropBottom: optional(boolean()), + allowDropHeader: optional(boolean()), + showMaximizeButton: optional(boolean()), + showEjectButton: optional(boolean()), + showAddWindowButton: optional(boolean()), + }); + const lockRowDecoder = object({ + itemId: nonEmptyStringDecoder, + type: constant("row"), + config: optional(rowLockConfigDecoder) + }); + const lockColumnDecoder = object({ + itemId: nonEmptyStringDecoder, + type: constant("column"), + config: optional(columnLockConfigDecoder) + }); + const lockGroupDecoder = object({ + itemId: nonEmptyStringDecoder, + type: constant("group"), + config: optional(groupLockConfigDecoder) + }); + const lockContainerDecoder = oneOf(lockRowDecoder, lockColumnDecoder, lockGroupDecoder); + const pinWorkspaceDecoder = object({ + workspaceId: nonEmptyStringDecoder, + icon: optional(nonEmptyStringDecoder) + }); + const setWorkspaceIconDecoder = object({ + workspaceId: nonEmptyStringDecoder, + icon: optional(nonEmptyStringDecoder) + }); + const workspacePinOptionsDecoder = optional(object({ + icon: optional(nonEmptyStringDecoder) + })); + const shortcutConfigDecoder = object({ + shortcut: nonEmptyStringDecoder, + frameId: nonEmptyStringDecoder + }); + const shortcutClickedDataDecoder = object({ + shortcut: nonEmptyStringDecoder, + frameId: nonEmptyStringDecoder + }); + const setMaximizationBoundaryAPIConfigDecoder = object({ + enabled: boolean() + }); + const loadingAnimationConfigDecoder = object({ + itemId: nonEmptyStringDecoder, + type: loadingAnimationTypeDecoder + }); + const operationCheckConfigDecoder = object({ + operation: nonEmptyStringDecoder + }); + const setWindowDragModeDecoder = object({ + itemId: nonEmptyStringDecoder, + dragMode: windowDragModeDecoder + }); + const setLoadingStrategyDecoder = object({ + itemId: nonEmptyStringDecoder, + strategy: loadingStrategyDecoder + }); + + const webPlatformMethodName = "T42.Web.Platform.Control"; + const webPlatformWspStreamName = "T42.Web.Platform.WSP.Stream"; + const OUTGOING_METHODS = { + control: { name: "T42.Workspaces.Control", isStream: false }, + frameStream: { name: "T42.Workspaces.Stream.Frame", isStream: true }, + workspaceStream: { name: "T42.Workspaces.Stream.Workspace", isStream: true }, + containerStream: { name: "T42.Workspaces.Stream.Container", isStream: true }, + windowStream: { name: "T42.Workspaces.Stream.Window", isStream: true } + }; + const INCOMING_METHODS = { + control: { name: "T42.Workspaces.Client.Control", isStream: false }, + }; + const STREAMS = { + frame: { name: "T42.Workspaces.Stream.Frame", payloadDecoder: frameStreamDataDecoder }, + workspace: { name: "T42.Workspaces.Stream.Workspace", payloadDecoder: workspaceStreamDataDecoder }, + container: { name: "T42.Workspaces.Stream.Container", payloadDecoder: containerStreamDataDecoder }, + window: { name: "T42.Workspaces.Stream.Window", payloadDecoder: windowStreamDataDecoder } + }; + const CLIENT_OPERATIONS = { + shortcutClicked: { name: "shortcutClicked", argsDecoder: shortcutClickedDataDecoder, resultDecoder: voidResultDecoder }, + }; + const OPERATIONS = { + ping: { name: "ping", resultDecoder: pingResultDecoder }, + isWindowInWorkspace: { name: "isWindowInWorkspace", argsDecoder: simpleItemConfigDecoder, resultDecoder: isWindowInSwimlaneResultDecoder }, + createWorkspace: { name: "createWorkspace", resultDecoder: workspaceSnapshotResultDecoder, argsDecoder: workspaceCreateConfigDecoder }, + createFrame: { name: "createFrame", resultDecoder: frameSummaryResultDecoder, argsDecoder: emptyFrameDefinitionDecoder }, + initFrame: { name: "initFrame", resultDecoder: voidResultDecoder, argsDecoder: frameInitProtocolConfigDecoder }, + getAllFramesSummaries: { name: "getAllFramesSummaries", resultDecoder: frameSummariesResultDecoder }, + getFrameSummary: { name: "getFrameSummary", resultDecoder: frameSummaryDecoder, argsDecoder: getFrameSummaryConfigDecoder }, + getAllWorkspacesSummaries: { name: "getAllWorkspacesSummaries", resultDecoder: workspaceSummariesResultDecoder }, + getWorkspaceSnapshot: { name: "getWorkspaceSnapshot", resultDecoder: workspaceSnapshotResultDecoder, argsDecoder: simpleItemConfigDecoder }, + getAllLayoutsSummaries: { name: "getAllLayoutsSummaries", resultDecoder: layoutSummariesDecoder }, + openWorkspace: { name: "openWorkspace", argsDecoder: openWorkspaceConfigDecoder, resultDecoder: workspaceSnapshotResultDecoder }, + deleteLayout: { name: "deleteLayout", resultDecoder: voidResultDecoder, argsDecoder: deleteLayoutConfigDecoder }, + saveLayout: { name: "saveLayout", resultDecoder: workspaceLayoutDecoder, argsDecoder: workspaceLayoutSaveConfigDecoder }, + importLayout: { name: "importLayout", resultDecoder: voidResultDecoder, argsDecoder: workspacesImportLayoutDecoder }, + importLayouts: { name: "importLayouts", resultDecoder: voidResultDecoder, argsDecoder: workspacesImportLayoutsDecoder }, + exportAllLayouts: { name: "exportAllLayouts", resultDecoder: exportedLayoutsResultDecoder }, + restoreItem: { name: "restoreItem", argsDecoder: simpleItemConfigDecoder, resultDecoder: voidResultDecoder }, + maximizeItem: { name: "maximizeItem", argsDecoder: simpleItemConfigDecoder, resultDecoder: voidResultDecoder }, + focusItem: { name: "focusItem", argsDecoder: simpleItemConfigDecoder, resultDecoder: voidResultDecoder }, + closeItem: { name: "closeItem", argsDecoder: simpleItemConfigDecoder, resultDecoder: voidResultDecoder }, + resizeItem: { name: "resizeItem", argsDecoder: resizeItemConfigDecoder, resultDecoder: voidResultDecoder }, + setMaximizationBoundary: { name: "setMaximizationBoundary", argsDecoder: setMaximizationBoundaryConfigDecoder, resultDecoder: voidResultDecoder }, + changeFrameState: { name: "changeFrameState", argsDecoder: frameStateConfigDecoder, resultDecoder: voidResultDecoder }, + getFrameState: { name: "getFrameState", argsDecoder: simpleItemConfigDecoder, resultDecoder: frameStateResultDecoder }, + getFrameBounds: { name: "getFrameBounds", argsDecoder: simpleItemConfigDecoder, resultDecoder: frameBoundsResultDecoder }, + moveFrame: { name: "moveFrame", argsDecoder: moveFrameConfigDecoder, resultDecoder: voidResultDecoder }, + getFrameSnapshot: { name: "getFrameSnapshot", argsDecoder: frameSnapshotConfigDecoder, resultDecoder: frameSnapshotResultDecoder }, + forceLoadWindow: { name: "forceLoadWindow", argsDecoder: simpleItemConfigDecoder, resultDecoder: simpleWindowOperationSuccessResultDecoder }, + ejectWindow: { name: "ejectWindow", argsDecoder: simpleItemConfigDecoder, resultDecoder: simpleWindowOperationSuccessResultDecoder }, + setItemTitle: { name: "setItemTitle", argsDecoder: setItemTitleConfigDecoder, resultDecoder: voidResultDecoder }, + moveWindowTo: { name: "moveWindowTo", argsDecoder: moveWindowConfigDecoder, resultDecoder: voidResultDecoder }, + addWindow: { name: "addWindow", argsDecoder: addWindowConfigDecoder, resultDecoder: addItemResultDecoder }, + addContainer: { name: "addContainer", argsDecoder: addContainerConfigDecoder, resultDecoder: addItemResultDecoder }, + bundleWorkspace: { name: "bundleWorkspace", argsDecoder: bundleWorkspaceConfigDecoder, resultDecoder: voidResultDecoder }, + bundleItem: { name: "bundleItem", argsDecoder: bundleItemConfigDecoder, resultDecoder: voidResultDecoder }, + hibernateWorkspace: { name: "hibernateWorkspace", argsDecoder: workspaceSelectorDecoder, resultDecoder: voidResultDecoder }, + resumeWorkspace: { name: "resumeWorkspace", argsDecoder: workspaceSelectorDecoder, resultDecoder: voidResultDecoder }, + lockWorkspace: { name: "lockWorkspace", argsDecoder: lockWorkspaceDecoder, resultDecoder: voidResultDecoder }, + lockWindow: { name: "lockWindow", argsDecoder: lockWindowDecoder, resultDecoder: voidResultDecoder }, + lockContainer: { name: "lockContainer", argsDecoder: lockContainerDecoder, resultDecoder: voidResultDecoder }, + pinWorkspace: { name: "pinWorkspace", argsDecoder: pinWorkspaceDecoder, resultDecoder: voidResultDecoder }, + unpinWorkspace: { name: "unpinWorkspace", argsDecoder: workspaceSelectorDecoder, resultDecoder: voidResultDecoder }, + getWorkspaceIcon: { name: "getWorkspaceIcon", argsDecoder: workspaceSelectorDecoder, resultDecoder: getWorkspaceIconResultDecoder }, + setWorkspaceIcon: { name: "setWorkspaceIcon", argsDecoder: setWorkspaceIconDecoder, resultDecoder: voidResultDecoder }, + registerShortcut: { name: "registerShortcut", argsDecoder: shortcutConfigDecoder, resultDecoder: voidResultDecoder }, + unregisterShortcut: { name: "unregisterShortcut", argsDecoder: shortcutConfigDecoder, resultDecoder: voidResultDecoder }, + showLoadingAnimation: { name: "showLoadingAnimation", argsDecoder: loadingAnimationConfigDecoder, resultDecoder: voidResultDecoder }, + hideLoadingAnimation: { name: "hideLoadingAnimation", argsDecoder: loadingAnimationConfigDecoder, resultDecoder: voidResultDecoder }, + getPlatformFrameId: { name: "getPlatformFrameId", resultDecoder: getPlatformFrameIdResultDecoder }, + operationCheck: { name: "operationCheck", argsDecoder: operationCheckConfigDecoder, resultDecoder: operationCheckResultDecoder }, + setWindowDragMode: { name: "setWindowDragMode", argsDecoder: setWindowDragModeDecoder, resultDecoder: voidResultDecoder }, + setLoadingStrategy: { name: "setLoadingStrategy", argsDecoder: setLoadingStrategyDecoder, resultDecoder: voidResultDecoder } + }; + + class PromiseWrapper { + resolve; + reject; + promise; + constructor() { + this.promise = new Promise((res, rej) => { + this.resolve = res; + this.reject = rej; + }); + } + } + + class Bridge { + transport; + registry; + activeSubscriptions = []; + pendingSubScriptions = []; + constructor(transport, registry) { + this.transport = transport; + this.registry = registry; + } + async createCoreEventSubscription() { + await this.transport.coreSubscriptionReady(this.handleCoreEvent.bind(this)); + } + handleCoreSubscription(config) { + const registryKey = `${config.eventType}-${config.action}`; + const scope = config.scope; + const scopeId = config.scopeId; + return this.registry.add(registryKey, (args) => { + const scopeConfig = { + type: scope, + id: scopeId + }; + const receivedIds = { + frame: args.frameSummary?.id || args.windowSummary?.config.frameId, + workspace: args.workspaceSummary?.id || args.windowSummary?.config.workspaceId, + container: args.containerSummary?.itemId, + window: args.windowSummary?.itemId + }; + const shouldInvokeCallback = this.checkScopeMatch(scopeConfig, receivedIds); + if (!shouldInvokeCallback) { + return; + } + config.callback(args); + }); + } + async send(operationName, operationArgs) { + const operationDefinition = Object.values(OPERATIONS).find((operation) => operation.name === operationName); + if (!operationDefinition) { + throw new Error(`Cannot find definition for operation name: ${operationName}`); + } + if (operationDefinition.argsDecoder) { + try { + operationDefinition.argsDecoder.runWithException(operationArgs); + } + catch (error) { + throw new Error(`Unexpected internal outgoing validation error: ${error.message}, for input: ${JSON.stringify(error.input)}, for operation ${operationName}`); + } + } + try { + const operationResult = await this.transport.transmitControl(operationDefinition.name, operationArgs); + operationDefinition.resultDecoder.runWithException(operationResult); + return operationResult; + } + catch (error) { + if (error.kind) { + throw new Error(`Unexpected internal incoming validation error: ${error.message}, for input: ${JSON.stringify(error.input)}, for operation ${operationName}`); + } + throw new Error(error.message); + } + } + async subscribe(config) { + const pendingSub = this.getPendingSubscription(config); + if (pendingSub) { + await pendingSub.promise; + } + let activeSub = this.getActiveSubscription(config); + const registryKey = this.getRegistryKey(config); + if (!activeSub) { + const pendingPromise = new PromiseWrapper(); + const pendingSubscription = { + streamType: config.eventType, + level: config.scope, + levelId: config.scopeId, + promise: pendingPromise.promise + }; + this.pendingSubScriptions.push(pendingSubscription); + try { + const stream = STREAMS[config.eventType]; + const gdSub = await this.transport.subscribe(stream.name, this.getBranchKey(config), config.eventType); + gdSub.onData((streamData) => { + const data = streamData.data; + const requestedArgumentsResult = streamRequestArgumentsDecoder.run(streamData.requestArguments); + const actionResult = workspaceEventActionDecoder.run(data.action); + if (!requestedArgumentsResult.ok || !actionResult.ok) { + return; + } + const streamType = requestedArgumentsResult.result.type; + const branch = requestedArgumentsResult.result.branch; + const keyToExecute = `${streamType}-${branch}-${actionResult.result}`; + const validatedPayload = STREAMS[streamType].payloadDecoder.run(data.payload); + if (!validatedPayload.ok) { + return; + } + this.registry.execute(keyToExecute, validatedPayload.result); + }); + activeSub = { + streamType: config.eventType, + level: config.scope, + levelId: config.scopeId, + callbacksCount: 0, + gdSub + }; + this.activeSubscriptions.push(activeSub); + pendingPromise.resolve(); + } + catch (error) { + pendingPromise.reject(error); + throw error; + } + finally { + this.removePendingSubscription(pendingSubscription); + } + } + const unsubscribe = this.registry.add(registryKey, config.callback); + ++activeSub.callbacksCount; + return () => { + unsubscribe(); + --activeSub.callbacksCount; + if (activeSub.callbacksCount === 0) { + activeSub.gdSub.close(); + this.activeSubscriptions.splice(this.activeSubscriptions.indexOf(activeSub), 1); + } + }; + } + onOperation(callback) { + const wrappedCallback = (payload, caller) => { + const operationName = payload.operation; + const operationArgs = payload.data; + const operationDefinition = Object.values(CLIENT_OPERATIONS).find((operation) => operation.name === operationName); + if (!operationDefinition) { + throw new Error(`Cannot find definition for operation name: ${operationName}`); + } + if (operationDefinition.argsDecoder) { + try { + operationDefinition.argsDecoder.runWithException(operationArgs); + } + catch (error) { + throw new Error(`Unexpected internal outgoing validation error: ${error.message}, for input: ${JSON.stringify(error.input)}, for operation ${operationName}`); + } + } + callback(payload, caller); + }; + return this.transport.onInternalMethodInvoked("control", wrappedCallback); + } + checkScopeMatch(scope, receivedIds) { + if (scope.type === "global") { + return true; + } + if (scope.type === "frame" && scope.id === receivedIds.frame) { + return true; + } + if (scope.type === "workspace" && scope.id === receivedIds.workspace) { + return true; + } + if (scope.type === "container" && scope.id === receivedIds.container) { + return true; + } + if (scope.type === "window" && scope.id === receivedIds.window) { + return true; + } + return false; + } + handleCoreEvent(args) { + const data = args.data; + try { + const verifiedAction = workspaceEventActionDecoder.runWithException(data.action); + const verifiedType = eventTypeDecoder.runWithException(data.type); + const verifiedPayload = STREAMS[verifiedType].payloadDecoder.runWithException(data.payload); + const registryKey = `${verifiedType}-${verifiedAction}`; + this.registry.execute(registryKey, verifiedPayload); + } + catch (error) { + console.warn(`Cannot handle event with data ${JSON.stringify(data)}, because of validation error: ${error.message}`); + } + } + getBranchKey(config) { + return config.scope === "global" ? config.scope : `${config.scope}_${config.scopeId}`; + } + getRegistryKey(config) { + return `${config.eventType}-${this.getBranchKey(config)}-${config.action}`; + } + getActiveSubscription(config) { + return this.activeSubscriptions + .find((activeSub) => activeSub.streamType === config.eventType && + activeSub.level === config.scope && + activeSub.levelId === config.scopeId); + } + getPendingSubscription(config) { + return this.pendingSubScriptions + .find((activeSub) => activeSub.streamType === config.eventType && + activeSub.level === config.scope && + activeSub.levelId === config.scopeId); + } + removePendingSubscription(pendingSubscription) { + const index = this.pendingSubScriptions.indexOf(pendingSubscription); + if (index >= 0) { + this.pendingSubScriptions.splice(index, 1); + } + } + } + + const promisePlus = (promise, timeoutMilliseconds, timeoutMessage) => { + return new Promise((resolve, reject) => { + let promiseActive = true; + const timeout = setTimeout(() => { + if (!promiseActive) { + return; + } + promiseActive = false; + const message = timeoutMessage; + reject(message); + }, timeoutMilliseconds); + promise() + .then((result) => { + if (!promiseActive) { + return; + } + promiseActive = false; + clearTimeout(timeout); + resolve(result); + }) + .catch((error) => { + if (!promiseActive) { + return; + } + promiseActive = false; + clearTimeout(timeout); + reject(error); + }); + }); + }; + + const isDesktop = () => { + return typeof window === "undefined" ? + true : + window.glue42gd || window.iodesktop; + }; + const browserGlobal = () => { + return typeof window === "undefined" ? null : + window.glue42core || window.iobrowser; + }; + + class InteropTransport { + agm; + registry; + defaultTransportTimeout = 120000; + coreEventMethodInitiated = false; + corePlatformSubPromise; + constructor(agm, registry) { + this.agm = agm; + this.registry = registry; + } + async initiate(actualWindowId) { + if (isDesktop()) { + await Promise.all(Object.values(OUTGOING_METHODS).map((method) => { + return this.verifyMethodLive(method.name); + })); + await Promise.all(Object.keys(INCOMING_METHODS).map((method) => { + return this.registerMethod(method); + })); + return; + } + const systemId = browserGlobal().communicationId; + await Promise.all([ + this.verifyMethodLive(webPlatformMethodName, systemId), + this.verifyMethodLive(webPlatformWspStreamName, systemId) + ]); + await this.transmitControl("frameHello", { windowId: actualWindowId }); + } + coreSubscriptionReady(eventCallback) { + if (!this.coreEventMethodInitiated) { + this.subscribePlatform(eventCallback); + } + return this.corePlatformSubPromise; + } + subscribePlatform(eventCallback) { + this.coreEventMethodInitiated = true; + const systemId = browserGlobal().communicationId; + this.corePlatformSubPromise = this.agm.subscribe(webPlatformWspStreamName, systemId ? { target: { instance: systemId } } : undefined); + this.corePlatformSubPromise + .then((sub) => { + sub.onData((data) => eventCallback(data.data)); + }); + } + async subscribe(streamName, streamBranch, streamType) { + const subscriptionArgs = { + branch: streamBranch, + type: streamType + }; + let subscription; + try { + subscription = await this.agm.subscribe(streamName, { arguments: subscriptionArgs }); + } + catch (error) { + const message = `Internal subscription error! Error details: stream - ${streamName}, branch: ${streamBranch}. Internal message: ${error.message}`; + throw new Error(message); + } + return subscription; + } + async transmitControl(operation, operationArguments) { + const invocationArguments = isDesktop() ? { operation, operationArguments } : { operation, domain: "workspaces", data: operationArguments }; + const methodName = isDesktop() ? OUTGOING_METHODS.control.name : webPlatformMethodName; + const platformTarget = isDesktop() ? undefined : browserGlobal().communicationId; + let invocationResult; + const baseErrorMessage = `Internal Workspaces Communication Error. Attempted operation: ${JSON.stringify(invocationArguments)}. `; + try { + invocationResult = await this.agm.invoke(methodName, invocationArguments, platformTarget ? { instance: platformTarget } : "best", { methodResponseTimeoutMs: this.defaultTransportTimeout }); + if (!invocationResult) { + throw new Error("Received unsupported result from GD - empty result"); + } + if (!Array.isArray(invocationResult.all_return_values) || invocationResult.all_return_values.length === 0) { + throw new Error("Received unsupported result from GD - empty values collection"); + } + } + catch (error) { + if (error && error.all_errors && error.all_errors.length) { + const invocationErrorMessage = error.all_errors[0].message; + throw new Error(`${baseErrorMessage} -> Inner message: ${invocationErrorMessage}`); + } + throw new Error(`${baseErrorMessage} -> Inner message: ${error.message}`); + } + return invocationResult.all_return_values[0].returned; + } + onInternalMethodInvoked(key, callback) { + return this.registry.add(key, callback); + } + verifyMethodLive(name, systemId) { + return promisePlus(() => { + return new Promise((resolve) => { + const hasMethod = this.agm.methods().some((method) => { + const nameMatch = method.name === name; + const serverMatch = systemId ? + method.getServers().some((server) => server.instance === systemId) : + true; + return nameMatch && serverMatch; + }); + if (hasMethod) { + resolve(); + return; + } + const unSub = this.agm.serverMethodAdded((data) => { + const method = data.method; + const server = data.server; + const serverMatch = systemId ? + server.instance === systemId : + true; + if (method.name === name && serverMatch) { + unSub(); + resolve(); + } + }); + }); + }, 15000, "Timeout waiting for the Workspaces communication channels"); + } + registerMethod(key) { + const method = INCOMING_METHODS[key]; + return this.agm.register(method.name, (args, caller) => { + this.registry.execute(key, args, caller); + }); + } + } + + const privateData$4 = new WeakMap(); + class ParentBuilder { + constructor(definition, base) { + const children = base.wrapChildren(definition.children); + delete definition.children; + privateData$4.set(this, { base, children, definition }); + } + get type() { + return privateData$4.get(this).definition.type; + } + addColumn(definition) { + const base = privateData$4.get(this).base; + return base.add("column", privateData$4.get(this).children, definition); + } + addRow(definition) { + const base = privateData$4.get(this).base; + return base.add("row", privateData$4.get(this).children, definition); + } + addGroup(definition) { + const base = privateData$4.get(this).base; + return base.add("group", privateData$4.get(this).children, definition); + } + addWindow(definition) { + const base = privateData$4.get(this).base; + base.addWindow(privateData$4.get(this).children, definition); + return this; + } + serialize() { + const definition = privateData$4.get(this).definition; + definition.children = privateData$4.get(this).base.serializeChildren(privateData$4.get(this).children); + return definition; + } + } + + class BaseBuilder { + getBuilder; + constructor(getBuilder) { + this.getBuilder = getBuilder; + } + wrapChildren(children) { + return children.map((child) => { + if (child.type === "window") { + return child; + } + return this.getBuilder({ type: child.type, definition: child }); + }); + } + add(type, children, definition) { + const validatedDefinition = parentDefinitionDecoder.runWithException(definition); + const childBuilder = this.getBuilder({ type, definition: validatedDefinition }); + children.push(childBuilder); + return childBuilder; + } + addWindow(children, definition) { + const validatedDefinition = swimlaneWindowDefinitionDecoder.runWithException(definition); + validatedDefinition.type = "window"; + children.push(validatedDefinition); + } + serializeChildren(children) { + return children.map((child) => { + if (child instanceof ParentBuilder) { + return child.serialize(); + } + else { + return child; + } + }); + } + } + + const privateData$3 = new WeakMap(); + class WorkspaceBuilder { + constructor(definition, base, controller) { + const children = base.wrapChildren(definition.children); + delete definition.children; + privateData$3.set(this, { base, children, definition, controller }); + } + addColumn(definition) { + const children = privateData$3.get(this).children; + const areAllColumns = children.every((child) => child instanceof ParentBuilder && child.type === "column"); + if (!areAllColumns) { + throw new Error("Cannot add a column to this workspace, because there are already children of another type"); + } + const base = privateData$3.get(this).base; + return base.add("column", children, definition); + } + addRow(definition) { + const children = privateData$3.get(this).children; + const areAllRows = children.every((child) => child instanceof ParentBuilder && child.type === "row"); + if (!areAllRows) { + throw new Error("Cannot add a row to this workspace, because there are already children of another type"); + } + const base = privateData$3.get(this).base; + return base.add("row", children, definition); + } + addGroup(definition) { + const children = privateData$3.get(this).children; + if (children.length !== 0) { + throw new Error("Cannot add a group to this workspace, because there are already defined children."); + } + const base = privateData$3.get(this).base; + return base.add("group", children, definition); + } + addWindow(definition) { + const children = privateData$3.get(this).children; + if (children.length !== 0) { + throw new Error("Cannot add a window to this workspace, because there are already defined children."); + } + const base = privateData$3.get(this).base; + base.addWindow(children, definition); + return this; + } + getChildAt(index) { + nonNegativeNumberDecoder.runWithException(index); + const data = privateData$3.get(this).children; + return data[index]; + } + async create(config) { + const saveConfig = workspaceBuilderCreateConfigDecoder.runWithException(config); + const definition = privateData$3.get(this).definition; + definition.children = privateData$3.get(this).base.serializeChildren(privateData$3.get(this).children); + const controller = privateData$3.get(this).controller; + return controller.createWorkspace(definition, saveConfig); + } + } + + const privateData$2 = new WeakMap(); + const getBase$2 = (model) => { + return privateData$2.get(model).base; + }; + class Row { + constructor(base) { + privateData$2.set(this, { base }); + } + get type() { + return "row"; + } + get id() { + return getBase$2(this).getId(this); + } + get frameId() { + return getBase$2(this).getFrameId(this); + } + get workspaceId() { + return getBase$2(this).getWorkspaceId(this); + } + get positionIndex() { + return getBase$2(this).getPositionIndex(this); + } + get children() { + return getBase$2(this).getAllChildren(this); + } + get parent() { + return getBase$2(this).getMyParent(this); + } + get frame() { + return getBase$2(this).getMyFrame(this); + } + get workspace() { + return getBase$2(this).getMyWorkspace(this); + } + get allowDrop() { + return getBase$2(this).getAllowDrop(this); + } + get allowSplitters() { + return getBase$2(this).getAllowSplitters(this); + } + get minWidth() { + return getBase$2(this).getMinWidth(this); + } + get minHeight() { + return getBase$2(this).getMinHeight(this); + } + get maxWidth() { + return getBase$2(this).getMaxWidth(this); + } + get maxHeight() { + return getBase$2(this).getMaxHeight(this); + } + get width() { + return getBase$2(this).getWidthInPx(this); + } + get height() { + return getBase$2(this).getHeightInPx(this); + } + get isPinned() { + return getBase$2(this).getIsPinned(this); + } + get isMaximized() { + return getBase$2(this).getIsMaximized(this); + } + get maximizationBoundary() { + return getBase$2(this).getMaximizationBoundary(this); + } + addWindow(definition) { + return getBase$2(this).addWindow(this, definition, "row"); + } + async addGroup(definition) { + if (definition?.type && definition.type !== "group") { + throw new Error(`Expected a group definition, but received ${definition.type}`); + } + return getBase$2(this).addParent(this, "group", "row", definition); + } + async addColumn(definition) { + if (definition?.type && definition.type !== "column") { + throw new Error(`Expected a column definition, but received ${definition.type}`); + } + return getBase$2(this).addParent(this, "column", "row", definition); + } + async addRow() { + throw new Error("Adding rows as row children is not supported"); + } + removeChild(predicate) { + return getBase$2(this).removeChild(this, predicate); + } + maximize() { + return getBase$2(this).maximize(this); + } + restore() { + return getBase$2(this).restore(this); + } + close() { + return getBase$2(this).close(this); + } + lock(config) { + let lockConfigResult = undefined; + if (typeof config === "function") { + const currentLockConfig = { + allowDrop: this.allowDrop, + allowSplitters: this.allowSplitters + }; + lockConfigResult = config(currentLockConfig); + } + else { + lockConfigResult = config; + } + const verifiedConfig = lockConfigResult === undefined ? undefined : rowLockConfigDecoder.runWithException(lockConfigResult); + return getBase$2(this).lockContainer(this, verifiedConfig); + } + async setHeight(height) { + nonNegativeNumberDecoder.runWithException(height); + return getBase$2(this).setHeight(this, height); + } + async onLockConfigurationChanged(callback) { + checkThrowCallback(callback); + const wrappedCallback = async () => { + await this.workspace.refreshReference(); + callback({ + allowDrop: this.allowDrop, + allowSplitters: this.allowSplitters + }); + }; + const config = { + callback: wrappedCallback, + action: "lock-configuration-changed", + eventType: "container", + scope: "container" + }; + const unsubscribe = await getBase$2(this).processLocalSubscription(this, config); + return unsubscribe; + } + async setMaximizationBoundary(config) { + const validatedConfig = setMaximizationBoundaryAPIConfigDecoder.runWithException(config); + return getBase$2(this).setMaximizationBoundary(this, validatedConfig); + } + } + + const privateData$1 = new WeakMap(); + const getBase$1 = (model) => { + return privateData$1.get(model).base; + }; + class Column { + constructor(base) { + privateData$1.set(this, { base }); + } + get type() { + return "column"; + } + get id() { + return getBase$1(this).getId(this); + } + get frameId() { + return getBase$1(this).getFrameId(this); + } + get workspaceId() { + return getBase$1(this).getWorkspaceId(this); + } + get positionIndex() { + return getBase$1(this).getPositionIndex(this); + } + get children() { + return getBase$1(this).getAllChildren(this); + } + get parent() { + return getBase$1(this).getMyParent(this); + } + get frame() { + return getBase$1(this).getMyFrame(this); + } + get workspace() { + return getBase$1(this).getMyWorkspace(this); + } + get allowDrop() { + return getBase$1(this).getAllowDrop(this); + } + get allowSplitters() { + return getBase$1(this).getAllowSplitters(this); + } + get minWidth() { + return getBase$1(this).getMinWidth(this); + } + get minHeight() { + return getBase$1(this).getMinHeight(this); + } + get maxWidth() { + return getBase$1(this).getMaxWidth(this); + } + get maxHeight() { + return getBase$1(this).getMaxHeight(this); + } + get width() { + return getBase$1(this).getWidthInPx(this); + } + get height() { + return getBase$1(this).getHeightInPx(this); + } + get isPinned() { + return getBase$1(this).getIsPinned(this); + } + get isMaximized() { + return getBase$1(this).getIsMaximized(this); + } + get maximizationBoundary() { + return getBase$1(this).getMaximizationBoundary(this); + } + addWindow(definition) { + return getBase$1(this).addWindow(this, definition, "column"); + } + async addGroup(definition) { + if (definition?.type && definition.type !== "group") { + throw new Error(`Expected a group definition, but received ${definition.type}`); + } + return getBase$1(this).addParent(this, "group", "column", definition); + } + async addColumn() { + throw new Error("Adding columns as column children is not supported"); + } + async addRow(definition) { + if (definition?.type && definition.type !== "row") { + throw new Error(`Expected a row definition, but received ${definition.type}`); + } + return getBase$1(this).addParent(this, "row", "column", definition); + } + removeChild(predicate) { + return getBase$1(this).removeChild(this, predicate); + } + maximize() { + return getBase$1(this).maximize(this); + } + restore() { + return getBase$1(this).restore(this); + } + close() { + return getBase$1(this).close(this); + } + lock(config) { + let lockConfigResult = undefined; + if (typeof config === "function") { + const currentLockConfig = { + allowDrop: this.allowDrop, + allowSplitters: this.allowSplitters + }; + lockConfigResult = config(currentLockConfig); + } + else { + lockConfigResult = config; + } + const verifiedConfig = lockConfigResult === undefined ? undefined : columnLockConfigDecoder.runWithException(lockConfigResult); + return getBase$1(this).lockContainer(this, verifiedConfig); + } + async setWidth(width) { + nonNegativeNumberDecoder.runWithException(width); + return getBase$1(this).setWidth(this, width); + } + async onLockConfigurationChanged(callback) { + checkThrowCallback(callback); + const wrappedCallback = async () => { + await this.workspace.refreshReference(); + callback({ + allowDrop: this.allowDrop, + allowSplitters: this.allowSplitters + }); + }; + const config = { + callback: wrappedCallback, + action: "lock-configuration-changed", + eventType: "container", + scope: "container" + }; + const unsubscribe = await getBase$1(this).processLocalSubscription(this, config); + return unsubscribe; + } + async setMaximizationBoundary(config) { + const validatedConfig = setMaximizationBoundaryAPIConfigDecoder.runWithException(config); + return getBase$1(this).setMaximizationBoundary(this, validatedConfig); + } + } + + const privateData = new WeakMap(); + const getBase = (model) => { + return privateData.get(model).base; + }; + class Group { + constructor(base) { + privateData.set(this, { base }); + } + get type() { + return "group"; + } + get id() { + return getBase(this).getId(this); + } + get frameId() { + return getBase(this).getFrameId(this); + } + get workspaceId() { + return getBase(this).getWorkspaceId(this); + } + get positionIndex() { + return getBase(this).getPositionIndex(this); + } + get children() { + return getBase(this).getAllChildren(this); + } + get parent() { + return getBase(this).getMyParent(this); + } + get frame() { + return getBase(this).getMyFrame(this); + } + get workspace() { + return getBase(this).getMyWorkspace(this); + } + get allowExtract() { + return getBase(this).getAllowExtract(this); + } + get allowReorder() { + return getBase(this).getAllowReorder(this); + } + get allowDropLeft() { + return getBase(this).getAllowDropLeft(this); + } + get allowDropRight() { + return getBase(this).getAllowDropRight(this); + } + get allowDropTop() { + return getBase(this).getAllowDropTop(this); + } + get allowDropBottom() { + return getBase(this).getAllowDropBottom(this); + } + get allowDropHeader() { + return getBase(this).getAllowDropHeader(this); + } + get allowDrop() { + return getBase(this).getAllowDrop(this); + } + get showMaximizeButton() { + return getBase(this).getShowMaximizeButton(this); + } + get showEjectButton() { + return getBase(this).getShowEjectButton(this); + } + get showAddWindowButton() { + return getBase(this).getShowAddWindowButton(this); + } + get minWidth() { + return getBase(this).getMinWidth(this); + } + get minHeight() { + return getBase(this).getMinHeight(this); + } + get maxWidth() { + return getBase(this).getMaxWidth(this); + } + get maxHeight() { + return getBase(this).getMaxHeight(this); + } + get width() { + return getBase(this).getWidthInPx(this); + } + get height() { + return getBase(this).getHeightInPx(this); + } + get isMaximized() { + return getBase(this).getIsMaximized(this); + } + addWindow(definition) { + return getBase(this).addWindow(this, definition, "group"); + } + async addGroup() { + throw new Error("Adding groups as group child is not supported"); + } + async addColumn() { + throw new Error("Adding columns as group child is not supported"); + } + async addRow() { + throw new Error("Adding rows as group child is not supported"); + } + removeChild(predicate) { + return getBase(this).removeChild(this, predicate); + } + maximize() { + return getBase(this).maximize(this); + } + restore() { + return getBase(this).restore(this); + } + close() { + return getBase(this).close(this); + } + lock(config) { + let lockConfigResult = undefined; + if (typeof config === "function") { + const currentLockConfig = { + allowDrop: this.allowDrop, + allowDropHeader: this.allowDropHeader, + allowDropLeft: this.allowDropLeft, + allowDropRight: this.allowDropRight, + allowDropTop: this.allowDropTop, + allowDropBottom: this.allowDropBottom, + allowExtract: this.allowExtract, + allowReorder: this.allowReorder, + showAddWindowButton: this.showAddWindowButton, + showEjectButton: this.showEjectButton, + showMaximizeButton: this.showMaximizeButton + }; + lockConfigResult = config(currentLockConfig); + } + else { + lockConfigResult = config; + } + const verifiedConfig = lockConfigResult === undefined ? undefined : groupLockConfigDecoder.runWithException(lockConfigResult); + return getBase(this).lockContainer(this, verifiedConfig); + } + async setSize(config) { + const verifiedConfig = elementResizeConfigDecoder.runWithException(config); + if (!verifiedConfig.width && !verifiedConfig.height) { + throw new Error("Expected either width or height to be passed."); + } + return getBase(this).setSize(this, config.width, config.height); + } + async bundleToRow() { + await getBase(this).bundleTo(this, "row"); + await this.workspace.refreshReference(); + } + async bundleToColumn() { + await getBase(this).bundleTo(this, "column"); + await this.workspace.refreshReference(); + } + async onLockConfigurationChanged(callback) { + checkThrowCallback(callback); + const wrappedCallback = async () => { + await this.workspace.refreshReference(); + callback({ + allowDrop: this.allowDrop, + allowDropHeader: this.allowDropHeader, + allowDropLeft: this.allowDropLeft, + allowDropTop: this.allowDropTop, + allowDropRight: this.allowDropRight, + allowDropBottom: this.allowDropBottom, + allowExtract: this.allowExtract, + allowReorder: this.allowReorder, + showAddWindowButton: this.showAddWindowButton, + showEjectButton: this.showEjectButton, + showMaximizeButton: this.showMaximizeButton + }); + }; + const config = { + callback: wrappedCallback, + action: "lock-configuration-changed", + eventType: "container", + scope: "container" + }; + const unsubscribe = await getBase(this).processLocalSubscription(this, config); + return unsubscribe; + } + } + + const DEFAULT_WINDOW_DRAG_MODE = "keepInside"; + + const data$3 = new WeakMap(); + const getData$3 = (model) => { + return data$3.get(model).manager.getWorkspaceData(model); + }; + const getDataManager = (model) => { + return data$3.get(model).manager; + }; + class Workspace { + constructor(dataManager) { + data$3.set(this, { manager: dataManager }); + } + get id() { + return getData$3(this).id; + } + get frameId() { + return getData$3(this).config.frameId; + } + get positionIndex() { + return getData$3(this).config.positionIndex; + } + get title() { + return getData$3(this).config.title; + } + get layoutName() { + return getData$3(this).config.layoutName; + } + get isHibernated() { + return getData$3(this).config.isHibernated; + } + get isSelected() { + return getData$3(this).config.isSelected; + } + get children() { + return getData$3(this).children; + } + get frame() { + return getData$3(this).frame; + } + get allowSplitters() { + return getData$3(this).config.allowSplitters; + } + get allowSystemHibernation() { + return getData$3(this).config.allowSystemHibernation; + } + get allowDrop() { + return getData$3(this).config.allowDrop; + } + get allowDropLeft() { + return getData$3(this).config.allowDropLeft; + } + get allowDropTop() { + return getData$3(this).config.allowDropTop; + } + get allowDropRight() { + return getData$3(this).config.allowDropRight; + } + get allowDropBottom() { + return getData$3(this).config.allowDropBottom; + } + get allowExtract() { + return getData$3(this).config.allowExtract; + } + get allowWindowReorder() { + return getData$3(this).config.allowWindowReorder; + } + get showCloseButton() { + return getData$3(this).config.showCloseButton; + } + get showSaveButton() { + return getData$3(this).config.showSaveButton; + } + get allowWorkspaceTabReorder() { + return getData$3(this).config.allowWorkspaceTabReorder; + } + get allowWorkspaceTabExtract() { + return getData$3(this).config.allowWorkspaceTabExtract; + } + get minWidth() { + return getData$3(this).config.minWidth; + } + get minHeight() { + return getData$3(this).config.minHeight; + } + get maxWidth() { + return getData$3(this).config.maxWidth; + } + get maxHeight() { + return getData$3(this).config.maxHeight; + } + get width() { + return getData$3(this).config.widthInPx; + } + get height() { + return getData$3(this).config.heightInPx; + } + get showWindowCloseButtons() { + return getData$3(this).config.showWindowCloseButtons; + } + get showEjectButtons() { + return getData$3(this).config.showEjectButtons; + } + get showAddWindowButtons() { + return getData$3(this).config.showAddWindowButtons; + } + get isPinned() { + return getData$3(this).config.isPinned; + } + get windowDragMode() { + const desktopGlobal = isDesktop(); + if (!desktopGlobal) { + return DEFAULT_WINDOW_DRAG_MODE; + } + return getData$3(this).config.windowDragMode; + } + get loadingStrategy() { + if (!isDesktop()) { + console.warn("The workspace.loadingStrategy property is not supported in IO Connect Browser"); + } + return getData$3(this).config.loadingStrategy; + } + async setLoadingStrategy(strategy) { + if (!isDesktop()) { + throw new Error("Not supported in IO Connect Browser"); + } + const controller = getData$3(this).controller; + await controller.setLoadingStrategy(this.id, strategy); + await this.refreshReference(); + } + async removeChild(predicate) { + checkThrowCallback(predicate); + const child = this.children.find(predicate); + if (!child) { + return; + } + await child.close(); + await this.refreshReference(); + } + async remove(predicate) { + checkThrowCallback(predicate); + const controller = getData$3(this).controller; + const child = controller.iterateFindChild(this.children, predicate); + await child.close(); + await this.refreshReference(); + } + async focus() { + await getData$3(this).controller.focusItem(this.id); + await this.refreshReference(); + } + async close() { + const controller = getData$3(this).controller; + const workspaces = await getData$3(this).frame.workspaces(); + const platformFrameId = (await controller.getPlatformFrameId()).id; + const shouldCloseFrame = workspaces.length === 1 && + workspaces.every((wsp) => wsp.id === this.id) && + platformFrameId !== this.frame.id; + if (shouldCloseFrame) { + return this.frame.close(); + } + await controller.closeItem(this.id); + } + snapshot() { + return getData$3(this).controller.getSnapshot(this.id, "workspace"); + } + async saveLayout(name, config) { + nonEmptyStringDecoder.runWithException(name); + await getData$3(this).controller.saveLayout({ name, workspaceId: this.id, saveContext: config?.saveContext, metadata: config?.metadata, allowMultiple: config?.allowMultiple }); + } + async setTitle(title) { + nonEmptyStringDecoder.runWithException(title); + const controller = getData$3(this).controller; + await controller.setItemTitle(this.id, title); + await this.refreshReference(); + } + getContext() { + const controller = getData$3(this).controller; + return controller.getWorkspaceContext(this.id); + } + setContext(data) { + const controller = getData$3(this).controller; + return controller.setWorkspaceContext(this.id, data); + } + updateContext(data) { + const controller = getData$3(this).controller; + return controller.updateWorkspaceContext(this.id, data); + } + onContextUpdated(callback) { + const controller = getData$3(this).controller; + return controller.subscribeWorkspaceContextUpdated(this.id, callback); + } + async refreshReference() { + const newSnapshot = (await getData$3(this).controller.getSnapshot(this.id, "workspace")); + const currentChildrenFlat = getData$3(this).controller.flatChildren(getData$3(this).children); + const newChildren = getData$3(this).controller.refreshChildren({ + existingChildren: currentChildrenFlat, + workspace: this, + parent: this, + children: newSnapshot.children + }); + const currentFrame = this.frame; + let actualFrame; + if (currentFrame.id === newSnapshot.config.frameId) { + getDataManager(this).remapFrame(currentFrame, newSnapshot.frameSummary); + actualFrame = currentFrame; + } + else { + const frameCreateConfig = { + summary: newSnapshot.frameSummary + }; + const newFrame = getData$3(this).ioc.getModel("frame", frameCreateConfig); + actualFrame = newFrame; + } + getDataManager(this).remapWorkspace(this, { + config: newSnapshot.config, + children: newChildren, + frame: actualFrame + }); + } + async getIcon() { + const controller = getData$3(this).controller; + return controller.getWorkspaceIcon(this.id); + } + async setIcon(icon) { + const controller = getData$3(this).controller; + return controller.setWorkspaceIcon(this.id, icon); + } + getBox(predicate) { + checkThrowCallback(predicate); + const children = getData$3(this).children; + const controller = getData$3(this).controller; + return controller.iterateFindChild(children, (child) => child.type !== "window" && predicate(child)); + } + getAllBoxes(predicate) { + checkThrowCallback(predicate, true); + const children = getData$3(this).children; + const controller = getData$3(this).controller; + const allParents = controller.iterateFilterChildren(children, (child) => child.type !== "window"); + if (!predicate) { + return allParents; + } + return allParents.filter(predicate); + } + getRow(predicate) { + checkThrowCallback(predicate); + return this.getBox((parent) => parent.type === "row" && predicate(parent)); + } + getAllRows(predicate) { + checkThrowCallback(predicate, true); + if (predicate) { + return this.getAllBoxes((parent) => parent.type === "row" && predicate(parent)); + } + return this.getAllBoxes((parent) => parent.type === "row"); + } + getColumn(predicate) { + checkThrowCallback(predicate); + return this.getBox((parent) => parent.type === "column" && predicate(parent)); + } + getAllColumns(predicate) { + checkThrowCallback(predicate, true); + if (predicate) { + return this.getAllBoxes((parent) => parent.type === "column" && predicate(parent)); + } + return this.getAllBoxes((parent) => parent.type === "column"); + } + getGroup(predicate) { + checkThrowCallback(predicate); + return this.getBox((parent) => parent.type === "group" && predicate(parent)); + } + getAllGroups(predicate) { + checkThrowCallback(predicate, true); + if (predicate) { + return this.getAllBoxes((parent) => parent.type === "group" && predicate(parent)); + } + return this.getAllBoxes((parent) => parent.type === "group"); + } + getWindow(predicate) { + checkThrowCallback(predicate); + const children = getData$3(this).children; + const controller = getData$3(this).controller; + return controller.iterateFindChild(children, (child) => child.type === "window" && predicate(child)); + } + getAllWindows(predicate) { + checkThrowCallback(predicate, true); + const children = getData$3(this).children; + const controller = getData$3(this).controller; + const allWindows = controller.iterateFilterChildren(children, (child) => child.type === "window"); + if (!predicate) { + return allWindows; + } + return allWindows.filter(predicate); + } + addRow(definition) { + return getData$3(this).base.addParent(this, "row", "workspace", definition); + } + addColumn(definition) { + return getData$3(this).base.addParent(this, "column", "workspace", definition); + } + addGroup(definition) { + return getData$3(this).base.addParent(this, "group", "workspace", definition); + } + addWindow(definition) { + return getData$3(this).base.addWindow(this, definition, "workspace"); + } + async bundleToRow() { + await getData$3(this).controller.bundleWorkspaceTo("row", this.id); + await this.refreshReference(); + } + async bundleToColumn() { + await getData$3(this).controller.bundleWorkspaceTo("column", this.id); + await this.refreshReference(); + } + async hibernate() { + await getData$3(this).controller.hibernateWorkspace(this.id); + await this.refreshReference(); + } + async resume() { + await getData$3(this).controller.resumeWorkspace(this.id); + await this.refreshReference(); + } + async lock(config) { + let lockConfigResult = undefined; + if (typeof config === "function") { + const currentLockConfig = { + allowDrop: this.allowDrop, + allowDropLeft: this.allowDropLeft, + allowDropTop: this.allowDropTop, + allowDropRight: this.allowDropRight, + allowDropBottom: this.allowDropBottom, + allowSystemHibernation: this.allowSystemHibernation, + allowExtract: this.allowExtract, + allowWindowReorder: this.allowWindowReorder, + allowSplitters: this.allowSplitters, + showCloseButton: this.showCloseButton, + showSaveButton: this.showSaveButton, + allowWorkspaceTabReorder: this.allowWorkspaceTabReorder, + allowWorkspaceTabExtract: this.allowWorkspaceTabExtract, + showAddWindowButtons: this.showAddWindowButtons, + showEjectButtons: this.showEjectButtons, + showWindowCloseButtons: this.showWindowCloseButtons + }; + lockConfigResult = config(currentLockConfig); + } + else { + lockConfigResult = config; + } + const verifiedConfig = lockConfigResult === undefined ? undefined : workspaceLockConfigDecoder.runWithException(lockConfigResult); + await getData$3(this).controller.lockWorkspace(this.id, verifiedConfig); + await this.refreshReference(); + } + async pin(options) { + workspacePinOptionsDecoder.runWithException(options); + await getData$3(this).controller.pinWorkspace(this.id, options?.icon); + await this.refreshReference(); + } + async unpin() { + await getData$3(this).controller.unpinWorkspace(this.id); + await this.refreshReference(); + } + async showLoadingAnimation() { + if (!isDesktop()) { + throw new Error("Not supported in IO Connect Browser"); + } + await getData$3(this).controller.showWorkspaceLoadingAnimation(this.id); + } + async hideLoadingAnimation() { + if (!isDesktop()) { + throw new Error("Not supported in IO Connect Browser"); + } + await getData$3(this).controller.hideWorkspaceLoadingAnimation(this.id); + } + async setWindowDragMode(mode) { + const desktopGlobal = isDesktop(); + if (!desktopGlobal) { + throw new Error("Not supported in IO Connect Browser"); + } + windowDragModeDecoder.runWithException(mode); + await getData$3(this).controller.setWindowDragMode(this.id, mode); + await this.refreshReference(); + } + async onClosed(callback) { + checkThrowCallback(callback); + const id = getData$3(this).id; + const wrappedCallback = async (payload) => { + callback({ frameId: payload.frameSummary.id, workspaceId: payload.workspaceSummary.id, frameBounds: payload.frameBounds }); + }; + const config = { + action: "closed", + eventType: "workspace", + scope: "workspace", + scopeId: id, + callback: wrappedCallback + }; + const unsubscribe = await getData$3(this).controller.processLocalSubscription(config, id); + return unsubscribe; + } + async onHibernated(callback) { + checkThrowCallback(callback); + const id = getData$3(this).id; + const wrappedCallback = async () => { + await this.refreshReference(); + callback(); + }; + const config = { + action: "hibernated", + eventType: "workspace", + scope: "workspace", + scopeId: id, + callback: wrappedCallback + }; + const unsubscribe = await getData$3(this).controller.processLocalSubscription(config, id); + return unsubscribe; + } + async onResumed(callback) { + checkThrowCallback(callback); + const id = getData$3(this).id; + const wrappedCallback = async () => { + await this.refreshReference(); + callback(); + }; + const config = { + action: "resumed", + eventType: "workspace", + scope: "workspace", + scopeId: id, + callback: wrappedCallback + }; + const unsubscribe = await getData$3(this).controller.processLocalSubscription(config, id); + return unsubscribe; + } + async onWindowAdded(callback) { + checkThrowCallback(callback); + const id = getData$3(this).id; + const wrappedCallback = async (payload) => { + await this.refreshReference(); + const windowParent = this.getBox((parent) => parent.id === payload.windowSummary.parentId); + const foundWindow = windowParent.children.find((child) => { + return child.type === "window" && child.elementId === payload.windowSummary.itemId; + }); + callback(foundWindow); + }; + const config = { + action: "added", + eventType: "window", + scope: "workspace", + scopeId: id, + callback: wrappedCallback + }; + const unsubscribe = await getData$3(this).controller.processLocalSubscription(config, id); + return unsubscribe; + } + async onWindowRemoved(callback) { + checkThrowCallback(callback); + const id = getData$3(this).id; + const wrappedCallback = async (payload) => { + await this.refreshReference(); + const { windowId, workspaceId, frameId } = payload.windowSummary.config; + callback({ windowId, workspaceId, frameId }); + }; + const config = { + action: "removed", + eventType: "window", + scope: "workspace", + scopeId: id, + callback: wrappedCallback + }; + const unsubscribe = await getData$3(this).controller.processLocalSubscription(config, id); + return unsubscribe; + } + async onWindowLoaded(callback) { + checkThrowCallback(callback); + const id = getData$3(this).id; + const wrappedCallback = async (payload) => { + await this.refreshReference(); + const foundWindow = this.getWindow((win) => { + return win.id && win.id === payload.windowSummary.config.windowId; + }); + callback(foundWindow); + }; + const config = { + action: "loaded", + eventType: "window", + scope: "workspace", + scopeId: id, + callback: wrappedCallback + }; + const unsubscribe = await getData$3(this).controller.processLocalSubscription(config, id); + return unsubscribe; + } + async onWindowMaximized(callback) { + checkThrowCallback(callback); + const id = getData$3(this).id; + const wrappedCallback = async (payload) => { + await this.refreshReference(); + const windowParent = this.getBox((parent) => parent.id === payload.windowSummary.parentId); + const foundWindow = windowParent.children.find((child) => { + return child.type === "window" && child.elementId === payload.windowSummary.itemId; + }); + callback(foundWindow); + }; + const config = { + action: "maximized", + eventType: "window", + scope: "workspace", + scopeId: id, + callback: wrappedCallback + }; + const unsubscribe = await getData$3(this).controller.processLocalSubscription(config, id); + return unsubscribe; + } + async onWindowRestored(callback) { + checkThrowCallback(callback); + const id = getData$3(this).id; + const wrappedCallback = async (payload) => { + await this.refreshReference(); + const windowParent = this.getBox((parent) => parent.id === payload.windowSummary.parentId); + const foundWindow = windowParent.children.find((child) => { + return child.type === "window" && child.elementId === payload.windowSummary.itemId; + }); + callback(foundWindow); + }; + const config = { + action: "restored", + eventType: "window", + scope: "workspace", + scopeId: id, + callback: wrappedCallback + }; + const unsubscribe = await getData$3(this).controller.processLocalSubscription(config, id); + return unsubscribe; + } + async onWindowSelected(callback) { + checkThrowCallback(callback); + const id = getData$3(this).id; + const wrappedCallback = async (payload) => { + await this.refreshReference(); + const windowParent = this.getBox((parent) => parent.id === payload.windowSummary.parentId); + const foundWindow = windowParent.children.find((child) => { + return child.type === "window" && child.elementId === payload.windowSummary.itemId; + }); + callback(foundWindow); + }; + const config = { + action: "selected", + eventType: "window", + scope: "workspace", + scopeId: id, + callback: wrappedCallback + }; + const unsubscribe = await getData$3(this).controller.processLocalSubscription(config, id); + return unsubscribe; + } + async onLockConfigurationChanged(callback) { + checkThrowCallback(callback); + const id = getData$3(this).id; + const wrappedCallback = async () => { + await this.refreshReference(); + callback({ + allowDrop: this.allowDrop, + allowDropLeft: this.allowDropLeft, + allowDropTop: this.allowDropTop, + allowDropRight: this.allowDropRight, + allowDropBottom: this.allowDropBottom, + allowSystemHibernation: this.allowSystemHibernation, + allowExtract: this.allowExtract, + allowSplitters: this.allowSplitters, + allowWindowReorder: this.allowWindowReorder, + allowWorkspaceTabExtract: this.allowWorkspaceTabExtract, + allowWorkspaceTabReorder: this.allowWorkspaceTabReorder, + showAddWindowButtons: this.showAddWindowButtons, + showCloseButton: this.showCloseButton, + showEjectButtons: this.showEjectButtons, + showSaveButton: this.showSaveButton, + showWindowCloseButtons: this.showWindowCloseButtons + }); + }; + const config = { + action: "lock-configuration-changed", + eventType: "workspace", + scope: "workspace", + scopeId: id, + callback: wrappedCallback + }; + const unsubscribe = await getData$3(this).controller.processLocalSubscription(config, id); + return unsubscribe; + } + } + + const data$2 = new WeakMap(); + const getData$2 = (model) => { + return data$2.get(model).manager.getWindowData(model); + }; + class Window { + constructor(dataManager) { + data$2.set(this, { manager: dataManager }); + } + get id() { + return getData$2(this).config.windowId; + } + get elementId() { + return getData$2(this).id; + } + get type() { + return "window"; + } + get frameId() { + return getData$2(this).frame.id; + } + get workspaceId() { + return getData$2(this).workspace.id; + } + get positionIndex() { + return getData$2(this).config.positionIndex; + } + get isMaximized() { + return getData$2(this).config.isMaximized; + } + get isLoaded() { + return getData$2(this).controller.checkIsWindowLoaded(this.id); + } + get isSelected() { + return getData$2(this).config.isSelected; + } + get focused() { + return this.getGdWindow().isFocused; + } + get title() { + return getData$2(this).config.title; + } + get allowExtract() { + return getData$2(this).config.allowExtract; + } + get allowReorder() { + return getData$2(this).config.allowReorder; + } + get showCloseButton() { + return getData$2(this).config.showCloseButton; + } + get width() { + return getData$2(this).config.widthInPx; + } + get height() { + return getData$2(this).config.heightInPx; + } + get minWidth() { + return getData$2(this).config.minWidth; + } + get minHeight() { + return getData$2(this).config.minHeight; + } + get maxWidth() { + return getData$2(this).config.maxWidth; + } + get maxHeight() { + return getData$2(this).config.maxHeight; + } + get workspace() { + return getData$2(this).workspace; + } + get frame() { + return getData$2(this).frame; + } + get parent() { + return getData$2(this).parent; + } + get appName() { + return getData$2(this).config.appName; + } + async forceLoad() { + if (this.isLoaded) { + return; + } + const controller = getData$2(this).controller; + const itemId = getData$2(this).id; + const windowId = await controller.forceLoadWindow(itemId); + getData$2(this).config.windowId = windowId; + await this.workspace.refreshReference(); + } + async focus() { + const id = getData$2(this).id; + const controller = getData$2(this).controller; + await controller.focusItem(id); + await this.workspace.refreshReference(); + } + async close() { + const id = getData$2(this).id; + const controller = getData$2(this).controller; + await controller.closeItem(id); + await getData$2(this) + .parent + .removeChild((child) => child.id === id); + await this.workspace.refreshReference(); + } + async setTitle(title) { + nonEmptyStringDecoder.runWithException(title); + const itemId = getData$2(this).id; + const controller = getData$2(this).controller; + await controller.setItemTitle(itemId, title); + await this.workspace.refreshReference(); + } + async maximize() { + const id = getData$2(this).id; + const controller = getData$2(this).controller; + await controller.maximizeItem(id); + await this.workspace.refreshReference(); + } + async restore() { + const id = getData$2(this).id; + const controller = getData$2(this).controller; + await controller.restoreItem(id); + await this.workspace.refreshReference(); + } + async eject() { + if (!this.isLoaded) { + throw new Error("Cannot eject this window, because it is not loaded yet"); + } + const itemId = getData$2(this).id; + const newWindowId = await getData$2(this).controller.ejectWindow(itemId); + getData$2(this).config.windowId = newWindowId; + await this.workspace.refreshReference(); + return this.getGdWindow(); + } + getGdWindow() { + if (!this.isLoaded) { + throw new Error("Cannot fetch this GD window, because the window is not yet loaded"); + } + const myId = getData$2(this).config.windowId; + const controller = getData$2(this).controller; + return controller.getGDWindow(myId); + } + async moveTo(parent) { + if (!(parent instanceof Row || parent instanceof Column || parent instanceof Group)) { + throw new Error("Cannot add to the provided parent, because the provided parent is not an instance of Row, Column or Group"); + } + const myId = getData$2(this).id; + const controller = getData$2(this).controller; + const foundParent = await controller.getParent((p) => p.id === parent.id); + if (!foundParent) { + throw new Error("Cannot move the window to the selected parent, because this parent does not exist."); + } + await controller.moveWindowTo(myId, parent.id); + await this.workspace.refreshReference(); + } + async lock(config) { + let lockConfigResult = undefined; + if (typeof config === "function") { + const currentLockConfig = { + allowExtract: this.allowExtract, + allowReorder: this.allowReorder, + showCloseButton: this.showCloseButton + }; + lockConfigResult = config(currentLockConfig); + } + else { + lockConfigResult = config; + } + const verifiedConfig = lockConfigResult === undefined ? undefined : windowLockConfigDecoder.runWithException(lockConfigResult); + const windowPlacementId = getData$2(this).id; + await getData$2(this).controller.lockWindow(windowPlacementId, verifiedConfig); + await this.workspace.refreshReference(); + } + async setSize(config) { + const verifiedConfig = elementResizeConfigDecoder.runWithException(config); + if (!verifiedConfig.width && !verifiedConfig.height) { + throw new Error("Expected either width or height to be passed."); + } + const myId = getData$2(this).id; + const controller = getData$2(this).controller; + await controller.resizeItem(myId, { + height: verifiedConfig.height, + width: verifiedConfig.width, + relative: false + }); + await this.workspace.refreshReference(); + } + async onRemoved(callback) { + checkThrowCallback(callback); + const id = getData$2(this).id; + const wrappedCallback = async () => { + await this.workspace.refreshReference(); + callback(); + }; + const config = { + callback: wrappedCallback, + action: "removed", + eventType: "window", + scope: "window" + }; + const unsubscribe = await getData$2(this).controller.processLocalSubscription(config, id); + return unsubscribe; + } + async onLockConfigurationChanged(callback) { + checkThrowCallback(callback); + const id = getData$2(this).id; + const wrappedCallback = async () => { + await this.workspace.refreshReference(); + callback({ + allowExtract: this.allowExtract, + allowReorder: this.allowReorder, + showCloseButton: this.showCloseButton + }); + }; + const config = { + callback: wrappedCallback, + action: "lock-configuration-changed", + eventType: "window", + scope: "window" + }; + const unsubscribe = await getData$2(this).controller.processLocalSubscription(config, id); + return unsubscribe; + } + } + + const data$1 = new WeakMap(); + const getData$1 = (model) => { + return data$1.get(model).manager.getFrameData(model); + }; + class Frame { + constructor(dataManager) { + data$1.set(this, { manager: dataManager }); + } + async registerShortcut(shortcut, callback) { + nonEmptyStringDecoder.runWithException(shortcut); + checkThrowCallback(callback); + const myId = getData$1(this).summary.id; + const unsubscribe = await getData$1(this).controller.registerShortcut(shortcut, myId, callback); + return unsubscribe; + } + get id() { + return getData$1(this).summary.id; + } + get isInitialized() { + return getData$1(this).summary.isInitialized; + } + getBounds() { + const myId = getData$1(this).summary.id; + return getData$1(this).controller.getFrameBounds(myId); + } + async resize(config) { + const validatedConfig = resizeConfigDecoder.runWithException(config); + const myId = getData$1(this).summary.id; + return getData$1(this).controller.resizeItem(myId, validatedConfig); + } + async move(config) { + const validatedConfig = moveConfigDecoder.runWithException(config); + const myId = getData$1(this).summary.id; + return getData$1(this).controller.moveFrame(myId, validatedConfig); + } + focus() { + const myId = getData$1(this).summary.id; + return getData$1(this).controller.focusItem(myId); + } + async state() { + if (!isDesktop()) { + throw new Error("State operations are not supported in IO Connect Browser"); + } + const myId = getData$1(this).summary.id; + return getData$1(this).controller.getFrameState(myId); + } + async minimize() { + if (!isDesktop()) { + throw new Error("State operations are not supported in IO Connect Browser"); + } + const myId = getData$1(this).summary.id; + return getData$1(this).controller.changeFrameState(myId, "minimized"); + } + async maximize() { + if (!isDesktop()) { + throw new Error("State operations are not supported in IO Connect Browser"); + } + const myId = getData$1(this).summary.id; + return getData$1(this).controller.changeFrameState(myId, "maximized"); + } + async restore() { + if (!isDesktop()) { + throw new Error("State operations are not supported in IO Connect Browser"); + } + const myId = getData$1(this).summary.id; + return getData$1(this).controller.changeFrameState(myId, "normal"); + } + close() { + const myId = getData$1(this).summary.id; + return getData$1(this).controller.closeItem(myId); + } + snapshot() { + const myId = getData$1(this).summary.id; + return getData$1(this).controller.getSnapshot(myId, "frame"); + } + async workspaces() { + const controller = getData$1(this).controller; + return controller.getWorkspacesByFrameId(this.id); + } + async getConstraints() { + const controller = getData$1(this).controller; + const myId = getData$1(this).summary.id; + return controller.getFrameConstraints(myId); + } + async restoreWorkspace(name, options) { + nonEmptyStringDecoder.runWithException(name); + const validatedOptions = restoreWorkspaceConfigDecoder.runWithException(options); + return getData$1(this).controller.restoreWorkspace(name, validatedOptions); + } + createWorkspace(definition, config) { + const validatedDefinition = workspaceDefinitionDecoder.runWithException(definition); + const validatedConfig = workspaceBuilderCreateConfigDecoder.runWithException(config); + return getData$1(this).controller.createWorkspace(validatedDefinition, validatedConfig); + } + async init(config) { + frameInitConfigDecoder.runWithException(config); + if (getData$1(this).summary.isInitialized) { + throw new Error("The frame has already been initialized"); + } + return getData$1(this).controller.initFrame(this.id, config); + } + async onClosed(callback) { + checkThrowCallback(callback); + const myId = getData$1(this).summary.id; + const wrappedCallback = (payload) => { + callback({ frameId: payload.frameSummary.id, frameBounds: payload.frameBounds }); + }; + const config = { + callback: wrappedCallback, + action: "closed", + eventType: "frame", + scope: "frame" + }; + const unsubscribe = await getData$1(this).controller.processLocalSubscription(config, myId); + return unsubscribe; + } + async onMaximized(callback) { + checkThrowCallback(callback); + const myId = getData$1(this).summary.id; + const wrappedCallback = () => { + callback(); + }; + const config = { + callback: wrappedCallback, + action: "maximized", + eventType: "frame", + scope: "frame" + }; + const unsubscribe = await getData$1(this).controller.processLocalSubscription(config, myId); + return unsubscribe; + } + async onMinimized(callback) { + checkThrowCallback(callback); + const myId = getData$1(this).summary.id; + const wrappedCallback = () => { + callback(); + }; + const config = { + callback: wrappedCallback, + action: "minimized", + eventType: "frame", + scope: "frame" + }; + const unsubscribe = await getData$1(this).controller.processLocalSubscription(config, myId); + return unsubscribe; + } + async onNormal(callback) { + checkThrowCallback(callback); + const myId = getData$1(this).summary.id; + const wrappedCallback = () => { + callback(); + }; + const config = { + callback: wrappedCallback, + action: "normal", + eventType: "frame", + scope: "frame" + }; + const unsubscribe = await getData$1(this).controller.processLocalSubscription(config, myId); + return unsubscribe; + } + async onWorkspaceOpened(callback) { + checkThrowCallback(callback); + const myId = getData$1(this).summary.id; + const wrappedCallback = async (payload) => { + const workspace = await getData$1(this).controller.transformStreamPayloadToWorkspace(payload); + callback(workspace); + }; + const config = { + callback: wrappedCallback, + action: "opened", + eventType: "workspace", + scope: "frame" + }; + const unsubscribe = await getData$1(this).controller.processLocalSubscription(config, myId); + return unsubscribe; + } + async onWorkspaceSelected(callback) { + checkThrowCallback(callback); + const myId = getData$1(this).summary.id; + const wrappedCallback = async (payload) => { + const workspace = await getData$1(this).controller.getWorkspaceById(payload.workspaceSummary.id); + callback(workspace); + }; + const config = { + callback: wrappedCallback, + action: "selected", + eventType: "workspace", + scope: "frame" + }; + const unsubscribe = await getData$1(this).controller.processLocalSubscription(config, myId); + return unsubscribe; + } + async onWorkspaceClosed(callback) { + checkThrowCallback(callback); + const myId = getData$1(this).summary.id; + const wrappedCallback = (payload) => { + callback({ frameId: payload.frameSummary.id, workspaceId: payload.workspaceSummary.id, frameBounds: payload.frameBounds }); + }; + const config = { + callback: wrappedCallback, + action: "closed", + eventType: "workspace", + scope: "frame" + }; + const unsubscribe = await getData$1(this).controller.processLocalSubscription(config, myId); + return unsubscribe; + } + async onWindowAdded(callback) { + checkThrowCallback(callback); + const myId = getData$1(this).summary.id; + const wrappedCallback = async (payload) => { + const foundParent = await getData$1(this).controller.getParent((parent) => parent.id === payload.windowSummary.parentId); + const foundWindow = foundParent.children.find((child) => child.type === "window" && child.positionIndex === payload.windowSummary.config.positionIndex); + callback(foundWindow); + }; + const config = { + callback: wrappedCallback, + action: "added", + eventType: "window", + scope: "frame" + }; + const unsubscribe = await getData$1(this).controller.processLocalSubscription(config, myId); + return unsubscribe; + } + async onWindowRemoved(callback) { + checkThrowCallback(callback); + const myId = getData$1(this).summary.id; + const wrappedCallback = (payload) => { + const { windowId, workspaceId, frameId } = payload.windowSummary.config; + callback({ windowId, workspaceId, frameId }); + }; + const config = { + callback: wrappedCallback, + action: "removed", + eventType: "window", + scope: "frame" + }; + const unsubscribe = await getData$1(this).controller.processLocalSubscription(config, myId); + return unsubscribe; + } + async onWindowLoaded(callback) { + checkThrowCallback(callback); + const myId = getData$1(this).summary.id; + const wrappedCallback = async (payload) => { + const foundParent = await getData$1(this).controller.getParent((parent) => { + return parent.id === payload.windowSummary.parentId; + }); + const foundWindow = foundParent.children.find((child) => child.type === "window" && child.positionIndex === payload.windowSummary.config.positionIndex); + callback(foundWindow); + }; + const config = { + callback: wrappedCallback, + action: "loaded", + eventType: "window", + scope: "frame" + }; + const unsubscribe = await getData$1(this).controller.processLocalSubscription(config, myId); + return unsubscribe; + } + async onInitializationRequested(callback) { + checkThrowCallback(callback); + if (!this.isInitialized) { + callback(getData$1(this).summary.initializationContext); + } + return () => { }; + } + async onFocusChanged(callback) { + checkThrowCallback(callback); + const myData = getData$1(this); + const { id } = myData.summary; + const wrappedCallback = (args) => { + callback({ isFocused: args.frameSummary.isFocused }); + }; + const config = { + callback: wrappedCallback, + action: "focus", + eventType: "frame", + scope: "frame" + }; + const unsubscribe = await myData.controller.processLocalSubscription(config, id); + return unsubscribe; + } + } + + class PrivateDataManager { + parentsData = new WeakMap(); + workspacesData = new WeakMap(); + windowsData = new WeakMap(); + framesData = new WeakMap(); + deleteData(model) { + if (model instanceof Window) { + this.windowsData.delete(model); + } + if (model instanceof Workspace) { + this.workspacesData.delete(model); + } + if (model instanceof Row || model instanceof Column || model instanceof Group) { + this.parentsData.delete(model); + } + if (model instanceof Frame) { + this.framesData.delete(model); + } + } + setWindowData(model, data) { + this.windowsData.set(model, data); + } + setWorkspaceData(model, data) { + this.workspacesData.set(model, data); + } + setParentData(model, data) { + this.parentsData.set(model, data); + } + setFrameData(model, data) { + this.framesData.set(model, data); + } + getWindowData(model) { + return this.windowsData.get(model); + } + getWorkspaceData(model) { + return this.workspacesData.get(model); + } + getParentData(model) { + return this.parentsData.get(model); + } + getFrameData(model) { + return this.framesData.get(model); + } + remapChild(model, newData) { + if (model instanceof Window) { + const data = this.windowsData.get(model); + data.parent = newData.parent || data.parent; + data.config = newData.config || data.config; + } + if (model instanceof Row || model instanceof Column || model instanceof Group) { + const data = this.parentsData.get(model); + data.parent = newData.parent || data.parent; + data.config = newData.config || data.config; + data.children = newData.children || data.children; + } + } + remapFrame(model, newData) { + const data = this.framesData.get(model); + data.summary = newData; + } + remapWorkspace(model, newData) { + const data = this.workspacesData.get(model); + data.frame = newData.frame || data.frame; + data.config = newData.config || data.config; + data.children = newData.children || data.children; + } + } + + const data = new WeakMap(); + const getData = (base, model) => { + const manager = data.get(base).manager; + if (model instanceof Workspace) { + return manager.getWorkspaceData(model); + } + return data.get(base).manager.getParentData(model); + }; + class Base { + frameId; + workspaceId; + positionIndex; + constructor(dataManager) { + data.set(this, { manager: dataManager }); + } + getId(model) { + return getData(this, model).id; + } + getPositionIndex(model) { + return getData(this, model).config.positionIndex; + } + getWorkspaceId(model) { + const privateData = getData(this, model); + return privateData.config.workspaceId || privateData.workspace.id; + } + getFrameId(model) { + return getData(this, model).frame.id; + } + getAllChildren(model, predicate) { + checkThrowCallback(predicate, true); + const children = getData(this, model).children; + if (typeof predicate === "undefined") { + return children; + } + return children.filter(predicate); + } + getMyParent(model) { + if (model instanceof Workspace) { + return model; + } + return getData(this, model).parent; + } + getMyFrame(model) { + return getData(this, model).frame; + } + getMyWorkspace(model) { + if (model instanceof Workspace) { + return model; + } + return getData(this, model).workspace; + } + async addWindow(model, definition, parentType) { + if (!definition.appName && !definition.windowId) { + throw new Error("The window definition should contain either an appName or a windowId"); + } + const validatedDefinition = swimlaneWindowDefinitionDecoder.runWithException(definition); + const controller = getData(this, model).controller; + const operationResult = await controller.add("window", getData(this, model).id, parentType, validatedDefinition); + if (model instanceof Workspace) { + await model.refreshReference(); + return model.getWindow(w => w.elementId === operationResult.itemId); + } + const myWorkspace = this.getMyWorkspace(model); + await myWorkspace.refreshReference(); + return myWorkspace.getWindow(w => w.elementId === operationResult.itemId); + } + async addParent(model, typeToAdd, parentType, definition) { + const parentDefinition = this.transformDefinition(typeToAdd, definition); + const controller = getData(this, model).controller; + const newParentId = (await controller.add("container", getData(this, model).id, parentType, parentDefinition)).itemId; + if (model instanceof Workspace) { + await model.refreshReference(); + return model.getBox((parent) => parent.id === newParentId); + } + const myWorkspace = this.getMyWorkspace(model); + await myWorkspace.refreshReference(); + return myWorkspace.getBox((parent) => parent.id === newParentId); + } + async removeChild(model, predicate) { + checkThrowCallback(predicate); + const child = this.getAllChildren(model).find(predicate); + if (!child) { + return; + } + await child.close(); + if (model instanceof Workspace) { + await model.refreshReference(); + return; + } + await this.getMyWorkspace(model).refreshReference(); + } + async maximize(model) { + const { controller, id } = getData(this, model); + await controller.maximizeItem(id); + await this.getMyWorkspace(model.parent).refreshReference(); + } + async restore(model) { + const { controller, id } = getData(this, model); + await controller.restoreItem(id); + await this.getMyWorkspace(model.parent).refreshReference(); + } + async close(model) { + const modelData = getData(this, model); + const controller = getData(this, model).controller; + await controller.closeItem(modelData.id); + await this.getMyWorkspace(modelData.parent).refreshReference(); + } + async lockContainer(model, config) { + const modelData = getData(this, model); + const controller = getData(this, model).controller; + await controller.lockContainer(modelData.id, model.type, config); + await this.getMyWorkspace(modelData.parent).refreshReference(); + } + getAllowDrop(model) { + return getData(this, model).config.allowDrop; + } + getAllowDropLeft(model) { + const privateData = getData(this, model); + if (privateData.type !== "group") { + throw new Error(`Property allowDropLeft is available only for groups and not on ${model.type} ${model.id}`); + } + return privateData.config.allowDropLeft; + } + getAllowDropRight(model) { + const privateData = getData(this, model); + if (privateData.type !== "group") { + throw new Error(`Property allowDropRight is available only for groups and not on ${model.type} ${model.id}`); + } + return privateData.config.allowDropRight; + } + getAllowDropTop(model) { + const privateData = getData(this, model); + if (privateData.type !== "group") { + throw new Error(`Property allowDropTop is available only for groups and not on ${model.type} ${model.id}`); + } + return privateData.config.allowDropTop; + } + getAllowDropBottom(model) { + const privateData = getData(this, model); + if (privateData.type !== "group") { + throw new Error(`Property allowDropBottom is available only for groups and not on ${model.type} ${model.id}`); + } + return privateData.config.allowDropBottom; + } + getAllowDropHeader(model) { + const privateData = getData(this, model); + if (privateData.type !== "group") { + throw new Error(`Property allowDropHeader is available only for groups and not on ${model.type} ${model.id}`); + } + return privateData.config.allowDropHeader; + } + getAllowSplitters(model) { + const privateData = getData(this, model); + if (privateData.type === "group") { + throw new Error(`Cannot get allow splitters from private data ${privateData.type}`); + } + return privateData.config.allowSplitters; + } + getAllowExtract(model) { + const privateData = getData(this, model); + if (privateData.type !== "group") { + throw new Error(`Cannot get allow extract from private data ${privateData.type} with config ${privateData.type !== "workspace" ? privateData.config.type : ""}`); + } + return privateData.config.allowExtract; + } + getAllowReorder(model) { + const privateData = getData(this, model); + if (privateData.type !== "group") { + throw new Error(`Cannot get allow extract from private data ${privateData.type} with config ${privateData.type !== "workspace" ? privateData.config.type : ""}`); + } + return privateData.config.allowReorder; + } + getShowMaximizeButton(model) { + const privateData = getData(this, model); + if (privateData.type !== "group") { + throw new Error(`Cannot get show maximize button from private data${privateData.type} with config ${privateData.type !== "workspace" ? privateData.config.type : ""}`); + } + return privateData.config.showMaximizeButton; + } + getShowEjectButton(model) { + const privateData = getData(this, model); + if (privateData.type !== "group") { + throw new Error(`Cannot get show eject button from private data${privateData.type} with config ${privateData.type !== "workspace" ? privateData.config.type : ""}`); + } + return privateData.config.showEjectButton; + } + getShowAddWindowButton(model) { + const privateData = getData(this, model); + if (privateData.type !== "group") { + throw new Error(`Cannot get add window button from private data${privateData.type} with config ${privateData.type !== "workspace" ? privateData.config.type : ""}`); + } + return privateData.config.showAddWindowButton; + } + getMinWidth(model) { + const privateData = getData(this, model); + return privateData.config.minWidth; + } + getMaxWidth(model) { + const privateData = getData(this, model); + return privateData.config.maxWidth; + } + getMinHeight(model) { + const privateData = getData(this, model); + return privateData.config.minHeight; + } + getMaxHeight(model) { + const privateData = getData(this, model); + return privateData.config.maxHeight; + } + getWidthInPx(model) { + const privateData = getData(this, model); + return privateData.config.widthInPx; + } + getHeightInPx(model) { + const privateData = getData(this, model); + return privateData.config.heightInPx; + } + getIsPinned(model) { + const privateData = getData(this, model); + return privateData.config.isPinned; + } + getIsMaximized(model) { + const privateData = getData(this, model); + return privateData.config.isMaximized; + } + getMaximizationBoundary(model) { + const privateData = getData(this, model); + return privateData.config.maximizationBoundary; + } + async setHeight(model, height) { + const modelData = getData(this, model); + const { controller, id } = modelData; + await controller.resizeItem(id, { + height + }); + await this.getMyWorkspace(modelData.parent).refreshReference(); + } + async setWidth(model, width) { + const modelData = getData(this, model); + const { controller, id } = modelData; + await controller.resizeItem(id, { + width + }); + await this.getMyWorkspace(modelData.parent).refreshReference(); + } + async setSize(model, width, height) { + const modelData = getData(this, model); + const { controller, id } = modelData; + await controller.resizeItem(id, { + width, + height + }); + await this.getMyWorkspace(modelData.parent).refreshReference(); + } + async setMaximizationBoundary(model, config) { + const modelData = getData(this, model); + const { controller, id } = modelData; + await controller.setMaximizationBoundary(id, config); + await this.getMyWorkspace(modelData.parent).refreshReference(); + } + async bundleTo(model, type) { + const modelData = getData(this, model); + const { controller, id } = modelData; + await controller.bundleItemTo(type, id); + } + async processLocalSubscription(model, subscriptionConfig) { + return getData(this, model).controller.processLocalSubscription(subscriptionConfig, this.getId(model)); + } + transformDefinition(type, definition) { + let parentDefinition; + if (typeof definition === "undefined") { + parentDefinition = { type, children: [] }; + } + else if (definition instanceof ParentBuilder) { + parentDefinition = definition.serialize(); + } + else { + if (typeof definition.type === "undefined") { + definition.type = type; + } + parentDefinition = strictParentDefinitionDecoder.runWithException(definition); + parentDefinition.children = parentDefinition.children || []; + } + return parentDefinition; + } + } + + class BaseController { + ioc; + windows; + contexts; + layouts; + constructor(ioc, windows, contexts, layouts) { + this.ioc = ioc; + this.windows = windows; + this.contexts = contexts; + this.layouts = layouts; + } + get bridge() { + return this.ioc.bridge; + } + get privateDataManager() { + return this.ioc.privateDataManager; + } + checkIsWindowLoaded(windowId) { + return (!!windowId) && this.windows.list().some((win) => win.id === windowId); + } + async createWorkspace(createConfig) { + const snapshot = await this.bridge.send(OPERATIONS.createWorkspace.name, createConfig); + const frameConfig = { + summary: snapshot.frameSummary + }; + const frame = this.ioc.getModel("frame", frameConfig); + const workspaceConfig = { frame, snapshot }; + return this.ioc.getModel("workspace", workspaceConfig); + } + async createEmptyFrame(definition) { + const frameSummary = await this.bridge.send(OPERATIONS.createFrame.name, definition); + const frameConfig = { + summary: frameSummary + }; + return this.ioc.getModel("frame", frameConfig); + } + async initFrame(frameId, config) { + await this.bridge.send(OPERATIONS.initFrame.name, { frameId, ...config }); + } + async restoreWorkspace(name, options) { + const snapshot = await this.bridge.send(OPERATIONS.openWorkspace.name, { name, restoreOptions: options }); + const frameSummary = await this.bridge.send(OPERATIONS.getFrameSummary.name, { itemId: snapshot.config.frameId }); + const frameConfig = { + summary: frameSummary + }; + const frame = this.ioc.getModel("frame", frameConfig); + const workspaceConfig = { frame, snapshot }; + return this.ioc.getModel("workspace", workspaceConfig); + } + async add(type, parentId, parentType, definition) { + let operationName; + const operationArgs = { definition, parentId, parentType }; + if (type === "window") { + operationName = OPERATIONS.addWindow.name; + } + else if (type === "container") { + operationName = OPERATIONS.addContainer.name; + } + else { + throw new Error(`Unrecognized add type: ${type}`); + } + return await this.bridge.send(operationName, operationArgs); + } + async getFrame(windowId) { + const frameSummary = await this.bridge.send(OPERATIONS.getFrameSummary.name, { itemId: windowId }); + const frameConfig = { + summary: frameSummary + }; + return this.ioc.getModel("frame", frameConfig); + } + getFrames(allFrameSummaries, predicate) { + return allFrameSummaries.reduce((frames, frameSummary) => { + const frameConfig = { + summary: frameSummary + }; + const frameToCheck = this.ioc.getModel("frame", frameConfig); + if (!predicate || predicate(frameToCheck)) { + frames.push(frameToCheck); + } + return frames; + }, []); + } + getAllWorkspaceSummaries(...bridgeResults) { + const allSummaries = bridgeResults.reduce((summaries, summaryResult) => { + summaries.push(...summaryResult.summaries); + return summaries; + }, []); + return allSummaries.map((summary) => { + return Object.assign({}, { id: summary.id, width: summary.config.widthInPx, height: summary.config.heightInPx }, summary.config); + }); + } + handleOnSaved(callback) { + const wrappedCallback = (layout) => { + if (layout.type !== "Workspace") { + return; + } + callback(layout); + }; + const addedUnSub = this.layouts.onAdded(wrappedCallback); + const changedUnSub = this.layouts.onChanged(wrappedCallback); + return () => { + addedUnSub(); + changedUnSub(); + }; + } + handleOnRemoved(callback) { + const wrappedCallback = (layout) => { + if (layout.type !== "Workspace") { + return; + } + callback(layout); + }; + return this.layouts.onRemoved(wrappedCallback); + } + async importLayouts(layouts, mode) { + await this.layouts.import(layouts, mode); + } + async transformStreamPayloadToWorkspace(payload) { + const frameConfig = { + summary: payload.frameSummary + }; + const frame = this.ioc.getModel("frame", frameConfig); + const snapshot = payload.workspaceSnapshot || (await this.bridge.send(OPERATIONS.getWorkspaceSnapshot.name, { itemId: payload.workspaceSummary.id })); + const workspaceConfig = { frame, snapshot }; + const workspace = this.ioc.getModel("workspace", workspaceConfig); + return workspace; + } + async fetchWorkspace(itemId) { + const snapshot = await this.bridge.send(OPERATIONS.getWorkspaceSnapshot.name, { itemId }); + const frameConfig = { + summary: snapshot.frameSummary + }; + const frame = this.ioc.getModel("frame", frameConfig); + const workspaceConfig = { frame, snapshot }; + return this.ioc.getModel("workspace", workspaceConfig); + } + async bundleWorkspaceTo(type, workspaceId) { + await this.bridge.send(OPERATIONS.bundleWorkspace.name, { type, workspaceId }); + } + async bundleItemTo(type, itemId) { + const isSupported = await this.isOperationSupported(OPERATIONS.bundleItem.name); + if (!isSupported) { + throw new Error(`Operation ${OPERATIONS.bundleItem.name} is not supported. Ensure that you are running the latest version of all packages`); + } + await this.bridge.send(OPERATIONS.bundleItem.name, { type, itemId }); + } + getWorkspaceContext(workspaceId) { + const contextName = `___workspace___${workspaceId}`; + return this.contexts.get(contextName); + } + setWorkspaceContext(workspaceId, data) { + const contextName = `___workspace___${workspaceId}`; + return this.contexts.set(contextName, data); + } + updateWorkspaceContext(workspaceId, data) { + const contextName = `___workspace___${workspaceId}`; + return this.contexts.update(contextName, data); + } + subscribeWorkspaceContextUpdated(workspaceId, callback) { + const contextName = `___workspace___${workspaceId}`; + return this.contexts.subscribe(contextName, callback); + } + async restoreItem(itemId) { + await this.bridge.send(OPERATIONS.restoreItem.name, { itemId }); + } + async maximizeItem(itemId) { + await this.bridge.send(OPERATIONS.maximizeItem.name, { itemId }); + } + async focusItem(itemId) { + await this.bridge.send(OPERATIONS.focusItem.name, { itemId }); + } + async closeItem(itemId) { + await this.bridge.send(OPERATIONS.closeItem.name, { itemId }); + } + async resizeItem(itemId, config) { + await this.bridge.send(OPERATIONS.resizeItem.name, Object.assign({}, { itemId }, config)); + } + async setMaximizationBoundary(itemId, config) { + await this.bridge.send(OPERATIONS.setMaximizationBoundary.name, Object.assign({}, { itemId }, config)); + } + async showWorkspaceLoadingAnimation(workspaceId) { + await this.bridge.send(OPERATIONS.showLoadingAnimation.name, { itemId: workspaceId, type: "workspace" }); + } + async hideWorkspaceLoadingAnimation(workspaceId) { + await this.bridge.send(OPERATIONS.hideLoadingAnimation.name, { itemId: workspaceId, type: "workspace" }); + } + async setWindowDragMode(workspaceId, dragMode) { + await this.bridge.send(OPERATIONS.setWindowDragMode.name, { itemId: workspaceId, dragMode }); + } + async moveFrame(itemId, config) { + await this.bridge.send(OPERATIONS.moveFrame.name, Object.assign({}, { itemId }, config)); + } + getGDWindow(itemId) { + return this.windows.list().find((gdWindow) => gdWindow.id === itemId); + } + async forceLoadWindow(itemId) { + const controlResult = await this.bridge.send(OPERATIONS.forceLoadWindow.name, { itemId }); + return controlResult.windowId; + } + async ejectWindow(itemId) { + return await this.bridge.send(OPERATIONS.ejectWindow.name, { itemId }); + } + async moveWindowTo(itemId, newParentId) { + await this.bridge.send(OPERATIONS.moveWindowTo.name, { itemId, containerId: newParentId }); + } + async getSnapshot(itemId, type) { + let result; + if (type === "workspace") { + result = await this.bridge.send(OPERATIONS.getWorkspaceSnapshot.name, { itemId }); + } + else if (type === "frame") { + result = await this.bridge.send(OPERATIONS.getFrameSnapshot.name, { itemId }); + } + return result; + } + async setItemTitle(itemId, title) { + await this.bridge.send(OPERATIONS.setItemTitle.name, { itemId, title }); + } + refreshChildren(config) { + const { parent, children, existingChildren, workspace } = config; + if (parent instanceof Window || parent.type === "window") { + return; + } + const newChildren = children.map((newChildSnapshot) => { + let childToAdd = existingChildren.find((child) => { + return child.type === "window" ? child.elementId === newChildSnapshot.id : child.id === newChildSnapshot.id; + }); + if (childToAdd) { + this.privateDataManager.remapChild(childToAdd, { + parent: parent, + children: [], + config: newChildSnapshot.config + }); + } + else { + let createConfig; + if (newChildSnapshot.type === "window") { + createConfig = { + id: newChildSnapshot.id, + parent: parent, + frame: workspace.frame, + workspace, + config: newChildSnapshot.config, + }; + } + else { + createConfig = { + id: newChildSnapshot.id, + parent: parent, + frame: workspace.frame, + workspace, + config: newChildSnapshot.config, + children: [] + }; + } + childToAdd = this.ioc.getModel(newChildSnapshot.type, createConfig); + } + if (newChildSnapshot.type !== "window") { + this.refreshChildren({ + workspace, existingChildren, + children: newChildSnapshot.children, + parent: childToAdd + }); + } + return childToAdd; + }); + if (parent instanceof Workspace) { + return newChildren; + } + else { + this.privateDataManager.remapChild(parent, { children: newChildren }); + return newChildren; + } + } + iterateFindChild(children, predicate) { + let foundChild = children.find((child) => predicate(child)); + if (foundChild) { + return foundChild; + } + children.some((child) => { + if (child instanceof Window) { + return false; + } + foundChild = this.iterateFindChild(child.children, predicate); + if (foundChild) { + return true; + } + }); + return foundChild; + } + iterateFilterChildren(children, predicate) { + const foundChildren = children.filter((child) => predicate(child)); + const grandChildren = children.reduce((innerFound, child) => { + if (child instanceof Window) { + return innerFound; + } + innerFound.push(...this.iterateFilterChildren(child.children, predicate)); + return innerFound; + }, []); + foundChildren.push(...grandChildren); + return foundChildren; + } + notifyWindowAdded(windowId) { + return new Promise((resolve) => { + const alreadyPresent = this.windows.list().some((win) => win.id === windowId); + if (alreadyPresent) { + return resolve(); + } + const unsubscribe = this.windows.onWindowAdded((win) => { + if (win.id !== windowId) { + return; + } + if (unsubscribe) { + unsubscribe(); + } + resolve(); + }); + }); + } + async hibernateWorkspace(workspaceId) { + await this.bridge.send(OPERATIONS.hibernateWorkspace.name, { workspaceId }); + } + async resumeWorkspace(workspaceId) { + await this.bridge.send(OPERATIONS.resumeWorkspace.name, { workspaceId }); + } + async lockWorkspace(workspaceId, config) { + await this.bridge.send(OPERATIONS.lockWorkspace.name, { workspaceId, config }); + } + async lockWindow(windowPlacementId, config) { + await this.bridge.send(OPERATIONS.lockWindow.name, { windowPlacementId, config }); + } + async lockContainer(itemId, type, config) { + await this.bridge.send(OPERATIONS.lockContainer.name, { itemId, type, config }); + } + async pinWorkspace(workspaceId, icon) { + await this.bridge.send(OPERATIONS.pinWorkspace.name, { workspaceId, icon }); + } + async unpinWorkspace(workspaceId) { + await this.bridge.send(OPERATIONS.unpinWorkspace.name, { workspaceId }); + } + async getWorkspaceIcon(workspaceId) { + const result = await this.bridge.send(OPERATIONS.getWorkspaceIcon.name, { workspaceId }); + return result.icon; + } + setWorkspaceIcon(workspaceId, icon) { + return this.bridge.send(OPERATIONS.setWorkspaceIcon.name, { workspaceId, icon }); + } + async getPlatformFrameId() { + try { + const result = await this.bridge.send(OPERATIONS.getPlatformFrameId.name, {}); + return result; + } + catch (error) { + return {}; + } + } + async setLoadingStrategy(workspaceId, strategy) { + await this.isOperationSupported(OPERATIONS.setLoadingStrategy.name); + return this.bridge.send(OPERATIONS.setLoadingStrategy.name, { itemId: workspaceId, strategy }); + } + async isOperationSupported(operation) { + if (isDesktop()) { + return { isSupported: true }; + } + return await this.bridge.send(OPERATIONS.operationCheck.name, { operation }); + } + } + + class MainController { + bridge; + base; + shortcutsController; + constructor(bridge, base, shortcutsController) { + this.bridge = bridge; + this.base = base; + this.shortcutsController = shortcutsController; + } + checkIsWindowLoaded(windowId) { + return this.base.checkIsWindowLoaded(windowId); + } + async checkIsInSwimlane(windowId) { + const controlResult = await this.bridge.send(OPERATIONS.isWindowInWorkspace.name, { itemId: windowId }); + return controlResult.inWorkspace; + } + async createWorkspace(definition, saveConfig) { + const createConfig = Object.assign({}, definition, { saveConfig }); + return await this.base.createWorkspace(createConfig); + } + async createEmptyFrame(definition) { + return await this.base.createEmptyFrame(definition); + } + async initFrame(frameId, config) { + return this.base.initFrame(frameId, config); + } + async restoreWorkspace(name, options) { + const allLayouts = await this.getLayoutSummaries(); + const layoutExists = allLayouts.some((summary) => summary.name === name); + if (!layoutExists) { + throw new Error(`This layout: ${name} cannot be restored, because it doesn't exist.`); + } + if (options?.frameId) { + const allFrameSummaries = await this.bridge.send(OPERATIONS.getAllFramesSummaries.name); + const foundMatchingFrame = allFrameSummaries.summaries.some((summary) => summary.id === options.frameId); + if (!foundMatchingFrame) { + throw new Error(`Cannot reuse the frame with id: ${options.frameId}, because there is no frame with that ID found`); + } + } + return await this.base.restoreWorkspace(name, options); + } + async add(type, parentId, parentType, definition) { + return await this.base.add(type, parentId, parentType, definition); + } + processLocalSubscription(config, levelId) { + return isDesktop() ? + this.handleEnterpriseLocalSubscription(config, levelId) : + this.handleCoreLocalSubscription(config, levelId); + } + processGlobalSubscription(callback, eventType, action) { + return isDesktop() ? + this.handleEnterpriseGlobalSubscription(callback, eventType, action) : + this.handleCoreGlobalSubscription(callback, eventType, action); + } + async getFrame(selector) { + if (selector.windowId) { + return await this.base.getFrame(selector.windowId); + } + if (selector.predicate) { + return (await this.getFrames(selector.predicate))[0]; + } + throw new Error(`The provided selector is not valid: ${JSON.stringify(selector)}`); + } + async getFrames(predicate) { + const allFrameSummaries = await this.bridge.send(OPERATIONS.getAllFramesSummaries.name); + return this.base.getFrames(allFrameSummaries.summaries, predicate); + } + getWorkspaceById(workspaceId) { + return this.base.fetchWorkspace(workspaceId); + } + async getWorkspaceByWindowId(itemId) { + if (!isDesktop()) { + return (await this.getWorkspaces((wsp) => !!wsp.getWindow((w) => w.id === itemId)))[0]; + } + return this.base.fetchWorkspace(itemId); + } + transformStreamPayloadToWorkspace(payload) { + return this.base.transformStreamPayloadToWorkspace(payload); + } + async getWorkspace(predicate) { + let foundWorkspace; + await this.iterateWorkspaces((wsp, end) => { + if (predicate(wsp)) { + foundWorkspace = wsp; + end(); + } + }); + return foundWorkspace; + } + async getWorkspaces(predicate) { + const matchingWorkspaces = []; + await this.iterateWorkspaces((wsp) => { + if (!predicate || predicate(wsp)) { + matchingWorkspaces.push(wsp); + } + }); + return matchingWorkspaces; + } + async getWorkspacesByFrameId(frameId) { + const workspaceSummaries = await this.getAllWorkspaceSummaries(); + const summariesForFrame = workspaceSummaries.filter((s) => s.frameId === frameId); + const workspacesForFrame = await Promise.all(summariesForFrame.map((summary) => { + return this.base.fetchWorkspace(summary.id); + })); + return workspacesForFrame; + } + async getAllWorkspaceSummaries() { + const allSummariesResult = await this.bridge.send(OPERATIONS.getAllWorkspacesSummaries.name, {}); + return this.base.getAllWorkspaceSummaries(allSummariesResult); + } + async getWindow(predicate) { + let resultWindow; + await this.iterateWorkspaces((wsp, end) => { + const foundWindow = wsp.getWindow(predicate); + if (foundWindow) { + resultWindow = foundWindow; + end(); + } + }); + return resultWindow; + } + async getParent(predicate) { + let resultParent; + await this.iterateWorkspaces((wsp, end) => { + const foundParent = wsp.getBox(predicate); + if (foundParent) { + resultParent = foundParent; + end(); + } + }); + return resultParent; + } + async getLayoutSummaries() { + const allLayouts = await this.bridge.send(OPERATIONS.getAllLayoutsSummaries.name); + return allLayouts.summaries; + } + async deleteLayout(name) { + await this.bridge.send(OPERATIONS.deleteLayout.name, { name }); + } + async exportLayout(predicate) { + const allLayoutsResult = await this.bridge.send(OPERATIONS.exportAllLayouts.name); + return allLayoutsResult.layouts.reduce((matchingLayouts, layout) => { + if (!predicate || predicate(layout)) { + matchingLayouts.push(layout); + } + return matchingLayouts; + }, []); + } + async saveLayout(config) { + return await this.bridge.send(OPERATIONS.saveLayout.name, config); + } + async importLayouts(layouts, mode) { + if (isDesktop()) { + try { + await this.bridge.send(OPERATIONS.importLayouts.name, { layouts, mode }); + } + catch (error) { + await Promise.all(layouts.map((layout) => this.bridge.send(OPERATIONS.importLayout.name, { layout, mode }))); + } + return; + } + await this.base.importLayouts(layouts, mode); + } + handleOnSaved(callback) { + return this.base.handleOnSaved(callback); + } + handleOnRemoved(callback) { + return this.base.handleOnRemoved(callback); + } + async bundleWorkspaceTo(type, workspaceId) { + return await this.base.bundleWorkspaceTo(type, workspaceId); + } + async bundleItemTo(type, id) { + return await this.base.bundleItemTo(type, id); + } + getWorkspaceContext(workspaceId) { + return this.base.getWorkspaceContext(workspaceId); + } + setWorkspaceContext(workspaceId, data) { + return this.base.setWorkspaceContext(workspaceId, data); + } + updateWorkspaceContext(workspaceId, data) { + return this.base.updateWorkspaceContext(workspaceId, data); + } + subscribeWorkspaceContextUpdated(workspaceId, callback) { + return this.base.subscribeWorkspaceContextUpdated(workspaceId, callback); + } + async restoreItem(itemId) { + return await this.base.restoreItem(itemId); + } + async maximizeItem(itemId) { + return await this.base.maximizeItem(itemId); + } + async focusItem(itemId) { + return await this.base.focusItem(itemId); + } + async changeFrameState(frameId, state) { + await this.bridge.send(OPERATIONS.changeFrameState.name, { frameId, requestedState: state }); + } + async getFrameBounds(frameId) { + const frameResult = await this.bridge.send(OPERATIONS.getFrameBounds.name, { itemId: frameId }); + return frameResult.bounds; + } + async getFrameState(frameId) { + const frameResult = await this.bridge.send(OPERATIONS.getFrameState.name, { itemId: frameId }); + return frameResult.state; + } + async closeItem(itemId) { + return await this.base.closeItem(itemId); + } + async resizeItem(itemId, config) { + return await this.base.resizeItem(itemId, config); + } + async setMaximizationBoundary(itemId, config) { + return await this.base.setMaximizationBoundary(itemId, config); + } + async showWorkspaceLoadingAnimation(workspaceId) { + return await this.base.showWorkspaceLoadingAnimation(workspaceId); + } + async hideWorkspaceLoadingAnimation(workspaceId) { + return await this.base.hideWorkspaceLoadingAnimation(workspaceId); + } + async setWindowDragMode(workspaceId, dragMode) { + return await this.base.setWindowDragMode(workspaceId, dragMode); + } + async moveFrame(itemId, config) { + return await this.base.moveFrame(itemId, config); + } + getGDWindow(itemId) { + return this.base.getGDWindow(itemId); + } + async forceLoadWindow(itemId) { + const windowId = await this.base.forceLoadWindow(itemId); + await this.base.notifyWindowAdded(windowId); + return windowId; + } + async ejectWindow(itemId) { + const windowId = (await this.base.ejectWindow(itemId)).windowId; + await this.base.notifyWindowAdded(windowId); + return windowId; + } + async moveWindowTo(itemId, newParentId) { + return await this.base.moveWindowTo(itemId, newParentId); + } + async getSnapshot(itemId, type) { + return await this.base.getSnapshot(itemId, type); + } + async setItemTitle(itemId, title) { + return await this.base.setItemTitle(itemId, title); + } + flatChildren(children) { + return children.reduce((soFar, child) => { + soFar.push(child); + if (child.type !== "window") { + soFar.push(...this.flatChildren(child.children)); + } + return soFar; + }, []); + } + refreshChildren(config) { + return this.base.refreshChildren(config); + } + iterateFindChild(children, predicate) { + return this.base.iterateFindChild(children, predicate); + } + iterateFilterChildren(children, predicate) { + return this.base.iterateFilterChildren(children, predicate); + } + hibernateWorkspace(workspaceId) { + return this.base.hibernateWorkspace(workspaceId); + } + resumeWorkspace(workspaceId) { + return this.base.resumeWorkspace(workspaceId); + } + lockWorkspace(workspaceId, config) { + return this.base.lockWorkspace(workspaceId, config); + } + lockWindow(windowPlacementId, config) { + return this.base.lockWindow(windowPlacementId, config); + } + lockContainer(itemId, type, config) { + return this.base.lockContainer(itemId, type, config); + } + pinWorkspace(workspaceId, icon) { + return this.base.pinWorkspace(workspaceId, icon); + } + unpinWorkspace(workspaceId) { + return this.base.unpinWorkspace(workspaceId); + } + getWorkspaceIcon(workspaceId) { + return this.base.getWorkspaceIcon(workspaceId); + } + setWorkspaceIcon(workspaceId, icon) { + return this.base.setWorkspaceIcon(workspaceId, icon); + } + async getFrameConstraints(frameId) { + const frameSnapshot = await this.getSnapshot(frameId, "frame"); + return { + minWidth: frameSnapshot.config.minWidth, + maxWidth: frameSnapshot.config.maxWidth, + minHeight: frameSnapshot.config.minHeight, + maxHeight: frameSnapshot.config.maxHeight, + }; + } + registerShortcut(shortcut, frameId, callback) { + return this.shortcutsController.registerShortcut(shortcut, frameId, callback); + } + getPlatformFrameId() { + return this.base.getPlatformFrameId(); + } + setLoadingStrategy(workspaceId, strategy) { + return this.base.setLoadingStrategy(workspaceId, strategy); + } + async handleCoreLocalSubscription(config, levelId) { + await this.bridge.createCoreEventSubscription(); + config.scopeId = config.scopeId || levelId; + if (config.eventType === "window" && config.action === "loaded") { + const originalCB = config.callback; + const wrappedCB = async (callbackData) => { + await this.base.notifyWindowAdded(callbackData.windowSummary.config.windowId); + originalCB(callbackData); + }; + config.callback = wrappedCB; + } + return this.bridge.handleCoreSubscription(config); + } + handleEnterpriseLocalSubscription(config, levelId) { + config.scopeId = config.scopeId || levelId; + if (config.eventType === "window" && config.action === "loaded") { + const originalCB = config.callback; + const wrappedCB = async (callbackData) => { + await this.base.notifyWindowAdded(callbackData.windowSummary.config.windowId); + originalCB(callbackData); + }; + config.callback = wrappedCB; + } + return this.bridge.subscribe(config); + } + async handleCoreGlobalSubscription(callback, eventType, action) { + await this.bridge.createCoreEventSubscription(); + const config = { + eventType, callback, action, + scope: "global", + }; + if (eventType === "window" && action === "loaded") { + const wrappedCB = async (callbackData) => { + await this.base.notifyWindowAdded(callbackData.windowSummary.config.windowId); + callback(callbackData); + }; + config.callback = wrappedCB; + } + return this.bridge.handleCoreSubscription(config); + } + handleEnterpriseGlobalSubscription(callback, eventType, action) { + const config = { + eventType, callback, action, + scope: "global", + }; + if (eventType === "window" && action === "loaded") { + const wrappedCB = async (callbackData) => { + await this.base.notifyWindowAdded(callbackData.windowSummary.config.windowId); + callback(callbackData); + }; + config.callback = wrappedCB; + } + return this.bridge.subscribe(config); + } + async iterateWorkspaces(callback) { + let ended = false; + const end = () => { ended = true; }; + const workspaceSummaries = await this.getAllWorkspaceSummaries(); + for (const summary of workspaceSummaries) { + if (ended) { + return; + } + const wsp = await this.base.fetchWorkspace(summary.id); + callback(wsp, end); + } + } + } + + class ShortcutsController { + bridge; + _shortcuts = CallbackFactory(); + constructor(bridge) { + this.bridge = bridge; + this.bridge.onOperation((payload, caller) => { + if (payload.operation === CLIENT_OPERATIONS.shortcutClicked.name) { + const data = payload.data; + this._shortcuts.execute(`${data.frameId}-${data.shortcut}`); + } + }); + } + async registerShortcut(shortcut, frameId, callback) { + await this.bridge.send(OPERATIONS.registerShortcut.name, { shortcut, frameId }); + const un = this._shortcuts.add(`${frameId}-${shortcut}`, callback); + return () => { + un(); + this.bridge.send(OPERATIONS.unregisterShortcut.name, { shortcut, frameId }); + }; + } + } + + class IoC { + agm; + windows; + layouts; + contexts; + _controllerInstance; + _bridgeInstance; + _transportInstance; + _privateDataManagerInstance; + _parentBaseInstance; + _baseController; + _shortcutsController; + constructor(agm, windows, layouts, contexts) { + this.agm = agm; + this.windows = windows; + this.layouts = layouts; + this.contexts = contexts; + } + get baseController() { + if (!this._baseController) { + this._baseController = new BaseController(this, this.windows, this.contexts, this.layouts); + } + return this._baseController; + } + get controller() { + if (!this._controllerInstance) { + this._controllerInstance = new MainController(this.bridge, this.baseController, this.shortcutsController); + } + return this._controllerInstance; + } + get shortcutsController() { + if (!this._shortcutsController) { + this._shortcutsController = new ShortcutsController(this.bridge); + } + return this._shortcutsController; + } + get bridge() { + if (!this._bridgeInstance) { + this._bridgeInstance = new Bridge(this.transport, CallbackFactory()); + } + return this._bridgeInstance; + } + get transport() { + if (!this._transportInstance) { + this._transportInstance = new InteropTransport(this.agm, CallbackFactory()); + } + return this._transportInstance; + } + get privateDataManager() { + if (!this._privateDataManagerInstance) { + this._privateDataManagerInstance = new PrivateDataManager(); + } + return this._privateDataManagerInstance; + } + get parentBase() { + if (!this._parentBaseInstance) { + this._parentBaseInstance = new Base(this.privateDataManager); + } + return this._parentBaseInstance; + } + async initiate(actualWindowId) { + await this.transport.initiate(actualWindowId); + } + getModel(type, createConfig) { + switch (type) { + case "frame": { + const newFrame = new Frame(this.privateDataManager); + const { summary } = createConfig; + const frameData = { summary, controller: this.controller }; + this.privateDataManager.setFrameData(newFrame, frameData); + return newFrame; + } + case "window": { + const { id, parent, frame, workspace, config } = createConfig; + const windowPrivateData = { + type: "window", + controller: this.controller, + config, id, parent, frame, workspace + }; + const newWindow = new Window(this.privateDataManager); + this.privateDataManager.setWindowData(newWindow, windowPrivateData); + return newWindow; + } + case "row": + case "column": + case "group": { + const { id, children, parent, frame, workspace, config } = createConfig; + const newParent = type === "column" ? new Column(this.parentBase) : + type === "row" ? new Row(this.parentBase) : new Group(this.parentBase); + const builtChildren = this.buildChildren(children, frame, workspace, newParent); + const parentPrivateData = { + id, parent, frame, workspace, + config, + type, + controller: this.controller, + children: builtChildren, + }; + this.privateDataManager.setParentData(newParent, parentPrivateData); + return newParent; + } + case "workspace": { + const { snapshot, frame } = createConfig; + const newWorkspace = new Workspace(this.privateDataManager); + const children = this.buildChildren(snapshot.children, frame, newWorkspace, newWorkspace); + const workspacePrivateData = { + id: snapshot.id, + type: "workspace", + config: snapshot.config, + base: this.parentBase, + controller: this.controller, + children, frame, ioc: this + }; + this.privateDataManager.setWorkspaceData(newWorkspace, workspacePrivateData); + return newWorkspace; + } + default: throw new Error(`Unrecognized type: ${type}`); + } + } + getBuilder(config) { + config.definition = config.definition || {}; + if (!Array.isArray(config.definition.children)) { + config.definition.children = []; + } + const baseBuilder = new BaseBuilder(this.getBuilder.bind(this)); + switch (config.type) { + case "workspace": { + return new WorkspaceBuilder(config.definition, baseBuilder, this.controller); + } + case "row": + case "column": + case "group": { + config.definition.type = config.type; + return new ParentBuilder(config.definition, baseBuilder); + } + default: throw new Error(`Unexpected Builder creation error, provided config: ${JSON.stringify(config)}`); + } + } + buildChildren(children, frame, workspace, parent) { + return children.map((child) => { + switch (child.type) { + case "window": return this.getModel("window", { + id: child.id, + config: child.config, + frame, workspace, parent + }); + case "column": return this.getModel(child.type, { + id: child.id, + config: child.config, + children: child.children, + frame, workspace, parent + }); + case "row": return this.getModel(child.type, { + id: child.id, + config: child.config, + children: child.children, + frame, workspace, parent + }); + case "group": return this.getModel(child.type, { + id: child.id, + config: child.config, + children: child.children, + frame, workspace, parent + }); + default: throw new Error(`Unsupported child type: ${child.type}`); + } + }); + } + } + + var version = "3.5.6"; + + const composeAPI = (glue, ioc) => { + const controller = ioc.controller; + const inWorkspace = () => { + const myId = glue.windows.my().id; + if (!myId) { + throw new Error("Cannot get my frame, because my id is undefined."); + } + return controller.checkIsInSwimlane(myId); + }; + const getBuilder = (config) => { + const validatedConfig = builderConfigDecoder.runWithException(config); + return ioc.getBuilder(validatedConfig); + }; + const getMyFrame = async () => { + const windowId = glue.windows.my().id; + if (!windowId) { + throw new Error("Cannot get my frame, because my id is undefined."); + } + const isInSwimlane = await controller.checkIsInSwimlane(windowId); + if (!isInSwimlane) { + throw new Error("Cannot fetch your frame, because this window is not in a workspace"); + } + return controller.getFrame({ windowId }); + }; + const getFrame = async (predicate) => { + checkThrowCallback(predicate); + return controller.getFrame({ predicate }); + }; + const getAllFrames = async (predicate) => { + checkThrowCallback(predicate, true); + return controller.getFrames(predicate); + }; + const getAllWorkspacesSummaries = () => { + return controller.getAllWorkspaceSummaries(); + }; + const getMyWorkspace = async () => { + const myId = glue.windows.my().id; + if (!myId) { + throw new Error("Cannot get my workspace, because my id is undefined."); + } + const isInSwimlane = await controller.checkIsInSwimlane(myId); + if (!isInSwimlane) { + throw new Error("Cannot fetch your workspace, because this window is not in a workspace"); + } + return await controller.getWorkspaceByWindowId(myId); + }; + const getWorkspace = async (predicate) => { + checkThrowCallback(predicate); + return (await controller.getWorkspaces(predicate))[0]; + }; + const getWorkspaceById = async (workspaceId) => { + nonEmptyStringDecoder.runWithException(workspaceId); + return controller.getWorkspaceById(workspaceId); + }; + const getAllWorkspaces = (predicate) => { + checkThrowCallback(predicate, true); + return controller.getWorkspaces(predicate); + }; + const getWindow = async (predicate) => { + checkThrowCallback(predicate); + return controller.getWindow(predicate); + }; + const getParent = async (predicate) => { + checkThrowCallback(predicate); + return controller.getParent(predicate); + }; + const restoreWorkspace = async (name, options) => { + nonEmptyStringDecoder.runWithException(name); + const validatedOptions = restoreWorkspaceConfigDecoder.runWithException(options); + return controller.restoreWorkspace(name, validatedOptions); + }; + const createWorkspace = async (definition, saveConfig) => { + const validatedDefinition = workspaceDefinitionDecoder.runWithException(definition); + const validatedConfig = workspaceBuilderCreateConfigDecoder.runWithException(saveConfig); + return controller.createWorkspace(validatedDefinition, validatedConfig); + }; + const createEmptyFrame = async (definition) => { + const validatedDefinition = emptyFrameDefinitionDecoder.runWithException(definition); + return controller.createEmptyFrame(validatedDefinition ?? {}); + }; + const layouts = { + getSummaries: () => { + return controller.getLayoutSummaries(); + }, + delete: async (name) => { + nonEmptyStringDecoder.runWithException(name); + return controller.deleteLayout(name); + }, + export: async (predicate) => { + checkThrowCallback(predicate, true); + return controller.exportLayout(predicate); + }, + import: async (layouts, mode = "replace") => { + if (!Array.isArray(layouts)) { + throw new Error(`The provided layouts argument is not an array: ${JSON.stringify(layouts)}`); + } + layouts.forEach((layout) => workspaceLayoutDecoder.runWithException(layout)); + return controller.importLayouts(layouts, mode); + }, + save: async (config) => { + const verifiedConfig = workspaceLayoutSaveConfigDecoder.runWithException(config); + return controller.saveLayout(verifiedConfig); + }, + onSaved: async (callback) => { + checkThrowCallback(callback); + return controller.handleOnSaved(callback); + }, + onRemoved: async (callback) => { + checkThrowCallback(callback); + return controller.handleOnRemoved(callback); + } + }; + const onFrameOpened = async (callback) => { + checkThrowCallback(callback); + const wrappedCallback = (payload) => { + const frameConfig = { + summary: payload.frameSummary + }; + const frame = ioc.getModel("frame", frameConfig); + callback(frame); + }; + const unsubscribe = await controller.processGlobalSubscription(wrappedCallback, "frame", "opened"); + return unsubscribe; + }; + const onFrameClosed = async (callback) => { + checkThrowCallback(callback); + const wrappedCallback = (payload) => { + callback({ frameId: payload.frameSummary.id, frameBounds: payload.frameBounds }); + }; + const unsubscribe = await controller.processGlobalSubscription(wrappedCallback, "frame", "closed"); + return unsubscribe; + }; + const onWorkspaceOpened = async (callback) => { + checkThrowCallback(callback); + const wrappedCallback = async (payload) => { + const workspace = await controller.transformStreamPayloadToWorkspace(payload); + callback(workspace); + }; + const unsubscribe = await controller.processGlobalSubscription(wrappedCallback, "workspace", "opened"); + return unsubscribe; + }; + const onWorkspaceClosed = async (callback) => { + checkThrowCallback(callback); + const wrappedCallback = (payload) => { + callback({ frameId: payload.frameSummary.id, workspaceId: payload.workspaceSummary.id, frameBounds: payload.frameBounds }); + }; + const unsubscribe = await controller.processGlobalSubscription(wrappedCallback, "workspace", "closed"); + return unsubscribe; + }; + const onWorkspaceHibernated = async (callback) => { + checkThrowCallback(callback); + const wrappedCallback = async (payload) => { + const workspace = await controller.transformStreamPayloadToWorkspace(payload); + callback(workspace); + }; + const unsubscribe = await controller.processGlobalSubscription(wrappedCallback, "workspace", "hibernated"); + return unsubscribe; + }; + const onWorkspaceResumed = async (callback) => { + checkThrowCallback(callback); + const wrappedCallback = async (payload) => { + const workspace = await controller.transformStreamPayloadToWorkspace(payload); + callback(workspace); + }; + const unsubscribe = await controller.processGlobalSubscription(wrappedCallback, "workspace", "resumed"); + return unsubscribe; + }; + const onWindowAdded = async (callback) => { + checkThrowCallback(callback); + const wrappedCallback = async (payload) => { + const snapshot = (await controller.getSnapshot(payload.windowSummary.config.workspaceId, "workspace")); + const frameConfig = { + summary: snapshot.frameSummary + }; + const frame = ioc.getModel("frame", frameConfig); + const workspaceConfig = { frame, snapshot }; + const workspace = ioc.getModel("workspace", workspaceConfig); + const windowParent = workspace.getBox((parent) => parent.id === payload.windowSummary.parentId); + const foundWindow = windowParent.children.find((child) => child.type === "window" && child.elementId === payload.windowSummary.itemId); + callback(foundWindow); + }; + const unsubscribe = await controller.processGlobalSubscription(wrappedCallback, "window", "added"); + return unsubscribe; + }; + const onWindowLoaded = async (callback) => { + checkThrowCallback(callback); + const wrappedCallback = async (payload) => { + const snapshot = (await controller.getSnapshot(payload.windowSummary.config.workspaceId, "workspace")); + const frameConfig = { + summary: snapshot.frameSummary + }; + const frame = ioc.getModel("frame", frameConfig); + const workspaceConfig = { frame, snapshot }; + const workspace = ioc.getModel("workspace", workspaceConfig); + const foundWindow = workspace.getWindow((win) => win.id && win.id === payload.windowSummary.config.windowId); + callback(foundWindow); + }; + const unsubscribe = await controller.processGlobalSubscription(wrappedCallback, "window", "loaded"); + return unsubscribe; + }; + const onWindowRemoved = async (callback) => { + checkThrowCallback(callback); + const wrappedCallback = (payload) => { + const { windowId, workspaceId, frameId } = payload.windowSummary.config; + callback({ windowId, workspaceId, frameId }); + }; + const unsubscribe = await controller.processGlobalSubscription(wrappedCallback, "window", "removed"); + return unsubscribe; + }; + const onWindowMaximized = async (callback) => { + checkThrowCallback(callback); + const wrappedCallback = async (payload) => { + const snapshot = (await controller.getSnapshot(payload.windowSummary.config.workspaceId, "workspace")); + const frameConfig = { + summary: snapshot.frameSummary + }; + const frame = ioc.getModel("frame", frameConfig); + const workspaceConfig = { frame, snapshot }; + const workspace = ioc.getModel("workspace", workspaceConfig); + const windowParent = workspace.getBox((parent) => parent.id === payload.windowSummary.parentId); + const foundWindow = windowParent.children.find((child) => child.type === "window" && child.elementId === payload.windowSummary.itemId); + callback(foundWindow); + }; + const unsubscribe = await controller.processGlobalSubscription(wrappedCallback, "window", "maximized"); + return unsubscribe; + }; + const onWindowRestored = async (callback) => { + checkThrowCallback(callback); + const wrappedCallback = async (payload) => { + const snapshot = (await controller.getSnapshot(payload.windowSummary.config.workspaceId, "workspace")); + const frameConfig = { + summary: snapshot.frameSummary + }; + const frame = ioc.getModel("frame", frameConfig); + const workspaceConfig = { frame, snapshot }; + const workspace = ioc.getModel("workspace", workspaceConfig); + const windowParent = workspace.getBox((parent) => parent.id === payload.windowSummary.parentId); + const foundWindow = windowParent.children.find((child) => child.type === "window" && child.elementId === payload.windowSummary.itemId); + callback(foundWindow); + }; + const unsubscribe = await controller.processGlobalSubscription(wrappedCallback, "window", "restored"); + return unsubscribe; + }; + const onWindowSelected = async (callback) => { + checkThrowCallback(callback); + const wrappedCallback = async (payload) => { + const snapshot = (await controller.getSnapshot(payload.windowSummary.config.workspaceId, "workspace")); + const frameConfig = { + summary: snapshot.frameSummary + }; + const frame = ioc.getModel("frame", frameConfig); + const workspaceConfig = { frame, snapshot }; + const workspace = ioc.getModel("workspace", workspaceConfig); + const windowParent = workspace.getBox((parent) => parent.id === payload.windowSummary.parentId); + const foundWindow = windowParent.children.find((child) => child.type === "window" && child.elementId === payload.windowSummary.itemId); + callback(foundWindow); + }; + const unsubscribe = await controller.processGlobalSubscription(wrappedCallback, "window", "selected"); + return unsubscribe; + }; + const waitForFrame = async (id) => { + nonEmptyStringDecoder.runWithException(id); + return new Promise((res, rej) => { + let unsub = () => { + }; + onFrameOpened((f) => { + if (f.id === id) { + res(f); + unsub(); + } + }).then((u) => { + unsub = u; + return getAllFrames(); + }).then((frames) => { + const myFrame = frames.find((f) => f.id === id); + if (myFrame) { + res(myFrame); + unsub(); + } + }).catch(rej); + }); + }; + return { + inWorkspace, + getBuilder, + getMyFrame, + getFrame, + getAllFrames, + getAllWorkspacesSummaries, + getMyWorkspace, + getWorkspace, + getWorkspaceById, + getAllWorkspaces, + getWindow, + getBox: getParent, + restoreWorkspace, + createWorkspace, + createEmptyFrame, + waitForFrame, + layouts, + onFrameOpened, + onFrameClosed, + onWorkspaceOpened, + onWorkspaceClosed, + onWorkspaceHibernated, + onWorkspaceResumed, + onWindowAdded, + onWindowLoaded, + onWindowRemoved, + onWindowMaximized, + onWindowRestored, + onWindowSelected, + version + }; + }; + + const factoryFunction = async (io) => { + const ioc = new IoC(io.agm, io.windows, io.layouts, io.contexts); + const actualWindowId = io.interop.instance.windowId; + await ioc.initiate(actualWindowId); + io.workspaces = composeAPI(io, ioc); + }; + if (typeof window !== "undefined") { + window.IOWorkspaces = factoryFunction; + } + + return factoryFunction; + +})); +//# sourceMappingURL=workspaces.umd.js.map diff --git a/typescript/start/client-details/tsconfig.json b/typescript/start/client-details/tsconfig.json new file mode 100644 index 0000000..11ec879 --- /dev/null +++ b/typescript/start/client-details/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "./dist", + "rootDir": "./src" + }, + "include": ["./src", "../../types"] +} \ No newline at end of file diff --git a/typescript/start/client-details/webpack.config.js b/typescript/start/client-details/webpack.config.js new file mode 100644 index 0000000..919ae75 --- /dev/null +++ b/typescript/start/client-details/webpack.config.js @@ -0,0 +1,31 @@ +const path = require('path'); +const CopyWebpackPlugin = require('copy-webpack-plugin'); + +module.exports = { + mode: 'development', + entry: './src/index.ts', + module: { + rules: [ + { + test: /\.tsx?$/, + use: 'ts-loader', + exclude: /node_modules/, + }, + ], + }, + resolve: { + extensions: ['.tsx', '.ts', '.js'], + }, + output: { + filename: 'index.js', + path: path.resolve(__dirname, 'dist'), + }, + plugins: [ + new CopyWebpackPlugin({ + patterns: [ + { from: 'src/index.html', to: 'index.html' }, + { from: '../../../javascript/start/client-details/lib', to: 'lib' } + ], + }), + ], +}; \ No newline at end of file diff --git a/typescript/start/clients/esbuild.js b/typescript/start/clients/esbuild.js new file mode 100644 index 0000000..27c80dc --- /dev/null +++ b/typescript/start/clients/esbuild.js @@ -0,0 +1,48 @@ +const fs = require('fs'); +const path = require('path'); +const { build } = require('esbuild'); + +// Directory paths +const srcDir = path.join(__dirname, 'src'); +const distDir = path.join(__dirname, 'dist'); + +// Ensure dist directory exists +if (!fs.existsSync(distDir)) { + fs.mkdirSync(distDir, { recursive: true }); +} + +// Copy HTML file +fs.copyFileSync( + path.join(srcDir, 'index.html'), + path.join(distDir, 'index.html') +); + +// Copy lib directory +const libSrcDir = path.join(srcDir, 'lib'); +const libDistDir = path.join(distDir, 'lib'); + +if (!fs.existsSync(libDistDir)) { + fs.mkdirSync(libDistDir, { recursive: true }); +} + +fs.readdirSync(libSrcDir).forEach(file => { + fs.copyFileSync( + path.join(libSrcDir, file), + path.join(libDistDir, file) + ); +}); + +// Build with esbuild +build({ + entryPoints: [path.join(srcDir, 'index.ts')], + bundle: true, + outfile: path.join(distDir, 'index.js'), + platform: 'browser', + format: 'iife', + sourcemap: true, + target: ['es2020'], + tsconfig: path.join(__dirname, 'tsconfig.json'), +}).catch((error) => { + console.error(error); + process.exit(1); +}); \ No newline at end of file diff --git a/typescript/start/clients/src/index.html b/typescript/start/clients/src/index.html new file mode 100644 index 0000000..9822066 --- /dev/null +++ b/typescript/start/clients/src/index.html @@ -0,0 +1,55 @@ + + + + + + + + + + + + Clients + + + + + + + + + + + +
+
+
+
+ io.Connect is unavailable +
+
+ +
+
+
+

Clients

+
+
+
+ + + + + + + + + + + +
Full NamePIDGIDAccount Manager
+
+
+ + + diff --git a/typescript/start/clients/src/index.ts b/typescript/start/clients/src/index.ts new file mode 100644 index 0000000..bf89eca --- /dev/null +++ b/typescript/start/clients/src/index.ts @@ -0,0 +1,101 @@ +const setupClients = (clients: Client[]): void => { + const table = document.getElementById("clientsTable")?.getElementsByTagName("tbody")[0]; + if (!table) return; + + const addRowCell = (row: HTMLTableRowElement, cellData: string, cssClass?: string): void => { + const cell = document.createElement("td"); + + cell.innerText = cellData; + + if (cssClass) { + cell.className = cssClass; + } + + row.appendChild(cell); + }; + + const addRow = (table: HTMLTableSectionElement, client: Client): void => { + const row = document.createElement("tr"); + + addRowCell(row, client.name || ""); + addRowCell(row, client.pId || ""); + addRowCell(row, client.gId || ""); + addRowCell(row, client.accountManager || ""); + + row.onclick = () => { + clientClickedHandler(client); + }; + + table.appendChild(row); + }; + + clients.forEach((client) => { + addRow(table, client); + }); +}; + +// TODO: Chapter 3 +// const toggleIOAvailable = (): void => { +// const span = document.getElementById("ioConnectSpan"); +// if (!span) return; + +// span.classList.remove("bg-danger"); +// span.classList.add("bg-success"); +// span.textContent = "io.Connect is available"; +// }; + +const clientClickedHandler = async (client: Client): Promise => { + // TODO: Chapter 5.2 + + // TODO: Chapter 5.3 + + // TODO: Chapter 6.1 + + // TODO: Chapter 7.2 + + // TODO: Chapter 9.3 +}; + +let counter = 1; + +const stocksButtonHandler = (): void => { + const instanceID = sessionStorage.getItem("counter"); + + // TODO: Chapter 4.1 + + counter++; + sessionStorage.setItem("counter", counter.toString()); + + // TODO: Chapter 8.1 +}; + +const raiseNotificationOnWorkspaceOpen = async (clientName: string, workspace: Workspace): Promise => { + // TODO: Chapter 11.1 +}; + +const start = async (): Promise => { + const clientsResponse = await fetch("http://localhost:8080/api/clients"); + const clients = await clientsResponse.json() as Client[]; + + setupClients(clients); + + const stocksButton = document.getElementById("stocks-btn"); + if (stocksButton) { + stocksButton.onclick = stocksButtonHandler; + } + + // TODO: Chapter 3 + + // TODO: Chapter 12.1 + + // TODO: Chapter 13 +}; + +// Add io property to window object when needed +declare global { + interface Window { + io?: IODesktopAPI; + } +} + +start().catch(console.error); \ No newline at end of file diff --git a/typescript/start/clients/src/lib/desktop.umd.js b/typescript/start/clients/src/lib/desktop.umd.js new file mode 100644 index 0000000..6cea2c9 --- /dev/null +++ b/typescript/start/clients/src/lib/desktop.umd.js @@ -0,0 +1,23144 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define(factory) : + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.desktop = factory()); +})(this, (function () { 'use strict'; + + var MetricTypes = { + STRING: 1, + NUMBER: 2, + TIMESTAMP: 3, + OBJECT: 4 + }; + + function getMetricTypeByValue(metric) { + if (metric.type === MetricTypes.TIMESTAMP) { + return "timestamp"; + } + else if (metric.type === MetricTypes.NUMBER) { + return "number"; + } + else if (metric.type === MetricTypes.STRING) { + return "string"; + } + else if (metric.type === MetricTypes.OBJECT) { + return "object"; + } + return "unknown"; + } + function getTypeByValue(value) { + if (value.constructor === Date) { + return "timestamp"; + } + else if (typeof value === "number") { + return "number"; + } + else if (typeof value === "string") { + return "string"; + } + else if (typeof value === "object") { + return "object"; + } + else { + return "string"; + } + } + function serializeMetric(metric) { + const serializedMetrics = {}; + const type = getMetricTypeByValue(metric); + if (type === "object") { + const values = Object.keys(metric.value).reduce((memo, key) => { + const innerType = getTypeByValue(metric.value[key]); + if (innerType === "object") { + const composite = defineNestedComposite(metric.value[key]); + memo[key] = { + type: "object", + description: "", + context: {}, + composite, + }; + } + else { + memo[key] = { + type: innerType, + description: "", + context: {}, + }; + } + return memo; + }, {}); + serializedMetrics.composite = values; + } + serializedMetrics.name = normalizeMetricName(metric.path.join("/") + "/" + metric.name); + serializedMetrics.type = type; + serializedMetrics.description = metric.description; + serializedMetrics.context = {}; + return serializedMetrics; + } + function defineNestedComposite(values) { + return Object.keys(values).reduce((memo, key) => { + const type = getTypeByValue(values[key]); + if (type === "object") { + memo[key] = { + type: "object", + description: "", + context: {}, + composite: defineNestedComposite(values[key]), + }; + } + else { + memo[key] = { + type, + description: "", + context: {}, + }; + } + return memo; + }, {}); + } + function normalizeMetricName(name) { + if (typeof name !== "undefined" && name.length > 0 && name[0] !== "/") { + return "/" + name; + } + else { + return name; + } + } + function getMetricValueByType(metric) { + const type = getMetricTypeByValue(metric); + if (type === "timestamp") { + return Date.now(); + } + else { + return publishNestedComposite(metric.value); + } + } + function publishNestedComposite(values) { + if (typeof values !== "object") { + return values; + } + return Object.keys(values).reduce((memo, key) => { + const value = values[key]; + if (typeof value === "object" && value.constructor !== Date) { + memo[key] = publishNestedComposite(value); + } + else if (value.constructor === Date) { + memo[key] = new Date(value).getTime(); + } + else if (value.constructor === Boolean) { + memo[key] = value.toString(); + } + else { + memo[key] = value; + } + return memo; + }, {}); + } + function flatten(arr) { + return arr.reduce((flat, toFlatten) => { + return flat.concat(Array.isArray(toFlatten) ? flatten(toFlatten) : toFlatten); + }, []); + } + function getHighestState(arr) { + return arr.sort((a, b) => { + if (!a.state) { + return 1; + } + if (!b.state) { + return -1; + } + return b.state - a.state; + })[0]; + } + function aggregateDescription(arr) { + let msg = ""; + arr.forEach((m, idx, a) => { + const path = m.path.join("."); + if (idx === a.length - 1) { + msg += path + "." + m.name + ": " + m.description; + } + else { + msg += path + "." + m.name + ": " + m.description + ","; + } + }); + if (msg.length > 100) { + return msg.slice(0, 100) + "..."; + } + else { + return msg; + } + } + function composeMsgForRootStateMetric(system) { + const aggregatedState = system.root.getAggregateState(); + const merged = flatten(aggregatedState); + const highestState = getHighestState(merged); + const aggregateDesc = aggregateDescription(merged); + return { + description: aggregateDesc, + value: highestState.state, + }; + } + + function gw3 (connection, config) { + if (!connection || typeof connection !== "object") { + throw new Error("Connection is required parameter"); + } + let joinPromise; + let session; + const init = (repo) => { + let resolveReadyPromise; + joinPromise = new Promise((resolve) => { + resolveReadyPromise = resolve; + }); + session = connection.domain("metrics"); + session.onJoined((reconnect) => { + if (!reconnect && resolveReadyPromise) { + resolveReadyPromise(); + resolveReadyPromise = undefined; + } + const rootStateMetric = { + name: "/State", + type: "object", + composite: { + Description: { + type: "string", + description: "", + }, + Value: { + type: "number", + description: "", + }, + }, + description: "System state", + context: {}, + }; + const defineRootMetricsMsg = { + type: "define", + metrics: [rootStateMetric], + }; + session.send(defineRootMetricsMsg); + if (reconnect) { + replayRepo(repo); + } + }); + session.join({ + system: config.system, + service: config.service, + instance: config.instance + }); + }; + const replayRepo = (repo) => { + replaySystem(repo.root); + }; + const replaySystem = (system) => { + createSystem(system); + system.metrics.forEach((m) => { + createMetric(m); + }); + system.subSystems.forEach((ss) => { + replaySystem(ss); + }); + }; + const createSystem = async (system) => { + if (system.parent === undefined) { + return; + } + await joinPromise; + const metric = { + name: normalizeMetricName(system.path.join("/") + "/" + system.name + "/State"), + type: "object", + composite: { + Description: { + type: "string", + description: "", + }, + Value: { + type: "number", + description: "", + }, + }, + description: "System state", + context: {}, + }; + const createMetricsMsg = { + type: "define", + metrics: [metric], + }; + session.send(createMetricsMsg); + }; + const updateSystem = async (system, state) => { + await joinPromise; + const shadowedUpdateMetric = { + type: "publish", + values: [{ + name: normalizeMetricName(system.path.join("/") + "/" + system.name + "/State"), + value: { + Description: state.description, + Value: state.state, + }, + timestamp: Date.now(), + }], + }; + session.send(shadowedUpdateMetric); + const stateObj = composeMsgForRootStateMetric(system); + const rootMetric = { + type: "publish", + peer_id: connection.peerId, + values: [{ + name: "/State", + value: { + Description: stateObj.description, + Value: stateObj.value, + }, + timestamp: Date.now(), + }], + }; + session.send(rootMetric); + }; + const createMetric = async (metric) => { + const metricClone = cloneMetric(metric); + await joinPromise; + const m = serializeMetric(metricClone); + const createMetricsMsg = { + type: "define", + metrics: [m], + }; + session.send(createMetricsMsg); + if (typeof metricClone.value !== "undefined") { + updateMetricCore(metricClone); + } + }; + const updateMetric = async (metric) => { + const metricClone = cloneMetric(metric); + await joinPromise; + updateMetricCore(metricClone); + }; + const updateMetricCore = (metric) => { + if (canUpdate()) { + const value = getMetricValueByType(metric); + const publishMetricsMsg = { + type: "publish", + values: [{ + name: normalizeMetricName(metric.path.join("/") + "/" + metric.name), + value, + timestamp: Date.now(), + }], + }; + return session.sendFireAndForget(publishMetricsMsg); + } + return Promise.resolve(); + }; + const cloneMetric = (metric) => { + const metricClone = { ...metric }; + if (typeof metric.value === "object" && metric.value !== null) { + metricClone.value = { ...metric.value }; + } + return metricClone; + }; + const canUpdate = () => { + try { + const func = config.canUpdateMetric ?? (() => true); + return func(); + } + catch { + return true; + } + }; + return { + init, + createSystem, + updateSystem, + createMetric, + updateMetric, + }; + } + + var Helpers = { + validate: (definition, parent, transport) => { + if (definition === null || typeof definition !== "object") { + throw new Error("Missing definition"); + } + if (parent === null || typeof parent !== "object") { + throw new Error("Missing parent"); + } + if (transport === null || typeof transport !== "object") { + throw new Error("Missing transport"); + } + }, + }; + + class BaseMetric { + definition; + system; + transport; + value; + type; + path = []; + name; + description; + get repo() { + return this.system?.repo; + } + get id() { return `${this.system.path}/${name}`; } + constructor(definition, system, transport, value, type) { + this.definition = definition; + this.system = system; + this.transport = transport; + this.value = value; + this.type = type; + Helpers.validate(definition, system, transport); + this.path = system.path.slice(0); + this.path.push(system.name); + this.name = definition.name; + this.description = definition.description; + transport.createMetric(this); + } + update(newValue) { + this.value = newValue; + return this.transport.updateMetric(this); + } + } + + class NumberMetric extends BaseMetric { + constructor(definition, system, transport, value) { + super(definition, system, transport, value, MetricTypes.NUMBER); + } + incrementBy(num) { + this.update(this.value + num); + } + increment() { + this.incrementBy(1); + } + decrement() { + this.incrementBy(-1); + } + decrementBy(num) { + this.incrementBy(num * -1); + } + } + + class ObjectMetric extends BaseMetric { + constructor(definition, system, transport, value) { + super(definition, system, transport, value, MetricTypes.OBJECT); + } + update(newValue) { + this.mergeValues(newValue); + return this.transport.updateMetric(this); + } + mergeValues(values) { + return Object.keys(this.value).forEach((k) => { + if (typeof values[k] !== "undefined") { + this.value[k] = values[k]; + } + }); + } + } + + class StringMetric extends BaseMetric { + constructor(definition, system, transport, value) { + super(definition, system, transport, value, MetricTypes.STRING); + } + } + + class TimestampMetric extends BaseMetric { + constructor(definition, system, transport, value) { + super(definition, system, transport, value, MetricTypes.TIMESTAMP); + } + now() { + this.update(new Date()); + } + } + + function system$1(name, repo, protocol, parent, description) { + if (!repo) { + throw new Error("Repository is required"); + } + if (!protocol) { + throw new Error("Transport is required"); + } + const _transport = protocol; + const _name = name; + const _description = description || ""; + const _repo = repo; + const _parent = parent; + const _path = _buildPath(parent); + let _state = {}; + const id = _arrayToString(_path, "/") + name; + const root = repo.root; + const _subSystems = []; + const _metrics = []; + function subSystem(nameSystem, descriptionSystem) { + if (!nameSystem || nameSystem.length === 0) { + throw new Error("name is required"); + } + const match = _subSystems.filter((s) => s.name === nameSystem); + if (match.length > 0) { + return match[0]; + } + const _system = system$1(nameSystem, _repo, _transport, me, descriptionSystem); + _subSystems.push(_system); + return _system; + } + function setState(state, stateDescription) { + _state = { state, description: stateDescription }; + _transport.updateSystem(me, _state); + } + function stringMetric(definition, value) { + return _getOrCreateMetric(definition, MetricTypes.STRING, value, (metricDef) => new StringMetric(metricDef, me, _transport, value)); + } + function numberMetric(definition, value) { + return _getOrCreateMetric(definition, MetricTypes.NUMBER, value, (metricDef) => new NumberMetric(metricDef, me, _transport, value)); + } + function objectMetric(definition, value) { + return _getOrCreateMetric(definition, MetricTypes.OBJECT, value, (metricDef) => new ObjectMetric(metricDef, me, _transport, value)); + } + function timestampMetric(definition, value) { + return _getOrCreateMetric(definition, MetricTypes.TIMESTAMP, value, (metricDef) => new TimestampMetric(metricDef, me, _transport, value)); + } + function _getOrCreateMetric(metricObject, expectedType, value, createMetric) { + let metricDef = { name: "" }; + if (typeof metricObject === "string") { + metricDef = { name: metricObject }; + } + else { + metricDef = metricObject; + } + const matching = _metrics.filter((shadowedMetric) => shadowedMetric.name === metricDef.name); + if (matching.length > 0) { + const existing = matching[0]; + if (existing.type !== expectedType) { + throw new Error(`A metric named ${metricDef.name} is already defined with different type.`); + } + if (typeof value !== "undefined") { + existing + .update(value) + .catch(() => { }); + } + return existing; + } + const metric = createMetric(metricDef); + _metrics.push(metric); + return metric; + } + function _buildPath(shadowedSystem) { + if (!shadowedSystem || !shadowedSystem.parent) { + return []; + } + const path = _buildPath(shadowedSystem.parent); + path.push(shadowedSystem.name); + return path; + } + function _arrayToString(path, separator) { + return ((path && path.length > 0) ? path.join(separator) : ""); + } + function getAggregateState() { + const aggState = []; + if (Object.keys(_state).length > 0) { + aggState.push({ + name: _name, + path: _path, + state: _state.state, + description: _state.description, + }); + } + _subSystems.forEach((shadowedSubSystem) => { + const result = shadowedSubSystem.getAggregateState(); + if (result.length > 0) { + aggState.push(...result); + } + }); + return aggState; + } + const me = { + get name() { + return _name; + }, + get description() { + return _description; + }, + get repo() { + return _repo; + }, + get parent() { + return _parent; + }, + path: _path, + id, + root, + get subSystems() { + return _subSystems; + }, + get metrics() { + return _metrics; + }, + subSystem, + getState: () => { + return _state; + }, + setState, + stringMetric, + timestampMetric, + objectMetric, + numberMetric, + getAggregateState, + }; + _transport.createSystem(me); + return me; + } + + class Repository { + root; + constructor(options, protocol) { + protocol.init(this); + this.root = system$1("", this, protocol); + this.addSystemMetrics(this.root, options.clickStream || options.clickStream === undefined); + } + addSystemMetrics(rootSystem, useClickStream) { + if (typeof navigator !== "undefined") { + rootSystem.stringMetric("UserAgent", navigator.userAgent); + } + if (useClickStream && typeof document !== "undefined") { + const clickStream = rootSystem.subSystem("ClickStream"); + const documentClickHandler = (e) => { + if (!e.target) { + return; + } + const target = e.target; + const className = target ? target.getAttribute("class") ?? "" : ""; + clickStream.objectMetric("LastBrowserEvent", { + type: "click", + timestamp: new Date(), + target: { + className, + id: target.id, + type: "<" + target.tagName.toLowerCase() + ">", + href: target.href || "", + }, + }); + }; + clickStream.objectMetric("Page", { + title: document.title, + page: window.location.href, + }); + if (document.addEventListener) { + document.addEventListener("click", documentClickHandler); + } + else { + document.attachEvent("onclick", documentClickHandler); + } + } + rootSystem.stringMetric("StartTime", (new Date()).toString()); + const urlMetric = rootSystem.stringMetric("StartURL", ""); + const appNameMetric = rootSystem.stringMetric("AppName", ""); + if (typeof window !== "undefined") { + if (typeof window.location !== "undefined") { + const startUrl = window.location.href; + urlMetric.update(startUrl); + } + if (typeof window.glue42gd !== "undefined") { + appNameMetric.update(window.glue42gd.appName); + } + } + } + } + + class NullProtocol { + init(repo) { + } + createSystem(system) { + return Promise.resolve(); + } + updateSystem(metric, state) { + return Promise.resolve(); + } + createMetric(metric) { + return Promise.resolve(); + } + updateMetric(metric) { + return Promise.resolve(); + } + } + + class PerfTracker { + api; + lastCount = 0; + initialPublishTimeout = 10 * 1000; + publishInterval = 60 * 1000; + system; + constructor(api, initialPublishTimeout, publishInterval) { + this.api = api; + this.initialPublishTimeout = initialPublishTimeout ?? this.initialPublishTimeout; + this.publishInterval = publishInterval ?? this.publishInterval; + this.scheduleCollection(); + this.system = this.api.subSystem("performance", "Performance data published by the web application"); + } + scheduleCollection() { + setTimeout(() => { + this.collect(); + setInterval(() => { + this.collect(); + }, this.publishInterval); + }, this.initialPublishTimeout); + } + collect() { + try { + this.collectMemory(); + this.collectEntries(); + } + catch { + } + } + collectMemory() { + const memory = window.performance.memory; + this.system.stringMetric("memory", JSON.stringify({ + totalJSHeapSize: memory.totalJSHeapSize, + usedJSHeapSize: memory.usedJSHeapSize + })); + } + collectEntries() { + const allEntries = window.performance.getEntries(); + if (allEntries.length <= this.lastCount) { + return; + } + this.lastCount = allEntries.length; + const jsonfiedEntries = allEntries.map((i) => i.toJSON()); + this.system.stringMetric("entries", JSON.stringify(jsonfiedEntries)); + } + } + + var metrics = (options) => { + let protocol; + if (!options.connection || typeof options.connection !== "object") { + protocol = new NullProtocol(); + } + else { + protocol = gw3(options.connection, options); + } + const repo = new Repository(options, protocol); + let rootSystem = repo.root; + if (!options.disableAutoAppSystem) { + rootSystem = rootSystem.subSystem("App"); + } + const api = addFAVSupport(rootSystem); + initPerf(api, options.pagePerformanceMetrics); + return api; + }; + function initPerf(api, config) { + if (typeof window === "undefined") { + return; + } + const perfConfig = window?.glue42gd?.metrics?.pagePerformanceMetrics; + if (perfConfig) { + config = perfConfig; + } + if (config?.enabled) { + new PerfTracker(api, config.initialPublishTimeout, config.publishInterval); + } + } + function addFAVSupport(system) { + const reportingSystem = system.subSystem("reporting"); + const def = { + name: "features" + }; + let featureMetric; + const featureMetricFunc = (name, action, payload) => { + if (typeof name === "undefined" || name === "") { + throw new Error("name is mandatory"); + } + else if (typeof action === "undefined" || action === "") { + throw new Error("action is mandatory"); + } + else if (typeof payload === "undefined" || payload === "") { + throw new Error("payload is mandatory"); + } + if (!featureMetric) { + featureMetric = reportingSystem.objectMetric(def, { name, action, payload }); + } + else { + featureMetric.update({ + name, + action, + payload + }); + } + }; + system.featureMetric = featureMetricFunc; + return system; + } + + var commonjsGlobal$1 = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; + + function getDefaultExportFromCjs$1 (x) { + return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; + } + + function createRegistry$1(options) { + if (options && options.errorHandling + && typeof options.errorHandling !== "function" + && options.errorHandling !== "log" + && options.errorHandling !== "silent" + && options.errorHandling !== "throw") { + throw new Error("Invalid options passed to createRegistry. Prop errorHandling should be [\"log\" | \"silent\" | \"throw\" | (err) => void], but " + typeof options.errorHandling + " was passed"); + } + var _userErrorHandler = options && typeof options.errorHandling === "function" && options.errorHandling; + var callbacks = {}; + function add(key, callback, replayArgumentsArr) { + var callbacksForKey = callbacks[key]; + if (!callbacksForKey) { + callbacksForKey = []; + callbacks[key] = callbacksForKey; + } + callbacksForKey.push(callback); + if (replayArgumentsArr) { + setTimeout(function () { + replayArgumentsArr.forEach(function (replayArgument) { + var _a; + if ((_a = callbacks[key]) === null || _a === void 0 ? void 0 : _a.includes(callback)) { + try { + if (Array.isArray(replayArgument)) { + callback.apply(undefined, replayArgument); + } + else { + callback.apply(undefined, [replayArgument]); + } + } + catch (err) { + _handleError(err, key); + } + } + }); + }, 0); + } + return function () { + var allForKey = callbacks[key]; + if (!allForKey) { + return; + } + allForKey = allForKey.reduce(function (acc, element, index) { + if (!(element === callback && acc.length === index)) { + acc.push(element); + } + return acc; + }, []); + if (allForKey.length === 0) { + delete callbacks[key]; + } + else { + callbacks[key] = allForKey; + } + }; + } + function execute(key) { + var argumentsArr = []; + for (var _i = 1; _i < arguments.length; _i++) { + argumentsArr[_i - 1] = arguments[_i]; + } + var callbacksForKey = callbacks[key]; + if (!callbacksForKey || callbacksForKey.length === 0) { + return []; + } + var results = []; + callbacksForKey.forEach(function (callback) { + try { + var result = callback.apply(undefined, argumentsArr); + results.push(result); + } + catch (err) { + results.push(undefined); + _handleError(err, key); + } + }); + return results; + } + function _handleError(exceptionArtifact, key) { + var errParam = exceptionArtifact instanceof Error ? exceptionArtifact : new Error(exceptionArtifact); + if (_userErrorHandler) { + _userErrorHandler(errParam); + return; + } + var msg = "[ERROR] callback-registry: User callback for key \"" + key + "\" failed: " + errParam.stack; + if (options) { + switch (options.errorHandling) { + case "log": + return console.error(msg); + case "silent": + return; + case "throw": + throw new Error(msg); + } + } + console.error(msg); + } + function clear() { + callbacks = {}; + } + function clearKey(key) { + var callbacksForKey = callbacks[key]; + if (!callbacksForKey) { + return; + } + delete callbacks[key]; + } + return { + add: add, + execute: execute, + clear: clear, + clearKey: clearKey + }; + } + createRegistry$1.default = createRegistry$1; + var lib$1 = createRegistry$1; + + + var CallbackRegistryFactory$1 = /*@__PURE__*/getDefaultExportFromCjs$1(lib$1); + + class InProcTransport { + gw; + registry = CallbackRegistryFactory$1(); + client; + constructor(settings, logger) { + this.gw = settings.facade; + this.gw.connect((_client, message) => { + this.messageHandler(message); + }).then((client) => { + this.client = client; + }); + } + get isObjectBasedTransport() { + return true; + } + sendObject(msg) { + if (this.client) { + this.client.send(msg); + return Promise.resolve(undefined); + } + else { + return Promise.reject(`not connected`); + } + } + send(_msg) { + return Promise.reject("not supported"); + } + onMessage(callback) { + return this.registry.add("onMessage", callback); + } + onConnectedChanged(callback) { + callback(true); + return () => { }; + } + close() { + return Promise.resolve(); + } + open() { + return Promise.resolve(); + } + name() { + return "in-memory"; + } + reconnect() { + return Promise.resolve(); + } + messageHandler(msg) { + this.registry.execute("onMessage", msg); + } + } + + class SharedWorkerTransport { + logger; + worker; + registry = CallbackRegistryFactory$1(); + constructor(workerFile, logger) { + this.logger = logger; + this.worker = new SharedWorker(workerFile); + this.worker.port.onmessage = (e) => { + this.messageHandler(e.data); + }; + } + get isObjectBasedTransport() { + return true; + } + sendObject(msg) { + this.worker.port.postMessage(msg); + return Promise.resolve(); + } + send(_msg) { + return Promise.reject("not supported"); + } + onMessage(callback) { + return this.registry.add("onMessage", callback); + } + onConnectedChanged(callback) { + callback(true); + return () => { }; + } + close() { + return Promise.resolve(); + } + open() { + return Promise.resolve(); + } + name() { + return "shared-worker"; + } + reconnect() { + return Promise.resolve(); + } + messageHandler(msg) { + this.registry.execute("onMessage", msg); + } + } + + let Utils$1 = class Utils { + static isNode() { + if (typeof Utils._isNode !== "undefined") { + return Utils._isNode; + } + if (typeof window !== "undefined") { + Utils._isNode = false; + return false; + } + try { + Utils._isNode = Object.prototype.toString.call(global.process) === "[object process]"; + } + catch (e) { + Utils._isNode = false; + } + return Utils._isNode; + } + static _isNode; + }; + + let PromiseWrapper$1 = class PromiseWrapper { + static delay(time) { + return new Promise((resolve) => setTimeout(resolve, time)); + } + resolve; + reject; + promise; + rejected = false; + resolved = false; + get ended() { + return this.rejected || this.resolved; + } + constructor() { + this.promise = new Promise((resolve, reject) => { + this.resolve = (t) => { + this.resolved = true; + resolve(t); + }; + this.reject = (err) => { + this.rejected = true; + reject(err); + }; + }); + } + }; + + const timers = {}; + function getAllTimers() { + return timers; + } + function timer (timerName) { + const existing = timers[timerName]; + if (existing) { + return existing; + } + const marks = []; + function now() { + return new Date().getTime(); + } + const startTime = now(); + mark("start", startTime); + let endTime; + let period; + function stop() { + endTime = now(); + mark("end", endTime); + period = endTime - startTime; + return period; + } + function mark(name, time) { + const currentTime = time ?? now(); + let diff = 0; + if (marks.length > 0) { + diff = currentTime - marks[marks.length - 1].time; + } + marks.push({ name, time: currentTime, diff }); + } + const timerObj = { + get startTime() { + return startTime; + }, + get endTime() { + return endTime; + }, + get period() { + return period; + }, + stop, + mark, + marks + }; + timers[timerName] = timerObj; + return timerObj; + } + + const WebSocketConstructor = Utils$1.isNode() ? require("ws") : window.WebSocket; + class WS { + ws; + logger; + settings; + startupTimer = timer("connection"); + _running = true; + _registry = CallbackRegistryFactory$1(); + wsRequests = []; + constructor(settings, logger) { + this.settings = settings; + this.logger = logger; + if (!this.settings.ws) { + throw new Error("ws is missing"); + } + } + onMessage(callback) { + return this._registry.add("onMessage", callback); + } + send(msg, options) { + return new Promise((resolve, reject) => { + this.waitForSocketConnection(() => { + try { + this.ws?.send(msg); + resolve(); + } + catch (e) { + reject(e); + } + }, reject); + }); + } + open() { + this.logger.info("opening ws..."); + this._running = true; + return new Promise((resolve, reject) => { + this.waitForSocketConnection(resolve, reject); + }); + } + close() { + this._running = false; + if (this.ws) { + this.ws.close(); + } + return Promise.resolve(); + } + onConnectedChanged(callback) { + return this._registry.add("onConnectedChanged", callback); + } + name() { + return this.settings.ws; + } + reconnect() { + this.ws?.close(); + const pw = new PromiseWrapper$1(); + this.waitForSocketConnection(() => { + pw.resolve(); + }); + return pw.promise; + } + waitForSocketConnection(callback, failed) { + failed = failed ?? (() => { }); + if (!this._running) { + failed(`wait for socket on ${this.settings.ws} failed - socket closed by user`); + return; + } + if (this.ws?.readyState === 1) { + callback(); + return; + } + this.wsRequests.push({ callback, failed }); + if (this.wsRequests.length > 1) { + return; + } + this.openSocket(); + } + async openSocket(retryInterval, retriesLeft) { + this.logger.info(`opening ws to ${this.settings.ws}, retryInterval: ${retryInterval}, retriesLeft: ${retriesLeft}...`); + this.startupTimer.mark("opening-socket"); + if (retryInterval === undefined) { + retryInterval = this.settings.reconnectInterval; + } + if (typeof retriesLeft === "undefined") { + retriesLeft = this.settings.reconnectAttempts; + } + if (retriesLeft !== undefined) { + if (retriesLeft === 0) { + this.notifyForSocketState(`wait for socket on ${this.settings.ws} failed - no more retries left`); + return; + } + this.logger.debug(`will retry ${retriesLeft} more times (every ${retryInterval} ms)`); + } + try { + await this.initiateSocket(); + this.startupTimer.mark("socket-initiated"); + this.notifyForSocketState(); + } + catch { + setTimeout(() => { + const retries = retriesLeft === undefined ? undefined : retriesLeft - 1; + this.openSocket(retryInterval, retries); + }, retryInterval); + } + } + initiateSocket() { + const pw = new PromiseWrapper$1(); + this.logger.debug(`initiating ws to ${this.settings.ws}...`); + this.ws = new WebSocketConstructor(this.settings.ws ?? ""); + this.ws.onerror = (err) => { + let reason = ""; + try { + reason = JSON.stringify(err); + } + catch (error) { + const seen = new WeakSet(); + const replacer = (key, value) => { + if (typeof value === "object" && value !== null) { + if (seen.has(value)) { + return; + } + seen.add(value); + } + return value; + }; + reason = JSON.stringify(err, replacer); + } + this.logger.info(`ws error - reason: ${reason}`); + pw.reject("error"); + this.notifyStatusChanged(false, reason); + }; + this.ws.onclose = (err) => { + this.logger.info(`ws closed - code: ${err?.code} reason: ${err?.reason}`); + pw.reject("closed"); + this.notifyStatusChanged(false); + }; + this.ws.onopen = () => { + this.startupTimer.mark("ws-opened"); + this.logger.info(`ws opened ${this.settings.identity?.application}`); + pw.resolve(); + this.notifyStatusChanged(true); + }; + this.ws.onmessage = (message) => { + this._registry.execute("onMessage", message.data); + }; + return pw.promise; + } + notifyForSocketState(error) { + this.wsRequests.forEach((wsRequest) => { + if (error) { + if (wsRequest.failed) { + wsRequest.failed(error); + } + } + else { + wsRequest.callback(); + } + }); + this.wsRequests = []; + } + notifyStatusChanged(status, reason) { + this._registry.execute("onConnectedChanged", status, reason); + } + } + + class MessageReplayerImpl { + specs; + specsNames = []; + messages = {}; + isDone; + subs = {}; + subsRefCount = {}; + connection; + constructor(specs) { + this.specs = {}; + for (const spec of specs) { + this.specs[spec.name] = spec; + this.specsNames.push(spec.name); + } + } + init(connection) { + this.connection = connection; + for (const name of this.specsNames) { + for (const type of this.specs[name].types) { + let refCount = this.subsRefCount[type]; + if (!refCount) { + refCount = 0; + } + refCount += 1; + this.subsRefCount[type] = refCount; + if (refCount > 1) { + continue; + } + const sub = connection.on(type, (msg) => this.processMessage(type, msg)); + this.subs[type] = sub; + } + } + } + processMessage(type, msg) { + if (this.isDone || !msg) { + return; + } + for (const name of this.specsNames) { + if (this.specs[name].types.indexOf(type) !== -1) { + const messages = this.messages[name] || []; + this.messages[name] = messages; + messages.push(msg); + } + } + } + drain(name, callback) { + if (callback) { + (this.messages[name] || []).forEach(callback); + } + delete this.messages[name]; + for (const type of this.specs[name].types) { + this.subsRefCount[type] -= 1; + if (this.subsRefCount[type] <= 0) { + this.connection?.off(this.subs[type]); + delete this.subs[type]; + delete this.subsRefCount[type]; + } + } + delete this.specs[name]; + if (!this.specs.length) { + this.isDone = true; + } + } + } + + let urlAlphabet$1 = + 'useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict'; + let nanoid$1 = (size = 21) => { + let id = ''; + let i = size; + while (i--) { + id += urlAlphabet$1[(Math.random() * 64) | 0]; + } + return id + }; + + const PromisePlus$1 = (executor, timeoutMilliseconds, timeoutMessage) => { + return new Promise((resolve, reject) => { + const timeout = setTimeout(() => { + const message = timeoutMessage || `Promise timeout hit: ${timeoutMilliseconds}`; + reject(message); + }, timeoutMilliseconds); + const providedPromise = new Promise(executor); + providedPromise + .then((result) => { + clearTimeout(timeout); + resolve(result); + }) + .catch((error) => { + clearTimeout(timeout); + reject(error); + }); + }); + }; + + class WebPlatformTransport { + settings; + logger; + identity; + isPreferredActivated; + _communicationId; + publicWindowId; + selfAssignedWindowId; + iAmConnected = false; + parentReady = false; + rejected = false; + parentPingResolve; + parentPingInterval; + connectionResolve; + extConnectionResolve; + extConnectionReject; + connectionReject; + port; + myClientId; + children = []; + extContentAvailable = false; + extContentConnecting = false; + extContentConnected = false; + parentWindowId; + parentInExtMode = false; + webNamespace = "g42_core_web"; + parent; + parentType; + parentPingTimeout = 5000; + connectionRequestTimeout = 7000; + defaultTargetString = "*"; + registry = CallbackRegistryFactory$1(); + messages = { + connectionAccepted: { name: "connectionAccepted", handle: this.handleConnectionAccepted.bind(this) }, + connectionRejected: { name: "connectionRejected", handle: this.handleConnectionRejected.bind(this) }, + connectionRequest: { name: "connectionRequest", handle: this.handleConnectionRequest.bind(this) }, + parentReady: { + name: "parentReady", handle: () => { + } + }, + parentPing: { name: "parentPing", handle: this.handleParentPing.bind(this) }, + platformPing: { name: "platformPing", handle: this.handlePlatformPing.bind(this) }, + platformReady: { name: "platformReady", handle: this.handlePlatformReady.bind(this) }, + clientUnload: { name: "clientUnload", handle: this.handleClientUnload.bind(this) }, + manualUnload: { name: "manualUnload", handle: this.handleManualUnload.bind(this) }, + extConnectionResponse: { name: "extConnectionResponse", handle: this.handleExtConnectionResponse.bind(this) }, + extSetupRequest: { name: "extSetupRequest", handle: this.handleExtSetupRequest.bind(this) }, + gatewayDisconnect: { name: "gatewayDisconnect", handle: this.handleGatewayDisconnect.bind(this) }, + gatewayInternalConnect: { name: "gatewayInternalConnect", handle: this.handleGatewayInternalConnect.bind(this) } + }; + constructor(settings, logger, identity) { + this.settings = settings; + this.logger = logger; + this.identity = identity; + this.extContentAvailable = !!window.glue42ext; + this.setUpMessageListener(); + this.setUpUnload(); + this.setupPlatformUnloadListener(); + this.parentType = window.name.includes("#wsp") ? "workspace" : undefined; + } + manualSetReadyState() { + this.iAmConnected = true; + this.parentReady = true; + } + get transportWindowId() { + return this.publicWindowId; + } + get communicationId() { + return this._communicationId; + } + async sendObject(msg) { + if (this.extContentConnected) { + return window.postMessage({ glue42ExtOut: msg }, this.defaultTargetString); + } + if (!this.port) { + throw new Error("Cannot send message, because the port was not opened yet"); + } + this.port.postMessage(msg); + } + get isObjectBasedTransport() { + return true; + } + onMessage(callback) { + return this.registry.add("onMessage", callback); + } + send() { + return Promise.reject("not supported"); + } + onConnectedChanged(callback) { + return this.registry.add("onConnectedChanged", callback); + } + async open() { + this.logger.debug("opening a connection to the web platform gateway."); + await this.connect(); + this.notifyStatusChanged(true); + } + close() { + const message = { + glue42core: { + type: this.messages.gatewayDisconnect.name, + data: { + clientId: this.myClientId, + ownWindowId: this.identity?.windowId + } + } + }; + this.port?.postMessage(message); + this.parentReady = false; + this.notifyStatusChanged(false, "manual reconnection"); + return Promise.resolve(); + } + name() { + return "web-platform"; + } + async reconnect() { + await this.close(); + return Promise.resolve(); + } + initiateInternalConnection() { + return new Promise((resolve, reject) => { + this.logger.debug("opening an internal web platform connection"); + this.port = this.settings.port; + if (this.iAmConnected) { + this.logger.warn("cannot open a new connection, because this client is currently connected"); + return; + } + this.port.onmessage = (event) => { + if (this.iAmConnected && !event.data?.glue42core) { + this.registry.execute("onMessage", event.data); + return; + } + const data = event.data?.glue42core; + if (!data) { + return; + } + if (data.type === this.messages.gatewayInternalConnect.name && data.success) { + this.publicWindowId = this.settings.windowId; + if (this.identity && this.publicWindowId) { + this.identity.windowId = this.publicWindowId; + this.identity.instance = this.publicWindowId; + } + resolve(); + } + if (data.type === this.messages.gatewayInternalConnect.name && data.error) { + reject(data.error); + } + }; + this.port.postMessage({ + glue42core: { + type: this.messages.gatewayInternalConnect.name + } + }); + }); + } + initiateRemoteConnection(target) { + return PromisePlus$1((resolve, reject) => { + this.connectionResolve = resolve; + this.connectionReject = reject; + this.myClientId = this.myClientId ?? nanoid$1(10); + const bridgeInstanceId = this.getMyWindowId() || nanoid$1(10); + const request = { + glue42core: { + type: this.messages.connectionRequest.name, + clientId: this.myClientId, + clientType: "child", + bridgeInstanceId, + selfAssignedWindowId: this.selfAssignedWindowId + } + }; + this.logger.debug("sending connection request"); + if (this.extContentConnecting) { + request.glue42core.clientType = "child"; + request.glue42core.bridgeInstanceId = this.myClientId; + request.glue42core.parentWindowId = this.parentWindowId; + return window.postMessage(request, this.defaultTargetString); + } + if (!target) { + throw new Error("Cannot send a connection request, because no glue target was specified!"); + } + target.postMessage(request, this.defaultTargetString); + }, this.connectionRequestTimeout, "The connection to the target glue window timed out"); + } + async isParentCheckSuccess(parentCheck) { + try { + await parentCheck; + return { success: true }; + } + catch (error) { + return { success: false }; + } + } + setUpMessageListener() { + if (this.settings.port) { + this.logger.debug("skipping generic message listener, because this is an internal client"); + return; + } + window.addEventListener("message", (event) => { + const data = event.data?.glue42core; + if (!data || this.rejected) { + return; + } + const allowedOrigins = this.settings.allowedOrigins || []; + if (allowedOrigins.length && !allowedOrigins.includes(event.origin)) { + this.logger.warn(`received a message from an origin which is not in the allowed list: ${event.origin}`); + return; + } + if (!this.checkMessageTypeValid(data.type)) { + this.logger.error(`cannot handle the incoming glue42 core message, because the type is invalid: ${data.type}`); + return; + } + const messageType = data.type; + this.logger.debug(`received valid glue42core message of type: ${messageType}`); + this.messages[messageType].handle(event); + }); + } + setUpUnload() { + if (this.settings.port) { + this.logger.debug("skipping unload event listener, because this is an internal client"); + return; + } + window.addEventListener("beforeunload", () => { + if (this.extContentConnected) { + return; + } + const message = { + glue42core: { + type: this.messages.clientUnload.name, + data: { + clientId: this.myClientId, + ownWindowId: this.identity?.windowId + } + } + }; + if (this.parent) { + this.parent.postMessage(message, this.defaultTargetString); + } + this.port?.postMessage(message); + }); + } + handlePlatformReady(event) { + this.logger.debug("the web platform gave the ready signal"); + this.parentReady = true; + if (this.parentPingResolve) { + this.parentPingResolve(); + delete this.parentPingResolve; + } + if (this.parentPingInterval) { + clearInterval(this.parentPingInterval); + delete this.parentPingInterval; + } + this.parent = event.source; + this.parentType = window.name.includes("#wsp") ? "workspace" : "window"; + } + handleConnectionAccepted(event) { + const data = event.data?.glue42core; + if (this.myClientId === data.clientId) { + return this.handleAcceptanceOfMyRequest(data); + } + return this.handleAcceptanceOfGrandChildRequest(data, event); + } + handleAcceptanceOfMyRequest(data) { + this.logger.debug("handling a connection accepted signal targeted at me."); + this.isPreferredActivated = data.isPreferredActivated; + if (this.extContentConnecting) { + return this.processExtContentConnection(data); + } + if (!data.port) { + this.logger.error("cannot set up my connection, because I was not provided with a port"); + return; + } + this.publicWindowId = this.getMyWindowId(); + if (this.identity) { + this.identity.windowId = this.publicWindowId; + this.identity.instance = this.identity.instance ? this.identity.instance : this.publicWindowId || nanoid$1(10); + } + if (this.identity && data.appName) { + this.identity.application = data.appName; + this.identity.applicationName = data.appName; + } + this._communicationId = data.communicationId; + this.port = data.port; + this.port.onmessage = (e) => this.registry.execute("onMessage", e.data); + if (this.connectionResolve) { + this.logger.debug("my connection is set up, calling the connection resolve."); + this.connectionResolve(); + delete this.connectionResolve; + return; + } + this.logger.error("unable to call the connection resolve, because no connection promise was found"); + } + processExtContentConnection(data) { + this.logger.debug("handling a connection accepted signal targeted at me for extension content connection."); + this.extContentConnecting = false; + this.extContentConnected = true; + this.publicWindowId = this.parentWindowId || this.myClientId; + if (this.extContentConnecting && this.identity) { + this.identity.windowId = this.publicWindowId; + } + if (this.identity && data.appName) { + this.identity.application = data.appName; + this.identity.applicationName = data.appName; + } + window.addEventListener("message", (event) => { + const extData = event.data?.glue42ExtInc; + if (!extData) { + return; + } + const allowedOrigins = this.settings.allowedOrigins || []; + if (allowedOrigins.length && !allowedOrigins.includes(event.origin)) { + this.logger.warn(`received a message from an origin which is not in the allowed list: ${event.origin}`); + return; + } + this.registry.execute("onMessage", extData); + }); + if (this.connectionResolve) { + this.logger.debug("my connection is set up, calling the connection resolve."); + this.connectionResolve(); + delete this.connectionResolve; + return; + } + } + handleAcceptanceOfGrandChildRequest(data, event) { + if (this.extContentConnecting || this.extContentConnected) { + this.logger.debug("cannot process acceptance of a grandchild, because I am connected to a content script"); + return; + } + this.logger.debug(`handling a connection accepted signal targeted at a grandchild: ${data.clientId}`); + const child = this.children.find((c) => c.grandChildId === data.clientId); + if (!child) { + this.logger.error(`cannot handle connection accepted for grandchild: ${data.clientId}, because there is no grandchild with this id`); + return; + } + child.connected = true; + this.logger.debug(`the grandchild connection for ${data.clientId} is set up, forwarding the success message and the gateway port`); + data.parentWindowId = this.publicWindowId; + child.source.postMessage(event.data, child.origin, [data.port]); + return; + } + handleConnectionRejected(event) { + this.logger.debug("handling a connection rejection. Most likely the reason is that this window was not created by a glue API call"); + if (!this.connectionReject) { + return; + } + const errorMsg = typeof event.data.glue42core?.error === "string" + ? `Connection was rejected. ${event.data.glue42core?.error}` + : "The platform connection was rejected. Most likely because this window was not created by a glue API call"; + this.connectionReject(errorMsg); + delete this.connectionReject; + } + handleConnectionRequest(event) { + if (this.extContentConnecting) { + this.logger.debug("This connection request event is targeted at the extension content"); + return; + } + const source = event.source; + const data = event.data.glue42core; + if (!data.clientType || data.clientType !== "grandChild") { + return this.rejectConnectionRequest(source, event.origin, "rejecting a connection request, because the source was not opened by a glue API call"); + } + if (!data.clientId) { + return this.rejectConnectionRequest(source, event.origin, "rejecting a connection request, because the source did not provide a valid id"); + } + if (!this.parent) { + return this.rejectConnectionRequest(source, event.origin, "Cannot forward the connection request, because no direct connection to the platform was found"); + } + this.logger.debug(`handling a connection request for a grandchild: ${data.clientId}`); + this.children.push({ grandChildId: data.clientId, source, connected: false, origin: event.origin }); + this.logger.debug(`grandchild: ${data.clientId} is prepared, forwarding connection request to the platform`); + this.parent.postMessage(event.data, this.defaultTargetString); + } + handleParentPing(event) { + if (!this.parentReady) { + this.logger.debug("my parent is not ready, I am ignoring the parent ping"); + return; + } + if (!this.iAmConnected) { + this.logger.debug("i am not fully connected yet, I am ignoring the parent ping"); + return; + } + const message = { + glue42core: { + type: this.messages.parentReady.name + } + }; + if (this.extContentConnected) { + message.glue42core.extMode = { windowId: this.myClientId }; + } + const source = event.source; + this.logger.debug("responding to a parent ping with a ready message"); + source.postMessage(message, event.origin); + } + setupPlatformUnloadListener() { + this.onMessage((msg) => { + if (msg.type === "platformUnload") { + this.logger.debug("detected a web platform unload"); + this.parentReady = false; + this.notifyStatusChanged(false, "Gateway unloaded"); + } + }); + } + handleManualUnload() { + const message = { + glue42core: { + type: this.messages.clientUnload.name, + data: { + clientId: this.myClientId, + ownWindowId: this.identity?.windowId + } + } + }; + if (this.extContentConnected) { + return window.postMessage({ glue42ExtOut: message }, this.defaultTargetString); + } + this.port?.postMessage(message); + } + handleClientUnload(event) { + const data = event.data.glue42core; + const clientId = data?.data.clientId; + if (!clientId) { + this.logger.warn("cannot process grand child unload, because the provided id was not valid"); + return; + } + const foundChild = this.children.find((child) => child.grandChildId === clientId); + if (!foundChild) { + this.logger.warn("cannot process grand child unload, because this client is unaware of this grandchild"); + return; + } + this.logger.debug(`handling grandchild unload for id: ${clientId}`); + this.children = this.children.filter((child) => child.grandChildId !== clientId); + } + handlePlatformPing() { + return; + } + notifyStatusChanged(status, reason) { + this.iAmConnected = status; + this.registry.execute("onConnectedChanged", status, reason); + } + checkMessageTypeValid(typeToValidate) { + return typeof typeToValidate === "string" && !!this.messages[typeToValidate]; + } + rejectConnectionRequest(source, origin, reason) { + this.rejected = true; + this.logger.error(reason); + const rejection = { + glue42core: { + type: this.messages.connectionRejected.name + } + }; + source.postMessage(rejection, origin); + } + requestConnectionPermissionFromExt() { + return this.waitForContentScript() + .then(() => PromisePlus$1((resolve, reject) => { + this.extConnectionResolve = resolve; + this.extConnectionReject = reject; + const message = { + glue42core: { + type: "extSetupRequest" + } + }; + this.logger.debug("permission request to the extension content script was sent"); + window.postMessage(message, this.defaultTargetString); + }, this.parentPingTimeout, "Cannot initialize glue, because this app was not opened or created by a Glue Client and the request for extension connection timed out")); + } + handleExtConnectionResponse(event) { + const data = event.data?.glue42core; + if (!data.approved) { + return this.extConnectionReject ? this.extConnectionReject("Cannot initialize glue, because this app was not opened or created by a Glue Client and the request for extension connection was rejected") : undefined; + } + if (this.extConnectionResolve) { + this.extConnectionResolve(); + delete this.extConnectionResolve; + } + this.extContentConnecting = true; + this.parentType = "extension"; + this.logger.debug("The extension connection was approved, proceeding."); + } + handleExtSetupRequest() { + return; + } + handleGatewayDisconnect() { + return; + } + handleGatewayInternalConnect() { + return; + } + waitForContentScript() { + const contentReady = !!window.glue42ext?.content; + if (contentReady) { + return Promise.resolve(); + } + return PromisePlus$1((resolve) => { + window.addEventListener("Glue42EXTReady", () => { + resolve(); + }); + }, this.connectionRequestTimeout, "The content script was available, but was never heard to be ready"); + } + async connect() { + if (this.settings.port) { + await this.initiateInternalConnection(); + this.logger.debug("internal web platform connection completed"); + return; + } + this.logger.debug("opening a client web platform connection"); + await this.findParent(); + await this.initiateRemoteConnection(this.parent); + this.logger.debug("the client is connected"); + } + async findParent() { + const connectionNotPossibleMsg = "Cannot initiate glue, because this window was not opened or created by a glue client"; + const myInsideParents = this.getPossibleParentsInWindow(window); + const myOutsideParents = this.getPossibleParentsOutsideWindow(window.top?.opener, window.top); + const uniqueParents = new Set([...myInsideParents, ...myOutsideParents]); + if (!uniqueParents.size && !this.extContentAvailable) { + throw new Error(connectionNotPossibleMsg); + } + if (!uniqueParents.size && this.extContentAvailable) { + await this.requestConnectionPermissionFromExt(); + return; + } + const defaultParentCheck = await this.isParentCheckSuccess(this.confirmParent(Array.from(uniqueParents))); + if (defaultParentCheck.success) { + this.logger.debug("The default parent was found!"); + return; + } + if (!this.extContentAvailable) { + throw new Error(connectionNotPossibleMsg); + } + await this.requestConnectionPermissionFromExt(); + } + getPossibleParentsInWindow(currentWindow) { + return (!currentWindow?.parent || currentWindow === currentWindow.parent) ? [] : [currentWindow.parent, ...this.getPossibleParentsInWindow(currentWindow.parent)]; + } + getPossibleParentsOutsideWindow(opener, current) { + return (!opener || !current || opener === current) ? [] : [opener, ...this.getPossibleParentsInWindow(opener), ...this.getPossibleParentsOutsideWindow(opener.opener, opener)]; + } + confirmParent(targets) { + const connectionNotPossibleMsg = "Cannot initiate glue, because this window was not opened or created by a glue client"; + const parentCheck = PromisePlus$1((resolve) => { + this.parentPingResolve = resolve; + const message = { + glue42core: { + type: this.messages.platformPing.name + } + }; + this.parentPingInterval = setInterval(() => { + targets.forEach((target) => { + target.postMessage(message, this.defaultTargetString); + }); + }, 1000); + }, this.parentPingTimeout, connectionNotPossibleMsg); + parentCheck.catch(() => { + if (this.parentPingInterval) { + clearInterval(this.parentPingInterval); + delete this.parentPingInterval; + } + }); + return parentCheck; + } + getMyWindowId() { + if (this.parentType === "workspace") { + return window.name.substring(0, window.name.indexOf("#wsp")); + } + if (window !== window.top) { + return; + } + if (window.name?.includes("g42")) { + return window.name; + } + this.selfAssignedWindowId = this.selfAssignedWindowId || `g42-${nanoid$1(10)}`; + return this.selfAssignedWindowId; + } + } + + const waitForInvocations = (invocations, callback) => { + let left = invocations; + return () => { + left--; + if (left === 0) { + callback(); + } + }; + }; + + class AsyncSequelizer { + minSequenceInterval; + queue = []; + isExecutingQueue = false; + constructor(minSequenceInterval = 0) { + this.minSequenceInterval = minSequenceInterval; + } + enqueue(action) { + return new Promise((resolve, reject) => { + this.queue.push({ action, resolve, reject }); + this.executeQueue(); + }); + } + async executeQueue() { + if (this.isExecutingQueue) { + return; + } + this.isExecutingQueue = true; + while (this.queue.length) { + const operation = this.queue.shift(); + if (!operation) { + this.isExecutingQueue = false; + return; + } + try { + const actionResult = await operation.action(); + operation.resolve(actionResult); + } + catch (error) { + operation.reject(error); + } + await this.intervalBreak(); + } + this.isExecutingQueue = false; + } + intervalBreak() { + return new Promise((res) => setTimeout(res, this.minSequenceInterval)); + } + } + + function domainSession (domain, connection, logger, successMessages, errorMessages) { + if (domain == null) { + domain = "global"; + } + successMessages = successMessages ?? ["success"]; + errorMessages = errorMessages ?? ["error"]; + let isJoined = domain === "global"; + let tryReconnecting = false; + let _latestOptions; + let _connectionOn = false; + const callbacks = CallbackRegistryFactory$1(); + connection.disconnected(handleConnectionDisconnected); + connection.loggedIn(handleConnectionLoggedIn); + connection.on("success", (msg) => handleSuccessMessage(msg)); + connection.on("error", (msg) => handleErrorMessage(msg)); + connection.on("result", (msg) => handleSuccessMessage(msg)); + if (successMessages) { + successMessages.forEach((sm) => { + connection.on(sm, (msg) => handleSuccessMessage(msg)); + }); + } + if (errorMessages) { + errorMessages.forEach((sm) => { + connection.on(sm, (msg) => handleErrorMessage(msg)); + }); + } + const requestsMap = {}; + function join(options) { + _latestOptions = options; + return new Promise((resolve, reject) => { + if (isJoined) { + resolve({}); + return; + } + let joinPromise; + if (domain === "global") { + joinPromise = _connectionOn ? Promise.resolve({}) : Promise.reject("not connected to gateway"); + } + else { + logger.debug(`joining domain ${domain}`); + const joinMsg = { + type: "join", + destination: domain, + domain: "global", + options, + }; + joinPromise = send(joinMsg); + } + joinPromise + .then(() => { + handleJoined(); + resolve({}); + }) + .catch((err) => { + logger.debug("error joining " + domain + " domain: " + JSON.stringify(err)); + reject(err); + }); + }); + } + function leave() { + if (domain === "global") { + return Promise.resolve(); + } + logger.debug("stopping session " + domain + "..."); + const leaveMsg = { + type: "leave", + destination: domain, + domain: "global", + }; + tryReconnecting = false; + return send(leaveMsg) + .then(() => { + isJoined = false; + callbacks.execute("onLeft"); + }) + .catch(() => { + isJoined = false; + callbacks.execute("onLeft"); + }); + } + function handleJoined() { + logger.debug("did join " + domain); + isJoined = true; + const wasReconnect = tryReconnecting; + tryReconnecting = false; + callbacks.execute("onJoined", wasReconnect); + } + function handleConnectionDisconnected() { + _connectionOn = false; + logger.debug("connection is down"); + isJoined = false; + tryReconnecting = true; + callbacks.execute("onLeft", { disconnected: true }); + } + function handleConnectionLoggedIn() { + _connectionOn = true; + if (tryReconnecting) { + logger.debug("connection is now up - trying to reconnect..."); + join(_latestOptions); + } + } + function onJoined(callback) { + if (isJoined) { + callback(false); + } + return callbacks.add("onJoined", callback); + } + function onLeft(callback) { + if (!isJoined) { + callback(); + } + return callbacks.add("onLeft", callback); + } + function handleErrorMessage(msg) { + if (domain !== msg.domain) { + return; + } + const requestId = msg.request_id; + if (!requestId) { + return; + } + const entry = requestsMap[requestId]; + if (!entry) { + return; + } + entry.error(msg); + } + function handleSuccessMessage(msg) { + if (msg.domain !== domain) { + return; + } + const requestId = msg.request_id; + if (!requestId) { + return; + } + const entry = requestsMap[requestId]; + if (!entry) { + return; + } + entry.success(msg); + } + function getNextRequestId() { + return nanoid$1(10); + } + let queuedCalls = []; + function send(msg, tag, options) { + const ignore = ["hello", "join"]; + if (msg.type && ignore.indexOf(msg.type) === -1) { + if (!isJoined) { + console.warn(`trying to send a message (${msg.domain} ${msg.type}) but not connected, will queue`); + const pw = new PromiseWrapper$1(); + queuedCalls.push({ msg, tag, options, pw }); + if (queuedCalls.length === 1) { + const unsubscribe = onJoined(() => { + logger.info(`joined - will now send queued messages (${queuedCalls.length} -> [${queuedCalls.map((m) => m.msg.type)}])`); + queuedCalls.forEach((qm) => { + send(qm.msg, qm.tag, qm.options) + .then((t) => qm.pw.resolve(t)) + .catch((e) => qm.pw.reject(e)); + }); + queuedCalls = []; + unsubscribe(); + }); + } + return pw.promise; + } + } + options = options ?? {}; + msg.request_id = msg.request_id ?? getNextRequestId(); + msg.domain = msg.domain ?? domain; + if (!options.skipPeerId) { + msg.peer_id = connection.peerId; + } + const requestId = msg.request_id; + return new Promise((resolve, reject) => { + requestsMap[requestId] = { + success: (successMsg) => { + delete requestsMap[requestId]; + successMsg._tag = tag; + resolve(successMsg); + }, + error: (errorMsg) => { + logger.warn(`Gateway error - ${JSON.stringify(errorMsg)}`); + delete requestsMap[requestId]; + errorMsg._tag = tag; + reject(errorMsg); + }, + }; + connection + .send(msg, options) + .catch((err) => { + requestsMap[requestId].error({ err }); + }); + }); + } + function sendFireAndForget(msg) { + msg.request_id = msg.request_id ? msg.request_id : getNextRequestId(); + msg.domain = msg.domain ?? domain; + msg.peer_id = connection.peerId; + return connection.send(msg); + } + return { + join, + leave, + onJoined, + onLeft, + send, + sendFireAndForget, + on: (type, callback) => { + connection.on(type, (msg) => { + if (msg.domain !== domain) { + return; + } + try { + callback(msg); + } + catch (e) { + logger.error(`Callback failed: ${e} \n ${e.stack} \n msg was: ${JSON.stringify(msg)}`, e); + } + }); + }, + loggedIn: (callback) => connection.loggedIn(callback), + connected: (callback) => connection.connected(callback), + disconnected: (callback) => connection.disconnected(callback), + get peerId() { + return connection.peerId; + }, + get domain() { + return domain; + }, + }; + } + + class Connection { + settings; + logger; + protocolVersion = 3; + peerId; + token; + info; + resolvedIdentity; + availableDomains; + gatewayToken; + replayer; + messageHandlers = {}; + ids = 1; + registry = CallbackRegistryFactory$1(); + _connected = false; + isTrace = false; + transport; + _defaultTransport; + _defaultAuth; + _targetTransport; + _targetAuth; + _swapTransport = false; + _switchInProgress = false; + _transportSubscriptions = []; + datePrefix = "#T42_DATE#"; + datePrefixLen = this.datePrefix.length; + dateMinLen = this.datePrefixLen + 1; + datePrefixFirstChar = this.datePrefix[0]; + _sequelizer = new AsyncSequelizer(); + _isLoggedIn = false; + shouldTryLogin = true; + pingTimer; + sessions = []; + globalDomain; + initialLogin = true; + initialLoginAttempts = 3; + loginConfig; + constructor(settings, logger) { + this.settings = settings; + this.logger = logger; + settings = settings || {}; + settings.reconnectAttempts = settings.reconnectAttempts ?? 10; + settings.reconnectInterval = settings.reconnectInterval ?? 1000; + if (settings.inproc) { + this.transport = new InProcTransport(settings.inproc, logger.subLogger("inMemory")); + } + else if (settings.sharedWorker) { + this.transport = new SharedWorkerTransport(settings.sharedWorker, logger.subLogger("shared-worker")); + } + else if (settings.webPlatform) { + this.transport = new WebPlatformTransport(settings.webPlatform, logger.subLogger("web-platform"), settings.identity); + } + else if (settings.ws !== undefined) { + this.transport = new WS(settings, logger.subLogger("ws")); + } + else { + throw new Error("No connection information specified"); + } + this.isTrace = logger.canPublish("trace"); + logger.debug(`starting with ${this.transport.name()} transport`); + const unsubConnectionChanged = this.transport.onConnectedChanged(this.handleConnectionChanged.bind(this)); + const unsubOnMessage = this.transport.onMessage(this.handleTransportMessage.bind(this)); + this._transportSubscriptions.push(unsubConnectionChanged); + this._transportSubscriptions.push(unsubOnMessage); + this._defaultTransport = this.transport; + this.ping(); + } + async switchTransport(settings) { + return this._sequelizer.enqueue(async () => { + if (!settings || typeof settings !== "object") { + throw new Error("Cannot switch transports, because the settings are missing or invalid."); + } + if (typeof settings.type === "undefined") { + throw new Error("Cannot switch the transport, because the type is not defined"); + } + this.logger.trace(`Starting transport switch with settings: ${JSON.stringify(settings)}`); + const switchTargetTransport = settings.type === "secondary" ? this.getNewSecondaryTransport(settings) : this._defaultTransport; + this._targetTransport = switchTargetTransport; + this._targetAuth = settings.type === "secondary" ? this.getNewSecondaryAuth(settings) : this._defaultAuth; + const verifyPromise = this.verifyConnection(); + this._swapTransport = true; + this._switchInProgress = true; + this.logger.trace("The new transport has been set, closing the current transport"); + await this.transport.close(); + try { + await verifyPromise; + const isSwitchSuccess = this.transport === switchTargetTransport; + this.logger.info(`The reconnection after the switch was completed. Was the switch a success: ${isSwitchSuccess}`); + this._switchInProgress = false; + return { success: isSwitchSuccess }; + } + catch (error) { + this.logger.info("The reconnection after the switch timed out, reverting back to the default transport."); + this.switchTransport({ type: "default" }); + this._switchInProgress = false; + return { success: false }; + } + }); + } + onLibReAnnounced(callback) { + return this.registry.add("libReAnnounced", callback); + } + setLibReAnnounced(lib) { + this.registry.execute("libReAnnounced", lib); + } + send(message, options) { + if (this.transport.sendObject && + this.transport.isObjectBasedTransport) { + const msg = this.createObjectMessage(message); + if (this.isTrace) { + this.logger.trace(`>> ${JSON.stringify(msg)}`); + } + return this.transport.sendObject(msg, options); + } + else { + const strMessage = this.createStringMessage(message); + if (this.isTrace) { + this.logger.trace(`>> ${strMessage}`); + } + return this.transport.send(strMessage, options); + } + } + on(type, messageHandler) { + type = type.toLowerCase(); + if (this.messageHandlers[type] === undefined) { + this.messageHandlers[type] = {}; + } + const id = this.ids++; + this.messageHandlers[type][id] = messageHandler; + return { + type, + id, + }; + } + off(info) { + delete this.messageHandlers[info.type.toLowerCase()][info.id]; + } + get isConnected() { + return this._isLoggedIn; + } + connected(callback) { + return this.loggedIn(() => { + const currentServer = this.transport.name(); + callback(currentServer); + }); + } + disconnected(callback) { + return this.registry.add("disconnected", callback); + } + async login(authRequest, reconnect) { + if (!this._defaultAuth) { + this._defaultAuth = authRequest; + } + if (this._swapTransport) { + this.logger.trace("Detected a transport swap, swapping transports"); + const newAuth = this.transportSwap(); + authRequest = newAuth ?? authRequest; + } + this.logger.trace(`Starting login for transport: ${this.transport.name()} and auth ${JSON.stringify(authRequest)}`); + try { + await this.transport.open(); + this.logger.trace(`Transport: ${this.transport.name()} opened, logging in`); + timer("connection").mark("transport-opened"); + const identity = await this.loginCore(authRequest, reconnect); + this.logger.trace(`Logged in with identity: ${JSON.stringify(identity)}`); + timer("connection").mark("protocol-logged-in"); + return identity; + } + catch (error) { + if (this._switchInProgress) { + this.logger.trace("An error while logging in after a transport swap, preparing a default swap."); + this.prepareDefaultSwap(); + } + throw new Error(error); + } + } + async logout() { + await this.logoutCore(); + await this.transport.close(); + } + loggedIn(callback) { + if (this._isLoggedIn) { + callback(); + } + return this.registry.add("onLoggedIn", callback); + } + domain(domain, successMessages, errorMessages) { + let session = this.sessions.find((s) => s.domain === domain); + if (!session) { + session = domainSession(domain, this, this.logger.subLogger(`domain=${domain}`), successMessages, errorMessages); + this.sessions.push(session); + } + return session; + } + authToken() { + const createTokenReq = { + domain: "global", + type: "create-token" + }; + if (!this.globalDomain) { + return Promise.reject(new Error("no global domain session")); + } + return this.globalDomain.send(createTokenReq) + .then((res) => { + return res.token; + }); + } + reconnect() { + return this.transport.reconnect(); + } + setLoggedIn(value) { + this._isLoggedIn = value; + if (this._isLoggedIn) { + this.registry.execute("onLoggedIn"); + } + } + distributeMessage(message, type) { + const handlers = this.messageHandlers[type.toLowerCase()]; + if (handlers !== undefined) { + Object.keys(handlers).forEach((handlerId) => { + const handler = handlers[handlerId]; + if (handler !== undefined) { + try { + handler(message); + } + catch (error) { + try { + this.logger.error(`Message handler failed with ${error.stack}`, error); + } + catch (loggerError) { + console.log("Message handler failed", error); + } + } + } + }); + } + } + handleConnectionChanged(connected) { + if (this._connected === connected) { + return; + } + this._connected = connected; + if (connected) { + if (this.settings?.replaySpecs?.length) { + this.replayer = new MessageReplayerImpl(this.settings.replaySpecs); + this.replayer.init(this); + } + this.registry.execute("connected"); + } + else { + this.handleDisconnected(); + this.registry.execute("disconnected"); + } + } + handleDisconnected() { + this.setLoggedIn(false); + const tryToLogin = this.shouldTryLogin; + if (tryToLogin && this.initialLogin) { + if (this.initialLoginAttempts <= 0) { + return; + } + this.initialLoginAttempts--; + } + this.logger.debug("disconnected - will try new login?" + this.shouldTryLogin); + if (this.shouldTryLogin) { + if (!this.loginConfig) { + throw new Error("no login info"); + } + this.login(this.loginConfig, true) + .catch(() => { + setTimeout(this.handleDisconnected.bind(this), this.settings.reconnectInterval || 1000); + }); + } + } + handleTransportMessage(msg) { + let msgObj; + if (typeof msg === "string") { + msgObj = this.processStringMessage(msg); + } + else { + msgObj = this.processObjectMessage(msg); + } + if (this.isTrace) { + this.logger.trace(`<< ${JSON.stringify(msgObj)}`); + } + this.distributeMessage(msgObj.msg, msgObj.msgType); + } + verifyConnection() { + return PromisePlus$1((resolve) => { + let unsub; + const ready = waitForInvocations(2, () => { + if (unsub) { + unsub(); + } + resolve(); + }); + unsub = this.onLibReAnnounced((lib) => { + if (lib.name === "interop") { + return ready(); + } + if (lib.name === "contexts") { + return ready(); + } + }); + }, 10000, "Transport switch timed out waiting for all libraries to be re-announced"); + } + getNewSecondaryTransport(settings) { + if (!settings.transportConfig?.url) { + throw new Error("Missing secondary transport URL."); + } + return new WS(Object.assign({}, this.settings, { ws: settings.transportConfig.url, reconnectAttempts: 1 }), this.logger.subLogger("ws-secondary")); + } + getNewSecondaryAuth(settings) { + if (!settings.transportConfig?.auth) { + throw new Error("Missing secondary transport auth information."); + } + return settings.transportConfig.auth; + } + transportSwap() { + this._swapTransport = false; + if (!this._targetTransport || !this._targetAuth) { + this.logger.warn(`Error while switching transports - either the target transport or auth is not defined: transport defined -> ${!!this._defaultTransport}, auth defined -> ${!!this._targetAuth}. Staying on the current one.`); + return; + } + this._transportSubscriptions.forEach((unsub) => unsub()); + this._transportSubscriptions = []; + this.transport = this._targetTransport; + const unsubConnectionChanged = this.transport.onConnectedChanged(this.handleConnectionChanged.bind(this)); + const unsubOnMessage = this.transport.onMessage(this.handleTransportMessage.bind(this)); + this._transportSubscriptions.push(unsubConnectionChanged); + this._transportSubscriptions.push(unsubOnMessage); + return this._targetAuth; + } + prepareDefaultSwap() { + this._transportSubscriptions.forEach((unsub) => unsub()); + this._transportSubscriptions = []; + this.transport.close().catch((error) => this.logger.warn(`Error closing the ${this.transport.name()} transport after a failed connection attempt: ${JSON.stringify(error)}`)); + this._targetTransport = this._defaultTransport; + this._targetAuth = this._defaultAuth; + this._swapTransport = true; + } + processStringMessage(message) { + const msg = JSON.parse(message, (key, value) => { + if (typeof value !== "string") { + return value; + } + if (value.length < this.dateMinLen) { + return value; + } + if (!value.startsWith(this.datePrefixFirstChar)) { + return value; + } + if (value.substring(0, this.datePrefixLen) !== this.datePrefix) { + return value; + } + try { + const milliseconds = parseInt(value.substring(this.datePrefixLen, value.length), 10); + if (isNaN(milliseconds)) { + return value; + } + return new Date(milliseconds); + } + catch (ex) { + return value; + } + }); + return { + msg, + msgType: msg.type, + }; + } + createStringMessage(message) { + const oldToJson = Date.prototype.toJSON; + try { + const datePrefix = this.datePrefix; + Date.prototype.toJSON = function () { + return datePrefix + this.getTime(); + }; + const result = JSON.stringify(message); + return result; + } + finally { + Date.prototype.toJSON = oldToJson; + } + } + processObjectMessage(message) { + if (!message.type) { + throw new Error("Object should have type property"); + } + return { + msg: message, + msgType: message.type, + }; + } + createObjectMessage(message) { + return message; + } + async loginCore(config, reconnect) { + this.logger.info("logging in..."); + this.loginConfig = config; + if (!this.loginConfig) { + this.loginConfig = { username: "", password: "" }; + } + this.shouldTryLogin = true; + const authentication = await this.setupAuthConfig(config, reconnect); + const helloMsg = { + type: "hello", + identity: this.settings.identity, + authentication + }; + if (config.sessionId) { + helloMsg.request_id = config.sessionId; + } + this.globalDomain = domainSession("global", this, this.logger.subLogger("global-domain"), [ + "welcome", + "token", + "authentication-request" + ]); + const sendOptions = { skipPeerId: true }; + if (this.initialLogin) { + sendOptions.retryInterval = this.settings.reconnectInterval; + sendOptions.maxRetries = this.settings.reconnectAttempts; + } + try { + const welcomeMsg = await this.tryAuthenticate(this.globalDomain, helloMsg, sendOptions, config); + this.initialLogin = false; + this.logger.info("login successful with peerId " + welcomeMsg.peer_id); + this.peerId = welcomeMsg.peer_id; + this.resolvedIdentity = welcomeMsg.resolved_identity; + this.availableDomains = welcomeMsg.available_domains; + if (welcomeMsg.options) { + this.token = welcomeMsg.options.access_token; + this.info = welcomeMsg.options.info; + } + this.setLoggedIn(true); + return welcomeMsg.resolved_identity; + } + catch (err) { + this.logger.error("error sending hello message - " + (err.message || err.msg || err.reason || err), err); + throw err; + } + finally { + if (config?.flowCallback && config.sessionId) { + config.flowCallback(config.sessionId, null); + } + } + } + async tryAuthenticate(globalDomain, helloMsg, sendOptions, config) { + let welcomeMsg; + while (true) { + const msg = await globalDomain.send(helloMsg, undefined, sendOptions); + if (msg.type === "authentication-request") { + const token = Buffer.from(msg.authentication.token, "base64"); + if (config.flowCallback && config.sessionId) { + helloMsg.authentication.token = + (await config.flowCallback(config.sessionId, token)) + .data + .toString("base64"); + } + helloMsg.request_id = config.sessionId; + } + else if (msg.type === "welcome") { + welcomeMsg = msg; + break; + } + else if (msg.type === "error") { + throw new Error("Authentication failed: " + msg.reason); + } + else { + throw new Error("Unexpected message type during authentication: " + msg.type); + } + } + return welcomeMsg; + } + async setupAuthConfig(config, reconnect) { + const authentication = {}; + this.gatewayToken = config.gatewayToken; + if (config.gatewayToken) { + if (reconnect) { + try { + config.gatewayToken = await this.getNewGWToken(); + } + catch (e) { + this.logger.warn(`failed to get GW token when reconnecting ${e?.message || e}`); + } + } + authentication.method = "gateway-token"; + authentication.token = config.gatewayToken; + this.gatewayToken = config.gatewayToken; + } + else if (config.flowName === "sspi") { + authentication.provider = "win"; + authentication.method = "access-token"; + if (config.flowCallback && config.sessionId) { + authentication.token = + (await config.flowCallback(config.sessionId, null)) + .data + .toString("base64"); + } + else { + throw new Error("Invalid SSPI config"); + } + } + else if (config.token) { + authentication.method = "access-token"; + authentication.token = config.token; + } + else if (config.username) { + authentication.method = "secret"; + authentication.login = config.username; + authentication.secret = config.password; + } + else if (config.provider) { + authentication.provider = config.provider; + authentication.providerContext = config.providerContext; + } + else { + throw new Error("invalid auth message" + JSON.stringify(config)); + } + return authentication; + } + async logoutCore() { + this.logger.debug("logging out..."); + this.shouldTryLogin = false; + if (this.pingTimer) { + clearTimeout(this.pingTimer); + } + const promises = this.sessions.map((session) => { + session.leave(); + }); + await Promise.all(promises); + } + getNewGWToken() { + if (typeof window !== "undefined") { + const glue42gd = window.glue42gd; + if (glue42gd) { + return glue42gd.getGWToken(); + } + } + return Promise.reject(new Error("not running in GD")); + } + ping() { + if (!this.shouldTryLogin) { + return; + } + if (this._isLoggedIn) { + this.send({ type: "ping" }); + } + this.pingTimer = setTimeout(() => { + this.ping(); + }, 30 * 1000); + } + } + + const order = ["trace", "debug", "info", "warn", "error", "off"]; + let Logger$1 = class Logger { + name; + parent; + static Interop; + static InteropMethodName = "T42.AppLogger.Log"; + static Instance; + path; + subLoggers = []; + _consoleLevel; + _publishLevel; + loggerFullName; + includeTimeAndLevel; + logFn = console; + customLogFn = false; + constructor(name, parent, logFn) { + this.name = name; + this.parent = parent; + this.name = name; + if (parent) { + this.path = `${parent.path}.${name}`; + } + else { + this.path = name; + } + this.loggerFullName = `[${this.path}]`; + this.includeTimeAndLevel = !logFn; + if (logFn) { + this.logFn = logFn; + this.customLogFn = true; + } + } + subLogger(name) { + const existingSub = this.subLoggers.filter((subLogger) => { + return subLogger.name === name; + })[0]; + if (existingSub !== undefined) { + return existingSub; + } + Object.keys(this).forEach((key) => { + if (key === name) { + throw new Error("This sub logger name is not allowed."); + } + }); + const sub = new Logger(name, this, this.customLogFn ? this.logFn : undefined); + this.subLoggers.push(sub); + return sub; + } + publishLevel(level) { + if (level) { + this._publishLevel = level; + } + return this._publishLevel || this.parent?.publishLevel(); + } + consoleLevel(level) { + if (level) { + this._consoleLevel = level; + } + return this._consoleLevel || this.parent?.consoleLevel(); + } + log(message, level, error) { + this.publishMessage(level || "info", message, error); + } + trace(message) { + this.log(message, "trace"); + } + debug(message) { + this.log(message, "debug"); + } + info(message) { + this.log(message, "info"); + } + warn(message) { + this.log(message, "warn"); + } + error(message, err) { + this.log(message, "error", err); + } + canPublish(level, compareWith) { + const levelIdx = order.indexOf(level); + const restrictionIdx = order.indexOf(compareWith || this.consoleLevel() || "trace"); + return levelIdx >= restrictionIdx; + } + publishMessage(level, message, error) { + const loggerName = this.loggerFullName; + if (level === "error" && !error) { + const e = new Error(); + if (e.stack) { + message = + message + + "\n" + + e.stack + .split("\n") + .slice(4) + .join("\n"); + } + } + if (this.canPublish(level, this.publishLevel())) { + const interop = Logger.Interop; + if (interop) { + try { + if (interop.methods({ name: Logger.InteropMethodName }).length > 0) { + const args = { + msg: message, + logger: loggerName, + level + }; + if (error && error instanceof Error) { + args.error = { + message: error.message, + stack: error.stack ?? "" + }; + } + interop.invoke(Logger.InteropMethodName, args); + } + } + catch { + } + } + } + if (this.canPublish(level)) { + let prefix = ""; + if (this.includeTimeAndLevel) { + const date = new Date(); + const time = `${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}:${date.getMilliseconds()}`; + prefix = `[${time}] [${level}] `; + } + const toPrint = `${prefix}${loggerName}: ${message}`; + switch (level) { + case "trace": + this.logFn.debug(toPrint); + break; + case "debug": + if (this.logFn.debug) { + this.logFn.debug(toPrint); + } + else { + this.logFn.log(toPrint); + } + break; + case "info": + this.logFn.info(toPrint); + break; + case "warn": + this.logFn.warn(toPrint); + break; + case "error": + this.logFn.error(toPrint, error); + break; + } + } + } + }; + + const GW_MESSAGE_CREATE_CONTEXT = "create-context"; + const GW_MESSAGE_ACTIVITY_CREATED = "created"; + const GW_MESSAGE_ACTIVITY_DESTROYED = "destroyed"; + const GW_MESSAGE_CONTEXT_CREATED = "context-created"; + const GW_MESSAGE_CONTEXT_ADDED = "context-added"; + const GW_MESSAGE_SUBSCRIBE_CONTEXT = "subscribe-context"; + const GW_MESSAGE_SUBSCRIBED_CONTEXT = "subscribed-context"; + const GW_MESSAGE_UNSUBSCRIBE_CONTEXT = "unsubscribe-context"; + const GW_MESSAGE_DESTROY_CONTEXT = "destroy-context"; + const GW_MESSAGE_CONTEXT_DESTROYED = "context-destroyed"; + const GW_MESSAGE_UPDATE_CONTEXT = "update-context"; + const GW_MESSAGE_CONTEXT_UPDATED = "context-updated"; + const GW_MESSAGE_JOINED_ACTIVITY = "joined"; + + const ContextMessageReplaySpec = { + get name() { + return "context"; + }, + get types() { + return [ + GW_MESSAGE_CREATE_CONTEXT, + GW_MESSAGE_ACTIVITY_CREATED, + GW_MESSAGE_ACTIVITY_DESTROYED, + GW_MESSAGE_CONTEXT_CREATED, + GW_MESSAGE_CONTEXT_ADDED, + GW_MESSAGE_SUBSCRIBE_CONTEXT, + GW_MESSAGE_SUBSCRIBED_CONTEXT, + GW_MESSAGE_UNSUBSCRIBE_CONTEXT, + GW_MESSAGE_DESTROY_CONTEXT, + GW_MESSAGE_CONTEXT_DESTROYED, + GW_MESSAGE_UPDATE_CONTEXT, + GW_MESSAGE_CONTEXT_UPDATED, + GW_MESSAGE_JOINED_ACTIVITY + ]; + } + }; + + var version$1 = "6.5.2-fmr-beta"; + + function prepareConfig$1 (configuration, ext, glue42gd) { + let nodeStartingContext; + if (Utils$1.isNode()) { + const startingContextString = process.env._GD_STARTING_CONTEXT_; + if (startingContextString) { + try { + nodeStartingContext = JSON.parse(startingContextString); + } + catch { + } + } + } + function getConnection() { + const gwConfig = configuration.gateway; + const protocolVersion = gwConfig?.protocolVersion ?? 3; + const reconnectInterval = gwConfig?.reconnectInterval; + const reconnectAttempts = gwConfig?.reconnectAttempts; + const defaultWs = "ws://localhost:8385"; + let ws = gwConfig?.ws; + const sharedWorker = gwConfig?.sharedWorker; + const inproc = gwConfig?.inproc; + const webPlatform = gwConfig?.webPlatform ?? undefined; + if (glue42gd) { + ws = glue42gd.gwURL; + } + if (Utils$1.isNode() && nodeStartingContext && nodeStartingContext.gwURL) { + ws = nodeStartingContext.gwURL; + } + if (!ws && !sharedWorker && !inproc) { + ws = defaultWs; + } + let instanceId; + let windowId; + let pid; + let environment; + let region; + const appName = getApplication(); + let uniqueAppName = appName; + if (typeof glue42gd !== "undefined") { + windowId = glue42gd.windowId; + pid = glue42gd.pid; + if (glue42gd.env) { + environment = glue42gd.env.env; + region = glue42gd.env.region; + } + uniqueAppName = glue42gd.application ?? "glue-app"; + instanceId = glue42gd.appInstanceId; + } + else if (Utils$1.isNode()) { + pid = process.pid; + if (nodeStartingContext) { + environment = nodeStartingContext.env; + region = nodeStartingContext.region; + instanceId = nodeStartingContext.instanceId; + } + } + else if (typeof window?.glue42electron !== "undefined") { + windowId = window?.glue42electron.instanceId; + pid = window?.glue42electron.pid; + environment = window?.glue42electron.env; + region = window?.glue42electron.region; + uniqueAppName = window?.glue42electron.application ?? "glue-app"; + instanceId = window?.glue42electron.instanceId; + } + else ; + const replaySpecs = configuration.gateway?.replaySpecs ?? []; + replaySpecs.push(ContextMessageReplaySpec); + let identity = { + application: uniqueAppName, + applicationName: appName, + windowId, + instance: instanceId, + process: pid, + region, + environment, + api: ext.version || version$1 + }; + if (configuration.identity) { + identity = Object.assign(identity, configuration.identity); + } + return { + identity, + reconnectInterval, + ws, + sharedWorker, + webPlatform, + inproc, + protocolVersion, + reconnectAttempts, + replaySpecs, + }; + } + function getContexts() { + if (typeof configuration.contexts === "undefined") { + return { reAnnounceKnownContexts: true }; + } + if (typeof configuration.contexts === "boolean" && configuration.contexts) { + return { reAnnounceKnownContexts: true }; + } + if (typeof configuration.contexts === "object") { + return Object.assign({}, { reAnnounceKnownContexts: true }, configuration.contexts); + } + return false; + } + function getApplication() { + if (configuration.application) { + return configuration.application; + } + if (glue42gd) { + return glue42gd.applicationName; + } + if (typeof window !== "undefined" && typeof window.glue42electron !== "undefined") { + return window.glue42electron.application; + } + const uid = nanoid$1(10); + if (Utils$1.isNode()) { + if (nodeStartingContext) { + return nodeStartingContext.applicationConfig.name; + } + return "NodeJS" + uid; + } + if (typeof window !== "undefined" && typeof document !== "undefined") { + return document.title + ` (${uid})`; + } + return uid; + } + function getAuth() { + if (typeof configuration.auth === "string") { + return { + token: configuration.auth + }; + } + if (configuration.auth) { + return configuration.auth; + } + if (Utils$1.isNode() && nodeStartingContext && nodeStartingContext.gwToken) { + return { + gatewayToken: nodeStartingContext.gwToken + }; + } + if (configuration.gateway?.webPlatform || configuration.gateway?.inproc || configuration.gateway?.sharedWorker) { + return { + username: "glue42", password: "glue42" + }; + } + } + function getLogger() { + let config = configuration.logger; + const defaultLevel = "warn"; + if (!config) { + config = defaultLevel; + } + let gdConsoleLevel; + if (glue42gd) { + gdConsoleLevel = glue42gd.consoleLogLevel; + } + if (typeof config === "string") { + return { console: gdConsoleLevel ?? config, publish: defaultLevel }; + } + return { + console: gdConsoleLevel ?? config.console ?? defaultLevel, + publish: config.publish ?? defaultLevel + }; + } + const connection = getConnection(); + let application = getApplication(); + if (typeof window !== "undefined") { + const windowAsAny = window; + const containerApplication = windowAsAny.htmlContainer ? + `${windowAsAny.htmlContainer.containerName}.${windowAsAny.htmlContainer.application}` : + windowAsAny?.glue42gd?.application; + if (containerApplication) { + application = containerApplication; + } + } + return { + bus: configuration.bus ?? false, + application, + auth: getAuth(), + logger: getLogger(), + connection, + metrics: configuration.metrics ?? true, + contexts: getContexts(), + version: ext.version || version$1, + libs: ext.libs ?? [], + customLogger: configuration.customLogger + }; + } + + class GW3ContextData { + name; + contextId; + context; + isAnnounced; + joinedActivity; + updateCallbacks = {}; + activityId; + sentExplicitSubscription; + hasReceivedSnapshot; + constructor(contextId, name, isAnnounced, activityId) { + this.contextId = contextId; + this.name = name; + this.isAnnounced = isAnnounced; + this.activityId = activityId; + this.context = {}; + } + hasCallbacks() { + return Object.keys(this.updateCallbacks).length > 0; + } + getState() { + if (this.isAnnounced && this.hasCallbacks()) { + return 3; + } + if (this.isAnnounced) { + return 2; + } + if (this.hasCallbacks()) { + return 1; + } + return 0; + } + } + + var lodash_clonedeep = {exports: {}}; + + /** + * lodash (Custom Build) + * Build: `lodash modularize exports="npm" -o ./` + * Copyright jQuery Foundation and other contributors + * Released under MIT license + * Based on Underscore.js 1.8.3 + * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + */ + lodash_clonedeep.exports; + + (function (module, exports) { + /** Used as the size to enable large array optimizations. */ + var LARGE_ARRAY_SIZE = 200; + + /** Used to stand-in for `undefined` hash values. */ + var HASH_UNDEFINED = '__lodash_hash_undefined__'; + + /** Used as references for various `Number` constants. */ + var MAX_SAFE_INTEGER = 9007199254740991; + + /** `Object#toString` result references. */ + var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + boolTag = '[object Boolean]', + dateTag = '[object Date]', + errorTag = '[object Error]', + funcTag = '[object Function]', + genTag = '[object GeneratorFunction]', + mapTag = '[object Map]', + numberTag = '[object Number]', + objectTag = '[object Object]', + promiseTag = '[object Promise]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + symbolTag = '[object Symbol]', + weakMapTag = '[object WeakMap]'; + + var arrayBufferTag = '[object ArrayBuffer]', + dataViewTag = '[object DataView]', + float32Tag = '[object Float32Array]', + float64Tag = '[object Float64Array]', + int8Tag = '[object Int8Array]', + int16Tag = '[object Int16Array]', + int32Tag = '[object Int32Array]', + uint8Tag = '[object Uint8Array]', + uint8ClampedTag = '[object Uint8ClampedArray]', + uint16Tag = '[object Uint16Array]', + uint32Tag = '[object Uint32Array]'; + + /** + * Used to match `RegExp` + * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns). + */ + var reRegExpChar = /[\\^$.*+?()[\]{}|]/g; + + /** Used to match `RegExp` flags from their coerced string values. */ + var reFlags = /\w*$/; + + /** Used to detect host constructors (Safari). */ + var reIsHostCtor = /^\[object .+?Constructor\]$/; + + /** Used to detect unsigned integer values. */ + var reIsUint = /^(?:0|[1-9]\d*)$/; + + /** Used to identify `toStringTag` values supported by `_.clone`. */ + var cloneableTags = {}; + cloneableTags[argsTag] = cloneableTags[arrayTag] = + cloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] = + cloneableTags[boolTag] = cloneableTags[dateTag] = + cloneableTags[float32Tag] = cloneableTags[float64Tag] = + cloneableTags[int8Tag] = cloneableTags[int16Tag] = + cloneableTags[int32Tag] = cloneableTags[mapTag] = + cloneableTags[numberTag] = cloneableTags[objectTag] = + cloneableTags[regexpTag] = cloneableTags[setTag] = + cloneableTags[stringTag] = cloneableTags[symbolTag] = + cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] = + cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true; + cloneableTags[errorTag] = cloneableTags[funcTag] = + cloneableTags[weakMapTag] = false; + + /** Detect free variable `global` from Node.js. */ + var freeGlobal = typeof commonjsGlobal$1 == 'object' && commonjsGlobal$1 && commonjsGlobal$1.Object === Object && commonjsGlobal$1; + + /** Detect free variable `self`. */ + var freeSelf = typeof self == 'object' && self && self.Object === Object && self; + + /** Used as a reference to the global object. */ + var root = freeGlobal || freeSelf || Function('return this')(); + + /** Detect free variable `exports`. */ + var freeExports = exports && !exports.nodeType && exports; + + /** Detect free variable `module`. */ + var freeModule = freeExports && 'object' == 'object' && module && !module.nodeType && module; + + /** Detect the popular CommonJS extension `module.exports`. */ + var moduleExports = freeModule && freeModule.exports === freeExports; + + /** + * Adds the key-value `pair` to `map`. + * + * @private + * @param {Object} map The map to modify. + * @param {Array} pair The key-value pair to add. + * @returns {Object} Returns `map`. + */ + function addMapEntry(map, pair) { + // Don't return `map.set` because it's not chainable in IE 11. + map.set(pair[0], pair[1]); + return map; + } + + /** + * Adds `value` to `set`. + * + * @private + * @param {Object} set The set to modify. + * @param {*} value The value to add. + * @returns {Object} Returns `set`. + */ + function addSetEntry(set, value) { + // Don't return `set.add` because it's not chainable in IE 11. + set.add(value); + return set; + } + + /** + * A specialized version of `_.forEach` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns `array`. + */ + function arrayEach(array, iteratee) { + var index = -1, + length = array ? array.length : 0; + + while (++index < length) { + if (iteratee(array[index], index, array) === false) { + break; + } + } + return array; + } + + /** + * Appends the elements of `values` to `array`. + * + * @private + * @param {Array} array The array to modify. + * @param {Array} values The values to append. + * @returns {Array} Returns `array`. + */ + function arrayPush(array, values) { + var index = -1, + length = values.length, + offset = array.length; + + while (++index < length) { + array[offset + index] = values[index]; + } + return array; + } + + /** + * A specialized version of `_.reduce` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {boolean} [initAccum] Specify using the first element of `array` as + * the initial value. + * @returns {*} Returns the accumulated value. + */ + function arrayReduce(array, iteratee, accumulator, initAccum) { + var index = -1, + length = array ? array.length : 0; + while (++index < length) { + accumulator = iteratee(accumulator, array[index], index, array); + } + return accumulator; + } + + /** + * The base implementation of `_.times` without support for iteratee shorthands + * or max array length checks. + * + * @private + * @param {number} n The number of times to invoke `iteratee`. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the array of results. + */ + function baseTimes(n, iteratee) { + var index = -1, + result = Array(n); + + while (++index < n) { + result[index] = iteratee(index); + } + return result; + } + + /** + * Gets the value at `key` of `object`. + * + * @private + * @param {Object} [object] The object to query. + * @param {string} key The key of the property to get. + * @returns {*} Returns the property value. + */ + function getValue(object, key) { + return object == null ? undefined : object[key]; + } + + /** + * Checks if `value` is a host object in IE < 9. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a host object, else `false`. + */ + function isHostObject(value) { + // Many host objects are `Object` objects that can coerce to strings + // despite having improperly defined `toString` methods. + var result = false; + if (value != null && typeof value.toString != 'function') { + try { + result = !!(value + ''); + } catch (e) {} + } + return result; + } + + /** + * Converts `map` to its key-value pairs. + * + * @private + * @param {Object} map The map to convert. + * @returns {Array} Returns the key-value pairs. + */ + function mapToArray(map) { + var index = -1, + result = Array(map.size); + + map.forEach(function(value, key) { + result[++index] = [key, value]; + }); + return result; + } + + /** + * Creates a unary function that invokes `func` with its argument transformed. + * + * @private + * @param {Function} func The function to wrap. + * @param {Function} transform The argument transform. + * @returns {Function} Returns the new function. + */ + function overArg(func, transform) { + return function(arg) { + return func(transform(arg)); + }; + } + + /** + * Converts `set` to an array of its values. + * + * @private + * @param {Object} set The set to convert. + * @returns {Array} Returns the values. + */ + function setToArray(set) { + var index = -1, + result = Array(set.size); + + set.forEach(function(value) { + result[++index] = value; + }); + return result; + } + + /** Used for built-in method references. */ + var arrayProto = Array.prototype, + funcProto = Function.prototype, + objectProto = Object.prototype; + + /** Used to detect overreaching core-js shims. */ + var coreJsData = root['__core-js_shared__']; + + /** Used to detect methods masquerading as native. */ + var maskSrcKey = (function() { + var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || ''); + return uid ? ('Symbol(src)_1.' + uid) : ''; + }()); + + /** Used to resolve the decompiled source of functions. */ + var funcToString = funcProto.toString; + + /** Used to check objects for own properties. */ + var hasOwnProperty = objectProto.hasOwnProperty; + + /** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ + var objectToString = objectProto.toString; + + /** Used to detect if a method is native. */ + var reIsNative = RegExp('^' + + funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&') + .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' + ); + + /** Built-in value references. */ + var Buffer = moduleExports ? root.Buffer : undefined, + Symbol = root.Symbol, + Uint8Array = root.Uint8Array, + getPrototype = overArg(Object.getPrototypeOf, Object), + objectCreate = Object.create, + propertyIsEnumerable = objectProto.propertyIsEnumerable, + splice = arrayProto.splice; + + /* Built-in method references for those with the same name as other `lodash` methods. */ + var nativeGetSymbols = Object.getOwnPropertySymbols, + nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined, + nativeKeys = overArg(Object.keys, Object); + + /* Built-in method references that are verified to be native. */ + var DataView = getNative(root, 'DataView'), + Map = getNative(root, 'Map'), + Promise = getNative(root, 'Promise'), + Set = getNative(root, 'Set'), + WeakMap = getNative(root, 'WeakMap'), + nativeCreate = getNative(Object, 'create'); + + /** Used to detect maps, sets, and weakmaps. */ + var dataViewCtorString = toSource(DataView), + mapCtorString = toSource(Map), + promiseCtorString = toSource(Promise), + setCtorString = toSource(Set), + weakMapCtorString = toSource(WeakMap); + + /** Used to convert symbols to primitives and strings. */ + var symbolProto = Symbol ? Symbol.prototype : undefined, + symbolValueOf = symbolProto ? symbolProto.valueOf : undefined; + + /** + * Creates a hash object. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + function Hash(entries) { + var index = -1, + length = entries ? entries.length : 0; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } + } + + /** + * Removes all key-value entries from the hash. + * + * @private + * @name clear + * @memberOf Hash + */ + function hashClear() { + this.__data__ = nativeCreate ? nativeCreate(null) : {}; + } + + /** + * Removes `key` and its value from the hash. + * + * @private + * @name delete + * @memberOf Hash + * @param {Object} hash The hash to modify. + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function hashDelete(key) { + return this.has(key) && delete this.__data__[key]; + } + + /** + * Gets the hash value for `key`. + * + * @private + * @name get + * @memberOf Hash + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function hashGet(key) { + var data = this.__data__; + if (nativeCreate) { + var result = data[key]; + return result === HASH_UNDEFINED ? undefined : result; + } + return hasOwnProperty.call(data, key) ? data[key] : undefined; + } + + /** + * Checks if a hash value for `key` exists. + * + * @private + * @name has + * @memberOf Hash + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function hashHas(key) { + var data = this.__data__; + return nativeCreate ? data[key] !== undefined : hasOwnProperty.call(data, key); + } + + /** + * Sets the hash `key` to `value`. + * + * @private + * @name set + * @memberOf Hash + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the hash instance. + */ + function hashSet(key, value) { + var data = this.__data__; + data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value; + return this; + } + + // Add methods to `Hash`. + Hash.prototype.clear = hashClear; + Hash.prototype['delete'] = hashDelete; + Hash.prototype.get = hashGet; + Hash.prototype.has = hashHas; + Hash.prototype.set = hashSet; + + /** + * Creates an list cache object. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + function ListCache(entries) { + var index = -1, + length = entries ? entries.length : 0; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } + } + + /** + * Removes all key-value entries from the list cache. + * + * @private + * @name clear + * @memberOf ListCache + */ + function listCacheClear() { + this.__data__ = []; + } + + /** + * Removes `key` and its value from the list cache. + * + * @private + * @name delete + * @memberOf ListCache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function listCacheDelete(key) { + var data = this.__data__, + index = assocIndexOf(data, key); + + if (index < 0) { + return false; + } + var lastIndex = data.length - 1; + if (index == lastIndex) { + data.pop(); + } else { + splice.call(data, index, 1); + } + return true; + } + + /** + * Gets the list cache value for `key`. + * + * @private + * @name get + * @memberOf ListCache + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function listCacheGet(key) { + var data = this.__data__, + index = assocIndexOf(data, key); + + return index < 0 ? undefined : data[index][1]; + } + + /** + * Checks if a list cache value for `key` exists. + * + * @private + * @name has + * @memberOf ListCache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function listCacheHas(key) { + return assocIndexOf(this.__data__, key) > -1; + } + + /** + * Sets the list cache `key` to `value`. + * + * @private + * @name set + * @memberOf ListCache + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the list cache instance. + */ + function listCacheSet(key, value) { + var data = this.__data__, + index = assocIndexOf(data, key); + + if (index < 0) { + data.push([key, value]); + } else { + data[index][1] = value; + } + return this; + } + + // Add methods to `ListCache`. + ListCache.prototype.clear = listCacheClear; + ListCache.prototype['delete'] = listCacheDelete; + ListCache.prototype.get = listCacheGet; + ListCache.prototype.has = listCacheHas; + ListCache.prototype.set = listCacheSet; + + /** + * Creates a map cache object to store key-value pairs. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + function MapCache(entries) { + var index = -1, + length = entries ? entries.length : 0; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } + } + + /** + * Removes all key-value entries from the map. + * + * @private + * @name clear + * @memberOf MapCache + */ + function mapCacheClear() { + this.__data__ = { + 'hash': new Hash, + 'map': new (Map || ListCache), + 'string': new Hash + }; + } + + /** + * Removes `key` and its value from the map. + * + * @private + * @name delete + * @memberOf MapCache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function mapCacheDelete(key) { + return getMapData(this, key)['delete'](key); + } + + /** + * Gets the map value for `key`. + * + * @private + * @name get + * @memberOf MapCache + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function mapCacheGet(key) { + return getMapData(this, key).get(key); + } + + /** + * Checks if a map value for `key` exists. + * + * @private + * @name has + * @memberOf MapCache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function mapCacheHas(key) { + return getMapData(this, key).has(key); + } + + /** + * Sets the map `key` to `value`. + * + * @private + * @name set + * @memberOf MapCache + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the map cache instance. + */ + function mapCacheSet(key, value) { + getMapData(this, key).set(key, value); + return this; + } + + // Add methods to `MapCache`. + MapCache.prototype.clear = mapCacheClear; + MapCache.prototype['delete'] = mapCacheDelete; + MapCache.prototype.get = mapCacheGet; + MapCache.prototype.has = mapCacheHas; + MapCache.prototype.set = mapCacheSet; + + /** + * Creates a stack cache object to store key-value pairs. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + function Stack(entries) { + this.__data__ = new ListCache(entries); + } + + /** + * Removes all key-value entries from the stack. + * + * @private + * @name clear + * @memberOf Stack + */ + function stackClear() { + this.__data__ = new ListCache; + } + + /** + * Removes `key` and its value from the stack. + * + * @private + * @name delete + * @memberOf Stack + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function stackDelete(key) { + return this.__data__['delete'](key); + } + + /** + * Gets the stack value for `key`. + * + * @private + * @name get + * @memberOf Stack + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function stackGet(key) { + return this.__data__.get(key); + } + + /** + * Checks if a stack value for `key` exists. + * + * @private + * @name has + * @memberOf Stack + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function stackHas(key) { + return this.__data__.has(key); + } + + /** + * Sets the stack `key` to `value`. + * + * @private + * @name set + * @memberOf Stack + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the stack cache instance. + */ + function stackSet(key, value) { + var cache = this.__data__; + if (cache instanceof ListCache) { + var pairs = cache.__data__; + if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) { + pairs.push([key, value]); + return this; + } + cache = this.__data__ = new MapCache(pairs); + } + cache.set(key, value); + return this; + } + + // Add methods to `Stack`. + Stack.prototype.clear = stackClear; + Stack.prototype['delete'] = stackDelete; + Stack.prototype.get = stackGet; + Stack.prototype.has = stackHas; + Stack.prototype.set = stackSet; + + /** + * Creates an array of the enumerable property names of the array-like `value`. + * + * @private + * @param {*} value The value to query. + * @param {boolean} inherited Specify returning inherited property names. + * @returns {Array} Returns the array of property names. + */ + function arrayLikeKeys(value, inherited) { + // Safari 8.1 makes `arguments.callee` enumerable in strict mode. + // Safari 9 makes `arguments.length` enumerable in strict mode. + var result = (isArray(value) || isArguments(value)) + ? baseTimes(value.length, String) + : []; + + var length = result.length, + skipIndexes = !!length; + + for (var key in value) { + if ((hasOwnProperty.call(value, key)) && + !(skipIndexes && (key == 'length' || isIndex(key, length)))) { + result.push(key); + } + } + return result; + } + + /** + * Assigns `value` to `key` of `object` if the existing value is not equivalent + * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. + * + * @private + * @param {Object} object The object to modify. + * @param {string} key The key of the property to assign. + * @param {*} value The value to assign. + */ + function assignValue(object, key, value) { + var objValue = object[key]; + if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) || + (value === undefined && !(key in object))) { + object[key] = value; + } + } + + /** + * Gets the index at which the `key` is found in `array` of key-value pairs. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} key The key to search for. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function assocIndexOf(array, key) { + var length = array.length; + while (length--) { + if (eq(array[length][0], key)) { + return length; + } + } + return -1; + } + + /** + * The base implementation of `_.assign` without support for multiple sources + * or `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @returns {Object} Returns `object`. + */ + function baseAssign(object, source) { + return object && copyObject(source, keys(source), object); + } + + /** + * The base implementation of `_.clone` and `_.cloneDeep` which tracks + * traversed objects. + * + * @private + * @param {*} value The value to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @param {boolean} [isFull] Specify a clone including symbols. + * @param {Function} [customizer] The function to customize cloning. + * @param {string} [key] The key of `value`. + * @param {Object} [object] The parent object of `value`. + * @param {Object} [stack] Tracks traversed objects and their clone counterparts. + * @returns {*} Returns the cloned value. + */ + function baseClone(value, isDeep, isFull, customizer, key, object, stack) { + var result; + if (customizer) { + result = object ? customizer(value, key, object, stack) : customizer(value); + } + if (result !== undefined) { + return result; + } + if (!isObject(value)) { + return value; + } + var isArr = isArray(value); + if (isArr) { + result = initCloneArray(value); + if (!isDeep) { + return copyArray(value, result); + } + } else { + var tag = getTag(value), + isFunc = tag == funcTag || tag == genTag; + + if (isBuffer(value)) { + return cloneBuffer(value, isDeep); + } + if (tag == objectTag || tag == argsTag || (isFunc && !object)) { + if (isHostObject(value)) { + return object ? value : {}; + } + result = initCloneObject(isFunc ? {} : value); + if (!isDeep) { + return copySymbols(value, baseAssign(result, value)); + } + } else { + if (!cloneableTags[tag]) { + return object ? value : {}; + } + result = initCloneByTag(value, tag, baseClone, isDeep); + } + } + // Check for circular references and return its corresponding clone. + stack || (stack = new Stack); + var stacked = stack.get(value); + if (stacked) { + return stacked; + } + stack.set(value, result); + + if (!isArr) { + var props = isFull ? getAllKeys(value) : keys(value); + } + arrayEach(props || value, function(subValue, key) { + if (props) { + key = subValue; + subValue = value[key]; + } + // Recursively populate clone (susceptible to call stack limits). + assignValue(result, key, baseClone(subValue, isDeep, isFull, customizer, key, value, stack)); + }); + return result; + } + + /** + * The base implementation of `_.create` without support for assigning + * properties to the created object. + * + * @private + * @param {Object} prototype The object to inherit from. + * @returns {Object} Returns the new object. + */ + function baseCreate(proto) { + return isObject(proto) ? objectCreate(proto) : {}; + } + + /** + * The base implementation of `getAllKeys` and `getAllKeysIn` which uses + * `keysFunc` and `symbolsFunc` to get the enumerable property names and + * symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Function} keysFunc The function to get the keys of `object`. + * @param {Function} symbolsFunc The function to get the symbols of `object`. + * @returns {Array} Returns the array of property names and symbols. + */ + function baseGetAllKeys(object, keysFunc, symbolsFunc) { + var result = keysFunc(object); + return isArray(object) ? result : arrayPush(result, symbolsFunc(object)); + } + + /** + * The base implementation of `getTag`. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the `toStringTag`. + */ + function baseGetTag(value) { + return objectToString.call(value); + } + + /** + * The base implementation of `_.isNative` without bad shim checks. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a native function, + * else `false`. + */ + function baseIsNative(value) { + if (!isObject(value) || isMasked(value)) { + return false; + } + var pattern = (isFunction(value) || isHostObject(value)) ? reIsNative : reIsHostCtor; + return pattern.test(toSource(value)); + } + + /** + * The base implementation of `_.keys` which doesn't treat sparse arrays as dense. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ + function baseKeys(object) { + if (!isPrototype(object)) { + return nativeKeys(object); + } + var result = []; + for (var key in Object(object)) { + if (hasOwnProperty.call(object, key) && key != 'constructor') { + result.push(key); + } + } + return result; + } + + /** + * Creates a clone of `buffer`. + * + * @private + * @param {Buffer} buffer The buffer to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Buffer} Returns the cloned buffer. + */ + function cloneBuffer(buffer, isDeep) { + if (isDeep) { + return buffer.slice(); + } + var result = new buffer.constructor(buffer.length); + buffer.copy(result); + return result; + } + + /** + * Creates a clone of `arrayBuffer`. + * + * @private + * @param {ArrayBuffer} arrayBuffer The array buffer to clone. + * @returns {ArrayBuffer} Returns the cloned array buffer. + */ + function cloneArrayBuffer(arrayBuffer) { + var result = new arrayBuffer.constructor(arrayBuffer.byteLength); + new Uint8Array(result).set(new Uint8Array(arrayBuffer)); + return result; + } + + /** + * Creates a clone of `dataView`. + * + * @private + * @param {Object} dataView The data view to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned data view. + */ + function cloneDataView(dataView, isDeep) { + var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer; + return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength); + } + + /** + * Creates a clone of `map`. + * + * @private + * @param {Object} map The map to clone. + * @param {Function} cloneFunc The function to clone values. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned map. + */ + function cloneMap(map, isDeep, cloneFunc) { + var array = isDeep ? cloneFunc(mapToArray(map), true) : mapToArray(map); + return arrayReduce(array, addMapEntry, new map.constructor); + } + + /** + * Creates a clone of `regexp`. + * + * @private + * @param {Object} regexp The regexp to clone. + * @returns {Object} Returns the cloned regexp. + */ + function cloneRegExp(regexp) { + var result = new regexp.constructor(regexp.source, reFlags.exec(regexp)); + result.lastIndex = regexp.lastIndex; + return result; + } + + /** + * Creates a clone of `set`. + * + * @private + * @param {Object} set The set to clone. + * @param {Function} cloneFunc The function to clone values. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned set. + */ + function cloneSet(set, isDeep, cloneFunc) { + var array = isDeep ? cloneFunc(setToArray(set), true) : setToArray(set); + return arrayReduce(array, addSetEntry, new set.constructor); + } + + /** + * Creates a clone of the `symbol` object. + * + * @private + * @param {Object} symbol The symbol object to clone. + * @returns {Object} Returns the cloned symbol object. + */ + function cloneSymbol(symbol) { + return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {}; + } + + /** + * Creates a clone of `typedArray`. + * + * @private + * @param {Object} typedArray The typed array to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned typed array. + */ + function cloneTypedArray(typedArray, isDeep) { + var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer; + return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length); + } + + /** + * Copies the values of `source` to `array`. + * + * @private + * @param {Array} source The array to copy values from. + * @param {Array} [array=[]] The array to copy values to. + * @returns {Array} Returns `array`. + */ + function copyArray(source, array) { + var index = -1, + length = source.length; + + array || (array = Array(length)); + while (++index < length) { + array[index] = source[index]; + } + return array; + } + + /** + * Copies properties of `source` to `object`. + * + * @private + * @param {Object} source The object to copy properties from. + * @param {Array} props The property identifiers to copy. + * @param {Object} [object={}] The object to copy properties to. + * @param {Function} [customizer] The function to customize copied values. + * @returns {Object} Returns `object`. + */ + function copyObject(source, props, object, customizer) { + object || (object = {}); + + var index = -1, + length = props.length; + + while (++index < length) { + var key = props[index]; + + var newValue = undefined; + + assignValue(object, key, newValue === undefined ? source[key] : newValue); + } + return object; + } + + /** + * Copies own symbol properties of `source` to `object`. + * + * @private + * @param {Object} source The object to copy symbols from. + * @param {Object} [object={}] The object to copy symbols to. + * @returns {Object} Returns `object`. + */ + function copySymbols(source, object) { + return copyObject(source, getSymbols(source), object); + } + + /** + * Creates an array of own enumerable property names and symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names and symbols. + */ + function getAllKeys(object) { + return baseGetAllKeys(object, keys, getSymbols); + } + + /** + * Gets the data for `map`. + * + * @private + * @param {Object} map The map to query. + * @param {string} key The reference key. + * @returns {*} Returns the map data. + */ + function getMapData(map, key) { + var data = map.__data__; + return isKeyable(key) + ? data[typeof key == 'string' ? 'string' : 'hash'] + : data.map; + } + + /** + * Gets the native function at `key` of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {string} key The key of the method to get. + * @returns {*} Returns the function if it's native, else `undefined`. + */ + function getNative(object, key) { + var value = getValue(object, key); + return baseIsNative(value) ? value : undefined; + } + + /** + * Creates an array of the own enumerable symbol properties of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. + */ + var getSymbols = nativeGetSymbols ? overArg(nativeGetSymbols, Object) : stubArray; + + /** + * Gets the `toStringTag` of `value`. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the `toStringTag`. + */ + var getTag = baseGetTag; + + // Fallback for data views, maps, sets, and weak maps in IE 11, + // for data views in Edge < 14, and promises in Node.js. + if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) || + (Map && getTag(new Map) != mapTag) || + (Promise && getTag(Promise.resolve()) != promiseTag) || + (Set && getTag(new Set) != setTag) || + (WeakMap && getTag(new WeakMap) != weakMapTag)) { + getTag = function(value) { + var result = objectToString.call(value), + Ctor = result == objectTag ? value.constructor : undefined, + ctorString = Ctor ? toSource(Ctor) : undefined; + + if (ctorString) { + switch (ctorString) { + case dataViewCtorString: return dataViewTag; + case mapCtorString: return mapTag; + case promiseCtorString: return promiseTag; + case setCtorString: return setTag; + case weakMapCtorString: return weakMapTag; + } + } + return result; + }; + } + + /** + * Initializes an array clone. + * + * @private + * @param {Array} array The array to clone. + * @returns {Array} Returns the initialized clone. + */ + function initCloneArray(array) { + var length = array.length, + result = array.constructor(length); + + // Add properties assigned by `RegExp#exec`. + if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) { + result.index = array.index; + result.input = array.input; + } + return result; + } + + /** + * Initializes an object clone. + * + * @private + * @param {Object} object The object to clone. + * @returns {Object} Returns the initialized clone. + */ + function initCloneObject(object) { + return (typeof object.constructor == 'function' && !isPrototype(object)) + ? baseCreate(getPrototype(object)) + : {}; + } + + /** + * Initializes an object clone based on its `toStringTag`. + * + * **Note:** This function only supports cloning values with tags of + * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. + * + * @private + * @param {Object} object The object to clone. + * @param {string} tag The `toStringTag` of the object to clone. + * @param {Function} cloneFunc The function to clone values. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the initialized clone. + */ + function initCloneByTag(object, tag, cloneFunc, isDeep) { + var Ctor = object.constructor; + switch (tag) { + case arrayBufferTag: + return cloneArrayBuffer(object); + + case boolTag: + case dateTag: + return new Ctor(+object); + + case dataViewTag: + return cloneDataView(object, isDeep); + + case float32Tag: case float64Tag: + case int8Tag: case int16Tag: case int32Tag: + case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag: + return cloneTypedArray(object, isDeep); + + case mapTag: + return cloneMap(object, isDeep, cloneFunc); + + case numberTag: + case stringTag: + return new Ctor(object); + + case regexpTag: + return cloneRegExp(object); + + case setTag: + return cloneSet(object, isDeep, cloneFunc); + + case symbolTag: + return cloneSymbol(object); + } + } + + /** + * Checks if `value` is a valid array-like index. + * + * @private + * @param {*} value The value to check. + * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. + * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. + */ + function isIndex(value, length) { + length = length == null ? MAX_SAFE_INTEGER : length; + return !!length && + (typeof value == 'number' || reIsUint.test(value)) && + (value > -1 && value % 1 == 0 && value < length); + } + + /** + * Checks if `value` is suitable for use as unique object key. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is suitable, else `false`. + */ + function isKeyable(value) { + var type = typeof value; + return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean') + ? (value !== '__proto__') + : (value === null); + } + + /** + * Checks if `func` has its source masked. + * + * @private + * @param {Function} func The function to check. + * @returns {boolean} Returns `true` if `func` is masked, else `false`. + */ + function isMasked(func) { + return !!maskSrcKey && (maskSrcKey in func); + } + + /** + * Checks if `value` is likely a prototype object. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a prototype, else `false`. + */ + function isPrototype(value) { + var Ctor = value && value.constructor, + proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto; + + return value === proto; + } + + /** + * Converts `func` to its source code. + * + * @private + * @param {Function} func The function to process. + * @returns {string} Returns the source code. + */ + function toSource(func) { + if (func != null) { + try { + return funcToString.call(func); + } catch (e) {} + try { + return (func + ''); + } catch (e) {} + } + return ''; + } + + /** + * This method is like `_.clone` except that it recursively clones `value`. + * + * @static + * @memberOf _ + * @since 1.0.0 + * @category Lang + * @param {*} value The value to recursively clone. + * @returns {*} Returns the deep cloned value. + * @see _.clone + * @example + * + * var objects = [{ 'a': 1 }, { 'b': 2 }]; + * + * var deep = _.cloneDeep(objects); + * console.log(deep[0] === objects[0]); + * // => false + */ + function cloneDeep(value) { + return baseClone(value, true, true); + } + + /** + * Performs a + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * comparison between two values to determine if they are equivalent. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'a': 1 }; + * var other = { 'a': 1 }; + * + * _.eq(object, object); + * // => true + * + * _.eq(object, other); + * // => false + * + * _.eq('a', 'a'); + * // => true + * + * _.eq('a', Object('a')); + * // => false + * + * _.eq(NaN, NaN); + * // => true + */ + function eq(value, other) { + return value === other || (value !== value && other !== other); + } + + /** + * Checks if `value` is likely an `arguments` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an `arguments` object, + * else `false`. + * @example + * + * _.isArguments(function() { return arguments; }()); + * // => true + * + * _.isArguments([1, 2, 3]); + * // => false + */ + function isArguments(value) { + // Safari 8.1 makes `arguments.callee` enumerable in strict mode. + return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') && + (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag); + } + + /** + * Checks if `value` is classified as an `Array` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array, else `false`. + * @example + * + * _.isArray([1, 2, 3]); + * // => true + * + * _.isArray(document.body.children); + * // => false + * + * _.isArray('abc'); + * // => false + * + * _.isArray(_.noop); + * // => false + */ + var isArray = Array.isArray; + + /** + * Checks if `value` is array-like. A value is considered array-like if it's + * not a function and has a `value.length` that's an integer greater than or + * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is array-like, else `false`. + * @example + * + * _.isArrayLike([1, 2, 3]); + * // => true + * + * _.isArrayLike(document.body.children); + * // => true + * + * _.isArrayLike('abc'); + * // => true + * + * _.isArrayLike(_.noop); + * // => false + */ + function isArrayLike(value) { + return value != null && isLength(value.length) && !isFunction(value); + } + + /** + * This method is like `_.isArrayLike` except that it also checks if `value` + * is an object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array-like object, + * else `false`. + * @example + * + * _.isArrayLikeObject([1, 2, 3]); + * // => true + * + * _.isArrayLikeObject(document.body.children); + * // => true + * + * _.isArrayLikeObject('abc'); + * // => false + * + * _.isArrayLikeObject(_.noop); + * // => false + */ + function isArrayLikeObject(value) { + return isObjectLike(value) && isArrayLike(value); + } + + /** + * Checks if `value` is a buffer. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a buffer, else `false`. + * @example + * + * _.isBuffer(new Buffer(2)); + * // => true + * + * _.isBuffer(new Uint8Array(2)); + * // => false + */ + var isBuffer = nativeIsBuffer || stubFalse; + + /** + * Checks if `value` is classified as a `Function` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a function, else `false`. + * @example + * + * _.isFunction(_); + * // => true + * + * _.isFunction(/abc/); + * // => false + */ + function isFunction(value) { + // The use of `Object#toString` avoids issues with the `typeof` operator + // in Safari 8-9 which returns 'object' for typed array and other constructors. + var tag = isObject(value) ? objectToString.call(value) : ''; + return tag == funcTag || tag == genTag; + } + + /** + * Checks if `value` is a valid array-like length. + * + * **Note:** This method is loosely based on + * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. + * @example + * + * _.isLength(3); + * // => true + * + * _.isLength(Number.MIN_VALUE); + * // => false + * + * _.isLength(Infinity); + * // => false + * + * _.isLength('3'); + * // => false + */ + function isLength(value) { + return typeof value == 'number' && + value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; + } + + /** + * Checks if `value` is the + * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) + * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(_.noop); + * // => true + * + * _.isObject(null); + * // => false + */ + function isObject(value) { + var type = typeof value; + return !!value && (type == 'object' || type == 'function'); + } + + /** + * Checks if `value` is object-like. A value is object-like if it's not `null` + * and has a `typeof` result of "object". + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @example + * + * _.isObjectLike({}); + * // => true + * + * _.isObjectLike([1, 2, 3]); + * // => true + * + * _.isObjectLike(_.noop); + * // => false + * + * _.isObjectLike(null); + * // => false + */ + function isObjectLike(value) { + return !!value && typeof value == 'object'; + } + + /** + * Creates an array of the own enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. See the + * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) + * for more details. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keys(new Foo); + * // => ['a', 'b'] (iteration order is not guaranteed) + * + * _.keys('hi'); + * // => ['0', '1'] + */ + function keys(object) { + return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object); + } + + /** + * This method returns a new empty array. + * + * @static + * @memberOf _ + * @since 4.13.0 + * @category Util + * @returns {Array} Returns the new empty array. + * @example + * + * var arrays = _.times(2, _.stubArray); + * + * console.log(arrays); + * // => [[], []] + * + * console.log(arrays[0] === arrays[1]); + * // => false + */ + function stubArray() { + return []; + } + + /** + * This method returns `false`. + * + * @static + * @memberOf _ + * @since 4.13.0 + * @category Util + * @returns {boolean} Returns `false`. + * @example + * + * _.times(2, _.stubFalse); + * // => [false, false] + */ + function stubFalse() { + return false; + } + + module.exports = cloneDeep; + } (lodash_clonedeep, lodash_clonedeep.exports)); + + var lodash_clonedeepExports = lodash_clonedeep.exports; + var cloneDeep = /*@__PURE__*/getDefaultExportFromCjs$1(lodash_clonedeepExports); + + function applyContextDelta(context, delta, logger) { + try { + if (logger?.canPublish("trace")) { + logger?.trace(`applying context delta ${JSON.stringify(delta)} on context ${JSON.stringify(context)}`); + } + if (!delta) { + return context; + } + if (delta.reset) { + context = { ...delta.reset }; + return context; + } + context = deepClone(context, undefined); + if (delta.commands) { + for (const command of delta.commands) { + if (command.type === "remove") { + deletePath(context, command.path); + } + else if (command.type === "set") { + setValueToPath(context, command.value, command.path); + } + } + return context; + } + const added = delta.added; + const updated = delta.updated; + const removed = delta.removed; + if (added) { + Object.keys(added).forEach((key) => { + context[key] = added[key]; + }); + } + if (updated) { + Object.keys(updated).forEach((key) => { + mergeObjectsProperties(key, context, updated); + }); + } + if (removed) { + removed.forEach((key) => { + delete context[key]; + }); + } + return context; + } + catch (e) { + logger?.error(`error applying context delta ${JSON.stringify(delta)} on context ${JSON.stringify(context)}`, e); + return context; + } + } + function deepClone(obj, hash) { + return cloneDeep(obj); + } + const mergeObjectsProperties = (key, what, withWhat) => { + const right = withWhat[key]; + if (right === undefined) { + return what; + } + const left = what[key]; + if (!left || !right) { + what[key] = right; + return what; + } + if (typeof left === "string" || + typeof left === "number" || + typeof left === "boolean" || + typeof right === "string" || + typeof right === "number" || + typeof right === "boolean" || + Array.isArray(left) || + Array.isArray(right)) { + what[key] = right; + return what; + } + what[key] = Object.assign({}, left, right); + return what; + }; + function deepEqual(x, y) { + if (x === y) { + return true; + } + if (!(x instanceof Object) || !(y instanceof Object)) { + return false; + } + if (x.constructor !== y.constructor) { + return false; + } + for (const p in x) { + if (!x.hasOwnProperty(p)) { + continue; + } + if (!y.hasOwnProperty(p)) { + return false; + } + if (x[p] === y[p]) { + continue; + } + if (typeof (x[p]) !== "object") { + return false; + } + if (!deepEqual(x[p], y[p])) { + return false; + } + } + for (const p in y) { + if (y.hasOwnProperty(p) && !x.hasOwnProperty(p)) { + return false; + } + } + return true; + } + function setValueToPath(obj, value, path) { + const pathArr = path.split("."); + let i; + for (i = 0; i < pathArr.length - 1; i++) { + if (!obj[pathArr[i]]) { + obj[pathArr[i]] = {}; + } + if (typeof obj[pathArr[i]] !== "object") { + obj[pathArr[i]] = {}; + } + obj = obj[pathArr[i]]; + } + obj[pathArr[i]] = value; + } + function isSubset(superObj, subObj) { + return Object.keys(subObj).every((ele) => { + if (typeof subObj[ele] === "object") { + return isSubset(superObj?.[ele] || {}, subObj[ele] || {}); + } + return subObj[ele] === superObj?.[ele]; + }); + } + function deletePath(obj, path) { + const pathArr = path.split("."); + let i; + for (i = 0; i < pathArr.length - 1; i++) { + if (!obj[pathArr[i]]) { + return; + } + obj = obj[pathArr[i]]; + } + delete obj[pathArr[i]]; + } + + let GW3Bridge$1 = class GW3Bridge { + _logger; + _connection; + _trackAllContexts; + _reAnnounceKnownContexts; + _gw3Session; + _contextNameToData = {}; + _gw3Subscriptions = []; + _nextCallbackSubscriptionNumber = 0; + _creationPromises = {}; + _contextNameToId = {}; + _contextIdToName = {}; + _protocolVersion = undefined; + _contextsTempCache = {}; + _contextsSubscriptionsCache = []; + _systemContextsSubKey; + get protocolVersion() { + if (!this._protocolVersion) { + const contextsDomainInfo = this._connection.availableDomains.find((d) => d.uri === "context"); + this._protocolVersion = contextsDomainInfo?.version ?? 1; + } + return this._protocolVersion; + } + get setPathSupported() { + return this.protocolVersion >= 2; + } + constructor(config) { + this._connection = config.connection; + this._logger = config.logger; + this._trackAllContexts = config.trackAllContexts; + this._reAnnounceKnownContexts = config.reAnnounceKnownContexts; + this._gw3Session = this._connection.domain("global", [ + GW_MESSAGE_CONTEXT_CREATED, + GW_MESSAGE_SUBSCRIBED_CONTEXT, + GW_MESSAGE_CONTEXT_DESTROYED, + GW_MESSAGE_CONTEXT_UPDATED, + ]); + this._gw3Session.disconnected(this.resetState.bind(this)); + this._gw3Session.onJoined((wasReconnect) => { + if (!wasReconnect) { + return; + } + if (!this._reAnnounceKnownContexts) { + return this._connection.setLibReAnnounced({ name: "contexts" }); + } + this.reInitiateState().then(() => this._connection.setLibReAnnounced({ name: "contexts" })); + }); + this.subscribeToContextCreatedMessages(); + this.subscribeToContextUpdatedMessages(); + this.subscribeToContextDestroyedMessages(); + this._connection.replayer?.drain(ContextMessageReplaySpec.name, (message) => { + const type = message.type; + if (!type) { + return; + } + if (type === GW_MESSAGE_CONTEXT_CREATED || + type === GW_MESSAGE_CONTEXT_ADDED || + type === GW_MESSAGE_ACTIVITY_CREATED) { + this.handleContextCreatedMessage(message); + } + else if (type === GW_MESSAGE_SUBSCRIBED_CONTEXT || + type === GW_MESSAGE_CONTEXT_UPDATED || + type === GW_MESSAGE_JOINED_ACTIVITY) { + this.handleContextUpdatedMessage(message); + } + else if (type === GW_MESSAGE_CONTEXT_DESTROYED || + type === GW_MESSAGE_ACTIVITY_DESTROYED) { + this.handleContextDestroyedMessage(message); + } + }); + } + dispose() { + for (const sub of this._gw3Subscriptions) { + this._connection.off(sub); + } + this._gw3Subscriptions.length = 0; + for (const contextName in this._contextNameToData) { + if (this._contextNameToId.hasOwnProperty(contextName)) { + delete this._contextNameToData[contextName]; + } + } + } + createContext(name, data) { + if (name in this._creationPromises) { + return this._creationPromises[name]; + } + this._creationPromises[name] = + this._gw3Session + .send({ + type: GW_MESSAGE_CREATE_CONTEXT, + domain: "global", + name, + data, + lifetime: "retained", + }) + .then((createContextMsg) => { + this._contextNameToId[name] = createContextMsg.context_id; + this._contextIdToName[createContextMsg.context_id] = name; + const contextData = this._contextNameToData[name] || new GW3ContextData(createContextMsg.context_id, name, true, undefined); + contextData.isAnnounced = true; + contextData.name = name; + contextData.contextId = createContextMsg.context_id; + contextData.context = createContextMsg.data || deepClone(data); + contextData.hasReceivedSnapshot = true; + this._contextNameToData[name] = contextData; + delete this._creationPromises[name]; + return createContextMsg.context_id; + }); + return this._creationPromises[name]; + } + all() { + return Object.keys(this._contextNameToData) + .filter((name) => this._contextNameToData[name].isAnnounced); + } + async update(name, delta) { + if (delta) { + delta = deepClone(delta); + } + if (name in this._creationPromises) { + await this._creationPromises[name]; + } + const contextData = this._contextNameToData[name]; + if (!contextData || !contextData.isAnnounced) { + return this.createContext(name, delta); + } + let currentContext = contextData.context; + if (!contextData.hasCallbacks()) { + currentContext = await this.get(contextData.name); + } + const calculatedDelta = this.setPathSupported ? + this.calculateContextDeltaV2(currentContext, delta) : + this.calculateContextDeltaV1(currentContext, delta); + if (!Object.keys(calculatedDelta.added).length + && !Object.keys(calculatedDelta.updated).length + && !calculatedDelta.removed.length + && !calculatedDelta.commands?.length) { + return Promise.resolve(); + } + return this._gw3Session + .send({ + type: GW_MESSAGE_UPDATE_CONTEXT, + domain: "global", + context_id: contextData.contextId, + delta: calculatedDelta, + }, {}, { skipPeerId: false }) + .then((gwResponse) => { + this.handleUpdated(contextData, calculatedDelta, { + updaterId: gwResponse.peer_id + }); + }); + } + async set(name, data) { + if (data) { + data = deepClone(data); + } + if (name in this._creationPromises) { + await this._creationPromises[name]; + } + const contextData = this._contextNameToData[name]; + if (!contextData || !contextData.isAnnounced) { + return this.createContext(name, data); + } + return this._gw3Session + .send({ + type: GW_MESSAGE_UPDATE_CONTEXT, + domain: "global", + context_id: contextData.contextId, + delta: { reset: data }, + }, {}, { skipPeerId: false }) + .then((gwResponse) => { + this.handleUpdated(contextData, { + reset: data, + added: {}, + removed: [], + updated: {} + }, { + updaterId: gwResponse.peer_id + }); + }); + } + setPath(name, path, value) { + if (!this.setPathSupported) { + return Promise.reject("glue.contexts.setPath operation is not supported, use Glue42 3.10 or later"); + } + return this.setPaths(name, [{ path, value }]); + } + async setPaths(name, pathValues) { + if (!this.setPathSupported) { + return Promise.reject("glue.contexts.setPaths operation is not supported, use Glue42 3.10 or later"); + } + if (pathValues) { + pathValues = deepClone(pathValues); + } + if (name in this._creationPromises) { + await this._creationPromises[name]; + } + const contextData = this._contextNameToData[name]; + if (!contextData || !contextData.isAnnounced) { + const obj = {}; + for (const pathValue of pathValues) { + setValueToPath(obj, pathValue.value, pathValue.path); + } + return this.createContext(name, obj); + } + const commands = []; + for (const pathValue of pathValues) { + if (pathValue.value === null) { + commands.push({ type: "remove", path: pathValue.path }); + } + else { + commands.push({ type: "set", path: pathValue.path, value: pathValue.value }); + } + } + return this._gw3Session + .send({ + type: GW_MESSAGE_UPDATE_CONTEXT, + domain: "global", + context_id: contextData.contextId, + delta: { commands } + }, {}, { skipPeerId: false }) + .then((gwResponse) => { + this.handleUpdated(contextData, { + added: {}, + removed: [], + updated: {}, + commands + }, { + updaterId: gwResponse.peer_id + }); + }); + } + async get(name) { + if (name in this._creationPromises) { + await this._creationPromises[name]; + } + const contextData = this._contextNameToData[name]; + if (!contextData || !contextData.isAnnounced) { + return Promise.resolve({}); + } + if (contextData && (!contextData.hasCallbacks() || !contextData.hasReceivedSnapshot)) { + return new Promise((resolve) => { + this.subscribe(name, (data, _d, _r, un) => { + this.unsubscribe(un); + resolve(data); + }); + }); + } + const context = contextData?.context ?? {}; + return Promise.resolve(deepClone(context)); + } + async subscribe(name, callback, subscriptionKey) { + if (name in this._creationPromises) { + await this._creationPromises[name]; + } + const thisCallbackSubscriptionNumber = typeof subscriptionKey === "undefined" ? this._nextCallbackSubscriptionNumber : subscriptionKey; + if (typeof subscriptionKey === "undefined") { + this._nextCallbackSubscriptionNumber += 1; + } + if (this._contextsSubscriptionsCache.every((subscription) => subscription.subKey !== this._nextCallbackSubscriptionNumber)) { + this._contextsSubscriptionsCache.push({ contextName: name, subKey: thisCallbackSubscriptionNumber, callback }); + } + let contextData = this._contextNameToData[name]; + if (!contextData || + !contextData.isAnnounced) { + contextData = contextData || new GW3ContextData(undefined, name, false, undefined); + this._contextNameToData[name] = contextData; + contextData.updateCallbacks[thisCallbackSubscriptionNumber] = callback; + return Promise.resolve(thisCallbackSubscriptionNumber); + } + const hadCallbacks = contextData.hasCallbacks(); + contextData.updateCallbacks[thisCallbackSubscriptionNumber] = callback; + if (!hadCallbacks) { + if (!contextData.joinedActivity) { + if (contextData.context && contextData.sentExplicitSubscription) { + if (contextData.hasReceivedSnapshot) { + const clone = deepClone(contextData.context); + callback(clone, clone, [], thisCallbackSubscriptionNumber); + } + return Promise.resolve(thisCallbackSubscriptionNumber); + } + return this.sendSubscribe(contextData) + .then(() => thisCallbackSubscriptionNumber); + } + else { + if (contextData.hasReceivedSnapshot) { + const clone = deepClone(contextData.context); + callback(clone, clone, [], thisCallbackSubscriptionNumber); + } + return Promise.resolve(thisCallbackSubscriptionNumber); + } + } + else { + if (contextData.hasReceivedSnapshot) { + const clone = deepClone(contextData.context); + callback(clone, clone, [], thisCallbackSubscriptionNumber); + } + return Promise.resolve(thisCallbackSubscriptionNumber); + } + } + unsubscribe(subscriptionKey) { + this._contextsSubscriptionsCache = this._contextsSubscriptionsCache.filter((subscription) => subscription.subKey !== subscriptionKey); + for (const name of Object.keys(this._contextNameToData)) { + const contextData = this._contextNameToData[name]; + if (!contextData) { + return; + } + const hadCallbacks = contextData.hasCallbacks(); + delete contextData.updateCallbacks[subscriptionKey]; + if (contextData.isAnnounced && + hadCallbacks && + !contextData.hasCallbacks() && + contextData.sentExplicitSubscription) { + this.sendUnsubscribe(contextData).catch(() => { }); + } + if (!contextData.isAnnounced && + !contextData.hasCallbacks()) { + delete this._contextNameToData[name]; + } + } + } + async destroy(name) { + if (name in this._creationPromises) { + await this._creationPromises[name]; + } + const contextData = this._contextNameToData[name]; + if (!contextData) { + return Promise.reject(`context with ${name} does not exist`); + } + return this._gw3Session + .send({ + type: GW_MESSAGE_DESTROY_CONTEXT, + domain: "global", + context_id: contextData.contextId, + }).then((_) => undefined); + } + handleUpdated(contextData, delta, extraData) { + const oldContext = contextData.context; + contextData.context = applyContextDelta(contextData.context, delta, this._logger); + contextData.hasReceivedSnapshot = true; + if (this._contextNameToData[contextData.name] === contextData && + !deepEqual(oldContext, contextData.context)) { + this.invokeUpdateCallbacks(contextData, delta, extraData); + } + } + subscribeToContextCreatedMessages() { + const createdMessageTypes = [ + GW_MESSAGE_CONTEXT_ADDED, + GW_MESSAGE_CONTEXT_CREATED, + GW_MESSAGE_ACTIVITY_CREATED, + ]; + for (const createdMessageType of createdMessageTypes) { + const sub = this._connection.on(createdMessageType, this.handleContextCreatedMessage.bind(this)); + this._gw3Subscriptions.push(sub); + } + } + handleContextCreatedMessage(contextCreatedMsg) { + const createdMessageType = contextCreatedMsg.type; + if (createdMessageType === GW_MESSAGE_ACTIVITY_CREATED) { + this._contextNameToId[contextCreatedMsg.activity_id] = contextCreatedMsg.context_id; + this._contextIdToName[contextCreatedMsg.context_id] = contextCreatedMsg.activity_id; + } + else if (createdMessageType === GW_MESSAGE_CONTEXT_ADDED) { + this._contextNameToId[contextCreatedMsg.name] = contextCreatedMsg.context_id; + this._contextIdToName[contextCreatedMsg.context_id] = contextCreatedMsg.name; + } + else ; + const name = this._contextIdToName[contextCreatedMsg.context_id]; + if (!name) { + throw new Error("Received created event for context with unknown name: " + contextCreatedMsg.context_id); + } + if (!this._contextNameToId[name]) { + throw new Error("Received created event for context with unknown id: " + contextCreatedMsg.context_id); + } + let contextData = this._contextNameToData[name]; + if (contextData) { + if (contextData.isAnnounced) { + return; + } + else { + if (!contextData.hasCallbacks()) { + throw new Error("Assertion failure: contextData.hasCallbacks()"); + } + contextData.isAnnounced = true; + contextData.contextId = contextCreatedMsg.context_id; + contextData.activityId = contextCreatedMsg.activity_id; + if (!contextData.sentExplicitSubscription) { + this.sendSubscribe(contextData); + } + } + } + else { + this._contextNameToData[name] = contextData = + new GW3ContextData(contextCreatedMsg.context_id, name, true, contextCreatedMsg.activity_id); + if (this._trackAllContexts) { + this.subscribe(name, () => { }).then((subKey) => this._systemContextsSubKey = subKey); + } + } + } + subscribeToContextUpdatedMessages() { + const updatedMessageTypes = [ + GW_MESSAGE_CONTEXT_UPDATED, + GW_MESSAGE_SUBSCRIBED_CONTEXT, + GW_MESSAGE_JOINED_ACTIVITY, + ]; + for (const updatedMessageType of updatedMessageTypes) { + const sub = this._connection.on(updatedMessageType, this.handleContextUpdatedMessage.bind(this)); + this._gw3Subscriptions.push(sub); + } + } + handleContextUpdatedMessage(contextUpdatedMsg) { + const updatedMessageType = contextUpdatedMsg.type; + const contextId = contextUpdatedMsg.context_id; + let contextData = this._contextNameToData[this._contextIdToName[contextId]]; + const justSeen = !contextData || !contextData.isAnnounced; + if (updatedMessageType === GW_MESSAGE_JOINED_ACTIVITY) { + if (!contextData) { + contextData = + this._contextNameToData[contextUpdatedMsg.activity_id] || + new GW3ContextData(contextId, contextUpdatedMsg.activity_id, true, contextUpdatedMsg.activity_id); + } + this._contextNameToData[contextUpdatedMsg.activity_id] = contextData; + this._contextIdToName[contextId] = contextUpdatedMsg.activity_id; + this._contextNameToId[contextUpdatedMsg.activity_id] = contextId; + contextData.contextId = contextId; + contextData.isAnnounced = true; + contextData.activityId = contextUpdatedMsg.activity_id; + contextData.joinedActivity = true; + } + else { + if (!contextData || !contextData.isAnnounced) { + if (updatedMessageType === GW_MESSAGE_SUBSCRIBED_CONTEXT) { + contextData = contextData || new GW3ContextData(contextId, contextUpdatedMsg.name, true, undefined); + contextData.sentExplicitSubscription = true; + this._contextNameToData[contextUpdatedMsg.name] = contextData; + this._contextIdToName[contextId] = contextUpdatedMsg.name; + this._contextNameToId[contextUpdatedMsg.name] = contextId; + } + else { + this._logger.error(`Received 'update' for unknown context: ${contextId}`); + } + return; + } + } + const oldContext = contextData.context; + contextData.hasReceivedSnapshot = true; + if (updatedMessageType === GW_MESSAGE_SUBSCRIBED_CONTEXT) { + contextData.context = contextUpdatedMsg.data || {}; + } + else if (updatedMessageType === GW_MESSAGE_JOINED_ACTIVITY) { + contextData.context = contextUpdatedMsg.context_snapshot || {}; + } + else if (updatedMessageType === GW_MESSAGE_CONTEXT_UPDATED) { + contextData.context = applyContextDelta(contextData.context, contextUpdatedMsg.delta, this._logger); + } + else { + throw new Error("Unrecognized context update message " + updatedMessageType); + } + if (justSeen || + !deepEqual(contextData.context, oldContext) || + updatedMessageType === GW_MESSAGE_SUBSCRIBED_CONTEXT) { + this.invokeUpdateCallbacks(contextData, contextUpdatedMsg.delta, { updaterId: contextUpdatedMsg.updater_id }); + } + } + invokeUpdateCallbacks(contextData, delta, extraData) { + delta = delta || { added: {}, updated: {}, reset: {}, removed: [] }; + if (delta.commands) { + delta.added = delta.updated = delta.reset = {}; + delta.removed = []; + for (const command of delta.commands) { + if (command.type === "remove") { + if (command.path.indexOf(".") === -1) { + delta.removed.push(command.path); + } + setValueToPath(delta.updated, null, command.path); + } + else if (command.type === "set") { + setValueToPath(delta.updated, command.value, command.path); + } + } + } + for (const updateCallbackIndex in contextData.updateCallbacks) { + if (contextData.updateCallbacks.hasOwnProperty(updateCallbackIndex)) { + try { + const updateCallback = contextData.updateCallbacks[updateCallbackIndex]; + updateCallback(deepClone(contextData.context), deepClone(Object.assign({}, delta.added || {}, delta.updated || {}, delta.reset || {})), delta.removed, parseInt(updateCallbackIndex, 10), extraData); + } + catch (err) { + this._logger.debug("callback error: " + JSON.stringify(err)); + } + } + } + } + subscribeToContextDestroyedMessages() { + const destroyedMessageTypes = [ + GW_MESSAGE_CONTEXT_DESTROYED, + GW_MESSAGE_ACTIVITY_DESTROYED, + ]; + for (const destroyedMessageType of destroyedMessageTypes) { + const sub = this._connection.on(destroyedMessageType, this.handleContextDestroyedMessage.bind(this)); + this._gw3Subscriptions.push(sub); + } + } + handleContextDestroyedMessage(destroyedMsg) { + const destroyedMessageType = destroyedMsg.type; + let contextId; + let name; + if (destroyedMessageType === GW_MESSAGE_ACTIVITY_DESTROYED) { + name = destroyedMsg.activity_id; + contextId = this._contextNameToId[name]; + if (!contextId) { + this._logger.error(`Received 'destroyed' for unknown activity: ${destroyedMsg.activity_id}`); + return; + } + } + else { + contextId = destroyedMsg.context_id; + name = this._contextIdToName[contextId]; + if (!name) { + this._logger.error(`Received 'destroyed' for unknown context: ${destroyedMsg.context_id}`); + return; + } + } + delete this._contextIdToName[contextId]; + delete this._contextNameToId[name]; + const contextData = this._contextNameToData[name]; + delete this._contextNameToData[name]; + if (!contextData || !contextData.isAnnounced) { + this._logger.error(`Received 'destroyed' for unknown context: ${contextId}`); + return; + } + } + sendSubscribe(contextData) { + contextData.sentExplicitSubscription = true; + return this._gw3Session + .send({ + type: GW_MESSAGE_SUBSCRIBE_CONTEXT, + domain: "global", + context_id: contextData.contextId, + }).then((_) => undefined); + } + sendUnsubscribe(contextData) { + contextData.sentExplicitSubscription = false; + return this._gw3Session + .send({ + type: GW_MESSAGE_UNSUBSCRIBE_CONTEXT, + domain: "global", + context_id: contextData.contextId, + }).then((_) => undefined); + } + calculateContextDeltaV1(from, to) { + const delta = { added: {}, updated: {}, removed: [], reset: undefined }; + if (from) { + for (const x of Object.keys(from)) { + if (Object.keys(to).indexOf(x) !== -1 + && to[x] !== null + && !deepEqual(from[x], to[x])) { + delta.updated[x] = to[x]; + } + } + } + for (const x of Object.keys(to)) { + if (!from || (Object.keys(from).indexOf(x) === -1)) { + if (to[x] !== null) { + delta.added[x] = to[x]; + } + } + else if (to[x] === null) { + delta.removed.push(x); + } + } + return delta; + } + calculateContextDeltaV2(from, to) { + const delta = { added: {}, updated: {}, removed: [], reset: undefined, commands: [] }; + for (const x of Object.keys(to)) { + if (to[x] !== null) { + const fromX = from ? from[x] : null; + if (!deepEqual(fromX, to[x])) { + delta.commands?.push({ type: "set", path: x, value: to[x] }); + } + } + else { + delta.commands?.push({ type: "remove", path: x }); + } + } + return delta; + } + resetState() { + for (const sub of this._gw3Subscriptions) { + this._connection.off(sub); + } + if (this._systemContextsSubKey) { + this.unsubscribe(this._systemContextsSubKey); + delete this._systemContextsSubKey; + } + this._gw3Subscriptions = []; + this._contextNameToId = {}; + this._contextIdToName = {}; + delete this._protocolVersion; + this._contextsTempCache = Object.keys(this._contextNameToData).reduce((cacheSoFar, ctxName) => { + const contextData = this._contextNameToData[ctxName]; + if (contextData.isAnnounced && (contextData.activityId || contextData.sentExplicitSubscription)) { + cacheSoFar[ctxName] = this._contextNameToData[ctxName].context; + } + return cacheSoFar; + }, {}); + this._contextNameToData = {}; + } + async reInitiateState() { + this.subscribeToContextCreatedMessages(); + this.subscribeToContextUpdatedMessages(); + this.subscribeToContextDestroyedMessages(); + this._connection.replayer?.drain(ContextMessageReplaySpec.name, (message) => { + const type = message.type; + if (!type) { + return; + } + if (type === GW_MESSAGE_CONTEXT_CREATED || + type === GW_MESSAGE_CONTEXT_ADDED || + type === GW_MESSAGE_ACTIVITY_CREATED) { + this.handleContextCreatedMessage(message); + } + else if (type === GW_MESSAGE_SUBSCRIBED_CONTEXT || + type === GW_MESSAGE_CONTEXT_UPDATED || + type === GW_MESSAGE_JOINED_ACTIVITY) { + this.handleContextUpdatedMessage(message); + } + else if (type === GW_MESSAGE_CONTEXT_DESTROYED || + type === GW_MESSAGE_ACTIVITY_DESTROYED) { + this.handleContextDestroyedMessage(message); + } + }); + await Promise.all(this._contextsSubscriptionsCache.map((subscription) => this.subscribe(subscription.contextName, subscription.callback, subscription.subKey))); + await this.flushQueue(); + for (const ctxName in this._contextsTempCache) { + if (typeof this._contextsTempCache[ctxName] !== "object" || Object.keys(this._contextsTempCache[ctxName]).length === 0) { + continue; + } + const lastKnownData = this._contextsTempCache[ctxName]; + this._logger.info(`Re-announcing known context: ${ctxName}`); + await this.flushQueue(); + await this.update(ctxName, lastKnownData); + } + this._contextsTempCache = {}; + this._logger.info("Contexts are re-announced"); + } + flushQueue() { + return new Promise((resolve) => setTimeout(() => resolve(), 0)); + } + }; + + class ContextsModule { + initTime; + initStartTime; + initEndTime; + _bridge; + constructor(config) { + this._bridge = new GW3Bridge$1(config); + } + all() { + return this._bridge.all(); + } + update(name, data) { + this.checkName(name); + this.checkData(data); + return this._bridge.update(name, data); + } + set(name, data) { + this.checkName(name); + this.checkData(data); + return this._bridge.set(name, data); + } + setPath(name, path, data) { + this.checkName(name); + this.checkPath(path); + const isTopLevelPath = path === ""; + if (isTopLevelPath) { + this.checkData(data); + return this.set(name, data); + } + return this._bridge.setPath(name, path, data); + } + setPaths(name, paths) { + this.checkName(name); + if (!Array.isArray(paths)) { + throw new Error("Please provide the paths as an array of PathValues!"); + } + for (const { path, value } of paths) { + this.checkPath(path); + const isTopLevelPath = path === ""; + if (isTopLevelPath) { + this.checkData(value); + } + } + return this._bridge.setPaths(name, paths); + } + subscribe(name, callback) { + this.checkName(name); + if (typeof callback !== "function") { + throw new Error("Please provide the callback as a function!"); + } + return this._bridge + .subscribe(name, (data, delta, removed, key, extraData) => callback(data, delta, removed, () => this._bridge.unsubscribe(key), extraData)) + .then((key) => () => { + this._bridge.unsubscribe(key); + }); + } + get(name) { + this.checkName(name); + return this._bridge.get(name); + } + ready() { + return Promise.resolve(this); + } + destroy(name) { + this.checkName(name); + return this._bridge.destroy(name); + } + get setPathSupported() { + return this._bridge.setPathSupported; + } + checkName(name) { + if (typeof name !== "string" || name === "") { + throw new Error("Please provide the name as a non-empty string!"); + } + } + checkPath(path) { + if (typeof path !== "string") { + throw new Error("Please provide the path as a dot delimited string!"); + } + } + checkData(data) { + if (typeof data !== "object") { + throw new Error("Please provide the data as an object!"); + } + } + } + + function promisify$2 (promise, successCallback, errorCallback) { + if (typeof successCallback !== "function" && typeof errorCallback !== "function") { + return promise; + } + if (typeof successCallback !== "function") { + successCallback = () => { }; + } + else if (typeof errorCallback !== "function") { + errorCallback = () => { }; + } + return promise.then(successCallback, errorCallback); + } + + function rejectAfter(ms = 0, promise, error) { + let timeout; + const clearTimeoutIfThere = () => { + if (timeout) { + clearTimeout(timeout); + } + }; + promise + .then(() => { + clearTimeoutIfThere(); + }) + .catch(() => { + clearTimeoutIfThere(); + }); + return new Promise((resolve, reject) => { + timeout = setTimeout(() => reject(error), ms); + }); + } + + var InvokeStatus; + (function (InvokeStatus) { + InvokeStatus[InvokeStatus["Success"] = 0] = "Success"; + InvokeStatus[InvokeStatus["Error"] = 1] = "Error"; + })(InvokeStatus || (InvokeStatus = {})); + class Client { + protocol; + repo; + instance; + configuration; + constructor(protocol, repo, instance, configuration) { + this.protocol = protocol; + this.repo = repo; + this.instance = instance; + this.configuration = configuration; + } + subscribe(method, options, successCallback, errorCallback, existingSub) { + const callProtocolSubscribe = (targetServers, stream, successProxy, errorProxy) => { + options.methodResponseTimeout = options.methodResponseTimeout ?? options.waitTimeoutMs; + this.protocol.client.subscribe(stream, options, targetServers, successProxy, errorProxy, existingSub); + }; + const promise = new Promise((resolve, reject) => { + const successProxy = (sub) => { + resolve(sub); + }; + const errorProxy = (err) => { + reject(err); + }; + if (!method) { + reject(`Method definition is required. Please, provide either a unique string for a method name or a “methodDefinition” object with a required “name” property.`); + return; + } + let methodDef; + if (typeof method === "string") { + methodDef = { name: method }; + } + else { + methodDef = method; + } + if (!methodDef.name) { + reject(`Method definition is required. Please, provide either a unique string for a method name or a “methodDefinition” object with a required “name” property.`); + return; + } + if (options === undefined) { + options = {}; + } + let target = options.target; + if (target === undefined) { + target = "best"; + } + if (typeof target === "string" && target !== "all" && target !== "best") { + reject(new Error(`"${target}" is not a valid target. Valid targets are "all", "best", or an instance.`)); + return; + } + if (options.methodResponseTimeout === undefined) { + options.methodResponseTimeout = options.method_response_timeout; + if (options.methodResponseTimeout === undefined) { + options.methodResponseTimeout = this.configuration.methodResponseTimeout; + } + } + if (options.waitTimeoutMs === undefined) { + options.waitTimeoutMs = options.wait_for_method_timeout; + if (options.waitTimeoutMs === undefined) { + options.waitTimeoutMs = this.configuration.waitTimeoutMs; + } + } + const delayStep = 500; + let delayTillNow = 0; + let currentServers = this.getServerMethodsByFilterAndTarget(methodDef, target); + if (currentServers.length > 0) { + callProtocolSubscribe(currentServers, currentServers[0].methods[0], successProxy, errorProxy); + } + else { + const retry = () => { + if (!target || !(options.waitTimeoutMs)) { + return; + } + delayTillNow += delayStep; + currentServers = this.getServerMethodsByFilterAndTarget(methodDef, target); + if (currentServers.length > 0) { + const streamInfo = currentServers[0].methods[0]; + callProtocolSubscribe(currentServers, streamInfo, successProxy, errorProxy); + } + else if (delayTillNow >= options.waitTimeoutMs) { + const def = typeof method === "string" ? { name: method } : method; + callProtocolSubscribe(currentServers, def, successProxy, errorProxy); + } + else { + setTimeout(retry, delayStep); + } + }; + setTimeout(retry, delayStep); + } + }); + return promisify$2(promise, successCallback, errorCallback); + } + servers(methodFilter) { + const filterCopy = methodFilter === undefined + ? undefined + : { ...methodFilter }; + return this.getServers(filterCopy).map((serverMethodMap) => { + return serverMethodMap.server.instance; + }); + } + methods(methodFilter) { + if (typeof methodFilter === "string") { + methodFilter = { name: methodFilter }; + } + else { + methodFilter = { ...methodFilter }; + } + return this.getMethods(methodFilter); + } + methodsForInstance(instance) { + return this.getMethodsForInstance(instance); + } + methodAdded(callback) { + return this.repo.onMethodAdded(callback); + } + methodRemoved(callback) { + return this.repo.onMethodRemoved(callback); + } + serverAdded(callback) { + return this.repo.onServerAdded(callback); + } + serverRemoved(callback) { + return this.repo.onServerRemoved((server, reason) => { + callback(server, reason); + }); + } + serverMethodAdded(callback) { + return this.repo.onServerMethodAdded((server, method) => { + callback({ server, method }); + }); + } + serverMethodRemoved(callback) { + return this.repo.onServerMethodRemoved((server, method) => { + callback({ server, method }); + }); + } + async invoke(methodFilter, argumentObj, target, additionalOptions, success, error) { + const getInvokePromise = async () => { + let methodDefinition; + if (typeof methodFilter === "string") { + methodDefinition = { name: methodFilter }; + } + else { + methodDefinition = { ...methodFilter }; + } + if (!methodDefinition.name) { + return Promise.reject(`Method definition is required. Please, provide either a unique string for a method name or a “methodDefinition” object with a required “name” property.`); + } + if (!argumentObj) { + argumentObj = {}; + } + if (!target) { + target = "best"; + } + if (typeof target === "string" && target !== "all" && target !== "best" && target !== "skipMine") { + return Promise.reject(new Error(`"${target}" is not a valid target. Valid targets are "all" and "best".`)); + } + if (!additionalOptions) { + additionalOptions = {}; + } + if (additionalOptions.methodResponseTimeoutMs === undefined) { + additionalOptions.methodResponseTimeoutMs = additionalOptions.method_response_timeout; + if (additionalOptions.methodResponseTimeoutMs === undefined) { + additionalOptions.methodResponseTimeoutMs = this.configuration.methodResponseTimeout; + } + } + if (additionalOptions.waitTimeoutMs === undefined) { + additionalOptions.waitTimeoutMs = additionalOptions.wait_for_method_timeout; + if (additionalOptions.waitTimeoutMs === undefined) { + additionalOptions.waitTimeoutMs = this.configuration.waitTimeoutMs; + } + } + if (additionalOptions.waitTimeoutMs !== undefined && typeof additionalOptions.waitTimeoutMs !== "number") { + return Promise.reject(new Error(`"${additionalOptions.waitTimeoutMs}" is not a valid number for "waitTimeoutMs" `)); + } + if (typeof argumentObj !== "object") { + return Promise.reject(new Error(`The method arguments must be an object. method: ${methodDefinition.name}`)); + } + let serversMethodMap = this.getServerMethodsByFilterAndTarget(methodDefinition, target); + if (serversMethodMap.length === 0) { + try { + serversMethodMap = await this.tryToAwaitForMethods(methodDefinition, target, additionalOptions); + } + catch (err) { + const method = { + ...methodDefinition, + getServers: () => [], + supportsStreaming: false, + objectTypes: methodDefinition.objectTypes ?? [], + flags: methodDefinition.flags?.metadata ?? {} + }; + const errorObj = { + method, + called_with: argumentObj, + message: `Can not find a method matching ${JSON.stringify(methodFilter)} with server filter ${JSON.stringify(target)}`, + executed_by: undefined, + returned: undefined, + status: undefined, + }; + return Promise.reject(errorObj); + } + } + const timeout = additionalOptions.methodResponseTimeoutMs; + const additionalOptionsCopy = additionalOptions; + const invokePromises = serversMethodMap.map((serversMethodPair) => { + const invId = nanoid$1(10); + const method = serversMethodPair.methods[0]; + const server = serversMethodPair.server; + const invokePromise = this.protocol.client.invoke(invId, method, argumentObj, server, additionalOptionsCopy); + return Promise.race([ + invokePromise, + rejectAfter(timeout, invokePromise, { + invocationId: invId, + message: `Invocation timeout (${timeout} ms) reached for method name: ${method?.name}, target instance: ${JSON.stringify(server.instance)}, options: ${JSON.stringify(additionalOptionsCopy)}`, + status: InvokeStatus.Error, + }) + ]); + }); + const invocationMessages = await Promise.all(invokePromises); + const results = this.getInvocationResultObj(invocationMessages, methodDefinition, argumentObj); + const allRejected = invocationMessages.every((result) => result.status === InvokeStatus.Error); + if (allRejected) { + return Promise.reject(results); + } + return results; + }; + return promisify$2(getInvokePromise(), success, error); + } + getInvocationResultObj(invocationResults, method, calledWith) { + const all_return_values = invocationResults + .filter((invokeMessage) => invokeMessage.status === InvokeStatus.Success) + .reduce((allValues, currentValue) => { + allValues = [ + ...allValues, + { + executed_by: currentValue.instance, + returned: currentValue.result, + called_with: calledWith, + method, + message: currentValue.message, + status: currentValue.status, + } + ]; + return allValues; + }, []); + const all_errors = invocationResults + .filter((invokeMessage) => invokeMessage.status === InvokeStatus.Error) + .reduce((allErrors, currError) => { + allErrors = [ + ...allErrors, + { + executed_by: currError.instance, + called_with: calledWith, + name: method.name, + message: currError.message, + } + ]; + return allErrors; + }, []); + const invResult = invocationResults[0]; + const result = { + method, + called_with: calledWith, + returned: invResult.result, + executed_by: invResult.instance, + all_return_values, + all_errors, + message: invResult.message, + status: invResult.status + }; + return result; + } + tryToAwaitForMethods(methodDefinition, target, additionalOptions) { + return new Promise((resolve, reject) => { + if (additionalOptions.waitTimeoutMs === 0) { + reject(); + return; + } + const delayStep = 500; + let delayTillNow = 0; + const retry = () => { + delayTillNow += delayStep; + const serversMethodMap = this.getServerMethodsByFilterAndTarget(methodDefinition, target); + if (serversMethodMap.length > 0) { + clearInterval(interval); + resolve(serversMethodMap); + } + else if (delayTillNow >= (additionalOptions.waitTimeoutMs || 10000)) { + clearInterval(interval); + reject(); + return; + } + }; + const interval = setInterval(retry, delayStep); + }); + } + filterByTarget(target, serverMethodMap) { + if (typeof target === "string") { + if (target === "all") { + return [...serverMethodMap]; + } + else if (target === "best") { + const localMachine = serverMethodMap + .find((s) => s.server.instance.isLocal); + if (localMachine) { + return [localMachine]; + } + if (serverMethodMap[0] !== undefined) { + return [serverMethodMap[0]]; + } + } + else if (target === "skipMine") { + return serverMethodMap.filter(({ server }) => server.instance.peerId !== this.instance.peerId); + } + } + else { + let targetArray; + if (!Array.isArray(target)) { + targetArray = [target]; + } + else { + targetArray = target; + } + const allServersMatching = targetArray.reduce((matches, filter) => { + const myMatches = serverMethodMap.filter((serverMethodPair) => { + return this.instanceMatch(filter, serverMethodPair.server.instance); + }); + return matches.concat(myMatches); + }, []); + return allServersMatching; + } + return []; + } + instanceMatch(instanceFilter, instanceDefinition) { + if (instanceFilter?.peerId && instanceFilter?.instance) { + instanceFilter = { ...instanceFilter }; + delete instanceFilter.peerId; + } + return this.containsProps(instanceFilter, instanceDefinition); + } + methodMatch(methodFilter, methodDefinition) { + return this.containsProps(methodFilter, methodDefinition); + } + containsProps(filter, repoMethod) { + const filterProps = Object.keys(filter) + .filter((prop) => { + return filter[prop] !== undefined + && filter[prop] !== null + && typeof filter[prop] !== "function" + && prop !== "object_types" + && prop !== "display_name" + && prop !== "id" + && prop !== "gatewayId" + && prop !== "identifier" + && prop[0] !== "_"; + }); + return filterProps.every((prop) => { + let isMatch; + const filterValue = filter[prop]; + const repoMethodValue = repoMethod[prop]; + switch (prop) { + case "objectTypes": + isMatch = (filterValue || []).every((filterValueEl) => { + return (repoMethodValue || []).includes(filterValueEl); + }); + break; + case "flags": + isMatch = isSubset(repoMethodValue || {}, filterValue || {}); + break; + default: + isMatch = String(filterValue).toLowerCase() === String(repoMethodValue).toLowerCase(); + } + return isMatch; + }); + } + getMethods(methodFilter) { + if (methodFilter === undefined) { + return this.repo.getMethods(); + } + const methods = this.repo.getMethods().filter((method) => { + return this.methodMatch(methodFilter, method); + }); + return methods; + } + getMethodsForInstance(instanceFilter) { + const allServers = this.repo.getServers(); + const matchingServers = allServers.filter((server) => { + return this.instanceMatch(instanceFilter, server.instance); + }); + if (matchingServers.length === 0) { + return []; + } + let resultMethodsObject = {}; + if (matchingServers.length === 1) { + resultMethodsObject = matchingServers[0].methods; + } + else { + matchingServers.forEach((server) => { + Object.keys(server.methods).forEach((methodKey) => { + const method = server.methods[methodKey]; + resultMethodsObject[method.identifier] = method; + }); + }); + } + return Object.keys(resultMethodsObject) + .map((key) => { + return resultMethodsObject[key]; + }); + } + getServers(methodFilter) { + const servers = this.repo.getServers(); + if (methodFilter === undefined) { + return servers.map((server) => { + return { server, methods: [] }; + }); + } + return servers.reduce((prev, current) => { + const methodsForServer = Object.values(current.methods); + const matchingMethods = methodsForServer.filter((method) => { + return this.methodMatch(methodFilter, method); + }); + if (matchingMethods.length > 0) { + prev.push({ server: current, methods: matchingMethods }); + } + return prev; + }, []); + } + getServerMethodsByFilterAndTarget(methodFilter, target) { + const serversMethodMap = this.getServers(methodFilter); + return this.filterByTarget(target, serversMethodMap); + } + } + + class ServerSubscription { + protocol; + repoMethod; + subscription; + constructor(protocol, repoMethod, subscription) { + this.protocol = protocol; + this.repoMethod = repoMethod; + this.subscription = subscription; + } + get stream() { + if (!this.repoMethod.stream) { + throw new Error("no stream"); + } + return this.repoMethod.stream; + } + get arguments() { return this.subscription.arguments || {}; } + get branchKey() { return this.subscription.branchKey; } + get instance() { + if (!this.subscription.instance) { + throw new Error("no instance"); + } + return this.subscription.instance; + } + close() { + this.protocol.server.closeSingleSubscription(this.repoMethod, this.subscription); + } + push(data) { + this.protocol.server.pushDataToSingle(this.repoMethod, this.subscription, data); + } + } + + class Request { + protocol; + repoMethod; + requestContext; + arguments; + instance; + constructor(protocol, repoMethod, requestContext) { + this.protocol = protocol; + this.repoMethod = repoMethod; + this.requestContext = requestContext; + this.arguments = requestContext.arguments; + this.instance = requestContext.instance; + } + accept() { + this.protocol.server.acceptRequestOnBranch(this.requestContext, this.repoMethod, ""); + } + acceptOnBranch(branch) { + this.protocol.server.acceptRequestOnBranch(this.requestContext, this.repoMethod, branch); + } + reject(reason) { + this.protocol.server.rejectRequest(this.requestContext, this.repoMethod, reason); + } + } + + let ServerStreaming$1 = class ServerStreaming { + protocol; + server; + constructor(protocol, server) { + this.protocol = protocol; + this.server = server; + protocol.server.onSubRequest((rc, rm) => this.handleSubRequest(rc, rm)); + protocol.server.onSubAdded((sub, rm) => this.handleSubAdded(sub, rm)); + protocol.server.onSubRemoved((sub, rm) => this.handleSubRemoved(sub, rm)); + } + handleSubRequest(requestContext, repoMethod) { + if (!(repoMethod && + repoMethod.streamCallbacks && + typeof repoMethod.streamCallbacks.subscriptionRequestHandler === "function")) { + return; + } + const request = new Request(this.protocol, repoMethod, requestContext); + repoMethod.streamCallbacks.subscriptionRequestHandler(request); + } + handleSubAdded(subscription, repoMethod) { + if (!(repoMethod && + repoMethod.streamCallbacks && + typeof repoMethod.streamCallbacks.subscriptionAddedHandler === "function")) { + return; + } + const sub = new ServerSubscription(this.protocol, repoMethod, subscription); + repoMethod.streamCallbacks.subscriptionAddedHandler(sub); + } + handleSubRemoved(subscription, repoMethod) { + if (!(repoMethod && + repoMethod.streamCallbacks && + typeof repoMethod.streamCallbacks.subscriptionRemovedHandler === "function")) { + return; + } + const sub = new ServerSubscription(this.protocol, repoMethod, subscription); + repoMethod.streamCallbacks.subscriptionRemovedHandler(sub); + } + }; + + class ServerBranch { + key; + protocol; + repoMethod; + constructor(key, protocol, repoMethod) { + this.key = key; + this.protocol = protocol; + this.repoMethod = repoMethod; + } + subscriptions() { + const subList = this.protocol.server.getSubscriptionList(this.repoMethod, this.key); + return subList.map((sub) => { + return new ServerSubscription(this.protocol, this.repoMethod, sub); + }); + } + close() { + this.protocol.server.closeAllSubscriptions(this.repoMethod, this.key); + } + push(data) { + this.protocol.server.pushData(this.repoMethod, data, [this.key]); + } + } + + class ServerStream { + _protocol; + _repoMethod; + _server; + name; + constructor(_protocol, _repoMethod, _server) { + this._protocol = _protocol; + this._repoMethod = _repoMethod; + this._server = _server; + this.name = this._repoMethod.definition.name; + } + branches(key) { + const bList = this._protocol.server.getBranchList(this._repoMethod); + if (key) { + if (bList.indexOf(key) > -1) { + return new ServerBranch(key, this._protocol, this._repoMethod); + } + return undefined; + } + else { + return bList.map((branchKey) => { + return new ServerBranch(branchKey, this._protocol, this._repoMethod); + }); + } + } + branch(key) { + return this.branches(key); + } + subscriptions() { + const subList = this._protocol.server.getSubscriptionList(this._repoMethod); + return subList.map((sub) => { + return new ServerSubscription(this._protocol, this._repoMethod, sub); + }); + } + get definition() { + const def2 = this._repoMethod.definition; + return { + accepts: def2.accepts, + description: def2.description, + displayName: def2.displayName, + name: def2.name, + objectTypes: def2.objectTypes, + returns: def2.returns, + supportsStreaming: def2.supportsStreaming, + flags: def2.flags?.metadata, + }; + } + close() { + this._protocol.server.closeAllSubscriptions(this._repoMethod); + this._server.unregister(this._repoMethod.definition, true); + } + push(data, branches) { + if (typeof branches !== "string" && !Array.isArray(branches) && branches !== undefined) { + throw new Error("invalid branches should be string or string array"); + } + if (typeof data !== "object") { + throw new Error("Invalid arguments. Data must be an object."); + } + this._protocol.server.pushData(this._repoMethod, data, branches); + } + updateRepoMethod(repoMethod) { + this._repoMethod = repoMethod; + } + } + + class Server { + protocol; + serverRepository; + streaming; + invocations = 0; + currentlyUnregistering = {}; + constructor(protocol, serverRepository) { + this.protocol = protocol; + this.serverRepository = serverRepository; + this.streaming = new ServerStreaming$1(protocol, this); + this.protocol.server.onInvoked(this.onMethodInvoked.bind(this)); + } + createStream(streamDef, callbacks, successCallback, errorCallback, existingStream) { + const promise = new Promise((resolve, reject) => { + if (!streamDef) { + reject("The stream name must be unique! Please, provide either a unique string for a stream name to “glue.interop.createStream()” or a “methodDefinition” object with a unique “name” property for the stream."); + return; + } + let streamMethodDefinition; + if (typeof streamDef === "string") { + streamMethodDefinition = { name: "" + streamDef }; + } + else { + streamMethodDefinition = { ...streamDef }; + } + if (!streamMethodDefinition.name) { + return reject(`The “name” property is required for the “streamDefinition” object and must be unique. Stream definition: ${JSON.stringify(streamMethodDefinition)}`); + } + const nameAlreadyExists = this.serverRepository.getList() + .some((serverMethod) => serverMethod.definition.name === streamMethodDefinition.name); + if (nameAlreadyExists) { + return reject(`A stream with the name "${streamMethodDefinition.name}" already exists! Please, provide a unique name for the stream.`); + } + streamMethodDefinition.supportsStreaming = true; + if (!callbacks) { + callbacks = {}; + } + if (typeof callbacks.subscriptionRequestHandler !== "function") { + callbacks.subscriptionRequestHandler = (request) => { + request.accept(); + }; + } + const repoMethod = this.serverRepository.add({ + definition: streamMethodDefinition, + streamCallbacks: callbacks, + protocolState: {}, + }); + this.protocol.server.createStream(repoMethod) + .then(() => { + let streamUserObject; + if (existingStream) { + streamUserObject = existingStream; + existingStream.updateRepoMethod(repoMethod); + } + else { + streamUserObject = new ServerStream(this.protocol, repoMethod, this); + } + repoMethod.stream = streamUserObject; + resolve(streamUserObject); + }) + .catch((err) => { + if (repoMethod.repoId) { + this.serverRepository.remove(repoMethod.repoId); + } + reject(err); + }); + }); + return promisify$2(promise, successCallback, errorCallback); + } + register(methodDefinition, callback) { + if (!methodDefinition) { + return Promise.reject("Method definition is required. Please, provide either a unique string for a method name or a “methodDefinition” object with a required “name” property."); + } + if (typeof callback !== "function") { + return Promise.reject(`The second parameter must be a callback function. Method: ${typeof methodDefinition === "string" ? methodDefinition : methodDefinition.name}`); + } + const wrappedCallbackFunction = async (context, resultCallback) => { + try { + const result = callback(context.args, context.instance); + if (result && typeof result.then === "function") { + const resultValue = await result; + resultCallback(undefined, resultValue); + } + else { + resultCallback(undefined, result); + } + } + catch (e) { + resultCallback(e ?? "", e ?? ""); + } + }; + wrappedCallbackFunction.userCallback = callback; + return this.registerCore(methodDefinition, wrappedCallbackFunction); + } + registerAsync(methodDefinition, callback) { + if (!methodDefinition) { + return Promise.reject("Method definition is required. Please, provide either a unique string for a method name or a “methodDefinition” object with a required “name” property."); + } + if (typeof callback !== "function") { + return Promise.reject(`The second parameter must be a callback function. Method: ${typeof methodDefinition === "string" ? methodDefinition : methodDefinition.name}`); + } + const wrappedCallback = async (context, resultCallback) => { + try { + let resultCalled = false; + const success = (result) => { + if (!resultCalled) { + resultCallback(undefined, result); + } + resultCalled = true; + }; + const error = (e) => { + if (!resultCalled) { + if (!e) { + e = ""; + } + resultCallback(e, e); + } + resultCalled = true; + }; + const methodResult = callback(context.args, context.instance, success, error); + if (methodResult && typeof methodResult.then === "function") { + methodResult + .then(success) + .catch(error); + } + } + catch (e) { + resultCallback(e, undefined); + } + }; + wrappedCallback.userCallbackAsync = callback; + return this.registerCore(methodDefinition, wrappedCallback); + } + async unregister(methodFilter, forStream = false) { + if (methodFilter === undefined) { + return Promise.reject("Please, provide either a unique string for a name or an object containing a “name” property."); + } + if (typeof methodFilter === "function") { + await this.unregisterWithPredicate(methodFilter, forStream); + return; + } + let methodDefinition; + if (typeof methodFilter === "string") { + methodDefinition = { name: methodFilter }; + } + else { + methodDefinition = methodFilter; + } + if (methodDefinition.name === undefined) { + return Promise.reject("Method name is required. Cannot find a method if the method name is undefined!"); + } + const methodToBeRemoved = this.serverRepository.getList().find((serverMethod) => { + return serverMethod.definition.name === methodDefinition.name + && (serverMethod.definition.supportsStreaming || false) === forStream; + }); + if (!methodToBeRemoved) { + return Promise.reject(`Method with a name "${methodDefinition.name}" does not exist or is not registered by your application!`); + } + await this.removeMethodsOrStreams([methodToBeRemoved]); + } + async unregisterWithPredicate(filterPredicate, forStream) { + const methodsOrStreamsToRemove = this.serverRepository.getList() + .filter((sm) => filterPredicate(sm.definition)) + .filter((serverMethod) => (serverMethod.definition.supportsStreaming || false) === forStream); + if (!methodsOrStreamsToRemove || methodsOrStreamsToRemove.length === 0) { + return Promise.reject(`Could not find a ${forStream ? "stream" : "method"} matching the specified condition!`); + } + await this.removeMethodsOrStreams(methodsOrStreamsToRemove); + } + removeMethodsOrStreams(methodsToRemove) { + const methodUnregPromises = []; + methodsToRemove.forEach((method) => { + const promise = this.protocol.server.unregister(method) + .then(() => { + if (method.repoId) { + this.serverRepository.remove(method.repoId); + } + }); + methodUnregPromises.push(promise); + this.addAsCurrentlyUnregistering(method.definition.name, promise); + }); + return Promise.all(methodUnregPromises); + } + async addAsCurrentlyUnregistering(methodName, promise) { + const timeout = new Promise((resolve) => setTimeout(resolve, 5000)); + this.currentlyUnregistering[methodName] = Promise.race([promise, timeout]).then(() => { + delete this.currentlyUnregistering[methodName]; + }); + } + async registerCore(method, theFunction) { + let methodDefinition; + if (typeof method === "string") { + methodDefinition = { name: "" + method }; + } + else { + methodDefinition = { ...method }; + } + if (!methodDefinition.name) { + return Promise.reject(`Please, provide a (unique) string value for the “name” property in the “methodDefinition” object: ${JSON.stringify(method)}`); + } + const unregisterInProgress = this.currentlyUnregistering[methodDefinition.name]; + if (typeof unregisterInProgress !== "undefined") { + await unregisterInProgress; + } + const nameAlreadyExists = this.serverRepository.getList() + .some((serverMethod) => serverMethod.definition.name === methodDefinition.name); + if (nameAlreadyExists) { + return Promise.reject(`A method with the name "${methodDefinition.name}" already exists! Please, provide a unique name for the method.`); + } + if (methodDefinition.supportsStreaming) { + return Promise.reject(`When you create methods with “glue.interop.register()” or “glue.interop.registerAsync()” the property “supportsStreaming” cannot be “true”. If you want “${methodDefinition.name}” to be a stream, please use the “glue.interop.createStream()” method.`); + } + const repoMethod = this.serverRepository.add({ + definition: methodDefinition, + theFunction, + protocolState: {}, + }); + return this.protocol.server.register(repoMethod) + .catch((err) => { + if (repoMethod?.repoId) { + this.serverRepository.remove(repoMethod.repoId); + } + throw err; + }); + } + onMethodInvoked(methodToExecute, invocationId, invocationArgs) { + if (!methodToExecute || !methodToExecute.theFunction) { + return; + } + methodToExecute.theFunction(invocationArgs, (err, result) => { + if (err !== undefined && err !== null) { + if (err.message && typeof err.message === "string") { + err = err.message; + } + else if (typeof err !== "string") { + try { + err = JSON.stringify(err); + } + catch (unStrException) { + err = `un-stringifyable error in onMethodInvoked! Top level prop names: ${Object.keys(err)}`; + } + } + } + if (!result) { + result = {}; + } + else if (typeof result !== "object" || Array.isArray(result)) { + result = { _value: result }; + } + this.protocol.server.methodInvocationResult(methodToExecute, invocationId, err, result); + }); + } + } + + class InstanceWrapper { + wrapped = {}; + constructor(API, instance, connection) { + this.wrapped.getMethods = function () { + return API.methodsForInstance(this); + }; + this.wrapped.getStreams = function () { + return API.methodsForInstance(this).filter((m) => m.supportsStreaming); + }; + if (instance) { + this.refreshWrappedObject(instance); + } + if (connection) { + connection.loggedIn(() => { + this.refresh(connection); + }); + this.refresh(connection); + } + } + unwrap() { + return this.wrapped; + } + refresh(connection) { + if (!connection) { + return; + } + const resolvedIdentity = connection?.resolvedIdentity; + const instance = Object.assign({}, resolvedIdentity ?? {}, { peerId: connection?.peerId }); + this.refreshWrappedObject(instance); + } + refreshWrappedObject(resolvedIdentity) { + Object.keys(resolvedIdentity).forEach((key) => { + this.wrapped[key] = resolvedIdentity[key]; + }); + this.wrapped.user = resolvedIdentity.user; + this.wrapped.instance = resolvedIdentity.instance; + this.wrapped.application = resolvedIdentity.application ?? nanoid$1(10); + this.wrapped.applicationName = resolvedIdentity.applicationName; + this.wrapped.pid = resolvedIdentity.pid ?? resolvedIdentity.process ?? Math.floor(Math.random() * 10000000000); + this.wrapped.machine = resolvedIdentity.machine; + this.wrapped.environment = resolvedIdentity.environment; + this.wrapped.region = resolvedIdentity.region; + this.wrapped.windowId = resolvedIdentity.windowId; + this.wrapped.isLocal = resolvedIdentity.isLocal ?? true; + this.wrapped.api = resolvedIdentity.api; + this.wrapped.service = resolvedIdentity.service; + this.wrapped.peerId = resolvedIdentity.peerId; + } + } + + const hideMethodSystemFlags = (method) => { + return { + ...method, + flags: method.flags.metadata || {} + }; + }; + class ClientRepository { + logger; + API; + servers = {}; + myServer; + methodsCount = {}; + callbacks = CallbackRegistryFactory$1(); + constructor(logger, API) { + this.logger = logger; + this.API = API; + const peerId = this.API.instance.peerId; + this.myServer = { + id: peerId, + methods: {}, + instance: this.API.instance, + wrapper: this.API.unwrappedInstance, + }; + this.servers[peerId] = this.myServer; + } + addServer(info, serverId) { + this.logger.debug(`adding server ${serverId}`); + const current = this.servers[serverId]; + if (current) { + return current.id; + } + const wrapper = new InstanceWrapper(this.API, info); + const serverEntry = { + id: serverId, + methods: {}, + instance: wrapper.unwrap(), + wrapper, + }; + this.servers[serverId] = serverEntry; + this.callbacks.execute("onServerAdded", serverEntry.instance); + return serverId; + } + removeServerById(id, reason) { + const server = this.servers[id]; + if (!server) { + this.logger.warn(`not aware of server ${id}, my state ${JSON.stringify(Object.keys(this.servers))}`); + return; + } + else { + this.logger.debug(`removing server ${id}`); + } + Object.keys(server.methods).forEach((methodId) => { + this.removeServerMethod(id, methodId); + }); + delete this.servers[id]; + this.callbacks.execute("onServerRemoved", server.instance, reason); + } + addServerMethod(serverId, method) { + const server = this.servers[serverId]; + if (!server) { + throw new Error("server does not exists"); + } + if (server.methods[method.id]) { + return; + } + const identifier = this.createMethodIdentifier(method); + const that = this; + const methodDefinition = { + identifier, + gatewayId: method.id, + name: method.name, + displayName: method.display_name, + description: method.description, + version: method.version, + objectTypes: method.object_types || [], + accepts: method.input_signature, + returns: method.result_signature, + supportsStreaming: typeof method.flags !== "undefined" ? method.flags.streaming : false, + flags: method.flags ?? {}, + getServers: () => { + return that.getServersByMethod(identifier); + } + }; + methodDefinition.object_types = methodDefinition.objectTypes; + methodDefinition.display_name = methodDefinition.displayName; + methodDefinition.version = methodDefinition.version; + server.methods[method.id] = methodDefinition; + const clientMethodDefinition = hideMethodSystemFlags(methodDefinition); + if (!this.methodsCount[identifier]) { + this.methodsCount[identifier] = 0; + this.callbacks.execute("onMethodAdded", clientMethodDefinition); + } + this.methodsCount[identifier] = this.methodsCount[identifier] + 1; + this.callbacks.execute("onServerMethodAdded", server.instance, clientMethodDefinition); + return methodDefinition; + } + removeServerMethod(serverId, methodId) { + const server = this.servers[serverId]; + if (!server) { + throw new Error("server does not exists"); + } + const method = server.methods[methodId]; + delete server.methods[methodId]; + const clientMethodDefinition = hideMethodSystemFlags(method); + this.methodsCount[method.identifier] = this.methodsCount[method.identifier] - 1; + if (this.methodsCount[method.identifier] === 0) { + this.callbacks.execute("onMethodRemoved", clientMethodDefinition); + } + this.callbacks.execute("onServerMethodRemoved", server.instance, clientMethodDefinition); + } + getMethods() { + return this.extractMethodsFromServers(Object.values(this.servers)).map(hideMethodSystemFlags); + } + getServers() { + return Object.values(this.servers).map(this.hideServerMethodSystemFlags); + } + onServerAdded(callback) { + const unsubscribeFunc = this.callbacks.add("onServerAdded", callback); + const serversWithMethodsToReplay = this.getServers().map((s) => s.instance); + return this.returnUnsubWithDelayedReplay(unsubscribeFunc, serversWithMethodsToReplay, callback); + } + onMethodAdded(callback) { + const unsubscribeFunc = this.callbacks.add("onMethodAdded", callback); + const methodsToReplay = this.getMethods(); + return this.returnUnsubWithDelayedReplay(unsubscribeFunc, methodsToReplay, callback); + } + onServerMethodAdded(callback) { + const unsubscribeFunc = this.callbacks.add("onServerMethodAdded", callback); + let unsubCalled = false; + const servers = this.getServers(); + setTimeout(() => { + servers.forEach((server) => { + const methods = server.methods; + Object.keys(methods).forEach((methodId) => { + if (!unsubCalled) { + callback(server.instance, methods[methodId]); + } + }); + }); + }, 0); + return () => { + unsubCalled = true; + unsubscribeFunc(); + }; + } + onMethodRemoved(callback) { + const unsubscribeFunc = this.callbacks.add("onMethodRemoved", callback); + return unsubscribeFunc; + } + onServerRemoved(callback) { + const unsubscribeFunc = this.callbacks.add("onServerRemoved", callback); + return unsubscribeFunc; + } + onServerMethodRemoved(callback) { + const unsubscribeFunc = this.callbacks.add("onServerMethodRemoved", callback); + return unsubscribeFunc; + } + getServerById(id) { + const server = this.servers[id]; + if (!server) { + return undefined; + } + return this.hideServerMethodSystemFlags(this.servers[id]); + } + reset() { + Object.keys(this.servers).forEach((key) => { + this.removeServerById(key, "reset"); + }); + this.servers = { + [this.myServer.id]: this.myServer + }; + this.methodsCount = {}; + } + createMethodIdentifier(methodInfo) { + const accepts = methodInfo.input_signature ?? ""; + const returns = methodInfo.result_signature ?? ""; + return (methodInfo.name + accepts + returns).toLowerCase(); + } + getServersByMethod(identifier) { + const allServers = []; + Object.values(this.servers).forEach((server) => { + Object.values(server.methods).forEach((method) => { + if (method.identifier === identifier) { + allServers.push(server.instance); + } + }); + }); + return allServers; + } + returnUnsubWithDelayedReplay(unsubscribeFunc, collectionToReplay, callback) { + let unsubCalled = false; + setTimeout(() => { + collectionToReplay.forEach((item) => { + if (!unsubCalled) { + callback(item); + } + }); + }, 0); + return () => { + unsubCalled = true; + unsubscribeFunc(); + }; + } + hideServerMethodSystemFlags(server) { + const clientMethods = {}; + Object.entries(server.methods).forEach(([name, method]) => { + clientMethods[name] = hideMethodSystemFlags(method); + }); + return { + ...server, + methods: clientMethods + }; + } + extractMethodsFromServers(servers) { + const methods = Object.values(servers).reduce((clientMethods, server) => { + return [...clientMethods, ...Object.values(server.methods)]; + }, []); + return methods; + } + } + + class ServerRepository { + nextId = 0; + methods = []; + add(method) { + method.repoId = String(this.nextId); + this.nextId += 1; + this.methods.push(method); + return method; + } + remove(repoId) { + if (typeof repoId !== "string") { + return new TypeError("Expecting a string"); + } + this.methods = this.methods.filter((m) => { + return m.repoId !== repoId; + }); + } + getById(id) { + if (typeof id !== "string") { + return undefined; + } + return this.methods.find((m) => { + return m.repoId === id; + }); + } + getList() { + return this.methods.map((m) => m); + } + length() { + return this.methods.length; + } + reset() { + this.methods = []; + } + } + + const SUBSCRIPTION_REQUEST = "onSubscriptionRequest"; + const SUBSCRIPTION_ADDED = "onSubscriptionAdded"; + const SUBSCRIPTION_REMOVED = "onSubscriptionRemoved"; + class ServerStreaming { + session; + repository; + serverRepository; + ERR_URI_SUBSCRIPTION_FAILED = "com.tick42.agm.errors.subscription.failure"; + callbacks = CallbackRegistryFactory$1(); + nextStreamId = 0; + constructor(session, repository, serverRepository) { + this.session = session; + this.repository = repository; + this.serverRepository = serverRepository; + session.on("add-interest", (msg) => { + this.handleAddInterest(msg); + }); + session.on("remove-interest", (msg) => { + this.handleRemoveInterest(msg); + }); + } + acceptRequestOnBranch(requestContext, streamingMethod, branch) { + if (typeof branch !== "string") { + branch = ""; + } + if (typeof streamingMethod.protocolState.subscriptionsMap !== "object") { + throw new TypeError("The streaming method is missing its subscriptions."); + } + if (!Array.isArray(streamingMethod.protocolState.branchKeyToStreamIdMap)) { + throw new TypeError("The streaming method is missing its branches."); + } + const streamId = this.getStreamId(streamingMethod, branch); + const key = requestContext.msg.subscription_id; + const subscription = { + id: key, + arguments: requestContext.arguments, + instance: requestContext.instance, + branchKey: branch, + streamId, + subscribeMsg: requestContext.msg, + }; + streamingMethod.protocolState.subscriptionsMap[key] = subscription; + this.session.sendFireAndForget({ + type: "accepted", + subscription_id: key, + stream_id: streamId, + }); + this.callbacks.execute(SUBSCRIPTION_ADDED, subscription, streamingMethod); + } + rejectRequest(requestContext, streamingMethod, reason) { + if (typeof reason !== "string") { + reason = ""; + } + this.sendSubscriptionFailed("Subscription rejected by user. " + reason, requestContext.msg.subscription_id); + } + pushData(streamingMethod, data, branches) { + if (typeof streamingMethod !== "object" || !Array.isArray(streamingMethod.protocolState.branchKeyToStreamIdMap)) { + return; + } + if (typeof data !== "object") { + throw new Error("Invalid arguments. Data must be an object."); + } + if (typeof branches === "string") { + branches = [branches]; + } + else if (!Array.isArray(branches) || branches.length <= 0) { + branches = []; + } + const streamIdList = streamingMethod.protocolState.branchKeyToStreamIdMap + .filter((br) => { + if (!branches || branches.length === 0) { + return true; + } + return branches.indexOf(br.key) >= 0; + }).map((br) => { + return br.streamId; + }); + streamIdList.forEach((streamId) => { + const publishMessage = { + type: "publish", + stream_id: streamId, + data, + }; + this.session.sendFireAndForget(publishMessage); + }); + } + pushDataToSingle(method, subscription, data) { + if (typeof data !== "object") { + throw new Error("Invalid arguments. Data must be an object."); + } + const postMessage = { + type: "post", + subscription_id: subscription.id, + data, + }; + this.session.sendFireAndForget(postMessage); + } + closeSingleSubscription(streamingMethod, subscription) { + if (streamingMethod.protocolState.subscriptionsMap) { + delete streamingMethod.protocolState.subscriptionsMap[subscription.id]; + } + const dropSubscriptionMessage = { + type: "drop-subscription", + subscription_id: subscription.id, + reason: "Server dropping a single subscription", + }; + this.session.sendFireAndForget(dropSubscriptionMessage); + subscription.instance; + this.callbacks.execute(SUBSCRIPTION_REMOVED, subscription, streamingMethod); + } + closeMultipleSubscriptions(streamingMethod, branchKey) { + if (typeof streamingMethod !== "object" || typeof streamingMethod.protocolState.subscriptionsMap !== "object") { + return; + } + if (!streamingMethod.protocolState.subscriptionsMap) { + return; + } + const subscriptionsMap = streamingMethod.protocolState.subscriptionsMap; + let subscriptionsToClose = Object.keys(subscriptionsMap) + .map((key) => { + return subscriptionsMap[key]; + }); + if (typeof branchKey === "string") { + subscriptionsToClose = subscriptionsToClose.filter((sub) => { + return sub.branchKey === branchKey; + }); + } + subscriptionsToClose.forEach((subscription) => { + delete subscriptionsMap[subscription.id]; + const drop = { + type: "drop-subscription", + subscription_id: subscription.id, + reason: "Server dropping all subscriptions on stream_id: " + subscription.streamId, + }; + this.session.sendFireAndForget(drop); + }); + } + getSubscriptionList(streamingMethod, branchKey) { + if (typeof streamingMethod !== "object") { + return []; + } + let subscriptions = []; + if (!streamingMethod.protocolState.subscriptionsMap) { + return []; + } + const subscriptionsMap = streamingMethod.protocolState.subscriptionsMap; + const allSubscriptions = Object.keys(subscriptionsMap) + .map((key) => { + return subscriptionsMap[key]; + }); + if (typeof branchKey !== "string") { + subscriptions = allSubscriptions; + } + else { + subscriptions = allSubscriptions.filter((sub) => { + return sub.branchKey === branchKey; + }); + } + return subscriptions; + } + getBranchList(streamingMethod) { + if (typeof streamingMethod !== "object") { + return []; + } + if (!streamingMethod.protocolState.subscriptionsMap) { + return []; + } + const subscriptionsMap = streamingMethod.protocolState.subscriptionsMap; + const allSubscriptions = Object.keys(subscriptionsMap) + .map((key) => { + return subscriptionsMap[key]; + }); + const result = []; + allSubscriptions.forEach((sub) => { + let branch = ""; + if (typeof sub === "object" && typeof sub.branchKey === "string") { + branch = sub.branchKey; + } + if (result.indexOf(branch) === -1) { + result.push(branch); + } + }); + return result; + } + onSubAdded(callback) { + this.onSubscriptionLifetimeEvent(SUBSCRIPTION_ADDED, callback); + } + onSubRequest(callback) { + this.onSubscriptionLifetimeEvent(SUBSCRIPTION_REQUEST, callback); + } + onSubRemoved(callback) { + this.onSubscriptionLifetimeEvent(SUBSCRIPTION_REMOVED, callback); + } + handleRemoveInterest(msg) { + const streamingMethod = this.serverRepository.getById(msg.method_id); + if (typeof msg.subscription_id !== "string" || + typeof streamingMethod !== "object") { + return; + } + if (!streamingMethod.protocolState.subscriptionsMap) { + return; + } + if (typeof streamingMethod.protocolState.subscriptionsMap[msg.subscription_id] !== "object") { + return; + } + const subscription = streamingMethod.protocolState.subscriptionsMap[msg.subscription_id]; + delete streamingMethod.protocolState.subscriptionsMap[msg.subscription_id]; + this.callbacks.execute(SUBSCRIPTION_REMOVED, subscription, streamingMethod); + } + onSubscriptionLifetimeEvent(eventName, handlerFunc) { + this.callbacks.add(eventName, handlerFunc); + } + getNextStreamId() { + return this.nextStreamId++ + ""; + } + handleAddInterest(msg) { + const caller = this.repository.getServerById(msg.caller_id); + const instance = caller?.instance ?? {}; + const requestContext = { + msg, + arguments: msg.arguments_kv || {}, + instance, + }; + const streamingMethod = this.serverRepository.getById(msg.method_id); + if (streamingMethod === undefined) { + const errorMsg = "No method with id " + msg.method_id + " on this server."; + this.sendSubscriptionFailed(errorMsg, msg.subscription_id); + return; + } + if (streamingMethod.protocolState.subscriptionsMap && + streamingMethod.protocolState.subscriptionsMap[msg.subscription_id]) { + this.sendSubscriptionFailed("A subscription with id " + msg.subscription_id + " already exists.", msg.subscription_id); + return; + } + this.callbacks.execute(SUBSCRIPTION_REQUEST, requestContext, streamingMethod); + } + sendSubscriptionFailed(reason, subscriptionId) { + const errorMessage = { + type: "error", + reason_uri: this.ERR_URI_SUBSCRIPTION_FAILED, + reason, + request_id: subscriptionId, + }; + this.session.sendFireAndForget(errorMessage); + } + getStreamId(streamingMethod, branchKey) { + if (typeof branchKey !== "string") { + branchKey = ""; + } + if (!streamingMethod.protocolState.branchKeyToStreamIdMap) { + throw new Error(`streaming ${streamingMethod.definition.name} method without protocol state`); + } + const needleBranch = streamingMethod.protocolState.branchKeyToStreamIdMap.filter((branch) => { + return branch.key === branchKey; + })[0]; + let streamId = (needleBranch ? needleBranch.streamId : undefined); + if (typeof streamId !== "string" || streamId === "") { + streamId = this.getNextStreamId(); + streamingMethod.protocolState.branchKeyToStreamIdMap.push({ key: branchKey, streamId }); + } + return streamId; + } + } + + class ServerProtocol { + session; + clientRepository; + serverRepository; + logger; + callbacks = CallbackRegistryFactory$1(); + streaming; + constructor(session, clientRepository, serverRepository, logger) { + this.session = session; + this.clientRepository = clientRepository; + this.serverRepository = serverRepository; + this.logger = logger; + this.streaming = new ServerStreaming(session, clientRepository, serverRepository); + this.session.on("invoke", (msg) => this.handleInvokeMessage(msg)); + } + createStream(repoMethod) { + repoMethod.protocolState.subscriptionsMap = {}; + repoMethod.protocolState.branchKeyToStreamIdMap = []; + return this.register(repoMethod, true); + } + register(repoMethod, isStreaming) { + const methodDef = repoMethod.definition; + const flags = Object.assign({}, { metadata: methodDef.flags ?? {} }, { streaming: isStreaming || false }); + const registerMsg = { + type: "register", + methods: [{ + id: repoMethod.repoId, + name: methodDef.name, + display_name: methodDef.displayName, + description: methodDef.description, + version: methodDef.version, + flags, + object_types: methodDef.objectTypes || methodDef.object_types, + input_signature: methodDef.accepts, + result_signature: methodDef.returns, + restrictions: undefined, + }], + }; + return this.session.send(registerMsg, { methodId: repoMethod.repoId }) + .then(() => { + this.logger.debug("registered method " + repoMethod.definition.name + " with id " + repoMethod.repoId); + }) + .catch((msg) => { + this.logger.warn(`failed to register method ${repoMethod.definition.name} with id ${repoMethod.repoId} - ${JSON.stringify(msg)}`); + throw msg; + }); + } + onInvoked(callback) { + this.callbacks.add("onInvoked", callback); + } + methodInvocationResult(method, invocationId, err, result) { + let msg; + if (err || err === "") { + msg = { + type: "error", + request_id: invocationId, + reason_uri: "agm.errors.client_error", + reason: err, + context: result, + peer_id: undefined, + }; + } + else { + msg = { + type: "yield", + invocation_id: invocationId, + peer_id: this.session.peerId, + result, + request_id: undefined, + }; + } + this.session.sendFireAndForget(msg); + } + async unregister(method) { + const msg = { + type: "unregister", + methods: [method.repoId], + }; + await this.session.send(msg); + } + getBranchList(method) { + return this.streaming.getBranchList(method); + } + getSubscriptionList(method, branchKey) { + return this.streaming.getSubscriptionList(method, branchKey); + } + closeAllSubscriptions(method, branchKey) { + this.streaming.closeMultipleSubscriptions(method, branchKey); + } + pushData(method, data, branches) { + this.streaming.pushData(method, data, branches); + } + pushDataToSingle(method, subscription, data) { + this.streaming.pushDataToSingle(method, subscription, data); + } + closeSingleSubscription(method, subscription) { + this.streaming.closeSingleSubscription(method, subscription); + } + acceptRequestOnBranch(requestContext, method, branch) { + this.streaming.acceptRequestOnBranch(requestContext, method, branch); + } + rejectRequest(requestContext, method, reason) { + this.streaming.rejectRequest(requestContext, method, reason); + } + onSubRequest(callback) { + this.streaming.onSubRequest(callback); + } + onSubAdded(callback) { + this.streaming.onSubAdded(callback); + } + onSubRemoved(callback) { + this.streaming.onSubRemoved(callback); + } + handleInvokeMessage(msg) { + const invocationId = msg.invocation_id; + const callerId = msg.caller_id; + const methodId = msg.method_id; + const args = msg.arguments_kv; + const methodList = this.serverRepository.getList(); + const method = methodList.filter((m) => { + return m.repoId === methodId; + })[0]; + if (method === undefined) { + return; + } + const client = this.clientRepository.getServerById(callerId)?.instance; + const invocationArgs = { args, instance: client }; + this.callbacks.execute("onInvoked", method, invocationId, invocationArgs); + } + } + + class UserSubscription { + repository; + subscriptionData; + get requestArguments() { + return this.subscriptionData.params.arguments || {}; + } + get servers() { + return this.subscriptionData.trackedServers.reduce((servers, pair) => { + if (pair.subscriptionId) { + const server = this.repository.getServerById(pair.serverId)?.instance; + if (server) { + servers.push(server); + } + } + return servers; + }, []); + } + get serverInstance() { + return this.servers[0]; + } + get stream() { + return this.subscriptionData.method; + } + constructor(repository, subscriptionData) { + this.repository = repository; + this.subscriptionData = subscriptionData; + } + onData(dataCallback) { + if (typeof dataCallback !== "function") { + throw new TypeError("The data callback must be a function."); + } + this.subscriptionData.handlers.onData.push(dataCallback); + if (this.subscriptionData.handlers.onData.length === 1 && this.subscriptionData.queued.data.length > 0) { + this.subscriptionData.queued.data.forEach((dataItem) => { + dataCallback(dataItem); + }); + } + } + onClosed(closedCallback) { + if (typeof closedCallback !== "function") { + throw new TypeError("The callback must be a function."); + } + this.subscriptionData.handlers.onClosed.push(closedCallback); + } + onFailed(callback) { + } + onConnected(callback) { + if (typeof callback !== "function") { + throw new TypeError("The callback must be a function."); + } + this.subscriptionData.handlers.onConnected.push(callback); + } + close() { + this.subscriptionData.close(); + } + setNewSubscription(newSub) { + this.subscriptionData = newSub; + } + } + + class TimedCache { + config; + cache = []; + timeoutIds = []; + constructor(config) { + this.config = config; + } + add(element) { + const id = nanoid$1(10); + this.cache.push({ id, element }); + const timeoutId = setTimeout(() => { + const elementIdx = this.cache.findIndex((entry) => entry.id === id); + if (elementIdx < 0) { + return; + } + this.cache.splice(elementIdx, 1); + }, this.config.ELEMENT_TTL_MS); + this.timeoutIds.push(timeoutId); + } + flush() { + const elements = this.cache.map((entry) => entry.element); + this.timeoutIds.forEach((id) => clearInterval(id)); + this.cache = []; + this.timeoutIds = []; + return elements; + } + } + + const STATUS_AWAITING_ACCEPT = "awaitingAccept"; + const STATUS_SUBSCRIBED = "subscribed"; + const ERR_MSG_SUB_FAILED = "Subscription failed."; + const ERR_MSG_SUB_REJECTED = "Subscription rejected."; + const ON_CLOSE_MSG_SERVER_INIT = "ServerInitiated"; + const ON_CLOSE_MSG_CLIENT_INIT = "ClientInitiated"; + class ClientStreaming { + session; + repository; + logger; + subscriptionsList = {}; + timedCache = new TimedCache({ ELEMENT_TTL_MS: 10000 }); + subscriptionIdToLocalKeyMap = {}; + nextSubLocalKey = 0; + constructor(session, repository, logger) { + this.session = session; + this.repository = repository; + this.logger = logger; + session.on("subscribed", this.handleSubscribed); + session.on("event", this.handleEventData); + session.on("subscription-cancelled", this.handleSubscriptionCancelled); + } + subscribe(streamingMethod, params, targetServers, success, error, existingSub) { + if (targetServers.length === 0) { + error({ + method: streamingMethod, + called_with: params.arguments, + message: ERR_MSG_SUB_FAILED + " No available servers matched the target params.", + }); + return; + } + const subLocalKey = this.getNextSubscriptionLocalKey(); + const pendingSub = this.registerSubscription(subLocalKey, streamingMethod, params, success, error, params.methodResponseTimeout || 10000, existingSub); + if (typeof pendingSub !== "object") { + error({ + method: streamingMethod, + called_with: params.arguments, + message: ERR_MSG_SUB_FAILED + " Unable to register the user callbacks.", + }); + return; + } + targetServers.forEach((target) => { + const serverId = target.server.id; + const method = target.methods.find((m) => m.name === streamingMethod.name); + if (!method) { + this.logger.error(`can not find method ${streamingMethod.name} for target ${target.server.id}`); + return; + } + pendingSub.trackedServers.push({ + serverId, + subscriptionId: undefined, + }); + const msg = { + type: "subscribe", + server_id: serverId, + method_id: method.gatewayId, + arguments_kv: params.arguments, + }; + this.session.send(msg, { serverId, subLocalKey }) + .then((m) => this.handleSubscribed(m)) + .catch((err) => this.handleErrorSubscribing(err)); + }); + } + drainSubscriptions() { + const existing = Object.values(this.subscriptionsList); + this.subscriptionsList = {}; + this.subscriptionIdToLocalKeyMap = {}; + return existing; + } + drainSubscriptionsCache() { + return this.timedCache.flush(); + } + getNextSubscriptionLocalKey() { + const current = this.nextSubLocalKey; + this.nextSubLocalKey += 1; + return current; + } + registerSubscription(subLocalKey, method, params, success, error, timeout, existingSub) { + const subsInfo = { + localKey: subLocalKey, + status: STATUS_AWAITING_ACCEPT, + method, + params, + success, + error, + trackedServers: [], + handlers: { + onData: existingSub?.handlers.onData || [], + onClosed: existingSub?.handlers.onClosed || [], + onConnected: existingSub?.handlers.onConnected || [], + }, + queued: { + data: [], + closers: [], + }, + timeoutId: undefined, + close: () => this.closeSubscription(subLocalKey), + subscription: existingSub?.subscription + }; + if (!existingSub) { + if (params.onData) { + subsInfo.handlers.onData.push(params.onData); + } + if (params.onClosed) { + subsInfo.handlers.onClosed.push(params.onClosed); + } + if (params.onConnected) { + subsInfo.handlers.onConnected.push(params.onConnected); + } + } + this.subscriptionsList[subLocalKey] = subsInfo; + subsInfo.timeoutId = setTimeout(() => { + if (this.subscriptionsList[subLocalKey] === undefined) { + return; + } + const pendingSub = this.subscriptionsList[subLocalKey]; + if (pendingSub.status === STATUS_AWAITING_ACCEPT) { + error({ + method, + called_with: params.arguments, + message: ERR_MSG_SUB_FAILED + " Subscription attempt timed out after " + timeout + " ms.", + }); + delete this.subscriptionsList[subLocalKey]; + } + else if (pendingSub.status === STATUS_SUBSCRIBED && pendingSub.trackedServers.length > 0) { + pendingSub.trackedServers = pendingSub.trackedServers.filter((server) => { + return (typeof server.subscriptionId !== "undefined"); + }); + delete pendingSub.timeoutId; + if (pendingSub.trackedServers.length <= 0) { + this.callOnClosedHandlers(pendingSub); + delete this.subscriptionsList[subLocalKey]; + } + } + }, timeout); + return subsInfo; + } + handleErrorSubscribing = (errorResponse) => { + const tag = errorResponse._tag; + const subLocalKey = tag.subLocalKey; + const pendingSub = this.subscriptionsList[subLocalKey]; + if (typeof pendingSub !== "object") { + return; + } + pendingSub.trackedServers = pendingSub.trackedServers.filter((server) => { + return server.serverId !== tag.serverId; + }); + if (pendingSub.trackedServers.length <= 0) { + clearTimeout(pendingSub.timeoutId); + if (pendingSub.status === STATUS_AWAITING_ACCEPT) { + const reason = (typeof errorResponse.reason === "string" && errorResponse.reason !== "") ? + ' Publisher said "' + errorResponse.reason + '".' : + " No reason given."; + const callArgs = typeof pendingSub.params.arguments === "object" ? + JSON.stringify(pendingSub.params.arguments) : + "{}"; + pendingSub.error({ + message: ERR_MSG_SUB_REJECTED + reason + " Called with:" + callArgs, + called_with: pendingSub.params.arguments, + method: pendingSub.method, + }); + } + else if (pendingSub.status === STATUS_SUBSCRIBED) { + this.callOnClosedHandlers(pendingSub); + } + delete this.subscriptionsList[subLocalKey]; + } + }; + handleSubscribed = (msg) => { + const subLocalKey = msg._tag.subLocalKey; + const pendingSub = this.subscriptionsList[subLocalKey]; + if (typeof pendingSub !== "object") { + return; + } + const serverId = msg._tag.serverId; + const acceptingServer = pendingSub.trackedServers + .filter((server) => { + return server.serverId === serverId; + })[0]; + if (typeof acceptingServer !== "object") { + return; + } + acceptingServer.subscriptionId = msg.subscription_id; + this.subscriptionIdToLocalKeyMap[msg.subscription_id] = subLocalKey; + const isFirstResponse = (pendingSub.status === STATUS_AWAITING_ACCEPT); + pendingSub.status = STATUS_SUBSCRIBED; + if (isFirstResponse) { + let reconnect = false; + let sub = pendingSub.subscription; + if (sub) { + sub.setNewSubscription(pendingSub); + pendingSub.success(sub); + reconnect = true; + } + else { + sub = new UserSubscription(this.repository, pendingSub); + pendingSub.subscription = sub; + pendingSub.success(sub); + } + for (const handler of pendingSub.handlers.onConnected) { + try { + handler(sub.serverInstance, reconnect); + } + catch (e) { + } + } + } + }; + handleEventData = (msg) => { + const subLocalKey = this.subscriptionIdToLocalKeyMap[msg.subscription_id]; + if (typeof subLocalKey === "undefined") { + return; + } + const subscription = this.subscriptionsList[subLocalKey]; + if (typeof subscription !== "object") { + return; + } + const trackedServersFound = subscription.trackedServers.filter((s) => { + return s.subscriptionId === msg.subscription_id; + }); + if (trackedServersFound.length !== 1) { + return; + } + const isPrivateData = msg.oob; + const sendingServerId = trackedServersFound[0].serverId; + const server = this.repository.getServerById(sendingServerId); + const receivedStreamData = () => { + return { + data: msg.data, + server: server?.instance ?? {}, + requestArguments: subscription.params.arguments, + message: undefined, + private: isPrivateData, + }; + }; + const onDataHandlers = subscription.handlers.onData; + const queuedData = subscription.queued.data; + if (onDataHandlers.length > 0) { + onDataHandlers.forEach((callback) => { + if (typeof callback === "function") { + callback(receivedStreamData()); + } + }); + } + else { + queuedData.push(receivedStreamData()); + } + }; + handleSubscriptionCancelled = (msg) => { + const subLocalKey = this.subscriptionIdToLocalKeyMap[msg.subscription_id]; + if (typeof subLocalKey === "undefined") { + return; + } + const subscription = this.subscriptionsList[subLocalKey]; + if (typeof subscription !== "object") { + return; + } + const expectedNewLength = subscription.trackedServers.length - 1; + subscription.trackedServers = subscription.trackedServers.filter((server) => { + if (server.subscriptionId === msg.subscription_id) { + subscription.queued.closers.push(server.serverId); + return false; + } + else { + return true; + } + }); + if (subscription.trackedServers.length !== expectedNewLength) { + return; + } + if (subscription.trackedServers.length <= 0) { + this.timedCache.add(subscription); + clearTimeout(subscription.timeoutId); + this.callOnClosedHandlers(subscription); + delete this.subscriptionsList[subLocalKey]; + } + delete this.subscriptionIdToLocalKeyMap[msg.subscription_id]; + }; + callOnClosedHandlers(subscription, reason) { + const closersCount = subscription.queued.closers.length; + const closingServerId = (closersCount > 0) ? subscription.queued.closers[closersCount - 1] : null; + let closingServer; + if (closingServerId !== undefined && typeof closingServerId === "string") { + closingServer = this.repository.getServerById(closingServerId)?.instance ?? {}; + } + subscription.handlers.onClosed.forEach((callback) => { + if (typeof callback !== "function") { + return; + } + callback({ + message: reason || ON_CLOSE_MSG_SERVER_INIT, + requestArguments: subscription.params.arguments || {}, + server: closingServer, + stream: subscription.method, + }); + }); + } + closeSubscription(subLocalKey) { + const subscription = this.subscriptionsList[subLocalKey]; + if (typeof subscription !== "object") { + return; + } + subscription.trackedServers.forEach((server) => { + if (typeof server.subscriptionId === "undefined") { + return; + } + subscription.queued.closers.push(server.serverId); + this.session.sendFireAndForget({ + type: "unsubscribe", + subscription_id: server.subscriptionId, + reason_uri: "", + reason: ON_CLOSE_MSG_CLIENT_INIT, + }); + delete this.subscriptionIdToLocalKeyMap[server.subscriptionId]; + }); + subscription.trackedServers = []; + this.callOnClosedHandlers(subscription, ON_CLOSE_MSG_CLIENT_INIT); + delete this.subscriptionsList[subLocalKey]; + } + } + + class ClientProtocol { + session; + repository; + logger; + streaming; + constructor(session, repository, logger) { + this.session = session; + this.repository = repository; + this.logger = logger; + session.on("peer-added", (msg) => this.handlePeerAdded(msg)); + session.on("peer-removed", (msg) => this.handlePeerRemoved(msg)); + session.on("methods-added", (msg) => this.handleMethodsAddedMessage(msg)); + session.on("methods-removed", (msg) => this.handleMethodsRemovedMessage(msg)); + this.streaming = new ClientStreaming(session, repository, logger); + } + subscribe(stream, options, targetServers, success, error, existingSub) { + this.streaming.subscribe(stream, options, targetServers, success, error, existingSub); + } + invoke(id, method, args, target) { + const serverId = target.id; + const methodId = method.gatewayId; + const msg = { + type: "call", + server_id: serverId, + method_id: methodId, + arguments_kv: args, + }; + return this.session.send(msg, { invocationId: id, serverId }) + .then((m) => this.handleResultMessage(m)) + .catch((err) => this.handleInvocationError(err)); + } + drainSubscriptions() { + return this.streaming.drainSubscriptions(); + } + drainSubscriptionsCache() { + return this.streaming.drainSubscriptionsCache(); + } + handlePeerAdded(msg) { + const newPeerId = msg.new_peer_id; + const remoteId = msg.identity; + const isLocal = msg.meta ? msg.meta.local : true; + const pid = Number(remoteId.process); + const serverInfo = { + machine: remoteId.machine, + pid: isNaN(pid) ? remoteId.process : pid, + instance: remoteId.instance, + application: remoteId.application, + applicationName: remoteId.applicationName, + environment: remoteId.environment, + region: remoteId.region, + user: remoteId.user, + windowId: remoteId.windowId, + peerId: newPeerId, + api: remoteId.api, + isLocal + }; + this.repository.addServer(serverInfo, newPeerId); + } + handlePeerRemoved(msg) { + const removedPeerId = msg.removed_id; + const reason = msg.reason; + this.repository.removeServerById(removedPeerId, reason); + } + handleMethodsAddedMessage(msg) { + const serverId = msg.server_id; + const methods = msg.methods; + methods.forEach((method) => { + this.repository.addServerMethod(serverId, method); + }); + } + handleMethodsRemovedMessage(msg) { + const serverId = msg.server_id; + const methodIdList = msg.methods; + const server = this.repository.getServerById(serverId); + if (server) { + const serverMethodKeys = Object.keys(server.methods); + serverMethodKeys.forEach((methodKey) => { + const method = server.methods[methodKey]; + if (methodIdList.indexOf(method.gatewayId) > -1) { + this.repository.removeServerMethod(serverId, methodKey); + } + }); + } + } + handleResultMessage(msg) { + const invocationId = msg._tag.invocationId; + const result = msg.result; + const serverId = msg._tag.serverId; + const server = this.repository.getServerById(serverId); + return { + invocationId, + result, + instance: server?.instance, + status: InvokeStatus.Success, + message: "" + }; + } + handleInvocationError(msg) { + this.logger.debug(`handle invocation error ${JSON.stringify(msg)}`); + if ("_tag" in msg) { + const invocationId = msg._tag.invocationId; + const serverId = msg._tag.serverId; + const server = this.repository.getServerById(serverId); + const message = msg.reason; + const context = msg.context; + return { + invocationId, + result: context, + instance: server?.instance, + status: InvokeStatus.Error, + message + }; + } + else { + return { + invocationId: "", + message: msg.message, + status: InvokeStatus.Error, + error: msg + }; + } + } + } + + function gW3ProtocolFactory (instance, connection, clientRepository, serverRepository, libConfig, interop) { + const logger = libConfig.logger.subLogger("gw3-protocol"); + let resolveReadyPromise; + const readyPromise = new Promise((resolve) => { + resolveReadyPromise = resolve; + }); + const session = connection.domain("agm", ["subscribed"]); + const server = new ServerProtocol(session, clientRepository, serverRepository, logger.subLogger("server")); + const client = new ClientProtocol(session, clientRepository, logger.subLogger("client")); + async function handleReconnect() { + logger.info("reconnected - will replay registered methods and subscriptions"); + client.drainSubscriptionsCache().forEach((sub) => { + const methodInfo = sub.method; + const params = Object.assign({}, sub.params); + logger.info(`trying to soft-re-subscribe to method ${methodInfo.name}, with params: ${JSON.stringify(params)}`); + interop.client.subscribe(methodInfo, params, undefined, undefined, sub).then(() => logger.info(`soft-subscribing to method ${methodInfo.name} DONE`)).catch((error) => logger.warn(`subscribing to method ${methodInfo.name} failed: ${JSON.stringify(error)}}`)); + }); + const reconnectionPromises = []; + const existingSubscriptions = client.drainSubscriptions(); + for (const sub of existingSubscriptions) { + const methodInfo = sub.method; + const params = Object.assign({}, sub.params); + logger.info(`trying to re-subscribe to method ${methodInfo.name}, with params: ${JSON.stringify(params)}`); + reconnectionPromises.push(interop.client.subscribe(methodInfo, params, undefined, undefined, sub).then(() => logger.info(`subscribing to method ${methodInfo.name} DONE`))); + } + const registeredMethods = serverRepository.getList(); + serverRepository.reset(); + for (const method of registeredMethods) { + const def = method.definition; + if (method.stream) { + reconnectionPromises.push(interop.server.createStream(def, method.streamCallbacks, undefined, undefined, method.stream) + .then(() => logger.info(`subscribing to method ${def.name} DONE`)) + .catch(() => logger.warn(`subscribing to method ${def.name} FAILED`))); + } + else if (method?.theFunction?.userCallback) { + reconnectionPromises.push(interop.register(def, method.theFunction.userCallback) + .then(() => logger.info(`registering method ${def.name} DONE`)) + .catch(() => logger.warn(`registering method ${def.name} FAILED`))); + } + else if (method?.theFunction?.userCallbackAsync) { + reconnectionPromises.push(interop.registerAsync(def, method.theFunction.userCallbackAsync) + .then(() => logger.info(`registering method ${def.name} DONE`)) + .catch(() => logger.warn(`registering method ${def.name} FAILED`))); + } + } + await Promise.all(reconnectionPromises); + logger.info("Interop is re-announced"); + } + function handleInitialJoin() { + if (resolveReadyPromise) { + resolveReadyPromise({ + client, + server, + }); + resolveReadyPromise = undefined; + } + } + session.onJoined((reconnect) => { + clientRepository.addServer(instance, connection.peerId); + if (reconnect) { + handleReconnect().then(() => connection.setLibReAnnounced({ name: "interop" })).catch((error) => logger.warn(`Error while re-announcing interop: ${JSON.stringify(error)}`)); + } + else { + handleInitialJoin(); + } + }); + session.onLeft(() => { + clientRepository.reset(); + }); + session.join(); + return readyPromise; + } + + class Interop { + instance; + readyPromise; + client; + server; + unwrappedInstance; + protocol; + clientRepository; + serverRepository; + constructor(configuration) { + if (typeof configuration === "undefined") { + throw new Error("configuration is required"); + } + if (typeof configuration.connection === "undefined") { + throw new Error("configuration.connections is required"); + } + const connection = configuration.connection; + if (typeof configuration.methodResponseTimeout !== "number") { + configuration.methodResponseTimeout = 30 * 1000; + } + if (typeof configuration.waitTimeoutMs !== "number") { + configuration.waitTimeoutMs = 30 * 1000; + } + this.unwrappedInstance = new InstanceWrapper(this, undefined, connection); + this.instance = this.unwrappedInstance.unwrap(); + this.clientRepository = new ClientRepository(configuration.logger.subLogger("cRep"), this); + this.serverRepository = new ServerRepository(); + let protocolPromise; + if (connection.protocolVersion === 3) { + protocolPromise = gW3ProtocolFactory(this.instance, connection, this.clientRepository, this.serverRepository, configuration, this); + } + else { + throw new Error(`protocol ${connection.protocolVersion} not supported`); + } + this.readyPromise = protocolPromise.then((protocol) => { + this.protocol = protocol; + this.client = new Client(this.protocol, this.clientRepository, this.instance, configuration); + this.server = new Server(this.protocol, this.serverRepository); + return this; + }); + } + ready() { + return this.readyPromise; + } + serverRemoved(callback) { + return this.client.serverRemoved(callback); + } + serverAdded(callback) { + return this.client.serverAdded(callback); + } + serverMethodRemoved(callback) { + return this.client.serverMethodRemoved(callback); + } + serverMethodAdded(callback) { + return this.client.serverMethodAdded(callback); + } + methodRemoved(callback) { + return this.client.methodRemoved(callback); + } + methodAdded(callback) { + return this.client.methodAdded(callback); + } + methodsForInstance(instance) { + return this.client.methodsForInstance(instance); + } + methods(methodFilter) { + return this.client.methods(methodFilter); + } + servers(methodFilter) { + return this.client.servers(methodFilter); + } + subscribe(method, options, successCallback, errorCallback) { + return this.client.subscribe(method, options, successCallback, errorCallback); + } + createStream(streamDef, callbacks, successCallback, errorCallback) { + return this.server.createStream(streamDef, callbacks, successCallback, errorCallback); + } + unregister(methodFilter) { + return this.server.unregister(methodFilter); + } + registerAsync(methodDefinition, callback) { + return this.server.registerAsync(methodDefinition, callback); + } + register(methodDefinition, callback) { + return this.server.register(methodDefinition, callback); + } + invoke(methodFilter, argumentObj, target, additionalOptions, success, error) { + return this.client.invoke(methodFilter, argumentObj, target, additionalOptions, success, error); + } + waitForMethod(name) { + const pw = new PromiseWrapper$1(); + const unsubscribe = this.client.methodAdded((m) => { + if (m.name === name) { + unsubscribe(); + pw.resolve(m); + } + }); + return pw.promise; + } + } + + const successMessages = ["subscribed", "success"]; + class MessageBus { + connection; + logger; + peerId; + session; + subscriptions; + readyPromise; + constructor(connection, logger) { + this.connection = connection; + this.logger = logger; + this.peerId = connection.peerId; + this.subscriptions = []; + this.session = connection.domain("bus", successMessages); + this.readyPromise = this.session.join(); + this.readyPromise.then(() => { + this.watchOnEvent(); + }); + } + ready() { + return this.readyPromise; + } + publish = (topic, data, options) => { + const { routingKey, target } = options || {}; + const args = this.removeEmptyValues({ + type: "publish", + topic, + data, + peer_id: this.peerId, + routing_key: routingKey, + target_identity: target + }); + this.session.send(args); + }; + subscribe = (topic, callback, options) => { + return new Promise((resolve, reject) => { + const { routingKey, target } = options || {}; + const args = this.removeEmptyValues({ + type: "subscribe", + topic, + peer_id: this.peerId, + routing_key: routingKey, + source: target + }); + this.session.send(args) + .then((response) => { + const { subscription_id } = response; + this.subscriptions.push({ subscription_id, topic, callback, source: target }); + resolve({ + unsubscribe: () => { + this.session.send({ type: "unsubscribe", subscription_id, peer_id: this.peerId }); + this.subscriptions = this.subscriptions.filter((s) => s.subscription_id !== subscription_id); + return Promise.resolve(); + } + }); + }) + .catch((error) => reject(error)); + }); + }; + watchOnEvent = () => { + this.session.on("event", (args) => { + const { data, subscription_id } = args; + const source = args["publisher-identity"]; + const subscription = this.subscriptions.find((s) => s.subscription_id === subscription_id); + if (subscription) { + if (!subscription.source) { + subscription.callback(data, subscription.topic, source); + } + else { + if (this.keysMatch(subscription.source, source)) { + subscription.callback(data, subscription.topic, source); + } + } + } + }); + }; + removeEmptyValues(obj) { + const cleaned = {}; + Object.keys(obj).forEach((key) => { + if (obj[key] !== undefined && obj[key] !== null) { + cleaned[key] = obj[key]; + } + }); + return cleaned; + } + keysMatch(obj1, obj2) { + const keysObj1 = Object.keys(obj1); + let allMatch = true; + keysObj1.forEach((key) => { + if (obj1[key] !== obj2[key]) { + allMatch = false; + } + }); + return allMatch; + } + } + + const IOConnectCoreFactory = (userConfig, ext) => { + const iodesktop = typeof window === "object" ? (window.iodesktop ?? window.glue42gd) : undefined; + const preloadPromise = typeof window === "object" ? (window.gdPreloadPromise ?? Promise.resolve()) : Promise.resolve(); + const glueInitTimer = timer("glue"); + userConfig = userConfig || {}; + ext = ext || {}; + const internalConfig = prepareConfig$1(userConfig, ext, iodesktop); + let _connection; + let _interop; + let _logger; + let _metrics; + let _contexts; + let _bus; + let _allowTrace; + const libs = {}; + function registerLib(name, inner, t) { + _allowTrace = _logger.canPublish("trace"); + if (_allowTrace) { + _logger.trace(`registering ${name} module`); + } + const done = (e) => { + inner.initTime = t.stop(); + inner.initEndTime = t.endTime; + inner.marks = t.marks; + if (!_allowTrace) { + return; + } + const traceMessage = e ? + `${name} failed - ${e.message}` : + `${name} is ready - ${t.endTime - t.startTime}`; + _logger.trace(traceMessage); + }; + inner.initStartTime = t.startTime; + if (inner.ready) { + inner.ready() + .then(() => { + done(); + }) + .catch((e) => { + const error = typeof e === "string" ? new Error(e) : e; + done(error); + }); + } + else { + done(); + } + if (!Array.isArray(name)) { + name = [name]; + } + name.forEach((n) => { + libs[n] = inner; + IOConnectCoreFactory[n] = inner; + }); + } + function setupConnection() { + const initTimer = timer("connection"); + _connection = new Connection(internalConfig.connection, _logger.subLogger("connection")); + let authPromise = Promise.resolve(internalConfig.auth); + if (internalConfig.connection && !internalConfig.auth) { + if (iodesktop) { + authPromise = iodesktop.getGWToken() + .then((token) => { + return { + gatewayToken: token + }; + }); + } + else if (typeof window !== "undefined" && window?.glue42electron) { + if (typeof window.glue42electron.gwToken === "string") { + authPromise = Promise.resolve({ + gatewayToken: window.glue42electron.gwToken + }); + } + } + else { + authPromise = Promise.reject("You need to provide auth information"); + } + } + return authPromise + .then((authConfig) => { + initTimer.mark("auth-promise-resolved"); + let authRequest; + if (Object.prototype.toString.call(authConfig) === "[object Object]") { + authRequest = authConfig; + } + else { + throw new Error("Invalid auth object - " + JSON.stringify(authConfig)); + } + return _connection.login(authRequest); + }) + .then(() => { + registerLib("connection", _connection, initTimer); + return internalConfig; + }) + .catch((e) => { + if (_connection) { + _connection.logout(); + } + throw e; + }); + } + function setupLogger() { + const initTimer = timer("logger"); + _logger = new Logger$1(`${internalConfig.connection.identity?.application}`, undefined, internalConfig.customLogger); + _logger.consoleLevel(internalConfig.logger.console); + _logger.publishLevel(internalConfig.logger.publish); + if (_logger.canPublish("debug")) { + _logger.debug("initializing glue..."); + } + registerLib("logger", _logger, initTimer); + return Promise.resolve(undefined); + } + function setupMetrics() { + const initTimer = timer("metrics"); + const config = internalConfig.metrics; + const metricsPublishingEnabledFunc = iodesktop?.getMetricsPublishingEnabled; + const identity = internalConfig.connection.identity; + const canUpdateMetric = metricsPublishingEnabledFunc ? metricsPublishingEnabledFunc : () => true; + const disableAutoAppSystem = (typeof config !== "boolean" && config.disableAutoAppSystem) ?? false; + _metrics = metrics({ + connection: config ? _connection : undefined, + logger: _logger.subLogger("metrics"), + canUpdateMetric, + system: "Glue42", + service: identity?.service ?? iodesktop?.applicationName ?? internalConfig.application, + instance: identity?.instance ?? identity?.windowId ?? nanoid$1(10), + disableAutoAppSystem, + pagePerformanceMetrics: typeof config !== "boolean" ? config?.pagePerformanceMetrics : undefined + }); + registerLib("metrics", _metrics, initTimer); + return Promise.resolve(); + } + function setupInterop() { + const initTimer = timer("interop"); + const agmConfig = { + connection: _connection, + logger: _logger.subLogger("interop"), + }; + _interop = new Interop(agmConfig); + Logger$1.Interop = _interop; + registerLib(["interop", "agm"], _interop, initTimer); + return Promise.resolve(); + } + function setupContexts() { + const hasActivities = (internalConfig.activities && _connection.protocolVersion === 3); + const needsContexts = internalConfig.contexts || hasActivities; + if (needsContexts) { + const initTimer = timer("contexts"); + _contexts = new ContextsModule({ + connection: _connection, + logger: _logger.subLogger("contexts"), + trackAllContexts: typeof internalConfig.contexts === "object" ? internalConfig.contexts.trackAllContexts : false, + reAnnounceKnownContexts: typeof internalConfig.contexts === "object" ? internalConfig.contexts.reAnnounceKnownContexts : false + }); + registerLib("contexts", _contexts, initTimer); + return _contexts; + } + else { + const replayer = _connection.replayer; + if (replayer) { + replayer.drain(ContextMessageReplaySpec.name); + } + } + } + async function setupBus() { + if (!internalConfig.bus) { + return Promise.resolve(); + } + const initTimer = timer("bus"); + _bus = new MessageBus(_connection, _logger.subLogger("bus")); + registerLib("bus", _bus, initTimer); + return Promise.resolve(); + } + function setupExternalLibs(externalLibs) { + try { + externalLibs.forEach((lib) => { + setupExternalLib(lib.name, lib.create); + }); + return Promise.resolve(); + } + catch (e) { + return Promise.reject(e); + } + } + function setupExternalLib(name, createCallback) { + const initTimer = timer(name); + const lib = createCallback(libs); + if (lib) { + registerLib(name, lib, initTimer); + } + } + function waitForLibs() { + const libsReadyPromises = Object.keys(libs).map((key) => { + const lib = libs[key]; + return lib.ready ? + lib.ready() : Promise.resolve(); + }); + return Promise.all(libsReadyPromises); + } + function constructGlueObject() { + const feedbackFunc = (feedbackInfo) => { + if (!_interop) { + return; + } + _interop.invoke("T42.ACS.Feedback", feedbackInfo, "best"); + }; + const info = { + coreVersion: version$1, + version: internalConfig.version + }; + glueInitTimer.stop(); + const glue = { + feedback: feedbackFunc, + info, + logger: _logger, + interop: _interop, + agm: _interop, + connection: _connection, + metrics: _metrics, + contexts: _contexts, + bus: _bus, + version: internalConfig.version, + userConfig, + done: () => { + _logger?.info("done called by user..."); + return _connection.logout(); + } + }; + glue.performance = { + get glueVer() { + return internalConfig.version; + }, + get glueConfig() { + return JSON.stringify(userConfig); + }, + get browser() { + return window.performance.timing.toJSON(); + }, + get memory() { + return window.performance.memory; + }, + get initTimes() { + const all = getAllTimers(); + return Object.keys(all).map((key) => { + const t = all[key]; + return { + name: key, + duration: t.endTime - t.startTime, + marks: t.marks, + startTime: t.startTime, + endTime: t.endTime + }; + }); + } + }; + Object.keys(libs).forEach((key) => { + const lib = libs[key]; + glue[key] = lib; + }); + glue.config = {}; + Object.keys(internalConfig).forEach((k) => { + glue.config[k] = internalConfig[k]; + }); + if (ext && ext.extOptions) { + Object.keys(ext.extOptions).forEach((k) => { + glue.config[k] = ext?.extOptions[k]; + }); + } + if (ext?.enrichGlue) { + ext.enrichGlue(glue); + } + if (iodesktop && iodesktop.updatePerfData) { + iodesktop.updatePerfData(glue.performance); + } + if (glue.agm) { + const deprecatedDecorator = (fn, wrong, proper) => { + return function () { + glue.logger.warn(`glue.js - 'glue.agm.${wrong}' method is deprecated, use 'glue.interop.${proper}' instead.`); + return fn.apply(glue.agm, arguments); + }; + }; + const agmAny = glue.agm; + agmAny.method_added = deprecatedDecorator(glue.agm.methodAdded, "method_added", "methodAdded"); + agmAny.method_removed = deprecatedDecorator(glue.agm.methodRemoved, "method_removed", "methodRemoved"); + agmAny.server_added = deprecatedDecorator(glue.agm.serverAdded, "server_added", "serverAdded"); + agmAny.server_method_aded = deprecatedDecorator(glue.agm.serverMethodAdded, "server_method_aded", "serverMethodAdded"); + agmAny.server_method_removed = deprecatedDecorator(glue.agm.serverMethodRemoved, "server_method_removed", "serverMethodRemoved"); + } + return glue; + } + async function registerInstanceIfNeeded() { + const RegisterInstanceMethodName = "T42.ACS.RegisterInstance"; + if (Utils$1.isNode() && typeof process.env._GD_STARTING_CONTEXT_ === "undefined" && typeof userConfig?.application !== "undefined") { + const isMethodAvailable = _interop.methods({ name: RegisterInstanceMethodName }).length > 0; + if (isMethodAvailable) { + try { + await _interop.invoke(RegisterInstanceMethodName, { appName: userConfig?.application, pid: process.pid }); + } + catch (error) { + const typedError = error; + _logger.error(`Cannot register as an instance: ${JSON.stringify(typedError.message)}`); + } + } + } + } + return preloadPromise + .then(setupLogger) + .then(setupConnection) + .then(() => Promise.all([setupMetrics(), setupInterop(), setupContexts(), setupBus()])) + .then(() => _interop.readyPromise) + .then(() => registerInstanceIfNeeded()) + .then(() => { + return setupExternalLibs(internalConfig.libs || []); + }) + .then(waitForLibs) + .then(constructGlueObject) + .catch((err) => { + return Promise.reject({ + err, + libs + }); + }); + }; + if (typeof window !== "undefined") { + window.IOConnectCore = IOConnectCoreFactory; + } + IOConnectCoreFactory.version = version$1; + IOConnectCoreFactory.default = IOConnectCoreFactory; + + class ActivityEntity { + constructor(id) { + this._id = id; + } + get id() { + return this._id; + } + _update(other) { + if (other._id !== this._id) { + throw Error("Can not update from entity with different id."); + } + this._updateCore(other); + } + _updateCore(other) { + return; + } + _beforeDelete(other) { + return; + } + } + + function isNumber(arg) { + return typeof arg === "number"; + } + function isString(arg) { + return typeof arg === "string"; + } + function isObject(arg) { + return typeof arg === "object" && !Array.isArray(arg) && arg !== null; + } + function isArray(arg) { + if (Array.isArray) { + return Array.isArray(arg); + } + return toString.call(arg) === "[object Array]"; + } + function isUndefined(arg) { + return typeof arg === "undefined"; + } + function isUndefinedOrNull(arg) { + return arg === null || typeof arg === "undefined"; + } + function isNullOrWhiteSpace(str) { + return (typeof str !== "string" || !str || str.length === 0 || /^\s*$/.test(str)); + } + function isBoolean(obj) { + return obj === true || obj === false || toString.call(obj) === "[object Boolean]"; + } + function isFunction(arg) { + return !!(arg && arg.constructor && arg.call && arg.apply); + } + function some(array, predicate) { + for (let index = 0; index < array.length; index++) { + if (predicate(array[index], index)) { + return true; + } + } + return false; + } + function ifNotUndefined(what, doWithIt) { + if (typeof what !== "undefined") { + doWithIt(what); + } + } + function promisify$1(promise, successCallback, errorCallback) { + if (typeof successCallback !== "function" && typeof errorCallback !== "function") { + return promise; + } + if (typeof successCallback !== "function") { + successCallback = () => { return; }; + } + else if (typeof errorCallback !== "function") { + errorCallback = () => { return; }; + } + promise.then(successCallback, errorCallback); + } + + class ActivityType extends ActivityEntity { + constructor(name, ownerWindow, helperWindows, description) { + super(name); + this._name = name; + this._description = description; + this._ownerWindow = ownerWindow; + this._helperWindows = helperWindows || []; + } + get name() { + return this._name; + } + get description() { + return this._description; + } + get helperWindows() { + return this._helperWindows.map((hw) => this.covertToWindowDef(hw)); + } + get ownerWindow() { + return this.covertToWindowDef(this._ownerWindow); + } + initiate(context, callback, configuration) { + return this._manager.initiate(this._name, context, callback, configuration); + } + _updateCore(other) { + super._updateCore(other); + ifNotUndefined(other._description, (x) => this._description = x); + ifNotUndefined(other._ownerWindow, (x) => this._ownerWindow = x); + ifNotUndefined(other._helperWindows, (x) => this._helperWindows = x); + } + covertToWindowDef(windowType) { + var _a, _b; + return { + type: (_a = windowType === null || windowType === void 0 ? void 0 : windowType.id) === null || _a === void 0 ? void 0 : _a.type, + name: (_b = windowType === null || windowType === void 0 ? void 0 : windowType.id) === null || _b === void 0 ? void 0 : _b.name + }; + } + } + + class WindowType extends ActivityEntity { + constructor(name, appByWindowTypeGetter) { + super(name); + this._name = name; + this._appByWindowTypeGetter = appByWindowTypeGetter; + } + get name() { + return this._name; + } + get config() { + return this._appByWindowTypeGetter(this._name); + } + get windows() { + return this._manager.getWindows({ type: this._name }); + } + create(activity, configuration) { + const definition = Object.assign({ type: this.name, name: this.name, isIndependent: false }, configuration); + return this._manager.createWindow(activity, definition); + } + } + + class EntityEvent { + constructor(entitiy, context) { + this.entity = entitiy; + this.context = context; + } + } + class EntityEventContext { + constructor(eventType) { + this.type = eventType; + } + } + class ActivityStatusChangeEventContext extends EntityEventContext { + constructor(newStatus, oldStatus) { + super(EntityEventType.StatusChange); + this.newStatus = newStatus; + this.oldStatus = oldStatus; + } + } + class ActivityContextChangedEventContext extends EntityEventContext { + constructor(context, updated, removed) { + super(EntityEventType.ActivityContextChange); + this.context = typeof context === "string" ? JSON.parse(context) : context; + this.updated = updated; + this.removed = removed; + } + } + class EntityEventType { + } + EntityEventType.Added = "added"; + EntityEventType.Removed = "removed"; + EntityEventType.Updated = "updated"; + EntityEventType.Closed = "closed"; + EntityEventType.StatusChange = "statusChange"; + EntityEventType.ActivityContextChange = "activityContextUpdate"; + EntityEventType.ActivityWindowEvent = "activityWindowEvent"; + EntityEventType.ActivityWindowJoinedActivity = "joined"; + EntityEventType.ActivityWindowLeftActivity = "left"; + class ActivityState { + } + ActivityState.Created = "created"; + ActivityState.Started = "started"; + ActivityState.Destroyed = "destroyed"; + + class ActivityAGM { + constructor(activity) { + this._activity = activity; + } + register(definition, handler) { + this._ensureHasAgm(); + ActivityAGM.AGM.register(definition, handler); + } + servers() { + this._ensureHasAgm(); + if (isUndefinedOrNull(this._activity)) { + return []; + } + return this._activity.windows.map((w) => { + return w.instance; + }); + } + methods() { + this._ensureHasAgm(); + if (isUndefinedOrNull(this._activity)) { + return []; + } + const windows = this._activity.windows; + const methodNames = []; + const methods = []; + windows.forEach((window) => { + const windowMethods = this.methodsForWindow(window); + windowMethods.forEach((currentWindowMethod) => { + if (methodNames.indexOf(currentWindowMethod.name) === -1) { + methodNames.push(currentWindowMethod.name); + methods.push(currentWindowMethod); + } + }); + }); + return methods; + } + methodsForWindow(window) { + this._ensureHasAgm(); + if (!window.instance) { + return []; + } + return ActivityAGM.AGM.methodsForInstance(window.instance); + } + invoke(methodName, arg, target, options, success, error) { + this._ensureHasAgm(); + const activityServers = this.servers(); + if (isUndefinedOrNull(target)) { + target = "activity.all"; + } + if (isString(target)) { + if (target === "activity.all") ; + else if (target === "activity.best") { + const potentialTargets = activityServers.filter((server) => { + const methods = ActivityAGM.AGM.methodsForInstance(server); + return methods.filter((m) => { + return m.name === methodName; + }).length > 0; + }); + if (potentialTargets.length > 0) { + [potentialTargets[0]]; + } + } + else if (target === "all" || target === "best") { + return promisify$1(ActivityAGM.AGM.invoke(methodName, arg, target, options), success, error); + } + else { + throw new Error("Invalid invoke target " + target); + } + } + else if (isArray(target)) { + if (target.length >= 0) { + const firstElem = target[0]; + if (this._isInstance(firstElem)) { + target.map((instance) => instance); + } + else if (this._isActivityWindow(firstElem)) { + target.map((win) => win.instance); + } + else { + throw new Error("Unknown target object"); + } + } + } + else { + if (this._isInstance(target)) ; + else if (this._isActivityWindow(target)) { + [target.instance]; + } + else { + throw new Error("Unknown target object"); + } + } + throw new Error("Not implemented"); + } + unregister(definition) { + this._ensureHasAgm(); + return ActivityAGM.AGM.unregister(definition); + } + createStream(methodDefinition, subscriptionAddedHandler, subscriptionRemovedHandler) { + this._ensureHasAgm(); + ActivityAGM.AGM.createStream(methodDefinition, { + subscriptionAddedHandler, + subscriptionRemovedHandler, + subscriptionRequestHandler: undefined + }); + } + subscribe(methodDefinition, parameters, target) { + this._ensureHasAgm(); + return ActivityAGM.AGM.subscribe(methodDefinition, parameters); + } + _ensureHasAgm() { + if (isUndefinedOrNull(ActivityAGM.AGM)) { + throw new Error("Agm should be configured to be used in activity"); + } + } + _isInstance(obj) { + return obj.application !== undefined; + } + _isActivityWindow(obj) { + return obj.instance !== undefined; + } + } + + class AttachedActivityDescriptor { + constructor(manager, ownerActivityId, state) { + this._manager = manager; + this._ownerActivityId = ownerActivityId; + this._state = state; + } + get ownerId() { + return this._state.ownerId; + } + get windowIds() { + return this._state.windowIds; + } + get frameColor() { + return this._state.frameColor; + } + get context() { + return this._state.context; + } + get tag() { + return this._state.tag; + } + detach(descriptor) { + descriptor = descriptor || {}; + const merged = {}; + Object.keys(this._state).forEach((prop) => { + merged[prop] = this._state[prop]; + }); + merged.context = descriptor.context || merged.context; + merged.frameColor = descriptor.frameColor || merged.frameColor; + return this._manager.detachActivities(this._ownerActivityId, merged); + } + } + + const nextTick = (cb) => { + setTimeout(cb, 0); + }; + function nodeify(promise, callback) { + if (!isFunction(callback)) { + return promise; + } + promise.then((resp) => { + nextTick(() => { + callback(null, resp); + }); + }, (err) => { + nextTick(() => { + callback(err, null); + }); + }); + } + + class Activity extends ActivityEntity { + constructor(id, actType, status, context, ownerId) { + super(id); + this._id = id; + this._actType = actType; + this._status = status; + this._context = context; + this._ownerId = ownerId; + this._agm = new ActivityAGM(this); + } + get type() { + if (this._manager) { + return this._manager.getActivityType(this._actType); + } + return undefined; + } + get context() { + return this._context; + } + get status() { + return this._status; + } + get owner() { + if (!this._ownerId) { + return null; + } + return this._manager.getWindows({ id: this._ownerId })[0]; + } + get windows() { + return this._manager.getWindows({ activityId: this._id }); + } + get agm() { + return this._agm; + } + addWindow(window, callback) { + return this._manager.addWindowToActivity(this, window, callback); + } + createWindow(windowType, callback) { + return this._manager.createWindow(this, windowType, callback); + } + createStackedWindows(windowTypes, timeout, callback) { + return this._manager.createStackedWindows(this, windowTypes, timeout, callback); + } + leave(window, callback) { + return this._manager.leaveWindowFromActivity(this, window, callback); + } + getWindowsByType(windowType) { + const filter = { activityId: this._id, type: windowType }; + return this._manager.getWindows(filter); + } + setContext(context, callback) { + return this._manager.setActivityContext(this, context, callback); + } + updateContext(context, callback) { + return this._manager.updateActivityContext(this, context, callback); + } + onStatusChange(handler) { + return this._manager.subscribeActivityEvents((a, ns, os) => { + if (a.id === this.id) { + handler(a, ns, os); + } + }); + } + onWindowEvent(handler) { + return this._manager.subscribeWindowEvents((a, w, e) => { + if (a.id === this.id) { + handler(a, w, e); + } + }); + } + onContextChanged(handler) { + this._manager.subscribeActivityContextChanged((act, context, updated, removed) => { + if (act.id === this.id) { + handler(context, updated, removed, act); + } + }); + try { + handler(this.context, this.context, [], this); + } + catch (e) { + return; + } + } + stop() { + this._manager.stopActivity(this); + } + clone(options) { + return this._manager.clone(this, options); + } + attach(activity, tag) { + let activityId; + if (typeof activity === "string") { + activityId = activity; + } + else { + activityId = activity.id; + } + return this._manager.attachActivities(activityId, this.id, tag); + } + onActivityAttached(callback) { + this._manager.subscribeActivitiesAttached((newActId, oldActId, descriptor) => { + if (newActId !== this._id) { + return; + } + callback(descriptor); + }); + } + onDetached(callback) { + this._manager.subscribeActivitiesDetached((newAct, originalActivity, state) => { + if (originalActivity.id !== this._id) { + return; + } + callback(newAct, state); + }); + } + _updateCore(other) { + super._updateCore(other); + ifNotUndefined(other._actType, (x) => this._actType = x); + ifNotUndefined(other._context, (x) => this._context = x); + ifNotUndefined(other._ownerId, (x) => this._ownerId = x); + if (other._status && (!this._status || (this._status.state !== other._status.state))) { + this._status = other._status; + } + } + _updateDescriptors(allStates) { + this._attached = allStates.map((s) => { + return new AttachedActivityDescriptor(this._manager, this._id, s); + }); + } + get attached() { + return this._attached; + } + setFrameColor(color, callback) { + const promise = new Promise((resolve, reject) => { + let callbacksToWait = this.windows.length; + if (callbacksToWait === 0) { + resolve(this); + } + this.windows.forEach((w) => { + w.underlyingWindow.setFrameColor(color, () => { + callbacksToWait--; + if (callbacksToWait <= 0) { + resolve(this); + } + }); + }); + setTimeout(() => { + if (callbacksToWait > 0) { + reject(this.id + " - timed out waiting for setFrameColor with" + color); + } + }, 5000); + }); + return nodeify(promise, callback); + } + getFrameColor() { + if (!this.windows || this.windows.length === 0) { + return ""; + } + return this.windows[0].underlyingWindow.frameColor; + } + } + + class LogLevel { + } + LogLevel.Trace = "trace"; + LogLevel.Debug = "debug"; + LogLevel.Info = "info"; + LogLevel.Warn = "warn"; + LogLevel.Error = "error"; + class Logger { + static GetNamed(name) { + return new Logger(name); + } + static Get(owner) { + return new Logger(Logger.GetTypeName(owner)); + } + constructor(name) { + this._name = name; + if (!isUndefinedOrNull(Logger.GlueLogger)) { + this._glueLogger = Logger.GlueLogger.subLogger(name); + } + } + trace(message) { + if (!isUndefinedOrNull(this._glueLogger)) { + this._glueLogger.trace(message); + } + else { + if (Logger.Level === LogLevel.Trace) { + console.info(this._getMessage(message, LogLevel.Trace)); + } + } + } + debug(message) { + if (!isUndefinedOrNull(this._glueLogger)) { + this._glueLogger.debug(message); + } + else { + if (Logger.Level === LogLevel.Debug || + Logger.Level === LogLevel.Trace) { + console.info(this._getMessage(message, LogLevel.Debug)); + } + } + } + info(message) { + if (!isUndefinedOrNull(this._glueLogger)) { + this._glueLogger.info(message); + } + else { + if (Logger.Level === LogLevel.Debug || + Logger.Level === LogLevel.Trace || + Logger.Level === LogLevel.Info) { + console.info(this._getMessage(message, LogLevel.Info)); + } + } + } + warn(message) { + if (!isUndefinedOrNull(this._glueLogger)) { + this._glueLogger.warn(message); + } + else { + if (Logger.Level === LogLevel.Debug || + Logger.Level === LogLevel.Trace || + Logger.Level === LogLevel.Info || + Logger.Level === LogLevel.Warn) { + console.info(this._getMessage(message, LogLevel.Info)); + } + } + } + error(message) { + if (!isUndefinedOrNull(this._glueLogger)) { + this._glueLogger.error(message); + } + else { + console.error(this._getMessage(message, LogLevel.Error)); + console.trace(); + } + } + _getMessage(message, level) { + return "[" + level + "] " + this._name + " - " + message; + } + static GetTypeName(object) { + const funcNameRegex = /function (.{1,})\(/; + const results = (funcNameRegex).exec(object.constructor.toString()); + return (results && results.length > 1) ? results[1] : ""; + } + } + Logger.Level = LogLevel.Info; + + class ActivityWindow extends ActivityEntity { + constructor(id, name, type, activityId, instance, isIndependent, windowGetter, hcWindowId) { + super(id); + this._logger = Logger.Get("window"); + this._type = type; + this._activityId = activityId; + this._name = name; + this._instance = instance; + this._isIndependent = isIndependent; + this._windowGetter = windowGetter; + this._hcWindowId = hcWindowId; + } + getBounds() { + return this._manager.getWindowBounds(this.id); + } + get name() { + return this._name; + } + get isIndependent() { + return this._isIndependent; + } + get type() { + if (this._manager) { + return this._manager.getWindowType(this._type); + } + return undefined; + } + get activity() { + if (isUndefined(this._activityId)) { + return undefined; + } + return this._manager.getActivityById(this._activityId); + } + get isOwner() { + const act = this.activity; + if (isUndefined(act)) { + return false; + } + return act.owner.id === this.id; + } + setVisible(isVisible, callback) { + return this._manager.setWindowVisibility(this.id, isVisible); + } + activate(focus) { + return this._manager.activateWindow(this.id, focus); + } + setBounds(bounds, callback) { + return this._manager.setWindowBounds(this.id, bounds, callback); + } + close() { + return this._manager.closeWindow(this.id); + } + get instance() { + return this._instance; + } + get underlyingWindow() { + const window = this._windowGetter(); + if (!window) { + return { + id: this._hcWindowId + }; + } + return window; + } + onActivityJoined(callback) { + this._subscribeForActivityWindowEvent(EntityEventType.ActivityWindowJoinedActivity, callback); + } + onActivityRemoved(callback) { + this._subscribeForActivityWindowEvent(EntityEventType.ActivityWindowLeftActivity, callback); + } + _updateCore(other) { + ifNotUndefined(other._activityId, (x) => this._activityId = x); + ifNotUndefined(other._isIndependent, (x) => this._isIndependent = x); + ifNotUndefined(other._hcWindowId, (x) => this._hcWindowId = x); + ifNotUndefined(other._type, (x) => this._type = x); + ifNotUndefined(other._name, (x) => this._name = x); + if (!isUndefinedOrNull(other._instance)) { + this._instance = other._instance; + } + } + _subscribeForActivityWindowEvent(eventName, callback) { + this._manager.subscribeWindowEvents((activity, window, event) => { + if (window.id !== this.id) { + return; + } + if (event === eventName) { + callback(activity); + } + }); + } + _beforeDelete(other) { + this._hcWindowId = other._hcWindowId; + } + } + + class ActivityStatus { + constructor(state, message, time) { + this.state = state; + this.message = message; + this.time = time; + } + getState() { + return this.state; + } + getMessage() { + return this.message; + } + getTime() { + return this.time; + } + } + + const gwMmessageError = "error"; + const gwMessageAddActivityTypes = "add-types"; + const gwMmessageActivityTypesAdded = "types-added"; + const gwMessageRemoveActivityTypes = "remove-types"; + const gwMessageActivityTypesRemoved = "types-removed"; + const gwMessageActivityCreated = "created"; + const gwMessageActivityDestroyed = "destroyed"; + const gwMessageActivityInitiated = "initiated"; + const gwMmessageJoinActivity = "join-activity"; + const gwMessageJoinedActivity = "joined"; + const gwMessageActivityJoined = "activity-joined"; + const gwMessageLeaveActivity = "leave-activity"; + const gwMessageActivityLeft = "left"; + const gwNmessageMergeActivities = "merge"; + const gwMessageSplitActivities = "split"; + const gwMessageOwnerChanged = "owner-changed"; + const gwMessageAddPeerFactories = "add-peer-factories"; + const gwMessagePeerFactoriesAdded = "peer-factories-added"; + const gwMessageRemovePeerFactories = "remove-peer-factories"; + const gwMessagePeerFactoriesRemoved = "peer-factories-removed"; + const gwMessageCreateActivity = "create"; + const gwMessageCreatePeer = "create-peer"; + const gwMessagePeerRequested = "peer-requested"; + const gwMessageReady = "ready"; + const gwMessagePeerCreated = "peer-created"; + const gwMessageDestroyActivity = "destroy"; + const gwMessageDisposePeer = "dispose-peer"; + const gwMessageDestroyPeer = "destroy-peer"; + class GW3Bridge { + static activityTypeGwMessageEntityToActivityType(entity, description) { + const nameToWindowType = (windowName) => new WindowType(windowName, undefined); + return new ActivityType(entity.name, entity.owner_type && nameToWindowType(entity.owner_type), entity.helper_types && entity.helper_types.map(nameToWindowType), description); + } + static peerFactoryGwMessageEntityToWindowType(entity) { + return new WindowType(entity.peer_type, (_) => undefined); + } + static activityGwMessageToActivity(msg, status) { + const ownerId = msg.owner !== undefined ? msg.owner.peer_id : msg.owner_id; + return new Activity(msg.activity_id, msg.activity_type, status, msg.context_snapshot, ownerId); + } + static activityToActivityStatusChangeEvent(act) { + return new EntityEvent(act, new ActivityStatusChangeEventContext(act.status, undefined)); + } + constructor(config) { + this._activityChangeCallbacks = []; + this._activityTypeStatusChangeCallbacks = []; + this._activityWindowChangeCallbacks = []; + this._windowTypeStatusChangeCallbacks = []; + this._peerIdAndFactoryIdToPeerType = {}; + this._peerFactoriesRegisteredByUs = {}; + this._gw3Subscriptions = []; + this._contextSubscriptions = {}; + this._activityTypesInitiatedFromMe = {}; + this._config = config; + this._connection = config.connection; + this._logger = config.logger; + this._contexts = config.contexts; + this._windows = config.windows; + this._sessionJoinedPromise = new Promise((resolve) => { + this._sessionJoinedPromiseResolve = resolve; + }); + this._activityJoinedPromise = new Promise((resolve) => { + this._activityJoinedPromiseResolve = resolve; + }); + if (!this._config.activityId) { + this._activityJoinedPromiseResolve({}); + } + this._gw3Session = this._connection.domain("activity", ["joined", "initiated", "peer-created", "token"]); + if (typeof window !== "undefined") { + const glue42gd = (window).glue42gd; + if (glue42gd && glue42gd.activityInfo) { + if (typeof glue42gd.addRefreshHandler === "function") { + glue42gd.addRefreshHandler((success, error) => { + this._gw3Session + .send({ + type: "reload" + }) + .then((msg) => { + if (!msg.token) { + error("Expected gateway token for refreshing."); + return; + } + try { + glue42gd.setGWToken(msg.token); + } + catch (e) { + error(e.message || e); + return; + } + success(); + }, error); + }); + } + if (glue42gd && typeof glue42gd.addWillNavigateHandler === "function") { + glue42gd.addWillNavigateHandler((success, error) => { + this._gw3Session + .send({ + type: "reload" + }) + .then((msg) => { + if (!msg.token) { + error("Expected gateway token for refreshing."); + return; + } + try { + glue42gd.setGWToken(msg.token); + } + catch (e) { + error(e.message || e); + return; + } + success(); + }, error); + }); + } + } + } + } + get bridgeType() { + return "GW3"; + } + init() { + this.forwardActivityTypeMessagesToStatusEventHandlers(); + this.subscribe(gwMessageActivityCreated, this.handleActivityCreatedMessage); + this.subscribe(gwMessageActivityDestroyed, this.handleActivityDestroyedMessage); + this.forwardActivityMessagesToStatusEventHandlers(); + this.forwardActivityCreatedAndJoinedActivityToActivityWindowEventHandlers(); + this.forwardPeerFactoryMessagesToStatusEventHandlers(); + this.forwardPeerFactoryMessagesToPeerFactoryRequests(); + this.subscribe(gwMessagePeerFactoriesAdded, this.handlePeerFactoriesAdded); + this.subscribe(gwMessagePeerFactoriesRemoved, this.handlePeerFactoriesRemoved); + this.forwardActivityWindowMessagesToEventHandlers(); + this.subscribe(gwMessageDisposePeer, () => { + if (this._config.disposeRequestHandling === "dispose") { + this.dispose(); + return; + } + if (this._config.disposeRequestHandling === "exit") { + if (this._windows && typeof this._windows.my() !== "undefined") { + this._windows.my().close(); + return; + } + if (typeof window !== "undefined" && typeof (window).close === "function") { + window.close(); + return; + } + if (typeof process !== "undefined" && typeof (process).exit === "function") { + process.exit(); + return; + } + } + }); + this._gw3Session.onJoined(() => { + if (this._config.mode === "trackMyOnly" || + this._config.mode === "trackMyTypeAndInitiatedFromMe") { + this._sessionJoinedPromiseResolve(this); + } + else { + this._gw3Session + .send({ + type: "subscribe", + activity_types: (this._config.mode === "trackAll" ? [] : + this._config.mode === "trackTypes" ? this._config.typesToTrack : []) + }) + .then(() => { + this._sessionJoinedPromiseResolve(this); + }); + } + }); + this._gw3Session.join(); + } + dispose() { + this._gw3Subscriptions.forEach((sub) => sub && this._connection.off(sub)); + this._gw3Subscriptions.length = 0; + } + ready() { + return Promise.all([this._sessionJoinedPromise, this._activityJoinedPromise]); + } + initReady() { + return this._sessionJoinedPromise; + } + onActivityTypeStatusChange(callback) { + this._activityTypeStatusChangeCallbacks.push(callback); + } + registerActivityType(activityTypeName, ownerWindow, helperWindows, config, description) { + const entity = {}; + entity.name = activityTypeName; + const toActivityPeerConfig = (windowDefinition) => ({ type: windowDefinition.type, name: windowDefinition.name, configuration: windowDefinition }); + entity.owner_type = toActivityPeerConfig(ownerWindow); + entity.helper_types = helperWindows.map(toActivityPeerConfig); + return this._gw3Session + .send({ + type: gwMessageAddActivityTypes, + types: [entity] + }) + .then(() => { + const activityType = GW3Bridge.activityTypeGwMessageEntityToActivityType(entity, description); + this.invokeCallbacks(this._activityTypeStatusChangeCallbacks, new EntityEvent(activityType, new EntityEventContext(EntityEventType.Added)), gwMessageAddActivityTypes); + return activityType; + }); + } + unregisterActivityType(activityTypeName) { + return this._gw3Session + .send({ + type: gwMessageRemoveActivityTypes, + types: [activityTypeName] + }) + .then(() => { + const activityType = new ActivityType(activityTypeName, undefined, undefined, undefined); + this.invokeCallbacks(this._activityTypeStatusChangeCallbacks, new EntityEvent(activityType, new EntityEventContext(EntityEventType.Removed)), gwMessageAddActivityTypes); + }); + } + onWindowTypeStatusChange(callback) { + this._windowTypeStatusChangeCallbacks.push(callback); + } + registerWindowFactory(windowType, factory, parameters) { + if (this._peerFactoriesRegisteredByUs[windowType]) { + return Promise.reject(new Error(`Factory for windowType ${windowType} already registered.`)); + } + this._peerFactoriesRegisteredByUs[windowType] = factory; + const entity = { + id: windowType, + peer_type: windowType, + configuration: parameters + }; + return this._gw3Session.send({ + type: gwMessageAddPeerFactories, + factories: [entity] + }) + .then(() => { + this.invokeCallbacks(this._windowTypeStatusChangeCallbacks, new EntityEvent(GW3Bridge.peerFactoryGwMessageEntityToWindowType(entity), new EntityEventContext(EntityEventType.Added)), gwMessageAddPeerFactories); + }) + .catch(() => { + delete this._peerFactoriesRegisteredByUs[windowType]; + }); + } + unregisterWindowFactory(windowType) { + const factory = this._peerFactoriesRegisteredByUs[windowType]; + if (!factory) { + return Promise.reject(new Error(`Factory for windowType ${windowType} not registered.`)); + } + delete this._peerFactoriesRegisteredByUs[windowType]; + return this._gw3Session.send({ + type: gwMessageRemovePeerFactories, + factory_ids: [windowType] + }).then(() => { + this.invokeCallbacks(this._windowTypeStatusChangeCallbacks, new EntityEvent(new WindowType(windowType, undefined), new EntityEventContext(EntityEventType.Removed)), gwMessageAddPeerFactories); + }); + } + onActivityStatusChange(callback) { + this._activityChangeCallbacks.push(callback); + } + initiateActivity(activityType, context, configuration) { + const initiateMsg = { + type: gwMessageCreateActivity, + activity_type: activityType, + initial_context: context, + }; + if (this.isOverrideTypeDefinition(configuration)) { + initiateMsg.types_override = { + owner_type: { type: configuration.owner.type, name: configuration.owner.name, configuration: configuration.owner }, + helper_types: configuration.helpers && configuration.helpers.map((wd) => ({ type: wd.type, name: wd.name, configuration: wd })) + }; + } + else { + initiateMsg.configuration = configuration && configuration.map((wd) => ({ type: wd.type, name: wd.name, configuration: wd })); + } + return this.sendCreateAndMapResultingMessagesToPromise(initiateMsg, gwMessageActivityInitiated, (msg, requestId) => msg.request_id === requestId, gwMessageActivityCreated, (msg, requestId, initMsg) => msg.activity_id === initMsg.activity_id, gwMessageActivityDestroyed, (msg, requestId, initMsg) => msg.activity_id === initMsg.activity_id, (msg) => msg.activity_id, null).then((id) => { + if (this._config.mode === "trackMyTypeAndInitiatedFromMe") { + if (!this._activityTypesInitiatedFromMe[activityType]) { + this._activityTypesInitiatedFromMe[activityType] = true; + return this._gw3Session + .send({ + type: "subscribe", + activity_types: [activityType] + }) + .then(() => { + return id; + }); + } + } + return id; + }); + } + stopActivity(activity) { + return this._gw3Session.send({ + type: gwMessageDestroyActivity, + activity_id: activity.id, + reason_uri: "com.tick42.glue.activity.constants.destroyReason.general", + reason: "Destroying activity" + }).then((_) => true); + } + updateActivityContext(activity, context, fullReplace, removedKeys) { + if (fullReplace) { + return this._contexts.set(activity.id, context); + } + else { + removedKeys = removedKeys || []; + for (const x of removedKeys) { + context[x] = null; + } + return this._contexts.update(activity.id, context); + } + } + announceWindow(windowType, activityWindowId) { + throw new Error("Invalid operation 'announceWindow' for GW3 protocol"); + } + registerWindow(type, name, independent) { + let shouldSendReady = typeof this._connection.gatewayToken !== "undefined"; + const peerId = this._connection.peerId; + if (typeof window !== "undefined") { + const glue42gd = window.glue42gd; + if (glue42gd) { + shouldSendReady = typeof glue42gd.activityInfo !== "undefined"; + } + } + if (shouldSendReady) { + this._gw3Session.send({ + type: gwMessageReady, + }); + } + this.invokeCallbacks(this._activityWindowChangeCallbacks, new EntityEvent(new ActivityWindow(peerId, name, type, undefined, this.getAgmInstance(peerId), independent, this.generateWindowGetter(peerId), undefined), new EntityEventContext(EntityEventType.Added)), "register window"); + return Promise.resolve(peerId); + } + onActivityWindowChange(callback) { + this._activityWindowChangeCallbacks.push(callback); + } + createWindow(activityId, windowDefinition) { + if (!windowDefinition.layout) { + if (windowDefinition.left || windowDefinition.width || windowDefinition.height || windowDefinition.top) { + windowDefinition.layout = { + mode: "pixels", + cellSize: 1, + }; + } + } + const joinPeer = (id) => { + if (!activityId) { + return; + } + return this.joinActivity(activityId, id, windowDefinition.name) + .then(() => { + return id; + }); + }; + return this.sendCreateAndMapResultingMessagesToPromise({ + type: gwMessageCreatePeer, + peer_type: windowDefinition.type, + peer_name: windowDefinition.name || windowDefinition.type, + configuration: windowDefinition, + activity_id: activityId, + }, undefined, undefined, gwMessagePeerCreated, (msg, requestId) => msg.request_id === requestId, undefined, undefined, (msg) => msg.created_id, joinPeer) + .then(joinPeer); + } + async closeWindow(id) { + await this._gw3Session.send({ + type: gwMessageDestroyPeer, + destroy_peer_id: id + }); + } + getAnnouncementInfo() { + let activityId = this._config.activityId || (this._config.announcementInfo && this._config.announcementInfo.activityId); + let activityWindowType = (this._config.announcementInfo && this._config.announcementInfo.activityWindowType); + let activityWindowIndependent = (this._config.announcementInfo && this._config.announcementInfo.activityWindowIndependent); + let activityWindowName = (this._config.announcementInfo && this._config.announcementInfo.activityWindowName); + if (typeof window !== "undefined" && + typeof window.location !== "undefined" && + window.location.search && + typeof URLSearchParams === "function") { + const searchParams = new URLSearchParams(location.search.slice(1)); + activityWindowType = activityWindowType || searchParams.get("t42PeerType"); + activityWindowType = activityWindowType || searchParams.get("t42ActivityWindowType"); + if (typeof activityWindowIndependent === "undefined") { + activityWindowIndependent = searchParams.get("t42ActivityWindowIndependent"); + } + activityWindowName = activityWindowName || searchParams.get("t42ActivityWindowName"); + activityId = activityId || searchParams.get("t42ActivityId"); + } + activityWindowType = activityWindowType || "unknown"; + activityWindowIndependent = activityWindowIndependent || false; + activityWindowName = activityWindowName || this._connection.peerId; + return { + activityWindowId: undefined, + activityId, + activityWindowType, + activityWindowIndependent, + activityWindowName, + }; + } + joinActivity(activityId, windowId, name) { + const maybeName = (name && { name }) || {}; + return this._gw3Session.send({ + type: gwMmessageJoinActivity, + target_id: windowId, + activity_id: activityId, + ...maybeName + }).then(() => { + this.invokeCallbacks(this._activityWindowChangeCallbacks, new EntityEvent(new ActivityWindow(windowId, undefined, undefined, activityId, this.getAgmInstance(windowId), undefined, this.generateWindowGetter(windowId), undefined), new EntityEventContext(EntityEventType.ActivityWindowJoinedActivity)), "activity joined - ActivityWindow"); + this.invokeCallbacks(this._activityChangeCallbacks, new EntityEvent(new Activity(activityId, undefined, new ActivityStatus("created", undefined, undefined), undefined, undefined), new EntityEventContext(EntityEventType.Updated)), "activity joined - Activity"); + }); + } + leaveActivity(activityId, windowId) { + return this._gw3Session.send({ + type: gwMessageLeaveActivity, + target_id: windowId, + activity_id: activityId + }).then(() => { + this.invokeCallbacks(this._activityWindowChangeCallbacks, new EntityEvent(new ActivityWindow(windowId, undefined, undefined, null, this.getAgmInstance(windowId), undefined, this.generateWindowGetter(windowId), undefined), new EntityEventContext(EntityEventType.ActivityWindowLeftActivity)), "activity left - ActivityWindow"); + this.invokeCallbacks(this._activityChangeCallbacks, new EntityEvent(new Activity(activityId, undefined, new ActivityStatus("created", undefined, undefined), undefined, undefined), new EntityEventContext(EntityEventType.Updated)), "activity left - Activity"); + }); + } + getActivityTypes() { + return Promise.resolve([]); + } + getWindowTypes() { + return Promise.resolve([]); + } + getActivities() { + return Promise.resolve([]); + } + getActivityWindows() { + return Promise.resolve([]); + } + createStackedWindows(id, windowDefinitions, timeout) { + return undefined; + } + getWindowBounds(id) { + return undefined; + } + setWindowBounds(id, bounds) { + return undefined; + } + activateWindow(id, focus) { + return undefined; + } + setWindowVisibility(id, visible) { + return undefined; + } + cloneActivity(id, cloneOptions) { + return undefined; + } + attachActivities(from, to, tag) { + return this._gw3Session.send({ + type: gwNmessageMergeActivities, + into: to, + merge: from + }); + } + detachActivities(activityId, newActivityInfo) { + return this._gw3Session.send({ + type: gwMessageSplitActivities, + from: activityId, + }).then(() => ""); + } + onActivitiesAttached(callback) { + } + onActivitiesDetached(callback) { + } + onActivityAttachedDescriptorsRefreshed(callback) { + } + getAttachedDescriptors() { + return Promise.resolve([]); + } + getRandomRequestId() { + return this._connection.peerId + ":" + Math.floor(Math.random() * 1e9) + ""; + } + forwardAddedAndRemovedMessagesToEventHandler(addedMessageType, removedMessageType, mapper, handlers) { + const getGetEntityEvent = (isAdded) => (entity) => new EntityEvent(entity, new EntityEventContext(isAdded ? + EntityEventType.Added : + EntityEventType.Removed)); + const sub1 = addedMessageType && this.forwardMessageToEventHandler(addedMessageType, (msg) => mapper(msg, true), getGetEntityEvent(true), handlers); + const sub2 = removedMessageType && this.forwardMessageToEventHandler(removedMessageType, (msg) => mapper(msg, false), getGetEntityEvent(false), handlers); + return [sub1, sub2].filter((x) => x); + } + forwardMessageToEventHandler(messageType, mapper, getEntityEvent, handler) { + return this.subscribe(messageType, (msg) => { + mapper(msg) + .forEach((ent) => handler.forEach((h) => h(getEntityEvent(ent, msg)))); + }); + } + sendCreateAndMapResultingMessagesToPromise(msg, initiatedMessageType, initiatedMessageFilter, createdMessageType, createdMessageFilter, cancelledMessageType, cancelledMessageFilter, createdMessageToPromiseResolution, listenForRecreates) { + const reqId = this.getRandomRequestId(); + let resolveCreatedPromise; + let rejectCreatedPromise; + const createdPromise = new Promise((resolve, reject) => { + resolveCreatedPromise = resolve; + rejectCreatedPromise = reject; + }); + let initiatedMessageAck = null; + let initiatedSubscription; + let createdSubscription; + let cancelledSubscription; + let errorSubscription; + const dropSubscriptions = () => { + this.dropSubscription(initiatedSubscription); + if (!listenForRecreates) { + this.dropSubscription(createdSubscription); + } + this.dropSubscription(cancelledSubscription); + this.dropSubscription(errorSubscription); + }; + initiatedSubscription = initiatedMessageType && + this.subscribe(initiatedMessageType, (msg4) => { + if (!initiatedMessageFilter(msg4, reqId)) { + return; + } + initiatedMessageAck = msg4; + this.dropSubscription(initiatedSubscription); + }); + let recreated = false; + createdSubscription = + this.subscribe(createdMessageType, (msg1) => { + if (!createdMessageFilter(msg1, reqId, initiatedMessageAck)) { + return; + } + if (recreated) { + if (listenForRecreates) { + listenForRecreates(createdMessageToPromiseResolution(msg1)); + } + } + else { + recreated = true; + resolveCreatedPromise(createdMessageToPromiseResolution(msg1)); + } + }); + cancelledSubscription = cancelledMessageType && + this.subscribe(cancelledMessageType, (msg2) => { + if (!cancelledMessageFilter(msg2, reqId, initiatedMessageAck)) { + return; + } + rejectCreatedPromise(msg2); + }); + errorSubscription = cancelledMessageType && + this.subscribe(gwMmessageError, (msg3) => { + if (msg3.request_id !== reqId) { + return; + } + rejectCreatedPromise(msg3); + }); + msg.request_id = reqId; + const toReturn = this._gw3Session + .send(msg) + .then(() => { + return createdPromise; + }); + toReturn.then(dropSubscriptions, dropSubscriptions); + return toReturn; + } + peerFactoryIdAndOwnerIdToWindowType(factoryId, ownerId) { + const peerType = this._peerIdAndFactoryIdToPeerType[ownerId + ":" + factoryId]; + if (!peerType) { + return null; + } + else { + return new WindowType(peerType, undefined); + } + } + subscribe(messageType, handler) { + const sub = this._connection.on(messageType, (msg) => handler.bind(this)(msg)); + this._gw3Subscriptions.push(sub); + return sub; + } + dropSubscription(subscription) { + if (subscription) { + this._connection.off(subscription); + delete this._gw3Subscriptions[this._gw3Subscriptions.indexOf(subscription)]; + } + } + invokeCallbacks(callbacks, event, description) { + callbacks.forEach((cb) => { + try { + cb(event); + } + catch (err) { + this._logger.error(`Error in ${description || event.context.type} callback: ` + JSON.stringify(err)); + } + }); + } + handleActivityCreatedMessage(msg) { + if (!msg.context_id) { + this._logger.error("Activity created with unknown context_id: " + msg.activity_id); + } + else { + if (!this._contextSubscriptions[msg.activity_id]) { + this.subscribeToContext(msg); + } + } + } + async subscribeToContext(msg) { + const activityId = msg.activity_id; + this._contextSubscriptions[activityId] = + await this._contexts.subscribe(activityId, (data, updated, removed) => { + const event = new EntityEvent(new Activity(activityId, undefined, undefined, data, undefined), new ActivityContextChangedEventContext(data, updated, removed)); + this.invokeCallbacks(this._activityChangeCallbacks, event, "context updated"); + }); + } + handleActivityDestroyedMessage(msg) { + const unsubscribeContext = this._contextSubscriptions[msg.activity_id]; + if (typeof unsubscribeContext === "function") { + unsubscribeContext(); + } + delete this._contextSubscriptions[msg.activity_id]; + } + handlePeerFactoriesAdded(msg) { + msg.factories.forEach((entity) => { + this._peerIdAndFactoryIdToPeerType[msg.owner_id + ":" + entity.id] = entity.peer_type; + }); + } + handlePeerFactoriesRemoved(msg) { + msg.factory_ids.forEach((factoryId) => { + delete this._peerIdAndFactoryIdToPeerType[msg.owner_id + ":" + factoryId]; + }); + } + forwardActivityTypeMessagesToStatusEventHandlers() { + this.forwardAddedAndRemovedMessagesToEventHandler(gwMmessageActivityTypesAdded, gwMessageActivityTypesRemoved, (msg, isAdded) => isAdded + ? msg.types.map((t) => GW3Bridge.activityTypeGwMessageEntityToActivityType(t, undefined)) + : msg.types.map((t) => new ActivityType(t.name, undefined, undefined, undefined)), this._activityTypeStatusChangeCallbacks); + } + forwardActivityCreatedAndJoinedActivityToActivityWindowEventHandlers() { + for (const activityCreatedMessage of [gwMessageActivityCreated, gwMessageJoinedActivity, gwMessageOwnerChanged]) { + this.forwardMessageToEventHandler(activityCreatedMessage, (msg) => ([msg.owner || { ...msg, type: msg.peer_type, name: msg.peer_name, peer_id: msg.owner_id }]) + .concat(msg.participants || []) + .map((info) => new ActivityWindow(info.peer_id, info.name, info.type, msg.activity_id, this.getAgmInstance(info.peer_id), undefined, this.generateWindowGetter(info.peer_id), undefined)), (ent, msg) => new EntityEvent(ent, new EntityEventContext(EntityEventType.ActivityWindowJoinedActivity)), this._activityWindowChangeCallbacks); + } + } + forwardActivityMessagesToStatusEventHandlers() { + for (const createdMessage of [gwMessageActivityCreated, gwMessageJoinedActivity]) { + this.forwardMessageToEventHandler(createdMessage, (msg) => [GW3Bridge.activityGwMessageToActivity(msg, new ActivityStatus("started", "", new Date()))], (ent, msg) => GW3Bridge.activityToActivityStatusChangeEvent(ent), this._activityChangeCallbacks); + } + this.forwardMessageToEventHandler(gwMessageActivityDestroyed, (msg) => [GW3Bridge.activityGwMessageToActivity(msg, new ActivityStatus("destroyed", msg.reason, new Date()))], (ent, msg) => GW3Bridge.activityToActivityStatusChangeEvent(ent), this._activityChangeCallbacks); + this.forwardMessageToEventHandler(gwMessageActivityInitiated, (msg) => [GW3Bridge.activityGwMessageToActivity(msg, new ActivityStatus("created", "", new Date()))], (ent, msg) => GW3Bridge.activityToActivityStatusChangeEvent(ent), this._activityChangeCallbacks); + this.forwardMessageToEventHandler(gwMessageOwnerChanged, (msg) => [GW3Bridge.activityGwMessageToActivity(msg, new ActivityStatus("created", "", new Date()))], (ent, msg) => GW3Bridge.activityToActivityStatusChangeEvent(ent), this._activityChangeCallbacks); + } + forwardPeerFactoryMessagesToStatusEventHandlers() { + this.forwardAddedAndRemovedMessagesToEventHandler(gwMessagePeerFactoriesAdded, gwMessagePeerFactoriesRemoved, (msg, isAdded) => isAdded + ? msg.factories.map(GW3Bridge.peerFactoryGwMessageEntityToWindowType) + : msg.factory_ids.map((id) => this.peerFactoryIdAndOwnerIdToWindowType(id, msg.owner_id)).filter((x) => x != null), this._windowTypeStatusChangeCallbacks); + } + forwardPeerFactoryMessagesToPeerFactoryRequests() { + this.subscribe(gwMessagePeerRequested, (msg) => { + const factory = this._peerFactoriesRegisteredByUs[msg.peer_factory]; + if (!factory) { + this._gw3Session.send({ + type: gwMmessageError, + request_id: msg.request_id, + reason: `Unknown peer factory ${msg.peer_factory}` + }); + return; + } + try { + const configuration = msg.configuration || {}; + configuration.gateway_token = configuration.gateway_token || msg.gateway_token; + configuration.peer_factory = configuration.peer_factory || msg.peer_factory; + const promise = factory({ + activityId: msg.activity && msg.activity.id, + activityType: msg.activity && msg.activity.type, + type: msg.configuration && msg.configuration.type, + gwToken: configuration.gateway_token, + configuration + }); + if (promise && promise.then && promise.catch) { + promise.catch((err) => this._gw3Session.send({ + type: gwMmessageError, + request_id: msg.request_id, + reason: err && (err.message || JSON.stringify(err)) + })); + } + } + catch (err) { + this._gw3Session.send({ + type: gwMmessageError, + request_id: msg.request_id, + reason: err && (err.message || JSON.stringify(err)) + }); + } + }); + } + forwardActivityWindowMessagesToEventHandlers() { + for (const joinedMessage of [gwMessageActivityJoined, gwMessageJoinedActivity]) { + this.subscribe(joinedMessage, (msg) => { + const joinedId = (joinedMessage === gwMessageActivityJoined) ? msg.joined_id : msg.peer_id; + const joinedType = (joinedMessage === gwMessageActivityJoined) ? msg.joined_type : msg.peer_type; + const joinedName = (joinedMessage === gwMessageActivityJoined) ? msg.joined_name : msg.peer_name; + const entity = new ActivityWindow(joinedId, joinedName, joinedType, msg.activity_id, this.getAgmInstance(joinedId), undefined, this.generateWindowGetter(joinedId), undefined); + if (!this._contextSubscriptions[msg.activity_id]) { + this.subscribeToContext(msg).then(() => { + if (joinedMessage === gwMessageJoinedActivity) { + this._activityJoinedPromiseResolve({}); + } + }); + } + else if (joinedMessage === gwMessageJoinedActivity) { + this._activityJoinedPromiseResolve({}); + } + this.invokeCallbacks(this._activityWindowChangeCallbacks, new EntityEvent(entity, new EntityEventContext(EntityEventType.ActivityWindowJoinedActivity)), joinedMessage); + }); + } + this.subscribe(gwMessageActivityLeft, (msg) => { + const entity = new ActivityWindow(msg.left_id, undefined, undefined, null, this.getAgmInstance(msg.left_id), undefined, this.generateWindowGetter(msg.left_id), undefined); + this.invokeCallbacks(this._activityWindowChangeCallbacks, new EntityEvent(entity, new EntityEventContext(EntityEventType.ActivityWindowLeftActivity)), gwMessageActivityLeft); + }); + this.forwardAddedAndRemovedMessagesToEventHandler(gwMessagePeerCreated, undefined, (msg) => [ + new ActivityWindow(msg.created_id, undefined, undefined, undefined, undefined, undefined, this.generateWindowGetter(msg.created_id), undefined) + ], this._activityWindowChangeCallbacks); + } + getAgmInstance(id) { + return this._config.agm.servers().find((s) => s.peerId === id || s.windowId === id); + } + generateWindowGetter(peerId) { + return () => { + const server = this.getAgmInstance(peerId); + if (!server) { + return; + } + const windowId = server.windowId; + return this._config.windows.list().filter((w) => w.id === windowId)[0]; + }; + } + isOverrideTypeDefinition(value) { + if (typeof value === "undefined") { + return false; + } + if (value.owner) { + return true; + } + return false; + } + } + + class ActivityMy { + constructor(manager, windows) { + this._myAttached = []; + this._myDetached = []; + this._myAttachedTo = []; + this._myDetachedFrom = []; + this._myActivityFrameColorChanged = []; + this._myActivityJoinedCallbacks = []; + this._myActivityRemovedCallbacks = []; + this._myContextUpdateCallbacks = []; + this._logger = Logger.Get(this); + this._m = manager; + manager.ready() + .then((am) => { + am.subscribeActivityContextChanged(this._subscribeMyContextChanged.bind(this)); + am.subscribeWindowEvents(this._subscribeMyWindowEvent.bind(this)); + am.subscribeActivitiesAttached(this._subscribeActivitiesAttached.bind(this)); + am.subscribeActivitiesDetached(this._subscribeActivitiesDetached.bind(this)); + if (windows) { + windows.onWindowFrameColorChanged(this._subscribeWindowFrameColorChanged.bind(this)); + } + }); + } + get window() { + if (isUndefinedOrNull(this._w)) { + const announcedWindows = this._m.announcedWindows; + if (announcedWindows.length > 0) { + this._w = announcedWindows[0]; + } + } + return this._w; + } + get activity() { + const myWin = this.window; + if (isUndefinedOrNull(myWin)) { + return undefined; + } + return myWin.activity; + } + createWindow(windowType) { + return this._m.createWindow(this.activity, windowType); + } + createStackedWindows(windowTypes, timeout) { + return this._m.createStackedWindows(this.activity, windowTypes, timeout); + } + get context() { + const activity = this.activity; + if (isUndefined(activity)) { + return {}; + } + return activity.context; + } + updateContext(context, callback) { + const activity = this.activity; + if (isUndefined(activity)) { + return new Promise((resolve, reject) => { + reject("Not in activity"); + }); + } + return activity.updateContext(context, callback); + } + setContext(context, callback) { + const activity = this.activity; + if (isUndefined(activity)) { + return new Promise((resolve, reject) => { + reject("Not in activity"); + }); + } + return activity.setContext(context, callback); + } + onActivityJoined(callback) { + this._myActivityJoinedCallbacks.push(callback); + const myWin = this.window; + if (!isUndefinedOrNull(myWin) && !isUndefinedOrNull(myWin.activity)) { + callback(myWin.activity); + } + } + onActivityLeft(callback) { + this._myActivityRemovedCallbacks.push(callback); + } + onContextChanged(callback) { + this._myContextUpdateCallbacks.push(callback); + const myWin = this.window; + if (isUndefinedOrNull(myWin)) { + return; + } + const activity = myWin.activity; + if (isUndefinedOrNull(activity)) { + return; + } + callback(activity.context, activity.context, [], activity); + } + clone(options, callback) { + const act = this.activity; + return this._m.clone(act, options, callback); + } + attach(activity, tag) { + let activityId; + if (typeof activity === "string") { + activityId = activity; + } + else { + activityId = activity.id; + } + return this._m.attachActivities(activityId, this.activity.id, tag); + } + onActivityAttached(callback) { + this._myAttached.push(callback); + } + onActivityDetached(callback) { + this._myDetached.push(callback); + } + onAttachedToActivity(callback) { + this._myAttachedTo.push(callback); + } + onDetachedFromActivity(callback) { + this._myDetachedFrom.push(callback); + } + get attached() { + if (!this.activity) { + return []; + } + return this.activity.attached; + } + setFrameColor(color, callback) { + if (this.activity) { + return this.activity.setFrameColor(color, callback); + } + else { + return Promise.resolve(null); + } + } + getFrameColor() { + if (this.activity) { + return this.activity.getFrameColor(); + } + return ""; + } + onFrameColorChanged(callback) { + this._myActivityFrameColorChanged.push(callback); + } + _subscribeMyContextChanged(activity, context, delta, removed) { + const myWin = this.window; + if (isUndefinedOrNull(myWin)) { + return; + } + const myActivity = myWin.activity; + if (isUndefinedOrNull(myActivity)) { + return; + } + if (activity.id !== myActivity.id) { + return; + } + this._notifyMyContextChanged(activity, context, delta, removed); + } + _subscribeMyWindowEvent(activity, window, event) { + if (isUndefinedOrNull(this.window)) { + return; + } + if (this.window.id !== window.id) { + return; + } + if (event === EntityEventType.ActivityWindowJoinedActivity) { + this._notifyMyWindowEvent(activity, this._myActivityJoinedCallbacks); + this._notifyMyContextChanged(activity, activity.context, null, null); + } + else if (event === EntityEventType.ActivityWindowLeftActivity) { + this._notifyMyWindowEvent(activity, this._myActivityRemovedCallbacks); + } + } + _notifyMyWindowEvent(activity, callbackStore) { + callbackStore.forEach((element) => { + try { + element(activity, event); + } + catch (e) { + this._logger.warn("error in user callback " + e); + } + }); + } + _notifyMyContextChanged(activity, context, delta, removed) { + delta = delta || {}; + removed = removed || []; + this._myContextUpdateCallbacks.forEach((element) => { + try { + element(context, delta, removed, activity); + } + catch (e) { + this._logger.warn("error in user callback " + e); + } + }); + } + _notifyAttached(state) { + this._myAttached.forEach((cb) => { + try { + cb(state); + } + catch (e) { + this._logger.warn("error in user callback " + e); + } + }); + } + _notifyDetached(state) { + this._myDetached.forEach((cb) => { + try { + cb(state); + } + catch (e) { + this._logger.warn("error in user callback " + e); + } + }); + } + _notifyAttachedTo(state) { + this._myAttachedTo.forEach((cb) => { + try { + cb(this.activity, state); + } + catch (e) { + this._logger.warn("error in user callback " + e); + } + }); + } + _notifyDetachedFrom(detached, existing, state) { + this._myDetachedFrom.forEach((cb) => { + try { + cb(detached, existing, state); + } + catch (e) { + this._logger.warn("error in user callback " + e); + } + }); + } + _subscribeActivitiesAttached(newAct, state) { + const myWin = this.window; + if (isUndefinedOrNull(myWin)) { + return; + } + const myActivity = myWin.activity; + if (isUndefinedOrNull(myActivity)) { + return; + } + if (newAct.id !== myActivity.id) { + return; + } + if (state.windowIds.indexOf(myWin.id) >= 0) { + this._notifyAttachedTo(state); + return; + } + this._notifyAttached(state); + } + _subscribeActivitiesDetached(newAct, oldAct, state) { + const myWin = this.window; + if (isUndefinedOrNull(myWin)) { + return; + } + const myActivity = myWin.activity; + if (isUndefinedOrNull(myActivity)) { + return; + } + if (oldAct.id === myActivity.id) { + this._notifyDetached(state); + } + if (newAct.id === myActivity.id) { + this._notifyDetachedFrom(newAct, oldAct, state); + } + } + _subscribeWindowFrameColorChanged(window) { + const act = this.activity; + if (!act) { + return; + } + if (!act.owner) { + return; + } + if (act.owner.underlyingWindow.id === window.id) { + this._myActivityFrameColorChanged.forEach((callback) => { + callback(window.frameColor); + }); + } + } + } + + class ReadyMarker { + constructor(name, signalsToWait) { + this._logger = Logger.Get("ReadyMarker [" + name + "]"); + this._logger.debug("Initializing ready marker for '" + name + "' with " + signalsToWait + " signals to wait"); + if (signalsToWait <= 0) { + throw new Error("Invalid signal number. Should be > 0"); + } + this._signals = signalsToWait; + this._callbacks = []; + this._name = name; + } + setCallback(callback) { + if (this.isSet()) { + callback(undefined); + return; + } + else if (this.isError()) { + callback(this._error); + return; + } + this._callbacks.push(callback); + } + signal(message) { + this._logger.debug("Signaled - " + message + " - signals left " + (this._signals - 1)); + this._signals--; + if (this._signals < 0) { + throw new Error("Error in ready marker '" + this._name + " - signals are " + this._signals); + } + if (this.isSet()) { + this._callbacks.forEach((callback) => { + callback(undefined); + }); + } + } + error(error) { + this._error = error; + this._callbacks.forEach((errorCallback) => { + errorCallback(error); + }); + } + isSet() { + if (this.isError()) { + return false; + } + return this._signals === 0; + } + isError() { + return !isUndefined(this._error); + } + getError() { + return this._error; + } + } + + class EntityObservableCollection { + constructor(processNew) { + this._items = {}; + this._listeners = []; + this._processNew = processNew; + } + addOne(item) { + this.add([item]); + } + add(items) { + items.forEach((element) => { + this.process(new EntityEvent(element, new EntityEventContext(EntityEventType.Added))); + }); + } + process(event) { + const context = event.context; + const type = context.type; + const entity = event.entity; + if (type === EntityEventType.StatusChange && + !context.oldStatus) { + const act = this._items[entity.id]; + if (act) { + context.oldStatus = act.status; + } + } + if (type === EntityEventType.StatusChange && + context.oldStatus && + context.newStatus && + context.oldStatus.state === + context.newStatus.state) { + context.type = EntityEventType.Updated; + } + if (typeof htmlContainer === "undefined") { + if (type === EntityEventType.ActivityWindowJoinedActivity && + this._items[entity.id] && + this._items[entity.id].activity) { + context.type = EntityEventType.Updated; + } + if (type === EntityEventType.ActivityWindowLeftActivity && + this._items[entity.id] && + !this._items[entity.id].activity) { + context.type = EntityEventType.Updated; + } + } + const internalEntity = this._updateInternalCollections(entity, type, context); + this._notifyListeners(internalEntity, context); + return internalEntity; + } + get() { + const result = []; + for (const key in this._items) { + if (this._items.hasOwnProperty(key)) { + const element = this._items[key]; + result.push(element); + } + } + return result; + } + getByName(name) { + for (const key in this._items) { + if (key === name) { + return this._items[key]; + } + } + return undefined; + } + getOrWait(name) { + return new Promise((resolve) => { + const entityAddedHandler = (entity) => { + if (entity.id !== name) { + return; + } + resolve(entity); + this.unsubscribe(entityAddedHandler); + }; + this.subscribe(entityAddedHandler); + const window = this.getByName(name); + if (window) { + this.unsubscribe(entityAddedHandler); + resolve(window); + return; + } + }); + } + subscribe(handler) { + this._listeners.push(handler); + Object.keys(this._items).forEach((key) => { + const element = this._items[key]; + handler(element, new EntityEventContext(EntityEventType.Added.toString())); + }); + return () => { + this.unsubscribe(handler); + }; + } + unsubscribe(handler) { + const index = this._listeners.indexOf(handler); + if (index !== -1) { + this._listeners.splice(index, 1); + } + } + _notifyListeners(entity, context) { + this._listeners.forEach((listener) => { + try { + listener(entity, context); + } + catch (e) { + return; + } + }); + } + _updateInternalCollections(entity, type, context) { + const entityAsAny = entity; + const isActivityDestroy = (type === EntityEventType.StatusChange && + entityAsAny.status && + entityAsAny.status.state === ActivityState.Destroyed) || + (type === EntityEventType.StatusChange && + context && + context.newStatus && + context.newStatus.state === ActivityState.Destroyed); + const isWindowClose = type === EntityEventType.Closed; + const isTypeRemove = type === EntityEventType.Removed && typeof entityAsAny.isIndependent === "undefined"; + if (isTypeRemove || isWindowClose || isActivityDestroy) { + const oldEntity = this._items[entity.id]; + delete this._items[entity.id]; + this._processNew(entity); + if (oldEntity) { + entity._beforeDelete(oldEntity); + } + return entity; + } + else { + const key = entity.id; + if (!this._items.hasOwnProperty(key)) { + this._processNew(entity); + this._items[entity.id] = entity; + } + else { + this._items[entity.id]._update(entity); + } + } + return this._items[entity.id]; + } + } + + class ActivityManager { + get usingHc() { + return this._bridge.bridgeType === "HC"; + } + get announcedWindows() { + return this._announcedWindows; + } + set announcedWindows(v) { + throw new Error("not allowed"); + } + constructor(bridge, autoAnnounce, windows) { + this._logger = Logger.Get("activityManager"); + this._announcedWindows = []; + this._attachedCallbacks = []; + this._detachedCallbacks = []; + this._frameColorChangesCallbacks = []; + this._windowHandlers = []; + this._bridge = bridge; + this._activityTypes = new EntityObservableCollection((e) => this._grabEntity(e)); + this._windowTypes = new EntityObservableCollection((e) => this._grabEntity(e)); + this._activities = new EntityObservableCollection((e) => this._grabEntity(e)); + this._windows = new EntityObservableCollection((e) => this._grabEntity(e)); + this._dataReadyMarker = new ReadyMarker("Activity Manager Data", ["GetActivityTypes", "GetWindowTypes", "GetActivities", "GetWindows"].length); + this._descriptorsMarker = new ReadyMarker("Attached Activities Descriptors", ["GetDescriptors"].length); + if (autoAnnounce) { + this._readyMarker = new ReadyMarker("Activity Manager Announce", ["Announcement"].length); + this._dataReadyMarker.setCallback((dataErr) => { + if (dataErr) { + this._readyMarker.error(dataErr); + } + this._descriptorsMarker.setCallback((err) => { + if (err) { + this._readyMarker.error(err); + } + this._logger.debug("Auto announcing window"); + this.announceWindow() + .then((w) => { + this._announcedWindows.push(w); + this._readyMarker.signal("Successfully announced window with id '" + w.id + "'"); + }) + .catch((errCatch) => { + this._logger.debug("Will not announce window - " + errCatch); + this._readyMarker.signal(); + }); + }); + this.refreshDescriptors(); + }); + } + else { + this._readyMarker = this._dataReadyMarker; + } + this._bridge.onActivitiesAttached((e) => { + this._handleActivitiesAttached(e); + }); + this._bridge.onActivitiesDetached((e) => { + this._handleActivitiesDetached(e); + }); + this._bridge.onActivityAttachedDescriptorsRefreshed((e) => { + this._handleActivityDescriptorsRefreshed(e); + }); + if (windows) { + windows.onWindowFrameColorChanged(this._handleWindowFrameColorChanged.bind(this)); + } + this._bridge.init(); + this._subscribeForData(); + this._bridge + .initReady() + .then((aw) => { + this._getInitialData(); + }) + .catch((error) => { + console.log(error); + }); + } + ready(callback) { + const promise = new Promise((resolve, reject) => { + this._readyMarker.setCallback((err) => { + if (!err) { + resolve(this); + } + else { + reject(this._readyMarker.getError()); + } + }); + }); + return nodeify(Promise.all([this._bridge.ready(), promise]).then(() => this), callback); + } + getActivityTypes() { + return this._activityTypes.get(); + } + getActivityType(name) { + return this._activityTypes.getByName(name); + } + registerActivityType(activityTypeName, ownerWindowType, helperWindowTypes, config, description, callback) { + const promise = new Promise((resolve, reject) => { + if (isUndefinedOrNull(activityTypeName)) { + reject("activityTypeName argument can not be undefined"); + return; + } + if (!isString(activityTypeName)) { + reject("activityTypeName should be string"); + return; + } + const actType = this.getActivityType(activityTypeName); + if (!isUndefinedOrNull(actType)) { + reject("Activity type '" + activityTypeName + "' already exists"); + return; + } + let ownerDefinition; + if (isUndefined(ownerWindowType)) { + reject("Owner window type can not be undefined"); + return; + } + if (isString(ownerWindowType)) { + ownerDefinition = { type: (ownerWindowType), name: "", isIndependent: false, arguments: {} }; + } + else { + ownerDefinition = (ownerWindowType); + } + const helperDefinitions = []; + if (!isUndefined(helperWindowTypes) && isArray(helperWindowTypes)) { + for (const index in helperWindowTypes) { + const item = helperWindowTypes[index]; + if (isString(item)) { + const definition = { + type: (item), + name: "", + isIndependent: false, + arguments: {}, + relativeTo: "", + relativeDirection: "", + windowStyleAttributes: {} + }; + helperDefinitions.push(definition); + } + else { + helperDefinitions.push(item); + } + } + } + this._bridge + .registerActivityType(activityTypeName, ownerDefinition, helperDefinitions, config, description) + .then((activityType) => { + this._grabEntity(activityType); + resolve(activityType); + }) + .catch((error) => { + reject(error); + }); + }); + return nodeify(promise, callback); + } + unregisterActivityType(type, callback) { + const promise = new Promise((resolve, reject) => { + const actType = this.getActivityType(type); + if (isUndefined(actType)) { + reject("Activity type '" + type + "' does not exists"); + return; + } + this._bridge.unregisterActivityType(type).then(() => resolve(actType), reject); + }); + return nodeify(promise, callback); + } + initiate(activityType, context, callback, configuration) { + const promise = new Promise((resolve, reject) => { + const actType = this.getActivityType(activityType); + if (isUndefined(actType)) { + reject("Activity type '" + activityType + "' does not exists"); + return; + } + this._bridge + .initiateActivity(activityType, context, configuration) + .then((actId) => { + this._activities + .getOrWait(actId) + .then((act) => { + resolve(act); + }) + .catch((err) => reject(err)); + }) + .catch((err) => { + reject(err); + }); + }); + return nodeify(promise, callback); + } + subscribeActivityTypeEvents(handler) { + this._activityTypes.subscribe((at, context) => { + handler(at, context.type); + }); + } + getWindowTypes() { + return this._windowTypes.get(); + } + getWindowType(name) { + return this._windowTypes.getByName(name); + } + registerWindowFactory(windowType, factoryMethod, callback) { + const promise = new Promise((resolve, reject) => { + if (isUndefinedOrNull(windowType)) { + reject("no windowType specified"); + return; + } + if (isObject(windowType)) { + windowType = windowType.getName(); + } + else if (!isString(windowType)) { + reject("windowType should be string or object that has getName method"); + return; + } + this._bridge + .registerWindowFactory(windowType, factoryMethod) + .then((v) => { + resolve(v); + }) + .catch((err) => { + reject(err); + }); + }); + return nodeify(promise, callback); + } + unregisterWindowFactory(windowType, callback) { + const promise = new Promise((resolve, reject) => { + if (isUndefinedOrNull(windowType)) { + reject("no windowType specified"); + return; + } + if (!isString(windowType)) { + reject("windowType should be a string"); + return; + } + this._bridge + .unregisterWindowFactory(windowType) + .then((v) => { + resolve(v); + }) + .catch((err) => { + reject(err); + }); + }); + return nodeify(promise, callback); + } + getActivities(activityType) { + let act = this._activities.get(); + act = act.filter((a) => a._ownerId); + if (!activityType) { + return act; + } + let types = activityType; + if (isString(activityType)) { + types = [activityType]; + } + else if (activityType instanceof ActivityType) { + types = [activityType.name]; + } + else if (activityType instanceof Array) ; + else { + throw new Error("Invalid input argument 'activityType' = " + activityType); + } + return act.filter((at) => { + const type = at.type; + return some(types, (t) => { + return type.id === t.id; + }); + }); + } + getActivityById(id) { + return this._activities.getByName(id); + } + announceWindow(activityWindowId, windowType) { + const promise = new Promise((resolve, reject) => { + const announcementInfo = this._bridge.getAnnouncementInfo(); + if (isUndefined(activityWindowId)) { + activityWindowId = announcementInfo.activityWindowId; + } + if (isUndefined(windowType)) { + windowType = announcementInfo.activityWindowType; + } + if (isUndefinedOrNull(windowType)) { + throw new Error("Can not announce - unknown windowType"); + } + const activityId = announcementInfo && announcementInfo.activityId; + if (isUndefinedOrNull(activityWindowId)) { + this._logger.debug("Registering window with type:'" + windowType + "', name:'" + announcementInfo.activityWindowName + "', ind.:'" + announcementInfo.activityWindowIndependent + "'"); + this._bridge.registerWindow(windowType, announcementInfo.activityWindowName, announcementInfo.activityWindowIndependent) + .then(this._windows.getOrWait.bind(this._windows)) + .then((w) => { + if (activityId) { + return this._activities.getOrWait(activityId).then((_) => w); + } + else { + return w; + } + }) + .then((w) => { + resolve(w); + }) + .catch((err) => { + this._logger.error(err); + }); + } + else { + this._logger.debug("Announcing window with id '" + activityWindowId + "' and type '" + windowType + "'"); + const currentWindow = this._windows.getByName(activityWindowId); + if (!isUndefinedOrNull(currentWindow)) { + this._logger.debug("Window with id '" + activityWindowId + "' already announced - reusing the window"); + resolve(currentWindow); + return; + } + const windowEventHandler = (a, w, e) => { + if (activityWindowId === w.id) { + if (e === EntityEventType.ActivityWindowJoinedActivity) { + const activity = w.activity; + if (isUndefined(activity)) { + reject("UNDEFINED ACTIVITY"); + } + this._logger.trace("Got joined event for id '" + activityWindowId + "'"); + resolve(w); + this.unsubscribeWindowEvents(windowEventHandler); + } + } + }; + this.subscribeWindowEvents(windowEventHandler); + this._logger.trace("Waiting for joined event for id '" + activityWindowId + "'"); + this._bridge.announceWindow(windowType, activityWindowId); + } + }); + return promise; + } + subscribeWindowTypeEvents(handler) { + this._windowTypes.subscribe((wt, context) => { + handler(wt, context.type); + }); + } + subscribeActivityEvents(handler) { + return this._activities.subscribe((act, context) => { + if (context.type === EntityEventType.StatusChange) { + const p = context; + handler(act, p.newStatus, p.oldStatus); + } + if (context.type === EntityEventType.Removed || + (context.type === EntityEventType.StatusChange && + context.newStatus.getState() === ActivityState.Destroyed)) { + for (const window of this._windows.get()) { + if (window.activity && window.activity.id === act.id) { + this._windows.process(new EntityEvent(window, new EntityEventContext(EntityEventType.ActivityWindowLeftActivity))); + } + } + } + }); + } + subscribeWindowEvents(handler) { + const wrappingHandler = (window, context) => { + let eventType = context.type; + if (eventType === EntityEventType.Added) { + eventType = "opened"; + } + handler(window.activity, window, eventType); + }; + this._windowHandlers.push([handler, wrappingHandler]); + return this._windows.subscribe(wrappingHandler); + } + unsubscribeWindowEvents(handler) { + const found = this._windowHandlers.find((pair) => pair[0] === handler); + if (found) { + this._windowHandlers.splice(this._windowHandlers.indexOf(found), 1); + this._windows.unsubscribe(found[1]); + } + } + createWindow(activity, windowTypeOrConfiguration, callback) { + const promise = new Promise((resolve, reject) => { + if (isUndefinedOrNull(windowTypeOrConfiguration)) { + reject("windowType is undefined"); + } + let windowDefinition; + if (isString(windowTypeOrConfiguration)) { + windowDefinition = { type: (windowTypeOrConfiguration), name: "", isIndependent: false, arguments: {} }; + } + else if (windowTypeOrConfiguration instanceof WindowType) { + windowDefinition = { + type: windowTypeOrConfiguration.type || windowTypeOrConfiguration.id, + name: windowTypeOrConfiguration.name || windowTypeOrConfiguration.type || windowTypeOrConfiguration.id, + isIndependent: false + }; + } + else { + const invalidKeys = ["url"]; + const filteredWindowTypeOrConfiguration = {}; + Object.keys(windowTypeOrConfiguration).forEach((key) => { + if (invalidKeys.indexOf(key) === -1) { + filteredWindowTypeOrConfiguration[key] = windowTypeOrConfiguration[key]; + } + }); + windowDefinition = filteredWindowTypeOrConfiguration; + } + let relativeToWindow; + if (!isUndefinedOrNull(windowDefinition.relativeTo)) { + relativeToWindow = windowDefinition.relativeTo; + if (typeof relativeToWindow === "string") { + const windows = this.getWindows({ type: relativeToWindow }); + if (!isUndefinedOrNull(windows) && windows.length > 0) { + windowDefinition.relativeTo = windows[0].id; + } + } + else if (!isUndefinedOrNull(relativeToWindow.type)) { + const windows = this.getWindows({ type: relativeToWindow.type }); + if (!isUndefinedOrNull(windows) && windows.length > 0) { + windowDefinition.relativeTo = windows[0].id; + } + } + else if (!isUndefinedOrNull(relativeToWindow.windowId)) { + windowDefinition.relativeTo = relativeToWindow.windowId; + } + } + this._bridge.createWindow(activity && activity.id, windowDefinition) + .then((wid) => { + this._logger.debug("Window created, waiting for window entity with id " + wid); + const handler = (window, context) => { + if (window.id === wid && (!activity || window.activity)) { + this._logger.debug("Got entity window with id " + wid); + resolve(window); + this._windows.unsubscribe(handler); + } + }; + this._windows.subscribe(handler); + }) + .catch((err) => { + reject(err); + }); + }); + return nodeify(promise, callback); + } + createStackedWindows(activity, relativeWindowTypes, timeout, callback) { + const promise = new Promise((resolve, reject) => { + if (isUndefinedOrNull(activity)) { + reject("activity is undefined"); + } + if (isUndefinedOrNull(relativeWindowTypes)) { + reject("relativeWindowTypes is undefined"); + } + if (!Array.isArray(relativeWindowTypes)) { + reject("relativeWindowTypes has to be an array"); + } + if (isUndefinedOrNull(timeout)) { + timeout = 20000; + } + const windowDefinitions = []; + relativeWindowTypes.forEach((element) => { + let windowDefinition; + if (isString(element)) { + windowDefinition = { type: (element), name: "", isIndependent: false, arguments: {} }; + } + else { + windowDefinition = (element); + } + windowDefinition.stackedWindow = true; + windowDefinition.timeout = timeout; + let relativeToWindow; + if (!isUndefinedOrNull(windowDefinition.relativeTo)) { + relativeToWindow = windowDefinition.relativeTo; + if (!isUndefinedOrNull(relativeToWindow.type)) { + windowDefinition.relativeTo = relativeToWindow.type; + } + else if (!isUndefinedOrNull(relativeToWindow.windowId)) { + const windows = this.getWindows({ id: relativeToWindow.windowId }); + if (!isUndefinedOrNull(windows) && windows.length > 0) { + windowDefinition.relativeTo = windows[0].type.name; + } + } + } + windowDefinitions.push(windowDefinition); + }); + const tasks = []; + windowDefinitions.forEach((wd) => tasks.push(this.createWindow(activity, wd))); + Promise.all(tasks).then(resolve).catch(reject); + }); + return nodeify(promise, callback); + } + addWindowToActivity(activity, window, callback) { + const toReturn = this._bridge.joinActivity(activity.id, window.id) + .then(() => window); + nodeify(toReturn, callback); + return toReturn; + } + leaveWindowFromActivity(activity, window, callback) { + const toReturn = this._bridge.leaveActivity(activity.id, window.id) + .then(() => window); + nodeify(toReturn, callback); + return toReturn; + } + setActivityContext(activity, context, callback) { + const promise = new Promise((resolve, reject) => { + if (isUndefinedOrNull(activity)) { + reject("activity can not be null"); + } + this._bridge + .updateActivityContext(activity, context, true) + .then((_) => { + resolve(activity); + }) + .catch((err) => { + reject(err); + }); + }); + return nodeify(promise, callback); + } + updateActivityContext(activity, context, callback) { + const promise = new Promise((resolve, reject) => { + if (isUndefinedOrNull(activity)) { + reject("activity can not be null"); + } + const removedKeys = []; + for (const key in context) { + if (context.hasOwnProperty(key) && context[key] === null) { + removedKeys.push(key); + } + } + for (const removedKey of removedKeys) { + delete context[removedKey]; + } + this._bridge + .updateActivityContext(activity, context, false, removedKeys) + .then((_) => { + resolve(activity); + }) + .catch((err) => { + reject(err); + }); + }); + return nodeify(promise, callback); + } + subscribeActivityContextChanged(handler) { + this._activities.subscribe((act, context) => { + if (context.type === EntityEventType.ActivityContextChange) { + const updateContext = context; + handler(act, updateContext.context, updateContext.updated, updateContext.removed); + } + }); + } + stopActivity(activity, callback) { + const promise = this._bridge.stopActivity(activity); + return nodeify(promise, callback); + } + getWindows(filter) { + if (isUndefined(filter)) { + return this._windows.get(); + } + if (!isUndefined(filter.id)) { + return [this._windows.getByName(filter.id)]; + } + const allWindows = this._windows.get(); + return allWindows.filter((w) => { + if (!isUndefined(filter.type) && w.type.id !== filter.type) { + return false; + } + if (!isUndefined(filter.name) && w.name !== filter.name) { + return false; + } + if (!isUndefined(filter.activityId)) { + if (isUndefinedOrNull(w.activity)) { + return false; + } + if (w.activity.id !== filter.activityId) { + return false; + } + } + return true; + }); + } + getWindowBounds(id) { + return this._bridge.getWindowBounds(id); + } + setWindowBounds(id, bounds, callback) { + const promise = new Promise((resolve, reject) => { + this._bridge.setWindowBounds(id, bounds) + .then(() => resolve()) + .catch((err) => reject(err)); + }); + return nodeify(promise, callback); + } + closeWindow(id) { + return this._bridge.closeWindow(id); + } + activateWindow(id, focus) { + return this._bridge.activateWindow(id, focus); + } + setWindowVisibility(id, visible) { + return this._bridge.setWindowVisibility(id, visible); + } + clone(activity, cloneOptions, callback) { + const promise = new Promise((resolve, reject) => { + if (!activity) { + reject("activity can not be null"); + } + this._bridge.cloneActivity(activity.id, cloneOptions) + .then((activityId) => { + this._activities + .getOrWait(activityId) + .then((act) => { + resolve(act); + }) + .catch((err) => reject(err)); + }) + .catch((err) => reject(err)); + }); + return nodeify(promise, callback); + } + attachActivities(from, to, tag, callback) { + tag = tag || {}; + const promise = new Promise((resolve, reject) => { + const fromActivity = this._activities.getByName(from); + if (!fromActivity) { + reject("can not find activity with id " + from); + return; + } + const toActivity = this._activities.getByName(to); + if (!toActivity) { + reject("can not find activity with id " + to); + return; + } + return this._bridge.attachActivities(from, to, tag) + .then((data) => { + const newActId = data.to; + const state = data.descriptor; + const allStates = data.descriptors; + this._activities.getOrWait(newActId).then((act) => { + act._updateDescriptors(allStates); + const stateWrapped = act.attached.filter((u) => u.ownerId === state.ownerId)[0]; + resolve(stateWrapped); + }); + }) + .catch((err) => { + reject(err); + }); + }); + return nodeify(promise, callback); + } + detachActivities(activityId, descriptor, callback) { + const promise = new Promise((resolve, reject) => { + return this._bridge.detachActivities(activityId, descriptor) + .then(() => { + const oldActId = undefined; + const newActId = undefined; + const descriptors = undefined; + this._activities + .getOrWait(oldActId) + .then((oldAct) => { + oldAct._updateDescriptors(descriptors); + this._activities + .getOrWait(newActId) + .then((newAct) => { + resolve(newAct); + }); + }) + .catch((err) => reject(err)); + }) + .catch((err) => { + reject(err); + }); + }); + return nodeify(promise, callback); + } + subscribeActivitiesAttached(callback) { + this._attachedCallbacks.push(callback); + } + subscribeActivitiesDetached(callback) { + this._detachedCallbacks.push(callback); + } + subscribeActivityFrameColorChanged(callback) { + this._frameColorChangesCallbacks.push(callback); + } + _grabEntity(entity) { + entity._manager = this; + } + _getInitialData() { + this._logger.debug("Request initial data..."); + this._bridge.getActivityTypes() + .then((at) => { + this._activityTypes.add(at); + this._dataReadyMarker.signal("Got act types"); + }) + .catch((error) => { + this._logger.error(error); + this._dataReadyMarker.error("Can not initialize ActivityManager - error getting activity types -" + error); + }); + this._bridge.getWindowTypes() + .then((wt) => { + this._windowTypes.add(wt); + this._dataReadyMarker.signal("Got window types"); + }) + .catch((error) => { + this._logger.error(error); + this._dataReadyMarker.error("Can not initialize ActivityManager - error getting window types " + error); + }); + this._bridge.getActivities() + .then((ac) => { + this._activities.add(ac); + this._dataReadyMarker.signal("Got activities"); + }) + .catch((error) => { + this._logger.error(error); + this._dataReadyMarker.error("Can not initialize ActivityManager - error getting activity instances -" + error); + }); + this._bridge.getActivityWindows() + .then((aw) => { + this._windows.add(aw); + this._dataReadyMarker.signal("Got windows"); + }) + .catch((error) => { + this._logger.error(error); + this._dataReadyMarker.error("Can not initialize ActivityManager - error getting activity windows -" + error); + }); + } + _subscribeForData() { + this._logger.debug("Subscribe for data..."); + this._bridge.onActivityTypeStatusChange((event) => { + this._activityTypes.process(event); + }); + this._bridge.onWindowTypeStatusChange((event) => { + this._windowTypes.process(event); + }); + this._bridge.onActivityWindowChange((event) => { + this._windows.process(event); + }); + this._bridge.onActivityStatusChange((event) => { + this._activities.process(event); + }); + } + _handleActivitiesAttached(data) { + const newActId = data.to; + const descriptor = data.descriptor; + const descriptors = data.descriptors; + this._activities.getOrWait(newActId).then((act) => { + act._updateDescriptors(descriptors); + const descriptorAsObjectFromAPI = act.attached.filter((u) => u.ownerId === descriptor.ownerId)[0]; + this._attachedCallbacks.forEach((callback) => { + try { + callback(act, descriptorAsObjectFromAPI); + } + catch (err) { + return; + } + }); + }); + } + _handleActivitiesDetached(data) { + const oldActId = data.oldActivityId; + const newActId = data.newActivityId; + const descriptors = data.descriptors; + const descriptor = data.descriptor; + this._activities.getOrWait(oldActId).then((oldAct) => { + oldAct._updateDescriptors(descriptors); + this._activities.getOrWait(newActId).then((newAct) => { + this._detachedCallbacks.forEach((callback) => { + try { + callback(newAct, oldAct, descriptor); + } + catch (err) { + return; + } + }); + }); + }); + } + _handleActivityDescriptorsRefreshed(data) { + const id = data.id; + const descriptors = data.descriptors; + const act = this._activities.getByName(id); + if (act) { + act._updateDescriptors(descriptors); + } + } + refreshDescriptors() { + this._bridge.getAttachedDescriptors() + .then((map) => { + if (map) { + Object.keys(map).forEach((key) => { + const actId = key; + const descriptors = map[key]; + const act = this._activities.getByName(actId); + if (act) { + act._updateDescriptors(descriptors); + } + }); + } + this._descriptorsMarker.signal("Successfully got descriptors"); + }) + .catch((err) => { + this._descriptorsMarker.error("failed to get descriptors - " + err); + }); + } + _handleWindowFrameColorChanged(win) { + if (!win.activityId) { + return; + } + const act = this._activities.getByName(win.activityId); + if (!act) { + return; + } + if (!act.owner) { + return; + } + if (act.owner.underlyingWindow.id !== win.id) { + return; + } + this._frameColorChangesCallbacks.forEach((callback) => { + try { + callback(act, win.frameColor); + } + catch (e) { + return; + } + }); + } + } + + class ActivityManagementAPI { + constructor(manager, my) { + this._m = manager; + this._my = my; + this.activityTypes = { + get: this._getActivityTypesWrapper.bind(this), + register: this._m.registerActivityType.bind(this._m), + unregister: this._m.unregisterActivityType.bind(this._m), + subscribe: this._m.subscribeActivityTypeEvents.bind(this._m), + unsubscribe: undefined, + initiate: this._m.initiate.bind(this._m) + }; + this.windowTypes = { + get: this._getWindowTypesWrapper.bind(this), + registerFactory: this._m.registerWindowFactory.bind(this._m), + unregisterFactory: this._m.unregisterWindowFactory.bind(this._m), + subscribe: this._m.subscribeWindowTypeEvents.bind(this._m), + unsubscribe: undefined + }; + this.windows = { + get: this._m.getWindows.bind(this._m), + subscribe: this._m.subscribeWindowEvents.bind(this._m), + announce: this._m.announceWindow.bind(this._m), + unsubscribe: undefined, + create: this._m.createWindow.bind(this._m) + }; + this.instances = { + get: this._m.getActivities.bind(this._m), + subscribe: this._m.subscribeActivityEvents.bind(this._m), + unsubscribe: undefined + }; + } + onAttached(callback) { + this._m.subscribeActivitiesAttached(callback); + } + onDetached(callback) { + this._m.subscribeActivitiesDetached(callback); + } + onActivityFrameColorChanged(callback) { + this._m.subscribeActivityFrameColorChanged(callback); + } + _getActivityTypesWrapper(name) { + if (isUndefined(name)) { + return this._m.getActivityTypes(); + } + return this._m.getActivityType(name); + } + _getWindowTypesWrapper(name) { + if (isUndefined(name)) { + return this._m.getWindowTypes(); + } + return this._m.getWindowType(name); + } + } + + class ActivityAPI { + constructor(manager, my) { + this._mgr = manager; + this._my = my; + this.all = new ActivityManagementAPI(manager, my); + } + ready(callback) { + const promise = new Promise((resolve, reject) => { + this._mgr.ready() + .then(() => { + resolve(this); + }) + .catch((err) => { + reject(err); + }); + }); + return nodeify(promise, callback); + } + get my() { + return this._my; + } + get aware() { + return this._my.window !== undefined; + } + get inActivity() { + return this.aware && this._my.activity !== undefined; + } + get agm() { + if (!this.aware) { + return undefined; + } + if (!this.inActivity) { + return new ActivityAGM(null); + } + return this._my.activity.agm; + } + getAvailableFrameColors() { + return []; + } + } + + class ActivityModule { + static checkIsUsingGW3Implementation(connection) { + return connection.protocolVersion === 3; + } + get api() { + return this._api; + } + set api(value) { + this._api = value; + } + constructor(config) { + if (!config) { + throw new Error("config can not be null"); + } + if (!isUndefined(config.logLevel)) { + Logger.Level = config.logLevel; + } + if (!isUndefinedOrNull(config.logger)) { + Logger.GlueLogger = config.logger; + } + let bridge; + this._isUsingHCImplementation = config.gdMajorVersion === 2; + this._isUsingGW3Implementation = ActivityModule.checkIsUsingGW3Implementation(config.connection); + if (this._isUsingHCImplementation) { + throw new Error("GD2 not supported"); + } + else if (this._isUsingGW3Implementation) { + bridge = new GW3Bridge(config); + } + else { + throw new Error("Unable to instantiate activity bridge implementation"); + } + if (!bridge) { + throw new Error("A bridge to native activity is needed to create activity lib."); + } + ActivityAGM.AGM = config.agm; + const activityManager = new ActivityManager(bridge, !config.disableAutoAnnounce, config.windows); + const my = new ActivityMy(activityManager, config.windows); + this._api = new ActivityAPI(activityManager, my); + this._readyPromise = activityManager.ready().then((_) => this); + } + get isUsingHCImplementation() { + return this._isUsingHCImplementation; + } + get isUsingGW3Implementation() { + return this._isUsingGW3Implementation; + } + ready(callback) { + return nodeify(this._readyPromise, callback); + } + } + + const ShutdownMethodName = "T42.ACS.Shutdown"; + const OnGDShutdownMethodName = "T42.ACS.OnGDShutdown"; + const RestartMethodName = "T42.ACS.Restart"; + const GetConfigurationRegionMethodName = "T42.ACS.GetConfigurationRegion"; + const SetConfigurationRegionMethodName = "T42.ACS.SetConfigurationRegion"; + const GetUserMethodName = "T42.ACS.GetUser"; + const GetBranchesMethodName = "T42.ACS.GetBranches"; + const GetCurrentBranchMethodName = "T42.ACS.GetCurrentBranch"; + const SetCurrentBranchMethodName = "T42.ACS.SetCurrentBranch"; + const GetFunctionalEntitlementMethodName = "T42.ACS.GetFunctionalEntitlement"; + const CanIMethodName = "T42.ACS.CanI"; + const StartApplicationMethodName = "T42.ACS.StartApplication"; + const StopApplicationMethodName = "T42.ACS.StopApplication"; + const ActivateApplicationMethodName = "T42.ACS.ActivateApplication"; + const ACSExecute = "T42.ACS.Execute"; + const OnEventMethodName = "T42.ACS.OnEvent"; + const GetApplicationsMethodName = "T42.ACS.GetApplications"; + + var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; + + function getDefaultExportFromCjs (x) { + return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; + } + + function createRegistry(options) { + if (options && options.errorHandling + && typeof options.errorHandling !== "function" + && options.errorHandling !== "log" + && options.errorHandling !== "silent" + && options.errorHandling !== "throw") { + throw new Error("Invalid options passed to createRegistry. Prop errorHandling should be [\"log\" | \"silent\" | \"throw\" | (err) => void], but " + typeof options.errorHandling + " was passed"); + } + var _userErrorHandler = options && typeof options.errorHandling === "function" && options.errorHandling; + var callbacks = {}; + function add(key, callback, replayArgumentsArr) { + var callbacksForKey = callbacks[key]; + if (!callbacksForKey) { + callbacksForKey = []; + callbacks[key] = callbacksForKey; + } + callbacksForKey.push(callback); + if (replayArgumentsArr) { + setTimeout(function () { + replayArgumentsArr.forEach(function (replayArgument) { + var _a; + if ((_a = callbacks[key]) === null || _a === void 0 ? void 0 : _a.includes(callback)) { + try { + if (Array.isArray(replayArgument)) { + callback.apply(undefined, replayArgument); + } + else { + callback.apply(undefined, [replayArgument]); + } + } + catch (err) { + _handleError(err, key); + } + } + }); + }, 0); + } + return function () { + var allForKey = callbacks[key]; + if (!allForKey) { + return; + } + allForKey = allForKey.reduce(function (acc, element, index) { + if (!(element === callback && acc.length === index)) { + acc.push(element); + } + return acc; + }, []); + if (allForKey.length === 0) { + delete callbacks[key]; + } + else { + callbacks[key] = allForKey; + } + }; + } + function execute(key) { + var argumentsArr = []; + for (var _i = 1; _i < arguments.length; _i++) { + argumentsArr[_i - 1] = arguments[_i]; + } + var callbacksForKey = callbacks[key]; + if (!callbacksForKey || callbacksForKey.length === 0) { + return []; + } + var results = []; + callbacksForKey.forEach(function (callback) { + try { + var result = callback.apply(undefined, argumentsArr); + results.push(result); + } + catch (err) { + results.push(undefined); + _handleError(err, key); + } + }); + return results; + } + function _handleError(exceptionArtifact, key) { + var errParam = exceptionArtifact instanceof Error ? exceptionArtifact : new Error(exceptionArtifact); + if (_userErrorHandler) { + _userErrorHandler(errParam); + return; + } + var msg = "[ERROR] callback-registry: User callback for key \"" + key + "\" failed: " + errParam.stack; + if (options) { + switch (options.errorHandling) { + case "log": + return console.error(msg); + case "silent": + return; + case "throw": + throw new Error(msg); + } + } + console.error(msg); + } + function clear() { + callbacks = {}; + } + function clearKey(key) { + var callbacksForKey = callbacks[key]; + if (!callbacksForKey) { + return; + } + delete callbacks[key]; + } + return { + add: add, + execute: execute, + clear: clear, + clearKey: clearKey + }; + } + createRegistry.default = createRegistry; + var lib = createRegistry; + + + var CallbackRegistryFactory = /*@__PURE__*/getDefaultExportFromCjs(lib); + + function objectValues(source) { + if (!source) { + return []; + } + return Object.keys(source).map((key) => source[key]); + } + function objectClone(obj) { + let result; + try { + result = JSON.parse(JSON.stringify(obj || {})); + } + catch (error) { + result = {}; + } + return result; + } + function validate(callback, configuration) { + if (configuration.throwErrors) { + if (typeof callback !== "function") { + throw new Error("Please provide the callback as a function!"); + } + } + } + + const INTEROP_METHOD_RESPONSE_TIMEOUT_MS = 90000; + const INTEROP_METHOD_WAIT_TIMEOUT_MS = 90000; + + let urlAlphabet = + 'useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict'; + let nanoid = (size = 21) => { + let id = ''; + let i = size | 0; + while (i--) { + id += urlAlphabet[(Math.random() * 64) | 0]; + } + return id + }; + + class Utils { + static getGDMajorVersion() { + if (typeof window === "undefined") { + return -1; + } + if (!window.glueDesktop) { + return -1; + } + if (!window.glueDesktop.version) { + return -1; + } + const parsed = window.glueDesktop.version.split("."); + const major = Number(parsed[0]); + return isNaN(major) ? -1 : major; + } + static typedError(error) { + let err; + if (error instanceof Error) { + err = error; + } + else if (typeof error === "string") { + err = new Error(error); + } + else if ("message" in error && typeof error.message === "string" && error.message.length > 0) { + err = new Error(error.message); + } + else if ("returned" in error + && typeof error.returned === "object" + && "errorMsg" in error.returned + && typeof error.returned.errorMsg === "string" + && error.returned.errorMsg.length > 0) { + err = new Error(error.returned.errorMsg); + } + else { + err = new Error("Unknown error"); + } + return err; + } + static async callbackifyPromise(action, successCallback, errorCallback) { + const success = (result) => { + if (typeof successCallback === "function") { + successCallback(result); + } + return Promise.resolve(result); + }; + const fail = (error) => { + const err = Utils.typedError(error); + if (typeof errorCallback === "function") { + errorCallback(err.message); + return; + } + return Promise.reject(err); + }; + try { + const result = await action(); + return success(result); + } + catch (error) { + return fail(error); + } + } + static getMonitor(bounds, displays) { + const monitorsSortedByOverlap = displays.map((m) => { + const { left, top, workingAreaWidth: width, workingAreaHeight: height } = m; + const overlap = this.calculateTotalOverlap({ left, top, width, height }, bounds); + return { + monitor: m, + totalOverlap: overlap + }; + }).sort((a, b) => b.totalOverlap - a.totalOverlap); + return monitorsSortedByOverlap[0].monitor; + } + static getDisplayCenterOfScreen(a, currentDisplay, primaryDisplay) { + const physicalWidth = a.width / currentDisplay.scaleFactor; + const physicalHeight = a.height / currentDisplay.scaleFactor; + const physicalDisplayLeft = currentDisplay.workArea.left / primaryDisplay.scaleFactor; + const physicalDisplayTop = currentDisplay.workArea.top / primaryDisplay.scaleFactor; + const physicalDisplayWidth = currentDisplay.workArea.width / currentDisplay.scaleFactor; + const physicalDisplayHeight = currentDisplay.workArea.height / currentDisplay.scaleFactor; + const physicalHOffset = Math.max((physicalDisplayWidth - physicalWidth) / 2, 0); + const physicalVOffset = Math.max((physicalDisplayHeight - physicalHeight) / 2, 0); + const centeredPhysicalLeft = Math.floor(physicalDisplayLeft + physicalHOffset); + const centeredPhysicalTop = Math.floor(physicalDisplayTop + physicalVOffset); + const left = centeredPhysicalLeft * primaryDisplay.scaleFactor; + const top = centeredPhysicalTop * primaryDisplay.scaleFactor; + return { + left, + top, + width: a.width, + height: a.height + }; + } + static isNode() { + if (typeof Utils._isNode !== "undefined") { + return Utils._isNode; + } + if (typeof window !== "undefined") { + Utils._isNode = false; + return false; + } + try { + Utils._isNode = Object.prototype.toString.call(global.process) === "[object process]"; + } + catch (e) { + Utils._isNode = false; + } + return Utils._isNode; + } + static generateId() { + return nanoid(10); + } + static isPromise(value) { + return Boolean(value && typeof value.then === 'function'); + } + static isAsyncFunction(value) { + return value && {}.toString.call(value) === '[object AsyncFunction]'; + } + static isNullOrUndefined(value) { + return value === null || value === undefined; + } + static calculateTotalOverlap(r1, r2) { + const r1x = r1.left; + const r1y = r1.top; + const r1xMax = r1x + r1.width; + const r1yMax = r1y + r1.height; + const r2x = r2.left; + const r2y = r2.top; + const r2xMax = r2x + r2.width; + const r2yMax = r2y + r2.height; + const xOverlap = Math.max(0, Math.min(r1xMax, r2xMax) - Math.max(r1x, r2x)); + const yOverlap = Math.max(0, Math.min(r1yMax, r2yMax) - Math.max(r1y, r2y)); + return xOverlap * yOverlap; + } + } + + class ApplicationImpl { + constructor(_appManager, _name, _agm, _logger, _configuration) { + this._appManager = _appManager; + this._name = _name; + this._agm = _agm; + this._logger = _logger; + this._configuration = _configuration; + this._registry = CallbackRegistryFactory(); + _appManager.onInstanceStarted((instance) => { + if (instance.application && instance.application.name !== this._name) { + return; + } + this._registry.execute("instanceStarted", instance); + }); + _appManager.onInstanceStopped((instance) => { + if (instance.application && instance.application.name !== this._name) { + return; + } + this._registry.execute("instanceStopped", instance); + }); + _appManager.onAppRemoved((app) => { + if (app.name !== this._name) { + return; + } + this._registry.execute("appRemoved", app); + }); + _appManager.onAppChanged((app) => { + if (app.name !== this._name) { + return; + } + this._registry.execute("appChanged", app); + }); + _appManager.onAppAvailable((app) => { + if (app.name !== this._name) { + return; + } + this._props.IsReady = true; + this._registry.execute("appAvailable", app); + }); + _appManager.onAppUnavailable((app) => { + if (app.name !== this._name) { + return; + } + this._props.IsReady = false; + this._registry.execute("appUnavailable", app); + }); + } + get name() { return this._name; } + get title() { return this._props.Title; } + get version() { return this._props.Version; } + get autoStart() { return this._props.AutoStart; } + get isShell() { return this._props.IsShell; } + get caption() { return this._props.Caption; } + get hidden() { return this._props.IsHidden; } + get container() { return this._props.ApplicationName; } + get activityType() { return this._props.ActivityType; } + get activityWindowType() { return this._props.ActivityWindowType; } + get windowSettings() { + if (!this._props.Arguments) { + return {}; + } + return objectClone(this._props.Arguments); + } + get allowMultiple() { return this._props.AllowMultiple; } + get available() { return this._props.IsReady || true; } + get icon() { return this._props.Icon; } + get iconURL() { return this._props.IconUrl; } + get sortOrder() { return this._props.SortOrder; } + get userProperties() { + if (!this._props.UserProperties) { + return {}; + } + return objectClone(this._props.UserProperties); + } + get keywords() { + if (!this._props.Keywords) { + return []; + } + return this._props.Keywords; + } + get isActivity() { + return this._props.ActivityType !== undefined && this._props.ActivityType !== ""; + } + get configuration() { + return { + autoStart: this._props.AutoStart, + caption: this._props.Caption, + hidden: this._props.IsHidden, + container: this._props.ApplicationName, + activityType: this._props.ActivityType, + allowMultiple: this._props.AllowMultiple + }; + } + get instances() { + return this._appManager.instances().filter((instance) => instance.application.name === this._name); + } + get type() { + return this._props.Type; + } + get mode() { + if (!this._props) { + return "unknown"; + } + if (this._props.Mode && typeof this._props.Mode === "string") { + return this._props.Mode.toLowerCase(); + } + if (this.isActivity) { + return "unknown"; + } + if (this._props.Arguments && this._props.Arguments.mode && typeof this._props.Arguments.mode === "string") { + return this._props.Arguments.mode.toLowerCase(); + } + let styleAttributes = this._props.WindowStyleAttributes; + if (styleAttributes) { + styleAttributes = styleAttributes.split(" ").join(""); + const searchFor = "mode:\""; + const modeIndex = styleAttributes.indexOf(searchFor); + if (modeIndex !== -1) { + const startModeIndex = modeIndex + searchFor.length; + const stopModeIndex = styleAttributes.indexOf("\"", startModeIndex); + const style = styleAttributes.substr(startModeIndex, stopModeIndex - startModeIndex); + if (style && typeof style === "string") { + return style.toLowerCase(); + } + } + } + return "flat"; + } + async getConfiguration() { + const result = await this._agm.invoke(GetApplicationsMethodName, { v2: { apps: [this._name] } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + const config = result.returned.applications[0]; + return config; + } + updateFromProps(props) { + if (!this._props) { + this._props = { Name: props.Name }; + } + Object.keys(props).forEach((key) => { + this._props[key] = props[key]; + }); + } + start(context, options) { + return new Promise(async (resolve, reject) => { + var _a, _b, _c, _d; + if (isUndefinedOrNull(context)) { + context = {}; + } + else if (((_a = this._configuration()) === null || _a === void 0 ? void 0 : _a.throwErrors) && typeof context !== "object" || Array.isArray(context)) { + return reject(new Error(`Invalid "context" parameter - must be an object.`)); + } + if (isUndefinedOrNull(options)) { + options = {}; + } + else if (((_b = this._configuration()) === null || _b === void 0 ? void 0 : _b.throwErrors) && typeof options !== "object") { + return reject(new Error(`Invalid "options" parameter - must be an object.`)); + } + const name = this._name; + let waitForAGMInstance = (_d = ((_c = options.awaitInterop) !== null && _c !== void 0 ? _c : options.waitForAGMReady)) !== null && _d !== void 0 ? _d : true; + let startTimeout = 60000; + if (typeof options.timeout === "number") { + startTimeout = options.timeout * 1000; + } + if (options.relativeTo !== undefined && typeof options.relativeTo !== "string") { + options.relativeTo = options.relativeTo.id || ""; + } + const waitForApplicationInstance = (id) => { + let unsub; + const timeout = setTimeout(() => { + if (unsub) { + unsub(); + } + const errMsg = `timed out while waiting for instance id ${id} for app ${this.name}`; + this._logger.error(errMsg); + reject(new Error(errMsg)); + }, startTimeout); + const waitFunc = (i) => { + if (i.id !== id) { + return; + } + if (unsub) { + unsub(); + unsub = undefined; + } + clearTimeout(timeout); + resolve(i); + }; + if (waitForAGMInstance) { + const instance = this._appManager.instances().find((i) => i.id === id); + if (instance) { + unsub = instance.onAgmReady(waitFunc); + } + else { + unsub = this._appManager.onInstanceAgmServerReady(waitFunc); + } + } + else { + unsub = this._appManager.onInstanceStarted(waitFunc); + } + }; + try { + this._logger.trace(`starting application ${name} with options: ${JSON.stringify(options)}`); + const result = await this._agm.invoke(StartApplicationMethodName, { + Name: name, + Context: context, + Options: options + }, "best", { + methodResponseTimeoutMs: startTimeout, + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + const acsResult = result.returned; + if (typeof acsResult.timeout !== "undefined" && typeof options.timeout === "undefined") { + startTimeout = acsResult.timeout * 1000; + } + if (typeof acsResult.waitForInterop !== "undefined" && (typeof options.waitForAGMReady === "undefined" && typeof options.awaitInterop === "undefined")) { + waitForAGMInstance = acsResult.waitForInterop; + } + if (acsResult && acsResult.Id) { + if (this._appManager.mode === "startOnly") { + const instance = this._appManager.handleInstanceStarted({ + ActivityId: undefined, + IsActivityOwner: undefined, + Context: undefined, + Title: undefined, + AgmServers: undefined, + Id: acsResult.Id, + Name: acsResult.Name, + }); + resolve(instance); + } + else { + waitForApplicationInstance(acsResult.Id); + } + } + else { + resolve(undefined); + } + } + catch (error) { + const err = Utils.typedError(error); + reject(err); + } + }); + } + onInstanceStarted(callback) { + validate(callback, this._configuration()); + return this._registry.add("instanceStarted", callback); + } + onInstanceStopped(callback) { + validate(callback, this._configuration()); + return this._registry.add("instanceStopped", callback); + } + onAvailable(callback) { + validate(callback, this._configuration()); + if (this._props.IsReady) { + setTimeout(() => { + this._registry.execute("appAvailable", this); + }, 0); + } + return this._registry.add("appAvailable", callback); + } + onUnavailable(callback) { + validate(callback, this._configuration()); + if (this._props.IsReady === false) { + setTimeout(() => { + this._registry.execute("appUnavailable", this); + }, 0); + } + return this._registry.add("appUnavailable", callback); + } + onChanged(callback) { + validate(callback, this._configuration()); + this._registry.add("appChanged", callback); + } + onRemoved(callback) { + validate(callback, this._configuration()); + this._registry.add("appRemoved", callback); + } + } + + class InstanceImpl { + constructor(_id, _appName, _appManager, _agm, _activities, _windows, _logger, startFailed, _configuration) { + this._id = _id; + this._appName = _appName; + this._appManager = _appManager; + this._agm = _agm; + this._activities = _activities; + this._windows = _windows; + this._logger = _logger; + this._configuration = _configuration; + this._registry = CallbackRegistryFactory(); + if (startFailed) { + return; + } + this._unsubscribeInstanceStopped = this._appManager.onInstanceStopped((instance) => { + if (instance.id !== this._id) { + return; + } + this._registry.execute("stopped", instance); + }); + this._unsubscribeInstanceAgmServerReady = this._appManager.onInstanceAgmServerReady((instance) => { + if (instance.id !== this._id) { + return; + } + this._registry.execute("agmReady", instance); + }); + } + get id() { return this._id; } + get application() { return this._appManager.application(this._appName); } + get activity() { + if (!this._activities) { + throw new Error("This method requires glue.activities library to be enabled."); + } + return this._activities.all.instances.get() + .filter((activityInstance) => activityInstance.id === this._activityId)[0]; + } + get isActivityOwner() { return this._isActivityOwner; } + get activityInstances() { + return this._appManager.instances().filter((i) => i.application.type !== "activity" && + i.activityId && + i.activityId === this._activityId); + } + get activityOwnerInstance() { + if (!this._activityId) { + return undefined; + } + return this.activityInstances.filter((inst) => inst === null || inst === void 0 ? void 0 : inst.isActivityOwner)[0]; + } + get window() { + if (!this._windows) { + throw new Error("This method requires glue.windows library to be enabled."); + } + let win = this._windows.list().find((w) => w.id === this._id); + if (!win && this._activities && this.activity && this.activityOwnerInstance) { + win = this.activityOwnerInstance.window; + } + return win; + } + get context() { + var _a, _b, _c; + return (_c = (_a = this._startUpContext) !== null && _a !== void 0 ? _a : (_b = this.window) === null || _b === void 0 ? void 0 : _b.context) !== null && _c !== void 0 ? _c : {}; + } + get title() { return this._title; } + get isActivityInstance() { return this._isActivityInstance; } + get activityId() { return this._activityId; } + get inActivity() { return this._inActivity; } + get isSingleWindowApp() { return !this._inActivity; } + get agm() { + return this._agmInstance; + } + get interopInstance() { + return this._agmInstance; + } + onInteropReady(callback) { + validate(callback, this._configuration()); + if (this._agmInstance) { + setTimeout(() => { + this._registry.execute("agmReady", this); + }, 0); + } + return this._registry.add("agmReady", callback); + } + onAgmReady(callback) { + return this.onInteropReady(callback); + } + onStopped(callback) { + validate(callback, this._configuration()); + return this._registry.add("stopped", callback); + } + getWindow() { + return new Promise((resolve, reject) => { + const result = this.window; + if (result) { + resolve(result); + return; + } + const done = (error, window) => { + if (error) { + reject(error); + } + if (window) { + resolve(window); + } + setTimeout(() => { + clearTimeout(timeout); + unsub(); + }, 0); + }; + this._logger.trace(`waiting for window with id ${this._id} to appear`); + const timeoutInSeconds = 60; + const timeout = setTimeout(() => { + this._logger.trace(`window with id ${this._id} did not appear in ${timeoutInSeconds} sec`); + done(new Error(`can not find a window with id ${this._id}`)); + }, timeoutInSeconds * 1000); + const unsub = this._windows.onWindowAdded((w) => { + if (w.id === this._id) { + this._logger.trace(`window with id ${this._id} appeared`); + done(undefined, w); + } + }); + }); + } + updateFromProps(props) { + this._startUpContext = props.Context; + this._title = props.Title; + this._isActivityInstance = false; + if (props.ActivityId && props.ActivityId !== "") { + this._activityId = props.ActivityId; + this._isActivityInstance = true; + } + this._isActivityOwner = props.IsActivityOwner; + if (!this._activityId && this._startUpContext && this._startUpContext.activityId) { + this._activityId = this._startUpContext.activityId; + } + this._inActivity = Boolean(this._activityId); + this.updateAgmInstanceFromProps(props); + } + updateAgmInstanceFromProps(props) { + if (!props.AgmServers) { + return; + } + const agmInstances = props.AgmServers; + if (agmInstances && agmInstances.length > 0 && !isUndefinedOrNull(agmInstances[0])) { + this._agmInstance = agmInstances[0]; + } + } + stop() { + return new Promise((resolve, reject) => { + let idToResolve = this._id; + if (this.isActivityOwner) { + idToResolve = this.activityId; + } + const unsubscribe = this._appManager.onInstanceStopped((instance) => { + if (instance.id === idToResolve) { + this._logger.trace(`instance with id ${idToResolve} stopped`); + unsubscribe(); + resolve(); + } + }); + this._logger.trace(`stopping instance with id ${this._id}`); + this._agm.invoke(StopApplicationMethodName, { + Name: this._appName, + Id: this._id + }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }) + .then(() => { + if (this._appManager.mode === "startOnly") { + this._appManager.handleInstanceStopped({ + Name: this._appName, + Id: this.id + }); + resolve(); + } + }) + .catch((err) => reject(err)); + }); + } + activate() { + return this._agm.invoke(ActivateApplicationMethodName, { Name: this._appName, Id: this._id }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + done() { + this._registry.clear(); + this._unsubscribeInstanceAgmServerReady(); + this._unsubscribeInstanceStopped(); + } + getContext() { + return Promise.resolve(this.context); + } + async startedBy() { + const result = await this._agm.invoke(ACSExecute, { command: "getStartedBy", Name: this._appName, Id: this._id }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return result.returned; + } + } + + class AppManagerImpl { + constructor(mode, _agm, _activities, _windows, _logger, _gdMajorVersion, _configuration) { + this.mode = mode; + this._agm = _agm; + this._activities = _activities; + this._windows = _windows; + this._logger = _logger; + this._gdMajorVersion = _gdMajorVersion; + this._configuration = _configuration; + this._apps = {}; + this._instances = []; + this._registry = CallbackRegistryFactory(); + this.getConfigurations = async (apps) => { + const args = { + v2: { + apps: undefined + } + }; + if (Array.isArray(apps)) { + args.v2 = { + apps + }; + } + const result = await this._agm.invoke(GetApplicationsMethodName, args, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return result.returned.applications; + }; + this.application = (name) => { + var _a; + if (((_a = this._configuration()) === null || _a === void 0 ? void 0 : _a.throwErrors) && typeof name !== "string" || isNullOrWhiteSpace(name)) { + throw new Error(`"name" must be string`); + } + return this._apps[name]; + }; + this.applications = () => { + return Object.keys(this._apps).map((k) => this._apps[k]); + }; + this.instances = () => { + return this._instances.map((i) => i); + }; + this.getMyInstance = () => { + const glue42gd = typeof window !== "undefined" && window.glue42gd; + if (glue42gd) { + if (this._gdMajorVersion >= 3) { + const instanceId = glue42gd.appInstanceId; + return this._instances.find((i) => i.id === instanceId); + } + } + else { + const instanceId = this._agm.instance.instance; + return this._instances.find((i) => i.id === instanceId); + } + return undefined; + }; + this.getMyApplication = () => { + var _a; + if (this._agm.instance) { + return (_a = this.application(this._agm.instance.applicationName)) !== null && _a !== void 0 ? _a : this.application(this._agm.instance.application); + } + }; + this.handleSnapshotAppsAdded = (newApps) => { + const currentApps = this.applications(); + if (currentApps.length > 0) { + currentApps.forEach((item) => { + const name = item.name; + const alreadyExists = newApps.find((i) => i.Name === item.name); + if (!alreadyExists) { + this.handleAppRemoved({ Name: name }); + } + }); + } + newApps.forEach((item) => { + const alreadyExists = currentApps.find((i) => i.name === item.Name); + if (!alreadyExists) { + this.handleAppAdded(item); + } + }); + }; + this.handleSnapshotInstanceStarted = (newInstances) => { + const currentInstances = this.instances(); + if (currentInstances.length > 0) { + currentInstances.forEach((item) => { + const id = item.id; + const alreadyExists = newInstances.find((i) => i.Id === id); + if (!alreadyExists) { + this.handleInstanceStopped({ Name: item.application.name, Id: id }); + } + }); + } + newInstances.forEach((item) => { + const alreadyExists = currentInstances.find((i) => i.id === item.Id); + if (!alreadyExists) { + this.handleInstanceStarted(item); + } + }); + }; + this.handleAppAdded = (props) => { + const id = this._getAppId(props); + this._logger.trace(`adding app ${id}`); + this._apps[id] = new ApplicationImpl(this, id, this._agm, this._logger, this._configuration); + const app = this._updateAppFromProps(props); + this._registry.execute("appAdded", app); + this._registry.execute("appAvailable", app); + }; + this.handleAppUpdated = (props) => { + const app = this._updateAppFromProps(props); + this._registry.execute("appChanged", app); + }; + this.handleAppRemoved = (props) => { + const id = this._getAppId(props); + this._logger.trace(`removing app ${id}`); + const app = this.application(id); + this._instances = this._instances.filter((i) => i.application.name !== app.name); + delete this._apps[id]; + this._registry.execute("appRemoved", app); + }; + this.handleAppReady = (props) => { + const id = this._getAppId(props); + const app = this._getAppOrThrow(id); + app.updateFromProps(props); + if (app.available) { + this._registry.execute("appAvailable", app); + } + else { + this._registry.execute("appUnavailable", app); + } + }; + this.handleInstanceStarted = (props) => { + this._logger.trace(`started app ${props.Name} ${props.Id}`); + const id = this._getInstanceId(props); + const appName = this._getInstanceAppName(props); + const instance = new InstanceImpl(id, appName, this, this._agm, this._activities, this._windows, this._logger, false, this._configuration); + this._updateInstanceFromProps(instance, props); + this._instances.push(instance); + this._registry.execute("instanceStarted", instance); + return instance; + }; + this.handleInstanceStopped = (props) => { + this._logger.trace(`instance stopped ${props.Name} ${props.Id}`); + const id = this._getInstanceId(props); + const appName = this._getInstanceAppName(props); + const instance = this._getInstanceOrThrow(id, appName); + this._instances = this._instances.filter((i) => !this._matchInstance(i, id, appName)); + this._registry.execute("instanceStopped", instance); + instance.done(); + }; + this.handleInstanceAgmServerReady = (props) => { + this._logger.trace(`instance interop server ready ${props.Name} ${props.Id}`); + const id = this._getInstanceId(props); + const appName = this._getInstanceAppName(props); + const instance = this._getInstanceOrThrow(id, appName); + instance.updateAgmInstanceFromProps(props); + this._registry.execute("instanceAgmServerReady", instance); + }; + this.handleInstanceStartFailed = (props) => { + const id = this._getInstanceId(props); + const appName = this._getInstanceAppName(props); + const startFailed = true; + const instance = new InstanceImpl(id, appName, undefined, undefined, undefined, undefined, this._logger, startFailed, this._configuration); + this._updateInstanceFromProps(instance, props); + this._registry.execute("instanceStartFailed", instance); + }; + this.handleInstanceUpdated = (props) => { + const id = this._getInstanceId(props); + const app = this._getInstanceAppName(props); + const instance = this._getInstanceOrThrow(id, app); + this._updateInstanceFromProps(instance, props); + }; + this.onInstanceStarted = (callback) => { + validate(callback, this._configuration()); + return this._registry.add("instanceStarted", callback, this._instances); + }; + this.onInstanceStartFailed = (callback) => { + validate(callback, this._configuration()); + return this._registry.add("instanceStartFailed", callback); + }; + this.onInstanceStopped = (callback) => { + validate(callback, this._configuration()); + return this._registry.add("instanceStopped", callback); + }; + this.onInstanceUpdated = (callback) => { + validate(callback, this._configuration()); + return this._registry.add("instanceChanged", callback); + }; + this.onInstanceAgmServerReady = (callback) => { + validate(callback, this._configuration()); + return this._registry.add("instanceAgmServerReady", callback); + }; + this.onAppAdded = (callback) => { + validate(callback, this._configuration()); + return this._registry.add("appAdded", callback, Object.values(this._apps)); + }; + this.onAppRemoved = (callback) => { + validate(callback, this._configuration()); + return this._registry.add("appRemoved", callback); + }; + this.onAppAvailable = (callback) => { + validate(callback, this._configuration()); + return this._registry.add("appAvailable", callback); + }; + this.onAppUnavailable = (callback) => { + validate(callback, this._configuration()); + return this._registry.add("appUnavailable", callback); + }; + this.onAppChanged = (callback) => { + validate(callback, this._configuration()); + return this._registry.add("appChanged", callback); + }; + } + _getAppOrThrow(id) { + const result = this.application(id); + if (!result) { + throw Error(`app with id ${id} not found`); + } + return result; + } + _getAppId(props) { + return props.Name; + } + _matchInstance(instance, id, appName) { + return instance.id === id && instance.application.name === appName; + } + _getInstanceByIdAndName(id, appName) { + return this._instances.filter((i) => this._matchInstance(i, id, appName))[0]; + } + _getInstanceOrThrow(id, appName) { + const result = this._getInstanceByIdAndName(id, appName); + if (!result) { + throw Error(`instance with id ${id} not found`); + } + return result; + } + _getInstanceId(props) { + return props.Id; + } + _getInstanceAppName(props) { + return props.Name; + } + _updateAppFromProps(props) { + const id = this._getAppId(props); + this._logger.trace(`updating app with + ${id}, ${JSON.stringify(props)}`); + const app = this._getAppOrThrow(id); + app.updateFromProps(props); + return app; + } + _updateInstanceFromProps(instance, props) { + this._logger.trace("updating instance with " + this._getInstanceId(props) + " for app " + this._getInstanceAppName(props)); + instance.updateFromProps(props); + } + } + + function promisify(promise, successCallback, errorCallback) { + const isFunction = (arg) => { + return !!(arg && arg.constructor && arg.call && arg.apply); + }; + if (!isFunction(successCallback) && !isFunction(errorCallback)) { + return promise; + } + if (!isFunction(successCallback)) { + successCallback = () => { + }; + } + else if (!isFunction(errorCallback)) { + errorCallback = () => { + }; + } + return promise.then(successCallback, errorCallback); + } + class EntitlementsImpl { + constructor(_agm) { + this._agm = _agm; + this._registry = CallbackRegistryFactory(); + this._isMethodRegistered = false; + this.handleBranchModified = (branch) => { + this._registry.execute("branchChanged", branch); + }; + this.handleBranchesModified = (branches) => { + this._registry.execute("branchesChanged", branches); + }; + this.getRegion = (success, error) => { + return promisify(this._agmInvoke(GetConfigurationRegionMethodName, (e) => e.returned.Region), success, error); + }; + this.getBranches = (success, error) => { + const promise = this._agmInvoke(GetBranchesMethodName, (e) => { + const obj = e.returned.Branches; + return Object.keys(obj).map((key) => obj[key]); + }); + return promisify(promise, success, error); + }; + this.getCurrentBranch = (success, error) => { + const promise = this._agmInvoke(GetCurrentBranchMethodName, (e) => e.returned.Branch, undefined); + return promisify(promise, success, error); + }; + this.setRegion = (region, success, error) => { + const promise = this._agmInvoke(SetConfigurationRegionMethodName, (e) => e.returned.ResultMessage, { Region: region }); + return promisify(promise, success, error); + }; + this.setCurrentBranch = (branch, success, error) => { + const promise = this._agmInvoke(SetCurrentBranchMethodName, (e) => e.returned.ResultMessage, { Branch: branch }); + return promisify(promise, success, error); + }; + this.currentUser = (success, error) => { + const promise = this._agmInvoke(GetUserMethodName); + return promisify(promise, success, error); + }; + this.getFunctionalEntitlement = (funct, success, error) => { + const promise = this._agmInvoke(GetFunctionalEntitlementMethodName, (e) => e.returned.Entitlement, { Function: funct }); + return promisify(promise, success, error); + }; + this.getFunctionalEntitlementBranch = (funct, branch, success, error) => { + const promise = this._agmInvoke(GetFunctionalEntitlementMethodName, (e) => e.returned.Entitlement, { Function: funct, Branch: branch }); + return promisify(promise, success, error); + }; + this.canI = (func, success, error) => { + const promise = this._agmInvoke(CanIMethodName, (e) => e.returned.Result, { Function: func }); + return promisify(promise, success, error); + }; + this.canIBranch = (func, branch, success, error) => { + const promise = this._agmInvoke(CanIMethodName, (e) => e.returned.Result, { Function: func, Branch: branch }); + return promisify(promise, success, error); + }; + this.onBranchesChanged = (callback) => { + return this._registry.add("branchesChanged", callback); + }; + this.onBranchChanged = (callback) => { + return this._registry.add("branchChanged", callback); + }; + this.exit = (options) => { + return this._agmInvoke(ShutdownMethodName, null, options); + }; + this.onShuttingDown = (callback) => { + this.registerMethod(); + return this._registry.add("onShuttingDown", callback); + }; + this.restart = (options) => { + return this._agmInvoke(RestartMethodName, null, options); + }; + this._agmInvoke = (method, transformFunction, args) => { + args = args || {}; + return new Promise((resolve, reject) => { + const errHandler = (error) => reject(error); + this._agm.invoke(method, args, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }) + .then((result) => { + if (!transformFunction) { + transformFunction = (d) => d.returned; + } + resolve(transformFunction(result)); + }) + .catch(errHandler); + }); + }; + } + registerMethod() { + if (!this._isMethodRegistered) { + this._agm.register(OnGDShutdownMethodName, async (args) => { + try { + const results = await Promise.all(this._registry.execute("onShuttingDown", args)); + const prevent = results.some((r) => r.prevent); + return { prevent }; + } + catch (error) { + } + }); + this._isMethodRegistered = true; + } + } + } + + function snapshot(interop, appManager) { + return new Promise((resolve, reject) => { + interop.invoke(GetApplicationsMethodName, { skipIcon: true }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }) + .then((response) => { + var _a; + const data = response.returned; + const configuration = (_a = response.returned.configuration) !== null && _a !== void 0 ? _a : {}; + if (!data) { + resolve(configuration); + } + const applications = data.applications; + if (!applications) { + resolve(configuration); + } + objectValues(applications).map((item) => appManager.handleAppAdded(item)); + resolve(configuration); + }) + .catch((err) => reject(new Error(`Error getting application snapshot: ${err.message}`))); + }); + } + + const OnBranchChangedEvent = "OnBranchChanged"; + const OnBranchesModifiedEvent = "OnBranchesModified"; + const OnApplicationAddedEvent = "OnApplicationAdded"; + const OnApplicationRemovedEvent = "OnApplicationRemoved"; + const OnApplicationChangedEvent = "OnApplicationChanged"; + const OnApplicationReadyEvent = "OnApplicationReady"; + const OnApplicationStartedEvent = "OnApplicationStarted"; + const OnApplicationAgmServerReadyEvent = "OnApplicationAgmServerReady"; + const OnApplicationUpdatedEvent = "OnApplicationUpdated"; + const OnApplicationStoppedEvent = "OnApplicationStopped"; + const OnApplicationStartFailedEvent = "OnApplicationStartFailed"; + + function createDataSubscription(agm, applications, entitlements, skipIcons) { + let subscription; + let initiated = false; + const start = () => { + let resolveFunc; + let rejectFunc; + const resultPromise = new Promise((resolve, reject) => { + resolveFunc = resolve; + rejectFunc = reject; + }); + agm.subscribe(OnEventMethodName, { arguments: { skipIcon: skipIcons }, waitTimeoutMs: 10000 }) + .then((s) => { + subscription = s; + subscription.onData((streamData) => { + var _a; + const events = streamData.data; + const configuration = (_a = events.configuration) !== null && _a !== void 0 ? _a : {}; + const onApplicationAddedEventArgs = objectValues(events[OnApplicationAddedEvent]); + if (streamData.data.isSnapshot) { + applications.handleSnapshotAppsAdded(onApplicationAddedEventArgs); + } + else { + onApplicationAddedEventArgs.forEach((item) => applications.handleAppAdded(item)); + } + objectValues(events[OnApplicationChangedEvent]) + .forEach((item) => applications.handleAppUpdated(item)); + objectValues(events[OnApplicationRemovedEvent]) + .forEach((item) => applications.handleAppRemoved(item)); + objectValues(events[OnApplicationReadyEvent]) + .forEach((item) => applications.handleAppReady(item)); + const onApplicationStartedEventArgs = objectValues(events[OnApplicationStartedEvent]); + if (streamData.data.isSnapshot) { + applications.handleSnapshotInstanceStarted(onApplicationStartedEventArgs); + } + else { + onApplicationStartedEventArgs.forEach((item) => applications.handleInstanceStarted(item)); + } + objectValues(events[OnApplicationStartFailedEvent]) + .forEach((item) => applications.handleInstanceStartFailed(item)); + objectValues(events[OnApplicationStoppedEvent]) + .forEach((item) => applications.handleInstanceStopped(item)); + objectValues(events[OnApplicationUpdatedEvent]) + .forEach((item) => applications.handleInstanceUpdated(item)); + objectValues(events[OnApplicationAgmServerReadyEvent]) + .forEach((item) => applications.handleInstanceAgmServerReady(item)); + objectValues(events[OnBranchChangedEvent]) + .forEach((item) => entitlements.handleBranchModified(item)); + objectValues(events[OnBranchesModifiedEvent]) + .forEach((item) => entitlements.handleBranchesModified(item)); + if (!initiated) { + initiated = true; + const hasMyAppInSnapShot = onApplicationAddedEventArgs.some((a) => a.Name === agm.instance.application); + const hasMyInstanceInSnapShot = onApplicationStartedEventArgs.some((i) => i.Id === agm.instance.instance); + if (hasMyAppInSnapShot) { + if (hasMyInstanceInSnapShot) { + resolveFunc(configuration); + } + else { + const un = applications.onInstanceStarted((i) => { + if (i.id === agm.instance.instance) { + un(); + resolveFunc(configuration); + } + }); + } + } + else { + resolveFunc(configuration); + } + } + }); + subscription.onFailed((err) => rejectFunc(err)); + }) + .catch((err) => { var _a; return rejectFunc(`Error subscribing for ${OnEventMethodName} stream. Err: ${(_a = err.message) !== null && _a !== void 0 ? _a : JSON.stringify(err)}`); }); + return resultPromise; + }; + const stop = () => { + if (subscription) { + subscription.close(); + } + }; + return { + start, + stop + }; + } + + const InMemoryStoreCommandMethodName = "T42.ACS.InMemoryStoreCommand"; + class InMemoryStore { + constructor(interop) { + this.interop = interop; + } + import(apps, mode) { + if (!apps || !Array.isArray(apps)) { + return Promise.reject(new Error("invalid apps argument - should be an array of application definitions")); + } + if (mode && mode !== "replace" && mode !== "merge") { + return Promise.reject(new Error("invalid mode argument - should be 'replace' or 'merge'")); + } + mode = mode !== null && mode !== void 0 ? mode : "replace"; + const command = { + command: "import", + args: { + apps, + mode + } + }; + return this.interop.invoke(InMemoryStoreCommandMethodName, command, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }) + .then((r) => r.returned); + } + export() { + return this.interop.invoke(InMemoryStoreCommandMethodName, { command: "export" }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }) + .then((r) => r.returned.apps); + } + remove(app) { + if (!app || typeof app !== "string") { + return Promise.reject(new Error("invalid app name, should be a string value")); + } + const command = { + command: "remove", + args: { + apps: [app] + } + }; + return this.interop.invoke(InMemoryStoreCommandMethodName, command, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }).then((r) => r.returned); + } + clear() { + const command = { + command: "clear" + }; + return this.interop.invoke(InMemoryStoreCommandMethodName, command, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }).then((r) => r.returned); + } + createAppDef(name, url) { + if (!url) { + url = "https://google.com"; + } + return { + name, + type: "window", + title: name, + details: { + url + } + }; + } + } + + var AppManagerFactory = (config) => { + if (!config) { + throw Error("config not set"); + } + if (!config.agm) { + throw Error("config.agm is missing"); + } + const START_ONLY = "startOnly"; + const SKIP_ICONS = "skipIcons"; + const FULL = "full"; + const mode = config.mode || START_ONLY; + if (mode !== START_ONLY && mode !== SKIP_ICONS && mode !== FULL) { + throw new Error(`Invalid mode for appManager lib - ${mode} is not supported`); + } + const activities = config.activities; + const agm = config.agm; + const logger = config.logger; + const windows = config.windows; + let configuration = {}; + const appManager = new AppManagerImpl(mode, agm, activities, windows, logger.subLogger("applications"), config.gdMajorVersion, () => configuration); + const entitlements = new EntitlementsImpl(agm); + let readyPromise; + if (mode === START_ONLY) { + readyPromise = snapshot(agm, appManager); + } + else { + const subscription = createDataSubscription(agm, appManager, entitlements, mode === SKIP_ICONS); + readyPromise = subscription.start(); + } + const api = { + ready: () => readyPromise.then((c) => { configuration = c; }), + applications: appManager.applications, + application: appManager.application, + getConfigurations: appManager.getConfigurations, + onAppAdded: appManager.onAppAdded, + onAppRemoved: appManager.onAppRemoved, + onAppChanged: appManager.onAppChanged, + onAppAvailable: appManager.onAppAvailable, + onAppUnavailable: appManager.onAppUnavailable, + instances: appManager.instances, + get myInstance() { + return appManager.getMyInstance(); + }, + get myApplication() { + return appManager.getMyApplication(); + }, + onInstanceStarted: appManager.onInstanceStarted, + onInstanceStopped: appManager.onInstanceStopped, + onInstanceUpdated: appManager.onInstanceUpdated, + onInstanceStartFailed: appManager.onInstanceStartFailed, + getRegion: entitlements.getRegion, + getBranches: entitlements.getBranches, + getCurrentBranch: entitlements.getCurrentBranch, + getFunctionalEntitlement: entitlements.getFunctionalEntitlement, + getFunctionalEntitlementBranch: entitlements.getFunctionalEntitlementBranch, + setCurrentBranch: entitlements.setCurrentBranch, + setRegion: entitlements.setRegion, + currentUser: entitlements.currentUser, + canI: entitlements.canI, + canIBranch: entitlements.canIBranch, + onBranchesChanged: entitlements.onBranchesChanged, + exit: entitlements.exit, + restart: entitlements.restart, + onShuttingDown: entitlements.onShuttingDown, + inMemory: new InMemoryStore(agm) + }; + return api; + }; + + const T42JumpListAction = "T42.JumpList.Action"; + class JumpListManager { + constructor() { + this._groupActionCallbacks = new Map(); + this._registered = false; + } + init(executor, agm, logger) { + this._executor = executor; + this._agm = agm; + this._logger = logger; + this.registerCallbackMethod(); + } + setEnabled(windowId, enabled) { + const settings = { + enabled + }; + return this._executor.updateJumpList(windowId, settings); + } + createCategory(windowId, title, actions) { + this.validateActions(title, actions); + const settings = { + category: { + title, + operation: "create", + actions: this.toUpdateActions(windowId, "create", title, actions) + } + }; + return this._executor.updateJumpList(windowId, settings); + } + removeCategory(windowId, title) { + const settings = { + category: { + title, + operation: "remove", + actions: [] + } + }; + this.manageActionCallback(windowId, settings.category.operation, title); + return this._executor.updateJumpList(windowId, settings); + } + createActions(windowId, categoryTitle, actions) { + this.validateActions(categoryTitle, actions); + const settings = { + category: { + title: categoryTitle, + operation: "update", + actions: this.toUpdateActions(windowId, "create", categoryTitle, actions) + } + }; + return this._executor.updateJumpList(windowId, settings); + } + removeActions(windowId, categoryTitle, actions) { + const settings = { + category: { + title: categoryTitle, + operation: "update", + actions: this.toUpdateActions(windowId, "remove", categoryTitle, actions) + } + }; + return this._executor.updateJumpList(windowId, settings); + } + async getActions(windowId, catgoryTitle) { + const actions = []; + const configuration = await this.getJumpListSettings(windowId); + const currentCategory = configuration.categories.find((category) => category.title === catgoryTitle); + if (currentCategory) { + currentCategory.actions.forEach((action) => { + const actionCallback = this.getActionCallback(action.callbackId); + if (actionCallback) { + action.callback = actionCallback.callback; + } + actions.push({ + icon: action.icon, + callback: action.callback, + singleInstanceTitle: action.singleInstanceTitle, + multiInstanceTitle: action.multiInstanceTitle + }); + }); + } + return Promise.resolve(actions); + } + getJumpListSettings(windowId) { + return this._executor.getJumpList(windowId); + } + toUpdateActions(windowId, operation, categoryTitle, actions) { + return actions.map((action) => { + const updateAction = { + icon: action.icon, + callback: action.callback, + callbackId: Utils.generateId(), + singleInstanceTitle: action.singleInstanceTitle, + multiInstanceTitle: action.multiInstanceTitle, + operation + }; + this.manageActionCallback(windowId, operation, categoryTitle, updateAction); + return updateAction; + }); + } + manageActionCallback(windowId, operation, categoryTitle, updateAction) { + var _a; + const groupCallbacksKey = `${categoryTitle}-${windowId}`; + if (operation === "create") { + if (!this._groupActionCallbacks.has(groupCallbacksKey)) { + this._groupActionCallbacks.set(groupCallbacksKey, []); + } + const categoryActionCallbacks = this._groupActionCallbacks.get(groupCallbacksKey); + categoryActionCallbacks.push({ + callbackId: updateAction.callbackId, + callback: updateAction.callback + }); + } + else if (operation === "remove") { + if (updateAction) { + let categoryActionCallbacks = (_a = this._groupActionCallbacks.get(groupCallbacksKey)) !== null && _a !== void 0 ? _a : []; + categoryActionCallbacks = categoryActionCallbacks.filter((accCal) => accCal.callbackId !== updateAction.callbackId); + if (categoryActionCallbacks.length === 0) { + this._groupActionCallbacks.delete(groupCallbacksKey); + } + else { + this._groupActionCallbacks.set(groupCallbacksKey, categoryActionCallbacks); + } + } + else { + this._groupActionCallbacks.delete(groupCallbacksKey); + } + } + } + registerCallbackMethod() { + if (this._registered) { + return; + } + this._registered = true; + try { + this._agm.register(T42JumpListAction, (args, caller) => { + const actionCallback = this.getActionCallback(args.callbackId); + if (actionCallback) { + try { + actionCallback.callback(); + } + catch (e) { + this._logger.error("Unable to execute user callback for jump list action!", e); + } + } + }); + } + catch (e) { + this._logger.error(`Unable to register method ${T42JumpListAction} for invoking jump list action callbacks!`, e); + return Promise.reject(e); + } + } + getActionCallback(callbackId) { + let callbackAction; + [...this._groupActionCallbacks.values()].forEach((callbacks) => { + const callback = callbacks.find((cal) => cal.callbackId === callbackId); + if (callback) { + callbackAction = callback; + } + }); + return callbackAction; + } + validateActions(category, actions) { + if (!(actions && actions.length > 0)) { + throw new Error(`Category '${category}' doesn't contain any actions!`); + } + actions.forEach((action) => { + if (!action.singleInstanceTitle) { + throw new Error(`Category '${category}' contains an action with undefined singleInstanceTitle!`); + } + if (!action.multiInstanceTitle) { + throw new Error(`Category '${category}' contains an action with undefined multiInstanceTitle!`); + } + if (!action.callback) { + throw new Error(`Category '${category}' contains an action with undefined callback function!`); + } + }); + } + } + var jumpListManager = new JumpListManager(); + + class WindowStore { + constructor() { + this.waitForTimeoutInMilliseconds = 60000; + this._windows = {}; + this._pendingWindows = {}; + this._pendingWindowsStates = {}; + this._registry = CallbackRegistryFactory(); + } + init(logger) { + this._logger = logger; + } + get(id) { + return this._windows[id] || this._pendingWindows[id]; + } + getIfReady(id) { + return this._windows[id]; + } + get list() { + return this._windows; + } + add(window, state) { + const isExist = typeof this._pendingWindows[window.API.id] !== "undefined"; + if (isExist) { + this._logger.error(`trying to add window with id ${window.API.id} from windowStore, which already exists`); + return; + } + this._pendingWindows[window.API.id] = window; + this._pendingWindowsStates[window.API.id] = state; + this._registry.execute("on-added", window); + if (this.shouldMarkReadyToShow(state)) { + this.markReadyToShow(window.API.id); + } + } + remove(window) { + delete this._windows[window.API.id]; + delete this._pendingWindows[window.API.id]; + delete this._pendingWindowsStates[window.API.id]; + this._registry.execute("on-removed", window); + } + setUrlChangedState(windowId) { + const targetWindowState = this._pendingWindowsStates[windowId]; + if (typeof targetWindowState === "undefined") { + return; + } + targetWindowState.urlChanged = true; + if (this.shouldMarkReadyToShow(targetWindowState)) { + this.markReadyToShow(windowId); + } + } + setCompositionChangedState(wrapper) { + const windowId = wrapper.API.id; + const targetWindowState = this._pendingWindowsStates[windowId]; + if (typeof targetWindowState === "undefined") { + return; + } + targetWindowState.compositionChanged = true; + if (this.shouldMarkReadyToShow(targetWindowState)) { + this.markReadyToShow(windowId); + } + } + waitFor(id) { + return new Promise((resolve, reject) => { + let unReady; + let unRemoved; + const timeout = setTimeout(() => { + unReady(); + unRemoved(); + reject(new Error(`Window with id "${id}" was not ready within ${this.waitForTimeoutInMilliseconds} milliseconds.`)); + }, this.waitForTimeoutInMilliseconds); + const win = this._windows[id]; + if (win) { + clearTimeout(timeout); + resolve(win); + } + else { + const cleanup = () => { + clearTimeout(timeout); + unReady(); + unRemoved(); + }; + unReady = this.onReadyWindow((w) => { + if (w.API.id !== id) { + return; + } + cleanup(); + resolve(w); + }); + unRemoved = this.onRemoved((w) => { + if (w.API.id !== id) { + return; + } + cleanup(); + reject(new Error(`Window with id "${id}" was closed before it became ready.`)); + }); + } + }); + } + onReadyWindow(callback) { + return this._registry.add("on-ready", callback); + } + onAdded(callback) { + return this._registry.add("on-added", callback); + } + onRemoved(callback) { + return this._registry.add("on-removed", callback); + } + markReadyToShow(windowId) { + if (this._pendingWindows[windowId]) { + this._windows[windowId] = this._pendingWindows[windowId]; + delete this._pendingWindows[windowId]; + delete this._pendingWindowsStates[windowId]; + } + this._registry.execute("on-ready", this._windows[windowId]); + } + shouldMarkReadyToShow(targetWindowState) { + return targetWindowState && targetWindowState.urlChanged && targetWindowState.ready && targetWindowState.compositionChanged; + } + } + var windowStore = new WindowStore(); + + class JumpListActions { + constructor(windowId, configuration) { + this.windowId = windowId; + this._categoryTitle = configuration.title; + } + list() { + return jumpListManager.getActions(this.windowId, this._categoryTitle); + } + create(actions) { + return jumpListManager.createActions(this.windowId, this._categoryTitle, actions); + } + remove(actions) { + return jumpListManager.removeActions(this.windowId, this._categoryTitle, actions); + } + } + + class JumpListCategories { + constructor(windowId) { + this.windowId = windowId; + } + list() { + return this.getCategories(); + } + create(title, actions) { + return jumpListManager.createCategory(this.windowId, title, actions); + } + remove(title) { + return jumpListManager.removeCategory(this.windowId, title); + } + async find(title) { + const categories = await this.getCategories(); + return categories.find((cat) => cat.title === title); + } + async getCategories() { + const result = []; + const configuration = await jumpListManager.getJumpListSettings(this.windowId); + configuration.categories.forEach((category) => { + result.push({ + title: category.title, + actions: new JumpListActions(this.windowId, category) + }); + }); + return result; + } + } + + class JumpList { + constructor(windowId) { + this.windowId = windowId; + this._categories = new JumpListCategories(windowId); + } + get categories() { + return this._categories; + } + async isEnabled() { + const configuration = await jumpListManager.getJumpListSettings(this.windowId); + return configuration.enabled; + } + setEnabled(enabled) { + return jumpListManager.setEnabled(this.windowId, enabled); + } + } + + var windowFactory = (id, options, executor, logger, appManagerGetter, displayAPIGetter, channelsAPIGetter, agm) => { + var _a, _b, _c, _d; + const _registry = CallbackRegistryFactory(); + const getChannels = () => { + const channels = channelsAPIGetter(); + if (!channels) { + throw new Error(`To use this method you need to enable channels API - set the channels property to true when initializing the Glue42 library`); + } + return channels; + }; + const _id = id; + const _name = options.name; + const _mode = options.mode; + let _bounds = options.bounds; + let _url = options.url; + let _title = options.title; + let _context = (_a = options.context) !== null && _a !== void 0 ? _a : {}; + let _frameColor = options.frameColor; + let _focus = options.focus; + let _neighbours = (_b = options.neighbours) !== null && _b !== void 0 ? _b : {}; + let _groupId = options.groupId; + let _isGroupHeaderVisible = options.isGroupHeaderVisible; + let _isTabHeaderVisible = options.isTabHeaderVisible; + let _isGroupHibernated = options.isGroupHibernated; + let _isGroupVisible = options.isGroupVisible; + let _isTabSelected = (_c = options.isTabSelected) !== null && _c !== void 0 ? _c : false; + let _settings = options.settings; + const _applicationName = options.applicationName; + let _isVisible = options.isVisible; + let _isSticky = options.isSticky; + let _isCollapsed = options.isCollapsed; + let _windowState = options.state; + let _tabGroupId = options.tabGroupId; + let _tabIndex = options.tabIndex; + let _frameId = options.frameId; + let _isLocked = options.isLocked; + let _allowWorkspaceDrop = options.allowWorkspaceDrop; + let _isPinned = options.isPinned; + let _group; + let _frameButtons = (_d = options.frameButtons) !== null && _d !== void 0 ? _d : []; + let _zoomFactor = options.zoomFactor; + let _placementSettings = options.placementSettings; + const _jumpList = new JumpList(id); + function close(cbOrOptions, error) { + if (typeof cbOrOptions === "undefined" || typeof cbOrOptions === "function") { + return Utils.callbackifyPromise(() => { + if (!id) { + throw new Error("The window is already closed."); + } + return executor.close(resultWindow); + }, cbOrOptions, error); + } + else { + return executor.close(resultWindow, cbOrOptions); + } + } + function navigate(newUrl, optionsOrCallback, error) { + if (typeof optionsOrCallback === "function") { + return Utils.callbackifyPromise(() => { + if (isNullOrWhiteSpace(newUrl)) { + throw new Error("The new URL must be a non-empty string."); + } + return executor.navigate(resultWindow, newUrl); + }, optionsOrCallback, error); + } + if (isNullOrWhiteSpace(newUrl)) { + throw new Error("The new URL must be a non-empty string."); + } + if ((optionsOrCallback === null || optionsOrCallback === void 0 ? void 0 : optionsOrCallback.timeout) && typeof optionsOrCallback.timeout !== "number") { + throw new Error("Timeout argument must be a valid number"); + } + return executor.navigate(resultWindow, newUrl, optionsOrCallback); + } + function setStyle(style, success, error) { + return Utils.callbackifyPromise(() => { + if (!style || Object.keys(style).length === 0 || Object.keys(style).every((key) => !key)) { + throw new Error("Invalid style arguments: " + JSON.stringify(style)); + } + if (style && style.focus !== undefined) { + if (typeof style.focus !== "boolean") { + throw new Error("Focus must be a boolean value. Currently, only `focus: true` is supported."); + } + else if (style.focus === false) { + console.warn("`focus: false` is not supported!"); + } + } + if (style && style.hidden !== undefined && typeof style.hidden !== "boolean") { + throw new Error("The `hidden` property must hold a boolean value."); + } + for (const prop of ["minHeight", "maxHeight", "minWidth", "maxWidth"]) { + const styleAsAny = style; + const value = styleAsAny[prop]; + if (prop in style) { + if (isUndefinedOrNull(value)) { + delete styleAsAny[prop]; + continue; + } + if (!isNumber(styleAsAny[prop])) { + throw new Error(`"${prop}" must be a number`); + } + } + } + return executor.setStyle(resultWindow, style); + }, success, error); + } + function resetButtons(buttons, success, error) { + return Utils.callbackifyPromise(() => executor.resetButtons(resultWindow, buttons), success, error); + } + function getButtons() { + return executor.getButtons(resultWindow); + } + function setOnTop(onTop, success, error) { + return Utils.callbackifyPromise(() => { + if (typeof onTop === "string") { + if (onTop !== "always") { + throw new Error("`onTop` must hold a `always` value."); + } + } + else if (typeof onTop !== "boolean") { + throw new Error("`onTop` must hold a boolean or `always` value."); + } + return executor.setOnTop(resultWindow, onTop); + }, success, error); + } + function setSizeConstraints(constraints, success, error) { + return Utils.callbackifyPromise(() => { + if (!constraints || Object.keys(constraints).every((value) => value === undefined)) { + throw new Error("The properties of `constraints` cannot be null or undefined."); + } + return executor.setSizeConstraints(resultWindow, constraints); + }, success, error); + } + function getSizeConstraints() { + return executor.getSizeConstraints(resultWindow); + } + function setTitle(newTitle, success, error) { + return Utils.callbackifyPromise(() => { + if (isUndefinedOrNull(newTitle)) { + throw new Error("`newTitle` must not be null or undefined."); + } + if (newTitle === _title) { + return Promise.resolve(resultWindow); + } + return executor.setTitle(resultWindow, newTitle); + }, success, error); + } + function setSticky(isSticky, success, error) { + return Utils.callbackifyPromise(() => { + if (typeof isSticky !== "boolean") { + throw new Error("`isSticky` must hold a boolean value."); + } + return executor.setSticky(resultWindow, isSticky); + }, success, error); + } + function setAllowWorkspaceDrop(allowWorkspaceDrop) { + if (typeof allowWorkspaceDrop !== "boolean") { + throw new Error("`allowWorkspaceDrop` must hold a boolean value."); + } + return executor.setAllowWorkspaceDrop(resultWindow, allowWorkspaceDrop); + } + function pin() { + return executor.pin(resultWindow); + } + function unpin() { + return executor.unpin(resultWindow); + } + function moveResize(bounds, success, error) { + return Utils.callbackifyPromise(() => { + if (isUndefinedOrNull(bounds)) { + throw new Error("The properties of `bounds` cannot be null or undefined."); + } + return executor.moveResize(resultWindow, bounds); + }, success, error); + } + function addFrameButton(buttonInfo, success, error) { + return Utils.callbackifyPromise(() => { + if (typeof buttonInfo === "undefined" || Object.keys(buttonInfo).length === 0) { + throw new Error("Button info is not available."); + } + if (isNullOrWhiteSpace(buttonInfo.buttonId)) { + throw new Error("`buttonId` must not be null or undefined."); + } + if (isNullOrWhiteSpace(buttonInfo.imageBase64)) { + throw new Error("`imageBase64` must not be null or undefined."); + } + return executor.addFrameButton(resultWindow, buttonInfo); + }, success, error); + } + function removeFrameButton(buttonId, success, error) { + return Utils.callbackifyPromise(() => { + if (isNullOrWhiteSpace(buttonId)) { + throw new Error("`buttonId` must not be null or undefined."); + } + return executor.removeFrameButton(resultWindow, buttonId); + }, success, error); + } + function activate(success, error) { + return Utils.callbackifyPromise(() => { + if (_focus) { + return Promise.resolve(resultWindow); + } + return executor.activate(resultWindow); + }, success, error); + } + function focus(success, error) { + return Utils.callbackifyPromise(() => { + if (_focus) { + return Promise.resolve(resultWindow); + } + return executor.focus(resultWindow); + }, success, error); + } + function maximizeRestore(success, error) { + return Utils.callbackifyPromise(() => { + return executor.maximizeRestore(resultWindow); + }, success, error); + } + function maximize(success, error) { + return Utils.callbackifyPromise(() => { + if (_windowState === "maximized") { + return Promise.resolve(resultWindow); + } + return executor.maximize(resultWindow); + }, success, error); + } + function restore(success, error) { + return Utils.callbackifyPromise(() => { + if (_windowState === "normal") { + return Promise.resolve(resultWindow); + } + return executor.restore(resultWindow); + }, success, error); + } + function minimize(success, error) { + return Utils.callbackifyPromise(() => { + if (_windowState === "minimized") { + return Promise.resolve(resultWindow); + } + return executor.minimize(resultWindow); + }, success, error); + } + function collapse(success, error) { + return Utils.callbackifyPromise(() => { + if (_isCollapsed) { + return Promise.resolve(resultWindow); + } + return executor.collapse(resultWindow); + }, success, error); + } + function expand(success, error) { + return Utils.callbackifyPromise(() => { + if (!_isCollapsed) { + return Promise.resolve(resultWindow); + } + return executor.expand(resultWindow); + }, success, error); + } + function toggleCollapse(success, error) { + return Utils.callbackifyPromise(() => { + return executor.toggleCollapse(resultWindow); + }, success, error); + } + function snap(target, direction, success, error) { + return Utils.callbackifyPromise(() => { + if (isUndefinedOrNull(target)) { + throw new Error(`A target window is not specified - ${typeof target === "string" ? target : JSON.stringify(target)}`); + } + if (typeof target === "string") { + const win = windowStore.get(target); + if (!win) { + throw new Error(`Invalid "target" parameter or no such window. Invoked with: ${target}`); + } + target = win.API; + } + if (typeof direction === "string") { + direction = { + direction, + autoAlign: true + }; + } + return executor.snap(resultWindow, target, direction); + }, success, error); + } + function attachTab(tab, opt, success, error) { + return Utils.callbackifyPromise(() => { + var _a; + const errorMessage = `Invalid "tab" parameter - must be an object with an "id" property or a string. Invoked for source window with ID:`; + if (isUndefinedOrNull(tab)) { + const errMsg = `${errorMessage} ${typeof tab === "string" ? tab : JSON.stringify(tab)}`; + throw new Error(errMsg); + } + let sourceWindow; + if (typeof tab === "string") { + sourceWindow = (_a = windowStore.get(tab)) === null || _a === void 0 ? void 0 : _a.API; + if (isUndefinedOrNull(sourceWindow)) { + const errMsg = `${errorMessage} ${typeof sourceWindow === "string" ? sourceWindow : JSON.stringify(sourceWindow)}`; + throw new Error(errMsg); + } + } + else if (!isUndefinedOrNull(tab.id)) { + sourceWindow = tab; + } + else { + throw new Error(errorMessage); + } + const attachOptions = {}; + if (!isUndefinedOrNull(opt)) { + if (typeof opt === "number") { + attachOptions.index = opt; + } + else { + attachOptions.selected = opt.selected; + attachOptions.index = opt.index; + } + } + return executor.attachTab(resultWindow, sourceWindow, attachOptions); + }, success, error); + } + function detachTab(opt = {}, success, error) { + return Utils.callbackifyPromise(() => { + const argsForSend = {}; + function isDetachRelative(o) { + return o.relativeTo !== undefined; + } + if (isDetachRelative(opt)) { + if (typeof opt.relativeTo === "string") { + argsForSend.relativeTo = opt.relativeTo; + } + else if (!isUndefinedOrNull(opt.relativeTo.id)) { + argsForSend.relativeTo = opt.relativeTo.id; + } + if (!isUndefinedOrNull(opt.relativeDirection)) { + argsForSend.relativeDirection = opt.relativeDirection; + } + if (!isUndefinedOrNull(opt.width)) { + argsForSend.width = opt.width; + } + if (!isUndefinedOrNull(opt.height)) { + argsForSend.height = opt.height; + } + } + else { + if (!isUndefinedOrNull(opt.bounds)) { + argsForSend.bounds = opt.bounds; + } + } + if (!isUndefinedOrNull(opt.hideTabHeader)) { + argsForSend.hideTabHeader = opt.hideTabHeader; + } + return executor.detachTab(resultWindow, argsForSend); + }, success, error); + } + function setVisible(toBeVisible, success, error) { + return Utils.callbackifyPromise(() => { + return executor.setVisible(resultWindow, toBeVisible); + }, success, error); + } + async function center(display) { + if (display) { + validateCenterArguments(display); + } + return executor.center(resultWindow, display); + } + function validateCenterArguments(display) { + if (typeof display !== "object") { + throw Error("display argument must be a valid display object"); + } + if (!display.workArea || !display.scaleFactor) { + throw Error("display argument is not a valid display object"); + } + } + function showLoader(loader) { + return executor.showLoader(resultWindow, loader); + } + function hideLoader() { + return executor.hideLoader(resultWindow); + } + function updateContext(context, success, error) { + return Utils.callbackifyPromise(() => { + if (!isObject(context)) { + throw new Error(`"context" must not be null or undefined.`); + } + return executor.updateContext(resultWindow, context, false); + }, success, error); + } + function lock(success, error) { + return Utils.callbackifyPromise(() => { + return executor.lock(resultWindow); + }, success, error); + } + function unlock(success, error) { + return Utils.callbackifyPromise(() => { + return executor.unlock(resultWindow); + }, success, error); + } + function getIcon(success, error) { + return Utils.callbackifyPromise(() => { + return executor.getIcon(resultWindow); + }, success, error); + } + function setIcon(base64Image, success, error) { + return Utils.callbackifyPromise(() => { + if (isNullOrWhiteSpace(base64Image)) { + throw new Error(`"base64Image" must be a non-empty string.`); + } + return executor.setIcon(resultWindow, base64Image); + }, success, error); + } + function setFrameColor(frameColor, success, error) { + return Utils.callbackifyPromise(() => { + if (isNullOrWhiteSpace(frameColor)) { + throw new Error(`"frameColor" must be a non-empty string`); + } + return executor.setFrameColor(resultWindow, frameColor); + }, success, error); + } + function setTabHeaderVisible(toBeTabHeaderVisible, success, error) { + return Utils.callbackifyPromise(() => { + if (typeof toBeTabHeaderVisible !== "boolean") { + throw new Error(`"toBeTabHeaderVisible" must hold a boolean value.`); + } + return executor.setTabHeaderVisible(resultWindow, toBeTabHeaderVisible); + }, success, error); + } + async function setTabTooltip(tooltip) { + if (isNullOrWhiteSpace(tooltip)) { + throw new Error(`"${tooltip}" must not be null or undefined`); + } + return executor.setTabTooltip(resultWindow, tooltip); + } + async function getTabTooltip() { + return executor.getTabTooltip(resultWindow); + } + function showPopup(config) { + return executor.showPopup(resultWindow, config); + } + function createFlydown(config) { + return executor.createFlydown(resultWindow.id, config); + } + function setModalState(isModal) { + return executor.setModalState(resultWindow.id, isModal || false); + } + function zoomIn(success, error) { + return Utils.callbackifyPromise(() => { + return executor.zoomIn(resultWindow); + }, success, error); + } + function zoomOut(success, error) { + return Utils.callbackifyPromise(() => { + return executor.zoomOut(resultWindow); + }, success, error); + } + function setZoomFactor(zoomFactor, success, error) { + return Utils.callbackifyPromise(() => { + if (isNaN(zoomFactor)) { + throw new Error(`zoomFactor is not a number`); + } + return executor.setZoomFactor(resultWindow, zoomFactor); + }, success, error); + } + function showDevTools() { + return executor.showDevTools(resultWindow); + } + function capture(captureOptions) { + return executor.capture(resultWindow, captureOptions); + } + function flash(suppliedOptions, mode) { + const flashOptions = { + shouldFlash: true, + mode: "auto" + }; + if (typeof suppliedOptions === "boolean") { + flashOptions.shouldFlash = suppliedOptions; + } + if (typeof mode !== "undefined") { + flashOptions.mode = mode; + } + return executor.flash(resultWindow, flashOptions); + } + function flashTab(suppliedOptions) { + const flashOptions = { + shouldFlash: true, + }; + if (typeof suppliedOptions === "boolean") { + flashOptions.shouldFlash = suppliedOptions; + } + return executor.flashTab(resultWindow, flashOptions); + } + function print(printOptions) { + return executor.print(resultWindow, printOptions); + } + function printToPDF(printToPDFOptions) { + return executor.printToPDF(resultWindow, printToPDFOptions); + } + function ungroup(ungroupOptions) { + return new Promise((resolve, reject) => { + const unGroupChanged = onGroupChanged((win, newGroup, oldGroup) => { + if (id === win.id) { + unGroupChanged(); + resolve(resultWindow); + } + }); + executor.ungroup(resultWindow, ungroupOptions) + .catch((e) => { + unGroupChanged(); + reject(e); + }); + }); + } + function place(placementSettings) { + return executor.place(resultWindow, placementSettings); + } + function refresh(ignoreCache) { + return executor.refresh(resultWindow, ignoreCache); + } + function download(url, opts) { + return executor.download(resultWindow, url, opts); + } + function configure(settings) { + return executor.configureWindow(resultWindow, settings); + } + function getConfiguration() { + return executor.getWindowConfiguration(resultWindow); + } + function getDockingPlacement() { + return executor.getDockingPlacement(resultWindow); + } + function dock(opts) { + return executor.dock(resultWindow, opts); + } + async function clone(cloneOptions) { + return executor.clone(resultWindow, cloneOptions); + } + async function executeCode(code) { + if (!code) { + throw new Error("Code argument is missing"); + } + if (typeof code !== "string") { + throw new Error("Code argument must be a valid string"); + } + const response = await executor.executeCode(resultWindow, code); + return response.result; + } + function onTitleChanged(callback) { + if (!isFunction(callback)) { + throw new Error("callback should be a function"); + } + callback(resultWindow.title, resultWindow); + return onEventCore("onTitleChanged", callback); + } + function onClose(callback) { + if (!isFunction(callback)) { + throw new Error("callback should be a function"); + } + if (id === undefined) { + callback(resultWindow); + } + return _registry.add("onClose", callback); + } + function onUrlChanged(callback) { + return onEventCore("onUrlChanged", callback); + } + function onFrameButtonAdded(callback) { + return onEventCore("onFrameButtonAdded", callback); + } + function onFrameButtonRemoved(callback) { + return onEventCore("onFrameButtonRemoved", callback); + } + function onFrameButtonClicked(callback) { + return onEventCore("onFrameButtonClicked", callback); + } + function onCollapsed(callback) { + if (!isFunction(callback)) { + throw new Error("callback should be a function"); + } + if (_isCollapsed) { + callback(resultWindow); + } + return _registry.add("collapsed", callback); + } + function onExpanded(callback) { + if (!isFunction(callback)) { + throw new Error("callback should be a function"); + } + if (!_isCollapsed) { + callback(resultWindow); + } + return _registry.add("expanded", callback); + } + function onMaximized(callback) { + if (_windowState === "maximized") { + return onEventCore("maximized", callback, [resultWindow]); + } + else { + return onEventCore("maximized", callback); + } + } + function onMinimized(callback) { + if (_windowState === "minimized") { + return onEventCore("minimized", callback, [resultWindow]); + } + else { + return onEventCore("minimized", callback); + } + } + function onNormal(callback) { + if (_windowState === "normal") { + return onEventCore("normal", callback, [resultWindow]); + } + else { + return onEventCore("normal", callback); + } + } + function onAttached(callback) { + return onEventCore("attached", callback); + } + function onDetached(callback) { + return onEventCore("detached", callback); + } + function onVisibilityChanged(callback) { + return onEventCore("visibility-changed", callback); + } + function onContextUpdated(callback) { + return onEventCore("context-updated", callback); + } + function onLockingChanged(callback) { + return onEventCore("lock-changed", callback); + } + function onBoundsChanged(callback) { + return onEventCore("bounds-changed", callback); + } + function onFocusChanged(callback) { + return onEventCore("focus-changed", callback); + } + function onStickyChanged(callback) { + return onEventCore("sticky-changed", callback); + } + function onFrameColorChanged(callback) { + return onEventCore("frame-color-changed", callback); + } + function onTabHeaderVisibilityChanged(callback) { + return onEventCore("tab-header-visibility-changed", callback); + } + function onWindowAttached(callback) { + return onEventCore("window-attached", callback); + } + function onWindowDetached(callback) { + return onEventCore("window-detached", callback); + } + function onGroupChanged(callback) { + return onEventCore("group-changed", callback); + } + function onTabSelectionChanged(callback) { + return onEventCore("tab-selection-changed", callback); + } + function onChannelRestrictionsChanged(callback) { + if (!isFunction(callback)) { + throw new Error("callback must be a function"); + } + return onEventCore("channel-restrictions-changed", callback); + } + function onClosing(callback) { + if (!isFunction(callback)) { + throw new Error("callback must be a function"); + } + const callbackWrap = (success, error, prevent) => { + const promise = callback(prevent); + if (promise === null || promise === void 0 ? void 0 : promise.then) { + promise.then(success).catch(error); + } + else { + success(); + } + }; + return executor.onClosing(callbackWrap, resultWindow); + } + function onRefreshing(callback) { + if (!isFunction(callback)) { + throw new Error("callback must be a function"); + } + const callbackWrap = (success, error, prevent) => { + const promise = callback(prevent); + if (promise === null || promise === void 0 ? void 0 : promise.then) { + promise.then(success).catch(error); + } + else { + success(); + } + }; + return executor.onRefreshing(callbackWrap, resultWindow); + } + function onNavigating(callback) { + if (!isFunction(callback)) { + throw new Error("callback must be a function"); + } + const callbackWrap = (success, error, prevent, args) => { + const promise = callback(args); + if (promise === null || promise === void 0 ? void 0 : promise.then) { + promise.then(success).catch(error); + } + else { + success(); + } + }; + return executor.onNavigating(callbackWrap, resultWindow); + } + function onZoomFactorChanged(callback) { + return onEventCore("zoom-factor-changed", callback); + } + function onPlacementSettingsChanged(callback) { + return onEventCore("placementSettingsChanged", callback); + } + function onNeighboursChanged(callback) { + return onEventCore("neighbours-changed", callback); + } + function onDockingChanged(callback) { + return onEventCore("docking-changed", callback); + } + function onEventCore(key, callback, replayArguments) { + if (!isFunction(callback)) { + throw new Error("callback must be a function"); + } + return _registry.add(key, callback, replayArguments); + } + function goBack() { + return executor.goBack(resultWindow); + } + function goForward() { + return executor.goForward(resultWindow); + } + function startDrag(option) { + return executor.startDrag(resultWindow, option); + } + function showDialog(dialogOptions) { + if ((dialogOptions === null || dialogOptions === void 0 ? void 0 : dialogOptions.timerDuration) && isNaN(dialogOptions === null || dialogOptions === void 0 ? void 0 : dialogOptions.timerDuration)) { + throw new Error("timerDuration must be a number"); + } + if ((dialogOptions === null || dialogOptions === void 0 ? void 0 : dialogOptions.showTimer) && typeof (dialogOptions === null || dialogOptions === void 0 ? void 0 : dialogOptions.showTimer) !== "boolean") { + throw new Error("showTimer must be a boolean"); + } + return executor.showDialog(resultWindow, dialogOptions); + } + function handleUpdate(updated) { + _url = updated.url; + _title = updated.title; + _context = updated.context || {}; + _bounds = updated.bounds; + _frameColor = updated.frameColor; + _focus = updated.focus; + _neighbours = updated.neighbours || {}; + _groupId = updated.groupId; + _isGroupHeaderVisible = updated.isGroupHeaderVisible; + _isTabHeaderVisible = updated.isTabHeaderVisible; + _isGroupHibernated = updated.isGroupHibernated; + _isGroupVisible = updated.isGroupVisible; + _isTabSelected = updated.isTabSelected; + _settings = updated.settings; + _isVisible = updated.isVisible; + _isSticky = updated.isSticky; + _isCollapsed = updated.isCollapsed; + _windowState = updated.state; + _tabGroupId = updated.tabGroupId; + _frameId = updated.frameId; + _isLocked = updated.isLocked; + _allowWorkspaceDrop = updated.allowWorkspaceDrop; + _isPinned = updated.isPinned; + _zoomFactor = updated.zoomFactor; + _placementSettings = updated.placementSettings; + } + function handleTitleChanged(newTitle) { + _title = newTitle; + executor.finished + .finally(() => { + _registry.execute("onTitleChanged", newTitle, resultWindow); + }); + } + function handleUrlChanged(newUrl) { + _url = newUrl; + _registry.execute("onUrlChanged", newUrl, resultWindow); + } + function handleVisibilityChanged(isVisible) { + if (isVisible === _isVisible) { + return; + } + _isVisible = isVisible; + _registry.execute("visibility-changed", resultWindow); + } + function handleWindowSettingsChanged(settings) { + _settings = settings; + _registry.execute("settings-changed", resultWindow); + } + function handleContextUpdated(context) { + _context = context; + _registry.execute("context-updated", _context, resultWindow); + } + function handleWindowClose() { + if (id === undefined) { + return; + } + _registry.execute("onClose", resultWindow); + id = undefined; + } + function handleFrameButtonAdded(frameButton) { + const buttonObj = ["buttonId", "imageBase64", "order", "tooltip"].reduce((memo, k) => { + memo[k] = frameButton[k]; + return memo; + }, {}); + const frameButtonsIds = _frameButtons.map((btn) => { + return btn.buttonId; + }); + if (frameButtonsIds.indexOf(frameButton.buttonId) === -1) { + _frameButtons.push(buttonObj); + } + _registry.execute("onFrameButtonAdded", buttonObj, resultWindow); + } + function handleFrameButtonRemoved(frameButtonId) { + let button; + _frameButtons = _frameButtons.reduce((memo, btn) => { + if (btn.buttonId === frameButtonId) { + button = btn; + } + else { + memo.push(btn); + } + return memo; + }, []); + if (button !== undefined) { + _registry.execute("onFrameButtonRemoved", button, resultWindow); + } + } + function handleFrameButtonClicked(frameButton) { + const button = _frameButtons.filter((btn) => { + return btn.buttonId === frameButton.buttonId; + }); + if (button.length > 0) { + _registry.execute("onFrameButtonClicked", button[0], resultWindow); + } + } + async function handleWindowChangeState(state) { + if (state === "collapsed") { + _isCollapsed = true; + } + else if (state === "expanded") { + _isCollapsed = false; + } + else { + _windowState = state; + } + await executor.finished; + _registry.execute(state, resultWindow); + } + function handleFrameIsLockedChanged(isLocked) { + _isLocked = isLocked; + _registry.execute("lock-changed", resultWindow); + } + function handleBoundsChanged(bounds) { + if (_bounds.top === bounds.top && _bounds.left === bounds.left && _bounds.width === bounds.width && _bounds.height === bounds.height) { + return; + } + _bounds = bounds; + _registry.execute("bounds-changed", resultWindow); + } + function handleFocusChanged(isFocused) { + _focus = isFocused; + _registry.execute("focus-changed", resultWindow); + } + function handleIsStickyChanged(isSticky) { + _isSticky = isSticky; + _registry.execute("sticky-changed", isSticky, resultWindow); + } + function handleFrameColorChanged(frameColor) { + _frameColor = frameColor; + _registry.execute("frame-color-changed", resultWindow); + } + function handleFrameAttached(tabGroupId, frameId, isTabHeaderVisible) { + _tabGroupId = tabGroupId; + _frameId = frameId; + _isTabHeaderVisible = isTabHeaderVisible; + _registry.execute("frame-attached", resultWindow); + } + function handleCompositionChanged(state) { + _neighbours = state.neighbors || {}; + _tabIndex = state.index; + _registry.execute("neighbours-changed", _neighbours, resultWindow); + } + function handleAllowWorkspaceDropChanged(allowWorkspaceDrop) { + _allowWorkspaceDrop = allowWorkspaceDrop; + _registry.execute("allow-workspace-drop-changed", resultWindow); + } + function handleIsPinnedChanged(isPinned) { + _isPinned = isPinned; + _registry.execute("is-pinned-changed", resultWindow); + } + function handleGroupHeaderVisibilityChanged(isGroupHeaderVisible) { + _isGroupHeaderVisible = isGroupHeaderVisible; + } + function handleTabHeaderVisibilityChanged(isTabHeaderVisible) { + if (_isTabHeaderVisible !== isTabHeaderVisible) { + _isTabHeaderVisible = isTabHeaderVisible; + _registry.execute("tab-header-visibility-changed", resultWindow); + } + } + async function handleFrameSelectionChanged(newWindow, prevWindow) { + let selectedWindow; + if (newWindow === id) { + _isTabSelected = true; + selectedWindow = resultWindow; + } + else { + _isTabSelected = false; + selectedWindow = windowStore.get(newWindow) ? windowStore.get(newWindow).API : undefined; + } + const previousWindow = windowStore.get(prevWindow) ? windowStore.get(prevWindow).API : undefined; + await executor.finished; + _registry.execute("tab-selection-changed", selectedWindow, previousWindow, resultWindow); + } + async function handleAttached(newTabGroupId, newFrameId, tabHeaderVisible, isLocked, winsToBeNotified) { + _tabGroupId = newTabGroupId; + _isTabHeaderVisible = tabHeaderVisible; + _frameId = newFrameId; + if (typeof isLocked !== "undefined") { + _isLocked = isLocked; + } + await executor.finished; + winsToBeNotified.forEach((w) => { + w.Events.handleWindowAttached(resultWindow); + }); + _registry.execute("attached", resultWindow); + } + function handleWindowAttached(win) { + _registry.execute("window-attached", win); + } + async function handleDetached(isLocked, winsToBeNotified) { + _tabGroupId = undefined; + _isTabSelected = false; + if (typeof isLocked !== "undefined") { + _isLocked = isLocked; + } + await executor.finished; + winsToBeNotified.forEach((w) => { + w.Events.handleWindowDetached(resultWindow); + }); + _registry.execute("detached", resultWindow); + } + function handleWindowDetached(win) { + _registry.execute("window-detached", win); + } + function handleZoomFactorChanged(zoomFactor) { + _zoomFactor = zoomFactor; + _registry.execute("zoom-factor-changed", resultWindow); + } + function handlePlacementSettingsChanged(placementSettings) { + let promise; + const copy = placementSettings; + if (!copy.display) { + promise = Promise.resolve(undefined); + } + else { + const displayAPI = displayAPIGetter(); + if (!displayAPI) { + promise = Promise.resolve(undefined); + } + else { + const index = copy.display - 1; + promise = new Promise((resolve, reject) => { + displayAPI.all().then((displays) => { + const display = displays.find((d) => d.index === index); + resolve(display); + }).catch(reject); + }); + } + } + void promise.then((d) => { + copy.display = d; + _placementSettings = copy; + _registry.execute("placementSettingsChanged", resultWindow); + }); + } + function handleDockingChanged(data) { + _registry.execute("docking-changed", resultWindow, { + docked: data.docked, + position: data.position, + claimScreenArea: data.claimScreenArea + }); + } + function handleChannelRestrictionsChanged(data) { + _registry.execute("channel-restrictions-changed", data); + } + function handleGroupChanged(newGroup, oldGroup) { + _group = newGroup; + _groupId = newGroup === null || newGroup === void 0 ? void 0 : newGroup.id; + if (!isUndefinedOrNull(newGroup) && !isUndefinedOrNull(oldGroup)) { + _registry.execute("group-changed", resultWindow, newGroup, oldGroup); + } + } + function getAllTabs() { + const allWindows = windowStore.list; + if (_mode.toLowerCase() !== "tab") { + return []; + } + const tabs = Object.keys(allWindows).reduce((memo, win) => { + const window = allWindows[win]; + if (window + && window.API.tabGroupId + && typeof window.API.tabGroupId !== "undefined" + && typeof resultWindow.tabGroupId !== "undefined" + && window.API.tabGroupId === resultWindow.tabGroupId) { + memo.push(window.API); + } + return memo; + }, []); + return tabs.sort((w1, w2) => { + if (w1.tabIndex !== w2.tabIndex) { + if (w1.tabIndex === -1) { + return Number.MAX_SAFE_INTEGER; + } + if (w2.tabIndex === -1) { + return Number.MIN_SAFE_INTEGER; + } + } + return w1.tabIndex - w2.tabIndex; + }); + } + function mapWindowIdsToWindowObjects(windowIdArr) { + return windowIdArr.reduce((memo, winId) => { + const window = windowStore.get(winId); + if (window) { + memo.push(window.API); + } + return memo; + }, []); + } + function getNeighboursByDirection(direction) { + const windowIds = _neighbours[direction]; + if (typeof windowIds !== "undefined") { + return mapWindowIdsToWindowObjects(windowIds); + } + } + function getApplicationName() { + var _a; + if (_applicationName) { + return _applicationName; + } + if (_context._APPLICATION_NAME) { + return _context._APPLICATION_NAME; + } + if (_context && _context._t42 && _context._t42.application) { + return _context._t42.application; + } + const info = getWindowInfo(); + if (info && info.applicationName) { + return info.applicationName; + } + const appManager = appManagerGetter(); + if (appManager) { + const instance = appManager.instances().find((i) => id === i.id); + if (instance) { + return (_a = instance.application) === null || _a === void 0 ? void 0 : _a.name; + } + } + return undefined; + } + function getWindowInfo() { + if (typeof window !== "undefined" && window.glue42gd && window.glue42gd.getWindowInfo) { + const info = window.glue42gd.getWindowInfo(id); + if (!info) { + return undefined; + } + else { + return info; + } + } + } + const resultWindow = { + get id() { + return _id; + }, + get name() { + return _name; + }, + get application() { + const appManager = appManagerGetter(); + const appName = getApplicationName(); + if (appName && appManager) { + return appManager.application(appName); + } + }, + get hostInstance() { + return executor.hostInstance; + }, + get interopInstance() { + const instance = agm.servers().find((s) => s.windowId === this.id); + if (instance) { + return instance; + } + else { + const appName = getApplicationName(); + if (appName) { + return { application: appName }; + } + } + }, + get agmInstance() { + return resultWindow.interopInstance; + }, + get url() { + return _url; + }, + get title() { + return _title; + }, + get windowStyleAttributes() { + return _settings; + }, + get settings() { + return _settings; + }, + get tabGroupId() { + return _mode.toLowerCase() === "tab" ? _tabGroupId : undefined; + }, + get tabIndex() { + return _mode.toLowerCase() === "tab" ? _tabIndex : undefined; + }, + get frameId() { + return _frameId; + }, + get frameButtons() { + return _frameButtons.sort((b1, b2) => b1.order - b2.order); + }, + get mode() { + return _mode; + }, + get state() { + return _windowState; + }, + get isCollapsed() { + return _isCollapsed; + }, + get isVisible() { + return _isVisible; + }, + get isLocked() { + return _isLocked; + }, + get context() { + return _context; + }, + get bounds() { + return _bounds; + }, + get minHeight() { + return _settings.minHeight; + }, + get maxHeight() { + return _settings.maxHeight; + }, + get minWidth() { + return _settings.minWidth; + }, + get maxWidth() { + return _settings.maxWidth; + }, + get isFocused() { + return _focus; + }, + get frameColor() { + return _frameColor; + }, + get opened() { + return resultWindow.id !== undefined; + }, + get group() { + return _group; + }, + get groupId() { + return _groupId; + }, + get isSticky() { + return _isSticky; + }, + get topNeighbours() { + return getNeighboursByDirection("top"); + }, + get leftNeighbours() { + return getNeighboursByDirection("left"); + }, + get rightNeighbours() { + return getNeighboursByDirection("right"); + }, + get bottomNeighbours() { + return getNeighboursByDirection("bottom"); + }, + get isGroupHeaderVisible() { + return _isGroupHeaderVisible; + }, + get activityId() { + if (_context._t42) { + return _context._t42.activityId; + } + const info = getWindowInfo(); + if (!info) { + return undefined; + } + return info.activityId; + }, + get activityWindowId() { + if (_context._t42) { + return _context._t42.activityWindowId; + } + const info = getWindowInfo(); + if (!info) { + return undefined; + } + return info.activityWindowId; + }, + get windowType() { + return options.windowType || "electron"; + }, + get zoomFactor() { + return _zoomFactor; + }, + get screen() { + if (typeof window !== "undefined" && window.glue42gd) { + return Utils.getMonitor(resultWindow.bounds, window.glue42gd.monitors); + } + return undefined; + }, + get placementSettings() { + return Object.assign({}, _placementSettings); + }, + get jumpList() { + return _jumpList; + }, + get allowWorkspaceDrop() { + return _allowWorkspaceDrop; + }, + get isPinned() { + return _isPinned; + }, + maximize, + restore, + minimize, + maximizeRestore, + collapse, + expand, + toggleCollapse, + focus, + activate, + moveResize, + setTitle, + setStyle, + setOnTop, + resetButtons, + getButtons, + setSizeConstraints, + getSizeConstraints, + navigate, + addFrameButton, + removeFrameButton, + setVisible, + show: () => setVisible(true), + hide: () => setVisible(false), + center, + close, + snap, + showLoader, + hideLoader, + updateContext, + lock, + unlock, + getIcon, + setIcon, + setFrameColor, + setTabTooltip, + getTabTooltip, + attachTab, + detachTab, + setTabHeaderVisible, + showPopup, + createFlydown, + setModalState, + setZoomFactor, + zoomIn, + zoomOut, + showDevTools, + capture, + flash, + flashTab, + setSticky, + setAllowWorkspaceDrop, + pin, + unpin, + print, + printToPDF, + place, + ungroup, + refresh, + goBack, + goForward, + download, + configure, + getConfiguration, + getDockingPlacement, + dock, + clone, + executeCode, + getChannel: async () => { + var _a; + const wins = await getChannels().getWindowsWithChannels({ windowIds: [_id] }); + return (_a = wins[0]) === null || _a === void 0 ? void 0 : _a.channel; + }, + startDrag, + showDialog, + onClose, + onUrlChanged, + onTitleChanged, + onFrameButtonAdded, + onFrameButtonRemoved, + onFrameButtonClicked, + onCollapsed, + onExpanded, + onMinimized, + onMaximized, + onNormal, + onAttached, + onDetached, + onVisibilityChanged, + onContextUpdated, + onLockingChanged, + onBoundsChanged, + onFrameColorChanged, + onFocusChanged, + onStickyChanged, + onGroupChanged, + onWindowAttached, + onWindowDetached, + onTabSelectionChanged, + onTabHeaderVisibilityChanged, + onClosing, + onRefreshing, + onZoomFactorChanged, + onPlacementSettingsChanged, + onNeighboursChanged, + onDockingChanged, + onNavigating, + onChannelRestrictionsChanged, + get tabs() { + return getAllTabs(); + }, + get isTabHeaderVisible() { + return _isTabHeaderVisible; + }, + get isTabSelected() { + return _isTabSelected; + }, + getURL() { + return Promise.resolve(_url); + }, + getTitle() { + return Promise.resolve(_title); + }, + getBounds() { + return Promise.resolve(_bounds); + }, + getContext() { + return Promise.resolve(_context); + }, + setContext(context) { + if (!isObject(context)) { + throw new Error(`"context" must not be null or undefined, set to empty object if you want to clear it out.`); + } + return executor.updateContext(resultWindow, context, true); + }, + getDisplay() { + const displayAPI = displayAPIGetter(); + return displayAPI.getByWindowId(id); + }, + resizeTo(width, height) { + return moveResize({ width, height }); + }, + moveTo(top, left) { + return moveResize({ top, left }); + }, + async getParentWindow() { + var _a; + const myParentId = _settings.parentInstanceId; + if (!myParentId) { + return undefined; + } + return (_a = windowStore.list[myParentId]) === null || _a === void 0 ? void 0 : _a.API; + }, + async getChildWindows() { + return Object.keys(windowStore.list) + .map((key) => windowStore.list[key].API) + .filter((w) => { + const parentId = w.settings.parentInstanceId; + return parentId === id; + }); + }, + joinChannel: (name) => { + return getChannels().join(name, id); + }, + leaveChannel: () => { + return getChannels().leave(id); + } + }; + const events = { + handleUpdate, + handleWindowClose, + handleWindowChangeState, + handleTitleChanged, + handleVisibilityChanged, + handleUrlChanged, + handleWindowSettingsChanged, + handleContextUpdated, + handleFrameIsLockedChanged, + handleBoundsChanged, + handleFocusChanged, + handleFrameButtonAdded, + handleFrameButtonRemoved, + handleFrameButtonClicked, + handleFrameColorChanged, + handleFrameAttached, + handleFrameSelectionChanged, + handleCompositionChanged, + handleAllowWorkspaceDropChanged, + handleIsPinnedChanged, + handleGroupHeaderVisibilityChanged, + handleTabHeaderVisibilityChanged, + handleGroupChanged, + handleAttached, + handleDetached, + handleWindowAttached, + handleWindowDetached, + handleZoomFactorChanged, + handleIsStickyChanged, + handlePlacementSettingsChanged, + handleDockingChanged, + handleChannelRestrictionsChanged + }; + const groupArgs = { + get isGroupHibernated() { + return _isGroupHibernated; + }, + get isGroupVisible() { + return _isGroupVisible; + }, + }; + return { + API: resultWindow, + Events: events, + GroupCreationArgs: groupArgs + }; + }; + + function getWindowsByTabGroupId(windowId, tabGroupId) { + const windows = windowStore.list; + return Object.keys(windows).reduce((memo, id) => { + const win = windows[id]; + if (win.API.tabGroupId === tabGroupId && win.API.id !== windowId) { + memo.push(win); + } + return memo; + }, []); + } + function isEmpty(object) { + if (!object || Object.keys(object).every((value) => object[value] === undefined)) { + return true; + } + return false; + } + + class GDExecutor { + constructor() { + this.GroupMethodName = "T42.Group.Execute"; + this.WndMethodName = "T42.Wnd.Execute"; + this._registry = CallbackRegistryFactory(); + this._finished = Promise.resolve(); + this._configuration = { + windowAvailableOnURLChanged: true + }; + this.unsubCallbacks = {}; + } + get hostInstance() { + return this.agmTarget; + } + get finished() { + return this._finished; + } + get configuration() { + return this._configuration; + } + init(agm, instance) { + this.agm = agm; + this.agmTarget = instance; + this._registry.add("event", (data) => { + if (data.type === "Closed") { + const keys = Object.keys(this.unsubCallbacks); + keys.forEach((key) => { + const isSameWindow = key.startsWith(data.windowId); + if (isSameWindow) { + delete this.unsubCallbacks[key]; + } + }); + } + }); + } + setConfiguration(config) { + this._configuration = { ...this._configuration, ...config }; + } + handleEvent(data) { + this._registry.execute("event", data); + } + async open(options) { + let finishedResolve; + this._finished = new Promise((resolve) => { + finishedResolve = resolve; + }); + try { + const result = await this.agm.invoke("T42.Wnd.Create", options, this.agmTarget, { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_RESPONSE_TIMEOUT_MS + }); + if (result.returned === undefined) { + throw new Error("failed to execute T42.Wnd.Create - unknown reason"); + } + const id = result.returned.id; + const win = await windowStore.waitFor(id); + if (!this.configuration || this.configuration.windowAvailableOnURLChanged) { + setTimeout(() => { + if (win.API.windowType === "electron") { + win.Events.handleUrlChanged(win.API.url); + } + }, 0); + } + return win.API; + } + finally { + finishedResolve(); + } + } + async close(w, options) { + const result = await this.execute("close", { windowId: w.id, options }, `Closed`); + if (options) { + return result.closed; + } + return w; + } + async navigate(w, newUrl, urlLoadOptions) { + let methodResponseTimeoutMs = 120000; + if (typeof urlLoadOptions === "object" && typeof urlLoadOptions.timeout === "number") { + methodResponseTimeoutMs = urlLoadOptions.timeout * 1000; + delete urlLoadOptions.timeout; + } + await this.execute("navigate", { windowId: w.id, options: { url: newUrl, urlLoadOptions }, invocationOptions: { methodResponseTimeoutMs } }, "UrlChanged"); + return w; + } + async setStyle(w, style) { + var _a; + const stylePromises = []; + const wait = (promise) => stylePromises.push(promise); + if (!isUndefinedOrNull(style.focus) && !w.isFocused) { + wait(w.focus()); + } + if (!isUndefinedOrNull(style.hidden)) { + const toBeVisible = !style.hidden; + wait(w.setVisible(toBeVisible)); + } + if (!isUndefinedOrNull(style.onTop)) { + wait(w.setOnTop(style.onTop)); + } + if (!isNullOrWhiteSpace(style.tabTooltip) || !isNullOrWhiteSpace(style.tabToolTip)) { + const toolTip = (_a = style.tabTooltip) !== null && _a !== void 0 ? _a : style.tabToolTip; + wait(w.setTabTooltip(toolTip)); + } + if (!isNullOrWhiteSpace(style.tabTitle)) { + wait(this.execute("setTabTitle", { windowId: w.id, options: { tabTitle: style.tabTitle } })); + } + const constraints = { + minHeight: style.minHeight, + minWidth: style.minWidth, + maxHeight: style.maxHeight, + maxWidth: style.maxWidth, + }; + const hasConstraints = !isEmpty(constraints); + if (hasConstraints) { + wait(w.setSizeConstraints(constraints)); + } + const buttons = { + allowClose: style.allowClose, + allowCollapse: style.allowCollapse, + allowLockUnlock: style.allowLockUnlock, + allowMaximize: style.allowMaximize, + allowMinimize: style.allowMinimize + }; + const hasButtons = !isEmpty(buttons); + if (hasButtons) { + wait(w.resetButtons(buttons)); + } + await Promise.all(stylePromises); + return w; + } + async setSizeConstraints(w, constraints) { + await this.execute("setSizeConstraints", { windowId: w.id, options: constraints }); + return w; + } + async getSizeConstraints(w) { + const sizeConstraint = await this.execute("getSizeConstraints", { windowId: w.id }); + return sizeConstraint; + } + async setTabTooltip(w, tabTooltip) { + await this.execute("setTabTooltip", { windowId: w.id, options: { tabTooltip } }); + return w; + } + async getTabTooltip(w) { + const result = await this.execute("getTabTooltip", { windowId: w.id }); + return result.tabTooltip; + } + async resetButtons(w, buttonsConfig) { + await this.execute("resetButtons", { windowId: w.id, options: buttonsConfig }); + return w; + } + async getButtons(w) { + const buttons = await this.execute("getButtons", { windowId: w.id }); + return buttons; + } + async setOnTop(w, onTop) { + await this.execute("setOnTop", { windowId: w.id, options: { onTop } }); + return w; + } + async setTitle(w, newTitle) { + const options = { + windowId: w.id, + options: { + title: newTitle + } + }; + await this.execute("setTitle", options, "TitleChanged"); + return w; + } + async setSticky(w, isSticky) { + const options = { + windowId: w.id, + options: { + isSticky + } + }; + await this.execute("setSticky", options); + return w; + } + async setAllowWorkspaceDrop(w, allowWorkspaceDrop) { + const options = { + windowId: w.id, + options: { + allowWorkspaceDrop + } + }; + await this.execute("setAllowWorkspaceDrop", options); + return w; + } + async pin(windowToPin) { + const options = { + windowId: windowToPin.id + }; + await this.execute("pinTab", options); + return windowToPin; + } + async unpin(pinnedWindow) { + const options = { + windowId: pinnedWindow.id + }; + await this.execute("unpinTab", options); + return pinnedWindow; + } + async moveResize(w, bounds) { + if (typeof window !== "undefined" && window.glueDesktop.versionNum < 31200) { + return new Promise(async (res, rej) => { + const resolveImmediately = this.areBoundsEqual(bounds, w); + let isDone = false; + const done = () => { + if (isDone) { + return; + } + isDone = true; + if (unsubscribeBoundsChanged) { + unsubscribeBoundsChanged(); + unsubscribeBoundsChanged = undefined; + } + res(w); + if (resolveTimeout) { + clearTimeout(resolveTimeout); + resolveTimeout = undefined; + } + }; + let resolveTimeout; + let unsubscribeBoundsChanged; + if (!resolveImmediately) { + unsubscribeBoundsChanged = w.onBoundsChanged((win) => { + if (!this.areBoundsEqual(bounds, win)) { + return; + } + done(); + }); + } + try { + await this.execute("moveResize", { windowId: w.id, options: { bounds } }); + } + catch (error) { + rej(error); + return; + } + if (resolveImmediately) { + done(); + return; + } + resolveTimeout = setTimeout(() => { + done(); + }, 1000); + }); + } + else { + await this.execute("moveResize", { windowId: w.id, options: { bounds } }); + } + return w; + } + async addFrameButton(w, buttonInfo) { + await this.execute("addButton", { windowId: w.id, options: buttonInfo }, "ButtonAdded"); + return w; + } + async removeFrameButton(w, buttonId) { + await this.execute("removeButton", { windowId: w.id, options: buttonId }, "ButtonRemoved"); + return w; + } + async activate(w) { + await this.execute("activate", { windowId: w.id }); + return w; + } + async focus(w) { + await this.execute("focus", { windowId: w.id }); + return w; + } + async maximizeRestore(w) { + await this.execute("maximizeRestore", { windowId: w.id }, "StateChanged"); + return w; + } + async maximize(w) { + await this.execute("maximize", { windowId: w.id }, "StateChanged"); + return w; + } + async restore(w) { + await this.execute("restore", { windowId: w.id }, "StateChanged"); + return w; + } + async minimize(w) { + await this.execute("minimize", { windowId: w.id }, "StateChanged"); + return w; + } + async collapse(w) { + await this.execute("collapse", { windowId: w.id }, "StateChanged"); + return w; + } + async expand(w) { + await this.execute("expand", { windowId: w.id }, "StateChanged"); + return w; + } + async toggleCollapse(w) { + await this.execute("toggleCollapse", { windowId: w.id }, "StateChanged"); + return w; + } + async snap(w, targetWindow, options) { + const args = { + targetWindowId: targetWindow.id + }; + args.snappingEdge = options.direction; + args.autoAlign = options.autoAlign; + await this.execute("snap", { windowId: w.id, options: args }, "CompositionChanged", `CompositionChanged-${targetWindow.id}`); + return w; + } + async attachTab(w, sourceWindow, options) { + await this.execute("attachTab", { + windowId: w.id, + options: { + index: options, + sourceWindowId: sourceWindow.id, + targetWindowId: w.id, + } + }, `WindowFrameAdded-${sourceWindow.id}`, `WindowFrameRemoved-${sourceWindow.id}`); + return w; + } + async detachTab(w, options) { + const eventKeys = ["WindowFrameRemoved", `WindowFrameAdded`]; + if (!isUndefinedOrNull(options === null || options === void 0 ? void 0 : options.relativeTo)) { + eventKeys.push(`CompositionChanged`); + eventKeys.push(`CompositionChanged-${options.relativeTo}`); + } + else { + eventKeys.push("BoundsChanged"); + } + await this.execute("detachTab", { windowId: w.id, options }, ...eventKeys); + return w; + } + async setVisible(w, toBeVisible = true) { + let command; + if (toBeVisible) { + command = "show"; + } + else { + command = "hide"; + } + await this.execute(command, { windowId: w.id }, "VisibilityChanged"); + return w; + } + async center(w, display) { + await this.execute("center", { windowId: w.id, options: display }); + return w; + } + async showLoader(w, loader) { + await this.execute("showLoadingAnimation", { windowId: w.id, options: loader }); + return w; + } + async hideLoader(w) { + await this.execute("hideLoadingAnimation", { windowId: w.id }); + return w; + } + async updateContext(w, context, replace) { + let un; + try { + const contextWithoutUndefinedValues = this.swapUndefinedToNull(context); + const done = new Promise((resolve, reject) => { + un = w.onContextUpdated(() => { + resolve(); + }); + }); + await Promise.all([this.execute("updateContext", { + windowId: w.id, context: contextWithoutUndefinedValues, replace + }), done]); + return w; + } + finally { + if (un) { + un(); + } + } + } + async lock(w) { + await this.execute("lockUnlock", { windowId: w.id, options: { lock: true } }, "FrameIsLockedChanged"); + return w; + } + async unlock(w) { + await this.execute("lockUnlock", { windowId: w.id, options: { lock: false } }, "FrameIsLockedChanged"); + return w; + } + async getIcon(w) { + const result = await this.execute("getIcon", { + windowId: w.id, + options: {} + }); + return result.icon; + } + async setIcon(w, base64Image) { + await this.execute("setIcon", { + windowId: w.id, + options: { + dataURL: base64Image + } + }); + return w; + } + async setFrameColor(w, frameColor) { + await this.execute("setFrameColor", { windowId: w.id, options: { frameColor } }, "FrameColorChanged"); + return w; + } + async setTabHeaderVisible(w, toBeTabHeaderVisible) { + await this.execute("setTabHeaderVisible", { + windowId: w.id, + options: { + toShow: toBeTabHeaderVisible + } + }, "TabHeaderVisibilityChanged"); + return w; + } + async showGroupPopup(id, options) { + const reformatedOptions = this.showPopupCore(id, options); + await this.executeGroup("showGroupPopup", { + groupId: id, + options: reformatedOptions + }); + } + async showPopup(targetWindow, options) { + const reformatedOptions = this.showPopupCore(targetWindow.id, options); + await this.execute("showPopupWindow", { + windowId: targetWindow.id, + options: reformatedOptions + }); + return targetWindow; + } + async createFlydown(windowId, options) { + if (!options) { + throw new Error("The options object is not valid!"); + } + const optionsCopy = { ...options }; + if (!optionsCopy.horizontalOffset) { + optionsCopy.horizontalOffset = 0; + } + if (!optionsCopy.verticalOffset) { + optionsCopy.verticalOffset = 0; + } + const fullOptions = this.reformatFlydownOptions(windowId, optionsCopy); + return this.execute("setFlydownArea", { windowId, options: fullOptions }).then(() => { + const zoneIds = fullOptions.zones.map((z) => z.id); + fullOptions.zones.forEach((z) => { + let callback = typeof (z.flydownSize) === "function" ? + z.flydownSize : () => z.flydownSize; + if (options.size instanceof Function && z.flydownSize) { + callback = async (data, cancel) => { + let result; + if (options.size instanceof Function) { + result = await options.size(data, cancel); + } + if (z.flydownSize instanceof Function && z.flydownSize !== options.size) { + return await z.flydownSize(data, cancel) || result; + } + return result || z.flydownSize; + }; + } + this._registry.clearKey(`${fullOptions.targetId}_${z.id}`); + this._registry.add(`${fullOptions.targetId}_${z.id}`, callback); + }); + return { + destroy: () => this.clearFlydownArea(fullOptions.targetId, zoneIds), + options: optionsCopy + }; + }); + } + async setModalState(windowId, isModal) { + return this.execute("setModalState", { windowId, options: { isModal } }); + } + async autoArrange(displayId) { + return this.execute("autoArrange", { options: { displayId } }); + } + async handleFlydownBoundsRequested(targetId, data) { + const cancelCallback = () => data.cancel = true; + const callbackData = { + zoneId: data.flydownId, + flydownWindowBounds: data.flydownWindowBounds, + flydownWindowId: data.flydownWindowId, + }; + const responses = await Promise.all(this._registry.execute(`${targetId}_${data.flydownId}`, callbackData, cancelCallback)); + if (responses.length === 1) { + const defaultResponse = { height: 0, width: 0, top: 0, left: 0 }; + const response = typeof (responses[0]) === "object" && !Array.isArray(responses[0]) ? responses[0] : defaultResponse; + const responseOptions = { ...data, flydownWindowBounds: response }; + return responseOptions; + } + } + async handleOnEventRequested(callbackId, args) { + var _a; + const callbacks = (_a = this.unsubCallbacks[callbackId]) !== null && _a !== void 0 ? _a : []; + let prevented = false; + const preventArgs = []; + await Promise.all(callbacks.map((cb) => { + return new Promise((resolve, reject) => { + cb(() => { + resolve(); + }, () => { + reject(); + }, (pArgs) => { + prevented = true; + preventArgs.push(pArgs); + }, args); + }); + })); + return { prevented, preventArgs }; + } + async zoomIn(window) { + await this.execute("zoomIn", { + windowId: window.id, + }); + return window; + } + async zoomOut(window) { + await this.execute("zoomOut", { + windowId: window.id, + }); + return window; + } + async setZoomFactor(window, zoomFactor) { + await this.execute("setZoomFactor", { + windowId: window.id, + options: { + zoomFactor + } + }); + return window; + } + async showDevTools(window) { + await this.execute("showDevTools", { + windowId: window.id, + }); + return window; + } + async capture(window, options) { + const base64screenshot = (await this.execute("captureScreenshot", { windowId: window.id, options: { ...options } })).data; + return base64screenshot; + } + async captureGroup(windowIds, options) { + const base64screenshot = (await this.execute("captureGroupScreenshot", { windowId: windowIds[0], options: { groupWindowIds: windowIds, ...options } })).data; + return base64screenshot; + } + async flash(resultWindow, options) { + await this.execute("flash", { windowId: resultWindow.id, options: { ...options } }); + return resultWindow; + } + async flashTab(resultWindow, options) { + await this.execute("flashTab", { windowId: resultWindow.id, options: { ...options } }); + return resultWindow; + } + async configure(windowId, options) { + return this.execute("configure", { windowId, options: { ...options } }); + } + async print(resultWindow, options) { + await this.execute("print", { windowId: resultWindow.id, options: { ...options } }); + return resultWindow; + } + async printToPDF(resultWindow, options) { + const filePath = (await this.execute("printToPDF", { windowId: resultWindow.id, options: { ...options } })).filePath; + return filePath; + } + async place(window, options) { + const copy = { ...options }; + if (!options.display || options.display === "current") { + copy.display = await window.getDisplay(); + } + if (copy.display && typeof copy.display !== "string" && typeof copy.display !== "number") { + copy.display = copy.display.index + 1; + } + return this.execute("place", { windowId: window.id, options: { ...copy } }); + } + async refresh(resultWindow, ignoreCache) { + await this.execute("refresh", { windowId: resultWindow.id, options: { ignoreCache } }); + return resultWindow; + } + async download(resultWindow, url, options = {}) { + options.enableDownloadBar = !options.silent; + const result = await this.execute("downloadURL", { windowId: resultWindow.id, options: { url, options } }); + return { + url, + path: result.fullPath, + size: result.fileSize, + }; + } + async configureWindow(resultWindow, options) { + await this.execute("configureWindow", { windowId: resultWindow.id, options }); + return resultWindow; + } + async getWindowConfiguration(resultWindow) { + const config = await this.execute("getWindowConfiguration", { windowId: resultWindow.id }); + return config; + } + async startDrag(resultWindow, options) { + await this.execute("startDrag", { windowId: resultWindow.id, options }); + return resultWindow; + } + showDialog(resultWindow, options) { + return new Promise((res, rej) => { + const token = Utils.generateId(); + const un = this._registry.add("event", (args) => { + if (args.type === "DialogResult" && args.windowId === resultWindow.id && args.data.token === token) { + un(); + const data = args.data; + if ("status" in data) { + if (data.status === "failed") { + rej(new Error(data.message)); + } + else if (data.status === "successful") { + res(data.result); + } + } + } + }); + this.execute("showDialog", { windowId: resultWindow.id, options: Object.assign({}, { ...options }, { token }) }); + }); + } + async execute(command, options, ...eventKeys) { + return this.executeCore(this.WndMethodName, command, options, ...eventKeys); + } + async executeGroup(command, options, ...eventKeys) { + return this.executeCore(this.GroupMethodName, command, options, ...eventKeys); + } + async ungroup(w, options) { + const args = { + windowId: w.id, + options + }; + await this.execute("ungroup", args); + return w; + } + async updateJumpList(windowId, options) { + const args = { + windowId, + options + }; + await this.execute("updateJumplist", args); + } + async getJumpList(windowId) { + const args = { + windowId, + }; + const result = await this.execute("getJumplist", args); + return result; + } + onClosing(callback, gdWindow) { + const glue42gd = typeof window !== "undefined" && window.glue42gd; + if (glue42gd && gdWindow.windowType === "electron") { + return glue42gd.addCloseHandler(callback, gdWindow.id); + } + else { + return this.nonWindowHandlers(callback, gdWindow.id, "OnClosing"); + } + } + onGroupClosing(callback, group) { + return this.nonWindowHandlersCore(group.id, "OnClosing", true, callback); + } + onRefreshing(callback, gdWindow) { + const glue42gd = typeof window !== "undefined" && window.glue42gd; + if (glue42gd && gdWindow.windowType === "electron") { + return glue42gd.addRefreshHandler(callback, gdWindow.id); + } + else { + return this.nonWindowHandlers(callback, gdWindow.id, "OnRefreshing"); + } + } + onNavigating(callback, gdWindow) { + const glue42gd = typeof window !== "undefined" && window.glue42gd; + if (glue42gd && gdWindow.windowType === "electron") { + return glue42gd.addWillNavigateHandler(callback, gdWindow.id); + } + else { + return this.nonWindowHandlers(callback, gdWindow.id, "OnNavigating"); + } + } + async clone(window, cloneOptions) { + const args = { + windowId: window.id, + options: cloneOptions + }; + const result = await this.execute("clone", args); + const win = await windowStore.waitFor(result.id); + return win.API; + } + async executeCode(targetWindow, code) { + const args = { + windowId: targetWindow.id, + options: { + code + } + }; + return this.execute("executeCode", args); + } + async goBack(resultWindow) { + await this.execute("goBack", { windowId: resultWindow.id }); + } + async goForward(resultWindow) { + await this.execute("goForward", { windowId: resultWindow.id }); + } + async getDockingPlacement(window) { + return this.execute("getDockingPlacement", { windowId: window.id }); + } + dock(window, options) { + return this.execute("dock", { windowId: window.id, options }); + } + clearCallbacks(id) { + const keys = Object.keys(this.unsubCallbacks); + keys.forEach((key) => { + if (key.startsWith(id)) { + delete this.unsubCallbacks[key]; + } + }); + } + nonWindowHandlers(callback, targetId, type) { + return this.nonWindowHandlersCore(targetId, type, false, callback); + } + nonWindowHandlersCore(targetId, type, isGroup, callback) { + const id = `${targetId}-${type}`; + const unsub = () => { + var _a; + if (this.unsubCallbacks[id]) { + const callbacks = this.unsubCallbacks[id]; + this.unsubCallbacks[id] = callbacks.filter((cb) => cb !== callback); + if (this.unsubCallbacks[id].length === 0) { + delete this.unsubCallbacks[id]; + } + } + const cbs = (_a = this.unsubCallbacks[id]) !== null && _a !== void 0 ? _a : []; + if (cbs.length === 0) { + const options = { + unsubscribe: true + }; + if (isGroup) { + this.executeGroup(type, { + groupId: targetId, + options + }); + } + else { + this.execute(type, { + windowId: targetId, + options + }); + } + } + }; + if (this.unsubCallbacks[id]) { + this.unsubCallbacks[id].push(callback); + return unsub; + } + else { + this.unsubCallbacks[id] = [callback]; + } + if (isGroup) { + this.executeGroup(type, { groupId: targetId }); + } + else { + this.execute(type, { windowId: targetId }); + } + return unsub; + } + reformatFlydownOptions(windowId, options) { + const assignGeneralIfUnassigned = (zone, prop) => { + if (options[prop] && (zone[prop] === undefined || zone[prop] === null)) { + const valueFromOptions = options[prop]; + zone[prop] = valueFromOptions; + } + }; + const zones = options.zones.map((z) => { + assignGeneralIfUnassigned(z, "windowId"); + assignGeneralIfUnassigned(z, "targetLocation"); + if (options.size && (z.flydownSize === undefined || z.flydownSize === null)) { + z.flydownSize = options.size; + } + z.flydownBounds = z.flydownSize; + z.flydownId = z.windowId; + if (!z.targetLocation) { + z.targetLocation = "bottom"; + } + return z; + }); + return { + ...options, + zones, + targetId: windowId, + flydownBounds: options.size, + flydownActiveArea: options.activeArea + }; + } + clearFlydownArea(windowId, areaIds) { + return this.execute("clearFlydownWindowArea", { + windowId, + options: {} + }).then(() => { + areaIds.forEach((id) => { + this._registry.clearKey(`${windowId}_${id}`); + }); + }); + } + executeWithoutToken(params, ...eventKeys) { + const uns = []; + const executed = eventKeys === null || eventKeys === void 0 ? void 0 : eventKeys.filter((k) => !isUndefinedOrNull(k)).map((key) => { + return new Promise((r) => { + const [type, windowId = params.windowId] = key.split("-"); + uns.push(this._registry.add("event", (data) => { + if (data.type === type && data.windowId === windowId) { + r(); + } + })); + }); + }); + const action = new Promise((resolve, reject) => { + this.agm.invoke("T42.Wnd.Execute", params, this.agmTarget, { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_RESPONSE_TIMEOUT_MS + }) + .then((i) => { + if (i.returned && i.returned.errorMsg) { + reject(i); + } + else { + resolve(i.returned); + } + }) + .catch((e) => reject(e)); + }); + return Promise.all([action, ...executed]) + .then((r) => { + return r[0]; + }) + .finally(() => { + uns.forEach((un) => un()); + }); + } + async executeCore(methodName, command, options, ...eventKeys) { + const { invocationOptions, ...invocationArgs } = options; + const params = { + ...invocationArgs, + command, + }; + let finishedResolve; + this._finished = new Promise((resolve) => { + finishedResolve = resolve; + }); + try { + if (typeof window !== "undefined" && window.glueDesktop.versionNum < 31200) { + return await this.executeWithoutToken(params, ...eventKeys); + } + else { + return await this.executeWithToken(methodName, params, invocationOptions); + } + } + finally { + finishedResolve(); + } + } + async executeWithToken(methodName, options, invocationOptions) { + let un; + try { + const token = Utils.generateId(); + const event = new Promise((r) => { + un = this._registry.add("event", (data) => { + if (data.token === token) { + r(); + } + }); + }); + const execute = new Promise((resolve, reject) => { + options.token = token; + if (!invocationOptions) { + invocationOptions = { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_RESPONSE_TIMEOUT_MS + }; + } + else if (!invocationOptions.methodResponseTimeoutMs) { + invocationOptions.methodResponseTimeoutMs = INTEROP_METHOD_RESPONSE_TIMEOUT_MS; + } + else if (!invocationOptions.waitTimeoutMs) { + invocationOptions.waitTimeoutMs = INTEROP_METHOD_WAIT_TIMEOUT_MS; + } + this.agm.invoke(methodName, options, this.agmTarget, invocationOptions) + .then((i) => { + if (i.returned && i.returned.errorMsg) { + reject(new Error(i.returned.errorMsg)); + } + else { + resolve(i.returned); + } + }) + .catch((e) => { + const error = Utils.typedError(e); + reject(error); + }); + }); + const result = await Promise.all([execute, event]); + return result[0]; + } + finally { + if (un) { + un(); + } + } + } + areBoundsEqual(requested, w) { + const current = w.bounds; + const settings = w.settings; + let height = requested.height; + let width = requested.width; + if (requested.height < settings.minHeight) { + height = settings.minHeight; + } + if (requested.height > settings.maxHeight) { + height = settings.maxHeight; + } + if (requested.width < settings.minWidth) { + width = settings.minWidth; + } + if (requested.width > settings.maxWidth) { + width = settings.maxWidth; + } + const areHeightsEqual = height ? current.height === height : true; + const areWidthsEqual = width ? current.width === width : true; + const areLeftsEqual = requested.left ? current.left === requested.left : true; + const areTopsEqual = requested.top ? current.top === requested.top : true; + return areHeightsEqual && areWidthsEqual && areLeftsEqual && areTopsEqual; + } + swapUndefinedToNull(context) { + try { + const copy = {}; + for (const key of Object.keys(context)) { + let value = context[key]; + if (typeof value === "undefined") { + value = null; + } + copy[key] = value; + } + return copy; + } + catch { + return context; + } + } + showPopupCore(id, options) { + if (!options) { + throw new Error("The options object is not valid!"); + } + const optionsCopy = { ...options }; + if (!optionsCopy.targetLocation) { + optionsCopy.targetLocation = "bottom"; + } + const reformatedOptions = { + ...optionsCopy, + popupBounds: optionsCopy.size, + targetId: id, + popupId: optionsCopy.windowId + }; + return reformatedOptions; + } + } + var executor = new GDExecutor(); + + class GDEnvironment { + constructor(agm, logger, appManagerGetter, displayAPIGetter, channelsAPIGetter, wndId, groupId) { + this._registry = CallbackRegistryFactory(); + this._agm = agm; + this._logger = logger.subLogger("gd-env"); + this._windowId = wndId; + this._groupId = groupId; + this._appManagerGetter = appManagerGetter; + this._displayAPIGetter = displayAPIGetter; + this._channelsAPIGetter = channelsAPIGetter; + } + init() { + return new Promise((resolve, reject) => { + this._agm.register("T42.Wnd.OnEventWithResponse", (args, caller) => { + return this.respondToEvent(args); + }); + new Promise((streamResolve, streamReject) => { + this._agm.subscribe("T42.Wnd.OnEvent", { + target: "best", + arguments: { + withConfig: true + }, + onData: (streamData) => { + if (streamData.data.type === "Configuration") { + this._configuration = streamData.data; + executor.setConfiguration(this._configuration); + return; + } + this.updateWindow(streamData.data, resolve); + executor.handleEvent(streamData.data); + }, + onConnected: (instance) => { + this._agmInstance = instance; + executor.init(this._agm, this._agmInstance); + } + }).catch((error) => { + var _a; + const message = `${(_a = error === null || error === void 0 ? void 0 : error.method) === null || _a === void 0 ? void 0 : _a.name} - ${JSON.stringify(error === null || error === void 0 ? void 0 : error.called_with)} - ${error === null || error === void 0 ? void 0 : error.message}`; + reject(new Error(message)); + }); + }); + }); + } + get executor() { + return executor; + } + open(name, url, options) { + options = options || {}; + const copyOptions = { ...options }; + if (copyOptions.relativeTo !== undefined && typeof copyOptions.relativeTo !== "string") { + copyOptions.relativeTo = copyOptions.relativeTo.id || ""; + } + copyOptions.name = name; + copyOptions.url = url; + copyOptions.windowState = options.windowState || options.state; + delete copyOptions.state; + return this.executor.open(copyOptions); + } + createFlydown(windowId, options) { + return this.executor.createFlydown(windowId, options); + } + async showPopup(windowId, options) { + const window = windowStore.get(windowId); + await this.executor.showPopup(window.API, options); + } + tabAttached(callback) { + return this._registry.add("tab-attached", callback); + } + tabDetached(callback) { + return this._registry.add("tab-detached", callback); + } + onWindowFrameColorChanged(callback) { + return this._registry.add("frame-color-changed", callback); + } + onEvent(callback) { + return this._registry.add("window-event", callback); + } + my() { + return this._windowId; + } + myGroup() { + return this._groupId; + } + onCompositionChanged(callback) { + return this._registry.add("composition-changed", callback); + } + onGroupHeaderVisibilityChanged(callback) { + return this._registry.add("group-header-changed", callback); + } + onGroupVisibilityChanged(callback) { + return this._registry.add("group-visibility-changed", callback); + } + onGroupStateChanged(callback) { + return this._registry.add("group-state-changed", callback); + } + onWindowGotFocus(callback) { + return this._registry.add("got-focus", callback); + } + onWindowLostFocus(callback) { + return this._registry.add("lost-focus", callback); + } + onWindowsAutoArrangeChanged(callback) { + return this._registry.add("windows-auto-arranged-changed", callback); + } + respondToEvent(args) { + if (args.type === "ShowFlydownBoundsRequested") { + return this.executor.handleFlydownBoundsRequested(args.data.windowId, args.data); + } + else if (args.type === "OnClosing" || args.type === "OnRefreshing" || args.type === "OnNavigating") { + return this.executor.handleOnEventRequested(args.data.callbackId, args.data.args); + } + return Promise.reject(`There isn't a handler for ${args.type}`); + } + updateWindow(windowInfo, readyResolve) { + const extendedStreamEvent = this.getExtendedStreamEvent(windowInfo); + if (windowInfo.type === "Snapshot") { + const windowInfoFullInfoEvent = windowInfo; + windowInfoFullInfoEvent.windows.forEach((w) => { + const existingWindow = windowStore.get(w.id); + if (existingWindow) { + existingWindow.Events.handleUpdate(this.mapToWindowConstructorOptions(w)); + existingWindow.GroupCreationArgs = this.mapToGroupCreationArgs(w); + } + else { + this.createWindowFromSnapshot(w.id, w); + } + this._registry.execute("window-event", extendedStreamEvent); + }); + readyResolve(this); + return; + } + if (windowInfo.type === "CommandExecuted") { + this._registry.execute("window-event", extendedStreamEvent); + return; + } + if (windowInfo.type === "Created") { + const windowInfoCreatedEvent = (windowInfo); + this.createWindowFromStream(windowInfoCreatedEvent.windowId, windowInfoCreatedEvent.data || {}); + this._registry.execute("window-event", extendedStreamEvent); + return; + } + if (windowInfo.type === "OnGroupVisibilityChanged") { + const info = windowInfo; + this._registry.execute("group-visibility-changed", info.data); + this._registry.execute("window-event", windowInfo); + return; + } + if (windowInfo.type === "OnGroupStateChanged") { + const info = windowInfo; + this._registry.execute("group-state-changed", info.data); + this._registry.execute("window-event", windowInfo); + return; + } + if (windowInfo.type === "OnWindowsAutoArrangeChanged") { + const info = windowInfo; + this._registry.execute("windows-auto-arranged-changed", info.data); + this._registry.execute("window-event", windowInfo); + return; + } + const windowObjectAndEvents = windowStore.get((windowInfo).windowId); + if (!windowObjectAndEvents) { + this._logger.error(`received update for unknown window. Stream:', ${JSON.stringify(windowInfo, null, 4)}`); + return; + } + const theWindow = windowObjectAndEvents.API; + const theWindowEvents = windowObjectAndEvents.Events; + if (windowInfo.type === "BoundsChanged") { + const windowInfoBoundsChangedEvent = windowInfo; + theWindowEvents.handleBoundsChanged(windowInfoBoundsChangedEvent.data); + } + if (windowInfo.type === "UrlChanged") { + const windowInfoUrlChangedEvent = windowInfo; + windowStore.setUrlChangedState(windowInfoUrlChangedEvent.windowId); + theWindowEvents.handleUrlChanged(windowInfoUrlChangedEvent.data); + } + if (windowInfo.type === "TitleChanged") { + const windowInfoTitleChanged = windowInfo; + theWindowEvents.handleTitleChanged(windowInfoTitleChanged.data); + } + if (windowInfo.type === "IsStickyChanged") { + const windowInfoIsStickyChangedChanged = windowInfo; + theWindowEvents.handleIsStickyChanged(windowInfoIsStickyChangedChanged.data); + } + if (windowInfo.type === "VisibilityChanged") { + theWindowEvents.handleVisibilityChanged(windowInfo.data); + } + if (windowInfo.type === "ContextChanged") { + theWindowEvents.handleContextUpdated(windowInfo.data); + } + if (windowInfo.type === "StateChanged") { + theWindowEvents.handleWindowChangeState(windowInfo.data); + } + if (windowInfo.type === "FrameColorChanged") { + theWindowEvents.handleFrameColorChanged(windowInfo.data); + this._registry.execute("frame-color-changed", theWindow); + } + if (windowInfo.type === "CompositionChanged") { + const windowInfoCompositionChanged = windowInfo; + theWindowEvents.handleCompositionChanged(windowInfoCompositionChanged.data); + windowStore.setCompositionChangedState(windowObjectAndEvents); + this._registry.execute("composition-changed", windowInfoCompositionChanged.data); + } + if (windowInfo.type === "GroupHeaderVisibilityChanged") { + const info = windowInfo; + theWindowEvents.handleGroupHeaderVisibilityChanged(info.data.groupHeaderVisible); + this._registry.execute("group-header-changed", info.data); + } + if (windowInfo.type === "FocusChanged") { + const windowInfoFocusChanged = windowInfo; + this.focusChanged(theWindowEvents, theWindow, windowInfoFocusChanged.data); + } + if (windowInfo.type === "WindowFrameChanged") { + theWindowEvents.handleFrameAttached(windowInfo.data.frameId, windowInfo.data.frameId, windowInfo.data.isTabHeaderVisible); + this._registry.execute("frame-changed"); + } + if (windowInfo.type === "WindowFrameAdded") { + const winsToBeNotified = getWindowsByTabGroupId(theWindow.id, windowInfo.data.frameId); + const data = windowInfo.data; + theWindowEvents.handleAttached(data.frameId, data.frameId, data.isTabHeaderVisible, data.isLocked, winsToBeNotified) + .then(async () => { + if (winsToBeNotified.length > 0) { + await executor.finished; + this._registry.execute("tab-attached", theWindow, windowInfo.data.frameId, windowInfo.data.isTabHeaderVisible); + } + }); + } + if (windowInfo.type === "WindowFrameRemoved") { + const oldTabGroupId = theWindow.tabGroupId; + const winsToBeNotified = getWindowsByTabGroupId(theWindow.id, oldTabGroupId); + theWindowEvents.handleDetached(windowInfo.data.isLocked, winsToBeNotified) + .then(async () => { + if (winsToBeNotified.length > 0) { + await executor.finished; + this._registry.execute("tab-detached", theWindow, windowInfo.data.frameId, theWindow.tabGroupId); + } + }); + } + if (windowInfo.type === "TabHeaderVisibilityChanged") { + theWindowEvents.handleTabHeaderVisibilityChanged(windowInfo.data.isTabHeaderVisible); + } + if (windowInfo.type === "FrameSelectionChanged") { + theWindowEvents.handleFrameSelectionChanged(windowInfo.data.newWindowId, windowInfo.data.prevWindowId); + } + if (windowInfo.type === "ButtonClicked") { + theWindowEvents.handleFrameButtonClicked(windowInfo.data); + } + if (windowInfo.type === "ButtonAdded") { + theWindowEvents.handleFrameButtonAdded(windowInfo.data); + } + if (windowInfo.type === "ButtonRemoved") { + theWindowEvents.handleFrameButtonRemoved(windowInfo.data); + } + if (windowInfo.type === "WindowZoomFactorChanged") { + theWindowEvents.handleZoomFactorChanged(windowInfo.data); + } + if (windowInfo.type === "Closed") { + windowStore.remove(windowObjectAndEvents); + theWindowEvents.handleWindowClose(); + } + if (windowInfo.type === "FrameIsLockedChanged") { + theWindowEvents.handleFrameIsLockedChanged(windowInfo.data); + } + if (windowInfo.type === "PlacementSettingsChanged") { + theWindowEvents.handlePlacementSettingsChanged(windowInfo.data); + } + if (windowInfo.type === "DockingChanged") { + theWindowEvents.handleDockingChanged(windowInfo.data); + } + if (windowInfo.type === "AllowWorkspaceDropChanged") { + theWindowEvents.handleAllowWorkspaceDropChanged(windowInfo.data); + } + if (windowInfo.type === "IsPinnedChanged") { + theWindowEvents.handleIsPinnedChanged(windowInfo.data); + } + if (windowInfo.type === "WindowChannelRestrictionsChanged") { + theWindowEvents.handleChannelRestrictionsChanged(windowInfo.data); + } + this._registry.execute("window-event", extendedStreamEvent); + } + createWindowFromSnapshot(windowId, options) { + const windowObjAndEvents = this.createWindowCore(windowId, options); + windowStore.add(windowObjAndEvents, { + ready: true, + urlChanged: true, + compositionChanged: true + }); + } + createWindowFromStream(windowId, options) { + var _a; + const windowObjAndEvents = this.createWindowCore(windowId, options); + const isRemote = windowObjAndEvents.API.windowType === "remote"; + const isFrameless = windowObjAndEvents.API.windowType === "electron" && windowObjAndEvents.API.mode === "frameless"; + const isHidden = windowObjAndEvents.API.isVisible === false; + let urlChanged = false; + let compositionChanged = false; + if (isRemote) { + urlChanged = true; + } + if (isFrameless || isHidden) { + compositionChanged = true; + } + if (!isRemote) { + urlChanged = !((_a = this._configuration) === null || _a === void 0 ? void 0 : _a.windowAvailableOnURLChanged); + } + windowStore.add(windowObjAndEvents, { + ready: true, + urlChanged, + compositionChanged + }); + } + createWindowCore(windowId, options) { + const windowObjAndEvents = windowFactory(windowId, this.mapToWindowConstructorOptions(options), executor, this._logger, this._appManagerGetter, this._displayAPIGetter, this._channelsAPIGetter, this._agm); + windowObjAndEvents.GroupCreationArgs = this.mapToGroupCreationArgs(options); + return windowObjAndEvents; + } + async focusChanged(theWindowEvents, theWindow, focus) { + theWindowEvents.handleFocusChanged(focus); + try { + if (!this._configuration.windowAvailableOnURLChanged) { + await windowStore.waitFor(theWindow.id); + } + } + catch (error) { + return; + } + if (focus) { + this._registry.execute("got-focus", theWindow); + } + else { + this._registry.execute("lost-focus", theWindow); + } + } + mapToWindowConstructorOptions(args) { + return { + name: args.name, + context: args.context, + bounds: args.bounds, + url: args.url, + title: args.title, + isVisible: args.isVisible, + focus: args.isFocused, + state: args.state, + frameColor: args.frameColor, + groupId: args.groupId, + neighbours: args.neighbors, + isFocused: args.isFocused, + isGroupHeaderVisible: args.groupHeaderVisible, + isCollapsed: args.isCollapsed, + tabGroupId: args.frameId, + frameId: args.frameId, + mode: args.mode, + isTabHeaderVisible: args.isTabHeaderVisible, + isTabSelected: args.isActiveTab, + settings: args.settings, + windowType: args.windowType, + zoomFactor: args.zoomFactor, + isLocked: args.isLocked, + placementSettings: args.placementSettings, + isSticky: args.isSticky, + tabIndex: args.tabIndex, + frameButtons: args.frameButtons, + jumpListOptions: args.jumpList, + applicationName: args.applicationName, + allowWorkspaceDrop: args.allowWorkspaceDrop, + isPinned: args.isPinned + }; + } + mapToGroupCreationArgs(args) { + return { + isGroupHibernated: args.isGroupHibernated, + isGroupVisible: args.isGroupVisible + }; + } + getExtendedStreamEvent(streamEvent) { + try { + if (!streamEvent.windowId) { + return streamEvent; + } + const window = windowStore.get(streamEvent.windowId); + if (!window) { + return streamEvent; + } + const result = { + state: streamEvent.type, + windowName: window.API.name, + ...streamEvent + }; + if (result.state === "WindowFrameAdded") { + result.state = "TabAttached"; + } + if (result.state === "StateChanged") { + result.state = result.data.charAt(0).toUpperCase() + result.data.slice(1); + } + if (result.state === "ButtonAdded") { + result.state = "FrameButtonAdded"; + } + if (result.state === "ButtonRemoved") { + result.state = "FrameButtonRemoved"; + } + return result; + } + catch (error) { + return streamEvent; + } + } + } + + var envDetector = (agm, logger, appManagerGetter, displayAPIGetter, channelsAPIGetter, gdMajorVersion) => { + var _a; + const _logger = logger; + if (gdMajorVersion === 2) { + _logger.trace("running in HC"); + throw new Error("GD2 not supported"); + } + else if (gdMajorVersion >= 3) { + _logger.trace("running in GD 3"); + return new GDEnvironment(agm, _logger, appManagerGetter, displayAPIGetter, channelsAPIGetter, window.glue42gd.windowId, (_a = window.webGroupsManager) === null || _a === void 0 ? void 0 : _a.id).init(); + } + else { + _logger.trace("running in Browser or Node"); + return new GDEnvironment(agm, _logger, appManagerGetter, displayAPIGetter, channelsAPIGetter).init(); + } + }; + + var groupFactory = (id, executor) => { + const _registry = CallbackRegistryFactory(); + const _windowsId = []; + let _isHibernatedFlag; + let _isVisible; + async function addWindow(winId) { + var _a, _b, _c, _d; + if (_windowsId.indexOf(winId) === -1) { + _windowsId.push(winId); + const win = windowStore.get(winId); + win.Events.handleGroupChanged(groupObject, undefined); + _isHibernatedFlag = (_b = (_a = win.GroupCreationArgs.isGroupHibernated) !== null && _a !== void 0 ? _a : _isHibernatedFlag) !== null && _b !== void 0 ? _b : false; + _isVisible = (_d = (_c = win.GroupCreationArgs.isGroupVisible) !== null && _c !== void 0 ? _c : _isVisible) !== null && _d !== void 0 ? _d : true; + await executor.finished; + _registry.execute("window-added", groupObject, win.API); + } + } + async function removeWindow(win) { + const index = _windowsId.indexOf(win.API.id); + if (index !== -1) { + _windowsId.splice(index, 1); + win.Events.handleGroupChanged(undefined, groupObject); + await executor.finished; + _registry.execute("window-removed", groupObject, win.API); + } + } + function find(window, success, error) { + let winId; + if (typeof window === "string") { + winId = window; + } + else if (!isUndefinedOrNull(window)) { + winId = window.id; + } + const win = _mapToWindowObject(winId); + if (win) { + if (typeof success === "function") { + success(win); + } + return win; + } + else { + if (typeof error === "function") { + error(`No window with ID: ${winId}`); + } + } + } + function windows(success) { + const mappedWindows = _mapToWindowObjects(); + return mappedWindows; + } + async function execute(command, options, ...keys) { + await executor.execute(command, options, ...keys); + return groupObject; + } + function handleGroupHeaderVisibilityChanged(windowInfo) { + _registry.execute("header-visibility-changed", groupObject); + } + function handleGroupVisibilityChanged(visibile) { + _isVisible = visibile; + _registry.execute("group-visibility-changed", groupObject); + } + function handleGroupHibernateChanged(isHibernatedFlag) { + _isHibernatedFlag = isHibernatedFlag; + } + function _mapToWindowObjects() { + const winObjects = []; + _windowsId.forEach((winId) => { + const windowObject = _mapToWindowObject(winId); + if (typeof windowObject !== "undefined") { + winObjects.push(windowObject); + } + }); + return winObjects; + } + function _mapToWindowObject(windowId) { + return windowStore.get(windowId) ? windowStore.get(windowId).API : undefined; + } + function _getGroupHeaderVisibility() { + const windowWithHiddenHeader = _mapToWindowObjects().find((w) => !w.isGroupHeaderVisible); + const _isGroupHeaderVisible = windowWithHiddenHeader === undefined; + return _isGroupHeaderVisible; + } + function isHibernated() { + return _isHibernatedFlag; + } + function onHeaderVisibilityChanged(callback) { + return _registry.add("header-visibility-changed", callback); + } + function onWindowAdded(callback) { + return _registry.add("window-added", callback); + } + function onWindowRemoved(callback) { + return _registry.add("window-removed", callback); + } + function onVisibilityChanged(callback) { + if (!callback) { + throw new Error("Callback argument is required"); + } + if (callback && typeof callback !== "function") { + throw new Error("Callback argument must be a function"); + } + return _registry.add("group-visibility-changed", callback); + } + function onClosing(callback) { + if (typeof callback !== "function") { + throw new Error("callback must be a function"); + } + const callbackWrap = (success, error, prevent) => { + const promise = callback(prevent); + if (promise === null || promise === void 0 ? void 0 : promise.then) { + promise.then(success).catch(error); + } + else { + success(); + } + }; + return executor.onGroupClosing(callbackWrap, groupObject); + } + const groupObject = { + id, + get windows() { + return windows(); + }, + find, + get isHeaderVisible() { + return _getGroupHeaderVisibility(); + }, + get isHibernated() { + return isHibernated(); + }, + get isVisible() { + return _isVisible; + }, + showHeader: (success, error) => { + return Utils.callbackifyPromise(() => { + return execute("setGroupHeaderVisibility", { windowId: _windowsId[0], options: { toShow: true } }, ..._windowsId.map((w) => `GroupHeaderVisibilityChanged-${w}`)); + }, success, error); + }, + hideHeader: (success, error) => { + return Utils.callbackifyPromise(() => { + return execute("setGroupHeaderVisibility", { windowId: _windowsId[0], options: { toShow: false } }, ..._windowsId.map((w) => `GroupHeaderVisibilityChanged-${w}`)); + }, success, error); + }, + getTitle: async () => { + const r = await executor.execute("getGroupTitle", { windowId: _windowsId[0] }); + return r.title; + }, + setTitle: async (title) => { + if (isNullOrWhiteSpace(title)) { + throw new Error("`title` must not be null or undefined."); + } + return execute("setGroupTitle", { windowId: _windowsId[0], options: { title } }); + }, + capture: (captureOptions) => { + return executor.captureGroup(_windowsId, captureOptions); + }, + maximize: (success, error) => { + return Utils.callbackifyPromise(() => { + return execute("maximizeGroup", { windowId: _windowsId[0] }, ..._windowsId.map((w) => `StateChanged-${w}`)); + }, success, error); + }, + restore: (success, error) => { + return Utils.callbackifyPromise(() => { + return execute("restoreGroup", { windowId: _windowsId[0] }, ..._windowsId.map((w) => `StateChanged-${w}`)); + }, success, error); + }, + show: (activate) => { + if (!isUndefinedOrNull(activate) && !isBoolean(activate)) { + throw new Error("Activate flag must be a boolean!"); + } + activate = !isUndefinedOrNull(activate) ? activate : true; + return executor.executeGroup("showGroup", { + groupId: id, + options: { activate } + }); + }, + hide: () => { + return executor.executeGroup("hideGroup", { + groupId: id + }); + }, + close: () => { + return executor.executeGroup("closeGroup", { + groupId: id + }); + }, + showPopup: (options) => { + return executor.showGroupPopup(id, options); + }, + onHeaderVisibilityChanged, + onWindowAdded, + onWindowRemoved, + onVisibilityChanged, + onClosing, + }; + const internal = { + get windows() { + return _windowsId; + }, + addWindow, + removeWindow, + handleGroupHeaderVisibilityChanged, + handleGroupVisibilityChanged, + handleGroupHibernateChanged + }; + return { + groupAPI: groupObject, + groupInternal: internal, + }; + }; + + var groupsFactory = (environment, logger) => { + const _registry = CallbackRegistryFactory(); + const _groups = {}; + let heardForWindowsCounter = -1; + const windows = windowStore.list; + Object.keys(windows).forEach((k) => { + const win = windows[k]; + const groupId = win.API.groupId; + const winId = win.API.id; + if (!isNullOrWhiteSpace(groupId)) { + addWindow(groupId, winId); + } + }); + windowStore.onRemoved((w) => { + const group = findGroupWrapperByWindow(w.API); + removeWindow(group, w); + }); + environment.onCompositionChanged((windowInfo) => { + handleCompositionChanged(windowInfo); + }); + environment.onGroupHeaderVisibilityChanged((windowInfo) => { + const windowId = windowInfo.windowId; + const group = findGroupByWindow(windowId); + if (typeof group !== "undefined") { + const groupEvents = _groups[group.id]; + if (heardForWindowsCounter === -1) { + heardForWindowsCounter = group.windows.length; + } + heardForWindowsCounter--; + if (heardForWindowsCounter === 0) { + heardForWindowsCounter = -1; + groupEvents.groupInternal.handleGroupHeaderVisibilityChanged(windowInfo); + } + } + }); + environment.onGroupVisibilityChanged((data) => { + const groupEvents = _groups[data.groupId]; + if (groupEvents) { + groupEvents.groupInternal.handleGroupVisibilityChanged(data.visible); + } + }); + environment.onGroupStateChanged((data) => { + const groupWrapper = _groups[data.groupId]; + if (data.state === "hibernated") { + if (groupWrapper === null || groupWrapper === void 0 ? void 0 : groupWrapper.groupAPI) { + groupWrapper.groupInternal.handleGroupHibernateChanged(true); + } + _registry.execute("group-hibernated", data.groupId); + } + else if (data.state === "resumed") { + if (groupWrapper === null || groupWrapper === void 0 ? void 0 : groupWrapper.groupAPI) { + groupWrapper.groupInternal.handleGroupHibernateChanged(false); + } + _registry.execute("group-resumed", groupWrapper.groupAPI); + } + }); + function my() { + var _a; + return findGroupByWindow((_a = environment.myGroup()) !== null && _a !== void 0 ? _a : environment.my()); + } + async function create(options) { + if (isUndefinedOrNull(options)) { + throw new Error(`options must be defined`); + } + if (isUndefinedOrNull(options.groups) || !Array.isArray(options.groups) || options.groups.length === 0) { + throw new Error(`options.groups must be defined`); + } + const { groupIds } = await executor.executeGroup("createGroups", { + options + }); + const groups = groupIds.map((groupId) => { + return waitForGroup(groupId); + }); + return Promise.all(groups); + } + async function close(idOrGroup, options) { + if (isUndefinedOrNull(idOrGroup)) { + throw new Error(`group must be defined`); + } + let groupId = ""; + if (typeof idOrGroup === "string") { + groupId = idOrGroup; + } + else { + groupId = idOrGroup.id; + } + if (isUndefinedOrNull(options)) { + throw new Error(`options must be defined`); + } + await executor.executeGroup("closeGroup", { + groupId, + options + }); + } + function list(success) { + const result = Object.keys(_groups).map((groupId) => { + if (_groups[groupId]) { + return _groups[groupId].groupAPI; + } + }); + if (typeof success === "function") { + success(result); + } + return result; + } + function findGroupByWindow(winId, success, error) { + let windowId; + if (typeof winId === "string") { + windowId = winId; + } + else if (!isUndefinedOrNull(winId)) { + windowId = winId.id; + } + const result = Object.values(_groups).find((groupObj) => { + const group = groupObj.groupAPI; + const wins = group.windows.filter((w) => w.id === windowId); + return wins.length; + }); + if (result) { + if (typeof success === "function") { + success(result.groupAPI); + } + return result.groupAPI; + } + else if (typeof error === "function") { + error(`Cannot find the group of the window.`); + } + } + function waitForGroup(groupId) { + if (!groupId) { + return Promise.reject(new Error(`groupId must be defined`)); + } + return new Promise((res, rej) => { + const groupWrapper = _groups[groupId]; + if (groupWrapper) { + res(groupWrapper.groupAPI); + } + else { + const un = onGroupAdded((group) => { + if (group.id === groupId) { + un(); + res(group); + } + }); + } + }); + } + function getMyGroup() { + var _a; + return waitForGroup((_a = environment.myGroup()) !== null && _a !== void 0 ? _a : environment.my()); + } + async function resume(groupId, activate) { + validateGroupIdArg(groupId); + if (!isUndefinedOrNull(activate) && !isBoolean(activate)) { + throw new Error("Activate flag must be a boolean!"); + } + activate = !isUndefinedOrNull(activate) ? activate : true; + await executor.executeGroup("resumeGroup", { + groupId, + options: { activate } + }); + } + async function hibernate(groupId) { + validateGroupIdArg(groupId); + await executor.executeGroup("hibernateGroup", { + groupId + }); + return groupId; + } + function onGroupAdded(callback) { + return _registry.add("group-added", callback); + } + function onGroupRemoved(callback) { + return _registry.add("group-removed", callback); + } + function onWindowMoved(callback) { + return _registry.add("window-moved", callback); + } + function onHibernated(callback) { + if (!callback) { + throw new Error("Callback argument is required"); + } + if (callback && typeof callback !== "function") { + throw new Error("Callback argument must be a function"); + } + return _registry.add("group-hibernated", callback); + } + function onResumed(callback) { + if (!callback) { + throw new Error("Callback argument is required"); + } + if (callback && typeof callback !== "function") { + throw new Error("Callback argument must be a function"); + } + return _registry.add("group-resumed", callback); + } + function createOrGet(groupId) { + if (!_groups.hasOwnProperty(groupId)) { + const createdGroupWrapper = groupFactory(groupId, environment.executor); + _groups[groupId] = createdGroupWrapper; + const group = createdGroupWrapper.groupAPI; + _registry.execute("group-added", group); + return createdGroupWrapper; + } + else { + return _groups[groupId]; + } + } + function deleteIfEmpty(groupWrapper) { + const group = groupWrapper.groupAPI; + if (group.windows.length === 0) { + delete _groups[group.id]; + executor.clearCallbacks(group.id); + _registry.execute("group-removed", group); + } + } + function addWindow(groupId, winId) { + const group = createOrGet(groupId); + group.groupInternal.addWindow(winId); + return group; + } + function removeWindow(group, win) { + if (!group) { + return; + } + group.groupInternal.removeWindow(win); + deleteIfEmpty(group); + } + function handleCompositionChanged(state) { + const groupId = state.groupId; + const windowId = state.windowId; + const win = windowStore.get(windowId); + if (!win) { + return; + } + const currentGroup = findGroupWrapperByWindow(win.API); + if (isUndefinedOrNull(groupId)) { + removeWindow(currentGroup, win); + return; + } + if (isUndefinedOrNull(currentGroup) && !isUndefinedOrNull(groupId)) { + addWindow(groupId, win.API.id); + return; + } + if (currentGroup.groupAPI.id !== groupId) { + moveWindow(win, currentGroup.groupAPI.id, groupId); + } + } + function moveWindow(win, from, to) { + const winId = win.API.id; + const fromGroup = _groups[from]; + removeWindow(fromGroup, win); + const toGroup = addWindow(to, winId); + win.Events.handleGroupChanged(toGroup.groupAPI, fromGroup.groupAPI); + _registry.execute("window-moved", winId, from, to); + } + function findGroupWrapperByWindow(winId) { + let windowId; + if (typeof winId === "string") { + windowId = winId; + } + else if (!isUndefinedOrNull(winId)) { + windowId = winId.id; + } + return Object.values(_groups).find((groupObj) => { + const groupInternal = groupObj.groupInternal; + const wins = groupInternal.windows.filter((id) => id === windowId); + return wins.length; + }); + } + function validateGroupIdArg(groupId) { + if (!groupId || typeof groupId !== "string") { + throw new Error("Please provide a valid Group ID as a non-empty string!"); + } + } + const groups = { + get my() { + return my(); + }, + create, + close, + list, + findGroupByWindow, + waitForGroup, + getMyGroup, + onGroupAdded, + onGroupRemoved, + hibernate, + resume, + onHibernated, + onResumed + }; + const events = { onWindowMoved }; + return { + groupsAPI: groups, + groupsEvents: events, + }; + }; + + var WindowsFactory = (agm, logger, appManagerGetter, displayAPIGetter, channelsGetter, gdMajorVersion) => { + const _registry = CallbackRegistryFactory(); + const _logger = logger; + let groups; + let environment; + windowStore.init(_logger); + const isReady = new Promise((resolve, reject) => { + envDetector(agm, _logger, appManagerGetter, displayAPIGetter, channelsGetter, gdMajorVersion) + .then((env) => { + environment = env; + groups = groupsFactory(env); + jumpListManager.init(env.executor, agm, _logger); + resolve(); + }) + .catch((e) => { + const err = `Timed out waiting for connection to Glue42 Enterprise: Error: ${e.message}`; + _logger.error(err, e); + reject(new Error(err)); + }); + }); + function ready() { + return isReady; + } + function my() { + const myWindow = windowStore.getIfReady(environment.my()); + return myWindow ? myWindow.API : undefined; + } + function open(name, url, options, success, error) { + return Utils.callbackifyPromise(() => { + if (isNullOrWhiteSpace(name)) { + throw new Error("The window name is missing."); + } + if (isNullOrWhiteSpace(url)) { + throw new Error("The window URL is missing."); + } + if (!isUndefinedOrNull(options)) { + const optionsAsAny = options; + for (const prop of ["minHeight", "maxHeight", "minWidth", "maxWidth", "width", "height", "top", "left"]) { + if (prop in optionsAsAny) { + const value = optionsAsAny[prop]; + if (isUndefinedOrNull(value)) { + delete optionsAsAny[prop]; + continue; + } + if (!isNumber(value)) { + const errMessage = `${prop} must be a number`; + throw new Error(errMessage); + } + if (optionsAsAny[prop] === "width" || optionsAsAny[prop] === "height") { + if (value <= 0) { + const errMessage = `${prop} must be a positive number`; + throw new Error(errMessage); + } + } + } + } + } + return environment.open(name, url, options); + }, success, error); + } + function find(name, success, error) { + const windows = windowStore.list; + const windowsForListing = Object.keys(windows).reduce((memo, winId) => { + var _a; + const window = windows[winId]; + if (((_a = window === null || window === void 0 ? void 0 : window.API) === null || _a === void 0 ? void 0 : _a.name) === name) { + memo.push(window.API); + } + return memo; + }, []); + const win = windowsForListing[0]; + if (win) { + if (typeof success === "function") { + success(windowsForListing[0]); + } + return windowsForListing[0]; + } + else { + if (typeof error === "function") { + error("There is no window with name:" + name); + } + } + } + function findById(id, success, error) { + const windows = windowStore.list; + const windowsForListing = Object.keys(windows).reduce((memo, winId) => { + const window = windows[winId]; + if (typeof window !== "undefined" && window.API.id === id) { + memo.push(window.API); + } + return memo; + }, []); + const win = windowsForListing[0]; + if (win) { + if (typeof success === "function") { + success(windowsForListing[0]); + } + return windowsForListing[0]; + } + else { + if (typeof error === "function") { + error("There is no window with such id:" + id); + } + } + } + function list(success) { + const windows = windowStore.list; + const windowsForListing = Object.keys(windows) + .map((k) => { + return windows[k].API; + }); + if (typeof success !== "function") { + return windowsForListing; + } + success(windowsForListing); + } + function configure(options) { + const win = my(); + const winId = win ? win.id : ""; + return executor.configure(winId, options); + } + function autoArrange(displayId) { + return executor.autoArrange(displayId); + } + function windowAdded(callback) { + return _registry.add("window-added", callback); + } + function windowRemoved(callback) { + return _registry.add("window-removed", callback); + } + function tabAttached(callback) { + let unsubFunc; + let unsubscribed = false; + isReady.then(() => { + if (unsubscribed) { + return; + } + unsubFunc = environment.tabAttached(callback); + }); + return () => { + unsubscribed = true; + if (unsubFunc) { + unsubFunc(); + } + }; + } + function tabDetached(callback) { + let unsubFunc; + let unsubscribed = false; + isReady.then(() => { + if (unsubscribed) { + return; + } + unsubFunc = environment.tabDetached(callback); + }); + return () => { + unsubscribed = true; + if (unsubFunc) { + unsubFunc(); + } + }; + } + function onWindowFrameColorChanged(callback) { + let unsubFunc; + let unsubscribed = false; + isReady.then(() => { + if (unsubscribed) { + return; + } + unsubFunc = environment.onWindowFrameColorChanged(callback); + }); + return () => { + unsubscribed = true; + if (unsubFunc) { + unsubFunc(); + } + }; + } + function onWindowGotFocus(callback) { + let unsubFunc; + let unsubscribed = false; + isReady.then(() => { + if (unsubscribed) { + return; + } + unsubFunc = environment.onWindowGotFocus(callback); + }); + return () => { + unsubscribed = true; + if (unsubFunc) { + unsubFunc(); + } + }; + } + function onWindowLostFocus(callback) { + let unsubFunc; + let unsubscribed = false; + isReady.then(() => { + if (unsubscribed) { + return; + } + unsubFunc = environment.onWindowLostFocus(callback); + }); + return () => { + unsubscribed = true; + if (unsubFunc) { + unsubFunc(); + } + }; + } + function onArrangementChanged(callback) { + return environment.onWindowsAutoArrangeChanged(callback); + } + function onEvent(callback) { + let unsubFunc; + let unsubscribed = false; + isReady.then(() => { + if (unsubscribed) { + return; + } + unsubFunc = environment.onEvent(callback); + }); + return () => { + unsubscribed = true; + if (unsubFunc) { + unsubFunc(); + } + }; + } + function createFlydown(targetId, config) { + return environment.createFlydown(targetId, config); + } + function showPopup(targetId, config) { + return environment.showPopup(targetId, config); + } + function handleWindowAdded(w) { + _registry.execute("window-added", w.API); + } + function handleWindowRemoved(w) { + _registry.execute("window-removed", w.API); + } + windowStore.onReadyWindow(handleWindowAdded); + windowStore.onRemoved(handleWindowRemoved); + return { + my, + open, + find, + findById, + list, + ready, + onWindowAdded: windowAdded, + windowAdded, + onWindowRemoved: windowRemoved, + windowRemoved, + onTabAttached: tabAttached, + onTabDetached: tabDetached, + onWindowFrameColorChanged, + onArrangementChanged, + get groups() { + return groups.groupsAPI; + }, + onWindowGotFocus, + onWindowLostFocus, + onEvent, + createFlydown, + showPopup, + configure, + autoArrange + }; + }; + + class LayoutStore { + constructor() { + this.layouts = []; + } + removeWhere(condition) { + this.layouts = this.layouts.filter(condition); + } + removeAll() { + this.layouts = []; + } + add(item) { + this.layouts.push(item); + } + get all() { + return this.layouts; + } + where(condition) { + return this.layouts.filter(condition); + } + first(condition) { + return this.where(condition)[0]; + } + } + var store = new LayoutStore(); + + const SaveContextMethodName = "T42.HC.GetSaveContext"; + class ContextProvider { + constructor(config, activitiesGetter, callbacks, logger) { + this.config = config; + this.activitiesGetter = activitiesGetter; + this.callbacks = callbacks; + this.logger = logger; + this.interop = config.agm; + this.registerRequestMethods(); + } + onSaveRequested(callback) { + return this.callbacks.add("saveRequested", callback); + } + isActivityOwner() { + if (typeof htmlContainer !== "undefined") { + const context = htmlContainer.getContext(); + return context && context._t42 && context._t42.activityIsOwner; + } + const activities = this.activitiesGetter(); + if (!activities) { + return false; + } + if (!activities.inActivity) { + return false; + } + const myWindow = activities.my.window; + const myActivity = activities.my.activity; + if (!myActivity && !myWindow) { + return false; + } + return myActivity.owner.id === myWindow.id; + } + registerRequestMethods() { + this.interop.register(SaveContextMethodName, (args) => { + const usersCbs = this.callbacks.execute("saveRequested", args); + if ((usersCbs === null || usersCbs === void 0 ? void 0 : usersCbs.length) > 1) { + this.logger.warn(`Multiple subscriptions for "glue.layouts.onSaveRequested" - only the first one will be used`); + } + const requestResult = usersCbs[0]; + const autoSaveWindowContext = this.config.autoSaveWindowContext; + if (typeof autoSaveWindowContext === "boolean" && autoSaveWindowContext) { + return { autoSaveWindowContext }; + } + else if (Array.isArray(autoSaveWindowContext) && autoSaveWindowContext.length > 0) { + return { autoSaveWindowContext }; + } + const result = { windowContext: requestResult === null || requestResult === void 0 ? void 0 : requestResult.windowContext, activityContext: undefined }; + if (this.isActivityOwner()) { + result.activityContext = requestResult === null || requestResult === void 0 ? void 0 : requestResult.activityContext; + } + return result; + }); + } + } + + function transformACSLayout(something) { + if (!something) { + return something; + } + if (Array.isArray(something)) { + return something.map((item) => { + return transformACSLayout(item); + }); + } + if (typeof something === "string" || typeof something === "number" || typeof something === "boolean") { + return something; + } + const initial = {}; + return Object.keys(something).reduce((accumulator, current) => { + var _a; + const value = something[current]; + const convertedValue = transformACSLayout(value); + let key = current; + if (((_a = current[0]) === null || _a === void 0 ? void 0 : _a.toLowerCase()) !== current[0]) { + key = current[0].toLowerCase() + current.substr(1); + } + accumulator[key] = convertedValue; + return accumulator; + }, initial); + } + + class LayoutImpl { + constructor(data) { + this.name = data.name; + this.type = data.type; + this.components = data.components; + this.context = data.context; + this.metadata = data.metadata; + this.version = data.version; + this.displays = data.displays; + } + } + + var main = {}; + + var application = {}; + + /** + * This file was automatically generated by json-schema-to-typescript. + * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file, + * and run json-schema-to-typescript to regenerate this file. + */ + Object.defineProperty(application, "__esModule", { value: true }); + + var system = {}; + + /** + * This file was automatically generated by json-schema-to-typescript. + * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file, + * and run json-schema-to-typescript to regenerate this file. + */ + Object.defineProperty(system, "__esModule", { value: true }); + + var layout = {}; + + Object.defineProperty(layout, "__esModule", { value: true }); + layout.SwimlaneItemType = layout.LayoutType = void 0; + var LayoutType; + (function (LayoutType) { + LayoutType["Global"] = "Global"; + LayoutType["Activity"] = "Activity"; + LayoutType["ApplicationDefault"] = "ApplicationDefault"; + LayoutType["Swimlane"] = "Swimlane"; + LayoutType["Workspaces"] = "Workspace"; + })(LayoutType || (layout.LayoutType = LayoutType = {})); + var SwimlaneItemType; + (function (SwimlaneItemType) { + SwimlaneItemType["Tab"] = "tab"; + SwimlaneItemType["Window"] = "window"; + SwimlaneItemType["Canvas"] = "canvas"; + })(SwimlaneItemType || (layout.SwimlaneItemType = SwimlaneItemType = {})); + + var swTheme = {}; + + /** + * This file was automatically generated by json-schema-to-typescript. + * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file, + * and run json-schema-to-typescript to regenerate this file. + */ + Object.defineProperty(swTheme, "__esModule", { value: true }); + + var swConfiguration = {}; + + /** + * This file was automatically generated by json-schema-to-typescript. + * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file, + * and run json-schema-to-typescript to regenerate this file. + */ + Object.defineProperty(swConfiguration, "__esModule", { value: true }); + + (function (exports) { + var __createBinding = (commonjsGlobal && commonjsGlobal.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; + })); + var __exportStar = (commonjsGlobal && commonjsGlobal.__exportStar) || function(m, exports) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); + }; + Object.defineProperty(exports, "__esModule", { value: true }); + // export { SchemaValidator } from "./validator"; + // export { FileProvider } from "./fileProvider"; + // export { SchemaProvider } from "./provider"; + __exportStar(application, exports); + __exportStar(system, exports); + __exportStar(layout, exports); + __exportStar(swTheme, exports); + __exportStar(swConfiguration, exports); + + } (main)); + + const LayoutsCommandMethod = "T42.ACS.Command"; + class LayoutsAPIImpl { + constructor(config, stream, callbacks, logger) { + this.config = config; + this.stream = stream; + this.callbacks = callbacks; + this.isRegisterMethodForLayoutModified = false; + this.appManager = config.appManager; + this.provider = new ContextProvider(config, config.activityGetter, callbacks, logger); + stream.subscribe(); + } + async setDefaultGlobal(name) { + const methodName = "SelectDefaultLayout"; + await this.invokeMethodCore(methodName, { name }); + return; + } + async clearDefaultGlobal() { + const methodName = "DeselectDefaultLayout"; + await this.invokeMethodCore(methodName); + return; + } + async getDefaultGlobal() { + const methodName = "GetDefaultLayout"; + const result = await this.invokeMethodCore(methodName); + const layout = result.returned; + if (layout === null || layout === undefined || (typeof layout === 'object' && Object.keys(layout).length === 0)) { + return undefined; + } + return objectClone(this.isSlimMode() ? layout : this.list().find((l) => l.name === layout.name && l.type === layout.type)); + } + ready() { + if (this.config.mode === "fullWaitSnapshot") { + return this.stream.gotSnapshot; + } + return this.stream.ready; + } + save(layout) { + return new Promise((resolve, reject) => { + var _a, _b; + this.verifyNotSlimMode(); + if (isUndefinedOrNull(layout)) { + return reject(new Error("layout is required")); + } + if (isNullOrWhiteSpace(layout.name)) { + return reject(new Error("layout.name argument is required")); + } + if (isNullOrWhiteSpace(layout.type)) { + layout.type = "Global"; + } + if (!isNullOrWhiteSpace(layout.activityId)) { + layout.type = "Activity"; + } + const layoutObject = { + name: layout.name, + type: layout.type, + context: (_a = layout.context) !== null && _a !== void 0 ? _a : {}, + metadata: (_b = layout.metadata) !== null && _b !== void 0 ? _b : {}, + options: {}, + }; + if (layout.type === "Activity") { + let actId = layout.activityId; + if (!actId) { + if (!this.appManager.myInstance.inActivity) { + return reject(new Error("Current application is not in activity. Cannot save activity layout for it.")); + } + actId = this.appManager.myInstance.activityId; + } + layoutObject.activityId = actId; + } + else if (layout.type === "Global") { + if (Array.isArray(layout.ignoreInstances)) { + layoutObject.options.ignoreInstances = layout.ignoreInstances; + } + if (Array.isArray(layout.instances)) { + layoutObject.options.instances = layout.instances; + } + if (typeof layout.setAsCurrent === "boolean") { + layoutObject.options.setAsCurrent = layout.setAsCurrent; + } + } + else { + return reject(new Error(`layout type ${layout.type} is not supported`)); + } + this.invokeMethodAndTrack("SaveLayout", layoutObject, resolve, reject); + }); + } + restore(options) { + return new Promise((resolve, reject) => { + var _a, _b, _c; + this.verifyNotSlimMode(); + if (isUndefinedOrNull(options)) { + return reject(new Error("options argument is required")); + } + if (isNullOrWhiteSpace(options.name)) { + return reject(new Error("options.name argument is required")); + } + if (isNullOrWhiteSpace(options.type)) { + options.type = "Global"; + } + if (!isNullOrWhiteSpace(options.activityIdToJoin)) { + options.type = "Activity"; + } + if (options.type === "Activity") { + if (isUndefinedOrNull(options.setActivityContext)) { + options.setActivityContext = true; + } + if (typeof options.setActivityContext !== "boolean") { + return reject(new Error("`setActivityContext` must hold a boolean value.")); + } + options.activityIdToJoin = (_a = options.activityIdToJoin) !== null && _a !== void 0 ? _a : this.appManager.myInstance.activityId; + } + if (!isUndefinedOrNull(options.closeRunningInstance)) { + options.closeRunningInstances = options.closeRunningInstance; + } + if (isUndefinedOrNull(options.closeRunningInstances)) { + options.closeRunningInstances = true; + } + if (!isBoolean(options.closeRunningInstances)) { + return reject(new Error("`closeRunningInstances` must hold a boolean value.")); + } + if (isUndefinedOrNull(options.closeMe)) { + options.closeMe = options.closeRunningInstances; + } + if (!isBoolean(options.closeMe)) { + return reject(new Error("`closeMe` must hold a boolean value.")); + } + if (!isUndefinedOrNull(options.context) && !isObject(options.context)) { + return reject(new Error("`context` must hold an object value.")); + } + if (!isUndefinedOrNull(options.timeout) && typeof options.timeout !== "number") { + return reject(new Error("`timeout` must hold an number value.")); + } + options.context = (_b = options.context) !== null && _b !== void 0 ? _b : {}; + const restoreOptions = { + activityToJoin: options.activityIdToJoin, + setActivityContext: options.setActivityContext, + ignoreActivityWindowTypes: options.ignoreActivityWindowTypes, + reuseExistingWindows: options.reuseWindows, + closeRunningInstances: options.closeRunningInstances, + excludeFromClosing: options.closeMe ? [] : [(_c = this.appManager.myInstance) === null || _c === void 0 ? void 0 : _c.id] + }; + const arg = { + type: options.type, + name: options.name, + context: options.context, + options: restoreOptions + }; + if (options.timeout) { + arg.timeout = options.timeout; + } + this.invokeMethodAndTrack("RestoreLayout", arg, resolve, reject, true); + }); + } + reset(options) { + return new Promise((resolve, reject) => { + this.verifyNotSlimMode(); + if (typeof options !== "object") { + return reject(new Error("options argument is required")); + } + if (isNullOrWhiteSpace(options.layoutId)) { + return reject(new Error("options.layoutId argument is required")); + } + const msg = { + ...options + }; + this.invokeMethodAndTrack("ResetLayout", msg, resolve, reject, true); + }); + } + remove(type, name) { + return new Promise((resolve, reject) => { + this.verifyNotSlimMode(); + if (!name) { + return reject(new Error("name argument is required")); + } + if (!type) { + return reject(new Error("type argument is required")); + } + const msg = { + type, + name, + }; + this.invokeMethodAndTrack("RemoveLayout", msg, resolve, reject); + }); + } + list() { + this.verifyNotSlimMode(); + return objectClone(store.all); + } + import(layouts, mode) { + return new Promise((resolve, reject) => { + this.verifyNotSlimMode(); + if (!isUndefinedOrNull(mode)) { + if (mode !== "merge" && mode !== "replace") { + return reject(new Error(`${mode} is not supported - only "merge" and "replace"`)); + } + } + if (!Array.isArray(layouts)) { + return reject(new Error("layouts arguments is not an array")); + } + const msg = { + mode: mode || "replace", + layouts + }; + this.invokeMethodAndTrack("ImportLayouts", msg, resolve, reject, true); + }); + } + export(layoutType) { + return new Promise((resolve, reject) => { + var _a; + if (!isUndefinedOrNull(layoutType) && !((_a = Object.values(main.LayoutType)) === null || _a === void 0 ? void 0 : _a.includes(layoutType))) { + return reject(new Error(`${layoutType} is not a supported Layout Type`)); + } + const handleResult = (result) => { + let layouts = this.getObjectValues(result.Layouts).map((t) => new LayoutImpl(transformACSLayout(t))); + if (layoutType) { + layouts = layouts.filter((l) => l.type === layoutType); + } + resolve(layouts); + }; + this.invokeMethodAndTrack("ExportLayouts", {}, handleResult, reject, true); + }); + } + rename(layout, newName) { + return new Promise((resolve, reject) => { + this.verifyNotSlimMode(); + if (!layout) { + return reject(new Error("layout argument is required")); + } + if (!layout.name) { + return reject(new Error("name argument is required")); + } + if (!layout.type) { + return reject(new Error("type argument is required")); + } + const msg = { type: layout.type, oldName: layout.name, newName }; + this.invokeMethodAndTrack("RenameLayout", msg, resolve, reject); + }); + } + updateMetadata(layout) { + return new Promise((resolve, reject) => { + if (!layout) { + return reject(new Error("layout argument is required")); + } + if (!layout.name) { + return reject(new Error("name argument is required")); + } + if (!layout.type) { + return reject(new Error("type argument is required")); + } + if (!layout.metadata) { + return reject(new Error("metadata argument is required")); + } + const layoutObject = { + name: layout.name, + type: layout.type, + metadata: layout.metadata + }; + this.invokeMethodAndTrack("UpdateMetadata", layoutObject, resolve, reject, true); + }); + } + hibernate(name, options) { + return new Promise((resolve, reject) => { + if (!name) { + return reject(new Error("name cannot be empty")); + } + options = options || {}; + const request = { + name, + type: "Global", + context: options.context || {}, + metadata: options.metadata || {}, + }; + this.invokeMethodAndTrack("HibernateLayout", request, resolve, reject, true); + }); + } + resume(name, context, options) { + return new Promise((resolve, reject) => { + if (!name) { + return reject(new Error("name cannot be empty")); + } + const request = { + name, + type: "Global", + context, + ...options + }; + this.invokeMethodAndTrack("ResumeLayout", request, resolve, reject, true); + }); + } + async getCurrentLayout() { + const methodName = "GetCurrentLayout"; + const result = await this.invokeMethodCore(methodName); + let layout = result.returned.layout; + if (!layout) { + return undefined; + } + if (!this.isSlimMode()) { + layout = this.list().find((l) => l.name === layout.name && l.type === layout.type); + } + return objectClone(layout); + } + getRestoredLayoutsInfo() { + return new Promise((resolve, reject) => { + const methodName = "GetRestoredLayoutsInfo"; + this.invokeMethodCore(methodName) + .then((result) => { + const restoredLayouts = result.returned; + resolve(restoredLayouts); + }) + .catch(reject); + }); + } + onAdded(callback) { + const result = this.callbacks.add("added", callback); + if (store.all.length > 0) { + store.all.forEach((layout) => { + try { + callback(layout); + } + catch (err) { } + }); + } + return result; + } + onRemoved(callback) { + return this.callbacks.add("removed", callback); + } + onChanged(callback) { + return this.callbacks.add("changed", callback); + } + onRestored(callback) { + return this.callbacks.add("restored", callback); + } + onRenamed(callback) { + return this.callbacks.add("renamed", callback); + } + onEvent(callback) { + return this.stream.onEvent(callback); + } + onSaveRequested(callback) { + return this.provider.onSaveRequested(callback); + } + onLayoutModified(callback) { + if (this.isRegisterMethodForLayoutModified === false) { + this.isRegisterMethodForLayoutModified = true; + this.registerMethodForLayoutModified(); + } + return this.callbacks.add("layout-modified", callback); + } + updateAppContextInCurrent(context) { + return new Promise((resolve, reject) => { + if (context && typeof context !== "object") { + return reject(new Error("Context must be an object")); + } + context = context !== null && context !== void 0 ? context : {}; + const request = { + context + }; + this.invokeMethodAndTrack("UpdateLayoutComponentContext", request, resolve, reject, true); + }); + } + updateDefaultContext(context) { + return new Promise((resolve, reject) => { + if (context && typeof context !== "object") { + return reject(new Error("Context must be an object")); + } + context = context !== null && context !== void 0 ? context : {}; + const request = { + context + }; + this.invokeMethodAndTrack("UpdateDefaultContext", request, resolve, reject, true); + }); + } + async get(name, type) { + const matching = this.list().find((l) => l.name === name && l.type === type); + if (!matching) { + throw new Error(`cannot find layout with name=${name} and type=${type}`); + } + return objectClone(matching); + } + async getAll(type) { + var _a; + if (!isUndefinedOrNull(type) && !((_a = Object.values(main.LayoutType)) === null || _a === void 0 ? void 0 : _a.includes(type))) { + throw new Error((`${type} is not a supported Layout Type`)); + } + const matching = this.list().filter((l) => type === l.type); + return objectClone(matching); + } + async forceRefresh() { + const methodName = "RefreshLayouts"; + await this.invokeMethodCore(methodName); + } + isSlimMode() { + return this.config.mode === "slim"; + } + verifyNotSlimMode() { + if (this.isSlimMode()) { + throw Error("Operation not allowed in slim mode. Run in full mode."); + } + } + async registerMethodForLayoutModified() { + await this.config.agm.register("T42.ACS.LayoutModified", (args, caller) => { + this.callbacks.execute("layout-modified", args); + }); + } + invokeMethodAndTrack(methodName, args, resolve, reject, skipStreamEvent) { + let streamEventReceived = skipStreamEvent; + let agmResult; + const token = Utils.generateId(); + args.token = token; + const handleResult = () => { + if (streamEventReceived && agmResult) { + resolve(agmResult); + } + }; + const methodResponseTimeoutMs = 120 * 1000; + if (!skipStreamEvent) { + this.stream.waitFor(token, methodResponseTimeoutMs) + .then(() => { + streamEventReceived = true; + handleResult(); + }) + .catch((err) => { + reject(err); + }); + } + const responseHandler = (result) => { + if (!result.returned) { + return reject(new Error("No result from method " + methodName)); + } + if (result.returned.status && (result.returned.status !== "Success" && result.returned.status !== "PartialSuccess")) { + if (typeof (result.returned) === "string") { + return reject(new Error(result.returned)); + } + else if (typeof (result.returned) === "object") { + if (result.returned.status && result.returned.failed) { + return reject(new Error(`${result.returned.status}: ${JSON.stringify(result.returned.failed)}`)); + } + else { + return reject(new Error(result.returned)); + } + } + } + agmResult = result.returned; + handleResult(); + }; + this.invokeMethodCore(methodName, args, "best", { methodResponseTimeoutMs }) + .then(responseHandler) + .catch((err) => reject(err)); + } + async invokeMethodCore(methodName, args, target, options) { + options = options !== null && options !== void 0 ? options : {}; + if (typeof options.methodResponseTimeoutMs === "undefined") { + options.methodResponseTimeoutMs = INTEROP_METHOD_WAIT_TIMEOUT_MS; + } + if (typeof options.waitTimeoutMs === "undefined") { + options.waitTimeoutMs = INTEROP_METHOD_WAIT_TIMEOUT_MS; + } + if (this.isCommandMethodPresent()) { + return await this.config.agm.invoke(LayoutsCommandMethod, { command: methodName, data: args }, target, options); + } + else { + return await this.config.agm.invoke(`T42.ACS.${methodName}`, args, target, options); + } + } + getObjectValues(obj) { + if (!obj) { + return []; + } + return Object.keys(obj).map((k) => obj[k]); + } + isCommandMethodPresent() { + return this.config.agm.methods().some((method) => method.name === LayoutsCommandMethod); + } + } + + class ACSStream { + constructor(agm, callbacks) { + this.agm = agm; + this.callbacks = callbacks; + this.StreamName = "T42.ACS.OnLayoutEvent"; + this.ready = new Promise((resolve, reject) => { + this.resolveReady = resolve; + this.rejectReady = reject; + }); + this.gotSnapshot = new Promise((resolve, reject) => { + this.resolveGotSnapshot = resolve; + this.rejectGotSnapshot = reject; + }); + } + subscribe(noRetry) { + const transform = (obj) => { + return this.getObjectValues(obj).map((t) => transformACSLayout(t)); + }; + if (!this.checkForLayoutEventMethod()) { + if (noRetry) { + this.resolveReady(); + } + setTimeout(() => { + this.subscribe(true); + }, 500); + } + else { + this.agm.subscribe(this.StreamName, { waitTimeoutMs: 10000 }) + .then((subs) => { + subs.onData((args) => { + const data = args.data; + if (data.IsSnapshot) { + this.resolveGotSnapshot(); + } + this.addLayouts(transform(data.OnLayoutAdded), data.IsSnapshot); + this.removeLayouts(transform(data.OnLayoutRemoved)); + this.changeLayouts(transform(data.OnLayoutChanged)); + this.renameLayouts(transform(data.OnLayoutRenamed)); + this.restoredLayout(transform(data.OnLayoutRestored)); + this.callbacks.execute("streamEvent", data); + }); + subs.onFailed((err) => { + const msg = `Can not subscribe to "${this.StreamName}" stream - ${JSON.stringify(err)}`; + this.rejectReady(msg); + this.rejectGotSnapshot(msg); + }); + this.resolveReady(); + }) + .catch((err) => { + const msg = `Error subscribing to "${this.StreamName}" stream - ${JSON.stringify(err)}`; + this.rejectReady(msg); + this.rejectGotSnapshot(msg); + }); + } + } + onEvent(callback) { + return this.callbacks.add("streamEvent", callback); + } + waitFor(token, timeout) { + if (!timeout) { + timeout = 30000; + } + return new Promise((resolve, reject) => { + let done = false; + const unsubscribe = this.onEvent((streamEvent) => { + if (streamEvent.Token === token) { + done = true; + unsubscribe(); + resolve(); + } + }); + setTimeout(() => { + if (!done) { + reject("timed out"); + } + }, timeout); + }); + } + checkForLayoutEventMethod() { + try { + return this.agm + .methods() + .map((m) => m.name) + .indexOf(this.StreamName) !== -1; + } + catch (e) { + return false; + } + } + addLayouts(layoutsData, isSnapshot) { + if (!layoutsData) { + return; + } + const createAndNotifyLayout = (layoutData) => { + const layout = new LayoutImpl(layoutData); + store.add(layout); + this.callbacks.execute("added", layout); + }; + layoutsData.forEach((layoutData) => { + if (isSnapshot) { + const found = store.first((existingLayout) => this.compareLayouts(existingLayout, layoutData)); + if (!found) { + createAndNotifyLayout(layoutData); + } + } + else { + createAndNotifyLayout(layoutData); + } + }); + } + removeLayouts(removedLayouts) { + if (!removedLayouts) { + return; + } + removedLayouts.forEach((removedLayout) => { + store.removeWhere((existingLayout) => !this.compareLayouts(existingLayout, removedLayout)); + this.callbacks.execute("removed", removedLayout); + }); + } + changeLayouts(changedLayouts) { + if (!changedLayouts) { + return; + } + changedLayouts.forEach((changedLayout) => { + store.removeWhere((existingLayout) => !this.compareLayouts(existingLayout, changedLayout)); + store.add(new LayoutImpl(changedLayout)); + this.callbacks.execute("changed", changedLayout); + }); + } + renameLayouts(renamedLayouts) { + if (!renamedLayouts) { + return; + } + renamedLayouts.forEach((renamedLayout) => { + const existingLayout = store.first((current) => this.compareLayouts(current, { type: renamedLayout.type, name: renamedLayout.oldName })); + if (!existingLayout) { + throw Error(`received rename event for unknown layout with type ${renamedLayout.type} and name ${renamedLayout.oldName}`); + } + existingLayout.name = renamedLayout.newName; + this.callbacks.execute("renamed", existingLayout); + }); + } + compareLayouts(layout1, layout2) { + return layout1.name === layout2.name && layout1.type === layout2.type; + } + getObjectValues(obj) { + if (!obj) { + return []; + } + return Object.keys(obj).map((k) => obj[k]); + } + restoredLayout(restoredLayouts) { + if (!restoredLayouts) { + return; + } + restoredLayouts.forEach((restoredLayout) => { + const existingLayout = store.first((current) => this.compareLayouts(current, { type: restoredLayout.type, name: restoredLayout.name })); + this.callbacks.execute("restored", existingLayout); + }); + } + } + + function LayoutsFactory (config) { + if (!config.agm) { + throw Error("config.agm is required"); + } + if (!config.logger) { + throw Error("config.logger is required"); + } + config.mode = config.mode || "slim"; + const logger = config.logger; + const callbacks = CallbackRegistryFactory(); + let acsStream; + if (config.mode === "full" || "fullWaitSnapshot") { + acsStream = new ACSStream(config.agm, callbacks); + } + return new LayoutsAPIImpl(config, acsStream, callbacks, logger); + } + + const T42DisplayCommand = "T42.Displays.Command"; + const T42DisplayOnEvent = "T42.Displays.OnEvent"; + class DisplayManager { + constructor(_agm, _logger) { + this._agm = _agm; + this._logger = _logger; + this._registry = CallbackRegistryFactory(); + this._registered = false; + this.all = async () => { + const displays = await this.callGD(DisplayCommand.GetAll, {}); + return displays.map(this.decorateDisplay); + }; + this.get = async (id) => { + const display = await this.callGD(DisplayCommand.Get, { id }); + return this.decorateDisplay(display); + }; + this.getPrimary = async () => { + const primary = (await this.all()).find((d) => d.isPrimary); + return primary; + }; + this.capture = async (options) => { + const screenshot = await this.callGD(DisplayCommand.Capture, { ...options }); + return screenshot; + }; + this.captureAll = async (options) => { + const screenshots = await this.callGD(DisplayCommand.CaptureAll, { ...options }); + return screenshots; + }; + this.getMousePosition = async () => { + const point = await this.callGD(DisplayCommand.GetMousePosition); + return point; + }; + this.callGD = async (command, options) => { + const invocationResult = await this._agm.invoke(T42DisplayCommand, { options: { ...options }, command }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return invocationResult.returned.data; + }; + this.decorateDisplay = (original) => { + const decoratedDisplay = { + ...original, + capture: (size) => this.capture({ id: original.id, size }) + }; + const workAreaAsAny = decoratedDisplay.workArea; + workAreaAsAny.x = workAreaAsAny.left; + workAreaAsAny.y = decoratedDisplay.workArea.top; + return decoratedDisplay; + }; + } + getByWindowId(id) { + const current = this.callGD(DisplayCommand.GetByWindowId, { id }); + return current; + } + onDisplayChanged(cb) { + this.register(); + return this._registry.add("on-display-changed", cb); + } + register() { + if (this._registered) { + return; + } + this._registered = true; + this._agm.register(T42DisplayOnEvent, (args, caller) => { + const event = args.event; + const data = args.data; + switch (event) { + case "display-changed": + this._registry.execute("on-display-changed", data.displays.map(this.decorateDisplay)); + break; + default: + this._logger.warn(`unknown event - ${event}`); + break; + } + }); + } + } + var DisplayCommand; + (function (DisplayCommand) { + DisplayCommand["Capture"] = "capture"; + DisplayCommand["CaptureAll"] = "captureAll"; + DisplayCommand["GetAll"] = "getAll"; + DisplayCommand["Get"] = "get"; + DisplayCommand["GetByWindowId"] = "getByWindowId"; + DisplayCommand["GetMousePosition"] = "getMousePosition"; + })(DisplayCommand || (DisplayCommand = {})); + + class SingleChannelID { + constructor(channel) { + this.channel = channel; + } + get isJoinedToAnyChannel() { + return !!this.channel; + } + isOnChannel(channel) { + return this.channel === channel; + } + leaveChannel(channel) { + if (channel === undefined || this.channel === channel) { + this.channel = undefined; + } + } + joinChannel(channel) { + this.channel = channel; + } + all() { + if (this.channel) { + return [this.channel]; + } + return []; + } + toString() { + return this.channel; + } + equals(other) { + if (other instanceof SingleChannelID) { + return this.channel === other.channel; + } + return false; + } + } + class MultiChannelId { + constructor(channels) { + this.ChannelDelimiter = "+++"; + if (!channels) { + this.channels = []; + } + else if (typeof channels === "string") { + this.channels = channels === null || channels === void 0 ? void 0 : channels.split(this.ChannelDelimiter).filter(Boolean); + } + else { + this.channels = (channels !== null && channels !== void 0 ? channels : []).filter(Boolean); + } + } + get isJoinedToAnyChannel() { + return this.channels.length > 0; + } + isOnChannel(channel) { + return this.channels.includes(channel); + } + joinChannel(channel) { + const newChannels = new MultiChannelId(channel); + newChannels.all().forEach((newChannel) => { + if (!this.channels.includes(newChannel)) { + this.channels.push(newChannel); + } + }); + } + leaveChannel(channel) { + const channelsToLeave = new MultiChannelId(channel !== null && channel !== void 0 ? channel : this.channels); + channelsToLeave.all().forEach((c) => { + this.channels = this.channels.filter((ch) => ch !== c); + }); + } + all() { + return this.channels; + } + toString() { + if (this.channels.length === 0) { + return undefined; + } + return this.channels.join(this.ChannelDelimiter); + } + equals(other) { + if (other instanceof MultiChannelId) { + return this.channels.length === other.channels.length && + this.channels.every((c, i) => c === other.channels[i]); + } + return false; + } + } + + let interop; + let myInstanceId; + let logger; + const T42_ANNOUNCE_METHOD_NAME = "T42.Channels.Announce"; + const T42_COMMAND_METHOD_NAME = "T42.Channels.Command"; + async function setupInterop(interopLib, channels, loggerAPI) { + var _a, _b; + logger = loggerAPI; + interop = interopLib; + if (typeof window !== "undefined") { + if (window.glue42gd) { + myInstanceId = window.glue42gd.windowId; + } + } + if (!myInstanceId) { + myInstanceId = interopLib.instance.instance; + } + await interop.register(T42_COMMAND_METHOD_NAME, (args) => { + const command = args.command; + if (!command) { + throw new Error("missing command argument"); + } + logger.trace(`received command "${command}" with ${JSON.stringify(args)}`); + if (command === "join") { + const id = args.channel; + if (!id) { + throw new Error("missing argument id"); + } + return channels.joinNoSelectorSwitch(id); + } + if (command === "leave") { + return channels.leaveNoSelectorSwitch(); + } + if (command === "get") { + const id = channels.current(); + return { id }; + } + if (command === "restrictions-changed") { + const restrictions = args.restrictions; + const targetWindowId = args.swId; + channels.handleRestrictionsChanged(restrictions, targetWindowId); + return; + } + if (command === "isFdc3DataWrappingSupported") { + return { isSupported: true }; + } + if (command === "join-multi") { + const channelsToJoin = args.channelsToJoin; + if (!channelsToJoin) { + throw new Error("missing argument channelsToJoin"); + } + return channels.joinNoSelectorSwitch(new MultiChannelId(channelsToJoin).toString()); + } + if (command === "leave-multi") { + const channelsToLeave = args.channelsToLeave; + return channels.leaveNoSelectorSwitch(new MultiChannelId(channelsToLeave).toString()); + } + throw new Error(`unknown command ${command}`); + }); + const result = await interop.invoke(T42_ANNOUNCE_METHOD_NAME, { swId: myInstanceId, instance: interop.instance.instance }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_RESPONSE_TIMEOUT_MS + }); + if ((_a = result.returned) === null || _a === void 0 ? void 0 : _a.restrictions) { + channels.handleRestrictionsChanged((_b = result.returned) === null || _b === void 0 ? void 0 : _b.restrictions, myInstanceId); + } + return result.returned; + } + async function sendLeaveChannel(channel, winId) { + var _a; + await invoke("leaveChannel", { channel }, (_a = winId !== null && winId !== void 0 ? winId : winId) !== null && _a !== void 0 ? _a : myInstanceId); + } + async function sendSwitchChannelUI(channel, winId) { + await invoke("switchChannel", { newChannel: channel }, winId !== null && winId !== void 0 ? winId : myInstanceId); + } + async function setRestrictions(restrictions) { + var _a; + await invoke("restrict", restrictions, (_a = restrictions.windowId) !== null && _a !== void 0 ? _a : myInstanceId); + } + async function getRestrictionsByWindow(id) { + try { + const result = await invoke("getRestrictions", {}, id !== null && id !== void 0 ? id : myInstanceId); + return result.returned; + } + catch (e) { + } + } + async function setRestrictionsForAllChannels(restrictions) { + var _a; + await invoke("restrictAll", restrictions, (_a = restrictions.windowId) !== null && _a !== void 0 ? _a : myInstanceId); + } + async function getChannelsInfo(filter) { + const result = await invoke("getChannelsInfo", { filter }); + return result.returned; + } + async function addOrRemoveChannel(command, id, color, label) { + await invoke(command, { id, color, label }); + } + async function getChannelInitInfo(config, i) { + if (typeof config.operationMode !== "boolean" && typeof config.operationMode === "string") { + validateMode(config.operationMode); + return { mode: config.operationMode, initialChannel: undefined }; + } + try { + const result = await i.invoke(T42_ANNOUNCE_METHOD_NAME, { command: "getChannelsMode" }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_RESPONSE_TIMEOUT_MS, + }); + const initialChannel = result.returned.initialChannel; + if (result.returned.mode === "single") { + return { + mode: "single", + initialChannel + }; + } + else if (result.returned.mode === "multi") { + return { + mode: "multi", + initialChannel + }; + } + else { + return { + mode: "single", + initialChannel + }; + } + } + catch (e) { + return { mode: "single", initialChannel: undefined }; + } + } + function invoke(command, data, swId) { + const args = { command, data }; + if (swId) { + args.swId = swId; + } + return interop.invoke(T42_ANNOUNCE_METHOD_NAME, args, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_RESPONSE_TIMEOUT_MS, + }); + } + function validateMode(mode) { + if (mode !== "single" && mode !== "multi") { + throw new Error(`Invalid mode: ${mode}`); + } + } + + const CONTEXT_PREFIX = "___channel___"; + const LATEST_FDC3_TYPE = "latest_fdc3_type"; + class BaseSharedContextSubscriber { + constructor(contexts) { + this.contexts = contexts; + } + subscribe(callback) { + this.callback = callback; + } + subscribeFor(name, callback) { + if (!this.isChannel(name)) { + return Promise.reject(new Error(`Channel with name: ${name} doesn't exist!`)); + } + const contextName = this.createContextName(name); + return this.contexts.subscribe(contextName, (data, _, __, ___, extraData) => { + callback(data.data, data, extraData === null || extraData === void 0 ? void 0 : extraData.updaterId); + }); + } + all() { + const contextNames = this.contexts.all(); + const channelContextNames = contextNames.filter((contextName) => contextName.startsWith(CONTEXT_PREFIX)); + const channelNames = channelContextNames.map((channelContextName) => channelContextName.substr(CONTEXT_PREFIX.length)); + return channelNames; + } + async getContextData(name) { + if (!this.isChannel(name)) { + throw new Error(`A channel with name: ${name} doesn't exist!`); + } + const contextName = this.createContextName(name); + const contextData = await this.contexts.get(contextName); + if (contextData[LATEST_FDC3_TYPE]) { + return this.getContextWithFdc3Data(contextData); + } + else { + delete contextData[LATEST_FDC3_TYPE]; + } + return contextData; + } + updateChannel(name, data) { + const contextName = this.createContextName(name); + return this.contexts.update(contextName, data); + } + updateData(name, data) { + const contextName = this.createContextName(name); + const fdc3Type = this.getFDC3Type(data); + if (this.contexts.setPathSupported) { + const pathValues = Object.keys(data).map((key) => { + return { + path: `data.` + key, + value: data[key] + }; + }); + if (fdc3Type) { + pathValues.push({ path: LATEST_FDC3_TYPE, value: fdc3Type }); + } + return this.contexts.setPaths(contextName, pathValues); + } + else { + if (fdc3Type) { + data[LATEST_FDC3_TYPE] = fdc3Type; + } + return this.contexts.update(contextName, { data }); + } + } + setPaths(name, paths) { + const contextName = this.createContextName(name); + if (this.contexts.setPathSupported) { + const pathValues = paths.map((p) => { + return { + path: `data.` + p.path, + value: p.value + }; + }); + pathValues.map((p) => { + const fdc3Type = this.getFDC3Type(p.value); + if (fdc3Type) { + pathValues.push({ path: LATEST_FDC3_TYPE, value: fdc3Type }); + } + }); + return this.contexts.setPaths(contextName, pathValues); + } + else { + throw new Error("setPaths is not supported!"); + } + } + clearContextData(name) { + const contextName = this.createContextName(name); + return this.contexts.update(contextName, { data: {}, [LATEST_FDC3_TYPE]: undefined }); + } + isChannel(name) { + return this.all().some((channelName) => channelName === name); + } + async remove(name) { + if (!this.isChannel(name)) { + throw new Error(`A channel with name: ${name} doesn't exist!`); + } + const contextName = this.createContextName(name); + await this.contexts.destroy(contextName); + } + createContextName(name) { + return CONTEXT_PREFIX + name; + } + getFDC3Type(data) { + const fdc3PropsArr = Object.keys(data).filter((key) => key.indexOf("fdc3_") === 0); + if (fdc3PropsArr.length === 0) { + return; + } + if (fdc3PropsArr.length > 1) { + throw new Error("FDC3 does not support updating of multiple context keys"); + } + return fdc3PropsArr[0].split("_").slice(1).join("_"); + } + getContextWithFdc3Data(channelContext) { + const { latest_fdc3_type, ...rest } = channelContext; + const parsedType = latest_fdc3_type.split("&").join("."); + const fdc3Context = { type: parsedType, ...rest.data[`fdc3_${latest_fdc3_type}`] }; + delete rest.data[`fdc3_${latest_fdc3_type}`]; + const context = { + name: channelContext.name, + meta: channelContext.meta, + data: { + ...rest.data, + fdc3: fdc3Context + } + }; + return context; + } + } + class MultiSharedContextSubscriber extends BaseSharedContextSubscriber { + constructor() { + super(...arguments); + this.currentlySubscribedChannels = []; + this.unsubscribeMap = {}; + } + async switchChannel(id) { + const newChannels = new MultiChannelId(id).all(); + for (const newChannel of newChannels) { + if (!this.currentlySubscribedChannels.includes(newChannel)) { + await this.subscribeToChannel(newChannel); + } + } + } + async leave(id) { + const channelsToLeave = new MultiChannelId(id).all(); + for (const newChannel of channelsToLeave) { + if (this.currentlySubscribedChannels.includes(newChannel)) { + this.unsubscribeFromChannel(newChannel); + } + } + } + async updateData(id, data) { + const channels = new MultiChannelId(id).all(); + for (const channel of channels) { + await super.updateData(channel, data); + } + } + async setPaths(id, paths) { + const channels = new MultiChannelId(id).all(); + for (const channel of channels) { + await super.setPaths(channel, paths); + } + } + isChannel(name) { + const channels = new MultiChannelId(name).all(); + return channels.every((channel) => super.isChannel(channel)); + } + async subscribeToChannel(name) { + const contextName = this.createContextName(name); + const usub = await this.contexts.subscribe(contextName, (data, _, __, ___, extraData) => { + if (this.callback) { + this.callback(data.data, data, extraData === null || extraData === void 0 ? void 0 : extraData.updaterId); + } + }); + this.currentlySubscribedChannels.push(name); + this.unsubscribeMap[contextName] = usub; + } + async unsubscribeFromChannel(name) { + const contextName = this.createContextName(name); + const unsub = this.unsubscribeMap[contextName]; + if (unsub) { + unsub(); + delete this.unsubscribeMap[contextName]; + } + this.currentlySubscribedChannels = this.currentlySubscribedChannels.filter((channel) => channel !== name); + } + } + class SharedContextSubscriber extends BaseSharedContextSubscriber { + async switchChannel(name) { + this.unsubscribe(); + const contextName = this.createContextName(name); + this.unsubscribeFunc = await this.contexts.subscribe(contextName, (data, _, __, ___, extraData) => { + if (this.callback) { + this.callback(data.data, data, extraData === null || extraData === void 0 ? void 0 : extraData.updaterId); + } + }); + } + async leave() { + if (this.callback) { + this.callback({}, undefined); + } + this.unsubscribe(); + } + unsubscribe() { + if (this.unsubscribeFunc) { + this.unsubscribeFunc(); + this.unsubscribeFunc = undefined; + } + } + } + + const validateFdc3Options = (options) => { + if (typeof options !== "object" || Array.isArray(options)) { + throw new Error(`Provide options as an object`); + } + if (options.contextType && (typeof options.contextType !== "string" || !options.contextType.length)) { + throw new Error(`Provide options.contextType as a non-empty string`); + } + }; + + class ChannelsImpl { + constructor(interop, getWindowsAPI, getAppManagerAPI, logger) { + this.interop = interop; + this.getWindowsAPI = getWindowsAPI; + this.getAppManagerAPI = getAppManagerAPI; + this.logger = logger; + this.subsKey = "subs"; + this.changedKey = "changed"; + this.channelsChangedKey = "channelsChanged"; + this.isInitialJoin = true; + this.registry = CallbackRegistryFactory(); + this.pendingReplays = {}; + this.pendingRestrictionCallbacks = new Map(); + } + async getMyChannels(options) { + if (!this.currentChannelID) { + return Promise.resolve([]); + } + if (this.currentChannelID.all().length === 0) { + return Promise.resolve([]); + } + const result = []; + for (const channel of this.currentChannelID.all()) { + result.push(await this.get(channel, options)); + } + return result; + } + async init(shared, mode, initial) { + this.mode = mode; + this.shared = shared; + this.shared.subscribe(this.handler.bind(this)); + this.subscribeForChannelRestrictionsChange(); + let initialChannel = initial; + if (typeof window !== "undefined" && typeof window.glue42gd !== "undefined") { + initialChannel = window.glue42gd.initialChannel; + } + this.currentChannelID = this.getID(initialChannel); + this.logger.trace(`initialized with mode: "${mode}" and initial channel: "${initialChannel}"`); + if (this.currentChannelID.isJoinedToAnyChannel) { + this.logger.trace(`joining initial channel: "${this.currentChannelID.toString()}"`); + await this.joinNoSelectorSwitch(this.currentChannelID.toString()); + } + } + subscribe(callback, options) { + if (typeof callback !== "function") { + throw new Error("Please provide the callback as a function!"); + } + const id = Utils.generateId(); + this.pendingReplays[id] = true; + const wrappedCallback = (options === null || options === void 0 ? void 0 : options.contextType) + ? this.getWrappedSubscribeCallbackWithFdc3Type(callback, id, options.contextType) + : this.getWrappedSubscribeCallback(callback, id); + if (this.lastUpdate) { + let lastUpdate = Object.assign({}, this.lastUpdate); + setTimeout(async () => { + if (this.pendingReplays[id]) { + if (this.lastUpdate) { + lastUpdate = this.lastUpdate; + } + wrappedCallback(lastUpdate.context.data, lastUpdate.context, lastUpdate.updaterId); + } + delete this.pendingReplays[id]; + }, 0); + } + const unsub = this.registry.add(this.subsKey, wrappedCallback); + return () => { + this.pendingReplays[id] = false; + this.pendingRestrictionCallbacks.delete(id); + unsub(); + }; + } + async subscribeFor(name, callback, options) { + if (typeof name !== "string") { + throw new Error("Please provide the name as a string!"); + } + if (typeof callback !== "function") { + throw new Error("Please provide the callback as a function!"); + } + const id = Utils.generateId(); + const wrappedCallback = (options === null || options === void 0 ? void 0 : options.contextType) + ? this.getWrappedSubscribeCallbackWithFdc3Type(callback, id, options.contextType) + : this.getWrappedSubscribeCallback(callback, id); + const unsub = await this.shared.subscribeFor(name, wrappedCallback); + return () => { + this.pendingRestrictionCallbacks.delete(id); + unsub(); + }; + } + async publish(data, options) { + if (typeof data !== "object") { + throw new Error("Please provide the data as an object!"); + } + if (options) { + this.validatePublishOptions(options); + } + if (typeof options === "object") { + return this.publishWithOptions(data, options); + } + const channelName = typeof options === "string" ? options : this.currentChannelID.toString(); + if (!channelName) { + throw new Error("Not joined to any channel!"); + } + if (!this.shared.isChannel(channelName)) { + return Promise.reject(new Error(`A channel with name: ${channelName} doesn't exist!`)); + } + if (this.mode === "multi") { + const channelsToPublish = new MultiChannelId(channelName).all(); + const restrictedChannels = []; + for (const cn of channelsToPublish) { + const canPublish = (await this.getRestrictionsByChannel(cn)).write; + if (!canPublish) { + restrictedChannels.push(cn); + continue; + } + await this.shared.updateData(cn, data); + } + if (restrictedChannels.length > 0) { + const restrictedChannelsErr = `Unable to publish due to restrictions to the following channels: ${restrictedChannels.join(", ")}`; + if (restrictedChannels.length === channelsToPublish.length) { + throw new Error(restrictedChannelsErr); + } + else { + this.logger.warn(restrictedChannelsErr); + } + } + } + else { + const canPublish = (await this.getRestrictionsByChannel(channelName)).write; + if (!canPublish) { + throw new Error(`Window does not have permission to write to channel ${channelName}`); + } + return this.shared.updateData(channelName, data); + } + } + async setPaths(paths, name) { + if (name) { + if (typeof name !== "string") { + throw new Error("Please provide the name as a string!"); + } + if (!this.shared.isChannel(name)) { + return Promise.reject(new Error(`A channel with name: ${name} doesn't exist!`)); + } + if (!(await this.getRestrictionsByChannel(name)).write) { + throw new Error(`Window does not have permission to write to channel ${name}`); + } + return this.shared.setPaths(name, paths); + } + if (!this.currentChannelID) { + throw new Error("Not joined to any channel!"); + } + if (!(await this.getRestrictionsByChannel(this.currentChannelID.toString())).write) { + throw new Error(`Window does not have permission to write to channel ${this.currentChannelID.toString()}`); + } + if (!Array.isArray(paths)) { + throw new Error("Path Values argument is not a valid array"); + } + paths.forEach((path) => { + this.validatePathArgs(path); + }); + return this.shared.setPaths(this.currentChannelID.toString(), paths); + } + async setPath(path, name) { + if (name) { + if (typeof name !== "string") { + throw new Error("Please provide the name as a string!"); + } + if (!this.shared.isChannel(name)) { + return Promise.reject(new Error(`A channel with name: ${name} doesn't exist!`)); + } + if (!(await this.getRestrictionsByChannel(name)).write) { + throw new Error(`Window does not have permission to write to channel ${name}`); + } + return this.shared.setPaths(name, [path]); + } + if (!this.currentChannelID) { + throw new Error("Not joined to any channel!"); + } + if (!(await this.getRestrictionsByChannel(this.currentChannelID.toString())).write) { + throw new Error(`Window does not have permission to write to channel ${this.currentChannelID.toString()}`); + } + this.validatePathArgs(path); + return this.shared.setPaths(this.currentChannelID.toString(), [path]); + } + all() { + const channelNames = this.shared.all(); + return Promise.resolve(channelNames); + } + async list() { + const channelNames = await this.all(); + const channelContexts = await Promise.all(channelNames.map((channelName) => this.get(channelName))); + return channelContexts; + } + async get(name, options) { + if (typeof name !== "string") { + return Promise.reject(new Error("Please provide the channel name as a string!")); + } + if (!(options === null || options === void 0 ? void 0 : options.contextType)) { + return this.shared.getContextData(name); + } + validateFdc3Options(options); + const context = await this.shared.getContextData(name); + return this.getContextWithFdc3Type(context, options.contextType); + } + getMy(options) { + if (!this.currentChannelID) { + return Promise.resolve(undefined); + } + if (this.currentChannelID.all().length === 0) { + return Promise.resolve(undefined); + } + return this.get(this.currentChannelID.all()[0], options); + } + async join(name, windowId) { + if (windowId !== undefined && windowId !== null) { + this.validateWindowIdArg(windowId); + this.logger.trace(`joining channel ${name} for window: ${windowId}`); + return sendSwitchChannelUI(name, windowId); + } + return this.joinCore(name); + } + async joinNoSelectorSwitch(channelName) { + this.logger.trace(`joining channel "${channelName}" from command`); + return this.joinCore(channelName, false); + } + leave(options) { + this.logger.trace(`leaving channel with options: ${JSON.stringify(options)}`); + let windowId; + let channelName; + if (typeof options === "string") { + windowId = options; + } + else if (typeof options === "object" && !Array.isArray(options) && options !== null && options !== undefined) { + if (options.windowId) { + windowId = options.windowId; + } + if (options.channel) { + channelName = options.channel; + } + } + if (this.mode === "multi") { + return this.leaveWhenMulti(channelName, windowId); + } + else { + return this.leaveWhenSingle(channelName, windowId); + } + } + leaveNoSelectorSwitch(channelName) { + this.logger.trace(`leaving channel "${channelName}" from command`); + return this.leaveCore(false, channelName); + } + current() { + return this.currentChannelID.toString(); + } + my() { + return this.current(); + } + myChannels() { + var _a; + return (_a = this.currentChannelID.all()) !== null && _a !== void 0 ? _a : []; + } + onChannelsChanged(callback) { + if (typeof callback !== "function") { + throw new Error("Please provide the callback as a function!"); + } + let timeoutId; + const current = this.current(); + if (current) { + timeoutId = setTimeout(() => { + callback(this.myChannels()); + }, 0); + } + const un = this.registry.add(this.channelsChangedKey, callback); + return () => { + un(); + clearTimeout(timeoutId); + }; + } + changed(callback) { + if (typeof callback !== "function") { + throw new Error("Please provide the callback as a function!"); + } + const current = this.current(); + if (current) { + setTimeout(() => { + callback(this.current()); + }, 0); + } + return this.registry.add(this.changedKey, () => { + callback(this.current()); + }); + } + onChanged(callback) { + return this.changed(callback); + } + async add(info) { + var _a; + if (typeof info !== "object") { + throw new Error("Please provide the info as an object!"); + } + if (typeof info.name === "undefined") { + throw new Error("info.name is missing!"); + } + if (typeof info.name !== "string") { + throw new Error("Please provide the info.name as a string!"); + } + if (typeof info.meta === "undefined") { + throw new Error("info.meta is missing!"); + } + if (typeof info.meta !== "object") { + throw new Error("Please provide the info.meta as an object!"); + } + if (typeof info.meta.color === "undefined") { + throw new Error("info.meta.color is missing!"); + } + if (typeof info.meta.color !== "string") { + throw new Error("Please provide the info.meta.color as a string!"); + } + const context = { + name: info.name, + meta: info.meta || {}, + data: info.data || {} + }; + this.logger.trace(`adding channel: ${info.name}`); + await addOrRemoveChannel("addChannel", info.name, info.meta.color, (_a = info.meta) === null || _a === void 0 ? void 0 : _a.label); + await this.shared.updateChannel(info.name, context); + return context; + } + async remove(channel) { + if (typeof channel !== "string") { + throw new Error("Please provide the channel name as a string!"); + } + this.logger.trace(`removing channel: ${channel}`); + await this.shared.remove(channel); + await addOrRemoveChannel("removeChannel", channel); + } + async getWindowsOnChannel(channel) { + this.validateChannelArg(channel); + const windowInfos = await this.getWindowsWithChannels({ channels: [channel] }); + return windowInfos.map((w) => w.window); + } + async getWindowsWithChannels(filter) { + this.validateWindowsWithChannelsFilter(filter); + try { + const info = await getChannelsInfo(filter); + const windowsAPI = this.getWindowsAPI(); + if (info === null || info === void 0 ? void 0 : info.windows) { + return info.windows.reduce((memo, windowInfo) => { + const window = windowsAPI.findById(windowInfo.windowId); + memo.push({ + window, + channel: windowInfo.channel, + application: windowInfo.application + }); + return memo; + }, []); + } + } + catch (er) { + this.logger.error(`Error getting all channel enabled windows. This method is available since Glue42 3.12`, er); + } + return []; + } + async restrict(restriction) { + this.validateRestrictionConfig(restriction); + return setRestrictions(restriction); + } + async getRestrictions(windowId) { + if (windowId) { + this.validateWindowIdArg(windowId); + } + return getRestrictionsByWindow(windowId); + } + async restrictAll(restriction) { + this.validateRestrictionConfig(restriction); + return setRestrictionsForAllChannels(restriction); + } + handleRestrictionsChanged(restrictions, windowId) { + this.registry.execute("restrictions-changed", { + restrictions, + windowId + }); + } + async clearChannelData(channel) { + const channelName = typeof channel === "string" ? channel : this.currentChannelID.toString(); + if (!channelName) { + return; + } + if (!this.shared.isChannel(channelName)) { + return; + } + const canPublish = (await this.getRestrictionsByChannel(channelName)).write; + if (!canPublish) { + return; + } + return this.shared.clearContextData(channelName); + } + handler(data, context, updaterId) { + if (!context && !updaterId) { + this.lastUpdate = undefined; + return; + } + this.lastUpdate = { context, updaterId }; + this.pendingReplays = {}; + this.registry.execute(this.subsKey, data, context, updaterId); + } + async joinCore(name, changeSelector = true) { + this.logger.trace(`joining channel "${name}" ${changeSelector ? "" : "from command"}`); + if (typeof name !== "string") { + throw new Error("Please provide the channel name as a string!"); + } + const newId = this.getID(name); + if (!this.isInitialJoin && this.currentChannelID.isOnChannel(newId.toString())) { + this.logger.trace(`already on channel: "${name}" ${changeSelector ? "" : "from command"}`); + return; + } + this.isInitialJoin = false; + await Promise.all(newId.all().map((n) => this.verifyChannelExists(n))); + this.currentChannelID.joinChannel(name); + this.lastUpdate = undefined; + this.logger.trace(`switching channel context to: "${name}" ${changeSelector ? "" : "from command"}`); + await this.shared.switchChannel(this.currentChannelID.toString()); + if (changeSelector) { + this.logger.trace(`switching UI channel to: "${name}" ${changeSelector ? "" : "from command"}`); + await sendSwitchChannelUI(name); + this.logger.trace(`switched UI channel to: "${name}" ${changeSelector ? "" : "from command"}`); + } + this.raiseChannelsChangedEvents(); + this.logger.trace(`joined channel: ${name} ${changeSelector ? "" : "from command"} - current channel/s: ${this.currentChannelID.toString()}`); + } + async verifyChannelExists(name) { + const doesChannelExist = (channelName) => { + const channelNames = this.shared.all(); + return channelNames.includes(channelName); + }; + if (!doesChannelExist(name)) { + const channelExistsPromise = new Promise((resolve, reject) => { + const intervalId = setInterval(() => { + if (doesChannelExist(name)) { + clearTimeout(timeoutId); + clearInterval(intervalId); + resolve(); + } + }, 100); + const timeoutId = setTimeout(() => { + clearInterval(intervalId); + return reject(new Error(`A channel with name: ${name} doesn't exist!`)); + }, 3000); + }); + await channelExistsPromise; + } + } + async leaveCore(changeSelector = true, channelID) { + if (!this.currentChannelID.isJoinedToAnyChannel) { + this.logger.trace(`leave called ${changeSelector ? "" : "from command"} when not joined to any channel change selector`); + return; + } + if (channelID && !this.currentChannelID.isOnChannel(channelID)) { + this.logger.trace(`leave called ${changeSelector ? "" : "from command"} when not joined to channel: "${channelID}"`); + return; + } + this.logger.trace(`leaving context channel: "${channelID}" ${changeSelector ? "" : "from command"}`); + this.currentChannelID.leaveChannel(channelID); + await this.shared.leave(channelID); + this.lastUpdate = undefined; + this.raiseChannelsChangedEvents(); + if (changeSelector) { + this.logger.trace(`switching UI channel to: "${channelID}" ${changeSelector ? "" : "from command"}`); + await sendSwitchChannelUI(this.currentChannelID.toString()); + this.logger.trace(`switched UI channel to: "${channelID}" ${changeSelector ? "" : "from command"}`); + } + this.logger.trace(`left single channel: "${channelID}" ${changeSelector ? "" : "from command"} - current channel/s: "${this.currentChannelID.toString()}"`); + return Promise.resolve(); + } + async leaveCoreMulti(changeSelector = true, channelID) { + this.logger.trace(`leaving multi channel: "${channelID.toString()}" ${changeSelector ? "" : "from command"}`); + const currentChannels = this.currentChannelID.all(); + const isJoinedToChannel = currentChannels.some((c) => channelID.isOnChannel(c)); + if (!isJoinedToChannel || !this.currentChannelID.isJoinedToAnyChannel) { + this.logger.trace(`leave called ${changeSelector ? "" : "from command"} when not joined to any channel`); + return; + } + const channelName = channelID.toString(); + this.currentChannelID.leaveChannel(channelName); + await this.shared.leave(channelName); + this.lastUpdate = undefined; + this.raiseChannelsChangedEvents(); + if (changeSelector) { + this.logger.trace(`switching UI channel to: "${channelName}" ${changeSelector ? "" : "from command"}`); + await sendLeaveChannel(channelName); + this.logger.trace(`switched UI channel to: "${channelName}" ${changeSelector ? "" : "from command"}`); + } + this.logger.trace(`left multi channel: "${channelName}" ${changeSelector ? "" : "from command"} - current channel/s: ${this.currentChannelID.toString()}`); + return Promise.resolve(); + } + raiseChannelsChangedEvents() { + this.registry.execute(this.changedKey, this.currentChannelID.toString()); + this.registry.execute(this.channelsChangedKey, this.currentChannelID.all()); + } + async getRestrictionsByChannel(channelName) { + var _a; + const restrictions = (_a = this.channelRestrictions) !== null && _a !== void 0 ? _a : await getRestrictionsByWindow(); + if (!restrictions || !Array.isArray(restrictions.channels) || !restrictions.channels.find(c => c.name === channelName)) { + return { + read: true, + write: true + }; + } + const byChannel = restrictions.channels.find(c => c.name === channelName); + return byChannel; + } + onRestrictionsChanged(callback, callbackId, currentChannelName) { + this.pendingRestrictionCallbacks.set(callbackId, { + cb: callback, + channelName: currentChannelName + }); + if (this.onRestrictionsChangedSub) { + return; + } + this.onRestrictionsChangedSub = this.registry.add("restrictions-changed", ({ restrictions }) => { + this.logger.trace(`restrictions changed - ${JSON.stringify(restrictions)}`); + this.pendingRestrictionCallbacks.forEach(({ cb, channelName }, id) => { + const currentChannel = restrictions.channels.find((c) => c.name === channelName); + if (!currentChannel) { + this.logger.trace(`channel "${channelName}" not found in restrictions`); + return; + } + if (currentChannel.read) { + this.pendingRestrictionCallbacks.delete(id); + if (this.pendingRestrictionCallbacks.values.length === 0 && this.onRestrictionsChangedSub) { + this.onRestrictionsChangedSub(); + this.onRestrictionsChangedSub = null; + } + cb(); + } + }); + }); + } + subscribeForChannelRestrictionsChange() { + this.registry.add("restrictions-changed", (r) => { + this.logger.trace(`channel restrictions changed - ${JSON.stringify(r.restrictions)}`); + this.channelRestrictions = r.restrictions; + }); + } + validatePathArgs(path) { + if (!path) { + throw new Error("Please provide a valid path value argument"); + } + if (typeof path !== "object") { + throw new Error(`Path Value argument is not a valid object: ${JSON.stringify(path)}`); + } + if (!path.path) { + throw new Error(`path property is missing from Path Value argument: ${JSON.stringify(path)}`); + } + if (!path.value) { + throw new Error(`value property is missing from Path Value argument: ${JSON.stringify(path)}`); + } + if (typeof path.path !== "string") { + throw new Error(`path property is not a valid string from the Path Value argument: ${JSON.stringify(path)}`); + } + } + validatePublishOptions(options) { + if ((typeof options !== "string" && typeof options !== "object") || Array.isArray(options)) { + throw new Error("Provide options as a string or an object"); + } + if (typeof options === "object") { + this.validatePublishOptionsObject(options); + return; + } + if (options === "string" && !options.length) { + throw new Error("Provide options as a non-empty string"); + } + } + validatePublishOptionsObject(options) { + if (typeof options !== "object" || Array.isArray(options)) { + throw new Error("Provide options as an object"); + } + if (options.name && (typeof options.name !== "string" || !options.name.length)) { + throw new Error("Provide options.name as a non-empty string"); + } + if (Object.keys(options).includes("fdc3") && typeof options.fdc3 !== "boolean") { + throw new Error("Provide options.fdc3 as a boolean"); + } + } + async publishWithOptions(data, options) { + const channelName = options.name || this.currentChannelID.toString(); + if (!this.shared.isChannel(channelName)) { + throw new Error(`A channel with name: ${options.name} doesn't exist!`); + } + if (!channelName) { + throw new Error("Cannot publish to channel, because not joined to a channel!"); + } + const canPublish = (await this.getRestrictionsByChannel(channelName)).write; + if (!canPublish) { + throw new Error(`Window does not have permission to write to channel ${this.currentChannelID.toString()}`); + } + if (!options.fdc3) { + return this.shared.updateData(channelName, data); + } + return this.publishFdc3Data(channelName, data); + } + async publishFdc3Data(channelName, data) { + var _a; + if (typeof data.type !== "string" || !((_a = data.type) === null || _a === void 0 ? void 0 : _a.length)) { + throw new Error("Expected a valid FDC3 Context with compulsory 'type' field"); + } + const { type, ...rest } = data; + const parsedType = type.split(".").join("&"); + const fdc3DataToPublish = { [`fdc3_${parsedType}`]: rest }; + return this.shared.updateData(channelName, fdc3DataToPublish); + } + getWrappedSubscribeCallback(callback, id) { + const wrappedCallback = async (_, context, updaterId) => { + const restrictionByChannel = await this.getRestrictionsByChannel(context.name); + const channelData = this.getDataWithFdc3Encoding(context); + if (restrictionByChannel.read) { + callback(channelData, context, updaterId); + } + else { + this.onRestrictionsChanged(() => { + callback(channelData, context, updaterId); + }, id, context.name); + } + }; + return wrappedCallback; + } + getWrappedSubscribeCallbackWithFdc3Type(callback, id, fdc3Type) { + const didReplay = { replayed: false }; + const wrappedCallback = async (_, context, updaterId) => { + const restrictionByChannel = await this.getRestrictionsByChannel(context.name); + const callbackWithTypesChecks = () => { + const { data, latest_fdc3_type } = context; + const searchedType = `fdc3_${fdc3Type.split(".").join("&")}`; + if (!data[searchedType]) { + return; + } + if (didReplay.replayed) { + return this.parseDataAndInvokeSubscribeCallback({ latestFdc3TypeEncoded: latest_fdc3_type, searchedType: fdc3Type, callback, context, updaterId }); + } + const fdc3Data = { type: fdc3Type, ...data[searchedType] }; + callback({ fdc3: fdc3Data }, context, updaterId); + didReplay.replayed = true; + }; + if (restrictionByChannel.read) { + callbackWithTypesChecks(); + return; + } + this.onRestrictionsChanged(callbackWithTypesChecks, id, context.name); + }; + return wrappedCallback; + } + parseDataAndInvokeSubscribeCallback(args) { + const { latestFdc3TypeEncoded, searchedType, callback, context, updaterId } = args; + const latestPublishedType = latestFdc3TypeEncoded.split("&").join("."); + if (latestPublishedType !== searchedType) { + return; + } + const fdc3Data = { type: searchedType, ...context.data[`fdc3_${latestFdc3TypeEncoded}`] }; + callback({ fdc3: fdc3Data }, context, updaterId); + } + getContextWithFdc3Type(context, searchedType) { + var _a, _b; + if (((_b = (_a = context.data) === null || _a === void 0 ? void 0 : _a.fdc3) === null || _b === void 0 ? void 0 : _b.type) === searchedType) { + return { + name: context.name, + meta: context.meta, + data: { fdc3: context.data.fdc3 } + }; + } + const encodedType = `fdc3_${searchedType.split(".").join("&")}`; + if (!context.data[encodedType]) { + return { + name: context.name, + meta: context.meta, + data: {} + }; + } + const fdc3Context = { type: searchedType, ...context.data[encodedType] }; + return { + name: context.name, + meta: context.meta, + data: { fdc3: fdc3Context } + }; + } + getDataWithFdc3Encoding(context) { + const { data, latest_fdc3_type } = context; + if (!latest_fdc3_type) { + return data; + } + const parsedType = latest_fdc3_type.split("&").join("."); + const latestTypePropName = `fdc3_${latest_fdc3_type}`; + const fdc3Data = { type: parsedType, ...data[latestTypePropName] }; + const { [latestTypePropName]: latestFDC3Type, ...rest } = data; + return { ...rest, fdc3: fdc3Data }; + } + getID(id) { + if (this.mode === "multi") { + return new MultiChannelId(id); + } + else { + return new SingleChannelID(id); + } + } + leaveWhenSingle(channelName, windowId) { + if (windowId) { + this.logger.trace(`leaving single channel "${channelName}" for window: "${windowId}"`); + return sendSwitchChannelUI(undefined, windowId); + } + this.logger.trace(`leaving single channel "${channelName}" for our window`); + return this.leaveCore(true, channelName); + } + async leaveWhenMulti(channelName, windowId) { + if (windowId) { + this.logger.trace(`leaving multi channel "${channelName}" for window: "${windowId}"`); + return sendLeaveChannel(channelName, windowId); + } + else { + const channelId = channelName ? new MultiChannelId(channelName) : this.currentChannelID; + this.logger.trace(`leaving multi channel "${channelId.toString()}" for our window`); + return this.leaveCoreMulti(true, channelId); + } + } + validateWindowIdArg(windowId) { + if (typeof windowId !== "string") { + throw new Error("The window ID must be a non-empty string!"); + } + const windows = this.getWindowsAPI(); + if (!windows.findById(windowId)) { + throw new Error(`Window with ID "${windowId}" doesn't exist!`); + } + } + validateChannelArg(channel) { + if (!channel) { + throw new Error("Please provide a valid Channel name as a non-empty string!"); + } + if (typeof channel !== "string") { + throw new Error("The Channel name must be a non-empty string!"); + } + const channelNames = this.shared.all(); + if (channelNames.every((name) => name !== channel)) { + throw new Error(`Channel "${channel}" does not exist!"`); + } + } + validateWindowsWithChannelsFilter(filter) { + if (filter === undefined) { + return; + } + if (filter === null || Array.isArray(filter) || typeof filter !== "object") { + throw new Error("The `filter` argument must be a valid object!"); + } + } + isRestrictions(restriction) { + return 'name' in restriction; + } + validateRestrictionConfig(restriction) { + if (restriction === null || restriction === undefined || Array.isArray(restriction) || typeof restriction !== "object") { + throw new Error("The `restrictions` argument must be a valid object with Channel restrictions!"); + } + if (this.isRestrictions(restriction) && typeof restriction.name !== "string") { + throw new Error("The `name` restriction property must be a non-empty string!"); + } + if (restriction.read !== null && restriction.read !== undefined && typeof restriction.read !== "boolean") { + throw new Error("The `read` restriction property must be a boolean value!"); + } + if (restriction.write !== null && restriction.write !== undefined && typeof restriction.write !== "boolean") { + throw new Error("The `write` restriction property must be a boolean value!"); + } + if ((restriction.read === null || restriction.read === undefined) && (restriction.write === null || restriction.write === undefined)) { + throw new Error("It's required to set either the `read` or the `write` property of the Channel restriction object!"); + } + if (restriction.windowId !== null && restriction.windowId !== undefined) { + this.validateWindowIdArg(restriction.windowId); + } + } + } + + function factory$4(config, contexts, agm, getWindowsAPI, getAppManagerAPI, logger) { + const channelsReadyPromise = getChannelInitInfo(config, agm) + .then(async ({ mode, initialChannel }) => { + const sharedContexts = mode === "single" ? new SharedContextSubscriber(contexts) : new MultiSharedContextSubscriber(contexts); + if (mode === "multi") { + logger.info(`multi-channel mode enabled`); + } + await channels.init(sharedContexts, mode, initialChannel); + await setupInterop(agm, channels, logger); + return true; + }); + const channels = new ChannelsImpl(agm, getWindowsAPI, getAppManagerAPI, logger); + return { + subscribe: channels.subscribe.bind(channels), + subscribeFor: channels.subscribeFor.bind(channels), + publish: channels.publish.bind(channels), + setPath: channels.setPath.bind(channels), + setPaths: channels.setPaths.bind(channels), + all: channels.all.bind(channels), + list: channels.list.bind(channels), + get: channels.get.bind(channels), + join: channels.join.bind(channels), + leave: channels.leave.bind(channels), + restrict: channels.restrict.bind(channels), + getRestrictions: channels.getRestrictions.bind(channels), + clearChannelData: channels.clearChannelData.bind(channels), + restrictAll: channels.restrictAll.bind(channels), + current: channels.current.bind(channels), + my: channels.my.bind(channels), + changed: channels.changed.bind(channels), + onChanged: channels.onChanged.bind(channels), + add: channels.add.bind(channels), + remove: channels.remove.bind(channels), + getWindowsOnChannel: channels.getWindowsOnChannel.bind(channels), + getWindowsWithChannels: channels.getWindowsWithChannels.bind(channels), + getMy: channels.getMy.bind(channels), + ready: async () => { + await Promise.all([contexts.ready(), channelsReadyPromise]); + }, + get mode() { return channels.mode; }, + getMyChannels: channels.getMyChannels.bind(channels), + myChannels: channels.myChannels.bind(channels), + onChannelsChanged: channels.onChannelsChanged.bind(channels), + }; + } + + const CommandMethod = "T42.Hotkeys.Command"; + const InvokeMethod = "T42.Hotkeys.Invoke"; + const RegisterCommand = "register"; + const UnregisterCommand = "unregister"; + const UnregisterAllCommand = "unregisterAll"; + class HotkeysImpl { + constructor(agm) { + this.agm = agm; + this.registry = CallbackRegistryFactory(); + this.firstHotkey = true; + this.hotkeys = new Map(); + } + async register(info, callback) { + if (typeof info === "undefined") { + throw new Error("Hotkey parameter missing"); + } + if (typeof info === "string") { + info = { + hotkey: info + }; + } + else { + if (!info.hotkey) { + throw new Error("Info's hotkey parameter missing"); + } + info = { + hotkey: info.hotkey, + description: info.description + }; + } + const hkToLower = this.formatHotkey(info.hotkey); + if (this.hotkeys.has(hkToLower)) { + throw new Error(`Shortcut for ${hkToLower} already registered`); + } + if (this.firstHotkey) { + this.firstHotkey = false; + await this.registerInvokeAGMMethod(); + } + this.registry.add(hkToLower, callback); + await this.agm.invoke(CommandMethod, { command: RegisterCommand, hotkey: hkToLower, description: info.description }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + this.hotkeys.set(hkToLower, info); + } + async unregister(hotkey) { + if (typeof hotkey === "undefined") { + throw new Error("hotkey parameter missing"); + } + if (typeof hotkey !== "string") { + throw new Error("hotkey parameter must be string"); + } + const hkToLower = this.formatHotkey(hotkey); + await this.agm.invoke(CommandMethod, { command: UnregisterCommand, hotkey: hkToLower }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + this.hotkeys.delete(hkToLower); + this.registry.clearKey(hkToLower); + } + async unregisterAll() { + await this.agm.invoke(CommandMethod, { command: UnregisterAllCommand }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + this.hotkeys.clear(); + this.registry.clear(); + } + isRegistered(hotkey) { + const hkToLower = this.formatHotkey(hotkey); + return this.hotkeys.has(hkToLower); + } + registerInvokeAGMMethod() { + return this.agm.register(InvokeMethod, (args) => { + const hkToLower = args.key.toLowerCase(); + const info = this.hotkeys.get(hkToLower); + this.registry.execute(hkToLower, info); + }); + } + formatHotkey(hotkey) { + if (hotkey) { + return hotkey.replace(/\s/g, "").toLowerCase(); + } + } + } + + function factory$3(agm) { + const hotkeys = new HotkeysImpl(agm); + return { + register: hotkeys.register.bind(hotkeys), + unregister: hotkeys.unregister.bind(hotkeys), + unregisterAll: hotkeys.unregisterAll.bind(hotkeys), + isRegistered: hotkeys.isRegistered.bind(hotkeys), + ready: () => Promise.resolve() + }; + } + + var version = "6.12.0"; + + var prepareConfig = (options) => { + function getLibConfig(value, defaultMode, trueMode) { + if (typeof value === "boolean" && !value) { + return undefined; + } + const mode = getModeAsString(value, defaultMode, trueMode); + if (typeof mode === "undefined") { + return undefined; + } + if (typeof value === "object") { + value.mode = mode; + return value; + } + return { + mode, + }; + } + function getModeAsString(value, defaultMode, trueMode) { + if (typeof value === "object") { + return getModeAsString(value.mode, defaultMode, trueMode).toString(); + } + else if (typeof value === "undefined") { + if (typeof defaultMode === "boolean" && !defaultMode) { + return undefined; + } + else if (typeof defaultMode === "boolean" && defaultMode) { + return typeof trueMode === "undefined" ? defaultMode : trueMode; + } + else if (typeof defaultMode === "undefined") { + return undefined; + } + else { + return defaultMode; + } + } + else if (typeof value === "boolean") { + if (value) { + return (typeof trueMode === "undefined") ? defaultMode : trueMode; + } + else { + return undefined; + } + } + return value; + } + const appDefaultMode = true; + const appDefaultTrueMode = "startOnly"; + const activitiesDefaultMode = Utils.isNode() ? false : "trackMyTypeAndInitiatedFromMe"; + const activitiesTrueMode = "trackMyTypeAndInitiatedFromMe"; + const layoutsDefaultMode = "slim"; + const layoutsTrueMode = layoutsDefaultMode; + const channelsConfig = () => { + if (typeof options.channels === "boolean") { + return options.channels; + } + else if (typeof options.channels === "object" && typeof options.channels.enabled === "boolean" && options.channels.enabled) { + return { mode: true, ...options.channels }; + } + else { + return false; + } + }; + const exposeAPI = typeof options.exposeAPI === "boolean" || typeof options.exposeGlue === "boolean"; + return { + layouts: getLibConfig(options.layouts, layoutsDefaultMode, layoutsTrueMode), + activities: getLibConfig(options.activities, activitiesDefaultMode, activitiesTrueMode), + appManager: getLibConfig(options.appManager, appDefaultMode, appDefaultTrueMode), + windows: getLibConfig(options.windows, true, true), + channels: getLibConfig(channelsConfig(), false, true), + displays: getLibConfig(options.displays, true, true), + exposeAPI: exposeAPI ? exposeAPI : true + }; + }; + + class Glue42Notification { + constructor(options) { + this.options = options; + this.callbacks = CallbackRegistryFactory(); + this.actions = options.actions; + this.body = options.body; + this.badge = options.badge; + this.data = options.data; + this.dir = options.dir; + this.icon = options.icon; + this.image = options.image; + this.lang = options.lang; + this.renotify = options.renotify; + this.requireInteraction = options.requireInteraction; + this.silent = options.silent; + this.tag = options.tag; + this.timestamp = options.timestamp; + this.title = options.title; + } + close() { + throw new Error("Method not implemented."); + } + addEventListener(type, listener, options) { + this.callbacks.add(type, listener); + } + removeEventListener(type, listener, options) { + } + dispatchEvent(event) { + this.callbacks.execute(event.type, event); + return true; + } + } + + class PanelAPI { + constructor(interop, onStreamEvent) { + this.interop = interop; + this.onStreamEvent = onStreamEvent; + } + onVisibilityChanged(callback) { + return this.onStreamEvent("on-panel-visibility-changed", callback); + } + toggle() { + return this.interop.invoke("T42.Notifications.Show", undefined, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + show() { + return this.interop.invoke("T42.Notifications.Show", { show: true }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + hide() { + return this.interop.invoke("T42.Notifications.Hide"); + } + async isVisible() { + const interopResult = await this.interop.invoke("T42.Notifications.Execute", { command: "isPanelVisible" }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return interopResult.returned.panelVisible; + } + toAPI() { + return { + onVisibilityChanged: this.onVisibilityChanged.bind(this), + toggle: this.toggle.bind(this), + show: this.show.bind(this), + hide: this.hide.bind(this), + isVisible: this.isVisible.bind(this) + }; + } + } + + const STARTING_INDEX = 0; + class Notifications { + constructor(interop, logger) { + this.interop = interop; + this.NotificationsSubscribeStream = "T42.GNS.Subscribe.Notifications"; + this.NotificationsCounterStream = "T42.Notifications.Counter"; + this.RaiseNotificationMethodName = "T42.GNS.Publish.RaiseNotification"; + this.NotificationsExecuteMethod = "T42.Notifications.Execute"; + this.NotificationFilterMethodName = "T42.Notifications.Filter"; + this.methodsRegistered = false; + this.NOTIFICATIONS_CONFIGURE_METHOD_NAME = "T42.Notifications.Configure"; + this.methodNameRoot = "T42.Notifications.Handler-" + Utils.generateId(); + this.nextId = 0; + this.notifications = {}; + this.registry = CallbackRegistryFactory(); + this.subscribedForNotifications = false; + this.subscribedCounterStream = false; + this.subscriptionsCountForNotifications = 0; + this.subscriptionsCountForCounter = 0; + this.logger = logger.subLogger("notifications"); + this._panel = new PanelAPI(interop, this.onStreamEventCore.bind(this)); + this._panelAPI = this._panel.toAPI(); + this.subscribeInternalEvents(); + } + get maxActions() { + return 10; + } + get panel() { + return this._panelAPI; + } + async raise(options) { + var _a; + const notification = await this.createNotification(options); + const g42notification = new Glue42Notification(options); + this.notifications[notification.id] = g42notification; + try { + const invocationResult = await this.interop.invoke(this.RaiseNotificationMethodName, { notification }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + g42notification.id = (_a = invocationResult.returned) === null || _a === void 0 ? void 0 : _a.id; + } + catch (err) { + const errorMessage = err.message; + setTimeout(() => { + this.handleNotificationErrorEvent(g42notification, errorMessage); + }, 1); + } + return g42notification; + } + async setFilter(filter) { + const result = await this.interop.invoke(this.NotificationFilterMethodName, filter, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return result.returned; + } + async getFilter() { + const result = await this.interop.invoke(this.NotificationFilterMethodName, undefined, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return result.returned; + } + async configure(options) { + var _a, _b, _c, _d, _e, _f, _g, _h; + if (!options || Array.isArray(options)) { + throw new Error("Invalid options - should be an object."); + } + if (Object.values(options).length === 0) { + throw new Error("The argument must be a non-empty object."); + } + if (typeof options.enable !== "undefined" && typeof options.enable !== "boolean") { + throw new Error("Expected type of enabled - boolean."); + } + if (typeof options.enableToasts !== "undefined" && typeof options.enableToasts !== "boolean") { + throw new Error("Expected type of enableToasts - boolean."); + } + if (typeof options.toastExpiry !== "undefined" && typeof options.toastExpiry !== "number") { + throw new Error("Expected type of toastExpiry - number."); + } + if (options.sourceFilter && typeof options.sourceFilter !== "object") { + throw new Error("Expected type of sourceFilter - object."); + } + if (((_a = options.sourceFilter) === null || _a === void 0 ? void 0 : _a.allowed) && !Array.isArray((_b = options.sourceFilter) === null || _b === void 0 ? void 0 : _b.allowed)) { + throw new Error("Expected type of sourceFilter.allowed - array."); + } + if (((_c = options.sourceFilter) === null || _c === void 0 ? void 0 : _c.blocked) && !Array.isArray((_d = options.sourceFilter) === null || _d === void 0 ? void 0 : _d.blocked)) { + throw new Error("Expected type of sourceFilter.blocked - array."); + } + if (options.toasts && typeof options.toasts !== "object") { + throw new Error("Expected type of (options.toasts - object."); + } + if (((_e = options.toasts) === null || _e === void 0 ? void 0 : _e.mode) && typeof options.toasts.mode !== "string") { + throw new Error("Expected type of (options.toasts.mode - string."); + } + if (((_f = options.toasts) === null || _f === void 0 ? void 0 : _f.stackBy) && typeof options.toasts.stackBy !== "string") { + throw new Error("Expected type of (options.toasts.stackBy - string."); + } + if (options.placement && typeof options.placement !== "object") { + throw new Error("Expected type of (options.placement - object."); + } + if (((_g = options.placement) === null || _g === void 0 ? void 0 : _g.toasts) && typeof options.placement.toasts !== "string") { + throw new Error("Expected type of (options.placement.toasts - string."); + } + if (((_h = options.placement) === null || _h === void 0 ? void 0 : _h.panel) && typeof options.placement.panel !== "string") { + throw new Error("Expected type of (options.placement.panel - string."); + } + if (typeof options.closeNotificationOnClick !== "undefined" && typeof options.closeNotificationOnClick !== "boolean") { + throw new Error("Expected type of closeNotificationOnClick - boolean."); + } + const result = await this.interop.invoke(this.NOTIFICATIONS_CONFIGURE_METHOD_NAME, options, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return result.returned; + } + async getConfiguration() { + const result = await this.interop.invoke(this.NotificationsExecuteMethod, { command: "getConfiguration" }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return result.returned; + } + async list() { + const interopResult = await this.interop.invoke(this.NotificationsExecuteMethod, { + command: "list", + data: { statesVersion2: true } + }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return interopResult.returned.notifications; + } + async updateData(id, data) { + const replacer = (key, value) => typeof value === "undefined" ? null : value; + const attribute = { + key: "data", + value: { + stringValue: JSON.stringify(data, replacer) + } + }; + const interopResult = await this.interop.invoke(this.NotificationsExecuteMethod, { command: "create-or-update-attribute", data: { id, attribute } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return interopResult.returned; + } + onRaised(callback) { + return this.onStreamEventCore("on-notification-raised", callback); + } + onStateChanged(callback) { + return this.onStreamEventCore("on-state-changed", callback); + } + onClosed(callback) { + return this.onStreamEventCore("on-notification-closed", callback); + } + onConfigurationChanged(callback) { + if (typeof callback !== "function") { + throw new Error("Please provide the callback as a function!"); + } + this.subscribe(); + const un = this.registry.add("on-configuration-changed", callback); + return () => { + un(); + this.closeStreamSubscriptionIfNoNeeded(); + }; + } + onCounterChanged(callback) { + if (typeof callback !== "function") { + throw new Error("Please provide the callback as a function!"); + } + this.subscribeForCounterStream(); + const un = this.registry.add("on-counter-changed", callback); + return () => { + un(); + this.closeStreamCounterSubscriptionIfNoNeeded(); + }; + } + onDataChanged(callback) { + if (typeof callback !== "function") { + throw new Error("Please provide the callback as a function!"); + } + this.subscribe(); + const un = this.registry.add("on-notification-data-changed", callback); + return () => { + un(); + this.closeStreamSubscriptionIfNoNeeded(); + }; + } + async clearAll() { + await this.interop.invoke(this.NotificationsExecuteMethod, { command: "clearAll" }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async clearOld() { + await this.interop.invoke(this.NotificationsExecuteMethod, { command: "clearAllOld", data: { statesVersion2: true } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async clear(id) { + if (!id) { + throw new Error("The 'id' argument cannot be null or undefined"); + } + if (typeof (id) !== "string") { + throw new Error("The 'id' argument must be a string"); + } + await this.interop.invoke(this.NotificationsExecuteMethod, { command: "clear", data: { id } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async clearMany(notifications) { + this.validateNotificationsArr(notifications); + await this.interop.invoke(this.NotificationsExecuteMethod, { command: "clearMany", data: { notifications } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async click(id, action, options) { + await this.interop.invoke(this.NotificationsExecuteMethod, { command: "click", data: { id, action, options } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async snooze(id, duration) { + await this.interop.invoke(this.NotificationsExecuteMethod, { command: "snooze", data: { id, duration } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async snoozeMany(notifications, duration) { + if (!duration) { + throw new Error("The 'duration' argument cannot be null or undefined"); + } + if (typeof duration !== "number") { + throw new Error("The 'duration' argument must be a valid number"); + } + this.validateNotificationsArr(notifications); + await this.interop.invoke(this.NotificationsExecuteMethod, { command: "snoozeMany", data: { notifications, duration } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async setState(id, state) { + if (!id) { + throw new Error("The 'id' argument cannot be null or undefined"); + } + if (typeof (id) !== "string") { + throw new Error("The 'id' argument must be a string"); + } + if (!state) { + throw new Error("The 'state' argument cannot be null or undefined"); + } + this.validateState(state); + await this.interop.invoke(this.NotificationsExecuteMethod, { command: "updateState", data: { id, state } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async setStates(notifications, state) { + if (!state) { + throw new Error("The 'state' argument cannot be null or undefined"); + } + if (typeof state !== "string") { + throw new Error("The 'state' argument must be a valid string"); + } + this.validateNotificationsArr(notifications); + await this.interop.invoke(this.NotificationsExecuteMethod, { command: "updateStates", data: { notifications, state } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + toAPI() { + return { + maxActions: this.maxActions, + panel: this._panel.toAPI(), + raise: this.raise.bind(this), + setFilter: this.setFilter.bind(this), + getFilter: this.getFilter.bind(this), + configure: this.configure.bind(this), + getConfiguration: this.getConfiguration.bind(this), + list: this.list.bind(this), + onRaised: this.onRaised.bind(this), + onStateChanged: this.onStateChanged.bind(this), + onClosed: this.onClosed.bind(this), + onConfigurationChanged: this.onConfigurationChanged.bind(this), + onCounterChanged: this.onCounterChanged.bind(this), + onDataChanged: this.onDataChanged.bind(this), + clearAll: this.clearAll.bind(this), + clearOld: this.clearOld.bind(this), + clear: this.clear.bind(this), + click: this.click.bind(this), + setState: this.setState.bind(this), + updateData: this.updateData.bind(this), + snooze: this.snooze.bind(this), + snoozeMany: this.snoozeMany.bind(this), + clearMany: this.clearMany.bind(this), + setStates: this.setStates.bind(this), + import: this.importNotifications.bind(this) + }; + } + async importNotifications(notifications) { + if (!notifications || !Array.isArray(notifications) || notifications.length === 0) { + throw new Error("Notifications argument must be a valid array with notification options"); + } + const notificationsToImport = await Promise.all(notifications.map((notificationOptions) => this.createNotification(notificationOptions, true))); + const invocationResult = await this.interop.invoke(this.NotificationsExecuteMethod, { command: "importNotifications", data: { notificationSettings: notificationsToImport } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return invocationResult.returned.notifications; + } + async createNotification(options, imported) { + var _a, _b, _c, _d; + this.validate(options, imported); + if (!this.methodsRegistered) { + const bunchOfPromises = []; + for (let index = STARTING_INDEX; index < this.maxActions; index++) { + bunchOfPromises.push(this.interop.register(`${this.methodNameRoot}_${index}`, this.handleNotificationEvent.bind(this))); + } + this.methodsRegistered = true; + await Promise.all(bunchOfPromises); + } + const id = (_a = options.id) !== null && _a !== void 0 ? _a : Utils.generateId(); + const type = (_b = options.type) !== null && _b !== void 0 ? _b : "Notification"; + const notification = { + id, + state: (_c = options.state) !== null && _c !== void 0 ? _c : "Active", + title: options.title, + type, + severity: (_d = options.severity) !== null && _d !== void 0 ? _d : "None", + description: options.body, + glueRoutingDetailMethodName: `${this.methodNameRoot}_${STARTING_INDEX}`, + actions: [], + sourceId: id, + source: options.source, + publishExtraEvents: true, + clickInterop: options.clickInterop + }; + if (options.actions) { + this.handleActions(options, id, notification); + } + this.handleOptions(options, notification); + return notification; + } + onStreamEventCore(key, callback) { + if (typeof callback !== "function") { + throw new Error("Please provide the callback as a function!"); + } + this.subscribe(); + const un = this.registry.add(key, callback); + return () => { + un(); + this.closeStreamSubscriptionIfNoNeeded(); + }; + } + handleOptions(options, notification) { + if (options.icon) { + notification.attributes = notification.attributes || []; + notification.attributes.push({ key: "icon", value: { stringValue: options.icon } }); + } + if (options.data) { + notification.attributes = notification.attributes || []; + const dataAsString = JSON.stringify(options.data); + notification.attributes.push({ key: "data", value: { stringValue: dataAsString } }); + } + if (typeof options.panelExpiry === "number") { + notification.attributes = notification.attributes || []; + notification.attributes.push({ key: "panelExpiry", value: { stringValue: options.panelExpiry.toString() } }); + } + if (typeof options.toastExpiry === "number") { + notification.attributes = notification.attributes || []; + notification.attributes.push({ key: "toastExpiry", value: { stringValue: options.toastExpiry.toString() } }); + } + } + handleActions(options, id, notification) { + var _a, _b, _c; + const validActions = options.actions.slice(0, this.maxActions); + let index = STARTING_INDEX; + for (const action of validActions) { + const args = { + g42notificationId: id, + g42action: action.action, + g42interopMethod: (_a = action.interop) === null || _a === void 0 ? void 0 : _a.method, + g42interopTarget: (_b = action.interop) === null || _b === void 0 ? void 0 : _b.target, + g42interopArguments: JSON.stringify((_c = action.interop) === null || _c === void 0 ? void 0 : _c.arguments) + }; + const parameters = Object.keys(args).map((key) => { + const value = args[key]; + return { + name: key, + value: { + stringValue: value + } + }; + }); + const glueAction = { + name: `${this.methodNameRoot}_${index}`, + description: action.title, + displayName: action.title, + displayPath: action.displayPath, + displayId: action.displayId, + parameters + }; + notification.actions.push(glueAction); + index++; + } + } + validate(options, imported) { + if (!options) { + throw new Error("invalid options - should be an object"); + } + if (typeof options !== "object") { + throw new Error("invalid options - should be an object"); + } + if (!options.title) { + throw new Error("invalid options - should have a title"); + } + if (typeof options.title !== "string") { + throw new Error("invalid options - title should be a string"); + } + if (options.severity && typeof options.severity !== "string") { + throw new Error("invalid options - severity should be a string"); + } + if (options.panelExpiry && typeof options.panelExpiry !== "number") { + throw new Error("invalid options - panelExpiry should be a number"); + } + if (options.toastExpiry && typeof options.toastExpiry !== "number") { + throw new Error("invalid options - toastExpiry should be a number"); + } + if (options.state) { + this.validateState(options.state, imported); + } + } + validateState(state, imported) { + if (typeof (state) !== "string") { + throw new Error("The 'state' argument must be a string"); + } + const validStates = [ + "Active", + "Acknowledged", + "Stale" + ]; + if (imported) { + validStates.push("Seen", "Snoozed", "Processing", "Closed"); + } + if (!validStates.includes(state)) { + throw new Error(`The state argument: ${state} is not valid!`); + } + } + subscribe() { + this.subscriptionsCountForNotifications++; + if (!this.subscribedForNotifications) { + this.subscribedForNotifications = true; + this.logger.info(`Attempting to subscribe to "${this.NotificationsSubscribeStream}".`); + this.interop + .subscribe(this.NotificationsSubscribeStream, { + arguments: { + sendDeltaOnly: true, + statesVersion2: true + } + }) + .then((sub) => { + this.subscriptionForNotifications = sub; + this.logger.info(`Successfully subscribed to "${this.NotificationsSubscribeStream}".`); + sub.onData(({ data }) => { + this.handleData(data); + }); + sub.onClosed((...args) => { + this.subscribedForNotifications = false; + this.logger.info(`Stream subscription Closed - ${JSON.stringify(args)}`); + }); + sub.onFailed((...args) => { + this.subscribedForNotifications = false; + this.logger.warn(`Stream subscription Failed - ${JSON.stringify(args)}`); + }); + }) + .catch((e) => { + this.subscribedForNotifications = false; + this.logger.error(`Unable to subscribe to "${this.NotificationsSubscribeStream}"`, e); + }); + } + } + subscribeForCounterStream() { + this.subscriptionsCountForCounter++; + if (!this.subscribedCounterStream) { + this.subscribedCounterStream = true; + this.logger.info(`Attempting to subscribe to "${this.NotificationsCounterStream}".`); + this.interop + .subscribe(this.NotificationsCounterStream, { + arguments: { + sendDeltaOnly: true + } + }) + .then((sub) => { + this.subscriptionForCounter = sub; + this.logger.info(`Successfully subscribed to "${this.NotificationsCounterStream}".`); + sub.onData(({ data }) => { + this.registry.execute("on-counter-changed", { count: data.count }); + }); + sub.onClosed((...args) => { + this.subscribedCounterStream = false; + this.logger.info(`Stream subscription Closed - ${JSON.stringify(args)}`); + }); + sub.onFailed((...args) => { + this.subscribedCounterStream = false; + this.logger.warn(`Stream subscription Failed - ${JSON.stringify(args)}`); + }); + }) + .catch((e) => { + this.subscribedCounterStream = false; + this.logger.error(`Unable to subscribe to "${this.NotificationsCounterStream}"`, e); + }); + } + } + subscribeInternalEvents() { + this.registry.add("on-notification-closed", (id) => { + this.handleOnClosed(id); + }); + this.registry.add("on-notification-raised", (notification) => { + this.handleOnShow(notification.id); + }); + } + handleData(message) { + var _a; + try { + if ("items" in message && Array.isArray(message.items)) { + this.handleItemsData(message); + } + else if ("deltas" in message && Array.isArray(message.deltas)) { + this.handleDeltas(message); + } + if ("configuration" in message && typeof message.configuration === "object") { + this.logger.info(`Received configuration ${JSON.stringify(message.configuration)} from the stream`); + this.registry.execute("on-configuration-changed", message.configuration, message.configuration.allApplications); + } + if ("command" in message && typeof message.command === "string") { + this.logger.info(`Received command "${(_a = message.command) !== null && _a !== void 0 ? _a : JSON.stringify(message)}" from the stream`); + if (message.command === "showPanel" || message.command === "hidePanel") { + this.registry.execute("on-panel-visibility-changed", message.command === "showPanel"); + } + } + } + catch (e) { + this.logger.error(`Failed to parse data from the stream`, e); + } + } + handleItemsData(message) { + const items = message.items; + this.logger.info(`Received ${items.length} notifications from the stream`); + const notifications = items; + if (message.isSnapshot) { + notifications.forEach((n) => { + this.registry.execute("on-notification-raised", n); + }); + } + else { + const notification = notifications[0]; + if (notification.state === "Closed") { + this.registry.execute("on-notification-closed", { id: notification.id }); + } + else { + this.registry.execute("on-notification-raised", notification); + } + } + } + handleDeltas(message) { + const deltas = message.deltas; + deltas.forEach((info) => { + var _a; + const id = info.id; + const delta = (_a = info.delta) !== null && _a !== void 0 ? _a : {}; + if (delta.state === "Closed") { + this.registry.execute("on-notification-closed", { id, ...delta }); + } + else if (delta.state) { + this.registry.execute("on-state-changed", { id }, delta.state); + } + else if (delta.attributes) { + const attributes = delta.attributes; + const dataAttribute = attributes.find((a) => a.key === "data"); + if (dataAttribute) { + this.registry.execute("on-notification-data-changed", { id }, JSON.parse(dataAttribute.value.stringValue)); + } + } + }); + } + handleOnClosed(id) { + const { notification, key } = this.getNotification(id); + if (notification) { + this.handleEvent(notification, "close"); + delete this.notifications[key]; + } + } + handleOnShow(id) { + const { notification } = this.getNotification(id); + if (notification) { + this.handleEvent(notification, "show"); + } + } + getNotification(id) { + let notification; + let key; + for (const k in this.notifications) { + if (this.notifications[k].id === id) { + notification = this.notifications[k]; + key = k; + break; + } + } + return { notification, key }; + } + handleNotificationEvent(args) { + const gnsNotificationArgs = this.getGnsNotificationArgs(args); + if (gnsNotificationArgs.event === "unknown") { + return; + } + const notification = this.notifications[gnsNotificationArgs.notificationId]; + if (!notification) { + return; + } + this.handleNotificationEventCore(notification, gnsNotificationArgs); + } + handleNotificationEventCore(notification, args) { + switch (args.event) { + case "action": { + return this.handleNotificationActionEvent(notification, args.notificationActionPayload); + } + case "click": { + return this.handleNotificationClickEvent(notification); + } + case "close": { + return this.handleEvent(notification, "close"); + } + case "error": { + return this.handleNotificationErrorEvent(notification, args.error); + } + case "show": { + return this.handleEvent(notification, "show"); + } + } + } + handleNotificationActionEvent(notification, payload) { + const event = { + type: "onaction", + action: payload.g42action + }; + if (notification.onaction) { + notification.onaction(event); + } + notification.dispatchEvent(event); + } + handleNotificationClickEvent(notification) { + const event = { type: "onclick" }; + if (notification.onclick) { + notification.onclick(event); + } + notification.dispatchEvent(event); + } + handleEvent(notification, eventType) { + var _a; + const event = { type: eventType }; + const eventName = `on${eventType}`; + (_a = notification[eventName]) === null || _a === void 0 ? void 0 : _a.call(notification, event); + notification.dispatchEvent(event); + } + handleNotificationErrorEvent(notification, error) { + const event = { type: "onerror", error }; + if (notification.onerror) { + notification.onerror(event); + } + notification.dispatchEvent(event); + } + getGnsNotificationArgs(args) { + var _a; + let result; + const event = (_a = args.notification) === null || _a === void 0 ? void 0 : _a.event; + if (!event) { + result = this.getBackwardGnsNotificationArgs(args); + } + else { + result = { + event, + notificationId: args.notification.sourceNotificationId, + notificationActionPayload: args + }; + } + return result; + } + getBackwardGnsNotificationArgs(args) { + var _a; + let result; + if (args.g42notificationId) { + result = { + event: "action", + notificationId: args.g42notificationId, + notificationActionPayload: args + }; + } + else if ((_a = args.notification) === null || _a === void 0 ? void 0 : _a.sourceNotificationId) { + result = { + event: "click", + notificationId: args.notification.sourceNotificationId, + notificationActionPayload: args + }; + } + else { + result = { + event: "unknown", + notificationId: undefined, + notificationActionPayload: args + }; + } + return result; + } + closeStreamSubscriptionIfNoNeeded() { + this.subscriptionsCountForNotifications--; + if (this.subscriptionForNotifications && this.subscriptionsCountForNotifications === 0) { + this.subscriptionForNotifications.close(); + this.subscriptionForNotifications = undefined; + } + } + closeStreamCounterSubscriptionIfNoNeeded() { + this.subscriptionsCountForCounter--; + if (this.subscriptionForCounter && this.subscriptionsCountForCounter === 0) { + this.subscriptionForCounter.close(); + this.subscriptionForCounter = undefined; + } + } + validateNotificationsArr(notifications) { + if (!Array.isArray(notifications)) { + throw new Error("The 'notifications' argument must be an array with valid notification IDs"); + } + if (notifications.some((n) => typeof n !== "string")) { + throw new Error("The 'notifications' argument must contain only valid string notification IDs"); + } + } + } + + const ThemesConfigurationMethodName = "T42.Themes.Configuration"; + class ThemesImpl { + constructor(contexts, interop) { + this.contexts = contexts; + this.interop = interop; + this.registry = CallbackRegistryFactory(); + this.isSubscribed = false; + this.getConfiguration(); + } + async list() { + await this.getConfiguration(); + if (!this.getMethodName) { + throw new Error("not supported"); + } + return (await this.getAll()).returned.all; + } + async getCurrent() { + await this.getConfiguration(); + if (!this.getMethodName) { + throw new Error("not supported"); + } + const all = await this.getAll(); + return all.returned.all.find((t) => t.name === all.returned.selected); + } + async select(theme) { + await this.getConfiguration(); + if (!this.setMethodName) { + throw new Error("not supported"); + } + await this.interop.invoke(this.setMethodName, { theme }); + } + onChanged(callback) { + if (!callback) { + throw new Error("Callback argument is required"); + } + if (callback && typeof callback !== "function") { + throw new Error("Callback argument must be a function"); + } + this.subscribe(); + return this.registry.add("changed", callback); + } + async getConfiguration() { + try { + if (this.sharedContextName) { + return; + } + const config = await this.interop.invoke(ThemesConfigurationMethodName); + this.sharedContextName = config.returned.sharedContextName; + this.getMethodName = config.returned.getThemesMethodName; + this.setMethodName = config.returned.setThemesMethodName; + } + catch (error) { + return; + } + } + async getAll() { + await this.getConfiguration(); + return await this.interop.invoke(this.getMethodName); + } + async subscribe() { + await this.getConfiguration(); + if (this.isSubscribed) { + return; + } + this.isSubscribed = true; + this.contexts.subscribe(this.sharedContextName, (data) => { + if (data && data.all && data.selected) { + this.registry.execute("changed", data.all.find((t) => t.name === data.selected)); + } + }); + } + } + + function factory$2(contexts, interop) { + const themes = new ThemesImpl(contexts, interop); + return { + list: themes.list.bind(themes), + getCurrent: themes.getCurrent.bind(themes), + select: themes.select.bind(themes), + onChanged: themes.onChanged.bind(themes), + ready: () => Promise.resolve(), + }; + } + + const connectBrowserAppProps = ["name", "title", "version", "customProperties", "icon", "caption", "type"]; + const fdc3v2AppProps = ["appId", "name", "type", "details", "version", "title", "tooltip", "lang", "description", "categories", "icons", "screenshots", "contactEmail", "moreInfo", "publisher", "customConfig", "hostManifests", "interop", "localizedVersions"]; + + /** + * Wraps values in an `Ok` type. + * + * Example: `ok(5) // => {ok: true, result: 5}` + */ + var ok = function (result) { return ({ ok: true, result: result }); }; + /** + * Wraps errors in an `Err` type. + * + * Example: `err('on fire') // => {ok: false, error: 'on fire'}` + */ + var err = function (error) { return ({ ok: false, error: error }); }; + /** + * Create a `Promise` that either resolves with the result of `Ok` or rejects + * with the error of `Err`. + */ + var asPromise = function (r) { + return r.ok === true ? Promise.resolve(r.result) : Promise.reject(r.error); + }; + /** + * Unwraps a `Result` and returns either the result of an `Ok`, or + * `defaultValue`. + * + * Example: + * ``` + * Result.withDefault(5, number().run(json)) + * ``` + * + * It would be nice if `Decoder` had an instance method that mirrored this + * function. Such a method would look something like this: + * ``` + * class Decoder
{ + * runWithDefault = (defaultValue: A, json: any): A => + * Result.withDefault(defaultValue, this.run(json)); + * } + * + * number().runWithDefault(5, json) + * ``` + * Unfortunately, the type of `defaultValue: A` on the method causes issues + * with type inference on the `object` decoder in some situations. While these + * inference issues can be solved by providing the optional type argument for + * `object`s, the extra trouble and confusion doesn't seem worth it. + */ + var withDefault = function (defaultValue, r) { + return r.ok === true ? r.result : defaultValue; + }; + /** + * Return the successful result, or throw an error. + */ + var withException = function (r) { + if (r.ok === true) { + return r.result; + } + else { + throw r.error; + } + }; + /** + * Apply `f` to the result of an `Ok`, or pass the error through. + */ + var map = function (f, r) { + return r.ok === true ? ok(f(r.result)) : r; + }; + /** + * Apply `f` to the result of two `Ok`s, or pass an error through. If both + * `Result`s are errors then the first one is returned. + */ + var map2 = function (f, ar, br) { + return ar.ok === false ? ar : + br.ok === false ? br : + ok(f(ar.result, br.result)); + }; + /** + * Apply `f` to the error of an `Err`, or pass the success through. + */ + var mapError = function (f, r) { + return r.ok === true ? r : err(f(r.error)); + }; + /** + * Chain together a sequence of computations that may fail, similar to a + * `Promise`. If the first computation fails then the error will propagate + * through. If it succeeds, then `f` will be applied to the value, returning a + * new `Result`. + */ + var andThen = function (f, r) { + return r.ok === true ? f(r.result) : r; + }; + + /*! ***************************************************************************** + Copyright (c) Microsoft Corporation. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THIS SOFTWARE. + ***************************************************************************** */ + /* global Reflect, Promise */ + + + + var __assign = function() { + __assign = Object.assign || function __assign(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; + } + return t; + }; + return __assign.apply(this, arguments); + }; + + function __rest(s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { + if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) + t[p[i]] = s[p[i]]; + } + return t; + } + + function isEqual(a, b) { + if (a === b) { + return true; + } + if (a === null && b === null) { + return true; + } + if (typeof (a) !== typeof (b)) { + return false; + } + if (typeof (a) === 'object') { + // Array + if (Array.isArray(a)) { + if (!Array.isArray(b)) { + return false; + } + if (a.length !== b.length) { + return false; + } + for (var i = 0; i < a.length; i++) { + if (!isEqual(a[i], b[i])) { + return false; + } + } + return true; + } + // Hash table + var keys = Object.keys(a); + if (keys.length !== Object.keys(b).length) { + return false; + } + for (var i = 0; i < keys.length; i++) { + if (!b.hasOwnProperty(keys[i])) { + return false; + } + if (!isEqual(a[keys[i]], b[keys[i]])) { + return false; + } + } + return true; + } + } + /* + * Helpers + */ + var isJsonArray = function (json) { return Array.isArray(json); }; + var isJsonObject = function (json) { + return typeof json === 'object' && json !== null && !isJsonArray(json); + }; + var typeString = function (json) { + switch (typeof json) { + case 'string': + return 'a string'; + case 'number': + return 'a number'; + case 'boolean': + return 'a boolean'; + case 'undefined': + return 'undefined'; + case 'object': + if (json instanceof Array) { + return 'an array'; + } + else if (json === null) { + return 'null'; + } + else { + return 'an object'; + } + default: + return JSON.stringify(json); + } + }; + var expectedGot = function (expected, got) { + return "expected " + expected + ", got " + typeString(got); + }; + var printPath = function (paths) { + return paths.map(function (path) { return (typeof path === 'string' ? "." + path : "[" + path + "]"); }).join(''); + }; + var prependAt = function (newAt, _a) { + var at = _a.at, rest = __rest(_a, ["at"]); + return (__assign({ at: newAt + (at || '') }, rest)); + }; + /** + * Decoders transform json objects with unknown structure into known and + * verified forms. You can create objects of type `Decoder` with either the + * primitive decoder functions, such as `boolean()` and `string()`, or by + * applying higher-order decoders to the primitives, such as `array(boolean())` + * or `dict(string())`. + * + * Each of the decoder functions are available both as a static method on + * `Decoder` and as a function alias -- for example the string decoder is + * defined at `Decoder.string()`, but is also aliased to `string()`. Using the + * function aliases exported with the library is recommended. + * + * `Decoder` exposes a number of 'run' methods, which all decode json in the + * same way, but communicate success and failure in different ways. The `map` + * and `andThen` methods modify decoders without having to call a 'run' method. + * + * Alternatively, the main decoder `run()` method returns an object of type + * `Result`. This library provides a number of helper + * functions for dealing with the `Result` type, so you can do all the same + * things with a `Result` as with the decoder methods. + */ + var Decoder = /** @class */ (function () { + /** + * The Decoder class constructor is kept private to separate the internal + * `decode` function from the external `run` function. The distinction + * between the two functions is that `decode` returns a + * `Partial` on failure, which contains an unfinished error + * report. When `run` is called on a decoder, the relevant series of `decode` + * calls is made, and then on failure the resulting `Partial` + * is turned into a `DecoderError` by filling in the missing information. + * + * While hiding the constructor may seem restrictive, leveraging the + * provided decoder combinators and helper functions such as + * `andThen` and `map` should be enough to build specialized decoders as + * needed. + */ + function Decoder(decode) { + var _this = this; + this.decode = decode; + /** + * Run the decoder and return a `Result` with either the decoded value or a + * `DecoderError` containing the json input, the location of the error, and + * the error message. + * + * Examples: + * ``` + * number().run(12) + * // => {ok: true, result: 12} + * + * string().run(9001) + * // => + * // { + * // ok: false, + * // error: { + * // kind: 'DecoderError', + * // input: 9001, + * // at: 'input', + * // message: 'expected a string, got 9001' + * // } + * // } + * ``` + */ + this.run = function (json) { + return mapError(function (error) { return ({ + kind: 'DecoderError', + input: json, + at: 'input' + (error.at || ''), + message: error.message || '' + }); }, _this.decode(json)); + }; + /** + * Run the decoder as a `Promise`. + */ + this.runPromise = function (json) { return asPromise(_this.run(json)); }; + /** + * Run the decoder and return the value on success, or throw an exception + * with a formatted error string. + */ + this.runWithException = function (json) { return withException(_this.run(json)); }; + /** + * Construct a new decoder that applies a transformation to the decoded + * result. If the decoder succeeds then `f` will be applied to the value. If + * it fails the error will propagated through. + * + * Example: + * ``` + * number().map(x => x * 5).run(10) + * // => {ok: true, result: 50} + * ``` + */ + this.map = function (f) { + return new Decoder(function (json) { return map(f, _this.decode(json)); }); + }; + /** + * Chain together a sequence of decoders. The first decoder will run, and + * then the function will determine what decoder to run second. If the result + * of the first decoder succeeds then `f` will be applied to the decoded + * value. If it fails the error will propagate through. + * + * This is a very powerful method -- it can act as both the `map` and `where` + * methods, can improve error messages for edge cases, and can be used to + * make a decoder for custom types. + * + * Example of adding an error message: + * ``` + * const versionDecoder = valueAt(['version'], number()); + * const infoDecoder3 = object({a: boolean()}); + * + * const decoder = versionDecoder.andThen(version => { + * switch (version) { + * case 3: + * return infoDecoder3; + * default: + * return fail(`Unable to decode info, version ${version} is not supported.`); + * } + * }); + * + * decoder.run({version: 3, a: true}) + * // => {ok: true, result: {a: true}} + * + * decoder.run({version: 5, x: 'abc'}) + * // => + * // { + * // ok: false, + * // error: {... message: 'Unable to decode info, version 5 is not supported.'} + * // } + * ``` + * + * Example of decoding a custom type: + * ``` + * // nominal type for arrays with a length of at least one + * type NonEmptyArray = T[] & { __nonEmptyArrayBrand__: void }; + * + * const nonEmptyArrayDecoder = (values: Decoder): Decoder> => + * array(values).andThen(arr => + * arr.length > 0 + * ? succeed(createNonEmptyArray(arr)) + * : fail(`expected a non-empty array, got an empty array`) + * ); + * ``` + */ + this.andThen = function (f) { + return new Decoder(function (json) { + return andThen(function (value) { return f(value).decode(json); }, _this.decode(json)); + }); + }; + /** + * Add constraints to a decoder _without_ changing the resulting type. The + * `test` argument is a predicate function which returns true for valid + * inputs. When `test` fails on an input, the decoder fails with the given + * `errorMessage`. + * + * ``` + * const chars = (length: number): Decoder => + * string().where( + * (s: string) => s.length === length, + * `expected a string of length ${length}` + * ); + * + * chars(5).run('12345') + * // => {ok: true, result: '12345'} + * + * chars(2).run('HELLO') + * // => {ok: false, error: {... message: 'expected a string of length 2'}} + * + * chars(12).run(true) + * // => {ok: false, error: {... message: 'expected a string, got a boolean'}} + * ``` + */ + this.where = function (test, errorMessage) { + return _this.andThen(function (value) { return (test(value) ? Decoder.succeed(value) : Decoder.fail(errorMessage)); }); + }; + } + /** + * Decoder primitive that validates strings, and fails on all other input. + */ + Decoder.string = function () { + return new Decoder(function (json) { + return typeof json === 'string' + ? ok(json) + : err({ message: expectedGot('a string', json) }); + }); + }; + /** + * Decoder primitive that validates numbers, and fails on all other input. + */ + Decoder.number = function () { + return new Decoder(function (json) { + return typeof json === 'number' + ? ok(json) + : err({ message: expectedGot('a number', json) }); + }); + }; + /** + * Decoder primitive that validates booleans, and fails on all other input. + */ + Decoder.boolean = function () { + return new Decoder(function (json) { + return typeof json === 'boolean' + ? ok(json) + : err({ message: expectedGot('a boolean', json) }); + }); + }; + Decoder.constant = function (value) { + return new Decoder(function (json) { + return isEqual(json, value) + ? ok(value) + : err({ message: "expected " + JSON.stringify(value) + ", got " + JSON.stringify(json) }); + }); + }; + Decoder.object = function (decoders) { + return new Decoder(function (json) { + if (isJsonObject(json) && decoders) { + var obj = {}; + for (var key in decoders) { + if (decoders.hasOwnProperty(key)) { + var r = decoders[key].decode(json[key]); + if (r.ok === true) { + // tslint:disable-next-line:strict-type-predicates + if (r.result !== undefined) { + obj[key] = r.result; + } + } + else if (json[key] === undefined) { + return err({ message: "the key '" + key + "' is required but was not present" }); + } + else { + return err(prependAt("." + key, r.error)); + } + } + } + return ok(obj); + } + else if (isJsonObject(json)) { + return ok(json); + } + else { + return err({ message: expectedGot('an object', json) }); + } + }); + }; + Decoder.array = function (decoder) { + return new Decoder(function (json) { + if (isJsonArray(json) && decoder) { + var decodeValue_1 = function (v, i) { + return mapError(function (err$$1) { return prependAt("[" + i + "]", err$$1); }, decoder.decode(v)); + }; + return json.reduce(function (acc, v, i) { + return map2(function (arr, result) { return arr.concat([result]); }, acc, decodeValue_1(v, i)); + }, ok([])); + } + else if (isJsonArray(json)) { + return ok(json); + } + else { + return err({ message: expectedGot('an array', json) }); + } + }); + }; + Decoder.tuple = function (decoders) { + return new Decoder(function (json) { + if (isJsonArray(json)) { + if (json.length !== decoders.length) { + return err({ + message: "expected a tuple of length " + decoders.length + ", got one of length " + json.length + }); + } + var result = []; + for (var i = 0; i < decoders.length; i++) { + var nth = decoders[i].decode(json[i]); + if (nth.ok) { + result[i] = nth.result; + } + else { + return err(prependAt("[" + i + "]", nth.error)); + } + } + return ok(result); + } + else { + return err({ message: expectedGot("a tuple of length " + decoders.length, json) }); + } + }); + }; + Decoder.union = function (ad, bd) { + var decoders = []; + for (var _i = 2; _i < arguments.length; _i++) { + decoders[_i - 2] = arguments[_i]; + } + return Decoder.oneOf.apply(Decoder, [ad, bd].concat(decoders)); + }; + Decoder.intersection = function (ad, bd) { + var ds = []; + for (var _i = 2; _i < arguments.length; _i++) { + ds[_i - 2] = arguments[_i]; + } + return new Decoder(function (json) { + return [ad, bd].concat(ds).reduce(function (acc, decoder) { return map2(Object.assign, acc, decoder.decode(json)); }, ok({})); + }); + }; + /** + * Escape hatch to bypass validation. Always succeeds and types the result as + * `any`. Useful for defining decoders incrementally, particularly for + * complex objects. + * + * Example: + * ``` + * interface User { + * name: string; + * complexUserData: ComplexType; + * } + * + * const userDecoder: Decoder = object({ + * name: string(), + * complexUserData: anyJson() + * }); + * ``` + */ + Decoder.anyJson = function () { return new Decoder(function (json) { return ok(json); }); }; + /** + * Decoder identity function which always succeeds and types the result as + * `unknown`. + */ + Decoder.unknownJson = function () { + return new Decoder(function (json) { return ok(json); }); + }; + /** + * Decoder for json objects where the keys are unknown strings, but the values + * should all be of the same type. + * + * Example: + * ``` + * dict(number()).run({chocolate: 12, vanilla: 10, mint: 37}); + * // => {ok: true, result: {chocolate: 12, vanilla: 10, mint: 37}} + * ``` + */ + Decoder.dict = function (decoder) { + return new Decoder(function (json) { + if (isJsonObject(json)) { + var obj = {}; + for (var key in json) { + if (json.hasOwnProperty(key)) { + var r = decoder.decode(json[key]); + if (r.ok === true) { + obj[key] = r.result; + } + else { + return err(prependAt("." + key, r.error)); + } + } + } + return ok(obj); + } + else { + return err({ message: expectedGot('an object', json) }); + } + }); + }; + /** + * Decoder for values that may be `undefined`. This is primarily helpful for + * decoding interfaces with optional fields. + * + * Example: + * ``` + * interface User { + * id: number; + * isOwner?: boolean; + * } + * + * const decoder: Decoder = object({ + * id: number(), + * isOwner: optional(boolean()) + * }); + * ``` + */ + Decoder.optional = function (decoder) { + return new Decoder(function (json) { return (json === undefined || json === null ? ok(undefined) : decoder.decode(json)); }); + }; + /** + * Decoder that attempts to run each decoder in `decoders` and either succeeds + * with the first successful decoder, or fails after all decoders have failed. + * + * Note that `oneOf` expects the decoders to all have the same return type, + * while `union` creates a decoder for the union type of all the input + * decoders. + * + * Examples: + * ``` + * oneOf(string(), number().map(String)) + * oneOf(constant('start'), constant('stop'), succeed('unknown')) + * ``` + */ + Decoder.oneOf = function () { + var decoders = []; + for (var _i = 0; _i < arguments.length; _i++) { + decoders[_i] = arguments[_i]; + } + return new Decoder(function (json) { + var errors = []; + for (var i = 0; i < decoders.length; i++) { + var r = decoders[i].decode(json); + if (r.ok === true) { + return r; + } + else { + errors[i] = r.error; + } + } + var errorsList = errors + .map(function (error) { return "at error" + (error.at || '') + ": " + error.message; }) + .join('", "'); + return err({ + message: "expected a value matching one of the decoders, got the errors [\"" + errorsList + "\"]" + }); + }); + }; + /** + * Decoder that always succeeds with either the decoded value, or a fallback + * default value. + */ + Decoder.withDefault = function (defaultValue, decoder) { + return new Decoder(function (json) { + return ok(withDefault(defaultValue, decoder.decode(json))); + }); + }; + /** + * Decoder that pulls a specific field out of a json structure, instead of + * decoding and returning the full structure. The `paths` array describes the + * object keys and array indices to traverse, so that values can be pulled out + * of a nested structure. + * + * Example: + * ``` + * const decoder = valueAt(['a', 'b', 0], string()); + * + * decoder.run({a: {b: ['surprise!']}}) + * // => {ok: true, result: 'surprise!'} + * + * decoder.run({a: {x: 'cats'}}) + * // => {ok: false, error: {... at: 'input.a.b[0]' message: 'path does not exist'}} + * ``` + * + * Note that the `decoder` is ran on the value found at the last key in the + * path, even if the last key is not found. This allows the `optional` + * decoder to succeed when appropriate. + * ``` + * const optionalDecoder = valueAt(['a', 'b', 'c'], optional(string())); + * + * optionalDecoder.run({a: {b: {c: 'surprise!'}}}) + * // => {ok: true, result: 'surprise!'} + * + * optionalDecoder.run({a: {b: 'cats'}}) + * // => {ok: false, error: {... at: 'input.a.b.c' message: 'expected an object, got "cats"'} + * + * optionalDecoder.run({a: {b: {z: 1}}}) + * // => {ok: true, result: undefined} + * ``` + */ + Decoder.valueAt = function (paths, decoder) { + return new Decoder(function (json) { + var jsonAtPath = json; + for (var i = 0; i < paths.length; i++) { + if (jsonAtPath === undefined) { + return err({ + at: printPath(paths.slice(0, i + 1)), + message: 'path does not exist' + }); + } + else if (typeof paths[i] === 'string' && !isJsonObject(jsonAtPath)) { + return err({ + at: printPath(paths.slice(0, i + 1)), + message: expectedGot('an object', jsonAtPath) + }); + } + else if (typeof paths[i] === 'number' && !isJsonArray(jsonAtPath)) { + return err({ + at: printPath(paths.slice(0, i + 1)), + message: expectedGot('an array', jsonAtPath) + }); + } + else { + jsonAtPath = jsonAtPath[paths[i]]; + } + } + return mapError(function (error) { + return jsonAtPath === undefined + ? { at: printPath(paths), message: 'path does not exist' } + : prependAt(printPath(paths), error); + }, decoder.decode(jsonAtPath)); + }); + }; + /** + * Decoder that ignores the input json and always succeeds with `fixedValue`. + */ + Decoder.succeed = function (fixedValue) { + return new Decoder(function (json) { return ok(fixedValue); }); + }; + /** + * Decoder that ignores the input json and always fails with `errorMessage`. + */ + Decoder.fail = function (errorMessage) { + return new Decoder(function (json) { return err({ message: errorMessage }); }); + }; + /** + * Decoder that allows for validating recursive data structures. Unlike with + * functions, decoders assigned to variables can't reference themselves + * before they are fully defined. We can avoid prematurely referencing the + * decoder by wrapping it in a function that won't be called until use, at + * which point the decoder has been defined. + * + * Example: + * ``` + * interface Comment { + * msg: string; + * replies: Comment[]; + * } + * + * const decoder: Decoder = object({ + * msg: string(), + * replies: lazy(() => array(decoder)) + * }); + * ``` + */ + Decoder.lazy = function (mkDecoder) { + return new Decoder(function (json) { return mkDecoder().decode(json); }); + }; + return Decoder; + }()); + + /* tslint:disable:variable-name */ + /** See `Decoder.string` */ + var string = Decoder.string; + /** See `Decoder.number` */ + var number = Decoder.number; + /** See `Decoder.boolean` */ + var boolean = Decoder.boolean; + /** See `Decoder.anyJson` */ + var anyJson = Decoder.anyJson; + /** See `Decoder.unknownJson` */ + Decoder.unknownJson; + /** See `Decoder.constant` */ + var constant = Decoder.constant; + /** See `Decoder.object` */ + var object = Decoder.object; + /** See `Decoder.array` */ + var array = Decoder.array; + /** See `Decoder.tuple` */ + Decoder.tuple; + /** See `Decoder.dict` */ + var dict = Decoder.dict; + /** See `Decoder.optional` */ + var optional = Decoder.optional; + /** See `Decoder.oneOf` */ + var oneOf = Decoder.oneOf; + /** See `Decoder.union` */ + Decoder.union; + /** See `Decoder.intersection` */ + Decoder.intersection; + /** See `Decoder.withDefault` */ + Decoder.withDefault; + /** See `Decoder.valueAt` */ + Decoder.valueAt; + /** See `Decoder.succeed` */ + Decoder.succeed; + /** See `Decoder.fail` */ + Decoder.fail; + /** See `Decoder.lazy` */ + Decoder.lazy; + + const nonEmptyStringDecoder = string().where((s) => s.length > 0, "Expected a non-empty string"); + const nonNegativeNumberDecoder = number().where((num) => num >= 0, "Expected a non-negative number"); + + const intentDefinitionDecoder = object({ + name: nonEmptyStringDecoder, + displayName: optional(string()), + contexts: optional(array(string())), + customConfig: optional(object()) + }); + const v2TypeDecoder = oneOf(constant("web"), constant("native"), constant("citrix"), constant("onlineNative"), constant("other")); + const v2DetailsDecoder = object({ + url: nonEmptyStringDecoder + }); + const v2IconDecoder = object({ + src: nonEmptyStringDecoder, + size: optional(nonEmptyStringDecoder), + type: optional(nonEmptyStringDecoder) + }); + const v2ScreenshotDecoder = object({ + src: nonEmptyStringDecoder, + size: optional(nonEmptyStringDecoder), + type: optional(nonEmptyStringDecoder), + label: optional(nonEmptyStringDecoder) + }); + const v2ListensForIntentDecoder = object({ + contexts: array(nonEmptyStringDecoder), + displayName: optional(nonEmptyStringDecoder), + resultType: optional(nonEmptyStringDecoder), + customConfig: optional(anyJson()) + }); + const v2IntentsDecoder = object({ + listensFor: optional(dict(v2ListensForIntentDecoder)), + raises: optional(dict(array(nonEmptyStringDecoder))) + }); + const v2UserChannelDecoder = object({ + broadcasts: optional(array(nonEmptyStringDecoder)), + listensFor: optional(array(nonEmptyStringDecoder)) + }); + const v2AppChannelDecoder = object({ + name: nonEmptyStringDecoder, + description: optional(nonEmptyStringDecoder), + broadcasts: optional(array(nonEmptyStringDecoder)), + listensFor: optional(array(nonEmptyStringDecoder)) + }); + const v2InteropDecoder = object({ + intents: optional(v2IntentsDecoder), + userChannels: optional(v2UserChannelDecoder), + appChannels: optional(array(v2AppChannelDecoder)) + }); + const glue42ApplicationDetailsDecoder = object({ + url: optional(nonEmptyStringDecoder), + top: optional(number()), + left: optional(number()), + width: optional(nonNegativeNumberDecoder), + height: optional(nonNegativeNumberDecoder) + }); + const glue42HostManifestsBrowserDecoder = object({ + name: optional(nonEmptyStringDecoder), + type: optional(nonEmptyStringDecoder.where((s) => s === "window", "Expected a value of window")), + title: optional(nonEmptyStringDecoder), + version: optional(nonEmptyStringDecoder), + customProperties: optional(anyJson()), + icon: optional(string()), + caption: optional(string()), + details: optional(glue42ApplicationDetailsDecoder), + intents: optional(array(intentDefinitionDecoder)), + hidden: optional(boolean()) + }); + const v1DefinitionDecoder = object({ + name: nonEmptyStringDecoder, + appId: nonEmptyStringDecoder, + title: optional(nonEmptyStringDecoder), + version: optional(nonEmptyStringDecoder), + manifest: nonEmptyStringDecoder, + manifestType: nonEmptyStringDecoder, + tooltip: optional(nonEmptyStringDecoder), + description: optional(nonEmptyStringDecoder), + contactEmail: optional(nonEmptyStringDecoder), + supportEmail: optional(nonEmptyStringDecoder), + publisher: optional(nonEmptyStringDecoder), + images: optional(array(object({ url: optional(nonEmptyStringDecoder) }))), + icons: optional(array(object({ icon: optional(nonEmptyStringDecoder) }))), + customConfig: anyJson(), + intents: optional(array(intentDefinitionDecoder)) + }); + const v2LocalizedDefinitionDecoder = object({ + appId: optional(nonEmptyStringDecoder), + name: optional(nonEmptyStringDecoder), + details: optional(v2DetailsDecoder), + version: optional(nonEmptyStringDecoder), + title: optional(nonEmptyStringDecoder), + tooltip: optional(nonEmptyStringDecoder), + lang: optional(nonEmptyStringDecoder), + description: optional(nonEmptyStringDecoder), + categories: optional(array(nonEmptyStringDecoder)), + icons: optional(array(v2IconDecoder)), + screenshots: optional(array(v2ScreenshotDecoder)), + contactEmail: optional(nonEmptyStringDecoder), + supportEmail: optional(nonEmptyStringDecoder), + moreInfo: optional(nonEmptyStringDecoder), + publisher: optional(nonEmptyStringDecoder), + customConfig: optional(array(anyJson())), + hostManifests: optional(anyJson()), + interop: optional(v2InteropDecoder) + }); + const v2DefinitionDecoder = object({ + appId: nonEmptyStringDecoder, + name: nonEmptyStringDecoder, + type: v2TypeDecoder, + details: v2DetailsDecoder, + version: optional(nonEmptyStringDecoder), + title: optional(nonEmptyStringDecoder), + tooltip: optional(nonEmptyStringDecoder), + lang: optional(nonEmptyStringDecoder), + description: optional(nonEmptyStringDecoder), + categories: optional(array(nonEmptyStringDecoder)), + icons: optional(array(v2IconDecoder)), + screenshots: optional(array(v2ScreenshotDecoder)), + contactEmail: optional(nonEmptyStringDecoder), + supportEmail: optional(nonEmptyStringDecoder), + moreInfo: optional(nonEmptyStringDecoder), + publisher: optional(nonEmptyStringDecoder), + customConfig: optional(array(anyJson())), + hostManifests: optional(anyJson()), + interop: optional(v2InteropDecoder), + localizedVersions: optional(dict(v2LocalizedDefinitionDecoder)) + }); + const allDefinitionsDecoder = oneOf(v1DefinitionDecoder, v2DefinitionDecoder); + + const parseDecoderErrorToStringMessage = (error) => { + return `${error.kind} at ${error.at}: ${JSON.stringify(error.input)}. Reason - ${error.message}`; + }; + + class FDC3Service { + fdc3ToDesktopDefinitionType = { + web: "window", + native: "exe", + citrix: "citrix", + onlineNative: "clickonce", + other: "window" + }; + toApi() { + return { + isFdc3Definition: this.isFdc3Definition.bind(this), + parseToBrowserBaseAppData: this.parseToBrowserBaseAppData.bind(this), + parseToDesktopAppConfig: this.parseToDesktopAppConfig.bind(this) + }; + } + isFdc3Definition(definition) { + const decodeRes = allDefinitionsDecoder.run(definition); + if (!decodeRes.ok) { + return { isFdc3: false, reason: parseDecoderErrorToStringMessage(decodeRes.error) }; + } + if (definition.appId && definition.details) { + return { isFdc3: true, version: "2.0" }; + } + if (definition.manifest) { + return { isFdc3: true, version: "1.2" }; + } + return { isFdc3: false, reason: "The passed definition is not FDC3" }; + } + parseToBrowserBaseAppData(definition) { + const { isFdc3, version } = this.isFdc3Definition(definition); + if (!isFdc3) { + throw new Error("The passed definition is not FDC3"); + } + const decodeRes = allDefinitionsDecoder.run(definition); + if (!decodeRes.ok) { + throw new Error(`Invalid FDC3 ${version} definition. Error: ${parseDecoderErrorToStringMessage(decodeRes.error)}`); + } + const userProperties = this.getUserPropertiesFromDefinition(definition, version); + const createOptions = { url: this.getUrl(definition, version) }; + const baseApplicationData = { + name: definition.appId, + type: "window", + createOptions, + userProperties: { + ...userProperties, + intents: version === "1.2" + ? userProperties.intents + : this.getIntentsFromV2AppDefinition(definition), + details: createOptions + }, + title: definition.title, + version: definition.version, + icon: this.getIconFromDefinition(definition, version), + caption: definition.description, + fdc3: version === "2.0" ? { ...definition, definitionVersion: "2.0" } : undefined, + }; + const ioConnectDefinition = definition.hostManifests?.ioConnect || definition.hostManifests?.["Glue42"]; + if (!ioConnectDefinition) { + return baseApplicationData; + } + const ioDefinitionDecodeRes = glue42HostManifestsBrowserDecoder.run(ioConnectDefinition); + if (!ioDefinitionDecodeRes.ok) { + throw new Error(`Invalid FDC3 ${version} definition. Error: ${parseDecoderErrorToStringMessage(ioDefinitionDecodeRes.error)}`); + } + if (!Object.keys(ioDefinitionDecodeRes.result).length) { + return baseApplicationData; + } + return this.mergeBaseAppDataWithGlueManifest(baseApplicationData, ioDefinitionDecodeRes.result); + } + parseToDesktopAppConfig(definition) { + const { isFdc3, version } = this.isFdc3Definition(definition); + if (!isFdc3) { + throw new Error("The passed definition is not FDC3"); + } + const decodeRes = allDefinitionsDecoder.run(definition); + if (!decodeRes.ok) { + throw new Error(`Invalid FDC3 ${version} definition. Error: ${parseDecoderErrorToStringMessage(decodeRes.error)}`); + } + if (version === "1.2") { + const fdc3v1Definition = definition; + return { + name: fdc3v1Definition.appId, + type: "window", + details: { + url: this.getUrl(definition, version) + }, + version: fdc3v1Definition.version, + title: fdc3v1Definition.title, + tooltip: fdc3v1Definition.tooltip, + caption: fdc3v1Definition.description, + icon: fdc3v1Definition.icons?.[0].icon, + intents: fdc3v1Definition.intents, + customProperties: { + manifestType: fdc3v1Definition.manifestType, + images: fdc3v1Definition.images, + contactEmail: fdc3v1Definition.contactEmail, + supportEmail: fdc3v1Definition.supportEmail, + publisher: fdc3v1Definition.publisher, + icons: fdc3v1Definition.icons, + customConfig: fdc3v1Definition.customConfig + } + }; + } + const fdc3v2Definition = definition; + const desktopDefinition = { + name: fdc3v2Definition.appId, + type: this.fdc3ToDesktopDefinitionType[fdc3v2Definition.type], + details: fdc3v2Definition.details, + version: fdc3v2Definition.version, + title: fdc3v2Definition.title, + tooltip: fdc3v2Definition.tooltip, + caption: fdc3v2Definition.description, + icon: this.getIconFromDefinition(fdc3v2Definition, "2.0"), + intents: this.getIntentsFromV2AppDefinition(fdc3v2Definition), + fdc3: { ...fdc3v2Definition, definitionVersion: "2.0" } + }; + const ioConnectDefinition = definition.hostManifests?.ioConnect || definition.hostManifests?.["Glue42"]; + if (!ioConnectDefinition) { + return desktopDefinition; + } + if (typeof ioConnectDefinition !== "object" || Array.isArray(ioConnectDefinition)) { + throw new Error(`Invalid '${definition.hostManifests.ioConnect ? "hostManifests.ioConnect" : "hostManifests['Glue42']"}' key`); + } + return this.mergeDesktopConfigWithGlueManifest(desktopDefinition, ioConnectDefinition); + } + getUserPropertiesFromDefinition(definition, version) { + if (version === "1.2") { + return Object.fromEntries(Object.entries(definition).filter(([key]) => !connectBrowserAppProps.includes(key))); + } + return Object.fromEntries(Object.entries(definition).filter(([key]) => !connectBrowserAppProps.includes(key) && !fdc3v2AppProps.includes(key))); + } + getUrl(definition, version) { + let url; + if (version === "1.2") { + const parsedManifest = JSON.parse(definition.manifest); + url = parsedManifest.details?.url || parsedManifest.url; + } + else { + url = definition.details?.url; + } + if (!url || typeof url !== "string") { + throw new Error(`Invalid FDC3 ${version} definition. Provide valid 'url' under '${version === "1.2" ? "manifest" : "details"}' key`); + } + return url; + } + getIntentsFromV2AppDefinition(definition) { + const fdc3Intents = definition.interop?.intents?.listensFor; + if (!fdc3Intents) { + return; + } + const intents = Object.entries(fdc3Intents).map((fdc3Intent) => { + const [intentName, intentData] = fdc3Intent; + return { + name: intentName, + ...intentData + }; + }); + return intents; + } + getIconFromDefinition(definition, version) { + if (version === "1.2") { + return definition.icons?.find((iconDef) => iconDef.icon)?.icon || undefined; + } + return definition.icons?.find((iconDef) => iconDef.src)?.src || undefined; + } + mergeBaseAppDataWithGlueManifest(baseAppData, hostManifestDefinition) { + let baseApplicationDefinition = baseAppData; + if (hostManifestDefinition.details) { + const details = { ...baseAppData.createOptions, ...hostManifestDefinition.details }; + baseApplicationDefinition.createOptions = details; + baseApplicationDefinition.userProperties.details = details; + } + if (Array.isArray(hostManifestDefinition.intents)) { + baseApplicationDefinition.userProperties.intents = (baseApplicationDefinition.userProperties.intents || []).concat(hostManifestDefinition.intents); + } + baseApplicationDefinition = { ...baseApplicationDefinition, ...hostManifestDefinition }; + delete baseApplicationDefinition.details; + delete baseApplicationDefinition.intents; + return baseApplicationDefinition; + } + mergeDesktopConfigWithGlueManifest(config, desktopDefinition) { + const appConfig = Object.assign({}, config, desktopDefinition, { details: { ...config.details, ...desktopDefinition.details } }); + if (Array.isArray(desktopDefinition.intents)) { + appConfig.intents = (config.intents || []).concat(desktopDefinition.intents); + } + return appConfig; + } + } + + const decoders$1 = { + common: { + nonEmptyStringDecoder, + nonNegativeNumberDecoder + }, + fdc3: { + allDefinitionsDecoder, + v1DefinitionDecoder, + v2DefinitionDecoder + } + }; + + var INTENTS_ERRORS; + (function (INTENTS_ERRORS) { + INTENTS_ERRORS["USER_CANCELLED"] = "User Closed Intents Resolver UI without choosing a handler"; + INTENTS_ERRORS["CALLER_NOT_DEFINED"] = "Caller Id is not defined"; + INTENTS_ERRORS["TIMEOUT_HIT"] = "Timeout hit"; + INTENTS_ERRORS["INTENT_NOT_FOUND"] = "Cannot find Intent"; + INTENTS_ERRORS["HANDLER_NOT_FOUND"] = "Cannot find Intent Handler"; + INTENTS_ERRORS["TARGET_INSTANCE_UNAVAILABLE"] = "Cannot start Target Instance"; + INTENTS_ERRORS["INTENT_DELIVERY_FAILED"] = "Target Instance did not add a listener"; + INTENTS_ERRORS["RESOLVER_UNAVAILABLE"] = "Intents Resolver UI unavailable"; + INTENTS_ERRORS["RESOLVER_TIMEOUT"] = "User did not choose a handler"; + INTENTS_ERRORS["INVALID_RESOLVER_RESPONSE"] = "Intents Resolver UI returned invalid response"; + INTENTS_ERRORS["INTENT_HANDLER_REJECTION"] = "Intent Handler function processing the raised intent threw an error or rejected the promise it returned"; + })(INTENTS_ERRORS || (INTENTS_ERRORS = {})); + + class IoC { + _fdc3; + _decoders = decoders$1; + _errors = { + intents: INTENTS_ERRORS + }; + get fdc3() { + if (!this._fdc3) { + this._fdc3 = new FDC3Service().toApi(); + } + return this._fdc3; + } + get decoders() { + return this._decoders; + } + get errors() { + return this._errors; + } + } + + const ioc = new IoC(); + ioc.fdc3; + ioc.decoders; + const errors = ioc.errors; + + const GLUE42_FDC3_INTENTS_METHOD_PREFIX = "Tick42.FDC3.Intents."; + const INTENTS_RESOLVER_INTEROP_PREFIX = "T42.Intents.Resolver.Control"; + const INTENTS_RESOLVER_WIDTH = 400; + const INTENTS_RESOLVER_HEIGHT = 440; + const DEFAULT_RESOLVER_RESPONSE_TIMEOUT = 60 * 1000; + const INTENT_HANDLER_DEFAULT_PROPS = ["applicationName", "type"]; + const INTENTS_RESOLVER_APP_NAME = "intentsResolver"; + const MAX_SET_TIMEOUT_DELAY = 2147483647; + const DEFAULT_METHOD_RESPONSE_TIMEOUT_MS = 60 * 1000; + const DEFAULT_RAISE_TIMEOUT_MS = 90 * 1000; + const DEFAULT_PICK_HANDLER_BY_TIMEOUT_MS = 90 * 1000; + const ERRORS = errors.intents; + + const PromisePlus = (executor, timeoutMilliseconds, timeoutMessage) => { + return new Promise((resolve, reject) => { + const timeout = setTimeout(() => { + const message = timeoutMessage || `Promise timeout hit: ${timeoutMilliseconds}`; + reject(message); + }, timeoutMilliseconds); + const providedPromise = new Promise(executor); + providedPromise + .then((result) => { + clearTimeout(timeout); + resolve(result); + }) + .catch((error) => { + clearTimeout(timeout); + reject(error); + }); + }); + }; + const PromiseWrap = (promise, timeoutMilliseconds, timeoutMessage) => { + return new Promise((resolve, reject) => { + let promiseActive = true; + const timeout = setTimeout(() => { + if (!promiseActive) { + return; + } + promiseActive = false; + const message = timeoutMessage || `Promise timeout hit: ${timeoutMilliseconds}`; + reject(message); + }, timeoutMilliseconds); + promise() + .then((result) => { + if (!promiseActive) { + return; + } + promiseActive = false; + clearTimeout(timeout); + resolve(result); + }) + .catch((error) => { + if (!promiseActive) { + return; + } + promiseActive = false; + clearTimeout(timeout); + reject(error); + }); + }); + }; + + const validateIntentHandlerAsResponse = (handler) => { + if (typeof handler !== "object") { + return { isValid: false, error: `Response object has invalid 'handler' key. Expected an object, got ${typeof handler}` }; + } + const compulsoryKeysExist = INTENT_HANDLER_DEFAULT_PROPS.filter((key) => !(key in handler)); + if (compulsoryKeysExist.length) { + return { isValid: false, error: `Handler in Response object does not provide compulsory keys: ${compulsoryKeysExist.join(", ")}` }; + } + return { isValid: true, ok: handler }; + }; + const validateIntentRequestTarget = (target) => { + if (!target) { + return; + } + if (typeof target !== "string" && typeof target !== "object") { + throw new Error(`Please provide the intent target as one of the valid values: "reuse", "startNew", { app: string }, { instance: string } `); + } + }; + const validateIntentRequestContext = (context) => { + if (!context) { + return; + } + if (typeof context !== "object") { + throw new Error(`Please provide the intent context as an object`); + } + if (context.type && typeof context.type !== "string") { + throw new Error(`Please provide the intent context as an object with 'type' property as string`); + } + if (context.data && typeof context.data !== "object") { + throw new Error(`Please provide the intent context as an object with 'data' property as object`); + } + }; + const validateIntentRequestHandler = (handler) => { + if (!handler.applicationName) { + throw new Error(`Please provide applicationName for handler ${JSON.stringify(handler)}`); + } + if (!handler.type) { + throw new Error(`Please provide type for handler ${JSON.stringify(handler)}`); + } + if (handler.type === "instance" && !handler.instanceId) { + throw new Error(`Please provide instanceId for handler ${JSON.stringify(handler)}`); + } + }; + const validateIntentRequestTimeout = (timeout) => { + if (!timeout) { + return; + } + if (typeof timeout !== "number") { + throw new Error(`Please provide the timeout as a number`); + } + if (timeout <= 0) { + throw new Error(`Please provide the timeout as a positive number`); + } + }; + const validateWaitUserResponseIndefinitely = (waitUserResponseIndefinitely) => { + if (!waitUserResponseIndefinitely) { + return; + } + if (typeof waitUserResponseIndefinitely !== "boolean") { + throw new Error("Please provide waitUserResponseIndefinitely as a boolean"); + } + }; + const validateHandlerFilter = (handlerFilter) => { + if (!handlerFilter) { + throw new Error(`Provide 'handlerFilter' with at least one filter criteria of the following: 'intent' | 'contextTypes' | 'resultType' | 'applicationNames'`); + } + const { title, openResolver, timeout, intent, contextTypes, resultType, applicationNames } = handlerFilter; + if (typeof title !== "undefined" && (typeof title !== "string" || !title.length)) { + throw new Error(`Provide 'title' as a non empty string`); + } + if (typeof openResolver !== "undefined" && typeof openResolver !== "boolean") { + throw new Error(`Provide 'openResolver' prop as a boolean`); + } + if (typeof timeout !== "undefined" && (typeof timeout !== "number" || timeout <= 0)) { + throw new Error(`Provide 'timeout' prop as a positive number`); + } + if (typeof intent !== "undefined" && (typeof intent !== "string" || !intent.length)) { + throw new Error(`Provide 'intent' as a non empty string`); + } + if (typeof contextTypes !== "undefined" && (!Array.isArray(contextTypes) || contextTypes.some(ctx => typeof ctx !== "string"))) { + throw new Error(`Provide 'contextTypes' as an array of non empty strings`); + } + if (typeof resultType !== "undefined" && (typeof resultType !== "string" || !resultType.length)) { + throw new Error(`Provide 'resultType' as a non empty string`); + } + if (typeof applicationNames !== "undefined" && (!Array.isArray(applicationNames) || applicationNames.some(appName => typeof appName !== "string"))) { + throw new Error(`Provide 'applicationNames' as an array of non empty strings`); + } + const errorMsg = "Provide at least one filter criteria of the following: 'intent' | 'contextTypes' | 'resultType' | 'applicationNames'"; + if (!Object.keys(handlerFilter).length) { + throw new Error(errorMsg); + } + if (!intent && !resultType && (!contextTypes || !contextTypes.length) && (!applicationNames || !applicationNames.length)) { + throw new Error(errorMsg); + } + }; + const validateResolverResponse = (responseObj) => { + var _a, _b; + if (typeof responseObj.intent !== "string") { + return { isValid: false, error: `Response object has invalid 'intent' key. Expected a string, got ${typeof responseObj.intent}` }; + } + if (((_a = responseObj.userSettings) === null || _a === void 0 ? void 0 : _a.preserveChoice) && typeof ((_b = responseObj.userSettings) === null || _b === void 0 ? void 0 : _b.preserveChoice) !== "boolean") { + return { isValid: false, error: `Response object has invalid 'userSettings.preserveChoice' key. Expected a boolean, got ${typeof responseObj.userSettings.preserveChoice}` }; + } + const { isValid, error } = validateIntentHandlerAsResponse(responseObj.handler); + return isValid + ? { isValid: true, ok: responseObj } + : { isValid, error }; + }; + const validateIntentRequest = (request) => { + validateIntentRequestContext(request.context); + validateIntentRequestTarget(request.target); + validateIntentRequestTimeout(request.timeout); + validateWaitUserResponseIndefinitely(request.waitUserResponseIndefinitely); + if (typeof request.clearSavedHandler !== "undefined" && typeof request.clearSavedHandler !== "boolean") { + throw new Error("Please provide 'clearSavedHandler' as a boolean"); + } + if (request.handlers) { + request.handlers.forEach((handler) => validateIntentRequestHandler(handler)); + } + }; + const validateIntentHandler = (handler) => { + if (typeof handler !== "object") { + throw new Error("IntentHandler must be an object"); + } + if (typeof handler.applicationName !== "string" || !handler.applicationName.length) { + throw new Error(`Please provide 'applicationName' as a non-empty string`); + } + if (typeof handler.type !== "string" || !["app", "instance"].includes(handler.type)) { + throw new Error(`Invalid 'type' property. Expected 'app' | 'instance' got ${handler.type}`); + } + if (typeof handler.applicationTitle !== "undefined" && typeof handler.applicationTitle !== "string") { + throw new Error(`Provide 'applicationTitle' as a string`); + } + if (typeof handler.applicationDescription !== "undefined" && typeof handler.applicationDescription !== "string") { + throw new Error(`Provide 'applicationDescription' as a string`); + } + if (typeof handler.applicationIcon !== "undefined" && typeof handler.applicationIcon !== "string") { + throw new Error(`Provide 'applicationIcon' as a string`); + } + if (typeof handler.displayName !== "undefined" && typeof handler.displayName !== "string") { + throw new Error(`Provide 'displayName' as a string`); + } + if (typeof handler.contextTypes !== "undefined" && (!Array.isArray(handler.contextTypes) || handler.contextTypes.some(ctx => typeof ctx !== "string"))) { + throw new Error(`Provide 'contextTypes' as an array of non empty strings`); + } + if (typeof handler.instanceId !== "undefined" && typeof handler.instanceId !== "string") { + throw new Error(`Provide 'instanceId' as a string`); + } + if (typeof handler.instanceTitle !== "undefined" && typeof handler.instanceTitle !== "string") { + throw new Error(`Provide 'instanceTitle' as a string`); + } + if (typeof handler.resultType !== "undefined" && typeof handler.resultType !== "string") { + throw new Error(`Provide 'resultType' as a string`); + } + }; + const clearNullUndefined = (obj) => { + Object.keys(obj).forEach(key => { + if (obj[key] === null || obj[key] === undefined) { + delete obj[key]; + } + }); + }; + + class Intents { + constructor(interop, windows, logger, options, prefsController, appManager) { + this.interop = interop; + this.windows = windows; + this.logger = logger; + this.prefsController = prefsController; + this.appManager = appManager; + this.myIntents = new Set(); + this.intentsResolverResponsePromises = {}; + this.useIntentsResolverUI = true; + this.unregisterIntentPromises = []; + this.addedHandlerInfoPerApp = {}; + this.checkIfIntentsResolverIsEnabled(options, appManager); + } + async find(intentFilter) { + await Promise.all(this.unregisterIntentPromises); + let intents = await this.all(); + if (typeof intentFilter === "undefined") { + return intents; + } + if (typeof intentFilter === "string") { + return intents.filter((intent) => intent.name === intentFilter); + } + if (typeof intentFilter !== "object") { + throw new Error("Please provide the intentFilter as a string or an object!"); + } + if (intentFilter.contextType) { + const ctToLower = intentFilter.contextType.toLowerCase(); + intents = intents.filter((intent) => intent.handlers.some((handler) => { var _a; return (_a = handler.contextTypes) === null || _a === void 0 ? void 0 : _a.some((ct) => ct.toLowerCase() === ctToLower); })); + } + if (intentFilter.resultType) { + const resultTypeToLower = intentFilter.resultType.toLowerCase(); + intents = intents.filter((intent) => intent.handlers.some((handler) => { var _a; return ((_a = handler.resultType) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === resultTypeToLower; })); + } + if (intentFilter.name) { + intents = intents.filter((intent) => intent.name === intentFilter.name); + } + return intents; + } + async raise(intentRequest) { + if ((typeof intentRequest !== "string" && typeof intentRequest !== "object") || (typeof intentRequest === "object" && typeof intentRequest.intent !== "string")) { + throw new Error("Please provide the intent as a string or an object with an intent property!"); + } + if (typeof intentRequest === "string") { + intentRequest = { intent: intentRequest }; + } + validateIntentRequest(intentRequest); + await Promise.all(this.unregisterIntentPromises); + if (intentRequest.clearSavedHandler) { + this.logger.trace(`User removes saved handler for intent ${intentRequest.intent}`); + await this.removeRememberedHandler(intentRequest.intent); + } + const resolverInstance = {}; + const timeout = intentRequest.waitUserResponseIndefinitely ? MAX_SET_TIMEOUT_DELAY : intentRequest.timeout || DEFAULT_RAISE_TIMEOUT_MS; + const resultFromRememberedHandler = await this.checkHandleRaiseWithRememberedHandler(intentRequest, resolverInstance, timeout); + if (resultFromRememberedHandler) { + return resultFromRememberedHandler; + } + const coreRaiseIntentFn = this.coreRaiseIntent.bind(this, { request: intentRequest, resolverInstance, timeout }); + if (intentRequest.waitUserResponseIndefinitely) { + return coreRaiseIntentFn(); + } + const resultPromise = PromiseWrap(coreRaiseIntentFn, timeout, `${ERRORS.TIMEOUT_HIT} hit for intent request ${JSON.stringify(intentRequest)}`); + resultPromise.catch(() => this.handleRaiseOnError(resolverInstance.instanceId)); + return resultPromise; + } + async all() { + await Promise.all(this.unregisterIntentPromises); + let apps; + try { + const result = await this.interop.invoke("T42.ACS.GetApplications", { withIntentsInfo: true }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + apps = result.returned.applications; + } + catch (e) { + this.logger.error(`Failed to get the applications!`, e); + return []; + } + const intents = {}; + const appsWithIntents = apps.filter((app) => app.intents && app.intents.length > 0); + for (const app of appsWithIntents) { + for (const intentDef of app.intents) { + let intent = intents[intentDef.name]; + if (!intent) { + intent = { + name: intentDef.name, + handlers: [], + }; + intents[intentDef.name] = intent; + } + const handler = { + applicationName: app.name, + applicationTitle: app.title || "", + applicationDescription: app.caption, + displayName: intentDef.displayName, + contextTypes: intentDef.contexts, + applicationIcon: app.icon, + type: "app", + resultType: intentDef.resultType + }; + intent.handlers.push(handler); + } + } + const servers = this.interop.servers(); + const serverWindowIds = servers.map((server) => server.windowId).filter((serverWindowId) => typeof serverWindowId !== "undefined"); + const T42WndGetInfo = "T42.Wnd.GetInfo"; + const isT42WndGetInfoMethodRegistered = this.interop.methods().some((method) => method.name === T42WndGetInfo); + let windowsInfos; + if (isT42WndGetInfoMethodRegistered) { + try { + const result = await this.interop.invoke(T42WndGetInfo, { ids: serverWindowIds }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + windowsInfos = result.returned.windows; + } + catch (e) { + } + } + for (const server of servers) { + await Promise.all(server.getMethods() + .filter((method) => method.name.startsWith(GLUE42_FDC3_INTENTS_METHOD_PREFIX)) + .map(async (method) => { + const intentName = method.name.replace(GLUE42_FDC3_INTENTS_METHOD_PREFIX, ""); + let intent = intents[intentName]; + if (!intent) { + intent = { + name: intentName, + handlers: [], + }; + intents[intentName] = intent; + } + const title = await this.windowsIdToTitle(server.windowId, windowsInfos); + const handler = this.constructIntentHandler({ method, apps, server, intentName, title }); + intent.handlers.push(handler); + })); + } + return Object.values(intents); + } + addIntentListener(intent, handler) { + if ((typeof intent !== "string" && typeof intent !== "object") || (typeof intent === "object" && typeof intent.intent !== "string")) { + throw new Error("Please provide the intent as a string or an object with an intent property!"); + } + if (typeof handler !== "function") { + throw new Error("Please provide the handler as a function!"); + } + const intentName = typeof intent === "string" ? intent : intent.intent; + const methodName = `${GLUE42_FDC3_INTENTS_METHOD_PREFIX}${intentName}`; + let intentFlag = {}; + let registerPromise; + const alreadyRegistered = this.myIntents.has(intentName); + if (alreadyRegistered) { + throw new Error(`Intent listener for intent ${intentName} already registered!`); + } + this.myIntents.add(intentName); + const result = { + unsubscribe: () => { + this.myIntents.delete(intentName); + registerPromise + .then(() => this.interop.unregister(methodName)) + .catch((err) => this.logger.trace(`Unregistration of a method with name ${methodName} failed with reason: ${JSON.stringify(err)}`)); + } + }; + if (typeof intent === "object") { + const { intent: removed, ...rest } = intent; + intentFlag = rest; + } + registerPromise = this.interop.register({ name: methodName, flags: { intent: intentFlag } }, (args) => { + if (this.myIntents.has(intentName)) { + return handler(args); + } + }); + registerPromise.catch((err) => { + this.myIntents.delete(intentName); + this.logger.warn(`Registration of a method with name ${methodName} failed with reason: ${JSON.stringify(err)}`); + }); + return result; + } + async register(intent, handler) { + if ((typeof intent !== "string" && typeof intent !== "object") || (typeof intent === "object" && typeof intent.intent !== "string")) { + throw new Error("Please provide the intent as a string or an object with an intent property!"); + } + if (typeof handler !== "function") { + throw new Error("Please provide the handler as a function!"); + } + await Promise.all(this.unregisterIntentPromises); + const intentName = typeof intent === "string" ? intent : intent.intent; + const methodName = this.buildInteropMethodName(intentName); + let intentFlag = {}; + const alreadyRegistered = this.myIntents.has(intentName); + if (alreadyRegistered) { + throw new Error(`Intent listener for intent ${intentName} already registered!`); + } + this.myIntents.add(intentName); + if (typeof intent === "object") { + const { intent: removed, ...rest } = intent; + intentFlag = rest; + } + try { + await this.interop.register({ name: methodName, flags: { intent: intentFlag } }, (args, caller) => { + if (this.myIntents.has(intentName)) { + return handler(args, caller); + } + }); + } + catch (err) { + this.myIntents.delete(intentName); + throw new Error(`Registration of a method with name ${methodName} failed with reason: ${JSON.stringify(err)}`); + } + return { + unsubscribe: () => this.unsubscribeIntent(intentName) + }; + } + async filterHandlers(handlerFilter) { + var _a, _b; + validateHandlerFilter(handlerFilter); + if (handlerFilter.openResolver && !this.useIntentsResolverUI) { + throw new Error("Cannot resolve 'filterHandlers' request using Intents Resolver UI because it's globally disabled"); + } + (_a = this.logger) === null || _a === void 0 ? void 0 : _a.trace(`Received 'filterHandlers' command with request: ${JSON.stringify(handlerFilter)}`); + const filteredHandlers = this.filterHandlersBy(await this.all(), handlerFilter); + if (!filteredHandlers || !filteredHandlers.length) { + return { handlers: [] }; + } + const { open, reason } = this.checkIfResolverShouldBeOpenedForFilterHandlers(filteredHandlers, handlerFilter); + if (!open) { + (_b = this.logger) === null || _b === void 0 ? void 0 : _b.trace(`Intent Resolver UI won't be used. Reason: ${reason}`); + return { handlers: filteredHandlers }; + } + const resolverInstance = { instanceId: undefined }; + const timeout = handlerFilter.timeout || DEFAULT_PICK_HANDLER_BY_TIMEOUT_MS; + const handler = await PromiseWrap(() => this.startResolverApp({ request: handlerFilter, resolverInstance, method: 'filterHandlers' }), timeout, `Timeout of ${timeout}ms hit for 'filterHandlers' request with filter: ${JSON.stringify(handlerFilter)}`); + return { handlers: [handler] }; + } + async getIntents(handler) { + var _a; + this.logger.trace(`Received 'getIntents' command with handler ${JSON.stringify(handler)}`); + validateIntentHandler(handler); + const intents = await this.all(); + clearNullUndefined(handler); + (_a = this.logger) === null || _a === void 0 ? void 0 : _a.trace(`Extracting valid intents for the passed handler`); + const intentsWithInfo = this.extractIntentsWithInfoByHandler(intents, handler); + this.logger.trace(`Returning intents for handler ${JSON.stringify(handler)}`); + return { intents: intentsWithInfo }; + } + async clearSavedHandlers() { + this.logger.trace("Removing all saved handlers from prefs storage for current app"); + await this.prefsController.update({ intents: undefined }); + } + onHandlerAdded(callback) { + var _a; + const unAppAdded = (_a = this.appManager) === null || _a === void 0 ? void 0 : _a.onAppAdded(async (app) => { + var _a; + const appName = app.name; + const appDef = await app.getConfiguration(); + const isIntentHandler = (_a = appDef === null || appDef === void 0 ? void 0 : appDef.intents) === null || _a === void 0 ? void 0 : _a.length; + if (!isIntentHandler) { + return; + } + appDef.intents.forEach((intent) => { + const handler = this.constructIntentHandlerFromApp(appDef, intent); + if (!this.addedHandlerInfoPerApp[appName]) { + this.addedHandlerInfoPerApp[appName] = []; + } + const appHandlers = this.addedHandlerInfoPerApp[appName]; + appHandlers.push({ handler, name: intent.name }); + callback(handler, intent.name); + }); + }); + const unServerMethodAdded = this.interop.serverMethodAdded(({ method, server }) => { + if (!method.name.startsWith(GLUE42_FDC3_INTENTS_METHOD_PREFIX)) { + return; + } + const intentName = method.name.replace(GLUE42_FDC3_INTENTS_METHOD_PREFIX, ""); + const intentsInfo = this.constructIntentHandler({ method, apps: [], server, intentName, title: "" }); + callback(intentsInfo, intentName); + }); + return () => { + if (typeof unServerMethodAdded === "function") { + unServerMethodAdded(); + } + if (typeof unAppAdded === "function") { + unAppAdded(); + } + }; + } + onHandlerRemoved(callback) { + var _a; + const unAppRemoved = (_a = this.appManager) === null || _a === void 0 ? void 0 : _a.onAppRemoved(async (app) => { + const appName = app.name; + const handlers = this.addedHandlerInfoPerApp[appName]; + const isIntentHandler = handlers === null || handlers === void 0 ? void 0 : handlers.length; + if (!isIntentHandler) { + return; + } + delete this.addedHandlerInfoPerApp[appName]; + handlers.forEach((addedHandlerInfo) => { + callback(addedHandlerInfo.handler, addedHandlerInfo.name); + }); + }); + const unServerMethodAdded = this.interop.serverMethodRemoved(({ method, server }) => { + if (!method.name.startsWith(GLUE42_FDC3_INTENTS_METHOD_PREFIX)) { + return; + } + const intentName = method.name.replace(GLUE42_FDC3_INTENTS_METHOD_PREFIX, ""); + const intentsInfo = this.constructIntentHandler({ method, apps: [], server, intentName, title: "" }); + callback(intentsInfo, intentName); + }); + return () => { + if (typeof unServerMethodAdded === "function") { + unServerMethodAdded(); + } + if (typeof unAppRemoved === "function") { + unAppRemoved(); + } + }; + } + toAPI() { + return { + all: this.all.bind(this), + find: this.find.bind(this), + raise: this.raise.bind(this), + addIntentListener: this.addIntentListener.bind(this), + register: this.register.bind(this), + filterHandlers: this.filterHandlers.bind(this), + getIntents: this.getIntents.bind(this), + clearSavedHandlers: this.clearSavedHandlers.bind(this), + onHandlerAdded: this.onHandlerAdded.bind(this), + onHandlerRemoved: this.onHandlerRemoved.bind(this) + }; + } + filterHandlersBy(intents, filter) { + const filteredIntentsWithHandlers = intents.filter((intent) => { + if (filter.intent && filter.intent !== intent.name) { + return; + } + if (filter.resultType) { + const filteredHandlers = intent.handlers.filter((handler) => handler.resultType && handler.resultType === filter.resultType); + if (!filteredHandlers.length) + return; + intent.handlers = filteredHandlers; + } + if (filter.contextTypes) { + const filteredHandlers = intent.handlers.filter((handler) => { var _a; return (_a = filter.contextTypes) === null || _a === void 0 ? void 0 : _a.every((contextType) => { var _a; return (_a = handler.contextTypes) === null || _a === void 0 ? void 0 : _a.includes(contextType); }); }); + if (!filteredHandlers.length) + return; + intent.handlers = filteredHandlers; + } + if (filter.applicationNames) { + const filteredHandlers = intent.handlers.filter((handler) => { var _a; return (_a = filter.applicationNames) === null || _a === void 0 ? void 0 : _a.includes(handler.applicationName); }); + if (!filteredHandlers.length) + return; + intent.handlers = filteredHandlers; + } + return intent; + }); + return filteredIntentsWithHandlers.map((intent) => intent.handlers).flat(1); + } + async coreRaiseIntent({ request, resolverInstance, timeout }) { + var _a, _b; + const intentDef = await this.get(request.intent); + if (typeof intentDef === "undefined") { + throw new Error(`${ERRORS.INTENT_NOT_FOUND} with name ${request.intent}`); + } + const { open, reason } = await this.checkIfResolverShouldBeOpenedForRaise(intentDef, request); + if (!open) { + this.logger.trace(`Intent Resolver UI won't be used. Reason: ${reason}`); + return request.waitUserResponseIndefinitely + ? PromiseWrap(() => this.raiseIntent(request, timeout), timeout, `${ERRORS.TIMEOUT_HIT} - waited ${timeout}ms for 'raise' to resolve`) + : this.raiseIntent(request, timeout); + } + const resolverHandler = await this.startResolverApp({ request, method: "raise", resolverInstance }); + (_a = this.logger) === null || _a === void 0 ? void 0 : _a.trace(`Raising intent to target handler: ${JSON.stringify(resolverHandler)} with timeout of ${timeout}`); + if (request.waitUserResponseIndefinitely) { + return PromiseWrap(() => this.raiseIntentToTargetHandler(request, resolverHandler, timeout), timeout, `${ERRORS.TIMEOUT_HIT} - waited ${timeout}ms for 'raise' to resolve`); + } + const result = await this.raiseIntentToTargetHandler(request, resolverHandler, timeout); + (_b = this.logger) === null || _b === void 0 ? void 0 : _b.trace(`Result from raise() method for intent ${JSON.stringify(request.intent)}: ${JSON.stringify(result)}`); + return result; + } + async get(intent) { + return (await this.all()).find((registeredIntent) => registeredIntent.name === intent); + } + async raiseIntent(intentRequest, timeout) { + const intentName = intentRequest.intent; + const intentDef = await this.get(intentName); + if (typeof intentDef === "undefined") { + throw new Error(`${ERRORS.INTENT_NOT_FOUND} with name ${intentRequest.intent}`); + } + const firstFoundAppHandler = intentRequest.handlers ? this.findHandlerByFilter(intentRequest.handlers, { type: "app" }) : this.findHandlerByFilter(intentDef.handlers, { type: "app" }); + const firstFoundInstanceHandler = intentRequest.handlers ? this.findHandlerByFilter(intentRequest.handlers, { type: "instance" }) : this.findHandlerByFilter(intentDef.handlers, { type: "instance" }); + let handler; + if (!intentRequest.target || intentRequest.target === "reuse") { + handler = firstFoundInstanceHandler || firstFoundAppHandler; + } + if (intentRequest.target === "startNew") { + handler = firstFoundAppHandler; + } + if (typeof intentRequest.target === "object" && intentRequest.target.app) { + handler = this.findHandlerByFilter(intentDef.handlers, { app: intentRequest.target.app }); + } + if (typeof intentRequest.target === "object" && intentRequest.target.instance) { + handler = this.findHandlerByFilter(intentDef.handlers, { instance: intentRequest.target.instance, app: intentRequest.target.app }); + } + if (!handler) { + throw new Error(`Can not raise intent for request ${JSON.stringify(intentRequest)} - can not find intent handler!`); + } + const result = await this.raiseIntentToTargetHandler(intentRequest, handler, timeout); + return result; + } + async raiseIntentToTargetHandler(intentRequest, handler, timeout) { + var _a, _b; + (_a = this.logger) === null || _a === void 0 ? void 0 : _a.trace(`Raising intent to target handler:${JSON.stringify(handler)}`); + if (!handler.instanceId) { + const instanceIdPromise = this.invokeStartApp(handler.applicationName, intentRequest.context, intentRequest.options).catch((err) => { + const reasonMsg = typeof err === "string" ? err : JSON.stringify(err); + throw new Error(`${ERRORS.TARGET_INSTANCE_UNAVAILABLE}. Reason: ${reasonMsg}`); + }); + handler.instanceId = await instanceIdPromise; + } + const methodName = `${GLUE42_FDC3_INTENTS_METHOD_PREFIX}${intentRequest.intent}`; + const invokeOptions = { + methodResponseTimeoutMs: timeout ? timeout + 1000 : DEFAULT_METHOD_RESPONSE_TIMEOUT_MS, + waitTimeoutMs: timeout ? timeout + 1000 : DEFAULT_METHOD_RESPONSE_TIMEOUT_MS + }; + const resultPromise = this.interop.invoke(methodName, intentRequest.context, { instance: handler.instanceId }, invokeOptions) + .catch((err) => { + const reasonMsg = typeof err === "string" ? err : JSON.stringify(err); + throw new Error(`${ERRORS.INTENT_HANDLER_REJECTION}. Reason: ${reasonMsg}`); + }); + const result = await resultPromise; + (_b = this.logger) === null || _b === void 0 ? void 0 : _b.trace(`raiseIntent command completed. Returning result: ${JSON.stringify(result)}`); + return { + request: intentRequest, + handler: { ...handler, type: "instance" }, + result: result.returned + }; + } + async startResolverApp({ request, method, resolverInstance }) { + var _a, _b, _c, _d; + (_a = this.logger) === null || _a === void 0 ? void 0 : _a.trace(`Intents Resolver UI with app name ${this.intentsResolverAppName} will be used for request: ${JSON.stringify(request)}`); + const responseMethodName = await this.registerIntentResolverMethod(); + (_b = this.logger) === null || _b === void 0 ? void 0 : _b.trace(`Registered interop method ${responseMethodName}`); + const startContext = this.buildStartContext(method, request, responseMethodName); + const startOptions = await this.buildStartOptions(); + (_c = this.logger) === null || _c === void 0 ? void 0 : _c.trace(`Starting Intents Resolver UI with context: ${JSON.stringify(startContext)} and options: ${JSON.stringify(startOptions)}`); + const instance = await this.appManager.application(this.intentsResolverAppName).start(startContext, startOptions); + resolverInstance.instanceId = instance.id; + (_d = this.logger) === null || _d === void 0 ? void 0 : _d.trace(`Intents Resolver instance with id ${instance.id} opened`); + this.subscribeOnInstanceStopped(instance, method); + const timeout = request.timeout || method === "raise" ? DEFAULT_RAISE_TIMEOUT_MS : DEFAULT_PICK_HANDLER_BY_TIMEOUT_MS; + this.createResponsePromise({ + intent: method === "raise" ? request.intent : undefined, + instanceId: instance.id, + responseMethodName, + timeout, + errorMsg: `Timeout of ${timeout}ms hit waiting for the user to choose a handler ${method === "raise" + ? `for intent ${request.intent}` + : `for '${method}' method with filter ${JSON.stringify(request)}`}` + }); + const handler = await this.handleInstanceResponse({ instanceId: instance.id, caller: startContext.initialCaller, method, request }); + return handler; + } + async windowsIdToTitle(id, windowsInfos) { + var _a, _b; + if (typeof windowsInfos !== "undefined") { + return (_a = windowsInfos.find((windowsInfo) => windowsInfo.id === id)) === null || _a === void 0 ? void 0 : _a.title; + } + const window = (_b = this.windows) === null || _b === void 0 ? void 0 : _b.findById(id); + const title = await (window === null || window === void 0 ? void 0 : window.getTitle()); + return title; + } + async handleInstanceResponse({ instanceId, method, request, caller }) { + var _a, _b, _c; + try { + const response = await this.intentsResolverResponsePromises[instanceId].promise; + const subMessage = method === "raise" ? `for intent ${response.intent} ` : ""; + (_a = this.logger) === null || _a === void 0 ? void 0 : _a.trace(`Intent handler chosen ${subMessage}: ${JSON.stringify(response.handler)}. Stopping resolver instance with id ${instanceId}`); + this.stopResolverInstance(instanceId); + (_b = this.logger) === null || _b === void 0 ? void 0 : _b.trace(`Instance with id ${instanceId} successfully stopped`); + if ((_c = response.userSettings) === null || _c === void 0 ? void 0 : _c.preserveChoice) { + await this.saveUserChoice({ + intent: response.intent, + handler: response.handler, + filter: method === "filterHandlers" + ? { applicationNames: request.applicationNames, contextTypes: request.contextTypes, resultType: request.resultType } + : undefined, + caller + }); + } + return response.handler; + } + catch (error) { + this.stopResolverInstance(instanceId); + throw new Error(error); + } + } + async registerIntentResolverMethod() { + const methodName = INTENTS_RESOLVER_INTEROP_PREFIX + Utils.generateId(); + await this.interop.register(methodName, (args, callerId) => this.resolverResponseHandler(args, callerId)); + return methodName; + } + resolverResponseHandler(args, callerId) { + const { instance } = callerId; + const isValid = validateResolverResponse(args); + if (!isValid) { + this.logger.trace(`Intent Resolver instance with id ${callerId.instance} sent invalid response. Error: ${isValid.error}`); + this.intentsResolverResponsePromises[instance].reject(isValid.error); + this.stopResolverInstance(instance); + return; + } + const validResponse = isValid.ok; + this.intentsResolverResponsePromises[instance].resolve(validResponse); + this.cleanUpIntentResolverPromise(instance); + } + buildStartContext(method, request, methodName) { + var _a; + const myAppName = this.interop.instance.application || this.interop.instance.applicationName; + const myAppTitle = ((_a = this.appManager.application(myAppName)) === null || _a === void 0 ? void 0 : _a.title) || ""; + const baseStartContext = { + callerId: this.interop.instance.instance, + methodName, + initialCaller: { id: this.interop.instance.instance, applicationName: myAppName, applicationTitle: myAppTitle }, + resolverApi: "1.0" + }; + return method === "raise" + ? { ...baseStartContext, intent: request } + : { ...baseStartContext, handlerFilter: request }; + } + async buildStartOptions() { + const win = this.windows.my(); + if (!win) { + return; + } + const bounds = await win.getBounds(); + return { + top: await this.getResolverStartupTopBound(bounds), + left: (bounds.width - INTENTS_RESOLVER_WIDTH) / 2 + bounds.left, + width: INTENTS_RESOLVER_WIDTH, + height: INTENTS_RESOLVER_HEIGHT + }; + } + async getResolverStartupTopBound(bounds) { + const myDisplay = await this.windows.my().getDisplay(); + const minWorkareaHeight = myDisplay.workArea.height; + const top = (bounds.height - INTENTS_RESOLVER_HEIGHT) / 2 + bounds.top; + if (top < 0) { + return 0; + } + if (top + INTENTS_RESOLVER_HEIGHT > minWorkareaHeight) { + return minWorkareaHeight / 2; + } + return top; + } + createResponsePromise({ instanceId, intent, responseMethodName, timeout, errorMsg }) { + let resolve = () => { }; + let reject = () => { }; + const promise = PromisePlus((res, rej) => { + resolve = res; + reject = rej; + }, timeout, errorMsg); + this.intentsResolverResponsePromises[instanceId] = { intent, resolve, reject, promise, methodName: responseMethodName }; + } + async invokeStartApp(application, context, options) { + const result = await this.interop.invoke("T42.ACS.StartApplication", { Name: application, options: { ...options, startedByIntentAPI: true } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return result.returned.Id; + } + subscribeOnInstanceStopped(instance, method) { + const { application } = instance; + const unsub = application.onInstanceStopped((inst) => { + if (inst.id !== instance.id) { + return; + } + const intentPromise = this.intentsResolverResponsePromises[inst.id]; + if (!intentPromise) { + return unsub(); + } + const errorMsg = `Cannot resolve ${method === "raise" ? `raised intent ${intentPromise.intent}` : `'${method}' method`} - User closed ${instance.application.name} app without choosing a handler`; + intentPromise.reject(errorMsg); + this.cleanUpIntentResolverPromise(inst.id); + unsub(); + }); + } + async cleanUpIntentResolverPromise(instanceId) { + const intentPromise = this.intentsResolverResponsePromises[instanceId]; + if (!intentPromise) { + return; + } + const unregisterPromise = this.interop.unregister(intentPromise.methodName); + unregisterPromise.catch((error) => this.logger.warn(error)); + delete this.intentsResolverResponsePromises[instanceId]; + } + handleRaiseOnError(instanceId) { + if (!instanceId) { + return; + } + this.stopResolverInstance(instanceId); + } + stopResolverInstance(instanceId) { + const gdWin = this.windows.findById(instanceId); + gdWin === null || gdWin === void 0 ? void 0 : gdWin.close().catch((err) => this.logger.error(err)); + } + checkIfIntentsResolverIsEnabled(options, appManager) { + var _a, _b, _c, _d, _e; + if (!appManager) { + this.useIntentsResolverUI = false; + return; + } + this.useIntentsResolverUI = typeof ((_a = options.intents) === null || _a === void 0 ? void 0 : _a.enableIntentsResolverUI) === "boolean" + ? options.intents.enableIntentsResolverUI + : true; + this.intentsResolverAppName = (_c = (_b = options.intents) === null || _b === void 0 ? void 0 : _b.intentsResolverAppName) !== null && _c !== void 0 ? _c : INTENTS_RESOLVER_APP_NAME; + this.intentsResolverResponseTimeout = (_e = (_d = options.intents) === null || _d === void 0 ? void 0 : _d.methodResponseTimeoutMs) !== null && _e !== void 0 ? _e : DEFAULT_RESOLVER_RESPONSE_TIMEOUT; + } + async checkIfResolverShouldBeOpenedForRaise(intent, request) { + const checkOpen = this.checkIfIntentsResolverShouldBeOpened(); + if (!checkOpen.open) { + return checkOpen; + } + const hasMoreThanOneHandler = await this.checkIfIntentHasMoreThanOneHandler(intent, request); + if (!hasMoreThanOneHandler) { + return { open: false, reason: `Raised intent ${intent.name} has only one handler` }; + } + return { open: true }; + } + checkIfResolverShouldBeOpenedForFilterHandlers(handlers, filter) { + if (handlers.length === 1) { + return { open: false, reason: `There's only one valid intent handler for filter ${JSON.stringify(filter)}` }; + } + if (typeof (filter === null || filter === void 0 ? void 0 : filter.openResolver) === "boolean" && !filter.openResolver) { + return { open: false, reason: "Intents resolver is disabled by IntentHandler filter" }; + } + return this.checkIfIntentsResolverShouldBeOpened(); + } + checkIfIntentsResolverShouldBeOpened() { + if (!this.useIntentsResolverUI) { + return { open: false, reason: `Intent Resolver is disabled. Resolving to first found handler` }; + } + const intentsResolverApp = this.appManager.application(this.intentsResolverAppName); + if (!intentsResolverApp) { + return { open: false, reason: `Intent Resolver Application with name ${this.intentsResolverAppName} not found.` }; + } + return { open: true }; + } + async checkIfIntentHasMoreThanOneHandler(intent, request) { + const handlers = await this.removeSingletons(request.handlers || intent.handlers); + if (!request.target) { + return handlers.length > 1; + } + if (request.target === "reuse") { + return handlers.filter(handler => handler.type === "instance" && handler.instanceId).length > 1 || intent.handlers.filter(handler => handler.type === "app").length > 1; + } + if (request.target === "startNew") { + return handlers.filter(handler => handler.type === "app").length > 1; + } + if (request.target.instance) { + return false; + } + if (request.target.app) { + const searchedAppName = request.target.app; + const instanceHandlersByAppName = handlers.filter((handler) => handler.applicationName === searchedAppName && handler.instanceId); + return instanceHandlersByAppName.length > 1; + } + return false; + } + async removeSingletons(handlers) { + const handlersWithSingletonProp = await Promise.all(handlers.map(async (handler) => { + if (handler.type === "instance") { + return handler; + } + const appConfig = await this.appManager.application(handler.applicationName).getConfiguration(); + const isSingleton = appConfig.allowMultiple === false; + return { ...handler, isSingleton }; + })); + const filteredSingletonsWithOpenedInstances = handlersWithSingletonProp.filter((handler, _, currentHandlers) => { + if (handler.instanceId || !handler.isSingleton) { + return handler; + } + const openedInstance = currentHandlers.find((h) => h.instanceId && h.applicationName === handler.applicationName); + if (openedInstance) { + return; + } + return handler; + }); + return filteredSingletonsWithOpenedInstances; + } + buildInteropMethodName(intentName) { + return `${GLUE42_FDC3_INTENTS_METHOD_PREFIX}${intentName}`; + } + clearUnregistrationPromise(promiseToRemove) { + this.unregisterIntentPromises = this.unregisterIntentPromises.filter((promise) => promise !== promiseToRemove); + } + unsubscribeIntent(intentName) { + this.myIntents.delete(intentName); + const methodName = this.buildInteropMethodName(intentName); + const unregisterPromise = this.interop.unregister(methodName); + this.unregisterIntentPromises.push(unregisterPromise); + unregisterPromise + .then(() => { + this.clearUnregistrationPromise(unregisterPromise); + }) + .catch((err) => { + this.logger.error(`Unregistration of a method with name ${methodName} failed with reason: `, err); + this.clearUnregistrationPromise(unregisterPromise); + }); + } + findHandlerByFilter(handlers, filter) { + if (filter.type) { + return handlers.find((handler) => handler.type === filter.type); + } + if (filter.instance) { + return handlers.find((handler) => filter.app + ? handler.applicationName === filter.app && handler.instanceId === filter.instance + : handler.instanceId === filter.instance); + } + if (filter.app) { + return handlers.find((handler) => handler.applicationName === filter.app); + } + } + extractIntentsWithInfoByHandler(intents, handler) { + const intentsWithInfo = intents.reduce((validIntentsWithInfo, intent) => { + intent.handlers.forEach((currentHandler) => { + const isValid = Object.keys(handler).every((key) => { + var _a; + return key === "contextTypes" + ? (_a = handler.contextTypes) === null || _a === void 0 ? void 0 : _a.every((contextType) => { var _a; return (_a = currentHandler.contextTypes) === null || _a === void 0 ? void 0 : _a.includes(contextType); }) + : currentHandler[key] === handler[key]; + }); + if (!isValid) { + return; + } + const intentWithInfo = { + intent: intent.name, + contextTypes: currentHandler.contextTypes, + description: currentHandler.applicationDescription, + displayName: currentHandler.displayName, + icon: currentHandler.applicationIcon, + resultType: currentHandler.resultType + }; + validIntentsWithInfo.push(intentWithInfo); + }); + return validIntentsWithInfo; + }, []); + return intentsWithInfo; + } + async removeRememberedHandler(intentName) { + var _a; + this.logger.trace(`Removing saved handler from prefs storage for intent ${intentName}`); + let prefs; + try { + prefs = await this.prefsController.get(); + } + catch (error) { + this.logger.warn(`prefs.get() threw the following error: ${typeof error === "string" ? error : JSON.stringify(error)}`); + return; + } + const intentPrefs = (_a = prefs.data) === null || _a === void 0 ? void 0 : _a.intents; + if (!intentPrefs) { + this.logger.trace("No app prefs found for current app"); + return; + } + delete intentPrefs[intentName]; + const updatedPrefs = { + ...prefs.data, + intents: intentPrefs + }; + try { + await this.prefsController.update(updatedPrefs); + } + catch (error) { + this.logger.warn(`prefs.update() threw the following error: ${typeof error === "string" ? error : JSON.stringify(error)}`); + return; + } + this.logger.trace(`Handler saved choice for intent ${intentName} removed successfully`); + } + async checkForRememberedHandler(intentRequest) { + var _a, _b; + let prefs; + try { + prefs = await this.prefsController.get(); + } + catch (error) { + this.logger.warn(`prefs.get() threw the following error: ${typeof error === "string" ? error : JSON.stringify(error)}`); + return; + } + const prefsForIntent = (_b = (_a = prefs.data) === null || _a === void 0 ? void 0 : _a.intents) === null || _b === void 0 ? void 0 : _b[intentRequest.intent]; + return prefsForIntent === null || prefsForIntent === void 0 ? void 0 : prefsForIntent.handler; + } + async checkHandleRaiseWithRememberedHandler(intentRequest, resolverInstance, timeout) { + if (intentRequest.target) { + return; + } + const rememberedHandler = await this.checkForRememberedHandler(intentRequest); + if (!rememberedHandler) { + return; + } + const request = { + ...intentRequest, + target: { + app: rememberedHandler.applicationName, + instance: rememberedHandler.instanceId + } + }; + try { + const response = await this.coreRaiseIntent({ request, resolverInstance, timeout }); + return response; + } + catch (error) { + this.logger.trace("Could not raise intent to remembered handler. Removing it from Prefs store"); + await this.removeRememberedHandler(intentRequest.intent); + } + } + async saveUserChoice({ intent, handler, filter, caller }) { + var _a, _b; + const prevPrefs = await this.prefsController.get(caller.applicationName); + const prevIntentsPrefs = ((_a = prevPrefs === null || prevPrefs === void 0 ? void 0 : prevPrefs.data) === null || _a === void 0 ? void 0 : _a.intents) || {}; + const prefsToUpdate = { + ...prevPrefs.data, + intents: { + ...prevIntentsPrefs, + [intent]: { handler, filter } + } + }; + await this.prefsController.update(prefsToUpdate, { app: caller.applicationName }); + (_b = this.logger) === null || _b === void 0 ? void 0 : _b.info(`Saved user's choice of handler for '${caller.applicationName}' app`); + } + constructIntentHandler({ apps, intentName, method, server, title }) { + const info = method.flags.intent; + const app = apps.find((appWithIntents) => appWithIntents.name === server.application); + let appIntent; + if (app === null || app === void 0 ? void 0 : app.intents) { + appIntent = app.intents.find((appDefIntent) => appDefIntent.name === intentName); + } + const handler = { + instanceId: server.instance, + applicationName: server.application, + applicationIcon: info.icon || (app === null || app === void 0 ? void 0 : app.icon), + applicationTitle: (app === null || app === void 0 ? void 0 : app.title) || "", + applicationDescription: info.description || (app === null || app === void 0 ? void 0 : app.caption), + displayName: info.displayName || (appIntent === null || appIntent === void 0 ? void 0 : appIntent.displayName), + contextTypes: info.contextTypes || (appIntent === null || appIntent === void 0 ? void 0 : appIntent.contexts), + instanceTitle: title, + type: "instance", + resultType: (appIntent === null || appIntent === void 0 ? void 0 : appIntent.resultType) || info.resultType + }; + return handler; + } + constructIntentHandlerFromApp(app, intent) { + return { + applicationName: app.name, + applicationTitle: app.title || "", + applicationDescription: app.caption, + displayName: intent.displayName, + contextTypes: intent.contexts, + applicationIcon: app.icon, + type: "app", + resultType: intent.resultType + }; + } + } + + class FactoryCallInfo { + constructor() { + this.initialized = false; + this.details = []; + this.reject = () => { }; + this.resolve = () => { }; + } + init(config) { + this.initialized = true; + this.addCall(config); + this.promise = new Promise((resolve, reject) => { + this.resolve = resolve; + this.reject = reject; + }); + } + addCall(config) { + this.details.push({ date: new Date(), config }); + } + done(g) { + this.resolve(g); + } + error(e) { + this.reject(e); + } + } + + class Prefs { + constructor(appName, interop) { + this.appName = appName; + this.interop = interop; + this.registry = CallbackRegistryFactory(); + this.interopMethodRegistered = false; + } + async get(app) { + const data = (await this.interop.invoke(Prefs.T42GetPrefsMethodName, { app: app !== null && app !== void 0 ? app : this.appName }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + })); + return data.returned; + } + async set(data, options) { + var _a; + this.verifyDataObject(data); + await this.interop.invoke(Prefs.T42SetPrefsMethodName, { app: (_a = options === null || options === void 0 ? void 0 : options.app) !== null && _a !== void 0 ? _a : this.appName, data, merge: false }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async setFor(app, data) { + this.verifyApp(app); + this.verifyDataObject(data); + return this.set(data, { app }); + } + async update(data, options) { + var _a; + this.verifyDataObject(data); + await this.interop.invoke(Prefs.T42SetPrefsMethodName, { app: (_a = options === null || options === void 0 ? void 0 : options.app) !== null && _a !== void 0 ? _a : this.appName, data, merge: true }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async updateFor(app, data) { + this.verifyApp(app); + this.verifyDataObject(data); + return this.update(data, { app }); + } + async clear(app) { + await this.interop.invoke(Prefs.T42SetPrefsMethodName, { app: app !== null && app !== void 0 ? app : this.appName, clear: true }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async clearFor(app) { + this.verifyApp(app); + await this.interop.invoke(Prefs.T42SetPrefsMethodName, { app, clear: true }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async getAll() { + const data = (await this.interop.invoke(Prefs.T42GetPrefsMethodName, undefined, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + })); + return data.returned; + } + async clearAll() { + await this.interop.invoke(Prefs.T42SetPrefsMethodName, { clear: true }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + subscribe(callback) { + this.verifyCallback(callback); + return this.subscribeFor(this.appName, callback); + } + subscribeFor(app, callback) { + this.verifyApp(app); + this.verifyCallback(callback); + const unsubscribeFn = this.registry.add(app, callback); + this.registerInteropIfNeeded() + .then(() => { + this.interop.invoke(Prefs.T42GetPrefsMethodName, { app, subscribe: true }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + }); + return () => { + unsubscribeFn(); + }; + } + async registerInteropIfNeeded() { + if (this.interopMethodRegistered) { + return; + } + this.interopMethodRegistered = true; + await this.interop.register(Prefs.T42UpdatePrefsMethodName, (args) => { + this.registry.execute(args.app, args); + }); + } + verifyApp(app) { + if (!app) { + throw new Error(`app should be defined`); + } + if (!isString(app)) { + throw new Error(`app should be a string`); + } + } + verifyDataObject(data) { + if (!data) { + throw new Error(`data should be defined`); + } + if (!isObject(data)) { + throw new Error(`data should be an object`); + } + } + verifyCallback(callback) { + if (!isFunction(callback)) { + throw new Error(`callback should be defined`); + } + } + } + Prefs.T42UpdatePrefsMethodName = "T42.Prefs.Update"; + Prefs.T42GetPrefsMethodName = "T42.Prefs.Get"; + Prefs.T42SetPrefsMethodName = "T42.Prefs.Set"; + + class Cookies { + constructor(methodName, interop) { + this.methodName = methodName; + this.interop = interop; + } + async get(filter) { + const result = await this.invoke("get-cookies", { filter }); + return result.returned.cookies; + } + async set(cookie) { + this.verifyCookieObject(cookie); + await this.invoke("set-cookie", cookie); + } + async remove(url, name) { + if (!isString(url)) { + throw new Error(`url should be a string`); + } + if (!isString(name)) { + throw new Error(`name should be a string`); + } + await this.invoke("remove-cookie", { url, name }); + } + invoke(command, data) { + return this.interop.invoke(this.methodName, { command, args: data }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_RESPONSE_TIMEOUT_MS, + }); + } + verifyCookieObject(cookie) { + if (!cookie) { + throw new Error(`cookie should be defined`); + } + if (!isObject(cookie)) { + throw new Error(`cookie should be an object`); + } + if (Utils.isNullOrUndefined(cookie.url) || !isString(cookie.url)) { + throw new Error(`cookie.url should be a string`); + } + if (Utils.isNullOrUndefined(cookie.name) || !isString(cookie.name)) { + throw new Error(`cookie.name should be a string`); + } + if (!Utils.isNullOrUndefined(cookie.value) && !isString(cookie.value)) { + throw new Error(`cookie.value should be a string`); + } + if (!Utils.isNullOrUndefined(cookie.domain) && !isString(cookie.domain)) { + throw new Error(`cookie.domain should be a string`); + } + if (!Utils.isNullOrUndefined(cookie.path) && !isString(cookie.path)) { + throw new Error(`cookie.path should be a string`); + } + if (!Utils.isNullOrUndefined(cookie.secure) && typeof cookie.secure !== "boolean") { + throw new Error(`cookie.secure should be a boolean`); + } + if (!Utils.isNullOrUndefined(cookie.httpOnly) && typeof cookie.httpOnly !== "boolean") { + throw new Error(`cookie.httpOnly should be a boolean`); + } + if (!Utils.isNullOrUndefined(cookie.expirationDate) && typeof cookie.expirationDate !== "number") { + throw new Error(`cookie.expirationDate should be a number`); + } + } + } + + function factory$1(agm, methodName) { + const cookies = new Cookies(methodName, agm); + return { + get: cookies.get.bind(cookies), + remove: cookies.remove.bind(cookies), + set: cookies.set.bind(cookies), + ready: () => Promise.resolve() + }; + } + + class EventsDispatcher { + constructor(config) { + this.config = config; + this.glue42EventName = "Glue42"; + this.events = { + notifyStarted: { name: "notifyStarted", handle: this.handleNotifyStarted.bind(this) }, + requestGlue: { name: "requestGlue", handle: this.handleRequestGlue.bind(this) } + }; + } + start(glue) { + if (Utils.isNode()) { + return; + } + this.glue = glue; + this.wireCustomEventListener(); + this.announceStarted(); + } + wireCustomEventListener() { + window.addEventListener(this.glue42EventName, (event) => { + const data = event.detail; + if (!data || !data.glue42) { + return; + } + const glue42Event = data.glue42.event; + const foundHandler = this.events[glue42Event]; + if (!foundHandler) { + return; + } + foundHandler.handle(data.glue42.message); + }); + } + announceStarted() { + this.send("start"); + } + handleRequestGlue() { + if (!this.config.exposeAPI) { + this.send("requestGlueResponse", { error: "Will not give access to the underlying Glue API, because it was explicitly denied upon initialization." }); + return; + } + this.send("requestGlueResponse", { glue: this.glue }); + } + handleNotifyStarted() { + this.announceStarted(); + } + send(eventName, message) { + const payload = { glue42: { event: eventName, message } }; + const event = new CustomEvent(this.glue42EventName, { detail: payload }); + window.dispatchEvent(event); + } + } + + class PromiseWrapper { + static delay(time) { + return new Promise((resolve) => setTimeout(resolve, time)); + } + static async delayForever() { + const biggestPossibleDelay = 2147483647; + while (true) { + await this.delay(biggestPossibleDelay); + } + } + get ended() { + return this.rejected || this.resolved; + } + constructor() { + this.promise = new Promise((resolve, reject) => { + this.resolve = (t) => { + this.resolved = true; + resolve(t); + }; + this.reject = (err) => { + this.rejected = true; + reject(err); + }; + }); + } + } + + class Interception { + constructor() { + this.InterceptorMethodName = "T42.GD.Interception.Execute"; + this.InterceptorHandlerMethodName = "T42.GD.Interception.Handler"; + this.interceptions = []; + } + init(interop) { + this.interop = interop; + } + async register(request) { + if (!request || typeof request !== "object" || Array.isArray(request)) { + throw new Error(`Please provide a valid object.`); + } + const handler = request.handler; + if (typeof handler !== "function") { + throw new Error("Please provide a valid handler function."); + } + const interceptions = request.interceptions; + this.validateInterceptions(interceptions); + this.interceptions.push(request); + try { + await this.interop.invoke(this.InterceptorMethodName, { + command: "register", + interceptions + }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + await this.registerMethodIfNotRegistered(); + } + catch (error) { + this.interceptions = this.interceptions.filter((i) => i !== request); + const message = error.message || "Unknown error"; + const newError = new Error(`Failed to register interception: ${message}`); + throw newError; + } + } + async unregister(request) { + if (!request || typeof request !== "object" || Array.isArray(request)) { + throw new Error(`Please provide a valid object.`); + } + const interceptions = request.interceptions; + this.validateInterceptions(interceptions); + try { + await this.interop.invoke(this.InterceptorMethodName, { + command: "unregister", + interceptions + }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + this.interceptions = this.interceptions.filter((config) => { + return !interceptions.some((interception) => { + return config.interceptions.some((i) => { + return i.domain === interception.domain && i.operation === interception.operation; + }); + }); + }); + } + catch (error) { + const message = error.message || "Unknown error"; + const newError = new Error(`Failed to unregister interception: ${message}`); + throw newError; + } + } + async handleInterception(domain, operation, operationArgs, phase) { + if (this.interop.methods(this.InterceptorMethodName).length === 0) { + return {}; + } + const result = await this.interop.invoke(this.InterceptorMethodName, { + command: "raiseInterception", + interceptions: [{ + operationArgs, + domain, + operation, + phase + }] + }, 'best', { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return result.returned; + } + static createProxyObject(apiToIntercept, domain, interception) { + const methods = Interception.OperationsPerDomain[domain] || []; + const handler = { + get(target, propertyKey, receiver) { + const property = Reflect.get(target, propertyKey, receiver); + try { + if (typeof property !== "function") { + return property; + } + const shouldIntercept = methods.includes(propertyKey); + const isAwaitable = Utils.isPromise(property) || Utils.isAsyncFunction(property); + if (!shouldIntercept || !isAwaitable) { + return property; + } + return Interception.interceptMethod(property, propertyKey, target, domain, interception); + } + catch (error) { + return property; + } + } + }; + const proxyAPI = new Proxy(apiToIntercept, handler); + return proxyAPI; + } + static interceptMethod(originalMethod, propertyKey, target, domain, interception) { + return async function (...args) { + const beforeInterceptionResult = await interception.handleInterception(domain, propertyKey, args, "before"); + if (!Utils.isNullOrUndefined(beforeInterceptionResult.operationResult)) { + return beforeInterceptionResult.operationResult; + } + if (!Utils.isNullOrUndefined(beforeInterceptionResult.operationArgs)) { + args = beforeInterceptionResult.operationArgs; + } + const methodResult = await originalMethod.apply(target, args); + const afterInterceptionResult = await interception.handleInterception(domain, propertyKey, [methodResult], "after"); + if (!Utils.isNullOrUndefined(afterInterceptionResult.operationResult)) { + return afterInterceptionResult.operationResult; + } + return methodResult; + }; + } + toAPI() { + return { + register: this.register.bind(this), + unregister: this.unregister.bind(this), + }; + } + async registerMethodIfNotRegistered() { + var _a; + if ((_a = this.whenRegisteredPromise) === null || _a === void 0 ? void 0 : _a.ended) { + return; + } + this.whenRegisteredPromise = new PromiseWrapper(); + this.registerMethod(); + } + async registerMethod() { + await this.interop.register(this.InterceptorHandlerMethodName, async (data) => { + const command = data.command; + if (command === "raiseInterception") { + const raisedInterception = data.interception; + const interceptor = this.interceptions.find((config) => { + return config.interceptions.some((interception) => { + return interception.domain === raisedInterception.domain && interception.operation === raisedInterception.operation; + }); + }); + const result = await interceptor.handler(raisedInterception); + return result; + } + }); + this.whenRegisteredPromise.resolve(); + } + validateInterceptions(interceptions) { + if (!Array.isArray(interceptions)) { + throw new Error("Please provide a valid array of interceptions."); + } + if (interceptions.length === 0) { + throw new Error("Please provide at least one interception."); + } + for (const interception of interceptions) { + if (typeof interception === "undefined" || interception === null || typeof interception !== "object" || Array.isArray(interception)) { + throw new Error("Please provide a valid interception object."); + } + if (typeof interception.domain !== "string" || !interception.domain) { + throw new Error("Please provide a valid domain string."); + } + if (typeof interception.operation !== "string" || !interception.operation) { + throw new Error("Please provide a valid operation string."); + } + this.validateTypeString(interception); + } + } + validateTypeString(interception) { + if (!isUndefinedOrNull(interception.phase)) { + const isValidType = ["all", "before", "after"].includes(interception.phase); + if (typeof interception.phase !== "string" || !isValidType) { + throw new Error("Please provide a valid phase string."); + } + } + } + } + Interception.OperationsPerDomain = { + "intents": ["raise"] + }; + + const callInfo = new FactoryCallInfo(); + const factory = async (options) => { + let firstRun = false; + if (!callInfo.initialized) { + firstRun = true; + callInfo.init(options); + } + const glue42gd = typeof window !== "undefined" && window.glue42gd; + if (glue42gd) { + if (!firstRun) { + callInfo.addCall(options); + return callInfo.promise; + } + } + const g = await factoryCore(options, glue42gd); + callInfo.resolve(g); + return g; + }; + const factoryCore = async (options, glue42gd) => { + const T42GDExecuteMethod = "T42.GD.Execute"; + const gdMajorVersion = Utils.getGDMajorVersion(); + options = options || {}; + const glueConfig = prepareConfig(options); + options.gateway = options.gateway || {}; + let _appManager; + let _activity; + let _windows; + let _displays; + let _channels; + let _prefs; + const _interceptors = new Interception(); + const _browserEventsDispatcher = new EventsDispatcher(glueConfig); + function createWindows(core) { + if (glueConfig.windows) { + const windowsLogger = getLibLogger("windows", core.logger, glueConfig.windows); + _windows = WindowsFactory(core.agm, windowsLogger, () => { + return _appManager; + }, () => { + return _displays; + }, () => { + return _channels; + }, gdMajorVersion); + debugLog(_windows); + return _windows; + } + } + function createActivities(core) { + var _a; + if (glueConfig.activities) { + if (ActivityModule.checkIsUsingGW3Implementation && ActivityModule.checkIsUsingGW3Implementation(core.connection)) { + const activityLogger = getLibLogger("activity", core.logger, glueConfig.activities); + _activity = new ActivityModule({ + connection: core.connection, + contexts: core.contexts, + agm: core.agm, + logger: activityLogger, + logLevel: "info", + disableAutoAnnounce: false, + disposeRequestHandling: "exit", + announcementInfo: null, + windows: _windows, + appManagerGetter: () => { + return _appManager; + }, + mode: glueConfig.activities.mode, + typesToTrack: glueConfig.activities.typesToTrack, + activityId: (_a = glue42gd === null || glue42gd === void 0 ? void 0 : glue42gd.activityInfo) === null || _a === void 0 ? void 0 : _a.activityId, + gdMajorVersion + }).api; + debugLog(_activity); + return _activity; + } + } + } + function createAppManager(core) { + if (!glueConfig.appManager) { + return; + } + const logger = getLibLogger("appManager", core.logger, glueConfig.appManager); + _appManager = AppManagerFactory({ + agm: core.agm, + windows: _windows, + logger, + activities: _activity, + mode: glueConfig.appManager.mode, + gdMajorVersion + }); + debugLog(_appManager); + return _appManager; + } + function createLayouts(core) { + var _a; + if (!glueConfig.layouts) { + return; + } + const logger = getLibLogger("layouts", core.logger, glueConfig.layouts); + const layoutsConfig = glueConfig.layouts; + const lay = LayoutsFactory({ + agm: core.agm, + appManager: _appManager, + activityGetter: () => _activity, + logger, + mode: layoutsConfig.mode, + autoSaveWindowContext: (_a = layoutsConfig.autoSaveWindowContext) !== null && _a !== void 0 ? _a : false, + gdMajorVersion + }); + debugLog(lay); + return lay; + } + function createChannels(core) { + if (!glueConfig.channels) { + return; + } + const logger = getLibLogger("channels", core.logger, glueConfig.channels); + if (!core.contexts) { + logger.error("Channels library requires Contexts library to be initialized."); + return; + } + _channels = factory$4({ operationMode: glueConfig.channels.operationMode }, core.contexts, core.agm, () => _windows, () => _appManager, logger); + debugLog(_channels); + return _channels; + } + function createHotkeys(core) { + const hotkeysAPI = factory$3(core.agm); + debugLog(hotkeysAPI); + return hotkeysAPI; + } + function createIntents(core) { + const domain = "intents"; + const intents = new Intents(core.agm, _windows, core.logger.subLogger(domain), options, _prefs, _appManager); + const intentsAPI = intents.toAPI(); + const proxyIntentsAPI = Interception.createProxyObject(intentsAPI, domain, _interceptors); + debugLog(proxyIntentsAPI); + return proxyIntentsAPI; + } + function createNotifications(core) { + const notificationsAPI = new Notifications(core.interop, core.logger).toAPI(); + debugLog(notificationsAPI); + return notificationsAPI; + } + function createDisplaysApi(core) { + if (glueConfig.displays) { + const displaysLogger = getLibLogger("displays", core.logger, glueConfig.displays); + _displays = new DisplayManager(core.agm, displaysLogger); + debugLog(_displays); + return _displays; + } + } + function createThemes(core) { + if (!core.contexts) { + return; + } + const themesAPI = factory$2(core.contexts, core.interop); + debugLog(themesAPI); + return themesAPI; + } + function createPrefs(core) { + var _a, _b; + const appName = (_b = (_a = options.application) !== null && _a !== void 0 ? _a : glue42gd === null || glue42gd === void 0 ? void 0 : glue42gd.applicationName) !== null && _b !== void 0 ? _b : core.interop.instance.application; + _prefs = new Prefs(appName, core.interop); + debugLog(_prefs); + return _prefs; + } + function createCookies(core) { + const api = factory$1(core.interop, T42GDExecuteMethod); + debugLog(api); + return api; + } + function createInterception(core) { + _interceptors.init(core.interop); + debugLog(_interceptors); + return _interceptors.toAPI(); + } + function getLibLogger(loggerName, logger, config) { + const newLogger = logger.subLogger(loggerName); + if (config && config.logger) { + const loggerConfig = config.logger; + if (loggerConfig.console) { + newLogger.consoleLevel(loggerConfig.console); + } + if (loggerConfig.publish) { + newLogger.publishLevel(loggerConfig.publish); + } + } + return newLogger; + } + const ext = { + libs: [ + { name: "windows", create: createWindows }, + { name: "activities", create: createActivities }, + { name: "appManager", create: createAppManager }, + { name: "layouts", create: createLayouts }, + { name: "channels", create: createChannels }, + { name: "hotkeys", create: createHotkeys }, + { name: "displays", create: createDisplaysApi }, + { name: "prefs", create: createPrefs }, + { name: "intents", create: createIntents }, + { name: "notifications", create: createNotifications }, + { name: "themes", create: createThemes }, + { name: "cookies", create: createCookies }, + { name: "interception", create: createInterception } + ], + version, + enrichGlue: (glue) => { + glue.config.activities = glueConfig.activities; + glue.config.windows = glueConfig.windows; + glue.config.appManager = glueConfig.appManager; + glue.config.layouts = glueConfig.layouts; + glue.config.channels = glueConfig.channels; + glue.config.displays = glueConfig.displays; + }, + }; + const currentLog = []; + if (typeof window !== "undefined") { + if (!window.glueFactoryLog) { + window.glueFactoryLog = []; + } + window.glueFactoryLog.push(currentLog); + } + function debugLog(entry) { + currentLog.push(entry); + } + const glueApi = (await IOConnectCoreFactory(options, ext)); + if (Array.isArray(options === null || options === void 0 ? void 0 : options.libraries) && options.libraries.length) { + await Promise.all(options.libraries.map((lib) => lib(glueApi, options))); + } + _browserEventsDispatcher.start(glueApi); + return glueApi; + }; + factory.coreVersion = IOConnectCoreFactory.version; + factory.version = version; + factory.calls = callInfo; + + var _a, _b; + let whatToExpose = factory; + let shouldSetToWindow = true; + if (typeof window !== "undefined") { + const windowAsAny = window; + const iodesktop = (_a = windowAsAny.iodesktop) !== null && _a !== void 0 ? _a : windowAsAny.glue42gd; + if (iodesktop && iodesktop.autoInjected) { + whatToExpose = (_b = windowAsAny.IODesktop) !== null && _b !== void 0 ? _b : windowAsAny.Glue; + shouldSetToWindow = false; + } + if (shouldSetToWindow) { + windowAsAny.Glue = whatToExpose; + windowAsAny.IODesktop = whatToExpose; + } + delete windowAsAny.IOBrowser; + delete windowAsAny.GlueCore; + } + whatToExpose.default = whatToExpose; + var whatToExpose$1 = whatToExpose; + + return whatToExpose$1; + +})); +//# sourceMappingURL=desktop.umd.js.map diff --git a/typescript/start/clients/src/lib/io.applications.css b/typescript/start/clients/src/lib/io.applications.css new file mode 100644 index 0000000..98e5910 --- /dev/null +++ b/typescript/start/clients/src/lib/io.applications.css @@ -0,0 +1,12 @@ +:root{--bs-blue: #007be5;--bs-indigo: #6610f2;--bs-purple: #6f42c1;--bs-pink: #fd397a;--bs-red: #ff511f;--bs-orange: #fd7e14;--bs-yellow: #f9a825;--bs-green: #43a047;--bs-teal: #616161;--bs-cyan: #469eb9;--bs-white: #fff;--bs-gray: #6c757d;--bs-gray-dark: #343a40;--bs-gray-100: #f8f9fa;--bs-gray-200: #e9ecef;--bs-gray-300: #dee2e6;--bs-gray-400: #ced4da;--bs-gray-500: #adb5bd;--bs-gray-600: #6c757d;--bs-gray-700: #495057;--bs-gray-800: #343a40;--bs-gray-900: #212529;--bs-primary: #007be5;--bs-secondary: #616161;--bs-success: #43a047;--bs-info: #469eb9;--bs-warning: #f9a825;--bs-danger: #ff511f;--bs-light: #616161;--bs-dark: #616161;--bs-primary-rgb: 0,123,229;--bs-secondary-rgb: 97,97,97;--bs-success-rgb: 67,160,71;--bs-info-rgb: 70,158,185;--bs-warning-rgb: 249,168,37;--bs-danger-rgb: 255,81,31;--bs-light-rgb: 97,97,97;--bs-dark-rgb: 97,97,97;--bs-white-rgb: 255,255,255;--bs-black-rgb: 0,0,0;--bs-body-color-rgb: 33,37,41;--bs-body-bg-rgb: 255,255,255;--bs-font-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--bs-gradient: linear-gradient(180deg, rgba(255,255,255,0.15), rgba(255,255,255,0));--bs-body-font-family: Montserrat,Helvetica Neue,Arial,sans-serif;--bs-body-font-size: .75rem;--bs-body-font-weight: 400;--bs-body-line-height: 1.5;--bs-body-color: #212529;--bs-body-bg: #fff}:root{--t42-font-family: "Montserrat", "Helvetica Neue", Arial, sans-serif;--t42-font-size: 0.75rem;--bs-gutter-x: 0.938rem;--primary: #007be5;--secondary: #616161;--success: #43a047;--info: #616161;--warning: #f9a825;--danger: #ff511f;--light: #616161;--dark: #616161;--white: #ffffff}.dark{--t42-bg-light-base: 0, 0%;--t42-bg-light-l: 18%;--t42-bg-light: 45, 45, 45;--t42-bg-mid: 37, 37, 37;--t42-bg-dark: 30, 30, 30;--t42-content-color-base: 0, 0%;--t42-content-color: #bababa;--t42-content-color-l: 73%;--t42-content-color-muted: hsl(var(--t42-content-color-base), 63%);--t42-content-color-disabled: hsl(var(--t42-content-color-base), 43%);--t42-color-opacity-025: hsla(var(--t42-content-color-base), 100%, 0.025);--t42-color-opacity-05: hsla(var(--t42-content-color-base), 100%, 0.05);--t42-color-opacity-10: hsla(var(--t42-content-color-base), 100%, 0.1);--t42-color-opacity-20: hsla(var(--t42-content-color-base), 100%, 0.2);--t42-color-opacity-30: hsla(var(--t42-content-color-base), 100%, 0.3);--t42-link-color: hsl(var(--t42-content-color-base), 100%);--t42-shadow: 0 0 12px 0 hsla(var(--t42-content-color-base), 0%, 0.15);--t42-border: 0.0625rem solid var(--t42-color-opacity-10);--t42-logo-icon: url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 xmlns:xlink=%27http://www.w3.org/1999/xlink%27 x=%270px%27 y=%270px%27 viewBox=%270 0 100.2 121%27 style=%27enable-background:new 0 0 100.2 121;%27%3E%3Cpath fill=%27%233A77BC%27 d=%27M59.4,10.6l-8.3,8.3c-0.5,0.5-1.4,0.5-1.9,0l-8.3-8.3c-0.5-0.5-0.5-1.4,0-1.9l8.3-8.3c0.5-0.5,1.4-0.5,1.9,0 l8.3,8.3C59.9,9.2,59.9,10.1,59.4,10.6z M59.3,110.4l-8.3-8.3c-0.5-0.5-1.4-0.5-1.9,0l-8.3,8.3c-0.5,0.5-0.5,1.4,0,1.9l8.3,8.3 c0.5,0.5,1.4,0.5,1.9,0l8.3-8.3C59.9,111.8,59.9,110.9,59.3,110.4z%27/%3E%3Cpath fill=%27%23FFFFFF%27 d=%27M100.1,60.1c0.3,7.3-2.9,14.3-9.3,20.6l-24.7,24.7c-0.6,0.6-1.5,0.6-2.1,0l-8.1-8.1c-0.6-0.6-0.6-1.5,0-2.1 l24.7-24.7c0.1-0.1,0.2-0.2,0.3-0.3c3.2-3.3,4.7-6.7,4.4-10.2c0-0.4-0.1-0.8-0.2-1.3c-0.6-3.3-2.8-7-6.8-11l-9.9-9.9 c-0.3-0.3-0.7-0.5-1.1-0.5c-0.4,0-0.8,0.2-1.3,0.6L34.5,69.6c-0.6,0.6-1.5,0.6-2.1,0L27.7,65c-3.3-3.3-3.8-5.1-1.3-7.6 c11.1-11.2,22-22.1,33.2-33.2c2.7-2.7,5.1-4.2,7.5-4.3c2.5-0.1,4.7,1.2,6.9,3.5l14.3,14.3C95.9,45.3,99.8,52.8,100.1,60.1 L100.1,60.1z M0,60.9c0.3,7.3,3.7,14.3,11.2,21.9l14.8,14.8c2.3,2.3,4.5,3.6,6.9,3.5c2.4-0.1,4.8-1.6,7.5-4.3 c11.1-11.1,22.1-22,33.2-33.2c2.5-2.5,2-4.3-1.3-7.6l-4.7-4.7c-0.6-0.6-1.5-0.6-2.1,0L34,83c-0.5,0.5-0.9,0.6-1.3,0.6 c-0.4,0-0.7-0.1-1.1-0.5L21.3,72.7c-4-4-5.7-7.2-6.3-10.5c-0.1-0.4-0.1-0.8-0.2-1.3c-0.3-3.5,1.2-6.9,4.4-10.2 c0.1-0.1,0.2-0.2,0.3-0.3l24.7-24.7c0.6-0.6,0.6-1.5,0-2.1l-8.1-8.1c-0.6-0.6-1.5-0.6-2.1,0L9.3,40.3C2.9,46.6-0.3,53.5,0,60.9 L0,60.9z%27/%3E%3C/svg%3E%0A");--t42-icon-color: var(--t42-link-color);--t42-list-group-hover-bg-special: hsla(var(--t42-content-color-base), 100%, 0.065);--backdrop-filter: blur(5px) saturate(200%);--accordion-filter: invert(1) brightness(1);--filter-close: invert(1);--t42-body: rgb(var(--t42-bg-dark));--pink: rgb(0 170 200);--t42-link-hover-color: hsl(var(--t42-bg-light-base), 100%);--t42-link-hover-bg: var(--t42-color-opacity-05);--t42-link-active-bg: var(--t42-color-opacity-10);--t42-input-bg: rgb(var(--t42-bg-dark));--t42-input-disabled-bg: Hsla(var(--t42-content-color-base), 100%, 0.075);--t42-tooltip-bg: rgba(var(--t42-bg-dark), 0.85);--t42-modal-bg: rgba(var(--t42-bg-light), 0.75);--t42-table-active-bg: rgba(255, 255, 255, 0.1);--t42-select-indicator: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9IiNFRUVFRUUiIHZpZXdCb3g9IjAgMCAxNiAxNiI+PHBhdGggZD0iTTIuNSA1LjVjLjQtLjQgMS0uNSAxLjYgMGwzLjkgMy43bDMuOS0zLjdjLjUtLjUgMS4xLS40IDEuNiAwYy40LjQuNCAxLjIgMCAxLjZjLS40LjQtNC43IDQuNS00LjcgNC41Yy0uMi4yLS41LjMtLjguM3MtLjYtLjEtLjgtLjNjMCAwLTQuMy00LjEtNC43LTQuNXMtLjQtMS4yIDAtMS42eiI+PC9wYXRoPjwvc3ZnPg==)}.light{--t42-bg-light-base: 0, 0%;--t42-bg-light-l: 100%;--t42-bg-light: 255, 255, 255;--t42-bg-mid: 250, 250, 250;--t42-bg-dark: 245, 245, 245;--t42-content-color-base: 0, 0%;--t42-content-color: #757575;--t42-content-color-l: 46%;--t42-content-color-muted: hsl(var(--t42-content-color-base), 66%);--t42-color-opacity-025: hsla(var(--t42-content-color-base), 0%, 0.025);--t42-color-opacity-05: hsla(var(--t42-content-color-base), 0%, 0.05);--t42-color-opacity-10: hsla(var(--t42-content-color-base), 0%, 0.075);--t42-color-opacity-30: hsla(var(--t42-content-color-base), 0%, 0.1);--t42-color-opacity-20: hsla(var(--t42-content-color-base), 0%, 0.2);--t42-link-color: hsl(var(--t42-content-color-base), 5%);--t42-shadow: 0 0 12px 0 hsla(var(--t42-content-color-base), 0%, 0.05);--t42-border: 0.0625rem solid var(--t42-color-opacity-10);--t42-logo-icon: url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 xmlns:xlink=%27http://www.w3.org/1999/xlink%27 x=%270px%27 y=%270px%27 viewBox=%270 0 100.2 121%27 style=%27enable-background:new 0 0 100.2 121;%27%3E%3Cpath fill=%27%233A77BC%27 d=%27M59.4,10.6l-8.3,8.3c-0.5,0.5-1.4,0.5-1.9,0l-8.3-8.3c-0.5-0.5-0.5-1.4,0-1.9l8.3-8.3c0.5-0.5,1.4-0.5,1.9,0 l8.3,8.3C59.9,9.2,59.9,10.1,59.4,10.6z M59.3,110.4l-8.3-8.3c-0.5-0.5-1.4-0.5-1.9,0l-8.3,8.3c-0.5,0.5-0.5,1.4,0,1.9l8.3,8.3 c0.5,0.5,1.4,0.5,1.9,0l8.3-8.3C59.9,111.8,59.9,110.9,59.3,110.4z%27/%3E%3Cpath fill=%27%23083044%27 d=%27M100.1,60.1c0.3,7.3-2.9,14.3-9.3,20.6l-24.7,24.7c-0.6,0.6-1.5,0.6-2.1,0l-8.1-8.1c-0.6-0.6-0.6-1.5,0-2.1 l24.7-24.7c0.1-0.1,0.2-0.2,0.3-0.3c3.2-3.3,4.7-6.7,4.4-10.2c0-0.4-0.1-0.8-0.2-1.3c-0.6-3.3-2.8-7-6.8-11l-9.9-9.9 c-0.3-0.3-0.7-0.5-1.1-0.5c-0.4,0-0.8,0.2-1.3,0.6L34.5,69.6c-0.6,0.6-1.5,0.6-2.1,0L27.7,65c-3.3-3.3-3.8-5.1-1.3-7.6 c11.1-11.2,22-22.1,33.2-33.2c2.7-2.7,5.1-4.2,7.5-4.3c2.5-0.1,4.7,1.2,6.9,3.5l14.3,14.3C95.9,45.3,99.8,52.8,100.1,60.1 L100.1,60.1z M0,60.9c0.3,7.3,3.7,14.3,11.2,21.9l14.8,14.8c2.3,2.3,4.5,3.6,6.9,3.5c2.4-0.1,4.8-1.6,7.5-4.3 c11.1-11.1,22.1-22,33.2-33.2c2.5-2.5,2-4.3-1.3-7.6l-4.7-4.7c-0.6-0.6-1.5-0.6-2.1,0L34,83c-0.5,0.5-0.9,0.6-1.3,0.6 c-0.4,0-0.7-0.1-1.1-0.5L21.3,72.7c-4-4-5.7-7.2-6.3-10.5c-0.1-0.4-0.1-0.8-0.2-1.3c-0.3-3.5,1.2-6.9,4.4-10.2 c0.1-0.1,0.2-0.2,0.3-0.3l24.7-24.7c0.6-0.6,0.6-1.5,0-2.1l-8.1-8.1c-0.6-0.6-1.5-0.6-2.1,0L9.3,40.3C2.9,46.6-0.3,53.5,0,60.9 L0,60.9z%27/%3E%3C/svg%3E%0A");--t42-icon-color: Hsl(var(--t42-content-color-base), 38%);--t42-list-group-hover-bg-special: hsla(var(--t42-content-color-base), 95%, 0.065);--backdrop-filter: blur(5px) saturate(200%);--accordion-filter: brightness(0%);--filter-close: invert(0);--t42-body: rgb(var(--t42-bg-mid));--t42-link-hover-color: hsl(var(--t42-bg-light-base), 0%);--t42-link-hover-bg: hsl(var(--t42-content-color-base), 95%);--t42-link-active-bg: hsl(var(--t42-content-color-base), 90%);--t42-input-bg: rgb(var(--t42-bg-light));--t42-input-disabled-bg: var(--t42-color-opacity-10);--t42-tooltip-bg: rgba(var(--t42-bg-light), 0.95);--t42-modal-bg: rgba(var(--t42-bg-light), 0.95);--t42-table-active-bg: rgba(0, 0, 0, 0.025);--t42-select-indicator: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9IiM2MTYxNjEiIHZpZXdCb3g9IjAgMCAxNiAxNiI+PHBhdGggZD0iTTIuNSA1LjVjLjQtLjQgMS0uNSAxLjYgMGwzLjkgMy43bDMuOS0zLjdjLjUtLjUgMS4xLS40IDEuNiAwYy40LjQuNCAxLjIgMCAxLjZjLS40LjQtNC43IDQuNS00LjcgNC41Yy0uMi4yLS41LjMtLjguM3MtLjYtLjEtLjgtLjNjMCAwLTQuMy00LjEtNC43LTQuNXMtLjQtMS4yIDAtMS42eiI+PC9wYXRoPjwvc3ZnPg==)}*,*::before,*::after{box-sizing:border-box}@media (prefers-reduced-motion: no-preference){:root{scroll-behavior:smooth}}body{margin:0;font-family:var(--bs-body-font-family);font-size:var(--bs-body-font-size);font-weight:var(--bs-body-font-weight);line-height:var(--bs-body-line-height);color:var(--bs-body-color);text-align:var(--bs-body-text-align);background-color:var(--bs-body-bg);-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:rgba(0,0,0,0)}hr{margin:1rem 0;color:inherit;background-color:currentColor;border:0;opacity:.25}hr:not([size]){height:1px}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem;font-weight:500;line-height:1.2;color:var(--t42-link-color)}h1{font-size:calc(1.26563rem + .1875vw)}@media (min-width: 1200px){h1{font-size:1.40625rem}}h2{font-size:1.125rem}h3{font-size:.98475rem}h4{font-size:.84375rem}h5{font-size:.75rem}h6{font-size:.7035rem}p{margin-top:0;margin-bottom:1rem}abbr[title],abbr[data-bs-original-title]{text-decoration:underline dotted;cursor:help;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}ol,ul{padding-left:2rem}ol,ul,dl{margin-top:0;margin-bottom:1rem}ol ol,ul ul,ol ul,ul ol{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:.875em}mark{padding:0.2rem 0.2rem 0;background-color:#007be5}sub,sup{position:relative;font-size:.75em;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:var(--t42-link-color);text-decoration:underline}a:hover{color:var(--t42-link-hover-color)}a:not([href]):not([class]),a:not([href]):not([class]):hover{color:inherit;text-decoration:none}pre,code,kbd,samp{font-family:var(--bs-font-monospace);font-size:1em;direction:ltr /* rtl:ignore */;unicode-bidi:bidi-override}pre{display:block;margin-top:0;margin-bottom:1rem;overflow:auto;font-size:inherit;color:var(--t42-content-color)}pre code{font-size:inherit;color:inherit;word-break:normal}code{font-size:inherit;color:#469eb9;word-wrap:break-word}a>code{color:inherit}kbd{padding:.2rem .4rem;font-size:inherit;color:#fff;background-color:#212529;border-radius:.25rem}kbd kbd{padding:0;font-size:1em;font-weight:700}figure{margin:0 0 1rem}img,svg{vertical-align:middle}table{caption-side:bottom;border-collapse:collapse}caption{padding-top:.25rem;padding-bottom:.25rem;color:var(--t42-content-color-muted);text-align:left}th{text-align:inherit;text-align:-webkit-match-parent}thead,tbody,tfoot,tr,td,th{border-color:inherit;border-style:solid;border-width:0}label{display:inline-block}button{border-radius:0}button:focus:not(:focus-visible){outline:0}input,button,select,optgroup,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,select{text-transform:none}[role="button"]{cursor:pointer}select{word-wrap:normal}select:disabled{opacity:1}[list]::-webkit-calendar-picker-indicator{display:none}button,[type="button"],[type="reset"],[type="submit"]{-webkit-appearance:button}button:not(:disabled),[type="button"]:not(:disabled),[type="reset"]:not(:disabled),[type="submit"]:not(:disabled){cursor:pointer}::-moz-focus-inner{padding:0;border-style:none}textarea{resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{float:left;width:100%;padding:0;margin-bottom:.5rem;font-size:calc(1.275rem + .3vw);line-height:inherit}@media (min-width: 1200px){legend{font-size:1.5rem}}legend+*{clear:left}::-webkit-datetime-edit-fields-wrapper,::-webkit-datetime-edit-text,::-webkit-datetime-edit-minute,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-year-field{padding:0}::-webkit-inner-spin-button{height:auto}[type="search"]{outline-offset:-2px;-webkit-appearance:textfield}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-color-swatch-wrapper{padding:0}::file-selector-button{font:inherit}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}iframe{border:0}summary{display:list-item;cursor:pointer}progress{vertical-align:baseline}[hidden]{display:none !important}body{color:var(--t42-content-color);font-family:var(--t42-font-family);background-color:var(--t42-body)}a:focus,button:focus,div:focus,span:focus{outline:0}a{text-decoration:none}dt{font-weight:normal}::selection{color:var(--white);background-color:var(--primary)}::-webkit-scrollbar{width:4px;height:4px}::-webkit-scrollbar-track{border-radius:.25rem;background:transparent}::-webkit-scrollbar-thumb{border-radius:.25rem;background:var(--t42-color-opacity-10)}::-webkit-resizer{background:transparent}::-webkit-scrollbar-corner{background:transparent}::-webkit-scrollbar-thumb:window-inactive{background:transparent}::-webkit-scrollbar-thumb:hover,::-webkit-scrollbar-thumb:active{background:Hsla(var(--t42-content-color-base), 100%, 0.05)}.accordion-button{position:relative;display:flex;align-items:center;width:100%;padding:1rem 1.25rem;font-size:.75rem;color:var(--t42-link-color);text-align:left;background-color:Rgb(var(--t42-bg-mid));border:0;border-radius:0;overflow-anchor:none;transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out,border-radius 0.15s ease}@media (prefers-reduced-motion: reduce){.accordion-button{transition:none}}.accordion-button:not(.collapsed){color:var(--t42-link-color);background-color:Rgb(var(--t42-bg-mid));box-shadow:inset 0 -1px 0 var(--t42-color-opacity-10)}.accordion-button:not(.collapsed)::after{background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 16 16%27 fill=%27var%28--t42-link-color%29%27%3e%3cpath fill-rule=%27evenodd%27 d=%27M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z%27/%3e%3c/svg%3e");transform:rotate(-180deg)}.accordion-button::after{flex-shrink:0;width:1.25rem;height:1.25rem;margin-left:auto;content:"";background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 16 16%27 fill=%27var%28--t42-link-color%29%27%3e%3cpath fill-rule=%27evenodd%27 d=%27M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z%27/%3e%3c/svg%3e");background-repeat:no-repeat;background-size:1.25rem;transition:transform 0.2s ease-in-out}@media (prefers-reduced-motion: reduce){.accordion-button::after{transition:none}}.accordion-button:hover{z-index:2}.accordion-button:focus{z-index:3;border-color:#007be5;outline:0;box-shadow:0 0 0 0 rgba(0,123,229,0.25)}.accordion-header{margin-bottom:0}.accordion-item{background-color:Rgb(var(--t42-bg-mid));border:1px solid var(--t42-color-opacity-10)}.accordion-item:first-of-type{border-top-left-radius:0;border-top-right-radius:0}.accordion-item:first-of-type .accordion-button{border-top-left-radius:0;border-top-right-radius:0}.accordion-item:not(:first-of-type){border-top:0}.accordion-item:last-of-type{border-bottom-right-radius:0;border-bottom-left-radius:0}.accordion-item:last-of-type .accordion-button.collapsed{border-bottom-right-radius:0;border-bottom-left-radius:0}.accordion-item:last-of-type .accordion-collapse{border-bottom-right-radius:0;border-bottom-left-radius:0}.accordion-body{padding:1rem 1.25rem}.accordion-flush .accordion-collapse{border-width:0}.accordion-flush .accordion-item{border-right:0;border-left:0;border-radius:0}.accordion-flush .accordion-item:first-child{border-top:0}.accordion-flush .accordion-item:last-child{border-bottom:0}.accordion-flush .accordion-item .accordion-button{border-radius:0}.accordion-button::after,.accordion-button:not(.collapsed)::after{filter:var(--accordion-filter)}.accordion-button:disabled,.accordion-button.disabled{color:var(--t42-content-color-disabled)}.accordion-button:disabled::after,.accordion-button.disabled::after{opacity:0.25}.alert{position:relative;padding:.75rem .875rem;margin-bottom:.5rem;border:1px solid transparent;border-radius:0}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-right:2.625rem}.alert-dismissible .btn-close{position:absolute;top:0;right:0;z-index:2;padding:.9375rem .875rem}.alert-primary{color:#004a89;background-color:#cce5fa;border-color:#b3d7f7}.alert-primary .alert-link{color:#003b6e}.alert-secondary{color:#3a3a3a;background-color:#dfdfdf;border-color:#d0d0d0}.alert-secondary .alert-link{color:#2e2e2e}.alert-success{color:#28602b;background-color:#d9ecda;border-color:#c7e3c8}.alert-success .alert-link{color:#204d22}.alert-info{color:#2a5f6f;background-color:#daecf1;border-color:#c8e2ea}.alert-info .alert-link{color:#224c59}.alert-warning{color:#64430f;background-color:#feeed3;border-color:#fde5be}.alert-warning .alert-link{color:#50360c}.alert-danger{color:#993113;background-color:#ffdcd2;border-color:#ffcbbc}.alert-danger .alert-link{color:#7a270f}.alert-light{color:#3a3a3a;background-color:#dfdfdf;border-color:#d0d0d0}.alert-light .alert-link{color:#2e2e2e}.alert-dark{color:#3a3a3a;background-color:#dfdfdf;border-color:#d0d0d0}.alert-dark .alert-link{color:#2e2e2e}.alert{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border-color;position:relative;z-index:10000;display:flex;align-items:center;border:0.0625rem solid var(--t42-color-opacity-10);overflow:hidden;color:var(--t42-content-color);background-color:Rgba(var(--t42-bg-light), 0.75);background-repeat:no-repeat;background-size:100%;backdrop-filter:var(--backdrop-filter)}.alert h5{margin-bottom:0;color:var(--t42-content-color)}.alert p{margin-bottom:0}.alert-link{color:var(--t42-link-color);font-weight:normal}.alert-dismissible .close{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border-color;position:absolute;top:50%;right:0.75rem;width:1.5rem;height:1.5rem;padding:0;border:0;border-radius:50%;color:var(--t42-content-color);font-weight:700;font-size:1rem;line-height:1;background-color:var(--t42-color-opacity-05);transform:translateY(-50%);opacity:0.5}.alert-dismissible .close::before{position:relative;top:-1px}.alert-dismissible .close:hover{opacity:1}.alert::before{z-index:1;width:1.25rem;height:1.25rem;margin-right:0.875rem;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-position:center;mask-position:center;background-color:var(--t42-icon-color);content:""}.alert::after{position:absolute;top:0;left:0;z-index:-1;width:1px;height:1px;border-radius:50%;opacity:1;animation:color-pulse 3s infinite;content:""}.alert-primary:hover,.alert-secondary:hover,.alert-info:hover,.alert-light:hover,.alert-dark:hover{border-color:#616161}.alert-primary::after,.alert-secondary::after,.alert-info::after,.alert-light::after,.alert-dark::after{background:#616161;background:radial-gradient(circle, rgba(255,255,255,0.35) 0%, rgba(97,97,97,0.75) 60%, #616161 75%, #616161 100%)}.alert-primary::before,.alert-secondary::before,.alert-info::before,.alert-light::before,.alert-dark::before{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M260.6 484.4q0-4.1-4.6-4.1q-16.9 0-29.2-12.3t-11.8-29.2q0-4.6-4.6-4.6t-4.6 4.6q0 21 14.8 35.8t35.3 14.3q4.6 0 4.6-4.6zM493.6 402.4q0 14.8-10.8 25.6t-25.6 10.8h-128q0 30.2-21.5 51.7t-51.7 21.5t-51.7-21.5t-21.5-51.7h-128q-14.8 0-25.6-10.8t-10.8-25.6q14.3-12.3 26.1-25.1t24.1-34.3t21.5-45.6t13.8-58.9t5.6-74.2q0-43 33.8-80.4t87.6-45.6q-2.6-5.1-2.6-10.8q0-11.8 8.2-19.5t19.5-8.2t19.5 8.2t8.2 19.5q0 5.6-2.6 10.8q54.3 8.2 87.6 45.6t33.8 80.4q0 39.9 5.6 74.2t14.3 58.9t21 45.6t24.6 34.3t25.6 25.1z%27%3E%3C/path%3E%3C/svg%3E")}.alert-success:hover{border-color:#43a047}.alert-success::after{background:#43a047;background:radial-gradient(circle, rgba(255,255,255,0.35) 0%, rgba(67,160,71,0.75) 60%, #43a047 75%, #43a047 100%)}.alert-success::before{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M477.4 152.8q0 11.3-8.2 19.5l-245.8 245.8q-8.2 7.7-19.5 7.7t-19.5-7.7l-142.3-142.3q-7.7-8.2-7.7-19.5t7.7-19.5l38.9-38.9q8.2-8.2 19.5-8.2t19.5 8.2l84 84.5l187.4-187.9q8.2-8.2 19.5-8.2t19.5 8.2l38.9 38.9q8.2 7.7 8.2 19.5z%27%3E%3C/path%3E%3C/svg%3E")}.alert-warning:hover{border-color:#f9a825}.alert-warning::after{background:#f9a825;background:radial-gradient(circle, rgba(255,255,255,0.35) 0%, rgba(249,168,37,0.75) 60%, #f9a825 75%, #f9a825 100%)}.alert-warning::before{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M292.4 410.9v-54.3q0-4.1-2.6-6.7t-6.1-2.6h-55.3q-3.6 0-6.1 2.6t-2.6 6.7v54.3q0 4.1 2.6 6.7t6.1 3.1h55.3q3.6 0 6.1-3.1t2.6-6.7zM291.8 304.4l5.1-131.6q0-3.1-2.6-5.1q-3.6-3.1-7.2-3.1h-62.5q-3.1 0-7.2 3.1q-2.6 2-2.6 6.1l4.6 130.6q0 2.6 3.1 4.6t6.7 1.5h52.7q4.1 0 7.2-1.5t2.6-4.6zM288.3 37.1l219.1 402.4q10.2 17.9-.5 35.8q-4.6 8.7-13.3 13.3t-17.9 5.1h-439.3q-9.2 0-17.9-5.1t-13.3-13.3q-10.8-17.9-.5-35.8l219.6-402.4q4.6-8.7 13.3-13.8t18.4-5.1t18.4 5.1t13.8 13.8z%27%3E%3C/path%3E%3C/svg%3E%0A")}.alert-danger:hover{border-color:#ff511f}.alert-danger::after{background:#ff511f;background:radial-gradient(circle, rgba(255,255,255,0.35) 0%, rgba(255,81,31,0.75) 60%, #ff511f 75%, #ff511f 100%)}.alert-danger::before{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 402 512%27%3E%3Cpath d=%27M370.728 359.68q0 11.264-7.68 19.456l-38.912 38.912q-8.192 7.68-19.456 7.68t-19.456-7.68l-83.968-84.48-83.968 84.48q-8.192 7.68-19.456 7.68t-19.456-7.68l-38.912-38.912q-8.192-8.192-8.192-19.456t8.192-19.456l83.968-83.968-83.968-83.968q-8.192-8.192-8.192-19.456t8.192-19.456l38.912-38.912q8.192-8.192 19.456-8.192t19.456 8.192l83.968 83.968 83.968-83.968q8.192-8.192 19.456-8.192t19.456 8.192l38.912 38.912q7.68 7.68 7.68 19.456t-7.68 19.456l-83.968 83.968 83.968 83.968q7.68 7.68 7.68 19.456z%27%3E%3C/path%3E%3C/svg%3E")}@keyframes color-pulse{0%{transform:scale(1);opacity:1}50%{transform:scale(250);opacity:0}100%{opacity:0}}.badge{display:inline-block;padding:.2rem .5rem;font-size:.75em;font-weight:300;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:1rem}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.badge{border:var(--t42-border);color:var(--t42-link-color);backdrop-filter:var(--backdrop-filter)}.badge.bg-primary{border:0.0625rem solid #007be5;background-color:rgba(0,123,229,0.15) !important}.badge.bg-secondary{border:0.0625rem solid #616161;background-color:rgba(97,97,97,0.15) !important}.badge.bg-success{border:0.0625rem solid #43a047;background-color:rgba(67,160,71,0.15) !important}.badge.bg-info{border:0.0625rem solid #469eb9;background-color:rgba(70,158,185,0.15) !important}.badge.bg-warning{border:0.0625rem solid #f9a825;background-color:rgba(249,168,37,0.15) !important}.badge.bg-danger{border:0.0625rem solid #ff511f;background-color:rgba(255,81,31,0.15) !important}.badge.bg-light{border:0.0625rem solid #616161;background-color:rgba(97,97,97,0.15) !important}.badge.bg-dark{border:0.0625rem solid #616161;background-color:rgba(97,97,97,0.15) !important}button .badge{border:0.0625rem solid var(--t42-color-opacity-30)}button:hover .badge{color:var(--white)}.btn-close{box-sizing:content-box;width:1em;height:1em;padding:0 0;color:var(--t42-content-color);background:transparent url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 16 16%27 fill=%27var%28--t42-content-color%29%27%3e%3cpath d=%27M.293.293a1 1 0 011.414 0L8 6.586 14.293.293a1 1 0 111.414 1.414L9.414 8l6.293 6.293a1 1 0 01-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 01-1.414-1.414L6.586 8 .293 1.707a1 1 0 010-1.414z%27/%3e%3c/svg%3e") center/1em auto no-repeat;border:0;border-radius:.25rem;opacity:.5}.btn-close:hover{color:var(--t42-content-color);text-decoration:none;opacity:.75}.btn-close:focus{outline:0;box-shadow:0 0 0 0 rgba(0,123,229,0.25);opacity:1}.btn-close:disabled,.btn-close.disabled{pointer-events:none;user-select:none;opacity:.25}.btn-close-white{filter:invert(1) grayscale(100%) brightness(200%)}.btn{display:inline-block;font-weight:400;line-height:1.875rem;color:#212529;text-align:center;text-decoration:none;vertical-align:middle;cursor:pointer;user-select:none;background-color:transparent;border:1px solid transparent;padding:0 .875rem;font-size:.75rem;border-radius:0;transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.btn{transition:none}}.btn:hover{color:#212529}.btn-check:focus+.btn,.btn:focus{outline:0;box-shadow:0 0 0 0 rgba(0,123,229,0.25)}.btn:disabled,.btn.disabled,fieldset:disabled .btn{pointer-events:none;opacity:.35}.btn-primary{color:#000;background-color:#007be5;border-color:#007be5}.btn-primary:hover{color:#000;background-color:#268fe9;border-color:#1a88e8}.btn-check:focus+.btn-primary,.btn-primary:focus{color:#000;background-color:#268fe9;border-color:#1a88e8;box-shadow:0 0 0 0 rgba(0,105,195,0.5)}.btn-check:checked+.btn-primary,.btn-check:active+.btn-primary,.btn-primary:active,.btn-primary.active,.show>.btn-primary.dropdown-toggle{color:#000;background-color:#3395ea;border-color:#1a88e8}.btn-check:checked+.btn-primary:focus,.btn-check:active+.btn-primary:focus,.btn-primary:active:focus,.btn-primary.active:focus,.show>.btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(0,105,195,0.5)}.btn-primary:disabled,.btn-primary.disabled{color:#000;background-color:#007be5;border-color:#007be5}.btn-secondary{color:#fff;background-color:#616161;border-color:#616161}.btn-secondary:hover{color:#fff;background-color:#525252;border-color:#4e4e4e}.btn-check:focus+.btn-secondary,.btn-secondary:focus{color:#fff;background-color:#525252;border-color:#4e4e4e;box-shadow:0 0 0 0 rgba(121,121,121,0.5)}.btn-check:checked+.btn-secondary,.btn-check:active+.btn-secondary,.btn-secondary:active,.btn-secondary.active,.show>.btn-secondary.dropdown-toggle{color:#fff;background-color:#4e4e4e;border-color:#494949}.btn-check:checked+.btn-secondary:focus,.btn-check:active+.btn-secondary:focus,.btn-secondary:active:focus,.btn-secondary.active:focus,.show>.btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(121,121,121,0.5)}.btn-secondary:disabled,.btn-secondary.disabled{color:#fff;background-color:#616161;border-color:#616161}.btn-success{color:#000;background-color:#43a047;border-color:#43a047}.btn-success:hover{color:#000;background-color:#5fae63;border-color:#56aa59}.btn-check:focus+.btn-success,.btn-success:focus{color:#000;background-color:#5fae63;border-color:#56aa59;box-shadow:0 0 0 0 rgba(57,136,60,0.5)}.btn-check:checked+.btn-success,.btn-check:active+.btn-success,.btn-success:active,.btn-success.active,.show>.btn-success.dropdown-toggle{color:#000;background-color:#69b36c;border-color:#56aa59}.btn-check:checked+.btn-success:focus,.btn-check:active+.btn-success:focus,.btn-success:active:focus,.btn-success.active:focus,.show>.btn-success.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(57,136,60,0.5)}.btn-success:disabled,.btn-success.disabled{color:#000;background-color:#43a047;border-color:#43a047}.btn-info{color:#000;background-color:#469eb9;border-color:#469eb9}.btn-info:hover{color:#000;background-color:#62adc4;border-color:#59a8c0}.btn-check:focus+.btn-info,.btn-info:focus{color:#000;background-color:#62adc4;border-color:#59a8c0;box-shadow:0 0 0 0 rgba(60,134,157,0.5)}.btn-check:checked+.btn-info,.btn-check:active+.btn-info,.btn-info:active,.btn-info.active,.show>.btn-info.dropdown-toggle{color:#000;background-color:#6bb1c7;border-color:#59a8c0}.btn-check:checked+.btn-info:focus,.btn-check:active+.btn-info:focus,.btn-info:active:focus,.btn-info.active:focus,.show>.btn-info.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(60,134,157,0.5)}.btn-info:disabled,.btn-info.disabled{color:#000;background-color:#469eb9;border-color:#469eb9}.btn-warning{color:#000;background-color:#f9a825;border-color:#f9a825}.btn-warning:hover{color:#000;background-color:#fab546;border-color:#fab13b}.btn-check:focus+.btn-warning,.btn-warning:focus{color:#000;background-color:#fab546;border-color:#fab13b;box-shadow:0 0 0 0 rgba(212,143,31,0.5)}.btn-check:checked+.btn-warning,.btn-check:active+.btn-warning,.btn-warning:active,.btn-warning.active,.show>.btn-warning.dropdown-toggle{color:#000;background-color:#fab951;border-color:#fab13b}.btn-check:checked+.btn-warning:focus,.btn-check:active+.btn-warning:focus,.btn-warning:active:focus,.btn-warning.active:focus,.show>.btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(212,143,31,0.5)}.btn-warning:disabled,.btn-warning.disabled{color:#000;background-color:#f9a825;border-color:#f9a825}.btn-danger{color:#000;background-color:#ff511f;border-color:#ff511f}.btn-danger:hover{color:#000;background-color:#ff6b41;border-color:#ff6235}.btn-check:focus+.btn-danger,.btn-danger:focus{color:#000;background-color:#ff6b41;border-color:#ff6235;box-shadow:0 0 0 0 rgba(217,69,26,0.5)}.btn-check:checked+.btn-danger,.btn-check:active+.btn-danger,.btn-danger:active,.btn-danger.active,.show>.btn-danger.dropdown-toggle{color:#000;background-color:#ff744c;border-color:#ff6235}.btn-check:checked+.btn-danger:focus,.btn-check:active+.btn-danger:focus,.btn-danger:active:focus,.btn-danger.active:focus,.show>.btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(217,69,26,0.5)}.btn-danger:disabled,.btn-danger.disabled{color:#000;background-color:#ff511f;border-color:#ff511f}.btn-light{color:#fff;background-color:#616161;border-color:#616161}.btn-light:hover{color:#fff;background-color:#525252;border-color:#4e4e4e}.btn-check:focus+.btn-light,.btn-light:focus{color:#fff;background-color:#525252;border-color:#4e4e4e;box-shadow:0 0 0 0 rgba(121,121,121,0.5)}.btn-check:checked+.btn-light,.btn-check:active+.btn-light,.btn-light:active,.btn-light.active,.show>.btn-light.dropdown-toggle{color:#fff;background-color:#4e4e4e;border-color:#494949}.btn-check:checked+.btn-light:focus,.btn-check:active+.btn-light:focus,.btn-light:active:focus,.btn-light.active:focus,.show>.btn-light.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(121,121,121,0.5)}.btn-light:disabled,.btn-light.disabled{color:#fff;background-color:#616161;border-color:#616161}.btn-dark{color:#fff;background-color:#616161;border-color:#616161}.btn-dark:hover{color:#fff;background-color:#525252;border-color:#4e4e4e}.btn-check:focus+.btn-dark,.btn-dark:focus{color:#fff;background-color:#525252;border-color:#4e4e4e;box-shadow:0 0 0 0 rgba(121,121,121,0.5)}.btn-check:checked+.btn-dark,.btn-check:active+.btn-dark,.btn-dark:active,.btn-dark.active,.show>.btn-dark.dropdown-toggle{color:#fff;background-color:#4e4e4e;border-color:#494949}.btn-check:checked+.btn-dark:focus,.btn-check:active+.btn-dark:focus,.btn-dark:active:focus,.btn-dark.active:focus,.show>.btn-dark.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(121,121,121,0.5)}.btn-dark:disabled,.btn-dark.disabled{color:#fff;background-color:#616161;border-color:#616161}.btn-outline-primary{color:#007be5;border-color:#007be5}.btn-outline-primary:hover{color:#000;background-color:#007be5;border-color:#007be5}.btn-check:focus+.btn-outline-primary,.btn-outline-primary:focus{box-shadow:0 0 0 0 rgba(0,123,229,0.5)}.btn-check:checked+.btn-outline-primary,.btn-check:active+.btn-outline-primary,.btn-outline-primary:active,.btn-outline-primary.active,.btn-outline-primary.dropdown-toggle.show{color:#000;background-color:#007be5;border-color:#007be5}.btn-check:checked+.btn-outline-primary:focus,.btn-check:active+.btn-outline-primary:focus,.btn-outline-primary:active:focus,.btn-outline-primary.active:focus,.btn-outline-primary.dropdown-toggle.show:focus{box-shadow:0 0 0 0 rgba(0,123,229,0.5)}.btn-outline-primary:disabled,.btn-outline-primary.disabled{color:#007be5;background-color:transparent}.btn-outline-secondary{color:#616161;border-color:#616161}.btn-outline-secondary:hover{color:#fff;background-color:#616161;border-color:#616161}.btn-check:focus+.btn-outline-secondary,.btn-outline-secondary:focus{box-shadow:0 0 0 0 rgba(97,97,97,0.5)}.btn-check:checked+.btn-outline-secondary,.btn-check:active+.btn-outline-secondary,.btn-outline-secondary:active,.btn-outline-secondary.active,.btn-outline-secondary.dropdown-toggle.show{color:#fff;background-color:#616161;border-color:#616161}.btn-check:checked+.btn-outline-secondary:focus,.btn-check:active+.btn-outline-secondary:focus,.btn-outline-secondary:active:focus,.btn-outline-secondary.active:focus,.btn-outline-secondary.dropdown-toggle.show:focus{box-shadow:0 0 0 0 rgba(97,97,97,0.5)}.btn-outline-secondary:disabled,.btn-outline-secondary.disabled{color:#616161;background-color:transparent}.btn-outline-success{color:#43a047;border-color:#43a047}.btn-outline-success:hover{color:#000;background-color:#43a047;border-color:#43a047}.btn-check:focus+.btn-outline-success,.btn-outline-success:focus{box-shadow:0 0 0 0 rgba(67,160,71,0.5)}.btn-check:checked+.btn-outline-success,.btn-check:active+.btn-outline-success,.btn-outline-success:active,.btn-outline-success.active,.btn-outline-success.dropdown-toggle.show{color:#000;background-color:#43a047;border-color:#43a047}.btn-check:checked+.btn-outline-success:focus,.btn-check:active+.btn-outline-success:focus,.btn-outline-success:active:focus,.btn-outline-success.active:focus,.btn-outline-success.dropdown-toggle.show:focus{box-shadow:0 0 0 0 rgba(67,160,71,0.5)}.btn-outline-success:disabled,.btn-outline-success.disabled{color:#43a047;background-color:transparent}.btn-outline-info{color:#469eb9;border-color:#469eb9}.btn-outline-info:hover{color:#000;background-color:#469eb9;border-color:#469eb9}.btn-check:focus+.btn-outline-info,.btn-outline-info:focus{box-shadow:0 0 0 0 rgba(70,158,185,0.5)}.btn-check:checked+.btn-outline-info,.btn-check:active+.btn-outline-info,.btn-outline-info:active,.btn-outline-info.active,.btn-outline-info.dropdown-toggle.show{color:#000;background-color:#469eb9;border-color:#469eb9}.btn-check:checked+.btn-outline-info:focus,.btn-check:active+.btn-outline-info:focus,.btn-outline-info:active:focus,.btn-outline-info.active:focus,.btn-outline-info.dropdown-toggle.show:focus{box-shadow:0 0 0 0 rgba(70,158,185,0.5)}.btn-outline-info:disabled,.btn-outline-info.disabled{color:#469eb9;background-color:transparent}.btn-outline-warning{color:#f9a825;border-color:#f9a825}.btn-outline-warning:hover{color:#000;background-color:#f9a825;border-color:#f9a825}.btn-check:focus+.btn-outline-warning,.btn-outline-warning:focus{box-shadow:0 0 0 0 rgba(249,168,37,0.5)}.btn-check:checked+.btn-outline-warning,.btn-check:active+.btn-outline-warning,.btn-outline-warning:active,.btn-outline-warning.active,.btn-outline-warning.dropdown-toggle.show{color:#000;background-color:#f9a825;border-color:#f9a825}.btn-check:checked+.btn-outline-warning:focus,.btn-check:active+.btn-outline-warning:focus,.btn-outline-warning:active:focus,.btn-outline-warning.active:focus,.btn-outline-warning.dropdown-toggle.show:focus{box-shadow:0 0 0 0 rgba(249,168,37,0.5)}.btn-outline-warning:disabled,.btn-outline-warning.disabled{color:#f9a825;background-color:transparent}.btn-outline-danger{color:#ff511f;border-color:#ff511f}.btn-outline-danger:hover{color:#000;background-color:#ff511f;border-color:#ff511f}.btn-check:focus+.btn-outline-danger,.btn-outline-danger:focus{box-shadow:0 0 0 0 rgba(255,81,31,0.5)}.btn-check:checked+.btn-outline-danger,.btn-check:active+.btn-outline-danger,.btn-outline-danger:active,.btn-outline-danger.active,.btn-outline-danger.dropdown-toggle.show{color:#000;background-color:#ff511f;border-color:#ff511f}.btn-check:checked+.btn-outline-danger:focus,.btn-check:active+.btn-outline-danger:focus,.btn-outline-danger:active:focus,.btn-outline-danger.active:focus,.btn-outline-danger.dropdown-toggle.show:focus{box-shadow:0 0 0 0 rgba(255,81,31,0.5)}.btn-outline-danger:disabled,.btn-outline-danger.disabled{color:#ff511f;background-color:transparent}.btn-outline-light{color:#616161;border-color:#616161}.btn-outline-light:hover{color:#fff;background-color:#616161;border-color:#616161}.btn-check:focus+.btn-outline-light,.btn-outline-light:focus{box-shadow:0 0 0 0 rgba(97,97,97,0.5)}.btn-check:checked+.btn-outline-light,.btn-check:active+.btn-outline-light,.btn-outline-light:active,.btn-outline-light.active,.btn-outline-light.dropdown-toggle.show{color:#fff;background-color:#616161;border-color:#616161}.btn-check:checked+.btn-outline-light:focus,.btn-check:active+.btn-outline-light:focus,.btn-outline-light:active:focus,.btn-outline-light.active:focus,.btn-outline-light.dropdown-toggle.show:focus{box-shadow:0 0 0 0 rgba(97,97,97,0.5)}.btn-outline-light:disabled,.btn-outline-light.disabled{color:#616161;background-color:transparent}.btn-outline-dark{color:#616161;border-color:#616161}.btn-outline-dark:hover{color:#fff;background-color:#616161;border-color:#616161}.btn-check:focus+.btn-outline-dark,.btn-outline-dark:focus{box-shadow:0 0 0 0 rgba(97,97,97,0.5)}.btn-check:checked+.btn-outline-dark,.btn-check:active+.btn-outline-dark,.btn-outline-dark:active,.btn-outline-dark.active,.btn-outline-dark.dropdown-toggle.show{color:#fff;background-color:#616161;border-color:#616161}.btn-check:checked+.btn-outline-dark:focus,.btn-check:active+.btn-outline-dark:focus,.btn-outline-dark:active:focus,.btn-outline-dark.active:focus,.btn-outline-dark.dropdown-toggle.show:focus{box-shadow:0 0 0 0 rgba(97,97,97,0.5)}.btn-outline-dark:disabled,.btn-outline-dark.disabled{color:#616161;background-color:transparent}.btn-link{font-weight:400;color:var(--t42-link-color);text-decoration:underline}.btn-link:hover{color:var(--t42-link-hover-color)}.btn-link:disabled,.btn-link.disabled{color:#6c757d}.btn-lg,.btn-group-lg>.btn{padding:0 .875rem;font-size:.75rem;border-radius:0}.btn-sm,.btn-group-sm>.btn{padding:0 .875rem;font-size:.75rem;border-radius:0}.btn-group,.btn-group-vertical{position:relative;display:inline-flex;vertical-align:middle}.btn-group>.btn,.btn-group-vertical>.btn{position:relative;flex:1 1 auto}.btn-group>.btn-check:checked+.btn,.btn-group>.btn-check:focus+.btn,.btn-group>.btn:hover,.btn-group>.btn:focus,.btn-group>.btn:active,.btn-group>.btn.active,.btn-group-vertical>.btn-check:checked+.btn,.btn-group-vertical>.btn-check:focus+.btn,.btn-group-vertical>.btn:hover,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn.active{z-index:1}.btn-toolbar{display:flex;flex-wrap:wrap;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group>.btn:not(:first-child),.btn-group>.btn-group:not(:first-child){margin-left:-1px}.btn-group>.btn:not(:last-child):not(.dropdown-toggle),.btn-group>.btn-group:not(:last-child)>.btn{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:nth-child(n+3),.btn-group>:not(.btn-check)+.btn,.btn-group>.btn-group:not(:first-child)>.btn{border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.65625rem;padding-left:.65625rem}.dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after,.dropend .dropdown-toggle-split::after{margin-left:0}.dropstart .dropdown-toggle-split::before{margin-right:0}.btn-sm+.dropdown-toggle-split,.btn-group-sm>.btn+.dropdown-toggle-split{padding-right:.65625rem;padding-left:.65625rem}.btn-lg+.dropdown-toggle-split,.btn-group-lg>.btn+.dropdown-toggle-split{padding-right:.65625rem;padding-left:.65625rem}.btn-group-vertical{flex-direction:column;align-items:flex-start;justify-content:center}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn:not(:first-child),.btn-group-vertical>.btn-group:not(:first-child){margin-top:-1px}.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle),.btn-group-vertical>.btn-group:not(:last-child)>.btn{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn ~ .btn,.btn-group-vertical>.btn-group:not(:first-child)>.btn{border-top-left-radius:0;border-top-right-radius:0}button,button:focus{outline:none}.btn{color:var(--t42-link-color);transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, border-color;cursor:default}.btn.disabled,.btn:disabled{color:var(--t42-link-color);cursor:default}.btn:not(.disabled):not(:disabled).active,.btn:not(.disabled):not(:disabled):hover{border-color:var(--t42-color-opacity-30);color:var(--white);backdrop-filter:var(--backdrop-filter)}.btn:focus,.btn:active{color:var(--white)}.btn-primary{background-color:rgba(0,123,229,0.05)}.btn-primary.disabled,.btn-primary:disabled{background-color:rgba(0,123,229,0.05)}.btn-primary:not(.disabled):not(:disabled).active,.btn-primary:not(.disabled):not(:disabled):hover{background-color:#007be5}.btn-primary:not(.disabled):not(:disabled).btn-icon.active,.btn-primary:not(.disabled):not(:disabled).btn-icon:focus,.btn-primary:not(.disabled):not(:disabled).btn-icon:hover{color:var(--white)}.btn-primary.dropdown-toggle.active,.btn-primary.dropdown-toggle:active,.btn-primary.dropdown-toggle:focus{border-color:var(--t42-color-opacity-30);background-color:#007be5}.btn-secondary{background-color:rgba(97,97,97,0.05)}.btn-secondary.disabled,.btn-secondary:disabled{background-color:rgba(97,97,97,0.05)}.btn-secondary:not(.disabled):not(:disabled).active,.btn-secondary:not(.disabled):not(:disabled):hover{background-color:#616161}.btn-secondary:not(.disabled):not(:disabled).btn-icon.active,.btn-secondary:not(.disabled):not(:disabled).btn-icon:focus,.btn-secondary:not(.disabled):not(:disabled).btn-icon:hover{color:var(--white)}.btn-secondary.dropdown-toggle.active,.btn-secondary.dropdown-toggle:active,.btn-secondary.dropdown-toggle:focus{border-color:var(--t42-color-opacity-30);background-color:#616161}.btn-success{background-color:rgba(67,160,71,0.05)}.btn-success.disabled,.btn-success:disabled{background-color:rgba(67,160,71,0.05)}.btn-success:not(.disabled):not(:disabled).active,.btn-success:not(.disabled):not(:disabled):hover{background-color:#43a047}.btn-success:not(.disabled):not(:disabled).btn-icon.active,.btn-success:not(.disabled):not(:disabled).btn-icon:focus,.btn-success:not(.disabled):not(:disabled).btn-icon:hover{color:var(--white)}.btn-success.dropdown-toggle.active,.btn-success.dropdown-toggle:active,.btn-success.dropdown-toggle:focus{border-color:var(--t42-color-opacity-30);background-color:#43a047}.btn-info{background-color:rgba(70,158,185,0.05)}.btn-info.disabled,.btn-info:disabled{background-color:rgba(70,158,185,0.05)}.btn-info:not(.disabled):not(:disabled).active,.btn-info:not(.disabled):not(:disabled):hover{background-color:#469eb9}.btn-info:not(.disabled):not(:disabled).btn-icon.active,.btn-info:not(.disabled):not(:disabled).btn-icon:focus,.btn-info:not(.disabled):not(:disabled).btn-icon:hover{color:var(--white)}.btn-info.dropdown-toggle.active,.btn-info.dropdown-toggle:active,.btn-info.dropdown-toggle:focus{border-color:var(--t42-color-opacity-30);background-color:#469eb9}.btn-warning{background-color:rgba(249,168,37,0.05)}.btn-warning.disabled,.btn-warning:disabled{background-color:rgba(249,168,37,0.05)}.btn-warning:not(.disabled):not(:disabled).active,.btn-warning:not(.disabled):not(:disabled):hover{background-color:#f9a825}.btn-warning:not(.disabled):not(:disabled).btn-icon.active,.btn-warning:not(.disabled):not(:disabled).btn-icon:focus,.btn-warning:not(.disabled):not(:disabled).btn-icon:hover{color:var(--white)}.btn-warning.dropdown-toggle.active,.btn-warning.dropdown-toggle:active,.btn-warning.dropdown-toggle:focus{border-color:var(--t42-color-opacity-30);background-color:#f9a825}.btn-danger{background-color:rgba(255,81,31,0.05)}.btn-danger.disabled,.btn-danger:disabled{background-color:rgba(255,81,31,0.05)}.btn-danger:not(.disabled):not(:disabled).active,.btn-danger:not(.disabled):not(:disabled):hover{background-color:#ff511f}.btn-danger:not(.disabled):not(:disabled).btn-icon.active,.btn-danger:not(.disabled):not(:disabled).btn-icon:focus,.btn-danger:not(.disabled):not(:disabled).btn-icon:hover{color:var(--white)}.btn-danger.dropdown-toggle.active,.btn-danger.dropdown-toggle:active,.btn-danger.dropdown-toggle:focus{border-color:var(--t42-color-opacity-30);background-color:#ff511f}.btn-light{background-color:rgba(97,97,97,0.05)}.btn-light.disabled,.btn-light:disabled{background-color:rgba(97,97,97,0.05)}.btn-light:not(.disabled):not(:disabled).active,.btn-light:not(.disabled):not(:disabled):hover{background-color:#616161}.btn-light:not(.disabled):not(:disabled).btn-icon.active,.btn-light:not(.disabled):not(:disabled).btn-icon:focus,.btn-light:not(.disabled):not(:disabled).btn-icon:hover{color:var(--white)}.btn-light.dropdown-toggle.active,.btn-light.dropdown-toggle:active,.btn-light.dropdown-toggle:focus{border-color:var(--t42-color-opacity-30);background-color:#616161}.btn-dark{background-color:rgba(97,97,97,0.05)}.btn-dark.disabled,.btn-dark:disabled{background-color:rgba(97,97,97,0.05)}.btn-dark:not(.disabled):not(:disabled).active,.btn-dark:not(.disabled):not(:disabled):hover{background-color:#616161}.btn-dark:not(.disabled):not(:disabled).btn-icon.active,.btn-dark:not(.disabled):not(:disabled).btn-icon:focus,.btn-dark:not(.disabled):not(:disabled).btn-icon:hover{color:var(--white)}.btn-dark.dropdown-toggle.active,.btn-dark.dropdown-toggle:active,.btn-dark.dropdown-toggle:focus{border-color:var(--t42-color-opacity-30);background-color:#616161}.btn-link{text-decoration:none;backdrop-filter:none}.btn-link:not(.disabled):not(:disabled).active,.btn-link:not(.disabled):not(:disabled):focus,.btn-link:not(.disabled):not(:disabled):hover{border-color:transparent;color:var(--t42-link-color);text-decoration:underline}.btn-icon:not(.disabled):not(:disabled).active,.btn-icon:not(.disabled):not(:disabled):focus,.btn-icon:not(.disabled):not(:disabled):hover{color:var(--t42-link-color)}.btn-icon-action{display:flex;justify-content:center;width:1rem;height:1rem;padding:0;border-radius:50%;font-size:0.75rem;transition:all .2s ease-in-out}@media (prefers-reduced-motion: reduce){.btn-icon-action{transition:none}}.btn-icon-action:not(.disabled):not(:disabled).active,.btn-icon-action:not(.disabled):not(:disabled):hover,.btn-icon-action:not(.disabled):not(:disabled):focus{border-color:transparent;background-color:Rgb(var(--t42-bg-light));box-shadow:var(--t42-shadow)}.btn-icon-action-right{position:absolute;right:0.25rem}.btn-icon-action-show-hover{transition:all .2s ease-in-out}@media (prefers-reduced-motion: reduce){.btn-icon-action-show-hover{transition:none}}.btn-icon-action-show-hover .btn-icon-action{opacity:0}.btn-icon-action-show-hover:not(.disabled):not(:disabled):hover .btn-icon-action{opacity:1}.btn-close{width:1rem;height:1rem;filter:var(--filter-close)}.breadcrumb{display:flex;flex-wrap:wrap;padding:0 0;margin-bottom:.5rem;list-style:none;background-color:rgba(0,0,0,0)}.breadcrumb-item+.breadcrumb-item{padding-left:.5rem}.breadcrumb-item+.breadcrumb-item::before{float:left;padding-right:.5rem;color:#6c757d;content:var(--bs-breadcrumb-divider, "/") /* rtl: var(--bs-breadcrumb-divider, "/") */}.breadcrumb-item.active{color:var(--t42-link-color)}.breadcrumb-item{font-size:83.3%}.breadcrumb-item.active{text-decoration:underline}.breadcrumb-item+.breadcrumb-item{padding-left:0}.breadcrumb-item+.breadcrumb-item::before{position:relative;top:0.063rem;left:0.063rem;width:0.75rem;height:0.75rem;background-color:var(--t42-content-color);content:"";-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M339.2,256.3c0,2.4-0.9,4.4-2.6,6.1L203,396c-1.7,1.7-3.8,2.6-6.1,2.6c-2.4,0-4.6-0.9-6.7-2.6l-14.3-14.3 c-2-2-3.1-4.3-3.1-6.7s1-4.6,3.1-6.7L288,256.3L175.9,143.6c-2-1.7-3.1-3.8-3.1-6.1s1-4.6,3.1-6.7l14.3-14.3c1.7-2,3.9-3.1,6.7-3.1 s4.8,1,6.1,3.1l133.6,133.1C338.3,251.3,339.2,253.5,339.2,256.3L339.2,256.3z%27/%3E%3C/svg%3E")}mark,.mark{color:var(--white)}pre{background-color:var(--t42-bg-dark)}blockquote,.blockquote{padding:1rem 1rem 0.01rem;border-left:0.25rem solid var(--secondary);background-color:Rgb(var(--t42-bg-dark))}.blockquote-footer{margin-top:-2rem;margin-left:1.25rem;color:var(--t42-content-color-muted);font-size:0.875em}pre{border:0.0625rem solid var(--t42-color-opacity-10)}.card{position:relative;display:flex;flex-direction:column;min-width:0;word-wrap:break-word;background-color:Rgba(var(--t42-bg-light), 0.75);background-clip:border-box;border:1px solid var(--t42-color-opacity-10);border-radius:0}.card>hr{margin-right:0;margin-left:0}.card>.list-group{border-top:inherit;border-bottom:inherit}.card>.list-group:first-child{border-top-width:0;border-top-left-radius:0;border-top-right-radius:0}.card>.list-group:last-child{border-bottom-width:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.card>.card-header+.list-group,.card>.list-group+.card-footer{border-top:0}.card-body{flex:1 1 auto;padding:1.25rem 1.25rem}.card-title{margin-bottom:.5rem}.card-subtitle{margin-top:-.25rem;margin-bottom:0}.card-text:last-child{margin-bottom:0}.card-link+.card-link{margin-left:1.25rem}.card-header{padding:.625rem 1.25rem;margin-bottom:0;color:var(--t42-link-color);background-color:rgba(0,0,0,0);border-bottom:1px solid var(--t42-color-opacity-10)}.card-header:first-child{border-radius:0 0 0 0}.card-footer{padding:.625rem 1.25rem;color:var(--t42-link-color);background-color:rgba(0,0,0,0);border-top:1px solid var(--t42-color-opacity-10)}.card-footer:last-child{border-radius:0 0 0 0}.card-header-tabs{margin-right:-.625rem;margin-bottom:-.625rem;margin-left:-.625rem;border-bottom:0}.card-header-tabs .nav-link.active{background-color:Rgba(var(--t42-bg-light), 0.75);border-bottom-color:Rgba(var(--t42-bg-light), 0.75)}.card-header-pills{margin-right:-.625rem;margin-left:-.625rem}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1rem;border-radius:0}.card-img,.card-img-top,.card-img-bottom{width:100%}.card-img,.card-img-top{border-top-left-radius:0;border-top-right-radius:0}.card-img,.card-img-bottom{border-bottom-right-radius:0;border-bottom-left-radius:0}.card-group>.card{margin-bottom:.75rem}@media (min-width: 576px){.card-group{display:flex;flex-flow:row wrap}.card-group>.card{flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:not(:last-child) .card-img-top,.card-group>.card:not(:last-child) .card-header{border-top-right-radius:0}.card-group>.card:not(:last-child) .card-img-bottom,.card-group>.card:not(:last-child) .card-footer{border-bottom-right-radius:0}.card-group>.card:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:not(:first-child) .card-img-top,.card-group>.card:not(:first-child) .card-header{border-top-left-radius:0}.card-group>.card:not(:first-child) .card-img-bottom,.card-group>.card:not(:first-child) .card-footer{border-bottom-left-radius:0}}.card{box-shadow:var(--t42-shadow);backdrop-filter:var(--backdrop-filter)}.card .card-header{border-bottom-width:0}.card .card-subtitle{margin-bottom:0.5rem;font-size:83.3%}.card.bg-primary{background-color:transparent !important}.card.bg-primary .card-header{background-color:Rgba(var(--t42-bg-mid), 0.75)}.card.bg-primary .card-body{background-color:Rgba(var(--t42-bg-light), 0.75)}.card.bg-secondary{background-color:transparent !important}.card.bg-secondary .card-header{background-color:Rgba(var(--t42-bg-light), 0.75)}.card.bg-secondary .card-body{background-color:Rgba(var(--t42-bg-mid), 0.75)}.card:not(.bg-primary):not(.bg-secondary) .card-header+.card-body{padding-top:0}.card-header-tabs{margin-bottom:0}.accordion .card:first-of-type,.accordion .card:not(:first-of-type):not(:last-of-type){margin-bottom:0.5rem;border-bottom:var(--t42-border)}.accordion .card-header{position:relative;padding:0}.accordion .card-header .btn-link{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;width:100%;padding:0.75rem 2rem;line-height:1.4;text-align:left}.accordion .card-header .btn-link::before{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:transform;position:absolute;display:inline-block;width:0.75rem;height:0.75rem;background-color:var(--t42-content-color);transform:translateX(-1rem) translateY(0.063rem) rotate(-90deg);content:"";-webkit-mask-image:var(--t42-select-indicator)}.accordion .card-header .btn-link:hover{backdrop-filter:none}.accordion .card-header .btn-link.collapsed::before{transform:translateX(-1rem) translateY(0.063rem)}.accordion .card-header .btn-link.disabled::before,.accordion .card-header .btn-link:disabled::before{opacity:.35}.accordion .card-body{padding:0 1.25rem 1.25rem}.accordion .bg-primary .card-body,.accordion .bg-secondary .card-body{padding:1.25rem}.dropup,.dropend,.dropdown,.dropstart{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:0;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{position:absolute;z-index:1000;display:none;min-width:10rem;padding:0 0;margin:0;font-size:.75rem;color:var(--t42-content-color);text-align:left;list-style:none;background-color:Rgba(var(--t42-bg-light), 0.75);background-clip:padding-box;border:1px solid var(--t42-color-opacity-10);border-radius:0}.dropdown-menu[data-bs-popper]{top:100%;left:0;margin-top:.125rem}.dropdown-menu-start{--bs-position: start}.dropdown-menu-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-end{--bs-position: end}.dropdown-menu-end[data-bs-popper]{right:0;left:auto}@media (min-width: 576px){.dropdown-menu-sm-start{--bs-position: start}.dropdown-menu-sm-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-sm-end{--bs-position: end}.dropdown-menu-sm-end[data-bs-popper]{right:0;left:auto}}@media (min-width: 768px){.dropdown-menu-md-start{--bs-position: start}.dropdown-menu-md-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-md-end{--bs-position: end}.dropdown-menu-md-end[data-bs-popper]{right:0;left:auto}}@media (min-width: 992px){.dropdown-menu-lg-start{--bs-position: start}.dropdown-menu-lg-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-lg-end{--bs-position: end}.dropdown-menu-lg-end[data-bs-popper]{right:0;left:auto}}@media (min-width: 1200px){.dropdown-menu-xl-start{--bs-position: start}.dropdown-menu-xl-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-xl-end{--bs-position: end}.dropdown-menu-xl-end[data-bs-popper]{right:0;left:auto}}@media (min-width: 1400px){.dropdown-menu-xxl-start{--bs-position: start}.dropdown-menu-xxl-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-xxl-end{--bs-position: end}.dropdown-menu-xxl-end[data-bs-popper]{right:0;left:auto}}.dropup .dropdown-menu[data-bs-popper]{top:auto;bottom:100%;margin-top:0;margin-bottom:.125rem}.dropup .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:0;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropend .dropdown-menu[data-bs-popper]{top:0;right:auto;left:100%;margin-top:0;margin-left:.125rem}.dropend .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:0;content:"";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid}.dropend .dropdown-toggle:empty::after{margin-left:0}.dropend .dropdown-toggle::after{vertical-align:0}.dropstart .dropdown-menu[data-bs-popper]{top:0;right:100%;left:auto;margin-top:0;margin-right:.125rem}.dropstart .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:0;content:""}.dropstart .dropdown-toggle::after{display:none}.dropstart .dropdown-toggle::before{display:inline-block;margin-right:.255em;vertical-align:0;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropstart .dropdown-toggle:empty::after{margin-left:0}.dropstart .dropdown-toggle::before{vertical-align:0}.dropdown-divider{height:0;margin:0 0;overflow:hidden;border-top:1px solid var(--t42-color-opacity-10)}.dropdown-item{display:block;width:100%;padding:.375rem 1rem;clear:both;font-weight:400;color:var(--t42-content-color);text-align:inherit;text-decoration:none;white-space:nowrap;background-color:transparent;border:0}.dropdown-item:first-child{border-top-left-radius:0;border-top-right-radius:0}.dropdown-item:last-child{border-bottom-right-radius:0;border-bottom-left-radius:0}.dropdown-item:hover,.dropdown-item:focus{color:var(--t42-link-hover-color);background-color:var(--t42-link-hover-bg)}.dropdown-item.active,.dropdown-item:active{color:var(--t42-link-hover-color);text-decoration:none;background-color:var(--t42-link-active-bg)}.dropdown-item.disabled,.dropdown-item:disabled{color:#adb5bd;pointer-events:none;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:0 1rem;margin-bottom:0;font-size:.65625rem;color:shade-color(#616161, 10%);white-space:nowrap}.dropdown-item-text{display:block;padding:.375rem 1rem;color:var(--t42-content-color)}.dropdown-menu-dark{color:#dee2e6;background-color:#343a40;border-color:var(--t42-color-opacity-10)}.dropdown-menu-dark .dropdown-item{color:#dee2e6}.dropdown-menu-dark .dropdown-item:hover,.dropdown-menu-dark .dropdown-item:focus{color:#fff;background-color:rgba(255,255,255,0.15)}.dropdown-menu-dark .dropdown-item.active,.dropdown-menu-dark .dropdown-item:active{color:var(--t42-link-hover-color);background-color:var(--t42-link-active-bg)}.dropdown-menu-dark .dropdown-item.disabled,.dropdown-menu-dark .dropdown-item:disabled{color:#adb5bd}.dropdown-menu-dark .dropdown-divider{border-color:var(--t42-color-opacity-10)}.dropdown-menu-dark .dropdown-item-text{color:#dee2e6}.dropdown-menu-dark .dropdown-header{color:#adb5bd}.dropdown-menu{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:opacity, visability;display:block;visibility:hidden;opacity:0;backdrop-filter:var(--backdrop-filter)}.dropdown-menu.show{visibility:visible;opacity:1}.dropdown-toggle::after{position:relative;width:0.5rem;height:0.5rem;border:0;background-color:var(--t42-link-color);content:"";-webkit-mask-image:url("data:image/svg+xml,%3Csvg version=%271.1%27 xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M480.768 186.88l-211.968 211.456q-5.12 5.632-12.8 5.632t-12.8-5.632l-211.968-211.456q-5.632-5.632-5.632-13.312t5.632-12.8l47.616-47.104q5.12-5.632 12.8-5.632t12.8 5.632l151.552 151.552 151.552-151.552q5.632-5.632 12.8-5.632t13.312 5.632l47.104 47.104q5.632 5.632 5.632 12.8t-5.632 13.312z%27%3E%3C/path%3E%3C/svg%3E")}.dropdown-toggle.show::after{color:var(--white)}.dropup .dropdown-toggle::after{position:relative;top:0.188rem;width:0.5rem;height:0.5rem;border:0;background-color:var(--t42-link-color);content:"";-webkit-mask-image:url("data:image/svg+xml,%3Csvg version=%271.1%27 xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M480.768 351.488l-47.104 47.104q-5.632 5.12-13.312 5.12t-12.8-5.12l-151.552-152.064-151.552 152.064q-5.632 5.12-12.8 5.12t-12.8-5.12l-47.616-47.104q-5.632-5.632-5.632-13.312t5.632-12.8l211.968-211.968q5.632-5.12 12.8-5.12t12.8 5.12l211.968 211.968q5.632 5.632 5.632 12.8t-5.632 13.312z%27%3E%3C/path%3E%3C/svg%3E%0A")}.form-label{margin-bottom:.5rem}.col-form-label{padding-top:1px;padding-bottom:1px;margin-bottom:0;font-size:inherit;line-height:1.875rem}.col-form-label-lg{padding-top:1px;padding-bottom:1px;font-size:.75rem}.col-form-label-sm{padding-top:1px;padding-bottom:1px;font-size:.75rem}.form-text{margin-top:.25rem;font-size:.875em;color:var(--t42-content-color-muted)}.form-control{display:block;width:100%;padding:0 .875rem;font-size:.75rem;font-weight:400;line-height:1.875rem;color:var(--t42-link-color);background-color:var(--t42-input-bg);background-clip:padding-box;border:1px solid var(--t42-color-opacity-10);appearance:none;border-radius:0;transition:border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.form-control{transition:none}}.form-control[type="file"]{overflow:hidden}.form-control[type="file"]:not(:disabled):not([readonly]){cursor:pointer}.form-control:focus{color:var(--t42-link-color);background-color:var(--t42-input-bg);border-color:#007be5;outline:0;box-shadow:0 0 0 0 rgba(0,123,229,0.25)}.form-control::-webkit-date-and-time-value{height:1.875rem}.form-control::placeholder{color:var(--t42-content-color-muted);opacity:1}.form-control:disabled,.form-control[readonly]{background-color:var(--t42-input-disabled-bg);opacity:1}.form-control::file-selector-button{padding:0 .875rem;margin:0 -.875rem;margin-inline-end:.875rem;color:var(--t42-link-color);background-color:#e9ecef;pointer-events:none;border-color:inherit;border-style:solid;border-width:0;border-inline-end-width:1px;border-radius:0;transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.form-control::file-selector-button{transition:none}}.form-control:hover:not(:disabled):not([readonly])::file-selector-button{background-color:#dde0e3}.form-control::-webkit-file-upload-button{padding:0 .875rem;margin:0 -.875rem;margin-inline-end:.875rem;color:var(--t42-link-color);background-color:#e9ecef;pointer-events:none;border-color:inherit;border-style:solid;border-width:0;border-inline-end-width:1px;border-radius:0;transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.form-control::-webkit-file-upload-button{transition:none}}.form-control:hover:not(:disabled):not([readonly])::-webkit-file-upload-button{background-color:#dde0e3}.form-control-plaintext{display:block;width:100%;padding:0 0;margin-bottom:0;line-height:1.875rem;color:var(--t42-content-color);background-color:transparent;border:solid transparent;border-width:1px 0}.form-control-plaintext.form-control-sm,.form-control-plaintext.form-control-lg{padding-right:0;padding-left:0}.form-control-sm{min-height:2rem;padding:0 .875rem;font-size:.75rem;border-radius:0}.form-control-sm::file-selector-button{padding:0 .875rem;margin:0 -.875rem;margin-inline-end:.875rem}.form-control-sm::-webkit-file-upload-button{padding:0 .875rem;margin:0 -.875rem;margin-inline-end:.875rem}.form-control-lg{min-height:2rem;padding:0 .875rem;font-size:.75rem;border-radius:0}.form-control-lg::file-selector-button{padding:0 .875rem;margin:0 -.875rem;margin-inline-end:.875rem}.form-control-lg::-webkit-file-upload-button{padding:0 .875rem;margin:0 -.875rem;margin-inline-end:.875rem}textarea.form-control{min-height:2rem}textarea.form-control-sm{min-height:2rem}textarea.form-control-lg{min-height:2rem}.form-control-color{width:3rem;height:auto;padding:0}.form-control-color:not(:disabled):not([readonly]){cursor:pointer}.form-control-color::-moz-color-swatch{height:1.875rem;border-radius:0}.form-control-color::-webkit-color-swatch{height:1.875rem;border-radius:0}.form-select{display:block;width:100%;padding:0 2.625rem 0 .875rem;-moz-padding-start:calc(.875rem - 3px);font-size:.75rem;font-weight:400;line-height:1.875rem;color:var(--t42-link-color);background-color:var(--t42-input-bg);background-image:var(--t42-select-indicator);background-repeat:no-repeat;background-position:right 0.5rem center;background-size:1rem;border:1px solid var(--t42-color-opacity-10);border-radius:0;transition:border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out;appearance:none}@media (prefers-reduced-motion: reduce){.form-select{transition:none}}.form-select:focus{border-color:#007be5;outline:0;box-shadow:0 0 0 0 rgba(0,123,229,0.25)}.form-select[multiple],.form-select[size]:not([size="1"]){padding-right:.875rem;background-image:none}.form-select:disabled{background-color:#e9ecef}.form-select:-moz-focusring{color:transparent;text-shadow:0 0 0 var(--t42-link-color)}.form-select-sm{padding-top:0;padding-bottom:0;padding-left:.875rem;font-size:.75rem;border-radius:0}.form-select-lg{padding-top:0;padding-bottom:0;padding-left:.875rem;font-size:.75rem;border-radius:0}.form-check{display:block;min-height:1.125rem;padding-left:1.25rem;margin-bottom:0}.form-check .form-check-input{float:left;margin-left:-1.25rem}.form-check-input{width:1em;height:1em;margin-top:.25em;vertical-align:top;background-color:var(--t42-input-bg);background-repeat:no-repeat;background-position:center;background-size:contain;border:1px solid rgba(0,0,0,0.25);appearance:none;color-adjust:exact}.form-check-input[type="checkbox"]{border-radius:.25em}.form-check-input[type="radio"]{border-radius:50%}.form-check-input:active{filter:brightness(90%)}.form-check-input:focus{border-color:#007be5;outline:0;box-shadow:0 0 0 0 rgba(0,123,229,0.25)}.form-check-input:checked{background-color:#007be5;border-color:#007be5}.form-check-input:checked[type="checkbox"]{background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 20 20%27%3e%3cpath fill=%27none%27 stroke=%27%23fff%27 stroke-linecap=%27round%27 stroke-linejoin=%27round%27 stroke-width=%273%27 d=%27M6 10l3 3l6-6%27/%3e%3c/svg%3e")}.form-check-input:checked[type="radio"]{background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%27-4 -4 8 8%27%3e%3ccircle r=%272%27 fill=%27%23fff%27/%3e%3c/svg%3e")}.form-check-input[type="checkbox"]:indeterminate{background-color:#007be5;border-color:#007be5;background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 20 20%27%3e%3cpath fill=%27none%27 stroke=%27%23fff%27 stroke-linecap=%27round%27 stroke-linejoin=%27round%27 stroke-width=%273%27 d=%27M6 10h8%27/%3e%3c/svg%3e")}.form-check-input:disabled{pointer-events:none;filter:none;opacity:.5}.form-check-input[disabled] ~ .form-check-label,.form-check-input:disabled ~ .form-check-label{opacity:.5}.form-switch{padding-left:2.5em}.form-switch .form-check-input{width:2em;margin-left:-2.5em;background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%27-4 -4 8 8%27%3e%3ccircle r=%273%27 fill=%27rgba%280,0,0,0.25%29%27/%3e%3c/svg%3e");background-position:left center;border-radius:2em;transition:background-position 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.form-switch .form-check-input{transition:none}}.form-switch .form-check-input:focus{background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%27-4 -4 8 8%27%3e%3ccircle r=%273%27 fill=%27%23007be5%27/%3e%3c/svg%3e")}.form-switch .form-check-input:checked{background-position:right center;background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%27-4 -4 8 8%27%3e%3ccircle r=%273%27 fill=%27%23fff%27/%3e%3c/svg%3e")}.form-check-inline{display:inline-block;margin-right:1rem}.btn-check{position:absolute;clip:rect(0, 0, 0, 0);pointer-events:none}.btn-check[disabled]+.btn,.btn-check:disabled+.btn{pointer-events:none;filter:none;opacity:.35}.form-range{width:100%;height:1rem;padding:0;background-color:transparent;appearance:none}.form-range:focus{outline:0}.form-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 0 rgba(0,123,229,0.25)}.form-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 0 rgba(0,123,229,0.25)}.form-range::-moz-focus-outer{border:0}.form-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-.25rem;background-color:#007be5;border:0;border-radius:1rem;transition:background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out;appearance:none}@media (prefers-reduced-motion: reduce){.form-range::-webkit-slider-thumb{transition:none}}.form-range::-webkit-slider-thumb:active{background-color:#b3d7f7}.form-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.form-range::-moz-range-thumb{width:1rem;height:1rem;background-color:#007be5;border:0;border-radius:1rem;transition:background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out;appearance:none}@media (prefers-reduced-motion: reduce){.form-range::-moz-range-thumb{transition:none}}.form-range::-moz-range-thumb:active{background-color:#b3d7f7}.form-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.form-range:disabled{pointer-events:none}.form-range:disabled::-webkit-slider-thumb{background-color:#adb5bd}.form-range:disabled::-moz-range-thumb{background-color:#adb5bd}.form-floating{position:relative}.form-floating>.form-control,.form-floating>.form-select{height:calc(3.5rem + 2px);line-height:1.25}.form-floating>label{position:absolute;top:0;left:0;height:100%;padding:1rem .875rem;pointer-events:none;border:1px solid transparent;transform-origin:0 0;transition:opacity 0.1s ease-in-out,transform 0.1s ease-in-out}@media (prefers-reduced-motion: reduce){.form-floating>label{transition:none}}.form-floating>.form-control{padding:1rem .875rem}.form-floating>.form-control::placeholder{color:transparent}.form-floating>.form-control:focus,.form-floating>.form-control:not(:placeholder-shown){padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control:-webkit-autofill{padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-select{padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control:focus ~ label,.form-floating>.form-control:not(:placeholder-shown) ~ label,.form-floating>.form-select ~ label{opacity:.65;transform:scale(0.85) translateY(-0.5rem) translateX(0.15rem)}.form-floating>.form-control:-webkit-autofill ~ label{opacity:.65;transform:scale(0.85) translateY(-0.5rem) translateX(0.15rem)}.input-group{position:relative;display:flex;flex-wrap:wrap;align-items:stretch;width:100%}.input-group>.form-control,.input-group>.form-select{position:relative;flex:1 1 auto;width:1%;min-width:0}.input-group>.form-control:focus,.input-group>.form-select:focus{z-index:3}.input-group .btn{position:relative;z-index:2}.input-group .btn:focus{z-index:3}.input-group-text{display:flex;align-items:center;padding:0 .875rem;font-size:.75rem;font-weight:400;line-height:1.875rem;color:var(--t42-content-color);text-align:center;white-space:nowrap;background-color:#e9ecef;border:1px solid var(--t42-color-opacity-10);border-radius:0}.input-group-lg>.form-control,.input-group-lg>.form-select,.input-group-lg>.input-group-text,.input-group-lg>.btn{padding:0 .875rem;font-size:.75rem;border-radius:0}.input-group-sm>.form-control,.input-group-sm>.form-select,.input-group-sm>.input-group-text,.input-group-sm>.btn{padding:0 .875rem;font-size:.75rem;border-radius:0}.input-group-lg>.form-select,.input-group-sm>.form-select{padding-right:3.5rem}.input-group:not(.has-validation)>:not(:last-child):not(.dropdown-toggle):not(.dropdown-menu),.input-group:not(.has-validation)>.dropdown-toggle:nth-last-child(n+3){border-top-right-radius:0;border-bottom-right-radius:0}.input-group.has-validation>:nth-last-child(n+3):not(.dropdown-toggle):not(.dropdown-menu),.input-group.has-validation>.dropdown-toggle:nth-last-child(n+4){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>:not(:first-child):not(.dropdown-menu):not(.valid-tooltip):not(.valid-feedback):not(.invalid-tooltip):not(.invalid-feedback){margin-left:-1px;border-top-left-radius:0;border-bottom-left-radius:0}.valid-feedback{display:none;width:100%;margin-top:.5rem;font-size:.7rem;color:#43a047}.valid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem 1rem;margin-top:.1rem;font-size:.65625rem;color:#000;background-color:#43a047;border-radius:0}.was-validated :valid ~ .valid-feedback,.was-validated :valid ~ .valid-tooltip,.is-valid ~ .valid-feedback,.is-valid ~ .valid-tooltip{display:block}.was-validated .form-control:valid,.form-control.is-valid{border-color:#43a047;padding-right:2rem;background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 8 8%27%3e%3cpath fill=%27%2343a047%27 d=%27M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z%27/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right .5rem center;background-size:1rem 1rem}.was-validated .form-control:valid:focus,.form-control.is-valid:focus{border-color:#43a047;box-shadow:0 0 0 0 rgba(67,160,71,0.25)}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{padding-right:2rem;background-position:top .5rem right .5rem}.was-validated .form-select:valid,.form-select.is-valid{border-color:#43a047}.was-validated .form-select:valid:not([multiple]):not([size]),.was-validated .form-select:valid:not([multiple])[size="1"],.form-select.is-valid:not([multiple]):not([size]),.form-select.is-valid:not([multiple])[size="1"]{padding-right:3.5rem;background-image:var(--t42-select-indicator),url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 8 8%27%3e%3cpath fill=%27%2343a047%27 d=%27M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z%27/%3e%3c/svg%3e");background-position:right 0.5rem center,right 1.75rem center;background-size:1rem,1rem}.was-validated .form-select:valid:focus,.form-select.is-valid:focus{border-color:#43a047;box-shadow:0 0 0 0 rgba(67,160,71,0.25)}.was-validated .form-check-input:valid,.form-check-input.is-valid{border-color:#43a047}.was-validated .form-check-input:valid:checked,.form-check-input.is-valid:checked{background-color:#43a047}.was-validated .form-check-input:valid:focus,.form-check-input.is-valid:focus{box-shadow:0 0 0 0 rgba(67,160,71,0.25)}.was-validated .form-check-input:valid ~ .form-check-label,.form-check-input.is-valid ~ .form-check-label{color:#43a047}.form-check-inline .form-check-input ~ .valid-feedback{margin-left:.5em}.was-validated .input-group .form-control:valid,.input-group .form-control.is-valid,.was-validated .input-group .form-select:valid,.input-group .form-select.is-valid{z-index:1}.was-validated .input-group .form-control:valid:focus,.input-group .form-control.is-valid:focus,.was-validated .input-group .form-select:valid:focus,.input-group .form-select.is-valid:focus{z-index:3}.invalid-feedback{display:none;width:100%;margin-top:.5rem;font-size:.7rem;color:#ff511f}.invalid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem 1rem;margin-top:.1rem;font-size:.65625rem;color:#000;background-color:#ff511f;border-radius:0}.was-validated :invalid ~ .invalid-feedback,.was-validated :invalid ~ .invalid-tooltip,.is-invalid ~ .invalid-feedback,.is-invalid ~ .invalid-tooltip{display:block}.was-validated .form-control:invalid,.form-control.is-invalid{border-color:#ff511f;padding-right:2rem;background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 12 12%27 width=%2712%27 height=%2712%27 fill=%27none%27 stroke=%27%23ff511f%27%3e%3ccircle cx=%276%27 cy=%276%27 r=%274.5%27/%3e%3cpath stroke-linejoin=%27round%27 d=%27M5.8 3.6h.4L6 6.5z%27/%3e%3ccircle cx=%276%27 cy=%278.2%27 r=%27.6%27 fill=%27%23ff511f%27 stroke=%27none%27/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right .5rem center;background-size:1rem 1rem}.was-validated .form-control:invalid:focus,.form-control.is-invalid:focus{border-color:#ff511f;box-shadow:0 0 0 0 rgba(255,81,31,0.25)}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{padding-right:2rem;background-position:top .5rem right .5rem}.was-validated .form-select:invalid,.form-select.is-invalid{border-color:#ff511f}.was-validated .form-select:invalid:not([multiple]):not([size]),.was-validated .form-select:invalid:not([multiple])[size="1"],.form-select.is-invalid:not([multiple]):not([size]),.form-select.is-invalid:not([multiple])[size="1"]{padding-right:3.5rem;background-image:var(--t42-select-indicator),url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 12 12%27 width=%2712%27 height=%2712%27 fill=%27none%27 stroke=%27%23ff511f%27%3e%3ccircle cx=%276%27 cy=%276%27 r=%274.5%27/%3e%3cpath stroke-linejoin=%27round%27 d=%27M5.8 3.6h.4L6 6.5z%27/%3e%3ccircle cx=%276%27 cy=%278.2%27 r=%27.6%27 fill=%27%23ff511f%27 stroke=%27none%27/%3e%3c/svg%3e");background-position:right 0.5rem center,right 1.75rem center;background-size:1rem,1rem}.was-validated .form-select:invalid:focus,.form-select.is-invalid:focus{border-color:#ff511f;box-shadow:0 0 0 0 rgba(255,81,31,0.25)}.was-validated .form-check-input:invalid,.form-check-input.is-invalid{border-color:#ff511f}.was-validated .form-check-input:invalid:checked,.form-check-input.is-invalid:checked{background-color:#ff511f}.was-validated .form-check-input:invalid:focus,.form-check-input.is-invalid:focus{box-shadow:0 0 0 0 rgba(255,81,31,0.25)}.was-validated .form-check-input:invalid ~ .form-check-label,.form-check-input.is-invalid ~ .form-check-label{color:#ff511f}.form-check-inline .form-check-input ~ .invalid-feedback{margin-left:.5em}.was-validated .input-group .form-control:invalid,.input-group .form-control.is-invalid,.was-validated .input-group .form-select:invalid,.input-group .form-select.is-invalid{z-index:2}.was-validated .input-group .form-control:invalid:focus,.input-group .form-control.is-invalid:focus,.was-validated .input-group .form-select:invalid:focus,.input-group .form-select.is-invalid:focus{z-index:3}input{background-color:var(--t42-input-bg)}input[type="number"]::-webkit-calendar-picker-indicator,input[type="datetime-local"]::-webkit-calendar-picker-indicator,input[type="month"]::-webkit-calendar-picker-indicator,input[type="week"]::-webkit-calendar-picker-indicator,input[type="time"]::-webkit-calendar-picker-indicator,input[type="date"]::-webkit-calendar-picker-indicator{background:transparent}input[type="number"]::-webkit-inner-spin-button,input[type="datetime-local"]::-webkit-inner-spin-button,input[type="month"]::-webkit-inner-spin-button,input[type="week"]::-webkit-inner-spin-button,input[type="time"]::-webkit-inner-spin-button,input[type="date"]::-webkit-inner-spin-button{appearance:none}input[type="color"],input[type="range"]{padding:0;border:0}form div[class^="col"]{position:relative}.form-check-label input[type="checkbox"],.form-check-label input[type="radio"]{margin-top:0.125rem;margin-left:-1.2rem;opacity:1}.form-check .form-check-input:disabled{opacity:0}.form-check-label{margin-bottom:0}.form-check-inline .form-check-label{padding-left:0.25rem}.form-check-inline input[type="radio"]:checked+label::after{left:-1rem}.form-control{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border;background-color:transparent}.form-control:disabled,.form-control.disabled,.form-control[readonly]{cursor:default;opacity:0.65}.form-control.is-valid,.form-control.is-invalid{border-color:var(--t42-color-opacity-10)}.form-control.is-valid:focus,.form-control.is-invalid:focus{border-color:var(--primary);box-shadow:none}.form-control[type="file"]{opacity:0}.form-text{color:var(--secondary)}.form-control-plaintext:focus{outline:0}select{background-image:var(--t42-select-indicator);background-repeat:no-repeat;background-position:right 0.5rem center;background-size:1rem;cursor:pointer;appearance:none}select[multiple]{padding:0;background-image:none}select[multiple] option{padding:0 0.875rem}select[multiple] option:checked{background-color:var(--primary)}select:disabled{border-color:transparent;cursor:default;opacity:0.65}textarea,textarea.form-control{min-height:90px;max-height:180px;padding-top:5px;padding-bottom:5px}textarea:disabled,textarea.form-control:disabled{border-color:transparent}input[type="range"]{width:100%;appearance:none}input[type="range"]:focus{background-color:transparent;outline:none}input[type="range"]:focus::-ms-fill-lower,input[type="range"]:focus::-ms-fill-upper{background:var(--primary)}input[type="range"]::-webkit-slider-runnable-track{width:100%;height:0.0625rem;border:0;border-radius:0;background:var(--t42-color-opacity-10);box-shadow:none;cursor:pointer}input[type="range"]::-webkit-slider-thumb{width:12px;height:12px;margin-top:-5px;border:0;border-radius:50%;background:var(--primary);box-shadow:none;cursor:pointer;appearance:none}input[type="range"]:focus::-webkit-slider-runnable-track{background:var(--t42-color-opacity-10)}input[type="range"]::-moz-range-track{width:100%;height:2px;border:0;border-radius:0;background:var(--t42-color-opacity-10);box-shadow:none;cursor:pointer}input[type="range"]::-moz-range-thumb{width:12px;height:12px;border:0;border-radius:50px;background:var(--primary);box-shadow:none;cursor:pointer}input[type="range"]::-ms-track{width:100%;height:2px;border-color:transparent;color:transparent;background:transparent;cursor:pointer}input[type="range"]::-ms-fill-lower,input[type="range"]::-ms-fill-upper{border:0;border-radius:0;background:var(--primary);box-shadow:none}input[type="range"]::-ms-thumb{width:12px;height:12px;border:0;border-radius:50px;background:var(--primary);box-shadow:none;cursor:pointer}input[type="checkbox"]{opacity:0}input[type="checkbox"]+label{position:relative;color:var(--t42-content-color-muted);cursor:pointer;user-select:none}input[type="checkbox"]+label::before{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, border-color;position:absolute;top:0.0625rem;left:-1.25rem;display:block;width:0.875rem;height:0.875rem;border:0.0625rem solid var(--t42-content-color-muted);border-radius:0;cursor:pointer;content:"";pointer-events:all}input[type="checkbox"]+label::after{position:absolute;top:0.125rem;left:-1.188rem;display:block;width:0.875rem;height:0.875rem;background-image:none;content:"";-webkit-mask-size:0.75rem;-webkit-mask-repeat:no-repeat;content:""}input[type="checkbox"].indeterminate+label::before,input[type="checkbox"]:indeterminate+label::before{border-color:var(--t42-color-opacity-30);background-color:var(--primary)}input[type="checkbox"].indeterminate+label::after,input[type="checkbox"]:indeterminate+label::after{top:0.375rem;left:-1.063rem;width:0.5rem;height:0.188rem;background-color:var(--white)}input[type="checkbox"]:disabled+label,input[type="checkbox"]:disabled+.form-check-label{color:var(--t42-content-color-disabled)}input[type="checkbox"]:checked.disabled+label,input[type="checkbox"]:checked:disabled+label,input[type="checkbox"]:indeterminate.disabled+label,input[type="checkbox"]:indeterminate:disabled+label,input[type="checkbox"].disabled+label,input[type="checkbox"]:disabled+label{color:var(--t42-content-color-disabled)}input[type="checkbox"]:checked.disabled+label::before,input[type="checkbox"]:checked:disabled+label::before,input[type="checkbox"]:indeterminate.disabled+label::before,input[type="checkbox"]:indeterminate:disabled+label::before,input[type="checkbox"].disabled+label::before,input[type="checkbox"]:disabled+label::before{border-color:transparent;background-color:var(--t42-color-opacity-10)}input[type="checkbox"]:checked+label::before{border-color:var(--t42-color-opacity-30);background-color:var(--primary)}input[type="checkbox"]:checked+label::after{background-color:var(--t42-link-color);-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M212.48599,435.14899c-11.60532,0.00003-21.16266-4.77866-28.672-14.336l-92.16-120.832 c-5.46133-8.19202-7.50933-17.06665-6.144-26.62399s5.80267-17.408,13.312-23.552s16.21333-8.53334,26.112-7.168 c9.89867,1.36533,17.92,6.14401,24.064,14.336l60.416,78.84799L360.966,93.13298c5.46133-8.192,12.79999-13.312,22.01599-15.36 s18.26132-0.68267,27.13599,4.096c8.19199,5.46133,13.31198,12.8,15.35999,22.016s0.68265,18.26133-4.09601,27.136l-179.2,286.71997 c-6.82668,10.9227-16.384,16.384-28.672,16.384L212.48599,435.14899z%27/%3E%3C/svg%3E")}input[type="radio"]{opacity:0}input[type="radio"]+label{position:relative;color:var(--t42-content-color-muted);cursor:pointer;user-select:none}input[type="radio"]+label::before{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, border;position:absolute;top:0.0625rem;left:-1.25rem;display:block;width:0.875rem;height:0.875rem;border:0.0625rem solid var(--t42-content-color-muted);border-radius:50%;cursor:pointer;content:"";pointer-events:all}input[type="radio"]+label::after{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, border;position:absolute;top:0.313rem;left:-1rem;display:block;width:0.375rem;height:0.375rem;border-radius:50%;color:var(--white);background-image:none;transform:scale(0);opacity:0;content:""}input[type="radio"]+label:focus{border-color:var(--primary)}input[type="radio"]:disabled+label,input[type="radio"]:disabled+.form-check-label{color:var(--t42-content-color-disabled)}input[type="radio"]:checked.disabled+label,input[type="radio"]:checked:disabled+label,input[type="radio"].disabled+label,input[type="radio"]:disabled+label{color:var(--t42-content-color-disabled)}input[type="radio"]:checked.disabled+label::before,input[type="radio"]:checked:disabled+label::before,input[type="radio"].disabled+label::before,input[type="radio"]:disabled+label::before{border-color:transparent;background-color:var(--t42-color-opacity-10)}input[type="radio"]:checked+label::before{border-color:var(--t42-color-opacity-30);background-color:var(--primary)}input[type="radio"]:checked+label::after{background-color:var(--white);transform:scale(1);opacity:1}.custom-control{padding-left:1.25rem}.custom-control .custom-control-input:checked ~ .custom-control-label::before{border-color:var(--t42-color-opacity-30)}.custom-select,.form-select{max-height:2rem;background-color:transparent;background-image:var(--t42-select-indicator);background-repeat:no-repeat;background-position:right 0.5rem center;background-size:1rem}.custom-select:focus,.custom-select option,.form-select:focus,.form-select option{background-color:var(--t42-input-bg)}.custom-select:disabled option,.form-select:disabled option{background-color:transparent}.custom-radio .custom-control-label{color:var(--t42-content-color-muted);user-select:none}.custom-radio .custom-control-label::after{background:none}.custom-radio .custom-control-input:checked ~ .custom-control-label::after{background-image:none}.custom-checkbox .custom-control-label{color:var(--t42-content-color-muted);user-select:none}.custom-checkbox .custom-control-label::after{background:none}.custom-checkbox .custom-control-input:checked ~ .custom-control-label::after{background-image:none}.custom-checkbox .custom-control-input:disabled .custom-control-label::after,.custom-checkbox .custom-control-input:disabled:checked ~ .custom-control-label::after,.custom-checkbox .custom-control-input:disabled:indeterminate ~ .custom-control-label::after{opacity:0.4}.custom-checkbox .custom-control-input:disabled ~ .custom-control-label::before{border-color:transparent}.switch{position:relative;display:inline-block;align-items:center;height:0.875rem;margin-bottom:0;padding-left:2rem;cursor:pointer}.switch.disabled{color:var(--t42-content-color-disabled)}.switch .slider{position:absolute;top:0;right:0;bottom:0;left:0;width:1.75rem;border:1px solid var(--t42-content-color-muted);cursor:pointer;transition:0.4s}.switch .slider::before{position:absolute;bottom:0.125rem;left:0.125rem;width:0.5rem;height:0.5rem;background-color:var(--t42-content-color-muted);transition:0.4s;content:""}.switch input{width:0;height:0;opacity:0}.switch input:checked+.slider{border:var(--t42-border);background-color:var(--primary)}.switch input:checked+.slider::before{background-color:var(--white);transform:translateX(0.875rem)}.switch input:focus+.slider{box-shadow:0 0 1px #2196f3}.switch input:disabled+.slider{border:var(--t42-border);background-color:var(--t42-color-opacity-10)}.switch input:disabled+.slider::before{background-color:var(--t42-color-opacity-20)}.input-group-prepend .input-group-text{justify-content:center;border-right:0}.input-group-append .input-group-text{justify-content:center;border-left:0}.input-group-append .custom-control,.input-group-prepend .custom-control{margin-bottom:0;padding-left:0.875rem}.input-group-append .custom-control-label,.input-group-prepend .custom-control-label{position:absolute;left:0;min-width:0.875rem;min-height:0.875rem}.input-group-append .custom-control-label::before,.input-group-prepend .custom-control-label::before{left:0}.input-group-append .custom-control-label::after,.input-group-prepend .custom-control-label::after{left:0.25rem}.input-group-append .custom-checkbox .custom-control-label::after,.input-group-prepend .custom-checkbox .custom-control-label::after{left:0.125rem}.custom-file{margin-bottom:1rem}.custom-file-input,.form-control[type="file"]{z-index:1}.custom-file-input:focus ~ .custom-file-label,.form-control[type="file"]:focus ~ .custom-file-label{background-color:var(--t42-input-bg)}.custom-file-label,.input-group-text{background-color:transparent}.custom-file-label::after,.input-group-text::after{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color;background-color:Rgba(--secondary, 0.05);cursor:pointer}.custom-file-label:hover::after,.input-group-text:hover::after{color:var(--white);background-color:var(--secondary)}.form-control[type="file"]+.input-group-text{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color,color;position:absolute;top:0;right:0;left:0;z-index:1;height:2rem;padding:0.375rem 0.875rem;border:var(--t42-border);color:var(--t42-content-color-muted)}.form-control[type="file"]+.input-group-text::after{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color,color;position:absolute;top:0;right:0;bottom:0;z-index:3;display:block;height:100%;padding:0.375rem 0.875rem;border-left:inherit;color:var(--t42-link-color);line-height:1.5;cursor:pointer;content:"Browse"}.form-control[type="file"]+.input-group-text:hover{background-color:var(--t42-input-bg)}.form-control[type="file"]+.input-group-text:hover::after{color:var(--white);background-color:var(--secondary)}.custom-switch{padding-left:2rem}.custom-switch .custom-control-label::before{left:-2rem}.custom-switch .custom-control-label::after{top:0.25rem;left:-1.813rem;width:0.5rem;height:0.5rem}.custom-switch .custom-control-input:checked ~ .custom-control-label::after{background-color:var(--white);content:""}.custom-switch .custom-control-input:not(:disabled):active ~ .custom-control-label::before{border-color:var(--t42-color-opacity-30);background-color:var(--primary)}.valid-feedback,.valid-tooltip,.invalid-feedback,.invalid-tooltip,.warning-feedback,.warning-tooltip{position:absolute;bottom:-1rem;width:calc(100% - 1.875rem);margin-top:0;overflow:hidden;color:var(--t42-content-color);font-size:.7rem;white-space:nowrap;text-overflow:ellipsis}.valid-tooltip,.invalid-tooltip,.warning-tooltip{color:var(--t42-content-color-muted)}.custom-radio label+div,.custom-checkbox label+div,.form-check label+div{width:calc(100% + 1.25rem);transform:translateX(-1.25rem)}.form-group{margin-bottom:1rem}label{margin-bottom:0.5rem}.form-row{display:flex;flex-wrap:wrap;margin-right:-0.5rem;margin-left:-0.5rem}.form-row>.col,.form-row>[class*="col-"]{padding-right:0.5rem;padding-left:0.5rem}.form-inline{display:flex;flex-flow:row wrap;align-items:center}.form-inline .form-check{width:100%}@media (min-width: 576px){.form-inline label{display:flex;align-items:center;justify-content:center;margin-bottom:0}.form-inline .form-group{display:flex;flex:0 0 auto;flex-flow:row wrap;align-items:center;margin-bottom:0}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-plaintext{display:inline-block}.form-inline .input-group,.form-inline .custom-select,.form-inline .form-select{width:auto}.form-inline .form-check{display:flex;align-items:center;justify-content:center;width:auto;padding-left:0}.form-inline .form-check-input{position:relative;flex-shrink:0;margin-top:0;margin-left:0}.form-inline .custom-control{align-items:center;justify-content:center}.form-inline .custom-control-label{margin-bottom:0}}/*! + * Bootstrap Grid v5.1.3 (https://getbootstrap.com/) + * Copyright 2011-2021 The Bootstrap Authors + * Copyright 2011-2021 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) + */:root{--bs-blue: #007be5;--bs-indigo: #6610f2;--bs-purple: #6f42c1;--bs-pink: #fd397a;--bs-red: #ff511f;--bs-orange: #fd7e14;--bs-yellow: #f9a825;--bs-green: #43a047;--bs-teal: #616161;--bs-cyan: #469eb9;--bs-white: #fff;--bs-gray: #6c757d;--bs-gray-dark: #343a40;--bs-gray-100: #f8f9fa;--bs-gray-200: #e9ecef;--bs-gray-300: #dee2e6;--bs-gray-400: #ced4da;--bs-gray-500: #adb5bd;--bs-gray-600: #6c757d;--bs-gray-700: #495057;--bs-gray-800: #343a40;--bs-gray-900: #212529;--bs-primary: #007be5;--bs-secondary: #616161;--bs-success: #43a047;--bs-info: #469eb9;--bs-warning: #f9a825;--bs-danger: #ff511f;--bs-light: #616161;--bs-dark: #616161;--bs-primary-rgb: 0,123,229;--bs-secondary-rgb: 97,97,97;--bs-success-rgb: 67,160,71;--bs-info-rgb: 70,158,185;--bs-warning-rgb: 249,168,37;--bs-danger-rgb: 255,81,31;--bs-light-rgb: 97,97,97;--bs-dark-rgb: 97,97,97;--bs-white-rgb: 255,255,255;--bs-black-rgb: 0,0,0;--bs-body-color-rgb: 33,37,41;--bs-body-bg-rgb: 255,255,255;--bs-font-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--bs-gradient: linear-gradient(180deg, rgba(255,255,255,0.15), rgba(255,255,255,0));--bs-body-font-family: Montserrat,Helvetica Neue,Arial,sans-serif;--bs-body-font-size: .75rem;--bs-body-font-weight: 400;--bs-body-line-height: 1.5;--bs-body-color: #212529;--bs-body-bg: #fff}.container,.container-fluid,.container-sm,.container-md,.container-lg,.container-xl,.container-xxl{width:100%;padding-right:var(--bs-gutter-x, .75rem);padding-left:var(--bs-gutter-x, .75rem);margin-right:auto;margin-left:auto}@media (min-width: 576px){.container,.container-sm{max-width:540px}}@media (min-width: 768px){.container,.container-sm,.container-md{max-width:720px}}@media (min-width: 992px){.container,.container-sm,.container-md,.container-lg{max-width:960px}}@media (min-width: 1200px){.container,.container-sm,.container-md,.container-lg,.container-xl{max-width:1140px}}@media (min-width: 1400px){.container,.container-sm,.container-md,.container-lg,.container-xl,.container-xxl{max-width:1320px}}.row{--bs-gutter-x: 1.5rem;--bs-gutter-y: 0;display:flex;flex-wrap:wrap;margin-top:calc(-1 * var(--bs-gutter-y));margin-right:calc(-.5 * var(--bs-gutter-x));margin-left:calc(-.5 * var(--bs-gutter-x))}.row>*{box-sizing:border-box;flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--bs-gutter-x) * .5);padding-left:calc(var(--bs-gutter-x) * .5);margin-top:var(--bs-gutter-y)}.col{flex:1 0 0%}.row-cols-auto>*{flex:0 0 auto;width:auto}.row-cols-1>*{flex:0 0 auto;width:100%}.row-cols-2>*{flex:0 0 auto;width:50%}.row-cols-3>*{flex:0 0 auto;width:33.33333%}.row-cols-4>*{flex:0 0 auto;width:25%}.row-cols-5>*{flex:0 0 auto;width:20%}.row-cols-6>*{flex:0 0 auto;width:16.66667%}.col-auto{flex:0 0 auto;width:auto}.col-1{flex:0 0 auto;width:8.33333%}.col-2{flex:0 0 auto;width:16.66667%}.col-3{flex:0 0 auto;width:25%}.col-4{flex:0 0 auto;width:33.33333%}.col-5{flex:0 0 auto;width:41.66667%}.col-6{flex:0 0 auto;width:50%}.col-7{flex:0 0 auto;width:58.33333%}.col-8{flex:0 0 auto;width:66.66667%}.col-9{flex:0 0 auto;width:75%}.col-10{flex:0 0 auto;width:83.33333%}.col-11{flex:0 0 auto;width:91.66667%}.col-12{flex:0 0 auto;width:100%}.offset-1{margin-left:8.33333%}.offset-2{margin-left:16.66667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.33333%}.offset-5{margin-left:41.66667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.33333%}.offset-8{margin-left:66.66667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.33333%}.offset-11{margin-left:91.66667%}.g-0,.gx-0{--bs-gutter-x: 0}.g-0,.gy-0{--bs-gutter-y: 0}.g-1,.gx-1{--bs-gutter-x: .25rem}.g-1,.gy-1{--bs-gutter-y: .25rem}.g-2,.gx-2{--bs-gutter-x: .5rem}.g-2,.gy-2{--bs-gutter-y: .5rem}.g-3,.gx-3{--bs-gutter-x: 1rem}.g-3,.gy-3{--bs-gutter-y: 1rem}.g-4,.gx-4{--bs-gutter-x: 1.5rem}.g-4,.gy-4{--bs-gutter-y: 1.5rem}.g-5,.gx-5{--bs-gutter-x: 3rem}.g-5,.gy-5{--bs-gutter-y: 3rem}@media (min-width: 576px){.col-sm{flex:1 0 0%}.row-cols-sm-auto>*{flex:0 0 auto;width:auto}.row-cols-sm-1>*{flex:0 0 auto;width:100%}.row-cols-sm-2>*{flex:0 0 auto;width:50%}.row-cols-sm-3>*{flex:0 0 auto;width:33.33333%}.row-cols-sm-4>*{flex:0 0 auto;width:25%}.row-cols-sm-5>*{flex:0 0 auto;width:20%}.row-cols-sm-6>*{flex:0 0 auto;width:16.66667%}.col-sm-auto{flex:0 0 auto;width:auto}.col-sm-1{flex:0 0 auto;width:8.33333%}.col-sm-2{flex:0 0 auto;width:16.66667%}.col-sm-3{flex:0 0 auto;width:25%}.col-sm-4{flex:0 0 auto;width:33.33333%}.col-sm-5{flex:0 0 auto;width:41.66667%}.col-sm-6{flex:0 0 auto;width:50%}.col-sm-7{flex:0 0 auto;width:58.33333%}.col-sm-8{flex:0 0 auto;width:66.66667%}.col-sm-9{flex:0 0 auto;width:75%}.col-sm-10{flex:0 0 auto;width:83.33333%}.col-sm-11{flex:0 0 auto;width:91.66667%}.col-sm-12{flex:0 0 auto;width:100%}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.33333%}.offset-sm-2{margin-left:16.66667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.33333%}.offset-sm-5{margin-left:41.66667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.33333%}.offset-sm-8{margin-left:66.66667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.33333%}.offset-sm-11{margin-left:91.66667%}.g-sm-0,.gx-sm-0{--bs-gutter-x: 0}.g-sm-0,.gy-sm-0{--bs-gutter-y: 0}.g-sm-1,.gx-sm-1{--bs-gutter-x: .25rem}.g-sm-1,.gy-sm-1{--bs-gutter-y: .25rem}.g-sm-2,.gx-sm-2{--bs-gutter-x: .5rem}.g-sm-2,.gy-sm-2{--bs-gutter-y: .5rem}.g-sm-3,.gx-sm-3{--bs-gutter-x: 1rem}.g-sm-3,.gy-sm-3{--bs-gutter-y: 1rem}.g-sm-4,.gx-sm-4{--bs-gutter-x: 1.5rem}.g-sm-4,.gy-sm-4{--bs-gutter-y: 1.5rem}.g-sm-5,.gx-sm-5{--bs-gutter-x: 3rem}.g-sm-5,.gy-sm-5{--bs-gutter-y: 3rem}}@media (min-width: 768px){.col-md{flex:1 0 0%}.row-cols-md-auto>*{flex:0 0 auto;width:auto}.row-cols-md-1>*{flex:0 0 auto;width:100%}.row-cols-md-2>*{flex:0 0 auto;width:50%}.row-cols-md-3>*{flex:0 0 auto;width:33.33333%}.row-cols-md-4>*{flex:0 0 auto;width:25%}.row-cols-md-5>*{flex:0 0 auto;width:20%}.row-cols-md-6>*{flex:0 0 auto;width:16.66667%}.col-md-auto{flex:0 0 auto;width:auto}.col-md-1{flex:0 0 auto;width:8.33333%}.col-md-2{flex:0 0 auto;width:16.66667%}.col-md-3{flex:0 0 auto;width:25%}.col-md-4{flex:0 0 auto;width:33.33333%}.col-md-5{flex:0 0 auto;width:41.66667%}.col-md-6{flex:0 0 auto;width:50%}.col-md-7{flex:0 0 auto;width:58.33333%}.col-md-8{flex:0 0 auto;width:66.66667%}.col-md-9{flex:0 0 auto;width:75%}.col-md-10{flex:0 0 auto;width:83.33333%}.col-md-11{flex:0 0 auto;width:91.66667%}.col-md-12{flex:0 0 auto;width:100%}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.33333%}.offset-md-2{margin-left:16.66667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.33333%}.offset-md-5{margin-left:41.66667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.33333%}.offset-md-8{margin-left:66.66667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.33333%}.offset-md-11{margin-left:91.66667%}.g-md-0,.gx-md-0{--bs-gutter-x: 0}.g-md-0,.gy-md-0{--bs-gutter-y: 0}.g-md-1,.gx-md-1{--bs-gutter-x: .25rem}.g-md-1,.gy-md-1{--bs-gutter-y: .25rem}.g-md-2,.gx-md-2{--bs-gutter-x: .5rem}.g-md-2,.gy-md-2{--bs-gutter-y: .5rem}.g-md-3,.gx-md-3{--bs-gutter-x: 1rem}.g-md-3,.gy-md-3{--bs-gutter-y: 1rem}.g-md-4,.gx-md-4{--bs-gutter-x: 1.5rem}.g-md-4,.gy-md-4{--bs-gutter-y: 1.5rem}.g-md-5,.gx-md-5{--bs-gutter-x: 3rem}.g-md-5,.gy-md-5{--bs-gutter-y: 3rem}}@media (min-width: 992px){.col-lg{flex:1 0 0%}.row-cols-lg-auto>*{flex:0 0 auto;width:auto}.row-cols-lg-1>*{flex:0 0 auto;width:100%}.row-cols-lg-2>*{flex:0 0 auto;width:50%}.row-cols-lg-3>*{flex:0 0 auto;width:33.33333%}.row-cols-lg-4>*{flex:0 0 auto;width:25%}.row-cols-lg-5>*{flex:0 0 auto;width:20%}.row-cols-lg-6>*{flex:0 0 auto;width:16.66667%}.col-lg-auto{flex:0 0 auto;width:auto}.col-lg-1{flex:0 0 auto;width:8.33333%}.col-lg-2{flex:0 0 auto;width:16.66667%}.col-lg-3{flex:0 0 auto;width:25%}.col-lg-4{flex:0 0 auto;width:33.33333%}.col-lg-5{flex:0 0 auto;width:41.66667%}.col-lg-6{flex:0 0 auto;width:50%}.col-lg-7{flex:0 0 auto;width:58.33333%}.col-lg-8{flex:0 0 auto;width:66.66667%}.col-lg-9{flex:0 0 auto;width:75%}.col-lg-10{flex:0 0 auto;width:83.33333%}.col-lg-11{flex:0 0 auto;width:91.66667%}.col-lg-12{flex:0 0 auto;width:100%}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.33333%}.offset-lg-2{margin-left:16.66667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.33333%}.offset-lg-5{margin-left:41.66667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.33333%}.offset-lg-8{margin-left:66.66667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.33333%}.offset-lg-11{margin-left:91.66667%}.g-lg-0,.gx-lg-0{--bs-gutter-x: 0}.g-lg-0,.gy-lg-0{--bs-gutter-y: 0}.g-lg-1,.gx-lg-1{--bs-gutter-x: .25rem}.g-lg-1,.gy-lg-1{--bs-gutter-y: .25rem}.g-lg-2,.gx-lg-2{--bs-gutter-x: .5rem}.g-lg-2,.gy-lg-2{--bs-gutter-y: .5rem}.g-lg-3,.gx-lg-3{--bs-gutter-x: 1rem}.g-lg-3,.gy-lg-3{--bs-gutter-y: 1rem}.g-lg-4,.gx-lg-4{--bs-gutter-x: 1.5rem}.g-lg-4,.gy-lg-4{--bs-gutter-y: 1.5rem}.g-lg-5,.gx-lg-5{--bs-gutter-x: 3rem}.g-lg-5,.gy-lg-5{--bs-gutter-y: 3rem}}@media (min-width: 1200px){.col-xl{flex:1 0 0%}.row-cols-xl-auto>*{flex:0 0 auto;width:auto}.row-cols-xl-1>*{flex:0 0 auto;width:100%}.row-cols-xl-2>*{flex:0 0 auto;width:50%}.row-cols-xl-3>*{flex:0 0 auto;width:33.33333%}.row-cols-xl-4>*{flex:0 0 auto;width:25%}.row-cols-xl-5>*{flex:0 0 auto;width:20%}.row-cols-xl-6>*{flex:0 0 auto;width:16.66667%}.col-xl-auto{flex:0 0 auto;width:auto}.col-xl-1{flex:0 0 auto;width:8.33333%}.col-xl-2{flex:0 0 auto;width:16.66667%}.col-xl-3{flex:0 0 auto;width:25%}.col-xl-4{flex:0 0 auto;width:33.33333%}.col-xl-5{flex:0 0 auto;width:41.66667%}.col-xl-6{flex:0 0 auto;width:50%}.col-xl-7{flex:0 0 auto;width:58.33333%}.col-xl-8{flex:0 0 auto;width:66.66667%}.col-xl-9{flex:0 0 auto;width:75%}.col-xl-10{flex:0 0 auto;width:83.33333%}.col-xl-11{flex:0 0 auto;width:91.66667%}.col-xl-12{flex:0 0 auto;width:100%}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.33333%}.offset-xl-2{margin-left:16.66667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.33333%}.offset-xl-5{margin-left:41.66667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.33333%}.offset-xl-8{margin-left:66.66667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.33333%}.offset-xl-11{margin-left:91.66667%}.g-xl-0,.gx-xl-0{--bs-gutter-x: 0}.g-xl-0,.gy-xl-0{--bs-gutter-y: 0}.g-xl-1,.gx-xl-1{--bs-gutter-x: .25rem}.g-xl-1,.gy-xl-1{--bs-gutter-y: .25rem}.g-xl-2,.gx-xl-2{--bs-gutter-x: .5rem}.g-xl-2,.gy-xl-2{--bs-gutter-y: .5rem}.g-xl-3,.gx-xl-3{--bs-gutter-x: 1rem}.g-xl-3,.gy-xl-3{--bs-gutter-y: 1rem}.g-xl-4,.gx-xl-4{--bs-gutter-x: 1.5rem}.g-xl-4,.gy-xl-4{--bs-gutter-y: 1.5rem}.g-xl-5,.gx-xl-5{--bs-gutter-x: 3rem}.g-xl-5,.gy-xl-5{--bs-gutter-y: 3rem}}@media (min-width: 1400px){.col-xxl{flex:1 0 0%}.row-cols-xxl-auto>*{flex:0 0 auto;width:auto}.row-cols-xxl-1>*{flex:0 0 auto;width:100%}.row-cols-xxl-2>*{flex:0 0 auto;width:50%}.row-cols-xxl-3>*{flex:0 0 auto;width:33.33333%}.row-cols-xxl-4>*{flex:0 0 auto;width:25%}.row-cols-xxl-5>*{flex:0 0 auto;width:20%}.row-cols-xxl-6>*{flex:0 0 auto;width:16.66667%}.col-xxl-auto{flex:0 0 auto;width:auto}.col-xxl-1{flex:0 0 auto;width:8.33333%}.col-xxl-2{flex:0 0 auto;width:16.66667%}.col-xxl-3{flex:0 0 auto;width:25%}.col-xxl-4{flex:0 0 auto;width:33.33333%}.col-xxl-5{flex:0 0 auto;width:41.66667%}.col-xxl-6{flex:0 0 auto;width:50%}.col-xxl-7{flex:0 0 auto;width:58.33333%}.col-xxl-8{flex:0 0 auto;width:66.66667%}.col-xxl-9{flex:0 0 auto;width:75%}.col-xxl-10{flex:0 0 auto;width:83.33333%}.col-xxl-11{flex:0 0 auto;width:91.66667%}.col-xxl-12{flex:0 0 auto;width:100%}.offset-xxl-0{margin-left:0}.offset-xxl-1{margin-left:8.33333%}.offset-xxl-2{margin-left:16.66667%}.offset-xxl-3{margin-left:25%}.offset-xxl-4{margin-left:33.33333%}.offset-xxl-5{margin-left:41.66667%}.offset-xxl-6{margin-left:50%}.offset-xxl-7{margin-left:58.33333%}.offset-xxl-8{margin-left:66.66667%}.offset-xxl-9{margin-left:75%}.offset-xxl-10{margin-left:83.33333%}.offset-xxl-11{margin-left:91.66667%}.g-xxl-0,.gx-xxl-0{--bs-gutter-x: 0}.g-xxl-0,.gy-xxl-0{--bs-gutter-y: 0}.g-xxl-1,.gx-xxl-1{--bs-gutter-x: .25rem}.g-xxl-1,.gy-xxl-1{--bs-gutter-y: .25rem}.g-xxl-2,.gx-xxl-2{--bs-gutter-x: .5rem}.g-xxl-2,.gy-xxl-2{--bs-gutter-y: .5rem}.g-xxl-3,.gx-xxl-3{--bs-gutter-x: 1rem}.g-xxl-3,.gy-xxl-3{--bs-gutter-y: 1rem}.g-xxl-4,.gx-xxl-4{--bs-gutter-x: 1.5rem}.g-xxl-4,.gy-xxl-4{--bs-gutter-y: 1.5rem}.g-xxl-5,.gx-xxl-5{--bs-gutter-x: 3rem}.g-xxl-5,.gy-xxl-5{--bs-gutter-y: 3rem}}.d-inline{display:inline !important}.d-inline-block{display:inline-block !important}.d-block{display:block !important}.d-grid{display:grid !important}.d-table{display:table !important}.d-table-row{display:table-row !important}.d-table-cell{display:table-cell !important}.d-flex{display:flex !important}.d-inline-flex{display:inline-flex !important}.d-none{display:none !important}.flex-fill{flex:1 1 auto !important}.flex-row{flex-direction:row !important}.flex-column{flex-direction:column !important}.flex-row-reverse{flex-direction:row-reverse !important}.flex-column-reverse{flex-direction:column-reverse !important}.flex-grow-0{flex-grow:0 !important}.flex-grow-1{flex-grow:1 !important}.flex-shrink-0{flex-shrink:0 !important}.flex-shrink-1{flex-shrink:1 !important}.flex-wrap{flex-wrap:wrap !important}.flex-nowrap{flex-wrap:nowrap !important}.flex-wrap-reverse{flex-wrap:wrap-reverse !important}.justify-content-start{justify-content:flex-start !important}.justify-content-end{justify-content:flex-end !important}.justify-content-center{justify-content:center !important}.justify-content-between{justify-content:space-between !important}.justify-content-around{justify-content:space-around !important}.justify-content-evenly{justify-content:space-evenly !important}.align-items-start{align-items:flex-start !important}.align-items-end{align-items:flex-end !important}.align-items-center{align-items:center !important}.align-items-baseline{align-items:baseline !important}.align-items-stretch{align-items:stretch !important}.align-content-start{align-content:flex-start !important}.align-content-end{align-content:flex-end !important}.align-content-center{align-content:center !important}.align-content-between{align-content:space-between !important}.align-content-around{align-content:space-around !important}.align-content-stretch{align-content:stretch !important}.align-self-auto{align-self:auto !important}.align-self-start{align-self:flex-start !important}.align-self-end{align-self:flex-end !important}.align-self-center{align-self:center !important}.align-self-baseline{align-self:baseline !important}.align-self-stretch{align-self:stretch !important}.order-first{order:-1 !important}.order-0{order:0 !important}.order-1{order:1 !important}.order-2{order:2 !important}.order-3{order:3 !important}.order-4{order:4 !important}.order-5{order:5 !important}.order-last{order:6 !important}.m-0{margin:0 !important}.m-1{margin:.25rem !important}.m-2{margin:.5rem !important}.m-3{margin:1rem !important}.m-4{margin:1.5rem !important}.m-5{margin:3rem !important}.m-auto{margin:auto !important}.mx-0{margin-right:0 !important;margin-left:0 !important}.mx-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-3{margin-right:1rem !important;margin-left:1rem !important}.mx-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-5{margin-right:3rem !important;margin-left:3rem !important}.mx-auto{margin-right:auto !important;margin-left:auto !important}.my-0{margin-top:0 !important;margin-bottom:0 !important}.my-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-0{margin-top:0 !important}.mt-1{margin-top:.25rem !important}.mt-2{margin-top:.5rem !important}.mt-3{margin-top:1rem !important}.mt-4{margin-top:1.5rem !important}.mt-5{margin-top:3rem !important}.mt-auto{margin-top:auto !important}.me-0{margin-right:0 !important}.me-1{margin-right:.25rem !important}.me-2{margin-right:.5rem !important}.me-3{margin-right:1rem !important}.me-4{margin-right:1.5rem !important}.me-5{margin-right:3rem !important}.me-auto{margin-right:auto !important}.mb-0{margin-bottom:0 !important}.mb-1{margin-bottom:.25rem !important}.mb-2{margin-bottom:.5rem !important}.mb-3{margin-bottom:1rem !important}.mb-4{margin-bottom:1.5rem !important}.mb-5{margin-bottom:3rem !important}.mb-auto{margin-bottom:auto !important}.ms-0{margin-left:0 !important}.ms-1{margin-left:.25rem !important}.ms-2{margin-left:.5rem !important}.ms-3{margin-left:1rem !important}.ms-4{margin-left:1.5rem !important}.ms-5{margin-left:3rem !important}.ms-auto{margin-left:auto !important}.p-0{padding:0 !important}.p-1{padding:.25rem !important}.p-2{padding:.5rem !important}.p-3{padding:1rem !important}.p-4{padding:1.5rem !important}.p-5{padding:3rem !important}.px-0{padding-right:0 !important;padding-left:0 !important}.px-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-3{padding-right:1rem !important;padding-left:1rem !important}.px-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-5{padding-right:3rem !important;padding-left:3rem !important}.py-0{padding-top:0 !important;padding-bottom:0 !important}.py-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-0{padding-top:0 !important}.pt-1{padding-top:.25rem !important}.pt-2{padding-top:.5rem !important}.pt-3{padding-top:1rem !important}.pt-4{padding-top:1.5rem !important}.pt-5{padding-top:3rem !important}.pe-0{padding-right:0 !important}.pe-1{padding-right:.25rem !important}.pe-2{padding-right:.5rem !important}.pe-3{padding-right:1rem !important}.pe-4{padding-right:1.5rem !important}.pe-5{padding-right:3rem !important}.pb-0{padding-bottom:0 !important}.pb-1{padding-bottom:.25rem !important}.pb-2{padding-bottom:.5rem !important}.pb-3{padding-bottom:1rem !important}.pb-4{padding-bottom:1.5rem !important}.pb-5{padding-bottom:3rem !important}.ps-0{padding-left:0 !important}.ps-1{padding-left:.25rem !important}.ps-2{padding-left:.5rem !important}.ps-3{padding-left:1rem !important}.ps-4{padding-left:1.5rem !important}.ps-5{padding-left:3rem !important}@media (min-width: 576px){.d-sm-inline{display:inline !important}.d-sm-inline-block{display:inline-block !important}.d-sm-block{display:block !important}.d-sm-grid{display:grid !important}.d-sm-table{display:table !important}.d-sm-table-row{display:table-row !important}.d-sm-table-cell{display:table-cell !important}.d-sm-flex{display:flex !important}.d-sm-inline-flex{display:inline-flex !important}.d-sm-none{display:none !important}.flex-sm-fill{flex:1 1 auto !important}.flex-sm-row{flex-direction:row !important}.flex-sm-column{flex-direction:column !important}.flex-sm-row-reverse{flex-direction:row-reverse !important}.flex-sm-column-reverse{flex-direction:column-reverse !important}.flex-sm-grow-0{flex-grow:0 !important}.flex-sm-grow-1{flex-grow:1 !important}.flex-sm-shrink-0{flex-shrink:0 !important}.flex-sm-shrink-1{flex-shrink:1 !important}.flex-sm-wrap{flex-wrap:wrap !important}.flex-sm-nowrap{flex-wrap:nowrap !important}.flex-sm-wrap-reverse{flex-wrap:wrap-reverse !important}.justify-content-sm-start{justify-content:flex-start !important}.justify-content-sm-end{justify-content:flex-end !important}.justify-content-sm-center{justify-content:center !important}.justify-content-sm-between{justify-content:space-between !important}.justify-content-sm-around{justify-content:space-around !important}.justify-content-sm-evenly{justify-content:space-evenly !important}.align-items-sm-start{align-items:flex-start !important}.align-items-sm-end{align-items:flex-end !important}.align-items-sm-center{align-items:center !important}.align-items-sm-baseline{align-items:baseline !important}.align-items-sm-stretch{align-items:stretch !important}.align-content-sm-start{align-content:flex-start !important}.align-content-sm-end{align-content:flex-end !important}.align-content-sm-center{align-content:center !important}.align-content-sm-between{align-content:space-between !important}.align-content-sm-around{align-content:space-around !important}.align-content-sm-stretch{align-content:stretch !important}.align-self-sm-auto{align-self:auto !important}.align-self-sm-start{align-self:flex-start !important}.align-self-sm-end{align-self:flex-end !important}.align-self-sm-center{align-self:center !important}.align-self-sm-baseline{align-self:baseline !important}.align-self-sm-stretch{align-self:stretch !important}.order-sm-first{order:-1 !important}.order-sm-0{order:0 !important}.order-sm-1{order:1 !important}.order-sm-2{order:2 !important}.order-sm-3{order:3 !important}.order-sm-4{order:4 !important}.order-sm-5{order:5 !important}.order-sm-last{order:6 !important}.m-sm-0{margin:0 !important}.m-sm-1{margin:.25rem !important}.m-sm-2{margin:.5rem !important}.m-sm-3{margin:1rem !important}.m-sm-4{margin:1.5rem !important}.m-sm-5{margin:3rem !important}.m-sm-auto{margin:auto !important}.mx-sm-0{margin-right:0 !important;margin-left:0 !important}.mx-sm-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-sm-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-sm-3{margin-right:1rem !important;margin-left:1rem !important}.mx-sm-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-sm-5{margin-right:3rem !important;margin-left:3rem !important}.mx-sm-auto{margin-right:auto !important;margin-left:auto !important}.my-sm-0{margin-top:0 !important;margin-bottom:0 !important}.my-sm-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-sm-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-sm-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-sm-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-sm-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-sm-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-sm-0{margin-top:0 !important}.mt-sm-1{margin-top:.25rem !important}.mt-sm-2{margin-top:.5rem !important}.mt-sm-3{margin-top:1rem !important}.mt-sm-4{margin-top:1.5rem !important}.mt-sm-5{margin-top:3rem !important}.mt-sm-auto{margin-top:auto !important}.me-sm-0{margin-right:0 !important}.me-sm-1{margin-right:.25rem !important}.me-sm-2{margin-right:.5rem !important}.me-sm-3{margin-right:1rem !important}.me-sm-4{margin-right:1.5rem !important}.me-sm-5{margin-right:3rem !important}.me-sm-auto{margin-right:auto !important}.mb-sm-0{margin-bottom:0 !important}.mb-sm-1{margin-bottom:.25rem !important}.mb-sm-2{margin-bottom:.5rem !important}.mb-sm-3{margin-bottom:1rem !important}.mb-sm-4{margin-bottom:1.5rem !important}.mb-sm-5{margin-bottom:3rem !important}.mb-sm-auto{margin-bottom:auto !important}.ms-sm-0{margin-left:0 !important}.ms-sm-1{margin-left:.25rem !important}.ms-sm-2{margin-left:.5rem !important}.ms-sm-3{margin-left:1rem !important}.ms-sm-4{margin-left:1.5rem !important}.ms-sm-5{margin-left:3rem !important}.ms-sm-auto{margin-left:auto !important}.p-sm-0{padding:0 !important}.p-sm-1{padding:.25rem !important}.p-sm-2{padding:.5rem !important}.p-sm-3{padding:1rem !important}.p-sm-4{padding:1.5rem !important}.p-sm-5{padding:3rem !important}.px-sm-0{padding-right:0 !important;padding-left:0 !important}.px-sm-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-sm-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-sm-3{padding-right:1rem !important;padding-left:1rem !important}.px-sm-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-sm-5{padding-right:3rem !important;padding-left:3rem !important}.py-sm-0{padding-top:0 !important;padding-bottom:0 !important}.py-sm-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-sm-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-sm-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-sm-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-sm-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-sm-0{padding-top:0 !important}.pt-sm-1{padding-top:.25rem !important}.pt-sm-2{padding-top:.5rem !important}.pt-sm-3{padding-top:1rem !important}.pt-sm-4{padding-top:1.5rem !important}.pt-sm-5{padding-top:3rem !important}.pe-sm-0{padding-right:0 !important}.pe-sm-1{padding-right:.25rem !important}.pe-sm-2{padding-right:.5rem !important}.pe-sm-3{padding-right:1rem !important}.pe-sm-4{padding-right:1.5rem !important}.pe-sm-5{padding-right:3rem !important}.pb-sm-0{padding-bottom:0 !important}.pb-sm-1{padding-bottom:.25rem !important}.pb-sm-2{padding-bottom:.5rem !important}.pb-sm-3{padding-bottom:1rem !important}.pb-sm-4{padding-bottom:1.5rem !important}.pb-sm-5{padding-bottom:3rem !important}.ps-sm-0{padding-left:0 !important}.ps-sm-1{padding-left:.25rem !important}.ps-sm-2{padding-left:.5rem !important}.ps-sm-3{padding-left:1rem !important}.ps-sm-4{padding-left:1.5rem !important}.ps-sm-5{padding-left:3rem !important}}@media (min-width: 768px){.d-md-inline{display:inline !important}.d-md-inline-block{display:inline-block !important}.d-md-block{display:block !important}.d-md-grid{display:grid !important}.d-md-table{display:table !important}.d-md-table-row{display:table-row !important}.d-md-table-cell{display:table-cell !important}.d-md-flex{display:flex !important}.d-md-inline-flex{display:inline-flex !important}.d-md-none{display:none !important}.flex-md-fill{flex:1 1 auto !important}.flex-md-row{flex-direction:row !important}.flex-md-column{flex-direction:column !important}.flex-md-row-reverse{flex-direction:row-reverse !important}.flex-md-column-reverse{flex-direction:column-reverse !important}.flex-md-grow-0{flex-grow:0 !important}.flex-md-grow-1{flex-grow:1 !important}.flex-md-shrink-0{flex-shrink:0 !important}.flex-md-shrink-1{flex-shrink:1 !important}.flex-md-wrap{flex-wrap:wrap !important}.flex-md-nowrap{flex-wrap:nowrap !important}.flex-md-wrap-reverse{flex-wrap:wrap-reverse !important}.justify-content-md-start{justify-content:flex-start !important}.justify-content-md-end{justify-content:flex-end !important}.justify-content-md-center{justify-content:center !important}.justify-content-md-between{justify-content:space-between !important}.justify-content-md-around{justify-content:space-around !important}.justify-content-md-evenly{justify-content:space-evenly !important}.align-items-md-start{align-items:flex-start !important}.align-items-md-end{align-items:flex-end !important}.align-items-md-center{align-items:center !important}.align-items-md-baseline{align-items:baseline !important}.align-items-md-stretch{align-items:stretch !important}.align-content-md-start{align-content:flex-start !important}.align-content-md-end{align-content:flex-end !important}.align-content-md-center{align-content:center !important}.align-content-md-between{align-content:space-between !important}.align-content-md-around{align-content:space-around !important}.align-content-md-stretch{align-content:stretch !important}.align-self-md-auto{align-self:auto !important}.align-self-md-start{align-self:flex-start !important}.align-self-md-end{align-self:flex-end !important}.align-self-md-center{align-self:center !important}.align-self-md-baseline{align-self:baseline !important}.align-self-md-stretch{align-self:stretch !important}.order-md-first{order:-1 !important}.order-md-0{order:0 !important}.order-md-1{order:1 !important}.order-md-2{order:2 !important}.order-md-3{order:3 !important}.order-md-4{order:4 !important}.order-md-5{order:5 !important}.order-md-last{order:6 !important}.m-md-0{margin:0 !important}.m-md-1{margin:.25rem !important}.m-md-2{margin:.5rem !important}.m-md-3{margin:1rem !important}.m-md-4{margin:1.5rem !important}.m-md-5{margin:3rem !important}.m-md-auto{margin:auto !important}.mx-md-0{margin-right:0 !important;margin-left:0 !important}.mx-md-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-md-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-md-3{margin-right:1rem !important;margin-left:1rem !important}.mx-md-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-md-5{margin-right:3rem !important;margin-left:3rem !important}.mx-md-auto{margin-right:auto !important;margin-left:auto !important}.my-md-0{margin-top:0 !important;margin-bottom:0 !important}.my-md-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-md-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-md-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-md-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-md-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-md-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-md-0{margin-top:0 !important}.mt-md-1{margin-top:.25rem !important}.mt-md-2{margin-top:.5rem !important}.mt-md-3{margin-top:1rem !important}.mt-md-4{margin-top:1.5rem !important}.mt-md-5{margin-top:3rem !important}.mt-md-auto{margin-top:auto !important}.me-md-0{margin-right:0 !important}.me-md-1{margin-right:.25rem !important}.me-md-2{margin-right:.5rem !important}.me-md-3{margin-right:1rem !important}.me-md-4{margin-right:1.5rem !important}.me-md-5{margin-right:3rem !important}.me-md-auto{margin-right:auto !important}.mb-md-0{margin-bottom:0 !important}.mb-md-1{margin-bottom:.25rem !important}.mb-md-2{margin-bottom:.5rem !important}.mb-md-3{margin-bottom:1rem !important}.mb-md-4{margin-bottom:1.5rem !important}.mb-md-5{margin-bottom:3rem !important}.mb-md-auto{margin-bottom:auto !important}.ms-md-0{margin-left:0 !important}.ms-md-1{margin-left:.25rem !important}.ms-md-2{margin-left:.5rem !important}.ms-md-3{margin-left:1rem !important}.ms-md-4{margin-left:1.5rem !important}.ms-md-5{margin-left:3rem !important}.ms-md-auto{margin-left:auto !important}.p-md-0{padding:0 !important}.p-md-1{padding:.25rem !important}.p-md-2{padding:.5rem !important}.p-md-3{padding:1rem !important}.p-md-4{padding:1.5rem !important}.p-md-5{padding:3rem !important}.px-md-0{padding-right:0 !important;padding-left:0 !important}.px-md-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-md-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-md-3{padding-right:1rem !important;padding-left:1rem !important}.px-md-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-md-5{padding-right:3rem !important;padding-left:3rem !important}.py-md-0{padding-top:0 !important;padding-bottom:0 !important}.py-md-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-md-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-md-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-md-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-md-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-md-0{padding-top:0 !important}.pt-md-1{padding-top:.25rem !important}.pt-md-2{padding-top:.5rem !important}.pt-md-3{padding-top:1rem !important}.pt-md-4{padding-top:1.5rem !important}.pt-md-5{padding-top:3rem !important}.pe-md-0{padding-right:0 !important}.pe-md-1{padding-right:.25rem !important}.pe-md-2{padding-right:.5rem !important}.pe-md-3{padding-right:1rem !important}.pe-md-4{padding-right:1.5rem !important}.pe-md-5{padding-right:3rem !important}.pb-md-0{padding-bottom:0 !important}.pb-md-1{padding-bottom:.25rem !important}.pb-md-2{padding-bottom:.5rem !important}.pb-md-3{padding-bottom:1rem !important}.pb-md-4{padding-bottom:1.5rem !important}.pb-md-5{padding-bottom:3rem !important}.ps-md-0{padding-left:0 !important}.ps-md-1{padding-left:.25rem !important}.ps-md-2{padding-left:.5rem !important}.ps-md-3{padding-left:1rem !important}.ps-md-4{padding-left:1.5rem !important}.ps-md-5{padding-left:3rem !important}}@media (min-width: 992px){.d-lg-inline{display:inline !important}.d-lg-inline-block{display:inline-block !important}.d-lg-block{display:block !important}.d-lg-grid{display:grid !important}.d-lg-table{display:table !important}.d-lg-table-row{display:table-row !important}.d-lg-table-cell{display:table-cell !important}.d-lg-flex{display:flex !important}.d-lg-inline-flex{display:inline-flex !important}.d-lg-none{display:none !important}.flex-lg-fill{flex:1 1 auto !important}.flex-lg-row{flex-direction:row !important}.flex-lg-column{flex-direction:column !important}.flex-lg-row-reverse{flex-direction:row-reverse !important}.flex-lg-column-reverse{flex-direction:column-reverse !important}.flex-lg-grow-0{flex-grow:0 !important}.flex-lg-grow-1{flex-grow:1 !important}.flex-lg-shrink-0{flex-shrink:0 !important}.flex-lg-shrink-1{flex-shrink:1 !important}.flex-lg-wrap{flex-wrap:wrap !important}.flex-lg-nowrap{flex-wrap:nowrap !important}.flex-lg-wrap-reverse{flex-wrap:wrap-reverse !important}.justify-content-lg-start{justify-content:flex-start !important}.justify-content-lg-end{justify-content:flex-end !important}.justify-content-lg-center{justify-content:center !important}.justify-content-lg-between{justify-content:space-between !important}.justify-content-lg-around{justify-content:space-around !important}.justify-content-lg-evenly{justify-content:space-evenly !important}.align-items-lg-start{align-items:flex-start !important}.align-items-lg-end{align-items:flex-end !important}.align-items-lg-center{align-items:center !important}.align-items-lg-baseline{align-items:baseline !important}.align-items-lg-stretch{align-items:stretch !important}.align-content-lg-start{align-content:flex-start !important}.align-content-lg-end{align-content:flex-end !important}.align-content-lg-center{align-content:center !important}.align-content-lg-between{align-content:space-between !important}.align-content-lg-around{align-content:space-around !important}.align-content-lg-stretch{align-content:stretch !important}.align-self-lg-auto{align-self:auto !important}.align-self-lg-start{align-self:flex-start !important}.align-self-lg-end{align-self:flex-end !important}.align-self-lg-center{align-self:center !important}.align-self-lg-baseline{align-self:baseline !important}.align-self-lg-stretch{align-self:stretch !important}.order-lg-first{order:-1 !important}.order-lg-0{order:0 !important}.order-lg-1{order:1 !important}.order-lg-2{order:2 !important}.order-lg-3{order:3 !important}.order-lg-4{order:4 !important}.order-lg-5{order:5 !important}.order-lg-last{order:6 !important}.m-lg-0{margin:0 !important}.m-lg-1{margin:.25rem !important}.m-lg-2{margin:.5rem !important}.m-lg-3{margin:1rem !important}.m-lg-4{margin:1.5rem !important}.m-lg-5{margin:3rem !important}.m-lg-auto{margin:auto !important}.mx-lg-0{margin-right:0 !important;margin-left:0 !important}.mx-lg-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-lg-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-lg-3{margin-right:1rem !important;margin-left:1rem !important}.mx-lg-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-lg-5{margin-right:3rem !important;margin-left:3rem !important}.mx-lg-auto{margin-right:auto !important;margin-left:auto !important}.my-lg-0{margin-top:0 !important;margin-bottom:0 !important}.my-lg-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-lg-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-lg-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-lg-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-lg-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-lg-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-lg-0{margin-top:0 !important}.mt-lg-1{margin-top:.25rem !important}.mt-lg-2{margin-top:.5rem !important}.mt-lg-3{margin-top:1rem !important}.mt-lg-4{margin-top:1.5rem !important}.mt-lg-5{margin-top:3rem !important}.mt-lg-auto{margin-top:auto !important}.me-lg-0{margin-right:0 !important}.me-lg-1{margin-right:.25rem !important}.me-lg-2{margin-right:.5rem !important}.me-lg-3{margin-right:1rem !important}.me-lg-4{margin-right:1.5rem !important}.me-lg-5{margin-right:3rem !important}.me-lg-auto{margin-right:auto !important}.mb-lg-0{margin-bottom:0 !important}.mb-lg-1{margin-bottom:.25rem !important}.mb-lg-2{margin-bottom:.5rem !important}.mb-lg-3{margin-bottom:1rem !important}.mb-lg-4{margin-bottom:1.5rem !important}.mb-lg-5{margin-bottom:3rem !important}.mb-lg-auto{margin-bottom:auto !important}.ms-lg-0{margin-left:0 !important}.ms-lg-1{margin-left:.25rem !important}.ms-lg-2{margin-left:.5rem !important}.ms-lg-3{margin-left:1rem !important}.ms-lg-4{margin-left:1.5rem !important}.ms-lg-5{margin-left:3rem !important}.ms-lg-auto{margin-left:auto !important}.p-lg-0{padding:0 !important}.p-lg-1{padding:.25rem !important}.p-lg-2{padding:.5rem !important}.p-lg-3{padding:1rem !important}.p-lg-4{padding:1.5rem !important}.p-lg-5{padding:3rem !important}.px-lg-0{padding-right:0 !important;padding-left:0 !important}.px-lg-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-lg-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-lg-3{padding-right:1rem !important;padding-left:1rem !important}.px-lg-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-lg-5{padding-right:3rem !important;padding-left:3rem !important}.py-lg-0{padding-top:0 !important;padding-bottom:0 !important}.py-lg-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-lg-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-lg-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-lg-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-lg-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-lg-0{padding-top:0 !important}.pt-lg-1{padding-top:.25rem !important}.pt-lg-2{padding-top:.5rem !important}.pt-lg-3{padding-top:1rem !important}.pt-lg-4{padding-top:1.5rem !important}.pt-lg-5{padding-top:3rem !important}.pe-lg-0{padding-right:0 !important}.pe-lg-1{padding-right:.25rem !important}.pe-lg-2{padding-right:.5rem !important}.pe-lg-3{padding-right:1rem !important}.pe-lg-4{padding-right:1.5rem !important}.pe-lg-5{padding-right:3rem !important}.pb-lg-0{padding-bottom:0 !important}.pb-lg-1{padding-bottom:.25rem !important}.pb-lg-2{padding-bottom:.5rem !important}.pb-lg-3{padding-bottom:1rem !important}.pb-lg-4{padding-bottom:1.5rem !important}.pb-lg-5{padding-bottom:3rem !important}.ps-lg-0{padding-left:0 !important}.ps-lg-1{padding-left:.25rem !important}.ps-lg-2{padding-left:.5rem !important}.ps-lg-3{padding-left:1rem !important}.ps-lg-4{padding-left:1.5rem !important}.ps-lg-5{padding-left:3rem !important}}@media (min-width: 1200px){.d-xl-inline{display:inline !important}.d-xl-inline-block{display:inline-block !important}.d-xl-block{display:block !important}.d-xl-grid{display:grid !important}.d-xl-table{display:table !important}.d-xl-table-row{display:table-row !important}.d-xl-table-cell{display:table-cell !important}.d-xl-flex{display:flex !important}.d-xl-inline-flex{display:inline-flex !important}.d-xl-none{display:none !important}.flex-xl-fill{flex:1 1 auto !important}.flex-xl-row{flex-direction:row !important}.flex-xl-column{flex-direction:column !important}.flex-xl-row-reverse{flex-direction:row-reverse !important}.flex-xl-column-reverse{flex-direction:column-reverse !important}.flex-xl-grow-0{flex-grow:0 !important}.flex-xl-grow-1{flex-grow:1 !important}.flex-xl-shrink-0{flex-shrink:0 !important}.flex-xl-shrink-1{flex-shrink:1 !important}.flex-xl-wrap{flex-wrap:wrap !important}.flex-xl-nowrap{flex-wrap:nowrap !important}.flex-xl-wrap-reverse{flex-wrap:wrap-reverse !important}.justify-content-xl-start{justify-content:flex-start !important}.justify-content-xl-end{justify-content:flex-end !important}.justify-content-xl-center{justify-content:center !important}.justify-content-xl-between{justify-content:space-between !important}.justify-content-xl-around{justify-content:space-around !important}.justify-content-xl-evenly{justify-content:space-evenly !important}.align-items-xl-start{align-items:flex-start !important}.align-items-xl-end{align-items:flex-end !important}.align-items-xl-center{align-items:center !important}.align-items-xl-baseline{align-items:baseline !important}.align-items-xl-stretch{align-items:stretch !important}.align-content-xl-start{align-content:flex-start !important}.align-content-xl-end{align-content:flex-end !important}.align-content-xl-center{align-content:center !important}.align-content-xl-between{align-content:space-between !important}.align-content-xl-around{align-content:space-around !important}.align-content-xl-stretch{align-content:stretch !important}.align-self-xl-auto{align-self:auto !important}.align-self-xl-start{align-self:flex-start !important}.align-self-xl-end{align-self:flex-end !important}.align-self-xl-center{align-self:center !important}.align-self-xl-baseline{align-self:baseline !important}.align-self-xl-stretch{align-self:stretch !important}.order-xl-first{order:-1 !important}.order-xl-0{order:0 !important}.order-xl-1{order:1 !important}.order-xl-2{order:2 !important}.order-xl-3{order:3 !important}.order-xl-4{order:4 !important}.order-xl-5{order:5 !important}.order-xl-last{order:6 !important}.m-xl-0{margin:0 !important}.m-xl-1{margin:.25rem !important}.m-xl-2{margin:.5rem !important}.m-xl-3{margin:1rem !important}.m-xl-4{margin:1.5rem !important}.m-xl-5{margin:3rem !important}.m-xl-auto{margin:auto !important}.mx-xl-0{margin-right:0 !important;margin-left:0 !important}.mx-xl-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-xl-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-xl-3{margin-right:1rem !important;margin-left:1rem !important}.mx-xl-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-xl-5{margin-right:3rem !important;margin-left:3rem !important}.mx-xl-auto{margin-right:auto !important;margin-left:auto !important}.my-xl-0{margin-top:0 !important;margin-bottom:0 !important}.my-xl-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-xl-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-xl-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-xl-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-xl-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-xl-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-xl-0{margin-top:0 !important}.mt-xl-1{margin-top:.25rem !important}.mt-xl-2{margin-top:.5rem !important}.mt-xl-3{margin-top:1rem !important}.mt-xl-4{margin-top:1.5rem !important}.mt-xl-5{margin-top:3rem !important}.mt-xl-auto{margin-top:auto !important}.me-xl-0{margin-right:0 !important}.me-xl-1{margin-right:.25rem !important}.me-xl-2{margin-right:.5rem !important}.me-xl-3{margin-right:1rem !important}.me-xl-4{margin-right:1.5rem !important}.me-xl-5{margin-right:3rem !important}.me-xl-auto{margin-right:auto !important}.mb-xl-0{margin-bottom:0 !important}.mb-xl-1{margin-bottom:.25rem !important}.mb-xl-2{margin-bottom:.5rem !important}.mb-xl-3{margin-bottom:1rem !important}.mb-xl-4{margin-bottom:1.5rem !important}.mb-xl-5{margin-bottom:3rem !important}.mb-xl-auto{margin-bottom:auto !important}.ms-xl-0{margin-left:0 !important}.ms-xl-1{margin-left:.25rem !important}.ms-xl-2{margin-left:.5rem !important}.ms-xl-3{margin-left:1rem !important}.ms-xl-4{margin-left:1.5rem !important}.ms-xl-5{margin-left:3rem !important}.ms-xl-auto{margin-left:auto !important}.p-xl-0{padding:0 !important}.p-xl-1{padding:.25rem !important}.p-xl-2{padding:.5rem !important}.p-xl-3{padding:1rem !important}.p-xl-4{padding:1.5rem !important}.p-xl-5{padding:3rem !important}.px-xl-0{padding-right:0 !important;padding-left:0 !important}.px-xl-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-xl-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-xl-3{padding-right:1rem !important;padding-left:1rem !important}.px-xl-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-xl-5{padding-right:3rem !important;padding-left:3rem !important}.py-xl-0{padding-top:0 !important;padding-bottom:0 !important}.py-xl-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-xl-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-xl-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-xl-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-xl-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-xl-0{padding-top:0 !important}.pt-xl-1{padding-top:.25rem !important}.pt-xl-2{padding-top:.5rem !important}.pt-xl-3{padding-top:1rem !important}.pt-xl-4{padding-top:1.5rem !important}.pt-xl-5{padding-top:3rem !important}.pe-xl-0{padding-right:0 !important}.pe-xl-1{padding-right:.25rem !important}.pe-xl-2{padding-right:.5rem !important}.pe-xl-3{padding-right:1rem !important}.pe-xl-4{padding-right:1.5rem !important}.pe-xl-5{padding-right:3rem !important}.pb-xl-0{padding-bottom:0 !important}.pb-xl-1{padding-bottom:.25rem !important}.pb-xl-2{padding-bottom:.5rem !important}.pb-xl-3{padding-bottom:1rem !important}.pb-xl-4{padding-bottom:1.5rem !important}.pb-xl-5{padding-bottom:3rem !important}.ps-xl-0{padding-left:0 !important}.ps-xl-1{padding-left:.25rem !important}.ps-xl-2{padding-left:.5rem !important}.ps-xl-3{padding-left:1rem !important}.ps-xl-4{padding-left:1.5rem !important}.ps-xl-5{padding-left:3rem !important}}@media (min-width: 1400px){.d-xxl-inline{display:inline !important}.d-xxl-inline-block{display:inline-block !important}.d-xxl-block{display:block !important}.d-xxl-grid{display:grid !important}.d-xxl-table{display:table !important}.d-xxl-table-row{display:table-row !important}.d-xxl-table-cell{display:table-cell !important}.d-xxl-flex{display:flex !important}.d-xxl-inline-flex{display:inline-flex !important}.d-xxl-none{display:none !important}.flex-xxl-fill{flex:1 1 auto !important}.flex-xxl-row{flex-direction:row !important}.flex-xxl-column{flex-direction:column !important}.flex-xxl-row-reverse{flex-direction:row-reverse !important}.flex-xxl-column-reverse{flex-direction:column-reverse !important}.flex-xxl-grow-0{flex-grow:0 !important}.flex-xxl-grow-1{flex-grow:1 !important}.flex-xxl-shrink-0{flex-shrink:0 !important}.flex-xxl-shrink-1{flex-shrink:1 !important}.flex-xxl-wrap{flex-wrap:wrap !important}.flex-xxl-nowrap{flex-wrap:nowrap !important}.flex-xxl-wrap-reverse{flex-wrap:wrap-reverse !important}.justify-content-xxl-start{justify-content:flex-start !important}.justify-content-xxl-end{justify-content:flex-end !important}.justify-content-xxl-center{justify-content:center !important}.justify-content-xxl-between{justify-content:space-between !important}.justify-content-xxl-around{justify-content:space-around !important}.justify-content-xxl-evenly{justify-content:space-evenly !important}.align-items-xxl-start{align-items:flex-start !important}.align-items-xxl-end{align-items:flex-end !important}.align-items-xxl-center{align-items:center !important}.align-items-xxl-baseline{align-items:baseline !important}.align-items-xxl-stretch{align-items:stretch !important}.align-content-xxl-start{align-content:flex-start !important}.align-content-xxl-end{align-content:flex-end !important}.align-content-xxl-center{align-content:center !important}.align-content-xxl-between{align-content:space-between !important}.align-content-xxl-around{align-content:space-around !important}.align-content-xxl-stretch{align-content:stretch !important}.align-self-xxl-auto{align-self:auto !important}.align-self-xxl-start{align-self:flex-start !important}.align-self-xxl-end{align-self:flex-end !important}.align-self-xxl-center{align-self:center !important}.align-self-xxl-baseline{align-self:baseline !important}.align-self-xxl-stretch{align-self:stretch !important}.order-xxl-first{order:-1 !important}.order-xxl-0{order:0 !important}.order-xxl-1{order:1 !important}.order-xxl-2{order:2 !important}.order-xxl-3{order:3 !important}.order-xxl-4{order:4 !important}.order-xxl-5{order:5 !important}.order-xxl-last{order:6 !important}.m-xxl-0{margin:0 !important}.m-xxl-1{margin:.25rem !important}.m-xxl-2{margin:.5rem !important}.m-xxl-3{margin:1rem !important}.m-xxl-4{margin:1.5rem !important}.m-xxl-5{margin:3rem !important}.m-xxl-auto{margin:auto !important}.mx-xxl-0{margin-right:0 !important;margin-left:0 !important}.mx-xxl-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-xxl-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-xxl-3{margin-right:1rem !important;margin-left:1rem !important}.mx-xxl-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-xxl-5{margin-right:3rem !important;margin-left:3rem !important}.mx-xxl-auto{margin-right:auto !important;margin-left:auto !important}.my-xxl-0{margin-top:0 !important;margin-bottom:0 !important}.my-xxl-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-xxl-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-xxl-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-xxl-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-xxl-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-xxl-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-xxl-0{margin-top:0 !important}.mt-xxl-1{margin-top:.25rem !important}.mt-xxl-2{margin-top:.5rem !important}.mt-xxl-3{margin-top:1rem !important}.mt-xxl-4{margin-top:1.5rem !important}.mt-xxl-5{margin-top:3rem !important}.mt-xxl-auto{margin-top:auto !important}.me-xxl-0{margin-right:0 !important}.me-xxl-1{margin-right:.25rem !important}.me-xxl-2{margin-right:.5rem !important}.me-xxl-3{margin-right:1rem !important}.me-xxl-4{margin-right:1.5rem !important}.me-xxl-5{margin-right:3rem !important}.me-xxl-auto{margin-right:auto !important}.mb-xxl-0{margin-bottom:0 !important}.mb-xxl-1{margin-bottom:.25rem !important}.mb-xxl-2{margin-bottom:.5rem !important}.mb-xxl-3{margin-bottom:1rem !important}.mb-xxl-4{margin-bottom:1.5rem !important}.mb-xxl-5{margin-bottom:3rem !important}.mb-xxl-auto{margin-bottom:auto !important}.ms-xxl-0{margin-left:0 !important}.ms-xxl-1{margin-left:.25rem !important}.ms-xxl-2{margin-left:.5rem !important}.ms-xxl-3{margin-left:1rem !important}.ms-xxl-4{margin-left:1.5rem !important}.ms-xxl-5{margin-left:3rem !important}.ms-xxl-auto{margin-left:auto !important}.p-xxl-0{padding:0 !important}.p-xxl-1{padding:.25rem !important}.p-xxl-2{padding:.5rem !important}.p-xxl-3{padding:1rem !important}.p-xxl-4{padding:1.5rem !important}.p-xxl-5{padding:3rem !important}.px-xxl-0{padding-right:0 !important;padding-left:0 !important}.px-xxl-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-xxl-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-xxl-3{padding-right:1rem !important;padding-left:1rem !important}.px-xxl-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-xxl-5{padding-right:3rem !important;padding-left:3rem !important}.py-xxl-0{padding-top:0 !important;padding-bottom:0 !important}.py-xxl-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-xxl-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-xxl-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-xxl-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-xxl-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-xxl-0{padding-top:0 !important}.pt-xxl-1{padding-top:.25rem !important}.pt-xxl-2{padding-top:.5rem !important}.pt-xxl-3{padding-top:1rem !important}.pt-xxl-4{padding-top:1.5rem !important}.pt-xxl-5{padding-top:3rem !important}.pe-xxl-0{padding-right:0 !important}.pe-xxl-1{padding-right:.25rem !important}.pe-xxl-2{padding-right:.5rem !important}.pe-xxl-3{padding-right:1rem !important}.pe-xxl-4{padding-right:1.5rem !important}.pe-xxl-5{padding-right:3rem !important}.pb-xxl-0{padding-bottom:0 !important}.pb-xxl-1{padding-bottom:.25rem !important}.pb-xxl-2{padding-bottom:.5rem !important}.pb-xxl-3{padding-bottom:1rem !important}.pb-xxl-4{padding-bottom:1.5rem !important}.pb-xxl-5{padding-bottom:3rem !important}.ps-xxl-0{padding-left:0 !important}.ps-xxl-1{padding-left:.25rem !important}.ps-xxl-2{padding-left:.5rem !important}.ps-xxl-3{padding-left:1rem !important}.ps-xxl-4{padding-left:1.5rem !important}.ps-xxl-5{padding-left:3rem !important}}@media print{.d-print-inline{display:inline !important}.d-print-inline-block{display:inline-block !important}.d-print-block{display:block !important}.d-print-grid{display:grid !important}.d-print-table{display:table !important}.d-print-table-row{display:table-row !important}.d-print-table-cell{display:table-cell !important}.d-print-flex{display:flex !important}.d-print-inline-flex{display:inline-flex !important}.d-print-none{display:none !important}}.row{--bs-gutter-x: 1.875rem}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:#fff;border:1px solid #dee2e6;border-radius:.25rem;max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:.875em;color:#6c757d}.list-group{display:flex;flex-direction:column;padding-left:0;margin-bottom:0;border-radius:0}.list-group-numbered{list-style-type:none;counter-reset:section}.list-group-numbered>li::before{content:counters(section, ".") ". ";counter-increment:section}.list-group-item-action{width:100%;color:var(--t42-content-color);text-align:inherit}.list-group-item-action:hover,.list-group-item-action:focus{z-index:1;color:var(--t42-link-hover-color);text-decoration:none;background-color:var(--t42-link-hover-bg)}.list-group-item-action:active{color:var(--t42-link-hover-color);background-color:var(--t42-link-active-bg)}.list-group-item{position:relative;display:block;padding:.75rem 1.25rem;color:inherit;text-decoration:none;background-color:Rgb(var(--t42-bg-mid));border:1px solid rgba(0,0,0,0)}.list-group-item:first-child{border-top-left-radius:inherit;border-top-right-radius:inherit}.list-group-item:last-child{border-bottom-right-radius:inherit;border-bottom-left-radius:inherit}.list-group-item.disabled,.list-group-item:disabled{color:var(--t42-content-color-disabled);pointer-events:none;background-color:rgba(0,0,0,0)}.list-group-item.active{z-index:2;color:var(--t42-link-hover-color);background-color:var(--t42-link-active-bg);border-color:rgba(0,0,0,0)}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{margin-top:-1px;border-top-width:1px}.list-group-horizontal{flex-direction:row}.list-group-horizontal>.list-group-item:first-child{border-bottom-left-radius:0;border-top-right-radius:0}.list-group-horizontal>.list-group-item:last-child{border-top-right-radius:0;border-bottom-left-radius:0}.list-group-horizontal>.list-group-item.active{margin-top:0}.list-group-horizontal>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}@media (min-width: 576px){.list-group-horizontal-sm{flex-direction:row}.list-group-horizontal-sm>.list-group-item:first-child{border-bottom-left-radius:0;border-top-right-radius:0}.list-group-horizontal-sm>.list-group-item:last-child{border-top-right-radius:0;border-bottom-left-radius:0}.list-group-horizontal-sm>.list-group-item.active{margin-top:0}.list-group-horizontal-sm>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-sm>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width: 768px){.list-group-horizontal-md{flex-direction:row}.list-group-horizontal-md>.list-group-item:first-child{border-bottom-left-radius:0;border-top-right-radius:0}.list-group-horizontal-md>.list-group-item:last-child{border-top-right-radius:0;border-bottom-left-radius:0}.list-group-horizontal-md>.list-group-item.active{margin-top:0}.list-group-horizontal-md>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-md>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width: 992px){.list-group-horizontal-lg{flex-direction:row}.list-group-horizontal-lg>.list-group-item:first-child{border-bottom-left-radius:0;border-top-right-radius:0}.list-group-horizontal-lg>.list-group-item:last-child{border-top-right-radius:0;border-bottom-left-radius:0}.list-group-horizontal-lg>.list-group-item.active{margin-top:0}.list-group-horizontal-lg>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-lg>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width: 1200px){.list-group-horizontal-xl{flex-direction:row}.list-group-horizontal-xl>.list-group-item:first-child{border-bottom-left-radius:0;border-top-right-radius:0}.list-group-horizontal-xl>.list-group-item:last-child{border-top-right-radius:0;border-bottom-left-radius:0}.list-group-horizontal-xl>.list-group-item.active{margin-top:0}.list-group-horizontal-xl>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-xl>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width: 1400px){.list-group-horizontal-xxl{flex-direction:row}.list-group-horizontal-xxl>.list-group-item:first-child{border-bottom-left-radius:0;border-top-right-radius:0}.list-group-horizontal-xxl>.list-group-item:last-child{border-top-right-radius:0;border-bottom-left-radius:0}.list-group-horizontal-xxl>.list-group-item.active{margin-top:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}.list-group-flush{border-radius:0}.list-group-flush>.list-group-item{border-width:0 0 1px}.list-group-flush>.list-group-item:last-child{border-bottom-width:0}.list-group-item-primary{color:#004a89;background-color:#cce5fa}.list-group-item-primary.list-group-item-action:hover,.list-group-item-primary.list-group-item-action:focus{color:#004a89;background-color:#b8cee1}.list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#004a89;border-color:#004a89}.list-group-item-secondary{color:#3a3a3a;background-color:#dfdfdf}.list-group-item-secondary.list-group-item-action:hover,.list-group-item-secondary.list-group-item-action:focus{color:#3a3a3a;background-color:#c9c9c9}.list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#3a3a3a;border-color:#3a3a3a}.list-group-item-success{color:#28602b;background-color:#d9ecda}.list-group-item-success.list-group-item-action:hover,.list-group-item-success.list-group-item-action:focus{color:#28602b;background-color:#c3d4c4}.list-group-item-success.list-group-item-action.active{color:#fff;background-color:#28602b;border-color:#28602b}.list-group-item-info{color:#2a5f6f;background-color:#daecf1}.list-group-item-info.list-group-item-action:hover,.list-group-item-info.list-group-item-action:focus{color:#2a5f6f;background-color:#c4d4d9}.list-group-item-info.list-group-item-action.active{color:#fff;background-color:#2a5f6f;border-color:#2a5f6f}.list-group-item-warning{color:#64430f;background-color:#feeed3}.list-group-item-warning.list-group-item-action:hover,.list-group-item-warning.list-group-item-action:focus{color:#64430f;background-color:#e5d6be}.list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#64430f;border-color:#64430f}.list-group-item-danger{color:#993113;background-color:#ffdcd2}.list-group-item-danger.list-group-item-action:hover,.list-group-item-danger.list-group-item-action:focus{color:#993113;background-color:#e6c6bd}.list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#993113;border-color:#993113}.list-group-item-light{color:#3a3a3a;background-color:#dfdfdf}.list-group-item-light.list-group-item-action:hover,.list-group-item-light.list-group-item-action:focus{color:#3a3a3a;background-color:#c9c9c9}.list-group-item-light.list-group-item-action.active{color:#fff;background-color:#3a3a3a;border-color:#3a3a3a}.list-group-item-dark{color:#3a3a3a;background-color:#dfdfdf}.list-group-item-dark.list-group-item-action:hover,.list-group-item-dark.list-group-item-action:focus{color:#3a3a3a;background-color:#c9c9c9}.list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#3a3a3a;border-color:#3a3a3a}.list-unstyled{padding-left:0;list-style:none}.list-group{box-shadow:var(--t42-shadow)}.list-group-item{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:color;margin-bottom:0;border:0;border-bottom:var(--t42-border);backdrop-filter:var(--backdrop-filter)}.list-group-item:last-child{border-bottom:transparent}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{margin-top:0;border-top-width:0}.list-group-item-action{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background,color;transition-duration:0.25s}.list-group-item-action:hover,.list-group-item-action:focus{background-color:var(--t42-list-group-hover-bg-special)}.list-group-item-action.active:hover{background-color:var(--t42-color-opacity-05)}.modal{position:fixed;top:0;left:0;z-index:1055;display:none;width:100%;height:100%;overflow-x:hidden;overflow-y:auto;outline:0}.modal-dialog{position:relative;width:auto;margin:.5rem;pointer-events:none}.modal.fade .modal-dialog{transition:transform 0.3s ease-out;transform:translate(0, -50px)}@media (prefers-reduced-motion: reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{transform:none}.modal.modal-static .modal-dialog{transform:scale(1.02)}.modal-dialog-scrollable{height:calc(100% - 1rem)}.modal-dialog-scrollable .modal-content{max-height:100%;overflow:hidden}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{display:flex;align-items:center;min-height:calc(100% - 1rem)}.modal-content{position:relative;display:flex;flex-direction:column;width:100%;pointer-events:auto;background-color:var(--t42-modal-bg);background-clip:padding-box;border:.0625rem solid var(--t42-color-opacity-10);border-radius:0;outline:0}.modal-backdrop{position:fixed;top:0;left:0;z-index:1050;width:100vw;height:100vh;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:.5}.modal-header{display:flex;flex-shrink:0;align-items:center;justify-content:space-between;padding:1rem 1rem;border-bottom:.0625rem solid rgba(0,0,0,0);border-top-left-radius:0;border-top-right-radius:0}.modal-header .btn-close{padding:.5rem .5rem;margin:-.5rem -.5rem -.5rem auto}.modal-title{margin-bottom:0;line-height:1.5}.modal-body{position:relative;flex:1 1 auto;padding:1rem}.modal-footer{display:flex;flex-wrap:wrap;flex-shrink:0;align-items:center;justify-content:flex-end;padding:.75rem;border-top:.0625rem solid rgba(0,0,0,0);border-bottom-right-radius:0;border-bottom-left-radius:0}.modal-footer>*{margin:.25rem}@media (min-width: 576px){.modal-dialog{max-width:500px;margin:1.75rem auto}.modal-dialog-scrollable{height:calc(100% - 3.5rem)}.modal-dialog-centered{min-height:calc(100% - 3.5rem)}.modal-sm{max-width:300px}}@media (min-width: 992px){.modal-lg,.modal-xl{max-width:800px}}@media (min-width: 1200px){.modal-xl{max-width:1140px}}.modal-fullscreen{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen .modal-header{border-radius:0}.modal-fullscreen .modal-body{overflow-y:auto}.modal-fullscreen .modal-footer{border-radius:0}@media (max-width: 575.98px){.modal-fullscreen-sm-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-sm-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-sm-down .modal-header{border-radius:0}.modal-fullscreen-sm-down .modal-body{overflow-y:auto}.modal-fullscreen-sm-down .modal-footer{border-radius:0}}@media (max-width: 767.98px){.modal-fullscreen-md-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-md-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-md-down .modal-header{border-radius:0}.modal-fullscreen-md-down .modal-body{overflow-y:auto}.modal-fullscreen-md-down .modal-footer{border-radius:0}}@media (max-width: 991.98px){.modal-fullscreen-lg-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-lg-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-lg-down .modal-header{border-radius:0}.modal-fullscreen-lg-down .modal-body{overflow-y:auto}.modal-fullscreen-lg-down .modal-footer{border-radius:0}}@media (max-width: 1199.98px){.modal-fullscreen-xl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xl-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-xl-down .modal-header{border-radius:0}.modal-fullscreen-xl-down .modal-body{overflow-y:auto}.modal-fullscreen-xl-down .modal-footer{border-radius:0}}@media (max-width: 1399.98px){.modal-fullscreen-xxl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xxl-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-xxl-down .modal-header{border-radius:0}.modal-fullscreen-xxl-down .modal-body{overflow-y:auto}.modal-fullscreen-xxl-down .modal-footer{border-radius:0}}.modal{backdrop-filter:var(--backdrop-filter)}.modal .btn-close{font-size:1.25rem;background-size:0.75rem;filter:var(--filter-close)}.modal-content{border-top:0;background:linear-gradient(to bottom right, Rgba(var(--t42-bg-light), 0.75) 0%, Rgba(var(--t42-bg-dark), 0.75) 100%);box-shadow:var(--t42-shadow)}.modal-content::before{display:block;height:0.0625rem;background:linear-gradient(90deg, #007be5 0%, rgba(0,123,229,0.5) 100%);content:""}.modal-body{padding:0 1rem}.modal-body p:last-child{margin-bottom:0}.modal-sm .modal-footer{flex-direction:column}.modal-sm .modal-footer .btn{width:100%}.modal-sm .modal-footer .btn:not(:last-of-type){margin-bottom:0.5rem}.modal-fill-in{background-color:Rgba(var(--t42-bg-light), 0.75)}.modal-fill-in.modal-dialog{display:flex;flex-flow:column nowrap;align-content:center;align-items:center;justify-content:center;width:auto;max-width:100%;height:100%;margin:0 auto}.modal-fill-in .modal-content{display:flex;max-width:600px;border-color:transparent;background:transparent;background-color:transparent;box-shadow:none;backdrop-filter:none;pointer-events:auto}.modal-fill-in .modal-content::before{display:none}.modal-fill-in::before{position:fixed;top:0;right:0;left:0;display:block;height:0.0625rem;background:linear-gradient(90deg, #007be5 0%, rgba(0,123,229,0.5) 100%);content:""}.modal-fill-in.modal-lg .modal-content{max-width:800px}.modal-fill-in.modal-sm .modal-content{max-width:300px}.nav{display:flex;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:.45rem 1rem;color:var(--t42-link-color);text-decoration:none;transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.nav-link{transition:none}}.nav-link:hover,.nav-link:focus{color:var(--t42-link-hover-color)}.nav-link.disabled{color:var(--t42-content-color-disabled);pointer-events:none;cursor:default}.nav-tabs{border-bottom:.0625rem solid var(--t42-color-opacity-10)}.nav-tabs .nav-link{margin-bottom:-.0625rem;background:none;border:.0625rem solid transparent;border-top-left-radius:0;border-top-right-radius:0}.nav-tabs .nav-link:hover,.nav-tabs .nav-link:focus{border-color:transparent transparent var(--t42-color-opacity-10);isolation:isolate}.nav-tabs .nav-link.disabled{color:var(--t42-content-color-disabled);background-color:transparent;border-color:transparent}.nav-tabs .nav-link.active,.nav-tabs .nav-item.show .nav-link{color:var(--t42-link-hover-color);background-color:var(--t42-link-active-bg);border-color:transparent transparent #007be5}.nav-tabs .dropdown-menu{margin-top:-.0625rem;border-top-left-radius:0;border-top-right-radius:0}.nav-pills .nav-link{background:none;border:0;border-radius:.25rem}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:var(--t42-link-hover-color);background-color:var(--t42-link-active-bg)}.nav-fill>.nav-link,.nav-fill .nav-item{flex:1 1 auto;text-align:center}.nav-justified>.nav-link,.nav-justified .nav-item{flex-basis:0;flex-grow:1;text-align:center}.nav-fill .nav-item .nav-link,.nav-justified .nav-item .nav-link{width:100%}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-link{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, border-color, color;margin-right:3px;border:.0625rem solid transparent}.nav-link:not(.disabled):not(:disabled):focus,.nav-link:not(.disabled):not(:disabled):active,.nav-link:not(.disabled):not(:disabled).active,.nav-link:not(.disabled):not(:disabled):hover{border-color:var(--t42-color-opacity-10);color:var(--t42-link-color);background-color:var(--t42-link-hover-bg)}.nav-link.dropdown-toggle::after{right:-0.125rem}.navbar-nav .nav-item{bottom:-1px}.navbar-nav .nav-item .nav-link{border-bottom:0}.navbar-nav .nav-item:not(.disabled):not(:disabled):focus .nav-link,.navbar-nav .nav-item:not(.disabled):not(:disabled):active .nav-link,.navbar-nav .nav-item:not(.disabled):not(:disabled).active .nav-link,.navbar-nav .nav-item:not(.disabled):not(:disabled):hover .nav-link{border-color:var(--t42-color-opacity-10)}.nav.flex-column .nav-link{margin-bottom:3px}.nav-tabs .nav-link{position:relative;display:flex;align-items:center;height:2rem}.nav-tabs .nav-link::before{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:height;position:absolute;bottom:-2px;left:-1px;width:calc(100% + 2px);height:0;background-color:var(--primary);content:""}.nav-tabs .nav-link.active::before{height:3px}.nav-tabs .nav-link.active:hover::before{height:0}.nav-tabs .nav-link .btn-close{width:0.5rem;height:0.5rem}.nav-tabs .nav-item{margin-right:0}.nav-tabs .dropdown.show .dropdown-toggle{border-color:transparent}.nav-tabs.flex-column .nav-link.active:hover::before{width:0}.nav-tabs.flex-column .nav-link::before{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:width;top:-1px;width:0;height:100%;margin-left:0;background-color:var(--primary);content:""}.nav-tabs.flex-column .nav-link.active::before{width:3px;height:calc(100% + 2px)}.nav-pills .nav-link{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;width:100%;padding:0.25rem 1rem;border:1px solid transparent;border-radius:1rem}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{position:relative;border-color:transparent}.nav-pills .nav-item{margin-right:3px}.nav-pills .nav-item:last-child{margin-right:0}.nav-pills .nav-link.active:not(.dropdown-toggle),.nav-pills .show>.nav-link:not(.dropdown-toggle){padding:0.25rem 1.75rem 0.25rem 1rem}.nav-pills .nav-link.active:not(.dropdown-toggle)::before,.nav-pills .show>.nav-link:not(.dropdown-toggle)::before{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:right;position:absolute;top:50%;right:10px;width:8px;height:8px;border-radius:50%;background-color:var(--primary);transform:translateY(-50%);content:""}.nav-pills .nav-link.active:not(.dropdown-toggle):hover::before,.nav-pills .show>.nav-link:not(.dropdown-toggle):hover::before{right:-10px}.nav-justified .nav-item .nav-link::before{right:1px;left:-1px;margin-left:0}.tab-content{padding-top:0.5rem}.nav-action-buttons .nav-link{position:relative;padding:0.45rem 1.5rem 0.45rem 1rem}.nav-action-buttons .icon-cancel::before{display:block;width:1rem;height:1rem;background-color:var(--t42-content-color);content:"";-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M366.854,336.384c6.14398,6.14398,9.216,13.48267,9.216,22.01599s-3.07202,15.87198-9.216,22.01599 c-6.14398,5.46133-13.48267,8.19202-22.01599,8.19199c-8.53333,0.00003-15.87201-2.73065-22.01602-8.19199l-67.584-77.82401 l-67.584,77.82401c-6.144,5.46133-13.48267,8.19202-22.01601,8.19199c-8.53333,0.00003-15.87199-2.73065-22.01599-8.19199 c-5.46133-6.14401-8.192-13.48267-8.192-22.01599s2.73067-15.87201,8.192-22.01599l70.65599-79.87201l-70.65601-80.896 c-5.46132-6.144-8.19199-13.48268-8.19199-22.01601c0-8.53334,2.73067-15.87201,8.19199-22.01601 c6.14401-5.46133,13.48267-8.19199,22.01601-8.192c8.53334,0.00001,15.87201,2.73067,22.01601,8.192l67.584,77.82401 l67.584-77.82401c6.14401-5.46133,13.4827-8.19199,22.01602-8.192c8.53333,0.00001,15.87201,2.73067,22.01599,8.192 c6.14398,6.144,9.216,13.48267,9.216,22.01601c0,8.53333-3.07202,15.87201-9.216,22.01601l-70.65601,80.896L366.854,336.384z%27/%3E%3C/svg%3E")}.navbar{position:relative;display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;padding-top:0;padding-right:.875rem;padding-bottom:0;padding-left:.875rem}.navbar>.container,.navbar>.container-fluid,.navbar>.container-sm,.navbar>.container-md,.navbar>.container-lg,.navbar>.container-xl,.navbar>.container-xxl{display:flex;flex-wrap:inherit;align-items:center;justify-content:space-between}.navbar-brand{padding-top:.075rem;padding-bottom:.075rem;margin-right:1rem;font-size:1.25rem;text-decoration:none;white-space:nowrap}.navbar-nav{display:flex;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-nav .dropdown-menu{position:static}.navbar-text{padding-top:.45rem;padding-bottom:.45rem}.navbar-collapse{flex-basis:100%;flex-grow:1;align-items:center}.navbar-toggler{padding:0 0;font-size:.9375rem;line-height:1;background-color:transparent;border:1px solid transparent;border-radius:0;transition:box-shadow 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.navbar-toggler{transition:none}}.navbar-toggler:hover{text-decoration:none}.navbar-toggler:focus{text-decoration:none;outline:0;box-shadow:0 0 0 0}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;background-repeat:no-repeat;background-position:center;background-size:100%}.navbar-nav-scroll{max-height:var(--bs-scroll-height, 75vh);overflow-y:auto}@media (min-width: 576px){.navbar-expand-sm{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-sm .navbar-nav{flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm .navbar-nav-scroll{overflow:visible}.navbar-expand-sm .navbar-collapse{display:flex !important;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}.navbar-expand-sm .offcanvas-header{display:none}.navbar-expand-sm .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;visibility:visible !important;background-color:transparent;border-right:0;border-left:0;transition:none;transform:none}.navbar-expand-sm .offcanvas-top,.navbar-expand-sm .offcanvas-bottom{height:auto;border-top:0;border-bottom:0}.navbar-expand-sm .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width: 768px){.navbar-expand-md{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-md .navbar-nav{flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-md .navbar-nav-scroll{overflow:visible}.navbar-expand-md .navbar-collapse{display:flex !important;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}.navbar-expand-md .offcanvas-header{display:none}.navbar-expand-md .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;visibility:visible !important;background-color:transparent;border-right:0;border-left:0;transition:none;transform:none}.navbar-expand-md .offcanvas-top,.navbar-expand-md .offcanvas-bottom{height:auto;border-top:0;border-bottom:0}.navbar-expand-md .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width: 992px){.navbar-expand-lg{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-lg .navbar-nav{flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-lg .navbar-nav-scroll{overflow:visible}.navbar-expand-lg .navbar-collapse{display:flex !important;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}.navbar-expand-lg .offcanvas-header{display:none}.navbar-expand-lg .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;visibility:visible !important;background-color:transparent;border-right:0;border-left:0;transition:none;transform:none}.navbar-expand-lg .offcanvas-top,.navbar-expand-lg .offcanvas-bottom{height:auto;border-top:0;border-bottom:0}.navbar-expand-lg .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width: 1200px){.navbar-expand-xl{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-xl .navbar-nav{flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xl .navbar-nav-scroll{overflow:visible}.navbar-expand-xl .navbar-collapse{display:flex !important;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}.navbar-expand-xl .offcanvas-header{display:none}.navbar-expand-xl .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;visibility:visible !important;background-color:transparent;border-right:0;border-left:0;transition:none;transform:none}.navbar-expand-xl .offcanvas-top,.navbar-expand-xl .offcanvas-bottom{height:auto;border-top:0;border-bottom:0}.navbar-expand-xl .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width: 1400px){.navbar-expand-xxl{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-xxl .navbar-nav{flex-direction:row}.navbar-expand-xxl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xxl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xxl .navbar-nav-scroll{overflow:visible}.navbar-expand-xxl .navbar-collapse{display:flex !important;flex-basis:auto}.navbar-expand-xxl .navbar-toggler{display:none}.navbar-expand-xxl .offcanvas-header{display:none}.navbar-expand-xxl .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;visibility:visible !important;background-color:transparent;border-right:0;border-left:0;transition:none;transform:none}.navbar-expand-xxl .offcanvas-top,.navbar-expand-xxl .offcanvas-bottom{height:auto;border-top:0;border-bottom:0}.navbar-expand-xxl .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}.navbar-expand{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand .navbar-nav{flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand .navbar-nav-scroll{overflow:visible}.navbar-expand .navbar-collapse{display:flex !important;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-expand .offcanvas-header{display:none}.navbar-expand .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;visibility:visible !important;background-color:transparent;border-right:0;border-left:0;transition:none;transform:none}.navbar-expand .offcanvas-top,.navbar-expand .offcanvas-bottom{height:auto;border-top:0;border-bottom:0}.navbar-expand .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}.navbar-light .navbar-brand{color:var(--t42-link-color)}.navbar-light .navbar-brand:hover,.navbar-light .navbar-brand:focus{color:var(--t42-link-hover-color)}.navbar-light .navbar-nav .nav-link{color:var(--t42-link-color)}.navbar-light .navbar-nav .nav-link:hover,.navbar-light .navbar-nav .nav-link:focus{color:var(--t42-link-hover-color)}.navbar-light .navbar-nav .nav-link.disabled{color:var(--t42-content-color-disabled)}.navbar-light .navbar-nav .show>.nav-link,.navbar-light .navbar-nav .nav-link.active{color:var(--t42-link-hover-color)}.navbar-light .navbar-toggler{color:var(--t42-link-color);border-color:rgba(0,0,0,0.1)}.navbar-light .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 30 30%27%3e%3cpath stroke=%27var%28--t42-link-color%29%27 stroke-linecap=%27round%27 stroke-miterlimit=%2710%27 stroke-width=%272%27 d=%27M4 7h22M4 15h22M4 23h22%27/%3e%3c/svg%3e")}.navbar-light .navbar-text{color:var(--t42-link-color)}.navbar-light .navbar-text a,.navbar-light .navbar-text a:hover,.navbar-light .navbar-text a:focus{color:var(--t42-link-hover-color)}.navbar-dark .navbar-brand{color:var(--t42-link-color)}.navbar-dark .navbar-brand:hover,.navbar-dark .navbar-brand:focus{color:var(--t42-link-hover-color)}.navbar-dark .navbar-nav .nav-link{color:var(--t42-link-color)}.navbar-dark .navbar-nav .nav-link:hover,.navbar-dark .navbar-nav .nav-link:focus{color:var(--t42-link-hover-color)}.navbar-dark .navbar-nav .nav-link.disabled{color:var(--t42-content-color-disabled)}.navbar-dark .navbar-nav .show>.nav-link,.navbar-dark .navbar-nav .nav-link.active{color:var(--t42-link-hover-color)}.navbar-dark .navbar-toggler{color:var(--t42-link-color);border-color:rgba(255,255,255,0.1)}.navbar-dark .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 30 30%27%3e%3cpath stroke=%27var%28--t42-link-color%29%27 stroke-linecap=%27round%27 stroke-miterlimit=%2710%27 stroke-width=%272%27 d=%27M4 7h22M4 15h22M4 23h22%27/%3e%3c/svg%3e")}.navbar-dark .navbar-text{color:var(--t42-link-color)}.navbar-dark .navbar-text a,.navbar-dark .navbar-text a:hover,.navbar-dark .navbar-text a:focus{color:var(--t42-link-hover-color)}.navbar{border-bottom:var(--t42-border);background-color:Rgba(var(--t42-bg-mid), 0.75);backdrop-filter:var(--backdrop-filter)}.navbar-dark{background-color:Rgba(var(--t42-bg-dark), 0.75)}.navbar-light{background-color:Rgba(var(--t42-bg-light), 0.75)}.navbar .nav-item{position:relative}.navbar .nav-item.show:focus .nav-link:not(.disabled):not(:disabled),.navbar .nav-item.show:active .nav-link:not(.disabled):not(:disabled),.navbar .nav-item.show.active .nav-link:not(.disabled):not(:disabled),.navbar .nav-item:not(.disabled):not(:disabled):focus .nav-link:not(.disabled):not(:disabled),.navbar .nav-item:not(.disabled):not(:disabled):active .nav-link:not(.disabled):not(:disabled),.navbar .nav-item:not(.disabled):not(:disabled).active .nav-link:not(.disabled):not(:disabled){color:var(--t42-link-color);background-color:var(--t42-color-opacity-10)}.navbar .nav-item.show:hover .nav-link:not(.disabled):not(:disabled),.navbar .nav-item:not(.disabled):not(:disabled):hover .nav-link:not(.disabled):not(:disabled){color:var(--t42-link-color);background-color:var(--t42-color-opacity-05)}.navbar .nav-link{padding-right:.875rem;padding-left:.875rem}.navbar .btn-group{height:100%;padding-left:.875rem;border-left:var(--t42-border)}.pagination{display:flex;padding-left:0;list-style:none}.page-link{position:relative;display:block;color:var(--t42-content-color);text-decoration:none;background-color:rgba(0,0,0,0);border:0 solid rgba(0,0,0,0);transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.page-link{transition:none}}.page-link:hover{z-index:2;color:var(--t42-link-hover-color);background-color:var(--t42-link-hover-bg);border-color:#dee2e6}.page-link:focus{z-index:3;color:var(--t42-link-hover-color);background-color:rgba(0,0,0,0);outline:0;box-shadow:0 0 0 0 rgba(0,123,229,0.25)}.page-item:not(:first-child) .page-link{margin-left:0}.page-item.active .page-link{z-index:3;color:var(--white);background-color:var(--primary);border-color:var(--primary)}.page-item.disabled .page-link{color:var(--t42-content-color-disabled);pointer-events:none;background-color:rgba(0,0,0,0);border-color:#dee2e6}.page-link{padding:.125rem .5rem}.page-item:first-child .page-link{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.page-item:last-child .page-link{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.pagination-lg .page-link{padding:.75rem 1.5rem;font-size:.9375rem}.pagination-lg .page-item:first-child .page-link{border-top-left-radius:1rem;border-bottom-left-radius:1rem}.pagination-lg .page-item:last-child .page-link{border-top-right-radius:1rem;border-bottom-right-radius:1rem}.pagination-sm .page-link{padding:.25rem .5rem;font-size:.65625rem}.pagination-sm .page-item:first-child .page-link{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.pagination-sm .page-item:last-child .page-link{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.page-link{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, color;display:flex;align-items:center;justify-content:center;min-width:1.5rem;min-height:1.5rem;border-radius:0.25rem;overflow:hidden}.page-link[aria-label="Next"],.page-link[aria-label="Previous"]{padding:0}.page-link[aria-label="Next"] span{background:var(--t42-select-indicator) center center/1rem 1rem no-repeat;transform:rotate(-90deg)}.page-link[aria-label="Previous"] span{background:var(--t42-select-indicator) center center/1rem 1rem no-repeat;transform:rotate(90deg)}.page-link>span{width:100%;height:100%;min-height:1rem;font-size:0;clip:initial}.pagination-lg .page-link[aria-label="Next"],.pagination-lg .page-link[aria-label="Previous"]{padding:0.75rem 1.5rem}.page-item{margin-right:8px}.page-item:first-child .page-link>span:not(.sr-only)::before,.page-item:last-child .page-link>span:not(.sr-only)::before{top:-0.125rem}.page-item.active .page-link:hover,.page-item:active .page-link:hover{background-color:var(--t42-color-opacity-05)}.page-item.active.disabled .page-link{background-color:var(--t42-color-opacity-10)}.popover{position:absolute;top:0;left:0 /* rtl:ignore */;z-index:1070;display:block;max-width:276px;font-family:"Montserrat","Helvetica Neue",Arial,sans-serif;font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.65625rem;word-wrap:break-word;background-color:Rgba(var(--t42-bg-dark), 0.75);background-clip:padding-box;border:1px solid var(--t42-color-opacity-10);border-radius:0}.popover .popover-arrow{position:absolute;display:block;width:1rem;height:.5rem}.popover .popover-arrow::before,.popover .popover-arrow::after{position:absolute;display:block;content:"";border-color:transparent;border-style:solid}.bs-popover-top>.popover-arrow,.bs-popover-auto[data-popper-placement^="top"]>.popover-arrow{bottom:calc(-.5rem - 1px)}.bs-popover-top>.popover-arrow::before,.bs-popover-auto[data-popper-placement^="top"]>.popover-arrow::before{bottom:0;border-width:.5rem .5rem 0;border-top-color:var(--t42-color-opacity-10)}.bs-popover-top>.popover-arrow::after,.bs-popover-auto[data-popper-placement^="top"]>.popover-arrow::after{bottom:1px;border-width:.5rem .5rem 0;border-top-color:var(--t42-color-opacity-10)}.bs-popover-end>.popover-arrow,.bs-popover-auto[data-popper-placement^="right"]>.popover-arrow{left:calc(-.5rem - 1px);width:.5rem;height:1rem}.bs-popover-end>.popover-arrow::before,.bs-popover-auto[data-popper-placement^="right"]>.popover-arrow::before{left:0;border-width:.5rem .5rem .5rem 0;border-right-color:var(--t42-color-opacity-10)}.bs-popover-end>.popover-arrow::after,.bs-popover-auto[data-popper-placement^="right"]>.popover-arrow::after{left:1px;border-width:.5rem .5rem .5rem 0;border-right-color:var(--t42-color-opacity-10)}.bs-popover-bottom>.popover-arrow,.bs-popover-auto[data-popper-placement^="bottom"]>.popover-arrow{top:calc(-.5rem - 1px)}.bs-popover-bottom>.popover-arrow::before,.bs-popover-auto[data-popper-placement^="bottom"]>.popover-arrow::before{top:0;border-width:0 .5rem .5rem .5rem;border-bottom-color:var(--t42-color-opacity-10)}.bs-popover-bottom>.popover-arrow::after,.bs-popover-auto[data-popper-placement^="bottom"]>.popover-arrow::after{top:1px;border-width:0 .5rem .5rem .5rem;border-bottom-color:var(--t42-color-opacity-10)}.bs-popover-bottom .popover-header::before,.bs-popover-auto[data-popper-placement^="bottom"] .popover-header::before{position:absolute;top:0;left:50%;display:block;width:1rem;margin-left:-.5rem;content:"";border-bottom:1px solid Rgba(var(--t42-bg-mid), 0.75)}.bs-popover-start>.popover-arrow,.bs-popover-auto[data-popper-placement^="left"]>.popover-arrow{right:calc(-.5rem - 1px);width:.5rem;height:1rem}.bs-popover-start>.popover-arrow::before,.bs-popover-auto[data-popper-placement^="left"]>.popover-arrow::before{right:0;border-width:.5rem 0 .5rem .5rem;border-left-color:var(--t42-color-opacity-10)}.bs-popover-start>.popover-arrow::after,.bs-popover-auto[data-popper-placement^="left"]>.popover-arrow::after{right:1px;border-width:.5rem 0 .5rem .5rem;border-left-color:var(--t42-color-opacity-10)}.popover-header{padding:.55rem 1rem;margin-bottom:0;font-size:.75rem;color:var(--t42-link-color);background-color:Rgba(var(--t42-bg-mid), 0.75);border-bottom:1px solid var(--t42-color-opacity-10);border-top-left-radius:0;border-top-right-radius:0}.popover-header:empty{display:none}.popover-body{padding:1rem 1rem;color:var(--t42-content-color)}.popover{backdrop-filter:var(--backdrop-filter)}@keyframes progress-bar-stripes{0%{background-position-x:1.063rem}}.progress{display:flex;height:1.063rem;overflow:hidden;font-size:.6rem;background-color:Rgb(var(--t42-bg-mid));border-radius:0}.progress-bar{display:flex;flex-direction:column;justify-content:center;overflow:hidden;color:#fff;text-align:center;white-space:nowrap;background-color:#007be5;transition:width 0.6s ease}@media (prefers-reduced-motion: reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-size:1.063rem 1.063rem}.progress-bar-animated{animation:1s linear infinite progress-bar-stripes}@media (prefers-reduced-motion: reduce){.progress-bar-animated{animation:none}}.progress{border:var(--t42-border)}.table{--bs-table-bg: rgba(0,0,0,0);--bs-table-accent-bg: rgba(0,0,0,0);--bs-table-striped-color: var(--t42-content-color);--bs-table-striped-bg: rgba(0,0,0,0.05);--bs-table-active-color: var(--t42-content-color);--bs-table-active-bg: rgba(0,0,0,0.1);--bs-table-hover-color: var(--t42-link-color);--bs-table-hover-bg: rgba(0,0,0,0.075);width:100%;margin-bottom:1rem;color:var(--t42-content-color);vertical-align:top;border-color:var(--t42-color-opacity-10)}.table>:not(caption)>*>*{padding:.25rem .313rem;background-color:var(--bs-table-bg);border-bottom-width:1px;box-shadow:inset 0 0 0 9999px var(--bs-table-accent-bg)}.table>tbody{vertical-align:inherit}.table>thead{vertical-align:bottom}.table>:not(:first-child){border-top:2px solid currentColor}.caption-top{caption-side:top}.table-sm>:not(caption)>*>*{padding:.25rem .25rem}.table-bordered>:not(caption)>*{border-width:1px 0}.table-bordered>:not(caption)>*>*{border-width:0 1px}.table-borderless>:not(caption)>*>*{border-bottom-width:0}.table-borderless>:not(:first-child){border-top-width:0}.table-striped>tbody>tr:nth-of-type(odd)>*{--bs-table-accent-bg: var(--bs-table-striped-bg);color:var(--bs-table-striped-color)}.table-active{--bs-table-accent-bg: var(--bs-table-active-bg);color:var(--bs-table-active-color)}.table-hover>tbody>tr:hover>*{--bs-table-accent-bg: var(--bs-table-hover-bg);color:var(--bs-table-hover-color)}.table-primary{--bs-table-bg: #cce5fa;--bs-table-striped-bg: #c2daee;--bs-table-striped-color: #000;--bs-table-active-bg: #b8cee1;--bs-table-active-color: #000;--bs-table-hover-bg: #bdd4e7;--bs-table-hover-color: #000;color:#000;border-color:#b8cee1}.table-secondary{--bs-table-bg: #dfdfdf;--bs-table-striped-bg: #d4d4d4;--bs-table-striped-color: #000;--bs-table-active-bg: #c9c9c9;--bs-table-active-color: #000;--bs-table-hover-bg: #cecece;--bs-table-hover-color: #000;color:#000;border-color:#c9c9c9}.table-success{--bs-table-bg: #d9ecda;--bs-table-striped-bg: #cee0cf;--bs-table-striped-color: #000;--bs-table-active-bg: #c3d4c4;--bs-table-active-color: #000;--bs-table-hover-bg: #c9daca;--bs-table-hover-color: #000;color:#000;border-color:#c3d4c4}.table-info{--bs-table-bg: #daecf1;--bs-table-striped-bg: #cfe0e5;--bs-table-striped-color: #000;--bs-table-active-bg: #c4d4d9;--bs-table-active-color: #000;--bs-table-hover-bg: #cadadf;--bs-table-hover-color: #000;color:#000;border-color:#c4d4d9}.table-warning{--bs-table-bg: #feeed3;--bs-table-striped-bg: #f1e2c8;--bs-table-striped-color: #000;--bs-table-active-bg: #e5d6be;--bs-table-active-color: #000;--bs-table-hover-bg: #ebdcc3;--bs-table-hover-color: #000;color:#000;border-color:#e5d6be}.table-danger{--bs-table-bg: #ffdcd2;--bs-table-striped-bg: #f2d1c8;--bs-table-striped-color: #000;--bs-table-active-bg: #e6c6bd;--bs-table-active-color: #000;--bs-table-hover-bg: #ecccc2;--bs-table-hover-color: #000;color:#000;border-color:#e6c6bd}.table-light{--bs-table-bg: #616161;--bs-table-striped-bg: dimgray;--bs-table-striped-color: #fff;--bs-table-active-bg: #717171;--bs-table-active-color: #fff;--bs-table-hover-bg: #6d6d6d;--bs-table-hover-color: #fff;color:#fff;border-color:#717171}.table-dark{--bs-table-bg: #616161;--bs-table-striped-bg: dimgray;--bs-table-striped-color: #fff;--bs-table-active-bg: #717171;--bs-table-active-color: #fff;--bs-table-hover-bg: #6d6d6d;--bs-table-hover-color: #fff;color:#fff;border-color:#717171}.table-responsive{overflow-x:auto;-webkit-overflow-scrolling:touch}@media (max-width: 575.98px){.table-responsive-sm{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width: 767.98px){.table-responsive-md{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width: 991.98px){.table-responsive-lg{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width: 1199.98px){.table-responsive-xl{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width: 1399.98px){.table-responsive-xxl{overflow-x:auto;-webkit-overflow-scrolling:touch}}.table>:not(:first-child){border-width:0}.table td,.table th{white-space:nowrap;vertical-align:middle}.table a{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border;border-bottom:0.063rem dashed var(--dark);color:var(--t42-content-color)}.table a:hover{border-bottom-color:var(--t42-content-color);border-bottom-style:solid;color:var(--t42-link-color);text-decoration:none}.table thead th{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;border-width:1px 0;color:Hsl(var(--t42-content-color-base), calc(var(--t42-content-color-l) - 20%));font-weight:normal;font-size:83.3%;text-transform:uppercase}.table td{position:relative}.table td .btn,.table td .btn-sm,.table td .btn-group-sm>.btn,.table td .btn-lg,.table td .btn-group-lg>.btn{line-height:1.25rem}.table td .btn-icon i{position:relative;top:0.0625rem}.table tr th:first-child,.table tr td:first-child{padding-left:0.5rem}.table tr th:last-child,.table tr td:last-child{padding-right:0.5rem}.table-hover tbody tr:hover{background-color:var(--t42-table-active-bg)}.table-hover tbody tr:hover a{border-bottom-color:var(--t42-content-color);color:var(--t42-link-color)}.table-responsive{border:0}.tooltip{position:absolute;z-index:1080;display:block;margin:0;font-family:"Montserrat","Helvetica Neue",Arial,sans-serif;font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.65625rem;word-wrap:break-word;opacity:0}.tooltip.show{opacity:1}.tooltip .tooltip-arrow{position:absolute;display:block;width:.8rem;height:.4rem}.tooltip .tooltip-arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-top,.bs-tooltip-auto[data-popper-placement^="top"]{padding:.4rem 0}.bs-tooltip-top .tooltip-arrow,.bs-tooltip-auto[data-popper-placement^="top"] .tooltip-arrow{bottom:0}.bs-tooltip-top .tooltip-arrow::before,.bs-tooltip-auto[data-popper-placement^="top"] .tooltip-arrow::before{top:-1px;border-width:.4rem .4rem 0;border-top-color:var(--t42-tooltip-bg)}.bs-tooltip-end,.bs-tooltip-auto[data-popper-placement^="right"]{padding:0 .4rem}.bs-tooltip-end .tooltip-arrow,.bs-tooltip-auto[data-popper-placement^="right"] .tooltip-arrow{left:0;width:.4rem;height:.8rem}.bs-tooltip-end .tooltip-arrow::before,.bs-tooltip-auto[data-popper-placement^="right"] .tooltip-arrow::before{right:-1px;border-width:.4rem .4rem .4rem 0;border-right-color:var(--t42-tooltip-bg)}.bs-tooltip-bottom,.bs-tooltip-auto[data-popper-placement^="bottom"]{padding:.4rem 0}.bs-tooltip-bottom .tooltip-arrow,.bs-tooltip-auto[data-popper-placement^="bottom"] .tooltip-arrow{top:0}.bs-tooltip-bottom .tooltip-arrow::before,.bs-tooltip-auto[data-popper-placement^="bottom"] .tooltip-arrow::before{bottom:-1px;border-width:0 .4rem .4rem;border-bottom-color:var(--t42-tooltip-bg)}.bs-tooltip-start,.bs-tooltip-auto[data-popper-placement^="left"]{padding:0 .4rem}.bs-tooltip-start .tooltip-arrow,.bs-tooltip-auto[data-popper-placement^="left"] .tooltip-arrow{right:0;width:.4rem;height:.8rem}.bs-tooltip-start .tooltip-arrow::before,.bs-tooltip-auto[data-popper-placement^="left"] .tooltip-arrow::before{left:-1px;border-width:.4rem 0 .4rem .4rem;border-left-color:var(--t42-tooltip-bg)}.tooltip-inner{max-width:200px;padding:.25rem 1rem;color:var(--t42-content-color);text-align:center;background-color:var(--t42-tooltip-bg);border-radius:0}.tooltip .tooltip-inner{border:var(--t42-border);box-shadow:var(--t42-shadow)}.bs-tooltip-top .arrow,.bs-tooltip-auto[data-popper-placement^="top"] .arrow{bottom:1px}.bs-tooltip-top .arrow::before,.bs-tooltip-auto[data-popper-placement^="top"] .arrow::before{border-top-color:var(--t42-color-opacity-10)}.bs-tooltip-bottom .arrow,.bs-tooltip-auto[data-popper-placement^="bottom"] .arrow{top:1px}.bs-tooltip-bottom .arrow::before,.bs-tooltip-auto[data-popper-placement^="bottom"] .arrow::before{border-bottom-color:var(--t42-color-opacity-10)}.bs-tooltip-right .arrow{left:1px}.bs-tooltip-right .arrow::before{border-right-color:var(--t42-color-opacity-10)}.bs-tooltip-left .arrow{right:1px}.bs-tooltip-left .arrow::before{border-left-color:var(--t42-color-opacity-10)}.fade{transition:opacity 0.15s linear}@media (prefers-reduced-motion: reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{height:0;overflow:hidden;transition:height 0.35s ease}@media (prefers-reduced-motion: reduce){.collapsing{transition:none}}.collapsing.collapse-horizontal{width:0;height:auto;transition:width 0.35s ease}@media (prefers-reduced-motion: reduce){.collapsing.collapse-horizontal{transition:none}}mark,.mark{color:var(--white)}pre{background-color:var(--t42-bg-dark)}blockquote,.blockquote{padding:1rem 1rem 0.01rem;border-left:0.25rem solid var(--secondary);background-color:Rgb(var(--t42-bg-dark))}.blockquote-footer{margin-top:-2rem;margin-left:1.25rem;color:var(--t42-content-color-muted);font-size:0.875em}.clearfix::after{display:block;clear:both;content:""}.link-primary{color:#007be5}.link-primary:hover,.link-primary:focus{color:#3395ea}.link-secondary{color:#616161}.link-secondary:hover,.link-secondary:focus{color:#4e4e4e}.link-success{color:#43a047}.link-success:hover,.link-success:focus{color:#69b36c}.link-info{color:#469eb9}.link-info:hover,.link-info:focus{color:#6bb1c7}.link-warning{color:#f9a825}.link-warning:hover,.link-warning:focus{color:#fab951}.link-danger{color:#ff511f}.link-danger:hover,.link-danger:focus{color:#ff744c}.link-light{color:#616161}.link-light:hover,.link-light:focus{color:#4e4e4e}.link-dark{color:#616161}.link-dark:hover,.link-dark:focus{color:#4e4e4e}.ratio{position:relative;width:100%}.ratio::before{display:block;padding-top:var(--bs-aspect-ratio);content:""}.ratio>*{position:absolute;top:0;left:0;width:100%;height:100%}.ratio-1x1{--bs-aspect-ratio: 100%}.ratio-4x3{--bs-aspect-ratio: calc(3 / 4 * 100%)}.ratio-16x9{--bs-aspect-ratio: calc(9 / 16 * 100%)}.ratio-21x9{--bs-aspect-ratio: calc(9 / 21 * 100%)}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}.sticky-top{position:sticky;top:0;z-index:1020}@media (min-width: 576px){.sticky-sm-top{position:sticky;top:0;z-index:1020}}@media (min-width: 768px){.sticky-md-top{position:sticky;top:0;z-index:1020}}@media (min-width: 992px){.sticky-lg-top{position:sticky;top:0;z-index:1020}}@media (min-width: 1200px){.sticky-xl-top{position:sticky;top:0;z-index:1020}}@media (min-width: 1400px){.sticky-xxl-top{position:sticky;top:0;z-index:1020}}.hstack{display:flex;flex-direction:row;align-items:center;align-self:stretch}.vstack{display:flex;flex:1 1 auto;flex-direction:column;align-self:stretch}.visually-hidden,.visually-hidden-focusable:not(:focus):not(:focus-within){position:absolute !important;width:1px !important;height:1px !important;padding:0 !important;margin:-1px !important;overflow:hidden !important;clip:rect(0, 0, 0, 0) !important;white-space:nowrap !important;border:0 !important}.stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.vr{display:inline-block;align-self:stretch;width:1px;min-height:1em;background-color:currentColor;opacity:.25}.align-baseline{vertical-align:baseline !important}.align-top{vertical-align:top !important}.align-middle{vertical-align:middle !important}.align-bottom{vertical-align:bottom !important}.align-text-bottom{vertical-align:text-bottom !important}.align-text-top{vertical-align:text-top !important}.float-start{float:left !important}.float-end{float:right !important}.float-none{float:none !important}.opacity-0{opacity:0 !important}.opacity-25{opacity:.25 !important}.opacity-50{opacity:.5 !important}.opacity-75{opacity:.75 !important}.opacity-100{opacity:1 !important}.overflow-auto{overflow:auto !important}.overflow-hidden{overflow:hidden !important}.overflow-visible{overflow:visible !important}.overflow-scroll{overflow:scroll !important}.d-inline{display:inline !important}.d-inline-block{display:inline-block !important}.d-block{display:block !important}.d-grid{display:grid !important}.d-table{display:table !important}.d-table-row{display:table-row !important}.d-table-cell{display:table-cell !important}.d-flex{display:flex !important}.d-inline-flex{display:inline-flex !important}.d-none{display:none !important}.shadow{box-shadow:0 0.5rem 1rem rgba(0,0,0,0.15) !important}.shadow-sm{box-shadow:0 0.125rem 0.25rem rgba(0,0,0,0.075) !important}.shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,0.175) !important}.shadow-none{box-shadow:none !important}.position-static{position:static !important}.position-relative{position:relative !important}.position-absolute{position:absolute !important}.position-fixed{position:fixed !important}.position-sticky{position:sticky !important}.top-0{top:0 !important}.top-50{top:50% !important}.top-100{top:100% !important}.bottom-0{bottom:0 !important}.bottom-50{bottom:50% !important}.bottom-100{bottom:100% !important}.start-0{left:0 !important}.start-50{left:50% !important}.start-100{left:100% !important}.end-0{right:0 !important}.end-50{right:50% !important}.end-100{right:100% !important}.translate-middle{transform:translate(-50%, -50%) !important}.translate-middle-x{transform:translateX(-50%) !important}.translate-middle-y{transform:translateY(-50%) !important}.border{border:1px solid #dee2e6 !important}.border-0{border:0 !important}.border-top{border-top:1px solid #dee2e6 !important}.border-top-0{border-top:0 !important}.border-end{border-right:1px solid #dee2e6 !important}.border-end-0{border-right:0 !important}.border-bottom{border-bottom:1px solid #dee2e6 !important}.border-bottom-0{border-bottom:0 !important}.border-start{border-left:1px solid #dee2e6 !important}.border-start-0{border-left:0 !important}.border-primary{border-color:#007be5 !important}.border-secondary{border-color:#616161 !important}.border-success{border-color:#43a047 !important}.border-info{border-color:#469eb9 !important}.border-warning{border-color:#f9a825 !important}.border-danger{border-color:#ff511f !important}.border-light{border-color:#616161 !important}.border-dark{border-color:#616161 !important}.border-white{border-color:#fff !important}.border-1{border-width:1px !important}.border-2{border-width:2px !important}.border-3{border-width:3px !important}.border-4{border-width:4px !important}.border-5{border-width:5px !important}.w-25{width:25% !important}.w-50{width:50% !important}.w-75{width:75% !important}.w-100{width:100% !important}.w-auto{width:auto !important}.mw-100{max-width:100% !important}.vw-100{width:100vw !important}.min-vw-100{min-width:100vw !important}.h-25{height:25% !important}.h-50{height:50% !important}.h-75{height:75% !important}.h-100{height:100% !important}.h-auto{height:auto !important}.mh-100{max-height:100% !important}.vh-100{height:100vh !important}.min-vh-100{min-height:100vh !important}.flex-fill{flex:1 1 auto !important}.flex-row{flex-direction:row !important}.flex-column{flex-direction:column !important}.flex-row-reverse{flex-direction:row-reverse !important}.flex-column-reverse{flex-direction:column-reverse !important}.flex-grow-0{flex-grow:0 !important}.flex-grow-1{flex-grow:1 !important}.flex-shrink-0{flex-shrink:0 !important}.flex-shrink-1{flex-shrink:1 !important}.flex-wrap{flex-wrap:wrap !important}.flex-nowrap{flex-wrap:nowrap !important}.flex-wrap-reverse{flex-wrap:wrap-reverse !important}.gap-0{gap:0 !important}.gap-1{gap:.25rem !important}.gap-2{gap:.5rem !important}.gap-3{gap:1rem !important}.gap-4{gap:1.5rem !important}.gap-5{gap:3rem !important}.justify-content-start{justify-content:flex-start !important}.justify-content-end{justify-content:flex-end !important}.justify-content-center{justify-content:center !important}.justify-content-between{justify-content:space-between !important}.justify-content-around{justify-content:space-around !important}.justify-content-evenly{justify-content:space-evenly !important}.align-items-start{align-items:flex-start !important}.align-items-end{align-items:flex-end !important}.align-items-center{align-items:center !important}.align-items-baseline{align-items:baseline !important}.align-items-stretch{align-items:stretch !important}.align-content-start{align-content:flex-start !important}.align-content-end{align-content:flex-end !important}.align-content-center{align-content:center !important}.align-content-between{align-content:space-between !important}.align-content-around{align-content:space-around !important}.align-content-stretch{align-content:stretch !important}.align-self-auto{align-self:auto !important}.align-self-start{align-self:flex-start !important}.align-self-end{align-self:flex-end !important}.align-self-center{align-self:center !important}.align-self-baseline{align-self:baseline !important}.align-self-stretch{align-self:stretch !important}.order-first{order:-1 !important}.order-0{order:0 !important}.order-1{order:1 !important}.order-2{order:2 !important}.order-3{order:3 !important}.order-4{order:4 !important}.order-5{order:5 !important}.order-last{order:6 !important}.m-0{margin:0 !important}.m-1{margin:.25rem !important}.m-2{margin:.5rem !important}.m-3{margin:1rem !important}.m-4{margin:1.5rem !important}.m-5{margin:3rem !important}.m-auto{margin:auto !important}.mx-0{margin-right:0 !important;margin-left:0 !important}.mx-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-3{margin-right:1rem !important;margin-left:1rem !important}.mx-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-5{margin-right:3rem !important;margin-left:3rem !important}.mx-auto{margin-right:auto !important;margin-left:auto !important}.my-0{margin-top:0 !important;margin-bottom:0 !important}.my-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-0{margin-top:0 !important}.mt-1{margin-top:.25rem !important}.mt-2{margin-top:.5rem !important}.mt-3{margin-top:1rem !important}.mt-4{margin-top:1.5rem !important}.mt-5{margin-top:3rem !important}.mt-auto{margin-top:auto !important}.me-0{margin-right:0 !important}.me-1{margin-right:.25rem !important}.me-2{margin-right:.5rem !important}.me-3{margin-right:1rem !important}.me-4{margin-right:1.5rem !important}.me-5{margin-right:3rem !important}.me-auto{margin-right:auto !important}.mb-0{margin-bottom:0 !important}.mb-1{margin-bottom:.25rem !important}.mb-2{margin-bottom:.5rem !important}.mb-3{margin-bottom:1rem !important}.mb-4{margin-bottom:1.5rem !important}.mb-5{margin-bottom:3rem !important}.mb-auto{margin-bottom:auto !important}.ms-0{margin-left:0 !important}.ms-1{margin-left:.25rem !important}.ms-2{margin-left:.5rem !important}.ms-3{margin-left:1rem !important}.ms-4{margin-left:1.5rem !important}.ms-5{margin-left:3rem !important}.ms-auto{margin-left:auto !important}.p-0{padding:0 !important}.p-1{padding:.25rem !important}.p-2{padding:.5rem !important}.p-3{padding:1rem !important}.p-4{padding:1.5rem !important}.p-5{padding:3rem !important}.px-0{padding-right:0 !important;padding-left:0 !important}.px-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-3{padding-right:1rem !important;padding-left:1rem !important}.px-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-5{padding-right:3rem !important;padding-left:3rem !important}.py-0{padding-top:0 !important;padding-bottom:0 !important}.py-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-0{padding-top:0 !important}.pt-1{padding-top:.25rem !important}.pt-2{padding-top:.5rem !important}.pt-3{padding-top:1rem !important}.pt-4{padding-top:1.5rem !important}.pt-5{padding-top:3rem !important}.pe-0{padding-right:0 !important}.pe-1{padding-right:.25rem !important}.pe-2{padding-right:.5rem !important}.pe-3{padding-right:1rem !important}.pe-4{padding-right:1.5rem !important}.pe-5{padding-right:3rem !important}.pb-0{padding-bottom:0 !important}.pb-1{padding-bottom:.25rem !important}.pb-2{padding-bottom:.5rem !important}.pb-3{padding-bottom:1rem !important}.pb-4{padding-bottom:1.5rem !important}.pb-5{padding-bottom:3rem !important}.ps-0{padding-left:0 !important}.ps-1{padding-left:.25rem !important}.ps-2{padding-left:.5rem !important}.ps-3{padding-left:1rem !important}.ps-4{padding-left:1.5rem !important}.ps-5{padding-left:3rem !important}.font-monospace{font-family:var(--bs-font-monospace) !important}.fs-1{font-size:calc(1.26563rem + .1875vw) !important}.fs-2{font-size:1.125rem !important}.fs-3{font-size:.98475rem !important}.fs-4{font-size:.84375rem !important}.fs-5{font-size:.75rem !important}.fs-6{font-size:.7035rem !important}.fst-italic{font-style:italic !important}.fst-normal{font-style:normal !important}.fw-light{font-weight:300 !important}.fw-lighter{font-weight:lighter !important}.fw-normal{font-weight:400 !important}.fw-bold{font-weight:700 !important}.fw-bolder{font-weight:bolder !important}.lh-1{line-height:1 !important}.lh-sm{line-height:1.25 !important}.lh-base{line-height:1.5 !important}.lh-lg{line-height:2 !important}.text-start{text-align:left !important}.text-end{text-align:right !important}.text-center{text-align:center !important}.text-decoration-none{text-decoration:none !important}.text-decoration-underline{text-decoration:underline !important}.text-decoration-line-through{text-decoration:line-through !important}.text-lowercase{text-transform:lowercase !important}.text-uppercase{text-transform:uppercase !important}.text-capitalize{text-transform:capitalize !important}.text-wrap{white-space:normal !important}.text-nowrap{white-space:nowrap !important}.text-break{word-wrap:break-word !important;word-break:break-word !important}.text-primary{--bs-text-opacity: 1;color:rgba(var(--bs-primary-rgb), var(--bs-text-opacity)) !important}.text-secondary{--bs-text-opacity: 1;color:rgba(var(--bs-secondary-rgb), var(--bs-text-opacity)) !important}.text-success{--bs-text-opacity: 1;color:rgba(var(--bs-success-rgb), var(--bs-text-opacity)) !important}.text-info{--bs-text-opacity: 1;color:rgba(var(--bs-info-rgb), var(--bs-text-opacity)) !important}.text-warning{--bs-text-opacity: 1;color:rgba(var(--bs-warning-rgb), var(--bs-text-opacity)) !important}.text-danger{--bs-text-opacity: 1;color:rgba(var(--bs-danger-rgb), var(--bs-text-opacity)) !important}.text-light{--bs-text-opacity: 1;color:rgba(var(--bs-light-rgb), var(--bs-text-opacity)) !important}.text-dark{--bs-text-opacity: 1;color:rgba(var(--bs-dark-rgb), var(--bs-text-opacity)) !important}.text-black{--bs-text-opacity: 1;color:rgba(var(--bs-black-rgb), var(--bs-text-opacity)) !important}.text-white{--bs-text-opacity: 1;color:rgba(var(--bs-white-rgb), var(--bs-text-opacity)) !important}.text-body{--bs-text-opacity: 1;color:rgba(var(--bs-body-color-rgb), var(--bs-text-opacity)) !important}.text-muted{--bs-text-opacity: 1;color:var(--t42-content-color-muted) !important}.text-black-50{--bs-text-opacity: 1;color:rgba(0,0,0,0.5) !important}.text-white-50{--bs-text-opacity: 1;color:rgba(255,255,255,0.5) !important}.text-reset{--bs-text-opacity: 1;color:inherit !important}.text-opacity-25{--bs-text-opacity: .25}.text-opacity-50{--bs-text-opacity: .5}.text-opacity-75{--bs-text-opacity: .75}.text-opacity-100{--bs-text-opacity: 1}.bg-primary{--bs-bg-opacity: 1;background-color:rgba(var(--bs-primary-rgb), var(--bs-bg-opacity)) !important}.bg-secondary{--bs-bg-opacity: 1;background-color:rgba(var(--bs-secondary-rgb), var(--bs-bg-opacity)) !important}.bg-success{--bs-bg-opacity: 1;background-color:rgba(var(--bs-success-rgb), var(--bs-bg-opacity)) !important}.bg-info{--bs-bg-opacity: 1;background-color:rgba(var(--bs-info-rgb), var(--bs-bg-opacity)) !important}.bg-warning{--bs-bg-opacity: 1;background-color:rgba(var(--bs-warning-rgb), var(--bs-bg-opacity)) !important}.bg-danger{--bs-bg-opacity: 1;background-color:rgba(var(--bs-danger-rgb), var(--bs-bg-opacity)) !important}.bg-light{--bs-bg-opacity: 1;background-color:rgba(var(--bs-light-rgb), var(--bs-bg-opacity)) !important}.bg-dark{--bs-bg-opacity: 1;background-color:rgba(var(--bs-dark-rgb), var(--bs-bg-opacity)) !important}.bg-black{--bs-bg-opacity: 1;background-color:rgba(var(--bs-black-rgb), var(--bs-bg-opacity)) !important}.bg-white{--bs-bg-opacity: 1;background-color:rgba(var(--bs-white-rgb), var(--bs-bg-opacity)) !important}.bg-body{--bs-bg-opacity: 1;background-color:rgba(var(--bs-body-bg-rgb), var(--bs-bg-opacity)) !important}.bg-transparent{--bs-bg-opacity: 1;background-color:rgba(0,0,0,0) !important}.bg-opacity-10{--bs-bg-opacity: .1}.bg-opacity-25{--bs-bg-opacity: .25}.bg-opacity-50{--bs-bg-opacity: .5}.bg-opacity-75{--bs-bg-opacity: .75}.bg-opacity-100{--bs-bg-opacity: 1}.bg-gradient{background-image:var(--bs-gradient) !important}.user-select-all{user-select:all !important}.user-select-auto{user-select:auto !important}.user-select-none{user-select:none !important}.pe-none{pointer-events:none !important}.pe-auto{pointer-events:auto !important}.rounded{border-radius:.25rem !important}.rounded-0{border-radius:0 !important}.rounded-1{border-radius:.25rem !important}.rounded-2{border-radius:.25rem !important}.rounded-3{border-radius:1rem !important}.rounded-circle{border-radius:50% !important}.rounded-pill{border-radius:50rem !important}.rounded-top{border-top-left-radius:.25rem !important;border-top-right-radius:.25rem !important}.rounded-end{border-top-right-radius:.25rem !important;border-bottom-right-radius:.25rem !important}.rounded-bottom{border-bottom-right-radius:.25rem !important;border-bottom-left-radius:.25rem !important}.rounded-start{border-bottom-left-radius:.25rem !important;border-top-left-radius:.25rem !important}.visible{visibility:visible !important}.invisible{visibility:hidden !important}@media (min-width: 576px){.float-sm-start{float:left !important}.float-sm-end{float:right !important}.float-sm-none{float:none !important}.d-sm-inline{display:inline !important}.d-sm-inline-block{display:inline-block !important}.d-sm-block{display:block !important}.d-sm-grid{display:grid !important}.d-sm-table{display:table !important}.d-sm-table-row{display:table-row !important}.d-sm-table-cell{display:table-cell !important}.d-sm-flex{display:flex !important}.d-sm-inline-flex{display:inline-flex !important}.d-sm-none{display:none !important}.flex-sm-fill{flex:1 1 auto !important}.flex-sm-row{flex-direction:row !important}.flex-sm-column{flex-direction:column !important}.flex-sm-row-reverse{flex-direction:row-reverse !important}.flex-sm-column-reverse{flex-direction:column-reverse !important}.flex-sm-grow-0{flex-grow:0 !important}.flex-sm-grow-1{flex-grow:1 !important}.flex-sm-shrink-0{flex-shrink:0 !important}.flex-sm-shrink-1{flex-shrink:1 !important}.flex-sm-wrap{flex-wrap:wrap !important}.flex-sm-nowrap{flex-wrap:nowrap !important}.flex-sm-wrap-reverse{flex-wrap:wrap-reverse !important}.gap-sm-0{gap:0 !important}.gap-sm-1{gap:.25rem !important}.gap-sm-2{gap:.5rem !important}.gap-sm-3{gap:1rem !important}.gap-sm-4{gap:1.5rem !important}.gap-sm-5{gap:3rem !important}.justify-content-sm-start{justify-content:flex-start !important}.justify-content-sm-end{justify-content:flex-end !important}.justify-content-sm-center{justify-content:center !important}.justify-content-sm-between{justify-content:space-between !important}.justify-content-sm-around{justify-content:space-around !important}.justify-content-sm-evenly{justify-content:space-evenly !important}.align-items-sm-start{align-items:flex-start !important}.align-items-sm-end{align-items:flex-end !important}.align-items-sm-center{align-items:center !important}.align-items-sm-baseline{align-items:baseline !important}.align-items-sm-stretch{align-items:stretch !important}.align-content-sm-start{align-content:flex-start !important}.align-content-sm-end{align-content:flex-end !important}.align-content-sm-center{align-content:center !important}.align-content-sm-between{align-content:space-between !important}.align-content-sm-around{align-content:space-around !important}.align-content-sm-stretch{align-content:stretch !important}.align-self-sm-auto{align-self:auto !important}.align-self-sm-start{align-self:flex-start !important}.align-self-sm-end{align-self:flex-end !important}.align-self-sm-center{align-self:center !important}.align-self-sm-baseline{align-self:baseline !important}.align-self-sm-stretch{align-self:stretch !important}.order-sm-first{order:-1 !important}.order-sm-0{order:0 !important}.order-sm-1{order:1 !important}.order-sm-2{order:2 !important}.order-sm-3{order:3 !important}.order-sm-4{order:4 !important}.order-sm-5{order:5 !important}.order-sm-last{order:6 !important}.m-sm-0{margin:0 !important}.m-sm-1{margin:.25rem !important}.m-sm-2{margin:.5rem !important}.m-sm-3{margin:1rem !important}.m-sm-4{margin:1.5rem !important}.m-sm-5{margin:3rem !important}.m-sm-auto{margin:auto !important}.mx-sm-0{margin-right:0 !important;margin-left:0 !important}.mx-sm-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-sm-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-sm-3{margin-right:1rem !important;margin-left:1rem !important}.mx-sm-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-sm-5{margin-right:3rem !important;margin-left:3rem !important}.mx-sm-auto{margin-right:auto !important;margin-left:auto !important}.my-sm-0{margin-top:0 !important;margin-bottom:0 !important}.my-sm-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-sm-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-sm-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-sm-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-sm-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-sm-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-sm-0{margin-top:0 !important}.mt-sm-1{margin-top:.25rem !important}.mt-sm-2{margin-top:.5rem !important}.mt-sm-3{margin-top:1rem !important}.mt-sm-4{margin-top:1.5rem !important}.mt-sm-5{margin-top:3rem !important}.mt-sm-auto{margin-top:auto !important}.me-sm-0{margin-right:0 !important}.me-sm-1{margin-right:.25rem !important}.me-sm-2{margin-right:.5rem !important}.me-sm-3{margin-right:1rem !important}.me-sm-4{margin-right:1.5rem !important}.me-sm-5{margin-right:3rem !important}.me-sm-auto{margin-right:auto !important}.mb-sm-0{margin-bottom:0 !important}.mb-sm-1{margin-bottom:.25rem !important}.mb-sm-2{margin-bottom:.5rem !important}.mb-sm-3{margin-bottom:1rem !important}.mb-sm-4{margin-bottom:1.5rem !important}.mb-sm-5{margin-bottom:3rem !important}.mb-sm-auto{margin-bottom:auto !important}.ms-sm-0{margin-left:0 !important}.ms-sm-1{margin-left:.25rem !important}.ms-sm-2{margin-left:.5rem !important}.ms-sm-3{margin-left:1rem !important}.ms-sm-4{margin-left:1.5rem !important}.ms-sm-5{margin-left:3rem !important}.ms-sm-auto{margin-left:auto !important}.p-sm-0{padding:0 !important}.p-sm-1{padding:.25rem !important}.p-sm-2{padding:.5rem !important}.p-sm-3{padding:1rem !important}.p-sm-4{padding:1.5rem !important}.p-sm-5{padding:3rem !important}.px-sm-0{padding-right:0 !important;padding-left:0 !important}.px-sm-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-sm-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-sm-3{padding-right:1rem !important;padding-left:1rem !important}.px-sm-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-sm-5{padding-right:3rem !important;padding-left:3rem !important}.py-sm-0{padding-top:0 !important;padding-bottom:0 !important}.py-sm-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-sm-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-sm-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-sm-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-sm-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-sm-0{padding-top:0 !important}.pt-sm-1{padding-top:.25rem !important}.pt-sm-2{padding-top:.5rem !important}.pt-sm-3{padding-top:1rem !important}.pt-sm-4{padding-top:1.5rem !important}.pt-sm-5{padding-top:3rem !important}.pe-sm-0{padding-right:0 !important}.pe-sm-1{padding-right:.25rem !important}.pe-sm-2{padding-right:.5rem !important}.pe-sm-3{padding-right:1rem !important}.pe-sm-4{padding-right:1.5rem !important}.pe-sm-5{padding-right:3rem !important}.pb-sm-0{padding-bottom:0 !important}.pb-sm-1{padding-bottom:.25rem !important}.pb-sm-2{padding-bottom:.5rem !important}.pb-sm-3{padding-bottom:1rem !important}.pb-sm-4{padding-bottom:1.5rem !important}.pb-sm-5{padding-bottom:3rem !important}.ps-sm-0{padding-left:0 !important}.ps-sm-1{padding-left:.25rem !important}.ps-sm-2{padding-left:.5rem !important}.ps-sm-3{padding-left:1rem !important}.ps-sm-4{padding-left:1.5rem !important}.ps-sm-5{padding-left:3rem !important}.text-sm-start{text-align:left !important}.text-sm-end{text-align:right !important}.text-sm-center{text-align:center !important}}@media (min-width: 768px){.float-md-start{float:left !important}.float-md-end{float:right !important}.float-md-none{float:none !important}.d-md-inline{display:inline !important}.d-md-inline-block{display:inline-block !important}.d-md-block{display:block !important}.d-md-grid{display:grid !important}.d-md-table{display:table !important}.d-md-table-row{display:table-row !important}.d-md-table-cell{display:table-cell !important}.d-md-flex{display:flex !important}.d-md-inline-flex{display:inline-flex !important}.d-md-none{display:none !important}.flex-md-fill{flex:1 1 auto !important}.flex-md-row{flex-direction:row !important}.flex-md-column{flex-direction:column !important}.flex-md-row-reverse{flex-direction:row-reverse !important}.flex-md-column-reverse{flex-direction:column-reverse !important}.flex-md-grow-0{flex-grow:0 !important}.flex-md-grow-1{flex-grow:1 !important}.flex-md-shrink-0{flex-shrink:0 !important}.flex-md-shrink-1{flex-shrink:1 !important}.flex-md-wrap{flex-wrap:wrap !important}.flex-md-nowrap{flex-wrap:nowrap !important}.flex-md-wrap-reverse{flex-wrap:wrap-reverse !important}.gap-md-0{gap:0 !important}.gap-md-1{gap:.25rem !important}.gap-md-2{gap:.5rem !important}.gap-md-3{gap:1rem !important}.gap-md-4{gap:1.5rem !important}.gap-md-5{gap:3rem !important}.justify-content-md-start{justify-content:flex-start !important}.justify-content-md-end{justify-content:flex-end !important}.justify-content-md-center{justify-content:center !important}.justify-content-md-between{justify-content:space-between !important}.justify-content-md-around{justify-content:space-around !important}.justify-content-md-evenly{justify-content:space-evenly !important}.align-items-md-start{align-items:flex-start !important}.align-items-md-end{align-items:flex-end !important}.align-items-md-center{align-items:center !important}.align-items-md-baseline{align-items:baseline !important}.align-items-md-stretch{align-items:stretch !important}.align-content-md-start{align-content:flex-start !important}.align-content-md-end{align-content:flex-end !important}.align-content-md-center{align-content:center !important}.align-content-md-between{align-content:space-between !important}.align-content-md-around{align-content:space-around !important}.align-content-md-stretch{align-content:stretch !important}.align-self-md-auto{align-self:auto !important}.align-self-md-start{align-self:flex-start !important}.align-self-md-end{align-self:flex-end !important}.align-self-md-center{align-self:center !important}.align-self-md-baseline{align-self:baseline !important}.align-self-md-stretch{align-self:stretch !important}.order-md-first{order:-1 !important}.order-md-0{order:0 !important}.order-md-1{order:1 !important}.order-md-2{order:2 !important}.order-md-3{order:3 !important}.order-md-4{order:4 !important}.order-md-5{order:5 !important}.order-md-last{order:6 !important}.m-md-0{margin:0 !important}.m-md-1{margin:.25rem !important}.m-md-2{margin:.5rem !important}.m-md-3{margin:1rem !important}.m-md-4{margin:1.5rem !important}.m-md-5{margin:3rem !important}.m-md-auto{margin:auto !important}.mx-md-0{margin-right:0 !important;margin-left:0 !important}.mx-md-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-md-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-md-3{margin-right:1rem !important;margin-left:1rem !important}.mx-md-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-md-5{margin-right:3rem !important;margin-left:3rem !important}.mx-md-auto{margin-right:auto !important;margin-left:auto !important}.my-md-0{margin-top:0 !important;margin-bottom:0 !important}.my-md-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-md-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-md-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-md-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-md-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-md-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-md-0{margin-top:0 !important}.mt-md-1{margin-top:.25rem !important}.mt-md-2{margin-top:.5rem !important}.mt-md-3{margin-top:1rem !important}.mt-md-4{margin-top:1.5rem !important}.mt-md-5{margin-top:3rem !important}.mt-md-auto{margin-top:auto !important}.me-md-0{margin-right:0 !important}.me-md-1{margin-right:.25rem !important}.me-md-2{margin-right:.5rem !important}.me-md-3{margin-right:1rem !important}.me-md-4{margin-right:1.5rem !important}.me-md-5{margin-right:3rem !important}.me-md-auto{margin-right:auto !important}.mb-md-0{margin-bottom:0 !important}.mb-md-1{margin-bottom:.25rem !important}.mb-md-2{margin-bottom:.5rem !important}.mb-md-3{margin-bottom:1rem !important}.mb-md-4{margin-bottom:1.5rem !important}.mb-md-5{margin-bottom:3rem !important}.mb-md-auto{margin-bottom:auto !important}.ms-md-0{margin-left:0 !important}.ms-md-1{margin-left:.25rem !important}.ms-md-2{margin-left:.5rem !important}.ms-md-3{margin-left:1rem !important}.ms-md-4{margin-left:1.5rem !important}.ms-md-5{margin-left:3rem !important}.ms-md-auto{margin-left:auto !important}.p-md-0{padding:0 !important}.p-md-1{padding:.25rem !important}.p-md-2{padding:.5rem !important}.p-md-3{padding:1rem !important}.p-md-4{padding:1.5rem !important}.p-md-5{padding:3rem !important}.px-md-0{padding-right:0 !important;padding-left:0 !important}.px-md-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-md-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-md-3{padding-right:1rem !important;padding-left:1rem !important}.px-md-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-md-5{padding-right:3rem !important;padding-left:3rem !important}.py-md-0{padding-top:0 !important;padding-bottom:0 !important}.py-md-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-md-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-md-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-md-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-md-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-md-0{padding-top:0 !important}.pt-md-1{padding-top:.25rem !important}.pt-md-2{padding-top:.5rem !important}.pt-md-3{padding-top:1rem !important}.pt-md-4{padding-top:1.5rem !important}.pt-md-5{padding-top:3rem !important}.pe-md-0{padding-right:0 !important}.pe-md-1{padding-right:.25rem !important}.pe-md-2{padding-right:.5rem !important}.pe-md-3{padding-right:1rem !important}.pe-md-4{padding-right:1.5rem !important}.pe-md-5{padding-right:3rem !important}.pb-md-0{padding-bottom:0 !important}.pb-md-1{padding-bottom:.25rem !important}.pb-md-2{padding-bottom:.5rem !important}.pb-md-3{padding-bottom:1rem !important}.pb-md-4{padding-bottom:1.5rem !important}.pb-md-5{padding-bottom:3rem !important}.ps-md-0{padding-left:0 !important}.ps-md-1{padding-left:.25rem !important}.ps-md-2{padding-left:.5rem !important}.ps-md-3{padding-left:1rem !important}.ps-md-4{padding-left:1.5rem !important}.ps-md-5{padding-left:3rem !important}.text-md-start{text-align:left !important}.text-md-end{text-align:right !important}.text-md-center{text-align:center !important}}@media (min-width: 992px){.float-lg-start{float:left !important}.float-lg-end{float:right !important}.float-lg-none{float:none !important}.d-lg-inline{display:inline !important}.d-lg-inline-block{display:inline-block !important}.d-lg-block{display:block !important}.d-lg-grid{display:grid !important}.d-lg-table{display:table !important}.d-lg-table-row{display:table-row !important}.d-lg-table-cell{display:table-cell !important}.d-lg-flex{display:flex !important}.d-lg-inline-flex{display:inline-flex !important}.d-lg-none{display:none !important}.flex-lg-fill{flex:1 1 auto !important}.flex-lg-row{flex-direction:row !important}.flex-lg-column{flex-direction:column !important}.flex-lg-row-reverse{flex-direction:row-reverse !important}.flex-lg-column-reverse{flex-direction:column-reverse !important}.flex-lg-grow-0{flex-grow:0 !important}.flex-lg-grow-1{flex-grow:1 !important}.flex-lg-shrink-0{flex-shrink:0 !important}.flex-lg-shrink-1{flex-shrink:1 !important}.flex-lg-wrap{flex-wrap:wrap !important}.flex-lg-nowrap{flex-wrap:nowrap !important}.flex-lg-wrap-reverse{flex-wrap:wrap-reverse !important}.gap-lg-0{gap:0 !important}.gap-lg-1{gap:.25rem !important}.gap-lg-2{gap:.5rem !important}.gap-lg-3{gap:1rem !important}.gap-lg-4{gap:1.5rem !important}.gap-lg-5{gap:3rem !important}.justify-content-lg-start{justify-content:flex-start !important}.justify-content-lg-end{justify-content:flex-end !important}.justify-content-lg-center{justify-content:center !important}.justify-content-lg-between{justify-content:space-between !important}.justify-content-lg-around{justify-content:space-around !important}.justify-content-lg-evenly{justify-content:space-evenly !important}.align-items-lg-start{align-items:flex-start !important}.align-items-lg-end{align-items:flex-end !important}.align-items-lg-center{align-items:center !important}.align-items-lg-baseline{align-items:baseline !important}.align-items-lg-stretch{align-items:stretch !important}.align-content-lg-start{align-content:flex-start !important}.align-content-lg-end{align-content:flex-end !important}.align-content-lg-center{align-content:center !important}.align-content-lg-between{align-content:space-between !important}.align-content-lg-around{align-content:space-around !important}.align-content-lg-stretch{align-content:stretch !important}.align-self-lg-auto{align-self:auto !important}.align-self-lg-start{align-self:flex-start !important}.align-self-lg-end{align-self:flex-end !important}.align-self-lg-center{align-self:center !important}.align-self-lg-baseline{align-self:baseline !important}.align-self-lg-stretch{align-self:stretch !important}.order-lg-first{order:-1 !important}.order-lg-0{order:0 !important}.order-lg-1{order:1 !important}.order-lg-2{order:2 !important}.order-lg-3{order:3 !important}.order-lg-4{order:4 !important}.order-lg-5{order:5 !important}.order-lg-last{order:6 !important}.m-lg-0{margin:0 !important}.m-lg-1{margin:.25rem !important}.m-lg-2{margin:.5rem !important}.m-lg-3{margin:1rem !important}.m-lg-4{margin:1.5rem !important}.m-lg-5{margin:3rem !important}.m-lg-auto{margin:auto !important}.mx-lg-0{margin-right:0 !important;margin-left:0 !important}.mx-lg-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-lg-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-lg-3{margin-right:1rem !important;margin-left:1rem !important}.mx-lg-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-lg-5{margin-right:3rem !important;margin-left:3rem !important}.mx-lg-auto{margin-right:auto !important;margin-left:auto !important}.my-lg-0{margin-top:0 !important;margin-bottom:0 !important}.my-lg-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-lg-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-lg-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-lg-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-lg-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-lg-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-lg-0{margin-top:0 !important}.mt-lg-1{margin-top:.25rem !important}.mt-lg-2{margin-top:.5rem !important}.mt-lg-3{margin-top:1rem !important}.mt-lg-4{margin-top:1.5rem !important}.mt-lg-5{margin-top:3rem !important}.mt-lg-auto{margin-top:auto !important}.me-lg-0{margin-right:0 !important}.me-lg-1{margin-right:.25rem !important}.me-lg-2{margin-right:.5rem !important}.me-lg-3{margin-right:1rem !important}.me-lg-4{margin-right:1.5rem !important}.me-lg-5{margin-right:3rem !important}.me-lg-auto{margin-right:auto !important}.mb-lg-0{margin-bottom:0 !important}.mb-lg-1{margin-bottom:.25rem !important}.mb-lg-2{margin-bottom:.5rem !important}.mb-lg-3{margin-bottom:1rem !important}.mb-lg-4{margin-bottom:1.5rem !important}.mb-lg-5{margin-bottom:3rem !important}.mb-lg-auto{margin-bottom:auto !important}.ms-lg-0{margin-left:0 !important}.ms-lg-1{margin-left:.25rem !important}.ms-lg-2{margin-left:.5rem !important}.ms-lg-3{margin-left:1rem !important}.ms-lg-4{margin-left:1.5rem !important}.ms-lg-5{margin-left:3rem !important}.ms-lg-auto{margin-left:auto !important}.p-lg-0{padding:0 !important}.p-lg-1{padding:.25rem !important}.p-lg-2{padding:.5rem !important}.p-lg-3{padding:1rem !important}.p-lg-4{padding:1.5rem !important}.p-lg-5{padding:3rem !important}.px-lg-0{padding-right:0 !important;padding-left:0 !important}.px-lg-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-lg-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-lg-3{padding-right:1rem !important;padding-left:1rem !important}.px-lg-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-lg-5{padding-right:3rem !important;padding-left:3rem !important}.py-lg-0{padding-top:0 !important;padding-bottom:0 !important}.py-lg-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-lg-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-lg-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-lg-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-lg-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-lg-0{padding-top:0 !important}.pt-lg-1{padding-top:.25rem !important}.pt-lg-2{padding-top:.5rem !important}.pt-lg-3{padding-top:1rem !important}.pt-lg-4{padding-top:1.5rem !important}.pt-lg-5{padding-top:3rem !important}.pe-lg-0{padding-right:0 !important}.pe-lg-1{padding-right:.25rem !important}.pe-lg-2{padding-right:.5rem !important}.pe-lg-3{padding-right:1rem !important}.pe-lg-4{padding-right:1.5rem !important}.pe-lg-5{padding-right:3rem !important}.pb-lg-0{padding-bottom:0 !important}.pb-lg-1{padding-bottom:.25rem !important}.pb-lg-2{padding-bottom:.5rem !important}.pb-lg-3{padding-bottom:1rem !important}.pb-lg-4{padding-bottom:1.5rem !important}.pb-lg-5{padding-bottom:3rem !important}.ps-lg-0{padding-left:0 !important}.ps-lg-1{padding-left:.25rem !important}.ps-lg-2{padding-left:.5rem !important}.ps-lg-3{padding-left:1rem !important}.ps-lg-4{padding-left:1.5rem !important}.ps-lg-5{padding-left:3rem !important}.text-lg-start{text-align:left !important}.text-lg-end{text-align:right !important}.text-lg-center{text-align:center !important}}@media (min-width: 1200px){.float-xl-start{float:left !important}.float-xl-end{float:right !important}.float-xl-none{float:none !important}.d-xl-inline{display:inline !important}.d-xl-inline-block{display:inline-block !important}.d-xl-block{display:block !important}.d-xl-grid{display:grid !important}.d-xl-table{display:table !important}.d-xl-table-row{display:table-row !important}.d-xl-table-cell{display:table-cell !important}.d-xl-flex{display:flex !important}.d-xl-inline-flex{display:inline-flex !important}.d-xl-none{display:none !important}.flex-xl-fill{flex:1 1 auto !important}.flex-xl-row{flex-direction:row !important}.flex-xl-column{flex-direction:column !important}.flex-xl-row-reverse{flex-direction:row-reverse !important}.flex-xl-column-reverse{flex-direction:column-reverse !important}.flex-xl-grow-0{flex-grow:0 !important}.flex-xl-grow-1{flex-grow:1 !important}.flex-xl-shrink-0{flex-shrink:0 !important}.flex-xl-shrink-1{flex-shrink:1 !important}.flex-xl-wrap{flex-wrap:wrap !important}.flex-xl-nowrap{flex-wrap:nowrap !important}.flex-xl-wrap-reverse{flex-wrap:wrap-reverse !important}.gap-xl-0{gap:0 !important}.gap-xl-1{gap:.25rem !important}.gap-xl-2{gap:.5rem !important}.gap-xl-3{gap:1rem !important}.gap-xl-4{gap:1.5rem !important}.gap-xl-5{gap:3rem !important}.justify-content-xl-start{justify-content:flex-start !important}.justify-content-xl-end{justify-content:flex-end !important}.justify-content-xl-center{justify-content:center !important}.justify-content-xl-between{justify-content:space-between !important}.justify-content-xl-around{justify-content:space-around !important}.justify-content-xl-evenly{justify-content:space-evenly !important}.align-items-xl-start{align-items:flex-start !important}.align-items-xl-end{align-items:flex-end !important}.align-items-xl-center{align-items:center !important}.align-items-xl-baseline{align-items:baseline !important}.align-items-xl-stretch{align-items:stretch !important}.align-content-xl-start{align-content:flex-start !important}.align-content-xl-end{align-content:flex-end !important}.align-content-xl-center{align-content:center !important}.align-content-xl-between{align-content:space-between !important}.align-content-xl-around{align-content:space-around !important}.align-content-xl-stretch{align-content:stretch !important}.align-self-xl-auto{align-self:auto !important}.align-self-xl-start{align-self:flex-start !important}.align-self-xl-end{align-self:flex-end !important}.align-self-xl-center{align-self:center !important}.align-self-xl-baseline{align-self:baseline !important}.align-self-xl-stretch{align-self:stretch !important}.order-xl-first{order:-1 !important}.order-xl-0{order:0 !important}.order-xl-1{order:1 !important}.order-xl-2{order:2 !important}.order-xl-3{order:3 !important}.order-xl-4{order:4 !important}.order-xl-5{order:5 !important}.order-xl-last{order:6 !important}.m-xl-0{margin:0 !important}.m-xl-1{margin:.25rem !important}.m-xl-2{margin:.5rem !important}.m-xl-3{margin:1rem !important}.m-xl-4{margin:1.5rem !important}.m-xl-5{margin:3rem !important}.m-xl-auto{margin:auto !important}.mx-xl-0{margin-right:0 !important;margin-left:0 !important}.mx-xl-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-xl-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-xl-3{margin-right:1rem !important;margin-left:1rem !important}.mx-xl-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-xl-5{margin-right:3rem !important;margin-left:3rem !important}.mx-xl-auto{margin-right:auto !important;margin-left:auto !important}.my-xl-0{margin-top:0 !important;margin-bottom:0 !important}.my-xl-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-xl-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-xl-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-xl-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-xl-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-xl-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-xl-0{margin-top:0 !important}.mt-xl-1{margin-top:.25rem !important}.mt-xl-2{margin-top:.5rem !important}.mt-xl-3{margin-top:1rem !important}.mt-xl-4{margin-top:1.5rem !important}.mt-xl-5{margin-top:3rem !important}.mt-xl-auto{margin-top:auto !important}.me-xl-0{margin-right:0 !important}.me-xl-1{margin-right:.25rem !important}.me-xl-2{margin-right:.5rem !important}.me-xl-3{margin-right:1rem !important}.me-xl-4{margin-right:1.5rem !important}.me-xl-5{margin-right:3rem !important}.me-xl-auto{margin-right:auto !important}.mb-xl-0{margin-bottom:0 !important}.mb-xl-1{margin-bottom:.25rem !important}.mb-xl-2{margin-bottom:.5rem !important}.mb-xl-3{margin-bottom:1rem !important}.mb-xl-4{margin-bottom:1.5rem !important}.mb-xl-5{margin-bottom:3rem !important}.mb-xl-auto{margin-bottom:auto !important}.ms-xl-0{margin-left:0 !important}.ms-xl-1{margin-left:.25rem !important}.ms-xl-2{margin-left:.5rem !important}.ms-xl-3{margin-left:1rem !important}.ms-xl-4{margin-left:1.5rem !important}.ms-xl-5{margin-left:3rem !important}.ms-xl-auto{margin-left:auto !important}.p-xl-0{padding:0 !important}.p-xl-1{padding:.25rem !important}.p-xl-2{padding:.5rem !important}.p-xl-3{padding:1rem !important}.p-xl-4{padding:1.5rem !important}.p-xl-5{padding:3rem !important}.px-xl-0{padding-right:0 !important;padding-left:0 !important}.px-xl-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-xl-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-xl-3{padding-right:1rem !important;padding-left:1rem !important}.px-xl-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-xl-5{padding-right:3rem !important;padding-left:3rem !important}.py-xl-0{padding-top:0 !important;padding-bottom:0 !important}.py-xl-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-xl-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-xl-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-xl-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-xl-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-xl-0{padding-top:0 !important}.pt-xl-1{padding-top:.25rem !important}.pt-xl-2{padding-top:.5rem !important}.pt-xl-3{padding-top:1rem !important}.pt-xl-4{padding-top:1.5rem !important}.pt-xl-5{padding-top:3rem !important}.pe-xl-0{padding-right:0 !important}.pe-xl-1{padding-right:.25rem !important}.pe-xl-2{padding-right:.5rem !important}.pe-xl-3{padding-right:1rem !important}.pe-xl-4{padding-right:1.5rem !important}.pe-xl-5{padding-right:3rem !important}.pb-xl-0{padding-bottom:0 !important}.pb-xl-1{padding-bottom:.25rem !important}.pb-xl-2{padding-bottom:.5rem !important}.pb-xl-3{padding-bottom:1rem !important}.pb-xl-4{padding-bottom:1.5rem !important}.pb-xl-5{padding-bottom:3rem !important}.ps-xl-0{padding-left:0 !important}.ps-xl-1{padding-left:.25rem !important}.ps-xl-2{padding-left:.5rem !important}.ps-xl-3{padding-left:1rem !important}.ps-xl-4{padding-left:1.5rem !important}.ps-xl-5{padding-left:3rem !important}.text-xl-start{text-align:left !important}.text-xl-end{text-align:right !important}.text-xl-center{text-align:center !important}}@media (min-width: 1400px){.float-xxl-start{float:left !important}.float-xxl-end{float:right !important}.float-xxl-none{float:none !important}.d-xxl-inline{display:inline !important}.d-xxl-inline-block{display:inline-block !important}.d-xxl-block{display:block !important}.d-xxl-grid{display:grid !important}.d-xxl-table{display:table !important}.d-xxl-table-row{display:table-row !important}.d-xxl-table-cell{display:table-cell !important}.d-xxl-flex{display:flex !important}.d-xxl-inline-flex{display:inline-flex !important}.d-xxl-none{display:none !important}.flex-xxl-fill{flex:1 1 auto !important}.flex-xxl-row{flex-direction:row !important}.flex-xxl-column{flex-direction:column !important}.flex-xxl-row-reverse{flex-direction:row-reverse !important}.flex-xxl-column-reverse{flex-direction:column-reverse !important}.flex-xxl-grow-0{flex-grow:0 !important}.flex-xxl-grow-1{flex-grow:1 !important}.flex-xxl-shrink-0{flex-shrink:0 !important}.flex-xxl-shrink-1{flex-shrink:1 !important}.flex-xxl-wrap{flex-wrap:wrap !important}.flex-xxl-nowrap{flex-wrap:nowrap !important}.flex-xxl-wrap-reverse{flex-wrap:wrap-reverse !important}.gap-xxl-0{gap:0 !important}.gap-xxl-1{gap:.25rem !important}.gap-xxl-2{gap:.5rem !important}.gap-xxl-3{gap:1rem !important}.gap-xxl-4{gap:1.5rem !important}.gap-xxl-5{gap:3rem !important}.justify-content-xxl-start{justify-content:flex-start !important}.justify-content-xxl-end{justify-content:flex-end !important}.justify-content-xxl-center{justify-content:center !important}.justify-content-xxl-between{justify-content:space-between !important}.justify-content-xxl-around{justify-content:space-around !important}.justify-content-xxl-evenly{justify-content:space-evenly !important}.align-items-xxl-start{align-items:flex-start !important}.align-items-xxl-end{align-items:flex-end !important}.align-items-xxl-center{align-items:center !important}.align-items-xxl-baseline{align-items:baseline !important}.align-items-xxl-stretch{align-items:stretch !important}.align-content-xxl-start{align-content:flex-start !important}.align-content-xxl-end{align-content:flex-end !important}.align-content-xxl-center{align-content:center !important}.align-content-xxl-between{align-content:space-between !important}.align-content-xxl-around{align-content:space-around !important}.align-content-xxl-stretch{align-content:stretch !important}.align-self-xxl-auto{align-self:auto !important}.align-self-xxl-start{align-self:flex-start !important}.align-self-xxl-end{align-self:flex-end !important}.align-self-xxl-center{align-self:center !important}.align-self-xxl-baseline{align-self:baseline !important}.align-self-xxl-stretch{align-self:stretch !important}.order-xxl-first{order:-1 !important}.order-xxl-0{order:0 !important}.order-xxl-1{order:1 !important}.order-xxl-2{order:2 !important}.order-xxl-3{order:3 !important}.order-xxl-4{order:4 !important}.order-xxl-5{order:5 !important}.order-xxl-last{order:6 !important}.m-xxl-0{margin:0 !important}.m-xxl-1{margin:.25rem !important}.m-xxl-2{margin:.5rem !important}.m-xxl-3{margin:1rem !important}.m-xxl-4{margin:1.5rem !important}.m-xxl-5{margin:3rem !important}.m-xxl-auto{margin:auto !important}.mx-xxl-0{margin-right:0 !important;margin-left:0 !important}.mx-xxl-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-xxl-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-xxl-3{margin-right:1rem !important;margin-left:1rem !important}.mx-xxl-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-xxl-5{margin-right:3rem !important;margin-left:3rem !important}.mx-xxl-auto{margin-right:auto !important;margin-left:auto !important}.my-xxl-0{margin-top:0 !important;margin-bottom:0 !important}.my-xxl-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-xxl-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-xxl-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-xxl-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-xxl-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-xxl-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-xxl-0{margin-top:0 !important}.mt-xxl-1{margin-top:.25rem !important}.mt-xxl-2{margin-top:.5rem !important}.mt-xxl-3{margin-top:1rem !important}.mt-xxl-4{margin-top:1.5rem !important}.mt-xxl-5{margin-top:3rem !important}.mt-xxl-auto{margin-top:auto !important}.me-xxl-0{margin-right:0 !important}.me-xxl-1{margin-right:.25rem !important}.me-xxl-2{margin-right:.5rem !important}.me-xxl-3{margin-right:1rem !important}.me-xxl-4{margin-right:1.5rem !important}.me-xxl-5{margin-right:3rem !important}.me-xxl-auto{margin-right:auto !important}.mb-xxl-0{margin-bottom:0 !important}.mb-xxl-1{margin-bottom:.25rem !important}.mb-xxl-2{margin-bottom:.5rem !important}.mb-xxl-3{margin-bottom:1rem !important}.mb-xxl-4{margin-bottom:1.5rem !important}.mb-xxl-5{margin-bottom:3rem !important}.mb-xxl-auto{margin-bottom:auto !important}.ms-xxl-0{margin-left:0 !important}.ms-xxl-1{margin-left:.25rem !important}.ms-xxl-2{margin-left:.5rem !important}.ms-xxl-3{margin-left:1rem !important}.ms-xxl-4{margin-left:1.5rem !important}.ms-xxl-5{margin-left:3rem !important}.ms-xxl-auto{margin-left:auto !important}.p-xxl-0{padding:0 !important}.p-xxl-1{padding:.25rem !important}.p-xxl-2{padding:.5rem !important}.p-xxl-3{padding:1rem !important}.p-xxl-4{padding:1.5rem !important}.p-xxl-5{padding:3rem !important}.px-xxl-0{padding-right:0 !important;padding-left:0 !important}.px-xxl-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-xxl-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-xxl-3{padding-right:1rem !important;padding-left:1rem !important}.px-xxl-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-xxl-5{padding-right:3rem !important;padding-left:3rem !important}.py-xxl-0{padding-top:0 !important;padding-bottom:0 !important}.py-xxl-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-xxl-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-xxl-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-xxl-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-xxl-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-xxl-0{padding-top:0 !important}.pt-xxl-1{padding-top:.25rem !important}.pt-xxl-2{padding-top:.5rem !important}.pt-xxl-3{padding-top:1rem !important}.pt-xxl-4{padding-top:1.5rem !important}.pt-xxl-5{padding-top:3rem !important}.pe-xxl-0{padding-right:0 !important}.pe-xxl-1{padding-right:.25rem !important}.pe-xxl-2{padding-right:.5rem !important}.pe-xxl-3{padding-right:1rem !important}.pe-xxl-4{padding-right:1.5rem !important}.pe-xxl-5{padding-right:3rem !important}.pb-xxl-0{padding-bottom:0 !important}.pb-xxl-1{padding-bottom:.25rem !important}.pb-xxl-2{padding-bottom:.5rem !important}.pb-xxl-3{padding-bottom:1rem !important}.pb-xxl-4{padding-bottom:1.5rem !important}.pb-xxl-5{padding-bottom:3rem !important}.ps-xxl-0{padding-left:0 !important}.ps-xxl-1{padding-left:.25rem !important}.ps-xxl-2{padding-left:.5rem !important}.ps-xxl-3{padding-left:1rem !important}.ps-xxl-4{padding-left:1.5rem !important}.ps-xxl-5{padding-left:3rem !important}.text-xxl-start{text-align:left !important}.text-xxl-end{text-align:right !important}.text-xxl-center{text-align:center !important}}@media (min-width: 1200px){.fs-1{font-size:1.40625rem !important}}@media print{.d-print-inline{display:inline !important}.d-print-inline-block{display:inline-block !important}.d-print-block{display:block !important}.d-print-grid{display:grid !important}.d-print-table{display:table !important}.d-print-table-row{display:table-row !important}.d-print-table-cell{display:table-cell !important}.d-print-flex{display:flex !important}.d-print-inline-flex{display:inline-flex !important}.d-print-none{display:none !important}}body{background-size:cover}.bg-light{background-color:Rgb(var(--t42-bg-light)) !important}.bg-dark{background-color:Rgb(var(--t42-bg-dark)) !important}.bg-base{background-color:Rgb(var(--t42-bg-mid)) !important}.border{border:0.0625rem solid var(--t42-color-opacity-10) !important}.border-primary{border-color:#007be5 !important}.border-secondary,.border-info,.border-light,.border-dark,.border-white{border-color:var(--t42-color-opacity-10) !important}.border-success{border-color:#43a047 !important}.border-danger{border-color:#ff511f !important}.border-warning{border-color:#f9a825 !important}.pl-0{padding-left:0}.pl-1{padding-left:0.25rem}.pl-2{padding-left:0.5rem}.pl-3{padding-left:1rem}.pl-4{padding-left:1.5rem}.pl-5{padding-left:3rem}.pl-auto{padding-left:auto}.pr-0{padding-right:0}.pr-1{padding-right:0.25rem}.pr-2{padding-right:0.5rem}.pr-3{padding-right:1rem}.pr-4{padding-right:1.5rem}.pr-5{padding-right:3rem}.pr-auto{padding-right:auto}.ml-0{margin-left:0}.ml-1{margin-left:0.25rem}.ml-2{margin-left:0.5rem}.ml-3{margin-left:1rem}.ml-4{margin-left:1.5rem}.ml-5{margin-left:3rem}.ml-auto{margin-left:auto}.mr-0{margin-right:0}.mr-1{margin-right:0.25rem}.mr-2{margin-right:0.5rem}.mr-3{margin-right:1rem}.mr-4{margin-right:1.5rem}.mr-5{margin-right:3rem}.mr-auto{margin-right:auto}@keyframes spinner-border{to{transform:rotate(360deg) /* rtl:ignore */}}.spinner-border{display:inline-block;width:2rem;height:2rem;vertical-align:-.125em;border:.25em solid currentColor;border-right-color:transparent;border-radius:50%;animation:.75s linear infinite spinner-border}.spinner-border-sm{width:1rem;height:1rem;border-width:.2em}@keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1;transform:none}}.spinner-grow{display:inline-block;width:2rem;height:2rem;vertical-align:-.125em;background-color:currentColor;border-radius:50%;opacity:0;animation:.75s linear infinite spinner-grow}.spinner-grow-sm{width:1rem;height:1rem}@media (prefers-reduced-motion: reduce){.spinner-border,.spinner-grow{animation-duration:1.5s}}.loader-wrapper{display:flex;flex-direction:column;flex-grow:1;gap:1rem;align-items:center;justify-content:center}.loader-wrapper .loader{width:2rem;height:2rem;border-radius:50%;background:radial-gradient(farthest-side, #999d9e 94%, rgba(0,0,0,0)) center top/4px 4px no-repeat,conic-gradient(rgba(0,0,0,0) 15%, #999d9e);-webkit-mask:radial-gradient(farthest-side, rgba(0,0,0,0) calc(100% - 4px), #000 0)}.loader-wrapper.active .loader{animation:s3 1.5s infinite linear}@keyframes s3{to{transform:rotate(1turn)}}.loader-wrapper .loader-text{margin:0 auto;padding:0 0.833rem;overflow:hidden;color:var(--t42-content-color-muted);text-align:center;text-overflow:ellipsis}@keyframes clipMe{0%,100%{clip:rect(0, 220px, 2px, 0)}25%{clip:rect(0, 2px, 220px, 0)}50%{clip:rect(218px, 220px, 220px, 0)}75%{clip:rect(0, 220px, 220px, 218px)}}@keyframes spin{from{transform:rotate(0deg)}to{transform:rotate(360deg)}}.spinner{display:inline-block;animation-name:spin;animation-duration:3000ms;animation-timing-function:linear;animation-iteration-count:infinite}@font-face{font-weight:400;font-family:"Montserrat";font-style:normal;src:url(data:font/ttf;base64,AAEAAAARAQAABAAQR0RFRrFss1wAAmssAAACfkdQT1N2Wb7+AAJtrAABFy5HU1VCjJZZRgADhNwAAC8mT1MvMlYMpE4AAfmwAAAAYGNtYXBfILVpAAH6EAAACuRjdnQgMKUWggACEzwAAADkZnBnbU0kjnwAAgT0AAANbWdhc3AAAAAQAAJrJAAAAAhnbHlmzhsdpQAAARwAAct0aGVhZA5QtXgAAduUAAAANmhoZWEG0AwiAAH5jAAAACRobXR4v8HBsgAB28wAAB3AbG9jYfsbiDIAAcywAAAO4m1heHAIxQ5XAAHMkAAAACBuYW1lKqFFSQACFCAAAAHucG9zdFa6PIcAAhYQAABVE3ByZXDNS6zAAAISZAAAANUAAgAoAAACIwK8AAMABwApQCYAAAACAwACZQQBAwEBA1UEAQMDAV0AAQMBTQQEBAcEBxIREAUNFysTIREhJREhESgB+/4FAav+pQK8/URGAjD90AAAAv//AAAC3QK8AAcACgArQCgJAQQCAUoFAQQAAAEEAGYAAgJCSwMBAQFDAUwICAgKCAoREREQBgoYKyUhByMBMwEjJwMDAif+jE1nAT1jAT5pcJeXr68CvP1E/wFX/qn/////AAAC3QN3ACIABAAAAAMHEgKaAAD/////AAAC3QN3ACIABAAAAAMHGQKaAAD/////AAAC3QPhACIABAAAACcHMQKaAJYBBwcuApoBEQARsQIBsJawMyuxAwG4ARGwMysA//////88At0DdwAiAAQAAAAjBv8CmgAAAAMHGQKaAAD/////AAAC3QPhACIABAAAACcHMQKaAJYBBwctApoBEQARsQIBsJawMyuxAwG4ARGwMysA/////wAAAt0D7QAiAAQAAAAnBzECmgCWAQcHNAKaAP4AELECAbCWsDMrsQMBsP6wMyv/////AAAC3QPgACIABAAAACcHMQKaAJYBBwcyApoBEQARsQIBsJawMyuxAwG4ARGwMysA/////wAAAt0DdwAiAAQAAAADBxcCmgAA/////wAAAt0DdwAiAAQAAAADBxYCmgAA/////wAAAt0DvgAiAAQAAAAnBy8CmgCWAQcHLgNCAO4AELECAbCWsDMrsQMBsO6wMyv//////zwC3QN3ACIABAAAACMG/wKaAAAAAwcWApoAAP////8AAALdA74AIgAEAAAAJwcvApoAlgEHBy0DQgDuABCxAgGwlrAzK7EDAbDusDMr/////wAAAt0D0wAiAAQAAAAnBy8CmgCWAQcHNAMcAOQAELECAbCWsDMrsQMBsOSwMyv/////AAAC3QPmACIABAAAACcHLwKaAJYBBwcyApoBFwARsQIBsJawMyuxAwG4ARewMysA/////wAAAt0DdwAiAAQAAAADByMCmgAA/////wAAAt0DbQAiAAQAAAADBwoCmgAA//////88At0CvAAiAAQAAAADBv8CmgAA/////wAAAt0DdwAiAAQAAAADBxACmgAA/////wAAAt0DuwAiAAQAAAADByICmgAA/////wAAAt0DfQAiAAQAAAADByQCmgAA/////wAAAt0DVAAiAAQAAAADBx4CmgAA//////8gAvMCvAAiAAQAAAADBwMECAAA/////wAAAt0D1gAiAAQAAAEHBvACmgCqAAixAgKwqrAzK/////8AAALdBB0AIgAEAAABBwbxApoAqgAIsQICsKqwMyv/////AAAC3QN3ACIABAAAAAMHGgKaAAAAAv//AAAD3wK8AA8AEwBEQEEABQAGCQUGZQsBCQABBwkBZQgBBAQDXQADA0JLCgEHBwBdAgEAAEMATBAQAAAQExATEhEADwAPEREREREREQwKGyslFSE1IQcjASEVIRUhFSEVJxEjAwPf/gT+6mdnAaECMf51AV/+oWMU01dXr68CvFfXVeKoAWb+mv////8AAAPfA3cAIgAeAAAAAwcSA0AAAAADAGkAAALDArwADgAXAB8APEA5DgEEAgFKAAIABAUCBGUGAQMDAV0AAQFCSwcBBQUAXQAAAEMATBgYDw8YHxgeHRsPFw8WJyEkCAoXKwAWFRQGIyERITIWFRQGBwEVMzI2NTQmIxI2NTQjIxUzAn1GiYP+sgE6eIMzK/6NzU1TU01uVqvm5gFaWURbYgK8YFU3UBUBAOA5Nzc5/eY4PHXpAAABADD/+AKtAsQAGwAuQCsYFwsKBAIBAUoAAQEAXwAAAEhLAAICA18EAQMDSQNMAAAAGwAaJiQmBQoXKwQmJjU0NjYzMhYXByYjIgYGFRQWFjMyNxcGBiMBOalgYKppUogwQU92Tn5HR35OdVBBMIlSCF2jZmajXTc2P1NGe0xMe0ZUPzY4//8AMP/4Aq0DdwAiACEAAAADBxICxwAA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BwcDUQBzAAixAQGwc7AzK///AGn/LwLDArwAIgBSAAAAAwcEAsEAAP//AGkAAALDA3cAIgBSAAAAAwcXAsEAAP//AGkAAALDA3cAIgBSAAAAAwcWAsEAAP//AGn/PALDArwAIgBSAAAAAwb/AsEAAAABAGkAAADNArwAAwATQBAAAABCSwABAUMBTBEQAgoWKxMzESNpZGQCvP1EAAIAV//4Am0CvAAPABMAM0AwAwEABAIBAgACSgAEBAFdAwEBAUJLAAAAAl8FAQICSQJMAAATEhEQAA8ADhMlBgoWKwQmJzcWFjMyNjURMxEUBiMDMxEjAQN8MCcsaDdeYmSeiORkZAgmIVAeIG5vAY7+d5miAsT+eQD//wBQAAABUgN3ACIAWAAAAAMHEgHHAAD////5AAABPQN3ACIAWAAAAAMHGQHHAAD////oAAABTgN3ACIAWAAAAAMHFgHHAAD///+uAAABGwN3ACIAWAAAAAMHIwHHAAD//wALAAABKwNtACIAWAAAAAMHCgHHAAD//wAPAAABOQP0ACIAWAAAACcHKwHHAJYBBwcuAccBJAARsQECsJawMyuxAwG4ASSwMysA//8AYAAAANYDfQAiAFgAAAADBw4BxwAA//8AaP88AM4CvAAiAFgAAAADBv8BxwAA////5AAAAOYDdwAiAFgAAAADBxABxwAA//8APwAAAQADuwAiAFgAAAADByIBxwAA////+QAAAT0DfQAiAFgAAAADByQBxwAA//8AFgAAASADVAAiAFgAAAADBygBxwAA//8ATv8gAPECvAAiAFgAAAADByoB+AAA////8wAAAUMDdwAiAFgAAAADBxoBxwAAAAH/9//4AZ4CvAAQACxAKQMCAgABAUoAAQECXQACAkJLAAAAA18EAQMDSQNMAAAAEAAPERMkBQoXKxYmJzcWMzI2NREjNSERFAYjhGwhOjpYOz39AWBvbAg1MERTSEYBiVf+JXR1////9//4AaIDdwAiAGgAAAADBxYCGwAAAAEAaQAAAs4CvAALAB9AHAkGAQMAAQFKAgEBAUJLAwEAAEMATBISERIEChgrAQcVIxEzEQEzAQEjAU2AZGQBfHL+1QE+dQE3grUCvP55AYf+xf5///8AaQAAAs4DdwAiAGoAAAADBxcCowAA//8Aaf75As4CvAAiAGoAAAADBwECowAA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KAcKGSsBERQGBwYVFBYzMjY3FwYjIiY1NDcmJjURMxEUMzI2NRECs15XkCIcECEMEygyOEBFf41kxWBmArz+cnaSHjNJGBwJCDEYNy5DMQifjgGO/nbhb3IBigD//wBj//gCswPWACIAxwAAAQcG8AK4AKoACLEBArCqsDMr//8AY//4ArMDdwAiAMcAAAADBxoCuAAA//8AY//4ArMD9AAiAMcAAAAnBzICuACWAQcHLgK4ASQAEbEBAbCWsDMrsQIBuAEksDMrAAAB//8AAALJArwABgAhQB4FAQABAUoDAgIBAUJLAAAAQwBMAAAABgAGEREEChYrAQEjATMTEwLJ/s1j/sxs/P4CvP1EArz9wQI/AAEAIAAABEYCvAAMACdAJAsIAwMAAgFKBQQDAwICQksBAQAAQwBMAAAADAAMEhESEQYKGCsBAyMDAyMDMxMTMxMTBEbqab+/a+pnvcVcwcECvP1EAi/90QK8/ccCOf3EAjz//wAgAAAERgN3ACIA4AAAAAMHEgNgAAD//wAgAAAERgN3ACIA4AAAAAMHFgNgAAD//wAgAAAERgNtACIA4AAAAAMHCgNgAAD//wAgAAAERgN3ACIA4AAAAAMHEANgAAAAAQANAAAClAK8AAsAJkAjCgcEAQQAAQFKAgEBAUJLBAMCAABDAEwAAAALAAsSEhIFChcrIQMDIwEDMxMTMwMBAiHSz3MBB/dyxMJt9wEJASH+3wFnAVX+8wEN/q7+lgAAAf/8AAACiwK8AAgAHUAaBgMAAwABAUoCAQEBQksAAABDAEwSEhEDChcrJRUjNQEzExMzAXVj/upr4OFj8vL0Acj+jwFx/////AAAAosDdwAiAOYAAAADBxICcAAA/////AAAAosDdwAiAOYAAAADBxYCcAAA/////AAAAosDbQAiAOYAAAADBwoCcAAA/////AAAAosDfQAiAOYAAAADBw4CcAAA/////P88AosCvAAiAOYAAAADBv8CcAAA/////AAAAosDdwAiAOYAAAADBxACcAAA/////AAAAosDuwAiAOYAAAADByICcAAA/////AAAAosDVAAiAOYAAAADBx4CcAAA/////AAAAosDdwAiAOYAAAADBxoCcAAAAAEAKwAAAnQCvAAJAC9ALAgBAQIDAQADAkoAAQECXQACAkJLBAEDAwBdAAAAQwBM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AfIAxAAIsQEBsMSwMyv//wBb/y8CUgLmACIB2AAAAAMHBAKDAAD////YAAACUgO1ACIB2AAAAQcG7QG3ANQACLEBAbDUsDMr////2AAAAlIDoQAiAdgAAAEHBxYBtwAqAAixAQGwKrAzK///AFv/PAJSAuYAIgHYAAAAAwb/AoMAAP//AEoAAADMAvUAIgHfAAAAAwcpAbcAAAABAFsAAAC7AhIAAwATQBAAAABFSwABAUMBTBEQAgoWKxMzESNbYGACEv3u//8AQAAAAUIC4QAiAd8AAAADBucBtwAA//8AAgAAARQC4QAiAd8AAAADBzcBtwAA////8QAAASUC4QAiAd8AAAADBzYBtwAA////ngAAAQsC4QAiAd8AAAADBvsBtwAA//8AEgAAAQQC1gAiAd8AAAADBzUBtwAA/////wAAASkDXgAiAd8AAAAjBysBtwAAAQcHLgG3AI4ACLEDAbCOsDMr//8AUAAAAMYC5wAiAd8AAAADBuMBtwAA//8ASv88AMwC9QAiAd8AAAAjBykBtwAAAAMG/wG3AAD////UAAAA1gLhACIB3wAAAAMG5QG3AAD//wAvAAAA8AMlACIB3wAAAAMG+gG3AAD//wACAAABFALnACIB3wAAAAMHOgG3AAD//wBK/zgB6AL1ACIB3wAAACMHKQG3AAAAIwHwARcAAAADBykC0wAA//8ABgAAARACvgAiAd8AAAADBzkBtwAA//8APP8gAN8C9QAiAd8AAAAjBykBtwAAAAMHKgHmAAD////8AAABGgLhACIB3wAAAAMHOAG3AAD///+k/zgA0QL1ACIB8AAAAAMHKQG8AAAAAf+k/zgAwAISAA4AKUAmAwEAAQIBAgACSgABAUVLAAAAAmADAQICTQJMAAAADgANEyQEChYrBiYnNxYzMjY1ETMRFAYjDDwUHx4wJilgWFHIEBBKGS8uAiz91lJe////pP84ASoC4QAiAfAAAAADBzYBvAAAAAEAWwAAAmYC5gALACNAIAkGAQMAAgFKAAEBREsAAgJFSwMBAABDAEwSEhESBAoYKyUHFSMRMxEBMwcTIwEpbmBgASF03/V292aRAub+JAEI2/7J////2AAAAmYDtQAiAfIAAAEHBu0BtwDUAAixAQGw1LAzK///AFv++QJmAuYAIgHyAAAAAwcBAmUAAAABAFsAAAJm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yNQBDP70/////wAAAmgDBwAiAt8AAAEHBucCXwAmAAixAgGwJrAzK/////8AAAJoAwcAIgLfAAABBwbvAl8AJgAIsQIBsCawMyv/////AAACaANxACIC3wAAACcHMQJfACYBBwcuAl8AoQAQsQIBsCawMyuxAwGwobAzK///////PAJoAwcAIgLfAAAAIwb/Al8AAAEHBu8CXwAmAAixAwGwJrAzK/////8AAAJoA3EAIgLfAAAAJwcxAl8AJgEHBy0CXwChABCxAgGwJrAzK7EDAbChsDMr/////wAAAmgDfQAiAt8AAAAnBzECXwAmAQcHNAJfAI4AELECAbAmsDMrsQMBsI6wMyv/////AAACaANwACIC3wAAACcHMQJfACYBBwcyAl8AoQAQsQIBsCawMyuxAwGwobAzK/////8AAAJoAwcAIgLfAAABBwbtAl8AJgAIsQIBsCawMyv/////AAACaAMHACIC3wAAAQcG7AJfACYACLECAbAmsDMr/////wAAAnkDTgAiAt8AAAAnBy8CXwAmAQcHLgMHAH4AELECAbAmsDMrsQMBsH6wMyv//////zwCaAMHACIC3wAAACMG/wJfAAABBwbsAl8AJgAIsQMBsCawMyv/////AAACaANOACIC3wAAACcHLwJfACYBBwctAwcAfgAQsQIBsCawMyuxAwGwfrAzK/////8AAAJoA2MAIgLfAAAAJwcvAl8AJgEHBzQC4QB0ABCxAgGwJrAzK7EDAbB0sDMr/////wAAAmgDdgAiAt8AAAAnBy8CXwAmAQcHMgJfAKcAELECAbAmsDMrsQMBsKewMyv/////AAACaAMHACIC3wAAAQcG+wJfACYACLECArAmsDMr/////wAAAmgC/QAiAt8AAAEHBt8CXwAmAAixAgKwJrAzK///////PAJoAjgAIgLfAAAAAwb/Al8AAP////8AAAJoAwcAIgLfAAABBwblAl8AJgAIsQIBsCawMyv/////AAACaANLACIC3wAAAQcG+gJfACYACLECAbAmsDMr/////wAAAmgDDQAiAt8AAAEHBvwCXwAmAAixAgGwJrAzK/////8AAAJoAuQAIgLfAAABBwb2Al8AJgAIsQIBsCawMyv//////yACfgI4ACIC3wAAAAMHAwOTAAD/////AAACaANSACIC3wAAAQcG8AJf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VAD////w/zgCNgISAAICbwYA////8P84AjYC4QAiAm8GAAADB1gB8AAAAAMAK/8+AvoC5gARABgAHgA3QDQeAQAGAUoABAMEgwgBBwcDXwUBAwMiSwAGBgBfAgEAACFLAAEBJAFMFhEUEREUERERCQcdKyQGBxUjNSYmNTQ2NzUzFRYWFQQWFxEGBhUENTQmJxEC+qSVXpWjopZelaT9kG1sbWwCEW5sj44Iu7sIjXx7igjPzwiLelVgBwF0B15TrKxUXQf+iwD//wAJAAACFQISAAICbvsAAAEAKgAAAgQCEgARAC9ALBABAwIDAQEDAkoAAwABAAMBZwUEAgICIksAAAAhAEwAAAARABEjEyIRBgcYKwERIzUGIyImNTUzFRQWMzI3NQIEYFZVY2xgRT5GUQIS/e7WKFxcrKY3OCPyAAABAF3/gQKTAhIACwApQCYAAAMAUgQBAgIiSwYFAgMDAV4AAQEhAUwAAAALAAsREREREQcHGSslFSM1IREzESERMxECk1v+JWABImBU038CEv5CAb7+QgAAAQBdAAADUAISAAsAJUAiBgUDAwEBIksEAQICAF4AAAAhAEwAAAALAAsREREREQcHGSsBESERMxEzETMRMxEDUP0NYOpg6QIS/e4CEv5CAb7+QgG+AP//AF3/jwOfAhIAIgUmAAAAAwdaArIAAAABAF3/gQIoAhIACwBGS7AKUFhAGAABAAABbwUBAwMiSwAEBABeAgEAACEATBtAFwABAAGEBQEDAyJLAAQEAF4CAQAAIQBMWUAJEREREREQBgcaKyEjFSM1IxEzESERMwIot1u5YAELYH9/AhL+QgG+AAACAF3//gIhAhIACgATADBALQUBAgADBAIDZQABASJLBgEEBABeAAAAIQBMCwsAAAsTCxIRDwAKAAkRJAcHFisAFhUUBicnETMVFxI2NTQmJycVFwG3anNr5mCVKkNBQ35+AV1aUlZdAQECErMB/uk2NTQwAQLQAQACAAQAAAJhAhIADAAVADZAMwYBAwAEBQMEZQABAQJdAAICIksHAQUFAF0AAAAhAEwNDQAADRUNFBMRAAwACxERJAgHFysAFhUUBiMjESM1IRUzEjY1NCYjIxUzAfhpc2nfogECkCpAPz98fAFfW1JVXQG+VLP+6jY1MzHPAAADAF3//gLJAhIACgAOABcANkAz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hAMBAgIBXQABASEBTAAAAAUABRERBAcWKzcVIzUjNfpccVfwmVcAAQA6/2cA2wBXAAUAH0AcAAABAIQDAQICAV0AAQEhAUwAAAAFAAUREQQHFis3FSM1IzXbXURX8JlXAAEAQP+PANoAUgAFADxLsApQWEASAAABAQBvAwECAgFdAAEBIQFMG0ARAAABAIQDAQICAV0AAQEhAUxZQAsAAAAFAAUREQQHFis3FSM1IzXaV0NSw3FSAP///jICWf92A0sAIgcxAAABBgcuAHsACLEBAbB7sDMr///+MgJZ/3YDSwAiBzEAAAEGBy0AewAIsQEBsHuwMyv///4yAln/dgNXACIHMQAAAQYHNABoAAixAQGwaLAzK////i8CWf95A0oAIgcxAAABBgcyAHsACLEBAbB7sDMr///+IQJfABoDKAAiBy8AAAEHBy4AqABYAAixAQGwWLAzK////iECX//BAygAIgcvAAABBwctAKgAWAAIsQEBsFiwMyv///4hAl//pAM9ACIHLwAAAQcHNACCAE4ACLEBAbBOsDMr///+IQJf/4cDUAAiBy8AAAEHBzIAAACBAAixAQGwgbAzK////jIC7/92A+EAJwcxAAAAlgEHBy4AAAERABGxAAGwlrAzK7EBAbgBEbAzKwD///4yAu//dgPhACcHMQAAAJYBBwctAAABEQARsQABsJawMyuxAQG4ARGwMysA///+MgLv/3YD7QAnBzEAAACWAQcHNAAAAP4AELEAAbCWsDMrsQEBsP6wMyv///4vAu//eQPgACcHMQAAAJYBBwcyAAABEQARsQABsJawMyuxAQG4ARGwMysA///+IQL1ABoDvgAnBy8AAACWAQcHLgCoAO4AELEAAbCWsDMrsQEBsO6wMyv///4hAvX/wQO+ACcHLwAAAJYBBwctAKgA7gAQsQABsJawMyuxAQGw7rAzK////iEC9f+kA9MAJwcvAAAAlgEHBzQAggDkABCxAAGwlrAzK7EBAbDksDMr///+IQL1/4cD5gAnBy8AAACWAQcHMgAAARcAEbEAAbCWsDMrsQEBuAEXsDMrAAABAF//ZwC8ABcAAwAYQBUAAQAAAVUAAQEAXQAAAQBNERACBxYrFyM1M7xdXZmwAAABAF7/jwC5ABUAAwAYQBUAAQAAAVUAAQEAXQAAAQBNERACBxYrFyM1M7lb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UXdRg1GUUaVRtlHHUdhR6VICUhtSgFKLUp9SsFLJUuJS+1NDU3xTuVQOVFFUYlRzVH9UkFScVK1UuVUPVSBVOVVBVVJVa1V3VYhVlFWlVbFVxlZEVmNWdFaFVpFWnVauVrpWxlb0VwVXFlcnVzhXSVdaV2ZXd1eIV5lXslfHV+BX+VgSWCNYNFhFWF5YrFi9WM5Y51kLWTxZTVleWW9ZgFmtWdBZ4VnyWgNaFFogWjFaQlpTWmRaklqjWrRaxVrRWw1bHlsvW0hbXVt2W49bqFu5W8pb41v4XBFcKlxDXFRcZVxxXIJck1ykXLVcwVzSXONc9F1ZXWpdf13WXedd+F4JXh5eL15IXl1edl6PXqheuV7KXtte5174XwlfGl8rX0RfXV/pX/pgSGCBYOJg82EEYRVhJmE3YUhhXGGGYY5hn2HtYf5iD2IgYjFiSmJWYmdieGKJYsVi1mLiYvNjKGM5Y0VjpmOyY/dkCGQZZCVkNmRCZKJkrmS6ZMtlFmVAZVFlYmVuZXpli2WXZaNl7WX+Zg9mIGYxZkJmU2ZfZnBmgWaSZqtmwGbZZvJnC2ccZy1nPmdXZ2NndGeFZ55n5mf3aAhoGWgqaHVohmiXaKhouWjKaNto7Gj9aQ5pSWlaaWtpfGmIad9qH2onamJqr2rNatlq+ms7a0NrT2tba5tr+WwfbCtsN2yNbLtsx20hbVVtXW1lbYltkW2Zbblt8m3+blBugG62buJvDm8ab0Fvem+4b8Rv0HAxcDlwSXCYcK5wunDCcQBxc3G1ciRybXK4csxzGXNJc5hzpHOwc7xz+nQ3dGt0d3SDdNZ04nWZdaV1sXW5dc112XYNdhl2XXaTdp93B3cTdxt3J3dud6x34XggeF54anh2eH54injheO14+XkFeVF5XXlpeXV5iXmhea15uXnFedF53Xnoefh6RnqQesh7I3txe3l7qnvzfEF8f3yLfMJ85n05fWN9b317fYd9j33Ufdx96H30ffx+CH6nfrN+6380fzx/RH9Qf5p/5IA1gKOBM4GugbaCDoIagiaCMoI6gkaCUoJegmqCdoKCgo6CloLvgveDXYOng8SD1oQHhEeET4RbhGeEo4T+hSSFMIU8hZKFvYXJhhiGS4ZxhnmGnYalhq2GzYbVhuGHMIc4h22HmYfEh9CICYhFiISIyYjViTKJOolKiZaJoomuibqKAYqKisiLJouKi9uL44wxjF+MrYy5jRaNIo1djZ6Nz43bjeeN845FjtOO347rjw6PIo8uj2KPbo+vj7eP95BZkGWQbZB5kL6ROJF6ka2R6pImkjKSPpJGklKSpJKwkrySyJMRkx2TKZM1k4eTk5Ofk6uTt5PDk8+T2pPmlDWUepSylQqVXJVklZWV35ZXlpmWpZcDl1qXYpell/6YBpgSmB6YT5hymHqYgpiKmL+Yy5ktmTmZgZnPmkaabpp6moaamJrymv6bBpsSmyabLps2mz6bSptWm16bapvom/ScRJxMnFScYJyonPadXp3GnkCemJ6knrCeuJ7EnxOfH58rnzefQ59Pn1ufZ5+/n+agMqB0oLCgwaDJoQqhKaFpobKh5aItoo+izaM4o5mj36P9pD2kiKS+pQelD6VSpVqlaKV3pYallaWkpbOlwqXRpeCl76X+pkCmaKaopvCnI6drp82oC6h2qNipHqlFqYWpzqoDqkyqVKqXqp+rA6sRqx+rLas7q0mrV6tlq3OrgauPq8mr76wtrHOso6zlrTytd63Xri+uPq5krqKu6K73rzqvSa+Fr5Svo6+yr8Gv0K/fr+6v/bAMsBuwKrA5sFGwYbBxsIGwkbChsLGwwbDRsOGxFrExsVaxe7GNsbqxyrH5siiylLK2swuzZLNws4ezmbOws8yz57QMtBm0PrRVtHq0vrUFtSW1SLVrtZG1nrWrtbi1xbXStd+1+LYRtiq2MrZLtlO2W7ZotnW2graOtpq2ubbbtue287b/tya3Ubd+t5O3qLe1t8K38bgiuC64OrhZuHu4nbjxuUi5VLlguWy5eLmfucq597oNuiq6Oro6ujq6Oro6ujq6OrqWuuG7c7vfvFG8371Jvbq98r5UvsO+/79Xv6C/28BIwFjA5cErwXzBwsHswizCuML4wwDDRcNNw3XDjsOrw/XEJ8SBxJfErsTYxQTFOsW+xjLGUMayxybHacdxx3nHnMfVyATIDMhvyR7J/sodyjXKW8p0ypPKq8rUyuzLHss8y1vLfsuly8vL3sv6zBTMKsxUzGbMdsyOzJ7MxMzczQLNGs3KzjjOY87iz2TP6tAx0HnQj9Cx0QbRK9Fi0cvSU9J60pHSsdK+03fT5dQk1DXURtRX1IHUktSs1L3U1tTn1PjVHtU11VrVf9WP1cHWA9ZI1rzWzdbe1u/XDdce1y/XQNd115vXydf22CLYS9iJ2LnY+dkx2WHZftmc2brZzNnm2iHaONpP2mbajNqj2rna0Nrl2vzbE9s121bbd9uO27zcLNxD3FrccdyL3KLcudzQ3QHdI91N3Wfded2P3andzN4L3lPehN6k3sTe5t8I3zLfld+53+rgMuBU4Hzg8uEJ4S/hU+Ft4Yrhl+Gj4cDh2eH24ibiVOJu4oripuKv4rjiweLK4tPi3OLl4u7i9+MA4wnjEuMb4zTjTeNk45LjwOPs5AnkJuRS5GLkcuSC5JLko+S05MXk1uTt5QTlGuUx5UflXeVz5YrlouW6AAAAAQAAAAczM3QVnhxfDzz1AAcD6AAAAADWC/5GAAAAANYeQAX8uP75Bk0EHQAAAAcAAgAAAAAAAAJLACgAAAAAAQ0AAAENAAAC3P//Atz//wLc//8C3P//Atz//wLc//8C3P//Atz//wLc//8C3P//Atz//wLc//8C3P//Atz//wLc//8C3P//Atz//wLc//8C3P//Atz//wLc//8C3P//Atz//wLc//8C3P//Atz//wQX//8EF///AvUAaQLTADAC0wAwAtMAMALTADAC0wAwAtMAMALTADADOgBpBa4AaQNCAAsDOgBpA0IACwM6AGkDOgBpBUMAaQKeAGkCngBpAp4AaQKeAGkCngBpAp4AaQKeAGkCngBpAp4AaQKeAGkCngBpAp4AaQKeAGkCngBpAp4AaQKeAGkCngBpAp4AaQKeAGkCngBpAp4AaQKeAGkCngBpAm8AHwJvAB8CewBpAwQAMAMEADADBAAwAwQAMAMEADADBAAwAwQAMAMnADADLABpAzwACQMsAGkDLABpAywAaQMsAGkBNgBpAtAAVwE2AFABNv/5ATb/6AE2/64BNgALATYADwE2AGABNgBoATb/5AE2AD8BNv/5ATYAFgE2AE4BNv/zAgH/9wIB//cCzwBpAs8AaQLPAGkCUgBpBFMAaQJSAFACUgBpAlIAaQJSAGkCUgBpA24AaQJSAGkCWgAJA7sAaQO7AGkDLABpBS0AaQMsAGkDLABpAywAaQMsAGkDLABpAywAaQRIAGkDLABpAywAaQNIADADSAAwA0gAMANIADADSAAwA0gAMANIADADSAAwA0gAMANIADADSAAwA0gAMANIADADSAAwA0gAMANIADADSAAwA0gAMANIADADSAAwA0gAMANIADADSAAwA0gAMANIADADSAAwA0gAMANIADADSAAwA0gAMANIADADSAAwA0gAMANIADAEZgAwAtIAaQLSAGkDSAAwAtcAaQLXAGkC1wBpAtcAaQLXAGkC1wBpAtcAaQLXAGkCbQApAm0AKQJtACkBAgBQAm0AKQJtACkCbQApAm0AKQJtACkCbQApAm0AKQJtACkC+wBjAzEAMAJLAAQCSwAEAksABAJLAAQCSwAEAksABAJLAAQDFwBjAxcAYwMXAGMDFwBjAxcAYwMXAGMDFwBjAxcAYwMXAGMDFwBjAx8AYwMfAGMDHwBjAx8AYwMfAGMDHwBjAxcAYwMXAGMDFwBjAxcAYwMXAGMDFwBjAxcAYwMXAGMCyP//BGYAIARmACAEZgAgBGYAIARmACACoQANAof//AKH//wCh//8Aof//AKH//wCh//8Aof//AKH//wCh//8Aof//AKRACsCkQArApEAKwKRACsCkQArAtAAVwMgAGMDIABjAyAAYwMgAGMDIABjAyAAYwMgAGMDIABjAyAAYwMgAGMDIABjAyAAYwMgAGMDIABjAyAAYwMgAGMDIABjAyAAYwMgAGMDIABjAyAAYwMgAGMDIABjAyAAYwMgAGMDIABjBDIAWgQyAFoFrgBpBU0AaQKEADMChAAzAoQAMwKEADMChAAzAoQAMwKEADMChAAzAoQAMwKEADMChAAzAoQAMwKEADMChAAzAoQAMwKEADMChAAzAoQAMwKEADMChAAzAoQAMwKEADMChAAzAl4AYwMEADADBAAwAwQAMAMEADADBAAwAwQAMAMEADADLAAwAcgAKwLQAFcByAArAtAAVwHIACsByAArAcj/+AHIACsByAArAcgAKwHIACsByAArAcgAKwHIACsByAArAcgAKwHIACsB///3Af//9wRvAGkEywBpBMsAaQMeAGkFHQBpAx4AaQMeAGkDHgBpAx4AaQMeAGkDHgBpBDoAaQMeAGkDHgBpA0gAMAMxAEUCVv/8Alb//AJW//wCVv/8Alb//AJW//wCVv/8AxoAYwMaAGMDGgBjAxoAYwMaAGMDGgBjAxoAYwMaAGMDGgBjAxoAYwMaAGMDGgBjAxoAYwMaAGMDGgBjAxoAYwMaAGMDGgBjAxoAYwMaAGMDGgBjAxoAYwMaAGMDGgBjBKYAYwSmAGMEpgBjBKYAYwSmAGMDEwBeAxMAXgMTAF4DEwBeAxMAXgMTAF4DEwBeAxMAXgMTAF4DEwBeApsAMAKbADACmwAwApsAMAKbADACVgAyAlYAMgJWADICVgAyAlYAMgJWADICVgAyAlYAMgJWADICVgAyAlYAMgJWADICVgAyAlYAMgJWADICVgAyAlYAMgJWADICVgAyAlYAMgJWADICVgAyAlYAMgJWADICVgAyAlYAMgPdADID3QAyAqoAWwI7ACoCOwAqAjsAKgI7ACoCOwAqAjsAKgI7ACoCqgAqAoAAKgKqACoCqgAqAqoAKgKqACoEuwAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAg//7AIP/+wBYQAPArIAKgKyACoCsgAqArIAKgKyACoCsgAqArIAKgK6ACoCqQBbAqkAAAKpAFsCqf/YAqn/2AKpAFsBFwBKARcAWwEXAEABFwACARf/8QEX/54BFwASARf//wEXAFABFwBKARf/1AEXAC8BFwACAjMASgEXAAYBFwA8ARf//AEc/6QBHP+kARz/pAJoAFsCaP/YAmgAWwJeAFsBFwBbARcAQAEXAFsBFwBYAVoAWwEXAFgCMwBbARf/6AEn//kEIQBbBCEAWwKpAFsCqQBbAwIANQKpAFsCqQBbAqkAWwKpAFsCqQBbA8UAWwKpAFsCqQBbAnsAKgJ7ACoCewAqAnsAKgJ7ACoCewAqAnsAKgJ7ACoCewAqAnsAKgJ7ACoCewAqAnsAKgJ7ACoCewAqAnsAKgJ7ACoCewAqAnsAKgJ7ACoCewAqAn8AKgJ7ACoCewAqAnsAKgJ7ACoCewAqAnsAKgJ7ACoCewAqAnsAKgJ7ACoCewAqAnsAKgQrACoCqgBbAqoAWwKqACoBmgBbAZoAWwGaADcBmgBYAZr//QGaAFgBmgBIAZr/6AH1ABgB9QAYAfUAGAD/AFAB9QAYAfUAGAH1ABgB9QAYAfUAGAH1ABgB9QAYAfUAGAKkAFsBMgAZAZ4ADwGoABQBngAPAZ4ADwGeAA8BngAJAZ4ADwGeAA8CpQBWAqUAVgKlAFYCpQBWAqUAVgKlAFYCpQBWAqUAVgKlAFYCpQBWAq0AVgKtAFYCrQBWAq0AVgKtAFYCrQBWAqUAVgKlAFYCpQBWAqUAVgKlAFYCpQBWAqUAVgKlAFYCL//+A4MABgODAAYDgwAGA4MABgODAAYCKAAOAi//6gIv/+oCL//qAi//6gIv/+oCL//qAi//6gIv/+oCL//qAi//6gIJACgCCQAoAgkAKAIJACgCCQAoAjIASAKqACoCqgAqAqoAKgKqACoCqgAqAqoAKgKqACoCqgAqAqoAKgKqACoCqgAqAqoAKgKqACoCqgAqAqoAKgKqACoCqgAqAqoAKgKqACoCqgAqAqoAKgKqACoCqgAqAqoAKgKqACoCqgAqA90AMgPdADIEvQAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAArAVMAWwFBAFsBQQBAAUEAWwFBAFsBbQBbAUEAWwI1AFsBQQApAUH/8QQ6ACoBiwBWAZUADAGLAFYBiwBWAYsAVgGL//YBiwBWAYsASAPZAFYD2QBWA9kAVgPZAFYD2QBWAqUAVAKlAFQCpQBUAqUAVAKlAFQCpQBUAqUAVAKlAFQCpQBUAhMALQITAC0CEwAtAhMALQITAC0EsQAEAsgADwJ4AA8CugBbAosADwJn//8CZ///Amf//wJn//8CZ///Amf//wJn//8CZ///Amf//wJn//8CZ///Amf//wJn//8CZ///Amf//wJn//8CZ///Amf//wJn//8CZ///Amf//wJn//8CZ///Amf//wJn//8CZ///A2z//wNs//8ChABhAmEALAJhACwCYQAsAmEALAJhACwCYQAsAmEALAK+AGEC0gAgAr4AYQLSACACvgBhAr4AYQTOAGECOgBhAjoAYQI6AGECOgBhAjoAYQI6AGECOgBhAjoAYQI6AGECOgBhAjoAYQI6AEMCOgBhAjoAYQI6AGECOgBhAjoAYQI6AGECOgBhAjoAYQI6AGECOgBhAjoAYQKcACwCMAAlAjAAJQIgAGECjgAsAo4ALAKOACwCjgAsAo4ALAKOACwCjgAsAq8ALAK7AGEC4wAiArsAYQK7AGECuwBhArsAYQEiAGEBIgBhASIARgJQAEEBIgAIASL/9wEi/6QBIgAYASIABQEiAFYBIgBeASL/2gEiADUBIgAIAm8ATAEiAAwBIgBDASIAAgHB//wBwf/8AmwAYQJsAGECbABhAmwAYQH7AGEB+wBHAfsAYQH7AGEB+wBhAfsAYQO8AGEB+wBhAfv/+AMyAGEDMgBhArsAYQK7AGECuwBhArsAYQK7AGECuwBhArsAYQR8AGECuwBhArsAYQLCACwCwgAsAsIALALCACwCwgAsAsIALALCACwCwgAsAsIALALCACwCwgAsAsIALALCACwCwgAsAsIALALCACwCwgAsAsIALALCACwCwgAsAsIALALCACwCwgAsAsIALALCACwCwgAsAsIALALCACwCwgAsAsIALALCACwCwgAsAsIALALCACwDqwAsAm8AYQJvAGECwgAsAnYAYQJ2AGECdgBhAnYAYQJ2AFQCdgBhAnYAYQJ2AGECEwAlAhMAJQITACUA/wBQAhMAJQITACUCEwAlAhMAJQITACUCEwAlAhMAJQITACUCigBbAe0ABAHtAAQB7QAEAe0ABAHtAAQB7QAEAe0ABAHtAAQCqABbAqgAWwKoAFsCqABbAqgAWwKoAFsCqABbAqgAWwKoAFsCqABbArAAWwKwAFsCsABbArAAWwKwAFsCsABbAqgAWwKoAFsCqABbAqgAWwKoAFsCqABbAqgAWwKoAFsCaQAIA70AIgO9ACIDvQAiA70AIgO9ACICPAAMAjkAAgI5AAICOQACAjkAAgI5AAICOQACAjkAAgI5AAICOQACAjkAAgIrACkCKwApAisAKQIrACkCKwApAq8AWwKvAFsCrwBbAq8AWwKvAFsCrwBbAq8AWwKvAFsCrwBbAq8AWwKvAFsCrwBbAq8AWwKvAFsCrwBbAq8AWwKvAFsCrwBbAq8AWwKvAFsCrwBbAq8AWwKvAFsCrwBbAq8AWwKvAFsDmQBVA5kAVQToAGECJwAqAicAKgInACoCJwAqAicAKgInACoCJwAqAicAKgInACoCJwAqAicAKgInACoCJwAqAicAKgInACoCJwAqAicAKgInACoCJwAqAicAKgInACoCJwAqAicAKgKcADkCCABbAo4ALAKOACwCjgAsAo4ALAKOACwCjgAsAo4ALAK0ACwBqgA5AaoAOQGqADkCbwBBAaoAOQGqADkBqv/pAaoAOQGqADkBqgA5AaoAHwGqADkBqgA5Am8ATAGqADkBqgA5AaoAOQHB//wBwf/8A7wAYQQAAGEEAABhAq4AYQKuAGECrgBhAq4AYQKuAGECrgBhAq4AYQRvAGECrgBhAq4AYQLCACwB9//8Aff//AH3//wB9//8Aff//AH3//wB9//8Aff//AKuAFsCrgBbAq4AWwKuAFsCrgBbAq4AWwKuAFsCrgBbAq4AWwKuAFsCtgBbArYAWwK2AFsCtgBbArYAWwK2AFsCrgBbAq4AWwKuAFsCrgBbAq4AWwKuAFsCrgBbAq4AWwP/AFsD/wBbA/8AWwP/AFsD/wBbAqMAVgKjAFYCowBWAqMAVgKjAFYCowBWAqMAVgKjAFYCowBWAqMAVgIrACkCKwApAisAKQIrACkCKwApAZQAJQGiACAC9gAMAtsAbQLrAG0CQgBtAkIAbQJFAG0DJAANApkAbQKZAG0CmQBtBAUAEwKCACADNwBtAzcAbQM3AG0DUwBtAscAbQLHAG0DFgANA8MAbQM0AG0DUAAzAzUAbQLKAG0CzgA0AlsADQKzABACswAQA54ALQKcABEC4AA2Az0AbQRHAG0EYABtAycAbQLJAG0DPAANA+EAbQSjAA0EnABtAnwAMQLEADUCwwAdAT0AbQE2AAsCHAASA0oADQRLAG0C2wA6A0EADgMrABMDhAASA1AAMwL5AA4CagAeAr8AbQQsABMCggAgAvMAbQLkAG0C3QAjAzsADQNPAG0EPwBtBKwAbQNQAG0DzgA5As4ANAJbAA0CmwAGAof//ALBABEDzgAOAvsANgLgADUC4ABtAyUAbQPdACAD3QAgAT4AbQQFABMCygBtAy8AbQNQAG0C3AAzA+gAbQL2AAwC9gAMBBYABwKZAG0DNwApAzcAKQQFABMCggAgAm8AHwM3AG0DNwBtA1AAMwNQADMDUAAzAsMAHQKzABACswAQArMAEALgADYCQgBtA+EAbQJrAB0CoAAOAqwAGgKCADkDFwAMA1YAMwQ9ABUC4wAfAt0AbQMw/7QDMQANAxkADgLlAA0DnQAxAk8AbQKCACACzgA0As4ANAMgAGMDRAAeAoQAMwKEADMChAAzAxoAYwMaAGMDGgBjAxoAYwMWACACzQBcAncADQMTAF4DEwBeA58AMgLMAF8DaAAOA+EAXwSfAAwEjABtAf//9wM7ABMCdwANAyAAYwMgAGMEMgBaAoQAMwMaAGMDGgBjAxMAXgMTAF4DEwBeA+EAXwNIADAC7wAaAk0AMAKWAD4CZgBdAegAXQHoAF0B0gBdApgACAJ0ACwCdAAsAnQALANRAA0CIAAcArYAXQK2AF0CtgBdAswAXQJWAF0CVgBdAoEABQMeAF0CqQBdAoEALAKlAF0CsABdAjsALAHtAAQCO//wAjv/8AMlACsCHQAJAmEAKgKyAF0DrQBdA60AXQKGAF0CPwBdAn8ABAMnAF0DpgAFA7gAXQIYACsCQQAsAj8AGAEbAEwBFwASARz/ogKi/9wDbABdAmQAMAKj//YCZQAAAsAADwKKACwCVAAFAgQAKwJZAF0DcgANAiAAHAJWAF0CZgBbAlUAAAKeAAQCvgBdA3YAXQKlAF0D0ABdAyYALwI7ACwB7QAEAj4ABgI+AAYCHQAJAwMABQJ6ACoCYQApAqIAXQK8AF0DAwAVAwMAFQEbAF0DUQANAlYAXQKXAAUCrwBdAr8AXQJeACcDPQBdAk0AMAJNADAD4wAwAnQALAJzADgCcwA4A1EADQIgABwCD//sArYAXQK2AF0CgQAsAooALAKKACwCPwAYAjv/8AI7//ACO//wAmEAKgHoAF0DJwBdAewADQIdAAsCOQAWAiAANQKBAAUCsAAuA6oACQJeABYCuwBeAqn/pQKWAAUCfgBMAiEALgKzACkDUQANAe7/9wKeAE0CngBNAp4ATQJVAF4CPAAFAqkAXQKiAF0EGwBdAmMALAK3AE0EGwBOBDQATgJAAFACnAAFA1cAXgH0AF0CIAAcAjsALAHoAF0CbgAnARcABgKzACcCpQBWBBsATgKqACoCswApAmQAKgJkACoCZAAqAp4ATQKeAE0CngBNAp4ATQKWAEYEGwBdAqUAVAKlAFQCSQBQAqUABQMoAFADrQAIA7IAXQJ6//wCqgAqAqoAKgPdADICZAAqAmQAKwJkACsCngBNAp4ATQKlAFQCpQBUAqUAVAMoAFACawARAtz//wOCAAkCqgBbAtT/+ALc//8CzwBpApsAMAFyAAgCPgAOAjwABQKdACYCPgARAmkAMAJWAB4ChAAsAmkAHAKsADIBcgAIAj4ABgI8AAYCnQAmAj4AEQJpADACVgAeAoQALAJpABwBrgAcAa4AUQGuABwBrgAbAa4AFgGuABsBrgAlAa4AJAGuABwBrgAgArwAPQK8AJACvAA8ArwAPgK8ADUCvABBArwASgK8AEkCvAA7ArwAQQK8ADwCvACQArwARwK8AD4CvAA1ArwAQQK8AEoCvABJArwAOwK8AEEBrgAcAa4AUQGuABwBrgAbAa4AFgGuABsBrgAlAa4AJAGuABwBrgAgAa4AHAGuAFEBrgAcAa4AGwGuABYBrgAbAa4AJQGuACQBrgAcAa4AIAGuABwBrgBRAa4AHAGuABsBrgAWAa4AGwGuACUBrgAkAa4AHAGuACABrgAcAa4AUQGuABwBrgAbAa4AFgGuABsBrgAlAa4AJAGuABwBrgAgAK7/QgQKAFEECgBRBAoAHAQKAFEECgAbBAoAUQQKABsECgAbBAoAJAGQABMBYP/aAQsAQgE6AEIA4wAuAOMAMAKzAC4BDABFAQwARQK/ABsA4wAuAj0ACQI9AEUBhwA/ANIAPwDjAC4BYP/kAfQAAAFg/9oBHwBMAU4ATAFYAH4BYP/kAIEALQFfADkBXwATAU0AaQFNABMBUQBfAVIAIAFzAEMBcwAdAWEAcwFhAB0BZQBpAWYAKgPoAAAB9AAAArwALwPoAAABfwA5AX8AOQF/ADkD6AAAAfQAAAGTAEMB+AAuAfgAIgE4AC4BOAAiAaAAMAGgAC4BoAAwAOMALgDjADAA4wAwAgwAOAIMACwBTAA4AUwALAEMAEUBDABFAdwALgHdACIBIgAuASMAIgDnADMCCgAIAgkARQGHAD8BnwAwAZ8ALgGfADAA4gAuAOIAMADjADAA0gA/AUkAJAFJACsCvAAAAGQAAADjAAABDQAAAIYAAAAAAAAC0wAwAjsAKgLTADACvAAfAm0AKQKqACoDJwAeAcH/pAKXAB4DBAAwAzgAVwKUAB4ChgAeAsgAHgOUAGkDcAAeBmoAaQNLAB4C7gAeAtAAHQKGAB4C0QBMAqoAMwSqAB4Cw//8AR8ATAIaAEwBYP/kAkYAQwJGAEMCRgBrAkYAQwJGAEMCRgBDAkYAQwJGAEMCRgBDAkYAQwJGAEMCRgA6AkYAOgJGAEMCRgAlA5sAKgGP/90DggAJAtz//wMsAGkCkQArAyMAQwKqAFsCvABIA0sAJQS6ACUCWABgAlgAeAJYAEMCWAB5AlgAagJYAG4CWABgAlgAbwLZADICWABfAlgAYAJYAEMCWABq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Bz4HPQdEB0MHTAdKB0cHQAdFB0EHRgdJB04HUwdSB1QHUAblBucG7AbyBvYG7wbjBt8G+gbwBuoG7QRuBG8ElwRqBI8EjgSRBJIEkwSMBI0ElAR3BHQEgQSIBGYEZwRoBGkEbARtBHAEcQRyBHMEdgSCBIMEhQSEBIYEhwSKBIsEiQSQBJUElgUGBQcFCAUJBQwFDQUQBREFEgUTBRYFIgUjBSUFJAUmBScFKgUrBSkFMAU1BTYFDgUPBTcFCgUvBS4FMQUyBTMFLAUtBTQFFwUUBSEFKASYBTgEmQU5BJoFOgSbBTsEdQUVBNgFeQTZBXoEawULBJwFPASdBT0EngU+BJ8FPwSgBUAEoQVBBKIFQgSjBUMEpAVEBKUFRQSmBUcEqAVIBKkFSQSqBUoEqwVLBKwFTAStBU0ErgVOBK8FTwSwBVAEsQVRBLMFUwS0BVQEtQS2BVYEtwVXBVgEuAVZBLkFWgS6BVsEuwVcBVUEvAVdBL0FXgS+BV8EvwVgBMAFYQTBBWIEwgVjBMMFZATEBWUExQVmBMYFZwTHBWgEyAVpBMkFagTKBWsEywVsBMwFbQTNBW4EzgVvBM8FcATQBXEE0QVyBNIFcwTTBXQE1AV1BNUFdgTWBXcE1wV4BKcFRgSyBVIE2gV7BNsFfAAlAasALQGyAC4BswBEAckAQwHIADQBuQBQAdYAVwHdAFQB2gBfAeUAcwH7AHUB/QB4AgAAfgIGAH8CBwCCAgoAowIrAKQCLACeAiYAnQIlAK8CNwCxAjkAuwJDALwCRAC0AjwAtwI/AL0CRQDFAk4AxgJPAN4CZwDaAmMA5AJtAOECagDjAmwA6gJzAPQCfQAVAZsAFwGdAA4BlAAQAZYAEQGXABIBmAAPAZUABwGNAAkBjwAKAZAACwGRAAgBjgA+AcMAQAHFAEYBywA2AbsAOAG9ADkBvgA6Ab8ANwG8AGMB6QBhAecAkQIZAJMCGwCIAhAAigISAIsCEwCMAhQAiQIRAJUCHQCXAh8AmAIgAJkCIQCWAh4AzgJXANACWQDSAlsA1AJdANUCXgDWAl8A0wJcAOwCdQDrAnQA7QJ2AO8CeAZzBnUGdwZ0BngGSgZJBkgGSwZXBlgGVgbVBtYGJwaBBoUGfgZ/BoQGjwaKBoIGgwZ5Bo4GjAaGBocGiwW/Bb4GtQavBrEGswa3BrgGtgawBrIGtAajBqcGqQaWBpIGqgaeBp0GwgbGBsMGxwbEBsgGxQbJALUCPbAALCCwAFVYRVkgIEu4AA5RS7AGU1pYsDQbsChZYGYgilVYsAIlYbkIAAgAY2MjYhshIbAAWbAAQyNEsgABAENgQi2wASywIGBmLbACLCBkILDAULAEJlqyKAELQ0VjRbAGRVghsAMlWVJbWCEjIRuKWCCwUFBYIbBAWRsgsDhQWCGwOFlZILEBC0NFY0VhZLAoUFghsQELQ0VjRSCwMFBYIbAwWRsgsMBQWCBmIIqKYSCwClBYYBsgsCBQWCGwCmAbILA2UFghsDZgG2BZWVkbsAIlsApDY7AAUliwAEuwClBYIbAKQxtLsB5QWCGwHkthuBAAY7AKQ2O4BQBiWVlkYVmwAStZWSOwAFBYZVlZLbADLCBFILAEJWFkILAFQ1BYsAUjQrAGI0IbISFZsAFgLbAELCMhIyEgZLEFYkIgsAYjQrAGRVgbsQELQ0VjsQELQ7AHYEVjsAMqISCwBkMgiiCKsAErsTAFJbAEJlFYYFAbYVJZWCNZIVkgsEBTWLABKxshsEBZI7AAUFhlWS2wBSywB0MrsgACAENgQi2wBiywByNCIyCwACNCYbACYmawAWOwAWCwBSotsAcsICBFILAMQ2O4BABiILAAUFiwQGBZZrABY2BEsAFgLbAILLIHDABDRUIqIbIAAQBDYEItsAkssABDI0SyAAEAQ2BCLbAKLCAgRSCwASsjsABDsAQlYCBFiiNhIGQgsCBQWCGwABuwMFBYsCAbsEBZWSOwAFBYZVmwAyUjYUREsAFgLbALLCAgRSCwASsjsABDsAQlYCBFiiNhIGSwJFBYsAAbsEBZI7AAUFhlWbADJSNhRESwAWAtsAwsILAAI0KyCwoDRVghGyMhWSohLbANLLECAkWwZGFELbAOLLABYCAgsA1DSrAAUFggsA0jQlmwDkNKsABSWCCwDiNCWS2wDywgsBBiZrABYyC4BABjiiNhsA9DYCCKYCCwDyNCIy2wECxLVFixBGREWSSwDWUjeC2wESxLUVhLU1ixBGREWRshWSSwE2UjeC2wEiyxABBDVVixEBBDsAFhQrAPK1mwAEOwAiVCsQ0CJUKxDgIlQrABFiMgsAMlUFixAQBDYLAEJUKKiiCKI2GwDiohI7ABYSCKI2GwDiohG7EBAENgsAIlQrACJWGwDiohWbANQ0ewDkNHYLACYiCwAFBYsEBgWWawAWMgsAxDY7gEAGIgsABQWLBAYFlmsAFjYLEAABMjRLABQ7AAPrIBAQFDYEItsBMsALEAAkVUWLAQI0IgRbAMI0KwCyOwB2BCIGCwAWG1EhIBAA8AQkKKYLESBiuwiSsbIlktsBQssQATKy2wFSyxARMrLbAWLLECEystsBcssQMTKy2wGCyxBBMrLbAZLLEFEystsBossQYTKy2wGyyxBxMrLbAcLLEIEystsB0ssQkTKy2wKSwjILAQYmawAWOwBmBLVFgjIC6wAV0bISFZLbAqLCMgsBBiZrABY7AWYEtUWCMgLrABcRshIVktsCssIyCwEGJmsAFjsCZgS1RYIyAusAFyGyEhWS2wHiwAsA0rsQACRVRYsBAjQiBFsAwjQrALI7AHYEIgYLABYbUSEgEADwBCQopgsRIGK7CJKxsiWS2wHyyxAB4rLbAgLLEBHistsCEssQIeKy2wIiyxAx4rLbAjLLEEHistsCQssQUeKy2wJSyxBh4rLbAmLLEHHistsCcssQgeKy2wKCyxCR4rLbAsLCA8sAFgLbAtLCBgsBJgIEMjsAFgQ7ACJWGwAWCwLCohLbAuLLAtK7AtKi2wLywgIEcgILAMQ2O4BABiILAAUFiwQGBZZrABY2AjYTgjIIpVWCBHICCwDENjuAQAYiCwAFBYsEBgWWawAWNgI2E4GyFZLbAwLACxAAJFVFixDA1FQrABFrAvKrEFARVFWDBZGyJZLbAxLACwDSuxAAJFVFixDA1FQrABFrAvKrEFARVFWDBZGyJZLbAyLCA1sAFgLbAzLACxDA1FQrABRWO4BABiILAAUFiwQGBZZrABY7ABK7AMQ2O4BABiILAAUFiwQGBZZrABY7ABK7AAFrQAAAAAAEQ+IzixMgEVKiEtsDQsIDwgRyCwDENjuAQAYiCwAFBYsEBgWWawAWNgsABDYTgtsDUsLhc8LbA2LCA8IEcgsAxDY7gEAGIgsABQWLBAYFlmsAFjYLAAQ2GwAUNjOC2wNyyxAgAWJSAuIEewACNCsAIlSYqKRyNHI2EgWGIbIVmwASNCsjYBARUUKi2wOCywABawESNCsAQlsAQlRyNHI2GxCgBCsAlDK2WKLiMgIDyKOC2wOSywABawESNCsAQlsAQlIC5HI0cjYSCwBCNCsQoAQrAJQysgsGBQWCCwQFFYswIgAyAbswImAxpZQkIjILAIQyCKI0cjRyNhI0ZgsARDsAJiILAAUFiwQGBZZrABY2AgsAErIIqKYSCwAkNgZCOwA0NhZFBYsAJDYRuwA0NgWbADJbACYiCwAFBYsEBgWWawAWNhIyAgsAQmI0ZhOBsjsAhDRrACJbAIQ0cjRyNhYCCwBEOwAmIgsABQWLBAYFlmsAFjYCMgsAErI7AEQ2CwASuwBSVhsAUlsAJiILAAUFiwQGBZZrABY7AEJmEgsAQlYGQjsAMlYGRQWCEbIyFZIyAgsAQmI0ZhOFktsDossAAWsBEjQiAgILAFJiAuRyNHI2EjPDgtsDsssAAWsBEjQiCwCCNCICAgRiNHsAErI2E4LbA8LLAAFrARI0KwAyWwAiVHI0cjYbAAVFguIDwjIRuwAiWwAiVHI0cjYSCwBSWwBCVHI0cjYbAGJbAFJUmwAiVhuQgACABjYyMgWGIbIVljuAQAYiCwAFBYsEBgWWawAWNgIy4jICA8ijgjIVktsD0ssAAWsBEjQiCwCEMgLkcjRyNhIGCwIGBmsAJiILAAUFiwQGBZZrABYyMgIDyKOC2wPiwjIC5GsAIlRrARQ1hQG1JZWCA8WS6xLgEUKy2wPywjIC5GsAIlRrARQ1hSG1BZWCA8WS6xLgEUKy2wQCwjIC5GsAIlRrARQ1hQG1JZWCA8WSMgLkawAiVGsBFDWFIbUFlYIDxZLrEuARQrLbBBLLA4KyMgLkawAiVGsBFDWFAbUllYIDxZLrEuARQrLbBCLLA5K4ogIDywBCNCijgjIC5GsAIlRrARQ1hQG1JZWCA8WS6xLgEUK7AEQy6wListsEMssAAWsAQlsAQmICAgRiNHYbAKI0IuRyNHI2GwCUMrIyA8IC4jOLEuARQrLbBELLEIBCVCsAAWsAQlsAQlIC5HI0cjYSCwBCNCsQoAQrAJQysgsGBQWCCwQFFYswIgAyAbswImAxpZQkIjIEewBEOwAmIgsABQWLBAYFlmsAFjYCCwASsgiophILACQ2BkI7ADQ2FkUFiwAkNhG7ADQ2BZsAMlsAJiILAAUFiwQGBZZrABY2GwAiVGYTgjIDwjOBshICBGI0ewASsjYTghWbEuARQrLbBFLLEAOCsusS4BFCstsEYssQA5KyEjICA8sAQjQiM4sS4BFCuwBEMusC4rLbBHLLAAFSBHsAAjQrIAAQEVFBMusDQqLbBILLAAFSBHsAAjQrIAAQEVFBMusDQqLbBJLLEAARQTsDUqLbBKLLA3Ki2wSyywABZFIyAuIEaKI2E4sS4BFCstsEwssAgjQrBLKy2wTSyyAABEKy2wTiyyAAFEKy2wTyyyAQBEKy2wUCyyAQFEKy2wUSyyAABFKy2wUiyyAAFFKy2wUyyyAQBFKy2wVCyyAQFFKy2wVSyzAAAAQSstsFYsswABAEErLbBXLLMBAABBKy2wWCyzAQEAQSstsFksswAAAUErLbBaLLMAAQFBKy2wWyyzAQABQSstsFwsswEBAUErLbBdLLIAAEMrLbBeLLIAAUMrLbBfLLIBAEMrLbBgLLIBAUMrLbBhLLIAAEYrLbBiLLIAAUYrLbBjLLIBAEYrLbBkLLIBAUYrLbBlLLMAAABCKy2wZiyzAAEAQistsGcsswEAAEIrLbBoLLMBAQBCKy2waSyzAAABQistsGosswABAUIrLbBrLLMBAAFCKy2wbCyzAQEBQistsG0ssQA6Ky6xLgEUKy2wbiyxADorsD4rLbBvLLEAOiuwPystsHAssAAWsQA6K7BAKy2wcSyxATorsD4rLbByLLEBOiuwPystsHMssAAWsQE6K7BAKy2wdCyxADsrLrEuARQrLbB1LLEAOyuwPistsHYssQA7K7A/Ky2wdyyxADsrsEArLbB4LLEBOyuwPistsHkssQE7K7A/Ky2weiyxATsrsEArLbB7LLEAPCsusS4BFCstsHwssQA8K7A+Ky2wfSyxADwrsD8rLbB+LLEAPCuwQCstsH8ssQE8K7A+Ky2wgCyxATwrsD8rLbCBLLEBPCuwQCstsIIssQA9Ky6xLgEUKy2wgyyxAD0rsD4rLbCELLEAPSuwPystsIUssQA9K7BAKy2whiyxAT0rsD4rLbCHLLEBPSuwPystsIgssQE9K7BAKy2wiSyzCQQCA0VYIRsjIVlCK7AIZbADJFB4sQUBFUVYMFktAAAAAEu4AMhSWLEBAY5ZsAG5CAAIAGNwsQAHQkAJAGtbSzsAJwcAKrEAB0JAEHACYAhQCEAINAYsBB4HBwgqsQAHQkAQcgBoBlgGSAY6BDACJQUHCCqxAA5CQQkcQBhAFEAQQA1AC0AHwAAHAAkqsQAVQkEJAEAAQABAAEAAQABAAEAABwAJKrEDAESxJAGIUViwQIhYsQNkRLEmAYhRWLoIgAABBECIY1RYsQMARFlZWVlAEHIAYgZSBkIGNgQuAiAFBwwquAH/hbAEjbECAESzBWQGAEREAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYQBhAFQAVAK8AAACEgAA/z4CxP/4Ahf/+v84AGIAYgBUAFQCOAAAAkD/+ABiAGIAVABUAjgCOAAAAAACOAJA//j/+ABhAGEAVABUArwAAALmAhIAAP8+AsT/+AL1Ahf/+v84AGEAYQBUAFQBO/+cAuYCEgAA/z4BQP+XAvUCF//6/z4AYQBhAFQAVALmAUcC5gISAAD/PgLrAUIC9QIX//r/OAAYABgAGAAYAAAACABmAAMAAQQJAAAAsAAAAAMAAQQJAAEAIgCwAAMAAQQJAAIADgDSAAMAAQQJAAMAOADgAAMAAQQJAAQAIgCwAAMAAQQJAAUAGgEYAAMAAQQJAAYAIgEyAAMAAQQJAA4ANAFUAEMAbwBwAHkAcgBpAGcAaAB0ACAAMgAwADEAMQAgAFQAaABlACAATQBvAG4AdABzAGUAcgByAGEAdAAgAFAAcgBvAGoAZQBjAHQAIABBAHUAdABoAG8AcgBzACAAKABoAHQAdABwAHMAOgAvAC8AZwBpAHQAaAB1AGIALgBjAG8AbQAvAEoAdQBsAGkAZQB0AGEAVQBsAGEALwBNAG8AbgB0AHMAZQByAHIAYQB0ACkATQBvAG4AdABzAGUAcgByAGEAdAAgAE0AZQBkAGkAdQBtAFIAZQBnAHUAbABhAHIANwAuADIAMAAwADsAVQBMAEEAIAA7AE0AbwBuAHQAcwBlAHIAcgBhAHQALQBNAGUAZABpAHUAbQBWAGUAcgBzAGkAbwBuACAANwAuADIAMAAwAE0AbwBuAHQAcwBlAHIAcgBhAHQALQBNAGUAZABpAHUAbQBoAHQAdABwADoALwAvAHMAYwByAGkAcAB0AHMALgBzAGkAbAAuAG8AcgBnAC8ATwBGAEwAAAACAAAAAAAA/7UAMgAAAAAAAAAAAAAAAAAAAAAAAAAAB3AAAAECAAIAAwAkAMkBAwEEAQUBBgEHAQgBCQDHAQoBCwEMAQ0BDgEPAGIBEACtAREBEgETARQAYwEVAK4AkAEWACUAJgD9AP8AZAEXARgBGQAnARoA6QEbARwBHQEeAR8AKABlASABIQEiAMgBIwEkASUBJgEnASgAygEpASoAywErASwBLQEuAS8BMAExATIBMwApACoA+AE0ATUBNgE3ATgBOQArAToBOwE8AT0BPgAsAT8AzAFAAM0BQQDOAUIA+gFDAM8BRAFFAUYBRwFIAC0BSQAuAUoBSwAvAUwBTQFOAU8BUAFRAVIBUwDiADABVAAxAVUBVgFXAVgBWQFaAVsBXAFdAGYAMgDQAV4A0QFfAWABYQFiAWMBZABnAWUBZgFnANMBaAFpAWoBawFsAW0BbgFvAXABcQFyAXMBdACRAXUArwF2AXcBeACwADMA7QA0ADUBeQF6AXsBfAF9AX4BfwA2AYABgQGCAOQBgwD7AYQBhQGGAYcBiAGJAYoANwGLAYwBjQGOAY8BkAA4ANQBkQGSANUBkwBoAZQA1gGVAZYBlwGYAZkBmgGbAZwBnQGeAZ8BoAGhAaIBowA5ADoBpAGlAaYBpwA7ADwA6wGoALsBqQGqAasBrAGtAa4APQGvAOYBsAGxAbIBswG0AbUBtgG3AbgBuQG6AbsBvAG9Ab4BvwHAAcEBwgHDAcQBxQHGAccByAHJAcoBywHMAc0BzgHPAdAB0QHSAdMB1AHVAdYB1wHYAdkB2gHbAdwB3QHeAd8B4AHhAeIB4wHkAeUB5gHnAegB6QHqAesB7AHtAe4B7wHwAfEB8gHzAfQB9QH2AfcB+AH5AfoB+wH8Af0B/gH/AgACAQICAgMCBAIFAgYCBwIIAgkCCgILAgwCDQIOAg8CEAIRAhICEwIUAhUCFgIXAhgCGQIaAhsCHAIdAh4CHwIgAiECIgIjAiQCJQImAicCKAIpAioCKwIsAi0CLgIvAjACMQIyAjMCNAI1AjYCNwI4AjkCOgI7AjwCPQI+Aj8CQAJBAkICQwJEAkUCRgBEAGkCRwJIAkkCSgJLAkwCTQBrAk4CTwJQAlECUgJTAGwCVABqAlUCVgJXAlgAbgJZAG0AoAJaAEUARgD+AQAAbwJbAlwCXQBHAOoCXgEBAl8CYAJhAEgAcAJiAmMCZAByAmUCZgJnAmgCaQJqAHMCawJsAHECbQJuAm8CcAJxAnICcwJ0AnUCdgBJAEoA+QJ3AngCeQJ6AnsCfABLAn0CfgJ/AoACgQBMANcAdAKCAHYCgwB3AoQChQKGAHUChwKIAokCigKLAowATQKNAo4ATgKPApACkQBPApICkwKUApUClgKXApgA4wBQApkAUQKaApsCnAKdAp4CnwKgAqECogB4AFIAeQKjAHsCpAKlAqYCpwKoAqkAfAKqAqsCrAB6Aq0CrgKvArACsQKyArMCtAK1ArYCtwK4ArkAoQK6AH0CuwK8Ar0AsQBTAO4AVABVAr4CvwLAAsECwgLDAsQAVgLFAsYCxwDlAsgA/ALJAsoCywLMAs0AiQLOAFcCzwLQAtEC0gLTAtQC1QBYAH4C1gLXAIAC2ACBAtkAfwLaAtsC3ALdAt4C3wLgAuEC4gLjAuQC5QLmAucC6ABZAFoC6QLqAusC7ABbAFwA7ALtALoC7gLvAvAC8QLyAvMAXQL0AOcC9QL2AvcC+AL5AvoC+wL8Av0C/gL/AwADAQMCAwMDBAMFAwYDBwMIAwkDCgMLAwwDDQMOAw8DEAMRAxIDEwMUAxUDFgMXAxgDGQMaAxsDHAMdAx4DHwMgAyEDIgMjAyQDJQMmAycDKAMpAyoDKwMsAy0DLgMvAzADMQMyAzMDNAM1AzYDNwM4AzkDOgM7AzwDPQM+Az8DQANBA0IDQwNEA0UDRgNHA0gDSQNKA0sDTANNA04DTwNQA1EDUgNTAMAAwQNUA1UDVgNXA1gDWQNaA1sDXANdA14DXwNgA2EDYgNjA2QDZQNmA2cDaANpA2oDawNsA20DbgNvA3ADcQNyA3MDdAN1A3YDdwN4A3kDegN7A3wDfQN+A38DgAOBA4IDgwOEA4UDhgOHA4gDiQOKA4sDjAONA44DjwOQA5EDkgOTA5QDlQOWA5cDmAOZA5oDmwOcA50DngOfA6ADoQOiA6MDpAOlA6YDpwOoA6kDqgOrA6wDrQOuA68DsAOxA7IDswO0A7UDtgO3A7gDuQO6A7sDvAO9A74DvwPAA8EDwgPDA8QDxQPGA8cDyAPJA8oDywPMA80DzgPPA9AD0QPSA9MD1APVA9YD1wPYA9kD2gPbA9wD3QPeA98D4APhA+ID4wPkA+UD5gPnA+gD6QPqA+sD7APtA+4D7wPwA/ED8gPzA/QD9QP2A/cD+AP5A/oD+wP8A/0D/gP/BAAEAQQCBAMEBAQFBAYEBwQIBAkECgQLBAwEDQQOBA8EEAQRBBIEEwQUBBUEFgQXBBgEGQQaBBsEHAQdBB4EHwQgBCEEIgQjBCQEJQQmBCcEKAQpBCoEKwQsBC0ELgQvBDAEMQQyBDMENAQ1BDYENwQ4BDkEOgQ7BDwEPQQ+BD8EQARBBEIEQwREBEUERgRHBEgESQRKBEsETARNBE4ETwRQBFEEUgRTBFQEVQRWBFcEWARZBFoEWwRcBF0EXgRfBGAEYQRiBGMEZARlBGYEZwRoBGkEagRrBGwEbQRuBG8EcARxBHIEcwR0BHUEdgR3BHgEeQR6BHsEfAR9BH4EfwSABIEEggSDBIQEhQSGBIcEiASJBIoEiwSMBI0EjgSPBJAEkQSSBJMElASVBJYElwSYBJkEmgSbBJwEnQSeBJ8EoAShBKIEowSkBKUEpgSnBKgEqQSqBKsErAStBK4ErwSwBLEEsgSzBLQEtQS2BLcEuAS5BLoEuwS8BL0EvgS/BMAEwQTCBMMExATFBMYExwTIBMkEygTLBMwEzQTOBM8E0ATRBNIE0wTUBNUE1gTXBNgE2QTaAJ0AngTbBNwE3QTeBN8E4AThBOIE4wTkBOUE5gTnBOgE6QTqBOsE7ATtBO4E7wTwBPEE8gTzBPQE9QT2BPcE+AT5BPoE+wT8BP0E/gT/BQAFAQUCBQMFBAUFBQYFBwUIBQkFCgULBQwFDQUOBQ8FEAURBRIFEwUUBRUFFgUXBRgFGQUaBRsFHAUdBR4FHwUgBSEFIgUjBSQFJQUmBScFKAUpBSoFKwUsBS0FLgUvBTAFMQUyBTMFNAU1BTYFNwU4BTkFOgU7BTwFPQU+BT8FQAVBBUIFQwVEBUUFRgVHBUgFSQVKBUsFTAVNBU4FTwVQBVEFUgVTBVQFVQVWBVcFWAVZBVoFWwVcBV0FXgVfBWAFYQViBWMFZAVlBWYFZwVoBWkFagVrBWwFbQVuBW8FcAVxBXIFcwV0BXUFdgV3BXgFeQV6BXsFfAV9BX4FfwWABYEFggWDBYQFhQWGBYcFiAWJBYoFiwWMBY0FjgWPBZAFkQWSBZMFlAWVBZYFlwWYBZkFmgWbBZwFnQWeBZ8FoAWhBaIFowWkBaUFpgWnBagFqQWqBasFrAWtBa4FrwWwBbEFsgWzBbQFtQW2BbcFuAW5BboFuwW8Bb0FvgW/BcAFwQXCBcMFxAXFBcYFxwXIBckFygXLBcwFzQXOBc8F0AXRBdIF0wXUBdUF1gXXBdgF2QXaBdsF3AXdBd4F3wXgBeEF4gXjBeQF5QXmBecF6AXpBeoF6wXsBe0F7gXvBfAF8QXyBfMF9AX1BfYF9wX4BfkF+gX7BfwF/QX+Bf8GAAYBBgIGAwYEBgUGBgYHBggGCQYKBgsGDAYNBg4GDwYQBhEGEgYTBhQGFQYWBhcGGAYZBhoGGwYcBh0GHgYfBiAGIQYiBiMGJAYlBiYGJwYoBikGKgYrBiwGLQYuBi8GMAYxAJsGMgYzABMAFAAVABYAFwAYABkAGgAbABwGNAY1BjYGNwY4BjkGOgY7BjwGPQY+Bj8GQAZBBkIGQwZEBkUGRgZHBkgGSQZKBksGTAZNBk4GTwZQBlEGUgZTBlQGVQZWBlcGWAZZBloGWwZcBl0GXgZfBmAGYQZiBmMGZAZlBmYGZwZoBmkGagZrBmwGbQZuBm8GcAZxBnIGcwZ0BnUGdgZ3BngGeQZ6BnsGfAZ9Bn4GfwaABoEGggaDALwA9AaEBoUA9QD2BoYGhwaIBokADQA/AMMAhwAdAA8AqwAEAKMABgARACIAogAFAAoAHgASAEIGigaLBowGjQaOBo8AXgBgAD4AQAALAAwGkAaRBpIGkwaUBpUAswCyBpYGlwAQBpgGmQaaBpsGnACpAKoAvgC/AMUAtAC1ALYAtwDEBp0GngafBqAGoQaiBqMGpAalBqYGpwaoBqkGqgarBqwGrQauBq8GsAaxBrIGswa0BrUGtga3BrgGuQa6AIQGuwC9AAcGvAa9AKYA9wa+Br8GwAbBBsIGwwbEBsUGxgbHBsgAhQbJBsoGywCWBswGzQbOAA4A7wDwALgAIACPACEAHwCVAJQAkwCnAGEApAbPAJIAnAbQBtEAmgCZAKUG0gCYAAgAxgbTBtQG1QbWBtcG2AbZBtoG2wbcBt0G3gbfBuAG4QbiALkG4wbkBuUG5gbnBugG6QbqBusG7AAjAAkAiACGAIsAigCMAIMAXwDoBu0AggDCBu4G7wBBBvAG8QbyBvMG9Ab1BvYG9wb4BvkG+gb7BvwG/Qb+Bv8HAAcBBwIHAwcEBwUHBgcHBwgHCQcKBwsHDAcNBw4HDwcQBxEHEgcTBxQHFQcWBxcHGAcZBxoHGwccBx0HHgcfByAHIQciByMHJAclByYHJwcoBykHKgcrBywHLQcuBy8HMAcxBzIHMwc0BzUHNgc3BzgHOQc6BzsHPAc9Bz4HPwdAB0EHQgdDB0QHRQdGB0cHSAdJB0oHSwdMB00HTgdPB1AHUQdSB1MHVAdVB1YHVwdYB1kHWgdbB1wHXQCNANsA4QDeANgAjgDcAEMA3wDaAOAA3QDZB14HXwdgB2EHYgdjB2QHZQdmB2cHaAdpB2oHawdsB20HbgdvB3AHcQdyB3MHdAd1B3YHdwd4BE5VTEwGQWJyZXZlB3VuaTFFQUUHdW5pMUVCNgd1bmkxRUIwB3VuaTFFQjIHdW5pMUVCNAd1bmkwMUNEB3VuaTFFQTQHdW5pMUVBQwd1bmkxRUE2B3VuaTFFQTgHdW5pMUVBQQd1bmkwMjAwB3VuaTFFQTAHdW5pMUVBMgd1bmkwMjAyB0FtYWNyb24HQW9nb25lawpBcmluZ2FjdXRlB0FFYWN1dGUHdW5pMUUwOAtDY2lyY3VtZmxleApDZG90YWNjZW50B3VuaTAxQzQGRGNhcm9uBkRjcm9hdAd1bmkxRTBDB3VuaTFFMEUHdW5pMDFDNQZFYnJldmUGRWNhcm9uB3VuaTFFMUMHdW5pMUVCRQd1bmkxRUM2B3VuaTFFQzAHdW5pMUVDMgd1bmkxRUM0B3VuaTAyMDQKRWRvdGFjY2VudAd1bmkxRUI4B3VuaTFFQkEHdW5pMDIwNgdFbWFjcm9uB3VuaTFFMTYHdW5pMUUxNAdFb2dvbmVrB3VuaTFFQkMHdW5pMDFCNwd1bmkwMUVFBkdjYXJvbgtHY2lyY3VtZmxleAxHY29tbWFhY2NlbnQKR2RvdGFjY2VudAd1bmkxRTIwB3VuaTAxRTQESGJhcgd1bmkxRTJBB3VuaTAyMUULSGNpcmN1bWZsZXgHdW5pMUUyNAJJSgZJYnJldmUHdW5pMDIwOAd1bmkxRTJFB3VuaTFFQ0EHdW5pMUVDOAd1bmkwMjBBB0ltYWNyb24HSW9nb25lawZJdGlsZGULSmNpcmN1bWZsZXgHdW5pMDFFOAxLY29tbWFhY2NlbnQHdW5pMDFDNwZMYWN1dGUGTGNhcm9uDExjb21tYWFjY2VudARMZG90B3VuaTFFMzYHdW5pMDFDOAd1bmkxRTNBB3VuaTFFNDIHdW5pMDFDQQZOYWN1dGUGTmNhcm9uDE5jb21tYWFjY2VudAd1bmkxRTQ0B3VuaTFFNDYDRW5nB3VuaTAxQ0IHdW5pMUU0OAZPYnJldmUHdW5pMUVEMAd1bmkxRUQ4B3VuaTFFRDIHdW5pMUVENAd1bmkxRUQ2B3VuaTAyMEMHdW5pMDIyQQd1bmkwMjMwB3VuaTFFQ0MHdW5pMUVDRQVPaG9ybgd1bmkxRURBB3VuaTFFRTIHdW5pMUVEQwd1bmkxRURFB3VuaTFFRTANT2h1bmdhcnVtbGF1dAd1bmkwMjBFB09tYWNyb24HdW5pMUU1Mgd1bmkxRTUwB3VuaTAxRUELT3NsYXNoYWN1dGUHdW5pMUU0Qwd1bmkxRTRFB3VuaTAyMkMGUmFjdXRlBlJjYXJvbgxSY29tbWFhY2NlbnQHdW5pMDIxMAd1bmkxRTVBB3VuaTAyMTIHdW5pMUU1RQZTYWN1dGUHdW5pMUU2NAd1bmlBNzhCB3VuaTFFNjYLU2NpcmN1bWZsZXgMU2NvbW1hYWNjZW50B3VuaTFFNjAHdW5pMUU2Mgd1bmkxRTY4B3VuaTFFOUUHdW5pMDE4RgRUYmFyBlRjYXJvbgd1bmkwMTYyB3VuaTAyMUEHdW5pMUU2Qwd1bmkxRTZFBlVicmV2ZQd1bmkwMUQzB3VuaTAyMTQHdW5pMUVFNAd1bmkxRUU2BVVob3JuB3VuaTFFRTgHdW5pMUVGMAd1bmkxRUVBB3VuaTFFRUMHdW5pMUVFRQ1VaHVuZ2FydW1sYXV0B3VuaTAyMTYHVW1hY3Jvbgd1bmkxRTdBB1VvZ29uZWsFVXJpbmcGVXRpbGRlB3VuaTFFNzgGV2FjdXRlC1djaXJjdW1mbGV4CVdkaWVyZXNpcwZXZ3JhdmULWWNpcmN1bWZsZXgHdW5pMUU4RQd1bmkxRUY0BllncmF2ZQd1bmkxRUY2B3VuaTAyMzIHdW5pMUVGOAZaYWN1dGUKWmRvdGFjY2VudAd1bmkxRTkyEElhY3V0ZV9KLmxvY2xOTEQGQS5zczAxC0FhY3V0ZS5zczAxC0FicmV2ZS5zczAxDHVuaTFFQUUuc3MwMQx1bmkxRUI2LnNzMDEMdW5pMUVCMC5zczAxDHVuaTFFQjIuc3MwMQx1bmkxRUI0LnNzMDEMdW5pMDFDRC5zczAxEEFjaXJjdW1mbGV4LnNzMDEMdW5pMUVBNC5zczAxDHVuaTFFQUMuc3MwMQx1bmkxRUE2LnNzMDEMdW5pMUVBOC5zczAxDHVuaTFFQUEuc3MwMQx1bmkwMjAwLnNzMDEOQWRpZXJlc2lzLnNzMDEMdW5pMUVBMC5zczAxC0FncmF2ZS5zczAxDHVuaTFFQTIuc3MwMQx1bmkwMjAyLnNzMDEMQW1hY3Jvbi5zczAxDEFvZ29uZWsuc3MwMQpBcmluZy5zczAxD0FyaW5nYWN1dGUuc3MwMQtBdGlsZGUuc3MwMQdBRS5zczAxDEFFYWN1dGUuc3MwMQx1bmkwMUM0LnNzMDEMdW5pMDFDNS5zczAxBkUuc3MwMQtFYWN1dGUuc3MwMQtFYnJldmUuc3MwMQtFY2Fyb24uc3MwMQx1bmkxRTFDLnNzMDEQRWNpcmN1bWZsZXguc3MwMQx1bmkxRUJFLnNzMDEMdW5pMUVDNi5zczAxDHVuaTFFQzAuc3MwMQx1bmkxRUMyLnNzMDEMdW5pMUVDNC5zczAxDHVuaTAyMDQuc3MwMQ5FZGllcmVzaXMuc3MwMQ9FZG90YWNjZW50LnNzMDEMdW5pMUVCOC5zczAxC0VncmF2ZS5zczAxDHVuaTFFQkEuc3MwMQx1bmkwMjA2LnNzMDEMRW1hY3Jvbi5zczAxDHVuaTFFMTYuc3MwMQx1bmkxRTE0LnNzMDEMRW9nb25lay5zczAxDHVuaTFFQkMuc3MwMQZGLnNzMDEGRy5zczAxC0dicmV2ZS5zczAxC0djYXJvbi5zczAxEEdjaXJjdW1mbGV4LnNzMDERR2NvbW1hYWNjZW50LnNzMDEPR2RvdGFjY2VudC5zczAxDHVuaTFFMjAuc3MwMQx1bmkwMUU0LnNzMDEGSS5zczAxB0lKLnNzMDELSWFjdXRlLnNzMDEVSWFjdXRlX0oubG9jbE5MRC5zczAxC0licmV2ZS5zczAxEEljaXJjdW1mbGV4LnNzMDEMdW5pMDIwOC5zczAxDklkaWVyZXNpcy5zczAxDHVuaTFFMkUuc3MwMQ9JZG90YWNjZW50LnNzMDEMdW5pMUVDQS5zczAxC0lncmF2ZS5zczAxDHVuaTFFQzguc3MwMQx1bmkwMjBBLnNzMDEMSW1hY3Jvbi5zczAxDElvZ29uZWsuc3MwMQtJdGlsZGUuc3MwMQZKLnNzMDEQSmNpcmN1bWZsZXguc3MwMQx1bmkwMUM3LnNzMDEGTS5zczAxDHVuaTFFNDIuc3MwMQZOLnNzMDEMdW5pMDFDQS5zczAxC05hY3V0ZS5zczAxC05jYXJvbi5zczAxEU5jb21tYWFjY2VudC5zczAxDHVuaTFFNDQuc3MwMQx1bmkxRTQ2LnNzMDEIRW5nLnNzMDEMdW5pMDFDQi5zczAxDHVuaTFFNDguc3MwMQtOdGlsZGUuc3MwMQZRLnNzMDEMdW5pMDE4Ri5zczAxBlQuc3MwMQlUYmFyLnNzMDELVGNhcm9uLnNzMDEMdW5pMDE2Mi5zczAxDHVuaTAyMUEuc3MwMQx1bmkxRTZDLnNzMDEMdW5pMUU2RS5zczAxBlUuc3MwMQtVYWN1dGUuc3MwMQtVYnJldmUuc3MwMQx1bmkwMUQzLnNzMDEQVWNpcmN1bWZsZXguc3MwMQx1bmkwMjE0LnNzMDEOVWRpZXJlc2lzLnNzMDEMdW5pMUVFNC5zczAxC1VncmF2ZS5zczAxDHVuaTFFRTYuc3MwMQpVaG9ybi5zczAxDHVuaTFFRTguc3MwMQx1bmkxRUYwLnNzMDEMdW5pMUVFQS5zczAxDHVuaTFFRUMuc3MwMQx1bmkxRUVFLnNzMDESVWh1bmdhcnVtbGF1dC5zczAxDHVuaTAyMTYuc3MwMQxVbWFjcm9uLnNzMDEMdW5pMUU3QS5zczAxDFVvZ29uZWsuc3MwMQpVcmluZy5zczAxC1V0aWxkZS5zczAxDHVuaTFFNzguc3MwMQZXLnNzMDELV2FjdXRlLnNzMDEQV2NpcmN1bWZsZXguc3MwMQ5XZGllcmVzaXMuc3MwMQtXZ3JhdmUuc3MwMQZZLnNzMDELWWFjdXRlLnNzMDEQWWNpcmN1bWZsZXguc3MwMQ5ZZGllcmVzaXMuc3MwMQx1bmkxRThFLnNzMDEMdW5pMUVGNC5zczAxC1lncmF2ZS5zczAxDHVuaTFFRjYuc3MwMQx1bmkwMjMyLnNzMDEMdW5pMUVGOC5zczAxBlouc3MwMQtaYWN1dGUuc3MwMQtaY2Fyb24uc3MwMQ9aZG90YWNjZW50LnNzMDEMdW5pMUU5Mi5zczAxBmFicmV2ZQd1bmkxRUFGB3VuaTFFQjcHdW5pMUVCMQd1bmkxRUIzB3VuaTFFQjUHdW5pMDFDRQd1bmkxRUE1B3VuaTFFQUQHdW5pMUVBNwd1bmkxRUE5B3VuaTFFQUIHdW5pMDIwMQd1bmkxRUExB3VuaTFFQTMHdW5pMDIwMwdhbWFjcm9uB2FvZ29uZWsKYXJpbmdhY3V0ZQdhZWFjdXRlB3VuaTFFMDkLY2NpcmN1bWZsZXgKY2RvdGFjY2VudAZkY2Fyb24HdW5pMUUwRAd1bmkxRTBGB3VuaTAxQzYGZWJyZXZlBmVjYXJvbgd1bmkxRTFEB3VuaTFFQkYHdW5pMUVDNwd1bmkxRUMxB3VuaTFFQzMHdW5pMUVDNQd1bmkwMjA1CmVkb3RhY2NlbnQHdW5pMUVCOQd1bmkxRUJCB3VuaTAyMDcHZW1hY3Jvbgd1bmkxRTE3B3VuaTFFMTUHZW9nb25lawd1bmkxRUJEB3VuaTAyNTkHdW5pMDI5Mgd1bmkwMUVGBmdjYXJvbgtnY2lyY3VtZmxleAxnY29tbWFhY2NlbnQKZ2RvdGFjY2VudAd1bmkxRTIxB3VuaTAxRTUEaGJhcgd1bmkxRTJCB3VuaTAyMUYLaGNpcmN1bWZsZXgHdW5pMUUyNQZpYnJldmUHdW5pMDIwOQd1bmkxRTJGCWkubG9jbFRSSwd1bmkxRUNCB3VuaTFFQzkHdW5pMDIwQgJpagdpbWFjcm9uB2lvZ29uZWsGaXRpbGRlB3VuaTAyMzcLamNpcmN1bWZsZXgHdW5pMDFFOQxrY29tbWFhY2NlbnQMa2dyZWVubGFuZGljBmxhY3V0ZQZsY2Fyb24MbGNvbW1hYWNjZW50BGxkb3QHdW5pMUUzNwd1bmkwMUM5B3VuaTFFM0IHdW5pMUU0MwZuYWN1dGULbmFwb3N0cm9waGUGbmNhcm9uDG5jb21tYWFjY2VudAd1bmkxRTQ1B3VuaTFFNDcDZW5nB3VuaTAxQ0MHdW5pMUU0OQZvYnJldmUHdW5pMUVEMQd1bmkxRUQ5B3VuaTFFRDMHdW5pMUVENQd1bmkxRUQ3B3VuaTAyMEQHdW5pMDIyQgd1bmkwMjMxB3VuaTFFQ0QHdW5pMUVDRgVvaG9ybgd1bmkxRURCB3VuaTFFRTMHdW5pMUVERAd1bmkxRURGB3VuaTFFRTENb2h1bmdhcnVtbGF1dAd1bmkwMjBGB29tYWNyb24HdW5pMUU1Mwd1bmkxRTUxB3VuaTAxRUILb3NsYXNoYWN1dGUHdW5pMUU0RAd1bmkxRTRGB3VuaTAyMkQGcmFjdXRlBnJjYXJvbgxyY29tbWFhY2NlbnQHdW5pMDIxMQd1bmkxRTVCB3VuaTAyMTMHdW5pMUU1RgZzYWN1dGUHdW5pMUU2NQd1bmlBNzhDB3VuaTFFNjcLc2NpcmN1bWZsZXgMc2NvbW1hYWNjZW50B3VuaTFFNjEHdW5pMUU2Mwd1bmkxRTY5BWxvbmdzBHRiYXIGdGNhcm9uB3VuaTAxNjMHdW5pMDIxQgd1bmkxRTk3B3VuaTFFNkQHdW5pMUU2RgZ1YnJldmUHdW5pMDFENAd1bmkwMjE1B3VuaTFFRTUHdW5pMUVFNwV1aG9ybgd1bmkxRUU5B3VuaTFFRjEHdW5pMUVFQgd1bmkxRUVEB3VuaTFFRUYNdWh1bmdhcnVtbGF1dAd1bmkwMjE3B3VtYWNyb24HdW5pMUU3Qgd1b2dvbmVrBXVyaW5nBnV0aWxkZQd1bmkxRTc5BndhY3V0ZQt3Y2lyY3VtZmxleAl3ZGllcmVzaXMGd2dyYXZlC3ljaXJjdW1mbGV4B3VuaTFFOEYHdW5pMUVGNQZ5Z3JhdmUHdW5pMUVGNwd1bmkwMjMzB3VuaTFFRjkGemFjdXRlCnpkb3RhY2NlbnQHdW5pMUU5MxBpYWN1dGVfai5sb2NsTkxEBmEuc3MwMQthYWN1dGUuc3MwMQthYnJldmUuc3MwMQx1bmkxRUFGLnNzMDEMdW5pMUVCNy5zczAxDHVuaTFFQjEuc3MwMQx1bmkxRUIzLnNzMDEMdW5pMUVCNS5zczAxDHVuaTAxQ0Uuc3MwMRBhY2lyY3VtZmxleC5zczAxDHVuaTFFQTUuc3MwMQx1bmkxRUFELnNzMDEMdW5pMUVBNy5zczAxDHVuaTFFQTkuc3MwMQx1bmkxRUFCLnNzMDEMdW5pMDIwMS5zczAxDmFkaWVyZXNpcy5zczAxDHVuaTFFQTEuc3MwMQthZ3JhdmUuc3MwMQx1bmkxRUEzLnNzMDEMdW5pMDIwMy5zczAxDGFtYWNyb24uc3MwMQxhb2dvbmVrLnNzMDEKYXJpbmcuc3MwMQ9hcmluZ2FjdXRlLnNzMDELYXRpbGRlLnNzMDEHYWUuc3MwMQxhZWFjdXRlLnNzMDEMdW5pMDFDNi5zczAxBmUuc3MwMQtlYWN1dGUuc3MwMQtlYnJldmUuc3MwMQtlY2Fyb24uc3MwMQx1bmkxRTFELnNzMDEQZWNpcmN1bWZsZXguc3MwMQx1bmkxRUJGLnNzMDEMdW5pMUVDNy5zczAxDHVuaTFFQzEuc3MwMQx1bmkxRUMzLnNzMDEMdW5pMUVDNS5zczAxDHVuaTAyMDUuc3MwMQ5lZGllcmVzaXMuc3MwMQ9lZG90YWNjZW50LnNzMDEMdW5pMUVCOS5zczAxC2VncmF2ZS5zczAxDHVuaTFFQkIuc3MwMQx1bmkwMjA3LnNzMDEMZW1hY3Jvbi5zczAxDHVuaTFFMTcuc3MwMQx1bmkxRTE1LnNzMDEMZW9nb25lay5zczAxDHVuaTFFQkQuc3MwMQx1bmkwMjU5LnNzMDEGZi5zczAxBmwuc3MwMQtsYWN1dGUuc3MwMQtsY2Fyb24uc3MwMRFsY29tbWFhY2NlbnQuc3MwMQlsZG90LnNzMDEMdW5pMUUzNy5zczAxDHVuaTAxQzkuc3MwMQx1bmkxRTNCLnNzMDELbHNsYXNoLnNzMDEHb2Uuc3MwMQZ0LnNzMDEJdGJhci5zczAxC3RjYXJvbi5zczAxDHVuaTAxNjMuc3MwMQx1bmkwMjFCLnNzMDEMdW5pMUU5Ny5zczAxDHVuaTFFNkQuc3MwMQx1bmkxRTZGLnNzMDEGdy5zczAxC3dhY3V0ZS5zczAxEHdjaXJjdW1mbGV4LnNzMDEOd2RpZXJlc2lzLnNzMDELd2dyYXZlLnNzMDEGeS5zczAxC3lhY3V0ZS5zczAxEHljaXJjdW1mbGV4LnNzMDEOeWRpZXJlc2lzLnNzMDEMdW5pMUVGNS5zczAxC3lncmF2ZS5zczAxDHVuaTFFRjcuc3MwMQx1bmkwMjMzLnNzMDEMdW5pMUVGOS5zczAxBnouc3MwMQt6YWN1dGUuc3MwMQt6Y2Fyb24uc3MwMQ96ZG90YWNjZW50LnNzMDEMdW5pMUU5My5zczAxA1RfaAdmaS5zczAxB2ZsLnNzMDEEYS5zYwlhYWN1dGUuc2MJYWJyZXZlLnNjCnVuaTFFQUYuc2MKdW5pMUVCNy5zYwp1bmkxRUIxLnNjCnVuaTFFQjMuc2MKdW5pMUVCNS5zYwp1bmkwMUNFLnNjDmFjaXJjdW1mbGV4LnNjCnVuaTFFQTUuc2MKdW5pMUVBRC5zYwp1bmkxRUE3LnNjCnVuaTFFQTkuc2MKdW5pMUVBQi5zYwp1bmkwMjAxLnNjDGFkaWVyZXNpcy5zYwp1bmkxRUExLnNjCWFncmF2ZS5zYwp1bmkxRUEzLnNjCnVuaTAyMDMuc2MKYW1hY3Jvbi5zYwphb2dvbmVrLnNjCGFyaW5nLnNjDWFyaW5nYWN1dGUuc2MJYXRpbGRlLnNjBWFlLnNjCmFlYWN1dGUuc2MEYi5zYwRjLnNjCWNhY3V0ZS5zYwljY2Fyb24uc2MLY2NlZGlsbGEuc2MKdW5pMUUwOS5zYw5jY2lyY3VtZmxleC5zYw1jZG90YWNjZW50LnNjBGQuc2MGZXRoLnNjCWRjYXJvbi5zYwlkY3JvYXQuc2MKdW5pMUUwRC5zYwp1bmkxRTBGLnNjCnVuaTAxQzYuc2MEZS5zYwllYWN1dGUuc2MJZWJyZXZlLnNjCWVjYXJvbi5zYwp1bmkxRTFELnNjDmVjaXJjdW1mbGV4LnNjCnVuaTFFQkYuc2MKdW5pMUVDNy5zYwp1bmkxRUMxLnNjCnVuaTFFQzMuc2MKdW5pMUVDNS5zYwp1bmkwMjA1LnNjDGVkaWVyZXNpcy5zYw1lZG90YWNjZW50LnNjCnVuaTFFQjkuc2MJZWdyYXZlLnNjCnVuaTFFQkIuc2MKdW5pMDIwNy5zYwplbWFjcm9uLnNjCnVuaTFFMTcuc2MKdW5pMUUxNS5zYwplb2dvbmVrLnNjCnVuaTFFQkQuc2MKdW5pMDI1OS5zYwp1bmkwMjkyLnNjCnVuaTAxRUYuc2MEZi5zYwRnLnNjCWdicmV2ZS5zYwlnY2Fyb24uc2MOZ2NpcmN1bWZsZXguc2MPZ2NvbW1hYWNjZW50LnNjDWdkb3RhY2NlbnQuc2MKdW5pMUUyMS5zYwp1bmkwMUU1LnNjBGguc2MHaGJhci5zYwp1bmkxRTJCLnNjCnVuaTAyMUYuc2MOaGNpcmN1bWZsZXguc2MKdW5pMUUyNS5zYwRpLnNjC2RvdGxlc3NpLnNjCWlhY3V0ZS5zYxNpYWN1dGVfai5sb2NsTkxELnNjCWlicmV2ZS5zYw5pY2lyY3VtZmxleC5zYwp1bmkwMjA5LnNjDGlkaWVyZXNpcy5zYwp1bmkxRTJGLnNjDGkuc2MubG9jbFRSSwp1bmkxRUNCLnNjCWlncmF2ZS5zYwp1bmkxRUM5LnNjCnVuaTAyMEIuc2MFaWouc2MKaW1hY3Jvbi5zYwppb2dvbmVrLnNjCWl0aWxkZS5zYwRqLnNjDmpjaXJjdW1mbGV4LnNjBGsuc2MKdW5pMDFFOS5zYw9rY29tbWFhY2NlbnQuc2MPa2dyZWVubGFuZGljLnNjBGwuc2MJbGFjdXRlLnNjCWxjYXJvbi5zYw9sY29tbWFhY2NlbnQuc2MHbGRvdC5zYwp1bmkxRTM3LnNjCnVuaTAxQzkuc2MKdW5pMUUzQi5zYwlsc2xhc2guc2MEbS5zYwp1bmkxRTQzLnNjBG4uc2MJbmFjdXRlLnNjCW5jYXJvbi5zYw9uY29tbWFhY2NlbnQuc2MKdW5pMUU0NS5zYwp1bmkxRTQ3LnNjBmVuZy5zYwp1bmkwMUNDLnNjCnVuaTFFNDkuc2MJbnRpbGRlLnNjBG8uc2MJb2FjdXRlLnNjCW9icmV2ZS5zYw5vY2lyY3VtZmxleC5zYwp1bmkxRUQxLnNjCnVuaTFFRDkuc2MKdW5pMUVEMy5zYwp1bmkxRUQ1LnNjCnVuaTFFRDcuc2MKdW5pMDIwRC5zYwxvZGllcmVzaXMuc2MKdW5pMDIyQi5zYwp1bmkwMjMxLnNjCnVuaTFFQ0Quc2MJb2dyYXZlLnNjCnVuaTFFQ0Yuc2MIb2hvcm4uc2MKdW5pMUVEQi5zYwp1bmkxRUUzLnNjCnVuaTFFREQuc2MKdW5pMUVERi5zYwp1bmkxRUUxLnNjEG9odW5nYXJ1bWxhdXQuc2MKdW5pMDIwRi5zYwpvbWFjcm9uLnNjCnVuaTFFNTMuc2MKdW5pMUU1MS5zYwp1bmkwMUVCLnNjCW9zbGFzaC5zYw5vc2xhc2hhY3V0ZS5zYwlvdGlsZGUuc2MKdW5pMUU0RC5zYwp1bmkxRTRGLnNjCnVuaTAyMkQuc2MFb2Uuc2MEcC5zYwh0aG9ybi5zYwRxLnNjBHIuc2MJcmFjdXRlLnNjCXJjYXJvbi5zYw9yY29tbWFhY2NlbnQuc2MKdW5pMDIxMS5zYwp1bmkxRTVCLnNjCnVuaTAyMTMuc2MKdW5pMUU1Ri5zYwRzLnNjCXNhY3V0ZS5zYwp1bmkxRTY1LnNjCnVuaUE3OEMuc2MJc2Nhcm9uLnNjCnVuaTFFNjcuc2MLc2NlZGlsbGEuc2MOc2NpcmN1bWZsZXguc2MPc2NvbW1hYWNjZW50LnNjCnVuaTFFNjEuc2MKdW5pMUU2My5zYwp1bmkxRTY5LnNjDWdlcm1hbmRibHMuc2MEdC5zYwd0YmFyLnNjCXRjYXJvbi5zYwp1bmkwMTYzLnNjCnVuaTAyMUIuc2MKdW5pMUU5Ny5zYwp1bmkxRTZELnNjCnVuaTFFNkYuc2MEdS5zYwl1YWN1dGUuc2MJdWJyZXZlLnNjCnVuaTAxRDQuc2MOdWNpcmN1bWZsZXguc2MKdW5pMDIxNS5zYwx1ZGllcmVzaXMuc2MKdW5pMUVFNS5zYwl1Z3JhdmUuc2MKdW5pMUVFNy5zYwh1aG9ybi5zYwp1bmkxRUU5LnNjCnVuaTFFRjEuc2MKdW5pMUVFQi5zYwp1bmkxRUVELnNjCnVuaTFFRUYuc2MQdWh1bmdhcnVtbGF1dC5zYwp1bmkwMjE3LnNjCnVtYWNyb24uc2MKdW5pMUU3Qi5zYwp1b2dvbmVrLnNjCHVyaW5nLnNjCXV0aWxkZS5zYwp1bmkxRTc5LnNjBHYuc2MEdy5zYwl3YWN1dGUuc2MOd2NpcmN1bWZsZXguc2MMd2RpZXJlc2lzLnNjCXdncmF2ZS5zYwR4LnNjBHkuc2MJeWFjdXRlLnNjDnljaXJjdW1mbGV4LnNjDHlkaWVyZXNpcy5zYwp1bmkxRThGLnNjCnVuaTFFRjUuc2MJeWdyYXZlLnNjCnVuaTFFRjcuc2MKdW5pMDIzMy5zYwp1bmkxRUY5LnNjBHouc2MJemFjdXRlLnNjCXpjYXJvbi5zYw16ZG90YWNjZW50LnNjCnVuaTFFOTMuc2MJYS5zYy5zczAxDmFhY3V0ZS5zYy5zczAxDmFicmV2ZS5zYy5zczAxD3VuaTFFQUYuc2Muc3MwMQ91bmkxRUI3LnNjLnNzMDEPdW5pMUVCMS5zYy5zczAxD3VuaTFFQjMuc2Muc3MwMQ91bmkxRUI1LnNjLnNzMDEPdW5pMDFDRS5zYy5zczAxE2FjaXJjdW1mbGV4LnNjLnNzMDEPdW5pMUVBNS5zYy5zczAxD3VuaTFFQUQuc2Muc3MwMQ91bmkxRUE3LnNjLnNzMDEPdW5pMUVBOS5zYy5zczAxD3VuaTFFQUIuc2Muc3MwMQ91bmkwMjAxLnNjLnNzMDERYWRpZXJlc2lzLnNjLnNzMDEPdW5pMUVBMS5zYy5zczAxDmFncmF2ZS5zYy5zczAxD3VuaTFFQTMuc2Muc3MwMQ91bmkwMjAzLnNjLnNzMDEPYW1hY3Jvbi5zYy5zczAxD2FvZ29uZWsuc2Muc3MwMQ1hcmluZy5zYy5zczAxEmFyaW5nYWN1dGUuc2Muc3MwMQ5hdGlsZGUuc2Muc3MwMQphZS5zYy5zczAxD2FlYWN1dGUuc2Muc3MwMQ91bmkwMUM2LnNjLnNzMDEJZS5zYy5zczAxDmVhY3V0ZS5zYy5zczAxDmVicmV2ZS5zYy5zczAxDmVjYXJvbi5zYy5zczAxD3VuaTFFMUQuc2Muc3MwMRNlY2lyY3VtZmxleC5zYy5zczAxD3VuaTFFQkYuc2Muc3MwMQ91bmkxRUM3LnNjLnNzMDEPdW5pMUVDMS5zYy5zczAxD3VuaTFFQzMuc2Muc3MwMQ91bmkxRUM1LnNjLnNzMDEPdW5pMDIwNS5zYy5zczAxEWVkaWVyZXNpcy5zYy5zczAxEmVkb3RhY2NlbnQuc2Muc3MwMQ91bmkxRUI5LnNjLnNzMDEOZWdyYXZlLnNjLnNzMDEPdW5pMUVCQi5zYy5zczAxD3VuaTAyMDcuc2Muc3MwMQ9lbWFjcm9uLnNjLnNzMDEPdW5pMUUxNy5zYy5zczAxD3VuaTFFMTUuc2Muc3MwMQ9lb2dvbmVrLnNjLnNzMDEPdW5pMUVCRC5zYy5zczAxD3VuaTAyNTkuc2Muc3MwMQlmLnNjLnNzMDEJZy5zYy5zczAxDmdicmV2ZS5zYy5zczAxDmdjYXJvbi5zYy5zczAxE2djaXJjdW1mbGV4LnNjLnNzMDEUZ2NvbW1hYWNjZW50LnNjLnNzMDESZ2RvdGFjY2VudC5zYy5zczAxD3VuaTFFMjEuc2Muc3MwMQ91bmkwMUU1LnNjLnNzMDEJaS5zYy5zczAxEGRvdGxlc3NpLnNjLnNzMDEOaWFjdXRlLnNjLnNzMDEYaWFjdXRlX2oubG9jbE5MRC5zYy5zczAxDmlicmV2ZS5zYy5zczAxE2ljaXJjdW1mbGV4LnNjLnNzMDEPdW5pMDIwOS5zYy5zczAxEWlkaWVyZXNpcy5zYy5zczAxD3VuaTFFMkYuc2Muc3MwMQ91bmkxRUNCLnNjLnNzMDEOaWdyYXZlLnNjLnNzMDEPdW5pMUVDOS5zYy5zczAxD3VuaTAyMEIuc2Muc3MwMQppai5zYy5zczAxD2ltYWNyb24uc2Muc3MwMQ9pb2dvbmVrLnNjLnNzMDEOaXRpbGRlLnNjLnNzMDEJai5zYy5zczAxE2pjaXJjdW1mbGV4LnNjLnNzMDEPdW5pMDFDOS5zYy5zczAxCW0uc2Muc3MwMQ91bmkxRTQzLnNjLnNzMDEJbi5zYy5zczAxDm5hY3V0ZS5zYy5zczAxDm5jYXJvbi5zYy5zczAxFG5jb21tYWFjY2VudC5zYy5zczAxD3VuaTFFNDUuc2Muc3MwMQ91bmkxRTQ3LnNjLnNzMDELZW5nLnNjLnNzMDEPdW5pMDFDQy5zYy5zczAxD3VuaTFFNDkuc2Muc3MwMQ5udGlsZGUuc2Muc3MwMQlxLnNjLnNzMDEJdC5zYy5zczAxDHRiYXIuc2Muc3MwMQ50Y2Fyb24uc2Muc3MwMQ91bmkwMTYzLnNjLnNzMDEPdW5pMDIxQi5zYy5zczAxD3VuaTFFOTcuc2Muc3MwMQ91bmkxRTZELnNjLnNzMDEPdW5pMUU2Ri5zYy5zczAxCXUuc2Muc3MwMQ51YWN1dGUuc2Muc3MwMQ51YnJldmUuc2Muc3MwMQ91bmkwMUQ0LnNjLnNzMDETdWNpcmN1bWZsZXguc2Muc3MwMQ91bmkwMjE1LnNjLnNzMDERdWRpZXJlc2lzLnNjLnNzMDEPdW5pMUVFNS5zYy5zczAxDnVncmF2ZS5zYy5zczAxD3VuaTFFRTcuc2Muc3MwMQ11aG9ybi5zYy5zczAxD3VuaTFFRTkuc2Muc3MwMQ91bmkxRUYxLnNjLnNzMDEPdW5pMUVFQi5zYy5zczAxD3VuaTFFRUQuc2Muc3MwMQ91bmkxRUVGLnNjLnNzMDEVdWh1bmdhcnVtbGF1dC5zYy5zczAxD3VuaTAyMTcuc2Muc3MwMQ91bWFjcm9uLnNjLnNzMDEPdW5pMUU3Qi5zYy5zczAxD3VvZ29uZWsuc2Muc3MwMQ11cmluZy5zYy5zczAxDnV0aWxkZS5zYy5zczAxD3VuaTFFNzkuc2Muc3MwMQl3LnNjLnNzMDEOd2FjdXRlLnNjLnNzMDETd2NpcmN1bWZsZXguc2Muc3MwMRF3ZGllcmVzaXMuc2Muc3MwMQ53Z3JhdmUuc2Muc3MwMQl5LnNjLnNzMDEOeWFjdXRlLnNjLnNzMDETeWNpcmN1bWZsZXguc2Muc3MwMRF5ZGllcmVzaXMuc2Muc3MwMQ91bmkxRThGLnNjLnNzMDEPdW5pMUVGNS5zYy5zczAxDnlncmF2ZS5zYy5zczAxD3VuaTFFRjcuc2Muc3MwMQ91bmkwMjMzLnNjLnNzMDEPdW5pMUVGOS5zYy5zczAxCXouc2Muc3MwMQ56YWN1dGUuc2Muc3MwMQ56Y2Fyb24uc2Muc3MwMRJ6ZG90YWNjZW50LnNjLnNzMDEPdW5pMUU5My5zYy5zczAxB3VuaTA0MTAHdW5pMDQxMQd1bmkwNDEyB3VuaTA0MTMHdW5pMDQwMwd1bmkwNDkwB3VuaTA0MTQHdW5pMDQxNQd1bmkwNDAwB3VuaTA0MDEHdW5pMDQxNgd1bmkwNDE3B3VuaTA0MTgHdW5pMDQxOQd1bmkwNDBEB3VuaTA0OEEHdW5pMDQxQQd1bmkwNDBDB3VuaTA0MUIHdW5pMDQxQwd1bmkwNDFEB3VuaTA0MUUHdW5pMDQxRgd1bmkwNDIwB3VuaTA0MjEHdW5pMDQyMgd1bmkwNDIzB3VuaTA0MEUHdW5pMDQyNAd1bmkwNDI1B3VuaTA0MjcHdW5pMDQyNgd1bmkwNDI4B3VuaTA0MjkHdW5pMDQwRgd1bmkwNDJDB3VuaTA0MkEHdW5pMDQyQgd1bmkwNDA5B3VuaTA0MEEHdW5pMDQwNQd1bmkwNDA0B3VuaTA0MkQHdW5pMDQwNgd1bmkwNDA3B3VuaTA0MDgHdW5pMDQwQgd1bmkwNDJFB3VuaTA0MkYHdW5pMDQwMgd1bmkwNDYyB3VuaTA0NkEHdW5pMDQ3Mgd1bmkwNDc0B3VuaTA0OTIHdW5pMDQ5NAd1bmkwNDk2B3VuaTA0OTgHdW5pMDQ5QQd1bmkwNDlDB3VuaTA0OUUHdW5pMDRBMAd1bmkwNEEyB3VuaTA0QTQHdW5pMDRBNgd1bmkwNTI0B3VuaTA0QTgHdW5pMDRBQQd1bmkwNEFDB3VuaTA0QUUHdW5pMDRCMAd1bmkwNEIyB3VuaTA0QjQHdW5pMDRCNgd1bmkwNEI4B3VuaTA0QkEHdW5pMDUyNgd1bmkwNEJDB3VuaTA0QkUHdW5pMDRDMAd1bmkwNEMxB3VuaTA0QzMHdW5pMDRDNwd1bmkwNEM5B3VuaTA0Q0IHdW5pMDRDRAd1bmkwNEQwB3VuaTA0RDIHdW5pMDRENAd1bmkwNEQ2B3VuaTA0RDgHdW5pMDREQQd1bmkwNERDB3VuaTA0REUHdW5pMDRFMAd1bmkwNEUyB3VuaTA0RTQHdW5pMDRFNgd1bmkwNEU4B3VuaTA0RUEHdW5pMDRFQwd1bmkwNEVFB3VuaTA0RjAHdW5pMDRGMgd1bmkwNEY0B3VuaTA0RjYHdW5pMDRGOAd1bmkwNEZBB3VuaTA0RkMHdW5pMDRGRQd1bmkwNTEwB3VuaTA1MTIHdW5pMDUxQQd1bmkwNTFDB3VuaTA0OEMHdW5pMDQ4RQd1bmkwNTI4B3VuaTA1MkUPdW5pMDQxNC5sb2NsQkdSD3VuaTA0MUIubG9jbEJHUg91bmkwNDI0LmxvY2xCR1IPdW5pMDQ5Mi5sb2NsQlNID3VuaTA0OTgubG9jbEJTSA91bmkwNEFBLmxvY2xCU0gPdW5pMDRBQS5sb2NsQ0hVDHVuaTA0MTAuc3MwMQx1bmkwNDE0LnNzMDEMdW5pMDQxNS5zczAxDHVuaTA0MDAuc3MwMQx1bmkwNDAxLnNzMDEMdW5pMDQxOC5zczAxDHVuaTA0MTkuc3MwMQx1bmkwNDhBLnNzMDEMdW5pMDQwRC5zczAxDHVuaTA0MUIuc3MwMQx1bmkwNDIwLnNzMDEMdW5pMDQyMi5zczAxDHVuaTA0MjMuc3MwMQx1bmkwNDBFLnNzMDEMdW5pMDQyNC5zczAxDHVuaTA0MkMuc3MwMQx1bmkwNDJBLnNzMDEMdW5pMDQyQi5zczAxDHVuaTA0MDkuc3MwMQx1bmkwNDBBLnNzMDEMdW5pMDQwOC5zczAxDHVuaTA0NjIuc3MwMQx1bmkwNEFDLnNzMDEMdW5pMDREMC5zczAxDHVuaTA0RDIuc3MwMQx1bmkwNEQ0LnNzMDEMdW5pMDRENi5zczAxDHVuaTA0RTIuc3MwMQx1bmkwNEU0LnNzMDEMdW5pMDRFRS5zczAxDHVuaTA0RjAuc3MwMQx1bmkwNEYyLnNzMDEMdW5pMDRGOC5zczAxDHVuaTA1MUEuc3MwMQx1bmkwNDhDLnNzMDEHdW5pMDQzMAd1bmkwNDMxB3VuaTA0MzIHdW5pMDQzMwd1bmkwNDUzB3VuaTA0OTEHdW5pMDQzNAd1bmkwNDM1B3VuaTA0NTAHdW5pMDQ1MQd1bmkwNDM2B3VuaTA0MzcHdW5pMDQzOAd1bmkwNDM5B3VuaTA0NUQHdW5pMDQ4Qgd1bmkwNDNBB3VuaTA0NUMHdW5pMDQzQgd1bmkwNDNDB3VuaTA0M0QHdW5pMDQzRQd1bmkwNDNGB3VuaTA0NDAHdW5pMDQ0MQd1bmkwNDQyB3VuaTA0NDMHdW5pMDQ1RQd1bmkwNDQ0B3VuaTA0NDUHdW5pMDQ0Nwd1bmkwNDQ2B3VuaTA0NDgHdW5pMDQ0OQd1bmkwNDVGB3VuaTA0NEMHdW5pMDQ0QQd1bmkwNDRCB3VuaTA0NTkHdW5pMDQ1QQd1bmkwNDU1B3VuaTA0NTQHdW5pMDQ0RAd1bmkwNDU2B3VuaTA0NTcHdW5pMDQ1OAd1bmkwNDVCB3VuaTA0NEUHdW5pMDQ0Rgd1bmkwNDUyB3VuaTA0NjMHdW5pMDQ2Qgd1bmkwNDczB3VuaTA0NzUHdW5pMDQ5Mwd1bmkwNDk1B3VuaTA0OTcHdW5pMDQ5OQd1bmkwNDlCB3VuaTA0OUQHdW5pMDQ5Rgd1bmkwNEExB3VuaTA0QTMHdW5pMDRBNQd1bmkwNTI1B3VuaTA0QTcHdW5pMDRBOQd1bmkwNEFCB3VuaTA0QUQHdW5pMDRBRgd1bmkwNEIxB3VuaTA0QjMHdW5pMDRCNQd1bmkwNEI3B3VuaTA0QjkHdW5pMDRCQgd1bmkwNTI3B3VuaTA0QkQHdW5pMDRCRgd1bmkwNENGB3VuaTA0QzIHdW5pMDRDNAd1bmkwNEM2B3VuaTA0QzgHdW5pMDRDQQd1bmkwNENDB3VuaTA0Q0UHdW5pMDREMQd1bmkwNEQzB3VuaTA0RDUHdW5pMDRENwd1bmkwNEQ5B3VuaTA0REIHdW5pMDRERAd1bmkwNERGB3VuaTA0RTEHdW5pMDRFMwd1bmkwNEU1B3VuaTA0RTcHdW5pMDRFOQd1bmkwNEVCB3VuaTA0RUQHdW5pMDRFRgd1bmkwNEYxB3VuaTA0RjMHdW5pMDRGNQd1bmkwNEY3B3VuaTA0RjkHdW5pMDRGQgd1bmkwNEZEB3VuaTA0RkYHdW5pMDUxMQd1bmkwNTEzB3VuaTA1MUIHdW5pMDUxRAd1bmkwNDhEB3VuaTA0OEYHdW5pMDUyOQd1bmkwNTJGD3VuaTA0MzIubG9jbEJHUg91bmkwNDMzLmxvY2xCR1IPdW5pMDQzNC5sb2NsQkdSD3VuaTA0MzYubG9jbEJHUg91bmkwNDM3LmxvY2xCR1IPdW5pMDQzOC5sb2NsQkdSD3VuaTA0MzkubG9jbEJHUg91bmkwNDVELmxvY2xCR1IPdW5pMDQzQS5sb2NsQkdSD3VuaTA0M0IubG9jbEJHUg91bmkwNDNELmxvY2xCR1IPdW5pMDQzRi5sb2NsQkdSD3VuaTA0NDIubG9jbEJHUg91bmkwNDQ3LmxvY2xCR1IPdW5pMDQ0Ni5sb2NsQkdSD3VuaTA0NDgubG9jbEJHUg91bmkwNDQ5LmxvY2xCR1IPdW5pMDQ0Qy5sb2NsQkdSD3VuaTA0NEEubG9jbEJHUg91bmkwNDRFLmxvY2xCR1IPdW5pMDQ5My5sb2NsQlNID3VuaTA0OTkubG9jbEJTSA91bmkwNEFCLmxvY2xDSFUPdW5pMDQ1My5sb2NsTUtED3VuaTA0MzEubG9jbFNSQg91bmkwNDMzLmxvY2xTUkIPdW5pMDQzNC5sb2NsU1JCD3VuaTA0M0YubG9jbFNSQg91bmkwNDQyLmxvY2xTUkIMdW5pMDQzMC5zczAxDHVuaTA0MzQuc3MwMQx1bmkwNDM1LnNzMDEMdW5pMDQ1MC5zczAxDHVuaTA0NTEuc3MwMQx1bmkwNDM4LnNzMDEMdW5pMDQzOS5zczAxDHVuaTA0OEIuc3MwMQx1bmkwNDVELnNzMDEMdW5pMDQ0MC5zczAxDHVuaTA0NDIuc3MwMQx1bmkwNDQzLnNzMDEMdW5pMDQ1RS5zczAxDHVuaTA0NEMuc3MwMQx1bmkwNDRBLnNzMDEMdW5pMDQ0Qi5zczAxDHVuaTA0NTkuc3MwMQx1bmkwNDVBLnNzMDEMdW5pMDQ2My5zczAxDHVuaTA0RDEuc3MwMQx1bmkwNEQzLnNzMDEMdW5pMDRENS5zczAxDHVuaTA0RDcuc3MwMQx1bmkwNEQ5LnNzMDEMdW5pMDREQi5zczAxDHVuaTA0RTMuc3MwMQx1bmkwNEU1LnNzMDEMdW5pMDRFRi5zczAxDHVuaTA0RjEuc3MwMQx1bmkwNEYzLnNzMDEMdW5pMDRGOS5zczAxDHVuaTA0OEQuc3MwMQd1bmkwMzk0B3VuaTAzQTkHdW5pMDNCQwd1bmkyMTJCB3VuaTIxMkEIemVyby5vc2YHb25lLm9zZgd0d28ub3NmCXRocmVlLm9zZghmb3VyLm9zZghmaXZlLm9zZgdzaXgub3NmCXNldmVuLm9zZgllaWdodC5vc2YIbmluZS5vc2YJemVyby5zaW5mCG9uZS5zaW5mCHR3by5zaW5mCnRocmVlLnNpbmYJZm91ci5zaW5mCWZpdmUuc2luZghzaXguc2luZgpzZXZlbi5zaW5mCmVpZ2h0LnNpbmYJbmluZS5zaW5mB3plcm8udGYGb25lLnRmBnR3by50Zgh0aHJlZS50Zgdmb3VyLnRmB2ZpdmUudGYGc2l4LnRmCHNldmVuLnRmCGVpZ2h0LnRmB25pbmUudGYJemVyby50b3NmCG9uZS50b3NmCHR3by50b3NmCnRocmVlLnRvc2YJZm91ci50b3NmCWZpdmUudG9zZghzaXgudG9zZgpzZXZlbi50b3NmCmVpZ2h0LnRvc2YJbmluZS50b3NmB3VuaTIwODAHdW5pMjA4MQd1bmkyMDgyB3VuaTIwODMHdW5pMjA4NAd1bmkyMDg1B3VuaTIwODYHdW5pMjA4Nwd1bmkyMDg4B3VuaTIwODkJemVyby5kbm9tCG9uZS5kbm9tCHR3by5kbm9tCnRocmVlLmRub20JZm91ci5kbm9tCWZpdmUuZG5vbQhzaXguZG5vbQpzZXZlbi5kbm9tCmVpZ2h0LmRub20JbmluZS5kbm9tCXplcm8ubnVtcghvbmUubnVtcgh0d28ubnVtcgp0aHJlZS5udW1yCWZvdXIubnVtcglmaXZlLm51bXIIc2l4Lm51bXIKc2V2ZW4ubnVtcgplaWdodC5udW1yCW5pbmUubnVtcgd1bmkyMDcwB3VuaTAwQjkHdW5pMDBCMgd1bmkwMEIzB3VuaTIwNzQHdW5pMjA3NQd1bmkyMDc2B3VuaTIwNzcHdW5pMjA3OAd1bmkyMDc5B3VuaTIxNTMHdW5pMjE1NAlvbmVlaWdodGgMdGhyZWVlaWdodGhzC2ZpdmVlaWdodGhzDHNldmVuZWlnaHRocw5iYWNrc2xhc2guY2FzZRNwZXJpb2RjZW50ZXJlZC5jYXNlC2J1bGxldC5jYXNlG3BlcmlvZGNlbnRlcmVkLmxvY2xDQVQuY2FzZQpzbGFzaC5jYXNlFnBlcmlvZGNlbnRlcmVkLmxvY2xDQVQOYnJhY2VsZWZ0LmNhc2UPYnJhY2VyaWdodC5jYXNlEGJyYWNrZXRsZWZ0LmNhc2URYnJhY2tldHJpZ2h0LmNhc2UOcGFyZW5sZWZ0LmNhc2UPcGFyZW5yaWdodC5jYXNlCmZpZ3VyZWRhc2gHdW5pMjAxNQd1bmkyMDEwB3VuaTAwQUQLZW1kYXNoLmNhc2ULZW5kYXNoLmNhc2ULaHlwaGVuLmNhc2USZ3VpbGxlbW90bGVmdC5jYXNlE2d1aWxsZW1vdHJpZ2h0LmNhc2USZ3VpbHNpbmdsbGVmdC5jYXNlE2d1aWxzaW5nbHJpZ2h0LmNhc2UJZXhjbGFtLnNjDWV4Y2xhbWRvd24uc2MQZ3VpbGxlbW90bGVmdC5zYxFndWlsbGVtb3RyaWdodC5zYxBndWlsc2luZ2xsZWZ0LnNjEWd1aWxzaW5nbHJpZ2h0LnNjCXBlcmlvZC5zYwtxdWVzdGlvbi5zYw9xdWVzdGlvbmRvd24uc2MLcXVvdGVkYmwuc2MPcXVvdGVkYmxiYXNlLnNjD3F1b3RlZGJsbGVmdC5zYxBxdW90ZWRibHJpZ2h0LnNjDHF1b3RlbGVmdC5zYw1xdW90ZXJpZ2h0LnNjEXF1b3Rlc2luZ2xiYXNlLnNjDnF1b3Rlc2luZ2xlLnNjB3VuaTI3RTgHdW5pMjdFOQd1bmkyMDA3B3VuaTIwMEEHdW5pMjAwOAd1bmkwMEEwB3VuaTIwMDkHdW5pMjAwQgd1bmkyMEI1DWNvbG9ubW9uZXRhcnkEZG9uZwRFdXJvB3VuaTIwQjIHdW5pMjBCNAd1bmkyMEFEBGxpcmEHdW5pMjBCQQd1bmkyMEJDB3VuaTIwQTYGcGVzZXRhB3VuaTIwQjEHdW5pMjBCRAd1bmkyMEI5B3VuaTIwQjgHdW5pMjBBRQd1bmkyMEE5B3VuaTIyMTkHdW5pMjA1Mgd1bmkyMjE1CGVtcHR5c2V0B3VuaTIxMjYHdW5pMjIwNgd1bmkwMEI1B2Fycm93dXAHdW5pMjE5NwphcnJvd3JpZ2h0B3VuaTIxOTgJYXJyb3dkb3duB3VuaTIxOTkJYXJyb3dsZWZ0B3VuaTIxOTYJYXJyb3dib3RoCWFycm93dXBkbgxhcnJvd3VwLmNhc2UPYXJyb3dyaWdodC5jYXNlDmFycm93ZG93bi5jYXNlDmFycm93bGVmdC5jYXNlB3VuaTI1QzYHdW5pMjVDNwlmaWxsZWRib3gHdW5pMjVBMQd0cmlhZ3VwB3VuaTI1QjYHdHJpYWdkbgd1bmkyNUMwB3VuaTI1QjMHdW5pMjVCNwd1bmkyNUJEB3VuaTI1QzEHdW5pMjExMwllc3RpbWF0ZWQHdW5pMjExNgZtaW51dGUGc2Vjb25kB2F0LmNhc2UMdW5pMjExNi5zczAxDGFtcGVyc2FuZC5zYwd1bmkwMzA4C3VuaTAzMDgwMzAwC3VuaTAzMDgwMzAxC3VuaTAzMDgwMzA0B3VuaTAzMDcLdW5pMDMwNzAzMDQJZ3JhdmVjb21iC3VuaTAzMDAwMzA0CWFjdXRlY29tYgt1bmkwMzAxMDMwNwt1bmkwMzAxMDMwNAd1bmkwMzBCDWNhcm9uY29tYi5hbHQHdW5pMDMwMgd1bmkwMzBDC3VuaTAzMEMwMzA3B3VuaTAzMDYHdW5pMDMwQQt1bmkwMzBBMDMwMQl0aWxkZWNvbWILdW5pMDMwMzAzMDgTdGlsZGVjb21iX2FjdXRlY29tYgt1bmkwMzAzMDMwNAd1bmkwMzA0C3VuaTAzMDQwMzA4C3VuaTAzMDQwMzAwC3VuaTAzMDQwMzAxDWhvb2thYm92ZWNvbWIHdW5pMDMwRgd1bmkwMzExB3VuaTAzMTIHdW5pMDMxQgxkb3RiZWxvd2NvbWIHdW5pMDMyNAd1bmkwMzI2B3VuaTAzMjcHdW5pMDMyOAd1bmkwMzJFB3VuaTAzMzEHdW5pMDMzNQd1bmkwMzM2B3VuaTAzMzcHdW5pMDMzOAx1bmkwMzA4LmNhc2UQdW5pMDMwODAzMDAuY2FzZRB1bmkwMzA4MDMwMS5jYXNlEHVuaTAzMDgwMzA0LmNhc2UMdW5pMDMwNy5jYXNlEHVuaTAzMDcwMzA0LmNhc2UOZ3JhdmVjb21iLmNhc2UQdW5pMDMwMDAzMDQuY2FzZQ5hY3V0ZWNvbWIuY2FzZRB1bmkwMzAxMDMwNy5jYXNlEHVuaTAzMDEwMzA0LmNhc2UMdW5pMDMwQi5jYXNlDHVuaTAzMDIuY2FzZQx1bmkwMzBDLmNhc2UQdW5pMDMwQzAzMDcuY2FzZQx1bmkwMzA2LmNhc2UOdGlsZGVjb21iLmNhc2UQdW5pMDMwMzAzMDguY2FzZRh0aWxkZWNvbWJfYWN1dGVjb21iLmNhc2UQdW5pMDMwMzAzMDQuY2FzZQx1bmkwMzA0LmNhc2UQdW5pMDMwNDAzMDguY2FzZRB1bmkwMzA0MDMwMC5jYXNlEHVuaTAzMDQwMzAxLmNhc2USaG9va2Fib3ZlY29tYi5jYXNlDHVuaTAzMEYuY2FzZQx1bmkwMzExLmNhc2UMdW5pMDMzNS5jYXNlDHVuaTAzMzcuY2FzZQx1bmkwMzM4LmNhc2UTdW5pMDMwNC5uYXJyb3cuY2FzZQl1bmkwMzA3LmkJdW5pMDMyOC5pEHVuaTAzMDgubG9jbFZJRVQQdW5pMDMwNy5sb2NsVklFVBJncmF2ZWNvbWIubG9jbFZJRVQSYWN1dGVjb21iLmxvY2xWSUVUEHVuaTAzMDIubG9jbFZJRVQQdW5pMDMwQy5sb2NsVklFVBB1bmkwMzA2LmxvY2xWSUVUEnRpbGRlY29tYi5sb2NsVklFVBB1bmkwMzA0LmxvY2xWSUVUFmhvb2thYm92ZWNvbWIubG9jbFZJRVQOdW5pMDMwOC5uYXJyb3cOdW5pMDMwMi5uYXJyb3cOdW5pMDMwNi5uYXJyb3cQdGlsZGVjb21iLm5hcnJvdw51bmkwMzA0Lm5hcnJvdw51bmkwMzExLm5hcnJvdxNjYXJvbmNvbWIuYWx0LnNob3J0CXVuaTAzMzUudAd1bmkwMkJDB3VuaTAyQkIHdW5pMDJCQQd1bmkwMkM5B3VuaTAyQ0IHdW5pMDJCOQd1bmkwMkJGB3VuaTAyQkUHdW5pMDJDQQd1bmkwMkNDB3VuaTAyQzgKdW5pMDMzNS5zYwp1bmkwMzM2LnNjCnVuaTAzMzguc2MLYnJldmVjb21iY3kQYnJldmVjb21iY3kuY2FzZQtkZXNjZW5kZXJjeRBkZXNjZW5kZXJjeS5jYXNlFmRlc2NlbmRlcmN5LmNhc2Uuc2hvcnQRZGVzY2VuZGVyY3kuc2hvcnQLdW5pMDMwNjAzMDELdW5pMDMwNjAzMDALdW5pMDMwNjAzMDkLdW5pMDMwNjAzMDMLdW5pMDMwMjAzMDELdW5pMDMwMjAzMDALdW5pMDMwMjAzMDkLdW5pMDMwMjAzMDMQdW5pMDMwNjAzMDEuY2FzZRB1bmkwMzA2MDMwMC5jYXNlEHVuaTAzMDYwMzA5LmNhc2UQdW5pMDMwNjAzMDMuY2FzZRB1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AAMAAAAAAAMAAwADAAMACAADAAAAAAAAAAAAGwAAAAD/9gAAAAAACAAAAAAAAAAA/+wAAAAAAAAAAAAAAAAAAAAAAAAAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/+QAAAAAAAAAAAAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/2AAAAAAAHAAAAAP/2AAD/9AAAAAAAAAAAAAAAAAAAAAAAAAAA/8cAAAAAAAAAAAAAAAAAAAAHAAAABwAAAAAAAAAAAAD//QAAAAAAAAAAAAP/9gAIAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkAAP/2AAAAAAAKAAoAAAAA//YAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/7QAAAAAAAwAAAAoAAAAKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//bAAoAAAAAAAMAAwADAAMAAwADAAAAAAAAAAAAEwAAAAD/9gAAAAAAAAAAAAD/9gAA/+wAAAAAAAAAAAAAAAAAAAAAAAAAAP+/AAAAAAAAAAAAAAAAAAAAAAAAAAcAAP/2//YAAAAN/+7/qQAAAAD/2//5/9j/3gAA//kAAAADAAAAAwAAAAMAAAAK//YACAAA/+z/9v/s//P//QAAAAcAAAADAAD/6QAAAAf/9gAHAAAAAAAAAAAAAAAA/9YAAAAAAAAAAAAAAAAAAAAAAAcAAP/2AAAAAAAAAAD/8QAAAAAAAAAA//H/2AAA/+b/9AAAAAAAAAAAAAAAAAAAAAD//QAAAAD/5wAAAAD/4gAAAAAAAAAAAAAAAAAAAAAAAP/5AAcAAAAAAAAAAAAAAAAAJgAIAAgAAAAAAAAAAAAAAAAAAP/s/+8AAAAAAAAAAAAKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIQAAAAAAHAAAAAAAAwAAAAAAAAAAAA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAsAAAAAAAAAAAAAAADAAAAAAAA/+//9wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAmAAAAAAAAAAAAAAAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/58AAAAAAAD/wQADAAMAAwAA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BiUADAYmBicANQYoBigAMQYpBioAEAYrBisAQQYsBiwAQgYuBi4AEAYvBi8AEQYwBjAAEgYxBjIAFAYzBjMAMQY0BjQAKwY1BjUALQY2BjYADAY3BjgAUQY6BjoAKwY9Bj0ATQY/Bj8ATQZDBkMATgZFBkUATgZHBkcAUwZMBk4ANQZRBlEAUQZSBlIANQZTBlMARQZUBlQANQZVBlUARQZWBlYAEAZXBlcAEwZYBlgAOwZZBlkAEwZaBloAOwZbBlsAEAZcBlwAUQZdBl0AUAZeBl4AUQZfBl8AUAZiBmIANQZkBmQANQZmBmYAEAZqBmoAEAZvBm8AEAZ5BnkAJQZ6BnoAOAZ7BnsAJQZ8BnwAMgZ9Bn0AJgZ+Bn4AOAZ/Bn8AMgaABoAAKAaBBoEAMgaCBoIAJQaEBoQAMgaFBoUANgaGBoYAMgaIBogAMgaKBosAMgaMBowAFQaNBo0ANgaQBpAAMgaRBpEAGwaUBpQAKwaVBpYANQaYBpgANQahBqIANQanBqcAAQaqBqoANQarBqsAUgatBq4ADwbKBsoAJQbLBssAMAbMBswAOgbNBs0AFgbOBs8AJQbQBtAAPQbRBtEAHgbXBtcAJQbaBtsAFAbcBtwAJQc+Bz4AEwACAAgACgAaBJgFCjDQQfBOrlTMbU6FfI8WAAEAsgAEAAAAVAQKAV4BaAGGAYYBhgGGAYYBhgGGAbQBtAG0AbQBtAG0Af4B/gH+Af4B/gH+Af4B/gH+Af4ENAIoAigCKAIoAigCKAIoA44ClgJCA6oCjAJQAmICcAJ+AowClgKgAs4C3AOOA5wDqgPcBF4EXgReBFgEWAPuBE4D9AROA/4D/gQEBFgEWARYBFgEWARwBHAEWARYBAoENAQ0BE4EWARYBFgEWAReBF4EcAABAFQASQCUAKkAwADBAMIAwwDEAMUAxgDfAOAA4QDiAOMA5ADmAOcA6ADpAOoA6wDsAO0A7gDvASsBVwFYAVkBWgFbAVwBXQGgAbABygHPAd4B4gHjAeoB7QHvAfgB/gIxAkoCTAJkArQDhQRkBGUGJAYmBicGMAY0BjUGOgY8Bj4GQAZMBk0GTgZTBlUGVwZZBmMGZQaBBoUGjQaUBpUGlgaYBqEG2AbdBz4AAgYlAAYGNgAGAAcGNAApBjUAKAY6ACkGPQAIBj8ACAZHAAMGlAApAAsB4QAZ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//YAAAAAAAAAAAAAAAAAAAAAAAD/7wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAAAAAAoAAAAA//YAAAAAAAAAAAAAAAAAAAAA//YAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/s//cAAAAAAAAAAAAAAAD/+QAAAAAAAAAAAAD/9QAA//cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//kAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//0AAP/2AAAAAAAAAAAAAAAA//sAAAAA//0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//kAAAAAAAAAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/j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ACMCmQKaAE0CmwKzACMCtAK9AG8CvgK+ACMCvwLGAG8CxwLUADoC1QLZAEMC2gLaAAYC2wLcADMC3gLeADMC3wL6AE4C+wL7AFUC/AMCACQDAwMgAFUDIQMhACQDJAMkAFUDJQMsACQDLQNEAFUDRQNGAB8DRwNfAFUDYAOCACQDgwOEAFUDhQOFACQDhgONAFUDjgOQAFcDkgOZAFcDmwOiADQDowO6ADsDuwPAAD4DwQPBAEADwgPLAEEDzAPQAFoD0QPqAE8D7QPtAFUD7gQEABQEBQQFACQEBgQGAFIEBwQOACQEDwQRAFsEEgQSAFUEEwQbAFsEHAQcAFUEHQQfAFsEIAQhACAEIgQuAFUELwQvACQEMAQ3ADQEOARUADsEVQReAEIEXwRjAFoEZARlAA0EZgRmAEYEZwRrAGsEbARsAEcEbQRvAGsEcARwAAoEcQRxAEsEcgR3AGsEeAR4AEcEeQR6AGsEewR7AAUEfAR9AGsEfgR+AAUEfwR/AAYEgASBAAoEggSCAAUEgwSDAAoEhASEAAEEhQSJAGsEigSKAAYEiwSLAGsEjASMAEcEjQSNAGsEjgSOAEwEjwSPAAUEkASQAEsEkQSSAGsEkwSTAAMElASUAAYElQSVAGsElgSWAAoElwSYAAYEmQSZAAoEmgSaAAUEmwSbAAkEnQSdAGsEngSeAAoEnwSfAEsEoASiAGsEowSjAAYEpASnAGsEqASpAAUEqgSqAAYEqwSsAAsErQStAAoErgSuAAYErwSwAAEEsQSyAGsEswS0AAIEtQS1AGsEtgS2AAoEtwS5AGsEugS6AAEEuwS7AGsEvAS+AEYEvwS/AGsEwATBAAUEwgTCAAoEwwTEAEsExQTGAGsExwTJAAUEygTKAEsEywTNAAoEzgTOAAEEzwTRAGsE0gTTAAoE1ATUAEoE1QTVAEcE1gTWAAUE1wTXAAkE2ATaAGsE2wTcAEcE3QTdAEYE3gTeAAUE3wTfAGsE4QTiAAUE4wTjAFwE5ATkAF4E5QTnAEoE6ATrAGsE7ATsAEkE7QTtAFwE7gTuAAcE7wTwAAwE8QTxAAUE8gTyAAgE8wTzAAYE9AT0AAgE9QT1AEcE9gT2AGsE9wT3AAQE+QT5AAcE+gT7AFwE/AT8AEYE/QT9AEoE/gT/AGsFAAUCAAwFBAUEAAUFBQUFAAgFBgUGAE0FBwUHAAUFCAULAGUFDAUMAEgFDQUPACMFEAUQAD8FEQURAFEFEgUXAGUFGAUYAEgFGQUaAGUFGwUbACMFHAUdAGUFHgUeACMFHwUfADUFIAUhAD0FIgUiACMFIwUjAD8FJAUkADoFJQUpAGUFKgUqADUFKwUrAGUFLAUsAEgFLQUtAGUFLgUuAC4FLwUvACMFMAUwAFEFMQUyAGUFMwUzAGQFNAU0AG0FNQU1AGUFNgU2AD8FNwU3AG8FOAU4ADUFOQU5AD8FOgU6ACMFOwU7AD0FPAU8ABkFPQU9AGUFPgU+AD8FPwU/AFEFQAVBAGUFQgVCAG8FQwVDADUFRAVHAGUFSAVJACMFSgVKADUFSwVMAD0FTQVNAD8FTgVOADUFTwVQADoFUQVSAG8FUwVUABEFVQVVAG8FVgVWAD8FVwVXAGUFWAVYAEgFWQVaAGUFWwVbADoFXAVcAGUFXQVfAE0FYAViACMFYwVjAD8FZAVlAFEFZgVnAGUFaAVqACMFawVrAFEFbAVuAD0FbwVvADoFcAVyAGUFcwV0AD8FdQV1AFYFdgV2AEgFdwV3ACMFeAV4AD0FeQV5AC8FegV6AGUFewV7AGQFfAV8AEgFfQV9ACMFfgV+AC4FfwV/ACMFgAWAAD8FgQWBAFEFggWEADoFhQWFAG8FhgWGAEgFhwWJAGUFigWOADoFjwWPADUFkAWQAG8FkQWRAGUFkgWSAFEFkwWTACMFlAWUAGUFlQWVAA8FlgWWAGUFlwWXACMFmAWZADoFmgWeACMFnwWiADoFowWjAG4FpQWnADoFqAWoABwFqQWpADoFqgWqAEgFqwWrAGUFrQWuACMFrwWvAE0FsAWxACMFswW4ADoFuQW5AC8FugW6AEYFvgW+AEYFvwW/AGsFwAXAAEQFwQXBACUFwgXCAFkFwwXDADYFxAXEABcFxQXFAFMFxgXGAEQFxwXHADAFyAXIABUFyQXJACEFygXKAEUFywXLACYFzAXMADkFzQXNADcFzgXOABgFzwXPAFQF0AXQAEQF0QXRADEF0gXSABUF0wXTACIGJAYkAA0GJQYlAA4GJgYnAB0GKAYoABIGKQYqACgGKwYrAGAGLAYsABYGLgYuACgGLwYvACkGMAYwACoGMQYyAC0GMwYzABIGNAY0ADIGNQY1ADwGNgY2AA4GNwY4AB4GOgY6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BSMAEwUkBSQAQAUlBSkAPwUrBSsAPwUtBS0APwUuBS4AGwUvBS8AGQUxBTIAPwUzBTMAPQU1BTUAPwU2BTYAEwU3BTcAPgU5BTkAEwU6BToAGQU7BTsAEQU9BT0APwU+BT4AEwVABUEAPwVCBUIAPgVEBUcAPwVIBUkAGQVLBUwAEQVNBU0AEwVPBVAAQAVRBVIAPgVVBVUAPgVWBVYAEwVXBVcAPwVZBVoAPwVbBVsAQAVcBVwAPwVdBV8ACgVgBWIAGQVjBWMAEwVmBWcAPwVoBWoAGQVsBW4AEQVvBW8AQAVwBXIAPwVzBXQAEwV3BXcAGQV4BXgAEQV6BXoAPwV7BXsAPQV9BX0AGQV+BX4AGwV/BX8AGQWABYAAEwWCBYQAQAWFBYUAPgWHBYkAPwWKBY4AQAWQBZAAPgWRBZEAPwWTBZMAGQWUBZQAPwWWBZYAPwWXBZcAGQWYBZkAQAWaBZ4AGQWfBaIAQAWlBacAQAWpBakAQAWrBasAPwWtBa4AGQWvBa8ACgWwBbEAGQWzBbgAQAW6BboAAQW+Bb4AAQXBBcEAKwXCBcIAOQXDBcMAOAXEBcQAJwXHBccANQXKBcoAPAXLBcsALAXMBcwAOgXOBc4AKAXPBc8AJgXRBdEANgYkBiQADAYlBiUAHwYmBicAKgYoBigAIgYpBioALwYrBisAIwYuBi4ALwYvBi8AMAYwBjAAMQYxBjIANAYzBjMAIgY0BjQANwY1BjUAOwY2BjYAHwY6BjoANwY9Bj0AIAY/Bj8AIAZBBkEALQZDBkMAIQZFBkUAIQZHBkcALgZMBk4AKgZSBlIAKgZUBlQAKgZWBlYALwZYBlgAMwZaBloAMwZbBlsALwZgBmAAJAZhBmEAJQZiBmIAKgZjBmMAKQZkBmQAKgZlBmUAKQZmBmYALwZoBmgAMgZqBmoALwZvBm8ALwZ5BnkAFQZ6BnoAGQZ7BnsAFQZ9Bn0AFgZ+Bn4AGQaCBoIAFQaUBpQANwaVBpYAKgaYBpgAKgahBqIAKganBqcAAQaqBqoAKgarBqsAPwbKBsoAFQbOBs8AFQbXBtcAFQbaBtsANAbcBtwAFQACAJ4ABAAAAKwAsAABAEcAAP+j//n/9AAKAB4AKAAh//YAFAAK/6j/9v/2ABQAAwAHAB4ABwAUABH/7P/5//P/2QARAA0AEf/2//0AUAAg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AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9AAA//D/8AAAAAD/7f/3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/8f/q//f/9AAA/+0AAP/s//P/9//w//cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKACUABwAA//b/9gAA/+n/+f/bAAAAAAAAAAAAHgAAAAAAFAAAAAcAAP/9//kAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwAAAAAACP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABf/9AAAABQAFAAAAAoAAAAUAAoABwAAAAAADf/2AAAAFAAAAAAAAwAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAACP/2AAAACAAAAAAAAwAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKAAoAFAAA/+z/7AAA/+L/9v/YAAoAAABkAEQAFAAKAAAACAAAAAD/9gAA//YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAEQAAAAAACAADAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/zAAD/6QAA//T/7wAA/9//1v/WAAAAEf/0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA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ABIFhQWFAAQFhwWJAAgFkAWQAAkFkgWSABIFlAWUAAsFlQWVAAkFnAWeAAEFowWjAAkFrwWwAAEFsQWxAAkGiQaJAAwAAgFrAAQAHwBMACAAIABNACEAJwAwACgARgBNAEcASABIAEkASQBNAEoAUQAwAFIAZwBNAGoAgwBNAIQApgAwAKcAqABNAKkAqQAwAKoAsQBNALIAtABOALYAvQBOAL8AvwAwAMAAxgACAMcA3gAxAN8A5AAyAOUA5QA2AOYA7wAzAPUA9QBNAPYBDwABARABEQBMARIBEwBNASsBKwABASwBMwAwATUBNQBNAUUBRgBJAUcBSABNAUoBVABNAVUBVgAwAVcBXQBKAV4BegAxAYoBpQA3AaYBpgATAacBzAAWAc4BzgAPAdAB1wAWAdgB3QATAd4B7gBCAe8B8QBBAfIB9AATAfUB9QBCAfYB/gATAf8CCwBCAgwCLgAWAi8CLwBCAjACMAATAjECMQAWAjICOQBCAjoCPABFAj4CRQBFAkYCRgATAkgCTwAjAlACZwBGAmgCbQApAm4CbgAqAm8CeAApAnkCfQArAn8CmAAWApkCmgA3ApsCswAWArQCvQATAr4CvgAWAr8CxgATAscC1ABGAtUC2QArAtoC2gACAtsC3AAjAt4C3gAjBGQEZQAEBGYEZgBMBGcEawBNBGwEbAA1BG0EbwBNBHAEcAA2BHEEcQBIBHIEdwBNBHgEeAA1BHkEegBNBHsEewAwBHwEfQBNBH4EfgAwBH8EfwACBIAEgQA2BIIEggAwBIMEgwA2BIQEhAAuBIUEiQBNBIoEigACBIsEiwBNBIwEjAA1BI0EjQBNBI4EjgBOBI8EjwAwBJAEkABIBJEEkgBNBJQElAACBJUElQBNBJYElgA2BJcEmAACBJkEmQA2BJoEmgAwBJsEmwAyBJ0EnQBNBJ4EngA2BJ8EnwBIBKAEogBNBKMEowACBKQEpwBNBKgEqQAwBKoEqgACBKsErAAzBK0ErQA2BK4ErgACBK8EsAAuBLEEsgBNBLMEtAAvBLUEtQBNBLYEtgA2BLcEuQBNBLoEugAuBLsEuwBNBLwEvgBMBL8EvwBNBMAEwQAwBMIEwgA2BMMExABIBMUExgBNBMcEyQAwBMoEygBIBMsEzQA2BM4EzgAuBM8E0QBNBNIE0wA2BNUE1QA1BNYE1gAwBNcE1wAyBNgE2gBNBNsE3AA1BN0E3QBMBN4E3gAwBN8E3wBNBOEE4gAwBOME4wABBOQE5ABHBOgE6wBNBO0E7QABBO4E7gBKBPEE8QAwBPIE8gAxBPME8wACBPQE9AAxBPUE9QA1BPYE9gBNBPcE9wBJBPkE+QBKBPoE+wABBPwE/ABMBP4E/wBNBQQFBAAwBQUFBQAxBQYFBgA3BQcFBwAwBQgFCwBCBQwFDAAOBQ0FDwAWBRAFEAAqBREFEQAPBRIFFwBCBRgFGAAOBRkFGgBCBRsFGwAWBRwFHQBCBR4FHgAWBR8FHwAkBSAFIQApBSIFIgAWBSMFIwAqBSQFJABGBSUFKQBCBSoFKgAkBSsFKwBCBSwFLAAOBS0FLQBCBS4FLgBFBS8FLwAWBTAFMAAPBTEFMgBCBTMFMwBBBTUFNQBCBTYFNgAqBTcFNwATBTgFOAAkBTkFOQAqBToFOgAWBTsFOwApBT0FPQBCBT4FPgAqBT8FPwAPBUAFQQBCBUIFQgATBUMFQwAkBUQFRwBCBUgFSQAWBUoFSgAkBUsFTAApBU0FTQAqBU4FTgAkBU8FUABGBVEFUgATBVMFVAAJBVUFVQATBVYFVgAqBVcFVwBCBVgFWAAOBVkFWgBCBVsFWwBGBVwFXABCBV0FXwA3BWAFYgAWBWMFYwAqBWQFZQAPBWYFZwBCBWgFagAWBWsFawAPBWwFbgApBW8FbwBGBXAFcgBCBXMFdAAqBXUFdQBEBXYFdgAOBXcFdwAWBXgFeAApBXkFeQAgBXoFegBCBXsFewBBBXwFfAAOBX0FfQAWBX4FfgBFBX8FfwAWBYAFgAAqBYEFgQAPBYIFhABGBYUFhQATBYYFhgAOBYcFiQBCBYoFjgBGBY8FjwAkBZAFkAATBZEFkQBCBZIFkgAPBZMFkwAWBZQFlABCBZUFlQAGBZYFlgBCBZcFlwAWBZgFmQBGBZoFngAWBZ8FogBGBaUFpwBGBagFqABLBakFqQBGBaoFqgAOBasFqwBCBa0FrgAWBa8FrwA3BbAFsQAWBbMFuABGBbkFuQAgBboFugBMBb4FvgBMBb8FvwBNBcAFwAAsBcEFwQAXBcIFwgAoBcMFwwAlBcQFxAAQBcUFxQA/BcYFxgAsBccFxwAhBcgFyAANBckFyQAUBcoFygAtBcsFywAYBcwFzAA7Bc0FzQAm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D4oPig+KCrAPig+KD4oPig+KD4oPig+KD4oKqg+KD4oPig+KD4oPig+KD4oPig+KD4oPig+KD4oPigugD4oLjguUCg4LoA+KD4oPig+KChQPigoaD4oLuA+KD4oKIA+KD4oPig+KD4oPigomD4oPigrCCiwKzg+KD4oKMgo4Cj4Pig+KD4oPigpED4oPig+KD4oPigv0D4oLUgtYC6wLZAtqD4oPigsoD4oPig+KD4oK1A+KD4oOOg+KC74Pig+KD4oPigpKD4oPig+KD4oKUA+KD4oKVg+KClwPig+KCtoPigrgCuYPigraD4oKYgrmD4oPig+KD4oPig+KD4oPig+KD4oPigvED4oLyg+KD4oOOg+KCmgKbg+KCnQPigp6CoAPigqGD4oKjAqSD4oPig+KD4oPig+KCpgPigqeCqQPig+KD4oKqg+KD4oPig+KCrAPig+KD4oPig+KD4oPig+KD4oPig+KD4oKtg+KCrwPig+KCrYPigq8D4oPigrCCsgKzg+KD4oPig+KCtQPig+KCtoPigrgCuYPigrsD4oK8g+KD4oK/gsECvgPig+KCv4LBAsKD4oPigsQD4oLFg+KD4oLHAsiCygPig+KD4oPigsuD4oPig+KD4oLNA+KD4oPig+KCzoPig+KDjoPigtAD4oPig+KD4oLRg+KD4oPig+KC0wPig+KC1ILWAteC2QLagtSC1gLrAtkC2oLUgtYC14LZAtqD4oPigtwD4oPig+KD4oLdg+KD4oPig+KC3wPig+KD4oPiguCD4oPig+KD4oLiA+KD4oPig+KC7gPig+KC44LlAuaC6APig+KD4oLpg+KD4oPig+KC6wPig+KD4oPig+KC7IPig+KD4oPig+KD4oPig+KC7gPig+KDjoPigu+D4oPigvED4oLyg+KD4oLxA+KC8oPig+KDXoMEgwMD4oPigweDCQMKg+KD4oMHgwkC9APig+KDB4MJAvWD4oPigw2DDwMDA+KDEgMNgw8DAwPigxIDDYMPAwMD4oMSAw2DDwL3A+KDEgPig+KD4oPig+KC/oPigwADAYPigxaD4oL4g+KD4oMWg+KC+IPig+KD4oPigvoD4oPig+KD4oL7g+KD4oPig+KD4oL9A+KC/oPigwADAYPig16DBIMDA+KD4oNegwSDEIPig+KDvQPigwYD4oPigweDCQMKg+KD4oMNgw8DDAPigxIDDYMPAxCD4oMSAxaD4oMTg+KD4oMWg+KDFQPig+KDFoPigxgD4oPig+KD4oMZg+KD4oPig+KD4oMbA+KDYwNkg2GD4oPigxyD4oMeA+KD4oPig+KDigPig+KD4oPig6UD4oPig2qDbANtg+KD4oNqg2wDH4Pig+KDaoNsAyED4oPig+KD4oNdA+KD4oOfA+KDoIPig+KD4oPigyKD4oPig+KD4oMig+KD4oPig+KDJAPig+KD4oPigyWD4oPig+KD4oPNg+KD4oPig+KDJwPig+KD4oPig+KD4oPig16D4oNgA+KD4oOWA+KDl4OZA+KDdoN4A28DewN8g+KD4oPig+KD4oMog+KDKgPig+KDogPig6OD4oPig0gD4oNJg0sD4oOFg+KDK4Pig+KDhYPigyuD4oPig+KD4oPig+KD4oPig+KDTgPig+KD4oPig+KD4oPig+KD4oPig+KD4oPig+KD4oONA+KD4oPigy0DjQPig+KD4oPigy6D4oMwA+KDMYPig+KDMwPig+KD4oPig+KD4oOgg+KD4oNXAzSDNgPig+KDpoOoAzeD4oPig+KD4oM5A+KD4oM6g+KDPAM9g6CD4oPig34D4oPig+KD4oM/A+KD4oPig+KDXQPig+KDnwPig6CD4oPig+KD4oPNg+KD4oNAg+KDQgPig+KDQ4Pig0UD4oPig5YD4oOXg5kD4oOWA+KDRoOZA+KD4oPig+KD4oPig6ID4oOjg+KD4oNIA+KDSYNLA+KD4oPig+KDTIPig+KD4oPig0yD4oPig+KD4oPig+KD4oPig04D4oPig+KD4oNPg+KD4oOag+KDWINRA1KDVAPig1WD4oPig1QD4oNVg+KD4oNXA+KDWINaA1uD4oPig10D4oPig+KD4oPig+KD4oOWA+KDl4OZA+KDXoPig2AD4oPig2MDZINhg+KD4oNjA2SDZgPig+KDZ4Pig2kD4oPig2qDbANtg+KD4oN2g3CDbwPig+KDdoNwg3mD4oPig+KD4oNyA+KD4oOfA+KDgQPig+KD4oPig3OD4oPig+KD4oN1A+KD4oN2g3gDeYN7A3yD4oPig34D4oPig+KD4oN/g+KD4oPig+KDgQPig+KDhYPig4KD4oPig4WD4oOEA+KD4oOFg+KDhwPig+KD4oPig4iD4oPig+KD4oOKA+KD4oPig+KDi4ONA+KD4oPig+KD4oPig46D4oOQA+KD4oORg+KDkwPig+KD4oPig+KD4oPig+KD4oOxA+KD4oPVA9aDtYPig9mD1QPWg7WD4oPZg9UD1oO4g+KD2YPig+KDlIPig+KDlgPig5eDmQPig5qD4oOcA+KD4oO9A+KD4oPig+KD4oPig+KD4oPig9UD1oO1g+KD2YPig+KDnYPig+KD4oPig52D4oPig58D4oOgg+KD4oOiA+KDo4Pig+KD4oPig6UD4oPig6aDqAOpg+KD4oPig+KDtYPig+KDqwOsg9sD4oOuA+KD4oOvg+KD4oPDA8SDwYPig+KD4oPig7ED4oPig8kDyoPMA+KD4oPJA8qDsoPig+KDyQPKg7QD4oPig9UD1oO1g+KD2YPVA9aDtYPig9mD1QPWg7cD4oPZg9UD1oO4g+KD2YO6A+KDu4Pig+KDvQPig+KD4oPig94D4oO+g+KD4oPeA+KDvoPig+KD4oPig8AD4oPig8MDxIPBg+KD4oPDA8SDxgPig+KD4oPig8eD4oPig8kDyoPMA+KD4oPPA9CDzYPig+KDzwPQg9ID4oPig9UD1oPTg+KD2YPVA9aD2APig9mD3gPig9sD4oPig94D4oPcg+KD4oPeA+KD34Pig+KD4oPig+ED4oPigABAX0AAAABAUoDUwABAWUDUwABAWUDOQABAZoDUwABAZoCvAABAWcDUwABAfICvAABAogCSgABAUoAAAABAYMAAAABAUACvAABANAAAAABAJsAAAABAM0AAAABAJsDOQABAQoCvAABAWcCvAABAX0CvAABAfAAAAABAfACvQABA0QCvAABAS8CvAABAS8BUwABAU4AAAABAU4CvAABAUsA+QABAUQAAAABAUQCvAABAUEA+QABAS4AAAABAS4CvAABAS4BUwABAVUCvAABAVQCvAABAlUAAAABAk8CvwABAJ8AAAABANEAAAABAJ8CvAABAgQCvAABAZkAAAABAZkCvAABAZkCKQABAeEAAAABAeECvAABAXsCvAABAXsAAAABAuoAAAABAXsDOQABAhwAAAABAhwCvAABAW8AAAABAmkAAAABAWUCvAABAZ0CvAABAZ0DOQABAgQDOQABAT8DOQABAZoDNQABAZoDOQABAagAAAABAfUAAAABAagDOQABAagBXgABAoECvAABAUADOQABAVQDNQABAVQDOQABAVQDUwABAVUDOQABA0MAAAABA3QAAAABAfIDOQABAK4CSgABAWYCvAABAagCvAABAMcCSgABAUoCvAABAT8CvAABAZYAAAABAZ8CvAABAV4DUwABAV4DOQABAY8DUwABAYoCvAABAfECvAABAOwCvAABAQ4CSgABATwAAAABAT4CvAABATsBSgABAY8CvAABAr0AAAABAhQCvAABAV4AAAABAlEAAAABAV4CvAABAY8DNQABAYgAAAABArEAAAABAY8DOQABAo4CvAABAYoDNQABAYoDOQABApcAAAABAYoDUwABAfEDOQABAMMCSgABATgAAAABATgCEwABATUCvQABATUCowABAVUCEgABAVUCvQABAVUCswABATQCvQABAYIAAAABAW4CEgABARACEgABAaACEgABAgEBugABAQsAAAABAQsCEgABATkAAAABAL0AAAABAI0CxQABAIsCowABAI4CxQABAVsAAAABAJAC5gABAMMCeQABATMCEAABAUEAAAABAUECEgABAYoAAAABAYoCEgABArECEAABAPgAAAABAPgCEgABAPgA/AABAR4ABQABARQCEgABARMCEgABAMgCegABAQQCEgABAdAAAAABAcoCEAABAI0AAAABAI0C5gABAI0BZgABARYC5gABAagCEgABAY8AAAABAY8CEgABASECEgABAR8AAAABAf0AAAABASECowABAdkAAAABAc0CEgABATUAAAABAgkAAAABATUCEgABAT8CEgABAGsCEgABAagCowABAVUCnwABAVUCowABAT8AAAABAaIAAAABAT8CowABAT8BCQABAcgCEgABAUUCEgABAUUCowABAQcCowABARACnwABARACowABAaAAAAABARACvQABARQCowABASMCEAABAaACowABAJoBugABAS8AAAABAUICEgABAdQAAAABAdQCEgABATECEgABAVIAAAABAVICEgABAVIBpgABAVkAAAABAVkCEgABAgYCEAABAPsAAAABAQcCEgABAToAAAABAS4CEgABASMCuwABAIsAAAABALsAAAABAIsCnwABAVAAAAABAkkAAAABAhoCEgABAgYCnQABAUgCEgABATACvQABATACowABAUYCEgABAUYCswABAUYCvQABAWkAAAABAVYCEgABAhQAAAABAVACEgABAZUCEgABAU8CEgABAU8AAAABAk8AAAABAU8CowABAeUCEgABATAAAAABAb0AAAABATACEgABATQCEgABATQAAAABAKcCEgABATQCowABAUYCnwABAUcAAAABAkAAAAABAUYCowABAhECEgABAVACnwABAVACowABApUAAAABAVACvQABAZUCowABAAAAAAAJAAAAAQAIAAEABAAAA7wABgEAAAEACAABAAwAHAABACoASgABAAYG/wcABwEHAgcEBwUAAQAFBv8HAAcBBwQHBQAGAAAAGgAAABoAAAAaAAAAGgAAABoAAAAaAAH+1AAAAAUAEgAMABIAGAAeAAH+1P9qAAH+1P9vAAH+1P9jAAH+1P9yAAYCAAABAAgAAQF6AAwAAQGgAEAAAgAIBt8G6gAABuwG/QAMBwoHJAAeB0AHQQA5B0UHRQA7B0gHSgA8B0wHUQA/B1MHVABFAEcAkACuAK4ArgKSAJYAugCuALoAnACuALoAwADAAsAAwACiAKIAwACuAK4ArgCoAK4ArgCuALQAugDAAMYAzADqAOoA6gDSANgA9gDqAPYA3gDqAPYA/AD8At4A/AD8AOoA6gDqAOQA6gDqAOoA8AD2APwBFAEOAQ4BDgEgASABIAECAQgBDgEOARQBGgEgAAH+1AKjAAH+1AMwAAH+1AMxAAH+1AL9AAH+1AKfAAH+1AMtAAH+1AMDAAH+1AK9AAH+1AKzAAH+1ALfAAH+1AM5AAH+1ANSAAH+1APGAAH+1APHAAH+1AM1AAH+1APDAAH+1AOZAAH+1ANTAAH+1ANJAAEBLAKjAAEBLAK8AAEBLAK9AAEBLAKfAAEBLAL9AAEBLAKzAAYCAAABAAgAAQAMACgAAQAyAWoAAgAEBt8G6gAABuwG/QAMBwoHJAAeB14HbQA5AAIAAQdeB20AAABJAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABMgAAATIAAAEyAAABMgAAATIAAAEyAAABMgAAATIAAAEyAAABMgAAATIAAAEyAAABMgAAATIAAAEyAAABMgAAATIAAAEyAAABMgAAATIAAAEyAAABJgAAATIAAAEyAAABMgAAATIAAAEyAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEyAAABMgAAATIAAAEyAAABMgAAATIAAAEyAAABMgAB/tQCuwAB/tQCEgAB/tQCvAAQACgAKAAiACgALgAuADQAOgBGAEYAQABGAEwATABSAFgAAf7UAyUAAf7UAxoAAf98AvcAAf9WAwsAAf7UAyAAAf7UA7sAAf7UA7AAAf98A40AAf9WA6EAAf7UA7YAAQAMACIABQEKAq4AAgADBt8G6gAABuwHJwAMB14HbQBIAAIAJgAEAEgAAABKAH8ARQCBAKYAewCpALQAoQC2AL0ArQC/ANoAtQDcAN4A0QDgAOQA1ADmAPQA2QD2ASoA6AEsATYBHQE4AVABKAFSAVQBQQFWAaUBRAGnAa4BlAGwAc4BnAHQAdYBuwHYAgcBwgIJAjwB8gI+AkUCJgJIAm0CLgJvAn0CVAJ/ArMCYwK1AtkCmALfAyMCvQMlAzUDAgM3A1sDEwNdA4IDOAOFA5ADXgOSA5kDagObA7YDcgO4A7oDjgO8A8ADkQPCBAUDlgQHBBED2gQTBCoD5QQsBC4D/QQwBGMEAABYAAIBmAACAZgAAgGYAAIBmAACAZgAAgGYAAIBmAACAZgAAgGYAAIBmAACAZgAAgGYAAIBmAACAZgAAgGYAAIBmAACAZgAAgGYAAIBmAACAZgAAgGYAAIBmAACAZgAAgGYAAIBmAACAZgAAgGYAAIBmAACAZgAAgGYAAQBmAAAAWgAAAFoAAABaAAAAWgAAQFiAAABaAAAAWgAAwFuAAMBdAADAYwAAwF6AAIBngACAZ4AAgGeAAIBngACAZ4AAgGeAAIBngACAZ4AAgGeAAIBngACAZ4AAgGeAAIBngACAZ4AAgGeAAIBngACAZ4AAgGeAAIBngACAZ4AAgGeAAIBgAACAZ4AAgGeAAIBngACAZ4AAgGeAAMBhgADAYwAAwGSAAIBmAACAZgAAgGYAAIBmAACAZgAAgGYAAIBmAACAZgAAgGeAAIBngACAZ4AAgGeAAIBngACAZ4AAgGeAAIBngAB/tUAAAAB/tQAAAAB/tQBtgAB/kwBtgAB/soBCgAB/tQCuwAB/tQBZAAB/ycBggAB/mMBXgAB/tQCEgAB/tQCvAQ0KlIqWCpGPJQ8lCpSKlgqNDyUPJQqUipYKl48lDyUKlIqWCoQPJQ8lCouKlgqXjyUPJQqUipYKhA8lDyUKlIqWCoKPJQ8lCpSKlgqEDyUPJQqUipYKl48lDyUKlIqWCpePJQ8lCpSKlgqFjyUPJQqLipYKl48lDyUKlIqWCoWPJQ8lCpSKlgqHDyUPJQqUipYKiI8lDyUKlIqWCo0PJQ8lCpSKlgqKDyUPJQqLipYKkY8lDyUKlIqWCo0PJQ8lCpSKlgqOjyUPJQqUipYKl48lDyUKlIqWCpAPJQ8lCpSKlgqRjyUPJQqUipYKkw8lDyUKlIqWCpMPJQ8lCpSKlgqXjyUPJQuWjyULlQ8lDyULlo8lC5gPJQ8lCpkPJQqajyUPJQqgjyUKnA8lDyUKoI8lCp2PJQ8lCqCPJQqfDyUPJQqgjyUKnA8lDyUKoI8lCp2PJQ8lCqCPJQqfDyUPJQqgjyUKog8lDyUM0w8lCrQLn48lCqOPJQqlC5+PJQqmjyUKqAqpjyUM0w8lCqsLn48lCqyPJQquCq+PJQqxDyUKtAufjyUKso8lCrQLn48lCrWPJQq3C5+PJQrHiskKxg8lDyUKx4rJDjaPJQ8lCseKyQrKjyUPJQrHiskKyo8lDyUKx4rJCsqPJQ8lCseKyQrKjyUPJQrHiskKuI8lDyUKwArJCsqPJQ8lCseKyQq4jyUPJQrHiskKug8lDyUKx4rJCruPJQ8lCseKyQ42jyUPJQrHiskKvQ8lDyUKx4rJCr6PJQ8lCsAKyQrGDyUPJQrHiskONo8lDyUKx4rJCsGPJQ8lCseKyQrKjyUPJQrHiskKww8lDyUKx4rJCsSPJQ8lCseKyQrEjyUPJQrHiskKxg8lDyUKx4rJCsqPJQ8lCs2PJQrMDyUPJQrNjyUKzw8lDyULDg8lC72PJQ8lCw4PJQu2DyUPJQsODyULtg8lDyULDg8lC7YPJQ8lCwgPJQu9jyUPJQsODyULuQ8lDyULDg8lC7qPJQ8lCw4PJQu9jyUPJQsODyULDIrWjyUK0I8lCtIK048lCtUPJQsMitaPJQsODyULD4rWjyULDg8lCw+K1o8lCwgPJQsMitaPJQriiuQK948lDyUPJQ8lCtgPJQ8lCuKK5ArxjyUPJQriiuQK5Y8lDyUK4orkCuWPJQ8lCuKK5ArxjyUPJQriiuQK2Y8lDyUK4orkCtsPJQ8lCuKK5ArcjyUPJQreCuQK948lDyUK4orkCvGPJQ8lCuKK5ArfjyUPJQriiuQK5Y8lDyUK4orkCuEPJQ8lCuKK5Ar3jyUPJQriiuQK5Y8lDyUPJQ8lCucPJQ8lDyUPJQrojyUPJQrqDyUK7o8lDyUK6g8lCuuPJQ8lCu0PJQrujyUPJQvUDyUK94vXC9iL1A8lCvAL1wvYi9QPJQrxi9cL2IvUDyUK94vXC9iK8w8lCveL1wvYi9QPJQr3i9cL2IrzDyUK94vXC9iL1A8lCvSL1wvYivYPJQr3i9cL2Ir5DyUK+or8Cv2K/w8lCwIPJQ8lCwCPJQsCDyUPJQsODyULDI8lDyULDg8lCwOPJQ8lCw4PJQsFDyUPJQsODyULD48lDyULCA8lCwyPJQ8lCw4PJQsGjyUPJQsIDyULDI8lDyULDg8lCwmPJQ8lCwsPJQsMjyUPJQsODyULD48lDyULIAshiyqLJIsmCyALIYsdCySLJgsgCyGLHoskiyYLIAshix6LJIsmCyALIYsRCySLJgsYiyGLHoskiyYLIAshixELJIsmCyALIYsSiySLJgsgCyGLFAskiyYLIAshix0LJIsmCyALIYsViySLJgsgCyGLIwskiyYLIAshixcLJIsmCxiLIYsqiySLJgsgCyGLHQskiyYLIAshixoLJIsmCyAPJQsqjyUPJQsgDyULHQ8lDyULGI8lCyqPJQ8lCyAPJQsdDyUPJQsgDyULGg8lDyULIA8lCx6PJQ8lCyALIYsdCySLJgsgCyGLHoskiyYLIAshixuLJIsmCyALIYsjCySLJgsgCyGLIwskiyYPJQ8lCyqPJQ8lCyALIYsqiySLJgsgCyGLHQskiyYLIAshix6LJIsmCyALIYsjCySLJgsgCyGLIwskiyYLIAshiyMLJIsmCyePJQspDyUPJQ8lDyULKo8lDyULLw8lCzOPJQ8lCy8PJQssDyUPJQsvDyULMI8lDyULLY8lCzOPJQ8lCy8PJQssDyUPJQstjyULM48lDyULLw8lCzCPJQ8lCzIPJQszjyUPJQs7DyULPI8lDyULOw8lCzUPJQ8lCzsPJQs2jyUPJQs7DyULOY8lDyULOw8lCzgPJQ8lCzsPJQs8jyUPJQs7DyULOY8lDyULPg8lCzyPJQ8lCzsPJQs/jyUPJQs+DyULPI8lDyULPg8lCz+PJQ8lDhEPJQtBDyUPJQtEDyULSItKDyULRA8lC0iLSg8lC0QPJQtCi0oPJQtEDyULSItKDyULRY8lC0iLSg8lC0WPJQtIi0oPJQtHDyULSItKDyULWQtai06PJQtdi1kLWotRjyULXYtZC1qLV48lC12LWQtai1ePJQtdi1kLWotXjyULXYtZC1qLUY8lC12LWQtai0uPJQtdi00LWotOjyULXYtZC1qLUY8lC12LWQtai1APJQtdi1kLWotOjyULXYtZC1qLUY8lC12LTQtai06PJQtdi1kLWotRjyULXYtZC1qLUA8lC12LWQtai1ePJQtdi1kLWotRjyULXYtZC1qLV48lC12LWQtai1MPJQtdi1kLWotUjyULXYtZC1qLVg8lC12LWQtai1ePJQtdi1kLWotcDyULXYtjjyULXw8lDyULY48lC2UPJQ8lC2OPJQtgjyUPJQtjjyULYg8lDyULY48lC2UPJQ8lC3EPJQtrC3QPJQtxDyULbIt0DyULcQ8lC3KLdA8lC3EPJQtmi3QPJQtxDyULaAt0DyULaY8lC2sLdA8lC3EPJQtsi3QPJQtxDyULbgt0DyULcQ8lC2+LdA8lC3EPJQtyi3QPJQt4jyULfQ8lDyULeI8lC3WPJQ8lC3iPJQt3DyUPJQt4jyULeg8lDyULe48lC30PJQ8lC5CLkguNjyUPJQuQi5ILiQ8lDyULkIuSC5OPJQ8lC5CLkguADyUPJQuHi5ILk48lDyULkIuSC4APJQ8lC5CLkgt+jyUPJQuQi5ILgA8lDyULkIuSC5OPJQ8lC5CLkguTjyUPJQuQi5ILgY8lDyULh4uSC5OPJQ8lC5CLkguBjyUPJQuQi5ILgw8lDyULkIuSC4SPJQ8lC5CLkguJDyUPJQuQi5ILhg8lDyULh4uSC42PJQ8lC5CLkguJDyUPJQuQi5ILio8lDyULkIuSC5OPJQ8lC5CLkguMDyUPJQuQi5ILjY8lDyULkIuSC48PJQ8lC5CLkguPDyUPJQuQi5ILk48lDyULlo8lC5UPJQ8lC5aPJQuYDyUPJQuZjyULmwufjyULnI8lC54Ln48lC7GLswuwDyUPJQuxi7MLqg8lDyULsYuzC7SPJQ8lC7GLswu0jyUPJQuxi7MLtI8lDyULsYuzC7SPJQ8lC7GLswuhDyUPJQuoi7MLtI8lDyULsYuzC6EPJQ8lC7GLswuijyUPJQuxi7MLpA8lDyULsYuzC6oPJQ8lC7GLswuljyUPJQuxi7MLpw8lDyULqIuzC7APJQ8lC7GLswuqDyUPJQuxi7MLq48lDyULsYuzC7SPJQ8lC7GLswutDyUPJQuxi7MLro8lDyULsYuzC66PJQ8lC7GPJQuwDyUPJQuxi7MLtI8lDyULvA8lC72PJQ8lC7wPJQu2DyUPJQu8DyULtg8lDyULvA8lC7YPJQ8lC7ePJQu9jyUPJQu8DyULuQ8lDyULvA8lC7qPJQ8lC7wPJQu9jyUPJQvMi84Lyw8lDyUPJQ8lC78PJQ8lC8yLzgvGjyUPJQvMi84Lz48lDyULzIvOC8+PJQ8lC8yLzgvGjyUPJQvMi84LwI8lDyULzIvOC8IPJQ8lC8yLzgvDjyUPJQvFC84Lyw8lDyULzIvOC8aPJQ8lC8yLzgvIDyUPJQvMi84Lz48lDyULzIvOC8mPJQ8lC8yLzgvLDyUPJQvMi84Lz48lDyUPJQ8lC9EPJQ8lDyUPJQvSjyUPJQvUDyUL1YvXC9iL2g8lC90PJQ8lC9uPJQvdDyUPJQvpDyUL548lDyUL6Q8lC96PJQ8lC+kPJQvgDyUPJQvpDyUL6o8lDyUL4w8lC+ePJQ8lC+kPJQvhjyUPJQvjDyUL548lDyUL6Q8lC+SPJQ8lC+YPJQvnjyUPJQvpDyUL6o8lDyUL7A8lC+2PJQ8lDNYPJQvzi/UPJQzWDyUL84v1DyUM1g8lC+8L9Q8lDNYPJQvzi/UPJQvwjyUL84v1DyUL8I8lC/OL9Q8lC/IPJQvzi/UPJQwEDAWL/48lDAiMBAwFi/sPJQwIjAQMBYwCjyUMCIwEDAWMAo8lDAiMBAwFjAKPJQwIjAQMBYv7DyUMCIwEDAWL9o8lDAiL+AwFi/+PJQwIjAQMBYv7DyUMCIwEDAWL+Y8lDAiMBAwFi/+PJQwIjAQMBYv7DyUMCIv4DAWL/48lDAiMBAwFi/sPJQwIjAQMBYv5jyUMCIwEDAWMAo8lDAiMBAwFi/sPJQwIjAQMBYwCjyUMCIwEDAWL/I8lDAiMBAwFi/4PJQwIjAQMBYv/jyUMCIwEDAWMAQ8lDAiMBAwFjAKPJQwIjAQMBYwHDyUMCIwOjyUMCg8lDyUMDo8lDBAPJQ8lDA6PJQwLjyUPJQwOjyUMDQ8lDyUMDo8lDBAPJQ8lDBwPJQwWDyUPJQwcDyUMF48lDyUMHA8lDB2PJQ8lDBwPJQwRjyUPJQwcDyUMEw8lDyUMFI8lDBYPJQ8lDBwPJQwXjyUPJQwcDyUMGQ8lDyUMHA8lDBqPJQ8lDBwPJQwdjyUPJQ6SDyUMI48lDyUOkg8lDB8PJQ8lDpIPJQwgjyUPJQ6SDyUMIg8lDyUOiQ8lDCOPJQ8lDnoMNYwyjyUPJQ56DDWMLg8lDyUOegw1jDcPJQ8lDnoMNYwmjyUPJQ59DDWMNw8lDyUOegw1jCaPJQ8lDnoMNYwlDyUPJQ56DDWMJo8lDyUOegw1jDcPJQ8lDnoMNYw3DyUPJQ56DDWMKA8lDyUOfQw1jDcPJQ8lDnoMNYwoDyUPJQ56DDWMKY8lDyUOegw1jCsPJQ8lDnoMNYwuDyUPJQ56DDWMLI8lDyUOfQw1jDKPJQ8lDnoMNYwuDyUPJQ56DDWML48lDyUOegw1jDcPJQ8lDnoMNYwxDyUPJQ56DDWMMo8lDyUOegw1jDQPJQ8lDnoMNYw0DyUPJQ56DDWMNw8lDyUMOg8lDDiPJQ8lDDoPJQw7jyUPJQxBjyUMPQ8lDyUMQY8lDD6PJQ8lDEGPJQxADyUPJQxBjyUMPQ8lDyUMQY8lDD6PJQ8lDEGPJQxADyUPJQxBjyUMQw8lDyUMRI8lDyUNQ41FDESPJQ8lDUONRQxEjyUPJQ1DjUUMRg8lDyUNQ41FDEePJQ8lDUONRQxJDyUMSo1DjUUO1AxeDFOPJQ8lDtQMXgxVDyUPJQ7UDF4MX48lDyUO1AxeDF+PJQ8lDtQMXgxfjyUPJQ7UDF4MX48lDyUO1AxeDEwPJQ8lDgUMXgxfjyUPJQ7UDF4MTA8lDyUO1AxeDE2PJQ8lDtQMXgxPDyUPJQ7UDF4MVQ8lDyUO1AxeDFCPJQ8lDtQMXgxSDyUPJQ4FDF4MU48lDyUO1AxeDFUPJQ8lDtQMXgxWjyUPJQ7UDF4MX48lDyUO1AxeDFgPJQ8lDtQMXgxZjyUPJQ7UDF4MWY8lDyUMWw8lDFyPJQ8lDtQMXgxfjyUPJQxhDGKMZA8lDyUMZw8lDGWPJQ8lDGcPJQxojyUPJQ8lDyUMag8lDyUPJQ8lDGuPJQ8lDyUPJQxrjyUPJQ8lDyUMa48lDyUPJQ8lDG0PJQ8lDyUPJQxujyUPJQ8lDyUMcA8lDyUOkg8lDWkMdIx2DpIPJQ1pDHSMdgxxjyUNaQx0jHYOkg8lDIyMdIx2DpIPJQxzDHSMdg6JDyUNaQx0jHYM3AyDjIIPJQ8lDNwMg4x3jyUPJQzcDIOMfY8lDyUM3AyDjIUPJQ8lDNwMg4yFDyUPJQzcDIOMfY8lDyUM3AyDjHkPJQ8lDNwMg4x6jyUPJQzcDIOMfA8lDyUM2oyDjIIPJQ8lDNwMg4x9jyUPJQzcDIOMfw8lDyUM3AyDjIUPJQ8lDNwMg4ySjyUPJQzcDIOMgI8lDyUM3AyDjIIPJQ8lDNwMg4yFDyUPJQ8lDyUMho8lDyUPJQ8lDIgPJQ8lDyUPJQyJjyUPJQyLDyUNaQ8lDI+Miw8lDIyPJQyPjI4PJQ1pDyUMj44LDyUMkQ8lDyUM3A8lDWkNaoyUDNwPJQ1hjWqMlAzcDyUNaQ1qjJQM2o8lDWkNaoyUDNwPJQ1pDWqMlAzajyUNaQ1qjJQM3A8lDJKNaoyUDN8PJQ1pDWqMlAyVjyUMlwyYjJoMm48lDyUPJQ8lDJ0PJQ8lDyUPJQ6SDyUMp48lDyUOkg8lDJ6PJQ8lDKAPJQyhjyUPJQ6SDyUMqQ8lDyUOiQ8lDKePJQ8lDpIPJQyjDyUPJQ6JDyUMp48lDyUOkg8lDKSPJQ8lDKYPJQynjyUPJQ6SDyUMqQ8lDyUMxYzHDL4MygzLjMWMxwy7DMoMy4zFjMcMxAzKDMuMxYzHDMQMygzLjMWMxwyqjMoMy4yyDMcMxAzKDMuMxYzHDKqMygzLjMWMxwysDMoMy4zFjMcMrYzKDMuMxYzHDLsMygzLjMWMxwyvDMoMy4zFjMcMyIzKDMuMxYzHDLCMygzLjLIMxwy+DMoMy4zFjMcMuwzKDMuMxYzHDLOMygzLjLmPJQzXjyUPJQy5jyUMto8lDyUMtQ8lDNePJQ8lDLmPJQy2jyUPJQy5jyUMuA8lDyUMuY8lDMQPJQ8lDMWMxwy7DMoMy4zFjMcMxAzKDMuMxYzHDLyMygzLjMWMxwzIjMoMy4zFjMcMyIzKDMuMxY8lDL4Mygy/jMWMxwzBDMoMy4zFjMcMwozKDMuMxYzHDMQMygzLjMWMxwzIjMoMy4zFjMcMyIzKDMuMxYzHDMiMygzLjM0PJQzOjyUPJQzQDyUM0Y8lDyUM0w8lDNSPJQ8lDNYPJQzXjyUPJQzcDyUM4I8lDyUM3A8lDNkPJQ8lDNwPJQzdjyUPJQzajyUM4I8lDyUM3A8lDNkPJQ8lDNqPJQzgjyUPJQzcDyUM3Y8lDyUM3w8lDOCPJQ8lDOgPJQzpjyUPJQzoDyUM4g8lDyUM6A8lDOOPJQ8lDOgPJQzmjyUPJQzoDyUM5Q8lDyUM6A8lDOmPJQ8lDOgPJQzmjyUPJQzrDyUM6Y8lDyUM6A8lDOyPJQ8lDOsPJQzpjyUPJQzrDyUM7I8lDyUM9A8lDPoM+4z9DO4PJQzvjPEM8oz0DyUM+gz7jP0M9A8lDPoM+4z9DPcPJQz6DPuM/Qz0DyUM9Yz7jP0M9w8lDPoM+4z9DPiPJQz6DPuM/Q23DQGNig8lDQSNtw0BjYuPJQ0EjbcNAY2RjyUNBI23DQGNkY8lDQSNtw0BjZGPJQ0EjbcNAY2LjyUNBI23DQGNhw8lDQSM/o0BjYoPJQ0EjbcNAY2LjyUNBI23DQGNjQ8lDQSNtw0BjYoPJQ0EjbcNAY2LjyUNBIz+jQGNig8lDQSNtw0BjYuPJQ0EjbcNAY2NDyUNBI23DQGNkY8lDQSNtw0BjYuPJQ0EjbcNAY2RjyUNBI23DQGNjo8lDQSNtw0BjQMPJQ0EjbcNAY2KDyUNBI23DQGNAA8lDQSNtw0BjZGPJQ0EjbcNAY0DDyUNBI0GDyUNB48lDyUNDY8lDQkPJQ8lDQ2PJQ0PDyUPJQ0NjyUNCo8lDyUNDY8lDQwPJQ8lDQ2PJQ0PDyUPJQ0bDyUNFQ8lDyUNGw8lDRaPJQ8lDRsPJQ0cjyUPJQ0bDyUNEI8lDyUNGw8lDRIPJQ8lDROPJQ0VDyUPJQ0bDyUNFo8lDyUNGw8lDRgPJQ8lDRsPJQ0ZjyUPJQ0bDyUNHI8lDyUNIQ8lDSWPJQ8lDSEPJQ0eDyUPJQ0hDyUNH48lDyUNIQ8lDSKPJQ8lDSQPJQ0ljyUPJQ05DTqNNg8lDyUNOQ06jTGPJQ8lDTkNOo08DyUPJQ05DTqNKI8lDyUNMA06jTwPJQ8lDTkNOo0ojyUPJQ05DTqNJw8lDyUNOQ06jSiPJQ8lDTkNOo08DyUPJQ05DTqNPA8lDyUNOQ06jSoPJQ8lDTANOo08DyUPJQ05DTqNKg8lDyUNOQ06jSuPJQ8lDTkNOo0tDyUPJQ05DTqNMY8lDyUNOQ06jS6PJQ8lDTANOo02DyUPJQ05DTqNMY8lDyUNOQ06jTMPJQ8lDTkNOo08DyUPJQ05DTqNNI8lDyUNOQ06jTYPJQ8lDTkNOo03jyUPJQ05DTqNN48lDyUNOQ06jTwPJQ8lDyUPJQ09jyUPJQ8lDyUNPw8lDyUNQI8lDUINQ41FDViNWg1PjyUPJQ1YjVoNUQ8lDyUNWI1aDVuPJQ8lDViNWg1bjyUPJQ1YjVoNW48lDyUNWI1aDVuPJQ8lDViNWg1GjyUPJQ1ODVoNW48lDyUNWI1aDUaPJQ8lDViNWg1IDyUPJQ1YjVoNSY8lDyUNWI1aDVEPJQ8lDViNWg1LDyUPJQ1YjVoNTI8lDyUNTg1aDU+PJQ8lDViNWg1RDyUPJQ1YjVoNUo8lDyUNWI1aDVuPJQ8lDViNWg1UDyUPJQ1YjVoNVY8lDyUNWI1aDVWPJQ8lDdmPJQ1XDyUPJQ1YjVoNW48lDyUNXQ1ejWAPJQ8lDWePJQ1pDWqNc41njyUNYY1qjXONZ48lDWkNao1zjWMPJQ1pDWqNc41njyUNaQ1qjXONYw8lDWkNao1zjWePJQ1kjWqNc41mDyUNaQ1qjXONZ48lDWkNao1zjWwPJQ1tjyUPJQ11DyUNew18jX4Nbw8lDXCNcg1zjXUPJQ17DXyNfg11DyUNew18jX4NeA8lDXsNfI1+DXUPJQ12jXyNfg14DyUNew18jX4NeY8lDXsNfI1+DYQPJQ1/jyUPJQ2EDyUNhY8lDyUNhA8lDYEPJQ8lDYQPJQ2CjyUPJQ2EDyUNhY8lDyUNkA8lDYoPJQ8lDZAPJQ2LjyUPJQ2QDyUNkY8lDyUNkA8lDYcPJQ8lDYiPJQ2KDyUPJQ2QDyUNi48lDyUNkA8lDY0PJQ8lDZAPJQ2OjyUPJQ2QDyUNkY8lDyUNlg8lDZqPJQ8lDZYPJQ2TDyUPJQ2WDyUNlI8lDyUNlg8lDZePJQ8lDZkPJQ2ajyUPJQ7UDayNqY8lDyUO1A2sjaUPJQ8lDtQNrI2uDyUPJQ7UDayNnY8lDyUOBQ2sja4PJQ8lDtQNrI2djyUPJQ7UDayNnA8lDyUO1A2sjZ2PJQ8lDtQNrI2uDyUPJQ7UDayNrg8lDyUO1A2sjZ8PJQ8lDgUNrI2uDyUPJQ7UDayNnw8lDyUO1A2sjaCPJQ8lDtQNrI2iDyUPJQ7UDayNpQ8lDyUO1A2sjaOPJQ8lDgUNrI2pjyUPJQ7UDayNpQ8lDyUO1A2sjaaPJQ8lDtQNrI2uDyUPJQ7UDayNqA8lDyUO1A2sjamPJQ8lDtQNrI2rDyUPJQ7UDayNqw8lDyUO1A2sja4PJQ8lDbEPJQ2vjyUPJQ2xDyUNso8lDyUNvQ8lDbQPJQ8lDbcPJQ6/DyUPJQ23DyUNtY8lDyUNtw8lDrePJQ8lDbcPJQ6/DyUPJQ23DyUNtY8lDyUNtw8lDrePJQ8lDbcPJQ66jyUPJQ29DyUOAg6eDyUNuI8lDboNu48lDb0PJQ39jp4PJQ2+jyUNwA3BjyUNww8lDgIOng8lDcSPJQ4CDp4PJQ3GDyUNx46eDyUN2Y3bDdgPJQ8lDdmN2w3SDyUPJQ3ZjdsN3I8lDyUN2Y3bDdyPJQ8lDdmN2w3cjyUPJQ3ZjdsN3I8lDyUN2Y3bDckPJQ8lDdCN2w3cjyUPJQ3ZjdsNyQ8lDyUN2Y3bDcqPJQ8lDdmN2w3MDyUPJQ3ZjdsN0g8lDyUN2Y3bDc2PJQ8lDdmN2w3PDyUPJQ3QjdsN2A8lDyUN2Y3bDdIPJQ8lDdmN2w3TjyUPJQ3ZjdsN3I8lDyUN2Y3bDdUPJQ8lDdmN2w3WjyUPJQ3ZjdsN1o8lDyUN2Y3bDdgPJQ8lDdmN2w3cjyUPJQ60jyUOtg8lDyUN348lDd4PJQ8lDd+PJQ3hDyUPJQ8BDyUOvw8lDyUPAQ8lDrePJQ8lDwEPJQ63jyUPJQ8BDyUOt48lDyUO9o8lDr8PJQ8lDwEPJQ66jyUPJQ8BDyUOvA8lDyUPAQ8lDr8PJQ8lDh6PJQ4dDeiPJQ3ijyUN5A3ljyUN5w8lDh0N6I8lDh6PJQ4gDeiPJQ4ejyUOIA3ojyUOGI8lDh0N6I8lDfYN9430jyUPJQ32DfeN9I8lDyUN9g33jfAPJQ8lDfYN9435DyUPJQ32DfeN+Q8lDyUN9g33jfAPJQ8lDfYN943qDyUPJQ32DfeN648lDyUN9g33je0PJQ8lDe6N9430jyUPJQ32DfeN8A8lDyUN9g33jfGPJQ8lDfYN9435DyUPJQ8lDyUOyA8lDyUN9g33jfMPJQ8lDfYN9430jyUPJQ32DfeN+Q8lDyUPJQ8lDfqPJQ8lDyUPJQ38DyUPJQ4AjyUOAg8lDyUOAI8lDf2PJQ8lDf8PJQ4CDyUPJQ4AjyUOAg8lDyUO1A8lDgmO1w7YjtQPJQ4DjtcO2I7UDyUOCY7XDtiOBQ8lDgmO1w7YjtQPJQ4JjtcO2I4FDyUOCY7XDtiO1A8lDgaO1w7YjggPJQ4JjtcO2I4LDyUODI4ODg+OEQ8lDhQPJQ8lDhKPJQ4UDyUPJQ4ejyUOHQ8lDyUOHo8lDhWPJQ8lDh6PJQ4gDyUPJQ4YjyUOHQ8lDyUOHo8lDhcPJQ8lDhiPJQ4dDyUPJQ4ejyUOGg8lDyUOG48lDh0PJQ8lDh6PJQ4gDyUPJQ4zjjUOLw44DjmOM441DiwOOA45jjOONQ4yDjgOOY4zjjUOMg44DjmOM441DiGOOA45jikONQ4yDjgOOY4zjjUOIY44DjmOM441DiMOOA45jjOONQ4kjjgOOY4zjjUOLA44DjmOM441DiYOOA45jjOONQ42jjgOOY4zjjUOJ444DjmOKQ41Di8OOA45jjOONQ4sDjgOOY4zjjUOKo44DjmOM48lDi8PJQ8lDjOPJQ4sDyUPJQ4pDyUOLw8lDyUOM48lDiwPJQ8lDjOPJQ4qjyUPJQ4zjyUOMg8lDyUOM441DiwOOA45jjOONQ4yDjgOOY4zjjUOLY44DjmOM441DjaOOA45jjOONQ42jjgOOY8lDyUOLw8lDyUOMI41DuYOOA45jjCONQ7ejjgOOY4zjjUOMg44DjmOM441DjaOOA45jjOONQ42jjgOOY4zjjUONo44DjmOOw8lDjyPJQ8lDyUPJQ4+DyUPJQ5CjyUORw8lDyUOQo8lDj+PJQ8lDkKPJQ5EDyUPJQ5BDyUORw8lDyUOQo8lDj+PJQ8lDkEPJQ5HDyUPJQ5CjyUORA8lDyUORY8lDkcPJQ8lDk6PJQ5QDyUPJQ5OjyUOSI8lDyUOTo8lDkoPJQ8lDk6PJQ5NDyUPJQ5OjyUOS48lDyUOTo8lDlAPJQ8lDk6PJQ5NDyUPJQ5RjyUOUA8lDyUOTo8lDlMPJQ8lDlGPJQ5QDyUPJQ5RjyUOUw8lDyUOVg8lDlwOXY8lDlYPJQ5cDl2PJQ5WDyUOVI5djyUOVg8lDlwOXY8lDlkPJQ5cDl2PJQ5WDyUOV45djyUOWQ8lDlwOXY8lDlqPJQ5cDl2PJQ8BDl8O/I8lDmCPAQ5fDvmPJQ5gjwEOXw7/jyUOYI8BDl8O/48lDmCPAQ5fDv+PJQ5gjwEOXw75jyUOYI8BDl8O9Q8lDmCO9o5fDvyPJQ5gjwEOXw75jyUOYI8BDl8O+A8lDmCPAQ5fDvyPJQ5gjwEOXw75jyUOYI72jl8O/I8lDmCPAQ5fDvmPJQ5gjwEOXw74DyUOYI8BDl8O/48lDmCPAQ5fDvmPJQ5gjwEOXw7/jyUOYI8BDl8O+w8lDmCPAQ5fDwQPJQ5gjwEOXw7+DyUOYI8BDl8O/48lDmCPAQ5fDwQPJQ5gjmaPJQ5iDyUPJQ5mjyUOaA8lDyUOZo8lDmOPJQ8lDmaPJQ5lDyUPJQ5mjyUOaA8lDyUOdA8lDm4PJQ8lDnQPJQ5vjyUPJQ50DyUOdY8lDyUOdA8lDmmPJQ8lDnQPJQ5rDyUPJQ5sjyUObg8lDyUOdA8lDm+PJQ8lDnQPJQ5xDyUPJQ50DyUOco8lDyUOdA8lDnWPJQ8lDnoPJQ5+jyUPJQ56DyUOdw8lDyUOeg8lDniPJQ8lDnoPJQ57jyUPJQ59DyUOfo8lDyUOkg6Tjo8PJQ8lDpIOk46KjyUPJQ6SDpOOlQ8lDyUOkg6TjoGPJQ8lDokOk46VDyUPJQ6SDpOOgY8lDyUOkg6TjoAPJQ8lDpIOk46BjyUPJQ6SDpOOlQ8lDyUOkg6TjpUPJQ8lDpIOk46DDyUPJQ6JDpOOlQ8lDyUOkg6TjoMPJQ8lDpIOk46EjyUPJQ6SDpOOhg8lDyUOkg6TjoqPJQ8lDpIOk46HjyUPJQ6JDpOOjw8lDyUOkg6TjoqPJQ8lDpIOk46MDyUPJQ6SDpOOlQ8lDyUOkg6Tjo2PJQ8lDpIOk46PDyUPJQ6SDpOOkI8lDyUOkg6TjpCPJQ8lDpIOk46VDyUPJQ6YDyUOlo8lDyUOmA8lDpmPJQ8lDpsPJQ6cjp4PJQ6wDrGOro8lDyUOsA6xjqiPJQ8lDrAOsY6zDyUPJQ6wDrGOsw8lDyUOsA6xjrMPJQ8lDrAOsY6zDyUPJQ6wDrGOn48lDyUOpw6xjrMPJQ8lDrAOsY6fjyUPJQ6wDrGOoQ8lDyUOsA6xjqKPJQ8lDrAOsY6ojyUPJQ6wDrGOpA8lDyUOsA6xjqWPJQ8lDqcOsY6ujyUPJQ6wDrGOqI8lDyUOsA6xjqoPJQ8lDrAOsY6zDyUPJQ6wDrGOq48lDyUOsA6xjq0PJQ8lDrAOsY6tDyUPJQ8lDyUOro8lDyUOsA6xjrMPJQ8lDrSPJQ62DyUPJQ69jyUOvw8lDyUOvY8lDrePJQ8lDr2PJQ63jyUPJQ69jyUOt48lDyUOuQ8lDr8PJQ8lDr2PJQ66jyUPJQ69jyUOvA8lDyUOvY8lDr8PJQ8lDsyOzg7LDyUPJQ7Mjs4Oyw8lDyUOzI7ODsUPJQ8lDsyOzg7PjyUPJQ7Mjs4Oz48lDyUOzI7ODsUPJQ8lDsyOzg7AjyUPJQ7Mjs4Owg8lDyUOw47ODssPJQ8lDsyOzg7FDyUPJQ7Mjs4Oxo8lDyUOzI7ODs+PJQ8lDyUPJQ7IDyUPJQ7Mjs4OyY8lDyUOzI7ODssPJQ8lDsyOzg7PjyUPJQ8lDyUO0Q8lDyUPJQ8lDtKPJQ8lDtQPJQ7VjtcO2I7aDyUO3Q8lDyUO248lDt0PJQ8lDuePJQ7mDyUPJQ7njyUO3o8lDyUO548lDukPJQ8lDuGPJQ7mDyUPJQ7njyUO4A8lDyUO4Y8lDuYPJQ8lDuePJQ7jDyUPJQ7kjyUO5g8lDyUO548lDukPJQ8lDuwPJQ7yDvOPJQ7sDyUO8g7zjyUO7A8lDuqO848lDuwPJQ7yDvOPJQ7vDyUO8g7zjyUO7A8lDu2O848lDu8PJQ7yDvOPJQ7wjyUO8g7zjyUPAQ8CjvyPJQ8FjwEPAo75jyUPBY8BDwKO/48lDwWPAQ8Cjv+PJQ8FjwEPAo7/jyUPBY8BDwKO+Y8lDwWPAQ8CjvUPJQ8FjvaPAo78jyUPBY8BDwKO+Y8lDwWPAQ8CjvgPJQ8FjwEPAo78jyUPBY8BDwKO+Y8lDwWO9o8CjvyPJQ8FjwEPAo75jyUPBY8BDwKO+A8lDwWPAQ8Cjv+PJQ8FjwEPAo75jyUPBY8BDwKO/48lDwWPAQ8CjvsPJQ8FjwEPAo8EDyUPBY8BDwKO/I8lDwWPAQ8Cjv4PJQ8FjwEPAo7/jyUPBY8BDwKPBA8lDwWPC48lDwcPJQ8lDwuPJQ8NDyUPJQ8LjyUPCI8lDyUPC48lDwoPJQ8lDwuPJQ8NDyUPJQ8ZDyUPEw8lDyUPGQ8lDxSPJQ8lDxkPJQ8ajyUPJQ8ZDyUPDo8lDyUPGQ8lDxAPJQ8lDxGPJQ8TDyUPJQ8ZDyUPFI8lDyUPGQ8lDxYPJQ8lDxkPJQ8XjyUPJQ8ZDyUPGo8lDyUPHw8lDyOPJQ8lDx8PJQ8cDyUPJQ8fDyUPHY8lDyUPHw8lDyCPJQ8lDyIPJQ8jjyUPJQAAQFuA7sAAQFuA7AAAQIWA40AAQHwA6EAAQFuA7YAAQFu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AFYAZQB0AIMAkQCgAK8AvgDNANwA6wD6AQkBGAEnATYAAP//ABUADAAbACoAOQBIAFcAZgB1AIQAkgChALAAvwDOAN0A7AD7AQoBGQEoATcAAP//ABUADQAcACsAOgBJAFgAZwB2AIUAkwCiALEAwADPAN4A7QD8AQsBGgEpATgAAP//ABUADgAdACwAOwBKAFkAaAB3AIYAlACjALIAwQDQAN8A7gD9AQwBGwEqATkBOmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNjbXAHgmNjbXAHgmNjbXAHgmNjbXAHgmNjbXAHgmNjbXAHcmNjbXAHgmNjbXAHgmNjbXAHgmNjbXAHgmNjbXAHgmNjbXAHgmNjbXAHgmNjbXAHgmNjbXAHgmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxvY2wHsGxvY2wHtmxvY2wHvGxvY2wHwmxvY2wHyGxvY2wHzmxvY2wH1GxvY2wH2mxvY2wH4GxvY2wH5mxvY2wH7GxvY2wH8mxvY2wH+GxvY2wH/m51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQgAAAAIAAAABAAAAAQAkAAAAAQAmAAAABgACAAMABAAFAAYABwAAAAQAAgADAAQABQAAAAEAJwAAAAEAGgAAAAMAGwAcAB0AAAABACgAAAABACAAAAABABEAAAABABUAAAABABQAAAABABIAAAABABMAAAABABAAAAABAAkAAAABAA8AAAABAAwAAAABAAsAAAABAAgAAAABAAoAAAABAA0AAAABAA4AAAABABkAAAABACMAAAACAB4AHwAAAAEAIQAAAAEAKQAAAAEAFwAAAAEAJQAAAAEAKgAAAAEAFgAAAAEAGAAAAAEAIgAtAFwG3hGaEkgSrhKuFAIUAhSsFNoVHhUeFUAVQBVAFUAVQBVUFcIV1hX8FhYWPBZKFlgWiBZmFnQWiBaWFt4XJhdIF2AXeBeQF64Z+BxUHUYdZh2OHY4iniM4AAEAAAABAAgAAgRCAh4C+wL8Av0C/gL/AwADAQMCAwMDBAMFAwYDBwMIAyIDIwMtAy4DLwMwAzEDMgNHA0gDSQNLA0wDTQNOA08DUANRA1IDUwNhA2IDYwNkA2UDZgNnA2gDaQNqA2sDbANtA24DbwNwA3EDcgNzA3QDdQN2A3cDeAN5A3oDewN8A30DfgN/A4ADgQOCA4MDhAOGA4cDiAOJA4oDiwOMA40DjgOPA5ADkQOSA5MDlQOWA5cDmAOZA5oDuwPBAvsC/AL9Av4C/wMAAwEDAgMDAwQDBQMGAwcDCAMiAyMDJQMmAycDKAMpAyoDKwMsAy0DLgMvAzADMQMyAzQDNQM3AzgDOQM6AzsDPAM9Az4DPwNAA0EDQgNDA0QDRgNHA0gDSQNKA1QDVQNWA1cDWANZA1oDWwNcA10DXgNfA2EDYgNjA2QDZQNmA2cDaANpA2oDawNsA20DbgNvA3ADcQNyA3MDdAN1A3YDdwN4A3kDegN7A3wDfQN+A38DgAOBA4MDhAOFA4YDhwOIA4kDigOLA4wDjQOOA48DkAORA5IDkwOVA5YDlwOYA5kDmgOjA6QDpQOmA6cDqAOpA6oDqwOsA60DrgOvA7ADsQOyA7MDtAO1A7YDtwO4A7kDugO7A8EDxgM2At0C3gPRA9ID0wPUA9UD1gPXA9gD2QPaA9sD3APdA94D3wPgA+ED4gPjA+QD5QPmA+cD6APpA+oD6wPsA+0D7gPvA/AD8QPyA/MD9AP1A/YD9wP4A/kD+gP7A/wD/QP+A/8EAAQBBAIEAwQEBAUEBgQHBAgECQQKBAsEDAQNBA4EDwQQBBEEEgQTBBQEFQQWBBcEGAQZBBoEGwQcBB0EHgQfBCAEIQQiBCMEJAQlBCYEJwQoBCkEKgQrBCwELQQuBC8EMAQxBDIEMwQ0BDUENgQ3BDgEOQQ6BDsEPAQ9BD4EPwRABEEEQgRDBEQERQRGBEcESARJBEoESwRMBE0ETgRPBFAEUQRSBFMEVARVBFYEVwRYBFkEWgRbBFwEXQReBF8EYARhBGIEYwTjBOUE5gTnBOgE6QTrBOoE7QTuBO8E8ATyBPME9AT1BPYE9wT4BN8E4AT5BPoE+wT8BP0E/gT/BQAFAQUCBQMFBAUFBZoFlQV9BZQFnAWdBZ4FgAWBBaEFhQWGBYcFowWlBaYFigWLBYwFjQWpBaoFqwWQBawFkQWSBZMFrQWuBa8FsAWxBbIFswW0BbUFtgW3BbgFuQX8Bf0F/gX/BgAGAQYCBgMGBAYFBjYGOAZgBmEGZgZnBmgGaQZwBjkGQgZDBkQGRQZGBkcGTwZQBlEGagZrBmwGbQZuBm8GuQa6BrsGvAbcBt4G3QcKBwsHDAcNBw4HDwcQBxEHEgcTBxQHFQcWBxcHGAcZBxoHGwccBx0HHgcfByAHIQciByMHJAdWByYHZgdnB2gHaQdqB2sHbAdtAAIAXgAgACgAAAAqAC4ACQBHAEgADgBSAFcAEABqAG0AFgBvAHYAGgCFAKgAIgCqALcARgC5AL4AVADfAN8AWgDlAOUAWwGmAbMAXAHNAc4AagHQAd0AbAHfAe4AegHxAfUAigH/AgIAjwIEAgsAkwINAi0AmwIvAj8AvAJBAkYAzQJQAmgA0wJuAm4A7AJzAnMA7QJ+An4A7gLbAtwA7wLfAvoA8QMJAyEBDQMkAywBJgMzAzsBLwM9A0YBOANRA1EBQgNUA18BQwOFA4UBTwObA7oBUAO8A8ABcAPCA9ABdQRmBGYBhARtBG8BhQRyBHUBiAR9BH0BjAR/BIEBjQSJBI0BkASTBJMBlQSYBJgBlgScBJwBlwSfBJ8BmASqBKoBmQS8BL8BmgTFBMYBngTLBM0BoATQBNABowTWBNYBpATYBNgBpQUGBQgBpgUKBQoBqQUNBREBqgUVBRYBrwUYBRgBsQUaBRoBsgUdBR0BswUgBSEBtAUkBScBtgUrBS0BugU1BTUBvQU4BTgBvgU8BTwBvwU/BT8BwAVJBUkBwQVdBWIBwgVmBWcByAVsBW4BygVxBXEBzQV5BXkBzgYGBg8BzwYlBiUB2QYnBicB2gYrBiwB2wYuBjIB3QY7BkEB4gZIBkkB6QZMBkwB6wZWBlsB7AavBq8B8gaxBrEB8wazBrMB9Aa1BrUB9QbKBssB9gbYBtgB+AbfBuoB+QbsBu8CBQbyBvwCCQcHBwgCFAdeB2UCFgADAAAAAQAIAAEJtAEyAmoCcgJ4An4ChAKKApAClgKcAqICqAKuArQCugLAAsYCzALSAtgC3gLkAuoC8AL2AvwDAgMIAw4DFAMaAyADJgMsAzIDOAM+A0QDSgNQA1YDXANiA2gDbgN0A3oDgAOGA4wDkgOYA54DpAOqA7ADtgO8A8IDyAPOA9QD2gPgA+YD7APyA/gD/gQEBAoEEAQWBBwEIgQoBC4ENAQ6BEAERgRMBFIEWAReBGQEagRwBHYEfASCBIgEjgSUBJoHdgSgBKYErASyBLgEvgTEBMwE0gTYBN4E5ATqBPAE9gT8BQIFCAUOBRQFGgUgBSYFLAUyBTgFPgVEBUoFUAVWBVwFYgVoBW4FdAV6BYAFhgWMBZIFmAWeBaQFqgWwBbYFvAXCBcgFzgXUBdoF4AXmBewF9AX6BgAGBgYMBhIGGAYeBiQGKgYwBjYGPAZCBkgGTgZUBloGYAZmBmwGcgZ4Bn4GhAaKBpAGlgacBqIGqAauBrQGugbABsYGzAbSBtgG3gbkBuoG8Ab2BvwHAgcIBw4HFAcaByAHJgcsBzIHOgdAB0YHTAdSB1gHXgdkB2oHcAd2B3wHggeIB44HlAeaB6IHqAeuB7QHugfAB8YHzAfSB9gH3gfkB+oH8Af2B/wIAggICA4IFAgaCCAIJggsCDIIOAg+CEQISghSCFgIXghkCGoIcgh4CH4IjgieCK4IvgjOCN4I7gj+CQ4JHgkkCSoJMAk2CTwJQglICU4JVAkeCSQJKgkwCTYJPAlCCUgJTglUCVoJXgliCWYJagluCXIJdgl6CX4JggmKCZAJlgmcCaIJqAmuAAMEZALfAPYAAgLgAPcAAgLhAPgAAgLiAPkAAgLjAPoAAgLkAPsAAgLlAPwAAgLmAP0AAgLnAP4AAgLoAP8AAgLpAQAAAgLqAQEAAgLrAQIAAgLsAQMAAgLtAQQAAgLuAQUAAgLvAQYAAgLwAQcAAgLxAQgAAgLyAQkAAgLzAQoAAgL0AQsAAgL1AQwAAgL2AQ0AAgL3AQ4AAgL4AQ8AAgL5ARAAAgL6AREAAgMJARIAAgMJARMAAgMKARQAAgMLARUAAgMMARYAAgMNARcAAgMOARgAAgMPARkAAgMQARoAAgMRARsAAgMSARwAAgMTAR0AAgMUAR4AAgMVAR8AAgMWASAAAgMXASEAAgMYASIAAgMZASMAAgMaASQAAgMbASUAAgMcASYAAgMdAScAAgMeASgAAgMfASkAAgMgASoAAgMkASsAAgMlASwAAgMmAS0AAgMnAS4AAgMoAS8AAgMpATAAAgMqATEAAgMrATIAAgMsATMAAgMzATQAAgNBATUAAgM1ATYAAgM3ATgAAgM4ATkAAgM5AToAAgM6ATsAAgM7ATwAAgM8AT0AAgM9AT4AAgM+AT8AAgM/AUAAAgNAAUEAAgNCAUIAAgNDAUMAAgNEAUQAAgNFAUUAAgNGAUYAAgNRAUcAAgNUAUgAAgNVAUkAAgNWAUoAAgNdAUsAAgNXAUwAAgNYAU0AAgNZAU4AAgNaAU8AAgNbAVAAAgNcAVEAAgNdAVIAAgNeAVMAAgNfAVQAAgOFAVUAAgC6A5QAAgMhAVYAAgObAVcAAgOcAVgAAgOdAVkAAwDEA54BWgACA58BWwACA6EBXAACA6IBXQACA6MBXgACA6QBXwACA6UBYAACA6YBYQACA6cBYgACA6gBYwACA6kBZAACA6oBZQACA6sBZgACA6wBZwACA60BaAACA64BaQACA68BagACA7ABawACA7EBbAACA7IBbQACA7MBbgACA7QBbwACA7UBcAACA7YBcQACA7cBcgACA7gBcwACA7kBdAACA7oBdQACA7wBdgACA70BdwACA74BeAACA78BeQACA8ABegACA8IBewACA8MBfAACA8QBfQACA8UBfgACA8YBfwACA8cBgAACA8gBgQACA8kBggACA8oBgwACA8sBhAACA8wBhQACA80BhgACA84BhwACA88BiAACA9ABiQACAzYBNwADBGQC3wJ/AAIC4AKAAAIC4QKBAAIC4gKCAAIC4wKDAAIC5AKEAAIC5QKFAAIC5gKGAAIC5wKHAAIC6AKIAAIC6QKJAAIC6gKKAAIC6wKLAAIC7AKMAAIC7QKNAAIC7gKOAAIC7wKPAAIC8AKQAAIC8QKRAAIC8gKSAAIC8wKTAAIC9AKUAAIC9QKVAAIC9gKWAAIC9wKXAAIC+AKYAAIC+QKZAAIC+gKaAAIDCQKbAAIDCgKcAAIDCwKdAAIDDAKeAAIDDQKfAAIDDgKgAAIDDwKhAAIDEAKiAAIDEQKjAAIDEgKkAAIDEwKlAAIDFAKmAAIDFQKnAAIDFgKoAAIDFwKpAAIDGAKqAAIDGQKrAAIDGgKsAAIDGwKtAAIDHAKuAAIDHQKvAAIDHgKwAAIDHwKxAAIDIAKyAAIDIQKzAAIDJAK0AAMB3wHmAzMAAgHwA0UAAgNLArUAAgNMArYAAgNNArcAAgNOArgAAgNPArkAAgNQAroAAgNRArsAAgNSArwAAgNTAr0AAgRlA2AAAgOCAr4AAgJCA5QAAgObAr8AAgOcAsAAAgOdAsEAAwJMA54CwgACA58CwwACA6ACxAACA6ECxQACA6ICxgACA7wCxwACA70CyAACA74CyQACA78CygACA8ACywACA8ICzAACA8MCzQACA8QCzgACA8UCzwACA8cC0AACA8gC0QACA8kC0gACA8oC0wACA8sC1AACA8wC1QACA80C1gACA84C1wACA88C2AACA9AC2QACBNwE5AACBN0E7AACBN4E8QACBOIE4QACBX4FlgADBX8FlwWbAAIFggWfAAIFgwWgAAIFhAWiAAIFiAWYAAMFiQWZBaQAAgWOBacAAgWPBagABwXyBdQGEAYGBfwF3gXKAAcF8wXVBhEGBwX9Bd8FywAHBfQF1gYSBggF/gXgBcwABwX1BdcGEwYJBf8F4QXNAAcF9gXYBhQGCgYABeIFzgAHBfcF2QYVBgsGAQXjBc8ABwX4BdoGFgYMBgIF5AXQAAcF+QXbBhcGDQYDBeUF0QAHBfoF3AYYBg4GBAXmBdIABwX7Bd0GGQYPBgUF5wXTAAIFwAXoAAIFwQXpAAIFwgXqAAIFwwXrAAIFxAXsAAIFxQXtAAIFxgXuAAIFxwXvAAIFyAXwAAIFyQXxAAEFygABBcsAAQXMAAEFzQABBc4AAQXPAAEF0AABBdEAAQXSAAEF0wADBjsGOQY3AAIGGgY6AAIGYgZcAAIGYwZdAAIGZAZeAAIGZQZfAAIHJQdVAAIHJwdXAAIAKgAEAB8AAAApACkAHAAvAEYAHQBJAFEANQBYAGkAPgBuAG4AUAB3AIQAUQCpAKkAXwC4ALgAYAC/AN4AYQDgAOQAgQDmAPUAhgGKAaUAlgG0AcwAsgHPAc8AywHeAd4AzAHvAe8AzQH2Af4AzgIMAgwA1wIuAi4A2AJAAkAA2QJIAk8A2gJpAm0A4gJvAnIA5wJ0An0A6wRsBGwA9QR4BHgA9gSCBIIA9wSpBKkA+AUJBQkA+QUMBQwA+gUSBRQA+wUcBRwA/gUfBR8A/wUpBSoBAAXABdMBAgXeBfEBFgYmBiYBKgY0BjQBKwZSBlUBLAcGBwYBMAcJBwkBMQAGAAAABAAOACAAbgCAAAMAAAABACYAAQA+AAEAAAArAAMAAAABABQAAgAcACwAAQAAACsAAQACAd4B7wACAAIG/gcAAAAHAgcJAAMAAQAPBt8G4wblBucG6gbsBu0G7wbwBvIG9gb6BvsG/Ab9AAMAAQB+AAEAfgAAAAEAAAArAAMAAQASAAEAbAAAAAEAAAArAAIABAAEAYkAAARmBQUBhgW6BbsCJgW+Bb8CKAAGAAAAAgAKABwAAwAAAAEANAABACQAAQAAACsAAwABABIAAQAiAAAAAQAAACsAAgACBwoHJwAAB2YHbQAeAAIABgbfBuoAAAbsBu8ADAbyBvwAEAcGBwYAGwcIBwkAHAdeB2UAHgAEAAAAAQAIAAEBKgAPACQAPgBIAFIAZABuAHgAkgCsAMYA0ADaAOwA9gEQAAMACAAOABQG4AACBuUG4QACBucG4gACBvYAAQAEBuQAAgb2AAEABAbmAAIG9gACAAYADAboAAIG4wbpAAIG9gABAAQG7gACBuMAAQAEBvEAAgbnAAMACAAOABQG8wACBt8G9AACBucG9QACBvYAAwAIAA4AFAb3AAIG3wb4AAIG5Qb5AAIG5wADAAgADgAUBwsAAgcQBwwAAgcSBw0AAgceAAEABAcPAAIHHgABAAQHEQACBx4AAgAGAAwHEwACBw4HFAACBx4AAQAEBxgAAgcOAAMACAAOABQHGwACBwoHHAACBxIHHQACBx4AAwAIAA4AFAcfAAIHCgcgAAIHEAchAAIHEgABAA8G3wbjBuUG5wbtBvAG8gb2BwoHDgcQBxIHFwcaBx4ABAAAAAEACAABAJYABAAOADAAUgB0AAQACgAQABYAHAdjAAIG5QdiAAIG5wdlAAIG8gdkAAIG+gAEAAoAEAAWABwHXwACBuUHXgACBucHYQACBvIHYAACBvoABAAKABAAFgAcB2sAAgcQB2oAAgcSB20AAgcaB2wAAgciAAQACgAQABYAHAdnAAIHEAdmAAIHEgdpAAIHGgdoAAIHIgABAAQG7AbvBxYHGQAEAAAAAQAIAAEAHgACAAoAFAABAAQA9QACAGgAAQAEAn4AAgHvAAEAAgBaAeAABgAAAAIACgAkAAMAAQAUAAEALgABABQAAQAAACsAAQABAfYAAwABABoAAQAUAAEAGgABAAAALAABAAEGJgABAAEAbQABAAAAAQAIAAIADgAEALoAxAJCAkwAAQAEALgAwwJAAksAAQAAAAEACAABAAYACAABAAEB3gABAAAAAQAIAAIANAAXBNwE3QTeBX0FfgV/BYAFgQWCBYMFhAWFBYYFhwWIBYkFigWLBYwFjQWOBY8FkAABABcEbAR4BIIFCAUJBQwFEAURBRIFEwUUBRYFGAUaBRwFHwUkBSUFJgUnBSkFKgU1AAEAAAABAAgAAQAGAIoAAQABBQoAAQAAAAEACAACABAABQWVBZYFlwWYBZkAAQAFBQcFCQUMBRwFHwABAAAAAQAIAAIACgACBOIFkwABAAIEqQVJAAEAAAABAAgAAgAQAAUE3wTgBOEFkQWSAAEABQScBJ8EqQU8BT8AAQAAAAEACAABANAAMgABAAAAAQAIAAEAwgAUAAEAAAABAAgAAQC0AFAAAQAAAAEACAABAKYAPAABAAAAAQAIAAEABv/mAAEAAQY0AAEAAAABAAgAAQCEAEYABgAAAAIACgAiAAMAAQASAAEANAAAAAEAAAAsAAEAAQYaAAMAAQASAAEAHAAAAAEAAAAsAAIAAQX8BgUAAAACAAEGBgYPAAAABgAAAAIACgAkAAMAAQAsAAEAEgAAAAEAAAAsAAEAAgAEAYoAAwABABIAAQAcAAAAAQAAACwAAgABBcAFyQAAAAEAAgCEAgwABAAAAAEACAABABQAAQAIAAEABAbYAAMCDAYuAAEAAQB5AAEAAAABAAgAAQAG//YAAgABBcoF0wAAAAEAAAABAAgAAQAG/+IAAgABBd4F8QAAAAEAAAABAAgAAQAGAB4AAgABBcAF0wAAAAEAAAABAAgAAQAGAAoAAgACBcAFyQAABd4F5wAKAAEAAAABAAgAAgIUAQcC3wLgAuEC4gLjAuQC5QLmAucC6ALpAuoC6wLsAu0C7gLvAvAC8QLyAvMC9AL1AvYC9wL4AvkC+gL7AvwC/QL+Av8DAAMBAwIDAwMJAwQDBQMGAwcDCAMJAwoDCwMMAw0DDgMPAxADEQMSAxMDFAMVAxYDFwMYAxkDGgMbAxwDHQMeAx8DIAMiAyMDJAMlAyYDJwMoAykDKgMrAywDLQMuAy8DMAMxAzIDMwNBAzUDNwM4AzkDOgM7AzwDPQM+Az8DQANCA0MDRANFA0YDRwNIA0kDSwNRA0wDTQNOA08DUANRA1IDUwNUA1UDVgNdA1cDWANZA1oDWwNcA10DXgNfA2ADYQNiA2MDZANlA2YDZwNoA2kDagNrA2wDbQNuA28DcANxA3IDcwN0A3UDdgN3A3gDeQN6A3sDfAN9A34DfwOAA4EDggODA4QDhQOGA4cDiAOJA4oDiwOMA40DjgOPA5ADkQOSA5MDlAOVA5YDlwOYA5kDmgMhA5sDnAOdA54DnwOhA6IDowOkA6UDpgOnA6gDqQOqA6sDrAOtA64DrwOwA7EDsgOzA7QDtQO2A7cDuAO5A7oDuwO8A70DvgO/A8ADwQPCA8MDxAPFA8YDxwPIA8kDygPLA8wDzQPOA88D0AM2BmAGYQZmBmcGaAZpBnAGYgZjBmQGZQZqBmsGbAZtBm4GbwbeB1UHVgdXAAIABwAEAPUAAAYrBiwA8gYuBjIA9AZSBlsA+QbLBssBAwcGBwcBBAcJBwkBBgABAAAAAQAIAAICFAEHAt8C4ALhAuIC4wLkAuUC5gLnAugC6QLqAusC7ALtAu4C7wLwAvEC8gLzAvQC9QL2AvcC+AL5AvoC+wL8Av0C/gL/AwADAQMCAwMDBAMFAwYDBwMIAwkDCgMLAwwDDQMOAw8DEAMRAxIDEwMUAxUDFgMXAxgDGQMaAxsDHAMdAx4DHwMgAyEDIgMjAyQDJQMmAycDKAMpAyoDKwMsAy0DLgMvAzADMQMyAzMDNAM1AzcDOAM5AzoDOwM8Az0DPgM/A0ADQQNCA0MDRANFA0YDRwNIA0kDSgNLA0wDTQNOA08DUANRA1IDUwNUA1UDVgNXA1gDWQNaA1sDXANdA14DXwNgA2EDYgNjA2QDZQNmA2cDaANpA2oDawNsA20DbgNvA3ADcQNyA3MDdAN1A3YDdwN4A3kDegN7A3wDfQN+A38DgAOBA4IDgwOEA4UDhgOHA4gDiQOKA4sDjAONA44DjwOQA5EDkgOTA5QDlQOWA5cDmAOZA5oDmwOcA50DngOfA6ADoQOiA6MDpAOlA6YDpwOoA6kDqgOrA6wDrQOuA68DsAOxA7IDswO0A7UDtgO3A7gDuQO6A7sDvAO9A74DvwPAA8EDwgPDA8QDxQPGA8cDyAPJA8oDywPMA80DzgPPA9ADNgZgBmEGZgZnBmgGaQZwBmIGYwZkBmUGagZrBmwGbQZuBm8G3gdVB1YHVwACAAoBigHvAAAB8QICAGYCBAJGAHgCSAJ+ALsGKwYsAPIGLgYyAPQGUgZbAPkGywbLAQMHBgcHAQQHCQcJAQYAAQAAAAEACAACAIAAPQY2BjcGOAY6BjkGQgZDBkQGRQZGBkcGTwZQBlEGXAZdBl4GXwa5BroGuwa8BtwHCgcLBwwHDQcOBw8HEAcRBxIHEwcUBxUHFgcXBxgHGQcaBxsHHAcdBx4HHwcgByEHIgcjByQHJQcmBycHZgdnB2gHaQdqB2sHbAdtAAIAEQYlBicAAAY0BjQAAwY7BkEABAZIBkkACwZMBkwADQZSBlUADgavBq8AEgaxBrEAEwazBrMAFAa1BrUAFQbKBsoAFgbfBuoAFwbsBu8AIwbyBvwAJwcGBwYAMgcIBwkAMwdeB2UANQAEAAAAAQAIAAEAEgABAAgAAQAEAtoAAgHYAAEAAQDAAAQAAAABAAgAAQAaAAEACAACAAYADALbAAIB3gLcAAIB9gABAAEBzwABAAAAAQAIAAIDlgHIAPYA9wD4APkA+gD7APwA/QD+AP8BAAEBAQIBAwEEAQUBBgEHAQgBCQEKAQsBDAENAQ4BDwEQAREBEgETARQBFQEWARcBGAEZARoBGwEcAR0BHgEfASABIQEiASMBJAElASYBJwEoASkBKgErASwBLQEuAS8BMAExATIBMwE0ATUBNgE4ATkBOgE7ATwBPQE+AT8BQAFBAUIBQwFEAUUBRgFHAUgBSQFKAUsBTAFNAU4BTwFQAVEBUgFTAVQBVQFWAVcBWAFZAVoBWwFcAV0BXgFfAWABYQFiAWMBZAFlAWYBZwFoAWkBagFrAWwBbQFuAW8BcAFxAXIBcwF0AXUBdgF3AXgBeQF6AXsBfAF9AX4BfwGAAYEBggGDAYQBhQGGAYcBiAGJATcCfwKAAoECggKDAoQChQKGAocCiAKJAooCiwKMAo0CjgKPApACkQKSApMClAKVApYClwKYApkCmgKbApwCnQKeAp8CoAKhAqICowKkAqUCpgKnAqgCqQKqAqsCrAKtAq4CrwKwArECsgKzArQCtQK2ArcCuAK5AroCuwK8Ar0CvgK/AsACwQLCAsMCxALFAsYCxwLIAskCygLLAswCzQLOAs8C0ALRAtIC0wLUAtUC1gLXAtgC2QLdAt4D0QPSA9MD1APVA9YD1wPYA9kD2gPbA9wD3QPeA98D4APhA+ID4wPkA+UD5gPnA+gD6QPqA+sD7APtA+4D7wPwA/ED8gPzA/QD9QP2A/cD+AP5A/oD+wP8A/0D/gP/BAAEAQQCBAMEBAQFBAYEBwQIBAkECgQLBAwEDQQOBA8EEAQRBBIEEwQUBBUEFgQXBBgEGQQaBBsEHAQdBB4EHwQgBCEEIgQjBCQEJQQmBCcEKAQpBCoEKwQsBC0ELgQvBDAEMQQyBDMENAQ1BDYENwQ4BDkEOgQ7BDwEPQQ+BD8EQARBBEIEQwREBEUERgRHBEgESQRKBEsETARNBE4ETwRQBFEEUgRTBFQEVQRWBFcEWARZBFoEWwRcBF0EXgRfBGAEYQRiBGME4wTkBOUE5gTnBOgE6QTrBOoE7ATtBO4E7wTwBPEE8gTzBPQE9QT2BPcE+AT5BPoE+wT8BP0E/gT/BQAFAQUCBQMFBAUFBZoFmwWcBZ0FngWfBaAFogWhBaMFpAWlBaYFpwWoBakFqgWrBawFrQWuBa8FsAWxBbIFswW0BbUFtgW3BbgFuQbdAAIAPQAEAB8AAAApACkAHAAvAEYAHQBJAFEANQBYAGkAPgBuAG4AUAB3AIMAUQCpAKkAXgC/AN4AXwDgAOQAfwDmAPUAhAGKAaUAlAG0AcwAsAHPAc8AyQH2Af4AygIuAi4A0wJIAk8A1AJpAm0A3AJvAnIA4QJ0An0A5QLbAtwA7wLfAvoA8QMJAyEBDQMkAywBJgMzAzsBLwM9A0YBOANRA1EBQgNUA18BQwOFA4UBTwObA7oBUAO8A8ABcAPCA9ABdQRmBGYBhARsBG8BhQRyBHUBiQR4BHgBjQR9BH0BjgR/BIIBjwSJBI0BkwSTBJMBmASYBJgBmQSqBKoBmgS8BL8BmwTFBMYBnwTLBM0BoQTQBNABpATWBNYBpQTYBNgBpgUGBQYBpwUMBQ8BqAUSBRUBrAUdBR0BsAUfBSEBsQUpBS0BtAU4BTgBuQVdBWIBugVmBWcBwAVsBW4BwgVxBXEBxQV5BXkBxgbYBtgBxwABAAAAAQAIAAIAWAApAd8B8AY7BwoHCwcMBw0HDgcPBxAHEQcSBxMHFAcVBxYHFwcYBxkHGgcbBxwHHQceBx8HIAchByIHIwckByUHJgcnB2YHZwdoB2kHagdrB2wHbQACAAkB3gHeAAAB7wHvAAEGJgYmAAIG3wbqAAMG7AbvAA8G8gb8ABMHBgcGAB4HCAcJAB8HXgdlACEAAQAAAAEACAACACQADwRkBGUEZARlBfwF/QX+Bf8GAAYBBgIGAwYEBgUGOQABAA8ABACEAYoCDAYGBgcGCAYJBgoGCwYMBg0GDgYPBiYAAA==) format("truetype")}@font-face{font-weight:normal;font-family:"tick42-icons";font-style:normal;src:url(data:font/ttf;base64,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YGAGCAcGqgJK/bYCgP1KJhsaARscJQK2JhsaARscJQAAAQAAAAEAAH2fuHdfDzz1AAsEAAAAAADhVnMIAAAAAOFWcwj//f+9BQADwwAAAAgAAgAAAAAAAAABAAADwP/AAAAFJP/9//0FAAABAAAAAAAAAAAAAAAAAAAA9wQAAAAAAAAAAAAAAAIAAAAEAAAABAAAAAO2//8ESQAAA24AAANuAAACkf//A24AAAO2//8CSQAABAAAAAO2//8CAAAAAmYAAALNAAACHwAAAmYAAAJmAAACqwAAAeEAAAOFAAADhQAAA24AAAQAAAAEkf//AyQAAANWAAACZgAAAOEAAAJIAAADrgAAAysAAAOaAAAEAAAAA24AAAQAAAAEAAAABAAAAAQAAAAEAP/9A24AAAQAAAADWAAAAyQAAANuAAADbgAAA24AAAQAAAADtgAAAbYAAAQAAAAEAAAAA24AAANuAAADbgAAA24AAAQAAAAEAAAABAAAAAQAAAAEAQAABAAAAAQAAAAEAAAAApH//wQA//0EAAAABAD//QQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAAA24AAAO2AAAEAAAAA7b//wMkAAADJAAAAyQAAAQAAAAEAAAAA24AAANuAAADtgAAA7YAAAMkAAADtv//BAAAAAQAAAADbgAABEkAAALbAAADtv//A7b//wQAAAACSQAAAkkAAAFuAAABbgAAAtsAAAQAAAAC2wAABAAAAAO2AAADbgAAA24AAAO2AAADtgAAA7YAAANHAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAADJAAAAtsAAAMkAAADbgAABAAAAANuAAADtv//A7b//wJJAAACSQAAAkkAAAQAAAAEAAAABAAAAAQAAAAESQAABEkAAAQAAAAEAAAAA24AAANuAAACSQAAAkkAAAKRAAACkQAAAW4AAAFuAAACkQAAApEAAARJAAADbgAAA7b//wO2//8EAAAAA24AAAQAAAADtv//BEkAAAO2AAAESQAABAAAAAMkAAACSQAAA7b//wJJAAABbgAAAW4AAAKR//8DJAAAA7b//wKR//8DJAAAANsAAANuAAADbgAAA24AAANuAAACSQAAAkkAAANuAAADtgAAA7YAAAQAAAAEAAAAA24AAANuAAABtgAAAbYAAAQAAAAEAAAABAAAAAUkAAADbgAAA24AAANuAAADbgAAA24AAANuAAADbgAAA24AAANuAAADbgAAA24AAANuAAADbgAABJEAAASRAAAEkQAAA24AAASR//8Ekf//BJH//wSR//8Ekf//BJEAAAQAAAADbgAAA24AAANuAAADbgAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAO2//8DbgAABAAAAAQAAAAEkf//BAAAAAQAAAAAAAAAAAoAFAAeAQgBbAHkAk4DIgP+BEIIOAj2CTQJjAosCkoKZAqCCqQK0Ar8CyoLZguaC9IMNAzEDPINnA4gDl4OfA6wDvoPGg84D2wP0hAGEFQQhBD0EfgSOBJ8Ep4TVhO4FBoUYBXAFioWbBaqFzAXdBfiGFAY1hmWGpYcAhx2HQIdih64IAQgZiFGIhQjcCRuJKwk3iU4JbwmBCYeJjgmuCc6J9IoKihsKJAo0ikCKbIqQiq2KxYr0Cw+LIws+i2gLeguWi6SLxgvoC/8MCAwRjBqMI4wvjDuMRwxTDGIMcQyADI8MqIzGjNgM8o0HjR6NMg1fjbONx43Xjd8OFg4zjlcOdQ6SjrEOwY7SDtyO+Q8VDywPcA+Aj5EPmg+jD8GP5A/+kBUQLRBFEFcQcxCZELCQxRDZkO4RApEOERmRJREwkUkRXJF8EZuRzJHXEe4SAxIiEjQSURJrkniSppLiEv+TFRMlE0ITZpOFk5gTrhPEE9QT5xP7FBEUPZRyFH+UnxS/FOWVDBUyFViVY5VulXoVhZWXFbcV2pYSljeWWxZ4FpIWuJbjlwGXLZdEF2SXeBejF8OX7JgXGB6YLphSmG2YlJi7GNaY/xkdmTkZXRmKGbCZ3poHmiSaWBqSGsga6Zr1Gv4bERspm0SAAEAAAD3As4ADwAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAOAK4AAQAAAAAAAQAMAAAAAQAAAAAAAgAHAI0AAQAAAAAAAwAMAEUAAQAAAAAABAAMAKIAAQAAAAAABQALACQAAQAAAAAABgAMAGkAAQAAAAAACgAaAMYAAwABBAkAAQAYAAwAAwABBAkAAgAOAJQAAwABBAkAAwAYAFEAAwABBAkABAAYAK4AAwABBAkABQAWAC8AAwABBAkABgAYAHUAAwABBAkACgA0AOB0aWNrNDItaWNvbnMAdABpAGMAawA0ADIALQBpAGMAbwBuAHNWZXJzaW9uIDEuMABWAGUAcgBzAGkAbwBuACAAMQAuADB0aWNrNDItaWNvbnMAdABpAGMAawA0ADIALQBpAGMAbwBuAHN0aWNrNDItaWNvbnMAdABpAGMAawA0ADIALQBpAGMAbwBuAHNSZWd1bGFyAFIAZQBnAHUAbABhAHJ0aWNrNDItaWNvbnMAdABpAGMAawA0ADIALQBpAGMAbwBuAHNGb250IGdlbmVyYXRlZCBieSBJY29Nb29uLgBGAG8AbgB0ACAAZwBlAG4AZQByAGEAdABlAGQAIABiAHkAIABJAGMAbwBNAG8AbwBuAC4AAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA) format("truetype")}[class^="icon-"],[class*=" icon-"]{font-weight:normal;font-family:"tick42-icons";font-style:normal;font-variant:normal;line-height:1;text-transform:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.tick42-custom-icon i{color:var(--t42-link-color)}.tick42-custom-icon img{display:block}.tick42-custom-icon.disabled i,.tick42-custom-icon:disabled i{color:var(--t42-content-color-disabled)}i.disabled,.disabled i{color:var(--t42-content-color-disabled)}.icon-size-12 i{font-size:0.75rem}.icon-size-12 i,.icon-size-12 img{width:0.75rem;height:0.75rem}.icon-size-14 i{font-size:0.875rem}.icon-size-14 i,.icon-size-14 img{width:0.875rem;height:0.875rem}.icon-size-24 i{font-size:1.5rem}.icon-size-24 i,.icon-size-24 img{width:1.5rem;height:1.5rem}.icon-size-16 i,.icon-size-16 img{width:1rem;height:1rem}.icon-size-16 i{font-size:1rem}.icon-size-32 i,.icon-size-32 img{width:2rem;height:2rem}.icon-size-32 i{font-size:2rem}.icon-size-48 i,.icon-size-48 img{width:3rem;height:3rem}.icon-size-48 i{font-size:3rem}.icon-size-64 i,.icon-size-64 img{width:4rem;height:4rem}.icon-size-64 i{font-size:4rem}.icon-size-80 i,.icon-size-80 img{width:5rem;height:5rem}.icon-size-80 i{font-size:5rem}.icon-size-96 i,.icon-size-96 img{width:6rem;height:6rem}.icon-size-96 i{font-size:6rem}.icon-size-112 i,.icon-size-112 img{width:7rem;height:7rem}.icon-size-112 i{font-size:7rem}.icon-size-128 i,.icon-size-128 img{width:8rem;height:8rem}.icon-size-128 i{font-size:8rem}.icon-primary i::before{color:#007be5}.icon-secondary i::before{color:#616161}.icon-success i::before{color:#43a047}.icon-info i::before{color:#469eb9}.icon-warning i::before{color:#f9a825}.icon-danger i::before{color:#ff511f}.icon-light i::before{color:#616161}.icon-dark i::before{color:#616161}.icon-dev-tools::before{content:"\e901"}.icon-interop::before{content:"\e900"}.icon-mail::before{content:"\e800"}.icon-attention::before{content:"\e801"}.icon-print::before{content:"\e802"}.icon-picture::before{content:"\e803"}.icon-thumbs-up::before{content:"\e804"}.icon-thumbs-down::before{content:"\e805"}.icon-lock::before{content:"\e806"}.icon-globe::before{content:"\e807"}.icon-calendar::before{content:"\e808"}.icon-location::before{content:"\e809"}.icon-briefcase::before{content:"\e80a"}.icon-export::before{content:"\e80b"}.icon-play::before{content:"\e80c"}.icon-stop::before{content:"\e80d"}.icon-record::before{content:"\e80e"}.icon-pause::before{content:"\e80f"}.icon-to-end::before{content:"\e810"}.icon-to-start::before{content:"\e811"}.icon-check::before{content:"\e812"}.icon-cancel::before{content:"\e813"}.icon-fast-forward::before{content:"\e814"}.icon-fast-backward::before{content:"\e815"}.icon-attention-circled::before{content:"\e816"}.icon-bell::before{content:"\e817"}.icon-chart-bar::before{content:"\e818"}.icon-phone::before{content:"\e819"}.icon-doc-add::before{content:"\e81a"}.icon-layout::before{content:"\e81b"}.icon-dot::before{content:"\e81c"}.icon-dot-2::before{content:"\e81d"}.icon-dot-3::before{content:"\e81e"}.icon-resize-full-1::before{content:"\e81f"}.icon-resize-small-1::before{content:"\e820"}.icon-checkbox::before{content:"\e821"}.icon-cancel-circled::before{content:"\e822"}.icon-03-context-viewer::before{content:"\e823"}.icon-volume-off-1::before{content:"\e824"}.icon-volume::before{content:"\e825"}.icon-headphones-1::before{content:"\e826"}.icon-performance-report::before{content:"\e827"}.icon-pause-1::before{content:"\e828"}.icon-volume-up-1::before{content:"\e829"}.icon-volume-down-1::before{content:"\e82a"}.icon-trash-empty::before{content:"\e839"}.icon-resize-small::before{content:"\e83b"}.icon-resize-full::before{content:"\e83c"}.icon-doc::before{content:"\e83d"}.icon-cog::before{content:"\e83e"}.icon-wrench::before{content:"\e83f"}.icon-resize-vertical::before{content:"\e840"}.icon-resize-horizontal::before{content:"\e841"}.icon-edit::before{content:"\e842"}.icon-pencil-1::before{content:"\e843"}.icon-cw-2::before{content:"\e844"}.icon-ccw-1::before{content:"\e845"}.icon-arrows-cw-1::before{content:"\e847"}.icon-th-large::before{content:"\e848"}.icon-th::before{content:"\e849"}.icon-spin5::before{content:"\e84a"}.icon-spin6::before{content:"\e84b"}.icon-spin4::before{content:"\e84c"}.icon-spin3::before{content:"\e84d"}.icon-spin2::before{content:"\e84e"}.icon-spin1::before{content:"\e84f"}.icon-pin::before{content:"\e850"}.icon-trading-controls::before{content:"\e856"}.icon-icon-coverage::before{content:"\e857"}.icon-taxes::before{content:"\e858"}.icon-credit::before{content:"\e859"}.icon-checkbox-checked::before{content:"\e85a"}.icon-checkbox-indeterminate::before{content:"\e85b"}.icon-radio::before{content:"\e85c"}.icon-radio-choose::before{content:"\e85d"}.icon-arrow-up-down::before{content:"\e85e"}.icon-arrow-double-left::before{content:"\e85f"}.icon-arrow-double-right::before{content:"\e860"}.icon-floppy::before{content:"\e861"}.icon-logout::before{content:"\e862"}.icon-mail-1::before{content:"\e864"}.icon-search-1::before{content:"\e865"}.icon-plus-1::before{content:"\e866"}.icon-minus-1::before{content:"\e867"}.icon-cancel-1::before{content:"\e868"}.icon-ok::before{content:"\e869"}.icon-th-list::before{content:"\e86a"}.icon-help-circled::before{content:"\e86b"}.icon-info-circled::before{content:"\e86c"}.icon-home::before{content:"\e86d"}.icon-link-1::before{content:"\e86e"}.icon-attach-1::before{content:"\e86f"}.icon-lock-open-1::before{content:"\e870"}.icon-eye::before{content:"\e871"}.icon-eye-off::before{content:"\e872"}.icon-tag::before{content:"\e873"}.icon-tags::before{content:"\e874"}.icon-bookmark::before{content:"\e875"}.icon-download-1::before{content:"\e876"}.icon-upload-1::before{content:"\e877"}.icon-forward-1::before{content:"\e878"}.icon-down-dir::before{content:"\e879"}.icon-up-dir::before{content:"\e87a"}.icon-left-dir::before{content:"\e87b"}.icon-right-dir::before{content:"\e87c"}.icon-left-open-1::before{content:"\e87d"}.icon-down-open-1::before{content:"\e87e"}.icon-right-open-1::before{content:"\e87f"}.icon-up-open-1::before{content:"\e880"}.icon-down-big::before{content:"\e881"}.icon-left-big::before{content:"\e882"}.icon-right-big::before{content:"\e883"}.icon-up-big::before{content:"\e884"}.icon-asterisk::before{content:"\e885"}.icon-check-1::before{content:"\e886"}.icon-tick42-icon-monochrome::before{content:"\e887"}.icon-task-manager::before{content:"\e888"}.icon-context-viewer::before{content:"\e889"}.icon-help-2::before{content:"\e88a"}.icon-star-empty-1::before{content:"\e88b"}.icon-star-full::before{content:"\e902"}.icon-move::before{content:"\f047"}.icon-link-ext::before{content:"\f08e"}.icon-check-empty::before{content:"\f096"}.icon-bookmark-empty::before{content:"\f097"}.icon-filter::before{content:"\f0b0"}.icon-resize-full-alt::before{content:"\f0b2"}.icon-docs::before{content:"\f0c5"}.icon-menu-1::before{content:"\f0c9"}.icon-table::before{content:"\f0ce"}.icon-columns::before{content:"\f0db"}.icon-sort::before{content:"\f0dc"}.icon-sort-down::before{content:"\f0dd"}.icon-sort-up::before{content:"\f0de"}.icon-mail-alt::before{content:"\f0e0"}.icon-sitemap::before{content:"\f0e8"}.icon-paste::before{content:"\f0ea"}.icon-exchange::before{content:"\f0ec"}.icon-download-cloud::before{content:"\f0ed"}.icon-upload-cloud::before{content:"\f0ee"}.icon-suitcase-1::before{content:"\f0f2"}.icon-bell-alt::before{content:"\f0f3"}.icon-doc-text-1::before{content:"\f0f6"}.icon-plus-squared::before{content:"\f0fe"}.icon-angle-double-left::before{content:"\f100"}.icon-angle-double-right::before{content:"\f101"}.icon-angle-double-up::before{content:"\f102"}.icon-angle-double-down::before{content:"\f103"}.icon-angle-left::before{content:"\f104"}.icon-angle-right::before{content:"\f105"}.icon-angle-up::before{content:"\f106"}.icon-angle-down::before{content:"\f107"}.icon-laptop::before{content:"\f109"}.icon-circle-empty::before{content:"\f10c"}.icon-quote-left::before{content:"\f10d"}.icon-quote-right::before{content:"\f10e"}.icon-spinner::before{content:"\f110"}.icon-circle::before{content:"\f111"}.icon-reply-1::before{content:"\f112"}.icon-folder-empty::before{content:"\f114"}.icon-folder-open-empty::before{content:"\f115"}.icon-terminal::before{content:"\f120"}.icon-code::before{content:"\f121"}.icon-reply-all-1::before{content:"\f122"}.icon-direction::before{content:"\f124"}.icon-fork::before{content:"\f126"}.icon-unlink::before{content:"\f127"}.icon-help::before{content:"\f128"}.icon-info::before{content:"\f129"}.icon-attention-alt::before{content:"\f12a"}.icon-mic::before{content:"\f130"}.icon-mute::before{content:"\f131"}.icon-calendar-empty::before{content:"\f133"}.icon-lock-open-alt::before{content:"\f13e"}.icon-ellipsis::before{content:"\f141"}.icon-ellipsis-vert::before{content:"\f142"}.icon-minus-squared::before{content:"\f146"}.icon-ok-squared::before{content:"\f14a"}.icon-link-ext-alt::before{content:"\f14c"}.icon-expand-right::before{content:"\f152"}.icon-euro::before{content:"\f153"}.icon-dollar::before{content:"\f155"}.icon-doc-inv::before{content:"\f15b"}.icon-sort-name-up::before{content:"\f15d"}.icon-sort-name-down::before{content:"\f15e"}.icon-sort-alt-up::before{content:"\f160"}.icon-sort-alt-down::before{content:"\f161"}.icon-sort-number-up::before{content:"\f162"}.icon-sort-number-down::before{content:"\f163"}.icon-down::before{content:"\f175"}.icon-up::before{content:"\f176"}.icon-left::before{content:"\f177"}.icon-right::before{content:"\f178"}.icon-cube::before{content:"\f1b2"}.icon-cubes::before{content:"\f1b3"}.icon-database::before{content:"\f1c0"}.icon-file-pdf::before{content:"\f1c1"}.icon-file-word::before{content:"\f1c2"}.icon-file-excel::before{content:"\f1c3"}.icon-file-powerpoint::before{content:"\f1c4"}.icon-file-image::before{content:"\f1c5"}.icon-file-archive::before{content:"\f1c6"}.icon-file-audio::before{content:"\f1c7"}.icon-file-video::before{content:"\f1c8"}.icon-file-code::before{content:"\f1c9"}.icon-circle-thin::before{content:"\f1db"}.icon-sliders::before{content:"\f1de"}.icon-share::before{content:"\f1e0"}.icon-wifi::before{content:"\f1eb"}.icon-bell-off::before{content:"\f1f6"}.icon-bell-off-empty::before{content:"\f1f7"}.icon-copyright::before{content:"\f1f9"}.icon-chart-area::before{content:"\f1fe"}.icon-chart-line::before{content:"\f201"}.icon-toggle-off::before{content:"\f204"}.icon-toggle-on::before{content:"\f205"}.icon-user-plus::before{content:"\f234"}.icon-user-times::before{content:"\f235"}.icon-clone::before{content:"\f24d"}.icon-hourglass-o::before{content:"\f250"}.icon-hourglass-1::before{content:"\f251"}.icon-hourglass-2::before{content:"\f252"}.icon-hourglass-3::before{content:"\f253"}.icon-calendar-plus-o::before{content:"\f271"}.icon-calendar-minus-o::before{content:"\f272"}.icon-calendar-times-o::before{content:"\f273"}.icon-calendar-check-o::before{content:"\f274"}.icon-hashtag::before{content:"\f292"}.icon-low-vision::before{content:"\f2a8"}.icon-envelope-open-o::before{content:"\f2b7"}.icon-address-book-o::before{content:"\f2ba"}.icon-user-o::before{content:"\f2c0"}.icon-window-maximize::before{content:"\f2d0"}.icon-window-minimize::before{content:"\f2d1"}.icon-window-restore::before{content:"\f2d2"}.icon-window-close::before{content:"\f2d3"}.icon-window-close-o::before{content:"\f2d4"}.icon-app::before{content:"\e903"}.icon-download-arrow::before{content:"\e904"}.icon-logo::before{content:"\e905"}.icon-feedback::before{content:"\e906"}.icon-action::before{content:"\e907"}.icon-swimlane::before{content:"\e908"}div.ag-dnd-ghost{border-color:transparent;border-radius:0.25rem;color:var(--white);font-size:0.75rem;font-family:inherit;line-height:inherit;background-color:var(--primary);cursor:default}div .ag-dnd-ghost-icon{display:flex;float:none;padding:0 0.25rem 0 0}div .ag-dnd-ghost-icon .ag-icon{background-color:var(--white)}.ag-tick42{padding-top:0}.ag-tick42 a{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border;border-bottom:0.063rem dashed var(--dark);color:var(--t42-content-color)}.ag-tick42 a:hover{text-decoration:none}.ag-tick42 .ag-filter-body{margin:0}.ag-tick42 input{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border;padding:0 0.5rem;border:var(--t42-border);color:var(--t42-content-color);line-height:2rem;background-color:var(--t42-input-bg)}.ag-tick42 input:focus{border-color:var(--primary);outline:0}.ag-tick42 input.ag-column-name-filter{margin-left:0.5rem}.ag-tick42 .ag-input-wrapper{padding:0.25rem}.ag-tick42 .ag-input-wrapper.ag-checkbox-input-wrapper{padding:0}.ag-tick42 .ag-cell-wrapper.ag-row-group{align-items:center}.ag-tick42 .ag-cell{padding:0 0.25rem;border-bottom:var(--t42-border);line-height:1.875rem;white-space:nowrap;text-overflow:ellipsis}.ag-tick42 .ag-cell .btn,.ag-tick42 .ag-cell .btn-sm,.ag-tick42 .ag-cell .btn-group-sm>.btn,.ag-tick42 .ag-cell .btn-lg,.ag-tick42 .ag-cell .btn-group-lg>.btn{line-height:1.25rem}.ag-tick42 .ag-cell .btn-icon i{position:relative;top:0.0625rem}.ag-tick42 .ag-cell:focus{outline:1px solid var(--primary)}.ag-tick42 .ag-cell .dropdown-toggle{width:20px;height:20px;margin-top:-3px;padding:0;border:0;line-height:22px}.ag-tick42 .ag-cell .dropdown-toggle::after{background-color:transparent;content:""}.ag-tick42 .ag-row::before{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:width;position:absolute;top:0;bottom:0;left:0;z-index:1;width:0;background-color:var(--primary);content:""}.ag-tick42 .ag-row.ag-row-selected{color:var(--t42-link-color);background-color:var(--t42-color-opacity-10)}.ag-tick42 .ag-row.ag-row-selected .ag-icon{color:var(--t42-link-color)}.ag-tick42 .ag-pinned-left-header,.ag-tick42 .ag-pinned-left-cols-container,.ag-tick42 .ag-pinned-right-header,.ag-tick42 .ag-pinned-right-cols-container{background-color:Rgb(var(--t42-bg-mid))}.ag-tick42 .ag-pinned-left-cols-container .ag-row-selected::before,.ag-tick42 .ag-pinned-left-cols-container.ag-hidden+.ag-center-cols-clipper .ag-row-selected::before{width:2px}.ag-tick42 .ag-row-hover{background-color:var(--t42-color-opacity-10)}.ag-tick42 .ag-row-hover .ag-cell{color:var(--t42-link-color)}.ag-tick42 .ag-row-hover .ag-loading .ag-icon-loading::after{background:Rgb(var(--t42-bg-light))}.ag-tick42 .ag-row-hover a{border-bottom-color:var(--t42-content-color);color:var(--t42-link-color)}.ag-tick42 .ag-row-hover a:hover{border-bottom-style:solid}.ag-tick42 .ag-header-row:last-of-type{border-bottom:var(--t42-border)}.ag-tick42 .ag-header-cell,.ag-tick42 .ag-header-group-cell{padding:0 0.25rem;border-top:var(--t42-border);border-left:var(--t42-border);color:Hsl(var(--t42-content-color-base), calc(var(--t42-content-color-l) - 20%))}.ag-tick42 .ag-header-cell:first-of-type,.ag-tick42 .ag-header-group-cell:first-of-type{border-left:0}.ag-tick42 .ag-header-cell .ag-header-cell-label,.ag-tick42 .ag-header-cell .ag-header-group-cell-label,.ag-tick42 .ag-header-group-cell .ag-header-cell-label,.ag-tick42 .ag-header-group-cell .ag-header-group-cell-label{font-weight:normal;font-size:83.3%;line-height:1.875rem;text-transform:uppercase}.ag-tick42 .ag-header-cell .ag-header-select-all,.ag-tick42 .ag-header-group-cell .ag-header-select-all{margin-right:0.5rem}.ag-tick42 .ag-header-cell-moving{background-color:Hsl(var(--t42-bg-light-base), calc(var(--t42-bg-light-l) + 5%))}.ag-tick42 .ag-cell-inline-editing{padding-top:0}.ag-tick42 .ag-cell-edit-input{border-top:0;border-bottom:0;border-radius:0}.ag-tick42 .ag-icon{font-family:inherit}.ag-tick42 .ag-icon::before{content:""}.ag-tick42 .ag-react-container .btn-icon{margin-bottom:0.125rem;padding:0 0.5rem}.ag-tick42 .ag-tabs-header{display:flex;height:1.875rem;border-bottom:var(--t42-border);border-bottom-width:0.063rem}.ag-tick42 .ag-tabs-header .ag-tab{display:flex;align-items:center;justify-content:center;width:1.875rem;height:1.875rem;color:var(--primary);cursor:pointer}.ag-tick42 .ag-tabs-header .ag-tab.ag-tab-selected{background-color:var(--primary)}.ag-tick42 .ag-tabs-header .ag-tab.ag-tab-selected .ag-icon{background-color:var(--white)}.ag-tick42 .ag-tabs-body{max-height:280px;overflow:auto}.ag-tick42 .ag-menu,.ag-tick42 .ag-tool-panel{z-index:1040;border:var(--t42-border);border-radius:0;overflow:initial;background-color:rgba(var(--t42-bg-light), 0.75);box-shadow:var(--t42-shadow);backdrop-filter:var(--backdrop-filter)}.ag-tick42 .ag-menu .ag-column-select-column,.ag-tick42 .ag-menu .ag-column-select-column-group,.ag-tick42 .ag-tool-panel .ag-column-select-column,.ag-tick42 .ag-tool-panel .ag-column-select-column-group{display:flex;align-items:center;margin-left:0;line-height:2rem;cursor:pointer}.ag-tick42 .ag-menu .ag-column-select-column .ag-column-select-checkbox:hover,.ag-tick42 .ag-menu .ag-column-select-column-group .ag-column-select-checkbox:hover,.ag-tick42 .ag-tool-panel .ag-column-select-column .ag-column-select-checkbox:hover,.ag-tick42 .ag-tool-panel .ag-column-select-column-group .ag-column-select-checkbox:hover{color:var(--t42-link-color)}.ag-tick42 .ag-menu .ag-column-select-column:hover,.ag-tick42 .ag-menu .ag-column-select-column-group:hover,.ag-tick42 .ag-tool-panel .ag-column-select-column:hover,.ag-tick42 .ag-tool-panel .ag-column-select-column-group:hover{color:Hsl(var(--t42-content--base), 100%);background-color:var(--t42-color-opacity-10)}.ag-tick42 .ag-menu .ag-column-select-header,.ag-tick42 .ag-tool-panel .ag-column-select-header{padding:0.5rem}.ag-tick42 .ag-menu .ag-column-select-column-label,.ag-tick42 .ag-tool-panel .ag-column-select-column-label{margin-left:0.25rem}.ag-tick42 .ag-tab-body{max-height:220px;overflow:auto}.ag-tick42 .ag-tab-body .ag-set-filter-list{height:9rem}.ag-tick42 .ag-tab-body input{border:var(--t42-border)}.ag-tick42 .ag-tab-body input:focus{border-color:var(--primary)}.ag-tick42 .ag-menu-option{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:color;line-height:2rem;cursor:pointer}.ag-tick42 .ag-menu-option .ag-menu-option-icon{color:var(--t42-content-color)}.ag-tick42 .ag-menu-option .ag-menu-option-icon,.ag-tick42 .ag-menu-option .ag-menu-option-popup-pointer{width:2rem;color:var(--t42-content-color);text-align:center}.ag-tick42 .ag-menu-option .ag-menu-option-icon.ag-menu-option-popup-pointer,.ag-tick42 .ag-menu-option .ag-menu-option-icon:hover,.ag-tick42 .ag-menu-option .ag-menu-option-popup-pointer.ag-menu-option-popup-pointer,.ag-tick42 .ag-menu-option .ag-menu-option-popup-pointer:hover{color:var(--t42-content-color)}.ag-tick42 .ag-menu-option .ag-menu-option-icon.ag-menu-option-popup-pointer .ag-icon,.ag-tick42 .ag-menu-option .ag-menu-option-icon:hover .ag-icon,.ag-tick42 .ag-menu-option .ag-menu-option-popup-pointer.ag-menu-option-popup-pointer .ag-icon,.ag-tick42 .ag-menu-option .ag-menu-option-popup-pointer:hover .ag-icon{color:var(--t42-content-color)}.ag-tick42 .ag-menu-option.ag-menu-option-active{color:var(--t42-link-color);background-color:var(--t42-color-opacity-10)}.ag-tick42 .ag-menu-option.ag-menu-option-active .ag-icon{color:var(--t42-content-color)}.ag-tick42 .ag-menu-separator{border-bottom:var(--t42-border);border-bottom-color:var(--t42-color-opacity-10)}.ag-tick42 .ag-menu-column-select-wrapper,.ag-tick42 .ag-primary-cols-list-panel{height:auto}.ag-tick42 .ag-tool-panel .ag-pivot-mode{padding-top:0.5rem}.ag-tick42 .ag-column-tool-panel-column{padding:0 0.25rem}.ag-tick42 .ag-column-tool-panel-column .ag-icon{margin:0 0.25rem}.ag-tick42 .ag-column-tool-panel-column-label,.ag-tick42 span.ag-column-tool-panel-column-group{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;padding-left:0.25rem}.ag-tick42 .ag-column-tool-panel-column-group .ag-icon{margin:0 0.25rem 0 0}.ag-tick42 .ag-root+.ag-tool-panel{box-shadow:none}.ag-tick42 .ag-row-group-leaf-indent{margin-left:24px}.ag-tick42 .ag-group-expanded,.ag-tick42 .ag-group-contracted{display:flex;align-items:center;min-width:0.75rem;height:100%;margin-right:0.5rem}.ag-tick42 .ag-group-value .ag-react-container{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;display:inline;font-size:87.5%}.ag-tick42 .ag-popup-editor{box-shadow:var(--t42-shadow)}.ag-tick42 .ag-rich-select{border:var(--t42-border);border-radius:0;overflow-y:auto;background-color:Rgb(var(--t42-bg-light), 1)}.ag-tick42 .ag-rich-select-row{padding-left:0.75rem}.ag-tick42 .ag-rich-select-row-selected{background:var(--t42-color-opacity-10)}.ag-tick42 .ag-rich-select-value{position:relative;height:2rem;padding-left:0.75rem;border-bottom:var(--t42-border);line-height:2rem}.ag-tick42 .ag-rich-select-value::before{position:absolute;top:0;bottom:0;left:0;width:3px;background-color:var(--primary);content:""}.ag-tick42 .icon-window-maximize::before,.ag-tick42 .icon-window-minimize::before,.ag-tick42 .icon-window-ok::before{font-size:0.813rem}.ag-tick42 .ag-column-drop{border-top:var(--t42-border)}.ag-tick42 .ag-column-drop.ag-column-drop-horizontal{display:flex;height:1.875rem}.ag-tick42 .ag-column-drop.ag-column-drop-horizontal div{display:flex;align-items:center}.ag-tick42 .ag-column-drop.ag-column-drop-horizontal div:first-of-type{margin-right:0.25rem}.ag-tick42 .ag-column-drop .ag-column-drop-empty-message{align-self:center}.ag-tick42 .ag-column-drop .ag-column-drop-cell{display:flex;height:1.125rem;margin:0.125rem 0.25rem;padding:0 0.125rem 0 0.25rem;border-radius:0.25rem;background-color:Rgb(var(--t42-bg-light))}.ag-tick42 .ag-column-drop .ag-column-drop-cell .ag-column-drop-cell-text{padding:0 0.25rem;line-height:1.125rem}.ag-tick42 .ag-column-drop.ag-column-drop-vertical div{justify-content:start}.ag-tick42 .ag-column-drop.ag-column-drop-vertical .ag-icon-group{margin:0 0.25rem}.ag-tick42 .ag-right-arrow{width:1.5rem;padding:0 0.25rem;overflow:hidden;text-indent:-999px;background-color:var(--t42-content-color);transform:rotate(-90deg);-webkit-mask-image:var(--t42-select-indicator)}.ag-tick42 .ag-right-arrow::before{position:absolute;text-indent:999px}.ag-tick42 .ag-group-checkbox{display:flex;align-items:center;width:1rem;height:100%;margin-right:0.5rem}.ag-tick42 .ag-group-checkbox .ag-icon{width:0.875rem;height:0.875rem}.ag-tick42 .ag-group-checkbox:empty{width:initial}.ag-tick42 .ag-ltr .ag-toolpanel-indent-1{padding-left:1rem}.ag-tick42 .ag-ltr .ag-toolpanel-indent-2{padding-left:2rem}.ag-tick42 .ag-ltr .ag-toolpanel-indent-3{padding-left:3rem}.ag-tick42 .ag-ltr .ag-row-group-indent-1{padding-left:calc(1 * 1.45rem)}.ag-tick42 .ag-ltr .ag-row-group-indent-2{padding-left:calc(2 * 1.45rem)}.ag-tick42 .ag-ltr .ag-row-group-indent-3{padding-left:calc(3 * 1.45rem)}.ag-menu .ag-filter-checkbox{min-width:2rem}.ag-menu .ag-icon-checkbox-checked::after{width:0.625rem;height:0.625rem}.ag-menu .ag-column-group-icons{width:1.5rem}.ag-menu .ag-labeled.ag-label-align-right>div{margin-left:0.25rem}.ag-filter-panel{width:100%}.loading-filter{background-color:rgba(var(--t42-bg-light), 0.75);backdrop-filter:var(--backdrop-filter)}#selectAllContainer,.ag-set-filter-item{display:flex;align-items:center;cursor:pointer}#selectAllContainer .ag-filter-value,#selectAllContainer .ag-set-filter-item-value,.ag-set-filter-item .ag-filter-value,.ag-set-filter-item .ag-set-filter-item-value{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}#selectAllContainer .ag-set-filter-item-value,.ag-set-filter-item .ag-set-filter-item-value{margin-left:0.25rem}.ag-filter-checkbox{justify-content:center;min-width:2rem;color:var(--primary)}.ag-set-filter-item:hover,.ag-filter-header-container:hover label{color:var(--t42-link-color);background-color:var(--t42-color-opacity-10)}.ag-set-filter-item:hover .ag-icon,.ag-filter-header-container:hover label .ag-icon{color:var(--t42-link-color)}.ag-input-text-wrapper{padding:0.25rem 0.25rem 0}.ag-primary-cols-header-panel{align-items:center;padding:0.25rem 0.25rem 0.25rem 0}.ag-primary-cols-header-panel div:nth-child(1){width:1.25rem}.ag-primary-cols-header-panel div:nth-child(2){width:1rem;margin-right:0.25rem}.ag-filter-toolpanel-header{display:flex}.ag-filter-toolpanel-header .ag-header-cell-text{padding:0 0.25rem}.ag-filter-condition{justify-content:space-evenly;padding:0.5rem 0}.ag-filter-condition .ag-labeled.ag-label-align-right div{margin-left:0}.ag-radio-button-label{position:relative;color:var(--t42-content-color-muted);cursor:pointer;user-select:none}.ag-radio-button-input-wrapper::before{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, border;position:absolute;left:-1.125rem;display:block;width:0.875rem;height:0.875rem;border:0.0625rem solid var(--t42-content-color-muted);border-radius:50%;cursor:pointer;content:"";pointer-events:all}.ag-radio-button-input-wrapper::after{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, border;position:absolute;left:-0.875rem;display:block;width:0.375rem;height:0.375rem;border-radius:50%;color:var(--white);background-image:none;transform:scale(0);opacity:0;content:""}.ag-radio-button-input-wrapper:focus{border-color:var(--primary)}.ag-radio-button-input-wrapper.ag-checked::before{border-color:var(--t42-color-opacity-30);background-color:var(--primary)}.ag-radio-button-input-wrapper.ag-checked::after{background-color:var(--white);transform:scale(1);opacity:1}.ag-list{z-index:1100;background-color:rgba(var(--t42-bg-mid), 0.7);backdrop-filter:var(--backdrop-filter)}.ag-list .ag-list-item{padding:0 0.5rem;line-height:2rem;cursor:pointer}.ag-list .ag-list-item:hover{background-color:Rgb(var(--t42-bg-light))}.ag-picker-field-wrapper{height:2rem;padding:0 0.5rem;line-height:2rem;cursor:pointer}.ag-column-select-header-icon{display:flex;align-items:center}.ag-column-select-header .ag-text-field-input{height:1.875rem;line-height:1.875rem}.ag-filter-list-panel .ag-filter-toolpanel-expand{margin:0 0.25rem}.ag-filter-list-panel .ag-filter-toolpanel-group-container,.ag-filter-list-panel .ag-filter-toolpanel-instance-filter{padding-left:0.25rem}.ag-side-bar{position:relative}.ag-side-bar .ag-side-bar-right .ag-tool-panel-horizontal-resize{left:-0.375rem}.ag-side-bar>div:first-child{border:var(--t42-border);background-color:var(--t42-color-opacity-10)}.ag-side-bar .ag-pivot-mode-select{display:flex;padding:0.25rem;border-bottom:var(--t42-border)}.ag-side-bar .ag-pivot-mode-select label{margin:0 0 0 0.5rem}.ag-side-bar .ag-pivot-mode-select .ag-checkbox-label{padding-left:0.25rem}.ag-side-bar .ag-side-buttons div.ag-side-button button{width:1rem;height:1rem;padding:0;border:0.0625rem solid transparent;color:Hsl(var(--t42-content-color-base), 100%);background-color:transparent}.ag-side-bar .ag-side-buttons div.ag-side-button button:hover{color:Hsl(var(--t42-content-color-base), 100%);background-color:Rgb(var(--t42-bg-dark))}.ag-side-bar .ag-side-buttons div.ag-side-button button>span{display:none}.ag-side-bar .ag-side-buttons div.ag-side-button.ag-selected button{border-color:var(--t42-color-opacity-30);background-color:var(--primary)}.ag-side-bar .ag-side-buttons div.ag-side-button.ag-selected button [class*="ag-icon-"]{background-color:var(--white)}.ag-side-bar .ag-icon-checkbox-checked::after{width:0.625rem;height:0.625rem}.ag-side-bar .ag-column-panel,.ag-side-bar .ag-filter-panel{padding-left:0.25rem}.ag-side-bar .ag-filter-checkbox{margin-right:0.25rem}.ag-tool-panel-wrapper{border-top:var(--t42-border);border-bottom:var(--t42-border)}.ag-tool-panel-wrapper .ag-set-filter-list{width:100%;height:auto}.ag-tool-panel-wrapper .ag-column-select-checkbox,.ag-tool-panel-wrapper .ag-column-select-header-checkbox{margin:0 0.25rem}.ag-tool-panel-horizontal-resize{top:initial;width:0.188rem;background-color:var(--t42-color-opacity-10)}.ag-column-panel,.ag-column-select-panel,.ag-column-drop-vertical,.ag-column-drop-list{display:block;min-height:initial;max-height:initial;overflow:visible}.ag-column-panel input,.ag-column-select-panel input,.ag-column-drop-vertical input,.ag-column-drop-list input{border:var(--t42-border)}.ag-column-panel input:focus,.ag-column-select-panel input:focus,.ag-column-drop-vertical input:focus,.ag-column-drop-list input:focus{border-color:var(--primary)}[class*="ag-icon-"],.icon-check-1,.icon-check-empty,.icon-resize-horizontal{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:color, transform;display:block;width:0.75rem;height:0.75rem;margin:0 auto;background-color:var(--t42-content-color);background-image:none;mask-repeat:no-repeat;mask-position:center;cursor:pointer}[class*="ag-icon-"]:hover,.icon-check-1:hover,.icon-check-empty:hover,.icon-resize-horizontal:hover{background-color:var(--t42-link-color)}.ag-menu-option-disabled{color:var(--t42-content-color-disabled)}.ag-menu-option-disabled .ag-icon{background-color:var(--t42-content-color-disabled)}.ag-icon-menu{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M475.4,384v36.4c0,5.1-1.7,9.4-5.1,12.8s-7.9,5.3-13.3,5.6H55c-5.1,0-9.4-1.9-12.8-5.6c-3.4-3.8-5.3-8-5.6-12.8V384 c0-5.1,1.9-9.4,5.6-12.8c3.8-3.4,8-5.3,12.8-5.6h401.9c5.1,0,9.6,1.9,13.3,5.6C474,375,475.7,379.2,475.4,384z M475.4,237.6v36.9 c0,4.8-1.7,9-5.1,12.8s-7.9,5.5-13.3,5.1H55c-5.1,0-9.4-1.7-12.8-5.1s-5.3-7.7-5.6-12.8v-36.9c0-4.8,1.9-9,5.6-12.8 c3.8-3.8,8-5.5,12.8-5.1h401.9c5.1,0,9.6,1.7,13.3,5.1S475.7,232.5,475.4,237.6z M475.4,91.7V128c0,4.8-1.7,9-5.1,12.8 s-7.9,5.6-13.3,5.6H55c-5.1,0-9.4-1.9-12.8-5.6s-5.3-8-5.6-12.8V91.7c0-5.1,1.9-9.6,5.6-13.3c3.8-3.8,8-5.5,12.8-5.1h401.9 c5.1,0,9.6,1.7,13.3,5.1S475.7,86.2,475.4,91.7z%27/%3E%3C/svg%3E%0A")}.ag-header-icon{margin-left:0.125rem}.ag-header-icon .ag-icon-menu{line-height:1.875rem}.ag-icon-asc{-webkit-mask-image:var(--t42-select-indicator);transform:rotate(180deg)}.ag-icon-desc{-webkit-mask-image:var(--t42-select-indicator);margin-bottom:2px}.ag-icon-filter{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 16 16%27%3E%3Cpath d=%27M14.9,1.4c0.1,0.3,0.1,0.5-0.1,0.7L9.9,7v7.4c0,0.3-0.1,0.5-0.4,0.6C9.4,15,9.4,15,9.3,15c-0.2,0-0.3-0.1-0.4-0.2l-2.5-2.5 c-0.1-0.1-0.2-0.3-0.2-0.4V7L1.2,2.1C1,1.9,0.9,1.7,1.1,1.4C1.2,1.1,1.4,1,1.7,1h12.7C14.6,1,14.8,1.1,14.9,1.4L14.9,1.4z%27/%3E%3C/svg%3E")}.ag-icon-none{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 16 16%27%3E%3Cpath d=%27M1 6L5 2Q6 1 7 2L11 6Q11 7 10 7L2 7Q1 7 1 6M2 8Q1 8 1 9L5 13Q6 14 7 13L11 9Q11 8 10 8L2 8%27/%3E%3C/svg%3E%0A")}.ag-icon-indeterminate,.ag-icon-checkbox-indeterminate,.ag-icon-checkbox-indeterminate-readonly,.ag-icon-checkbox-unchecked,.ag-icon-checkbox-unchecked-readonly,.ag-icon-checkbox-checked-readonly,.ag-icon-checkbox-checked,.icon-check-1,.icon-check-empty,.ag-checkbox-input-wrapper,.ag-toggle-button-input-wrapper{position:relative;padding:0;color:var(--t42-content-color-muted);background-color:transparent;cursor:pointer;user-select:none}.ag-icon-indeterminate::before,.ag-icon-checkbox-indeterminate::before,.ag-icon-checkbox-indeterminate-readonly::before,.ag-icon-checkbox-unchecked::before,.ag-icon-checkbox-unchecked-readonly::before,.ag-icon-checkbox-checked-readonly::before,.ag-icon-checkbox-checked::before,.icon-check-1::before,.icon-check-empty::before,.ag-checkbox-input-wrapper::before,.ag-toggle-button-input-wrapper::before{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, border-color;display:block;width:100%;height:100%;border:var(--t42-border);border-color:var(--t42-content-color);cursor:pointer;content:"";pointer-events:all}.ag-icon-indeterminate:focus,.ag-icon-checkbox-indeterminate:focus,.ag-icon-checkbox-indeterminate-readonly:focus,.ag-icon-checkbox-unchecked:focus,.ag-icon-checkbox-unchecked-readonly:focus,.ag-icon-checkbox-checked-readonly:focus,.ag-icon-checkbox-checked:focus,.icon-check-1:focus,.icon-check-empty:focus,.ag-checkbox-input-wrapper:focus,.ag-toggle-button-input-wrapper:focus{border-color:var(--primary)}.ag-icon-indeterminate:hover,.ag-icon-checkbox-indeterminate:hover,.ag-icon-checkbox-indeterminate-readonly:hover,.ag-icon-checkbox-unchecked:hover,.ag-icon-checkbox-unchecked-readonly:hover,.ag-icon-checkbox-checked-readonly:hover,.ag-icon-checkbox-checked:hover,.icon-check-1:hover,.icon-check-empty:hover,.ag-checkbox-input-wrapper:hover,.ag-toggle-button-input-wrapper:hover{background-color:transparent}.ag-icon-checkbox-indeterminate,.ag-icon-checkbox-indeterminate-readonly,.ag-icon-checkbox-checked,.ag-icon-checkbox-checked-readonly,.icon-check-empty,.ag-checkbox-input-wrapper.ag-indeterminate,.ag-checkbox-input-wrapper.ag-checked,.ag-toggle-button-input-wrapper.ag-checked{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background, color}.ag-icon-checkbox-indeterminate::before,.ag-icon-checkbox-indeterminate-readonly::before,.ag-icon-checkbox-checked::before,.ag-icon-checkbox-checked-readonly::before,.icon-check-empty::before,.ag-checkbox-input-wrapper.ag-indeterminate::before,.ag-checkbox-input-wrapper.ag-checked::before,.ag-toggle-button-input-wrapper.ag-checked::before{border:0.0625rem solid var(--t42-color-opacity-30);background:var(--primary)}.ag-icon-checkbox-indeterminate::after,.ag-icon-checkbox-indeterminate-readonly::after,.ag-icon-checkbox-checked::after,.ag-icon-checkbox-checked-readonly::after,.icon-check-empty::after,.ag-checkbox-input-wrapper.ag-indeterminate::after,.ag-checkbox-input-wrapper.ag-checked::after,.ag-toggle-button-input-wrapper.ag-checked::after{position:absolute;top:0.063rem;left:0.063rem;display:block;width:0.75rem;height:0.75rem;background:var(--white);content:""}.ag-icon-checkbox-checked::after,.ag-icon-checkbox-checked-readonly::after,.icon-check-empty::after,.ag-checkbox-input-wrapper.ag-checked::after,.ag-toggle-button-input-wrapper.ag-checked::after{-webkit-mask-image:url("data:image/svg+xml,%3Csvg version=%271.1%27 xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M477.44 152.832q0 11.264-8.192 19.456l-245.76 245.76q-8.192 7.68-19.456 7.68t-19.456-7.68l-142.336-142.336q-7.68-8.192-7.68-19.456t7.68-19.456l38.912-38.912q8.192-8.192 19.456-8.192t19.456 8.192l83.968 84.48 187.392-187.904q8.192-8.192 19.456-8.192t19.456 8.192l38.912 38.912q8.192 7.68 8.192 19.456z%27%3E%3C/path%3E%3C/svg%3E%0A")}.ag-icon-checkbox-indeterminate::after,.ag-icon-checkbox-indeterminate-readonly::after,.ag-checkbox-input-wrapper.ag-indeterminate::after{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 -1 5 6%27%3E%3Cpath d=%27M 1 1 A 1 1 0 0 0 1 2 L 4 2 A 1 1 0 0 0 4 1 L 1 1%27/%3E%3C/svg%3E%0A")}.ag-checkbox-input-wrapper.ag-indeterminate::after{top:0.125rem;left:0.125rem}.ag-checkbox-input-wrapper::before,.ag-toggle-button-input-wrapper::before{width:0.875rem;height:0.875rem}.ag-checkbox-input-wrapper .ag-checkbox-input,.ag-checkbox-input-wrapper .ag-toggle-button-input,.ag-toggle-button-input-wrapper .ag-checkbox-input,.ag-toggle-button-input-wrapper .ag-toggle-button-input{position:absolute;z-index:2;width:0.875rem;height:0.875rem}.ag-icon-columns{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M146.432 374.784v55.296q0 11.264-8.192 18.944t-19.456 8.192h-91.136q-11.776 0-19.456-8.192t-8.192-18.944v-55.296q0-11.264 8.192-19.456t19.456-7.68h91.136q11.776 0 19.456 7.68t8.192 19.456zM146.432 228.864v54.784q0 11.264-8.192 19.456t-19.456 7.68h-91.136q-11.776 0-19.456-7.68t-8.192-19.456v-54.784q0-11.776 8.192-19.456t19.456-8.192h91.136q11.776 0 19.456 8.192t8.192 19.456zM329.216 374.784v55.296q0 11.264-8.192 18.944t-19.456 8.192h-91.136q-11.776 0-19.456-8.192t-8.192-18.944v-55.296q0-11.264 8.192-19.456t19.456-7.68h91.136q11.776 0 19.456 7.68t8.192 19.456zM146.432 82.432v54.784q0 11.264-8.192 19.456t-19.456 8.192h-91.136q-11.776 0-19.456-8.192t-8.192-19.456v-54.784q0-11.264 8.192-19.456t19.456-8.192h91.136q11.776 0 19.456 8.192t8.192 19.456zM329.216 228.864v54.784q0 11.264-8.192 19.456t-19.456 7.68h-91.136q-11.776 0-19.456-7.68t-8.192-19.456v-54.784q0-11.776 8.192-19.456t19.456-8.192h91.136q11.776 0 19.456 8.192t8.192 19.456zM512 374.784v55.296q0 11.264-8.192 18.944t-19.456 8.192h-91.136q-11.264 0-19.456-8.192t-8.192-18.944v-55.296q0-11.264 8.192-19.456t19.456-7.68h91.136q11.776 0 19.456 7.68t8.192 19.456zM329.216 82.432v54.784q0 11.264-8.192 19.456t-19.456 8.192h-91.136q-11.776 0-19.456-8.192t-8.192-19.456v-54.784q0-11.264 8.192-19.456t19.456-8.192h91.136q11.776 0 19.456 8.192t8.192 19.456zM512 228.864v54.784q0 11.264-8.192 19.456t-19.456 7.68h-91.136q-11.264 0-19.456-7.68t-8.192-19.456v-54.784q0-11.776 8.192-19.456t19.456-8.192h91.136q11.776 0 19.456 8.192t8.192 19.456zM512 82.432v54.784q0 11.264-8.192 19.456t-19.456 8.192h-91.136q-11.264 0-19.456-8.192t-8.192-19.456v-54.784q0-11.264 8.192-19.456t19.456-8.192h91.136q11.776 0 19.456 8.192t8.192 19.456z%27%3E%3C/path%3E%3C/svg%3E")}.ag-icon-pin{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M228.4,228.6v-128c0-2.7-0.9-4.9-2.6-6.7s-3.9-2.6-6.7-2.6c-2.7,0-4.9,0.9-6.7,2.6c-1.7,1.7-2.6,3.9-2.6,6.7v128 c0,2.7,0.9,4.9,2.6,6.7c1.7,1.7,3.9,2.6,6.7,2.6c2.7,0,4.9-0.9,6.7-2.6S228.4,231.3,228.4,228.6z M420.4,329.5c0,4.8-1.9,9-5.6,12.8 c-3.8,3.8-8,5.5-12.8,5.1H279.6l-14.8,138.2c-0.3,2.4-1.4,4.3-3.1,5.6c-1.7,1.4-3.6,2.2-5.6,2.6h-0.5c-5.1,0-8-2.6-8.7-7.7 l-22-138.8H109.6c-5.1,0-9.4-1.7-12.8-5.1c-3.4-3.4-5.3-7.7-5.6-12.8c0-23.6,7.5-44.7,22.5-63.5s31.9-28.2,50.7-28.2V91.4 c-9.9,0-18.4-3.6-25.6-10.8c-7.2-7.2-10.9-15.7-11.3-25.6s3.4-18.4,11.3-25.6c7.9-7.2,16.4-10.9,25.6-11.3h182.8 c9.9,0,18.4,3.8,25.6,11.3s10.8,16,10.8,25.6s-3.6,18.1-10.8,25.6S357,91.7,347.1,91.4v146.4c18.8,0,35.7,9.4,50.7,28.2 C412.8,284.8,420.4,305.9,420.4,329.5L420.4,329.5z%27/%3E%3C/svg%3E")}.ag-icon-small-right,.ag-icon-small-down{width:0.65rem;height:0.65rem;-webkit-mask-image:var(--t42-select-indicator);transform:rotate(-90deg)}.ag-icon-small-down{transform:rotate(0)}.ag-icon-tick{-webkit-mask-image:url("data:image/svg+xml,%3Csvg version=%271.1%27 xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M477.44 152.832q0 11.264-8.192 19.456l-245.76 245.76q-8.192 7.68-19.456 7.68t-19.456-7.68l-142.336-142.336q-7.68-8.192-7.68-19.456t7.68-19.456l38.912-38.912q8.192-8.192 19.456-8.192t19.456 8.192l83.968 84.48 187.392-187.904q8.192-8.192 19.456-8.192t19.456 8.192l38.912 38.912q8.192 7.68 8.192 19.456z%27%3E%3C/path%3E%3C/svg%3E%0A")}.ag-icon-copy{-webkit-mask-image:url("data:image/svg+xml,")}.ag-icon-csv,.ag-icon-excel{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M0 0zq0-7.7-5.1-12.8zM475.3 356.6v91.6q0 11.3-8.2 18.9t-19.5 8.2h-420.4q-11.8 0-19.5-8.2t-8.2-18.9v-91.6q0-11.3 8.2-19.5t19.5-8.2h132.6l38.4 38.9q16.9 16.4 38.9 16.4t38.9-16.4l38.9-38.9h132.6q11.3 0 19.5 8.2t8.2 19.5zM382.1 193.8q5.1 11.8-4.1 20l-128 128q-5.1 5.6-12.8 5.6t-12.8-5.6l-128-128q-8.7-8.2-4.1-20q5.1-10.8 16.9-10.8h73.2v-128q0-7.7 5.6-12.8t12.8-5.6h73.2q7.2 0 12.8 5.6t5.1 12.8v128h73.2q12.3 0 16.9 10.8M347 439A1 1 0 00347 402A1 1 0 00347 439M420 439A1 1 0 00420 402A1 1 0 00420 439zz%27/%3E%3C/svg%3E%0A")}.ag-icon-expanded{-webkit-mask-image:var(--t42-select-indicator);transform:rotate(-90deg)}.ag-icon-contracted{-webkit-mask-image:var(--t42-select-indicator);transform:rotate(90deg)}.ag-header-expand-icon-collapsed .ag-icon-contracted{margin-bottom:1px;transform:rotate(90deg);-webkit-mask-image:var(--t42-select-indicator)}.ag-icon-paste{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M219.648 475.648h256v-183.296h-119.296q-11.264 0-18.944-7.68t-8.192-19.456v-118.784h-109.568v329.216zM292.352 64v-18.432q0-3.584-2.56-6.144t-6.144-3.072h-201.216q-3.584 0-6.656 3.072t-2.56 6.144v18.432q0 3.584 2.56 6.656t6.656 2.56h201.216q3.584 0 6.144-2.56t2.56-6.656zM365.568 256h85.504l-85.504-85.504v85.504zM512 292.352v192q0 11.776-8.192 19.456t-19.456 8.192h-273.92q-11.776 0-19.456-8.192t-8.192-19.456v-45.568h-155.136q-11.776 0-19.456-8.192t-8.192-18.944v-384q0-11.776 8.192-19.456t19.456-8.192h310.784q11.264 0 19.456 8.192t7.68 19.456v93.696q6.144 3.584 10.24 7.68l116.736 116.736q8.192 7.68 13.824 21.504t5.632 25.088z%27%3E%3C/path%3E%3C/svg%3E%0A")}.ag-icon-arrows{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M512 256q0 7.168-5.632 12.8l-72.704 73.216q-5.632 5.632-13.312 5.632t-12.8-5.632-5.12-12.8v-36.864h-110.080v110.080h36.864q7.168 0 12.8 5.12t5.632 12.8-5.632 12.8l-73.216 73.216q-5.12 5.632-12.8 5.632t-12.8-5.632l-73.216-73.216q-5.632-5.12-5.632-12.8t5.632-12.8 12.8-5.12h36.864v-110.080h-110.080v36.864q0 7.168-5.12 12.8t-12.8 5.632-12.8-5.632l-73.216-73.216q-5.632-5.632-5.632-12.8t5.632-12.8l73.216-73.216q5.12-5.632 12.8-5.632t12.8 5.632 5.12 12.8v36.864h110.080v-110.080h-36.864q-7.168 0-12.8-5.12t-5.632-12.8 5.632-13.312l73.216-72.704q5.632-5.632 12.8-5.632t12.8 5.632l73.216 72.704q5.632 5.632 5.632 13.312t-5.632 12.8-12.8 5.12h-36.864v110.080h110.080v-36.864q0-7.168 5.12-12.8t12.8-5.632 13.312 5.632l72.704 73.216q5.632 5.12 5.632 12.8z%27%3E%3C/path%3E%3C/svg%3E%0A")}.ag-icon-not-allowed{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27m 182.8 238.1 h 145.9 v -55.3 c 0 -20.1 -7.2 -37.4 -21.5 -51.7 s -31.6 -21.3 -51.7 -21 c -20.1 0.3 -37.4 7.3 -51.7 21 s -21.3 30.9 -21 51.7 l -0 55.3 l 0 0 z m 237.6 27.1 v 164.9 c 0 7.5 -2.7 13.8 -8.2 18.9 s -11.9 7.9 -19.5 8.2 h -273.9 c -7.9 0 -14.3 -2.7 -19.5 -8.2 c -5.1 -5.5 -7.9 -11.8 -8.2 -18.9 v -164.9 c 0 -7.5 2.7 -14 8.2 -19.5 s 11.9 -8 19.5 -7.7 h 8.7 v -55.3 c 0 -34.8 12.6 -64.9 37.9 -90.1 s 55.3 -37.9 90.1 -37.9 s 65 12.6 90.6 37.9 s 38.1 55.3 37.4 90.1 v 55.3 h 9.2 c 7.9 0 14.3 2.6 19.5 7.7 s 7.8 11.7 8.2 19.5 z%27/%3E%3C/svg%3E")}.ag-icon-eye-slash{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M 475.6 256.3 q -43.5 -67.6 -109.1 -100.9 q 17.4 29.7 17.4 64 q 0 52.7 -37.4 90.6 t -90.6 37.4 t -90.6 -37.4 t -37.4 -90.6 q 0 -34.3 17.4 -64 q -65.5 33.3 -109.1 100.9 q 38.4 58.4 95.7 93.2 t 123.9 34.8 t 124.4 -34.8 t 95.2 -93.2 z M 269.8 146.2 q 0 -5.6 -4.1 -9.7 t -9.7 -3.6 q -35.8 0 -61.4 25.6 t -25.6 60.9 q 0 5.6 4.1 9.7 t 9.7 4.1 t 9.7 -4.1 t 4.1 -9.7 q 0 -24.6 17.4 -42 t 42 -17.4 q 5.6 0 9.7 -4.1 t 4.1 -9.7 z M 512 256.3 q 0 9.7 -5.6 19.5 q -39.9 66 -107.5 105.5 t -142.8 39.4 t -142.8 -39.4 t -107.5 -105.5 q -5.6 -9.7 -5.6 -19.5 t 5.6 -20 q 39.9 -65.5 107.5 -105 t 142.8 -39.9 t 142.8 39.9 t 107.5 105 q 5.6 10.2 5.6 20 z%27%3E%3C/path%3E%3C/svg%3E%0A")}.ag-icon-group{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M146.4 374.8v55.3q0 11.3-8.2 18.9t-19.5 8.2h-91.1q-11.8 0-19.5-8.2t-8.2-18.9v-55.3q0-11.3 8.2-19.5t19.5-7.7h91.1q11.8 0 19.5 7.7t8.2 19.5zM146.4 228.9v54.8q0 11.3-8.2 19.5t-19.5 7.7h-91.1q-11.8 0-19.5-7.7t-8.2-19.5v-54.8q0-11.8 8.2-19.5t19.5-8.2h91.1q11.8 0 19.5 8.2t8.2 19.5zM512 374.8v55.3q0 11.3-8.2 18.9t-19.5 8.2h-273.9q-11.8 0-19.5-8.2t-8.2-18.9v-55.3q0-11.3 8.2-19.5t19.5-7.7h273.9q11.8 0 19.5 7.7t8.2 19.5zM146.4 82.4v54.8q0 11.3-8.2 19.5t-19.5 8.2h-91.1q-11.8 0-19.5-8.2t-8.2-19.5v-54.8q0-11.3 8.2-19.5t19.5-8.2h91.1q11.8 0 19.5 8.2t8.2 19.5zM512 228.9v54.8q0 11.3-8.2 19.5t-19.5 7.7h-273.9q-11.8 0-19.5-7.7t-8.2-19.5v-54.8q0-11.8 8.2-19.5t19.5-8.2h273.9q11.8 0 19.5 8.2t8.2 19.5zM512 82.4v54.8q0 11.3-8.2 19.5t-19.5 8.2h-273.9q-11.8 0-19.5-8.2t-8.2-19.5v-54.8q0-11.3 8.2-19.5t19.5-8.2h273.9q11.8 0 19.5 8.2t8.2 19.5z%27%3E%3C/path%3E%3C/svg%3E%0A")}.ag-icon-grip{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 16 16%27%3E%3Cpath d=%27M4 3L6 3L6 5L4 5L4 3M4 7L6 7L6 9L4 9L4 7M4 11L6 11L6 13L4 13L4 11M8 3L10 3L10 5L8 5L8 3M8 7L10 7L10 9L8 9L8 7M8 11L10 11L10 13L8 13L8 11%27/%3E%3C/svg%3E%0A");margin:0}.ag-icon-tree-open{-webkit-mask-image:var(--t42-select-indicator);transform:rotate(180deg)}.ag-icon-tree-closed{-webkit-mask-image:var(--t42-select-indicator);transform:rotate(270deg)}.ag-icon-tree-indeterminate{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 -1 5 6%27%3E%3Cpath d=%27M 1 1 A 1 1 0 0 0 1 2 L 4 2 A 1 1 0 0 0 4 1 L 1 1%27/%3E%3C/svg%3E%0A")}.ag-icon-save{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M 420.6 319.2 V 393 c 0 22.9 -8 42.3 -24.1 58.4 s -35.5 24.1 -58.4 24.1 H 100.6 c -22.9 0 -42.3 -8 -58.4 -24.1 S 18.2 415.8 18.2 393 V 155.4 c 0 -22.5 8 -41.8 24.1 -57.9 S 77.7 73.3 100.6 73 h 72.7 c 2.4 0 4.6 1 6.7 3.1 c 2 2 2.9 4.1 2.6 6.1 c 0 5.1 -2.6 8.2 -7.7 9.2 c -14.7 5.1 -27.3 10.9 -37.9 17.4 c -1.7 0.7 -3.2 1 -4.6 1 h -31.7 c -12.6 0 -23.4 4.4 -32.3 13.3 s -13.5 19.6 -13.8 32.3 V 393 c 0 12.6 4.6 23.4 13.8 32.3 c 9.2 8.9 20 13.5 32.3 13.8 h 237.6 c 12.6 0 23.4 -4.6 32.3 -13.8 c 8.9 -9.2 13.3 -20 13.3 -32.3 V 332 c 0 -3.8 1.7 -6.5 5.1 -8.2 c 5.5 -2.4 10.8 -6 15.9 -10.8 c 2.7 -3.1 6 -3.8 9.7 -2 C 418.6 312.7 420.6 315.5 420.6 319.2 L 420.6 319.2 z M 488.2 177.4 L 378.6 287 c -3.4 3.8 -7.7 5.6 -12.8 5.6 c -2.4 0 -4.8 -0.5 -7.2 -1.5 c -7.5 -3.1 -11.3 -8.7 -11.3 -16.9 v -54.8 h -45.6 c -61.8 0 -103.6 12.5 -125.4 37.4 c -22.5 26.3 -29.5 71.3 -21 135.2 c 0.7 4.4 -1.2 7.7 -5.6 9.7 c -1.7 0.3 -2.9 0.5 -3.6 0.5 c -3.1 0 -5.5 -1.2 -7.2 -3.6 c -2 -2.7 -4.1 -5.6 -6.1 -8.7 c -2 -3.1 -5.8 -9.7 -11.3 -20 c -5.5 -10.2 -10.2 -19.6 -14.3 -28.2 c -4.1 -8.5 -7.7 -19.5 -10.8 -32.8 c -3.1 -13.3 -4.8 -24.9 -5.1 -34.8 c 0 -9.2 0.3 -17.9 1 -26.1 c 0.7 -8.2 2 -16.7 4.1 -25.6 c 2 -8.9 4.6 -17.2 7.7 -25.1 c 3.1 -7.9 7.7 -15.5 13.8 -23 c 6.1 -7.5 12.6 -14.7 19.5 -21.5 s 15.7 -12.6 26.6 -17.4 c 10.9 -4.8 22.9 -9.4 35.8 -13.8 c 13 -4.4 28.2 -7.3 45.6 -8.7 s 36.2 -2.4 56.3 -3.1 h 45.6 V 55 c 0 -8.2 3.8 -13.8 11.3 -16.9 c 2.4 -1 4.8 -1.5 7.2 -1.5 c 4.8 0 9 1.9 12.8 5.6 l 109.6 109.6 c 3.8 3.4 5.6 7.7 5.6 12.8 S 491.9 174 488.2 177.4 L 488.2 177.4 z%27/%3E%3C/svg%3E")}.ag-tooltip{padding:0.125rem 0.5rem;border:0.0625rem solid var(--t42-color-opacity-10);border-radius:0.25rem;background:Rgb(var(--t42-bg-light));box-shadow:var(--t42-shadow)}.ag-icon-cancel{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M366.9 336.4c6.1 6.1 9.2 13.5 9.2 22s-3.1 15.9-9.2 22c-6.1 5.5-13.5 8.2-22 8.2c-8.5 0-15.9-2.7-22-8.2l-67.6-77.8l-67.6 77.8c-6.1 5.5-13.5 8.2-22 8.2c-8.5 0-15.9-2.7-22-8.2c-5.5-6.1-8.2-13.5-8.2-22s2.7-15.9 8.2-22l70.7-79.9l-70.7-80.9c-5.5-6.1-8.2-13.5-8.2-22c0-8.5 2.7-15.9 8.2-22c6.1-5.5 13.5-8.2 22-8.2c8.5 0 15.9 2.7 22 8.2l67.6 77.8l67.6-77.8c6.1-5.5 13.5-8.2 22-8.2c8.5 0 15.9 2.7 22 8.2c6.1 6.1 9.2 13.5 9.2 22c0 8.5-3.1 15.9-9.2 22l-70.7 80.9L366.9 336.4z%27/%3E%3C/svg%3E")}.icon-check-empty::after{width:0.65rem;height:0.65rem}.icon-resize-horizontal{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M512 256q0 7.2-5.6 12.8l-72.7 73.2q-5.6 5.6-13.3 5.6t-12.8-5.6t-5.1-12.8v-36.9h-292.9v36.9q0 7.2-5.1 12.8t-12.8 5.6t-12.8-5.6l-73.2-73.2q-5.6-5.6-5.6-12.8t5.6-12.8l73.2-73.2q5.1-5.6 12.8-5.6t12.8 5.6t5.1 12.8v36.9h292.9v-36.9q0-7.2 5.1-12.8t12.8-5.6t13.3 5.6l72.7 73.2q5.6 5.1 5.6 12.8z%27%3E%3C/path%3E%3C/svg%3E%0A")}.ag-icon-aggregation{margin:0 0.25rem;-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 16 16%27%3E%3Cpath d=%27M3.6,1.7c-0.2,0.7-0.9,1.1-1.5,1C1.5,2.6,1,2,1,1.3C1,0.7,1.5,0.1,2.1,0c0.4-0.1,0.7,0,1,0.2C3.4,0.4,3.6,0.7,3.7,1 c0.3,0,0.5,0.1,0.8,0.3C4.7,1.5,5,1.8,5.2,2.1c0.2,0.3,0.4,0.7,0.6,1c0.1,0.2,0.3,0.5,0.5,0.7c0.2,0.2,0.5,0.5,0.8,0.6 c0.1,0.1,0.3,0.1,0.5,0.1c0.6,0,2.3,0,2.9,0c0.4,0,0.7,0,1.1,0c0,0,0,0,0.1,0c0,0,0,0,0-0.1c0-0.1,0-0.2,0-0.3c0,0,0-0.1,0-0.1 c0-0.1,0.1-0.1,0.2-0.1c0.1,0,0.1,0,0.1,0.1c0.1,0,0.1,0.1,0.2,0.2c0.2,0.2,0.3,0.3,0.5,0.5C12.8,4.8,13,5,13.1,5.1c0,0,0,0,0,0 c0,0,0,0-0.1,0c-1.5,0-4.1,0-5.7,0C7.2,5.2,7,5.1,6.8,5C6.6,4.9,6.3,4.8,6.1,4.6C5.7,4.3,5.5,4,5.2,3.5C5,3.2,4.8,2.8,4.6,2.4 C4.4,2.2,4.3,2.1,4.1,1.9C4,1.8,3.9,1.7,3.8,1.7C3.7,1.7,3.7,1.7,3.6,1.7z%27/%3E%3Cpath d=%27M3.6,7.7c1,0,10.6,0,11,0c0.1,0,0.1,0,0.1,0.1C14.8,7.8,14.9,7.9,15,8c-0.1,0.1-0.2,0.2-0.3,0.3c0,0,0,0-0.1,0 c0,0,0,0-0.1,0c-3.3,0-7.7,0-10.9,0C3.5,8.8,3.2,9.1,2.8,9.3C2.5,9.4,2.2,9.4,2,9.3C1.4,9.1,1,8.6,1,8c0-0.7,0.5-1.2,1.1-1.3 c0.3-0.1,0.7,0,1,0.2C3.4,7.1,3.6,7.3,3.6,7.7z%27/%3E%3Cpath d=%27M13.1,10.9C13.1,10.9,13.1,10.9,13.1,10.9c-0.3,0.3-0.6,0.6-0.8,0.8c-0.1,0.1-0.2,0.2-0.3,0.3c0,0-0.1,0.1-0.1,0.1 c0,0-0.1,0-0.1,0c-0.1,0-0.1,0-0.2-0.1c0,0,0-0.1,0-0.1c0-0.1,0-0.2,0-0.3c0,0,0,0,0-0.1c-1,0-3.1,0-4.1,0c-0.1,0-0.3,0-0.4,0.1 c-0.3,0.1-0.5,0.2-0.7,0.4c-0.2,0.2-0.4,0.5-0.6,0.8c-0.2,0.4-0.4,0.7-0.7,1.1c-0.2,0.2-0.4,0.4-0.6,0.6c-0.1,0.1-0.3,0.2-0.4,0.3 c-0.1,0.1-0.3,0.2-0.4,0.2c0,0-0.1,0-0.1,0c-0.1,0.4-0.3,0.7-0.7,0.9C2.7,16,2.4,16,2.1,16C1.5,15.9,1,15.3,1,14.7 c0-0.7,0.5-1.2,1-1.3c0.3-0.1,0.7,0,1,0.2c0.3,0.2,0.5,0.5,0.6,0.8c0.1,0,0.2,0,0.2,0C4,14.2,4.1,14.1,4.2,14 c0.2-0.2,0.3-0.4,0.5-0.6c0.2-0.3,0.4-0.6,0.6-1c0.2-0.3,0.4-0.6,0.6-0.9c0.3-0.2,0.5-0.5,0.9-0.6c0.2-0.1,0.4-0.1,0.6-0.1 c0,0,0.1,0,0.1,0c0.6,0,2.4,0,3,0c0.8,0,1.7,0,2.5,0C13.1,10.9,13.1,10.9,13.1,10.9C13.1,10.9,13.1,10.9,13.1,10.9z%27/%3E%3Cpath d=%27M3.6,11.7c-0.1,0.4-0.3,0.7-0.7,0.9c-0.3,0.2-0.6,0.2-0.9,0.1C1.5,12.6,1,12.1,1,11.4c0-0.7,0.5-1.2,1.1-1.3 c0.3-0.1,0.7,0,1,0.2c0.3,0.2,0.5,0.5,0.6,0.8c0.1,0,0.1,0,0.2,0c0.2,0,0.3-0.1,0.4-0.2c0.2-0.1,0.4-0.3,0.5-0.4 C4.9,10.3,5,10.2,5,10.2C5.3,9.9,5.6,9.7,6,9.6c0.3-0.1,0.6-0.2,0.8-0.2c0.1,0,0.1,0,0.2,0c1.1,0,3.4,0,4.5,0c0.9,0,1.8,0,2.6,0 c0,0,0,0,0.1,0c0,0,0,0,0,0C14,9.6,13.8,9.8,13.6,10c-1.8,0-4.8,0-6.6,0c-0.3,0-0.6,0.1-0.9,0.2c-0.2,0.1-0.5,0.3-0.6,0.5 c-0.3,0.3-0.5,0.5-0.8,0.7c-0.2,0.1-0.4,0.2-0.6,0.3C3.9,11.7,3.8,11.7,3.6,11.7C3.7,11.7,3.7,11.7,3.6,11.7z%27/%3E%3Cpath d=%27M3.6,4.9C3.5,5.3,3.3,5.6,2.9,5.8C2.6,5.9,2.3,6,2,5.9C1.4,5.7,1,5.2,1,4.5c0-0.6,0.5-1.2,1.1-1.3c0.7-0.1,1.4,0.3,1.5,1 c0,0,0.1,0,0.1,0c0.3,0,0.5,0.1,0.7,0.3C4.7,4.7,5,4.9,5.2,5c0.1,0.1,0.2,0.2,0.4,0.4c0.3,0.3,0.6,0.5,1,0.5C6.7,6,6.9,6,7,6 c1.8,0,4.8,0,6.6,0c0.1,0.1,0.3,0.3,0.6,0.6c0,0,0,0,0,0c0,0,0,0,0,0c0,0,0,0-0.1,0c-2,0-5.1,0-7.1,0c-0.3,0-0.5,0-0.8-0.1 C6,6.5,5.7,6.4,5.5,6.2C5.3,6.1,5.1,5.9,5,5.8C4.8,5.5,4.5,5.3,4.2,5.1C4.1,5,3.9,4.9,3.6,4.9z%27/%3E%3C/svg%3E%0A")}.ag-icon-loading{position:relative;width:1rem;height:1rem;border-radius:50%;background:linear-gradient(to right, var(--t42-icon-color), Rgba(var(--t42-bg-dark) 42%));transform:translateZ(0);animation:icon-loading 1.4s infinite linear}.ag-icon-loading::before{position:absolute;top:0;left:0;width:50%;height:50%;border-radius:100% 0 0;background:var(--t42-icon-color);content:""}.ag-icon-loading::after{position:absolute;top:0;right:0;bottom:0;left:0;width:75%;height:75%;margin:auto;border-radius:50%;background:Rgb(var(--t42-bg-dark));content:""}.ag-loading{display:flex;padding-left:0.5rem}@keyframes icon-loading{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.search{position:relative}.search i{position:absolute;top:0.625rem;right:0.75rem;width:.75rem;height:.75rem;background-color:var(--t42-content-color);-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M328.9 219.4q0-52.7-37.4-90.1t-90.6-37.9t-90.6 37.9t-37.4 90.1t37.4 90.6t90.6 37.4t90.6-37.4t37.4-90.6zM475.3 457.5q0 14.8-11.3 25.6t-25.6 10.8q-15.4 0-25.6-10.8l-97.8-97.8q-51.2 35.3-114.2 35.3q-41 0-78.3-15.9t-64-43t-43-64t-15.9-78.3t15.9-77.8t43-64.5t64-43t78.3-15.9t78.3 15.9t64 43t43 64.5t15.9 77.8q0 63-35.3 114.2l97.8 97.8q10.8 10.8 10.8 26.1z%27%3E%3C/path%3E%3C/svg%3E%0A")}.search-results{position:absolute;top:33px;max-height:215px;overflow-y:auto}.search-results .list-group-item{white-space:nowrap}.select{position:relative;z-index:12;display:flex;align-items:center;justify-content:center;width:100%;height:2rem;list-style:none;cursor:pointer}.select input[type="radio"]{opacity:1}.select_expand{position:absolute;top:0;right:0;width:0;height:2rem}.select_expand::after{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:transform;position:absolute;top:50%;right:0;z-index:2;width:1rem;height:1rem;background:var(--t42-select-indicator) center center/1rem 1rem no-repeat;transform:translate(-65%, -55%);content:"";pointer-events:none}.select_expand:checked+.select_close_label+.select_options .select_label:hover{color:var(--t42-link-hover-color);background-color:var(--t42-link-active-bg)}.select_expand:checked::after{transform:translate(-65%, -55%) rotate(-180deg)}.select_expand_label{position:absolute;top:0;left:0;display:block;width:100%;height:2rem;margin-bottom:0;cursor:pointer}.select_close{display:none}.select_close_label{position:fixed;top:0;left:0;display:none;margin-bottom:0}.select_items{position:absolute;top:0;left:0;width:100%;min-height:2rem;border-color:var(--t42-color-opacity-10);border-style:solid;border-width:1px}.select_items:hover{border-color:var(--primary)}.select_input{display:none}.select_label{display:block;height:0;margin-bottom:0;padding-left:0.875rem;overflow:hidden;line-height:2rem;cursor:pointer;transition:all 200ms cubic-bezier(0.4, 0.25, 0.3, 1)}.select_label-placeholder{position:absolute;top:0;left:0;height:2rem;vertical-align:middle;background-color:transparent}.select_expand:checked+.select_close_label{display:block}.select_expand:checked+.select_close_label::before,.select_expand:checked+.select_close_label::after{display:none}.select_expand:checked+.select_close_label+.select_options .select_label{height:2rem}.select_expand:checked+.select_close_label+.select_options+.select_expand_label{display:none}.select_input:checked+.select_label{height:2rem}.select_option label{color:var(--t42-content-color)}.select_options{max-height:10rem;padding-left:0;overflow:auto;list-style:none}.dark{--t42-json-icons: url("data:image/svg+xml,%3C%3Fxml version=%271.0%27 encoding=%27UTF-8%27 standalone=%27no%27%3F%3E%3Csvg xmlns:dc=%27http://purl.org/dc/elements/1.1/%27 xmlns:cc=%27http://creativecommons.org/ns%23%27 xmlns:rdf=%27http://www.w3.org/1999/02/22-rdf-syntax-ns%23%27 xmlns:svg=%27http://www.w3.org/2000/svg%27 xmlns=%27http://www.w3.org/2000/svg%27 xmlns:sodipodi=%27http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd%27 xmlns:inkscape=%27http://www.inkscape.org/namespaces/inkscape%27 width=%27240%27 height=%27144%27 id=%27svg4136%27 version=%271.1%27 inkscape:version=%270.91 r13725%27 sodipodi:docname=%27jsoneditor-icons.svg%27%3E%3Ctitle id=%27title6512%27%3EJSON Editor Icons%3C/title%3E%3Crect id=%27svg_1-7%27 height=%2716%27 width=%2716%27 y=%273.999995%27 x=%2728.000006%27 style=%27fill:%23ff511f;%27 /%3E%3Crect x=%277%27 y=%2711%27 width=%2710%27 height=%272%27 id=%27svg_1-1%27 style=%27fill:%23ffffff;%27 /%3E%3Crect x=%2711%27 y=%277%27 width=%272%27 height=%2710%27 id=%27svg_1-1-1%27 style=%27fill:%23ffffff;%27 /%3E%3Cg id=%27g4299-3%27 transform=%27matrix%280.70710678,-0.70710678,0.70710678,0.70710678,19.029435,12.000001%29%27 style=%27%27%3E%3Crect x=%277%27 y=%2711%27 width=%2710%27 height=%272%27 id=%27svg_1-1-0%27 style=%27fill:%23ffffff;%27 /%3E%3Crect x=%2711%27 y=%277%27 width=%272%27 height=%2710%27 id=%27svg_1-1-1-9%27 style=%27fill:%23ffffff;%27 /%3E%3C/g%3E%3Crect height=%277%27 width=%277%27 y=%277%27 x=%2755%27 style=%27fill:%23ffffff;stroke-width:1;stroke:%23ffffff%27 /%3E%3Crect id=%27svg_1-7-5-7%27 height=%277%27 width=%277%27 y=%2710%27 x=%2758%27 style=%27fill:%23ffffff;stroke-width:1;stroke:%231d1d1d%27 /%3E%3Cg id=%27g4378%27%3E%3Crect style=%27fill:%23ffffff;%27 x=%27198%27 y=%2711%27 width=%278%27 height=%272%27 id=%27svg_1-7-5-3%27 /%3E%3Crect id=%27rect4374%27 height=%272%27 width=%2712%27 y=%277%27 x=%27198%27 style=%27fill:%23ffffff;%27 /%3E%3Crect id=%27rect4376%27 height=%272%27 width=%274%27 y=%2715%27 x=%27198%27 style=%27fill:%23ffffff;%27 /%3E%3C/g%3E%3Cg transform=%27matrix%281,0,0,-1,-23.999995,23.999995%29%27 id=%27g4383%27%3E%3Crect id=%27rect4385%27 height=%272%27 width=%278%27 y=%2711%27 x=%27198%27 style=%27fill:%23ffffff;%27 /%3E%3Crect style=%27fill:%23ffffff;%27 x=%27198%27 y=%277%27 width=%2712%27 height=%272%27 id=%27rect4387%27 /%3E%3Crect style=%27fill:%23ffffff;%27 x=%27198%27 y=%2715%27 width=%274%27 height=%272%27 id=%27rect4389%27 /%3E%3C/g%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 85.10447,6.0157384 -0.0156,1.4063 c 3.02669,-0.2402 0.33008,3.6507996 2.48438,4.5780996 -2.18694,1.0938 0.49191,4.9069 -2.45313,4.5781 l -0.0156,1.4219 c 5.70828,0.559 1.03264,-5.1005 4.70313,-5.2656 l 0,-1.4063 c -3.61303,-0.027 1.11893,-5.7069996 -4.70313,-5.3124996 z%27 id=%27path4351%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 82.78125,5.9984384 0.0156,1.4063 c -3.02668,-0.2402 -0.33007,3.6506996 -2.48437,4.5780996 2.18694,1.0938 -0.49192,4.9069 2.45312,4.5781 l 0.0156,1.4219 c -5.70827,0.559 -1.03263,-5.1004 -4.70312,-5.2656 l 0,-1.4063 c 3.61303,-0.027 -1.11894,-5.7070996 4.70312,-5.3124996 z%27 id=%27path4351-9%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 103.719,5.6719384 0,12.7187996 3.03125,0 0,-1.5313 -1.34375,0 0,-9.6249996 1.375,0 0,-1.5625 z%27 id=%27path2987%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 112.2185,5.6721984 0,12.7187996 -3.03125,0 0,-1.5313 1.34375,0 0,-9.6249996 -1.375,0 0,-1.5625 z%27 id=%27path2987-1%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27M133,6.4h-1.9l-4.8,11.2h1.8l1.1-2.9h5.7l1.1,2.9h1.8L133,6.4z M129.7,13.5l2.3-5.5l2.3,5.5L129.7,13.5z%27 id=%27path3780%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 156.47655,5.8917384 0,2.1797 0.46093,2.3983996 1.82813,0 0.39844,-2.3983996 0,-2.1797 z%27 id=%27path5008-2%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 152.51561,5.8906384 0,2.1797 0.46094,2.3983996 1.82812,0 0.39844,-2.3983996 0,-2.1797 z%27 id=%27path5008-2-8%27 /%3E%3Crect id=%27svg_1-7-2%27 height=%272%27 width=%2712%27 y=%2764%27 x=%2754%27 style=%27fill:%236e6e6e;%27 /%3E%3Crect id=%27svg_1-7-2-2%27 height=%273%27 width=%273%27 y=%2752%27 x=%2780%27 style=%27fill:%236e6e6e;%27 /%3E%3Crect style=%27fill:%236e6e6e;%27 x=%2785%27 y=%2752%27 width=%273%27 height=%273%27 id=%27rect4561%27 /%3E%3Crect style=%27fill:%236e6e6e;%27 x=%2780%27 y=%2758%27 width=%273%27 height=%273%27 id=%27rect4563%27 /%3E%3Crect id=%27rect4565%27 height=%273%27 width=%273%27 y=%2758%27 x=%2785%27 style=%27fill:%236e6e6e;%27 /%3E%3Crect id=%27rect4567%27 height=%273%27 width=%273%27 y=%2764%27 x=%2780%27 style=%27fill:%236e6e6e;%27 /%3E%3Crect style=%27fill:%236e6e6e;%27 x=%2785%27 y=%2764%27 width=%273%27 height=%273%27 id=%27rect4569%27 /%3E%3Ccircle style=%27opacity:1;fill:none;stroke:%236e6e6e;stroke-width:2;%27 id=%27path4571%27 cx=%27110.06081%27 cy=%2757.939209%27 r=%274.7438836%27 /%3E%3Crect style=%27fill:%236e6e6e;%27 x=%27116.64566%27 y=%27-31.79752%27 width=%274.229713%27 height=%276.4053884%27 id=%27rect4563-2%27 transform=%27matrix%280.70710678,0.70710678,-0.70710678,0.70710678,0,0%29%27 /%3E%3Cpath style=%27fill:%236e6e6e;fill-rule:evenodd;%27 d=%27M 125,56 138.77027,56.095 132,64 Z%27 id=%27path4613%27 /%3E%3Cpath id=%27path4615%27 d=%27M 149,64 162.77027,63.905 156,56 Z%27 style=%27fill:%236e6e6e;fill-rule:evenodd;%27 /%3E%3Crect style=%27fill:%236e6e6e;%27 x=%2754%27 y=%2753%27 width=%2712%27 height=%272%27 id=%27rect4638%27 /%3E%3Crect id=%27svg_1-7-2-24%27 height=%272%27 width=%2713%27 y=%27-56%27 x=%2753%27 style=%27fill:%236e6e6e;%27 transform=%27matrix%280,1,-1,0,0,0%29%27 /%3E%3Crect transform=%27matrix%280,1,-1,0,0,0%29%27 style=%27fill:%236e6e6e;%27 x=%2753%27 y=%27-66%27 width=%2713%27 height=%272%27 id=%27rect4657%27 /%3E%3Crect id=%27rect4659%27 height=%271%27 width=%2712%27 y=%2757%27 x=%2754%27 style=%27fill:%236e6e6e;%27 /%3E%3Crect style=%27fill:%23ffffff;%27 x=%2754%27 y=%2788%27 width=%2712%27 height=%272%27 id=%27rect4661%27 /%3E%3Crect style=%27fill:%23ffffff;%27 x=%2780%27 y=%2776%27 width=%273%27 height=%273%27 id=%27rect4663%27 /%3E%3Crect id=%27rect4665%27 height=%273%27 width=%273%27 y=%2776%27 x=%2785%27 style=%27fill:%23ffffff;%27 /%3E%3Crect id=%27rect4667%27 height=%273%27 width=%273%27 y=%2782%27 x=%2780%27 style=%27fill:%23ffffff;%27 /%3E%3Crect style=%27fill:%23ffffff;%27 x=%2785%27 y=%2782%27 width=%273%27 height=%273%27 id=%27rect4669%27 /%3E%3Crect style=%27fill:%23ffffff;%27 x=%2780%27 y=%2788%27 width=%273%27 height=%273%27 id=%27rect4671%27 /%3E%3Crect id=%27rect4673%27 height=%273%27 width=%273%27 y=%2788%27 x=%2785%27 style=%27fill:%23ffffff;%27 /%3E%3Ccircle r=%274.7438836%27 cy=%2781.939331%27 cx=%27110.06081%27 id=%27circle4675%27 style=%27opacity:1;fill:none;stroke:%23ffffff;stroke-width:2;%27 /%3E%3Crect transform=%27matrix%280.70710678,0.70710678,-0.70710678,0.70710678,0,0%29%27 id=%27rect4677%27 height=%276.4053884%27 width=%274.229713%27 y=%27-14.826816%27 x=%27133.6163%27 style=%27fill:%23ffffff;%27 /%3E%3Cpath id=%27path4679%27 d=%27m 125,80.000005 13.77027,0.09499 L 132,87.999992 Z%27 style=%27fill:%23ffffff;%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27M 149,88.0002 162.77027,87.9052 156,80.0002 Z%27 id=%27path4681%27 /%3E%3Crect id=%27rect4683%27 height=%272%27 width=%2712%27 y=%2777%27 x=%2754%27 style=%27fill:%23ffffff;%27 /%3E%3Crect transform=%27matrix%280,1,-1,0,0,0%29%27 style=%27fill:%23ffffff;%27 x=%2777%27 y=%27-56%27 width=%2713%27 height=%272%27 id=%27rect4685%27 /%3E%3Crect id=%27rect4687%27 height=%272%27 width=%2713%27 y=%27-66%27 x=%2777%27 style=%27fill:%23ffffff;%27 transform=%27matrix%280,1,-1,0,0,0%29%27 /%3E%3Crect style=%27fill:%23ffffff;%27 x=%2754%27 y=%2781%27 width=%2712%27 height=%271%27 id=%27rect4689%27 /%3E%3Crect id=%27rect4761-1%27 height=%272%27 width=%2716%27 y=%27101%27 x=%2776%27 style=%27fill:%23ffffff;%27 /%3E%3Crect id=%27rect4761-0%27 height=%272%27 width=%2716%27 y=%27105%27 x=%2776%27 style=%27fill:%23ffffff;%27 /%3E%3Crect id=%27rect4761-7%27 height=%272%27 width=%279%27 y=%27109%27 x=%2776%27 style=%27fill:%23ffffff;%27 /%3E%3Crect id=%27rect4761-1-1%27 height=%272%27 width=%2712%27 y=%27125%27 x=%2776%27 style=%27fill:%23ffffff;%27 /%3E%3Crect id=%27rect4761-1-1-4%27 height=%272%27 width=%2710%27 y=%27137%27 x=%2776%27 style=%27fill:%23ffffff;%27 /%3E%3Crect id=%27rect4761-1-1-4-4%27 height=%272%27 width=%2710%27 y=%27129%27 x=%2782%27 style=%27fill:%23ffffff;%27 /%3E%3Crect id=%27rect4761-1-1-4-4-3%27 height=%272%27 width=%279%27 y=%27133%27 x=%2782%27 style=%27fill:%23ffffff;%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 36.398438,100.0254 c -0.423362,-0.013 -0.846847,0.01 -1.265626,0.062 -1.656562,0.2196 -3.244567,0.9739 -4.507812,2.2266 L 29,100.5991 l -2.324219,7.7129 7.826172,-1.9062 -1.804687,-1.9063 c 1.597702,-1.5308 4.048706,-1.8453 5.984375,-0.7207 1.971162,1.1452 2.881954,3.3975 2.308593,5.5508 -0.573361,2.1533 -2.533865,3.6953 -4.830078,3.6953 l 0,3.0742 c 3.550756,0 6.710442,-2.4113 7.650391,-5.9414 0.939949,-3.5301 -0.618463,-7.2736 -3.710938,-9.0703 -1.159678,-0.6738 -2.431087,-1.0231 -3.701171,-1.0625 z%27 id=%27path4138%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 59.722656,99.9629 c -1.270084,0.039 -2.541493,0.3887 -3.701172,1.0625 -3.092475,1.7967 -4.650886,5.5402 -3.710937,9.0703 0.939949,3.5301 4.09768,5.9414 7.648437,5.9414 l 0,-3.0742 c -2.296214,0 -4.256717,-1.542 -4.830078,-3.6953 -0.573361,-2.1533 0.337432,-4.4056 2.308594,-5.5508 1.935731,-1.1246 4.38863,-0.8102 5.986326,0.7207 l -1.806638,1.9063 7.828128,1.9062 -2.32422,-7.7129 -1.62696,1.7168 c -1.26338,-1.2531 -2.848917,-2.0088 -4.505855,-2.2285 -0.418778,-0.055 -0.842263,-0.076 -1.265625,-0.062 z%27 id=%27path4138-1%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 10.5,100 0,2 -2.4999996,0 L 12,107 l 4,-5 -2.5,0 0,-2 -3,0 z%27 id=%27path3055-0-77%27 /%3E%3Cpath style=%27fill:none;stroke:%23ffffff;%27 d=%27m 4.9850574,108.015 14.0298856,-0.03%27 id=%27path5244-5-0-5%27 /%3E%3Cpath style=%27fill:none;stroke:%23ffffff;%27 d=%27m 4.9849874,132.015 14.0298866,-0.03%27 id=%27path5244-5-0-5-8%27 /%3E%3Cpath style=%27color:%23000000;fill:%236e6e6e;%27 d=%27m 36.398438,123.9629 c -0.423362,-0.013 -0.846847,0.01 -1.265626,0.062 -1.656562,0.2196 -3.244567,0.9739 -4.507812,2.2266 L 29,124.5366 l -2.324219,7.7129 7.826172,-1.9062 -1.804687,-1.9063 c 1.597702,-1.5308 4.048706,-1.8453 5.984375,-0.7207 1.971162,1.1453 2.881954,3.3975 2.308593,5.5508 -0.573361,2.1533 -2.533864,3.6953 -4.830078,3.6953 l 0,3.0742 c 3.550757,0 6.710442,-2.4093 7.650391,-5.9394 0.939949,-3.5301 -0.618463,-7.2756 -3.710938,-9.0723 -1.159678,-0.6737 -2.431087,-1.0231 -3.701171,-1.0625 z%27 id=%27path4138-12%27 /%3E%3Cpath style=%27color:%23000000;fill:%236e6e6e;%27 d=%27m 59.722656,123.9629 c -1.270084,0.039 -2.541493,0.3888 -3.701172,1.0625 -3.092475,1.7967 -4.650886,5.5422 -3.710937,9.0723 0.939949,3.5301 4.09768,5.9394 7.648437,5.9394 l 0,-3.0742 c -2.296214,0 -4.256717,-1.542 -4.830078,-3.6953 -0.573361,-2.1533 0.337432,-4.4055 2.308594,-5.5508 1.935731,-1.1246 4.38863,-0.8102 5.986326,0.7207 l -1.806638,1.9063 7.828128,1.9062 -2.32422,-7.7129 -1.62696,1.7168 c -1.26338,-1.2531 -2.848917,-2.0088 -4.505855,-2.2285 -0.418778,-0.055 -0.842263,-0.076 -1.265625,-0.062 z%27 id=%27path4138-1-3%27 /%3E%3Cpath id=%27path6191%27 d=%27m 10.5,116 0,-2 -2.4999996,0 L 12,109 l 4,5 -2.5,0 0,2 -3,0 z%27 style=%27fill:%23ffffff;stroke-width:1.96599996;%27 /%3E%3Cpath style=%27fill:%23ffffff;stroke-width:1.96599996;%27 d=%27m 10.5,129 0,-2 -2.4999996,0 L 12,122 l 4,5 -2.5,0 0,2 -3,0 z%27 id=%27path6193%27 /%3E%3Cpath id=%27path6195%27 d=%27m 10.5,135 0,2 -2.4999996,0 L 12,142 l 4,-5 -2.5,0 0,-2 -3,0 z%27 style=%27fill:%23ffffff;stroke-width:1.96599996;%27 /%3E%3Cpath sodipodi:type=%27star%27 style=%27fill:%236e6e6e;%27 id=%27path4500%27 sodipodi:sides=%273%27 sodipodi:cx=%2711.55581%27 sodipodi:cy=%2760.073242%27 sodipodi:r1=%275.1116104%27 sodipodi:r2=%272.5558052%27 sodipodi:arg1=%270%27 sodipodi:arg2=%271.0471976%27 inkscape:flatsided=%27false%27 inkscape:rounded=%270%27 inkscape:randomized=%270%27 d=%27m 16.66742,60.073242 -3.833708,2.213392 -3.8337072,2.213393 0,-4.426785 0,-4.426784 3.8337082,2.213392 z%27 inkscape:transform-center-x=%27-1.2779026%27 /%3E%3Cpath inkscape:transform-center-x=%271.277902%27 d=%27m -31.500004,60.073242 -3.833708,2.213392 -3.833707,2.213393 0,-4.426785 0,-4.426784 3.833707,2.213392 z%27 inkscape:randomized=%270%27 inkscape:rounded=%270%27 inkscape:flatsided=%27false%27 sodipodi:arg2=%271.0471976%27 sodipodi:arg1=%270%27 sodipodi:r2=%272.5558052%27 sodipodi:r1=%275.1116104%27 sodipodi:cy=%2760.073242%27 sodipodi:cx=%27-36.611614%27 sodipodi:sides=%273%27 id=%27path4502%27 style=%27fill:%236e6e6e;%27 sodipodi:type=%27star%27 transform=%27scale%28-1,1%29%27 /%3E%3Cpath d=%27m 16.66742,60.073212 -3.833708,2.213392 -3.8337072,2.213392 0,-4.426784 0,-4.426785 3.8337082,2.213392 z%27 inkscape:randomized=%270%27 inkscape:rounded=%270%27 inkscape:flatsided=%27false%27 sodipodi:arg2=%271.0471976%27 sodipodi:arg1=%270%27 sodipodi:r2=%272.5558052%27 sodipodi:r1=%275.1116104%27 sodipodi:cy=%2760.073212%27 sodipodi:cx=%2711.55581%27 sodipodi:sides=%273%27 id=%27path4504%27 style=%27fill:%236e6e6e;%27 sodipodi:type=%27star%27 transform=%27matrix%280,1,-1,0,72.0074,71.7877%29%27 inkscape:transform-center-y=%271.2779029%27 /%3E%3Cpath inkscape:transform-center-y=%27-1.2779026%27 transform=%27matrix%280,-1,-1,0,96,96%29%27 sodipodi:type=%27star%27 style=%27fill:%236e6e6e;%27 id=%27path4506%27 sodipodi:sides=%273%27 sodipodi:cx=%2711.55581%27 sodipodi:cy=%2760.073212%27 sodipodi:r1=%275.1116104%27 sodipodi:r2=%272.5558052%27 sodipodi:arg1=%270%27 sodipodi:arg2=%271.0471976%27 inkscape:flatsided=%27false%27 inkscape:rounded=%270%27 inkscape:randomized=%270%27 d=%27m 16.66742,60.073212 -3.833708,2.213392 -3.8337072,2.213392 0,-4.426784 0,-4.426785 3.8337082,2.213392 z%27 /%3E%3Cpath id=%27path4615-5%27 d=%27m 171.82574,65.174193 16.34854,0 -8.17427,-13.348454 z%27 style=%27fill:%23f9a825;fill-rule:evenodd;stroke:%23f9a825;stroke-width:2;%27 /%3E%3Cpath style=%27opacity:1;fill:%23ffffff;%27 d=%27m 179,55 0,6 2,0 0,-6%27 id=%27path4300%27 /%3E%3Cpath style=%27opacity:1;fill:%23ffffff;%27 d=%27m 179,62 0,2 2,0 0,-2%27 id=%27path4300-6%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27M 99.994369,113.0221 102,114.98353 l 7,-6.9558 3,0.97227 2,-1 1,-2 0,-3 -3,3 -3,-3 3,-3 -3,0 -2,1 -1,2 0.99437,3.0221 z%27 id=%27path4268%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 234,6 0,2 -5,5 0,5 -2,0 0,-5 -5,-5 0,-2%27 id=%27path3546%27 /%3E%3Cg transform=%27matrix%281.3333328,0,0,-1.5999992,-139.9999,127.19999%29%27 id=%27g4383-6%27%3E%3Crect id=%27rect4385-2%27 height=%271%27 width=%276%27 y=%2712.625005%27 x=%27198%27 style=%27fill:%23ffffff;stroke:%23000000;stroke-width:0%27 /%3E%3Crect style=%27fill:%23ffffff;stroke:%23000000;stroke-width:0%27 x=%27198%27 y=%2715.125007%27 width=%278%27 height=%271%27 id=%27rect4387-9%27 /%3E%3Crect style=%27fill:%23ffffff;stroke:%23000000;stroke-width:0%27 x=%27198%27 y=%277.6250024%27 width=%273%27 height=%271%27 id=%27rect4389-1-0%27 /%3E%3Crect style=%27fill:%23ffffff;stroke:%23000000;stroke-width:0%27 x=%27198%27 y=%2710.125004%27 width=%274%27 height=%271%27 id=%27rect4389-1-9%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 207.00001,16.375004 0,-5.625005 -2.25,0 3,-3.1250014 3,3.1250014 -2.25,0 0,5.625005 -1.5,0%27 id=%27path4402%27 /%3E%3C/g%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 164,100 0,3 -6,6 0,7 -4,0 0,-7 -6,-6 0,-3%27 id=%27path3546-2-2%27 /%3E%3Cpath id=%27path4402-5-7%27 d=%27m 15,41 0,-7 -4,0 0,3 -5,-4 5,-4 0,3 6,0 0,9%27 style=%27fill:%23ffffff;%27 /%3E%3C/svg%3E%0A")}.light{--t42-json-icons: url("data:image/svg+xml,%3C%3Fxml version=%271.0%27 encoding=%27UTF-8%27 standalone=%27no%27%3F%3E%3Csvg xmlns:dc=%27http://purl.org/dc/elements/1.1/%27 xmlns:cc=%27http://creativecommons.org/ns%23%27 xmlns:rdf=%27http://www.w3.org/1999/02/22-rdf-syntax-ns%23%27 xmlns:svg=%27http://www.w3.org/2000/svg%27 xmlns=%27http://www.w3.org/2000/svg%27 xmlns:sodipodi=%27http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd%27 xmlns:inkscape=%27http://www.inkscape.org/namespaces/inkscape%27 width=%27240%27 height=%27144%27 id=%27svg4136%27 version=%271.1%27 inkscape:version=%270.91 r13725%27 sodipodi:docname=%27jsoneditor-icons.svg%27%3E%3Ctitle id=%27title6512%27%3EJSON Editor Icons%3C/title%3E%3Crect id=%27svg_1-7%27 height=%2716%27 width=%2716%27 y=%273.999995%27 x=%2728.000006%27 style=%27fill:%23ff511f;%27 /%3E%3Crect x=%277%27 y=%2711%27 width=%2710%27 height=%272%27 id=%27svg_1-1%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect x=%2711%27 y=%277%27 width=%272%27 height=%2710%27 id=%27svg_1-1-1%27 style=%27fill:%230d0d0d;%27 /%3E%3Cg id=%27g4299-3%27 transform=%27matrix%280.70710678,-0.70710678,0.70710678,0.70710678,19.029435,12.000001%29%27 style=%27%27%3E%3Crect x=%277%27 y=%2711%27 width=%2710%27 height=%272%27 id=%27svg_1-1-0%27 style=%27fill:%23ffffff;%27 /%3E%3Crect x=%2711%27 y=%277%27 width=%272%27 height=%2710%27 id=%27svg_1-1-1-9%27 style=%27fill:%23ffffff;%27 /%3E%3C/g%3E%3Crect height=%277%27 width=%277%27 y=%277%27 x=%2755%27 style=%27fill:%230d0d0d;stroke-width:1;stroke:%230d0d0d%27 /%3E%3Crect id=%27svg_1-7-5-7%27 height=%277%27 width=%277%27 y=%2710%27 x=%2758%27 style=%27fill:%230d0d0d;stroke-width:1;stroke:%23ffffff%27 /%3E%3Cg id=%27g4378%27%3E%3Crect style=%27fill:%230d0d0d;%27 x=%27198%27 y=%2711%27 width=%278%27 height=%272%27 id=%27svg_1-7-5-3%27 /%3E%3Crect id=%27rect4374%27 height=%272%27 width=%2712%27 y=%277%27 x=%27198%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect id=%27rect4376%27 height=%272%27 width=%274%27 y=%2715%27 x=%27198%27 style=%27fill:%230d0d0d;%27 /%3E%3C/g%3E%3Cg transform=%27matrix%281,0,0,-1,-23.999995,23.999995%29%27 id=%27g4383%27%3E%3Crect id=%27rect4385%27 height=%272%27 width=%278%27 y=%2711%27 x=%27198%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect style=%27fill:%230d0d0d;%27 x=%27198%27 y=%277%27 width=%2712%27 height=%272%27 id=%27rect4387%27 /%3E%3Crect style=%27fill:%230d0d0d;%27 x=%27198%27 y=%2715%27 width=%274%27 height=%272%27 id=%27rect4389%27 /%3E%3C/g%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 85.10447,6.0157384 -0.0156,1.4063 c 3.02669,-0.2402 0.33008,3.6507996 2.48438,4.5780996 -2.18694,1.0938 0.49191,4.9069 -2.45313,4.5781 l -0.0156,1.4219 c 5.70828,0.559 1.03264,-5.1005 4.70313,-5.2656 l 0,-1.4063 c -3.61303,-0.027 1.11893,-5.7069996 -4.70313,-5.3124996 z%27 id=%27path4351%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 82.78125,5.9984384 0.0156,1.4063 c -3.02668,-0.2402 -0.33007,3.6506996 -2.48437,4.5780996 2.18694,1.0938 -0.49192,4.9069 2.45312,4.5781 l 0.0156,1.4219 c -5.70827,0.559 -1.03263,-5.1004 -4.70312,-5.2656 l 0,-1.4063 c 3.61303,-0.027 -1.11894,-5.7070996 4.70312,-5.3124996 z%27 id=%27path4351-9%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 103.719,5.6719384 0,12.7187996 3.03125,0 0,-1.5313 -1.34375,0 0,-9.6249996 1.375,0 0,-1.5625 z%27 id=%27path2987%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 112.2185,5.6721984 0,12.7187996 -3.03125,0 0,-1.5313 1.34375,0 0,-9.6249996 -1.375,0 0,-1.5625 z%27 id=%27path2987-1%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27M133,6.4h-1.9l-4.8,11.2h1.8l1.1-2.9h5.7l1.1,2.9h1.8L133,6.4z M129.7,13.5l2.3-5.5l2.3,5.5L129.7,13.5z%27 id=%27path3780%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 156.47655,5.8917384 0,2.1797 0.46093,2.3983996 1.82813,0 0.39844,-2.3983996 0,-2.1797 z%27 id=%27path5008-2%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 152.51561,5.8906384 0,2.1797 0.46094,2.3983996 1.82812,0 0.39844,-2.3983996 0,-2.1797 z%27 id=%27path5008-2-8%27 /%3E%3Crect id=%27svg_1-7-2%27 height=%272%27 width=%2712%27 y=%2764%27 x=%2754%27 style=%27fill:%236e6e6e;%27 /%3E%3Crect id=%27svg_1-7-2-2%27 height=%273%27 width=%273%27 y=%2752%27 x=%2780%27 style=%27fill:%236e6e6e;%27 /%3E%3Crect style=%27fill:%236e6e6e;%27 x=%2785%27 y=%2752%27 width=%273%27 height=%273%27 id=%27rect4561%27 /%3E%3Crect style=%27fill:%236e6e6e;%27 x=%2780%27 y=%2758%27 width=%273%27 height=%273%27 id=%27rect4563%27 /%3E%3Crect id=%27rect4565%27 height=%273%27 width=%273%27 y=%2758%27 x=%2785%27 style=%27fill:%236e6e6e;%27 /%3E%3Crect id=%27rect4567%27 height=%273%27 width=%273%27 y=%2764%27 x=%2780%27 style=%27fill:%236e6e6e;%27 /%3E%3Crect style=%27fill:%236e6e6e;%27 x=%2785%27 y=%2764%27 width=%273%27 height=%273%27 id=%27rect4569%27 /%3E%3Ccircle style=%27opacity:1;fill:none;stroke:%236e6e6e;stroke-width:2;%27 id=%27path4571%27 cx=%27110.06081%27 cy=%2757.939209%27 r=%274.7438836%27 /%3E%3Crect style=%27fill:%236e6e6e;%27 x=%27116.64566%27 y=%27-31.79752%27 width=%274.229713%27 height=%276.4053884%27 id=%27rect4563-2%27 transform=%27matrix%280.70710678,0.70710678,-0.70710678,0.70710678,0,0%29%27 /%3E%3Cpath style=%27fill:%236e6e6e;fill-rule:evenodd;%27 d=%27M 125,56 138.77027,56.095 132,64 Z%27 id=%27path4613%27 /%3E%3Cpath id=%27path4615%27 d=%27M 149,64 162.77027,63.905 156,56 Z%27 style=%27fill:%236e6e6e;fill-rule:evenodd;%27 /%3E%3Crect style=%27fill:%236e6e6e;%27 x=%2754%27 y=%2753%27 width=%2712%27 height=%272%27 id=%27rect4638%27 /%3E%3Crect id=%27svg_1-7-2-24%27 height=%272%27 width=%2713%27 y=%27-56%27 x=%2753%27 style=%27fill:%236e6e6e;%27 transform=%27matrix%280,1,-1,0,0,0%29%27 /%3E%3Crect transform=%27matrix%280,1,-1,0,0,0%29%27 style=%27fill:%236e6e6e;%27 x=%2753%27 y=%27-66%27 width=%2713%27 height=%272%27 id=%27rect4657%27 /%3E%3Crect id=%27rect4659%27 height=%271%27 width=%2712%27 y=%2757%27 x=%2754%27 style=%27fill:%236e6e6e;%27 /%3E%3Crect style=%27fill:%230d0d0d;%27 x=%2754%27 y=%2788%27 width=%2712%27 height=%272%27 id=%27rect4661%27 /%3E%3Crect style=%27fill:%230d0d0d;%27 x=%2780%27 y=%2776%27 width=%273%27 height=%273%27 id=%27rect4663%27 /%3E%3Crect id=%27rect4665%27 height=%273%27 width=%273%27 y=%2776%27 x=%2785%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect id=%27rect4667%27 height=%273%27 width=%273%27 y=%2782%27 x=%2780%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect style=%27fill:%230d0d0d;%27 x=%2785%27 y=%2782%27 width=%273%27 height=%273%27 id=%27rect4669%27 /%3E%3Crect style=%27fill:%230d0d0d;%27 x=%2780%27 y=%2788%27 width=%273%27 height=%273%27 id=%27rect4671%27 /%3E%3Crect id=%27rect4673%27 height=%273%27 width=%273%27 y=%2788%27 x=%2785%27 style=%27fill:%230d0d0d;%27 /%3E%3Ccircle r=%274.7438836%27 cy=%2781.939331%27 cx=%27110.06081%27 id=%27circle4675%27 style=%27opacity:1;fill:none;stroke:%230d0d0d;stroke-width:2;%27 /%3E%3Crect transform=%27matrix%280.70710678,0.70710678,-0.70710678,0.70710678,0,0%29%27 id=%27rect4677%27 height=%276.4053884%27 width=%274.229713%27 y=%27-14.826816%27 x=%27133.6163%27 style=%27fill:%230d0d0d;%27 /%3E%3Cpath id=%27path4679%27 d=%27m 125,80.000005 13.77027,0.09499 L 132,87.999992 Z%27 style=%27fill:%230d0d0d;%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27M 149,88.0002 162.77027,87.9052 156,80.0002 Z%27 id=%27path4681%27 /%3E%3Crect id=%27rect4683%27 height=%272%27 width=%2712%27 y=%2777%27 x=%2754%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect transform=%27matrix%280,1,-1,0,0,0%29%27 style=%27fill:%230d0d0d;%27 x=%2777%27 y=%27-56%27 width=%2713%27 height=%272%27 id=%27rect4685%27 /%3E%3Crect id=%27rect4687%27 height=%272%27 width=%2713%27 y=%27-66%27 x=%2777%27 style=%27fill:%230d0d0d;%27 transform=%27matrix%280,1,-1,0,0,0%29%27 /%3E%3Crect style=%27fill:%230d0d0d;%27 x=%2754%27 y=%2781%27 width=%2712%27 height=%271%27 id=%27rect4689%27 /%3E%3Crect id=%27rect4761-1%27 height=%272%27 width=%2716%27 y=%27101%27 x=%2776%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect id=%27rect4761-0%27 height=%272%27 width=%2716%27 y=%27105%27 x=%2776%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect id=%27rect4761-7%27 height=%272%27 width=%279%27 y=%27109%27 x=%2776%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect id=%27rect4761-1-1%27 height=%272%27 width=%2712%27 y=%27125%27 x=%2776%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect id=%27rect4761-1-1-4%27 height=%272%27 width=%2710%27 y=%27137%27 x=%2776%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect id=%27rect4761-1-1-4-4%27 height=%272%27 width=%2710%27 y=%27129%27 x=%2782%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect id=%27rect4761-1-1-4-4-3%27 height=%272%27 width=%279%27 y=%27133%27 x=%2782%27 style=%27fill:%230d0d0d;%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 36.398438,100.0254 c -0.423362,-0.013 -0.846847,0.01 -1.265626,0.062 -1.656562,0.2196 -3.244567,0.9739 -4.507812,2.2266 L 29,100.5991 l -2.324219,7.7129 7.826172,-1.9062 -1.804687,-1.9063 c 1.597702,-1.5308 4.048706,-1.8453 5.984375,-0.7207 1.971162,1.1452 2.881954,3.3975 2.308593,5.5508 -0.573361,2.1533 -2.533865,3.6953 -4.830078,3.6953 l 0,3.0742 c 3.550756,0 6.710442,-2.4113 7.650391,-5.9414 0.939949,-3.5301 -0.618463,-7.2736 -3.710938,-9.0703 -1.159678,-0.6738 -2.431087,-1.0231 -3.701171,-1.0625 z%27 id=%27path4138%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 59.722656,99.9629 c -1.270084,0.039 -2.541493,0.3887 -3.701172,1.0625 -3.092475,1.7967 -4.650886,5.5402 -3.710937,9.0703 0.939949,3.5301 4.09768,5.9414 7.648437,5.9414 l 0,-3.0742 c -2.296214,0 -4.256717,-1.542 -4.830078,-3.6953 -0.573361,-2.1533 0.337432,-4.4056 2.308594,-5.5508 1.935731,-1.1246 4.38863,-0.8102 5.986326,0.7207 l -1.806638,1.9063 7.828128,1.9062 -2.32422,-7.7129 -1.62696,1.7168 c -1.26338,-1.2531 -2.848917,-2.0088 -4.505855,-2.2285 -0.418778,-0.055 -0.842263,-0.076 -1.265625,-0.062 z%27 id=%27path4138-1%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 10.5,100 0,2 -2.4999996,0 L 12,107 l 4,-5 -2.5,0 0,-2 -3,0 z%27 id=%27path3055-0-77%27 /%3E%3Cpath style=%27fill:none;stroke:%230d0d0d;%27 d=%27m 4.9850574,108.015 14.0298856,-0.03%27 id=%27path5244-5-0-5%27 /%3E%3Cpath style=%27fill:none;stroke:%230d0d0d;%27 d=%27m 4.9849874,132.015 14.0298866,-0.03%27 id=%27path5244-5-0-5-8%27 /%3E%3Cpath style=%27color:%23000000;fill:%236e6e6e;%27 d=%27m 36.398438,123.9629 c -0.423362,-0.013 -0.846847,0.01 -1.265626,0.062 -1.656562,0.2196 -3.244567,0.9739 -4.507812,2.2266 L 29,124.5366 l -2.324219,7.7129 7.826172,-1.9062 -1.804687,-1.9063 c 1.597702,-1.5308 4.048706,-1.8453 5.984375,-0.7207 1.971162,1.1453 2.881954,3.3975 2.308593,5.5508 -0.573361,2.1533 -2.533864,3.6953 -4.830078,3.6953 l 0,3.0742 c 3.550757,0 6.710442,-2.4093 7.650391,-5.9394 0.939949,-3.5301 -0.618463,-7.2756 -3.710938,-9.0723 -1.159678,-0.6737 -2.431087,-1.0231 -3.701171,-1.0625 z%27 id=%27path4138-12%27 /%3E%3Cpath style=%27color:%23000000;fill:%236e6e6e;%27 d=%27m 59.722656,123.9629 c -1.270084,0.039 -2.541493,0.3888 -3.701172,1.0625 -3.092475,1.7967 -4.650886,5.5422 -3.710937,9.0723 0.939949,3.5301 4.09768,5.9394 7.648437,5.9394 l 0,-3.0742 c -2.296214,0 -4.256717,-1.542 -4.830078,-3.6953 -0.573361,-2.1533 0.337432,-4.4055 2.308594,-5.5508 1.935731,-1.1246 4.38863,-0.8102 5.986326,0.7207 l -1.806638,1.9063 7.828128,1.9062 -2.32422,-7.7129 -1.62696,1.7168 c -1.26338,-1.2531 -2.848917,-2.0088 -4.505855,-2.2285 -0.418778,-0.055 -0.842263,-0.076 -1.265625,-0.062 z%27 id=%27path4138-1-3%27 /%3E%3Cpath id=%27path6191%27 d=%27m 10.5,116 0,-2 -2.4999996,0 L 12,109 l 4,5 -2.5,0 0,2 -3,0 z%27 style=%27fill:%230d0d0d;stroke-width:2;%27 /%3E%3Cpath style=%27fill:%230d0d0d;stroke-width:2;%27 d=%27m 10.5,129 0,-2 -2.4999996,0 L 12,122 l 4,5 -2.5,0 0,2 -3,0 z%27 id=%27path6193%27 /%3E%3Cpath id=%27path6195%27 d=%27m 10.5,135 0,2 -2.4999996,0 L 12,142 l 4,-5 -2.5,0 0,-2 -3,0 z%27 style=%27fill:%230d0d0d;stroke-width:2;%27 /%3E%3Cpath sodipodi:type=%27star%27 style=%27fill:%236e6e6e;%27 id=%27path4500%27 sodipodi:sides=%273%27 sodipodi:cx=%2711.55581%27 sodipodi:cy=%2760.073242%27 sodipodi:r1=%275.1116104%27 sodipodi:r2=%272.5558052%27 sodipodi:arg1=%270%27 sodipodi:arg2=%271.0471976%27 inkscape:flatsided=%27false%27 inkscape:rounded=%270%27 inkscape:randomized=%270%27 d=%27m 16.66742,60.073242 -3.833708,2.213392 -3.8337072,2.213393 0,-4.426785 0,-4.426784 3.8337082,2.213392 z%27 inkscape:transform-center-x=%27-1.2779026%27 /%3E%3Cpath inkscape:transform-center-x=%271.277902%27 d=%27m -31.500004,60.073242 -3.833708,2.213392 -3.833707,2.213393 0,-4.426785 0,-4.426784 3.833707,2.213392 z%27 inkscape:randomized=%270%27 inkscape:rounded=%270%27 inkscape:flatsided=%27false%27 sodipodi:arg2=%271.0471976%27 sodipodi:arg1=%270%27 sodipodi:r2=%272.5558052%27 sodipodi:r1=%275.1116104%27 sodipodi:cy=%2760.073242%27 sodipodi:cx=%27-36.611614%27 sodipodi:sides=%273%27 id=%27path4502%27 style=%27fill:%236e6e6e;%27 sodipodi:type=%27star%27 transform=%27scale%28-1,1%29%27 /%3E%3Cpath d=%27m 16.66742,60.073212 -3.833708,2.213392 -3.8337072,2.213392 0,-4.426784 0,-4.426785 3.8337082,2.213392 z%27 inkscape:randomized=%270%27 inkscape:rounded=%270%27 inkscape:flatsided=%27false%27 sodipodi:arg2=%271.0471976%27 sodipodi:arg1=%270%27 sodipodi:r2=%272.5558052%27 sodipodi:r1=%275.1116104%27 sodipodi:cy=%2760.073212%27 sodipodi:cx=%2711.55581%27 sodipodi:sides=%273%27 id=%27path4504%27 style=%27fill:%236e6e6e;%27 sodipodi:type=%27star%27 transform=%27matrix%280,1,-1,0,72.0074,71.7877%29%27 inkscape:transform-center-y=%271.2779029%27 /%3E%3Cpath inkscape:transform-center-y=%27-1.2779026%27 transform=%27matrix%280,-1,-1,0,96,96%29%27 sodipodi:type=%27star%27 style=%27fill:%236e6e6e;%27 id=%27path4506%27 sodipodi:sides=%273%27 sodipodi:cx=%2711.55581%27 sodipodi:cy=%2760.073212%27 sodipodi:r1=%275.1116104%27 sodipodi:r2=%272.5558052%27 sodipodi:arg1=%270%27 sodipodi:arg2=%271.0471976%27 inkscape:flatsided=%27false%27 inkscape:rounded=%270%27 inkscape:randomized=%270%27 d=%27m 16.66742,60.073212 -3.833708,2.213392 -3.8337072,2.213392 0,-4.426784 0,-4.426785 3.8337082,2.213392 z%27 /%3E%3Cpath id=%27path4615-5%27 d=%27m 171.82574,65.174193 16.34854,0 -8.17427,-13.348454 z%27 style=%27fill:%23f9a825;fill-rule:evenodd;stroke:%23f9a825;stroke-width:2;%27 /%3E%3Cpath style=%27opacity:1;fill:%23ffffff;%27 d=%27m 179,55 0,6 2,0 0,-6%27 id=%27path4300%27 /%3E%3Cpath style=%27opacity:1;fill:%23ffffff;%27 d=%27m 179,62 0,2 2,0 0,-2%27 id=%27path4300-6%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27M 99.994369,113.0221 102,114.98353 l 7,-6.9558 3,0.97227 2,-1 1,-2 0,-3 -3,3 -3,-3 3,-3 -3,0 -2,1 -1,2 0.99437,3.0221 z%27 id=%27path4268%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 234,6 0,2 -5,5 0,5 -2,0 0,-5 -5,-5 0,-2%27 id=%27path3546%27 /%3E%3Cg transform=%27matrix%281.3333328,0,0,-1.5999992,-139.9999,127.19999%29%27 id=%27g4383-6%27%3E%3Crect id=%27rect4385-2%27 height=%271%27 width=%276%27 y=%2712.625005%27 x=%27198%27 style=%27fill:%230d0d0d;stroke:%23000000;stroke-width:0%27 /%3E%3Crect style=%27fill:%230d0d0d;stroke:%23000000;stroke-width:0%27 x=%27198%27 y=%2715.125007%27 width=%278%27 height=%271%27 id=%27rect4387-9%27 /%3E%3Crect style=%27fill:%230d0d0d;stroke:%23000000;stroke-width:0%27 x=%27198%27 y=%277.6250024%27 width=%273%27 height=%271%27 id=%27rect4389-1-0%27 /%3E%3Crect style=%27fill:%230d0d0d;stroke:%23000000;stroke-width:0%27 x=%27198%27 y=%2710.125004%27 width=%274%27 height=%271%27 id=%27rect4389-1-9%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 207.00001,16.375004 0,-5.625005 -2.25,0 3,-3.1250014 3,3.1250014 -2.25,0 0,5.625005 -1.5,0%27 id=%27path4402%27 /%3E%3C/g%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 164,100 0,3 -6,6 0,7 -4,0 0,-7 -6,-6 0,-3%27 id=%27path3546-2-2%27 /%3E%3Cpath id=%27path4402-5-7%27 d=%27m 15,41 0,-7 -4,0 0,3 -5,-4 5,-4 0,3 6,0 0,9%27 style=%27fill:%230d0d0d;%27 /%3E%3C/svg%3E%0A")}body{/*! + * Selectr 2.4.13 + * http://mobius.ovh/docs/selectr + * + * Released under the MIT license + */}body .jsoneditor,body .jsoneditor-modal{-webkit-text-size-adjust:none;text-size-adjust:none}body .jsoneditor input,body .jsoneditor input:not([type]),body .jsoneditor input[type="text"],body .jsoneditor input[type="search"],body .jsoneditor-modal input,body .jsoneditor-modal input:not([type]),body .jsoneditor-modal input[type="text"],body .jsoneditor-modal input[type="search"]{height:auto;border:inherit;box-shadow:none;font-size:inherit;box-sizing:inherit;padding:inherit;font-family:inherit;transition:none;line-height:inherit}body .jsoneditor input:focus,body .jsoneditor input:not([type]):focus,body .jsoneditor input[type="text"]:focus,body .jsoneditor input[type="search"]:focus,body .jsoneditor-modal input:focus,body .jsoneditor-modal input:not([type]):focus,body .jsoneditor-modal input[type="text"]:focus,body .jsoneditor-modal input[type="search"]:focus{border:inherit;box-shadow:inherit}body .jsoneditor textarea,body .jsoneditor-modal textarea{height:inherit}body .jsoneditor select,body .jsoneditor-modal select{display:inherit;height:inherit}body .jsoneditor label,body .jsoneditor-modal label{font-size:inherit;font-weight:inherit;color:inherit}body .jsoneditor table,body .jsoneditor-modal table{border-collapse:collapse;width:auto}body .jsoneditor td,body .jsoneditor th,body .jsoneditor-modal td,body .jsoneditor-modal th{padding:0;display:table-cell;text-align:left;vertical-align:inherit;border-radius:inherit}body .jsoneditor .autocomplete.dropdown{position:absolute;background:var(--t42-content-color);box-shadow:var(--t42-shadow);border:1px solid var(--t42-color-opacity-10);overflow-x:hidden;overflow-y:auto;cursor:default;margin:0;padding:5px;text-align:left;outline:0;font-family:var(--bs-font-monospace);font-size:var(--t42-font-size)}body .jsoneditor .autocomplete.dropdown .item{color:var(--t42-content-color)}body .jsoneditor .autocomplete.dropdown .item.hover{background-color:Rgb(var(--t42-bg-mid))}body .jsoneditor .autocomplete.hint{color:var(--t42-content-color);top:4px;left:4px}body .jsoneditor-contextmenu-root{position:relative;width:0;height:0}body .jsoneditor-contextmenu{position:absolute;box-sizing:content-box;z-index:2}body .jsoneditor-contextmenu .jsoneditor-menu{position:relative;left:0;top:0;width:128px;height:auto;background:var(--t42-content-color);border:1px solid var(--t42-color-opacity-10);box-shadow:var(--t42-shadow);list-style:none;margin:0;padding:0}body .jsoneditor-contextmenu .jsoneditor-menu button{position:relative;padding:0 8px 0 0;margin:0;width:128px;height:auto;border:none;cursor:pointer;color:var(--t42-content-color);background:transparent;font-size:var(--t42-font-size);font-family:var(--t42-font-family);box-sizing:border-box;text-align:left}body .jsoneditor-contextmenu .jsoneditor-menu button::-moz-focus-inner{padding:0;border:0}body .jsoneditor-contextmenu .jsoneditor-menu button.jsoneditor-default{width:96px}body .jsoneditor-contextmenu .jsoneditor-menu button.jsoneditor-expand{float:right;width:32px;height:24px;border-left:1px solid var(--t42-color-opacity-10)}body .jsoneditor-contextmenu .jsoneditor-menu li{overflow:hidden}body .jsoneditor-contextmenu .jsoneditor-menu li ul{display:none;position:relative;left:-10px;top:0;border:none;box-shadow:inset var(--t42-shadow);padding:0 10px;-webkit-transition:all 0.3s ease-out;-moz-transition:all 0.3s ease-out;-o-transition:all 0.3s ease-out;transition:all 0.3s ease-out}body .jsoneditor-contextmenu .jsoneditor-menu li ul .jsoneditor-icon{margin-left:24px}body .jsoneditor-contextmenu .jsoneditor-menu li ul li button{padding-left:24px;animation:all ease-in-out 1s}body .jsoneditor-contextmenu .jsoneditor-menu li button .jsoneditor-expand{position:absolute;top:0;right:0;width:24px;height:24px;padding:0;margin:0 4px 0 0;background-image:"/";background-position:0 -72px}body .jsoneditor-contextmenu .jsoneditor-icon{position:absolute;top:0;left:0;width:24px;height:24px;border:none;padding:0;margin:0;background-image:"/"}body .jsoneditor-contextmenu .jsoneditor-text{padding:4px 0 4px 24px;word-wrap:break-word}body .jsoneditor-contextmenu .jsoneditor-text.jsoneditor-right-margin{padding-right:24px}body .jsoneditor-contextmenu .jsoneditor-separator{height:0;border-top:1px solid var(--t42-color-opacity-10);padding-top:5px;margin-top:5px}body .jsoneditor-contextmenu button.jsoneditor-remove .jsoneditor-icon{background-position:-24px 0}body .jsoneditor-contextmenu button.jsoneditor-append .jsoneditor-icon{background-position:0 0}body .jsoneditor-contextmenu button.jsoneditor-insert .jsoneditor-icon{background-position:0 0}body .jsoneditor-contextmenu button.jsoneditor-duplicate .jsoneditor-icon{background-position:-48px 0}body .jsoneditor-contextmenu button.jsoneditor-sort-asc .jsoneditor-icon{background-position:-168px 0}body .jsoneditor-contextmenu button.jsoneditor-sort-desc .jsoneditor-icon{background-position:-192px 0}body .jsoneditor-contextmenu button.jsoneditor-transform .jsoneditor-icon{background-position:-216px 0}body .jsoneditor-contextmenu button.jsoneditor-extract .jsoneditor-icon{background-position:0 -24px}body .jsoneditor-contextmenu button.jsoneditor-type-string .jsoneditor-icon{background-position:-144px 0}body .jsoneditor-contextmenu button.jsoneditor-type-auto .jsoneditor-icon{background-position:-120px 0}body .jsoneditor-contextmenu button.jsoneditor-type-object .jsoneditor-icon{background-position:-72px 0}body .jsoneditor-contextmenu button.jsoneditor-type-array .jsoneditor-icon{background-position:-96px 0}body .jsoneditor-contextmenu button.jsoneditor-type-modes .jsoneditor-icon{background-image:none;width:6px}body .jsoneditor-contextmenu ul,body .jsoneditor-contextmenu li{box-sizing:content-box;position:relative}body .jsoneditor-contextmenu .jsoneditor-menu button:hover,body .jsoneditor-contextmenu .jsoneditor-menu button:focus{color:var(--t42-content-color);background-color:var(--t42-color-opacity-10);outline:none}body .jsoneditor-contextmenu .jsoneditor-menu li button.jsoneditor-selected,body .jsoneditor-contextmenu .jsoneditor-menu li button.jsoneditor-selected:hover,body .jsoneditor-contextmenu .jsoneditor-menu li button.jsoneditor-selected:focus{color:var(--t42-content-color);background-color:var(--red)}body .jsoneditor-contextmenu .jsoneditor-menu li ul li button:hover,body .jsoneditor-contextmenu .jsoneditor-menu li ul li button:focus{background-color:var(--t42-color-opacity-10)}body .jsoneditor-modal{max-width:95%;border-radius:2px !important;padding:45px 15px 15px 15px !important;box-shadow:var(--t42-shadow);color:var(--t42-content-color);line-height:1.3em}body .jsoneditor-modal.jsoneditor-modal-transform{width:600px !important}body .jsoneditor-modal .pico-modal-header{position:absolute;box-sizing:border-box;top:0;left:0;width:100%;padding:0 10px;height:30px;line-height:30px;font-family:var(--t42-font-family);font-size:11pt;background:var(--primary);color:var(--t42-content-color)}body .jsoneditor-modal table{width:100%}body .jsoneditor-modal table td{padding:3px 0}body .jsoneditor-modal table td.jsoneditor-modal-input{text-align:right;padding-right:0;white-space:nowrap}body .jsoneditor-modal table td.jsoneditor-modal-actions{padding-top:15px}body .jsoneditor-modal table th{vertical-align:middle}body .jsoneditor-modal p:first-child{margin-top:0}body .jsoneditor-modal a{color:var(--primary)}body .jsoneditor-modal .jsoneditor-jmespath-block{margin-bottom:10px}body .jsoneditor-modal .pico-close{background:none !important;font-size:24px !important;top:7px !important;right:7px !important;color:var(--t42-content-color)}body .jsoneditor-modal input{padding:4px}body .jsoneditor-modal input[type="text"]{cursor:inherit}body .jsoneditor-modal input[disabled]{background:var(--t42-content-color-muted);color:var(--t42-content-color-muted)}body .jsoneditor-modal .jsoneditor-select-wrapper{position:relative;display:inline-block}body .jsoneditor-modal .jsoneditor-select-wrapper:after{content:"";width:0;height:0;border-left:5px solid transparent;border-right:5px solid transparent;border-top:6px solid #666;position:absolute;right:8px;top:14px;pointer-events:none}body .jsoneditor-modal select{padding:3px 24px 3px 10px;min-width:180px;max-width:350px;-webkit-appearance:none;-moz-appearance:none;appearance:none;text-indent:0;text-overflow:"";font-size:var(--t42-font-size);line-height:1.5em}body .jsoneditor-modal select::-ms-expand{display:none}body .jsoneditor-modal .jsoneditor-button-group input{padding:4px 10px;margin:0;border-radius:0;border-left-style:none}body .jsoneditor-modal .jsoneditor-button-group input.jsoneditor-button-first{border-top-left-radius:3px;border-bottom-left-radius:3px;border-left-style:solid}body .jsoneditor-modal .jsoneditor-button-group input.jsoneditor-button-last{border-top-right-radius:3px;border-bottom-right-radius:3px}body .jsoneditor-modal .jsoneditor-transform-preview{background:var(--t42-color-opacity-10);height:200px}body .jsoneditor-modal .jsoneditor-transform-preview.jsoneditor-error{color:var(--red)}body .jsoneditor-modal .jsoneditor-jmespath-wizard{line-height:1.2em;width:100%;padding:0;border-radius:3px}body .jsoneditor-modal .jsoneditor-jmespath-label{font-weight:bold;color:dodgerblue;margin-top:20px;margin-bottom:5px}body .jsoneditor-modal .jsoneditor-jmespath-wizard-table{width:100%;border-collapse:collapse}body .jsoneditor-modal .jsoneditor-jmespath-wizard-label{font-style:italic;margin:4px 0 2px 0}body .jsoneditor-modal .jsoneditor-inline{position:relative;display:inline-block;width:100%;padding-top:2px;padding-bottom:2px}body .jsoneditor-modal .jsoneditor-inline:not(:last-child){padding-right:2px}body .jsoneditor-modal .jsoneditor-jmespath-filter{display:flex;flex-wrap:wrap}body .jsoneditor-modal .jsoneditor-jmespath-filter-field{width:180px}body .jsoneditor-modal .jsoneditor-jmespath-filter-relation{width:100px}body .jsoneditor-modal .jsoneditor-jmespath-filter-value{min-width:180px;flex:1}body .jsoneditor-modal .jsoneditor-jmespath-sort-field{width:170px}body .jsoneditor-modal .jsoneditor-jmespath-sort-order{width:150px}body .jsoneditor-modal .jsoneditor-jmespath-select-fields{width:100%}body .jsoneditor-modal .selectr-selected{border-color:var(--t42-color-opacity-10);padding:4px 28px 4px 8px}body .jsoneditor-modal .selectr-selected .selectr-tag{background-color:var(--primary);border-radius:5px}body .jsoneditor-modal table th,body .jsoneditor-modal table td{text-align:left;vertical-align:middle;font-weight:normal;color:var(--t42-content-color);border-spacing:0;border-collapse:collapse}body .jsoneditor-modal select,body .jsoneditor-modal textarea,body .jsoneditor-modal input,body .jsoneditor-modal input[type="text"],body .jsoneditor-modal input[type="text"]:focus,body .jsoneditor-modal #query{background:#ffffff;border:1px solid var(--t42-color-opacity-10);color:var(--t42-content-color);border-radius:3px;padding:4px}body .jsoneditor-modal textarea,body .jsoneditor-modal #query{border-radius:unset}body .jsoneditor-modal,body .jsoneditor-modal table td,body .jsoneditor-modal table th,body .jsoneditor-modal select,body .jsoneditor-modal option,body .jsoneditor-modal textarea,body .jsoneditor-modal input,body .jsoneditor-modal input[type="text"],body .jsoneditor-modal #query{font-size:10.5pt;font-family:var(--t42-font-family)}body .jsoneditor-modal #query,body .jsoneditor-modal .jsoneditor-transform-preview{font-family:var(--bs-font-monospace);font-size:var(--t42-font-size);width:100%;box-sizing:border-box}body .jsoneditor-modal input[type="button"],body .jsoneditor-modal input[type="submit"]{background:var(--t42-color-opacity-10);padding:4px 20px}body .jsoneditor-modal select,body .jsoneditor-modal input{cursor:pointer}body .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-asc input.jsoneditor-button-asc,body .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-desc input.jsoneditor-button-desc{background:var(--primary);border-color:var(--primary);color:var(--t42-content-color)}body .jsoneditor{color:var(--t42-content-color);border:thin solid var(--primary);-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;width:100%;height:100%;position:relative;padding:0;line-height:100%}body div.jsoneditor-field,body div.jsoneditor-value,body a.jsoneditor-value,body div.jsoneditor-readonly,body div.jsoneditor-default{border:1px solid transparent;min-height:16px;min-width:32px;line-height:16px;padding:2px;margin:1px;word-wrap:break-word;word-break:break-word;overflow-wrap:break-word;float:left}body div.jsoneditor-field p,body div.jsoneditor-value p{margin:0}body div.jsoneditor-value.jsoneditor-empty::after{content:"value"}body div.jsoneditor-value.jsoneditor-string{color:var(--green)}body div.jsoneditor-value.jsoneditor-number{color:var(--red)}body div.jsoneditor-value.jsoneditor-boolean{color:var(--yellow)}body div.jsoneditor-value.jsoneditor-null{color:var(--primary)}body div.jsoneditor-value.jsoneditor-color-value{color:var(--t42-content-color)}body div.jsoneditor-value.jsoneditor-invalid{color:var(--white)}body div.jsoneditor-readonly{min-width:16px;color:var(--t42-content-color-muted)}body div.jsoneditor-empty{border-color:var(--t42-color-opacity-10);border-style:dashed;border-radius:2px}body div.jsoneditor-field.jsoneditor-empty::after{content:"field"}body div.jsoneditor td{vertical-align:top}body div.jsoneditor td.jsoneditor-separator{padding:3px 0;vertical-align:top;color:var(--t42-content-color-muted)}body div.jsoneditor td.jsoneditor-tree{vertical-align:top}body div.jsoneditor.busy pre.jsoneditor-preview{background:var(--t42-color-opacity-10);color:var(--t42-content-color-muted)}body div.jsoneditor.busy div.jsoneditor-busy{display:inherit}body div.jsoneditor code.jsoneditor-preview{background:none}body div.jsoneditor.jsoneditor-mode-preview pre.jsoneditor-preview{width:100%;height:100%;box-sizing:border-box;overflow:auto;padding:2px;margin:0;white-space:pre-wrap;word-break:break-all}body div.jsoneditor-default{color:var(--t42-content-color-muted);padding-left:10px}body div.jsoneditor-tree{width:100%;height:100%;position:relative;overflow:auto;background:var(--t42-content-color)}body div.jsoneditor-tree button.jsoneditor-button{width:24px;height:24px;padding:0;margin:0;border:none;cursor:pointer;background-color:transparent;background-image:"/"}body div.jsoneditor-tree button.jsoneditor-button:focus{background-color:var(--t42-color-opacity-10);outline:#e5e5e5 solid 1px}body div.jsoneditor-tree button.jsoneditor-collapsed{background-position:0 -48px}body div.jsoneditor-tree button.jsoneditor-expanded{background-position:0 -72px}body div.jsoneditor-tree button.jsoneditor-contextmenu-button{background-position:-48px -72px}body div.jsoneditor-tree button.jsoneditor-invisible{visibility:hidden;background:none}body div.jsoneditor-tree button.jsoneditor-dragarea{background-image:"/";background-position:-72px -72px;cursor:move}body div.jsoneditor-tree *:focus{outline:none}body div.jsoneditor-tree div.jsoneditor-show-more{display:inline-block;padding:3px 4px;margin:2px 0;background-color:var(--t42-color-opacity-10);border-radius:3px;color:var(--t42-content-color-muted);font-family:var(--t42-font-family);font-size:var(--t42-font-size)}body div.jsoneditor-tree div.jsoneditor-show-more a{display:inline-block;color:var(--t42-content-color-muted)}body div.jsoneditor-tree div.jsoneditor-color{display:inline-block;width:12px;height:12px;margin:4px;border:1px solid var(--t42-content-color-muted);cursor:pointer}body div.jsoneditor-tree div.jsoneditor-color.jsoneditor-color-readonly{cursor:inherit}body div.jsoneditor-tree div.jsoneditor-date{background:var(--t42-content-color);color:var(--t42-content-color);font-family:var(--t42-font-family);border-radius:3px;display:inline-block;padding:3px;margin:0 3px}body div.jsoneditor-tree table.jsoneditor-tree{border-collapse:collapse;border-spacing:0;width:100%}body div.jsoneditor-tree .jsoneditor-button{display:block}body div.jsoneditor-tree .jsoneditor-button.jsoneditor-schema-error{width:24px;height:24px;padding:0;margin:0 4px 0 0;background-image:"/";background-position:-168px -48px;background-color:transparent}body div.jsoneditor-outer{position:static;width:100%;height:100%;margin:0;padding:0;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}body div.jsoneditor-outer.has-nav-bar{margin-top:-26px;padding-top:26px}body div.jsoneditor-outer.has-nav-bar.has-main-menu-bar{margin-top:-61px;padding-top:61px}body div.jsoneditor-outer.has-status-bar{margin-bottom:-26px;padding-bottom:26px}body div.jsoneditor-outer.has-main-menu-bar{margin-top:-35px;padding-top:35px}body div.jsoneditor-busy{position:absolute;top:15%;left:0;box-sizing:border-box;width:100%;text-align:center;display:none}body div.jsoneditor-busy span{background-color:var(--t42-color-opacity-10);border:1px solid var(--t42-color-opacity-10);border-radius:3px;padding:5px 15px;box-shadow:var(--t42-shadow)}body div.jsoneditor-field.jsoneditor-empty::after,body div.jsoneditor-value.jsoneditor-empty::after{pointer-events:none;color:var(--t42-content-color-muted);font-size:8pt}body div.jsoneditor-value.jsoneditor-url,body a.jsoneditor-value.jsoneditor-url{color:var(--green);text-decoration:underline}body a.jsoneditor-value.jsoneditor-url{display:inline-block;padding:2px;margin:2px}body a.jsoneditor-value.jsoneditor-url:hover,body a.jsoneditor-value.jsoneditor-url:focus{color:var(--red)}body div.jsoneditor-field[contenteditable="true"]:focus,body div.jsoneditor-field[contenteditable="true"]:hover,body div.jsoneditor-value[contenteditable="true"]:focus,body div.jsoneditor-value[contenteditable="true"]:hover,body div.jsoneditor-field.jsoneditor-highlight,body div.jsoneditor-value.jsoneditor-highlight{background-color:var(--t42-color-opacity-10);border:1px solid var(--t42-color-opacity-10);border-radius:2px}body div.jsoneditor-field.jsoneditor-highlight-active,body div.jsoneditor-field.jsoneditor-highlight-active:focus,body div.jsoneditor-field.jsoneditor-highlight-active:hover,body div.jsoneditor-value.jsoneditor-highlight-active,body div.jsoneditor-value.jsoneditor-highlight-active:focus,body div.jsoneditor-value.jsoneditor-highlight-active:hover{background-color:#fe0;border:1px solid #ffc700;border-radius:2px}body div.jsoneditor-value.jsoneditor-object,body div.jsoneditor-value.jsoneditor-array{min-width:16px}body div.jsoneditor-tree button.jsoneditor-contextmenu-button:hover,body div.jsoneditor-tree button.jsoneditor-contextmenu-button:focus,body div.jsoneditor-tree button.jsoneditor-contextmenu-button.jsoneditor-selected,body tr.jsoneditor-selected.jsoneditor-first button.jsoneditor-contextmenu-button{background-position:-48px -48px}body div.jsoneditor-tree div.jsoneditor-show-more a:hover,body div.jsoneditor-tree div.jsoneditor-show-more a:focus{color:var(--red)}body textarea.jsoneditor-text,body .ace-jsoneditor{min-height:150px}body textarea.jsoneditor-text.ace_editor,body .ace-jsoneditor.ace_editor{font-family:var(--bs-font-monospace)}body textarea.jsoneditor-text{width:100%;height:100%;margin:0;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;outline-width:0;border:none;background-color:var(--t42-content-color);resize:none}body tr.jsoneditor-highlight,body tr.jsoneditor-selected{background-color:var(--t42-content-color-muted)}body tr.jsoneditor-selected button.jsoneditor-dragarea,body tr.jsoneditor-selected button.jsoneditor-contextmenu-button{visibility:hidden}body tr.jsoneditor-selected.jsoneditor-first button.jsoneditor-dragarea,body tr.jsoneditor-selected.jsoneditor-first button.jsoneditor-contextmenu-button{visibility:visible}body div.jsoneditor-tree button.jsoneditor-dragarea:hover,body div.jsoneditor-tree button.jsoneditor-dragarea:focus,body tr.jsoneditor-selected.jsoneditor-first button.jsoneditor-dragarea{background-position:-72px -48px}body div.jsoneditor tr,body div.jsoneditor th,body div.jsoneditor td{padding:0;margin:0}body div.jsoneditor-field,body div.jsoneditor-value,body div.jsoneditor td,body div.jsoneditor th,body div.jsoneditor textarea,body pre.jsoneditor-preview,body .jsoneditor-schema-error,body .jsoneditor-popover{font-family:var(--bs-font-monospace);font-size:var(--t42-font-size);color:var(--t42-content-color)}body .jsoneditor-schema-error{cursor:default;display:inline-block;height:24px;line-height:24px;position:relative;text-align:center;width:24px}body .jsoneditor-popover{background-color:Rgb(var(--t42-bg-light));border-radius:3px;box-shadow:var(--t42-shadow);color:var(--t42-content-color);padding:7px 10px;position:absolute;cursor:auto;width:200px}body .jsoneditor-popover.jsoneditor-above{bottom:32px;left:-98px}body .jsoneditor-popover.jsoneditor-above:before{border-top:7px solid Rgb(var(--t42-bg-light));bottom:-7px}body .jsoneditor-popover.jsoneditor-below{top:32px;left:-98px}body .jsoneditor-popover.jsoneditor-below:before{border-bottom:7px solid Rgb(var(--t42-bg-light));top:-7px}body .jsoneditor-popover.jsoneditor-left{top:-7px;right:32px}body .jsoneditor-popover.jsoneditor-left:before{border-left:7px solid Rgb(var(--t42-bg-light));border-top:7px solid transparent;border-bottom:7px solid transparent;content:"";top:19px;right:-14px;left:inherit;margin-left:inherit;margin-top:-7px;position:absolute}body .jsoneditor-popover.jsoneditor-right{top:-7px;left:32px}body .jsoneditor-popover.jsoneditor-right:before{border-right:7px solid Rgb(var(--t42-bg-light));border-top:7px solid transparent;border-bottom:7px solid transparent;content:"";top:19px;left:-14px;margin-left:inherit;margin-top:-7px;position:absolute}body .jsoneditor-popover:before{border-right:7px solid transparent;border-left:7px solid transparent;content:"";display:block;left:50%;margin-left:-7px;position:absolute}body .jsoneditor-text-errors tr.jump-to-line:hover{text-decoration:underline;cursor:pointer}body .jsoneditor-schema-error:hover .jsoneditor-popover,body .jsoneditor-schema-error:focus .jsoneditor-popover{display:block;animation:fade-in 0.3s linear 1, move-up 0.3s linear 1}@keyframes fade-in{from{opacity:0}to{opacity:1}}body .jsoneditor .jsoneditor-validation-errors-container{max-height:130px;overflow-y:auto}body .jsoneditor .jsoneditor-validation-errors{width:100%;overflow:hidden}body .jsoneditor .jsoneditor-additional-errors{position:absolute;margin:auto;bottom:31px;left:calc(50% - 92px);color:var(--t42-content-color-muted);background-color:Rgb(var(--t42-bg-mid));padding:7px 15px;border-radius:8px}body .jsoneditor .jsoneditor-additional-errors.visible{visibility:visible;opacity:1;transition:opacity 2s linear}body .jsoneditor .jsoneditor-additional-errors.hidden{visibility:hidden;opacity:0;transition:visibility 0s 2s, opacity 2s linear}body .jsoneditor .jsoneditor-text-errors{width:100%;border-collapse:collapse;border-top:1px solid #ffc700}body .jsoneditor .jsoneditor-text-errors td{padding:3px 6px;vertical-align:middle}body .jsoneditor .jsoneditor-text-errors td pre{margin:0;white-space:pre-wrap}body .jsoneditor .jsoneditor-text-errors tr{background-color:var(--t42-color-opacity-10)}body .jsoneditor .jsoneditor-text-errors tr.parse-error{background-color:var(--red)}body .jsoneditor-text-errors .jsoneditor-schema-error{border:none;width:24px;height:24px;padding:0;margin:0 4px 0 0;cursor:pointer}body .jsoneditor-text-errors tr .jsoneditor-schema-error{background-image:"/";background-position:-168px -48px;background-color:transparent}body .jsoneditor-text-errors tr.parse-error .jsoneditor-schema-error{background-image:"/";background-position:-25px 0px;background-color:transparent}body .jsoneditor-anchor{cursor:pointer}body .jsoneditor-anchor .picker_wrapper.popup.popup_bottom{top:28px;left:-10px}body .fadein{-webkit-animation:fadein 0.3s;animation:fadein 0.3s;-moz-animation:fadein 0.3s;-o-animation:fadein 0.3s}@keyframes fadein{0%{opacity:0}100%{opacity:1}}body .jsoneditor-modal input[type="search"].selectr-input{border:1px solid #d3d3d3;width:calc(100% - 4px);margin:2px;padding:4px;box-sizing:border-box}body .jsoneditor-modal button.selectr-input-clear{right:8px}body .jsoneditor-menu{width:100%;height:35px;padding:2px;margin:0;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;color:var(--t42-content-color);background-color:var(--primary);border-bottom:1px solid var(--primary)}body .jsoneditor-menu>button,body .jsoneditor-menu>.jsoneditor-modes>button{width:26px;height:26px;margin:2px;padding:0;border-radius:2px;border:1px solid transparent;background-color:transparent;background-image:"/";color:var(--t42-content-color);opacity:0.8;font-family:var(--t42-font-family);font-size:var(--t42-font-size);float:left}body .jsoneditor-menu>button:hover,body .jsoneditor-menu>.jsoneditor-modes>button:hover{background-color:rgba(255,255,255,0.2);border:1px solid rgba(255,255,255,0.4)}body .jsoneditor-menu>button:focus,body .jsoneditor-menu>button:active,body .jsoneditor-menu>.jsoneditor-modes>button:focus,body .jsoneditor-menu>.jsoneditor-modes>button:active{background-color:rgba(255,255,255,0.3)}body .jsoneditor-menu>button:disabled,body .jsoneditor-menu>.jsoneditor-modes>button:disabled{opacity:0.5;background-color:transparent;border:none}body .jsoneditor-menu>button.jsoneditor-collapse-all{background-position:0 -96px}body .jsoneditor-menu>button.jsoneditor-expand-all{background-position:0 -120px}body .jsoneditor-menu>button.jsoneditor-sort{background-position:-120px -96px}body .jsoneditor-menu>button.jsoneditor-transform{background-position:-144px -96px}body .jsoneditor.jsoneditor-mode-view>.jsoneditor-menu>button.jsoneditor-sort,body .jsoneditor.jsoneditor-mode-form>.jsoneditor-menu>button.jsoneditor-sort,body .jsoneditor.jsoneditor-mode-view>.jsoneditor-menu>button.jsoneditor-transform,body .jsoneditor.jsoneditor-mode-form>.jsoneditor-menu>button.jsoneditor-transform{display:none}body .jsoneditor-menu>button.jsoneditor-undo{background-position:-24px -96px}body .jsoneditor-menu>button.jsoneditor-undo:disabled{background-position:-24px -120px}body .jsoneditor-menu>button.jsoneditor-redo{background-position:-48px -96px}body .jsoneditor-menu>button.jsoneditor-redo:disabled{background-position:-48px -120px}body .jsoneditor-menu>button.jsoneditor-compact{background-position:-72px -96px}body .jsoneditor-menu>button.jsoneditor-format{background-position:-72px -120px}body .jsoneditor-menu>button.jsoneditor-repair{background-position:-96px -96px}body .jsoneditor-menu>.jsoneditor-modes{display:inline-block;float:left}body .jsoneditor-menu>.jsoneditor-modes>button{background-image:none;width:auto;padding-left:6px;padding-right:6px}body .jsoneditor-menu>button.jsoneditor-separator,body .jsoneditor-menu>.jsoneditor-modes>button.jsoneditor-separator{margin-left:10px}body .jsoneditor-menu a{font-family:var(--t42-font-family);font-size:var(--t42-font-size);color:var(--t42-content-color);opacity:0.8;vertical-align:middle}body .jsoneditor-menu a:hover{opacity:1}body .jsoneditor-menu a.jsoneditor-poweredBy{font-size:8pt;position:absolute;right:0;top:0;padding:10px}body .jsoneditor-navigation-bar{width:100%;height:26px;line-height:26px;padding:0;margin:0;border-bottom:1px solid var(--t42-color-opacity-10);-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;color:var(--t42-content-color-muted);background-color:Rgb(var(--t42-bg-mid));overflow:hidden;font-family:var(--t42-font-family);font-size:var(--t42-font-size)}body .jsoneditor-search{font-family:var(--t42-font-family);position:absolute;right:4px;top:4px;border-collapse:collapse;border-spacing:0;display:flex}body .jsoneditor-search input{color:var(--t42-content-color);width:120px;border:none;outline:none;margin:1px;line-height:20px;font-family:var(--t42-font-family)}body .jsoneditor-search button{width:16px;height:24px;padding:0;margin:0;border:none;background:"/";vertical-align:top}body .jsoneditor-search button:hover{background-color:transparent}body .jsoneditor-search button.jsoneditor-refresh{width:18px;background-position:-99px -73px}body .jsoneditor-search button.jsoneditor-next{cursor:pointer;background-position:-124px -73px}body .jsoneditor-search button.jsoneditor-next:hover{background-position:-124px -49px}body .jsoneditor-search button.jsoneditor-previous{cursor:pointer;background-position:-148px -73px;margin-right:2px}body .jsoneditor-search button.jsoneditor-previous:hover{background-position:-148px -49px}body .jsoneditor-results{font-family:var(--t42-font-family);color:var(--t42-content-color);padding-right:5px;line-height:26px}body .jsoneditor-frame{border:1px solid transparent;background-color:var(--t42-content-color);padding:0 2px;margin:0}body .jsoneditor-statusbar{line-height:26px;height:26px;color:var(--t42-content-color-muted);background-color:Rgb(var(--t42-bg-mid));border-top:1px solid var(--t42-color-opacity-10);-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;font-size:var(--t42-font-size)}body .jsoneditor-statusbar>.jsoneditor-curserinfo-val{margin-right:12px}body .jsoneditor-statusbar>.jsoneditor-curserinfo-count{margin-left:4px}body .jsoneditor-statusbar>.jsoneditor-validation-error-icon{float:right;width:24px;height:24px;padding:0;margin-top:1px;background-image:"/";background-position:-168px -48px;cursor:pointer}body .jsoneditor-statusbar>.jsoneditor-validation-error-count{float:right;margin:0 4px 0 0;cursor:pointer}body .jsoneditor-statusbar>.jsoneditor-parse-error-icon{float:right;width:24px;height:24px;padding:0;margin:1px;background-image:"/";background-position:-25px 0px}body .jsoneditor-statusbar .jsoneditor-array-info a{color:inherit}body div.jsoneditor-statusbar>.jsoneditor-curserinfo-label,body div.jsoneditor-statusbar>.jsoneditor-size-info{margin:0 4px}body .jsoneditor-treepath{padding:0 5px;overflow:hidden;white-space:nowrap;outline:none}body .jsoneditor-treepath.show-all{word-wrap:break-word;white-space:normal;position:absolute;background-color:Rgb(var(--t42-bg-mid));z-index:1;box-shadow:var(--t42-shadow)}body .jsoneditor-treepath.show-all span.jsoneditor-treepath-show-all-btn{display:none}body .jsoneditor-treepath div.jsoneditor-contextmenu-root{position:absolute;left:0}body .jsoneditor-treepath .jsoneditor-treepath-show-all-btn{position:absolute;background-color:Rgb(var(--t42-bg-mid));left:0;height:20px;padding:0 3px;cursor:pointer}body .jsoneditor-treepath .jsoneditor-treepath-element{margin:1px;font-family:var(--t42-font-family);font-size:var(--t42-font-size)}body .jsoneditor-treepath .jsoneditor-treepath-seperator{margin:2px;font-size:9pt;font-family:var(--t42-font-family)}body .jsoneditor-treepath span.jsoneditor-treepath-element:hover,body .jsoneditor-treepath span.jsoneditor-treepath-seperator:hover{cursor:pointer;text-decoration:underline}body .selectr-container{position:relative}body .selectr-container li{list-style:none}body .selectr-hidden{position:absolute;overflow:hidden;clip:rect(0px, 0px, 0px, 0px);width:1px;height:1px;margin:-1px;padding:0;border:0 none}body .selectr-visible{position:absolute;left:0;top:0;width:100%;height:100%;opacity:0;z-index:11}body .selectr-desktop.multiple .selectr-visible{display:none}body .selectr-desktop.multiple.native-open .selectr-visible{top:100%;min-height:200px !important;height:auto;opacity:1;display:block}body .selectr-container.multiple.selectr-mobile .selectr-selected{z-index:0}body .selectr-selected{position:relative;z-index:1;box-sizing:border-box;width:100%;padding:7px 28px 7px 14px;cursor:pointer;border:1px solid Rgb(var(--t42-bg-mid));border-radius:3px;background-color:var(--t42-content-color)}body .selectr-selected::before{position:absolute;top:50%;right:10px;width:0;height:0;content:'';-o-transform:rotate(0deg) translate3d(0px, -50%, 0px);-ms-transform:rotate(0deg) translate3d(0px, -50%, 0px);-moz-transform:rotate(0deg) translate3d(0px, -50%, 0px);-webkit-transform:rotate(0deg) translate3d(0px, -50%, 0px);transform:rotate(0deg) translate3d(0px, -50%, 0px);border-width:4px 4px 0 4px;border-style:solid;border-color:#6c7a86 transparent transparent}body .selectr-container.open .selectr-selected::before,body .selectr-container.native-open .selectr-selected::before{border-width:0 4px 4px 4px;border-style:solid;border-color:transparent transparent #6c7a86}body .selectr-label{display:none;overflow:hidden;width:100%;white-space:nowrap;text-overflow:ellipsis}body .selectr-placeholder{color:#6c7a86}body .selectr-tags{margin:0;padding:0;white-space:normal}body .has-selected .selectr-tags{margin:0 0 -2px}body .selectr-tag{list-style:none;position:relative;float:left;padding:2px 25px 2px 8px;margin:0 2px 2px 0;cursor:default;color:var(--t42-content-color);border:medium none;border-radius:10px;background:#acb7bf none repeat scroll 0 0}body .selectr-container.multiple.has-selected .selectr-selected{padding:5px 28px 5px 5px}body .selectr-options-container{position:absolute;z-index:10000;top:calc(100% - 1px);left:0;display:none;box-sizing:border-box;width:100%;border-width:0 1px 1px;border-style:solid;border-color:transparent Rgb(var(--t42-bg-mid)) Rgb(var(--t42-bg-mid));border-radius:0 0 3px 3px;background-color:var(--t42-content-color)}body .selectr-container.open .selectr-options-container{display:block}body .selectr-input-container{position:relative;display:none}body .selectr-clear,body .selectr-input-clear,body .selectr-tag-remove{position:absolute;top:50%;right:22px;width:20px;height:20px;padding:0;cursor:pointer;-o-transform:translate3d(0px, -50%, 0px);-ms-transform:translate3d(0px, -50%, 0px);-moz-transform:translate3d(0px, -50%, 0px);-webkit-transform:translate3d(0px, -50%, 0px);transform:translate3d(0px, -50%, 0px);border:medium none;background-color:transparent;z-index:11}body .selectr-clear,body .selectr-input-clear{display:none}body .selectr-container.has-selected .selectr-clear,body .selectr-input-container.active .selectr-input-clear{display:block}body .selectr-selected .selectr-tag-remove{right:2px}body .selectr-clear::before,body .selectr-clear::after,body .selectr-input-clear::before,body .selectr-input-clear::after,body .selectr-tag-remove::before,body .selectr-tag-remove::after{position:absolute;top:5px;left:9px;width:2px;height:10px;content:' ';background-color:#6c7a86}body .selectr-tag-remove::before,body .selectr-tag-remove::after{top:4px;width:3px;height:12px;background-color:var(--t42-content-color)}body .selectr-clear:before,body .selectr-input-clear::before,body .selectr-tag-remove::before{-o-transform:rotate(45deg);-ms-transform:rotate(45deg);-moz-transform:rotate(45deg);-webkit-transform:rotate(45deg);transform:rotate(45deg)}body .selectr-clear:after,body .selectr-input-clear::after,body .selectr-tag-remove::after{-o-transform:rotate(-45deg);-ms-transform:rotate(-45deg);-moz-transform:rotate(-45deg);-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}body .selectr-input-container.active,body .selectr-input-container.active .selectr-clear{display:block}body .selectr-input{top:5px;left:5px;box-sizing:border-box;width:calc(100% - 30px);margin:10px 15px;padding:7px 30px 7px 9px;border:1px solid Rgb(var(--t42-bg-mid));border-radius:3px}body .selectr-notice{display:none;box-sizing:border-box;width:100%;padding:8px 16px;border-top:1px solid Rgb(var(--t42-bg-mid));border-radius:0 0 3px 3px;background-color:var(--t42-content-color)}body .selectr-container.notice .selectr-notice{display:block}body .selectr-container.notice .selectr-selected{border-radius:3px 3px 0 0}body .selectr-options{position:relative;top:calc(100% + 2px);display:none;overflow-x:auto;overflow-y:scroll;max-height:200px;margin:0;padding:0}body .selectr-container.open .selectr-options,body .selectr-container.open .selectr-input-container,body .selectr-container.notice .selectr-options-container{display:block}body .selectr-option{position:relative;display:block;padding:5px 20px;list-style:outside none none;cursor:pointer;font-weight:normal}body .selectr-options.optgroups>.selectr-option{padding-left:25px}body .selectr-optgroup{font-weight:bold;padding:0}body .selectr-optgroup--label{font-weight:bold;margin-top:10px;padding:5px 15px}body .selectr-match{text-decoration:underline}body .selectr-option.selected{background-color:#ddd}body .selectr-option.active{color:var(--t42-content-color);background-color:#5897fb}body .selectr-option.disabled{opacity:0.4}body .selectr-option.excluded{display:none}body .selectr-container.open .selectr-selected{border-color:Rgb(var(--t42-bg-mid)) Rgb(var(--t42-bg-mid)) transparent Rgb(var(--t42-bg-mid));border-radius:3px 3px 0 0}body .selectr-container.open .selectr-selected::after{-o-transform:rotate(180deg) translate3d(0px, 50%, 0px);-ms-transform:rotate(180deg) translate3d(0px, 50%, 0px);-moz-transform:rotate(180deg) translate3d(0px, 50%, 0px);-webkit-transform:rotate(180deg) translate3d(0px, 50%, 0px);transform:rotate(180deg) translate3d(0px, 50%, 0px)}body .selectr-disabled{opacity:.6}body .selectr-empty,body .has-selected .selectr-placeholder{display:none}body .has-selected .selectr-label{display:block}body .taggable .selectr-selected{padding:4px 28px 4px 4px}body .taggable .selectr-selected::after{display:table;content:" ";clear:both}body .taggable .selectr-label{width:auto}body .taggable .selectr-tags{float:left;display:block}body .taggable .selectr-placeholder{display:none}body .input-tag{float:left;min-width:90px;width:auto}body .selectr-tag-input{border:medium none;padding:3px 10px;width:100%;font-family:inherit;font-weight:inherit;font-size:inherit}body .selectr-input-container.loading::after{position:absolute;top:50%;right:20px;width:20px;height:20px;content:'';-o-transform:translate3d(0px, -50%, 0px);-ms-transform:translate3d(0px, -50%, 0px);-moz-transform:translate3d(0px, -50%, 0px);-webkit-transform:translate3d(0px, -50%, 0px);transform:translate3d(0px, -50%, 0px);-o-transform-origin:50% 0 0;-ms-transform-origin:50% 0 0;-moz-transform-origin:50% 0 0;-webkit-transform-origin:50% 0 0;transform-origin:50% 0 0;-moz-animation:500ms linear 0s normal forwards infinite running selectr-spin;-webkit-animation:500ms linear 0s normal forwards infinite running selectr-spin;animation:500ms linear 0s normal forwards infinite running selectr-spin;border-width:3px;border-style:solid;border-color:#aaa #ddd #ddd;border-radius:50%}@-webkit-keyframes selectr-spin{0%{-webkit-transform:rotate(0deg) translate3d(0px, -50%, 0px);transform:rotate(0deg) translate3d(0px, -50%, 0px)}100%{-webkit-transform:rotate(360deg) translate3d(0px, -50%, 0px);transform:rotate(360deg) translate3d(0px, -50%, 0px)}}@keyframes selectr-spin{0%{-webkit-transform:rotate(0deg) translate3d(0px, -50%, 0px);transform:rotate(0deg) translate3d(0px, -50%, 0px)}100%{-webkit-transform:rotate(360deg) translate3d(0px, -50%, 0px);transform:rotate(360deg) translate3d(0px, -50%, 0px)}}body .selectr-container.open.inverted .selectr-selected{border-color:transparent Rgb(var(--t42-bg-mid)) Rgb(var(--t42-bg-mid));border-radius:0 0 3px 3px}body .selectr-container.inverted .selectr-options-container{border-width:1px 1px 0;border-color:Rgb(var(--t42-bg-mid)) Rgb(var(--t42-bg-mid)) transparent;border-radius:3px 3px 0 0;background-color:var(--t42-content-color)}body .selectr-container.inverted .selectr-options-container{top:auto;bottom:calc(100% - 1px)}body .selectr-container ::-webkit-input-placeholder{color:#6c7a86;opacity:1}body .selectr-container ::-moz-placeholder{color:#6c7a86;opacity:1}body .selectr-container :-ms-input-placeholder{color:#6c7a86;opacity:1}body .selectr-container ::placeholder{color:#6c7a86;opacity:1}body #jsoneditor{height:100%}body .jsoneditor{border-color:var(--t42-color-opacity-10)}body .jsoneditor textarea{line-height:1.5;background-color:Rgb(var(--t42-bg-dark));min-height:100%}body .jsoneditor input{outline:0}body .jsoneditor input:focus{outline:0}body .jsoneditor-button:focus{outline:none}body .jsoneditor-menu{border-bottom-color:var(--t42-color-opacity-10);background-color:Rgb(var(--t42-bg-light))}body .jsoneditor-menu button{background-image:var(--t42-json-icons);background-color:transparent}body .jsoneditor-menu button:hover,body .jsoneditor-menu button:focus{color:var(--t42-link-hover-color)}body .jsoneditor-menu>button,body .jsoneditor-menu>.jsoneditor-modes>button{border-radius:0;font-size:.75rem;backdrop-filter:var(--backdrop-filter);transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, color}body .jsoneditor-menu>button:hover:not(.disabled):not(:disabled),body .jsoneditor-menu>button:active,body .jsoneditor-menu>.jsoneditor-modes>button:hover:not(.disabled):not(:disabled),body .jsoneditor-menu>.jsoneditor-modes>button:active{border-color:transparent;color:var(--t42-link-hover-color);background-color:var(--t42-color-opacity-10)}body .jsoneditor-menu li button.jsoneditor-selected{background-color:var(--t42-color-opacity-10)}body .jsoneditor-menu .jsoneditor-poweredBy{display:none}body .jsoneditor-frame{padding:0 .875rem;border-color:var(--t42-color-opacity-10);background-color:transparent;display:flex;transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border-color}body .jsoneditor-frame:focus-within{border-color:var(--primary);background-color:var(--t42-input-bg);outline:0}body .jsoneditor-frame table td{vertical-align:middle}body .jsoneditor-search input[type="text"]{border:0}body .jsoneditor-search input[type="text"]:focus{border:0}body .jsoneditor-search input{background-color:transparent}body .jsoneditor-contextmenu{z-index:2}body .jsoneditor-contextmenu .jsoneditor-menu{border-color:var(--t42-color-opacity-10);background:linear-gradient(to bottom right, rgba(var(--t42-bg-light), 0.75) 0%, rgba(var(--t42-bg-dark), 0.75) 100%);box-shadow:var(--t42-shadow);backdrop-filter:var(--backdrop-filter)}body .jsoneditor-contextmenu .jsoneditor-menu button button .jsoneditor-expand,body .jsoneditor-contextmenu .jsoneditor-menu li button .jsoneditor-expand{background-image:var(--t42-json-icons);z-index:1}body .jsoneditor-contextmenu .jsoneditor-menu button button.jsoneditor-selected,body .jsoneditor-contextmenu .jsoneditor-menu li button.jsoneditor-selected{background-color:var(--t42-color-opacity-10);transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, color}body .jsoneditor-contextmenu .jsoneditor-menu button button.jsoneditor-selected:hover,body .jsoneditor-contextmenu .jsoneditor-menu button button.jsoneditor-selected:focus,body .jsoneditor-contextmenu .jsoneditor-menu li button.jsoneditor-selected:hover,body .jsoneditor-contextmenu .jsoneditor-menu li button.jsoneditor-selected:focus{color:var(--t42-link-hover-color);background-color:var(--t42-color-opacity-10)}body .jsoneditor-contextmenu .jsoneditor-menu button{display:flex;justify-content:start}body .jsoneditor-contextmenu .jsoneditor-menu button.jsoneditor-default{float:left;z-index:1}body .jsoneditor-contextmenu .jsoneditor-menu li ul{padding:0 !important;left:0}body .jsoneditor-contextmenu .jsoneditor-menu li ul li button{padding-left:1rem}body .jsoneditor-contextmenu .jsoneditor-menu li ul .jsoneditor-icon{position:relative;margin-left:0}body .jsoneditor-contextmenu .jsoneditor-menu .jsoneditor-text{padding:0;line-height:1.5rem}body .jsoneditor-contextmenu .jsoneditor-icon{position:relative;background-image:var(--t42-json-icons)}body .jsoneditor-contextmenu .jsoneditor-separator{margin-top:0;padding-top:0}body .jsoneditor-mode-preview pre.jsoneditor-preview{border:0;line-height:1.5}body .jsoneditor-modal{border-top:0;background:linear-gradient(to bottom right, rgba(var(--t42-bg-light), 0.75) 0%, rgba(var(--t42-bg-dark), 0.75) 100%) !important;box-shadow:var(--t42-shadow) !important;backdrop-filter:var(--backdrop-filter)}body .jsoneditor-modal::before{position:absolute;top:0;right:0;left:0;display:block;width:100%;height:0.0625rem;background:linear-gradient(90deg, #007be5 0%, rgba(0,123,229,0.5) 100%);content:""}body .jsoneditor-modal .pico-modal-header{padding:0.5rem 0.988rem;background:transparent;font-size:0.75rem}body .jsoneditor-modal .pico-close{top:1rem !important;right:1rem !important;color:var(--t42-content-color-muted);transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:color}body .jsoneditor-modal .pico-close:not(.disabled):not(:disabled).active,body .jsoneditor-modal .pico-close:not(.disabled):not(:disabled):focus,body .jsoneditor-modal .pico-close:not(.disabled):not(:disabled):hover{color:var(--t42-link-color)}body .jsoneditor-modal table td{font-size:0.75rem;padding:0 0.25rem}body .jsoneditor-modal table td.jsoneditor-modal-input{padding-top:0.25rem;padding-bottom:0.25rem;text-align:left}body .jsoneditor-modal table td.jsoneditor-modal-input.jsoneditor-modal-actions{text-align:right}body .jsoneditor-modal table th{font-size:0.75rem}body .jsoneditor-modal label,body .jsoneditor-modal p{font-size:0.75rem}body .jsoneditor-modal select{min-width:12.375rem}body .jsoneditor-modal .selectr-selected{padding:0 0.857rem}body .jsoneditor-modal select,body .jsoneditor-modal textarea,body .jsoneditor-modal input,body .jsoneditor-modal input[type="text"],body .jsoneditor-modal input[type="search"],body .jsoneditor-modal #query{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border;border-color:var(--t42-color-opacity-10);border-radius:0;font-size:0.75rem;background-color:var(--t42-input-bg)}body .jsoneditor-modal select:focus,body .jsoneditor-modal textarea:focus,body .jsoneditor-modal input:focus,body .jsoneditor-modal input[type="text"]:focus,body .jsoneditor-modal input[type="search"]:focus,body .jsoneditor-modal #query:focus{border-color:var(--primary);box-shadow:none;outline:0;padding:0 0 0 .875rem;border-radius:0}body .jsoneditor-modal select:disabled,body .jsoneditor-modal select.disabled,body .jsoneditor-modal select[readonly],body .jsoneditor-modal textarea:disabled,body .jsoneditor-modal textarea.disabled,body .jsoneditor-modal textarea[readonly],body .jsoneditor-modal input:disabled,body .jsoneditor-modal input.disabled,body .jsoneditor-modal input[readonly],body .jsoneditor-modal input[type="text"]:disabled,body .jsoneditor-modal input[type="text"].disabled,body .jsoneditor-modal input[type="text"][readonly],body .jsoneditor-modal input[type="search"]:disabled,body .jsoneditor-modal input[type="search"].disabled,body .jsoneditor-modal input[type="search"][readonly],body .jsoneditor-modal #query:disabled,body .jsoneditor-modal #query.disabled,body .jsoneditor-modal #query[readonly]{cursor:default;opacity:0.65}body .jsoneditor-modal input[type="search"].selectr-input{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border-color;border:var(--t42-border);background-color:var(--t42-input-bg);margin:0;line-height:1.5rem;width:100%;padding:0 0.5rem}body .jsoneditor-modal input[type="search"].selectr-input:hover{border-color:var(--primary)}body .jsoneditor-modal .jsoneditor-select-wrapper::after{border-top:var(--t42-color-opacity-10)}body .jsoneditor-modal input[type="button"],body .jsoneditor-modal input[type="submit"]{padding:0 .875rem;border-radius:0;color:var(--t42-link-color);line-height:1.875rem;background:transparent;transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, border-color}body .jsoneditor-modal input[type="button"]:not(.disabled):not(:disabled).active,body .jsoneditor-modal input[type="button"]:not(.disabled):not(:disabled):hover,body .jsoneditor-modal input[type="submit"]:not(.disabled):not(:disabled).active,body .jsoneditor-modal input[type="submit"]:not(.disabled):not(:disabled):hover{border-color:var(--t42-color-opacity-30);color:var(--white);background:var(--primary)}body .jsoneditor-modal .jsoneditor-button-group input.jsoneditor-button-first{border-left-style:solid;border-top-left-radius:0;border-bottom-left-radius:0}body .jsoneditor-modal .jsoneditor-button-group input.jsoneditor-button-last{border-top-right-radius:0;border-bottom-right-radius:0}body .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-asc input.jsoneditor-button-asc,body .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-desc input.jsoneditor-button-desc{color:var(--white);background:var(--primary)}body .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-asc input.jsoneditor-button-asc:hover,body .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-asc input.jsoneditor-button-asc:focus,body .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-asc input.jsoneditor-button-asc:active,body .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-desc input.jsoneditor-button-desc:hover,body .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-desc input.jsoneditor-button-desc:focus,body .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-desc input.jsoneditor-button-desc:active{border-color:var(--t42-color-opacity-30);color:var(--white)}body .jsoneditor-modal .jsoneditor-jmespath-label{color:var(--t42-content-color);font-weight:400}body .jsoneditor-modal .jsoneditor-jmespath-filter-value input{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border-color;line-height:1.875rem;padding:0 0 0 .875rem;font-size:0.75rem;background-color:var(--t42-input-bg)}body .jsoneditor-modal .jsoneditor-jmespath-filter-value input:focus,body .jsoneditor-modal .jsoneditor-jmespath-filter-value input:hover{background-color:var(--t42-input-bg);border-color:var(--primary)}body .jsoneditor-jmespath-block .jsoneditor-modal-actions{text-align:right}body div.jsoneditor td.jsoneditor-tree{vertical-align:middle}body div.jsoneditor td.jsoneditor-separator{vertical-align:middle}body div.jsoneditor-tree{background:transparent}body div.jsoneditor-tree button.jsoneditor-button{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, outline-color;background-image:var(--t42-json-icons)}body div.jsoneditor-tree button.jsoneditor-button:focus{background-color:transparent;outline-color:var(--t42-color-opacity-10)}body tr.jsoneditor-selected,body tr.jsoneditor-highlight{background-color:var(--t42-color-opacity-10)}body .selectr-selected{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border-color;height:2rem;font-size:0.75rem;font-weight:400;line-height:1.875rem;background-color:var(--t42-input-bg);border-radius:0}body .selectr-selected::before{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:transform;right:0.5rem;border:0;width:0.75rem;height:0.75rem;background:var(--t42-select-indicator) center center/1rem 1rem no-repeat;transform:translateY(-50%)}body .selectr-placeholder{color:var(--t42-content-color-muted)}body .selectr-container.open .selectr-selected{border-radius:0;border-color:var(--primary)}body .selectr-container.open .selectr-selected::before{border:0;transform:rotate(180deg) translateY(50%)}body .selectr-container.open .selectr-options-container{border-left-color:var(--primary);border-right-color:var(--primary);border-bottom-color:var(--primary)}body .selectr-options{overflow-y:auto}body .selectr-options-container{min-height:2rem;border-color:var(--t42-color-opacity-10);border-style:solid;border-width:1px;background-color:Rgb(var(--t42-bg-dark))}body .selectr-options .active{color:var(--t42-link-hover-color);background-color:var(--t42-color-opacity-10)}body .selectr-options .selected{color:var(--t42-link-hover-color);background-color:var(--primary)}body .selectr-option{padding:0 0 0 0.875rem;line-height:2rem;font-size:0.75rem}body .selectr-input{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border-color;border:var(--t42-border);background-color:var(--t42-input-bg)}body .selectr-input:hover{border-color:var(--primary)}body .selectr-input-container{padding:0.25rem}body .selectr-clear::before,body .selectr-clear::after{background-color:var(--t42-content-color)}body .jsoneditor .ace-jsoneditor .ace_text-input{min-height:auto}body .jsoneditor .ace-jsoneditor.ace_editor,body .jsoneditor .ace-jsoneditor .ace_scroller{background-color:Rgb(var(--t42-bg-dark))}body .jsoneditor .ace-jsoneditor .ace_gutter{color:var(--t42-content-color-muted);background-color:Rgb(var(--t42-bg-mid))}body .jsoneditor .ace-jsoneditor .ace_gutter-active-line{background-color:Rgb(var(--t42-bg-light))}body .jsoneditor .ace-jsoneditor .ace_cursor{border-color:Rgb(var(--t42-content-color))}body .jsoneditor .ace-jsoneditor .ace_marker-layer .ace_active-line{background-color:rgba(var(--secondary), 0.25)}body .jsoneditor .ace-jsoneditor .ace_marker-layer .ace_selection{background-color:var(--t42-color-opacity-10)}body .jsoneditor .ace-jsoneditor .ace_marker-layer .ace_selected-word{border-color:var(--t42-color-opacity-10);background-color:var(--t42-color-opacity-10)}body .jsoneditor .ace-jsoneditor .ace_marker-layer .ace_bracket{border:var(--t42-border)}body .jsoneditor .ace-jsoneditor .ace_variable{color:var(--t42-content-color)}body .jsoneditor .ace-jsoneditor .ace_constant.ace_numeric{color:#ff511f}body .jsoneditor .ace-jsoneditor .ace_constant.ace_language{color:#f9a825}body .jsoneditor .ace-jsoneditor .ace_string{color:#43a047}body .jsoneditor .ace-jsoneditor .ace_fold{border-color:var(--t42-color-opacity-10);background-color:Rgb(var(--t42-bg-light));transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-image}body .jsoneditor .ace-jsoneditor .ace_fold-widget:hover,body .jsoneditor .ace-jsoneditor .ace_fold-widget:active{border-color:var(--t42-color-opacity-30);background-color:var(--t42-color-opacity-10);box-shadow:none}body .pico-modal-contents{display:block} + diff --git a/typescript/start/clients/src/lib/workspaces.umd.js b/typescript/start/clients/src/lib/workspaces.umd.js new file mode 100644 index 0000000..53ca1d8 --- /dev/null +++ b/typescript/start/clients/src/lib/workspaces.umd.js @@ -0,0 +1,5302 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define(factory) : + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.workspaces = factory()); +})(this, (function () { 'use strict'; + + function getDefaultExportFromCjs (x) { + return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; + } + + function createRegistry(options) { + if (options && options.errorHandling + && typeof options.errorHandling !== "function" + && options.errorHandling !== "log" + && options.errorHandling !== "silent" + && options.errorHandling !== "throw") { + throw new Error("Invalid options passed to createRegistry. Prop errorHandling should be [\"log\" | \"silent\" | \"throw\" | (err) => void], but " + typeof options.errorHandling + " was passed"); + } + var _userErrorHandler = options && typeof options.errorHandling === "function" && options.errorHandling; + var callbacks = {}; + function add(key, callback, replayArgumentsArr) { + var callbacksForKey = callbacks[key]; + if (!callbacksForKey) { + callbacksForKey = []; + callbacks[key] = callbacksForKey; + } + callbacksForKey.push(callback); + if (replayArgumentsArr) { + setTimeout(function () { + replayArgumentsArr.forEach(function (replayArgument) { + var _a; + if ((_a = callbacks[key]) === null || _a === void 0 ? void 0 : _a.includes(callback)) { + try { + if (Array.isArray(replayArgument)) { + callback.apply(undefined, replayArgument); + } + else { + callback.apply(undefined, [replayArgument]); + } + } + catch (err) { + _handleError(err, key); + } + } + }); + }, 0); + } + return function () { + var allForKey = callbacks[key]; + if (!allForKey) { + return; + } + allForKey = allForKey.reduce(function (acc, element, index) { + if (!(element === callback && acc.length === index)) { + acc.push(element); + } + return acc; + }, []); + if (allForKey.length === 0) { + delete callbacks[key]; + } + else { + callbacks[key] = allForKey; + } + }; + } + function execute(key) { + var argumentsArr = []; + for (var _i = 1; _i < arguments.length; _i++) { + argumentsArr[_i - 1] = arguments[_i]; + } + var callbacksForKey = callbacks[key]; + if (!callbacksForKey || callbacksForKey.length === 0) { + return []; + } + var results = []; + callbacksForKey.forEach(function (callback) { + try { + var result = callback.apply(undefined, argumentsArr); + results.push(result); + } + catch (err) { + results.push(undefined); + _handleError(err, key); + } + }); + return results; + } + function _handleError(exceptionArtifact, key) { + var errParam = exceptionArtifact instanceof Error ? exceptionArtifact : new Error(exceptionArtifact); + if (_userErrorHandler) { + _userErrorHandler(errParam); + return; + } + var msg = "[ERROR] callback-registry: User callback for key \"" + key + "\" failed: " + errParam.stack; + if (options) { + switch (options.errorHandling) { + case "log": + return console.error(msg); + case "silent": + return; + case "throw": + throw new Error(msg); + } + } + console.error(msg); + } + function clear() { + callbacks = {}; + } + function clearKey(key) { + var callbacksForKey = callbacks[key]; + if (!callbacksForKey) { + return; + } + delete callbacks[key]; + } + return { + add: add, + execute: execute, + clear: clear, + clearKey: clearKey + }; + } + createRegistry.default = createRegistry; + var lib = createRegistry; + + + var CallbackFactory = /*@__PURE__*/getDefaultExportFromCjs(lib); + + /** + * Wraps values in an `Ok` type. + * + * Example: `ok(5) // => {ok: true, result: 5}` + */ + var ok = function (result) { return ({ ok: true, result: result }); }; + /** + * Wraps errors in an `Err` type. + * + * Example: `err('on fire') // => {ok: false, error: 'on fire'}` + */ + var err = function (error) { return ({ ok: false, error: error }); }; + /** + * Create a `Promise` that either resolves with the result of `Ok` or rejects + * with the error of `Err`. + */ + var asPromise = function (r) { + return r.ok === true ? Promise.resolve(r.result) : Promise.reject(r.error); + }; + /** + * Unwraps a `Result` and returns either the result of an `Ok`, or + * `defaultValue`. + * + * Example: + * ``` + * Result.withDefault(5, number().run(json)) + * ``` + * + * It would be nice if `Decoder` had an instance method that mirrored this + * function. Such a method would look something like this: + * ``` + * class Decoder { + * runWithDefault = (defaultValue: A, json: any): A => + * Result.withDefault(defaultValue, this.run(json)); + * } + * + * number().runWithDefault(5, json) + * ``` + * Unfortunately, the type of `defaultValue: A` on the method causes issues + * with type inference on the `object` decoder in some situations. While these + * inference issues can be solved by providing the optional type argument for + * `object`s, the extra trouble and confusion doesn't seem worth it. + */ + var withDefault = function (defaultValue, r) { + return r.ok === true ? r.result : defaultValue; + }; + /** + * Return the successful result, or throw an error. + */ + var withException = function (r) { + if (r.ok === true) { + return r.result; + } + else { + throw r.error; + } + }; + /** + * Apply `f` to the result of an `Ok`, or pass the error through. + */ + var map = function (f, r) { + return r.ok === true ? ok(f(r.result)) : r; + }; + /** + * Apply `f` to the result of two `Ok`s, or pass an error through. If both + * `Result`s are errors then the first one is returned. + */ + var map2 = function (f, ar, br) { + return ar.ok === false ? ar : + br.ok === false ? br : + ok(f(ar.result, br.result)); + }; + /** + * Apply `f` to the error of an `Err`, or pass the success through. + */ + var mapError = function (f, r) { + return r.ok === true ? r : err(f(r.error)); + }; + /** + * Chain together a sequence of computations that may fail, similar to a + * `Promise`. If the first computation fails then the error will propagate + * through. If it succeeds, then `f` will be applied to the value, returning a + * new `Result`. + */ + var andThen = function (f, r) { + return r.ok === true ? f(r.result) : r; + }; + + /*! ***************************************************************************** + Copyright (c) Microsoft Corporation. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THIS SOFTWARE. + ***************************************************************************** */ + /* global Reflect, Promise */ + + + + var __assign = function() { + __assign = Object.assign || function __assign(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; + } + return t; + }; + return __assign.apply(this, arguments); + }; + + function __rest(s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { + if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) + t[p[i]] = s[p[i]]; + } + return t; + } + + function isEqual(a, b) { + if (a === b) { + return true; + } + if (a === null && b === null) { + return true; + } + if (typeof (a) !== typeof (b)) { + return false; + } + if (typeof (a) === 'object') { + // Array + if (Array.isArray(a)) { + if (!Array.isArray(b)) { + return false; + } + if (a.length !== b.length) { + return false; + } + for (var i = 0; i < a.length; i++) { + if (!isEqual(a[i], b[i])) { + return false; + } + } + return true; + } + // Hash table + var keys = Object.keys(a); + if (keys.length !== Object.keys(b).length) { + return false; + } + for (var i = 0; i < keys.length; i++) { + if (!b.hasOwnProperty(keys[i])) { + return false; + } + if (!isEqual(a[keys[i]], b[keys[i]])) { + return false; + } + } + return true; + } + } + /* + * Helpers + */ + var isJsonArray = function (json) { return Array.isArray(json); }; + var isJsonObject = function (json) { + return typeof json === 'object' && json !== null && !isJsonArray(json); + }; + var typeString = function (json) { + switch (typeof json) { + case 'string': + return 'a string'; + case 'number': + return 'a number'; + case 'boolean': + return 'a boolean'; + case 'undefined': + return 'undefined'; + case 'object': + if (json instanceof Array) { + return 'an array'; + } + else if (json === null) { + return 'null'; + } + else { + return 'an object'; + } + default: + return JSON.stringify(json); + } + }; + var expectedGot = function (expected, got) { + return "expected " + expected + ", got " + typeString(got); + }; + var printPath = function (paths) { + return paths.map(function (path) { return (typeof path === 'string' ? "." + path : "[" + path + "]"); }).join(''); + }; + var prependAt = function (newAt, _a) { + var at = _a.at, rest = __rest(_a, ["at"]); + return (__assign({ at: newAt + (at || '') }, rest)); + }; + /** + * Decoders transform json objects with unknown structure into known and + * verified forms. You can create objects of type `Decoder` with either the + * primitive decoder functions, such as `boolean()` and `string()`, or by + * applying higher-order decoders to the primitives, such as `array(boolean())` + * or `dict(string())`. + * + * Each of the decoder functions are available both as a static method on + * `Decoder` and as a function alias -- for example the string decoder is + * defined at `Decoder.string()`, but is also aliased to `string()`. Using the + * function aliases exported with the library is recommended. + * + * `Decoder` exposes a number of 'run' methods, which all decode json in the + * same way, but communicate success and failure in different ways. The `map` + * and `andThen` methods modify decoders without having to call a 'run' method. + * + * Alternatively, the main decoder `run()` method returns an object of type + * `Result`. This library provides a number of helper + * functions for dealing with the `Result` type, so you can do all the same + * things with a `Result` as with the decoder methods. + */ + var Decoder = /** @class */ (function () { + /** + * The Decoder class constructor is kept private to separate the internal + * `decode` function from the external `run` function. The distinction + * between the two functions is that `decode` returns a + * `Partial` on failure, which contains an unfinished error + * report. When `run` is called on a decoder, the relevant series of `decode` + * calls is made, and then on failure the resulting `Partial` + * is turned into a `DecoderError` by filling in the missing information. + * + * While hiding the constructor may seem restrictive, leveraging the + * provided decoder combinators and helper functions such as + * `andThen` and `map` should be enough to build specialized decoders as + * needed. + */ + function Decoder(decode) { + var _this = this; + this.decode = decode; + /** + * Run the decoder and return a `Result` with either the decoded value or a + * `DecoderError` containing the json input, the location of the error, and + * the error message. + * + * Examples: + * ``` + * number().run(12) + * // => {ok: true, result: 12} + * + * string().run(9001) + * // => + * // { + * // ok: false, + * // error: { + * // kind: 'DecoderError', + * // input: 9001, + * // at: 'input', + * // message: 'expected a string, got 9001' + * // } + * // } + * ``` + */ + this.run = function (json) { + return mapError(function (error) { return ({ + kind: 'DecoderError', + input: json, + at: 'input' + (error.at || ''), + message: error.message || '' + }); }, _this.decode(json)); + }; + /** + * Run the decoder as a `Promise`. + */ + this.runPromise = function (json) { return asPromise(_this.run(json)); }; + /** + * Run the decoder and return the value on success, or throw an exception + * with a formatted error string. + */ + this.runWithException = function (json) { return withException(_this.run(json)); }; + /** + * Construct a new decoder that applies a transformation to the decoded + * result. If the decoder succeeds then `f` will be applied to the value. If + * it fails the error will propagated through. + * + * Example: + * ``` + * number().map(x => x * 5).run(10) + * // => {ok: true, result: 50} + * ``` + */ + this.map = function (f) { + return new Decoder(function (json) { return map(f, _this.decode(json)); }); + }; + /** + * Chain together a sequence of decoders. The first decoder will run, and + * then the function will determine what decoder to run second. If the result + * of the first decoder succeeds then `f` will be applied to the decoded + * value. If it fails the error will propagate through. + * + * This is a very powerful method -- it can act as both the `map` and `where` + * methods, can improve error messages for edge cases, and can be used to + * make a decoder for custom types. + * + * Example of adding an error message: + * ``` + * const versionDecoder = valueAt(['version'], number()); + * const infoDecoder3 = object({a: boolean()}); + * + * const decoder = versionDecoder.andThen(version => { + * switch (version) { + * case 3: + * return infoDecoder3; + * default: + * return fail(`Unable to decode info, version ${version} is not supported.`); + * } + * }); + * + * decoder.run({version: 3, a: true}) + * // => {ok: true, result: {a: true}} + * + * decoder.run({version: 5, x: 'abc'}) + * // => + * // { + * // ok: false, + * // error: {... message: 'Unable to decode info, version 5 is not supported.'} + * // } + * ``` + * + * Example of decoding a custom type: + * ``` + * // nominal type for arrays with a length of at least one + * type NonEmptyArray = T[] & { __nonEmptyArrayBrand__: void }; + * + * const nonEmptyArrayDecoder = (values: Decoder): Decoder> => + * array(values).andThen(arr => + * arr.length > 0 + * ? succeed(createNonEmptyArray(arr)) + * : fail(`expected a non-empty array, got an empty array`) + * ); + * ``` + */ + this.andThen = function (f) { + return new Decoder(function (json) { + return andThen(function (value) { return f(value).decode(json); }, _this.decode(json)); + }); + }; + /** + * Add constraints to a decoder _without_ changing the resulting type. The + * `test` argument is a predicate function which returns true for valid + * inputs. When `test` fails on an input, the decoder fails with the given + * `errorMessage`. + * + * ``` + * const chars = (length: number): Decoder => + * string().where( + * (s: string) => s.length === length, + * `expected a string of length ${length}` + * ); + * + * chars(5).run('12345') + * // => {ok: true, result: '12345'} + * + * chars(2).run('HELLO') + * // => {ok: false, error: {... message: 'expected a string of length 2'}} + * + * chars(12).run(true) + * // => {ok: false, error: {... message: 'expected a string, got a boolean'}} + * ``` + */ + this.where = function (test, errorMessage) { + return _this.andThen(function (value) { return (test(value) ? Decoder.succeed(value) : Decoder.fail(errorMessage)); }); + }; + } + /** + * Decoder primitive that validates strings, and fails on all other input. + */ + Decoder.string = function () { + return new Decoder(function (json) { + return typeof json === 'string' + ? ok(json) + : err({ message: expectedGot('a string', json) }); + }); + }; + /** + * Decoder primitive that validates numbers, and fails on all other input. + */ + Decoder.number = function () { + return new Decoder(function (json) { + return typeof json === 'number' + ? ok(json) + : err({ message: expectedGot('a number', json) }); + }); + }; + /** + * Decoder primitive that validates booleans, and fails on all other input. + */ + Decoder.boolean = function () { + return new Decoder(function (json) { + return typeof json === 'boolean' + ? ok(json) + : err({ message: expectedGot('a boolean', json) }); + }); + }; + Decoder.constant = function (value) { + return new Decoder(function (json) { + return isEqual(json, value) + ? ok(value) + : err({ message: "expected " + JSON.stringify(value) + ", got " + JSON.stringify(json) }); + }); + }; + Decoder.object = function (decoders) { + return new Decoder(function (json) { + if (isJsonObject(json) && decoders) { + var obj = {}; + for (var key in decoders) { + if (decoders.hasOwnProperty(key)) { + var r = decoders[key].decode(json[key]); + if (r.ok === true) { + // tslint:disable-next-line:strict-type-predicates + if (r.result !== undefined) { + obj[key] = r.result; + } + } + else if (json[key] === undefined) { + return err({ message: "the key '" + key + "' is required but was not present" }); + } + else { + return err(prependAt("." + key, r.error)); + } + } + } + return ok(obj); + } + else if (isJsonObject(json)) { + return ok(json); + } + else { + return err({ message: expectedGot('an object', json) }); + } + }); + }; + Decoder.array = function (decoder) { + return new Decoder(function (json) { + if (isJsonArray(json) && decoder) { + var decodeValue_1 = function (v, i) { + return mapError(function (err$$1) { return prependAt("[" + i + "]", err$$1); }, decoder.decode(v)); + }; + return json.reduce(function (acc, v, i) { + return map2(function (arr, result) { return arr.concat([result]); }, acc, decodeValue_1(v, i)); + }, ok([])); + } + else if (isJsonArray(json)) { + return ok(json); + } + else { + return err({ message: expectedGot('an array', json) }); + } + }); + }; + Decoder.tuple = function (decoders) { + return new Decoder(function (json) { + if (isJsonArray(json)) { + if (json.length !== decoders.length) { + return err({ + message: "expected a tuple of length " + decoders.length + ", got one of length " + json.length + }); + } + var result = []; + for (var i = 0; i < decoders.length; i++) { + var nth = decoders[i].decode(json[i]); + if (nth.ok) { + result[i] = nth.result; + } + else { + return err(prependAt("[" + i + "]", nth.error)); + } + } + return ok(result); + } + else { + return err({ message: expectedGot("a tuple of length " + decoders.length, json) }); + } + }); + }; + Decoder.union = function (ad, bd) { + var decoders = []; + for (var _i = 2; _i < arguments.length; _i++) { + decoders[_i - 2] = arguments[_i]; + } + return Decoder.oneOf.apply(Decoder, [ad, bd].concat(decoders)); + }; + Decoder.intersection = function (ad, bd) { + var ds = []; + for (var _i = 2; _i < arguments.length; _i++) { + ds[_i - 2] = arguments[_i]; + } + return new Decoder(function (json) { + return [ad, bd].concat(ds).reduce(function (acc, decoder) { return map2(Object.assign, acc, decoder.decode(json)); }, ok({})); + }); + }; + /** + * Escape hatch to bypass validation. Always succeeds and types the result as + * `any`. Useful for defining decoders incrementally, particularly for + * complex objects. + * + * Example: + * ``` + * interface User { + * name: string; + * complexUserData: ComplexType; + * } + * + * const userDecoder: Decoder = object({ + * name: string(), + * complexUserData: anyJson() + * }); + * ``` + */ + Decoder.anyJson = function () { return new Decoder(function (json) { return ok(json); }); }; + /** + * Decoder identity function which always succeeds and types the result as + * `unknown`. + */ + Decoder.unknownJson = function () { + return new Decoder(function (json) { return ok(json); }); + }; + /** + * Decoder for json objects where the keys are unknown strings, but the values + * should all be of the same type. + * + * Example: + * ``` + * dict(number()).run({chocolate: 12, vanilla: 10, mint: 37}); + * // => {ok: true, result: {chocolate: 12, vanilla: 10, mint: 37}} + * ``` + */ + Decoder.dict = function (decoder) { + return new Decoder(function (json) { + if (isJsonObject(json)) { + var obj = {}; + for (var key in json) { + if (json.hasOwnProperty(key)) { + var r = decoder.decode(json[key]); + if (r.ok === true) { + obj[key] = r.result; + } + else { + return err(prependAt("." + key, r.error)); + } + } + } + return ok(obj); + } + else { + return err({ message: expectedGot('an object', json) }); + } + }); + }; + /** + * Decoder for values that may be `undefined`. This is primarily helpful for + * decoding interfaces with optional fields. + * + * Example: + * ``` + * interface User { + * id: number; + * isOwner?: boolean; + * } + * + * const decoder: Decoder = object({ + * id: number(), + * isOwner: optional(boolean()) + * }); + * ``` + */ + Decoder.optional = function (decoder) { + return new Decoder(function (json) { return (json === undefined || json === null ? ok(undefined) : decoder.decode(json)); }); + }; + /** + * Decoder that attempts to run each decoder in `decoders` and either succeeds + * with the first successful decoder, or fails after all decoders have failed. + * + * Note that `oneOf` expects the decoders to all have the same return type, + * while `union` creates a decoder for the union type of all the input + * decoders. + * + * Examples: + * ``` + * oneOf(string(), number().map(String)) + * oneOf(constant('start'), constant('stop'), succeed('unknown')) + * ``` + */ + Decoder.oneOf = function () { + var decoders = []; + for (var _i = 0; _i < arguments.length; _i++) { + decoders[_i] = arguments[_i]; + } + return new Decoder(function (json) { + var errors = []; + for (var i = 0; i < decoders.length; i++) { + var r = decoders[i].decode(json); + if (r.ok === true) { + return r; + } + else { + errors[i] = r.error; + } + } + var errorsList = errors + .map(function (error) { return "at error" + (error.at || '') + ": " + error.message; }) + .join('", "'); + return err({ + message: "expected a value matching one of the decoders, got the errors [\"" + errorsList + "\"]" + }); + }); + }; + /** + * Decoder that always succeeds with either the decoded value, or a fallback + * default value. + */ + Decoder.withDefault = function (defaultValue, decoder) { + return new Decoder(function (json) { + return ok(withDefault(defaultValue, decoder.decode(json))); + }); + }; + /** + * Decoder that pulls a specific field out of a json structure, instead of + * decoding and returning the full structure. The `paths` array describes the + * object keys and array indices to traverse, so that values can be pulled out + * of a nested structure. + * + * Example: + * ``` + * const decoder = valueAt(['a', 'b', 0], string()); + * + * decoder.run({a: {b: ['surprise!']}}) + * // => {ok: true, result: 'surprise!'} + * + * decoder.run({a: {x: 'cats'}}) + * // => {ok: false, error: {... at: 'input.a.b[0]' message: 'path does not exist'}} + * ``` + * + * Note that the `decoder` is ran on the value found at the last key in the + * path, even if the last key is not found. This allows the `optional` + * decoder to succeed when appropriate. + * ``` + * const optionalDecoder = valueAt(['a', 'b', 'c'], optional(string())); + * + * optionalDecoder.run({a: {b: {c: 'surprise!'}}}) + * // => {ok: true, result: 'surprise!'} + * + * optionalDecoder.run({a: {b: 'cats'}}) + * // => {ok: false, error: {... at: 'input.a.b.c' message: 'expected an object, got "cats"'} + * + * optionalDecoder.run({a: {b: {z: 1}}}) + * // => {ok: true, result: undefined} + * ``` + */ + Decoder.valueAt = function (paths, decoder) { + return new Decoder(function (json) { + var jsonAtPath = json; + for (var i = 0; i < paths.length; i++) { + if (jsonAtPath === undefined) { + return err({ + at: printPath(paths.slice(0, i + 1)), + message: 'path does not exist' + }); + } + else if (typeof paths[i] === 'string' && !isJsonObject(jsonAtPath)) { + return err({ + at: printPath(paths.slice(0, i + 1)), + message: expectedGot('an object', jsonAtPath) + }); + } + else if (typeof paths[i] === 'number' && !isJsonArray(jsonAtPath)) { + return err({ + at: printPath(paths.slice(0, i + 1)), + message: expectedGot('an array', jsonAtPath) + }); + } + else { + jsonAtPath = jsonAtPath[paths[i]]; + } + } + return mapError(function (error) { + return jsonAtPath === undefined + ? { at: printPath(paths), message: 'path does not exist' } + : prependAt(printPath(paths), error); + }, decoder.decode(jsonAtPath)); + }); + }; + /** + * Decoder that ignores the input json and always succeeds with `fixedValue`. + */ + Decoder.succeed = function (fixedValue) { + return new Decoder(function (json) { return ok(fixedValue); }); + }; + /** + * Decoder that ignores the input json and always fails with `errorMessage`. + */ + Decoder.fail = function (errorMessage) { + return new Decoder(function (json) { return err({ message: errorMessage }); }); + }; + /** + * Decoder that allows for validating recursive data structures. Unlike with + * functions, decoders assigned to variables can't reference themselves + * before they are fully defined. We can avoid prematurely referencing the + * decoder by wrapping it in a function that won't be called until use, at + * which point the decoder has been defined. + * + * Example: + * ``` + * interface Comment { + * msg: string; + * replies: Comment[]; + * } + * + * const decoder: Decoder = object({ + * msg: string(), + * replies: lazy(() => array(decoder)) + * }); + * ``` + */ + Decoder.lazy = function (mkDecoder) { + return new Decoder(function (json) { return mkDecoder().decode(json); }); + }; + return Decoder; + }()); + + /* tslint:disable:variable-name */ + /** See `Decoder.string` */ + var string = Decoder.string; + /** See `Decoder.number` */ + var number = Decoder.number; + /** See `Decoder.boolean` */ + var boolean = Decoder.boolean; + /** See `Decoder.anyJson` */ + var anyJson = Decoder.anyJson; + /** See `Decoder.unknownJson` */ + Decoder.unknownJson; + /** See `Decoder.constant` */ + var constant = Decoder.constant; + /** See `Decoder.object` */ + var object = Decoder.object; + /** See `Decoder.array` */ + var array = Decoder.array; + /** See `Decoder.tuple` */ + Decoder.tuple; + /** See `Decoder.dict` */ + Decoder.dict; + /** See `Decoder.optional` */ + var optional = Decoder.optional; + /** See `Decoder.oneOf` */ + var oneOf = Decoder.oneOf; + /** See `Decoder.union` */ + Decoder.union; + /** See `Decoder.intersection` */ + var intersection = Decoder.intersection; + /** See `Decoder.withDefault` */ + Decoder.withDefault; + /** See `Decoder.valueAt` */ + Decoder.valueAt; + /** See `Decoder.succeed` */ + Decoder.succeed; + /** See `Decoder.fail` */ + Decoder.fail; + /** See `Decoder.lazy` */ + var lazy = Decoder.lazy; + + const nonEmptyStringDecoder = string().where((s) => s.length > 0, "Expected a non-empty string"); + const nonNegativeNumberDecoder = number().where((num) => num >= 0, "Expected a non-negative number"); + const positiveNumberDecoder = number().where((num) => num > 0, "Expected a positive number"); + const windowDragModeDecoder = oneOf(constant("keepInside"), constant("autoEject")); + const isWindowInSwimlaneResultDecoder = object({ + inWorkspace: boolean() + }); + const allParentDecoder = oneOf(constant("workspace"), constant("row"), constant("column"), constant("group")); + const subParentDecoder = oneOf(constant("row"), constant("column"), constant("group")); + const frameStateDecoder = oneOf(constant("maximized"), constant("minimized"), constant("normal")); + const loadingAnimationTypeDecoder = oneOf(constant("workspace")); + const checkThrowCallback = (callback, allowUndefined) => { + const argumentType = typeof callback; + if (allowUndefined && argumentType !== "function" && argumentType !== "undefined") { + throw new Error(`Provided argument must be either undefined or of type function, provided: ${argumentType}`); + } + if (!allowUndefined && argumentType !== "function") { + throw new Error(`Provided argument must be of type function, provided: ${argumentType}`); + } + }; + const workspaceBuilderCreateConfigDecoder = optional(object({ + saveLayout: optional(boolean()) + })); + const deleteLayoutConfigDecoder = object({ + name: nonEmptyStringDecoder + }); + const windowDefinitionConfigDecoder = object({ + minWidth: optional(number()), + maxWidth: optional(number()), + minHeight: optional(number()), + maxHeight: optional(number()), + allowExtract: optional(boolean()), + allowReorder: optional(boolean()), + showCloseButton: optional(boolean()) + }); + const groupDefinitionConfigDecoder = object({ + minWidth: optional(number()), + maxWidth: optional(number()), + minHeight: optional(number()), + maxHeight: optional(number()), + allowExtract: optional(boolean()), + allowReorder: optional(boolean()), + allowDrop: optional(boolean()), + allowDropHeader: optional(boolean()), + allowDropLeft: optional(boolean()), + allowDropRight: optional(boolean()), + allowDropTop: optional(boolean()), + allowDropBottom: optional(boolean()), + showMaximizeButton: optional(boolean()), + showEjectButton: optional(boolean()), + showAddWindowButton: optional(boolean()) + }); + const rowDefinitionConfigDecoder = object({ + minHeight: optional(number()), + maxHeight: optional(number()), + allowDrop: optional(boolean()), + allowSplitters: optional(boolean()), + isPinned: optional(boolean()), + maximizationBoundary: optional(boolean()) + }); + const columnDefinitionConfigDecoder = object({ + minWidth: optional(number()), + maxWidth: optional(number()), + allowDrop: optional(boolean()), + allowSplitters: optional(boolean()), + isPinned: optional(boolean()), + maximizationBoundary: optional(boolean()) + }); + const swimlaneWindowDefinitionDecoder = object({ + type: optional(constant("window")), + appName: optional(nonEmptyStringDecoder), + windowId: optional(nonEmptyStringDecoder), + context: optional(anyJson()), + config: optional(windowDefinitionConfigDecoder) + }); + const strictSwimlaneWindowDefinitionDecoder = object({ + type: constant("window"), + appName: optional(nonEmptyStringDecoder), + windowId: optional(nonEmptyStringDecoder), + context: optional(anyJson()), + config: optional(windowDefinitionConfigDecoder) + }); + const parentDefinitionDecoder = optional(object({ + type: optional(subParentDecoder), + children: optional(lazy(() => array(oneOf(swimlaneWindowDefinitionDecoder, parentDefinitionDecoder)))), + config: optional(anyJson()) + })); + const strictColumnDefinitionDecoder = object({ + type: constant("column"), + children: optional(lazy(() => array(oneOf(strictSwimlaneWindowDefinitionDecoder, strictParentDefinitionDecoder)))), + config: optional(columnDefinitionConfigDecoder) + }); + const strictRowDefinitionDecoder = object({ + type: constant("row"), + children: optional(lazy(() => array(oneOf(strictSwimlaneWindowDefinitionDecoder, strictParentDefinitionDecoder)))), + config: optional(rowDefinitionConfigDecoder) + }); + const strictGroupDefinitionDecoder = object({ + type: constant("group"), + children: optional(lazy(() => array(oneOf(strictSwimlaneWindowDefinitionDecoder, strictParentDefinitionDecoder)))), + config: optional(groupDefinitionConfigDecoder) + }); + const strictParentDefinitionDecoder = oneOf(strictGroupDefinitionDecoder, strictColumnDefinitionDecoder, strictRowDefinitionDecoder); + oneOf(string().where((s) => s.toLowerCase() === "maximized", "Expected a case insensitive variation of 'maximized'"), string().where((s) => s.toLowerCase() === "normal", "Expected a case insensitive variation of 'normal'")); + const newFrameConfigDecoder = object({ + bounds: optional(object({ + left: optional(number()), + top: optional(number()), + width: optional(nonNegativeNumberDecoder), + height: optional(nonNegativeNumberDecoder) + })), + frameId: optional(nonEmptyStringDecoder) + }); + const loadingStrategyDecoder = oneOf(constant("direct"), constant("delayed"), constant("lazy")); + const restoreWorkspaceConfigDecoder = optional(object({ + app: optional(nonEmptyStringDecoder), + context: optional(anyJson()), + loadingStrategy: optional(loadingStrategyDecoder), + title: optional(nonEmptyStringDecoder), + reuseWorkspaceId: optional(nonEmptyStringDecoder), + frameId: optional(nonEmptyStringDecoder), + applicationName: optional(nonEmptyStringDecoder), + lockdown: optional(boolean()), + activateFrame: optional(boolean()), + newFrame: optional(oneOf(newFrameConfigDecoder, boolean())), + noTabHeader: optional(boolean()), + inMemoryLayout: optional(boolean()), + icon: optional(nonEmptyStringDecoder), + isPinned: optional(boolean()), + isSelected: optional(boolean()), + positionIndex: optional(nonNegativeNumberDecoder), + allowSystemHibernation: optional(boolean()) + })); + const openWorkspaceConfigDecoder = object({ + name: nonEmptyStringDecoder, + restoreOptions: optional(restoreWorkspaceConfigDecoder) + }); + const workspaceDefinitionDecoder = object({ + children: optional(array(oneOf(swimlaneWindowDefinitionDecoder, strictParentDefinitionDecoder))), + context: optional(anyJson()), + config: optional(object({ + title: optional(nonEmptyStringDecoder), + position: optional(nonNegativeNumberDecoder), + isFocused: optional(boolean()), + noTabHeader: optional(boolean()), + reuseWorkspaceId: optional(nonEmptyStringDecoder), + loadingStrategy: optional(loadingStrategyDecoder), + allowDrop: optional(boolean()), + allowDropLeft: optional(boolean()), + allowDropTop: optional(boolean()), + allowDropRight: optional(boolean()), + allowDropBottom: optional(boolean()), + allowSystemHibernation: optional(boolean()), + allowExtract: optional(boolean()), + allowWindowReorder: optional(boolean()), + showSaveButton: optional(boolean()), + allowWorkspaceTabReorder: optional(boolean()), + allowWorkspaceTabExtract: optional(boolean()), + showCloseButton: optional(boolean()), + allowSplitters: optional(boolean()), + showWindowCloseButtons: optional(boolean()), + showEjectButtons: optional(boolean()), + showAddWindowButtons: optional(boolean()), + icon: optional(nonEmptyStringDecoder), + isPinned: optional(boolean()), + isSelected: optional(boolean()), + positionIndex: optional(nonNegativeNumberDecoder), + windowDragMode: optional(windowDragModeDecoder) + })), + frame: optional(object({ + activate: optional(boolean()), + reuseFrameId: optional(nonEmptyStringDecoder), + applicationName: optional(nonEmptyStringDecoder), + newFrame: optional(oneOf(boolean(), newFrameConfigDecoder)) + })) + }); + const workspaceSelectorDecoder = object({ + workspaceId: nonEmptyStringDecoder + }); + const restoreWorkspaceDefinitionDecoder = object({ + name: nonEmptyStringDecoder, + restoreOptions: optional(restoreWorkspaceConfigDecoder) + }); + const emptyFrameDefinitionDecoder = optional(object({ + applicationName: optional(string()), + frameConfig: optional(newFrameConfigDecoder), + context: optional(object()), + layoutComponentId: optional(nonEmptyStringDecoder) + })); + const frameInitConfigDecoder = object({ + workspaces: array(oneOf(optional(workspaceDefinitionDecoder), optional(restoreWorkspaceDefinitionDecoder))) + }); + const frameInitProtocolConfigDecoder = object({ + frameId: nonEmptyStringDecoder, + workspaces: array(oneOf(workspaceDefinitionDecoder, restoreWorkspaceDefinitionDecoder)) + }); + const builderConfigDecoder = object({ + type: allParentDecoder, + definition: optional(oneOf(workspaceDefinitionDecoder, parentDefinitionDecoder)) + }); + const workspaceCreateConfigDecoder = intersection(workspaceDefinitionDecoder, object({ + saveConfig: optional(object({ + saveLayout: optional(boolean()) + })) + })); + const getFrameSummaryConfigDecoder = object({ + itemId: nonEmptyStringDecoder + }); + const frameInitializationContextDecoder = object({ + context: optional(object()) + }); + const frameSummaryDecoder = object({ + id: nonEmptyStringDecoder, + isFocused: optional(boolean()), + isInitialized: optional(boolean()), + initializationContext: optional(frameInitializationContextDecoder) + }); + object({ + type: subParentDecoder, + id: nonEmptyStringDecoder, + frameId: nonEmptyStringDecoder, + workspaceId: nonEmptyStringDecoder, + positionIndex: number() + }); + const eventTypeDecoder = oneOf(constant("frame"), constant("workspace"), constant("container"), constant("window")); + const streamRequestArgumentsDecoder = object({ + type: eventTypeDecoder, + branch: nonEmptyStringDecoder + }); + const workspaceEventActionDecoder = oneOf(constant("opened"), constant("closing"), constant("closed"), constant("focus"), constant("added"), constant("loaded"), constant("removed"), constant("childrenUpdate"), constant("containerChange"), constant("maximized"), constant("restored"), constant("minimized"), constant("normal"), constant("selected"), constant("lock-configuration-changed"), constant("hibernated"), constant("resumed")); + const workspaceConfigResultDecoder = object({ + frameId: nonEmptyStringDecoder, + title: nonEmptyStringDecoder, + positionIndex: nonNegativeNumberDecoder, + name: nonEmptyStringDecoder, + layoutName: optional(nonEmptyStringDecoder), + isHibernated: optional(boolean()), + isSelected: optional(boolean()), + allowDrop: optional(boolean()), + allowSystemHibernation: optional(boolean()), + allowExtract: optional(boolean()), + allowWindowReorder: optional(boolean()), + allowSplitters: optional(boolean()), + showCloseButton: optional(boolean()), + showSaveButton: optional(boolean()), + allowWorkspaceTabReorder: optional(boolean()), + allowWorkspaceTabExtract: optional(boolean()), + allowDropLeft: optional(boolean()), + allowDropTop: optional(boolean()), + allowDropRight: optional(boolean()), + allowDropBottom: optional(boolean()), + minWidth: optional(number()), + maxWidth: optional(number()), + minHeight: optional(number()), + maxHeight: optional(number()), + showAddWindowButtons: optional(boolean()), + showEjectButtons: optional(boolean()), + showWindowCloseButtons: optional(boolean()), + widthInPx: optional(number()), + heightInPx: optional(number()), + isPinned: optional(boolean()), + windowDragMode: optional(windowDragModeDecoder), + loadingStrategy: optional(loadingStrategyDecoder) + }); + const baseChildSnapshotConfigDecoder = object({ + frameId: nonEmptyStringDecoder, + workspaceId: nonEmptyStringDecoder, + positionIndex: number(), + minWidth: optional(number()), + maxWidth: optional(number()), + minHeight: optional(number()), + maxHeight: optional(number()) + }); + const parentSnapshotConfigDecoder = anyJson(); + const swimlaneWindowSnapshotConfigDecoder = intersection(baseChildSnapshotConfigDecoder, object({ + windowId: optional(nonEmptyStringDecoder), + isMaximized: optional(boolean()), + isFocused: boolean(), + isSelected: optional(boolean()), + title: optional(string()), + appName: optional(nonEmptyStringDecoder), + allowExtract: optional(boolean()), + allowReorder: optional(boolean()), + showCloseButton: optional(boolean()), + minWidth: optional(number()), + minHeight: optional(number()), + maxWidth: optional(number()), + maxHeight: optional(number()), + widthInPx: optional(number()), + heightInPx: optional(number()), + context: optional(anyJson()) + })); + const customWorkspaceSubParentSnapshotDecoder = object({ + id: optional(nonEmptyStringDecoder), + config: parentSnapshotConfigDecoder, + children: optional(lazy(() => array(customWorkspaceChildSnapshotDecoder))), + type: oneOf(constant("row"), constant("column"), constant("group")) + }); + const customWorkspaceWindowSnapshotDecoder = object({ + id: optional(nonEmptyStringDecoder), + config: swimlaneWindowSnapshotConfigDecoder, + type: constant("window") + }); + const customWorkspaceChildSnapshotDecoder = oneOf(customWorkspaceWindowSnapshotDecoder, customWorkspaceSubParentSnapshotDecoder); + const childSnapshotResultDecoder = customWorkspaceChildSnapshotDecoder; + const workspaceSnapshotResultDecoder = object({ + id: nonEmptyStringDecoder, + config: workspaceConfigResultDecoder, + children: array(childSnapshotResultDecoder), + frameSummary: frameSummaryDecoder, + context: optional(anyJson()) + }); + const windowLayoutItemDecoder = object({ + type: constant("window"), + config: object({ + appName: nonEmptyStringDecoder, + windowId: optional(nonEmptyStringDecoder), + context: optional(anyJson()), + url: optional(nonEmptyStringDecoder), + title: optional(string()), + allowExtract: optional(boolean()), + allowReorder: optional(boolean()), + showCloseButton: optional(boolean()), + minWidth: optional(number()), + minHeight: optional(number()), + maxWidth: optional(number()), + maxHeight: optional(number()), + isMaximized: optional(boolean()) + }) + }); + const groupLayoutItemDecoder = object({ + type: constant("group"), + config: anyJson(), + children: array(oneOf(windowLayoutItemDecoder)) + }); + const columnLayoutItemDecoder = object({ + type: constant("column"), + config: anyJson(), + children: array(oneOf(groupLayoutItemDecoder, windowLayoutItemDecoder, lazy(() => columnLayoutItemDecoder), lazy(() => rowLayoutItemDecoder))) + }); + const rowLayoutItemDecoder = object({ + type: constant("row"), + config: anyJson(), + children: array(oneOf(columnLayoutItemDecoder, groupLayoutItemDecoder, windowLayoutItemDecoder, lazy(() => rowLayoutItemDecoder))) + }); + const workspaceLayoutDecoder = object({ + name: nonEmptyStringDecoder, + type: constant("Workspace"), + metadata: optional(anyJson()), + components: array(object({ + type: constant("Workspace"), + application: optional(string()), + state: object({ + config: anyJson(), + context: anyJson(), + children: array(oneOf(rowLayoutItemDecoder, columnLayoutItemDecoder, groupLayoutItemDecoder, windowLayoutItemDecoder)) + }) + })) + }); + const workspacesImportLayoutDecoder = object({ + layout: workspaceLayoutDecoder, + mode: oneOf(constant("replace"), constant("merge")) + }); + const workspacesImportLayoutsDecoder = object({ + layouts: array(workspaceLayoutDecoder), + mode: oneOf(constant("replace"), constant("merge")) + }); + const exportedLayoutsResultDecoder = object({ + layouts: array(workspaceLayoutDecoder) + }); + const frameSummaryResultDecoder = object({ + id: nonEmptyStringDecoder, + isFocused: optional(boolean()), + isInitialized: optional(boolean()), + initializationContext: optional(frameInitializationContextDecoder) + }); + const frameSummariesResultDecoder = object({ + summaries: array(frameSummaryResultDecoder) + }); + const workspaceSummaryResultDecoder = object({ + id: nonEmptyStringDecoder, + config: workspaceConfigResultDecoder + }); + const workspaceSummariesResultDecoder = object({ + summaries: array(workspaceSummaryResultDecoder) + }); + const frameSnapshotResultDecoder = object({ + id: nonEmptyStringDecoder, + config: anyJson(), + workspaces: array(workspaceSnapshotResultDecoder) + }); + const layoutSummaryDecoder = object({ + name: nonEmptyStringDecoder, + applicationName: optional(string()) + }); + const layoutSummariesDecoder = object({ + summaries: array(layoutSummaryDecoder) + }); + const simpleWindowOperationSuccessResultDecoder = object({ + windowId: nonEmptyStringDecoder + }); + const voidResultDecoder = anyJson(); + const frameStateResultDecoder = object({ + state: frameStateDecoder + }); + const frameBoundsDecoder = object({ + top: number(), + left: number(), + width: nonNegativeNumberDecoder, + height: nonNegativeNumberDecoder + }); + const frameBoundsResultDecoder = object({ + bounds: frameBoundsDecoder + }); + const getWorkspaceIconResultDecoder = object({ + icon: optional(nonEmptyStringDecoder) + }); + const getPlatformFrameIdResultDecoder = object({ + id: optional(nonEmptyStringDecoder) + }); + const operationCheckResultDecoder = object({ + isSupported: boolean() + }); + const resizeConfigDecoder = object({ + width: optional(positiveNumberDecoder), + height: optional(positiveNumberDecoder), + relative: optional(boolean()) + }); + const moveConfigDecoder = object({ + top: optional(number()), + left: optional(number()), + relative: optional(boolean()) + }); + const simpleItemConfigDecoder = object({ + itemId: nonEmptyStringDecoder + }); + const frameSnapshotConfigDecoder = object({ + itemId: nonEmptyStringDecoder, + excludeIds: optional(boolean()) + }); + const frameStateConfigDecoder = object({ + frameId: nonEmptyStringDecoder, + requestedState: frameStateDecoder + }); + const setItemTitleConfigDecoder = object({ + itemId: nonEmptyStringDecoder, + title: nonEmptyStringDecoder + }); + const moveWindowConfigDecoder = object({ + itemId: nonEmptyStringDecoder, + containerId: nonEmptyStringDecoder + }); + const resizeItemConfigDecoder = intersection(simpleItemConfigDecoder, resizeConfigDecoder); + const setMaximizationBoundaryConfigDecoder = object({ + itemId: nonEmptyStringDecoder, + enabled: boolean() + }); + const moveFrameConfigDecoder = intersection(simpleItemConfigDecoder, moveConfigDecoder); + object({ + id: nonEmptyStringDecoder, + type: subParentDecoder + }); + const addWindowConfigDecoder = object({ + definition: swimlaneWindowDefinitionDecoder, + parentId: nonEmptyStringDecoder, + parentType: allParentDecoder + }); + const addContainerConfigDecoder = object({ + definition: strictParentDefinitionDecoder, + parentId: nonEmptyStringDecoder, + parentType: allParentDecoder + }); + const addItemResultDecoder = object({ + itemId: nonEmptyStringDecoder, + windowId: optional(nonEmptyStringDecoder) + }); + const pingResultDecoder = object({ + live: boolean() + }); + const bundleWorkspaceConfigDecoder = object({ + type: oneOf(constant("row"), constant("column")), + workspaceId: nonEmptyStringDecoder + }); + const bundleItemConfigDecoder = object({ + type: oneOf(constant("row"), constant("column")), + itemId: nonEmptyStringDecoder + }); + const containerSummaryResultDecoder = object({ + itemId: nonEmptyStringDecoder, + config: parentSnapshotConfigDecoder + }); + const frameStreamDataDecoder = object({ + frameSummary: frameSummaryDecoder, + frameBounds: optional(frameBoundsDecoder) + }); + const workspaceStreamDataDecoder = object({ + workspaceSummary: workspaceSummaryResultDecoder, + frameSummary: frameSummaryDecoder, + workspaceSnapshot: optional(workspaceSnapshotResultDecoder), + frameBounds: optional(frameBoundsDecoder) + }); + const containerStreamDataDecoder = object({ + containerSummary: containerSummaryResultDecoder + }); + const windowStreamDataDecoder = object({ + windowSummary: object({ + itemId: nonEmptyStringDecoder, + parentId: nonEmptyStringDecoder, + config: swimlaneWindowSnapshotConfigDecoder + }) + }); + const workspaceLayoutSaveConfigDecoder = object({ + name: nonEmptyStringDecoder, + workspaceId: nonEmptyStringDecoder, + saveContext: optional(boolean()), + allowMultiple: optional(boolean()), + metadata: optional(object()) + }); + const workspaceLockConfigDecoder = object({ + allowDrop: optional(boolean()), + allowDropLeft: optional(boolean()), + allowDropTop: optional(boolean()), + allowDropRight: optional(boolean()), + allowDropBottom: optional(boolean()), + allowSystemHibernation: optional(boolean()), + allowExtract: optional(boolean()), + allowWindowReorder: optional(boolean()), + allowSplitters: optional(boolean()), + showCloseButton: optional(boolean()), + showSaveButton: optional(boolean()), + allowWorkspaceTabReorder: optional(boolean()), + allowWorkspaceTabExtract: optional(boolean()), + showWindowCloseButtons: optional(boolean()), + showAddWindowButtons: optional(boolean()), + showEjectButtons: optional(boolean()), + }); + const lockWorkspaceDecoder = object({ + workspaceId: nonEmptyStringDecoder, + config: optional(workspaceLockConfigDecoder) + }); + const windowLockConfigDecoder = object({ + allowExtract: optional(boolean()), + allowReorder: optional(boolean()), + showCloseButton: optional(boolean()) + }); + const elementResizeConfigDecoder = object({ + width: optional(nonNegativeNumberDecoder), + height: optional(nonNegativeNumberDecoder) + }); + const lockWindowDecoder = object({ + windowPlacementId: nonEmptyStringDecoder, + config: optional(windowLockConfigDecoder) + }); + const rowLockConfigDecoder = object({ + allowDrop: optional(boolean()), + allowSplitters: optional(boolean()), + }); + const columnLockConfigDecoder = object({ + allowDrop: optional(boolean()), + allowSplitters: optional(boolean()), + }); + const groupLockConfigDecoder = object({ + allowExtract: optional(boolean()), + allowReorder: optional(boolean()), + allowDrop: optional(boolean()), + allowDropLeft: optional(boolean()), + allowDropRight: optional(boolean()), + allowDropTop: optional(boolean()), + allowDropBottom: optional(boolean()), + allowDropHeader: optional(boolean()), + showMaximizeButton: optional(boolean()), + showEjectButton: optional(boolean()), + showAddWindowButton: optional(boolean()), + }); + const lockRowDecoder = object({ + itemId: nonEmptyStringDecoder, + type: constant("row"), + config: optional(rowLockConfigDecoder) + }); + const lockColumnDecoder = object({ + itemId: nonEmptyStringDecoder, + type: constant("column"), + config: optional(columnLockConfigDecoder) + }); + const lockGroupDecoder = object({ + itemId: nonEmptyStringDecoder, + type: constant("group"), + config: optional(groupLockConfigDecoder) + }); + const lockContainerDecoder = oneOf(lockRowDecoder, lockColumnDecoder, lockGroupDecoder); + const pinWorkspaceDecoder = object({ + workspaceId: nonEmptyStringDecoder, + icon: optional(nonEmptyStringDecoder) + }); + const setWorkspaceIconDecoder = object({ + workspaceId: nonEmptyStringDecoder, + icon: optional(nonEmptyStringDecoder) + }); + const workspacePinOptionsDecoder = optional(object({ + icon: optional(nonEmptyStringDecoder) + })); + const shortcutConfigDecoder = object({ + shortcut: nonEmptyStringDecoder, + frameId: nonEmptyStringDecoder + }); + const shortcutClickedDataDecoder = object({ + shortcut: nonEmptyStringDecoder, + frameId: nonEmptyStringDecoder + }); + const setMaximizationBoundaryAPIConfigDecoder = object({ + enabled: boolean() + }); + const loadingAnimationConfigDecoder = object({ + itemId: nonEmptyStringDecoder, + type: loadingAnimationTypeDecoder + }); + const operationCheckConfigDecoder = object({ + operation: nonEmptyStringDecoder + }); + const setWindowDragModeDecoder = object({ + itemId: nonEmptyStringDecoder, + dragMode: windowDragModeDecoder + }); + const setLoadingStrategyDecoder = object({ + itemId: nonEmptyStringDecoder, + strategy: loadingStrategyDecoder + }); + + const webPlatformMethodName = "T42.Web.Platform.Control"; + const webPlatformWspStreamName = "T42.Web.Platform.WSP.Stream"; + const OUTGOING_METHODS = { + control: { name: "T42.Workspaces.Control", isStream: false }, + frameStream: { name: "T42.Workspaces.Stream.Frame", isStream: true }, + workspaceStream: { name: "T42.Workspaces.Stream.Workspace", isStream: true }, + containerStream: { name: "T42.Workspaces.Stream.Container", isStream: true }, + windowStream: { name: "T42.Workspaces.Stream.Window", isStream: true } + }; + const INCOMING_METHODS = { + control: { name: "T42.Workspaces.Client.Control", isStream: false }, + }; + const STREAMS = { + frame: { name: "T42.Workspaces.Stream.Frame", payloadDecoder: frameStreamDataDecoder }, + workspace: { name: "T42.Workspaces.Stream.Workspace", payloadDecoder: workspaceStreamDataDecoder }, + container: { name: "T42.Workspaces.Stream.Container", payloadDecoder: containerStreamDataDecoder }, + window: { name: "T42.Workspaces.Stream.Window", payloadDecoder: windowStreamDataDecoder } + }; + const CLIENT_OPERATIONS = { + shortcutClicked: { name: "shortcutClicked", argsDecoder: shortcutClickedDataDecoder, resultDecoder: voidResultDecoder }, + }; + const OPERATIONS = { + ping: { name: "ping", resultDecoder: pingResultDecoder }, + isWindowInWorkspace: { name: "isWindowInWorkspace", argsDecoder: simpleItemConfigDecoder, resultDecoder: isWindowInSwimlaneResultDecoder }, + createWorkspace: { name: "createWorkspace", resultDecoder: workspaceSnapshotResultDecoder, argsDecoder: workspaceCreateConfigDecoder }, + createFrame: { name: "createFrame", resultDecoder: frameSummaryResultDecoder, argsDecoder: emptyFrameDefinitionDecoder }, + initFrame: { name: "initFrame", resultDecoder: voidResultDecoder, argsDecoder: frameInitProtocolConfigDecoder }, + getAllFramesSummaries: { name: "getAllFramesSummaries", resultDecoder: frameSummariesResultDecoder }, + getFrameSummary: { name: "getFrameSummary", resultDecoder: frameSummaryDecoder, argsDecoder: getFrameSummaryConfigDecoder }, + getAllWorkspacesSummaries: { name: "getAllWorkspacesSummaries", resultDecoder: workspaceSummariesResultDecoder }, + getWorkspaceSnapshot: { name: "getWorkspaceSnapshot", resultDecoder: workspaceSnapshotResultDecoder, argsDecoder: simpleItemConfigDecoder }, + getAllLayoutsSummaries: { name: "getAllLayoutsSummaries", resultDecoder: layoutSummariesDecoder }, + openWorkspace: { name: "openWorkspace", argsDecoder: openWorkspaceConfigDecoder, resultDecoder: workspaceSnapshotResultDecoder }, + deleteLayout: { name: "deleteLayout", resultDecoder: voidResultDecoder, argsDecoder: deleteLayoutConfigDecoder }, + saveLayout: { name: "saveLayout", resultDecoder: workspaceLayoutDecoder, argsDecoder: workspaceLayoutSaveConfigDecoder }, + importLayout: { name: "importLayout", resultDecoder: voidResultDecoder, argsDecoder: workspacesImportLayoutDecoder }, + importLayouts: { name: "importLayouts", resultDecoder: voidResultDecoder, argsDecoder: workspacesImportLayoutsDecoder }, + exportAllLayouts: { name: "exportAllLayouts", resultDecoder: exportedLayoutsResultDecoder }, + restoreItem: { name: "restoreItem", argsDecoder: simpleItemConfigDecoder, resultDecoder: voidResultDecoder }, + maximizeItem: { name: "maximizeItem", argsDecoder: simpleItemConfigDecoder, resultDecoder: voidResultDecoder }, + focusItem: { name: "focusItem", argsDecoder: simpleItemConfigDecoder, resultDecoder: voidResultDecoder }, + closeItem: { name: "closeItem", argsDecoder: simpleItemConfigDecoder, resultDecoder: voidResultDecoder }, + resizeItem: { name: "resizeItem", argsDecoder: resizeItemConfigDecoder, resultDecoder: voidResultDecoder }, + setMaximizationBoundary: { name: "setMaximizationBoundary", argsDecoder: setMaximizationBoundaryConfigDecoder, resultDecoder: voidResultDecoder }, + changeFrameState: { name: "changeFrameState", argsDecoder: frameStateConfigDecoder, resultDecoder: voidResultDecoder }, + getFrameState: { name: "getFrameState", argsDecoder: simpleItemConfigDecoder, resultDecoder: frameStateResultDecoder }, + getFrameBounds: { name: "getFrameBounds", argsDecoder: simpleItemConfigDecoder, resultDecoder: frameBoundsResultDecoder }, + moveFrame: { name: "moveFrame", argsDecoder: moveFrameConfigDecoder, resultDecoder: voidResultDecoder }, + getFrameSnapshot: { name: "getFrameSnapshot", argsDecoder: frameSnapshotConfigDecoder, resultDecoder: frameSnapshotResultDecoder }, + forceLoadWindow: { name: "forceLoadWindow", argsDecoder: simpleItemConfigDecoder, resultDecoder: simpleWindowOperationSuccessResultDecoder }, + ejectWindow: { name: "ejectWindow", argsDecoder: simpleItemConfigDecoder, resultDecoder: simpleWindowOperationSuccessResultDecoder }, + setItemTitle: { name: "setItemTitle", argsDecoder: setItemTitleConfigDecoder, resultDecoder: voidResultDecoder }, + moveWindowTo: { name: "moveWindowTo", argsDecoder: moveWindowConfigDecoder, resultDecoder: voidResultDecoder }, + addWindow: { name: "addWindow", argsDecoder: addWindowConfigDecoder, resultDecoder: addItemResultDecoder }, + addContainer: { name: "addContainer", argsDecoder: addContainerConfigDecoder, resultDecoder: addItemResultDecoder }, + bundleWorkspace: { name: "bundleWorkspace", argsDecoder: bundleWorkspaceConfigDecoder, resultDecoder: voidResultDecoder }, + bundleItem: { name: "bundleItem", argsDecoder: bundleItemConfigDecoder, resultDecoder: voidResultDecoder }, + hibernateWorkspace: { name: "hibernateWorkspace", argsDecoder: workspaceSelectorDecoder, resultDecoder: voidResultDecoder }, + resumeWorkspace: { name: "resumeWorkspace", argsDecoder: workspaceSelectorDecoder, resultDecoder: voidResultDecoder }, + lockWorkspace: { name: "lockWorkspace", argsDecoder: lockWorkspaceDecoder, resultDecoder: voidResultDecoder }, + lockWindow: { name: "lockWindow", argsDecoder: lockWindowDecoder, resultDecoder: voidResultDecoder }, + lockContainer: { name: "lockContainer", argsDecoder: lockContainerDecoder, resultDecoder: voidResultDecoder }, + pinWorkspace: { name: "pinWorkspace", argsDecoder: pinWorkspaceDecoder, resultDecoder: voidResultDecoder }, + unpinWorkspace: { name: "unpinWorkspace", argsDecoder: workspaceSelectorDecoder, resultDecoder: voidResultDecoder }, + getWorkspaceIcon: { name: "getWorkspaceIcon", argsDecoder: workspaceSelectorDecoder, resultDecoder: getWorkspaceIconResultDecoder }, + setWorkspaceIcon: { name: "setWorkspaceIcon", argsDecoder: setWorkspaceIconDecoder, resultDecoder: voidResultDecoder }, + registerShortcut: { name: "registerShortcut", argsDecoder: shortcutConfigDecoder, resultDecoder: voidResultDecoder }, + unregisterShortcut: { name: "unregisterShortcut", argsDecoder: shortcutConfigDecoder, resultDecoder: voidResultDecoder }, + showLoadingAnimation: { name: "showLoadingAnimation", argsDecoder: loadingAnimationConfigDecoder, resultDecoder: voidResultDecoder }, + hideLoadingAnimation: { name: "hideLoadingAnimation", argsDecoder: loadingAnimationConfigDecoder, resultDecoder: voidResultDecoder }, + getPlatformFrameId: { name: "getPlatformFrameId", resultDecoder: getPlatformFrameIdResultDecoder }, + operationCheck: { name: "operationCheck", argsDecoder: operationCheckConfigDecoder, resultDecoder: operationCheckResultDecoder }, + setWindowDragMode: { name: "setWindowDragMode", argsDecoder: setWindowDragModeDecoder, resultDecoder: voidResultDecoder }, + setLoadingStrategy: { name: "setLoadingStrategy", argsDecoder: setLoadingStrategyDecoder, resultDecoder: voidResultDecoder } + }; + + class PromiseWrapper { + resolve; + reject; + promise; + constructor() { + this.promise = new Promise((res, rej) => { + this.resolve = res; + this.reject = rej; + }); + } + } + + class Bridge { + transport; + registry; + activeSubscriptions = []; + pendingSubScriptions = []; + constructor(transport, registry) { + this.transport = transport; + this.registry = registry; + } + async createCoreEventSubscription() { + await this.transport.coreSubscriptionReady(this.handleCoreEvent.bind(this)); + } + handleCoreSubscription(config) { + const registryKey = `${config.eventType}-${config.action}`; + const scope = config.scope; + const scopeId = config.scopeId; + return this.registry.add(registryKey, (args) => { + const scopeConfig = { + type: scope, + id: scopeId + }; + const receivedIds = { + frame: args.frameSummary?.id || args.windowSummary?.config.frameId, + workspace: args.workspaceSummary?.id || args.windowSummary?.config.workspaceId, + container: args.containerSummary?.itemId, + window: args.windowSummary?.itemId + }; + const shouldInvokeCallback = this.checkScopeMatch(scopeConfig, receivedIds); + if (!shouldInvokeCallback) { + return; + } + config.callback(args); + }); + } + async send(operationName, operationArgs) { + const operationDefinition = Object.values(OPERATIONS).find((operation) => operation.name === operationName); + if (!operationDefinition) { + throw new Error(`Cannot find definition for operation name: ${operationName}`); + } + if (operationDefinition.argsDecoder) { + try { + operationDefinition.argsDecoder.runWithException(operationArgs); + } + catch (error) { + throw new Error(`Unexpected internal outgoing validation error: ${error.message}, for input: ${JSON.stringify(error.input)}, for operation ${operationName}`); + } + } + try { + const operationResult = await this.transport.transmitControl(operationDefinition.name, operationArgs); + operationDefinition.resultDecoder.runWithException(operationResult); + return operationResult; + } + catch (error) { + if (error.kind) { + throw new Error(`Unexpected internal incoming validation error: ${error.message}, for input: ${JSON.stringify(error.input)}, for operation ${operationName}`); + } + throw new Error(error.message); + } + } + async subscribe(config) { + const pendingSub = this.getPendingSubscription(config); + if (pendingSub) { + await pendingSub.promise; + } + let activeSub = this.getActiveSubscription(config); + const registryKey = this.getRegistryKey(config); + if (!activeSub) { + const pendingPromise = new PromiseWrapper(); + const pendingSubscription = { + streamType: config.eventType, + level: config.scope, + levelId: config.scopeId, + promise: pendingPromise.promise + }; + this.pendingSubScriptions.push(pendingSubscription); + try { + const stream = STREAMS[config.eventType]; + const gdSub = await this.transport.subscribe(stream.name, this.getBranchKey(config), config.eventType); + gdSub.onData((streamData) => { + const data = streamData.data; + const requestedArgumentsResult = streamRequestArgumentsDecoder.run(streamData.requestArguments); + const actionResult = workspaceEventActionDecoder.run(data.action); + if (!requestedArgumentsResult.ok || !actionResult.ok) { + return; + } + const streamType = requestedArgumentsResult.result.type; + const branch = requestedArgumentsResult.result.branch; + const keyToExecute = `${streamType}-${branch}-${actionResult.result}`; + const validatedPayload = STREAMS[streamType].payloadDecoder.run(data.payload); + if (!validatedPayload.ok) { + return; + } + this.registry.execute(keyToExecute, validatedPayload.result); + }); + activeSub = { + streamType: config.eventType, + level: config.scope, + levelId: config.scopeId, + callbacksCount: 0, + gdSub + }; + this.activeSubscriptions.push(activeSub); + pendingPromise.resolve(); + } + catch (error) { + pendingPromise.reject(error); + throw error; + } + finally { + this.removePendingSubscription(pendingSubscription); + } + } + const unsubscribe = this.registry.add(registryKey, config.callback); + ++activeSub.callbacksCount; + return () => { + unsubscribe(); + --activeSub.callbacksCount; + if (activeSub.callbacksCount === 0) { + activeSub.gdSub.close(); + this.activeSubscriptions.splice(this.activeSubscriptions.indexOf(activeSub), 1); + } + }; + } + onOperation(callback) { + const wrappedCallback = (payload, caller) => { + const operationName = payload.operation; + const operationArgs = payload.data; + const operationDefinition = Object.values(CLIENT_OPERATIONS).find((operation) => operation.name === operationName); + if (!operationDefinition) { + throw new Error(`Cannot find definition for operation name: ${operationName}`); + } + if (operationDefinition.argsDecoder) { + try { + operationDefinition.argsDecoder.runWithException(operationArgs); + } + catch (error) { + throw new Error(`Unexpected internal outgoing validation error: ${error.message}, for input: ${JSON.stringify(error.input)}, for operation ${operationName}`); + } + } + callback(payload, caller); + }; + return this.transport.onInternalMethodInvoked("control", wrappedCallback); + } + checkScopeMatch(scope, receivedIds) { + if (scope.type === "global") { + return true; + } + if (scope.type === "frame" && scope.id === receivedIds.frame) { + return true; + } + if (scope.type === "workspace" && scope.id === receivedIds.workspace) { + return true; + } + if (scope.type === "container" && scope.id === receivedIds.container) { + return true; + } + if (scope.type === "window" && scope.id === receivedIds.window) { + return true; + } + return false; + } + handleCoreEvent(args) { + const data = args.data; + try { + const verifiedAction = workspaceEventActionDecoder.runWithException(data.action); + const verifiedType = eventTypeDecoder.runWithException(data.type); + const verifiedPayload = STREAMS[verifiedType].payloadDecoder.runWithException(data.payload); + const registryKey = `${verifiedType}-${verifiedAction}`; + this.registry.execute(registryKey, verifiedPayload); + } + catch (error) { + console.warn(`Cannot handle event with data ${JSON.stringify(data)}, because of validation error: ${error.message}`); + } + } + getBranchKey(config) { + return config.scope === "global" ? config.scope : `${config.scope}_${config.scopeId}`; + } + getRegistryKey(config) { + return `${config.eventType}-${this.getBranchKey(config)}-${config.action}`; + } + getActiveSubscription(config) { + return this.activeSubscriptions + .find((activeSub) => activeSub.streamType === config.eventType && + activeSub.level === config.scope && + activeSub.levelId === config.scopeId); + } + getPendingSubscription(config) { + return this.pendingSubScriptions + .find((activeSub) => activeSub.streamType === config.eventType && + activeSub.level === config.scope && + activeSub.levelId === config.scopeId); + } + removePendingSubscription(pendingSubscription) { + const index = this.pendingSubScriptions.indexOf(pendingSubscription); + if (index >= 0) { + this.pendingSubScriptions.splice(index, 1); + } + } + } + + const promisePlus = (promise, timeoutMilliseconds, timeoutMessage) => { + return new Promise((resolve, reject) => { + let promiseActive = true; + const timeout = setTimeout(() => { + if (!promiseActive) { + return; + } + promiseActive = false; + const message = timeoutMessage; + reject(message); + }, timeoutMilliseconds); + promise() + .then((result) => { + if (!promiseActive) { + return; + } + promiseActive = false; + clearTimeout(timeout); + resolve(result); + }) + .catch((error) => { + if (!promiseActive) { + return; + } + promiseActive = false; + clearTimeout(timeout); + reject(error); + }); + }); + }; + + const isDesktop = () => { + return typeof window === "undefined" ? + true : + window.glue42gd || window.iodesktop; + }; + const browserGlobal = () => { + return typeof window === "undefined" ? null : + window.glue42core || window.iobrowser; + }; + + class InteropTransport { + agm; + registry; + defaultTransportTimeout = 120000; + coreEventMethodInitiated = false; + corePlatformSubPromise; + constructor(agm, registry) { + this.agm = agm; + this.registry = registry; + } + async initiate(actualWindowId) { + if (isDesktop()) { + await Promise.all(Object.values(OUTGOING_METHODS).map((method) => { + return this.verifyMethodLive(method.name); + })); + await Promise.all(Object.keys(INCOMING_METHODS).map((method) => { + return this.registerMethod(method); + })); + return; + } + const systemId = browserGlobal().communicationId; + await Promise.all([ + this.verifyMethodLive(webPlatformMethodName, systemId), + this.verifyMethodLive(webPlatformWspStreamName, systemId) + ]); + await this.transmitControl("frameHello", { windowId: actualWindowId }); + } + coreSubscriptionReady(eventCallback) { + if (!this.coreEventMethodInitiated) { + this.subscribePlatform(eventCallback); + } + return this.corePlatformSubPromise; + } + subscribePlatform(eventCallback) { + this.coreEventMethodInitiated = true; + const systemId = browserGlobal().communicationId; + this.corePlatformSubPromise = this.agm.subscribe(webPlatformWspStreamName, systemId ? { target: { instance: systemId } } : undefined); + this.corePlatformSubPromise + .then((sub) => { + sub.onData((data) => eventCallback(data.data)); + }); + } + async subscribe(streamName, streamBranch, streamType) { + const subscriptionArgs = { + branch: streamBranch, + type: streamType + }; + let subscription; + try { + subscription = await this.agm.subscribe(streamName, { arguments: subscriptionArgs }); + } + catch (error) { + const message = `Internal subscription error! Error details: stream - ${streamName}, branch: ${streamBranch}. Internal message: ${error.message}`; + throw new Error(message); + } + return subscription; + } + async transmitControl(operation, operationArguments) { + const invocationArguments = isDesktop() ? { operation, operationArguments } : { operation, domain: "workspaces", data: operationArguments }; + const methodName = isDesktop() ? OUTGOING_METHODS.control.name : webPlatformMethodName; + const platformTarget = isDesktop() ? undefined : browserGlobal().communicationId; + let invocationResult; + const baseErrorMessage = `Internal Workspaces Communication Error. Attempted operation: ${JSON.stringify(invocationArguments)}. `; + try { + invocationResult = await this.agm.invoke(methodName, invocationArguments, platformTarget ? { instance: platformTarget } : "best", { methodResponseTimeoutMs: this.defaultTransportTimeout }); + if (!invocationResult) { + throw new Error("Received unsupported result from GD - empty result"); + } + if (!Array.isArray(invocationResult.all_return_values) || invocationResult.all_return_values.length === 0) { + throw new Error("Received unsupported result from GD - empty values collection"); + } + } + catch (error) { + if (error && error.all_errors && error.all_errors.length) { + const invocationErrorMessage = error.all_errors[0].message; + throw new Error(`${baseErrorMessage} -> Inner message: ${invocationErrorMessage}`); + } + throw new Error(`${baseErrorMessage} -> Inner message: ${error.message}`); + } + return invocationResult.all_return_values[0].returned; + } + onInternalMethodInvoked(key, callback) { + return this.registry.add(key, callback); + } + verifyMethodLive(name, systemId) { + return promisePlus(() => { + return new Promise((resolve) => { + const hasMethod = this.agm.methods().some((method) => { + const nameMatch = method.name === name; + const serverMatch = systemId ? + method.getServers().some((server) => server.instance === systemId) : + true; + return nameMatch && serverMatch; + }); + if (hasMethod) { + resolve(); + return; + } + const unSub = this.agm.serverMethodAdded((data) => { + const method = data.method; + const server = data.server; + const serverMatch = systemId ? + server.instance === systemId : + true; + if (method.name === name && serverMatch) { + unSub(); + resolve(); + } + }); + }); + }, 15000, "Timeout waiting for the Workspaces communication channels"); + } + registerMethod(key) { + const method = INCOMING_METHODS[key]; + return this.agm.register(method.name, (args, caller) => { + this.registry.execute(key, args, caller); + }); + } + } + + const privateData$4 = new WeakMap(); + class ParentBuilder { + constructor(definition, base) { + const children = base.wrapChildren(definition.children); + delete definition.children; + privateData$4.set(this, { base, children, definition }); + } + get type() { + return privateData$4.get(this).definition.type; + } + addColumn(definition) { + const base = privateData$4.get(this).base; + return base.add("column", privateData$4.get(this).children, definition); + } + addRow(definition) { + const base = privateData$4.get(this).base; + return base.add("row", privateData$4.get(this).children, definition); + } + addGroup(definition) { + const base = privateData$4.get(this).base; + return base.add("group", privateData$4.get(this).children, definition); + } + addWindow(definition) { + const base = privateData$4.get(this).base; + base.addWindow(privateData$4.get(this).children, definition); + return this; + } + serialize() { + const definition = privateData$4.get(this).definition; + definition.children = privateData$4.get(this).base.serializeChildren(privateData$4.get(this).children); + return definition; + } + } + + class BaseBuilder { + getBuilder; + constructor(getBuilder) { + this.getBuilder = getBuilder; + } + wrapChildren(children) { + return children.map((child) => { + if (child.type === "window") { + return child; + } + return this.getBuilder({ type: child.type, definition: child }); + }); + } + add(type, children, definition) { + const validatedDefinition = parentDefinitionDecoder.runWithException(definition); + const childBuilder = this.getBuilder({ type, definition: validatedDefinition }); + children.push(childBuilder); + return childBuilder; + } + addWindow(children, definition) { + const validatedDefinition = swimlaneWindowDefinitionDecoder.runWithException(definition); + validatedDefinition.type = "window"; + children.push(validatedDefinition); + } + serializeChildren(children) { + return children.map((child) => { + if (child instanceof ParentBuilder) { + return child.serialize(); + } + else { + return child; + } + }); + } + } + + const privateData$3 = new WeakMap(); + class WorkspaceBuilder { + constructor(definition, base, controller) { + const children = base.wrapChildren(definition.children); + delete definition.children; + privateData$3.set(this, { base, children, definition, controller }); + } + addColumn(definition) { + const children = privateData$3.get(this).children; + const areAllColumns = children.every((child) => child instanceof ParentBuilder && child.type === "column"); + if (!areAllColumns) { + throw new Error("Cannot add a column to this workspace, because there are already children of another type"); + } + const base = privateData$3.get(this).base; + return base.add("column", children, definition); + } + addRow(definition) { + const children = privateData$3.get(this).children; + const areAllRows = children.every((child) => child instanceof ParentBuilder && child.type === "row"); + if (!areAllRows) { + throw new Error("Cannot add a row to this workspace, because there are already children of another type"); + } + const base = privateData$3.get(this).base; + return base.add("row", children, definition); + } + addGroup(definition) { + const children = privateData$3.get(this).children; + if (children.length !== 0) { + throw new Error("Cannot add a group to this workspace, because there are already defined children."); + } + const base = privateData$3.get(this).base; + return base.add("group", children, definition); + } + addWindow(definition) { + const children = privateData$3.get(this).children; + if (children.length !== 0) { + throw new Error("Cannot add a window to this workspace, because there are already defined children."); + } + const base = privateData$3.get(this).base; + base.addWindow(children, definition); + return this; + } + getChildAt(index) { + nonNegativeNumberDecoder.runWithException(index); + const data = privateData$3.get(this).children; + return data[index]; + } + async create(config) { + const saveConfig = workspaceBuilderCreateConfigDecoder.runWithException(config); + const definition = privateData$3.get(this).definition; + definition.children = privateData$3.get(this).base.serializeChildren(privateData$3.get(this).children); + const controller = privateData$3.get(this).controller; + return controller.createWorkspace(definition, saveConfig); + } + } + + const privateData$2 = new WeakMap(); + const getBase$2 = (model) => { + return privateData$2.get(model).base; + }; + class Row { + constructor(base) { + privateData$2.set(this, { base }); + } + get type() { + return "row"; + } + get id() { + return getBase$2(this).getId(this); + } + get frameId() { + return getBase$2(this).getFrameId(this); + } + get workspaceId() { + return getBase$2(this).getWorkspaceId(this); + } + get positionIndex() { + return getBase$2(this).getPositionIndex(this); + } + get children() { + return getBase$2(this).getAllChildren(this); + } + get parent() { + return getBase$2(this).getMyParent(this); + } + get frame() { + return getBase$2(this).getMyFrame(this); + } + get workspace() { + return getBase$2(this).getMyWorkspace(this); + } + get allowDrop() { + return getBase$2(this).getAllowDrop(this); + } + get allowSplitters() { + return getBase$2(this).getAllowSplitters(this); + } + get minWidth() { + return getBase$2(this).getMinWidth(this); + } + get minHeight() { + return getBase$2(this).getMinHeight(this); + } + get maxWidth() { + return getBase$2(this).getMaxWidth(this); + } + get maxHeight() { + return getBase$2(this).getMaxHeight(this); + } + get width() { + return getBase$2(this).getWidthInPx(this); + } + get height() { + return getBase$2(this).getHeightInPx(this); + } + get isPinned() { + return getBase$2(this).getIsPinned(this); + } + get isMaximized() { + return getBase$2(this).getIsMaximized(this); + } + get maximizationBoundary() { + return getBase$2(this).getMaximizationBoundary(this); + } + addWindow(definition) { + return getBase$2(this).addWindow(this, definition, "row"); + } + async addGroup(definition) { + if (definition?.type && definition.type !== "group") { + throw new Error(`Expected a group definition, but received ${definition.type}`); + } + return getBase$2(this).addParent(this, "group", "row", definition); + } + async addColumn(definition) { + if (definition?.type && definition.type !== "column") { + throw new Error(`Expected a column definition, but received ${definition.type}`); + } + return getBase$2(this).addParent(this, "column", "row", definition); + } + async addRow() { + throw new Error("Adding rows as row children is not supported"); + } + removeChild(predicate) { + return getBase$2(this).removeChild(this, predicate); + } + maximize() { + return getBase$2(this).maximize(this); + } + restore() { + return getBase$2(this).restore(this); + } + close() { + return getBase$2(this).close(this); + } + lock(config) { + let lockConfigResult = undefined; + if (typeof config === "function") { + const currentLockConfig = { + allowDrop: this.allowDrop, + allowSplitters: this.allowSplitters + }; + lockConfigResult = config(currentLockConfig); + } + else { + lockConfigResult = config; + } + const verifiedConfig = lockConfigResult === undefined ? undefined : rowLockConfigDecoder.runWithException(lockConfigResult); + return getBase$2(this).lockContainer(this, verifiedConfig); + } + async setHeight(height) { + nonNegativeNumberDecoder.runWithException(height); + return getBase$2(this).setHeight(this, height); + } + async onLockConfigurationChanged(callback) { + checkThrowCallback(callback); + const wrappedCallback = async () => { + await this.workspace.refreshReference(); + callback({ + allowDrop: this.allowDrop, + allowSplitters: this.allowSplitters + }); + }; + const config = { + callback: wrappedCallback, + action: "lock-configuration-changed", + eventType: "container", + scope: "container" + }; + const unsubscribe = await getBase$2(this).processLocalSubscription(this, config); + return unsubscribe; + } + async setMaximizationBoundary(config) { + const validatedConfig = setMaximizationBoundaryAPIConfigDecoder.runWithException(config); + return getBase$2(this).setMaximizationBoundary(this, validatedConfig); + } + } + + const privateData$1 = new WeakMap(); + const getBase$1 = (model) => { + return privateData$1.get(model).base; + }; + class Column { + constructor(base) { + privateData$1.set(this, { base }); + } + get type() { + return "column"; + } + get id() { + return getBase$1(this).getId(this); + } + get frameId() { + return getBase$1(this).getFrameId(this); + } + get workspaceId() { + return getBase$1(this).getWorkspaceId(this); + } + get positionIndex() { + return getBase$1(this).getPositionIndex(this); + } + get children() { + return getBase$1(this).getAllChildren(this); + } + get parent() { + return getBase$1(this).getMyParent(this); + } + get frame() { + return getBase$1(this).getMyFrame(this); + } + get workspace() { + return getBase$1(this).getMyWorkspace(this); + } + get allowDrop() { + return getBase$1(this).getAllowDrop(this); + } + get allowSplitters() { + return getBase$1(this).getAllowSplitters(this); + } + get minWidth() { + return getBase$1(this).getMinWidth(this); + } + get minHeight() { + return getBase$1(this).getMinHeight(this); + } + get maxWidth() { + return getBase$1(this).getMaxWidth(this); + } + get maxHeight() { + return getBase$1(this).getMaxHeight(this); + } + get width() { + return getBase$1(this).getWidthInPx(this); + } + get height() { + return getBase$1(this).getHeightInPx(this); + } + get isPinned() { + return getBase$1(this).getIsPinned(this); + } + get isMaximized() { + return getBase$1(this).getIsMaximized(this); + } + get maximizationBoundary() { + return getBase$1(this).getMaximizationBoundary(this); + } + addWindow(definition) { + return getBase$1(this).addWindow(this, definition, "column"); + } + async addGroup(definition) { + if (definition?.type && definition.type !== "group") { + throw new Error(`Expected a group definition, but received ${definition.type}`); + } + return getBase$1(this).addParent(this, "group", "column", definition); + } + async addColumn() { + throw new Error("Adding columns as column children is not supported"); + } + async addRow(definition) { + if (definition?.type && definition.type !== "row") { + throw new Error(`Expected a row definition, but received ${definition.type}`); + } + return getBase$1(this).addParent(this, "row", "column", definition); + } + removeChild(predicate) { + return getBase$1(this).removeChild(this, predicate); + } + maximize() { + return getBase$1(this).maximize(this); + } + restore() { + return getBase$1(this).restore(this); + } + close() { + return getBase$1(this).close(this); + } + lock(config) { + let lockConfigResult = undefined; + if (typeof config === "function") { + const currentLockConfig = { + allowDrop: this.allowDrop, + allowSplitters: this.allowSplitters + }; + lockConfigResult = config(currentLockConfig); + } + else { + lockConfigResult = config; + } + const verifiedConfig = lockConfigResult === undefined ? undefined : columnLockConfigDecoder.runWithException(lockConfigResult); + return getBase$1(this).lockContainer(this, verifiedConfig); + } + async setWidth(width) { + nonNegativeNumberDecoder.runWithException(width); + return getBase$1(this).setWidth(this, width); + } + async onLockConfigurationChanged(callback) { + checkThrowCallback(callback); + const wrappedCallback = async () => { + await this.workspace.refreshReference(); + callback({ + allowDrop: this.allowDrop, + allowSplitters: this.allowSplitters + }); + }; + const config = { + callback: wrappedCallback, + action: "lock-configuration-changed", + eventType: "container", + scope: "container" + }; + const unsubscribe = await getBase$1(this).processLocalSubscription(this, config); + return unsubscribe; + } + async setMaximizationBoundary(config) { + const validatedConfig = setMaximizationBoundaryAPIConfigDecoder.runWithException(config); + return getBase$1(this).setMaximizationBoundary(this, validatedConfig); + } + } + + const privateData = new WeakMap(); + const getBase = (model) => { + return privateData.get(model).base; + }; + class Group { + constructor(base) { + privateData.set(this, { base }); + } + get type() { + return "group"; + } + get id() { + return getBase(this).getId(this); + } + get frameId() { + return getBase(this).getFrameId(this); + } + get workspaceId() { + return getBase(this).getWorkspaceId(this); + } + get positionIndex() { + return getBase(this).getPositionIndex(this); + } + get children() { + return getBase(this).getAllChildren(this); + } + get parent() { + return getBase(this).getMyParent(this); + } + get frame() { + return getBase(this).getMyFrame(this); + } + get workspace() { + return getBase(this).getMyWorkspace(this); + } + get allowExtract() { + return getBase(this).getAllowExtract(this); + } + get allowReorder() { + return getBase(this).getAllowReorder(this); + } + get allowDropLeft() { + return getBase(this).getAllowDropLeft(this); + } + get allowDropRight() { + return getBase(this).getAllowDropRight(this); + } + get allowDropTop() { + return getBase(this).getAllowDropTop(this); + } + get allowDropBottom() { + return getBase(this).getAllowDropBottom(this); + } + get allowDropHeader() { + return getBase(this).getAllowDropHeader(this); + } + get allowDrop() { + return getBase(this).getAllowDrop(this); + } + get showMaximizeButton() { + return getBase(this).getShowMaximizeButton(this); + } + get showEjectButton() { + return getBase(this).getShowEjectButton(this); + } + get showAddWindowButton() { + return getBase(this).getShowAddWindowButton(this); + } + get minWidth() { + return getBase(this).getMinWidth(this); + } + get minHeight() { + return getBase(this).getMinHeight(this); + } + get maxWidth() { + return getBase(this).getMaxWidth(this); + } + get maxHeight() { + return getBase(this).getMaxHeight(this); + } + get width() { + return getBase(this).getWidthInPx(this); + } + get height() { + return getBase(this).getHeightInPx(this); + } + get isMaximized() { + return getBase(this).getIsMaximized(this); + } + addWindow(definition) { + return getBase(this).addWindow(this, definition, "group"); + } + async addGroup() { + throw new Error("Adding groups as group child is not supported"); + } + async addColumn() { + throw new Error("Adding columns as group child is not supported"); + } + async addRow() { + throw new Error("Adding rows as group child is not supported"); + } + removeChild(predicate) { + return getBase(this).removeChild(this, predicate); + } + maximize() { + return getBase(this).maximize(this); + } + restore() { + return getBase(this).restore(this); + } + close() { + return getBase(this).close(this); + } + lock(config) { + let lockConfigResult = undefined; + if (typeof config === "function") { + const currentLockConfig = { + allowDrop: this.allowDrop, + allowDropHeader: this.allowDropHeader, + allowDropLeft: this.allowDropLeft, + allowDropRight: this.allowDropRight, + allowDropTop: this.allowDropTop, + allowDropBottom: this.allowDropBottom, + allowExtract: this.allowExtract, + allowReorder: this.allowReorder, + showAddWindowButton: this.showAddWindowButton, + showEjectButton: this.showEjectButton, + showMaximizeButton: this.showMaximizeButton + }; + lockConfigResult = config(currentLockConfig); + } + else { + lockConfigResult = config; + } + const verifiedConfig = lockConfigResult === undefined ? undefined : groupLockConfigDecoder.runWithException(lockConfigResult); + return getBase(this).lockContainer(this, verifiedConfig); + } + async setSize(config) { + const verifiedConfig = elementResizeConfigDecoder.runWithException(config); + if (!verifiedConfig.width && !verifiedConfig.height) { + throw new Error("Expected either width or height to be passed."); + } + return getBase(this).setSize(this, config.width, config.height); + } + async bundleToRow() { + await getBase(this).bundleTo(this, "row"); + await this.workspace.refreshReference(); + } + async bundleToColumn() { + await getBase(this).bundleTo(this, "column"); + await this.workspace.refreshReference(); + } + async onLockConfigurationChanged(callback) { + checkThrowCallback(callback); + const wrappedCallback = async () => { + await this.workspace.refreshReference(); + callback({ + allowDrop: this.allowDrop, + allowDropHeader: this.allowDropHeader, + allowDropLeft: this.allowDropLeft, + allowDropTop: this.allowDropTop, + allowDropRight: this.allowDropRight, + allowDropBottom: this.allowDropBottom, + allowExtract: this.allowExtract, + allowReorder: this.allowReorder, + showAddWindowButton: this.showAddWindowButton, + showEjectButton: this.showEjectButton, + showMaximizeButton: this.showMaximizeButton + }); + }; + const config = { + callback: wrappedCallback, + action: "lock-configuration-changed", + eventType: "container", + scope: "container" + }; + const unsubscribe = await getBase(this).processLocalSubscription(this, config); + return unsubscribe; + } + } + + const DEFAULT_WINDOW_DRAG_MODE = "keepInside"; + + const data$3 = new WeakMap(); + const getData$3 = (model) => { + return data$3.get(model).manager.getWorkspaceData(model); + }; + const getDataManager = (model) => { + return data$3.get(model).manager; + }; + class Workspace { + constructor(dataManager) { + data$3.set(this, { manager: dataManager }); + } + get id() { + return getData$3(this).id; + } + get frameId() { + return getData$3(this).config.frameId; + } + get positionIndex() { + return getData$3(this).config.positionIndex; + } + get title() { + return getData$3(this).config.title; + } + get layoutName() { + return getData$3(this).config.layoutName; + } + get isHibernated() { + return getData$3(this).config.isHibernated; + } + get isSelected() { + return getData$3(this).config.isSelected; + } + get children() { + return getData$3(this).children; + } + get frame() { + return getData$3(this).frame; + } + get allowSplitters() { + return getData$3(this).config.allowSplitters; + } + get allowSystemHibernation() { + return getData$3(this).config.allowSystemHibernation; + } + get allowDrop() { + return getData$3(this).config.allowDrop; + } + get allowDropLeft() { + return getData$3(this).config.allowDropLeft; + } + get allowDropTop() { + return getData$3(this).config.allowDropTop; + } + get allowDropRight() { + return getData$3(this).config.allowDropRight; + } + get allowDropBottom() { + return getData$3(this).config.allowDropBottom; + } + get allowExtract() { + return getData$3(this).config.allowExtract; + } + get allowWindowReorder() { + return getData$3(this).config.allowWindowReorder; + } + get showCloseButton() { + return getData$3(this).config.showCloseButton; + } + get showSaveButton() { + return getData$3(this).config.showSaveButton; + } + get allowWorkspaceTabReorder() { + return getData$3(this).config.allowWorkspaceTabReorder; + } + get allowWorkspaceTabExtract() { + return getData$3(this).config.allowWorkspaceTabExtract; + } + get minWidth() { + return getData$3(this).config.minWidth; + } + get minHeight() { + return getData$3(this).config.minHeight; + } + get maxWidth() { + return getData$3(this).config.maxWidth; + } + get maxHeight() { + return getData$3(this).config.maxHeight; + } + get width() { + return getData$3(this).config.widthInPx; + } + get height() { + return getData$3(this).config.heightInPx; + } + get showWindowCloseButtons() { + return getData$3(this).config.showWindowCloseButtons; + } + get showEjectButtons() { + return getData$3(this).config.showEjectButtons; + } + get showAddWindowButtons() { + return getData$3(this).config.showAddWindowButtons; + } + get isPinned() { + return getData$3(this).config.isPinned; + } + get windowDragMode() { + const desktopGlobal = isDesktop(); + if (!desktopGlobal) { + return DEFAULT_WINDOW_DRAG_MODE; + } + return getData$3(this).config.windowDragMode; + } + get loadingStrategy() { + if (!isDesktop()) { + console.warn("The workspace.loadingStrategy property is not supported in IO Connect Browser"); + } + return getData$3(this).config.loadingStrategy; + } + async setLoadingStrategy(strategy) { + if (!isDesktop()) { + throw new Error("Not supported in IO Connect Browser"); + } + const controller = getData$3(this).controller; + await controller.setLoadingStrategy(this.id, strategy); + await this.refreshReference(); + } + async removeChild(predicate) { + checkThrowCallback(predicate); + const child = this.children.find(predicate); + if (!child) { + return; + } + await child.close(); + await this.refreshReference(); + } + async remove(predicate) { + checkThrowCallback(predicate); + const controller = getData$3(this).controller; + const child = controller.iterateFindChild(this.children, predicate); + await child.close(); + await this.refreshReference(); + } + async focus() { + await getData$3(this).controller.focusItem(this.id); + await this.refreshReference(); + } + async close() { + const controller = getData$3(this).controller; + const workspaces = await getData$3(this).frame.workspaces(); + const platformFrameId = (await controller.getPlatformFrameId()).id; + const shouldCloseFrame = workspaces.length === 1 && + workspaces.every((wsp) => wsp.id === this.id) && + platformFrameId !== this.frame.id; + if (shouldCloseFrame) { + return this.frame.close(); + } + await controller.closeItem(this.id); + } + snapshot() { + return getData$3(this).controller.getSnapshot(this.id, "workspace"); + } + async saveLayout(name, config) { + nonEmptyStringDecoder.runWithException(name); + await getData$3(this).controller.saveLayout({ name, workspaceId: this.id, saveContext: config?.saveContext, metadata: config?.metadata, allowMultiple: config?.allowMultiple }); + } + async setTitle(title) { + nonEmptyStringDecoder.runWithException(title); + const controller = getData$3(this).controller; + await controller.setItemTitle(this.id, title); + await this.refreshReference(); + } + getContext() { + const controller = getData$3(this).controller; + return controller.getWorkspaceContext(this.id); + } + setContext(data) { + const controller = getData$3(this).controller; + return controller.setWorkspaceContext(this.id, data); + } + updateContext(data) { + const controller = getData$3(this).controller; + return controller.updateWorkspaceContext(this.id, data); + } + onContextUpdated(callback) { + const controller = getData$3(this).controller; + return controller.subscribeWorkspaceContextUpdated(this.id, callback); + } + async refreshReference() { + const newSnapshot = (await getData$3(this).controller.getSnapshot(this.id, "workspace")); + const currentChildrenFlat = getData$3(this).controller.flatChildren(getData$3(this).children); + const newChildren = getData$3(this).controller.refreshChildren({ + existingChildren: currentChildrenFlat, + workspace: this, + parent: this, + children: newSnapshot.children + }); + const currentFrame = this.frame; + let actualFrame; + if (currentFrame.id === newSnapshot.config.frameId) { + getDataManager(this).remapFrame(currentFrame, newSnapshot.frameSummary); + actualFrame = currentFrame; + } + else { + const frameCreateConfig = { + summary: newSnapshot.frameSummary + }; + const newFrame = getData$3(this).ioc.getModel("frame", frameCreateConfig); + actualFrame = newFrame; + } + getDataManager(this).remapWorkspace(this, { + config: newSnapshot.config, + children: newChildren, + frame: actualFrame + }); + } + async getIcon() { + const controller = getData$3(this).controller; + return controller.getWorkspaceIcon(this.id); + } + async setIcon(icon) { + const controller = getData$3(this).controller; + return controller.setWorkspaceIcon(this.id, icon); + } + getBox(predicate) { + checkThrowCallback(predicate); + const children = getData$3(this).children; + const controller = getData$3(this).controller; + return controller.iterateFindChild(children, (child) => child.type !== "window" && predicate(child)); + } + getAllBoxes(predicate) { + checkThrowCallback(predicate, true); + const children = getData$3(this).children; + const controller = getData$3(this).controller; + const allParents = controller.iterateFilterChildren(children, (child) => child.type !== "window"); + if (!predicate) { + return allParents; + } + return allParents.filter(predicate); + } + getRow(predicate) { + checkThrowCallback(predicate); + return this.getBox((parent) => parent.type === "row" && predicate(parent)); + } + getAllRows(predicate) { + checkThrowCallback(predicate, true); + if (predicate) { + return this.getAllBoxes((parent) => parent.type === "row" && predicate(parent)); + } + return this.getAllBoxes((parent) => parent.type === "row"); + } + getColumn(predicate) { + checkThrowCallback(predicate); + return this.getBox((parent) => parent.type === "column" && predicate(parent)); + } + getAllColumns(predicate) { + checkThrowCallback(predicate, true); + if (predicate) { + return this.getAllBoxes((parent) => parent.type === "column" && predicate(parent)); + } + return this.getAllBoxes((parent) => parent.type === "column"); + } + getGroup(predicate) { + checkThrowCallback(predicate); + return this.getBox((parent) => parent.type === "group" && predicate(parent)); + } + getAllGroups(predicate) { + checkThrowCallback(predicate, true); + if (predicate) { + return this.getAllBoxes((parent) => parent.type === "group" && predicate(parent)); + } + return this.getAllBoxes((parent) => parent.type === "group"); + } + getWindow(predicate) { + checkThrowCallback(predicate); + const children = getData$3(this).children; + const controller = getData$3(this).controller; + return controller.iterateFindChild(children, (child) => child.type === "window" && predicate(child)); + } + getAllWindows(predicate) { + checkThrowCallback(predicate, true); + const children = getData$3(this).children; + const controller = getData$3(this).controller; + const allWindows = controller.iterateFilterChildren(children, (child) => child.type === "window"); + if (!predicate) { + return allWindows; + } + return allWindows.filter(predicate); + } + addRow(definition) { + return getData$3(this).base.addParent(this, "row", "workspace", definition); + } + addColumn(definition) { + return getData$3(this).base.addParent(this, "column", "workspace", definition); + } + addGroup(definition) { + return getData$3(this).base.addParent(this, "group", "workspace", definition); + } + addWindow(definition) { + return getData$3(this).base.addWindow(this, definition, "workspace"); + } + async bundleToRow() { + await getData$3(this).controller.bundleWorkspaceTo("row", this.id); + await this.refreshReference(); + } + async bundleToColumn() { + await getData$3(this).controller.bundleWorkspaceTo("column", this.id); + await this.refreshReference(); + } + async hibernate() { + await getData$3(this).controller.hibernateWorkspace(this.id); + await this.refreshReference(); + } + async resume() { + await getData$3(this).controller.resumeWorkspace(this.id); + await this.refreshReference(); + } + async lock(config) { + let lockConfigResult = undefined; + if (typeof config === "function") { + const currentLockConfig = { + allowDrop: this.allowDrop, + allowDropLeft: this.allowDropLeft, + allowDropTop: this.allowDropTop, + allowDropRight: this.allowDropRight, + allowDropBottom: this.allowDropBottom, + allowSystemHibernation: this.allowSystemHibernation, + allowExtract: this.allowExtract, + allowWindowReorder: this.allowWindowReorder, + allowSplitters: this.allowSplitters, + showCloseButton: this.showCloseButton, + showSaveButton: this.showSaveButton, + allowWorkspaceTabReorder: this.allowWorkspaceTabReorder, + allowWorkspaceTabExtract: this.allowWorkspaceTabExtract, + showAddWindowButtons: this.showAddWindowButtons, + showEjectButtons: this.showEjectButtons, + showWindowCloseButtons: this.showWindowCloseButtons + }; + lockConfigResult = config(currentLockConfig); + } + else { + lockConfigResult = config; + } + const verifiedConfig = lockConfigResult === undefined ? undefined : workspaceLockConfigDecoder.runWithException(lockConfigResult); + await getData$3(this).controller.lockWorkspace(this.id, verifiedConfig); + await this.refreshReference(); + } + async pin(options) { + workspacePinOptionsDecoder.runWithException(options); + await getData$3(this).controller.pinWorkspace(this.id, options?.icon); + await this.refreshReference(); + } + async unpin() { + await getData$3(this).controller.unpinWorkspace(this.id); + await this.refreshReference(); + } + async showLoadingAnimation() { + if (!isDesktop()) { + throw new Error("Not supported in IO Connect Browser"); + } + await getData$3(this).controller.showWorkspaceLoadingAnimation(this.id); + } + async hideLoadingAnimation() { + if (!isDesktop()) { + throw new Error("Not supported in IO Connect Browser"); + } + await getData$3(this).controller.hideWorkspaceLoadingAnimation(this.id); + } + async setWindowDragMode(mode) { + const desktopGlobal = isDesktop(); + if (!desktopGlobal) { + throw new Error("Not supported in IO Connect Browser"); + } + windowDragModeDecoder.runWithException(mode); + await getData$3(this).controller.setWindowDragMode(this.id, mode); + await this.refreshReference(); + } + async onClosed(callback) { + checkThrowCallback(callback); + const id = getData$3(this).id; + const wrappedCallback = async (payload) => { + callback({ frameId: payload.frameSummary.id, workspaceId: payload.workspaceSummary.id, frameBounds: payload.frameBounds }); + }; + const config = { + action: "closed", + eventType: "workspace", + scope: "workspace", + scopeId: id, + callback: wrappedCallback + }; + const unsubscribe = await getData$3(this).controller.processLocalSubscription(config, id); + return unsubscribe; + } + async onHibernated(callback) { + checkThrowCallback(callback); + const id = getData$3(this).id; + const wrappedCallback = async () => { + await this.refreshReference(); + callback(); + }; + const config = { + action: "hibernated", + eventType: "workspace", + scope: "workspace", + scopeId: id, + callback: wrappedCallback + }; + const unsubscribe = await getData$3(this).controller.processLocalSubscription(config, id); + return unsubscribe; + } + async onResumed(callback) { + checkThrowCallback(callback); + const id = getData$3(this).id; + const wrappedCallback = async () => { + await this.refreshReference(); + callback(); + }; + const config = { + action: "resumed", + eventType: "workspace", + scope: "workspace", + scopeId: id, + callback: wrappedCallback + }; + const unsubscribe = await getData$3(this).controller.processLocalSubscription(config, id); + return unsubscribe; + } + async onWindowAdded(callback) { + checkThrowCallback(callback); + const id = getData$3(this).id; + const wrappedCallback = async (payload) => { + await this.refreshReference(); + const windowParent = this.getBox((parent) => parent.id === payload.windowSummary.parentId); + const foundWindow = windowParent.children.find((child) => { + return child.type === "window" && child.elementId === payload.windowSummary.itemId; + }); + callback(foundWindow); + }; + const config = { + action: "added", + eventType: "window", + scope: "workspace", + scopeId: id, + callback: wrappedCallback + }; + const unsubscribe = await getData$3(this).controller.processLocalSubscription(config, id); + return unsubscribe; + } + async onWindowRemoved(callback) { + checkThrowCallback(callback); + const id = getData$3(this).id; + const wrappedCallback = async (payload) => { + await this.refreshReference(); + const { windowId, workspaceId, frameId } = payload.windowSummary.config; + callback({ windowId, workspaceId, frameId }); + }; + const config = { + action: "removed", + eventType: "window", + scope: "workspace", + scopeId: id, + callback: wrappedCallback + }; + const unsubscribe = await getData$3(this).controller.processLocalSubscription(config, id); + return unsubscribe; + } + async onWindowLoaded(callback) { + checkThrowCallback(callback); + const id = getData$3(this).id; + const wrappedCallback = async (payload) => { + await this.refreshReference(); + const foundWindow = this.getWindow((win) => { + return win.id && win.id === payload.windowSummary.config.windowId; + }); + callback(foundWindow); + }; + const config = { + action: "loaded", + eventType: "window", + scope: "workspace", + scopeId: id, + callback: wrappedCallback + }; + const unsubscribe = await getData$3(this).controller.processLocalSubscription(config, id); + return unsubscribe; + } + async onWindowMaximized(callback) { + checkThrowCallback(callback); + const id = getData$3(this).id; + const wrappedCallback = async (payload) => { + await this.refreshReference(); + const windowParent = this.getBox((parent) => parent.id === payload.windowSummary.parentId); + const foundWindow = windowParent.children.find((child) => { + return child.type === "window" && child.elementId === payload.windowSummary.itemId; + }); + callback(foundWindow); + }; + const config = { + action: "maximized", + eventType: "window", + scope: "workspace", + scopeId: id, + callback: wrappedCallback + }; + const unsubscribe = await getData$3(this).controller.processLocalSubscription(config, id); + return unsubscribe; + } + async onWindowRestored(callback) { + checkThrowCallback(callback); + const id = getData$3(this).id; + const wrappedCallback = async (payload) => { + await this.refreshReference(); + const windowParent = this.getBox((parent) => parent.id === payload.windowSummary.parentId); + const foundWindow = windowParent.children.find((child) => { + return child.type === "window" && child.elementId === payload.windowSummary.itemId; + }); + callback(foundWindow); + }; + const config = { + action: "restored", + eventType: "window", + scope: "workspace", + scopeId: id, + callback: wrappedCallback + }; + const unsubscribe = await getData$3(this).controller.processLocalSubscription(config, id); + return unsubscribe; + } + async onWindowSelected(callback) { + checkThrowCallback(callback); + const id = getData$3(this).id; + const wrappedCallback = async (payload) => { + await this.refreshReference(); + const windowParent = this.getBox((parent) => parent.id === payload.windowSummary.parentId); + const foundWindow = windowParent.children.find((child) => { + return child.type === "window" && child.elementId === payload.windowSummary.itemId; + }); + callback(foundWindow); + }; + const config = { + action: "selected", + eventType: "window", + scope: "workspace", + scopeId: id, + callback: wrappedCallback + }; + const unsubscribe = await getData$3(this).controller.processLocalSubscription(config, id); + return unsubscribe; + } + async onLockConfigurationChanged(callback) { + checkThrowCallback(callback); + const id = getData$3(this).id; + const wrappedCallback = async () => { + await this.refreshReference(); + callback({ + allowDrop: this.allowDrop, + allowDropLeft: this.allowDropLeft, + allowDropTop: this.allowDropTop, + allowDropRight: this.allowDropRight, + allowDropBottom: this.allowDropBottom, + allowSystemHibernation: this.allowSystemHibernation, + allowExtract: this.allowExtract, + allowSplitters: this.allowSplitters, + allowWindowReorder: this.allowWindowReorder, + allowWorkspaceTabExtract: this.allowWorkspaceTabExtract, + allowWorkspaceTabReorder: this.allowWorkspaceTabReorder, + showAddWindowButtons: this.showAddWindowButtons, + showCloseButton: this.showCloseButton, + showEjectButtons: this.showEjectButtons, + showSaveButton: this.showSaveButton, + showWindowCloseButtons: this.showWindowCloseButtons + }); + }; + const config = { + action: "lock-configuration-changed", + eventType: "workspace", + scope: "workspace", + scopeId: id, + callback: wrappedCallback + }; + const unsubscribe = await getData$3(this).controller.processLocalSubscription(config, id); + return unsubscribe; + } + } + + const data$2 = new WeakMap(); + const getData$2 = (model) => { + return data$2.get(model).manager.getWindowData(model); + }; + class Window { + constructor(dataManager) { + data$2.set(this, { manager: dataManager }); + } + get id() { + return getData$2(this).config.windowId; + } + get elementId() { + return getData$2(this).id; + } + get type() { + return "window"; + } + get frameId() { + return getData$2(this).frame.id; + } + get workspaceId() { + return getData$2(this).workspace.id; + } + get positionIndex() { + return getData$2(this).config.positionIndex; + } + get isMaximized() { + return getData$2(this).config.isMaximized; + } + get isLoaded() { + return getData$2(this).controller.checkIsWindowLoaded(this.id); + } + get isSelected() { + return getData$2(this).config.isSelected; + } + get focused() { + return this.getGdWindow().isFocused; + } + get title() { + return getData$2(this).config.title; + } + get allowExtract() { + return getData$2(this).config.allowExtract; + } + get allowReorder() { + return getData$2(this).config.allowReorder; + } + get showCloseButton() { + return getData$2(this).config.showCloseButton; + } + get width() { + return getData$2(this).config.widthInPx; + } + get height() { + return getData$2(this).config.heightInPx; + } + get minWidth() { + return getData$2(this).config.minWidth; + } + get minHeight() { + return getData$2(this).config.minHeight; + } + get maxWidth() { + return getData$2(this).config.maxWidth; + } + get maxHeight() { + return getData$2(this).config.maxHeight; + } + get workspace() { + return getData$2(this).workspace; + } + get frame() { + return getData$2(this).frame; + } + get parent() { + return getData$2(this).parent; + } + get appName() { + return getData$2(this).config.appName; + } + async forceLoad() { + if (this.isLoaded) { + return; + } + const controller = getData$2(this).controller; + const itemId = getData$2(this).id; + const windowId = await controller.forceLoadWindow(itemId); + getData$2(this).config.windowId = windowId; + await this.workspace.refreshReference(); + } + async focus() { + const id = getData$2(this).id; + const controller = getData$2(this).controller; + await controller.focusItem(id); + await this.workspace.refreshReference(); + } + async close() { + const id = getData$2(this).id; + const controller = getData$2(this).controller; + await controller.closeItem(id); + await getData$2(this) + .parent + .removeChild((child) => child.id === id); + await this.workspace.refreshReference(); + } + async setTitle(title) { + nonEmptyStringDecoder.runWithException(title); + const itemId = getData$2(this).id; + const controller = getData$2(this).controller; + await controller.setItemTitle(itemId, title); + await this.workspace.refreshReference(); + } + async maximize() { + const id = getData$2(this).id; + const controller = getData$2(this).controller; + await controller.maximizeItem(id); + await this.workspace.refreshReference(); + } + async restore() { + const id = getData$2(this).id; + const controller = getData$2(this).controller; + await controller.restoreItem(id); + await this.workspace.refreshReference(); + } + async eject() { + if (!this.isLoaded) { + throw new Error("Cannot eject this window, because it is not loaded yet"); + } + const itemId = getData$2(this).id; + const newWindowId = await getData$2(this).controller.ejectWindow(itemId); + getData$2(this).config.windowId = newWindowId; + await this.workspace.refreshReference(); + return this.getGdWindow(); + } + getGdWindow() { + if (!this.isLoaded) { + throw new Error("Cannot fetch this GD window, because the window is not yet loaded"); + } + const myId = getData$2(this).config.windowId; + const controller = getData$2(this).controller; + return controller.getGDWindow(myId); + } + async moveTo(parent) { + if (!(parent instanceof Row || parent instanceof Column || parent instanceof Group)) { + throw new Error("Cannot add to the provided parent, because the provided parent is not an instance of Row, Column or Group"); + } + const myId = getData$2(this).id; + const controller = getData$2(this).controller; + const foundParent = await controller.getParent((p) => p.id === parent.id); + if (!foundParent) { + throw new Error("Cannot move the window to the selected parent, because this parent does not exist."); + } + await controller.moveWindowTo(myId, parent.id); + await this.workspace.refreshReference(); + } + async lock(config) { + let lockConfigResult = undefined; + if (typeof config === "function") { + const currentLockConfig = { + allowExtract: this.allowExtract, + allowReorder: this.allowReorder, + showCloseButton: this.showCloseButton + }; + lockConfigResult = config(currentLockConfig); + } + else { + lockConfigResult = config; + } + const verifiedConfig = lockConfigResult === undefined ? undefined : windowLockConfigDecoder.runWithException(lockConfigResult); + const windowPlacementId = getData$2(this).id; + await getData$2(this).controller.lockWindow(windowPlacementId, verifiedConfig); + await this.workspace.refreshReference(); + } + async setSize(config) { + const verifiedConfig = elementResizeConfigDecoder.runWithException(config); + if (!verifiedConfig.width && !verifiedConfig.height) { + throw new Error("Expected either width or height to be passed."); + } + const myId = getData$2(this).id; + const controller = getData$2(this).controller; + await controller.resizeItem(myId, { + height: verifiedConfig.height, + width: verifiedConfig.width, + relative: false + }); + await this.workspace.refreshReference(); + } + async onRemoved(callback) { + checkThrowCallback(callback); + const id = getData$2(this).id; + const wrappedCallback = async () => { + await this.workspace.refreshReference(); + callback(); + }; + const config = { + callback: wrappedCallback, + action: "removed", + eventType: "window", + scope: "window" + }; + const unsubscribe = await getData$2(this).controller.processLocalSubscription(config, id); + return unsubscribe; + } + async onLockConfigurationChanged(callback) { + checkThrowCallback(callback); + const id = getData$2(this).id; + const wrappedCallback = async () => { + await this.workspace.refreshReference(); + callback({ + allowExtract: this.allowExtract, + allowReorder: this.allowReorder, + showCloseButton: this.showCloseButton + }); + }; + const config = { + callback: wrappedCallback, + action: "lock-configuration-changed", + eventType: "window", + scope: "window" + }; + const unsubscribe = await getData$2(this).controller.processLocalSubscription(config, id); + return unsubscribe; + } + } + + const data$1 = new WeakMap(); + const getData$1 = (model) => { + return data$1.get(model).manager.getFrameData(model); + }; + class Frame { + constructor(dataManager) { + data$1.set(this, { manager: dataManager }); + } + async registerShortcut(shortcut, callback) { + nonEmptyStringDecoder.runWithException(shortcut); + checkThrowCallback(callback); + const myId = getData$1(this).summary.id; + const unsubscribe = await getData$1(this).controller.registerShortcut(shortcut, myId, callback); + return unsubscribe; + } + get id() { + return getData$1(this).summary.id; + } + get isInitialized() { + return getData$1(this).summary.isInitialized; + } + getBounds() { + const myId = getData$1(this).summary.id; + return getData$1(this).controller.getFrameBounds(myId); + } + async resize(config) { + const validatedConfig = resizeConfigDecoder.runWithException(config); + const myId = getData$1(this).summary.id; + return getData$1(this).controller.resizeItem(myId, validatedConfig); + } + async move(config) { + const validatedConfig = moveConfigDecoder.runWithException(config); + const myId = getData$1(this).summary.id; + return getData$1(this).controller.moveFrame(myId, validatedConfig); + } + focus() { + const myId = getData$1(this).summary.id; + return getData$1(this).controller.focusItem(myId); + } + async state() { + if (!isDesktop()) { + throw new Error("State operations are not supported in IO Connect Browser"); + } + const myId = getData$1(this).summary.id; + return getData$1(this).controller.getFrameState(myId); + } + async minimize() { + if (!isDesktop()) { + throw new Error("State operations are not supported in IO Connect Browser"); + } + const myId = getData$1(this).summary.id; + return getData$1(this).controller.changeFrameState(myId, "minimized"); + } + async maximize() { + if (!isDesktop()) { + throw new Error("State operations are not supported in IO Connect Browser"); + } + const myId = getData$1(this).summary.id; + return getData$1(this).controller.changeFrameState(myId, "maximized"); + } + async restore() { + if (!isDesktop()) { + throw new Error("State operations are not supported in IO Connect Browser"); + } + const myId = getData$1(this).summary.id; + return getData$1(this).controller.changeFrameState(myId, "normal"); + } + close() { + const myId = getData$1(this).summary.id; + return getData$1(this).controller.closeItem(myId); + } + snapshot() { + const myId = getData$1(this).summary.id; + return getData$1(this).controller.getSnapshot(myId, "frame"); + } + async workspaces() { + const controller = getData$1(this).controller; + return controller.getWorkspacesByFrameId(this.id); + } + async getConstraints() { + const controller = getData$1(this).controller; + const myId = getData$1(this).summary.id; + return controller.getFrameConstraints(myId); + } + async restoreWorkspace(name, options) { + nonEmptyStringDecoder.runWithException(name); + const validatedOptions = restoreWorkspaceConfigDecoder.runWithException(options); + return getData$1(this).controller.restoreWorkspace(name, validatedOptions); + } + createWorkspace(definition, config) { + const validatedDefinition = workspaceDefinitionDecoder.runWithException(definition); + const validatedConfig = workspaceBuilderCreateConfigDecoder.runWithException(config); + return getData$1(this).controller.createWorkspace(validatedDefinition, validatedConfig); + } + async init(config) { + frameInitConfigDecoder.runWithException(config); + if (getData$1(this).summary.isInitialized) { + throw new Error("The frame has already been initialized"); + } + return getData$1(this).controller.initFrame(this.id, config); + } + async onClosed(callback) { + checkThrowCallback(callback); + const myId = getData$1(this).summary.id; + const wrappedCallback = (payload) => { + callback({ frameId: payload.frameSummary.id, frameBounds: payload.frameBounds }); + }; + const config = { + callback: wrappedCallback, + action: "closed", + eventType: "frame", + scope: "frame" + }; + const unsubscribe = await getData$1(this).controller.processLocalSubscription(config, myId); + return unsubscribe; + } + async onMaximized(callback) { + checkThrowCallback(callback); + const myId = getData$1(this).summary.id; + const wrappedCallback = () => { + callback(); + }; + const config = { + callback: wrappedCallback, + action: "maximized", + eventType: "frame", + scope: "frame" + }; + const unsubscribe = await getData$1(this).controller.processLocalSubscription(config, myId); + return unsubscribe; + } + async onMinimized(callback) { + checkThrowCallback(callback); + const myId = getData$1(this).summary.id; + const wrappedCallback = () => { + callback(); + }; + const config = { + callback: wrappedCallback, + action: "minimized", + eventType: "frame", + scope: "frame" + }; + const unsubscribe = await getData$1(this).controller.processLocalSubscription(config, myId); + return unsubscribe; + } + async onNormal(callback) { + checkThrowCallback(callback); + const myId = getData$1(this).summary.id; + const wrappedCallback = () => { + callback(); + }; + const config = { + callback: wrappedCallback, + action: "normal", + eventType: "frame", + scope: "frame" + }; + const unsubscribe = await getData$1(this).controller.processLocalSubscription(config, myId); + return unsubscribe; + } + async onWorkspaceOpened(callback) { + checkThrowCallback(callback); + const myId = getData$1(this).summary.id; + const wrappedCallback = async (payload) => { + const workspace = await getData$1(this).controller.transformStreamPayloadToWorkspace(payload); + callback(workspace); + }; + const config = { + callback: wrappedCallback, + action: "opened", + eventType: "workspace", + scope: "frame" + }; + const unsubscribe = await getData$1(this).controller.processLocalSubscription(config, myId); + return unsubscribe; + } + async onWorkspaceSelected(callback) { + checkThrowCallback(callback); + const myId = getData$1(this).summary.id; + const wrappedCallback = async (payload) => { + const workspace = await getData$1(this).controller.getWorkspaceById(payload.workspaceSummary.id); + callback(workspace); + }; + const config = { + callback: wrappedCallback, + action: "selected", + eventType: "workspace", + scope: "frame" + }; + const unsubscribe = await getData$1(this).controller.processLocalSubscription(config, myId); + return unsubscribe; + } + async onWorkspaceClosed(callback) { + checkThrowCallback(callback); + const myId = getData$1(this).summary.id; + const wrappedCallback = (payload) => { + callback({ frameId: payload.frameSummary.id, workspaceId: payload.workspaceSummary.id, frameBounds: payload.frameBounds }); + }; + const config = { + callback: wrappedCallback, + action: "closed", + eventType: "workspace", + scope: "frame" + }; + const unsubscribe = await getData$1(this).controller.processLocalSubscription(config, myId); + return unsubscribe; + } + async onWindowAdded(callback) { + checkThrowCallback(callback); + const myId = getData$1(this).summary.id; + const wrappedCallback = async (payload) => { + const foundParent = await getData$1(this).controller.getParent((parent) => parent.id === payload.windowSummary.parentId); + const foundWindow = foundParent.children.find((child) => child.type === "window" && child.positionIndex === payload.windowSummary.config.positionIndex); + callback(foundWindow); + }; + const config = { + callback: wrappedCallback, + action: "added", + eventType: "window", + scope: "frame" + }; + const unsubscribe = await getData$1(this).controller.processLocalSubscription(config, myId); + return unsubscribe; + } + async onWindowRemoved(callback) { + checkThrowCallback(callback); + const myId = getData$1(this).summary.id; + const wrappedCallback = (payload) => { + const { windowId, workspaceId, frameId } = payload.windowSummary.config; + callback({ windowId, workspaceId, frameId }); + }; + const config = { + callback: wrappedCallback, + action: "removed", + eventType: "window", + scope: "frame" + }; + const unsubscribe = await getData$1(this).controller.processLocalSubscription(config, myId); + return unsubscribe; + } + async onWindowLoaded(callback) { + checkThrowCallback(callback); + const myId = getData$1(this).summary.id; + const wrappedCallback = async (payload) => { + const foundParent = await getData$1(this).controller.getParent((parent) => { + return parent.id === payload.windowSummary.parentId; + }); + const foundWindow = foundParent.children.find((child) => child.type === "window" && child.positionIndex === payload.windowSummary.config.positionIndex); + callback(foundWindow); + }; + const config = { + callback: wrappedCallback, + action: "loaded", + eventType: "window", + scope: "frame" + }; + const unsubscribe = await getData$1(this).controller.processLocalSubscription(config, myId); + return unsubscribe; + } + async onInitializationRequested(callback) { + checkThrowCallback(callback); + if (!this.isInitialized) { + callback(getData$1(this).summary.initializationContext); + } + return () => { }; + } + async onFocusChanged(callback) { + checkThrowCallback(callback); + const myData = getData$1(this); + const { id } = myData.summary; + const wrappedCallback = (args) => { + callback({ isFocused: args.frameSummary.isFocused }); + }; + const config = { + callback: wrappedCallback, + action: "focus", + eventType: "frame", + scope: "frame" + }; + const unsubscribe = await myData.controller.processLocalSubscription(config, id); + return unsubscribe; + } + } + + class PrivateDataManager { + parentsData = new WeakMap(); + workspacesData = new WeakMap(); + windowsData = new WeakMap(); + framesData = new WeakMap(); + deleteData(model) { + if (model instanceof Window) { + this.windowsData.delete(model); + } + if (model instanceof Workspace) { + this.workspacesData.delete(model); + } + if (model instanceof Row || model instanceof Column || model instanceof Group) { + this.parentsData.delete(model); + } + if (model instanceof Frame) { + this.framesData.delete(model); + } + } + setWindowData(model, data) { + this.windowsData.set(model, data); + } + setWorkspaceData(model, data) { + this.workspacesData.set(model, data); + } + setParentData(model, data) { + this.parentsData.set(model, data); + } + setFrameData(model, data) { + this.framesData.set(model, data); + } + getWindowData(model) { + return this.windowsData.get(model); + } + getWorkspaceData(model) { + return this.workspacesData.get(model); + } + getParentData(model) { + return this.parentsData.get(model); + } + getFrameData(model) { + return this.framesData.get(model); + } + remapChild(model, newData) { + if (model instanceof Window) { + const data = this.windowsData.get(model); + data.parent = newData.parent || data.parent; + data.config = newData.config || data.config; + } + if (model instanceof Row || model instanceof Column || model instanceof Group) { + const data = this.parentsData.get(model); + data.parent = newData.parent || data.parent; + data.config = newData.config || data.config; + data.children = newData.children || data.children; + } + } + remapFrame(model, newData) { + const data = this.framesData.get(model); + data.summary = newData; + } + remapWorkspace(model, newData) { + const data = this.workspacesData.get(model); + data.frame = newData.frame || data.frame; + data.config = newData.config || data.config; + data.children = newData.children || data.children; + } + } + + const data = new WeakMap(); + const getData = (base, model) => { + const manager = data.get(base).manager; + if (model instanceof Workspace) { + return manager.getWorkspaceData(model); + } + return data.get(base).manager.getParentData(model); + }; + class Base { + frameId; + workspaceId; + positionIndex; + constructor(dataManager) { + data.set(this, { manager: dataManager }); + } + getId(model) { + return getData(this, model).id; + } + getPositionIndex(model) { + return getData(this, model).config.positionIndex; + } + getWorkspaceId(model) { + const privateData = getData(this, model); + return privateData.config.workspaceId || privateData.workspace.id; + } + getFrameId(model) { + return getData(this, model).frame.id; + } + getAllChildren(model, predicate) { + checkThrowCallback(predicate, true); + const children = getData(this, model).children; + if (typeof predicate === "undefined") { + return children; + } + return children.filter(predicate); + } + getMyParent(model) { + if (model instanceof Workspace) { + return model; + } + return getData(this, model).parent; + } + getMyFrame(model) { + return getData(this, model).frame; + } + getMyWorkspace(model) { + if (model instanceof Workspace) { + return model; + } + return getData(this, model).workspace; + } + async addWindow(model, definition, parentType) { + if (!definition.appName && !definition.windowId) { + throw new Error("The window definition should contain either an appName or a windowId"); + } + const validatedDefinition = swimlaneWindowDefinitionDecoder.runWithException(definition); + const controller = getData(this, model).controller; + const operationResult = await controller.add("window", getData(this, model).id, parentType, validatedDefinition); + if (model instanceof Workspace) { + await model.refreshReference(); + return model.getWindow(w => w.elementId === operationResult.itemId); + } + const myWorkspace = this.getMyWorkspace(model); + await myWorkspace.refreshReference(); + return myWorkspace.getWindow(w => w.elementId === operationResult.itemId); + } + async addParent(model, typeToAdd, parentType, definition) { + const parentDefinition = this.transformDefinition(typeToAdd, definition); + const controller = getData(this, model).controller; + const newParentId = (await controller.add("container", getData(this, model).id, parentType, parentDefinition)).itemId; + if (model instanceof Workspace) { + await model.refreshReference(); + return model.getBox((parent) => parent.id === newParentId); + } + const myWorkspace = this.getMyWorkspace(model); + await myWorkspace.refreshReference(); + return myWorkspace.getBox((parent) => parent.id === newParentId); + } + async removeChild(model, predicate) { + checkThrowCallback(predicate); + const child = this.getAllChildren(model).find(predicate); + if (!child) { + return; + } + await child.close(); + if (model instanceof Workspace) { + await model.refreshReference(); + return; + } + await this.getMyWorkspace(model).refreshReference(); + } + async maximize(model) { + const { controller, id } = getData(this, model); + await controller.maximizeItem(id); + await this.getMyWorkspace(model.parent).refreshReference(); + } + async restore(model) { + const { controller, id } = getData(this, model); + await controller.restoreItem(id); + await this.getMyWorkspace(model.parent).refreshReference(); + } + async close(model) { + const modelData = getData(this, model); + const controller = getData(this, model).controller; + await controller.closeItem(modelData.id); + await this.getMyWorkspace(modelData.parent).refreshReference(); + } + async lockContainer(model, config) { + const modelData = getData(this, model); + const controller = getData(this, model).controller; + await controller.lockContainer(modelData.id, model.type, config); + await this.getMyWorkspace(modelData.parent).refreshReference(); + } + getAllowDrop(model) { + return getData(this, model).config.allowDrop; + } + getAllowDropLeft(model) { + const privateData = getData(this, model); + if (privateData.type !== "group") { + throw new Error(`Property allowDropLeft is available only for groups and not on ${model.type} ${model.id}`); + } + return privateData.config.allowDropLeft; + } + getAllowDropRight(model) { + const privateData = getData(this, model); + if (privateData.type !== "group") { + throw new Error(`Property allowDropRight is available only for groups and not on ${model.type} ${model.id}`); + } + return privateData.config.allowDropRight; + } + getAllowDropTop(model) { + const privateData = getData(this, model); + if (privateData.type !== "group") { + throw new Error(`Property allowDropTop is available only for groups and not on ${model.type} ${model.id}`); + } + return privateData.config.allowDropTop; + } + getAllowDropBottom(model) { + const privateData = getData(this, model); + if (privateData.type !== "group") { + throw new Error(`Property allowDropBottom is available only for groups and not on ${model.type} ${model.id}`); + } + return privateData.config.allowDropBottom; + } + getAllowDropHeader(model) { + const privateData = getData(this, model); + if (privateData.type !== "group") { + throw new Error(`Property allowDropHeader is available only for groups and not on ${model.type} ${model.id}`); + } + return privateData.config.allowDropHeader; + } + getAllowSplitters(model) { + const privateData = getData(this, model); + if (privateData.type === "group") { + throw new Error(`Cannot get allow splitters from private data ${privateData.type}`); + } + return privateData.config.allowSplitters; + } + getAllowExtract(model) { + const privateData = getData(this, model); + if (privateData.type !== "group") { + throw new Error(`Cannot get allow extract from private data ${privateData.type} with config ${privateData.type !== "workspace" ? privateData.config.type : ""}`); + } + return privateData.config.allowExtract; + } + getAllowReorder(model) { + const privateData = getData(this, model); + if (privateData.type !== "group") { + throw new Error(`Cannot get allow extract from private data ${privateData.type} with config ${privateData.type !== "workspace" ? privateData.config.type : ""}`); + } + return privateData.config.allowReorder; + } + getShowMaximizeButton(model) { + const privateData = getData(this, model); + if (privateData.type !== "group") { + throw new Error(`Cannot get show maximize button from private data${privateData.type} with config ${privateData.type !== "workspace" ? privateData.config.type : ""}`); + } + return privateData.config.showMaximizeButton; + } + getShowEjectButton(model) { + const privateData = getData(this, model); + if (privateData.type !== "group") { + throw new Error(`Cannot get show eject button from private data${privateData.type} with config ${privateData.type !== "workspace" ? privateData.config.type : ""}`); + } + return privateData.config.showEjectButton; + } + getShowAddWindowButton(model) { + const privateData = getData(this, model); + if (privateData.type !== "group") { + throw new Error(`Cannot get add window button from private data${privateData.type} with config ${privateData.type !== "workspace" ? privateData.config.type : ""}`); + } + return privateData.config.showAddWindowButton; + } + getMinWidth(model) { + const privateData = getData(this, model); + return privateData.config.minWidth; + } + getMaxWidth(model) { + const privateData = getData(this, model); + return privateData.config.maxWidth; + } + getMinHeight(model) { + const privateData = getData(this, model); + return privateData.config.minHeight; + } + getMaxHeight(model) { + const privateData = getData(this, model); + return privateData.config.maxHeight; + } + getWidthInPx(model) { + const privateData = getData(this, model); + return privateData.config.widthInPx; + } + getHeightInPx(model) { + const privateData = getData(this, model); + return privateData.config.heightInPx; + } + getIsPinned(model) { + const privateData = getData(this, model); + return privateData.config.isPinned; + } + getIsMaximized(model) { + const privateData = getData(this, model); + return privateData.config.isMaximized; + } + getMaximizationBoundary(model) { + const privateData = getData(this, model); + return privateData.config.maximizationBoundary; + } + async setHeight(model, height) { + const modelData = getData(this, model); + const { controller, id } = modelData; + await controller.resizeItem(id, { + height + }); + await this.getMyWorkspace(modelData.parent).refreshReference(); + } + async setWidth(model, width) { + const modelData = getData(this, model); + const { controller, id } = modelData; + await controller.resizeItem(id, { + width + }); + await this.getMyWorkspace(modelData.parent).refreshReference(); + } + async setSize(model, width, height) { + const modelData = getData(this, model); + const { controller, id } = modelData; + await controller.resizeItem(id, { + width, + height + }); + await this.getMyWorkspace(modelData.parent).refreshReference(); + } + async setMaximizationBoundary(model, config) { + const modelData = getData(this, model); + const { controller, id } = modelData; + await controller.setMaximizationBoundary(id, config); + await this.getMyWorkspace(modelData.parent).refreshReference(); + } + async bundleTo(model, type) { + const modelData = getData(this, model); + const { controller, id } = modelData; + await controller.bundleItemTo(type, id); + } + async processLocalSubscription(model, subscriptionConfig) { + return getData(this, model).controller.processLocalSubscription(subscriptionConfig, this.getId(model)); + } + transformDefinition(type, definition) { + let parentDefinition; + if (typeof definition === "undefined") { + parentDefinition = { type, children: [] }; + } + else if (definition instanceof ParentBuilder) { + parentDefinition = definition.serialize(); + } + else { + if (typeof definition.type === "undefined") { + definition.type = type; + } + parentDefinition = strictParentDefinitionDecoder.runWithException(definition); + parentDefinition.children = parentDefinition.children || []; + } + return parentDefinition; + } + } + + class BaseController { + ioc; + windows; + contexts; + layouts; + constructor(ioc, windows, contexts, layouts) { + this.ioc = ioc; + this.windows = windows; + this.contexts = contexts; + this.layouts = layouts; + } + get bridge() { + return this.ioc.bridge; + } + get privateDataManager() { + return this.ioc.privateDataManager; + } + checkIsWindowLoaded(windowId) { + return (!!windowId) && this.windows.list().some((win) => win.id === windowId); + } + async createWorkspace(createConfig) { + const snapshot = await this.bridge.send(OPERATIONS.createWorkspace.name, createConfig); + const frameConfig = { + summary: snapshot.frameSummary + }; + const frame = this.ioc.getModel("frame", frameConfig); + const workspaceConfig = { frame, snapshot }; + return this.ioc.getModel("workspace", workspaceConfig); + } + async createEmptyFrame(definition) { + const frameSummary = await this.bridge.send(OPERATIONS.createFrame.name, definition); + const frameConfig = { + summary: frameSummary + }; + return this.ioc.getModel("frame", frameConfig); + } + async initFrame(frameId, config) { + await this.bridge.send(OPERATIONS.initFrame.name, { frameId, ...config }); + } + async restoreWorkspace(name, options) { + const snapshot = await this.bridge.send(OPERATIONS.openWorkspace.name, { name, restoreOptions: options }); + const frameSummary = await this.bridge.send(OPERATIONS.getFrameSummary.name, { itemId: snapshot.config.frameId }); + const frameConfig = { + summary: frameSummary + }; + const frame = this.ioc.getModel("frame", frameConfig); + const workspaceConfig = { frame, snapshot }; + return this.ioc.getModel("workspace", workspaceConfig); + } + async add(type, parentId, parentType, definition) { + let operationName; + const operationArgs = { definition, parentId, parentType }; + if (type === "window") { + operationName = OPERATIONS.addWindow.name; + } + else if (type === "container") { + operationName = OPERATIONS.addContainer.name; + } + else { + throw new Error(`Unrecognized add type: ${type}`); + } + return await this.bridge.send(operationName, operationArgs); + } + async getFrame(windowId) { + const frameSummary = await this.bridge.send(OPERATIONS.getFrameSummary.name, { itemId: windowId }); + const frameConfig = { + summary: frameSummary + }; + return this.ioc.getModel("frame", frameConfig); + } + getFrames(allFrameSummaries, predicate) { + return allFrameSummaries.reduce((frames, frameSummary) => { + const frameConfig = { + summary: frameSummary + }; + const frameToCheck = this.ioc.getModel("frame", frameConfig); + if (!predicate || predicate(frameToCheck)) { + frames.push(frameToCheck); + } + return frames; + }, []); + } + getAllWorkspaceSummaries(...bridgeResults) { + const allSummaries = bridgeResults.reduce((summaries, summaryResult) => { + summaries.push(...summaryResult.summaries); + return summaries; + }, []); + return allSummaries.map((summary) => { + return Object.assign({}, { id: summary.id, width: summary.config.widthInPx, height: summary.config.heightInPx }, summary.config); + }); + } + handleOnSaved(callback) { + const wrappedCallback = (layout) => { + if (layout.type !== "Workspace") { + return; + } + callback(layout); + }; + const addedUnSub = this.layouts.onAdded(wrappedCallback); + const changedUnSub = this.layouts.onChanged(wrappedCallback); + return () => { + addedUnSub(); + changedUnSub(); + }; + } + handleOnRemoved(callback) { + const wrappedCallback = (layout) => { + if (layout.type !== "Workspace") { + return; + } + callback(layout); + }; + return this.layouts.onRemoved(wrappedCallback); + } + async importLayouts(layouts, mode) { + await this.layouts.import(layouts, mode); + } + async transformStreamPayloadToWorkspace(payload) { + const frameConfig = { + summary: payload.frameSummary + }; + const frame = this.ioc.getModel("frame", frameConfig); + const snapshot = payload.workspaceSnapshot || (await this.bridge.send(OPERATIONS.getWorkspaceSnapshot.name, { itemId: payload.workspaceSummary.id })); + const workspaceConfig = { frame, snapshot }; + const workspace = this.ioc.getModel("workspace", workspaceConfig); + return workspace; + } + async fetchWorkspace(itemId) { + const snapshot = await this.bridge.send(OPERATIONS.getWorkspaceSnapshot.name, { itemId }); + const frameConfig = { + summary: snapshot.frameSummary + }; + const frame = this.ioc.getModel("frame", frameConfig); + const workspaceConfig = { frame, snapshot }; + return this.ioc.getModel("workspace", workspaceConfig); + } + async bundleWorkspaceTo(type, workspaceId) { + await this.bridge.send(OPERATIONS.bundleWorkspace.name, { type, workspaceId }); + } + async bundleItemTo(type, itemId) { + const isSupported = await this.isOperationSupported(OPERATIONS.bundleItem.name); + if (!isSupported) { + throw new Error(`Operation ${OPERATIONS.bundleItem.name} is not supported. Ensure that you are running the latest version of all packages`); + } + await this.bridge.send(OPERATIONS.bundleItem.name, { type, itemId }); + } + getWorkspaceContext(workspaceId) { + const contextName = `___workspace___${workspaceId}`; + return this.contexts.get(contextName); + } + setWorkspaceContext(workspaceId, data) { + const contextName = `___workspace___${workspaceId}`; + return this.contexts.set(contextName, data); + } + updateWorkspaceContext(workspaceId, data) { + const contextName = `___workspace___${workspaceId}`; + return this.contexts.update(contextName, data); + } + subscribeWorkspaceContextUpdated(workspaceId, callback) { + const contextName = `___workspace___${workspaceId}`; + return this.contexts.subscribe(contextName, callback); + } + async restoreItem(itemId) { + await this.bridge.send(OPERATIONS.restoreItem.name, { itemId }); + } + async maximizeItem(itemId) { + await this.bridge.send(OPERATIONS.maximizeItem.name, { itemId }); + } + async focusItem(itemId) { + await this.bridge.send(OPERATIONS.focusItem.name, { itemId }); + } + async closeItem(itemId) { + await this.bridge.send(OPERATIONS.closeItem.name, { itemId }); + } + async resizeItem(itemId, config) { + await this.bridge.send(OPERATIONS.resizeItem.name, Object.assign({}, { itemId }, config)); + } + async setMaximizationBoundary(itemId, config) { + await this.bridge.send(OPERATIONS.setMaximizationBoundary.name, Object.assign({}, { itemId }, config)); + } + async showWorkspaceLoadingAnimation(workspaceId) { + await this.bridge.send(OPERATIONS.showLoadingAnimation.name, { itemId: workspaceId, type: "workspace" }); + } + async hideWorkspaceLoadingAnimation(workspaceId) { + await this.bridge.send(OPERATIONS.hideLoadingAnimation.name, { itemId: workspaceId, type: "workspace" }); + } + async setWindowDragMode(workspaceId, dragMode) { + await this.bridge.send(OPERATIONS.setWindowDragMode.name, { itemId: workspaceId, dragMode }); + } + async moveFrame(itemId, config) { + await this.bridge.send(OPERATIONS.moveFrame.name, Object.assign({}, { itemId }, config)); + } + getGDWindow(itemId) { + return this.windows.list().find((gdWindow) => gdWindow.id === itemId); + } + async forceLoadWindow(itemId) { + const controlResult = await this.bridge.send(OPERATIONS.forceLoadWindow.name, { itemId }); + return controlResult.windowId; + } + async ejectWindow(itemId) { + return await this.bridge.send(OPERATIONS.ejectWindow.name, { itemId }); + } + async moveWindowTo(itemId, newParentId) { + await this.bridge.send(OPERATIONS.moveWindowTo.name, { itemId, containerId: newParentId }); + } + async getSnapshot(itemId, type) { + let result; + if (type === "workspace") { + result = await this.bridge.send(OPERATIONS.getWorkspaceSnapshot.name, { itemId }); + } + else if (type === "frame") { + result = await this.bridge.send(OPERATIONS.getFrameSnapshot.name, { itemId }); + } + return result; + } + async setItemTitle(itemId, title) { + await this.bridge.send(OPERATIONS.setItemTitle.name, { itemId, title }); + } + refreshChildren(config) { + const { parent, children, existingChildren, workspace } = config; + if (parent instanceof Window || parent.type === "window") { + return; + } + const newChildren = children.map((newChildSnapshot) => { + let childToAdd = existingChildren.find((child) => { + return child.type === "window" ? child.elementId === newChildSnapshot.id : child.id === newChildSnapshot.id; + }); + if (childToAdd) { + this.privateDataManager.remapChild(childToAdd, { + parent: parent, + children: [], + config: newChildSnapshot.config + }); + } + else { + let createConfig; + if (newChildSnapshot.type === "window") { + createConfig = { + id: newChildSnapshot.id, + parent: parent, + frame: workspace.frame, + workspace, + config: newChildSnapshot.config, + }; + } + else { + createConfig = { + id: newChildSnapshot.id, + parent: parent, + frame: workspace.frame, + workspace, + config: newChildSnapshot.config, + children: [] + }; + } + childToAdd = this.ioc.getModel(newChildSnapshot.type, createConfig); + } + if (newChildSnapshot.type !== "window") { + this.refreshChildren({ + workspace, existingChildren, + children: newChildSnapshot.children, + parent: childToAdd + }); + } + return childToAdd; + }); + if (parent instanceof Workspace) { + return newChildren; + } + else { + this.privateDataManager.remapChild(parent, { children: newChildren }); + return newChildren; + } + } + iterateFindChild(children, predicate) { + let foundChild = children.find((child) => predicate(child)); + if (foundChild) { + return foundChild; + } + children.some((child) => { + if (child instanceof Window) { + return false; + } + foundChild = this.iterateFindChild(child.children, predicate); + if (foundChild) { + return true; + } + }); + return foundChild; + } + iterateFilterChildren(children, predicate) { + const foundChildren = children.filter((child) => predicate(child)); + const grandChildren = children.reduce((innerFound, child) => { + if (child instanceof Window) { + return innerFound; + } + innerFound.push(...this.iterateFilterChildren(child.children, predicate)); + return innerFound; + }, []); + foundChildren.push(...grandChildren); + return foundChildren; + } + notifyWindowAdded(windowId) { + return new Promise((resolve) => { + const alreadyPresent = this.windows.list().some((win) => win.id === windowId); + if (alreadyPresent) { + return resolve(); + } + const unsubscribe = this.windows.onWindowAdded((win) => { + if (win.id !== windowId) { + return; + } + if (unsubscribe) { + unsubscribe(); + } + resolve(); + }); + }); + } + async hibernateWorkspace(workspaceId) { + await this.bridge.send(OPERATIONS.hibernateWorkspace.name, { workspaceId }); + } + async resumeWorkspace(workspaceId) { + await this.bridge.send(OPERATIONS.resumeWorkspace.name, { workspaceId }); + } + async lockWorkspace(workspaceId, config) { + await this.bridge.send(OPERATIONS.lockWorkspace.name, { workspaceId, config }); + } + async lockWindow(windowPlacementId, config) { + await this.bridge.send(OPERATIONS.lockWindow.name, { windowPlacementId, config }); + } + async lockContainer(itemId, type, config) { + await this.bridge.send(OPERATIONS.lockContainer.name, { itemId, type, config }); + } + async pinWorkspace(workspaceId, icon) { + await this.bridge.send(OPERATIONS.pinWorkspace.name, { workspaceId, icon }); + } + async unpinWorkspace(workspaceId) { + await this.bridge.send(OPERATIONS.unpinWorkspace.name, { workspaceId }); + } + async getWorkspaceIcon(workspaceId) { + const result = await this.bridge.send(OPERATIONS.getWorkspaceIcon.name, { workspaceId }); + return result.icon; + } + setWorkspaceIcon(workspaceId, icon) { + return this.bridge.send(OPERATIONS.setWorkspaceIcon.name, { workspaceId, icon }); + } + async getPlatformFrameId() { + try { + const result = await this.bridge.send(OPERATIONS.getPlatformFrameId.name, {}); + return result; + } + catch (error) { + return {}; + } + } + async setLoadingStrategy(workspaceId, strategy) { + await this.isOperationSupported(OPERATIONS.setLoadingStrategy.name); + return this.bridge.send(OPERATIONS.setLoadingStrategy.name, { itemId: workspaceId, strategy }); + } + async isOperationSupported(operation) { + if (isDesktop()) { + return { isSupported: true }; + } + return await this.bridge.send(OPERATIONS.operationCheck.name, { operation }); + } + } + + class MainController { + bridge; + base; + shortcutsController; + constructor(bridge, base, shortcutsController) { + this.bridge = bridge; + this.base = base; + this.shortcutsController = shortcutsController; + } + checkIsWindowLoaded(windowId) { + return this.base.checkIsWindowLoaded(windowId); + } + async checkIsInSwimlane(windowId) { + const controlResult = await this.bridge.send(OPERATIONS.isWindowInWorkspace.name, { itemId: windowId }); + return controlResult.inWorkspace; + } + async createWorkspace(definition, saveConfig) { + const createConfig = Object.assign({}, definition, { saveConfig }); + return await this.base.createWorkspace(createConfig); + } + async createEmptyFrame(definition) { + return await this.base.createEmptyFrame(definition); + } + async initFrame(frameId, config) { + return this.base.initFrame(frameId, config); + } + async restoreWorkspace(name, options) { + const allLayouts = await this.getLayoutSummaries(); + const layoutExists = allLayouts.some((summary) => summary.name === name); + if (!layoutExists) { + throw new Error(`This layout: ${name} cannot be restored, because it doesn't exist.`); + } + if (options?.frameId) { + const allFrameSummaries = await this.bridge.send(OPERATIONS.getAllFramesSummaries.name); + const foundMatchingFrame = allFrameSummaries.summaries.some((summary) => summary.id === options.frameId); + if (!foundMatchingFrame) { + throw new Error(`Cannot reuse the frame with id: ${options.frameId}, because there is no frame with that ID found`); + } + } + return await this.base.restoreWorkspace(name, options); + } + async add(type, parentId, parentType, definition) { + return await this.base.add(type, parentId, parentType, definition); + } + processLocalSubscription(config, levelId) { + return isDesktop() ? + this.handleEnterpriseLocalSubscription(config, levelId) : + this.handleCoreLocalSubscription(config, levelId); + } + processGlobalSubscription(callback, eventType, action) { + return isDesktop() ? + this.handleEnterpriseGlobalSubscription(callback, eventType, action) : + this.handleCoreGlobalSubscription(callback, eventType, action); + } + async getFrame(selector) { + if (selector.windowId) { + return await this.base.getFrame(selector.windowId); + } + if (selector.predicate) { + return (await this.getFrames(selector.predicate))[0]; + } + throw new Error(`The provided selector is not valid: ${JSON.stringify(selector)}`); + } + async getFrames(predicate) { + const allFrameSummaries = await this.bridge.send(OPERATIONS.getAllFramesSummaries.name); + return this.base.getFrames(allFrameSummaries.summaries, predicate); + } + getWorkspaceById(workspaceId) { + return this.base.fetchWorkspace(workspaceId); + } + async getWorkspaceByWindowId(itemId) { + if (!isDesktop()) { + return (await this.getWorkspaces((wsp) => !!wsp.getWindow((w) => w.id === itemId)))[0]; + } + return this.base.fetchWorkspace(itemId); + } + transformStreamPayloadToWorkspace(payload) { + return this.base.transformStreamPayloadToWorkspace(payload); + } + async getWorkspace(predicate) { + let foundWorkspace; + await this.iterateWorkspaces((wsp, end) => { + if (predicate(wsp)) { + foundWorkspace = wsp; + end(); + } + }); + return foundWorkspace; + } + async getWorkspaces(predicate) { + const matchingWorkspaces = []; + await this.iterateWorkspaces((wsp) => { + if (!predicate || predicate(wsp)) { + matchingWorkspaces.push(wsp); + } + }); + return matchingWorkspaces; + } + async getWorkspacesByFrameId(frameId) { + const workspaceSummaries = await this.getAllWorkspaceSummaries(); + const summariesForFrame = workspaceSummaries.filter((s) => s.frameId === frameId); + const workspacesForFrame = await Promise.all(summariesForFrame.map((summary) => { + return this.base.fetchWorkspace(summary.id); + })); + return workspacesForFrame; + } + async getAllWorkspaceSummaries() { + const allSummariesResult = await this.bridge.send(OPERATIONS.getAllWorkspacesSummaries.name, {}); + return this.base.getAllWorkspaceSummaries(allSummariesResult); + } + async getWindow(predicate) { + let resultWindow; + await this.iterateWorkspaces((wsp, end) => { + const foundWindow = wsp.getWindow(predicate); + if (foundWindow) { + resultWindow = foundWindow; + end(); + } + }); + return resultWindow; + } + async getParent(predicate) { + let resultParent; + await this.iterateWorkspaces((wsp, end) => { + const foundParent = wsp.getBox(predicate); + if (foundParent) { + resultParent = foundParent; + end(); + } + }); + return resultParent; + } + async getLayoutSummaries() { + const allLayouts = await this.bridge.send(OPERATIONS.getAllLayoutsSummaries.name); + return allLayouts.summaries; + } + async deleteLayout(name) { + await this.bridge.send(OPERATIONS.deleteLayout.name, { name }); + } + async exportLayout(predicate) { + const allLayoutsResult = await this.bridge.send(OPERATIONS.exportAllLayouts.name); + return allLayoutsResult.layouts.reduce((matchingLayouts, layout) => { + if (!predicate || predicate(layout)) { + matchingLayouts.push(layout); + } + return matchingLayouts; + }, []); + } + async saveLayout(config) { + return await this.bridge.send(OPERATIONS.saveLayout.name, config); + } + async importLayouts(layouts, mode) { + if (isDesktop()) { + try { + await this.bridge.send(OPERATIONS.importLayouts.name, { layouts, mode }); + } + catch (error) { + await Promise.all(layouts.map((layout) => this.bridge.send(OPERATIONS.importLayout.name, { layout, mode }))); + } + return; + } + await this.base.importLayouts(layouts, mode); + } + handleOnSaved(callback) { + return this.base.handleOnSaved(callback); + } + handleOnRemoved(callback) { + return this.base.handleOnRemoved(callback); + } + async bundleWorkspaceTo(type, workspaceId) { + return await this.base.bundleWorkspaceTo(type, workspaceId); + } + async bundleItemTo(type, id) { + return await this.base.bundleItemTo(type, id); + } + getWorkspaceContext(workspaceId) { + return this.base.getWorkspaceContext(workspaceId); + } + setWorkspaceContext(workspaceId, data) { + return this.base.setWorkspaceContext(workspaceId, data); + } + updateWorkspaceContext(workspaceId, data) { + return this.base.updateWorkspaceContext(workspaceId, data); + } + subscribeWorkspaceContextUpdated(workspaceId, callback) { + return this.base.subscribeWorkspaceContextUpdated(workspaceId, callback); + } + async restoreItem(itemId) { + return await this.base.restoreItem(itemId); + } + async maximizeItem(itemId) { + return await this.base.maximizeItem(itemId); + } + async focusItem(itemId) { + return await this.base.focusItem(itemId); + } + async changeFrameState(frameId, state) { + await this.bridge.send(OPERATIONS.changeFrameState.name, { frameId, requestedState: state }); + } + async getFrameBounds(frameId) { + const frameResult = await this.bridge.send(OPERATIONS.getFrameBounds.name, { itemId: frameId }); + return frameResult.bounds; + } + async getFrameState(frameId) { + const frameResult = await this.bridge.send(OPERATIONS.getFrameState.name, { itemId: frameId }); + return frameResult.state; + } + async closeItem(itemId) { + return await this.base.closeItem(itemId); + } + async resizeItem(itemId, config) { + return await this.base.resizeItem(itemId, config); + } + async setMaximizationBoundary(itemId, config) { + return await this.base.setMaximizationBoundary(itemId, config); + } + async showWorkspaceLoadingAnimation(workspaceId) { + return await this.base.showWorkspaceLoadingAnimation(workspaceId); + } + async hideWorkspaceLoadingAnimation(workspaceId) { + return await this.base.hideWorkspaceLoadingAnimation(workspaceId); + } + async setWindowDragMode(workspaceId, dragMode) { + return await this.base.setWindowDragMode(workspaceId, dragMode); + } + async moveFrame(itemId, config) { + return await this.base.moveFrame(itemId, config); + } + getGDWindow(itemId) { + return this.base.getGDWindow(itemId); + } + async forceLoadWindow(itemId) { + const windowId = await this.base.forceLoadWindow(itemId); + await this.base.notifyWindowAdded(windowId); + return windowId; + } + async ejectWindow(itemId) { + const windowId = (await this.base.ejectWindow(itemId)).windowId; + await this.base.notifyWindowAdded(windowId); + return windowId; + } + async moveWindowTo(itemId, newParentId) { + return await this.base.moveWindowTo(itemId, newParentId); + } + async getSnapshot(itemId, type) { + return await this.base.getSnapshot(itemId, type); + } + async setItemTitle(itemId, title) { + return await this.base.setItemTitle(itemId, title); + } + flatChildren(children) { + return children.reduce((soFar, child) => { + soFar.push(child); + if (child.type !== "window") { + soFar.push(...this.flatChildren(child.children)); + } + return soFar; + }, []); + } + refreshChildren(config) { + return this.base.refreshChildren(config); + } + iterateFindChild(children, predicate) { + return this.base.iterateFindChild(children, predicate); + } + iterateFilterChildren(children, predicate) { + return this.base.iterateFilterChildren(children, predicate); + } + hibernateWorkspace(workspaceId) { + return this.base.hibernateWorkspace(workspaceId); + } + resumeWorkspace(workspaceId) { + return this.base.resumeWorkspace(workspaceId); + } + lockWorkspace(workspaceId, config) { + return this.base.lockWorkspace(workspaceId, config); + } + lockWindow(windowPlacementId, config) { + return this.base.lockWindow(windowPlacementId, config); + } + lockContainer(itemId, type, config) { + return this.base.lockContainer(itemId, type, config); + } + pinWorkspace(workspaceId, icon) { + return this.base.pinWorkspace(workspaceId, icon); + } + unpinWorkspace(workspaceId) { + return this.base.unpinWorkspace(workspaceId); + } + getWorkspaceIcon(workspaceId) { + return this.base.getWorkspaceIcon(workspaceId); + } + setWorkspaceIcon(workspaceId, icon) { + return this.base.setWorkspaceIcon(workspaceId, icon); + } + async getFrameConstraints(frameId) { + const frameSnapshot = await this.getSnapshot(frameId, "frame"); + return { + minWidth: frameSnapshot.config.minWidth, + maxWidth: frameSnapshot.config.maxWidth, + minHeight: frameSnapshot.config.minHeight, + maxHeight: frameSnapshot.config.maxHeight, + }; + } + registerShortcut(shortcut, frameId, callback) { + return this.shortcutsController.registerShortcut(shortcut, frameId, callback); + } + getPlatformFrameId() { + return this.base.getPlatformFrameId(); + } + setLoadingStrategy(workspaceId, strategy) { + return this.base.setLoadingStrategy(workspaceId, strategy); + } + async handleCoreLocalSubscription(config, levelId) { + await this.bridge.createCoreEventSubscription(); + config.scopeId = config.scopeId || levelId; + if (config.eventType === "window" && config.action === "loaded") { + const originalCB = config.callback; + const wrappedCB = async (callbackData) => { + await this.base.notifyWindowAdded(callbackData.windowSummary.config.windowId); + originalCB(callbackData); + }; + config.callback = wrappedCB; + } + return this.bridge.handleCoreSubscription(config); + } + handleEnterpriseLocalSubscription(config, levelId) { + config.scopeId = config.scopeId || levelId; + if (config.eventType === "window" && config.action === "loaded") { + const originalCB = config.callback; + const wrappedCB = async (callbackData) => { + await this.base.notifyWindowAdded(callbackData.windowSummary.config.windowId); + originalCB(callbackData); + }; + config.callback = wrappedCB; + } + return this.bridge.subscribe(config); + } + async handleCoreGlobalSubscription(callback, eventType, action) { + await this.bridge.createCoreEventSubscription(); + const config = { + eventType, callback, action, + scope: "global", + }; + if (eventType === "window" && action === "loaded") { + const wrappedCB = async (callbackData) => { + await this.base.notifyWindowAdded(callbackData.windowSummary.config.windowId); + callback(callbackData); + }; + config.callback = wrappedCB; + } + return this.bridge.handleCoreSubscription(config); + } + handleEnterpriseGlobalSubscription(callback, eventType, action) { + const config = { + eventType, callback, action, + scope: "global", + }; + if (eventType === "window" && action === "loaded") { + const wrappedCB = async (callbackData) => { + await this.base.notifyWindowAdded(callbackData.windowSummary.config.windowId); + callback(callbackData); + }; + config.callback = wrappedCB; + } + return this.bridge.subscribe(config); + } + async iterateWorkspaces(callback) { + let ended = false; + const end = () => { ended = true; }; + const workspaceSummaries = await this.getAllWorkspaceSummaries(); + for (const summary of workspaceSummaries) { + if (ended) { + return; + } + const wsp = await this.base.fetchWorkspace(summary.id); + callback(wsp, end); + } + } + } + + class ShortcutsController { + bridge; + _shortcuts = CallbackFactory(); + constructor(bridge) { + this.bridge = bridge; + this.bridge.onOperation((payload, caller) => { + if (payload.operation === CLIENT_OPERATIONS.shortcutClicked.name) { + const data = payload.data; + this._shortcuts.execute(`${data.frameId}-${data.shortcut}`); + } + }); + } + async registerShortcut(shortcut, frameId, callback) { + await this.bridge.send(OPERATIONS.registerShortcut.name, { shortcut, frameId }); + const un = this._shortcuts.add(`${frameId}-${shortcut}`, callback); + return () => { + un(); + this.bridge.send(OPERATIONS.unregisterShortcut.name, { shortcut, frameId }); + }; + } + } + + class IoC { + agm; + windows; + layouts; + contexts; + _controllerInstance; + _bridgeInstance; + _transportInstance; + _privateDataManagerInstance; + _parentBaseInstance; + _baseController; + _shortcutsController; + constructor(agm, windows, layouts, contexts) { + this.agm = agm; + this.windows = windows; + this.layouts = layouts; + this.contexts = contexts; + } + get baseController() { + if (!this._baseController) { + this._baseController = new BaseController(this, this.windows, this.contexts, this.layouts); + } + return this._baseController; + } + get controller() { + if (!this._controllerInstance) { + this._controllerInstance = new MainController(this.bridge, this.baseController, this.shortcutsController); + } + return this._controllerInstance; + } + get shortcutsController() { + if (!this._shortcutsController) { + this._shortcutsController = new ShortcutsController(this.bridge); + } + return this._shortcutsController; + } + get bridge() { + if (!this._bridgeInstance) { + this._bridgeInstance = new Bridge(this.transport, CallbackFactory()); + } + return this._bridgeInstance; + } + get transport() { + if (!this._transportInstance) { + this._transportInstance = new InteropTransport(this.agm, CallbackFactory()); + } + return this._transportInstance; + } + get privateDataManager() { + if (!this._privateDataManagerInstance) { + this._privateDataManagerInstance = new PrivateDataManager(); + } + return this._privateDataManagerInstance; + } + get parentBase() { + if (!this._parentBaseInstance) { + this._parentBaseInstance = new Base(this.privateDataManager); + } + return this._parentBaseInstance; + } + async initiate(actualWindowId) { + await this.transport.initiate(actualWindowId); + } + getModel(type, createConfig) { + switch (type) { + case "frame": { + const newFrame = new Frame(this.privateDataManager); + const { summary } = createConfig; + const frameData = { summary, controller: this.controller }; + this.privateDataManager.setFrameData(newFrame, frameData); + return newFrame; + } + case "window": { + const { id, parent, frame, workspace, config } = createConfig; + const windowPrivateData = { + type: "window", + controller: this.controller, + config, id, parent, frame, workspace + }; + const newWindow = new Window(this.privateDataManager); + this.privateDataManager.setWindowData(newWindow, windowPrivateData); + return newWindow; + } + case "row": + case "column": + case "group": { + const { id, children, parent, frame, workspace, config } = createConfig; + const newParent = type === "column" ? new Column(this.parentBase) : + type === "row" ? new Row(this.parentBase) : new Group(this.parentBase); + const builtChildren = this.buildChildren(children, frame, workspace, newParent); + const parentPrivateData = { + id, parent, frame, workspace, + config, + type, + controller: this.controller, + children: builtChildren, + }; + this.privateDataManager.setParentData(newParent, parentPrivateData); + return newParent; + } + case "workspace": { + const { snapshot, frame } = createConfig; + const newWorkspace = new Workspace(this.privateDataManager); + const children = this.buildChildren(snapshot.children, frame, newWorkspace, newWorkspace); + const workspacePrivateData = { + id: snapshot.id, + type: "workspace", + config: snapshot.config, + base: this.parentBase, + controller: this.controller, + children, frame, ioc: this + }; + this.privateDataManager.setWorkspaceData(newWorkspace, workspacePrivateData); + return newWorkspace; + } + default: throw new Error(`Unrecognized type: ${type}`); + } + } + getBuilder(config) { + config.definition = config.definition || {}; + if (!Array.isArray(config.definition.children)) { + config.definition.children = []; + } + const baseBuilder = new BaseBuilder(this.getBuilder.bind(this)); + switch (config.type) { + case "workspace": { + return new WorkspaceBuilder(config.definition, baseBuilder, this.controller); + } + case "row": + case "column": + case "group": { + config.definition.type = config.type; + return new ParentBuilder(config.definition, baseBuilder); + } + default: throw new Error(`Unexpected Builder creation error, provided config: ${JSON.stringify(config)}`); + } + } + buildChildren(children, frame, workspace, parent) { + return children.map((child) => { + switch (child.type) { + case "window": return this.getModel("window", { + id: child.id, + config: child.config, + frame, workspace, parent + }); + case "column": return this.getModel(child.type, { + id: child.id, + config: child.config, + children: child.children, + frame, workspace, parent + }); + case "row": return this.getModel(child.type, { + id: child.id, + config: child.config, + children: child.children, + frame, workspace, parent + }); + case "group": return this.getModel(child.type, { + id: child.id, + config: child.config, + children: child.children, + frame, workspace, parent + }); + default: throw new Error(`Unsupported child type: ${child.type}`); + } + }); + } + } + + var version = "3.5.6"; + + const composeAPI = (glue, ioc) => { + const controller = ioc.controller; + const inWorkspace = () => { + const myId = glue.windows.my().id; + if (!myId) { + throw new Error("Cannot get my frame, because my id is undefined."); + } + return controller.checkIsInSwimlane(myId); + }; + const getBuilder = (config) => { + const validatedConfig = builderConfigDecoder.runWithException(config); + return ioc.getBuilder(validatedConfig); + }; + const getMyFrame = async () => { + const windowId = glue.windows.my().id; + if (!windowId) { + throw new Error("Cannot get my frame, because my id is undefined."); + } + const isInSwimlane = await controller.checkIsInSwimlane(windowId); + if (!isInSwimlane) { + throw new Error("Cannot fetch your frame, because this window is not in a workspace"); + } + return controller.getFrame({ windowId }); + }; + const getFrame = async (predicate) => { + checkThrowCallback(predicate); + return controller.getFrame({ predicate }); + }; + const getAllFrames = async (predicate) => { + checkThrowCallback(predicate, true); + return controller.getFrames(predicate); + }; + const getAllWorkspacesSummaries = () => { + return controller.getAllWorkspaceSummaries(); + }; + const getMyWorkspace = async () => { + const myId = glue.windows.my().id; + if (!myId) { + throw new Error("Cannot get my workspace, because my id is undefined."); + } + const isInSwimlane = await controller.checkIsInSwimlane(myId); + if (!isInSwimlane) { + throw new Error("Cannot fetch your workspace, because this window is not in a workspace"); + } + return await controller.getWorkspaceByWindowId(myId); + }; + const getWorkspace = async (predicate) => { + checkThrowCallback(predicate); + return (await controller.getWorkspaces(predicate))[0]; + }; + const getWorkspaceById = async (workspaceId) => { + nonEmptyStringDecoder.runWithException(workspaceId); + return controller.getWorkspaceById(workspaceId); + }; + const getAllWorkspaces = (predicate) => { + checkThrowCallback(predicate, true); + return controller.getWorkspaces(predicate); + }; + const getWindow = async (predicate) => { + checkThrowCallback(predicate); + return controller.getWindow(predicate); + }; + const getParent = async (predicate) => { + checkThrowCallback(predicate); + return controller.getParent(predicate); + }; + const restoreWorkspace = async (name, options) => { + nonEmptyStringDecoder.runWithException(name); + const validatedOptions = restoreWorkspaceConfigDecoder.runWithException(options); + return controller.restoreWorkspace(name, validatedOptions); + }; + const createWorkspace = async (definition, saveConfig) => { + const validatedDefinition = workspaceDefinitionDecoder.runWithException(definition); + const validatedConfig = workspaceBuilderCreateConfigDecoder.runWithException(saveConfig); + return controller.createWorkspace(validatedDefinition, validatedConfig); + }; + const createEmptyFrame = async (definition) => { + const validatedDefinition = emptyFrameDefinitionDecoder.runWithException(definition); + return controller.createEmptyFrame(validatedDefinition ?? {}); + }; + const layouts = { + getSummaries: () => { + return controller.getLayoutSummaries(); + }, + delete: async (name) => { + nonEmptyStringDecoder.runWithException(name); + return controller.deleteLayout(name); + }, + export: async (predicate) => { + checkThrowCallback(predicate, true); + return controller.exportLayout(predicate); + }, + import: async (layouts, mode = "replace") => { + if (!Array.isArray(layouts)) { + throw new Error(`The provided layouts argument is not an array: ${JSON.stringify(layouts)}`); + } + layouts.forEach((layout) => workspaceLayoutDecoder.runWithException(layout)); + return controller.importLayouts(layouts, mode); + }, + save: async (config) => { + const verifiedConfig = workspaceLayoutSaveConfigDecoder.runWithException(config); + return controller.saveLayout(verifiedConfig); + }, + onSaved: async (callback) => { + checkThrowCallback(callback); + return controller.handleOnSaved(callback); + }, + onRemoved: async (callback) => { + checkThrowCallback(callback); + return controller.handleOnRemoved(callback); + } + }; + const onFrameOpened = async (callback) => { + checkThrowCallback(callback); + const wrappedCallback = (payload) => { + const frameConfig = { + summary: payload.frameSummary + }; + const frame = ioc.getModel("frame", frameConfig); + callback(frame); + }; + const unsubscribe = await controller.processGlobalSubscription(wrappedCallback, "frame", "opened"); + return unsubscribe; + }; + const onFrameClosed = async (callback) => { + checkThrowCallback(callback); + const wrappedCallback = (payload) => { + callback({ frameId: payload.frameSummary.id, frameBounds: payload.frameBounds }); + }; + const unsubscribe = await controller.processGlobalSubscription(wrappedCallback, "frame", "closed"); + return unsubscribe; + }; + const onWorkspaceOpened = async (callback) => { + checkThrowCallback(callback); + const wrappedCallback = async (payload) => { + const workspace = await controller.transformStreamPayloadToWorkspace(payload); + callback(workspace); + }; + const unsubscribe = await controller.processGlobalSubscription(wrappedCallback, "workspace", "opened"); + return unsubscribe; + }; + const onWorkspaceClosed = async (callback) => { + checkThrowCallback(callback); + const wrappedCallback = (payload) => { + callback({ frameId: payload.frameSummary.id, workspaceId: payload.workspaceSummary.id, frameBounds: payload.frameBounds }); + }; + const unsubscribe = await controller.processGlobalSubscription(wrappedCallback, "workspace", "closed"); + return unsubscribe; + }; + const onWorkspaceHibernated = async (callback) => { + checkThrowCallback(callback); + const wrappedCallback = async (payload) => { + const workspace = await controller.transformStreamPayloadToWorkspace(payload); + callback(workspace); + }; + const unsubscribe = await controller.processGlobalSubscription(wrappedCallback, "workspace", "hibernated"); + return unsubscribe; + }; + const onWorkspaceResumed = async (callback) => { + checkThrowCallback(callback); + const wrappedCallback = async (payload) => { + const workspace = await controller.transformStreamPayloadToWorkspace(payload); + callback(workspace); + }; + const unsubscribe = await controller.processGlobalSubscription(wrappedCallback, "workspace", "resumed"); + return unsubscribe; + }; + const onWindowAdded = async (callback) => { + checkThrowCallback(callback); + const wrappedCallback = async (payload) => { + const snapshot = (await controller.getSnapshot(payload.windowSummary.config.workspaceId, "workspace")); + const frameConfig = { + summary: snapshot.frameSummary + }; + const frame = ioc.getModel("frame", frameConfig); + const workspaceConfig = { frame, snapshot }; + const workspace = ioc.getModel("workspace", workspaceConfig); + const windowParent = workspace.getBox((parent) => parent.id === payload.windowSummary.parentId); + const foundWindow = windowParent.children.find((child) => child.type === "window" && child.elementId === payload.windowSummary.itemId); + callback(foundWindow); + }; + const unsubscribe = await controller.processGlobalSubscription(wrappedCallback, "window", "added"); + return unsubscribe; + }; + const onWindowLoaded = async (callback) => { + checkThrowCallback(callback); + const wrappedCallback = async (payload) => { + const snapshot = (await controller.getSnapshot(payload.windowSummary.config.workspaceId, "workspace")); + const frameConfig = { + summary: snapshot.frameSummary + }; + const frame = ioc.getModel("frame", frameConfig); + const workspaceConfig = { frame, snapshot }; + const workspace = ioc.getModel("workspace", workspaceConfig); + const foundWindow = workspace.getWindow((win) => win.id && win.id === payload.windowSummary.config.windowId); + callback(foundWindow); + }; + const unsubscribe = await controller.processGlobalSubscription(wrappedCallback, "window", "loaded"); + return unsubscribe; + }; + const onWindowRemoved = async (callback) => { + checkThrowCallback(callback); + const wrappedCallback = (payload) => { + const { windowId, workspaceId, frameId } = payload.windowSummary.config; + callback({ windowId, workspaceId, frameId }); + }; + const unsubscribe = await controller.processGlobalSubscription(wrappedCallback, "window", "removed"); + return unsubscribe; + }; + const onWindowMaximized = async (callback) => { + checkThrowCallback(callback); + const wrappedCallback = async (payload) => { + const snapshot = (await controller.getSnapshot(payload.windowSummary.config.workspaceId, "workspace")); + const frameConfig = { + summary: snapshot.frameSummary + }; + const frame = ioc.getModel("frame", frameConfig); + const workspaceConfig = { frame, snapshot }; + const workspace = ioc.getModel("workspace", workspaceConfig); + const windowParent = workspace.getBox((parent) => parent.id === payload.windowSummary.parentId); + const foundWindow = windowParent.children.find((child) => child.type === "window" && child.elementId === payload.windowSummary.itemId); + callback(foundWindow); + }; + const unsubscribe = await controller.processGlobalSubscription(wrappedCallback, "window", "maximized"); + return unsubscribe; + }; + const onWindowRestored = async (callback) => { + checkThrowCallback(callback); + const wrappedCallback = async (payload) => { + const snapshot = (await controller.getSnapshot(payload.windowSummary.config.workspaceId, "workspace")); + const frameConfig = { + summary: snapshot.frameSummary + }; + const frame = ioc.getModel("frame", frameConfig); + const workspaceConfig = { frame, snapshot }; + const workspace = ioc.getModel("workspace", workspaceConfig); + const windowParent = workspace.getBox((parent) => parent.id === payload.windowSummary.parentId); + const foundWindow = windowParent.children.find((child) => child.type === "window" && child.elementId === payload.windowSummary.itemId); + callback(foundWindow); + }; + const unsubscribe = await controller.processGlobalSubscription(wrappedCallback, "window", "restored"); + return unsubscribe; + }; + const onWindowSelected = async (callback) => { + checkThrowCallback(callback); + const wrappedCallback = async (payload) => { + const snapshot = (await controller.getSnapshot(payload.windowSummary.config.workspaceId, "workspace")); + const frameConfig = { + summary: snapshot.frameSummary + }; + const frame = ioc.getModel("frame", frameConfig); + const workspaceConfig = { frame, snapshot }; + const workspace = ioc.getModel("workspace", workspaceConfig); + const windowParent = workspace.getBox((parent) => parent.id === payload.windowSummary.parentId); + const foundWindow = windowParent.children.find((child) => child.type === "window" && child.elementId === payload.windowSummary.itemId); + callback(foundWindow); + }; + const unsubscribe = await controller.processGlobalSubscription(wrappedCallback, "window", "selected"); + return unsubscribe; + }; + const waitForFrame = async (id) => { + nonEmptyStringDecoder.runWithException(id); + return new Promise((res, rej) => { + let unsub = () => { + }; + onFrameOpened((f) => { + if (f.id === id) { + res(f); + unsub(); + } + }).then((u) => { + unsub = u; + return getAllFrames(); + }).then((frames) => { + const myFrame = frames.find((f) => f.id === id); + if (myFrame) { + res(myFrame); + unsub(); + } + }).catch(rej); + }); + }; + return { + inWorkspace, + getBuilder, + getMyFrame, + getFrame, + getAllFrames, + getAllWorkspacesSummaries, + getMyWorkspace, + getWorkspace, + getWorkspaceById, + getAllWorkspaces, + getWindow, + getBox: getParent, + restoreWorkspace, + createWorkspace, + createEmptyFrame, + waitForFrame, + layouts, + onFrameOpened, + onFrameClosed, + onWorkspaceOpened, + onWorkspaceClosed, + onWorkspaceHibernated, + onWorkspaceResumed, + onWindowAdded, + onWindowLoaded, + onWindowRemoved, + onWindowMaximized, + onWindowRestored, + onWindowSelected, + version + }; + }; + + const factoryFunction = async (io) => { + const ioc = new IoC(io.agm, io.windows, io.layouts, io.contexts); + const actualWindowId = io.interop.instance.windowId; + await ioc.initiate(actualWindowId); + io.workspaces = composeAPI(io, ioc); + }; + if (typeof window !== "undefined") { + window.IOWorkspaces = factoryFunction; + } + + return factoryFunction; + +})); +//# sourceMappingURL=workspaces.umd.js.map diff --git a/typescript/start/clients/tsconfig.json b/typescript/start/clients/tsconfig.json new file mode 100644 index 0000000..11ec879 --- /dev/null +++ b/typescript/start/clients/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "./dist", + "rootDir": "./src" + }, + "include": ["./src", "../../types"] +} \ No newline at end of file diff --git a/typescript/start/clients/webpack.config.js b/typescript/start/clients/webpack.config.js new file mode 100644 index 0000000..cf31d79 --- /dev/null +++ b/typescript/start/clients/webpack.config.js @@ -0,0 +1,31 @@ +const path = require('path'); +const CopyWebpackPlugin = require('copy-webpack-plugin'); + +module.exports = { + mode: 'development', + entry: './src/index.ts', + module: { + rules: [ + { + test: /\.tsx?$/, + use: 'ts-loader', + exclude: /node_modules/, + }, + ], + }, + resolve: { + extensions: ['.tsx', '.ts', '.js'], + }, + output: { + filename: 'index.js', + path: path.resolve(__dirname, 'dist'), + }, + plugins: [ + new CopyWebpackPlugin({ + patterns: [ + { from: 'src/index.html', to: 'index.html' }, + { from: 'src/lib', to: 'lib' } + ], + }), + ], +}; \ No newline at end of file diff --git a/typescript/start/layouts/Client Space.json b/typescript/start/layouts/Client Space.json new file mode 100644 index 0000000..b4ef1a8 --- /dev/null +++ b/typescript/start/layouts/Client Space.json @@ -0,0 +1,63 @@ +{ + "name": "Client Space", + "type": "Workspace", + "metadata": {}, + "components": [ + { + "type": "Workspace", + "state": { + "children": [ + { + "type": "column", + "children": [ + { + "type": "row", + "children": [ + { + "type": "group", + "children": [ + { + "type": "window", + "config": { + "appName": "client-details", + "title": "Client Details" + } + } + ], + "config": {} + }, + { + "type": "column", + "children": [ + { + "type": "group", + "children": [ + { + "type": "window", + "config": { + "appName": "stocks", + "title": "Stocks" + } + } + ], + "config": {} + } + ], + "config": {} + } + ], + "config": {} + } + ], + "config": {} + } + ], + "config": { + "name": "Client Space", + "title": "Client Space" + }, + "context": {} + } + } + ] +} \ No newline at end of file diff --git a/typescript/start/package-lock.json b/typescript/start/package-lock.json new file mode 100644 index 0000000..44f0867 --- /dev/null +++ b/typescript/start/package-lock.json @@ -0,0 +1,1270 @@ +{ + "name": "ts-tutorial-start", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "ts-tutorial-start", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "concurrently": "^9.1.2", + "http-server": "^14.1.1" + }, + "devDependencies": { + "esbuild": "^0.20.1", + "typescript": "^5.3.3" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz", + "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz", + "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz", + "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz", + "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz", + "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz", + "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz", + "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz", + "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz", + "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz", + "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz", + "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz", + "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz", + "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz", + "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz", + "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz", + "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz", + "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz", + "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz", + "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz", + "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz", + "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz", + "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz", + "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/async": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", + "license": "MIT" + }, + "node_modules/basic-auth": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", + "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", + "license": "MIT", + "dependencies": { + "safe-buffer": "5.1.2" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chalk/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" + }, + "node_modules/concurrently": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-9.1.2.tgz", + "integrity": "sha512-H9MWcoPsYddwbOGM6difjVwVZHl63nwMEwDJG/L7VGtuaJhb12h2caPG2tVPWs7emuYix252iGfqOyrz1GczTQ==", + "license": "MIT", + "dependencies": { + "chalk": "^4.1.2", + "lodash": "^4.17.21", + "rxjs": "^7.8.1", + "shell-quote": "^1.8.1", + "supports-color": "^8.1.1", + "tree-kill": "^1.2.2", + "yargs": "^17.7.2" + }, + "bin": { + "conc": "dist/bin/concurrently.js", + "concurrently": "dist/bin/concurrently.js" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/open-cli-tools/concurrently?sponsor=1" + } + }, + "node_modules/corser": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/corser/-/corser-2.0.1.tgz", + "integrity": "sha512-utCYNzRSQIZNPIcGZdQc92UVJYAhtGAteCFg0yRaFm8f0P+CPtyGyHXJcGXnffjCybUCEx3FQ2G7U3/o9eIkVQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/debug": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", + "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/esbuild": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz", + "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.20.2", + "@esbuild/android-arm": "0.20.2", + "@esbuild/android-arm64": "0.20.2", + "@esbuild/android-x64": "0.20.2", + "@esbuild/darwin-arm64": "0.20.2", + "@esbuild/darwin-x64": "0.20.2", + "@esbuild/freebsd-arm64": "0.20.2", + "@esbuild/freebsd-x64": "0.20.2", + "@esbuild/linux-arm": "0.20.2", + "@esbuild/linux-arm64": "0.20.2", + "@esbuild/linux-ia32": "0.20.2", + "@esbuild/linux-loong64": "0.20.2", + "@esbuild/linux-mips64el": "0.20.2", + "@esbuild/linux-ppc64": "0.20.2", + "@esbuild/linux-riscv64": "0.20.2", + "@esbuild/linux-s390x": "0.20.2", + "@esbuild/linux-x64": "0.20.2", + "@esbuild/netbsd-x64": "0.20.2", + "@esbuild/openbsd-x64": "0.20.2", + "@esbuild/sunos-x64": "0.20.2", + "@esbuild/win32-arm64": "0.20.2", + "@esbuild/win32-ia32": "0.20.2", + "@esbuild/win32-x64": "0.20.2" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "license": "MIT" + }, + "node_modules/follow-redirects": { + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "license": "MIT", + "bin": { + "he": "bin/he" + } + }, + "node_modules/html-encoding-sniffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", + "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==", + "license": "MIT", + "dependencies": { + "whatwg-encoding": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "license": "MIT", + "dependencies": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/http-server": { + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/http-server/-/http-server-14.1.1.tgz", + "integrity": "sha512-+cbxadF40UXd9T01zUHgA+rlo2Bg1Srer4+B4NwIHdaGxAGGv59nYRnGGDJ9LBk7alpS0US+J+bLLdQOOkJq4A==", + "license": "MIT", + "dependencies": { + "basic-auth": "^2.0.1", + "chalk": "^4.1.2", + "corser": "^2.0.1", + "he": "^1.2.0", + "html-encoding-sniffer": "^3.0.0", + "http-proxy": "^1.18.1", + "mime": "^1.6.0", + "minimist": "^1.2.6", + "opener": "^1.5.1", + "portfinder": "^1.0.28", + "secure-compare": "3.0.1", + "union": "~0.5.0", + "url-join": "^4.0.1" + }, + "bin": { + "http-server": "bin/http-server" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "license": "MIT" + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/opener": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", + "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", + "license": "(WTFPL OR MIT)", + "bin": { + "opener": "bin/opener-bin.js" + } + }, + "node_modules/portfinder": { + "version": "1.0.37", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.37.tgz", + "integrity": "sha512-yuGIEjDAYnnOex9ddMnKZEMFE0CcGo6zbfzDklkmT1m5z734ss6JMzN9rNB3+RR7iS+F10D4/BVIaXOyh8PQKw==", + "license": "MIT", + "dependencies": { + "async": "^3.2.6", + "debug": "^4.3.6" + }, + "engines": { + "node": ">= 10.12" + } + }, + "node_modules/qs": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz", + "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==", + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "license": "MIT" + }, + "node_modules/rxjs": { + "version": "7.8.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", + "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" + }, + "node_modules/secure-compare": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/secure-compare/-/secure-compare-3.0.1.tgz", + "integrity": "sha512-AckIIV90rPDcBcglUwXPF3kg0P0qmPsPXAj6BBEENQE1p5yA1xfmDJzfi1Tappj37Pv2mVbKpL3Z1T+Nn7k1Qw==", + "license": "MIT" + }, + "node_modules/shell-quote": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.2.tgz", + "integrity": "sha512-AzqKpGKjrj7EM6rKVQEPpB288oCfnrEIuyoT9cyF4nmGa7V8Zk6f7RRqYisX8X9m+Q7bd632aZW4ky7EhbQztA==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "license": "MIT", + "bin": { + "tree-kill": "cli.js" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/typescript": { + "version": "5.8.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", + "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/union": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/union/-/union-0.5.0.tgz", + "integrity": "sha512-N6uOhuW6zO95P3Mel2I2zMsbsanvvtgn6jVqJv4vbVcz/JN0OkL9suomjQGmWtxJQXOCqUJvquc1sMeNz/IwlA==", + "dependencies": { + "qs": "^6.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/url-join": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz", + "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==", + "license": "MIT" + }, + "node_modules/whatwg-encoding": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz", + "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==", + "license": "MIT", + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "license": "ISC", + "engines": { + "node": ">=12" + } + } + } +} diff --git a/typescript/start/package.json b/typescript/start/package.json new file mode 100644 index 0000000..c8112ae --- /dev/null +++ b/typescript/start/package.json @@ -0,0 +1,28 @@ +{ + "name": "ts-tutorial-start", + "version": "1.0.0", + "description": "io.Connect Desktop TypeScript Tutorial - Start", + "scripts": { + "build": "npm run build:clients && npm run build:stocks && npm run build:client-details && npm run build:portfolio-downloader", + "build:clients": "node clients/esbuild.js", + "build:stocks": "node stocks/esbuild.js", + "build:client-details": "node client-details/esbuild.js", + "build:portfolio-downloader": "node portfolio-downloader/esbuild.js", + "start:clients": "http-server ./clients/dist -p 9000 -c-1", + "start:stocks": "http-server ./stocks/dist -p 9100 -c-1", + "start:clientDetails": "http-server ./client-details/dist -p 9200 -c-1", + "start:downloader": "http-server ./portfolio-downloader/dist -p 9300 -c-1", + "start": "concurrently \"npm run start:clients\" \"npm run start:stocks\" \"npm run start:clientDetails\" \"npm run start:downloader\"" + }, + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "concurrently": "^9.1.2", + "http-server": "^14.1.1" + }, + "devDependencies": { + "esbuild": "^0.20.1", + "typescript": "^5.3.3" + } +} \ No newline at end of file diff --git a/typescript/start/portfolio-downloader/esbuild.js b/typescript/start/portfolio-downloader/esbuild.js new file mode 100644 index 0000000..27c80dc --- /dev/null +++ b/typescript/start/portfolio-downloader/esbuild.js @@ -0,0 +1,48 @@ +const fs = require('fs'); +const path = require('path'); +const { build } = require('esbuild'); + +// Directory paths +const srcDir = path.join(__dirname, 'src'); +const distDir = path.join(__dirname, 'dist'); + +// Ensure dist directory exists +if (!fs.existsSync(distDir)) { + fs.mkdirSync(distDir, { recursive: true }); +} + +// Copy HTML file +fs.copyFileSync( + path.join(srcDir, 'index.html'), + path.join(distDir, 'index.html') +); + +// Copy lib directory +const libSrcDir = path.join(srcDir, 'lib'); +const libDistDir = path.join(distDir, 'lib'); + +if (!fs.existsSync(libDistDir)) { + fs.mkdirSync(libDistDir, { recursive: true }); +} + +fs.readdirSync(libSrcDir).forEach(file => { + fs.copyFileSync( + path.join(libSrcDir, file), + path.join(libDistDir, file) + ); +}); + +// Build with esbuild +build({ + entryPoints: [path.join(srcDir, 'index.ts')], + bundle: true, + outfile: path.join(distDir, 'index.js'), + platform: 'browser', + format: 'iife', + sourcemap: true, + target: ['es2020'], + tsconfig: path.join(__dirname, 'tsconfig.json'), +}).catch((error) => { + console.error(error); + process.exit(1); +}); \ No newline at end of file diff --git a/typescript/start/portfolio-downloader/src/index.html b/typescript/start/portfolio-downloader/src/index.html new file mode 100644 index 0000000..628a0c6 --- /dev/null +++ b/typescript/start/portfolio-downloader/src/index.html @@ -0,0 +1,41 @@ + + + + + + + + + + + + Portfolio Downloader + + + + + + + + + + +
+
+
+
+ io.Connect is unavailable +
+
+
+

Portfolio Downloader

+
+
+
+

+
+
+
+ + + \ No newline at end of file diff --git a/typescript/start/portfolio-downloader/src/index.ts b/typescript/start/portfolio-downloader/src/index.ts new file mode 100644 index 0000000..dcd8ab6 --- /dev/null +++ b/typescript/start/portfolio-downloader/src/index.ts @@ -0,0 +1,62 @@ +interface IntentContext { + data: { + clientName: string; + portfolio: Stock[]; + }; +} + +const intentHandler = (context: IntentContext | null): void => { + if (!context) { + return; + } + + setupTitle(context.data.clientName); + + const dataToWrite = JSON.stringify({ + date: new Date(Date.now()).toLocaleString("en-US"), + portfolio: context.data.portfolio + }, null, 4); + const blob = new Blob([dataToWrite], { type: "application/json" }); + const download = document.getElementById("download") as HTMLAnchorElement; + if (!download) return; + + const href = URL.createObjectURL(blob); + + download.href = href; + download.click(); + URL.revokeObjectURL(href); +}; + +const setupTitle = (clientName: string): void => { + const title = document.getElementById("portfolioName"); + if (!title) return; + + title.innerText = `Downloading the portfolio of ${clientName}...`; +}; + +// TODO: Chapter 3 +// const toggleIOAvailable = (): void => { +// const span = document.getElementById("ioConnectSpan"); +// if (!span) return; + +// span.classList.remove("bg-danger"); +// span.classList.add("bg-success"); +// span.textContent = "io.Connect is available"; +// }; + +async function start(): Promise { + // TODO: Chapter 3 + + // TODO: Chapter 12.1 + + // TODO: Chapter 10.1 +} + +// Add window properties when needed +declare global { + interface Window { + io?: IODesktopAPI; + } +} + +start().catch(console.error); \ No newline at end of file diff --git a/typescript/start/portfolio-downloader/src/lib/desktop.umd.js b/typescript/start/portfolio-downloader/src/lib/desktop.umd.js new file mode 100644 index 0000000..6cea2c9 --- /dev/null +++ b/typescript/start/portfolio-downloader/src/lib/desktop.umd.js @@ -0,0 +1,23144 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define(factory) : + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.desktop = factory()); +})(this, (function () { 'use strict'; + + var MetricTypes = { + STRING: 1, + NUMBER: 2, + TIMESTAMP: 3, + OBJECT: 4 + }; + + function getMetricTypeByValue(metric) { + if (metric.type === MetricTypes.TIMESTAMP) { + return "timestamp"; + } + else if (metric.type === MetricTypes.NUMBER) { + return "number"; + } + else if (metric.type === MetricTypes.STRING) { + return "string"; + } + else if (metric.type === MetricTypes.OBJECT) { + return "object"; + } + return "unknown"; + } + function getTypeByValue(value) { + if (value.constructor === Date) { + return "timestamp"; + } + else if (typeof value === "number") { + return "number"; + } + else if (typeof value === "string") { + return "string"; + } + else if (typeof value === "object") { + return "object"; + } + else { + return "string"; + } + } + function serializeMetric(metric) { + const serializedMetrics = {}; + const type = getMetricTypeByValue(metric); + if (type === "object") { + const values = Object.keys(metric.value).reduce((memo, key) => { + const innerType = getTypeByValue(metric.value[key]); + if (innerType === "object") { + const composite = defineNestedComposite(metric.value[key]); + memo[key] = { + type: "object", + description: "", + context: {}, + composite, + }; + } + else { + memo[key] = { + type: innerType, + description: "", + context: {}, + }; + } + return memo; + }, {}); + serializedMetrics.composite = values; + } + serializedMetrics.name = normalizeMetricName(metric.path.join("/") + "/" + metric.name); + serializedMetrics.type = type; + serializedMetrics.description = metric.description; + serializedMetrics.context = {}; + return serializedMetrics; + } + function defineNestedComposite(values) { + return Object.keys(values).reduce((memo, key) => { + const type = getTypeByValue(values[key]); + if (type === "object") { + memo[key] = { + type: "object", + description: "", + context: {}, + composite: defineNestedComposite(values[key]), + }; + } + else { + memo[key] = { + type, + description: "", + context: {}, + }; + } + return memo; + }, {}); + } + function normalizeMetricName(name) { + if (typeof name !== "undefined" && name.length > 0 && name[0] !== "/") { + return "/" + name; + } + else { + return name; + } + } + function getMetricValueByType(metric) { + const type = getMetricTypeByValue(metric); + if (type === "timestamp") { + return Date.now(); + } + else { + return publishNestedComposite(metric.value); + } + } + function publishNestedComposite(values) { + if (typeof values !== "object") { + return values; + } + return Object.keys(values).reduce((memo, key) => { + const value = values[key]; + if (typeof value === "object" && value.constructor !== Date) { + memo[key] = publishNestedComposite(value); + } + else if (value.constructor === Date) { + memo[key] = new Date(value).getTime(); + } + else if (value.constructor === Boolean) { + memo[key] = value.toString(); + } + else { + memo[key] = value; + } + return memo; + }, {}); + } + function flatten(arr) { + return arr.reduce((flat, toFlatten) => { + return flat.concat(Array.isArray(toFlatten) ? flatten(toFlatten) : toFlatten); + }, []); + } + function getHighestState(arr) { + return arr.sort((a, b) => { + if (!a.state) { + return 1; + } + if (!b.state) { + return -1; + } + return b.state - a.state; + })[0]; + } + function aggregateDescription(arr) { + let msg = ""; + arr.forEach((m, idx, a) => { + const path = m.path.join("."); + if (idx === a.length - 1) { + msg += path + "." + m.name + ": " + m.description; + } + else { + msg += path + "." + m.name + ": " + m.description + ","; + } + }); + if (msg.length > 100) { + return msg.slice(0, 100) + "..."; + } + else { + return msg; + } + } + function composeMsgForRootStateMetric(system) { + const aggregatedState = system.root.getAggregateState(); + const merged = flatten(aggregatedState); + const highestState = getHighestState(merged); + const aggregateDesc = aggregateDescription(merged); + return { + description: aggregateDesc, + value: highestState.state, + }; + } + + function gw3 (connection, config) { + if (!connection || typeof connection !== "object") { + throw new Error("Connection is required parameter"); + } + let joinPromise; + let session; + const init = (repo) => { + let resolveReadyPromise; + joinPromise = new Promise((resolve) => { + resolveReadyPromise = resolve; + }); + session = connection.domain("metrics"); + session.onJoined((reconnect) => { + if (!reconnect && resolveReadyPromise) { + resolveReadyPromise(); + resolveReadyPromise = undefined; + } + const rootStateMetric = { + name: "/State", + type: "object", + composite: { + Description: { + type: "string", + description: "", + }, + Value: { + type: "number", + description: "", + }, + }, + description: "System state", + context: {}, + }; + const defineRootMetricsMsg = { + type: "define", + metrics: [rootStateMetric], + }; + session.send(defineRootMetricsMsg); + if (reconnect) { + replayRepo(repo); + } + }); + session.join({ + system: config.system, + service: config.service, + instance: config.instance + }); + }; + const replayRepo = (repo) => { + replaySystem(repo.root); + }; + const replaySystem = (system) => { + createSystem(system); + system.metrics.forEach((m) => { + createMetric(m); + }); + system.subSystems.forEach((ss) => { + replaySystem(ss); + }); + }; + const createSystem = async (system) => { + if (system.parent === undefined) { + return; + } + await joinPromise; + const metric = { + name: normalizeMetricName(system.path.join("/") + "/" + system.name + "/State"), + type: "object", + composite: { + Description: { + type: "string", + description: "", + }, + Value: { + type: "number", + description: "", + }, + }, + description: "System state", + context: {}, + }; + const createMetricsMsg = { + type: "define", + metrics: [metric], + }; + session.send(createMetricsMsg); + }; + const updateSystem = async (system, state) => { + await joinPromise; + const shadowedUpdateMetric = { + type: "publish", + values: [{ + name: normalizeMetricName(system.path.join("/") + "/" + system.name + "/State"), + value: { + Description: state.description, + Value: state.state, + }, + timestamp: Date.now(), + }], + }; + session.send(shadowedUpdateMetric); + const stateObj = composeMsgForRootStateMetric(system); + const rootMetric = { + type: "publish", + peer_id: connection.peerId, + values: [{ + name: "/State", + value: { + Description: stateObj.description, + Value: stateObj.value, + }, + timestamp: Date.now(), + }], + }; + session.send(rootMetric); + }; + const createMetric = async (metric) => { + const metricClone = cloneMetric(metric); + await joinPromise; + const m = serializeMetric(metricClone); + const createMetricsMsg = { + type: "define", + metrics: [m], + }; + session.send(createMetricsMsg); + if (typeof metricClone.value !== "undefined") { + updateMetricCore(metricClone); + } + }; + const updateMetric = async (metric) => { + const metricClone = cloneMetric(metric); + await joinPromise; + updateMetricCore(metricClone); + }; + const updateMetricCore = (metric) => { + if (canUpdate()) { + const value = getMetricValueByType(metric); + const publishMetricsMsg = { + type: "publish", + values: [{ + name: normalizeMetricName(metric.path.join("/") + "/" + metric.name), + value, + timestamp: Date.now(), + }], + }; + return session.sendFireAndForget(publishMetricsMsg); + } + return Promise.resolve(); + }; + const cloneMetric = (metric) => { + const metricClone = { ...metric }; + if (typeof metric.value === "object" && metric.value !== null) { + metricClone.value = { ...metric.value }; + } + return metricClone; + }; + const canUpdate = () => { + try { + const func = config.canUpdateMetric ?? (() => true); + return func(); + } + catch { + return true; + } + }; + return { + init, + createSystem, + updateSystem, + createMetric, + updateMetric, + }; + } + + var Helpers = { + validate: (definition, parent, transport) => { + if (definition === null || typeof definition !== "object") { + throw new Error("Missing definition"); + } + if (parent === null || typeof parent !== "object") { + throw new Error("Missing parent"); + } + if (transport === null || typeof transport !== "object") { + throw new Error("Missing transport"); + } + }, + }; + + class BaseMetric { + definition; + system; + transport; + value; + type; + path = []; + name; + description; + get repo() { + return this.system?.repo; + } + get id() { return `${this.system.path}/${name}`; } + constructor(definition, system, transport, value, type) { + this.definition = definition; + this.system = system; + this.transport = transport; + this.value = value; + this.type = type; + Helpers.validate(definition, system, transport); + this.path = system.path.slice(0); + this.path.push(system.name); + this.name = definition.name; + this.description = definition.description; + transport.createMetric(this); + } + update(newValue) { + this.value = newValue; + return this.transport.updateMetric(this); + } + } + + class NumberMetric extends BaseMetric { + constructor(definition, system, transport, value) { + super(definition, system, transport, value, MetricTypes.NUMBER); + } + incrementBy(num) { + this.update(this.value + num); + } + increment() { + this.incrementBy(1); + } + decrement() { + this.incrementBy(-1); + } + decrementBy(num) { + this.incrementBy(num * -1); + } + } + + class ObjectMetric extends BaseMetric { + constructor(definition, system, transport, value) { + super(definition, system, transport, value, MetricTypes.OBJECT); + } + update(newValue) { + this.mergeValues(newValue); + return this.transport.updateMetric(this); + } + mergeValues(values) { + return Object.keys(this.value).forEach((k) => { + if (typeof values[k] !== "undefined") { + this.value[k] = values[k]; + } + }); + } + } + + class StringMetric extends BaseMetric { + constructor(definition, system, transport, value) { + super(definition, system, transport, value, MetricTypes.STRING); + } + } + + class TimestampMetric extends BaseMetric { + constructor(definition, system, transport, value) { + super(definition, system, transport, value, MetricTypes.TIMESTAMP); + } + now() { + this.update(new Date()); + } + } + + function system$1(name, repo, protocol, parent, description) { + if (!repo) { + throw new Error("Repository is required"); + } + if (!protocol) { + throw new Error("Transport is required"); + } + const _transport = protocol; + const _name = name; + const _description = description || ""; + const _repo = repo; + const _parent = parent; + const _path = _buildPath(parent); + let _state = {}; + const id = _arrayToString(_path, "/") + name; + const root = repo.root; + const _subSystems = []; + const _metrics = []; + function subSystem(nameSystem, descriptionSystem) { + if (!nameSystem || nameSystem.length === 0) { + throw new Error("name is required"); + } + const match = _subSystems.filter((s) => s.name === nameSystem); + if (match.length > 0) { + return match[0]; + } + const _system = system$1(nameSystem, _repo, _transport, me, descriptionSystem); + _subSystems.push(_system); + return _system; + } + function setState(state, stateDescription) { + _state = { state, description: stateDescription }; + _transport.updateSystem(me, _state); + } + function stringMetric(definition, value) { + return _getOrCreateMetric(definition, MetricTypes.STRING, value, (metricDef) => new StringMetric(metricDef, me, _transport, value)); + } + function numberMetric(definition, value) { + return _getOrCreateMetric(definition, MetricTypes.NUMBER, value, (metricDef) => new NumberMetric(metricDef, me, _transport, value)); + } + function objectMetric(definition, value) { + return _getOrCreateMetric(definition, MetricTypes.OBJECT, value, (metricDef) => new ObjectMetric(metricDef, me, _transport, value)); + } + function timestampMetric(definition, value) { + return _getOrCreateMetric(definition, MetricTypes.TIMESTAMP, value, (metricDef) => new TimestampMetric(metricDef, me, _transport, value)); + } + function _getOrCreateMetric(metricObject, expectedType, value, createMetric) { + let metricDef = { name: "" }; + if (typeof metricObject === "string") { + metricDef = { name: metricObject }; + } + else { + metricDef = metricObject; + } + const matching = _metrics.filter((shadowedMetric) => shadowedMetric.name === metricDef.name); + if (matching.length > 0) { + const existing = matching[0]; + if (existing.type !== expectedType) { + throw new Error(`A metric named ${metricDef.name} is already defined with different type.`); + } + if (typeof value !== "undefined") { + existing + .update(value) + .catch(() => { }); + } + return existing; + } + const metric = createMetric(metricDef); + _metrics.push(metric); + return metric; + } + function _buildPath(shadowedSystem) { + if (!shadowedSystem || !shadowedSystem.parent) { + return []; + } + const path = _buildPath(shadowedSystem.parent); + path.push(shadowedSystem.name); + return path; + } + function _arrayToString(path, separator) { + return ((path && path.length > 0) ? path.join(separator) : ""); + } + function getAggregateState() { + const aggState = []; + if (Object.keys(_state).length > 0) { + aggState.push({ + name: _name, + path: _path, + state: _state.state, + description: _state.description, + }); + } + _subSystems.forEach((shadowedSubSystem) => { + const result = shadowedSubSystem.getAggregateState(); + if (result.length > 0) { + aggState.push(...result); + } + }); + return aggState; + } + const me = { + get name() { + return _name; + }, + get description() { + return _description; + }, + get repo() { + return _repo; + }, + get parent() { + return _parent; + }, + path: _path, + id, + root, + get subSystems() { + return _subSystems; + }, + get metrics() { + return _metrics; + }, + subSystem, + getState: () => { + return _state; + }, + setState, + stringMetric, + timestampMetric, + objectMetric, + numberMetric, + getAggregateState, + }; + _transport.createSystem(me); + return me; + } + + class Repository { + root; + constructor(options, protocol) { + protocol.init(this); + this.root = system$1("", this, protocol); + this.addSystemMetrics(this.root, options.clickStream || options.clickStream === undefined); + } + addSystemMetrics(rootSystem, useClickStream) { + if (typeof navigator !== "undefined") { + rootSystem.stringMetric("UserAgent", navigator.userAgent); + } + if (useClickStream && typeof document !== "undefined") { + const clickStream = rootSystem.subSystem("ClickStream"); + const documentClickHandler = (e) => { + if (!e.target) { + return; + } + const target = e.target; + const className = target ? target.getAttribute("class") ?? "" : ""; + clickStream.objectMetric("LastBrowserEvent", { + type: "click", + timestamp: new Date(), + target: { + className, + id: target.id, + type: "<" + target.tagName.toLowerCase() + ">", + href: target.href || "", + }, + }); + }; + clickStream.objectMetric("Page", { + title: document.title, + page: window.location.href, + }); + if (document.addEventListener) { + document.addEventListener("click", documentClickHandler); + } + else { + document.attachEvent("onclick", documentClickHandler); + } + } + rootSystem.stringMetric("StartTime", (new Date()).toString()); + const urlMetric = rootSystem.stringMetric("StartURL", ""); + const appNameMetric = rootSystem.stringMetric("AppName", ""); + if (typeof window !== "undefined") { + if (typeof window.location !== "undefined") { + const startUrl = window.location.href; + urlMetric.update(startUrl); + } + if (typeof window.glue42gd !== "undefined") { + appNameMetric.update(window.glue42gd.appName); + } + } + } + } + + class NullProtocol { + init(repo) { + } + createSystem(system) { + return Promise.resolve(); + } + updateSystem(metric, state) { + return Promise.resolve(); + } + createMetric(metric) { + return Promise.resolve(); + } + updateMetric(metric) { + return Promise.resolve(); + } + } + + class PerfTracker { + api; + lastCount = 0; + initialPublishTimeout = 10 * 1000; + publishInterval = 60 * 1000; + system; + constructor(api, initialPublishTimeout, publishInterval) { + this.api = api; + this.initialPublishTimeout = initialPublishTimeout ?? this.initialPublishTimeout; + this.publishInterval = publishInterval ?? this.publishInterval; + this.scheduleCollection(); + this.system = this.api.subSystem("performance", "Performance data published by the web application"); + } + scheduleCollection() { + setTimeout(() => { + this.collect(); + setInterval(() => { + this.collect(); + }, this.publishInterval); + }, this.initialPublishTimeout); + } + collect() { + try { + this.collectMemory(); + this.collectEntries(); + } + catch { + } + } + collectMemory() { + const memory = window.performance.memory; + this.system.stringMetric("memory", JSON.stringify({ + totalJSHeapSize: memory.totalJSHeapSize, + usedJSHeapSize: memory.usedJSHeapSize + })); + } + collectEntries() { + const allEntries = window.performance.getEntries(); + if (allEntries.length <= this.lastCount) { + return; + } + this.lastCount = allEntries.length; + const jsonfiedEntries = allEntries.map((i) => i.toJSON()); + this.system.stringMetric("entries", JSON.stringify(jsonfiedEntries)); + } + } + + var metrics = (options) => { + let protocol; + if (!options.connection || typeof options.connection !== "object") { + protocol = new NullProtocol(); + } + else { + protocol = gw3(options.connection, options); + } + const repo = new Repository(options, protocol); + let rootSystem = repo.root; + if (!options.disableAutoAppSystem) { + rootSystem = rootSystem.subSystem("App"); + } + const api = addFAVSupport(rootSystem); + initPerf(api, options.pagePerformanceMetrics); + return api; + }; + function initPerf(api, config) { + if (typeof window === "undefined") { + return; + } + const perfConfig = window?.glue42gd?.metrics?.pagePerformanceMetrics; + if (perfConfig) { + config = perfConfig; + } + if (config?.enabled) { + new PerfTracker(api, config.initialPublishTimeout, config.publishInterval); + } + } + function addFAVSupport(system) { + const reportingSystem = system.subSystem("reporting"); + const def = { + name: "features" + }; + let featureMetric; + const featureMetricFunc = (name, action, payload) => { + if (typeof name === "undefined" || name === "") { + throw new Error("name is mandatory"); + } + else if (typeof action === "undefined" || action === "") { + throw new Error("action is mandatory"); + } + else if (typeof payload === "undefined" || payload === "") { + throw new Error("payload is mandatory"); + } + if (!featureMetric) { + featureMetric = reportingSystem.objectMetric(def, { name, action, payload }); + } + else { + featureMetric.update({ + name, + action, + payload + }); + } + }; + system.featureMetric = featureMetricFunc; + return system; + } + + var commonjsGlobal$1 = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; + + function getDefaultExportFromCjs$1 (x) { + return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; + } + + function createRegistry$1(options) { + if (options && options.errorHandling + && typeof options.errorHandling !== "function" + && options.errorHandling !== "log" + && options.errorHandling !== "silent" + && options.errorHandling !== "throw") { + throw new Error("Invalid options passed to createRegistry. Prop errorHandling should be [\"log\" | \"silent\" | \"throw\" | (err) => void], but " + typeof options.errorHandling + " was passed"); + } + var _userErrorHandler = options && typeof options.errorHandling === "function" && options.errorHandling; + var callbacks = {}; + function add(key, callback, replayArgumentsArr) { + var callbacksForKey = callbacks[key]; + if (!callbacksForKey) { + callbacksForKey = []; + callbacks[key] = callbacksForKey; + } + callbacksForKey.push(callback); + if (replayArgumentsArr) { + setTimeout(function () { + replayArgumentsArr.forEach(function (replayArgument) { + var _a; + if ((_a = callbacks[key]) === null || _a === void 0 ? void 0 : _a.includes(callback)) { + try { + if (Array.isArray(replayArgument)) { + callback.apply(undefined, replayArgument); + } + else { + callback.apply(undefined, [replayArgument]); + } + } + catch (err) { + _handleError(err, key); + } + } + }); + }, 0); + } + return function () { + var allForKey = callbacks[key]; + if (!allForKey) { + return; + } + allForKey = allForKey.reduce(function (acc, element, index) { + if (!(element === callback && acc.length === index)) { + acc.push(element); + } + return acc; + }, []); + if (allForKey.length === 0) { + delete callbacks[key]; + } + else { + callbacks[key] = allForKey; + } + }; + } + function execute(key) { + var argumentsArr = []; + for (var _i = 1; _i < arguments.length; _i++) { + argumentsArr[_i - 1] = arguments[_i]; + } + var callbacksForKey = callbacks[key]; + if (!callbacksForKey || callbacksForKey.length === 0) { + return []; + } + var results = []; + callbacksForKey.forEach(function (callback) { + try { + var result = callback.apply(undefined, argumentsArr); + results.push(result); + } + catch (err) { + results.push(undefined); + _handleError(err, key); + } + }); + return results; + } + function _handleError(exceptionArtifact, key) { + var errParam = exceptionArtifact instanceof Error ? exceptionArtifact : new Error(exceptionArtifact); + if (_userErrorHandler) { + _userErrorHandler(errParam); + return; + } + var msg = "[ERROR] callback-registry: User callback for key \"" + key + "\" failed: " + errParam.stack; + if (options) { + switch (options.errorHandling) { + case "log": + return console.error(msg); + case "silent": + return; + case "throw": + throw new Error(msg); + } + } + console.error(msg); + } + function clear() { + callbacks = {}; + } + function clearKey(key) { + var callbacksForKey = callbacks[key]; + if (!callbacksForKey) { + return; + } + delete callbacks[key]; + } + return { + add: add, + execute: execute, + clear: clear, + clearKey: clearKey + }; + } + createRegistry$1.default = createRegistry$1; + var lib$1 = createRegistry$1; + + + var CallbackRegistryFactory$1 = /*@__PURE__*/getDefaultExportFromCjs$1(lib$1); + + class InProcTransport { + gw; + registry = CallbackRegistryFactory$1(); + client; + constructor(settings, logger) { + this.gw = settings.facade; + this.gw.connect((_client, message) => { + this.messageHandler(message); + }).then((client) => { + this.client = client; + }); + } + get isObjectBasedTransport() { + return true; + } + sendObject(msg) { + if (this.client) { + this.client.send(msg); + return Promise.resolve(undefined); + } + else { + return Promise.reject(`not connected`); + } + } + send(_msg) { + return Promise.reject("not supported"); + } + onMessage(callback) { + return this.registry.add("onMessage", callback); + } + onConnectedChanged(callback) { + callback(true); + return () => { }; + } + close() { + return Promise.resolve(); + } + open() { + return Promise.resolve(); + } + name() { + return "in-memory"; + } + reconnect() { + return Promise.resolve(); + } + messageHandler(msg) { + this.registry.execute("onMessage", msg); + } + } + + class SharedWorkerTransport { + logger; + worker; + registry = CallbackRegistryFactory$1(); + constructor(workerFile, logger) { + this.logger = logger; + this.worker = new SharedWorker(workerFile); + this.worker.port.onmessage = (e) => { + this.messageHandler(e.data); + }; + } + get isObjectBasedTransport() { + return true; + } + sendObject(msg) { + this.worker.port.postMessage(msg); + return Promise.resolve(); + } + send(_msg) { + return Promise.reject("not supported"); + } + onMessage(callback) { + return this.registry.add("onMessage", callback); + } + onConnectedChanged(callback) { + callback(true); + return () => { }; + } + close() { + return Promise.resolve(); + } + open() { + return Promise.resolve(); + } + name() { + return "shared-worker"; + } + reconnect() { + return Promise.resolve(); + } + messageHandler(msg) { + this.registry.execute("onMessage", msg); + } + } + + let Utils$1 = class Utils { + static isNode() { + if (typeof Utils._isNode !== "undefined") { + return Utils._isNode; + } + if (typeof window !== "undefined") { + Utils._isNode = false; + return false; + } + try { + Utils._isNode = Object.prototype.toString.call(global.process) === "[object process]"; + } + catch (e) { + Utils._isNode = false; + } + return Utils._isNode; + } + static _isNode; + }; + + let PromiseWrapper$1 = class PromiseWrapper { + static delay(time) { + return new Promise((resolve) => setTimeout(resolve, time)); + } + resolve; + reject; + promise; + rejected = false; + resolved = false; + get ended() { + return this.rejected || this.resolved; + } + constructor() { + this.promise = new Promise((resolve, reject) => { + this.resolve = (t) => { + this.resolved = true; + resolve(t); + }; + this.reject = (err) => { + this.rejected = true; + reject(err); + }; + }); + } + }; + + const timers = {}; + function getAllTimers() { + return timers; + } + function timer (timerName) { + const existing = timers[timerName]; + if (existing) { + return existing; + } + const marks = []; + function now() { + return new Date().getTime(); + } + const startTime = now(); + mark("start", startTime); + let endTime; + let period; + function stop() { + endTime = now(); + mark("end", endTime); + period = endTime - startTime; + return period; + } + function mark(name, time) { + const currentTime = time ?? now(); + let diff = 0; + if (marks.length > 0) { + diff = currentTime - marks[marks.length - 1].time; + } + marks.push({ name, time: currentTime, diff }); + } + const timerObj = { + get startTime() { + return startTime; + }, + get endTime() { + return endTime; + }, + get period() { + return period; + }, + stop, + mark, + marks + }; + timers[timerName] = timerObj; + return timerObj; + } + + const WebSocketConstructor = Utils$1.isNode() ? require("ws") : window.WebSocket; + class WS { + ws; + logger; + settings; + startupTimer = timer("connection"); + _running = true; + _registry = CallbackRegistryFactory$1(); + wsRequests = []; + constructor(settings, logger) { + this.settings = settings; + this.logger = logger; + if (!this.settings.ws) { + throw new Error("ws is missing"); + } + } + onMessage(callback) { + return this._registry.add("onMessage", callback); + } + send(msg, options) { + return new Promise((resolve, reject) => { + this.waitForSocketConnection(() => { + try { + this.ws?.send(msg); + resolve(); + } + catch (e) { + reject(e); + } + }, reject); + }); + } + open() { + this.logger.info("opening ws..."); + this._running = true; + return new Promise((resolve, reject) => { + this.waitForSocketConnection(resolve, reject); + }); + } + close() { + this._running = false; + if (this.ws) { + this.ws.close(); + } + return Promise.resolve(); + } + onConnectedChanged(callback) { + return this._registry.add("onConnectedChanged", callback); + } + name() { + return this.settings.ws; + } + reconnect() { + this.ws?.close(); + const pw = new PromiseWrapper$1(); + this.waitForSocketConnection(() => { + pw.resolve(); + }); + return pw.promise; + } + waitForSocketConnection(callback, failed) { + failed = failed ?? (() => { }); + if (!this._running) { + failed(`wait for socket on ${this.settings.ws} failed - socket closed by user`); + return; + } + if (this.ws?.readyState === 1) { + callback(); + return; + } + this.wsRequests.push({ callback, failed }); + if (this.wsRequests.length > 1) { + return; + } + this.openSocket(); + } + async openSocket(retryInterval, retriesLeft) { + this.logger.info(`opening ws to ${this.settings.ws}, retryInterval: ${retryInterval}, retriesLeft: ${retriesLeft}...`); + this.startupTimer.mark("opening-socket"); + if (retryInterval === undefined) { + retryInterval = this.settings.reconnectInterval; + } + if (typeof retriesLeft === "undefined") { + retriesLeft = this.settings.reconnectAttempts; + } + if (retriesLeft !== undefined) { + if (retriesLeft === 0) { + this.notifyForSocketState(`wait for socket on ${this.settings.ws} failed - no more retries left`); + return; + } + this.logger.debug(`will retry ${retriesLeft} more times (every ${retryInterval} ms)`); + } + try { + await this.initiateSocket(); + this.startupTimer.mark("socket-initiated"); + this.notifyForSocketState(); + } + catch { + setTimeout(() => { + const retries = retriesLeft === undefined ? undefined : retriesLeft - 1; + this.openSocket(retryInterval, retries); + }, retryInterval); + } + } + initiateSocket() { + const pw = new PromiseWrapper$1(); + this.logger.debug(`initiating ws to ${this.settings.ws}...`); + this.ws = new WebSocketConstructor(this.settings.ws ?? ""); + this.ws.onerror = (err) => { + let reason = ""; + try { + reason = JSON.stringify(err); + } + catch (error) { + const seen = new WeakSet(); + const replacer = (key, value) => { + if (typeof value === "object" && value !== null) { + if (seen.has(value)) { + return; + } + seen.add(value); + } + return value; + }; + reason = JSON.stringify(err, replacer); + } + this.logger.info(`ws error - reason: ${reason}`); + pw.reject("error"); + this.notifyStatusChanged(false, reason); + }; + this.ws.onclose = (err) => { + this.logger.info(`ws closed - code: ${err?.code} reason: ${err?.reason}`); + pw.reject("closed"); + this.notifyStatusChanged(false); + }; + this.ws.onopen = () => { + this.startupTimer.mark("ws-opened"); + this.logger.info(`ws opened ${this.settings.identity?.application}`); + pw.resolve(); + this.notifyStatusChanged(true); + }; + this.ws.onmessage = (message) => { + this._registry.execute("onMessage", message.data); + }; + return pw.promise; + } + notifyForSocketState(error) { + this.wsRequests.forEach((wsRequest) => { + if (error) { + if (wsRequest.failed) { + wsRequest.failed(error); + } + } + else { + wsRequest.callback(); + } + }); + this.wsRequests = []; + } + notifyStatusChanged(status, reason) { + this._registry.execute("onConnectedChanged", status, reason); + } + } + + class MessageReplayerImpl { + specs; + specsNames = []; + messages = {}; + isDone; + subs = {}; + subsRefCount = {}; + connection; + constructor(specs) { + this.specs = {}; + for (const spec of specs) { + this.specs[spec.name] = spec; + this.specsNames.push(spec.name); + } + } + init(connection) { + this.connection = connection; + for (const name of this.specsNames) { + for (const type of this.specs[name].types) { + let refCount = this.subsRefCount[type]; + if (!refCount) { + refCount = 0; + } + refCount += 1; + this.subsRefCount[type] = refCount; + if (refCount > 1) { + continue; + } + const sub = connection.on(type, (msg) => this.processMessage(type, msg)); + this.subs[type] = sub; + } + } + } + processMessage(type, msg) { + if (this.isDone || !msg) { + return; + } + for (const name of this.specsNames) { + if (this.specs[name].types.indexOf(type) !== -1) { + const messages = this.messages[name] || []; + this.messages[name] = messages; + messages.push(msg); + } + } + } + drain(name, callback) { + if (callback) { + (this.messages[name] || []).forEach(callback); + } + delete this.messages[name]; + for (const type of this.specs[name].types) { + this.subsRefCount[type] -= 1; + if (this.subsRefCount[type] <= 0) { + this.connection?.off(this.subs[type]); + delete this.subs[type]; + delete this.subsRefCount[type]; + } + } + delete this.specs[name]; + if (!this.specs.length) { + this.isDone = true; + } + } + } + + let urlAlphabet$1 = + 'useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict'; + let nanoid$1 = (size = 21) => { + let id = ''; + let i = size; + while (i--) { + id += urlAlphabet$1[(Math.random() * 64) | 0]; + } + return id + }; + + const PromisePlus$1 = (executor, timeoutMilliseconds, timeoutMessage) => { + return new Promise((resolve, reject) => { + const timeout = setTimeout(() => { + const message = timeoutMessage || `Promise timeout hit: ${timeoutMilliseconds}`; + reject(message); + }, timeoutMilliseconds); + const providedPromise = new Promise(executor); + providedPromise + .then((result) => { + clearTimeout(timeout); + resolve(result); + }) + .catch((error) => { + clearTimeout(timeout); + reject(error); + }); + }); + }; + + class WebPlatformTransport { + settings; + logger; + identity; + isPreferredActivated; + _communicationId; + publicWindowId; + selfAssignedWindowId; + iAmConnected = false; + parentReady = false; + rejected = false; + parentPingResolve; + parentPingInterval; + connectionResolve; + extConnectionResolve; + extConnectionReject; + connectionReject; + port; + myClientId; + children = []; + extContentAvailable = false; + extContentConnecting = false; + extContentConnected = false; + parentWindowId; + parentInExtMode = false; + webNamespace = "g42_core_web"; + parent; + parentType; + parentPingTimeout = 5000; + connectionRequestTimeout = 7000; + defaultTargetString = "*"; + registry = CallbackRegistryFactory$1(); + messages = { + connectionAccepted: { name: "connectionAccepted", handle: this.handleConnectionAccepted.bind(this) }, + connectionRejected: { name: "connectionRejected", handle: this.handleConnectionRejected.bind(this) }, + connectionRequest: { name: "connectionRequest", handle: this.handleConnectionRequest.bind(this) }, + parentReady: { + name: "parentReady", handle: () => { + } + }, + parentPing: { name: "parentPing", handle: this.handleParentPing.bind(this) }, + platformPing: { name: "platformPing", handle: this.handlePlatformPing.bind(this) }, + platformReady: { name: "platformReady", handle: this.handlePlatformReady.bind(this) }, + clientUnload: { name: "clientUnload", handle: this.handleClientUnload.bind(this) }, + manualUnload: { name: "manualUnload", handle: this.handleManualUnload.bind(this) }, + extConnectionResponse: { name: "extConnectionResponse", handle: this.handleExtConnectionResponse.bind(this) }, + extSetupRequest: { name: "extSetupRequest", handle: this.handleExtSetupRequest.bind(this) }, + gatewayDisconnect: { name: "gatewayDisconnect", handle: this.handleGatewayDisconnect.bind(this) }, + gatewayInternalConnect: { name: "gatewayInternalConnect", handle: this.handleGatewayInternalConnect.bind(this) } + }; + constructor(settings, logger, identity) { + this.settings = settings; + this.logger = logger; + this.identity = identity; + this.extContentAvailable = !!window.glue42ext; + this.setUpMessageListener(); + this.setUpUnload(); + this.setupPlatformUnloadListener(); + this.parentType = window.name.includes("#wsp") ? "workspace" : undefined; + } + manualSetReadyState() { + this.iAmConnected = true; + this.parentReady = true; + } + get transportWindowId() { + return this.publicWindowId; + } + get communicationId() { + return this._communicationId; + } + async sendObject(msg) { + if (this.extContentConnected) { + return window.postMessage({ glue42ExtOut: msg }, this.defaultTargetString); + } + if (!this.port) { + throw new Error("Cannot send message, because the port was not opened yet"); + } + this.port.postMessage(msg); + } + get isObjectBasedTransport() { + return true; + } + onMessage(callback) { + return this.registry.add("onMessage", callback); + } + send() { + return Promise.reject("not supported"); + } + onConnectedChanged(callback) { + return this.registry.add("onConnectedChanged", callback); + } + async open() { + this.logger.debug("opening a connection to the web platform gateway."); + await this.connect(); + this.notifyStatusChanged(true); + } + close() { + const message = { + glue42core: { + type: this.messages.gatewayDisconnect.name, + data: { + clientId: this.myClientId, + ownWindowId: this.identity?.windowId + } + } + }; + this.port?.postMessage(message); + this.parentReady = false; + this.notifyStatusChanged(false, "manual reconnection"); + return Promise.resolve(); + } + name() { + return "web-platform"; + } + async reconnect() { + await this.close(); + return Promise.resolve(); + } + initiateInternalConnection() { + return new Promise((resolve, reject) => { + this.logger.debug("opening an internal web platform connection"); + this.port = this.settings.port; + if (this.iAmConnected) { + this.logger.warn("cannot open a new connection, because this client is currently connected"); + return; + } + this.port.onmessage = (event) => { + if (this.iAmConnected && !event.data?.glue42core) { + this.registry.execute("onMessage", event.data); + return; + } + const data = event.data?.glue42core; + if (!data) { + return; + } + if (data.type === this.messages.gatewayInternalConnect.name && data.success) { + this.publicWindowId = this.settings.windowId; + if (this.identity && this.publicWindowId) { + this.identity.windowId = this.publicWindowId; + this.identity.instance = this.publicWindowId; + } + resolve(); + } + if (data.type === this.messages.gatewayInternalConnect.name && data.error) { + reject(data.error); + } + }; + this.port.postMessage({ + glue42core: { + type: this.messages.gatewayInternalConnect.name + } + }); + }); + } + initiateRemoteConnection(target) { + return PromisePlus$1((resolve, reject) => { + this.connectionResolve = resolve; + this.connectionReject = reject; + this.myClientId = this.myClientId ?? nanoid$1(10); + const bridgeInstanceId = this.getMyWindowId() || nanoid$1(10); + const request = { + glue42core: { + type: this.messages.connectionRequest.name, + clientId: this.myClientId, + clientType: "child", + bridgeInstanceId, + selfAssignedWindowId: this.selfAssignedWindowId + } + }; + this.logger.debug("sending connection request"); + if (this.extContentConnecting) { + request.glue42core.clientType = "child"; + request.glue42core.bridgeInstanceId = this.myClientId; + request.glue42core.parentWindowId = this.parentWindowId; + return window.postMessage(request, this.defaultTargetString); + } + if (!target) { + throw new Error("Cannot send a connection request, because no glue target was specified!"); + } + target.postMessage(request, this.defaultTargetString); + }, this.connectionRequestTimeout, "The connection to the target glue window timed out"); + } + async isParentCheckSuccess(parentCheck) { + try { + await parentCheck; + return { success: true }; + } + catch (error) { + return { success: false }; + } + } + setUpMessageListener() { + if (this.settings.port) { + this.logger.debug("skipping generic message listener, because this is an internal client"); + return; + } + window.addEventListener("message", (event) => { + const data = event.data?.glue42core; + if (!data || this.rejected) { + return; + } + const allowedOrigins = this.settings.allowedOrigins || []; + if (allowedOrigins.length && !allowedOrigins.includes(event.origin)) { + this.logger.warn(`received a message from an origin which is not in the allowed list: ${event.origin}`); + return; + } + if (!this.checkMessageTypeValid(data.type)) { + this.logger.error(`cannot handle the incoming glue42 core message, because the type is invalid: ${data.type}`); + return; + } + const messageType = data.type; + this.logger.debug(`received valid glue42core message of type: ${messageType}`); + this.messages[messageType].handle(event); + }); + } + setUpUnload() { + if (this.settings.port) { + this.logger.debug("skipping unload event listener, because this is an internal client"); + return; + } + window.addEventListener("beforeunload", () => { + if (this.extContentConnected) { + return; + } + const message = { + glue42core: { + type: this.messages.clientUnload.name, + data: { + clientId: this.myClientId, + ownWindowId: this.identity?.windowId + } + } + }; + if (this.parent) { + this.parent.postMessage(message, this.defaultTargetString); + } + this.port?.postMessage(message); + }); + } + handlePlatformReady(event) { + this.logger.debug("the web platform gave the ready signal"); + this.parentReady = true; + if (this.parentPingResolve) { + this.parentPingResolve(); + delete this.parentPingResolve; + } + if (this.parentPingInterval) { + clearInterval(this.parentPingInterval); + delete this.parentPingInterval; + } + this.parent = event.source; + this.parentType = window.name.includes("#wsp") ? "workspace" : "window"; + } + handleConnectionAccepted(event) { + const data = event.data?.glue42core; + if (this.myClientId === data.clientId) { + return this.handleAcceptanceOfMyRequest(data); + } + return this.handleAcceptanceOfGrandChildRequest(data, event); + } + handleAcceptanceOfMyRequest(data) { + this.logger.debug("handling a connection accepted signal targeted at me."); + this.isPreferredActivated = data.isPreferredActivated; + if (this.extContentConnecting) { + return this.processExtContentConnection(data); + } + if (!data.port) { + this.logger.error("cannot set up my connection, because I was not provided with a port"); + return; + } + this.publicWindowId = this.getMyWindowId(); + if (this.identity) { + this.identity.windowId = this.publicWindowId; + this.identity.instance = this.identity.instance ? this.identity.instance : this.publicWindowId || nanoid$1(10); + } + if (this.identity && data.appName) { + this.identity.application = data.appName; + this.identity.applicationName = data.appName; + } + this._communicationId = data.communicationId; + this.port = data.port; + this.port.onmessage = (e) => this.registry.execute("onMessage", e.data); + if (this.connectionResolve) { + this.logger.debug("my connection is set up, calling the connection resolve."); + this.connectionResolve(); + delete this.connectionResolve; + return; + } + this.logger.error("unable to call the connection resolve, because no connection promise was found"); + } + processExtContentConnection(data) { + this.logger.debug("handling a connection accepted signal targeted at me for extension content connection."); + this.extContentConnecting = false; + this.extContentConnected = true; + this.publicWindowId = this.parentWindowId || this.myClientId; + if (this.extContentConnecting && this.identity) { + this.identity.windowId = this.publicWindowId; + } + if (this.identity && data.appName) { + this.identity.application = data.appName; + this.identity.applicationName = data.appName; + } + window.addEventListener("message", (event) => { + const extData = event.data?.glue42ExtInc; + if (!extData) { + return; + } + const allowedOrigins = this.settings.allowedOrigins || []; + if (allowedOrigins.length && !allowedOrigins.includes(event.origin)) { + this.logger.warn(`received a message from an origin which is not in the allowed list: ${event.origin}`); + return; + } + this.registry.execute("onMessage", extData); + }); + if (this.connectionResolve) { + this.logger.debug("my connection is set up, calling the connection resolve."); + this.connectionResolve(); + delete this.connectionResolve; + return; + } + } + handleAcceptanceOfGrandChildRequest(data, event) { + if (this.extContentConnecting || this.extContentConnected) { + this.logger.debug("cannot process acceptance of a grandchild, because I am connected to a content script"); + return; + } + this.logger.debug(`handling a connection accepted signal targeted at a grandchild: ${data.clientId}`); + const child = this.children.find((c) => c.grandChildId === data.clientId); + if (!child) { + this.logger.error(`cannot handle connection accepted for grandchild: ${data.clientId}, because there is no grandchild with this id`); + return; + } + child.connected = true; + this.logger.debug(`the grandchild connection for ${data.clientId} is set up, forwarding the success message and the gateway port`); + data.parentWindowId = this.publicWindowId; + child.source.postMessage(event.data, child.origin, [data.port]); + return; + } + handleConnectionRejected(event) { + this.logger.debug("handling a connection rejection. Most likely the reason is that this window was not created by a glue API call"); + if (!this.connectionReject) { + return; + } + const errorMsg = typeof event.data.glue42core?.error === "string" + ? `Connection was rejected. ${event.data.glue42core?.error}` + : "The platform connection was rejected. Most likely because this window was not created by a glue API call"; + this.connectionReject(errorMsg); + delete this.connectionReject; + } + handleConnectionRequest(event) { + if (this.extContentConnecting) { + this.logger.debug("This connection request event is targeted at the extension content"); + return; + } + const source = event.source; + const data = event.data.glue42core; + if (!data.clientType || data.clientType !== "grandChild") { + return this.rejectConnectionRequest(source, event.origin, "rejecting a connection request, because the source was not opened by a glue API call"); + } + if (!data.clientId) { + return this.rejectConnectionRequest(source, event.origin, "rejecting a connection request, because the source did not provide a valid id"); + } + if (!this.parent) { + return this.rejectConnectionRequest(source, event.origin, "Cannot forward the connection request, because no direct connection to the platform was found"); + } + this.logger.debug(`handling a connection request for a grandchild: ${data.clientId}`); + this.children.push({ grandChildId: data.clientId, source, connected: false, origin: event.origin }); + this.logger.debug(`grandchild: ${data.clientId} is prepared, forwarding connection request to the platform`); + this.parent.postMessage(event.data, this.defaultTargetString); + } + handleParentPing(event) { + if (!this.parentReady) { + this.logger.debug("my parent is not ready, I am ignoring the parent ping"); + return; + } + if (!this.iAmConnected) { + this.logger.debug("i am not fully connected yet, I am ignoring the parent ping"); + return; + } + const message = { + glue42core: { + type: this.messages.parentReady.name + } + }; + if (this.extContentConnected) { + message.glue42core.extMode = { windowId: this.myClientId }; + } + const source = event.source; + this.logger.debug("responding to a parent ping with a ready message"); + source.postMessage(message, event.origin); + } + setupPlatformUnloadListener() { + this.onMessage((msg) => { + if (msg.type === "platformUnload") { + this.logger.debug("detected a web platform unload"); + this.parentReady = false; + this.notifyStatusChanged(false, "Gateway unloaded"); + } + }); + } + handleManualUnload() { + const message = { + glue42core: { + type: this.messages.clientUnload.name, + data: { + clientId: this.myClientId, + ownWindowId: this.identity?.windowId + } + } + }; + if (this.extContentConnected) { + return window.postMessage({ glue42ExtOut: message }, this.defaultTargetString); + } + this.port?.postMessage(message); + } + handleClientUnload(event) { + const data = event.data.glue42core; + const clientId = data?.data.clientId; + if (!clientId) { + this.logger.warn("cannot process grand child unload, because the provided id was not valid"); + return; + } + const foundChild = this.children.find((child) => child.grandChildId === clientId); + if (!foundChild) { + this.logger.warn("cannot process grand child unload, because this client is unaware of this grandchild"); + return; + } + this.logger.debug(`handling grandchild unload for id: ${clientId}`); + this.children = this.children.filter((child) => child.grandChildId !== clientId); + } + handlePlatformPing() { + return; + } + notifyStatusChanged(status, reason) { + this.iAmConnected = status; + this.registry.execute("onConnectedChanged", status, reason); + } + checkMessageTypeValid(typeToValidate) { + return typeof typeToValidate === "string" && !!this.messages[typeToValidate]; + } + rejectConnectionRequest(source, origin, reason) { + this.rejected = true; + this.logger.error(reason); + const rejection = { + glue42core: { + type: this.messages.connectionRejected.name + } + }; + source.postMessage(rejection, origin); + } + requestConnectionPermissionFromExt() { + return this.waitForContentScript() + .then(() => PromisePlus$1((resolve, reject) => { + this.extConnectionResolve = resolve; + this.extConnectionReject = reject; + const message = { + glue42core: { + type: "extSetupRequest" + } + }; + this.logger.debug("permission request to the extension content script was sent"); + window.postMessage(message, this.defaultTargetString); + }, this.parentPingTimeout, "Cannot initialize glue, because this app was not opened or created by a Glue Client and the request for extension connection timed out")); + } + handleExtConnectionResponse(event) { + const data = event.data?.glue42core; + if (!data.approved) { + return this.extConnectionReject ? this.extConnectionReject("Cannot initialize glue, because this app was not opened or created by a Glue Client and the request for extension connection was rejected") : undefined; + } + if (this.extConnectionResolve) { + this.extConnectionResolve(); + delete this.extConnectionResolve; + } + this.extContentConnecting = true; + this.parentType = "extension"; + this.logger.debug("The extension connection was approved, proceeding."); + } + handleExtSetupRequest() { + return; + } + handleGatewayDisconnect() { + return; + } + handleGatewayInternalConnect() { + return; + } + waitForContentScript() { + const contentReady = !!window.glue42ext?.content; + if (contentReady) { + return Promise.resolve(); + } + return PromisePlus$1((resolve) => { + window.addEventListener("Glue42EXTReady", () => { + resolve(); + }); + }, this.connectionRequestTimeout, "The content script was available, but was never heard to be ready"); + } + async connect() { + if (this.settings.port) { + await this.initiateInternalConnection(); + this.logger.debug("internal web platform connection completed"); + return; + } + this.logger.debug("opening a client web platform connection"); + await this.findParent(); + await this.initiateRemoteConnection(this.parent); + this.logger.debug("the client is connected"); + } + async findParent() { + const connectionNotPossibleMsg = "Cannot initiate glue, because this window was not opened or created by a glue client"; + const myInsideParents = this.getPossibleParentsInWindow(window); + const myOutsideParents = this.getPossibleParentsOutsideWindow(window.top?.opener, window.top); + const uniqueParents = new Set([...myInsideParents, ...myOutsideParents]); + if (!uniqueParents.size && !this.extContentAvailable) { + throw new Error(connectionNotPossibleMsg); + } + if (!uniqueParents.size && this.extContentAvailable) { + await this.requestConnectionPermissionFromExt(); + return; + } + const defaultParentCheck = await this.isParentCheckSuccess(this.confirmParent(Array.from(uniqueParents))); + if (defaultParentCheck.success) { + this.logger.debug("The default parent was found!"); + return; + } + if (!this.extContentAvailable) { + throw new Error(connectionNotPossibleMsg); + } + await this.requestConnectionPermissionFromExt(); + } + getPossibleParentsInWindow(currentWindow) { + return (!currentWindow?.parent || currentWindow === currentWindow.parent) ? [] : [currentWindow.parent, ...this.getPossibleParentsInWindow(currentWindow.parent)]; + } + getPossibleParentsOutsideWindow(opener, current) { + return (!opener || !current || opener === current) ? [] : [opener, ...this.getPossibleParentsInWindow(opener), ...this.getPossibleParentsOutsideWindow(opener.opener, opener)]; + } + confirmParent(targets) { + const connectionNotPossibleMsg = "Cannot initiate glue, because this window was not opened or created by a glue client"; + const parentCheck = PromisePlus$1((resolve) => { + this.parentPingResolve = resolve; + const message = { + glue42core: { + type: this.messages.platformPing.name + } + }; + this.parentPingInterval = setInterval(() => { + targets.forEach((target) => { + target.postMessage(message, this.defaultTargetString); + }); + }, 1000); + }, this.parentPingTimeout, connectionNotPossibleMsg); + parentCheck.catch(() => { + if (this.parentPingInterval) { + clearInterval(this.parentPingInterval); + delete this.parentPingInterval; + } + }); + return parentCheck; + } + getMyWindowId() { + if (this.parentType === "workspace") { + return window.name.substring(0, window.name.indexOf("#wsp")); + } + if (window !== window.top) { + return; + } + if (window.name?.includes("g42")) { + return window.name; + } + this.selfAssignedWindowId = this.selfAssignedWindowId || `g42-${nanoid$1(10)}`; + return this.selfAssignedWindowId; + } + } + + const waitForInvocations = (invocations, callback) => { + let left = invocations; + return () => { + left--; + if (left === 0) { + callback(); + } + }; + }; + + class AsyncSequelizer { + minSequenceInterval; + queue = []; + isExecutingQueue = false; + constructor(minSequenceInterval = 0) { + this.minSequenceInterval = minSequenceInterval; + } + enqueue(action) { + return new Promise((resolve, reject) => { + this.queue.push({ action, resolve, reject }); + this.executeQueue(); + }); + } + async executeQueue() { + if (this.isExecutingQueue) { + return; + } + this.isExecutingQueue = true; + while (this.queue.length) { + const operation = this.queue.shift(); + if (!operation) { + this.isExecutingQueue = false; + return; + } + try { + const actionResult = await operation.action(); + operation.resolve(actionResult); + } + catch (error) { + operation.reject(error); + } + await this.intervalBreak(); + } + this.isExecutingQueue = false; + } + intervalBreak() { + return new Promise((res) => setTimeout(res, this.minSequenceInterval)); + } + } + + function domainSession (domain, connection, logger, successMessages, errorMessages) { + if (domain == null) { + domain = "global"; + } + successMessages = successMessages ?? ["success"]; + errorMessages = errorMessages ?? ["error"]; + let isJoined = domain === "global"; + let tryReconnecting = false; + let _latestOptions; + let _connectionOn = false; + const callbacks = CallbackRegistryFactory$1(); + connection.disconnected(handleConnectionDisconnected); + connection.loggedIn(handleConnectionLoggedIn); + connection.on("success", (msg) => handleSuccessMessage(msg)); + connection.on("error", (msg) => handleErrorMessage(msg)); + connection.on("result", (msg) => handleSuccessMessage(msg)); + if (successMessages) { + successMessages.forEach((sm) => { + connection.on(sm, (msg) => handleSuccessMessage(msg)); + }); + } + if (errorMessages) { + errorMessages.forEach((sm) => { + connection.on(sm, (msg) => handleErrorMessage(msg)); + }); + } + const requestsMap = {}; + function join(options) { + _latestOptions = options; + return new Promise((resolve, reject) => { + if (isJoined) { + resolve({}); + return; + } + let joinPromise; + if (domain === "global") { + joinPromise = _connectionOn ? Promise.resolve({}) : Promise.reject("not connected to gateway"); + } + else { + logger.debug(`joining domain ${domain}`); + const joinMsg = { + type: "join", + destination: domain, + domain: "global", + options, + }; + joinPromise = send(joinMsg); + } + joinPromise + .then(() => { + handleJoined(); + resolve({}); + }) + .catch((err) => { + logger.debug("error joining " + domain + " domain: " + JSON.stringify(err)); + reject(err); + }); + }); + } + function leave() { + if (domain === "global") { + return Promise.resolve(); + } + logger.debug("stopping session " + domain + "..."); + const leaveMsg = { + type: "leave", + destination: domain, + domain: "global", + }; + tryReconnecting = false; + return send(leaveMsg) + .then(() => { + isJoined = false; + callbacks.execute("onLeft"); + }) + .catch(() => { + isJoined = false; + callbacks.execute("onLeft"); + }); + } + function handleJoined() { + logger.debug("did join " + domain); + isJoined = true; + const wasReconnect = tryReconnecting; + tryReconnecting = false; + callbacks.execute("onJoined", wasReconnect); + } + function handleConnectionDisconnected() { + _connectionOn = false; + logger.debug("connection is down"); + isJoined = false; + tryReconnecting = true; + callbacks.execute("onLeft", { disconnected: true }); + } + function handleConnectionLoggedIn() { + _connectionOn = true; + if (tryReconnecting) { + logger.debug("connection is now up - trying to reconnect..."); + join(_latestOptions); + } + } + function onJoined(callback) { + if (isJoined) { + callback(false); + } + return callbacks.add("onJoined", callback); + } + function onLeft(callback) { + if (!isJoined) { + callback(); + } + return callbacks.add("onLeft", callback); + } + function handleErrorMessage(msg) { + if (domain !== msg.domain) { + return; + } + const requestId = msg.request_id; + if (!requestId) { + return; + } + const entry = requestsMap[requestId]; + if (!entry) { + return; + } + entry.error(msg); + } + function handleSuccessMessage(msg) { + if (msg.domain !== domain) { + return; + } + const requestId = msg.request_id; + if (!requestId) { + return; + } + const entry = requestsMap[requestId]; + if (!entry) { + return; + } + entry.success(msg); + } + function getNextRequestId() { + return nanoid$1(10); + } + let queuedCalls = []; + function send(msg, tag, options) { + const ignore = ["hello", "join"]; + if (msg.type && ignore.indexOf(msg.type) === -1) { + if (!isJoined) { + console.warn(`trying to send a message (${msg.domain} ${msg.type}) but not connected, will queue`); + const pw = new PromiseWrapper$1(); + queuedCalls.push({ msg, tag, options, pw }); + if (queuedCalls.length === 1) { + const unsubscribe = onJoined(() => { + logger.info(`joined - will now send queued messages (${queuedCalls.length} -> [${queuedCalls.map((m) => m.msg.type)}])`); + queuedCalls.forEach((qm) => { + send(qm.msg, qm.tag, qm.options) + .then((t) => qm.pw.resolve(t)) + .catch((e) => qm.pw.reject(e)); + }); + queuedCalls = []; + unsubscribe(); + }); + } + return pw.promise; + } + } + options = options ?? {}; + msg.request_id = msg.request_id ?? getNextRequestId(); + msg.domain = msg.domain ?? domain; + if (!options.skipPeerId) { + msg.peer_id = connection.peerId; + } + const requestId = msg.request_id; + return new Promise((resolve, reject) => { + requestsMap[requestId] = { + success: (successMsg) => { + delete requestsMap[requestId]; + successMsg._tag = tag; + resolve(successMsg); + }, + error: (errorMsg) => { + logger.warn(`Gateway error - ${JSON.stringify(errorMsg)}`); + delete requestsMap[requestId]; + errorMsg._tag = tag; + reject(errorMsg); + }, + }; + connection + .send(msg, options) + .catch((err) => { + requestsMap[requestId].error({ err }); + }); + }); + } + function sendFireAndForget(msg) { + msg.request_id = msg.request_id ? msg.request_id : getNextRequestId(); + msg.domain = msg.domain ?? domain; + msg.peer_id = connection.peerId; + return connection.send(msg); + } + return { + join, + leave, + onJoined, + onLeft, + send, + sendFireAndForget, + on: (type, callback) => { + connection.on(type, (msg) => { + if (msg.domain !== domain) { + return; + } + try { + callback(msg); + } + catch (e) { + logger.error(`Callback failed: ${e} \n ${e.stack} \n msg was: ${JSON.stringify(msg)}`, e); + } + }); + }, + loggedIn: (callback) => connection.loggedIn(callback), + connected: (callback) => connection.connected(callback), + disconnected: (callback) => connection.disconnected(callback), + get peerId() { + return connection.peerId; + }, + get domain() { + return domain; + }, + }; + } + + class Connection { + settings; + logger; + protocolVersion = 3; + peerId; + token; + info; + resolvedIdentity; + availableDomains; + gatewayToken; + replayer; + messageHandlers = {}; + ids = 1; + registry = CallbackRegistryFactory$1(); + _connected = false; + isTrace = false; + transport; + _defaultTransport; + _defaultAuth; + _targetTransport; + _targetAuth; + _swapTransport = false; + _switchInProgress = false; + _transportSubscriptions = []; + datePrefix = "#T42_DATE#"; + datePrefixLen = this.datePrefix.length; + dateMinLen = this.datePrefixLen + 1; + datePrefixFirstChar = this.datePrefix[0]; + _sequelizer = new AsyncSequelizer(); + _isLoggedIn = false; + shouldTryLogin = true; + pingTimer; + sessions = []; + globalDomain; + initialLogin = true; + initialLoginAttempts = 3; + loginConfig; + constructor(settings, logger) { + this.settings = settings; + this.logger = logger; + settings = settings || {}; + settings.reconnectAttempts = settings.reconnectAttempts ?? 10; + settings.reconnectInterval = settings.reconnectInterval ?? 1000; + if (settings.inproc) { + this.transport = new InProcTransport(settings.inproc, logger.subLogger("inMemory")); + } + else if (settings.sharedWorker) { + this.transport = new SharedWorkerTransport(settings.sharedWorker, logger.subLogger("shared-worker")); + } + else if (settings.webPlatform) { + this.transport = new WebPlatformTransport(settings.webPlatform, logger.subLogger("web-platform"), settings.identity); + } + else if (settings.ws !== undefined) { + this.transport = new WS(settings, logger.subLogger("ws")); + } + else { + throw new Error("No connection information specified"); + } + this.isTrace = logger.canPublish("trace"); + logger.debug(`starting with ${this.transport.name()} transport`); + const unsubConnectionChanged = this.transport.onConnectedChanged(this.handleConnectionChanged.bind(this)); + const unsubOnMessage = this.transport.onMessage(this.handleTransportMessage.bind(this)); + this._transportSubscriptions.push(unsubConnectionChanged); + this._transportSubscriptions.push(unsubOnMessage); + this._defaultTransport = this.transport; + this.ping(); + } + async switchTransport(settings) { + return this._sequelizer.enqueue(async () => { + if (!settings || typeof settings !== "object") { + throw new Error("Cannot switch transports, because the settings are missing or invalid."); + } + if (typeof settings.type === "undefined") { + throw new Error("Cannot switch the transport, because the type is not defined"); + } + this.logger.trace(`Starting transport switch with settings: ${JSON.stringify(settings)}`); + const switchTargetTransport = settings.type === "secondary" ? this.getNewSecondaryTransport(settings) : this._defaultTransport; + this._targetTransport = switchTargetTransport; + this._targetAuth = settings.type === "secondary" ? this.getNewSecondaryAuth(settings) : this._defaultAuth; + const verifyPromise = this.verifyConnection(); + this._swapTransport = true; + this._switchInProgress = true; + this.logger.trace("The new transport has been set, closing the current transport"); + await this.transport.close(); + try { + await verifyPromise; + const isSwitchSuccess = this.transport === switchTargetTransport; + this.logger.info(`The reconnection after the switch was completed. Was the switch a success: ${isSwitchSuccess}`); + this._switchInProgress = false; + return { success: isSwitchSuccess }; + } + catch (error) { + this.logger.info("The reconnection after the switch timed out, reverting back to the default transport."); + this.switchTransport({ type: "default" }); + this._switchInProgress = false; + return { success: false }; + } + }); + } + onLibReAnnounced(callback) { + return this.registry.add("libReAnnounced", callback); + } + setLibReAnnounced(lib) { + this.registry.execute("libReAnnounced", lib); + } + send(message, options) { + if (this.transport.sendObject && + this.transport.isObjectBasedTransport) { + const msg = this.createObjectMessage(message); + if (this.isTrace) { + this.logger.trace(`>> ${JSON.stringify(msg)}`); + } + return this.transport.sendObject(msg, options); + } + else { + const strMessage = this.createStringMessage(message); + if (this.isTrace) { + this.logger.trace(`>> ${strMessage}`); + } + return this.transport.send(strMessage, options); + } + } + on(type, messageHandler) { + type = type.toLowerCase(); + if (this.messageHandlers[type] === undefined) { + this.messageHandlers[type] = {}; + } + const id = this.ids++; + this.messageHandlers[type][id] = messageHandler; + return { + type, + id, + }; + } + off(info) { + delete this.messageHandlers[info.type.toLowerCase()][info.id]; + } + get isConnected() { + return this._isLoggedIn; + } + connected(callback) { + return this.loggedIn(() => { + const currentServer = this.transport.name(); + callback(currentServer); + }); + } + disconnected(callback) { + return this.registry.add("disconnected", callback); + } + async login(authRequest, reconnect) { + if (!this._defaultAuth) { + this._defaultAuth = authRequest; + } + if (this._swapTransport) { + this.logger.trace("Detected a transport swap, swapping transports"); + const newAuth = this.transportSwap(); + authRequest = newAuth ?? authRequest; + } + this.logger.trace(`Starting login for transport: ${this.transport.name()} and auth ${JSON.stringify(authRequest)}`); + try { + await this.transport.open(); + this.logger.trace(`Transport: ${this.transport.name()} opened, logging in`); + timer("connection").mark("transport-opened"); + const identity = await this.loginCore(authRequest, reconnect); + this.logger.trace(`Logged in with identity: ${JSON.stringify(identity)}`); + timer("connection").mark("protocol-logged-in"); + return identity; + } + catch (error) { + if (this._switchInProgress) { + this.logger.trace("An error while logging in after a transport swap, preparing a default swap."); + this.prepareDefaultSwap(); + } + throw new Error(error); + } + } + async logout() { + await this.logoutCore(); + await this.transport.close(); + } + loggedIn(callback) { + if (this._isLoggedIn) { + callback(); + } + return this.registry.add("onLoggedIn", callback); + } + domain(domain, successMessages, errorMessages) { + let session = this.sessions.find((s) => s.domain === domain); + if (!session) { + session = domainSession(domain, this, this.logger.subLogger(`domain=${domain}`), successMessages, errorMessages); + this.sessions.push(session); + } + return session; + } + authToken() { + const createTokenReq = { + domain: "global", + type: "create-token" + }; + if (!this.globalDomain) { + return Promise.reject(new Error("no global domain session")); + } + return this.globalDomain.send(createTokenReq) + .then((res) => { + return res.token; + }); + } + reconnect() { + return this.transport.reconnect(); + } + setLoggedIn(value) { + this._isLoggedIn = value; + if (this._isLoggedIn) { + this.registry.execute("onLoggedIn"); + } + } + distributeMessage(message, type) { + const handlers = this.messageHandlers[type.toLowerCase()]; + if (handlers !== undefined) { + Object.keys(handlers).forEach((handlerId) => { + const handler = handlers[handlerId]; + if (handler !== undefined) { + try { + handler(message); + } + catch (error) { + try { + this.logger.error(`Message handler failed with ${error.stack}`, error); + } + catch (loggerError) { + console.log("Message handler failed", error); + } + } + } + }); + } + } + handleConnectionChanged(connected) { + if (this._connected === connected) { + return; + } + this._connected = connected; + if (connected) { + if (this.settings?.replaySpecs?.length) { + this.replayer = new MessageReplayerImpl(this.settings.replaySpecs); + this.replayer.init(this); + } + this.registry.execute("connected"); + } + else { + this.handleDisconnected(); + this.registry.execute("disconnected"); + } + } + handleDisconnected() { + this.setLoggedIn(false); + const tryToLogin = this.shouldTryLogin; + if (tryToLogin && this.initialLogin) { + if (this.initialLoginAttempts <= 0) { + return; + } + this.initialLoginAttempts--; + } + this.logger.debug("disconnected - will try new login?" + this.shouldTryLogin); + if (this.shouldTryLogin) { + if (!this.loginConfig) { + throw new Error("no login info"); + } + this.login(this.loginConfig, true) + .catch(() => { + setTimeout(this.handleDisconnected.bind(this), this.settings.reconnectInterval || 1000); + }); + } + } + handleTransportMessage(msg) { + let msgObj; + if (typeof msg === "string") { + msgObj = this.processStringMessage(msg); + } + else { + msgObj = this.processObjectMessage(msg); + } + if (this.isTrace) { + this.logger.trace(`<< ${JSON.stringify(msgObj)}`); + } + this.distributeMessage(msgObj.msg, msgObj.msgType); + } + verifyConnection() { + return PromisePlus$1((resolve) => { + let unsub; + const ready = waitForInvocations(2, () => { + if (unsub) { + unsub(); + } + resolve(); + }); + unsub = this.onLibReAnnounced((lib) => { + if (lib.name === "interop") { + return ready(); + } + if (lib.name === "contexts") { + return ready(); + } + }); + }, 10000, "Transport switch timed out waiting for all libraries to be re-announced"); + } + getNewSecondaryTransport(settings) { + if (!settings.transportConfig?.url) { + throw new Error("Missing secondary transport URL."); + } + return new WS(Object.assign({}, this.settings, { ws: settings.transportConfig.url, reconnectAttempts: 1 }), this.logger.subLogger("ws-secondary")); + } + getNewSecondaryAuth(settings) { + if (!settings.transportConfig?.auth) { + throw new Error("Missing secondary transport auth information."); + } + return settings.transportConfig.auth; + } + transportSwap() { + this._swapTransport = false; + if (!this._targetTransport || !this._targetAuth) { + this.logger.warn(`Error while switching transports - either the target transport or auth is not defined: transport defined -> ${!!this._defaultTransport}, auth defined -> ${!!this._targetAuth}. Staying on the current one.`); + return; + } + this._transportSubscriptions.forEach((unsub) => unsub()); + this._transportSubscriptions = []; + this.transport = this._targetTransport; + const unsubConnectionChanged = this.transport.onConnectedChanged(this.handleConnectionChanged.bind(this)); + const unsubOnMessage = this.transport.onMessage(this.handleTransportMessage.bind(this)); + this._transportSubscriptions.push(unsubConnectionChanged); + this._transportSubscriptions.push(unsubOnMessage); + return this._targetAuth; + } + prepareDefaultSwap() { + this._transportSubscriptions.forEach((unsub) => unsub()); + this._transportSubscriptions = []; + this.transport.close().catch((error) => this.logger.warn(`Error closing the ${this.transport.name()} transport after a failed connection attempt: ${JSON.stringify(error)}`)); + this._targetTransport = this._defaultTransport; + this._targetAuth = this._defaultAuth; + this._swapTransport = true; + } + processStringMessage(message) { + const msg = JSON.parse(message, (key, value) => { + if (typeof value !== "string") { + return value; + } + if (value.length < this.dateMinLen) { + return value; + } + if (!value.startsWith(this.datePrefixFirstChar)) { + return value; + } + if (value.substring(0, this.datePrefixLen) !== this.datePrefix) { + return value; + } + try { + const milliseconds = parseInt(value.substring(this.datePrefixLen, value.length), 10); + if (isNaN(milliseconds)) { + return value; + } + return new Date(milliseconds); + } + catch (ex) { + return value; + } + }); + return { + msg, + msgType: msg.type, + }; + } + createStringMessage(message) { + const oldToJson = Date.prototype.toJSON; + try { + const datePrefix = this.datePrefix; + Date.prototype.toJSON = function () { + return datePrefix + this.getTime(); + }; + const result = JSON.stringify(message); + return result; + } + finally { + Date.prototype.toJSON = oldToJson; + } + } + processObjectMessage(message) { + if (!message.type) { + throw new Error("Object should have type property"); + } + return { + msg: message, + msgType: message.type, + }; + } + createObjectMessage(message) { + return message; + } + async loginCore(config, reconnect) { + this.logger.info("logging in..."); + this.loginConfig = config; + if (!this.loginConfig) { + this.loginConfig = { username: "", password: "" }; + } + this.shouldTryLogin = true; + const authentication = await this.setupAuthConfig(config, reconnect); + const helloMsg = { + type: "hello", + identity: this.settings.identity, + authentication + }; + if (config.sessionId) { + helloMsg.request_id = config.sessionId; + } + this.globalDomain = domainSession("global", this, this.logger.subLogger("global-domain"), [ + "welcome", + "token", + "authentication-request" + ]); + const sendOptions = { skipPeerId: true }; + if (this.initialLogin) { + sendOptions.retryInterval = this.settings.reconnectInterval; + sendOptions.maxRetries = this.settings.reconnectAttempts; + } + try { + const welcomeMsg = await this.tryAuthenticate(this.globalDomain, helloMsg, sendOptions, config); + this.initialLogin = false; + this.logger.info("login successful with peerId " + welcomeMsg.peer_id); + this.peerId = welcomeMsg.peer_id; + this.resolvedIdentity = welcomeMsg.resolved_identity; + this.availableDomains = welcomeMsg.available_domains; + if (welcomeMsg.options) { + this.token = welcomeMsg.options.access_token; + this.info = welcomeMsg.options.info; + } + this.setLoggedIn(true); + return welcomeMsg.resolved_identity; + } + catch (err) { + this.logger.error("error sending hello message - " + (err.message || err.msg || err.reason || err), err); + throw err; + } + finally { + if (config?.flowCallback && config.sessionId) { + config.flowCallback(config.sessionId, null); + } + } + } + async tryAuthenticate(globalDomain, helloMsg, sendOptions, config) { + let welcomeMsg; + while (true) { + const msg = await globalDomain.send(helloMsg, undefined, sendOptions); + if (msg.type === "authentication-request") { + const token = Buffer.from(msg.authentication.token, "base64"); + if (config.flowCallback && config.sessionId) { + helloMsg.authentication.token = + (await config.flowCallback(config.sessionId, token)) + .data + .toString("base64"); + } + helloMsg.request_id = config.sessionId; + } + else if (msg.type === "welcome") { + welcomeMsg = msg; + break; + } + else if (msg.type === "error") { + throw new Error("Authentication failed: " + msg.reason); + } + else { + throw new Error("Unexpected message type during authentication: " + msg.type); + } + } + return welcomeMsg; + } + async setupAuthConfig(config, reconnect) { + const authentication = {}; + this.gatewayToken = config.gatewayToken; + if (config.gatewayToken) { + if (reconnect) { + try { + config.gatewayToken = await this.getNewGWToken(); + } + catch (e) { + this.logger.warn(`failed to get GW token when reconnecting ${e?.message || e}`); + } + } + authentication.method = "gateway-token"; + authentication.token = config.gatewayToken; + this.gatewayToken = config.gatewayToken; + } + else if (config.flowName === "sspi") { + authentication.provider = "win"; + authentication.method = "access-token"; + if (config.flowCallback && config.sessionId) { + authentication.token = + (await config.flowCallback(config.sessionId, null)) + .data + .toString("base64"); + } + else { + throw new Error("Invalid SSPI config"); + } + } + else if (config.token) { + authentication.method = "access-token"; + authentication.token = config.token; + } + else if (config.username) { + authentication.method = "secret"; + authentication.login = config.username; + authentication.secret = config.password; + } + else if (config.provider) { + authentication.provider = config.provider; + authentication.providerContext = config.providerContext; + } + else { + throw new Error("invalid auth message" + JSON.stringify(config)); + } + return authentication; + } + async logoutCore() { + this.logger.debug("logging out..."); + this.shouldTryLogin = false; + if (this.pingTimer) { + clearTimeout(this.pingTimer); + } + const promises = this.sessions.map((session) => { + session.leave(); + }); + await Promise.all(promises); + } + getNewGWToken() { + if (typeof window !== "undefined") { + const glue42gd = window.glue42gd; + if (glue42gd) { + return glue42gd.getGWToken(); + } + } + return Promise.reject(new Error("not running in GD")); + } + ping() { + if (!this.shouldTryLogin) { + return; + } + if (this._isLoggedIn) { + this.send({ type: "ping" }); + } + this.pingTimer = setTimeout(() => { + this.ping(); + }, 30 * 1000); + } + } + + const order = ["trace", "debug", "info", "warn", "error", "off"]; + let Logger$1 = class Logger { + name; + parent; + static Interop; + static InteropMethodName = "T42.AppLogger.Log"; + static Instance; + path; + subLoggers = []; + _consoleLevel; + _publishLevel; + loggerFullName; + includeTimeAndLevel; + logFn = console; + customLogFn = false; + constructor(name, parent, logFn) { + this.name = name; + this.parent = parent; + this.name = name; + if (parent) { + this.path = `${parent.path}.${name}`; + } + else { + this.path = name; + } + this.loggerFullName = `[${this.path}]`; + this.includeTimeAndLevel = !logFn; + if (logFn) { + this.logFn = logFn; + this.customLogFn = true; + } + } + subLogger(name) { + const existingSub = this.subLoggers.filter((subLogger) => { + return subLogger.name === name; + })[0]; + if (existingSub !== undefined) { + return existingSub; + } + Object.keys(this).forEach((key) => { + if (key === name) { + throw new Error("This sub logger name is not allowed."); + } + }); + const sub = new Logger(name, this, this.customLogFn ? this.logFn : undefined); + this.subLoggers.push(sub); + return sub; + } + publishLevel(level) { + if (level) { + this._publishLevel = level; + } + return this._publishLevel || this.parent?.publishLevel(); + } + consoleLevel(level) { + if (level) { + this._consoleLevel = level; + } + return this._consoleLevel || this.parent?.consoleLevel(); + } + log(message, level, error) { + this.publishMessage(level || "info", message, error); + } + trace(message) { + this.log(message, "trace"); + } + debug(message) { + this.log(message, "debug"); + } + info(message) { + this.log(message, "info"); + } + warn(message) { + this.log(message, "warn"); + } + error(message, err) { + this.log(message, "error", err); + } + canPublish(level, compareWith) { + const levelIdx = order.indexOf(level); + const restrictionIdx = order.indexOf(compareWith || this.consoleLevel() || "trace"); + return levelIdx >= restrictionIdx; + } + publishMessage(level, message, error) { + const loggerName = this.loggerFullName; + if (level === "error" && !error) { + const e = new Error(); + if (e.stack) { + message = + message + + "\n" + + e.stack + .split("\n") + .slice(4) + .join("\n"); + } + } + if (this.canPublish(level, this.publishLevel())) { + const interop = Logger.Interop; + if (interop) { + try { + if (interop.methods({ name: Logger.InteropMethodName }).length > 0) { + const args = { + msg: message, + logger: loggerName, + level + }; + if (error && error instanceof Error) { + args.error = { + message: error.message, + stack: error.stack ?? "" + }; + } + interop.invoke(Logger.InteropMethodName, args); + } + } + catch { + } + } + } + if (this.canPublish(level)) { + let prefix = ""; + if (this.includeTimeAndLevel) { + const date = new Date(); + const time = `${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}:${date.getMilliseconds()}`; + prefix = `[${time}] [${level}] `; + } + const toPrint = `${prefix}${loggerName}: ${message}`; + switch (level) { + case "trace": + this.logFn.debug(toPrint); + break; + case "debug": + if (this.logFn.debug) { + this.logFn.debug(toPrint); + } + else { + this.logFn.log(toPrint); + } + break; + case "info": + this.logFn.info(toPrint); + break; + case "warn": + this.logFn.warn(toPrint); + break; + case "error": + this.logFn.error(toPrint, error); + break; + } + } + } + }; + + const GW_MESSAGE_CREATE_CONTEXT = "create-context"; + const GW_MESSAGE_ACTIVITY_CREATED = "created"; + const GW_MESSAGE_ACTIVITY_DESTROYED = "destroyed"; + const GW_MESSAGE_CONTEXT_CREATED = "context-created"; + const GW_MESSAGE_CONTEXT_ADDED = "context-added"; + const GW_MESSAGE_SUBSCRIBE_CONTEXT = "subscribe-context"; + const GW_MESSAGE_SUBSCRIBED_CONTEXT = "subscribed-context"; + const GW_MESSAGE_UNSUBSCRIBE_CONTEXT = "unsubscribe-context"; + const GW_MESSAGE_DESTROY_CONTEXT = "destroy-context"; + const GW_MESSAGE_CONTEXT_DESTROYED = "context-destroyed"; + const GW_MESSAGE_UPDATE_CONTEXT = "update-context"; + const GW_MESSAGE_CONTEXT_UPDATED = "context-updated"; + const GW_MESSAGE_JOINED_ACTIVITY = "joined"; + + const ContextMessageReplaySpec = { + get name() { + return "context"; + }, + get types() { + return [ + GW_MESSAGE_CREATE_CONTEXT, + GW_MESSAGE_ACTIVITY_CREATED, + GW_MESSAGE_ACTIVITY_DESTROYED, + GW_MESSAGE_CONTEXT_CREATED, + GW_MESSAGE_CONTEXT_ADDED, + GW_MESSAGE_SUBSCRIBE_CONTEXT, + GW_MESSAGE_SUBSCRIBED_CONTEXT, + GW_MESSAGE_UNSUBSCRIBE_CONTEXT, + GW_MESSAGE_DESTROY_CONTEXT, + GW_MESSAGE_CONTEXT_DESTROYED, + GW_MESSAGE_UPDATE_CONTEXT, + GW_MESSAGE_CONTEXT_UPDATED, + GW_MESSAGE_JOINED_ACTIVITY + ]; + } + }; + + var version$1 = "6.5.2-fmr-beta"; + + function prepareConfig$1 (configuration, ext, glue42gd) { + let nodeStartingContext; + if (Utils$1.isNode()) { + const startingContextString = process.env._GD_STARTING_CONTEXT_; + if (startingContextString) { + try { + nodeStartingContext = JSON.parse(startingContextString); + } + catch { + } + } + } + function getConnection() { + const gwConfig = configuration.gateway; + const protocolVersion = gwConfig?.protocolVersion ?? 3; + const reconnectInterval = gwConfig?.reconnectInterval; + const reconnectAttempts = gwConfig?.reconnectAttempts; + const defaultWs = "ws://localhost:8385"; + let ws = gwConfig?.ws; + const sharedWorker = gwConfig?.sharedWorker; + const inproc = gwConfig?.inproc; + const webPlatform = gwConfig?.webPlatform ?? undefined; + if (glue42gd) { + ws = glue42gd.gwURL; + } + if (Utils$1.isNode() && nodeStartingContext && nodeStartingContext.gwURL) { + ws = nodeStartingContext.gwURL; + } + if (!ws && !sharedWorker && !inproc) { + ws = defaultWs; + } + let instanceId; + let windowId; + let pid; + let environment; + let region; + const appName = getApplication(); + let uniqueAppName = appName; + if (typeof glue42gd !== "undefined") { + windowId = glue42gd.windowId; + pid = glue42gd.pid; + if (glue42gd.env) { + environment = glue42gd.env.env; + region = glue42gd.env.region; + } + uniqueAppName = glue42gd.application ?? "glue-app"; + instanceId = glue42gd.appInstanceId; + } + else if (Utils$1.isNode()) { + pid = process.pid; + if (nodeStartingContext) { + environment = nodeStartingContext.env; + region = nodeStartingContext.region; + instanceId = nodeStartingContext.instanceId; + } + } + else if (typeof window?.glue42electron !== "undefined") { + windowId = window?.glue42electron.instanceId; + pid = window?.glue42electron.pid; + environment = window?.glue42electron.env; + region = window?.glue42electron.region; + uniqueAppName = window?.glue42electron.application ?? "glue-app"; + instanceId = window?.glue42electron.instanceId; + } + else ; + const replaySpecs = configuration.gateway?.replaySpecs ?? []; + replaySpecs.push(ContextMessageReplaySpec); + let identity = { + application: uniqueAppName, + applicationName: appName, + windowId, + instance: instanceId, + process: pid, + region, + environment, + api: ext.version || version$1 + }; + if (configuration.identity) { + identity = Object.assign(identity, configuration.identity); + } + return { + identity, + reconnectInterval, + ws, + sharedWorker, + webPlatform, + inproc, + protocolVersion, + reconnectAttempts, + replaySpecs, + }; + } + function getContexts() { + if (typeof configuration.contexts === "undefined") { + return { reAnnounceKnownContexts: true }; + } + if (typeof configuration.contexts === "boolean" && configuration.contexts) { + return { reAnnounceKnownContexts: true }; + } + if (typeof configuration.contexts === "object") { + return Object.assign({}, { reAnnounceKnownContexts: true }, configuration.contexts); + } + return false; + } + function getApplication() { + if (configuration.application) { + return configuration.application; + } + if (glue42gd) { + return glue42gd.applicationName; + } + if (typeof window !== "undefined" && typeof window.glue42electron !== "undefined") { + return window.glue42electron.application; + } + const uid = nanoid$1(10); + if (Utils$1.isNode()) { + if (nodeStartingContext) { + return nodeStartingContext.applicationConfig.name; + } + return "NodeJS" + uid; + } + if (typeof window !== "undefined" && typeof document !== "undefined") { + return document.title + ` (${uid})`; + } + return uid; + } + function getAuth() { + if (typeof configuration.auth === "string") { + return { + token: configuration.auth + }; + } + if (configuration.auth) { + return configuration.auth; + } + if (Utils$1.isNode() && nodeStartingContext && nodeStartingContext.gwToken) { + return { + gatewayToken: nodeStartingContext.gwToken + }; + } + if (configuration.gateway?.webPlatform || configuration.gateway?.inproc || configuration.gateway?.sharedWorker) { + return { + username: "glue42", password: "glue42" + }; + } + } + function getLogger() { + let config = configuration.logger; + const defaultLevel = "warn"; + if (!config) { + config = defaultLevel; + } + let gdConsoleLevel; + if (glue42gd) { + gdConsoleLevel = glue42gd.consoleLogLevel; + } + if (typeof config === "string") { + return { console: gdConsoleLevel ?? config, publish: defaultLevel }; + } + return { + console: gdConsoleLevel ?? config.console ?? defaultLevel, + publish: config.publish ?? defaultLevel + }; + } + const connection = getConnection(); + let application = getApplication(); + if (typeof window !== "undefined") { + const windowAsAny = window; + const containerApplication = windowAsAny.htmlContainer ? + `${windowAsAny.htmlContainer.containerName}.${windowAsAny.htmlContainer.application}` : + windowAsAny?.glue42gd?.application; + if (containerApplication) { + application = containerApplication; + } + } + return { + bus: configuration.bus ?? false, + application, + auth: getAuth(), + logger: getLogger(), + connection, + metrics: configuration.metrics ?? true, + contexts: getContexts(), + version: ext.version || version$1, + libs: ext.libs ?? [], + customLogger: configuration.customLogger + }; + } + + class GW3ContextData { + name; + contextId; + context; + isAnnounced; + joinedActivity; + updateCallbacks = {}; + activityId; + sentExplicitSubscription; + hasReceivedSnapshot; + constructor(contextId, name, isAnnounced, activityId) { + this.contextId = contextId; + this.name = name; + this.isAnnounced = isAnnounced; + this.activityId = activityId; + this.context = {}; + } + hasCallbacks() { + return Object.keys(this.updateCallbacks).length > 0; + } + getState() { + if (this.isAnnounced && this.hasCallbacks()) { + return 3; + } + if (this.isAnnounced) { + return 2; + } + if (this.hasCallbacks()) { + return 1; + } + return 0; + } + } + + var lodash_clonedeep = {exports: {}}; + + /** + * lodash (Custom Build) + * Build: `lodash modularize exports="npm" -o ./` + * Copyright jQuery Foundation and other contributors + * Released under MIT license + * Based on Underscore.js 1.8.3 + * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + */ + lodash_clonedeep.exports; + + (function (module, exports) { + /** Used as the size to enable large array optimizations. */ + var LARGE_ARRAY_SIZE = 200; + + /** Used to stand-in for `undefined` hash values. */ + var HASH_UNDEFINED = '__lodash_hash_undefined__'; + + /** Used as references for various `Number` constants. */ + var MAX_SAFE_INTEGER = 9007199254740991; + + /** `Object#toString` result references. */ + var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + boolTag = '[object Boolean]', + dateTag = '[object Date]', + errorTag = '[object Error]', + funcTag = '[object Function]', + genTag = '[object GeneratorFunction]', + mapTag = '[object Map]', + numberTag = '[object Number]', + objectTag = '[object Object]', + promiseTag = '[object Promise]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + symbolTag = '[object Symbol]', + weakMapTag = '[object WeakMap]'; + + var arrayBufferTag = '[object ArrayBuffer]', + dataViewTag = '[object DataView]', + float32Tag = '[object Float32Array]', + float64Tag = '[object Float64Array]', + int8Tag = '[object Int8Array]', + int16Tag = '[object Int16Array]', + int32Tag = '[object Int32Array]', + uint8Tag = '[object Uint8Array]', + uint8ClampedTag = '[object Uint8ClampedArray]', + uint16Tag = '[object Uint16Array]', + uint32Tag = '[object Uint32Array]'; + + /** + * Used to match `RegExp` + * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns). + */ + var reRegExpChar = /[\\^$.*+?()[\]{}|]/g; + + /** Used to match `RegExp` flags from their coerced string values. */ + var reFlags = /\w*$/; + + /** Used to detect host constructors (Safari). */ + var reIsHostCtor = /^\[object .+?Constructor\]$/; + + /** Used to detect unsigned integer values. */ + var reIsUint = /^(?:0|[1-9]\d*)$/; + + /** Used to identify `toStringTag` values supported by `_.clone`. */ + var cloneableTags = {}; + cloneableTags[argsTag] = cloneableTags[arrayTag] = + cloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] = + cloneableTags[boolTag] = cloneableTags[dateTag] = + cloneableTags[float32Tag] = cloneableTags[float64Tag] = + cloneableTags[int8Tag] = cloneableTags[int16Tag] = + cloneableTags[int32Tag] = cloneableTags[mapTag] = + cloneableTags[numberTag] = cloneableTags[objectTag] = + cloneableTags[regexpTag] = cloneableTags[setTag] = + cloneableTags[stringTag] = cloneableTags[symbolTag] = + cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] = + cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true; + cloneableTags[errorTag] = cloneableTags[funcTag] = + cloneableTags[weakMapTag] = false; + + /** Detect free variable `global` from Node.js. */ + var freeGlobal = typeof commonjsGlobal$1 == 'object' && commonjsGlobal$1 && commonjsGlobal$1.Object === Object && commonjsGlobal$1; + + /** Detect free variable `self`. */ + var freeSelf = typeof self == 'object' && self && self.Object === Object && self; + + /** Used as a reference to the global object. */ + var root = freeGlobal || freeSelf || Function('return this')(); + + /** Detect free variable `exports`. */ + var freeExports = exports && !exports.nodeType && exports; + + /** Detect free variable `module`. */ + var freeModule = freeExports && 'object' == 'object' && module && !module.nodeType && module; + + /** Detect the popular CommonJS extension `module.exports`. */ + var moduleExports = freeModule && freeModule.exports === freeExports; + + /** + * Adds the key-value `pair` to `map`. + * + * @private + * @param {Object} map The map to modify. + * @param {Array} pair The key-value pair to add. + * @returns {Object} Returns `map`. + */ + function addMapEntry(map, pair) { + // Don't return `map.set` because it's not chainable in IE 11. + map.set(pair[0], pair[1]); + return map; + } + + /** + * Adds `value` to `set`. + * + * @private + * @param {Object} set The set to modify. + * @param {*} value The value to add. + * @returns {Object} Returns `set`. + */ + function addSetEntry(set, value) { + // Don't return `set.add` because it's not chainable in IE 11. + set.add(value); + return set; + } + + /** + * A specialized version of `_.forEach` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns `array`. + */ + function arrayEach(array, iteratee) { + var index = -1, + length = array ? array.length : 0; + + while (++index < length) { + if (iteratee(array[index], index, array) === false) { + break; + } + } + return array; + } + + /** + * Appends the elements of `values` to `array`. + * + * @private + * @param {Array} array The array to modify. + * @param {Array} values The values to append. + * @returns {Array} Returns `array`. + */ + function arrayPush(array, values) { + var index = -1, + length = values.length, + offset = array.length; + + while (++index < length) { + array[offset + index] = values[index]; + } + return array; + } + + /** + * A specialized version of `_.reduce` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {boolean} [initAccum] Specify using the first element of `array` as + * the initial value. + * @returns {*} Returns the accumulated value. + */ + function arrayReduce(array, iteratee, accumulator, initAccum) { + var index = -1, + length = array ? array.length : 0; + while (++index < length) { + accumulator = iteratee(accumulator, array[index], index, array); + } + return accumulator; + } + + /** + * The base implementation of `_.times` without support for iteratee shorthands + * or max array length checks. + * + * @private + * @param {number} n The number of times to invoke `iteratee`. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the array of results. + */ + function baseTimes(n, iteratee) { + var index = -1, + result = Array(n); + + while (++index < n) { + result[index] = iteratee(index); + } + return result; + } + + /** + * Gets the value at `key` of `object`. + * + * @private + * @param {Object} [object] The object to query. + * @param {string} key The key of the property to get. + * @returns {*} Returns the property value. + */ + function getValue(object, key) { + return object == null ? undefined : object[key]; + } + + /** + * Checks if `value` is a host object in IE < 9. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a host object, else `false`. + */ + function isHostObject(value) { + // Many host objects are `Object` objects that can coerce to strings + // despite having improperly defined `toString` methods. + var result = false; + if (value != null && typeof value.toString != 'function') { + try { + result = !!(value + ''); + } catch (e) {} + } + return result; + } + + /** + * Converts `map` to its key-value pairs. + * + * @private + * @param {Object} map The map to convert. + * @returns {Array} Returns the key-value pairs. + */ + function mapToArray(map) { + var index = -1, + result = Array(map.size); + + map.forEach(function(value, key) { + result[++index] = [key, value]; + }); + return result; + } + + /** + * Creates a unary function that invokes `func` with its argument transformed. + * + * @private + * @param {Function} func The function to wrap. + * @param {Function} transform The argument transform. + * @returns {Function} Returns the new function. + */ + function overArg(func, transform) { + return function(arg) { + return func(transform(arg)); + }; + } + + /** + * Converts `set` to an array of its values. + * + * @private + * @param {Object} set The set to convert. + * @returns {Array} Returns the values. + */ + function setToArray(set) { + var index = -1, + result = Array(set.size); + + set.forEach(function(value) { + result[++index] = value; + }); + return result; + } + + /** Used for built-in method references. */ + var arrayProto = Array.prototype, + funcProto = Function.prototype, + objectProto = Object.prototype; + + /** Used to detect overreaching core-js shims. */ + var coreJsData = root['__core-js_shared__']; + + /** Used to detect methods masquerading as native. */ + var maskSrcKey = (function() { + var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || ''); + return uid ? ('Symbol(src)_1.' + uid) : ''; + }()); + + /** Used to resolve the decompiled source of functions. */ + var funcToString = funcProto.toString; + + /** Used to check objects for own properties. */ + var hasOwnProperty = objectProto.hasOwnProperty; + + /** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ + var objectToString = objectProto.toString; + + /** Used to detect if a method is native. */ + var reIsNative = RegExp('^' + + funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&') + .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' + ); + + /** Built-in value references. */ + var Buffer = moduleExports ? root.Buffer : undefined, + Symbol = root.Symbol, + Uint8Array = root.Uint8Array, + getPrototype = overArg(Object.getPrototypeOf, Object), + objectCreate = Object.create, + propertyIsEnumerable = objectProto.propertyIsEnumerable, + splice = arrayProto.splice; + + /* Built-in method references for those with the same name as other `lodash` methods. */ + var nativeGetSymbols = Object.getOwnPropertySymbols, + nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined, + nativeKeys = overArg(Object.keys, Object); + + /* Built-in method references that are verified to be native. */ + var DataView = getNative(root, 'DataView'), + Map = getNative(root, 'Map'), + Promise = getNative(root, 'Promise'), + Set = getNative(root, 'Set'), + WeakMap = getNative(root, 'WeakMap'), + nativeCreate = getNative(Object, 'create'); + + /** Used to detect maps, sets, and weakmaps. */ + var dataViewCtorString = toSource(DataView), + mapCtorString = toSource(Map), + promiseCtorString = toSource(Promise), + setCtorString = toSource(Set), + weakMapCtorString = toSource(WeakMap); + + /** Used to convert symbols to primitives and strings. */ + var symbolProto = Symbol ? Symbol.prototype : undefined, + symbolValueOf = symbolProto ? symbolProto.valueOf : undefined; + + /** + * Creates a hash object. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + function Hash(entries) { + var index = -1, + length = entries ? entries.length : 0; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } + } + + /** + * Removes all key-value entries from the hash. + * + * @private + * @name clear + * @memberOf Hash + */ + function hashClear() { + this.__data__ = nativeCreate ? nativeCreate(null) : {}; + } + + /** + * Removes `key` and its value from the hash. + * + * @private + * @name delete + * @memberOf Hash + * @param {Object} hash The hash to modify. + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function hashDelete(key) { + return this.has(key) && delete this.__data__[key]; + } + + /** + * Gets the hash value for `key`. + * + * @private + * @name get + * @memberOf Hash + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function hashGet(key) { + var data = this.__data__; + if (nativeCreate) { + var result = data[key]; + return result === HASH_UNDEFINED ? undefined : result; + } + return hasOwnProperty.call(data, key) ? data[key] : undefined; + } + + /** + * Checks if a hash value for `key` exists. + * + * @private + * @name has + * @memberOf Hash + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function hashHas(key) { + var data = this.__data__; + return nativeCreate ? data[key] !== undefined : hasOwnProperty.call(data, key); + } + + /** + * Sets the hash `key` to `value`. + * + * @private + * @name set + * @memberOf Hash + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the hash instance. + */ + function hashSet(key, value) { + var data = this.__data__; + data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value; + return this; + } + + // Add methods to `Hash`. + Hash.prototype.clear = hashClear; + Hash.prototype['delete'] = hashDelete; + Hash.prototype.get = hashGet; + Hash.prototype.has = hashHas; + Hash.prototype.set = hashSet; + + /** + * Creates an list cache object. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + function ListCache(entries) { + var index = -1, + length = entries ? entries.length : 0; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } + } + + /** + * Removes all key-value entries from the list cache. + * + * @private + * @name clear + * @memberOf ListCache + */ + function listCacheClear() { + this.__data__ = []; + } + + /** + * Removes `key` and its value from the list cache. + * + * @private + * @name delete + * @memberOf ListCache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function listCacheDelete(key) { + var data = this.__data__, + index = assocIndexOf(data, key); + + if (index < 0) { + return false; + } + var lastIndex = data.length - 1; + if (index == lastIndex) { + data.pop(); + } else { + splice.call(data, index, 1); + } + return true; + } + + /** + * Gets the list cache value for `key`. + * + * @private + * @name get + * @memberOf ListCache + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function listCacheGet(key) { + var data = this.__data__, + index = assocIndexOf(data, key); + + return index < 0 ? undefined : data[index][1]; + } + + /** + * Checks if a list cache value for `key` exists. + * + * @private + * @name has + * @memberOf ListCache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function listCacheHas(key) { + return assocIndexOf(this.__data__, key) > -1; + } + + /** + * Sets the list cache `key` to `value`. + * + * @private + * @name set + * @memberOf ListCache + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the list cache instance. + */ + function listCacheSet(key, value) { + var data = this.__data__, + index = assocIndexOf(data, key); + + if (index < 0) { + data.push([key, value]); + } else { + data[index][1] = value; + } + return this; + } + + // Add methods to `ListCache`. + ListCache.prototype.clear = listCacheClear; + ListCache.prototype['delete'] = listCacheDelete; + ListCache.prototype.get = listCacheGet; + ListCache.prototype.has = listCacheHas; + ListCache.prototype.set = listCacheSet; + + /** + * Creates a map cache object to store key-value pairs. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + function MapCache(entries) { + var index = -1, + length = entries ? entries.length : 0; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } + } + + /** + * Removes all key-value entries from the map. + * + * @private + * @name clear + * @memberOf MapCache + */ + function mapCacheClear() { + this.__data__ = { + 'hash': new Hash, + 'map': new (Map || ListCache), + 'string': new Hash + }; + } + + /** + * Removes `key` and its value from the map. + * + * @private + * @name delete + * @memberOf MapCache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function mapCacheDelete(key) { + return getMapData(this, key)['delete'](key); + } + + /** + * Gets the map value for `key`. + * + * @private + * @name get + * @memberOf MapCache + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function mapCacheGet(key) { + return getMapData(this, key).get(key); + } + + /** + * Checks if a map value for `key` exists. + * + * @private + * @name has + * @memberOf MapCache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function mapCacheHas(key) { + return getMapData(this, key).has(key); + } + + /** + * Sets the map `key` to `value`. + * + * @private + * @name set + * @memberOf MapCache + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the map cache instance. + */ + function mapCacheSet(key, value) { + getMapData(this, key).set(key, value); + return this; + } + + // Add methods to `MapCache`. + MapCache.prototype.clear = mapCacheClear; + MapCache.prototype['delete'] = mapCacheDelete; + MapCache.prototype.get = mapCacheGet; + MapCache.prototype.has = mapCacheHas; + MapCache.prototype.set = mapCacheSet; + + /** + * Creates a stack cache object to store key-value pairs. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + function Stack(entries) { + this.__data__ = new ListCache(entries); + } + + /** + * Removes all key-value entries from the stack. + * + * @private + * @name clear + * @memberOf Stack + */ + function stackClear() { + this.__data__ = new ListCache; + } + + /** + * Removes `key` and its value from the stack. + * + * @private + * @name delete + * @memberOf Stack + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function stackDelete(key) { + return this.__data__['delete'](key); + } + + /** + * Gets the stack value for `key`. + * + * @private + * @name get + * @memberOf Stack + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function stackGet(key) { + return this.__data__.get(key); + } + + /** + * Checks if a stack value for `key` exists. + * + * @private + * @name has + * @memberOf Stack + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function stackHas(key) { + return this.__data__.has(key); + } + + /** + * Sets the stack `key` to `value`. + * + * @private + * @name set + * @memberOf Stack + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the stack cache instance. + */ + function stackSet(key, value) { + var cache = this.__data__; + if (cache instanceof ListCache) { + var pairs = cache.__data__; + if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) { + pairs.push([key, value]); + return this; + } + cache = this.__data__ = new MapCache(pairs); + } + cache.set(key, value); + return this; + } + + // Add methods to `Stack`. + Stack.prototype.clear = stackClear; + Stack.prototype['delete'] = stackDelete; + Stack.prototype.get = stackGet; + Stack.prototype.has = stackHas; + Stack.prototype.set = stackSet; + + /** + * Creates an array of the enumerable property names of the array-like `value`. + * + * @private + * @param {*} value The value to query. + * @param {boolean} inherited Specify returning inherited property names. + * @returns {Array} Returns the array of property names. + */ + function arrayLikeKeys(value, inherited) { + // Safari 8.1 makes `arguments.callee` enumerable in strict mode. + // Safari 9 makes `arguments.length` enumerable in strict mode. + var result = (isArray(value) || isArguments(value)) + ? baseTimes(value.length, String) + : []; + + var length = result.length, + skipIndexes = !!length; + + for (var key in value) { + if ((hasOwnProperty.call(value, key)) && + !(skipIndexes && (key == 'length' || isIndex(key, length)))) { + result.push(key); + } + } + return result; + } + + /** + * Assigns `value` to `key` of `object` if the existing value is not equivalent + * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. + * + * @private + * @param {Object} object The object to modify. + * @param {string} key The key of the property to assign. + * @param {*} value The value to assign. + */ + function assignValue(object, key, value) { + var objValue = object[key]; + if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) || + (value === undefined && !(key in object))) { + object[key] = value; + } + } + + /** + * Gets the index at which the `key` is found in `array` of key-value pairs. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} key The key to search for. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function assocIndexOf(array, key) { + var length = array.length; + while (length--) { + if (eq(array[length][0], key)) { + return length; + } + } + return -1; + } + + /** + * The base implementation of `_.assign` without support for multiple sources + * or `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @returns {Object} Returns `object`. + */ + function baseAssign(object, source) { + return object && copyObject(source, keys(source), object); + } + + /** + * The base implementation of `_.clone` and `_.cloneDeep` which tracks + * traversed objects. + * + * @private + * @param {*} value The value to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @param {boolean} [isFull] Specify a clone including symbols. + * @param {Function} [customizer] The function to customize cloning. + * @param {string} [key] The key of `value`. + * @param {Object} [object] The parent object of `value`. + * @param {Object} [stack] Tracks traversed objects and their clone counterparts. + * @returns {*} Returns the cloned value. + */ + function baseClone(value, isDeep, isFull, customizer, key, object, stack) { + var result; + if (customizer) { + result = object ? customizer(value, key, object, stack) : customizer(value); + } + if (result !== undefined) { + return result; + } + if (!isObject(value)) { + return value; + } + var isArr = isArray(value); + if (isArr) { + result = initCloneArray(value); + if (!isDeep) { + return copyArray(value, result); + } + } else { + var tag = getTag(value), + isFunc = tag == funcTag || tag == genTag; + + if (isBuffer(value)) { + return cloneBuffer(value, isDeep); + } + if (tag == objectTag || tag == argsTag || (isFunc && !object)) { + if (isHostObject(value)) { + return object ? value : {}; + } + result = initCloneObject(isFunc ? {} : value); + if (!isDeep) { + return copySymbols(value, baseAssign(result, value)); + } + } else { + if (!cloneableTags[tag]) { + return object ? value : {}; + } + result = initCloneByTag(value, tag, baseClone, isDeep); + } + } + // Check for circular references and return its corresponding clone. + stack || (stack = new Stack); + var stacked = stack.get(value); + if (stacked) { + return stacked; + } + stack.set(value, result); + + if (!isArr) { + var props = isFull ? getAllKeys(value) : keys(value); + } + arrayEach(props || value, function(subValue, key) { + if (props) { + key = subValue; + subValue = value[key]; + } + // Recursively populate clone (susceptible to call stack limits). + assignValue(result, key, baseClone(subValue, isDeep, isFull, customizer, key, value, stack)); + }); + return result; + } + + /** + * The base implementation of `_.create` without support for assigning + * properties to the created object. + * + * @private + * @param {Object} prototype The object to inherit from. + * @returns {Object} Returns the new object. + */ + function baseCreate(proto) { + return isObject(proto) ? objectCreate(proto) : {}; + } + + /** + * The base implementation of `getAllKeys` and `getAllKeysIn` which uses + * `keysFunc` and `symbolsFunc` to get the enumerable property names and + * symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Function} keysFunc The function to get the keys of `object`. + * @param {Function} symbolsFunc The function to get the symbols of `object`. + * @returns {Array} Returns the array of property names and symbols. + */ + function baseGetAllKeys(object, keysFunc, symbolsFunc) { + var result = keysFunc(object); + return isArray(object) ? result : arrayPush(result, symbolsFunc(object)); + } + + /** + * The base implementation of `getTag`. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the `toStringTag`. + */ + function baseGetTag(value) { + return objectToString.call(value); + } + + /** + * The base implementation of `_.isNative` without bad shim checks. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a native function, + * else `false`. + */ + function baseIsNative(value) { + if (!isObject(value) || isMasked(value)) { + return false; + } + var pattern = (isFunction(value) || isHostObject(value)) ? reIsNative : reIsHostCtor; + return pattern.test(toSource(value)); + } + + /** + * The base implementation of `_.keys` which doesn't treat sparse arrays as dense. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ + function baseKeys(object) { + if (!isPrototype(object)) { + return nativeKeys(object); + } + var result = []; + for (var key in Object(object)) { + if (hasOwnProperty.call(object, key) && key != 'constructor') { + result.push(key); + } + } + return result; + } + + /** + * Creates a clone of `buffer`. + * + * @private + * @param {Buffer} buffer The buffer to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Buffer} Returns the cloned buffer. + */ + function cloneBuffer(buffer, isDeep) { + if (isDeep) { + return buffer.slice(); + } + var result = new buffer.constructor(buffer.length); + buffer.copy(result); + return result; + } + + /** + * Creates a clone of `arrayBuffer`. + * + * @private + * @param {ArrayBuffer} arrayBuffer The array buffer to clone. + * @returns {ArrayBuffer} Returns the cloned array buffer. + */ + function cloneArrayBuffer(arrayBuffer) { + var result = new arrayBuffer.constructor(arrayBuffer.byteLength); + new Uint8Array(result).set(new Uint8Array(arrayBuffer)); + return result; + } + + /** + * Creates a clone of `dataView`. + * + * @private + * @param {Object} dataView The data view to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned data view. + */ + function cloneDataView(dataView, isDeep) { + var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer; + return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength); + } + + /** + * Creates a clone of `map`. + * + * @private + * @param {Object} map The map to clone. + * @param {Function} cloneFunc The function to clone values. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned map. + */ + function cloneMap(map, isDeep, cloneFunc) { + var array = isDeep ? cloneFunc(mapToArray(map), true) : mapToArray(map); + return arrayReduce(array, addMapEntry, new map.constructor); + } + + /** + * Creates a clone of `regexp`. + * + * @private + * @param {Object} regexp The regexp to clone. + * @returns {Object} Returns the cloned regexp. + */ + function cloneRegExp(regexp) { + var result = new regexp.constructor(regexp.source, reFlags.exec(regexp)); + result.lastIndex = regexp.lastIndex; + return result; + } + + /** + * Creates a clone of `set`. + * + * @private + * @param {Object} set The set to clone. + * @param {Function} cloneFunc The function to clone values. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned set. + */ + function cloneSet(set, isDeep, cloneFunc) { + var array = isDeep ? cloneFunc(setToArray(set), true) : setToArray(set); + return arrayReduce(array, addSetEntry, new set.constructor); + } + + /** + * Creates a clone of the `symbol` object. + * + * @private + * @param {Object} symbol The symbol object to clone. + * @returns {Object} Returns the cloned symbol object. + */ + function cloneSymbol(symbol) { + return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {}; + } + + /** + * Creates a clone of `typedArray`. + * + * @private + * @param {Object} typedArray The typed array to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned typed array. + */ + function cloneTypedArray(typedArray, isDeep) { + var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer; + return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length); + } + + /** + * Copies the values of `source` to `array`. + * + * @private + * @param {Array} source The array to copy values from. + * @param {Array} [array=[]] The array to copy values to. + * @returns {Array} Returns `array`. + */ + function copyArray(source, array) { + var index = -1, + length = source.length; + + array || (array = Array(length)); + while (++index < length) { + array[index] = source[index]; + } + return array; + } + + /** + * Copies properties of `source` to `object`. + * + * @private + * @param {Object} source The object to copy properties from. + * @param {Array} props The property identifiers to copy. + * @param {Object} [object={}] The object to copy properties to. + * @param {Function} [customizer] The function to customize copied values. + * @returns {Object} Returns `object`. + */ + function copyObject(source, props, object, customizer) { + object || (object = {}); + + var index = -1, + length = props.length; + + while (++index < length) { + var key = props[index]; + + var newValue = undefined; + + assignValue(object, key, newValue === undefined ? source[key] : newValue); + } + return object; + } + + /** + * Copies own symbol properties of `source` to `object`. + * + * @private + * @param {Object} source The object to copy symbols from. + * @param {Object} [object={}] The object to copy symbols to. + * @returns {Object} Returns `object`. + */ + function copySymbols(source, object) { + return copyObject(source, getSymbols(source), object); + } + + /** + * Creates an array of own enumerable property names and symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names and symbols. + */ + function getAllKeys(object) { + return baseGetAllKeys(object, keys, getSymbols); + } + + /** + * Gets the data for `map`. + * + * @private + * @param {Object} map The map to query. + * @param {string} key The reference key. + * @returns {*} Returns the map data. + */ + function getMapData(map, key) { + var data = map.__data__; + return isKeyable(key) + ? data[typeof key == 'string' ? 'string' : 'hash'] + : data.map; + } + + /** + * Gets the native function at `key` of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {string} key The key of the method to get. + * @returns {*} Returns the function if it's native, else `undefined`. + */ + function getNative(object, key) { + var value = getValue(object, key); + return baseIsNative(value) ? value : undefined; + } + + /** + * Creates an array of the own enumerable symbol properties of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. + */ + var getSymbols = nativeGetSymbols ? overArg(nativeGetSymbols, Object) : stubArray; + + /** + * Gets the `toStringTag` of `value`. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the `toStringTag`. + */ + var getTag = baseGetTag; + + // Fallback for data views, maps, sets, and weak maps in IE 11, + // for data views in Edge < 14, and promises in Node.js. + if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) || + (Map && getTag(new Map) != mapTag) || + (Promise && getTag(Promise.resolve()) != promiseTag) || + (Set && getTag(new Set) != setTag) || + (WeakMap && getTag(new WeakMap) != weakMapTag)) { + getTag = function(value) { + var result = objectToString.call(value), + Ctor = result == objectTag ? value.constructor : undefined, + ctorString = Ctor ? toSource(Ctor) : undefined; + + if (ctorString) { + switch (ctorString) { + case dataViewCtorString: return dataViewTag; + case mapCtorString: return mapTag; + case promiseCtorString: return promiseTag; + case setCtorString: return setTag; + case weakMapCtorString: return weakMapTag; + } + } + return result; + }; + } + + /** + * Initializes an array clone. + * + * @private + * @param {Array} array The array to clone. + * @returns {Array} Returns the initialized clone. + */ + function initCloneArray(array) { + var length = array.length, + result = array.constructor(length); + + // Add properties assigned by `RegExp#exec`. + if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) { + result.index = array.index; + result.input = array.input; + } + return result; + } + + /** + * Initializes an object clone. + * + * @private + * @param {Object} object The object to clone. + * @returns {Object} Returns the initialized clone. + */ + function initCloneObject(object) { + return (typeof object.constructor == 'function' && !isPrototype(object)) + ? baseCreate(getPrototype(object)) + : {}; + } + + /** + * Initializes an object clone based on its `toStringTag`. + * + * **Note:** This function only supports cloning values with tags of + * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. + * + * @private + * @param {Object} object The object to clone. + * @param {string} tag The `toStringTag` of the object to clone. + * @param {Function} cloneFunc The function to clone values. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the initialized clone. + */ + function initCloneByTag(object, tag, cloneFunc, isDeep) { + var Ctor = object.constructor; + switch (tag) { + case arrayBufferTag: + return cloneArrayBuffer(object); + + case boolTag: + case dateTag: + return new Ctor(+object); + + case dataViewTag: + return cloneDataView(object, isDeep); + + case float32Tag: case float64Tag: + case int8Tag: case int16Tag: case int32Tag: + case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag: + return cloneTypedArray(object, isDeep); + + case mapTag: + return cloneMap(object, isDeep, cloneFunc); + + case numberTag: + case stringTag: + return new Ctor(object); + + case regexpTag: + return cloneRegExp(object); + + case setTag: + return cloneSet(object, isDeep, cloneFunc); + + case symbolTag: + return cloneSymbol(object); + } + } + + /** + * Checks if `value` is a valid array-like index. + * + * @private + * @param {*} value The value to check. + * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. + * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. + */ + function isIndex(value, length) { + length = length == null ? MAX_SAFE_INTEGER : length; + return !!length && + (typeof value == 'number' || reIsUint.test(value)) && + (value > -1 && value % 1 == 0 && value < length); + } + + /** + * Checks if `value` is suitable for use as unique object key. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is suitable, else `false`. + */ + function isKeyable(value) { + var type = typeof value; + return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean') + ? (value !== '__proto__') + : (value === null); + } + + /** + * Checks if `func` has its source masked. + * + * @private + * @param {Function} func The function to check. + * @returns {boolean} Returns `true` if `func` is masked, else `false`. + */ + function isMasked(func) { + return !!maskSrcKey && (maskSrcKey in func); + } + + /** + * Checks if `value` is likely a prototype object. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a prototype, else `false`. + */ + function isPrototype(value) { + var Ctor = value && value.constructor, + proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto; + + return value === proto; + } + + /** + * Converts `func` to its source code. + * + * @private + * @param {Function} func The function to process. + * @returns {string} Returns the source code. + */ + function toSource(func) { + if (func != null) { + try { + return funcToString.call(func); + } catch (e) {} + try { + return (func + ''); + } catch (e) {} + } + return ''; + } + + /** + * This method is like `_.clone` except that it recursively clones `value`. + * + * @static + * @memberOf _ + * @since 1.0.0 + * @category Lang + * @param {*} value The value to recursively clone. + * @returns {*} Returns the deep cloned value. + * @see _.clone + * @example + * + * var objects = [{ 'a': 1 }, { 'b': 2 }]; + * + * var deep = _.cloneDeep(objects); + * console.log(deep[0] === objects[0]); + * // => false + */ + function cloneDeep(value) { + return baseClone(value, true, true); + } + + /** + * Performs a + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * comparison between two values to determine if they are equivalent. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'a': 1 }; + * var other = { 'a': 1 }; + * + * _.eq(object, object); + * // => true + * + * _.eq(object, other); + * // => false + * + * _.eq('a', 'a'); + * // => true + * + * _.eq('a', Object('a')); + * // => false + * + * _.eq(NaN, NaN); + * // => true + */ + function eq(value, other) { + return value === other || (value !== value && other !== other); + } + + /** + * Checks if `value` is likely an `arguments` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an `arguments` object, + * else `false`. + * @example + * + * _.isArguments(function() { return arguments; }()); + * // => true + * + * _.isArguments([1, 2, 3]); + * // => false + */ + function isArguments(value) { + // Safari 8.1 makes `arguments.callee` enumerable in strict mode. + return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') && + (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag); + } + + /** + * Checks if `value` is classified as an `Array` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array, else `false`. + * @example + * + * _.isArray([1, 2, 3]); + * // => true + * + * _.isArray(document.body.children); + * // => false + * + * _.isArray('abc'); + * // => false + * + * _.isArray(_.noop); + * // => false + */ + var isArray = Array.isArray; + + /** + * Checks if `value` is array-like. A value is considered array-like if it's + * not a function and has a `value.length` that's an integer greater than or + * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is array-like, else `false`. + * @example + * + * _.isArrayLike([1, 2, 3]); + * // => true + * + * _.isArrayLike(document.body.children); + * // => true + * + * _.isArrayLike('abc'); + * // => true + * + * _.isArrayLike(_.noop); + * // => false + */ + function isArrayLike(value) { + return value != null && isLength(value.length) && !isFunction(value); + } + + /** + * This method is like `_.isArrayLike` except that it also checks if `value` + * is an object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array-like object, + * else `false`. + * @example + * + * _.isArrayLikeObject([1, 2, 3]); + * // => true + * + * _.isArrayLikeObject(document.body.children); + * // => true + * + * _.isArrayLikeObject('abc'); + * // => false + * + * _.isArrayLikeObject(_.noop); + * // => false + */ + function isArrayLikeObject(value) { + return isObjectLike(value) && isArrayLike(value); + } + + /** + * Checks if `value` is a buffer. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a buffer, else `false`. + * @example + * + * _.isBuffer(new Buffer(2)); + * // => true + * + * _.isBuffer(new Uint8Array(2)); + * // => false + */ + var isBuffer = nativeIsBuffer || stubFalse; + + /** + * Checks if `value` is classified as a `Function` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a function, else `false`. + * @example + * + * _.isFunction(_); + * // => true + * + * _.isFunction(/abc/); + * // => false + */ + function isFunction(value) { + // The use of `Object#toString` avoids issues with the `typeof` operator + // in Safari 8-9 which returns 'object' for typed array and other constructors. + var tag = isObject(value) ? objectToString.call(value) : ''; + return tag == funcTag || tag == genTag; + } + + /** + * Checks if `value` is a valid array-like length. + * + * **Note:** This method is loosely based on + * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. + * @example + * + * _.isLength(3); + * // => true + * + * _.isLength(Number.MIN_VALUE); + * // => false + * + * _.isLength(Infinity); + * // => false + * + * _.isLength('3'); + * // => false + */ + function isLength(value) { + return typeof value == 'number' && + value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; + } + + /** + * Checks if `value` is the + * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) + * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(_.noop); + * // => true + * + * _.isObject(null); + * // => false + */ + function isObject(value) { + var type = typeof value; + return !!value && (type == 'object' || type == 'function'); + } + + /** + * Checks if `value` is object-like. A value is object-like if it's not `null` + * and has a `typeof` result of "object". + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @example + * + * _.isObjectLike({}); + * // => true + * + * _.isObjectLike([1, 2, 3]); + * // => true + * + * _.isObjectLike(_.noop); + * // => false + * + * _.isObjectLike(null); + * // => false + */ + function isObjectLike(value) { + return !!value && typeof value == 'object'; + } + + /** + * Creates an array of the own enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. See the + * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) + * for more details. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keys(new Foo); + * // => ['a', 'b'] (iteration order is not guaranteed) + * + * _.keys('hi'); + * // => ['0', '1'] + */ + function keys(object) { + return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object); + } + + /** + * This method returns a new empty array. + * + * @static + * @memberOf _ + * @since 4.13.0 + * @category Util + * @returns {Array} Returns the new empty array. + * @example + * + * var arrays = _.times(2, _.stubArray); + * + * console.log(arrays); + * // => [[], []] + * + * console.log(arrays[0] === arrays[1]); + * // => false + */ + function stubArray() { + return []; + } + + /** + * This method returns `false`. + * + * @static + * @memberOf _ + * @since 4.13.0 + * @category Util + * @returns {boolean} Returns `false`. + * @example + * + * _.times(2, _.stubFalse); + * // => [false, false] + */ + function stubFalse() { + return false; + } + + module.exports = cloneDeep; + } (lodash_clonedeep, lodash_clonedeep.exports)); + + var lodash_clonedeepExports = lodash_clonedeep.exports; + var cloneDeep = /*@__PURE__*/getDefaultExportFromCjs$1(lodash_clonedeepExports); + + function applyContextDelta(context, delta, logger) { + try { + if (logger?.canPublish("trace")) { + logger?.trace(`applying context delta ${JSON.stringify(delta)} on context ${JSON.stringify(context)}`); + } + if (!delta) { + return context; + } + if (delta.reset) { + context = { ...delta.reset }; + return context; + } + context = deepClone(context, undefined); + if (delta.commands) { + for (const command of delta.commands) { + if (command.type === "remove") { + deletePath(context, command.path); + } + else if (command.type === "set") { + setValueToPath(context, command.value, command.path); + } + } + return context; + } + const added = delta.added; + const updated = delta.updated; + const removed = delta.removed; + if (added) { + Object.keys(added).forEach((key) => { + context[key] = added[key]; + }); + } + if (updated) { + Object.keys(updated).forEach((key) => { + mergeObjectsProperties(key, context, updated); + }); + } + if (removed) { + removed.forEach((key) => { + delete context[key]; + }); + } + return context; + } + catch (e) { + logger?.error(`error applying context delta ${JSON.stringify(delta)} on context ${JSON.stringify(context)}`, e); + return context; + } + } + function deepClone(obj, hash) { + return cloneDeep(obj); + } + const mergeObjectsProperties = (key, what, withWhat) => { + const right = withWhat[key]; + if (right === undefined) { + return what; + } + const left = what[key]; + if (!left || !right) { + what[key] = right; + return what; + } + if (typeof left === "string" || + typeof left === "number" || + typeof left === "boolean" || + typeof right === "string" || + typeof right === "number" || + typeof right === "boolean" || + Array.isArray(left) || + Array.isArray(right)) { + what[key] = right; + return what; + } + what[key] = Object.assign({}, left, right); + return what; + }; + function deepEqual(x, y) { + if (x === y) { + return true; + } + if (!(x instanceof Object) || !(y instanceof Object)) { + return false; + } + if (x.constructor !== y.constructor) { + return false; + } + for (const p in x) { + if (!x.hasOwnProperty(p)) { + continue; + } + if (!y.hasOwnProperty(p)) { + return false; + } + if (x[p] === y[p]) { + continue; + } + if (typeof (x[p]) !== "object") { + return false; + } + if (!deepEqual(x[p], y[p])) { + return false; + } + } + for (const p in y) { + if (y.hasOwnProperty(p) && !x.hasOwnProperty(p)) { + return false; + } + } + return true; + } + function setValueToPath(obj, value, path) { + const pathArr = path.split("."); + let i; + for (i = 0; i < pathArr.length - 1; i++) { + if (!obj[pathArr[i]]) { + obj[pathArr[i]] = {}; + } + if (typeof obj[pathArr[i]] !== "object") { + obj[pathArr[i]] = {}; + } + obj = obj[pathArr[i]]; + } + obj[pathArr[i]] = value; + } + function isSubset(superObj, subObj) { + return Object.keys(subObj).every((ele) => { + if (typeof subObj[ele] === "object") { + return isSubset(superObj?.[ele] || {}, subObj[ele] || {}); + } + return subObj[ele] === superObj?.[ele]; + }); + } + function deletePath(obj, path) { + const pathArr = path.split("."); + let i; + for (i = 0; i < pathArr.length - 1; i++) { + if (!obj[pathArr[i]]) { + return; + } + obj = obj[pathArr[i]]; + } + delete obj[pathArr[i]]; + } + + let GW3Bridge$1 = class GW3Bridge { + _logger; + _connection; + _trackAllContexts; + _reAnnounceKnownContexts; + _gw3Session; + _contextNameToData = {}; + _gw3Subscriptions = []; + _nextCallbackSubscriptionNumber = 0; + _creationPromises = {}; + _contextNameToId = {}; + _contextIdToName = {}; + _protocolVersion = undefined; + _contextsTempCache = {}; + _contextsSubscriptionsCache = []; + _systemContextsSubKey; + get protocolVersion() { + if (!this._protocolVersion) { + const contextsDomainInfo = this._connection.availableDomains.find((d) => d.uri === "context"); + this._protocolVersion = contextsDomainInfo?.version ?? 1; + } + return this._protocolVersion; + } + get setPathSupported() { + return this.protocolVersion >= 2; + } + constructor(config) { + this._connection = config.connection; + this._logger = config.logger; + this._trackAllContexts = config.trackAllContexts; + this._reAnnounceKnownContexts = config.reAnnounceKnownContexts; + this._gw3Session = this._connection.domain("global", [ + GW_MESSAGE_CONTEXT_CREATED, + GW_MESSAGE_SUBSCRIBED_CONTEXT, + GW_MESSAGE_CONTEXT_DESTROYED, + GW_MESSAGE_CONTEXT_UPDATED, + ]); + this._gw3Session.disconnected(this.resetState.bind(this)); + this._gw3Session.onJoined((wasReconnect) => { + if (!wasReconnect) { + return; + } + if (!this._reAnnounceKnownContexts) { + return this._connection.setLibReAnnounced({ name: "contexts" }); + } + this.reInitiateState().then(() => this._connection.setLibReAnnounced({ name: "contexts" })); + }); + this.subscribeToContextCreatedMessages(); + this.subscribeToContextUpdatedMessages(); + this.subscribeToContextDestroyedMessages(); + this._connection.replayer?.drain(ContextMessageReplaySpec.name, (message) => { + const type = message.type; + if (!type) { + return; + } + if (type === GW_MESSAGE_CONTEXT_CREATED || + type === GW_MESSAGE_CONTEXT_ADDED || + type === GW_MESSAGE_ACTIVITY_CREATED) { + this.handleContextCreatedMessage(message); + } + else if (type === GW_MESSAGE_SUBSCRIBED_CONTEXT || + type === GW_MESSAGE_CONTEXT_UPDATED || + type === GW_MESSAGE_JOINED_ACTIVITY) { + this.handleContextUpdatedMessage(message); + } + else if (type === GW_MESSAGE_CONTEXT_DESTROYED || + type === GW_MESSAGE_ACTIVITY_DESTROYED) { + this.handleContextDestroyedMessage(message); + } + }); + } + dispose() { + for (const sub of this._gw3Subscriptions) { + this._connection.off(sub); + } + this._gw3Subscriptions.length = 0; + for (const contextName in this._contextNameToData) { + if (this._contextNameToId.hasOwnProperty(contextName)) { + delete this._contextNameToData[contextName]; + } + } + } + createContext(name, data) { + if (name in this._creationPromises) { + return this._creationPromises[name]; + } + this._creationPromises[name] = + this._gw3Session + .send({ + type: GW_MESSAGE_CREATE_CONTEXT, + domain: "global", + name, + data, + lifetime: "retained", + }) + .then((createContextMsg) => { + this._contextNameToId[name] = createContextMsg.context_id; + this._contextIdToName[createContextMsg.context_id] = name; + const contextData = this._contextNameToData[name] || new GW3ContextData(createContextMsg.context_id, name, true, undefined); + contextData.isAnnounced = true; + contextData.name = name; + contextData.contextId = createContextMsg.context_id; + contextData.context = createContextMsg.data || deepClone(data); + contextData.hasReceivedSnapshot = true; + this._contextNameToData[name] = contextData; + delete this._creationPromises[name]; + return createContextMsg.context_id; + }); + return this._creationPromises[name]; + } + all() { + return Object.keys(this._contextNameToData) + .filter((name) => this._contextNameToData[name].isAnnounced); + } + async update(name, delta) { + if (delta) { + delta = deepClone(delta); + } + if (name in this._creationPromises) { + await this._creationPromises[name]; + } + const contextData = this._contextNameToData[name]; + if (!contextData || !contextData.isAnnounced) { + return this.createContext(name, delta); + } + let currentContext = contextData.context; + if (!contextData.hasCallbacks()) { + currentContext = await this.get(contextData.name); + } + const calculatedDelta = this.setPathSupported ? + this.calculateContextDeltaV2(currentContext, delta) : + this.calculateContextDeltaV1(currentContext, delta); + if (!Object.keys(calculatedDelta.added).length + && !Object.keys(calculatedDelta.updated).length + && !calculatedDelta.removed.length + && !calculatedDelta.commands?.length) { + return Promise.resolve(); + } + return this._gw3Session + .send({ + type: GW_MESSAGE_UPDATE_CONTEXT, + domain: "global", + context_id: contextData.contextId, + delta: calculatedDelta, + }, {}, { skipPeerId: false }) + .then((gwResponse) => { + this.handleUpdated(contextData, calculatedDelta, { + updaterId: gwResponse.peer_id + }); + }); + } + async set(name, data) { + if (data) { + data = deepClone(data); + } + if (name in this._creationPromises) { + await this._creationPromises[name]; + } + const contextData = this._contextNameToData[name]; + if (!contextData || !contextData.isAnnounced) { + return this.createContext(name, data); + } + return this._gw3Session + .send({ + type: GW_MESSAGE_UPDATE_CONTEXT, + domain: "global", + context_id: contextData.contextId, + delta: { reset: data }, + }, {}, { skipPeerId: false }) + .then((gwResponse) => { + this.handleUpdated(contextData, { + reset: data, + added: {}, + removed: [], + updated: {} + }, { + updaterId: gwResponse.peer_id + }); + }); + } + setPath(name, path, value) { + if (!this.setPathSupported) { + return Promise.reject("glue.contexts.setPath operation is not supported, use Glue42 3.10 or later"); + } + return this.setPaths(name, [{ path, value }]); + } + async setPaths(name, pathValues) { + if (!this.setPathSupported) { + return Promise.reject("glue.contexts.setPaths operation is not supported, use Glue42 3.10 or later"); + } + if (pathValues) { + pathValues = deepClone(pathValues); + } + if (name in this._creationPromises) { + await this._creationPromises[name]; + } + const contextData = this._contextNameToData[name]; + if (!contextData || !contextData.isAnnounced) { + const obj = {}; + for (const pathValue of pathValues) { + setValueToPath(obj, pathValue.value, pathValue.path); + } + return this.createContext(name, obj); + } + const commands = []; + for (const pathValue of pathValues) { + if (pathValue.value === null) { + commands.push({ type: "remove", path: pathValue.path }); + } + else { + commands.push({ type: "set", path: pathValue.path, value: pathValue.value }); + } + } + return this._gw3Session + .send({ + type: GW_MESSAGE_UPDATE_CONTEXT, + domain: "global", + context_id: contextData.contextId, + delta: { commands } + }, {}, { skipPeerId: false }) + .then((gwResponse) => { + this.handleUpdated(contextData, { + added: {}, + removed: [], + updated: {}, + commands + }, { + updaterId: gwResponse.peer_id + }); + }); + } + async get(name) { + if (name in this._creationPromises) { + await this._creationPromises[name]; + } + const contextData = this._contextNameToData[name]; + if (!contextData || !contextData.isAnnounced) { + return Promise.resolve({}); + } + if (contextData && (!contextData.hasCallbacks() || !contextData.hasReceivedSnapshot)) { + return new Promise((resolve) => { + this.subscribe(name, (data, _d, _r, un) => { + this.unsubscribe(un); + resolve(data); + }); + }); + } + const context = contextData?.context ?? {}; + return Promise.resolve(deepClone(context)); + } + async subscribe(name, callback, subscriptionKey) { + if (name in this._creationPromises) { + await this._creationPromises[name]; + } + const thisCallbackSubscriptionNumber = typeof subscriptionKey === "undefined" ? this._nextCallbackSubscriptionNumber : subscriptionKey; + if (typeof subscriptionKey === "undefined") { + this._nextCallbackSubscriptionNumber += 1; + } + if (this._contextsSubscriptionsCache.every((subscription) => subscription.subKey !== this._nextCallbackSubscriptionNumber)) { + this._contextsSubscriptionsCache.push({ contextName: name, subKey: thisCallbackSubscriptionNumber, callback }); + } + let contextData = this._contextNameToData[name]; + if (!contextData || + !contextData.isAnnounced) { + contextData = contextData || new GW3ContextData(undefined, name, false, undefined); + this._contextNameToData[name] = contextData; + contextData.updateCallbacks[thisCallbackSubscriptionNumber] = callback; + return Promise.resolve(thisCallbackSubscriptionNumber); + } + const hadCallbacks = contextData.hasCallbacks(); + contextData.updateCallbacks[thisCallbackSubscriptionNumber] = callback; + if (!hadCallbacks) { + if (!contextData.joinedActivity) { + if (contextData.context && contextData.sentExplicitSubscription) { + if (contextData.hasReceivedSnapshot) { + const clone = deepClone(contextData.context); + callback(clone, clone, [], thisCallbackSubscriptionNumber); + } + return Promise.resolve(thisCallbackSubscriptionNumber); + } + return this.sendSubscribe(contextData) + .then(() => thisCallbackSubscriptionNumber); + } + else { + if (contextData.hasReceivedSnapshot) { + const clone = deepClone(contextData.context); + callback(clone, clone, [], thisCallbackSubscriptionNumber); + } + return Promise.resolve(thisCallbackSubscriptionNumber); + } + } + else { + if (contextData.hasReceivedSnapshot) { + const clone = deepClone(contextData.context); + callback(clone, clone, [], thisCallbackSubscriptionNumber); + } + return Promise.resolve(thisCallbackSubscriptionNumber); + } + } + unsubscribe(subscriptionKey) { + this._contextsSubscriptionsCache = this._contextsSubscriptionsCache.filter((subscription) => subscription.subKey !== subscriptionKey); + for (const name of Object.keys(this._contextNameToData)) { + const contextData = this._contextNameToData[name]; + if (!contextData) { + return; + } + const hadCallbacks = contextData.hasCallbacks(); + delete contextData.updateCallbacks[subscriptionKey]; + if (contextData.isAnnounced && + hadCallbacks && + !contextData.hasCallbacks() && + contextData.sentExplicitSubscription) { + this.sendUnsubscribe(contextData).catch(() => { }); + } + if (!contextData.isAnnounced && + !contextData.hasCallbacks()) { + delete this._contextNameToData[name]; + } + } + } + async destroy(name) { + if (name in this._creationPromises) { + await this._creationPromises[name]; + } + const contextData = this._contextNameToData[name]; + if (!contextData) { + return Promise.reject(`context with ${name} does not exist`); + } + return this._gw3Session + .send({ + type: GW_MESSAGE_DESTROY_CONTEXT, + domain: "global", + context_id: contextData.contextId, + }).then((_) => undefined); + } + handleUpdated(contextData, delta, extraData) { + const oldContext = contextData.context; + contextData.context = applyContextDelta(contextData.context, delta, this._logger); + contextData.hasReceivedSnapshot = true; + if (this._contextNameToData[contextData.name] === contextData && + !deepEqual(oldContext, contextData.context)) { + this.invokeUpdateCallbacks(contextData, delta, extraData); + } + } + subscribeToContextCreatedMessages() { + const createdMessageTypes = [ + GW_MESSAGE_CONTEXT_ADDED, + GW_MESSAGE_CONTEXT_CREATED, + GW_MESSAGE_ACTIVITY_CREATED, + ]; + for (const createdMessageType of createdMessageTypes) { + const sub = this._connection.on(createdMessageType, this.handleContextCreatedMessage.bind(this)); + this._gw3Subscriptions.push(sub); + } + } + handleContextCreatedMessage(contextCreatedMsg) { + const createdMessageType = contextCreatedMsg.type; + if (createdMessageType === GW_MESSAGE_ACTIVITY_CREATED) { + this._contextNameToId[contextCreatedMsg.activity_id] = contextCreatedMsg.context_id; + this._contextIdToName[contextCreatedMsg.context_id] = contextCreatedMsg.activity_id; + } + else if (createdMessageType === GW_MESSAGE_CONTEXT_ADDED) { + this._contextNameToId[contextCreatedMsg.name] = contextCreatedMsg.context_id; + this._contextIdToName[contextCreatedMsg.context_id] = contextCreatedMsg.name; + } + else ; + const name = this._contextIdToName[contextCreatedMsg.context_id]; + if (!name) { + throw new Error("Received created event for context with unknown name: " + contextCreatedMsg.context_id); + } + if (!this._contextNameToId[name]) { + throw new Error("Received created event for context with unknown id: " + contextCreatedMsg.context_id); + } + let contextData = this._contextNameToData[name]; + if (contextData) { + if (contextData.isAnnounced) { + return; + } + else { + if (!contextData.hasCallbacks()) { + throw new Error("Assertion failure: contextData.hasCallbacks()"); + } + contextData.isAnnounced = true; + contextData.contextId = contextCreatedMsg.context_id; + contextData.activityId = contextCreatedMsg.activity_id; + if (!contextData.sentExplicitSubscription) { + this.sendSubscribe(contextData); + } + } + } + else { + this._contextNameToData[name] = contextData = + new GW3ContextData(contextCreatedMsg.context_id, name, true, contextCreatedMsg.activity_id); + if (this._trackAllContexts) { + this.subscribe(name, () => { }).then((subKey) => this._systemContextsSubKey = subKey); + } + } + } + subscribeToContextUpdatedMessages() { + const updatedMessageTypes = [ + GW_MESSAGE_CONTEXT_UPDATED, + GW_MESSAGE_SUBSCRIBED_CONTEXT, + GW_MESSAGE_JOINED_ACTIVITY, + ]; + for (const updatedMessageType of updatedMessageTypes) { + const sub = this._connection.on(updatedMessageType, this.handleContextUpdatedMessage.bind(this)); + this._gw3Subscriptions.push(sub); + } + } + handleContextUpdatedMessage(contextUpdatedMsg) { + const updatedMessageType = contextUpdatedMsg.type; + const contextId = contextUpdatedMsg.context_id; + let contextData = this._contextNameToData[this._contextIdToName[contextId]]; + const justSeen = !contextData || !contextData.isAnnounced; + if (updatedMessageType === GW_MESSAGE_JOINED_ACTIVITY) { + if (!contextData) { + contextData = + this._contextNameToData[contextUpdatedMsg.activity_id] || + new GW3ContextData(contextId, contextUpdatedMsg.activity_id, true, contextUpdatedMsg.activity_id); + } + this._contextNameToData[contextUpdatedMsg.activity_id] = contextData; + this._contextIdToName[contextId] = contextUpdatedMsg.activity_id; + this._contextNameToId[contextUpdatedMsg.activity_id] = contextId; + contextData.contextId = contextId; + contextData.isAnnounced = true; + contextData.activityId = contextUpdatedMsg.activity_id; + contextData.joinedActivity = true; + } + else { + if (!contextData || !contextData.isAnnounced) { + if (updatedMessageType === GW_MESSAGE_SUBSCRIBED_CONTEXT) { + contextData = contextData || new GW3ContextData(contextId, contextUpdatedMsg.name, true, undefined); + contextData.sentExplicitSubscription = true; + this._contextNameToData[contextUpdatedMsg.name] = contextData; + this._contextIdToName[contextId] = contextUpdatedMsg.name; + this._contextNameToId[contextUpdatedMsg.name] = contextId; + } + else { + this._logger.error(`Received 'update' for unknown context: ${contextId}`); + } + return; + } + } + const oldContext = contextData.context; + contextData.hasReceivedSnapshot = true; + if (updatedMessageType === GW_MESSAGE_SUBSCRIBED_CONTEXT) { + contextData.context = contextUpdatedMsg.data || {}; + } + else if (updatedMessageType === GW_MESSAGE_JOINED_ACTIVITY) { + contextData.context = contextUpdatedMsg.context_snapshot || {}; + } + else if (updatedMessageType === GW_MESSAGE_CONTEXT_UPDATED) { + contextData.context = applyContextDelta(contextData.context, contextUpdatedMsg.delta, this._logger); + } + else { + throw new Error("Unrecognized context update message " + updatedMessageType); + } + if (justSeen || + !deepEqual(contextData.context, oldContext) || + updatedMessageType === GW_MESSAGE_SUBSCRIBED_CONTEXT) { + this.invokeUpdateCallbacks(contextData, contextUpdatedMsg.delta, { updaterId: contextUpdatedMsg.updater_id }); + } + } + invokeUpdateCallbacks(contextData, delta, extraData) { + delta = delta || { added: {}, updated: {}, reset: {}, removed: [] }; + if (delta.commands) { + delta.added = delta.updated = delta.reset = {}; + delta.removed = []; + for (const command of delta.commands) { + if (command.type === "remove") { + if (command.path.indexOf(".") === -1) { + delta.removed.push(command.path); + } + setValueToPath(delta.updated, null, command.path); + } + else if (command.type === "set") { + setValueToPath(delta.updated, command.value, command.path); + } + } + } + for (const updateCallbackIndex in contextData.updateCallbacks) { + if (contextData.updateCallbacks.hasOwnProperty(updateCallbackIndex)) { + try { + const updateCallback = contextData.updateCallbacks[updateCallbackIndex]; + updateCallback(deepClone(contextData.context), deepClone(Object.assign({}, delta.added || {}, delta.updated || {}, delta.reset || {})), delta.removed, parseInt(updateCallbackIndex, 10), extraData); + } + catch (err) { + this._logger.debug("callback error: " + JSON.stringify(err)); + } + } + } + } + subscribeToContextDestroyedMessages() { + const destroyedMessageTypes = [ + GW_MESSAGE_CONTEXT_DESTROYED, + GW_MESSAGE_ACTIVITY_DESTROYED, + ]; + for (const destroyedMessageType of destroyedMessageTypes) { + const sub = this._connection.on(destroyedMessageType, this.handleContextDestroyedMessage.bind(this)); + this._gw3Subscriptions.push(sub); + } + } + handleContextDestroyedMessage(destroyedMsg) { + const destroyedMessageType = destroyedMsg.type; + let contextId; + let name; + if (destroyedMessageType === GW_MESSAGE_ACTIVITY_DESTROYED) { + name = destroyedMsg.activity_id; + contextId = this._contextNameToId[name]; + if (!contextId) { + this._logger.error(`Received 'destroyed' for unknown activity: ${destroyedMsg.activity_id}`); + return; + } + } + else { + contextId = destroyedMsg.context_id; + name = this._contextIdToName[contextId]; + if (!name) { + this._logger.error(`Received 'destroyed' for unknown context: ${destroyedMsg.context_id}`); + return; + } + } + delete this._contextIdToName[contextId]; + delete this._contextNameToId[name]; + const contextData = this._contextNameToData[name]; + delete this._contextNameToData[name]; + if (!contextData || !contextData.isAnnounced) { + this._logger.error(`Received 'destroyed' for unknown context: ${contextId}`); + return; + } + } + sendSubscribe(contextData) { + contextData.sentExplicitSubscription = true; + return this._gw3Session + .send({ + type: GW_MESSAGE_SUBSCRIBE_CONTEXT, + domain: "global", + context_id: contextData.contextId, + }).then((_) => undefined); + } + sendUnsubscribe(contextData) { + contextData.sentExplicitSubscription = false; + return this._gw3Session + .send({ + type: GW_MESSAGE_UNSUBSCRIBE_CONTEXT, + domain: "global", + context_id: contextData.contextId, + }).then((_) => undefined); + } + calculateContextDeltaV1(from, to) { + const delta = { added: {}, updated: {}, removed: [], reset: undefined }; + if (from) { + for (const x of Object.keys(from)) { + if (Object.keys(to).indexOf(x) !== -1 + && to[x] !== null + && !deepEqual(from[x], to[x])) { + delta.updated[x] = to[x]; + } + } + } + for (const x of Object.keys(to)) { + if (!from || (Object.keys(from).indexOf(x) === -1)) { + if (to[x] !== null) { + delta.added[x] = to[x]; + } + } + else if (to[x] === null) { + delta.removed.push(x); + } + } + return delta; + } + calculateContextDeltaV2(from, to) { + const delta = { added: {}, updated: {}, removed: [], reset: undefined, commands: [] }; + for (const x of Object.keys(to)) { + if (to[x] !== null) { + const fromX = from ? from[x] : null; + if (!deepEqual(fromX, to[x])) { + delta.commands?.push({ type: "set", path: x, value: to[x] }); + } + } + else { + delta.commands?.push({ type: "remove", path: x }); + } + } + return delta; + } + resetState() { + for (const sub of this._gw3Subscriptions) { + this._connection.off(sub); + } + if (this._systemContextsSubKey) { + this.unsubscribe(this._systemContextsSubKey); + delete this._systemContextsSubKey; + } + this._gw3Subscriptions = []; + this._contextNameToId = {}; + this._contextIdToName = {}; + delete this._protocolVersion; + this._contextsTempCache = Object.keys(this._contextNameToData).reduce((cacheSoFar, ctxName) => { + const contextData = this._contextNameToData[ctxName]; + if (contextData.isAnnounced && (contextData.activityId || contextData.sentExplicitSubscription)) { + cacheSoFar[ctxName] = this._contextNameToData[ctxName].context; + } + return cacheSoFar; + }, {}); + this._contextNameToData = {}; + } + async reInitiateState() { + this.subscribeToContextCreatedMessages(); + this.subscribeToContextUpdatedMessages(); + this.subscribeToContextDestroyedMessages(); + this._connection.replayer?.drain(ContextMessageReplaySpec.name, (message) => { + const type = message.type; + if (!type) { + return; + } + if (type === GW_MESSAGE_CONTEXT_CREATED || + type === GW_MESSAGE_CONTEXT_ADDED || + type === GW_MESSAGE_ACTIVITY_CREATED) { + this.handleContextCreatedMessage(message); + } + else if (type === GW_MESSAGE_SUBSCRIBED_CONTEXT || + type === GW_MESSAGE_CONTEXT_UPDATED || + type === GW_MESSAGE_JOINED_ACTIVITY) { + this.handleContextUpdatedMessage(message); + } + else if (type === GW_MESSAGE_CONTEXT_DESTROYED || + type === GW_MESSAGE_ACTIVITY_DESTROYED) { + this.handleContextDestroyedMessage(message); + } + }); + await Promise.all(this._contextsSubscriptionsCache.map((subscription) => this.subscribe(subscription.contextName, subscription.callback, subscription.subKey))); + await this.flushQueue(); + for (const ctxName in this._contextsTempCache) { + if (typeof this._contextsTempCache[ctxName] !== "object" || Object.keys(this._contextsTempCache[ctxName]).length === 0) { + continue; + } + const lastKnownData = this._contextsTempCache[ctxName]; + this._logger.info(`Re-announcing known context: ${ctxName}`); + await this.flushQueue(); + await this.update(ctxName, lastKnownData); + } + this._contextsTempCache = {}; + this._logger.info("Contexts are re-announced"); + } + flushQueue() { + return new Promise((resolve) => setTimeout(() => resolve(), 0)); + } + }; + + class ContextsModule { + initTime; + initStartTime; + initEndTime; + _bridge; + constructor(config) { + this._bridge = new GW3Bridge$1(config); + } + all() { + return this._bridge.all(); + } + update(name, data) { + this.checkName(name); + this.checkData(data); + return this._bridge.update(name, data); + } + set(name, data) { + this.checkName(name); + this.checkData(data); + return this._bridge.set(name, data); + } + setPath(name, path, data) { + this.checkName(name); + this.checkPath(path); + const isTopLevelPath = path === ""; + if (isTopLevelPath) { + this.checkData(data); + return this.set(name, data); + } + return this._bridge.setPath(name, path, data); + } + setPaths(name, paths) { + this.checkName(name); + if (!Array.isArray(paths)) { + throw new Error("Please provide the paths as an array of PathValues!"); + } + for (const { path, value } of paths) { + this.checkPath(path); + const isTopLevelPath = path === ""; + if (isTopLevelPath) { + this.checkData(value); + } + } + return this._bridge.setPaths(name, paths); + } + subscribe(name, callback) { + this.checkName(name); + if (typeof callback !== "function") { + throw new Error("Please provide the callback as a function!"); + } + return this._bridge + .subscribe(name, (data, delta, removed, key, extraData) => callback(data, delta, removed, () => this._bridge.unsubscribe(key), extraData)) + .then((key) => () => { + this._bridge.unsubscribe(key); + }); + } + get(name) { + this.checkName(name); + return this._bridge.get(name); + } + ready() { + return Promise.resolve(this); + } + destroy(name) { + this.checkName(name); + return this._bridge.destroy(name); + } + get setPathSupported() { + return this._bridge.setPathSupported; + } + checkName(name) { + if (typeof name !== "string" || name === "") { + throw new Error("Please provide the name as a non-empty string!"); + } + } + checkPath(path) { + if (typeof path !== "string") { + throw new Error("Please provide the path as a dot delimited string!"); + } + } + checkData(data) { + if (typeof data !== "object") { + throw new Error("Please provide the data as an object!"); + } + } + } + + function promisify$2 (promise, successCallback, errorCallback) { + if (typeof successCallback !== "function" && typeof errorCallback !== "function") { + return promise; + } + if (typeof successCallback !== "function") { + successCallback = () => { }; + } + else if (typeof errorCallback !== "function") { + errorCallback = () => { }; + } + return promise.then(successCallback, errorCallback); + } + + function rejectAfter(ms = 0, promise, error) { + let timeout; + const clearTimeoutIfThere = () => { + if (timeout) { + clearTimeout(timeout); + } + }; + promise + .then(() => { + clearTimeoutIfThere(); + }) + .catch(() => { + clearTimeoutIfThere(); + }); + return new Promise((resolve, reject) => { + timeout = setTimeout(() => reject(error), ms); + }); + } + + var InvokeStatus; + (function (InvokeStatus) { + InvokeStatus[InvokeStatus["Success"] = 0] = "Success"; + InvokeStatus[InvokeStatus["Error"] = 1] = "Error"; + })(InvokeStatus || (InvokeStatus = {})); + class Client { + protocol; + repo; + instance; + configuration; + constructor(protocol, repo, instance, configuration) { + this.protocol = protocol; + this.repo = repo; + this.instance = instance; + this.configuration = configuration; + } + subscribe(method, options, successCallback, errorCallback, existingSub) { + const callProtocolSubscribe = (targetServers, stream, successProxy, errorProxy) => { + options.methodResponseTimeout = options.methodResponseTimeout ?? options.waitTimeoutMs; + this.protocol.client.subscribe(stream, options, targetServers, successProxy, errorProxy, existingSub); + }; + const promise = new Promise((resolve, reject) => { + const successProxy = (sub) => { + resolve(sub); + }; + const errorProxy = (err) => { + reject(err); + }; + if (!method) { + reject(`Method definition is required. Please, provide either a unique string for a method name or a “methodDefinition” object with a required “name” property.`); + return; + } + let methodDef; + if (typeof method === "string") { + methodDef = { name: method }; + } + else { + methodDef = method; + } + if (!methodDef.name) { + reject(`Method definition is required. Please, provide either a unique string for a method name or a “methodDefinition” object with a required “name” property.`); + return; + } + if (options === undefined) { + options = {}; + } + let target = options.target; + if (target === undefined) { + target = "best"; + } + if (typeof target === "string" && target !== "all" && target !== "best") { + reject(new Error(`"${target}" is not a valid target. Valid targets are "all", "best", or an instance.`)); + return; + } + if (options.methodResponseTimeout === undefined) { + options.methodResponseTimeout = options.method_response_timeout; + if (options.methodResponseTimeout === undefined) { + options.methodResponseTimeout = this.configuration.methodResponseTimeout; + } + } + if (options.waitTimeoutMs === undefined) { + options.waitTimeoutMs = options.wait_for_method_timeout; + if (options.waitTimeoutMs === undefined) { + options.waitTimeoutMs = this.configuration.waitTimeoutMs; + } + } + const delayStep = 500; + let delayTillNow = 0; + let currentServers = this.getServerMethodsByFilterAndTarget(methodDef, target); + if (currentServers.length > 0) { + callProtocolSubscribe(currentServers, currentServers[0].methods[0], successProxy, errorProxy); + } + else { + const retry = () => { + if (!target || !(options.waitTimeoutMs)) { + return; + } + delayTillNow += delayStep; + currentServers = this.getServerMethodsByFilterAndTarget(methodDef, target); + if (currentServers.length > 0) { + const streamInfo = currentServers[0].methods[0]; + callProtocolSubscribe(currentServers, streamInfo, successProxy, errorProxy); + } + else if (delayTillNow >= options.waitTimeoutMs) { + const def = typeof method === "string" ? { name: method } : method; + callProtocolSubscribe(currentServers, def, successProxy, errorProxy); + } + else { + setTimeout(retry, delayStep); + } + }; + setTimeout(retry, delayStep); + } + }); + return promisify$2(promise, successCallback, errorCallback); + } + servers(methodFilter) { + const filterCopy = methodFilter === undefined + ? undefined + : { ...methodFilter }; + return this.getServers(filterCopy).map((serverMethodMap) => { + return serverMethodMap.server.instance; + }); + } + methods(methodFilter) { + if (typeof methodFilter === "string") { + methodFilter = { name: methodFilter }; + } + else { + methodFilter = { ...methodFilter }; + } + return this.getMethods(methodFilter); + } + methodsForInstance(instance) { + return this.getMethodsForInstance(instance); + } + methodAdded(callback) { + return this.repo.onMethodAdded(callback); + } + methodRemoved(callback) { + return this.repo.onMethodRemoved(callback); + } + serverAdded(callback) { + return this.repo.onServerAdded(callback); + } + serverRemoved(callback) { + return this.repo.onServerRemoved((server, reason) => { + callback(server, reason); + }); + } + serverMethodAdded(callback) { + return this.repo.onServerMethodAdded((server, method) => { + callback({ server, method }); + }); + } + serverMethodRemoved(callback) { + return this.repo.onServerMethodRemoved((server, method) => { + callback({ server, method }); + }); + } + async invoke(methodFilter, argumentObj, target, additionalOptions, success, error) { + const getInvokePromise = async () => { + let methodDefinition; + if (typeof methodFilter === "string") { + methodDefinition = { name: methodFilter }; + } + else { + methodDefinition = { ...methodFilter }; + } + if (!methodDefinition.name) { + return Promise.reject(`Method definition is required. Please, provide either a unique string for a method name or a “methodDefinition” object with a required “name” property.`); + } + if (!argumentObj) { + argumentObj = {}; + } + if (!target) { + target = "best"; + } + if (typeof target === "string" && target !== "all" && target !== "best" && target !== "skipMine") { + return Promise.reject(new Error(`"${target}" is not a valid target. Valid targets are "all" and "best".`)); + } + if (!additionalOptions) { + additionalOptions = {}; + } + if (additionalOptions.methodResponseTimeoutMs === undefined) { + additionalOptions.methodResponseTimeoutMs = additionalOptions.method_response_timeout; + if (additionalOptions.methodResponseTimeoutMs === undefined) { + additionalOptions.methodResponseTimeoutMs = this.configuration.methodResponseTimeout; + } + } + if (additionalOptions.waitTimeoutMs === undefined) { + additionalOptions.waitTimeoutMs = additionalOptions.wait_for_method_timeout; + if (additionalOptions.waitTimeoutMs === undefined) { + additionalOptions.waitTimeoutMs = this.configuration.waitTimeoutMs; + } + } + if (additionalOptions.waitTimeoutMs !== undefined && typeof additionalOptions.waitTimeoutMs !== "number") { + return Promise.reject(new Error(`"${additionalOptions.waitTimeoutMs}" is not a valid number for "waitTimeoutMs" `)); + } + if (typeof argumentObj !== "object") { + return Promise.reject(new Error(`The method arguments must be an object. method: ${methodDefinition.name}`)); + } + let serversMethodMap = this.getServerMethodsByFilterAndTarget(methodDefinition, target); + if (serversMethodMap.length === 0) { + try { + serversMethodMap = await this.tryToAwaitForMethods(methodDefinition, target, additionalOptions); + } + catch (err) { + const method = { + ...methodDefinition, + getServers: () => [], + supportsStreaming: false, + objectTypes: methodDefinition.objectTypes ?? [], + flags: methodDefinition.flags?.metadata ?? {} + }; + const errorObj = { + method, + called_with: argumentObj, + message: `Can not find a method matching ${JSON.stringify(methodFilter)} with server filter ${JSON.stringify(target)}`, + executed_by: undefined, + returned: undefined, + status: undefined, + }; + return Promise.reject(errorObj); + } + } + const timeout = additionalOptions.methodResponseTimeoutMs; + const additionalOptionsCopy = additionalOptions; + const invokePromises = serversMethodMap.map((serversMethodPair) => { + const invId = nanoid$1(10); + const method = serversMethodPair.methods[0]; + const server = serversMethodPair.server; + const invokePromise = this.protocol.client.invoke(invId, method, argumentObj, server, additionalOptionsCopy); + return Promise.race([ + invokePromise, + rejectAfter(timeout, invokePromise, { + invocationId: invId, + message: `Invocation timeout (${timeout} ms) reached for method name: ${method?.name}, target instance: ${JSON.stringify(server.instance)}, options: ${JSON.stringify(additionalOptionsCopy)}`, + status: InvokeStatus.Error, + }) + ]); + }); + const invocationMessages = await Promise.all(invokePromises); + const results = this.getInvocationResultObj(invocationMessages, methodDefinition, argumentObj); + const allRejected = invocationMessages.every((result) => result.status === InvokeStatus.Error); + if (allRejected) { + return Promise.reject(results); + } + return results; + }; + return promisify$2(getInvokePromise(), success, error); + } + getInvocationResultObj(invocationResults, method, calledWith) { + const all_return_values = invocationResults + .filter((invokeMessage) => invokeMessage.status === InvokeStatus.Success) + .reduce((allValues, currentValue) => { + allValues = [ + ...allValues, + { + executed_by: currentValue.instance, + returned: currentValue.result, + called_with: calledWith, + method, + message: currentValue.message, + status: currentValue.status, + } + ]; + return allValues; + }, []); + const all_errors = invocationResults + .filter((invokeMessage) => invokeMessage.status === InvokeStatus.Error) + .reduce((allErrors, currError) => { + allErrors = [ + ...allErrors, + { + executed_by: currError.instance, + called_with: calledWith, + name: method.name, + message: currError.message, + } + ]; + return allErrors; + }, []); + const invResult = invocationResults[0]; + const result = { + method, + called_with: calledWith, + returned: invResult.result, + executed_by: invResult.instance, + all_return_values, + all_errors, + message: invResult.message, + status: invResult.status + }; + return result; + } + tryToAwaitForMethods(methodDefinition, target, additionalOptions) { + return new Promise((resolve, reject) => { + if (additionalOptions.waitTimeoutMs === 0) { + reject(); + return; + } + const delayStep = 500; + let delayTillNow = 0; + const retry = () => { + delayTillNow += delayStep; + const serversMethodMap = this.getServerMethodsByFilterAndTarget(methodDefinition, target); + if (serversMethodMap.length > 0) { + clearInterval(interval); + resolve(serversMethodMap); + } + else if (delayTillNow >= (additionalOptions.waitTimeoutMs || 10000)) { + clearInterval(interval); + reject(); + return; + } + }; + const interval = setInterval(retry, delayStep); + }); + } + filterByTarget(target, serverMethodMap) { + if (typeof target === "string") { + if (target === "all") { + return [...serverMethodMap]; + } + else if (target === "best") { + const localMachine = serverMethodMap + .find((s) => s.server.instance.isLocal); + if (localMachine) { + return [localMachine]; + } + if (serverMethodMap[0] !== undefined) { + return [serverMethodMap[0]]; + } + } + else if (target === "skipMine") { + return serverMethodMap.filter(({ server }) => server.instance.peerId !== this.instance.peerId); + } + } + else { + let targetArray; + if (!Array.isArray(target)) { + targetArray = [target]; + } + else { + targetArray = target; + } + const allServersMatching = targetArray.reduce((matches, filter) => { + const myMatches = serverMethodMap.filter((serverMethodPair) => { + return this.instanceMatch(filter, serverMethodPair.server.instance); + }); + return matches.concat(myMatches); + }, []); + return allServersMatching; + } + return []; + } + instanceMatch(instanceFilter, instanceDefinition) { + if (instanceFilter?.peerId && instanceFilter?.instance) { + instanceFilter = { ...instanceFilter }; + delete instanceFilter.peerId; + } + return this.containsProps(instanceFilter, instanceDefinition); + } + methodMatch(methodFilter, methodDefinition) { + return this.containsProps(methodFilter, methodDefinition); + } + containsProps(filter, repoMethod) { + const filterProps = Object.keys(filter) + .filter((prop) => { + return filter[prop] !== undefined + && filter[prop] !== null + && typeof filter[prop] !== "function" + && prop !== "object_types" + && prop !== "display_name" + && prop !== "id" + && prop !== "gatewayId" + && prop !== "identifier" + && prop[0] !== "_"; + }); + return filterProps.every((prop) => { + let isMatch; + const filterValue = filter[prop]; + const repoMethodValue = repoMethod[prop]; + switch (prop) { + case "objectTypes": + isMatch = (filterValue || []).every((filterValueEl) => { + return (repoMethodValue || []).includes(filterValueEl); + }); + break; + case "flags": + isMatch = isSubset(repoMethodValue || {}, filterValue || {}); + break; + default: + isMatch = String(filterValue).toLowerCase() === String(repoMethodValue).toLowerCase(); + } + return isMatch; + }); + } + getMethods(methodFilter) { + if (methodFilter === undefined) { + return this.repo.getMethods(); + } + const methods = this.repo.getMethods().filter((method) => { + return this.methodMatch(methodFilter, method); + }); + return methods; + } + getMethodsForInstance(instanceFilter) { + const allServers = this.repo.getServers(); + const matchingServers = allServers.filter((server) => { + return this.instanceMatch(instanceFilter, server.instance); + }); + if (matchingServers.length === 0) { + return []; + } + let resultMethodsObject = {}; + if (matchingServers.length === 1) { + resultMethodsObject = matchingServers[0].methods; + } + else { + matchingServers.forEach((server) => { + Object.keys(server.methods).forEach((methodKey) => { + const method = server.methods[methodKey]; + resultMethodsObject[method.identifier] = method; + }); + }); + } + return Object.keys(resultMethodsObject) + .map((key) => { + return resultMethodsObject[key]; + }); + } + getServers(methodFilter) { + const servers = this.repo.getServers(); + if (methodFilter === undefined) { + return servers.map((server) => { + return { server, methods: [] }; + }); + } + return servers.reduce((prev, current) => { + const methodsForServer = Object.values(current.methods); + const matchingMethods = methodsForServer.filter((method) => { + return this.methodMatch(methodFilter, method); + }); + if (matchingMethods.length > 0) { + prev.push({ server: current, methods: matchingMethods }); + } + return prev; + }, []); + } + getServerMethodsByFilterAndTarget(methodFilter, target) { + const serversMethodMap = this.getServers(methodFilter); + return this.filterByTarget(target, serversMethodMap); + } + } + + class ServerSubscription { + protocol; + repoMethod; + subscription; + constructor(protocol, repoMethod, subscription) { + this.protocol = protocol; + this.repoMethod = repoMethod; + this.subscription = subscription; + } + get stream() { + if (!this.repoMethod.stream) { + throw new Error("no stream"); + } + return this.repoMethod.stream; + } + get arguments() { return this.subscription.arguments || {}; } + get branchKey() { return this.subscription.branchKey; } + get instance() { + if (!this.subscription.instance) { + throw new Error("no instance"); + } + return this.subscription.instance; + } + close() { + this.protocol.server.closeSingleSubscription(this.repoMethod, this.subscription); + } + push(data) { + this.protocol.server.pushDataToSingle(this.repoMethod, this.subscription, data); + } + } + + class Request { + protocol; + repoMethod; + requestContext; + arguments; + instance; + constructor(protocol, repoMethod, requestContext) { + this.protocol = protocol; + this.repoMethod = repoMethod; + this.requestContext = requestContext; + this.arguments = requestContext.arguments; + this.instance = requestContext.instance; + } + accept() { + this.protocol.server.acceptRequestOnBranch(this.requestContext, this.repoMethod, ""); + } + acceptOnBranch(branch) { + this.protocol.server.acceptRequestOnBranch(this.requestContext, this.repoMethod, branch); + } + reject(reason) { + this.protocol.server.rejectRequest(this.requestContext, this.repoMethod, reason); + } + } + + let ServerStreaming$1 = class ServerStreaming { + protocol; + server; + constructor(protocol, server) { + this.protocol = protocol; + this.server = server; + protocol.server.onSubRequest((rc, rm) => this.handleSubRequest(rc, rm)); + protocol.server.onSubAdded((sub, rm) => this.handleSubAdded(sub, rm)); + protocol.server.onSubRemoved((sub, rm) => this.handleSubRemoved(sub, rm)); + } + handleSubRequest(requestContext, repoMethod) { + if (!(repoMethod && + repoMethod.streamCallbacks && + typeof repoMethod.streamCallbacks.subscriptionRequestHandler === "function")) { + return; + } + const request = new Request(this.protocol, repoMethod, requestContext); + repoMethod.streamCallbacks.subscriptionRequestHandler(request); + } + handleSubAdded(subscription, repoMethod) { + if (!(repoMethod && + repoMethod.streamCallbacks && + typeof repoMethod.streamCallbacks.subscriptionAddedHandler === "function")) { + return; + } + const sub = new ServerSubscription(this.protocol, repoMethod, subscription); + repoMethod.streamCallbacks.subscriptionAddedHandler(sub); + } + handleSubRemoved(subscription, repoMethod) { + if (!(repoMethod && + repoMethod.streamCallbacks && + typeof repoMethod.streamCallbacks.subscriptionRemovedHandler === "function")) { + return; + } + const sub = new ServerSubscription(this.protocol, repoMethod, subscription); + repoMethod.streamCallbacks.subscriptionRemovedHandler(sub); + } + }; + + class ServerBranch { + key; + protocol; + repoMethod; + constructor(key, protocol, repoMethod) { + this.key = key; + this.protocol = protocol; + this.repoMethod = repoMethod; + } + subscriptions() { + const subList = this.protocol.server.getSubscriptionList(this.repoMethod, this.key); + return subList.map((sub) => { + return new ServerSubscription(this.protocol, this.repoMethod, sub); + }); + } + close() { + this.protocol.server.closeAllSubscriptions(this.repoMethod, this.key); + } + push(data) { + this.protocol.server.pushData(this.repoMethod, data, [this.key]); + } + } + + class ServerStream { + _protocol; + _repoMethod; + _server; + name; + constructor(_protocol, _repoMethod, _server) { + this._protocol = _protocol; + this._repoMethod = _repoMethod; + this._server = _server; + this.name = this._repoMethod.definition.name; + } + branches(key) { + const bList = this._protocol.server.getBranchList(this._repoMethod); + if (key) { + if (bList.indexOf(key) > -1) { + return new ServerBranch(key, this._protocol, this._repoMethod); + } + return undefined; + } + else { + return bList.map((branchKey) => { + return new ServerBranch(branchKey, this._protocol, this._repoMethod); + }); + } + } + branch(key) { + return this.branches(key); + } + subscriptions() { + const subList = this._protocol.server.getSubscriptionList(this._repoMethod); + return subList.map((sub) => { + return new ServerSubscription(this._protocol, this._repoMethod, sub); + }); + } + get definition() { + const def2 = this._repoMethod.definition; + return { + accepts: def2.accepts, + description: def2.description, + displayName: def2.displayName, + name: def2.name, + objectTypes: def2.objectTypes, + returns: def2.returns, + supportsStreaming: def2.supportsStreaming, + flags: def2.flags?.metadata, + }; + } + close() { + this._protocol.server.closeAllSubscriptions(this._repoMethod); + this._server.unregister(this._repoMethod.definition, true); + } + push(data, branches) { + if (typeof branches !== "string" && !Array.isArray(branches) && branches !== undefined) { + throw new Error("invalid branches should be string or string array"); + } + if (typeof data !== "object") { + throw new Error("Invalid arguments. Data must be an object."); + } + this._protocol.server.pushData(this._repoMethod, data, branches); + } + updateRepoMethod(repoMethod) { + this._repoMethod = repoMethod; + } + } + + class Server { + protocol; + serverRepository; + streaming; + invocations = 0; + currentlyUnregistering = {}; + constructor(protocol, serverRepository) { + this.protocol = protocol; + this.serverRepository = serverRepository; + this.streaming = new ServerStreaming$1(protocol, this); + this.protocol.server.onInvoked(this.onMethodInvoked.bind(this)); + } + createStream(streamDef, callbacks, successCallback, errorCallback, existingStream) { + const promise = new Promise((resolve, reject) => { + if (!streamDef) { + reject("The stream name must be unique! Please, provide either a unique string for a stream name to “glue.interop.createStream()” or a “methodDefinition” object with a unique “name” property for the stream."); + return; + } + let streamMethodDefinition; + if (typeof streamDef === "string") { + streamMethodDefinition = { name: "" + streamDef }; + } + else { + streamMethodDefinition = { ...streamDef }; + } + if (!streamMethodDefinition.name) { + return reject(`The “name” property is required for the “streamDefinition” object and must be unique. Stream definition: ${JSON.stringify(streamMethodDefinition)}`); + } + const nameAlreadyExists = this.serverRepository.getList() + .some((serverMethod) => serverMethod.definition.name === streamMethodDefinition.name); + if (nameAlreadyExists) { + return reject(`A stream with the name "${streamMethodDefinition.name}" already exists! Please, provide a unique name for the stream.`); + } + streamMethodDefinition.supportsStreaming = true; + if (!callbacks) { + callbacks = {}; + } + if (typeof callbacks.subscriptionRequestHandler !== "function") { + callbacks.subscriptionRequestHandler = (request) => { + request.accept(); + }; + } + const repoMethod = this.serverRepository.add({ + definition: streamMethodDefinition, + streamCallbacks: callbacks, + protocolState: {}, + }); + this.protocol.server.createStream(repoMethod) + .then(() => { + let streamUserObject; + if (existingStream) { + streamUserObject = existingStream; + existingStream.updateRepoMethod(repoMethod); + } + else { + streamUserObject = new ServerStream(this.protocol, repoMethod, this); + } + repoMethod.stream = streamUserObject; + resolve(streamUserObject); + }) + .catch((err) => { + if (repoMethod.repoId) { + this.serverRepository.remove(repoMethod.repoId); + } + reject(err); + }); + }); + return promisify$2(promise, successCallback, errorCallback); + } + register(methodDefinition, callback) { + if (!methodDefinition) { + return Promise.reject("Method definition is required. Please, provide either a unique string for a method name or a “methodDefinition” object with a required “name” property."); + } + if (typeof callback !== "function") { + return Promise.reject(`The second parameter must be a callback function. Method: ${typeof methodDefinition === "string" ? methodDefinition : methodDefinition.name}`); + } + const wrappedCallbackFunction = async (context, resultCallback) => { + try { + const result = callback(context.args, context.instance); + if (result && typeof result.then === "function") { + const resultValue = await result; + resultCallback(undefined, resultValue); + } + else { + resultCallback(undefined, result); + } + } + catch (e) { + resultCallback(e ?? "", e ?? ""); + } + }; + wrappedCallbackFunction.userCallback = callback; + return this.registerCore(methodDefinition, wrappedCallbackFunction); + } + registerAsync(methodDefinition, callback) { + if (!methodDefinition) { + return Promise.reject("Method definition is required. Please, provide either a unique string for a method name or a “methodDefinition” object with a required “name” property."); + } + if (typeof callback !== "function") { + return Promise.reject(`The second parameter must be a callback function. Method: ${typeof methodDefinition === "string" ? methodDefinition : methodDefinition.name}`); + } + const wrappedCallback = async (context, resultCallback) => { + try { + let resultCalled = false; + const success = (result) => { + if (!resultCalled) { + resultCallback(undefined, result); + } + resultCalled = true; + }; + const error = (e) => { + if (!resultCalled) { + if (!e) { + e = ""; + } + resultCallback(e, e); + } + resultCalled = true; + }; + const methodResult = callback(context.args, context.instance, success, error); + if (methodResult && typeof methodResult.then === "function") { + methodResult + .then(success) + .catch(error); + } + } + catch (e) { + resultCallback(e, undefined); + } + }; + wrappedCallback.userCallbackAsync = callback; + return this.registerCore(methodDefinition, wrappedCallback); + } + async unregister(methodFilter, forStream = false) { + if (methodFilter === undefined) { + return Promise.reject("Please, provide either a unique string for a name or an object containing a “name” property."); + } + if (typeof methodFilter === "function") { + await this.unregisterWithPredicate(methodFilter, forStream); + return; + } + let methodDefinition; + if (typeof methodFilter === "string") { + methodDefinition = { name: methodFilter }; + } + else { + methodDefinition = methodFilter; + } + if (methodDefinition.name === undefined) { + return Promise.reject("Method name is required. Cannot find a method if the method name is undefined!"); + } + const methodToBeRemoved = this.serverRepository.getList().find((serverMethod) => { + return serverMethod.definition.name === methodDefinition.name + && (serverMethod.definition.supportsStreaming || false) === forStream; + }); + if (!methodToBeRemoved) { + return Promise.reject(`Method with a name "${methodDefinition.name}" does not exist or is not registered by your application!`); + } + await this.removeMethodsOrStreams([methodToBeRemoved]); + } + async unregisterWithPredicate(filterPredicate, forStream) { + const methodsOrStreamsToRemove = this.serverRepository.getList() + .filter((sm) => filterPredicate(sm.definition)) + .filter((serverMethod) => (serverMethod.definition.supportsStreaming || false) === forStream); + if (!methodsOrStreamsToRemove || methodsOrStreamsToRemove.length === 0) { + return Promise.reject(`Could not find a ${forStream ? "stream" : "method"} matching the specified condition!`); + } + await this.removeMethodsOrStreams(methodsOrStreamsToRemove); + } + removeMethodsOrStreams(methodsToRemove) { + const methodUnregPromises = []; + methodsToRemove.forEach((method) => { + const promise = this.protocol.server.unregister(method) + .then(() => { + if (method.repoId) { + this.serverRepository.remove(method.repoId); + } + }); + methodUnregPromises.push(promise); + this.addAsCurrentlyUnregistering(method.definition.name, promise); + }); + return Promise.all(methodUnregPromises); + } + async addAsCurrentlyUnregistering(methodName, promise) { + const timeout = new Promise((resolve) => setTimeout(resolve, 5000)); + this.currentlyUnregistering[methodName] = Promise.race([promise, timeout]).then(() => { + delete this.currentlyUnregistering[methodName]; + }); + } + async registerCore(method, theFunction) { + let methodDefinition; + if (typeof method === "string") { + methodDefinition = { name: "" + method }; + } + else { + methodDefinition = { ...method }; + } + if (!methodDefinition.name) { + return Promise.reject(`Please, provide a (unique) string value for the “name” property in the “methodDefinition” object: ${JSON.stringify(method)}`); + } + const unregisterInProgress = this.currentlyUnregistering[methodDefinition.name]; + if (typeof unregisterInProgress !== "undefined") { + await unregisterInProgress; + } + const nameAlreadyExists = this.serverRepository.getList() + .some((serverMethod) => serverMethod.definition.name === methodDefinition.name); + if (nameAlreadyExists) { + return Promise.reject(`A method with the name "${methodDefinition.name}" already exists! Please, provide a unique name for the method.`); + } + if (methodDefinition.supportsStreaming) { + return Promise.reject(`When you create methods with “glue.interop.register()” or “glue.interop.registerAsync()” the property “supportsStreaming” cannot be “true”. If you want “${methodDefinition.name}” to be a stream, please use the “glue.interop.createStream()” method.`); + } + const repoMethod = this.serverRepository.add({ + definition: methodDefinition, + theFunction, + protocolState: {}, + }); + return this.protocol.server.register(repoMethod) + .catch((err) => { + if (repoMethod?.repoId) { + this.serverRepository.remove(repoMethod.repoId); + } + throw err; + }); + } + onMethodInvoked(methodToExecute, invocationId, invocationArgs) { + if (!methodToExecute || !methodToExecute.theFunction) { + return; + } + methodToExecute.theFunction(invocationArgs, (err, result) => { + if (err !== undefined && err !== null) { + if (err.message && typeof err.message === "string") { + err = err.message; + } + else if (typeof err !== "string") { + try { + err = JSON.stringify(err); + } + catch (unStrException) { + err = `un-stringifyable error in onMethodInvoked! Top level prop names: ${Object.keys(err)}`; + } + } + } + if (!result) { + result = {}; + } + else if (typeof result !== "object" || Array.isArray(result)) { + result = { _value: result }; + } + this.protocol.server.methodInvocationResult(methodToExecute, invocationId, err, result); + }); + } + } + + class InstanceWrapper { + wrapped = {}; + constructor(API, instance, connection) { + this.wrapped.getMethods = function () { + return API.methodsForInstance(this); + }; + this.wrapped.getStreams = function () { + return API.methodsForInstance(this).filter((m) => m.supportsStreaming); + }; + if (instance) { + this.refreshWrappedObject(instance); + } + if (connection) { + connection.loggedIn(() => { + this.refresh(connection); + }); + this.refresh(connection); + } + } + unwrap() { + return this.wrapped; + } + refresh(connection) { + if (!connection) { + return; + } + const resolvedIdentity = connection?.resolvedIdentity; + const instance = Object.assign({}, resolvedIdentity ?? {}, { peerId: connection?.peerId }); + this.refreshWrappedObject(instance); + } + refreshWrappedObject(resolvedIdentity) { + Object.keys(resolvedIdentity).forEach((key) => { + this.wrapped[key] = resolvedIdentity[key]; + }); + this.wrapped.user = resolvedIdentity.user; + this.wrapped.instance = resolvedIdentity.instance; + this.wrapped.application = resolvedIdentity.application ?? nanoid$1(10); + this.wrapped.applicationName = resolvedIdentity.applicationName; + this.wrapped.pid = resolvedIdentity.pid ?? resolvedIdentity.process ?? Math.floor(Math.random() * 10000000000); + this.wrapped.machine = resolvedIdentity.machine; + this.wrapped.environment = resolvedIdentity.environment; + this.wrapped.region = resolvedIdentity.region; + this.wrapped.windowId = resolvedIdentity.windowId; + this.wrapped.isLocal = resolvedIdentity.isLocal ?? true; + this.wrapped.api = resolvedIdentity.api; + this.wrapped.service = resolvedIdentity.service; + this.wrapped.peerId = resolvedIdentity.peerId; + } + } + + const hideMethodSystemFlags = (method) => { + return { + ...method, + flags: method.flags.metadata || {} + }; + }; + class ClientRepository { + logger; + API; + servers = {}; + myServer; + methodsCount = {}; + callbacks = CallbackRegistryFactory$1(); + constructor(logger, API) { + this.logger = logger; + this.API = API; + const peerId = this.API.instance.peerId; + this.myServer = { + id: peerId, + methods: {}, + instance: this.API.instance, + wrapper: this.API.unwrappedInstance, + }; + this.servers[peerId] = this.myServer; + } + addServer(info, serverId) { + this.logger.debug(`adding server ${serverId}`); + const current = this.servers[serverId]; + if (current) { + return current.id; + } + const wrapper = new InstanceWrapper(this.API, info); + const serverEntry = { + id: serverId, + methods: {}, + instance: wrapper.unwrap(), + wrapper, + }; + this.servers[serverId] = serverEntry; + this.callbacks.execute("onServerAdded", serverEntry.instance); + return serverId; + } + removeServerById(id, reason) { + const server = this.servers[id]; + if (!server) { + this.logger.warn(`not aware of server ${id}, my state ${JSON.stringify(Object.keys(this.servers))}`); + return; + } + else { + this.logger.debug(`removing server ${id}`); + } + Object.keys(server.methods).forEach((methodId) => { + this.removeServerMethod(id, methodId); + }); + delete this.servers[id]; + this.callbacks.execute("onServerRemoved", server.instance, reason); + } + addServerMethod(serverId, method) { + const server = this.servers[serverId]; + if (!server) { + throw new Error("server does not exists"); + } + if (server.methods[method.id]) { + return; + } + const identifier = this.createMethodIdentifier(method); + const that = this; + const methodDefinition = { + identifier, + gatewayId: method.id, + name: method.name, + displayName: method.display_name, + description: method.description, + version: method.version, + objectTypes: method.object_types || [], + accepts: method.input_signature, + returns: method.result_signature, + supportsStreaming: typeof method.flags !== "undefined" ? method.flags.streaming : false, + flags: method.flags ?? {}, + getServers: () => { + return that.getServersByMethod(identifier); + } + }; + methodDefinition.object_types = methodDefinition.objectTypes; + methodDefinition.display_name = methodDefinition.displayName; + methodDefinition.version = methodDefinition.version; + server.methods[method.id] = methodDefinition; + const clientMethodDefinition = hideMethodSystemFlags(methodDefinition); + if (!this.methodsCount[identifier]) { + this.methodsCount[identifier] = 0; + this.callbacks.execute("onMethodAdded", clientMethodDefinition); + } + this.methodsCount[identifier] = this.methodsCount[identifier] + 1; + this.callbacks.execute("onServerMethodAdded", server.instance, clientMethodDefinition); + return methodDefinition; + } + removeServerMethod(serverId, methodId) { + const server = this.servers[serverId]; + if (!server) { + throw new Error("server does not exists"); + } + const method = server.methods[methodId]; + delete server.methods[methodId]; + const clientMethodDefinition = hideMethodSystemFlags(method); + this.methodsCount[method.identifier] = this.methodsCount[method.identifier] - 1; + if (this.methodsCount[method.identifier] === 0) { + this.callbacks.execute("onMethodRemoved", clientMethodDefinition); + } + this.callbacks.execute("onServerMethodRemoved", server.instance, clientMethodDefinition); + } + getMethods() { + return this.extractMethodsFromServers(Object.values(this.servers)).map(hideMethodSystemFlags); + } + getServers() { + return Object.values(this.servers).map(this.hideServerMethodSystemFlags); + } + onServerAdded(callback) { + const unsubscribeFunc = this.callbacks.add("onServerAdded", callback); + const serversWithMethodsToReplay = this.getServers().map((s) => s.instance); + return this.returnUnsubWithDelayedReplay(unsubscribeFunc, serversWithMethodsToReplay, callback); + } + onMethodAdded(callback) { + const unsubscribeFunc = this.callbacks.add("onMethodAdded", callback); + const methodsToReplay = this.getMethods(); + return this.returnUnsubWithDelayedReplay(unsubscribeFunc, methodsToReplay, callback); + } + onServerMethodAdded(callback) { + const unsubscribeFunc = this.callbacks.add("onServerMethodAdded", callback); + let unsubCalled = false; + const servers = this.getServers(); + setTimeout(() => { + servers.forEach((server) => { + const methods = server.methods; + Object.keys(methods).forEach((methodId) => { + if (!unsubCalled) { + callback(server.instance, methods[methodId]); + } + }); + }); + }, 0); + return () => { + unsubCalled = true; + unsubscribeFunc(); + }; + } + onMethodRemoved(callback) { + const unsubscribeFunc = this.callbacks.add("onMethodRemoved", callback); + return unsubscribeFunc; + } + onServerRemoved(callback) { + const unsubscribeFunc = this.callbacks.add("onServerRemoved", callback); + return unsubscribeFunc; + } + onServerMethodRemoved(callback) { + const unsubscribeFunc = this.callbacks.add("onServerMethodRemoved", callback); + return unsubscribeFunc; + } + getServerById(id) { + const server = this.servers[id]; + if (!server) { + return undefined; + } + return this.hideServerMethodSystemFlags(this.servers[id]); + } + reset() { + Object.keys(this.servers).forEach((key) => { + this.removeServerById(key, "reset"); + }); + this.servers = { + [this.myServer.id]: this.myServer + }; + this.methodsCount = {}; + } + createMethodIdentifier(methodInfo) { + const accepts = methodInfo.input_signature ?? ""; + const returns = methodInfo.result_signature ?? ""; + return (methodInfo.name + accepts + returns).toLowerCase(); + } + getServersByMethod(identifier) { + const allServers = []; + Object.values(this.servers).forEach((server) => { + Object.values(server.methods).forEach((method) => { + if (method.identifier === identifier) { + allServers.push(server.instance); + } + }); + }); + return allServers; + } + returnUnsubWithDelayedReplay(unsubscribeFunc, collectionToReplay, callback) { + let unsubCalled = false; + setTimeout(() => { + collectionToReplay.forEach((item) => { + if (!unsubCalled) { + callback(item); + } + }); + }, 0); + return () => { + unsubCalled = true; + unsubscribeFunc(); + }; + } + hideServerMethodSystemFlags(server) { + const clientMethods = {}; + Object.entries(server.methods).forEach(([name, method]) => { + clientMethods[name] = hideMethodSystemFlags(method); + }); + return { + ...server, + methods: clientMethods + }; + } + extractMethodsFromServers(servers) { + const methods = Object.values(servers).reduce((clientMethods, server) => { + return [...clientMethods, ...Object.values(server.methods)]; + }, []); + return methods; + } + } + + class ServerRepository { + nextId = 0; + methods = []; + add(method) { + method.repoId = String(this.nextId); + this.nextId += 1; + this.methods.push(method); + return method; + } + remove(repoId) { + if (typeof repoId !== "string") { + return new TypeError("Expecting a string"); + } + this.methods = this.methods.filter((m) => { + return m.repoId !== repoId; + }); + } + getById(id) { + if (typeof id !== "string") { + return undefined; + } + return this.methods.find((m) => { + return m.repoId === id; + }); + } + getList() { + return this.methods.map((m) => m); + } + length() { + return this.methods.length; + } + reset() { + this.methods = []; + } + } + + const SUBSCRIPTION_REQUEST = "onSubscriptionRequest"; + const SUBSCRIPTION_ADDED = "onSubscriptionAdded"; + const SUBSCRIPTION_REMOVED = "onSubscriptionRemoved"; + class ServerStreaming { + session; + repository; + serverRepository; + ERR_URI_SUBSCRIPTION_FAILED = "com.tick42.agm.errors.subscription.failure"; + callbacks = CallbackRegistryFactory$1(); + nextStreamId = 0; + constructor(session, repository, serverRepository) { + this.session = session; + this.repository = repository; + this.serverRepository = serverRepository; + session.on("add-interest", (msg) => { + this.handleAddInterest(msg); + }); + session.on("remove-interest", (msg) => { + this.handleRemoveInterest(msg); + }); + } + acceptRequestOnBranch(requestContext, streamingMethod, branch) { + if (typeof branch !== "string") { + branch = ""; + } + if (typeof streamingMethod.protocolState.subscriptionsMap !== "object") { + throw new TypeError("The streaming method is missing its subscriptions."); + } + if (!Array.isArray(streamingMethod.protocolState.branchKeyToStreamIdMap)) { + throw new TypeError("The streaming method is missing its branches."); + } + const streamId = this.getStreamId(streamingMethod, branch); + const key = requestContext.msg.subscription_id; + const subscription = { + id: key, + arguments: requestContext.arguments, + instance: requestContext.instance, + branchKey: branch, + streamId, + subscribeMsg: requestContext.msg, + }; + streamingMethod.protocolState.subscriptionsMap[key] = subscription; + this.session.sendFireAndForget({ + type: "accepted", + subscription_id: key, + stream_id: streamId, + }); + this.callbacks.execute(SUBSCRIPTION_ADDED, subscription, streamingMethod); + } + rejectRequest(requestContext, streamingMethod, reason) { + if (typeof reason !== "string") { + reason = ""; + } + this.sendSubscriptionFailed("Subscription rejected by user. " + reason, requestContext.msg.subscription_id); + } + pushData(streamingMethod, data, branches) { + if (typeof streamingMethod !== "object" || !Array.isArray(streamingMethod.protocolState.branchKeyToStreamIdMap)) { + return; + } + if (typeof data !== "object") { + throw new Error("Invalid arguments. Data must be an object."); + } + if (typeof branches === "string") { + branches = [branches]; + } + else if (!Array.isArray(branches) || branches.length <= 0) { + branches = []; + } + const streamIdList = streamingMethod.protocolState.branchKeyToStreamIdMap + .filter((br) => { + if (!branches || branches.length === 0) { + return true; + } + return branches.indexOf(br.key) >= 0; + }).map((br) => { + return br.streamId; + }); + streamIdList.forEach((streamId) => { + const publishMessage = { + type: "publish", + stream_id: streamId, + data, + }; + this.session.sendFireAndForget(publishMessage); + }); + } + pushDataToSingle(method, subscription, data) { + if (typeof data !== "object") { + throw new Error("Invalid arguments. Data must be an object."); + } + const postMessage = { + type: "post", + subscription_id: subscription.id, + data, + }; + this.session.sendFireAndForget(postMessage); + } + closeSingleSubscription(streamingMethod, subscription) { + if (streamingMethod.protocolState.subscriptionsMap) { + delete streamingMethod.protocolState.subscriptionsMap[subscription.id]; + } + const dropSubscriptionMessage = { + type: "drop-subscription", + subscription_id: subscription.id, + reason: "Server dropping a single subscription", + }; + this.session.sendFireAndForget(dropSubscriptionMessage); + subscription.instance; + this.callbacks.execute(SUBSCRIPTION_REMOVED, subscription, streamingMethod); + } + closeMultipleSubscriptions(streamingMethod, branchKey) { + if (typeof streamingMethod !== "object" || typeof streamingMethod.protocolState.subscriptionsMap !== "object") { + return; + } + if (!streamingMethod.protocolState.subscriptionsMap) { + return; + } + const subscriptionsMap = streamingMethod.protocolState.subscriptionsMap; + let subscriptionsToClose = Object.keys(subscriptionsMap) + .map((key) => { + return subscriptionsMap[key]; + }); + if (typeof branchKey === "string") { + subscriptionsToClose = subscriptionsToClose.filter((sub) => { + return sub.branchKey === branchKey; + }); + } + subscriptionsToClose.forEach((subscription) => { + delete subscriptionsMap[subscription.id]; + const drop = { + type: "drop-subscription", + subscription_id: subscription.id, + reason: "Server dropping all subscriptions on stream_id: " + subscription.streamId, + }; + this.session.sendFireAndForget(drop); + }); + } + getSubscriptionList(streamingMethod, branchKey) { + if (typeof streamingMethod !== "object") { + return []; + } + let subscriptions = []; + if (!streamingMethod.protocolState.subscriptionsMap) { + return []; + } + const subscriptionsMap = streamingMethod.protocolState.subscriptionsMap; + const allSubscriptions = Object.keys(subscriptionsMap) + .map((key) => { + return subscriptionsMap[key]; + }); + if (typeof branchKey !== "string") { + subscriptions = allSubscriptions; + } + else { + subscriptions = allSubscriptions.filter((sub) => { + return sub.branchKey === branchKey; + }); + } + return subscriptions; + } + getBranchList(streamingMethod) { + if (typeof streamingMethod !== "object") { + return []; + } + if (!streamingMethod.protocolState.subscriptionsMap) { + return []; + } + const subscriptionsMap = streamingMethod.protocolState.subscriptionsMap; + const allSubscriptions = Object.keys(subscriptionsMap) + .map((key) => { + return subscriptionsMap[key]; + }); + const result = []; + allSubscriptions.forEach((sub) => { + let branch = ""; + if (typeof sub === "object" && typeof sub.branchKey === "string") { + branch = sub.branchKey; + } + if (result.indexOf(branch) === -1) { + result.push(branch); + } + }); + return result; + } + onSubAdded(callback) { + this.onSubscriptionLifetimeEvent(SUBSCRIPTION_ADDED, callback); + } + onSubRequest(callback) { + this.onSubscriptionLifetimeEvent(SUBSCRIPTION_REQUEST, callback); + } + onSubRemoved(callback) { + this.onSubscriptionLifetimeEvent(SUBSCRIPTION_REMOVED, callback); + } + handleRemoveInterest(msg) { + const streamingMethod = this.serverRepository.getById(msg.method_id); + if (typeof msg.subscription_id !== "string" || + typeof streamingMethod !== "object") { + return; + } + if (!streamingMethod.protocolState.subscriptionsMap) { + return; + } + if (typeof streamingMethod.protocolState.subscriptionsMap[msg.subscription_id] !== "object") { + return; + } + const subscription = streamingMethod.protocolState.subscriptionsMap[msg.subscription_id]; + delete streamingMethod.protocolState.subscriptionsMap[msg.subscription_id]; + this.callbacks.execute(SUBSCRIPTION_REMOVED, subscription, streamingMethod); + } + onSubscriptionLifetimeEvent(eventName, handlerFunc) { + this.callbacks.add(eventName, handlerFunc); + } + getNextStreamId() { + return this.nextStreamId++ + ""; + } + handleAddInterest(msg) { + const caller = this.repository.getServerById(msg.caller_id); + const instance = caller?.instance ?? {}; + const requestContext = { + msg, + arguments: msg.arguments_kv || {}, + instance, + }; + const streamingMethod = this.serverRepository.getById(msg.method_id); + if (streamingMethod === undefined) { + const errorMsg = "No method with id " + msg.method_id + " on this server."; + this.sendSubscriptionFailed(errorMsg, msg.subscription_id); + return; + } + if (streamingMethod.protocolState.subscriptionsMap && + streamingMethod.protocolState.subscriptionsMap[msg.subscription_id]) { + this.sendSubscriptionFailed("A subscription with id " + msg.subscription_id + " already exists.", msg.subscription_id); + return; + } + this.callbacks.execute(SUBSCRIPTION_REQUEST, requestContext, streamingMethod); + } + sendSubscriptionFailed(reason, subscriptionId) { + const errorMessage = { + type: "error", + reason_uri: this.ERR_URI_SUBSCRIPTION_FAILED, + reason, + request_id: subscriptionId, + }; + this.session.sendFireAndForget(errorMessage); + } + getStreamId(streamingMethod, branchKey) { + if (typeof branchKey !== "string") { + branchKey = ""; + } + if (!streamingMethod.protocolState.branchKeyToStreamIdMap) { + throw new Error(`streaming ${streamingMethod.definition.name} method without protocol state`); + } + const needleBranch = streamingMethod.protocolState.branchKeyToStreamIdMap.filter((branch) => { + return branch.key === branchKey; + })[0]; + let streamId = (needleBranch ? needleBranch.streamId : undefined); + if (typeof streamId !== "string" || streamId === "") { + streamId = this.getNextStreamId(); + streamingMethod.protocolState.branchKeyToStreamIdMap.push({ key: branchKey, streamId }); + } + return streamId; + } + } + + class ServerProtocol { + session; + clientRepository; + serverRepository; + logger; + callbacks = CallbackRegistryFactory$1(); + streaming; + constructor(session, clientRepository, serverRepository, logger) { + this.session = session; + this.clientRepository = clientRepository; + this.serverRepository = serverRepository; + this.logger = logger; + this.streaming = new ServerStreaming(session, clientRepository, serverRepository); + this.session.on("invoke", (msg) => this.handleInvokeMessage(msg)); + } + createStream(repoMethod) { + repoMethod.protocolState.subscriptionsMap = {}; + repoMethod.protocolState.branchKeyToStreamIdMap = []; + return this.register(repoMethod, true); + } + register(repoMethod, isStreaming) { + const methodDef = repoMethod.definition; + const flags = Object.assign({}, { metadata: methodDef.flags ?? {} }, { streaming: isStreaming || false }); + const registerMsg = { + type: "register", + methods: [{ + id: repoMethod.repoId, + name: methodDef.name, + display_name: methodDef.displayName, + description: methodDef.description, + version: methodDef.version, + flags, + object_types: methodDef.objectTypes || methodDef.object_types, + input_signature: methodDef.accepts, + result_signature: methodDef.returns, + restrictions: undefined, + }], + }; + return this.session.send(registerMsg, { methodId: repoMethod.repoId }) + .then(() => { + this.logger.debug("registered method " + repoMethod.definition.name + " with id " + repoMethod.repoId); + }) + .catch((msg) => { + this.logger.warn(`failed to register method ${repoMethod.definition.name} with id ${repoMethod.repoId} - ${JSON.stringify(msg)}`); + throw msg; + }); + } + onInvoked(callback) { + this.callbacks.add("onInvoked", callback); + } + methodInvocationResult(method, invocationId, err, result) { + let msg; + if (err || err === "") { + msg = { + type: "error", + request_id: invocationId, + reason_uri: "agm.errors.client_error", + reason: err, + context: result, + peer_id: undefined, + }; + } + else { + msg = { + type: "yield", + invocation_id: invocationId, + peer_id: this.session.peerId, + result, + request_id: undefined, + }; + } + this.session.sendFireAndForget(msg); + } + async unregister(method) { + const msg = { + type: "unregister", + methods: [method.repoId], + }; + await this.session.send(msg); + } + getBranchList(method) { + return this.streaming.getBranchList(method); + } + getSubscriptionList(method, branchKey) { + return this.streaming.getSubscriptionList(method, branchKey); + } + closeAllSubscriptions(method, branchKey) { + this.streaming.closeMultipleSubscriptions(method, branchKey); + } + pushData(method, data, branches) { + this.streaming.pushData(method, data, branches); + } + pushDataToSingle(method, subscription, data) { + this.streaming.pushDataToSingle(method, subscription, data); + } + closeSingleSubscription(method, subscription) { + this.streaming.closeSingleSubscription(method, subscription); + } + acceptRequestOnBranch(requestContext, method, branch) { + this.streaming.acceptRequestOnBranch(requestContext, method, branch); + } + rejectRequest(requestContext, method, reason) { + this.streaming.rejectRequest(requestContext, method, reason); + } + onSubRequest(callback) { + this.streaming.onSubRequest(callback); + } + onSubAdded(callback) { + this.streaming.onSubAdded(callback); + } + onSubRemoved(callback) { + this.streaming.onSubRemoved(callback); + } + handleInvokeMessage(msg) { + const invocationId = msg.invocation_id; + const callerId = msg.caller_id; + const methodId = msg.method_id; + const args = msg.arguments_kv; + const methodList = this.serverRepository.getList(); + const method = methodList.filter((m) => { + return m.repoId === methodId; + })[0]; + if (method === undefined) { + return; + } + const client = this.clientRepository.getServerById(callerId)?.instance; + const invocationArgs = { args, instance: client }; + this.callbacks.execute("onInvoked", method, invocationId, invocationArgs); + } + } + + class UserSubscription { + repository; + subscriptionData; + get requestArguments() { + return this.subscriptionData.params.arguments || {}; + } + get servers() { + return this.subscriptionData.trackedServers.reduce((servers, pair) => { + if (pair.subscriptionId) { + const server = this.repository.getServerById(pair.serverId)?.instance; + if (server) { + servers.push(server); + } + } + return servers; + }, []); + } + get serverInstance() { + return this.servers[0]; + } + get stream() { + return this.subscriptionData.method; + } + constructor(repository, subscriptionData) { + this.repository = repository; + this.subscriptionData = subscriptionData; + } + onData(dataCallback) { + if (typeof dataCallback !== "function") { + throw new TypeError("The data callback must be a function."); + } + this.subscriptionData.handlers.onData.push(dataCallback); + if (this.subscriptionData.handlers.onData.length === 1 && this.subscriptionData.queued.data.length > 0) { + this.subscriptionData.queued.data.forEach((dataItem) => { + dataCallback(dataItem); + }); + } + } + onClosed(closedCallback) { + if (typeof closedCallback !== "function") { + throw new TypeError("The callback must be a function."); + } + this.subscriptionData.handlers.onClosed.push(closedCallback); + } + onFailed(callback) { + } + onConnected(callback) { + if (typeof callback !== "function") { + throw new TypeError("The callback must be a function."); + } + this.subscriptionData.handlers.onConnected.push(callback); + } + close() { + this.subscriptionData.close(); + } + setNewSubscription(newSub) { + this.subscriptionData = newSub; + } + } + + class TimedCache { + config; + cache = []; + timeoutIds = []; + constructor(config) { + this.config = config; + } + add(element) { + const id = nanoid$1(10); + this.cache.push({ id, element }); + const timeoutId = setTimeout(() => { + const elementIdx = this.cache.findIndex((entry) => entry.id === id); + if (elementIdx < 0) { + return; + } + this.cache.splice(elementIdx, 1); + }, this.config.ELEMENT_TTL_MS); + this.timeoutIds.push(timeoutId); + } + flush() { + const elements = this.cache.map((entry) => entry.element); + this.timeoutIds.forEach((id) => clearInterval(id)); + this.cache = []; + this.timeoutIds = []; + return elements; + } + } + + const STATUS_AWAITING_ACCEPT = "awaitingAccept"; + const STATUS_SUBSCRIBED = "subscribed"; + const ERR_MSG_SUB_FAILED = "Subscription failed."; + const ERR_MSG_SUB_REJECTED = "Subscription rejected."; + const ON_CLOSE_MSG_SERVER_INIT = "ServerInitiated"; + const ON_CLOSE_MSG_CLIENT_INIT = "ClientInitiated"; + class ClientStreaming { + session; + repository; + logger; + subscriptionsList = {}; + timedCache = new TimedCache({ ELEMENT_TTL_MS: 10000 }); + subscriptionIdToLocalKeyMap = {}; + nextSubLocalKey = 0; + constructor(session, repository, logger) { + this.session = session; + this.repository = repository; + this.logger = logger; + session.on("subscribed", this.handleSubscribed); + session.on("event", this.handleEventData); + session.on("subscription-cancelled", this.handleSubscriptionCancelled); + } + subscribe(streamingMethod, params, targetServers, success, error, existingSub) { + if (targetServers.length === 0) { + error({ + method: streamingMethod, + called_with: params.arguments, + message: ERR_MSG_SUB_FAILED + " No available servers matched the target params.", + }); + return; + } + const subLocalKey = this.getNextSubscriptionLocalKey(); + const pendingSub = this.registerSubscription(subLocalKey, streamingMethod, params, success, error, params.methodResponseTimeout || 10000, existingSub); + if (typeof pendingSub !== "object") { + error({ + method: streamingMethod, + called_with: params.arguments, + message: ERR_MSG_SUB_FAILED + " Unable to register the user callbacks.", + }); + return; + } + targetServers.forEach((target) => { + const serverId = target.server.id; + const method = target.methods.find((m) => m.name === streamingMethod.name); + if (!method) { + this.logger.error(`can not find method ${streamingMethod.name} for target ${target.server.id}`); + return; + } + pendingSub.trackedServers.push({ + serverId, + subscriptionId: undefined, + }); + const msg = { + type: "subscribe", + server_id: serverId, + method_id: method.gatewayId, + arguments_kv: params.arguments, + }; + this.session.send(msg, { serverId, subLocalKey }) + .then((m) => this.handleSubscribed(m)) + .catch((err) => this.handleErrorSubscribing(err)); + }); + } + drainSubscriptions() { + const existing = Object.values(this.subscriptionsList); + this.subscriptionsList = {}; + this.subscriptionIdToLocalKeyMap = {}; + return existing; + } + drainSubscriptionsCache() { + return this.timedCache.flush(); + } + getNextSubscriptionLocalKey() { + const current = this.nextSubLocalKey; + this.nextSubLocalKey += 1; + return current; + } + registerSubscription(subLocalKey, method, params, success, error, timeout, existingSub) { + const subsInfo = { + localKey: subLocalKey, + status: STATUS_AWAITING_ACCEPT, + method, + params, + success, + error, + trackedServers: [], + handlers: { + onData: existingSub?.handlers.onData || [], + onClosed: existingSub?.handlers.onClosed || [], + onConnected: existingSub?.handlers.onConnected || [], + }, + queued: { + data: [], + closers: [], + }, + timeoutId: undefined, + close: () => this.closeSubscription(subLocalKey), + subscription: existingSub?.subscription + }; + if (!existingSub) { + if (params.onData) { + subsInfo.handlers.onData.push(params.onData); + } + if (params.onClosed) { + subsInfo.handlers.onClosed.push(params.onClosed); + } + if (params.onConnected) { + subsInfo.handlers.onConnected.push(params.onConnected); + } + } + this.subscriptionsList[subLocalKey] = subsInfo; + subsInfo.timeoutId = setTimeout(() => { + if (this.subscriptionsList[subLocalKey] === undefined) { + return; + } + const pendingSub = this.subscriptionsList[subLocalKey]; + if (pendingSub.status === STATUS_AWAITING_ACCEPT) { + error({ + method, + called_with: params.arguments, + message: ERR_MSG_SUB_FAILED + " Subscription attempt timed out after " + timeout + " ms.", + }); + delete this.subscriptionsList[subLocalKey]; + } + else if (pendingSub.status === STATUS_SUBSCRIBED && pendingSub.trackedServers.length > 0) { + pendingSub.trackedServers = pendingSub.trackedServers.filter((server) => { + return (typeof server.subscriptionId !== "undefined"); + }); + delete pendingSub.timeoutId; + if (pendingSub.trackedServers.length <= 0) { + this.callOnClosedHandlers(pendingSub); + delete this.subscriptionsList[subLocalKey]; + } + } + }, timeout); + return subsInfo; + } + handleErrorSubscribing = (errorResponse) => { + const tag = errorResponse._tag; + const subLocalKey = tag.subLocalKey; + const pendingSub = this.subscriptionsList[subLocalKey]; + if (typeof pendingSub !== "object") { + return; + } + pendingSub.trackedServers = pendingSub.trackedServers.filter((server) => { + return server.serverId !== tag.serverId; + }); + if (pendingSub.trackedServers.length <= 0) { + clearTimeout(pendingSub.timeoutId); + if (pendingSub.status === STATUS_AWAITING_ACCEPT) { + const reason = (typeof errorResponse.reason === "string" && errorResponse.reason !== "") ? + ' Publisher said "' + errorResponse.reason + '".' : + " No reason given."; + const callArgs = typeof pendingSub.params.arguments === "object" ? + JSON.stringify(pendingSub.params.arguments) : + "{}"; + pendingSub.error({ + message: ERR_MSG_SUB_REJECTED + reason + " Called with:" + callArgs, + called_with: pendingSub.params.arguments, + method: pendingSub.method, + }); + } + else if (pendingSub.status === STATUS_SUBSCRIBED) { + this.callOnClosedHandlers(pendingSub); + } + delete this.subscriptionsList[subLocalKey]; + } + }; + handleSubscribed = (msg) => { + const subLocalKey = msg._tag.subLocalKey; + const pendingSub = this.subscriptionsList[subLocalKey]; + if (typeof pendingSub !== "object") { + return; + } + const serverId = msg._tag.serverId; + const acceptingServer = pendingSub.trackedServers + .filter((server) => { + return server.serverId === serverId; + })[0]; + if (typeof acceptingServer !== "object") { + return; + } + acceptingServer.subscriptionId = msg.subscription_id; + this.subscriptionIdToLocalKeyMap[msg.subscription_id] = subLocalKey; + const isFirstResponse = (pendingSub.status === STATUS_AWAITING_ACCEPT); + pendingSub.status = STATUS_SUBSCRIBED; + if (isFirstResponse) { + let reconnect = false; + let sub = pendingSub.subscription; + if (sub) { + sub.setNewSubscription(pendingSub); + pendingSub.success(sub); + reconnect = true; + } + else { + sub = new UserSubscription(this.repository, pendingSub); + pendingSub.subscription = sub; + pendingSub.success(sub); + } + for (const handler of pendingSub.handlers.onConnected) { + try { + handler(sub.serverInstance, reconnect); + } + catch (e) { + } + } + } + }; + handleEventData = (msg) => { + const subLocalKey = this.subscriptionIdToLocalKeyMap[msg.subscription_id]; + if (typeof subLocalKey === "undefined") { + return; + } + const subscription = this.subscriptionsList[subLocalKey]; + if (typeof subscription !== "object") { + return; + } + const trackedServersFound = subscription.trackedServers.filter((s) => { + return s.subscriptionId === msg.subscription_id; + }); + if (trackedServersFound.length !== 1) { + return; + } + const isPrivateData = msg.oob; + const sendingServerId = trackedServersFound[0].serverId; + const server = this.repository.getServerById(sendingServerId); + const receivedStreamData = () => { + return { + data: msg.data, + server: server?.instance ?? {}, + requestArguments: subscription.params.arguments, + message: undefined, + private: isPrivateData, + }; + }; + const onDataHandlers = subscription.handlers.onData; + const queuedData = subscription.queued.data; + if (onDataHandlers.length > 0) { + onDataHandlers.forEach((callback) => { + if (typeof callback === "function") { + callback(receivedStreamData()); + } + }); + } + else { + queuedData.push(receivedStreamData()); + } + }; + handleSubscriptionCancelled = (msg) => { + const subLocalKey = this.subscriptionIdToLocalKeyMap[msg.subscription_id]; + if (typeof subLocalKey === "undefined") { + return; + } + const subscription = this.subscriptionsList[subLocalKey]; + if (typeof subscription !== "object") { + return; + } + const expectedNewLength = subscription.trackedServers.length - 1; + subscription.trackedServers = subscription.trackedServers.filter((server) => { + if (server.subscriptionId === msg.subscription_id) { + subscription.queued.closers.push(server.serverId); + return false; + } + else { + return true; + } + }); + if (subscription.trackedServers.length !== expectedNewLength) { + return; + } + if (subscription.trackedServers.length <= 0) { + this.timedCache.add(subscription); + clearTimeout(subscription.timeoutId); + this.callOnClosedHandlers(subscription); + delete this.subscriptionsList[subLocalKey]; + } + delete this.subscriptionIdToLocalKeyMap[msg.subscription_id]; + }; + callOnClosedHandlers(subscription, reason) { + const closersCount = subscription.queued.closers.length; + const closingServerId = (closersCount > 0) ? subscription.queued.closers[closersCount - 1] : null; + let closingServer; + if (closingServerId !== undefined && typeof closingServerId === "string") { + closingServer = this.repository.getServerById(closingServerId)?.instance ?? {}; + } + subscription.handlers.onClosed.forEach((callback) => { + if (typeof callback !== "function") { + return; + } + callback({ + message: reason || ON_CLOSE_MSG_SERVER_INIT, + requestArguments: subscription.params.arguments || {}, + server: closingServer, + stream: subscription.method, + }); + }); + } + closeSubscription(subLocalKey) { + const subscription = this.subscriptionsList[subLocalKey]; + if (typeof subscription !== "object") { + return; + } + subscription.trackedServers.forEach((server) => { + if (typeof server.subscriptionId === "undefined") { + return; + } + subscription.queued.closers.push(server.serverId); + this.session.sendFireAndForget({ + type: "unsubscribe", + subscription_id: server.subscriptionId, + reason_uri: "", + reason: ON_CLOSE_MSG_CLIENT_INIT, + }); + delete this.subscriptionIdToLocalKeyMap[server.subscriptionId]; + }); + subscription.trackedServers = []; + this.callOnClosedHandlers(subscription, ON_CLOSE_MSG_CLIENT_INIT); + delete this.subscriptionsList[subLocalKey]; + } + } + + class ClientProtocol { + session; + repository; + logger; + streaming; + constructor(session, repository, logger) { + this.session = session; + this.repository = repository; + this.logger = logger; + session.on("peer-added", (msg) => this.handlePeerAdded(msg)); + session.on("peer-removed", (msg) => this.handlePeerRemoved(msg)); + session.on("methods-added", (msg) => this.handleMethodsAddedMessage(msg)); + session.on("methods-removed", (msg) => this.handleMethodsRemovedMessage(msg)); + this.streaming = new ClientStreaming(session, repository, logger); + } + subscribe(stream, options, targetServers, success, error, existingSub) { + this.streaming.subscribe(stream, options, targetServers, success, error, existingSub); + } + invoke(id, method, args, target) { + const serverId = target.id; + const methodId = method.gatewayId; + const msg = { + type: "call", + server_id: serverId, + method_id: methodId, + arguments_kv: args, + }; + return this.session.send(msg, { invocationId: id, serverId }) + .then((m) => this.handleResultMessage(m)) + .catch((err) => this.handleInvocationError(err)); + } + drainSubscriptions() { + return this.streaming.drainSubscriptions(); + } + drainSubscriptionsCache() { + return this.streaming.drainSubscriptionsCache(); + } + handlePeerAdded(msg) { + const newPeerId = msg.new_peer_id; + const remoteId = msg.identity; + const isLocal = msg.meta ? msg.meta.local : true; + const pid = Number(remoteId.process); + const serverInfo = { + machine: remoteId.machine, + pid: isNaN(pid) ? remoteId.process : pid, + instance: remoteId.instance, + application: remoteId.application, + applicationName: remoteId.applicationName, + environment: remoteId.environment, + region: remoteId.region, + user: remoteId.user, + windowId: remoteId.windowId, + peerId: newPeerId, + api: remoteId.api, + isLocal + }; + this.repository.addServer(serverInfo, newPeerId); + } + handlePeerRemoved(msg) { + const removedPeerId = msg.removed_id; + const reason = msg.reason; + this.repository.removeServerById(removedPeerId, reason); + } + handleMethodsAddedMessage(msg) { + const serverId = msg.server_id; + const methods = msg.methods; + methods.forEach((method) => { + this.repository.addServerMethod(serverId, method); + }); + } + handleMethodsRemovedMessage(msg) { + const serverId = msg.server_id; + const methodIdList = msg.methods; + const server = this.repository.getServerById(serverId); + if (server) { + const serverMethodKeys = Object.keys(server.methods); + serverMethodKeys.forEach((methodKey) => { + const method = server.methods[methodKey]; + if (methodIdList.indexOf(method.gatewayId) > -1) { + this.repository.removeServerMethod(serverId, methodKey); + } + }); + } + } + handleResultMessage(msg) { + const invocationId = msg._tag.invocationId; + const result = msg.result; + const serverId = msg._tag.serverId; + const server = this.repository.getServerById(serverId); + return { + invocationId, + result, + instance: server?.instance, + status: InvokeStatus.Success, + message: "" + }; + } + handleInvocationError(msg) { + this.logger.debug(`handle invocation error ${JSON.stringify(msg)}`); + if ("_tag" in msg) { + const invocationId = msg._tag.invocationId; + const serverId = msg._tag.serverId; + const server = this.repository.getServerById(serverId); + const message = msg.reason; + const context = msg.context; + return { + invocationId, + result: context, + instance: server?.instance, + status: InvokeStatus.Error, + message + }; + } + else { + return { + invocationId: "", + message: msg.message, + status: InvokeStatus.Error, + error: msg + }; + } + } + } + + function gW3ProtocolFactory (instance, connection, clientRepository, serverRepository, libConfig, interop) { + const logger = libConfig.logger.subLogger("gw3-protocol"); + let resolveReadyPromise; + const readyPromise = new Promise((resolve) => { + resolveReadyPromise = resolve; + }); + const session = connection.domain("agm", ["subscribed"]); + const server = new ServerProtocol(session, clientRepository, serverRepository, logger.subLogger("server")); + const client = new ClientProtocol(session, clientRepository, logger.subLogger("client")); + async function handleReconnect() { + logger.info("reconnected - will replay registered methods and subscriptions"); + client.drainSubscriptionsCache().forEach((sub) => { + const methodInfo = sub.method; + const params = Object.assign({}, sub.params); + logger.info(`trying to soft-re-subscribe to method ${methodInfo.name}, with params: ${JSON.stringify(params)}`); + interop.client.subscribe(methodInfo, params, undefined, undefined, sub).then(() => logger.info(`soft-subscribing to method ${methodInfo.name} DONE`)).catch((error) => logger.warn(`subscribing to method ${methodInfo.name} failed: ${JSON.stringify(error)}}`)); + }); + const reconnectionPromises = []; + const existingSubscriptions = client.drainSubscriptions(); + for (const sub of existingSubscriptions) { + const methodInfo = sub.method; + const params = Object.assign({}, sub.params); + logger.info(`trying to re-subscribe to method ${methodInfo.name}, with params: ${JSON.stringify(params)}`); + reconnectionPromises.push(interop.client.subscribe(methodInfo, params, undefined, undefined, sub).then(() => logger.info(`subscribing to method ${methodInfo.name} DONE`))); + } + const registeredMethods = serverRepository.getList(); + serverRepository.reset(); + for (const method of registeredMethods) { + const def = method.definition; + if (method.stream) { + reconnectionPromises.push(interop.server.createStream(def, method.streamCallbacks, undefined, undefined, method.stream) + .then(() => logger.info(`subscribing to method ${def.name} DONE`)) + .catch(() => logger.warn(`subscribing to method ${def.name} FAILED`))); + } + else if (method?.theFunction?.userCallback) { + reconnectionPromises.push(interop.register(def, method.theFunction.userCallback) + .then(() => logger.info(`registering method ${def.name} DONE`)) + .catch(() => logger.warn(`registering method ${def.name} FAILED`))); + } + else if (method?.theFunction?.userCallbackAsync) { + reconnectionPromises.push(interop.registerAsync(def, method.theFunction.userCallbackAsync) + .then(() => logger.info(`registering method ${def.name} DONE`)) + .catch(() => logger.warn(`registering method ${def.name} FAILED`))); + } + } + await Promise.all(reconnectionPromises); + logger.info("Interop is re-announced"); + } + function handleInitialJoin() { + if (resolveReadyPromise) { + resolveReadyPromise({ + client, + server, + }); + resolveReadyPromise = undefined; + } + } + session.onJoined((reconnect) => { + clientRepository.addServer(instance, connection.peerId); + if (reconnect) { + handleReconnect().then(() => connection.setLibReAnnounced({ name: "interop" })).catch((error) => logger.warn(`Error while re-announcing interop: ${JSON.stringify(error)}`)); + } + else { + handleInitialJoin(); + } + }); + session.onLeft(() => { + clientRepository.reset(); + }); + session.join(); + return readyPromise; + } + + class Interop { + instance; + readyPromise; + client; + server; + unwrappedInstance; + protocol; + clientRepository; + serverRepository; + constructor(configuration) { + if (typeof configuration === "undefined") { + throw new Error("configuration is required"); + } + if (typeof configuration.connection === "undefined") { + throw new Error("configuration.connections is required"); + } + const connection = configuration.connection; + if (typeof configuration.methodResponseTimeout !== "number") { + configuration.methodResponseTimeout = 30 * 1000; + } + if (typeof configuration.waitTimeoutMs !== "number") { + configuration.waitTimeoutMs = 30 * 1000; + } + this.unwrappedInstance = new InstanceWrapper(this, undefined, connection); + this.instance = this.unwrappedInstance.unwrap(); + this.clientRepository = new ClientRepository(configuration.logger.subLogger("cRep"), this); + this.serverRepository = new ServerRepository(); + let protocolPromise; + if (connection.protocolVersion === 3) { + protocolPromise = gW3ProtocolFactory(this.instance, connection, this.clientRepository, this.serverRepository, configuration, this); + } + else { + throw new Error(`protocol ${connection.protocolVersion} not supported`); + } + this.readyPromise = protocolPromise.then((protocol) => { + this.protocol = protocol; + this.client = new Client(this.protocol, this.clientRepository, this.instance, configuration); + this.server = new Server(this.protocol, this.serverRepository); + return this; + }); + } + ready() { + return this.readyPromise; + } + serverRemoved(callback) { + return this.client.serverRemoved(callback); + } + serverAdded(callback) { + return this.client.serverAdded(callback); + } + serverMethodRemoved(callback) { + return this.client.serverMethodRemoved(callback); + } + serverMethodAdded(callback) { + return this.client.serverMethodAdded(callback); + } + methodRemoved(callback) { + return this.client.methodRemoved(callback); + } + methodAdded(callback) { + return this.client.methodAdded(callback); + } + methodsForInstance(instance) { + return this.client.methodsForInstance(instance); + } + methods(methodFilter) { + return this.client.methods(methodFilter); + } + servers(methodFilter) { + return this.client.servers(methodFilter); + } + subscribe(method, options, successCallback, errorCallback) { + return this.client.subscribe(method, options, successCallback, errorCallback); + } + createStream(streamDef, callbacks, successCallback, errorCallback) { + return this.server.createStream(streamDef, callbacks, successCallback, errorCallback); + } + unregister(methodFilter) { + return this.server.unregister(methodFilter); + } + registerAsync(methodDefinition, callback) { + return this.server.registerAsync(methodDefinition, callback); + } + register(methodDefinition, callback) { + return this.server.register(methodDefinition, callback); + } + invoke(methodFilter, argumentObj, target, additionalOptions, success, error) { + return this.client.invoke(methodFilter, argumentObj, target, additionalOptions, success, error); + } + waitForMethod(name) { + const pw = new PromiseWrapper$1(); + const unsubscribe = this.client.methodAdded((m) => { + if (m.name === name) { + unsubscribe(); + pw.resolve(m); + } + }); + return pw.promise; + } + } + + const successMessages = ["subscribed", "success"]; + class MessageBus { + connection; + logger; + peerId; + session; + subscriptions; + readyPromise; + constructor(connection, logger) { + this.connection = connection; + this.logger = logger; + this.peerId = connection.peerId; + this.subscriptions = []; + this.session = connection.domain("bus", successMessages); + this.readyPromise = this.session.join(); + this.readyPromise.then(() => { + this.watchOnEvent(); + }); + } + ready() { + return this.readyPromise; + } + publish = (topic, data, options) => { + const { routingKey, target } = options || {}; + const args = this.removeEmptyValues({ + type: "publish", + topic, + data, + peer_id: this.peerId, + routing_key: routingKey, + target_identity: target + }); + this.session.send(args); + }; + subscribe = (topic, callback, options) => { + return new Promise((resolve, reject) => { + const { routingKey, target } = options || {}; + const args = this.removeEmptyValues({ + type: "subscribe", + topic, + peer_id: this.peerId, + routing_key: routingKey, + source: target + }); + this.session.send(args) + .then((response) => { + const { subscription_id } = response; + this.subscriptions.push({ subscription_id, topic, callback, source: target }); + resolve({ + unsubscribe: () => { + this.session.send({ type: "unsubscribe", subscription_id, peer_id: this.peerId }); + this.subscriptions = this.subscriptions.filter((s) => s.subscription_id !== subscription_id); + return Promise.resolve(); + } + }); + }) + .catch((error) => reject(error)); + }); + }; + watchOnEvent = () => { + this.session.on("event", (args) => { + const { data, subscription_id } = args; + const source = args["publisher-identity"]; + const subscription = this.subscriptions.find((s) => s.subscription_id === subscription_id); + if (subscription) { + if (!subscription.source) { + subscription.callback(data, subscription.topic, source); + } + else { + if (this.keysMatch(subscription.source, source)) { + subscription.callback(data, subscription.topic, source); + } + } + } + }); + }; + removeEmptyValues(obj) { + const cleaned = {}; + Object.keys(obj).forEach((key) => { + if (obj[key] !== undefined && obj[key] !== null) { + cleaned[key] = obj[key]; + } + }); + return cleaned; + } + keysMatch(obj1, obj2) { + const keysObj1 = Object.keys(obj1); + let allMatch = true; + keysObj1.forEach((key) => { + if (obj1[key] !== obj2[key]) { + allMatch = false; + } + }); + return allMatch; + } + } + + const IOConnectCoreFactory = (userConfig, ext) => { + const iodesktop = typeof window === "object" ? (window.iodesktop ?? window.glue42gd) : undefined; + const preloadPromise = typeof window === "object" ? (window.gdPreloadPromise ?? Promise.resolve()) : Promise.resolve(); + const glueInitTimer = timer("glue"); + userConfig = userConfig || {}; + ext = ext || {}; + const internalConfig = prepareConfig$1(userConfig, ext, iodesktop); + let _connection; + let _interop; + let _logger; + let _metrics; + let _contexts; + let _bus; + let _allowTrace; + const libs = {}; + function registerLib(name, inner, t) { + _allowTrace = _logger.canPublish("trace"); + if (_allowTrace) { + _logger.trace(`registering ${name} module`); + } + const done = (e) => { + inner.initTime = t.stop(); + inner.initEndTime = t.endTime; + inner.marks = t.marks; + if (!_allowTrace) { + return; + } + const traceMessage = e ? + `${name} failed - ${e.message}` : + `${name} is ready - ${t.endTime - t.startTime}`; + _logger.trace(traceMessage); + }; + inner.initStartTime = t.startTime; + if (inner.ready) { + inner.ready() + .then(() => { + done(); + }) + .catch((e) => { + const error = typeof e === "string" ? new Error(e) : e; + done(error); + }); + } + else { + done(); + } + if (!Array.isArray(name)) { + name = [name]; + } + name.forEach((n) => { + libs[n] = inner; + IOConnectCoreFactory[n] = inner; + }); + } + function setupConnection() { + const initTimer = timer("connection"); + _connection = new Connection(internalConfig.connection, _logger.subLogger("connection")); + let authPromise = Promise.resolve(internalConfig.auth); + if (internalConfig.connection && !internalConfig.auth) { + if (iodesktop) { + authPromise = iodesktop.getGWToken() + .then((token) => { + return { + gatewayToken: token + }; + }); + } + else if (typeof window !== "undefined" && window?.glue42electron) { + if (typeof window.glue42electron.gwToken === "string") { + authPromise = Promise.resolve({ + gatewayToken: window.glue42electron.gwToken + }); + } + } + else { + authPromise = Promise.reject("You need to provide auth information"); + } + } + return authPromise + .then((authConfig) => { + initTimer.mark("auth-promise-resolved"); + let authRequest; + if (Object.prototype.toString.call(authConfig) === "[object Object]") { + authRequest = authConfig; + } + else { + throw new Error("Invalid auth object - " + JSON.stringify(authConfig)); + } + return _connection.login(authRequest); + }) + .then(() => { + registerLib("connection", _connection, initTimer); + return internalConfig; + }) + .catch((e) => { + if (_connection) { + _connection.logout(); + } + throw e; + }); + } + function setupLogger() { + const initTimer = timer("logger"); + _logger = new Logger$1(`${internalConfig.connection.identity?.application}`, undefined, internalConfig.customLogger); + _logger.consoleLevel(internalConfig.logger.console); + _logger.publishLevel(internalConfig.logger.publish); + if (_logger.canPublish("debug")) { + _logger.debug("initializing glue..."); + } + registerLib("logger", _logger, initTimer); + return Promise.resolve(undefined); + } + function setupMetrics() { + const initTimer = timer("metrics"); + const config = internalConfig.metrics; + const metricsPublishingEnabledFunc = iodesktop?.getMetricsPublishingEnabled; + const identity = internalConfig.connection.identity; + const canUpdateMetric = metricsPublishingEnabledFunc ? metricsPublishingEnabledFunc : () => true; + const disableAutoAppSystem = (typeof config !== "boolean" && config.disableAutoAppSystem) ?? false; + _metrics = metrics({ + connection: config ? _connection : undefined, + logger: _logger.subLogger("metrics"), + canUpdateMetric, + system: "Glue42", + service: identity?.service ?? iodesktop?.applicationName ?? internalConfig.application, + instance: identity?.instance ?? identity?.windowId ?? nanoid$1(10), + disableAutoAppSystem, + pagePerformanceMetrics: typeof config !== "boolean" ? config?.pagePerformanceMetrics : undefined + }); + registerLib("metrics", _metrics, initTimer); + return Promise.resolve(); + } + function setupInterop() { + const initTimer = timer("interop"); + const agmConfig = { + connection: _connection, + logger: _logger.subLogger("interop"), + }; + _interop = new Interop(agmConfig); + Logger$1.Interop = _interop; + registerLib(["interop", "agm"], _interop, initTimer); + return Promise.resolve(); + } + function setupContexts() { + const hasActivities = (internalConfig.activities && _connection.protocolVersion === 3); + const needsContexts = internalConfig.contexts || hasActivities; + if (needsContexts) { + const initTimer = timer("contexts"); + _contexts = new ContextsModule({ + connection: _connection, + logger: _logger.subLogger("contexts"), + trackAllContexts: typeof internalConfig.contexts === "object" ? internalConfig.contexts.trackAllContexts : false, + reAnnounceKnownContexts: typeof internalConfig.contexts === "object" ? internalConfig.contexts.reAnnounceKnownContexts : false + }); + registerLib("contexts", _contexts, initTimer); + return _contexts; + } + else { + const replayer = _connection.replayer; + if (replayer) { + replayer.drain(ContextMessageReplaySpec.name); + } + } + } + async function setupBus() { + if (!internalConfig.bus) { + return Promise.resolve(); + } + const initTimer = timer("bus"); + _bus = new MessageBus(_connection, _logger.subLogger("bus")); + registerLib("bus", _bus, initTimer); + return Promise.resolve(); + } + function setupExternalLibs(externalLibs) { + try { + externalLibs.forEach((lib) => { + setupExternalLib(lib.name, lib.create); + }); + return Promise.resolve(); + } + catch (e) { + return Promise.reject(e); + } + } + function setupExternalLib(name, createCallback) { + const initTimer = timer(name); + const lib = createCallback(libs); + if (lib) { + registerLib(name, lib, initTimer); + } + } + function waitForLibs() { + const libsReadyPromises = Object.keys(libs).map((key) => { + const lib = libs[key]; + return lib.ready ? + lib.ready() : Promise.resolve(); + }); + return Promise.all(libsReadyPromises); + } + function constructGlueObject() { + const feedbackFunc = (feedbackInfo) => { + if (!_interop) { + return; + } + _interop.invoke("T42.ACS.Feedback", feedbackInfo, "best"); + }; + const info = { + coreVersion: version$1, + version: internalConfig.version + }; + glueInitTimer.stop(); + const glue = { + feedback: feedbackFunc, + info, + logger: _logger, + interop: _interop, + agm: _interop, + connection: _connection, + metrics: _metrics, + contexts: _contexts, + bus: _bus, + version: internalConfig.version, + userConfig, + done: () => { + _logger?.info("done called by user..."); + return _connection.logout(); + } + }; + glue.performance = { + get glueVer() { + return internalConfig.version; + }, + get glueConfig() { + return JSON.stringify(userConfig); + }, + get browser() { + return window.performance.timing.toJSON(); + }, + get memory() { + return window.performance.memory; + }, + get initTimes() { + const all = getAllTimers(); + return Object.keys(all).map((key) => { + const t = all[key]; + return { + name: key, + duration: t.endTime - t.startTime, + marks: t.marks, + startTime: t.startTime, + endTime: t.endTime + }; + }); + } + }; + Object.keys(libs).forEach((key) => { + const lib = libs[key]; + glue[key] = lib; + }); + glue.config = {}; + Object.keys(internalConfig).forEach((k) => { + glue.config[k] = internalConfig[k]; + }); + if (ext && ext.extOptions) { + Object.keys(ext.extOptions).forEach((k) => { + glue.config[k] = ext?.extOptions[k]; + }); + } + if (ext?.enrichGlue) { + ext.enrichGlue(glue); + } + if (iodesktop && iodesktop.updatePerfData) { + iodesktop.updatePerfData(glue.performance); + } + if (glue.agm) { + const deprecatedDecorator = (fn, wrong, proper) => { + return function () { + glue.logger.warn(`glue.js - 'glue.agm.${wrong}' method is deprecated, use 'glue.interop.${proper}' instead.`); + return fn.apply(glue.agm, arguments); + }; + }; + const agmAny = glue.agm; + agmAny.method_added = deprecatedDecorator(glue.agm.methodAdded, "method_added", "methodAdded"); + agmAny.method_removed = deprecatedDecorator(glue.agm.methodRemoved, "method_removed", "methodRemoved"); + agmAny.server_added = deprecatedDecorator(glue.agm.serverAdded, "server_added", "serverAdded"); + agmAny.server_method_aded = deprecatedDecorator(glue.agm.serverMethodAdded, "server_method_aded", "serverMethodAdded"); + agmAny.server_method_removed = deprecatedDecorator(glue.agm.serverMethodRemoved, "server_method_removed", "serverMethodRemoved"); + } + return glue; + } + async function registerInstanceIfNeeded() { + const RegisterInstanceMethodName = "T42.ACS.RegisterInstance"; + if (Utils$1.isNode() && typeof process.env._GD_STARTING_CONTEXT_ === "undefined" && typeof userConfig?.application !== "undefined") { + const isMethodAvailable = _interop.methods({ name: RegisterInstanceMethodName }).length > 0; + if (isMethodAvailable) { + try { + await _interop.invoke(RegisterInstanceMethodName, { appName: userConfig?.application, pid: process.pid }); + } + catch (error) { + const typedError = error; + _logger.error(`Cannot register as an instance: ${JSON.stringify(typedError.message)}`); + } + } + } + } + return preloadPromise + .then(setupLogger) + .then(setupConnection) + .then(() => Promise.all([setupMetrics(), setupInterop(), setupContexts(), setupBus()])) + .then(() => _interop.readyPromise) + .then(() => registerInstanceIfNeeded()) + .then(() => { + return setupExternalLibs(internalConfig.libs || []); + }) + .then(waitForLibs) + .then(constructGlueObject) + .catch((err) => { + return Promise.reject({ + err, + libs + }); + }); + }; + if (typeof window !== "undefined") { + window.IOConnectCore = IOConnectCoreFactory; + } + IOConnectCoreFactory.version = version$1; + IOConnectCoreFactory.default = IOConnectCoreFactory; + + class ActivityEntity { + constructor(id) { + this._id = id; + } + get id() { + return this._id; + } + _update(other) { + if (other._id !== this._id) { + throw Error("Can not update from entity with different id."); + } + this._updateCore(other); + } + _updateCore(other) { + return; + } + _beforeDelete(other) { + return; + } + } + + function isNumber(arg) { + return typeof arg === "number"; + } + function isString(arg) { + return typeof arg === "string"; + } + function isObject(arg) { + return typeof arg === "object" && !Array.isArray(arg) && arg !== null; + } + function isArray(arg) { + if (Array.isArray) { + return Array.isArray(arg); + } + return toString.call(arg) === "[object Array]"; + } + function isUndefined(arg) { + return typeof arg === "undefined"; + } + function isUndefinedOrNull(arg) { + return arg === null || typeof arg === "undefined"; + } + function isNullOrWhiteSpace(str) { + return (typeof str !== "string" || !str || str.length === 0 || /^\s*$/.test(str)); + } + function isBoolean(obj) { + return obj === true || obj === false || toString.call(obj) === "[object Boolean]"; + } + function isFunction(arg) { + return !!(arg && arg.constructor && arg.call && arg.apply); + } + function some(array, predicate) { + for (let index = 0; index < array.length; index++) { + if (predicate(array[index], index)) { + return true; + } + } + return false; + } + function ifNotUndefined(what, doWithIt) { + if (typeof what !== "undefined") { + doWithIt(what); + } + } + function promisify$1(promise, successCallback, errorCallback) { + if (typeof successCallback !== "function" && typeof errorCallback !== "function") { + return promise; + } + if (typeof successCallback !== "function") { + successCallback = () => { return; }; + } + else if (typeof errorCallback !== "function") { + errorCallback = () => { return; }; + } + promise.then(successCallback, errorCallback); + } + + class ActivityType extends ActivityEntity { + constructor(name, ownerWindow, helperWindows, description) { + super(name); + this._name = name; + this._description = description; + this._ownerWindow = ownerWindow; + this._helperWindows = helperWindows || []; + } + get name() { + return this._name; + } + get description() { + return this._description; + } + get helperWindows() { + return this._helperWindows.map((hw) => this.covertToWindowDef(hw)); + } + get ownerWindow() { + return this.covertToWindowDef(this._ownerWindow); + } + initiate(context, callback, configuration) { + return this._manager.initiate(this._name, context, callback, configuration); + } + _updateCore(other) { + super._updateCore(other); + ifNotUndefined(other._description, (x) => this._description = x); + ifNotUndefined(other._ownerWindow, (x) => this._ownerWindow = x); + ifNotUndefined(other._helperWindows, (x) => this._helperWindows = x); + } + covertToWindowDef(windowType) { + var _a, _b; + return { + type: (_a = windowType === null || windowType === void 0 ? void 0 : windowType.id) === null || _a === void 0 ? void 0 : _a.type, + name: (_b = windowType === null || windowType === void 0 ? void 0 : windowType.id) === null || _b === void 0 ? void 0 : _b.name + }; + } + } + + class WindowType extends ActivityEntity { + constructor(name, appByWindowTypeGetter) { + super(name); + this._name = name; + this._appByWindowTypeGetter = appByWindowTypeGetter; + } + get name() { + return this._name; + } + get config() { + return this._appByWindowTypeGetter(this._name); + } + get windows() { + return this._manager.getWindows({ type: this._name }); + } + create(activity, configuration) { + const definition = Object.assign({ type: this.name, name: this.name, isIndependent: false }, configuration); + return this._manager.createWindow(activity, definition); + } + } + + class EntityEvent { + constructor(entitiy, context) { + this.entity = entitiy; + this.context = context; + } + } + class EntityEventContext { + constructor(eventType) { + this.type = eventType; + } + } + class ActivityStatusChangeEventContext extends EntityEventContext { + constructor(newStatus, oldStatus) { + super(EntityEventType.StatusChange); + this.newStatus = newStatus; + this.oldStatus = oldStatus; + } + } + class ActivityContextChangedEventContext extends EntityEventContext { + constructor(context, updated, removed) { + super(EntityEventType.ActivityContextChange); + this.context = typeof context === "string" ? JSON.parse(context) : context; + this.updated = updated; + this.removed = removed; + } + } + class EntityEventType { + } + EntityEventType.Added = "added"; + EntityEventType.Removed = "removed"; + EntityEventType.Updated = "updated"; + EntityEventType.Closed = "closed"; + EntityEventType.StatusChange = "statusChange"; + EntityEventType.ActivityContextChange = "activityContextUpdate"; + EntityEventType.ActivityWindowEvent = "activityWindowEvent"; + EntityEventType.ActivityWindowJoinedActivity = "joined"; + EntityEventType.ActivityWindowLeftActivity = "left"; + class ActivityState { + } + ActivityState.Created = "created"; + ActivityState.Started = "started"; + ActivityState.Destroyed = "destroyed"; + + class ActivityAGM { + constructor(activity) { + this._activity = activity; + } + register(definition, handler) { + this._ensureHasAgm(); + ActivityAGM.AGM.register(definition, handler); + } + servers() { + this._ensureHasAgm(); + if (isUndefinedOrNull(this._activity)) { + return []; + } + return this._activity.windows.map((w) => { + return w.instance; + }); + } + methods() { + this._ensureHasAgm(); + if (isUndefinedOrNull(this._activity)) { + return []; + } + const windows = this._activity.windows; + const methodNames = []; + const methods = []; + windows.forEach((window) => { + const windowMethods = this.methodsForWindow(window); + windowMethods.forEach((currentWindowMethod) => { + if (methodNames.indexOf(currentWindowMethod.name) === -1) { + methodNames.push(currentWindowMethod.name); + methods.push(currentWindowMethod); + } + }); + }); + return methods; + } + methodsForWindow(window) { + this._ensureHasAgm(); + if (!window.instance) { + return []; + } + return ActivityAGM.AGM.methodsForInstance(window.instance); + } + invoke(methodName, arg, target, options, success, error) { + this._ensureHasAgm(); + const activityServers = this.servers(); + if (isUndefinedOrNull(target)) { + target = "activity.all"; + } + if (isString(target)) { + if (target === "activity.all") ; + else if (target === "activity.best") { + const potentialTargets = activityServers.filter((server) => { + const methods = ActivityAGM.AGM.methodsForInstance(server); + return methods.filter((m) => { + return m.name === methodName; + }).length > 0; + }); + if (potentialTargets.length > 0) { + [potentialTargets[0]]; + } + } + else if (target === "all" || target === "best") { + return promisify$1(ActivityAGM.AGM.invoke(methodName, arg, target, options), success, error); + } + else { + throw new Error("Invalid invoke target " + target); + } + } + else if (isArray(target)) { + if (target.length >= 0) { + const firstElem = target[0]; + if (this._isInstance(firstElem)) { + target.map((instance) => instance); + } + else if (this._isActivityWindow(firstElem)) { + target.map((win) => win.instance); + } + else { + throw new Error("Unknown target object"); + } + } + } + else { + if (this._isInstance(target)) ; + else if (this._isActivityWindow(target)) { + [target.instance]; + } + else { + throw new Error("Unknown target object"); + } + } + throw new Error("Not implemented"); + } + unregister(definition) { + this._ensureHasAgm(); + return ActivityAGM.AGM.unregister(definition); + } + createStream(methodDefinition, subscriptionAddedHandler, subscriptionRemovedHandler) { + this._ensureHasAgm(); + ActivityAGM.AGM.createStream(methodDefinition, { + subscriptionAddedHandler, + subscriptionRemovedHandler, + subscriptionRequestHandler: undefined + }); + } + subscribe(methodDefinition, parameters, target) { + this._ensureHasAgm(); + return ActivityAGM.AGM.subscribe(methodDefinition, parameters); + } + _ensureHasAgm() { + if (isUndefinedOrNull(ActivityAGM.AGM)) { + throw new Error("Agm should be configured to be used in activity"); + } + } + _isInstance(obj) { + return obj.application !== undefined; + } + _isActivityWindow(obj) { + return obj.instance !== undefined; + } + } + + class AttachedActivityDescriptor { + constructor(manager, ownerActivityId, state) { + this._manager = manager; + this._ownerActivityId = ownerActivityId; + this._state = state; + } + get ownerId() { + return this._state.ownerId; + } + get windowIds() { + return this._state.windowIds; + } + get frameColor() { + return this._state.frameColor; + } + get context() { + return this._state.context; + } + get tag() { + return this._state.tag; + } + detach(descriptor) { + descriptor = descriptor || {}; + const merged = {}; + Object.keys(this._state).forEach((prop) => { + merged[prop] = this._state[prop]; + }); + merged.context = descriptor.context || merged.context; + merged.frameColor = descriptor.frameColor || merged.frameColor; + return this._manager.detachActivities(this._ownerActivityId, merged); + } + } + + const nextTick = (cb) => { + setTimeout(cb, 0); + }; + function nodeify(promise, callback) { + if (!isFunction(callback)) { + return promise; + } + promise.then((resp) => { + nextTick(() => { + callback(null, resp); + }); + }, (err) => { + nextTick(() => { + callback(err, null); + }); + }); + } + + class Activity extends ActivityEntity { + constructor(id, actType, status, context, ownerId) { + super(id); + this._id = id; + this._actType = actType; + this._status = status; + this._context = context; + this._ownerId = ownerId; + this._agm = new ActivityAGM(this); + } + get type() { + if (this._manager) { + return this._manager.getActivityType(this._actType); + } + return undefined; + } + get context() { + return this._context; + } + get status() { + return this._status; + } + get owner() { + if (!this._ownerId) { + return null; + } + return this._manager.getWindows({ id: this._ownerId })[0]; + } + get windows() { + return this._manager.getWindows({ activityId: this._id }); + } + get agm() { + return this._agm; + } + addWindow(window, callback) { + return this._manager.addWindowToActivity(this, window, callback); + } + createWindow(windowType, callback) { + return this._manager.createWindow(this, windowType, callback); + } + createStackedWindows(windowTypes, timeout, callback) { + return this._manager.createStackedWindows(this, windowTypes, timeout, callback); + } + leave(window, callback) { + return this._manager.leaveWindowFromActivity(this, window, callback); + } + getWindowsByType(windowType) { + const filter = { activityId: this._id, type: windowType }; + return this._manager.getWindows(filter); + } + setContext(context, callback) { + return this._manager.setActivityContext(this, context, callback); + } + updateContext(context, callback) { + return this._manager.updateActivityContext(this, context, callback); + } + onStatusChange(handler) { + return this._manager.subscribeActivityEvents((a, ns, os) => { + if (a.id === this.id) { + handler(a, ns, os); + } + }); + } + onWindowEvent(handler) { + return this._manager.subscribeWindowEvents((a, w, e) => { + if (a.id === this.id) { + handler(a, w, e); + } + }); + } + onContextChanged(handler) { + this._manager.subscribeActivityContextChanged((act, context, updated, removed) => { + if (act.id === this.id) { + handler(context, updated, removed, act); + } + }); + try { + handler(this.context, this.context, [], this); + } + catch (e) { + return; + } + } + stop() { + this._manager.stopActivity(this); + } + clone(options) { + return this._manager.clone(this, options); + } + attach(activity, tag) { + let activityId; + if (typeof activity === "string") { + activityId = activity; + } + else { + activityId = activity.id; + } + return this._manager.attachActivities(activityId, this.id, tag); + } + onActivityAttached(callback) { + this._manager.subscribeActivitiesAttached((newActId, oldActId, descriptor) => { + if (newActId !== this._id) { + return; + } + callback(descriptor); + }); + } + onDetached(callback) { + this._manager.subscribeActivitiesDetached((newAct, originalActivity, state) => { + if (originalActivity.id !== this._id) { + return; + } + callback(newAct, state); + }); + } + _updateCore(other) { + super._updateCore(other); + ifNotUndefined(other._actType, (x) => this._actType = x); + ifNotUndefined(other._context, (x) => this._context = x); + ifNotUndefined(other._ownerId, (x) => this._ownerId = x); + if (other._status && (!this._status || (this._status.state !== other._status.state))) { + this._status = other._status; + } + } + _updateDescriptors(allStates) { + this._attached = allStates.map((s) => { + return new AttachedActivityDescriptor(this._manager, this._id, s); + }); + } + get attached() { + return this._attached; + } + setFrameColor(color, callback) { + const promise = new Promise((resolve, reject) => { + let callbacksToWait = this.windows.length; + if (callbacksToWait === 0) { + resolve(this); + } + this.windows.forEach((w) => { + w.underlyingWindow.setFrameColor(color, () => { + callbacksToWait--; + if (callbacksToWait <= 0) { + resolve(this); + } + }); + }); + setTimeout(() => { + if (callbacksToWait > 0) { + reject(this.id + " - timed out waiting for setFrameColor with" + color); + } + }, 5000); + }); + return nodeify(promise, callback); + } + getFrameColor() { + if (!this.windows || this.windows.length === 0) { + return ""; + } + return this.windows[0].underlyingWindow.frameColor; + } + } + + class LogLevel { + } + LogLevel.Trace = "trace"; + LogLevel.Debug = "debug"; + LogLevel.Info = "info"; + LogLevel.Warn = "warn"; + LogLevel.Error = "error"; + class Logger { + static GetNamed(name) { + return new Logger(name); + } + static Get(owner) { + return new Logger(Logger.GetTypeName(owner)); + } + constructor(name) { + this._name = name; + if (!isUndefinedOrNull(Logger.GlueLogger)) { + this._glueLogger = Logger.GlueLogger.subLogger(name); + } + } + trace(message) { + if (!isUndefinedOrNull(this._glueLogger)) { + this._glueLogger.trace(message); + } + else { + if (Logger.Level === LogLevel.Trace) { + console.info(this._getMessage(message, LogLevel.Trace)); + } + } + } + debug(message) { + if (!isUndefinedOrNull(this._glueLogger)) { + this._glueLogger.debug(message); + } + else { + if (Logger.Level === LogLevel.Debug || + Logger.Level === LogLevel.Trace) { + console.info(this._getMessage(message, LogLevel.Debug)); + } + } + } + info(message) { + if (!isUndefinedOrNull(this._glueLogger)) { + this._glueLogger.info(message); + } + else { + if (Logger.Level === LogLevel.Debug || + Logger.Level === LogLevel.Trace || + Logger.Level === LogLevel.Info) { + console.info(this._getMessage(message, LogLevel.Info)); + } + } + } + warn(message) { + if (!isUndefinedOrNull(this._glueLogger)) { + this._glueLogger.warn(message); + } + else { + if (Logger.Level === LogLevel.Debug || + Logger.Level === LogLevel.Trace || + Logger.Level === LogLevel.Info || + Logger.Level === LogLevel.Warn) { + console.info(this._getMessage(message, LogLevel.Info)); + } + } + } + error(message) { + if (!isUndefinedOrNull(this._glueLogger)) { + this._glueLogger.error(message); + } + else { + console.error(this._getMessage(message, LogLevel.Error)); + console.trace(); + } + } + _getMessage(message, level) { + return "[" + level + "] " + this._name + " - " + message; + } + static GetTypeName(object) { + const funcNameRegex = /function (.{1,})\(/; + const results = (funcNameRegex).exec(object.constructor.toString()); + return (results && results.length > 1) ? results[1] : ""; + } + } + Logger.Level = LogLevel.Info; + + class ActivityWindow extends ActivityEntity { + constructor(id, name, type, activityId, instance, isIndependent, windowGetter, hcWindowId) { + super(id); + this._logger = Logger.Get("window"); + this._type = type; + this._activityId = activityId; + this._name = name; + this._instance = instance; + this._isIndependent = isIndependent; + this._windowGetter = windowGetter; + this._hcWindowId = hcWindowId; + } + getBounds() { + return this._manager.getWindowBounds(this.id); + } + get name() { + return this._name; + } + get isIndependent() { + return this._isIndependent; + } + get type() { + if (this._manager) { + return this._manager.getWindowType(this._type); + } + return undefined; + } + get activity() { + if (isUndefined(this._activityId)) { + return undefined; + } + return this._manager.getActivityById(this._activityId); + } + get isOwner() { + const act = this.activity; + if (isUndefined(act)) { + return false; + } + return act.owner.id === this.id; + } + setVisible(isVisible, callback) { + return this._manager.setWindowVisibility(this.id, isVisible); + } + activate(focus) { + return this._manager.activateWindow(this.id, focus); + } + setBounds(bounds, callback) { + return this._manager.setWindowBounds(this.id, bounds, callback); + } + close() { + return this._manager.closeWindow(this.id); + } + get instance() { + return this._instance; + } + get underlyingWindow() { + const window = this._windowGetter(); + if (!window) { + return { + id: this._hcWindowId + }; + } + return window; + } + onActivityJoined(callback) { + this._subscribeForActivityWindowEvent(EntityEventType.ActivityWindowJoinedActivity, callback); + } + onActivityRemoved(callback) { + this._subscribeForActivityWindowEvent(EntityEventType.ActivityWindowLeftActivity, callback); + } + _updateCore(other) { + ifNotUndefined(other._activityId, (x) => this._activityId = x); + ifNotUndefined(other._isIndependent, (x) => this._isIndependent = x); + ifNotUndefined(other._hcWindowId, (x) => this._hcWindowId = x); + ifNotUndefined(other._type, (x) => this._type = x); + ifNotUndefined(other._name, (x) => this._name = x); + if (!isUndefinedOrNull(other._instance)) { + this._instance = other._instance; + } + } + _subscribeForActivityWindowEvent(eventName, callback) { + this._manager.subscribeWindowEvents((activity, window, event) => { + if (window.id !== this.id) { + return; + } + if (event === eventName) { + callback(activity); + } + }); + } + _beforeDelete(other) { + this._hcWindowId = other._hcWindowId; + } + } + + class ActivityStatus { + constructor(state, message, time) { + this.state = state; + this.message = message; + this.time = time; + } + getState() { + return this.state; + } + getMessage() { + return this.message; + } + getTime() { + return this.time; + } + } + + const gwMmessageError = "error"; + const gwMessageAddActivityTypes = "add-types"; + const gwMmessageActivityTypesAdded = "types-added"; + const gwMessageRemoveActivityTypes = "remove-types"; + const gwMessageActivityTypesRemoved = "types-removed"; + const gwMessageActivityCreated = "created"; + const gwMessageActivityDestroyed = "destroyed"; + const gwMessageActivityInitiated = "initiated"; + const gwMmessageJoinActivity = "join-activity"; + const gwMessageJoinedActivity = "joined"; + const gwMessageActivityJoined = "activity-joined"; + const gwMessageLeaveActivity = "leave-activity"; + const gwMessageActivityLeft = "left"; + const gwNmessageMergeActivities = "merge"; + const gwMessageSplitActivities = "split"; + const gwMessageOwnerChanged = "owner-changed"; + const gwMessageAddPeerFactories = "add-peer-factories"; + const gwMessagePeerFactoriesAdded = "peer-factories-added"; + const gwMessageRemovePeerFactories = "remove-peer-factories"; + const gwMessagePeerFactoriesRemoved = "peer-factories-removed"; + const gwMessageCreateActivity = "create"; + const gwMessageCreatePeer = "create-peer"; + const gwMessagePeerRequested = "peer-requested"; + const gwMessageReady = "ready"; + const gwMessagePeerCreated = "peer-created"; + const gwMessageDestroyActivity = "destroy"; + const gwMessageDisposePeer = "dispose-peer"; + const gwMessageDestroyPeer = "destroy-peer"; + class GW3Bridge { + static activityTypeGwMessageEntityToActivityType(entity, description) { + const nameToWindowType = (windowName) => new WindowType(windowName, undefined); + return new ActivityType(entity.name, entity.owner_type && nameToWindowType(entity.owner_type), entity.helper_types && entity.helper_types.map(nameToWindowType), description); + } + static peerFactoryGwMessageEntityToWindowType(entity) { + return new WindowType(entity.peer_type, (_) => undefined); + } + static activityGwMessageToActivity(msg, status) { + const ownerId = msg.owner !== undefined ? msg.owner.peer_id : msg.owner_id; + return new Activity(msg.activity_id, msg.activity_type, status, msg.context_snapshot, ownerId); + } + static activityToActivityStatusChangeEvent(act) { + return new EntityEvent(act, new ActivityStatusChangeEventContext(act.status, undefined)); + } + constructor(config) { + this._activityChangeCallbacks = []; + this._activityTypeStatusChangeCallbacks = []; + this._activityWindowChangeCallbacks = []; + this._windowTypeStatusChangeCallbacks = []; + this._peerIdAndFactoryIdToPeerType = {}; + this._peerFactoriesRegisteredByUs = {}; + this._gw3Subscriptions = []; + this._contextSubscriptions = {}; + this._activityTypesInitiatedFromMe = {}; + this._config = config; + this._connection = config.connection; + this._logger = config.logger; + this._contexts = config.contexts; + this._windows = config.windows; + this._sessionJoinedPromise = new Promise((resolve) => { + this._sessionJoinedPromiseResolve = resolve; + }); + this._activityJoinedPromise = new Promise((resolve) => { + this._activityJoinedPromiseResolve = resolve; + }); + if (!this._config.activityId) { + this._activityJoinedPromiseResolve({}); + } + this._gw3Session = this._connection.domain("activity", ["joined", "initiated", "peer-created", "token"]); + if (typeof window !== "undefined") { + const glue42gd = (window).glue42gd; + if (glue42gd && glue42gd.activityInfo) { + if (typeof glue42gd.addRefreshHandler === "function") { + glue42gd.addRefreshHandler((success, error) => { + this._gw3Session + .send({ + type: "reload" + }) + .then((msg) => { + if (!msg.token) { + error("Expected gateway token for refreshing."); + return; + } + try { + glue42gd.setGWToken(msg.token); + } + catch (e) { + error(e.message || e); + return; + } + success(); + }, error); + }); + } + if (glue42gd && typeof glue42gd.addWillNavigateHandler === "function") { + glue42gd.addWillNavigateHandler((success, error) => { + this._gw3Session + .send({ + type: "reload" + }) + .then((msg) => { + if (!msg.token) { + error("Expected gateway token for refreshing."); + return; + } + try { + glue42gd.setGWToken(msg.token); + } + catch (e) { + error(e.message || e); + return; + } + success(); + }, error); + }); + } + } + } + } + get bridgeType() { + return "GW3"; + } + init() { + this.forwardActivityTypeMessagesToStatusEventHandlers(); + this.subscribe(gwMessageActivityCreated, this.handleActivityCreatedMessage); + this.subscribe(gwMessageActivityDestroyed, this.handleActivityDestroyedMessage); + this.forwardActivityMessagesToStatusEventHandlers(); + this.forwardActivityCreatedAndJoinedActivityToActivityWindowEventHandlers(); + this.forwardPeerFactoryMessagesToStatusEventHandlers(); + this.forwardPeerFactoryMessagesToPeerFactoryRequests(); + this.subscribe(gwMessagePeerFactoriesAdded, this.handlePeerFactoriesAdded); + this.subscribe(gwMessagePeerFactoriesRemoved, this.handlePeerFactoriesRemoved); + this.forwardActivityWindowMessagesToEventHandlers(); + this.subscribe(gwMessageDisposePeer, () => { + if (this._config.disposeRequestHandling === "dispose") { + this.dispose(); + return; + } + if (this._config.disposeRequestHandling === "exit") { + if (this._windows && typeof this._windows.my() !== "undefined") { + this._windows.my().close(); + return; + } + if (typeof window !== "undefined" && typeof (window).close === "function") { + window.close(); + return; + } + if (typeof process !== "undefined" && typeof (process).exit === "function") { + process.exit(); + return; + } + } + }); + this._gw3Session.onJoined(() => { + if (this._config.mode === "trackMyOnly" || + this._config.mode === "trackMyTypeAndInitiatedFromMe") { + this._sessionJoinedPromiseResolve(this); + } + else { + this._gw3Session + .send({ + type: "subscribe", + activity_types: (this._config.mode === "trackAll" ? [] : + this._config.mode === "trackTypes" ? this._config.typesToTrack : []) + }) + .then(() => { + this._sessionJoinedPromiseResolve(this); + }); + } + }); + this._gw3Session.join(); + } + dispose() { + this._gw3Subscriptions.forEach((sub) => sub && this._connection.off(sub)); + this._gw3Subscriptions.length = 0; + } + ready() { + return Promise.all([this._sessionJoinedPromise, this._activityJoinedPromise]); + } + initReady() { + return this._sessionJoinedPromise; + } + onActivityTypeStatusChange(callback) { + this._activityTypeStatusChangeCallbacks.push(callback); + } + registerActivityType(activityTypeName, ownerWindow, helperWindows, config, description) { + const entity = {}; + entity.name = activityTypeName; + const toActivityPeerConfig = (windowDefinition) => ({ type: windowDefinition.type, name: windowDefinition.name, configuration: windowDefinition }); + entity.owner_type = toActivityPeerConfig(ownerWindow); + entity.helper_types = helperWindows.map(toActivityPeerConfig); + return this._gw3Session + .send({ + type: gwMessageAddActivityTypes, + types: [entity] + }) + .then(() => { + const activityType = GW3Bridge.activityTypeGwMessageEntityToActivityType(entity, description); + this.invokeCallbacks(this._activityTypeStatusChangeCallbacks, new EntityEvent(activityType, new EntityEventContext(EntityEventType.Added)), gwMessageAddActivityTypes); + return activityType; + }); + } + unregisterActivityType(activityTypeName) { + return this._gw3Session + .send({ + type: gwMessageRemoveActivityTypes, + types: [activityTypeName] + }) + .then(() => { + const activityType = new ActivityType(activityTypeName, undefined, undefined, undefined); + this.invokeCallbacks(this._activityTypeStatusChangeCallbacks, new EntityEvent(activityType, new EntityEventContext(EntityEventType.Removed)), gwMessageAddActivityTypes); + }); + } + onWindowTypeStatusChange(callback) { + this._windowTypeStatusChangeCallbacks.push(callback); + } + registerWindowFactory(windowType, factory, parameters) { + if (this._peerFactoriesRegisteredByUs[windowType]) { + return Promise.reject(new Error(`Factory for windowType ${windowType} already registered.`)); + } + this._peerFactoriesRegisteredByUs[windowType] = factory; + const entity = { + id: windowType, + peer_type: windowType, + configuration: parameters + }; + return this._gw3Session.send({ + type: gwMessageAddPeerFactories, + factories: [entity] + }) + .then(() => { + this.invokeCallbacks(this._windowTypeStatusChangeCallbacks, new EntityEvent(GW3Bridge.peerFactoryGwMessageEntityToWindowType(entity), new EntityEventContext(EntityEventType.Added)), gwMessageAddPeerFactories); + }) + .catch(() => { + delete this._peerFactoriesRegisteredByUs[windowType]; + }); + } + unregisterWindowFactory(windowType) { + const factory = this._peerFactoriesRegisteredByUs[windowType]; + if (!factory) { + return Promise.reject(new Error(`Factory for windowType ${windowType} not registered.`)); + } + delete this._peerFactoriesRegisteredByUs[windowType]; + return this._gw3Session.send({ + type: gwMessageRemovePeerFactories, + factory_ids: [windowType] + }).then(() => { + this.invokeCallbacks(this._windowTypeStatusChangeCallbacks, new EntityEvent(new WindowType(windowType, undefined), new EntityEventContext(EntityEventType.Removed)), gwMessageAddPeerFactories); + }); + } + onActivityStatusChange(callback) { + this._activityChangeCallbacks.push(callback); + } + initiateActivity(activityType, context, configuration) { + const initiateMsg = { + type: gwMessageCreateActivity, + activity_type: activityType, + initial_context: context, + }; + if (this.isOverrideTypeDefinition(configuration)) { + initiateMsg.types_override = { + owner_type: { type: configuration.owner.type, name: configuration.owner.name, configuration: configuration.owner }, + helper_types: configuration.helpers && configuration.helpers.map((wd) => ({ type: wd.type, name: wd.name, configuration: wd })) + }; + } + else { + initiateMsg.configuration = configuration && configuration.map((wd) => ({ type: wd.type, name: wd.name, configuration: wd })); + } + return this.sendCreateAndMapResultingMessagesToPromise(initiateMsg, gwMessageActivityInitiated, (msg, requestId) => msg.request_id === requestId, gwMessageActivityCreated, (msg, requestId, initMsg) => msg.activity_id === initMsg.activity_id, gwMessageActivityDestroyed, (msg, requestId, initMsg) => msg.activity_id === initMsg.activity_id, (msg) => msg.activity_id, null).then((id) => { + if (this._config.mode === "trackMyTypeAndInitiatedFromMe") { + if (!this._activityTypesInitiatedFromMe[activityType]) { + this._activityTypesInitiatedFromMe[activityType] = true; + return this._gw3Session + .send({ + type: "subscribe", + activity_types: [activityType] + }) + .then(() => { + return id; + }); + } + } + return id; + }); + } + stopActivity(activity) { + return this._gw3Session.send({ + type: gwMessageDestroyActivity, + activity_id: activity.id, + reason_uri: "com.tick42.glue.activity.constants.destroyReason.general", + reason: "Destroying activity" + }).then((_) => true); + } + updateActivityContext(activity, context, fullReplace, removedKeys) { + if (fullReplace) { + return this._contexts.set(activity.id, context); + } + else { + removedKeys = removedKeys || []; + for (const x of removedKeys) { + context[x] = null; + } + return this._contexts.update(activity.id, context); + } + } + announceWindow(windowType, activityWindowId) { + throw new Error("Invalid operation 'announceWindow' for GW3 protocol"); + } + registerWindow(type, name, independent) { + let shouldSendReady = typeof this._connection.gatewayToken !== "undefined"; + const peerId = this._connection.peerId; + if (typeof window !== "undefined") { + const glue42gd = window.glue42gd; + if (glue42gd) { + shouldSendReady = typeof glue42gd.activityInfo !== "undefined"; + } + } + if (shouldSendReady) { + this._gw3Session.send({ + type: gwMessageReady, + }); + } + this.invokeCallbacks(this._activityWindowChangeCallbacks, new EntityEvent(new ActivityWindow(peerId, name, type, undefined, this.getAgmInstance(peerId), independent, this.generateWindowGetter(peerId), undefined), new EntityEventContext(EntityEventType.Added)), "register window"); + return Promise.resolve(peerId); + } + onActivityWindowChange(callback) { + this._activityWindowChangeCallbacks.push(callback); + } + createWindow(activityId, windowDefinition) { + if (!windowDefinition.layout) { + if (windowDefinition.left || windowDefinition.width || windowDefinition.height || windowDefinition.top) { + windowDefinition.layout = { + mode: "pixels", + cellSize: 1, + }; + } + } + const joinPeer = (id) => { + if (!activityId) { + return; + } + return this.joinActivity(activityId, id, windowDefinition.name) + .then(() => { + return id; + }); + }; + return this.sendCreateAndMapResultingMessagesToPromise({ + type: gwMessageCreatePeer, + peer_type: windowDefinition.type, + peer_name: windowDefinition.name || windowDefinition.type, + configuration: windowDefinition, + activity_id: activityId, + }, undefined, undefined, gwMessagePeerCreated, (msg, requestId) => msg.request_id === requestId, undefined, undefined, (msg) => msg.created_id, joinPeer) + .then(joinPeer); + } + async closeWindow(id) { + await this._gw3Session.send({ + type: gwMessageDestroyPeer, + destroy_peer_id: id + }); + } + getAnnouncementInfo() { + let activityId = this._config.activityId || (this._config.announcementInfo && this._config.announcementInfo.activityId); + let activityWindowType = (this._config.announcementInfo && this._config.announcementInfo.activityWindowType); + let activityWindowIndependent = (this._config.announcementInfo && this._config.announcementInfo.activityWindowIndependent); + let activityWindowName = (this._config.announcementInfo && this._config.announcementInfo.activityWindowName); + if (typeof window !== "undefined" && + typeof window.location !== "undefined" && + window.location.search && + typeof URLSearchParams === "function") { + const searchParams = new URLSearchParams(location.search.slice(1)); + activityWindowType = activityWindowType || searchParams.get("t42PeerType"); + activityWindowType = activityWindowType || searchParams.get("t42ActivityWindowType"); + if (typeof activityWindowIndependent === "undefined") { + activityWindowIndependent = searchParams.get("t42ActivityWindowIndependent"); + } + activityWindowName = activityWindowName || searchParams.get("t42ActivityWindowName"); + activityId = activityId || searchParams.get("t42ActivityId"); + } + activityWindowType = activityWindowType || "unknown"; + activityWindowIndependent = activityWindowIndependent || false; + activityWindowName = activityWindowName || this._connection.peerId; + return { + activityWindowId: undefined, + activityId, + activityWindowType, + activityWindowIndependent, + activityWindowName, + }; + } + joinActivity(activityId, windowId, name) { + const maybeName = (name && { name }) || {}; + return this._gw3Session.send({ + type: gwMmessageJoinActivity, + target_id: windowId, + activity_id: activityId, + ...maybeName + }).then(() => { + this.invokeCallbacks(this._activityWindowChangeCallbacks, new EntityEvent(new ActivityWindow(windowId, undefined, undefined, activityId, this.getAgmInstance(windowId), undefined, this.generateWindowGetter(windowId), undefined), new EntityEventContext(EntityEventType.ActivityWindowJoinedActivity)), "activity joined - ActivityWindow"); + this.invokeCallbacks(this._activityChangeCallbacks, new EntityEvent(new Activity(activityId, undefined, new ActivityStatus("created", undefined, undefined), undefined, undefined), new EntityEventContext(EntityEventType.Updated)), "activity joined - Activity"); + }); + } + leaveActivity(activityId, windowId) { + return this._gw3Session.send({ + type: gwMessageLeaveActivity, + target_id: windowId, + activity_id: activityId + }).then(() => { + this.invokeCallbacks(this._activityWindowChangeCallbacks, new EntityEvent(new ActivityWindow(windowId, undefined, undefined, null, this.getAgmInstance(windowId), undefined, this.generateWindowGetter(windowId), undefined), new EntityEventContext(EntityEventType.ActivityWindowLeftActivity)), "activity left - ActivityWindow"); + this.invokeCallbacks(this._activityChangeCallbacks, new EntityEvent(new Activity(activityId, undefined, new ActivityStatus("created", undefined, undefined), undefined, undefined), new EntityEventContext(EntityEventType.Updated)), "activity left - Activity"); + }); + } + getActivityTypes() { + return Promise.resolve([]); + } + getWindowTypes() { + return Promise.resolve([]); + } + getActivities() { + return Promise.resolve([]); + } + getActivityWindows() { + return Promise.resolve([]); + } + createStackedWindows(id, windowDefinitions, timeout) { + return undefined; + } + getWindowBounds(id) { + return undefined; + } + setWindowBounds(id, bounds) { + return undefined; + } + activateWindow(id, focus) { + return undefined; + } + setWindowVisibility(id, visible) { + return undefined; + } + cloneActivity(id, cloneOptions) { + return undefined; + } + attachActivities(from, to, tag) { + return this._gw3Session.send({ + type: gwNmessageMergeActivities, + into: to, + merge: from + }); + } + detachActivities(activityId, newActivityInfo) { + return this._gw3Session.send({ + type: gwMessageSplitActivities, + from: activityId, + }).then(() => ""); + } + onActivitiesAttached(callback) { + } + onActivitiesDetached(callback) { + } + onActivityAttachedDescriptorsRefreshed(callback) { + } + getAttachedDescriptors() { + return Promise.resolve([]); + } + getRandomRequestId() { + return this._connection.peerId + ":" + Math.floor(Math.random() * 1e9) + ""; + } + forwardAddedAndRemovedMessagesToEventHandler(addedMessageType, removedMessageType, mapper, handlers) { + const getGetEntityEvent = (isAdded) => (entity) => new EntityEvent(entity, new EntityEventContext(isAdded ? + EntityEventType.Added : + EntityEventType.Removed)); + const sub1 = addedMessageType && this.forwardMessageToEventHandler(addedMessageType, (msg) => mapper(msg, true), getGetEntityEvent(true), handlers); + const sub2 = removedMessageType && this.forwardMessageToEventHandler(removedMessageType, (msg) => mapper(msg, false), getGetEntityEvent(false), handlers); + return [sub1, sub2].filter((x) => x); + } + forwardMessageToEventHandler(messageType, mapper, getEntityEvent, handler) { + return this.subscribe(messageType, (msg) => { + mapper(msg) + .forEach((ent) => handler.forEach((h) => h(getEntityEvent(ent, msg)))); + }); + } + sendCreateAndMapResultingMessagesToPromise(msg, initiatedMessageType, initiatedMessageFilter, createdMessageType, createdMessageFilter, cancelledMessageType, cancelledMessageFilter, createdMessageToPromiseResolution, listenForRecreates) { + const reqId = this.getRandomRequestId(); + let resolveCreatedPromise; + let rejectCreatedPromise; + const createdPromise = new Promise((resolve, reject) => { + resolveCreatedPromise = resolve; + rejectCreatedPromise = reject; + }); + let initiatedMessageAck = null; + let initiatedSubscription; + let createdSubscription; + let cancelledSubscription; + let errorSubscription; + const dropSubscriptions = () => { + this.dropSubscription(initiatedSubscription); + if (!listenForRecreates) { + this.dropSubscription(createdSubscription); + } + this.dropSubscription(cancelledSubscription); + this.dropSubscription(errorSubscription); + }; + initiatedSubscription = initiatedMessageType && + this.subscribe(initiatedMessageType, (msg4) => { + if (!initiatedMessageFilter(msg4, reqId)) { + return; + } + initiatedMessageAck = msg4; + this.dropSubscription(initiatedSubscription); + }); + let recreated = false; + createdSubscription = + this.subscribe(createdMessageType, (msg1) => { + if (!createdMessageFilter(msg1, reqId, initiatedMessageAck)) { + return; + } + if (recreated) { + if (listenForRecreates) { + listenForRecreates(createdMessageToPromiseResolution(msg1)); + } + } + else { + recreated = true; + resolveCreatedPromise(createdMessageToPromiseResolution(msg1)); + } + }); + cancelledSubscription = cancelledMessageType && + this.subscribe(cancelledMessageType, (msg2) => { + if (!cancelledMessageFilter(msg2, reqId, initiatedMessageAck)) { + return; + } + rejectCreatedPromise(msg2); + }); + errorSubscription = cancelledMessageType && + this.subscribe(gwMmessageError, (msg3) => { + if (msg3.request_id !== reqId) { + return; + } + rejectCreatedPromise(msg3); + }); + msg.request_id = reqId; + const toReturn = this._gw3Session + .send(msg) + .then(() => { + return createdPromise; + }); + toReturn.then(dropSubscriptions, dropSubscriptions); + return toReturn; + } + peerFactoryIdAndOwnerIdToWindowType(factoryId, ownerId) { + const peerType = this._peerIdAndFactoryIdToPeerType[ownerId + ":" + factoryId]; + if (!peerType) { + return null; + } + else { + return new WindowType(peerType, undefined); + } + } + subscribe(messageType, handler) { + const sub = this._connection.on(messageType, (msg) => handler.bind(this)(msg)); + this._gw3Subscriptions.push(sub); + return sub; + } + dropSubscription(subscription) { + if (subscription) { + this._connection.off(subscription); + delete this._gw3Subscriptions[this._gw3Subscriptions.indexOf(subscription)]; + } + } + invokeCallbacks(callbacks, event, description) { + callbacks.forEach((cb) => { + try { + cb(event); + } + catch (err) { + this._logger.error(`Error in ${description || event.context.type} callback: ` + JSON.stringify(err)); + } + }); + } + handleActivityCreatedMessage(msg) { + if (!msg.context_id) { + this._logger.error("Activity created with unknown context_id: " + msg.activity_id); + } + else { + if (!this._contextSubscriptions[msg.activity_id]) { + this.subscribeToContext(msg); + } + } + } + async subscribeToContext(msg) { + const activityId = msg.activity_id; + this._contextSubscriptions[activityId] = + await this._contexts.subscribe(activityId, (data, updated, removed) => { + const event = new EntityEvent(new Activity(activityId, undefined, undefined, data, undefined), new ActivityContextChangedEventContext(data, updated, removed)); + this.invokeCallbacks(this._activityChangeCallbacks, event, "context updated"); + }); + } + handleActivityDestroyedMessage(msg) { + const unsubscribeContext = this._contextSubscriptions[msg.activity_id]; + if (typeof unsubscribeContext === "function") { + unsubscribeContext(); + } + delete this._contextSubscriptions[msg.activity_id]; + } + handlePeerFactoriesAdded(msg) { + msg.factories.forEach((entity) => { + this._peerIdAndFactoryIdToPeerType[msg.owner_id + ":" + entity.id] = entity.peer_type; + }); + } + handlePeerFactoriesRemoved(msg) { + msg.factory_ids.forEach((factoryId) => { + delete this._peerIdAndFactoryIdToPeerType[msg.owner_id + ":" + factoryId]; + }); + } + forwardActivityTypeMessagesToStatusEventHandlers() { + this.forwardAddedAndRemovedMessagesToEventHandler(gwMmessageActivityTypesAdded, gwMessageActivityTypesRemoved, (msg, isAdded) => isAdded + ? msg.types.map((t) => GW3Bridge.activityTypeGwMessageEntityToActivityType(t, undefined)) + : msg.types.map((t) => new ActivityType(t.name, undefined, undefined, undefined)), this._activityTypeStatusChangeCallbacks); + } + forwardActivityCreatedAndJoinedActivityToActivityWindowEventHandlers() { + for (const activityCreatedMessage of [gwMessageActivityCreated, gwMessageJoinedActivity, gwMessageOwnerChanged]) { + this.forwardMessageToEventHandler(activityCreatedMessage, (msg) => ([msg.owner || { ...msg, type: msg.peer_type, name: msg.peer_name, peer_id: msg.owner_id }]) + .concat(msg.participants || []) + .map((info) => new ActivityWindow(info.peer_id, info.name, info.type, msg.activity_id, this.getAgmInstance(info.peer_id), undefined, this.generateWindowGetter(info.peer_id), undefined)), (ent, msg) => new EntityEvent(ent, new EntityEventContext(EntityEventType.ActivityWindowJoinedActivity)), this._activityWindowChangeCallbacks); + } + } + forwardActivityMessagesToStatusEventHandlers() { + for (const createdMessage of [gwMessageActivityCreated, gwMessageJoinedActivity]) { + this.forwardMessageToEventHandler(createdMessage, (msg) => [GW3Bridge.activityGwMessageToActivity(msg, new ActivityStatus("started", "", new Date()))], (ent, msg) => GW3Bridge.activityToActivityStatusChangeEvent(ent), this._activityChangeCallbacks); + } + this.forwardMessageToEventHandler(gwMessageActivityDestroyed, (msg) => [GW3Bridge.activityGwMessageToActivity(msg, new ActivityStatus("destroyed", msg.reason, new Date()))], (ent, msg) => GW3Bridge.activityToActivityStatusChangeEvent(ent), this._activityChangeCallbacks); + this.forwardMessageToEventHandler(gwMessageActivityInitiated, (msg) => [GW3Bridge.activityGwMessageToActivity(msg, new ActivityStatus("created", "", new Date()))], (ent, msg) => GW3Bridge.activityToActivityStatusChangeEvent(ent), this._activityChangeCallbacks); + this.forwardMessageToEventHandler(gwMessageOwnerChanged, (msg) => [GW3Bridge.activityGwMessageToActivity(msg, new ActivityStatus("created", "", new Date()))], (ent, msg) => GW3Bridge.activityToActivityStatusChangeEvent(ent), this._activityChangeCallbacks); + } + forwardPeerFactoryMessagesToStatusEventHandlers() { + this.forwardAddedAndRemovedMessagesToEventHandler(gwMessagePeerFactoriesAdded, gwMessagePeerFactoriesRemoved, (msg, isAdded) => isAdded + ? msg.factories.map(GW3Bridge.peerFactoryGwMessageEntityToWindowType) + : msg.factory_ids.map((id) => this.peerFactoryIdAndOwnerIdToWindowType(id, msg.owner_id)).filter((x) => x != null), this._windowTypeStatusChangeCallbacks); + } + forwardPeerFactoryMessagesToPeerFactoryRequests() { + this.subscribe(gwMessagePeerRequested, (msg) => { + const factory = this._peerFactoriesRegisteredByUs[msg.peer_factory]; + if (!factory) { + this._gw3Session.send({ + type: gwMmessageError, + request_id: msg.request_id, + reason: `Unknown peer factory ${msg.peer_factory}` + }); + return; + } + try { + const configuration = msg.configuration || {}; + configuration.gateway_token = configuration.gateway_token || msg.gateway_token; + configuration.peer_factory = configuration.peer_factory || msg.peer_factory; + const promise = factory({ + activityId: msg.activity && msg.activity.id, + activityType: msg.activity && msg.activity.type, + type: msg.configuration && msg.configuration.type, + gwToken: configuration.gateway_token, + configuration + }); + if (promise && promise.then && promise.catch) { + promise.catch((err) => this._gw3Session.send({ + type: gwMmessageError, + request_id: msg.request_id, + reason: err && (err.message || JSON.stringify(err)) + })); + } + } + catch (err) { + this._gw3Session.send({ + type: gwMmessageError, + request_id: msg.request_id, + reason: err && (err.message || JSON.stringify(err)) + }); + } + }); + } + forwardActivityWindowMessagesToEventHandlers() { + for (const joinedMessage of [gwMessageActivityJoined, gwMessageJoinedActivity]) { + this.subscribe(joinedMessage, (msg) => { + const joinedId = (joinedMessage === gwMessageActivityJoined) ? msg.joined_id : msg.peer_id; + const joinedType = (joinedMessage === gwMessageActivityJoined) ? msg.joined_type : msg.peer_type; + const joinedName = (joinedMessage === gwMessageActivityJoined) ? msg.joined_name : msg.peer_name; + const entity = new ActivityWindow(joinedId, joinedName, joinedType, msg.activity_id, this.getAgmInstance(joinedId), undefined, this.generateWindowGetter(joinedId), undefined); + if (!this._contextSubscriptions[msg.activity_id]) { + this.subscribeToContext(msg).then(() => { + if (joinedMessage === gwMessageJoinedActivity) { + this._activityJoinedPromiseResolve({}); + } + }); + } + else if (joinedMessage === gwMessageJoinedActivity) { + this._activityJoinedPromiseResolve({}); + } + this.invokeCallbacks(this._activityWindowChangeCallbacks, new EntityEvent(entity, new EntityEventContext(EntityEventType.ActivityWindowJoinedActivity)), joinedMessage); + }); + } + this.subscribe(gwMessageActivityLeft, (msg) => { + const entity = new ActivityWindow(msg.left_id, undefined, undefined, null, this.getAgmInstance(msg.left_id), undefined, this.generateWindowGetter(msg.left_id), undefined); + this.invokeCallbacks(this._activityWindowChangeCallbacks, new EntityEvent(entity, new EntityEventContext(EntityEventType.ActivityWindowLeftActivity)), gwMessageActivityLeft); + }); + this.forwardAddedAndRemovedMessagesToEventHandler(gwMessagePeerCreated, undefined, (msg) => [ + new ActivityWindow(msg.created_id, undefined, undefined, undefined, undefined, undefined, this.generateWindowGetter(msg.created_id), undefined) + ], this._activityWindowChangeCallbacks); + } + getAgmInstance(id) { + return this._config.agm.servers().find((s) => s.peerId === id || s.windowId === id); + } + generateWindowGetter(peerId) { + return () => { + const server = this.getAgmInstance(peerId); + if (!server) { + return; + } + const windowId = server.windowId; + return this._config.windows.list().filter((w) => w.id === windowId)[0]; + }; + } + isOverrideTypeDefinition(value) { + if (typeof value === "undefined") { + return false; + } + if (value.owner) { + return true; + } + return false; + } + } + + class ActivityMy { + constructor(manager, windows) { + this._myAttached = []; + this._myDetached = []; + this._myAttachedTo = []; + this._myDetachedFrom = []; + this._myActivityFrameColorChanged = []; + this._myActivityJoinedCallbacks = []; + this._myActivityRemovedCallbacks = []; + this._myContextUpdateCallbacks = []; + this._logger = Logger.Get(this); + this._m = manager; + manager.ready() + .then((am) => { + am.subscribeActivityContextChanged(this._subscribeMyContextChanged.bind(this)); + am.subscribeWindowEvents(this._subscribeMyWindowEvent.bind(this)); + am.subscribeActivitiesAttached(this._subscribeActivitiesAttached.bind(this)); + am.subscribeActivitiesDetached(this._subscribeActivitiesDetached.bind(this)); + if (windows) { + windows.onWindowFrameColorChanged(this._subscribeWindowFrameColorChanged.bind(this)); + } + }); + } + get window() { + if (isUndefinedOrNull(this._w)) { + const announcedWindows = this._m.announcedWindows; + if (announcedWindows.length > 0) { + this._w = announcedWindows[0]; + } + } + return this._w; + } + get activity() { + const myWin = this.window; + if (isUndefinedOrNull(myWin)) { + return undefined; + } + return myWin.activity; + } + createWindow(windowType) { + return this._m.createWindow(this.activity, windowType); + } + createStackedWindows(windowTypes, timeout) { + return this._m.createStackedWindows(this.activity, windowTypes, timeout); + } + get context() { + const activity = this.activity; + if (isUndefined(activity)) { + return {}; + } + return activity.context; + } + updateContext(context, callback) { + const activity = this.activity; + if (isUndefined(activity)) { + return new Promise((resolve, reject) => { + reject("Not in activity"); + }); + } + return activity.updateContext(context, callback); + } + setContext(context, callback) { + const activity = this.activity; + if (isUndefined(activity)) { + return new Promise((resolve, reject) => { + reject("Not in activity"); + }); + } + return activity.setContext(context, callback); + } + onActivityJoined(callback) { + this._myActivityJoinedCallbacks.push(callback); + const myWin = this.window; + if (!isUndefinedOrNull(myWin) && !isUndefinedOrNull(myWin.activity)) { + callback(myWin.activity); + } + } + onActivityLeft(callback) { + this._myActivityRemovedCallbacks.push(callback); + } + onContextChanged(callback) { + this._myContextUpdateCallbacks.push(callback); + const myWin = this.window; + if (isUndefinedOrNull(myWin)) { + return; + } + const activity = myWin.activity; + if (isUndefinedOrNull(activity)) { + return; + } + callback(activity.context, activity.context, [], activity); + } + clone(options, callback) { + const act = this.activity; + return this._m.clone(act, options, callback); + } + attach(activity, tag) { + let activityId; + if (typeof activity === "string") { + activityId = activity; + } + else { + activityId = activity.id; + } + return this._m.attachActivities(activityId, this.activity.id, tag); + } + onActivityAttached(callback) { + this._myAttached.push(callback); + } + onActivityDetached(callback) { + this._myDetached.push(callback); + } + onAttachedToActivity(callback) { + this._myAttachedTo.push(callback); + } + onDetachedFromActivity(callback) { + this._myDetachedFrom.push(callback); + } + get attached() { + if (!this.activity) { + return []; + } + return this.activity.attached; + } + setFrameColor(color, callback) { + if (this.activity) { + return this.activity.setFrameColor(color, callback); + } + else { + return Promise.resolve(null); + } + } + getFrameColor() { + if (this.activity) { + return this.activity.getFrameColor(); + } + return ""; + } + onFrameColorChanged(callback) { + this._myActivityFrameColorChanged.push(callback); + } + _subscribeMyContextChanged(activity, context, delta, removed) { + const myWin = this.window; + if (isUndefinedOrNull(myWin)) { + return; + } + const myActivity = myWin.activity; + if (isUndefinedOrNull(myActivity)) { + return; + } + if (activity.id !== myActivity.id) { + return; + } + this._notifyMyContextChanged(activity, context, delta, removed); + } + _subscribeMyWindowEvent(activity, window, event) { + if (isUndefinedOrNull(this.window)) { + return; + } + if (this.window.id !== window.id) { + return; + } + if (event === EntityEventType.ActivityWindowJoinedActivity) { + this._notifyMyWindowEvent(activity, this._myActivityJoinedCallbacks); + this._notifyMyContextChanged(activity, activity.context, null, null); + } + else if (event === EntityEventType.ActivityWindowLeftActivity) { + this._notifyMyWindowEvent(activity, this._myActivityRemovedCallbacks); + } + } + _notifyMyWindowEvent(activity, callbackStore) { + callbackStore.forEach((element) => { + try { + element(activity, event); + } + catch (e) { + this._logger.warn("error in user callback " + e); + } + }); + } + _notifyMyContextChanged(activity, context, delta, removed) { + delta = delta || {}; + removed = removed || []; + this._myContextUpdateCallbacks.forEach((element) => { + try { + element(context, delta, removed, activity); + } + catch (e) { + this._logger.warn("error in user callback " + e); + } + }); + } + _notifyAttached(state) { + this._myAttached.forEach((cb) => { + try { + cb(state); + } + catch (e) { + this._logger.warn("error in user callback " + e); + } + }); + } + _notifyDetached(state) { + this._myDetached.forEach((cb) => { + try { + cb(state); + } + catch (e) { + this._logger.warn("error in user callback " + e); + } + }); + } + _notifyAttachedTo(state) { + this._myAttachedTo.forEach((cb) => { + try { + cb(this.activity, state); + } + catch (e) { + this._logger.warn("error in user callback " + e); + } + }); + } + _notifyDetachedFrom(detached, existing, state) { + this._myDetachedFrom.forEach((cb) => { + try { + cb(detached, existing, state); + } + catch (e) { + this._logger.warn("error in user callback " + e); + } + }); + } + _subscribeActivitiesAttached(newAct, state) { + const myWin = this.window; + if (isUndefinedOrNull(myWin)) { + return; + } + const myActivity = myWin.activity; + if (isUndefinedOrNull(myActivity)) { + return; + } + if (newAct.id !== myActivity.id) { + return; + } + if (state.windowIds.indexOf(myWin.id) >= 0) { + this._notifyAttachedTo(state); + return; + } + this._notifyAttached(state); + } + _subscribeActivitiesDetached(newAct, oldAct, state) { + const myWin = this.window; + if (isUndefinedOrNull(myWin)) { + return; + } + const myActivity = myWin.activity; + if (isUndefinedOrNull(myActivity)) { + return; + } + if (oldAct.id === myActivity.id) { + this._notifyDetached(state); + } + if (newAct.id === myActivity.id) { + this._notifyDetachedFrom(newAct, oldAct, state); + } + } + _subscribeWindowFrameColorChanged(window) { + const act = this.activity; + if (!act) { + return; + } + if (!act.owner) { + return; + } + if (act.owner.underlyingWindow.id === window.id) { + this._myActivityFrameColorChanged.forEach((callback) => { + callback(window.frameColor); + }); + } + } + } + + class ReadyMarker { + constructor(name, signalsToWait) { + this._logger = Logger.Get("ReadyMarker [" + name + "]"); + this._logger.debug("Initializing ready marker for '" + name + "' with " + signalsToWait + " signals to wait"); + if (signalsToWait <= 0) { + throw new Error("Invalid signal number. Should be > 0"); + } + this._signals = signalsToWait; + this._callbacks = []; + this._name = name; + } + setCallback(callback) { + if (this.isSet()) { + callback(undefined); + return; + } + else if (this.isError()) { + callback(this._error); + return; + } + this._callbacks.push(callback); + } + signal(message) { + this._logger.debug("Signaled - " + message + " - signals left " + (this._signals - 1)); + this._signals--; + if (this._signals < 0) { + throw new Error("Error in ready marker '" + this._name + " - signals are " + this._signals); + } + if (this.isSet()) { + this._callbacks.forEach((callback) => { + callback(undefined); + }); + } + } + error(error) { + this._error = error; + this._callbacks.forEach((errorCallback) => { + errorCallback(error); + }); + } + isSet() { + if (this.isError()) { + return false; + } + return this._signals === 0; + } + isError() { + return !isUndefined(this._error); + } + getError() { + return this._error; + } + } + + class EntityObservableCollection { + constructor(processNew) { + this._items = {}; + this._listeners = []; + this._processNew = processNew; + } + addOne(item) { + this.add([item]); + } + add(items) { + items.forEach((element) => { + this.process(new EntityEvent(element, new EntityEventContext(EntityEventType.Added))); + }); + } + process(event) { + const context = event.context; + const type = context.type; + const entity = event.entity; + if (type === EntityEventType.StatusChange && + !context.oldStatus) { + const act = this._items[entity.id]; + if (act) { + context.oldStatus = act.status; + } + } + if (type === EntityEventType.StatusChange && + context.oldStatus && + context.newStatus && + context.oldStatus.state === + context.newStatus.state) { + context.type = EntityEventType.Updated; + } + if (typeof htmlContainer === "undefined") { + if (type === EntityEventType.ActivityWindowJoinedActivity && + this._items[entity.id] && + this._items[entity.id].activity) { + context.type = EntityEventType.Updated; + } + if (type === EntityEventType.ActivityWindowLeftActivity && + this._items[entity.id] && + !this._items[entity.id].activity) { + context.type = EntityEventType.Updated; + } + } + const internalEntity = this._updateInternalCollections(entity, type, context); + this._notifyListeners(internalEntity, context); + return internalEntity; + } + get() { + const result = []; + for (const key in this._items) { + if (this._items.hasOwnProperty(key)) { + const element = this._items[key]; + result.push(element); + } + } + return result; + } + getByName(name) { + for (const key in this._items) { + if (key === name) { + return this._items[key]; + } + } + return undefined; + } + getOrWait(name) { + return new Promise((resolve) => { + const entityAddedHandler = (entity) => { + if (entity.id !== name) { + return; + } + resolve(entity); + this.unsubscribe(entityAddedHandler); + }; + this.subscribe(entityAddedHandler); + const window = this.getByName(name); + if (window) { + this.unsubscribe(entityAddedHandler); + resolve(window); + return; + } + }); + } + subscribe(handler) { + this._listeners.push(handler); + Object.keys(this._items).forEach((key) => { + const element = this._items[key]; + handler(element, new EntityEventContext(EntityEventType.Added.toString())); + }); + return () => { + this.unsubscribe(handler); + }; + } + unsubscribe(handler) { + const index = this._listeners.indexOf(handler); + if (index !== -1) { + this._listeners.splice(index, 1); + } + } + _notifyListeners(entity, context) { + this._listeners.forEach((listener) => { + try { + listener(entity, context); + } + catch (e) { + return; + } + }); + } + _updateInternalCollections(entity, type, context) { + const entityAsAny = entity; + const isActivityDestroy = (type === EntityEventType.StatusChange && + entityAsAny.status && + entityAsAny.status.state === ActivityState.Destroyed) || + (type === EntityEventType.StatusChange && + context && + context.newStatus && + context.newStatus.state === ActivityState.Destroyed); + const isWindowClose = type === EntityEventType.Closed; + const isTypeRemove = type === EntityEventType.Removed && typeof entityAsAny.isIndependent === "undefined"; + if (isTypeRemove || isWindowClose || isActivityDestroy) { + const oldEntity = this._items[entity.id]; + delete this._items[entity.id]; + this._processNew(entity); + if (oldEntity) { + entity._beforeDelete(oldEntity); + } + return entity; + } + else { + const key = entity.id; + if (!this._items.hasOwnProperty(key)) { + this._processNew(entity); + this._items[entity.id] = entity; + } + else { + this._items[entity.id]._update(entity); + } + } + return this._items[entity.id]; + } + } + + class ActivityManager { + get usingHc() { + return this._bridge.bridgeType === "HC"; + } + get announcedWindows() { + return this._announcedWindows; + } + set announcedWindows(v) { + throw new Error("not allowed"); + } + constructor(bridge, autoAnnounce, windows) { + this._logger = Logger.Get("activityManager"); + this._announcedWindows = []; + this._attachedCallbacks = []; + this._detachedCallbacks = []; + this._frameColorChangesCallbacks = []; + this._windowHandlers = []; + this._bridge = bridge; + this._activityTypes = new EntityObservableCollection((e) => this._grabEntity(e)); + this._windowTypes = new EntityObservableCollection((e) => this._grabEntity(e)); + this._activities = new EntityObservableCollection((e) => this._grabEntity(e)); + this._windows = new EntityObservableCollection((e) => this._grabEntity(e)); + this._dataReadyMarker = new ReadyMarker("Activity Manager Data", ["GetActivityTypes", "GetWindowTypes", "GetActivities", "GetWindows"].length); + this._descriptorsMarker = new ReadyMarker("Attached Activities Descriptors", ["GetDescriptors"].length); + if (autoAnnounce) { + this._readyMarker = new ReadyMarker("Activity Manager Announce", ["Announcement"].length); + this._dataReadyMarker.setCallback((dataErr) => { + if (dataErr) { + this._readyMarker.error(dataErr); + } + this._descriptorsMarker.setCallback((err) => { + if (err) { + this._readyMarker.error(err); + } + this._logger.debug("Auto announcing window"); + this.announceWindow() + .then((w) => { + this._announcedWindows.push(w); + this._readyMarker.signal("Successfully announced window with id '" + w.id + "'"); + }) + .catch((errCatch) => { + this._logger.debug("Will not announce window - " + errCatch); + this._readyMarker.signal(); + }); + }); + this.refreshDescriptors(); + }); + } + else { + this._readyMarker = this._dataReadyMarker; + } + this._bridge.onActivitiesAttached((e) => { + this._handleActivitiesAttached(e); + }); + this._bridge.onActivitiesDetached((e) => { + this._handleActivitiesDetached(e); + }); + this._bridge.onActivityAttachedDescriptorsRefreshed((e) => { + this._handleActivityDescriptorsRefreshed(e); + }); + if (windows) { + windows.onWindowFrameColorChanged(this._handleWindowFrameColorChanged.bind(this)); + } + this._bridge.init(); + this._subscribeForData(); + this._bridge + .initReady() + .then((aw) => { + this._getInitialData(); + }) + .catch((error) => { + console.log(error); + }); + } + ready(callback) { + const promise = new Promise((resolve, reject) => { + this._readyMarker.setCallback((err) => { + if (!err) { + resolve(this); + } + else { + reject(this._readyMarker.getError()); + } + }); + }); + return nodeify(Promise.all([this._bridge.ready(), promise]).then(() => this), callback); + } + getActivityTypes() { + return this._activityTypes.get(); + } + getActivityType(name) { + return this._activityTypes.getByName(name); + } + registerActivityType(activityTypeName, ownerWindowType, helperWindowTypes, config, description, callback) { + const promise = new Promise((resolve, reject) => { + if (isUndefinedOrNull(activityTypeName)) { + reject("activityTypeName argument can not be undefined"); + return; + } + if (!isString(activityTypeName)) { + reject("activityTypeName should be string"); + return; + } + const actType = this.getActivityType(activityTypeName); + if (!isUndefinedOrNull(actType)) { + reject("Activity type '" + activityTypeName + "' already exists"); + return; + } + let ownerDefinition; + if (isUndefined(ownerWindowType)) { + reject("Owner window type can not be undefined"); + return; + } + if (isString(ownerWindowType)) { + ownerDefinition = { type: (ownerWindowType), name: "", isIndependent: false, arguments: {} }; + } + else { + ownerDefinition = (ownerWindowType); + } + const helperDefinitions = []; + if (!isUndefined(helperWindowTypes) && isArray(helperWindowTypes)) { + for (const index in helperWindowTypes) { + const item = helperWindowTypes[index]; + if (isString(item)) { + const definition = { + type: (item), + name: "", + isIndependent: false, + arguments: {}, + relativeTo: "", + relativeDirection: "", + windowStyleAttributes: {} + }; + helperDefinitions.push(definition); + } + else { + helperDefinitions.push(item); + } + } + } + this._bridge + .registerActivityType(activityTypeName, ownerDefinition, helperDefinitions, config, description) + .then((activityType) => { + this._grabEntity(activityType); + resolve(activityType); + }) + .catch((error) => { + reject(error); + }); + }); + return nodeify(promise, callback); + } + unregisterActivityType(type, callback) { + const promise = new Promise((resolve, reject) => { + const actType = this.getActivityType(type); + if (isUndefined(actType)) { + reject("Activity type '" + type + "' does not exists"); + return; + } + this._bridge.unregisterActivityType(type).then(() => resolve(actType), reject); + }); + return nodeify(promise, callback); + } + initiate(activityType, context, callback, configuration) { + const promise = new Promise((resolve, reject) => { + const actType = this.getActivityType(activityType); + if (isUndefined(actType)) { + reject("Activity type '" + activityType + "' does not exists"); + return; + } + this._bridge + .initiateActivity(activityType, context, configuration) + .then((actId) => { + this._activities + .getOrWait(actId) + .then((act) => { + resolve(act); + }) + .catch((err) => reject(err)); + }) + .catch((err) => { + reject(err); + }); + }); + return nodeify(promise, callback); + } + subscribeActivityTypeEvents(handler) { + this._activityTypes.subscribe((at, context) => { + handler(at, context.type); + }); + } + getWindowTypes() { + return this._windowTypes.get(); + } + getWindowType(name) { + return this._windowTypes.getByName(name); + } + registerWindowFactory(windowType, factoryMethod, callback) { + const promise = new Promise((resolve, reject) => { + if (isUndefinedOrNull(windowType)) { + reject("no windowType specified"); + return; + } + if (isObject(windowType)) { + windowType = windowType.getName(); + } + else if (!isString(windowType)) { + reject("windowType should be string or object that has getName method"); + return; + } + this._bridge + .registerWindowFactory(windowType, factoryMethod) + .then((v) => { + resolve(v); + }) + .catch((err) => { + reject(err); + }); + }); + return nodeify(promise, callback); + } + unregisterWindowFactory(windowType, callback) { + const promise = new Promise((resolve, reject) => { + if (isUndefinedOrNull(windowType)) { + reject("no windowType specified"); + return; + } + if (!isString(windowType)) { + reject("windowType should be a string"); + return; + } + this._bridge + .unregisterWindowFactory(windowType) + .then((v) => { + resolve(v); + }) + .catch((err) => { + reject(err); + }); + }); + return nodeify(promise, callback); + } + getActivities(activityType) { + let act = this._activities.get(); + act = act.filter((a) => a._ownerId); + if (!activityType) { + return act; + } + let types = activityType; + if (isString(activityType)) { + types = [activityType]; + } + else if (activityType instanceof ActivityType) { + types = [activityType.name]; + } + else if (activityType instanceof Array) ; + else { + throw new Error("Invalid input argument 'activityType' = " + activityType); + } + return act.filter((at) => { + const type = at.type; + return some(types, (t) => { + return type.id === t.id; + }); + }); + } + getActivityById(id) { + return this._activities.getByName(id); + } + announceWindow(activityWindowId, windowType) { + const promise = new Promise((resolve, reject) => { + const announcementInfo = this._bridge.getAnnouncementInfo(); + if (isUndefined(activityWindowId)) { + activityWindowId = announcementInfo.activityWindowId; + } + if (isUndefined(windowType)) { + windowType = announcementInfo.activityWindowType; + } + if (isUndefinedOrNull(windowType)) { + throw new Error("Can not announce - unknown windowType"); + } + const activityId = announcementInfo && announcementInfo.activityId; + if (isUndefinedOrNull(activityWindowId)) { + this._logger.debug("Registering window with type:'" + windowType + "', name:'" + announcementInfo.activityWindowName + "', ind.:'" + announcementInfo.activityWindowIndependent + "'"); + this._bridge.registerWindow(windowType, announcementInfo.activityWindowName, announcementInfo.activityWindowIndependent) + .then(this._windows.getOrWait.bind(this._windows)) + .then((w) => { + if (activityId) { + return this._activities.getOrWait(activityId).then((_) => w); + } + else { + return w; + } + }) + .then((w) => { + resolve(w); + }) + .catch((err) => { + this._logger.error(err); + }); + } + else { + this._logger.debug("Announcing window with id '" + activityWindowId + "' and type '" + windowType + "'"); + const currentWindow = this._windows.getByName(activityWindowId); + if (!isUndefinedOrNull(currentWindow)) { + this._logger.debug("Window with id '" + activityWindowId + "' already announced - reusing the window"); + resolve(currentWindow); + return; + } + const windowEventHandler = (a, w, e) => { + if (activityWindowId === w.id) { + if (e === EntityEventType.ActivityWindowJoinedActivity) { + const activity = w.activity; + if (isUndefined(activity)) { + reject("UNDEFINED ACTIVITY"); + } + this._logger.trace("Got joined event for id '" + activityWindowId + "'"); + resolve(w); + this.unsubscribeWindowEvents(windowEventHandler); + } + } + }; + this.subscribeWindowEvents(windowEventHandler); + this._logger.trace("Waiting for joined event for id '" + activityWindowId + "'"); + this._bridge.announceWindow(windowType, activityWindowId); + } + }); + return promise; + } + subscribeWindowTypeEvents(handler) { + this._windowTypes.subscribe((wt, context) => { + handler(wt, context.type); + }); + } + subscribeActivityEvents(handler) { + return this._activities.subscribe((act, context) => { + if (context.type === EntityEventType.StatusChange) { + const p = context; + handler(act, p.newStatus, p.oldStatus); + } + if (context.type === EntityEventType.Removed || + (context.type === EntityEventType.StatusChange && + context.newStatus.getState() === ActivityState.Destroyed)) { + for (const window of this._windows.get()) { + if (window.activity && window.activity.id === act.id) { + this._windows.process(new EntityEvent(window, new EntityEventContext(EntityEventType.ActivityWindowLeftActivity))); + } + } + } + }); + } + subscribeWindowEvents(handler) { + const wrappingHandler = (window, context) => { + let eventType = context.type; + if (eventType === EntityEventType.Added) { + eventType = "opened"; + } + handler(window.activity, window, eventType); + }; + this._windowHandlers.push([handler, wrappingHandler]); + return this._windows.subscribe(wrappingHandler); + } + unsubscribeWindowEvents(handler) { + const found = this._windowHandlers.find((pair) => pair[0] === handler); + if (found) { + this._windowHandlers.splice(this._windowHandlers.indexOf(found), 1); + this._windows.unsubscribe(found[1]); + } + } + createWindow(activity, windowTypeOrConfiguration, callback) { + const promise = new Promise((resolve, reject) => { + if (isUndefinedOrNull(windowTypeOrConfiguration)) { + reject("windowType is undefined"); + } + let windowDefinition; + if (isString(windowTypeOrConfiguration)) { + windowDefinition = { type: (windowTypeOrConfiguration), name: "", isIndependent: false, arguments: {} }; + } + else if (windowTypeOrConfiguration instanceof WindowType) { + windowDefinition = { + type: windowTypeOrConfiguration.type || windowTypeOrConfiguration.id, + name: windowTypeOrConfiguration.name || windowTypeOrConfiguration.type || windowTypeOrConfiguration.id, + isIndependent: false + }; + } + else { + const invalidKeys = ["url"]; + const filteredWindowTypeOrConfiguration = {}; + Object.keys(windowTypeOrConfiguration).forEach((key) => { + if (invalidKeys.indexOf(key) === -1) { + filteredWindowTypeOrConfiguration[key] = windowTypeOrConfiguration[key]; + } + }); + windowDefinition = filteredWindowTypeOrConfiguration; + } + let relativeToWindow; + if (!isUndefinedOrNull(windowDefinition.relativeTo)) { + relativeToWindow = windowDefinition.relativeTo; + if (typeof relativeToWindow === "string") { + const windows = this.getWindows({ type: relativeToWindow }); + if (!isUndefinedOrNull(windows) && windows.length > 0) { + windowDefinition.relativeTo = windows[0].id; + } + } + else if (!isUndefinedOrNull(relativeToWindow.type)) { + const windows = this.getWindows({ type: relativeToWindow.type }); + if (!isUndefinedOrNull(windows) && windows.length > 0) { + windowDefinition.relativeTo = windows[0].id; + } + } + else if (!isUndefinedOrNull(relativeToWindow.windowId)) { + windowDefinition.relativeTo = relativeToWindow.windowId; + } + } + this._bridge.createWindow(activity && activity.id, windowDefinition) + .then((wid) => { + this._logger.debug("Window created, waiting for window entity with id " + wid); + const handler = (window, context) => { + if (window.id === wid && (!activity || window.activity)) { + this._logger.debug("Got entity window with id " + wid); + resolve(window); + this._windows.unsubscribe(handler); + } + }; + this._windows.subscribe(handler); + }) + .catch((err) => { + reject(err); + }); + }); + return nodeify(promise, callback); + } + createStackedWindows(activity, relativeWindowTypes, timeout, callback) { + const promise = new Promise((resolve, reject) => { + if (isUndefinedOrNull(activity)) { + reject("activity is undefined"); + } + if (isUndefinedOrNull(relativeWindowTypes)) { + reject("relativeWindowTypes is undefined"); + } + if (!Array.isArray(relativeWindowTypes)) { + reject("relativeWindowTypes has to be an array"); + } + if (isUndefinedOrNull(timeout)) { + timeout = 20000; + } + const windowDefinitions = []; + relativeWindowTypes.forEach((element) => { + let windowDefinition; + if (isString(element)) { + windowDefinition = { type: (element), name: "", isIndependent: false, arguments: {} }; + } + else { + windowDefinition = (element); + } + windowDefinition.stackedWindow = true; + windowDefinition.timeout = timeout; + let relativeToWindow; + if (!isUndefinedOrNull(windowDefinition.relativeTo)) { + relativeToWindow = windowDefinition.relativeTo; + if (!isUndefinedOrNull(relativeToWindow.type)) { + windowDefinition.relativeTo = relativeToWindow.type; + } + else if (!isUndefinedOrNull(relativeToWindow.windowId)) { + const windows = this.getWindows({ id: relativeToWindow.windowId }); + if (!isUndefinedOrNull(windows) && windows.length > 0) { + windowDefinition.relativeTo = windows[0].type.name; + } + } + } + windowDefinitions.push(windowDefinition); + }); + const tasks = []; + windowDefinitions.forEach((wd) => tasks.push(this.createWindow(activity, wd))); + Promise.all(tasks).then(resolve).catch(reject); + }); + return nodeify(promise, callback); + } + addWindowToActivity(activity, window, callback) { + const toReturn = this._bridge.joinActivity(activity.id, window.id) + .then(() => window); + nodeify(toReturn, callback); + return toReturn; + } + leaveWindowFromActivity(activity, window, callback) { + const toReturn = this._bridge.leaveActivity(activity.id, window.id) + .then(() => window); + nodeify(toReturn, callback); + return toReturn; + } + setActivityContext(activity, context, callback) { + const promise = new Promise((resolve, reject) => { + if (isUndefinedOrNull(activity)) { + reject("activity can not be null"); + } + this._bridge + .updateActivityContext(activity, context, true) + .then((_) => { + resolve(activity); + }) + .catch((err) => { + reject(err); + }); + }); + return nodeify(promise, callback); + } + updateActivityContext(activity, context, callback) { + const promise = new Promise((resolve, reject) => { + if (isUndefinedOrNull(activity)) { + reject("activity can not be null"); + } + const removedKeys = []; + for (const key in context) { + if (context.hasOwnProperty(key) && context[key] === null) { + removedKeys.push(key); + } + } + for (const removedKey of removedKeys) { + delete context[removedKey]; + } + this._bridge + .updateActivityContext(activity, context, false, removedKeys) + .then((_) => { + resolve(activity); + }) + .catch((err) => { + reject(err); + }); + }); + return nodeify(promise, callback); + } + subscribeActivityContextChanged(handler) { + this._activities.subscribe((act, context) => { + if (context.type === EntityEventType.ActivityContextChange) { + const updateContext = context; + handler(act, updateContext.context, updateContext.updated, updateContext.removed); + } + }); + } + stopActivity(activity, callback) { + const promise = this._bridge.stopActivity(activity); + return nodeify(promise, callback); + } + getWindows(filter) { + if (isUndefined(filter)) { + return this._windows.get(); + } + if (!isUndefined(filter.id)) { + return [this._windows.getByName(filter.id)]; + } + const allWindows = this._windows.get(); + return allWindows.filter((w) => { + if (!isUndefined(filter.type) && w.type.id !== filter.type) { + return false; + } + if (!isUndefined(filter.name) && w.name !== filter.name) { + return false; + } + if (!isUndefined(filter.activityId)) { + if (isUndefinedOrNull(w.activity)) { + return false; + } + if (w.activity.id !== filter.activityId) { + return false; + } + } + return true; + }); + } + getWindowBounds(id) { + return this._bridge.getWindowBounds(id); + } + setWindowBounds(id, bounds, callback) { + const promise = new Promise((resolve, reject) => { + this._bridge.setWindowBounds(id, bounds) + .then(() => resolve()) + .catch((err) => reject(err)); + }); + return nodeify(promise, callback); + } + closeWindow(id) { + return this._bridge.closeWindow(id); + } + activateWindow(id, focus) { + return this._bridge.activateWindow(id, focus); + } + setWindowVisibility(id, visible) { + return this._bridge.setWindowVisibility(id, visible); + } + clone(activity, cloneOptions, callback) { + const promise = new Promise((resolve, reject) => { + if (!activity) { + reject("activity can not be null"); + } + this._bridge.cloneActivity(activity.id, cloneOptions) + .then((activityId) => { + this._activities + .getOrWait(activityId) + .then((act) => { + resolve(act); + }) + .catch((err) => reject(err)); + }) + .catch((err) => reject(err)); + }); + return nodeify(promise, callback); + } + attachActivities(from, to, tag, callback) { + tag = tag || {}; + const promise = new Promise((resolve, reject) => { + const fromActivity = this._activities.getByName(from); + if (!fromActivity) { + reject("can not find activity with id " + from); + return; + } + const toActivity = this._activities.getByName(to); + if (!toActivity) { + reject("can not find activity with id " + to); + return; + } + return this._bridge.attachActivities(from, to, tag) + .then((data) => { + const newActId = data.to; + const state = data.descriptor; + const allStates = data.descriptors; + this._activities.getOrWait(newActId).then((act) => { + act._updateDescriptors(allStates); + const stateWrapped = act.attached.filter((u) => u.ownerId === state.ownerId)[0]; + resolve(stateWrapped); + }); + }) + .catch((err) => { + reject(err); + }); + }); + return nodeify(promise, callback); + } + detachActivities(activityId, descriptor, callback) { + const promise = new Promise((resolve, reject) => { + return this._bridge.detachActivities(activityId, descriptor) + .then(() => { + const oldActId = undefined; + const newActId = undefined; + const descriptors = undefined; + this._activities + .getOrWait(oldActId) + .then((oldAct) => { + oldAct._updateDescriptors(descriptors); + this._activities + .getOrWait(newActId) + .then((newAct) => { + resolve(newAct); + }); + }) + .catch((err) => reject(err)); + }) + .catch((err) => { + reject(err); + }); + }); + return nodeify(promise, callback); + } + subscribeActivitiesAttached(callback) { + this._attachedCallbacks.push(callback); + } + subscribeActivitiesDetached(callback) { + this._detachedCallbacks.push(callback); + } + subscribeActivityFrameColorChanged(callback) { + this._frameColorChangesCallbacks.push(callback); + } + _grabEntity(entity) { + entity._manager = this; + } + _getInitialData() { + this._logger.debug("Request initial data..."); + this._bridge.getActivityTypes() + .then((at) => { + this._activityTypes.add(at); + this._dataReadyMarker.signal("Got act types"); + }) + .catch((error) => { + this._logger.error(error); + this._dataReadyMarker.error("Can not initialize ActivityManager - error getting activity types -" + error); + }); + this._bridge.getWindowTypes() + .then((wt) => { + this._windowTypes.add(wt); + this._dataReadyMarker.signal("Got window types"); + }) + .catch((error) => { + this._logger.error(error); + this._dataReadyMarker.error("Can not initialize ActivityManager - error getting window types " + error); + }); + this._bridge.getActivities() + .then((ac) => { + this._activities.add(ac); + this._dataReadyMarker.signal("Got activities"); + }) + .catch((error) => { + this._logger.error(error); + this._dataReadyMarker.error("Can not initialize ActivityManager - error getting activity instances -" + error); + }); + this._bridge.getActivityWindows() + .then((aw) => { + this._windows.add(aw); + this._dataReadyMarker.signal("Got windows"); + }) + .catch((error) => { + this._logger.error(error); + this._dataReadyMarker.error("Can not initialize ActivityManager - error getting activity windows -" + error); + }); + } + _subscribeForData() { + this._logger.debug("Subscribe for data..."); + this._bridge.onActivityTypeStatusChange((event) => { + this._activityTypes.process(event); + }); + this._bridge.onWindowTypeStatusChange((event) => { + this._windowTypes.process(event); + }); + this._bridge.onActivityWindowChange((event) => { + this._windows.process(event); + }); + this._bridge.onActivityStatusChange((event) => { + this._activities.process(event); + }); + } + _handleActivitiesAttached(data) { + const newActId = data.to; + const descriptor = data.descriptor; + const descriptors = data.descriptors; + this._activities.getOrWait(newActId).then((act) => { + act._updateDescriptors(descriptors); + const descriptorAsObjectFromAPI = act.attached.filter((u) => u.ownerId === descriptor.ownerId)[0]; + this._attachedCallbacks.forEach((callback) => { + try { + callback(act, descriptorAsObjectFromAPI); + } + catch (err) { + return; + } + }); + }); + } + _handleActivitiesDetached(data) { + const oldActId = data.oldActivityId; + const newActId = data.newActivityId; + const descriptors = data.descriptors; + const descriptor = data.descriptor; + this._activities.getOrWait(oldActId).then((oldAct) => { + oldAct._updateDescriptors(descriptors); + this._activities.getOrWait(newActId).then((newAct) => { + this._detachedCallbacks.forEach((callback) => { + try { + callback(newAct, oldAct, descriptor); + } + catch (err) { + return; + } + }); + }); + }); + } + _handleActivityDescriptorsRefreshed(data) { + const id = data.id; + const descriptors = data.descriptors; + const act = this._activities.getByName(id); + if (act) { + act._updateDescriptors(descriptors); + } + } + refreshDescriptors() { + this._bridge.getAttachedDescriptors() + .then((map) => { + if (map) { + Object.keys(map).forEach((key) => { + const actId = key; + const descriptors = map[key]; + const act = this._activities.getByName(actId); + if (act) { + act._updateDescriptors(descriptors); + } + }); + } + this._descriptorsMarker.signal("Successfully got descriptors"); + }) + .catch((err) => { + this._descriptorsMarker.error("failed to get descriptors - " + err); + }); + } + _handleWindowFrameColorChanged(win) { + if (!win.activityId) { + return; + } + const act = this._activities.getByName(win.activityId); + if (!act) { + return; + } + if (!act.owner) { + return; + } + if (act.owner.underlyingWindow.id !== win.id) { + return; + } + this._frameColorChangesCallbacks.forEach((callback) => { + try { + callback(act, win.frameColor); + } + catch (e) { + return; + } + }); + } + } + + class ActivityManagementAPI { + constructor(manager, my) { + this._m = manager; + this._my = my; + this.activityTypes = { + get: this._getActivityTypesWrapper.bind(this), + register: this._m.registerActivityType.bind(this._m), + unregister: this._m.unregisterActivityType.bind(this._m), + subscribe: this._m.subscribeActivityTypeEvents.bind(this._m), + unsubscribe: undefined, + initiate: this._m.initiate.bind(this._m) + }; + this.windowTypes = { + get: this._getWindowTypesWrapper.bind(this), + registerFactory: this._m.registerWindowFactory.bind(this._m), + unregisterFactory: this._m.unregisterWindowFactory.bind(this._m), + subscribe: this._m.subscribeWindowTypeEvents.bind(this._m), + unsubscribe: undefined + }; + this.windows = { + get: this._m.getWindows.bind(this._m), + subscribe: this._m.subscribeWindowEvents.bind(this._m), + announce: this._m.announceWindow.bind(this._m), + unsubscribe: undefined, + create: this._m.createWindow.bind(this._m) + }; + this.instances = { + get: this._m.getActivities.bind(this._m), + subscribe: this._m.subscribeActivityEvents.bind(this._m), + unsubscribe: undefined + }; + } + onAttached(callback) { + this._m.subscribeActivitiesAttached(callback); + } + onDetached(callback) { + this._m.subscribeActivitiesDetached(callback); + } + onActivityFrameColorChanged(callback) { + this._m.subscribeActivityFrameColorChanged(callback); + } + _getActivityTypesWrapper(name) { + if (isUndefined(name)) { + return this._m.getActivityTypes(); + } + return this._m.getActivityType(name); + } + _getWindowTypesWrapper(name) { + if (isUndefined(name)) { + return this._m.getWindowTypes(); + } + return this._m.getWindowType(name); + } + } + + class ActivityAPI { + constructor(manager, my) { + this._mgr = manager; + this._my = my; + this.all = new ActivityManagementAPI(manager, my); + } + ready(callback) { + const promise = new Promise((resolve, reject) => { + this._mgr.ready() + .then(() => { + resolve(this); + }) + .catch((err) => { + reject(err); + }); + }); + return nodeify(promise, callback); + } + get my() { + return this._my; + } + get aware() { + return this._my.window !== undefined; + } + get inActivity() { + return this.aware && this._my.activity !== undefined; + } + get agm() { + if (!this.aware) { + return undefined; + } + if (!this.inActivity) { + return new ActivityAGM(null); + } + return this._my.activity.agm; + } + getAvailableFrameColors() { + return []; + } + } + + class ActivityModule { + static checkIsUsingGW3Implementation(connection) { + return connection.protocolVersion === 3; + } + get api() { + return this._api; + } + set api(value) { + this._api = value; + } + constructor(config) { + if (!config) { + throw new Error("config can not be null"); + } + if (!isUndefined(config.logLevel)) { + Logger.Level = config.logLevel; + } + if (!isUndefinedOrNull(config.logger)) { + Logger.GlueLogger = config.logger; + } + let bridge; + this._isUsingHCImplementation = config.gdMajorVersion === 2; + this._isUsingGW3Implementation = ActivityModule.checkIsUsingGW3Implementation(config.connection); + if (this._isUsingHCImplementation) { + throw new Error("GD2 not supported"); + } + else if (this._isUsingGW3Implementation) { + bridge = new GW3Bridge(config); + } + else { + throw new Error("Unable to instantiate activity bridge implementation"); + } + if (!bridge) { + throw new Error("A bridge to native activity is needed to create activity lib."); + } + ActivityAGM.AGM = config.agm; + const activityManager = new ActivityManager(bridge, !config.disableAutoAnnounce, config.windows); + const my = new ActivityMy(activityManager, config.windows); + this._api = new ActivityAPI(activityManager, my); + this._readyPromise = activityManager.ready().then((_) => this); + } + get isUsingHCImplementation() { + return this._isUsingHCImplementation; + } + get isUsingGW3Implementation() { + return this._isUsingGW3Implementation; + } + ready(callback) { + return nodeify(this._readyPromise, callback); + } + } + + const ShutdownMethodName = "T42.ACS.Shutdown"; + const OnGDShutdownMethodName = "T42.ACS.OnGDShutdown"; + const RestartMethodName = "T42.ACS.Restart"; + const GetConfigurationRegionMethodName = "T42.ACS.GetConfigurationRegion"; + const SetConfigurationRegionMethodName = "T42.ACS.SetConfigurationRegion"; + const GetUserMethodName = "T42.ACS.GetUser"; + const GetBranchesMethodName = "T42.ACS.GetBranches"; + const GetCurrentBranchMethodName = "T42.ACS.GetCurrentBranch"; + const SetCurrentBranchMethodName = "T42.ACS.SetCurrentBranch"; + const GetFunctionalEntitlementMethodName = "T42.ACS.GetFunctionalEntitlement"; + const CanIMethodName = "T42.ACS.CanI"; + const StartApplicationMethodName = "T42.ACS.StartApplication"; + const StopApplicationMethodName = "T42.ACS.StopApplication"; + const ActivateApplicationMethodName = "T42.ACS.ActivateApplication"; + const ACSExecute = "T42.ACS.Execute"; + const OnEventMethodName = "T42.ACS.OnEvent"; + const GetApplicationsMethodName = "T42.ACS.GetApplications"; + + var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; + + function getDefaultExportFromCjs (x) { + return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; + } + + function createRegistry(options) { + if (options && options.errorHandling + && typeof options.errorHandling !== "function" + && options.errorHandling !== "log" + && options.errorHandling !== "silent" + && options.errorHandling !== "throw") { + throw new Error("Invalid options passed to createRegistry. Prop errorHandling should be [\"log\" | \"silent\" | \"throw\" | (err) => void], but " + typeof options.errorHandling + " was passed"); + } + var _userErrorHandler = options && typeof options.errorHandling === "function" && options.errorHandling; + var callbacks = {}; + function add(key, callback, replayArgumentsArr) { + var callbacksForKey = callbacks[key]; + if (!callbacksForKey) { + callbacksForKey = []; + callbacks[key] = callbacksForKey; + } + callbacksForKey.push(callback); + if (replayArgumentsArr) { + setTimeout(function () { + replayArgumentsArr.forEach(function (replayArgument) { + var _a; + if ((_a = callbacks[key]) === null || _a === void 0 ? void 0 : _a.includes(callback)) { + try { + if (Array.isArray(replayArgument)) { + callback.apply(undefined, replayArgument); + } + else { + callback.apply(undefined, [replayArgument]); + } + } + catch (err) { + _handleError(err, key); + } + } + }); + }, 0); + } + return function () { + var allForKey = callbacks[key]; + if (!allForKey) { + return; + } + allForKey = allForKey.reduce(function (acc, element, index) { + if (!(element === callback && acc.length === index)) { + acc.push(element); + } + return acc; + }, []); + if (allForKey.length === 0) { + delete callbacks[key]; + } + else { + callbacks[key] = allForKey; + } + }; + } + function execute(key) { + var argumentsArr = []; + for (var _i = 1; _i < arguments.length; _i++) { + argumentsArr[_i - 1] = arguments[_i]; + } + var callbacksForKey = callbacks[key]; + if (!callbacksForKey || callbacksForKey.length === 0) { + return []; + } + var results = []; + callbacksForKey.forEach(function (callback) { + try { + var result = callback.apply(undefined, argumentsArr); + results.push(result); + } + catch (err) { + results.push(undefined); + _handleError(err, key); + } + }); + return results; + } + function _handleError(exceptionArtifact, key) { + var errParam = exceptionArtifact instanceof Error ? exceptionArtifact : new Error(exceptionArtifact); + if (_userErrorHandler) { + _userErrorHandler(errParam); + return; + } + var msg = "[ERROR] callback-registry: User callback for key \"" + key + "\" failed: " + errParam.stack; + if (options) { + switch (options.errorHandling) { + case "log": + return console.error(msg); + case "silent": + return; + case "throw": + throw new Error(msg); + } + } + console.error(msg); + } + function clear() { + callbacks = {}; + } + function clearKey(key) { + var callbacksForKey = callbacks[key]; + if (!callbacksForKey) { + return; + } + delete callbacks[key]; + } + return { + add: add, + execute: execute, + clear: clear, + clearKey: clearKey + }; + } + createRegistry.default = createRegistry; + var lib = createRegistry; + + + var CallbackRegistryFactory = /*@__PURE__*/getDefaultExportFromCjs(lib); + + function objectValues(source) { + if (!source) { + return []; + } + return Object.keys(source).map((key) => source[key]); + } + function objectClone(obj) { + let result; + try { + result = JSON.parse(JSON.stringify(obj || {})); + } + catch (error) { + result = {}; + } + return result; + } + function validate(callback, configuration) { + if (configuration.throwErrors) { + if (typeof callback !== "function") { + throw new Error("Please provide the callback as a function!"); + } + } + } + + const INTEROP_METHOD_RESPONSE_TIMEOUT_MS = 90000; + const INTEROP_METHOD_WAIT_TIMEOUT_MS = 90000; + + let urlAlphabet = + 'useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict'; + let nanoid = (size = 21) => { + let id = ''; + let i = size | 0; + while (i--) { + id += urlAlphabet[(Math.random() * 64) | 0]; + } + return id + }; + + class Utils { + static getGDMajorVersion() { + if (typeof window === "undefined") { + return -1; + } + if (!window.glueDesktop) { + return -1; + } + if (!window.glueDesktop.version) { + return -1; + } + const parsed = window.glueDesktop.version.split("."); + const major = Number(parsed[0]); + return isNaN(major) ? -1 : major; + } + static typedError(error) { + let err; + if (error instanceof Error) { + err = error; + } + else if (typeof error === "string") { + err = new Error(error); + } + else if ("message" in error && typeof error.message === "string" && error.message.length > 0) { + err = new Error(error.message); + } + else if ("returned" in error + && typeof error.returned === "object" + && "errorMsg" in error.returned + && typeof error.returned.errorMsg === "string" + && error.returned.errorMsg.length > 0) { + err = new Error(error.returned.errorMsg); + } + else { + err = new Error("Unknown error"); + } + return err; + } + static async callbackifyPromise(action, successCallback, errorCallback) { + const success = (result) => { + if (typeof successCallback === "function") { + successCallback(result); + } + return Promise.resolve(result); + }; + const fail = (error) => { + const err = Utils.typedError(error); + if (typeof errorCallback === "function") { + errorCallback(err.message); + return; + } + return Promise.reject(err); + }; + try { + const result = await action(); + return success(result); + } + catch (error) { + return fail(error); + } + } + static getMonitor(bounds, displays) { + const monitorsSortedByOverlap = displays.map((m) => { + const { left, top, workingAreaWidth: width, workingAreaHeight: height } = m; + const overlap = this.calculateTotalOverlap({ left, top, width, height }, bounds); + return { + monitor: m, + totalOverlap: overlap + }; + }).sort((a, b) => b.totalOverlap - a.totalOverlap); + return monitorsSortedByOverlap[0].monitor; + } + static getDisplayCenterOfScreen(a, currentDisplay, primaryDisplay) { + const physicalWidth = a.width / currentDisplay.scaleFactor; + const physicalHeight = a.height / currentDisplay.scaleFactor; + const physicalDisplayLeft = currentDisplay.workArea.left / primaryDisplay.scaleFactor; + const physicalDisplayTop = currentDisplay.workArea.top / primaryDisplay.scaleFactor; + const physicalDisplayWidth = currentDisplay.workArea.width / currentDisplay.scaleFactor; + const physicalDisplayHeight = currentDisplay.workArea.height / currentDisplay.scaleFactor; + const physicalHOffset = Math.max((physicalDisplayWidth - physicalWidth) / 2, 0); + const physicalVOffset = Math.max((physicalDisplayHeight - physicalHeight) / 2, 0); + const centeredPhysicalLeft = Math.floor(physicalDisplayLeft + physicalHOffset); + const centeredPhysicalTop = Math.floor(physicalDisplayTop + physicalVOffset); + const left = centeredPhysicalLeft * primaryDisplay.scaleFactor; + const top = centeredPhysicalTop * primaryDisplay.scaleFactor; + return { + left, + top, + width: a.width, + height: a.height + }; + } + static isNode() { + if (typeof Utils._isNode !== "undefined") { + return Utils._isNode; + } + if (typeof window !== "undefined") { + Utils._isNode = false; + return false; + } + try { + Utils._isNode = Object.prototype.toString.call(global.process) === "[object process]"; + } + catch (e) { + Utils._isNode = false; + } + return Utils._isNode; + } + static generateId() { + return nanoid(10); + } + static isPromise(value) { + return Boolean(value && typeof value.then === 'function'); + } + static isAsyncFunction(value) { + return value && {}.toString.call(value) === '[object AsyncFunction]'; + } + static isNullOrUndefined(value) { + return value === null || value === undefined; + } + static calculateTotalOverlap(r1, r2) { + const r1x = r1.left; + const r1y = r1.top; + const r1xMax = r1x + r1.width; + const r1yMax = r1y + r1.height; + const r2x = r2.left; + const r2y = r2.top; + const r2xMax = r2x + r2.width; + const r2yMax = r2y + r2.height; + const xOverlap = Math.max(0, Math.min(r1xMax, r2xMax) - Math.max(r1x, r2x)); + const yOverlap = Math.max(0, Math.min(r1yMax, r2yMax) - Math.max(r1y, r2y)); + return xOverlap * yOverlap; + } + } + + class ApplicationImpl { + constructor(_appManager, _name, _agm, _logger, _configuration) { + this._appManager = _appManager; + this._name = _name; + this._agm = _agm; + this._logger = _logger; + this._configuration = _configuration; + this._registry = CallbackRegistryFactory(); + _appManager.onInstanceStarted((instance) => { + if (instance.application && instance.application.name !== this._name) { + return; + } + this._registry.execute("instanceStarted", instance); + }); + _appManager.onInstanceStopped((instance) => { + if (instance.application && instance.application.name !== this._name) { + return; + } + this._registry.execute("instanceStopped", instance); + }); + _appManager.onAppRemoved((app) => { + if (app.name !== this._name) { + return; + } + this._registry.execute("appRemoved", app); + }); + _appManager.onAppChanged((app) => { + if (app.name !== this._name) { + return; + } + this._registry.execute("appChanged", app); + }); + _appManager.onAppAvailable((app) => { + if (app.name !== this._name) { + return; + } + this._props.IsReady = true; + this._registry.execute("appAvailable", app); + }); + _appManager.onAppUnavailable((app) => { + if (app.name !== this._name) { + return; + } + this._props.IsReady = false; + this._registry.execute("appUnavailable", app); + }); + } + get name() { return this._name; } + get title() { return this._props.Title; } + get version() { return this._props.Version; } + get autoStart() { return this._props.AutoStart; } + get isShell() { return this._props.IsShell; } + get caption() { return this._props.Caption; } + get hidden() { return this._props.IsHidden; } + get container() { return this._props.ApplicationName; } + get activityType() { return this._props.ActivityType; } + get activityWindowType() { return this._props.ActivityWindowType; } + get windowSettings() { + if (!this._props.Arguments) { + return {}; + } + return objectClone(this._props.Arguments); + } + get allowMultiple() { return this._props.AllowMultiple; } + get available() { return this._props.IsReady || true; } + get icon() { return this._props.Icon; } + get iconURL() { return this._props.IconUrl; } + get sortOrder() { return this._props.SortOrder; } + get userProperties() { + if (!this._props.UserProperties) { + return {}; + } + return objectClone(this._props.UserProperties); + } + get keywords() { + if (!this._props.Keywords) { + return []; + } + return this._props.Keywords; + } + get isActivity() { + return this._props.ActivityType !== undefined && this._props.ActivityType !== ""; + } + get configuration() { + return { + autoStart: this._props.AutoStart, + caption: this._props.Caption, + hidden: this._props.IsHidden, + container: this._props.ApplicationName, + activityType: this._props.ActivityType, + allowMultiple: this._props.AllowMultiple + }; + } + get instances() { + return this._appManager.instances().filter((instance) => instance.application.name === this._name); + } + get type() { + return this._props.Type; + } + get mode() { + if (!this._props) { + return "unknown"; + } + if (this._props.Mode && typeof this._props.Mode === "string") { + return this._props.Mode.toLowerCase(); + } + if (this.isActivity) { + return "unknown"; + } + if (this._props.Arguments && this._props.Arguments.mode && typeof this._props.Arguments.mode === "string") { + return this._props.Arguments.mode.toLowerCase(); + } + let styleAttributes = this._props.WindowStyleAttributes; + if (styleAttributes) { + styleAttributes = styleAttributes.split(" ").join(""); + const searchFor = "mode:\""; + const modeIndex = styleAttributes.indexOf(searchFor); + if (modeIndex !== -1) { + const startModeIndex = modeIndex + searchFor.length; + const stopModeIndex = styleAttributes.indexOf("\"", startModeIndex); + const style = styleAttributes.substr(startModeIndex, stopModeIndex - startModeIndex); + if (style && typeof style === "string") { + return style.toLowerCase(); + } + } + } + return "flat"; + } + async getConfiguration() { + const result = await this._agm.invoke(GetApplicationsMethodName, { v2: { apps: [this._name] } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + const config = result.returned.applications[0]; + return config; + } + updateFromProps(props) { + if (!this._props) { + this._props = { Name: props.Name }; + } + Object.keys(props).forEach((key) => { + this._props[key] = props[key]; + }); + } + start(context, options) { + return new Promise(async (resolve, reject) => { + var _a, _b, _c, _d; + if (isUndefinedOrNull(context)) { + context = {}; + } + else if (((_a = this._configuration()) === null || _a === void 0 ? void 0 : _a.throwErrors) && typeof context !== "object" || Array.isArray(context)) { + return reject(new Error(`Invalid "context" parameter - must be an object.`)); + } + if (isUndefinedOrNull(options)) { + options = {}; + } + else if (((_b = this._configuration()) === null || _b === void 0 ? void 0 : _b.throwErrors) && typeof options !== "object") { + return reject(new Error(`Invalid "options" parameter - must be an object.`)); + } + const name = this._name; + let waitForAGMInstance = (_d = ((_c = options.awaitInterop) !== null && _c !== void 0 ? _c : options.waitForAGMReady)) !== null && _d !== void 0 ? _d : true; + let startTimeout = 60000; + if (typeof options.timeout === "number") { + startTimeout = options.timeout * 1000; + } + if (options.relativeTo !== undefined && typeof options.relativeTo !== "string") { + options.relativeTo = options.relativeTo.id || ""; + } + const waitForApplicationInstance = (id) => { + let unsub; + const timeout = setTimeout(() => { + if (unsub) { + unsub(); + } + const errMsg = `timed out while waiting for instance id ${id} for app ${this.name}`; + this._logger.error(errMsg); + reject(new Error(errMsg)); + }, startTimeout); + const waitFunc = (i) => { + if (i.id !== id) { + return; + } + if (unsub) { + unsub(); + unsub = undefined; + } + clearTimeout(timeout); + resolve(i); + }; + if (waitForAGMInstance) { + const instance = this._appManager.instances().find((i) => i.id === id); + if (instance) { + unsub = instance.onAgmReady(waitFunc); + } + else { + unsub = this._appManager.onInstanceAgmServerReady(waitFunc); + } + } + else { + unsub = this._appManager.onInstanceStarted(waitFunc); + } + }; + try { + this._logger.trace(`starting application ${name} with options: ${JSON.stringify(options)}`); + const result = await this._agm.invoke(StartApplicationMethodName, { + Name: name, + Context: context, + Options: options + }, "best", { + methodResponseTimeoutMs: startTimeout, + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + const acsResult = result.returned; + if (typeof acsResult.timeout !== "undefined" && typeof options.timeout === "undefined") { + startTimeout = acsResult.timeout * 1000; + } + if (typeof acsResult.waitForInterop !== "undefined" && (typeof options.waitForAGMReady === "undefined" && typeof options.awaitInterop === "undefined")) { + waitForAGMInstance = acsResult.waitForInterop; + } + if (acsResult && acsResult.Id) { + if (this._appManager.mode === "startOnly") { + const instance = this._appManager.handleInstanceStarted({ + ActivityId: undefined, + IsActivityOwner: undefined, + Context: undefined, + Title: undefined, + AgmServers: undefined, + Id: acsResult.Id, + Name: acsResult.Name, + }); + resolve(instance); + } + else { + waitForApplicationInstance(acsResult.Id); + } + } + else { + resolve(undefined); + } + } + catch (error) { + const err = Utils.typedError(error); + reject(err); + } + }); + } + onInstanceStarted(callback) { + validate(callback, this._configuration()); + return this._registry.add("instanceStarted", callback); + } + onInstanceStopped(callback) { + validate(callback, this._configuration()); + return this._registry.add("instanceStopped", callback); + } + onAvailable(callback) { + validate(callback, this._configuration()); + if (this._props.IsReady) { + setTimeout(() => { + this._registry.execute("appAvailable", this); + }, 0); + } + return this._registry.add("appAvailable", callback); + } + onUnavailable(callback) { + validate(callback, this._configuration()); + if (this._props.IsReady === false) { + setTimeout(() => { + this._registry.execute("appUnavailable", this); + }, 0); + } + return this._registry.add("appUnavailable", callback); + } + onChanged(callback) { + validate(callback, this._configuration()); + this._registry.add("appChanged", callback); + } + onRemoved(callback) { + validate(callback, this._configuration()); + this._registry.add("appRemoved", callback); + } + } + + class InstanceImpl { + constructor(_id, _appName, _appManager, _agm, _activities, _windows, _logger, startFailed, _configuration) { + this._id = _id; + this._appName = _appName; + this._appManager = _appManager; + this._agm = _agm; + this._activities = _activities; + this._windows = _windows; + this._logger = _logger; + this._configuration = _configuration; + this._registry = CallbackRegistryFactory(); + if (startFailed) { + return; + } + this._unsubscribeInstanceStopped = this._appManager.onInstanceStopped((instance) => { + if (instance.id !== this._id) { + return; + } + this._registry.execute("stopped", instance); + }); + this._unsubscribeInstanceAgmServerReady = this._appManager.onInstanceAgmServerReady((instance) => { + if (instance.id !== this._id) { + return; + } + this._registry.execute("agmReady", instance); + }); + } + get id() { return this._id; } + get application() { return this._appManager.application(this._appName); } + get activity() { + if (!this._activities) { + throw new Error("This method requires glue.activities library to be enabled."); + } + return this._activities.all.instances.get() + .filter((activityInstance) => activityInstance.id === this._activityId)[0]; + } + get isActivityOwner() { return this._isActivityOwner; } + get activityInstances() { + return this._appManager.instances().filter((i) => i.application.type !== "activity" && + i.activityId && + i.activityId === this._activityId); + } + get activityOwnerInstance() { + if (!this._activityId) { + return undefined; + } + return this.activityInstances.filter((inst) => inst === null || inst === void 0 ? void 0 : inst.isActivityOwner)[0]; + } + get window() { + if (!this._windows) { + throw new Error("This method requires glue.windows library to be enabled."); + } + let win = this._windows.list().find((w) => w.id === this._id); + if (!win && this._activities && this.activity && this.activityOwnerInstance) { + win = this.activityOwnerInstance.window; + } + return win; + } + get context() { + var _a, _b, _c; + return (_c = (_a = this._startUpContext) !== null && _a !== void 0 ? _a : (_b = this.window) === null || _b === void 0 ? void 0 : _b.context) !== null && _c !== void 0 ? _c : {}; + } + get title() { return this._title; } + get isActivityInstance() { return this._isActivityInstance; } + get activityId() { return this._activityId; } + get inActivity() { return this._inActivity; } + get isSingleWindowApp() { return !this._inActivity; } + get agm() { + return this._agmInstance; + } + get interopInstance() { + return this._agmInstance; + } + onInteropReady(callback) { + validate(callback, this._configuration()); + if (this._agmInstance) { + setTimeout(() => { + this._registry.execute("agmReady", this); + }, 0); + } + return this._registry.add("agmReady", callback); + } + onAgmReady(callback) { + return this.onInteropReady(callback); + } + onStopped(callback) { + validate(callback, this._configuration()); + return this._registry.add("stopped", callback); + } + getWindow() { + return new Promise((resolve, reject) => { + const result = this.window; + if (result) { + resolve(result); + return; + } + const done = (error, window) => { + if (error) { + reject(error); + } + if (window) { + resolve(window); + } + setTimeout(() => { + clearTimeout(timeout); + unsub(); + }, 0); + }; + this._logger.trace(`waiting for window with id ${this._id} to appear`); + const timeoutInSeconds = 60; + const timeout = setTimeout(() => { + this._logger.trace(`window with id ${this._id} did not appear in ${timeoutInSeconds} sec`); + done(new Error(`can not find a window with id ${this._id}`)); + }, timeoutInSeconds * 1000); + const unsub = this._windows.onWindowAdded((w) => { + if (w.id === this._id) { + this._logger.trace(`window with id ${this._id} appeared`); + done(undefined, w); + } + }); + }); + } + updateFromProps(props) { + this._startUpContext = props.Context; + this._title = props.Title; + this._isActivityInstance = false; + if (props.ActivityId && props.ActivityId !== "") { + this._activityId = props.ActivityId; + this._isActivityInstance = true; + } + this._isActivityOwner = props.IsActivityOwner; + if (!this._activityId && this._startUpContext && this._startUpContext.activityId) { + this._activityId = this._startUpContext.activityId; + } + this._inActivity = Boolean(this._activityId); + this.updateAgmInstanceFromProps(props); + } + updateAgmInstanceFromProps(props) { + if (!props.AgmServers) { + return; + } + const agmInstances = props.AgmServers; + if (agmInstances && agmInstances.length > 0 && !isUndefinedOrNull(agmInstances[0])) { + this._agmInstance = agmInstances[0]; + } + } + stop() { + return new Promise((resolve, reject) => { + let idToResolve = this._id; + if (this.isActivityOwner) { + idToResolve = this.activityId; + } + const unsubscribe = this._appManager.onInstanceStopped((instance) => { + if (instance.id === idToResolve) { + this._logger.trace(`instance with id ${idToResolve} stopped`); + unsubscribe(); + resolve(); + } + }); + this._logger.trace(`stopping instance with id ${this._id}`); + this._agm.invoke(StopApplicationMethodName, { + Name: this._appName, + Id: this._id + }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }) + .then(() => { + if (this._appManager.mode === "startOnly") { + this._appManager.handleInstanceStopped({ + Name: this._appName, + Id: this.id + }); + resolve(); + } + }) + .catch((err) => reject(err)); + }); + } + activate() { + return this._agm.invoke(ActivateApplicationMethodName, { Name: this._appName, Id: this._id }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + done() { + this._registry.clear(); + this._unsubscribeInstanceAgmServerReady(); + this._unsubscribeInstanceStopped(); + } + getContext() { + return Promise.resolve(this.context); + } + async startedBy() { + const result = await this._agm.invoke(ACSExecute, { command: "getStartedBy", Name: this._appName, Id: this._id }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return result.returned; + } + } + + class AppManagerImpl { + constructor(mode, _agm, _activities, _windows, _logger, _gdMajorVersion, _configuration) { + this.mode = mode; + this._agm = _agm; + this._activities = _activities; + this._windows = _windows; + this._logger = _logger; + this._gdMajorVersion = _gdMajorVersion; + this._configuration = _configuration; + this._apps = {}; + this._instances = []; + this._registry = CallbackRegistryFactory(); + this.getConfigurations = async (apps) => { + const args = { + v2: { + apps: undefined + } + }; + if (Array.isArray(apps)) { + args.v2 = { + apps + }; + } + const result = await this._agm.invoke(GetApplicationsMethodName, args, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return result.returned.applications; + }; + this.application = (name) => { + var _a; + if (((_a = this._configuration()) === null || _a === void 0 ? void 0 : _a.throwErrors) && typeof name !== "string" || isNullOrWhiteSpace(name)) { + throw new Error(`"name" must be string`); + } + return this._apps[name]; + }; + this.applications = () => { + return Object.keys(this._apps).map((k) => this._apps[k]); + }; + this.instances = () => { + return this._instances.map((i) => i); + }; + this.getMyInstance = () => { + const glue42gd = typeof window !== "undefined" && window.glue42gd; + if (glue42gd) { + if (this._gdMajorVersion >= 3) { + const instanceId = glue42gd.appInstanceId; + return this._instances.find((i) => i.id === instanceId); + } + } + else { + const instanceId = this._agm.instance.instance; + return this._instances.find((i) => i.id === instanceId); + } + return undefined; + }; + this.getMyApplication = () => { + var _a; + if (this._agm.instance) { + return (_a = this.application(this._agm.instance.applicationName)) !== null && _a !== void 0 ? _a : this.application(this._agm.instance.application); + } + }; + this.handleSnapshotAppsAdded = (newApps) => { + const currentApps = this.applications(); + if (currentApps.length > 0) { + currentApps.forEach((item) => { + const name = item.name; + const alreadyExists = newApps.find((i) => i.Name === item.name); + if (!alreadyExists) { + this.handleAppRemoved({ Name: name }); + } + }); + } + newApps.forEach((item) => { + const alreadyExists = currentApps.find((i) => i.name === item.Name); + if (!alreadyExists) { + this.handleAppAdded(item); + } + }); + }; + this.handleSnapshotInstanceStarted = (newInstances) => { + const currentInstances = this.instances(); + if (currentInstances.length > 0) { + currentInstances.forEach((item) => { + const id = item.id; + const alreadyExists = newInstances.find((i) => i.Id === id); + if (!alreadyExists) { + this.handleInstanceStopped({ Name: item.application.name, Id: id }); + } + }); + } + newInstances.forEach((item) => { + const alreadyExists = currentInstances.find((i) => i.id === item.Id); + if (!alreadyExists) { + this.handleInstanceStarted(item); + } + }); + }; + this.handleAppAdded = (props) => { + const id = this._getAppId(props); + this._logger.trace(`adding app ${id}`); + this._apps[id] = new ApplicationImpl(this, id, this._agm, this._logger, this._configuration); + const app = this._updateAppFromProps(props); + this._registry.execute("appAdded", app); + this._registry.execute("appAvailable", app); + }; + this.handleAppUpdated = (props) => { + const app = this._updateAppFromProps(props); + this._registry.execute("appChanged", app); + }; + this.handleAppRemoved = (props) => { + const id = this._getAppId(props); + this._logger.trace(`removing app ${id}`); + const app = this.application(id); + this._instances = this._instances.filter((i) => i.application.name !== app.name); + delete this._apps[id]; + this._registry.execute("appRemoved", app); + }; + this.handleAppReady = (props) => { + const id = this._getAppId(props); + const app = this._getAppOrThrow(id); + app.updateFromProps(props); + if (app.available) { + this._registry.execute("appAvailable", app); + } + else { + this._registry.execute("appUnavailable", app); + } + }; + this.handleInstanceStarted = (props) => { + this._logger.trace(`started app ${props.Name} ${props.Id}`); + const id = this._getInstanceId(props); + const appName = this._getInstanceAppName(props); + const instance = new InstanceImpl(id, appName, this, this._agm, this._activities, this._windows, this._logger, false, this._configuration); + this._updateInstanceFromProps(instance, props); + this._instances.push(instance); + this._registry.execute("instanceStarted", instance); + return instance; + }; + this.handleInstanceStopped = (props) => { + this._logger.trace(`instance stopped ${props.Name} ${props.Id}`); + const id = this._getInstanceId(props); + const appName = this._getInstanceAppName(props); + const instance = this._getInstanceOrThrow(id, appName); + this._instances = this._instances.filter((i) => !this._matchInstance(i, id, appName)); + this._registry.execute("instanceStopped", instance); + instance.done(); + }; + this.handleInstanceAgmServerReady = (props) => { + this._logger.trace(`instance interop server ready ${props.Name} ${props.Id}`); + const id = this._getInstanceId(props); + const appName = this._getInstanceAppName(props); + const instance = this._getInstanceOrThrow(id, appName); + instance.updateAgmInstanceFromProps(props); + this._registry.execute("instanceAgmServerReady", instance); + }; + this.handleInstanceStartFailed = (props) => { + const id = this._getInstanceId(props); + const appName = this._getInstanceAppName(props); + const startFailed = true; + const instance = new InstanceImpl(id, appName, undefined, undefined, undefined, undefined, this._logger, startFailed, this._configuration); + this._updateInstanceFromProps(instance, props); + this._registry.execute("instanceStartFailed", instance); + }; + this.handleInstanceUpdated = (props) => { + const id = this._getInstanceId(props); + const app = this._getInstanceAppName(props); + const instance = this._getInstanceOrThrow(id, app); + this._updateInstanceFromProps(instance, props); + }; + this.onInstanceStarted = (callback) => { + validate(callback, this._configuration()); + return this._registry.add("instanceStarted", callback, this._instances); + }; + this.onInstanceStartFailed = (callback) => { + validate(callback, this._configuration()); + return this._registry.add("instanceStartFailed", callback); + }; + this.onInstanceStopped = (callback) => { + validate(callback, this._configuration()); + return this._registry.add("instanceStopped", callback); + }; + this.onInstanceUpdated = (callback) => { + validate(callback, this._configuration()); + return this._registry.add("instanceChanged", callback); + }; + this.onInstanceAgmServerReady = (callback) => { + validate(callback, this._configuration()); + return this._registry.add("instanceAgmServerReady", callback); + }; + this.onAppAdded = (callback) => { + validate(callback, this._configuration()); + return this._registry.add("appAdded", callback, Object.values(this._apps)); + }; + this.onAppRemoved = (callback) => { + validate(callback, this._configuration()); + return this._registry.add("appRemoved", callback); + }; + this.onAppAvailable = (callback) => { + validate(callback, this._configuration()); + return this._registry.add("appAvailable", callback); + }; + this.onAppUnavailable = (callback) => { + validate(callback, this._configuration()); + return this._registry.add("appUnavailable", callback); + }; + this.onAppChanged = (callback) => { + validate(callback, this._configuration()); + return this._registry.add("appChanged", callback); + }; + } + _getAppOrThrow(id) { + const result = this.application(id); + if (!result) { + throw Error(`app with id ${id} not found`); + } + return result; + } + _getAppId(props) { + return props.Name; + } + _matchInstance(instance, id, appName) { + return instance.id === id && instance.application.name === appName; + } + _getInstanceByIdAndName(id, appName) { + return this._instances.filter((i) => this._matchInstance(i, id, appName))[0]; + } + _getInstanceOrThrow(id, appName) { + const result = this._getInstanceByIdAndName(id, appName); + if (!result) { + throw Error(`instance with id ${id} not found`); + } + return result; + } + _getInstanceId(props) { + return props.Id; + } + _getInstanceAppName(props) { + return props.Name; + } + _updateAppFromProps(props) { + const id = this._getAppId(props); + this._logger.trace(`updating app with + ${id}, ${JSON.stringify(props)}`); + const app = this._getAppOrThrow(id); + app.updateFromProps(props); + return app; + } + _updateInstanceFromProps(instance, props) { + this._logger.trace("updating instance with " + this._getInstanceId(props) + " for app " + this._getInstanceAppName(props)); + instance.updateFromProps(props); + } + } + + function promisify(promise, successCallback, errorCallback) { + const isFunction = (arg) => { + return !!(arg && arg.constructor && arg.call && arg.apply); + }; + if (!isFunction(successCallback) && !isFunction(errorCallback)) { + return promise; + } + if (!isFunction(successCallback)) { + successCallback = () => { + }; + } + else if (!isFunction(errorCallback)) { + errorCallback = () => { + }; + } + return promise.then(successCallback, errorCallback); + } + class EntitlementsImpl { + constructor(_agm) { + this._agm = _agm; + this._registry = CallbackRegistryFactory(); + this._isMethodRegistered = false; + this.handleBranchModified = (branch) => { + this._registry.execute("branchChanged", branch); + }; + this.handleBranchesModified = (branches) => { + this._registry.execute("branchesChanged", branches); + }; + this.getRegion = (success, error) => { + return promisify(this._agmInvoke(GetConfigurationRegionMethodName, (e) => e.returned.Region), success, error); + }; + this.getBranches = (success, error) => { + const promise = this._agmInvoke(GetBranchesMethodName, (e) => { + const obj = e.returned.Branches; + return Object.keys(obj).map((key) => obj[key]); + }); + return promisify(promise, success, error); + }; + this.getCurrentBranch = (success, error) => { + const promise = this._agmInvoke(GetCurrentBranchMethodName, (e) => e.returned.Branch, undefined); + return promisify(promise, success, error); + }; + this.setRegion = (region, success, error) => { + const promise = this._agmInvoke(SetConfigurationRegionMethodName, (e) => e.returned.ResultMessage, { Region: region }); + return promisify(promise, success, error); + }; + this.setCurrentBranch = (branch, success, error) => { + const promise = this._agmInvoke(SetCurrentBranchMethodName, (e) => e.returned.ResultMessage, { Branch: branch }); + return promisify(promise, success, error); + }; + this.currentUser = (success, error) => { + const promise = this._agmInvoke(GetUserMethodName); + return promisify(promise, success, error); + }; + this.getFunctionalEntitlement = (funct, success, error) => { + const promise = this._agmInvoke(GetFunctionalEntitlementMethodName, (e) => e.returned.Entitlement, { Function: funct }); + return promisify(promise, success, error); + }; + this.getFunctionalEntitlementBranch = (funct, branch, success, error) => { + const promise = this._agmInvoke(GetFunctionalEntitlementMethodName, (e) => e.returned.Entitlement, { Function: funct, Branch: branch }); + return promisify(promise, success, error); + }; + this.canI = (func, success, error) => { + const promise = this._agmInvoke(CanIMethodName, (e) => e.returned.Result, { Function: func }); + return promisify(promise, success, error); + }; + this.canIBranch = (func, branch, success, error) => { + const promise = this._agmInvoke(CanIMethodName, (e) => e.returned.Result, { Function: func, Branch: branch }); + return promisify(promise, success, error); + }; + this.onBranchesChanged = (callback) => { + return this._registry.add("branchesChanged", callback); + }; + this.onBranchChanged = (callback) => { + return this._registry.add("branchChanged", callback); + }; + this.exit = (options) => { + return this._agmInvoke(ShutdownMethodName, null, options); + }; + this.onShuttingDown = (callback) => { + this.registerMethod(); + return this._registry.add("onShuttingDown", callback); + }; + this.restart = (options) => { + return this._agmInvoke(RestartMethodName, null, options); + }; + this._agmInvoke = (method, transformFunction, args) => { + args = args || {}; + return new Promise((resolve, reject) => { + const errHandler = (error) => reject(error); + this._agm.invoke(method, args, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }) + .then((result) => { + if (!transformFunction) { + transformFunction = (d) => d.returned; + } + resolve(transformFunction(result)); + }) + .catch(errHandler); + }); + }; + } + registerMethod() { + if (!this._isMethodRegistered) { + this._agm.register(OnGDShutdownMethodName, async (args) => { + try { + const results = await Promise.all(this._registry.execute("onShuttingDown", args)); + const prevent = results.some((r) => r.prevent); + return { prevent }; + } + catch (error) { + } + }); + this._isMethodRegistered = true; + } + } + } + + function snapshot(interop, appManager) { + return new Promise((resolve, reject) => { + interop.invoke(GetApplicationsMethodName, { skipIcon: true }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }) + .then((response) => { + var _a; + const data = response.returned; + const configuration = (_a = response.returned.configuration) !== null && _a !== void 0 ? _a : {}; + if (!data) { + resolve(configuration); + } + const applications = data.applications; + if (!applications) { + resolve(configuration); + } + objectValues(applications).map((item) => appManager.handleAppAdded(item)); + resolve(configuration); + }) + .catch((err) => reject(new Error(`Error getting application snapshot: ${err.message}`))); + }); + } + + const OnBranchChangedEvent = "OnBranchChanged"; + const OnBranchesModifiedEvent = "OnBranchesModified"; + const OnApplicationAddedEvent = "OnApplicationAdded"; + const OnApplicationRemovedEvent = "OnApplicationRemoved"; + const OnApplicationChangedEvent = "OnApplicationChanged"; + const OnApplicationReadyEvent = "OnApplicationReady"; + const OnApplicationStartedEvent = "OnApplicationStarted"; + const OnApplicationAgmServerReadyEvent = "OnApplicationAgmServerReady"; + const OnApplicationUpdatedEvent = "OnApplicationUpdated"; + const OnApplicationStoppedEvent = "OnApplicationStopped"; + const OnApplicationStartFailedEvent = "OnApplicationStartFailed"; + + function createDataSubscription(agm, applications, entitlements, skipIcons) { + let subscription; + let initiated = false; + const start = () => { + let resolveFunc; + let rejectFunc; + const resultPromise = new Promise((resolve, reject) => { + resolveFunc = resolve; + rejectFunc = reject; + }); + agm.subscribe(OnEventMethodName, { arguments: { skipIcon: skipIcons }, waitTimeoutMs: 10000 }) + .then((s) => { + subscription = s; + subscription.onData((streamData) => { + var _a; + const events = streamData.data; + const configuration = (_a = events.configuration) !== null && _a !== void 0 ? _a : {}; + const onApplicationAddedEventArgs = objectValues(events[OnApplicationAddedEvent]); + if (streamData.data.isSnapshot) { + applications.handleSnapshotAppsAdded(onApplicationAddedEventArgs); + } + else { + onApplicationAddedEventArgs.forEach((item) => applications.handleAppAdded(item)); + } + objectValues(events[OnApplicationChangedEvent]) + .forEach((item) => applications.handleAppUpdated(item)); + objectValues(events[OnApplicationRemovedEvent]) + .forEach((item) => applications.handleAppRemoved(item)); + objectValues(events[OnApplicationReadyEvent]) + .forEach((item) => applications.handleAppReady(item)); + const onApplicationStartedEventArgs = objectValues(events[OnApplicationStartedEvent]); + if (streamData.data.isSnapshot) { + applications.handleSnapshotInstanceStarted(onApplicationStartedEventArgs); + } + else { + onApplicationStartedEventArgs.forEach((item) => applications.handleInstanceStarted(item)); + } + objectValues(events[OnApplicationStartFailedEvent]) + .forEach((item) => applications.handleInstanceStartFailed(item)); + objectValues(events[OnApplicationStoppedEvent]) + .forEach((item) => applications.handleInstanceStopped(item)); + objectValues(events[OnApplicationUpdatedEvent]) + .forEach((item) => applications.handleInstanceUpdated(item)); + objectValues(events[OnApplicationAgmServerReadyEvent]) + .forEach((item) => applications.handleInstanceAgmServerReady(item)); + objectValues(events[OnBranchChangedEvent]) + .forEach((item) => entitlements.handleBranchModified(item)); + objectValues(events[OnBranchesModifiedEvent]) + .forEach((item) => entitlements.handleBranchesModified(item)); + if (!initiated) { + initiated = true; + const hasMyAppInSnapShot = onApplicationAddedEventArgs.some((a) => a.Name === agm.instance.application); + const hasMyInstanceInSnapShot = onApplicationStartedEventArgs.some((i) => i.Id === agm.instance.instance); + if (hasMyAppInSnapShot) { + if (hasMyInstanceInSnapShot) { + resolveFunc(configuration); + } + else { + const un = applications.onInstanceStarted((i) => { + if (i.id === agm.instance.instance) { + un(); + resolveFunc(configuration); + } + }); + } + } + else { + resolveFunc(configuration); + } + } + }); + subscription.onFailed((err) => rejectFunc(err)); + }) + .catch((err) => { var _a; return rejectFunc(`Error subscribing for ${OnEventMethodName} stream. Err: ${(_a = err.message) !== null && _a !== void 0 ? _a : JSON.stringify(err)}`); }); + return resultPromise; + }; + const stop = () => { + if (subscription) { + subscription.close(); + } + }; + return { + start, + stop + }; + } + + const InMemoryStoreCommandMethodName = "T42.ACS.InMemoryStoreCommand"; + class InMemoryStore { + constructor(interop) { + this.interop = interop; + } + import(apps, mode) { + if (!apps || !Array.isArray(apps)) { + return Promise.reject(new Error("invalid apps argument - should be an array of application definitions")); + } + if (mode && mode !== "replace" && mode !== "merge") { + return Promise.reject(new Error("invalid mode argument - should be 'replace' or 'merge'")); + } + mode = mode !== null && mode !== void 0 ? mode : "replace"; + const command = { + command: "import", + args: { + apps, + mode + } + }; + return this.interop.invoke(InMemoryStoreCommandMethodName, command, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }) + .then((r) => r.returned); + } + export() { + return this.interop.invoke(InMemoryStoreCommandMethodName, { command: "export" }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }) + .then((r) => r.returned.apps); + } + remove(app) { + if (!app || typeof app !== "string") { + return Promise.reject(new Error("invalid app name, should be a string value")); + } + const command = { + command: "remove", + args: { + apps: [app] + } + }; + return this.interop.invoke(InMemoryStoreCommandMethodName, command, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }).then((r) => r.returned); + } + clear() { + const command = { + command: "clear" + }; + return this.interop.invoke(InMemoryStoreCommandMethodName, command, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }).then((r) => r.returned); + } + createAppDef(name, url) { + if (!url) { + url = "https://google.com"; + } + return { + name, + type: "window", + title: name, + details: { + url + } + }; + } + } + + var AppManagerFactory = (config) => { + if (!config) { + throw Error("config not set"); + } + if (!config.agm) { + throw Error("config.agm is missing"); + } + const START_ONLY = "startOnly"; + const SKIP_ICONS = "skipIcons"; + const FULL = "full"; + const mode = config.mode || START_ONLY; + if (mode !== START_ONLY && mode !== SKIP_ICONS && mode !== FULL) { + throw new Error(`Invalid mode for appManager lib - ${mode} is not supported`); + } + const activities = config.activities; + const agm = config.agm; + const logger = config.logger; + const windows = config.windows; + let configuration = {}; + const appManager = new AppManagerImpl(mode, agm, activities, windows, logger.subLogger("applications"), config.gdMajorVersion, () => configuration); + const entitlements = new EntitlementsImpl(agm); + let readyPromise; + if (mode === START_ONLY) { + readyPromise = snapshot(agm, appManager); + } + else { + const subscription = createDataSubscription(agm, appManager, entitlements, mode === SKIP_ICONS); + readyPromise = subscription.start(); + } + const api = { + ready: () => readyPromise.then((c) => { configuration = c; }), + applications: appManager.applications, + application: appManager.application, + getConfigurations: appManager.getConfigurations, + onAppAdded: appManager.onAppAdded, + onAppRemoved: appManager.onAppRemoved, + onAppChanged: appManager.onAppChanged, + onAppAvailable: appManager.onAppAvailable, + onAppUnavailable: appManager.onAppUnavailable, + instances: appManager.instances, + get myInstance() { + return appManager.getMyInstance(); + }, + get myApplication() { + return appManager.getMyApplication(); + }, + onInstanceStarted: appManager.onInstanceStarted, + onInstanceStopped: appManager.onInstanceStopped, + onInstanceUpdated: appManager.onInstanceUpdated, + onInstanceStartFailed: appManager.onInstanceStartFailed, + getRegion: entitlements.getRegion, + getBranches: entitlements.getBranches, + getCurrentBranch: entitlements.getCurrentBranch, + getFunctionalEntitlement: entitlements.getFunctionalEntitlement, + getFunctionalEntitlementBranch: entitlements.getFunctionalEntitlementBranch, + setCurrentBranch: entitlements.setCurrentBranch, + setRegion: entitlements.setRegion, + currentUser: entitlements.currentUser, + canI: entitlements.canI, + canIBranch: entitlements.canIBranch, + onBranchesChanged: entitlements.onBranchesChanged, + exit: entitlements.exit, + restart: entitlements.restart, + onShuttingDown: entitlements.onShuttingDown, + inMemory: new InMemoryStore(agm) + }; + return api; + }; + + const T42JumpListAction = "T42.JumpList.Action"; + class JumpListManager { + constructor() { + this._groupActionCallbacks = new Map(); + this._registered = false; + } + init(executor, agm, logger) { + this._executor = executor; + this._agm = agm; + this._logger = logger; + this.registerCallbackMethod(); + } + setEnabled(windowId, enabled) { + const settings = { + enabled + }; + return this._executor.updateJumpList(windowId, settings); + } + createCategory(windowId, title, actions) { + this.validateActions(title, actions); + const settings = { + category: { + title, + operation: "create", + actions: this.toUpdateActions(windowId, "create", title, actions) + } + }; + return this._executor.updateJumpList(windowId, settings); + } + removeCategory(windowId, title) { + const settings = { + category: { + title, + operation: "remove", + actions: [] + } + }; + this.manageActionCallback(windowId, settings.category.operation, title); + return this._executor.updateJumpList(windowId, settings); + } + createActions(windowId, categoryTitle, actions) { + this.validateActions(categoryTitle, actions); + const settings = { + category: { + title: categoryTitle, + operation: "update", + actions: this.toUpdateActions(windowId, "create", categoryTitle, actions) + } + }; + return this._executor.updateJumpList(windowId, settings); + } + removeActions(windowId, categoryTitle, actions) { + const settings = { + category: { + title: categoryTitle, + operation: "update", + actions: this.toUpdateActions(windowId, "remove", categoryTitle, actions) + } + }; + return this._executor.updateJumpList(windowId, settings); + } + async getActions(windowId, catgoryTitle) { + const actions = []; + const configuration = await this.getJumpListSettings(windowId); + const currentCategory = configuration.categories.find((category) => category.title === catgoryTitle); + if (currentCategory) { + currentCategory.actions.forEach((action) => { + const actionCallback = this.getActionCallback(action.callbackId); + if (actionCallback) { + action.callback = actionCallback.callback; + } + actions.push({ + icon: action.icon, + callback: action.callback, + singleInstanceTitle: action.singleInstanceTitle, + multiInstanceTitle: action.multiInstanceTitle + }); + }); + } + return Promise.resolve(actions); + } + getJumpListSettings(windowId) { + return this._executor.getJumpList(windowId); + } + toUpdateActions(windowId, operation, categoryTitle, actions) { + return actions.map((action) => { + const updateAction = { + icon: action.icon, + callback: action.callback, + callbackId: Utils.generateId(), + singleInstanceTitle: action.singleInstanceTitle, + multiInstanceTitle: action.multiInstanceTitle, + operation + }; + this.manageActionCallback(windowId, operation, categoryTitle, updateAction); + return updateAction; + }); + } + manageActionCallback(windowId, operation, categoryTitle, updateAction) { + var _a; + const groupCallbacksKey = `${categoryTitle}-${windowId}`; + if (operation === "create") { + if (!this._groupActionCallbacks.has(groupCallbacksKey)) { + this._groupActionCallbacks.set(groupCallbacksKey, []); + } + const categoryActionCallbacks = this._groupActionCallbacks.get(groupCallbacksKey); + categoryActionCallbacks.push({ + callbackId: updateAction.callbackId, + callback: updateAction.callback + }); + } + else if (operation === "remove") { + if (updateAction) { + let categoryActionCallbacks = (_a = this._groupActionCallbacks.get(groupCallbacksKey)) !== null && _a !== void 0 ? _a : []; + categoryActionCallbacks = categoryActionCallbacks.filter((accCal) => accCal.callbackId !== updateAction.callbackId); + if (categoryActionCallbacks.length === 0) { + this._groupActionCallbacks.delete(groupCallbacksKey); + } + else { + this._groupActionCallbacks.set(groupCallbacksKey, categoryActionCallbacks); + } + } + else { + this._groupActionCallbacks.delete(groupCallbacksKey); + } + } + } + registerCallbackMethod() { + if (this._registered) { + return; + } + this._registered = true; + try { + this._agm.register(T42JumpListAction, (args, caller) => { + const actionCallback = this.getActionCallback(args.callbackId); + if (actionCallback) { + try { + actionCallback.callback(); + } + catch (e) { + this._logger.error("Unable to execute user callback for jump list action!", e); + } + } + }); + } + catch (e) { + this._logger.error(`Unable to register method ${T42JumpListAction} for invoking jump list action callbacks!`, e); + return Promise.reject(e); + } + } + getActionCallback(callbackId) { + let callbackAction; + [...this._groupActionCallbacks.values()].forEach((callbacks) => { + const callback = callbacks.find((cal) => cal.callbackId === callbackId); + if (callback) { + callbackAction = callback; + } + }); + return callbackAction; + } + validateActions(category, actions) { + if (!(actions && actions.length > 0)) { + throw new Error(`Category '${category}' doesn't contain any actions!`); + } + actions.forEach((action) => { + if (!action.singleInstanceTitle) { + throw new Error(`Category '${category}' contains an action with undefined singleInstanceTitle!`); + } + if (!action.multiInstanceTitle) { + throw new Error(`Category '${category}' contains an action with undefined multiInstanceTitle!`); + } + if (!action.callback) { + throw new Error(`Category '${category}' contains an action with undefined callback function!`); + } + }); + } + } + var jumpListManager = new JumpListManager(); + + class WindowStore { + constructor() { + this.waitForTimeoutInMilliseconds = 60000; + this._windows = {}; + this._pendingWindows = {}; + this._pendingWindowsStates = {}; + this._registry = CallbackRegistryFactory(); + } + init(logger) { + this._logger = logger; + } + get(id) { + return this._windows[id] || this._pendingWindows[id]; + } + getIfReady(id) { + return this._windows[id]; + } + get list() { + return this._windows; + } + add(window, state) { + const isExist = typeof this._pendingWindows[window.API.id] !== "undefined"; + if (isExist) { + this._logger.error(`trying to add window with id ${window.API.id} from windowStore, which already exists`); + return; + } + this._pendingWindows[window.API.id] = window; + this._pendingWindowsStates[window.API.id] = state; + this._registry.execute("on-added", window); + if (this.shouldMarkReadyToShow(state)) { + this.markReadyToShow(window.API.id); + } + } + remove(window) { + delete this._windows[window.API.id]; + delete this._pendingWindows[window.API.id]; + delete this._pendingWindowsStates[window.API.id]; + this._registry.execute("on-removed", window); + } + setUrlChangedState(windowId) { + const targetWindowState = this._pendingWindowsStates[windowId]; + if (typeof targetWindowState === "undefined") { + return; + } + targetWindowState.urlChanged = true; + if (this.shouldMarkReadyToShow(targetWindowState)) { + this.markReadyToShow(windowId); + } + } + setCompositionChangedState(wrapper) { + const windowId = wrapper.API.id; + const targetWindowState = this._pendingWindowsStates[windowId]; + if (typeof targetWindowState === "undefined") { + return; + } + targetWindowState.compositionChanged = true; + if (this.shouldMarkReadyToShow(targetWindowState)) { + this.markReadyToShow(windowId); + } + } + waitFor(id) { + return new Promise((resolve, reject) => { + let unReady; + let unRemoved; + const timeout = setTimeout(() => { + unReady(); + unRemoved(); + reject(new Error(`Window with id "${id}" was not ready within ${this.waitForTimeoutInMilliseconds} milliseconds.`)); + }, this.waitForTimeoutInMilliseconds); + const win = this._windows[id]; + if (win) { + clearTimeout(timeout); + resolve(win); + } + else { + const cleanup = () => { + clearTimeout(timeout); + unReady(); + unRemoved(); + }; + unReady = this.onReadyWindow((w) => { + if (w.API.id !== id) { + return; + } + cleanup(); + resolve(w); + }); + unRemoved = this.onRemoved((w) => { + if (w.API.id !== id) { + return; + } + cleanup(); + reject(new Error(`Window with id "${id}" was closed before it became ready.`)); + }); + } + }); + } + onReadyWindow(callback) { + return this._registry.add("on-ready", callback); + } + onAdded(callback) { + return this._registry.add("on-added", callback); + } + onRemoved(callback) { + return this._registry.add("on-removed", callback); + } + markReadyToShow(windowId) { + if (this._pendingWindows[windowId]) { + this._windows[windowId] = this._pendingWindows[windowId]; + delete this._pendingWindows[windowId]; + delete this._pendingWindowsStates[windowId]; + } + this._registry.execute("on-ready", this._windows[windowId]); + } + shouldMarkReadyToShow(targetWindowState) { + return targetWindowState && targetWindowState.urlChanged && targetWindowState.ready && targetWindowState.compositionChanged; + } + } + var windowStore = new WindowStore(); + + class JumpListActions { + constructor(windowId, configuration) { + this.windowId = windowId; + this._categoryTitle = configuration.title; + } + list() { + return jumpListManager.getActions(this.windowId, this._categoryTitle); + } + create(actions) { + return jumpListManager.createActions(this.windowId, this._categoryTitle, actions); + } + remove(actions) { + return jumpListManager.removeActions(this.windowId, this._categoryTitle, actions); + } + } + + class JumpListCategories { + constructor(windowId) { + this.windowId = windowId; + } + list() { + return this.getCategories(); + } + create(title, actions) { + return jumpListManager.createCategory(this.windowId, title, actions); + } + remove(title) { + return jumpListManager.removeCategory(this.windowId, title); + } + async find(title) { + const categories = await this.getCategories(); + return categories.find((cat) => cat.title === title); + } + async getCategories() { + const result = []; + const configuration = await jumpListManager.getJumpListSettings(this.windowId); + configuration.categories.forEach((category) => { + result.push({ + title: category.title, + actions: new JumpListActions(this.windowId, category) + }); + }); + return result; + } + } + + class JumpList { + constructor(windowId) { + this.windowId = windowId; + this._categories = new JumpListCategories(windowId); + } + get categories() { + return this._categories; + } + async isEnabled() { + const configuration = await jumpListManager.getJumpListSettings(this.windowId); + return configuration.enabled; + } + setEnabled(enabled) { + return jumpListManager.setEnabled(this.windowId, enabled); + } + } + + var windowFactory = (id, options, executor, logger, appManagerGetter, displayAPIGetter, channelsAPIGetter, agm) => { + var _a, _b, _c, _d; + const _registry = CallbackRegistryFactory(); + const getChannels = () => { + const channels = channelsAPIGetter(); + if (!channels) { + throw new Error(`To use this method you need to enable channels API - set the channels property to true when initializing the Glue42 library`); + } + return channels; + }; + const _id = id; + const _name = options.name; + const _mode = options.mode; + let _bounds = options.bounds; + let _url = options.url; + let _title = options.title; + let _context = (_a = options.context) !== null && _a !== void 0 ? _a : {}; + let _frameColor = options.frameColor; + let _focus = options.focus; + let _neighbours = (_b = options.neighbours) !== null && _b !== void 0 ? _b : {}; + let _groupId = options.groupId; + let _isGroupHeaderVisible = options.isGroupHeaderVisible; + let _isTabHeaderVisible = options.isTabHeaderVisible; + let _isGroupHibernated = options.isGroupHibernated; + let _isGroupVisible = options.isGroupVisible; + let _isTabSelected = (_c = options.isTabSelected) !== null && _c !== void 0 ? _c : false; + let _settings = options.settings; + const _applicationName = options.applicationName; + let _isVisible = options.isVisible; + let _isSticky = options.isSticky; + let _isCollapsed = options.isCollapsed; + let _windowState = options.state; + let _tabGroupId = options.tabGroupId; + let _tabIndex = options.tabIndex; + let _frameId = options.frameId; + let _isLocked = options.isLocked; + let _allowWorkspaceDrop = options.allowWorkspaceDrop; + let _isPinned = options.isPinned; + let _group; + let _frameButtons = (_d = options.frameButtons) !== null && _d !== void 0 ? _d : []; + let _zoomFactor = options.zoomFactor; + let _placementSettings = options.placementSettings; + const _jumpList = new JumpList(id); + function close(cbOrOptions, error) { + if (typeof cbOrOptions === "undefined" || typeof cbOrOptions === "function") { + return Utils.callbackifyPromise(() => { + if (!id) { + throw new Error("The window is already closed."); + } + return executor.close(resultWindow); + }, cbOrOptions, error); + } + else { + return executor.close(resultWindow, cbOrOptions); + } + } + function navigate(newUrl, optionsOrCallback, error) { + if (typeof optionsOrCallback === "function") { + return Utils.callbackifyPromise(() => { + if (isNullOrWhiteSpace(newUrl)) { + throw new Error("The new URL must be a non-empty string."); + } + return executor.navigate(resultWindow, newUrl); + }, optionsOrCallback, error); + } + if (isNullOrWhiteSpace(newUrl)) { + throw new Error("The new URL must be a non-empty string."); + } + if ((optionsOrCallback === null || optionsOrCallback === void 0 ? void 0 : optionsOrCallback.timeout) && typeof optionsOrCallback.timeout !== "number") { + throw new Error("Timeout argument must be a valid number"); + } + return executor.navigate(resultWindow, newUrl, optionsOrCallback); + } + function setStyle(style, success, error) { + return Utils.callbackifyPromise(() => { + if (!style || Object.keys(style).length === 0 || Object.keys(style).every((key) => !key)) { + throw new Error("Invalid style arguments: " + JSON.stringify(style)); + } + if (style && style.focus !== undefined) { + if (typeof style.focus !== "boolean") { + throw new Error("Focus must be a boolean value. Currently, only `focus: true` is supported."); + } + else if (style.focus === false) { + console.warn("`focus: false` is not supported!"); + } + } + if (style && style.hidden !== undefined && typeof style.hidden !== "boolean") { + throw new Error("The `hidden` property must hold a boolean value."); + } + for (const prop of ["minHeight", "maxHeight", "minWidth", "maxWidth"]) { + const styleAsAny = style; + const value = styleAsAny[prop]; + if (prop in style) { + if (isUndefinedOrNull(value)) { + delete styleAsAny[prop]; + continue; + } + if (!isNumber(styleAsAny[prop])) { + throw new Error(`"${prop}" must be a number`); + } + } + } + return executor.setStyle(resultWindow, style); + }, success, error); + } + function resetButtons(buttons, success, error) { + return Utils.callbackifyPromise(() => executor.resetButtons(resultWindow, buttons), success, error); + } + function getButtons() { + return executor.getButtons(resultWindow); + } + function setOnTop(onTop, success, error) { + return Utils.callbackifyPromise(() => { + if (typeof onTop === "string") { + if (onTop !== "always") { + throw new Error("`onTop` must hold a `always` value."); + } + } + else if (typeof onTop !== "boolean") { + throw new Error("`onTop` must hold a boolean or `always` value."); + } + return executor.setOnTop(resultWindow, onTop); + }, success, error); + } + function setSizeConstraints(constraints, success, error) { + return Utils.callbackifyPromise(() => { + if (!constraints || Object.keys(constraints).every((value) => value === undefined)) { + throw new Error("The properties of `constraints` cannot be null or undefined."); + } + return executor.setSizeConstraints(resultWindow, constraints); + }, success, error); + } + function getSizeConstraints() { + return executor.getSizeConstraints(resultWindow); + } + function setTitle(newTitle, success, error) { + return Utils.callbackifyPromise(() => { + if (isUndefinedOrNull(newTitle)) { + throw new Error("`newTitle` must not be null or undefined."); + } + if (newTitle === _title) { + return Promise.resolve(resultWindow); + } + return executor.setTitle(resultWindow, newTitle); + }, success, error); + } + function setSticky(isSticky, success, error) { + return Utils.callbackifyPromise(() => { + if (typeof isSticky !== "boolean") { + throw new Error("`isSticky` must hold a boolean value."); + } + return executor.setSticky(resultWindow, isSticky); + }, success, error); + } + function setAllowWorkspaceDrop(allowWorkspaceDrop) { + if (typeof allowWorkspaceDrop !== "boolean") { + throw new Error("`allowWorkspaceDrop` must hold a boolean value."); + } + return executor.setAllowWorkspaceDrop(resultWindow, allowWorkspaceDrop); + } + function pin() { + return executor.pin(resultWindow); + } + function unpin() { + return executor.unpin(resultWindow); + } + function moveResize(bounds, success, error) { + return Utils.callbackifyPromise(() => { + if (isUndefinedOrNull(bounds)) { + throw new Error("The properties of `bounds` cannot be null or undefined."); + } + return executor.moveResize(resultWindow, bounds); + }, success, error); + } + function addFrameButton(buttonInfo, success, error) { + return Utils.callbackifyPromise(() => { + if (typeof buttonInfo === "undefined" || Object.keys(buttonInfo).length === 0) { + throw new Error("Button info is not available."); + } + if (isNullOrWhiteSpace(buttonInfo.buttonId)) { + throw new Error("`buttonId` must not be null or undefined."); + } + if (isNullOrWhiteSpace(buttonInfo.imageBase64)) { + throw new Error("`imageBase64` must not be null or undefined."); + } + return executor.addFrameButton(resultWindow, buttonInfo); + }, success, error); + } + function removeFrameButton(buttonId, success, error) { + return Utils.callbackifyPromise(() => { + if (isNullOrWhiteSpace(buttonId)) { + throw new Error("`buttonId` must not be null or undefined."); + } + return executor.removeFrameButton(resultWindow, buttonId); + }, success, error); + } + function activate(success, error) { + return Utils.callbackifyPromise(() => { + if (_focus) { + return Promise.resolve(resultWindow); + } + return executor.activate(resultWindow); + }, success, error); + } + function focus(success, error) { + return Utils.callbackifyPromise(() => { + if (_focus) { + return Promise.resolve(resultWindow); + } + return executor.focus(resultWindow); + }, success, error); + } + function maximizeRestore(success, error) { + return Utils.callbackifyPromise(() => { + return executor.maximizeRestore(resultWindow); + }, success, error); + } + function maximize(success, error) { + return Utils.callbackifyPromise(() => { + if (_windowState === "maximized") { + return Promise.resolve(resultWindow); + } + return executor.maximize(resultWindow); + }, success, error); + } + function restore(success, error) { + return Utils.callbackifyPromise(() => { + if (_windowState === "normal") { + return Promise.resolve(resultWindow); + } + return executor.restore(resultWindow); + }, success, error); + } + function minimize(success, error) { + return Utils.callbackifyPromise(() => { + if (_windowState === "minimized") { + return Promise.resolve(resultWindow); + } + return executor.minimize(resultWindow); + }, success, error); + } + function collapse(success, error) { + return Utils.callbackifyPromise(() => { + if (_isCollapsed) { + return Promise.resolve(resultWindow); + } + return executor.collapse(resultWindow); + }, success, error); + } + function expand(success, error) { + return Utils.callbackifyPromise(() => { + if (!_isCollapsed) { + return Promise.resolve(resultWindow); + } + return executor.expand(resultWindow); + }, success, error); + } + function toggleCollapse(success, error) { + return Utils.callbackifyPromise(() => { + return executor.toggleCollapse(resultWindow); + }, success, error); + } + function snap(target, direction, success, error) { + return Utils.callbackifyPromise(() => { + if (isUndefinedOrNull(target)) { + throw new Error(`A target window is not specified - ${typeof target === "string" ? target : JSON.stringify(target)}`); + } + if (typeof target === "string") { + const win = windowStore.get(target); + if (!win) { + throw new Error(`Invalid "target" parameter or no such window. Invoked with: ${target}`); + } + target = win.API; + } + if (typeof direction === "string") { + direction = { + direction, + autoAlign: true + }; + } + return executor.snap(resultWindow, target, direction); + }, success, error); + } + function attachTab(tab, opt, success, error) { + return Utils.callbackifyPromise(() => { + var _a; + const errorMessage = `Invalid "tab" parameter - must be an object with an "id" property or a string. Invoked for source window with ID:`; + if (isUndefinedOrNull(tab)) { + const errMsg = `${errorMessage} ${typeof tab === "string" ? tab : JSON.stringify(tab)}`; + throw new Error(errMsg); + } + let sourceWindow; + if (typeof tab === "string") { + sourceWindow = (_a = windowStore.get(tab)) === null || _a === void 0 ? void 0 : _a.API; + if (isUndefinedOrNull(sourceWindow)) { + const errMsg = `${errorMessage} ${typeof sourceWindow === "string" ? sourceWindow : JSON.stringify(sourceWindow)}`; + throw new Error(errMsg); + } + } + else if (!isUndefinedOrNull(tab.id)) { + sourceWindow = tab; + } + else { + throw new Error(errorMessage); + } + const attachOptions = {}; + if (!isUndefinedOrNull(opt)) { + if (typeof opt === "number") { + attachOptions.index = opt; + } + else { + attachOptions.selected = opt.selected; + attachOptions.index = opt.index; + } + } + return executor.attachTab(resultWindow, sourceWindow, attachOptions); + }, success, error); + } + function detachTab(opt = {}, success, error) { + return Utils.callbackifyPromise(() => { + const argsForSend = {}; + function isDetachRelative(o) { + return o.relativeTo !== undefined; + } + if (isDetachRelative(opt)) { + if (typeof opt.relativeTo === "string") { + argsForSend.relativeTo = opt.relativeTo; + } + else if (!isUndefinedOrNull(opt.relativeTo.id)) { + argsForSend.relativeTo = opt.relativeTo.id; + } + if (!isUndefinedOrNull(opt.relativeDirection)) { + argsForSend.relativeDirection = opt.relativeDirection; + } + if (!isUndefinedOrNull(opt.width)) { + argsForSend.width = opt.width; + } + if (!isUndefinedOrNull(opt.height)) { + argsForSend.height = opt.height; + } + } + else { + if (!isUndefinedOrNull(opt.bounds)) { + argsForSend.bounds = opt.bounds; + } + } + if (!isUndefinedOrNull(opt.hideTabHeader)) { + argsForSend.hideTabHeader = opt.hideTabHeader; + } + return executor.detachTab(resultWindow, argsForSend); + }, success, error); + } + function setVisible(toBeVisible, success, error) { + return Utils.callbackifyPromise(() => { + return executor.setVisible(resultWindow, toBeVisible); + }, success, error); + } + async function center(display) { + if (display) { + validateCenterArguments(display); + } + return executor.center(resultWindow, display); + } + function validateCenterArguments(display) { + if (typeof display !== "object") { + throw Error("display argument must be a valid display object"); + } + if (!display.workArea || !display.scaleFactor) { + throw Error("display argument is not a valid display object"); + } + } + function showLoader(loader) { + return executor.showLoader(resultWindow, loader); + } + function hideLoader() { + return executor.hideLoader(resultWindow); + } + function updateContext(context, success, error) { + return Utils.callbackifyPromise(() => { + if (!isObject(context)) { + throw new Error(`"context" must not be null or undefined.`); + } + return executor.updateContext(resultWindow, context, false); + }, success, error); + } + function lock(success, error) { + return Utils.callbackifyPromise(() => { + return executor.lock(resultWindow); + }, success, error); + } + function unlock(success, error) { + return Utils.callbackifyPromise(() => { + return executor.unlock(resultWindow); + }, success, error); + } + function getIcon(success, error) { + return Utils.callbackifyPromise(() => { + return executor.getIcon(resultWindow); + }, success, error); + } + function setIcon(base64Image, success, error) { + return Utils.callbackifyPromise(() => { + if (isNullOrWhiteSpace(base64Image)) { + throw new Error(`"base64Image" must be a non-empty string.`); + } + return executor.setIcon(resultWindow, base64Image); + }, success, error); + } + function setFrameColor(frameColor, success, error) { + return Utils.callbackifyPromise(() => { + if (isNullOrWhiteSpace(frameColor)) { + throw new Error(`"frameColor" must be a non-empty string`); + } + return executor.setFrameColor(resultWindow, frameColor); + }, success, error); + } + function setTabHeaderVisible(toBeTabHeaderVisible, success, error) { + return Utils.callbackifyPromise(() => { + if (typeof toBeTabHeaderVisible !== "boolean") { + throw new Error(`"toBeTabHeaderVisible" must hold a boolean value.`); + } + return executor.setTabHeaderVisible(resultWindow, toBeTabHeaderVisible); + }, success, error); + } + async function setTabTooltip(tooltip) { + if (isNullOrWhiteSpace(tooltip)) { + throw new Error(`"${tooltip}" must not be null or undefined`); + } + return executor.setTabTooltip(resultWindow, tooltip); + } + async function getTabTooltip() { + return executor.getTabTooltip(resultWindow); + } + function showPopup(config) { + return executor.showPopup(resultWindow, config); + } + function createFlydown(config) { + return executor.createFlydown(resultWindow.id, config); + } + function setModalState(isModal) { + return executor.setModalState(resultWindow.id, isModal || false); + } + function zoomIn(success, error) { + return Utils.callbackifyPromise(() => { + return executor.zoomIn(resultWindow); + }, success, error); + } + function zoomOut(success, error) { + return Utils.callbackifyPromise(() => { + return executor.zoomOut(resultWindow); + }, success, error); + } + function setZoomFactor(zoomFactor, success, error) { + return Utils.callbackifyPromise(() => { + if (isNaN(zoomFactor)) { + throw new Error(`zoomFactor is not a number`); + } + return executor.setZoomFactor(resultWindow, zoomFactor); + }, success, error); + } + function showDevTools() { + return executor.showDevTools(resultWindow); + } + function capture(captureOptions) { + return executor.capture(resultWindow, captureOptions); + } + function flash(suppliedOptions, mode) { + const flashOptions = { + shouldFlash: true, + mode: "auto" + }; + if (typeof suppliedOptions === "boolean") { + flashOptions.shouldFlash = suppliedOptions; + } + if (typeof mode !== "undefined") { + flashOptions.mode = mode; + } + return executor.flash(resultWindow, flashOptions); + } + function flashTab(suppliedOptions) { + const flashOptions = { + shouldFlash: true, + }; + if (typeof suppliedOptions === "boolean") { + flashOptions.shouldFlash = suppliedOptions; + } + return executor.flashTab(resultWindow, flashOptions); + } + function print(printOptions) { + return executor.print(resultWindow, printOptions); + } + function printToPDF(printToPDFOptions) { + return executor.printToPDF(resultWindow, printToPDFOptions); + } + function ungroup(ungroupOptions) { + return new Promise((resolve, reject) => { + const unGroupChanged = onGroupChanged((win, newGroup, oldGroup) => { + if (id === win.id) { + unGroupChanged(); + resolve(resultWindow); + } + }); + executor.ungroup(resultWindow, ungroupOptions) + .catch((e) => { + unGroupChanged(); + reject(e); + }); + }); + } + function place(placementSettings) { + return executor.place(resultWindow, placementSettings); + } + function refresh(ignoreCache) { + return executor.refresh(resultWindow, ignoreCache); + } + function download(url, opts) { + return executor.download(resultWindow, url, opts); + } + function configure(settings) { + return executor.configureWindow(resultWindow, settings); + } + function getConfiguration() { + return executor.getWindowConfiguration(resultWindow); + } + function getDockingPlacement() { + return executor.getDockingPlacement(resultWindow); + } + function dock(opts) { + return executor.dock(resultWindow, opts); + } + async function clone(cloneOptions) { + return executor.clone(resultWindow, cloneOptions); + } + async function executeCode(code) { + if (!code) { + throw new Error("Code argument is missing"); + } + if (typeof code !== "string") { + throw new Error("Code argument must be a valid string"); + } + const response = await executor.executeCode(resultWindow, code); + return response.result; + } + function onTitleChanged(callback) { + if (!isFunction(callback)) { + throw new Error("callback should be a function"); + } + callback(resultWindow.title, resultWindow); + return onEventCore("onTitleChanged", callback); + } + function onClose(callback) { + if (!isFunction(callback)) { + throw new Error("callback should be a function"); + } + if (id === undefined) { + callback(resultWindow); + } + return _registry.add("onClose", callback); + } + function onUrlChanged(callback) { + return onEventCore("onUrlChanged", callback); + } + function onFrameButtonAdded(callback) { + return onEventCore("onFrameButtonAdded", callback); + } + function onFrameButtonRemoved(callback) { + return onEventCore("onFrameButtonRemoved", callback); + } + function onFrameButtonClicked(callback) { + return onEventCore("onFrameButtonClicked", callback); + } + function onCollapsed(callback) { + if (!isFunction(callback)) { + throw new Error("callback should be a function"); + } + if (_isCollapsed) { + callback(resultWindow); + } + return _registry.add("collapsed", callback); + } + function onExpanded(callback) { + if (!isFunction(callback)) { + throw new Error("callback should be a function"); + } + if (!_isCollapsed) { + callback(resultWindow); + } + return _registry.add("expanded", callback); + } + function onMaximized(callback) { + if (_windowState === "maximized") { + return onEventCore("maximized", callback, [resultWindow]); + } + else { + return onEventCore("maximized", callback); + } + } + function onMinimized(callback) { + if (_windowState === "minimized") { + return onEventCore("minimized", callback, [resultWindow]); + } + else { + return onEventCore("minimized", callback); + } + } + function onNormal(callback) { + if (_windowState === "normal") { + return onEventCore("normal", callback, [resultWindow]); + } + else { + return onEventCore("normal", callback); + } + } + function onAttached(callback) { + return onEventCore("attached", callback); + } + function onDetached(callback) { + return onEventCore("detached", callback); + } + function onVisibilityChanged(callback) { + return onEventCore("visibility-changed", callback); + } + function onContextUpdated(callback) { + return onEventCore("context-updated", callback); + } + function onLockingChanged(callback) { + return onEventCore("lock-changed", callback); + } + function onBoundsChanged(callback) { + return onEventCore("bounds-changed", callback); + } + function onFocusChanged(callback) { + return onEventCore("focus-changed", callback); + } + function onStickyChanged(callback) { + return onEventCore("sticky-changed", callback); + } + function onFrameColorChanged(callback) { + return onEventCore("frame-color-changed", callback); + } + function onTabHeaderVisibilityChanged(callback) { + return onEventCore("tab-header-visibility-changed", callback); + } + function onWindowAttached(callback) { + return onEventCore("window-attached", callback); + } + function onWindowDetached(callback) { + return onEventCore("window-detached", callback); + } + function onGroupChanged(callback) { + return onEventCore("group-changed", callback); + } + function onTabSelectionChanged(callback) { + return onEventCore("tab-selection-changed", callback); + } + function onChannelRestrictionsChanged(callback) { + if (!isFunction(callback)) { + throw new Error("callback must be a function"); + } + return onEventCore("channel-restrictions-changed", callback); + } + function onClosing(callback) { + if (!isFunction(callback)) { + throw new Error("callback must be a function"); + } + const callbackWrap = (success, error, prevent) => { + const promise = callback(prevent); + if (promise === null || promise === void 0 ? void 0 : promise.then) { + promise.then(success).catch(error); + } + else { + success(); + } + }; + return executor.onClosing(callbackWrap, resultWindow); + } + function onRefreshing(callback) { + if (!isFunction(callback)) { + throw new Error("callback must be a function"); + } + const callbackWrap = (success, error, prevent) => { + const promise = callback(prevent); + if (promise === null || promise === void 0 ? void 0 : promise.then) { + promise.then(success).catch(error); + } + else { + success(); + } + }; + return executor.onRefreshing(callbackWrap, resultWindow); + } + function onNavigating(callback) { + if (!isFunction(callback)) { + throw new Error("callback must be a function"); + } + const callbackWrap = (success, error, prevent, args) => { + const promise = callback(args); + if (promise === null || promise === void 0 ? void 0 : promise.then) { + promise.then(success).catch(error); + } + else { + success(); + } + }; + return executor.onNavigating(callbackWrap, resultWindow); + } + function onZoomFactorChanged(callback) { + return onEventCore("zoom-factor-changed", callback); + } + function onPlacementSettingsChanged(callback) { + return onEventCore("placementSettingsChanged", callback); + } + function onNeighboursChanged(callback) { + return onEventCore("neighbours-changed", callback); + } + function onDockingChanged(callback) { + return onEventCore("docking-changed", callback); + } + function onEventCore(key, callback, replayArguments) { + if (!isFunction(callback)) { + throw new Error("callback must be a function"); + } + return _registry.add(key, callback, replayArguments); + } + function goBack() { + return executor.goBack(resultWindow); + } + function goForward() { + return executor.goForward(resultWindow); + } + function startDrag(option) { + return executor.startDrag(resultWindow, option); + } + function showDialog(dialogOptions) { + if ((dialogOptions === null || dialogOptions === void 0 ? void 0 : dialogOptions.timerDuration) && isNaN(dialogOptions === null || dialogOptions === void 0 ? void 0 : dialogOptions.timerDuration)) { + throw new Error("timerDuration must be a number"); + } + if ((dialogOptions === null || dialogOptions === void 0 ? void 0 : dialogOptions.showTimer) && typeof (dialogOptions === null || dialogOptions === void 0 ? void 0 : dialogOptions.showTimer) !== "boolean") { + throw new Error("showTimer must be a boolean"); + } + return executor.showDialog(resultWindow, dialogOptions); + } + function handleUpdate(updated) { + _url = updated.url; + _title = updated.title; + _context = updated.context || {}; + _bounds = updated.bounds; + _frameColor = updated.frameColor; + _focus = updated.focus; + _neighbours = updated.neighbours || {}; + _groupId = updated.groupId; + _isGroupHeaderVisible = updated.isGroupHeaderVisible; + _isTabHeaderVisible = updated.isTabHeaderVisible; + _isGroupHibernated = updated.isGroupHibernated; + _isGroupVisible = updated.isGroupVisible; + _isTabSelected = updated.isTabSelected; + _settings = updated.settings; + _isVisible = updated.isVisible; + _isSticky = updated.isSticky; + _isCollapsed = updated.isCollapsed; + _windowState = updated.state; + _tabGroupId = updated.tabGroupId; + _frameId = updated.frameId; + _isLocked = updated.isLocked; + _allowWorkspaceDrop = updated.allowWorkspaceDrop; + _isPinned = updated.isPinned; + _zoomFactor = updated.zoomFactor; + _placementSettings = updated.placementSettings; + } + function handleTitleChanged(newTitle) { + _title = newTitle; + executor.finished + .finally(() => { + _registry.execute("onTitleChanged", newTitle, resultWindow); + }); + } + function handleUrlChanged(newUrl) { + _url = newUrl; + _registry.execute("onUrlChanged", newUrl, resultWindow); + } + function handleVisibilityChanged(isVisible) { + if (isVisible === _isVisible) { + return; + } + _isVisible = isVisible; + _registry.execute("visibility-changed", resultWindow); + } + function handleWindowSettingsChanged(settings) { + _settings = settings; + _registry.execute("settings-changed", resultWindow); + } + function handleContextUpdated(context) { + _context = context; + _registry.execute("context-updated", _context, resultWindow); + } + function handleWindowClose() { + if (id === undefined) { + return; + } + _registry.execute("onClose", resultWindow); + id = undefined; + } + function handleFrameButtonAdded(frameButton) { + const buttonObj = ["buttonId", "imageBase64", "order", "tooltip"].reduce((memo, k) => { + memo[k] = frameButton[k]; + return memo; + }, {}); + const frameButtonsIds = _frameButtons.map((btn) => { + return btn.buttonId; + }); + if (frameButtonsIds.indexOf(frameButton.buttonId) === -1) { + _frameButtons.push(buttonObj); + } + _registry.execute("onFrameButtonAdded", buttonObj, resultWindow); + } + function handleFrameButtonRemoved(frameButtonId) { + let button; + _frameButtons = _frameButtons.reduce((memo, btn) => { + if (btn.buttonId === frameButtonId) { + button = btn; + } + else { + memo.push(btn); + } + return memo; + }, []); + if (button !== undefined) { + _registry.execute("onFrameButtonRemoved", button, resultWindow); + } + } + function handleFrameButtonClicked(frameButton) { + const button = _frameButtons.filter((btn) => { + return btn.buttonId === frameButton.buttonId; + }); + if (button.length > 0) { + _registry.execute("onFrameButtonClicked", button[0], resultWindow); + } + } + async function handleWindowChangeState(state) { + if (state === "collapsed") { + _isCollapsed = true; + } + else if (state === "expanded") { + _isCollapsed = false; + } + else { + _windowState = state; + } + await executor.finished; + _registry.execute(state, resultWindow); + } + function handleFrameIsLockedChanged(isLocked) { + _isLocked = isLocked; + _registry.execute("lock-changed", resultWindow); + } + function handleBoundsChanged(bounds) { + if (_bounds.top === bounds.top && _bounds.left === bounds.left && _bounds.width === bounds.width && _bounds.height === bounds.height) { + return; + } + _bounds = bounds; + _registry.execute("bounds-changed", resultWindow); + } + function handleFocusChanged(isFocused) { + _focus = isFocused; + _registry.execute("focus-changed", resultWindow); + } + function handleIsStickyChanged(isSticky) { + _isSticky = isSticky; + _registry.execute("sticky-changed", isSticky, resultWindow); + } + function handleFrameColorChanged(frameColor) { + _frameColor = frameColor; + _registry.execute("frame-color-changed", resultWindow); + } + function handleFrameAttached(tabGroupId, frameId, isTabHeaderVisible) { + _tabGroupId = tabGroupId; + _frameId = frameId; + _isTabHeaderVisible = isTabHeaderVisible; + _registry.execute("frame-attached", resultWindow); + } + function handleCompositionChanged(state) { + _neighbours = state.neighbors || {}; + _tabIndex = state.index; + _registry.execute("neighbours-changed", _neighbours, resultWindow); + } + function handleAllowWorkspaceDropChanged(allowWorkspaceDrop) { + _allowWorkspaceDrop = allowWorkspaceDrop; + _registry.execute("allow-workspace-drop-changed", resultWindow); + } + function handleIsPinnedChanged(isPinned) { + _isPinned = isPinned; + _registry.execute("is-pinned-changed", resultWindow); + } + function handleGroupHeaderVisibilityChanged(isGroupHeaderVisible) { + _isGroupHeaderVisible = isGroupHeaderVisible; + } + function handleTabHeaderVisibilityChanged(isTabHeaderVisible) { + if (_isTabHeaderVisible !== isTabHeaderVisible) { + _isTabHeaderVisible = isTabHeaderVisible; + _registry.execute("tab-header-visibility-changed", resultWindow); + } + } + async function handleFrameSelectionChanged(newWindow, prevWindow) { + let selectedWindow; + if (newWindow === id) { + _isTabSelected = true; + selectedWindow = resultWindow; + } + else { + _isTabSelected = false; + selectedWindow = windowStore.get(newWindow) ? windowStore.get(newWindow).API : undefined; + } + const previousWindow = windowStore.get(prevWindow) ? windowStore.get(prevWindow).API : undefined; + await executor.finished; + _registry.execute("tab-selection-changed", selectedWindow, previousWindow, resultWindow); + } + async function handleAttached(newTabGroupId, newFrameId, tabHeaderVisible, isLocked, winsToBeNotified) { + _tabGroupId = newTabGroupId; + _isTabHeaderVisible = tabHeaderVisible; + _frameId = newFrameId; + if (typeof isLocked !== "undefined") { + _isLocked = isLocked; + } + await executor.finished; + winsToBeNotified.forEach((w) => { + w.Events.handleWindowAttached(resultWindow); + }); + _registry.execute("attached", resultWindow); + } + function handleWindowAttached(win) { + _registry.execute("window-attached", win); + } + async function handleDetached(isLocked, winsToBeNotified) { + _tabGroupId = undefined; + _isTabSelected = false; + if (typeof isLocked !== "undefined") { + _isLocked = isLocked; + } + await executor.finished; + winsToBeNotified.forEach((w) => { + w.Events.handleWindowDetached(resultWindow); + }); + _registry.execute("detached", resultWindow); + } + function handleWindowDetached(win) { + _registry.execute("window-detached", win); + } + function handleZoomFactorChanged(zoomFactor) { + _zoomFactor = zoomFactor; + _registry.execute("zoom-factor-changed", resultWindow); + } + function handlePlacementSettingsChanged(placementSettings) { + let promise; + const copy = placementSettings; + if (!copy.display) { + promise = Promise.resolve(undefined); + } + else { + const displayAPI = displayAPIGetter(); + if (!displayAPI) { + promise = Promise.resolve(undefined); + } + else { + const index = copy.display - 1; + promise = new Promise((resolve, reject) => { + displayAPI.all().then((displays) => { + const display = displays.find((d) => d.index === index); + resolve(display); + }).catch(reject); + }); + } + } + void promise.then((d) => { + copy.display = d; + _placementSettings = copy; + _registry.execute("placementSettingsChanged", resultWindow); + }); + } + function handleDockingChanged(data) { + _registry.execute("docking-changed", resultWindow, { + docked: data.docked, + position: data.position, + claimScreenArea: data.claimScreenArea + }); + } + function handleChannelRestrictionsChanged(data) { + _registry.execute("channel-restrictions-changed", data); + } + function handleGroupChanged(newGroup, oldGroup) { + _group = newGroup; + _groupId = newGroup === null || newGroup === void 0 ? void 0 : newGroup.id; + if (!isUndefinedOrNull(newGroup) && !isUndefinedOrNull(oldGroup)) { + _registry.execute("group-changed", resultWindow, newGroup, oldGroup); + } + } + function getAllTabs() { + const allWindows = windowStore.list; + if (_mode.toLowerCase() !== "tab") { + return []; + } + const tabs = Object.keys(allWindows).reduce((memo, win) => { + const window = allWindows[win]; + if (window + && window.API.tabGroupId + && typeof window.API.tabGroupId !== "undefined" + && typeof resultWindow.tabGroupId !== "undefined" + && window.API.tabGroupId === resultWindow.tabGroupId) { + memo.push(window.API); + } + return memo; + }, []); + return tabs.sort((w1, w2) => { + if (w1.tabIndex !== w2.tabIndex) { + if (w1.tabIndex === -1) { + return Number.MAX_SAFE_INTEGER; + } + if (w2.tabIndex === -1) { + return Number.MIN_SAFE_INTEGER; + } + } + return w1.tabIndex - w2.tabIndex; + }); + } + function mapWindowIdsToWindowObjects(windowIdArr) { + return windowIdArr.reduce((memo, winId) => { + const window = windowStore.get(winId); + if (window) { + memo.push(window.API); + } + return memo; + }, []); + } + function getNeighboursByDirection(direction) { + const windowIds = _neighbours[direction]; + if (typeof windowIds !== "undefined") { + return mapWindowIdsToWindowObjects(windowIds); + } + } + function getApplicationName() { + var _a; + if (_applicationName) { + return _applicationName; + } + if (_context._APPLICATION_NAME) { + return _context._APPLICATION_NAME; + } + if (_context && _context._t42 && _context._t42.application) { + return _context._t42.application; + } + const info = getWindowInfo(); + if (info && info.applicationName) { + return info.applicationName; + } + const appManager = appManagerGetter(); + if (appManager) { + const instance = appManager.instances().find((i) => id === i.id); + if (instance) { + return (_a = instance.application) === null || _a === void 0 ? void 0 : _a.name; + } + } + return undefined; + } + function getWindowInfo() { + if (typeof window !== "undefined" && window.glue42gd && window.glue42gd.getWindowInfo) { + const info = window.glue42gd.getWindowInfo(id); + if (!info) { + return undefined; + } + else { + return info; + } + } + } + const resultWindow = { + get id() { + return _id; + }, + get name() { + return _name; + }, + get application() { + const appManager = appManagerGetter(); + const appName = getApplicationName(); + if (appName && appManager) { + return appManager.application(appName); + } + }, + get hostInstance() { + return executor.hostInstance; + }, + get interopInstance() { + const instance = agm.servers().find((s) => s.windowId === this.id); + if (instance) { + return instance; + } + else { + const appName = getApplicationName(); + if (appName) { + return { application: appName }; + } + } + }, + get agmInstance() { + return resultWindow.interopInstance; + }, + get url() { + return _url; + }, + get title() { + return _title; + }, + get windowStyleAttributes() { + return _settings; + }, + get settings() { + return _settings; + }, + get tabGroupId() { + return _mode.toLowerCase() === "tab" ? _tabGroupId : undefined; + }, + get tabIndex() { + return _mode.toLowerCase() === "tab" ? _tabIndex : undefined; + }, + get frameId() { + return _frameId; + }, + get frameButtons() { + return _frameButtons.sort((b1, b2) => b1.order - b2.order); + }, + get mode() { + return _mode; + }, + get state() { + return _windowState; + }, + get isCollapsed() { + return _isCollapsed; + }, + get isVisible() { + return _isVisible; + }, + get isLocked() { + return _isLocked; + }, + get context() { + return _context; + }, + get bounds() { + return _bounds; + }, + get minHeight() { + return _settings.minHeight; + }, + get maxHeight() { + return _settings.maxHeight; + }, + get minWidth() { + return _settings.minWidth; + }, + get maxWidth() { + return _settings.maxWidth; + }, + get isFocused() { + return _focus; + }, + get frameColor() { + return _frameColor; + }, + get opened() { + return resultWindow.id !== undefined; + }, + get group() { + return _group; + }, + get groupId() { + return _groupId; + }, + get isSticky() { + return _isSticky; + }, + get topNeighbours() { + return getNeighboursByDirection("top"); + }, + get leftNeighbours() { + return getNeighboursByDirection("left"); + }, + get rightNeighbours() { + return getNeighboursByDirection("right"); + }, + get bottomNeighbours() { + return getNeighboursByDirection("bottom"); + }, + get isGroupHeaderVisible() { + return _isGroupHeaderVisible; + }, + get activityId() { + if (_context._t42) { + return _context._t42.activityId; + } + const info = getWindowInfo(); + if (!info) { + return undefined; + } + return info.activityId; + }, + get activityWindowId() { + if (_context._t42) { + return _context._t42.activityWindowId; + } + const info = getWindowInfo(); + if (!info) { + return undefined; + } + return info.activityWindowId; + }, + get windowType() { + return options.windowType || "electron"; + }, + get zoomFactor() { + return _zoomFactor; + }, + get screen() { + if (typeof window !== "undefined" && window.glue42gd) { + return Utils.getMonitor(resultWindow.bounds, window.glue42gd.monitors); + } + return undefined; + }, + get placementSettings() { + return Object.assign({}, _placementSettings); + }, + get jumpList() { + return _jumpList; + }, + get allowWorkspaceDrop() { + return _allowWorkspaceDrop; + }, + get isPinned() { + return _isPinned; + }, + maximize, + restore, + minimize, + maximizeRestore, + collapse, + expand, + toggleCollapse, + focus, + activate, + moveResize, + setTitle, + setStyle, + setOnTop, + resetButtons, + getButtons, + setSizeConstraints, + getSizeConstraints, + navigate, + addFrameButton, + removeFrameButton, + setVisible, + show: () => setVisible(true), + hide: () => setVisible(false), + center, + close, + snap, + showLoader, + hideLoader, + updateContext, + lock, + unlock, + getIcon, + setIcon, + setFrameColor, + setTabTooltip, + getTabTooltip, + attachTab, + detachTab, + setTabHeaderVisible, + showPopup, + createFlydown, + setModalState, + setZoomFactor, + zoomIn, + zoomOut, + showDevTools, + capture, + flash, + flashTab, + setSticky, + setAllowWorkspaceDrop, + pin, + unpin, + print, + printToPDF, + place, + ungroup, + refresh, + goBack, + goForward, + download, + configure, + getConfiguration, + getDockingPlacement, + dock, + clone, + executeCode, + getChannel: async () => { + var _a; + const wins = await getChannels().getWindowsWithChannels({ windowIds: [_id] }); + return (_a = wins[0]) === null || _a === void 0 ? void 0 : _a.channel; + }, + startDrag, + showDialog, + onClose, + onUrlChanged, + onTitleChanged, + onFrameButtonAdded, + onFrameButtonRemoved, + onFrameButtonClicked, + onCollapsed, + onExpanded, + onMinimized, + onMaximized, + onNormal, + onAttached, + onDetached, + onVisibilityChanged, + onContextUpdated, + onLockingChanged, + onBoundsChanged, + onFrameColorChanged, + onFocusChanged, + onStickyChanged, + onGroupChanged, + onWindowAttached, + onWindowDetached, + onTabSelectionChanged, + onTabHeaderVisibilityChanged, + onClosing, + onRefreshing, + onZoomFactorChanged, + onPlacementSettingsChanged, + onNeighboursChanged, + onDockingChanged, + onNavigating, + onChannelRestrictionsChanged, + get tabs() { + return getAllTabs(); + }, + get isTabHeaderVisible() { + return _isTabHeaderVisible; + }, + get isTabSelected() { + return _isTabSelected; + }, + getURL() { + return Promise.resolve(_url); + }, + getTitle() { + return Promise.resolve(_title); + }, + getBounds() { + return Promise.resolve(_bounds); + }, + getContext() { + return Promise.resolve(_context); + }, + setContext(context) { + if (!isObject(context)) { + throw new Error(`"context" must not be null or undefined, set to empty object if you want to clear it out.`); + } + return executor.updateContext(resultWindow, context, true); + }, + getDisplay() { + const displayAPI = displayAPIGetter(); + return displayAPI.getByWindowId(id); + }, + resizeTo(width, height) { + return moveResize({ width, height }); + }, + moveTo(top, left) { + return moveResize({ top, left }); + }, + async getParentWindow() { + var _a; + const myParentId = _settings.parentInstanceId; + if (!myParentId) { + return undefined; + } + return (_a = windowStore.list[myParentId]) === null || _a === void 0 ? void 0 : _a.API; + }, + async getChildWindows() { + return Object.keys(windowStore.list) + .map((key) => windowStore.list[key].API) + .filter((w) => { + const parentId = w.settings.parentInstanceId; + return parentId === id; + }); + }, + joinChannel: (name) => { + return getChannels().join(name, id); + }, + leaveChannel: () => { + return getChannels().leave(id); + } + }; + const events = { + handleUpdate, + handleWindowClose, + handleWindowChangeState, + handleTitleChanged, + handleVisibilityChanged, + handleUrlChanged, + handleWindowSettingsChanged, + handleContextUpdated, + handleFrameIsLockedChanged, + handleBoundsChanged, + handleFocusChanged, + handleFrameButtonAdded, + handleFrameButtonRemoved, + handleFrameButtonClicked, + handleFrameColorChanged, + handleFrameAttached, + handleFrameSelectionChanged, + handleCompositionChanged, + handleAllowWorkspaceDropChanged, + handleIsPinnedChanged, + handleGroupHeaderVisibilityChanged, + handleTabHeaderVisibilityChanged, + handleGroupChanged, + handleAttached, + handleDetached, + handleWindowAttached, + handleWindowDetached, + handleZoomFactorChanged, + handleIsStickyChanged, + handlePlacementSettingsChanged, + handleDockingChanged, + handleChannelRestrictionsChanged + }; + const groupArgs = { + get isGroupHibernated() { + return _isGroupHibernated; + }, + get isGroupVisible() { + return _isGroupVisible; + }, + }; + return { + API: resultWindow, + Events: events, + GroupCreationArgs: groupArgs + }; + }; + + function getWindowsByTabGroupId(windowId, tabGroupId) { + const windows = windowStore.list; + return Object.keys(windows).reduce((memo, id) => { + const win = windows[id]; + if (win.API.tabGroupId === tabGroupId && win.API.id !== windowId) { + memo.push(win); + } + return memo; + }, []); + } + function isEmpty(object) { + if (!object || Object.keys(object).every((value) => object[value] === undefined)) { + return true; + } + return false; + } + + class GDExecutor { + constructor() { + this.GroupMethodName = "T42.Group.Execute"; + this.WndMethodName = "T42.Wnd.Execute"; + this._registry = CallbackRegistryFactory(); + this._finished = Promise.resolve(); + this._configuration = { + windowAvailableOnURLChanged: true + }; + this.unsubCallbacks = {}; + } + get hostInstance() { + return this.agmTarget; + } + get finished() { + return this._finished; + } + get configuration() { + return this._configuration; + } + init(agm, instance) { + this.agm = agm; + this.agmTarget = instance; + this._registry.add("event", (data) => { + if (data.type === "Closed") { + const keys = Object.keys(this.unsubCallbacks); + keys.forEach((key) => { + const isSameWindow = key.startsWith(data.windowId); + if (isSameWindow) { + delete this.unsubCallbacks[key]; + } + }); + } + }); + } + setConfiguration(config) { + this._configuration = { ...this._configuration, ...config }; + } + handleEvent(data) { + this._registry.execute("event", data); + } + async open(options) { + let finishedResolve; + this._finished = new Promise((resolve) => { + finishedResolve = resolve; + }); + try { + const result = await this.agm.invoke("T42.Wnd.Create", options, this.agmTarget, { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_RESPONSE_TIMEOUT_MS + }); + if (result.returned === undefined) { + throw new Error("failed to execute T42.Wnd.Create - unknown reason"); + } + const id = result.returned.id; + const win = await windowStore.waitFor(id); + if (!this.configuration || this.configuration.windowAvailableOnURLChanged) { + setTimeout(() => { + if (win.API.windowType === "electron") { + win.Events.handleUrlChanged(win.API.url); + } + }, 0); + } + return win.API; + } + finally { + finishedResolve(); + } + } + async close(w, options) { + const result = await this.execute("close", { windowId: w.id, options }, `Closed`); + if (options) { + return result.closed; + } + return w; + } + async navigate(w, newUrl, urlLoadOptions) { + let methodResponseTimeoutMs = 120000; + if (typeof urlLoadOptions === "object" && typeof urlLoadOptions.timeout === "number") { + methodResponseTimeoutMs = urlLoadOptions.timeout * 1000; + delete urlLoadOptions.timeout; + } + await this.execute("navigate", { windowId: w.id, options: { url: newUrl, urlLoadOptions }, invocationOptions: { methodResponseTimeoutMs } }, "UrlChanged"); + return w; + } + async setStyle(w, style) { + var _a; + const stylePromises = []; + const wait = (promise) => stylePromises.push(promise); + if (!isUndefinedOrNull(style.focus) && !w.isFocused) { + wait(w.focus()); + } + if (!isUndefinedOrNull(style.hidden)) { + const toBeVisible = !style.hidden; + wait(w.setVisible(toBeVisible)); + } + if (!isUndefinedOrNull(style.onTop)) { + wait(w.setOnTop(style.onTop)); + } + if (!isNullOrWhiteSpace(style.tabTooltip) || !isNullOrWhiteSpace(style.tabToolTip)) { + const toolTip = (_a = style.tabTooltip) !== null && _a !== void 0 ? _a : style.tabToolTip; + wait(w.setTabTooltip(toolTip)); + } + if (!isNullOrWhiteSpace(style.tabTitle)) { + wait(this.execute("setTabTitle", { windowId: w.id, options: { tabTitle: style.tabTitle } })); + } + const constraints = { + minHeight: style.minHeight, + minWidth: style.minWidth, + maxHeight: style.maxHeight, + maxWidth: style.maxWidth, + }; + const hasConstraints = !isEmpty(constraints); + if (hasConstraints) { + wait(w.setSizeConstraints(constraints)); + } + const buttons = { + allowClose: style.allowClose, + allowCollapse: style.allowCollapse, + allowLockUnlock: style.allowLockUnlock, + allowMaximize: style.allowMaximize, + allowMinimize: style.allowMinimize + }; + const hasButtons = !isEmpty(buttons); + if (hasButtons) { + wait(w.resetButtons(buttons)); + } + await Promise.all(stylePromises); + return w; + } + async setSizeConstraints(w, constraints) { + await this.execute("setSizeConstraints", { windowId: w.id, options: constraints }); + return w; + } + async getSizeConstraints(w) { + const sizeConstraint = await this.execute("getSizeConstraints", { windowId: w.id }); + return sizeConstraint; + } + async setTabTooltip(w, tabTooltip) { + await this.execute("setTabTooltip", { windowId: w.id, options: { tabTooltip } }); + return w; + } + async getTabTooltip(w) { + const result = await this.execute("getTabTooltip", { windowId: w.id }); + return result.tabTooltip; + } + async resetButtons(w, buttonsConfig) { + await this.execute("resetButtons", { windowId: w.id, options: buttonsConfig }); + return w; + } + async getButtons(w) { + const buttons = await this.execute("getButtons", { windowId: w.id }); + return buttons; + } + async setOnTop(w, onTop) { + await this.execute("setOnTop", { windowId: w.id, options: { onTop } }); + return w; + } + async setTitle(w, newTitle) { + const options = { + windowId: w.id, + options: { + title: newTitle + } + }; + await this.execute("setTitle", options, "TitleChanged"); + return w; + } + async setSticky(w, isSticky) { + const options = { + windowId: w.id, + options: { + isSticky + } + }; + await this.execute("setSticky", options); + return w; + } + async setAllowWorkspaceDrop(w, allowWorkspaceDrop) { + const options = { + windowId: w.id, + options: { + allowWorkspaceDrop + } + }; + await this.execute("setAllowWorkspaceDrop", options); + return w; + } + async pin(windowToPin) { + const options = { + windowId: windowToPin.id + }; + await this.execute("pinTab", options); + return windowToPin; + } + async unpin(pinnedWindow) { + const options = { + windowId: pinnedWindow.id + }; + await this.execute("unpinTab", options); + return pinnedWindow; + } + async moveResize(w, bounds) { + if (typeof window !== "undefined" && window.glueDesktop.versionNum < 31200) { + return new Promise(async (res, rej) => { + const resolveImmediately = this.areBoundsEqual(bounds, w); + let isDone = false; + const done = () => { + if (isDone) { + return; + } + isDone = true; + if (unsubscribeBoundsChanged) { + unsubscribeBoundsChanged(); + unsubscribeBoundsChanged = undefined; + } + res(w); + if (resolveTimeout) { + clearTimeout(resolveTimeout); + resolveTimeout = undefined; + } + }; + let resolveTimeout; + let unsubscribeBoundsChanged; + if (!resolveImmediately) { + unsubscribeBoundsChanged = w.onBoundsChanged((win) => { + if (!this.areBoundsEqual(bounds, win)) { + return; + } + done(); + }); + } + try { + await this.execute("moveResize", { windowId: w.id, options: { bounds } }); + } + catch (error) { + rej(error); + return; + } + if (resolveImmediately) { + done(); + return; + } + resolveTimeout = setTimeout(() => { + done(); + }, 1000); + }); + } + else { + await this.execute("moveResize", { windowId: w.id, options: { bounds } }); + } + return w; + } + async addFrameButton(w, buttonInfo) { + await this.execute("addButton", { windowId: w.id, options: buttonInfo }, "ButtonAdded"); + return w; + } + async removeFrameButton(w, buttonId) { + await this.execute("removeButton", { windowId: w.id, options: buttonId }, "ButtonRemoved"); + return w; + } + async activate(w) { + await this.execute("activate", { windowId: w.id }); + return w; + } + async focus(w) { + await this.execute("focus", { windowId: w.id }); + return w; + } + async maximizeRestore(w) { + await this.execute("maximizeRestore", { windowId: w.id }, "StateChanged"); + return w; + } + async maximize(w) { + await this.execute("maximize", { windowId: w.id }, "StateChanged"); + return w; + } + async restore(w) { + await this.execute("restore", { windowId: w.id }, "StateChanged"); + return w; + } + async minimize(w) { + await this.execute("minimize", { windowId: w.id }, "StateChanged"); + return w; + } + async collapse(w) { + await this.execute("collapse", { windowId: w.id }, "StateChanged"); + return w; + } + async expand(w) { + await this.execute("expand", { windowId: w.id }, "StateChanged"); + return w; + } + async toggleCollapse(w) { + await this.execute("toggleCollapse", { windowId: w.id }, "StateChanged"); + return w; + } + async snap(w, targetWindow, options) { + const args = { + targetWindowId: targetWindow.id + }; + args.snappingEdge = options.direction; + args.autoAlign = options.autoAlign; + await this.execute("snap", { windowId: w.id, options: args }, "CompositionChanged", `CompositionChanged-${targetWindow.id}`); + return w; + } + async attachTab(w, sourceWindow, options) { + await this.execute("attachTab", { + windowId: w.id, + options: { + index: options, + sourceWindowId: sourceWindow.id, + targetWindowId: w.id, + } + }, `WindowFrameAdded-${sourceWindow.id}`, `WindowFrameRemoved-${sourceWindow.id}`); + return w; + } + async detachTab(w, options) { + const eventKeys = ["WindowFrameRemoved", `WindowFrameAdded`]; + if (!isUndefinedOrNull(options === null || options === void 0 ? void 0 : options.relativeTo)) { + eventKeys.push(`CompositionChanged`); + eventKeys.push(`CompositionChanged-${options.relativeTo}`); + } + else { + eventKeys.push("BoundsChanged"); + } + await this.execute("detachTab", { windowId: w.id, options }, ...eventKeys); + return w; + } + async setVisible(w, toBeVisible = true) { + let command; + if (toBeVisible) { + command = "show"; + } + else { + command = "hide"; + } + await this.execute(command, { windowId: w.id }, "VisibilityChanged"); + return w; + } + async center(w, display) { + await this.execute("center", { windowId: w.id, options: display }); + return w; + } + async showLoader(w, loader) { + await this.execute("showLoadingAnimation", { windowId: w.id, options: loader }); + return w; + } + async hideLoader(w) { + await this.execute("hideLoadingAnimation", { windowId: w.id }); + return w; + } + async updateContext(w, context, replace) { + let un; + try { + const contextWithoutUndefinedValues = this.swapUndefinedToNull(context); + const done = new Promise((resolve, reject) => { + un = w.onContextUpdated(() => { + resolve(); + }); + }); + await Promise.all([this.execute("updateContext", { + windowId: w.id, context: contextWithoutUndefinedValues, replace + }), done]); + return w; + } + finally { + if (un) { + un(); + } + } + } + async lock(w) { + await this.execute("lockUnlock", { windowId: w.id, options: { lock: true } }, "FrameIsLockedChanged"); + return w; + } + async unlock(w) { + await this.execute("lockUnlock", { windowId: w.id, options: { lock: false } }, "FrameIsLockedChanged"); + return w; + } + async getIcon(w) { + const result = await this.execute("getIcon", { + windowId: w.id, + options: {} + }); + return result.icon; + } + async setIcon(w, base64Image) { + await this.execute("setIcon", { + windowId: w.id, + options: { + dataURL: base64Image + } + }); + return w; + } + async setFrameColor(w, frameColor) { + await this.execute("setFrameColor", { windowId: w.id, options: { frameColor } }, "FrameColorChanged"); + return w; + } + async setTabHeaderVisible(w, toBeTabHeaderVisible) { + await this.execute("setTabHeaderVisible", { + windowId: w.id, + options: { + toShow: toBeTabHeaderVisible + } + }, "TabHeaderVisibilityChanged"); + return w; + } + async showGroupPopup(id, options) { + const reformatedOptions = this.showPopupCore(id, options); + await this.executeGroup("showGroupPopup", { + groupId: id, + options: reformatedOptions + }); + } + async showPopup(targetWindow, options) { + const reformatedOptions = this.showPopupCore(targetWindow.id, options); + await this.execute("showPopupWindow", { + windowId: targetWindow.id, + options: reformatedOptions + }); + return targetWindow; + } + async createFlydown(windowId, options) { + if (!options) { + throw new Error("The options object is not valid!"); + } + const optionsCopy = { ...options }; + if (!optionsCopy.horizontalOffset) { + optionsCopy.horizontalOffset = 0; + } + if (!optionsCopy.verticalOffset) { + optionsCopy.verticalOffset = 0; + } + const fullOptions = this.reformatFlydownOptions(windowId, optionsCopy); + return this.execute("setFlydownArea", { windowId, options: fullOptions }).then(() => { + const zoneIds = fullOptions.zones.map((z) => z.id); + fullOptions.zones.forEach((z) => { + let callback = typeof (z.flydownSize) === "function" ? + z.flydownSize : () => z.flydownSize; + if (options.size instanceof Function && z.flydownSize) { + callback = async (data, cancel) => { + let result; + if (options.size instanceof Function) { + result = await options.size(data, cancel); + } + if (z.flydownSize instanceof Function && z.flydownSize !== options.size) { + return await z.flydownSize(data, cancel) || result; + } + return result || z.flydownSize; + }; + } + this._registry.clearKey(`${fullOptions.targetId}_${z.id}`); + this._registry.add(`${fullOptions.targetId}_${z.id}`, callback); + }); + return { + destroy: () => this.clearFlydownArea(fullOptions.targetId, zoneIds), + options: optionsCopy + }; + }); + } + async setModalState(windowId, isModal) { + return this.execute("setModalState", { windowId, options: { isModal } }); + } + async autoArrange(displayId) { + return this.execute("autoArrange", { options: { displayId } }); + } + async handleFlydownBoundsRequested(targetId, data) { + const cancelCallback = () => data.cancel = true; + const callbackData = { + zoneId: data.flydownId, + flydownWindowBounds: data.flydownWindowBounds, + flydownWindowId: data.flydownWindowId, + }; + const responses = await Promise.all(this._registry.execute(`${targetId}_${data.flydownId}`, callbackData, cancelCallback)); + if (responses.length === 1) { + const defaultResponse = { height: 0, width: 0, top: 0, left: 0 }; + const response = typeof (responses[0]) === "object" && !Array.isArray(responses[0]) ? responses[0] : defaultResponse; + const responseOptions = { ...data, flydownWindowBounds: response }; + return responseOptions; + } + } + async handleOnEventRequested(callbackId, args) { + var _a; + const callbacks = (_a = this.unsubCallbacks[callbackId]) !== null && _a !== void 0 ? _a : []; + let prevented = false; + const preventArgs = []; + await Promise.all(callbacks.map((cb) => { + return new Promise((resolve, reject) => { + cb(() => { + resolve(); + }, () => { + reject(); + }, (pArgs) => { + prevented = true; + preventArgs.push(pArgs); + }, args); + }); + })); + return { prevented, preventArgs }; + } + async zoomIn(window) { + await this.execute("zoomIn", { + windowId: window.id, + }); + return window; + } + async zoomOut(window) { + await this.execute("zoomOut", { + windowId: window.id, + }); + return window; + } + async setZoomFactor(window, zoomFactor) { + await this.execute("setZoomFactor", { + windowId: window.id, + options: { + zoomFactor + } + }); + return window; + } + async showDevTools(window) { + await this.execute("showDevTools", { + windowId: window.id, + }); + return window; + } + async capture(window, options) { + const base64screenshot = (await this.execute("captureScreenshot", { windowId: window.id, options: { ...options } })).data; + return base64screenshot; + } + async captureGroup(windowIds, options) { + const base64screenshot = (await this.execute("captureGroupScreenshot", { windowId: windowIds[0], options: { groupWindowIds: windowIds, ...options } })).data; + return base64screenshot; + } + async flash(resultWindow, options) { + await this.execute("flash", { windowId: resultWindow.id, options: { ...options } }); + return resultWindow; + } + async flashTab(resultWindow, options) { + await this.execute("flashTab", { windowId: resultWindow.id, options: { ...options } }); + return resultWindow; + } + async configure(windowId, options) { + return this.execute("configure", { windowId, options: { ...options } }); + } + async print(resultWindow, options) { + await this.execute("print", { windowId: resultWindow.id, options: { ...options } }); + return resultWindow; + } + async printToPDF(resultWindow, options) { + const filePath = (await this.execute("printToPDF", { windowId: resultWindow.id, options: { ...options } })).filePath; + return filePath; + } + async place(window, options) { + const copy = { ...options }; + if (!options.display || options.display === "current") { + copy.display = await window.getDisplay(); + } + if (copy.display && typeof copy.display !== "string" && typeof copy.display !== "number") { + copy.display = copy.display.index + 1; + } + return this.execute("place", { windowId: window.id, options: { ...copy } }); + } + async refresh(resultWindow, ignoreCache) { + await this.execute("refresh", { windowId: resultWindow.id, options: { ignoreCache } }); + return resultWindow; + } + async download(resultWindow, url, options = {}) { + options.enableDownloadBar = !options.silent; + const result = await this.execute("downloadURL", { windowId: resultWindow.id, options: { url, options } }); + return { + url, + path: result.fullPath, + size: result.fileSize, + }; + } + async configureWindow(resultWindow, options) { + await this.execute("configureWindow", { windowId: resultWindow.id, options }); + return resultWindow; + } + async getWindowConfiguration(resultWindow) { + const config = await this.execute("getWindowConfiguration", { windowId: resultWindow.id }); + return config; + } + async startDrag(resultWindow, options) { + await this.execute("startDrag", { windowId: resultWindow.id, options }); + return resultWindow; + } + showDialog(resultWindow, options) { + return new Promise((res, rej) => { + const token = Utils.generateId(); + const un = this._registry.add("event", (args) => { + if (args.type === "DialogResult" && args.windowId === resultWindow.id && args.data.token === token) { + un(); + const data = args.data; + if ("status" in data) { + if (data.status === "failed") { + rej(new Error(data.message)); + } + else if (data.status === "successful") { + res(data.result); + } + } + } + }); + this.execute("showDialog", { windowId: resultWindow.id, options: Object.assign({}, { ...options }, { token }) }); + }); + } + async execute(command, options, ...eventKeys) { + return this.executeCore(this.WndMethodName, command, options, ...eventKeys); + } + async executeGroup(command, options, ...eventKeys) { + return this.executeCore(this.GroupMethodName, command, options, ...eventKeys); + } + async ungroup(w, options) { + const args = { + windowId: w.id, + options + }; + await this.execute("ungroup", args); + return w; + } + async updateJumpList(windowId, options) { + const args = { + windowId, + options + }; + await this.execute("updateJumplist", args); + } + async getJumpList(windowId) { + const args = { + windowId, + }; + const result = await this.execute("getJumplist", args); + return result; + } + onClosing(callback, gdWindow) { + const glue42gd = typeof window !== "undefined" && window.glue42gd; + if (glue42gd && gdWindow.windowType === "electron") { + return glue42gd.addCloseHandler(callback, gdWindow.id); + } + else { + return this.nonWindowHandlers(callback, gdWindow.id, "OnClosing"); + } + } + onGroupClosing(callback, group) { + return this.nonWindowHandlersCore(group.id, "OnClosing", true, callback); + } + onRefreshing(callback, gdWindow) { + const glue42gd = typeof window !== "undefined" && window.glue42gd; + if (glue42gd && gdWindow.windowType === "electron") { + return glue42gd.addRefreshHandler(callback, gdWindow.id); + } + else { + return this.nonWindowHandlers(callback, gdWindow.id, "OnRefreshing"); + } + } + onNavigating(callback, gdWindow) { + const glue42gd = typeof window !== "undefined" && window.glue42gd; + if (glue42gd && gdWindow.windowType === "electron") { + return glue42gd.addWillNavigateHandler(callback, gdWindow.id); + } + else { + return this.nonWindowHandlers(callback, gdWindow.id, "OnNavigating"); + } + } + async clone(window, cloneOptions) { + const args = { + windowId: window.id, + options: cloneOptions + }; + const result = await this.execute("clone", args); + const win = await windowStore.waitFor(result.id); + return win.API; + } + async executeCode(targetWindow, code) { + const args = { + windowId: targetWindow.id, + options: { + code + } + }; + return this.execute("executeCode", args); + } + async goBack(resultWindow) { + await this.execute("goBack", { windowId: resultWindow.id }); + } + async goForward(resultWindow) { + await this.execute("goForward", { windowId: resultWindow.id }); + } + async getDockingPlacement(window) { + return this.execute("getDockingPlacement", { windowId: window.id }); + } + dock(window, options) { + return this.execute("dock", { windowId: window.id, options }); + } + clearCallbacks(id) { + const keys = Object.keys(this.unsubCallbacks); + keys.forEach((key) => { + if (key.startsWith(id)) { + delete this.unsubCallbacks[key]; + } + }); + } + nonWindowHandlers(callback, targetId, type) { + return this.nonWindowHandlersCore(targetId, type, false, callback); + } + nonWindowHandlersCore(targetId, type, isGroup, callback) { + const id = `${targetId}-${type}`; + const unsub = () => { + var _a; + if (this.unsubCallbacks[id]) { + const callbacks = this.unsubCallbacks[id]; + this.unsubCallbacks[id] = callbacks.filter((cb) => cb !== callback); + if (this.unsubCallbacks[id].length === 0) { + delete this.unsubCallbacks[id]; + } + } + const cbs = (_a = this.unsubCallbacks[id]) !== null && _a !== void 0 ? _a : []; + if (cbs.length === 0) { + const options = { + unsubscribe: true + }; + if (isGroup) { + this.executeGroup(type, { + groupId: targetId, + options + }); + } + else { + this.execute(type, { + windowId: targetId, + options + }); + } + } + }; + if (this.unsubCallbacks[id]) { + this.unsubCallbacks[id].push(callback); + return unsub; + } + else { + this.unsubCallbacks[id] = [callback]; + } + if (isGroup) { + this.executeGroup(type, { groupId: targetId }); + } + else { + this.execute(type, { windowId: targetId }); + } + return unsub; + } + reformatFlydownOptions(windowId, options) { + const assignGeneralIfUnassigned = (zone, prop) => { + if (options[prop] && (zone[prop] === undefined || zone[prop] === null)) { + const valueFromOptions = options[prop]; + zone[prop] = valueFromOptions; + } + }; + const zones = options.zones.map((z) => { + assignGeneralIfUnassigned(z, "windowId"); + assignGeneralIfUnassigned(z, "targetLocation"); + if (options.size && (z.flydownSize === undefined || z.flydownSize === null)) { + z.flydownSize = options.size; + } + z.flydownBounds = z.flydownSize; + z.flydownId = z.windowId; + if (!z.targetLocation) { + z.targetLocation = "bottom"; + } + return z; + }); + return { + ...options, + zones, + targetId: windowId, + flydownBounds: options.size, + flydownActiveArea: options.activeArea + }; + } + clearFlydownArea(windowId, areaIds) { + return this.execute("clearFlydownWindowArea", { + windowId, + options: {} + }).then(() => { + areaIds.forEach((id) => { + this._registry.clearKey(`${windowId}_${id}`); + }); + }); + } + executeWithoutToken(params, ...eventKeys) { + const uns = []; + const executed = eventKeys === null || eventKeys === void 0 ? void 0 : eventKeys.filter((k) => !isUndefinedOrNull(k)).map((key) => { + return new Promise((r) => { + const [type, windowId = params.windowId] = key.split("-"); + uns.push(this._registry.add("event", (data) => { + if (data.type === type && data.windowId === windowId) { + r(); + } + })); + }); + }); + const action = new Promise((resolve, reject) => { + this.agm.invoke("T42.Wnd.Execute", params, this.agmTarget, { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_RESPONSE_TIMEOUT_MS + }) + .then((i) => { + if (i.returned && i.returned.errorMsg) { + reject(i); + } + else { + resolve(i.returned); + } + }) + .catch((e) => reject(e)); + }); + return Promise.all([action, ...executed]) + .then((r) => { + return r[0]; + }) + .finally(() => { + uns.forEach((un) => un()); + }); + } + async executeCore(methodName, command, options, ...eventKeys) { + const { invocationOptions, ...invocationArgs } = options; + const params = { + ...invocationArgs, + command, + }; + let finishedResolve; + this._finished = new Promise((resolve) => { + finishedResolve = resolve; + }); + try { + if (typeof window !== "undefined" && window.glueDesktop.versionNum < 31200) { + return await this.executeWithoutToken(params, ...eventKeys); + } + else { + return await this.executeWithToken(methodName, params, invocationOptions); + } + } + finally { + finishedResolve(); + } + } + async executeWithToken(methodName, options, invocationOptions) { + let un; + try { + const token = Utils.generateId(); + const event = new Promise((r) => { + un = this._registry.add("event", (data) => { + if (data.token === token) { + r(); + } + }); + }); + const execute = new Promise((resolve, reject) => { + options.token = token; + if (!invocationOptions) { + invocationOptions = { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_RESPONSE_TIMEOUT_MS + }; + } + else if (!invocationOptions.methodResponseTimeoutMs) { + invocationOptions.methodResponseTimeoutMs = INTEROP_METHOD_RESPONSE_TIMEOUT_MS; + } + else if (!invocationOptions.waitTimeoutMs) { + invocationOptions.waitTimeoutMs = INTEROP_METHOD_WAIT_TIMEOUT_MS; + } + this.agm.invoke(methodName, options, this.agmTarget, invocationOptions) + .then((i) => { + if (i.returned && i.returned.errorMsg) { + reject(new Error(i.returned.errorMsg)); + } + else { + resolve(i.returned); + } + }) + .catch((e) => { + const error = Utils.typedError(e); + reject(error); + }); + }); + const result = await Promise.all([execute, event]); + return result[0]; + } + finally { + if (un) { + un(); + } + } + } + areBoundsEqual(requested, w) { + const current = w.bounds; + const settings = w.settings; + let height = requested.height; + let width = requested.width; + if (requested.height < settings.minHeight) { + height = settings.minHeight; + } + if (requested.height > settings.maxHeight) { + height = settings.maxHeight; + } + if (requested.width < settings.minWidth) { + width = settings.minWidth; + } + if (requested.width > settings.maxWidth) { + width = settings.maxWidth; + } + const areHeightsEqual = height ? current.height === height : true; + const areWidthsEqual = width ? current.width === width : true; + const areLeftsEqual = requested.left ? current.left === requested.left : true; + const areTopsEqual = requested.top ? current.top === requested.top : true; + return areHeightsEqual && areWidthsEqual && areLeftsEqual && areTopsEqual; + } + swapUndefinedToNull(context) { + try { + const copy = {}; + for (const key of Object.keys(context)) { + let value = context[key]; + if (typeof value === "undefined") { + value = null; + } + copy[key] = value; + } + return copy; + } + catch { + return context; + } + } + showPopupCore(id, options) { + if (!options) { + throw new Error("The options object is not valid!"); + } + const optionsCopy = { ...options }; + if (!optionsCopy.targetLocation) { + optionsCopy.targetLocation = "bottom"; + } + const reformatedOptions = { + ...optionsCopy, + popupBounds: optionsCopy.size, + targetId: id, + popupId: optionsCopy.windowId + }; + return reformatedOptions; + } + } + var executor = new GDExecutor(); + + class GDEnvironment { + constructor(agm, logger, appManagerGetter, displayAPIGetter, channelsAPIGetter, wndId, groupId) { + this._registry = CallbackRegistryFactory(); + this._agm = agm; + this._logger = logger.subLogger("gd-env"); + this._windowId = wndId; + this._groupId = groupId; + this._appManagerGetter = appManagerGetter; + this._displayAPIGetter = displayAPIGetter; + this._channelsAPIGetter = channelsAPIGetter; + } + init() { + return new Promise((resolve, reject) => { + this._agm.register("T42.Wnd.OnEventWithResponse", (args, caller) => { + return this.respondToEvent(args); + }); + new Promise((streamResolve, streamReject) => { + this._agm.subscribe("T42.Wnd.OnEvent", { + target: "best", + arguments: { + withConfig: true + }, + onData: (streamData) => { + if (streamData.data.type === "Configuration") { + this._configuration = streamData.data; + executor.setConfiguration(this._configuration); + return; + } + this.updateWindow(streamData.data, resolve); + executor.handleEvent(streamData.data); + }, + onConnected: (instance) => { + this._agmInstance = instance; + executor.init(this._agm, this._agmInstance); + } + }).catch((error) => { + var _a; + const message = `${(_a = error === null || error === void 0 ? void 0 : error.method) === null || _a === void 0 ? void 0 : _a.name} - ${JSON.stringify(error === null || error === void 0 ? void 0 : error.called_with)} - ${error === null || error === void 0 ? void 0 : error.message}`; + reject(new Error(message)); + }); + }); + }); + } + get executor() { + return executor; + } + open(name, url, options) { + options = options || {}; + const copyOptions = { ...options }; + if (copyOptions.relativeTo !== undefined && typeof copyOptions.relativeTo !== "string") { + copyOptions.relativeTo = copyOptions.relativeTo.id || ""; + } + copyOptions.name = name; + copyOptions.url = url; + copyOptions.windowState = options.windowState || options.state; + delete copyOptions.state; + return this.executor.open(copyOptions); + } + createFlydown(windowId, options) { + return this.executor.createFlydown(windowId, options); + } + async showPopup(windowId, options) { + const window = windowStore.get(windowId); + await this.executor.showPopup(window.API, options); + } + tabAttached(callback) { + return this._registry.add("tab-attached", callback); + } + tabDetached(callback) { + return this._registry.add("tab-detached", callback); + } + onWindowFrameColorChanged(callback) { + return this._registry.add("frame-color-changed", callback); + } + onEvent(callback) { + return this._registry.add("window-event", callback); + } + my() { + return this._windowId; + } + myGroup() { + return this._groupId; + } + onCompositionChanged(callback) { + return this._registry.add("composition-changed", callback); + } + onGroupHeaderVisibilityChanged(callback) { + return this._registry.add("group-header-changed", callback); + } + onGroupVisibilityChanged(callback) { + return this._registry.add("group-visibility-changed", callback); + } + onGroupStateChanged(callback) { + return this._registry.add("group-state-changed", callback); + } + onWindowGotFocus(callback) { + return this._registry.add("got-focus", callback); + } + onWindowLostFocus(callback) { + return this._registry.add("lost-focus", callback); + } + onWindowsAutoArrangeChanged(callback) { + return this._registry.add("windows-auto-arranged-changed", callback); + } + respondToEvent(args) { + if (args.type === "ShowFlydownBoundsRequested") { + return this.executor.handleFlydownBoundsRequested(args.data.windowId, args.data); + } + else if (args.type === "OnClosing" || args.type === "OnRefreshing" || args.type === "OnNavigating") { + return this.executor.handleOnEventRequested(args.data.callbackId, args.data.args); + } + return Promise.reject(`There isn't a handler for ${args.type}`); + } + updateWindow(windowInfo, readyResolve) { + const extendedStreamEvent = this.getExtendedStreamEvent(windowInfo); + if (windowInfo.type === "Snapshot") { + const windowInfoFullInfoEvent = windowInfo; + windowInfoFullInfoEvent.windows.forEach((w) => { + const existingWindow = windowStore.get(w.id); + if (existingWindow) { + existingWindow.Events.handleUpdate(this.mapToWindowConstructorOptions(w)); + existingWindow.GroupCreationArgs = this.mapToGroupCreationArgs(w); + } + else { + this.createWindowFromSnapshot(w.id, w); + } + this._registry.execute("window-event", extendedStreamEvent); + }); + readyResolve(this); + return; + } + if (windowInfo.type === "CommandExecuted") { + this._registry.execute("window-event", extendedStreamEvent); + return; + } + if (windowInfo.type === "Created") { + const windowInfoCreatedEvent = (windowInfo); + this.createWindowFromStream(windowInfoCreatedEvent.windowId, windowInfoCreatedEvent.data || {}); + this._registry.execute("window-event", extendedStreamEvent); + return; + } + if (windowInfo.type === "OnGroupVisibilityChanged") { + const info = windowInfo; + this._registry.execute("group-visibility-changed", info.data); + this._registry.execute("window-event", windowInfo); + return; + } + if (windowInfo.type === "OnGroupStateChanged") { + const info = windowInfo; + this._registry.execute("group-state-changed", info.data); + this._registry.execute("window-event", windowInfo); + return; + } + if (windowInfo.type === "OnWindowsAutoArrangeChanged") { + const info = windowInfo; + this._registry.execute("windows-auto-arranged-changed", info.data); + this._registry.execute("window-event", windowInfo); + return; + } + const windowObjectAndEvents = windowStore.get((windowInfo).windowId); + if (!windowObjectAndEvents) { + this._logger.error(`received update for unknown window. Stream:', ${JSON.stringify(windowInfo, null, 4)}`); + return; + } + const theWindow = windowObjectAndEvents.API; + const theWindowEvents = windowObjectAndEvents.Events; + if (windowInfo.type === "BoundsChanged") { + const windowInfoBoundsChangedEvent = windowInfo; + theWindowEvents.handleBoundsChanged(windowInfoBoundsChangedEvent.data); + } + if (windowInfo.type === "UrlChanged") { + const windowInfoUrlChangedEvent = windowInfo; + windowStore.setUrlChangedState(windowInfoUrlChangedEvent.windowId); + theWindowEvents.handleUrlChanged(windowInfoUrlChangedEvent.data); + } + if (windowInfo.type === "TitleChanged") { + const windowInfoTitleChanged = windowInfo; + theWindowEvents.handleTitleChanged(windowInfoTitleChanged.data); + } + if (windowInfo.type === "IsStickyChanged") { + const windowInfoIsStickyChangedChanged = windowInfo; + theWindowEvents.handleIsStickyChanged(windowInfoIsStickyChangedChanged.data); + } + if (windowInfo.type === "VisibilityChanged") { + theWindowEvents.handleVisibilityChanged(windowInfo.data); + } + if (windowInfo.type === "ContextChanged") { + theWindowEvents.handleContextUpdated(windowInfo.data); + } + if (windowInfo.type === "StateChanged") { + theWindowEvents.handleWindowChangeState(windowInfo.data); + } + if (windowInfo.type === "FrameColorChanged") { + theWindowEvents.handleFrameColorChanged(windowInfo.data); + this._registry.execute("frame-color-changed", theWindow); + } + if (windowInfo.type === "CompositionChanged") { + const windowInfoCompositionChanged = windowInfo; + theWindowEvents.handleCompositionChanged(windowInfoCompositionChanged.data); + windowStore.setCompositionChangedState(windowObjectAndEvents); + this._registry.execute("composition-changed", windowInfoCompositionChanged.data); + } + if (windowInfo.type === "GroupHeaderVisibilityChanged") { + const info = windowInfo; + theWindowEvents.handleGroupHeaderVisibilityChanged(info.data.groupHeaderVisible); + this._registry.execute("group-header-changed", info.data); + } + if (windowInfo.type === "FocusChanged") { + const windowInfoFocusChanged = windowInfo; + this.focusChanged(theWindowEvents, theWindow, windowInfoFocusChanged.data); + } + if (windowInfo.type === "WindowFrameChanged") { + theWindowEvents.handleFrameAttached(windowInfo.data.frameId, windowInfo.data.frameId, windowInfo.data.isTabHeaderVisible); + this._registry.execute("frame-changed"); + } + if (windowInfo.type === "WindowFrameAdded") { + const winsToBeNotified = getWindowsByTabGroupId(theWindow.id, windowInfo.data.frameId); + const data = windowInfo.data; + theWindowEvents.handleAttached(data.frameId, data.frameId, data.isTabHeaderVisible, data.isLocked, winsToBeNotified) + .then(async () => { + if (winsToBeNotified.length > 0) { + await executor.finished; + this._registry.execute("tab-attached", theWindow, windowInfo.data.frameId, windowInfo.data.isTabHeaderVisible); + } + }); + } + if (windowInfo.type === "WindowFrameRemoved") { + const oldTabGroupId = theWindow.tabGroupId; + const winsToBeNotified = getWindowsByTabGroupId(theWindow.id, oldTabGroupId); + theWindowEvents.handleDetached(windowInfo.data.isLocked, winsToBeNotified) + .then(async () => { + if (winsToBeNotified.length > 0) { + await executor.finished; + this._registry.execute("tab-detached", theWindow, windowInfo.data.frameId, theWindow.tabGroupId); + } + }); + } + if (windowInfo.type === "TabHeaderVisibilityChanged") { + theWindowEvents.handleTabHeaderVisibilityChanged(windowInfo.data.isTabHeaderVisible); + } + if (windowInfo.type === "FrameSelectionChanged") { + theWindowEvents.handleFrameSelectionChanged(windowInfo.data.newWindowId, windowInfo.data.prevWindowId); + } + if (windowInfo.type === "ButtonClicked") { + theWindowEvents.handleFrameButtonClicked(windowInfo.data); + } + if (windowInfo.type === "ButtonAdded") { + theWindowEvents.handleFrameButtonAdded(windowInfo.data); + } + if (windowInfo.type === "ButtonRemoved") { + theWindowEvents.handleFrameButtonRemoved(windowInfo.data); + } + if (windowInfo.type === "WindowZoomFactorChanged") { + theWindowEvents.handleZoomFactorChanged(windowInfo.data); + } + if (windowInfo.type === "Closed") { + windowStore.remove(windowObjectAndEvents); + theWindowEvents.handleWindowClose(); + } + if (windowInfo.type === "FrameIsLockedChanged") { + theWindowEvents.handleFrameIsLockedChanged(windowInfo.data); + } + if (windowInfo.type === "PlacementSettingsChanged") { + theWindowEvents.handlePlacementSettingsChanged(windowInfo.data); + } + if (windowInfo.type === "DockingChanged") { + theWindowEvents.handleDockingChanged(windowInfo.data); + } + if (windowInfo.type === "AllowWorkspaceDropChanged") { + theWindowEvents.handleAllowWorkspaceDropChanged(windowInfo.data); + } + if (windowInfo.type === "IsPinnedChanged") { + theWindowEvents.handleIsPinnedChanged(windowInfo.data); + } + if (windowInfo.type === "WindowChannelRestrictionsChanged") { + theWindowEvents.handleChannelRestrictionsChanged(windowInfo.data); + } + this._registry.execute("window-event", extendedStreamEvent); + } + createWindowFromSnapshot(windowId, options) { + const windowObjAndEvents = this.createWindowCore(windowId, options); + windowStore.add(windowObjAndEvents, { + ready: true, + urlChanged: true, + compositionChanged: true + }); + } + createWindowFromStream(windowId, options) { + var _a; + const windowObjAndEvents = this.createWindowCore(windowId, options); + const isRemote = windowObjAndEvents.API.windowType === "remote"; + const isFrameless = windowObjAndEvents.API.windowType === "electron" && windowObjAndEvents.API.mode === "frameless"; + const isHidden = windowObjAndEvents.API.isVisible === false; + let urlChanged = false; + let compositionChanged = false; + if (isRemote) { + urlChanged = true; + } + if (isFrameless || isHidden) { + compositionChanged = true; + } + if (!isRemote) { + urlChanged = !((_a = this._configuration) === null || _a === void 0 ? void 0 : _a.windowAvailableOnURLChanged); + } + windowStore.add(windowObjAndEvents, { + ready: true, + urlChanged, + compositionChanged + }); + } + createWindowCore(windowId, options) { + const windowObjAndEvents = windowFactory(windowId, this.mapToWindowConstructorOptions(options), executor, this._logger, this._appManagerGetter, this._displayAPIGetter, this._channelsAPIGetter, this._agm); + windowObjAndEvents.GroupCreationArgs = this.mapToGroupCreationArgs(options); + return windowObjAndEvents; + } + async focusChanged(theWindowEvents, theWindow, focus) { + theWindowEvents.handleFocusChanged(focus); + try { + if (!this._configuration.windowAvailableOnURLChanged) { + await windowStore.waitFor(theWindow.id); + } + } + catch (error) { + return; + } + if (focus) { + this._registry.execute("got-focus", theWindow); + } + else { + this._registry.execute("lost-focus", theWindow); + } + } + mapToWindowConstructorOptions(args) { + return { + name: args.name, + context: args.context, + bounds: args.bounds, + url: args.url, + title: args.title, + isVisible: args.isVisible, + focus: args.isFocused, + state: args.state, + frameColor: args.frameColor, + groupId: args.groupId, + neighbours: args.neighbors, + isFocused: args.isFocused, + isGroupHeaderVisible: args.groupHeaderVisible, + isCollapsed: args.isCollapsed, + tabGroupId: args.frameId, + frameId: args.frameId, + mode: args.mode, + isTabHeaderVisible: args.isTabHeaderVisible, + isTabSelected: args.isActiveTab, + settings: args.settings, + windowType: args.windowType, + zoomFactor: args.zoomFactor, + isLocked: args.isLocked, + placementSettings: args.placementSettings, + isSticky: args.isSticky, + tabIndex: args.tabIndex, + frameButtons: args.frameButtons, + jumpListOptions: args.jumpList, + applicationName: args.applicationName, + allowWorkspaceDrop: args.allowWorkspaceDrop, + isPinned: args.isPinned + }; + } + mapToGroupCreationArgs(args) { + return { + isGroupHibernated: args.isGroupHibernated, + isGroupVisible: args.isGroupVisible + }; + } + getExtendedStreamEvent(streamEvent) { + try { + if (!streamEvent.windowId) { + return streamEvent; + } + const window = windowStore.get(streamEvent.windowId); + if (!window) { + return streamEvent; + } + const result = { + state: streamEvent.type, + windowName: window.API.name, + ...streamEvent + }; + if (result.state === "WindowFrameAdded") { + result.state = "TabAttached"; + } + if (result.state === "StateChanged") { + result.state = result.data.charAt(0).toUpperCase() + result.data.slice(1); + } + if (result.state === "ButtonAdded") { + result.state = "FrameButtonAdded"; + } + if (result.state === "ButtonRemoved") { + result.state = "FrameButtonRemoved"; + } + return result; + } + catch (error) { + return streamEvent; + } + } + } + + var envDetector = (agm, logger, appManagerGetter, displayAPIGetter, channelsAPIGetter, gdMajorVersion) => { + var _a; + const _logger = logger; + if (gdMajorVersion === 2) { + _logger.trace("running in HC"); + throw new Error("GD2 not supported"); + } + else if (gdMajorVersion >= 3) { + _logger.trace("running in GD 3"); + return new GDEnvironment(agm, _logger, appManagerGetter, displayAPIGetter, channelsAPIGetter, window.glue42gd.windowId, (_a = window.webGroupsManager) === null || _a === void 0 ? void 0 : _a.id).init(); + } + else { + _logger.trace("running in Browser or Node"); + return new GDEnvironment(agm, _logger, appManagerGetter, displayAPIGetter, channelsAPIGetter).init(); + } + }; + + var groupFactory = (id, executor) => { + const _registry = CallbackRegistryFactory(); + const _windowsId = []; + let _isHibernatedFlag; + let _isVisible; + async function addWindow(winId) { + var _a, _b, _c, _d; + if (_windowsId.indexOf(winId) === -1) { + _windowsId.push(winId); + const win = windowStore.get(winId); + win.Events.handleGroupChanged(groupObject, undefined); + _isHibernatedFlag = (_b = (_a = win.GroupCreationArgs.isGroupHibernated) !== null && _a !== void 0 ? _a : _isHibernatedFlag) !== null && _b !== void 0 ? _b : false; + _isVisible = (_d = (_c = win.GroupCreationArgs.isGroupVisible) !== null && _c !== void 0 ? _c : _isVisible) !== null && _d !== void 0 ? _d : true; + await executor.finished; + _registry.execute("window-added", groupObject, win.API); + } + } + async function removeWindow(win) { + const index = _windowsId.indexOf(win.API.id); + if (index !== -1) { + _windowsId.splice(index, 1); + win.Events.handleGroupChanged(undefined, groupObject); + await executor.finished; + _registry.execute("window-removed", groupObject, win.API); + } + } + function find(window, success, error) { + let winId; + if (typeof window === "string") { + winId = window; + } + else if (!isUndefinedOrNull(window)) { + winId = window.id; + } + const win = _mapToWindowObject(winId); + if (win) { + if (typeof success === "function") { + success(win); + } + return win; + } + else { + if (typeof error === "function") { + error(`No window with ID: ${winId}`); + } + } + } + function windows(success) { + const mappedWindows = _mapToWindowObjects(); + return mappedWindows; + } + async function execute(command, options, ...keys) { + await executor.execute(command, options, ...keys); + return groupObject; + } + function handleGroupHeaderVisibilityChanged(windowInfo) { + _registry.execute("header-visibility-changed", groupObject); + } + function handleGroupVisibilityChanged(visibile) { + _isVisible = visibile; + _registry.execute("group-visibility-changed", groupObject); + } + function handleGroupHibernateChanged(isHibernatedFlag) { + _isHibernatedFlag = isHibernatedFlag; + } + function _mapToWindowObjects() { + const winObjects = []; + _windowsId.forEach((winId) => { + const windowObject = _mapToWindowObject(winId); + if (typeof windowObject !== "undefined") { + winObjects.push(windowObject); + } + }); + return winObjects; + } + function _mapToWindowObject(windowId) { + return windowStore.get(windowId) ? windowStore.get(windowId).API : undefined; + } + function _getGroupHeaderVisibility() { + const windowWithHiddenHeader = _mapToWindowObjects().find((w) => !w.isGroupHeaderVisible); + const _isGroupHeaderVisible = windowWithHiddenHeader === undefined; + return _isGroupHeaderVisible; + } + function isHibernated() { + return _isHibernatedFlag; + } + function onHeaderVisibilityChanged(callback) { + return _registry.add("header-visibility-changed", callback); + } + function onWindowAdded(callback) { + return _registry.add("window-added", callback); + } + function onWindowRemoved(callback) { + return _registry.add("window-removed", callback); + } + function onVisibilityChanged(callback) { + if (!callback) { + throw new Error("Callback argument is required"); + } + if (callback && typeof callback !== "function") { + throw new Error("Callback argument must be a function"); + } + return _registry.add("group-visibility-changed", callback); + } + function onClosing(callback) { + if (typeof callback !== "function") { + throw new Error("callback must be a function"); + } + const callbackWrap = (success, error, prevent) => { + const promise = callback(prevent); + if (promise === null || promise === void 0 ? void 0 : promise.then) { + promise.then(success).catch(error); + } + else { + success(); + } + }; + return executor.onGroupClosing(callbackWrap, groupObject); + } + const groupObject = { + id, + get windows() { + return windows(); + }, + find, + get isHeaderVisible() { + return _getGroupHeaderVisibility(); + }, + get isHibernated() { + return isHibernated(); + }, + get isVisible() { + return _isVisible; + }, + showHeader: (success, error) => { + return Utils.callbackifyPromise(() => { + return execute("setGroupHeaderVisibility", { windowId: _windowsId[0], options: { toShow: true } }, ..._windowsId.map((w) => `GroupHeaderVisibilityChanged-${w}`)); + }, success, error); + }, + hideHeader: (success, error) => { + return Utils.callbackifyPromise(() => { + return execute("setGroupHeaderVisibility", { windowId: _windowsId[0], options: { toShow: false } }, ..._windowsId.map((w) => `GroupHeaderVisibilityChanged-${w}`)); + }, success, error); + }, + getTitle: async () => { + const r = await executor.execute("getGroupTitle", { windowId: _windowsId[0] }); + return r.title; + }, + setTitle: async (title) => { + if (isNullOrWhiteSpace(title)) { + throw new Error("`title` must not be null or undefined."); + } + return execute("setGroupTitle", { windowId: _windowsId[0], options: { title } }); + }, + capture: (captureOptions) => { + return executor.captureGroup(_windowsId, captureOptions); + }, + maximize: (success, error) => { + return Utils.callbackifyPromise(() => { + return execute("maximizeGroup", { windowId: _windowsId[0] }, ..._windowsId.map((w) => `StateChanged-${w}`)); + }, success, error); + }, + restore: (success, error) => { + return Utils.callbackifyPromise(() => { + return execute("restoreGroup", { windowId: _windowsId[0] }, ..._windowsId.map((w) => `StateChanged-${w}`)); + }, success, error); + }, + show: (activate) => { + if (!isUndefinedOrNull(activate) && !isBoolean(activate)) { + throw new Error("Activate flag must be a boolean!"); + } + activate = !isUndefinedOrNull(activate) ? activate : true; + return executor.executeGroup("showGroup", { + groupId: id, + options: { activate } + }); + }, + hide: () => { + return executor.executeGroup("hideGroup", { + groupId: id + }); + }, + close: () => { + return executor.executeGroup("closeGroup", { + groupId: id + }); + }, + showPopup: (options) => { + return executor.showGroupPopup(id, options); + }, + onHeaderVisibilityChanged, + onWindowAdded, + onWindowRemoved, + onVisibilityChanged, + onClosing, + }; + const internal = { + get windows() { + return _windowsId; + }, + addWindow, + removeWindow, + handleGroupHeaderVisibilityChanged, + handleGroupVisibilityChanged, + handleGroupHibernateChanged + }; + return { + groupAPI: groupObject, + groupInternal: internal, + }; + }; + + var groupsFactory = (environment, logger) => { + const _registry = CallbackRegistryFactory(); + const _groups = {}; + let heardForWindowsCounter = -1; + const windows = windowStore.list; + Object.keys(windows).forEach((k) => { + const win = windows[k]; + const groupId = win.API.groupId; + const winId = win.API.id; + if (!isNullOrWhiteSpace(groupId)) { + addWindow(groupId, winId); + } + }); + windowStore.onRemoved((w) => { + const group = findGroupWrapperByWindow(w.API); + removeWindow(group, w); + }); + environment.onCompositionChanged((windowInfo) => { + handleCompositionChanged(windowInfo); + }); + environment.onGroupHeaderVisibilityChanged((windowInfo) => { + const windowId = windowInfo.windowId; + const group = findGroupByWindow(windowId); + if (typeof group !== "undefined") { + const groupEvents = _groups[group.id]; + if (heardForWindowsCounter === -1) { + heardForWindowsCounter = group.windows.length; + } + heardForWindowsCounter--; + if (heardForWindowsCounter === 0) { + heardForWindowsCounter = -1; + groupEvents.groupInternal.handleGroupHeaderVisibilityChanged(windowInfo); + } + } + }); + environment.onGroupVisibilityChanged((data) => { + const groupEvents = _groups[data.groupId]; + if (groupEvents) { + groupEvents.groupInternal.handleGroupVisibilityChanged(data.visible); + } + }); + environment.onGroupStateChanged((data) => { + const groupWrapper = _groups[data.groupId]; + if (data.state === "hibernated") { + if (groupWrapper === null || groupWrapper === void 0 ? void 0 : groupWrapper.groupAPI) { + groupWrapper.groupInternal.handleGroupHibernateChanged(true); + } + _registry.execute("group-hibernated", data.groupId); + } + else if (data.state === "resumed") { + if (groupWrapper === null || groupWrapper === void 0 ? void 0 : groupWrapper.groupAPI) { + groupWrapper.groupInternal.handleGroupHibernateChanged(false); + } + _registry.execute("group-resumed", groupWrapper.groupAPI); + } + }); + function my() { + var _a; + return findGroupByWindow((_a = environment.myGroup()) !== null && _a !== void 0 ? _a : environment.my()); + } + async function create(options) { + if (isUndefinedOrNull(options)) { + throw new Error(`options must be defined`); + } + if (isUndefinedOrNull(options.groups) || !Array.isArray(options.groups) || options.groups.length === 0) { + throw new Error(`options.groups must be defined`); + } + const { groupIds } = await executor.executeGroup("createGroups", { + options + }); + const groups = groupIds.map((groupId) => { + return waitForGroup(groupId); + }); + return Promise.all(groups); + } + async function close(idOrGroup, options) { + if (isUndefinedOrNull(idOrGroup)) { + throw new Error(`group must be defined`); + } + let groupId = ""; + if (typeof idOrGroup === "string") { + groupId = idOrGroup; + } + else { + groupId = idOrGroup.id; + } + if (isUndefinedOrNull(options)) { + throw new Error(`options must be defined`); + } + await executor.executeGroup("closeGroup", { + groupId, + options + }); + } + function list(success) { + const result = Object.keys(_groups).map((groupId) => { + if (_groups[groupId]) { + return _groups[groupId].groupAPI; + } + }); + if (typeof success === "function") { + success(result); + } + return result; + } + function findGroupByWindow(winId, success, error) { + let windowId; + if (typeof winId === "string") { + windowId = winId; + } + else if (!isUndefinedOrNull(winId)) { + windowId = winId.id; + } + const result = Object.values(_groups).find((groupObj) => { + const group = groupObj.groupAPI; + const wins = group.windows.filter((w) => w.id === windowId); + return wins.length; + }); + if (result) { + if (typeof success === "function") { + success(result.groupAPI); + } + return result.groupAPI; + } + else if (typeof error === "function") { + error(`Cannot find the group of the window.`); + } + } + function waitForGroup(groupId) { + if (!groupId) { + return Promise.reject(new Error(`groupId must be defined`)); + } + return new Promise((res, rej) => { + const groupWrapper = _groups[groupId]; + if (groupWrapper) { + res(groupWrapper.groupAPI); + } + else { + const un = onGroupAdded((group) => { + if (group.id === groupId) { + un(); + res(group); + } + }); + } + }); + } + function getMyGroup() { + var _a; + return waitForGroup((_a = environment.myGroup()) !== null && _a !== void 0 ? _a : environment.my()); + } + async function resume(groupId, activate) { + validateGroupIdArg(groupId); + if (!isUndefinedOrNull(activate) && !isBoolean(activate)) { + throw new Error("Activate flag must be a boolean!"); + } + activate = !isUndefinedOrNull(activate) ? activate : true; + await executor.executeGroup("resumeGroup", { + groupId, + options: { activate } + }); + } + async function hibernate(groupId) { + validateGroupIdArg(groupId); + await executor.executeGroup("hibernateGroup", { + groupId + }); + return groupId; + } + function onGroupAdded(callback) { + return _registry.add("group-added", callback); + } + function onGroupRemoved(callback) { + return _registry.add("group-removed", callback); + } + function onWindowMoved(callback) { + return _registry.add("window-moved", callback); + } + function onHibernated(callback) { + if (!callback) { + throw new Error("Callback argument is required"); + } + if (callback && typeof callback !== "function") { + throw new Error("Callback argument must be a function"); + } + return _registry.add("group-hibernated", callback); + } + function onResumed(callback) { + if (!callback) { + throw new Error("Callback argument is required"); + } + if (callback && typeof callback !== "function") { + throw new Error("Callback argument must be a function"); + } + return _registry.add("group-resumed", callback); + } + function createOrGet(groupId) { + if (!_groups.hasOwnProperty(groupId)) { + const createdGroupWrapper = groupFactory(groupId, environment.executor); + _groups[groupId] = createdGroupWrapper; + const group = createdGroupWrapper.groupAPI; + _registry.execute("group-added", group); + return createdGroupWrapper; + } + else { + return _groups[groupId]; + } + } + function deleteIfEmpty(groupWrapper) { + const group = groupWrapper.groupAPI; + if (group.windows.length === 0) { + delete _groups[group.id]; + executor.clearCallbacks(group.id); + _registry.execute("group-removed", group); + } + } + function addWindow(groupId, winId) { + const group = createOrGet(groupId); + group.groupInternal.addWindow(winId); + return group; + } + function removeWindow(group, win) { + if (!group) { + return; + } + group.groupInternal.removeWindow(win); + deleteIfEmpty(group); + } + function handleCompositionChanged(state) { + const groupId = state.groupId; + const windowId = state.windowId; + const win = windowStore.get(windowId); + if (!win) { + return; + } + const currentGroup = findGroupWrapperByWindow(win.API); + if (isUndefinedOrNull(groupId)) { + removeWindow(currentGroup, win); + return; + } + if (isUndefinedOrNull(currentGroup) && !isUndefinedOrNull(groupId)) { + addWindow(groupId, win.API.id); + return; + } + if (currentGroup.groupAPI.id !== groupId) { + moveWindow(win, currentGroup.groupAPI.id, groupId); + } + } + function moveWindow(win, from, to) { + const winId = win.API.id; + const fromGroup = _groups[from]; + removeWindow(fromGroup, win); + const toGroup = addWindow(to, winId); + win.Events.handleGroupChanged(toGroup.groupAPI, fromGroup.groupAPI); + _registry.execute("window-moved", winId, from, to); + } + function findGroupWrapperByWindow(winId) { + let windowId; + if (typeof winId === "string") { + windowId = winId; + } + else if (!isUndefinedOrNull(winId)) { + windowId = winId.id; + } + return Object.values(_groups).find((groupObj) => { + const groupInternal = groupObj.groupInternal; + const wins = groupInternal.windows.filter((id) => id === windowId); + return wins.length; + }); + } + function validateGroupIdArg(groupId) { + if (!groupId || typeof groupId !== "string") { + throw new Error("Please provide a valid Group ID as a non-empty string!"); + } + } + const groups = { + get my() { + return my(); + }, + create, + close, + list, + findGroupByWindow, + waitForGroup, + getMyGroup, + onGroupAdded, + onGroupRemoved, + hibernate, + resume, + onHibernated, + onResumed + }; + const events = { onWindowMoved }; + return { + groupsAPI: groups, + groupsEvents: events, + }; + }; + + var WindowsFactory = (agm, logger, appManagerGetter, displayAPIGetter, channelsGetter, gdMajorVersion) => { + const _registry = CallbackRegistryFactory(); + const _logger = logger; + let groups; + let environment; + windowStore.init(_logger); + const isReady = new Promise((resolve, reject) => { + envDetector(agm, _logger, appManagerGetter, displayAPIGetter, channelsGetter, gdMajorVersion) + .then((env) => { + environment = env; + groups = groupsFactory(env); + jumpListManager.init(env.executor, agm, _logger); + resolve(); + }) + .catch((e) => { + const err = `Timed out waiting for connection to Glue42 Enterprise: Error: ${e.message}`; + _logger.error(err, e); + reject(new Error(err)); + }); + }); + function ready() { + return isReady; + } + function my() { + const myWindow = windowStore.getIfReady(environment.my()); + return myWindow ? myWindow.API : undefined; + } + function open(name, url, options, success, error) { + return Utils.callbackifyPromise(() => { + if (isNullOrWhiteSpace(name)) { + throw new Error("The window name is missing."); + } + if (isNullOrWhiteSpace(url)) { + throw new Error("The window URL is missing."); + } + if (!isUndefinedOrNull(options)) { + const optionsAsAny = options; + for (const prop of ["minHeight", "maxHeight", "minWidth", "maxWidth", "width", "height", "top", "left"]) { + if (prop in optionsAsAny) { + const value = optionsAsAny[prop]; + if (isUndefinedOrNull(value)) { + delete optionsAsAny[prop]; + continue; + } + if (!isNumber(value)) { + const errMessage = `${prop} must be a number`; + throw new Error(errMessage); + } + if (optionsAsAny[prop] === "width" || optionsAsAny[prop] === "height") { + if (value <= 0) { + const errMessage = `${prop} must be a positive number`; + throw new Error(errMessage); + } + } + } + } + } + return environment.open(name, url, options); + }, success, error); + } + function find(name, success, error) { + const windows = windowStore.list; + const windowsForListing = Object.keys(windows).reduce((memo, winId) => { + var _a; + const window = windows[winId]; + if (((_a = window === null || window === void 0 ? void 0 : window.API) === null || _a === void 0 ? void 0 : _a.name) === name) { + memo.push(window.API); + } + return memo; + }, []); + const win = windowsForListing[0]; + if (win) { + if (typeof success === "function") { + success(windowsForListing[0]); + } + return windowsForListing[0]; + } + else { + if (typeof error === "function") { + error("There is no window with name:" + name); + } + } + } + function findById(id, success, error) { + const windows = windowStore.list; + const windowsForListing = Object.keys(windows).reduce((memo, winId) => { + const window = windows[winId]; + if (typeof window !== "undefined" && window.API.id === id) { + memo.push(window.API); + } + return memo; + }, []); + const win = windowsForListing[0]; + if (win) { + if (typeof success === "function") { + success(windowsForListing[0]); + } + return windowsForListing[0]; + } + else { + if (typeof error === "function") { + error("There is no window with such id:" + id); + } + } + } + function list(success) { + const windows = windowStore.list; + const windowsForListing = Object.keys(windows) + .map((k) => { + return windows[k].API; + }); + if (typeof success !== "function") { + return windowsForListing; + } + success(windowsForListing); + } + function configure(options) { + const win = my(); + const winId = win ? win.id : ""; + return executor.configure(winId, options); + } + function autoArrange(displayId) { + return executor.autoArrange(displayId); + } + function windowAdded(callback) { + return _registry.add("window-added", callback); + } + function windowRemoved(callback) { + return _registry.add("window-removed", callback); + } + function tabAttached(callback) { + let unsubFunc; + let unsubscribed = false; + isReady.then(() => { + if (unsubscribed) { + return; + } + unsubFunc = environment.tabAttached(callback); + }); + return () => { + unsubscribed = true; + if (unsubFunc) { + unsubFunc(); + } + }; + } + function tabDetached(callback) { + let unsubFunc; + let unsubscribed = false; + isReady.then(() => { + if (unsubscribed) { + return; + } + unsubFunc = environment.tabDetached(callback); + }); + return () => { + unsubscribed = true; + if (unsubFunc) { + unsubFunc(); + } + }; + } + function onWindowFrameColorChanged(callback) { + let unsubFunc; + let unsubscribed = false; + isReady.then(() => { + if (unsubscribed) { + return; + } + unsubFunc = environment.onWindowFrameColorChanged(callback); + }); + return () => { + unsubscribed = true; + if (unsubFunc) { + unsubFunc(); + } + }; + } + function onWindowGotFocus(callback) { + let unsubFunc; + let unsubscribed = false; + isReady.then(() => { + if (unsubscribed) { + return; + } + unsubFunc = environment.onWindowGotFocus(callback); + }); + return () => { + unsubscribed = true; + if (unsubFunc) { + unsubFunc(); + } + }; + } + function onWindowLostFocus(callback) { + let unsubFunc; + let unsubscribed = false; + isReady.then(() => { + if (unsubscribed) { + return; + } + unsubFunc = environment.onWindowLostFocus(callback); + }); + return () => { + unsubscribed = true; + if (unsubFunc) { + unsubFunc(); + } + }; + } + function onArrangementChanged(callback) { + return environment.onWindowsAutoArrangeChanged(callback); + } + function onEvent(callback) { + let unsubFunc; + let unsubscribed = false; + isReady.then(() => { + if (unsubscribed) { + return; + } + unsubFunc = environment.onEvent(callback); + }); + return () => { + unsubscribed = true; + if (unsubFunc) { + unsubFunc(); + } + }; + } + function createFlydown(targetId, config) { + return environment.createFlydown(targetId, config); + } + function showPopup(targetId, config) { + return environment.showPopup(targetId, config); + } + function handleWindowAdded(w) { + _registry.execute("window-added", w.API); + } + function handleWindowRemoved(w) { + _registry.execute("window-removed", w.API); + } + windowStore.onReadyWindow(handleWindowAdded); + windowStore.onRemoved(handleWindowRemoved); + return { + my, + open, + find, + findById, + list, + ready, + onWindowAdded: windowAdded, + windowAdded, + onWindowRemoved: windowRemoved, + windowRemoved, + onTabAttached: tabAttached, + onTabDetached: tabDetached, + onWindowFrameColorChanged, + onArrangementChanged, + get groups() { + return groups.groupsAPI; + }, + onWindowGotFocus, + onWindowLostFocus, + onEvent, + createFlydown, + showPopup, + configure, + autoArrange + }; + }; + + class LayoutStore { + constructor() { + this.layouts = []; + } + removeWhere(condition) { + this.layouts = this.layouts.filter(condition); + } + removeAll() { + this.layouts = []; + } + add(item) { + this.layouts.push(item); + } + get all() { + return this.layouts; + } + where(condition) { + return this.layouts.filter(condition); + } + first(condition) { + return this.where(condition)[0]; + } + } + var store = new LayoutStore(); + + const SaveContextMethodName = "T42.HC.GetSaveContext"; + class ContextProvider { + constructor(config, activitiesGetter, callbacks, logger) { + this.config = config; + this.activitiesGetter = activitiesGetter; + this.callbacks = callbacks; + this.logger = logger; + this.interop = config.agm; + this.registerRequestMethods(); + } + onSaveRequested(callback) { + return this.callbacks.add("saveRequested", callback); + } + isActivityOwner() { + if (typeof htmlContainer !== "undefined") { + const context = htmlContainer.getContext(); + return context && context._t42 && context._t42.activityIsOwner; + } + const activities = this.activitiesGetter(); + if (!activities) { + return false; + } + if (!activities.inActivity) { + return false; + } + const myWindow = activities.my.window; + const myActivity = activities.my.activity; + if (!myActivity && !myWindow) { + return false; + } + return myActivity.owner.id === myWindow.id; + } + registerRequestMethods() { + this.interop.register(SaveContextMethodName, (args) => { + const usersCbs = this.callbacks.execute("saveRequested", args); + if ((usersCbs === null || usersCbs === void 0 ? void 0 : usersCbs.length) > 1) { + this.logger.warn(`Multiple subscriptions for "glue.layouts.onSaveRequested" - only the first one will be used`); + } + const requestResult = usersCbs[0]; + const autoSaveWindowContext = this.config.autoSaveWindowContext; + if (typeof autoSaveWindowContext === "boolean" && autoSaveWindowContext) { + return { autoSaveWindowContext }; + } + else if (Array.isArray(autoSaveWindowContext) && autoSaveWindowContext.length > 0) { + return { autoSaveWindowContext }; + } + const result = { windowContext: requestResult === null || requestResult === void 0 ? void 0 : requestResult.windowContext, activityContext: undefined }; + if (this.isActivityOwner()) { + result.activityContext = requestResult === null || requestResult === void 0 ? void 0 : requestResult.activityContext; + } + return result; + }); + } + } + + function transformACSLayout(something) { + if (!something) { + return something; + } + if (Array.isArray(something)) { + return something.map((item) => { + return transformACSLayout(item); + }); + } + if (typeof something === "string" || typeof something === "number" || typeof something === "boolean") { + return something; + } + const initial = {}; + return Object.keys(something).reduce((accumulator, current) => { + var _a; + const value = something[current]; + const convertedValue = transformACSLayout(value); + let key = current; + if (((_a = current[0]) === null || _a === void 0 ? void 0 : _a.toLowerCase()) !== current[0]) { + key = current[0].toLowerCase() + current.substr(1); + } + accumulator[key] = convertedValue; + return accumulator; + }, initial); + } + + class LayoutImpl { + constructor(data) { + this.name = data.name; + this.type = data.type; + this.components = data.components; + this.context = data.context; + this.metadata = data.metadata; + this.version = data.version; + this.displays = data.displays; + } + } + + var main = {}; + + var application = {}; + + /** + * This file was automatically generated by json-schema-to-typescript. + * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file, + * and run json-schema-to-typescript to regenerate this file. + */ + Object.defineProperty(application, "__esModule", { value: true }); + + var system = {}; + + /** + * This file was automatically generated by json-schema-to-typescript. + * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file, + * and run json-schema-to-typescript to regenerate this file. + */ + Object.defineProperty(system, "__esModule", { value: true }); + + var layout = {}; + + Object.defineProperty(layout, "__esModule", { value: true }); + layout.SwimlaneItemType = layout.LayoutType = void 0; + var LayoutType; + (function (LayoutType) { + LayoutType["Global"] = "Global"; + LayoutType["Activity"] = "Activity"; + LayoutType["ApplicationDefault"] = "ApplicationDefault"; + LayoutType["Swimlane"] = "Swimlane"; + LayoutType["Workspaces"] = "Workspace"; + })(LayoutType || (layout.LayoutType = LayoutType = {})); + var SwimlaneItemType; + (function (SwimlaneItemType) { + SwimlaneItemType["Tab"] = "tab"; + SwimlaneItemType["Window"] = "window"; + SwimlaneItemType["Canvas"] = "canvas"; + })(SwimlaneItemType || (layout.SwimlaneItemType = SwimlaneItemType = {})); + + var swTheme = {}; + + /** + * This file was automatically generated by json-schema-to-typescript. + * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file, + * and run json-schema-to-typescript to regenerate this file. + */ + Object.defineProperty(swTheme, "__esModule", { value: true }); + + var swConfiguration = {}; + + /** + * This file was automatically generated by json-schema-to-typescript. + * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file, + * and run json-schema-to-typescript to regenerate this file. + */ + Object.defineProperty(swConfiguration, "__esModule", { value: true }); + + (function (exports) { + var __createBinding = (commonjsGlobal && commonjsGlobal.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; + })); + var __exportStar = (commonjsGlobal && commonjsGlobal.__exportStar) || function(m, exports) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); + }; + Object.defineProperty(exports, "__esModule", { value: true }); + // export { SchemaValidator } from "./validator"; + // export { FileProvider } from "./fileProvider"; + // export { SchemaProvider } from "./provider"; + __exportStar(application, exports); + __exportStar(system, exports); + __exportStar(layout, exports); + __exportStar(swTheme, exports); + __exportStar(swConfiguration, exports); + + } (main)); + + const LayoutsCommandMethod = "T42.ACS.Command"; + class LayoutsAPIImpl { + constructor(config, stream, callbacks, logger) { + this.config = config; + this.stream = stream; + this.callbacks = callbacks; + this.isRegisterMethodForLayoutModified = false; + this.appManager = config.appManager; + this.provider = new ContextProvider(config, config.activityGetter, callbacks, logger); + stream.subscribe(); + } + async setDefaultGlobal(name) { + const methodName = "SelectDefaultLayout"; + await this.invokeMethodCore(methodName, { name }); + return; + } + async clearDefaultGlobal() { + const methodName = "DeselectDefaultLayout"; + await this.invokeMethodCore(methodName); + return; + } + async getDefaultGlobal() { + const methodName = "GetDefaultLayout"; + const result = await this.invokeMethodCore(methodName); + const layout = result.returned; + if (layout === null || layout === undefined || (typeof layout === 'object' && Object.keys(layout).length === 0)) { + return undefined; + } + return objectClone(this.isSlimMode() ? layout : this.list().find((l) => l.name === layout.name && l.type === layout.type)); + } + ready() { + if (this.config.mode === "fullWaitSnapshot") { + return this.stream.gotSnapshot; + } + return this.stream.ready; + } + save(layout) { + return new Promise((resolve, reject) => { + var _a, _b; + this.verifyNotSlimMode(); + if (isUndefinedOrNull(layout)) { + return reject(new Error("layout is required")); + } + if (isNullOrWhiteSpace(layout.name)) { + return reject(new Error("layout.name argument is required")); + } + if (isNullOrWhiteSpace(layout.type)) { + layout.type = "Global"; + } + if (!isNullOrWhiteSpace(layout.activityId)) { + layout.type = "Activity"; + } + const layoutObject = { + name: layout.name, + type: layout.type, + context: (_a = layout.context) !== null && _a !== void 0 ? _a : {}, + metadata: (_b = layout.metadata) !== null && _b !== void 0 ? _b : {}, + options: {}, + }; + if (layout.type === "Activity") { + let actId = layout.activityId; + if (!actId) { + if (!this.appManager.myInstance.inActivity) { + return reject(new Error("Current application is not in activity. Cannot save activity layout for it.")); + } + actId = this.appManager.myInstance.activityId; + } + layoutObject.activityId = actId; + } + else if (layout.type === "Global") { + if (Array.isArray(layout.ignoreInstances)) { + layoutObject.options.ignoreInstances = layout.ignoreInstances; + } + if (Array.isArray(layout.instances)) { + layoutObject.options.instances = layout.instances; + } + if (typeof layout.setAsCurrent === "boolean") { + layoutObject.options.setAsCurrent = layout.setAsCurrent; + } + } + else { + return reject(new Error(`layout type ${layout.type} is not supported`)); + } + this.invokeMethodAndTrack("SaveLayout", layoutObject, resolve, reject); + }); + } + restore(options) { + return new Promise((resolve, reject) => { + var _a, _b, _c; + this.verifyNotSlimMode(); + if (isUndefinedOrNull(options)) { + return reject(new Error("options argument is required")); + } + if (isNullOrWhiteSpace(options.name)) { + return reject(new Error("options.name argument is required")); + } + if (isNullOrWhiteSpace(options.type)) { + options.type = "Global"; + } + if (!isNullOrWhiteSpace(options.activityIdToJoin)) { + options.type = "Activity"; + } + if (options.type === "Activity") { + if (isUndefinedOrNull(options.setActivityContext)) { + options.setActivityContext = true; + } + if (typeof options.setActivityContext !== "boolean") { + return reject(new Error("`setActivityContext` must hold a boolean value.")); + } + options.activityIdToJoin = (_a = options.activityIdToJoin) !== null && _a !== void 0 ? _a : this.appManager.myInstance.activityId; + } + if (!isUndefinedOrNull(options.closeRunningInstance)) { + options.closeRunningInstances = options.closeRunningInstance; + } + if (isUndefinedOrNull(options.closeRunningInstances)) { + options.closeRunningInstances = true; + } + if (!isBoolean(options.closeRunningInstances)) { + return reject(new Error("`closeRunningInstances` must hold a boolean value.")); + } + if (isUndefinedOrNull(options.closeMe)) { + options.closeMe = options.closeRunningInstances; + } + if (!isBoolean(options.closeMe)) { + return reject(new Error("`closeMe` must hold a boolean value.")); + } + if (!isUndefinedOrNull(options.context) && !isObject(options.context)) { + return reject(new Error("`context` must hold an object value.")); + } + if (!isUndefinedOrNull(options.timeout) && typeof options.timeout !== "number") { + return reject(new Error("`timeout` must hold an number value.")); + } + options.context = (_b = options.context) !== null && _b !== void 0 ? _b : {}; + const restoreOptions = { + activityToJoin: options.activityIdToJoin, + setActivityContext: options.setActivityContext, + ignoreActivityWindowTypes: options.ignoreActivityWindowTypes, + reuseExistingWindows: options.reuseWindows, + closeRunningInstances: options.closeRunningInstances, + excludeFromClosing: options.closeMe ? [] : [(_c = this.appManager.myInstance) === null || _c === void 0 ? void 0 : _c.id] + }; + const arg = { + type: options.type, + name: options.name, + context: options.context, + options: restoreOptions + }; + if (options.timeout) { + arg.timeout = options.timeout; + } + this.invokeMethodAndTrack("RestoreLayout", arg, resolve, reject, true); + }); + } + reset(options) { + return new Promise((resolve, reject) => { + this.verifyNotSlimMode(); + if (typeof options !== "object") { + return reject(new Error("options argument is required")); + } + if (isNullOrWhiteSpace(options.layoutId)) { + return reject(new Error("options.layoutId argument is required")); + } + const msg = { + ...options + }; + this.invokeMethodAndTrack("ResetLayout", msg, resolve, reject, true); + }); + } + remove(type, name) { + return new Promise((resolve, reject) => { + this.verifyNotSlimMode(); + if (!name) { + return reject(new Error("name argument is required")); + } + if (!type) { + return reject(new Error("type argument is required")); + } + const msg = { + type, + name, + }; + this.invokeMethodAndTrack("RemoveLayout", msg, resolve, reject); + }); + } + list() { + this.verifyNotSlimMode(); + return objectClone(store.all); + } + import(layouts, mode) { + return new Promise((resolve, reject) => { + this.verifyNotSlimMode(); + if (!isUndefinedOrNull(mode)) { + if (mode !== "merge" && mode !== "replace") { + return reject(new Error(`${mode} is not supported - only "merge" and "replace"`)); + } + } + if (!Array.isArray(layouts)) { + return reject(new Error("layouts arguments is not an array")); + } + const msg = { + mode: mode || "replace", + layouts + }; + this.invokeMethodAndTrack("ImportLayouts", msg, resolve, reject, true); + }); + } + export(layoutType) { + return new Promise((resolve, reject) => { + var _a; + if (!isUndefinedOrNull(layoutType) && !((_a = Object.values(main.LayoutType)) === null || _a === void 0 ? void 0 : _a.includes(layoutType))) { + return reject(new Error(`${layoutType} is not a supported Layout Type`)); + } + const handleResult = (result) => { + let layouts = this.getObjectValues(result.Layouts).map((t) => new LayoutImpl(transformACSLayout(t))); + if (layoutType) { + layouts = layouts.filter((l) => l.type === layoutType); + } + resolve(layouts); + }; + this.invokeMethodAndTrack("ExportLayouts", {}, handleResult, reject, true); + }); + } + rename(layout, newName) { + return new Promise((resolve, reject) => { + this.verifyNotSlimMode(); + if (!layout) { + return reject(new Error("layout argument is required")); + } + if (!layout.name) { + return reject(new Error("name argument is required")); + } + if (!layout.type) { + return reject(new Error("type argument is required")); + } + const msg = { type: layout.type, oldName: layout.name, newName }; + this.invokeMethodAndTrack("RenameLayout", msg, resolve, reject); + }); + } + updateMetadata(layout) { + return new Promise((resolve, reject) => { + if (!layout) { + return reject(new Error("layout argument is required")); + } + if (!layout.name) { + return reject(new Error("name argument is required")); + } + if (!layout.type) { + return reject(new Error("type argument is required")); + } + if (!layout.metadata) { + return reject(new Error("metadata argument is required")); + } + const layoutObject = { + name: layout.name, + type: layout.type, + metadata: layout.metadata + }; + this.invokeMethodAndTrack("UpdateMetadata", layoutObject, resolve, reject, true); + }); + } + hibernate(name, options) { + return new Promise((resolve, reject) => { + if (!name) { + return reject(new Error("name cannot be empty")); + } + options = options || {}; + const request = { + name, + type: "Global", + context: options.context || {}, + metadata: options.metadata || {}, + }; + this.invokeMethodAndTrack("HibernateLayout", request, resolve, reject, true); + }); + } + resume(name, context, options) { + return new Promise((resolve, reject) => { + if (!name) { + return reject(new Error("name cannot be empty")); + } + const request = { + name, + type: "Global", + context, + ...options + }; + this.invokeMethodAndTrack("ResumeLayout", request, resolve, reject, true); + }); + } + async getCurrentLayout() { + const methodName = "GetCurrentLayout"; + const result = await this.invokeMethodCore(methodName); + let layout = result.returned.layout; + if (!layout) { + return undefined; + } + if (!this.isSlimMode()) { + layout = this.list().find((l) => l.name === layout.name && l.type === layout.type); + } + return objectClone(layout); + } + getRestoredLayoutsInfo() { + return new Promise((resolve, reject) => { + const methodName = "GetRestoredLayoutsInfo"; + this.invokeMethodCore(methodName) + .then((result) => { + const restoredLayouts = result.returned; + resolve(restoredLayouts); + }) + .catch(reject); + }); + } + onAdded(callback) { + const result = this.callbacks.add("added", callback); + if (store.all.length > 0) { + store.all.forEach((layout) => { + try { + callback(layout); + } + catch (err) { } + }); + } + return result; + } + onRemoved(callback) { + return this.callbacks.add("removed", callback); + } + onChanged(callback) { + return this.callbacks.add("changed", callback); + } + onRestored(callback) { + return this.callbacks.add("restored", callback); + } + onRenamed(callback) { + return this.callbacks.add("renamed", callback); + } + onEvent(callback) { + return this.stream.onEvent(callback); + } + onSaveRequested(callback) { + return this.provider.onSaveRequested(callback); + } + onLayoutModified(callback) { + if (this.isRegisterMethodForLayoutModified === false) { + this.isRegisterMethodForLayoutModified = true; + this.registerMethodForLayoutModified(); + } + return this.callbacks.add("layout-modified", callback); + } + updateAppContextInCurrent(context) { + return new Promise((resolve, reject) => { + if (context && typeof context !== "object") { + return reject(new Error("Context must be an object")); + } + context = context !== null && context !== void 0 ? context : {}; + const request = { + context + }; + this.invokeMethodAndTrack("UpdateLayoutComponentContext", request, resolve, reject, true); + }); + } + updateDefaultContext(context) { + return new Promise((resolve, reject) => { + if (context && typeof context !== "object") { + return reject(new Error("Context must be an object")); + } + context = context !== null && context !== void 0 ? context : {}; + const request = { + context + }; + this.invokeMethodAndTrack("UpdateDefaultContext", request, resolve, reject, true); + }); + } + async get(name, type) { + const matching = this.list().find((l) => l.name === name && l.type === type); + if (!matching) { + throw new Error(`cannot find layout with name=${name} and type=${type}`); + } + return objectClone(matching); + } + async getAll(type) { + var _a; + if (!isUndefinedOrNull(type) && !((_a = Object.values(main.LayoutType)) === null || _a === void 0 ? void 0 : _a.includes(type))) { + throw new Error((`${type} is not a supported Layout Type`)); + } + const matching = this.list().filter((l) => type === l.type); + return objectClone(matching); + } + async forceRefresh() { + const methodName = "RefreshLayouts"; + await this.invokeMethodCore(methodName); + } + isSlimMode() { + return this.config.mode === "slim"; + } + verifyNotSlimMode() { + if (this.isSlimMode()) { + throw Error("Operation not allowed in slim mode. Run in full mode."); + } + } + async registerMethodForLayoutModified() { + await this.config.agm.register("T42.ACS.LayoutModified", (args, caller) => { + this.callbacks.execute("layout-modified", args); + }); + } + invokeMethodAndTrack(methodName, args, resolve, reject, skipStreamEvent) { + let streamEventReceived = skipStreamEvent; + let agmResult; + const token = Utils.generateId(); + args.token = token; + const handleResult = () => { + if (streamEventReceived && agmResult) { + resolve(agmResult); + } + }; + const methodResponseTimeoutMs = 120 * 1000; + if (!skipStreamEvent) { + this.stream.waitFor(token, methodResponseTimeoutMs) + .then(() => { + streamEventReceived = true; + handleResult(); + }) + .catch((err) => { + reject(err); + }); + } + const responseHandler = (result) => { + if (!result.returned) { + return reject(new Error("No result from method " + methodName)); + } + if (result.returned.status && (result.returned.status !== "Success" && result.returned.status !== "PartialSuccess")) { + if (typeof (result.returned) === "string") { + return reject(new Error(result.returned)); + } + else if (typeof (result.returned) === "object") { + if (result.returned.status && result.returned.failed) { + return reject(new Error(`${result.returned.status}: ${JSON.stringify(result.returned.failed)}`)); + } + else { + return reject(new Error(result.returned)); + } + } + } + agmResult = result.returned; + handleResult(); + }; + this.invokeMethodCore(methodName, args, "best", { methodResponseTimeoutMs }) + .then(responseHandler) + .catch((err) => reject(err)); + } + async invokeMethodCore(methodName, args, target, options) { + options = options !== null && options !== void 0 ? options : {}; + if (typeof options.methodResponseTimeoutMs === "undefined") { + options.methodResponseTimeoutMs = INTEROP_METHOD_WAIT_TIMEOUT_MS; + } + if (typeof options.waitTimeoutMs === "undefined") { + options.waitTimeoutMs = INTEROP_METHOD_WAIT_TIMEOUT_MS; + } + if (this.isCommandMethodPresent()) { + return await this.config.agm.invoke(LayoutsCommandMethod, { command: methodName, data: args }, target, options); + } + else { + return await this.config.agm.invoke(`T42.ACS.${methodName}`, args, target, options); + } + } + getObjectValues(obj) { + if (!obj) { + return []; + } + return Object.keys(obj).map((k) => obj[k]); + } + isCommandMethodPresent() { + return this.config.agm.methods().some((method) => method.name === LayoutsCommandMethod); + } + } + + class ACSStream { + constructor(agm, callbacks) { + this.agm = agm; + this.callbacks = callbacks; + this.StreamName = "T42.ACS.OnLayoutEvent"; + this.ready = new Promise((resolve, reject) => { + this.resolveReady = resolve; + this.rejectReady = reject; + }); + this.gotSnapshot = new Promise((resolve, reject) => { + this.resolveGotSnapshot = resolve; + this.rejectGotSnapshot = reject; + }); + } + subscribe(noRetry) { + const transform = (obj) => { + return this.getObjectValues(obj).map((t) => transformACSLayout(t)); + }; + if (!this.checkForLayoutEventMethod()) { + if (noRetry) { + this.resolveReady(); + } + setTimeout(() => { + this.subscribe(true); + }, 500); + } + else { + this.agm.subscribe(this.StreamName, { waitTimeoutMs: 10000 }) + .then((subs) => { + subs.onData((args) => { + const data = args.data; + if (data.IsSnapshot) { + this.resolveGotSnapshot(); + } + this.addLayouts(transform(data.OnLayoutAdded), data.IsSnapshot); + this.removeLayouts(transform(data.OnLayoutRemoved)); + this.changeLayouts(transform(data.OnLayoutChanged)); + this.renameLayouts(transform(data.OnLayoutRenamed)); + this.restoredLayout(transform(data.OnLayoutRestored)); + this.callbacks.execute("streamEvent", data); + }); + subs.onFailed((err) => { + const msg = `Can not subscribe to "${this.StreamName}" stream - ${JSON.stringify(err)}`; + this.rejectReady(msg); + this.rejectGotSnapshot(msg); + }); + this.resolveReady(); + }) + .catch((err) => { + const msg = `Error subscribing to "${this.StreamName}" stream - ${JSON.stringify(err)}`; + this.rejectReady(msg); + this.rejectGotSnapshot(msg); + }); + } + } + onEvent(callback) { + return this.callbacks.add("streamEvent", callback); + } + waitFor(token, timeout) { + if (!timeout) { + timeout = 30000; + } + return new Promise((resolve, reject) => { + let done = false; + const unsubscribe = this.onEvent((streamEvent) => { + if (streamEvent.Token === token) { + done = true; + unsubscribe(); + resolve(); + } + }); + setTimeout(() => { + if (!done) { + reject("timed out"); + } + }, timeout); + }); + } + checkForLayoutEventMethod() { + try { + return this.agm + .methods() + .map((m) => m.name) + .indexOf(this.StreamName) !== -1; + } + catch (e) { + return false; + } + } + addLayouts(layoutsData, isSnapshot) { + if (!layoutsData) { + return; + } + const createAndNotifyLayout = (layoutData) => { + const layout = new LayoutImpl(layoutData); + store.add(layout); + this.callbacks.execute("added", layout); + }; + layoutsData.forEach((layoutData) => { + if (isSnapshot) { + const found = store.first((existingLayout) => this.compareLayouts(existingLayout, layoutData)); + if (!found) { + createAndNotifyLayout(layoutData); + } + } + else { + createAndNotifyLayout(layoutData); + } + }); + } + removeLayouts(removedLayouts) { + if (!removedLayouts) { + return; + } + removedLayouts.forEach((removedLayout) => { + store.removeWhere((existingLayout) => !this.compareLayouts(existingLayout, removedLayout)); + this.callbacks.execute("removed", removedLayout); + }); + } + changeLayouts(changedLayouts) { + if (!changedLayouts) { + return; + } + changedLayouts.forEach((changedLayout) => { + store.removeWhere((existingLayout) => !this.compareLayouts(existingLayout, changedLayout)); + store.add(new LayoutImpl(changedLayout)); + this.callbacks.execute("changed", changedLayout); + }); + } + renameLayouts(renamedLayouts) { + if (!renamedLayouts) { + return; + } + renamedLayouts.forEach((renamedLayout) => { + const existingLayout = store.first((current) => this.compareLayouts(current, { type: renamedLayout.type, name: renamedLayout.oldName })); + if (!existingLayout) { + throw Error(`received rename event for unknown layout with type ${renamedLayout.type} and name ${renamedLayout.oldName}`); + } + existingLayout.name = renamedLayout.newName; + this.callbacks.execute("renamed", existingLayout); + }); + } + compareLayouts(layout1, layout2) { + return layout1.name === layout2.name && layout1.type === layout2.type; + } + getObjectValues(obj) { + if (!obj) { + return []; + } + return Object.keys(obj).map((k) => obj[k]); + } + restoredLayout(restoredLayouts) { + if (!restoredLayouts) { + return; + } + restoredLayouts.forEach((restoredLayout) => { + const existingLayout = store.first((current) => this.compareLayouts(current, { type: restoredLayout.type, name: restoredLayout.name })); + this.callbacks.execute("restored", existingLayout); + }); + } + } + + function LayoutsFactory (config) { + if (!config.agm) { + throw Error("config.agm is required"); + } + if (!config.logger) { + throw Error("config.logger is required"); + } + config.mode = config.mode || "slim"; + const logger = config.logger; + const callbacks = CallbackRegistryFactory(); + let acsStream; + if (config.mode === "full" || "fullWaitSnapshot") { + acsStream = new ACSStream(config.agm, callbacks); + } + return new LayoutsAPIImpl(config, acsStream, callbacks, logger); + } + + const T42DisplayCommand = "T42.Displays.Command"; + const T42DisplayOnEvent = "T42.Displays.OnEvent"; + class DisplayManager { + constructor(_agm, _logger) { + this._agm = _agm; + this._logger = _logger; + this._registry = CallbackRegistryFactory(); + this._registered = false; + this.all = async () => { + const displays = await this.callGD(DisplayCommand.GetAll, {}); + return displays.map(this.decorateDisplay); + }; + this.get = async (id) => { + const display = await this.callGD(DisplayCommand.Get, { id }); + return this.decorateDisplay(display); + }; + this.getPrimary = async () => { + const primary = (await this.all()).find((d) => d.isPrimary); + return primary; + }; + this.capture = async (options) => { + const screenshot = await this.callGD(DisplayCommand.Capture, { ...options }); + return screenshot; + }; + this.captureAll = async (options) => { + const screenshots = await this.callGD(DisplayCommand.CaptureAll, { ...options }); + return screenshots; + }; + this.getMousePosition = async () => { + const point = await this.callGD(DisplayCommand.GetMousePosition); + return point; + }; + this.callGD = async (command, options) => { + const invocationResult = await this._agm.invoke(T42DisplayCommand, { options: { ...options }, command }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return invocationResult.returned.data; + }; + this.decorateDisplay = (original) => { + const decoratedDisplay = { + ...original, + capture: (size) => this.capture({ id: original.id, size }) + }; + const workAreaAsAny = decoratedDisplay.workArea; + workAreaAsAny.x = workAreaAsAny.left; + workAreaAsAny.y = decoratedDisplay.workArea.top; + return decoratedDisplay; + }; + } + getByWindowId(id) { + const current = this.callGD(DisplayCommand.GetByWindowId, { id }); + return current; + } + onDisplayChanged(cb) { + this.register(); + return this._registry.add("on-display-changed", cb); + } + register() { + if (this._registered) { + return; + } + this._registered = true; + this._agm.register(T42DisplayOnEvent, (args, caller) => { + const event = args.event; + const data = args.data; + switch (event) { + case "display-changed": + this._registry.execute("on-display-changed", data.displays.map(this.decorateDisplay)); + break; + default: + this._logger.warn(`unknown event - ${event}`); + break; + } + }); + } + } + var DisplayCommand; + (function (DisplayCommand) { + DisplayCommand["Capture"] = "capture"; + DisplayCommand["CaptureAll"] = "captureAll"; + DisplayCommand["GetAll"] = "getAll"; + DisplayCommand["Get"] = "get"; + DisplayCommand["GetByWindowId"] = "getByWindowId"; + DisplayCommand["GetMousePosition"] = "getMousePosition"; + })(DisplayCommand || (DisplayCommand = {})); + + class SingleChannelID { + constructor(channel) { + this.channel = channel; + } + get isJoinedToAnyChannel() { + return !!this.channel; + } + isOnChannel(channel) { + return this.channel === channel; + } + leaveChannel(channel) { + if (channel === undefined || this.channel === channel) { + this.channel = undefined; + } + } + joinChannel(channel) { + this.channel = channel; + } + all() { + if (this.channel) { + return [this.channel]; + } + return []; + } + toString() { + return this.channel; + } + equals(other) { + if (other instanceof SingleChannelID) { + return this.channel === other.channel; + } + return false; + } + } + class MultiChannelId { + constructor(channels) { + this.ChannelDelimiter = "+++"; + if (!channels) { + this.channels = []; + } + else if (typeof channels === "string") { + this.channels = channels === null || channels === void 0 ? void 0 : channels.split(this.ChannelDelimiter).filter(Boolean); + } + else { + this.channels = (channels !== null && channels !== void 0 ? channels : []).filter(Boolean); + } + } + get isJoinedToAnyChannel() { + return this.channels.length > 0; + } + isOnChannel(channel) { + return this.channels.includes(channel); + } + joinChannel(channel) { + const newChannels = new MultiChannelId(channel); + newChannels.all().forEach((newChannel) => { + if (!this.channels.includes(newChannel)) { + this.channels.push(newChannel); + } + }); + } + leaveChannel(channel) { + const channelsToLeave = new MultiChannelId(channel !== null && channel !== void 0 ? channel : this.channels); + channelsToLeave.all().forEach((c) => { + this.channels = this.channels.filter((ch) => ch !== c); + }); + } + all() { + return this.channels; + } + toString() { + if (this.channels.length === 0) { + return undefined; + } + return this.channels.join(this.ChannelDelimiter); + } + equals(other) { + if (other instanceof MultiChannelId) { + return this.channels.length === other.channels.length && + this.channels.every((c, i) => c === other.channels[i]); + } + return false; + } + } + + let interop; + let myInstanceId; + let logger; + const T42_ANNOUNCE_METHOD_NAME = "T42.Channels.Announce"; + const T42_COMMAND_METHOD_NAME = "T42.Channels.Command"; + async function setupInterop(interopLib, channels, loggerAPI) { + var _a, _b; + logger = loggerAPI; + interop = interopLib; + if (typeof window !== "undefined") { + if (window.glue42gd) { + myInstanceId = window.glue42gd.windowId; + } + } + if (!myInstanceId) { + myInstanceId = interopLib.instance.instance; + } + await interop.register(T42_COMMAND_METHOD_NAME, (args) => { + const command = args.command; + if (!command) { + throw new Error("missing command argument"); + } + logger.trace(`received command "${command}" with ${JSON.stringify(args)}`); + if (command === "join") { + const id = args.channel; + if (!id) { + throw new Error("missing argument id"); + } + return channels.joinNoSelectorSwitch(id); + } + if (command === "leave") { + return channels.leaveNoSelectorSwitch(); + } + if (command === "get") { + const id = channels.current(); + return { id }; + } + if (command === "restrictions-changed") { + const restrictions = args.restrictions; + const targetWindowId = args.swId; + channels.handleRestrictionsChanged(restrictions, targetWindowId); + return; + } + if (command === "isFdc3DataWrappingSupported") { + return { isSupported: true }; + } + if (command === "join-multi") { + const channelsToJoin = args.channelsToJoin; + if (!channelsToJoin) { + throw new Error("missing argument channelsToJoin"); + } + return channels.joinNoSelectorSwitch(new MultiChannelId(channelsToJoin).toString()); + } + if (command === "leave-multi") { + const channelsToLeave = args.channelsToLeave; + return channels.leaveNoSelectorSwitch(new MultiChannelId(channelsToLeave).toString()); + } + throw new Error(`unknown command ${command}`); + }); + const result = await interop.invoke(T42_ANNOUNCE_METHOD_NAME, { swId: myInstanceId, instance: interop.instance.instance }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_RESPONSE_TIMEOUT_MS + }); + if ((_a = result.returned) === null || _a === void 0 ? void 0 : _a.restrictions) { + channels.handleRestrictionsChanged((_b = result.returned) === null || _b === void 0 ? void 0 : _b.restrictions, myInstanceId); + } + return result.returned; + } + async function sendLeaveChannel(channel, winId) { + var _a; + await invoke("leaveChannel", { channel }, (_a = winId !== null && winId !== void 0 ? winId : winId) !== null && _a !== void 0 ? _a : myInstanceId); + } + async function sendSwitchChannelUI(channel, winId) { + await invoke("switchChannel", { newChannel: channel }, winId !== null && winId !== void 0 ? winId : myInstanceId); + } + async function setRestrictions(restrictions) { + var _a; + await invoke("restrict", restrictions, (_a = restrictions.windowId) !== null && _a !== void 0 ? _a : myInstanceId); + } + async function getRestrictionsByWindow(id) { + try { + const result = await invoke("getRestrictions", {}, id !== null && id !== void 0 ? id : myInstanceId); + return result.returned; + } + catch (e) { + } + } + async function setRestrictionsForAllChannels(restrictions) { + var _a; + await invoke("restrictAll", restrictions, (_a = restrictions.windowId) !== null && _a !== void 0 ? _a : myInstanceId); + } + async function getChannelsInfo(filter) { + const result = await invoke("getChannelsInfo", { filter }); + return result.returned; + } + async function addOrRemoveChannel(command, id, color, label) { + await invoke(command, { id, color, label }); + } + async function getChannelInitInfo(config, i) { + if (typeof config.operationMode !== "boolean" && typeof config.operationMode === "string") { + validateMode(config.operationMode); + return { mode: config.operationMode, initialChannel: undefined }; + } + try { + const result = await i.invoke(T42_ANNOUNCE_METHOD_NAME, { command: "getChannelsMode" }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_RESPONSE_TIMEOUT_MS, + }); + const initialChannel = result.returned.initialChannel; + if (result.returned.mode === "single") { + return { + mode: "single", + initialChannel + }; + } + else if (result.returned.mode === "multi") { + return { + mode: "multi", + initialChannel + }; + } + else { + return { + mode: "single", + initialChannel + }; + } + } + catch (e) { + return { mode: "single", initialChannel: undefined }; + } + } + function invoke(command, data, swId) { + const args = { command, data }; + if (swId) { + args.swId = swId; + } + return interop.invoke(T42_ANNOUNCE_METHOD_NAME, args, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_RESPONSE_TIMEOUT_MS, + }); + } + function validateMode(mode) { + if (mode !== "single" && mode !== "multi") { + throw new Error(`Invalid mode: ${mode}`); + } + } + + const CONTEXT_PREFIX = "___channel___"; + const LATEST_FDC3_TYPE = "latest_fdc3_type"; + class BaseSharedContextSubscriber { + constructor(contexts) { + this.contexts = contexts; + } + subscribe(callback) { + this.callback = callback; + } + subscribeFor(name, callback) { + if (!this.isChannel(name)) { + return Promise.reject(new Error(`Channel with name: ${name} doesn't exist!`)); + } + const contextName = this.createContextName(name); + return this.contexts.subscribe(contextName, (data, _, __, ___, extraData) => { + callback(data.data, data, extraData === null || extraData === void 0 ? void 0 : extraData.updaterId); + }); + } + all() { + const contextNames = this.contexts.all(); + const channelContextNames = contextNames.filter((contextName) => contextName.startsWith(CONTEXT_PREFIX)); + const channelNames = channelContextNames.map((channelContextName) => channelContextName.substr(CONTEXT_PREFIX.length)); + return channelNames; + } + async getContextData(name) { + if (!this.isChannel(name)) { + throw new Error(`A channel with name: ${name} doesn't exist!`); + } + const contextName = this.createContextName(name); + const contextData = await this.contexts.get(contextName); + if (contextData[LATEST_FDC3_TYPE]) { + return this.getContextWithFdc3Data(contextData); + } + else { + delete contextData[LATEST_FDC3_TYPE]; + } + return contextData; + } + updateChannel(name, data) { + const contextName = this.createContextName(name); + return this.contexts.update(contextName, data); + } + updateData(name, data) { + const contextName = this.createContextName(name); + const fdc3Type = this.getFDC3Type(data); + if (this.contexts.setPathSupported) { + const pathValues = Object.keys(data).map((key) => { + return { + path: `data.` + key, + value: data[key] + }; + }); + if (fdc3Type) { + pathValues.push({ path: LATEST_FDC3_TYPE, value: fdc3Type }); + } + return this.contexts.setPaths(contextName, pathValues); + } + else { + if (fdc3Type) { + data[LATEST_FDC3_TYPE] = fdc3Type; + } + return this.contexts.update(contextName, { data }); + } + } + setPaths(name, paths) { + const contextName = this.createContextName(name); + if (this.contexts.setPathSupported) { + const pathValues = paths.map((p) => { + return { + path: `data.` + p.path, + value: p.value + }; + }); + pathValues.map((p) => { + const fdc3Type = this.getFDC3Type(p.value); + if (fdc3Type) { + pathValues.push({ path: LATEST_FDC3_TYPE, value: fdc3Type }); + } + }); + return this.contexts.setPaths(contextName, pathValues); + } + else { + throw new Error("setPaths is not supported!"); + } + } + clearContextData(name) { + const contextName = this.createContextName(name); + return this.contexts.update(contextName, { data: {}, [LATEST_FDC3_TYPE]: undefined }); + } + isChannel(name) { + return this.all().some((channelName) => channelName === name); + } + async remove(name) { + if (!this.isChannel(name)) { + throw new Error(`A channel with name: ${name} doesn't exist!`); + } + const contextName = this.createContextName(name); + await this.contexts.destroy(contextName); + } + createContextName(name) { + return CONTEXT_PREFIX + name; + } + getFDC3Type(data) { + const fdc3PropsArr = Object.keys(data).filter((key) => key.indexOf("fdc3_") === 0); + if (fdc3PropsArr.length === 0) { + return; + } + if (fdc3PropsArr.length > 1) { + throw new Error("FDC3 does not support updating of multiple context keys"); + } + return fdc3PropsArr[0].split("_").slice(1).join("_"); + } + getContextWithFdc3Data(channelContext) { + const { latest_fdc3_type, ...rest } = channelContext; + const parsedType = latest_fdc3_type.split("&").join("."); + const fdc3Context = { type: parsedType, ...rest.data[`fdc3_${latest_fdc3_type}`] }; + delete rest.data[`fdc3_${latest_fdc3_type}`]; + const context = { + name: channelContext.name, + meta: channelContext.meta, + data: { + ...rest.data, + fdc3: fdc3Context + } + }; + return context; + } + } + class MultiSharedContextSubscriber extends BaseSharedContextSubscriber { + constructor() { + super(...arguments); + this.currentlySubscribedChannels = []; + this.unsubscribeMap = {}; + } + async switchChannel(id) { + const newChannels = new MultiChannelId(id).all(); + for (const newChannel of newChannels) { + if (!this.currentlySubscribedChannels.includes(newChannel)) { + await this.subscribeToChannel(newChannel); + } + } + } + async leave(id) { + const channelsToLeave = new MultiChannelId(id).all(); + for (const newChannel of channelsToLeave) { + if (this.currentlySubscribedChannels.includes(newChannel)) { + this.unsubscribeFromChannel(newChannel); + } + } + } + async updateData(id, data) { + const channels = new MultiChannelId(id).all(); + for (const channel of channels) { + await super.updateData(channel, data); + } + } + async setPaths(id, paths) { + const channels = new MultiChannelId(id).all(); + for (const channel of channels) { + await super.setPaths(channel, paths); + } + } + isChannel(name) { + const channels = new MultiChannelId(name).all(); + return channels.every((channel) => super.isChannel(channel)); + } + async subscribeToChannel(name) { + const contextName = this.createContextName(name); + const usub = await this.contexts.subscribe(contextName, (data, _, __, ___, extraData) => { + if (this.callback) { + this.callback(data.data, data, extraData === null || extraData === void 0 ? void 0 : extraData.updaterId); + } + }); + this.currentlySubscribedChannels.push(name); + this.unsubscribeMap[contextName] = usub; + } + async unsubscribeFromChannel(name) { + const contextName = this.createContextName(name); + const unsub = this.unsubscribeMap[contextName]; + if (unsub) { + unsub(); + delete this.unsubscribeMap[contextName]; + } + this.currentlySubscribedChannels = this.currentlySubscribedChannels.filter((channel) => channel !== name); + } + } + class SharedContextSubscriber extends BaseSharedContextSubscriber { + async switchChannel(name) { + this.unsubscribe(); + const contextName = this.createContextName(name); + this.unsubscribeFunc = await this.contexts.subscribe(contextName, (data, _, __, ___, extraData) => { + if (this.callback) { + this.callback(data.data, data, extraData === null || extraData === void 0 ? void 0 : extraData.updaterId); + } + }); + } + async leave() { + if (this.callback) { + this.callback({}, undefined); + } + this.unsubscribe(); + } + unsubscribe() { + if (this.unsubscribeFunc) { + this.unsubscribeFunc(); + this.unsubscribeFunc = undefined; + } + } + } + + const validateFdc3Options = (options) => { + if (typeof options !== "object" || Array.isArray(options)) { + throw new Error(`Provide options as an object`); + } + if (options.contextType && (typeof options.contextType !== "string" || !options.contextType.length)) { + throw new Error(`Provide options.contextType as a non-empty string`); + } + }; + + class ChannelsImpl { + constructor(interop, getWindowsAPI, getAppManagerAPI, logger) { + this.interop = interop; + this.getWindowsAPI = getWindowsAPI; + this.getAppManagerAPI = getAppManagerAPI; + this.logger = logger; + this.subsKey = "subs"; + this.changedKey = "changed"; + this.channelsChangedKey = "channelsChanged"; + this.isInitialJoin = true; + this.registry = CallbackRegistryFactory(); + this.pendingReplays = {}; + this.pendingRestrictionCallbacks = new Map(); + } + async getMyChannels(options) { + if (!this.currentChannelID) { + return Promise.resolve([]); + } + if (this.currentChannelID.all().length === 0) { + return Promise.resolve([]); + } + const result = []; + for (const channel of this.currentChannelID.all()) { + result.push(await this.get(channel, options)); + } + return result; + } + async init(shared, mode, initial) { + this.mode = mode; + this.shared = shared; + this.shared.subscribe(this.handler.bind(this)); + this.subscribeForChannelRestrictionsChange(); + let initialChannel = initial; + if (typeof window !== "undefined" && typeof window.glue42gd !== "undefined") { + initialChannel = window.glue42gd.initialChannel; + } + this.currentChannelID = this.getID(initialChannel); + this.logger.trace(`initialized with mode: "${mode}" and initial channel: "${initialChannel}"`); + if (this.currentChannelID.isJoinedToAnyChannel) { + this.logger.trace(`joining initial channel: "${this.currentChannelID.toString()}"`); + await this.joinNoSelectorSwitch(this.currentChannelID.toString()); + } + } + subscribe(callback, options) { + if (typeof callback !== "function") { + throw new Error("Please provide the callback as a function!"); + } + const id = Utils.generateId(); + this.pendingReplays[id] = true; + const wrappedCallback = (options === null || options === void 0 ? void 0 : options.contextType) + ? this.getWrappedSubscribeCallbackWithFdc3Type(callback, id, options.contextType) + : this.getWrappedSubscribeCallback(callback, id); + if (this.lastUpdate) { + let lastUpdate = Object.assign({}, this.lastUpdate); + setTimeout(async () => { + if (this.pendingReplays[id]) { + if (this.lastUpdate) { + lastUpdate = this.lastUpdate; + } + wrappedCallback(lastUpdate.context.data, lastUpdate.context, lastUpdate.updaterId); + } + delete this.pendingReplays[id]; + }, 0); + } + const unsub = this.registry.add(this.subsKey, wrappedCallback); + return () => { + this.pendingReplays[id] = false; + this.pendingRestrictionCallbacks.delete(id); + unsub(); + }; + } + async subscribeFor(name, callback, options) { + if (typeof name !== "string") { + throw new Error("Please provide the name as a string!"); + } + if (typeof callback !== "function") { + throw new Error("Please provide the callback as a function!"); + } + const id = Utils.generateId(); + const wrappedCallback = (options === null || options === void 0 ? void 0 : options.contextType) + ? this.getWrappedSubscribeCallbackWithFdc3Type(callback, id, options.contextType) + : this.getWrappedSubscribeCallback(callback, id); + const unsub = await this.shared.subscribeFor(name, wrappedCallback); + return () => { + this.pendingRestrictionCallbacks.delete(id); + unsub(); + }; + } + async publish(data, options) { + if (typeof data !== "object") { + throw new Error("Please provide the data as an object!"); + } + if (options) { + this.validatePublishOptions(options); + } + if (typeof options === "object") { + return this.publishWithOptions(data, options); + } + const channelName = typeof options === "string" ? options : this.currentChannelID.toString(); + if (!channelName) { + throw new Error("Not joined to any channel!"); + } + if (!this.shared.isChannel(channelName)) { + return Promise.reject(new Error(`A channel with name: ${channelName} doesn't exist!`)); + } + if (this.mode === "multi") { + const channelsToPublish = new MultiChannelId(channelName).all(); + const restrictedChannels = []; + for (const cn of channelsToPublish) { + const canPublish = (await this.getRestrictionsByChannel(cn)).write; + if (!canPublish) { + restrictedChannels.push(cn); + continue; + } + await this.shared.updateData(cn, data); + } + if (restrictedChannels.length > 0) { + const restrictedChannelsErr = `Unable to publish due to restrictions to the following channels: ${restrictedChannels.join(", ")}`; + if (restrictedChannels.length === channelsToPublish.length) { + throw new Error(restrictedChannelsErr); + } + else { + this.logger.warn(restrictedChannelsErr); + } + } + } + else { + const canPublish = (await this.getRestrictionsByChannel(channelName)).write; + if (!canPublish) { + throw new Error(`Window does not have permission to write to channel ${channelName}`); + } + return this.shared.updateData(channelName, data); + } + } + async setPaths(paths, name) { + if (name) { + if (typeof name !== "string") { + throw new Error("Please provide the name as a string!"); + } + if (!this.shared.isChannel(name)) { + return Promise.reject(new Error(`A channel with name: ${name} doesn't exist!`)); + } + if (!(await this.getRestrictionsByChannel(name)).write) { + throw new Error(`Window does not have permission to write to channel ${name}`); + } + return this.shared.setPaths(name, paths); + } + if (!this.currentChannelID) { + throw new Error("Not joined to any channel!"); + } + if (!(await this.getRestrictionsByChannel(this.currentChannelID.toString())).write) { + throw new Error(`Window does not have permission to write to channel ${this.currentChannelID.toString()}`); + } + if (!Array.isArray(paths)) { + throw new Error("Path Values argument is not a valid array"); + } + paths.forEach((path) => { + this.validatePathArgs(path); + }); + return this.shared.setPaths(this.currentChannelID.toString(), paths); + } + async setPath(path, name) { + if (name) { + if (typeof name !== "string") { + throw new Error("Please provide the name as a string!"); + } + if (!this.shared.isChannel(name)) { + return Promise.reject(new Error(`A channel with name: ${name} doesn't exist!`)); + } + if (!(await this.getRestrictionsByChannel(name)).write) { + throw new Error(`Window does not have permission to write to channel ${name}`); + } + return this.shared.setPaths(name, [path]); + } + if (!this.currentChannelID) { + throw new Error("Not joined to any channel!"); + } + if (!(await this.getRestrictionsByChannel(this.currentChannelID.toString())).write) { + throw new Error(`Window does not have permission to write to channel ${this.currentChannelID.toString()}`); + } + this.validatePathArgs(path); + return this.shared.setPaths(this.currentChannelID.toString(), [path]); + } + all() { + const channelNames = this.shared.all(); + return Promise.resolve(channelNames); + } + async list() { + const channelNames = await this.all(); + const channelContexts = await Promise.all(channelNames.map((channelName) => this.get(channelName))); + return channelContexts; + } + async get(name, options) { + if (typeof name !== "string") { + return Promise.reject(new Error("Please provide the channel name as a string!")); + } + if (!(options === null || options === void 0 ? void 0 : options.contextType)) { + return this.shared.getContextData(name); + } + validateFdc3Options(options); + const context = await this.shared.getContextData(name); + return this.getContextWithFdc3Type(context, options.contextType); + } + getMy(options) { + if (!this.currentChannelID) { + return Promise.resolve(undefined); + } + if (this.currentChannelID.all().length === 0) { + return Promise.resolve(undefined); + } + return this.get(this.currentChannelID.all()[0], options); + } + async join(name, windowId) { + if (windowId !== undefined && windowId !== null) { + this.validateWindowIdArg(windowId); + this.logger.trace(`joining channel ${name} for window: ${windowId}`); + return sendSwitchChannelUI(name, windowId); + } + return this.joinCore(name); + } + async joinNoSelectorSwitch(channelName) { + this.logger.trace(`joining channel "${channelName}" from command`); + return this.joinCore(channelName, false); + } + leave(options) { + this.logger.trace(`leaving channel with options: ${JSON.stringify(options)}`); + let windowId; + let channelName; + if (typeof options === "string") { + windowId = options; + } + else if (typeof options === "object" && !Array.isArray(options) && options !== null && options !== undefined) { + if (options.windowId) { + windowId = options.windowId; + } + if (options.channel) { + channelName = options.channel; + } + } + if (this.mode === "multi") { + return this.leaveWhenMulti(channelName, windowId); + } + else { + return this.leaveWhenSingle(channelName, windowId); + } + } + leaveNoSelectorSwitch(channelName) { + this.logger.trace(`leaving channel "${channelName}" from command`); + return this.leaveCore(false, channelName); + } + current() { + return this.currentChannelID.toString(); + } + my() { + return this.current(); + } + myChannels() { + var _a; + return (_a = this.currentChannelID.all()) !== null && _a !== void 0 ? _a : []; + } + onChannelsChanged(callback) { + if (typeof callback !== "function") { + throw new Error("Please provide the callback as a function!"); + } + let timeoutId; + const current = this.current(); + if (current) { + timeoutId = setTimeout(() => { + callback(this.myChannels()); + }, 0); + } + const un = this.registry.add(this.channelsChangedKey, callback); + return () => { + un(); + clearTimeout(timeoutId); + }; + } + changed(callback) { + if (typeof callback !== "function") { + throw new Error("Please provide the callback as a function!"); + } + const current = this.current(); + if (current) { + setTimeout(() => { + callback(this.current()); + }, 0); + } + return this.registry.add(this.changedKey, () => { + callback(this.current()); + }); + } + onChanged(callback) { + return this.changed(callback); + } + async add(info) { + var _a; + if (typeof info !== "object") { + throw new Error("Please provide the info as an object!"); + } + if (typeof info.name === "undefined") { + throw new Error("info.name is missing!"); + } + if (typeof info.name !== "string") { + throw new Error("Please provide the info.name as a string!"); + } + if (typeof info.meta === "undefined") { + throw new Error("info.meta is missing!"); + } + if (typeof info.meta !== "object") { + throw new Error("Please provide the info.meta as an object!"); + } + if (typeof info.meta.color === "undefined") { + throw new Error("info.meta.color is missing!"); + } + if (typeof info.meta.color !== "string") { + throw new Error("Please provide the info.meta.color as a string!"); + } + const context = { + name: info.name, + meta: info.meta || {}, + data: info.data || {} + }; + this.logger.trace(`adding channel: ${info.name}`); + await addOrRemoveChannel("addChannel", info.name, info.meta.color, (_a = info.meta) === null || _a === void 0 ? void 0 : _a.label); + await this.shared.updateChannel(info.name, context); + return context; + } + async remove(channel) { + if (typeof channel !== "string") { + throw new Error("Please provide the channel name as a string!"); + } + this.logger.trace(`removing channel: ${channel}`); + await this.shared.remove(channel); + await addOrRemoveChannel("removeChannel", channel); + } + async getWindowsOnChannel(channel) { + this.validateChannelArg(channel); + const windowInfos = await this.getWindowsWithChannels({ channels: [channel] }); + return windowInfos.map((w) => w.window); + } + async getWindowsWithChannels(filter) { + this.validateWindowsWithChannelsFilter(filter); + try { + const info = await getChannelsInfo(filter); + const windowsAPI = this.getWindowsAPI(); + if (info === null || info === void 0 ? void 0 : info.windows) { + return info.windows.reduce((memo, windowInfo) => { + const window = windowsAPI.findById(windowInfo.windowId); + memo.push({ + window, + channel: windowInfo.channel, + application: windowInfo.application + }); + return memo; + }, []); + } + } + catch (er) { + this.logger.error(`Error getting all channel enabled windows. This method is available since Glue42 3.12`, er); + } + return []; + } + async restrict(restriction) { + this.validateRestrictionConfig(restriction); + return setRestrictions(restriction); + } + async getRestrictions(windowId) { + if (windowId) { + this.validateWindowIdArg(windowId); + } + return getRestrictionsByWindow(windowId); + } + async restrictAll(restriction) { + this.validateRestrictionConfig(restriction); + return setRestrictionsForAllChannels(restriction); + } + handleRestrictionsChanged(restrictions, windowId) { + this.registry.execute("restrictions-changed", { + restrictions, + windowId + }); + } + async clearChannelData(channel) { + const channelName = typeof channel === "string" ? channel : this.currentChannelID.toString(); + if (!channelName) { + return; + } + if (!this.shared.isChannel(channelName)) { + return; + } + const canPublish = (await this.getRestrictionsByChannel(channelName)).write; + if (!canPublish) { + return; + } + return this.shared.clearContextData(channelName); + } + handler(data, context, updaterId) { + if (!context && !updaterId) { + this.lastUpdate = undefined; + return; + } + this.lastUpdate = { context, updaterId }; + this.pendingReplays = {}; + this.registry.execute(this.subsKey, data, context, updaterId); + } + async joinCore(name, changeSelector = true) { + this.logger.trace(`joining channel "${name}" ${changeSelector ? "" : "from command"}`); + if (typeof name !== "string") { + throw new Error("Please provide the channel name as a string!"); + } + const newId = this.getID(name); + if (!this.isInitialJoin && this.currentChannelID.isOnChannel(newId.toString())) { + this.logger.trace(`already on channel: "${name}" ${changeSelector ? "" : "from command"}`); + return; + } + this.isInitialJoin = false; + await Promise.all(newId.all().map((n) => this.verifyChannelExists(n))); + this.currentChannelID.joinChannel(name); + this.lastUpdate = undefined; + this.logger.trace(`switching channel context to: "${name}" ${changeSelector ? "" : "from command"}`); + await this.shared.switchChannel(this.currentChannelID.toString()); + if (changeSelector) { + this.logger.trace(`switching UI channel to: "${name}" ${changeSelector ? "" : "from command"}`); + await sendSwitchChannelUI(name); + this.logger.trace(`switched UI channel to: "${name}" ${changeSelector ? "" : "from command"}`); + } + this.raiseChannelsChangedEvents(); + this.logger.trace(`joined channel: ${name} ${changeSelector ? "" : "from command"} - current channel/s: ${this.currentChannelID.toString()}`); + } + async verifyChannelExists(name) { + const doesChannelExist = (channelName) => { + const channelNames = this.shared.all(); + return channelNames.includes(channelName); + }; + if (!doesChannelExist(name)) { + const channelExistsPromise = new Promise((resolve, reject) => { + const intervalId = setInterval(() => { + if (doesChannelExist(name)) { + clearTimeout(timeoutId); + clearInterval(intervalId); + resolve(); + } + }, 100); + const timeoutId = setTimeout(() => { + clearInterval(intervalId); + return reject(new Error(`A channel with name: ${name} doesn't exist!`)); + }, 3000); + }); + await channelExistsPromise; + } + } + async leaveCore(changeSelector = true, channelID) { + if (!this.currentChannelID.isJoinedToAnyChannel) { + this.logger.trace(`leave called ${changeSelector ? "" : "from command"} when not joined to any channel change selector`); + return; + } + if (channelID && !this.currentChannelID.isOnChannel(channelID)) { + this.logger.trace(`leave called ${changeSelector ? "" : "from command"} when not joined to channel: "${channelID}"`); + return; + } + this.logger.trace(`leaving context channel: "${channelID}" ${changeSelector ? "" : "from command"}`); + this.currentChannelID.leaveChannel(channelID); + await this.shared.leave(channelID); + this.lastUpdate = undefined; + this.raiseChannelsChangedEvents(); + if (changeSelector) { + this.logger.trace(`switching UI channel to: "${channelID}" ${changeSelector ? "" : "from command"}`); + await sendSwitchChannelUI(this.currentChannelID.toString()); + this.logger.trace(`switched UI channel to: "${channelID}" ${changeSelector ? "" : "from command"}`); + } + this.logger.trace(`left single channel: "${channelID}" ${changeSelector ? "" : "from command"} - current channel/s: "${this.currentChannelID.toString()}"`); + return Promise.resolve(); + } + async leaveCoreMulti(changeSelector = true, channelID) { + this.logger.trace(`leaving multi channel: "${channelID.toString()}" ${changeSelector ? "" : "from command"}`); + const currentChannels = this.currentChannelID.all(); + const isJoinedToChannel = currentChannels.some((c) => channelID.isOnChannel(c)); + if (!isJoinedToChannel || !this.currentChannelID.isJoinedToAnyChannel) { + this.logger.trace(`leave called ${changeSelector ? "" : "from command"} when not joined to any channel`); + return; + } + const channelName = channelID.toString(); + this.currentChannelID.leaveChannel(channelName); + await this.shared.leave(channelName); + this.lastUpdate = undefined; + this.raiseChannelsChangedEvents(); + if (changeSelector) { + this.logger.trace(`switching UI channel to: "${channelName}" ${changeSelector ? "" : "from command"}`); + await sendLeaveChannel(channelName); + this.logger.trace(`switched UI channel to: "${channelName}" ${changeSelector ? "" : "from command"}`); + } + this.logger.trace(`left multi channel: "${channelName}" ${changeSelector ? "" : "from command"} - current channel/s: ${this.currentChannelID.toString()}`); + return Promise.resolve(); + } + raiseChannelsChangedEvents() { + this.registry.execute(this.changedKey, this.currentChannelID.toString()); + this.registry.execute(this.channelsChangedKey, this.currentChannelID.all()); + } + async getRestrictionsByChannel(channelName) { + var _a; + const restrictions = (_a = this.channelRestrictions) !== null && _a !== void 0 ? _a : await getRestrictionsByWindow(); + if (!restrictions || !Array.isArray(restrictions.channels) || !restrictions.channels.find(c => c.name === channelName)) { + return { + read: true, + write: true + }; + } + const byChannel = restrictions.channels.find(c => c.name === channelName); + return byChannel; + } + onRestrictionsChanged(callback, callbackId, currentChannelName) { + this.pendingRestrictionCallbacks.set(callbackId, { + cb: callback, + channelName: currentChannelName + }); + if (this.onRestrictionsChangedSub) { + return; + } + this.onRestrictionsChangedSub = this.registry.add("restrictions-changed", ({ restrictions }) => { + this.logger.trace(`restrictions changed - ${JSON.stringify(restrictions)}`); + this.pendingRestrictionCallbacks.forEach(({ cb, channelName }, id) => { + const currentChannel = restrictions.channels.find((c) => c.name === channelName); + if (!currentChannel) { + this.logger.trace(`channel "${channelName}" not found in restrictions`); + return; + } + if (currentChannel.read) { + this.pendingRestrictionCallbacks.delete(id); + if (this.pendingRestrictionCallbacks.values.length === 0 && this.onRestrictionsChangedSub) { + this.onRestrictionsChangedSub(); + this.onRestrictionsChangedSub = null; + } + cb(); + } + }); + }); + } + subscribeForChannelRestrictionsChange() { + this.registry.add("restrictions-changed", (r) => { + this.logger.trace(`channel restrictions changed - ${JSON.stringify(r.restrictions)}`); + this.channelRestrictions = r.restrictions; + }); + } + validatePathArgs(path) { + if (!path) { + throw new Error("Please provide a valid path value argument"); + } + if (typeof path !== "object") { + throw new Error(`Path Value argument is not a valid object: ${JSON.stringify(path)}`); + } + if (!path.path) { + throw new Error(`path property is missing from Path Value argument: ${JSON.stringify(path)}`); + } + if (!path.value) { + throw new Error(`value property is missing from Path Value argument: ${JSON.stringify(path)}`); + } + if (typeof path.path !== "string") { + throw new Error(`path property is not a valid string from the Path Value argument: ${JSON.stringify(path)}`); + } + } + validatePublishOptions(options) { + if ((typeof options !== "string" && typeof options !== "object") || Array.isArray(options)) { + throw new Error("Provide options as a string or an object"); + } + if (typeof options === "object") { + this.validatePublishOptionsObject(options); + return; + } + if (options === "string" && !options.length) { + throw new Error("Provide options as a non-empty string"); + } + } + validatePublishOptionsObject(options) { + if (typeof options !== "object" || Array.isArray(options)) { + throw new Error("Provide options as an object"); + } + if (options.name && (typeof options.name !== "string" || !options.name.length)) { + throw new Error("Provide options.name as a non-empty string"); + } + if (Object.keys(options).includes("fdc3") && typeof options.fdc3 !== "boolean") { + throw new Error("Provide options.fdc3 as a boolean"); + } + } + async publishWithOptions(data, options) { + const channelName = options.name || this.currentChannelID.toString(); + if (!this.shared.isChannel(channelName)) { + throw new Error(`A channel with name: ${options.name} doesn't exist!`); + } + if (!channelName) { + throw new Error("Cannot publish to channel, because not joined to a channel!"); + } + const canPublish = (await this.getRestrictionsByChannel(channelName)).write; + if (!canPublish) { + throw new Error(`Window does not have permission to write to channel ${this.currentChannelID.toString()}`); + } + if (!options.fdc3) { + return this.shared.updateData(channelName, data); + } + return this.publishFdc3Data(channelName, data); + } + async publishFdc3Data(channelName, data) { + var _a; + if (typeof data.type !== "string" || !((_a = data.type) === null || _a === void 0 ? void 0 : _a.length)) { + throw new Error("Expected a valid FDC3 Context with compulsory 'type' field"); + } + const { type, ...rest } = data; + const parsedType = type.split(".").join("&"); + const fdc3DataToPublish = { [`fdc3_${parsedType}`]: rest }; + return this.shared.updateData(channelName, fdc3DataToPublish); + } + getWrappedSubscribeCallback(callback, id) { + const wrappedCallback = async (_, context, updaterId) => { + const restrictionByChannel = await this.getRestrictionsByChannel(context.name); + const channelData = this.getDataWithFdc3Encoding(context); + if (restrictionByChannel.read) { + callback(channelData, context, updaterId); + } + else { + this.onRestrictionsChanged(() => { + callback(channelData, context, updaterId); + }, id, context.name); + } + }; + return wrappedCallback; + } + getWrappedSubscribeCallbackWithFdc3Type(callback, id, fdc3Type) { + const didReplay = { replayed: false }; + const wrappedCallback = async (_, context, updaterId) => { + const restrictionByChannel = await this.getRestrictionsByChannel(context.name); + const callbackWithTypesChecks = () => { + const { data, latest_fdc3_type } = context; + const searchedType = `fdc3_${fdc3Type.split(".").join("&")}`; + if (!data[searchedType]) { + return; + } + if (didReplay.replayed) { + return this.parseDataAndInvokeSubscribeCallback({ latestFdc3TypeEncoded: latest_fdc3_type, searchedType: fdc3Type, callback, context, updaterId }); + } + const fdc3Data = { type: fdc3Type, ...data[searchedType] }; + callback({ fdc3: fdc3Data }, context, updaterId); + didReplay.replayed = true; + }; + if (restrictionByChannel.read) { + callbackWithTypesChecks(); + return; + } + this.onRestrictionsChanged(callbackWithTypesChecks, id, context.name); + }; + return wrappedCallback; + } + parseDataAndInvokeSubscribeCallback(args) { + const { latestFdc3TypeEncoded, searchedType, callback, context, updaterId } = args; + const latestPublishedType = latestFdc3TypeEncoded.split("&").join("."); + if (latestPublishedType !== searchedType) { + return; + } + const fdc3Data = { type: searchedType, ...context.data[`fdc3_${latestFdc3TypeEncoded}`] }; + callback({ fdc3: fdc3Data }, context, updaterId); + } + getContextWithFdc3Type(context, searchedType) { + var _a, _b; + if (((_b = (_a = context.data) === null || _a === void 0 ? void 0 : _a.fdc3) === null || _b === void 0 ? void 0 : _b.type) === searchedType) { + return { + name: context.name, + meta: context.meta, + data: { fdc3: context.data.fdc3 } + }; + } + const encodedType = `fdc3_${searchedType.split(".").join("&")}`; + if (!context.data[encodedType]) { + return { + name: context.name, + meta: context.meta, + data: {} + }; + } + const fdc3Context = { type: searchedType, ...context.data[encodedType] }; + return { + name: context.name, + meta: context.meta, + data: { fdc3: fdc3Context } + }; + } + getDataWithFdc3Encoding(context) { + const { data, latest_fdc3_type } = context; + if (!latest_fdc3_type) { + return data; + } + const parsedType = latest_fdc3_type.split("&").join("."); + const latestTypePropName = `fdc3_${latest_fdc3_type}`; + const fdc3Data = { type: parsedType, ...data[latestTypePropName] }; + const { [latestTypePropName]: latestFDC3Type, ...rest } = data; + return { ...rest, fdc3: fdc3Data }; + } + getID(id) { + if (this.mode === "multi") { + return new MultiChannelId(id); + } + else { + return new SingleChannelID(id); + } + } + leaveWhenSingle(channelName, windowId) { + if (windowId) { + this.logger.trace(`leaving single channel "${channelName}" for window: "${windowId}"`); + return sendSwitchChannelUI(undefined, windowId); + } + this.logger.trace(`leaving single channel "${channelName}" for our window`); + return this.leaveCore(true, channelName); + } + async leaveWhenMulti(channelName, windowId) { + if (windowId) { + this.logger.trace(`leaving multi channel "${channelName}" for window: "${windowId}"`); + return sendLeaveChannel(channelName, windowId); + } + else { + const channelId = channelName ? new MultiChannelId(channelName) : this.currentChannelID; + this.logger.trace(`leaving multi channel "${channelId.toString()}" for our window`); + return this.leaveCoreMulti(true, channelId); + } + } + validateWindowIdArg(windowId) { + if (typeof windowId !== "string") { + throw new Error("The window ID must be a non-empty string!"); + } + const windows = this.getWindowsAPI(); + if (!windows.findById(windowId)) { + throw new Error(`Window with ID "${windowId}" doesn't exist!`); + } + } + validateChannelArg(channel) { + if (!channel) { + throw new Error("Please provide a valid Channel name as a non-empty string!"); + } + if (typeof channel !== "string") { + throw new Error("The Channel name must be a non-empty string!"); + } + const channelNames = this.shared.all(); + if (channelNames.every((name) => name !== channel)) { + throw new Error(`Channel "${channel}" does not exist!"`); + } + } + validateWindowsWithChannelsFilter(filter) { + if (filter === undefined) { + return; + } + if (filter === null || Array.isArray(filter) || typeof filter !== "object") { + throw new Error("The `filter` argument must be a valid object!"); + } + } + isRestrictions(restriction) { + return 'name' in restriction; + } + validateRestrictionConfig(restriction) { + if (restriction === null || restriction === undefined || Array.isArray(restriction) || typeof restriction !== "object") { + throw new Error("The `restrictions` argument must be a valid object with Channel restrictions!"); + } + if (this.isRestrictions(restriction) && typeof restriction.name !== "string") { + throw new Error("The `name` restriction property must be a non-empty string!"); + } + if (restriction.read !== null && restriction.read !== undefined && typeof restriction.read !== "boolean") { + throw new Error("The `read` restriction property must be a boolean value!"); + } + if (restriction.write !== null && restriction.write !== undefined && typeof restriction.write !== "boolean") { + throw new Error("The `write` restriction property must be a boolean value!"); + } + if ((restriction.read === null || restriction.read === undefined) && (restriction.write === null || restriction.write === undefined)) { + throw new Error("It's required to set either the `read` or the `write` property of the Channel restriction object!"); + } + if (restriction.windowId !== null && restriction.windowId !== undefined) { + this.validateWindowIdArg(restriction.windowId); + } + } + } + + function factory$4(config, contexts, agm, getWindowsAPI, getAppManagerAPI, logger) { + const channelsReadyPromise = getChannelInitInfo(config, agm) + .then(async ({ mode, initialChannel }) => { + const sharedContexts = mode === "single" ? new SharedContextSubscriber(contexts) : new MultiSharedContextSubscriber(contexts); + if (mode === "multi") { + logger.info(`multi-channel mode enabled`); + } + await channels.init(sharedContexts, mode, initialChannel); + await setupInterop(agm, channels, logger); + return true; + }); + const channels = new ChannelsImpl(agm, getWindowsAPI, getAppManagerAPI, logger); + return { + subscribe: channels.subscribe.bind(channels), + subscribeFor: channels.subscribeFor.bind(channels), + publish: channels.publish.bind(channels), + setPath: channels.setPath.bind(channels), + setPaths: channels.setPaths.bind(channels), + all: channels.all.bind(channels), + list: channels.list.bind(channels), + get: channels.get.bind(channels), + join: channels.join.bind(channels), + leave: channels.leave.bind(channels), + restrict: channels.restrict.bind(channels), + getRestrictions: channels.getRestrictions.bind(channels), + clearChannelData: channels.clearChannelData.bind(channels), + restrictAll: channels.restrictAll.bind(channels), + current: channels.current.bind(channels), + my: channels.my.bind(channels), + changed: channels.changed.bind(channels), + onChanged: channels.onChanged.bind(channels), + add: channels.add.bind(channels), + remove: channels.remove.bind(channels), + getWindowsOnChannel: channels.getWindowsOnChannel.bind(channels), + getWindowsWithChannels: channels.getWindowsWithChannels.bind(channels), + getMy: channels.getMy.bind(channels), + ready: async () => { + await Promise.all([contexts.ready(), channelsReadyPromise]); + }, + get mode() { return channels.mode; }, + getMyChannels: channels.getMyChannels.bind(channels), + myChannels: channels.myChannels.bind(channels), + onChannelsChanged: channels.onChannelsChanged.bind(channels), + }; + } + + const CommandMethod = "T42.Hotkeys.Command"; + const InvokeMethod = "T42.Hotkeys.Invoke"; + const RegisterCommand = "register"; + const UnregisterCommand = "unregister"; + const UnregisterAllCommand = "unregisterAll"; + class HotkeysImpl { + constructor(agm) { + this.agm = agm; + this.registry = CallbackRegistryFactory(); + this.firstHotkey = true; + this.hotkeys = new Map(); + } + async register(info, callback) { + if (typeof info === "undefined") { + throw new Error("Hotkey parameter missing"); + } + if (typeof info === "string") { + info = { + hotkey: info + }; + } + else { + if (!info.hotkey) { + throw new Error("Info's hotkey parameter missing"); + } + info = { + hotkey: info.hotkey, + description: info.description + }; + } + const hkToLower = this.formatHotkey(info.hotkey); + if (this.hotkeys.has(hkToLower)) { + throw new Error(`Shortcut for ${hkToLower} already registered`); + } + if (this.firstHotkey) { + this.firstHotkey = false; + await this.registerInvokeAGMMethod(); + } + this.registry.add(hkToLower, callback); + await this.agm.invoke(CommandMethod, { command: RegisterCommand, hotkey: hkToLower, description: info.description }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + this.hotkeys.set(hkToLower, info); + } + async unregister(hotkey) { + if (typeof hotkey === "undefined") { + throw new Error("hotkey parameter missing"); + } + if (typeof hotkey !== "string") { + throw new Error("hotkey parameter must be string"); + } + const hkToLower = this.formatHotkey(hotkey); + await this.agm.invoke(CommandMethod, { command: UnregisterCommand, hotkey: hkToLower }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + this.hotkeys.delete(hkToLower); + this.registry.clearKey(hkToLower); + } + async unregisterAll() { + await this.agm.invoke(CommandMethod, { command: UnregisterAllCommand }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + this.hotkeys.clear(); + this.registry.clear(); + } + isRegistered(hotkey) { + const hkToLower = this.formatHotkey(hotkey); + return this.hotkeys.has(hkToLower); + } + registerInvokeAGMMethod() { + return this.agm.register(InvokeMethod, (args) => { + const hkToLower = args.key.toLowerCase(); + const info = this.hotkeys.get(hkToLower); + this.registry.execute(hkToLower, info); + }); + } + formatHotkey(hotkey) { + if (hotkey) { + return hotkey.replace(/\s/g, "").toLowerCase(); + } + } + } + + function factory$3(agm) { + const hotkeys = new HotkeysImpl(agm); + return { + register: hotkeys.register.bind(hotkeys), + unregister: hotkeys.unregister.bind(hotkeys), + unregisterAll: hotkeys.unregisterAll.bind(hotkeys), + isRegistered: hotkeys.isRegistered.bind(hotkeys), + ready: () => Promise.resolve() + }; + } + + var version = "6.12.0"; + + var prepareConfig = (options) => { + function getLibConfig(value, defaultMode, trueMode) { + if (typeof value === "boolean" && !value) { + return undefined; + } + const mode = getModeAsString(value, defaultMode, trueMode); + if (typeof mode === "undefined") { + return undefined; + } + if (typeof value === "object") { + value.mode = mode; + return value; + } + return { + mode, + }; + } + function getModeAsString(value, defaultMode, trueMode) { + if (typeof value === "object") { + return getModeAsString(value.mode, defaultMode, trueMode).toString(); + } + else if (typeof value === "undefined") { + if (typeof defaultMode === "boolean" && !defaultMode) { + return undefined; + } + else if (typeof defaultMode === "boolean" && defaultMode) { + return typeof trueMode === "undefined" ? defaultMode : trueMode; + } + else if (typeof defaultMode === "undefined") { + return undefined; + } + else { + return defaultMode; + } + } + else if (typeof value === "boolean") { + if (value) { + return (typeof trueMode === "undefined") ? defaultMode : trueMode; + } + else { + return undefined; + } + } + return value; + } + const appDefaultMode = true; + const appDefaultTrueMode = "startOnly"; + const activitiesDefaultMode = Utils.isNode() ? false : "trackMyTypeAndInitiatedFromMe"; + const activitiesTrueMode = "trackMyTypeAndInitiatedFromMe"; + const layoutsDefaultMode = "slim"; + const layoutsTrueMode = layoutsDefaultMode; + const channelsConfig = () => { + if (typeof options.channels === "boolean") { + return options.channels; + } + else if (typeof options.channels === "object" && typeof options.channels.enabled === "boolean" && options.channels.enabled) { + return { mode: true, ...options.channels }; + } + else { + return false; + } + }; + const exposeAPI = typeof options.exposeAPI === "boolean" || typeof options.exposeGlue === "boolean"; + return { + layouts: getLibConfig(options.layouts, layoutsDefaultMode, layoutsTrueMode), + activities: getLibConfig(options.activities, activitiesDefaultMode, activitiesTrueMode), + appManager: getLibConfig(options.appManager, appDefaultMode, appDefaultTrueMode), + windows: getLibConfig(options.windows, true, true), + channels: getLibConfig(channelsConfig(), false, true), + displays: getLibConfig(options.displays, true, true), + exposeAPI: exposeAPI ? exposeAPI : true + }; + }; + + class Glue42Notification { + constructor(options) { + this.options = options; + this.callbacks = CallbackRegistryFactory(); + this.actions = options.actions; + this.body = options.body; + this.badge = options.badge; + this.data = options.data; + this.dir = options.dir; + this.icon = options.icon; + this.image = options.image; + this.lang = options.lang; + this.renotify = options.renotify; + this.requireInteraction = options.requireInteraction; + this.silent = options.silent; + this.tag = options.tag; + this.timestamp = options.timestamp; + this.title = options.title; + } + close() { + throw new Error("Method not implemented."); + } + addEventListener(type, listener, options) { + this.callbacks.add(type, listener); + } + removeEventListener(type, listener, options) { + } + dispatchEvent(event) { + this.callbacks.execute(event.type, event); + return true; + } + } + + class PanelAPI { + constructor(interop, onStreamEvent) { + this.interop = interop; + this.onStreamEvent = onStreamEvent; + } + onVisibilityChanged(callback) { + return this.onStreamEvent("on-panel-visibility-changed", callback); + } + toggle() { + return this.interop.invoke("T42.Notifications.Show", undefined, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + show() { + return this.interop.invoke("T42.Notifications.Show", { show: true }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + hide() { + return this.interop.invoke("T42.Notifications.Hide"); + } + async isVisible() { + const interopResult = await this.interop.invoke("T42.Notifications.Execute", { command: "isPanelVisible" }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return interopResult.returned.panelVisible; + } + toAPI() { + return { + onVisibilityChanged: this.onVisibilityChanged.bind(this), + toggle: this.toggle.bind(this), + show: this.show.bind(this), + hide: this.hide.bind(this), + isVisible: this.isVisible.bind(this) + }; + } + } + + const STARTING_INDEX = 0; + class Notifications { + constructor(interop, logger) { + this.interop = interop; + this.NotificationsSubscribeStream = "T42.GNS.Subscribe.Notifications"; + this.NotificationsCounterStream = "T42.Notifications.Counter"; + this.RaiseNotificationMethodName = "T42.GNS.Publish.RaiseNotification"; + this.NotificationsExecuteMethod = "T42.Notifications.Execute"; + this.NotificationFilterMethodName = "T42.Notifications.Filter"; + this.methodsRegistered = false; + this.NOTIFICATIONS_CONFIGURE_METHOD_NAME = "T42.Notifications.Configure"; + this.methodNameRoot = "T42.Notifications.Handler-" + Utils.generateId(); + this.nextId = 0; + this.notifications = {}; + this.registry = CallbackRegistryFactory(); + this.subscribedForNotifications = false; + this.subscribedCounterStream = false; + this.subscriptionsCountForNotifications = 0; + this.subscriptionsCountForCounter = 0; + this.logger = logger.subLogger("notifications"); + this._panel = new PanelAPI(interop, this.onStreamEventCore.bind(this)); + this._panelAPI = this._panel.toAPI(); + this.subscribeInternalEvents(); + } + get maxActions() { + return 10; + } + get panel() { + return this._panelAPI; + } + async raise(options) { + var _a; + const notification = await this.createNotification(options); + const g42notification = new Glue42Notification(options); + this.notifications[notification.id] = g42notification; + try { + const invocationResult = await this.interop.invoke(this.RaiseNotificationMethodName, { notification }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + g42notification.id = (_a = invocationResult.returned) === null || _a === void 0 ? void 0 : _a.id; + } + catch (err) { + const errorMessage = err.message; + setTimeout(() => { + this.handleNotificationErrorEvent(g42notification, errorMessage); + }, 1); + } + return g42notification; + } + async setFilter(filter) { + const result = await this.interop.invoke(this.NotificationFilterMethodName, filter, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return result.returned; + } + async getFilter() { + const result = await this.interop.invoke(this.NotificationFilterMethodName, undefined, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return result.returned; + } + async configure(options) { + var _a, _b, _c, _d, _e, _f, _g, _h; + if (!options || Array.isArray(options)) { + throw new Error("Invalid options - should be an object."); + } + if (Object.values(options).length === 0) { + throw new Error("The argument must be a non-empty object."); + } + if (typeof options.enable !== "undefined" && typeof options.enable !== "boolean") { + throw new Error("Expected type of enabled - boolean."); + } + if (typeof options.enableToasts !== "undefined" && typeof options.enableToasts !== "boolean") { + throw new Error("Expected type of enableToasts - boolean."); + } + if (typeof options.toastExpiry !== "undefined" && typeof options.toastExpiry !== "number") { + throw new Error("Expected type of toastExpiry - number."); + } + if (options.sourceFilter && typeof options.sourceFilter !== "object") { + throw new Error("Expected type of sourceFilter - object."); + } + if (((_a = options.sourceFilter) === null || _a === void 0 ? void 0 : _a.allowed) && !Array.isArray((_b = options.sourceFilter) === null || _b === void 0 ? void 0 : _b.allowed)) { + throw new Error("Expected type of sourceFilter.allowed - array."); + } + if (((_c = options.sourceFilter) === null || _c === void 0 ? void 0 : _c.blocked) && !Array.isArray((_d = options.sourceFilter) === null || _d === void 0 ? void 0 : _d.blocked)) { + throw new Error("Expected type of sourceFilter.blocked - array."); + } + if (options.toasts && typeof options.toasts !== "object") { + throw new Error("Expected type of (options.toasts - object."); + } + if (((_e = options.toasts) === null || _e === void 0 ? void 0 : _e.mode) && typeof options.toasts.mode !== "string") { + throw new Error("Expected type of (options.toasts.mode - string."); + } + if (((_f = options.toasts) === null || _f === void 0 ? void 0 : _f.stackBy) && typeof options.toasts.stackBy !== "string") { + throw new Error("Expected type of (options.toasts.stackBy - string."); + } + if (options.placement && typeof options.placement !== "object") { + throw new Error("Expected type of (options.placement - object."); + } + if (((_g = options.placement) === null || _g === void 0 ? void 0 : _g.toasts) && typeof options.placement.toasts !== "string") { + throw new Error("Expected type of (options.placement.toasts - string."); + } + if (((_h = options.placement) === null || _h === void 0 ? void 0 : _h.panel) && typeof options.placement.panel !== "string") { + throw new Error("Expected type of (options.placement.panel - string."); + } + if (typeof options.closeNotificationOnClick !== "undefined" && typeof options.closeNotificationOnClick !== "boolean") { + throw new Error("Expected type of closeNotificationOnClick - boolean."); + } + const result = await this.interop.invoke(this.NOTIFICATIONS_CONFIGURE_METHOD_NAME, options, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return result.returned; + } + async getConfiguration() { + const result = await this.interop.invoke(this.NotificationsExecuteMethod, { command: "getConfiguration" }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return result.returned; + } + async list() { + const interopResult = await this.interop.invoke(this.NotificationsExecuteMethod, { + command: "list", + data: { statesVersion2: true } + }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return interopResult.returned.notifications; + } + async updateData(id, data) { + const replacer = (key, value) => typeof value === "undefined" ? null : value; + const attribute = { + key: "data", + value: { + stringValue: JSON.stringify(data, replacer) + } + }; + const interopResult = await this.interop.invoke(this.NotificationsExecuteMethod, { command: "create-or-update-attribute", data: { id, attribute } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return interopResult.returned; + } + onRaised(callback) { + return this.onStreamEventCore("on-notification-raised", callback); + } + onStateChanged(callback) { + return this.onStreamEventCore("on-state-changed", callback); + } + onClosed(callback) { + return this.onStreamEventCore("on-notification-closed", callback); + } + onConfigurationChanged(callback) { + if (typeof callback !== "function") { + throw new Error("Please provide the callback as a function!"); + } + this.subscribe(); + const un = this.registry.add("on-configuration-changed", callback); + return () => { + un(); + this.closeStreamSubscriptionIfNoNeeded(); + }; + } + onCounterChanged(callback) { + if (typeof callback !== "function") { + throw new Error("Please provide the callback as a function!"); + } + this.subscribeForCounterStream(); + const un = this.registry.add("on-counter-changed", callback); + return () => { + un(); + this.closeStreamCounterSubscriptionIfNoNeeded(); + }; + } + onDataChanged(callback) { + if (typeof callback !== "function") { + throw new Error("Please provide the callback as a function!"); + } + this.subscribe(); + const un = this.registry.add("on-notification-data-changed", callback); + return () => { + un(); + this.closeStreamSubscriptionIfNoNeeded(); + }; + } + async clearAll() { + await this.interop.invoke(this.NotificationsExecuteMethod, { command: "clearAll" }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async clearOld() { + await this.interop.invoke(this.NotificationsExecuteMethod, { command: "clearAllOld", data: { statesVersion2: true } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async clear(id) { + if (!id) { + throw new Error("The 'id' argument cannot be null or undefined"); + } + if (typeof (id) !== "string") { + throw new Error("The 'id' argument must be a string"); + } + await this.interop.invoke(this.NotificationsExecuteMethod, { command: "clear", data: { id } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async clearMany(notifications) { + this.validateNotificationsArr(notifications); + await this.interop.invoke(this.NotificationsExecuteMethod, { command: "clearMany", data: { notifications } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async click(id, action, options) { + await this.interop.invoke(this.NotificationsExecuteMethod, { command: "click", data: { id, action, options } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async snooze(id, duration) { + await this.interop.invoke(this.NotificationsExecuteMethod, { command: "snooze", data: { id, duration } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async snoozeMany(notifications, duration) { + if (!duration) { + throw new Error("The 'duration' argument cannot be null or undefined"); + } + if (typeof duration !== "number") { + throw new Error("The 'duration' argument must be a valid number"); + } + this.validateNotificationsArr(notifications); + await this.interop.invoke(this.NotificationsExecuteMethod, { command: "snoozeMany", data: { notifications, duration } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async setState(id, state) { + if (!id) { + throw new Error("The 'id' argument cannot be null or undefined"); + } + if (typeof (id) !== "string") { + throw new Error("The 'id' argument must be a string"); + } + if (!state) { + throw new Error("The 'state' argument cannot be null or undefined"); + } + this.validateState(state); + await this.interop.invoke(this.NotificationsExecuteMethod, { command: "updateState", data: { id, state } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async setStates(notifications, state) { + if (!state) { + throw new Error("The 'state' argument cannot be null or undefined"); + } + if (typeof state !== "string") { + throw new Error("The 'state' argument must be a valid string"); + } + this.validateNotificationsArr(notifications); + await this.interop.invoke(this.NotificationsExecuteMethod, { command: "updateStates", data: { notifications, state } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + toAPI() { + return { + maxActions: this.maxActions, + panel: this._panel.toAPI(), + raise: this.raise.bind(this), + setFilter: this.setFilter.bind(this), + getFilter: this.getFilter.bind(this), + configure: this.configure.bind(this), + getConfiguration: this.getConfiguration.bind(this), + list: this.list.bind(this), + onRaised: this.onRaised.bind(this), + onStateChanged: this.onStateChanged.bind(this), + onClosed: this.onClosed.bind(this), + onConfigurationChanged: this.onConfigurationChanged.bind(this), + onCounterChanged: this.onCounterChanged.bind(this), + onDataChanged: this.onDataChanged.bind(this), + clearAll: this.clearAll.bind(this), + clearOld: this.clearOld.bind(this), + clear: this.clear.bind(this), + click: this.click.bind(this), + setState: this.setState.bind(this), + updateData: this.updateData.bind(this), + snooze: this.snooze.bind(this), + snoozeMany: this.snoozeMany.bind(this), + clearMany: this.clearMany.bind(this), + setStates: this.setStates.bind(this), + import: this.importNotifications.bind(this) + }; + } + async importNotifications(notifications) { + if (!notifications || !Array.isArray(notifications) || notifications.length === 0) { + throw new Error("Notifications argument must be a valid array with notification options"); + } + const notificationsToImport = await Promise.all(notifications.map((notificationOptions) => this.createNotification(notificationOptions, true))); + const invocationResult = await this.interop.invoke(this.NotificationsExecuteMethod, { command: "importNotifications", data: { notificationSettings: notificationsToImport } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return invocationResult.returned.notifications; + } + async createNotification(options, imported) { + var _a, _b, _c, _d; + this.validate(options, imported); + if (!this.methodsRegistered) { + const bunchOfPromises = []; + for (let index = STARTING_INDEX; index < this.maxActions; index++) { + bunchOfPromises.push(this.interop.register(`${this.methodNameRoot}_${index}`, this.handleNotificationEvent.bind(this))); + } + this.methodsRegistered = true; + await Promise.all(bunchOfPromises); + } + const id = (_a = options.id) !== null && _a !== void 0 ? _a : Utils.generateId(); + const type = (_b = options.type) !== null && _b !== void 0 ? _b : "Notification"; + const notification = { + id, + state: (_c = options.state) !== null && _c !== void 0 ? _c : "Active", + title: options.title, + type, + severity: (_d = options.severity) !== null && _d !== void 0 ? _d : "None", + description: options.body, + glueRoutingDetailMethodName: `${this.methodNameRoot}_${STARTING_INDEX}`, + actions: [], + sourceId: id, + source: options.source, + publishExtraEvents: true, + clickInterop: options.clickInterop + }; + if (options.actions) { + this.handleActions(options, id, notification); + } + this.handleOptions(options, notification); + return notification; + } + onStreamEventCore(key, callback) { + if (typeof callback !== "function") { + throw new Error("Please provide the callback as a function!"); + } + this.subscribe(); + const un = this.registry.add(key, callback); + return () => { + un(); + this.closeStreamSubscriptionIfNoNeeded(); + }; + } + handleOptions(options, notification) { + if (options.icon) { + notification.attributes = notification.attributes || []; + notification.attributes.push({ key: "icon", value: { stringValue: options.icon } }); + } + if (options.data) { + notification.attributes = notification.attributes || []; + const dataAsString = JSON.stringify(options.data); + notification.attributes.push({ key: "data", value: { stringValue: dataAsString } }); + } + if (typeof options.panelExpiry === "number") { + notification.attributes = notification.attributes || []; + notification.attributes.push({ key: "panelExpiry", value: { stringValue: options.panelExpiry.toString() } }); + } + if (typeof options.toastExpiry === "number") { + notification.attributes = notification.attributes || []; + notification.attributes.push({ key: "toastExpiry", value: { stringValue: options.toastExpiry.toString() } }); + } + } + handleActions(options, id, notification) { + var _a, _b, _c; + const validActions = options.actions.slice(0, this.maxActions); + let index = STARTING_INDEX; + for (const action of validActions) { + const args = { + g42notificationId: id, + g42action: action.action, + g42interopMethod: (_a = action.interop) === null || _a === void 0 ? void 0 : _a.method, + g42interopTarget: (_b = action.interop) === null || _b === void 0 ? void 0 : _b.target, + g42interopArguments: JSON.stringify((_c = action.interop) === null || _c === void 0 ? void 0 : _c.arguments) + }; + const parameters = Object.keys(args).map((key) => { + const value = args[key]; + return { + name: key, + value: { + stringValue: value + } + }; + }); + const glueAction = { + name: `${this.methodNameRoot}_${index}`, + description: action.title, + displayName: action.title, + displayPath: action.displayPath, + displayId: action.displayId, + parameters + }; + notification.actions.push(glueAction); + index++; + } + } + validate(options, imported) { + if (!options) { + throw new Error("invalid options - should be an object"); + } + if (typeof options !== "object") { + throw new Error("invalid options - should be an object"); + } + if (!options.title) { + throw new Error("invalid options - should have a title"); + } + if (typeof options.title !== "string") { + throw new Error("invalid options - title should be a string"); + } + if (options.severity && typeof options.severity !== "string") { + throw new Error("invalid options - severity should be a string"); + } + if (options.panelExpiry && typeof options.panelExpiry !== "number") { + throw new Error("invalid options - panelExpiry should be a number"); + } + if (options.toastExpiry && typeof options.toastExpiry !== "number") { + throw new Error("invalid options - toastExpiry should be a number"); + } + if (options.state) { + this.validateState(options.state, imported); + } + } + validateState(state, imported) { + if (typeof (state) !== "string") { + throw new Error("The 'state' argument must be a string"); + } + const validStates = [ + "Active", + "Acknowledged", + "Stale" + ]; + if (imported) { + validStates.push("Seen", "Snoozed", "Processing", "Closed"); + } + if (!validStates.includes(state)) { + throw new Error(`The state argument: ${state} is not valid!`); + } + } + subscribe() { + this.subscriptionsCountForNotifications++; + if (!this.subscribedForNotifications) { + this.subscribedForNotifications = true; + this.logger.info(`Attempting to subscribe to "${this.NotificationsSubscribeStream}".`); + this.interop + .subscribe(this.NotificationsSubscribeStream, { + arguments: { + sendDeltaOnly: true, + statesVersion2: true + } + }) + .then((sub) => { + this.subscriptionForNotifications = sub; + this.logger.info(`Successfully subscribed to "${this.NotificationsSubscribeStream}".`); + sub.onData(({ data }) => { + this.handleData(data); + }); + sub.onClosed((...args) => { + this.subscribedForNotifications = false; + this.logger.info(`Stream subscription Closed - ${JSON.stringify(args)}`); + }); + sub.onFailed((...args) => { + this.subscribedForNotifications = false; + this.logger.warn(`Stream subscription Failed - ${JSON.stringify(args)}`); + }); + }) + .catch((e) => { + this.subscribedForNotifications = false; + this.logger.error(`Unable to subscribe to "${this.NotificationsSubscribeStream}"`, e); + }); + } + } + subscribeForCounterStream() { + this.subscriptionsCountForCounter++; + if (!this.subscribedCounterStream) { + this.subscribedCounterStream = true; + this.logger.info(`Attempting to subscribe to "${this.NotificationsCounterStream}".`); + this.interop + .subscribe(this.NotificationsCounterStream, { + arguments: { + sendDeltaOnly: true + } + }) + .then((sub) => { + this.subscriptionForCounter = sub; + this.logger.info(`Successfully subscribed to "${this.NotificationsCounterStream}".`); + sub.onData(({ data }) => { + this.registry.execute("on-counter-changed", { count: data.count }); + }); + sub.onClosed((...args) => { + this.subscribedCounterStream = false; + this.logger.info(`Stream subscription Closed - ${JSON.stringify(args)}`); + }); + sub.onFailed((...args) => { + this.subscribedCounterStream = false; + this.logger.warn(`Stream subscription Failed - ${JSON.stringify(args)}`); + }); + }) + .catch((e) => { + this.subscribedCounterStream = false; + this.logger.error(`Unable to subscribe to "${this.NotificationsCounterStream}"`, e); + }); + } + } + subscribeInternalEvents() { + this.registry.add("on-notification-closed", (id) => { + this.handleOnClosed(id); + }); + this.registry.add("on-notification-raised", (notification) => { + this.handleOnShow(notification.id); + }); + } + handleData(message) { + var _a; + try { + if ("items" in message && Array.isArray(message.items)) { + this.handleItemsData(message); + } + else if ("deltas" in message && Array.isArray(message.deltas)) { + this.handleDeltas(message); + } + if ("configuration" in message && typeof message.configuration === "object") { + this.logger.info(`Received configuration ${JSON.stringify(message.configuration)} from the stream`); + this.registry.execute("on-configuration-changed", message.configuration, message.configuration.allApplications); + } + if ("command" in message && typeof message.command === "string") { + this.logger.info(`Received command "${(_a = message.command) !== null && _a !== void 0 ? _a : JSON.stringify(message)}" from the stream`); + if (message.command === "showPanel" || message.command === "hidePanel") { + this.registry.execute("on-panel-visibility-changed", message.command === "showPanel"); + } + } + } + catch (e) { + this.logger.error(`Failed to parse data from the stream`, e); + } + } + handleItemsData(message) { + const items = message.items; + this.logger.info(`Received ${items.length} notifications from the stream`); + const notifications = items; + if (message.isSnapshot) { + notifications.forEach((n) => { + this.registry.execute("on-notification-raised", n); + }); + } + else { + const notification = notifications[0]; + if (notification.state === "Closed") { + this.registry.execute("on-notification-closed", { id: notification.id }); + } + else { + this.registry.execute("on-notification-raised", notification); + } + } + } + handleDeltas(message) { + const deltas = message.deltas; + deltas.forEach((info) => { + var _a; + const id = info.id; + const delta = (_a = info.delta) !== null && _a !== void 0 ? _a : {}; + if (delta.state === "Closed") { + this.registry.execute("on-notification-closed", { id, ...delta }); + } + else if (delta.state) { + this.registry.execute("on-state-changed", { id }, delta.state); + } + else if (delta.attributes) { + const attributes = delta.attributes; + const dataAttribute = attributes.find((a) => a.key === "data"); + if (dataAttribute) { + this.registry.execute("on-notification-data-changed", { id }, JSON.parse(dataAttribute.value.stringValue)); + } + } + }); + } + handleOnClosed(id) { + const { notification, key } = this.getNotification(id); + if (notification) { + this.handleEvent(notification, "close"); + delete this.notifications[key]; + } + } + handleOnShow(id) { + const { notification } = this.getNotification(id); + if (notification) { + this.handleEvent(notification, "show"); + } + } + getNotification(id) { + let notification; + let key; + for (const k in this.notifications) { + if (this.notifications[k].id === id) { + notification = this.notifications[k]; + key = k; + break; + } + } + return { notification, key }; + } + handleNotificationEvent(args) { + const gnsNotificationArgs = this.getGnsNotificationArgs(args); + if (gnsNotificationArgs.event === "unknown") { + return; + } + const notification = this.notifications[gnsNotificationArgs.notificationId]; + if (!notification) { + return; + } + this.handleNotificationEventCore(notification, gnsNotificationArgs); + } + handleNotificationEventCore(notification, args) { + switch (args.event) { + case "action": { + return this.handleNotificationActionEvent(notification, args.notificationActionPayload); + } + case "click": { + return this.handleNotificationClickEvent(notification); + } + case "close": { + return this.handleEvent(notification, "close"); + } + case "error": { + return this.handleNotificationErrorEvent(notification, args.error); + } + case "show": { + return this.handleEvent(notification, "show"); + } + } + } + handleNotificationActionEvent(notification, payload) { + const event = { + type: "onaction", + action: payload.g42action + }; + if (notification.onaction) { + notification.onaction(event); + } + notification.dispatchEvent(event); + } + handleNotificationClickEvent(notification) { + const event = { type: "onclick" }; + if (notification.onclick) { + notification.onclick(event); + } + notification.dispatchEvent(event); + } + handleEvent(notification, eventType) { + var _a; + const event = { type: eventType }; + const eventName = `on${eventType}`; + (_a = notification[eventName]) === null || _a === void 0 ? void 0 : _a.call(notification, event); + notification.dispatchEvent(event); + } + handleNotificationErrorEvent(notification, error) { + const event = { type: "onerror", error }; + if (notification.onerror) { + notification.onerror(event); + } + notification.dispatchEvent(event); + } + getGnsNotificationArgs(args) { + var _a; + let result; + const event = (_a = args.notification) === null || _a === void 0 ? void 0 : _a.event; + if (!event) { + result = this.getBackwardGnsNotificationArgs(args); + } + else { + result = { + event, + notificationId: args.notification.sourceNotificationId, + notificationActionPayload: args + }; + } + return result; + } + getBackwardGnsNotificationArgs(args) { + var _a; + let result; + if (args.g42notificationId) { + result = { + event: "action", + notificationId: args.g42notificationId, + notificationActionPayload: args + }; + } + else if ((_a = args.notification) === null || _a === void 0 ? void 0 : _a.sourceNotificationId) { + result = { + event: "click", + notificationId: args.notification.sourceNotificationId, + notificationActionPayload: args + }; + } + else { + result = { + event: "unknown", + notificationId: undefined, + notificationActionPayload: args + }; + } + return result; + } + closeStreamSubscriptionIfNoNeeded() { + this.subscriptionsCountForNotifications--; + if (this.subscriptionForNotifications && this.subscriptionsCountForNotifications === 0) { + this.subscriptionForNotifications.close(); + this.subscriptionForNotifications = undefined; + } + } + closeStreamCounterSubscriptionIfNoNeeded() { + this.subscriptionsCountForCounter--; + if (this.subscriptionForCounter && this.subscriptionsCountForCounter === 0) { + this.subscriptionForCounter.close(); + this.subscriptionForCounter = undefined; + } + } + validateNotificationsArr(notifications) { + if (!Array.isArray(notifications)) { + throw new Error("The 'notifications' argument must be an array with valid notification IDs"); + } + if (notifications.some((n) => typeof n !== "string")) { + throw new Error("The 'notifications' argument must contain only valid string notification IDs"); + } + } + } + + const ThemesConfigurationMethodName = "T42.Themes.Configuration"; + class ThemesImpl { + constructor(contexts, interop) { + this.contexts = contexts; + this.interop = interop; + this.registry = CallbackRegistryFactory(); + this.isSubscribed = false; + this.getConfiguration(); + } + async list() { + await this.getConfiguration(); + if (!this.getMethodName) { + throw new Error("not supported"); + } + return (await this.getAll()).returned.all; + } + async getCurrent() { + await this.getConfiguration(); + if (!this.getMethodName) { + throw new Error("not supported"); + } + const all = await this.getAll(); + return all.returned.all.find((t) => t.name === all.returned.selected); + } + async select(theme) { + await this.getConfiguration(); + if (!this.setMethodName) { + throw new Error("not supported"); + } + await this.interop.invoke(this.setMethodName, { theme }); + } + onChanged(callback) { + if (!callback) { + throw new Error("Callback argument is required"); + } + if (callback && typeof callback !== "function") { + throw new Error("Callback argument must be a function"); + } + this.subscribe(); + return this.registry.add("changed", callback); + } + async getConfiguration() { + try { + if (this.sharedContextName) { + return; + } + const config = await this.interop.invoke(ThemesConfigurationMethodName); + this.sharedContextName = config.returned.sharedContextName; + this.getMethodName = config.returned.getThemesMethodName; + this.setMethodName = config.returned.setThemesMethodName; + } + catch (error) { + return; + } + } + async getAll() { + await this.getConfiguration(); + return await this.interop.invoke(this.getMethodName); + } + async subscribe() { + await this.getConfiguration(); + if (this.isSubscribed) { + return; + } + this.isSubscribed = true; + this.contexts.subscribe(this.sharedContextName, (data) => { + if (data && data.all && data.selected) { + this.registry.execute("changed", data.all.find((t) => t.name === data.selected)); + } + }); + } + } + + function factory$2(contexts, interop) { + const themes = new ThemesImpl(contexts, interop); + return { + list: themes.list.bind(themes), + getCurrent: themes.getCurrent.bind(themes), + select: themes.select.bind(themes), + onChanged: themes.onChanged.bind(themes), + ready: () => Promise.resolve(), + }; + } + + const connectBrowserAppProps = ["name", "title", "version", "customProperties", "icon", "caption", "type"]; + const fdc3v2AppProps = ["appId", "name", "type", "details", "version", "title", "tooltip", "lang", "description", "categories", "icons", "screenshots", "contactEmail", "moreInfo", "publisher", "customConfig", "hostManifests", "interop", "localizedVersions"]; + + /** + * Wraps values in an `Ok` type. + * + * Example: `ok(5) // => {ok: true, result: 5}` + */ + var ok = function (result) { return ({ ok: true, result: result }); }; + /** + * Wraps errors in an `Err` type. + * + * Example: `err('on fire') // => {ok: false, error: 'on fire'}` + */ + var err = function (error) { return ({ ok: false, error: error }); }; + /** + * Create a `Promise` that either resolves with the result of `Ok` or rejects + * with the error of `Err`. + */ + var asPromise = function (r) { + return r.ok === true ? Promise.resolve(r.result) : Promise.reject(r.error); + }; + /** + * Unwraps a `Result` and returns either the result of an `Ok`, or + * `defaultValue`. + * + * Example: + * ``` + * Result.withDefault(5, number().run(json)) + * ``` + * + * It would be nice if `Decoder` had an instance method that mirrored this + * function. Such a method would look something like this: + * ``` + * class Decoder { + * runWithDefault = (defaultValue: A, json: any): A => + * Result.withDefault(defaultValue, this.run(json)); + * } + * + * number().runWithDefault(5, json) + * ``` + * Unfortunately, the type of `defaultValue: A` on the method causes issues + * with type inference on the `object` decoder in some situations. While these + * inference issues can be solved by providing the optional type argument for + * `object`s, the extra trouble and confusion doesn't seem worth it. + */ + var withDefault = function (defaultValue, r) { + return r.ok === true ? r.result : defaultValue; + }; + /** + * Return the successful result, or throw an error. + */ + var withException = function (r) { + if (r.ok === true) { + return r.result; + } + else { + throw r.error; + } + }; + /** + * Apply `f` to the result of an `Ok`, or pass the error through. + */ + var map = function (f, r) { + return r.ok === true ? ok(f(r.result)) : r; + }; + /** + * Apply `f` to the result of two `Ok`s, or pass an error through. If both + * `Result`s are errors then the first one is returned. + */ + var map2 = function (f, ar, br) { + return ar.ok === false ? ar : + br.ok === false ? br : + ok(f(ar.result, br.result)); + }; + /** + * Apply `f` to the error of an `Err`, or pass the success through. + */ + var mapError = function (f, r) { + return r.ok === true ? r : err(f(r.error)); + }; + /** + * Chain together a sequence of computations that may fail, similar to a + * `Promise`. If the first computation fails then the error will propagate + * through. If it succeeds, then `f` will be applied to the value, returning a + * new `Result`. + */ + var andThen = function (f, r) { + return r.ok === true ? f(r.result) : r; + }; + + /*! ***************************************************************************** + Copyright (c) Microsoft Corporation. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THIS SOFTWARE. + ***************************************************************************** */ + /* global Reflect, Promise */ + + + + var __assign = function() { + __assign = Object.assign || function __assign(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; + } + return t; + }; + return __assign.apply(this, arguments); + }; + + function __rest(s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { + if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) + t[p[i]] = s[p[i]]; + } + return t; + } + + function isEqual(a, b) { + if (a === b) { + return true; + } + if (a === null && b === null) { + return true; + } + if (typeof (a) !== typeof (b)) { + return false; + } + if (typeof (a) === 'object') { + // Array + if (Array.isArray(a)) { + if (!Array.isArray(b)) { + return false; + } + if (a.length !== b.length) { + return false; + } + for (var i = 0; i < a.length; i++) { + if (!isEqual(a[i], b[i])) { + return false; + } + } + return true; + } + // Hash table + var keys = Object.keys(a); + if (keys.length !== Object.keys(b).length) { + return false; + } + for (var i = 0; i < keys.length; i++) { + if (!b.hasOwnProperty(keys[i])) { + return false; + } + if (!isEqual(a[keys[i]], b[keys[i]])) { + return false; + } + } + return true; + } + } + /* + * Helpers + */ + var isJsonArray = function (json) { return Array.isArray(json); }; + var isJsonObject = function (json) { + return typeof json === 'object' && json !== null && !isJsonArray(json); + }; + var typeString = function (json) { + switch (typeof json) { + case 'string': + return 'a string'; + case 'number': + return 'a number'; + case 'boolean': + return 'a boolean'; + case 'undefined': + return 'undefined'; + case 'object': + if (json instanceof Array) { + return 'an array'; + } + else if (json === null) { + return 'null'; + } + else { + return 'an object'; + } + default: + return JSON.stringify(json); + } + }; + var expectedGot = function (expected, got) { + return "expected " + expected + ", got " + typeString(got); + }; + var printPath = function (paths) { + return paths.map(function (path) { return (typeof path === 'string' ? "." + path : "[" + path + "]"); }).join(''); + }; + var prependAt = function (newAt, _a) { + var at = _a.at, rest = __rest(_a, ["at"]); + return (__assign({ at: newAt + (at || '') }, rest)); + }; + /** + * Decoders transform json objects with unknown structure into known and + * verified forms. You can create objects of type `Decoder` with either the + * primitive decoder functions, such as `boolean()` and `string()`, or by + * applying higher-order decoders to the primitives, such as `array(boolean())` + * or `dict(string())`. + * + * Each of the decoder functions are available both as a static method on + * `Decoder` and as a function alias -- for example the string decoder is + * defined at `Decoder.string()`, but is also aliased to `string()`. Using the + * function aliases exported with the library is recommended. + * + * `Decoder` exposes a number of 'run' methods, which all decode json in the + * same way, but communicate success and failure in different ways. The `map` + * and `andThen` methods modify decoders without having to call a 'run' method. + * + * Alternatively, the main decoder `run()` method returns an object of type + * `Result`. This library provides a number of helper + * functions for dealing with the `Result` type, so you can do all the same + * things with a `Result` as with the decoder methods. + */ + var Decoder = /** @class */ (function () { + /** + * The Decoder class constructor is kept private to separate the internal + * `decode` function from the external `run` function. The distinction + * between the two functions is that `decode` returns a + * `Partial` on failure, which contains an unfinished error + * report. When `run` is called on a decoder, the relevant series of `decode` + * calls is made, and then on failure the resulting `Partial` + * is turned into a `DecoderError` by filling in the missing information. + * + * While hiding the constructor may seem restrictive, leveraging the + * provided decoder combinators and helper functions such as + * `andThen` and `map` should be enough to build specialized decoders as + * needed. + */ + function Decoder(decode) { + var _this = this; + this.decode = decode; + /** + * Run the decoder and return a `Result` with either the decoded value or a + * `DecoderError` containing the json input, the location of the error, and + * the error message. + * + * Examples: + * ``` + * number().run(12) + * // => {ok: true, result: 12} + * + * string().run(9001) + * // => + * // { + * // ok: false, + * // error: { + * // kind: 'DecoderError', + * // input: 9001, + * // at: 'input', + * // message: 'expected a string, got 9001' + * // } + * // } + * ``` + */ + this.run = function (json) { + return mapError(function (error) { return ({ + kind: 'DecoderError', + input: json, + at: 'input' + (error.at || ''), + message: error.message || '' + }); }, _this.decode(json)); + }; + /** + * Run the decoder as a `Promise`. + */ + this.runPromise = function (json) { return asPromise(_this.run(json)); }; + /** + * Run the decoder and return the value on success, or throw an exception + * with a formatted error string. + */ + this.runWithException = function (json) { return withException(_this.run(json)); }; + /** + * Construct a new decoder that applies a transformation to the decoded + * result. If the decoder succeeds then `f` will be applied to the value. If + * it fails the error will propagated through. + * + * Example: + * ``` + * number().map(x => x * 5).run(10) + * // => {ok: true, result: 50} + * ``` + */ + this.map = function (f) { + return new Decoder(function (json) { return map(f, _this.decode(json)); }); + }; + /** + * Chain together a sequence of decoders. The first decoder will run, and + * then the function will determine what decoder to run second. If the result + * of the first decoder succeeds then `f` will be applied to the decoded + * value. If it fails the error will propagate through. + * + * This is a very powerful method -- it can act as both the `map` and `where` + * methods, can improve error messages for edge cases, and can be used to + * make a decoder for custom types. + * + * Example of adding an error message: + * ``` + * const versionDecoder = valueAt(['version'], number()); + * const infoDecoder3 = object({a: boolean()}); + * + * const decoder = versionDecoder.andThen(version => { + * switch (version) { + * case 3: + * return infoDecoder3; + * default: + * return fail(`Unable to decode info, version ${version} is not supported.`); + * } + * }); + * + * decoder.run({version: 3, a: true}) + * // => {ok: true, result: {a: true}} + * + * decoder.run({version: 5, x: 'abc'}) + * // => + * // { + * // ok: false, + * // error: {... message: 'Unable to decode info, version 5 is not supported.'} + * // } + * ``` + * + * Example of decoding a custom type: + * ``` + * // nominal type for arrays with a length of at least one + * type NonEmptyArray = T[] & { __nonEmptyArrayBrand__: void }; + * + * const nonEmptyArrayDecoder = (values: Decoder): Decoder> => + * array(values).andThen(arr => + * arr.length > 0 + * ? succeed(createNonEmptyArray(arr)) + * : fail(`expected a non-empty array, got an empty array`) + * ); + * ``` + */ + this.andThen = function (f) { + return new Decoder(function (json) { + return andThen(function (value) { return f(value).decode(json); }, _this.decode(json)); + }); + }; + /** + * Add constraints to a decoder _without_ changing the resulting type. The + * `test` argument is a predicate function which returns true for valid + * inputs. When `test` fails on an input, the decoder fails with the given + * `errorMessage`. + * + * ``` + * const chars = (length: number): Decoder => + * string().where( + * (s: string) => s.length === length, + * `expected a string of length ${length}` + * ); + * + * chars(5).run('12345') + * // => {ok: true, result: '12345'} + * + * chars(2).run('HELLO') + * // => {ok: false, error: {... message: 'expected a string of length 2'}} + * + * chars(12).run(true) + * // => {ok: false, error: {... message: 'expected a string, got a boolean'}} + * ``` + */ + this.where = function (test, errorMessage) { + return _this.andThen(function (value) { return (test(value) ? Decoder.succeed(value) : Decoder.fail(errorMessage)); }); + }; + } + /** + * Decoder primitive that validates strings, and fails on all other input. + */ + Decoder.string = function () { + return new Decoder(function (json) { + return typeof json === 'string' + ? ok(json) + : err({ message: expectedGot('a string', json) }); + }); + }; + /** + * Decoder primitive that validates numbers, and fails on all other input. + */ + Decoder.number = function () { + return new Decoder(function (json) { + return typeof json === 'number' + ? ok(json) + : err({ message: expectedGot('a number', json) }); + }); + }; + /** + * Decoder primitive that validates booleans, and fails on all other input. + */ + Decoder.boolean = function () { + return new Decoder(function (json) { + return typeof json === 'boolean' + ? ok(json) + : err({ message: expectedGot('a boolean', json) }); + }); + }; + Decoder.constant = function (value) { + return new Decoder(function (json) { + return isEqual(json, value) + ? ok(value) + : err({ message: "expected " + JSON.stringify(value) + ", got " + JSON.stringify(json) }); + }); + }; + Decoder.object = function (decoders) { + return new Decoder(function (json) { + if (isJsonObject(json) && decoders) { + var obj = {}; + for (var key in decoders) { + if (decoders.hasOwnProperty(key)) { + var r = decoders[key].decode(json[key]); + if (r.ok === true) { + // tslint:disable-next-line:strict-type-predicates + if (r.result !== undefined) { + obj[key] = r.result; + } + } + else if (json[key] === undefined) { + return err({ message: "the key '" + key + "' is required but was not present" }); + } + else { + return err(prependAt("." + key, r.error)); + } + } + } + return ok(obj); + } + else if (isJsonObject(json)) { + return ok(json); + } + else { + return err({ message: expectedGot('an object', json) }); + } + }); + }; + Decoder.array = function (decoder) { + return new Decoder(function (json) { + if (isJsonArray(json) && decoder) { + var decodeValue_1 = function (v, i) { + return mapError(function (err$$1) { return prependAt("[" + i + "]", err$$1); }, decoder.decode(v)); + }; + return json.reduce(function (acc, v, i) { + return map2(function (arr, result) { return arr.concat([result]); }, acc, decodeValue_1(v, i)); + }, ok([])); + } + else if (isJsonArray(json)) { + return ok(json); + } + else { + return err({ message: expectedGot('an array', json) }); + } + }); + }; + Decoder.tuple = function (decoders) { + return new Decoder(function (json) { + if (isJsonArray(json)) { + if (json.length !== decoders.length) { + return err({ + message: "expected a tuple of length " + decoders.length + ", got one of length " + json.length + }); + } + var result = []; + for (var i = 0; i < decoders.length; i++) { + var nth = decoders[i].decode(json[i]); + if (nth.ok) { + result[i] = nth.result; + } + else { + return err(prependAt("[" + i + "]", nth.error)); + } + } + return ok(result); + } + else { + return err({ message: expectedGot("a tuple of length " + decoders.length, json) }); + } + }); + }; + Decoder.union = function (ad, bd) { + var decoders = []; + for (var _i = 2; _i < arguments.length; _i++) { + decoders[_i - 2] = arguments[_i]; + } + return Decoder.oneOf.apply(Decoder, [ad, bd].concat(decoders)); + }; + Decoder.intersection = function (ad, bd) { + var ds = []; + for (var _i = 2; _i < arguments.length; _i++) { + ds[_i - 2] = arguments[_i]; + } + return new Decoder(function (json) { + return [ad, bd].concat(ds).reduce(function (acc, decoder) { return map2(Object.assign, acc, decoder.decode(json)); }, ok({})); + }); + }; + /** + * Escape hatch to bypass validation. Always succeeds and types the result as + * `any`. Useful for defining decoders incrementally, particularly for + * complex objects. + * + * Example: + * ``` + * interface User { + * name: string; + * complexUserData: ComplexType; + * } + * + * const userDecoder: Decoder = object({ + * name: string(), + * complexUserData: anyJson() + * }); + * ``` + */ + Decoder.anyJson = function () { return new Decoder(function (json) { return ok(json); }); }; + /** + * Decoder identity function which always succeeds and types the result as + * `unknown`. + */ + Decoder.unknownJson = function () { + return new Decoder(function (json) { return ok(json); }); + }; + /** + * Decoder for json objects where the keys are unknown strings, but the values + * should all be of the same type. + * + * Example: + * ``` + * dict(number()).run({chocolate: 12, vanilla: 10, mint: 37}); + * // => {ok: true, result: {chocolate: 12, vanilla: 10, mint: 37}} + * ``` + */ + Decoder.dict = function (decoder) { + return new Decoder(function (json) { + if (isJsonObject(json)) { + var obj = {}; + for (var key in json) { + if (json.hasOwnProperty(key)) { + var r = decoder.decode(json[key]); + if (r.ok === true) { + obj[key] = r.result; + } + else { + return err(prependAt("." + key, r.error)); + } + } + } + return ok(obj); + } + else { + return err({ message: expectedGot('an object', json) }); + } + }); + }; + /** + * Decoder for values that may be `undefined`. This is primarily helpful for + * decoding interfaces with optional fields. + * + * Example: + * ``` + * interface User { + * id: number; + * isOwner?: boolean; + * } + * + * const decoder: Decoder = object({ + * id: number(), + * isOwner: optional(boolean()) + * }); + * ``` + */ + Decoder.optional = function (decoder) { + return new Decoder(function (json) { return (json === undefined || json === null ? ok(undefined) : decoder.decode(json)); }); + }; + /** + * Decoder that attempts to run each decoder in `decoders` and either succeeds + * with the first successful decoder, or fails after all decoders have failed. + * + * Note that `oneOf` expects the decoders to all have the same return type, + * while `union` creates a decoder for the union type of all the input + * decoders. + * + * Examples: + * ``` + * oneOf(string(), number().map(String)) + * oneOf(constant('start'), constant('stop'), succeed('unknown')) + * ``` + */ + Decoder.oneOf = function () { + var decoders = []; + for (var _i = 0; _i < arguments.length; _i++) { + decoders[_i] = arguments[_i]; + } + return new Decoder(function (json) { + var errors = []; + for (var i = 0; i < decoders.length; i++) { + var r = decoders[i].decode(json); + if (r.ok === true) { + return r; + } + else { + errors[i] = r.error; + } + } + var errorsList = errors + .map(function (error) { return "at error" + (error.at || '') + ": " + error.message; }) + .join('", "'); + return err({ + message: "expected a value matching one of the decoders, got the errors [\"" + errorsList + "\"]" + }); + }); + }; + /** + * Decoder that always succeeds with either the decoded value, or a fallback + * default value. + */ + Decoder.withDefault = function (defaultValue, decoder) { + return new Decoder(function (json) { + return ok(withDefault(defaultValue, decoder.decode(json))); + }); + }; + /** + * Decoder that pulls a specific field out of a json structure, instead of + * decoding and returning the full structure. The `paths` array describes the + * object keys and array indices to traverse, so that values can be pulled out + * of a nested structure. + * + * Example: + * ``` + * const decoder = valueAt(['a', 'b', 0], string()); + * + * decoder.run({a: {b: ['surprise!']}}) + * // => {ok: true, result: 'surprise!'} + * + * decoder.run({a: {x: 'cats'}}) + * // => {ok: false, error: {... at: 'input.a.b[0]' message: 'path does not exist'}} + * ``` + * + * Note that the `decoder` is ran on the value found at the last key in the + * path, even if the last key is not found. This allows the `optional` + * decoder to succeed when appropriate. + * ``` + * const optionalDecoder = valueAt(['a', 'b', 'c'], optional(string())); + * + * optionalDecoder.run({a: {b: {c: 'surprise!'}}}) + * // => {ok: true, result: 'surprise!'} + * + * optionalDecoder.run({a: {b: 'cats'}}) + * // => {ok: false, error: {... at: 'input.a.b.c' message: 'expected an object, got "cats"'} + * + * optionalDecoder.run({a: {b: {z: 1}}}) + * // => {ok: true, result: undefined} + * ``` + */ + Decoder.valueAt = function (paths, decoder) { + return new Decoder(function (json) { + var jsonAtPath = json; + for (var i = 0; i < paths.length; i++) { + if (jsonAtPath === undefined) { + return err({ + at: printPath(paths.slice(0, i + 1)), + message: 'path does not exist' + }); + } + else if (typeof paths[i] === 'string' && !isJsonObject(jsonAtPath)) { + return err({ + at: printPath(paths.slice(0, i + 1)), + message: expectedGot('an object', jsonAtPath) + }); + } + else if (typeof paths[i] === 'number' && !isJsonArray(jsonAtPath)) { + return err({ + at: printPath(paths.slice(0, i + 1)), + message: expectedGot('an array', jsonAtPath) + }); + } + else { + jsonAtPath = jsonAtPath[paths[i]]; + } + } + return mapError(function (error) { + return jsonAtPath === undefined + ? { at: printPath(paths), message: 'path does not exist' } + : prependAt(printPath(paths), error); + }, decoder.decode(jsonAtPath)); + }); + }; + /** + * Decoder that ignores the input json and always succeeds with `fixedValue`. + */ + Decoder.succeed = function (fixedValue) { + return new Decoder(function (json) { return ok(fixedValue); }); + }; + /** + * Decoder that ignores the input json and always fails with `errorMessage`. + */ + Decoder.fail = function (errorMessage) { + return new Decoder(function (json) { return err({ message: errorMessage }); }); + }; + /** + * Decoder that allows for validating recursive data structures. Unlike with + * functions, decoders assigned to variables can't reference themselves + * before they are fully defined. We can avoid prematurely referencing the + * decoder by wrapping it in a function that won't be called until use, at + * which point the decoder has been defined. + * + * Example: + * ``` + * interface Comment { + * msg: string; + * replies: Comment[]; + * } + * + * const decoder: Decoder = object({ + * msg: string(), + * replies: lazy(() => array(decoder)) + * }); + * ``` + */ + Decoder.lazy = function (mkDecoder) { + return new Decoder(function (json) { return mkDecoder().decode(json); }); + }; + return Decoder; + }()); + + /* tslint:disable:variable-name */ + /** See `Decoder.string` */ + var string = Decoder.string; + /** See `Decoder.number` */ + var number = Decoder.number; + /** See `Decoder.boolean` */ + var boolean = Decoder.boolean; + /** See `Decoder.anyJson` */ + var anyJson = Decoder.anyJson; + /** See `Decoder.unknownJson` */ + Decoder.unknownJson; + /** See `Decoder.constant` */ + var constant = Decoder.constant; + /** See `Decoder.object` */ + var object = Decoder.object; + /** See `Decoder.array` */ + var array = Decoder.array; + /** See `Decoder.tuple` */ + Decoder.tuple; + /** See `Decoder.dict` */ + var dict = Decoder.dict; + /** See `Decoder.optional` */ + var optional = Decoder.optional; + /** See `Decoder.oneOf` */ + var oneOf = Decoder.oneOf; + /** See `Decoder.union` */ + Decoder.union; + /** See `Decoder.intersection` */ + Decoder.intersection; + /** See `Decoder.withDefault` */ + Decoder.withDefault; + /** See `Decoder.valueAt` */ + Decoder.valueAt; + /** See `Decoder.succeed` */ + Decoder.succeed; + /** See `Decoder.fail` */ + Decoder.fail; + /** See `Decoder.lazy` */ + Decoder.lazy; + + const nonEmptyStringDecoder = string().where((s) => s.length > 0, "Expected a non-empty string"); + const nonNegativeNumberDecoder = number().where((num) => num >= 0, "Expected a non-negative number"); + + const intentDefinitionDecoder = object({ + name: nonEmptyStringDecoder, + displayName: optional(string()), + contexts: optional(array(string())), + customConfig: optional(object()) + }); + const v2TypeDecoder = oneOf(constant("web"), constant("native"), constant("citrix"), constant("onlineNative"), constant("other")); + const v2DetailsDecoder = object({ + url: nonEmptyStringDecoder + }); + const v2IconDecoder = object({ + src: nonEmptyStringDecoder, + size: optional(nonEmptyStringDecoder), + type: optional(nonEmptyStringDecoder) + }); + const v2ScreenshotDecoder = object({ + src: nonEmptyStringDecoder, + size: optional(nonEmptyStringDecoder), + type: optional(nonEmptyStringDecoder), + label: optional(nonEmptyStringDecoder) + }); + const v2ListensForIntentDecoder = object({ + contexts: array(nonEmptyStringDecoder), + displayName: optional(nonEmptyStringDecoder), + resultType: optional(nonEmptyStringDecoder), + customConfig: optional(anyJson()) + }); + const v2IntentsDecoder = object({ + listensFor: optional(dict(v2ListensForIntentDecoder)), + raises: optional(dict(array(nonEmptyStringDecoder))) + }); + const v2UserChannelDecoder = object({ + broadcasts: optional(array(nonEmptyStringDecoder)), + listensFor: optional(array(nonEmptyStringDecoder)) + }); + const v2AppChannelDecoder = object({ + name: nonEmptyStringDecoder, + description: optional(nonEmptyStringDecoder), + broadcasts: optional(array(nonEmptyStringDecoder)), + listensFor: optional(array(nonEmptyStringDecoder)) + }); + const v2InteropDecoder = object({ + intents: optional(v2IntentsDecoder), + userChannels: optional(v2UserChannelDecoder), + appChannels: optional(array(v2AppChannelDecoder)) + }); + const glue42ApplicationDetailsDecoder = object({ + url: optional(nonEmptyStringDecoder), + top: optional(number()), + left: optional(number()), + width: optional(nonNegativeNumberDecoder), + height: optional(nonNegativeNumberDecoder) + }); + const glue42HostManifestsBrowserDecoder = object({ + name: optional(nonEmptyStringDecoder), + type: optional(nonEmptyStringDecoder.where((s) => s === "window", "Expected a value of window")), + title: optional(nonEmptyStringDecoder), + version: optional(nonEmptyStringDecoder), + customProperties: optional(anyJson()), + icon: optional(string()), + caption: optional(string()), + details: optional(glue42ApplicationDetailsDecoder), + intents: optional(array(intentDefinitionDecoder)), + hidden: optional(boolean()) + }); + const v1DefinitionDecoder = object({ + name: nonEmptyStringDecoder, + appId: nonEmptyStringDecoder, + title: optional(nonEmptyStringDecoder), + version: optional(nonEmptyStringDecoder), + manifest: nonEmptyStringDecoder, + manifestType: nonEmptyStringDecoder, + tooltip: optional(nonEmptyStringDecoder), + description: optional(nonEmptyStringDecoder), + contactEmail: optional(nonEmptyStringDecoder), + supportEmail: optional(nonEmptyStringDecoder), + publisher: optional(nonEmptyStringDecoder), + images: optional(array(object({ url: optional(nonEmptyStringDecoder) }))), + icons: optional(array(object({ icon: optional(nonEmptyStringDecoder) }))), + customConfig: anyJson(), + intents: optional(array(intentDefinitionDecoder)) + }); + const v2LocalizedDefinitionDecoder = object({ + appId: optional(nonEmptyStringDecoder), + name: optional(nonEmptyStringDecoder), + details: optional(v2DetailsDecoder), + version: optional(nonEmptyStringDecoder), + title: optional(nonEmptyStringDecoder), + tooltip: optional(nonEmptyStringDecoder), + lang: optional(nonEmptyStringDecoder), + description: optional(nonEmptyStringDecoder), + categories: optional(array(nonEmptyStringDecoder)), + icons: optional(array(v2IconDecoder)), + screenshots: optional(array(v2ScreenshotDecoder)), + contactEmail: optional(nonEmptyStringDecoder), + supportEmail: optional(nonEmptyStringDecoder), + moreInfo: optional(nonEmptyStringDecoder), + publisher: optional(nonEmptyStringDecoder), + customConfig: optional(array(anyJson())), + hostManifests: optional(anyJson()), + interop: optional(v2InteropDecoder) + }); + const v2DefinitionDecoder = object({ + appId: nonEmptyStringDecoder, + name: nonEmptyStringDecoder, + type: v2TypeDecoder, + details: v2DetailsDecoder, + version: optional(nonEmptyStringDecoder), + title: optional(nonEmptyStringDecoder), + tooltip: optional(nonEmptyStringDecoder), + lang: optional(nonEmptyStringDecoder), + description: optional(nonEmptyStringDecoder), + categories: optional(array(nonEmptyStringDecoder)), + icons: optional(array(v2IconDecoder)), + screenshots: optional(array(v2ScreenshotDecoder)), + contactEmail: optional(nonEmptyStringDecoder), + supportEmail: optional(nonEmptyStringDecoder), + moreInfo: optional(nonEmptyStringDecoder), + publisher: optional(nonEmptyStringDecoder), + customConfig: optional(array(anyJson())), + hostManifests: optional(anyJson()), + interop: optional(v2InteropDecoder), + localizedVersions: optional(dict(v2LocalizedDefinitionDecoder)) + }); + const allDefinitionsDecoder = oneOf(v1DefinitionDecoder, v2DefinitionDecoder); + + const parseDecoderErrorToStringMessage = (error) => { + return `${error.kind} at ${error.at}: ${JSON.stringify(error.input)}. Reason - ${error.message}`; + }; + + class FDC3Service { + fdc3ToDesktopDefinitionType = { + web: "window", + native: "exe", + citrix: "citrix", + onlineNative: "clickonce", + other: "window" + }; + toApi() { + return { + isFdc3Definition: this.isFdc3Definition.bind(this), + parseToBrowserBaseAppData: this.parseToBrowserBaseAppData.bind(this), + parseToDesktopAppConfig: this.parseToDesktopAppConfig.bind(this) + }; + } + isFdc3Definition(definition) { + const decodeRes = allDefinitionsDecoder.run(definition); + if (!decodeRes.ok) { + return { isFdc3: false, reason: parseDecoderErrorToStringMessage(decodeRes.error) }; + } + if (definition.appId && definition.details) { + return { isFdc3: true, version: "2.0" }; + } + if (definition.manifest) { + return { isFdc3: true, version: "1.2" }; + } + return { isFdc3: false, reason: "The passed definition is not FDC3" }; + } + parseToBrowserBaseAppData(definition) { + const { isFdc3, version } = this.isFdc3Definition(definition); + if (!isFdc3) { + throw new Error("The passed definition is not FDC3"); + } + const decodeRes = allDefinitionsDecoder.run(definition); + if (!decodeRes.ok) { + throw new Error(`Invalid FDC3 ${version} definition. Error: ${parseDecoderErrorToStringMessage(decodeRes.error)}`); + } + const userProperties = this.getUserPropertiesFromDefinition(definition, version); + const createOptions = { url: this.getUrl(definition, version) }; + const baseApplicationData = { + name: definition.appId, + type: "window", + createOptions, + userProperties: { + ...userProperties, + intents: version === "1.2" + ? userProperties.intents + : this.getIntentsFromV2AppDefinition(definition), + details: createOptions + }, + title: definition.title, + version: definition.version, + icon: this.getIconFromDefinition(definition, version), + caption: definition.description, + fdc3: version === "2.0" ? { ...definition, definitionVersion: "2.0" } : undefined, + }; + const ioConnectDefinition = definition.hostManifests?.ioConnect || definition.hostManifests?.["Glue42"]; + if (!ioConnectDefinition) { + return baseApplicationData; + } + const ioDefinitionDecodeRes = glue42HostManifestsBrowserDecoder.run(ioConnectDefinition); + if (!ioDefinitionDecodeRes.ok) { + throw new Error(`Invalid FDC3 ${version} definition. Error: ${parseDecoderErrorToStringMessage(ioDefinitionDecodeRes.error)}`); + } + if (!Object.keys(ioDefinitionDecodeRes.result).length) { + return baseApplicationData; + } + return this.mergeBaseAppDataWithGlueManifest(baseApplicationData, ioDefinitionDecodeRes.result); + } + parseToDesktopAppConfig(definition) { + const { isFdc3, version } = this.isFdc3Definition(definition); + if (!isFdc3) { + throw new Error("The passed definition is not FDC3"); + } + const decodeRes = allDefinitionsDecoder.run(definition); + if (!decodeRes.ok) { + throw new Error(`Invalid FDC3 ${version} definition. Error: ${parseDecoderErrorToStringMessage(decodeRes.error)}`); + } + if (version === "1.2") { + const fdc3v1Definition = definition; + return { + name: fdc3v1Definition.appId, + type: "window", + details: { + url: this.getUrl(definition, version) + }, + version: fdc3v1Definition.version, + title: fdc3v1Definition.title, + tooltip: fdc3v1Definition.tooltip, + caption: fdc3v1Definition.description, + icon: fdc3v1Definition.icons?.[0].icon, + intents: fdc3v1Definition.intents, + customProperties: { + manifestType: fdc3v1Definition.manifestType, + images: fdc3v1Definition.images, + contactEmail: fdc3v1Definition.contactEmail, + supportEmail: fdc3v1Definition.supportEmail, + publisher: fdc3v1Definition.publisher, + icons: fdc3v1Definition.icons, + customConfig: fdc3v1Definition.customConfig + } + }; + } + const fdc3v2Definition = definition; + const desktopDefinition = { + name: fdc3v2Definition.appId, + type: this.fdc3ToDesktopDefinitionType[fdc3v2Definition.type], + details: fdc3v2Definition.details, + version: fdc3v2Definition.version, + title: fdc3v2Definition.title, + tooltip: fdc3v2Definition.tooltip, + caption: fdc3v2Definition.description, + icon: this.getIconFromDefinition(fdc3v2Definition, "2.0"), + intents: this.getIntentsFromV2AppDefinition(fdc3v2Definition), + fdc3: { ...fdc3v2Definition, definitionVersion: "2.0" } + }; + const ioConnectDefinition = definition.hostManifests?.ioConnect || definition.hostManifests?.["Glue42"]; + if (!ioConnectDefinition) { + return desktopDefinition; + } + if (typeof ioConnectDefinition !== "object" || Array.isArray(ioConnectDefinition)) { + throw new Error(`Invalid '${definition.hostManifests.ioConnect ? "hostManifests.ioConnect" : "hostManifests['Glue42']"}' key`); + } + return this.mergeDesktopConfigWithGlueManifest(desktopDefinition, ioConnectDefinition); + } + getUserPropertiesFromDefinition(definition, version) { + if (version === "1.2") { + return Object.fromEntries(Object.entries(definition).filter(([key]) => !connectBrowserAppProps.includes(key))); + } + return Object.fromEntries(Object.entries(definition).filter(([key]) => !connectBrowserAppProps.includes(key) && !fdc3v2AppProps.includes(key))); + } + getUrl(definition, version) { + let url; + if (version === "1.2") { + const parsedManifest = JSON.parse(definition.manifest); + url = parsedManifest.details?.url || parsedManifest.url; + } + else { + url = definition.details?.url; + } + if (!url || typeof url !== "string") { + throw new Error(`Invalid FDC3 ${version} definition. Provide valid 'url' under '${version === "1.2" ? "manifest" : "details"}' key`); + } + return url; + } + getIntentsFromV2AppDefinition(definition) { + const fdc3Intents = definition.interop?.intents?.listensFor; + if (!fdc3Intents) { + return; + } + const intents = Object.entries(fdc3Intents).map((fdc3Intent) => { + const [intentName, intentData] = fdc3Intent; + return { + name: intentName, + ...intentData + }; + }); + return intents; + } + getIconFromDefinition(definition, version) { + if (version === "1.2") { + return definition.icons?.find((iconDef) => iconDef.icon)?.icon || undefined; + } + return definition.icons?.find((iconDef) => iconDef.src)?.src || undefined; + } + mergeBaseAppDataWithGlueManifest(baseAppData, hostManifestDefinition) { + let baseApplicationDefinition = baseAppData; + if (hostManifestDefinition.details) { + const details = { ...baseAppData.createOptions, ...hostManifestDefinition.details }; + baseApplicationDefinition.createOptions = details; + baseApplicationDefinition.userProperties.details = details; + } + if (Array.isArray(hostManifestDefinition.intents)) { + baseApplicationDefinition.userProperties.intents = (baseApplicationDefinition.userProperties.intents || []).concat(hostManifestDefinition.intents); + } + baseApplicationDefinition = { ...baseApplicationDefinition, ...hostManifestDefinition }; + delete baseApplicationDefinition.details; + delete baseApplicationDefinition.intents; + return baseApplicationDefinition; + } + mergeDesktopConfigWithGlueManifest(config, desktopDefinition) { + const appConfig = Object.assign({}, config, desktopDefinition, { details: { ...config.details, ...desktopDefinition.details } }); + if (Array.isArray(desktopDefinition.intents)) { + appConfig.intents = (config.intents || []).concat(desktopDefinition.intents); + } + return appConfig; + } + } + + const decoders$1 = { + common: { + nonEmptyStringDecoder, + nonNegativeNumberDecoder + }, + fdc3: { + allDefinitionsDecoder, + v1DefinitionDecoder, + v2DefinitionDecoder + } + }; + + var INTENTS_ERRORS; + (function (INTENTS_ERRORS) { + INTENTS_ERRORS["USER_CANCELLED"] = "User Closed Intents Resolver UI without choosing a handler"; + INTENTS_ERRORS["CALLER_NOT_DEFINED"] = "Caller Id is not defined"; + INTENTS_ERRORS["TIMEOUT_HIT"] = "Timeout hit"; + INTENTS_ERRORS["INTENT_NOT_FOUND"] = "Cannot find Intent"; + INTENTS_ERRORS["HANDLER_NOT_FOUND"] = "Cannot find Intent Handler"; + INTENTS_ERRORS["TARGET_INSTANCE_UNAVAILABLE"] = "Cannot start Target Instance"; + INTENTS_ERRORS["INTENT_DELIVERY_FAILED"] = "Target Instance did not add a listener"; + INTENTS_ERRORS["RESOLVER_UNAVAILABLE"] = "Intents Resolver UI unavailable"; + INTENTS_ERRORS["RESOLVER_TIMEOUT"] = "User did not choose a handler"; + INTENTS_ERRORS["INVALID_RESOLVER_RESPONSE"] = "Intents Resolver UI returned invalid response"; + INTENTS_ERRORS["INTENT_HANDLER_REJECTION"] = "Intent Handler function processing the raised intent threw an error or rejected the promise it returned"; + })(INTENTS_ERRORS || (INTENTS_ERRORS = {})); + + class IoC { + _fdc3; + _decoders = decoders$1; + _errors = { + intents: INTENTS_ERRORS + }; + get fdc3() { + if (!this._fdc3) { + this._fdc3 = new FDC3Service().toApi(); + } + return this._fdc3; + } + get decoders() { + return this._decoders; + } + get errors() { + return this._errors; + } + } + + const ioc = new IoC(); + ioc.fdc3; + ioc.decoders; + const errors = ioc.errors; + + const GLUE42_FDC3_INTENTS_METHOD_PREFIX = "Tick42.FDC3.Intents."; + const INTENTS_RESOLVER_INTEROP_PREFIX = "T42.Intents.Resolver.Control"; + const INTENTS_RESOLVER_WIDTH = 400; + const INTENTS_RESOLVER_HEIGHT = 440; + const DEFAULT_RESOLVER_RESPONSE_TIMEOUT = 60 * 1000; + const INTENT_HANDLER_DEFAULT_PROPS = ["applicationName", "type"]; + const INTENTS_RESOLVER_APP_NAME = "intentsResolver"; + const MAX_SET_TIMEOUT_DELAY = 2147483647; + const DEFAULT_METHOD_RESPONSE_TIMEOUT_MS = 60 * 1000; + const DEFAULT_RAISE_TIMEOUT_MS = 90 * 1000; + const DEFAULT_PICK_HANDLER_BY_TIMEOUT_MS = 90 * 1000; + const ERRORS = errors.intents; + + const PromisePlus = (executor, timeoutMilliseconds, timeoutMessage) => { + return new Promise((resolve, reject) => { + const timeout = setTimeout(() => { + const message = timeoutMessage || `Promise timeout hit: ${timeoutMilliseconds}`; + reject(message); + }, timeoutMilliseconds); + const providedPromise = new Promise(executor); + providedPromise + .then((result) => { + clearTimeout(timeout); + resolve(result); + }) + .catch((error) => { + clearTimeout(timeout); + reject(error); + }); + }); + }; + const PromiseWrap = (promise, timeoutMilliseconds, timeoutMessage) => { + return new Promise((resolve, reject) => { + let promiseActive = true; + const timeout = setTimeout(() => { + if (!promiseActive) { + return; + } + promiseActive = false; + const message = timeoutMessage || `Promise timeout hit: ${timeoutMilliseconds}`; + reject(message); + }, timeoutMilliseconds); + promise() + .then((result) => { + if (!promiseActive) { + return; + } + promiseActive = false; + clearTimeout(timeout); + resolve(result); + }) + .catch((error) => { + if (!promiseActive) { + return; + } + promiseActive = false; + clearTimeout(timeout); + reject(error); + }); + }); + }; + + const validateIntentHandlerAsResponse = (handler) => { + if (typeof handler !== "object") { + return { isValid: false, error: `Response object has invalid 'handler' key. Expected an object, got ${typeof handler}` }; + } + const compulsoryKeysExist = INTENT_HANDLER_DEFAULT_PROPS.filter((key) => !(key in handler)); + if (compulsoryKeysExist.length) { + return { isValid: false, error: `Handler in Response object does not provide compulsory keys: ${compulsoryKeysExist.join(", ")}` }; + } + return { isValid: true, ok: handler }; + }; + const validateIntentRequestTarget = (target) => { + if (!target) { + return; + } + if (typeof target !== "string" && typeof target !== "object") { + throw new Error(`Please provide the intent target as one of the valid values: "reuse", "startNew", { app: string }, { instance: string } `); + } + }; + const validateIntentRequestContext = (context) => { + if (!context) { + return; + } + if (typeof context !== "object") { + throw new Error(`Please provide the intent context as an object`); + } + if (context.type && typeof context.type !== "string") { + throw new Error(`Please provide the intent context as an object with 'type' property as string`); + } + if (context.data && typeof context.data !== "object") { + throw new Error(`Please provide the intent context as an object with 'data' property as object`); + } + }; + const validateIntentRequestHandler = (handler) => { + if (!handler.applicationName) { + throw new Error(`Please provide applicationName for handler ${JSON.stringify(handler)}`); + } + if (!handler.type) { + throw new Error(`Please provide type for handler ${JSON.stringify(handler)}`); + } + if (handler.type === "instance" && !handler.instanceId) { + throw new Error(`Please provide instanceId for handler ${JSON.stringify(handler)}`); + } + }; + const validateIntentRequestTimeout = (timeout) => { + if (!timeout) { + return; + } + if (typeof timeout !== "number") { + throw new Error(`Please provide the timeout as a number`); + } + if (timeout <= 0) { + throw new Error(`Please provide the timeout as a positive number`); + } + }; + const validateWaitUserResponseIndefinitely = (waitUserResponseIndefinitely) => { + if (!waitUserResponseIndefinitely) { + return; + } + if (typeof waitUserResponseIndefinitely !== "boolean") { + throw new Error("Please provide waitUserResponseIndefinitely as a boolean"); + } + }; + const validateHandlerFilter = (handlerFilter) => { + if (!handlerFilter) { + throw new Error(`Provide 'handlerFilter' with at least one filter criteria of the following: 'intent' | 'contextTypes' | 'resultType' | 'applicationNames'`); + } + const { title, openResolver, timeout, intent, contextTypes, resultType, applicationNames } = handlerFilter; + if (typeof title !== "undefined" && (typeof title !== "string" || !title.length)) { + throw new Error(`Provide 'title' as a non empty string`); + } + if (typeof openResolver !== "undefined" && typeof openResolver !== "boolean") { + throw new Error(`Provide 'openResolver' prop as a boolean`); + } + if (typeof timeout !== "undefined" && (typeof timeout !== "number" || timeout <= 0)) { + throw new Error(`Provide 'timeout' prop as a positive number`); + } + if (typeof intent !== "undefined" && (typeof intent !== "string" || !intent.length)) { + throw new Error(`Provide 'intent' as a non empty string`); + } + if (typeof contextTypes !== "undefined" && (!Array.isArray(contextTypes) || contextTypes.some(ctx => typeof ctx !== "string"))) { + throw new Error(`Provide 'contextTypes' as an array of non empty strings`); + } + if (typeof resultType !== "undefined" && (typeof resultType !== "string" || !resultType.length)) { + throw new Error(`Provide 'resultType' as a non empty string`); + } + if (typeof applicationNames !== "undefined" && (!Array.isArray(applicationNames) || applicationNames.some(appName => typeof appName !== "string"))) { + throw new Error(`Provide 'applicationNames' as an array of non empty strings`); + } + const errorMsg = "Provide at least one filter criteria of the following: 'intent' | 'contextTypes' | 'resultType' | 'applicationNames'"; + if (!Object.keys(handlerFilter).length) { + throw new Error(errorMsg); + } + if (!intent && !resultType && (!contextTypes || !contextTypes.length) && (!applicationNames || !applicationNames.length)) { + throw new Error(errorMsg); + } + }; + const validateResolverResponse = (responseObj) => { + var _a, _b; + if (typeof responseObj.intent !== "string") { + return { isValid: false, error: `Response object has invalid 'intent' key. Expected a string, got ${typeof responseObj.intent}` }; + } + if (((_a = responseObj.userSettings) === null || _a === void 0 ? void 0 : _a.preserveChoice) && typeof ((_b = responseObj.userSettings) === null || _b === void 0 ? void 0 : _b.preserveChoice) !== "boolean") { + return { isValid: false, error: `Response object has invalid 'userSettings.preserveChoice' key. Expected a boolean, got ${typeof responseObj.userSettings.preserveChoice}` }; + } + const { isValid, error } = validateIntentHandlerAsResponse(responseObj.handler); + return isValid + ? { isValid: true, ok: responseObj } + : { isValid, error }; + }; + const validateIntentRequest = (request) => { + validateIntentRequestContext(request.context); + validateIntentRequestTarget(request.target); + validateIntentRequestTimeout(request.timeout); + validateWaitUserResponseIndefinitely(request.waitUserResponseIndefinitely); + if (typeof request.clearSavedHandler !== "undefined" && typeof request.clearSavedHandler !== "boolean") { + throw new Error("Please provide 'clearSavedHandler' as a boolean"); + } + if (request.handlers) { + request.handlers.forEach((handler) => validateIntentRequestHandler(handler)); + } + }; + const validateIntentHandler = (handler) => { + if (typeof handler !== "object") { + throw new Error("IntentHandler must be an object"); + } + if (typeof handler.applicationName !== "string" || !handler.applicationName.length) { + throw new Error(`Please provide 'applicationName' as a non-empty string`); + } + if (typeof handler.type !== "string" || !["app", "instance"].includes(handler.type)) { + throw new Error(`Invalid 'type' property. Expected 'app' | 'instance' got ${handler.type}`); + } + if (typeof handler.applicationTitle !== "undefined" && typeof handler.applicationTitle !== "string") { + throw new Error(`Provide 'applicationTitle' as a string`); + } + if (typeof handler.applicationDescription !== "undefined" && typeof handler.applicationDescription !== "string") { + throw new Error(`Provide 'applicationDescription' as a string`); + } + if (typeof handler.applicationIcon !== "undefined" && typeof handler.applicationIcon !== "string") { + throw new Error(`Provide 'applicationIcon' as a string`); + } + if (typeof handler.displayName !== "undefined" && typeof handler.displayName !== "string") { + throw new Error(`Provide 'displayName' as a string`); + } + if (typeof handler.contextTypes !== "undefined" && (!Array.isArray(handler.contextTypes) || handler.contextTypes.some(ctx => typeof ctx !== "string"))) { + throw new Error(`Provide 'contextTypes' as an array of non empty strings`); + } + if (typeof handler.instanceId !== "undefined" && typeof handler.instanceId !== "string") { + throw new Error(`Provide 'instanceId' as a string`); + } + if (typeof handler.instanceTitle !== "undefined" && typeof handler.instanceTitle !== "string") { + throw new Error(`Provide 'instanceTitle' as a string`); + } + if (typeof handler.resultType !== "undefined" && typeof handler.resultType !== "string") { + throw new Error(`Provide 'resultType' as a string`); + } + }; + const clearNullUndefined = (obj) => { + Object.keys(obj).forEach(key => { + if (obj[key] === null || obj[key] === undefined) { + delete obj[key]; + } + }); + }; + + class Intents { + constructor(interop, windows, logger, options, prefsController, appManager) { + this.interop = interop; + this.windows = windows; + this.logger = logger; + this.prefsController = prefsController; + this.appManager = appManager; + this.myIntents = new Set(); + this.intentsResolverResponsePromises = {}; + this.useIntentsResolverUI = true; + this.unregisterIntentPromises = []; + this.addedHandlerInfoPerApp = {}; + this.checkIfIntentsResolverIsEnabled(options, appManager); + } + async find(intentFilter) { + await Promise.all(this.unregisterIntentPromises); + let intents = await this.all(); + if (typeof intentFilter === "undefined") { + return intents; + } + if (typeof intentFilter === "string") { + return intents.filter((intent) => intent.name === intentFilter); + } + if (typeof intentFilter !== "object") { + throw new Error("Please provide the intentFilter as a string or an object!"); + } + if (intentFilter.contextType) { + const ctToLower = intentFilter.contextType.toLowerCase(); + intents = intents.filter((intent) => intent.handlers.some((handler) => { var _a; return (_a = handler.contextTypes) === null || _a === void 0 ? void 0 : _a.some((ct) => ct.toLowerCase() === ctToLower); })); + } + if (intentFilter.resultType) { + const resultTypeToLower = intentFilter.resultType.toLowerCase(); + intents = intents.filter((intent) => intent.handlers.some((handler) => { var _a; return ((_a = handler.resultType) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === resultTypeToLower; })); + } + if (intentFilter.name) { + intents = intents.filter((intent) => intent.name === intentFilter.name); + } + return intents; + } + async raise(intentRequest) { + if ((typeof intentRequest !== "string" && typeof intentRequest !== "object") || (typeof intentRequest === "object" && typeof intentRequest.intent !== "string")) { + throw new Error("Please provide the intent as a string or an object with an intent property!"); + } + if (typeof intentRequest === "string") { + intentRequest = { intent: intentRequest }; + } + validateIntentRequest(intentRequest); + await Promise.all(this.unregisterIntentPromises); + if (intentRequest.clearSavedHandler) { + this.logger.trace(`User removes saved handler for intent ${intentRequest.intent}`); + await this.removeRememberedHandler(intentRequest.intent); + } + const resolverInstance = {}; + const timeout = intentRequest.waitUserResponseIndefinitely ? MAX_SET_TIMEOUT_DELAY : intentRequest.timeout || DEFAULT_RAISE_TIMEOUT_MS; + const resultFromRememberedHandler = await this.checkHandleRaiseWithRememberedHandler(intentRequest, resolverInstance, timeout); + if (resultFromRememberedHandler) { + return resultFromRememberedHandler; + } + const coreRaiseIntentFn = this.coreRaiseIntent.bind(this, { request: intentRequest, resolverInstance, timeout }); + if (intentRequest.waitUserResponseIndefinitely) { + return coreRaiseIntentFn(); + } + const resultPromise = PromiseWrap(coreRaiseIntentFn, timeout, `${ERRORS.TIMEOUT_HIT} hit for intent request ${JSON.stringify(intentRequest)}`); + resultPromise.catch(() => this.handleRaiseOnError(resolverInstance.instanceId)); + return resultPromise; + } + async all() { + await Promise.all(this.unregisterIntentPromises); + let apps; + try { + const result = await this.interop.invoke("T42.ACS.GetApplications", { withIntentsInfo: true }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + apps = result.returned.applications; + } + catch (e) { + this.logger.error(`Failed to get the applications!`, e); + return []; + } + const intents = {}; + const appsWithIntents = apps.filter((app) => app.intents && app.intents.length > 0); + for (const app of appsWithIntents) { + for (const intentDef of app.intents) { + let intent = intents[intentDef.name]; + if (!intent) { + intent = { + name: intentDef.name, + handlers: [], + }; + intents[intentDef.name] = intent; + } + const handler = { + applicationName: app.name, + applicationTitle: app.title || "", + applicationDescription: app.caption, + displayName: intentDef.displayName, + contextTypes: intentDef.contexts, + applicationIcon: app.icon, + type: "app", + resultType: intentDef.resultType + }; + intent.handlers.push(handler); + } + } + const servers = this.interop.servers(); + const serverWindowIds = servers.map((server) => server.windowId).filter((serverWindowId) => typeof serverWindowId !== "undefined"); + const T42WndGetInfo = "T42.Wnd.GetInfo"; + const isT42WndGetInfoMethodRegistered = this.interop.methods().some((method) => method.name === T42WndGetInfo); + let windowsInfos; + if (isT42WndGetInfoMethodRegistered) { + try { + const result = await this.interop.invoke(T42WndGetInfo, { ids: serverWindowIds }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + windowsInfos = result.returned.windows; + } + catch (e) { + } + } + for (const server of servers) { + await Promise.all(server.getMethods() + .filter((method) => method.name.startsWith(GLUE42_FDC3_INTENTS_METHOD_PREFIX)) + .map(async (method) => { + const intentName = method.name.replace(GLUE42_FDC3_INTENTS_METHOD_PREFIX, ""); + let intent = intents[intentName]; + if (!intent) { + intent = { + name: intentName, + handlers: [], + }; + intents[intentName] = intent; + } + const title = await this.windowsIdToTitle(server.windowId, windowsInfos); + const handler = this.constructIntentHandler({ method, apps, server, intentName, title }); + intent.handlers.push(handler); + })); + } + return Object.values(intents); + } + addIntentListener(intent, handler) { + if ((typeof intent !== "string" && typeof intent !== "object") || (typeof intent === "object" && typeof intent.intent !== "string")) { + throw new Error("Please provide the intent as a string or an object with an intent property!"); + } + if (typeof handler !== "function") { + throw new Error("Please provide the handler as a function!"); + } + const intentName = typeof intent === "string" ? intent : intent.intent; + const methodName = `${GLUE42_FDC3_INTENTS_METHOD_PREFIX}${intentName}`; + let intentFlag = {}; + let registerPromise; + const alreadyRegistered = this.myIntents.has(intentName); + if (alreadyRegistered) { + throw new Error(`Intent listener for intent ${intentName} already registered!`); + } + this.myIntents.add(intentName); + const result = { + unsubscribe: () => { + this.myIntents.delete(intentName); + registerPromise + .then(() => this.interop.unregister(methodName)) + .catch((err) => this.logger.trace(`Unregistration of a method with name ${methodName} failed with reason: ${JSON.stringify(err)}`)); + } + }; + if (typeof intent === "object") { + const { intent: removed, ...rest } = intent; + intentFlag = rest; + } + registerPromise = this.interop.register({ name: methodName, flags: { intent: intentFlag } }, (args) => { + if (this.myIntents.has(intentName)) { + return handler(args); + } + }); + registerPromise.catch((err) => { + this.myIntents.delete(intentName); + this.logger.warn(`Registration of a method with name ${methodName} failed with reason: ${JSON.stringify(err)}`); + }); + return result; + } + async register(intent, handler) { + if ((typeof intent !== "string" && typeof intent !== "object") || (typeof intent === "object" && typeof intent.intent !== "string")) { + throw new Error("Please provide the intent as a string or an object with an intent property!"); + } + if (typeof handler !== "function") { + throw new Error("Please provide the handler as a function!"); + } + await Promise.all(this.unregisterIntentPromises); + const intentName = typeof intent === "string" ? intent : intent.intent; + const methodName = this.buildInteropMethodName(intentName); + let intentFlag = {}; + const alreadyRegistered = this.myIntents.has(intentName); + if (alreadyRegistered) { + throw new Error(`Intent listener for intent ${intentName} already registered!`); + } + this.myIntents.add(intentName); + if (typeof intent === "object") { + const { intent: removed, ...rest } = intent; + intentFlag = rest; + } + try { + await this.interop.register({ name: methodName, flags: { intent: intentFlag } }, (args, caller) => { + if (this.myIntents.has(intentName)) { + return handler(args, caller); + } + }); + } + catch (err) { + this.myIntents.delete(intentName); + throw new Error(`Registration of a method with name ${methodName} failed with reason: ${JSON.stringify(err)}`); + } + return { + unsubscribe: () => this.unsubscribeIntent(intentName) + }; + } + async filterHandlers(handlerFilter) { + var _a, _b; + validateHandlerFilter(handlerFilter); + if (handlerFilter.openResolver && !this.useIntentsResolverUI) { + throw new Error("Cannot resolve 'filterHandlers' request using Intents Resolver UI because it's globally disabled"); + } + (_a = this.logger) === null || _a === void 0 ? void 0 : _a.trace(`Received 'filterHandlers' command with request: ${JSON.stringify(handlerFilter)}`); + const filteredHandlers = this.filterHandlersBy(await this.all(), handlerFilter); + if (!filteredHandlers || !filteredHandlers.length) { + return { handlers: [] }; + } + const { open, reason } = this.checkIfResolverShouldBeOpenedForFilterHandlers(filteredHandlers, handlerFilter); + if (!open) { + (_b = this.logger) === null || _b === void 0 ? void 0 : _b.trace(`Intent Resolver UI won't be used. Reason: ${reason}`); + return { handlers: filteredHandlers }; + } + const resolverInstance = { instanceId: undefined }; + const timeout = handlerFilter.timeout || DEFAULT_PICK_HANDLER_BY_TIMEOUT_MS; + const handler = await PromiseWrap(() => this.startResolverApp({ request: handlerFilter, resolverInstance, method: 'filterHandlers' }), timeout, `Timeout of ${timeout}ms hit for 'filterHandlers' request with filter: ${JSON.stringify(handlerFilter)}`); + return { handlers: [handler] }; + } + async getIntents(handler) { + var _a; + this.logger.trace(`Received 'getIntents' command with handler ${JSON.stringify(handler)}`); + validateIntentHandler(handler); + const intents = await this.all(); + clearNullUndefined(handler); + (_a = this.logger) === null || _a === void 0 ? void 0 : _a.trace(`Extracting valid intents for the passed handler`); + const intentsWithInfo = this.extractIntentsWithInfoByHandler(intents, handler); + this.logger.trace(`Returning intents for handler ${JSON.stringify(handler)}`); + return { intents: intentsWithInfo }; + } + async clearSavedHandlers() { + this.logger.trace("Removing all saved handlers from prefs storage for current app"); + await this.prefsController.update({ intents: undefined }); + } + onHandlerAdded(callback) { + var _a; + const unAppAdded = (_a = this.appManager) === null || _a === void 0 ? void 0 : _a.onAppAdded(async (app) => { + var _a; + const appName = app.name; + const appDef = await app.getConfiguration(); + const isIntentHandler = (_a = appDef === null || appDef === void 0 ? void 0 : appDef.intents) === null || _a === void 0 ? void 0 : _a.length; + if (!isIntentHandler) { + return; + } + appDef.intents.forEach((intent) => { + const handler = this.constructIntentHandlerFromApp(appDef, intent); + if (!this.addedHandlerInfoPerApp[appName]) { + this.addedHandlerInfoPerApp[appName] = []; + } + const appHandlers = this.addedHandlerInfoPerApp[appName]; + appHandlers.push({ handler, name: intent.name }); + callback(handler, intent.name); + }); + }); + const unServerMethodAdded = this.interop.serverMethodAdded(({ method, server }) => { + if (!method.name.startsWith(GLUE42_FDC3_INTENTS_METHOD_PREFIX)) { + return; + } + const intentName = method.name.replace(GLUE42_FDC3_INTENTS_METHOD_PREFIX, ""); + const intentsInfo = this.constructIntentHandler({ method, apps: [], server, intentName, title: "" }); + callback(intentsInfo, intentName); + }); + return () => { + if (typeof unServerMethodAdded === "function") { + unServerMethodAdded(); + } + if (typeof unAppAdded === "function") { + unAppAdded(); + } + }; + } + onHandlerRemoved(callback) { + var _a; + const unAppRemoved = (_a = this.appManager) === null || _a === void 0 ? void 0 : _a.onAppRemoved(async (app) => { + const appName = app.name; + const handlers = this.addedHandlerInfoPerApp[appName]; + const isIntentHandler = handlers === null || handlers === void 0 ? void 0 : handlers.length; + if (!isIntentHandler) { + return; + } + delete this.addedHandlerInfoPerApp[appName]; + handlers.forEach((addedHandlerInfo) => { + callback(addedHandlerInfo.handler, addedHandlerInfo.name); + }); + }); + const unServerMethodAdded = this.interop.serverMethodRemoved(({ method, server }) => { + if (!method.name.startsWith(GLUE42_FDC3_INTENTS_METHOD_PREFIX)) { + return; + } + const intentName = method.name.replace(GLUE42_FDC3_INTENTS_METHOD_PREFIX, ""); + const intentsInfo = this.constructIntentHandler({ method, apps: [], server, intentName, title: "" }); + callback(intentsInfo, intentName); + }); + return () => { + if (typeof unServerMethodAdded === "function") { + unServerMethodAdded(); + } + if (typeof unAppRemoved === "function") { + unAppRemoved(); + } + }; + } + toAPI() { + return { + all: this.all.bind(this), + find: this.find.bind(this), + raise: this.raise.bind(this), + addIntentListener: this.addIntentListener.bind(this), + register: this.register.bind(this), + filterHandlers: this.filterHandlers.bind(this), + getIntents: this.getIntents.bind(this), + clearSavedHandlers: this.clearSavedHandlers.bind(this), + onHandlerAdded: this.onHandlerAdded.bind(this), + onHandlerRemoved: this.onHandlerRemoved.bind(this) + }; + } + filterHandlersBy(intents, filter) { + const filteredIntentsWithHandlers = intents.filter((intent) => { + if (filter.intent && filter.intent !== intent.name) { + return; + } + if (filter.resultType) { + const filteredHandlers = intent.handlers.filter((handler) => handler.resultType && handler.resultType === filter.resultType); + if (!filteredHandlers.length) + return; + intent.handlers = filteredHandlers; + } + if (filter.contextTypes) { + const filteredHandlers = intent.handlers.filter((handler) => { var _a; return (_a = filter.contextTypes) === null || _a === void 0 ? void 0 : _a.every((contextType) => { var _a; return (_a = handler.contextTypes) === null || _a === void 0 ? void 0 : _a.includes(contextType); }); }); + if (!filteredHandlers.length) + return; + intent.handlers = filteredHandlers; + } + if (filter.applicationNames) { + const filteredHandlers = intent.handlers.filter((handler) => { var _a; return (_a = filter.applicationNames) === null || _a === void 0 ? void 0 : _a.includes(handler.applicationName); }); + if (!filteredHandlers.length) + return; + intent.handlers = filteredHandlers; + } + return intent; + }); + return filteredIntentsWithHandlers.map((intent) => intent.handlers).flat(1); + } + async coreRaiseIntent({ request, resolverInstance, timeout }) { + var _a, _b; + const intentDef = await this.get(request.intent); + if (typeof intentDef === "undefined") { + throw new Error(`${ERRORS.INTENT_NOT_FOUND} with name ${request.intent}`); + } + const { open, reason } = await this.checkIfResolverShouldBeOpenedForRaise(intentDef, request); + if (!open) { + this.logger.trace(`Intent Resolver UI won't be used. Reason: ${reason}`); + return request.waitUserResponseIndefinitely + ? PromiseWrap(() => this.raiseIntent(request, timeout), timeout, `${ERRORS.TIMEOUT_HIT} - waited ${timeout}ms for 'raise' to resolve`) + : this.raiseIntent(request, timeout); + } + const resolverHandler = await this.startResolverApp({ request, method: "raise", resolverInstance }); + (_a = this.logger) === null || _a === void 0 ? void 0 : _a.trace(`Raising intent to target handler: ${JSON.stringify(resolverHandler)} with timeout of ${timeout}`); + if (request.waitUserResponseIndefinitely) { + return PromiseWrap(() => this.raiseIntentToTargetHandler(request, resolverHandler, timeout), timeout, `${ERRORS.TIMEOUT_HIT} - waited ${timeout}ms for 'raise' to resolve`); + } + const result = await this.raiseIntentToTargetHandler(request, resolverHandler, timeout); + (_b = this.logger) === null || _b === void 0 ? void 0 : _b.trace(`Result from raise() method for intent ${JSON.stringify(request.intent)}: ${JSON.stringify(result)}`); + return result; + } + async get(intent) { + return (await this.all()).find((registeredIntent) => registeredIntent.name === intent); + } + async raiseIntent(intentRequest, timeout) { + const intentName = intentRequest.intent; + const intentDef = await this.get(intentName); + if (typeof intentDef === "undefined") { + throw new Error(`${ERRORS.INTENT_NOT_FOUND} with name ${intentRequest.intent}`); + } + const firstFoundAppHandler = intentRequest.handlers ? this.findHandlerByFilter(intentRequest.handlers, { type: "app" }) : this.findHandlerByFilter(intentDef.handlers, { type: "app" }); + const firstFoundInstanceHandler = intentRequest.handlers ? this.findHandlerByFilter(intentRequest.handlers, { type: "instance" }) : this.findHandlerByFilter(intentDef.handlers, { type: "instance" }); + let handler; + if (!intentRequest.target || intentRequest.target === "reuse") { + handler = firstFoundInstanceHandler || firstFoundAppHandler; + } + if (intentRequest.target === "startNew") { + handler = firstFoundAppHandler; + } + if (typeof intentRequest.target === "object" && intentRequest.target.app) { + handler = this.findHandlerByFilter(intentDef.handlers, { app: intentRequest.target.app }); + } + if (typeof intentRequest.target === "object" && intentRequest.target.instance) { + handler = this.findHandlerByFilter(intentDef.handlers, { instance: intentRequest.target.instance, app: intentRequest.target.app }); + } + if (!handler) { + throw new Error(`Can not raise intent for request ${JSON.stringify(intentRequest)} - can not find intent handler!`); + } + const result = await this.raiseIntentToTargetHandler(intentRequest, handler, timeout); + return result; + } + async raiseIntentToTargetHandler(intentRequest, handler, timeout) { + var _a, _b; + (_a = this.logger) === null || _a === void 0 ? void 0 : _a.trace(`Raising intent to target handler:${JSON.stringify(handler)}`); + if (!handler.instanceId) { + const instanceIdPromise = this.invokeStartApp(handler.applicationName, intentRequest.context, intentRequest.options).catch((err) => { + const reasonMsg = typeof err === "string" ? err : JSON.stringify(err); + throw new Error(`${ERRORS.TARGET_INSTANCE_UNAVAILABLE}. Reason: ${reasonMsg}`); + }); + handler.instanceId = await instanceIdPromise; + } + const methodName = `${GLUE42_FDC3_INTENTS_METHOD_PREFIX}${intentRequest.intent}`; + const invokeOptions = { + methodResponseTimeoutMs: timeout ? timeout + 1000 : DEFAULT_METHOD_RESPONSE_TIMEOUT_MS, + waitTimeoutMs: timeout ? timeout + 1000 : DEFAULT_METHOD_RESPONSE_TIMEOUT_MS + }; + const resultPromise = this.interop.invoke(methodName, intentRequest.context, { instance: handler.instanceId }, invokeOptions) + .catch((err) => { + const reasonMsg = typeof err === "string" ? err : JSON.stringify(err); + throw new Error(`${ERRORS.INTENT_HANDLER_REJECTION}. Reason: ${reasonMsg}`); + }); + const result = await resultPromise; + (_b = this.logger) === null || _b === void 0 ? void 0 : _b.trace(`raiseIntent command completed. Returning result: ${JSON.stringify(result)}`); + return { + request: intentRequest, + handler: { ...handler, type: "instance" }, + result: result.returned + }; + } + async startResolverApp({ request, method, resolverInstance }) { + var _a, _b, _c, _d; + (_a = this.logger) === null || _a === void 0 ? void 0 : _a.trace(`Intents Resolver UI with app name ${this.intentsResolverAppName} will be used for request: ${JSON.stringify(request)}`); + const responseMethodName = await this.registerIntentResolverMethod(); + (_b = this.logger) === null || _b === void 0 ? void 0 : _b.trace(`Registered interop method ${responseMethodName}`); + const startContext = this.buildStartContext(method, request, responseMethodName); + const startOptions = await this.buildStartOptions(); + (_c = this.logger) === null || _c === void 0 ? void 0 : _c.trace(`Starting Intents Resolver UI with context: ${JSON.stringify(startContext)} and options: ${JSON.stringify(startOptions)}`); + const instance = await this.appManager.application(this.intentsResolverAppName).start(startContext, startOptions); + resolverInstance.instanceId = instance.id; + (_d = this.logger) === null || _d === void 0 ? void 0 : _d.trace(`Intents Resolver instance with id ${instance.id} opened`); + this.subscribeOnInstanceStopped(instance, method); + const timeout = request.timeout || method === "raise" ? DEFAULT_RAISE_TIMEOUT_MS : DEFAULT_PICK_HANDLER_BY_TIMEOUT_MS; + this.createResponsePromise({ + intent: method === "raise" ? request.intent : undefined, + instanceId: instance.id, + responseMethodName, + timeout, + errorMsg: `Timeout of ${timeout}ms hit waiting for the user to choose a handler ${method === "raise" + ? `for intent ${request.intent}` + : `for '${method}' method with filter ${JSON.stringify(request)}`}` + }); + const handler = await this.handleInstanceResponse({ instanceId: instance.id, caller: startContext.initialCaller, method, request }); + return handler; + } + async windowsIdToTitle(id, windowsInfos) { + var _a, _b; + if (typeof windowsInfos !== "undefined") { + return (_a = windowsInfos.find((windowsInfo) => windowsInfo.id === id)) === null || _a === void 0 ? void 0 : _a.title; + } + const window = (_b = this.windows) === null || _b === void 0 ? void 0 : _b.findById(id); + const title = await (window === null || window === void 0 ? void 0 : window.getTitle()); + return title; + } + async handleInstanceResponse({ instanceId, method, request, caller }) { + var _a, _b, _c; + try { + const response = await this.intentsResolverResponsePromises[instanceId].promise; + const subMessage = method === "raise" ? `for intent ${response.intent} ` : ""; + (_a = this.logger) === null || _a === void 0 ? void 0 : _a.trace(`Intent handler chosen ${subMessage}: ${JSON.stringify(response.handler)}. Stopping resolver instance with id ${instanceId}`); + this.stopResolverInstance(instanceId); + (_b = this.logger) === null || _b === void 0 ? void 0 : _b.trace(`Instance with id ${instanceId} successfully stopped`); + if ((_c = response.userSettings) === null || _c === void 0 ? void 0 : _c.preserveChoice) { + await this.saveUserChoice({ + intent: response.intent, + handler: response.handler, + filter: method === "filterHandlers" + ? { applicationNames: request.applicationNames, contextTypes: request.contextTypes, resultType: request.resultType } + : undefined, + caller + }); + } + return response.handler; + } + catch (error) { + this.stopResolverInstance(instanceId); + throw new Error(error); + } + } + async registerIntentResolverMethod() { + const methodName = INTENTS_RESOLVER_INTEROP_PREFIX + Utils.generateId(); + await this.interop.register(methodName, (args, callerId) => this.resolverResponseHandler(args, callerId)); + return methodName; + } + resolverResponseHandler(args, callerId) { + const { instance } = callerId; + const isValid = validateResolverResponse(args); + if (!isValid) { + this.logger.trace(`Intent Resolver instance with id ${callerId.instance} sent invalid response. Error: ${isValid.error}`); + this.intentsResolverResponsePromises[instance].reject(isValid.error); + this.stopResolverInstance(instance); + return; + } + const validResponse = isValid.ok; + this.intentsResolverResponsePromises[instance].resolve(validResponse); + this.cleanUpIntentResolverPromise(instance); + } + buildStartContext(method, request, methodName) { + var _a; + const myAppName = this.interop.instance.application || this.interop.instance.applicationName; + const myAppTitle = ((_a = this.appManager.application(myAppName)) === null || _a === void 0 ? void 0 : _a.title) || ""; + const baseStartContext = { + callerId: this.interop.instance.instance, + methodName, + initialCaller: { id: this.interop.instance.instance, applicationName: myAppName, applicationTitle: myAppTitle }, + resolverApi: "1.0" + }; + return method === "raise" + ? { ...baseStartContext, intent: request } + : { ...baseStartContext, handlerFilter: request }; + } + async buildStartOptions() { + const win = this.windows.my(); + if (!win) { + return; + } + const bounds = await win.getBounds(); + return { + top: await this.getResolverStartupTopBound(bounds), + left: (bounds.width - INTENTS_RESOLVER_WIDTH) / 2 + bounds.left, + width: INTENTS_RESOLVER_WIDTH, + height: INTENTS_RESOLVER_HEIGHT + }; + } + async getResolverStartupTopBound(bounds) { + const myDisplay = await this.windows.my().getDisplay(); + const minWorkareaHeight = myDisplay.workArea.height; + const top = (bounds.height - INTENTS_RESOLVER_HEIGHT) / 2 + bounds.top; + if (top < 0) { + return 0; + } + if (top + INTENTS_RESOLVER_HEIGHT > minWorkareaHeight) { + return minWorkareaHeight / 2; + } + return top; + } + createResponsePromise({ instanceId, intent, responseMethodName, timeout, errorMsg }) { + let resolve = () => { }; + let reject = () => { }; + const promise = PromisePlus((res, rej) => { + resolve = res; + reject = rej; + }, timeout, errorMsg); + this.intentsResolverResponsePromises[instanceId] = { intent, resolve, reject, promise, methodName: responseMethodName }; + } + async invokeStartApp(application, context, options) { + const result = await this.interop.invoke("T42.ACS.StartApplication", { Name: application, options: { ...options, startedByIntentAPI: true } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return result.returned.Id; + } + subscribeOnInstanceStopped(instance, method) { + const { application } = instance; + const unsub = application.onInstanceStopped((inst) => { + if (inst.id !== instance.id) { + return; + } + const intentPromise = this.intentsResolverResponsePromises[inst.id]; + if (!intentPromise) { + return unsub(); + } + const errorMsg = `Cannot resolve ${method === "raise" ? `raised intent ${intentPromise.intent}` : `'${method}' method`} - User closed ${instance.application.name} app without choosing a handler`; + intentPromise.reject(errorMsg); + this.cleanUpIntentResolverPromise(inst.id); + unsub(); + }); + } + async cleanUpIntentResolverPromise(instanceId) { + const intentPromise = this.intentsResolverResponsePromises[instanceId]; + if (!intentPromise) { + return; + } + const unregisterPromise = this.interop.unregister(intentPromise.methodName); + unregisterPromise.catch((error) => this.logger.warn(error)); + delete this.intentsResolverResponsePromises[instanceId]; + } + handleRaiseOnError(instanceId) { + if (!instanceId) { + return; + } + this.stopResolverInstance(instanceId); + } + stopResolverInstance(instanceId) { + const gdWin = this.windows.findById(instanceId); + gdWin === null || gdWin === void 0 ? void 0 : gdWin.close().catch((err) => this.logger.error(err)); + } + checkIfIntentsResolverIsEnabled(options, appManager) { + var _a, _b, _c, _d, _e; + if (!appManager) { + this.useIntentsResolverUI = false; + return; + } + this.useIntentsResolverUI = typeof ((_a = options.intents) === null || _a === void 0 ? void 0 : _a.enableIntentsResolverUI) === "boolean" + ? options.intents.enableIntentsResolverUI + : true; + this.intentsResolverAppName = (_c = (_b = options.intents) === null || _b === void 0 ? void 0 : _b.intentsResolverAppName) !== null && _c !== void 0 ? _c : INTENTS_RESOLVER_APP_NAME; + this.intentsResolverResponseTimeout = (_e = (_d = options.intents) === null || _d === void 0 ? void 0 : _d.methodResponseTimeoutMs) !== null && _e !== void 0 ? _e : DEFAULT_RESOLVER_RESPONSE_TIMEOUT; + } + async checkIfResolverShouldBeOpenedForRaise(intent, request) { + const checkOpen = this.checkIfIntentsResolverShouldBeOpened(); + if (!checkOpen.open) { + return checkOpen; + } + const hasMoreThanOneHandler = await this.checkIfIntentHasMoreThanOneHandler(intent, request); + if (!hasMoreThanOneHandler) { + return { open: false, reason: `Raised intent ${intent.name} has only one handler` }; + } + return { open: true }; + } + checkIfResolverShouldBeOpenedForFilterHandlers(handlers, filter) { + if (handlers.length === 1) { + return { open: false, reason: `There's only one valid intent handler for filter ${JSON.stringify(filter)}` }; + } + if (typeof (filter === null || filter === void 0 ? void 0 : filter.openResolver) === "boolean" && !filter.openResolver) { + return { open: false, reason: "Intents resolver is disabled by IntentHandler filter" }; + } + return this.checkIfIntentsResolverShouldBeOpened(); + } + checkIfIntentsResolverShouldBeOpened() { + if (!this.useIntentsResolverUI) { + return { open: false, reason: `Intent Resolver is disabled. Resolving to first found handler` }; + } + const intentsResolverApp = this.appManager.application(this.intentsResolverAppName); + if (!intentsResolverApp) { + return { open: false, reason: `Intent Resolver Application with name ${this.intentsResolverAppName} not found.` }; + } + return { open: true }; + } + async checkIfIntentHasMoreThanOneHandler(intent, request) { + const handlers = await this.removeSingletons(request.handlers || intent.handlers); + if (!request.target) { + return handlers.length > 1; + } + if (request.target === "reuse") { + return handlers.filter(handler => handler.type === "instance" && handler.instanceId).length > 1 || intent.handlers.filter(handler => handler.type === "app").length > 1; + } + if (request.target === "startNew") { + return handlers.filter(handler => handler.type === "app").length > 1; + } + if (request.target.instance) { + return false; + } + if (request.target.app) { + const searchedAppName = request.target.app; + const instanceHandlersByAppName = handlers.filter((handler) => handler.applicationName === searchedAppName && handler.instanceId); + return instanceHandlersByAppName.length > 1; + } + return false; + } + async removeSingletons(handlers) { + const handlersWithSingletonProp = await Promise.all(handlers.map(async (handler) => { + if (handler.type === "instance") { + return handler; + } + const appConfig = await this.appManager.application(handler.applicationName).getConfiguration(); + const isSingleton = appConfig.allowMultiple === false; + return { ...handler, isSingleton }; + })); + const filteredSingletonsWithOpenedInstances = handlersWithSingletonProp.filter((handler, _, currentHandlers) => { + if (handler.instanceId || !handler.isSingleton) { + return handler; + } + const openedInstance = currentHandlers.find((h) => h.instanceId && h.applicationName === handler.applicationName); + if (openedInstance) { + return; + } + return handler; + }); + return filteredSingletonsWithOpenedInstances; + } + buildInteropMethodName(intentName) { + return `${GLUE42_FDC3_INTENTS_METHOD_PREFIX}${intentName}`; + } + clearUnregistrationPromise(promiseToRemove) { + this.unregisterIntentPromises = this.unregisterIntentPromises.filter((promise) => promise !== promiseToRemove); + } + unsubscribeIntent(intentName) { + this.myIntents.delete(intentName); + const methodName = this.buildInteropMethodName(intentName); + const unregisterPromise = this.interop.unregister(methodName); + this.unregisterIntentPromises.push(unregisterPromise); + unregisterPromise + .then(() => { + this.clearUnregistrationPromise(unregisterPromise); + }) + .catch((err) => { + this.logger.error(`Unregistration of a method with name ${methodName} failed with reason: `, err); + this.clearUnregistrationPromise(unregisterPromise); + }); + } + findHandlerByFilter(handlers, filter) { + if (filter.type) { + return handlers.find((handler) => handler.type === filter.type); + } + if (filter.instance) { + return handlers.find((handler) => filter.app + ? handler.applicationName === filter.app && handler.instanceId === filter.instance + : handler.instanceId === filter.instance); + } + if (filter.app) { + return handlers.find((handler) => handler.applicationName === filter.app); + } + } + extractIntentsWithInfoByHandler(intents, handler) { + const intentsWithInfo = intents.reduce((validIntentsWithInfo, intent) => { + intent.handlers.forEach((currentHandler) => { + const isValid = Object.keys(handler).every((key) => { + var _a; + return key === "contextTypes" + ? (_a = handler.contextTypes) === null || _a === void 0 ? void 0 : _a.every((contextType) => { var _a; return (_a = currentHandler.contextTypes) === null || _a === void 0 ? void 0 : _a.includes(contextType); }) + : currentHandler[key] === handler[key]; + }); + if (!isValid) { + return; + } + const intentWithInfo = { + intent: intent.name, + contextTypes: currentHandler.contextTypes, + description: currentHandler.applicationDescription, + displayName: currentHandler.displayName, + icon: currentHandler.applicationIcon, + resultType: currentHandler.resultType + }; + validIntentsWithInfo.push(intentWithInfo); + }); + return validIntentsWithInfo; + }, []); + return intentsWithInfo; + } + async removeRememberedHandler(intentName) { + var _a; + this.logger.trace(`Removing saved handler from prefs storage for intent ${intentName}`); + let prefs; + try { + prefs = await this.prefsController.get(); + } + catch (error) { + this.logger.warn(`prefs.get() threw the following error: ${typeof error === "string" ? error : JSON.stringify(error)}`); + return; + } + const intentPrefs = (_a = prefs.data) === null || _a === void 0 ? void 0 : _a.intents; + if (!intentPrefs) { + this.logger.trace("No app prefs found for current app"); + return; + } + delete intentPrefs[intentName]; + const updatedPrefs = { + ...prefs.data, + intents: intentPrefs + }; + try { + await this.prefsController.update(updatedPrefs); + } + catch (error) { + this.logger.warn(`prefs.update() threw the following error: ${typeof error === "string" ? error : JSON.stringify(error)}`); + return; + } + this.logger.trace(`Handler saved choice for intent ${intentName} removed successfully`); + } + async checkForRememberedHandler(intentRequest) { + var _a, _b; + let prefs; + try { + prefs = await this.prefsController.get(); + } + catch (error) { + this.logger.warn(`prefs.get() threw the following error: ${typeof error === "string" ? error : JSON.stringify(error)}`); + return; + } + const prefsForIntent = (_b = (_a = prefs.data) === null || _a === void 0 ? void 0 : _a.intents) === null || _b === void 0 ? void 0 : _b[intentRequest.intent]; + return prefsForIntent === null || prefsForIntent === void 0 ? void 0 : prefsForIntent.handler; + } + async checkHandleRaiseWithRememberedHandler(intentRequest, resolverInstance, timeout) { + if (intentRequest.target) { + return; + } + const rememberedHandler = await this.checkForRememberedHandler(intentRequest); + if (!rememberedHandler) { + return; + } + const request = { + ...intentRequest, + target: { + app: rememberedHandler.applicationName, + instance: rememberedHandler.instanceId + } + }; + try { + const response = await this.coreRaiseIntent({ request, resolverInstance, timeout }); + return response; + } + catch (error) { + this.logger.trace("Could not raise intent to remembered handler. Removing it from Prefs store"); + await this.removeRememberedHandler(intentRequest.intent); + } + } + async saveUserChoice({ intent, handler, filter, caller }) { + var _a, _b; + const prevPrefs = await this.prefsController.get(caller.applicationName); + const prevIntentsPrefs = ((_a = prevPrefs === null || prevPrefs === void 0 ? void 0 : prevPrefs.data) === null || _a === void 0 ? void 0 : _a.intents) || {}; + const prefsToUpdate = { + ...prevPrefs.data, + intents: { + ...prevIntentsPrefs, + [intent]: { handler, filter } + } + }; + await this.prefsController.update(prefsToUpdate, { app: caller.applicationName }); + (_b = this.logger) === null || _b === void 0 ? void 0 : _b.info(`Saved user's choice of handler for '${caller.applicationName}' app`); + } + constructIntentHandler({ apps, intentName, method, server, title }) { + const info = method.flags.intent; + const app = apps.find((appWithIntents) => appWithIntents.name === server.application); + let appIntent; + if (app === null || app === void 0 ? void 0 : app.intents) { + appIntent = app.intents.find((appDefIntent) => appDefIntent.name === intentName); + } + const handler = { + instanceId: server.instance, + applicationName: server.application, + applicationIcon: info.icon || (app === null || app === void 0 ? void 0 : app.icon), + applicationTitle: (app === null || app === void 0 ? void 0 : app.title) || "", + applicationDescription: info.description || (app === null || app === void 0 ? void 0 : app.caption), + displayName: info.displayName || (appIntent === null || appIntent === void 0 ? void 0 : appIntent.displayName), + contextTypes: info.contextTypes || (appIntent === null || appIntent === void 0 ? void 0 : appIntent.contexts), + instanceTitle: title, + type: "instance", + resultType: (appIntent === null || appIntent === void 0 ? void 0 : appIntent.resultType) || info.resultType + }; + return handler; + } + constructIntentHandlerFromApp(app, intent) { + return { + applicationName: app.name, + applicationTitle: app.title || "", + applicationDescription: app.caption, + displayName: intent.displayName, + contextTypes: intent.contexts, + applicationIcon: app.icon, + type: "app", + resultType: intent.resultType + }; + } + } + + class FactoryCallInfo { + constructor() { + this.initialized = false; + this.details = []; + this.reject = () => { }; + this.resolve = () => { }; + } + init(config) { + this.initialized = true; + this.addCall(config); + this.promise = new Promise((resolve, reject) => { + this.resolve = resolve; + this.reject = reject; + }); + } + addCall(config) { + this.details.push({ date: new Date(), config }); + } + done(g) { + this.resolve(g); + } + error(e) { + this.reject(e); + } + } + + class Prefs { + constructor(appName, interop) { + this.appName = appName; + this.interop = interop; + this.registry = CallbackRegistryFactory(); + this.interopMethodRegistered = false; + } + async get(app) { + const data = (await this.interop.invoke(Prefs.T42GetPrefsMethodName, { app: app !== null && app !== void 0 ? app : this.appName }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + })); + return data.returned; + } + async set(data, options) { + var _a; + this.verifyDataObject(data); + await this.interop.invoke(Prefs.T42SetPrefsMethodName, { app: (_a = options === null || options === void 0 ? void 0 : options.app) !== null && _a !== void 0 ? _a : this.appName, data, merge: false }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async setFor(app, data) { + this.verifyApp(app); + this.verifyDataObject(data); + return this.set(data, { app }); + } + async update(data, options) { + var _a; + this.verifyDataObject(data); + await this.interop.invoke(Prefs.T42SetPrefsMethodName, { app: (_a = options === null || options === void 0 ? void 0 : options.app) !== null && _a !== void 0 ? _a : this.appName, data, merge: true }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async updateFor(app, data) { + this.verifyApp(app); + this.verifyDataObject(data); + return this.update(data, { app }); + } + async clear(app) { + await this.interop.invoke(Prefs.T42SetPrefsMethodName, { app: app !== null && app !== void 0 ? app : this.appName, clear: true }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async clearFor(app) { + this.verifyApp(app); + await this.interop.invoke(Prefs.T42SetPrefsMethodName, { app, clear: true }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async getAll() { + const data = (await this.interop.invoke(Prefs.T42GetPrefsMethodName, undefined, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + })); + return data.returned; + } + async clearAll() { + await this.interop.invoke(Prefs.T42SetPrefsMethodName, { clear: true }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + subscribe(callback) { + this.verifyCallback(callback); + return this.subscribeFor(this.appName, callback); + } + subscribeFor(app, callback) { + this.verifyApp(app); + this.verifyCallback(callback); + const unsubscribeFn = this.registry.add(app, callback); + this.registerInteropIfNeeded() + .then(() => { + this.interop.invoke(Prefs.T42GetPrefsMethodName, { app, subscribe: true }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + }); + return () => { + unsubscribeFn(); + }; + } + async registerInteropIfNeeded() { + if (this.interopMethodRegistered) { + return; + } + this.interopMethodRegistered = true; + await this.interop.register(Prefs.T42UpdatePrefsMethodName, (args) => { + this.registry.execute(args.app, args); + }); + } + verifyApp(app) { + if (!app) { + throw new Error(`app should be defined`); + } + if (!isString(app)) { + throw new Error(`app should be a string`); + } + } + verifyDataObject(data) { + if (!data) { + throw new Error(`data should be defined`); + } + if (!isObject(data)) { + throw new Error(`data should be an object`); + } + } + verifyCallback(callback) { + if (!isFunction(callback)) { + throw new Error(`callback should be defined`); + } + } + } + Prefs.T42UpdatePrefsMethodName = "T42.Prefs.Update"; + Prefs.T42GetPrefsMethodName = "T42.Prefs.Get"; + Prefs.T42SetPrefsMethodName = "T42.Prefs.Set"; + + class Cookies { + constructor(methodName, interop) { + this.methodName = methodName; + this.interop = interop; + } + async get(filter) { + const result = await this.invoke("get-cookies", { filter }); + return result.returned.cookies; + } + async set(cookie) { + this.verifyCookieObject(cookie); + await this.invoke("set-cookie", cookie); + } + async remove(url, name) { + if (!isString(url)) { + throw new Error(`url should be a string`); + } + if (!isString(name)) { + throw new Error(`name should be a string`); + } + await this.invoke("remove-cookie", { url, name }); + } + invoke(command, data) { + return this.interop.invoke(this.methodName, { command, args: data }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_RESPONSE_TIMEOUT_MS, + }); + } + verifyCookieObject(cookie) { + if (!cookie) { + throw new Error(`cookie should be defined`); + } + if (!isObject(cookie)) { + throw new Error(`cookie should be an object`); + } + if (Utils.isNullOrUndefined(cookie.url) || !isString(cookie.url)) { + throw new Error(`cookie.url should be a string`); + } + if (Utils.isNullOrUndefined(cookie.name) || !isString(cookie.name)) { + throw new Error(`cookie.name should be a string`); + } + if (!Utils.isNullOrUndefined(cookie.value) && !isString(cookie.value)) { + throw new Error(`cookie.value should be a string`); + } + if (!Utils.isNullOrUndefined(cookie.domain) && !isString(cookie.domain)) { + throw new Error(`cookie.domain should be a string`); + } + if (!Utils.isNullOrUndefined(cookie.path) && !isString(cookie.path)) { + throw new Error(`cookie.path should be a string`); + } + if (!Utils.isNullOrUndefined(cookie.secure) && typeof cookie.secure !== "boolean") { + throw new Error(`cookie.secure should be a boolean`); + } + if (!Utils.isNullOrUndefined(cookie.httpOnly) && typeof cookie.httpOnly !== "boolean") { + throw new Error(`cookie.httpOnly should be a boolean`); + } + if (!Utils.isNullOrUndefined(cookie.expirationDate) && typeof cookie.expirationDate !== "number") { + throw new Error(`cookie.expirationDate should be a number`); + } + } + } + + function factory$1(agm, methodName) { + const cookies = new Cookies(methodName, agm); + return { + get: cookies.get.bind(cookies), + remove: cookies.remove.bind(cookies), + set: cookies.set.bind(cookies), + ready: () => Promise.resolve() + }; + } + + class EventsDispatcher { + constructor(config) { + this.config = config; + this.glue42EventName = "Glue42"; + this.events = { + notifyStarted: { name: "notifyStarted", handle: this.handleNotifyStarted.bind(this) }, + requestGlue: { name: "requestGlue", handle: this.handleRequestGlue.bind(this) } + }; + } + start(glue) { + if (Utils.isNode()) { + return; + } + this.glue = glue; + this.wireCustomEventListener(); + this.announceStarted(); + } + wireCustomEventListener() { + window.addEventListener(this.glue42EventName, (event) => { + const data = event.detail; + if (!data || !data.glue42) { + return; + } + const glue42Event = data.glue42.event; + const foundHandler = this.events[glue42Event]; + if (!foundHandler) { + return; + } + foundHandler.handle(data.glue42.message); + }); + } + announceStarted() { + this.send("start"); + } + handleRequestGlue() { + if (!this.config.exposeAPI) { + this.send("requestGlueResponse", { error: "Will not give access to the underlying Glue API, because it was explicitly denied upon initialization." }); + return; + } + this.send("requestGlueResponse", { glue: this.glue }); + } + handleNotifyStarted() { + this.announceStarted(); + } + send(eventName, message) { + const payload = { glue42: { event: eventName, message } }; + const event = new CustomEvent(this.glue42EventName, { detail: payload }); + window.dispatchEvent(event); + } + } + + class PromiseWrapper { + static delay(time) { + return new Promise((resolve) => setTimeout(resolve, time)); + } + static async delayForever() { + const biggestPossibleDelay = 2147483647; + while (true) { + await this.delay(biggestPossibleDelay); + } + } + get ended() { + return this.rejected || this.resolved; + } + constructor() { + this.promise = new Promise((resolve, reject) => { + this.resolve = (t) => { + this.resolved = true; + resolve(t); + }; + this.reject = (err) => { + this.rejected = true; + reject(err); + }; + }); + } + } + + class Interception { + constructor() { + this.InterceptorMethodName = "T42.GD.Interception.Execute"; + this.InterceptorHandlerMethodName = "T42.GD.Interception.Handler"; + this.interceptions = []; + } + init(interop) { + this.interop = interop; + } + async register(request) { + if (!request || typeof request !== "object" || Array.isArray(request)) { + throw new Error(`Please provide a valid object.`); + } + const handler = request.handler; + if (typeof handler !== "function") { + throw new Error("Please provide a valid handler function."); + } + const interceptions = request.interceptions; + this.validateInterceptions(interceptions); + this.interceptions.push(request); + try { + await this.interop.invoke(this.InterceptorMethodName, { + command: "register", + interceptions + }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + await this.registerMethodIfNotRegistered(); + } + catch (error) { + this.interceptions = this.interceptions.filter((i) => i !== request); + const message = error.message || "Unknown error"; + const newError = new Error(`Failed to register interception: ${message}`); + throw newError; + } + } + async unregister(request) { + if (!request || typeof request !== "object" || Array.isArray(request)) { + throw new Error(`Please provide a valid object.`); + } + const interceptions = request.interceptions; + this.validateInterceptions(interceptions); + try { + await this.interop.invoke(this.InterceptorMethodName, { + command: "unregister", + interceptions + }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + this.interceptions = this.interceptions.filter((config) => { + return !interceptions.some((interception) => { + return config.interceptions.some((i) => { + return i.domain === interception.domain && i.operation === interception.operation; + }); + }); + }); + } + catch (error) { + const message = error.message || "Unknown error"; + const newError = new Error(`Failed to unregister interception: ${message}`); + throw newError; + } + } + async handleInterception(domain, operation, operationArgs, phase) { + if (this.interop.methods(this.InterceptorMethodName).length === 0) { + return {}; + } + const result = await this.interop.invoke(this.InterceptorMethodName, { + command: "raiseInterception", + interceptions: [{ + operationArgs, + domain, + operation, + phase + }] + }, 'best', { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return result.returned; + } + static createProxyObject(apiToIntercept, domain, interception) { + const methods = Interception.OperationsPerDomain[domain] || []; + const handler = { + get(target, propertyKey, receiver) { + const property = Reflect.get(target, propertyKey, receiver); + try { + if (typeof property !== "function") { + return property; + } + const shouldIntercept = methods.includes(propertyKey); + const isAwaitable = Utils.isPromise(property) || Utils.isAsyncFunction(property); + if (!shouldIntercept || !isAwaitable) { + return property; + } + return Interception.interceptMethod(property, propertyKey, target, domain, interception); + } + catch (error) { + return property; + } + } + }; + const proxyAPI = new Proxy(apiToIntercept, handler); + return proxyAPI; + } + static interceptMethod(originalMethod, propertyKey, target, domain, interception) { + return async function (...args) { + const beforeInterceptionResult = await interception.handleInterception(domain, propertyKey, args, "before"); + if (!Utils.isNullOrUndefined(beforeInterceptionResult.operationResult)) { + return beforeInterceptionResult.operationResult; + } + if (!Utils.isNullOrUndefined(beforeInterceptionResult.operationArgs)) { + args = beforeInterceptionResult.operationArgs; + } + const methodResult = await originalMethod.apply(target, args); + const afterInterceptionResult = await interception.handleInterception(domain, propertyKey, [methodResult], "after"); + if (!Utils.isNullOrUndefined(afterInterceptionResult.operationResult)) { + return afterInterceptionResult.operationResult; + } + return methodResult; + }; + } + toAPI() { + return { + register: this.register.bind(this), + unregister: this.unregister.bind(this), + }; + } + async registerMethodIfNotRegistered() { + var _a; + if ((_a = this.whenRegisteredPromise) === null || _a === void 0 ? void 0 : _a.ended) { + return; + } + this.whenRegisteredPromise = new PromiseWrapper(); + this.registerMethod(); + } + async registerMethod() { + await this.interop.register(this.InterceptorHandlerMethodName, async (data) => { + const command = data.command; + if (command === "raiseInterception") { + const raisedInterception = data.interception; + const interceptor = this.interceptions.find((config) => { + return config.interceptions.some((interception) => { + return interception.domain === raisedInterception.domain && interception.operation === raisedInterception.operation; + }); + }); + const result = await interceptor.handler(raisedInterception); + return result; + } + }); + this.whenRegisteredPromise.resolve(); + } + validateInterceptions(interceptions) { + if (!Array.isArray(interceptions)) { + throw new Error("Please provide a valid array of interceptions."); + } + if (interceptions.length === 0) { + throw new Error("Please provide at least one interception."); + } + for (const interception of interceptions) { + if (typeof interception === "undefined" || interception === null || typeof interception !== "object" || Array.isArray(interception)) { + throw new Error("Please provide a valid interception object."); + } + if (typeof interception.domain !== "string" || !interception.domain) { + throw new Error("Please provide a valid domain string."); + } + if (typeof interception.operation !== "string" || !interception.operation) { + throw new Error("Please provide a valid operation string."); + } + this.validateTypeString(interception); + } + } + validateTypeString(interception) { + if (!isUndefinedOrNull(interception.phase)) { + const isValidType = ["all", "before", "after"].includes(interception.phase); + if (typeof interception.phase !== "string" || !isValidType) { + throw new Error("Please provide a valid phase string."); + } + } + } + } + Interception.OperationsPerDomain = { + "intents": ["raise"] + }; + + const callInfo = new FactoryCallInfo(); + const factory = async (options) => { + let firstRun = false; + if (!callInfo.initialized) { + firstRun = true; + callInfo.init(options); + } + const glue42gd = typeof window !== "undefined" && window.glue42gd; + if (glue42gd) { + if (!firstRun) { + callInfo.addCall(options); + return callInfo.promise; + } + } + const g = await factoryCore(options, glue42gd); + callInfo.resolve(g); + return g; + }; + const factoryCore = async (options, glue42gd) => { + const T42GDExecuteMethod = "T42.GD.Execute"; + const gdMajorVersion = Utils.getGDMajorVersion(); + options = options || {}; + const glueConfig = prepareConfig(options); + options.gateway = options.gateway || {}; + let _appManager; + let _activity; + let _windows; + let _displays; + let _channels; + let _prefs; + const _interceptors = new Interception(); + const _browserEventsDispatcher = new EventsDispatcher(glueConfig); + function createWindows(core) { + if (glueConfig.windows) { + const windowsLogger = getLibLogger("windows", core.logger, glueConfig.windows); + _windows = WindowsFactory(core.agm, windowsLogger, () => { + return _appManager; + }, () => { + return _displays; + }, () => { + return _channels; + }, gdMajorVersion); + debugLog(_windows); + return _windows; + } + } + function createActivities(core) { + var _a; + if (glueConfig.activities) { + if (ActivityModule.checkIsUsingGW3Implementation && ActivityModule.checkIsUsingGW3Implementation(core.connection)) { + const activityLogger = getLibLogger("activity", core.logger, glueConfig.activities); + _activity = new ActivityModule({ + connection: core.connection, + contexts: core.contexts, + agm: core.agm, + logger: activityLogger, + logLevel: "info", + disableAutoAnnounce: false, + disposeRequestHandling: "exit", + announcementInfo: null, + windows: _windows, + appManagerGetter: () => { + return _appManager; + }, + mode: glueConfig.activities.mode, + typesToTrack: glueConfig.activities.typesToTrack, + activityId: (_a = glue42gd === null || glue42gd === void 0 ? void 0 : glue42gd.activityInfo) === null || _a === void 0 ? void 0 : _a.activityId, + gdMajorVersion + }).api; + debugLog(_activity); + return _activity; + } + } + } + function createAppManager(core) { + if (!glueConfig.appManager) { + return; + } + const logger = getLibLogger("appManager", core.logger, glueConfig.appManager); + _appManager = AppManagerFactory({ + agm: core.agm, + windows: _windows, + logger, + activities: _activity, + mode: glueConfig.appManager.mode, + gdMajorVersion + }); + debugLog(_appManager); + return _appManager; + } + function createLayouts(core) { + var _a; + if (!glueConfig.layouts) { + return; + } + const logger = getLibLogger("layouts", core.logger, glueConfig.layouts); + const layoutsConfig = glueConfig.layouts; + const lay = LayoutsFactory({ + agm: core.agm, + appManager: _appManager, + activityGetter: () => _activity, + logger, + mode: layoutsConfig.mode, + autoSaveWindowContext: (_a = layoutsConfig.autoSaveWindowContext) !== null && _a !== void 0 ? _a : false, + gdMajorVersion + }); + debugLog(lay); + return lay; + } + function createChannels(core) { + if (!glueConfig.channels) { + return; + } + const logger = getLibLogger("channels", core.logger, glueConfig.channels); + if (!core.contexts) { + logger.error("Channels library requires Contexts library to be initialized."); + return; + } + _channels = factory$4({ operationMode: glueConfig.channels.operationMode }, core.contexts, core.agm, () => _windows, () => _appManager, logger); + debugLog(_channels); + return _channels; + } + function createHotkeys(core) { + const hotkeysAPI = factory$3(core.agm); + debugLog(hotkeysAPI); + return hotkeysAPI; + } + function createIntents(core) { + const domain = "intents"; + const intents = new Intents(core.agm, _windows, core.logger.subLogger(domain), options, _prefs, _appManager); + const intentsAPI = intents.toAPI(); + const proxyIntentsAPI = Interception.createProxyObject(intentsAPI, domain, _interceptors); + debugLog(proxyIntentsAPI); + return proxyIntentsAPI; + } + function createNotifications(core) { + const notificationsAPI = new Notifications(core.interop, core.logger).toAPI(); + debugLog(notificationsAPI); + return notificationsAPI; + } + function createDisplaysApi(core) { + if (glueConfig.displays) { + const displaysLogger = getLibLogger("displays", core.logger, glueConfig.displays); + _displays = new DisplayManager(core.agm, displaysLogger); + debugLog(_displays); + return _displays; + } + } + function createThemes(core) { + if (!core.contexts) { + return; + } + const themesAPI = factory$2(core.contexts, core.interop); + debugLog(themesAPI); + return themesAPI; + } + function createPrefs(core) { + var _a, _b; + const appName = (_b = (_a = options.application) !== null && _a !== void 0 ? _a : glue42gd === null || glue42gd === void 0 ? void 0 : glue42gd.applicationName) !== null && _b !== void 0 ? _b : core.interop.instance.application; + _prefs = new Prefs(appName, core.interop); + debugLog(_prefs); + return _prefs; + } + function createCookies(core) { + const api = factory$1(core.interop, T42GDExecuteMethod); + debugLog(api); + return api; + } + function createInterception(core) { + _interceptors.init(core.interop); + debugLog(_interceptors); + return _interceptors.toAPI(); + } + function getLibLogger(loggerName, logger, config) { + const newLogger = logger.subLogger(loggerName); + if (config && config.logger) { + const loggerConfig = config.logger; + if (loggerConfig.console) { + newLogger.consoleLevel(loggerConfig.console); + } + if (loggerConfig.publish) { + newLogger.publishLevel(loggerConfig.publish); + } + } + return newLogger; + } + const ext = { + libs: [ + { name: "windows", create: createWindows }, + { name: "activities", create: createActivities }, + { name: "appManager", create: createAppManager }, + { name: "layouts", create: createLayouts }, + { name: "channels", create: createChannels }, + { name: "hotkeys", create: createHotkeys }, + { name: "displays", create: createDisplaysApi }, + { name: "prefs", create: createPrefs }, + { name: "intents", create: createIntents }, + { name: "notifications", create: createNotifications }, + { name: "themes", create: createThemes }, + { name: "cookies", create: createCookies }, + { name: "interception", create: createInterception } + ], + version, + enrichGlue: (glue) => { + glue.config.activities = glueConfig.activities; + glue.config.windows = glueConfig.windows; + glue.config.appManager = glueConfig.appManager; + glue.config.layouts = glueConfig.layouts; + glue.config.channels = glueConfig.channels; + glue.config.displays = glueConfig.displays; + }, + }; + const currentLog = []; + if (typeof window !== "undefined") { + if (!window.glueFactoryLog) { + window.glueFactoryLog = []; + } + window.glueFactoryLog.push(currentLog); + } + function debugLog(entry) { + currentLog.push(entry); + } + const glueApi = (await IOConnectCoreFactory(options, ext)); + if (Array.isArray(options === null || options === void 0 ? void 0 : options.libraries) && options.libraries.length) { + await Promise.all(options.libraries.map((lib) => lib(glueApi, options))); + } + _browserEventsDispatcher.start(glueApi); + return glueApi; + }; + factory.coreVersion = IOConnectCoreFactory.version; + factory.version = version; + factory.calls = callInfo; + + var _a, _b; + let whatToExpose = factory; + let shouldSetToWindow = true; + if (typeof window !== "undefined") { + const windowAsAny = window; + const iodesktop = (_a = windowAsAny.iodesktop) !== null && _a !== void 0 ? _a : windowAsAny.glue42gd; + if (iodesktop && iodesktop.autoInjected) { + whatToExpose = (_b = windowAsAny.IODesktop) !== null && _b !== void 0 ? _b : windowAsAny.Glue; + shouldSetToWindow = false; + } + if (shouldSetToWindow) { + windowAsAny.Glue = whatToExpose; + windowAsAny.IODesktop = whatToExpose; + } + delete windowAsAny.IOBrowser; + delete windowAsAny.GlueCore; + } + whatToExpose.default = whatToExpose; + var whatToExpose$1 = whatToExpose; + + return whatToExpose$1; + +})); +//# sourceMappingURL=desktop.umd.js.map diff --git a/typescript/start/portfolio-downloader/src/lib/io.applications.css b/typescript/start/portfolio-downloader/src/lib/io.applications.css new file mode 100644 index 0000000..98e5910 --- /dev/null +++ b/typescript/start/portfolio-downloader/src/lib/io.applications.css @@ -0,0 +1,12 @@ +:root{--bs-blue: #007be5;--bs-indigo: #6610f2;--bs-purple: #6f42c1;--bs-pink: #fd397a;--bs-red: #ff511f;--bs-orange: #fd7e14;--bs-yellow: #f9a825;--bs-green: #43a047;--bs-teal: #616161;--bs-cyan: #469eb9;--bs-white: #fff;--bs-gray: #6c757d;--bs-gray-dark: #343a40;--bs-gray-100: #f8f9fa;--bs-gray-200: #e9ecef;--bs-gray-300: #dee2e6;--bs-gray-400: #ced4da;--bs-gray-500: #adb5bd;--bs-gray-600: #6c757d;--bs-gray-700: #495057;--bs-gray-800: #343a40;--bs-gray-900: #212529;--bs-primary: #007be5;--bs-secondary: #616161;--bs-success: #43a047;--bs-info: #469eb9;--bs-warning: #f9a825;--bs-danger: #ff511f;--bs-light: #616161;--bs-dark: #616161;--bs-primary-rgb: 0,123,229;--bs-secondary-rgb: 97,97,97;--bs-success-rgb: 67,160,71;--bs-info-rgb: 70,158,185;--bs-warning-rgb: 249,168,37;--bs-danger-rgb: 255,81,31;--bs-light-rgb: 97,97,97;--bs-dark-rgb: 97,97,97;--bs-white-rgb: 255,255,255;--bs-black-rgb: 0,0,0;--bs-body-color-rgb: 33,37,41;--bs-body-bg-rgb: 255,255,255;--bs-font-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--bs-gradient: linear-gradient(180deg, rgba(255,255,255,0.15), rgba(255,255,255,0));--bs-body-font-family: Montserrat,Helvetica Neue,Arial,sans-serif;--bs-body-font-size: .75rem;--bs-body-font-weight: 400;--bs-body-line-height: 1.5;--bs-body-color: #212529;--bs-body-bg: #fff}:root{--t42-font-family: "Montserrat", "Helvetica Neue", Arial, sans-serif;--t42-font-size: 0.75rem;--bs-gutter-x: 0.938rem;--primary: #007be5;--secondary: #616161;--success: #43a047;--info: #616161;--warning: #f9a825;--danger: #ff511f;--light: #616161;--dark: #616161;--white: #ffffff}.dark{--t42-bg-light-base: 0, 0%;--t42-bg-light-l: 18%;--t42-bg-light: 45, 45, 45;--t42-bg-mid: 37, 37, 37;--t42-bg-dark: 30, 30, 30;--t42-content-color-base: 0, 0%;--t42-content-color: #bababa;--t42-content-color-l: 73%;--t42-content-color-muted: hsl(var(--t42-content-color-base), 63%);--t42-content-color-disabled: hsl(var(--t42-content-color-base), 43%);--t42-color-opacity-025: hsla(var(--t42-content-color-base), 100%, 0.025);--t42-color-opacity-05: hsla(var(--t42-content-color-base), 100%, 0.05);--t42-color-opacity-10: hsla(var(--t42-content-color-base), 100%, 0.1);--t42-color-opacity-20: hsla(var(--t42-content-color-base), 100%, 0.2);--t42-color-opacity-30: hsla(var(--t42-content-color-base), 100%, 0.3);--t42-link-color: hsl(var(--t42-content-color-base), 100%);--t42-shadow: 0 0 12px 0 hsla(var(--t42-content-color-base), 0%, 0.15);--t42-border: 0.0625rem solid var(--t42-color-opacity-10);--t42-logo-icon: url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 xmlns:xlink=%27http://www.w3.org/1999/xlink%27 x=%270px%27 y=%270px%27 viewBox=%270 0 100.2 121%27 style=%27enable-background:new 0 0 100.2 121;%27%3E%3Cpath fill=%27%233A77BC%27 d=%27M59.4,10.6l-8.3,8.3c-0.5,0.5-1.4,0.5-1.9,0l-8.3-8.3c-0.5-0.5-0.5-1.4,0-1.9l8.3-8.3c0.5-0.5,1.4-0.5,1.9,0 l8.3,8.3C59.9,9.2,59.9,10.1,59.4,10.6z M59.3,110.4l-8.3-8.3c-0.5-0.5-1.4-0.5-1.9,0l-8.3,8.3c-0.5,0.5-0.5,1.4,0,1.9l8.3,8.3 c0.5,0.5,1.4,0.5,1.9,0l8.3-8.3C59.9,111.8,59.9,110.9,59.3,110.4z%27/%3E%3Cpath fill=%27%23FFFFFF%27 d=%27M100.1,60.1c0.3,7.3-2.9,14.3-9.3,20.6l-24.7,24.7c-0.6,0.6-1.5,0.6-2.1,0l-8.1-8.1c-0.6-0.6-0.6-1.5,0-2.1 l24.7-24.7c0.1-0.1,0.2-0.2,0.3-0.3c3.2-3.3,4.7-6.7,4.4-10.2c0-0.4-0.1-0.8-0.2-1.3c-0.6-3.3-2.8-7-6.8-11l-9.9-9.9 c-0.3-0.3-0.7-0.5-1.1-0.5c-0.4,0-0.8,0.2-1.3,0.6L34.5,69.6c-0.6,0.6-1.5,0.6-2.1,0L27.7,65c-3.3-3.3-3.8-5.1-1.3-7.6 c11.1-11.2,22-22.1,33.2-33.2c2.7-2.7,5.1-4.2,7.5-4.3c2.5-0.1,4.7,1.2,6.9,3.5l14.3,14.3C95.9,45.3,99.8,52.8,100.1,60.1 L100.1,60.1z M0,60.9c0.3,7.3,3.7,14.3,11.2,21.9l14.8,14.8c2.3,2.3,4.5,3.6,6.9,3.5c2.4-0.1,4.8-1.6,7.5-4.3 c11.1-11.1,22.1-22,33.2-33.2c2.5-2.5,2-4.3-1.3-7.6l-4.7-4.7c-0.6-0.6-1.5-0.6-2.1,0L34,83c-0.5,0.5-0.9,0.6-1.3,0.6 c-0.4,0-0.7-0.1-1.1-0.5L21.3,72.7c-4-4-5.7-7.2-6.3-10.5c-0.1-0.4-0.1-0.8-0.2-1.3c-0.3-3.5,1.2-6.9,4.4-10.2 c0.1-0.1,0.2-0.2,0.3-0.3l24.7-24.7c0.6-0.6,0.6-1.5,0-2.1l-8.1-8.1c-0.6-0.6-1.5-0.6-2.1,0L9.3,40.3C2.9,46.6-0.3,53.5,0,60.9 L0,60.9z%27/%3E%3C/svg%3E%0A");--t42-icon-color: var(--t42-link-color);--t42-list-group-hover-bg-special: hsla(var(--t42-content-color-base), 100%, 0.065);--backdrop-filter: blur(5px) saturate(200%);--accordion-filter: invert(1) brightness(1);--filter-close: invert(1);--t42-body: rgb(var(--t42-bg-dark));--pink: rgb(0 170 200);--t42-link-hover-color: hsl(var(--t42-bg-light-base), 100%);--t42-link-hover-bg: var(--t42-color-opacity-05);--t42-link-active-bg: var(--t42-color-opacity-10);--t42-input-bg: rgb(var(--t42-bg-dark));--t42-input-disabled-bg: Hsla(var(--t42-content-color-base), 100%, 0.075);--t42-tooltip-bg: rgba(var(--t42-bg-dark), 0.85);--t42-modal-bg: rgba(var(--t42-bg-light), 0.75);--t42-table-active-bg: rgba(255, 255, 255, 0.1);--t42-select-indicator: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9IiNFRUVFRUUiIHZpZXdCb3g9IjAgMCAxNiAxNiI+PHBhdGggZD0iTTIuNSA1LjVjLjQtLjQgMS0uNSAxLjYgMGwzLjkgMy43bDMuOS0zLjdjLjUtLjUgMS4xLS40IDEuNiAwYy40LjQuNCAxLjIgMCAxLjZjLS40LjQtNC43IDQuNS00LjcgNC41Yy0uMi4yLS41LjMtLjguM3MtLjYtLjEtLjgtLjNjMCAwLTQuMy00LjEtNC43LTQuNXMtLjQtMS4yIDAtMS42eiI+PC9wYXRoPjwvc3ZnPg==)}.light{--t42-bg-light-base: 0, 0%;--t42-bg-light-l: 100%;--t42-bg-light: 255, 255, 255;--t42-bg-mid: 250, 250, 250;--t42-bg-dark: 245, 245, 245;--t42-content-color-base: 0, 0%;--t42-content-color: #757575;--t42-content-color-l: 46%;--t42-content-color-muted: hsl(var(--t42-content-color-base), 66%);--t42-color-opacity-025: hsla(var(--t42-content-color-base), 0%, 0.025);--t42-color-opacity-05: hsla(var(--t42-content-color-base), 0%, 0.05);--t42-color-opacity-10: hsla(var(--t42-content-color-base), 0%, 0.075);--t42-color-opacity-30: hsla(var(--t42-content-color-base), 0%, 0.1);--t42-color-opacity-20: hsla(var(--t42-content-color-base), 0%, 0.2);--t42-link-color: hsl(var(--t42-content-color-base), 5%);--t42-shadow: 0 0 12px 0 hsla(var(--t42-content-color-base), 0%, 0.05);--t42-border: 0.0625rem solid var(--t42-color-opacity-10);--t42-logo-icon: url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 xmlns:xlink=%27http://www.w3.org/1999/xlink%27 x=%270px%27 y=%270px%27 viewBox=%270 0 100.2 121%27 style=%27enable-background:new 0 0 100.2 121;%27%3E%3Cpath fill=%27%233A77BC%27 d=%27M59.4,10.6l-8.3,8.3c-0.5,0.5-1.4,0.5-1.9,0l-8.3-8.3c-0.5-0.5-0.5-1.4,0-1.9l8.3-8.3c0.5-0.5,1.4-0.5,1.9,0 l8.3,8.3C59.9,9.2,59.9,10.1,59.4,10.6z M59.3,110.4l-8.3-8.3c-0.5-0.5-1.4-0.5-1.9,0l-8.3,8.3c-0.5,0.5-0.5,1.4,0,1.9l8.3,8.3 c0.5,0.5,1.4,0.5,1.9,0l8.3-8.3C59.9,111.8,59.9,110.9,59.3,110.4z%27/%3E%3Cpath fill=%27%23083044%27 d=%27M100.1,60.1c0.3,7.3-2.9,14.3-9.3,20.6l-24.7,24.7c-0.6,0.6-1.5,0.6-2.1,0l-8.1-8.1c-0.6-0.6-0.6-1.5,0-2.1 l24.7-24.7c0.1-0.1,0.2-0.2,0.3-0.3c3.2-3.3,4.7-6.7,4.4-10.2c0-0.4-0.1-0.8-0.2-1.3c-0.6-3.3-2.8-7-6.8-11l-9.9-9.9 c-0.3-0.3-0.7-0.5-1.1-0.5c-0.4,0-0.8,0.2-1.3,0.6L34.5,69.6c-0.6,0.6-1.5,0.6-2.1,0L27.7,65c-3.3-3.3-3.8-5.1-1.3-7.6 c11.1-11.2,22-22.1,33.2-33.2c2.7-2.7,5.1-4.2,7.5-4.3c2.5-0.1,4.7,1.2,6.9,3.5l14.3,14.3C95.9,45.3,99.8,52.8,100.1,60.1 L100.1,60.1z M0,60.9c0.3,7.3,3.7,14.3,11.2,21.9l14.8,14.8c2.3,2.3,4.5,3.6,6.9,3.5c2.4-0.1,4.8-1.6,7.5-4.3 c11.1-11.1,22.1-22,33.2-33.2c2.5-2.5,2-4.3-1.3-7.6l-4.7-4.7c-0.6-0.6-1.5-0.6-2.1,0L34,83c-0.5,0.5-0.9,0.6-1.3,0.6 c-0.4,0-0.7-0.1-1.1-0.5L21.3,72.7c-4-4-5.7-7.2-6.3-10.5c-0.1-0.4-0.1-0.8-0.2-1.3c-0.3-3.5,1.2-6.9,4.4-10.2 c0.1-0.1,0.2-0.2,0.3-0.3l24.7-24.7c0.6-0.6,0.6-1.5,0-2.1l-8.1-8.1c-0.6-0.6-1.5-0.6-2.1,0L9.3,40.3C2.9,46.6-0.3,53.5,0,60.9 L0,60.9z%27/%3E%3C/svg%3E%0A");--t42-icon-color: Hsl(var(--t42-content-color-base), 38%);--t42-list-group-hover-bg-special: hsla(var(--t42-content-color-base), 95%, 0.065);--backdrop-filter: blur(5px) saturate(200%);--accordion-filter: brightness(0%);--filter-close: invert(0);--t42-body: rgb(var(--t42-bg-mid));--t42-link-hover-color: hsl(var(--t42-bg-light-base), 0%);--t42-link-hover-bg: hsl(var(--t42-content-color-base), 95%);--t42-link-active-bg: hsl(var(--t42-content-color-base), 90%);--t42-input-bg: rgb(var(--t42-bg-light));--t42-input-disabled-bg: var(--t42-color-opacity-10);--t42-tooltip-bg: rgba(var(--t42-bg-light), 0.95);--t42-modal-bg: rgba(var(--t42-bg-light), 0.95);--t42-table-active-bg: rgba(0, 0, 0, 0.025);--t42-select-indicator: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9IiM2MTYxNjEiIHZpZXdCb3g9IjAgMCAxNiAxNiI+PHBhdGggZD0iTTIuNSA1LjVjLjQtLjQgMS0uNSAxLjYgMGwzLjkgMy43bDMuOS0zLjdjLjUtLjUgMS4xLS40IDEuNiAwYy40LjQuNCAxLjIgMCAxLjZjLS40LjQtNC43IDQuNS00LjcgNC41Yy0uMi4yLS41LjMtLjguM3MtLjYtLjEtLjgtLjNjMCAwLTQuMy00LjEtNC43LTQuNXMtLjQtMS4yIDAtMS42eiI+PC9wYXRoPjwvc3ZnPg==)}*,*::before,*::after{box-sizing:border-box}@media (prefers-reduced-motion: no-preference){:root{scroll-behavior:smooth}}body{margin:0;font-family:var(--bs-body-font-family);font-size:var(--bs-body-font-size);font-weight:var(--bs-body-font-weight);line-height:var(--bs-body-line-height);color:var(--bs-body-color);text-align:var(--bs-body-text-align);background-color:var(--bs-body-bg);-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:rgba(0,0,0,0)}hr{margin:1rem 0;color:inherit;background-color:currentColor;border:0;opacity:.25}hr:not([size]){height:1px}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem;font-weight:500;line-height:1.2;color:var(--t42-link-color)}h1{font-size:calc(1.26563rem + .1875vw)}@media (min-width: 1200px){h1{font-size:1.40625rem}}h2{font-size:1.125rem}h3{font-size:.98475rem}h4{font-size:.84375rem}h5{font-size:.75rem}h6{font-size:.7035rem}p{margin-top:0;margin-bottom:1rem}abbr[title],abbr[data-bs-original-title]{text-decoration:underline dotted;cursor:help;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}ol,ul{padding-left:2rem}ol,ul,dl{margin-top:0;margin-bottom:1rem}ol ol,ul ul,ol ul,ul ol{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:.875em}mark{padding:0.2rem 0.2rem 0;background-color:#007be5}sub,sup{position:relative;font-size:.75em;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:var(--t42-link-color);text-decoration:underline}a:hover{color:var(--t42-link-hover-color)}a:not([href]):not([class]),a:not([href]):not([class]):hover{color:inherit;text-decoration:none}pre,code,kbd,samp{font-family:var(--bs-font-monospace);font-size:1em;direction:ltr /* rtl:ignore */;unicode-bidi:bidi-override}pre{display:block;margin-top:0;margin-bottom:1rem;overflow:auto;font-size:inherit;color:var(--t42-content-color)}pre code{font-size:inherit;color:inherit;word-break:normal}code{font-size:inherit;color:#469eb9;word-wrap:break-word}a>code{color:inherit}kbd{padding:.2rem .4rem;font-size:inherit;color:#fff;background-color:#212529;border-radius:.25rem}kbd kbd{padding:0;font-size:1em;font-weight:700}figure{margin:0 0 1rem}img,svg{vertical-align:middle}table{caption-side:bottom;border-collapse:collapse}caption{padding-top:.25rem;padding-bottom:.25rem;color:var(--t42-content-color-muted);text-align:left}th{text-align:inherit;text-align:-webkit-match-parent}thead,tbody,tfoot,tr,td,th{border-color:inherit;border-style:solid;border-width:0}label{display:inline-block}button{border-radius:0}button:focus:not(:focus-visible){outline:0}input,button,select,optgroup,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,select{text-transform:none}[role="button"]{cursor:pointer}select{word-wrap:normal}select:disabled{opacity:1}[list]::-webkit-calendar-picker-indicator{display:none}button,[type="button"],[type="reset"],[type="submit"]{-webkit-appearance:button}button:not(:disabled),[type="button"]:not(:disabled),[type="reset"]:not(:disabled),[type="submit"]:not(:disabled){cursor:pointer}::-moz-focus-inner{padding:0;border-style:none}textarea{resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{float:left;width:100%;padding:0;margin-bottom:.5rem;font-size:calc(1.275rem + .3vw);line-height:inherit}@media (min-width: 1200px){legend{font-size:1.5rem}}legend+*{clear:left}::-webkit-datetime-edit-fields-wrapper,::-webkit-datetime-edit-text,::-webkit-datetime-edit-minute,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-year-field{padding:0}::-webkit-inner-spin-button{height:auto}[type="search"]{outline-offset:-2px;-webkit-appearance:textfield}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-color-swatch-wrapper{padding:0}::file-selector-button{font:inherit}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}iframe{border:0}summary{display:list-item;cursor:pointer}progress{vertical-align:baseline}[hidden]{display:none !important}body{color:var(--t42-content-color);font-family:var(--t42-font-family);background-color:var(--t42-body)}a:focus,button:focus,div:focus,span:focus{outline:0}a{text-decoration:none}dt{font-weight:normal}::selection{color:var(--white);background-color:var(--primary)}::-webkit-scrollbar{width:4px;height:4px}::-webkit-scrollbar-track{border-radius:.25rem;background:transparent}::-webkit-scrollbar-thumb{border-radius:.25rem;background:var(--t42-color-opacity-10)}::-webkit-resizer{background:transparent}::-webkit-scrollbar-corner{background:transparent}::-webkit-scrollbar-thumb:window-inactive{background:transparent}::-webkit-scrollbar-thumb:hover,::-webkit-scrollbar-thumb:active{background:Hsla(var(--t42-content-color-base), 100%, 0.05)}.accordion-button{position:relative;display:flex;align-items:center;width:100%;padding:1rem 1.25rem;font-size:.75rem;color:var(--t42-link-color);text-align:left;background-color:Rgb(var(--t42-bg-mid));border:0;border-radius:0;overflow-anchor:none;transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out,border-radius 0.15s ease}@media (prefers-reduced-motion: reduce){.accordion-button{transition:none}}.accordion-button:not(.collapsed){color:var(--t42-link-color);background-color:Rgb(var(--t42-bg-mid));box-shadow:inset 0 -1px 0 var(--t42-color-opacity-10)}.accordion-button:not(.collapsed)::after{background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 16 16%27 fill=%27var%28--t42-link-color%29%27%3e%3cpath fill-rule=%27evenodd%27 d=%27M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z%27/%3e%3c/svg%3e");transform:rotate(-180deg)}.accordion-button::after{flex-shrink:0;width:1.25rem;height:1.25rem;margin-left:auto;content:"";background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 16 16%27 fill=%27var%28--t42-link-color%29%27%3e%3cpath fill-rule=%27evenodd%27 d=%27M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z%27/%3e%3c/svg%3e");background-repeat:no-repeat;background-size:1.25rem;transition:transform 0.2s ease-in-out}@media (prefers-reduced-motion: reduce){.accordion-button::after{transition:none}}.accordion-button:hover{z-index:2}.accordion-button:focus{z-index:3;border-color:#007be5;outline:0;box-shadow:0 0 0 0 rgba(0,123,229,0.25)}.accordion-header{margin-bottom:0}.accordion-item{background-color:Rgb(var(--t42-bg-mid));border:1px solid var(--t42-color-opacity-10)}.accordion-item:first-of-type{border-top-left-radius:0;border-top-right-radius:0}.accordion-item:first-of-type .accordion-button{border-top-left-radius:0;border-top-right-radius:0}.accordion-item:not(:first-of-type){border-top:0}.accordion-item:last-of-type{border-bottom-right-radius:0;border-bottom-left-radius:0}.accordion-item:last-of-type .accordion-button.collapsed{border-bottom-right-radius:0;border-bottom-left-radius:0}.accordion-item:last-of-type .accordion-collapse{border-bottom-right-radius:0;border-bottom-left-radius:0}.accordion-body{padding:1rem 1.25rem}.accordion-flush .accordion-collapse{border-width:0}.accordion-flush .accordion-item{border-right:0;border-left:0;border-radius:0}.accordion-flush .accordion-item:first-child{border-top:0}.accordion-flush .accordion-item:last-child{border-bottom:0}.accordion-flush .accordion-item .accordion-button{border-radius:0}.accordion-button::after,.accordion-button:not(.collapsed)::after{filter:var(--accordion-filter)}.accordion-button:disabled,.accordion-button.disabled{color:var(--t42-content-color-disabled)}.accordion-button:disabled::after,.accordion-button.disabled::after{opacity:0.25}.alert{position:relative;padding:.75rem .875rem;margin-bottom:.5rem;border:1px solid transparent;border-radius:0}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-right:2.625rem}.alert-dismissible .btn-close{position:absolute;top:0;right:0;z-index:2;padding:.9375rem .875rem}.alert-primary{color:#004a89;background-color:#cce5fa;border-color:#b3d7f7}.alert-primary .alert-link{color:#003b6e}.alert-secondary{color:#3a3a3a;background-color:#dfdfdf;border-color:#d0d0d0}.alert-secondary .alert-link{color:#2e2e2e}.alert-success{color:#28602b;background-color:#d9ecda;border-color:#c7e3c8}.alert-success .alert-link{color:#204d22}.alert-info{color:#2a5f6f;background-color:#daecf1;border-color:#c8e2ea}.alert-info .alert-link{color:#224c59}.alert-warning{color:#64430f;background-color:#feeed3;border-color:#fde5be}.alert-warning .alert-link{color:#50360c}.alert-danger{color:#993113;background-color:#ffdcd2;border-color:#ffcbbc}.alert-danger .alert-link{color:#7a270f}.alert-light{color:#3a3a3a;background-color:#dfdfdf;border-color:#d0d0d0}.alert-light .alert-link{color:#2e2e2e}.alert-dark{color:#3a3a3a;background-color:#dfdfdf;border-color:#d0d0d0}.alert-dark .alert-link{color:#2e2e2e}.alert{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border-color;position:relative;z-index:10000;display:flex;align-items:center;border:0.0625rem solid var(--t42-color-opacity-10);overflow:hidden;color:var(--t42-content-color);background-color:Rgba(var(--t42-bg-light), 0.75);background-repeat:no-repeat;background-size:100%;backdrop-filter:var(--backdrop-filter)}.alert h5{margin-bottom:0;color:var(--t42-content-color)}.alert p{margin-bottom:0}.alert-link{color:var(--t42-link-color);font-weight:normal}.alert-dismissible .close{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border-color;position:absolute;top:50%;right:0.75rem;width:1.5rem;height:1.5rem;padding:0;border:0;border-radius:50%;color:var(--t42-content-color);font-weight:700;font-size:1rem;line-height:1;background-color:var(--t42-color-opacity-05);transform:translateY(-50%);opacity:0.5}.alert-dismissible .close::before{position:relative;top:-1px}.alert-dismissible .close:hover{opacity:1}.alert::before{z-index:1;width:1.25rem;height:1.25rem;margin-right:0.875rem;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-position:center;mask-position:center;background-color:var(--t42-icon-color);content:""}.alert::after{position:absolute;top:0;left:0;z-index:-1;width:1px;height:1px;border-radius:50%;opacity:1;animation:color-pulse 3s infinite;content:""}.alert-primary:hover,.alert-secondary:hover,.alert-info:hover,.alert-light:hover,.alert-dark:hover{border-color:#616161}.alert-primary::after,.alert-secondary::after,.alert-info::after,.alert-light::after,.alert-dark::after{background:#616161;background:radial-gradient(circle, rgba(255,255,255,0.35) 0%, rgba(97,97,97,0.75) 60%, #616161 75%, #616161 100%)}.alert-primary::before,.alert-secondary::before,.alert-info::before,.alert-light::before,.alert-dark::before{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M260.6 484.4q0-4.1-4.6-4.1q-16.9 0-29.2-12.3t-11.8-29.2q0-4.6-4.6-4.6t-4.6 4.6q0 21 14.8 35.8t35.3 14.3q4.6 0 4.6-4.6zM493.6 402.4q0 14.8-10.8 25.6t-25.6 10.8h-128q0 30.2-21.5 51.7t-51.7 21.5t-51.7-21.5t-21.5-51.7h-128q-14.8 0-25.6-10.8t-10.8-25.6q14.3-12.3 26.1-25.1t24.1-34.3t21.5-45.6t13.8-58.9t5.6-74.2q0-43 33.8-80.4t87.6-45.6q-2.6-5.1-2.6-10.8q0-11.8 8.2-19.5t19.5-8.2t19.5 8.2t8.2 19.5q0 5.6-2.6 10.8q54.3 8.2 87.6 45.6t33.8 80.4q0 39.9 5.6 74.2t14.3 58.9t21 45.6t24.6 34.3t25.6 25.1z%27%3E%3C/path%3E%3C/svg%3E")}.alert-success:hover{border-color:#43a047}.alert-success::after{background:#43a047;background:radial-gradient(circle, rgba(255,255,255,0.35) 0%, rgba(67,160,71,0.75) 60%, #43a047 75%, #43a047 100%)}.alert-success::before{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M477.4 152.8q0 11.3-8.2 19.5l-245.8 245.8q-8.2 7.7-19.5 7.7t-19.5-7.7l-142.3-142.3q-7.7-8.2-7.7-19.5t7.7-19.5l38.9-38.9q8.2-8.2 19.5-8.2t19.5 8.2l84 84.5l187.4-187.9q8.2-8.2 19.5-8.2t19.5 8.2l38.9 38.9q8.2 7.7 8.2 19.5z%27%3E%3C/path%3E%3C/svg%3E")}.alert-warning:hover{border-color:#f9a825}.alert-warning::after{background:#f9a825;background:radial-gradient(circle, rgba(255,255,255,0.35) 0%, rgba(249,168,37,0.75) 60%, #f9a825 75%, #f9a825 100%)}.alert-warning::before{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M292.4 410.9v-54.3q0-4.1-2.6-6.7t-6.1-2.6h-55.3q-3.6 0-6.1 2.6t-2.6 6.7v54.3q0 4.1 2.6 6.7t6.1 3.1h55.3q3.6 0 6.1-3.1t2.6-6.7zM291.8 304.4l5.1-131.6q0-3.1-2.6-5.1q-3.6-3.1-7.2-3.1h-62.5q-3.1 0-7.2 3.1q-2.6 2-2.6 6.1l4.6 130.6q0 2.6 3.1 4.6t6.7 1.5h52.7q4.1 0 7.2-1.5t2.6-4.6zM288.3 37.1l219.1 402.4q10.2 17.9-.5 35.8q-4.6 8.7-13.3 13.3t-17.9 5.1h-439.3q-9.2 0-17.9-5.1t-13.3-13.3q-10.8-17.9-.5-35.8l219.6-402.4q4.6-8.7 13.3-13.8t18.4-5.1t18.4 5.1t13.8 13.8z%27%3E%3C/path%3E%3C/svg%3E%0A")}.alert-danger:hover{border-color:#ff511f}.alert-danger::after{background:#ff511f;background:radial-gradient(circle, rgba(255,255,255,0.35) 0%, rgba(255,81,31,0.75) 60%, #ff511f 75%, #ff511f 100%)}.alert-danger::before{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 402 512%27%3E%3Cpath d=%27M370.728 359.68q0 11.264-7.68 19.456l-38.912 38.912q-8.192 7.68-19.456 7.68t-19.456-7.68l-83.968-84.48-83.968 84.48q-8.192 7.68-19.456 7.68t-19.456-7.68l-38.912-38.912q-8.192-8.192-8.192-19.456t8.192-19.456l83.968-83.968-83.968-83.968q-8.192-8.192-8.192-19.456t8.192-19.456l38.912-38.912q8.192-8.192 19.456-8.192t19.456 8.192l83.968 83.968 83.968-83.968q8.192-8.192 19.456-8.192t19.456 8.192l38.912 38.912q7.68 7.68 7.68 19.456t-7.68 19.456l-83.968 83.968 83.968 83.968q7.68 7.68 7.68 19.456z%27%3E%3C/path%3E%3C/svg%3E")}@keyframes color-pulse{0%{transform:scale(1);opacity:1}50%{transform:scale(250);opacity:0}100%{opacity:0}}.badge{display:inline-block;padding:.2rem .5rem;font-size:.75em;font-weight:300;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:1rem}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.badge{border:var(--t42-border);color:var(--t42-link-color);backdrop-filter:var(--backdrop-filter)}.badge.bg-primary{border:0.0625rem solid #007be5;background-color:rgba(0,123,229,0.15) !important}.badge.bg-secondary{border:0.0625rem solid #616161;background-color:rgba(97,97,97,0.15) !important}.badge.bg-success{border:0.0625rem solid #43a047;background-color:rgba(67,160,71,0.15) !important}.badge.bg-info{border:0.0625rem solid #469eb9;background-color:rgba(70,158,185,0.15) !important}.badge.bg-warning{border:0.0625rem solid #f9a825;background-color:rgba(249,168,37,0.15) !important}.badge.bg-danger{border:0.0625rem solid #ff511f;background-color:rgba(255,81,31,0.15) !important}.badge.bg-light{border:0.0625rem solid #616161;background-color:rgba(97,97,97,0.15) !important}.badge.bg-dark{border:0.0625rem solid #616161;background-color:rgba(97,97,97,0.15) !important}button .badge{border:0.0625rem solid var(--t42-color-opacity-30)}button:hover .badge{color:var(--white)}.btn-close{box-sizing:content-box;width:1em;height:1em;padding:0 0;color:var(--t42-content-color);background:transparent url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 16 16%27 fill=%27var%28--t42-content-color%29%27%3e%3cpath d=%27M.293.293a1 1 0 011.414 0L8 6.586 14.293.293a1 1 0 111.414 1.414L9.414 8l6.293 6.293a1 1 0 01-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 01-1.414-1.414L6.586 8 .293 1.707a1 1 0 010-1.414z%27/%3e%3c/svg%3e") center/1em auto no-repeat;border:0;border-radius:.25rem;opacity:.5}.btn-close:hover{color:var(--t42-content-color);text-decoration:none;opacity:.75}.btn-close:focus{outline:0;box-shadow:0 0 0 0 rgba(0,123,229,0.25);opacity:1}.btn-close:disabled,.btn-close.disabled{pointer-events:none;user-select:none;opacity:.25}.btn-close-white{filter:invert(1) grayscale(100%) brightness(200%)}.btn{display:inline-block;font-weight:400;line-height:1.875rem;color:#212529;text-align:center;text-decoration:none;vertical-align:middle;cursor:pointer;user-select:none;background-color:transparent;border:1px solid transparent;padding:0 .875rem;font-size:.75rem;border-radius:0;transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.btn{transition:none}}.btn:hover{color:#212529}.btn-check:focus+.btn,.btn:focus{outline:0;box-shadow:0 0 0 0 rgba(0,123,229,0.25)}.btn:disabled,.btn.disabled,fieldset:disabled .btn{pointer-events:none;opacity:.35}.btn-primary{color:#000;background-color:#007be5;border-color:#007be5}.btn-primary:hover{color:#000;background-color:#268fe9;border-color:#1a88e8}.btn-check:focus+.btn-primary,.btn-primary:focus{color:#000;background-color:#268fe9;border-color:#1a88e8;box-shadow:0 0 0 0 rgba(0,105,195,0.5)}.btn-check:checked+.btn-primary,.btn-check:active+.btn-primary,.btn-primary:active,.btn-primary.active,.show>.btn-primary.dropdown-toggle{color:#000;background-color:#3395ea;border-color:#1a88e8}.btn-check:checked+.btn-primary:focus,.btn-check:active+.btn-primary:focus,.btn-primary:active:focus,.btn-primary.active:focus,.show>.btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(0,105,195,0.5)}.btn-primary:disabled,.btn-primary.disabled{color:#000;background-color:#007be5;border-color:#007be5}.btn-secondary{color:#fff;background-color:#616161;border-color:#616161}.btn-secondary:hover{color:#fff;background-color:#525252;border-color:#4e4e4e}.btn-check:focus+.btn-secondary,.btn-secondary:focus{color:#fff;background-color:#525252;border-color:#4e4e4e;box-shadow:0 0 0 0 rgba(121,121,121,0.5)}.btn-check:checked+.btn-secondary,.btn-check:active+.btn-secondary,.btn-secondary:active,.btn-secondary.active,.show>.btn-secondary.dropdown-toggle{color:#fff;background-color:#4e4e4e;border-color:#494949}.btn-check:checked+.btn-secondary:focus,.btn-check:active+.btn-secondary:focus,.btn-secondary:active:focus,.btn-secondary.active:focus,.show>.btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(121,121,121,0.5)}.btn-secondary:disabled,.btn-secondary.disabled{color:#fff;background-color:#616161;border-color:#616161}.btn-success{color:#000;background-color:#43a047;border-color:#43a047}.btn-success:hover{color:#000;background-color:#5fae63;border-color:#56aa59}.btn-check:focus+.btn-success,.btn-success:focus{color:#000;background-color:#5fae63;border-color:#56aa59;box-shadow:0 0 0 0 rgba(57,136,60,0.5)}.btn-check:checked+.btn-success,.btn-check:active+.btn-success,.btn-success:active,.btn-success.active,.show>.btn-success.dropdown-toggle{color:#000;background-color:#69b36c;border-color:#56aa59}.btn-check:checked+.btn-success:focus,.btn-check:active+.btn-success:focus,.btn-success:active:focus,.btn-success.active:focus,.show>.btn-success.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(57,136,60,0.5)}.btn-success:disabled,.btn-success.disabled{color:#000;background-color:#43a047;border-color:#43a047}.btn-info{color:#000;background-color:#469eb9;border-color:#469eb9}.btn-info:hover{color:#000;background-color:#62adc4;border-color:#59a8c0}.btn-check:focus+.btn-info,.btn-info:focus{color:#000;background-color:#62adc4;border-color:#59a8c0;box-shadow:0 0 0 0 rgba(60,134,157,0.5)}.btn-check:checked+.btn-info,.btn-check:active+.btn-info,.btn-info:active,.btn-info.active,.show>.btn-info.dropdown-toggle{color:#000;background-color:#6bb1c7;border-color:#59a8c0}.btn-check:checked+.btn-info:focus,.btn-check:active+.btn-info:focus,.btn-info:active:focus,.btn-info.active:focus,.show>.btn-info.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(60,134,157,0.5)}.btn-info:disabled,.btn-info.disabled{color:#000;background-color:#469eb9;border-color:#469eb9}.btn-warning{color:#000;background-color:#f9a825;border-color:#f9a825}.btn-warning:hover{color:#000;background-color:#fab546;border-color:#fab13b}.btn-check:focus+.btn-warning,.btn-warning:focus{color:#000;background-color:#fab546;border-color:#fab13b;box-shadow:0 0 0 0 rgba(212,143,31,0.5)}.btn-check:checked+.btn-warning,.btn-check:active+.btn-warning,.btn-warning:active,.btn-warning.active,.show>.btn-warning.dropdown-toggle{color:#000;background-color:#fab951;border-color:#fab13b}.btn-check:checked+.btn-warning:focus,.btn-check:active+.btn-warning:focus,.btn-warning:active:focus,.btn-warning.active:focus,.show>.btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(212,143,31,0.5)}.btn-warning:disabled,.btn-warning.disabled{color:#000;background-color:#f9a825;border-color:#f9a825}.btn-danger{color:#000;background-color:#ff511f;border-color:#ff511f}.btn-danger:hover{color:#000;background-color:#ff6b41;border-color:#ff6235}.btn-check:focus+.btn-danger,.btn-danger:focus{color:#000;background-color:#ff6b41;border-color:#ff6235;box-shadow:0 0 0 0 rgba(217,69,26,0.5)}.btn-check:checked+.btn-danger,.btn-check:active+.btn-danger,.btn-danger:active,.btn-danger.active,.show>.btn-danger.dropdown-toggle{color:#000;background-color:#ff744c;border-color:#ff6235}.btn-check:checked+.btn-danger:focus,.btn-check:active+.btn-danger:focus,.btn-danger:active:focus,.btn-danger.active:focus,.show>.btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(217,69,26,0.5)}.btn-danger:disabled,.btn-danger.disabled{color:#000;background-color:#ff511f;border-color:#ff511f}.btn-light{color:#fff;background-color:#616161;border-color:#616161}.btn-light:hover{color:#fff;background-color:#525252;border-color:#4e4e4e}.btn-check:focus+.btn-light,.btn-light:focus{color:#fff;background-color:#525252;border-color:#4e4e4e;box-shadow:0 0 0 0 rgba(121,121,121,0.5)}.btn-check:checked+.btn-light,.btn-check:active+.btn-light,.btn-light:active,.btn-light.active,.show>.btn-light.dropdown-toggle{color:#fff;background-color:#4e4e4e;border-color:#494949}.btn-check:checked+.btn-light:focus,.btn-check:active+.btn-light:focus,.btn-light:active:focus,.btn-light.active:focus,.show>.btn-light.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(121,121,121,0.5)}.btn-light:disabled,.btn-light.disabled{color:#fff;background-color:#616161;border-color:#616161}.btn-dark{color:#fff;background-color:#616161;border-color:#616161}.btn-dark:hover{color:#fff;background-color:#525252;border-color:#4e4e4e}.btn-check:focus+.btn-dark,.btn-dark:focus{color:#fff;background-color:#525252;border-color:#4e4e4e;box-shadow:0 0 0 0 rgba(121,121,121,0.5)}.btn-check:checked+.btn-dark,.btn-check:active+.btn-dark,.btn-dark:active,.btn-dark.active,.show>.btn-dark.dropdown-toggle{color:#fff;background-color:#4e4e4e;border-color:#494949}.btn-check:checked+.btn-dark:focus,.btn-check:active+.btn-dark:focus,.btn-dark:active:focus,.btn-dark.active:focus,.show>.btn-dark.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(121,121,121,0.5)}.btn-dark:disabled,.btn-dark.disabled{color:#fff;background-color:#616161;border-color:#616161}.btn-outline-primary{color:#007be5;border-color:#007be5}.btn-outline-primary:hover{color:#000;background-color:#007be5;border-color:#007be5}.btn-check:focus+.btn-outline-primary,.btn-outline-primary:focus{box-shadow:0 0 0 0 rgba(0,123,229,0.5)}.btn-check:checked+.btn-outline-primary,.btn-check:active+.btn-outline-primary,.btn-outline-primary:active,.btn-outline-primary.active,.btn-outline-primary.dropdown-toggle.show{color:#000;background-color:#007be5;border-color:#007be5}.btn-check:checked+.btn-outline-primary:focus,.btn-check:active+.btn-outline-primary:focus,.btn-outline-primary:active:focus,.btn-outline-primary.active:focus,.btn-outline-primary.dropdown-toggle.show:focus{box-shadow:0 0 0 0 rgba(0,123,229,0.5)}.btn-outline-primary:disabled,.btn-outline-primary.disabled{color:#007be5;background-color:transparent}.btn-outline-secondary{color:#616161;border-color:#616161}.btn-outline-secondary:hover{color:#fff;background-color:#616161;border-color:#616161}.btn-check:focus+.btn-outline-secondary,.btn-outline-secondary:focus{box-shadow:0 0 0 0 rgba(97,97,97,0.5)}.btn-check:checked+.btn-outline-secondary,.btn-check:active+.btn-outline-secondary,.btn-outline-secondary:active,.btn-outline-secondary.active,.btn-outline-secondary.dropdown-toggle.show{color:#fff;background-color:#616161;border-color:#616161}.btn-check:checked+.btn-outline-secondary:focus,.btn-check:active+.btn-outline-secondary:focus,.btn-outline-secondary:active:focus,.btn-outline-secondary.active:focus,.btn-outline-secondary.dropdown-toggle.show:focus{box-shadow:0 0 0 0 rgba(97,97,97,0.5)}.btn-outline-secondary:disabled,.btn-outline-secondary.disabled{color:#616161;background-color:transparent}.btn-outline-success{color:#43a047;border-color:#43a047}.btn-outline-success:hover{color:#000;background-color:#43a047;border-color:#43a047}.btn-check:focus+.btn-outline-success,.btn-outline-success:focus{box-shadow:0 0 0 0 rgba(67,160,71,0.5)}.btn-check:checked+.btn-outline-success,.btn-check:active+.btn-outline-success,.btn-outline-success:active,.btn-outline-success.active,.btn-outline-success.dropdown-toggle.show{color:#000;background-color:#43a047;border-color:#43a047}.btn-check:checked+.btn-outline-success:focus,.btn-check:active+.btn-outline-success:focus,.btn-outline-success:active:focus,.btn-outline-success.active:focus,.btn-outline-success.dropdown-toggle.show:focus{box-shadow:0 0 0 0 rgba(67,160,71,0.5)}.btn-outline-success:disabled,.btn-outline-success.disabled{color:#43a047;background-color:transparent}.btn-outline-info{color:#469eb9;border-color:#469eb9}.btn-outline-info:hover{color:#000;background-color:#469eb9;border-color:#469eb9}.btn-check:focus+.btn-outline-info,.btn-outline-info:focus{box-shadow:0 0 0 0 rgba(70,158,185,0.5)}.btn-check:checked+.btn-outline-info,.btn-check:active+.btn-outline-info,.btn-outline-info:active,.btn-outline-info.active,.btn-outline-info.dropdown-toggle.show{color:#000;background-color:#469eb9;border-color:#469eb9}.btn-check:checked+.btn-outline-info:focus,.btn-check:active+.btn-outline-info:focus,.btn-outline-info:active:focus,.btn-outline-info.active:focus,.btn-outline-info.dropdown-toggle.show:focus{box-shadow:0 0 0 0 rgba(70,158,185,0.5)}.btn-outline-info:disabled,.btn-outline-info.disabled{color:#469eb9;background-color:transparent}.btn-outline-warning{color:#f9a825;border-color:#f9a825}.btn-outline-warning:hover{color:#000;background-color:#f9a825;border-color:#f9a825}.btn-check:focus+.btn-outline-warning,.btn-outline-warning:focus{box-shadow:0 0 0 0 rgba(249,168,37,0.5)}.btn-check:checked+.btn-outline-warning,.btn-check:active+.btn-outline-warning,.btn-outline-warning:active,.btn-outline-warning.active,.btn-outline-warning.dropdown-toggle.show{color:#000;background-color:#f9a825;border-color:#f9a825}.btn-check:checked+.btn-outline-warning:focus,.btn-check:active+.btn-outline-warning:focus,.btn-outline-warning:active:focus,.btn-outline-warning.active:focus,.btn-outline-warning.dropdown-toggle.show:focus{box-shadow:0 0 0 0 rgba(249,168,37,0.5)}.btn-outline-warning:disabled,.btn-outline-warning.disabled{color:#f9a825;background-color:transparent}.btn-outline-danger{color:#ff511f;border-color:#ff511f}.btn-outline-danger:hover{color:#000;background-color:#ff511f;border-color:#ff511f}.btn-check:focus+.btn-outline-danger,.btn-outline-danger:focus{box-shadow:0 0 0 0 rgba(255,81,31,0.5)}.btn-check:checked+.btn-outline-danger,.btn-check:active+.btn-outline-danger,.btn-outline-danger:active,.btn-outline-danger.active,.btn-outline-danger.dropdown-toggle.show{color:#000;background-color:#ff511f;border-color:#ff511f}.btn-check:checked+.btn-outline-danger:focus,.btn-check:active+.btn-outline-danger:focus,.btn-outline-danger:active:focus,.btn-outline-danger.active:focus,.btn-outline-danger.dropdown-toggle.show:focus{box-shadow:0 0 0 0 rgba(255,81,31,0.5)}.btn-outline-danger:disabled,.btn-outline-danger.disabled{color:#ff511f;background-color:transparent}.btn-outline-light{color:#616161;border-color:#616161}.btn-outline-light:hover{color:#fff;background-color:#616161;border-color:#616161}.btn-check:focus+.btn-outline-light,.btn-outline-light:focus{box-shadow:0 0 0 0 rgba(97,97,97,0.5)}.btn-check:checked+.btn-outline-light,.btn-check:active+.btn-outline-light,.btn-outline-light:active,.btn-outline-light.active,.btn-outline-light.dropdown-toggle.show{color:#fff;background-color:#616161;border-color:#616161}.btn-check:checked+.btn-outline-light:focus,.btn-check:active+.btn-outline-light:focus,.btn-outline-light:active:focus,.btn-outline-light.active:focus,.btn-outline-light.dropdown-toggle.show:focus{box-shadow:0 0 0 0 rgba(97,97,97,0.5)}.btn-outline-light:disabled,.btn-outline-light.disabled{color:#616161;background-color:transparent}.btn-outline-dark{color:#616161;border-color:#616161}.btn-outline-dark:hover{color:#fff;background-color:#616161;border-color:#616161}.btn-check:focus+.btn-outline-dark,.btn-outline-dark:focus{box-shadow:0 0 0 0 rgba(97,97,97,0.5)}.btn-check:checked+.btn-outline-dark,.btn-check:active+.btn-outline-dark,.btn-outline-dark:active,.btn-outline-dark.active,.btn-outline-dark.dropdown-toggle.show{color:#fff;background-color:#616161;border-color:#616161}.btn-check:checked+.btn-outline-dark:focus,.btn-check:active+.btn-outline-dark:focus,.btn-outline-dark:active:focus,.btn-outline-dark.active:focus,.btn-outline-dark.dropdown-toggle.show:focus{box-shadow:0 0 0 0 rgba(97,97,97,0.5)}.btn-outline-dark:disabled,.btn-outline-dark.disabled{color:#616161;background-color:transparent}.btn-link{font-weight:400;color:var(--t42-link-color);text-decoration:underline}.btn-link:hover{color:var(--t42-link-hover-color)}.btn-link:disabled,.btn-link.disabled{color:#6c757d}.btn-lg,.btn-group-lg>.btn{padding:0 .875rem;font-size:.75rem;border-radius:0}.btn-sm,.btn-group-sm>.btn{padding:0 .875rem;font-size:.75rem;border-radius:0}.btn-group,.btn-group-vertical{position:relative;display:inline-flex;vertical-align:middle}.btn-group>.btn,.btn-group-vertical>.btn{position:relative;flex:1 1 auto}.btn-group>.btn-check:checked+.btn,.btn-group>.btn-check:focus+.btn,.btn-group>.btn:hover,.btn-group>.btn:focus,.btn-group>.btn:active,.btn-group>.btn.active,.btn-group-vertical>.btn-check:checked+.btn,.btn-group-vertical>.btn-check:focus+.btn,.btn-group-vertical>.btn:hover,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn.active{z-index:1}.btn-toolbar{display:flex;flex-wrap:wrap;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group>.btn:not(:first-child),.btn-group>.btn-group:not(:first-child){margin-left:-1px}.btn-group>.btn:not(:last-child):not(.dropdown-toggle),.btn-group>.btn-group:not(:last-child)>.btn{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:nth-child(n+3),.btn-group>:not(.btn-check)+.btn,.btn-group>.btn-group:not(:first-child)>.btn{border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.65625rem;padding-left:.65625rem}.dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after,.dropend .dropdown-toggle-split::after{margin-left:0}.dropstart .dropdown-toggle-split::before{margin-right:0}.btn-sm+.dropdown-toggle-split,.btn-group-sm>.btn+.dropdown-toggle-split{padding-right:.65625rem;padding-left:.65625rem}.btn-lg+.dropdown-toggle-split,.btn-group-lg>.btn+.dropdown-toggle-split{padding-right:.65625rem;padding-left:.65625rem}.btn-group-vertical{flex-direction:column;align-items:flex-start;justify-content:center}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn:not(:first-child),.btn-group-vertical>.btn-group:not(:first-child){margin-top:-1px}.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle),.btn-group-vertical>.btn-group:not(:last-child)>.btn{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn ~ .btn,.btn-group-vertical>.btn-group:not(:first-child)>.btn{border-top-left-radius:0;border-top-right-radius:0}button,button:focus{outline:none}.btn{color:var(--t42-link-color);transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, border-color;cursor:default}.btn.disabled,.btn:disabled{color:var(--t42-link-color);cursor:default}.btn:not(.disabled):not(:disabled).active,.btn:not(.disabled):not(:disabled):hover{border-color:var(--t42-color-opacity-30);color:var(--white);backdrop-filter:var(--backdrop-filter)}.btn:focus,.btn:active{color:var(--white)}.btn-primary{background-color:rgba(0,123,229,0.05)}.btn-primary.disabled,.btn-primary:disabled{background-color:rgba(0,123,229,0.05)}.btn-primary:not(.disabled):not(:disabled).active,.btn-primary:not(.disabled):not(:disabled):hover{background-color:#007be5}.btn-primary:not(.disabled):not(:disabled).btn-icon.active,.btn-primary:not(.disabled):not(:disabled).btn-icon:focus,.btn-primary:not(.disabled):not(:disabled).btn-icon:hover{color:var(--white)}.btn-primary.dropdown-toggle.active,.btn-primary.dropdown-toggle:active,.btn-primary.dropdown-toggle:focus{border-color:var(--t42-color-opacity-30);background-color:#007be5}.btn-secondary{background-color:rgba(97,97,97,0.05)}.btn-secondary.disabled,.btn-secondary:disabled{background-color:rgba(97,97,97,0.05)}.btn-secondary:not(.disabled):not(:disabled).active,.btn-secondary:not(.disabled):not(:disabled):hover{background-color:#616161}.btn-secondary:not(.disabled):not(:disabled).btn-icon.active,.btn-secondary:not(.disabled):not(:disabled).btn-icon:focus,.btn-secondary:not(.disabled):not(:disabled).btn-icon:hover{color:var(--white)}.btn-secondary.dropdown-toggle.active,.btn-secondary.dropdown-toggle:active,.btn-secondary.dropdown-toggle:focus{border-color:var(--t42-color-opacity-30);background-color:#616161}.btn-success{background-color:rgba(67,160,71,0.05)}.btn-success.disabled,.btn-success:disabled{background-color:rgba(67,160,71,0.05)}.btn-success:not(.disabled):not(:disabled).active,.btn-success:not(.disabled):not(:disabled):hover{background-color:#43a047}.btn-success:not(.disabled):not(:disabled).btn-icon.active,.btn-success:not(.disabled):not(:disabled).btn-icon:focus,.btn-success:not(.disabled):not(:disabled).btn-icon:hover{color:var(--white)}.btn-success.dropdown-toggle.active,.btn-success.dropdown-toggle:active,.btn-success.dropdown-toggle:focus{border-color:var(--t42-color-opacity-30);background-color:#43a047}.btn-info{background-color:rgba(70,158,185,0.05)}.btn-info.disabled,.btn-info:disabled{background-color:rgba(70,158,185,0.05)}.btn-info:not(.disabled):not(:disabled).active,.btn-info:not(.disabled):not(:disabled):hover{background-color:#469eb9}.btn-info:not(.disabled):not(:disabled).btn-icon.active,.btn-info:not(.disabled):not(:disabled).btn-icon:focus,.btn-info:not(.disabled):not(:disabled).btn-icon:hover{color:var(--white)}.btn-info.dropdown-toggle.active,.btn-info.dropdown-toggle:active,.btn-info.dropdown-toggle:focus{border-color:var(--t42-color-opacity-30);background-color:#469eb9}.btn-warning{background-color:rgba(249,168,37,0.05)}.btn-warning.disabled,.btn-warning:disabled{background-color:rgba(249,168,37,0.05)}.btn-warning:not(.disabled):not(:disabled).active,.btn-warning:not(.disabled):not(:disabled):hover{background-color:#f9a825}.btn-warning:not(.disabled):not(:disabled).btn-icon.active,.btn-warning:not(.disabled):not(:disabled).btn-icon:focus,.btn-warning:not(.disabled):not(:disabled).btn-icon:hover{color:var(--white)}.btn-warning.dropdown-toggle.active,.btn-warning.dropdown-toggle:active,.btn-warning.dropdown-toggle:focus{border-color:var(--t42-color-opacity-30);background-color:#f9a825}.btn-danger{background-color:rgba(255,81,31,0.05)}.btn-danger.disabled,.btn-danger:disabled{background-color:rgba(255,81,31,0.05)}.btn-danger:not(.disabled):not(:disabled).active,.btn-danger:not(.disabled):not(:disabled):hover{background-color:#ff511f}.btn-danger:not(.disabled):not(:disabled).btn-icon.active,.btn-danger:not(.disabled):not(:disabled).btn-icon:focus,.btn-danger:not(.disabled):not(:disabled).btn-icon:hover{color:var(--white)}.btn-danger.dropdown-toggle.active,.btn-danger.dropdown-toggle:active,.btn-danger.dropdown-toggle:focus{border-color:var(--t42-color-opacity-30);background-color:#ff511f}.btn-light{background-color:rgba(97,97,97,0.05)}.btn-light.disabled,.btn-light:disabled{background-color:rgba(97,97,97,0.05)}.btn-light:not(.disabled):not(:disabled).active,.btn-light:not(.disabled):not(:disabled):hover{background-color:#616161}.btn-light:not(.disabled):not(:disabled).btn-icon.active,.btn-light:not(.disabled):not(:disabled).btn-icon:focus,.btn-light:not(.disabled):not(:disabled).btn-icon:hover{color:var(--white)}.btn-light.dropdown-toggle.active,.btn-light.dropdown-toggle:active,.btn-light.dropdown-toggle:focus{border-color:var(--t42-color-opacity-30);background-color:#616161}.btn-dark{background-color:rgba(97,97,97,0.05)}.btn-dark.disabled,.btn-dark:disabled{background-color:rgba(97,97,97,0.05)}.btn-dark:not(.disabled):not(:disabled).active,.btn-dark:not(.disabled):not(:disabled):hover{background-color:#616161}.btn-dark:not(.disabled):not(:disabled).btn-icon.active,.btn-dark:not(.disabled):not(:disabled).btn-icon:focus,.btn-dark:not(.disabled):not(:disabled).btn-icon:hover{color:var(--white)}.btn-dark.dropdown-toggle.active,.btn-dark.dropdown-toggle:active,.btn-dark.dropdown-toggle:focus{border-color:var(--t42-color-opacity-30);background-color:#616161}.btn-link{text-decoration:none;backdrop-filter:none}.btn-link:not(.disabled):not(:disabled).active,.btn-link:not(.disabled):not(:disabled):focus,.btn-link:not(.disabled):not(:disabled):hover{border-color:transparent;color:var(--t42-link-color);text-decoration:underline}.btn-icon:not(.disabled):not(:disabled).active,.btn-icon:not(.disabled):not(:disabled):focus,.btn-icon:not(.disabled):not(:disabled):hover{color:var(--t42-link-color)}.btn-icon-action{display:flex;justify-content:center;width:1rem;height:1rem;padding:0;border-radius:50%;font-size:0.75rem;transition:all .2s ease-in-out}@media (prefers-reduced-motion: reduce){.btn-icon-action{transition:none}}.btn-icon-action:not(.disabled):not(:disabled).active,.btn-icon-action:not(.disabled):not(:disabled):hover,.btn-icon-action:not(.disabled):not(:disabled):focus{border-color:transparent;background-color:Rgb(var(--t42-bg-light));box-shadow:var(--t42-shadow)}.btn-icon-action-right{position:absolute;right:0.25rem}.btn-icon-action-show-hover{transition:all .2s ease-in-out}@media (prefers-reduced-motion: reduce){.btn-icon-action-show-hover{transition:none}}.btn-icon-action-show-hover .btn-icon-action{opacity:0}.btn-icon-action-show-hover:not(.disabled):not(:disabled):hover .btn-icon-action{opacity:1}.btn-close{width:1rem;height:1rem;filter:var(--filter-close)}.breadcrumb{display:flex;flex-wrap:wrap;padding:0 0;margin-bottom:.5rem;list-style:none;background-color:rgba(0,0,0,0)}.breadcrumb-item+.breadcrumb-item{padding-left:.5rem}.breadcrumb-item+.breadcrumb-item::before{float:left;padding-right:.5rem;color:#6c757d;content:var(--bs-breadcrumb-divider, "/") /* rtl: var(--bs-breadcrumb-divider, "/") */}.breadcrumb-item.active{color:var(--t42-link-color)}.breadcrumb-item{font-size:83.3%}.breadcrumb-item.active{text-decoration:underline}.breadcrumb-item+.breadcrumb-item{padding-left:0}.breadcrumb-item+.breadcrumb-item::before{position:relative;top:0.063rem;left:0.063rem;width:0.75rem;height:0.75rem;background-color:var(--t42-content-color);content:"";-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M339.2,256.3c0,2.4-0.9,4.4-2.6,6.1L203,396c-1.7,1.7-3.8,2.6-6.1,2.6c-2.4,0-4.6-0.9-6.7-2.6l-14.3-14.3 c-2-2-3.1-4.3-3.1-6.7s1-4.6,3.1-6.7L288,256.3L175.9,143.6c-2-1.7-3.1-3.8-3.1-6.1s1-4.6,3.1-6.7l14.3-14.3c1.7-2,3.9-3.1,6.7-3.1 s4.8,1,6.1,3.1l133.6,133.1C338.3,251.3,339.2,253.5,339.2,256.3L339.2,256.3z%27/%3E%3C/svg%3E")}mark,.mark{color:var(--white)}pre{background-color:var(--t42-bg-dark)}blockquote,.blockquote{padding:1rem 1rem 0.01rem;border-left:0.25rem solid var(--secondary);background-color:Rgb(var(--t42-bg-dark))}.blockquote-footer{margin-top:-2rem;margin-left:1.25rem;color:var(--t42-content-color-muted);font-size:0.875em}pre{border:0.0625rem solid var(--t42-color-opacity-10)}.card{position:relative;display:flex;flex-direction:column;min-width:0;word-wrap:break-word;background-color:Rgba(var(--t42-bg-light), 0.75);background-clip:border-box;border:1px solid var(--t42-color-opacity-10);border-radius:0}.card>hr{margin-right:0;margin-left:0}.card>.list-group{border-top:inherit;border-bottom:inherit}.card>.list-group:first-child{border-top-width:0;border-top-left-radius:0;border-top-right-radius:0}.card>.list-group:last-child{border-bottom-width:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.card>.card-header+.list-group,.card>.list-group+.card-footer{border-top:0}.card-body{flex:1 1 auto;padding:1.25rem 1.25rem}.card-title{margin-bottom:.5rem}.card-subtitle{margin-top:-.25rem;margin-bottom:0}.card-text:last-child{margin-bottom:0}.card-link+.card-link{margin-left:1.25rem}.card-header{padding:.625rem 1.25rem;margin-bottom:0;color:var(--t42-link-color);background-color:rgba(0,0,0,0);border-bottom:1px solid var(--t42-color-opacity-10)}.card-header:first-child{border-radius:0 0 0 0}.card-footer{padding:.625rem 1.25rem;color:var(--t42-link-color);background-color:rgba(0,0,0,0);border-top:1px solid var(--t42-color-opacity-10)}.card-footer:last-child{border-radius:0 0 0 0}.card-header-tabs{margin-right:-.625rem;margin-bottom:-.625rem;margin-left:-.625rem;border-bottom:0}.card-header-tabs .nav-link.active{background-color:Rgba(var(--t42-bg-light), 0.75);border-bottom-color:Rgba(var(--t42-bg-light), 0.75)}.card-header-pills{margin-right:-.625rem;margin-left:-.625rem}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1rem;border-radius:0}.card-img,.card-img-top,.card-img-bottom{width:100%}.card-img,.card-img-top{border-top-left-radius:0;border-top-right-radius:0}.card-img,.card-img-bottom{border-bottom-right-radius:0;border-bottom-left-radius:0}.card-group>.card{margin-bottom:.75rem}@media (min-width: 576px){.card-group{display:flex;flex-flow:row wrap}.card-group>.card{flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:not(:last-child) .card-img-top,.card-group>.card:not(:last-child) .card-header{border-top-right-radius:0}.card-group>.card:not(:last-child) .card-img-bottom,.card-group>.card:not(:last-child) .card-footer{border-bottom-right-radius:0}.card-group>.card:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:not(:first-child) .card-img-top,.card-group>.card:not(:first-child) .card-header{border-top-left-radius:0}.card-group>.card:not(:first-child) .card-img-bottom,.card-group>.card:not(:first-child) .card-footer{border-bottom-left-radius:0}}.card{box-shadow:var(--t42-shadow);backdrop-filter:var(--backdrop-filter)}.card .card-header{border-bottom-width:0}.card .card-subtitle{margin-bottom:0.5rem;font-size:83.3%}.card.bg-primary{background-color:transparent !important}.card.bg-primary .card-header{background-color:Rgba(var(--t42-bg-mid), 0.75)}.card.bg-primary .card-body{background-color:Rgba(var(--t42-bg-light), 0.75)}.card.bg-secondary{background-color:transparent !important}.card.bg-secondary .card-header{background-color:Rgba(var(--t42-bg-light), 0.75)}.card.bg-secondary .card-body{background-color:Rgba(var(--t42-bg-mid), 0.75)}.card:not(.bg-primary):not(.bg-secondary) .card-header+.card-body{padding-top:0}.card-header-tabs{margin-bottom:0}.accordion .card:first-of-type,.accordion .card:not(:first-of-type):not(:last-of-type){margin-bottom:0.5rem;border-bottom:var(--t42-border)}.accordion .card-header{position:relative;padding:0}.accordion .card-header .btn-link{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;width:100%;padding:0.75rem 2rem;line-height:1.4;text-align:left}.accordion .card-header .btn-link::before{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:transform;position:absolute;display:inline-block;width:0.75rem;height:0.75rem;background-color:var(--t42-content-color);transform:translateX(-1rem) translateY(0.063rem) rotate(-90deg);content:"";-webkit-mask-image:var(--t42-select-indicator)}.accordion .card-header .btn-link:hover{backdrop-filter:none}.accordion .card-header .btn-link.collapsed::before{transform:translateX(-1rem) translateY(0.063rem)}.accordion .card-header .btn-link.disabled::before,.accordion .card-header .btn-link:disabled::before{opacity:.35}.accordion .card-body{padding:0 1.25rem 1.25rem}.accordion .bg-primary .card-body,.accordion .bg-secondary .card-body{padding:1.25rem}.dropup,.dropend,.dropdown,.dropstart{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:0;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{position:absolute;z-index:1000;display:none;min-width:10rem;padding:0 0;margin:0;font-size:.75rem;color:var(--t42-content-color);text-align:left;list-style:none;background-color:Rgba(var(--t42-bg-light), 0.75);background-clip:padding-box;border:1px solid var(--t42-color-opacity-10);border-radius:0}.dropdown-menu[data-bs-popper]{top:100%;left:0;margin-top:.125rem}.dropdown-menu-start{--bs-position: start}.dropdown-menu-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-end{--bs-position: end}.dropdown-menu-end[data-bs-popper]{right:0;left:auto}@media (min-width: 576px){.dropdown-menu-sm-start{--bs-position: start}.dropdown-menu-sm-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-sm-end{--bs-position: end}.dropdown-menu-sm-end[data-bs-popper]{right:0;left:auto}}@media (min-width: 768px){.dropdown-menu-md-start{--bs-position: start}.dropdown-menu-md-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-md-end{--bs-position: end}.dropdown-menu-md-end[data-bs-popper]{right:0;left:auto}}@media (min-width: 992px){.dropdown-menu-lg-start{--bs-position: start}.dropdown-menu-lg-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-lg-end{--bs-position: end}.dropdown-menu-lg-end[data-bs-popper]{right:0;left:auto}}@media (min-width: 1200px){.dropdown-menu-xl-start{--bs-position: start}.dropdown-menu-xl-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-xl-end{--bs-position: end}.dropdown-menu-xl-end[data-bs-popper]{right:0;left:auto}}@media (min-width: 1400px){.dropdown-menu-xxl-start{--bs-position: start}.dropdown-menu-xxl-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-xxl-end{--bs-position: end}.dropdown-menu-xxl-end[data-bs-popper]{right:0;left:auto}}.dropup .dropdown-menu[data-bs-popper]{top:auto;bottom:100%;margin-top:0;margin-bottom:.125rem}.dropup .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:0;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropend .dropdown-menu[data-bs-popper]{top:0;right:auto;left:100%;margin-top:0;margin-left:.125rem}.dropend .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:0;content:"";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid}.dropend .dropdown-toggle:empty::after{margin-left:0}.dropend .dropdown-toggle::after{vertical-align:0}.dropstart .dropdown-menu[data-bs-popper]{top:0;right:100%;left:auto;margin-top:0;margin-right:.125rem}.dropstart .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:0;content:""}.dropstart .dropdown-toggle::after{display:none}.dropstart .dropdown-toggle::before{display:inline-block;margin-right:.255em;vertical-align:0;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropstart .dropdown-toggle:empty::after{margin-left:0}.dropstart .dropdown-toggle::before{vertical-align:0}.dropdown-divider{height:0;margin:0 0;overflow:hidden;border-top:1px solid var(--t42-color-opacity-10)}.dropdown-item{display:block;width:100%;padding:.375rem 1rem;clear:both;font-weight:400;color:var(--t42-content-color);text-align:inherit;text-decoration:none;white-space:nowrap;background-color:transparent;border:0}.dropdown-item:first-child{border-top-left-radius:0;border-top-right-radius:0}.dropdown-item:last-child{border-bottom-right-radius:0;border-bottom-left-radius:0}.dropdown-item:hover,.dropdown-item:focus{color:var(--t42-link-hover-color);background-color:var(--t42-link-hover-bg)}.dropdown-item.active,.dropdown-item:active{color:var(--t42-link-hover-color);text-decoration:none;background-color:var(--t42-link-active-bg)}.dropdown-item.disabled,.dropdown-item:disabled{color:#adb5bd;pointer-events:none;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:0 1rem;margin-bottom:0;font-size:.65625rem;color:shade-color(#616161, 10%);white-space:nowrap}.dropdown-item-text{display:block;padding:.375rem 1rem;color:var(--t42-content-color)}.dropdown-menu-dark{color:#dee2e6;background-color:#343a40;border-color:var(--t42-color-opacity-10)}.dropdown-menu-dark .dropdown-item{color:#dee2e6}.dropdown-menu-dark .dropdown-item:hover,.dropdown-menu-dark .dropdown-item:focus{color:#fff;background-color:rgba(255,255,255,0.15)}.dropdown-menu-dark .dropdown-item.active,.dropdown-menu-dark .dropdown-item:active{color:var(--t42-link-hover-color);background-color:var(--t42-link-active-bg)}.dropdown-menu-dark .dropdown-item.disabled,.dropdown-menu-dark .dropdown-item:disabled{color:#adb5bd}.dropdown-menu-dark .dropdown-divider{border-color:var(--t42-color-opacity-10)}.dropdown-menu-dark .dropdown-item-text{color:#dee2e6}.dropdown-menu-dark .dropdown-header{color:#adb5bd}.dropdown-menu{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:opacity, visability;display:block;visibility:hidden;opacity:0;backdrop-filter:var(--backdrop-filter)}.dropdown-menu.show{visibility:visible;opacity:1}.dropdown-toggle::after{position:relative;width:0.5rem;height:0.5rem;border:0;background-color:var(--t42-link-color);content:"";-webkit-mask-image:url("data:image/svg+xml,%3Csvg version=%271.1%27 xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M480.768 186.88l-211.968 211.456q-5.12 5.632-12.8 5.632t-12.8-5.632l-211.968-211.456q-5.632-5.632-5.632-13.312t5.632-12.8l47.616-47.104q5.12-5.632 12.8-5.632t12.8 5.632l151.552 151.552 151.552-151.552q5.632-5.632 12.8-5.632t13.312 5.632l47.104 47.104q5.632 5.632 5.632 12.8t-5.632 13.312z%27%3E%3C/path%3E%3C/svg%3E")}.dropdown-toggle.show::after{color:var(--white)}.dropup .dropdown-toggle::after{position:relative;top:0.188rem;width:0.5rem;height:0.5rem;border:0;background-color:var(--t42-link-color);content:"";-webkit-mask-image:url("data:image/svg+xml,%3Csvg version=%271.1%27 xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M480.768 351.488l-47.104 47.104q-5.632 5.12-13.312 5.12t-12.8-5.12l-151.552-152.064-151.552 152.064q-5.632 5.12-12.8 5.12t-12.8-5.12l-47.616-47.104q-5.632-5.632-5.632-13.312t5.632-12.8l211.968-211.968q5.632-5.12 12.8-5.12t12.8 5.12l211.968 211.968q5.632 5.632 5.632 12.8t-5.632 13.312z%27%3E%3C/path%3E%3C/svg%3E%0A")}.form-label{margin-bottom:.5rem}.col-form-label{padding-top:1px;padding-bottom:1px;margin-bottom:0;font-size:inherit;line-height:1.875rem}.col-form-label-lg{padding-top:1px;padding-bottom:1px;font-size:.75rem}.col-form-label-sm{padding-top:1px;padding-bottom:1px;font-size:.75rem}.form-text{margin-top:.25rem;font-size:.875em;color:var(--t42-content-color-muted)}.form-control{display:block;width:100%;padding:0 .875rem;font-size:.75rem;font-weight:400;line-height:1.875rem;color:var(--t42-link-color);background-color:var(--t42-input-bg);background-clip:padding-box;border:1px solid var(--t42-color-opacity-10);appearance:none;border-radius:0;transition:border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.form-control{transition:none}}.form-control[type="file"]{overflow:hidden}.form-control[type="file"]:not(:disabled):not([readonly]){cursor:pointer}.form-control:focus{color:var(--t42-link-color);background-color:var(--t42-input-bg);border-color:#007be5;outline:0;box-shadow:0 0 0 0 rgba(0,123,229,0.25)}.form-control::-webkit-date-and-time-value{height:1.875rem}.form-control::placeholder{color:var(--t42-content-color-muted);opacity:1}.form-control:disabled,.form-control[readonly]{background-color:var(--t42-input-disabled-bg);opacity:1}.form-control::file-selector-button{padding:0 .875rem;margin:0 -.875rem;margin-inline-end:.875rem;color:var(--t42-link-color);background-color:#e9ecef;pointer-events:none;border-color:inherit;border-style:solid;border-width:0;border-inline-end-width:1px;border-radius:0;transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.form-control::file-selector-button{transition:none}}.form-control:hover:not(:disabled):not([readonly])::file-selector-button{background-color:#dde0e3}.form-control::-webkit-file-upload-button{padding:0 .875rem;margin:0 -.875rem;margin-inline-end:.875rem;color:var(--t42-link-color);background-color:#e9ecef;pointer-events:none;border-color:inherit;border-style:solid;border-width:0;border-inline-end-width:1px;border-radius:0;transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.form-control::-webkit-file-upload-button{transition:none}}.form-control:hover:not(:disabled):not([readonly])::-webkit-file-upload-button{background-color:#dde0e3}.form-control-plaintext{display:block;width:100%;padding:0 0;margin-bottom:0;line-height:1.875rem;color:var(--t42-content-color);background-color:transparent;border:solid transparent;border-width:1px 0}.form-control-plaintext.form-control-sm,.form-control-plaintext.form-control-lg{padding-right:0;padding-left:0}.form-control-sm{min-height:2rem;padding:0 .875rem;font-size:.75rem;border-radius:0}.form-control-sm::file-selector-button{padding:0 .875rem;margin:0 -.875rem;margin-inline-end:.875rem}.form-control-sm::-webkit-file-upload-button{padding:0 .875rem;margin:0 -.875rem;margin-inline-end:.875rem}.form-control-lg{min-height:2rem;padding:0 .875rem;font-size:.75rem;border-radius:0}.form-control-lg::file-selector-button{padding:0 .875rem;margin:0 -.875rem;margin-inline-end:.875rem}.form-control-lg::-webkit-file-upload-button{padding:0 .875rem;margin:0 -.875rem;margin-inline-end:.875rem}textarea.form-control{min-height:2rem}textarea.form-control-sm{min-height:2rem}textarea.form-control-lg{min-height:2rem}.form-control-color{width:3rem;height:auto;padding:0}.form-control-color:not(:disabled):not([readonly]){cursor:pointer}.form-control-color::-moz-color-swatch{height:1.875rem;border-radius:0}.form-control-color::-webkit-color-swatch{height:1.875rem;border-radius:0}.form-select{display:block;width:100%;padding:0 2.625rem 0 .875rem;-moz-padding-start:calc(.875rem - 3px);font-size:.75rem;font-weight:400;line-height:1.875rem;color:var(--t42-link-color);background-color:var(--t42-input-bg);background-image:var(--t42-select-indicator);background-repeat:no-repeat;background-position:right 0.5rem center;background-size:1rem;border:1px solid var(--t42-color-opacity-10);border-radius:0;transition:border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out;appearance:none}@media (prefers-reduced-motion: reduce){.form-select{transition:none}}.form-select:focus{border-color:#007be5;outline:0;box-shadow:0 0 0 0 rgba(0,123,229,0.25)}.form-select[multiple],.form-select[size]:not([size="1"]){padding-right:.875rem;background-image:none}.form-select:disabled{background-color:#e9ecef}.form-select:-moz-focusring{color:transparent;text-shadow:0 0 0 var(--t42-link-color)}.form-select-sm{padding-top:0;padding-bottom:0;padding-left:.875rem;font-size:.75rem;border-radius:0}.form-select-lg{padding-top:0;padding-bottom:0;padding-left:.875rem;font-size:.75rem;border-radius:0}.form-check{display:block;min-height:1.125rem;padding-left:1.25rem;margin-bottom:0}.form-check .form-check-input{float:left;margin-left:-1.25rem}.form-check-input{width:1em;height:1em;margin-top:.25em;vertical-align:top;background-color:var(--t42-input-bg);background-repeat:no-repeat;background-position:center;background-size:contain;border:1px solid rgba(0,0,0,0.25);appearance:none;color-adjust:exact}.form-check-input[type="checkbox"]{border-radius:.25em}.form-check-input[type="radio"]{border-radius:50%}.form-check-input:active{filter:brightness(90%)}.form-check-input:focus{border-color:#007be5;outline:0;box-shadow:0 0 0 0 rgba(0,123,229,0.25)}.form-check-input:checked{background-color:#007be5;border-color:#007be5}.form-check-input:checked[type="checkbox"]{background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 20 20%27%3e%3cpath fill=%27none%27 stroke=%27%23fff%27 stroke-linecap=%27round%27 stroke-linejoin=%27round%27 stroke-width=%273%27 d=%27M6 10l3 3l6-6%27/%3e%3c/svg%3e")}.form-check-input:checked[type="radio"]{background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%27-4 -4 8 8%27%3e%3ccircle r=%272%27 fill=%27%23fff%27/%3e%3c/svg%3e")}.form-check-input[type="checkbox"]:indeterminate{background-color:#007be5;border-color:#007be5;background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 20 20%27%3e%3cpath fill=%27none%27 stroke=%27%23fff%27 stroke-linecap=%27round%27 stroke-linejoin=%27round%27 stroke-width=%273%27 d=%27M6 10h8%27/%3e%3c/svg%3e")}.form-check-input:disabled{pointer-events:none;filter:none;opacity:.5}.form-check-input[disabled] ~ .form-check-label,.form-check-input:disabled ~ .form-check-label{opacity:.5}.form-switch{padding-left:2.5em}.form-switch .form-check-input{width:2em;margin-left:-2.5em;background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%27-4 -4 8 8%27%3e%3ccircle r=%273%27 fill=%27rgba%280,0,0,0.25%29%27/%3e%3c/svg%3e");background-position:left center;border-radius:2em;transition:background-position 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.form-switch .form-check-input{transition:none}}.form-switch .form-check-input:focus{background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%27-4 -4 8 8%27%3e%3ccircle r=%273%27 fill=%27%23007be5%27/%3e%3c/svg%3e")}.form-switch .form-check-input:checked{background-position:right center;background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%27-4 -4 8 8%27%3e%3ccircle r=%273%27 fill=%27%23fff%27/%3e%3c/svg%3e")}.form-check-inline{display:inline-block;margin-right:1rem}.btn-check{position:absolute;clip:rect(0, 0, 0, 0);pointer-events:none}.btn-check[disabled]+.btn,.btn-check:disabled+.btn{pointer-events:none;filter:none;opacity:.35}.form-range{width:100%;height:1rem;padding:0;background-color:transparent;appearance:none}.form-range:focus{outline:0}.form-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 0 rgba(0,123,229,0.25)}.form-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 0 rgba(0,123,229,0.25)}.form-range::-moz-focus-outer{border:0}.form-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-.25rem;background-color:#007be5;border:0;border-radius:1rem;transition:background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out;appearance:none}@media (prefers-reduced-motion: reduce){.form-range::-webkit-slider-thumb{transition:none}}.form-range::-webkit-slider-thumb:active{background-color:#b3d7f7}.form-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.form-range::-moz-range-thumb{width:1rem;height:1rem;background-color:#007be5;border:0;border-radius:1rem;transition:background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out;appearance:none}@media (prefers-reduced-motion: reduce){.form-range::-moz-range-thumb{transition:none}}.form-range::-moz-range-thumb:active{background-color:#b3d7f7}.form-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.form-range:disabled{pointer-events:none}.form-range:disabled::-webkit-slider-thumb{background-color:#adb5bd}.form-range:disabled::-moz-range-thumb{background-color:#adb5bd}.form-floating{position:relative}.form-floating>.form-control,.form-floating>.form-select{height:calc(3.5rem + 2px);line-height:1.25}.form-floating>label{position:absolute;top:0;left:0;height:100%;padding:1rem .875rem;pointer-events:none;border:1px solid transparent;transform-origin:0 0;transition:opacity 0.1s ease-in-out,transform 0.1s ease-in-out}@media (prefers-reduced-motion: reduce){.form-floating>label{transition:none}}.form-floating>.form-control{padding:1rem .875rem}.form-floating>.form-control::placeholder{color:transparent}.form-floating>.form-control:focus,.form-floating>.form-control:not(:placeholder-shown){padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control:-webkit-autofill{padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-select{padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control:focus ~ label,.form-floating>.form-control:not(:placeholder-shown) ~ label,.form-floating>.form-select ~ label{opacity:.65;transform:scale(0.85) translateY(-0.5rem) translateX(0.15rem)}.form-floating>.form-control:-webkit-autofill ~ label{opacity:.65;transform:scale(0.85) translateY(-0.5rem) translateX(0.15rem)}.input-group{position:relative;display:flex;flex-wrap:wrap;align-items:stretch;width:100%}.input-group>.form-control,.input-group>.form-select{position:relative;flex:1 1 auto;width:1%;min-width:0}.input-group>.form-control:focus,.input-group>.form-select:focus{z-index:3}.input-group .btn{position:relative;z-index:2}.input-group .btn:focus{z-index:3}.input-group-text{display:flex;align-items:center;padding:0 .875rem;font-size:.75rem;font-weight:400;line-height:1.875rem;color:var(--t42-content-color);text-align:center;white-space:nowrap;background-color:#e9ecef;border:1px solid var(--t42-color-opacity-10);border-radius:0}.input-group-lg>.form-control,.input-group-lg>.form-select,.input-group-lg>.input-group-text,.input-group-lg>.btn{padding:0 .875rem;font-size:.75rem;border-radius:0}.input-group-sm>.form-control,.input-group-sm>.form-select,.input-group-sm>.input-group-text,.input-group-sm>.btn{padding:0 .875rem;font-size:.75rem;border-radius:0}.input-group-lg>.form-select,.input-group-sm>.form-select{padding-right:3.5rem}.input-group:not(.has-validation)>:not(:last-child):not(.dropdown-toggle):not(.dropdown-menu),.input-group:not(.has-validation)>.dropdown-toggle:nth-last-child(n+3){border-top-right-radius:0;border-bottom-right-radius:0}.input-group.has-validation>:nth-last-child(n+3):not(.dropdown-toggle):not(.dropdown-menu),.input-group.has-validation>.dropdown-toggle:nth-last-child(n+4){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>:not(:first-child):not(.dropdown-menu):not(.valid-tooltip):not(.valid-feedback):not(.invalid-tooltip):not(.invalid-feedback){margin-left:-1px;border-top-left-radius:0;border-bottom-left-radius:0}.valid-feedback{display:none;width:100%;margin-top:.5rem;font-size:.7rem;color:#43a047}.valid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem 1rem;margin-top:.1rem;font-size:.65625rem;color:#000;background-color:#43a047;border-radius:0}.was-validated :valid ~ .valid-feedback,.was-validated :valid ~ .valid-tooltip,.is-valid ~ .valid-feedback,.is-valid ~ .valid-tooltip{display:block}.was-validated .form-control:valid,.form-control.is-valid{border-color:#43a047;padding-right:2rem;background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 8 8%27%3e%3cpath fill=%27%2343a047%27 d=%27M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z%27/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right .5rem center;background-size:1rem 1rem}.was-validated .form-control:valid:focus,.form-control.is-valid:focus{border-color:#43a047;box-shadow:0 0 0 0 rgba(67,160,71,0.25)}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{padding-right:2rem;background-position:top .5rem right .5rem}.was-validated .form-select:valid,.form-select.is-valid{border-color:#43a047}.was-validated .form-select:valid:not([multiple]):not([size]),.was-validated .form-select:valid:not([multiple])[size="1"],.form-select.is-valid:not([multiple]):not([size]),.form-select.is-valid:not([multiple])[size="1"]{padding-right:3.5rem;background-image:var(--t42-select-indicator),url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 8 8%27%3e%3cpath fill=%27%2343a047%27 d=%27M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z%27/%3e%3c/svg%3e");background-position:right 0.5rem center,right 1.75rem center;background-size:1rem,1rem}.was-validated .form-select:valid:focus,.form-select.is-valid:focus{border-color:#43a047;box-shadow:0 0 0 0 rgba(67,160,71,0.25)}.was-validated .form-check-input:valid,.form-check-input.is-valid{border-color:#43a047}.was-validated .form-check-input:valid:checked,.form-check-input.is-valid:checked{background-color:#43a047}.was-validated .form-check-input:valid:focus,.form-check-input.is-valid:focus{box-shadow:0 0 0 0 rgba(67,160,71,0.25)}.was-validated .form-check-input:valid ~ .form-check-label,.form-check-input.is-valid ~ .form-check-label{color:#43a047}.form-check-inline .form-check-input ~ .valid-feedback{margin-left:.5em}.was-validated .input-group .form-control:valid,.input-group .form-control.is-valid,.was-validated .input-group .form-select:valid,.input-group .form-select.is-valid{z-index:1}.was-validated .input-group .form-control:valid:focus,.input-group .form-control.is-valid:focus,.was-validated .input-group .form-select:valid:focus,.input-group .form-select.is-valid:focus{z-index:3}.invalid-feedback{display:none;width:100%;margin-top:.5rem;font-size:.7rem;color:#ff511f}.invalid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem 1rem;margin-top:.1rem;font-size:.65625rem;color:#000;background-color:#ff511f;border-radius:0}.was-validated :invalid ~ .invalid-feedback,.was-validated :invalid ~ .invalid-tooltip,.is-invalid ~ .invalid-feedback,.is-invalid ~ .invalid-tooltip{display:block}.was-validated .form-control:invalid,.form-control.is-invalid{border-color:#ff511f;padding-right:2rem;background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 12 12%27 width=%2712%27 height=%2712%27 fill=%27none%27 stroke=%27%23ff511f%27%3e%3ccircle cx=%276%27 cy=%276%27 r=%274.5%27/%3e%3cpath stroke-linejoin=%27round%27 d=%27M5.8 3.6h.4L6 6.5z%27/%3e%3ccircle cx=%276%27 cy=%278.2%27 r=%27.6%27 fill=%27%23ff511f%27 stroke=%27none%27/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right .5rem center;background-size:1rem 1rem}.was-validated .form-control:invalid:focus,.form-control.is-invalid:focus{border-color:#ff511f;box-shadow:0 0 0 0 rgba(255,81,31,0.25)}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{padding-right:2rem;background-position:top .5rem right .5rem}.was-validated .form-select:invalid,.form-select.is-invalid{border-color:#ff511f}.was-validated .form-select:invalid:not([multiple]):not([size]),.was-validated .form-select:invalid:not([multiple])[size="1"],.form-select.is-invalid:not([multiple]):not([size]),.form-select.is-invalid:not([multiple])[size="1"]{padding-right:3.5rem;background-image:var(--t42-select-indicator),url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 12 12%27 width=%2712%27 height=%2712%27 fill=%27none%27 stroke=%27%23ff511f%27%3e%3ccircle cx=%276%27 cy=%276%27 r=%274.5%27/%3e%3cpath stroke-linejoin=%27round%27 d=%27M5.8 3.6h.4L6 6.5z%27/%3e%3ccircle cx=%276%27 cy=%278.2%27 r=%27.6%27 fill=%27%23ff511f%27 stroke=%27none%27/%3e%3c/svg%3e");background-position:right 0.5rem center,right 1.75rem center;background-size:1rem,1rem}.was-validated .form-select:invalid:focus,.form-select.is-invalid:focus{border-color:#ff511f;box-shadow:0 0 0 0 rgba(255,81,31,0.25)}.was-validated .form-check-input:invalid,.form-check-input.is-invalid{border-color:#ff511f}.was-validated .form-check-input:invalid:checked,.form-check-input.is-invalid:checked{background-color:#ff511f}.was-validated .form-check-input:invalid:focus,.form-check-input.is-invalid:focus{box-shadow:0 0 0 0 rgba(255,81,31,0.25)}.was-validated .form-check-input:invalid ~ .form-check-label,.form-check-input.is-invalid ~ .form-check-label{color:#ff511f}.form-check-inline .form-check-input ~ .invalid-feedback{margin-left:.5em}.was-validated .input-group .form-control:invalid,.input-group .form-control.is-invalid,.was-validated .input-group .form-select:invalid,.input-group .form-select.is-invalid{z-index:2}.was-validated .input-group .form-control:invalid:focus,.input-group .form-control.is-invalid:focus,.was-validated .input-group .form-select:invalid:focus,.input-group .form-select.is-invalid:focus{z-index:3}input{background-color:var(--t42-input-bg)}input[type="number"]::-webkit-calendar-picker-indicator,input[type="datetime-local"]::-webkit-calendar-picker-indicator,input[type="month"]::-webkit-calendar-picker-indicator,input[type="week"]::-webkit-calendar-picker-indicator,input[type="time"]::-webkit-calendar-picker-indicator,input[type="date"]::-webkit-calendar-picker-indicator{background:transparent}input[type="number"]::-webkit-inner-spin-button,input[type="datetime-local"]::-webkit-inner-spin-button,input[type="month"]::-webkit-inner-spin-button,input[type="week"]::-webkit-inner-spin-button,input[type="time"]::-webkit-inner-spin-button,input[type="date"]::-webkit-inner-spin-button{appearance:none}input[type="color"],input[type="range"]{padding:0;border:0}form div[class^="col"]{position:relative}.form-check-label input[type="checkbox"],.form-check-label input[type="radio"]{margin-top:0.125rem;margin-left:-1.2rem;opacity:1}.form-check .form-check-input:disabled{opacity:0}.form-check-label{margin-bottom:0}.form-check-inline .form-check-label{padding-left:0.25rem}.form-check-inline input[type="radio"]:checked+label::after{left:-1rem}.form-control{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border;background-color:transparent}.form-control:disabled,.form-control.disabled,.form-control[readonly]{cursor:default;opacity:0.65}.form-control.is-valid,.form-control.is-invalid{border-color:var(--t42-color-opacity-10)}.form-control.is-valid:focus,.form-control.is-invalid:focus{border-color:var(--primary);box-shadow:none}.form-control[type="file"]{opacity:0}.form-text{color:var(--secondary)}.form-control-plaintext:focus{outline:0}select{background-image:var(--t42-select-indicator);background-repeat:no-repeat;background-position:right 0.5rem center;background-size:1rem;cursor:pointer;appearance:none}select[multiple]{padding:0;background-image:none}select[multiple] option{padding:0 0.875rem}select[multiple] option:checked{background-color:var(--primary)}select:disabled{border-color:transparent;cursor:default;opacity:0.65}textarea,textarea.form-control{min-height:90px;max-height:180px;padding-top:5px;padding-bottom:5px}textarea:disabled,textarea.form-control:disabled{border-color:transparent}input[type="range"]{width:100%;appearance:none}input[type="range"]:focus{background-color:transparent;outline:none}input[type="range"]:focus::-ms-fill-lower,input[type="range"]:focus::-ms-fill-upper{background:var(--primary)}input[type="range"]::-webkit-slider-runnable-track{width:100%;height:0.0625rem;border:0;border-radius:0;background:var(--t42-color-opacity-10);box-shadow:none;cursor:pointer}input[type="range"]::-webkit-slider-thumb{width:12px;height:12px;margin-top:-5px;border:0;border-radius:50%;background:var(--primary);box-shadow:none;cursor:pointer;appearance:none}input[type="range"]:focus::-webkit-slider-runnable-track{background:var(--t42-color-opacity-10)}input[type="range"]::-moz-range-track{width:100%;height:2px;border:0;border-radius:0;background:var(--t42-color-opacity-10);box-shadow:none;cursor:pointer}input[type="range"]::-moz-range-thumb{width:12px;height:12px;border:0;border-radius:50px;background:var(--primary);box-shadow:none;cursor:pointer}input[type="range"]::-ms-track{width:100%;height:2px;border-color:transparent;color:transparent;background:transparent;cursor:pointer}input[type="range"]::-ms-fill-lower,input[type="range"]::-ms-fill-upper{border:0;border-radius:0;background:var(--primary);box-shadow:none}input[type="range"]::-ms-thumb{width:12px;height:12px;border:0;border-radius:50px;background:var(--primary);box-shadow:none;cursor:pointer}input[type="checkbox"]{opacity:0}input[type="checkbox"]+label{position:relative;color:var(--t42-content-color-muted);cursor:pointer;user-select:none}input[type="checkbox"]+label::before{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, border-color;position:absolute;top:0.0625rem;left:-1.25rem;display:block;width:0.875rem;height:0.875rem;border:0.0625rem solid var(--t42-content-color-muted);border-radius:0;cursor:pointer;content:"";pointer-events:all}input[type="checkbox"]+label::after{position:absolute;top:0.125rem;left:-1.188rem;display:block;width:0.875rem;height:0.875rem;background-image:none;content:"";-webkit-mask-size:0.75rem;-webkit-mask-repeat:no-repeat;content:""}input[type="checkbox"].indeterminate+label::before,input[type="checkbox"]:indeterminate+label::before{border-color:var(--t42-color-opacity-30);background-color:var(--primary)}input[type="checkbox"].indeterminate+label::after,input[type="checkbox"]:indeterminate+label::after{top:0.375rem;left:-1.063rem;width:0.5rem;height:0.188rem;background-color:var(--white)}input[type="checkbox"]:disabled+label,input[type="checkbox"]:disabled+.form-check-label{color:var(--t42-content-color-disabled)}input[type="checkbox"]:checked.disabled+label,input[type="checkbox"]:checked:disabled+label,input[type="checkbox"]:indeterminate.disabled+label,input[type="checkbox"]:indeterminate:disabled+label,input[type="checkbox"].disabled+label,input[type="checkbox"]:disabled+label{color:var(--t42-content-color-disabled)}input[type="checkbox"]:checked.disabled+label::before,input[type="checkbox"]:checked:disabled+label::before,input[type="checkbox"]:indeterminate.disabled+label::before,input[type="checkbox"]:indeterminate:disabled+label::before,input[type="checkbox"].disabled+label::before,input[type="checkbox"]:disabled+label::before{border-color:transparent;background-color:var(--t42-color-opacity-10)}input[type="checkbox"]:checked+label::before{border-color:var(--t42-color-opacity-30);background-color:var(--primary)}input[type="checkbox"]:checked+label::after{background-color:var(--t42-link-color);-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M212.48599,435.14899c-11.60532,0.00003-21.16266-4.77866-28.672-14.336l-92.16-120.832 c-5.46133-8.19202-7.50933-17.06665-6.144-26.62399s5.80267-17.408,13.312-23.552s16.21333-8.53334,26.112-7.168 c9.89867,1.36533,17.92,6.14401,24.064,14.336l60.416,78.84799L360.966,93.13298c5.46133-8.192,12.79999-13.312,22.01599-15.36 s18.26132-0.68267,27.13599,4.096c8.19199,5.46133,13.31198,12.8,15.35999,22.016s0.68265,18.26133-4.09601,27.136l-179.2,286.71997 c-6.82668,10.9227-16.384,16.384-28.672,16.384L212.48599,435.14899z%27/%3E%3C/svg%3E")}input[type="radio"]{opacity:0}input[type="radio"]+label{position:relative;color:var(--t42-content-color-muted);cursor:pointer;user-select:none}input[type="radio"]+label::before{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, border;position:absolute;top:0.0625rem;left:-1.25rem;display:block;width:0.875rem;height:0.875rem;border:0.0625rem solid var(--t42-content-color-muted);border-radius:50%;cursor:pointer;content:"";pointer-events:all}input[type="radio"]+label::after{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, border;position:absolute;top:0.313rem;left:-1rem;display:block;width:0.375rem;height:0.375rem;border-radius:50%;color:var(--white);background-image:none;transform:scale(0);opacity:0;content:""}input[type="radio"]+label:focus{border-color:var(--primary)}input[type="radio"]:disabled+label,input[type="radio"]:disabled+.form-check-label{color:var(--t42-content-color-disabled)}input[type="radio"]:checked.disabled+label,input[type="radio"]:checked:disabled+label,input[type="radio"].disabled+label,input[type="radio"]:disabled+label{color:var(--t42-content-color-disabled)}input[type="radio"]:checked.disabled+label::before,input[type="radio"]:checked:disabled+label::before,input[type="radio"].disabled+label::before,input[type="radio"]:disabled+label::before{border-color:transparent;background-color:var(--t42-color-opacity-10)}input[type="radio"]:checked+label::before{border-color:var(--t42-color-opacity-30);background-color:var(--primary)}input[type="radio"]:checked+label::after{background-color:var(--white);transform:scale(1);opacity:1}.custom-control{padding-left:1.25rem}.custom-control .custom-control-input:checked ~ .custom-control-label::before{border-color:var(--t42-color-opacity-30)}.custom-select,.form-select{max-height:2rem;background-color:transparent;background-image:var(--t42-select-indicator);background-repeat:no-repeat;background-position:right 0.5rem center;background-size:1rem}.custom-select:focus,.custom-select option,.form-select:focus,.form-select option{background-color:var(--t42-input-bg)}.custom-select:disabled option,.form-select:disabled option{background-color:transparent}.custom-radio .custom-control-label{color:var(--t42-content-color-muted);user-select:none}.custom-radio .custom-control-label::after{background:none}.custom-radio .custom-control-input:checked ~ .custom-control-label::after{background-image:none}.custom-checkbox .custom-control-label{color:var(--t42-content-color-muted);user-select:none}.custom-checkbox .custom-control-label::after{background:none}.custom-checkbox .custom-control-input:checked ~ .custom-control-label::after{background-image:none}.custom-checkbox .custom-control-input:disabled .custom-control-label::after,.custom-checkbox .custom-control-input:disabled:checked ~ .custom-control-label::after,.custom-checkbox .custom-control-input:disabled:indeterminate ~ .custom-control-label::after{opacity:0.4}.custom-checkbox .custom-control-input:disabled ~ .custom-control-label::before{border-color:transparent}.switch{position:relative;display:inline-block;align-items:center;height:0.875rem;margin-bottom:0;padding-left:2rem;cursor:pointer}.switch.disabled{color:var(--t42-content-color-disabled)}.switch .slider{position:absolute;top:0;right:0;bottom:0;left:0;width:1.75rem;border:1px solid var(--t42-content-color-muted);cursor:pointer;transition:0.4s}.switch .slider::before{position:absolute;bottom:0.125rem;left:0.125rem;width:0.5rem;height:0.5rem;background-color:var(--t42-content-color-muted);transition:0.4s;content:""}.switch input{width:0;height:0;opacity:0}.switch input:checked+.slider{border:var(--t42-border);background-color:var(--primary)}.switch input:checked+.slider::before{background-color:var(--white);transform:translateX(0.875rem)}.switch input:focus+.slider{box-shadow:0 0 1px #2196f3}.switch input:disabled+.slider{border:var(--t42-border);background-color:var(--t42-color-opacity-10)}.switch input:disabled+.slider::before{background-color:var(--t42-color-opacity-20)}.input-group-prepend .input-group-text{justify-content:center;border-right:0}.input-group-append .input-group-text{justify-content:center;border-left:0}.input-group-append .custom-control,.input-group-prepend .custom-control{margin-bottom:0;padding-left:0.875rem}.input-group-append .custom-control-label,.input-group-prepend .custom-control-label{position:absolute;left:0;min-width:0.875rem;min-height:0.875rem}.input-group-append .custom-control-label::before,.input-group-prepend .custom-control-label::before{left:0}.input-group-append .custom-control-label::after,.input-group-prepend .custom-control-label::after{left:0.25rem}.input-group-append .custom-checkbox .custom-control-label::after,.input-group-prepend .custom-checkbox .custom-control-label::after{left:0.125rem}.custom-file{margin-bottom:1rem}.custom-file-input,.form-control[type="file"]{z-index:1}.custom-file-input:focus ~ .custom-file-label,.form-control[type="file"]:focus ~ .custom-file-label{background-color:var(--t42-input-bg)}.custom-file-label,.input-group-text{background-color:transparent}.custom-file-label::after,.input-group-text::after{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color;background-color:Rgba(--secondary, 0.05);cursor:pointer}.custom-file-label:hover::after,.input-group-text:hover::after{color:var(--white);background-color:var(--secondary)}.form-control[type="file"]+.input-group-text{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color,color;position:absolute;top:0;right:0;left:0;z-index:1;height:2rem;padding:0.375rem 0.875rem;border:var(--t42-border);color:var(--t42-content-color-muted)}.form-control[type="file"]+.input-group-text::after{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color,color;position:absolute;top:0;right:0;bottom:0;z-index:3;display:block;height:100%;padding:0.375rem 0.875rem;border-left:inherit;color:var(--t42-link-color);line-height:1.5;cursor:pointer;content:"Browse"}.form-control[type="file"]+.input-group-text:hover{background-color:var(--t42-input-bg)}.form-control[type="file"]+.input-group-text:hover::after{color:var(--white);background-color:var(--secondary)}.custom-switch{padding-left:2rem}.custom-switch .custom-control-label::before{left:-2rem}.custom-switch .custom-control-label::after{top:0.25rem;left:-1.813rem;width:0.5rem;height:0.5rem}.custom-switch .custom-control-input:checked ~ .custom-control-label::after{background-color:var(--white);content:""}.custom-switch .custom-control-input:not(:disabled):active ~ .custom-control-label::before{border-color:var(--t42-color-opacity-30);background-color:var(--primary)}.valid-feedback,.valid-tooltip,.invalid-feedback,.invalid-tooltip,.warning-feedback,.warning-tooltip{position:absolute;bottom:-1rem;width:calc(100% - 1.875rem);margin-top:0;overflow:hidden;color:var(--t42-content-color);font-size:.7rem;white-space:nowrap;text-overflow:ellipsis}.valid-tooltip,.invalid-tooltip,.warning-tooltip{color:var(--t42-content-color-muted)}.custom-radio label+div,.custom-checkbox label+div,.form-check label+div{width:calc(100% + 1.25rem);transform:translateX(-1.25rem)}.form-group{margin-bottom:1rem}label{margin-bottom:0.5rem}.form-row{display:flex;flex-wrap:wrap;margin-right:-0.5rem;margin-left:-0.5rem}.form-row>.col,.form-row>[class*="col-"]{padding-right:0.5rem;padding-left:0.5rem}.form-inline{display:flex;flex-flow:row wrap;align-items:center}.form-inline .form-check{width:100%}@media (min-width: 576px){.form-inline label{display:flex;align-items:center;justify-content:center;margin-bottom:0}.form-inline .form-group{display:flex;flex:0 0 auto;flex-flow:row wrap;align-items:center;margin-bottom:0}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-plaintext{display:inline-block}.form-inline .input-group,.form-inline .custom-select,.form-inline .form-select{width:auto}.form-inline .form-check{display:flex;align-items:center;justify-content:center;width:auto;padding-left:0}.form-inline .form-check-input{position:relative;flex-shrink:0;margin-top:0;margin-left:0}.form-inline .custom-control{align-items:center;justify-content:center}.form-inline .custom-control-label{margin-bottom:0}}/*! + * Bootstrap Grid v5.1.3 (https://getbootstrap.com/) + * Copyright 2011-2021 The Bootstrap Authors + * Copyright 2011-2021 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) + */:root{--bs-blue: #007be5;--bs-indigo: #6610f2;--bs-purple: #6f42c1;--bs-pink: #fd397a;--bs-red: #ff511f;--bs-orange: #fd7e14;--bs-yellow: #f9a825;--bs-green: #43a047;--bs-teal: #616161;--bs-cyan: #469eb9;--bs-white: #fff;--bs-gray: #6c757d;--bs-gray-dark: #343a40;--bs-gray-100: #f8f9fa;--bs-gray-200: #e9ecef;--bs-gray-300: #dee2e6;--bs-gray-400: #ced4da;--bs-gray-500: #adb5bd;--bs-gray-600: #6c757d;--bs-gray-700: #495057;--bs-gray-800: #343a40;--bs-gray-900: #212529;--bs-primary: #007be5;--bs-secondary: #616161;--bs-success: #43a047;--bs-info: #469eb9;--bs-warning: #f9a825;--bs-danger: #ff511f;--bs-light: #616161;--bs-dark: #616161;--bs-primary-rgb: 0,123,229;--bs-secondary-rgb: 97,97,97;--bs-success-rgb: 67,160,71;--bs-info-rgb: 70,158,185;--bs-warning-rgb: 249,168,37;--bs-danger-rgb: 255,81,31;--bs-light-rgb: 97,97,97;--bs-dark-rgb: 97,97,97;--bs-white-rgb: 255,255,255;--bs-black-rgb: 0,0,0;--bs-body-color-rgb: 33,37,41;--bs-body-bg-rgb: 255,255,255;--bs-font-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--bs-gradient: linear-gradient(180deg, rgba(255,255,255,0.15), rgba(255,255,255,0));--bs-body-font-family: Montserrat,Helvetica Neue,Arial,sans-serif;--bs-body-font-size: .75rem;--bs-body-font-weight: 400;--bs-body-line-height: 1.5;--bs-body-color: #212529;--bs-body-bg: #fff}.container,.container-fluid,.container-sm,.container-md,.container-lg,.container-xl,.container-xxl{width:100%;padding-right:var(--bs-gutter-x, .75rem);padding-left:var(--bs-gutter-x, .75rem);margin-right:auto;margin-left:auto}@media (min-width: 576px){.container,.container-sm{max-width:540px}}@media (min-width: 768px){.container,.container-sm,.container-md{max-width:720px}}@media (min-width: 992px){.container,.container-sm,.container-md,.container-lg{max-width:960px}}@media (min-width: 1200px){.container,.container-sm,.container-md,.container-lg,.container-xl{max-width:1140px}}@media (min-width: 1400px){.container,.container-sm,.container-md,.container-lg,.container-xl,.container-xxl{max-width:1320px}}.row{--bs-gutter-x: 1.5rem;--bs-gutter-y: 0;display:flex;flex-wrap:wrap;margin-top:calc(-1 * var(--bs-gutter-y));margin-right:calc(-.5 * var(--bs-gutter-x));margin-left:calc(-.5 * var(--bs-gutter-x))}.row>*{box-sizing:border-box;flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--bs-gutter-x) * .5);padding-left:calc(var(--bs-gutter-x) * .5);margin-top:var(--bs-gutter-y)}.col{flex:1 0 0%}.row-cols-auto>*{flex:0 0 auto;width:auto}.row-cols-1>*{flex:0 0 auto;width:100%}.row-cols-2>*{flex:0 0 auto;width:50%}.row-cols-3>*{flex:0 0 auto;width:33.33333%}.row-cols-4>*{flex:0 0 auto;width:25%}.row-cols-5>*{flex:0 0 auto;width:20%}.row-cols-6>*{flex:0 0 auto;width:16.66667%}.col-auto{flex:0 0 auto;width:auto}.col-1{flex:0 0 auto;width:8.33333%}.col-2{flex:0 0 auto;width:16.66667%}.col-3{flex:0 0 auto;width:25%}.col-4{flex:0 0 auto;width:33.33333%}.col-5{flex:0 0 auto;width:41.66667%}.col-6{flex:0 0 auto;width:50%}.col-7{flex:0 0 auto;width:58.33333%}.col-8{flex:0 0 auto;width:66.66667%}.col-9{flex:0 0 auto;width:75%}.col-10{flex:0 0 auto;width:83.33333%}.col-11{flex:0 0 auto;width:91.66667%}.col-12{flex:0 0 auto;width:100%}.offset-1{margin-left:8.33333%}.offset-2{margin-left:16.66667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.33333%}.offset-5{margin-left:41.66667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.33333%}.offset-8{margin-left:66.66667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.33333%}.offset-11{margin-left:91.66667%}.g-0,.gx-0{--bs-gutter-x: 0}.g-0,.gy-0{--bs-gutter-y: 0}.g-1,.gx-1{--bs-gutter-x: .25rem}.g-1,.gy-1{--bs-gutter-y: .25rem}.g-2,.gx-2{--bs-gutter-x: .5rem}.g-2,.gy-2{--bs-gutter-y: .5rem}.g-3,.gx-3{--bs-gutter-x: 1rem}.g-3,.gy-3{--bs-gutter-y: 1rem}.g-4,.gx-4{--bs-gutter-x: 1.5rem}.g-4,.gy-4{--bs-gutter-y: 1.5rem}.g-5,.gx-5{--bs-gutter-x: 3rem}.g-5,.gy-5{--bs-gutter-y: 3rem}@media (min-width: 576px){.col-sm{flex:1 0 0%}.row-cols-sm-auto>*{flex:0 0 auto;width:auto}.row-cols-sm-1>*{flex:0 0 auto;width:100%}.row-cols-sm-2>*{flex:0 0 auto;width:50%}.row-cols-sm-3>*{flex:0 0 auto;width:33.33333%}.row-cols-sm-4>*{flex:0 0 auto;width:25%}.row-cols-sm-5>*{flex:0 0 auto;width:20%}.row-cols-sm-6>*{flex:0 0 auto;width:16.66667%}.col-sm-auto{flex:0 0 auto;width:auto}.col-sm-1{flex:0 0 auto;width:8.33333%}.col-sm-2{flex:0 0 auto;width:16.66667%}.col-sm-3{flex:0 0 auto;width:25%}.col-sm-4{flex:0 0 auto;width:33.33333%}.col-sm-5{flex:0 0 auto;width:41.66667%}.col-sm-6{flex:0 0 auto;width:50%}.col-sm-7{flex:0 0 auto;width:58.33333%}.col-sm-8{flex:0 0 auto;width:66.66667%}.col-sm-9{flex:0 0 auto;width:75%}.col-sm-10{flex:0 0 auto;width:83.33333%}.col-sm-11{flex:0 0 auto;width:91.66667%}.col-sm-12{flex:0 0 auto;width:100%}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.33333%}.offset-sm-2{margin-left:16.66667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.33333%}.offset-sm-5{margin-left:41.66667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.33333%}.offset-sm-8{margin-left:66.66667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.33333%}.offset-sm-11{margin-left:91.66667%}.g-sm-0,.gx-sm-0{--bs-gutter-x: 0}.g-sm-0,.gy-sm-0{--bs-gutter-y: 0}.g-sm-1,.gx-sm-1{--bs-gutter-x: .25rem}.g-sm-1,.gy-sm-1{--bs-gutter-y: .25rem}.g-sm-2,.gx-sm-2{--bs-gutter-x: .5rem}.g-sm-2,.gy-sm-2{--bs-gutter-y: .5rem}.g-sm-3,.gx-sm-3{--bs-gutter-x: 1rem}.g-sm-3,.gy-sm-3{--bs-gutter-y: 1rem}.g-sm-4,.gx-sm-4{--bs-gutter-x: 1.5rem}.g-sm-4,.gy-sm-4{--bs-gutter-y: 1.5rem}.g-sm-5,.gx-sm-5{--bs-gutter-x: 3rem}.g-sm-5,.gy-sm-5{--bs-gutter-y: 3rem}}@media (min-width: 768px){.col-md{flex:1 0 0%}.row-cols-md-auto>*{flex:0 0 auto;width:auto}.row-cols-md-1>*{flex:0 0 auto;width:100%}.row-cols-md-2>*{flex:0 0 auto;width:50%}.row-cols-md-3>*{flex:0 0 auto;width:33.33333%}.row-cols-md-4>*{flex:0 0 auto;width:25%}.row-cols-md-5>*{flex:0 0 auto;width:20%}.row-cols-md-6>*{flex:0 0 auto;width:16.66667%}.col-md-auto{flex:0 0 auto;width:auto}.col-md-1{flex:0 0 auto;width:8.33333%}.col-md-2{flex:0 0 auto;width:16.66667%}.col-md-3{flex:0 0 auto;width:25%}.col-md-4{flex:0 0 auto;width:33.33333%}.col-md-5{flex:0 0 auto;width:41.66667%}.col-md-6{flex:0 0 auto;width:50%}.col-md-7{flex:0 0 auto;width:58.33333%}.col-md-8{flex:0 0 auto;width:66.66667%}.col-md-9{flex:0 0 auto;width:75%}.col-md-10{flex:0 0 auto;width:83.33333%}.col-md-11{flex:0 0 auto;width:91.66667%}.col-md-12{flex:0 0 auto;width:100%}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.33333%}.offset-md-2{margin-left:16.66667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.33333%}.offset-md-5{margin-left:41.66667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.33333%}.offset-md-8{margin-left:66.66667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.33333%}.offset-md-11{margin-left:91.66667%}.g-md-0,.gx-md-0{--bs-gutter-x: 0}.g-md-0,.gy-md-0{--bs-gutter-y: 0}.g-md-1,.gx-md-1{--bs-gutter-x: .25rem}.g-md-1,.gy-md-1{--bs-gutter-y: .25rem}.g-md-2,.gx-md-2{--bs-gutter-x: .5rem}.g-md-2,.gy-md-2{--bs-gutter-y: .5rem}.g-md-3,.gx-md-3{--bs-gutter-x: 1rem}.g-md-3,.gy-md-3{--bs-gutter-y: 1rem}.g-md-4,.gx-md-4{--bs-gutter-x: 1.5rem}.g-md-4,.gy-md-4{--bs-gutter-y: 1.5rem}.g-md-5,.gx-md-5{--bs-gutter-x: 3rem}.g-md-5,.gy-md-5{--bs-gutter-y: 3rem}}@media (min-width: 992px){.col-lg{flex:1 0 0%}.row-cols-lg-auto>*{flex:0 0 auto;width:auto}.row-cols-lg-1>*{flex:0 0 auto;width:100%}.row-cols-lg-2>*{flex:0 0 auto;width:50%}.row-cols-lg-3>*{flex:0 0 auto;width:33.33333%}.row-cols-lg-4>*{flex:0 0 auto;width:25%}.row-cols-lg-5>*{flex:0 0 auto;width:20%}.row-cols-lg-6>*{flex:0 0 auto;width:16.66667%}.col-lg-auto{flex:0 0 auto;width:auto}.col-lg-1{flex:0 0 auto;width:8.33333%}.col-lg-2{flex:0 0 auto;width:16.66667%}.col-lg-3{flex:0 0 auto;width:25%}.col-lg-4{flex:0 0 auto;width:33.33333%}.col-lg-5{flex:0 0 auto;width:41.66667%}.col-lg-6{flex:0 0 auto;width:50%}.col-lg-7{flex:0 0 auto;width:58.33333%}.col-lg-8{flex:0 0 auto;width:66.66667%}.col-lg-9{flex:0 0 auto;width:75%}.col-lg-10{flex:0 0 auto;width:83.33333%}.col-lg-11{flex:0 0 auto;width:91.66667%}.col-lg-12{flex:0 0 auto;width:100%}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.33333%}.offset-lg-2{margin-left:16.66667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.33333%}.offset-lg-5{margin-left:41.66667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.33333%}.offset-lg-8{margin-left:66.66667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.33333%}.offset-lg-11{margin-left:91.66667%}.g-lg-0,.gx-lg-0{--bs-gutter-x: 0}.g-lg-0,.gy-lg-0{--bs-gutter-y: 0}.g-lg-1,.gx-lg-1{--bs-gutter-x: .25rem}.g-lg-1,.gy-lg-1{--bs-gutter-y: .25rem}.g-lg-2,.gx-lg-2{--bs-gutter-x: .5rem}.g-lg-2,.gy-lg-2{--bs-gutter-y: .5rem}.g-lg-3,.gx-lg-3{--bs-gutter-x: 1rem}.g-lg-3,.gy-lg-3{--bs-gutter-y: 1rem}.g-lg-4,.gx-lg-4{--bs-gutter-x: 1.5rem}.g-lg-4,.gy-lg-4{--bs-gutter-y: 1.5rem}.g-lg-5,.gx-lg-5{--bs-gutter-x: 3rem}.g-lg-5,.gy-lg-5{--bs-gutter-y: 3rem}}@media (min-width: 1200px){.col-xl{flex:1 0 0%}.row-cols-xl-auto>*{flex:0 0 auto;width:auto}.row-cols-xl-1>*{flex:0 0 auto;width:100%}.row-cols-xl-2>*{flex:0 0 auto;width:50%}.row-cols-xl-3>*{flex:0 0 auto;width:33.33333%}.row-cols-xl-4>*{flex:0 0 auto;width:25%}.row-cols-xl-5>*{flex:0 0 auto;width:20%}.row-cols-xl-6>*{flex:0 0 auto;width:16.66667%}.col-xl-auto{flex:0 0 auto;width:auto}.col-xl-1{flex:0 0 auto;width:8.33333%}.col-xl-2{flex:0 0 auto;width:16.66667%}.col-xl-3{flex:0 0 auto;width:25%}.col-xl-4{flex:0 0 auto;width:33.33333%}.col-xl-5{flex:0 0 auto;width:41.66667%}.col-xl-6{flex:0 0 auto;width:50%}.col-xl-7{flex:0 0 auto;width:58.33333%}.col-xl-8{flex:0 0 auto;width:66.66667%}.col-xl-9{flex:0 0 auto;width:75%}.col-xl-10{flex:0 0 auto;width:83.33333%}.col-xl-11{flex:0 0 auto;width:91.66667%}.col-xl-12{flex:0 0 auto;width:100%}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.33333%}.offset-xl-2{margin-left:16.66667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.33333%}.offset-xl-5{margin-left:41.66667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.33333%}.offset-xl-8{margin-left:66.66667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.33333%}.offset-xl-11{margin-left:91.66667%}.g-xl-0,.gx-xl-0{--bs-gutter-x: 0}.g-xl-0,.gy-xl-0{--bs-gutter-y: 0}.g-xl-1,.gx-xl-1{--bs-gutter-x: .25rem}.g-xl-1,.gy-xl-1{--bs-gutter-y: .25rem}.g-xl-2,.gx-xl-2{--bs-gutter-x: .5rem}.g-xl-2,.gy-xl-2{--bs-gutter-y: .5rem}.g-xl-3,.gx-xl-3{--bs-gutter-x: 1rem}.g-xl-3,.gy-xl-3{--bs-gutter-y: 1rem}.g-xl-4,.gx-xl-4{--bs-gutter-x: 1.5rem}.g-xl-4,.gy-xl-4{--bs-gutter-y: 1.5rem}.g-xl-5,.gx-xl-5{--bs-gutter-x: 3rem}.g-xl-5,.gy-xl-5{--bs-gutter-y: 3rem}}@media (min-width: 1400px){.col-xxl{flex:1 0 0%}.row-cols-xxl-auto>*{flex:0 0 auto;width:auto}.row-cols-xxl-1>*{flex:0 0 auto;width:100%}.row-cols-xxl-2>*{flex:0 0 auto;width:50%}.row-cols-xxl-3>*{flex:0 0 auto;width:33.33333%}.row-cols-xxl-4>*{flex:0 0 auto;width:25%}.row-cols-xxl-5>*{flex:0 0 auto;width:20%}.row-cols-xxl-6>*{flex:0 0 auto;width:16.66667%}.col-xxl-auto{flex:0 0 auto;width:auto}.col-xxl-1{flex:0 0 auto;width:8.33333%}.col-xxl-2{flex:0 0 auto;width:16.66667%}.col-xxl-3{flex:0 0 auto;width:25%}.col-xxl-4{flex:0 0 auto;width:33.33333%}.col-xxl-5{flex:0 0 auto;width:41.66667%}.col-xxl-6{flex:0 0 auto;width:50%}.col-xxl-7{flex:0 0 auto;width:58.33333%}.col-xxl-8{flex:0 0 auto;width:66.66667%}.col-xxl-9{flex:0 0 auto;width:75%}.col-xxl-10{flex:0 0 auto;width:83.33333%}.col-xxl-11{flex:0 0 auto;width:91.66667%}.col-xxl-12{flex:0 0 auto;width:100%}.offset-xxl-0{margin-left:0}.offset-xxl-1{margin-left:8.33333%}.offset-xxl-2{margin-left:16.66667%}.offset-xxl-3{margin-left:25%}.offset-xxl-4{margin-left:33.33333%}.offset-xxl-5{margin-left:41.66667%}.offset-xxl-6{margin-left:50%}.offset-xxl-7{margin-left:58.33333%}.offset-xxl-8{margin-left:66.66667%}.offset-xxl-9{margin-left:75%}.offset-xxl-10{margin-left:83.33333%}.offset-xxl-11{margin-left:91.66667%}.g-xxl-0,.gx-xxl-0{--bs-gutter-x: 0}.g-xxl-0,.gy-xxl-0{--bs-gutter-y: 0}.g-xxl-1,.gx-xxl-1{--bs-gutter-x: .25rem}.g-xxl-1,.gy-xxl-1{--bs-gutter-y: .25rem}.g-xxl-2,.gx-xxl-2{--bs-gutter-x: .5rem}.g-xxl-2,.gy-xxl-2{--bs-gutter-y: .5rem}.g-xxl-3,.gx-xxl-3{--bs-gutter-x: 1rem}.g-xxl-3,.gy-xxl-3{--bs-gutter-y: 1rem}.g-xxl-4,.gx-xxl-4{--bs-gutter-x: 1.5rem}.g-xxl-4,.gy-xxl-4{--bs-gutter-y: 1.5rem}.g-xxl-5,.gx-xxl-5{--bs-gutter-x: 3rem}.g-xxl-5,.gy-xxl-5{--bs-gutter-y: 3rem}}.d-inline{display:inline !important}.d-inline-block{display:inline-block !important}.d-block{display:block !important}.d-grid{display:grid !important}.d-table{display:table !important}.d-table-row{display:table-row !important}.d-table-cell{display:table-cell !important}.d-flex{display:flex !important}.d-inline-flex{display:inline-flex !important}.d-none{display:none !important}.flex-fill{flex:1 1 auto !important}.flex-row{flex-direction:row !important}.flex-column{flex-direction:column !important}.flex-row-reverse{flex-direction:row-reverse !important}.flex-column-reverse{flex-direction:column-reverse !important}.flex-grow-0{flex-grow:0 !important}.flex-grow-1{flex-grow:1 !important}.flex-shrink-0{flex-shrink:0 !important}.flex-shrink-1{flex-shrink:1 !important}.flex-wrap{flex-wrap:wrap !important}.flex-nowrap{flex-wrap:nowrap !important}.flex-wrap-reverse{flex-wrap:wrap-reverse !important}.justify-content-start{justify-content:flex-start !important}.justify-content-end{justify-content:flex-end !important}.justify-content-center{justify-content:center !important}.justify-content-between{justify-content:space-between !important}.justify-content-around{justify-content:space-around !important}.justify-content-evenly{justify-content:space-evenly !important}.align-items-start{align-items:flex-start !important}.align-items-end{align-items:flex-end !important}.align-items-center{align-items:center !important}.align-items-baseline{align-items:baseline !important}.align-items-stretch{align-items:stretch !important}.align-content-start{align-content:flex-start !important}.align-content-end{align-content:flex-end !important}.align-content-center{align-content:center !important}.align-content-between{align-content:space-between !important}.align-content-around{align-content:space-around !important}.align-content-stretch{align-content:stretch !important}.align-self-auto{align-self:auto !important}.align-self-start{align-self:flex-start !important}.align-self-end{align-self:flex-end !important}.align-self-center{align-self:center !important}.align-self-baseline{align-self:baseline !important}.align-self-stretch{align-self:stretch !important}.order-first{order:-1 !important}.order-0{order:0 !important}.order-1{order:1 !important}.order-2{order:2 !important}.order-3{order:3 !important}.order-4{order:4 !important}.order-5{order:5 !important}.order-last{order:6 !important}.m-0{margin:0 !important}.m-1{margin:.25rem !important}.m-2{margin:.5rem !important}.m-3{margin:1rem !important}.m-4{margin:1.5rem !important}.m-5{margin:3rem !important}.m-auto{margin:auto !important}.mx-0{margin-right:0 !important;margin-left:0 !important}.mx-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-3{margin-right:1rem !important;margin-left:1rem !important}.mx-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-5{margin-right:3rem !important;margin-left:3rem !important}.mx-auto{margin-right:auto !important;margin-left:auto !important}.my-0{margin-top:0 !important;margin-bottom:0 !important}.my-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-0{margin-top:0 !important}.mt-1{margin-top:.25rem !important}.mt-2{margin-top:.5rem !important}.mt-3{margin-top:1rem !important}.mt-4{margin-top:1.5rem !important}.mt-5{margin-top:3rem !important}.mt-auto{margin-top:auto !important}.me-0{margin-right:0 !important}.me-1{margin-right:.25rem !important}.me-2{margin-right:.5rem !important}.me-3{margin-right:1rem !important}.me-4{margin-right:1.5rem !important}.me-5{margin-right:3rem !important}.me-auto{margin-right:auto !important}.mb-0{margin-bottom:0 !important}.mb-1{margin-bottom:.25rem !important}.mb-2{margin-bottom:.5rem !important}.mb-3{margin-bottom:1rem !important}.mb-4{margin-bottom:1.5rem !important}.mb-5{margin-bottom:3rem !important}.mb-auto{margin-bottom:auto !important}.ms-0{margin-left:0 !important}.ms-1{margin-left:.25rem !important}.ms-2{margin-left:.5rem !important}.ms-3{margin-left:1rem !important}.ms-4{margin-left:1.5rem !important}.ms-5{margin-left:3rem !important}.ms-auto{margin-left:auto !important}.p-0{padding:0 !important}.p-1{padding:.25rem !important}.p-2{padding:.5rem !important}.p-3{padding:1rem !important}.p-4{padding:1.5rem !important}.p-5{padding:3rem !important}.px-0{padding-right:0 !important;padding-left:0 !important}.px-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-3{padding-right:1rem !important;padding-left:1rem !important}.px-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-5{padding-right:3rem !important;padding-left:3rem !important}.py-0{padding-top:0 !important;padding-bottom:0 !important}.py-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-0{padding-top:0 !important}.pt-1{padding-top:.25rem !important}.pt-2{padding-top:.5rem !important}.pt-3{padding-top:1rem !important}.pt-4{padding-top:1.5rem !important}.pt-5{padding-top:3rem !important}.pe-0{padding-right:0 !important}.pe-1{padding-right:.25rem !important}.pe-2{padding-right:.5rem !important}.pe-3{padding-right:1rem !important}.pe-4{padding-right:1.5rem !important}.pe-5{padding-right:3rem !important}.pb-0{padding-bottom:0 !important}.pb-1{padding-bottom:.25rem !important}.pb-2{padding-bottom:.5rem !important}.pb-3{padding-bottom:1rem !important}.pb-4{padding-bottom:1.5rem !important}.pb-5{padding-bottom:3rem !important}.ps-0{padding-left:0 !important}.ps-1{padding-left:.25rem !important}.ps-2{padding-left:.5rem !important}.ps-3{padding-left:1rem !important}.ps-4{padding-left:1.5rem !important}.ps-5{padding-left:3rem !important}@media (min-width: 576px){.d-sm-inline{display:inline !important}.d-sm-inline-block{display:inline-block !important}.d-sm-block{display:block !important}.d-sm-grid{display:grid !important}.d-sm-table{display:table !important}.d-sm-table-row{display:table-row !important}.d-sm-table-cell{display:table-cell !important}.d-sm-flex{display:flex !important}.d-sm-inline-flex{display:inline-flex !important}.d-sm-none{display:none !important}.flex-sm-fill{flex:1 1 auto !important}.flex-sm-row{flex-direction:row !important}.flex-sm-column{flex-direction:column !important}.flex-sm-row-reverse{flex-direction:row-reverse !important}.flex-sm-column-reverse{flex-direction:column-reverse !important}.flex-sm-grow-0{flex-grow:0 !important}.flex-sm-grow-1{flex-grow:1 !important}.flex-sm-shrink-0{flex-shrink:0 !important}.flex-sm-shrink-1{flex-shrink:1 !important}.flex-sm-wrap{flex-wrap:wrap !important}.flex-sm-nowrap{flex-wrap:nowrap !important}.flex-sm-wrap-reverse{flex-wrap:wrap-reverse !important}.justify-content-sm-start{justify-content:flex-start !important}.justify-content-sm-end{justify-content:flex-end !important}.justify-content-sm-center{justify-content:center !important}.justify-content-sm-between{justify-content:space-between !important}.justify-content-sm-around{justify-content:space-around !important}.justify-content-sm-evenly{justify-content:space-evenly !important}.align-items-sm-start{align-items:flex-start !important}.align-items-sm-end{align-items:flex-end !important}.align-items-sm-center{align-items:center !important}.align-items-sm-baseline{align-items:baseline !important}.align-items-sm-stretch{align-items:stretch !important}.align-content-sm-start{align-content:flex-start !important}.align-content-sm-end{align-content:flex-end !important}.align-content-sm-center{align-content:center !important}.align-content-sm-between{align-content:space-between !important}.align-content-sm-around{align-content:space-around !important}.align-content-sm-stretch{align-content:stretch !important}.align-self-sm-auto{align-self:auto !important}.align-self-sm-start{align-self:flex-start !important}.align-self-sm-end{align-self:flex-end !important}.align-self-sm-center{align-self:center !important}.align-self-sm-baseline{align-self:baseline !important}.align-self-sm-stretch{align-self:stretch !important}.order-sm-first{order:-1 !important}.order-sm-0{order:0 !important}.order-sm-1{order:1 !important}.order-sm-2{order:2 !important}.order-sm-3{order:3 !important}.order-sm-4{order:4 !important}.order-sm-5{order:5 !important}.order-sm-last{order:6 !important}.m-sm-0{margin:0 !important}.m-sm-1{margin:.25rem !important}.m-sm-2{margin:.5rem !important}.m-sm-3{margin:1rem !important}.m-sm-4{margin:1.5rem !important}.m-sm-5{margin:3rem !important}.m-sm-auto{margin:auto !important}.mx-sm-0{margin-right:0 !important;margin-left:0 !important}.mx-sm-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-sm-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-sm-3{margin-right:1rem !important;margin-left:1rem !important}.mx-sm-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-sm-5{margin-right:3rem !important;margin-left:3rem !important}.mx-sm-auto{margin-right:auto !important;margin-left:auto !important}.my-sm-0{margin-top:0 !important;margin-bottom:0 !important}.my-sm-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-sm-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-sm-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-sm-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-sm-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-sm-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-sm-0{margin-top:0 !important}.mt-sm-1{margin-top:.25rem !important}.mt-sm-2{margin-top:.5rem !important}.mt-sm-3{margin-top:1rem !important}.mt-sm-4{margin-top:1.5rem !important}.mt-sm-5{margin-top:3rem !important}.mt-sm-auto{margin-top:auto !important}.me-sm-0{margin-right:0 !important}.me-sm-1{margin-right:.25rem !important}.me-sm-2{margin-right:.5rem !important}.me-sm-3{margin-right:1rem !important}.me-sm-4{margin-right:1.5rem !important}.me-sm-5{margin-right:3rem !important}.me-sm-auto{margin-right:auto !important}.mb-sm-0{margin-bottom:0 !important}.mb-sm-1{margin-bottom:.25rem !important}.mb-sm-2{margin-bottom:.5rem !important}.mb-sm-3{margin-bottom:1rem !important}.mb-sm-4{margin-bottom:1.5rem !important}.mb-sm-5{margin-bottom:3rem !important}.mb-sm-auto{margin-bottom:auto !important}.ms-sm-0{margin-left:0 !important}.ms-sm-1{margin-left:.25rem !important}.ms-sm-2{margin-left:.5rem !important}.ms-sm-3{margin-left:1rem !important}.ms-sm-4{margin-left:1.5rem !important}.ms-sm-5{margin-left:3rem !important}.ms-sm-auto{margin-left:auto !important}.p-sm-0{padding:0 !important}.p-sm-1{padding:.25rem !important}.p-sm-2{padding:.5rem !important}.p-sm-3{padding:1rem !important}.p-sm-4{padding:1.5rem !important}.p-sm-5{padding:3rem !important}.px-sm-0{padding-right:0 !important;padding-left:0 !important}.px-sm-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-sm-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-sm-3{padding-right:1rem !important;padding-left:1rem !important}.px-sm-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-sm-5{padding-right:3rem !important;padding-left:3rem !important}.py-sm-0{padding-top:0 !important;padding-bottom:0 !important}.py-sm-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-sm-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-sm-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-sm-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-sm-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-sm-0{padding-top:0 !important}.pt-sm-1{padding-top:.25rem !important}.pt-sm-2{padding-top:.5rem !important}.pt-sm-3{padding-top:1rem !important}.pt-sm-4{padding-top:1.5rem !important}.pt-sm-5{padding-top:3rem !important}.pe-sm-0{padding-right:0 !important}.pe-sm-1{padding-right:.25rem !important}.pe-sm-2{padding-right:.5rem !important}.pe-sm-3{padding-right:1rem !important}.pe-sm-4{padding-right:1.5rem !important}.pe-sm-5{padding-right:3rem !important}.pb-sm-0{padding-bottom:0 !important}.pb-sm-1{padding-bottom:.25rem !important}.pb-sm-2{padding-bottom:.5rem !important}.pb-sm-3{padding-bottom:1rem !important}.pb-sm-4{padding-bottom:1.5rem !important}.pb-sm-5{padding-bottom:3rem !important}.ps-sm-0{padding-left:0 !important}.ps-sm-1{padding-left:.25rem !important}.ps-sm-2{padding-left:.5rem !important}.ps-sm-3{padding-left:1rem !important}.ps-sm-4{padding-left:1.5rem !important}.ps-sm-5{padding-left:3rem !important}}@media (min-width: 768px){.d-md-inline{display:inline !important}.d-md-inline-block{display:inline-block !important}.d-md-block{display:block !important}.d-md-grid{display:grid !important}.d-md-table{display:table !important}.d-md-table-row{display:table-row !important}.d-md-table-cell{display:table-cell !important}.d-md-flex{display:flex !important}.d-md-inline-flex{display:inline-flex !important}.d-md-none{display:none !important}.flex-md-fill{flex:1 1 auto !important}.flex-md-row{flex-direction:row !important}.flex-md-column{flex-direction:column !important}.flex-md-row-reverse{flex-direction:row-reverse !important}.flex-md-column-reverse{flex-direction:column-reverse !important}.flex-md-grow-0{flex-grow:0 !important}.flex-md-grow-1{flex-grow:1 !important}.flex-md-shrink-0{flex-shrink:0 !important}.flex-md-shrink-1{flex-shrink:1 !important}.flex-md-wrap{flex-wrap:wrap !important}.flex-md-nowrap{flex-wrap:nowrap !important}.flex-md-wrap-reverse{flex-wrap:wrap-reverse !important}.justify-content-md-start{justify-content:flex-start !important}.justify-content-md-end{justify-content:flex-end !important}.justify-content-md-center{justify-content:center !important}.justify-content-md-between{justify-content:space-between !important}.justify-content-md-around{justify-content:space-around !important}.justify-content-md-evenly{justify-content:space-evenly !important}.align-items-md-start{align-items:flex-start !important}.align-items-md-end{align-items:flex-end !important}.align-items-md-center{align-items:center !important}.align-items-md-baseline{align-items:baseline !important}.align-items-md-stretch{align-items:stretch !important}.align-content-md-start{align-content:flex-start !important}.align-content-md-end{align-content:flex-end !important}.align-content-md-center{align-content:center !important}.align-content-md-between{align-content:space-between !important}.align-content-md-around{align-content:space-around !important}.align-content-md-stretch{align-content:stretch !important}.align-self-md-auto{align-self:auto !important}.align-self-md-start{align-self:flex-start !important}.align-self-md-end{align-self:flex-end !important}.align-self-md-center{align-self:center !important}.align-self-md-baseline{align-self:baseline !important}.align-self-md-stretch{align-self:stretch !important}.order-md-first{order:-1 !important}.order-md-0{order:0 !important}.order-md-1{order:1 !important}.order-md-2{order:2 !important}.order-md-3{order:3 !important}.order-md-4{order:4 !important}.order-md-5{order:5 !important}.order-md-last{order:6 !important}.m-md-0{margin:0 !important}.m-md-1{margin:.25rem !important}.m-md-2{margin:.5rem !important}.m-md-3{margin:1rem !important}.m-md-4{margin:1.5rem !important}.m-md-5{margin:3rem !important}.m-md-auto{margin:auto !important}.mx-md-0{margin-right:0 !important;margin-left:0 !important}.mx-md-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-md-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-md-3{margin-right:1rem !important;margin-left:1rem !important}.mx-md-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-md-5{margin-right:3rem !important;margin-left:3rem !important}.mx-md-auto{margin-right:auto !important;margin-left:auto !important}.my-md-0{margin-top:0 !important;margin-bottom:0 !important}.my-md-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-md-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-md-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-md-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-md-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-md-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-md-0{margin-top:0 !important}.mt-md-1{margin-top:.25rem !important}.mt-md-2{margin-top:.5rem !important}.mt-md-3{margin-top:1rem !important}.mt-md-4{margin-top:1.5rem !important}.mt-md-5{margin-top:3rem !important}.mt-md-auto{margin-top:auto !important}.me-md-0{margin-right:0 !important}.me-md-1{margin-right:.25rem !important}.me-md-2{margin-right:.5rem !important}.me-md-3{margin-right:1rem !important}.me-md-4{margin-right:1.5rem !important}.me-md-5{margin-right:3rem !important}.me-md-auto{margin-right:auto !important}.mb-md-0{margin-bottom:0 !important}.mb-md-1{margin-bottom:.25rem !important}.mb-md-2{margin-bottom:.5rem !important}.mb-md-3{margin-bottom:1rem !important}.mb-md-4{margin-bottom:1.5rem !important}.mb-md-5{margin-bottom:3rem !important}.mb-md-auto{margin-bottom:auto !important}.ms-md-0{margin-left:0 !important}.ms-md-1{margin-left:.25rem !important}.ms-md-2{margin-left:.5rem !important}.ms-md-3{margin-left:1rem !important}.ms-md-4{margin-left:1.5rem !important}.ms-md-5{margin-left:3rem !important}.ms-md-auto{margin-left:auto !important}.p-md-0{padding:0 !important}.p-md-1{padding:.25rem !important}.p-md-2{padding:.5rem !important}.p-md-3{padding:1rem !important}.p-md-4{padding:1.5rem !important}.p-md-5{padding:3rem !important}.px-md-0{padding-right:0 !important;padding-left:0 !important}.px-md-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-md-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-md-3{padding-right:1rem !important;padding-left:1rem !important}.px-md-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-md-5{padding-right:3rem !important;padding-left:3rem !important}.py-md-0{padding-top:0 !important;padding-bottom:0 !important}.py-md-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-md-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-md-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-md-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-md-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-md-0{padding-top:0 !important}.pt-md-1{padding-top:.25rem !important}.pt-md-2{padding-top:.5rem !important}.pt-md-3{padding-top:1rem !important}.pt-md-4{padding-top:1.5rem !important}.pt-md-5{padding-top:3rem !important}.pe-md-0{padding-right:0 !important}.pe-md-1{padding-right:.25rem !important}.pe-md-2{padding-right:.5rem !important}.pe-md-3{padding-right:1rem !important}.pe-md-4{padding-right:1.5rem !important}.pe-md-5{padding-right:3rem !important}.pb-md-0{padding-bottom:0 !important}.pb-md-1{padding-bottom:.25rem !important}.pb-md-2{padding-bottom:.5rem !important}.pb-md-3{padding-bottom:1rem !important}.pb-md-4{padding-bottom:1.5rem !important}.pb-md-5{padding-bottom:3rem !important}.ps-md-0{padding-left:0 !important}.ps-md-1{padding-left:.25rem !important}.ps-md-2{padding-left:.5rem !important}.ps-md-3{padding-left:1rem !important}.ps-md-4{padding-left:1.5rem !important}.ps-md-5{padding-left:3rem !important}}@media (min-width: 992px){.d-lg-inline{display:inline !important}.d-lg-inline-block{display:inline-block !important}.d-lg-block{display:block !important}.d-lg-grid{display:grid !important}.d-lg-table{display:table !important}.d-lg-table-row{display:table-row !important}.d-lg-table-cell{display:table-cell !important}.d-lg-flex{display:flex !important}.d-lg-inline-flex{display:inline-flex !important}.d-lg-none{display:none !important}.flex-lg-fill{flex:1 1 auto !important}.flex-lg-row{flex-direction:row !important}.flex-lg-column{flex-direction:column !important}.flex-lg-row-reverse{flex-direction:row-reverse !important}.flex-lg-column-reverse{flex-direction:column-reverse !important}.flex-lg-grow-0{flex-grow:0 !important}.flex-lg-grow-1{flex-grow:1 !important}.flex-lg-shrink-0{flex-shrink:0 !important}.flex-lg-shrink-1{flex-shrink:1 !important}.flex-lg-wrap{flex-wrap:wrap !important}.flex-lg-nowrap{flex-wrap:nowrap !important}.flex-lg-wrap-reverse{flex-wrap:wrap-reverse !important}.justify-content-lg-start{justify-content:flex-start !important}.justify-content-lg-end{justify-content:flex-end !important}.justify-content-lg-center{justify-content:center !important}.justify-content-lg-between{justify-content:space-between !important}.justify-content-lg-around{justify-content:space-around !important}.justify-content-lg-evenly{justify-content:space-evenly !important}.align-items-lg-start{align-items:flex-start !important}.align-items-lg-end{align-items:flex-end !important}.align-items-lg-center{align-items:center !important}.align-items-lg-baseline{align-items:baseline !important}.align-items-lg-stretch{align-items:stretch !important}.align-content-lg-start{align-content:flex-start !important}.align-content-lg-end{align-content:flex-end !important}.align-content-lg-center{align-content:center !important}.align-content-lg-between{align-content:space-between !important}.align-content-lg-around{align-content:space-around !important}.align-content-lg-stretch{align-content:stretch !important}.align-self-lg-auto{align-self:auto !important}.align-self-lg-start{align-self:flex-start !important}.align-self-lg-end{align-self:flex-end !important}.align-self-lg-center{align-self:center !important}.align-self-lg-baseline{align-self:baseline !important}.align-self-lg-stretch{align-self:stretch !important}.order-lg-first{order:-1 !important}.order-lg-0{order:0 !important}.order-lg-1{order:1 !important}.order-lg-2{order:2 !important}.order-lg-3{order:3 !important}.order-lg-4{order:4 !important}.order-lg-5{order:5 !important}.order-lg-last{order:6 !important}.m-lg-0{margin:0 !important}.m-lg-1{margin:.25rem !important}.m-lg-2{margin:.5rem !important}.m-lg-3{margin:1rem !important}.m-lg-4{margin:1.5rem !important}.m-lg-5{margin:3rem !important}.m-lg-auto{margin:auto !important}.mx-lg-0{margin-right:0 !important;margin-left:0 !important}.mx-lg-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-lg-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-lg-3{margin-right:1rem !important;margin-left:1rem !important}.mx-lg-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-lg-5{margin-right:3rem !important;margin-left:3rem !important}.mx-lg-auto{margin-right:auto !important;margin-left:auto !important}.my-lg-0{margin-top:0 !important;margin-bottom:0 !important}.my-lg-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-lg-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-lg-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-lg-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-lg-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-lg-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-lg-0{margin-top:0 !important}.mt-lg-1{margin-top:.25rem !important}.mt-lg-2{margin-top:.5rem !important}.mt-lg-3{margin-top:1rem !important}.mt-lg-4{margin-top:1.5rem !important}.mt-lg-5{margin-top:3rem !important}.mt-lg-auto{margin-top:auto !important}.me-lg-0{margin-right:0 !important}.me-lg-1{margin-right:.25rem !important}.me-lg-2{margin-right:.5rem !important}.me-lg-3{margin-right:1rem !important}.me-lg-4{margin-right:1.5rem !important}.me-lg-5{margin-right:3rem !important}.me-lg-auto{margin-right:auto !important}.mb-lg-0{margin-bottom:0 !important}.mb-lg-1{margin-bottom:.25rem !important}.mb-lg-2{margin-bottom:.5rem !important}.mb-lg-3{margin-bottom:1rem !important}.mb-lg-4{margin-bottom:1.5rem !important}.mb-lg-5{margin-bottom:3rem !important}.mb-lg-auto{margin-bottom:auto !important}.ms-lg-0{margin-left:0 !important}.ms-lg-1{margin-left:.25rem !important}.ms-lg-2{margin-left:.5rem !important}.ms-lg-3{margin-left:1rem !important}.ms-lg-4{margin-left:1.5rem !important}.ms-lg-5{margin-left:3rem !important}.ms-lg-auto{margin-left:auto !important}.p-lg-0{padding:0 !important}.p-lg-1{padding:.25rem !important}.p-lg-2{padding:.5rem !important}.p-lg-3{padding:1rem !important}.p-lg-4{padding:1.5rem !important}.p-lg-5{padding:3rem !important}.px-lg-0{padding-right:0 !important;padding-left:0 !important}.px-lg-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-lg-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-lg-3{padding-right:1rem !important;padding-left:1rem !important}.px-lg-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-lg-5{padding-right:3rem !important;padding-left:3rem !important}.py-lg-0{padding-top:0 !important;padding-bottom:0 !important}.py-lg-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-lg-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-lg-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-lg-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-lg-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-lg-0{padding-top:0 !important}.pt-lg-1{padding-top:.25rem !important}.pt-lg-2{padding-top:.5rem !important}.pt-lg-3{padding-top:1rem !important}.pt-lg-4{padding-top:1.5rem !important}.pt-lg-5{padding-top:3rem !important}.pe-lg-0{padding-right:0 !important}.pe-lg-1{padding-right:.25rem !important}.pe-lg-2{padding-right:.5rem !important}.pe-lg-3{padding-right:1rem !important}.pe-lg-4{padding-right:1.5rem !important}.pe-lg-5{padding-right:3rem !important}.pb-lg-0{padding-bottom:0 !important}.pb-lg-1{padding-bottom:.25rem !important}.pb-lg-2{padding-bottom:.5rem !important}.pb-lg-3{padding-bottom:1rem !important}.pb-lg-4{padding-bottom:1.5rem !important}.pb-lg-5{padding-bottom:3rem !important}.ps-lg-0{padding-left:0 !important}.ps-lg-1{padding-left:.25rem !important}.ps-lg-2{padding-left:.5rem !important}.ps-lg-3{padding-left:1rem !important}.ps-lg-4{padding-left:1.5rem !important}.ps-lg-5{padding-left:3rem !important}}@media (min-width: 1200px){.d-xl-inline{display:inline !important}.d-xl-inline-block{display:inline-block !important}.d-xl-block{display:block !important}.d-xl-grid{display:grid !important}.d-xl-table{display:table !important}.d-xl-table-row{display:table-row !important}.d-xl-table-cell{display:table-cell !important}.d-xl-flex{display:flex !important}.d-xl-inline-flex{display:inline-flex !important}.d-xl-none{display:none !important}.flex-xl-fill{flex:1 1 auto !important}.flex-xl-row{flex-direction:row !important}.flex-xl-column{flex-direction:column !important}.flex-xl-row-reverse{flex-direction:row-reverse !important}.flex-xl-column-reverse{flex-direction:column-reverse !important}.flex-xl-grow-0{flex-grow:0 !important}.flex-xl-grow-1{flex-grow:1 !important}.flex-xl-shrink-0{flex-shrink:0 !important}.flex-xl-shrink-1{flex-shrink:1 !important}.flex-xl-wrap{flex-wrap:wrap !important}.flex-xl-nowrap{flex-wrap:nowrap !important}.flex-xl-wrap-reverse{flex-wrap:wrap-reverse !important}.justify-content-xl-start{justify-content:flex-start !important}.justify-content-xl-end{justify-content:flex-end !important}.justify-content-xl-center{justify-content:center !important}.justify-content-xl-between{justify-content:space-between !important}.justify-content-xl-around{justify-content:space-around !important}.justify-content-xl-evenly{justify-content:space-evenly !important}.align-items-xl-start{align-items:flex-start !important}.align-items-xl-end{align-items:flex-end !important}.align-items-xl-center{align-items:center !important}.align-items-xl-baseline{align-items:baseline !important}.align-items-xl-stretch{align-items:stretch !important}.align-content-xl-start{align-content:flex-start !important}.align-content-xl-end{align-content:flex-end !important}.align-content-xl-center{align-content:center !important}.align-content-xl-between{align-content:space-between !important}.align-content-xl-around{align-content:space-around !important}.align-content-xl-stretch{align-content:stretch !important}.align-self-xl-auto{align-self:auto !important}.align-self-xl-start{align-self:flex-start !important}.align-self-xl-end{align-self:flex-end !important}.align-self-xl-center{align-self:center !important}.align-self-xl-baseline{align-self:baseline !important}.align-self-xl-stretch{align-self:stretch !important}.order-xl-first{order:-1 !important}.order-xl-0{order:0 !important}.order-xl-1{order:1 !important}.order-xl-2{order:2 !important}.order-xl-3{order:3 !important}.order-xl-4{order:4 !important}.order-xl-5{order:5 !important}.order-xl-last{order:6 !important}.m-xl-0{margin:0 !important}.m-xl-1{margin:.25rem !important}.m-xl-2{margin:.5rem !important}.m-xl-3{margin:1rem !important}.m-xl-4{margin:1.5rem !important}.m-xl-5{margin:3rem !important}.m-xl-auto{margin:auto !important}.mx-xl-0{margin-right:0 !important;margin-left:0 !important}.mx-xl-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-xl-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-xl-3{margin-right:1rem !important;margin-left:1rem !important}.mx-xl-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-xl-5{margin-right:3rem !important;margin-left:3rem !important}.mx-xl-auto{margin-right:auto !important;margin-left:auto !important}.my-xl-0{margin-top:0 !important;margin-bottom:0 !important}.my-xl-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-xl-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-xl-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-xl-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-xl-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-xl-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-xl-0{margin-top:0 !important}.mt-xl-1{margin-top:.25rem !important}.mt-xl-2{margin-top:.5rem !important}.mt-xl-3{margin-top:1rem !important}.mt-xl-4{margin-top:1.5rem !important}.mt-xl-5{margin-top:3rem !important}.mt-xl-auto{margin-top:auto !important}.me-xl-0{margin-right:0 !important}.me-xl-1{margin-right:.25rem !important}.me-xl-2{margin-right:.5rem !important}.me-xl-3{margin-right:1rem !important}.me-xl-4{margin-right:1.5rem !important}.me-xl-5{margin-right:3rem !important}.me-xl-auto{margin-right:auto !important}.mb-xl-0{margin-bottom:0 !important}.mb-xl-1{margin-bottom:.25rem !important}.mb-xl-2{margin-bottom:.5rem !important}.mb-xl-3{margin-bottom:1rem !important}.mb-xl-4{margin-bottom:1.5rem !important}.mb-xl-5{margin-bottom:3rem !important}.mb-xl-auto{margin-bottom:auto !important}.ms-xl-0{margin-left:0 !important}.ms-xl-1{margin-left:.25rem !important}.ms-xl-2{margin-left:.5rem !important}.ms-xl-3{margin-left:1rem !important}.ms-xl-4{margin-left:1.5rem !important}.ms-xl-5{margin-left:3rem !important}.ms-xl-auto{margin-left:auto !important}.p-xl-0{padding:0 !important}.p-xl-1{padding:.25rem !important}.p-xl-2{padding:.5rem !important}.p-xl-3{padding:1rem !important}.p-xl-4{padding:1.5rem !important}.p-xl-5{padding:3rem !important}.px-xl-0{padding-right:0 !important;padding-left:0 !important}.px-xl-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-xl-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-xl-3{padding-right:1rem !important;padding-left:1rem !important}.px-xl-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-xl-5{padding-right:3rem !important;padding-left:3rem !important}.py-xl-0{padding-top:0 !important;padding-bottom:0 !important}.py-xl-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-xl-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-xl-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-xl-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-xl-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-xl-0{padding-top:0 !important}.pt-xl-1{padding-top:.25rem !important}.pt-xl-2{padding-top:.5rem !important}.pt-xl-3{padding-top:1rem !important}.pt-xl-4{padding-top:1.5rem !important}.pt-xl-5{padding-top:3rem !important}.pe-xl-0{padding-right:0 !important}.pe-xl-1{padding-right:.25rem !important}.pe-xl-2{padding-right:.5rem !important}.pe-xl-3{padding-right:1rem !important}.pe-xl-4{padding-right:1.5rem !important}.pe-xl-5{padding-right:3rem !important}.pb-xl-0{padding-bottom:0 !important}.pb-xl-1{padding-bottom:.25rem !important}.pb-xl-2{padding-bottom:.5rem !important}.pb-xl-3{padding-bottom:1rem !important}.pb-xl-4{padding-bottom:1.5rem !important}.pb-xl-5{padding-bottom:3rem !important}.ps-xl-0{padding-left:0 !important}.ps-xl-1{padding-left:.25rem !important}.ps-xl-2{padding-left:.5rem !important}.ps-xl-3{padding-left:1rem !important}.ps-xl-4{padding-left:1.5rem !important}.ps-xl-5{padding-left:3rem !important}}@media (min-width: 1400px){.d-xxl-inline{display:inline !important}.d-xxl-inline-block{display:inline-block !important}.d-xxl-block{display:block !important}.d-xxl-grid{display:grid !important}.d-xxl-table{display:table !important}.d-xxl-table-row{display:table-row !important}.d-xxl-table-cell{display:table-cell !important}.d-xxl-flex{display:flex !important}.d-xxl-inline-flex{display:inline-flex !important}.d-xxl-none{display:none !important}.flex-xxl-fill{flex:1 1 auto !important}.flex-xxl-row{flex-direction:row !important}.flex-xxl-column{flex-direction:column !important}.flex-xxl-row-reverse{flex-direction:row-reverse !important}.flex-xxl-column-reverse{flex-direction:column-reverse !important}.flex-xxl-grow-0{flex-grow:0 !important}.flex-xxl-grow-1{flex-grow:1 !important}.flex-xxl-shrink-0{flex-shrink:0 !important}.flex-xxl-shrink-1{flex-shrink:1 !important}.flex-xxl-wrap{flex-wrap:wrap !important}.flex-xxl-nowrap{flex-wrap:nowrap !important}.flex-xxl-wrap-reverse{flex-wrap:wrap-reverse !important}.justify-content-xxl-start{justify-content:flex-start !important}.justify-content-xxl-end{justify-content:flex-end !important}.justify-content-xxl-center{justify-content:center !important}.justify-content-xxl-between{justify-content:space-between !important}.justify-content-xxl-around{justify-content:space-around !important}.justify-content-xxl-evenly{justify-content:space-evenly !important}.align-items-xxl-start{align-items:flex-start !important}.align-items-xxl-end{align-items:flex-end !important}.align-items-xxl-center{align-items:center !important}.align-items-xxl-baseline{align-items:baseline !important}.align-items-xxl-stretch{align-items:stretch !important}.align-content-xxl-start{align-content:flex-start !important}.align-content-xxl-end{align-content:flex-end !important}.align-content-xxl-center{align-content:center !important}.align-content-xxl-between{align-content:space-between !important}.align-content-xxl-around{align-content:space-around !important}.align-content-xxl-stretch{align-content:stretch !important}.align-self-xxl-auto{align-self:auto !important}.align-self-xxl-start{align-self:flex-start !important}.align-self-xxl-end{align-self:flex-end !important}.align-self-xxl-center{align-self:center !important}.align-self-xxl-baseline{align-self:baseline !important}.align-self-xxl-stretch{align-self:stretch !important}.order-xxl-first{order:-1 !important}.order-xxl-0{order:0 !important}.order-xxl-1{order:1 !important}.order-xxl-2{order:2 !important}.order-xxl-3{order:3 !important}.order-xxl-4{order:4 !important}.order-xxl-5{order:5 !important}.order-xxl-last{order:6 !important}.m-xxl-0{margin:0 !important}.m-xxl-1{margin:.25rem !important}.m-xxl-2{margin:.5rem !important}.m-xxl-3{margin:1rem !important}.m-xxl-4{margin:1.5rem !important}.m-xxl-5{margin:3rem !important}.m-xxl-auto{margin:auto !important}.mx-xxl-0{margin-right:0 !important;margin-left:0 !important}.mx-xxl-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-xxl-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-xxl-3{margin-right:1rem !important;margin-left:1rem !important}.mx-xxl-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-xxl-5{margin-right:3rem !important;margin-left:3rem !important}.mx-xxl-auto{margin-right:auto !important;margin-left:auto !important}.my-xxl-0{margin-top:0 !important;margin-bottom:0 !important}.my-xxl-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-xxl-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-xxl-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-xxl-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-xxl-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-xxl-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-xxl-0{margin-top:0 !important}.mt-xxl-1{margin-top:.25rem !important}.mt-xxl-2{margin-top:.5rem !important}.mt-xxl-3{margin-top:1rem !important}.mt-xxl-4{margin-top:1.5rem !important}.mt-xxl-5{margin-top:3rem !important}.mt-xxl-auto{margin-top:auto !important}.me-xxl-0{margin-right:0 !important}.me-xxl-1{margin-right:.25rem !important}.me-xxl-2{margin-right:.5rem !important}.me-xxl-3{margin-right:1rem !important}.me-xxl-4{margin-right:1.5rem !important}.me-xxl-5{margin-right:3rem !important}.me-xxl-auto{margin-right:auto !important}.mb-xxl-0{margin-bottom:0 !important}.mb-xxl-1{margin-bottom:.25rem !important}.mb-xxl-2{margin-bottom:.5rem !important}.mb-xxl-3{margin-bottom:1rem !important}.mb-xxl-4{margin-bottom:1.5rem !important}.mb-xxl-5{margin-bottom:3rem !important}.mb-xxl-auto{margin-bottom:auto !important}.ms-xxl-0{margin-left:0 !important}.ms-xxl-1{margin-left:.25rem !important}.ms-xxl-2{margin-left:.5rem !important}.ms-xxl-3{margin-left:1rem !important}.ms-xxl-4{margin-left:1.5rem !important}.ms-xxl-5{margin-left:3rem !important}.ms-xxl-auto{margin-left:auto !important}.p-xxl-0{padding:0 !important}.p-xxl-1{padding:.25rem !important}.p-xxl-2{padding:.5rem !important}.p-xxl-3{padding:1rem !important}.p-xxl-4{padding:1.5rem !important}.p-xxl-5{padding:3rem !important}.px-xxl-0{padding-right:0 !important;padding-left:0 !important}.px-xxl-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-xxl-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-xxl-3{padding-right:1rem !important;padding-left:1rem !important}.px-xxl-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-xxl-5{padding-right:3rem !important;padding-left:3rem !important}.py-xxl-0{padding-top:0 !important;padding-bottom:0 !important}.py-xxl-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-xxl-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-xxl-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-xxl-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-xxl-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-xxl-0{padding-top:0 !important}.pt-xxl-1{padding-top:.25rem !important}.pt-xxl-2{padding-top:.5rem !important}.pt-xxl-3{padding-top:1rem !important}.pt-xxl-4{padding-top:1.5rem !important}.pt-xxl-5{padding-top:3rem !important}.pe-xxl-0{padding-right:0 !important}.pe-xxl-1{padding-right:.25rem !important}.pe-xxl-2{padding-right:.5rem !important}.pe-xxl-3{padding-right:1rem !important}.pe-xxl-4{padding-right:1.5rem !important}.pe-xxl-5{padding-right:3rem !important}.pb-xxl-0{padding-bottom:0 !important}.pb-xxl-1{padding-bottom:.25rem !important}.pb-xxl-2{padding-bottom:.5rem !important}.pb-xxl-3{padding-bottom:1rem !important}.pb-xxl-4{padding-bottom:1.5rem !important}.pb-xxl-5{padding-bottom:3rem !important}.ps-xxl-0{padding-left:0 !important}.ps-xxl-1{padding-left:.25rem !important}.ps-xxl-2{padding-left:.5rem !important}.ps-xxl-3{padding-left:1rem !important}.ps-xxl-4{padding-left:1.5rem !important}.ps-xxl-5{padding-left:3rem !important}}@media print{.d-print-inline{display:inline !important}.d-print-inline-block{display:inline-block !important}.d-print-block{display:block !important}.d-print-grid{display:grid !important}.d-print-table{display:table !important}.d-print-table-row{display:table-row !important}.d-print-table-cell{display:table-cell !important}.d-print-flex{display:flex !important}.d-print-inline-flex{display:inline-flex !important}.d-print-none{display:none !important}}.row{--bs-gutter-x: 1.875rem}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:#fff;border:1px solid #dee2e6;border-radius:.25rem;max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:.875em;color:#6c757d}.list-group{display:flex;flex-direction:column;padding-left:0;margin-bottom:0;border-radius:0}.list-group-numbered{list-style-type:none;counter-reset:section}.list-group-numbered>li::before{content:counters(section, ".") ". ";counter-increment:section}.list-group-item-action{width:100%;color:var(--t42-content-color);text-align:inherit}.list-group-item-action:hover,.list-group-item-action:focus{z-index:1;color:var(--t42-link-hover-color);text-decoration:none;background-color:var(--t42-link-hover-bg)}.list-group-item-action:active{color:var(--t42-link-hover-color);background-color:var(--t42-link-active-bg)}.list-group-item{position:relative;display:block;padding:.75rem 1.25rem;color:inherit;text-decoration:none;background-color:Rgb(var(--t42-bg-mid));border:1px solid rgba(0,0,0,0)}.list-group-item:first-child{border-top-left-radius:inherit;border-top-right-radius:inherit}.list-group-item:last-child{border-bottom-right-radius:inherit;border-bottom-left-radius:inherit}.list-group-item.disabled,.list-group-item:disabled{color:var(--t42-content-color-disabled);pointer-events:none;background-color:rgba(0,0,0,0)}.list-group-item.active{z-index:2;color:var(--t42-link-hover-color);background-color:var(--t42-link-active-bg);border-color:rgba(0,0,0,0)}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{margin-top:-1px;border-top-width:1px}.list-group-horizontal{flex-direction:row}.list-group-horizontal>.list-group-item:first-child{border-bottom-left-radius:0;border-top-right-radius:0}.list-group-horizontal>.list-group-item:last-child{border-top-right-radius:0;border-bottom-left-radius:0}.list-group-horizontal>.list-group-item.active{margin-top:0}.list-group-horizontal>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}@media (min-width: 576px){.list-group-horizontal-sm{flex-direction:row}.list-group-horizontal-sm>.list-group-item:first-child{border-bottom-left-radius:0;border-top-right-radius:0}.list-group-horizontal-sm>.list-group-item:last-child{border-top-right-radius:0;border-bottom-left-radius:0}.list-group-horizontal-sm>.list-group-item.active{margin-top:0}.list-group-horizontal-sm>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-sm>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width: 768px){.list-group-horizontal-md{flex-direction:row}.list-group-horizontal-md>.list-group-item:first-child{border-bottom-left-radius:0;border-top-right-radius:0}.list-group-horizontal-md>.list-group-item:last-child{border-top-right-radius:0;border-bottom-left-radius:0}.list-group-horizontal-md>.list-group-item.active{margin-top:0}.list-group-horizontal-md>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-md>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width: 992px){.list-group-horizontal-lg{flex-direction:row}.list-group-horizontal-lg>.list-group-item:first-child{border-bottom-left-radius:0;border-top-right-radius:0}.list-group-horizontal-lg>.list-group-item:last-child{border-top-right-radius:0;border-bottom-left-radius:0}.list-group-horizontal-lg>.list-group-item.active{margin-top:0}.list-group-horizontal-lg>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-lg>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width: 1200px){.list-group-horizontal-xl{flex-direction:row}.list-group-horizontal-xl>.list-group-item:first-child{border-bottom-left-radius:0;border-top-right-radius:0}.list-group-horizontal-xl>.list-group-item:last-child{border-top-right-radius:0;border-bottom-left-radius:0}.list-group-horizontal-xl>.list-group-item.active{margin-top:0}.list-group-horizontal-xl>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-xl>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width: 1400px){.list-group-horizontal-xxl{flex-direction:row}.list-group-horizontal-xxl>.list-group-item:first-child{border-bottom-left-radius:0;border-top-right-radius:0}.list-group-horizontal-xxl>.list-group-item:last-child{border-top-right-radius:0;border-bottom-left-radius:0}.list-group-horizontal-xxl>.list-group-item.active{margin-top:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}.list-group-flush{border-radius:0}.list-group-flush>.list-group-item{border-width:0 0 1px}.list-group-flush>.list-group-item:last-child{border-bottom-width:0}.list-group-item-primary{color:#004a89;background-color:#cce5fa}.list-group-item-primary.list-group-item-action:hover,.list-group-item-primary.list-group-item-action:focus{color:#004a89;background-color:#b8cee1}.list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#004a89;border-color:#004a89}.list-group-item-secondary{color:#3a3a3a;background-color:#dfdfdf}.list-group-item-secondary.list-group-item-action:hover,.list-group-item-secondary.list-group-item-action:focus{color:#3a3a3a;background-color:#c9c9c9}.list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#3a3a3a;border-color:#3a3a3a}.list-group-item-success{color:#28602b;background-color:#d9ecda}.list-group-item-success.list-group-item-action:hover,.list-group-item-success.list-group-item-action:focus{color:#28602b;background-color:#c3d4c4}.list-group-item-success.list-group-item-action.active{color:#fff;background-color:#28602b;border-color:#28602b}.list-group-item-info{color:#2a5f6f;background-color:#daecf1}.list-group-item-info.list-group-item-action:hover,.list-group-item-info.list-group-item-action:focus{color:#2a5f6f;background-color:#c4d4d9}.list-group-item-info.list-group-item-action.active{color:#fff;background-color:#2a5f6f;border-color:#2a5f6f}.list-group-item-warning{color:#64430f;background-color:#feeed3}.list-group-item-warning.list-group-item-action:hover,.list-group-item-warning.list-group-item-action:focus{color:#64430f;background-color:#e5d6be}.list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#64430f;border-color:#64430f}.list-group-item-danger{color:#993113;background-color:#ffdcd2}.list-group-item-danger.list-group-item-action:hover,.list-group-item-danger.list-group-item-action:focus{color:#993113;background-color:#e6c6bd}.list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#993113;border-color:#993113}.list-group-item-light{color:#3a3a3a;background-color:#dfdfdf}.list-group-item-light.list-group-item-action:hover,.list-group-item-light.list-group-item-action:focus{color:#3a3a3a;background-color:#c9c9c9}.list-group-item-light.list-group-item-action.active{color:#fff;background-color:#3a3a3a;border-color:#3a3a3a}.list-group-item-dark{color:#3a3a3a;background-color:#dfdfdf}.list-group-item-dark.list-group-item-action:hover,.list-group-item-dark.list-group-item-action:focus{color:#3a3a3a;background-color:#c9c9c9}.list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#3a3a3a;border-color:#3a3a3a}.list-unstyled{padding-left:0;list-style:none}.list-group{box-shadow:var(--t42-shadow)}.list-group-item{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:color;margin-bottom:0;border:0;border-bottom:var(--t42-border);backdrop-filter:var(--backdrop-filter)}.list-group-item:last-child{border-bottom:transparent}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{margin-top:0;border-top-width:0}.list-group-item-action{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background,color;transition-duration:0.25s}.list-group-item-action:hover,.list-group-item-action:focus{background-color:var(--t42-list-group-hover-bg-special)}.list-group-item-action.active:hover{background-color:var(--t42-color-opacity-05)}.modal{position:fixed;top:0;left:0;z-index:1055;display:none;width:100%;height:100%;overflow-x:hidden;overflow-y:auto;outline:0}.modal-dialog{position:relative;width:auto;margin:.5rem;pointer-events:none}.modal.fade .modal-dialog{transition:transform 0.3s ease-out;transform:translate(0, -50px)}@media (prefers-reduced-motion: reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{transform:none}.modal.modal-static .modal-dialog{transform:scale(1.02)}.modal-dialog-scrollable{height:calc(100% - 1rem)}.modal-dialog-scrollable .modal-content{max-height:100%;overflow:hidden}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{display:flex;align-items:center;min-height:calc(100% - 1rem)}.modal-content{position:relative;display:flex;flex-direction:column;width:100%;pointer-events:auto;background-color:var(--t42-modal-bg);background-clip:padding-box;border:.0625rem solid var(--t42-color-opacity-10);border-radius:0;outline:0}.modal-backdrop{position:fixed;top:0;left:0;z-index:1050;width:100vw;height:100vh;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:.5}.modal-header{display:flex;flex-shrink:0;align-items:center;justify-content:space-between;padding:1rem 1rem;border-bottom:.0625rem solid rgba(0,0,0,0);border-top-left-radius:0;border-top-right-radius:0}.modal-header .btn-close{padding:.5rem .5rem;margin:-.5rem -.5rem -.5rem auto}.modal-title{margin-bottom:0;line-height:1.5}.modal-body{position:relative;flex:1 1 auto;padding:1rem}.modal-footer{display:flex;flex-wrap:wrap;flex-shrink:0;align-items:center;justify-content:flex-end;padding:.75rem;border-top:.0625rem solid rgba(0,0,0,0);border-bottom-right-radius:0;border-bottom-left-radius:0}.modal-footer>*{margin:.25rem}@media (min-width: 576px){.modal-dialog{max-width:500px;margin:1.75rem auto}.modal-dialog-scrollable{height:calc(100% - 3.5rem)}.modal-dialog-centered{min-height:calc(100% - 3.5rem)}.modal-sm{max-width:300px}}@media (min-width: 992px){.modal-lg,.modal-xl{max-width:800px}}@media (min-width: 1200px){.modal-xl{max-width:1140px}}.modal-fullscreen{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen .modal-header{border-radius:0}.modal-fullscreen .modal-body{overflow-y:auto}.modal-fullscreen .modal-footer{border-radius:0}@media (max-width: 575.98px){.modal-fullscreen-sm-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-sm-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-sm-down .modal-header{border-radius:0}.modal-fullscreen-sm-down .modal-body{overflow-y:auto}.modal-fullscreen-sm-down .modal-footer{border-radius:0}}@media (max-width: 767.98px){.modal-fullscreen-md-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-md-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-md-down .modal-header{border-radius:0}.modal-fullscreen-md-down .modal-body{overflow-y:auto}.modal-fullscreen-md-down .modal-footer{border-radius:0}}@media (max-width: 991.98px){.modal-fullscreen-lg-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-lg-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-lg-down .modal-header{border-radius:0}.modal-fullscreen-lg-down .modal-body{overflow-y:auto}.modal-fullscreen-lg-down .modal-footer{border-radius:0}}@media (max-width: 1199.98px){.modal-fullscreen-xl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xl-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-xl-down .modal-header{border-radius:0}.modal-fullscreen-xl-down .modal-body{overflow-y:auto}.modal-fullscreen-xl-down .modal-footer{border-radius:0}}@media (max-width: 1399.98px){.modal-fullscreen-xxl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xxl-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-xxl-down .modal-header{border-radius:0}.modal-fullscreen-xxl-down .modal-body{overflow-y:auto}.modal-fullscreen-xxl-down .modal-footer{border-radius:0}}.modal{backdrop-filter:var(--backdrop-filter)}.modal .btn-close{font-size:1.25rem;background-size:0.75rem;filter:var(--filter-close)}.modal-content{border-top:0;background:linear-gradient(to bottom right, Rgba(var(--t42-bg-light), 0.75) 0%, Rgba(var(--t42-bg-dark), 0.75) 100%);box-shadow:var(--t42-shadow)}.modal-content::before{display:block;height:0.0625rem;background:linear-gradient(90deg, #007be5 0%, rgba(0,123,229,0.5) 100%);content:""}.modal-body{padding:0 1rem}.modal-body p:last-child{margin-bottom:0}.modal-sm .modal-footer{flex-direction:column}.modal-sm .modal-footer .btn{width:100%}.modal-sm .modal-footer .btn:not(:last-of-type){margin-bottom:0.5rem}.modal-fill-in{background-color:Rgba(var(--t42-bg-light), 0.75)}.modal-fill-in.modal-dialog{display:flex;flex-flow:column nowrap;align-content:center;align-items:center;justify-content:center;width:auto;max-width:100%;height:100%;margin:0 auto}.modal-fill-in .modal-content{display:flex;max-width:600px;border-color:transparent;background:transparent;background-color:transparent;box-shadow:none;backdrop-filter:none;pointer-events:auto}.modal-fill-in .modal-content::before{display:none}.modal-fill-in::before{position:fixed;top:0;right:0;left:0;display:block;height:0.0625rem;background:linear-gradient(90deg, #007be5 0%, rgba(0,123,229,0.5) 100%);content:""}.modal-fill-in.modal-lg .modal-content{max-width:800px}.modal-fill-in.modal-sm .modal-content{max-width:300px}.nav{display:flex;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:.45rem 1rem;color:var(--t42-link-color);text-decoration:none;transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.nav-link{transition:none}}.nav-link:hover,.nav-link:focus{color:var(--t42-link-hover-color)}.nav-link.disabled{color:var(--t42-content-color-disabled);pointer-events:none;cursor:default}.nav-tabs{border-bottom:.0625rem solid var(--t42-color-opacity-10)}.nav-tabs .nav-link{margin-bottom:-.0625rem;background:none;border:.0625rem solid transparent;border-top-left-radius:0;border-top-right-radius:0}.nav-tabs .nav-link:hover,.nav-tabs .nav-link:focus{border-color:transparent transparent var(--t42-color-opacity-10);isolation:isolate}.nav-tabs .nav-link.disabled{color:var(--t42-content-color-disabled);background-color:transparent;border-color:transparent}.nav-tabs .nav-link.active,.nav-tabs .nav-item.show .nav-link{color:var(--t42-link-hover-color);background-color:var(--t42-link-active-bg);border-color:transparent transparent #007be5}.nav-tabs .dropdown-menu{margin-top:-.0625rem;border-top-left-radius:0;border-top-right-radius:0}.nav-pills .nav-link{background:none;border:0;border-radius:.25rem}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:var(--t42-link-hover-color);background-color:var(--t42-link-active-bg)}.nav-fill>.nav-link,.nav-fill .nav-item{flex:1 1 auto;text-align:center}.nav-justified>.nav-link,.nav-justified .nav-item{flex-basis:0;flex-grow:1;text-align:center}.nav-fill .nav-item .nav-link,.nav-justified .nav-item .nav-link{width:100%}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-link{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, border-color, color;margin-right:3px;border:.0625rem solid transparent}.nav-link:not(.disabled):not(:disabled):focus,.nav-link:not(.disabled):not(:disabled):active,.nav-link:not(.disabled):not(:disabled).active,.nav-link:not(.disabled):not(:disabled):hover{border-color:var(--t42-color-opacity-10);color:var(--t42-link-color);background-color:var(--t42-link-hover-bg)}.nav-link.dropdown-toggle::after{right:-0.125rem}.navbar-nav .nav-item{bottom:-1px}.navbar-nav .nav-item .nav-link{border-bottom:0}.navbar-nav .nav-item:not(.disabled):not(:disabled):focus .nav-link,.navbar-nav .nav-item:not(.disabled):not(:disabled):active .nav-link,.navbar-nav .nav-item:not(.disabled):not(:disabled).active .nav-link,.navbar-nav .nav-item:not(.disabled):not(:disabled):hover .nav-link{border-color:var(--t42-color-opacity-10)}.nav.flex-column .nav-link{margin-bottom:3px}.nav-tabs .nav-link{position:relative;display:flex;align-items:center;height:2rem}.nav-tabs .nav-link::before{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:height;position:absolute;bottom:-2px;left:-1px;width:calc(100% + 2px);height:0;background-color:var(--primary);content:""}.nav-tabs .nav-link.active::before{height:3px}.nav-tabs .nav-link.active:hover::before{height:0}.nav-tabs .nav-link .btn-close{width:0.5rem;height:0.5rem}.nav-tabs .nav-item{margin-right:0}.nav-tabs .dropdown.show .dropdown-toggle{border-color:transparent}.nav-tabs.flex-column .nav-link.active:hover::before{width:0}.nav-tabs.flex-column .nav-link::before{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:width;top:-1px;width:0;height:100%;margin-left:0;background-color:var(--primary);content:""}.nav-tabs.flex-column .nav-link.active::before{width:3px;height:calc(100% + 2px)}.nav-pills .nav-link{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;width:100%;padding:0.25rem 1rem;border:1px solid transparent;border-radius:1rem}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{position:relative;border-color:transparent}.nav-pills .nav-item{margin-right:3px}.nav-pills .nav-item:last-child{margin-right:0}.nav-pills .nav-link.active:not(.dropdown-toggle),.nav-pills .show>.nav-link:not(.dropdown-toggle){padding:0.25rem 1.75rem 0.25rem 1rem}.nav-pills .nav-link.active:not(.dropdown-toggle)::before,.nav-pills .show>.nav-link:not(.dropdown-toggle)::before{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:right;position:absolute;top:50%;right:10px;width:8px;height:8px;border-radius:50%;background-color:var(--primary);transform:translateY(-50%);content:""}.nav-pills .nav-link.active:not(.dropdown-toggle):hover::before,.nav-pills .show>.nav-link:not(.dropdown-toggle):hover::before{right:-10px}.nav-justified .nav-item .nav-link::before{right:1px;left:-1px;margin-left:0}.tab-content{padding-top:0.5rem}.nav-action-buttons .nav-link{position:relative;padding:0.45rem 1.5rem 0.45rem 1rem}.nav-action-buttons .icon-cancel::before{display:block;width:1rem;height:1rem;background-color:var(--t42-content-color);content:"";-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M366.854,336.384c6.14398,6.14398,9.216,13.48267,9.216,22.01599s-3.07202,15.87198-9.216,22.01599 c-6.14398,5.46133-13.48267,8.19202-22.01599,8.19199c-8.53333,0.00003-15.87201-2.73065-22.01602-8.19199l-67.584-77.82401 l-67.584,77.82401c-6.144,5.46133-13.48267,8.19202-22.01601,8.19199c-8.53333,0.00003-15.87199-2.73065-22.01599-8.19199 c-5.46133-6.14401-8.192-13.48267-8.192-22.01599s2.73067-15.87201,8.192-22.01599l70.65599-79.87201l-70.65601-80.896 c-5.46132-6.144-8.19199-13.48268-8.19199-22.01601c0-8.53334,2.73067-15.87201,8.19199-22.01601 c6.14401-5.46133,13.48267-8.19199,22.01601-8.192c8.53334,0.00001,15.87201,2.73067,22.01601,8.192l67.584,77.82401 l67.584-77.82401c6.14401-5.46133,13.4827-8.19199,22.01602-8.192c8.53333,0.00001,15.87201,2.73067,22.01599,8.192 c6.14398,6.144,9.216,13.48267,9.216,22.01601c0,8.53333-3.07202,15.87201-9.216,22.01601l-70.65601,80.896L366.854,336.384z%27/%3E%3C/svg%3E")}.navbar{position:relative;display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;padding-top:0;padding-right:.875rem;padding-bottom:0;padding-left:.875rem}.navbar>.container,.navbar>.container-fluid,.navbar>.container-sm,.navbar>.container-md,.navbar>.container-lg,.navbar>.container-xl,.navbar>.container-xxl{display:flex;flex-wrap:inherit;align-items:center;justify-content:space-between}.navbar-brand{padding-top:.075rem;padding-bottom:.075rem;margin-right:1rem;font-size:1.25rem;text-decoration:none;white-space:nowrap}.navbar-nav{display:flex;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-nav .dropdown-menu{position:static}.navbar-text{padding-top:.45rem;padding-bottom:.45rem}.navbar-collapse{flex-basis:100%;flex-grow:1;align-items:center}.navbar-toggler{padding:0 0;font-size:.9375rem;line-height:1;background-color:transparent;border:1px solid transparent;border-radius:0;transition:box-shadow 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.navbar-toggler{transition:none}}.navbar-toggler:hover{text-decoration:none}.navbar-toggler:focus{text-decoration:none;outline:0;box-shadow:0 0 0 0}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;background-repeat:no-repeat;background-position:center;background-size:100%}.navbar-nav-scroll{max-height:var(--bs-scroll-height, 75vh);overflow-y:auto}@media (min-width: 576px){.navbar-expand-sm{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-sm .navbar-nav{flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm .navbar-nav-scroll{overflow:visible}.navbar-expand-sm .navbar-collapse{display:flex !important;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}.navbar-expand-sm .offcanvas-header{display:none}.navbar-expand-sm .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;visibility:visible !important;background-color:transparent;border-right:0;border-left:0;transition:none;transform:none}.navbar-expand-sm .offcanvas-top,.navbar-expand-sm .offcanvas-bottom{height:auto;border-top:0;border-bottom:0}.navbar-expand-sm .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width: 768px){.navbar-expand-md{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-md .navbar-nav{flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-md .navbar-nav-scroll{overflow:visible}.navbar-expand-md .navbar-collapse{display:flex !important;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}.navbar-expand-md .offcanvas-header{display:none}.navbar-expand-md .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;visibility:visible !important;background-color:transparent;border-right:0;border-left:0;transition:none;transform:none}.navbar-expand-md .offcanvas-top,.navbar-expand-md .offcanvas-bottom{height:auto;border-top:0;border-bottom:0}.navbar-expand-md .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width: 992px){.navbar-expand-lg{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-lg .navbar-nav{flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-lg .navbar-nav-scroll{overflow:visible}.navbar-expand-lg .navbar-collapse{display:flex !important;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}.navbar-expand-lg .offcanvas-header{display:none}.navbar-expand-lg .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;visibility:visible !important;background-color:transparent;border-right:0;border-left:0;transition:none;transform:none}.navbar-expand-lg .offcanvas-top,.navbar-expand-lg .offcanvas-bottom{height:auto;border-top:0;border-bottom:0}.navbar-expand-lg .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width: 1200px){.navbar-expand-xl{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-xl .navbar-nav{flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xl .navbar-nav-scroll{overflow:visible}.navbar-expand-xl .navbar-collapse{display:flex !important;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}.navbar-expand-xl .offcanvas-header{display:none}.navbar-expand-xl .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;visibility:visible !important;background-color:transparent;border-right:0;border-left:0;transition:none;transform:none}.navbar-expand-xl .offcanvas-top,.navbar-expand-xl .offcanvas-bottom{height:auto;border-top:0;border-bottom:0}.navbar-expand-xl .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width: 1400px){.navbar-expand-xxl{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-xxl .navbar-nav{flex-direction:row}.navbar-expand-xxl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xxl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xxl .navbar-nav-scroll{overflow:visible}.navbar-expand-xxl .navbar-collapse{display:flex !important;flex-basis:auto}.navbar-expand-xxl .navbar-toggler{display:none}.navbar-expand-xxl .offcanvas-header{display:none}.navbar-expand-xxl .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;visibility:visible !important;background-color:transparent;border-right:0;border-left:0;transition:none;transform:none}.navbar-expand-xxl .offcanvas-top,.navbar-expand-xxl .offcanvas-bottom{height:auto;border-top:0;border-bottom:0}.navbar-expand-xxl .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}.navbar-expand{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand .navbar-nav{flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand .navbar-nav-scroll{overflow:visible}.navbar-expand .navbar-collapse{display:flex !important;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-expand .offcanvas-header{display:none}.navbar-expand .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;visibility:visible !important;background-color:transparent;border-right:0;border-left:0;transition:none;transform:none}.navbar-expand .offcanvas-top,.navbar-expand .offcanvas-bottom{height:auto;border-top:0;border-bottom:0}.navbar-expand .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}.navbar-light .navbar-brand{color:var(--t42-link-color)}.navbar-light .navbar-brand:hover,.navbar-light .navbar-brand:focus{color:var(--t42-link-hover-color)}.navbar-light .navbar-nav .nav-link{color:var(--t42-link-color)}.navbar-light .navbar-nav .nav-link:hover,.navbar-light .navbar-nav .nav-link:focus{color:var(--t42-link-hover-color)}.navbar-light .navbar-nav .nav-link.disabled{color:var(--t42-content-color-disabled)}.navbar-light .navbar-nav .show>.nav-link,.navbar-light .navbar-nav .nav-link.active{color:var(--t42-link-hover-color)}.navbar-light .navbar-toggler{color:var(--t42-link-color);border-color:rgba(0,0,0,0.1)}.navbar-light .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 30 30%27%3e%3cpath stroke=%27var%28--t42-link-color%29%27 stroke-linecap=%27round%27 stroke-miterlimit=%2710%27 stroke-width=%272%27 d=%27M4 7h22M4 15h22M4 23h22%27/%3e%3c/svg%3e")}.navbar-light .navbar-text{color:var(--t42-link-color)}.navbar-light .navbar-text a,.navbar-light .navbar-text a:hover,.navbar-light .navbar-text a:focus{color:var(--t42-link-hover-color)}.navbar-dark .navbar-brand{color:var(--t42-link-color)}.navbar-dark .navbar-brand:hover,.navbar-dark .navbar-brand:focus{color:var(--t42-link-hover-color)}.navbar-dark .navbar-nav .nav-link{color:var(--t42-link-color)}.navbar-dark .navbar-nav .nav-link:hover,.navbar-dark .navbar-nav .nav-link:focus{color:var(--t42-link-hover-color)}.navbar-dark .navbar-nav .nav-link.disabled{color:var(--t42-content-color-disabled)}.navbar-dark .navbar-nav .show>.nav-link,.navbar-dark .navbar-nav .nav-link.active{color:var(--t42-link-hover-color)}.navbar-dark .navbar-toggler{color:var(--t42-link-color);border-color:rgba(255,255,255,0.1)}.navbar-dark .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 30 30%27%3e%3cpath stroke=%27var%28--t42-link-color%29%27 stroke-linecap=%27round%27 stroke-miterlimit=%2710%27 stroke-width=%272%27 d=%27M4 7h22M4 15h22M4 23h22%27/%3e%3c/svg%3e")}.navbar-dark .navbar-text{color:var(--t42-link-color)}.navbar-dark .navbar-text a,.navbar-dark .navbar-text a:hover,.navbar-dark .navbar-text a:focus{color:var(--t42-link-hover-color)}.navbar{border-bottom:var(--t42-border);background-color:Rgba(var(--t42-bg-mid), 0.75);backdrop-filter:var(--backdrop-filter)}.navbar-dark{background-color:Rgba(var(--t42-bg-dark), 0.75)}.navbar-light{background-color:Rgba(var(--t42-bg-light), 0.75)}.navbar .nav-item{position:relative}.navbar .nav-item.show:focus .nav-link:not(.disabled):not(:disabled),.navbar .nav-item.show:active .nav-link:not(.disabled):not(:disabled),.navbar .nav-item.show.active .nav-link:not(.disabled):not(:disabled),.navbar .nav-item:not(.disabled):not(:disabled):focus .nav-link:not(.disabled):not(:disabled),.navbar .nav-item:not(.disabled):not(:disabled):active .nav-link:not(.disabled):not(:disabled),.navbar .nav-item:not(.disabled):not(:disabled).active .nav-link:not(.disabled):not(:disabled){color:var(--t42-link-color);background-color:var(--t42-color-opacity-10)}.navbar .nav-item.show:hover .nav-link:not(.disabled):not(:disabled),.navbar .nav-item:not(.disabled):not(:disabled):hover .nav-link:not(.disabled):not(:disabled){color:var(--t42-link-color);background-color:var(--t42-color-opacity-05)}.navbar .nav-link{padding-right:.875rem;padding-left:.875rem}.navbar .btn-group{height:100%;padding-left:.875rem;border-left:var(--t42-border)}.pagination{display:flex;padding-left:0;list-style:none}.page-link{position:relative;display:block;color:var(--t42-content-color);text-decoration:none;background-color:rgba(0,0,0,0);border:0 solid rgba(0,0,0,0);transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.page-link{transition:none}}.page-link:hover{z-index:2;color:var(--t42-link-hover-color);background-color:var(--t42-link-hover-bg);border-color:#dee2e6}.page-link:focus{z-index:3;color:var(--t42-link-hover-color);background-color:rgba(0,0,0,0);outline:0;box-shadow:0 0 0 0 rgba(0,123,229,0.25)}.page-item:not(:first-child) .page-link{margin-left:0}.page-item.active .page-link{z-index:3;color:var(--white);background-color:var(--primary);border-color:var(--primary)}.page-item.disabled .page-link{color:var(--t42-content-color-disabled);pointer-events:none;background-color:rgba(0,0,0,0);border-color:#dee2e6}.page-link{padding:.125rem .5rem}.page-item:first-child .page-link{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.page-item:last-child .page-link{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.pagination-lg .page-link{padding:.75rem 1.5rem;font-size:.9375rem}.pagination-lg .page-item:first-child .page-link{border-top-left-radius:1rem;border-bottom-left-radius:1rem}.pagination-lg .page-item:last-child .page-link{border-top-right-radius:1rem;border-bottom-right-radius:1rem}.pagination-sm .page-link{padding:.25rem .5rem;font-size:.65625rem}.pagination-sm .page-item:first-child .page-link{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.pagination-sm .page-item:last-child .page-link{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.page-link{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, color;display:flex;align-items:center;justify-content:center;min-width:1.5rem;min-height:1.5rem;border-radius:0.25rem;overflow:hidden}.page-link[aria-label="Next"],.page-link[aria-label="Previous"]{padding:0}.page-link[aria-label="Next"] span{background:var(--t42-select-indicator) center center/1rem 1rem no-repeat;transform:rotate(-90deg)}.page-link[aria-label="Previous"] span{background:var(--t42-select-indicator) center center/1rem 1rem no-repeat;transform:rotate(90deg)}.page-link>span{width:100%;height:100%;min-height:1rem;font-size:0;clip:initial}.pagination-lg .page-link[aria-label="Next"],.pagination-lg .page-link[aria-label="Previous"]{padding:0.75rem 1.5rem}.page-item{margin-right:8px}.page-item:first-child .page-link>span:not(.sr-only)::before,.page-item:last-child .page-link>span:not(.sr-only)::before{top:-0.125rem}.page-item.active .page-link:hover,.page-item:active .page-link:hover{background-color:var(--t42-color-opacity-05)}.page-item.active.disabled .page-link{background-color:var(--t42-color-opacity-10)}.popover{position:absolute;top:0;left:0 /* rtl:ignore */;z-index:1070;display:block;max-width:276px;font-family:"Montserrat","Helvetica Neue",Arial,sans-serif;font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.65625rem;word-wrap:break-word;background-color:Rgba(var(--t42-bg-dark), 0.75);background-clip:padding-box;border:1px solid var(--t42-color-opacity-10);border-radius:0}.popover .popover-arrow{position:absolute;display:block;width:1rem;height:.5rem}.popover .popover-arrow::before,.popover .popover-arrow::after{position:absolute;display:block;content:"";border-color:transparent;border-style:solid}.bs-popover-top>.popover-arrow,.bs-popover-auto[data-popper-placement^="top"]>.popover-arrow{bottom:calc(-.5rem - 1px)}.bs-popover-top>.popover-arrow::before,.bs-popover-auto[data-popper-placement^="top"]>.popover-arrow::before{bottom:0;border-width:.5rem .5rem 0;border-top-color:var(--t42-color-opacity-10)}.bs-popover-top>.popover-arrow::after,.bs-popover-auto[data-popper-placement^="top"]>.popover-arrow::after{bottom:1px;border-width:.5rem .5rem 0;border-top-color:var(--t42-color-opacity-10)}.bs-popover-end>.popover-arrow,.bs-popover-auto[data-popper-placement^="right"]>.popover-arrow{left:calc(-.5rem - 1px);width:.5rem;height:1rem}.bs-popover-end>.popover-arrow::before,.bs-popover-auto[data-popper-placement^="right"]>.popover-arrow::before{left:0;border-width:.5rem .5rem .5rem 0;border-right-color:var(--t42-color-opacity-10)}.bs-popover-end>.popover-arrow::after,.bs-popover-auto[data-popper-placement^="right"]>.popover-arrow::after{left:1px;border-width:.5rem .5rem .5rem 0;border-right-color:var(--t42-color-opacity-10)}.bs-popover-bottom>.popover-arrow,.bs-popover-auto[data-popper-placement^="bottom"]>.popover-arrow{top:calc(-.5rem - 1px)}.bs-popover-bottom>.popover-arrow::before,.bs-popover-auto[data-popper-placement^="bottom"]>.popover-arrow::before{top:0;border-width:0 .5rem .5rem .5rem;border-bottom-color:var(--t42-color-opacity-10)}.bs-popover-bottom>.popover-arrow::after,.bs-popover-auto[data-popper-placement^="bottom"]>.popover-arrow::after{top:1px;border-width:0 .5rem .5rem .5rem;border-bottom-color:var(--t42-color-opacity-10)}.bs-popover-bottom .popover-header::before,.bs-popover-auto[data-popper-placement^="bottom"] .popover-header::before{position:absolute;top:0;left:50%;display:block;width:1rem;margin-left:-.5rem;content:"";border-bottom:1px solid Rgba(var(--t42-bg-mid), 0.75)}.bs-popover-start>.popover-arrow,.bs-popover-auto[data-popper-placement^="left"]>.popover-arrow{right:calc(-.5rem - 1px);width:.5rem;height:1rem}.bs-popover-start>.popover-arrow::before,.bs-popover-auto[data-popper-placement^="left"]>.popover-arrow::before{right:0;border-width:.5rem 0 .5rem .5rem;border-left-color:var(--t42-color-opacity-10)}.bs-popover-start>.popover-arrow::after,.bs-popover-auto[data-popper-placement^="left"]>.popover-arrow::after{right:1px;border-width:.5rem 0 .5rem .5rem;border-left-color:var(--t42-color-opacity-10)}.popover-header{padding:.55rem 1rem;margin-bottom:0;font-size:.75rem;color:var(--t42-link-color);background-color:Rgba(var(--t42-bg-mid), 0.75);border-bottom:1px solid var(--t42-color-opacity-10);border-top-left-radius:0;border-top-right-radius:0}.popover-header:empty{display:none}.popover-body{padding:1rem 1rem;color:var(--t42-content-color)}.popover{backdrop-filter:var(--backdrop-filter)}@keyframes progress-bar-stripes{0%{background-position-x:1.063rem}}.progress{display:flex;height:1.063rem;overflow:hidden;font-size:.6rem;background-color:Rgb(var(--t42-bg-mid));border-radius:0}.progress-bar{display:flex;flex-direction:column;justify-content:center;overflow:hidden;color:#fff;text-align:center;white-space:nowrap;background-color:#007be5;transition:width 0.6s ease}@media (prefers-reduced-motion: reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-size:1.063rem 1.063rem}.progress-bar-animated{animation:1s linear infinite progress-bar-stripes}@media (prefers-reduced-motion: reduce){.progress-bar-animated{animation:none}}.progress{border:var(--t42-border)}.table{--bs-table-bg: rgba(0,0,0,0);--bs-table-accent-bg: rgba(0,0,0,0);--bs-table-striped-color: var(--t42-content-color);--bs-table-striped-bg: rgba(0,0,0,0.05);--bs-table-active-color: var(--t42-content-color);--bs-table-active-bg: rgba(0,0,0,0.1);--bs-table-hover-color: var(--t42-link-color);--bs-table-hover-bg: rgba(0,0,0,0.075);width:100%;margin-bottom:1rem;color:var(--t42-content-color);vertical-align:top;border-color:var(--t42-color-opacity-10)}.table>:not(caption)>*>*{padding:.25rem .313rem;background-color:var(--bs-table-bg);border-bottom-width:1px;box-shadow:inset 0 0 0 9999px var(--bs-table-accent-bg)}.table>tbody{vertical-align:inherit}.table>thead{vertical-align:bottom}.table>:not(:first-child){border-top:2px solid currentColor}.caption-top{caption-side:top}.table-sm>:not(caption)>*>*{padding:.25rem .25rem}.table-bordered>:not(caption)>*{border-width:1px 0}.table-bordered>:not(caption)>*>*{border-width:0 1px}.table-borderless>:not(caption)>*>*{border-bottom-width:0}.table-borderless>:not(:first-child){border-top-width:0}.table-striped>tbody>tr:nth-of-type(odd)>*{--bs-table-accent-bg: var(--bs-table-striped-bg);color:var(--bs-table-striped-color)}.table-active{--bs-table-accent-bg: var(--bs-table-active-bg);color:var(--bs-table-active-color)}.table-hover>tbody>tr:hover>*{--bs-table-accent-bg: var(--bs-table-hover-bg);color:var(--bs-table-hover-color)}.table-primary{--bs-table-bg: #cce5fa;--bs-table-striped-bg: #c2daee;--bs-table-striped-color: #000;--bs-table-active-bg: #b8cee1;--bs-table-active-color: #000;--bs-table-hover-bg: #bdd4e7;--bs-table-hover-color: #000;color:#000;border-color:#b8cee1}.table-secondary{--bs-table-bg: #dfdfdf;--bs-table-striped-bg: #d4d4d4;--bs-table-striped-color: #000;--bs-table-active-bg: #c9c9c9;--bs-table-active-color: #000;--bs-table-hover-bg: #cecece;--bs-table-hover-color: #000;color:#000;border-color:#c9c9c9}.table-success{--bs-table-bg: #d9ecda;--bs-table-striped-bg: #cee0cf;--bs-table-striped-color: #000;--bs-table-active-bg: #c3d4c4;--bs-table-active-color: #000;--bs-table-hover-bg: #c9daca;--bs-table-hover-color: #000;color:#000;border-color:#c3d4c4}.table-info{--bs-table-bg: #daecf1;--bs-table-striped-bg: #cfe0e5;--bs-table-striped-color: #000;--bs-table-active-bg: #c4d4d9;--bs-table-active-color: #000;--bs-table-hover-bg: #cadadf;--bs-table-hover-color: #000;color:#000;border-color:#c4d4d9}.table-warning{--bs-table-bg: #feeed3;--bs-table-striped-bg: #f1e2c8;--bs-table-striped-color: #000;--bs-table-active-bg: #e5d6be;--bs-table-active-color: #000;--bs-table-hover-bg: #ebdcc3;--bs-table-hover-color: #000;color:#000;border-color:#e5d6be}.table-danger{--bs-table-bg: #ffdcd2;--bs-table-striped-bg: #f2d1c8;--bs-table-striped-color: #000;--bs-table-active-bg: #e6c6bd;--bs-table-active-color: #000;--bs-table-hover-bg: #ecccc2;--bs-table-hover-color: #000;color:#000;border-color:#e6c6bd}.table-light{--bs-table-bg: #616161;--bs-table-striped-bg: dimgray;--bs-table-striped-color: #fff;--bs-table-active-bg: #717171;--bs-table-active-color: #fff;--bs-table-hover-bg: #6d6d6d;--bs-table-hover-color: #fff;color:#fff;border-color:#717171}.table-dark{--bs-table-bg: #616161;--bs-table-striped-bg: dimgray;--bs-table-striped-color: #fff;--bs-table-active-bg: #717171;--bs-table-active-color: #fff;--bs-table-hover-bg: #6d6d6d;--bs-table-hover-color: #fff;color:#fff;border-color:#717171}.table-responsive{overflow-x:auto;-webkit-overflow-scrolling:touch}@media (max-width: 575.98px){.table-responsive-sm{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width: 767.98px){.table-responsive-md{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width: 991.98px){.table-responsive-lg{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width: 1199.98px){.table-responsive-xl{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width: 1399.98px){.table-responsive-xxl{overflow-x:auto;-webkit-overflow-scrolling:touch}}.table>:not(:first-child){border-width:0}.table td,.table th{white-space:nowrap;vertical-align:middle}.table a{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border;border-bottom:0.063rem dashed var(--dark);color:var(--t42-content-color)}.table a:hover{border-bottom-color:var(--t42-content-color);border-bottom-style:solid;color:var(--t42-link-color);text-decoration:none}.table thead th{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;border-width:1px 0;color:Hsl(var(--t42-content-color-base), calc(var(--t42-content-color-l) - 20%));font-weight:normal;font-size:83.3%;text-transform:uppercase}.table td{position:relative}.table td .btn,.table td .btn-sm,.table td .btn-group-sm>.btn,.table td .btn-lg,.table td .btn-group-lg>.btn{line-height:1.25rem}.table td .btn-icon i{position:relative;top:0.0625rem}.table tr th:first-child,.table tr td:first-child{padding-left:0.5rem}.table tr th:last-child,.table tr td:last-child{padding-right:0.5rem}.table-hover tbody tr:hover{background-color:var(--t42-table-active-bg)}.table-hover tbody tr:hover a{border-bottom-color:var(--t42-content-color);color:var(--t42-link-color)}.table-responsive{border:0}.tooltip{position:absolute;z-index:1080;display:block;margin:0;font-family:"Montserrat","Helvetica Neue",Arial,sans-serif;font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.65625rem;word-wrap:break-word;opacity:0}.tooltip.show{opacity:1}.tooltip .tooltip-arrow{position:absolute;display:block;width:.8rem;height:.4rem}.tooltip .tooltip-arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-top,.bs-tooltip-auto[data-popper-placement^="top"]{padding:.4rem 0}.bs-tooltip-top .tooltip-arrow,.bs-tooltip-auto[data-popper-placement^="top"] .tooltip-arrow{bottom:0}.bs-tooltip-top .tooltip-arrow::before,.bs-tooltip-auto[data-popper-placement^="top"] .tooltip-arrow::before{top:-1px;border-width:.4rem .4rem 0;border-top-color:var(--t42-tooltip-bg)}.bs-tooltip-end,.bs-tooltip-auto[data-popper-placement^="right"]{padding:0 .4rem}.bs-tooltip-end .tooltip-arrow,.bs-tooltip-auto[data-popper-placement^="right"] .tooltip-arrow{left:0;width:.4rem;height:.8rem}.bs-tooltip-end .tooltip-arrow::before,.bs-tooltip-auto[data-popper-placement^="right"] .tooltip-arrow::before{right:-1px;border-width:.4rem .4rem .4rem 0;border-right-color:var(--t42-tooltip-bg)}.bs-tooltip-bottom,.bs-tooltip-auto[data-popper-placement^="bottom"]{padding:.4rem 0}.bs-tooltip-bottom .tooltip-arrow,.bs-tooltip-auto[data-popper-placement^="bottom"] .tooltip-arrow{top:0}.bs-tooltip-bottom .tooltip-arrow::before,.bs-tooltip-auto[data-popper-placement^="bottom"] .tooltip-arrow::before{bottom:-1px;border-width:0 .4rem .4rem;border-bottom-color:var(--t42-tooltip-bg)}.bs-tooltip-start,.bs-tooltip-auto[data-popper-placement^="left"]{padding:0 .4rem}.bs-tooltip-start .tooltip-arrow,.bs-tooltip-auto[data-popper-placement^="left"] .tooltip-arrow{right:0;width:.4rem;height:.8rem}.bs-tooltip-start .tooltip-arrow::before,.bs-tooltip-auto[data-popper-placement^="left"] .tooltip-arrow::before{left:-1px;border-width:.4rem 0 .4rem .4rem;border-left-color:var(--t42-tooltip-bg)}.tooltip-inner{max-width:200px;padding:.25rem 1rem;color:var(--t42-content-color);text-align:center;background-color:var(--t42-tooltip-bg);border-radius:0}.tooltip .tooltip-inner{border:var(--t42-border);box-shadow:var(--t42-shadow)}.bs-tooltip-top .arrow,.bs-tooltip-auto[data-popper-placement^="top"] .arrow{bottom:1px}.bs-tooltip-top .arrow::before,.bs-tooltip-auto[data-popper-placement^="top"] .arrow::before{border-top-color:var(--t42-color-opacity-10)}.bs-tooltip-bottom .arrow,.bs-tooltip-auto[data-popper-placement^="bottom"] .arrow{top:1px}.bs-tooltip-bottom .arrow::before,.bs-tooltip-auto[data-popper-placement^="bottom"] .arrow::before{border-bottom-color:var(--t42-color-opacity-10)}.bs-tooltip-right .arrow{left:1px}.bs-tooltip-right .arrow::before{border-right-color:var(--t42-color-opacity-10)}.bs-tooltip-left .arrow{right:1px}.bs-tooltip-left .arrow::before{border-left-color:var(--t42-color-opacity-10)}.fade{transition:opacity 0.15s linear}@media (prefers-reduced-motion: reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{height:0;overflow:hidden;transition:height 0.35s ease}@media (prefers-reduced-motion: reduce){.collapsing{transition:none}}.collapsing.collapse-horizontal{width:0;height:auto;transition:width 0.35s ease}@media (prefers-reduced-motion: reduce){.collapsing.collapse-horizontal{transition:none}}mark,.mark{color:var(--white)}pre{background-color:var(--t42-bg-dark)}blockquote,.blockquote{padding:1rem 1rem 0.01rem;border-left:0.25rem solid var(--secondary);background-color:Rgb(var(--t42-bg-dark))}.blockquote-footer{margin-top:-2rem;margin-left:1.25rem;color:var(--t42-content-color-muted);font-size:0.875em}.clearfix::after{display:block;clear:both;content:""}.link-primary{color:#007be5}.link-primary:hover,.link-primary:focus{color:#3395ea}.link-secondary{color:#616161}.link-secondary:hover,.link-secondary:focus{color:#4e4e4e}.link-success{color:#43a047}.link-success:hover,.link-success:focus{color:#69b36c}.link-info{color:#469eb9}.link-info:hover,.link-info:focus{color:#6bb1c7}.link-warning{color:#f9a825}.link-warning:hover,.link-warning:focus{color:#fab951}.link-danger{color:#ff511f}.link-danger:hover,.link-danger:focus{color:#ff744c}.link-light{color:#616161}.link-light:hover,.link-light:focus{color:#4e4e4e}.link-dark{color:#616161}.link-dark:hover,.link-dark:focus{color:#4e4e4e}.ratio{position:relative;width:100%}.ratio::before{display:block;padding-top:var(--bs-aspect-ratio);content:""}.ratio>*{position:absolute;top:0;left:0;width:100%;height:100%}.ratio-1x1{--bs-aspect-ratio: 100%}.ratio-4x3{--bs-aspect-ratio: calc(3 / 4 * 100%)}.ratio-16x9{--bs-aspect-ratio: calc(9 / 16 * 100%)}.ratio-21x9{--bs-aspect-ratio: calc(9 / 21 * 100%)}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}.sticky-top{position:sticky;top:0;z-index:1020}@media (min-width: 576px){.sticky-sm-top{position:sticky;top:0;z-index:1020}}@media (min-width: 768px){.sticky-md-top{position:sticky;top:0;z-index:1020}}@media (min-width: 992px){.sticky-lg-top{position:sticky;top:0;z-index:1020}}@media (min-width: 1200px){.sticky-xl-top{position:sticky;top:0;z-index:1020}}@media (min-width: 1400px){.sticky-xxl-top{position:sticky;top:0;z-index:1020}}.hstack{display:flex;flex-direction:row;align-items:center;align-self:stretch}.vstack{display:flex;flex:1 1 auto;flex-direction:column;align-self:stretch}.visually-hidden,.visually-hidden-focusable:not(:focus):not(:focus-within){position:absolute !important;width:1px !important;height:1px !important;padding:0 !important;margin:-1px !important;overflow:hidden !important;clip:rect(0, 0, 0, 0) !important;white-space:nowrap !important;border:0 !important}.stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.vr{display:inline-block;align-self:stretch;width:1px;min-height:1em;background-color:currentColor;opacity:.25}.align-baseline{vertical-align:baseline !important}.align-top{vertical-align:top !important}.align-middle{vertical-align:middle !important}.align-bottom{vertical-align:bottom !important}.align-text-bottom{vertical-align:text-bottom !important}.align-text-top{vertical-align:text-top !important}.float-start{float:left !important}.float-end{float:right !important}.float-none{float:none !important}.opacity-0{opacity:0 !important}.opacity-25{opacity:.25 !important}.opacity-50{opacity:.5 !important}.opacity-75{opacity:.75 !important}.opacity-100{opacity:1 !important}.overflow-auto{overflow:auto !important}.overflow-hidden{overflow:hidden !important}.overflow-visible{overflow:visible !important}.overflow-scroll{overflow:scroll !important}.d-inline{display:inline !important}.d-inline-block{display:inline-block !important}.d-block{display:block !important}.d-grid{display:grid !important}.d-table{display:table !important}.d-table-row{display:table-row !important}.d-table-cell{display:table-cell !important}.d-flex{display:flex !important}.d-inline-flex{display:inline-flex !important}.d-none{display:none !important}.shadow{box-shadow:0 0.5rem 1rem rgba(0,0,0,0.15) !important}.shadow-sm{box-shadow:0 0.125rem 0.25rem rgba(0,0,0,0.075) !important}.shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,0.175) !important}.shadow-none{box-shadow:none !important}.position-static{position:static !important}.position-relative{position:relative !important}.position-absolute{position:absolute !important}.position-fixed{position:fixed !important}.position-sticky{position:sticky !important}.top-0{top:0 !important}.top-50{top:50% !important}.top-100{top:100% !important}.bottom-0{bottom:0 !important}.bottom-50{bottom:50% !important}.bottom-100{bottom:100% !important}.start-0{left:0 !important}.start-50{left:50% !important}.start-100{left:100% !important}.end-0{right:0 !important}.end-50{right:50% !important}.end-100{right:100% !important}.translate-middle{transform:translate(-50%, -50%) !important}.translate-middle-x{transform:translateX(-50%) !important}.translate-middle-y{transform:translateY(-50%) !important}.border{border:1px solid #dee2e6 !important}.border-0{border:0 !important}.border-top{border-top:1px solid #dee2e6 !important}.border-top-0{border-top:0 !important}.border-end{border-right:1px solid #dee2e6 !important}.border-end-0{border-right:0 !important}.border-bottom{border-bottom:1px solid #dee2e6 !important}.border-bottom-0{border-bottom:0 !important}.border-start{border-left:1px solid #dee2e6 !important}.border-start-0{border-left:0 !important}.border-primary{border-color:#007be5 !important}.border-secondary{border-color:#616161 !important}.border-success{border-color:#43a047 !important}.border-info{border-color:#469eb9 !important}.border-warning{border-color:#f9a825 !important}.border-danger{border-color:#ff511f !important}.border-light{border-color:#616161 !important}.border-dark{border-color:#616161 !important}.border-white{border-color:#fff !important}.border-1{border-width:1px !important}.border-2{border-width:2px !important}.border-3{border-width:3px !important}.border-4{border-width:4px !important}.border-5{border-width:5px !important}.w-25{width:25% !important}.w-50{width:50% !important}.w-75{width:75% !important}.w-100{width:100% !important}.w-auto{width:auto !important}.mw-100{max-width:100% !important}.vw-100{width:100vw !important}.min-vw-100{min-width:100vw !important}.h-25{height:25% !important}.h-50{height:50% !important}.h-75{height:75% !important}.h-100{height:100% !important}.h-auto{height:auto !important}.mh-100{max-height:100% !important}.vh-100{height:100vh !important}.min-vh-100{min-height:100vh !important}.flex-fill{flex:1 1 auto !important}.flex-row{flex-direction:row !important}.flex-column{flex-direction:column !important}.flex-row-reverse{flex-direction:row-reverse !important}.flex-column-reverse{flex-direction:column-reverse !important}.flex-grow-0{flex-grow:0 !important}.flex-grow-1{flex-grow:1 !important}.flex-shrink-0{flex-shrink:0 !important}.flex-shrink-1{flex-shrink:1 !important}.flex-wrap{flex-wrap:wrap !important}.flex-nowrap{flex-wrap:nowrap !important}.flex-wrap-reverse{flex-wrap:wrap-reverse !important}.gap-0{gap:0 !important}.gap-1{gap:.25rem !important}.gap-2{gap:.5rem !important}.gap-3{gap:1rem !important}.gap-4{gap:1.5rem !important}.gap-5{gap:3rem !important}.justify-content-start{justify-content:flex-start !important}.justify-content-end{justify-content:flex-end !important}.justify-content-center{justify-content:center !important}.justify-content-between{justify-content:space-between !important}.justify-content-around{justify-content:space-around !important}.justify-content-evenly{justify-content:space-evenly !important}.align-items-start{align-items:flex-start !important}.align-items-end{align-items:flex-end !important}.align-items-center{align-items:center !important}.align-items-baseline{align-items:baseline !important}.align-items-stretch{align-items:stretch !important}.align-content-start{align-content:flex-start !important}.align-content-end{align-content:flex-end !important}.align-content-center{align-content:center !important}.align-content-between{align-content:space-between !important}.align-content-around{align-content:space-around !important}.align-content-stretch{align-content:stretch !important}.align-self-auto{align-self:auto !important}.align-self-start{align-self:flex-start !important}.align-self-end{align-self:flex-end !important}.align-self-center{align-self:center !important}.align-self-baseline{align-self:baseline !important}.align-self-stretch{align-self:stretch !important}.order-first{order:-1 !important}.order-0{order:0 !important}.order-1{order:1 !important}.order-2{order:2 !important}.order-3{order:3 !important}.order-4{order:4 !important}.order-5{order:5 !important}.order-last{order:6 !important}.m-0{margin:0 !important}.m-1{margin:.25rem !important}.m-2{margin:.5rem !important}.m-3{margin:1rem !important}.m-4{margin:1.5rem !important}.m-5{margin:3rem !important}.m-auto{margin:auto !important}.mx-0{margin-right:0 !important;margin-left:0 !important}.mx-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-3{margin-right:1rem !important;margin-left:1rem !important}.mx-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-5{margin-right:3rem !important;margin-left:3rem !important}.mx-auto{margin-right:auto !important;margin-left:auto !important}.my-0{margin-top:0 !important;margin-bottom:0 !important}.my-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-0{margin-top:0 !important}.mt-1{margin-top:.25rem !important}.mt-2{margin-top:.5rem !important}.mt-3{margin-top:1rem !important}.mt-4{margin-top:1.5rem !important}.mt-5{margin-top:3rem !important}.mt-auto{margin-top:auto !important}.me-0{margin-right:0 !important}.me-1{margin-right:.25rem !important}.me-2{margin-right:.5rem !important}.me-3{margin-right:1rem !important}.me-4{margin-right:1.5rem !important}.me-5{margin-right:3rem !important}.me-auto{margin-right:auto !important}.mb-0{margin-bottom:0 !important}.mb-1{margin-bottom:.25rem !important}.mb-2{margin-bottom:.5rem !important}.mb-3{margin-bottom:1rem !important}.mb-4{margin-bottom:1.5rem !important}.mb-5{margin-bottom:3rem !important}.mb-auto{margin-bottom:auto !important}.ms-0{margin-left:0 !important}.ms-1{margin-left:.25rem !important}.ms-2{margin-left:.5rem !important}.ms-3{margin-left:1rem !important}.ms-4{margin-left:1.5rem !important}.ms-5{margin-left:3rem !important}.ms-auto{margin-left:auto !important}.p-0{padding:0 !important}.p-1{padding:.25rem !important}.p-2{padding:.5rem !important}.p-3{padding:1rem !important}.p-4{padding:1.5rem !important}.p-5{padding:3rem !important}.px-0{padding-right:0 !important;padding-left:0 !important}.px-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-3{padding-right:1rem !important;padding-left:1rem !important}.px-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-5{padding-right:3rem !important;padding-left:3rem !important}.py-0{padding-top:0 !important;padding-bottom:0 !important}.py-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-0{padding-top:0 !important}.pt-1{padding-top:.25rem !important}.pt-2{padding-top:.5rem !important}.pt-3{padding-top:1rem !important}.pt-4{padding-top:1.5rem !important}.pt-5{padding-top:3rem !important}.pe-0{padding-right:0 !important}.pe-1{padding-right:.25rem !important}.pe-2{padding-right:.5rem !important}.pe-3{padding-right:1rem !important}.pe-4{padding-right:1.5rem !important}.pe-5{padding-right:3rem !important}.pb-0{padding-bottom:0 !important}.pb-1{padding-bottom:.25rem !important}.pb-2{padding-bottom:.5rem !important}.pb-3{padding-bottom:1rem !important}.pb-4{padding-bottom:1.5rem !important}.pb-5{padding-bottom:3rem !important}.ps-0{padding-left:0 !important}.ps-1{padding-left:.25rem !important}.ps-2{padding-left:.5rem !important}.ps-3{padding-left:1rem !important}.ps-4{padding-left:1.5rem !important}.ps-5{padding-left:3rem !important}.font-monospace{font-family:var(--bs-font-monospace) !important}.fs-1{font-size:calc(1.26563rem + .1875vw) !important}.fs-2{font-size:1.125rem !important}.fs-3{font-size:.98475rem !important}.fs-4{font-size:.84375rem !important}.fs-5{font-size:.75rem !important}.fs-6{font-size:.7035rem !important}.fst-italic{font-style:italic !important}.fst-normal{font-style:normal !important}.fw-light{font-weight:300 !important}.fw-lighter{font-weight:lighter !important}.fw-normal{font-weight:400 !important}.fw-bold{font-weight:700 !important}.fw-bolder{font-weight:bolder !important}.lh-1{line-height:1 !important}.lh-sm{line-height:1.25 !important}.lh-base{line-height:1.5 !important}.lh-lg{line-height:2 !important}.text-start{text-align:left !important}.text-end{text-align:right !important}.text-center{text-align:center !important}.text-decoration-none{text-decoration:none !important}.text-decoration-underline{text-decoration:underline !important}.text-decoration-line-through{text-decoration:line-through !important}.text-lowercase{text-transform:lowercase !important}.text-uppercase{text-transform:uppercase !important}.text-capitalize{text-transform:capitalize !important}.text-wrap{white-space:normal !important}.text-nowrap{white-space:nowrap !important}.text-break{word-wrap:break-word !important;word-break:break-word !important}.text-primary{--bs-text-opacity: 1;color:rgba(var(--bs-primary-rgb), var(--bs-text-opacity)) !important}.text-secondary{--bs-text-opacity: 1;color:rgba(var(--bs-secondary-rgb), var(--bs-text-opacity)) !important}.text-success{--bs-text-opacity: 1;color:rgba(var(--bs-success-rgb), var(--bs-text-opacity)) !important}.text-info{--bs-text-opacity: 1;color:rgba(var(--bs-info-rgb), var(--bs-text-opacity)) !important}.text-warning{--bs-text-opacity: 1;color:rgba(var(--bs-warning-rgb), var(--bs-text-opacity)) !important}.text-danger{--bs-text-opacity: 1;color:rgba(var(--bs-danger-rgb), var(--bs-text-opacity)) !important}.text-light{--bs-text-opacity: 1;color:rgba(var(--bs-light-rgb), var(--bs-text-opacity)) !important}.text-dark{--bs-text-opacity: 1;color:rgba(var(--bs-dark-rgb), var(--bs-text-opacity)) !important}.text-black{--bs-text-opacity: 1;color:rgba(var(--bs-black-rgb), var(--bs-text-opacity)) !important}.text-white{--bs-text-opacity: 1;color:rgba(var(--bs-white-rgb), var(--bs-text-opacity)) !important}.text-body{--bs-text-opacity: 1;color:rgba(var(--bs-body-color-rgb), var(--bs-text-opacity)) !important}.text-muted{--bs-text-opacity: 1;color:var(--t42-content-color-muted) !important}.text-black-50{--bs-text-opacity: 1;color:rgba(0,0,0,0.5) !important}.text-white-50{--bs-text-opacity: 1;color:rgba(255,255,255,0.5) !important}.text-reset{--bs-text-opacity: 1;color:inherit !important}.text-opacity-25{--bs-text-opacity: .25}.text-opacity-50{--bs-text-opacity: .5}.text-opacity-75{--bs-text-opacity: .75}.text-opacity-100{--bs-text-opacity: 1}.bg-primary{--bs-bg-opacity: 1;background-color:rgba(var(--bs-primary-rgb), var(--bs-bg-opacity)) !important}.bg-secondary{--bs-bg-opacity: 1;background-color:rgba(var(--bs-secondary-rgb), var(--bs-bg-opacity)) !important}.bg-success{--bs-bg-opacity: 1;background-color:rgba(var(--bs-success-rgb), var(--bs-bg-opacity)) !important}.bg-info{--bs-bg-opacity: 1;background-color:rgba(var(--bs-info-rgb), var(--bs-bg-opacity)) !important}.bg-warning{--bs-bg-opacity: 1;background-color:rgba(var(--bs-warning-rgb), var(--bs-bg-opacity)) !important}.bg-danger{--bs-bg-opacity: 1;background-color:rgba(var(--bs-danger-rgb), var(--bs-bg-opacity)) !important}.bg-light{--bs-bg-opacity: 1;background-color:rgba(var(--bs-light-rgb), var(--bs-bg-opacity)) !important}.bg-dark{--bs-bg-opacity: 1;background-color:rgba(var(--bs-dark-rgb), var(--bs-bg-opacity)) !important}.bg-black{--bs-bg-opacity: 1;background-color:rgba(var(--bs-black-rgb), var(--bs-bg-opacity)) !important}.bg-white{--bs-bg-opacity: 1;background-color:rgba(var(--bs-white-rgb), var(--bs-bg-opacity)) !important}.bg-body{--bs-bg-opacity: 1;background-color:rgba(var(--bs-body-bg-rgb), var(--bs-bg-opacity)) !important}.bg-transparent{--bs-bg-opacity: 1;background-color:rgba(0,0,0,0) !important}.bg-opacity-10{--bs-bg-opacity: .1}.bg-opacity-25{--bs-bg-opacity: .25}.bg-opacity-50{--bs-bg-opacity: .5}.bg-opacity-75{--bs-bg-opacity: .75}.bg-opacity-100{--bs-bg-opacity: 1}.bg-gradient{background-image:var(--bs-gradient) !important}.user-select-all{user-select:all !important}.user-select-auto{user-select:auto !important}.user-select-none{user-select:none !important}.pe-none{pointer-events:none !important}.pe-auto{pointer-events:auto !important}.rounded{border-radius:.25rem !important}.rounded-0{border-radius:0 !important}.rounded-1{border-radius:.25rem !important}.rounded-2{border-radius:.25rem !important}.rounded-3{border-radius:1rem !important}.rounded-circle{border-radius:50% !important}.rounded-pill{border-radius:50rem !important}.rounded-top{border-top-left-radius:.25rem !important;border-top-right-radius:.25rem !important}.rounded-end{border-top-right-radius:.25rem !important;border-bottom-right-radius:.25rem !important}.rounded-bottom{border-bottom-right-radius:.25rem !important;border-bottom-left-radius:.25rem !important}.rounded-start{border-bottom-left-radius:.25rem !important;border-top-left-radius:.25rem !important}.visible{visibility:visible !important}.invisible{visibility:hidden !important}@media (min-width: 576px){.float-sm-start{float:left !important}.float-sm-end{float:right !important}.float-sm-none{float:none !important}.d-sm-inline{display:inline !important}.d-sm-inline-block{display:inline-block !important}.d-sm-block{display:block !important}.d-sm-grid{display:grid !important}.d-sm-table{display:table !important}.d-sm-table-row{display:table-row !important}.d-sm-table-cell{display:table-cell !important}.d-sm-flex{display:flex !important}.d-sm-inline-flex{display:inline-flex !important}.d-sm-none{display:none !important}.flex-sm-fill{flex:1 1 auto !important}.flex-sm-row{flex-direction:row !important}.flex-sm-column{flex-direction:column !important}.flex-sm-row-reverse{flex-direction:row-reverse !important}.flex-sm-column-reverse{flex-direction:column-reverse !important}.flex-sm-grow-0{flex-grow:0 !important}.flex-sm-grow-1{flex-grow:1 !important}.flex-sm-shrink-0{flex-shrink:0 !important}.flex-sm-shrink-1{flex-shrink:1 !important}.flex-sm-wrap{flex-wrap:wrap !important}.flex-sm-nowrap{flex-wrap:nowrap !important}.flex-sm-wrap-reverse{flex-wrap:wrap-reverse !important}.gap-sm-0{gap:0 !important}.gap-sm-1{gap:.25rem !important}.gap-sm-2{gap:.5rem !important}.gap-sm-3{gap:1rem !important}.gap-sm-4{gap:1.5rem !important}.gap-sm-5{gap:3rem !important}.justify-content-sm-start{justify-content:flex-start !important}.justify-content-sm-end{justify-content:flex-end !important}.justify-content-sm-center{justify-content:center !important}.justify-content-sm-between{justify-content:space-between !important}.justify-content-sm-around{justify-content:space-around !important}.justify-content-sm-evenly{justify-content:space-evenly !important}.align-items-sm-start{align-items:flex-start !important}.align-items-sm-end{align-items:flex-end !important}.align-items-sm-center{align-items:center !important}.align-items-sm-baseline{align-items:baseline !important}.align-items-sm-stretch{align-items:stretch !important}.align-content-sm-start{align-content:flex-start !important}.align-content-sm-end{align-content:flex-end !important}.align-content-sm-center{align-content:center !important}.align-content-sm-between{align-content:space-between !important}.align-content-sm-around{align-content:space-around !important}.align-content-sm-stretch{align-content:stretch !important}.align-self-sm-auto{align-self:auto !important}.align-self-sm-start{align-self:flex-start !important}.align-self-sm-end{align-self:flex-end !important}.align-self-sm-center{align-self:center !important}.align-self-sm-baseline{align-self:baseline !important}.align-self-sm-stretch{align-self:stretch !important}.order-sm-first{order:-1 !important}.order-sm-0{order:0 !important}.order-sm-1{order:1 !important}.order-sm-2{order:2 !important}.order-sm-3{order:3 !important}.order-sm-4{order:4 !important}.order-sm-5{order:5 !important}.order-sm-last{order:6 !important}.m-sm-0{margin:0 !important}.m-sm-1{margin:.25rem !important}.m-sm-2{margin:.5rem !important}.m-sm-3{margin:1rem !important}.m-sm-4{margin:1.5rem !important}.m-sm-5{margin:3rem !important}.m-sm-auto{margin:auto !important}.mx-sm-0{margin-right:0 !important;margin-left:0 !important}.mx-sm-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-sm-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-sm-3{margin-right:1rem !important;margin-left:1rem !important}.mx-sm-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-sm-5{margin-right:3rem !important;margin-left:3rem !important}.mx-sm-auto{margin-right:auto !important;margin-left:auto !important}.my-sm-0{margin-top:0 !important;margin-bottom:0 !important}.my-sm-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-sm-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-sm-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-sm-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-sm-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-sm-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-sm-0{margin-top:0 !important}.mt-sm-1{margin-top:.25rem !important}.mt-sm-2{margin-top:.5rem !important}.mt-sm-3{margin-top:1rem !important}.mt-sm-4{margin-top:1.5rem !important}.mt-sm-5{margin-top:3rem !important}.mt-sm-auto{margin-top:auto !important}.me-sm-0{margin-right:0 !important}.me-sm-1{margin-right:.25rem !important}.me-sm-2{margin-right:.5rem !important}.me-sm-3{margin-right:1rem !important}.me-sm-4{margin-right:1.5rem !important}.me-sm-5{margin-right:3rem !important}.me-sm-auto{margin-right:auto !important}.mb-sm-0{margin-bottom:0 !important}.mb-sm-1{margin-bottom:.25rem !important}.mb-sm-2{margin-bottom:.5rem !important}.mb-sm-3{margin-bottom:1rem !important}.mb-sm-4{margin-bottom:1.5rem !important}.mb-sm-5{margin-bottom:3rem !important}.mb-sm-auto{margin-bottom:auto !important}.ms-sm-0{margin-left:0 !important}.ms-sm-1{margin-left:.25rem !important}.ms-sm-2{margin-left:.5rem !important}.ms-sm-3{margin-left:1rem !important}.ms-sm-4{margin-left:1.5rem !important}.ms-sm-5{margin-left:3rem !important}.ms-sm-auto{margin-left:auto !important}.p-sm-0{padding:0 !important}.p-sm-1{padding:.25rem !important}.p-sm-2{padding:.5rem !important}.p-sm-3{padding:1rem !important}.p-sm-4{padding:1.5rem !important}.p-sm-5{padding:3rem !important}.px-sm-0{padding-right:0 !important;padding-left:0 !important}.px-sm-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-sm-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-sm-3{padding-right:1rem !important;padding-left:1rem !important}.px-sm-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-sm-5{padding-right:3rem !important;padding-left:3rem !important}.py-sm-0{padding-top:0 !important;padding-bottom:0 !important}.py-sm-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-sm-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-sm-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-sm-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-sm-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-sm-0{padding-top:0 !important}.pt-sm-1{padding-top:.25rem !important}.pt-sm-2{padding-top:.5rem !important}.pt-sm-3{padding-top:1rem !important}.pt-sm-4{padding-top:1.5rem !important}.pt-sm-5{padding-top:3rem !important}.pe-sm-0{padding-right:0 !important}.pe-sm-1{padding-right:.25rem !important}.pe-sm-2{padding-right:.5rem !important}.pe-sm-3{padding-right:1rem !important}.pe-sm-4{padding-right:1.5rem !important}.pe-sm-5{padding-right:3rem !important}.pb-sm-0{padding-bottom:0 !important}.pb-sm-1{padding-bottom:.25rem !important}.pb-sm-2{padding-bottom:.5rem !important}.pb-sm-3{padding-bottom:1rem !important}.pb-sm-4{padding-bottom:1.5rem !important}.pb-sm-5{padding-bottom:3rem !important}.ps-sm-0{padding-left:0 !important}.ps-sm-1{padding-left:.25rem !important}.ps-sm-2{padding-left:.5rem !important}.ps-sm-3{padding-left:1rem !important}.ps-sm-4{padding-left:1.5rem !important}.ps-sm-5{padding-left:3rem !important}.text-sm-start{text-align:left !important}.text-sm-end{text-align:right !important}.text-sm-center{text-align:center !important}}@media (min-width: 768px){.float-md-start{float:left !important}.float-md-end{float:right !important}.float-md-none{float:none !important}.d-md-inline{display:inline !important}.d-md-inline-block{display:inline-block !important}.d-md-block{display:block !important}.d-md-grid{display:grid !important}.d-md-table{display:table !important}.d-md-table-row{display:table-row !important}.d-md-table-cell{display:table-cell !important}.d-md-flex{display:flex !important}.d-md-inline-flex{display:inline-flex !important}.d-md-none{display:none !important}.flex-md-fill{flex:1 1 auto !important}.flex-md-row{flex-direction:row !important}.flex-md-column{flex-direction:column !important}.flex-md-row-reverse{flex-direction:row-reverse !important}.flex-md-column-reverse{flex-direction:column-reverse !important}.flex-md-grow-0{flex-grow:0 !important}.flex-md-grow-1{flex-grow:1 !important}.flex-md-shrink-0{flex-shrink:0 !important}.flex-md-shrink-1{flex-shrink:1 !important}.flex-md-wrap{flex-wrap:wrap !important}.flex-md-nowrap{flex-wrap:nowrap !important}.flex-md-wrap-reverse{flex-wrap:wrap-reverse !important}.gap-md-0{gap:0 !important}.gap-md-1{gap:.25rem !important}.gap-md-2{gap:.5rem !important}.gap-md-3{gap:1rem !important}.gap-md-4{gap:1.5rem !important}.gap-md-5{gap:3rem !important}.justify-content-md-start{justify-content:flex-start !important}.justify-content-md-end{justify-content:flex-end !important}.justify-content-md-center{justify-content:center !important}.justify-content-md-between{justify-content:space-between !important}.justify-content-md-around{justify-content:space-around !important}.justify-content-md-evenly{justify-content:space-evenly !important}.align-items-md-start{align-items:flex-start !important}.align-items-md-end{align-items:flex-end !important}.align-items-md-center{align-items:center !important}.align-items-md-baseline{align-items:baseline !important}.align-items-md-stretch{align-items:stretch !important}.align-content-md-start{align-content:flex-start !important}.align-content-md-end{align-content:flex-end !important}.align-content-md-center{align-content:center !important}.align-content-md-between{align-content:space-between !important}.align-content-md-around{align-content:space-around !important}.align-content-md-stretch{align-content:stretch !important}.align-self-md-auto{align-self:auto !important}.align-self-md-start{align-self:flex-start !important}.align-self-md-end{align-self:flex-end !important}.align-self-md-center{align-self:center !important}.align-self-md-baseline{align-self:baseline !important}.align-self-md-stretch{align-self:stretch !important}.order-md-first{order:-1 !important}.order-md-0{order:0 !important}.order-md-1{order:1 !important}.order-md-2{order:2 !important}.order-md-3{order:3 !important}.order-md-4{order:4 !important}.order-md-5{order:5 !important}.order-md-last{order:6 !important}.m-md-0{margin:0 !important}.m-md-1{margin:.25rem !important}.m-md-2{margin:.5rem !important}.m-md-3{margin:1rem !important}.m-md-4{margin:1.5rem !important}.m-md-5{margin:3rem !important}.m-md-auto{margin:auto !important}.mx-md-0{margin-right:0 !important;margin-left:0 !important}.mx-md-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-md-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-md-3{margin-right:1rem !important;margin-left:1rem !important}.mx-md-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-md-5{margin-right:3rem !important;margin-left:3rem !important}.mx-md-auto{margin-right:auto !important;margin-left:auto !important}.my-md-0{margin-top:0 !important;margin-bottom:0 !important}.my-md-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-md-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-md-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-md-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-md-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-md-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-md-0{margin-top:0 !important}.mt-md-1{margin-top:.25rem !important}.mt-md-2{margin-top:.5rem !important}.mt-md-3{margin-top:1rem !important}.mt-md-4{margin-top:1.5rem !important}.mt-md-5{margin-top:3rem !important}.mt-md-auto{margin-top:auto !important}.me-md-0{margin-right:0 !important}.me-md-1{margin-right:.25rem !important}.me-md-2{margin-right:.5rem !important}.me-md-3{margin-right:1rem !important}.me-md-4{margin-right:1.5rem !important}.me-md-5{margin-right:3rem !important}.me-md-auto{margin-right:auto !important}.mb-md-0{margin-bottom:0 !important}.mb-md-1{margin-bottom:.25rem !important}.mb-md-2{margin-bottom:.5rem !important}.mb-md-3{margin-bottom:1rem !important}.mb-md-4{margin-bottom:1.5rem !important}.mb-md-5{margin-bottom:3rem !important}.mb-md-auto{margin-bottom:auto !important}.ms-md-0{margin-left:0 !important}.ms-md-1{margin-left:.25rem !important}.ms-md-2{margin-left:.5rem !important}.ms-md-3{margin-left:1rem !important}.ms-md-4{margin-left:1.5rem !important}.ms-md-5{margin-left:3rem !important}.ms-md-auto{margin-left:auto !important}.p-md-0{padding:0 !important}.p-md-1{padding:.25rem !important}.p-md-2{padding:.5rem !important}.p-md-3{padding:1rem !important}.p-md-4{padding:1.5rem !important}.p-md-5{padding:3rem !important}.px-md-0{padding-right:0 !important;padding-left:0 !important}.px-md-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-md-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-md-3{padding-right:1rem !important;padding-left:1rem !important}.px-md-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-md-5{padding-right:3rem !important;padding-left:3rem !important}.py-md-0{padding-top:0 !important;padding-bottom:0 !important}.py-md-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-md-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-md-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-md-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-md-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-md-0{padding-top:0 !important}.pt-md-1{padding-top:.25rem !important}.pt-md-2{padding-top:.5rem !important}.pt-md-3{padding-top:1rem !important}.pt-md-4{padding-top:1.5rem !important}.pt-md-5{padding-top:3rem !important}.pe-md-0{padding-right:0 !important}.pe-md-1{padding-right:.25rem !important}.pe-md-2{padding-right:.5rem !important}.pe-md-3{padding-right:1rem !important}.pe-md-4{padding-right:1.5rem !important}.pe-md-5{padding-right:3rem !important}.pb-md-0{padding-bottom:0 !important}.pb-md-1{padding-bottom:.25rem !important}.pb-md-2{padding-bottom:.5rem !important}.pb-md-3{padding-bottom:1rem !important}.pb-md-4{padding-bottom:1.5rem !important}.pb-md-5{padding-bottom:3rem !important}.ps-md-0{padding-left:0 !important}.ps-md-1{padding-left:.25rem !important}.ps-md-2{padding-left:.5rem !important}.ps-md-3{padding-left:1rem !important}.ps-md-4{padding-left:1.5rem !important}.ps-md-5{padding-left:3rem !important}.text-md-start{text-align:left !important}.text-md-end{text-align:right !important}.text-md-center{text-align:center !important}}@media (min-width: 992px){.float-lg-start{float:left !important}.float-lg-end{float:right !important}.float-lg-none{float:none !important}.d-lg-inline{display:inline !important}.d-lg-inline-block{display:inline-block !important}.d-lg-block{display:block !important}.d-lg-grid{display:grid !important}.d-lg-table{display:table !important}.d-lg-table-row{display:table-row !important}.d-lg-table-cell{display:table-cell !important}.d-lg-flex{display:flex !important}.d-lg-inline-flex{display:inline-flex !important}.d-lg-none{display:none !important}.flex-lg-fill{flex:1 1 auto !important}.flex-lg-row{flex-direction:row !important}.flex-lg-column{flex-direction:column !important}.flex-lg-row-reverse{flex-direction:row-reverse !important}.flex-lg-column-reverse{flex-direction:column-reverse !important}.flex-lg-grow-0{flex-grow:0 !important}.flex-lg-grow-1{flex-grow:1 !important}.flex-lg-shrink-0{flex-shrink:0 !important}.flex-lg-shrink-1{flex-shrink:1 !important}.flex-lg-wrap{flex-wrap:wrap !important}.flex-lg-nowrap{flex-wrap:nowrap !important}.flex-lg-wrap-reverse{flex-wrap:wrap-reverse !important}.gap-lg-0{gap:0 !important}.gap-lg-1{gap:.25rem !important}.gap-lg-2{gap:.5rem !important}.gap-lg-3{gap:1rem !important}.gap-lg-4{gap:1.5rem !important}.gap-lg-5{gap:3rem !important}.justify-content-lg-start{justify-content:flex-start !important}.justify-content-lg-end{justify-content:flex-end !important}.justify-content-lg-center{justify-content:center !important}.justify-content-lg-between{justify-content:space-between !important}.justify-content-lg-around{justify-content:space-around !important}.justify-content-lg-evenly{justify-content:space-evenly !important}.align-items-lg-start{align-items:flex-start !important}.align-items-lg-end{align-items:flex-end !important}.align-items-lg-center{align-items:center !important}.align-items-lg-baseline{align-items:baseline !important}.align-items-lg-stretch{align-items:stretch !important}.align-content-lg-start{align-content:flex-start !important}.align-content-lg-end{align-content:flex-end !important}.align-content-lg-center{align-content:center !important}.align-content-lg-between{align-content:space-between !important}.align-content-lg-around{align-content:space-around !important}.align-content-lg-stretch{align-content:stretch !important}.align-self-lg-auto{align-self:auto !important}.align-self-lg-start{align-self:flex-start !important}.align-self-lg-end{align-self:flex-end !important}.align-self-lg-center{align-self:center !important}.align-self-lg-baseline{align-self:baseline !important}.align-self-lg-stretch{align-self:stretch !important}.order-lg-first{order:-1 !important}.order-lg-0{order:0 !important}.order-lg-1{order:1 !important}.order-lg-2{order:2 !important}.order-lg-3{order:3 !important}.order-lg-4{order:4 !important}.order-lg-5{order:5 !important}.order-lg-last{order:6 !important}.m-lg-0{margin:0 !important}.m-lg-1{margin:.25rem !important}.m-lg-2{margin:.5rem !important}.m-lg-3{margin:1rem !important}.m-lg-4{margin:1.5rem !important}.m-lg-5{margin:3rem !important}.m-lg-auto{margin:auto !important}.mx-lg-0{margin-right:0 !important;margin-left:0 !important}.mx-lg-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-lg-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-lg-3{margin-right:1rem !important;margin-left:1rem !important}.mx-lg-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-lg-5{margin-right:3rem !important;margin-left:3rem !important}.mx-lg-auto{margin-right:auto !important;margin-left:auto !important}.my-lg-0{margin-top:0 !important;margin-bottom:0 !important}.my-lg-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-lg-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-lg-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-lg-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-lg-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-lg-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-lg-0{margin-top:0 !important}.mt-lg-1{margin-top:.25rem !important}.mt-lg-2{margin-top:.5rem !important}.mt-lg-3{margin-top:1rem !important}.mt-lg-4{margin-top:1.5rem !important}.mt-lg-5{margin-top:3rem !important}.mt-lg-auto{margin-top:auto !important}.me-lg-0{margin-right:0 !important}.me-lg-1{margin-right:.25rem !important}.me-lg-2{margin-right:.5rem !important}.me-lg-3{margin-right:1rem !important}.me-lg-4{margin-right:1.5rem !important}.me-lg-5{margin-right:3rem !important}.me-lg-auto{margin-right:auto !important}.mb-lg-0{margin-bottom:0 !important}.mb-lg-1{margin-bottom:.25rem !important}.mb-lg-2{margin-bottom:.5rem !important}.mb-lg-3{margin-bottom:1rem !important}.mb-lg-4{margin-bottom:1.5rem !important}.mb-lg-5{margin-bottom:3rem !important}.mb-lg-auto{margin-bottom:auto !important}.ms-lg-0{margin-left:0 !important}.ms-lg-1{margin-left:.25rem !important}.ms-lg-2{margin-left:.5rem !important}.ms-lg-3{margin-left:1rem !important}.ms-lg-4{margin-left:1.5rem !important}.ms-lg-5{margin-left:3rem !important}.ms-lg-auto{margin-left:auto !important}.p-lg-0{padding:0 !important}.p-lg-1{padding:.25rem !important}.p-lg-2{padding:.5rem !important}.p-lg-3{padding:1rem !important}.p-lg-4{padding:1.5rem !important}.p-lg-5{padding:3rem !important}.px-lg-0{padding-right:0 !important;padding-left:0 !important}.px-lg-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-lg-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-lg-3{padding-right:1rem !important;padding-left:1rem !important}.px-lg-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-lg-5{padding-right:3rem !important;padding-left:3rem !important}.py-lg-0{padding-top:0 !important;padding-bottom:0 !important}.py-lg-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-lg-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-lg-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-lg-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-lg-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-lg-0{padding-top:0 !important}.pt-lg-1{padding-top:.25rem !important}.pt-lg-2{padding-top:.5rem !important}.pt-lg-3{padding-top:1rem !important}.pt-lg-4{padding-top:1.5rem !important}.pt-lg-5{padding-top:3rem !important}.pe-lg-0{padding-right:0 !important}.pe-lg-1{padding-right:.25rem !important}.pe-lg-2{padding-right:.5rem !important}.pe-lg-3{padding-right:1rem !important}.pe-lg-4{padding-right:1.5rem !important}.pe-lg-5{padding-right:3rem !important}.pb-lg-0{padding-bottom:0 !important}.pb-lg-1{padding-bottom:.25rem !important}.pb-lg-2{padding-bottom:.5rem !important}.pb-lg-3{padding-bottom:1rem !important}.pb-lg-4{padding-bottom:1.5rem !important}.pb-lg-5{padding-bottom:3rem !important}.ps-lg-0{padding-left:0 !important}.ps-lg-1{padding-left:.25rem !important}.ps-lg-2{padding-left:.5rem !important}.ps-lg-3{padding-left:1rem !important}.ps-lg-4{padding-left:1.5rem !important}.ps-lg-5{padding-left:3rem !important}.text-lg-start{text-align:left !important}.text-lg-end{text-align:right !important}.text-lg-center{text-align:center !important}}@media (min-width: 1200px){.float-xl-start{float:left !important}.float-xl-end{float:right !important}.float-xl-none{float:none !important}.d-xl-inline{display:inline !important}.d-xl-inline-block{display:inline-block !important}.d-xl-block{display:block !important}.d-xl-grid{display:grid !important}.d-xl-table{display:table !important}.d-xl-table-row{display:table-row !important}.d-xl-table-cell{display:table-cell !important}.d-xl-flex{display:flex !important}.d-xl-inline-flex{display:inline-flex !important}.d-xl-none{display:none !important}.flex-xl-fill{flex:1 1 auto !important}.flex-xl-row{flex-direction:row !important}.flex-xl-column{flex-direction:column !important}.flex-xl-row-reverse{flex-direction:row-reverse !important}.flex-xl-column-reverse{flex-direction:column-reverse !important}.flex-xl-grow-0{flex-grow:0 !important}.flex-xl-grow-1{flex-grow:1 !important}.flex-xl-shrink-0{flex-shrink:0 !important}.flex-xl-shrink-1{flex-shrink:1 !important}.flex-xl-wrap{flex-wrap:wrap !important}.flex-xl-nowrap{flex-wrap:nowrap !important}.flex-xl-wrap-reverse{flex-wrap:wrap-reverse !important}.gap-xl-0{gap:0 !important}.gap-xl-1{gap:.25rem !important}.gap-xl-2{gap:.5rem !important}.gap-xl-3{gap:1rem !important}.gap-xl-4{gap:1.5rem !important}.gap-xl-5{gap:3rem !important}.justify-content-xl-start{justify-content:flex-start !important}.justify-content-xl-end{justify-content:flex-end !important}.justify-content-xl-center{justify-content:center !important}.justify-content-xl-between{justify-content:space-between !important}.justify-content-xl-around{justify-content:space-around !important}.justify-content-xl-evenly{justify-content:space-evenly !important}.align-items-xl-start{align-items:flex-start !important}.align-items-xl-end{align-items:flex-end !important}.align-items-xl-center{align-items:center !important}.align-items-xl-baseline{align-items:baseline !important}.align-items-xl-stretch{align-items:stretch !important}.align-content-xl-start{align-content:flex-start !important}.align-content-xl-end{align-content:flex-end !important}.align-content-xl-center{align-content:center !important}.align-content-xl-between{align-content:space-between !important}.align-content-xl-around{align-content:space-around !important}.align-content-xl-stretch{align-content:stretch !important}.align-self-xl-auto{align-self:auto !important}.align-self-xl-start{align-self:flex-start !important}.align-self-xl-end{align-self:flex-end !important}.align-self-xl-center{align-self:center !important}.align-self-xl-baseline{align-self:baseline !important}.align-self-xl-stretch{align-self:stretch !important}.order-xl-first{order:-1 !important}.order-xl-0{order:0 !important}.order-xl-1{order:1 !important}.order-xl-2{order:2 !important}.order-xl-3{order:3 !important}.order-xl-4{order:4 !important}.order-xl-5{order:5 !important}.order-xl-last{order:6 !important}.m-xl-0{margin:0 !important}.m-xl-1{margin:.25rem !important}.m-xl-2{margin:.5rem !important}.m-xl-3{margin:1rem !important}.m-xl-4{margin:1.5rem !important}.m-xl-5{margin:3rem !important}.m-xl-auto{margin:auto !important}.mx-xl-0{margin-right:0 !important;margin-left:0 !important}.mx-xl-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-xl-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-xl-3{margin-right:1rem !important;margin-left:1rem !important}.mx-xl-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-xl-5{margin-right:3rem !important;margin-left:3rem !important}.mx-xl-auto{margin-right:auto !important;margin-left:auto !important}.my-xl-0{margin-top:0 !important;margin-bottom:0 !important}.my-xl-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-xl-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-xl-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-xl-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-xl-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-xl-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-xl-0{margin-top:0 !important}.mt-xl-1{margin-top:.25rem !important}.mt-xl-2{margin-top:.5rem !important}.mt-xl-3{margin-top:1rem !important}.mt-xl-4{margin-top:1.5rem !important}.mt-xl-5{margin-top:3rem !important}.mt-xl-auto{margin-top:auto !important}.me-xl-0{margin-right:0 !important}.me-xl-1{margin-right:.25rem !important}.me-xl-2{margin-right:.5rem !important}.me-xl-3{margin-right:1rem !important}.me-xl-4{margin-right:1.5rem !important}.me-xl-5{margin-right:3rem !important}.me-xl-auto{margin-right:auto !important}.mb-xl-0{margin-bottom:0 !important}.mb-xl-1{margin-bottom:.25rem !important}.mb-xl-2{margin-bottom:.5rem !important}.mb-xl-3{margin-bottom:1rem !important}.mb-xl-4{margin-bottom:1.5rem !important}.mb-xl-5{margin-bottom:3rem !important}.mb-xl-auto{margin-bottom:auto !important}.ms-xl-0{margin-left:0 !important}.ms-xl-1{margin-left:.25rem !important}.ms-xl-2{margin-left:.5rem !important}.ms-xl-3{margin-left:1rem !important}.ms-xl-4{margin-left:1.5rem !important}.ms-xl-5{margin-left:3rem !important}.ms-xl-auto{margin-left:auto !important}.p-xl-0{padding:0 !important}.p-xl-1{padding:.25rem !important}.p-xl-2{padding:.5rem !important}.p-xl-3{padding:1rem !important}.p-xl-4{padding:1.5rem !important}.p-xl-5{padding:3rem !important}.px-xl-0{padding-right:0 !important;padding-left:0 !important}.px-xl-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-xl-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-xl-3{padding-right:1rem !important;padding-left:1rem !important}.px-xl-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-xl-5{padding-right:3rem !important;padding-left:3rem !important}.py-xl-0{padding-top:0 !important;padding-bottom:0 !important}.py-xl-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-xl-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-xl-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-xl-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-xl-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-xl-0{padding-top:0 !important}.pt-xl-1{padding-top:.25rem !important}.pt-xl-2{padding-top:.5rem !important}.pt-xl-3{padding-top:1rem !important}.pt-xl-4{padding-top:1.5rem !important}.pt-xl-5{padding-top:3rem !important}.pe-xl-0{padding-right:0 !important}.pe-xl-1{padding-right:.25rem !important}.pe-xl-2{padding-right:.5rem !important}.pe-xl-3{padding-right:1rem !important}.pe-xl-4{padding-right:1.5rem !important}.pe-xl-5{padding-right:3rem !important}.pb-xl-0{padding-bottom:0 !important}.pb-xl-1{padding-bottom:.25rem !important}.pb-xl-2{padding-bottom:.5rem !important}.pb-xl-3{padding-bottom:1rem !important}.pb-xl-4{padding-bottom:1.5rem !important}.pb-xl-5{padding-bottom:3rem !important}.ps-xl-0{padding-left:0 !important}.ps-xl-1{padding-left:.25rem !important}.ps-xl-2{padding-left:.5rem !important}.ps-xl-3{padding-left:1rem !important}.ps-xl-4{padding-left:1.5rem !important}.ps-xl-5{padding-left:3rem !important}.text-xl-start{text-align:left !important}.text-xl-end{text-align:right !important}.text-xl-center{text-align:center !important}}@media (min-width: 1400px){.float-xxl-start{float:left !important}.float-xxl-end{float:right !important}.float-xxl-none{float:none !important}.d-xxl-inline{display:inline !important}.d-xxl-inline-block{display:inline-block !important}.d-xxl-block{display:block !important}.d-xxl-grid{display:grid !important}.d-xxl-table{display:table !important}.d-xxl-table-row{display:table-row !important}.d-xxl-table-cell{display:table-cell !important}.d-xxl-flex{display:flex !important}.d-xxl-inline-flex{display:inline-flex !important}.d-xxl-none{display:none !important}.flex-xxl-fill{flex:1 1 auto !important}.flex-xxl-row{flex-direction:row !important}.flex-xxl-column{flex-direction:column !important}.flex-xxl-row-reverse{flex-direction:row-reverse !important}.flex-xxl-column-reverse{flex-direction:column-reverse !important}.flex-xxl-grow-0{flex-grow:0 !important}.flex-xxl-grow-1{flex-grow:1 !important}.flex-xxl-shrink-0{flex-shrink:0 !important}.flex-xxl-shrink-1{flex-shrink:1 !important}.flex-xxl-wrap{flex-wrap:wrap !important}.flex-xxl-nowrap{flex-wrap:nowrap !important}.flex-xxl-wrap-reverse{flex-wrap:wrap-reverse !important}.gap-xxl-0{gap:0 !important}.gap-xxl-1{gap:.25rem !important}.gap-xxl-2{gap:.5rem !important}.gap-xxl-3{gap:1rem !important}.gap-xxl-4{gap:1.5rem !important}.gap-xxl-5{gap:3rem !important}.justify-content-xxl-start{justify-content:flex-start !important}.justify-content-xxl-end{justify-content:flex-end !important}.justify-content-xxl-center{justify-content:center !important}.justify-content-xxl-between{justify-content:space-between !important}.justify-content-xxl-around{justify-content:space-around !important}.justify-content-xxl-evenly{justify-content:space-evenly !important}.align-items-xxl-start{align-items:flex-start !important}.align-items-xxl-end{align-items:flex-end !important}.align-items-xxl-center{align-items:center !important}.align-items-xxl-baseline{align-items:baseline !important}.align-items-xxl-stretch{align-items:stretch !important}.align-content-xxl-start{align-content:flex-start !important}.align-content-xxl-end{align-content:flex-end !important}.align-content-xxl-center{align-content:center !important}.align-content-xxl-between{align-content:space-between !important}.align-content-xxl-around{align-content:space-around !important}.align-content-xxl-stretch{align-content:stretch !important}.align-self-xxl-auto{align-self:auto !important}.align-self-xxl-start{align-self:flex-start !important}.align-self-xxl-end{align-self:flex-end !important}.align-self-xxl-center{align-self:center !important}.align-self-xxl-baseline{align-self:baseline !important}.align-self-xxl-stretch{align-self:stretch !important}.order-xxl-first{order:-1 !important}.order-xxl-0{order:0 !important}.order-xxl-1{order:1 !important}.order-xxl-2{order:2 !important}.order-xxl-3{order:3 !important}.order-xxl-4{order:4 !important}.order-xxl-5{order:5 !important}.order-xxl-last{order:6 !important}.m-xxl-0{margin:0 !important}.m-xxl-1{margin:.25rem !important}.m-xxl-2{margin:.5rem !important}.m-xxl-3{margin:1rem !important}.m-xxl-4{margin:1.5rem !important}.m-xxl-5{margin:3rem !important}.m-xxl-auto{margin:auto !important}.mx-xxl-0{margin-right:0 !important;margin-left:0 !important}.mx-xxl-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-xxl-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-xxl-3{margin-right:1rem !important;margin-left:1rem !important}.mx-xxl-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-xxl-5{margin-right:3rem !important;margin-left:3rem !important}.mx-xxl-auto{margin-right:auto !important;margin-left:auto !important}.my-xxl-0{margin-top:0 !important;margin-bottom:0 !important}.my-xxl-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-xxl-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-xxl-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-xxl-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-xxl-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-xxl-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-xxl-0{margin-top:0 !important}.mt-xxl-1{margin-top:.25rem !important}.mt-xxl-2{margin-top:.5rem !important}.mt-xxl-3{margin-top:1rem !important}.mt-xxl-4{margin-top:1.5rem !important}.mt-xxl-5{margin-top:3rem !important}.mt-xxl-auto{margin-top:auto !important}.me-xxl-0{margin-right:0 !important}.me-xxl-1{margin-right:.25rem !important}.me-xxl-2{margin-right:.5rem !important}.me-xxl-3{margin-right:1rem !important}.me-xxl-4{margin-right:1.5rem !important}.me-xxl-5{margin-right:3rem !important}.me-xxl-auto{margin-right:auto !important}.mb-xxl-0{margin-bottom:0 !important}.mb-xxl-1{margin-bottom:.25rem !important}.mb-xxl-2{margin-bottom:.5rem !important}.mb-xxl-3{margin-bottom:1rem !important}.mb-xxl-4{margin-bottom:1.5rem !important}.mb-xxl-5{margin-bottom:3rem !important}.mb-xxl-auto{margin-bottom:auto !important}.ms-xxl-0{margin-left:0 !important}.ms-xxl-1{margin-left:.25rem !important}.ms-xxl-2{margin-left:.5rem !important}.ms-xxl-3{margin-left:1rem !important}.ms-xxl-4{margin-left:1.5rem !important}.ms-xxl-5{margin-left:3rem !important}.ms-xxl-auto{margin-left:auto !important}.p-xxl-0{padding:0 !important}.p-xxl-1{padding:.25rem !important}.p-xxl-2{padding:.5rem !important}.p-xxl-3{padding:1rem !important}.p-xxl-4{padding:1.5rem !important}.p-xxl-5{padding:3rem !important}.px-xxl-0{padding-right:0 !important;padding-left:0 !important}.px-xxl-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-xxl-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-xxl-3{padding-right:1rem !important;padding-left:1rem !important}.px-xxl-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-xxl-5{padding-right:3rem !important;padding-left:3rem !important}.py-xxl-0{padding-top:0 !important;padding-bottom:0 !important}.py-xxl-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-xxl-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-xxl-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-xxl-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-xxl-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-xxl-0{padding-top:0 !important}.pt-xxl-1{padding-top:.25rem !important}.pt-xxl-2{padding-top:.5rem !important}.pt-xxl-3{padding-top:1rem !important}.pt-xxl-4{padding-top:1.5rem !important}.pt-xxl-5{padding-top:3rem !important}.pe-xxl-0{padding-right:0 !important}.pe-xxl-1{padding-right:.25rem !important}.pe-xxl-2{padding-right:.5rem !important}.pe-xxl-3{padding-right:1rem !important}.pe-xxl-4{padding-right:1.5rem !important}.pe-xxl-5{padding-right:3rem !important}.pb-xxl-0{padding-bottom:0 !important}.pb-xxl-1{padding-bottom:.25rem !important}.pb-xxl-2{padding-bottom:.5rem !important}.pb-xxl-3{padding-bottom:1rem !important}.pb-xxl-4{padding-bottom:1.5rem !important}.pb-xxl-5{padding-bottom:3rem !important}.ps-xxl-0{padding-left:0 !important}.ps-xxl-1{padding-left:.25rem !important}.ps-xxl-2{padding-left:.5rem !important}.ps-xxl-3{padding-left:1rem !important}.ps-xxl-4{padding-left:1.5rem !important}.ps-xxl-5{padding-left:3rem !important}.text-xxl-start{text-align:left !important}.text-xxl-end{text-align:right !important}.text-xxl-center{text-align:center !important}}@media (min-width: 1200px){.fs-1{font-size:1.40625rem !important}}@media print{.d-print-inline{display:inline !important}.d-print-inline-block{display:inline-block !important}.d-print-block{display:block !important}.d-print-grid{display:grid !important}.d-print-table{display:table !important}.d-print-table-row{display:table-row !important}.d-print-table-cell{display:table-cell !important}.d-print-flex{display:flex !important}.d-print-inline-flex{display:inline-flex !important}.d-print-none{display:none !important}}body{background-size:cover}.bg-light{background-color:Rgb(var(--t42-bg-light)) !important}.bg-dark{background-color:Rgb(var(--t42-bg-dark)) !important}.bg-base{background-color:Rgb(var(--t42-bg-mid)) !important}.border{border:0.0625rem solid var(--t42-color-opacity-10) !important}.border-primary{border-color:#007be5 !important}.border-secondary,.border-info,.border-light,.border-dark,.border-white{border-color:var(--t42-color-opacity-10) !important}.border-success{border-color:#43a047 !important}.border-danger{border-color:#ff511f !important}.border-warning{border-color:#f9a825 !important}.pl-0{padding-left:0}.pl-1{padding-left:0.25rem}.pl-2{padding-left:0.5rem}.pl-3{padding-left:1rem}.pl-4{padding-left:1.5rem}.pl-5{padding-left:3rem}.pl-auto{padding-left:auto}.pr-0{padding-right:0}.pr-1{padding-right:0.25rem}.pr-2{padding-right:0.5rem}.pr-3{padding-right:1rem}.pr-4{padding-right:1.5rem}.pr-5{padding-right:3rem}.pr-auto{padding-right:auto}.ml-0{margin-left:0}.ml-1{margin-left:0.25rem}.ml-2{margin-left:0.5rem}.ml-3{margin-left:1rem}.ml-4{margin-left:1.5rem}.ml-5{margin-left:3rem}.ml-auto{margin-left:auto}.mr-0{margin-right:0}.mr-1{margin-right:0.25rem}.mr-2{margin-right:0.5rem}.mr-3{margin-right:1rem}.mr-4{margin-right:1.5rem}.mr-5{margin-right:3rem}.mr-auto{margin-right:auto}@keyframes spinner-border{to{transform:rotate(360deg) /* rtl:ignore */}}.spinner-border{display:inline-block;width:2rem;height:2rem;vertical-align:-.125em;border:.25em solid currentColor;border-right-color:transparent;border-radius:50%;animation:.75s linear infinite spinner-border}.spinner-border-sm{width:1rem;height:1rem;border-width:.2em}@keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1;transform:none}}.spinner-grow{display:inline-block;width:2rem;height:2rem;vertical-align:-.125em;background-color:currentColor;border-radius:50%;opacity:0;animation:.75s linear infinite spinner-grow}.spinner-grow-sm{width:1rem;height:1rem}@media (prefers-reduced-motion: reduce){.spinner-border,.spinner-grow{animation-duration:1.5s}}.loader-wrapper{display:flex;flex-direction:column;flex-grow:1;gap:1rem;align-items:center;justify-content:center}.loader-wrapper .loader{width:2rem;height:2rem;border-radius:50%;background:radial-gradient(farthest-side, #999d9e 94%, rgba(0,0,0,0)) center top/4px 4px no-repeat,conic-gradient(rgba(0,0,0,0) 15%, #999d9e);-webkit-mask:radial-gradient(farthest-side, rgba(0,0,0,0) calc(100% - 4px), #000 0)}.loader-wrapper.active .loader{animation:s3 1.5s infinite linear}@keyframes s3{to{transform:rotate(1turn)}}.loader-wrapper .loader-text{margin:0 auto;padding:0 0.833rem;overflow:hidden;color:var(--t42-content-color-muted);text-align:center;text-overflow:ellipsis}@keyframes clipMe{0%,100%{clip:rect(0, 220px, 2px, 0)}25%{clip:rect(0, 2px, 220px, 0)}50%{clip:rect(218px, 220px, 220px, 0)}75%{clip:rect(0, 220px, 220px, 218px)}}@keyframes spin{from{transform:rotate(0deg)}to{transform:rotate(360deg)}}.spinner{display:inline-block;animation-name:spin;animation-duration:3000ms;animation-timing-function:linear;animation-iteration-count:infinite}@font-face{font-weight:400;font-family:"Montserrat";font-style:normal;src:url(data:font/ttf;base64,AAEAAAARAQAABAAQR0RFRrFss1wAAmssAAACfkdQT1N2Wb7+AAJtrAABFy5HU1VCjJZZRgADhNwAAC8mT1MvMlYMpE4AAfmwAAAAYGNtYXBfILVpAAH6EAAACuRjdnQgMKUWggACEzwAAADkZnBnbU0kjnwAAgT0AAANbWdhc3AAAAAQAAJrJAAAAAhnbHlmzhsdpQAAARwAAct0aGVhZA5QtXgAAduUAAAANmhoZWEG0AwiAAH5jAAAACRobXR4v8HBsgAB28wAAB3AbG9jYfsbiDIAAcywAAAO4m1heHAIxQ5XAAHMkAAAACBuYW1lKqFFSQACFCAAAAHucG9zdFa6PIcAAhYQAABVE3ByZXDNS6zAAAISZAAAANUAAgAoAAACIwK8AAMABwApQCYAAAACAwACZQQBAwEBA1UEAQMDAV0AAQMBTQQEBAcEBxIREAUNFysTIREhJREhESgB+/4FAav+pQK8/URGAjD90AAAAv//AAAC3QK8AAcACgArQCgJAQQCAUoFAQQAAAEEAGYAAgJCSwMBAQFDAUwICAgKCAoREREQBgoYKyUhByMBMwEjJwMDAif+jE1nAT1jAT5pcJeXr68CvP1E/wFX/qn/////AAAC3QN3ACIABAAAAAMHEgKaAAD/////AAAC3QN3ACIABAAAAAMHGQKaAAD/////AAAC3QPhACIABAAAACcHMQKaAJYBBwcuApoBEQARsQIBsJawMyuxAwG4ARGwMysA//////88At0DdwAiAAQAAAAjBv8CmgAAAAMHGQKaAAD/////AAAC3QPhACIABAAAACcHMQKaAJYBBwctApoBEQARsQIBsJawMyuxAwG4ARGwMysA/////wAAAt0D7QAiAAQAAAAnBzECmgCWAQcHNAKaAP4AELECAbCWsDMrsQMBsP6wMyv/////AAAC3QPgACIABAAAACcHMQKaAJYBBwcyApoBEQARsQIBsJawMyuxAwG4ARGwMysA/////wAAAt0DdwAiAAQAAAADBxcCmgAA/////wAAAt0DdwAiAAQAAAADBxYCmgAA/////wAAAt0DvgAiAAQAAAAnBy8CmgCWAQcHLgNCAO4AELECAbCWsDMrsQMBsO6wMyv//////zwC3QN3ACIABAAAACMG/wKaAAAAAwcWApoAAP////8AAALdA74AIgAEAAAAJwcvApoAlgEHBy0DQgDuABCxAgGwlrAzK7EDAbDusDMr/////wAAAt0D0wAiAAQAAAAnBy8CmgCWAQcHNAMcAOQAELECAbCWsDMrsQMBsOSwMyv/////AAAC3QPmACIABAAAACcHLwKaAJYBBwcyApoBFwARsQIBsJawMyuxAwG4ARewMysA/////wAAAt0DdwAiAAQAAAADByMCmgAA/////wAAAt0DbQAiAAQAAAADBwoCmgAA//////88At0CvAAiAAQAAAADBv8CmgAA/////wAAAt0DdwAiAAQAAAADBxACmgAA/////wAAAt0DuwAiAAQAAAADByICmgAA/////wAAAt0DfQAiAAQAAAADByQCmgAA/////wAAAt0DVAAiAAQAAAADBx4CmgAA//////8gAvMCvAAiAAQAAAADBwMECAAA/////wAAAt0D1gAiAAQAAAEHBvACmgCqAAixAgKwqrAzK/////8AAALdBB0AIgAEAAABBwbxApoAqgAIsQICsKqwMyv/////AAAC3QN3ACIABAAAAAMHGgKaAAAAAv//AAAD3wK8AA8AEwBEQEEABQAGCQUGZQsBCQABBwkBZQgBBAQDXQADA0JLCgEHBwBdAgEAAEMATBAQAAAQExATEhEADwAPEREREREREQwKGyslFSE1IQcjASEVIRUhFSEVJxEjAwPf/gT+6mdnAaECMf51AV/+oWMU01dXr68CvFfXVeKoAWb+mv////8AAAPfA3cAIgAeAAAAAwcSA0AAAAADAGkAAALDArwADgAXAB8APEA5DgEEAgFKAAIABAUCBGUGAQMDAV0AAQFCSwcBBQUAXQAAAEMATBgYDw8YHxgeHRsPFw8WJyEkCAoXKwAWFRQGIyERITIWFRQGBwEVMzI2NTQmIxI2NTQjIxUzAn1GiYP+sgE6eIMzK/6NzU1TU01uVqvm5gFaWURbYgK8YFU3UBUBAOA5Nzc5/eY4PHXpAAABADD/+AKtAsQAGwAuQCsYFwsKBAIBAUoAAQEAXwAAAEhLAAICA18EAQMDSQNMAAAAGwAaJiQmBQoXKwQmJjU0NjYzMhYXByYjIgYGFRQWFjMyNxcGBiMBOalgYKppUogwQU92Tn5HR35OdVBBMIlSCF2jZmajXTc2P1NGe0xMe0ZUPzY4//8AMP/4Aq0DdwAiACEAAAADBxICxwAA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BwcDUQBzAAixAQGwc7AzK///AGn/LwLDArwAIgBSAAAAAwcEAsEAAP//AGkAAALDA3cAIgBSAAAAAwcXAsEAAP//AGkAAALDA3cAIgBSAAAAAwcWAsEAAP//AGn/PALDArwAIgBSAAAAAwb/AsEAAAABAGkAAADNArwAAwATQBAAAABCSwABAUMBTBEQAgoWKxMzESNpZGQCvP1EAAIAV//4Am0CvAAPABMAM0AwAwEABAIBAgACSgAEBAFdAwEBAUJLAAAAAl8FAQICSQJMAAATEhEQAA8ADhMlBgoWKwQmJzcWFjMyNjURMxEUBiMDMxEjAQN8MCcsaDdeYmSeiORkZAgmIVAeIG5vAY7+d5miAsT+eQD//wBQAAABUgN3ACIAWAAAAAMHEgHHAAD////5AAABPQN3ACIAWAAAAAMHGQHHAAD////oAAABTgN3ACIAWAAAAAMHFgHHAAD///+uAAABGwN3ACIAWAAAAAMHIwHHAAD//wALAAABKwNtACIAWAAAAAMHCgHHAAD//wAPAAABOQP0ACIAWAAAACcHKwHHAJYBBwcuAccBJAARsQECsJawMyuxAwG4ASSwMysA//8AYAAAANYDfQAiAFgAAAADBw4BxwAA//8AaP88AM4CvAAiAFgAAAADBv8BxwAA////5AAAAOYDdwAiAFgAAAADBxABxwAA//8APwAAAQADuwAiAFgAAAADByIBxwAA////+QAAAT0DfQAiAFgAAAADByQBxwAA//8AFgAAASADVAAiAFgAAAADBygBxwAA//8ATv8gAPECvAAiAFgAAAADByoB+AAA////8wAAAUMDdwAiAFgAAAADBxoBxwAAAAH/9//4AZ4CvAAQACxAKQMCAgABAUoAAQECXQACAkJLAAAAA18EAQMDSQNMAAAAEAAPERMkBQoXKxYmJzcWMzI2NREjNSERFAYjhGwhOjpYOz39AWBvbAg1MERTSEYBiVf+JXR1////9//4AaIDdwAiAGgAAAADBxYCGwAAAAEAaQAAAs4CvAALAB9AHAkGAQMAAQFKAgEBAUJLAwEAAEMATBISERIEChgrAQcVIxEzEQEzAQEjAU2AZGQBfHL+1QE+dQE3grUCvP55AYf+xf5///8AaQAAAs4DdwAiAGoAAAADBxcCowAA//8Aaf75As4CvAAiAGoAAAADBwECowAA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KAcKGSsBERQGBwYVFBYzMjY3FwYjIiY1NDcmJjURMxEUMzI2NRECs15XkCIcECEMEygyOEBFf41kxWBmArz+cnaSHjNJGBwJCDEYNy5DMQifjgGO/nbhb3IBigD//wBj//gCswPWACIAxwAAAQcG8AK4AKoACLEBArCqsDMr//8AY//4ArMDdwAiAMcAAAADBxoCuAAA//8AY//4ArMD9AAiAMcAAAAnBzICuACWAQcHLgK4ASQAEbEBAbCWsDMrsQIBuAEksDMrAAAB//8AAALJArwABgAhQB4FAQABAUoDAgIBAUJLAAAAQwBMAAAABgAGEREEChYrAQEjATMTEwLJ/s1j/sxs/P4CvP1EArz9wQI/AAEAIAAABEYCvAAMACdAJAsIAwMAAgFKBQQDAwICQksBAQAAQwBMAAAADAAMEhESEQYKGCsBAyMDAyMDMxMTMxMTBEbqab+/a+pnvcVcwcECvP1EAi/90QK8/ccCOf3EAjz//wAgAAAERgN3ACIA4AAAAAMHEgNgAAD//wAgAAAERgN3ACIA4AAAAAMHFgNgAAD//wAgAAAERgNtACIA4AAAAAMHCgNgAAD//wAgAAAERgN3ACIA4AAAAAMHEANgAAAAAQANAAAClAK8AAsAJkAjCgcEAQQAAQFKAgEBAUJLBAMCAABDAEwAAAALAAsSEhIFChcrIQMDIwEDMxMTMwMBAiHSz3MBB/dyxMJt9wEJASH+3wFnAVX+8wEN/q7+lgAAAf/8AAACiwK8AAgAHUAaBgMAAwABAUoCAQEBQksAAABDAEwSEhEDChcrJRUjNQEzExMzAXVj/upr4OFj8vL0Acj+jwFx/////AAAAosDdwAiAOYAAAADBxICcAAA/////AAAAosDdwAiAOYAAAADBxYCcAAA/////AAAAosDbQAiAOYAAAADBwoCcAAA/////AAAAosDfQAiAOYAAAADBw4CcAAA/////P88AosCvAAiAOYAAAADBv8CcAAA/////AAAAosDdwAiAOYAAAADBxACcAAA/////AAAAosDuwAiAOYAAAADByICcAAA/////AAAAosDVAAiAOYAAAADBx4CcAAA/////AAAAosDdwAiAOYAAAADBxoCcAAAAAEAKwAAAnQCvAAJAC9ALAgBAQIDAQADAkoAAQECXQACAkJLBAEDAwBdAAAAQwBM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AfIAxAAIsQEBsMSwMyv//wBb/y8CUgLmACIB2AAAAAMHBAKDAAD////YAAACUgO1ACIB2AAAAQcG7QG3ANQACLEBAbDUsDMr////2AAAAlIDoQAiAdgAAAEHBxYBtwAqAAixAQGwKrAzK///AFv/PAJSAuYAIgHYAAAAAwb/AoMAAP//AEoAAADMAvUAIgHfAAAAAwcpAbcAAAABAFsAAAC7AhIAAwATQBAAAABFSwABAUMBTBEQAgoWKxMzESNbYGACEv3u//8AQAAAAUIC4QAiAd8AAAADBucBtwAA//8AAgAAARQC4QAiAd8AAAADBzcBtwAA////8QAAASUC4QAiAd8AAAADBzYBtwAA////ngAAAQsC4QAiAd8AAAADBvsBtwAA//8AEgAAAQQC1gAiAd8AAAADBzUBtwAA/////wAAASkDXgAiAd8AAAAjBysBtwAAAQcHLgG3AI4ACLEDAbCOsDMr//8AUAAAAMYC5wAiAd8AAAADBuMBtwAA//8ASv88AMwC9QAiAd8AAAAjBykBtwAAAAMG/wG3AAD////UAAAA1gLhACIB3wAAAAMG5QG3AAD//wAvAAAA8AMlACIB3wAAAAMG+gG3AAD//wACAAABFALnACIB3wAAAAMHOgG3AAD//wBK/zgB6AL1ACIB3wAAACMHKQG3AAAAIwHwARcAAAADBykC0wAA//8ABgAAARACvgAiAd8AAAADBzkBtwAA//8APP8gAN8C9QAiAd8AAAAjBykBtwAAAAMHKgHmAAD////8AAABGgLhACIB3wAAAAMHOAG3AAD///+k/zgA0QL1ACIB8AAAAAMHKQG8AAAAAf+k/zgAwAISAA4AKUAmAwEAAQIBAgACSgABAUVLAAAAAmADAQICTQJMAAAADgANEyQEChYrBiYnNxYzMjY1ETMRFAYjDDwUHx4wJilgWFHIEBBKGS8uAiz91lJe////pP84ASoC4QAiAfAAAAADBzYBvAAAAAEAWwAAAmYC5gALACNAIAkGAQMAAgFKAAEBREsAAgJFSwMBAABDAEwSEhESBAoYKyUHFSMRMxEBMwcTIwEpbmBgASF03/V292aRAub+JAEI2/7J////2AAAAmYDtQAiAfIAAAEHBu0BtwDUAAixAQGw1LAzK///AFv++QJmAuYAIgHyAAAAAwcBAmUAAAABAFsAAAJm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yNQBDP70/////wAAAmgDBwAiAt8AAAEHBucCXwAmAAixAgGwJrAzK/////8AAAJoAwcAIgLfAAABBwbvAl8AJgAIsQIBsCawMyv/////AAACaANxACIC3wAAACcHMQJfACYBBwcuAl8AoQAQsQIBsCawMyuxAwGwobAzK///////PAJoAwcAIgLfAAAAIwb/Al8AAAEHBu8CXwAmAAixAwGwJrAzK/////8AAAJoA3EAIgLfAAAAJwcxAl8AJgEHBy0CXwChABCxAgGwJrAzK7EDAbChsDMr/////wAAAmgDfQAiAt8AAAAnBzECXwAmAQcHNAJfAI4AELECAbAmsDMrsQMBsI6wMyv/////AAACaANwACIC3wAAACcHMQJfACYBBwcyAl8AoQAQsQIBsCawMyuxAwGwobAzK/////8AAAJoAwcAIgLfAAABBwbtAl8AJgAIsQIBsCawMyv/////AAACaAMHACIC3wAAAQcG7AJfACYACLECAbAmsDMr/////wAAAnkDTgAiAt8AAAAnBy8CXwAmAQcHLgMHAH4AELECAbAmsDMrsQMBsH6wMyv//////zwCaAMHACIC3wAAACMG/wJfAAABBwbsAl8AJgAIsQMBsCawMyv/////AAACaANOACIC3wAAACcHLwJfACYBBwctAwcAfgAQsQIBsCawMyuxAwGwfrAzK/////8AAAJoA2MAIgLfAAAAJwcvAl8AJgEHBzQC4QB0ABCxAgGwJrAzK7EDAbB0sDMr/////wAAAmgDdgAiAt8AAAAnBy8CXwAmAQcHMgJfAKcAELECAbAmsDMrsQMBsKewMyv/////AAACaAMHACIC3wAAAQcG+wJfACYACLECArAmsDMr/////wAAAmgC/QAiAt8AAAEHBt8CXwAmAAixAgKwJrAzK///////PAJoAjgAIgLfAAAAAwb/Al8AAP////8AAAJoAwcAIgLfAAABBwblAl8AJgAIsQIBsCawMyv/////AAACaANLACIC3wAAAQcG+gJfACYACLECAbAmsDMr/////wAAAmgDDQAiAt8AAAEHBvwCXwAmAAixAgGwJrAzK/////8AAAJoAuQAIgLfAAABBwb2Al8AJgAIsQIBsCawMyv//////yACfgI4ACIC3wAAAAMHAwOTAAD/////AAACaANSACIC3wAAAQcG8AJf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VAD////w/zgCNgISAAICbwYA////8P84AjYC4QAiAm8GAAADB1gB8AAAAAMAK/8+AvoC5gARABgAHgA3QDQeAQAGAUoABAMEgwgBBwcDXwUBAwMiSwAGBgBfAgEAACFLAAEBJAFMFhEUEREUERERCQcdKyQGBxUjNSYmNTQ2NzUzFRYWFQQWFxEGBhUENTQmJxEC+qSVXpWjopZelaT9kG1sbWwCEW5sj44Iu7sIjXx7igjPzwiLelVgBwF0B15TrKxUXQf+iwD//wAJAAACFQISAAICbvsAAAEAKgAAAgQCEgARAC9ALBABAwIDAQEDAkoAAwABAAMBZwUEAgICIksAAAAhAEwAAAARABEjEyIRBgcYKwERIzUGIyImNTUzFRQWMzI3NQIEYFZVY2xgRT5GUQIS/e7WKFxcrKY3OCPyAAABAF3/gQKTAhIACwApQCYAAAMAUgQBAgIiSwYFAgMDAV4AAQEhAUwAAAALAAsREREREQcHGSslFSM1IREzESERMxECk1v+JWABImBU038CEv5CAb7+QgAAAQBdAAADUAISAAsAJUAiBgUDAwEBIksEAQICAF4AAAAhAEwAAAALAAsREREREQcHGSsBESERMxEzETMRMxEDUP0NYOpg6QIS/e4CEv5CAb7+QgG+AP//AF3/jwOfAhIAIgUmAAAAAwdaArIAAAABAF3/gQIoAhIACwBGS7AKUFhAGAABAAABbwUBAwMiSwAEBABeAgEAACEATBtAFwABAAGEBQEDAyJLAAQEAF4CAQAAIQBMWUAJEREREREQBgcaKyEjFSM1IxEzESERMwIot1u5YAELYH9/AhL+QgG+AAACAF3//gIhAhIACgATADBALQUBAgADBAIDZQABASJLBgEEBABeAAAAIQBMCwsAAAsTCxIRDwAKAAkRJAcHFisAFhUUBicnETMVFxI2NTQmJycVFwG3anNr5mCVKkNBQ35+AV1aUlZdAQECErMB/uk2NTQwAQLQAQACAAQAAAJhAhIADAAVADZAMwYBAwAEBQMEZQABAQJdAAICIksHAQUFAF0AAAAhAEwNDQAADRUNFBMRAAwACxERJAgHFysAFhUUBiMjESM1IRUzEjY1NCYjIxUzAfhpc2nfogECkCpAPz98fAFfW1JVXQG+VLP+6jY1MzHPAAADAF3//gLJAhIACgAOABcANkAz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hAMBAgIBXQABASEBTAAAAAUABRERBAcWKzcVIzUjNfpccVfwmVcAAQA6/2cA2wBXAAUAH0AcAAABAIQDAQICAV0AAQEhAUwAAAAFAAUREQQHFis3FSM1IzXbXURX8JlXAAEAQP+PANoAUgAFADxLsApQWEASAAABAQBvAwECAgFdAAEBIQFMG0ARAAABAIQDAQICAV0AAQEhAUxZQAsAAAAFAAUREQQHFis3FSM1IzXaV0NSw3FSAP///jICWf92A0sAIgcxAAABBgcuAHsACLEBAbB7sDMr///+MgJZ/3YDSwAiBzEAAAEGBy0AewAIsQEBsHuwMyv///4yAln/dgNXACIHMQAAAQYHNABoAAixAQGwaLAzK////i8CWf95A0oAIgcxAAABBgcyAHsACLEBAbB7sDMr///+IQJfABoDKAAiBy8AAAEHBy4AqABYAAixAQGwWLAzK////iECX//BAygAIgcvAAABBwctAKgAWAAIsQEBsFiwMyv///4hAl//pAM9ACIHLwAAAQcHNACCAE4ACLEBAbBOsDMr///+IQJf/4cDUAAiBy8AAAEHBzIAAACBAAixAQGwgbAzK////jIC7/92A+EAJwcxAAAAlgEHBy4AAAERABGxAAGwlrAzK7EBAbgBEbAzKwD///4yAu//dgPhACcHMQAAAJYBBwctAAABEQARsQABsJawMyuxAQG4ARGwMysA///+MgLv/3YD7QAnBzEAAACWAQcHNAAAAP4AELEAAbCWsDMrsQEBsP6wMyv///4vAu//eQPgACcHMQAAAJYBBwcyAAABEQARsQABsJawMyuxAQG4ARGwMysA///+IQL1ABoDvgAnBy8AAACWAQcHLgCoAO4AELEAAbCWsDMrsQEBsO6wMyv///4hAvX/wQO+ACcHLwAAAJYBBwctAKgA7gAQsQABsJawMyuxAQGw7rAzK////iEC9f+kA9MAJwcvAAAAlgEHBzQAggDkABCxAAGwlrAzK7EBAbDksDMr///+IQL1/4cD5gAnBy8AAACWAQcHMgAAARcAEbEAAbCWsDMrsQEBuAEXsDMrAAABAF//ZwC8ABcAAwAYQBUAAQAAAVUAAQEAXQAAAQBNERACBxYrFyM1M7xdXZmwAAABAF7/jwC5ABUAAwAYQBUAAQAAAVUAAQEAXQAAAQBNERACBxYrFyM1M7lb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UXdRg1GUUaVRtlHHUdhR6VICUhtSgFKLUp9SsFLJUuJS+1NDU3xTuVQOVFFUYlRzVH9UkFScVK1UuVUPVSBVOVVBVVJVa1V3VYhVlFWlVbFVxlZEVmNWdFaFVpFWnVauVrpWxlb0VwVXFlcnVzhXSVdaV2ZXd1eIV5lXslfHV+BX+VgSWCNYNFhFWF5YrFi9WM5Y51kLWTxZTVleWW9ZgFmtWdBZ4VnyWgNaFFogWjFaQlpTWmRaklqjWrRaxVrRWw1bHlsvW0hbXVt2W49bqFu5W8pb41v4XBFcKlxDXFRcZVxxXIJck1ykXLVcwVzSXONc9F1ZXWpdf13WXedd+F4JXh5eL15IXl1edl6PXqheuV7KXtte5174XwlfGl8rX0RfXV/pX/pgSGCBYOJg82EEYRVhJmE3YUhhXGGGYY5hn2HtYf5iD2IgYjFiSmJWYmdieGKJYsVi1mLiYvNjKGM5Y0VjpmOyY/dkCGQZZCVkNmRCZKJkrmS6ZMtlFmVAZVFlYmVuZXpli2WXZaNl7WX+Zg9mIGYxZkJmU2ZfZnBmgWaSZqtmwGbZZvJnC2ccZy1nPmdXZ2NndGeFZ55n5mf3aAhoGWgqaHVohmiXaKhouWjKaNto7Gj9aQ5pSWlaaWtpfGmIad9qH2onamJqr2rNatlq+ms7a0NrT2tba5tr+WwfbCtsN2yNbLtsx20hbVVtXW1lbYltkW2Zbblt8m3+blBugG62buJvDm8ab0Fvem+4b8Rv0HAxcDlwSXCYcK5wunDCcQBxc3G1ciRybXK4csxzGXNJc5hzpHOwc7xz+nQ3dGt0d3SDdNZ04nWZdaV1sXW5dc112XYNdhl2XXaTdp93B3cTdxt3J3dud6x34XggeF54anh2eH54injheO14+XkFeVF5XXlpeXV5iXmhea15uXnFedF53Xnoefh6RnqQesh7I3txe3l7qnvzfEF8f3yLfMJ85n05fWN9b317fYd9j33Ufdx96H30ffx+CH6nfrN+6380fzx/RH9Qf5p/5IA1gKOBM4GugbaCDoIagiaCMoI6gkaCUoJegmqCdoKCgo6CloLvgveDXYOng8SD1oQHhEeET4RbhGeEo4T+hSSFMIU8hZKFvYXJhhiGS4ZxhnmGnYalhq2GzYbVhuGHMIc4h22HmYfEh9CICYhFiISIyYjViTKJOolKiZaJoomuibqKAYqKisiLJouKi9uL44wxjF+MrYy5jRaNIo1djZ6Nz43bjeeN845FjtOO347rjw6PIo8uj2KPbo+vj7eP95BZkGWQbZB5kL6ROJF6ka2R6pImkjKSPpJGklKSpJKwkrySyJMRkx2TKZM1k4eTk5Ofk6uTt5PDk8+T2pPmlDWUepSylQqVXJVklZWV35ZXlpmWpZcDl1qXYpell/6YBpgSmB6YT5hymHqYgpiKmL+Yy5ktmTmZgZnPmkaabpp6moaamJrymv6bBpsSmyabLps2mz6bSptWm16bapvom/ScRJxMnFScYJyonPadXp3GnkCemJ6knrCeuJ7EnxOfH58rnzefQ59Pn1ufZ5+/n+agMqB0oLCgwaDJoQqhKaFpobKh5aItoo+izaM4o5mj36P9pD2kiKS+pQelD6VSpVqlaKV3pYallaWkpbOlwqXRpeCl76X+pkCmaKaopvCnI6drp82oC6h2qNipHqlFqYWpzqoDqkyqVKqXqp+rA6sRqx+rLas7q0mrV6tlq3OrgauPq8mr76wtrHOso6zlrTytd63Xri+uPq5krqKu6K73rzqvSa+Fr5Svo6+yr8Gv0K/fr+6v/bAMsBuwKrA5sFGwYbBxsIGwkbChsLGwwbDRsOGxFrExsVaxe7GNsbqxyrH5siiylLK2swuzZLNws4ezmbOws8yz57QMtBm0PrRVtHq0vrUFtSW1SLVrtZG1nrWrtbi1xbXStd+1+LYRtiq2MrZLtlO2W7ZotnW2graOtpq2ubbbtue287b/tya3Ubd+t5O3qLe1t8K38bgiuC64OrhZuHu4nbjxuUi5VLlguWy5eLmfucq597oNuiq6Oro6ujq6Oro6ujq6OrqWuuG7c7vfvFG8371Jvbq98r5UvsO+/79Xv6C/28BIwFjA5cErwXzBwsHswizCuML4wwDDRcNNw3XDjsOrw/XEJ8SBxJfErsTYxQTFOsW+xjLGUMayxybHacdxx3nHnMfVyATIDMhvyR7J/sodyjXKW8p0ypPKq8rUyuzLHss8y1vLfsuly8vL3sv6zBTMKsxUzGbMdsyOzJ7MxMzczQLNGs3KzjjOY87iz2TP6tAx0HnQj9Cx0QbRK9Fi0cvSU9J60pHSsdK+03fT5dQk1DXURtRX1IHUktSs1L3U1tTn1PjVHtU11VrVf9WP1cHWA9ZI1rzWzdbe1u/XDdce1y/XQNd115vXydf22CLYS9iJ2LnY+dkx2WHZftmc2brZzNnm2iHaONpP2mbajNqj2rna0Nrl2vzbE9s121bbd9uO27zcLNxD3FrccdyL3KLcudzQ3QHdI91N3Wfded2P3andzN4L3lPehN6k3sTe5t8I3zLfld+53+rgMuBU4Hzg8uEJ4S/hU+Ft4Yrhl+Gj4cDh2eH24ibiVOJu4oripuKv4rjiweLK4tPi3OLl4u7i9+MA4wnjEuMb4zTjTeNk45LjwOPs5AnkJuRS5GLkcuSC5JLko+S05MXk1uTt5QTlGuUx5UflXeVz5YrlouW6AAAAAQAAAAczM3QVnhxfDzz1AAcD6AAAAADWC/5GAAAAANYeQAX8uP75Bk0EHQAAAAcAAgAAAAAAAAJLACgAAAAAAQ0AAAENAAAC3P//Atz//wLc//8C3P//Atz//wLc//8C3P//Atz//wLc//8C3P//Atz//wLc//8C3P//Atz//wLc//8C3P//Atz//wLc//8C3P//Atz//wLc//8C3P//Atz//wLc//8C3P//Atz//wQX//8EF///AvUAaQLTADAC0wAwAtMAMALTADAC0wAwAtMAMALTADADOgBpBa4AaQNCAAsDOgBpA0IACwM6AGkDOgBpBUMAaQKeAGkCngBpAp4AaQKeAGkCngBpAp4AaQKeAGkCngBpAp4AaQKeAGkCngBpAp4AaQKeAGkCngBpAp4AaQKeAGkCngBpAp4AaQKeAGkCngBpAp4AaQKeAGkCngBpAm8AHwJvAB8CewBpAwQAMAMEADADBAAwAwQAMAMEADADBAAwAwQAMAMnADADLABpAzwACQMsAGkDLABpAywAaQMsAGkBNgBpAtAAVwE2AFABNv/5ATb/6AE2/64BNgALATYADwE2AGABNgBoATb/5AE2AD8BNv/5ATYAFgE2AE4BNv/zAgH/9wIB//cCzwBpAs8AaQLPAGkCUgBpBFMAaQJSAFACUgBpAlIAaQJSAGkCUgBpA24AaQJSAGkCWgAJA7sAaQO7AGkDLABpBS0AaQMsAGkDLABpAywAaQMsAGkDLABpAywAaQRIAGkDLABpAywAaQNIADADSAAwA0gAMANIADADSAAwA0gAMANIADADSAAwA0gAMANIADADSAAwA0gAMANIADADSAAwA0gAMANIADADSAAwA0gAMANIADADSAAwA0gAMANIADADSAAwA0gAMANIADADSAAwA0gAMANIADADSAAwA0gAMANIADADSAAwA0gAMANIADAEZgAwAtIAaQLSAGkDSAAwAtcAaQLXAGkC1wBpAtcAaQLXAGkC1wBpAtcAaQLXAGkCbQApAm0AKQJtACkBAgBQAm0AKQJtACkCbQApAm0AKQJtACkCbQApAm0AKQJtACkC+wBjAzEAMAJLAAQCSwAEAksABAJLAAQCSwAEAksABAJLAAQDFwBjAxcAYwMXAGMDFwBjAxcAYwMXAGMDFwBjAxcAYwMXAGMDFwBjAx8AYwMfAGMDHwBjAx8AYwMfAGMDHwBjAxcAYwMXAGMDFwBjAxcAYwMXAGMDFwBjAxcAYwMXAGMCyP//BGYAIARmACAEZgAgBGYAIARmACACoQANAof//AKH//wCh//8Aof//AKH//wCh//8Aof//AKH//wCh//8Aof//AKRACsCkQArApEAKwKRACsCkQArAtAAVwMgAGMDIABjAyAAYwMgAGMDIABjAyAAYwMgAGMDIABjAyAAYwMgAGMDIABjAyAAYwMgAGMDIABjAyAAYwMgAGMDIABjAyAAYwMgAGMDIABjAyAAYwMgAGMDIABjAyAAYwMgAGMDIABjBDIAWgQyAFoFrgBpBU0AaQKEADMChAAzAoQAMwKEADMChAAzAoQAMwKEADMChAAzAoQAMwKEADMChAAzAoQAMwKEADMChAAzAoQAMwKEADMChAAzAoQAMwKEADMChAAzAoQAMwKEADMChAAzAl4AYwMEADADBAAwAwQAMAMEADADBAAwAwQAMAMEADADLAAwAcgAKwLQAFcByAArAtAAVwHIACsByAArAcj/+AHIACsByAArAcgAKwHIACsByAArAcgAKwHIACsByAArAcgAKwHIACsB///3Af//9wRvAGkEywBpBMsAaQMeAGkFHQBpAx4AaQMeAGkDHgBpAx4AaQMeAGkDHgBpBDoAaQMeAGkDHgBpA0gAMAMxAEUCVv/8Alb//AJW//wCVv/8Alb//AJW//wCVv/8AxoAYwMaAGMDGgBjAxoAYwMaAGMDGgBjAxoAYwMaAGMDGgBjAxoAYwMaAGMDGgBjAxoAYwMaAGMDGgBjAxoAYwMaAGMDGgBjAxoAYwMaAGMDGgBjAxoAYwMaAGMDGgBjBKYAYwSmAGMEpgBjBKYAYwSmAGMDEwBeAxMAXgMTAF4DEwBeAxMAXgMTAF4DEwBeAxMAXgMTAF4DEwBeApsAMAKbADACmwAwApsAMAKbADACVgAyAlYAMgJWADICVgAyAlYAMgJWADICVgAyAlYAMgJWADICVgAyAlYAMgJWADICVgAyAlYAMgJWADICVgAyAlYAMgJWADICVgAyAlYAMgJWADICVgAyAlYAMgJWADICVgAyAlYAMgPdADID3QAyAqoAWwI7ACoCOwAqAjsAKgI7ACoCOwAqAjsAKgI7ACoCqgAqAoAAKgKqACoCqgAqAqoAKgKqACoEuwAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAg//7AIP/+wBYQAPArIAKgKyACoCsgAqArIAKgKyACoCsgAqArIAKgK6ACoCqQBbAqkAAAKpAFsCqf/YAqn/2AKpAFsBFwBKARcAWwEXAEABFwACARf/8QEX/54BFwASARf//wEXAFABFwBKARf/1AEXAC8BFwACAjMASgEXAAYBFwA8ARf//AEc/6QBHP+kARz/pAJoAFsCaP/YAmgAWwJeAFsBFwBbARcAQAEXAFsBFwBYAVoAWwEXAFgCMwBbARf/6AEn//kEIQBbBCEAWwKpAFsCqQBbAwIANQKpAFsCqQBbAqkAWwKpAFsCqQBbA8UAWwKpAFsCqQBbAnsAKgJ7ACoCewAqAnsAKgJ7ACoCewAqAnsAKgJ7ACoCewAqAnsAKgJ7ACoCewAqAnsAKgJ7ACoCewAqAnsAKgJ7ACoCewAqAnsAKgJ7ACoCewAqAn8AKgJ7ACoCewAqAnsAKgJ7ACoCewAqAnsAKgJ7ACoCewAqAnsAKgJ7ACoCewAqAnsAKgQrACoCqgBbAqoAWwKqACoBmgBbAZoAWwGaADcBmgBYAZr//QGaAFgBmgBIAZr/6AH1ABgB9QAYAfUAGAD/AFAB9QAYAfUAGAH1ABgB9QAYAfUAGAH1ABgB9QAYAfUAGAKkAFsBMgAZAZ4ADwGoABQBngAPAZ4ADwGeAA8BngAJAZ4ADwGeAA8CpQBWAqUAVgKlAFYCpQBWAqUAVgKlAFYCpQBWAqUAVgKlAFYCpQBWAq0AVgKtAFYCrQBWAq0AVgKtAFYCrQBWAqUAVgKlAFYCpQBWAqUAVgKlAFYCpQBWAqUAVgKlAFYCL//+A4MABgODAAYDgwAGA4MABgODAAYCKAAOAi//6gIv/+oCL//qAi//6gIv/+oCL//qAi//6gIv/+oCL//qAi//6gIJACgCCQAoAgkAKAIJACgCCQAoAjIASAKqACoCqgAqAqoAKgKqACoCqgAqAqoAKgKqACoCqgAqAqoAKgKqACoCqgAqAqoAKgKqACoCqgAqAqoAKgKqACoCqgAqAqoAKgKqACoCqgAqAqoAKgKqACoCqgAqAqoAKgKqACoCqgAqA90AMgPdADIEvQAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAArAVMAWwFBAFsBQQBAAUEAWwFBAFsBbQBbAUEAWwI1AFsBQQApAUH/8QQ6ACoBiwBWAZUADAGLAFYBiwBWAYsAVgGL//YBiwBWAYsASAPZAFYD2QBWA9kAVgPZAFYD2QBWAqUAVAKlAFQCpQBUAqUAVAKlAFQCpQBUAqUAVAKlAFQCpQBUAhMALQITAC0CEwAtAhMALQITAC0EsQAEAsgADwJ4AA8CugBbAosADwJn//8CZ///Amf//wJn//8CZ///Amf//wJn//8CZ///Amf//wJn//8CZ///Amf//wJn//8CZ///Amf//wJn//8CZ///Amf//wJn//8CZ///Amf//wJn//8CZ///Amf//wJn//8CZ///A2z//wNs//8ChABhAmEALAJhACwCYQAsAmEALAJhACwCYQAsAmEALAK+AGEC0gAgAr4AYQLSACACvgBhAr4AYQTOAGECOgBhAjoAYQI6AGECOgBhAjoAYQI6AGECOgBhAjoAYQI6AGECOgBhAjoAYQI6AEMCOgBhAjoAYQI6AGECOgBhAjoAYQI6AGECOgBhAjoAYQI6AGECOgBhAjoAYQKcACwCMAAlAjAAJQIgAGECjgAsAo4ALAKOACwCjgAsAo4ALAKOACwCjgAsAq8ALAK7AGEC4wAiArsAYQK7AGECuwBhArsAYQEiAGEBIgBhASIARgJQAEEBIgAIASL/9wEi/6QBIgAYASIABQEiAFYBIgBeASL/2gEiADUBIgAIAm8ATAEiAAwBIgBDASIAAgHB//wBwf/8AmwAYQJsAGECbABhAmwAYQH7AGEB+wBHAfsAYQH7AGEB+wBhAfsAYQO8AGEB+wBhAfv/+AMyAGEDMgBhArsAYQK7AGECuwBhArsAYQK7AGECuwBhArsAYQR8AGECuwBhArsAYQLCACwCwgAsAsIALALCACwCwgAsAsIALALCACwCwgAsAsIALALCACwCwgAsAsIALALCACwCwgAsAsIALALCACwCwgAsAsIALALCACwCwgAsAsIALALCACwCwgAsAsIALALCACwCwgAsAsIALALCACwCwgAsAsIALALCACwCwgAsAsIALALCACwDqwAsAm8AYQJvAGECwgAsAnYAYQJ2AGECdgBhAnYAYQJ2AFQCdgBhAnYAYQJ2AGECEwAlAhMAJQITACUA/wBQAhMAJQITACUCEwAlAhMAJQITACUCEwAlAhMAJQITACUCigBbAe0ABAHtAAQB7QAEAe0ABAHtAAQB7QAEAe0ABAHtAAQCqABbAqgAWwKoAFsCqABbAqgAWwKoAFsCqABbAqgAWwKoAFsCqABbArAAWwKwAFsCsABbArAAWwKwAFsCsABbAqgAWwKoAFsCqABbAqgAWwKoAFsCqABbAqgAWwKoAFsCaQAIA70AIgO9ACIDvQAiA70AIgO9ACICPAAMAjkAAgI5AAICOQACAjkAAgI5AAICOQACAjkAAgI5AAICOQACAjkAAgIrACkCKwApAisAKQIrACkCKwApAq8AWwKvAFsCrwBbAq8AWwKvAFsCrwBbAq8AWwKvAFsCrwBbAq8AWwKvAFsCrwBbAq8AWwKvAFsCrwBbAq8AWwKvAFsCrwBbAq8AWwKvAFsCrwBbAq8AWwKvAFsCrwBbAq8AWwKvAFsDmQBVA5kAVQToAGECJwAqAicAKgInACoCJwAqAicAKgInACoCJwAqAicAKgInACoCJwAqAicAKgInACoCJwAqAicAKgInACoCJwAqAicAKgInACoCJwAqAicAKgInACoCJwAqAicAKgKcADkCCABbAo4ALAKOACwCjgAsAo4ALAKOACwCjgAsAo4ALAK0ACwBqgA5AaoAOQGqADkCbwBBAaoAOQGqADkBqv/pAaoAOQGqADkBqgA5AaoAHwGqADkBqgA5Am8ATAGqADkBqgA5AaoAOQHB//wBwf/8A7wAYQQAAGEEAABhAq4AYQKuAGECrgBhAq4AYQKuAGECrgBhAq4AYQRvAGECrgBhAq4AYQLCACwB9//8Aff//AH3//wB9//8Aff//AH3//wB9//8Aff//AKuAFsCrgBbAq4AWwKuAFsCrgBbAq4AWwKuAFsCrgBbAq4AWwKuAFsCtgBbArYAWwK2AFsCtgBbArYAWwK2AFsCrgBbAq4AWwKuAFsCrgBbAq4AWwKuAFsCrgBbAq4AWwP/AFsD/wBbA/8AWwP/AFsD/wBbAqMAVgKjAFYCowBWAqMAVgKjAFYCowBWAqMAVgKjAFYCowBWAqMAVgIrACkCKwApAisAKQIrACkCKwApAZQAJQGiACAC9gAMAtsAbQLrAG0CQgBtAkIAbQJFAG0DJAANApkAbQKZAG0CmQBtBAUAEwKCACADNwBtAzcAbQM3AG0DUwBtAscAbQLHAG0DFgANA8MAbQM0AG0DUAAzAzUAbQLKAG0CzgA0AlsADQKzABACswAQA54ALQKcABEC4AA2Az0AbQRHAG0EYABtAycAbQLJAG0DPAANA+EAbQSjAA0EnABtAnwAMQLEADUCwwAdAT0AbQE2AAsCHAASA0oADQRLAG0C2wA6A0EADgMrABMDhAASA1AAMwL5AA4CagAeAr8AbQQsABMCggAgAvMAbQLkAG0C3QAjAzsADQNPAG0EPwBtBKwAbQNQAG0DzgA5As4ANAJbAA0CmwAGAof//ALBABEDzgAOAvsANgLgADUC4ABtAyUAbQPdACAD3QAgAT4AbQQFABMCygBtAy8AbQNQAG0C3AAzA+gAbQL2AAwC9gAMBBYABwKZAG0DNwApAzcAKQQFABMCggAgAm8AHwM3AG0DNwBtA1AAMwNQADMDUAAzAsMAHQKzABACswAQArMAEALgADYCQgBtA+EAbQJrAB0CoAAOAqwAGgKCADkDFwAMA1YAMwQ9ABUC4wAfAt0AbQMw/7QDMQANAxkADgLlAA0DnQAxAk8AbQKCACACzgA0As4ANAMgAGMDRAAeAoQAMwKEADMChAAzAxoAYwMaAGMDGgBjAxoAYwMWACACzQBcAncADQMTAF4DEwBeA58AMgLMAF8DaAAOA+EAXwSfAAwEjABtAf//9wM7ABMCdwANAyAAYwMgAGMEMgBaAoQAMwMaAGMDGgBjAxMAXgMTAF4DEwBeA+EAXwNIADAC7wAaAk0AMAKWAD4CZgBdAegAXQHoAF0B0gBdApgACAJ0ACwCdAAsAnQALANRAA0CIAAcArYAXQK2AF0CtgBdAswAXQJWAF0CVgBdAoEABQMeAF0CqQBdAoEALAKlAF0CsABdAjsALAHtAAQCO//wAjv/8AMlACsCHQAJAmEAKgKyAF0DrQBdA60AXQKGAF0CPwBdAn8ABAMnAF0DpgAFA7gAXQIYACsCQQAsAj8AGAEbAEwBFwASARz/ogKi/9wDbABdAmQAMAKj//YCZQAAAsAADwKKACwCVAAFAgQAKwJZAF0DcgANAiAAHAJWAF0CZgBbAlUAAAKeAAQCvgBdA3YAXQKlAF0D0ABdAyYALwI7ACwB7QAEAj4ABgI+AAYCHQAJAwMABQJ6ACoCYQApAqIAXQK8AF0DAwAVAwMAFQEbAF0DUQANAlYAXQKXAAUCrwBdAr8AXQJeACcDPQBdAk0AMAJNADAD4wAwAnQALAJzADgCcwA4A1EADQIgABwCD//sArYAXQK2AF0CgQAsAooALAKKACwCPwAYAjv/8AI7//ACO//wAmEAKgHoAF0DJwBdAewADQIdAAsCOQAWAiAANQKBAAUCsAAuA6oACQJeABYCuwBeAqn/pQKWAAUCfgBMAiEALgKzACkDUQANAe7/9wKeAE0CngBNAp4ATQJVAF4CPAAFAqkAXQKiAF0EGwBdAmMALAK3AE0EGwBOBDQATgJAAFACnAAFA1cAXgH0AF0CIAAcAjsALAHoAF0CbgAnARcABgKzACcCpQBWBBsATgKqACoCswApAmQAKgJkACoCZAAqAp4ATQKeAE0CngBNAp4ATQKWAEYEGwBdAqUAVAKlAFQCSQBQAqUABQMoAFADrQAIA7IAXQJ6//wCqgAqAqoAKgPdADICZAAqAmQAKwJkACsCngBNAp4ATQKlAFQCpQBUAqUAVAMoAFACawARAtz//wOCAAkCqgBbAtT/+ALc//8CzwBpApsAMAFyAAgCPgAOAjwABQKdACYCPgARAmkAMAJWAB4ChAAsAmkAHAKsADIBcgAIAj4ABgI8AAYCnQAmAj4AEQJpADACVgAeAoQALAJpABwBrgAcAa4AUQGuABwBrgAbAa4AFgGuABsBrgAlAa4AJAGuABwBrgAgArwAPQK8AJACvAA8ArwAPgK8ADUCvABBArwASgK8AEkCvAA7ArwAQQK8ADwCvACQArwARwK8AD4CvAA1ArwAQQK8AEoCvABJArwAOwK8AEEBrgAcAa4AUQGuABwBrgAbAa4AFgGuABsBrgAlAa4AJAGuABwBrgAgAa4AHAGuAFEBrgAcAa4AGwGuABYBrgAbAa4AJQGuACQBrgAcAa4AIAGuABwBrgBRAa4AHAGuABsBrgAWAa4AGwGuACUBrgAkAa4AHAGuACABrgAcAa4AUQGuABwBrgAbAa4AFgGuABsBrgAlAa4AJAGuABwBrgAgAK7/QgQKAFEECgBRBAoAHAQKAFEECgAbBAoAUQQKABsECgAbBAoAJAGQABMBYP/aAQsAQgE6AEIA4wAuAOMAMAKzAC4BDABFAQwARQK/ABsA4wAuAj0ACQI9AEUBhwA/ANIAPwDjAC4BYP/kAfQAAAFg/9oBHwBMAU4ATAFYAH4BYP/kAIEALQFfADkBXwATAU0AaQFNABMBUQBfAVIAIAFzAEMBcwAdAWEAcwFhAB0BZQBpAWYAKgPoAAAB9AAAArwALwPoAAABfwA5AX8AOQF/ADkD6AAAAfQAAAGTAEMB+AAuAfgAIgE4AC4BOAAiAaAAMAGgAC4BoAAwAOMALgDjADAA4wAwAgwAOAIMACwBTAA4AUwALAEMAEUBDABFAdwALgHdACIBIgAuASMAIgDnADMCCgAIAgkARQGHAD8BnwAwAZ8ALgGfADAA4gAuAOIAMADjADAA0gA/AUkAJAFJACsCvAAAAGQAAADjAAABDQAAAIYAAAAAAAAC0wAwAjsAKgLTADACvAAfAm0AKQKqACoDJwAeAcH/pAKXAB4DBAAwAzgAVwKUAB4ChgAeAsgAHgOUAGkDcAAeBmoAaQNLAB4C7gAeAtAAHQKGAB4C0QBMAqoAMwSqAB4Cw//8AR8ATAIaAEwBYP/kAkYAQwJGAEMCRgBrAkYAQwJGAEMCRgBDAkYAQwJGAEMCRgBDAkYAQwJGAEMCRgA6AkYAOgJGAEMCRgAlA5sAKgGP/90DggAJAtz//wMsAGkCkQArAyMAQwKqAFsCvABIA0sAJQS6ACUCWABgAlgAeAJYAEMCWAB5AlgAagJYAG4CWABgAlgAbwLZADICWABfAlgAYAJYAEMCWABq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Bz4HPQdEB0MHTAdKB0cHQAdFB0EHRgdJB04HUwdSB1QHUAblBucG7AbyBvYG7wbjBt8G+gbwBuoG7QRuBG8ElwRqBI8EjgSRBJIEkwSMBI0ElAR3BHQEgQSIBGYEZwRoBGkEbARtBHAEcQRyBHMEdgSCBIMEhQSEBIYEhwSKBIsEiQSQBJUElgUGBQcFCAUJBQwFDQUQBREFEgUTBRYFIgUjBSUFJAUmBScFKgUrBSkFMAU1BTYFDgUPBTcFCgUvBS4FMQUyBTMFLAUtBTQFFwUUBSEFKASYBTgEmQU5BJoFOgSbBTsEdQUVBNgFeQTZBXoEawULBJwFPASdBT0EngU+BJ8FPwSgBUAEoQVBBKIFQgSjBUMEpAVEBKUFRQSmBUcEqAVIBKkFSQSqBUoEqwVLBKwFTAStBU0ErgVOBK8FTwSwBVAEsQVRBLMFUwS0BVQEtQS2BVYEtwVXBVgEuAVZBLkFWgS6BVsEuwVcBVUEvAVdBL0FXgS+BV8EvwVgBMAFYQTBBWIEwgVjBMMFZATEBWUExQVmBMYFZwTHBWgEyAVpBMkFagTKBWsEywVsBMwFbQTNBW4EzgVvBM8FcATQBXEE0QVyBNIFcwTTBXQE1AV1BNUFdgTWBXcE1wV4BKcFRgSyBVIE2gV7BNsFfAAlAasALQGyAC4BswBEAckAQwHIADQBuQBQAdYAVwHdAFQB2gBfAeUAcwH7AHUB/QB4AgAAfgIGAH8CBwCCAgoAowIrAKQCLACeAiYAnQIlAK8CNwCxAjkAuwJDALwCRAC0AjwAtwI/AL0CRQDFAk4AxgJPAN4CZwDaAmMA5AJtAOECagDjAmwA6gJzAPQCfQAVAZsAFwGdAA4BlAAQAZYAEQGXABIBmAAPAZUABwGNAAkBjwAKAZAACwGRAAgBjgA+AcMAQAHFAEYBywA2AbsAOAG9ADkBvgA6Ab8ANwG8AGMB6QBhAecAkQIZAJMCGwCIAhAAigISAIsCEwCMAhQAiQIRAJUCHQCXAh8AmAIgAJkCIQCWAh4AzgJXANACWQDSAlsA1AJdANUCXgDWAl8A0wJcAOwCdQDrAnQA7QJ2AO8CeAZzBnUGdwZ0BngGSgZJBkgGSwZXBlgGVgbVBtYGJwaBBoUGfgZ/BoQGjwaKBoIGgwZ5Bo4GjAaGBocGiwW/Bb4GtQavBrEGswa3BrgGtgaw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AREBEgETARQAYwEVAK4AkAEWACUAJgD9AP8AZAEXARgBGQAnARoA6QEbARwBHQEeAR8AKABlASABIQEiAMgBIwEkASUBJgEnASgAygEpASoAywErASwBLQEuAS8BMAExATIBMwApACoA+AE0ATUBNgE3ATgBOQArAToBOwE8AT0BPgAsAT8AzAFAAM0BQQDOAUIA+gFDAM8BRAFFAUYBRwFIAC0BSQAuAUoBSwAvAUwBTQFOAU8BUAFRAVIBUwDiADABVAAxAVUBVgFXAVgBWQFaAVsBXAFdAGYAMgDQAV4A0QFfAWABYQFiAWMBZABnAWUBZgFnANMBaAFpAWoBawFsAW0BbgFvAXABcQFyAXMBdACRAXUArwF2AXcBeACwADMA7QA0ADUBeQF6AXsBfAF9AX4BfwA2AYABgQGCAOQBgwD7AYQBhQGGAYcBiAGJAYoANwGLAYwBjQGOAY8BkAA4ANQBkQGSANUBkwBoAZQA1gGVAZYBlwGYAZkBmgGbAZwBnQGeAZ8BoAGhAaIBowA5ADoBpAGlAaYBpwA7ADwA6wGoALsBqQGqAasBrAGtAa4APQGvAOYBsAGxAbIBswG0AbUBtgG3AbgBuQG6AbsBvAG9Ab4BvwHAAcEBwgHDAcQBxQHGAccByAHJAcoBywHMAc0BzgHPAdAB0QHSAdMB1AHVAdYB1wHYAdkB2gHbAdwB3QHeAd8B4AHhAeIB4wHkAeUB5gHnAegB6QHqAesB7AHtAe4B7wHwAfEB8gHzAfQB9QH2AfcB+AH5AfoB+wH8Af0B/gH/AgACAQICAgMCBAIFAgYCBwIIAgkCCgILAgwCDQIOAg8CEAIRAhICEwIUAhUCFgIXAhgCGQIaAhsCHAIdAh4CHwIgAiECIgIjAiQCJQImAicCKAIpAioCKwIsAi0CLgIvAjACMQIyAjMCNAI1AjYCNwI4AjkCOgI7AjwCPQI+Aj8CQAJBAkICQwJEAkUCRgBEAGkCRwJIAkkCSgJLAkwCTQBrAk4CTwJQAlECUgJTAGwCVABqAlUCVgJXAlgAbgJZAG0AoAJaAEUARgD+AQAAbwJbAlwCXQBHAOoCXgEBAl8CYAJhAEgAcAJiAmMCZAByAmUCZgJnAmgCaQJqAHMCawJsAHECbQJuAm8CcAJxAnICcwJ0AnUCdgBJAEoA+QJ3AngCeQJ6AnsCfABLAn0CfgJ/AoACgQBMANcAdAKCAHYCgwB3AoQChQKGAHUChwKIAokCigKLAowATQKNAo4ATgKPApACkQBPApICkwKUApUClgKXApgA4wBQApkAUQKaApsCnAKdAp4CnwKgAqECogB4AFIAeQKjAHsCpAKlAqYCpwKoAqkAfAKqAqsCrAB6Aq0CrgKvArACsQKyArMCtAK1ArYCtwK4ArkAoQK6AH0CuwK8Ar0AsQBTAO4AVABVAr4CvwLAAsECwgLDAsQAVgLFAsYCxwDlAsgA/ALJAsoCywLMAs0AiQLOAFcCzwLQAtEC0gLTAtQC1QBYAH4C1gLXAIAC2ACBAtkAfwLaAtsC3ALdAt4C3wLgAuEC4gLjAuQC5QLmAucC6ABZAFoC6QLqAusC7ABbAFwA7ALtALoC7gLvAvAC8QLyAvMAXQL0AOcC9QL2AvcC+AL5AvoC+wL8Av0C/gL/AwADAQMCAwMDBAMFAwYDBwMIAwkDCgMLAwwDDQMOAw8DEAMRAxIDEwMUAxUDFgMXAxgDGQMaAxsDHAMdAx4DHwMgAyEDIgMjAyQDJQMmAycDKAMpAyoDKwMsAy0DLgMvAzADMQMyAzMDNAM1AzYDNwM4AzkDOgM7AzwDPQM+Az8DQANBA0IDQwNEA0UDRgNHA0gDSQNKA0sDTANNA04DTwNQA1EDUgNTAMAAwQNUA1UDVgNXA1gDWQNaA1sDXANdA14DXwNgA2EDYgNjA2QDZQNmA2cDaANpA2oDawNsA20DbgNvA3ADcQNyA3MDdAN1A3YDdwN4A3kDegN7A3wDfQN+A38DgAOBA4IDgwOEA4UDhgOHA4gDiQOKA4sDjAONA44DjwOQA5EDkgOTA5QDlQOWA5cDmAOZA5oDmwOcA50DngOfA6ADoQOiA6MDpAOlA6YDpwOoA6kDqgOrA6wDrQOuA68DsAOxA7IDswO0A7UDtgO3A7gDuQO6A7sDvAO9A74DvwPAA8EDwgPDA8QDxQPGA8cDyAPJA8oDywPMA80DzgPPA9AD0QPSA9MD1APVA9YD1wPYA9kD2gPbA9wD3QPeA98D4APhA+ID4wPkA+UD5gPnA+gD6QPqA+sD7APtA+4D7wPwA/ED8gPzA/QD9QP2A/cD+AP5A/oD+wP8A/0D/gP/BAAEAQQCBAMEBAQFBAYEBwQIBAkECgQLBAwEDQQOBA8EEAQRBBIEEwQUBBUEFgQXBBgEGQQaBBsEHAQdBB4EHwQgBCEEIgQjBCQEJQQmBCcEKAQpBCoEKwQsBC0ELgQvBDAEMQQyBDMENAQ1BDYENwQ4BDkEOgQ7BDwEPQQ+BD8EQARBBEIEQwREBEUERgRHBEgESQRKBEsETARNBE4ETwRQBFEEUgRTBFQEVQRWBFcEWARZBFoEWwRcBF0EXgRfBGAEYQRiBGMEZARlBGYEZwRoBGkEagRrBGwEbQRuBG8EcARxBHIEcwR0BHUEdgR3BHgEeQR6BHsEfAR9BH4EfwSABIEEggSDBIQEhQSGBIcEiASJBIoEiwSMBI0EjgSPBJAEkQSSBJMElASVBJYElwSYBJkEmgSbBJwEnQSeBJ8EoAShBKIEowSkBKUEpgSnBKgEqQSqBKsErAStBK4ErwSwBLEEsgSzBLQEtQS2BLcEuAS5BLoEuwS8BL0EvgS/BMAEwQTCBMMExATFBMYExwTIBMkEygTLBMwEzQTOBM8E0ATRBNIE0wTUBNUE1gTXBNgE2QTaAJ0AngTbBNwE3QTeBN8E4AThBOIE4wTkBOUE5gTnBOgE6QTqBOsE7ATtBO4E7wTwBPEE8gTzBPQE9QT2BPcE+AT5BPoE+wT8BP0E/gT/BQAFAQUCBQMFBAUFBQYFBwUIBQkFCgULBQwFDQUOBQ8FEAURBRIFEwUUBRUFFgUXBRgFGQUaBRsFHAUdBR4FHwUgBSEFIgUjBSQFJQUmBScFKAUpBSoFKwUsBS0FLgUvBTAFMQUyBTMFNAU1BTYFNwU4BTkFOgU7BTwFPQU+BT8FQAVBBUIFQwVEBUUFRgVHBUgFSQVKBUsFTAVNBU4FTwVQBVEFUgVTBVQFVQVWBVcFWAVZBVoFWwVcBV0FXgVfBWAFYQViBWMFZAVlBWYFZwVoBWkFagVrBWwFbQVuBW8FcAVxBXIFcwV0BXUFdgV3BXgFeQV6BXsFfAV9BX4FfwWABYEFggWDBYQFhQWGBYcFiAWJBYoFiwWMBY0FjgWPBZAFkQWSBZMFlAWVBZYFlwWYBZkFmgWbBZwFnQWeBZ8FoAWhBaIFowWkBaUFpgWnBagFqQWqBasFrAWtBa4FrwWwBbEFsgWzBbQFtQW2BbcFuAW5BboFuwW8Bb0FvgW/BcAFwQXCBcMFxAXFBcYFxwXIBckFygXLBcwFzQXOBc8F0AXRBdIF0wXUBdUF1gXXBdgF2QXaBdsF3AXdBd4F3wXgBeEF4gXjBeQF5QXmBecF6AXpBeoF6wXsBe0F7gXvBfAF8QXyBfMF9AX1BfYF9wX4BfkF+gX7BfwF/QX+Bf8GAAYBBgIGAwYEBgUGBgYHBggGCQYKBgsGDAYNBg4GDwYQBhEGEgYTBhQGFQYWBhcGGAYZBhoGGwYcBh0GHgYfBiAGIQYiBiMGJAYlBiYGJwYoBikGKgYrBiwGLQYuBi8GMAYxAJsGMgYzABMAFAAVABYAFwAYABkAGgAbABwGNAY1BjYGNwY4BjkGOgY7BjwGPQY+Bj8GQAZBBkIGQwZEBkUGRgZHBkgGSQZKBksGTAZNBk4GTwZQBlEGUgZTBlQGVQZWBlcGWAZZBloGWwZcBl0GXgZfBmAGYQZiBmMGZAZlBmYGZwZoBmkGagZrBmwGbQZuBm8GcAZxBnIGcwZ0BnUGdgZ3BngGeQZ6BnsGfAZ9Bn4GfwaABoEGggaDALwA9AaEBoUA9QD2BoYGhwaIBokADQA/AMMAhwAdAA8AqwAEAKMABgARACIAogAFAAoAHgASAEIGigaLBowGjQaOBo8AXgBgAD4AQAALAAwGkAaRBpIGkwaUBpUAswCyBpYGlwAQBpgGmQaaBpsGnACpAKoAvgC/AMUAtAC1ALYAtwDEBp0GngafBqAGoQaiBqMGpAalBqYGpwaoBqkGqgarBqwGrQauBq8GsAaxBrIGswa0BrUGtga3BrgGuQa6AIQGuwC9AAcGvAa9AKYA9wa+Br8GwAbBBsIGwwbEBsUGxgbHBsgAhQbJBsoGywCWBswGzQbOAA4A7wDwALgAIACPACEAHwCVAJQAkwCnAGEApAbPAJIAnAbQBtEAmgCZAKUG0gCYAAgAxgbTBtQG1QbWBtcG2AbZBtoG2wbcBt0G3gbfBuAG4QbiALkG4wbkBuUG5gbnBugG6QbqBusG7AAjAAkAiACGAIsAigCMAIMAXwDoBu0AggDCBu4G7wBBBvAG8QbyBvMG9Ab1BvYG9wb4BvkG+gb7BvwG/Qb+Bv8HAAcBBwIHAwcEBwUHBgcHBwgHCQcKBwsHDAcNBw4HDwcQBxEHEgcTBxQHFQcWBxcHGAcZBxoHGwccBx0HHgcfByAHIQciByMHJAclByYHJwcoBykHKgcrBywHLQcuBy8HMAcxBzIHMwc0BzUHNgc3BzgHOQc6BzsHPAc9Bz4HPwdAB0EHQgdDB0QHRQdGB0cHSAdJB0oHSwdMB00HTgdPB1AHUQdSB1MHVAdVB1YHVwdYB1kHWgdbB1wHXQCNANsA4QDeANgAjgDcAEMA3wDaAOAA3QDZB14HXwdgB2EHYgdjB2QHZQdmB2cHaAdpB2oHawdsB20HbgdvB3AHcQdyB3MHdAd1B3YHdwd4BE5VTEwGQWJyZXZlB3VuaTFFQUUHdW5pMUVCNgd1bmkxRUIwB3VuaTFFQjIHdW5pMUVCNAd1bmkwMUNEB3VuaTFFQTQHdW5pMUVBQwd1bmkxRUE2B3VuaTFFQTgHdW5pMUVBQQd1bmkwMjAwB3VuaTFFQTAHdW5pMUVBMgd1bmkwMjAyB0FtYWNyb24HQW9nb25lawpBcmluZ2FjdXRlB0FFYWN1dGUHdW5pMUUwOAtDY2lyY3VtZmxleApDZG90YWNjZW50B3VuaTAxQzQGRGNhcm9uBkRjcm9hdAd1bmkxRTBDB3VuaTFFMEUHdW5pMDFDNQZFYnJldmUGRWNhcm9uB3VuaTFFMUMHdW5pMUVCRQd1bmkxRUM2B3VuaTFFQzAHdW5pMUVDMgd1bmkxRUM0B3VuaTAyMDQKRWRvdGFjY2VudAd1bmkxRUI4B3VuaTFFQkEHdW5pMDIwNgdFbWFjcm9uB3VuaTFFMTYHdW5pMUUxNAdFb2dvbmVrB3VuaTFFQkMHdW5pMDFCNwd1bmkwMUVFBkdjYXJvbgtHY2lyY3VtZmxleAxHY29tbWFhY2NlbnQKR2RvdGFjY2VudAd1bmkxRTIwB3VuaTAxRTQESGJhcgd1bmkxRTJBB3VuaTAyMUULSGNpcmN1bWZsZXgHdW5pMUUyNAJJSgZJYnJldmUHdW5pMDIwOAd1bmkxRTJFB3VuaTFFQ0EHdW5pMUVDOAd1bmkwMjBBB0ltYWNyb24HSW9nb25lawZJdGlsZGULSmNpcmN1bWZsZXgHdW5pMDFFOAxLY29tbWFhY2NlbnQHdW5pMDFDNwZMYWN1dGUGTGNhcm9uDExjb21tYWFjY2VudARMZG90B3VuaTFFMzYHdW5pMDFDOAd1bmkxRTNBB3VuaTFFNDIHdW5pMDFDQQZOYWN1dGUGTmNhcm9uDE5jb21tYWFjY2VudAd1bmkxRTQ0B3VuaTFFNDYDRW5nB3VuaTAxQ0IHdW5pMUU0OAZPYnJldmUHdW5pMUVEMAd1bmkxRUQ4B3VuaTFFRDIHdW5pMUVENAd1bmkxRUQ2B3VuaTAyMEMHdW5pMDIyQQd1bmkwMjMwB3VuaTFFQ0MHdW5pMUVDRQVPaG9ybgd1bmkxRURBB3VuaTFFRTIHdW5pMUVEQwd1bmkxRURFB3VuaTFFRTANT2h1bmdhcnVtbGF1dAd1bmkwMjBFB09tYWNyb24HdW5pMUU1Mgd1bmkxRTUwB3VuaTAxRUELT3NsYXNoYWN1dGUHdW5pMUU0Qwd1bmkxRTRFB3VuaTAyMkMGUmFjdXRlBlJjYXJvbgxSY29tbWFhY2NlbnQHdW5pMDIxMAd1bmkxRTVBB3VuaTAyMTIHdW5pMUU1RQZTYWN1dGUHdW5pMUU2NAd1bmlBNzhCB3VuaTFFNjYLU2NpcmN1bWZsZXgMU2NvbW1hYWNjZW50B3VuaTFFNjAHdW5pMUU2Mgd1bmkxRTY4B3VuaTFFOUUHdW5pMDE4RgRUYmFyBlRjYXJvbgd1bmkwMTYyB3VuaTAyMUEHdW5pMUU2Qwd1bmkxRTZFBlVicmV2ZQd1bmkwMUQzB3VuaTAyMTQHdW5pMUVFNAd1bmkxRUU2BVVob3JuB3VuaTFFRTgHdW5pMUVGMAd1bmkxRUVBB3VuaTFFRUMHdW5pMUVFRQ1VaHVuZ2FydW1sYXV0B3VuaTAyMTYHVW1hY3Jvbgd1bmkxRTdBB1VvZ29uZWsFVXJpbmcGVXRpbGRlB3VuaTFFNzgGV2FjdXRlC1djaXJjdW1mbGV4CVdkaWVyZXNpcwZXZ3JhdmULWWNpcmN1bWZsZXgHdW5pMUU4RQd1bmkxRUY0BllncmF2ZQd1bmkxRUY2B3VuaTAyMzIHdW5pMUVGOAZaYWN1dGUKWmRvdGFjY2VudAd1bmkxRTkyEElhY3V0ZV9KLmxvY2xOTEQGQS5zczAxC0FhY3V0ZS5zczAxC0FicmV2ZS5zczAxDHVuaTFFQUUuc3MwMQx1bmkxRUI2LnNzMDEMdW5pMUVCMC5zczAxDHVuaTFFQjIuc3MwMQx1bmkxRUI0LnNzMDEMdW5pMDFDRC5zczAxEEFjaXJjdW1mbGV4LnNzMDEMdW5pMUVBNC5zczAxDHVuaTFFQUMuc3MwMQx1bmkxRUE2LnNzMDEMdW5pMUVBOC5zczAxDHVuaTFFQUEuc3MwMQx1bmkwMjAwLnNzMDEOQWRpZXJlc2lzLnNzMDEMdW5pMUVBMC5zczAxC0FncmF2ZS5zczAxDHVuaTFFQTIuc3MwMQx1bmkwMjAyLnNzMDEMQW1hY3Jvbi5zczAxDEFvZ29uZWsuc3MwMQpBcmluZy5zczAxD0FyaW5nYWN1dGUuc3MwMQtBdGlsZGUuc3MwMQdBRS5zczAxDEFFYWN1dGUuc3MwMQx1bmkwMUM0LnNzMDEMdW5pMDFDNS5zczAxBkUuc3MwMQtFYWN1dGUuc3MwMQtFYnJldmUuc3MwMQtFY2Fyb24uc3MwMQx1bmkxRTFDLnNzMDEQRWNpcmN1bWZsZXguc3MwMQx1bmkxRUJFLnNzMDEMdW5pMUVDNi5zczAxDHVuaTFFQzAuc3MwMQx1bmkxRUMyLnNzMDEMdW5pMUVDNC5zczAxDHVuaTAyMDQuc3MwMQ5FZGllcmVzaXMuc3MwMQ9FZG90YWNjZW50LnNzMDEMdW5pMUVCOC5zczAxC0VncmF2ZS5zczAxDHVuaTFFQkEuc3MwMQx1bmkwMjA2LnNzMDEMRW1hY3Jvbi5zczAxDHVuaTFFMTYuc3MwMQx1bmkxRTE0LnNzMDEMRW9nb25lay5zczAxDHVuaTFFQkMuc3MwMQZGLnNzMDEGRy5zczAxC0dicmV2ZS5zczAxC0djYXJvbi5zczAxEEdjaXJjdW1mbGV4LnNzMDERR2NvbW1hYWNjZW50LnNzMDEPR2RvdGFjY2VudC5zczAxDHVuaTFFMjAuc3MwMQx1bmkwMUU0LnNzMDEGSS5zczAxB0lKLnNzMDELSWFjdXRlLnNzMDEVSWFjdXRlX0oubG9jbE5MRC5zczAxC0licmV2ZS5zczAxEEljaXJjdW1mbGV4LnNzMDEMdW5pMDIwOC5zczAxDklkaWVyZXNpcy5zczAxDHVuaTFFMkUuc3MwMQ9JZG90YWNjZW50LnNzMDEMdW5pMUVDQS5zczAxC0lncmF2ZS5zczAxDHVuaTFFQzguc3MwMQx1bmkwMjBBLnNzMDEMSW1hY3Jvbi5zczAxDElvZ29uZWsuc3MwMQtJdGlsZGUuc3MwMQZKLnNzMDEQSmNpcmN1bWZsZXguc3MwMQx1bmkwMUM3LnNzMDEGTS5zczAxDHVuaTFFNDIuc3MwMQZOLnNzMDEMdW5pMDFDQS5zczAxC05hY3V0ZS5zczAxC05jYXJvbi5zczAxEU5jb21tYWFjY2VudC5zczAxDHVuaTFFNDQuc3MwMQx1bmkxRTQ2LnNzMDEIRW5nLnNzMDEMdW5pMDFDQi5zczAxDHVuaTFFNDguc3MwMQtOdGlsZGUuc3MwMQZRLnNzMDEMdW5pMDE4Ri5zczAxBlQuc3MwMQlUYmFyLnNzMDELVGNhcm9uLnNzMDEMdW5pMDE2Mi5zczAxDHVuaTAyMUEuc3MwMQx1bmkxRTZDLnNzMDEMdW5pMUU2RS5zczAxBlUuc3MwMQtVYWN1dGUuc3MwMQtVYnJldmUuc3MwMQx1bmkwMUQzLnNzMDEQVWNpcmN1bWZsZXguc3MwMQx1bmkwMjE0LnNzMDEOVWRpZXJlc2lzLnNzMDEMdW5pMUVFNC5zczAxC1VncmF2ZS5zczAxDHVuaTFFRTYuc3MwMQpVaG9ybi5zczAxDHVuaTFFRTguc3MwMQx1bmkxRUYwLnNzMDEMdW5pMUVFQS5zczAxDHVuaTFFRUMuc3MwMQx1bmkxRUVFLnNzMDESVWh1bmdhcnVtbGF1dC5zczAxDHVuaTAyMTYuc3MwMQxVbWFjcm9uLnNzMDEMdW5pMUU3QS5zczAxDFVvZ29uZWsuc3MwMQpVcmluZy5zczAxC1V0aWxkZS5zczAxDHVuaTFFNzguc3MwMQZXLnNzMDELV2FjdXRlLnNzMDEQV2NpcmN1bWZsZXguc3MwMQ5XZGllcmVzaXMuc3MwMQtXZ3JhdmUuc3MwMQZZLnNzMDELWWFjdXRlLnNzMDEQWWNpcmN1bWZsZXguc3MwMQ5ZZGllcmVzaXMuc3MwMQx1bmkxRThFLnNzMDEMdW5pMUVGNC5zczAxC1lncmF2ZS5zczAxDHVuaTFFRjYuc3MwMQx1bmkwMjMyLnNzMDEMdW5pMUVGOC5zczAxBlouc3MwMQtaYWN1dGUuc3MwMQtaY2Fyb24uc3MwMQ9aZG90YWNjZW50LnNzMDEMdW5pMUU5Mi5zczAxBmFicmV2ZQd1bmkxRUFGB3VuaTFFQjcHdW5pMUVCMQd1bmkxRUIzB3VuaTFFQjUHdW5pMDFDRQd1bmkxRUE1B3VuaTFFQUQHdW5pMUVBNwd1bmkxRUE5B3VuaTFFQUIHdW5pMDIwMQd1bmkxRUExB3VuaTFFQTMHdW5pMDIwMwdhbWFjcm9uB2FvZ29uZWsKYXJpbmdhY3V0ZQdhZWFjdXRlB3VuaTFFMDkLY2NpcmN1bWZsZXgKY2RvdGFjY2VudAZkY2Fyb24HdW5pMUUwRAd1bmkxRTBGB3VuaTAxQzYGZWJyZXZlBmVjYXJvbgd1bmkxRTFEB3VuaTFFQkYHdW5pMUVDNwd1bmkxRUMxB3VuaTFFQzMHdW5pMUVDNQd1bmkwMjA1CmVkb3RhY2NlbnQHdW5pMUVCOQd1bmkxRUJCB3VuaTAyMDcHZW1hY3Jvbgd1bmkxRTE3B3VuaTFFMTUHZW9nb25lawd1bmkxRUJEB3VuaTAyNTkHdW5pMDI5Mgd1bmkwMUVGBmdjYXJvbgtnY2lyY3VtZmxleAxnY29tbWFhY2NlbnQKZ2RvdGFjY2VudAd1bmkxRTIxB3VuaTAxRTUEaGJhcgd1bmkxRTJCB3VuaTAyMUYLaGNpcmN1bWZsZXgHdW5pMUUyNQZpYnJldmUHdW5pMDIwOQd1bmkxRTJGCWkubG9jbFRSSwd1bmkxRUNCB3VuaTFFQzkHdW5pMDIwQgJpagdpbWFjcm9uB2lvZ29uZWsGaXRpbGRlB3VuaTAyMzcLamNpcmN1bWZsZXgHdW5pMDFFOQxrY29tbWFhY2NlbnQMa2dyZWVubGFuZGljBmxhY3V0ZQZsY2Fyb24MbGNvbW1hYWNjZW50BGxkb3QHdW5pMUUzNwd1bmkwMUM5B3VuaTFFM0IHdW5pMUU0MwZuYWN1dGULbmFwb3N0cm9waGUGbmNhcm9uDG5jb21tYWFjY2VudAd1bmkxRTQ1B3VuaTFFNDcDZW5nB3VuaTAxQ0MHdW5pMUU0OQZvYnJldmUHdW5pMUVEMQd1bmkxRUQ5B3VuaTFFRDMHdW5pMUVENQd1bmkxRUQ3B3VuaTAyMEQHdW5pMDIyQgd1bmkwMjMxB3VuaTFFQ0QHdW5pMUVDRgVvaG9ybgd1bmkxRURCB3VuaTFFRTMHdW5pMUVERAd1bmkxRURGB3VuaTFFRTENb2h1bmdhcnVtbGF1dAd1bmkwMjBGB29tYWNyb24HdW5pMUU1Mwd1bmkxRTUxB3VuaTAxRUILb3NsYXNoYWN1dGUHdW5pMUU0RAd1bmkxRTRGB3VuaTAyMkQGcmFjdXRlBnJjYXJvbgxyY29tbWFhY2NlbnQHdW5pMDIxMQd1bmkxRTVCB3VuaTAyMTMHdW5pMUU1RgZzYWN1dGUHdW5pMUU2NQd1bmlBNzhDB3VuaTFFNjcLc2NpcmN1bWZsZXgMc2NvbW1hYWNjZW50B3VuaTFFNjEHdW5pMUU2Mwd1bmkxRTY5BWxvbmdzBHRiYXIGdGNhcm9uB3VuaTAxNjMHdW5pMDIxQgd1bmkxRTk3B3VuaTFFNkQHdW5pMUU2RgZ1YnJldmUHdW5pMDFENAd1bmkwMjE1B3VuaTFFRTUHdW5pMUVFNwV1aG9ybgd1bmkxRUU5B3VuaTFFRjEHdW5pMUVFQgd1bmkxRUVEB3VuaTFFRUYNdWh1bmdhcnVtbGF1dAd1bmkwMjE3B3VtYWNyb24HdW5pMUU3Qgd1b2dvbmVrBXVyaW5nBnV0aWxkZQd1bmkxRTc5BndhY3V0ZQt3Y2lyY3VtZmxleAl3ZGllcmVzaXMGd2dyYXZlC3ljaXJjdW1mbGV4B3VuaTFFOEYHdW5pMUVGNQZ5Z3JhdmUHdW5pMUVGNwd1bmkwMjMzB3VuaTFFRjkGemFjdXRlCnpkb3RhY2NlbnQHdW5pMUU5MxBpYWN1dGVfai5sb2NsTkxEBmEuc3MwMQthYWN1dGUuc3MwMQthYnJldmUuc3MwMQx1bmkxRUFGLnNzMDEMdW5pMUVCNy5zczAxDHVuaTFFQjEuc3MwMQx1bmkxRUIzLnNzMDEMdW5pMUVCNS5zczAxDHVuaTAxQ0Uuc3MwMRBhY2lyY3VtZmxleC5zczAxDHVuaTFFQTUuc3MwMQx1bmkxRUFELnNzMDEMdW5pMUVBNy5zczAxDHVuaTFFQTkuc3MwMQx1bmkxRUFCLnNzMDEMdW5pMDIwMS5zczAxDmFkaWVyZXNpcy5zczAxDHVuaTFFQTEuc3MwMQthZ3JhdmUuc3MwMQx1bmkxRUEzLnNzMDEMdW5pMDIwMy5zczAxDGFtYWNyb24uc3MwMQxhb2dvbmVrLnNzMDEKYXJpbmcuc3MwMQ9hcmluZ2FjdXRlLnNzMDELYXRpbGRlLnNzMDEHYWUuc3MwMQxhZWFjdXRlLnNzMDEMdW5pMDFDNi5zczAxBmUuc3MwMQtlYWN1dGUuc3MwMQtlYnJldmUuc3MwMQtlY2Fyb24uc3MwMQx1bmkxRTFELnNzMDEQZWNpcmN1bWZsZXguc3MwMQx1bmkxRUJGLnNzMDEMdW5pMUVDNy5zczAxDHVuaTFFQzEuc3MwMQx1bmkxRUMzLnNzMDEMdW5pMUVDNS5zczAxDHVuaTAyMDUuc3MwMQ5lZGllcmVzaXMuc3MwMQ9lZG90YWNjZW50LnNzMDEMdW5pMUVCOS5zczAxC2VncmF2ZS5zczAxDHVuaTFFQkIuc3MwMQx1bmkwMjA3LnNzMDEMZW1hY3Jvbi5zczAxDHVuaTFFMTcuc3MwMQx1bmkxRTE1LnNzMDEMZW9nb25lay5zczAxDHVuaTFFQkQuc3MwMQx1bmkwMjU5LnNzMDEGZi5zczAxBmwuc3MwMQtsYWN1dGUuc3MwMQtsY2Fyb24uc3MwMRFsY29tbWFhY2NlbnQuc3MwMQlsZG90LnNzMDEMdW5pMUUzNy5zczAxDHVuaTAxQzkuc3MwMQx1bmkxRTNCLnNzMDELbHNsYXNoLnNzMDEHb2Uuc3MwMQZ0LnNzMDEJdGJhci5zczAxC3RjYXJvbi5zczAxDHVuaTAxNjMuc3MwMQx1bmkwMjFCLnNzMDEMdW5pMUU5Ny5zczAxDHVuaTFFNkQuc3MwMQx1bmkxRTZGLnNzMDEGdy5zczAxC3dhY3V0ZS5zczAxEHdjaXJjdW1mbGV4LnNzMDEOd2RpZXJlc2lzLnNzMDELd2dyYXZlLnNzMDEGeS5zczAxC3lhY3V0ZS5zczAxEHljaXJjdW1mbGV4LnNzMDEOeWRpZXJlc2lzLnNzMDEMdW5pMUVGNS5zczAxC3lncmF2ZS5zczAxDHVuaTFFRjcuc3MwMQx1bmkwMjMzLnNzMDEMdW5pMUVGOS5zczAxBnouc3MwMQt6YWN1dGUuc3MwMQt6Y2Fyb24uc3MwMQ96ZG90YWNjZW50LnNzMDEMdW5pMUU5My5zczAxA1RfaAdmaS5zczAxB2ZsLnNzMDEEYS5zYwlhYWN1dGUuc2MJYWJyZXZlLnNjCnVuaTFFQUYuc2MKdW5pMUVCNy5zYwp1bmkxRUIxLnNjCnVuaTFFQjMuc2MKdW5pMUVCNS5zYwp1bmkwMUNFLnNjDmFjaXJjdW1mbGV4LnNjCnVuaTFFQTUuc2MKdW5pMUVBRC5zYwp1bmkxRUE3LnNjCnVuaTFFQTkuc2MKdW5pMUVBQi5zYwp1bmkwMjAxLnNjDGFkaWVyZXNpcy5zYwp1bmkxRUExLnNjCWFncmF2ZS5zYwp1bmkxRUEzLnNjCnVuaTAyMDMuc2MKYW1hY3Jvbi5zYwphb2dvbmVrLnNjCGFyaW5nLnNjDWFyaW5nYWN1dGUuc2MJYXRpbGRlLnNjBWFlLnNjCmFlYWN1dGUuc2MEYi5zYwRjLnNjCWNhY3V0ZS5zYwljY2Fyb24uc2MLY2NlZGlsbGEuc2MKdW5pMUUwOS5zYw5jY2lyY3VtZmxleC5zYw1jZG90YWNjZW50LnNjBGQuc2MGZXRoLnNjCWRjYXJvbi5zYwlkY3JvYXQuc2MKdW5pMUUwRC5zYwp1bmkxRTBGLnNjCnVuaTAxQzYuc2MEZS5zYwllYWN1dGUuc2MJZWJyZXZlLnNjCWVjYXJvbi5zYwp1bmkxRTFELnNjDmVjaXJjdW1mbGV4LnNjCnVuaTFFQkYuc2MKdW5pMUVDNy5zYwp1bmkxRUMxLnNjCnVuaTFFQzMuc2MKdW5pMUVDNS5zYwp1bmkwMjA1LnNjDGVkaWVyZXNpcy5zYw1lZG90YWNjZW50LnNjCnVuaTFFQjkuc2MJZWdyYXZlLnNjCnVuaTFFQkIuc2MKdW5pMDIwNy5zYwplbWFjcm9uLnNjCnVuaTFFMTcuc2MKdW5pMUUxNS5zYwplb2dvbmVrLnNjCnVuaTFFQkQuc2MKdW5pMDI1OS5zYwp1bmkwMjkyLnNjCnVuaTAxRUYuc2MEZi5zYwRnLnNjCWdicmV2ZS5zYwlnY2Fyb24uc2MOZ2NpcmN1bWZsZXguc2MPZ2NvbW1hYWNjZW50LnNjDWdkb3RhY2NlbnQuc2MKdW5pMUUyMS5zYwp1bmkwMUU1LnNjBGguc2MHaGJhci5zYwp1bmkxRTJCLnNjCnVuaTAyMUYuc2MOaGNpcmN1bWZsZXguc2MKdW5pMUUyNS5zYwRpLnNjC2RvdGxlc3NpLnNjCWlhY3V0ZS5zYxNpYWN1dGVfai5sb2NsTkxELnNjCWlicmV2ZS5zYw5pY2lyY3VtZmxleC5zYwp1bmkwMjA5LnNjDGlkaWVyZXNpcy5zYwp1bmkxRTJGLnNjDGkuc2MubG9jbFRSSwp1bmkxRUNCLnNjCWlncmF2ZS5zYwp1bmkxRUM5LnNjCnVuaTAyMEIuc2MFaWouc2MKaW1hY3Jvbi5zYwppb2dvbmVrLnNjCWl0aWxkZS5zYwRqLnNjDmpjaXJjdW1mbGV4LnNjBGsuc2MKdW5pMDFFOS5zYw9rY29tbWFhY2NlbnQuc2MPa2dyZWVubGFuZGljLnNjBGwuc2MJbGFjdXRlLnNjCWxjYXJvbi5zYw9sY29tbWFhY2NlbnQuc2MHbGRvdC5zYwp1bmkxRTM3LnNjCnVuaTAxQzkuc2MKdW5pMUUzQi5zYwlsc2xhc2guc2MEbS5zYwp1bmkxRTQzLnNjBG4uc2MJbmFjdXRlLnNjCW5jYXJvbi5zYw9uY29tbWFhY2NlbnQuc2MKdW5pMUU0NS5zYwp1bmkxRTQ3LnNjBmVuZy5zYwp1bmkwMUNDLnNjCnVuaTFFNDkuc2MJbnRpbGRlLnNjBG8uc2MJb2FjdXRlLnNjCW9icmV2ZS5zYw5vY2lyY3VtZmxleC5zYwp1bmkxRUQxLnNjCnVuaTFFRDkuc2MKdW5pMUVEMy5zYwp1bmkxRUQ1LnNjCnVuaTFFRDcuc2MKdW5pMDIwRC5zYwxvZGllcmVzaXMuc2MKdW5pMDIyQi5zYwp1bmkwMjMxLnNjCnVuaTFFQ0Quc2MJb2dyYXZlLnNjCnVuaTFFQ0Yuc2MIb2hvcm4uc2MKdW5pMUVEQi5zYwp1bmkxRUUzLnNjCnVuaTFFREQuc2MKdW5pMUVERi5zYwp1bmkxRUUxLnNjEG9odW5nYXJ1bWxhdXQuc2MKdW5pMDIwRi5zYwpvbWFjcm9uLnNjCnVuaTFFNTMuc2MKdW5pMUU1MS5zYwp1bmkwMUVCLnNjCW9zbGFzaC5zYw5vc2xhc2hhY3V0ZS5zYwlvdGlsZGUuc2MKdW5pMUU0RC5zYwp1bmkxRTRGLnNjCnVuaTAyMkQuc2MFb2Uuc2MEcC5zYwh0aG9ybi5zYwRxLnNjBHIuc2MJcmFjdXRlLnNjCXJjYXJvbi5zYw9yY29tbWFhY2NlbnQuc2MKdW5pMDIxMS5zYwp1bmkxRTVCLnNjCnVuaTAyMTMuc2MKdW5pMUU1Ri5zYwRzLnNjCXNhY3V0ZS5zYwp1bmkxRTY1LnNjCnVuaUE3OEMuc2MJc2Nhcm9uLnNjCnVuaTFFNjcuc2MLc2NlZGlsbGEuc2MOc2NpcmN1bWZsZXguc2MPc2NvbW1hYWNjZW50LnNjCnVuaTFFNjEuc2MKdW5pMUU2My5zYwp1bmkxRTY5LnNjDWdlcm1hbmRibHMuc2MEdC5zYwd0YmFyLnNjCXRjYXJvbi5zYwp1bmkwMTYzLnNjCnVuaTAyMUIuc2MKdW5pMUU5Ny5zYwp1bmkxRTZELnNjCnVuaTFFNkYuc2MEdS5zYwl1YWN1dGUuc2MJdWJyZXZlLnNjCnVuaTAxRDQuc2MOdWNpcmN1bWZsZXguc2MKdW5pMDIxNS5zYwx1ZGllcmVzaXMuc2MKdW5pMUVFNS5zYwl1Z3JhdmUuc2MKdW5pMUVFNy5zYwh1aG9ybi5zYwp1bmkxRUU5LnNjCnVuaTFFRjEuc2MKdW5pMUVFQi5zYwp1bmkxRUVELnNjCnVuaTFFRUYuc2MQdWh1bmdhcnVtbGF1dC5zYwp1bmkwMjE3LnNjCnVtYWNyb24uc2MKdW5pMUU3Qi5zYwp1b2dvbmVrLnNjCHVyaW5nLnNjCXV0aWxkZS5zYwp1bmkxRTc5LnNjBHYuc2MEdy5zYwl3YWN1dGUuc2MOd2NpcmN1bWZsZXguc2MMd2RpZXJlc2lzLnNjCXdncmF2ZS5zYwR4LnNjBHkuc2MJeWFjdXRlLnNjDnljaXJjdW1mbGV4LnNjDHlkaWVyZXNpcy5zYwp1bmkxRThGLnNjCnVuaTFFRjUuc2MJeWdyYXZlLnNjCnVuaTFFRjcuc2MKdW5pMDIzMy5zYwp1bmkxRUY5LnNjBHouc2MJemFjdXRlLnNjCXpjYXJvbi5zYw16ZG90YWNjZW50LnNjCnVuaTFFOTMuc2MJYS5zYy5zczAxDmFhY3V0ZS5zYy5zczAxDmFicmV2ZS5zYy5zczAxD3VuaTFFQUYuc2Muc3MwMQ91bmkxRUI3LnNjLnNzMDEPdW5pMUVCMS5zYy5zczAxD3VuaTFFQjMuc2Muc3MwMQ91bmkxRUI1LnNjLnNzMDEPdW5pMDFDRS5zYy5zczAxE2FjaXJjdW1mbGV4LnNjLnNzMDEPdW5pMUVBNS5zYy5zczAxD3VuaTFFQUQuc2Muc3MwMQ91bmkxRUE3LnNjLnNzMDEPdW5pMUVBOS5zYy5zczAxD3VuaTFFQUIuc2Muc3MwMQ91bmkwMjAxLnNjLnNzMDERYWRpZXJlc2lzLnNjLnNzMDEPdW5pMUVBMS5zYy5zczAxDmFncmF2ZS5zYy5zczAxD3VuaTFFQTMuc2Muc3MwMQ91bmkwMjAzLnNjLnNzMDEPYW1hY3Jvbi5zYy5zczAxD2FvZ29uZWsuc2Muc3MwMQ1hcmluZy5zYy5zczAxEmFyaW5nYWN1dGUuc2Muc3MwMQ5hdGlsZGUuc2Muc3MwMQphZS5zYy5zczAxD2FlYWN1dGUuc2Muc3MwMQ91bmkwMUM2LnNjLnNzMDEJZS5zYy5zczAxDmVhY3V0ZS5zYy5zczAxDmVicmV2ZS5zYy5zczAxDmVjYXJvbi5zYy5zczAxD3VuaTFFMUQuc2Muc3MwMRNlY2lyY3VtZmxleC5zYy5zczAxD3VuaTFFQkYuc2Muc3MwMQ91bmkxRUM3LnNjLnNzMDEPdW5pMUVDMS5zYy5zczAxD3VuaTFFQzMuc2Muc3MwMQ91bmkxRUM1LnNjLnNzMDEPdW5pMDIwNS5zYy5zczAxEWVkaWVyZXNpcy5zYy5zczAxEmVkb3RhY2NlbnQuc2Muc3MwMQ91bmkxRUI5LnNjLnNzMDEOZWdyYXZlLnNjLnNzMDEPdW5pMUVCQi5zYy5zczAxD3VuaTAyMDcuc2Muc3MwMQ9lbWFjcm9uLnNjLnNzMDEPdW5pMUUxNy5zYy5zczAxD3VuaTFFMTUuc2Muc3MwMQ9lb2dvbmVrLnNjLnNzMDEPdW5pMUVCRC5zYy5zczAxD3VuaTAyNTkuc2Muc3MwMQlmLnNjLnNzMDEJZy5zYy5zczAxDmdicmV2ZS5zYy5zczAxDmdjYXJvbi5zYy5zczAxE2djaXJjdW1mbGV4LnNjLnNzMDEUZ2NvbW1hYWNjZW50LnNjLnNzMDESZ2RvdGFjY2VudC5zYy5zczAxD3VuaTFFMjEuc2Muc3MwMQ91bmkwMUU1LnNjLnNzMDEJaS5zYy5zczAxEGRvdGxlc3NpLnNjLnNzMDEOaWFjdXRlLnNjLnNzMDEYaWFjdXRlX2oubG9jbE5MRC5zYy5zczAxDmlicmV2ZS5zYy5zczAxE2ljaXJjdW1mbGV4LnNjLnNzMDEPdW5pMDIwOS5zYy5zczAxEWlkaWVyZXNpcy5zYy5zczAxD3VuaTFFMkYuc2Muc3MwMQ91bmkxRUNCLnNjLnNzMDEOaWdyYXZlLnNjLnNzMDEPdW5pMUVDOS5zYy5zczAxD3VuaTAyMEIuc2Muc3MwMQppai5zYy5zczAxD2ltYWNyb24uc2Muc3MwMQ9pb2dvbmVrLnNjLnNzMDEOaXRpbGRlLnNjLnNzMDEJai5zYy5zczAxE2pjaXJjdW1mbGV4LnNjLnNzMDEPdW5pMDFDOS5zYy5zczAxCW0uc2Muc3MwMQ91bmkxRTQzLnNjLnNzMDEJbi5zYy5zczAxDm5hY3V0ZS5zYy5zczAxDm5jYXJvbi5zYy5zczAxFG5jb21tYWFjY2VudC5zYy5zczAxD3VuaTFFNDUuc2Muc3MwMQ91bmkxRTQ3LnNjLnNzMDELZW5nLnNjLnNzMDEPdW5pMDFDQy5zYy5zczAxD3VuaTFFNDkuc2Muc3MwMQ5udGlsZGUuc2Muc3MwMQlxLnNjLnNzMDEJdC5zYy5zczAxDHRiYXIuc2Muc3MwMQ50Y2Fyb24uc2Muc3MwMQ91bmkwMTYzLnNjLnNzMDEPdW5pMDIxQi5zYy5zczAxD3VuaTFFOTcuc2Muc3MwMQ91bmkxRTZELnNjLnNzMDEPdW5pMUU2Ri5zYy5zczAxCXUuc2Muc3MwMQ51YWN1dGUuc2Muc3MwMQ51YnJldmUuc2Muc3MwMQ91bmkwMUQ0LnNjLnNzMDETdWNpcmN1bWZsZXguc2Muc3MwMQ91bmkwMjE1LnNjLnNzMDERdWRpZXJlc2lzLnNjLnNzMDEPdW5pMUVFNS5zYy5zczAxDnVncmF2ZS5zYy5zczAxD3VuaTFFRTcuc2Muc3MwMQ11aG9ybi5zYy5zczAxD3VuaTFFRTkuc2Muc3MwMQ91bmkxRUYxLnNjLnNzMDEPdW5pMUVFQi5zYy5zczAxD3VuaTFFRUQuc2Muc3MwMQ91bmkxRUVGLnNjLnNzMDEVdWh1bmdhcnVtbGF1dC5zYy5zczAxD3VuaTAyMTcuc2Muc3MwMQ91bWFjcm9uLnNjLnNzMDEPdW5pMUU3Qi5zYy5zczAxD3VvZ29uZWsuc2Muc3MwMQ11cmluZy5zYy5zczAxDnV0aWxkZS5zYy5zczAxD3VuaTFFNzkuc2Muc3MwMQl3LnNjLnNzMDEOd2FjdXRlLnNjLnNzMDETd2NpcmN1bWZsZXguc2Muc3MwMRF3ZGllcmVzaXMuc2Muc3MwMQ53Z3JhdmUuc2Muc3MwMQl5LnNjLnNzMDEOeWFjdXRlLnNjLnNzMDETeWNpcmN1bWZsZXguc2Muc3MwMRF5ZGllcmVzaXMuc2Muc3MwMQ91bmkxRThGLnNjLnNzMDEPdW5pMUVGNS5zYy5zczAxDnlncmF2ZS5zYy5zczAxD3VuaTFFRjcuc2Muc3MwMQ91bmkwMjMzLnNjLnNzMDEPdW5pMUVGOS5zYy5zczAxCXouc2Muc3MwMQ56YWN1dGUuc2Muc3MwMQ56Y2Fyb24uc2Muc3MwMRJ6ZG90YWNjZW50LnNjLnNzMDEPdW5pMUU5My5zYy5zczAxB3VuaTA0MTAHdW5pMDQxMQd1bmkwNDEyB3VuaTA0MTMHdW5pMDQwMwd1bmkwNDkwB3VuaTA0MTQHdW5pMDQxNQd1bmkwNDAwB3VuaTA0MDEHdW5pMDQxNgd1bmkwNDE3B3VuaTA0MTgHdW5pMDQxOQd1bmkwNDBEB3VuaTA0OEEHdW5pMDQxQQd1bmkwNDBDB3VuaTA0MUIHdW5pMDQxQwd1bmkwNDFEB3VuaTA0MUUHdW5pMDQxRgd1bmkwNDIwB3VuaTA0MjEHdW5pMDQyMgd1bmkwNDIzB3VuaTA0MEUHdW5pMDQyNAd1bmkwNDI1B3VuaTA0MjcHdW5pMDQyNgd1bmkwNDI4B3VuaTA0MjkHdW5pMDQwRgd1bmkwNDJDB3VuaTA0MkEHdW5pMDQyQgd1bmkwNDA5B3VuaTA0MEEHdW5pMDQwNQd1bmkwNDA0B3VuaTA0MkQHdW5pMDQwNgd1bmkwNDA3B3VuaTA0MDgHdW5pMDQwQgd1bmkwNDJFB3VuaTA0MkYHdW5pMDQwMgd1bmkwNDYyB3VuaTA0NkEHdW5pMDQ3Mgd1bmkwNDc0B3VuaTA0OTIHdW5pMDQ5NAd1bmkwNDk2B3VuaTA0OTgHdW5pMDQ5QQd1bmkwNDlDB3VuaTA0OUUHdW5pMDRBMAd1bmkwNEEyB3VuaTA0QTQHdW5pMDRBNgd1bmkwNTI0B3VuaTA0QTgHdW5pMDRBQQd1bmkwNEFDB3VuaTA0QUUHdW5pMDRCMAd1bmkwNEIyB3VuaTA0QjQHdW5pMDRCNgd1bmkwNEI4B3VuaTA0QkEHdW5pMDUyNgd1bmkwNEJDB3VuaTA0QkUHdW5pMDRDMAd1bmkwNEMxB3VuaTA0QzMHdW5pMDRDNwd1bmkwNEM5B3VuaTA0Q0IHdW5pMDRDRAd1bmkwNEQwB3VuaTA0RDIHdW5pMDRENAd1bmkwNEQ2B3VuaTA0RDgHdW5pMDREQQd1bmkwNERDB3VuaTA0REUHdW5pMDRFMAd1bmkwNEUyB3VuaTA0RTQHdW5pMDRFNgd1bmkwNEU4B3VuaTA0RUEHdW5pMDRFQwd1bmkwNEVFB3VuaTA0RjAHdW5pMDRGMgd1bmkwNEY0B3VuaTA0RjYHdW5pMDRGOAd1bmkwNEZBB3VuaTA0RkMHdW5pMDRGRQd1bmkwNTEwB3VuaTA1MTIHdW5pMDUxQQd1bmkwNTFDB3VuaTA0OEMHdW5pMDQ4RQd1bmkwNTI4B3VuaTA1MkUPdW5pMDQxNC5sb2NsQkdSD3VuaTA0MUIubG9jbEJHUg91bmkwNDI0LmxvY2xCR1IPdW5pMDQ5Mi5sb2NsQlNID3VuaTA0OTgubG9jbEJTSA91bmkwNEFBLmxvY2xCU0gPdW5pMDRBQS5sb2NsQ0hVDHVuaTA0MTAuc3MwMQx1bmkwNDE0LnNzMDEMdW5pMDQxNS5zczAxDHVuaTA0MDAuc3MwMQx1bmkwNDAxLnNzMDEMdW5pMDQxOC5zczAxDHVuaTA0MTkuc3MwMQx1bmkwNDhBLnNzMDEMdW5pMDQwRC5zczAxDHVuaTA0MUIuc3MwMQx1bmkwNDIwLnNzMDEMdW5pMDQyMi5zczAxDHVuaTA0MjMuc3MwMQx1bmkwNDBFLnNzMDEMdW5pMDQyNC5zczAxDHVuaTA0MkMuc3MwMQx1bmkwNDJBLnNzMDEMdW5pMDQyQi5zczAxDHVuaTA0MDkuc3MwMQx1bmkwNDBBLnNzMDEMdW5pMDQwOC5zczAxDHVuaTA0NjIuc3MwMQx1bmkwNEFDLnNzMDEMdW5pMDREMC5zczAxDHVuaTA0RDIuc3MwMQx1bmkwNEQ0LnNzMDEMdW5pMDRENi5zczAxDHVuaTA0RTIuc3MwMQx1bmkwNEU0LnNzMDEMdW5pMDRFRS5zczAxDHVuaTA0RjAuc3MwMQx1bmkwNEYyLnNzMDEMdW5pMDRGOC5zczAxDHVuaTA1MUEuc3MwMQx1bmkwNDhDLnNzMDEHdW5pMDQzMAd1bmkwNDMxB3VuaTA0MzIHdW5pMDQzMwd1bmkwNDUzB3VuaTA0OTEHdW5pMDQzNAd1bmkwNDM1B3VuaTA0NTAHdW5pMDQ1MQd1bmkwNDM2B3VuaTA0MzcHdW5pMDQzOAd1bmkwNDM5B3VuaTA0NUQHdW5pMDQ4Qgd1bmkwNDNBB3VuaTA0NUMHdW5pMDQzQgd1bmkwNDNDB3VuaTA0M0QHdW5pMDQzRQd1bmkwNDNGB3VuaTA0NDAHdW5pMDQ0MQd1bmkwNDQyB3VuaTA0NDMHdW5pMDQ1RQd1bmkwNDQ0B3VuaTA0NDUHdW5pMDQ0Nwd1bmkwNDQ2B3VuaTA0NDgHdW5pMDQ0OQd1bmkwNDVGB3VuaTA0NEMHdW5pMDQ0QQd1bmkwNDRCB3VuaTA0NTkHdW5pMDQ1QQd1bmkwNDU1B3VuaTA0NTQHdW5pMDQ0RAd1bmkwNDU2B3VuaTA0NTcHdW5pMDQ1OAd1bmkwNDVCB3VuaTA0NEUHdW5pMDQ0Rgd1bmkwNDUyB3VuaTA0NjMHdW5pMDQ2Qgd1bmkwNDczB3VuaTA0NzUHdW5pMDQ5Mwd1bmkwNDk1B3VuaTA0OTcHdW5pMDQ5OQd1bmkwNDlCB3VuaTA0OUQHdW5pMDQ5Rgd1bmkwNEExB3VuaTA0QTMHdW5pMDRBNQd1bmkwNTI1B3VuaTA0QTcHdW5pMDRBOQd1bmkwNEFCB3VuaTA0QUQHdW5pMDRBRgd1bmkwNEIxB3VuaTA0QjMHdW5pMDRCNQd1bmkwNEI3B3VuaTA0QjkHdW5pMDRCQgd1bmkwNTI3B3VuaTA0QkQHdW5pMDRCRgd1bmkwNENGB3VuaTA0QzIHdW5pMDRDNAd1bmkwNEM2B3VuaTA0QzgHdW5pMDRDQQd1bmkwNENDB3VuaTA0Q0UHdW5pMDREMQd1bmkwNEQzB3VuaTA0RDUHdW5pMDRENwd1bmkwNEQ5B3VuaTA0REIHdW5pMDRERAd1bmkwNERGB3VuaTA0RTEHdW5pMDRFMwd1bmkwNEU1B3VuaTA0RTcHdW5pMDRFOQd1bmkwNEVCB3VuaTA0RUQHdW5pMDRFRgd1bmkwNEYxB3VuaTA0RjMHdW5pMDRGNQd1bmkwNEY3B3VuaTA0RjkHdW5pMDRGQgd1bmkwNEZEB3VuaTA0RkYHdW5pMDUxMQd1bmkwNTEzB3VuaTA1MUIHdW5pMDUxRAd1bmkwNDhEB3VuaTA0OEYHdW5pMDUyOQd1bmkwNTJGD3VuaTA0MzIubG9jbEJHUg91bmkwNDMzLmxvY2xCR1IPdW5pMDQzNC5sb2NsQkdSD3VuaTA0MzYubG9jbEJHUg91bmkwNDM3LmxvY2xCR1IPdW5pMDQzOC5sb2NsQkdSD3VuaTA0MzkubG9jbEJHUg91bmkwNDVELmxvY2xCR1IPdW5pMDQzQS5sb2NsQkdSD3VuaTA0M0IubG9jbEJHUg91bmkwNDNELmxvY2xCR1IPdW5pMDQzRi5sb2NsQkdSD3VuaTA0NDIubG9jbEJHUg91bmkwNDQ3LmxvY2xCR1IPdW5pMDQ0Ni5sb2NsQkdSD3VuaTA0NDgubG9jbEJHUg91bmkwNDQ5LmxvY2xCR1IPdW5pMDQ0Qy5sb2NsQkdSD3VuaTA0NEEubG9jbEJHUg91bmkwNDRFLmxvY2xCR1IPdW5pMDQ5My5sb2NsQlNID3VuaTA0OTkubG9jbEJTSA91bmkwNEFCLmxvY2xDSFUPdW5pMDQ1My5sb2NsTUtED3VuaTA0MzEubG9jbFNSQg91bmkwNDMzLmxvY2xTUkIPdW5pMDQzNC5sb2NsU1JCD3VuaTA0M0YubG9jbFNSQg91bmkwNDQyLmxvY2xTUkIMdW5pMDQzMC5zczAxDHVuaTA0MzQuc3MwMQx1bmkwNDM1LnNzMDEMdW5pMDQ1MC5zczAxDHVuaTA0NTEuc3MwMQx1bmkwNDM4LnNzMDEMdW5pMDQzOS5zczAxDHVuaTA0OEIuc3MwMQx1bmkwNDVELnNzMDEMdW5pMDQ0MC5zczAxDHVuaTA0NDIuc3MwMQx1bmkwNDQzLnNzMDEMdW5pMDQ1RS5zczAxDHVuaTA0NEMuc3MwMQx1bmkwNDRBLnNzMDEMdW5pMDQ0Qi5zczAxDHVuaTA0NTkuc3MwMQx1bmkwNDVBLnNzMDEMdW5pMDQ2My5zczAxDHVuaTA0RDEuc3MwMQx1bmkwNEQzLnNzMDEMdW5pMDRENS5zczAxDHVuaTA0RDcuc3MwMQx1bmkwNEQ5LnNzMDEMdW5pMDREQi5zczAxDHVuaTA0RTMuc3MwMQx1bmkwNEU1LnNzMDEMdW5pMDRFRi5zczAxDHVuaTA0RjEuc3MwMQx1bmkwNEYzLnNzMDEMdW5pMDRGOS5zczAxDHVuaTA0OEQuc3MwMQd1bmkwMzk0B3VuaTAzQTkHdW5pMDNCQwd1bmkyMTJCB3VuaTIxMkEIemVyby5vc2YHb25lLm9zZgd0d28ub3NmCXRocmVlLm9zZghmb3VyLm9zZghmaXZlLm9zZgdzaXgub3NmCXNldmVuLm9zZgllaWdodC5vc2YIbmluZS5vc2YJemVyby5zaW5mCG9uZS5zaW5mCHR3by5zaW5mCnRocmVlLnNpbmYJZm91ci5zaW5mCWZpdmUuc2luZghzaXguc2luZgpzZXZlbi5zaW5mCmVpZ2h0LnNpbmYJbmluZS5zaW5mB3plcm8udGYGb25lLnRmBnR3by50Zgh0aHJlZS50Zgdmb3VyLnRmB2ZpdmUudGYGc2l4LnRmCHNldmVuLnRmCGVpZ2h0LnRmB25pbmUudGYJemVyby50b3NmCG9uZS50b3NmCHR3by50b3NmCnRocmVlLnRvc2YJZm91ci50b3NmCWZpdmUudG9zZghzaXgudG9zZgpzZXZlbi50b3NmCmVpZ2h0LnRvc2YJbmluZS50b3NmB3VuaTIwODAHdW5pMjA4MQd1bmkyMDgyB3VuaTIwODMHdW5pMjA4NAd1bmkyMDg1B3VuaTIwODYHdW5pMjA4Nwd1bmkyMDg4B3VuaTIwODkJemVyby5kbm9tCG9uZS5kbm9tCHR3by5kbm9tCnRocmVlLmRub20JZm91ci5kbm9tCWZpdmUuZG5vbQhzaXguZG5vbQpzZXZlbi5kbm9tCmVpZ2h0LmRub20JbmluZS5kbm9tCXplcm8ubnVtcghvbmUubnVtcgh0d28ubnVtcgp0aHJlZS5udW1yCWZvdXIubnVtcglmaXZlLm51bXIIc2l4Lm51bXIKc2V2ZW4ubnVtcgplaWdodC5udW1yCW5pbmUubnVtcgd1bmkyMDcwB3VuaTAwQjkHdW5pMDBCMgd1bmkwMEIzB3VuaTIwNzQHdW5pMjA3NQd1bmkyMDc2B3VuaTIwNzcHdW5pMjA3OAd1bmkyMDc5B3VuaTIxNTMHdW5pMjE1NAlvbmVlaWdodGgMdGhyZWVlaWdodGhzC2ZpdmVlaWdodGhzDHNldmVuZWlnaHRocw5iYWNrc2xhc2guY2FzZRNwZXJpb2RjZW50ZXJlZC5jYXNlC2J1bGxldC5jYXNlG3BlcmlvZGNlbnRlcmVkLmxvY2xDQVQuY2FzZQpzbGFzaC5jYXNlFnBlcmlvZGNlbnRlcmVkLmxvY2xDQVQOYnJhY2VsZWZ0LmNhc2UPYnJhY2VyaWdodC5jYXNlEGJyYWNrZXRsZWZ0LmNhc2URYnJhY2tldHJpZ2h0LmNhc2UOcGFyZW5sZWZ0LmNhc2UPcGFyZW5yaWdodC5jYXNlCmZpZ3VyZWRhc2gHdW5pMjAxNQd1bmkyMDEwB3VuaTAwQUQLZW1kYXNoLmNhc2ULZW5kYXNoLmNhc2ULaHlwaGVuLmNhc2USZ3VpbGxlbW90bGVmdC5jYXNlE2d1aWxsZW1vdHJpZ2h0LmNhc2USZ3VpbHNpbmdsbGVmdC5jYXNlE2d1aWxzaW5nbHJpZ2h0LmNhc2UJZXhjbGFtLnNjDWV4Y2xhbWRvd24uc2MQZ3VpbGxlbW90bGVmdC5zYxFndWlsbGVtb3RyaWdodC5zYxBndWlsc2luZ2xsZWZ0LnNjEWd1aWxzaW5nbHJpZ2h0LnNjCXBlcmlvZC5zYwtxdWVzdGlvbi5zYw9xdWVzdGlvbmRvd24uc2MLcXVvdGVkYmwuc2MPcXVvdGVkYmxiYXNlLnNjD3F1b3RlZGJsbGVmdC5zYxBxdW90ZWRibHJpZ2h0LnNjDHF1b3RlbGVmdC5zYw1xdW90ZXJpZ2h0LnNjEXF1b3Rlc2luZ2xiYXNlLnNjDnF1b3Rlc2luZ2xlLnNjB3VuaTI3RTgHdW5pMjdFOQd1bmkyMDA3B3VuaTIwMEEHdW5pMjAwOAd1bmkwMEEwB3VuaTIwMDkHdW5pMjAwQgd1bmkyMEI1DWNvbG9ubW9uZXRhcnkEZG9uZwRFdXJvB3VuaTIwQjIHdW5pMjBCNAd1bmkyMEFEBGxpcmEHdW5pMjBCQQd1bmkyMEJDB3VuaTIwQTYGcGVzZXRhB3VuaTIwQjEHdW5pMjBCRAd1bmkyMEI5B3VuaTIwQjgHdW5pMjBBRQd1bmkyMEE5B3VuaTIyMTkHdW5pMjA1Mgd1bmkyMjE1CGVtcHR5c2V0B3VuaTIxMjYHdW5pMjIwNgd1bmkwMEI1B2Fycm93dXAHdW5pMjE5NwphcnJvd3JpZ2h0B3VuaTIxOTgJYXJyb3dkb3duB3VuaTIxOTkJYXJyb3dsZWZ0B3VuaTIxOTYJYXJyb3dib3RoCWFycm93dXBkbgxhcnJvd3VwLmNhc2UPYXJyb3dyaWdodC5jYXNlDmFycm93ZG93bi5jYXNlDmFycm93bGVmdC5jYXNlB3VuaTI1QzYHdW5pMjVDNwlmaWxsZWRib3gHdW5pMjVBMQd0cmlhZ3VwB3VuaTI1QjYHdHJpYWdkbgd1bmkyNUMwB3VuaTI1QjMHdW5pMjVCNwd1bmkyNUJEB3VuaTI1QzEHdW5pMjExMwllc3RpbWF0ZWQHdW5pMjExNgZtaW51dGUGc2Vjb25kB2F0LmNhc2UMdW5pMjExNi5zczAxDGFtcGVyc2FuZC5zYwd1bmkwMzA4C3VuaTAzMDgwMzAwC3VuaTAzMDgwMzAxC3VuaTAzMDgwMzA0B3VuaTAzMDcLdW5pMDMwNzAzMDQJZ3JhdmVjb21iC3VuaTAzMDAwMzA0CWFjdXRlY29tYgt1bmkwMzAxMDMwNwt1bmkwMzAxMDMwNAd1bmkwMzBCDWNhcm9uY29tYi5hbHQHdW5pMDMwMgd1bmkwMzBDC3VuaTAzMEMwMzA3B3VuaTAzMDYHdW5pMDMwQQt1bmkwMzBBMDMwMQl0aWxkZWNvbWILdW5pMDMwMzAzMDgTdGlsZGVjb21iX2FjdXRlY29tYgt1bmkwMzAzMDMwNAd1bmkwMzA0C3VuaTAzMDQwMzA4C3VuaTAzMDQwMzAwC3VuaTAzMDQwMzAxDWhvb2thYm92ZWNvbWIHdW5pMDMwRgd1bmkwMzExB3VuaTAzMTIHdW5pMDMxQgxkb3RiZWxvd2NvbWIHdW5pMDMyNAd1bmkwMzI2B3VuaTAzMjcHdW5pMDMyOAd1bmkwMzJFB3VuaTAzMzEHdW5pMDMzNQd1bmkwMzM2B3VuaTAzMzcHdW5pMDMzOAx1bmkwMzA4LmNhc2UQdW5pMDMwODAzMDAuY2FzZRB1bmkwMzA4MDMwMS5jYXNlEHVuaTAzMDgwMzA0LmNhc2UMdW5pMDMwNy5jYXNlEHVuaTAzMDcwMzA0LmNhc2UOZ3JhdmVjb21iLmNhc2UQdW5pMDMwMDAzMDQuY2FzZQ5hY3V0ZWNvbWIuY2FzZRB1bmkwMzAxMDMwNy5jYXNlEHVuaTAzMDEwMzA0LmNhc2UMdW5pMDMwQi5jYXNlDHVuaTAzMDIuY2FzZQx1bmkwMzBDLmNhc2UQdW5pMDMwQzAzMDcuY2FzZQx1bmkwMzA2LmNhc2UOdGlsZGVjb21iLmNhc2UQdW5pMDMwMzAzMDguY2FzZRh0aWxkZWNvbWJfYWN1dGVjb21iLmNhc2UQdW5pMDMwMzAzMDQuY2FzZQx1bmkwMzA0LmNhc2UQdW5pMDMwNDAzMDguY2FzZRB1bmkwMzA0MDMwMC5jYXNlEHVuaTAzMDQwMzAxLmNhc2USaG9va2Fib3ZlY29tYi5jYXNlDHVuaTAzMEYuY2FzZQx1bmkwMzExLmNhc2UMdW5pMDMzNS5jYXNlDHVuaTAzMzcuY2FzZQx1bmkwMzM4LmNhc2UTdW5pMDMwNC5uYXJyb3cuY2FzZQl1bmkwMzA3LmkJdW5pMDMyOC5pEHVuaTAzMDgubG9jbFZJRVQQdW5pMDMwNy5sb2NsVklFVBJncmF2ZWNvbWIubG9jbFZJRVQSYWN1dGVjb21iLmxvY2xWSUVUEHVuaTAzMDIubG9jbFZJRVQQdW5pMDMwQy5sb2NsVklFVBB1bmkwMzA2LmxvY2xWSUVUEnRpbGRlY29tYi5sb2NsVklFVBB1bmkwMzA0LmxvY2xWSUVUFmhvb2thYm92ZWNvbWIubG9jbFZJRVQOdW5pMDMwOC5uYXJyb3cOdW5pMDMwMi5uYXJyb3cOdW5pMDMwNi5uYXJyb3cQdGlsZGVjb21iLm5hcnJvdw51bmkwMzA0Lm5hcnJvdw51bmkwMzExLm5hcnJvdxNjYXJvbmNvbWIuYWx0LnNob3J0CXVuaTAzMzUudAd1bmkwMkJDB3VuaTAyQkIHdW5pMDJCQQd1bmkwMkM5B3VuaTAyQ0IHdW5pMDJCOQd1bmkwMkJGB3VuaTAyQkUHdW5pMDJDQQd1bmkwMkNDB3VuaTAyQzgKdW5pMDMzNS5zYwp1bmkwMzM2LnNjCnVuaTAzMzguc2MLYnJldmVjb21iY3kQYnJldmVjb21iY3kuY2FzZQtkZXNjZW5kZXJjeRBkZXNjZW5kZXJjeS5jYXNlFmRlc2NlbmRlcmN5LmNhc2Uuc2hvcnQRZGVzY2VuZGVyY3kuc2hvcnQLdW5pMDMwNjAzMDELdW5pMDMwNjAzMDALdW5pMDMwNjAzMDkLdW5pMDMwNjAzMDMLdW5pMDMwMjAzMDELdW5pMDMwMjAzMDALdW5pMDMwMjAzMDkLdW5pMDMwMjAzMDMQdW5pMDMwNjAzMDEuY2FzZRB1bmkwMzA2MDMwMC5jYXNlEHVuaTAzMDYwMzA5LmNhc2UQdW5pMDMwNjAzMDMuY2FzZRB1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AAMAAAAAAAMAAwADAAMACAADAAAAAAAAAAAAGwAAAAD/9gAAAAAACAAAAAAAAAAA/+wAAAAAAAAAAAAAAAAAAAAAAAAAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/+QAAAAAAAAAAAAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/2AAAAAAAHAAAAAP/2AAD/9AAAAAAAAAAAAAAAAAAAAAAAAAAA/8cAAAAAAAAAAAAAAAAAAAAHAAAABwAAAAAAAAAAAAD//QAAAAAAAAAAAAP/9gAIAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkAAP/2AAAAAAAKAAoAAAAA//YAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/7QAAAAAAAwAAAAoAAAAKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//bAAoAAAAAAAMAAwADAAMAAwADAAAAAAAAAAAAEwAAAAD/9gAAAAAAAAAAAAD/9gAA/+wAAAAAAAAAAAAAAAAAAAAAAAAAAP+/AAAAAAAAAAAAAAAAAAAAAAAAAAcAAP/2//YAAAAN/+7/qQAAAAD/2//5/9j/3gAA//kAAAADAAAAAwAAAAMAAAAK//YACAAA/+z/9v/s//P//QAAAAcAAAADAAD/6QAAAAf/9gAHAAAAAAAAAAAAAAAA/9YAAAAAAAAAAAAAAAAAAAAAAAcAAP/2AAAAAAAAAAD/8QAAAAAAAAAA//H/2AAA/+b/9AAAAAAAAAAAAAAAAAAAAAD//QAAAAD/5wAAAAD/4gAAAAAAAAAAAAAAAAAAAAAAAP/5AAcAAAAAAAAAAAAAAAAAJgAIAAgAAAAAAAAAAAAAAAAAAP/s/+8AAAAAAAAAAAAKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIQAAAAAAHAAAAAAAAwAAAAAAAAAAAA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAsAAAAAAAAAAAAAAADAAAAAAAA/+//9wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAmAAAAAAAAAAAAAAAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/58AAAAAAAD/wQADAAMAAwAA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BiUADAYmBicANQYoBigAMQYpBioAEAYrBisAQQYsBiwAQgYuBi4AEAYvBi8AEQYwBjAAEgYxBjIAFAYzBjMAMQY0BjQAKwY1BjUALQY2BjYADAY3BjgAUQY6BjoAKwY9Bj0ATQY/Bj8ATQZDBkMATgZFBkUATgZHBkcAUwZMBk4ANQZRBlEAUQZSBlIANQZTBlMARQZUBlQANQZVBlUARQZWBlYAEAZXBlcAEwZYBlgAOwZZBlkAEwZaBloAOwZbBlsAEAZcBlwAUQZdBl0AUAZeBl4AUQZfBl8AUAZiBmIANQZkBmQANQZmBmYAEAZqBmoAEAZvBm8AEAZ5BnkAJQZ6BnoAOAZ7BnsAJQZ8BnwAMgZ9Bn0AJgZ+Bn4AOAZ/Bn8AMgaABoAAKAaBBoEAMgaCBoIAJQaEBoQAMgaFBoUANgaGBoYAMgaIBogAMgaKBosAMgaMBowAFQaNBo0ANgaQBpAAMgaRBpEAGwaUBpQAKwaVBpYANQaYBpgANQahBqIANQanBqcAAQaqBqoANQarBqsAUgatBq4ADwbKBsoAJQbLBssAMAbMBswAOgbNBs0AFgbOBs8AJQbQBtAAPQbRBtEAHgbXBtcAJQbaBtsAFAbcBtwAJQc+Bz4AEwACAAgACgAaBJgFCjDQQfBOrlTMbU6FfI8WAAEAsgAEAAAAVAQKAV4BaAGGAYYBhgGGAYYBhgGGAbQBtAG0AbQBtAG0Af4B/gH+Af4B/gH+Af4B/gH+Af4ENAIoAigCKAIoAigCKAIoA44ClgJCA6oCjAJQAmICcAJ+AowClgKgAs4C3AOOA5wDqgPcBF4EXgReBFgEWAPuBE4D9AROA/4D/gQEBFgEWARYBFgEWARwBHAEWARYBAoENAQ0BE4EWARYBFgEWAReBF4EcAABAFQASQCUAKkAwADBAMIAwwDEAMUAxgDfAOAA4QDiAOMA5ADmAOcA6ADpAOoA6wDsAO0A7gDvASsBVwFYAVkBWgFbAVwBXQGgAbABygHPAd4B4gHjAeoB7QHvAfgB/gIxAkoCTAJkArQDhQRkBGUGJAYmBicGMAY0BjUGOgY8Bj4GQAZMBk0GTgZTBlUGVwZZBmMGZQaBBoUGjQaUBpUGlgaYBqEG2AbdBz4AAgYlAAYGNgAGAAcGNAApBjUAKAY6ACkGPQAIBj8ACAZHAAMGlAApAAsB4QAZ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//YAAAAAAAAAAAAAAAAAAAAAAAD/7wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAAAAAAoAAAAA//YAAAAAAAAAAAAAAAAAAAAA//YAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/s//cAAAAAAAAAAAAAAAD/+QAAAAAAAAAAAAD/9QAA//cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//kAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//0AAP/2AAAAAAAAAAAAAAAA//sAAAAA//0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//kAAAAAAAAAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/j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ACMCmQKaAE0CmwKzACMCtAK9AG8CvgK+ACMCvwLGAG8CxwLUADoC1QLZAEMC2gLaAAYC2wLcADMC3gLeADMC3wL6AE4C+wL7AFUC/AMCACQDAwMgAFUDIQMhACQDJAMkAFUDJQMsACQDLQNEAFUDRQNGAB8DRwNfAFUDYAOCACQDgwOEAFUDhQOFACQDhgONAFUDjgOQAFcDkgOZAFcDmwOiADQDowO6ADsDuwPAAD4DwQPBAEADwgPLAEEDzAPQAFoD0QPqAE8D7QPtAFUD7gQEABQEBQQFACQEBgQGAFIEBwQOACQEDwQRAFsEEgQSAFUEEwQbAFsEHAQcAFUEHQQfAFsEIAQhACAEIgQuAFUELwQvACQEMAQ3ADQEOARUADsEVQReAEIEXwRjAFoEZARlAA0EZgRmAEYEZwRrAGsEbARsAEcEbQRvAGsEcARwAAoEcQRxAEsEcgR3AGsEeAR4AEcEeQR6AGsEewR7AAUEfAR9AGsEfgR+AAUEfwR/AAYEgASBAAoEggSCAAUEgwSDAAoEhASEAAEEhQSJAGsEigSKAAYEiwSLAGsEjASMAEcEjQSNAGsEjgSOAEwEjwSPAAUEkASQAEsEkQSSAGsEkwSTAAMElASUAAYElQSVAGsElgSWAAoElwSYAAYEmQSZAAoEmgSaAAUEmwSbAAkEnQSdAGsEngSeAAoEnwSfAEsEoASiAGsEowSjAAYEpASnAGsEqASpAAUEqgSqAAYEqwSsAAsErQStAAoErgSuAAYErwSwAAEEsQSyAGsEswS0AAIEtQS1AGsEtgS2AAoEtwS5AGsEugS6AAEEuwS7AGsEvAS+AEYEvwS/AGsEwATBAAUEwgTCAAoEwwTEAEsExQTGAGsExwTJAAUEygTKAEsEywTNAAoEzgTOAAEEzwTRAGsE0gTTAAoE1ATUAEoE1QTVAEcE1gTWAAUE1wTXAAkE2ATaAGsE2wTcAEcE3QTdAEYE3gTeAAUE3wTfAGsE4QTiAAUE4wTjAFwE5ATkAF4E5QTnAEoE6ATrAGsE7ATsAEkE7QTtAFwE7gTuAAcE7wTwAAwE8QTxAAUE8gTyAAgE8wTzAAYE9AT0AAgE9QT1AEcE9gT2AGsE9wT3AAQE+QT5AAcE+gT7AFwE/AT8AEYE/QT9AEoE/gT/AGsFAAUCAAwFBAUEAAUFBQUFAAgFBgUGAE0FBwUHAAUFCAULAGUFDAUMAEgFDQUPACMFEAUQAD8FEQURAFEFEgUXAGUFGAUYAEgFGQUaAGUFGwUbACMFHAUdAGUFHgUeACMFHwUfADUFIAUhAD0FIgUiACMFIwUjAD8FJAUkADoFJQUpAGUFKgUqADUFKwUrAGUFLAUsAEgFLQUtAGUFLgUuAC4FLwUvACMFMAUwAFEFMQUyAGUFMwUzAGQFNAU0AG0FNQU1AGUFNgU2AD8FNwU3AG8FOAU4ADUFOQU5AD8FOgU6ACMFOwU7AD0FPAU8ABkFPQU9AGUFPgU+AD8FPwU/AFEFQAVBAGUFQgVCAG8FQwVDADUFRAVHAGUFSAVJACMFSgVKADUFSwVMAD0FTQVNAD8FTgVOADUFTwVQADoFUQVSAG8FUwVUABEFVQVVAG8FVgVWAD8FVwVXAGUFWAVYAEgFWQVaAGUFWwVbADoFXAVcAGUFXQVfAE0FYAViACMFYwVjAD8FZAVlAFEFZgVnAGUFaAVqACMFawVrAFEFbAVuAD0FbwVvADoFcAVyAGUFcwV0AD8FdQV1AFYFdgV2AEgFdwV3ACMFeAV4AD0FeQV5AC8FegV6AGUFewV7AGQFfAV8AEgFfQV9ACMFfgV+AC4FfwV/ACMFgAWAAD8FgQWBAFEFggWEADoFhQWFAG8FhgWGAEgFhwWJAGUFigWOADoFjwWPADUFkAWQAG8FkQWRAGUFkgWSAFEFkwWTACMFlAWUAGUFlQWVAA8FlgWWAGUFlwWXACMFmAWZADoFmgWeACMFnwWiADoFowWjAG4FpQWnADoFqAWoABwFqQWpADoFqgWqAEgFqwWrAGUFrQWuACMFrwWvAE0FsAWxACMFswW4ADoFuQW5AC8FugW6AEYFvgW+AEYFvwW/AGsFwAXAAEQFwQXBACUFwgXCAFkFwwXDADYFxAXEABcFxQXFAFMFxgXGAEQFxwXHADAFyAXIABUFyQXJACEFygXKAEUFywXLACYFzAXMADkFzQXNADcFzgXOABgFzwXPAFQF0AXQAEQF0QXRADEF0gXSABUF0wXTACIGJAYkAA0GJQYlAA4GJgYnAB0GKAYoABIGKQYqACgGKwYrAGAGLAYsABYGLgYuACgGLwYvACkGMAYwACoGMQYyAC0GMwYzABIGNAY0ADIGNQY1ADwGNgY2AA4GNwY4AB4GOgY6ADIGPQY9AF8GPgY+AGcGPwY/AF8GQAZAAGwGQQZBAF0GQwZDABAGRQZFABAGRwZHAGoGTAZOAB0GUQZRAB4GUgZSAB0GUwZTABsGVAZUAB0GVQZVABsGVgZWACgGVwZXACsGWAZYACwGWQZZACsGWgZaACwGWwZbACgGXAZcAB4GXQZdABoGXgZeAB4GXwZfABoGYAZgAGEGYQZhAGIGYgZiAB0GYwZjAGMGZAZkAB0GZQZlAGMGZgZmACgGagZqACgGbwZvACgGeQZ5AAUGegZ6ACMGewZ7AAUGfQZ9AEwGfgZ+ACMGggaCAAUGhwaHAGsGiQaJAGsGlAaUADIGlQaWAB0GmAaYAB0GoQaiAB0GpwanAEYGqAaoAGsGqgaqAB0GqwarAGUGygbKAAUGywbLAFAGzAbMACcGzQbNAFgGzgbPAAUG0AbQADgG0QbRABMG1QbWAGYG1wbXAAUG2AbYAGsG2gbbAC0G3AbcAAUHPgc+ACsAAgxAAAQAAAxiDeAAGgA8AAD/+f+o/7j/ngAKAAoAA//zAAEAB//2//gAD//5//b/9v/V/9r/0AAU/8T/zgAS/9//3//f/9//1f/YAB7/3f/xADL/2//f/9b/9v/0//kAAwAI//IAAwADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/2/8z/5QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/9//n/+QAA/9j/9AAA//T/+f/0//T/9v/5AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//0AAAAA//QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/8cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/2//kAAAAK/+IAAAAAAAAAAAAAAAAAAAAAAAD/9gAAAAD/+//2//EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/+QAR/9EADQAA//YAAP/q/+sAAAAA//MAAP/5//j/8f/5AAMAAAAA/+IACAAAABT//QANAAAAAAAAAAAAAAAAAAD/+f/v//QAAP/u/+///f/z//b/+QAA//L/7//s//n/8//5//3/9QAAAAAAAAAAAAAAAAAAAAAAAAAA/9EAAAAA//kAAP/0AAAAAAAAAAAAAP/0AAD//QAAAAMAAAAFAAD/+QAAAAAAAAAAAAAAAwAAAAoAAAAAABv/+f/5//kAAAAAAAAAAP/3AAAAAAAAAAAAAP/5//n/+QAAAAAAAP/5AAAAAAAAAAAAAAAAAAD/+QAK/8UAA//7//kAAP/s//n/9v/2//YAAP/0//0AAAAA//QAAAAA//kAAAAAAAD/9gAA//YAAAAAABQAAAAAABQAAAAAAAAAAP/s//T/+f/0AAAAAAAA//QAAP/3//n/9v/vAAAAAAAAAAAAAAAAAAAAAAAAAAD/9AAg/+AAEgAA//kAAP/u/84AAAAAAAz/8QANAAj/+AAIABIADf/2ABQACP/jABsACgAbABQACwAS/+8ABQAA//YAAP/vAAAAAP/2//3//f/5AAf/9wAKAAP/4P/l/+8AAP/q//0AAwAAAAMAAAAAAAAAAAAAAAAAAAAA/9EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+IAAAAAAAAAAAAAAAD/+QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/8wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/8wAAAAAAAAAAP/5AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAN/+UACgAAAAAAAP/a//QAAP/2/98AAAAA//P/5wAIAAgACAAHAAv/7P/5AAD/7AAR//YAAwADAAD/1f/2ADL/2P/a/9AAAP/s/+4AAP/+AAsACAAAAAP/5P/s/+z//f/s//EAAP/4AAAACP/2AAAAAAAAAAAAAP/V/6z/2gAAAAAAA//m//oAAAAD//YAAP/5//j/8//o/+z/0AAU/8L/xwAI/+f/6v/V/+X/2P/kABv/v//0ADT/zP/2/7cAAP/v//kAAwAI/+EACgAKAAAAAwAAAAD//v/5//kAAgAUAAAAAAAAAAAAAAAAAAAAAP/5/8z/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/9AAD/9gAA/+f/+QAA//n/+f/5//f/+QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/9/8L//QAAAAAAAAAA//0AAAAAABH/8f/9AAAAAP/z//n//f/7/9j/9gAA//kAB//5AAf/7v/5ADz/9gAA//b/6v/n/+IAAAAAAAAAAP/2AAD/+v/4//b/9gAAAAAAAP/2AAAAAAAAAAAAAAAA//gAAAAAAAAAAAAA/8wAAAAAAAAAAP/9/9X/9gAAAAD/3wAAAAMAAP/9//kAAP/i/9gAAP/RAAMAAAAAAAD/7QAD/+IAAAAA//YAAP/n//YAAAAAAAD//f/hAAD/6QAA/+z/0//s//YAAP/kAAD//QAAAAAAAAAA/+8AAAAAAAAAAAAA/8wAAP/7AAAAAP/9AAAAAAAAAAD/9gAAAAAAAP/9AAAAAAAA/9MAAP/sAAAAAAAAAAD/+QAAAAD/9gAAABsAAP/s//YAAAAAAAAAAAAAAAAAAAAA/+8AAAAAAAAAAP/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/2/8wAAAAAAAAAAAAAAAAAAAAAAAoAAP/5AAAAAAAAAAAAAAAK//n/9v/2AAD/9gAAAAD/+QAAAAD/9gAAAAAAAP/z//EAAAAAAAAAAAAA//0AAAAA//QAAAAKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA7//YAKAAUAAgAA//l/9gADQAK//3/9gAeABL/9gAUACEAKv/wABcAHP/OACoAIAAlACsAFwAX//MACgAAAAD/+P/i//gAAAABAAAABwADABcADQAcAAj/3f/z//YAB//bAAAAAAAUAAgACAAAAAAAAAAAAAAAAP/2/8f//QAAAAAAAAAA//j/9gAAAAX/2P/5AAAAAP/1/+//8//x/87/7//YAAAAAAAAAAD/4wAA/+z/5wAA//b/9v/i/+IAAAAAAAD//f/rAAD/8v/2/+n/4gAAAAAAAP/2AAAAAAAAAAAAAAAA/+4AAAAAAAAAAAAA/8wAAAAAAAAAAAAA//YAAAAAAAAAAAAAAAAAAAAAAAAAAP/0AAAAAP/2AAAAAAAAAAAAAAAA//YAAAAA//YAAP/2//YAAAAAAAAAAP/5AAD/+QAA//T/8QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9AA0ACgAHgAN//f////s/+z/9P/0/+wAAAAQ//cAAAAhAB4AIf/sAC4AE//sABYAAwAeAA4AHgAa/+wAAAAA/+wAAP/5//kAAP/0//T//gAaADwAHv//AAb/9//0//T////sAAD/9P/3AAYAJQAVAAD/9AAAAAAAAABkAGQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAAAAAAAAD/9gAv//kAFQAD//YAAP/z/+H/9v/2/+7/8QAMAAr/6gALABIAF//fACYACP/YABsABwAbABcADQAS/+L/+AAA//YAAP/p/+sAAP/9//YAB//+ABgACwAHAAP/2//i/+wAA//Y//H//QAAAAMACwAA//YAAP/sAAAAAAAe/9sAAwAAAAAAAP/z//7/9v/s/+4AAAAAAAD/5wABAAMAAwAAAAj/7AAUAAD/8wAHAAIAAwAKABv/4v/2AC//6QAA/+IAAP/z//MAAAAAAAgAAwAAAAD/3//2//n//f/s//MAA//9AAAAAwAA//YAAAAAAAD/9gAy//kAFQAD//YAAP/k/9n/8f/s/+7/9gAJAAr/4gAOABUADv/lACYAAP/OABQAAAAeAA0AEgAV/+L/+P/2//n/6//i//gAAP/2//MAB//+ABMAEwAKAAP/1v/i/+IAAP/L//EAAP/5AAgADgAAAAAAAAAAAAD/+QAA/8wABAAAAAAAAP/0//QAAAAA//QAAAAAAAD/+AAAAAMACgAKAAAACgAAAAAAAAAAAAAAAwAHABEAAAAAAB4AAP/2AAAAAP/9//kAAP/+AAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIABQLfAyEAAAMkA5AAQwOSA+oAsAPtBEYBCQRIBGMBYwACAD8C+QL6AAQC+wL7AAIC/AMCAAMDAwMIAA0DCQMJABkDCgMgAAQDIQMhAA0DJAMkAAYDJQMsAAcDLQM1AAgDNgM2ABMDNwNAAAgDQQNBABMDQgNEAAgDRQNGABMDRwNKAAoDSwNQAAsDUQNRABMDUgNTAAsDVANcAAgDXQNdABMDXgNfAAgDYAOBAA0DggOCAAQDgwODAA4DhAOEABIDhQOFAA0DhgONAA8DjgOQABADkgOZABADmgOaAAIDmwOiABEDowOsABMDrQOyABQDswO6ABMDuwPAABYDwQPBABcDwgPLABgDzAPQABkD0QPqAAED7QPtABkD7gQEAAUEBQQFAA0EBgQGAAYEBwQOAAcEDwQRAAkEEgQSABMEEwQbAAkEHAQcAAgEHQQfAAkEIAQiAAgEIwQrAAwELAQsAAgELQQuAAwELwQvAA0EMAQ3ABEEOARBAAgEQgRCABQEQwRGABUESARPAAgEUARUABMEVQReAAgEXwRjABkAAgCKACEAJwABAEoAUQABAIQApgABAKkAqQABAL8AvwABASwBMwABAVUBVgABAt8C+gAuAvsC+wA6AvwDAgAQAwMDIAA6AyEDIQAQAyQDJAA6AyUDLAAQAy0DRAA6A0UDRgANA0cDXwA6A2ADggAQA4MDhAA6A4UDhQAQA4YDjQA6A44DkAAzA5IDmQAzA5sDogAfA6MDugAgA7sDwAAiA8EDwQAjA8IDywAkA8wD0AA5A+0D7QA6BAUEBQAQBAYEBgA7BAcEDgAQBBIEEgA6BBwEHAA6BCIELgA6BC8ELwAQBDAENwAfBDgEVAAgBFUEXgAlBF8EYwA5BGQEZQACBHsEewABBH4EfgABBIIEggABBI8EjwABBJoEmgABBKgEqQABBMAEwQABBMcEyQABBNYE1gABBN4E3gABBOEE4gABBPEE8QABBQQFBAABBQcFBwABBcAFwAAmBcEFwQARBcIFwgArBcMFwwApBcQFxAAIBcUFxQAoBcYFxgAmBccFxwAcBcgFyAAxBckFyQAOBcoFygAnBcsFywASBcwFzAAsBc0FzQAtBc4FzgAJBc8FzwA0BdAF0AAmBdEF0QAdBdIF0gAxBdMF0wAPBiQGJAACBiUGJQADBiYGJwAMBigGKAA1BikGKgAUBisGKwAFBiwGLAAGBi4GLgAUBi8GLwAVBjAGMAAXBjMGMwA1BjQGNAAeBjUGNQAhBjYGNgADBjoGOgAeBj0GPQA3Bj8GPwA3BkEGQQA4BkwGTgAMBlIGUgAMBlMGUwAKBlQGVAAMBlUGVQAKBlYGVgAUBlcGVwAYBlgGWAAaBlkGWQAYBloGWgAaBlsGWwAUBmAGYAA2BmEGYQAHBmIGYgAMBmMGYwALBmQGZAAMBmUGZQALBmYGZgAUBmcGZwAWBmgGaAAyBmoGagAUBmsGawAZBmwGbAAbBm0GbQAZBm4GbgAbBm8GbwAUBnkGeQABBnsGewABBoIGggABBpQGlAAeBpUGlgAMBpgGmAAMBqEGogAMBqoGqgAMBsoGygABBssGywAvBswGzAATBs4GzwABBtAG0AAqBtEG0QAEBtcG1wABBtwG3AABBt4G3gAwBz4HPgAYAAIF0gAEAAAF9gZIAAsAQwAAAAwAIAAG/+X/4v/s/9j/9AAMAAoAB//iABsABwAK//P/8//2//3/5wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK/+kAIAAMAAD/9gAA//YAAP/iAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACgAAAAD/9v/s/+wAAAAAAAAAAAAAAAAAAAAoAAAAFAAA//YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/o//2//YAKAAeABsAFAAAAAAAAP+lAB4AAAAAABQAKAAlABUACgAVAAoAFP/s/+X/7//9//3/+AADAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEYAJQAL/+wACP/s/+z/9v/f/8T/7P/iADgAFAATAAP/xAAK/8T/2AAUABQAJwAT//YAGgAMAAn/7P/sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAD/zgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAXAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAAAAAAAAAAAAAAAAAAAAcAAAAAAAAAAAAHAAAABwAAAAcAAAAAAAAAAAAAAAcAAAAHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcABwAHAAcABwAAAAD/7P/s//YAAAAAAAAAAAAAAAAAGwAIABQAAAAAACEAFwAMAAoAAAAIAAAAAAAAAAAAGwAAABsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAQAQBnwGfgaABoYGiAaKBpAGrQauBssGzQbQBtEG1QbWBt4AAgANBnwGfAACBn4GfgAFBoAGgAAGBoYGhgAHBogGiAACBooGigACBpAGkAACBq0GrgAIBs0GzQAJBtAG0AAKBtEG0QAEBtUG1gADBt4G3gABAAIBEwAEAB8AAQAhACcAFQBKAFEAFQBoAGkAAgCEAKYAFQCpAKkAFQCyALQAFgC2AL0AFgC/AL8AFQDAAMYABADfAOQABgDlAOUAFwDmAO8ABwDwAPQACQEQAREAAQEsATMAFQFFAUYAAwFVAVYAFQFXAV0ABQF7AYQACAGFAYkACQGKAaUACgGmAaYAPgGnAcwAGQHQAdcAGQHYAd0APgHeAe4APwHvAfEAPQHyAfQAPgH1AfUAPwH2Af4APgH/AgsAPwIMAi4AGQIvAi8APwIwAjAAPgIxAjEAGQIyAjkAPwI6AjwAGwI+AkUAGwJGAkYAPgJIAk8ADwJQAmcAQAJoAm0AEQJuAm4AEwJvAngAEQJ5An0AQQJ/ApgAGQKZApoACgKbArMAGQK0Ar0APgK+Ar4AGQK/AsYAPgLHAtQAQALVAtkAQQLaAtoABALbAtwADwLeAt4ADwLfAvoACwL8AwIAGgMhAyEAGgMlAywAGgNFA0YADQNgA4IAGgOFA4UAGgOOA5AAQgOSA5kAQgObA6IAEAO7A8AAEgPBA8EAHQPCA8sAFAPMA9AAHgPRA+oAGAQFBAUAGgQGBAYAHAQHBA4AGgQgBCEADgQvBC8AGgQwBDcAEARfBGMAHgRkBGUADARmBGYAAQRwBHAAFwR7BHsAFQR+BH4AFQR/BH8ABASABIEAFwSCBIIAFQSDBIMAFwSKBIoABASOBI4AFgSPBI8AFQSTBJMAAgSUBJQABASWBJYAFwSXBJgABASZBJkAFwSaBJoAFQSbBJsABgSeBJ4AFwSjBKMABASoBKkAFQSqBKoABASrBKwABwStBK0AFwSuBK4ABAS2BLYAFwS8BL4AAQTABMEAFQTCBMIAFwTHBMkAFQTLBM0AFwTSBNMAFwTWBNYAFQTXBNcABgTdBN0AAQTeBN4AFQThBOIAFQTuBO4ABQTvBPAACATxBPEAFQTzBPMABAT3BPcAAwT5BPkABQT8BPwAAQUABQIACAUEBQQAFQUGBQYACgUHBQcAFQUIBQsAPwUNBQ8AGQUQBRAAEwUSBRcAPwUZBRoAPwUbBRsAGQUcBR0APwUeBR4AGQUgBSEAEQUiBSIAGQUjBSMAEwUkBSQAQAUlBSkAPwUrBSsAPwUtBS0APwUuBS4AGwUvBS8AGQUxBTIAPwUzBTMAPQU1BTUAPwU2BTYAEwU3BTcAPgU5BTkAEwU6BToAGQU7BTsAEQU9BT0APwU+BT4AEwVABUEAPwVCBUIAPgVEBUcAPwVIBUkAGQVLBUwAEQVNBU0AEwVPBVAAQAVRBVIAPgVVBVUAPgVWBVYAEwVXBVcAPwVZBVoAPwVbBVsAQAVcBVwAPwVdBV8ACgVgBWIAGQVjBWMAEwVmBWcAPwVoBWoAGQVsBW4AEQVvBW8AQAVwBXIAPwVzBXQAEwV3BXcAGQV4BXgAEQV6BXoAPwV7BXsAPQV9BX0AGQV+BX4AGwV/BX8AGQWABYAAEwWCBYQAQAWFBYUAPgWHBYkAPwWKBY4AQAWQBZAAPgWRBZEAPwWTBZMAGQWUBZQAPwWWBZYAPwWXBZcAGQWYBZkAQAWaBZ4AGQWfBaIAQAWlBacAQAWpBakAQAWrBasAPwWtBa4AGQWvBa8ACgWwBbEAGQWzBbgAQAW6BboAAQW+Bb4AAQXBBcEAKwXCBcIAOQXDBcMAOAXEBcQAJwXHBccANQXKBcoAPAXLBcsALAXMBcwAOgXOBc4AKAXPBc8AJgXRBdEANgYkBiQADAYlBiUAHwYmBicAKgYoBigAIgYpBioALwYrBisAIwYuBi4ALwYvBi8AMAYwBjAAMQYxBjIANAYzBjMAIgY0BjQANwY1BjUAOwY2BjYAHwY6BjoANwY9Bj0AIAY/Bj8AIAZBBkEALQZDBkMAIQZFBkUAIQZHBkcALgZMBk4AKgZSBlIAKgZUBlQAKgZWBlYALwZYBlgAMwZaBloAMwZbBlsALwZgBmAAJAZhBmEAJQZiBmIAKgZjBmMAKQZkBmQAKgZlBmUAKQZmBmYALwZoBmgAMgZqBmoALwZvBm8ALwZ5BnkAFQZ6BnoAGQZ7BnsAFQZ9Bn0AFgZ+Bn4AGQaCBoIAFQaUBpQANwaVBpYAKgaYBpgAKgahBqIAKganBqcAAQaqBqoAKgarBqsAPwbKBsoAFQbOBs8AFQbXBtcAFQbaBtsANAbcBtwAFQACAJ4ABAAAAKwAsAABAEcAAP+j//n/9AAKAB4AKAAh//YAFAAK/6j/9v/2ABQAAwAHAB4ABwAUABH/7P/5//P/2QARAA0AEf/2//0AUAAg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AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9AAA//D/8AAAAAD/7f/3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/8f/q//f/9AAA/+0AAP/s//P/9//w//cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKACUABwAA//b/9gAA/+n/+f/bAAAAAAAAAAAAHgAAAAAAFAAAAAcAAP/9//kAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwAAAAAACP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABf/9AAAABQAFAAAAAoAAAAUAAoABwAAAAAADf/2AAAAFAAAAAAAAwAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAACP/2AAAACAAAAAAAAwAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKAAoAFAAA/+z/7AAA/+L/9v/YAAoAAABkAEQAFAAKAAAACAAAAAD/9gAA//YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAEQAAAAAACAADAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/zAAD/6QAA//T/7wAA/9//1v/WAAAAEf/0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA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ABIFhQWFAAQFhwWJAAgFkAWQAAkFkgWSABIFlAWUAAsFlQWVAAkFnAWeAAEFowWjAAkFrwWwAAEFsQWxAAkGiQaJAAwAAgFrAAQAHwBMACAAIABNACEAJwAwACgARgBNAEcASABIAEkASQBNAEoAUQAwAFIAZwBNAGoAgwBNAIQApgAwAKcAqABNAKkAqQAwAKoAsQBNALIAtABOALYAvQBOAL8AvwAwAMAAxgACAMcA3gAxAN8A5AAyAOUA5QA2AOYA7wAzAPUA9QBNAPYBDwABARABEQBMARIBEwBNASsBKwABASwBMwAwATUBNQBNAUUBRgBJAUcBSABNAUoBVABNAVUBVgAwAVcBXQBKAV4BegAxAYoBpQA3AaYBpgATAacBzAAWAc4BzgAPAdAB1wAWAdgB3QATAd4B7gBCAe8B8QBBAfIB9AATAfUB9QBCAfYB/gATAf8CCwBCAgwCLgAWAi8CLwBCAjACMAATAjECMQAWAjICOQBCAjoCPABFAj4CRQBFAkYCRgATAkgCTwAjAlACZwBGAmgCbQApAm4CbgAqAm8CeAApAnkCfQArAn8CmAAWApkCmgA3ApsCswAWArQCvQATAr4CvgAWAr8CxgATAscC1ABGAtUC2QArAtoC2gACAtsC3AAjAt4C3gAjBGQEZQAEBGYEZgBMBGcEawBNBGwEbAA1BG0EbwBNBHAEcAA2BHEEcQBIBHIEdwBNBHgEeAA1BHkEegBNBHsEewAwBHwEfQBNBH4EfgAwBH8EfwACBIAEgQA2BIIEggAwBIMEgwA2BIQEhAAuBIUEiQBNBIoEigACBIsEiwBNBIwEjAA1BI0EjQBNBI4EjgBOBI8EjwAwBJAEkABIBJEEkgBNBJQElAACBJUElQBNBJYElgA2BJcEmAACBJkEmQA2BJoEmgAwBJsEmwAyBJ0EnQBNBJ4EngA2BJ8EnwBIBKAEogBNBKMEowACBKQEpwBNBKgEqQAwBKoEqgACBKsErAAzBK0ErQA2BK4ErgACBK8EsAAuBLEEsgBNBLMEtAAvBLUEtQBNBLYEtgA2BLcEuQBNBLoEugAuBLsEuwBNBLwEvgBMBL8EvwBNBMAEwQAwBMIEwgA2BMMExABIBMUExgBNBMcEyQAwBMoEygBIBMsEzQA2BM4EzgAuBM8E0QBNBNIE0wA2BNUE1QA1BNYE1gAwBNcE1wAyBNgE2gBNBNsE3AA1BN0E3QBMBN4E3gAwBN8E3wBNBOEE4gAwBOME4wABBOQE5ABHBOgE6wBNBO0E7QABBO4E7gBKBPEE8QAwBPIE8gAxBPME8wACBPQE9AAxBPUE9QA1BPYE9gBNBPcE9wBJBPkE+QBKBPoE+wABBPwE/ABMBP4E/wBNBQQFBAAwBQUFBQAxBQYFBgA3BQcFBwAwBQgFCwBCBQwFDAAOBQ0FDwAWBRAFEAAqBREFEQAPBRIFFwBCBRgFGAAOBRkFGgBCBRsFGwAWBRwFHQBCBR4FHgAWBR8FHwAkBSAFIQApBSIFIgAWBSMFIwAqBSQFJABGBSUFKQBCBSoFKgAkBSsFKwBCBSwFLAAOBS0FLQBCBS4FLgBFBS8FLwAWBTAFMAAPBTEFMgBCBTMFMwBBBTUFNQBCBTYFNgAqBTcFNwATBTgFOAAkBTkFOQAqBToFOgAWBTsFOwApBT0FPQBCBT4FPgAqBT8FPwAPBUAFQQBCBUIFQgATBUMFQwAkBUQFRwBCBUgFSQAWBUoFSgAkBUsFTAApBU0FTQAqBU4FTgAkBU8FUABGBVEFUgATBVMFVAAJBVUFVQATBVYFVgAqBVcFVwBCBVgFWAAOBVkFWgBCBVsFWwBGBVwFXABCBV0FXwA3BWAFYgAWBWMFYwAqBWQFZQAPBWYFZwBCBWgFagAWBWsFawAPBWwFbgApBW8FbwBGBXAFcgBCBXMFdAAqBXUFdQBEBXYFdgAOBXcFdwAWBXgFeAApBXkFeQAgBXoFegBCBXsFewBBBXwFfAAOBX0FfQAWBX4FfgBFBX8FfwAWBYAFgAAqBYEFgQAPBYIFhABGBYUFhQATBYYFhgAOBYcFiQBCBYoFjgBGBY8FjwAkBZAFkAATBZEFkQBCBZIFkgAPBZMFkwAWBZQFlABCBZUFlQAGBZYFlgBCBZcFlwAWBZgFmQBGBZoFngAWBZ8FogBGBaUFpwBGBagFqABLBakFqQBGBaoFqgAOBasFqwBCBa0FrgAWBa8FrwA3BbAFsQAWBbMFuABGBbkFuQAgBboFugBMBb4FvgBMBb8FvwBNBcAFwAAsBcEFwQAXBcIFwgAoBcMFwwAlBcQFxAAQBcUFxQA/BcYFxgAsBccFxwAhBcgFyAANBckFyQAUBcoFygAtBcsFywAYBcwFzAA7Bc0FzQAm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D4oPig+KCrAPig+KD4oPig+KD4oPig+KD4oKqg+KD4oPig+KD4oPig+KD4oPig+KD4oPig+KD4oPigugD4oLjguUCg4LoA+KD4oPig+KChQPigoaD4oLuA+KD4oKIA+KD4oPig+KD4oPigomD4oPigrCCiwKzg+KD4oKMgo4Cj4Pig+KD4oPigpED4oPig+KD4oPigv0D4oLUgtYC6wLZAtqD4oPigsoD4oPig+KD4oK1A+KD4oOOg+KC74Pig+KD4oPigpKD4oPig+KD4oKUA+KD4oKVg+KClwPig+KCtoPigrgCuYPigraD4oKYgrmD4oPig+KD4oPig+KD4oPig+KD4oPigvED4oLyg+KD4oOOg+KCmgKbg+KCnQPigp6CoAPigqGD4oKjAqSD4oPig+KD4oPig+KCpgPigqeCqQPig+KD4oKqg+KD4oPig+KCrAPig+KD4oPig+KD4oPig+KD4oPig+KD4oKtg+KCrwPig+KCrYPigq8D4oPigrCCsgKzg+KD4oPig+KCtQPig+KCtoPigrgCuYPigrsD4oK8g+KD4oK/gsECvgPig+KCv4LBAsKD4oPigsQD4oLFg+KD4oLHAsiCygPig+KD4oPigsuD4oPig+KD4oLNA+KD4oPig+KCzoPig+KDjoPigtAD4oPig+KD4oLRg+KD4oPig+KC0wPig+KC1ILWAteC2QLagtSC1gLrAtkC2oLUgtYC14LZAtqD4oPigtwD4oPig+KD4oLdg+KD4oPig+KC3wPig+KD4oPiguCD4oPig+KD4oLiA+KD4oPig+KC7gPig+KC44LlAuaC6APig+KD4oLpg+KD4oPig+KC6wPig+KD4oPig+KC7IPig+KD4oPig+KD4oPig+KC7gPig+KDjoPigu+D4oPigvED4oLyg+KD4oLxA+KC8oPig+KDXoMEgwMD4oPigweDCQMKg+KD4oMHgwkC9APig+KDB4MJAvWD4oPigw2DDwMDA+KDEgMNgw8DAwPigxIDDYMPAwMD4oMSAw2DDwL3A+KDEgPig+KD4oPig+KC/oPigwADAYPigxaD4oL4g+KD4oMWg+KC+IPig+KD4oPigvoD4oPig+KD4oL7g+KD4oPig+KD4oL9A+KC/oPigwADAYPig16DBIMDA+KD4oNegwSDEIPig+KDvQPigwYD4oPigweDCQMKg+KD4oMNgw8DDAPigxIDDYMPAxCD4oMSAxaD4oMTg+KD4oMWg+KDFQPig+KDFoPigxgD4oPig+KD4oMZg+KD4oPig+KD4oMbA+KDYwNkg2GD4oPigxyD4oMeA+KD4oPig+KDigPig+KD4oPig6UD4oPig2qDbANtg+KD4oNqg2wDH4Pig+KDaoNsAyED4oPig+KD4oNdA+KD4oOfA+KDoIPig+KD4oPigyKD4oPig+KD4oMig+KD4oPig+KDJAPig+KD4oPigyWD4oPig+KD4oPNg+KD4oPig+KDJwPig+KD4oPig+KD4oPig16D4oNgA+KD4oOWA+KDl4OZA+KDdoN4A28DewN8g+KD4oPig+KD4oMog+KDKgPig+KDogPig6OD4oPig0gD4oNJg0sD4oOFg+KDK4Pig+KDhYPigyuD4oPig+KD4oPig+KD4oPig+KDTgPig+KD4oPig+KD4oPig+KD4oPig+KD4oPig+KD4oONA+KD4oPigy0DjQPig+KD4oPigy6D4oMwA+KDMYPig+KDMwPig+KD4oPig+KD4oOgg+KD4oNXAzSDNgPig+KDpoOoAzeD4oPig+KD4oM5A+KD4oM6g+KDPAM9g6CD4oPig34D4oPig+KD4oM/A+KD4oPig+KDXQPig+KDnwPig6CD4oPig+KD4oPNg+KD4oNAg+KDQgPig+KDQ4Pig0UD4oPig5YD4oOXg5kD4oOWA+KDRoOZA+KD4oPig+KD4oPig6ID4oOjg+KD4oNIA+KDSYNLA+KD4oPig+KDTIPig+KD4oPig0yD4oPig+KD4oPig+KD4oPig04D4oPig+KD4oNPg+KD4oOag+KDWINRA1KDVAPig1WD4oPig1QD4oNVg+KD4oNXA+KDWINaA1uD4oPig10D4oPig+KD4oPig+KD4oOWA+KDl4OZA+KDXoPig2AD4oPig2MDZINhg+KD4oNjA2SDZgPig+KDZ4Pig2kD4oPig2qDbANtg+KD4oN2g3CDbwPig+KDdoNwg3mD4oPig+KD4oNyA+KD4oOfA+KDgQPig+KD4oPig3OD4oPig+KD4oN1A+KD4oN2g3gDeYN7A3yD4oPig34D4oPig+KD4oN/g+KD4oPig+KDgQPig+KDhYPig4KD4oPig4WD4oOEA+KD4oOFg+KDhwPig+KD4oPig4iD4oPig+KD4oOKA+KD4oPig+KDi4ONA+KD4oPig+KD4oPig46D4oOQA+KD4oORg+KDkwPig+KD4oPig+KD4oPig+KD4oOxA+KD4oPVA9aDtYPig9mD1QPWg7WD4oPZg9UD1oO4g+KD2YPig+KDlIPig+KDlgPig5eDmQPig5qD4oOcA+KD4oO9A+KD4oPig+KD4oPig+KD4oPig9UD1oO1g+KD2YPig+KDnYPig+KD4oPig52D4oPig58D4oOgg+KD4oOiA+KDo4Pig+KD4oPig6UD4oPig6aDqAOpg+KD4oPig+KDtYPig+KDqwOsg9sD4oOuA+KD4oOvg+KD4oPDA8SDwYPig+KD4oPig7ED4oPig8kDyoPMA+KD4oPJA8qDsoPig+KDyQPKg7QD4oPig9UD1oO1g+KD2YPVA9aDtYPig9mD1QPWg7cD4oPZg9UD1oO4g+KD2YO6A+KDu4Pig+KDvQPig+KD4oPig94D4oO+g+KD4oPeA+KDvoPig+KD4oPig8AD4oPig8MDxIPBg+KD4oPDA8SDxgPig+KD4oPig8eD4oPig8kDyoPMA+KD4oPPA9CDzYPig+KDzwPQg9ID4oPig9UD1oPTg+KD2YPVA9aD2APig9mD3gPig9sD4oPig94D4oPcg+KD4oPeA+KD34Pig+KD4oPig+ED4oPigABAX0AAAABAUoDUwABAWUDUwABAWUDOQABAZoDUwABAZoCvAABAWcDUwABAfICvAABAogCSgABAUoAAAABAYMAAAABAUACvAABANAAAAABAJsAAAABAM0AAAABAJsDOQABAQoCvAABAWcCvAABAX0CvAABAfAAAAABAfACvQABA0QCvAABAS8CvAABAS8BUwABAU4AAAABAU4CvAABAUsA+QABAUQAAAABAUQCvAABAUEA+QABAS4AAAABAS4CvAABAS4BUwABAVUCvAABAVQCvAABAlUAAAABAk8CvwABAJ8AAAABANEAAAABAJ8CvAABAgQCvAABAZkAAAABAZkCvAABAZkCKQABAeEAAAABAeECvAABAXsCvAABAXsAAAABAuoAAAABAXsDOQABAhwAAAABAhwCvAABAW8AAAABAmkAAAABAWUCvAABAZ0CvAABAZ0DOQABAgQDOQABAT8DOQABAZoDNQABAZoDOQABAagAAAABAfUAAAABAagDOQABAagBXgABAoECvAABAUADOQABAVQDNQABAVQDOQABAVQDUwABAVUDOQABA0MAAAABA3QAAAABAfIDOQABAK4CSgABAWYCvAABAagCvAABAMcCSgABAUoCvAABAT8CvAABAZYAAAABAZ8CvAABAV4DUwABAV4DOQABAY8DUwABAYoCvAABAfECvAABAOwCvAABAQ4CSgABATwAAAABAT4CvAABATsBSgABAY8CvAABAr0AAAABAhQCvAABAV4AAAABAlEAAAABAV4CvAABAY8DNQABAYgAAAABArEAAAABAY8DOQABAo4CvAABAYoDNQABAYoDOQABApcAAAABAYoDUwABAfEDOQABAMMCSgABATgAAAABATgCEwABATUCvQABATUCowABAVUCEgABAVUCvQABAVUCswABATQCvQABAYIAAAABAW4CEgABARACEgABAaACEgABAgEBugABAQsAAAABAQsCEgABATkAAAABAL0AAAABAI0CxQABAIsCowABAI4CxQABAVsAAAABAJAC5gABAMMCeQABATMCEAABAUEAAAABAUECEgABAYoAAAABAYoCEgABArECEAABAPgAAAABAPgCEgABAPgA/AABAR4ABQABARQCEgABARMCEgABAMgCegABAQQCEgABAdAAAAABAcoCEAABAI0AAAABAI0C5gABAI0BZgABARYC5gABAagCEgABAY8AAAABAY8CEgABASECEgABAR8AAAABAf0AAAABASECowABAdkAAAABAc0CEgABATUAAAABAgkAAAABATUCEgABAT8CEgABAGsCEgABAagCowABAVUCnwABAVUCowABAT8AAAABAaIAAAABAT8CowABAT8BCQABAcgCEgABAUUCEgABAUUCowABAQcCowABARACnwABARACowABAaAAAAABARACvQABARQCowABASMCEAABAaACowABAJoBugABAS8AAAABAUICEgABAdQAAAABAdQCEgABATECEgABAVIAAAABAVICEgABAVIBpgABAVkAAAABAVkCEgABAgYCEAABAPsAAAABAQcCEgABAToAAAABAS4CEgABASMCuwABAIsAAAABALsAAAABAIsCnwABAVAAAAABAkkAAAABAhoCEgABAgYCnQABAUgCEgABATACvQABATACowABAUYCEgABAUYCswABAUYCvQABAWkAAAABAVYCEgABAhQAAAABAVACEgABAZUCEgABAU8CEgABAU8AAAABAk8AAAABAU8CowABAeUCEgABATAAAAABAb0AAAABATACEgABATQCEgABATQAAAABAKcCEgABATQCowABAUYCnwABAUcAAAABAkAAAAABAUYCowABAhECEgABAVACnwABAVACowABApUAAAABAVACvQABAZUCowABAAAAAAAJAAAAAQAIAAEABAAAA7wABgEAAAEACAABAAwAHAABACoASgABAAYG/wcABwEHAgcEBwUAAQAFBv8HAAcBBwQHBQAGAAAAGgAAABoAAAAaAAAAGgAAABoAAAAaAAH+1AAAAAUAEgAMABIAGAAeAAH+1P9qAAH+1P9vAAH+1P9jAAH+1P9yAAYCAAABAAgAAQF6AAwAAQGgAEAAAgAIBt8G6gAABuwG/QAMBwoHJAAeB0AHQQA5B0UHRQA7B0gHSgA8B0wHUQA/B1MHVABFAEcAkACuAK4ArgKSAJYAugCuALoAnACuALoAwADAAsAAwACiAKIAwACuAK4ArgCoAK4ArgCuALQAugDAAMYAzADqAOoA6gDSANgA9gDqAPYA3gDqAPYA/AD8At4A/AD8AOoA6gDqAOQA6gDqAOoA8AD2APwBFAEOAQ4BDgEgASABIAECAQgBDgEOARQBGgEgAAH+1AKjAAH+1AMwAAH+1AMxAAH+1AL9AAH+1AKfAAH+1AMtAAH+1AMDAAH+1AK9AAH+1AKzAAH+1ALfAAH+1AM5AAH+1ANSAAH+1APGAAH+1APHAAH+1AM1AAH+1APDAAH+1AOZAAH+1ANTAAH+1ANJAAEBLAKjAAEBLAK8AAEBLAK9AAEBLAKfAAEBLAL9AAEBLAKzAAYCAAABAAgAAQAMACgAAQAyAWoAAgAEBt8G6gAABuwG/QAMBwoHJAAeB14HbQA5AAIAAQdeB20AAABJAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABMgAAATIAAAEyAAABMgAAATIAAAEyAAABMgAAATIAAAEyAAABMgAAATIAAAEyAAABMgAAATIAAAEyAAABMgAAATIAAAEyAAABMgAAATIAAAEyAAABJgAAATIAAAEyAAABMgAAATIAAAEyAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEyAAABMgAAATIAAAEyAAABMgAAATIAAAEyAAABMgAB/tQCuwAB/tQCEgAB/tQCvAAQACgAKAAiACgALgAuADQAOgBGAEYAQABGAEwATABSAFgAAf7UAyUAAf7UAxoAAf98AvcAAf9WAwsAAf7UAyAAAf7UA7sAAf7UA7AAAf98A40AAf9WA6EAAf7UA7YAAQAMACIABQEKAq4AAgADBt8G6gAABuwHJwAMB14HbQBIAAIAJgAEAEgAAABKAH8ARQCBAKYAewCpALQAoQC2AL0ArQC/ANoAtQDcAN4A0QDgAOQA1ADmAPQA2QD2ASoA6AEsATYBHQE4AVABKAFSAVQBQQFWAaUBRAGnAa4BlAGwAc4BnAHQAdYBuwHYAgcBwgIJAjwB8gI+AkUCJgJIAm0CLgJvAn0CVAJ/ArMCYwK1AtkCmALfAyMCvQMlAzUDAgM3A1sDEwNdA4IDOAOFA5ADXgOSA5kDagObA7YDcgO4A7oDjgO8A8ADkQPCBAUDlgQHBBED2gQTBCoD5QQsBC4D/QQwBGMEAABYAAIBmAACAZgAAgGYAAIBmAACAZgAAgGYAAIBmAACAZgAAgGYAAIBmAACAZgAAgGYAAIBmAACAZgAAgGYAAIBmAACAZgAAgGYAAIBmAACAZgAAgGYAAIBmAACAZgAAgGYAAIBmAACAZgAAgGYAAIBmAACAZgAAgGYAAQBmAAAAWgAAAFoAAABaAAAAWgAAQFiAAABaAAAAWgAAwFuAAMBdAADAYwAAwF6AAIBngACAZ4AAgGeAAIBngACAZ4AAgGeAAIBngACAZ4AAgGeAAIBngACAZ4AAgGeAAIBngACAZ4AAgGeAAIBngACAZ4AAgGeAAIBngACAZ4AAgGeAAIBgAACAZ4AAgGeAAIBngACAZ4AAgGeAAMBhgADAYwAAwGSAAIBmAACAZgAAgGYAAIBmAACAZgAAgGYAAIBmAACAZgAAgGeAAIBngACAZ4AAgGeAAIBngACAZ4AAgGeAAIBngAB/tUAAAAB/tQAAAAB/tQBtgAB/kwBtgAB/soBCgAB/tQCuwAB/tQBZAAB/ycBggAB/mMBXgAB/tQCEgAB/tQCvAQ0KlIqWCpGPJQ8lCpSKlgqNDyUPJQqUipYKl48lDyUKlIqWCoQPJQ8lCouKlgqXjyUPJQqUipYKhA8lDyUKlIqWCoKPJQ8lCpSKlgqEDyUPJQqUipYKl48lDyUKlIqWCpePJQ8lCpSKlgqFjyUPJQqLipYKl48lDyUKlIqWCoWPJQ8lCpSKlgqHDyUPJQqUipYKiI8lDyUKlIqWCo0PJQ8lCpSKlgqKDyUPJQqLipYKkY8lDyUKlIqWCo0PJQ8lCpSKlgqOjyUPJQqUipYKl48lDyUKlIqWCpAPJQ8lCpSKlgqRjyUPJQqUipYKkw8lDyUKlIqWCpMPJQ8lCpSKlgqXjyUPJQuWjyULlQ8lDyULlo8lC5gPJQ8lCpkPJQqajyUPJQqgjyUKnA8lDyUKoI8lCp2PJQ8lCqCPJQqfDyUPJQqgjyUKnA8lDyUKoI8lCp2PJQ8lCqCPJQqfDyUPJQqgjyUKog8lDyUM0w8lCrQLn48lCqOPJQqlC5+PJQqmjyUKqAqpjyUM0w8lCqsLn48lCqyPJQquCq+PJQqxDyUKtAufjyUKso8lCrQLn48lCrWPJQq3C5+PJQrHiskKxg8lDyUKx4rJDjaPJQ8lCseKyQrKjyUPJQrHiskKyo8lDyUKx4rJCsqPJQ8lCseKyQrKjyUPJQrHiskKuI8lDyUKwArJCsqPJQ8lCseKyQq4jyUPJQrHiskKug8lDyUKx4rJCruPJQ8lCseKyQ42jyUPJQrHiskKvQ8lDyUKx4rJCr6PJQ8lCsAKyQrGDyUPJQrHiskONo8lDyUKx4rJCsGPJQ8lCseKyQrKjyUPJQrHiskKww8lDyUKx4rJCsSPJQ8lCseKyQrEjyUPJQrHiskKxg8lDyUKx4rJCsqPJQ8lCs2PJQrMDyUPJQrNjyUKzw8lDyULDg8lC72PJQ8lCw4PJQu2DyUPJQsODyULtg8lDyULDg8lC7YPJQ8lCwgPJQu9jyUPJQsODyULuQ8lDyULDg8lC7qPJQ8lCw4PJQu9jyUPJQsODyULDIrWjyUK0I8lCtIK048lCtUPJQsMitaPJQsODyULD4rWjyULDg8lCw+K1o8lCwgPJQsMitaPJQriiuQK948lDyUPJQ8lCtgPJQ8lCuKK5ArxjyUPJQriiuQK5Y8lDyUK4orkCuWPJQ8lCuKK5ArxjyUPJQriiuQK2Y8lDyUK4orkCtsPJQ8lCuKK5ArcjyUPJQreCuQK948lDyUK4orkCvGPJQ8lCuKK5ArfjyUPJQriiuQK5Y8lDyUK4orkCuEPJQ8lCuKK5Ar3jyUPJQriiuQK5Y8lDyUPJQ8lCucPJQ8lDyUPJQrojyUPJQrqDyUK7o8lDyUK6g8lCuuPJQ8lCu0PJQrujyUPJQvUDyUK94vXC9iL1A8lCvAL1wvYi9QPJQrxi9cL2IvUDyUK94vXC9iK8w8lCveL1wvYi9QPJQr3i9cL2IrzDyUK94vXC9iL1A8lCvSL1wvYivYPJQr3i9cL2Ir5DyUK+or8Cv2K/w8lCwIPJQ8lCwCPJQsCDyUPJQsODyULDI8lDyULDg8lCwOPJQ8lCw4PJQsFDyUPJQsODyULD48lDyULCA8lCwyPJQ8lCw4PJQsGjyUPJQsIDyULDI8lDyULDg8lCwmPJQ8lCwsPJQsMjyUPJQsODyULD48lDyULIAshiyqLJIsmCyALIYsdCySLJgsgCyGLHoskiyYLIAshix6LJIsmCyALIYsRCySLJgsYiyGLHoskiyYLIAshixELJIsmCyALIYsSiySLJgsgCyGLFAskiyYLIAshix0LJIsmCyALIYsViySLJgsgCyGLIwskiyYLIAshixcLJIsmCxiLIYsqiySLJgsgCyGLHQskiyYLIAshixoLJIsmCyAPJQsqjyUPJQsgDyULHQ8lDyULGI8lCyqPJQ8lCyAPJQsdDyUPJQsgDyULGg8lDyULIA8lCx6PJQ8lCyALIYsdCySLJgsgCyGLHoskiyYLIAshixuLJIsmCyALIYsjCySLJgsgCyGLIwskiyYPJQ8lCyqPJQ8lCyALIYsqiySLJgsgCyGLHQskiyYLIAshix6LJIsmCyALIYsjCySLJgsgCyGLIwskiyYLIAshiyMLJIsmCyePJQspDyUPJQ8lDyULKo8lDyULLw8lCzOPJQ8lCy8PJQssDyUPJQsvDyULMI8lDyULLY8lCzOPJQ8lCy8PJQssDyUPJQstjyULM48lDyULLw8lCzCPJQ8lCzIPJQszjyUPJQs7DyULPI8lDyULOw8lCzUPJQ8lCzsPJQs2jyUPJQs7DyULOY8lDyULOw8lCzgPJQ8lCzsPJQs8jyUPJQs7DyULOY8lDyULPg8lCzyPJQ8lCzsPJQs/jyUPJQs+DyULPI8lDyULPg8lCz+PJQ8lDhEPJQtBDyUPJQtEDyULSItKDyULRA8lC0iLSg8lC0QPJQtCi0oPJQtEDyULSItKDyULRY8lC0iLSg8lC0WPJQtIi0oPJQtHDyULSItKDyULWQtai06PJQtdi1kLWotRjyULXYtZC1qLV48lC12LWQtai1ePJQtdi1kLWotXjyULXYtZC1qLUY8lC12LWQtai0uPJQtdi00LWotOjyULXYtZC1qLUY8lC12LWQtai1APJQtdi1kLWotOjyULXYtZC1qLUY8lC12LTQtai06PJQtdi1kLWotRjyULXYtZC1qLUA8lC12LWQtai1ePJQtdi1kLWotRjyULXYtZC1qLV48lC12LWQtai1MPJQtdi1kLWotUjyULXYtZC1qLVg8lC12LWQtai1ePJQtdi1kLWotcDyULXYtjjyULXw8lDyULY48lC2UPJQ8lC2OPJQtgjyUPJQtjjyULYg8lDyULY48lC2UPJQ8lC3EPJQtrC3QPJQtxDyULbIt0DyULcQ8lC3KLdA8lC3EPJQtmi3QPJQtxDyULaAt0DyULaY8lC2sLdA8lC3EPJQtsi3QPJQtxDyULbgt0DyULcQ8lC2+LdA8lC3EPJQtyi3QPJQt4jyULfQ8lDyULeI8lC3WPJQ8lC3iPJQt3DyUPJQt4jyULeg8lDyULe48lC30PJQ8lC5CLkguNjyUPJQuQi5ILiQ8lDyULkIuSC5OPJQ8lC5CLkguADyUPJQuHi5ILk48lDyULkIuSC4APJQ8lC5CLkgt+jyUPJQuQi5ILgA8lDyULkIuSC5OPJQ8lC5CLkguTjyUPJQuQi5ILgY8lDyULh4uSC5OPJQ8lC5CLkguBjyUPJQuQi5ILgw8lDyULkIuSC4SPJQ8lC5CLkguJDyUPJQuQi5ILhg8lDyULh4uSC42PJQ8lC5CLkguJDyUPJQuQi5ILio8lDyULkIuSC5OPJQ8lC5CLkguMDyUPJQuQi5ILjY8lDyULkIuSC48PJQ8lC5CLkguPDyUPJQuQi5ILk48lDyULlo8lC5UPJQ8lC5aPJQuYDyUPJQuZjyULmwufjyULnI8lC54Ln48lC7GLswuwDyUPJQuxi7MLqg8lDyULsYuzC7SPJQ8lC7GLswu0jyUPJQuxi7MLtI8lDyULsYuzC7SPJQ8lC7GLswuhDyUPJQuoi7MLtI8lDyULsYuzC6EPJQ8lC7GLswuijyUPJQuxi7MLpA8lDyULsYuzC6oPJQ8lC7GLswuljyUPJQuxi7MLpw8lDyULqIuzC7APJQ8lC7GLswuqDyUPJQuxi7MLq48lDyULsYuzC7SPJQ8lC7GLswutDyUPJQuxi7MLro8lDyULsYuzC66PJQ8lC7GPJQuwDyUPJQuxi7MLtI8lDyULvA8lC72PJQ8lC7wPJQu2DyUPJQu8DyULtg8lDyULvA8lC7YPJQ8lC7ePJQu9jyUPJQu8DyULuQ8lDyULvA8lC7qPJQ8lC7wPJQu9jyUPJQvMi84Lyw8lDyUPJQ8lC78PJQ8lC8yLzgvGjyUPJQvMi84Lz48lDyULzIvOC8+PJQ8lC8yLzgvGjyUPJQvMi84LwI8lDyULzIvOC8IPJQ8lC8yLzgvDjyUPJQvFC84Lyw8lDyULzIvOC8aPJQ8lC8yLzgvIDyUPJQvMi84Lz48lDyULzIvOC8mPJQ8lC8yLzgvLDyUPJQvMi84Lz48lDyUPJQ8lC9EPJQ8lDyUPJQvSjyUPJQvUDyUL1YvXC9iL2g8lC90PJQ8lC9uPJQvdDyUPJQvpDyUL548lDyUL6Q8lC96PJQ8lC+kPJQvgDyUPJQvpDyUL6o8lDyUL4w8lC+ePJQ8lC+kPJQvhjyUPJQvjDyUL548lDyUL6Q8lC+SPJQ8lC+YPJQvnjyUPJQvpDyUL6o8lDyUL7A8lC+2PJQ8lDNYPJQvzi/UPJQzWDyUL84v1DyUM1g8lC+8L9Q8lDNYPJQvzi/UPJQvwjyUL84v1DyUL8I8lC/OL9Q8lC/IPJQvzi/UPJQwEDAWL/48lDAiMBAwFi/sPJQwIjAQMBYwCjyUMCIwEDAWMAo8lDAiMBAwFjAKPJQwIjAQMBYv7DyUMCIwEDAWL9o8lDAiL+AwFi/+PJQwIjAQMBYv7DyUMCIwEDAWL+Y8lDAiMBAwFi/+PJQwIjAQMBYv7DyUMCIv4DAWL/48lDAiMBAwFi/sPJQwIjAQMBYv5jyUMCIwEDAWMAo8lDAiMBAwFi/sPJQwIjAQMBYwCjyUMCIwEDAWL/I8lDAiMBAwFi/4PJQwIjAQMBYv/jyUMCIwEDAWMAQ8lDAiMBAwFjAKPJQwIjAQMBYwHDyUMCIwOjyUMCg8lDyUMDo8lDBAPJQ8lDA6PJQwLjyUPJQwOjyUMDQ8lDyUMDo8lDBAPJQ8lDBwPJQwWDyUPJQwcDyUMF48lDyUMHA8lDB2PJQ8lDBwPJQwRjyUPJQwcDyUMEw8lDyUMFI8lDBYPJQ8lDBwPJQwXjyUPJQwcDyUMGQ8lDyUMHA8lDBqPJQ8lDBwPJQwdjyUPJQ6SDyUMI48lDyUOkg8lDB8PJQ8lDpIPJQwgjyUPJQ6SDyUMIg8lDyUOiQ8lDCOPJQ8lDnoMNYwyjyUPJQ56DDWMLg8lDyUOegw1jDcPJQ8lDnoMNYwmjyUPJQ59DDWMNw8lDyUOegw1jCaPJQ8lDnoMNYwlDyUPJQ56DDWMJo8lDyUOegw1jDcPJQ8lDnoMNYw3DyUPJQ56DDWMKA8lDyUOfQw1jDcPJQ8lDnoMNYwoDyUPJQ56DDWMKY8lDyUOegw1jCsPJQ8lDnoMNYwuDyUPJQ56DDWMLI8lDyUOfQw1jDKPJQ8lDnoMNYwuDyUPJQ56DDWML48lDyUOegw1jDcPJQ8lDnoMNYwxDyUPJQ56DDWMMo8lDyUOegw1jDQPJQ8lDnoMNYw0DyUPJQ56DDWMNw8lDyUMOg8lDDiPJQ8lDDoPJQw7jyUPJQxBjyUMPQ8lDyUMQY8lDD6PJQ8lDEGPJQxADyUPJQxBjyUMPQ8lDyUMQY8lDD6PJQ8lDEGPJQxADyUPJQxBjyUMQw8lDyUMRI8lDyUNQ41FDESPJQ8lDUONRQxEjyUPJQ1DjUUMRg8lDyUNQ41FDEePJQ8lDUONRQxJDyUMSo1DjUUO1AxeDFOPJQ8lDtQMXgxVDyUPJQ7UDF4MX48lDyUO1AxeDF+PJQ8lDtQMXgxfjyUPJQ7UDF4MX48lDyUO1AxeDEwPJQ8lDgUMXgxfjyUPJQ7UDF4MTA8lDyUO1AxeDE2PJQ8lDtQMXgxPDyUPJQ7UDF4MVQ8lDyUO1AxeDFCPJQ8lDtQMXgxSDyUPJQ4FDF4MU48lDyUO1AxeDFUPJQ8lDtQMXgxWjyUPJQ7UDF4MX48lDyUO1AxeDFgPJQ8lDtQMXgxZjyUPJQ7UDF4MWY8lDyUMWw8lDFyPJQ8lDtQMXgxfjyUPJQxhDGKMZA8lDyUMZw8lDGWPJQ8lDGcPJQxojyUPJQ8lDyUMag8lDyUPJQ8lDGuPJQ8lDyUPJQxrjyUPJQ8lDyUMa48lDyUPJQ8lDG0PJQ8lDyUPJQxujyUPJQ8lDyUMcA8lDyUOkg8lDWkMdIx2DpIPJQ1pDHSMdgxxjyUNaQx0jHYOkg8lDIyMdIx2DpIPJQxzDHSMdg6JDyUNaQx0jHYM3AyDjIIPJQ8lDNwMg4x3jyUPJQzcDIOMfY8lDyUM3AyDjIUPJQ8lDNwMg4yFDyUPJQzcDIOMfY8lDyUM3AyDjHkPJQ8lDNwMg4x6jyUPJQzcDIOMfA8lDyUM2oyDjIIPJQ8lDNwMg4x9jyUPJQzcDIOMfw8lDyUM3AyDjIUPJQ8lDNwMg4ySjyUPJQzcDIOMgI8lDyUM3AyDjIIPJQ8lDNwMg4yFDyUPJQ8lDyUMho8lDyUPJQ8lDIgPJQ8lDyUPJQyJjyUPJQyLDyUNaQ8lDI+Miw8lDIyPJQyPjI4PJQ1pDyUMj44LDyUMkQ8lDyUM3A8lDWkNaoyUDNwPJQ1hjWqMlAzcDyUNaQ1qjJQM2o8lDWkNaoyUDNwPJQ1pDWqMlAzajyUNaQ1qjJQM3A8lDJKNaoyUDN8PJQ1pDWqMlAyVjyUMlwyYjJoMm48lDyUPJQ8lDJ0PJQ8lDyUPJQ6SDyUMp48lDyUOkg8lDJ6PJQ8lDKAPJQyhjyUPJQ6SDyUMqQ8lDyUOiQ8lDKePJQ8lDpIPJQyjDyUPJQ6JDyUMp48lDyUOkg8lDKSPJQ8lDKYPJQynjyUPJQ6SDyUMqQ8lDyUMxYzHDL4MygzLjMWMxwy7DMoMy4zFjMcMxAzKDMuMxYzHDMQMygzLjMWMxwyqjMoMy4yyDMcMxAzKDMuMxYzHDKqMygzLjMWMxwysDMoMy4zFjMcMrYzKDMuMxYzHDLsMygzLjMWMxwyvDMoMy4zFjMcMyIzKDMuMxYzHDLCMygzLjLIMxwy+DMoMy4zFjMcMuwzKDMuMxYzHDLOMygzLjLmPJQzXjyUPJQy5jyUMto8lDyUMtQ8lDNePJQ8lDLmPJQy2jyUPJQy5jyUMuA8lDyUMuY8lDMQPJQ8lDMWMxwy7DMoMy4zFjMcMxAzKDMuMxYzHDLyMygzLjMWMxwzIjMoMy4zFjMcMyIzKDMuMxY8lDL4Mygy/jMWMxwzBDMoMy4zFjMcMwozKDMuMxYzHDMQMygzLjMWMxwzIjMoMy4zFjMcMyIzKDMuMxYzHDMiMygzLjM0PJQzOjyUPJQzQDyUM0Y8lDyUM0w8lDNSPJQ8lDNYPJQzXjyUPJQzcDyUM4I8lDyUM3A8lDNkPJQ8lDNwPJQzdjyUPJQzajyUM4I8lDyUM3A8lDNkPJQ8lDNqPJQzgjyUPJQzcDyUM3Y8lDyUM3w8lDOCPJQ8lDOgPJQzpjyUPJQzoDyUM4g8lDyUM6A8lDOOPJQ8lDOgPJQzmjyUPJQzoDyUM5Q8lDyUM6A8lDOmPJQ8lDOgPJQzmjyUPJQzrDyUM6Y8lDyUM6A8lDOyPJQ8lDOsPJQzpjyUPJQzrDyUM7I8lDyUM9A8lDPoM+4z9DO4PJQzvjPEM8oz0DyUM+gz7jP0M9A8lDPoM+4z9DPcPJQz6DPuM/Qz0DyUM9Yz7jP0M9w8lDPoM+4z9DPiPJQz6DPuM/Q23DQGNig8lDQSNtw0BjYuPJQ0EjbcNAY2RjyUNBI23DQGNkY8lDQSNtw0BjZGPJQ0EjbcNAY2LjyUNBI23DQGNhw8lDQSM/o0BjYoPJQ0EjbcNAY2LjyUNBI23DQGNjQ8lDQSNtw0BjYoPJQ0EjbcNAY2LjyUNBIz+jQGNig8lDQSNtw0BjYuPJQ0EjbcNAY2NDyUNBI23DQGNkY8lDQSNtw0BjYuPJQ0EjbcNAY2RjyUNBI23DQGNjo8lDQSNtw0BjQMPJQ0EjbcNAY2KDyUNBI23DQGNAA8lDQSNtw0BjZGPJQ0EjbcNAY0DDyUNBI0GDyUNB48lDyUNDY8lDQkPJQ8lDQ2PJQ0PDyUPJQ0NjyUNCo8lDyUNDY8lDQwPJQ8lDQ2PJQ0PDyUPJQ0bDyUNFQ8lDyUNGw8lDRaPJQ8lDRsPJQ0cjyUPJQ0bDyUNEI8lDyUNGw8lDRIPJQ8lDROPJQ0VDyUPJQ0bDyUNFo8lDyUNGw8lDRgPJQ8lDRsPJQ0ZjyUPJQ0bDyUNHI8lDyUNIQ8lDSWPJQ8lDSEPJQ0eDyUPJQ0hDyUNH48lDyUNIQ8lDSKPJQ8lDSQPJQ0ljyUPJQ05DTqNNg8lDyUNOQ06jTGPJQ8lDTkNOo08DyUPJQ05DTqNKI8lDyUNMA06jTwPJQ8lDTkNOo0ojyUPJQ05DTqNJw8lDyUNOQ06jSiPJQ8lDTkNOo08DyUPJQ05DTqNPA8lDyUNOQ06jSoPJQ8lDTANOo08DyUPJQ05DTqNKg8lDyUNOQ06jSuPJQ8lDTkNOo0tDyUPJQ05DTqNMY8lDyUNOQ06jS6PJQ8lDTANOo02DyUPJQ05DTqNMY8lDyUNOQ06jTMPJQ8lDTkNOo08DyUPJQ05DTqNNI8lDyUNOQ06jTYPJQ8lDTkNOo03jyUPJQ05DTqNN48lDyUNOQ06jTwPJQ8lDyUPJQ09jyUPJQ8lDyUNPw8lDyUNQI8lDUINQ41FDViNWg1PjyUPJQ1YjVoNUQ8lDyUNWI1aDVuPJQ8lDViNWg1bjyUPJQ1YjVoNW48lDyUNWI1aDVuPJQ8lDViNWg1GjyUPJQ1ODVoNW48lDyUNWI1aDUaPJQ8lDViNWg1IDyUPJQ1YjVoNSY8lDyUNWI1aDVEPJQ8lDViNWg1LDyUPJQ1YjVoNTI8lDyUNTg1aDU+PJQ8lDViNWg1RDyUPJQ1YjVoNUo8lDyUNWI1aDVuPJQ8lDViNWg1UDyUPJQ1YjVoNVY8lDyUNWI1aDVWPJQ8lDdmPJQ1XDyUPJQ1YjVoNW48lDyUNXQ1ejWAPJQ8lDWePJQ1pDWqNc41njyUNYY1qjXONZ48lDWkNao1zjWMPJQ1pDWqNc41njyUNaQ1qjXONYw8lDWkNao1zjWePJQ1kjWqNc41mDyUNaQ1qjXONZ48lDWkNao1zjWwPJQ1tjyUPJQ11DyUNew18jX4Nbw8lDXCNcg1zjXUPJQ17DXyNfg11DyUNew18jX4NeA8lDXsNfI1+DXUPJQ12jXyNfg14DyUNew18jX4NeY8lDXsNfI1+DYQPJQ1/jyUPJQ2EDyUNhY8lDyUNhA8lDYEPJQ8lDYQPJQ2CjyUPJQ2EDyUNhY8lDyUNkA8lDYoPJQ8lDZAPJQ2LjyUPJQ2QDyUNkY8lDyUNkA8lDYcPJQ8lDYiPJQ2KDyUPJQ2QDyUNi48lDyUNkA8lDY0PJQ8lDZAPJQ2OjyUPJQ2QDyUNkY8lDyUNlg8lDZqPJQ8lDZYPJQ2TDyUPJQ2WDyUNlI8lDyUNlg8lDZePJQ8lDZkPJQ2ajyUPJQ7UDayNqY8lDyUO1A2sjaUPJQ8lDtQNrI2uDyUPJQ7UDayNnY8lDyUOBQ2sja4PJQ8lDtQNrI2djyUPJQ7UDayNnA8lDyUO1A2sjZ2PJQ8lDtQNrI2uDyUPJQ7UDayNrg8lDyUO1A2sjZ8PJQ8lDgUNrI2uDyUPJQ7UDayNnw8lDyUO1A2sjaCPJQ8lDtQNrI2iDyUPJQ7UDayNpQ8lDyUO1A2sjaOPJQ8lDgUNrI2pjyUPJQ7UDayNpQ8lDyUO1A2sjaaPJQ8lDtQNrI2uDyUPJQ7UDayNqA8lDyUO1A2sjamPJQ8lDtQNrI2rDyUPJQ7UDayNqw8lDyUO1A2sja4PJQ8lDbEPJQ2vjyUPJQ2xDyUNso8lDyUNvQ8lDbQPJQ8lDbcPJQ6/DyUPJQ23DyUNtY8lDyUNtw8lDrePJQ8lDbcPJQ6/DyUPJQ23DyUNtY8lDyUNtw8lDrePJQ8lDbcPJQ66jyUPJQ29DyUOAg6eDyUNuI8lDboNu48lDb0PJQ39jp4PJQ2+jyUNwA3BjyUNww8lDgIOng8lDcSPJQ4CDp4PJQ3GDyUNx46eDyUN2Y3bDdgPJQ8lDdmN2w3SDyUPJQ3ZjdsN3I8lDyUN2Y3bDdyPJQ8lDdmN2w3cjyUPJQ3ZjdsN3I8lDyUN2Y3bDckPJQ8lDdCN2w3cjyUPJQ3ZjdsNyQ8lDyUN2Y3bDcqPJQ8lDdmN2w3MDyUPJQ3ZjdsN0g8lDyUN2Y3bDc2PJQ8lDdmN2w3PDyUPJQ3QjdsN2A8lDyUN2Y3bDdIPJQ8lDdmN2w3TjyUPJQ3ZjdsN3I8lDyUN2Y3bDdUPJQ8lDdmN2w3WjyUPJQ3ZjdsN1o8lDyUN2Y3bDdgPJQ8lDdmN2w3cjyUPJQ60jyUOtg8lDyUN348lDd4PJQ8lDd+PJQ3hDyUPJQ8BDyUOvw8lDyUPAQ8lDrePJQ8lDwEPJQ63jyUPJQ8BDyUOt48lDyUO9o8lDr8PJQ8lDwEPJQ66jyUPJQ8BDyUOvA8lDyUPAQ8lDr8PJQ8lDh6PJQ4dDeiPJQ3ijyUN5A3ljyUN5w8lDh0N6I8lDh6PJQ4gDeiPJQ4ejyUOIA3ojyUOGI8lDh0N6I8lDfYN9430jyUPJQ32DfeN9I8lDyUN9g33jfAPJQ8lDfYN9435DyUPJQ32DfeN+Q8lDyUN9g33jfAPJQ8lDfYN943qDyUPJQ32DfeN648lDyUN9g33je0PJQ8lDe6N9430jyUPJQ32DfeN8A8lDyUN9g33jfGPJQ8lDfYN9435DyUPJQ8lDyUOyA8lDyUN9g33jfMPJQ8lDfYN9430jyUPJQ32DfeN+Q8lDyUPJQ8lDfqPJQ8lDyUPJQ38DyUPJQ4AjyUOAg8lDyUOAI8lDf2PJQ8lDf8PJQ4CDyUPJQ4AjyUOAg8lDyUO1A8lDgmO1w7YjtQPJQ4DjtcO2I7UDyUOCY7XDtiOBQ8lDgmO1w7YjtQPJQ4JjtcO2I4FDyUOCY7XDtiO1A8lDgaO1w7YjggPJQ4JjtcO2I4LDyUODI4ODg+OEQ8lDhQPJQ8lDhKPJQ4UDyUPJQ4ejyUOHQ8lDyUOHo8lDhWPJQ8lDh6PJQ4gDyUPJQ4YjyUOHQ8lDyUOHo8lDhcPJQ8lDhiPJQ4dDyUPJQ4ejyUOGg8lDyUOG48lDh0PJQ8lDh6PJQ4gDyUPJQ4zjjUOLw44DjmOM441DiwOOA45jjOONQ4yDjgOOY4zjjUOMg44DjmOM441DiGOOA45jikONQ4yDjgOOY4zjjUOIY44DjmOM441DiMOOA45jjOONQ4kjjgOOY4zjjUOLA44DjmOM441DiYOOA45jjOONQ42jjgOOY4zjjUOJ444DjmOKQ41Di8OOA45jjOONQ4sDjgOOY4zjjUOKo44DjmOM48lDi8PJQ8lDjOPJQ4sDyUPJQ4pDyUOLw8lDyUOM48lDiwPJQ8lDjOPJQ4qjyUPJQ4zjyUOMg8lDyUOM441DiwOOA45jjOONQ4yDjgOOY4zjjUOLY44DjmOM441DjaOOA45jjOONQ42jjgOOY8lDyUOLw8lDyUOMI41DuYOOA45jjCONQ7ejjgOOY4zjjUOMg44DjmOM441DjaOOA45jjOONQ42jjgOOY4zjjUONo44DjmOOw8lDjyPJQ8lDyUPJQ4+DyUPJQ5CjyUORw8lDyUOQo8lDj+PJQ8lDkKPJQ5EDyUPJQ5BDyUORw8lDyUOQo8lDj+PJQ8lDkEPJQ5HDyUPJQ5CjyUORA8lDyUORY8lDkcPJQ8lDk6PJQ5QDyUPJQ5OjyUOSI8lDyUOTo8lDkoPJQ8lDk6PJQ5NDyUPJQ5OjyUOS48lDyUOTo8lDlAPJQ8lDk6PJQ5NDyUPJQ5RjyUOUA8lDyUOTo8lDlMPJQ8lDlGPJQ5QDyUPJQ5RjyUOUw8lDyUOVg8lDlwOXY8lDlYPJQ5cDl2PJQ5WDyUOVI5djyUOVg8lDlwOXY8lDlkPJQ5cDl2PJQ5WDyUOV45djyUOWQ8lDlwOXY8lDlqPJQ5cDl2PJQ8BDl8O/I8lDmCPAQ5fDvmPJQ5gjwEOXw7/jyUOYI8BDl8O/48lDmCPAQ5fDv+PJQ5gjwEOXw75jyUOYI8BDl8O9Q8lDmCO9o5fDvyPJQ5gjwEOXw75jyUOYI8BDl8O+A8lDmCPAQ5fDvyPJQ5gjwEOXw75jyUOYI72jl8O/I8lDmCPAQ5fDvmPJQ5gjwEOXw74DyUOYI8BDl8O/48lDmCPAQ5fDvmPJQ5gjwEOXw7/jyUOYI8BDl8O+w8lDmCPAQ5fDwQPJQ5gjwEOXw7+DyUOYI8BDl8O/48lDmCPAQ5fDwQPJQ5gjmaPJQ5iDyUPJQ5mjyUOaA8lDyUOZo8lDmOPJQ8lDmaPJQ5lDyUPJQ5mjyUOaA8lDyUOdA8lDm4PJQ8lDnQPJQ5vjyUPJQ50DyUOdY8lDyUOdA8lDmmPJQ8lDnQPJQ5rDyUPJQ5sjyUObg8lDyUOdA8lDm+PJQ8lDnQPJQ5xDyUPJQ50DyUOco8lDyUOdA8lDnWPJQ8lDnoPJQ5+jyUPJQ56DyUOdw8lDyUOeg8lDniPJQ8lDnoPJQ57jyUPJQ59DyUOfo8lDyUOkg6Tjo8PJQ8lDpIOk46KjyUPJQ6SDpOOlQ8lDyUOkg6TjoGPJQ8lDokOk46VDyUPJQ6SDpOOgY8lDyUOkg6TjoAPJQ8lDpIOk46BjyUPJQ6SDpOOlQ8lDyUOkg6TjpUPJQ8lDpIOk46DDyUPJQ6JDpOOlQ8lDyUOkg6TjoMPJQ8lDpIOk46EjyUPJQ6SDpOOhg8lDyUOkg6TjoqPJQ8lDpIOk46HjyUPJQ6JDpOOjw8lDyUOkg6TjoqPJQ8lDpIOk46MDyUPJQ6SDpOOlQ8lDyUOkg6Tjo2PJQ8lDpIOk46PDyUPJQ6SDpOOkI8lDyUOkg6TjpCPJQ8lDpIOk46VDyUPJQ6YDyUOlo8lDyUOmA8lDpmPJQ8lDpsPJQ6cjp4PJQ6wDrGOro8lDyUOsA6xjqiPJQ8lDrAOsY6zDyUPJQ6wDrGOsw8lDyUOsA6xjrMPJQ8lDrAOsY6zDyUPJQ6wDrGOn48lDyUOpw6xjrMPJQ8lDrAOsY6fjyUPJQ6wDrGOoQ8lDyUOsA6xjqKPJQ8lDrAOsY6ojyUPJQ6wDrGOpA8lDyUOsA6xjqWPJQ8lDqcOsY6ujyUPJQ6wDrGOqI8lDyUOsA6xjqoPJQ8lDrAOsY6zDyUPJQ6wDrGOq48lDyUOsA6xjq0PJQ8lDrAOsY6tDyUPJQ8lDyUOro8lDyUOsA6xjrMPJQ8lDrSPJQ62DyUPJQ69jyUOvw8lDyUOvY8lDrePJQ8lDr2PJQ63jyUPJQ69jyUOt48lDyUOuQ8lDr8PJQ8lDr2PJQ66jyUPJQ69jyUOvA8lDyUOvY8lDr8PJQ8lDsyOzg7LDyUPJQ7Mjs4Oyw8lDyUOzI7ODsUPJQ8lDsyOzg7PjyUPJQ7Mjs4Oz48lDyUOzI7ODsUPJQ8lDsyOzg7AjyUPJQ7Mjs4Owg8lDyUOw47ODssPJQ8lDsyOzg7FDyUPJQ7Mjs4Oxo8lDyUOzI7ODs+PJQ8lDyUPJQ7IDyUPJQ7Mjs4OyY8lDyUOzI7ODssPJQ8lDsyOzg7PjyUPJQ8lDyUO0Q8lDyUPJQ8lDtKPJQ8lDtQPJQ7VjtcO2I7aDyUO3Q8lDyUO248lDt0PJQ8lDuePJQ7mDyUPJQ7njyUO3o8lDyUO548lDukPJQ8lDuGPJQ7mDyUPJQ7njyUO4A8lDyUO4Y8lDuYPJQ8lDuePJQ7jDyUPJQ7kjyUO5g8lDyUO548lDukPJQ8lDuwPJQ7yDvOPJQ7sDyUO8g7zjyUO7A8lDuqO848lDuwPJQ7yDvOPJQ7vDyUO8g7zjyUO7A8lDu2O848lDu8PJQ7yDvOPJQ7wjyUO8g7zjyUPAQ8CjvyPJQ8FjwEPAo75jyUPBY8BDwKO/48lDwWPAQ8Cjv+PJQ8FjwEPAo7/jyUPBY8BDwKO+Y8lDwWPAQ8CjvUPJQ8FjvaPAo78jyUPBY8BDwKO+Y8lDwWPAQ8CjvgPJQ8FjwEPAo78jyUPBY8BDwKO+Y8lDwWO9o8CjvyPJQ8FjwEPAo75jyUPBY8BDwKO+A8lDwWPAQ8Cjv+PJQ8FjwEPAo75jyUPBY8BDwKO/48lDwWPAQ8CjvsPJQ8FjwEPAo8EDyUPBY8BDwKO/I8lDwWPAQ8Cjv4PJQ8FjwEPAo7/jyUPBY8BDwKPBA8lDwWPC48lDwcPJQ8lDwuPJQ8NDyUPJQ8LjyUPCI8lDyUPC48lDwoPJQ8lDwuPJQ8NDyUPJQ8ZDyUPEw8lDyUPGQ8lDxSPJQ8lDxkPJQ8ajyUPJQ8ZDyUPDo8lDyUPGQ8lDxAPJQ8lDxGPJQ8TDyUPJQ8ZDyUPFI8lDyUPGQ8lDxYPJQ8lDxkPJQ8XjyUPJQ8ZDyUPGo8lDyUPHw8lDyOPJQ8lDx8PJQ8cDyUPJQ8fDyUPHY8lDyUPHw8lDyCPJQ8lDyIPJQ8jjyUPJQAAQFuA7sAAQFuA7AAAQIWA40AAQHwA6EAAQFuA7YAAQFu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AFYAZQB0AIMAkQCgAK8AvgDNANwA6wD6AQkBGAEnATYAAP//ABUADAAbACoAOQBIAFcAZgB1AIQAkgChALAAvwDOAN0A7AD7AQoBGQEoATcAAP//ABUADQAcACsAOgBJAFgAZwB2AIUAkwCiALEAwADPAN4A7QD8AQsBGgEpATgAAP//ABUADgAdACwAOwBKAFkAaAB3AIYAlACjALIAwQDQAN8A7gD9AQwBGwEqATkBOmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNjbXAHgmNjbXAHgmNjbXAHgmNjbXAHgmNjbXAHgmNjbXAHcmNjbXAHgmNjbXAHgmNjbXAHgmNjbXAHgmNjbXAHgmNjbXAHgmNjbXAHgmNjbXAHgmNjbXAHgmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxvY2wHsGxvY2wHtmxvY2wHvGxvY2wHwmxvY2wHyGxvY2wHzmxvY2wH1GxvY2wH2mxvY2wH4GxvY2wH5mxvY2wH7GxvY2wH8mxvY2wH+GxvY2wH/m51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQgAAAAIAAAABAAAAAQAkAAAAAQAmAAAABgACAAMABAAFAAYABwAAAAQAAgADAAQABQAAAAEAJwAAAAEAGgAAAAMAGwAcAB0AAAABACgAAAABACAAAAABABEAAAABABUAAAABABQAAAABABIAAAABABMAAAABABAAAAABAAkAAAABAA8AAAABAAwAAAABAAsAAAABAAgAAAABAAoAAAABAA0AAAABAA4AAAABABkAAAABACMAAAACAB4AHwAAAAEAIQAAAAEAKQAAAAEAFwAAAAEAJQAAAAEAKgAAAAEAFgAAAAEAGAAAAAEAIgAtAFwG3hGaEkgSrhKuFAIUAhSsFNoVHhUeFUAVQBVAFUAVQBVUFcIV1hX8FhYWPBZKFlgWiBZmFnQWiBaWFt4XJhdIF2AXeBeQF64Z+BxUHUYdZh2OHY4iniM4AAEAAAABAAgAAgRCAh4C+wL8Av0C/gL/AwADAQMCAwMDBAMFAwYDBwMIAyIDIwMtAy4DLwMwAzEDMgNHA0gDSQNLA0wDTQNOA08DUANRA1IDUwNhA2IDYwNkA2UDZgNnA2gDaQNqA2sDbANtA24DbwNwA3EDcgNzA3QDdQN2A3cDeAN5A3oDewN8A30DfgN/A4ADgQOCA4MDhAOGA4cDiAOJA4oDiwOMA40DjgOPA5ADkQOSA5MDlQOWA5cDmAOZA5oDuwPBAvsC/AL9Av4C/wMAAwEDAgMDAwQDBQMGAwcDCAMiAyMDJQMmAycDKAMpAyoDKwMsAy0DLgMvAzADMQMyAzQDNQM3AzgDOQM6AzsDPAM9Az4DPwNAA0EDQgNDA0QDRgNHA0gDSQNKA1QDVQNWA1cDWANZA1oDWwNcA10DXgNfA2EDYgNjA2QDZQNmA2cDaANpA2oDawNsA20DbgNvA3ADcQNyA3MDdAN1A3YDdwN4A3kDegN7A3wDfQN+A38DgAOBA4MDhAOFA4YDhwOIA4kDigOLA4wDjQOOA48DkAORA5IDkwOVA5YDlwOYA5kDmgOjA6QDpQOmA6cDqAOpA6oDqwOsA60DrgOvA7ADsQOyA7MDtAO1A7YDtwO4A7kDugO7A8EDxgM2At0C3gPRA9ID0wPUA9UD1gPXA9gD2QPaA9sD3APdA94D3wPgA+ED4gPjA+QD5QPmA+cD6APpA+oD6wPsA+0D7gPvA/AD8QPyA/MD9AP1A/YD9wP4A/kD+gP7A/wD/QP+A/8EAAQBBAIEAwQEBAUEBgQHBAgECQQKBAsEDAQNBA4EDwQQBBEEEgQTBBQEFQQWBBcEGAQZBBoEGwQcBB0EHgQfBCAEIQQiBCMEJAQlBCYEJwQoBCkEKgQrBCwELQQuBC8EMAQxBDIEMwQ0BDUENgQ3BDgEOQQ6BDsEPAQ9BD4EPwRABEEEQgRDBEQERQRGBEcESARJBEoESwRMBE0ETgRPBFAEUQRSBFMEVARVBFYEVwRYBFkEWgRbBFwEXQReBF8EYARhBGIEYwTjBOUE5gTnBOgE6QTrBOoE7QTuBO8E8ATyBPME9AT1BPYE9wT4BN8E4AT5BPoE+wT8BP0E/gT/BQAFAQUCBQMFBAUFBZoFlQV9BZQFnAWdBZ4FgAWBBaEFhQWGBYcFowWlBaYFigWLBYwFjQWpBaoFqwWQBawFkQWSBZMFrQWuBa8FsAWxBbIFswW0BbUFtgW3BbgFuQX8Bf0F/gX/BgAGAQYCBgMGBAYFBjYGOAZgBmEGZgZnBmgGaQZwBjkGQgZDBkQGRQZGBkcGTwZQBlEGagZrBmwGbQZuBm8GuQa6BrsGvAbcBt4G3QcKBwsHDAcNBw4HDwcQBxEHEgcTBxQHFQcWBxcHGAcZBxoHGwccBx0HHgcfByAHIQciByMHJAdWByYHZgdnB2gHaQdqB2sHbAdtAAIAXgAgACgAAAAqAC4ACQBHAEgADgBSAFcAEABqAG0AFgBvAHYAGgCFAKgAIgCqALcARgC5AL4AVADfAN8AWgDlAOUAWwGmAbMAXAHNAc4AagHQAd0AbAHfAe4AegHxAfUAigH/AgIAjwIEAgsAkwINAi0AmwIvAj8AvAJBAkYAzQJQAmgA0wJuAm4A7AJzAnMA7QJ+An4A7gLbAtwA7wLfAvoA8QMJAyEBDQMkAywBJgMzAzsBLwM9A0YBOANRA1EBQgNUA18BQwOFA4UBTwObA7oBUAO8A8ABcAPCA9ABdQRmBGYBhARtBG8BhQRyBHUBiAR9BH0BjAR/BIEBjQSJBI0BkASTBJMBlQSYBJgBlgScBJwBlwSfBJ8BmASqBKoBmQS8BL8BmgTFBMYBngTLBM0BoATQBNABowTWBNYBpATYBNgBpQUGBQgBpgUKBQoBqQUNBREBqgUVBRYBrwUYBRgBsQUaBRoBsgUdBR0BswUgBSEBtAUkBScBtgUrBS0BugU1BTUBvQU4BTgBvgU8BTwBvwU/BT8BwAVJBUkBwQVdBWIBwgVmBWcByAVsBW4BygVxBXEBzQV5BXkBzgYGBg8BzwYlBiUB2QYnBicB2gYrBiwB2wYuBjIB3QY7BkEB4gZIBkkB6QZMBkwB6wZWBlsB7AavBq8B8gaxBrEB8wazBrMB9Aa1BrUB9QbKBssB9gbYBtgB+AbfBuoB+QbsBu8CBQbyBvwCCQcHBwgCFAdeB2UCFgADAAAAAQAIAAEJtAEyAmoCcgJ4An4ChAKKApAClgKcAqICqAKuArQCugLAAsYCzALSAtgC3gLkAuoC8AL2AvwDAgMIAw4DFAMaAyADJgMsAzIDOAM+A0QDSgNQA1YDXANiA2gDbgN0A3oDgAOGA4wDkgOYA54DpAOqA7ADtgO8A8IDyAPOA9QD2gPgA+YD7APyA/gD/gQEBAoEEAQWBBwEIgQoBC4ENAQ6BEAERgRMBFIEWAReBGQEagRwBHYEfASCBIgEjgSUBJoHdgSgBKYErASyBLgEvgTEBMwE0gTYBN4E5ATqBPAE9gT8BQIFCAUOBRQFGgUgBSYFLAUyBTgFPgVEBUoFUAVWBVwFYgVoBW4FdAV6BYAFhgWMBZIFmAWeBaQFqgWwBbYFvAXCBcgFzgXUBdoF4AXmBewF9AX6BgAGBgYMBhIGGAYeBiQGKgYwBjYGPAZCBkgGTgZUBloGYAZmBmwGcgZ4Bn4GhAaKBpAGlgacBqIGqAauBrQGugbABsYGzAbSBtgG3gbkBuoG8Ab2BvwHAgcIBw4HFAcaByAHJgcsBzIHOgdAB0YHTAdSB1gHXgdkB2oHcAd2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AQIBAwEEAQUBBgEHAQgBCQEKAQsBDAENAQ4BDwEQAREBEgETARQBFQEWARcBGAEZARoBGwEcAR0BHgEfASABIQEiASMBJAElASYBJwEoASkBKgErASwBLQEuAS8BMAExATIBMwE0ATUBNgE4ATkBOgE7ATwBPQE+AT8BQAFBAUIBQwFEAUUBRgFHAUgBSQFKAUsBTAFNAU4BTwFQAVEBUgFTAVQBVQFWAVcBWAFZAVoBWwFcAV0BXgFfAWABYQFiAWMBZAFlAWYBZwFoAWkBagFrAWwBbQFuAW8BcAFxAXIBcwF0AXUBdgF3AXgBeQF6AXsBfAF9AX4BfwGAAYEBggGDAYQBhQGGAYcBiAGJATcCfwKAAoECggKDAoQChQKGAocCiAKJAooCiwKMAo0CjgKPApACkQKSApMClAKVApYClwKYApkCmgKbApwCnQKeAp8CoAKhAqICowKkAqUCpgKnAqgCqQKqAqsCrAKtAq4CrwKwArECsgKzArQCtQK2ArcCuAK5AroCuwK8Ar0CvgK/AsACwQLCAsMCxALFAsYCxwLIAskCygLLAswCzQLOAs8C0ALRAtIC0wLUAtUC1gLXAtgC2QLdAt4D0QPSA9MD1APVA9YD1wPYA9kD2gPbA9wD3QPeA98D4APhA+ID4wPkA+UD5gPnA+gD6QPqA+sD7APtA+4D7wPwA/ED8gPzA/QD9QP2A/cD+AP5A/oD+wP8A/0D/gP/BAAEAQQCBAMEBAQFBAYEBwQIBAkECgQLBAwEDQQOBA8EEAQRBBIEEwQUBBUEFgQXBBgEGQQaBBsEHAQdBB4EHwQgBCEEIgQjBCQEJQQmBCcEKAQpBCoEKwQsBC0ELgQvBDAEMQQyBDMENAQ1BDYENwQ4BDkEOgQ7BDwEPQQ+BD8EQARBBEIEQwREBEUERgRHBEgESQRKBEsETARNBE4ETwRQBFEEUgRTBFQEVQRWBFcEWARZBFoEWwRcBF0EXgRfBGAEYQRiBGME4wTkBOUE5gTnBOgE6QTrBOoE7ATtBO4E7wTwBPEE8gTzBPQE9QT2BPcE+AT5BPoE+wT8BP0E/gT/BQAFAQUCBQMFBAUFBZoFmwWcBZ0FngWfBaAFogWhBaMFpAWlBaYFpwWoBakFqgWrBawFrQWuBa8FsAWxBbIFswW0BbUFtgW3BbgFuQbdAAIAPQAEAB8AAAApACkAHAAvAEYAHQBJAFEANQBYAGkAPgBuAG4AUAB3AIMAUQCpAKkAXgC/AN4AXwDgAOQAfwDmAPUAhAGKAaUAlAG0AcwAsAHPAc8AyQH2Af4AygIuAi4A0wJIAk8A1AJpAm0A3AJvAnIA4QJ0An0A5QLbAtwA7wLfAvoA8QMJAyEBDQMkAywBJgMzAzsBLwM9A0YBOANRA1EBQgNUA18BQwOFA4UBTwObA7oBUAO8A8ABcAPCA9ABdQRmBGYBhARsBG8BhQRyBHUBiQR4BHgBjQR9BH0BjgR/BIIBjwSJBI0BkwSTBJMBmASYBJgBmQSqBKoBmgS8BL8BmwTFBMYBnwTLBM0BoQTQBNABpATWBNYBpQTYBNgBpgUGBQYBpwUMBQ8BqAUSBRUBrAUdBR0BsAUfBSEBsQUpBS0BtAU4BTgBuQVdBWIBugVmBWcBwAVsBW4BwgVxBXEBxQV5BXkBxgbYBtgBxwABAAAAAQAIAAIAWAApAd8B8AY7BwoHCwcMBw0HDgcPBxAHEQcSBxMHFAcVBxYHFwcYBxkHGgcbBxwHHQceBx8HIAchByIHIwckByUHJgcnB2YHZwdoB2kHagdrB2wHbQACAAkB3gHeAAAB7wHvAAEGJgYmAAIG3wbqAAMG7AbvAA8G8gb8ABMHBgcGAB4HCAcJAB8HXgdlACEAAQAAAAEACAACACQADwRkBGUEZARlBfwF/QX+Bf8GAAYBBgIGAwYEBgUGOQABAA8ABACEAYoCDAYGBgcGCAYJBgoGCwYMBg0GDgYPBiYAAA==) format("truetype")}@font-face{font-weight:normal;font-family:"tick42-icons";font-style:normal;src:url(data:font/ttf;base64,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YGAGCAcGqgJK/bYCgP1KJhsaARscJQK2JhsaARscJQAAAQAAAAEAAH2fuHdfDzz1AAsEAAAAAADhVnMIAAAAAOFWcwj//f+9BQADwwAAAAgAAgAAAAAAAAABAAADwP/AAAAFJP/9//0FAAABAAAAAAAAAAAAAAAAAAAA9wQAAAAAAAAAAAAAAAIAAAAEAAAABAAAAAO2//8ESQAAA24AAANuAAACkf//A24AAAO2//8CSQAABAAAAAO2//8CAAAAAmYAAALNAAACHwAAAmYAAAJmAAACqwAAAeEAAAOFAAADhQAAA24AAAQAAAAEkf//AyQAAANWAAACZgAAAOEAAAJIAAADrgAAAysAAAOaAAAEAAAAA24AAAQAAAAEAAAABAAAAAQAAAAEAP/9A24AAAQAAAADWAAAAyQAAANuAAADbgAAA24AAAQAAAADtgAAAbYAAAQAAAAEAAAAA24AAANuAAADbgAAA24AAAQAAAAEAAAABAAAAAQAAAAEAQAABAAAAAQAAAAEAAAAApH//wQA//0EAAAABAD//QQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAAA24AAAO2AAAEAAAAA7b//wMkAAADJAAAAyQAAAQAAAAEAAAAA24AAANuAAADtgAAA7YAAAMkAAADtv//BAAAAAQAAAADbgAABEkAAALbAAADtv//A7b//wQAAAACSQAAAkkAAAFuAAABbgAAAtsAAAQAAAAC2wAABAAAAAO2AAADbgAAA24AAAO2AAADtgAAA7YAAANHAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAADJAAAAtsAAAMkAAADbgAABAAAAANuAAADtv//A7b//wJJAAACSQAAAkkAAAQAAAAEAAAABAAAAAQAAAAESQAABEkAAAQAAAAEAAAAA24AAANuAAACSQAAAkkAAAKRAAACkQAAAW4AAAFuAAACkQAAApEAAARJAAADbgAAA7b//wO2//8EAAAAA24AAAQAAAADtv//BEkAAAO2AAAESQAABAAAAAMkAAACSQAAA7b//wJJAAABbgAAAW4AAAKR//8DJAAAA7b//wKR//8DJAAAANsAAANuAAADbgAAA24AAANuAAACSQAAAkkAAANuAAADtgAAA7YAAAQAAAAEAAAAA24AAANuAAABtgAAAbYAAAQAAAAEAAAABAAAAAUkAAADbgAAA24AAANuAAADbgAAA24AAANuAAADbgAAA24AAANuAAADbgAAA24AAANuAAADbgAABJEAAASRAAAEkQAAA24AAASR//8Ekf//BJH//wSR//8Ekf//BJEAAAQAAAADbgAAA24AAANuAAADbgAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAO2//8DbgAABAAAAAQAAAAEkf//BAAAAAQAAAAAAAAAAAoAFAAeAQgBbAHkAk4DIgP+BEIIOAj2CTQJjAosCkoKZAqCCqQK0Ar8CyoLZguaC9IMNAzEDPINnA4gDl4OfA6wDvoPGg84D2wP0hAGEFQQhBD0EfgSOBJ8Ep4TVhO4FBoUYBXAFioWbBaqFzAXdBfiGFAY1hmWGpYcAhx2HQIdih64IAQgZiFGIhQjcCRuJKwk3iU4JbwmBCYeJjgmuCc6J9IoKihsKJAo0ikCKbIqQiq2KxYr0Cw+LIws+i2gLeguWi6SLxgvoC/8MCAwRjBqMI4wvjDuMRwxTDGIMcQyADI8MqIzGjNgM8o0HjR6NMg1fjbONx43Xjd8OFg4zjlcOdQ6SjrEOwY7SDtyO+Q8VDywPcA+Aj5EPmg+jD8GP5A/+kBUQLRBFEFcQcxCZELCQxRDZkO4RApEOERmRJREwkUkRXJF8EZuRzJHXEe4SAxIiEjQSURJrkniSppLiEv+TFRMlE0ITZpOFk5gTrhPEE9QT5xP7FBEUPZRyFH+UnxS/FOWVDBUyFViVY5VulXoVhZWXFbcV2pYSljeWWxZ4FpIWuJbjlwGXLZdEF2SXeBejF8OX7JgXGB6YLphSmG2YlJi7GNaY/xkdmTkZXRmKGbCZ3poHmiSaWBqSGsga6Zr1Gv4bERspm0SAAEAAAD3As4ADwAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAOAK4AAQAAAAAAAQAMAAAAAQAAAAAAAgAHAI0AAQAAAAAAAwAMAEUAAQAAAAAABAAMAKIAAQAAAAAABQALACQAAQAAAAAABgAMAGkAAQAAAAAACgAaAMYAAwABBAkAAQAYAAwAAwABBAkAAgAOAJQAAwABBAkAAwAYAFEAAwABBAkABAAYAK4AAwABBAkABQAWAC8AAwABBAkABgAYAHUAAwABBAkACgA0AOB0aWNrNDItaWNvbnMAdABpAGMAawA0ADIALQBpAGMAbwBuAHNWZXJzaW9uIDEuMABWAGUAcgBzAGkAbwBuACAAMQAuADB0aWNrNDItaWNvbnMAdABpAGMAawA0ADIALQBpAGMAbwBuAHN0aWNrNDItaWNvbnMAdABpAGMAawA0ADIALQBpAGMAbwBuAHNSZWd1bGFyAFIAZQBnAHUAbABhAHJ0aWNrNDItaWNvbnMAdABpAGMAawA0ADIALQBpAGMAbwBuAHNGb250IGdlbmVyYXRlZCBieSBJY29Nb29uLgBGAG8AbgB0ACAAZwBlAG4AZQByAGEAdABlAGQAIABiAHkAIABJAGMAbwBNAG8AbwBuAC4AAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA) format("truetype")}[class^="icon-"],[class*=" icon-"]{font-weight:normal;font-family:"tick42-icons";font-style:normal;font-variant:normal;line-height:1;text-transform:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.tick42-custom-icon i{color:var(--t42-link-color)}.tick42-custom-icon img{display:block}.tick42-custom-icon.disabled i,.tick42-custom-icon:disabled i{color:var(--t42-content-color-disabled)}i.disabled,.disabled i{color:var(--t42-content-color-disabled)}.icon-size-12 i{font-size:0.75rem}.icon-size-12 i,.icon-size-12 img{width:0.75rem;height:0.75rem}.icon-size-14 i{font-size:0.875rem}.icon-size-14 i,.icon-size-14 img{width:0.875rem;height:0.875rem}.icon-size-24 i{font-size:1.5rem}.icon-size-24 i,.icon-size-24 img{width:1.5rem;height:1.5rem}.icon-size-16 i,.icon-size-16 img{width:1rem;height:1rem}.icon-size-16 i{font-size:1rem}.icon-size-32 i,.icon-size-32 img{width:2rem;height:2rem}.icon-size-32 i{font-size:2rem}.icon-size-48 i,.icon-size-48 img{width:3rem;height:3rem}.icon-size-48 i{font-size:3rem}.icon-size-64 i,.icon-size-64 img{width:4rem;height:4rem}.icon-size-64 i{font-size:4rem}.icon-size-80 i,.icon-size-80 img{width:5rem;height:5rem}.icon-size-80 i{font-size:5rem}.icon-size-96 i,.icon-size-96 img{width:6rem;height:6rem}.icon-size-96 i{font-size:6rem}.icon-size-112 i,.icon-size-112 img{width:7rem;height:7rem}.icon-size-112 i{font-size:7rem}.icon-size-128 i,.icon-size-128 img{width:8rem;height:8rem}.icon-size-128 i{font-size:8rem}.icon-primary i::before{color:#007be5}.icon-secondary i::before{color:#616161}.icon-success i::before{color:#43a047}.icon-info i::before{color:#469eb9}.icon-warning i::before{color:#f9a825}.icon-danger i::before{color:#ff511f}.icon-light i::before{color:#616161}.icon-dark i::before{color:#616161}.icon-dev-tools::before{content:"\e901"}.icon-interop::before{content:"\e900"}.icon-mail::before{content:"\e800"}.icon-attention::before{content:"\e801"}.icon-print::before{content:"\e802"}.icon-picture::before{content:"\e803"}.icon-thumbs-up::before{content:"\e804"}.icon-thumbs-down::before{content:"\e805"}.icon-lock::before{content:"\e806"}.icon-globe::before{content:"\e807"}.icon-calendar::before{content:"\e808"}.icon-location::before{content:"\e809"}.icon-briefcase::before{content:"\e80a"}.icon-export::before{content:"\e80b"}.icon-play::before{content:"\e80c"}.icon-stop::before{content:"\e80d"}.icon-record::before{content:"\e80e"}.icon-pause::before{content:"\e80f"}.icon-to-end::before{content:"\e810"}.icon-to-start::before{content:"\e811"}.icon-check::before{content:"\e812"}.icon-cancel::before{content:"\e813"}.icon-fast-forward::before{content:"\e814"}.icon-fast-backward::before{content:"\e815"}.icon-attention-circled::before{content:"\e816"}.icon-bell::before{content:"\e817"}.icon-chart-bar::before{content:"\e818"}.icon-phone::before{content:"\e819"}.icon-doc-add::before{content:"\e81a"}.icon-layout::before{content:"\e81b"}.icon-dot::before{content:"\e81c"}.icon-dot-2::before{content:"\e81d"}.icon-dot-3::before{content:"\e81e"}.icon-resize-full-1::before{content:"\e81f"}.icon-resize-small-1::before{content:"\e820"}.icon-checkbox::before{content:"\e821"}.icon-cancel-circled::before{content:"\e822"}.icon-03-context-viewer::before{content:"\e823"}.icon-volume-off-1::before{content:"\e824"}.icon-volume::before{content:"\e825"}.icon-headphones-1::before{content:"\e826"}.icon-performance-report::before{content:"\e827"}.icon-pause-1::before{content:"\e828"}.icon-volume-up-1::before{content:"\e829"}.icon-volume-down-1::before{content:"\e82a"}.icon-trash-empty::before{content:"\e839"}.icon-resize-small::before{content:"\e83b"}.icon-resize-full::before{content:"\e83c"}.icon-doc::before{content:"\e83d"}.icon-cog::before{content:"\e83e"}.icon-wrench::before{content:"\e83f"}.icon-resize-vertical::before{content:"\e840"}.icon-resize-horizontal::before{content:"\e841"}.icon-edit::before{content:"\e842"}.icon-pencil-1::before{content:"\e843"}.icon-cw-2::before{content:"\e844"}.icon-ccw-1::before{content:"\e845"}.icon-arrows-cw-1::before{content:"\e847"}.icon-th-large::before{content:"\e848"}.icon-th::before{content:"\e849"}.icon-spin5::before{content:"\e84a"}.icon-spin6::before{content:"\e84b"}.icon-spin4::before{content:"\e84c"}.icon-spin3::before{content:"\e84d"}.icon-spin2::before{content:"\e84e"}.icon-spin1::before{content:"\e84f"}.icon-pin::before{content:"\e850"}.icon-trading-controls::before{content:"\e856"}.icon-icon-coverage::before{content:"\e857"}.icon-taxes::before{content:"\e858"}.icon-credit::before{content:"\e859"}.icon-checkbox-checked::before{content:"\e85a"}.icon-checkbox-indeterminate::before{content:"\e85b"}.icon-radio::before{content:"\e85c"}.icon-radio-choose::before{content:"\e85d"}.icon-arrow-up-down::before{content:"\e85e"}.icon-arrow-double-left::before{content:"\e85f"}.icon-arrow-double-right::before{content:"\e860"}.icon-floppy::before{content:"\e861"}.icon-logout::before{content:"\e862"}.icon-mail-1::before{content:"\e864"}.icon-search-1::before{content:"\e865"}.icon-plus-1::before{content:"\e866"}.icon-minus-1::before{content:"\e867"}.icon-cancel-1::before{content:"\e868"}.icon-ok::before{content:"\e869"}.icon-th-list::before{content:"\e86a"}.icon-help-circled::before{content:"\e86b"}.icon-info-circled::before{content:"\e86c"}.icon-home::before{content:"\e86d"}.icon-link-1::before{content:"\e86e"}.icon-attach-1::before{content:"\e86f"}.icon-lock-open-1::before{content:"\e870"}.icon-eye::before{content:"\e871"}.icon-eye-off::before{content:"\e872"}.icon-tag::before{content:"\e873"}.icon-tags::before{content:"\e874"}.icon-bookmark::before{content:"\e875"}.icon-download-1::before{content:"\e876"}.icon-upload-1::before{content:"\e877"}.icon-forward-1::before{content:"\e878"}.icon-down-dir::before{content:"\e879"}.icon-up-dir::before{content:"\e87a"}.icon-left-dir::before{content:"\e87b"}.icon-right-dir::before{content:"\e87c"}.icon-left-open-1::before{content:"\e87d"}.icon-down-open-1::before{content:"\e87e"}.icon-right-open-1::before{content:"\e87f"}.icon-up-open-1::before{content:"\e880"}.icon-down-big::before{content:"\e881"}.icon-left-big::before{content:"\e882"}.icon-right-big::before{content:"\e883"}.icon-up-big::before{content:"\e884"}.icon-asterisk::before{content:"\e885"}.icon-check-1::before{content:"\e886"}.icon-tick42-icon-monochrome::before{content:"\e887"}.icon-task-manager::before{content:"\e888"}.icon-context-viewer::before{content:"\e889"}.icon-help-2::before{content:"\e88a"}.icon-star-empty-1::before{content:"\e88b"}.icon-star-full::before{content:"\e902"}.icon-move::before{content:"\f047"}.icon-link-ext::before{content:"\f08e"}.icon-check-empty::before{content:"\f096"}.icon-bookmark-empty::before{content:"\f097"}.icon-filter::before{content:"\f0b0"}.icon-resize-full-alt::before{content:"\f0b2"}.icon-docs::before{content:"\f0c5"}.icon-menu-1::before{content:"\f0c9"}.icon-table::before{content:"\f0ce"}.icon-columns::before{content:"\f0db"}.icon-sort::before{content:"\f0dc"}.icon-sort-down::before{content:"\f0dd"}.icon-sort-up::before{content:"\f0de"}.icon-mail-alt::before{content:"\f0e0"}.icon-sitemap::before{content:"\f0e8"}.icon-paste::before{content:"\f0ea"}.icon-exchange::before{content:"\f0ec"}.icon-download-cloud::before{content:"\f0ed"}.icon-upload-cloud::before{content:"\f0ee"}.icon-suitcase-1::before{content:"\f0f2"}.icon-bell-alt::before{content:"\f0f3"}.icon-doc-text-1::before{content:"\f0f6"}.icon-plus-squared::before{content:"\f0fe"}.icon-angle-double-left::before{content:"\f100"}.icon-angle-double-right::before{content:"\f101"}.icon-angle-double-up::before{content:"\f102"}.icon-angle-double-down::before{content:"\f103"}.icon-angle-left::before{content:"\f104"}.icon-angle-right::before{content:"\f105"}.icon-angle-up::before{content:"\f106"}.icon-angle-down::before{content:"\f107"}.icon-laptop::before{content:"\f109"}.icon-circle-empty::before{content:"\f10c"}.icon-quote-left::before{content:"\f10d"}.icon-quote-right::before{content:"\f10e"}.icon-spinner::before{content:"\f110"}.icon-circle::before{content:"\f111"}.icon-reply-1::before{content:"\f112"}.icon-folder-empty::before{content:"\f114"}.icon-folder-open-empty::before{content:"\f115"}.icon-terminal::before{content:"\f120"}.icon-code::before{content:"\f121"}.icon-reply-all-1::before{content:"\f122"}.icon-direction::before{content:"\f124"}.icon-fork::before{content:"\f126"}.icon-unlink::before{content:"\f127"}.icon-help::before{content:"\f128"}.icon-info::before{content:"\f129"}.icon-attention-alt::before{content:"\f12a"}.icon-mic::before{content:"\f130"}.icon-mute::before{content:"\f131"}.icon-calendar-empty::before{content:"\f133"}.icon-lock-open-alt::before{content:"\f13e"}.icon-ellipsis::before{content:"\f141"}.icon-ellipsis-vert::before{content:"\f142"}.icon-minus-squared::before{content:"\f146"}.icon-ok-squared::before{content:"\f14a"}.icon-link-ext-alt::before{content:"\f14c"}.icon-expand-right::before{content:"\f152"}.icon-euro::before{content:"\f153"}.icon-dollar::before{content:"\f155"}.icon-doc-inv::before{content:"\f15b"}.icon-sort-name-up::before{content:"\f15d"}.icon-sort-name-down::before{content:"\f15e"}.icon-sort-alt-up::before{content:"\f160"}.icon-sort-alt-down::before{content:"\f161"}.icon-sort-number-up::before{content:"\f162"}.icon-sort-number-down::before{content:"\f163"}.icon-down::before{content:"\f175"}.icon-up::before{content:"\f176"}.icon-left::before{content:"\f177"}.icon-right::before{content:"\f178"}.icon-cube::before{content:"\f1b2"}.icon-cubes::before{content:"\f1b3"}.icon-database::before{content:"\f1c0"}.icon-file-pdf::before{content:"\f1c1"}.icon-file-word::before{content:"\f1c2"}.icon-file-excel::before{content:"\f1c3"}.icon-file-powerpoint::before{content:"\f1c4"}.icon-file-image::before{content:"\f1c5"}.icon-file-archive::before{content:"\f1c6"}.icon-file-audio::before{content:"\f1c7"}.icon-file-video::before{content:"\f1c8"}.icon-file-code::before{content:"\f1c9"}.icon-circle-thin::before{content:"\f1db"}.icon-sliders::before{content:"\f1de"}.icon-share::before{content:"\f1e0"}.icon-wifi::before{content:"\f1eb"}.icon-bell-off::before{content:"\f1f6"}.icon-bell-off-empty::before{content:"\f1f7"}.icon-copyright::before{content:"\f1f9"}.icon-chart-area::before{content:"\f1fe"}.icon-chart-line::before{content:"\f201"}.icon-toggle-off::before{content:"\f204"}.icon-toggle-on::before{content:"\f205"}.icon-user-plus::before{content:"\f234"}.icon-user-times::before{content:"\f235"}.icon-clone::before{content:"\f24d"}.icon-hourglass-o::before{content:"\f250"}.icon-hourglass-1::before{content:"\f251"}.icon-hourglass-2::before{content:"\f252"}.icon-hourglass-3::before{content:"\f253"}.icon-calendar-plus-o::before{content:"\f271"}.icon-calendar-minus-o::before{content:"\f272"}.icon-calendar-times-o::before{content:"\f273"}.icon-calendar-check-o::before{content:"\f274"}.icon-hashtag::before{content:"\f292"}.icon-low-vision::before{content:"\f2a8"}.icon-envelope-open-o::before{content:"\f2b7"}.icon-address-book-o::before{content:"\f2ba"}.icon-user-o::before{content:"\f2c0"}.icon-window-maximize::before{content:"\f2d0"}.icon-window-minimize::before{content:"\f2d1"}.icon-window-restore::before{content:"\f2d2"}.icon-window-close::before{content:"\f2d3"}.icon-window-close-o::before{content:"\f2d4"}.icon-app::before{content:"\e903"}.icon-download-arrow::before{content:"\e904"}.icon-logo::before{content:"\e905"}.icon-feedback::before{content:"\e906"}.icon-action::before{content:"\e907"}.icon-swimlane::before{content:"\e908"}div.ag-dnd-ghost{border-color:transparent;border-radius:0.25rem;color:var(--white);font-size:0.75rem;font-family:inherit;line-height:inherit;background-color:var(--primary);cursor:default}div .ag-dnd-ghost-icon{display:flex;float:none;padding:0 0.25rem 0 0}div .ag-dnd-ghost-icon .ag-icon{background-color:var(--white)}.ag-tick42{padding-top:0}.ag-tick42 a{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border;border-bottom:0.063rem dashed var(--dark);color:var(--t42-content-color)}.ag-tick42 a:hover{text-decoration:none}.ag-tick42 .ag-filter-body{margin:0}.ag-tick42 input{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border;padding:0 0.5rem;border:var(--t42-border);color:var(--t42-content-color);line-height:2rem;background-color:var(--t42-input-bg)}.ag-tick42 input:focus{border-color:var(--primary);outline:0}.ag-tick42 input.ag-column-name-filter{margin-left:0.5rem}.ag-tick42 .ag-input-wrapper{padding:0.25rem}.ag-tick42 .ag-input-wrapper.ag-checkbox-input-wrapper{padding:0}.ag-tick42 .ag-cell-wrapper.ag-row-group{align-items:center}.ag-tick42 .ag-cell{padding:0 0.25rem;border-bottom:var(--t42-border);line-height:1.875rem;white-space:nowrap;text-overflow:ellipsis}.ag-tick42 .ag-cell .btn,.ag-tick42 .ag-cell .btn-sm,.ag-tick42 .ag-cell .btn-group-sm>.btn,.ag-tick42 .ag-cell .btn-lg,.ag-tick42 .ag-cell .btn-group-lg>.btn{line-height:1.25rem}.ag-tick42 .ag-cell .btn-icon i{position:relative;top:0.0625rem}.ag-tick42 .ag-cell:focus{outline:1px solid var(--primary)}.ag-tick42 .ag-cell .dropdown-toggle{width:20px;height:20px;margin-top:-3px;padding:0;border:0;line-height:22px}.ag-tick42 .ag-cell .dropdown-toggle::after{background-color:transparent;content:""}.ag-tick42 .ag-row::before{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:width;position:absolute;top:0;bottom:0;left:0;z-index:1;width:0;background-color:var(--primary);content:""}.ag-tick42 .ag-row.ag-row-selected{color:var(--t42-link-color);background-color:var(--t42-color-opacity-10)}.ag-tick42 .ag-row.ag-row-selected .ag-icon{color:var(--t42-link-color)}.ag-tick42 .ag-pinned-left-header,.ag-tick42 .ag-pinned-left-cols-container,.ag-tick42 .ag-pinned-right-header,.ag-tick42 .ag-pinned-right-cols-container{background-color:Rgb(var(--t42-bg-mid))}.ag-tick42 .ag-pinned-left-cols-container .ag-row-selected::before,.ag-tick42 .ag-pinned-left-cols-container.ag-hidden+.ag-center-cols-clipper .ag-row-selected::before{width:2px}.ag-tick42 .ag-row-hover{background-color:var(--t42-color-opacity-10)}.ag-tick42 .ag-row-hover .ag-cell{color:var(--t42-link-color)}.ag-tick42 .ag-row-hover .ag-loading .ag-icon-loading::after{background:Rgb(var(--t42-bg-light))}.ag-tick42 .ag-row-hover a{border-bottom-color:var(--t42-content-color);color:var(--t42-link-color)}.ag-tick42 .ag-row-hover a:hover{border-bottom-style:solid}.ag-tick42 .ag-header-row:last-of-type{border-bottom:var(--t42-border)}.ag-tick42 .ag-header-cell,.ag-tick42 .ag-header-group-cell{padding:0 0.25rem;border-top:var(--t42-border);border-left:var(--t42-border);color:Hsl(var(--t42-content-color-base), calc(var(--t42-content-color-l) - 20%))}.ag-tick42 .ag-header-cell:first-of-type,.ag-tick42 .ag-header-group-cell:first-of-type{border-left:0}.ag-tick42 .ag-header-cell .ag-header-cell-label,.ag-tick42 .ag-header-cell .ag-header-group-cell-label,.ag-tick42 .ag-header-group-cell .ag-header-cell-label,.ag-tick42 .ag-header-group-cell .ag-header-group-cell-label{font-weight:normal;font-size:83.3%;line-height:1.875rem;text-transform:uppercase}.ag-tick42 .ag-header-cell .ag-header-select-all,.ag-tick42 .ag-header-group-cell .ag-header-select-all{margin-right:0.5rem}.ag-tick42 .ag-header-cell-moving{background-color:Hsl(var(--t42-bg-light-base), calc(var(--t42-bg-light-l) + 5%))}.ag-tick42 .ag-cell-inline-editing{padding-top:0}.ag-tick42 .ag-cell-edit-input{border-top:0;border-bottom:0;border-radius:0}.ag-tick42 .ag-icon{font-family:inherit}.ag-tick42 .ag-icon::before{content:""}.ag-tick42 .ag-react-container .btn-icon{margin-bottom:0.125rem;padding:0 0.5rem}.ag-tick42 .ag-tabs-header{display:flex;height:1.875rem;border-bottom:var(--t42-border);border-bottom-width:0.063rem}.ag-tick42 .ag-tabs-header .ag-tab{display:flex;align-items:center;justify-content:center;width:1.875rem;height:1.875rem;color:var(--primary);cursor:pointer}.ag-tick42 .ag-tabs-header .ag-tab.ag-tab-selected{background-color:var(--primary)}.ag-tick42 .ag-tabs-header .ag-tab.ag-tab-selected .ag-icon{background-color:var(--white)}.ag-tick42 .ag-tabs-body{max-height:280px;overflow:auto}.ag-tick42 .ag-menu,.ag-tick42 .ag-tool-panel{z-index:1040;border:var(--t42-border);border-radius:0;overflow:initial;background-color:rgba(var(--t42-bg-light), 0.75);box-shadow:var(--t42-shadow);backdrop-filter:var(--backdrop-filter)}.ag-tick42 .ag-menu .ag-column-select-column,.ag-tick42 .ag-menu .ag-column-select-column-group,.ag-tick42 .ag-tool-panel .ag-column-select-column,.ag-tick42 .ag-tool-panel .ag-column-select-column-group{display:flex;align-items:center;margin-left:0;line-height:2rem;cursor:pointer}.ag-tick42 .ag-menu .ag-column-select-column .ag-column-select-checkbox:hover,.ag-tick42 .ag-menu .ag-column-select-column-group .ag-column-select-checkbox:hover,.ag-tick42 .ag-tool-panel .ag-column-select-column .ag-column-select-checkbox:hover,.ag-tick42 .ag-tool-panel .ag-column-select-column-group .ag-column-select-checkbox:hover{color:var(--t42-link-color)}.ag-tick42 .ag-menu .ag-column-select-column:hover,.ag-tick42 .ag-menu .ag-column-select-column-group:hover,.ag-tick42 .ag-tool-panel .ag-column-select-column:hover,.ag-tick42 .ag-tool-panel .ag-column-select-column-group:hover{color:Hsl(var(--t42-content--base), 100%);background-color:var(--t42-color-opacity-10)}.ag-tick42 .ag-menu .ag-column-select-header,.ag-tick42 .ag-tool-panel .ag-column-select-header{padding:0.5rem}.ag-tick42 .ag-menu .ag-column-select-column-label,.ag-tick42 .ag-tool-panel .ag-column-select-column-label{margin-left:0.25rem}.ag-tick42 .ag-tab-body{max-height:220px;overflow:auto}.ag-tick42 .ag-tab-body .ag-set-filter-list{height:9rem}.ag-tick42 .ag-tab-body input{border:var(--t42-border)}.ag-tick42 .ag-tab-body input:focus{border-color:var(--primary)}.ag-tick42 .ag-menu-option{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:color;line-height:2rem;cursor:pointer}.ag-tick42 .ag-menu-option .ag-menu-option-icon{color:var(--t42-content-color)}.ag-tick42 .ag-menu-option .ag-menu-option-icon,.ag-tick42 .ag-menu-option .ag-menu-option-popup-pointer{width:2rem;color:var(--t42-content-color);text-align:center}.ag-tick42 .ag-menu-option .ag-menu-option-icon.ag-menu-option-popup-pointer,.ag-tick42 .ag-menu-option .ag-menu-option-icon:hover,.ag-tick42 .ag-menu-option .ag-menu-option-popup-pointer.ag-menu-option-popup-pointer,.ag-tick42 .ag-menu-option .ag-menu-option-popup-pointer:hover{color:var(--t42-content-color)}.ag-tick42 .ag-menu-option .ag-menu-option-icon.ag-menu-option-popup-pointer .ag-icon,.ag-tick42 .ag-menu-option .ag-menu-option-icon:hover .ag-icon,.ag-tick42 .ag-menu-option .ag-menu-option-popup-pointer.ag-menu-option-popup-pointer .ag-icon,.ag-tick42 .ag-menu-option .ag-menu-option-popup-pointer:hover .ag-icon{color:var(--t42-content-color)}.ag-tick42 .ag-menu-option.ag-menu-option-active{color:var(--t42-link-color);background-color:var(--t42-color-opacity-10)}.ag-tick42 .ag-menu-option.ag-menu-option-active .ag-icon{color:var(--t42-content-color)}.ag-tick42 .ag-menu-separator{border-bottom:var(--t42-border);border-bottom-color:var(--t42-color-opacity-10)}.ag-tick42 .ag-menu-column-select-wrapper,.ag-tick42 .ag-primary-cols-list-panel{height:auto}.ag-tick42 .ag-tool-panel .ag-pivot-mode{padding-top:0.5rem}.ag-tick42 .ag-column-tool-panel-column{padding:0 0.25rem}.ag-tick42 .ag-column-tool-panel-column .ag-icon{margin:0 0.25rem}.ag-tick42 .ag-column-tool-panel-column-label,.ag-tick42 span.ag-column-tool-panel-column-group{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;padding-left:0.25rem}.ag-tick42 .ag-column-tool-panel-column-group .ag-icon{margin:0 0.25rem 0 0}.ag-tick42 .ag-root+.ag-tool-panel{box-shadow:none}.ag-tick42 .ag-row-group-leaf-indent{margin-left:24px}.ag-tick42 .ag-group-expanded,.ag-tick42 .ag-group-contracted{display:flex;align-items:center;min-width:0.75rem;height:100%;margin-right:0.5rem}.ag-tick42 .ag-group-value .ag-react-container{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;display:inline;font-size:87.5%}.ag-tick42 .ag-popup-editor{box-shadow:var(--t42-shadow)}.ag-tick42 .ag-rich-select{border:var(--t42-border);border-radius:0;overflow-y:auto;background-color:Rgb(var(--t42-bg-light), 1)}.ag-tick42 .ag-rich-select-row{padding-left:0.75rem}.ag-tick42 .ag-rich-select-row-selected{background:var(--t42-color-opacity-10)}.ag-tick42 .ag-rich-select-value{position:relative;height:2rem;padding-left:0.75rem;border-bottom:var(--t42-border);line-height:2rem}.ag-tick42 .ag-rich-select-value::before{position:absolute;top:0;bottom:0;left:0;width:3px;background-color:var(--primary);content:""}.ag-tick42 .icon-window-maximize::before,.ag-tick42 .icon-window-minimize::before,.ag-tick42 .icon-window-ok::before{font-size:0.813rem}.ag-tick42 .ag-column-drop{border-top:var(--t42-border)}.ag-tick42 .ag-column-drop.ag-column-drop-horizontal{display:flex;height:1.875rem}.ag-tick42 .ag-column-drop.ag-column-drop-horizontal div{display:flex;align-items:center}.ag-tick42 .ag-column-drop.ag-column-drop-horizontal div:first-of-type{margin-right:0.25rem}.ag-tick42 .ag-column-drop .ag-column-drop-empty-message{align-self:center}.ag-tick42 .ag-column-drop .ag-column-drop-cell{display:flex;height:1.125rem;margin:0.125rem 0.25rem;padding:0 0.125rem 0 0.25rem;border-radius:0.25rem;background-color:Rgb(var(--t42-bg-light))}.ag-tick42 .ag-column-drop .ag-column-drop-cell .ag-column-drop-cell-text{padding:0 0.25rem;line-height:1.125rem}.ag-tick42 .ag-column-drop.ag-column-drop-vertical div{justify-content:start}.ag-tick42 .ag-column-drop.ag-column-drop-vertical .ag-icon-group{margin:0 0.25rem}.ag-tick42 .ag-right-arrow{width:1.5rem;padding:0 0.25rem;overflow:hidden;text-indent:-999px;background-color:var(--t42-content-color);transform:rotate(-90deg);-webkit-mask-image:var(--t42-select-indicator)}.ag-tick42 .ag-right-arrow::before{position:absolute;text-indent:999px}.ag-tick42 .ag-group-checkbox{display:flex;align-items:center;width:1rem;height:100%;margin-right:0.5rem}.ag-tick42 .ag-group-checkbox .ag-icon{width:0.875rem;height:0.875rem}.ag-tick42 .ag-group-checkbox:empty{width:initial}.ag-tick42 .ag-ltr .ag-toolpanel-indent-1{padding-left:1rem}.ag-tick42 .ag-ltr .ag-toolpanel-indent-2{padding-left:2rem}.ag-tick42 .ag-ltr .ag-toolpanel-indent-3{padding-left:3rem}.ag-tick42 .ag-ltr .ag-row-group-indent-1{padding-left:calc(1 * 1.45rem)}.ag-tick42 .ag-ltr .ag-row-group-indent-2{padding-left:calc(2 * 1.45rem)}.ag-tick42 .ag-ltr .ag-row-group-indent-3{padding-left:calc(3 * 1.45rem)}.ag-menu .ag-filter-checkbox{min-width:2rem}.ag-menu .ag-icon-checkbox-checked::after{width:0.625rem;height:0.625rem}.ag-menu .ag-column-group-icons{width:1.5rem}.ag-menu .ag-labeled.ag-label-align-right>div{margin-left:0.25rem}.ag-filter-panel{width:100%}.loading-filter{background-color:rgba(var(--t42-bg-light), 0.75);backdrop-filter:var(--backdrop-filter)}#selectAllContainer,.ag-set-filter-item{display:flex;align-items:center;cursor:pointer}#selectAllContainer .ag-filter-value,#selectAllContainer .ag-set-filter-item-value,.ag-set-filter-item .ag-filter-value,.ag-set-filter-item .ag-set-filter-item-value{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}#selectAllContainer .ag-set-filter-item-value,.ag-set-filter-item .ag-set-filter-item-value{margin-left:0.25rem}.ag-filter-checkbox{justify-content:center;min-width:2rem;color:var(--primary)}.ag-set-filter-item:hover,.ag-filter-header-container:hover label{color:var(--t42-link-color);background-color:var(--t42-color-opacity-10)}.ag-set-filter-item:hover .ag-icon,.ag-filter-header-container:hover label .ag-icon{color:var(--t42-link-color)}.ag-input-text-wrapper{padding:0.25rem 0.25rem 0}.ag-primary-cols-header-panel{align-items:center;padding:0.25rem 0.25rem 0.25rem 0}.ag-primary-cols-header-panel div:nth-child(1){width:1.25rem}.ag-primary-cols-header-panel div:nth-child(2){width:1rem;margin-right:0.25rem}.ag-filter-toolpanel-header{display:flex}.ag-filter-toolpanel-header .ag-header-cell-text{padding:0 0.25rem}.ag-filter-condition{justify-content:space-evenly;padding:0.5rem 0}.ag-filter-condition .ag-labeled.ag-label-align-right div{margin-left:0}.ag-radio-button-label{position:relative;color:var(--t42-content-color-muted);cursor:pointer;user-select:none}.ag-radio-button-input-wrapper::before{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, border;position:absolute;left:-1.125rem;display:block;width:0.875rem;height:0.875rem;border:0.0625rem solid var(--t42-content-color-muted);border-radius:50%;cursor:pointer;content:"";pointer-events:all}.ag-radio-button-input-wrapper::after{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, border;position:absolute;left:-0.875rem;display:block;width:0.375rem;height:0.375rem;border-radius:50%;color:var(--white);background-image:none;transform:scale(0);opacity:0;content:""}.ag-radio-button-input-wrapper:focus{border-color:var(--primary)}.ag-radio-button-input-wrapper.ag-checked::before{border-color:var(--t42-color-opacity-30);background-color:var(--primary)}.ag-radio-button-input-wrapper.ag-checked::after{background-color:var(--white);transform:scale(1);opacity:1}.ag-list{z-index:1100;background-color:rgba(var(--t42-bg-mid), 0.7);backdrop-filter:var(--backdrop-filter)}.ag-list .ag-list-item{padding:0 0.5rem;line-height:2rem;cursor:pointer}.ag-list .ag-list-item:hover{background-color:Rgb(var(--t42-bg-light))}.ag-picker-field-wrapper{height:2rem;padding:0 0.5rem;line-height:2rem;cursor:pointer}.ag-column-select-header-icon{display:flex;align-items:center}.ag-column-select-header .ag-text-field-input{height:1.875rem;line-height:1.875rem}.ag-filter-list-panel .ag-filter-toolpanel-expand{margin:0 0.25rem}.ag-filter-list-panel .ag-filter-toolpanel-group-container,.ag-filter-list-panel .ag-filter-toolpanel-instance-filter{padding-left:0.25rem}.ag-side-bar{position:relative}.ag-side-bar .ag-side-bar-right .ag-tool-panel-horizontal-resize{left:-0.375rem}.ag-side-bar>div:first-child{border:var(--t42-border);background-color:var(--t42-color-opacity-10)}.ag-side-bar .ag-pivot-mode-select{display:flex;padding:0.25rem;border-bottom:var(--t42-border)}.ag-side-bar .ag-pivot-mode-select label{margin:0 0 0 0.5rem}.ag-side-bar .ag-pivot-mode-select .ag-checkbox-label{padding-left:0.25rem}.ag-side-bar .ag-side-buttons div.ag-side-button button{width:1rem;height:1rem;padding:0;border:0.0625rem solid transparent;color:Hsl(var(--t42-content-color-base), 100%);background-color:transparent}.ag-side-bar .ag-side-buttons div.ag-side-button button:hover{color:Hsl(var(--t42-content-color-base), 100%);background-color:Rgb(var(--t42-bg-dark))}.ag-side-bar .ag-side-buttons div.ag-side-button button>span{display:none}.ag-side-bar .ag-side-buttons div.ag-side-button.ag-selected button{border-color:var(--t42-color-opacity-30);background-color:var(--primary)}.ag-side-bar .ag-side-buttons div.ag-side-button.ag-selected button [class*="ag-icon-"]{background-color:var(--white)}.ag-side-bar .ag-icon-checkbox-checked::after{width:0.625rem;height:0.625rem}.ag-side-bar .ag-column-panel,.ag-side-bar .ag-filter-panel{padding-left:0.25rem}.ag-side-bar .ag-filter-checkbox{margin-right:0.25rem}.ag-tool-panel-wrapper{border-top:var(--t42-border);border-bottom:var(--t42-border)}.ag-tool-panel-wrapper .ag-set-filter-list{width:100%;height:auto}.ag-tool-panel-wrapper .ag-column-select-checkbox,.ag-tool-panel-wrapper .ag-column-select-header-checkbox{margin:0 0.25rem}.ag-tool-panel-horizontal-resize{top:initial;width:0.188rem;background-color:var(--t42-color-opacity-10)}.ag-column-panel,.ag-column-select-panel,.ag-column-drop-vertical,.ag-column-drop-list{display:block;min-height:initial;max-height:initial;overflow:visible}.ag-column-panel input,.ag-column-select-panel input,.ag-column-drop-vertical input,.ag-column-drop-list input{border:var(--t42-border)}.ag-column-panel input:focus,.ag-column-select-panel input:focus,.ag-column-drop-vertical input:focus,.ag-column-drop-list input:focus{border-color:var(--primary)}[class*="ag-icon-"],.icon-check-1,.icon-check-empty,.icon-resize-horizontal{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:color, transform;display:block;width:0.75rem;height:0.75rem;margin:0 auto;background-color:var(--t42-content-color);background-image:none;mask-repeat:no-repeat;mask-position:center;cursor:pointer}[class*="ag-icon-"]:hover,.icon-check-1:hover,.icon-check-empty:hover,.icon-resize-horizontal:hover{background-color:var(--t42-link-color)}.ag-menu-option-disabled{color:var(--t42-content-color-disabled)}.ag-menu-option-disabled .ag-icon{background-color:var(--t42-content-color-disabled)}.ag-icon-menu{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M475.4,384v36.4c0,5.1-1.7,9.4-5.1,12.8s-7.9,5.3-13.3,5.6H55c-5.1,0-9.4-1.9-12.8-5.6c-3.4-3.8-5.3-8-5.6-12.8V384 c0-5.1,1.9-9.4,5.6-12.8c3.8-3.4,8-5.3,12.8-5.6h401.9c5.1,0,9.6,1.9,13.3,5.6C474,375,475.7,379.2,475.4,384z M475.4,237.6v36.9 c0,4.8-1.7,9-5.1,12.8s-7.9,5.5-13.3,5.1H55c-5.1,0-9.4-1.7-12.8-5.1s-5.3-7.7-5.6-12.8v-36.9c0-4.8,1.9-9,5.6-12.8 c3.8-3.8,8-5.5,12.8-5.1h401.9c5.1,0,9.6,1.7,13.3,5.1S475.7,232.5,475.4,237.6z M475.4,91.7V128c0,4.8-1.7,9-5.1,12.8 s-7.9,5.6-13.3,5.6H55c-5.1,0-9.4-1.9-12.8-5.6s-5.3-8-5.6-12.8V91.7c0-5.1,1.9-9.6,5.6-13.3c3.8-3.8,8-5.5,12.8-5.1h401.9 c5.1,0,9.6,1.7,13.3,5.1S475.7,86.2,475.4,91.7z%27/%3E%3C/svg%3E%0A")}.ag-header-icon{margin-left:0.125rem}.ag-header-icon .ag-icon-menu{line-height:1.875rem}.ag-icon-asc{-webkit-mask-image:var(--t42-select-indicator);transform:rotate(180deg)}.ag-icon-desc{-webkit-mask-image:var(--t42-select-indicator);margin-bottom:2px}.ag-icon-filter{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 16 16%27%3E%3Cpath d=%27M14.9,1.4c0.1,0.3,0.1,0.5-0.1,0.7L9.9,7v7.4c0,0.3-0.1,0.5-0.4,0.6C9.4,15,9.4,15,9.3,15c-0.2,0-0.3-0.1-0.4-0.2l-2.5-2.5 c-0.1-0.1-0.2-0.3-0.2-0.4V7L1.2,2.1C1,1.9,0.9,1.7,1.1,1.4C1.2,1.1,1.4,1,1.7,1h12.7C14.6,1,14.8,1.1,14.9,1.4L14.9,1.4z%27/%3E%3C/svg%3E")}.ag-icon-none{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 16 16%27%3E%3Cpath d=%27M1 6L5 2Q6 1 7 2L11 6Q11 7 10 7L2 7Q1 7 1 6M2 8Q1 8 1 9L5 13Q6 14 7 13L11 9Q11 8 10 8L2 8%27/%3E%3C/svg%3E%0A")}.ag-icon-indeterminate,.ag-icon-checkbox-indeterminate,.ag-icon-checkbox-indeterminate-readonly,.ag-icon-checkbox-unchecked,.ag-icon-checkbox-unchecked-readonly,.ag-icon-checkbox-checked-readonly,.ag-icon-checkbox-checked,.icon-check-1,.icon-check-empty,.ag-checkbox-input-wrapper,.ag-toggle-button-input-wrapper{position:relative;padding:0;color:var(--t42-content-color-muted);background-color:transparent;cursor:pointer;user-select:none}.ag-icon-indeterminate::before,.ag-icon-checkbox-indeterminate::before,.ag-icon-checkbox-indeterminate-readonly::before,.ag-icon-checkbox-unchecked::before,.ag-icon-checkbox-unchecked-readonly::before,.ag-icon-checkbox-checked-readonly::before,.ag-icon-checkbox-checked::before,.icon-check-1::before,.icon-check-empty::before,.ag-checkbox-input-wrapper::before,.ag-toggle-button-input-wrapper::before{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, border-color;display:block;width:100%;height:100%;border:var(--t42-border);border-color:var(--t42-content-color);cursor:pointer;content:"";pointer-events:all}.ag-icon-indeterminate:focus,.ag-icon-checkbox-indeterminate:focus,.ag-icon-checkbox-indeterminate-readonly:focus,.ag-icon-checkbox-unchecked:focus,.ag-icon-checkbox-unchecked-readonly:focus,.ag-icon-checkbox-checked-readonly:focus,.ag-icon-checkbox-checked:focus,.icon-check-1:focus,.icon-check-empty:focus,.ag-checkbox-input-wrapper:focus,.ag-toggle-button-input-wrapper:focus{border-color:var(--primary)}.ag-icon-indeterminate:hover,.ag-icon-checkbox-indeterminate:hover,.ag-icon-checkbox-indeterminate-readonly:hover,.ag-icon-checkbox-unchecked:hover,.ag-icon-checkbox-unchecked-readonly:hover,.ag-icon-checkbox-checked-readonly:hover,.ag-icon-checkbox-checked:hover,.icon-check-1:hover,.icon-check-empty:hover,.ag-checkbox-input-wrapper:hover,.ag-toggle-button-input-wrapper:hover{background-color:transparent}.ag-icon-checkbox-indeterminate,.ag-icon-checkbox-indeterminate-readonly,.ag-icon-checkbox-checked,.ag-icon-checkbox-checked-readonly,.icon-check-empty,.ag-checkbox-input-wrapper.ag-indeterminate,.ag-checkbox-input-wrapper.ag-checked,.ag-toggle-button-input-wrapper.ag-checked{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background, color}.ag-icon-checkbox-indeterminate::before,.ag-icon-checkbox-indeterminate-readonly::before,.ag-icon-checkbox-checked::before,.ag-icon-checkbox-checked-readonly::before,.icon-check-empty::before,.ag-checkbox-input-wrapper.ag-indeterminate::before,.ag-checkbox-input-wrapper.ag-checked::before,.ag-toggle-button-input-wrapper.ag-checked::before{border:0.0625rem solid var(--t42-color-opacity-30);background:var(--primary)}.ag-icon-checkbox-indeterminate::after,.ag-icon-checkbox-indeterminate-readonly::after,.ag-icon-checkbox-checked::after,.ag-icon-checkbox-checked-readonly::after,.icon-check-empty::after,.ag-checkbox-input-wrapper.ag-indeterminate::after,.ag-checkbox-input-wrapper.ag-checked::after,.ag-toggle-button-input-wrapper.ag-checked::after{position:absolute;top:0.063rem;left:0.063rem;display:block;width:0.75rem;height:0.75rem;background:var(--white);content:""}.ag-icon-checkbox-checked::after,.ag-icon-checkbox-checked-readonly::after,.icon-check-empty::after,.ag-checkbox-input-wrapper.ag-checked::after,.ag-toggle-button-input-wrapper.ag-checked::after{-webkit-mask-image:url("data:image/svg+xml,%3Csvg version=%271.1%27 xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M477.44 152.832q0 11.264-8.192 19.456l-245.76 245.76q-8.192 7.68-19.456 7.68t-19.456-7.68l-142.336-142.336q-7.68-8.192-7.68-19.456t7.68-19.456l38.912-38.912q8.192-8.192 19.456-8.192t19.456 8.192l83.968 84.48 187.392-187.904q8.192-8.192 19.456-8.192t19.456 8.192l38.912 38.912q8.192 7.68 8.192 19.456z%27%3E%3C/path%3E%3C/svg%3E%0A")}.ag-icon-checkbox-indeterminate::after,.ag-icon-checkbox-indeterminate-readonly::after,.ag-checkbox-input-wrapper.ag-indeterminate::after{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 -1 5 6%27%3E%3Cpath d=%27M 1 1 A 1 1 0 0 0 1 2 L 4 2 A 1 1 0 0 0 4 1 L 1 1%27/%3E%3C/svg%3E%0A")}.ag-checkbox-input-wrapper.ag-indeterminate::after{top:0.125rem;left:0.125rem}.ag-checkbox-input-wrapper::before,.ag-toggle-button-input-wrapper::before{width:0.875rem;height:0.875rem}.ag-checkbox-input-wrapper .ag-checkbox-input,.ag-checkbox-input-wrapper .ag-toggle-button-input,.ag-toggle-button-input-wrapper .ag-checkbox-input,.ag-toggle-button-input-wrapper .ag-toggle-button-input{position:absolute;z-index:2;width:0.875rem;height:0.875rem}.ag-icon-columns{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M146.432 374.784v55.296q0 11.264-8.192 18.944t-19.456 8.192h-91.136q-11.776 0-19.456-8.192t-8.192-18.944v-55.296q0-11.264 8.192-19.456t19.456-7.68h91.136q11.776 0 19.456 7.68t8.192 19.456zM146.432 228.864v54.784q0 11.264-8.192 19.456t-19.456 7.68h-91.136q-11.776 0-19.456-7.68t-8.192-19.456v-54.784q0-11.776 8.192-19.456t19.456-8.192h91.136q11.776 0 19.456 8.192t8.192 19.456zM329.216 374.784v55.296q0 11.264-8.192 18.944t-19.456 8.192h-91.136q-11.776 0-19.456-8.192t-8.192-18.944v-55.296q0-11.264 8.192-19.456t19.456-7.68h91.136q11.776 0 19.456 7.68t8.192 19.456zM146.432 82.432v54.784q0 11.264-8.192 19.456t-19.456 8.192h-91.136q-11.776 0-19.456-8.192t-8.192-19.456v-54.784q0-11.264 8.192-19.456t19.456-8.192h91.136q11.776 0 19.456 8.192t8.192 19.456zM329.216 228.864v54.784q0 11.264-8.192 19.456t-19.456 7.68h-91.136q-11.776 0-19.456-7.68t-8.192-19.456v-54.784q0-11.776 8.192-19.456t19.456-8.192h91.136q11.776 0 19.456 8.192t8.192 19.456zM512 374.784v55.296q0 11.264-8.192 18.944t-19.456 8.192h-91.136q-11.264 0-19.456-8.192t-8.192-18.944v-55.296q0-11.264 8.192-19.456t19.456-7.68h91.136q11.776 0 19.456 7.68t8.192 19.456zM329.216 82.432v54.784q0 11.264-8.192 19.456t-19.456 8.192h-91.136q-11.776 0-19.456-8.192t-8.192-19.456v-54.784q0-11.264 8.192-19.456t19.456-8.192h91.136q11.776 0 19.456 8.192t8.192 19.456zM512 228.864v54.784q0 11.264-8.192 19.456t-19.456 7.68h-91.136q-11.264 0-19.456-7.68t-8.192-19.456v-54.784q0-11.776 8.192-19.456t19.456-8.192h91.136q11.776 0 19.456 8.192t8.192 19.456zM512 82.432v54.784q0 11.264-8.192 19.456t-19.456 8.192h-91.136q-11.264 0-19.456-8.192t-8.192-19.456v-54.784q0-11.264 8.192-19.456t19.456-8.192h91.136q11.776 0 19.456 8.192t8.192 19.456z%27%3E%3C/path%3E%3C/svg%3E")}.ag-icon-pin{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M228.4,228.6v-128c0-2.7-0.9-4.9-2.6-6.7s-3.9-2.6-6.7-2.6c-2.7,0-4.9,0.9-6.7,2.6c-1.7,1.7-2.6,3.9-2.6,6.7v128 c0,2.7,0.9,4.9,2.6,6.7c1.7,1.7,3.9,2.6,6.7,2.6c2.7,0,4.9-0.9,6.7-2.6S228.4,231.3,228.4,228.6z M420.4,329.5c0,4.8-1.9,9-5.6,12.8 c-3.8,3.8-8,5.5-12.8,5.1H279.6l-14.8,138.2c-0.3,2.4-1.4,4.3-3.1,5.6c-1.7,1.4-3.6,2.2-5.6,2.6h-0.5c-5.1,0-8-2.6-8.7-7.7 l-22-138.8H109.6c-5.1,0-9.4-1.7-12.8-5.1c-3.4-3.4-5.3-7.7-5.6-12.8c0-23.6,7.5-44.7,22.5-63.5s31.9-28.2,50.7-28.2V91.4 c-9.9,0-18.4-3.6-25.6-10.8c-7.2-7.2-10.9-15.7-11.3-25.6s3.4-18.4,11.3-25.6c7.9-7.2,16.4-10.9,25.6-11.3h182.8 c9.9,0,18.4,3.8,25.6,11.3s10.8,16,10.8,25.6s-3.6,18.1-10.8,25.6S357,91.7,347.1,91.4v146.4c18.8,0,35.7,9.4,50.7,28.2 C412.8,284.8,420.4,305.9,420.4,329.5L420.4,329.5z%27/%3E%3C/svg%3E")}.ag-icon-small-right,.ag-icon-small-down{width:0.65rem;height:0.65rem;-webkit-mask-image:var(--t42-select-indicator);transform:rotate(-90deg)}.ag-icon-small-down{transform:rotate(0)}.ag-icon-tick{-webkit-mask-image:url("data:image/svg+xml,%3Csvg version=%271.1%27 xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M477.44 152.832q0 11.264-8.192 19.456l-245.76 245.76q-8.192 7.68-19.456 7.68t-19.456-7.68l-142.336-142.336q-7.68-8.192-7.68-19.456t7.68-19.456l38.912-38.912q8.192-8.192 19.456-8.192t19.456 8.192l83.968 84.48 187.392-187.904q8.192-8.192 19.456-8.192t19.456 8.192l38.912 38.912q8.192 7.68 8.192 19.456z%27%3E%3C/path%3E%3C/svg%3E%0A")}.ag-icon-copy{-webkit-mask-image:url("data:image/svg+xml,")}.ag-icon-csv,.ag-icon-excel{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M0 0zq0-7.7-5.1-12.8zM475.3 356.6v91.6q0 11.3-8.2 18.9t-19.5 8.2h-420.4q-11.8 0-19.5-8.2t-8.2-18.9v-91.6q0-11.3 8.2-19.5t19.5-8.2h132.6l38.4 38.9q16.9 16.4 38.9 16.4t38.9-16.4l38.9-38.9h132.6q11.3 0 19.5 8.2t8.2 19.5zM382.1 193.8q5.1 11.8-4.1 20l-128 128q-5.1 5.6-12.8 5.6t-12.8-5.6l-128-128q-8.7-8.2-4.1-20q5.1-10.8 16.9-10.8h73.2v-128q0-7.7 5.6-12.8t12.8-5.6h73.2q7.2 0 12.8 5.6t5.1 12.8v128h73.2q12.3 0 16.9 10.8M347 439A1 1 0 00347 402A1 1 0 00347 439M420 439A1 1 0 00420 402A1 1 0 00420 439zz%27/%3E%3C/svg%3E%0A")}.ag-icon-expanded{-webkit-mask-image:var(--t42-select-indicator);transform:rotate(-90deg)}.ag-icon-contracted{-webkit-mask-image:var(--t42-select-indicator);transform:rotate(90deg)}.ag-header-expand-icon-collapsed .ag-icon-contracted{margin-bottom:1px;transform:rotate(90deg);-webkit-mask-image:var(--t42-select-indicator)}.ag-icon-paste{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M219.648 475.648h256v-183.296h-119.296q-11.264 0-18.944-7.68t-8.192-19.456v-118.784h-109.568v329.216zM292.352 64v-18.432q0-3.584-2.56-6.144t-6.144-3.072h-201.216q-3.584 0-6.656 3.072t-2.56 6.144v18.432q0 3.584 2.56 6.656t6.656 2.56h201.216q3.584 0 6.144-2.56t2.56-6.656zM365.568 256h85.504l-85.504-85.504v85.504zM512 292.352v192q0 11.776-8.192 19.456t-19.456 8.192h-273.92q-11.776 0-19.456-8.192t-8.192-19.456v-45.568h-155.136q-11.776 0-19.456-8.192t-8.192-18.944v-384q0-11.776 8.192-19.456t19.456-8.192h310.784q11.264 0 19.456 8.192t7.68 19.456v93.696q6.144 3.584 10.24 7.68l116.736 116.736q8.192 7.68 13.824 21.504t5.632 25.088z%27%3E%3C/path%3E%3C/svg%3E%0A")}.ag-icon-arrows{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M512 256q0 7.168-5.632 12.8l-72.704 73.216q-5.632 5.632-13.312 5.632t-12.8-5.632-5.12-12.8v-36.864h-110.080v110.080h36.864q7.168 0 12.8 5.12t5.632 12.8-5.632 12.8l-73.216 73.216q-5.12 5.632-12.8 5.632t-12.8-5.632l-73.216-73.216q-5.632-5.12-5.632-12.8t5.632-12.8 12.8-5.12h36.864v-110.080h-110.080v36.864q0 7.168-5.12 12.8t-12.8 5.632-12.8-5.632l-73.216-73.216q-5.632-5.632-5.632-12.8t5.632-12.8l73.216-73.216q5.12-5.632 12.8-5.632t12.8 5.632 5.12 12.8v36.864h110.080v-110.080h-36.864q-7.168 0-12.8-5.12t-5.632-12.8 5.632-13.312l73.216-72.704q5.632-5.632 12.8-5.632t12.8 5.632l73.216 72.704q5.632 5.632 5.632 13.312t-5.632 12.8-12.8 5.12h-36.864v110.080h110.080v-36.864q0-7.168 5.12-12.8t12.8-5.632 13.312 5.632l72.704 73.216q5.632 5.12 5.632 12.8z%27%3E%3C/path%3E%3C/svg%3E%0A")}.ag-icon-not-allowed{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27m 182.8 238.1 h 145.9 v -55.3 c 0 -20.1 -7.2 -37.4 -21.5 -51.7 s -31.6 -21.3 -51.7 -21 c -20.1 0.3 -37.4 7.3 -51.7 21 s -21.3 30.9 -21 51.7 l -0 55.3 l 0 0 z m 237.6 27.1 v 164.9 c 0 7.5 -2.7 13.8 -8.2 18.9 s -11.9 7.9 -19.5 8.2 h -273.9 c -7.9 0 -14.3 -2.7 -19.5 -8.2 c -5.1 -5.5 -7.9 -11.8 -8.2 -18.9 v -164.9 c 0 -7.5 2.7 -14 8.2 -19.5 s 11.9 -8 19.5 -7.7 h 8.7 v -55.3 c 0 -34.8 12.6 -64.9 37.9 -90.1 s 55.3 -37.9 90.1 -37.9 s 65 12.6 90.6 37.9 s 38.1 55.3 37.4 90.1 v 55.3 h 9.2 c 7.9 0 14.3 2.6 19.5 7.7 s 7.8 11.7 8.2 19.5 z%27/%3E%3C/svg%3E")}.ag-icon-eye-slash{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M 475.6 256.3 q -43.5 -67.6 -109.1 -100.9 q 17.4 29.7 17.4 64 q 0 52.7 -37.4 90.6 t -90.6 37.4 t -90.6 -37.4 t -37.4 -90.6 q 0 -34.3 17.4 -64 q -65.5 33.3 -109.1 100.9 q 38.4 58.4 95.7 93.2 t 123.9 34.8 t 124.4 -34.8 t 95.2 -93.2 z M 269.8 146.2 q 0 -5.6 -4.1 -9.7 t -9.7 -3.6 q -35.8 0 -61.4 25.6 t -25.6 60.9 q 0 5.6 4.1 9.7 t 9.7 4.1 t 9.7 -4.1 t 4.1 -9.7 q 0 -24.6 17.4 -42 t 42 -17.4 q 5.6 0 9.7 -4.1 t 4.1 -9.7 z M 512 256.3 q 0 9.7 -5.6 19.5 q -39.9 66 -107.5 105.5 t -142.8 39.4 t -142.8 -39.4 t -107.5 -105.5 q -5.6 -9.7 -5.6 -19.5 t 5.6 -20 q 39.9 -65.5 107.5 -105 t 142.8 -39.9 t 142.8 39.9 t 107.5 105 q 5.6 10.2 5.6 20 z%27%3E%3C/path%3E%3C/svg%3E%0A")}.ag-icon-group{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M146.4 374.8v55.3q0 11.3-8.2 18.9t-19.5 8.2h-91.1q-11.8 0-19.5-8.2t-8.2-18.9v-55.3q0-11.3 8.2-19.5t19.5-7.7h91.1q11.8 0 19.5 7.7t8.2 19.5zM146.4 228.9v54.8q0 11.3-8.2 19.5t-19.5 7.7h-91.1q-11.8 0-19.5-7.7t-8.2-19.5v-54.8q0-11.8 8.2-19.5t19.5-8.2h91.1q11.8 0 19.5 8.2t8.2 19.5zM512 374.8v55.3q0 11.3-8.2 18.9t-19.5 8.2h-273.9q-11.8 0-19.5-8.2t-8.2-18.9v-55.3q0-11.3 8.2-19.5t19.5-7.7h273.9q11.8 0 19.5 7.7t8.2 19.5zM146.4 82.4v54.8q0 11.3-8.2 19.5t-19.5 8.2h-91.1q-11.8 0-19.5-8.2t-8.2-19.5v-54.8q0-11.3 8.2-19.5t19.5-8.2h91.1q11.8 0 19.5 8.2t8.2 19.5zM512 228.9v54.8q0 11.3-8.2 19.5t-19.5 7.7h-273.9q-11.8 0-19.5-7.7t-8.2-19.5v-54.8q0-11.8 8.2-19.5t19.5-8.2h273.9q11.8 0 19.5 8.2t8.2 19.5zM512 82.4v54.8q0 11.3-8.2 19.5t-19.5 8.2h-273.9q-11.8 0-19.5-8.2t-8.2-19.5v-54.8q0-11.3 8.2-19.5t19.5-8.2h273.9q11.8 0 19.5 8.2t8.2 19.5z%27%3E%3C/path%3E%3C/svg%3E%0A")}.ag-icon-grip{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 16 16%27%3E%3Cpath d=%27M4 3L6 3L6 5L4 5L4 3M4 7L6 7L6 9L4 9L4 7M4 11L6 11L6 13L4 13L4 11M8 3L10 3L10 5L8 5L8 3M8 7L10 7L10 9L8 9L8 7M8 11L10 11L10 13L8 13L8 11%27/%3E%3C/svg%3E%0A");margin:0}.ag-icon-tree-open{-webkit-mask-image:var(--t42-select-indicator);transform:rotate(180deg)}.ag-icon-tree-closed{-webkit-mask-image:var(--t42-select-indicator);transform:rotate(270deg)}.ag-icon-tree-indeterminate{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 -1 5 6%27%3E%3Cpath d=%27M 1 1 A 1 1 0 0 0 1 2 L 4 2 A 1 1 0 0 0 4 1 L 1 1%27/%3E%3C/svg%3E%0A")}.ag-icon-save{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M 420.6 319.2 V 393 c 0 22.9 -8 42.3 -24.1 58.4 s -35.5 24.1 -58.4 24.1 H 100.6 c -22.9 0 -42.3 -8 -58.4 -24.1 S 18.2 415.8 18.2 393 V 155.4 c 0 -22.5 8 -41.8 24.1 -57.9 S 77.7 73.3 100.6 73 h 72.7 c 2.4 0 4.6 1 6.7 3.1 c 2 2 2.9 4.1 2.6 6.1 c 0 5.1 -2.6 8.2 -7.7 9.2 c -14.7 5.1 -27.3 10.9 -37.9 17.4 c -1.7 0.7 -3.2 1 -4.6 1 h -31.7 c -12.6 0 -23.4 4.4 -32.3 13.3 s -13.5 19.6 -13.8 32.3 V 393 c 0 12.6 4.6 23.4 13.8 32.3 c 9.2 8.9 20 13.5 32.3 13.8 h 237.6 c 12.6 0 23.4 -4.6 32.3 -13.8 c 8.9 -9.2 13.3 -20 13.3 -32.3 V 332 c 0 -3.8 1.7 -6.5 5.1 -8.2 c 5.5 -2.4 10.8 -6 15.9 -10.8 c 2.7 -3.1 6 -3.8 9.7 -2 C 418.6 312.7 420.6 315.5 420.6 319.2 L 420.6 319.2 z M 488.2 177.4 L 378.6 287 c -3.4 3.8 -7.7 5.6 -12.8 5.6 c -2.4 0 -4.8 -0.5 -7.2 -1.5 c -7.5 -3.1 -11.3 -8.7 -11.3 -16.9 v -54.8 h -45.6 c -61.8 0 -103.6 12.5 -125.4 37.4 c -22.5 26.3 -29.5 71.3 -21 135.2 c 0.7 4.4 -1.2 7.7 -5.6 9.7 c -1.7 0.3 -2.9 0.5 -3.6 0.5 c -3.1 0 -5.5 -1.2 -7.2 -3.6 c -2 -2.7 -4.1 -5.6 -6.1 -8.7 c -2 -3.1 -5.8 -9.7 -11.3 -20 c -5.5 -10.2 -10.2 -19.6 -14.3 -28.2 c -4.1 -8.5 -7.7 -19.5 -10.8 -32.8 c -3.1 -13.3 -4.8 -24.9 -5.1 -34.8 c 0 -9.2 0.3 -17.9 1 -26.1 c 0.7 -8.2 2 -16.7 4.1 -25.6 c 2 -8.9 4.6 -17.2 7.7 -25.1 c 3.1 -7.9 7.7 -15.5 13.8 -23 c 6.1 -7.5 12.6 -14.7 19.5 -21.5 s 15.7 -12.6 26.6 -17.4 c 10.9 -4.8 22.9 -9.4 35.8 -13.8 c 13 -4.4 28.2 -7.3 45.6 -8.7 s 36.2 -2.4 56.3 -3.1 h 45.6 V 55 c 0 -8.2 3.8 -13.8 11.3 -16.9 c 2.4 -1 4.8 -1.5 7.2 -1.5 c 4.8 0 9 1.9 12.8 5.6 l 109.6 109.6 c 3.8 3.4 5.6 7.7 5.6 12.8 S 491.9 174 488.2 177.4 L 488.2 177.4 z%27/%3E%3C/svg%3E")}.ag-tooltip{padding:0.125rem 0.5rem;border:0.0625rem solid var(--t42-color-opacity-10);border-radius:0.25rem;background:Rgb(var(--t42-bg-light));box-shadow:var(--t42-shadow)}.ag-icon-cancel{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M366.9 336.4c6.1 6.1 9.2 13.5 9.2 22s-3.1 15.9-9.2 22c-6.1 5.5-13.5 8.2-22 8.2c-8.5 0-15.9-2.7-22-8.2l-67.6-77.8l-67.6 77.8c-6.1 5.5-13.5 8.2-22 8.2c-8.5 0-15.9-2.7-22-8.2c-5.5-6.1-8.2-13.5-8.2-22s2.7-15.9 8.2-22l70.7-79.9l-70.7-80.9c-5.5-6.1-8.2-13.5-8.2-22c0-8.5 2.7-15.9 8.2-22c6.1-5.5 13.5-8.2 22-8.2c8.5 0 15.9 2.7 22 8.2l67.6 77.8l67.6-77.8c6.1-5.5 13.5-8.2 22-8.2c8.5 0 15.9 2.7 22 8.2c6.1 6.1 9.2 13.5 9.2 22c0 8.5-3.1 15.9-9.2 22l-70.7 80.9L366.9 336.4z%27/%3E%3C/svg%3E")}.icon-check-empty::after{width:0.65rem;height:0.65rem}.icon-resize-horizontal{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M512 256q0 7.2-5.6 12.8l-72.7 73.2q-5.6 5.6-13.3 5.6t-12.8-5.6t-5.1-12.8v-36.9h-292.9v36.9q0 7.2-5.1 12.8t-12.8 5.6t-12.8-5.6l-73.2-73.2q-5.6-5.6-5.6-12.8t5.6-12.8l73.2-73.2q5.1-5.6 12.8-5.6t12.8 5.6t5.1 12.8v36.9h292.9v-36.9q0-7.2 5.1-12.8t12.8-5.6t13.3 5.6l72.7 73.2q5.6 5.1 5.6 12.8z%27%3E%3C/path%3E%3C/svg%3E%0A")}.ag-icon-aggregation{margin:0 0.25rem;-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 16 16%27%3E%3Cpath d=%27M3.6,1.7c-0.2,0.7-0.9,1.1-1.5,1C1.5,2.6,1,2,1,1.3C1,0.7,1.5,0.1,2.1,0c0.4-0.1,0.7,0,1,0.2C3.4,0.4,3.6,0.7,3.7,1 c0.3,0,0.5,0.1,0.8,0.3C4.7,1.5,5,1.8,5.2,2.1c0.2,0.3,0.4,0.7,0.6,1c0.1,0.2,0.3,0.5,0.5,0.7c0.2,0.2,0.5,0.5,0.8,0.6 c0.1,0.1,0.3,0.1,0.5,0.1c0.6,0,2.3,0,2.9,0c0.4,0,0.7,0,1.1,0c0,0,0,0,0.1,0c0,0,0,0,0-0.1c0-0.1,0-0.2,0-0.3c0,0,0-0.1,0-0.1 c0-0.1,0.1-0.1,0.2-0.1c0.1,0,0.1,0,0.1,0.1c0.1,0,0.1,0.1,0.2,0.2c0.2,0.2,0.3,0.3,0.5,0.5C12.8,4.8,13,5,13.1,5.1c0,0,0,0,0,0 c0,0,0,0-0.1,0c-1.5,0-4.1,0-5.7,0C7.2,5.2,7,5.1,6.8,5C6.6,4.9,6.3,4.8,6.1,4.6C5.7,4.3,5.5,4,5.2,3.5C5,3.2,4.8,2.8,4.6,2.4 C4.4,2.2,4.3,2.1,4.1,1.9C4,1.8,3.9,1.7,3.8,1.7C3.7,1.7,3.7,1.7,3.6,1.7z%27/%3E%3Cpath d=%27M3.6,7.7c1,0,10.6,0,11,0c0.1,0,0.1,0,0.1,0.1C14.8,7.8,14.9,7.9,15,8c-0.1,0.1-0.2,0.2-0.3,0.3c0,0,0,0-0.1,0 c0,0,0,0-0.1,0c-3.3,0-7.7,0-10.9,0C3.5,8.8,3.2,9.1,2.8,9.3C2.5,9.4,2.2,9.4,2,9.3C1.4,9.1,1,8.6,1,8c0-0.7,0.5-1.2,1.1-1.3 c0.3-0.1,0.7,0,1,0.2C3.4,7.1,3.6,7.3,3.6,7.7z%27/%3E%3Cpath d=%27M13.1,10.9C13.1,10.9,13.1,10.9,13.1,10.9c-0.3,0.3-0.6,0.6-0.8,0.8c-0.1,0.1-0.2,0.2-0.3,0.3c0,0-0.1,0.1-0.1,0.1 c0,0-0.1,0-0.1,0c-0.1,0-0.1,0-0.2-0.1c0,0,0-0.1,0-0.1c0-0.1,0-0.2,0-0.3c0,0,0,0,0-0.1c-1,0-3.1,0-4.1,0c-0.1,0-0.3,0-0.4,0.1 c-0.3,0.1-0.5,0.2-0.7,0.4c-0.2,0.2-0.4,0.5-0.6,0.8c-0.2,0.4-0.4,0.7-0.7,1.1c-0.2,0.2-0.4,0.4-0.6,0.6c-0.1,0.1-0.3,0.2-0.4,0.3 c-0.1,0.1-0.3,0.2-0.4,0.2c0,0-0.1,0-0.1,0c-0.1,0.4-0.3,0.7-0.7,0.9C2.7,16,2.4,16,2.1,16C1.5,15.9,1,15.3,1,14.7 c0-0.7,0.5-1.2,1-1.3c0.3-0.1,0.7,0,1,0.2c0.3,0.2,0.5,0.5,0.6,0.8c0.1,0,0.2,0,0.2,0C4,14.2,4.1,14.1,4.2,14 c0.2-0.2,0.3-0.4,0.5-0.6c0.2-0.3,0.4-0.6,0.6-1c0.2-0.3,0.4-0.6,0.6-0.9c0.3-0.2,0.5-0.5,0.9-0.6c0.2-0.1,0.4-0.1,0.6-0.1 c0,0,0.1,0,0.1,0c0.6,0,2.4,0,3,0c0.8,0,1.7,0,2.5,0C13.1,10.9,13.1,10.9,13.1,10.9C13.1,10.9,13.1,10.9,13.1,10.9z%27/%3E%3Cpath d=%27M3.6,11.7c-0.1,0.4-0.3,0.7-0.7,0.9c-0.3,0.2-0.6,0.2-0.9,0.1C1.5,12.6,1,12.1,1,11.4c0-0.7,0.5-1.2,1.1-1.3 c0.3-0.1,0.7,0,1,0.2c0.3,0.2,0.5,0.5,0.6,0.8c0.1,0,0.1,0,0.2,0c0.2,0,0.3-0.1,0.4-0.2c0.2-0.1,0.4-0.3,0.5-0.4 C4.9,10.3,5,10.2,5,10.2C5.3,9.9,5.6,9.7,6,9.6c0.3-0.1,0.6-0.2,0.8-0.2c0.1,0,0.1,0,0.2,0c1.1,0,3.4,0,4.5,0c0.9,0,1.8,0,2.6,0 c0,0,0,0,0.1,0c0,0,0,0,0,0C14,9.6,13.8,9.8,13.6,10c-1.8,0-4.8,0-6.6,0c-0.3,0-0.6,0.1-0.9,0.2c-0.2,0.1-0.5,0.3-0.6,0.5 c-0.3,0.3-0.5,0.5-0.8,0.7c-0.2,0.1-0.4,0.2-0.6,0.3C3.9,11.7,3.8,11.7,3.6,11.7C3.7,11.7,3.7,11.7,3.6,11.7z%27/%3E%3Cpath d=%27M3.6,4.9C3.5,5.3,3.3,5.6,2.9,5.8C2.6,5.9,2.3,6,2,5.9C1.4,5.7,1,5.2,1,4.5c0-0.6,0.5-1.2,1.1-1.3c0.7-0.1,1.4,0.3,1.5,1 c0,0,0.1,0,0.1,0c0.3,0,0.5,0.1,0.7,0.3C4.7,4.7,5,4.9,5.2,5c0.1,0.1,0.2,0.2,0.4,0.4c0.3,0.3,0.6,0.5,1,0.5C6.7,6,6.9,6,7,6 c1.8,0,4.8,0,6.6,0c0.1,0.1,0.3,0.3,0.6,0.6c0,0,0,0,0,0c0,0,0,0,0,0c0,0,0,0-0.1,0c-2,0-5.1,0-7.1,0c-0.3,0-0.5,0-0.8-0.1 C6,6.5,5.7,6.4,5.5,6.2C5.3,6.1,5.1,5.9,5,5.8C4.8,5.5,4.5,5.3,4.2,5.1C4.1,5,3.9,4.9,3.6,4.9z%27/%3E%3C/svg%3E%0A")}.ag-icon-loading{position:relative;width:1rem;height:1rem;border-radius:50%;background:linear-gradient(to right, var(--t42-icon-color), Rgba(var(--t42-bg-dark) 42%));transform:translateZ(0);animation:icon-loading 1.4s infinite linear}.ag-icon-loading::before{position:absolute;top:0;left:0;width:50%;height:50%;border-radius:100% 0 0;background:var(--t42-icon-color);content:""}.ag-icon-loading::after{position:absolute;top:0;right:0;bottom:0;left:0;width:75%;height:75%;margin:auto;border-radius:50%;background:Rgb(var(--t42-bg-dark));content:""}.ag-loading{display:flex;padding-left:0.5rem}@keyframes icon-loading{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.search{position:relative}.search i{position:absolute;top:0.625rem;right:0.75rem;width:.75rem;height:.75rem;background-color:var(--t42-content-color);-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M328.9 219.4q0-52.7-37.4-90.1t-90.6-37.9t-90.6 37.9t-37.4 90.1t37.4 90.6t90.6 37.4t90.6-37.4t37.4-90.6zM475.3 457.5q0 14.8-11.3 25.6t-25.6 10.8q-15.4 0-25.6-10.8l-97.8-97.8q-51.2 35.3-114.2 35.3q-41 0-78.3-15.9t-64-43t-43-64t-15.9-78.3t15.9-77.8t43-64.5t64-43t78.3-15.9t78.3 15.9t64 43t43 64.5t15.9 77.8q0 63-35.3 114.2l97.8 97.8q10.8 10.8 10.8 26.1z%27%3E%3C/path%3E%3C/svg%3E%0A")}.search-results{position:absolute;top:33px;max-height:215px;overflow-y:auto}.search-results .list-group-item{white-space:nowrap}.select{position:relative;z-index:12;display:flex;align-items:center;justify-content:center;width:100%;height:2rem;list-style:none;cursor:pointer}.select input[type="radio"]{opacity:1}.select_expand{position:absolute;top:0;right:0;width:0;height:2rem}.select_expand::after{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:transform;position:absolute;top:50%;right:0;z-index:2;width:1rem;height:1rem;background:var(--t42-select-indicator) center center/1rem 1rem no-repeat;transform:translate(-65%, -55%);content:"";pointer-events:none}.select_expand:checked+.select_close_label+.select_options .select_label:hover{color:var(--t42-link-hover-color);background-color:var(--t42-link-active-bg)}.select_expand:checked::after{transform:translate(-65%, -55%) rotate(-180deg)}.select_expand_label{position:absolute;top:0;left:0;display:block;width:100%;height:2rem;margin-bottom:0;cursor:pointer}.select_close{display:none}.select_close_label{position:fixed;top:0;left:0;display:none;margin-bottom:0}.select_items{position:absolute;top:0;left:0;width:100%;min-height:2rem;border-color:var(--t42-color-opacity-10);border-style:solid;border-width:1px}.select_items:hover{border-color:var(--primary)}.select_input{display:none}.select_label{display:block;height:0;margin-bottom:0;padding-left:0.875rem;overflow:hidden;line-height:2rem;cursor:pointer;transition:all 200ms cubic-bezier(0.4, 0.25, 0.3, 1)}.select_label-placeholder{position:absolute;top:0;left:0;height:2rem;vertical-align:middle;background-color:transparent}.select_expand:checked+.select_close_label{display:block}.select_expand:checked+.select_close_label::before,.select_expand:checked+.select_close_label::after{display:none}.select_expand:checked+.select_close_label+.select_options .select_label{height:2rem}.select_expand:checked+.select_close_label+.select_options+.select_expand_label{display:none}.select_input:checked+.select_label{height:2rem}.select_option label{color:var(--t42-content-color)}.select_options{max-height:10rem;padding-left:0;overflow:auto;list-style:none}.dark{--t42-json-icons: url("data:image/svg+xml,%3C%3Fxml version=%271.0%27 encoding=%27UTF-8%27 standalone=%27no%27%3F%3E%3Csvg xmlns:dc=%27http://purl.org/dc/elements/1.1/%27 xmlns:cc=%27http://creativecommons.org/ns%23%27 xmlns:rdf=%27http://www.w3.org/1999/02/22-rdf-syntax-ns%23%27 xmlns:svg=%27http://www.w3.org/2000/svg%27 xmlns=%27http://www.w3.org/2000/svg%27 xmlns:sodipodi=%27http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd%27 xmlns:inkscape=%27http://www.inkscape.org/namespaces/inkscape%27 width=%27240%27 height=%27144%27 id=%27svg4136%27 version=%271.1%27 inkscape:version=%270.91 r13725%27 sodipodi:docname=%27jsoneditor-icons.svg%27%3E%3Ctitle id=%27title6512%27%3EJSON Editor Icons%3C/title%3E%3Crect id=%27svg_1-7%27 height=%2716%27 width=%2716%27 y=%273.999995%27 x=%2728.000006%27 style=%27fill:%23ff511f;%27 /%3E%3Crect x=%277%27 y=%2711%27 width=%2710%27 height=%272%27 id=%27svg_1-1%27 style=%27fill:%23ffffff;%27 /%3E%3Crect x=%2711%27 y=%277%27 width=%272%27 height=%2710%27 id=%27svg_1-1-1%27 style=%27fill:%23ffffff;%27 /%3E%3Cg id=%27g4299-3%27 transform=%27matrix%280.70710678,-0.70710678,0.70710678,0.70710678,19.029435,12.000001%29%27 style=%27%27%3E%3Crect x=%277%27 y=%2711%27 width=%2710%27 height=%272%27 id=%27svg_1-1-0%27 style=%27fill:%23ffffff;%27 /%3E%3Crect x=%2711%27 y=%277%27 width=%272%27 height=%2710%27 id=%27svg_1-1-1-9%27 style=%27fill:%23ffffff;%27 /%3E%3C/g%3E%3Crect height=%277%27 width=%277%27 y=%277%27 x=%2755%27 style=%27fill:%23ffffff;stroke-width:1;stroke:%23ffffff%27 /%3E%3Crect id=%27svg_1-7-5-7%27 height=%277%27 width=%277%27 y=%2710%27 x=%2758%27 style=%27fill:%23ffffff;stroke-width:1;stroke:%231d1d1d%27 /%3E%3Cg id=%27g4378%27%3E%3Crect style=%27fill:%23ffffff;%27 x=%27198%27 y=%2711%27 width=%278%27 height=%272%27 id=%27svg_1-7-5-3%27 /%3E%3Crect id=%27rect4374%27 height=%272%27 width=%2712%27 y=%277%27 x=%27198%27 style=%27fill:%23ffffff;%27 /%3E%3Crect id=%27rect4376%27 height=%272%27 width=%274%27 y=%2715%27 x=%27198%27 style=%27fill:%23ffffff;%27 /%3E%3C/g%3E%3Cg transform=%27matrix%281,0,0,-1,-23.999995,23.999995%29%27 id=%27g4383%27%3E%3Crect id=%27rect4385%27 height=%272%27 width=%278%27 y=%2711%27 x=%27198%27 style=%27fill:%23ffffff;%27 /%3E%3Crect style=%27fill:%23ffffff;%27 x=%27198%27 y=%277%27 width=%2712%27 height=%272%27 id=%27rect4387%27 /%3E%3Crect style=%27fill:%23ffffff;%27 x=%27198%27 y=%2715%27 width=%274%27 height=%272%27 id=%27rect4389%27 /%3E%3C/g%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 85.10447,6.0157384 -0.0156,1.4063 c 3.02669,-0.2402 0.33008,3.6507996 2.48438,4.5780996 -2.18694,1.0938 0.49191,4.9069 -2.45313,4.5781 l -0.0156,1.4219 c 5.70828,0.559 1.03264,-5.1005 4.70313,-5.2656 l 0,-1.4063 c -3.61303,-0.027 1.11893,-5.7069996 -4.70313,-5.3124996 z%27 id=%27path4351%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 82.78125,5.9984384 0.0156,1.4063 c -3.02668,-0.2402 -0.33007,3.6506996 -2.48437,4.5780996 2.18694,1.0938 -0.49192,4.9069 2.45312,4.5781 l 0.0156,1.4219 c -5.70827,0.559 -1.03263,-5.1004 -4.70312,-5.2656 l 0,-1.4063 c 3.61303,-0.027 -1.11894,-5.7070996 4.70312,-5.3124996 z%27 id=%27path4351-9%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 103.719,5.6719384 0,12.7187996 3.03125,0 0,-1.5313 -1.34375,0 0,-9.6249996 1.375,0 0,-1.5625 z%27 id=%27path2987%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 112.2185,5.6721984 0,12.7187996 -3.03125,0 0,-1.5313 1.34375,0 0,-9.6249996 -1.375,0 0,-1.5625 z%27 id=%27path2987-1%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27M133,6.4h-1.9l-4.8,11.2h1.8l1.1-2.9h5.7l1.1,2.9h1.8L133,6.4z M129.7,13.5l2.3-5.5l2.3,5.5L129.7,13.5z%27 id=%27path3780%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 156.47655,5.8917384 0,2.1797 0.46093,2.3983996 1.82813,0 0.39844,-2.3983996 0,-2.1797 z%27 id=%27path5008-2%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 152.51561,5.8906384 0,2.1797 0.46094,2.3983996 1.82812,0 0.39844,-2.3983996 0,-2.1797 z%27 id=%27path5008-2-8%27 /%3E%3Crect id=%27svg_1-7-2%27 height=%272%27 width=%2712%27 y=%2764%27 x=%2754%27 style=%27fill:%236e6e6e;%27 /%3E%3Crect id=%27svg_1-7-2-2%27 height=%273%27 width=%273%27 y=%2752%27 x=%2780%27 style=%27fill:%236e6e6e;%27 /%3E%3Crect style=%27fill:%236e6e6e;%27 x=%2785%27 y=%2752%27 width=%273%27 height=%273%27 id=%27rect4561%27 /%3E%3Crect style=%27fill:%236e6e6e;%27 x=%2780%27 y=%2758%27 width=%273%27 height=%273%27 id=%27rect4563%27 /%3E%3Crect id=%27rect4565%27 height=%273%27 width=%273%27 y=%2758%27 x=%2785%27 style=%27fill:%236e6e6e;%27 /%3E%3Crect id=%27rect4567%27 height=%273%27 width=%273%27 y=%2764%27 x=%2780%27 style=%27fill:%236e6e6e;%27 /%3E%3Crect style=%27fill:%236e6e6e;%27 x=%2785%27 y=%2764%27 width=%273%27 height=%273%27 id=%27rect4569%27 /%3E%3Ccircle style=%27opacity:1;fill:none;stroke:%236e6e6e;stroke-width:2;%27 id=%27path4571%27 cx=%27110.06081%27 cy=%2757.939209%27 r=%274.7438836%27 /%3E%3Crect style=%27fill:%236e6e6e;%27 x=%27116.64566%27 y=%27-31.79752%27 width=%274.229713%27 height=%276.4053884%27 id=%27rect4563-2%27 transform=%27matrix%280.70710678,0.70710678,-0.70710678,0.70710678,0,0%29%27 /%3E%3Cpath style=%27fill:%236e6e6e;fill-rule:evenodd;%27 d=%27M 125,56 138.77027,56.095 132,64 Z%27 id=%27path4613%27 /%3E%3Cpath id=%27path4615%27 d=%27M 149,64 162.77027,63.905 156,56 Z%27 style=%27fill:%236e6e6e;fill-rule:evenodd;%27 /%3E%3Crect style=%27fill:%236e6e6e;%27 x=%2754%27 y=%2753%27 width=%2712%27 height=%272%27 id=%27rect4638%27 /%3E%3Crect id=%27svg_1-7-2-24%27 height=%272%27 width=%2713%27 y=%27-56%27 x=%2753%27 style=%27fill:%236e6e6e;%27 transform=%27matrix%280,1,-1,0,0,0%29%27 /%3E%3Crect transform=%27matrix%280,1,-1,0,0,0%29%27 style=%27fill:%236e6e6e;%27 x=%2753%27 y=%27-66%27 width=%2713%27 height=%272%27 id=%27rect4657%27 /%3E%3Crect id=%27rect4659%27 height=%271%27 width=%2712%27 y=%2757%27 x=%2754%27 style=%27fill:%236e6e6e;%27 /%3E%3Crect style=%27fill:%23ffffff;%27 x=%2754%27 y=%2788%27 width=%2712%27 height=%272%27 id=%27rect4661%27 /%3E%3Crect style=%27fill:%23ffffff;%27 x=%2780%27 y=%2776%27 width=%273%27 height=%273%27 id=%27rect4663%27 /%3E%3Crect id=%27rect4665%27 height=%273%27 width=%273%27 y=%2776%27 x=%2785%27 style=%27fill:%23ffffff;%27 /%3E%3Crect id=%27rect4667%27 height=%273%27 width=%273%27 y=%2782%27 x=%2780%27 style=%27fill:%23ffffff;%27 /%3E%3Crect style=%27fill:%23ffffff;%27 x=%2785%27 y=%2782%27 width=%273%27 height=%273%27 id=%27rect4669%27 /%3E%3Crect style=%27fill:%23ffffff;%27 x=%2780%27 y=%2788%27 width=%273%27 height=%273%27 id=%27rect4671%27 /%3E%3Crect id=%27rect4673%27 height=%273%27 width=%273%27 y=%2788%27 x=%2785%27 style=%27fill:%23ffffff;%27 /%3E%3Ccircle r=%274.7438836%27 cy=%2781.939331%27 cx=%27110.06081%27 id=%27circle4675%27 style=%27opacity:1;fill:none;stroke:%23ffffff;stroke-width:2;%27 /%3E%3Crect transform=%27matrix%280.70710678,0.70710678,-0.70710678,0.70710678,0,0%29%27 id=%27rect4677%27 height=%276.4053884%27 width=%274.229713%27 y=%27-14.826816%27 x=%27133.6163%27 style=%27fill:%23ffffff;%27 /%3E%3Cpath id=%27path4679%27 d=%27m 125,80.000005 13.77027,0.09499 L 132,87.999992 Z%27 style=%27fill:%23ffffff;%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27M 149,88.0002 162.77027,87.9052 156,80.0002 Z%27 id=%27path4681%27 /%3E%3Crect id=%27rect4683%27 height=%272%27 width=%2712%27 y=%2777%27 x=%2754%27 style=%27fill:%23ffffff;%27 /%3E%3Crect transform=%27matrix%280,1,-1,0,0,0%29%27 style=%27fill:%23ffffff;%27 x=%2777%27 y=%27-56%27 width=%2713%27 height=%272%27 id=%27rect4685%27 /%3E%3Crect id=%27rect4687%27 height=%272%27 width=%2713%27 y=%27-66%27 x=%2777%27 style=%27fill:%23ffffff;%27 transform=%27matrix%280,1,-1,0,0,0%29%27 /%3E%3Crect style=%27fill:%23ffffff;%27 x=%2754%27 y=%2781%27 width=%2712%27 height=%271%27 id=%27rect4689%27 /%3E%3Crect id=%27rect4761-1%27 height=%272%27 width=%2716%27 y=%27101%27 x=%2776%27 style=%27fill:%23ffffff;%27 /%3E%3Crect id=%27rect4761-0%27 height=%272%27 width=%2716%27 y=%27105%27 x=%2776%27 style=%27fill:%23ffffff;%27 /%3E%3Crect id=%27rect4761-7%27 height=%272%27 width=%279%27 y=%27109%27 x=%2776%27 style=%27fill:%23ffffff;%27 /%3E%3Crect id=%27rect4761-1-1%27 height=%272%27 width=%2712%27 y=%27125%27 x=%2776%27 style=%27fill:%23ffffff;%27 /%3E%3Crect id=%27rect4761-1-1-4%27 height=%272%27 width=%2710%27 y=%27137%27 x=%2776%27 style=%27fill:%23ffffff;%27 /%3E%3Crect id=%27rect4761-1-1-4-4%27 height=%272%27 width=%2710%27 y=%27129%27 x=%2782%27 style=%27fill:%23ffffff;%27 /%3E%3Crect id=%27rect4761-1-1-4-4-3%27 height=%272%27 width=%279%27 y=%27133%27 x=%2782%27 style=%27fill:%23ffffff;%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 36.398438,100.0254 c -0.423362,-0.013 -0.846847,0.01 -1.265626,0.062 -1.656562,0.2196 -3.244567,0.9739 -4.507812,2.2266 L 29,100.5991 l -2.324219,7.7129 7.826172,-1.9062 -1.804687,-1.9063 c 1.597702,-1.5308 4.048706,-1.8453 5.984375,-0.7207 1.971162,1.1452 2.881954,3.3975 2.308593,5.5508 -0.573361,2.1533 -2.533865,3.6953 -4.830078,3.6953 l 0,3.0742 c 3.550756,0 6.710442,-2.4113 7.650391,-5.9414 0.939949,-3.5301 -0.618463,-7.2736 -3.710938,-9.0703 -1.159678,-0.6738 -2.431087,-1.0231 -3.701171,-1.0625 z%27 id=%27path4138%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 59.722656,99.9629 c -1.270084,0.039 -2.541493,0.3887 -3.701172,1.0625 -3.092475,1.7967 -4.650886,5.5402 -3.710937,9.0703 0.939949,3.5301 4.09768,5.9414 7.648437,5.9414 l 0,-3.0742 c -2.296214,0 -4.256717,-1.542 -4.830078,-3.6953 -0.573361,-2.1533 0.337432,-4.4056 2.308594,-5.5508 1.935731,-1.1246 4.38863,-0.8102 5.986326,0.7207 l -1.806638,1.9063 7.828128,1.9062 -2.32422,-7.7129 -1.62696,1.7168 c -1.26338,-1.2531 -2.848917,-2.0088 -4.505855,-2.2285 -0.418778,-0.055 -0.842263,-0.076 -1.265625,-0.062 z%27 id=%27path4138-1%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 10.5,100 0,2 -2.4999996,0 L 12,107 l 4,-5 -2.5,0 0,-2 -3,0 z%27 id=%27path3055-0-77%27 /%3E%3Cpath style=%27fill:none;stroke:%23ffffff;%27 d=%27m 4.9850574,108.015 14.0298856,-0.03%27 id=%27path5244-5-0-5%27 /%3E%3Cpath style=%27fill:none;stroke:%23ffffff;%27 d=%27m 4.9849874,132.015 14.0298866,-0.03%27 id=%27path5244-5-0-5-8%27 /%3E%3Cpath style=%27color:%23000000;fill:%236e6e6e;%27 d=%27m 36.398438,123.9629 c -0.423362,-0.013 -0.846847,0.01 -1.265626,0.062 -1.656562,0.2196 -3.244567,0.9739 -4.507812,2.2266 L 29,124.5366 l -2.324219,7.7129 7.826172,-1.9062 -1.804687,-1.9063 c 1.597702,-1.5308 4.048706,-1.8453 5.984375,-0.7207 1.971162,1.1453 2.881954,3.3975 2.308593,5.5508 -0.573361,2.1533 -2.533864,3.6953 -4.830078,3.6953 l 0,3.0742 c 3.550757,0 6.710442,-2.4093 7.650391,-5.9394 0.939949,-3.5301 -0.618463,-7.2756 -3.710938,-9.0723 -1.159678,-0.6737 -2.431087,-1.0231 -3.701171,-1.0625 z%27 id=%27path4138-12%27 /%3E%3Cpath style=%27color:%23000000;fill:%236e6e6e;%27 d=%27m 59.722656,123.9629 c -1.270084,0.039 -2.541493,0.3888 -3.701172,1.0625 -3.092475,1.7967 -4.650886,5.5422 -3.710937,9.0723 0.939949,3.5301 4.09768,5.9394 7.648437,5.9394 l 0,-3.0742 c -2.296214,0 -4.256717,-1.542 -4.830078,-3.6953 -0.573361,-2.1533 0.337432,-4.4055 2.308594,-5.5508 1.935731,-1.1246 4.38863,-0.8102 5.986326,0.7207 l -1.806638,1.9063 7.828128,1.9062 -2.32422,-7.7129 -1.62696,1.7168 c -1.26338,-1.2531 -2.848917,-2.0088 -4.505855,-2.2285 -0.418778,-0.055 -0.842263,-0.076 -1.265625,-0.062 z%27 id=%27path4138-1-3%27 /%3E%3Cpath id=%27path6191%27 d=%27m 10.5,116 0,-2 -2.4999996,0 L 12,109 l 4,5 -2.5,0 0,2 -3,0 z%27 style=%27fill:%23ffffff;stroke-width:1.96599996;%27 /%3E%3Cpath style=%27fill:%23ffffff;stroke-width:1.96599996;%27 d=%27m 10.5,129 0,-2 -2.4999996,0 L 12,122 l 4,5 -2.5,0 0,2 -3,0 z%27 id=%27path6193%27 /%3E%3Cpath id=%27path6195%27 d=%27m 10.5,135 0,2 -2.4999996,0 L 12,142 l 4,-5 -2.5,0 0,-2 -3,0 z%27 style=%27fill:%23ffffff;stroke-width:1.96599996;%27 /%3E%3Cpath sodipodi:type=%27star%27 style=%27fill:%236e6e6e;%27 id=%27path4500%27 sodipodi:sides=%273%27 sodipodi:cx=%2711.55581%27 sodipodi:cy=%2760.073242%27 sodipodi:r1=%275.1116104%27 sodipodi:r2=%272.5558052%27 sodipodi:arg1=%270%27 sodipodi:arg2=%271.0471976%27 inkscape:flatsided=%27false%27 inkscape:rounded=%270%27 inkscape:randomized=%270%27 d=%27m 16.66742,60.073242 -3.833708,2.213392 -3.8337072,2.213393 0,-4.426785 0,-4.426784 3.8337082,2.213392 z%27 inkscape:transform-center-x=%27-1.2779026%27 /%3E%3Cpath inkscape:transform-center-x=%271.277902%27 d=%27m -31.500004,60.073242 -3.833708,2.213392 -3.833707,2.213393 0,-4.426785 0,-4.426784 3.833707,2.213392 z%27 inkscape:randomized=%270%27 inkscape:rounded=%270%27 inkscape:flatsided=%27false%27 sodipodi:arg2=%271.0471976%27 sodipodi:arg1=%270%27 sodipodi:r2=%272.5558052%27 sodipodi:r1=%275.1116104%27 sodipodi:cy=%2760.073242%27 sodipodi:cx=%27-36.611614%27 sodipodi:sides=%273%27 id=%27path4502%27 style=%27fill:%236e6e6e;%27 sodipodi:type=%27star%27 transform=%27scale%28-1,1%29%27 /%3E%3Cpath d=%27m 16.66742,60.073212 -3.833708,2.213392 -3.8337072,2.213392 0,-4.426784 0,-4.426785 3.8337082,2.213392 z%27 inkscape:randomized=%270%27 inkscape:rounded=%270%27 inkscape:flatsided=%27false%27 sodipodi:arg2=%271.0471976%27 sodipodi:arg1=%270%27 sodipodi:r2=%272.5558052%27 sodipodi:r1=%275.1116104%27 sodipodi:cy=%2760.073212%27 sodipodi:cx=%2711.55581%27 sodipodi:sides=%273%27 id=%27path4504%27 style=%27fill:%236e6e6e;%27 sodipodi:type=%27star%27 transform=%27matrix%280,1,-1,0,72.0074,71.7877%29%27 inkscape:transform-center-y=%271.2779029%27 /%3E%3Cpath inkscape:transform-center-y=%27-1.2779026%27 transform=%27matrix%280,-1,-1,0,96,96%29%27 sodipodi:type=%27star%27 style=%27fill:%236e6e6e;%27 id=%27path4506%27 sodipodi:sides=%273%27 sodipodi:cx=%2711.55581%27 sodipodi:cy=%2760.073212%27 sodipodi:r1=%275.1116104%27 sodipodi:r2=%272.5558052%27 sodipodi:arg1=%270%27 sodipodi:arg2=%271.0471976%27 inkscape:flatsided=%27false%27 inkscape:rounded=%270%27 inkscape:randomized=%270%27 d=%27m 16.66742,60.073212 -3.833708,2.213392 -3.8337072,2.213392 0,-4.426784 0,-4.426785 3.8337082,2.213392 z%27 /%3E%3Cpath id=%27path4615-5%27 d=%27m 171.82574,65.174193 16.34854,0 -8.17427,-13.348454 z%27 style=%27fill:%23f9a825;fill-rule:evenodd;stroke:%23f9a825;stroke-width:2;%27 /%3E%3Cpath style=%27opacity:1;fill:%23ffffff;%27 d=%27m 179,55 0,6 2,0 0,-6%27 id=%27path4300%27 /%3E%3Cpath style=%27opacity:1;fill:%23ffffff;%27 d=%27m 179,62 0,2 2,0 0,-2%27 id=%27path4300-6%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27M 99.994369,113.0221 102,114.98353 l 7,-6.9558 3,0.97227 2,-1 1,-2 0,-3 -3,3 -3,-3 3,-3 -3,0 -2,1 -1,2 0.99437,3.0221 z%27 id=%27path4268%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 234,6 0,2 -5,5 0,5 -2,0 0,-5 -5,-5 0,-2%27 id=%27path3546%27 /%3E%3Cg transform=%27matrix%281.3333328,0,0,-1.5999992,-139.9999,127.19999%29%27 id=%27g4383-6%27%3E%3Crect id=%27rect4385-2%27 height=%271%27 width=%276%27 y=%2712.625005%27 x=%27198%27 style=%27fill:%23ffffff;stroke:%23000000;stroke-width:0%27 /%3E%3Crect style=%27fill:%23ffffff;stroke:%23000000;stroke-width:0%27 x=%27198%27 y=%2715.125007%27 width=%278%27 height=%271%27 id=%27rect4387-9%27 /%3E%3Crect style=%27fill:%23ffffff;stroke:%23000000;stroke-width:0%27 x=%27198%27 y=%277.6250024%27 width=%273%27 height=%271%27 id=%27rect4389-1-0%27 /%3E%3Crect style=%27fill:%23ffffff;stroke:%23000000;stroke-width:0%27 x=%27198%27 y=%2710.125004%27 width=%274%27 height=%271%27 id=%27rect4389-1-9%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 207.00001,16.375004 0,-5.625005 -2.25,0 3,-3.1250014 3,3.1250014 -2.25,0 0,5.625005 -1.5,0%27 id=%27path4402%27 /%3E%3C/g%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 164,100 0,3 -6,6 0,7 -4,0 0,-7 -6,-6 0,-3%27 id=%27path3546-2-2%27 /%3E%3Cpath id=%27path4402-5-7%27 d=%27m 15,41 0,-7 -4,0 0,3 -5,-4 5,-4 0,3 6,0 0,9%27 style=%27fill:%23ffffff;%27 /%3E%3C/svg%3E%0A")}.light{--t42-json-icons: url("data:image/svg+xml,%3C%3Fxml version=%271.0%27 encoding=%27UTF-8%27 standalone=%27no%27%3F%3E%3Csvg xmlns:dc=%27http://purl.org/dc/elements/1.1/%27 xmlns:cc=%27http://creativecommons.org/ns%23%27 xmlns:rdf=%27http://www.w3.org/1999/02/22-rdf-syntax-ns%23%27 xmlns:svg=%27http://www.w3.org/2000/svg%27 xmlns=%27http://www.w3.org/2000/svg%27 xmlns:sodipodi=%27http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd%27 xmlns:inkscape=%27http://www.inkscape.org/namespaces/inkscape%27 width=%27240%27 height=%27144%27 id=%27svg4136%27 version=%271.1%27 inkscape:version=%270.91 r13725%27 sodipodi:docname=%27jsoneditor-icons.svg%27%3E%3Ctitle id=%27title6512%27%3EJSON Editor Icons%3C/title%3E%3Crect id=%27svg_1-7%27 height=%2716%27 width=%2716%27 y=%273.999995%27 x=%2728.000006%27 style=%27fill:%23ff511f;%27 /%3E%3Crect x=%277%27 y=%2711%27 width=%2710%27 height=%272%27 id=%27svg_1-1%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect x=%2711%27 y=%277%27 width=%272%27 height=%2710%27 id=%27svg_1-1-1%27 style=%27fill:%230d0d0d;%27 /%3E%3Cg id=%27g4299-3%27 transform=%27matrix%280.70710678,-0.70710678,0.70710678,0.70710678,19.029435,12.000001%29%27 style=%27%27%3E%3Crect x=%277%27 y=%2711%27 width=%2710%27 height=%272%27 id=%27svg_1-1-0%27 style=%27fill:%23ffffff;%27 /%3E%3Crect x=%2711%27 y=%277%27 width=%272%27 height=%2710%27 id=%27svg_1-1-1-9%27 style=%27fill:%23ffffff;%27 /%3E%3C/g%3E%3Crect height=%277%27 width=%277%27 y=%277%27 x=%2755%27 style=%27fill:%230d0d0d;stroke-width:1;stroke:%230d0d0d%27 /%3E%3Crect id=%27svg_1-7-5-7%27 height=%277%27 width=%277%27 y=%2710%27 x=%2758%27 style=%27fill:%230d0d0d;stroke-width:1;stroke:%23ffffff%27 /%3E%3Cg id=%27g4378%27%3E%3Crect style=%27fill:%230d0d0d;%27 x=%27198%27 y=%2711%27 width=%278%27 height=%272%27 id=%27svg_1-7-5-3%27 /%3E%3Crect id=%27rect4374%27 height=%272%27 width=%2712%27 y=%277%27 x=%27198%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect id=%27rect4376%27 height=%272%27 width=%274%27 y=%2715%27 x=%27198%27 style=%27fill:%230d0d0d;%27 /%3E%3C/g%3E%3Cg transform=%27matrix%281,0,0,-1,-23.999995,23.999995%29%27 id=%27g4383%27%3E%3Crect id=%27rect4385%27 height=%272%27 width=%278%27 y=%2711%27 x=%27198%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect style=%27fill:%230d0d0d;%27 x=%27198%27 y=%277%27 width=%2712%27 height=%272%27 id=%27rect4387%27 /%3E%3Crect style=%27fill:%230d0d0d;%27 x=%27198%27 y=%2715%27 width=%274%27 height=%272%27 id=%27rect4389%27 /%3E%3C/g%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 85.10447,6.0157384 -0.0156,1.4063 c 3.02669,-0.2402 0.33008,3.6507996 2.48438,4.5780996 -2.18694,1.0938 0.49191,4.9069 -2.45313,4.5781 l -0.0156,1.4219 c 5.70828,0.559 1.03264,-5.1005 4.70313,-5.2656 l 0,-1.4063 c -3.61303,-0.027 1.11893,-5.7069996 -4.70313,-5.3124996 z%27 id=%27path4351%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 82.78125,5.9984384 0.0156,1.4063 c -3.02668,-0.2402 -0.33007,3.6506996 -2.48437,4.5780996 2.18694,1.0938 -0.49192,4.9069 2.45312,4.5781 l 0.0156,1.4219 c -5.70827,0.559 -1.03263,-5.1004 -4.70312,-5.2656 l 0,-1.4063 c 3.61303,-0.027 -1.11894,-5.7070996 4.70312,-5.3124996 z%27 id=%27path4351-9%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 103.719,5.6719384 0,12.7187996 3.03125,0 0,-1.5313 -1.34375,0 0,-9.6249996 1.375,0 0,-1.5625 z%27 id=%27path2987%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 112.2185,5.6721984 0,12.7187996 -3.03125,0 0,-1.5313 1.34375,0 0,-9.6249996 -1.375,0 0,-1.5625 z%27 id=%27path2987-1%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27M133,6.4h-1.9l-4.8,11.2h1.8l1.1-2.9h5.7l1.1,2.9h1.8L133,6.4z M129.7,13.5l2.3-5.5l2.3,5.5L129.7,13.5z%27 id=%27path3780%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 156.47655,5.8917384 0,2.1797 0.46093,2.3983996 1.82813,0 0.39844,-2.3983996 0,-2.1797 z%27 id=%27path5008-2%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 152.51561,5.8906384 0,2.1797 0.46094,2.3983996 1.82812,0 0.39844,-2.3983996 0,-2.1797 z%27 id=%27path5008-2-8%27 /%3E%3Crect id=%27svg_1-7-2%27 height=%272%27 width=%2712%27 y=%2764%27 x=%2754%27 style=%27fill:%236e6e6e;%27 /%3E%3Crect id=%27svg_1-7-2-2%27 height=%273%27 width=%273%27 y=%2752%27 x=%2780%27 style=%27fill:%236e6e6e;%27 /%3E%3Crect style=%27fill:%236e6e6e;%27 x=%2785%27 y=%2752%27 width=%273%27 height=%273%27 id=%27rect4561%27 /%3E%3Crect style=%27fill:%236e6e6e;%27 x=%2780%27 y=%2758%27 width=%273%27 height=%273%27 id=%27rect4563%27 /%3E%3Crect id=%27rect4565%27 height=%273%27 width=%273%27 y=%2758%27 x=%2785%27 style=%27fill:%236e6e6e;%27 /%3E%3Crect id=%27rect4567%27 height=%273%27 width=%273%27 y=%2764%27 x=%2780%27 style=%27fill:%236e6e6e;%27 /%3E%3Crect style=%27fill:%236e6e6e;%27 x=%2785%27 y=%2764%27 width=%273%27 height=%273%27 id=%27rect4569%27 /%3E%3Ccircle style=%27opacity:1;fill:none;stroke:%236e6e6e;stroke-width:2;%27 id=%27path4571%27 cx=%27110.06081%27 cy=%2757.939209%27 r=%274.7438836%27 /%3E%3Crect style=%27fill:%236e6e6e;%27 x=%27116.64566%27 y=%27-31.79752%27 width=%274.229713%27 height=%276.4053884%27 id=%27rect4563-2%27 transform=%27matrix%280.70710678,0.70710678,-0.70710678,0.70710678,0,0%29%27 /%3E%3Cpath style=%27fill:%236e6e6e;fill-rule:evenodd;%27 d=%27M 125,56 138.77027,56.095 132,64 Z%27 id=%27path4613%27 /%3E%3Cpath id=%27path4615%27 d=%27M 149,64 162.77027,63.905 156,56 Z%27 style=%27fill:%236e6e6e;fill-rule:evenodd;%27 /%3E%3Crect style=%27fill:%236e6e6e;%27 x=%2754%27 y=%2753%27 width=%2712%27 height=%272%27 id=%27rect4638%27 /%3E%3Crect id=%27svg_1-7-2-24%27 height=%272%27 width=%2713%27 y=%27-56%27 x=%2753%27 style=%27fill:%236e6e6e;%27 transform=%27matrix%280,1,-1,0,0,0%29%27 /%3E%3Crect transform=%27matrix%280,1,-1,0,0,0%29%27 style=%27fill:%236e6e6e;%27 x=%2753%27 y=%27-66%27 width=%2713%27 height=%272%27 id=%27rect4657%27 /%3E%3Crect id=%27rect4659%27 height=%271%27 width=%2712%27 y=%2757%27 x=%2754%27 style=%27fill:%236e6e6e;%27 /%3E%3Crect style=%27fill:%230d0d0d;%27 x=%2754%27 y=%2788%27 width=%2712%27 height=%272%27 id=%27rect4661%27 /%3E%3Crect style=%27fill:%230d0d0d;%27 x=%2780%27 y=%2776%27 width=%273%27 height=%273%27 id=%27rect4663%27 /%3E%3Crect id=%27rect4665%27 height=%273%27 width=%273%27 y=%2776%27 x=%2785%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect id=%27rect4667%27 height=%273%27 width=%273%27 y=%2782%27 x=%2780%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect style=%27fill:%230d0d0d;%27 x=%2785%27 y=%2782%27 width=%273%27 height=%273%27 id=%27rect4669%27 /%3E%3Crect style=%27fill:%230d0d0d;%27 x=%2780%27 y=%2788%27 width=%273%27 height=%273%27 id=%27rect4671%27 /%3E%3Crect id=%27rect4673%27 height=%273%27 width=%273%27 y=%2788%27 x=%2785%27 style=%27fill:%230d0d0d;%27 /%3E%3Ccircle r=%274.7438836%27 cy=%2781.939331%27 cx=%27110.06081%27 id=%27circle4675%27 style=%27opacity:1;fill:none;stroke:%230d0d0d;stroke-width:2;%27 /%3E%3Crect transform=%27matrix%280.70710678,0.70710678,-0.70710678,0.70710678,0,0%29%27 id=%27rect4677%27 height=%276.4053884%27 width=%274.229713%27 y=%27-14.826816%27 x=%27133.6163%27 style=%27fill:%230d0d0d;%27 /%3E%3Cpath id=%27path4679%27 d=%27m 125,80.000005 13.77027,0.09499 L 132,87.999992 Z%27 style=%27fill:%230d0d0d;%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27M 149,88.0002 162.77027,87.9052 156,80.0002 Z%27 id=%27path4681%27 /%3E%3Crect id=%27rect4683%27 height=%272%27 width=%2712%27 y=%2777%27 x=%2754%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect transform=%27matrix%280,1,-1,0,0,0%29%27 style=%27fill:%230d0d0d;%27 x=%2777%27 y=%27-56%27 width=%2713%27 height=%272%27 id=%27rect4685%27 /%3E%3Crect id=%27rect4687%27 height=%272%27 width=%2713%27 y=%27-66%27 x=%2777%27 style=%27fill:%230d0d0d;%27 transform=%27matrix%280,1,-1,0,0,0%29%27 /%3E%3Crect style=%27fill:%230d0d0d;%27 x=%2754%27 y=%2781%27 width=%2712%27 height=%271%27 id=%27rect4689%27 /%3E%3Crect id=%27rect4761-1%27 height=%272%27 width=%2716%27 y=%27101%27 x=%2776%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect id=%27rect4761-0%27 height=%272%27 width=%2716%27 y=%27105%27 x=%2776%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect id=%27rect4761-7%27 height=%272%27 width=%279%27 y=%27109%27 x=%2776%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect id=%27rect4761-1-1%27 height=%272%27 width=%2712%27 y=%27125%27 x=%2776%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect id=%27rect4761-1-1-4%27 height=%272%27 width=%2710%27 y=%27137%27 x=%2776%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect id=%27rect4761-1-1-4-4%27 height=%272%27 width=%2710%27 y=%27129%27 x=%2782%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect id=%27rect4761-1-1-4-4-3%27 height=%272%27 width=%279%27 y=%27133%27 x=%2782%27 style=%27fill:%230d0d0d;%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 36.398438,100.0254 c -0.423362,-0.013 -0.846847,0.01 -1.265626,0.062 -1.656562,0.2196 -3.244567,0.9739 -4.507812,2.2266 L 29,100.5991 l -2.324219,7.7129 7.826172,-1.9062 -1.804687,-1.9063 c 1.597702,-1.5308 4.048706,-1.8453 5.984375,-0.7207 1.971162,1.1452 2.881954,3.3975 2.308593,5.5508 -0.573361,2.1533 -2.533865,3.6953 -4.830078,3.6953 l 0,3.0742 c 3.550756,0 6.710442,-2.4113 7.650391,-5.9414 0.939949,-3.5301 -0.618463,-7.2736 -3.710938,-9.0703 -1.159678,-0.6738 -2.431087,-1.0231 -3.701171,-1.0625 z%27 id=%27path4138%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 59.722656,99.9629 c -1.270084,0.039 -2.541493,0.3887 -3.701172,1.0625 -3.092475,1.7967 -4.650886,5.5402 -3.710937,9.0703 0.939949,3.5301 4.09768,5.9414 7.648437,5.9414 l 0,-3.0742 c -2.296214,0 -4.256717,-1.542 -4.830078,-3.6953 -0.573361,-2.1533 0.337432,-4.4056 2.308594,-5.5508 1.935731,-1.1246 4.38863,-0.8102 5.986326,0.7207 l -1.806638,1.9063 7.828128,1.9062 -2.32422,-7.7129 -1.62696,1.7168 c -1.26338,-1.2531 -2.848917,-2.0088 -4.505855,-2.2285 -0.418778,-0.055 -0.842263,-0.076 -1.265625,-0.062 z%27 id=%27path4138-1%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 10.5,100 0,2 -2.4999996,0 L 12,107 l 4,-5 -2.5,0 0,-2 -3,0 z%27 id=%27path3055-0-77%27 /%3E%3Cpath style=%27fill:none;stroke:%230d0d0d;%27 d=%27m 4.9850574,108.015 14.0298856,-0.03%27 id=%27path5244-5-0-5%27 /%3E%3Cpath style=%27fill:none;stroke:%230d0d0d;%27 d=%27m 4.9849874,132.015 14.0298866,-0.03%27 id=%27path5244-5-0-5-8%27 /%3E%3Cpath style=%27color:%23000000;fill:%236e6e6e;%27 d=%27m 36.398438,123.9629 c -0.423362,-0.013 -0.846847,0.01 -1.265626,0.062 -1.656562,0.2196 -3.244567,0.9739 -4.507812,2.2266 L 29,124.5366 l -2.324219,7.7129 7.826172,-1.9062 -1.804687,-1.9063 c 1.597702,-1.5308 4.048706,-1.8453 5.984375,-0.7207 1.971162,1.1453 2.881954,3.3975 2.308593,5.5508 -0.573361,2.1533 -2.533864,3.6953 -4.830078,3.6953 l 0,3.0742 c 3.550757,0 6.710442,-2.4093 7.650391,-5.9394 0.939949,-3.5301 -0.618463,-7.2756 -3.710938,-9.0723 -1.159678,-0.6737 -2.431087,-1.0231 -3.701171,-1.0625 z%27 id=%27path4138-12%27 /%3E%3Cpath style=%27color:%23000000;fill:%236e6e6e;%27 d=%27m 59.722656,123.9629 c -1.270084,0.039 -2.541493,0.3888 -3.701172,1.0625 -3.092475,1.7967 -4.650886,5.5422 -3.710937,9.0723 0.939949,3.5301 4.09768,5.9394 7.648437,5.9394 l 0,-3.0742 c -2.296214,0 -4.256717,-1.542 -4.830078,-3.6953 -0.573361,-2.1533 0.337432,-4.4055 2.308594,-5.5508 1.935731,-1.1246 4.38863,-0.8102 5.986326,0.7207 l -1.806638,1.9063 7.828128,1.9062 -2.32422,-7.7129 -1.62696,1.7168 c -1.26338,-1.2531 -2.848917,-2.0088 -4.505855,-2.2285 -0.418778,-0.055 -0.842263,-0.076 -1.265625,-0.062 z%27 id=%27path4138-1-3%27 /%3E%3Cpath id=%27path6191%27 d=%27m 10.5,116 0,-2 -2.4999996,0 L 12,109 l 4,5 -2.5,0 0,2 -3,0 z%27 style=%27fill:%230d0d0d;stroke-width:2;%27 /%3E%3Cpath style=%27fill:%230d0d0d;stroke-width:2;%27 d=%27m 10.5,129 0,-2 -2.4999996,0 L 12,122 l 4,5 -2.5,0 0,2 -3,0 z%27 id=%27path6193%27 /%3E%3Cpath id=%27path6195%27 d=%27m 10.5,135 0,2 -2.4999996,0 L 12,142 l 4,-5 -2.5,0 0,-2 -3,0 z%27 style=%27fill:%230d0d0d;stroke-width:2;%27 /%3E%3Cpath sodipodi:type=%27star%27 style=%27fill:%236e6e6e;%27 id=%27path4500%27 sodipodi:sides=%273%27 sodipodi:cx=%2711.55581%27 sodipodi:cy=%2760.073242%27 sodipodi:r1=%275.1116104%27 sodipodi:r2=%272.5558052%27 sodipodi:arg1=%270%27 sodipodi:arg2=%271.0471976%27 inkscape:flatsided=%27false%27 inkscape:rounded=%270%27 inkscape:randomized=%270%27 d=%27m 16.66742,60.073242 -3.833708,2.213392 -3.8337072,2.213393 0,-4.426785 0,-4.426784 3.8337082,2.213392 z%27 inkscape:transform-center-x=%27-1.2779026%27 /%3E%3Cpath inkscape:transform-center-x=%271.277902%27 d=%27m -31.500004,60.073242 -3.833708,2.213392 -3.833707,2.213393 0,-4.426785 0,-4.426784 3.833707,2.213392 z%27 inkscape:randomized=%270%27 inkscape:rounded=%270%27 inkscape:flatsided=%27false%27 sodipodi:arg2=%271.0471976%27 sodipodi:arg1=%270%27 sodipodi:r2=%272.5558052%27 sodipodi:r1=%275.1116104%27 sodipodi:cy=%2760.073242%27 sodipodi:cx=%27-36.611614%27 sodipodi:sides=%273%27 id=%27path4502%27 style=%27fill:%236e6e6e;%27 sodipodi:type=%27star%27 transform=%27scale%28-1,1%29%27 /%3E%3Cpath d=%27m 16.66742,60.073212 -3.833708,2.213392 -3.8337072,2.213392 0,-4.426784 0,-4.426785 3.8337082,2.213392 z%27 inkscape:randomized=%270%27 inkscape:rounded=%270%27 inkscape:flatsided=%27false%27 sodipodi:arg2=%271.0471976%27 sodipodi:arg1=%270%27 sodipodi:r2=%272.5558052%27 sodipodi:r1=%275.1116104%27 sodipodi:cy=%2760.073212%27 sodipodi:cx=%2711.55581%27 sodipodi:sides=%273%27 id=%27path4504%27 style=%27fill:%236e6e6e;%27 sodipodi:type=%27star%27 transform=%27matrix%280,1,-1,0,72.0074,71.7877%29%27 inkscape:transform-center-y=%271.2779029%27 /%3E%3Cpath inkscape:transform-center-y=%27-1.2779026%27 transform=%27matrix%280,-1,-1,0,96,96%29%27 sodipodi:type=%27star%27 style=%27fill:%236e6e6e;%27 id=%27path4506%27 sodipodi:sides=%273%27 sodipodi:cx=%2711.55581%27 sodipodi:cy=%2760.073212%27 sodipodi:r1=%275.1116104%27 sodipodi:r2=%272.5558052%27 sodipodi:arg1=%270%27 sodipodi:arg2=%271.0471976%27 inkscape:flatsided=%27false%27 inkscape:rounded=%270%27 inkscape:randomized=%270%27 d=%27m 16.66742,60.073212 -3.833708,2.213392 -3.8337072,2.213392 0,-4.426784 0,-4.426785 3.8337082,2.213392 z%27 /%3E%3Cpath id=%27path4615-5%27 d=%27m 171.82574,65.174193 16.34854,0 -8.17427,-13.348454 z%27 style=%27fill:%23f9a825;fill-rule:evenodd;stroke:%23f9a825;stroke-width:2;%27 /%3E%3Cpath style=%27opacity:1;fill:%23ffffff;%27 d=%27m 179,55 0,6 2,0 0,-6%27 id=%27path4300%27 /%3E%3Cpath style=%27opacity:1;fill:%23ffffff;%27 d=%27m 179,62 0,2 2,0 0,-2%27 id=%27path4300-6%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27M 99.994369,113.0221 102,114.98353 l 7,-6.9558 3,0.97227 2,-1 1,-2 0,-3 -3,3 -3,-3 3,-3 -3,0 -2,1 -1,2 0.99437,3.0221 z%27 id=%27path4268%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 234,6 0,2 -5,5 0,5 -2,0 0,-5 -5,-5 0,-2%27 id=%27path3546%27 /%3E%3Cg transform=%27matrix%281.3333328,0,0,-1.5999992,-139.9999,127.19999%29%27 id=%27g4383-6%27%3E%3Crect id=%27rect4385-2%27 height=%271%27 width=%276%27 y=%2712.625005%27 x=%27198%27 style=%27fill:%230d0d0d;stroke:%23000000;stroke-width:0%27 /%3E%3Crect style=%27fill:%230d0d0d;stroke:%23000000;stroke-width:0%27 x=%27198%27 y=%2715.125007%27 width=%278%27 height=%271%27 id=%27rect4387-9%27 /%3E%3Crect style=%27fill:%230d0d0d;stroke:%23000000;stroke-width:0%27 x=%27198%27 y=%277.6250024%27 width=%273%27 height=%271%27 id=%27rect4389-1-0%27 /%3E%3Crect style=%27fill:%230d0d0d;stroke:%23000000;stroke-width:0%27 x=%27198%27 y=%2710.125004%27 width=%274%27 height=%271%27 id=%27rect4389-1-9%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 207.00001,16.375004 0,-5.625005 -2.25,0 3,-3.1250014 3,3.1250014 -2.25,0 0,5.625005 -1.5,0%27 id=%27path4402%27 /%3E%3C/g%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 164,100 0,3 -6,6 0,7 -4,0 0,-7 -6,-6 0,-3%27 id=%27path3546-2-2%27 /%3E%3Cpath id=%27path4402-5-7%27 d=%27m 15,41 0,-7 -4,0 0,3 -5,-4 5,-4 0,3 6,0 0,9%27 style=%27fill:%230d0d0d;%27 /%3E%3C/svg%3E%0A")}body{/*! + * Selectr 2.4.13 + * http://mobius.ovh/docs/selectr + * + * Released under the MIT license + */}body .jsoneditor,body .jsoneditor-modal{-webkit-text-size-adjust:none;text-size-adjust:none}body .jsoneditor input,body .jsoneditor input:not([type]),body .jsoneditor input[type="text"],body .jsoneditor input[type="search"],body .jsoneditor-modal input,body .jsoneditor-modal input:not([type]),body .jsoneditor-modal input[type="text"],body .jsoneditor-modal input[type="search"]{height:auto;border:inherit;box-shadow:none;font-size:inherit;box-sizing:inherit;padding:inherit;font-family:inherit;transition:none;line-height:inherit}body .jsoneditor input:focus,body .jsoneditor input:not([type]):focus,body .jsoneditor input[type="text"]:focus,body .jsoneditor input[type="search"]:focus,body .jsoneditor-modal input:focus,body .jsoneditor-modal input:not([type]):focus,body .jsoneditor-modal input[type="text"]:focus,body .jsoneditor-modal input[type="search"]:focus{border:inherit;box-shadow:inherit}body .jsoneditor textarea,body .jsoneditor-modal textarea{height:inherit}body .jsoneditor select,body .jsoneditor-modal select{display:inherit;height:inherit}body .jsoneditor label,body .jsoneditor-modal label{font-size:inherit;font-weight:inherit;color:inherit}body .jsoneditor table,body .jsoneditor-modal table{border-collapse:collapse;width:auto}body .jsoneditor td,body .jsoneditor th,body .jsoneditor-modal td,body .jsoneditor-modal th{padding:0;display:table-cell;text-align:left;vertical-align:inherit;border-radius:inherit}body .jsoneditor .autocomplete.dropdown{position:absolute;background:var(--t42-content-color);box-shadow:var(--t42-shadow);border:1px solid var(--t42-color-opacity-10);overflow-x:hidden;overflow-y:auto;cursor:default;margin:0;padding:5px;text-align:left;outline:0;font-family:var(--bs-font-monospace);font-size:var(--t42-font-size)}body .jsoneditor .autocomplete.dropdown .item{color:var(--t42-content-color)}body .jsoneditor .autocomplete.dropdown .item.hover{background-color:Rgb(var(--t42-bg-mid))}body .jsoneditor .autocomplete.hint{color:var(--t42-content-color);top:4px;left:4px}body .jsoneditor-contextmenu-root{position:relative;width:0;height:0}body .jsoneditor-contextmenu{position:absolute;box-sizing:content-box;z-index:2}body .jsoneditor-contextmenu .jsoneditor-menu{position:relative;left:0;top:0;width:128px;height:auto;background:var(--t42-content-color);border:1px solid var(--t42-color-opacity-10);box-shadow:var(--t42-shadow);list-style:none;margin:0;padding:0}body .jsoneditor-contextmenu .jsoneditor-menu button{position:relative;padding:0 8px 0 0;margin:0;width:128px;height:auto;border:none;cursor:pointer;color:var(--t42-content-color);background:transparent;font-size:var(--t42-font-size);font-family:var(--t42-font-family);box-sizing:border-box;text-align:left}body .jsoneditor-contextmenu .jsoneditor-menu button::-moz-focus-inner{padding:0;border:0}body .jsoneditor-contextmenu .jsoneditor-menu button.jsoneditor-default{width:96px}body .jsoneditor-contextmenu .jsoneditor-menu button.jsoneditor-expand{float:right;width:32px;height:24px;border-left:1px solid var(--t42-color-opacity-10)}body .jsoneditor-contextmenu .jsoneditor-menu li{overflow:hidden}body .jsoneditor-contextmenu .jsoneditor-menu li ul{display:none;position:relative;left:-10px;top:0;border:none;box-shadow:inset var(--t42-shadow);padding:0 10px;-webkit-transition:all 0.3s ease-out;-moz-transition:all 0.3s ease-out;-o-transition:all 0.3s ease-out;transition:all 0.3s ease-out}body .jsoneditor-contextmenu .jsoneditor-menu li ul .jsoneditor-icon{margin-left:24px}body .jsoneditor-contextmenu .jsoneditor-menu li ul li button{padding-left:24px;animation:all ease-in-out 1s}body .jsoneditor-contextmenu .jsoneditor-menu li button .jsoneditor-expand{position:absolute;top:0;right:0;width:24px;height:24px;padding:0;margin:0 4px 0 0;background-image:"/";background-position:0 -72px}body .jsoneditor-contextmenu .jsoneditor-icon{position:absolute;top:0;left:0;width:24px;height:24px;border:none;padding:0;margin:0;background-image:"/"}body .jsoneditor-contextmenu .jsoneditor-text{padding:4px 0 4px 24px;word-wrap:break-word}body .jsoneditor-contextmenu .jsoneditor-text.jsoneditor-right-margin{padding-right:24px}body .jsoneditor-contextmenu .jsoneditor-separator{height:0;border-top:1px solid var(--t42-color-opacity-10);padding-top:5px;margin-top:5px}body .jsoneditor-contextmenu button.jsoneditor-remove .jsoneditor-icon{background-position:-24px 0}body .jsoneditor-contextmenu button.jsoneditor-append .jsoneditor-icon{background-position:0 0}body .jsoneditor-contextmenu button.jsoneditor-insert .jsoneditor-icon{background-position:0 0}body .jsoneditor-contextmenu button.jsoneditor-duplicate .jsoneditor-icon{background-position:-48px 0}body .jsoneditor-contextmenu button.jsoneditor-sort-asc .jsoneditor-icon{background-position:-168px 0}body .jsoneditor-contextmenu button.jsoneditor-sort-desc .jsoneditor-icon{background-position:-192px 0}body .jsoneditor-contextmenu button.jsoneditor-transform .jsoneditor-icon{background-position:-216px 0}body .jsoneditor-contextmenu button.jsoneditor-extract .jsoneditor-icon{background-position:0 -24px}body .jsoneditor-contextmenu button.jsoneditor-type-string .jsoneditor-icon{background-position:-144px 0}body .jsoneditor-contextmenu button.jsoneditor-type-auto .jsoneditor-icon{background-position:-120px 0}body .jsoneditor-contextmenu button.jsoneditor-type-object .jsoneditor-icon{background-position:-72px 0}body .jsoneditor-contextmenu button.jsoneditor-type-array .jsoneditor-icon{background-position:-96px 0}body .jsoneditor-contextmenu button.jsoneditor-type-modes .jsoneditor-icon{background-image:none;width:6px}body .jsoneditor-contextmenu ul,body .jsoneditor-contextmenu li{box-sizing:content-box;position:relative}body .jsoneditor-contextmenu .jsoneditor-menu button:hover,body .jsoneditor-contextmenu .jsoneditor-menu button:focus{color:var(--t42-content-color);background-color:var(--t42-color-opacity-10);outline:none}body .jsoneditor-contextmenu .jsoneditor-menu li button.jsoneditor-selected,body .jsoneditor-contextmenu .jsoneditor-menu li button.jsoneditor-selected:hover,body .jsoneditor-contextmenu .jsoneditor-menu li button.jsoneditor-selected:focus{color:var(--t42-content-color);background-color:var(--red)}body .jsoneditor-contextmenu .jsoneditor-menu li ul li button:hover,body .jsoneditor-contextmenu .jsoneditor-menu li ul li button:focus{background-color:var(--t42-color-opacity-10)}body .jsoneditor-modal{max-width:95%;border-radius:2px !important;padding:45px 15px 15px 15px !important;box-shadow:var(--t42-shadow);color:var(--t42-content-color);line-height:1.3em}body .jsoneditor-modal.jsoneditor-modal-transform{width:600px !important}body .jsoneditor-modal .pico-modal-header{position:absolute;box-sizing:border-box;top:0;left:0;width:100%;padding:0 10px;height:30px;line-height:30px;font-family:var(--t42-font-family);font-size:11pt;background:var(--primary);color:var(--t42-content-color)}body .jsoneditor-modal table{width:100%}body .jsoneditor-modal table td{padding:3px 0}body .jsoneditor-modal table td.jsoneditor-modal-input{text-align:right;padding-right:0;white-space:nowrap}body .jsoneditor-modal table td.jsoneditor-modal-actions{padding-top:15px}body .jsoneditor-modal table th{vertical-align:middle}body .jsoneditor-modal p:first-child{margin-top:0}body .jsoneditor-modal a{color:var(--primary)}body .jsoneditor-modal .jsoneditor-jmespath-block{margin-bottom:10px}body .jsoneditor-modal .pico-close{background:none !important;font-size:24px !important;top:7px !important;right:7px !important;color:var(--t42-content-color)}body .jsoneditor-modal input{padding:4px}body .jsoneditor-modal input[type="text"]{cursor:inherit}body .jsoneditor-modal input[disabled]{background:var(--t42-content-color-muted);color:var(--t42-content-color-muted)}body .jsoneditor-modal .jsoneditor-select-wrapper{position:relative;display:inline-block}body .jsoneditor-modal .jsoneditor-select-wrapper:after{content:"";width:0;height:0;border-left:5px solid transparent;border-right:5px solid transparent;border-top:6px solid #666;position:absolute;right:8px;top:14px;pointer-events:none}body .jsoneditor-modal select{padding:3px 24px 3px 10px;min-width:180px;max-width:350px;-webkit-appearance:none;-moz-appearance:none;appearance:none;text-indent:0;text-overflow:"";font-size:var(--t42-font-size);line-height:1.5em}body .jsoneditor-modal select::-ms-expand{display:none}body .jsoneditor-modal .jsoneditor-button-group input{padding:4px 10px;margin:0;border-radius:0;border-left-style:none}body .jsoneditor-modal .jsoneditor-button-group input.jsoneditor-button-first{border-top-left-radius:3px;border-bottom-left-radius:3px;border-left-style:solid}body .jsoneditor-modal .jsoneditor-button-group input.jsoneditor-button-last{border-top-right-radius:3px;border-bottom-right-radius:3px}body .jsoneditor-modal .jsoneditor-transform-preview{background:var(--t42-color-opacity-10);height:200px}body .jsoneditor-modal .jsoneditor-transform-preview.jsoneditor-error{color:var(--red)}body .jsoneditor-modal .jsoneditor-jmespath-wizard{line-height:1.2em;width:100%;padding:0;border-radius:3px}body .jsoneditor-modal .jsoneditor-jmespath-label{font-weight:bold;color:dodgerblue;margin-top:20px;margin-bottom:5px}body .jsoneditor-modal .jsoneditor-jmespath-wizard-table{width:100%;border-collapse:collapse}body .jsoneditor-modal .jsoneditor-jmespath-wizard-label{font-style:italic;margin:4px 0 2px 0}body .jsoneditor-modal .jsoneditor-inline{position:relative;display:inline-block;width:100%;padding-top:2px;padding-bottom:2px}body .jsoneditor-modal .jsoneditor-inline:not(:last-child){padding-right:2px}body .jsoneditor-modal .jsoneditor-jmespath-filter{display:flex;flex-wrap:wrap}body .jsoneditor-modal .jsoneditor-jmespath-filter-field{width:180px}body .jsoneditor-modal .jsoneditor-jmespath-filter-relation{width:100px}body .jsoneditor-modal .jsoneditor-jmespath-filter-value{min-width:180px;flex:1}body .jsoneditor-modal .jsoneditor-jmespath-sort-field{width:170px}body .jsoneditor-modal .jsoneditor-jmespath-sort-order{width:150px}body .jsoneditor-modal .jsoneditor-jmespath-select-fields{width:100%}body .jsoneditor-modal .selectr-selected{border-color:var(--t42-color-opacity-10);padding:4px 28px 4px 8px}body .jsoneditor-modal .selectr-selected .selectr-tag{background-color:var(--primary);border-radius:5px}body .jsoneditor-modal table th,body .jsoneditor-modal table td{text-align:left;vertical-align:middle;font-weight:normal;color:var(--t42-content-color);border-spacing:0;border-collapse:collapse}body .jsoneditor-modal select,body .jsoneditor-modal textarea,body .jsoneditor-modal input,body .jsoneditor-modal input[type="text"],body .jsoneditor-modal input[type="text"]:focus,body .jsoneditor-modal #query{background:#ffffff;border:1px solid var(--t42-color-opacity-10);color:var(--t42-content-color);border-radius:3px;padding:4px}body .jsoneditor-modal textarea,body .jsoneditor-modal #query{border-radius:unset}body .jsoneditor-modal,body .jsoneditor-modal table td,body .jsoneditor-modal table th,body .jsoneditor-modal select,body .jsoneditor-modal option,body .jsoneditor-modal textarea,body .jsoneditor-modal input,body .jsoneditor-modal input[type="text"],body .jsoneditor-modal #query{font-size:10.5pt;font-family:var(--t42-font-family)}body .jsoneditor-modal #query,body .jsoneditor-modal .jsoneditor-transform-preview{font-family:var(--bs-font-monospace);font-size:var(--t42-font-size);width:100%;box-sizing:border-box}body .jsoneditor-modal input[type="button"],body .jsoneditor-modal input[type="submit"]{background:var(--t42-color-opacity-10);padding:4px 20px}body .jsoneditor-modal select,body .jsoneditor-modal input{cursor:pointer}body .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-asc input.jsoneditor-button-asc,body .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-desc input.jsoneditor-button-desc{background:var(--primary);border-color:var(--primary);color:var(--t42-content-color)}body .jsoneditor{color:var(--t42-content-color);border:thin solid var(--primary);-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;width:100%;height:100%;position:relative;padding:0;line-height:100%}body div.jsoneditor-field,body div.jsoneditor-value,body a.jsoneditor-value,body div.jsoneditor-readonly,body div.jsoneditor-default{border:1px solid transparent;min-height:16px;min-width:32px;line-height:16px;padding:2px;margin:1px;word-wrap:break-word;word-break:break-word;overflow-wrap:break-word;float:left}body div.jsoneditor-field p,body div.jsoneditor-value p{margin:0}body div.jsoneditor-value.jsoneditor-empty::after{content:"value"}body div.jsoneditor-value.jsoneditor-string{color:var(--green)}body div.jsoneditor-value.jsoneditor-number{color:var(--red)}body div.jsoneditor-value.jsoneditor-boolean{color:var(--yellow)}body div.jsoneditor-value.jsoneditor-null{color:var(--primary)}body div.jsoneditor-value.jsoneditor-color-value{color:var(--t42-content-color)}body div.jsoneditor-value.jsoneditor-invalid{color:var(--white)}body div.jsoneditor-readonly{min-width:16px;color:var(--t42-content-color-muted)}body div.jsoneditor-empty{border-color:var(--t42-color-opacity-10);border-style:dashed;border-radius:2px}body div.jsoneditor-field.jsoneditor-empty::after{content:"field"}body div.jsoneditor td{vertical-align:top}body div.jsoneditor td.jsoneditor-separator{padding:3px 0;vertical-align:top;color:var(--t42-content-color-muted)}body div.jsoneditor td.jsoneditor-tree{vertical-align:top}body div.jsoneditor.busy pre.jsoneditor-preview{background:var(--t42-color-opacity-10);color:var(--t42-content-color-muted)}body div.jsoneditor.busy div.jsoneditor-busy{display:inherit}body div.jsoneditor code.jsoneditor-preview{background:none}body div.jsoneditor.jsoneditor-mode-preview pre.jsoneditor-preview{width:100%;height:100%;box-sizing:border-box;overflow:auto;padding:2px;margin:0;white-space:pre-wrap;word-break:break-all}body div.jsoneditor-default{color:var(--t42-content-color-muted);padding-left:10px}body div.jsoneditor-tree{width:100%;height:100%;position:relative;overflow:auto;background:var(--t42-content-color)}body div.jsoneditor-tree button.jsoneditor-button{width:24px;height:24px;padding:0;margin:0;border:none;cursor:pointer;background-color:transparent;background-image:"/"}body div.jsoneditor-tree button.jsoneditor-button:focus{background-color:var(--t42-color-opacity-10);outline:#e5e5e5 solid 1px}body div.jsoneditor-tree button.jsoneditor-collapsed{background-position:0 -48px}body div.jsoneditor-tree button.jsoneditor-expanded{background-position:0 -72px}body div.jsoneditor-tree button.jsoneditor-contextmenu-button{background-position:-48px -72px}body div.jsoneditor-tree button.jsoneditor-invisible{visibility:hidden;background:none}body div.jsoneditor-tree button.jsoneditor-dragarea{background-image:"/";background-position:-72px -72px;cursor:move}body div.jsoneditor-tree *:focus{outline:none}body div.jsoneditor-tree div.jsoneditor-show-more{display:inline-block;padding:3px 4px;margin:2px 0;background-color:var(--t42-color-opacity-10);border-radius:3px;color:var(--t42-content-color-muted);font-family:var(--t42-font-family);font-size:var(--t42-font-size)}body div.jsoneditor-tree div.jsoneditor-show-more a{display:inline-block;color:var(--t42-content-color-muted)}body div.jsoneditor-tree div.jsoneditor-color{display:inline-block;width:12px;height:12px;margin:4px;border:1px solid var(--t42-content-color-muted);cursor:pointer}body div.jsoneditor-tree div.jsoneditor-color.jsoneditor-color-readonly{cursor:inherit}body div.jsoneditor-tree div.jsoneditor-date{background:var(--t42-content-color);color:var(--t42-content-color);font-family:var(--t42-font-family);border-radius:3px;display:inline-block;padding:3px;margin:0 3px}body div.jsoneditor-tree table.jsoneditor-tree{border-collapse:collapse;border-spacing:0;width:100%}body div.jsoneditor-tree .jsoneditor-button{display:block}body div.jsoneditor-tree .jsoneditor-button.jsoneditor-schema-error{width:24px;height:24px;padding:0;margin:0 4px 0 0;background-image:"/";background-position:-168px -48px;background-color:transparent}body div.jsoneditor-outer{position:static;width:100%;height:100%;margin:0;padding:0;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}body div.jsoneditor-outer.has-nav-bar{margin-top:-26px;padding-top:26px}body div.jsoneditor-outer.has-nav-bar.has-main-menu-bar{margin-top:-61px;padding-top:61px}body div.jsoneditor-outer.has-status-bar{margin-bottom:-26px;padding-bottom:26px}body div.jsoneditor-outer.has-main-menu-bar{margin-top:-35px;padding-top:35px}body div.jsoneditor-busy{position:absolute;top:15%;left:0;box-sizing:border-box;width:100%;text-align:center;display:none}body div.jsoneditor-busy span{background-color:var(--t42-color-opacity-10);border:1px solid var(--t42-color-opacity-10);border-radius:3px;padding:5px 15px;box-shadow:var(--t42-shadow)}body div.jsoneditor-field.jsoneditor-empty::after,body div.jsoneditor-value.jsoneditor-empty::after{pointer-events:none;color:var(--t42-content-color-muted);font-size:8pt}body div.jsoneditor-value.jsoneditor-url,body a.jsoneditor-value.jsoneditor-url{color:var(--green);text-decoration:underline}body a.jsoneditor-value.jsoneditor-url{display:inline-block;padding:2px;margin:2px}body a.jsoneditor-value.jsoneditor-url:hover,body a.jsoneditor-value.jsoneditor-url:focus{color:var(--red)}body div.jsoneditor-field[contenteditable="true"]:focus,body div.jsoneditor-field[contenteditable="true"]:hover,body div.jsoneditor-value[contenteditable="true"]:focus,body div.jsoneditor-value[contenteditable="true"]:hover,body div.jsoneditor-field.jsoneditor-highlight,body div.jsoneditor-value.jsoneditor-highlight{background-color:var(--t42-color-opacity-10);border:1px solid var(--t42-color-opacity-10);border-radius:2px}body div.jsoneditor-field.jsoneditor-highlight-active,body div.jsoneditor-field.jsoneditor-highlight-active:focus,body div.jsoneditor-field.jsoneditor-highlight-active:hover,body div.jsoneditor-value.jsoneditor-highlight-active,body div.jsoneditor-value.jsoneditor-highlight-active:focus,body div.jsoneditor-value.jsoneditor-highlight-active:hover{background-color:#fe0;border:1px solid #ffc700;border-radius:2px}body div.jsoneditor-value.jsoneditor-object,body div.jsoneditor-value.jsoneditor-array{min-width:16px}body div.jsoneditor-tree button.jsoneditor-contextmenu-button:hover,body div.jsoneditor-tree button.jsoneditor-contextmenu-button:focus,body div.jsoneditor-tree button.jsoneditor-contextmenu-button.jsoneditor-selected,body tr.jsoneditor-selected.jsoneditor-first button.jsoneditor-contextmenu-button{background-position:-48px -48px}body div.jsoneditor-tree div.jsoneditor-show-more a:hover,body div.jsoneditor-tree div.jsoneditor-show-more a:focus{color:var(--red)}body textarea.jsoneditor-text,body .ace-jsoneditor{min-height:150px}body textarea.jsoneditor-text.ace_editor,body .ace-jsoneditor.ace_editor{font-family:var(--bs-font-monospace)}body textarea.jsoneditor-text{width:100%;height:100%;margin:0;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;outline-width:0;border:none;background-color:var(--t42-content-color);resize:none}body tr.jsoneditor-highlight,body tr.jsoneditor-selected{background-color:var(--t42-content-color-muted)}body tr.jsoneditor-selected button.jsoneditor-dragarea,body tr.jsoneditor-selected button.jsoneditor-contextmenu-button{visibility:hidden}body tr.jsoneditor-selected.jsoneditor-first button.jsoneditor-dragarea,body tr.jsoneditor-selected.jsoneditor-first button.jsoneditor-contextmenu-button{visibility:visible}body div.jsoneditor-tree button.jsoneditor-dragarea:hover,body div.jsoneditor-tree button.jsoneditor-dragarea:focus,body tr.jsoneditor-selected.jsoneditor-first button.jsoneditor-dragarea{background-position:-72px -48px}body div.jsoneditor tr,body div.jsoneditor th,body div.jsoneditor td{padding:0;margin:0}body div.jsoneditor-field,body div.jsoneditor-value,body div.jsoneditor td,body div.jsoneditor th,body div.jsoneditor textarea,body pre.jsoneditor-preview,body .jsoneditor-schema-error,body .jsoneditor-popover{font-family:var(--bs-font-monospace);font-size:var(--t42-font-size);color:var(--t42-content-color)}body .jsoneditor-schema-error{cursor:default;display:inline-block;height:24px;line-height:24px;position:relative;text-align:center;width:24px}body .jsoneditor-popover{background-color:Rgb(var(--t42-bg-light));border-radius:3px;box-shadow:var(--t42-shadow);color:var(--t42-content-color);padding:7px 10px;position:absolute;cursor:auto;width:200px}body .jsoneditor-popover.jsoneditor-above{bottom:32px;left:-98px}body .jsoneditor-popover.jsoneditor-above:before{border-top:7px solid Rgb(var(--t42-bg-light));bottom:-7px}body .jsoneditor-popover.jsoneditor-below{top:32px;left:-98px}body .jsoneditor-popover.jsoneditor-below:before{border-bottom:7px solid Rgb(var(--t42-bg-light));top:-7px}body .jsoneditor-popover.jsoneditor-left{top:-7px;right:32px}body .jsoneditor-popover.jsoneditor-left:before{border-left:7px solid Rgb(var(--t42-bg-light));border-top:7px solid transparent;border-bottom:7px solid transparent;content:"";top:19px;right:-14px;left:inherit;margin-left:inherit;margin-top:-7px;position:absolute}body .jsoneditor-popover.jsoneditor-right{top:-7px;left:32px}body .jsoneditor-popover.jsoneditor-right:before{border-right:7px solid Rgb(var(--t42-bg-light));border-top:7px solid transparent;border-bottom:7px solid transparent;content:"";top:19px;left:-14px;margin-left:inherit;margin-top:-7px;position:absolute}body .jsoneditor-popover:before{border-right:7px solid transparent;border-left:7px solid transparent;content:"";display:block;left:50%;margin-left:-7px;position:absolute}body .jsoneditor-text-errors tr.jump-to-line:hover{text-decoration:underline;cursor:pointer}body .jsoneditor-schema-error:hover .jsoneditor-popover,body .jsoneditor-schema-error:focus .jsoneditor-popover{display:block;animation:fade-in 0.3s linear 1, move-up 0.3s linear 1}@keyframes fade-in{from{opacity:0}to{opacity:1}}body .jsoneditor .jsoneditor-validation-errors-container{max-height:130px;overflow-y:auto}body .jsoneditor .jsoneditor-validation-errors{width:100%;overflow:hidden}body .jsoneditor .jsoneditor-additional-errors{position:absolute;margin:auto;bottom:31px;left:calc(50% - 92px);color:var(--t42-content-color-muted);background-color:Rgb(var(--t42-bg-mid));padding:7px 15px;border-radius:8px}body .jsoneditor .jsoneditor-additional-errors.visible{visibility:visible;opacity:1;transition:opacity 2s linear}body .jsoneditor .jsoneditor-additional-errors.hidden{visibility:hidden;opacity:0;transition:visibility 0s 2s, opacity 2s linear}body .jsoneditor .jsoneditor-text-errors{width:100%;border-collapse:collapse;border-top:1px solid #ffc700}body .jsoneditor .jsoneditor-text-errors td{padding:3px 6px;vertical-align:middle}body .jsoneditor .jsoneditor-text-errors td pre{margin:0;white-space:pre-wrap}body .jsoneditor .jsoneditor-text-errors tr{background-color:var(--t42-color-opacity-10)}body .jsoneditor .jsoneditor-text-errors tr.parse-error{background-color:var(--red)}body .jsoneditor-text-errors .jsoneditor-schema-error{border:none;width:24px;height:24px;padding:0;margin:0 4px 0 0;cursor:pointer}body .jsoneditor-text-errors tr .jsoneditor-schema-error{background-image:"/";background-position:-168px -48px;background-color:transparent}body .jsoneditor-text-errors tr.parse-error .jsoneditor-schema-error{background-image:"/";background-position:-25px 0px;background-color:transparent}body .jsoneditor-anchor{cursor:pointer}body .jsoneditor-anchor .picker_wrapper.popup.popup_bottom{top:28px;left:-10px}body .fadein{-webkit-animation:fadein 0.3s;animation:fadein 0.3s;-moz-animation:fadein 0.3s;-o-animation:fadein 0.3s}@keyframes fadein{0%{opacity:0}100%{opacity:1}}body .jsoneditor-modal input[type="search"].selectr-input{border:1px solid #d3d3d3;width:calc(100% - 4px);margin:2px;padding:4px;box-sizing:border-box}body .jsoneditor-modal button.selectr-input-clear{right:8px}body .jsoneditor-menu{width:100%;height:35px;padding:2px;margin:0;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;color:var(--t42-content-color);background-color:var(--primary);border-bottom:1px solid var(--primary)}body .jsoneditor-menu>button,body .jsoneditor-menu>.jsoneditor-modes>button{width:26px;height:26px;margin:2px;padding:0;border-radius:2px;border:1px solid transparent;background-color:transparent;background-image:"/";color:var(--t42-content-color);opacity:0.8;font-family:var(--t42-font-family);font-size:var(--t42-font-size);float:left}body .jsoneditor-menu>button:hover,body .jsoneditor-menu>.jsoneditor-modes>button:hover{background-color:rgba(255,255,255,0.2);border:1px solid rgba(255,255,255,0.4)}body .jsoneditor-menu>button:focus,body .jsoneditor-menu>button:active,body .jsoneditor-menu>.jsoneditor-modes>button:focus,body .jsoneditor-menu>.jsoneditor-modes>button:active{background-color:rgba(255,255,255,0.3)}body .jsoneditor-menu>button:disabled,body .jsoneditor-menu>.jsoneditor-modes>button:disabled{opacity:0.5;background-color:transparent;border:none}body .jsoneditor-menu>button.jsoneditor-collapse-all{background-position:0 -96px}body .jsoneditor-menu>button.jsoneditor-expand-all{background-position:0 -120px}body .jsoneditor-menu>button.jsoneditor-sort{background-position:-120px -96px}body .jsoneditor-menu>button.jsoneditor-transform{background-position:-144px -96px}body .jsoneditor.jsoneditor-mode-view>.jsoneditor-menu>button.jsoneditor-sort,body .jsoneditor.jsoneditor-mode-form>.jsoneditor-menu>button.jsoneditor-sort,body .jsoneditor.jsoneditor-mode-view>.jsoneditor-menu>button.jsoneditor-transform,body .jsoneditor.jsoneditor-mode-form>.jsoneditor-menu>button.jsoneditor-transform{display:none}body .jsoneditor-menu>button.jsoneditor-undo{background-position:-24px -96px}body .jsoneditor-menu>button.jsoneditor-undo:disabled{background-position:-24px -120px}body .jsoneditor-menu>button.jsoneditor-redo{background-position:-48px -96px}body .jsoneditor-menu>button.jsoneditor-redo:disabled{background-position:-48px -120px}body .jsoneditor-menu>button.jsoneditor-compact{background-position:-72px -96px}body .jsoneditor-menu>button.jsoneditor-format{background-position:-72px -120px}body .jsoneditor-menu>button.jsoneditor-repair{background-position:-96px -96px}body .jsoneditor-menu>.jsoneditor-modes{display:inline-block;float:left}body .jsoneditor-menu>.jsoneditor-modes>button{background-image:none;width:auto;padding-left:6px;padding-right:6px}body .jsoneditor-menu>button.jsoneditor-separator,body .jsoneditor-menu>.jsoneditor-modes>button.jsoneditor-separator{margin-left:10px}body .jsoneditor-menu a{font-family:var(--t42-font-family);font-size:var(--t42-font-size);color:var(--t42-content-color);opacity:0.8;vertical-align:middle}body .jsoneditor-menu a:hover{opacity:1}body .jsoneditor-menu a.jsoneditor-poweredBy{font-size:8pt;position:absolute;right:0;top:0;padding:10px}body .jsoneditor-navigation-bar{width:100%;height:26px;line-height:26px;padding:0;margin:0;border-bottom:1px solid var(--t42-color-opacity-10);-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;color:var(--t42-content-color-muted);background-color:Rgb(var(--t42-bg-mid));overflow:hidden;font-family:var(--t42-font-family);font-size:var(--t42-font-size)}body .jsoneditor-search{font-family:var(--t42-font-family);position:absolute;right:4px;top:4px;border-collapse:collapse;border-spacing:0;display:flex}body .jsoneditor-search input{color:var(--t42-content-color);width:120px;border:none;outline:none;margin:1px;line-height:20px;font-family:var(--t42-font-family)}body .jsoneditor-search button{width:16px;height:24px;padding:0;margin:0;border:none;background:"/";vertical-align:top}body .jsoneditor-search button:hover{background-color:transparent}body .jsoneditor-search button.jsoneditor-refresh{width:18px;background-position:-99px -73px}body .jsoneditor-search button.jsoneditor-next{cursor:pointer;background-position:-124px -73px}body .jsoneditor-search button.jsoneditor-next:hover{background-position:-124px -49px}body .jsoneditor-search button.jsoneditor-previous{cursor:pointer;background-position:-148px -73px;margin-right:2px}body .jsoneditor-search button.jsoneditor-previous:hover{background-position:-148px -49px}body .jsoneditor-results{font-family:var(--t42-font-family);color:var(--t42-content-color);padding-right:5px;line-height:26px}body .jsoneditor-frame{border:1px solid transparent;background-color:var(--t42-content-color);padding:0 2px;margin:0}body .jsoneditor-statusbar{line-height:26px;height:26px;color:var(--t42-content-color-muted);background-color:Rgb(var(--t42-bg-mid));border-top:1px solid var(--t42-color-opacity-10);-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;font-size:var(--t42-font-size)}body .jsoneditor-statusbar>.jsoneditor-curserinfo-val{margin-right:12px}body .jsoneditor-statusbar>.jsoneditor-curserinfo-count{margin-left:4px}body .jsoneditor-statusbar>.jsoneditor-validation-error-icon{float:right;width:24px;height:24px;padding:0;margin-top:1px;background-image:"/";background-position:-168px -48px;cursor:pointer}body .jsoneditor-statusbar>.jsoneditor-validation-error-count{float:right;margin:0 4px 0 0;cursor:pointer}body .jsoneditor-statusbar>.jsoneditor-parse-error-icon{float:right;width:24px;height:24px;padding:0;margin:1px;background-image:"/";background-position:-25px 0px}body .jsoneditor-statusbar .jsoneditor-array-info a{color:inherit}body div.jsoneditor-statusbar>.jsoneditor-curserinfo-label,body div.jsoneditor-statusbar>.jsoneditor-size-info{margin:0 4px}body .jsoneditor-treepath{padding:0 5px;overflow:hidden;white-space:nowrap;outline:none}body .jsoneditor-treepath.show-all{word-wrap:break-word;white-space:normal;position:absolute;background-color:Rgb(var(--t42-bg-mid));z-index:1;box-shadow:var(--t42-shadow)}body .jsoneditor-treepath.show-all span.jsoneditor-treepath-show-all-btn{display:none}body .jsoneditor-treepath div.jsoneditor-contextmenu-root{position:absolute;left:0}body .jsoneditor-treepath .jsoneditor-treepath-show-all-btn{position:absolute;background-color:Rgb(var(--t42-bg-mid));left:0;height:20px;padding:0 3px;cursor:pointer}body .jsoneditor-treepath .jsoneditor-treepath-element{margin:1px;font-family:var(--t42-font-family);font-size:var(--t42-font-size)}body .jsoneditor-treepath .jsoneditor-treepath-seperator{margin:2px;font-size:9pt;font-family:var(--t42-font-family)}body .jsoneditor-treepath span.jsoneditor-treepath-element:hover,body .jsoneditor-treepath span.jsoneditor-treepath-seperator:hover{cursor:pointer;text-decoration:underline}body .selectr-container{position:relative}body .selectr-container li{list-style:none}body .selectr-hidden{position:absolute;overflow:hidden;clip:rect(0px, 0px, 0px, 0px);width:1px;height:1px;margin:-1px;padding:0;border:0 none}body .selectr-visible{position:absolute;left:0;top:0;width:100%;height:100%;opacity:0;z-index:11}body .selectr-desktop.multiple .selectr-visible{display:none}body .selectr-desktop.multiple.native-open .selectr-visible{top:100%;min-height:200px !important;height:auto;opacity:1;display:block}body .selectr-container.multiple.selectr-mobile .selectr-selected{z-index:0}body .selectr-selected{position:relative;z-index:1;box-sizing:border-box;width:100%;padding:7px 28px 7px 14px;cursor:pointer;border:1px solid Rgb(var(--t42-bg-mid));border-radius:3px;background-color:var(--t42-content-color)}body .selectr-selected::before{position:absolute;top:50%;right:10px;width:0;height:0;content:'';-o-transform:rotate(0deg) translate3d(0px, -50%, 0px);-ms-transform:rotate(0deg) translate3d(0px, -50%, 0px);-moz-transform:rotate(0deg) translate3d(0px, -50%, 0px);-webkit-transform:rotate(0deg) translate3d(0px, -50%, 0px);transform:rotate(0deg) translate3d(0px, -50%, 0px);border-width:4px 4px 0 4px;border-style:solid;border-color:#6c7a86 transparent transparent}body .selectr-container.open .selectr-selected::before,body .selectr-container.native-open .selectr-selected::before{border-width:0 4px 4px 4px;border-style:solid;border-color:transparent transparent #6c7a86}body .selectr-label{display:none;overflow:hidden;width:100%;white-space:nowrap;text-overflow:ellipsis}body .selectr-placeholder{color:#6c7a86}body .selectr-tags{margin:0;padding:0;white-space:normal}body .has-selected .selectr-tags{margin:0 0 -2px}body .selectr-tag{list-style:none;position:relative;float:left;padding:2px 25px 2px 8px;margin:0 2px 2px 0;cursor:default;color:var(--t42-content-color);border:medium none;border-radius:10px;background:#acb7bf none repeat scroll 0 0}body .selectr-container.multiple.has-selected .selectr-selected{padding:5px 28px 5px 5px}body .selectr-options-container{position:absolute;z-index:10000;top:calc(100% - 1px);left:0;display:none;box-sizing:border-box;width:100%;border-width:0 1px 1px;border-style:solid;border-color:transparent Rgb(var(--t42-bg-mid)) Rgb(var(--t42-bg-mid));border-radius:0 0 3px 3px;background-color:var(--t42-content-color)}body .selectr-container.open .selectr-options-container{display:block}body .selectr-input-container{position:relative;display:none}body .selectr-clear,body .selectr-input-clear,body .selectr-tag-remove{position:absolute;top:50%;right:22px;width:20px;height:20px;padding:0;cursor:pointer;-o-transform:translate3d(0px, -50%, 0px);-ms-transform:translate3d(0px, -50%, 0px);-moz-transform:translate3d(0px, -50%, 0px);-webkit-transform:translate3d(0px, -50%, 0px);transform:translate3d(0px, -50%, 0px);border:medium none;background-color:transparent;z-index:11}body .selectr-clear,body .selectr-input-clear{display:none}body .selectr-container.has-selected .selectr-clear,body .selectr-input-container.active .selectr-input-clear{display:block}body .selectr-selected .selectr-tag-remove{right:2px}body .selectr-clear::before,body .selectr-clear::after,body .selectr-input-clear::before,body .selectr-input-clear::after,body .selectr-tag-remove::before,body .selectr-tag-remove::after{position:absolute;top:5px;left:9px;width:2px;height:10px;content:' ';background-color:#6c7a86}body .selectr-tag-remove::before,body .selectr-tag-remove::after{top:4px;width:3px;height:12px;background-color:var(--t42-content-color)}body .selectr-clear:before,body .selectr-input-clear::before,body .selectr-tag-remove::before{-o-transform:rotate(45deg);-ms-transform:rotate(45deg);-moz-transform:rotate(45deg);-webkit-transform:rotate(45deg);transform:rotate(45deg)}body .selectr-clear:after,body .selectr-input-clear::after,body .selectr-tag-remove::after{-o-transform:rotate(-45deg);-ms-transform:rotate(-45deg);-moz-transform:rotate(-45deg);-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}body .selectr-input-container.active,body .selectr-input-container.active .selectr-clear{display:block}body .selectr-input{top:5px;left:5px;box-sizing:border-box;width:calc(100% - 30px);margin:10px 15px;padding:7px 30px 7px 9px;border:1px solid Rgb(var(--t42-bg-mid));border-radius:3px}body .selectr-notice{display:none;box-sizing:border-box;width:100%;padding:8px 16px;border-top:1px solid Rgb(var(--t42-bg-mid));border-radius:0 0 3px 3px;background-color:var(--t42-content-color)}body .selectr-container.notice .selectr-notice{display:block}body .selectr-container.notice .selectr-selected{border-radius:3px 3px 0 0}body .selectr-options{position:relative;top:calc(100% + 2px);display:none;overflow-x:auto;overflow-y:scroll;max-height:200px;margin:0;padding:0}body .selectr-container.open .selectr-options,body .selectr-container.open .selectr-input-container,body .selectr-container.notice .selectr-options-container{display:block}body .selectr-option{position:relative;display:block;padding:5px 20px;list-style:outside none none;cursor:pointer;font-weight:normal}body .selectr-options.optgroups>.selectr-option{padding-left:25px}body .selectr-optgroup{font-weight:bold;padding:0}body .selectr-optgroup--label{font-weight:bold;margin-top:10px;padding:5px 15px}body .selectr-match{text-decoration:underline}body .selectr-option.selected{background-color:#ddd}body .selectr-option.active{color:var(--t42-content-color);background-color:#5897fb}body .selectr-option.disabled{opacity:0.4}body .selectr-option.excluded{display:none}body .selectr-container.open .selectr-selected{border-color:Rgb(var(--t42-bg-mid)) Rgb(var(--t42-bg-mid)) transparent Rgb(var(--t42-bg-mid));border-radius:3px 3px 0 0}body .selectr-container.open .selectr-selected::after{-o-transform:rotate(180deg) translate3d(0px, 50%, 0px);-ms-transform:rotate(180deg) translate3d(0px, 50%, 0px);-moz-transform:rotate(180deg) translate3d(0px, 50%, 0px);-webkit-transform:rotate(180deg) translate3d(0px, 50%, 0px);transform:rotate(180deg) translate3d(0px, 50%, 0px)}body .selectr-disabled{opacity:.6}body .selectr-empty,body .has-selected .selectr-placeholder{display:none}body .has-selected .selectr-label{display:block}body .taggable .selectr-selected{padding:4px 28px 4px 4px}body .taggable .selectr-selected::after{display:table;content:" ";clear:both}body .taggable .selectr-label{width:auto}body .taggable .selectr-tags{float:left;display:block}body .taggable .selectr-placeholder{display:none}body .input-tag{float:left;min-width:90px;width:auto}body .selectr-tag-input{border:medium none;padding:3px 10px;width:100%;font-family:inherit;font-weight:inherit;font-size:inherit}body .selectr-input-container.loading::after{position:absolute;top:50%;right:20px;width:20px;height:20px;content:'';-o-transform:translate3d(0px, -50%, 0px);-ms-transform:translate3d(0px, -50%, 0px);-moz-transform:translate3d(0px, -50%, 0px);-webkit-transform:translate3d(0px, -50%, 0px);transform:translate3d(0px, -50%, 0px);-o-transform-origin:50% 0 0;-ms-transform-origin:50% 0 0;-moz-transform-origin:50% 0 0;-webkit-transform-origin:50% 0 0;transform-origin:50% 0 0;-moz-animation:500ms linear 0s normal forwards infinite running selectr-spin;-webkit-animation:500ms linear 0s normal forwards infinite running selectr-spin;animation:500ms linear 0s normal forwards infinite running selectr-spin;border-width:3px;border-style:solid;border-color:#aaa #ddd #ddd;border-radius:50%}@-webkit-keyframes selectr-spin{0%{-webkit-transform:rotate(0deg) translate3d(0px, -50%, 0px);transform:rotate(0deg) translate3d(0px, -50%, 0px)}100%{-webkit-transform:rotate(360deg) translate3d(0px, -50%, 0px);transform:rotate(360deg) translate3d(0px, -50%, 0px)}}@keyframes selectr-spin{0%{-webkit-transform:rotate(0deg) translate3d(0px, -50%, 0px);transform:rotate(0deg) translate3d(0px, -50%, 0px)}100%{-webkit-transform:rotate(360deg) translate3d(0px, -50%, 0px);transform:rotate(360deg) translate3d(0px, -50%, 0px)}}body .selectr-container.open.inverted .selectr-selected{border-color:transparent Rgb(var(--t42-bg-mid)) Rgb(var(--t42-bg-mid));border-radius:0 0 3px 3px}body .selectr-container.inverted .selectr-options-container{border-width:1px 1px 0;border-color:Rgb(var(--t42-bg-mid)) Rgb(var(--t42-bg-mid)) transparent;border-radius:3px 3px 0 0;background-color:var(--t42-content-color)}body .selectr-container.inverted .selectr-options-container{top:auto;bottom:calc(100% - 1px)}body .selectr-container ::-webkit-input-placeholder{color:#6c7a86;opacity:1}body .selectr-container ::-moz-placeholder{color:#6c7a86;opacity:1}body .selectr-container :-ms-input-placeholder{color:#6c7a86;opacity:1}body .selectr-container ::placeholder{color:#6c7a86;opacity:1}body #jsoneditor{height:100%}body .jsoneditor{border-color:var(--t42-color-opacity-10)}body .jsoneditor textarea{line-height:1.5;background-color:Rgb(var(--t42-bg-dark));min-height:100%}body .jsoneditor input{outline:0}body .jsoneditor input:focus{outline:0}body .jsoneditor-button:focus{outline:none}body .jsoneditor-menu{border-bottom-color:var(--t42-color-opacity-10);background-color:Rgb(var(--t42-bg-light))}body .jsoneditor-menu button{background-image:var(--t42-json-icons);background-color:transparent}body .jsoneditor-menu button:hover,body .jsoneditor-menu button:focus{color:var(--t42-link-hover-color)}body .jsoneditor-menu>button,body .jsoneditor-menu>.jsoneditor-modes>button{border-radius:0;font-size:.75rem;backdrop-filter:var(--backdrop-filter);transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, color}body .jsoneditor-menu>button:hover:not(.disabled):not(:disabled),body .jsoneditor-menu>button:active,body .jsoneditor-menu>.jsoneditor-modes>button:hover:not(.disabled):not(:disabled),body .jsoneditor-menu>.jsoneditor-modes>button:active{border-color:transparent;color:var(--t42-link-hover-color);background-color:var(--t42-color-opacity-10)}body .jsoneditor-menu li button.jsoneditor-selected{background-color:var(--t42-color-opacity-10)}body .jsoneditor-menu .jsoneditor-poweredBy{display:none}body .jsoneditor-frame{padding:0 .875rem;border-color:var(--t42-color-opacity-10);background-color:transparent;display:flex;transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border-color}body .jsoneditor-frame:focus-within{border-color:var(--primary);background-color:var(--t42-input-bg);outline:0}body .jsoneditor-frame table td{vertical-align:middle}body .jsoneditor-search input[type="text"]{border:0}body .jsoneditor-search input[type="text"]:focus{border:0}body .jsoneditor-search input{background-color:transparent}body .jsoneditor-contextmenu{z-index:2}body .jsoneditor-contextmenu .jsoneditor-menu{border-color:var(--t42-color-opacity-10);background:linear-gradient(to bottom right, rgba(var(--t42-bg-light), 0.75) 0%, rgba(var(--t42-bg-dark), 0.75) 100%);box-shadow:var(--t42-shadow);backdrop-filter:var(--backdrop-filter)}body .jsoneditor-contextmenu .jsoneditor-menu button button .jsoneditor-expand,body .jsoneditor-contextmenu .jsoneditor-menu li button .jsoneditor-expand{background-image:var(--t42-json-icons);z-index:1}body .jsoneditor-contextmenu .jsoneditor-menu button button.jsoneditor-selected,body .jsoneditor-contextmenu .jsoneditor-menu li button.jsoneditor-selected{background-color:var(--t42-color-opacity-10);transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, color}body .jsoneditor-contextmenu .jsoneditor-menu button button.jsoneditor-selected:hover,body .jsoneditor-contextmenu .jsoneditor-menu button button.jsoneditor-selected:focus,body .jsoneditor-contextmenu .jsoneditor-menu li button.jsoneditor-selected:hover,body .jsoneditor-contextmenu .jsoneditor-menu li button.jsoneditor-selected:focus{color:var(--t42-link-hover-color);background-color:var(--t42-color-opacity-10)}body .jsoneditor-contextmenu .jsoneditor-menu button{display:flex;justify-content:start}body .jsoneditor-contextmenu .jsoneditor-menu button.jsoneditor-default{float:left;z-index:1}body .jsoneditor-contextmenu .jsoneditor-menu li ul{padding:0 !important;left:0}body .jsoneditor-contextmenu .jsoneditor-menu li ul li button{padding-left:1rem}body .jsoneditor-contextmenu .jsoneditor-menu li ul .jsoneditor-icon{position:relative;margin-left:0}body .jsoneditor-contextmenu .jsoneditor-menu .jsoneditor-text{padding:0;line-height:1.5rem}body .jsoneditor-contextmenu .jsoneditor-icon{position:relative;background-image:var(--t42-json-icons)}body .jsoneditor-contextmenu .jsoneditor-separator{margin-top:0;padding-top:0}body .jsoneditor-mode-preview pre.jsoneditor-preview{border:0;line-height:1.5}body .jsoneditor-modal{border-top:0;background:linear-gradient(to bottom right, rgba(var(--t42-bg-light), 0.75) 0%, rgba(var(--t42-bg-dark), 0.75) 100%) !important;box-shadow:var(--t42-shadow) !important;backdrop-filter:var(--backdrop-filter)}body .jsoneditor-modal::before{position:absolute;top:0;right:0;left:0;display:block;width:100%;height:0.0625rem;background:linear-gradient(90deg, #007be5 0%, rgba(0,123,229,0.5) 100%);content:""}body .jsoneditor-modal .pico-modal-header{padding:0.5rem 0.988rem;background:transparent;font-size:0.75rem}body .jsoneditor-modal .pico-close{top:1rem !important;right:1rem !important;color:var(--t42-content-color-muted);transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:color}body .jsoneditor-modal .pico-close:not(.disabled):not(:disabled).active,body .jsoneditor-modal .pico-close:not(.disabled):not(:disabled):focus,body .jsoneditor-modal .pico-close:not(.disabled):not(:disabled):hover{color:var(--t42-link-color)}body .jsoneditor-modal table td{font-size:0.75rem;padding:0 0.25rem}body .jsoneditor-modal table td.jsoneditor-modal-input{padding-top:0.25rem;padding-bottom:0.25rem;text-align:left}body .jsoneditor-modal table td.jsoneditor-modal-input.jsoneditor-modal-actions{text-align:right}body .jsoneditor-modal table th{font-size:0.75rem}body .jsoneditor-modal label,body .jsoneditor-modal p{font-size:0.75rem}body .jsoneditor-modal select{min-width:12.375rem}body .jsoneditor-modal .selectr-selected{padding:0 0.857rem}body .jsoneditor-modal select,body .jsoneditor-modal textarea,body .jsoneditor-modal input,body .jsoneditor-modal input[type="text"],body .jsoneditor-modal input[type="search"],body .jsoneditor-modal #query{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border;border-color:var(--t42-color-opacity-10);border-radius:0;font-size:0.75rem;background-color:var(--t42-input-bg)}body .jsoneditor-modal select:focus,body .jsoneditor-modal textarea:focus,body .jsoneditor-modal input:focus,body .jsoneditor-modal input[type="text"]:focus,body .jsoneditor-modal input[type="search"]:focus,body .jsoneditor-modal #query:focus{border-color:var(--primary);box-shadow:none;outline:0;padding:0 0 0 .875rem;border-radius:0}body .jsoneditor-modal select:disabled,body .jsoneditor-modal select.disabled,body .jsoneditor-modal select[readonly],body .jsoneditor-modal textarea:disabled,body .jsoneditor-modal textarea.disabled,body .jsoneditor-modal textarea[readonly],body .jsoneditor-modal input:disabled,body .jsoneditor-modal input.disabled,body .jsoneditor-modal input[readonly],body .jsoneditor-modal input[type="text"]:disabled,body .jsoneditor-modal input[type="text"].disabled,body .jsoneditor-modal input[type="text"][readonly],body .jsoneditor-modal input[type="search"]:disabled,body .jsoneditor-modal input[type="search"].disabled,body .jsoneditor-modal input[type="search"][readonly],body .jsoneditor-modal #query:disabled,body .jsoneditor-modal #query.disabled,body .jsoneditor-modal #query[readonly]{cursor:default;opacity:0.65}body .jsoneditor-modal input[type="search"].selectr-input{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border-color;border:var(--t42-border);background-color:var(--t42-input-bg);margin:0;line-height:1.5rem;width:100%;padding:0 0.5rem}body .jsoneditor-modal input[type="search"].selectr-input:hover{border-color:var(--primary)}body .jsoneditor-modal .jsoneditor-select-wrapper::after{border-top:var(--t42-color-opacity-10)}body .jsoneditor-modal input[type="button"],body .jsoneditor-modal input[type="submit"]{padding:0 .875rem;border-radius:0;color:var(--t42-link-color);line-height:1.875rem;background:transparent;transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, border-color}body .jsoneditor-modal input[type="button"]:not(.disabled):not(:disabled).active,body .jsoneditor-modal input[type="button"]:not(.disabled):not(:disabled):hover,body .jsoneditor-modal input[type="submit"]:not(.disabled):not(:disabled).active,body .jsoneditor-modal input[type="submit"]:not(.disabled):not(:disabled):hover{border-color:var(--t42-color-opacity-30);color:var(--white);background:var(--primary)}body .jsoneditor-modal .jsoneditor-button-group input.jsoneditor-button-first{border-left-style:solid;border-top-left-radius:0;border-bottom-left-radius:0}body .jsoneditor-modal .jsoneditor-button-group input.jsoneditor-button-last{border-top-right-radius:0;border-bottom-right-radius:0}body .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-asc input.jsoneditor-button-asc,body .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-desc input.jsoneditor-button-desc{color:var(--white);background:var(--primary)}body .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-asc input.jsoneditor-button-asc:hover,body .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-asc input.jsoneditor-button-asc:focus,body .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-asc input.jsoneditor-button-asc:active,body .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-desc input.jsoneditor-button-desc:hover,body .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-desc input.jsoneditor-button-desc:focus,body .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-desc input.jsoneditor-button-desc:active{border-color:var(--t42-color-opacity-30);color:var(--white)}body .jsoneditor-modal .jsoneditor-jmespath-label{color:var(--t42-content-color);font-weight:400}body .jsoneditor-modal .jsoneditor-jmespath-filter-value input{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border-color;line-height:1.875rem;padding:0 0 0 .875rem;font-size:0.75rem;background-color:var(--t42-input-bg)}body .jsoneditor-modal .jsoneditor-jmespath-filter-value input:focus,body .jsoneditor-modal .jsoneditor-jmespath-filter-value input:hover{background-color:var(--t42-input-bg);border-color:var(--primary)}body .jsoneditor-jmespath-block .jsoneditor-modal-actions{text-align:right}body div.jsoneditor td.jsoneditor-tree{vertical-align:middle}body div.jsoneditor td.jsoneditor-separator{vertical-align:middle}body div.jsoneditor-tree{background:transparent}body div.jsoneditor-tree button.jsoneditor-button{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, outline-color;background-image:var(--t42-json-icons)}body div.jsoneditor-tree button.jsoneditor-button:focus{background-color:transparent;outline-color:var(--t42-color-opacity-10)}body tr.jsoneditor-selected,body tr.jsoneditor-highlight{background-color:var(--t42-color-opacity-10)}body .selectr-selected{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border-color;height:2rem;font-size:0.75rem;font-weight:400;line-height:1.875rem;background-color:var(--t42-input-bg);border-radius:0}body .selectr-selected::before{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:transform;right:0.5rem;border:0;width:0.75rem;height:0.75rem;background:var(--t42-select-indicator) center center/1rem 1rem no-repeat;transform:translateY(-50%)}body .selectr-placeholder{color:var(--t42-content-color-muted)}body .selectr-container.open .selectr-selected{border-radius:0;border-color:var(--primary)}body .selectr-container.open .selectr-selected::before{border:0;transform:rotate(180deg) translateY(50%)}body .selectr-container.open .selectr-options-container{border-left-color:var(--primary);border-right-color:var(--primary);border-bottom-color:var(--primary)}body .selectr-options{overflow-y:auto}body .selectr-options-container{min-height:2rem;border-color:var(--t42-color-opacity-10);border-style:solid;border-width:1px;background-color:Rgb(var(--t42-bg-dark))}body .selectr-options .active{color:var(--t42-link-hover-color);background-color:var(--t42-color-opacity-10)}body .selectr-options .selected{color:var(--t42-link-hover-color);background-color:var(--primary)}body .selectr-option{padding:0 0 0 0.875rem;line-height:2rem;font-size:0.75rem}body .selectr-input{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border-color;border:var(--t42-border);background-color:var(--t42-input-bg)}body .selectr-input:hover{border-color:var(--primary)}body .selectr-input-container{padding:0.25rem}body .selectr-clear::before,body .selectr-clear::after{background-color:var(--t42-content-color)}body .jsoneditor .ace-jsoneditor .ace_text-input{min-height:auto}body .jsoneditor .ace-jsoneditor.ace_editor,body .jsoneditor .ace-jsoneditor .ace_scroller{background-color:Rgb(var(--t42-bg-dark))}body .jsoneditor .ace-jsoneditor .ace_gutter{color:var(--t42-content-color-muted);background-color:Rgb(var(--t42-bg-mid))}body .jsoneditor .ace-jsoneditor .ace_gutter-active-line{background-color:Rgb(var(--t42-bg-light))}body .jsoneditor .ace-jsoneditor .ace_cursor{border-color:Rgb(var(--t42-content-color))}body .jsoneditor .ace-jsoneditor .ace_marker-layer .ace_active-line{background-color:rgba(var(--secondary), 0.25)}body .jsoneditor .ace-jsoneditor .ace_marker-layer .ace_selection{background-color:var(--t42-color-opacity-10)}body .jsoneditor .ace-jsoneditor .ace_marker-layer .ace_selected-word{border-color:var(--t42-color-opacity-10);background-color:var(--t42-color-opacity-10)}body .jsoneditor .ace-jsoneditor .ace_marker-layer .ace_bracket{border:var(--t42-border)}body .jsoneditor .ace-jsoneditor .ace_variable{color:var(--t42-content-color)}body .jsoneditor .ace-jsoneditor .ace_constant.ace_numeric{color:#ff511f}body .jsoneditor .ace-jsoneditor .ace_constant.ace_language{color:#f9a825}body .jsoneditor .ace-jsoneditor .ace_string{color:#43a047}body .jsoneditor .ace-jsoneditor .ace_fold{border-color:var(--t42-color-opacity-10);background-color:Rgb(var(--t42-bg-light));transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-image}body .jsoneditor .ace-jsoneditor .ace_fold-widget:hover,body .jsoneditor .ace-jsoneditor .ace_fold-widget:active{border-color:var(--t42-color-opacity-30);background-color:var(--t42-color-opacity-10);box-shadow:none}body .pico-modal-contents{display:block} + diff --git a/typescript/start/portfolio-downloader/tsconfig.json b/typescript/start/portfolio-downloader/tsconfig.json new file mode 100644 index 0000000..11ec879 --- /dev/null +++ b/typescript/start/portfolio-downloader/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "./dist", + "rootDir": "./src" + }, + "include": ["./src", "../../types"] +} \ No newline at end of file diff --git a/typescript/start/portfolio-downloader/webpack.config.js b/typescript/start/portfolio-downloader/webpack.config.js new file mode 100644 index 0000000..76eb236 --- /dev/null +++ b/typescript/start/portfolio-downloader/webpack.config.js @@ -0,0 +1,31 @@ +const path = require('path'); +const CopyWebpackPlugin = require('copy-webpack-plugin'); + +module.exports = { + mode: 'development', + entry: './src/index.ts', + module: { + rules: [ + { + test: /\.tsx?$/, + use: 'ts-loader', + exclude: /node_modules/, + }, + ], + }, + resolve: { + extensions: ['.tsx', '.ts', '.js'], + }, + output: { + filename: 'index.js', + path: path.resolve(__dirname, 'dist'), + }, + plugins: [ + new CopyWebpackPlugin({ + patterns: [ + { from: 'src/index.html', to: 'index.html' }, + { from: '../../../javascript/start/portfolio-downloader/lib', to: 'lib' } + ], + }), + ], +}; \ No newline at end of file diff --git a/typescript/start/stocks/esbuild.js b/typescript/start/stocks/esbuild.js new file mode 100644 index 0000000..27c80dc --- /dev/null +++ b/typescript/start/stocks/esbuild.js @@ -0,0 +1,48 @@ +const fs = require('fs'); +const path = require('path'); +const { build } = require('esbuild'); + +// Directory paths +const srcDir = path.join(__dirname, 'src'); +const distDir = path.join(__dirname, 'dist'); + +// Ensure dist directory exists +if (!fs.existsSync(distDir)) { + fs.mkdirSync(distDir, { recursive: true }); +} + +// Copy HTML file +fs.copyFileSync( + path.join(srcDir, 'index.html'), + path.join(distDir, 'index.html') +); + +// Copy lib directory +const libSrcDir = path.join(srcDir, 'lib'); +const libDistDir = path.join(distDir, 'lib'); + +if (!fs.existsSync(libDistDir)) { + fs.mkdirSync(libDistDir, { recursive: true }); +} + +fs.readdirSync(libSrcDir).forEach(file => { + fs.copyFileSync( + path.join(libSrcDir, file), + path.join(libDistDir, file) + ); +}); + +// Build with esbuild +build({ + entryPoints: [path.join(srcDir, 'index.ts')], + bundle: true, + outfile: path.join(distDir, 'index.js'), + platform: 'browser', + format: 'iife', + sourcemap: true, + target: ['es2020'], + tsconfig: path.join(__dirname, 'tsconfig.json'), +}).catch((error) => { + console.error(error); + process.exit(1); +}); \ No newline at end of file diff --git a/typescript/start/stocks/src/index.html b/typescript/start/stocks/src/index.html new file mode 100644 index 0000000..6b06265 --- /dev/null +++ b/typescript/start/stocks/src/index.html @@ -0,0 +1,56 @@ + + + + + + + + + + + + Stocks + + + + + + + + + + + +
+
+
+
+ io.Connect is unavailable +
+ + +
+
+

Stocks

+
+
+
+ + + + + + + + + + + +
SymbolDescriptionBidAsk
+
+
+ + + diff --git a/typescript/start/stocks/src/index.ts b/typescript/start/stocks/src/index.ts new file mode 100644 index 0000000..4786043 --- /dev/null +++ b/typescript/start/stocks/src/index.ts @@ -0,0 +1,213 @@ +let clientPortfolioStocks: Stock[] | undefined; +let clientName: string | undefined; + +interface PriceUpdate { + stocks: { + RIC: string; + Bid: string; + Ask: string; + }[]; +} + +interface StockWithPrices extends Stock { + Bid?: string; + Ask?: string; + Description?: string; +} + +const generateStockPrices = (handleNewPrices: (update: PriceUpdate) => void): void => { + setInterval(() => { + const priceUpdate: PriceUpdate = { + stocks: [ + { + RIC: "VOD.L", + Bid: Number(70 - Math.random() * 10).toFixed(2), + Ask: Number(70 + Math.random() * 10).toFixed(2) + }, + { + RIC: "TSCO.L", + Bid: Number(90 - Math.random() * 10).toFixed(2), + Ask: Number(90 + Math.random() * 10).toFixed(2) + }, + { + RIC: "BARC.L", + Bid: Number(105 - Math.random() * 10).toFixed(2), + Ask: Number(105 + Math.random() * 10).toFixed(2) + }, + { + RIC: "BMWG.DE", + Bid: Number(29 - Math.random() * 10).toFixed(2), + Ask: Number(29 + Math.random() * 10).toFixed(2) + }, + { + RIC: "AAL.L", + Bid: Number(46 - Math.random() * 10).toFixed(2), + Ask: Number(46 + Math.random() * 10).toFixed(2) + }, + { + RIC: "IBM.N", + Bid: Number(70 - Math.random() * 10).toFixed(2), + Ask: Number(70 + Math.random() * 10).toFixed(2) + }, + { + RIC: "AAPL.OQ", + Bid: Number(90 - Math.random() * 10).toFixed(2), + Ask: Number(90 + Math.random() * 10).toFixed(2) + }, + { + RIC: "BA.N", + Bid: Number(105 - Math.random() * 10).toFixed(2), + Ask: Number(105 + Math.random() * 10).toFixed(2) + }, + { + RIC: "TSLA:OQ", + Bid: Number(29 - Math.random() * 10).toFixed(2), + Ask: Number(29 + Math.random() * 10).toFixed(2) + }, + { + RIC: "ENBD.DU", + Bid: Number(46 - Math.random() * 10).toFixed(2), + Ask: Number(46 + Math.random() * 10).toFixed(2) + }, + { + RIC: "AMZN.OQ", + Bid: Number(29 - Math.random() * 10).toFixed(2), + Ask: Number(29 + Math.random() * 10).toFixed(2) + }, + { + RIC: "MSFT:OQ", + Bid: Number(46 - Math.random() * 10).toFixed(2), + Ask: Number(46 + Math.random() * 10).toFixed(2) + } + ] + }; + + handleNewPrices(priceUpdate); + }, 1500); +}; + +const setupStocks = (stocks: StockWithPrices[]): void => { + const tableElement = document.getElementById("stocksTable"); + if (!tableElement) return; + + const table = tableElement.getElementsByTagName("tbody")[0]; + if (!table) return; + + table.innerHTML = ""; + + const addRowCell = (row: HTMLTableRowElement, cellData: string, cssClass?: string): void => { + const cell = document.createElement("td"); + + cell.innerText = cellData; + + if (cssClass) { + cell.className = cssClass; + } + row.appendChild(cell); + }; + + const addRow = (table: HTMLTableSectionElement, stock: StockWithPrices): void => { + const row = document.createElement("tr"); + + addRowCell(row, stock.RIC || ""); + addRowCell(row, stock.Description || ""); + addRowCell(row, stock.Bid || ""); + addRowCell(row, stock.Ask || ""); + + row.setAttribute("data-ric", stock.RIC); + + row.onclick = () => { + stockClickedHandler(stock); + }; + + table.appendChild(row); + }; + + stocks.forEach((stock) => { + addRow(table, stock); + }); +}; + +// TODO: Chapter 3 +// const toggleIOAvailable = (): void => { +// const span = document.getElementById("ioConnectSpan"); +// if (!span) return; + +// span.classList.remove("bg-danger"); +// span.classList.add("bg-success"); +// span.textContent = "io.Connect is available"; +// }; + +const newPricesHandler = (priceUpdate: PriceUpdate): void => { + priceUpdate.stocks.forEach((stock) => { + const row = document.querySelectorAll(`[data-ric="${stock.RIC}"]`)[0] as HTMLTableRowElement; + + if (!row) { + return; + } + + const bidElement = row.children[2]; + if (bidElement) bidElement.textContent = stock.Bid; + + const askElement = row.children[3]; + if (askElement) askElement.textContent = stock.Ask; + }); + + // TODO: Chapter 5.1 +}; + +const stockClickedHandler = async (stock: StockWithPrices): Promise => { + // TODO: Chapter 4.1 + window.location.href = `http://${window.location.host}/details/index.html`; + + // TODO: Chapter 8.3 + + // TODO: Chapter 9.5 +}; + +const exportPortfolioButtonHandler = async (portfolio: Stock[]): Promise => { + // TODO: Chapter 10.2 +}; + +const start = async (): Promise => { + const stocksResponse = await fetch("http://localhost:8080/api/portfolio"); + const stocks = await stocksResponse.json() as StockWithPrices[]; + + setupStocks(stocks); + generateStockPrices(newPricesHandler); + + // TODO: Chapter 3 + + // TODO: Chapter 12.1 + + // TODO: Chapter 5.1 + + // TODO: Chapter 6.2 + + // TODO: Chapter 8.2 + + // TODO: Chapter 7.2 + + // TODO: Chapter 9.4 + + // TODO: Chapter 10.2 + // const exportPortfolioButton = document.getElementById("exportPortfolio"); + + // exportPortfolioButton.onclick = () => { + // if (!clientPortfolioStocks) { + // return; + // } + + // exportPortfolioButtonHandler(clientPortfolioStocks).catch(console.error); + // }; +}; + +// Add window properties when needed +declare global { + interface Window { + io?: IODesktopAPI; + priceStream?: any; + } +} + +start().catch(console.error); \ No newline at end of file diff --git a/typescript/start/stocks/src/lib/desktop.umd.js b/typescript/start/stocks/src/lib/desktop.umd.js new file mode 100644 index 0000000..6cea2c9 --- /dev/null +++ b/typescript/start/stocks/src/lib/desktop.umd.js @@ -0,0 +1,23144 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define(factory) : + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.desktop = factory()); +})(this, (function () { 'use strict'; + + var MetricTypes = { + STRING: 1, + NUMBER: 2, + TIMESTAMP: 3, + OBJECT: 4 + }; + + function getMetricTypeByValue(metric) { + if (metric.type === MetricTypes.TIMESTAMP) { + return "timestamp"; + } + else if (metric.type === MetricTypes.NUMBER) { + return "number"; + } + else if (metric.type === MetricTypes.STRING) { + return "string"; + } + else if (metric.type === MetricTypes.OBJECT) { + return "object"; + } + return "unknown"; + } + function getTypeByValue(value) { + if (value.constructor === Date) { + return "timestamp"; + } + else if (typeof value === "number") { + return "number"; + } + else if (typeof value === "string") { + return "string"; + } + else if (typeof value === "object") { + return "object"; + } + else { + return "string"; + } + } + function serializeMetric(metric) { + const serializedMetrics = {}; + const type = getMetricTypeByValue(metric); + if (type === "object") { + const values = Object.keys(metric.value).reduce((memo, key) => { + const innerType = getTypeByValue(metric.value[key]); + if (innerType === "object") { + const composite = defineNestedComposite(metric.value[key]); + memo[key] = { + type: "object", + description: "", + context: {}, + composite, + }; + } + else { + memo[key] = { + type: innerType, + description: "", + context: {}, + }; + } + return memo; + }, {}); + serializedMetrics.composite = values; + } + serializedMetrics.name = normalizeMetricName(metric.path.join("/") + "/" + metric.name); + serializedMetrics.type = type; + serializedMetrics.description = metric.description; + serializedMetrics.context = {}; + return serializedMetrics; + } + function defineNestedComposite(values) { + return Object.keys(values).reduce((memo, key) => { + const type = getTypeByValue(values[key]); + if (type === "object") { + memo[key] = { + type: "object", + description: "", + context: {}, + composite: defineNestedComposite(values[key]), + }; + } + else { + memo[key] = { + type, + description: "", + context: {}, + }; + } + return memo; + }, {}); + } + function normalizeMetricName(name) { + if (typeof name !== "undefined" && name.length > 0 && name[0] !== "/") { + return "/" + name; + } + else { + return name; + } + } + function getMetricValueByType(metric) { + const type = getMetricTypeByValue(metric); + if (type === "timestamp") { + return Date.now(); + } + else { + return publishNestedComposite(metric.value); + } + } + function publishNestedComposite(values) { + if (typeof values !== "object") { + return values; + } + return Object.keys(values).reduce((memo, key) => { + const value = values[key]; + if (typeof value === "object" && value.constructor !== Date) { + memo[key] = publishNestedComposite(value); + } + else if (value.constructor === Date) { + memo[key] = new Date(value).getTime(); + } + else if (value.constructor === Boolean) { + memo[key] = value.toString(); + } + else { + memo[key] = value; + } + return memo; + }, {}); + } + function flatten(arr) { + return arr.reduce((flat, toFlatten) => { + return flat.concat(Array.isArray(toFlatten) ? flatten(toFlatten) : toFlatten); + }, []); + } + function getHighestState(arr) { + return arr.sort((a, b) => { + if (!a.state) { + return 1; + } + if (!b.state) { + return -1; + } + return b.state - a.state; + })[0]; + } + function aggregateDescription(arr) { + let msg = ""; + arr.forEach((m, idx, a) => { + const path = m.path.join("."); + if (idx === a.length - 1) { + msg += path + "." + m.name + ": " + m.description; + } + else { + msg += path + "." + m.name + ": " + m.description + ","; + } + }); + if (msg.length > 100) { + return msg.slice(0, 100) + "..."; + } + else { + return msg; + } + } + function composeMsgForRootStateMetric(system) { + const aggregatedState = system.root.getAggregateState(); + const merged = flatten(aggregatedState); + const highestState = getHighestState(merged); + const aggregateDesc = aggregateDescription(merged); + return { + description: aggregateDesc, + value: highestState.state, + }; + } + + function gw3 (connection, config) { + if (!connection || typeof connection !== "object") { + throw new Error("Connection is required parameter"); + } + let joinPromise; + let session; + const init = (repo) => { + let resolveReadyPromise; + joinPromise = new Promise((resolve) => { + resolveReadyPromise = resolve; + }); + session = connection.domain("metrics"); + session.onJoined((reconnect) => { + if (!reconnect && resolveReadyPromise) { + resolveReadyPromise(); + resolveReadyPromise = undefined; + } + const rootStateMetric = { + name: "/State", + type: "object", + composite: { + Description: { + type: "string", + description: "", + }, + Value: { + type: "number", + description: "", + }, + }, + description: "System state", + context: {}, + }; + const defineRootMetricsMsg = { + type: "define", + metrics: [rootStateMetric], + }; + session.send(defineRootMetricsMsg); + if (reconnect) { + replayRepo(repo); + } + }); + session.join({ + system: config.system, + service: config.service, + instance: config.instance + }); + }; + const replayRepo = (repo) => { + replaySystem(repo.root); + }; + const replaySystem = (system) => { + createSystem(system); + system.metrics.forEach((m) => { + createMetric(m); + }); + system.subSystems.forEach((ss) => { + replaySystem(ss); + }); + }; + const createSystem = async (system) => { + if (system.parent === undefined) { + return; + } + await joinPromise; + const metric = { + name: normalizeMetricName(system.path.join("/") + "/" + system.name + "/State"), + type: "object", + composite: { + Description: { + type: "string", + description: "", + }, + Value: { + type: "number", + description: "", + }, + }, + description: "System state", + context: {}, + }; + const createMetricsMsg = { + type: "define", + metrics: [metric], + }; + session.send(createMetricsMsg); + }; + const updateSystem = async (system, state) => { + await joinPromise; + const shadowedUpdateMetric = { + type: "publish", + values: [{ + name: normalizeMetricName(system.path.join("/") + "/" + system.name + "/State"), + value: { + Description: state.description, + Value: state.state, + }, + timestamp: Date.now(), + }], + }; + session.send(shadowedUpdateMetric); + const stateObj = composeMsgForRootStateMetric(system); + const rootMetric = { + type: "publish", + peer_id: connection.peerId, + values: [{ + name: "/State", + value: { + Description: stateObj.description, + Value: stateObj.value, + }, + timestamp: Date.now(), + }], + }; + session.send(rootMetric); + }; + const createMetric = async (metric) => { + const metricClone = cloneMetric(metric); + await joinPromise; + const m = serializeMetric(metricClone); + const createMetricsMsg = { + type: "define", + metrics: [m], + }; + session.send(createMetricsMsg); + if (typeof metricClone.value !== "undefined") { + updateMetricCore(metricClone); + } + }; + const updateMetric = async (metric) => { + const metricClone = cloneMetric(metric); + await joinPromise; + updateMetricCore(metricClone); + }; + const updateMetricCore = (metric) => { + if (canUpdate()) { + const value = getMetricValueByType(metric); + const publishMetricsMsg = { + type: "publish", + values: [{ + name: normalizeMetricName(metric.path.join("/") + "/" + metric.name), + value, + timestamp: Date.now(), + }], + }; + return session.sendFireAndForget(publishMetricsMsg); + } + return Promise.resolve(); + }; + const cloneMetric = (metric) => { + const metricClone = { ...metric }; + if (typeof metric.value === "object" && metric.value !== null) { + metricClone.value = { ...metric.value }; + } + return metricClone; + }; + const canUpdate = () => { + try { + const func = config.canUpdateMetric ?? (() => true); + return func(); + } + catch { + return true; + } + }; + return { + init, + createSystem, + updateSystem, + createMetric, + updateMetric, + }; + } + + var Helpers = { + validate: (definition, parent, transport) => { + if (definition === null || typeof definition !== "object") { + throw new Error("Missing definition"); + } + if (parent === null || typeof parent !== "object") { + throw new Error("Missing parent"); + } + if (transport === null || typeof transport !== "object") { + throw new Error("Missing transport"); + } + }, + }; + + class BaseMetric { + definition; + system; + transport; + value; + type; + path = []; + name; + description; + get repo() { + return this.system?.repo; + } + get id() { return `${this.system.path}/${name}`; } + constructor(definition, system, transport, value, type) { + this.definition = definition; + this.system = system; + this.transport = transport; + this.value = value; + this.type = type; + Helpers.validate(definition, system, transport); + this.path = system.path.slice(0); + this.path.push(system.name); + this.name = definition.name; + this.description = definition.description; + transport.createMetric(this); + } + update(newValue) { + this.value = newValue; + return this.transport.updateMetric(this); + } + } + + class NumberMetric extends BaseMetric { + constructor(definition, system, transport, value) { + super(definition, system, transport, value, MetricTypes.NUMBER); + } + incrementBy(num) { + this.update(this.value + num); + } + increment() { + this.incrementBy(1); + } + decrement() { + this.incrementBy(-1); + } + decrementBy(num) { + this.incrementBy(num * -1); + } + } + + class ObjectMetric extends BaseMetric { + constructor(definition, system, transport, value) { + super(definition, system, transport, value, MetricTypes.OBJECT); + } + update(newValue) { + this.mergeValues(newValue); + return this.transport.updateMetric(this); + } + mergeValues(values) { + return Object.keys(this.value).forEach((k) => { + if (typeof values[k] !== "undefined") { + this.value[k] = values[k]; + } + }); + } + } + + class StringMetric extends BaseMetric { + constructor(definition, system, transport, value) { + super(definition, system, transport, value, MetricTypes.STRING); + } + } + + class TimestampMetric extends BaseMetric { + constructor(definition, system, transport, value) { + super(definition, system, transport, value, MetricTypes.TIMESTAMP); + } + now() { + this.update(new Date()); + } + } + + function system$1(name, repo, protocol, parent, description) { + if (!repo) { + throw new Error("Repository is required"); + } + if (!protocol) { + throw new Error("Transport is required"); + } + const _transport = protocol; + const _name = name; + const _description = description || ""; + const _repo = repo; + const _parent = parent; + const _path = _buildPath(parent); + let _state = {}; + const id = _arrayToString(_path, "/") + name; + const root = repo.root; + const _subSystems = []; + const _metrics = []; + function subSystem(nameSystem, descriptionSystem) { + if (!nameSystem || nameSystem.length === 0) { + throw new Error("name is required"); + } + const match = _subSystems.filter((s) => s.name === nameSystem); + if (match.length > 0) { + return match[0]; + } + const _system = system$1(nameSystem, _repo, _transport, me, descriptionSystem); + _subSystems.push(_system); + return _system; + } + function setState(state, stateDescription) { + _state = { state, description: stateDescription }; + _transport.updateSystem(me, _state); + } + function stringMetric(definition, value) { + return _getOrCreateMetric(definition, MetricTypes.STRING, value, (metricDef) => new StringMetric(metricDef, me, _transport, value)); + } + function numberMetric(definition, value) { + return _getOrCreateMetric(definition, MetricTypes.NUMBER, value, (metricDef) => new NumberMetric(metricDef, me, _transport, value)); + } + function objectMetric(definition, value) { + return _getOrCreateMetric(definition, MetricTypes.OBJECT, value, (metricDef) => new ObjectMetric(metricDef, me, _transport, value)); + } + function timestampMetric(definition, value) { + return _getOrCreateMetric(definition, MetricTypes.TIMESTAMP, value, (metricDef) => new TimestampMetric(metricDef, me, _transport, value)); + } + function _getOrCreateMetric(metricObject, expectedType, value, createMetric) { + let metricDef = { name: "" }; + if (typeof metricObject === "string") { + metricDef = { name: metricObject }; + } + else { + metricDef = metricObject; + } + const matching = _metrics.filter((shadowedMetric) => shadowedMetric.name === metricDef.name); + if (matching.length > 0) { + const existing = matching[0]; + if (existing.type !== expectedType) { + throw new Error(`A metric named ${metricDef.name} is already defined with different type.`); + } + if (typeof value !== "undefined") { + existing + .update(value) + .catch(() => { }); + } + return existing; + } + const metric = createMetric(metricDef); + _metrics.push(metric); + return metric; + } + function _buildPath(shadowedSystem) { + if (!shadowedSystem || !shadowedSystem.parent) { + return []; + } + const path = _buildPath(shadowedSystem.parent); + path.push(shadowedSystem.name); + return path; + } + function _arrayToString(path, separator) { + return ((path && path.length > 0) ? path.join(separator) : ""); + } + function getAggregateState() { + const aggState = []; + if (Object.keys(_state).length > 0) { + aggState.push({ + name: _name, + path: _path, + state: _state.state, + description: _state.description, + }); + } + _subSystems.forEach((shadowedSubSystem) => { + const result = shadowedSubSystem.getAggregateState(); + if (result.length > 0) { + aggState.push(...result); + } + }); + return aggState; + } + const me = { + get name() { + return _name; + }, + get description() { + return _description; + }, + get repo() { + return _repo; + }, + get parent() { + return _parent; + }, + path: _path, + id, + root, + get subSystems() { + return _subSystems; + }, + get metrics() { + return _metrics; + }, + subSystem, + getState: () => { + return _state; + }, + setState, + stringMetric, + timestampMetric, + objectMetric, + numberMetric, + getAggregateState, + }; + _transport.createSystem(me); + return me; + } + + class Repository { + root; + constructor(options, protocol) { + protocol.init(this); + this.root = system$1("", this, protocol); + this.addSystemMetrics(this.root, options.clickStream || options.clickStream === undefined); + } + addSystemMetrics(rootSystem, useClickStream) { + if (typeof navigator !== "undefined") { + rootSystem.stringMetric("UserAgent", navigator.userAgent); + } + if (useClickStream && typeof document !== "undefined") { + const clickStream = rootSystem.subSystem("ClickStream"); + const documentClickHandler = (e) => { + if (!e.target) { + return; + } + const target = e.target; + const className = target ? target.getAttribute("class") ?? "" : ""; + clickStream.objectMetric("LastBrowserEvent", { + type: "click", + timestamp: new Date(), + target: { + className, + id: target.id, + type: "<" + target.tagName.toLowerCase() + ">", + href: target.href || "", + }, + }); + }; + clickStream.objectMetric("Page", { + title: document.title, + page: window.location.href, + }); + if (document.addEventListener) { + document.addEventListener("click", documentClickHandler); + } + else { + document.attachEvent("onclick", documentClickHandler); + } + } + rootSystem.stringMetric("StartTime", (new Date()).toString()); + const urlMetric = rootSystem.stringMetric("StartURL", ""); + const appNameMetric = rootSystem.stringMetric("AppName", ""); + if (typeof window !== "undefined") { + if (typeof window.location !== "undefined") { + const startUrl = window.location.href; + urlMetric.update(startUrl); + } + if (typeof window.glue42gd !== "undefined") { + appNameMetric.update(window.glue42gd.appName); + } + } + } + } + + class NullProtocol { + init(repo) { + } + createSystem(system) { + return Promise.resolve(); + } + updateSystem(metric, state) { + return Promise.resolve(); + } + createMetric(metric) { + return Promise.resolve(); + } + updateMetric(metric) { + return Promise.resolve(); + } + } + + class PerfTracker { + api; + lastCount = 0; + initialPublishTimeout = 10 * 1000; + publishInterval = 60 * 1000; + system; + constructor(api, initialPublishTimeout, publishInterval) { + this.api = api; + this.initialPublishTimeout = initialPublishTimeout ?? this.initialPublishTimeout; + this.publishInterval = publishInterval ?? this.publishInterval; + this.scheduleCollection(); + this.system = this.api.subSystem("performance", "Performance data published by the web application"); + } + scheduleCollection() { + setTimeout(() => { + this.collect(); + setInterval(() => { + this.collect(); + }, this.publishInterval); + }, this.initialPublishTimeout); + } + collect() { + try { + this.collectMemory(); + this.collectEntries(); + } + catch { + } + } + collectMemory() { + const memory = window.performance.memory; + this.system.stringMetric("memory", JSON.stringify({ + totalJSHeapSize: memory.totalJSHeapSize, + usedJSHeapSize: memory.usedJSHeapSize + })); + } + collectEntries() { + const allEntries = window.performance.getEntries(); + if (allEntries.length <= this.lastCount) { + return; + } + this.lastCount = allEntries.length; + const jsonfiedEntries = allEntries.map((i) => i.toJSON()); + this.system.stringMetric("entries", JSON.stringify(jsonfiedEntries)); + } + } + + var metrics = (options) => { + let protocol; + if (!options.connection || typeof options.connection !== "object") { + protocol = new NullProtocol(); + } + else { + protocol = gw3(options.connection, options); + } + const repo = new Repository(options, protocol); + let rootSystem = repo.root; + if (!options.disableAutoAppSystem) { + rootSystem = rootSystem.subSystem("App"); + } + const api = addFAVSupport(rootSystem); + initPerf(api, options.pagePerformanceMetrics); + return api; + }; + function initPerf(api, config) { + if (typeof window === "undefined") { + return; + } + const perfConfig = window?.glue42gd?.metrics?.pagePerformanceMetrics; + if (perfConfig) { + config = perfConfig; + } + if (config?.enabled) { + new PerfTracker(api, config.initialPublishTimeout, config.publishInterval); + } + } + function addFAVSupport(system) { + const reportingSystem = system.subSystem("reporting"); + const def = { + name: "features" + }; + let featureMetric; + const featureMetricFunc = (name, action, payload) => { + if (typeof name === "undefined" || name === "") { + throw new Error("name is mandatory"); + } + else if (typeof action === "undefined" || action === "") { + throw new Error("action is mandatory"); + } + else if (typeof payload === "undefined" || payload === "") { + throw new Error("payload is mandatory"); + } + if (!featureMetric) { + featureMetric = reportingSystem.objectMetric(def, { name, action, payload }); + } + else { + featureMetric.update({ + name, + action, + payload + }); + } + }; + system.featureMetric = featureMetricFunc; + return system; + } + + var commonjsGlobal$1 = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; + + function getDefaultExportFromCjs$1 (x) { + return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; + } + + function createRegistry$1(options) { + if (options && options.errorHandling + && typeof options.errorHandling !== "function" + && options.errorHandling !== "log" + && options.errorHandling !== "silent" + && options.errorHandling !== "throw") { + throw new Error("Invalid options passed to createRegistry. Prop errorHandling should be [\"log\" | \"silent\" | \"throw\" | (err) => void], but " + typeof options.errorHandling + " was passed"); + } + var _userErrorHandler = options && typeof options.errorHandling === "function" && options.errorHandling; + var callbacks = {}; + function add(key, callback, replayArgumentsArr) { + var callbacksForKey = callbacks[key]; + if (!callbacksForKey) { + callbacksForKey = []; + callbacks[key] = callbacksForKey; + } + callbacksForKey.push(callback); + if (replayArgumentsArr) { + setTimeout(function () { + replayArgumentsArr.forEach(function (replayArgument) { + var _a; + if ((_a = callbacks[key]) === null || _a === void 0 ? void 0 : _a.includes(callback)) { + try { + if (Array.isArray(replayArgument)) { + callback.apply(undefined, replayArgument); + } + else { + callback.apply(undefined, [replayArgument]); + } + } + catch (err) { + _handleError(err, key); + } + } + }); + }, 0); + } + return function () { + var allForKey = callbacks[key]; + if (!allForKey) { + return; + } + allForKey = allForKey.reduce(function (acc, element, index) { + if (!(element === callback && acc.length === index)) { + acc.push(element); + } + return acc; + }, []); + if (allForKey.length === 0) { + delete callbacks[key]; + } + else { + callbacks[key] = allForKey; + } + }; + } + function execute(key) { + var argumentsArr = []; + for (var _i = 1; _i < arguments.length; _i++) { + argumentsArr[_i - 1] = arguments[_i]; + } + var callbacksForKey = callbacks[key]; + if (!callbacksForKey || callbacksForKey.length === 0) { + return []; + } + var results = []; + callbacksForKey.forEach(function (callback) { + try { + var result = callback.apply(undefined, argumentsArr); + results.push(result); + } + catch (err) { + results.push(undefined); + _handleError(err, key); + } + }); + return results; + } + function _handleError(exceptionArtifact, key) { + var errParam = exceptionArtifact instanceof Error ? exceptionArtifact : new Error(exceptionArtifact); + if (_userErrorHandler) { + _userErrorHandler(errParam); + return; + } + var msg = "[ERROR] callback-registry: User callback for key \"" + key + "\" failed: " + errParam.stack; + if (options) { + switch (options.errorHandling) { + case "log": + return console.error(msg); + case "silent": + return; + case "throw": + throw new Error(msg); + } + } + console.error(msg); + } + function clear() { + callbacks = {}; + } + function clearKey(key) { + var callbacksForKey = callbacks[key]; + if (!callbacksForKey) { + return; + } + delete callbacks[key]; + } + return { + add: add, + execute: execute, + clear: clear, + clearKey: clearKey + }; + } + createRegistry$1.default = createRegistry$1; + var lib$1 = createRegistry$1; + + + var CallbackRegistryFactory$1 = /*@__PURE__*/getDefaultExportFromCjs$1(lib$1); + + class InProcTransport { + gw; + registry = CallbackRegistryFactory$1(); + client; + constructor(settings, logger) { + this.gw = settings.facade; + this.gw.connect((_client, message) => { + this.messageHandler(message); + }).then((client) => { + this.client = client; + }); + } + get isObjectBasedTransport() { + return true; + } + sendObject(msg) { + if (this.client) { + this.client.send(msg); + return Promise.resolve(undefined); + } + else { + return Promise.reject(`not connected`); + } + } + send(_msg) { + return Promise.reject("not supported"); + } + onMessage(callback) { + return this.registry.add("onMessage", callback); + } + onConnectedChanged(callback) { + callback(true); + return () => { }; + } + close() { + return Promise.resolve(); + } + open() { + return Promise.resolve(); + } + name() { + return "in-memory"; + } + reconnect() { + return Promise.resolve(); + } + messageHandler(msg) { + this.registry.execute("onMessage", msg); + } + } + + class SharedWorkerTransport { + logger; + worker; + registry = CallbackRegistryFactory$1(); + constructor(workerFile, logger) { + this.logger = logger; + this.worker = new SharedWorker(workerFile); + this.worker.port.onmessage = (e) => { + this.messageHandler(e.data); + }; + } + get isObjectBasedTransport() { + return true; + } + sendObject(msg) { + this.worker.port.postMessage(msg); + return Promise.resolve(); + } + send(_msg) { + return Promise.reject("not supported"); + } + onMessage(callback) { + return this.registry.add("onMessage", callback); + } + onConnectedChanged(callback) { + callback(true); + return () => { }; + } + close() { + return Promise.resolve(); + } + open() { + return Promise.resolve(); + } + name() { + return "shared-worker"; + } + reconnect() { + return Promise.resolve(); + } + messageHandler(msg) { + this.registry.execute("onMessage", msg); + } + } + + let Utils$1 = class Utils { + static isNode() { + if (typeof Utils._isNode !== "undefined") { + return Utils._isNode; + } + if (typeof window !== "undefined") { + Utils._isNode = false; + return false; + } + try { + Utils._isNode = Object.prototype.toString.call(global.process) === "[object process]"; + } + catch (e) { + Utils._isNode = false; + } + return Utils._isNode; + } + static _isNode; + }; + + let PromiseWrapper$1 = class PromiseWrapper { + static delay(time) { + return new Promise((resolve) => setTimeout(resolve, time)); + } + resolve; + reject; + promise; + rejected = false; + resolved = false; + get ended() { + return this.rejected || this.resolved; + } + constructor() { + this.promise = new Promise((resolve, reject) => { + this.resolve = (t) => { + this.resolved = true; + resolve(t); + }; + this.reject = (err) => { + this.rejected = true; + reject(err); + }; + }); + } + }; + + const timers = {}; + function getAllTimers() { + return timers; + } + function timer (timerName) { + const existing = timers[timerName]; + if (existing) { + return existing; + } + const marks = []; + function now() { + return new Date().getTime(); + } + const startTime = now(); + mark("start", startTime); + let endTime; + let period; + function stop() { + endTime = now(); + mark("end", endTime); + period = endTime - startTime; + return period; + } + function mark(name, time) { + const currentTime = time ?? now(); + let diff = 0; + if (marks.length > 0) { + diff = currentTime - marks[marks.length - 1].time; + } + marks.push({ name, time: currentTime, diff }); + } + const timerObj = { + get startTime() { + return startTime; + }, + get endTime() { + return endTime; + }, + get period() { + return period; + }, + stop, + mark, + marks + }; + timers[timerName] = timerObj; + return timerObj; + } + + const WebSocketConstructor = Utils$1.isNode() ? require("ws") : window.WebSocket; + class WS { + ws; + logger; + settings; + startupTimer = timer("connection"); + _running = true; + _registry = CallbackRegistryFactory$1(); + wsRequests = []; + constructor(settings, logger) { + this.settings = settings; + this.logger = logger; + if (!this.settings.ws) { + throw new Error("ws is missing"); + } + } + onMessage(callback) { + return this._registry.add("onMessage", callback); + } + send(msg, options) { + return new Promise((resolve, reject) => { + this.waitForSocketConnection(() => { + try { + this.ws?.send(msg); + resolve(); + } + catch (e) { + reject(e); + } + }, reject); + }); + } + open() { + this.logger.info("opening ws..."); + this._running = true; + return new Promise((resolve, reject) => { + this.waitForSocketConnection(resolve, reject); + }); + } + close() { + this._running = false; + if (this.ws) { + this.ws.close(); + } + return Promise.resolve(); + } + onConnectedChanged(callback) { + return this._registry.add("onConnectedChanged", callback); + } + name() { + return this.settings.ws; + } + reconnect() { + this.ws?.close(); + const pw = new PromiseWrapper$1(); + this.waitForSocketConnection(() => { + pw.resolve(); + }); + return pw.promise; + } + waitForSocketConnection(callback, failed) { + failed = failed ?? (() => { }); + if (!this._running) { + failed(`wait for socket on ${this.settings.ws} failed - socket closed by user`); + return; + } + if (this.ws?.readyState === 1) { + callback(); + return; + } + this.wsRequests.push({ callback, failed }); + if (this.wsRequests.length > 1) { + return; + } + this.openSocket(); + } + async openSocket(retryInterval, retriesLeft) { + this.logger.info(`opening ws to ${this.settings.ws}, retryInterval: ${retryInterval}, retriesLeft: ${retriesLeft}...`); + this.startupTimer.mark("opening-socket"); + if (retryInterval === undefined) { + retryInterval = this.settings.reconnectInterval; + } + if (typeof retriesLeft === "undefined") { + retriesLeft = this.settings.reconnectAttempts; + } + if (retriesLeft !== undefined) { + if (retriesLeft === 0) { + this.notifyForSocketState(`wait for socket on ${this.settings.ws} failed - no more retries left`); + return; + } + this.logger.debug(`will retry ${retriesLeft} more times (every ${retryInterval} ms)`); + } + try { + await this.initiateSocket(); + this.startupTimer.mark("socket-initiated"); + this.notifyForSocketState(); + } + catch { + setTimeout(() => { + const retries = retriesLeft === undefined ? undefined : retriesLeft - 1; + this.openSocket(retryInterval, retries); + }, retryInterval); + } + } + initiateSocket() { + const pw = new PromiseWrapper$1(); + this.logger.debug(`initiating ws to ${this.settings.ws}...`); + this.ws = new WebSocketConstructor(this.settings.ws ?? ""); + this.ws.onerror = (err) => { + let reason = ""; + try { + reason = JSON.stringify(err); + } + catch (error) { + const seen = new WeakSet(); + const replacer = (key, value) => { + if (typeof value === "object" && value !== null) { + if (seen.has(value)) { + return; + } + seen.add(value); + } + return value; + }; + reason = JSON.stringify(err, replacer); + } + this.logger.info(`ws error - reason: ${reason}`); + pw.reject("error"); + this.notifyStatusChanged(false, reason); + }; + this.ws.onclose = (err) => { + this.logger.info(`ws closed - code: ${err?.code} reason: ${err?.reason}`); + pw.reject("closed"); + this.notifyStatusChanged(false); + }; + this.ws.onopen = () => { + this.startupTimer.mark("ws-opened"); + this.logger.info(`ws opened ${this.settings.identity?.application}`); + pw.resolve(); + this.notifyStatusChanged(true); + }; + this.ws.onmessage = (message) => { + this._registry.execute("onMessage", message.data); + }; + return pw.promise; + } + notifyForSocketState(error) { + this.wsRequests.forEach((wsRequest) => { + if (error) { + if (wsRequest.failed) { + wsRequest.failed(error); + } + } + else { + wsRequest.callback(); + } + }); + this.wsRequests = []; + } + notifyStatusChanged(status, reason) { + this._registry.execute("onConnectedChanged", status, reason); + } + } + + class MessageReplayerImpl { + specs; + specsNames = []; + messages = {}; + isDone; + subs = {}; + subsRefCount = {}; + connection; + constructor(specs) { + this.specs = {}; + for (const spec of specs) { + this.specs[spec.name] = spec; + this.specsNames.push(spec.name); + } + } + init(connection) { + this.connection = connection; + for (const name of this.specsNames) { + for (const type of this.specs[name].types) { + let refCount = this.subsRefCount[type]; + if (!refCount) { + refCount = 0; + } + refCount += 1; + this.subsRefCount[type] = refCount; + if (refCount > 1) { + continue; + } + const sub = connection.on(type, (msg) => this.processMessage(type, msg)); + this.subs[type] = sub; + } + } + } + processMessage(type, msg) { + if (this.isDone || !msg) { + return; + } + for (const name of this.specsNames) { + if (this.specs[name].types.indexOf(type) !== -1) { + const messages = this.messages[name] || []; + this.messages[name] = messages; + messages.push(msg); + } + } + } + drain(name, callback) { + if (callback) { + (this.messages[name] || []).forEach(callback); + } + delete this.messages[name]; + for (const type of this.specs[name].types) { + this.subsRefCount[type] -= 1; + if (this.subsRefCount[type] <= 0) { + this.connection?.off(this.subs[type]); + delete this.subs[type]; + delete this.subsRefCount[type]; + } + } + delete this.specs[name]; + if (!this.specs.length) { + this.isDone = true; + } + } + } + + let urlAlphabet$1 = + 'useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict'; + let nanoid$1 = (size = 21) => { + let id = ''; + let i = size; + while (i--) { + id += urlAlphabet$1[(Math.random() * 64) | 0]; + } + return id + }; + + const PromisePlus$1 = (executor, timeoutMilliseconds, timeoutMessage) => { + return new Promise((resolve, reject) => { + const timeout = setTimeout(() => { + const message = timeoutMessage || `Promise timeout hit: ${timeoutMilliseconds}`; + reject(message); + }, timeoutMilliseconds); + const providedPromise = new Promise(executor); + providedPromise + .then((result) => { + clearTimeout(timeout); + resolve(result); + }) + .catch((error) => { + clearTimeout(timeout); + reject(error); + }); + }); + }; + + class WebPlatformTransport { + settings; + logger; + identity; + isPreferredActivated; + _communicationId; + publicWindowId; + selfAssignedWindowId; + iAmConnected = false; + parentReady = false; + rejected = false; + parentPingResolve; + parentPingInterval; + connectionResolve; + extConnectionResolve; + extConnectionReject; + connectionReject; + port; + myClientId; + children = []; + extContentAvailable = false; + extContentConnecting = false; + extContentConnected = false; + parentWindowId; + parentInExtMode = false; + webNamespace = "g42_core_web"; + parent; + parentType; + parentPingTimeout = 5000; + connectionRequestTimeout = 7000; + defaultTargetString = "*"; + registry = CallbackRegistryFactory$1(); + messages = { + connectionAccepted: { name: "connectionAccepted", handle: this.handleConnectionAccepted.bind(this) }, + connectionRejected: { name: "connectionRejected", handle: this.handleConnectionRejected.bind(this) }, + connectionRequest: { name: "connectionRequest", handle: this.handleConnectionRequest.bind(this) }, + parentReady: { + name: "parentReady", handle: () => { + } + }, + parentPing: { name: "parentPing", handle: this.handleParentPing.bind(this) }, + platformPing: { name: "platformPing", handle: this.handlePlatformPing.bind(this) }, + platformReady: { name: "platformReady", handle: this.handlePlatformReady.bind(this) }, + clientUnload: { name: "clientUnload", handle: this.handleClientUnload.bind(this) }, + manualUnload: { name: "manualUnload", handle: this.handleManualUnload.bind(this) }, + extConnectionResponse: { name: "extConnectionResponse", handle: this.handleExtConnectionResponse.bind(this) }, + extSetupRequest: { name: "extSetupRequest", handle: this.handleExtSetupRequest.bind(this) }, + gatewayDisconnect: { name: "gatewayDisconnect", handle: this.handleGatewayDisconnect.bind(this) }, + gatewayInternalConnect: { name: "gatewayInternalConnect", handle: this.handleGatewayInternalConnect.bind(this) } + }; + constructor(settings, logger, identity) { + this.settings = settings; + this.logger = logger; + this.identity = identity; + this.extContentAvailable = !!window.glue42ext; + this.setUpMessageListener(); + this.setUpUnload(); + this.setupPlatformUnloadListener(); + this.parentType = window.name.includes("#wsp") ? "workspace" : undefined; + } + manualSetReadyState() { + this.iAmConnected = true; + this.parentReady = true; + } + get transportWindowId() { + return this.publicWindowId; + } + get communicationId() { + return this._communicationId; + } + async sendObject(msg) { + if (this.extContentConnected) { + return window.postMessage({ glue42ExtOut: msg }, this.defaultTargetString); + } + if (!this.port) { + throw new Error("Cannot send message, because the port was not opened yet"); + } + this.port.postMessage(msg); + } + get isObjectBasedTransport() { + return true; + } + onMessage(callback) { + return this.registry.add("onMessage", callback); + } + send() { + return Promise.reject("not supported"); + } + onConnectedChanged(callback) { + return this.registry.add("onConnectedChanged", callback); + } + async open() { + this.logger.debug("opening a connection to the web platform gateway."); + await this.connect(); + this.notifyStatusChanged(true); + } + close() { + const message = { + glue42core: { + type: this.messages.gatewayDisconnect.name, + data: { + clientId: this.myClientId, + ownWindowId: this.identity?.windowId + } + } + }; + this.port?.postMessage(message); + this.parentReady = false; + this.notifyStatusChanged(false, "manual reconnection"); + return Promise.resolve(); + } + name() { + return "web-platform"; + } + async reconnect() { + await this.close(); + return Promise.resolve(); + } + initiateInternalConnection() { + return new Promise((resolve, reject) => { + this.logger.debug("opening an internal web platform connection"); + this.port = this.settings.port; + if (this.iAmConnected) { + this.logger.warn("cannot open a new connection, because this client is currently connected"); + return; + } + this.port.onmessage = (event) => { + if (this.iAmConnected && !event.data?.glue42core) { + this.registry.execute("onMessage", event.data); + return; + } + const data = event.data?.glue42core; + if (!data) { + return; + } + if (data.type === this.messages.gatewayInternalConnect.name && data.success) { + this.publicWindowId = this.settings.windowId; + if (this.identity && this.publicWindowId) { + this.identity.windowId = this.publicWindowId; + this.identity.instance = this.publicWindowId; + } + resolve(); + } + if (data.type === this.messages.gatewayInternalConnect.name && data.error) { + reject(data.error); + } + }; + this.port.postMessage({ + glue42core: { + type: this.messages.gatewayInternalConnect.name + } + }); + }); + } + initiateRemoteConnection(target) { + return PromisePlus$1((resolve, reject) => { + this.connectionResolve = resolve; + this.connectionReject = reject; + this.myClientId = this.myClientId ?? nanoid$1(10); + const bridgeInstanceId = this.getMyWindowId() || nanoid$1(10); + const request = { + glue42core: { + type: this.messages.connectionRequest.name, + clientId: this.myClientId, + clientType: "child", + bridgeInstanceId, + selfAssignedWindowId: this.selfAssignedWindowId + } + }; + this.logger.debug("sending connection request"); + if (this.extContentConnecting) { + request.glue42core.clientType = "child"; + request.glue42core.bridgeInstanceId = this.myClientId; + request.glue42core.parentWindowId = this.parentWindowId; + return window.postMessage(request, this.defaultTargetString); + } + if (!target) { + throw new Error("Cannot send a connection request, because no glue target was specified!"); + } + target.postMessage(request, this.defaultTargetString); + }, this.connectionRequestTimeout, "The connection to the target glue window timed out"); + } + async isParentCheckSuccess(parentCheck) { + try { + await parentCheck; + return { success: true }; + } + catch (error) { + return { success: false }; + } + } + setUpMessageListener() { + if (this.settings.port) { + this.logger.debug("skipping generic message listener, because this is an internal client"); + return; + } + window.addEventListener("message", (event) => { + const data = event.data?.glue42core; + if (!data || this.rejected) { + return; + } + const allowedOrigins = this.settings.allowedOrigins || []; + if (allowedOrigins.length && !allowedOrigins.includes(event.origin)) { + this.logger.warn(`received a message from an origin which is not in the allowed list: ${event.origin}`); + return; + } + if (!this.checkMessageTypeValid(data.type)) { + this.logger.error(`cannot handle the incoming glue42 core message, because the type is invalid: ${data.type}`); + return; + } + const messageType = data.type; + this.logger.debug(`received valid glue42core message of type: ${messageType}`); + this.messages[messageType].handle(event); + }); + } + setUpUnload() { + if (this.settings.port) { + this.logger.debug("skipping unload event listener, because this is an internal client"); + return; + } + window.addEventListener("beforeunload", () => { + if (this.extContentConnected) { + return; + } + const message = { + glue42core: { + type: this.messages.clientUnload.name, + data: { + clientId: this.myClientId, + ownWindowId: this.identity?.windowId + } + } + }; + if (this.parent) { + this.parent.postMessage(message, this.defaultTargetString); + } + this.port?.postMessage(message); + }); + } + handlePlatformReady(event) { + this.logger.debug("the web platform gave the ready signal"); + this.parentReady = true; + if (this.parentPingResolve) { + this.parentPingResolve(); + delete this.parentPingResolve; + } + if (this.parentPingInterval) { + clearInterval(this.parentPingInterval); + delete this.parentPingInterval; + } + this.parent = event.source; + this.parentType = window.name.includes("#wsp") ? "workspace" : "window"; + } + handleConnectionAccepted(event) { + const data = event.data?.glue42core; + if (this.myClientId === data.clientId) { + return this.handleAcceptanceOfMyRequest(data); + } + return this.handleAcceptanceOfGrandChildRequest(data, event); + } + handleAcceptanceOfMyRequest(data) { + this.logger.debug("handling a connection accepted signal targeted at me."); + this.isPreferredActivated = data.isPreferredActivated; + if (this.extContentConnecting) { + return this.processExtContentConnection(data); + } + if (!data.port) { + this.logger.error("cannot set up my connection, because I was not provided with a port"); + return; + } + this.publicWindowId = this.getMyWindowId(); + if (this.identity) { + this.identity.windowId = this.publicWindowId; + this.identity.instance = this.identity.instance ? this.identity.instance : this.publicWindowId || nanoid$1(10); + } + if (this.identity && data.appName) { + this.identity.application = data.appName; + this.identity.applicationName = data.appName; + } + this._communicationId = data.communicationId; + this.port = data.port; + this.port.onmessage = (e) => this.registry.execute("onMessage", e.data); + if (this.connectionResolve) { + this.logger.debug("my connection is set up, calling the connection resolve."); + this.connectionResolve(); + delete this.connectionResolve; + return; + } + this.logger.error("unable to call the connection resolve, because no connection promise was found"); + } + processExtContentConnection(data) { + this.logger.debug("handling a connection accepted signal targeted at me for extension content connection."); + this.extContentConnecting = false; + this.extContentConnected = true; + this.publicWindowId = this.parentWindowId || this.myClientId; + if (this.extContentConnecting && this.identity) { + this.identity.windowId = this.publicWindowId; + } + if (this.identity && data.appName) { + this.identity.application = data.appName; + this.identity.applicationName = data.appName; + } + window.addEventListener("message", (event) => { + const extData = event.data?.glue42ExtInc; + if (!extData) { + return; + } + const allowedOrigins = this.settings.allowedOrigins || []; + if (allowedOrigins.length && !allowedOrigins.includes(event.origin)) { + this.logger.warn(`received a message from an origin which is not in the allowed list: ${event.origin}`); + return; + } + this.registry.execute("onMessage", extData); + }); + if (this.connectionResolve) { + this.logger.debug("my connection is set up, calling the connection resolve."); + this.connectionResolve(); + delete this.connectionResolve; + return; + } + } + handleAcceptanceOfGrandChildRequest(data, event) { + if (this.extContentConnecting || this.extContentConnected) { + this.logger.debug("cannot process acceptance of a grandchild, because I am connected to a content script"); + return; + } + this.logger.debug(`handling a connection accepted signal targeted at a grandchild: ${data.clientId}`); + const child = this.children.find((c) => c.grandChildId === data.clientId); + if (!child) { + this.logger.error(`cannot handle connection accepted for grandchild: ${data.clientId}, because there is no grandchild with this id`); + return; + } + child.connected = true; + this.logger.debug(`the grandchild connection for ${data.clientId} is set up, forwarding the success message and the gateway port`); + data.parentWindowId = this.publicWindowId; + child.source.postMessage(event.data, child.origin, [data.port]); + return; + } + handleConnectionRejected(event) { + this.logger.debug("handling a connection rejection. Most likely the reason is that this window was not created by a glue API call"); + if (!this.connectionReject) { + return; + } + const errorMsg = typeof event.data.glue42core?.error === "string" + ? `Connection was rejected. ${event.data.glue42core?.error}` + : "The platform connection was rejected. Most likely because this window was not created by a glue API call"; + this.connectionReject(errorMsg); + delete this.connectionReject; + } + handleConnectionRequest(event) { + if (this.extContentConnecting) { + this.logger.debug("This connection request event is targeted at the extension content"); + return; + } + const source = event.source; + const data = event.data.glue42core; + if (!data.clientType || data.clientType !== "grandChild") { + return this.rejectConnectionRequest(source, event.origin, "rejecting a connection request, because the source was not opened by a glue API call"); + } + if (!data.clientId) { + return this.rejectConnectionRequest(source, event.origin, "rejecting a connection request, because the source did not provide a valid id"); + } + if (!this.parent) { + return this.rejectConnectionRequest(source, event.origin, "Cannot forward the connection request, because no direct connection to the platform was found"); + } + this.logger.debug(`handling a connection request for a grandchild: ${data.clientId}`); + this.children.push({ grandChildId: data.clientId, source, connected: false, origin: event.origin }); + this.logger.debug(`grandchild: ${data.clientId} is prepared, forwarding connection request to the platform`); + this.parent.postMessage(event.data, this.defaultTargetString); + } + handleParentPing(event) { + if (!this.parentReady) { + this.logger.debug("my parent is not ready, I am ignoring the parent ping"); + return; + } + if (!this.iAmConnected) { + this.logger.debug("i am not fully connected yet, I am ignoring the parent ping"); + return; + } + const message = { + glue42core: { + type: this.messages.parentReady.name + } + }; + if (this.extContentConnected) { + message.glue42core.extMode = { windowId: this.myClientId }; + } + const source = event.source; + this.logger.debug("responding to a parent ping with a ready message"); + source.postMessage(message, event.origin); + } + setupPlatformUnloadListener() { + this.onMessage((msg) => { + if (msg.type === "platformUnload") { + this.logger.debug("detected a web platform unload"); + this.parentReady = false; + this.notifyStatusChanged(false, "Gateway unloaded"); + } + }); + } + handleManualUnload() { + const message = { + glue42core: { + type: this.messages.clientUnload.name, + data: { + clientId: this.myClientId, + ownWindowId: this.identity?.windowId + } + } + }; + if (this.extContentConnected) { + return window.postMessage({ glue42ExtOut: message }, this.defaultTargetString); + } + this.port?.postMessage(message); + } + handleClientUnload(event) { + const data = event.data.glue42core; + const clientId = data?.data.clientId; + if (!clientId) { + this.logger.warn("cannot process grand child unload, because the provided id was not valid"); + return; + } + const foundChild = this.children.find((child) => child.grandChildId === clientId); + if (!foundChild) { + this.logger.warn("cannot process grand child unload, because this client is unaware of this grandchild"); + return; + } + this.logger.debug(`handling grandchild unload for id: ${clientId}`); + this.children = this.children.filter((child) => child.grandChildId !== clientId); + } + handlePlatformPing() { + return; + } + notifyStatusChanged(status, reason) { + this.iAmConnected = status; + this.registry.execute("onConnectedChanged", status, reason); + } + checkMessageTypeValid(typeToValidate) { + return typeof typeToValidate === "string" && !!this.messages[typeToValidate]; + } + rejectConnectionRequest(source, origin, reason) { + this.rejected = true; + this.logger.error(reason); + const rejection = { + glue42core: { + type: this.messages.connectionRejected.name + } + }; + source.postMessage(rejection, origin); + } + requestConnectionPermissionFromExt() { + return this.waitForContentScript() + .then(() => PromisePlus$1((resolve, reject) => { + this.extConnectionResolve = resolve; + this.extConnectionReject = reject; + const message = { + glue42core: { + type: "extSetupRequest" + } + }; + this.logger.debug("permission request to the extension content script was sent"); + window.postMessage(message, this.defaultTargetString); + }, this.parentPingTimeout, "Cannot initialize glue, because this app was not opened or created by a Glue Client and the request for extension connection timed out")); + } + handleExtConnectionResponse(event) { + const data = event.data?.glue42core; + if (!data.approved) { + return this.extConnectionReject ? this.extConnectionReject("Cannot initialize glue, because this app was not opened or created by a Glue Client and the request for extension connection was rejected") : undefined; + } + if (this.extConnectionResolve) { + this.extConnectionResolve(); + delete this.extConnectionResolve; + } + this.extContentConnecting = true; + this.parentType = "extension"; + this.logger.debug("The extension connection was approved, proceeding."); + } + handleExtSetupRequest() { + return; + } + handleGatewayDisconnect() { + return; + } + handleGatewayInternalConnect() { + return; + } + waitForContentScript() { + const contentReady = !!window.glue42ext?.content; + if (contentReady) { + return Promise.resolve(); + } + return PromisePlus$1((resolve) => { + window.addEventListener("Glue42EXTReady", () => { + resolve(); + }); + }, this.connectionRequestTimeout, "The content script was available, but was never heard to be ready"); + } + async connect() { + if (this.settings.port) { + await this.initiateInternalConnection(); + this.logger.debug("internal web platform connection completed"); + return; + } + this.logger.debug("opening a client web platform connection"); + await this.findParent(); + await this.initiateRemoteConnection(this.parent); + this.logger.debug("the client is connected"); + } + async findParent() { + const connectionNotPossibleMsg = "Cannot initiate glue, because this window was not opened or created by a glue client"; + const myInsideParents = this.getPossibleParentsInWindow(window); + const myOutsideParents = this.getPossibleParentsOutsideWindow(window.top?.opener, window.top); + const uniqueParents = new Set([...myInsideParents, ...myOutsideParents]); + if (!uniqueParents.size && !this.extContentAvailable) { + throw new Error(connectionNotPossibleMsg); + } + if (!uniqueParents.size && this.extContentAvailable) { + await this.requestConnectionPermissionFromExt(); + return; + } + const defaultParentCheck = await this.isParentCheckSuccess(this.confirmParent(Array.from(uniqueParents))); + if (defaultParentCheck.success) { + this.logger.debug("The default parent was found!"); + return; + } + if (!this.extContentAvailable) { + throw new Error(connectionNotPossibleMsg); + } + await this.requestConnectionPermissionFromExt(); + } + getPossibleParentsInWindow(currentWindow) { + return (!currentWindow?.parent || currentWindow === currentWindow.parent) ? [] : [currentWindow.parent, ...this.getPossibleParentsInWindow(currentWindow.parent)]; + } + getPossibleParentsOutsideWindow(opener, current) { + return (!opener || !current || opener === current) ? [] : [opener, ...this.getPossibleParentsInWindow(opener), ...this.getPossibleParentsOutsideWindow(opener.opener, opener)]; + } + confirmParent(targets) { + const connectionNotPossibleMsg = "Cannot initiate glue, because this window was not opened or created by a glue client"; + const parentCheck = PromisePlus$1((resolve) => { + this.parentPingResolve = resolve; + const message = { + glue42core: { + type: this.messages.platformPing.name + } + }; + this.parentPingInterval = setInterval(() => { + targets.forEach((target) => { + target.postMessage(message, this.defaultTargetString); + }); + }, 1000); + }, this.parentPingTimeout, connectionNotPossibleMsg); + parentCheck.catch(() => { + if (this.parentPingInterval) { + clearInterval(this.parentPingInterval); + delete this.parentPingInterval; + } + }); + return parentCheck; + } + getMyWindowId() { + if (this.parentType === "workspace") { + return window.name.substring(0, window.name.indexOf("#wsp")); + } + if (window !== window.top) { + return; + } + if (window.name?.includes("g42")) { + return window.name; + } + this.selfAssignedWindowId = this.selfAssignedWindowId || `g42-${nanoid$1(10)}`; + return this.selfAssignedWindowId; + } + } + + const waitForInvocations = (invocations, callback) => { + let left = invocations; + return () => { + left--; + if (left === 0) { + callback(); + } + }; + }; + + class AsyncSequelizer { + minSequenceInterval; + queue = []; + isExecutingQueue = false; + constructor(minSequenceInterval = 0) { + this.minSequenceInterval = minSequenceInterval; + } + enqueue(action) { + return new Promise((resolve, reject) => { + this.queue.push({ action, resolve, reject }); + this.executeQueue(); + }); + } + async executeQueue() { + if (this.isExecutingQueue) { + return; + } + this.isExecutingQueue = true; + while (this.queue.length) { + const operation = this.queue.shift(); + if (!operation) { + this.isExecutingQueue = false; + return; + } + try { + const actionResult = await operation.action(); + operation.resolve(actionResult); + } + catch (error) { + operation.reject(error); + } + await this.intervalBreak(); + } + this.isExecutingQueue = false; + } + intervalBreak() { + return new Promise((res) => setTimeout(res, this.minSequenceInterval)); + } + } + + function domainSession (domain, connection, logger, successMessages, errorMessages) { + if (domain == null) { + domain = "global"; + } + successMessages = successMessages ?? ["success"]; + errorMessages = errorMessages ?? ["error"]; + let isJoined = domain === "global"; + let tryReconnecting = false; + let _latestOptions; + let _connectionOn = false; + const callbacks = CallbackRegistryFactory$1(); + connection.disconnected(handleConnectionDisconnected); + connection.loggedIn(handleConnectionLoggedIn); + connection.on("success", (msg) => handleSuccessMessage(msg)); + connection.on("error", (msg) => handleErrorMessage(msg)); + connection.on("result", (msg) => handleSuccessMessage(msg)); + if (successMessages) { + successMessages.forEach((sm) => { + connection.on(sm, (msg) => handleSuccessMessage(msg)); + }); + } + if (errorMessages) { + errorMessages.forEach((sm) => { + connection.on(sm, (msg) => handleErrorMessage(msg)); + }); + } + const requestsMap = {}; + function join(options) { + _latestOptions = options; + return new Promise((resolve, reject) => { + if (isJoined) { + resolve({}); + return; + } + let joinPromise; + if (domain === "global") { + joinPromise = _connectionOn ? Promise.resolve({}) : Promise.reject("not connected to gateway"); + } + else { + logger.debug(`joining domain ${domain}`); + const joinMsg = { + type: "join", + destination: domain, + domain: "global", + options, + }; + joinPromise = send(joinMsg); + } + joinPromise + .then(() => { + handleJoined(); + resolve({}); + }) + .catch((err) => { + logger.debug("error joining " + domain + " domain: " + JSON.stringify(err)); + reject(err); + }); + }); + } + function leave() { + if (domain === "global") { + return Promise.resolve(); + } + logger.debug("stopping session " + domain + "..."); + const leaveMsg = { + type: "leave", + destination: domain, + domain: "global", + }; + tryReconnecting = false; + return send(leaveMsg) + .then(() => { + isJoined = false; + callbacks.execute("onLeft"); + }) + .catch(() => { + isJoined = false; + callbacks.execute("onLeft"); + }); + } + function handleJoined() { + logger.debug("did join " + domain); + isJoined = true; + const wasReconnect = tryReconnecting; + tryReconnecting = false; + callbacks.execute("onJoined", wasReconnect); + } + function handleConnectionDisconnected() { + _connectionOn = false; + logger.debug("connection is down"); + isJoined = false; + tryReconnecting = true; + callbacks.execute("onLeft", { disconnected: true }); + } + function handleConnectionLoggedIn() { + _connectionOn = true; + if (tryReconnecting) { + logger.debug("connection is now up - trying to reconnect..."); + join(_latestOptions); + } + } + function onJoined(callback) { + if (isJoined) { + callback(false); + } + return callbacks.add("onJoined", callback); + } + function onLeft(callback) { + if (!isJoined) { + callback(); + } + return callbacks.add("onLeft", callback); + } + function handleErrorMessage(msg) { + if (domain !== msg.domain) { + return; + } + const requestId = msg.request_id; + if (!requestId) { + return; + } + const entry = requestsMap[requestId]; + if (!entry) { + return; + } + entry.error(msg); + } + function handleSuccessMessage(msg) { + if (msg.domain !== domain) { + return; + } + const requestId = msg.request_id; + if (!requestId) { + return; + } + const entry = requestsMap[requestId]; + if (!entry) { + return; + } + entry.success(msg); + } + function getNextRequestId() { + return nanoid$1(10); + } + let queuedCalls = []; + function send(msg, tag, options) { + const ignore = ["hello", "join"]; + if (msg.type && ignore.indexOf(msg.type) === -1) { + if (!isJoined) { + console.warn(`trying to send a message (${msg.domain} ${msg.type}) but not connected, will queue`); + const pw = new PromiseWrapper$1(); + queuedCalls.push({ msg, tag, options, pw }); + if (queuedCalls.length === 1) { + const unsubscribe = onJoined(() => { + logger.info(`joined - will now send queued messages (${queuedCalls.length} -> [${queuedCalls.map((m) => m.msg.type)}])`); + queuedCalls.forEach((qm) => { + send(qm.msg, qm.tag, qm.options) + .then((t) => qm.pw.resolve(t)) + .catch((e) => qm.pw.reject(e)); + }); + queuedCalls = []; + unsubscribe(); + }); + } + return pw.promise; + } + } + options = options ?? {}; + msg.request_id = msg.request_id ?? getNextRequestId(); + msg.domain = msg.domain ?? domain; + if (!options.skipPeerId) { + msg.peer_id = connection.peerId; + } + const requestId = msg.request_id; + return new Promise((resolve, reject) => { + requestsMap[requestId] = { + success: (successMsg) => { + delete requestsMap[requestId]; + successMsg._tag = tag; + resolve(successMsg); + }, + error: (errorMsg) => { + logger.warn(`Gateway error - ${JSON.stringify(errorMsg)}`); + delete requestsMap[requestId]; + errorMsg._tag = tag; + reject(errorMsg); + }, + }; + connection + .send(msg, options) + .catch((err) => { + requestsMap[requestId].error({ err }); + }); + }); + } + function sendFireAndForget(msg) { + msg.request_id = msg.request_id ? msg.request_id : getNextRequestId(); + msg.domain = msg.domain ?? domain; + msg.peer_id = connection.peerId; + return connection.send(msg); + } + return { + join, + leave, + onJoined, + onLeft, + send, + sendFireAndForget, + on: (type, callback) => { + connection.on(type, (msg) => { + if (msg.domain !== domain) { + return; + } + try { + callback(msg); + } + catch (e) { + logger.error(`Callback failed: ${e} \n ${e.stack} \n msg was: ${JSON.stringify(msg)}`, e); + } + }); + }, + loggedIn: (callback) => connection.loggedIn(callback), + connected: (callback) => connection.connected(callback), + disconnected: (callback) => connection.disconnected(callback), + get peerId() { + return connection.peerId; + }, + get domain() { + return domain; + }, + }; + } + + class Connection { + settings; + logger; + protocolVersion = 3; + peerId; + token; + info; + resolvedIdentity; + availableDomains; + gatewayToken; + replayer; + messageHandlers = {}; + ids = 1; + registry = CallbackRegistryFactory$1(); + _connected = false; + isTrace = false; + transport; + _defaultTransport; + _defaultAuth; + _targetTransport; + _targetAuth; + _swapTransport = false; + _switchInProgress = false; + _transportSubscriptions = []; + datePrefix = "#T42_DATE#"; + datePrefixLen = this.datePrefix.length; + dateMinLen = this.datePrefixLen + 1; + datePrefixFirstChar = this.datePrefix[0]; + _sequelizer = new AsyncSequelizer(); + _isLoggedIn = false; + shouldTryLogin = true; + pingTimer; + sessions = []; + globalDomain; + initialLogin = true; + initialLoginAttempts = 3; + loginConfig; + constructor(settings, logger) { + this.settings = settings; + this.logger = logger; + settings = settings || {}; + settings.reconnectAttempts = settings.reconnectAttempts ?? 10; + settings.reconnectInterval = settings.reconnectInterval ?? 1000; + if (settings.inproc) { + this.transport = new InProcTransport(settings.inproc, logger.subLogger("inMemory")); + } + else if (settings.sharedWorker) { + this.transport = new SharedWorkerTransport(settings.sharedWorker, logger.subLogger("shared-worker")); + } + else if (settings.webPlatform) { + this.transport = new WebPlatformTransport(settings.webPlatform, logger.subLogger("web-platform"), settings.identity); + } + else if (settings.ws !== undefined) { + this.transport = new WS(settings, logger.subLogger("ws")); + } + else { + throw new Error("No connection information specified"); + } + this.isTrace = logger.canPublish("trace"); + logger.debug(`starting with ${this.transport.name()} transport`); + const unsubConnectionChanged = this.transport.onConnectedChanged(this.handleConnectionChanged.bind(this)); + const unsubOnMessage = this.transport.onMessage(this.handleTransportMessage.bind(this)); + this._transportSubscriptions.push(unsubConnectionChanged); + this._transportSubscriptions.push(unsubOnMessage); + this._defaultTransport = this.transport; + this.ping(); + } + async switchTransport(settings) { + return this._sequelizer.enqueue(async () => { + if (!settings || typeof settings !== "object") { + throw new Error("Cannot switch transports, because the settings are missing or invalid."); + } + if (typeof settings.type === "undefined") { + throw new Error("Cannot switch the transport, because the type is not defined"); + } + this.logger.trace(`Starting transport switch with settings: ${JSON.stringify(settings)}`); + const switchTargetTransport = settings.type === "secondary" ? this.getNewSecondaryTransport(settings) : this._defaultTransport; + this._targetTransport = switchTargetTransport; + this._targetAuth = settings.type === "secondary" ? this.getNewSecondaryAuth(settings) : this._defaultAuth; + const verifyPromise = this.verifyConnection(); + this._swapTransport = true; + this._switchInProgress = true; + this.logger.trace("The new transport has been set, closing the current transport"); + await this.transport.close(); + try { + await verifyPromise; + const isSwitchSuccess = this.transport === switchTargetTransport; + this.logger.info(`The reconnection after the switch was completed. Was the switch a success: ${isSwitchSuccess}`); + this._switchInProgress = false; + return { success: isSwitchSuccess }; + } + catch (error) { + this.logger.info("The reconnection after the switch timed out, reverting back to the default transport."); + this.switchTransport({ type: "default" }); + this._switchInProgress = false; + return { success: false }; + } + }); + } + onLibReAnnounced(callback) { + return this.registry.add("libReAnnounced", callback); + } + setLibReAnnounced(lib) { + this.registry.execute("libReAnnounced", lib); + } + send(message, options) { + if (this.transport.sendObject && + this.transport.isObjectBasedTransport) { + const msg = this.createObjectMessage(message); + if (this.isTrace) { + this.logger.trace(`>> ${JSON.stringify(msg)}`); + } + return this.transport.sendObject(msg, options); + } + else { + const strMessage = this.createStringMessage(message); + if (this.isTrace) { + this.logger.trace(`>> ${strMessage}`); + } + return this.transport.send(strMessage, options); + } + } + on(type, messageHandler) { + type = type.toLowerCase(); + if (this.messageHandlers[type] === undefined) { + this.messageHandlers[type] = {}; + } + const id = this.ids++; + this.messageHandlers[type][id] = messageHandler; + return { + type, + id, + }; + } + off(info) { + delete this.messageHandlers[info.type.toLowerCase()][info.id]; + } + get isConnected() { + return this._isLoggedIn; + } + connected(callback) { + return this.loggedIn(() => { + const currentServer = this.transport.name(); + callback(currentServer); + }); + } + disconnected(callback) { + return this.registry.add("disconnected", callback); + } + async login(authRequest, reconnect) { + if (!this._defaultAuth) { + this._defaultAuth = authRequest; + } + if (this._swapTransport) { + this.logger.trace("Detected a transport swap, swapping transports"); + const newAuth = this.transportSwap(); + authRequest = newAuth ?? authRequest; + } + this.logger.trace(`Starting login for transport: ${this.transport.name()} and auth ${JSON.stringify(authRequest)}`); + try { + await this.transport.open(); + this.logger.trace(`Transport: ${this.transport.name()} opened, logging in`); + timer("connection").mark("transport-opened"); + const identity = await this.loginCore(authRequest, reconnect); + this.logger.trace(`Logged in with identity: ${JSON.stringify(identity)}`); + timer("connection").mark("protocol-logged-in"); + return identity; + } + catch (error) { + if (this._switchInProgress) { + this.logger.trace("An error while logging in after a transport swap, preparing a default swap."); + this.prepareDefaultSwap(); + } + throw new Error(error); + } + } + async logout() { + await this.logoutCore(); + await this.transport.close(); + } + loggedIn(callback) { + if (this._isLoggedIn) { + callback(); + } + return this.registry.add("onLoggedIn", callback); + } + domain(domain, successMessages, errorMessages) { + let session = this.sessions.find((s) => s.domain === domain); + if (!session) { + session = domainSession(domain, this, this.logger.subLogger(`domain=${domain}`), successMessages, errorMessages); + this.sessions.push(session); + } + return session; + } + authToken() { + const createTokenReq = { + domain: "global", + type: "create-token" + }; + if (!this.globalDomain) { + return Promise.reject(new Error("no global domain session")); + } + return this.globalDomain.send(createTokenReq) + .then((res) => { + return res.token; + }); + } + reconnect() { + return this.transport.reconnect(); + } + setLoggedIn(value) { + this._isLoggedIn = value; + if (this._isLoggedIn) { + this.registry.execute("onLoggedIn"); + } + } + distributeMessage(message, type) { + const handlers = this.messageHandlers[type.toLowerCase()]; + if (handlers !== undefined) { + Object.keys(handlers).forEach((handlerId) => { + const handler = handlers[handlerId]; + if (handler !== undefined) { + try { + handler(message); + } + catch (error) { + try { + this.logger.error(`Message handler failed with ${error.stack}`, error); + } + catch (loggerError) { + console.log("Message handler failed", error); + } + } + } + }); + } + } + handleConnectionChanged(connected) { + if (this._connected === connected) { + return; + } + this._connected = connected; + if (connected) { + if (this.settings?.replaySpecs?.length) { + this.replayer = new MessageReplayerImpl(this.settings.replaySpecs); + this.replayer.init(this); + } + this.registry.execute("connected"); + } + else { + this.handleDisconnected(); + this.registry.execute("disconnected"); + } + } + handleDisconnected() { + this.setLoggedIn(false); + const tryToLogin = this.shouldTryLogin; + if (tryToLogin && this.initialLogin) { + if (this.initialLoginAttempts <= 0) { + return; + } + this.initialLoginAttempts--; + } + this.logger.debug("disconnected - will try new login?" + this.shouldTryLogin); + if (this.shouldTryLogin) { + if (!this.loginConfig) { + throw new Error("no login info"); + } + this.login(this.loginConfig, true) + .catch(() => { + setTimeout(this.handleDisconnected.bind(this), this.settings.reconnectInterval || 1000); + }); + } + } + handleTransportMessage(msg) { + let msgObj; + if (typeof msg === "string") { + msgObj = this.processStringMessage(msg); + } + else { + msgObj = this.processObjectMessage(msg); + } + if (this.isTrace) { + this.logger.trace(`<< ${JSON.stringify(msgObj)}`); + } + this.distributeMessage(msgObj.msg, msgObj.msgType); + } + verifyConnection() { + return PromisePlus$1((resolve) => { + let unsub; + const ready = waitForInvocations(2, () => { + if (unsub) { + unsub(); + } + resolve(); + }); + unsub = this.onLibReAnnounced((lib) => { + if (lib.name === "interop") { + return ready(); + } + if (lib.name === "contexts") { + return ready(); + } + }); + }, 10000, "Transport switch timed out waiting for all libraries to be re-announced"); + } + getNewSecondaryTransport(settings) { + if (!settings.transportConfig?.url) { + throw new Error("Missing secondary transport URL."); + } + return new WS(Object.assign({}, this.settings, { ws: settings.transportConfig.url, reconnectAttempts: 1 }), this.logger.subLogger("ws-secondary")); + } + getNewSecondaryAuth(settings) { + if (!settings.transportConfig?.auth) { + throw new Error("Missing secondary transport auth information."); + } + return settings.transportConfig.auth; + } + transportSwap() { + this._swapTransport = false; + if (!this._targetTransport || !this._targetAuth) { + this.logger.warn(`Error while switching transports - either the target transport or auth is not defined: transport defined -> ${!!this._defaultTransport}, auth defined -> ${!!this._targetAuth}. Staying on the current one.`); + return; + } + this._transportSubscriptions.forEach((unsub) => unsub()); + this._transportSubscriptions = []; + this.transport = this._targetTransport; + const unsubConnectionChanged = this.transport.onConnectedChanged(this.handleConnectionChanged.bind(this)); + const unsubOnMessage = this.transport.onMessage(this.handleTransportMessage.bind(this)); + this._transportSubscriptions.push(unsubConnectionChanged); + this._transportSubscriptions.push(unsubOnMessage); + return this._targetAuth; + } + prepareDefaultSwap() { + this._transportSubscriptions.forEach((unsub) => unsub()); + this._transportSubscriptions = []; + this.transport.close().catch((error) => this.logger.warn(`Error closing the ${this.transport.name()} transport after a failed connection attempt: ${JSON.stringify(error)}`)); + this._targetTransport = this._defaultTransport; + this._targetAuth = this._defaultAuth; + this._swapTransport = true; + } + processStringMessage(message) { + const msg = JSON.parse(message, (key, value) => { + if (typeof value !== "string") { + return value; + } + if (value.length < this.dateMinLen) { + return value; + } + if (!value.startsWith(this.datePrefixFirstChar)) { + return value; + } + if (value.substring(0, this.datePrefixLen) !== this.datePrefix) { + return value; + } + try { + const milliseconds = parseInt(value.substring(this.datePrefixLen, value.length), 10); + if (isNaN(milliseconds)) { + return value; + } + return new Date(milliseconds); + } + catch (ex) { + return value; + } + }); + return { + msg, + msgType: msg.type, + }; + } + createStringMessage(message) { + const oldToJson = Date.prototype.toJSON; + try { + const datePrefix = this.datePrefix; + Date.prototype.toJSON = function () { + return datePrefix + this.getTime(); + }; + const result = JSON.stringify(message); + return result; + } + finally { + Date.prototype.toJSON = oldToJson; + } + } + processObjectMessage(message) { + if (!message.type) { + throw new Error("Object should have type property"); + } + return { + msg: message, + msgType: message.type, + }; + } + createObjectMessage(message) { + return message; + } + async loginCore(config, reconnect) { + this.logger.info("logging in..."); + this.loginConfig = config; + if (!this.loginConfig) { + this.loginConfig = { username: "", password: "" }; + } + this.shouldTryLogin = true; + const authentication = await this.setupAuthConfig(config, reconnect); + const helloMsg = { + type: "hello", + identity: this.settings.identity, + authentication + }; + if (config.sessionId) { + helloMsg.request_id = config.sessionId; + } + this.globalDomain = domainSession("global", this, this.logger.subLogger("global-domain"), [ + "welcome", + "token", + "authentication-request" + ]); + const sendOptions = { skipPeerId: true }; + if (this.initialLogin) { + sendOptions.retryInterval = this.settings.reconnectInterval; + sendOptions.maxRetries = this.settings.reconnectAttempts; + } + try { + const welcomeMsg = await this.tryAuthenticate(this.globalDomain, helloMsg, sendOptions, config); + this.initialLogin = false; + this.logger.info("login successful with peerId " + welcomeMsg.peer_id); + this.peerId = welcomeMsg.peer_id; + this.resolvedIdentity = welcomeMsg.resolved_identity; + this.availableDomains = welcomeMsg.available_domains; + if (welcomeMsg.options) { + this.token = welcomeMsg.options.access_token; + this.info = welcomeMsg.options.info; + } + this.setLoggedIn(true); + return welcomeMsg.resolved_identity; + } + catch (err) { + this.logger.error("error sending hello message - " + (err.message || err.msg || err.reason || err), err); + throw err; + } + finally { + if (config?.flowCallback && config.sessionId) { + config.flowCallback(config.sessionId, null); + } + } + } + async tryAuthenticate(globalDomain, helloMsg, sendOptions, config) { + let welcomeMsg; + while (true) { + const msg = await globalDomain.send(helloMsg, undefined, sendOptions); + if (msg.type === "authentication-request") { + const token = Buffer.from(msg.authentication.token, "base64"); + if (config.flowCallback && config.sessionId) { + helloMsg.authentication.token = + (await config.flowCallback(config.sessionId, token)) + .data + .toString("base64"); + } + helloMsg.request_id = config.sessionId; + } + else if (msg.type === "welcome") { + welcomeMsg = msg; + break; + } + else if (msg.type === "error") { + throw new Error("Authentication failed: " + msg.reason); + } + else { + throw new Error("Unexpected message type during authentication: " + msg.type); + } + } + return welcomeMsg; + } + async setupAuthConfig(config, reconnect) { + const authentication = {}; + this.gatewayToken = config.gatewayToken; + if (config.gatewayToken) { + if (reconnect) { + try { + config.gatewayToken = await this.getNewGWToken(); + } + catch (e) { + this.logger.warn(`failed to get GW token when reconnecting ${e?.message || e}`); + } + } + authentication.method = "gateway-token"; + authentication.token = config.gatewayToken; + this.gatewayToken = config.gatewayToken; + } + else if (config.flowName === "sspi") { + authentication.provider = "win"; + authentication.method = "access-token"; + if (config.flowCallback && config.sessionId) { + authentication.token = + (await config.flowCallback(config.sessionId, null)) + .data + .toString("base64"); + } + else { + throw new Error("Invalid SSPI config"); + } + } + else if (config.token) { + authentication.method = "access-token"; + authentication.token = config.token; + } + else if (config.username) { + authentication.method = "secret"; + authentication.login = config.username; + authentication.secret = config.password; + } + else if (config.provider) { + authentication.provider = config.provider; + authentication.providerContext = config.providerContext; + } + else { + throw new Error("invalid auth message" + JSON.stringify(config)); + } + return authentication; + } + async logoutCore() { + this.logger.debug("logging out..."); + this.shouldTryLogin = false; + if (this.pingTimer) { + clearTimeout(this.pingTimer); + } + const promises = this.sessions.map((session) => { + session.leave(); + }); + await Promise.all(promises); + } + getNewGWToken() { + if (typeof window !== "undefined") { + const glue42gd = window.glue42gd; + if (glue42gd) { + return glue42gd.getGWToken(); + } + } + return Promise.reject(new Error("not running in GD")); + } + ping() { + if (!this.shouldTryLogin) { + return; + } + if (this._isLoggedIn) { + this.send({ type: "ping" }); + } + this.pingTimer = setTimeout(() => { + this.ping(); + }, 30 * 1000); + } + } + + const order = ["trace", "debug", "info", "warn", "error", "off"]; + let Logger$1 = class Logger { + name; + parent; + static Interop; + static InteropMethodName = "T42.AppLogger.Log"; + static Instance; + path; + subLoggers = []; + _consoleLevel; + _publishLevel; + loggerFullName; + includeTimeAndLevel; + logFn = console; + customLogFn = false; + constructor(name, parent, logFn) { + this.name = name; + this.parent = parent; + this.name = name; + if (parent) { + this.path = `${parent.path}.${name}`; + } + else { + this.path = name; + } + this.loggerFullName = `[${this.path}]`; + this.includeTimeAndLevel = !logFn; + if (logFn) { + this.logFn = logFn; + this.customLogFn = true; + } + } + subLogger(name) { + const existingSub = this.subLoggers.filter((subLogger) => { + return subLogger.name === name; + })[0]; + if (existingSub !== undefined) { + return existingSub; + } + Object.keys(this).forEach((key) => { + if (key === name) { + throw new Error("This sub logger name is not allowed."); + } + }); + const sub = new Logger(name, this, this.customLogFn ? this.logFn : undefined); + this.subLoggers.push(sub); + return sub; + } + publishLevel(level) { + if (level) { + this._publishLevel = level; + } + return this._publishLevel || this.parent?.publishLevel(); + } + consoleLevel(level) { + if (level) { + this._consoleLevel = level; + } + return this._consoleLevel || this.parent?.consoleLevel(); + } + log(message, level, error) { + this.publishMessage(level || "info", message, error); + } + trace(message) { + this.log(message, "trace"); + } + debug(message) { + this.log(message, "debug"); + } + info(message) { + this.log(message, "info"); + } + warn(message) { + this.log(message, "warn"); + } + error(message, err) { + this.log(message, "error", err); + } + canPublish(level, compareWith) { + const levelIdx = order.indexOf(level); + const restrictionIdx = order.indexOf(compareWith || this.consoleLevel() || "trace"); + return levelIdx >= restrictionIdx; + } + publishMessage(level, message, error) { + const loggerName = this.loggerFullName; + if (level === "error" && !error) { + const e = new Error(); + if (e.stack) { + message = + message + + "\n" + + e.stack + .split("\n") + .slice(4) + .join("\n"); + } + } + if (this.canPublish(level, this.publishLevel())) { + const interop = Logger.Interop; + if (interop) { + try { + if (interop.methods({ name: Logger.InteropMethodName }).length > 0) { + const args = { + msg: message, + logger: loggerName, + level + }; + if (error && error instanceof Error) { + args.error = { + message: error.message, + stack: error.stack ?? "" + }; + } + interop.invoke(Logger.InteropMethodName, args); + } + } + catch { + } + } + } + if (this.canPublish(level)) { + let prefix = ""; + if (this.includeTimeAndLevel) { + const date = new Date(); + const time = `${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}:${date.getMilliseconds()}`; + prefix = `[${time}] [${level}] `; + } + const toPrint = `${prefix}${loggerName}: ${message}`; + switch (level) { + case "trace": + this.logFn.debug(toPrint); + break; + case "debug": + if (this.logFn.debug) { + this.logFn.debug(toPrint); + } + else { + this.logFn.log(toPrint); + } + break; + case "info": + this.logFn.info(toPrint); + break; + case "warn": + this.logFn.warn(toPrint); + break; + case "error": + this.logFn.error(toPrint, error); + break; + } + } + } + }; + + const GW_MESSAGE_CREATE_CONTEXT = "create-context"; + const GW_MESSAGE_ACTIVITY_CREATED = "created"; + const GW_MESSAGE_ACTIVITY_DESTROYED = "destroyed"; + const GW_MESSAGE_CONTEXT_CREATED = "context-created"; + const GW_MESSAGE_CONTEXT_ADDED = "context-added"; + const GW_MESSAGE_SUBSCRIBE_CONTEXT = "subscribe-context"; + const GW_MESSAGE_SUBSCRIBED_CONTEXT = "subscribed-context"; + const GW_MESSAGE_UNSUBSCRIBE_CONTEXT = "unsubscribe-context"; + const GW_MESSAGE_DESTROY_CONTEXT = "destroy-context"; + const GW_MESSAGE_CONTEXT_DESTROYED = "context-destroyed"; + const GW_MESSAGE_UPDATE_CONTEXT = "update-context"; + const GW_MESSAGE_CONTEXT_UPDATED = "context-updated"; + const GW_MESSAGE_JOINED_ACTIVITY = "joined"; + + const ContextMessageReplaySpec = { + get name() { + return "context"; + }, + get types() { + return [ + GW_MESSAGE_CREATE_CONTEXT, + GW_MESSAGE_ACTIVITY_CREATED, + GW_MESSAGE_ACTIVITY_DESTROYED, + GW_MESSAGE_CONTEXT_CREATED, + GW_MESSAGE_CONTEXT_ADDED, + GW_MESSAGE_SUBSCRIBE_CONTEXT, + GW_MESSAGE_SUBSCRIBED_CONTEXT, + GW_MESSAGE_UNSUBSCRIBE_CONTEXT, + GW_MESSAGE_DESTROY_CONTEXT, + GW_MESSAGE_CONTEXT_DESTROYED, + GW_MESSAGE_UPDATE_CONTEXT, + GW_MESSAGE_CONTEXT_UPDATED, + GW_MESSAGE_JOINED_ACTIVITY + ]; + } + }; + + var version$1 = "6.5.2-fmr-beta"; + + function prepareConfig$1 (configuration, ext, glue42gd) { + let nodeStartingContext; + if (Utils$1.isNode()) { + const startingContextString = process.env._GD_STARTING_CONTEXT_; + if (startingContextString) { + try { + nodeStartingContext = JSON.parse(startingContextString); + } + catch { + } + } + } + function getConnection() { + const gwConfig = configuration.gateway; + const protocolVersion = gwConfig?.protocolVersion ?? 3; + const reconnectInterval = gwConfig?.reconnectInterval; + const reconnectAttempts = gwConfig?.reconnectAttempts; + const defaultWs = "ws://localhost:8385"; + let ws = gwConfig?.ws; + const sharedWorker = gwConfig?.sharedWorker; + const inproc = gwConfig?.inproc; + const webPlatform = gwConfig?.webPlatform ?? undefined; + if (glue42gd) { + ws = glue42gd.gwURL; + } + if (Utils$1.isNode() && nodeStartingContext && nodeStartingContext.gwURL) { + ws = nodeStartingContext.gwURL; + } + if (!ws && !sharedWorker && !inproc) { + ws = defaultWs; + } + let instanceId; + let windowId; + let pid; + let environment; + let region; + const appName = getApplication(); + let uniqueAppName = appName; + if (typeof glue42gd !== "undefined") { + windowId = glue42gd.windowId; + pid = glue42gd.pid; + if (glue42gd.env) { + environment = glue42gd.env.env; + region = glue42gd.env.region; + } + uniqueAppName = glue42gd.application ?? "glue-app"; + instanceId = glue42gd.appInstanceId; + } + else if (Utils$1.isNode()) { + pid = process.pid; + if (nodeStartingContext) { + environment = nodeStartingContext.env; + region = nodeStartingContext.region; + instanceId = nodeStartingContext.instanceId; + } + } + else if (typeof window?.glue42electron !== "undefined") { + windowId = window?.glue42electron.instanceId; + pid = window?.glue42electron.pid; + environment = window?.glue42electron.env; + region = window?.glue42electron.region; + uniqueAppName = window?.glue42electron.application ?? "glue-app"; + instanceId = window?.glue42electron.instanceId; + } + else ; + const replaySpecs = configuration.gateway?.replaySpecs ?? []; + replaySpecs.push(ContextMessageReplaySpec); + let identity = { + application: uniqueAppName, + applicationName: appName, + windowId, + instance: instanceId, + process: pid, + region, + environment, + api: ext.version || version$1 + }; + if (configuration.identity) { + identity = Object.assign(identity, configuration.identity); + } + return { + identity, + reconnectInterval, + ws, + sharedWorker, + webPlatform, + inproc, + protocolVersion, + reconnectAttempts, + replaySpecs, + }; + } + function getContexts() { + if (typeof configuration.contexts === "undefined") { + return { reAnnounceKnownContexts: true }; + } + if (typeof configuration.contexts === "boolean" && configuration.contexts) { + return { reAnnounceKnownContexts: true }; + } + if (typeof configuration.contexts === "object") { + return Object.assign({}, { reAnnounceKnownContexts: true }, configuration.contexts); + } + return false; + } + function getApplication() { + if (configuration.application) { + return configuration.application; + } + if (glue42gd) { + return glue42gd.applicationName; + } + if (typeof window !== "undefined" && typeof window.glue42electron !== "undefined") { + return window.glue42electron.application; + } + const uid = nanoid$1(10); + if (Utils$1.isNode()) { + if (nodeStartingContext) { + return nodeStartingContext.applicationConfig.name; + } + return "NodeJS" + uid; + } + if (typeof window !== "undefined" && typeof document !== "undefined") { + return document.title + ` (${uid})`; + } + return uid; + } + function getAuth() { + if (typeof configuration.auth === "string") { + return { + token: configuration.auth + }; + } + if (configuration.auth) { + return configuration.auth; + } + if (Utils$1.isNode() && nodeStartingContext && nodeStartingContext.gwToken) { + return { + gatewayToken: nodeStartingContext.gwToken + }; + } + if (configuration.gateway?.webPlatform || configuration.gateway?.inproc || configuration.gateway?.sharedWorker) { + return { + username: "glue42", password: "glue42" + }; + } + } + function getLogger() { + let config = configuration.logger; + const defaultLevel = "warn"; + if (!config) { + config = defaultLevel; + } + let gdConsoleLevel; + if (glue42gd) { + gdConsoleLevel = glue42gd.consoleLogLevel; + } + if (typeof config === "string") { + return { console: gdConsoleLevel ?? config, publish: defaultLevel }; + } + return { + console: gdConsoleLevel ?? config.console ?? defaultLevel, + publish: config.publish ?? defaultLevel + }; + } + const connection = getConnection(); + let application = getApplication(); + if (typeof window !== "undefined") { + const windowAsAny = window; + const containerApplication = windowAsAny.htmlContainer ? + `${windowAsAny.htmlContainer.containerName}.${windowAsAny.htmlContainer.application}` : + windowAsAny?.glue42gd?.application; + if (containerApplication) { + application = containerApplication; + } + } + return { + bus: configuration.bus ?? false, + application, + auth: getAuth(), + logger: getLogger(), + connection, + metrics: configuration.metrics ?? true, + contexts: getContexts(), + version: ext.version || version$1, + libs: ext.libs ?? [], + customLogger: configuration.customLogger + }; + } + + class GW3ContextData { + name; + contextId; + context; + isAnnounced; + joinedActivity; + updateCallbacks = {}; + activityId; + sentExplicitSubscription; + hasReceivedSnapshot; + constructor(contextId, name, isAnnounced, activityId) { + this.contextId = contextId; + this.name = name; + this.isAnnounced = isAnnounced; + this.activityId = activityId; + this.context = {}; + } + hasCallbacks() { + return Object.keys(this.updateCallbacks).length > 0; + } + getState() { + if (this.isAnnounced && this.hasCallbacks()) { + return 3; + } + if (this.isAnnounced) { + return 2; + } + if (this.hasCallbacks()) { + return 1; + } + return 0; + } + } + + var lodash_clonedeep = {exports: {}}; + + /** + * lodash (Custom Build) + * Build: `lodash modularize exports="npm" -o ./` + * Copyright jQuery Foundation and other contributors + * Released under MIT license + * Based on Underscore.js 1.8.3 + * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + */ + lodash_clonedeep.exports; + + (function (module, exports) { + /** Used as the size to enable large array optimizations. */ + var LARGE_ARRAY_SIZE = 200; + + /** Used to stand-in for `undefined` hash values. */ + var HASH_UNDEFINED = '__lodash_hash_undefined__'; + + /** Used as references for various `Number` constants. */ + var MAX_SAFE_INTEGER = 9007199254740991; + + /** `Object#toString` result references. */ + var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + boolTag = '[object Boolean]', + dateTag = '[object Date]', + errorTag = '[object Error]', + funcTag = '[object Function]', + genTag = '[object GeneratorFunction]', + mapTag = '[object Map]', + numberTag = '[object Number]', + objectTag = '[object Object]', + promiseTag = '[object Promise]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + symbolTag = '[object Symbol]', + weakMapTag = '[object WeakMap]'; + + var arrayBufferTag = '[object ArrayBuffer]', + dataViewTag = '[object DataView]', + float32Tag = '[object Float32Array]', + float64Tag = '[object Float64Array]', + int8Tag = '[object Int8Array]', + int16Tag = '[object Int16Array]', + int32Tag = '[object Int32Array]', + uint8Tag = '[object Uint8Array]', + uint8ClampedTag = '[object Uint8ClampedArray]', + uint16Tag = '[object Uint16Array]', + uint32Tag = '[object Uint32Array]'; + + /** + * Used to match `RegExp` + * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns). + */ + var reRegExpChar = /[\\^$.*+?()[\]{}|]/g; + + /** Used to match `RegExp` flags from their coerced string values. */ + var reFlags = /\w*$/; + + /** Used to detect host constructors (Safari). */ + var reIsHostCtor = /^\[object .+?Constructor\]$/; + + /** Used to detect unsigned integer values. */ + var reIsUint = /^(?:0|[1-9]\d*)$/; + + /** Used to identify `toStringTag` values supported by `_.clone`. */ + var cloneableTags = {}; + cloneableTags[argsTag] = cloneableTags[arrayTag] = + cloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] = + cloneableTags[boolTag] = cloneableTags[dateTag] = + cloneableTags[float32Tag] = cloneableTags[float64Tag] = + cloneableTags[int8Tag] = cloneableTags[int16Tag] = + cloneableTags[int32Tag] = cloneableTags[mapTag] = + cloneableTags[numberTag] = cloneableTags[objectTag] = + cloneableTags[regexpTag] = cloneableTags[setTag] = + cloneableTags[stringTag] = cloneableTags[symbolTag] = + cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] = + cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true; + cloneableTags[errorTag] = cloneableTags[funcTag] = + cloneableTags[weakMapTag] = false; + + /** Detect free variable `global` from Node.js. */ + var freeGlobal = typeof commonjsGlobal$1 == 'object' && commonjsGlobal$1 && commonjsGlobal$1.Object === Object && commonjsGlobal$1; + + /** Detect free variable `self`. */ + var freeSelf = typeof self == 'object' && self && self.Object === Object && self; + + /** Used as a reference to the global object. */ + var root = freeGlobal || freeSelf || Function('return this')(); + + /** Detect free variable `exports`. */ + var freeExports = exports && !exports.nodeType && exports; + + /** Detect free variable `module`. */ + var freeModule = freeExports && 'object' == 'object' && module && !module.nodeType && module; + + /** Detect the popular CommonJS extension `module.exports`. */ + var moduleExports = freeModule && freeModule.exports === freeExports; + + /** + * Adds the key-value `pair` to `map`. + * + * @private + * @param {Object} map The map to modify. + * @param {Array} pair The key-value pair to add. + * @returns {Object} Returns `map`. + */ + function addMapEntry(map, pair) { + // Don't return `map.set` because it's not chainable in IE 11. + map.set(pair[0], pair[1]); + return map; + } + + /** + * Adds `value` to `set`. + * + * @private + * @param {Object} set The set to modify. + * @param {*} value The value to add. + * @returns {Object} Returns `set`. + */ + function addSetEntry(set, value) { + // Don't return `set.add` because it's not chainable in IE 11. + set.add(value); + return set; + } + + /** + * A specialized version of `_.forEach` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns `array`. + */ + function arrayEach(array, iteratee) { + var index = -1, + length = array ? array.length : 0; + + while (++index < length) { + if (iteratee(array[index], index, array) === false) { + break; + } + } + return array; + } + + /** + * Appends the elements of `values` to `array`. + * + * @private + * @param {Array} array The array to modify. + * @param {Array} values The values to append. + * @returns {Array} Returns `array`. + */ + function arrayPush(array, values) { + var index = -1, + length = values.length, + offset = array.length; + + while (++index < length) { + array[offset + index] = values[index]; + } + return array; + } + + /** + * A specialized version of `_.reduce` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {boolean} [initAccum] Specify using the first element of `array` as + * the initial value. + * @returns {*} Returns the accumulated value. + */ + function arrayReduce(array, iteratee, accumulator, initAccum) { + var index = -1, + length = array ? array.length : 0; + while (++index < length) { + accumulator = iteratee(accumulator, array[index], index, array); + } + return accumulator; + } + + /** + * The base implementation of `_.times` without support for iteratee shorthands + * or max array length checks. + * + * @private + * @param {number} n The number of times to invoke `iteratee`. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the array of results. + */ + function baseTimes(n, iteratee) { + var index = -1, + result = Array(n); + + while (++index < n) { + result[index] = iteratee(index); + } + return result; + } + + /** + * Gets the value at `key` of `object`. + * + * @private + * @param {Object} [object] The object to query. + * @param {string} key The key of the property to get. + * @returns {*} Returns the property value. + */ + function getValue(object, key) { + return object == null ? undefined : object[key]; + } + + /** + * Checks if `value` is a host object in IE < 9. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a host object, else `false`. + */ + function isHostObject(value) { + // Many host objects are `Object` objects that can coerce to strings + // despite having improperly defined `toString` methods. + var result = false; + if (value != null && typeof value.toString != 'function') { + try { + result = !!(value + ''); + } catch (e) {} + } + return result; + } + + /** + * Converts `map` to its key-value pairs. + * + * @private + * @param {Object} map The map to convert. + * @returns {Array} Returns the key-value pairs. + */ + function mapToArray(map) { + var index = -1, + result = Array(map.size); + + map.forEach(function(value, key) { + result[++index] = [key, value]; + }); + return result; + } + + /** + * Creates a unary function that invokes `func` with its argument transformed. + * + * @private + * @param {Function} func The function to wrap. + * @param {Function} transform The argument transform. + * @returns {Function} Returns the new function. + */ + function overArg(func, transform) { + return function(arg) { + return func(transform(arg)); + }; + } + + /** + * Converts `set` to an array of its values. + * + * @private + * @param {Object} set The set to convert. + * @returns {Array} Returns the values. + */ + function setToArray(set) { + var index = -1, + result = Array(set.size); + + set.forEach(function(value) { + result[++index] = value; + }); + return result; + } + + /** Used for built-in method references. */ + var arrayProto = Array.prototype, + funcProto = Function.prototype, + objectProto = Object.prototype; + + /** Used to detect overreaching core-js shims. */ + var coreJsData = root['__core-js_shared__']; + + /** Used to detect methods masquerading as native. */ + var maskSrcKey = (function() { + var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || ''); + return uid ? ('Symbol(src)_1.' + uid) : ''; + }()); + + /** Used to resolve the decompiled source of functions. */ + var funcToString = funcProto.toString; + + /** Used to check objects for own properties. */ + var hasOwnProperty = objectProto.hasOwnProperty; + + /** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ + var objectToString = objectProto.toString; + + /** Used to detect if a method is native. */ + var reIsNative = RegExp('^' + + funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&') + .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' + ); + + /** Built-in value references. */ + var Buffer = moduleExports ? root.Buffer : undefined, + Symbol = root.Symbol, + Uint8Array = root.Uint8Array, + getPrototype = overArg(Object.getPrototypeOf, Object), + objectCreate = Object.create, + propertyIsEnumerable = objectProto.propertyIsEnumerable, + splice = arrayProto.splice; + + /* Built-in method references for those with the same name as other `lodash` methods. */ + var nativeGetSymbols = Object.getOwnPropertySymbols, + nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined, + nativeKeys = overArg(Object.keys, Object); + + /* Built-in method references that are verified to be native. */ + var DataView = getNative(root, 'DataView'), + Map = getNative(root, 'Map'), + Promise = getNative(root, 'Promise'), + Set = getNative(root, 'Set'), + WeakMap = getNative(root, 'WeakMap'), + nativeCreate = getNative(Object, 'create'); + + /** Used to detect maps, sets, and weakmaps. */ + var dataViewCtorString = toSource(DataView), + mapCtorString = toSource(Map), + promiseCtorString = toSource(Promise), + setCtorString = toSource(Set), + weakMapCtorString = toSource(WeakMap); + + /** Used to convert symbols to primitives and strings. */ + var symbolProto = Symbol ? Symbol.prototype : undefined, + symbolValueOf = symbolProto ? symbolProto.valueOf : undefined; + + /** + * Creates a hash object. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + function Hash(entries) { + var index = -1, + length = entries ? entries.length : 0; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } + } + + /** + * Removes all key-value entries from the hash. + * + * @private + * @name clear + * @memberOf Hash + */ + function hashClear() { + this.__data__ = nativeCreate ? nativeCreate(null) : {}; + } + + /** + * Removes `key` and its value from the hash. + * + * @private + * @name delete + * @memberOf Hash + * @param {Object} hash The hash to modify. + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function hashDelete(key) { + return this.has(key) && delete this.__data__[key]; + } + + /** + * Gets the hash value for `key`. + * + * @private + * @name get + * @memberOf Hash + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function hashGet(key) { + var data = this.__data__; + if (nativeCreate) { + var result = data[key]; + return result === HASH_UNDEFINED ? undefined : result; + } + return hasOwnProperty.call(data, key) ? data[key] : undefined; + } + + /** + * Checks if a hash value for `key` exists. + * + * @private + * @name has + * @memberOf Hash + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function hashHas(key) { + var data = this.__data__; + return nativeCreate ? data[key] !== undefined : hasOwnProperty.call(data, key); + } + + /** + * Sets the hash `key` to `value`. + * + * @private + * @name set + * @memberOf Hash + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the hash instance. + */ + function hashSet(key, value) { + var data = this.__data__; + data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value; + return this; + } + + // Add methods to `Hash`. + Hash.prototype.clear = hashClear; + Hash.prototype['delete'] = hashDelete; + Hash.prototype.get = hashGet; + Hash.prototype.has = hashHas; + Hash.prototype.set = hashSet; + + /** + * Creates an list cache object. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + function ListCache(entries) { + var index = -1, + length = entries ? entries.length : 0; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } + } + + /** + * Removes all key-value entries from the list cache. + * + * @private + * @name clear + * @memberOf ListCache + */ + function listCacheClear() { + this.__data__ = []; + } + + /** + * Removes `key` and its value from the list cache. + * + * @private + * @name delete + * @memberOf ListCache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function listCacheDelete(key) { + var data = this.__data__, + index = assocIndexOf(data, key); + + if (index < 0) { + return false; + } + var lastIndex = data.length - 1; + if (index == lastIndex) { + data.pop(); + } else { + splice.call(data, index, 1); + } + return true; + } + + /** + * Gets the list cache value for `key`. + * + * @private + * @name get + * @memberOf ListCache + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function listCacheGet(key) { + var data = this.__data__, + index = assocIndexOf(data, key); + + return index < 0 ? undefined : data[index][1]; + } + + /** + * Checks if a list cache value for `key` exists. + * + * @private + * @name has + * @memberOf ListCache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function listCacheHas(key) { + return assocIndexOf(this.__data__, key) > -1; + } + + /** + * Sets the list cache `key` to `value`. + * + * @private + * @name set + * @memberOf ListCache + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the list cache instance. + */ + function listCacheSet(key, value) { + var data = this.__data__, + index = assocIndexOf(data, key); + + if (index < 0) { + data.push([key, value]); + } else { + data[index][1] = value; + } + return this; + } + + // Add methods to `ListCache`. + ListCache.prototype.clear = listCacheClear; + ListCache.prototype['delete'] = listCacheDelete; + ListCache.prototype.get = listCacheGet; + ListCache.prototype.has = listCacheHas; + ListCache.prototype.set = listCacheSet; + + /** + * Creates a map cache object to store key-value pairs. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + function MapCache(entries) { + var index = -1, + length = entries ? entries.length : 0; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } + } + + /** + * Removes all key-value entries from the map. + * + * @private + * @name clear + * @memberOf MapCache + */ + function mapCacheClear() { + this.__data__ = { + 'hash': new Hash, + 'map': new (Map || ListCache), + 'string': new Hash + }; + } + + /** + * Removes `key` and its value from the map. + * + * @private + * @name delete + * @memberOf MapCache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function mapCacheDelete(key) { + return getMapData(this, key)['delete'](key); + } + + /** + * Gets the map value for `key`. + * + * @private + * @name get + * @memberOf MapCache + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function mapCacheGet(key) { + return getMapData(this, key).get(key); + } + + /** + * Checks if a map value for `key` exists. + * + * @private + * @name has + * @memberOf MapCache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function mapCacheHas(key) { + return getMapData(this, key).has(key); + } + + /** + * Sets the map `key` to `value`. + * + * @private + * @name set + * @memberOf MapCache + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the map cache instance. + */ + function mapCacheSet(key, value) { + getMapData(this, key).set(key, value); + return this; + } + + // Add methods to `MapCache`. + MapCache.prototype.clear = mapCacheClear; + MapCache.prototype['delete'] = mapCacheDelete; + MapCache.prototype.get = mapCacheGet; + MapCache.prototype.has = mapCacheHas; + MapCache.prototype.set = mapCacheSet; + + /** + * Creates a stack cache object to store key-value pairs. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + function Stack(entries) { + this.__data__ = new ListCache(entries); + } + + /** + * Removes all key-value entries from the stack. + * + * @private + * @name clear + * @memberOf Stack + */ + function stackClear() { + this.__data__ = new ListCache; + } + + /** + * Removes `key` and its value from the stack. + * + * @private + * @name delete + * @memberOf Stack + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function stackDelete(key) { + return this.__data__['delete'](key); + } + + /** + * Gets the stack value for `key`. + * + * @private + * @name get + * @memberOf Stack + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function stackGet(key) { + return this.__data__.get(key); + } + + /** + * Checks if a stack value for `key` exists. + * + * @private + * @name has + * @memberOf Stack + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function stackHas(key) { + return this.__data__.has(key); + } + + /** + * Sets the stack `key` to `value`. + * + * @private + * @name set + * @memberOf Stack + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the stack cache instance. + */ + function stackSet(key, value) { + var cache = this.__data__; + if (cache instanceof ListCache) { + var pairs = cache.__data__; + if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) { + pairs.push([key, value]); + return this; + } + cache = this.__data__ = new MapCache(pairs); + } + cache.set(key, value); + return this; + } + + // Add methods to `Stack`. + Stack.prototype.clear = stackClear; + Stack.prototype['delete'] = stackDelete; + Stack.prototype.get = stackGet; + Stack.prototype.has = stackHas; + Stack.prototype.set = stackSet; + + /** + * Creates an array of the enumerable property names of the array-like `value`. + * + * @private + * @param {*} value The value to query. + * @param {boolean} inherited Specify returning inherited property names. + * @returns {Array} Returns the array of property names. + */ + function arrayLikeKeys(value, inherited) { + // Safari 8.1 makes `arguments.callee` enumerable in strict mode. + // Safari 9 makes `arguments.length` enumerable in strict mode. + var result = (isArray(value) || isArguments(value)) + ? baseTimes(value.length, String) + : []; + + var length = result.length, + skipIndexes = !!length; + + for (var key in value) { + if ((hasOwnProperty.call(value, key)) && + !(skipIndexes && (key == 'length' || isIndex(key, length)))) { + result.push(key); + } + } + return result; + } + + /** + * Assigns `value` to `key` of `object` if the existing value is not equivalent + * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. + * + * @private + * @param {Object} object The object to modify. + * @param {string} key The key of the property to assign. + * @param {*} value The value to assign. + */ + function assignValue(object, key, value) { + var objValue = object[key]; + if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) || + (value === undefined && !(key in object))) { + object[key] = value; + } + } + + /** + * Gets the index at which the `key` is found in `array` of key-value pairs. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} key The key to search for. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function assocIndexOf(array, key) { + var length = array.length; + while (length--) { + if (eq(array[length][0], key)) { + return length; + } + } + return -1; + } + + /** + * The base implementation of `_.assign` without support for multiple sources + * or `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @returns {Object} Returns `object`. + */ + function baseAssign(object, source) { + return object && copyObject(source, keys(source), object); + } + + /** + * The base implementation of `_.clone` and `_.cloneDeep` which tracks + * traversed objects. + * + * @private + * @param {*} value The value to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @param {boolean} [isFull] Specify a clone including symbols. + * @param {Function} [customizer] The function to customize cloning. + * @param {string} [key] The key of `value`. + * @param {Object} [object] The parent object of `value`. + * @param {Object} [stack] Tracks traversed objects and their clone counterparts. + * @returns {*} Returns the cloned value. + */ + function baseClone(value, isDeep, isFull, customizer, key, object, stack) { + var result; + if (customizer) { + result = object ? customizer(value, key, object, stack) : customizer(value); + } + if (result !== undefined) { + return result; + } + if (!isObject(value)) { + return value; + } + var isArr = isArray(value); + if (isArr) { + result = initCloneArray(value); + if (!isDeep) { + return copyArray(value, result); + } + } else { + var tag = getTag(value), + isFunc = tag == funcTag || tag == genTag; + + if (isBuffer(value)) { + return cloneBuffer(value, isDeep); + } + if (tag == objectTag || tag == argsTag || (isFunc && !object)) { + if (isHostObject(value)) { + return object ? value : {}; + } + result = initCloneObject(isFunc ? {} : value); + if (!isDeep) { + return copySymbols(value, baseAssign(result, value)); + } + } else { + if (!cloneableTags[tag]) { + return object ? value : {}; + } + result = initCloneByTag(value, tag, baseClone, isDeep); + } + } + // Check for circular references and return its corresponding clone. + stack || (stack = new Stack); + var stacked = stack.get(value); + if (stacked) { + return stacked; + } + stack.set(value, result); + + if (!isArr) { + var props = isFull ? getAllKeys(value) : keys(value); + } + arrayEach(props || value, function(subValue, key) { + if (props) { + key = subValue; + subValue = value[key]; + } + // Recursively populate clone (susceptible to call stack limits). + assignValue(result, key, baseClone(subValue, isDeep, isFull, customizer, key, value, stack)); + }); + return result; + } + + /** + * The base implementation of `_.create` without support for assigning + * properties to the created object. + * + * @private + * @param {Object} prototype The object to inherit from. + * @returns {Object} Returns the new object. + */ + function baseCreate(proto) { + return isObject(proto) ? objectCreate(proto) : {}; + } + + /** + * The base implementation of `getAllKeys` and `getAllKeysIn` which uses + * `keysFunc` and `symbolsFunc` to get the enumerable property names and + * symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Function} keysFunc The function to get the keys of `object`. + * @param {Function} symbolsFunc The function to get the symbols of `object`. + * @returns {Array} Returns the array of property names and symbols. + */ + function baseGetAllKeys(object, keysFunc, symbolsFunc) { + var result = keysFunc(object); + return isArray(object) ? result : arrayPush(result, symbolsFunc(object)); + } + + /** + * The base implementation of `getTag`. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the `toStringTag`. + */ + function baseGetTag(value) { + return objectToString.call(value); + } + + /** + * The base implementation of `_.isNative` without bad shim checks. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a native function, + * else `false`. + */ + function baseIsNative(value) { + if (!isObject(value) || isMasked(value)) { + return false; + } + var pattern = (isFunction(value) || isHostObject(value)) ? reIsNative : reIsHostCtor; + return pattern.test(toSource(value)); + } + + /** + * The base implementation of `_.keys` which doesn't treat sparse arrays as dense. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ + function baseKeys(object) { + if (!isPrototype(object)) { + return nativeKeys(object); + } + var result = []; + for (var key in Object(object)) { + if (hasOwnProperty.call(object, key) && key != 'constructor') { + result.push(key); + } + } + return result; + } + + /** + * Creates a clone of `buffer`. + * + * @private + * @param {Buffer} buffer The buffer to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Buffer} Returns the cloned buffer. + */ + function cloneBuffer(buffer, isDeep) { + if (isDeep) { + return buffer.slice(); + } + var result = new buffer.constructor(buffer.length); + buffer.copy(result); + return result; + } + + /** + * Creates a clone of `arrayBuffer`. + * + * @private + * @param {ArrayBuffer} arrayBuffer The array buffer to clone. + * @returns {ArrayBuffer} Returns the cloned array buffer. + */ + function cloneArrayBuffer(arrayBuffer) { + var result = new arrayBuffer.constructor(arrayBuffer.byteLength); + new Uint8Array(result).set(new Uint8Array(arrayBuffer)); + return result; + } + + /** + * Creates a clone of `dataView`. + * + * @private + * @param {Object} dataView The data view to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned data view. + */ + function cloneDataView(dataView, isDeep) { + var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer; + return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength); + } + + /** + * Creates a clone of `map`. + * + * @private + * @param {Object} map The map to clone. + * @param {Function} cloneFunc The function to clone values. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned map. + */ + function cloneMap(map, isDeep, cloneFunc) { + var array = isDeep ? cloneFunc(mapToArray(map), true) : mapToArray(map); + return arrayReduce(array, addMapEntry, new map.constructor); + } + + /** + * Creates a clone of `regexp`. + * + * @private + * @param {Object} regexp The regexp to clone. + * @returns {Object} Returns the cloned regexp. + */ + function cloneRegExp(regexp) { + var result = new regexp.constructor(regexp.source, reFlags.exec(regexp)); + result.lastIndex = regexp.lastIndex; + return result; + } + + /** + * Creates a clone of `set`. + * + * @private + * @param {Object} set The set to clone. + * @param {Function} cloneFunc The function to clone values. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned set. + */ + function cloneSet(set, isDeep, cloneFunc) { + var array = isDeep ? cloneFunc(setToArray(set), true) : setToArray(set); + return arrayReduce(array, addSetEntry, new set.constructor); + } + + /** + * Creates a clone of the `symbol` object. + * + * @private + * @param {Object} symbol The symbol object to clone. + * @returns {Object} Returns the cloned symbol object. + */ + function cloneSymbol(symbol) { + return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {}; + } + + /** + * Creates a clone of `typedArray`. + * + * @private + * @param {Object} typedArray The typed array to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned typed array. + */ + function cloneTypedArray(typedArray, isDeep) { + var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer; + return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length); + } + + /** + * Copies the values of `source` to `array`. + * + * @private + * @param {Array} source The array to copy values from. + * @param {Array} [array=[]] The array to copy values to. + * @returns {Array} Returns `array`. + */ + function copyArray(source, array) { + var index = -1, + length = source.length; + + array || (array = Array(length)); + while (++index < length) { + array[index] = source[index]; + } + return array; + } + + /** + * Copies properties of `source` to `object`. + * + * @private + * @param {Object} source The object to copy properties from. + * @param {Array} props The property identifiers to copy. + * @param {Object} [object={}] The object to copy properties to. + * @param {Function} [customizer] The function to customize copied values. + * @returns {Object} Returns `object`. + */ + function copyObject(source, props, object, customizer) { + object || (object = {}); + + var index = -1, + length = props.length; + + while (++index < length) { + var key = props[index]; + + var newValue = undefined; + + assignValue(object, key, newValue === undefined ? source[key] : newValue); + } + return object; + } + + /** + * Copies own symbol properties of `source` to `object`. + * + * @private + * @param {Object} source The object to copy symbols from. + * @param {Object} [object={}] The object to copy symbols to. + * @returns {Object} Returns `object`. + */ + function copySymbols(source, object) { + return copyObject(source, getSymbols(source), object); + } + + /** + * Creates an array of own enumerable property names and symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names and symbols. + */ + function getAllKeys(object) { + return baseGetAllKeys(object, keys, getSymbols); + } + + /** + * Gets the data for `map`. + * + * @private + * @param {Object} map The map to query. + * @param {string} key The reference key. + * @returns {*} Returns the map data. + */ + function getMapData(map, key) { + var data = map.__data__; + return isKeyable(key) + ? data[typeof key == 'string' ? 'string' : 'hash'] + : data.map; + } + + /** + * Gets the native function at `key` of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {string} key The key of the method to get. + * @returns {*} Returns the function if it's native, else `undefined`. + */ + function getNative(object, key) { + var value = getValue(object, key); + return baseIsNative(value) ? value : undefined; + } + + /** + * Creates an array of the own enumerable symbol properties of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. + */ + var getSymbols = nativeGetSymbols ? overArg(nativeGetSymbols, Object) : stubArray; + + /** + * Gets the `toStringTag` of `value`. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the `toStringTag`. + */ + var getTag = baseGetTag; + + // Fallback for data views, maps, sets, and weak maps in IE 11, + // for data views in Edge < 14, and promises in Node.js. + if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) || + (Map && getTag(new Map) != mapTag) || + (Promise && getTag(Promise.resolve()) != promiseTag) || + (Set && getTag(new Set) != setTag) || + (WeakMap && getTag(new WeakMap) != weakMapTag)) { + getTag = function(value) { + var result = objectToString.call(value), + Ctor = result == objectTag ? value.constructor : undefined, + ctorString = Ctor ? toSource(Ctor) : undefined; + + if (ctorString) { + switch (ctorString) { + case dataViewCtorString: return dataViewTag; + case mapCtorString: return mapTag; + case promiseCtorString: return promiseTag; + case setCtorString: return setTag; + case weakMapCtorString: return weakMapTag; + } + } + return result; + }; + } + + /** + * Initializes an array clone. + * + * @private + * @param {Array} array The array to clone. + * @returns {Array} Returns the initialized clone. + */ + function initCloneArray(array) { + var length = array.length, + result = array.constructor(length); + + // Add properties assigned by `RegExp#exec`. + if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) { + result.index = array.index; + result.input = array.input; + } + return result; + } + + /** + * Initializes an object clone. + * + * @private + * @param {Object} object The object to clone. + * @returns {Object} Returns the initialized clone. + */ + function initCloneObject(object) { + return (typeof object.constructor == 'function' && !isPrototype(object)) + ? baseCreate(getPrototype(object)) + : {}; + } + + /** + * Initializes an object clone based on its `toStringTag`. + * + * **Note:** This function only supports cloning values with tags of + * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. + * + * @private + * @param {Object} object The object to clone. + * @param {string} tag The `toStringTag` of the object to clone. + * @param {Function} cloneFunc The function to clone values. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the initialized clone. + */ + function initCloneByTag(object, tag, cloneFunc, isDeep) { + var Ctor = object.constructor; + switch (tag) { + case arrayBufferTag: + return cloneArrayBuffer(object); + + case boolTag: + case dateTag: + return new Ctor(+object); + + case dataViewTag: + return cloneDataView(object, isDeep); + + case float32Tag: case float64Tag: + case int8Tag: case int16Tag: case int32Tag: + case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag: + return cloneTypedArray(object, isDeep); + + case mapTag: + return cloneMap(object, isDeep, cloneFunc); + + case numberTag: + case stringTag: + return new Ctor(object); + + case regexpTag: + return cloneRegExp(object); + + case setTag: + return cloneSet(object, isDeep, cloneFunc); + + case symbolTag: + return cloneSymbol(object); + } + } + + /** + * Checks if `value` is a valid array-like index. + * + * @private + * @param {*} value The value to check. + * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. + * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. + */ + function isIndex(value, length) { + length = length == null ? MAX_SAFE_INTEGER : length; + return !!length && + (typeof value == 'number' || reIsUint.test(value)) && + (value > -1 && value % 1 == 0 && value < length); + } + + /** + * Checks if `value` is suitable for use as unique object key. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is suitable, else `false`. + */ + function isKeyable(value) { + var type = typeof value; + return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean') + ? (value !== '__proto__') + : (value === null); + } + + /** + * Checks if `func` has its source masked. + * + * @private + * @param {Function} func The function to check. + * @returns {boolean} Returns `true` if `func` is masked, else `false`. + */ + function isMasked(func) { + return !!maskSrcKey && (maskSrcKey in func); + } + + /** + * Checks if `value` is likely a prototype object. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a prototype, else `false`. + */ + function isPrototype(value) { + var Ctor = value && value.constructor, + proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto; + + return value === proto; + } + + /** + * Converts `func` to its source code. + * + * @private + * @param {Function} func The function to process. + * @returns {string} Returns the source code. + */ + function toSource(func) { + if (func != null) { + try { + return funcToString.call(func); + } catch (e) {} + try { + return (func + ''); + } catch (e) {} + } + return ''; + } + + /** + * This method is like `_.clone` except that it recursively clones `value`. + * + * @static + * @memberOf _ + * @since 1.0.0 + * @category Lang + * @param {*} value The value to recursively clone. + * @returns {*} Returns the deep cloned value. + * @see _.clone + * @example + * + * var objects = [{ 'a': 1 }, { 'b': 2 }]; + * + * var deep = _.cloneDeep(objects); + * console.log(deep[0] === objects[0]); + * // => false + */ + function cloneDeep(value) { + return baseClone(value, true, true); + } + + /** + * Performs a + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * comparison between two values to determine if they are equivalent. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'a': 1 }; + * var other = { 'a': 1 }; + * + * _.eq(object, object); + * // => true + * + * _.eq(object, other); + * // => false + * + * _.eq('a', 'a'); + * // => true + * + * _.eq('a', Object('a')); + * // => false + * + * _.eq(NaN, NaN); + * // => true + */ + function eq(value, other) { + return value === other || (value !== value && other !== other); + } + + /** + * Checks if `value` is likely an `arguments` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an `arguments` object, + * else `false`. + * @example + * + * _.isArguments(function() { return arguments; }()); + * // => true + * + * _.isArguments([1, 2, 3]); + * // => false + */ + function isArguments(value) { + // Safari 8.1 makes `arguments.callee` enumerable in strict mode. + return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') && + (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag); + } + + /** + * Checks if `value` is classified as an `Array` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array, else `false`. + * @example + * + * _.isArray([1, 2, 3]); + * // => true + * + * _.isArray(document.body.children); + * // => false + * + * _.isArray('abc'); + * // => false + * + * _.isArray(_.noop); + * // => false + */ + var isArray = Array.isArray; + + /** + * Checks if `value` is array-like. A value is considered array-like if it's + * not a function and has a `value.length` that's an integer greater than or + * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is array-like, else `false`. + * @example + * + * _.isArrayLike([1, 2, 3]); + * // => true + * + * _.isArrayLike(document.body.children); + * // => true + * + * _.isArrayLike('abc'); + * // => true + * + * _.isArrayLike(_.noop); + * // => false + */ + function isArrayLike(value) { + return value != null && isLength(value.length) && !isFunction(value); + } + + /** + * This method is like `_.isArrayLike` except that it also checks if `value` + * is an object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array-like object, + * else `false`. + * @example + * + * _.isArrayLikeObject([1, 2, 3]); + * // => true + * + * _.isArrayLikeObject(document.body.children); + * // => true + * + * _.isArrayLikeObject('abc'); + * // => false + * + * _.isArrayLikeObject(_.noop); + * // => false + */ + function isArrayLikeObject(value) { + return isObjectLike(value) && isArrayLike(value); + } + + /** + * Checks if `value` is a buffer. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a buffer, else `false`. + * @example + * + * _.isBuffer(new Buffer(2)); + * // => true + * + * _.isBuffer(new Uint8Array(2)); + * // => false + */ + var isBuffer = nativeIsBuffer || stubFalse; + + /** + * Checks if `value` is classified as a `Function` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a function, else `false`. + * @example + * + * _.isFunction(_); + * // => true + * + * _.isFunction(/abc/); + * // => false + */ + function isFunction(value) { + // The use of `Object#toString` avoids issues with the `typeof` operator + // in Safari 8-9 which returns 'object' for typed array and other constructors. + var tag = isObject(value) ? objectToString.call(value) : ''; + return tag == funcTag || tag == genTag; + } + + /** + * Checks if `value` is a valid array-like length. + * + * **Note:** This method is loosely based on + * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. + * @example + * + * _.isLength(3); + * // => true + * + * _.isLength(Number.MIN_VALUE); + * // => false + * + * _.isLength(Infinity); + * // => false + * + * _.isLength('3'); + * // => false + */ + function isLength(value) { + return typeof value == 'number' && + value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; + } + + /** + * Checks if `value` is the + * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) + * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(_.noop); + * // => true + * + * _.isObject(null); + * // => false + */ + function isObject(value) { + var type = typeof value; + return !!value && (type == 'object' || type == 'function'); + } + + /** + * Checks if `value` is object-like. A value is object-like if it's not `null` + * and has a `typeof` result of "object". + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @example + * + * _.isObjectLike({}); + * // => true + * + * _.isObjectLike([1, 2, 3]); + * // => true + * + * _.isObjectLike(_.noop); + * // => false + * + * _.isObjectLike(null); + * // => false + */ + function isObjectLike(value) { + return !!value && typeof value == 'object'; + } + + /** + * Creates an array of the own enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. See the + * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) + * for more details. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keys(new Foo); + * // => ['a', 'b'] (iteration order is not guaranteed) + * + * _.keys('hi'); + * // => ['0', '1'] + */ + function keys(object) { + return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object); + } + + /** + * This method returns a new empty array. + * + * @static + * @memberOf _ + * @since 4.13.0 + * @category Util + * @returns {Array} Returns the new empty array. + * @example + * + * var arrays = _.times(2, _.stubArray); + * + * console.log(arrays); + * // => [[], []] + * + * console.log(arrays[0] === arrays[1]); + * // => false + */ + function stubArray() { + return []; + } + + /** + * This method returns `false`. + * + * @static + * @memberOf _ + * @since 4.13.0 + * @category Util + * @returns {boolean} Returns `false`. + * @example + * + * _.times(2, _.stubFalse); + * // => [false, false] + */ + function stubFalse() { + return false; + } + + module.exports = cloneDeep; + } (lodash_clonedeep, lodash_clonedeep.exports)); + + var lodash_clonedeepExports = lodash_clonedeep.exports; + var cloneDeep = /*@__PURE__*/getDefaultExportFromCjs$1(lodash_clonedeepExports); + + function applyContextDelta(context, delta, logger) { + try { + if (logger?.canPublish("trace")) { + logger?.trace(`applying context delta ${JSON.stringify(delta)} on context ${JSON.stringify(context)}`); + } + if (!delta) { + return context; + } + if (delta.reset) { + context = { ...delta.reset }; + return context; + } + context = deepClone(context, undefined); + if (delta.commands) { + for (const command of delta.commands) { + if (command.type === "remove") { + deletePath(context, command.path); + } + else if (command.type === "set") { + setValueToPath(context, command.value, command.path); + } + } + return context; + } + const added = delta.added; + const updated = delta.updated; + const removed = delta.removed; + if (added) { + Object.keys(added).forEach((key) => { + context[key] = added[key]; + }); + } + if (updated) { + Object.keys(updated).forEach((key) => { + mergeObjectsProperties(key, context, updated); + }); + } + if (removed) { + removed.forEach((key) => { + delete context[key]; + }); + } + return context; + } + catch (e) { + logger?.error(`error applying context delta ${JSON.stringify(delta)} on context ${JSON.stringify(context)}`, e); + return context; + } + } + function deepClone(obj, hash) { + return cloneDeep(obj); + } + const mergeObjectsProperties = (key, what, withWhat) => { + const right = withWhat[key]; + if (right === undefined) { + return what; + } + const left = what[key]; + if (!left || !right) { + what[key] = right; + return what; + } + if (typeof left === "string" || + typeof left === "number" || + typeof left === "boolean" || + typeof right === "string" || + typeof right === "number" || + typeof right === "boolean" || + Array.isArray(left) || + Array.isArray(right)) { + what[key] = right; + return what; + } + what[key] = Object.assign({}, left, right); + return what; + }; + function deepEqual(x, y) { + if (x === y) { + return true; + } + if (!(x instanceof Object) || !(y instanceof Object)) { + return false; + } + if (x.constructor !== y.constructor) { + return false; + } + for (const p in x) { + if (!x.hasOwnProperty(p)) { + continue; + } + if (!y.hasOwnProperty(p)) { + return false; + } + if (x[p] === y[p]) { + continue; + } + if (typeof (x[p]) !== "object") { + return false; + } + if (!deepEqual(x[p], y[p])) { + return false; + } + } + for (const p in y) { + if (y.hasOwnProperty(p) && !x.hasOwnProperty(p)) { + return false; + } + } + return true; + } + function setValueToPath(obj, value, path) { + const pathArr = path.split("."); + let i; + for (i = 0; i < pathArr.length - 1; i++) { + if (!obj[pathArr[i]]) { + obj[pathArr[i]] = {}; + } + if (typeof obj[pathArr[i]] !== "object") { + obj[pathArr[i]] = {}; + } + obj = obj[pathArr[i]]; + } + obj[pathArr[i]] = value; + } + function isSubset(superObj, subObj) { + return Object.keys(subObj).every((ele) => { + if (typeof subObj[ele] === "object") { + return isSubset(superObj?.[ele] || {}, subObj[ele] || {}); + } + return subObj[ele] === superObj?.[ele]; + }); + } + function deletePath(obj, path) { + const pathArr = path.split("."); + let i; + for (i = 0; i < pathArr.length - 1; i++) { + if (!obj[pathArr[i]]) { + return; + } + obj = obj[pathArr[i]]; + } + delete obj[pathArr[i]]; + } + + let GW3Bridge$1 = class GW3Bridge { + _logger; + _connection; + _trackAllContexts; + _reAnnounceKnownContexts; + _gw3Session; + _contextNameToData = {}; + _gw3Subscriptions = []; + _nextCallbackSubscriptionNumber = 0; + _creationPromises = {}; + _contextNameToId = {}; + _contextIdToName = {}; + _protocolVersion = undefined; + _contextsTempCache = {}; + _contextsSubscriptionsCache = []; + _systemContextsSubKey; + get protocolVersion() { + if (!this._protocolVersion) { + const contextsDomainInfo = this._connection.availableDomains.find((d) => d.uri === "context"); + this._protocolVersion = contextsDomainInfo?.version ?? 1; + } + return this._protocolVersion; + } + get setPathSupported() { + return this.protocolVersion >= 2; + } + constructor(config) { + this._connection = config.connection; + this._logger = config.logger; + this._trackAllContexts = config.trackAllContexts; + this._reAnnounceKnownContexts = config.reAnnounceKnownContexts; + this._gw3Session = this._connection.domain("global", [ + GW_MESSAGE_CONTEXT_CREATED, + GW_MESSAGE_SUBSCRIBED_CONTEXT, + GW_MESSAGE_CONTEXT_DESTROYED, + GW_MESSAGE_CONTEXT_UPDATED, + ]); + this._gw3Session.disconnected(this.resetState.bind(this)); + this._gw3Session.onJoined((wasReconnect) => { + if (!wasReconnect) { + return; + } + if (!this._reAnnounceKnownContexts) { + return this._connection.setLibReAnnounced({ name: "contexts" }); + } + this.reInitiateState().then(() => this._connection.setLibReAnnounced({ name: "contexts" })); + }); + this.subscribeToContextCreatedMessages(); + this.subscribeToContextUpdatedMessages(); + this.subscribeToContextDestroyedMessages(); + this._connection.replayer?.drain(ContextMessageReplaySpec.name, (message) => { + const type = message.type; + if (!type) { + return; + } + if (type === GW_MESSAGE_CONTEXT_CREATED || + type === GW_MESSAGE_CONTEXT_ADDED || + type === GW_MESSAGE_ACTIVITY_CREATED) { + this.handleContextCreatedMessage(message); + } + else if (type === GW_MESSAGE_SUBSCRIBED_CONTEXT || + type === GW_MESSAGE_CONTEXT_UPDATED || + type === GW_MESSAGE_JOINED_ACTIVITY) { + this.handleContextUpdatedMessage(message); + } + else if (type === GW_MESSAGE_CONTEXT_DESTROYED || + type === GW_MESSAGE_ACTIVITY_DESTROYED) { + this.handleContextDestroyedMessage(message); + } + }); + } + dispose() { + for (const sub of this._gw3Subscriptions) { + this._connection.off(sub); + } + this._gw3Subscriptions.length = 0; + for (const contextName in this._contextNameToData) { + if (this._contextNameToId.hasOwnProperty(contextName)) { + delete this._contextNameToData[contextName]; + } + } + } + createContext(name, data) { + if (name in this._creationPromises) { + return this._creationPromises[name]; + } + this._creationPromises[name] = + this._gw3Session + .send({ + type: GW_MESSAGE_CREATE_CONTEXT, + domain: "global", + name, + data, + lifetime: "retained", + }) + .then((createContextMsg) => { + this._contextNameToId[name] = createContextMsg.context_id; + this._contextIdToName[createContextMsg.context_id] = name; + const contextData = this._contextNameToData[name] || new GW3ContextData(createContextMsg.context_id, name, true, undefined); + contextData.isAnnounced = true; + contextData.name = name; + contextData.contextId = createContextMsg.context_id; + contextData.context = createContextMsg.data || deepClone(data); + contextData.hasReceivedSnapshot = true; + this._contextNameToData[name] = contextData; + delete this._creationPromises[name]; + return createContextMsg.context_id; + }); + return this._creationPromises[name]; + } + all() { + return Object.keys(this._contextNameToData) + .filter((name) => this._contextNameToData[name].isAnnounced); + } + async update(name, delta) { + if (delta) { + delta = deepClone(delta); + } + if (name in this._creationPromises) { + await this._creationPromises[name]; + } + const contextData = this._contextNameToData[name]; + if (!contextData || !contextData.isAnnounced) { + return this.createContext(name, delta); + } + let currentContext = contextData.context; + if (!contextData.hasCallbacks()) { + currentContext = await this.get(contextData.name); + } + const calculatedDelta = this.setPathSupported ? + this.calculateContextDeltaV2(currentContext, delta) : + this.calculateContextDeltaV1(currentContext, delta); + if (!Object.keys(calculatedDelta.added).length + && !Object.keys(calculatedDelta.updated).length + && !calculatedDelta.removed.length + && !calculatedDelta.commands?.length) { + return Promise.resolve(); + } + return this._gw3Session + .send({ + type: GW_MESSAGE_UPDATE_CONTEXT, + domain: "global", + context_id: contextData.contextId, + delta: calculatedDelta, + }, {}, { skipPeerId: false }) + .then((gwResponse) => { + this.handleUpdated(contextData, calculatedDelta, { + updaterId: gwResponse.peer_id + }); + }); + } + async set(name, data) { + if (data) { + data = deepClone(data); + } + if (name in this._creationPromises) { + await this._creationPromises[name]; + } + const contextData = this._contextNameToData[name]; + if (!contextData || !contextData.isAnnounced) { + return this.createContext(name, data); + } + return this._gw3Session + .send({ + type: GW_MESSAGE_UPDATE_CONTEXT, + domain: "global", + context_id: contextData.contextId, + delta: { reset: data }, + }, {}, { skipPeerId: false }) + .then((gwResponse) => { + this.handleUpdated(contextData, { + reset: data, + added: {}, + removed: [], + updated: {} + }, { + updaterId: gwResponse.peer_id + }); + }); + } + setPath(name, path, value) { + if (!this.setPathSupported) { + return Promise.reject("glue.contexts.setPath operation is not supported, use Glue42 3.10 or later"); + } + return this.setPaths(name, [{ path, value }]); + } + async setPaths(name, pathValues) { + if (!this.setPathSupported) { + return Promise.reject("glue.contexts.setPaths operation is not supported, use Glue42 3.10 or later"); + } + if (pathValues) { + pathValues = deepClone(pathValues); + } + if (name in this._creationPromises) { + await this._creationPromises[name]; + } + const contextData = this._contextNameToData[name]; + if (!contextData || !contextData.isAnnounced) { + const obj = {}; + for (const pathValue of pathValues) { + setValueToPath(obj, pathValue.value, pathValue.path); + } + return this.createContext(name, obj); + } + const commands = []; + for (const pathValue of pathValues) { + if (pathValue.value === null) { + commands.push({ type: "remove", path: pathValue.path }); + } + else { + commands.push({ type: "set", path: pathValue.path, value: pathValue.value }); + } + } + return this._gw3Session + .send({ + type: GW_MESSAGE_UPDATE_CONTEXT, + domain: "global", + context_id: contextData.contextId, + delta: { commands } + }, {}, { skipPeerId: false }) + .then((gwResponse) => { + this.handleUpdated(contextData, { + added: {}, + removed: [], + updated: {}, + commands + }, { + updaterId: gwResponse.peer_id + }); + }); + } + async get(name) { + if (name in this._creationPromises) { + await this._creationPromises[name]; + } + const contextData = this._contextNameToData[name]; + if (!contextData || !contextData.isAnnounced) { + return Promise.resolve({}); + } + if (contextData && (!contextData.hasCallbacks() || !contextData.hasReceivedSnapshot)) { + return new Promise((resolve) => { + this.subscribe(name, (data, _d, _r, un) => { + this.unsubscribe(un); + resolve(data); + }); + }); + } + const context = contextData?.context ?? {}; + return Promise.resolve(deepClone(context)); + } + async subscribe(name, callback, subscriptionKey) { + if (name in this._creationPromises) { + await this._creationPromises[name]; + } + const thisCallbackSubscriptionNumber = typeof subscriptionKey === "undefined" ? this._nextCallbackSubscriptionNumber : subscriptionKey; + if (typeof subscriptionKey === "undefined") { + this._nextCallbackSubscriptionNumber += 1; + } + if (this._contextsSubscriptionsCache.every((subscription) => subscription.subKey !== this._nextCallbackSubscriptionNumber)) { + this._contextsSubscriptionsCache.push({ contextName: name, subKey: thisCallbackSubscriptionNumber, callback }); + } + let contextData = this._contextNameToData[name]; + if (!contextData || + !contextData.isAnnounced) { + contextData = contextData || new GW3ContextData(undefined, name, false, undefined); + this._contextNameToData[name] = contextData; + contextData.updateCallbacks[thisCallbackSubscriptionNumber] = callback; + return Promise.resolve(thisCallbackSubscriptionNumber); + } + const hadCallbacks = contextData.hasCallbacks(); + contextData.updateCallbacks[thisCallbackSubscriptionNumber] = callback; + if (!hadCallbacks) { + if (!contextData.joinedActivity) { + if (contextData.context && contextData.sentExplicitSubscription) { + if (contextData.hasReceivedSnapshot) { + const clone = deepClone(contextData.context); + callback(clone, clone, [], thisCallbackSubscriptionNumber); + } + return Promise.resolve(thisCallbackSubscriptionNumber); + } + return this.sendSubscribe(contextData) + .then(() => thisCallbackSubscriptionNumber); + } + else { + if (contextData.hasReceivedSnapshot) { + const clone = deepClone(contextData.context); + callback(clone, clone, [], thisCallbackSubscriptionNumber); + } + return Promise.resolve(thisCallbackSubscriptionNumber); + } + } + else { + if (contextData.hasReceivedSnapshot) { + const clone = deepClone(contextData.context); + callback(clone, clone, [], thisCallbackSubscriptionNumber); + } + return Promise.resolve(thisCallbackSubscriptionNumber); + } + } + unsubscribe(subscriptionKey) { + this._contextsSubscriptionsCache = this._contextsSubscriptionsCache.filter((subscription) => subscription.subKey !== subscriptionKey); + for (const name of Object.keys(this._contextNameToData)) { + const contextData = this._contextNameToData[name]; + if (!contextData) { + return; + } + const hadCallbacks = contextData.hasCallbacks(); + delete contextData.updateCallbacks[subscriptionKey]; + if (contextData.isAnnounced && + hadCallbacks && + !contextData.hasCallbacks() && + contextData.sentExplicitSubscription) { + this.sendUnsubscribe(contextData).catch(() => { }); + } + if (!contextData.isAnnounced && + !contextData.hasCallbacks()) { + delete this._contextNameToData[name]; + } + } + } + async destroy(name) { + if (name in this._creationPromises) { + await this._creationPromises[name]; + } + const contextData = this._contextNameToData[name]; + if (!contextData) { + return Promise.reject(`context with ${name} does not exist`); + } + return this._gw3Session + .send({ + type: GW_MESSAGE_DESTROY_CONTEXT, + domain: "global", + context_id: contextData.contextId, + }).then((_) => undefined); + } + handleUpdated(contextData, delta, extraData) { + const oldContext = contextData.context; + contextData.context = applyContextDelta(contextData.context, delta, this._logger); + contextData.hasReceivedSnapshot = true; + if (this._contextNameToData[contextData.name] === contextData && + !deepEqual(oldContext, contextData.context)) { + this.invokeUpdateCallbacks(contextData, delta, extraData); + } + } + subscribeToContextCreatedMessages() { + const createdMessageTypes = [ + GW_MESSAGE_CONTEXT_ADDED, + GW_MESSAGE_CONTEXT_CREATED, + GW_MESSAGE_ACTIVITY_CREATED, + ]; + for (const createdMessageType of createdMessageTypes) { + const sub = this._connection.on(createdMessageType, this.handleContextCreatedMessage.bind(this)); + this._gw3Subscriptions.push(sub); + } + } + handleContextCreatedMessage(contextCreatedMsg) { + const createdMessageType = contextCreatedMsg.type; + if (createdMessageType === GW_MESSAGE_ACTIVITY_CREATED) { + this._contextNameToId[contextCreatedMsg.activity_id] = contextCreatedMsg.context_id; + this._contextIdToName[contextCreatedMsg.context_id] = contextCreatedMsg.activity_id; + } + else if (createdMessageType === GW_MESSAGE_CONTEXT_ADDED) { + this._contextNameToId[contextCreatedMsg.name] = contextCreatedMsg.context_id; + this._contextIdToName[contextCreatedMsg.context_id] = contextCreatedMsg.name; + } + else ; + const name = this._contextIdToName[contextCreatedMsg.context_id]; + if (!name) { + throw new Error("Received created event for context with unknown name: " + contextCreatedMsg.context_id); + } + if (!this._contextNameToId[name]) { + throw new Error("Received created event for context with unknown id: " + contextCreatedMsg.context_id); + } + let contextData = this._contextNameToData[name]; + if (contextData) { + if (contextData.isAnnounced) { + return; + } + else { + if (!contextData.hasCallbacks()) { + throw new Error("Assertion failure: contextData.hasCallbacks()"); + } + contextData.isAnnounced = true; + contextData.contextId = contextCreatedMsg.context_id; + contextData.activityId = contextCreatedMsg.activity_id; + if (!contextData.sentExplicitSubscription) { + this.sendSubscribe(contextData); + } + } + } + else { + this._contextNameToData[name] = contextData = + new GW3ContextData(contextCreatedMsg.context_id, name, true, contextCreatedMsg.activity_id); + if (this._trackAllContexts) { + this.subscribe(name, () => { }).then((subKey) => this._systemContextsSubKey = subKey); + } + } + } + subscribeToContextUpdatedMessages() { + const updatedMessageTypes = [ + GW_MESSAGE_CONTEXT_UPDATED, + GW_MESSAGE_SUBSCRIBED_CONTEXT, + GW_MESSAGE_JOINED_ACTIVITY, + ]; + for (const updatedMessageType of updatedMessageTypes) { + const sub = this._connection.on(updatedMessageType, this.handleContextUpdatedMessage.bind(this)); + this._gw3Subscriptions.push(sub); + } + } + handleContextUpdatedMessage(contextUpdatedMsg) { + const updatedMessageType = contextUpdatedMsg.type; + const contextId = contextUpdatedMsg.context_id; + let contextData = this._contextNameToData[this._contextIdToName[contextId]]; + const justSeen = !contextData || !contextData.isAnnounced; + if (updatedMessageType === GW_MESSAGE_JOINED_ACTIVITY) { + if (!contextData) { + contextData = + this._contextNameToData[contextUpdatedMsg.activity_id] || + new GW3ContextData(contextId, contextUpdatedMsg.activity_id, true, contextUpdatedMsg.activity_id); + } + this._contextNameToData[contextUpdatedMsg.activity_id] = contextData; + this._contextIdToName[contextId] = contextUpdatedMsg.activity_id; + this._contextNameToId[contextUpdatedMsg.activity_id] = contextId; + contextData.contextId = contextId; + contextData.isAnnounced = true; + contextData.activityId = contextUpdatedMsg.activity_id; + contextData.joinedActivity = true; + } + else { + if (!contextData || !contextData.isAnnounced) { + if (updatedMessageType === GW_MESSAGE_SUBSCRIBED_CONTEXT) { + contextData = contextData || new GW3ContextData(contextId, contextUpdatedMsg.name, true, undefined); + contextData.sentExplicitSubscription = true; + this._contextNameToData[contextUpdatedMsg.name] = contextData; + this._contextIdToName[contextId] = contextUpdatedMsg.name; + this._contextNameToId[contextUpdatedMsg.name] = contextId; + } + else { + this._logger.error(`Received 'update' for unknown context: ${contextId}`); + } + return; + } + } + const oldContext = contextData.context; + contextData.hasReceivedSnapshot = true; + if (updatedMessageType === GW_MESSAGE_SUBSCRIBED_CONTEXT) { + contextData.context = contextUpdatedMsg.data || {}; + } + else if (updatedMessageType === GW_MESSAGE_JOINED_ACTIVITY) { + contextData.context = contextUpdatedMsg.context_snapshot || {}; + } + else if (updatedMessageType === GW_MESSAGE_CONTEXT_UPDATED) { + contextData.context = applyContextDelta(contextData.context, contextUpdatedMsg.delta, this._logger); + } + else { + throw new Error("Unrecognized context update message " + updatedMessageType); + } + if (justSeen || + !deepEqual(contextData.context, oldContext) || + updatedMessageType === GW_MESSAGE_SUBSCRIBED_CONTEXT) { + this.invokeUpdateCallbacks(contextData, contextUpdatedMsg.delta, { updaterId: contextUpdatedMsg.updater_id }); + } + } + invokeUpdateCallbacks(contextData, delta, extraData) { + delta = delta || { added: {}, updated: {}, reset: {}, removed: [] }; + if (delta.commands) { + delta.added = delta.updated = delta.reset = {}; + delta.removed = []; + for (const command of delta.commands) { + if (command.type === "remove") { + if (command.path.indexOf(".") === -1) { + delta.removed.push(command.path); + } + setValueToPath(delta.updated, null, command.path); + } + else if (command.type === "set") { + setValueToPath(delta.updated, command.value, command.path); + } + } + } + for (const updateCallbackIndex in contextData.updateCallbacks) { + if (contextData.updateCallbacks.hasOwnProperty(updateCallbackIndex)) { + try { + const updateCallback = contextData.updateCallbacks[updateCallbackIndex]; + updateCallback(deepClone(contextData.context), deepClone(Object.assign({}, delta.added || {}, delta.updated || {}, delta.reset || {})), delta.removed, parseInt(updateCallbackIndex, 10), extraData); + } + catch (err) { + this._logger.debug("callback error: " + JSON.stringify(err)); + } + } + } + } + subscribeToContextDestroyedMessages() { + const destroyedMessageTypes = [ + GW_MESSAGE_CONTEXT_DESTROYED, + GW_MESSAGE_ACTIVITY_DESTROYED, + ]; + for (const destroyedMessageType of destroyedMessageTypes) { + const sub = this._connection.on(destroyedMessageType, this.handleContextDestroyedMessage.bind(this)); + this._gw3Subscriptions.push(sub); + } + } + handleContextDestroyedMessage(destroyedMsg) { + const destroyedMessageType = destroyedMsg.type; + let contextId; + let name; + if (destroyedMessageType === GW_MESSAGE_ACTIVITY_DESTROYED) { + name = destroyedMsg.activity_id; + contextId = this._contextNameToId[name]; + if (!contextId) { + this._logger.error(`Received 'destroyed' for unknown activity: ${destroyedMsg.activity_id}`); + return; + } + } + else { + contextId = destroyedMsg.context_id; + name = this._contextIdToName[contextId]; + if (!name) { + this._logger.error(`Received 'destroyed' for unknown context: ${destroyedMsg.context_id}`); + return; + } + } + delete this._contextIdToName[contextId]; + delete this._contextNameToId[name]; + const contextData = this._contextNameToData[name]; + delete this._contextNameToData[name]; + if (!contextData || !contextData.isAnnounced) { + this._logger.error(`Received 'destroyed' for unknown context: ${contextId}`); + return; + } + } + sendSubscribe(contextData) { + contextData.sentExplicitSubscription = true; + return this._gw3Session + .send({ + type: GW_MESSAGE_SUBSCRIBE_CONTEXT, + domain: "global", + context_id: contextData.contextId, + }).then((_) => undefined); + } + sendUnsubscribe(contextData) { + contextData.sentExplicitSubscription = false; + return this._gw3Session + .send({ + type: GW_MESSAGE_UNSUBSCRIBE_CONTEXT, + domain: "global", + context_id: contextData.contextId, + }).then((_) => undefined); + } + calculateContextDeltaV1(from, to) { + const delta = { added: {}, updated: {}, removed: [], reset: undefined }; + if (from) { + for (const x of Object.keys(from)) { + if (Object.keys(to).indexOf(x) !== -1 + && to[x] !== null + && !deepEqual(from[x], to[x])) { + delta.updated[x] = to[x]; + } + } + } + for (const x of Object.keys(to)) { + if (!from || (Object.keys(from).indexOf(x) === -1)) { + if (to[x] !== null) { + delta.added[x] = to[x]; + } + } + else if (to[x] === null) { + delta.removed.push(x); + } + } + return delta; + } + calculateContextDeltaV2(from, to) { + const delta = { added: {}, updated: {}, removed: [], reset: undefined, commands: [] }; + for (const x of Object.keys(to)) { + if (to[x] !== null) { + const fromX = from ? from[x] : null; + if (!deepEqual(fromX, to[x])) { + delta.commands?.push({ type: "set", path: x, value: to[x] }); + } + } + else { + delta.commands?.push({ type: "remove", path: x }); + } + } + return delta; + } + resetState() { + for (const sub of this._gw3Subscriptions) { + this._connection.off(sub); + } + if (this._systemContextsSubKey) { + this.unsubscribe(this._systemContextsSubKey); + delete this._systemContextsSubKey; + } + this._gw3Subscriptions = []; + this._contextNameToId = {}; + this._contextIdToName = {}; + delete this._protocolVersion; + this._contextsTempCache = Object.keys(this._contextNameToData).reduce((cacheSoFar, ctxName) => { + const contextData = this._contextNameToData[ctxName]; + if (contextData.isAnnounced && (contextData.activityId || contextData.sentExplicitSubscription)) { + cacheSoFar[ctxName] = this._contextNameToData[ctxName].context; + } + return cacheSoFar; + }, {}); + this._contextNameToData = {}; + } + async reInitiateState() { + this.subscribeToContextCreatedMessages(); + this.subscribeToContextUpdatedMessages(); + this.subscribeToContextDestroyedMessages(); + this._connection.replayer?.drain(ContextMessageReplaySpec.name, (message) => { + const type = message.type; + if (!type) { + return; + } + if (type === GW_MESSAGE_CONTEXT_CREATED || + type === GW_MESSAGE_CONTEXT_ADDED || + type === GW_MESSAGE_ACTIVITY_CREATED) { + this.handleContextCreatedMessage(message); + } + else if (type === GW_MESSAGE_SUBSCRIBED_CONTEXT || + type === GW_MESSAGE_CONTEXT_UPDATED || + type === GW_MESSAGE_JOINED_ACTIVITY) { + this.handleContextUpdatedMessage(message); + } + else if (type === GW_MESSAGE_CONTEXT_DESTROYED || + type === GW_MESSAGE_ACTIVITY_DESTROYED) { + this.handleContextDestroyedMessage(message); + } + }); + await Promise.all(this._contextsSubscriptionsCache.map((subscription) => this.subscribe(subscription.contextName, subscription.callback, subscription.subKey))); + await this.flushQueue(); + for (const ctxName in this._contextsTempCache) { + if (typeof this._contextsTempCache[ctxName] !== "object" || Object.keys(this._contextsTempCache[ctxName]).length === 0) { + continue; + } + const lastKnownData = this._contextsTempCache[ctxName]; + this._logger.info(`Re-announcing known context: ${ctxName}`); + await this.flushQueue(); + await this.update(ctxName, lastKnownData); + } + this._contextsTempCache = {}; + this._logger.info("Contexts are re-announced"); + } + flushQueue() { + return new Promise((resolve) => setTimeout(() => resolve(), 0)); + } + }; + + class ContextsModule { + initTime; + initStartTime; + initEndTime; + _bridge; + constructor(config) { + this._bridge = new GW3Bridge$1(config); + } + all() { + return this._bridge.all(); + } + update(name, data) { + this.checkName(name); + this.checkData(data); + return this._bridge.update(name, data); + } + set(name, data) { + this.checkName(name); + this.checkData(data); + return this._bridge.set(name, data); + } + setPath(name, path, data) { + this.checkName(name); + this.checkPath(path); + const isTopLevelPath = path === ""; + if (isTopLevelPath) { + this.checkData(data); + return this.set(name, data); + } + return this._bridge.setPath(name, path, data); + } + setPaths(name, paths) { + this.checkName(name); + if (!Array.isArray(paths)) { + throw new Error("Please provide the paths as an array of PathValues!"); + } + for (const { path, value } of paths) { + this.checkPath(path); + const isTopLevelPath = path === ""; + if (isTopLevelPath) { + this.checkData(value); + } + } + return this._bridge.setPaths(name, paths); + } + subscribe(name, callback) { + this.checkName(name); + if (typeof callback !== "function") { + throw new Error("Please provide the callback as a function!"); + } + return this._bridge + .subscribe(name, (data, delta, removed, key, extraData) => callback(data, delta, removed, () => this._bridge.unsubscribe(key), extraData)) + .then((key) => () => { + this._bridge.unsubscribe(key); + }); + } + get(name) { + this.checkName(name); + return this._bridge.get(name); + } + ready() { + return Promise.resolve(this); + } + destroy(name) { + this.checkName(name); + return this._bridge.destroy(name); + } + get setPathSupported() { + return this._bridge.setPathSupported; + } + checkName(name) { + if (typeof name !== "string" || name === "") { + throw new Error("Please provide the name as a non-empty string!"); + } + } + checkPath(path) { + if (typeof path !== "string") { + throw new Error("Please provide the path as a dot delimited string!"); + } + } + checkData(data) { + if (typeof data !== "object") { + throw new Error("Please provide the data as an object!"); + } + } + } + + function promisify$2 (promise, successCallback, errorCallback) { + if (typeof successCallback !== "function" && typeof errorCallback !== "function") { + return promise; + } + if (typeof successCallback !== "function") { + successCallback = () => { }; + } + else if (typeof errorCallback !== "function") { + errorCallback = () => { }; + } + return promise.then(successCallback, errorCallback); + } + + function rejectAfter(ms = 0, promise, error) { + let timeout; + const clearTimeoutIfThere = () => { + if (timeout) { + clearTimeout(timeout); + } + }; + promise + .then(() => { + clearTimeoutIfThere(); + }) + .catch(() => { + clearTimeoutIfThere(); + }); + return new Promise((resolve, reject) => { + timeout = setTimeout(() => reject(error), ms); + }); + } + + var InvokeStatus; + (function (InvokeStatus) { + InvokeStatus[InvokeStatus["Success"] = 0] = "Success"; + InvokeStatus[InvokeStatus["Error"] = 1] = "Error"; + })(InvokeStatus || (InvokeStatus = {})); + class Client { + protocol; + repo; + instance; + configuration; + constructor(protocol, repo, instance, configuration) { + this.protocol = protocol; + this.repo = repo; + this.instance = instance; + this.configuration = configuration; + } + subscribe(method, options, successCallback, errorCallback, existingSub) { + const callProtocolSubscribe = (targetServers, stream, successProxy, errorProxy) => { + options.methodResponseTimeout = options.methodResponseTimeout ?? options.waitTimeoutMs; + this.protocol.client.subscribe(stream, options, targetServers, successProxy, errorProxy, existingSub); + }; + const promise = new Promise((resolve, reject) => { + const successProxy = (sub) => { + resolve(sub); + }; + const errorProxy = (err) => { + reject(err); + }; + if (!method) { + reject(`Method definition is required. Please, provide either a unique string for a method name or a “methodDefinition” object with a required “name” property.`); + return; + } + let methodDef; + if (typeof method === "string") { + methodDef = { name: method }; + } + else { + methodDef = method; + } + if (!methodDef.name) { + reject(`Method definition is required. Please, provide either a unique string for a method name or a “methodDefinition” object with a required “name” property.`); + return; + } + if (options === undefined) { + options = {}; + } + let target = options.target; + if (target === undefined) { + target = "best"; + } + if (typeof target === "string" && target !== "all" && target !== "best") { + reject(new Error(`"${target}" is not a valid target. Valid targets are "all", "best", or an instance.`)); + return; + } + if (options.methodResponseTimeout === undefined) { + options.methodResponseTimeout = options.method_response_timeout; + if (options.methodResponseTimeout === undefined) { + options.methodResponseTimeout = this.configuration.methodResponseTimeout; + } + } + if (options.waitTimeoutMs === undefined) { + options.waitTimeoutMs = options.wait_for_method_timeout; + if (options.waitTimeoutMs === undefined) { + options.waitTimeoutMs = this.configuration.waitTimeoutMs; + } + } + const delayStep = 500; + let delayTillNow = 0; + let currentServers = this.getServerMethodsByFilterAndTarget(methodDef, target); + if (currentServers.length > 0) { + callProtocolSubscribe(currentServers, currentServers[0].methods[0], successProxy, errorProxy); + } + else { + const retry = () => { + if (!target || !(options.waitTimeoutMs)) { + return; + } + delayTillNow += delayStep; + currentServers = this.getServerMethodsByFilterAndTarget(methodDef, target); + if (currentServers.length > 0) { + const streamInfo = currentServers[0].methods[0]; + callProtocolSubscribe(currentServers, streamInfo, successProxy, errorProxy); + } + else if (delayTillNow >= options.waitTimeoutMs) { + const def = typeof method === "string" ? { name: method } : method; + callProtocolSubscribe(currentServers, def, successProxy, errorProxy); + } + else { + setTimeout(retry, delayStep); + } + }; + setTimeout(retry, delayStep); + } + }); + return promisify$2(promise, successCallback, errorCallback); + } + servers(methodFilter) { + const filterCopy = methodFilter === undefined + ? undefined + : { ...methodFilter }; + return this.getServers(filterCopy).map((serverMethodMap) => { + return serverMethodMap.server.instance; + }); + } + methods(methodFilter) { + if (typeof methodFilter === "string") { + methodFilter = { name: methodFilter }; + } + else { + methodFilter = { ...methodFilter }; + } + return this.getMethods(methodFilter); + } + methodsForInstance(instance) { + return this.getMethodsForInstance(instance); + } + methodAdded(callback) { + return this.repo.onMethodAdded(callback); + } + methodRemoved(callback) { + return this.repo.onMethodRemoved(callback); + } + serverAdded(callback) { + return this.repo.onServerAdded(callback); + } + serverRemoved(callback) { + return this.repo.onServerRemoved((server, reason) => { + callback(server, reason); + }); + } + serverMethodAdded(callback) { + return this.repo.onServerMethodAdded((server, method) => { + callback({ server, method }); + }); + } + serverMethodRemoved(callback) { + return this.repo.onServerMethodRemoved((server, method) => { + callback({ server, method }); + }); + } + async invoke(methodFilter, argumentObj, target, additionalOptions, success, error) { + const getInvokePromise = async () => { + let methodDefinition; + if (typeof methodFilter === "string") { + methodDefinition = { name: methodFilter }; + } + else { + methodDefinition = { ...methodFilter }; + } + if (!methodDefinition.name) { + return Promise.reject(`Method definition is required. Please, provide either a unique string for a method name or a “methodDefinition” object with a required “name” property.`); + } + if (!argumentObj) { + argumentObj = {}; + } + if (!target) { + target = "best"; + } + if (typeof target === "string" && target !== "all" && target !== "best" && target !== "skipMine") { + return Promise.reject(new Error(`"${target}" is not a valid target. Valid targets are "all" and "best".`)); + } + if (!additionalOptions) { + additionalOptions = {}; + } + if (additionalOptions.methodResponseTimeoutMs === undefined) { + additionalOptions.methodResponseTimeoutMs = additionalOptions.method_response_timeout; + if (additionalOptions.methodResponseTimeoutMs === undefined) { + additionalOptions.methodResponseTimeoutMs = this.configuration.methodResponseTimeout; + } + } + if (additionalOptions.waitTimeoutMs === undefined) { + additionalOptions.waitTimeoutMs = additionalOptions.wait_for_method_timeout; + if (additionalOptions.waitTimeoutMs === undefined) { + additionalOptions.waitTimeoutMs = this.configuration.waitTimeoutMs; + } + } + if (additionalOptions.waitTimeoutMs !== undefined && typeof additionalOptions.waitTimeoutMs !== "number") { + return Promise.reject(new Error(`"${additionalOptions.waitTimeoutMs}" is not a valid number for "waitTimeoutMs" `)); + } + if (typeof argumentObj !== "object") { + return Promise.reject(new Error(`The method arguments must be an object. method: ${methodDefinition.name}`)); + } + let serversMethodMap = this.getServerMethodsByFilterAndTarget(methodDefinition, target); + if (serversMethodMap.length === 0) { + try { + serversMethodMap = await this.tryToAwaitForMethods(methodDefinition, target, additionalOptions); + } + catch (err) { + const method = { + ...methodDefinition, + getServers: () => [], + supportsStreaming: false, + objectTypes: methodDefinition.objectTypes ?? [], + flags: methodDefinition.flags?.metadata ?? {} + }; + const errorObj = { + method, + called_with: argumentObj, + message: `Can not find a method matching ${JSON.stringify(methodFilter)} with server filter ${JSON.stringify(target)}`, + executed_by: undefined, + returned: undefined, + status: undefined, + }; + return Promise.reject(errorObj); + } + } + const timeout = additionalOptions.methodResponseTimeoutMs; + const additionalOptionsCopy = additionalOptions; + const invokePromises = serversMethodMap.map((serversMethodPair) => { + const invId = nanoid$1(10); + const method = serversMethodPair.methods[0]; + const server = serversMethodPair.server; + const invokePromise = this.protocol.client.invoke(invId, method, argumentObj, server, additionalOptionsCopy); + return Promise.race([ + invokePromise, + rejectAfter(timeout, invokePromise, { + invocationId: invId, + message: `Invocation timeout (${timeout} ms) reached for method name: ${method?.name}, target instance: ${JSON.stringify(server.instance)}, options: ${JSON.stringify(additionalOptionsCopy)}`, + status: InvokeStatus.Error, + }) + ]); + }); + const invocationMessages = await Promise.all(invokePromises); + const results = this.getInvocationResultObj(invocationMessages, methodDefinition, argumentObj); + const allRejected = invocationMessages.every((result) => result.status === InvokeStatus.Error); + if (allRejected) { + return Promise.reject(results); + } + return results; + }; + return promisify$2(getInvokePromise(), success, error); + } + getInvocationResultObj(invocationResults, method, calledWith) { + const all_return_values = invocationResults + .filter((invokeMessage) => invokeMessage.status === InvokeStatus.Success) + .reduce((allValues, currentValue) => { + allValues = [ + ...allValues, + { + executed_by: currentValue.instance, + returned: currentValue.result, + called_with: calledWith, + method, + message: currentValue.message, + status: currentValue.status, + } + ]; + return allValues; + }, []); + const all_errors = invocationResults + .filter((invokeMessage) => invokeMessage.status === InvokeStatus.Error) + .reduce((allErrors, currError) => { + allErrors = [ + ...allErrors, + { + executed_by: currError.instance, + called_with: calledWith, + name: method.name, + message: currError.message, + } + ]; + return allErrors; + }, []); + const invResult = invocationResults[0]; + const result = { + method, + called_with: calledWith, + returned: invResult.result, + executed_by: invResult.instance, + all_return_values, + all_errors, + message: invResult.message, + status: invResult.status + }; + return result; + } + tryToAwaitForMethods(methodDefinition, target, additionalOptions) { + return new Promise((resolve, reject) => { + if (additionalOptions.waitTimeoutMs === 0) { + reject(); + return; + } + const delayStep = 500; + let delayTillNow = 0; + const retry = () => { + delayTillNow += delayStep; + const serversMethodMap = this.getServerMethodsByFilterAndTarget(methodDefinition, target); + if (serversMethodMap.length > 0) { + clearInterval(interval); + resolve(serversMethodMap); + } + else if (delayTillNow >= (additionalOptions.waitTimeoutMs || 10000)) { + clearInterval(interval); + reject(); + return; + } + }; + const interval = setInterval(retry, delayStep); + }); + } + filterByTarget(target, serverMethodMap) { + if (typeof target === "string") { + if (target === "all") { + return [...serverMethodMap]; + } + else if (target === "best") { + const localMachine = serverMethodMap + .find((s) => s.server.instance.isLocal); + if (localMachine) { + return [localMachine]; + } + if (serverMethodMap[0] !== undefined) { + return [serverMethodMap[0]]; + } + } + else if (target === "skipMine") { + return serverMethodMap.filter(({ server }) => server.instance.peerId !== this.instance.peerId); + } + } + else { + let targetArray; + if (!Array.isArray(target)) { + targetArray = [target]; + } + else { + targetArray = target; + } + const allServersMatching = targetArray.reduce((matches, filter) => { + const myMatches = serverMethodMap.filter((serverMethodPair) => { + return this.instanceMatch(filter, serverMethodPair.server.instance); + }); + return matches.concat(myMatches); + }, []); + return allServersMatching; + } + return []; + } + instanceMatch(instanceFilter, instanceDefinition) { + if (instanceFilter?.peerId && instanceFilter?.instance) { + instanceFilter = { ...instanceFilter }; + delete instanceFilter.peerId; + } + return this.containsProps(instanceFilter, instanceDefinition); + } + methodMatch(methodFilter, methodDefinition) { + return this.containsProps(methodFilter, methodDefinition); + } + containsProps(filter, repoMethod) { + const filterProps = Object.keys(filter) + .filter((prop) => { + return filter[prop] !== undefined + && filter[prop] !== null + && typeof filter[prop] !== "function" + && prop !== "object_types" + && prop !== "display_name" + && prop !== "id" + && prop !== "gatewayId" + && prop !== "identifier" + && prop[0] !== "_"; + }); + return filterProps.every((prop) => { + let isMatch; + const filterValue = filter[prop]; + const repoMethodValue = repoMethod[prop]; + switch (prop) { + case "objectTypes": + isMatch = (filterValue || []).every((filterValueEl) => { + return (repoMethodValue || []).includes(filterValueEl); + }); + break; + case "flags": + isMatch = isSubset(repoMethodValue || {}, filterValue || {}); + break; + default: + isMatch = String(filterValue).toLowerCase() === String(repoMethodValue).toLowerCase(); + } + return isMatch; + }); + } + getMethods(methodFilter) { + if (methodFilter === undefined) { + return this.repo.getMethods(); + } + const methods = this.repo.getMethods().filter((method) => { + return this.methodMatch(methodFilter, method); + }); + return methods; + } + getMethodsForInstance(instanceFilter) { + const allServers = this.repo.getServers(); + const matchingServers = allServers.filter((server) => { + return this.instanceMatch(instanceFilter, server.instance); + }); + if (matchingServers.length === 0) { + return []; + } + let resultMethodsObject = {}; + if (matchingServers.length === 1) { + resultMethodsObject = matchingServers[0].methods; + } + else { + matchingServers.forEach((server) => { + Object.keys(server.methods).forEach((methodKey) => { + const method = server.methods[methodKey]; + resultMethodsObject[method.identifier] = method; + }); + }); + } + return Object.keys(resultMethodsObject) + .map((key) => { + return resultMethodsObject[key]; + }); + } + getServers(methodFilter) { + const servers = this.repo.getServers(); + if (methodFilter === undefined) { + return servers.map((server) => { + return { server, methods: [] }; + }); + } + return servers.reduce((prev, current) => { + const methodsForServer = Object.values(current.methods); + const matchingMethods = methodsForServer.filter((method) => { + return this.methodMatch(methodFilter, method); + }); + if (matchingMethods.length > 0) { + prev.push({ server: current, methods: matchingMethods }); + } + return prev; + }, []); + } + getServerMethodsByFilterAndTarget(methodFilter, target) { + const serversMethodMap = this.getServers(methodFilter); + return this.filterByTarget(target, serversMethodMap); + } + } + + class ServerSubscription { + protocol; + repoMethod; + subscription; + constructor(protocol, repoMethod, subscription) { + this.protocol = protocol; + this.repoMethod = repoMethod; + this.subscription = subscription; + } + get stream() { + if (!this.repoMethod.stream) { + throw new Error("no stream"); + } + return this.repoMethod.stream; + } + get arguments() { return this.subscription.arguments || {}; } + get branchKey() { return this.subscription.branchKey; } + get instance() { + if (!this.subscription.instance) { + throw new Error("no instance"); + } + return this.subscription.instance; + } + close() { + this.protocol.server.closeSingleSubscription(this.repoMethod, this.subscription); + } + push(data) { + this.protocol.server.pushDataToSingle(this.repoMethod, this.subscription, data); + } + } + + class Request { + protocol; + repoMethod; + requestContext; + arguments; + instance; + constructor(protocol, repoMethod, requestContext) { + this.protocol = protocol; + this.repoMethod = repoMethod; + this.requestContext = requestContext; + this.arguments = requestContext.arguments; + this.instance = requestContext.instance; + } + accept() { + this.protocol.server.acceptRequestOnBranch(this.requestContext, this.repoMethod, ""); + } + acceptOnBranch(branch) { + this.protocol.server.acceptRequestOnBranch(this.requestContext, this.repoMethod, branch); + } + reject(reason) { + this.protocol.server.rejectRequest(this.requestContext, this.repoMethod, reason); + } + } + + let ServerStreaming$1 = class ServerStreaming { + protocol; + server; + constructor(protocol, server) { + this.protocol = protocol; + this.server = server; + protocol.server.onSubRequest((rc, rm) => this.handleSubRequest(rc, rm)); + protocol.server.onSubAdded((sub, rm) => this.handleSubAdded(sub, rm)); + protocol.server.onSubRemoved((sub, rm) => this.handleSubRemoved(sub, rm)); + } + handleSubRequest(requestContext, repoMethod) { + if (!(repoMethod && + repoMethod.streamCallbacks && + typeof repoMethod.streamCallbacks.subscriptionRequestHandler === "function")) { + return; + } + const request = new Request(this.protocol, repoMethod, requestContext); + repoMethod.streamCallbacks.subscriptionRequestHandler(request); + } + handleSubAdded(subscription, repoMethod) { + if (!(repoMethod && + repoMethod.streamCallbacks && + typeof repoMethod.streamCallbacks.subscriptionAddedHandler === "function")) { + return; + } + const sub = new ServerSubscription(this.protocol, repoMethod, subscription); + repoMethod.streamCallbacks.subscriptionAddedHandler(sub); + } + handleSubRemoved(subscription, repoMethod) { + if (!(repoMethod && + repoMethod.streamCallbacks && + typeof repoMethod.streamCallbacks.subscriptionRemovedHandler === "function")) { + return; + } + const sub = new ServerSubscription(this.protocol, repoMethod, subscription); + repoMethod.streamCallbacks.subscriptionRemovedHandler(sub); + } + }; + + class ServerBranch { + key; + protocol; + repoMethod; + constructor(key, protocol, repoMethod) { + this.key = key; + this.protocol = protocol; + this.repoMethod = repoMethod; + } + subscriptions() { + const subList = this.protocol.server.getSubscriptionList(this.repoMethod, this.key); + return subList.map((sub) => { + return new ServerSubscription(this.protocol, this.repoMethod, sub); + }); + } + close() { + this.protocol.server.closeAllSubscriptions(this.repoMethod, this.key); + } + push(data) { + this.protocol.server.pushData(this.repoMethod, data, [this.key]); + } + } + + class ServerStream { + _protocol; + _repoMethod; + _server; + name; + constructor(_protocol, _repoMethod, _server) { + this._protocol = _protocol; + this._repoMethod = _repoMethod; + this._server = _server; + this.name = this._repoMethod.definition.name; + } + branches(key) { + const bList = this._protocol.server.getBranchList(this._repoMethod); + if (key) { + if (bList.indexOf(key) > -1) { + return new ServerBranch(key, this._protocol, this._repoMethod); + } + return undefined; + } + else { + return bList.map((branchKey) => { + return new ServerBranch(branchKey, this._protocol, this._repoMethod); + }); + } + } + branch(key) { + return this.branches(key); + } + subscriptions() { + const subList = this._protocol.server.getSubscriptionList(this._repoMethod); + return subList.map((sub) => { + return new ServerSubscription(this._protocol, this._repoMethod, sub); + }); + } + get definition() { + const def2 = this._repoMethod.definition; + return { + accepts: def2.accepts, + description: def2.description, + displayName: def2.displayName, + name: def2.name, + objectTypes: def2.objectTypes, + returns: def2.returns, + supportsStreaming: def2.supportsStreaming, + flags: def2.flags?.metadata, + }; + } + close() { + this._protocol.server.closeAllSubscriptions(this._repoMethod); + this._server.unregister(this._repoMethod.definition, true); + } + push(data, branches) { + if (typeof branches !== "string" && !Array.isArray(branches) && branches !== undefined) { + throw new Error("invalid branches should be string or string array"); + } + if (typeof data !== "object") { + throw new Error("Invalid arguments. Data must be an object."); + } + this._protocol.server.pushData(this._repoMethod, data, branches); + } + updateRepoMethod(repoMethod) { + this._repoMethod = repoMethod; + } + } + + class Server { + protocol; + serverRepository; + streaming; + invocations = 0; + currentlyUnregistering = {}; + constructor(protocol, serverRepository) { + this.protocol = protocol; + this.serverRepository = serverRepository; + this.streaming = new ServerStreaming$1(protocol, this); + this.protocol.server.onInvoked(this.onMethodInvoked.bind(this)); + } + createStream(streamDef, callbacks, successCallback, errorCallback, existingStream) { + const promise = new Promise((resolve, reject) => { + if (!streamDef) { + reject("The stream name must be unique! Please, provide either a unique string for a stream name to “glue.interop.createStream()” or a “methodDefinition” object with a unique “name” property for the stream."); + return; + } + let streamMethodDefinition; + if (typeof streamDef === "string") { + streamMethodDefinition = { name: "" + streamDef }; + } + else { + streamMethodDefinition = { ...streamDef }; + } + if (!streamMethodDefinition.name) { + return reject(`The “name” property is required for the “streamDefinition” object and must be unique. Stream definition: ${JSON.stringify(streamMethodDefinition)}`); + } + const nameAlreadyExists = this.serverRepository.getList() + .some((serverMethod) => serverMethod.definition.name === streamMethodDefinition.name); + if (nameAlreadyExists) { + return reject(`A stream with the name "${streamMethodDefinition.name}" already exists! Please, provide a unique name for the stream.`); + } + streamMethodDefinition.supportsStreaming = true; + if (!callbacks) { + callbacks = {}; + } + if (typeof callbacks.subscriptionRequestHandler !== "function") { + callbacks.subscriptionRequestHandler = (request) => { + request.accept(); + }; + } + const repoMethod = this.serverRepository.add({ + definition: streamMethodDefinition, + streamCallbacks: callbacks, + protocolState: {}, + }); + this.protocol.server.createStream(repoMethod) + .then(() => { + let streamUserObject; + if (existingStream) { + streamUserObject = existingStream; + existingStream.updateRepoMethod(repoMethod); + } + else { + streamUserObject = new ServerStream(this.protocol, repoMethod, this); + } + repoMethod.stream = streamUserObject; + resolve(streamUserObject); + }) + .catch((err) => { + if (repoMethod.repoId) { + this.serverRepository.remove(repoMethod.repoId); + } + reject(err); + }); + }); + return promisify$2(promise, successCallback, errorCallback); + } + register(methodDefinition, callback) { + if (!methodDefinition) { + return Promise.reject("Method definition is required. Please, provide either a unique string for a method name or a “methodDefinition” object with a required “name” property."); + } + if (typeof callback !== "function") { + return Promise.reject(`The second parameter must be a callback function. Method: ${typeof methodDefinition === "string" ? methodDefinition : methodDefinition.name}`); + } + const wrappedCallbackFunction = async (context, resultCallback) => { + try { + const result = callback(context.args, context.instance); + if (result && typeof result.then === "function") { + const resultValue = await result; + resultCallback(undefined, resultValue); + } + else { + resultCallback(undefined, result); + } + } + catch (e) { + resultCallback(e ?? "", e ?? ""); + } + }; + wrappedCallbackFunction.userCallback = callback; + return this.registerCore(methodDefinition, wrappedCallbackFunction); + } + registerAsync(methodDefinition, callback) { + if (!methodDefinition) { + return Promise.reject("Method definition is required. Please, provide either a unique string for a method name or a “methodDefinition” object with a required “name” property."); + } + if (typeof callback !== "function") { + return Promise.reject(`The second parameter must be a callback function. Method: ${typeof methodDefinition === "string" ? methodDefinition : methodDefinition.name}`); + } + const wrappedCallback = async (context, resultCallback) => { + try { + let resultCalled = false; + const success = (result) => { + if (!resultCalled) { + resultCallback(undefined, result); + } + resultCalled = true; + }; + const error = (e) => { + if (!resultCalled) { + if (!e) { + e = ""; + } + resultCallback(e, e); + } + resultCalled = true; + }; + const methodResult = callback(context.args, context.instance, success, error); + if (methodResult && typeof methodResult.then === "function") { + methodResult + .then(success) + .catch(error); + } + } + catch (e) { + resultCallback(e, undefined); + } + }; + wrappedCallback.userCallbackAsync = callback; + return this.registerCore(methodDefinition, wrappedCallback); + } + async unregister(methodFilter, forStream = false) { + if (methodFilter === undefined) { + return Promise.reject("Please, provide either a unique string for a name or an object containing a “name” property."); + } + if (typeof methodFilter === "function") { + await this.unregisterWithPredicate(methodFilter, forStream); + return; + } + let methodDefinition; + if (typeof methodFilter === "string") { + methodDefinition = { name: methodFilter }; + } + else { + methodDefinition = methodFilter; + } + if (methodDefinition.name === undefined) { + return Promise.reject("Method name is required. Cannot find a method if the method name is undefined!"); + } + const methodToBeRemoved = this.serverRepository.getList().find((serverMethod) => { + return serverMethod.definition.name === methodDefinition.name + && (serverMethod.definition.supportsStreaming || false) === forStream; + }); + if (!methodToBeRemoved) { + return Promise.reject(`Method with a name "${methodDefinition.name}" does not exist or is not registered by your application!`); + } + await this.removeMethodsOrStreams([methodToBeRemoved]); + } + async unregisterWithPredicate(filterPredicate, forStream) { + const methodsOrStreamsToRemove = this.serverRepository.getList() + .filter((sm) => filterPredicate(sm.definition)) + .filter((serverMethod) => (serverMethod.definition.supportsStreaming || false) === forStream); + if (!methodsOrStreamsToRemove || methodsOrStreamsToRemove.length === 0) { + return Promise.reject(`Could not find a ${forStream ? "stream" : "method"} matching the specified condition!`); + } + await this.removeMethodsOrStreams(methodsOrStreamsToRemove); + } + removeMethodsOrStreams(methodsToRemove) { + const methodUnregPromises = []; + methodsToRemove.forEach((method) => { + const promise = this.protocol.server.unregister(method) + .then(() => { + if (method.repoId) { + this.serverRepository.remove(method.repoId); + } + }); + methodUnregPromises.push(promise); + this.addAsCurrentlyUnregistering(method.definition.name, promise); + }); + return Promise.all(methodUnregPromises); + } + async addAsCurrentlyUnregistering(methodName, promise) { + const timeout = new Promise((resolve) => setTimeout(resolve, 5000)); + this.currentlyUnregistering[methodName] = Promise.race([promise, timeout]).then(() => { + delete this.currentlyUnregistering[methodName]; + }); + } + async registerCore(method, theFunction) { + let methodDefinition; + if (typeof method === "string") { + methodDefinition = { name: "" + method }; + } + else { + methodDefinition = { ...method }; + } + if (!methodDefinition.name) { + return Promise.reject(`Please, provide a (unique) string value for the “name” property in the “methodDefinition” object: ${JSON.stringify(method)}`); + } + const unregisterInProgress = this.currentlyUnregistering[methodDefinition.name]; + if (typeof unregisterInProgress !== "undefined") { + await unregisterInProgress; + } + const nameAlreadyExists = this.serverRepository.getList() + .some((serverMethod) => serverMethod.definition.name === methodDefinition.name); + if (nameAlreadyExists) { + return Promise.reject(`A method with the name "${methodDefinition.name}" already exists! Please, provide a unique name for the method.`); + } + if (methodDefinition.supportsStreaming) { + return Promise.reject(`When you create methods with “glue.interop.register()” or “glue.interop.registerAsync()” the property “supportsStreaming” cannot be “true”. If you want “${methodDefinition.name}” to be a stream, please use the “glue.interop.createStream()” method.`); + } + const repoMethod = this.serverRepository.add({ + definition: methodDefinition, + theFunction, + protocolState: {}, + }); + return this.protocol.server.register(repoMethod) + .catch((err) => { + if (repoMethod?.repoId) { + this.serverRepository.remove(repoMethod.repoId); + } + throw err; + }); + } + onMethodInvoked(methodToExecute, invocationId, invocationArgs) { + if (!methodToExecute || !methodToExecute.theFunction) { + return; + } + methodToExecute.theFunction(invocationArgs, (err, result) => { + if (err !== undefined && err !== null) { + if (err.message && typeof err.message === "string") { + err = err.message; + } + else if (typeof err !== "string") { + try { + err = JSON.stringify(err); + } + catch (unStrException) { + err = `un-stringifyable error in onMethodInvoked! Top level prop names: ${Object.keys(err)}`; + } + } + } + if (!result) { + result = {}; + } + else if (typeof result !== "object" || Array.isArray(result)) { + result = { _value: result }; + } + this.protocol.server.methodInvocationResult(methodToExecute, invocationId, err, result); + }); + } + } + + class InstanceWrapper { + wrapped = {}; + constructor(API, instance, connection) { + this.wrapped.getMethods = function () { + return API.methodsForInstance(this); + }; + this.wrapped.getStreams = function () { + return API.methodsForInstance(this).filter((m) => m.supportsStreaming); + }; + if (instance) { + this.refreshWrappedObject(instance); + } + if (connection) { + connection.loggedIn(() => { + this.refresh(connection); + }); + this.refresh(connection); + } + } + unwrap() { + return this.wrapped; + } + refresh(connection) { + if (!connection) { + return; + } + const resolvedIdentity = connection?.resolvedIdentity; + const instance = Object.assign({}, resolvedIdentity ?? {}, { peerId: connection?.peerId }); + this.refreshWrappedObject(instance); + } + refreshWrappedObject(resolvedIdentity) { + Object.keys(resolvedIdentity).forEach((key) => { + this.wrapped[key] = resolvedIdentity[key]; + }); + this.wrapped.user = resolvedIdentity.user; + this.wrapped.instance = resolvedIdentity.instance; + this.wrapped.application = resolvedIdentity.application ?? nanoid$1(10); + this.wrapped.applicationName = resolvedIdentity.applicationName; + this.wrapped.pid = resolvedIdentity.pid ?? resolvedIdentity.process ?? Math.floor(Math.random() * 10000000000); + this.wrapped.machine = resolvedIdentity.machine; + this.wrapped.environment = resolvedIdentity.environment; + this.wrapped.region = resolvedIdentity.region; + this.wrapped.windowId = resolvedIdentity.windowId; + this.wrapped.isLocal = resolvedIdentity.isLocal ?? true; + this.wrapped.api = resolvedIdentity.api; + this.wrapped.service = resolvedIdentity.service; + this.wrapped.peerId = resolvedIdentity.peerId; + } + } + + const hideMethodSystemFlags = (method) => { + return { + ...method, + flags: method.flags.metadata || {} + }; + }; + class ClientRepository { + logger; + API; + servers = {}; + myServer; + methodsCount = {}; + callbacks = CallbackRegistryFactory$1(); + constructor(logger, API) { + this.logger = logger; + this.API = API; + const peerId = this.API.instance.peerId; + this.myServer = { + id: peerId, + methods: {}, + instance: this.API.instance, + wrapper: this.API.unwrappedInstance, + }; + this.servers[peerId] = this.myServer; + } + addServer(info, serverId) { + this.logger.debug(`adding server ${serverId}`); + const current = this.servers[serverId]; + if (current) { + return current.id; + } + const wrapper = new InstanceWrapper(this.API, info); + const serverEntry = { + id: serverId, + methods: {}, + instance: wrapper.unwrap(), + wrapper, + }; + this.servers[serverId] = serverEntry; + this.callbacks.execute("onServerAdded", serverEntry.instance); + return serverId; + } + removeServerById(id, reason) { + const server = this.servers[id]; + if (!server) { + this.logger.warn(`not aware of server ${id}, my state ${JSON.stringify(Object.keys(this.servers))}`); + return; + } + else { + this.logger.debug(`removing server ${id}`); + } + Object.keys(server.methods).forEach((methodId) => { + this.removeServerMethod(id, methodId); + }); + delete this.servers[id]; + this.callbacks.execute("onServerRemoved", server.instance, reason); + } + addServerMethod(serverId, method) { + const server = this.servers[serverId]; + if (!server) { + throw new Error("server does not exists"); + } + if (server.methods[method.id]) { + return; + } + const identifier = this.createMethodIdentifier(method); + const that = this; + const methodDefinition = { + identifier, + gatewayId: method.id, + name: method.name, + displayName: method.display_name, + description: method.description, + version: method.version, + objectTypes: method.object_types || [], + accepts: method.input_signature, + returns: method.result_signature, + supportsStreaming: typeof method.flags !== "undefined" ? method.flags.streaming : false, + flags: method.flags ?? {}, + getServers: () => { + return that.getServersByMethod(identifier); + } + }; + methodDefinition.object_types = methodDefinition.objectTypes; + methodDefinition.display_name = methodDefinition.displayName; + methodDefinition.version = methodDefinition.version; + server.methods[method.id] = methodDefinition; + const clientMethodDefinition = hideMethodSystemFlags(methodDefinition); + if (!this.methodsCount[identifier]) { + this.methodsCount[identifier] = 0; + this.callbacks.execute("onMethodAdded", clientMethodDefinition); + } + this.methodsCount[identifier] = this.methodsCount[identifier] + 1; + this.callbacks.execute("onServerMethodAdded", server.instance, clientMethodDefinition); + return methodDefinition; + } + removeServerMethod(serverId, methodId) { + const server = this.servers[serverId]; + if (!server) { + throw new Error("server does not exists"); + } + const method = server.methods[methodId]; + delete server.methods[methodId]; + const clientMethodDefinition = hideMethodSystemFlags(method); + this.methodsCount[method.identifier] = this.methodsCount[method.identifier] - 1; + if (this.methodsCount[method.identifier] === 0) { + this.callbacks.execute("onMethodRemoved", clientMethodDefinition); + } + this.callbacks.execute("onServerMethodRemoved", server.instance, clientMethodDefinition); + } + getMethods() { + return this.extractMethodsFromServers(Object.values(this.servers)).map(hideMethodSystemFlags); + } + getServers() { + return Object.values(this.servers).map(this.hideServerMethodSystemFlags); + } + onServerAdded(callback) { + const unsubscribeFunc = this.callbacks.add("onServerAdded", callback); + const serversWithMethodsToReplay = this.getServers().map((s) => s.instance); + return this.returnUnsubWithDelayedReplay(unsubscribeFunc, serversWithMethodsToReplay, callback); + } + onMethodAdded(callback) { + const unsubscribeFunc = this.callbacks.add("onMethodAdded", callback); + const methodsToReplay = this.getMethods(); + return this.returnUnsubWithDelayedReplay(unsubscribeFunc, methodsToReplay, callback); + } + onServerMethodAdded(callback) { + const unsubscribeFunc = this.callbacks.add("onServerMethodAdded", callback); + let unsubCalled = false; + const servers = this.getServers(); + setTimeout(() => { + servers.forEach((server) => { + const methods = server.methods; + Object.keys(methods).forEach((methodId) => { + if (!unsubCalled) { + callback(server.instance, methods[methodId]); + } + }); + }); + }, 0); + return () => { + unsubCalled = true; + unsubscribeFunc(); + }; + } + onMethodRemoved(callback) { + const unsubscribeFunc = this.callbacks.add("onMethodRemoved", callback); + return unsubscribeFunc; + } + onServerRemoved(callback) { + const unsubscribeFunc = this.callbacks.add("onServerRemoved", callback); + return unsubscribeFunc; + } + onServerMethodRemoved(callback) { + const unsubscribeFunc = this.callbacks.add("onServerMethodRemoved", callback); + return unsubscribeFunc; + } + getServerById(id) { + const server = this.servers[id]; + if (!server) { + return undefined; + } + return this.hideServerMethodSystemFlags(this.servers[id]); + } + reset() { + Object.keys(this.servers).forEach((key) => { + this.removeServerById(key, "reset"); + }); + this.servers = { + [this.myServer.id]: this.myServer + }; + this.methodsCount = {}; + } + createMethodIdentifier(methodInfo) { + const accepts = methodInfo.input_signature ?? ""; + const returns = methodInfo.result_signature ?? ""; + return (methodInfo.name + accepts + returns).toLowerCase(); + } + getServersByMethod(identifier) { + const allServers = []; + Object.values(this.servers).forEach((server) => { + Object.values(server.methods).forEach((method) => { + if (method.identifier === identifier) { + allServers.push(server.instance); + } + }); + }); + return allServers; + } + returnUnsubWithDelayedReplay(unsubscribeFunc, collectionToReplay, callback) { + let unsubCalled = false; + setTimeout(() => { + collectionToReplay.forEach((item) => { + if (!unsubCalled) { + callback(item); + } + }); + }, 0); + return () => { + unsubCalled = true; + unsubscribeFunc(); + }; + } + hideServerMethodSystemFlags(server) { + const clientMethods = {}; + Object.entries(server.methods).forEach(([name, method]) => { + clientMethods[name] = hideMethodSystemFlags(method); + }); + return { + ...server, + methods: clientMethods + }; + } + extractMethodsFromServers(servers) { + const methods = Object.values(servers).reduce((clientMethods, server) => { + return [...clientMethods, ...Object.values(server.methods)]; + }, []); + return methods; + } + } + + class ServerRepository { + nextId = 0; + methods = []; + add(method) { + method.repoId = String(this.nextId); + this.nextId += 1; + this.methods.push(method); + return method; + } + remove(repoId) { + if (typeof repoId !== "string") { + return new TypeError("Expecting a string"); + } + this.methods = this.methods.filter((m) => { + return m.repoId !== repoId; + }); + } + getById(id) { + if (typeof id !== "string") { + return undefined; + } + return this.methods.find((m) => { + return m.repoId === id; + }); + } + getList() { + return this.methods.map((m) => m); + } + length() { + return this.methods.length; + } + reset() { + this.methods = []; + } + } + + const SUBSCRIPTION_REQUEST = "onSubscriptionRequest"; + const SUBSCRIPTION_ADDED = "onSubscriptionAdded"; + const SUBSCRIPTION_REMOVED = "onSubscriptionRemoved"; + class ServerStreaming { + session; + repository; + serverRepository; + ERR_URI_SUBSCRIPTION_FAILED = "com.tick42.agm.errors.subscription.failure"; + callbacks = CallbackRegistryFactory$1(); + nextStreamId = 0; + constructor(session, repository, serverRepository) { + this.session = session; + this.repository = repository; + this.serverRepository = serverRepository; + session.on("add-interest", (msg) => { + this.handleAddInterest(msg); + }); + session.on("remove-interest", (msg) => { + this.handleRemoveInterest(msg); + }); + } + acceptRequestOnBranch(requestContext, streamingMethod, branch) { + if (typeof branch !== "string") { + branch = ""; + } + if (typeof streamingMethod.protocolState.subscriptionsMap !== "object") { + throw new TypeError("The streaming method is missing its subscriptions."); + } + if (!Array.isArray(streamingMethod.protocolState.branchKeyToStreamIdMap)) { + throw new TypeError("The streaming method is missing its branches."); + } + const streamId = this.getStreamId(streamingMethod, branch); + const key = requestContext.msg.subscription_id; + const subscription = { + id: key, + arguments: requestContext.arguments, + instance: requestContext.instance, + branchKey: branch, + streamId, + subscribeMsg: requestContext.msg, + }; + streamingMethod.protocolState.subscriptionsMap[key] = subscription; + this.session.sendFireAndForget({ + type: "accepted", + subscription_id: key, + stream_id: streamId, + }); + this.callbacks.execute(SUBSCRIPTION_ADDED, subscription, streamingMethod); + } + rejectRequest(requestContext, streamingMethod, reason) { + if (typeof reason !== "string") { + reason = ""; + } + this.sendSubscriptionFailed("Subscription rejected by user. " + reason, requestContext.msg.subscription_id); + } + pushData(streamingMethod, data, branches) { + if (typeof streamingMethod !== "object" || !Array.isArray(streamingMethod.protocolState.branchKeyToStreamIdMap)) { + return; + } + if (typeof data !== "object") { + throw new Error("Invalid arguments. Data must be an object."); + } + if (typeof branches === "string") { + branches = [branches]; + } + else if (!Array.isArray(branches) || branches.length <= 0) { + branches = []; + } + const streamIdList = streamingMethod.protocolState.branchKeyToStreamIdMap + .filter((br) => { + if (!branches || branches.length === 0) { + return true; + } + return branches.indexOf(br.key) >= 0; + }).map((br) => { + return br.streamId; + }); + streamIdList.forEach((streamId) => { + const publishMessage = { + type: "publish", + stream_id: streamId, + data, + }; + this.session.sendFireAndForget(publishMessage); + }); + } + pushDataToSingle(method, subscription, data) { + if (typeof data !== "object") { + throw new Error("Invalid arguments. Data must be an object."); + } + const postMessage = { + type: "post", + subscription_id: subscription.id, + data, + }; + this.session.sendFireAndForget(postMessage); + } + closeSingleSubscription(streamingMethod, subscription) { + if (streamingMethod.protocolState.subscriptionsMap) { + delete streamingMethod.protocolState.subscriptionsMap[subscription.id]; + } + const dropSubscriptionMessage = { + type: "drop-subscription", + subscription_id: subscription.id, + reason: "Server dropping a single subscription", + }; + this.session.sendFireAndForget(dropSubscriptionMessage); + subscription.instance; + this.callbacks.execute(SUBSCRIPTION_REMOVED, subscription, streamingMethod); + } + closeMultipleSubscriptions(streamingMethod, branchKey) { + if (typeof streamingMethod !== "object" || typeof streamingMethod.protocolState.subscriptionsMap !== "object") { + return; + } + if (!streamingMethod.protocolState.subscriptionsMap) { + return; + } + const subscriptionsMap = streamingMethod.protocolState.subscriptionsMap; + let subscriptionsToClose = Object.keys(subscriptionsMap) + .map((key) => { + return subscriptionsMap[key]; + }); + if (typeof branchKey === "string") { + subscriptionsToClose = subscriptionsToClose.filter((sub) => { + return sub.branchKey === branchKey; + }); + } + subscriptionsToClose.forEach((subscription) => { + delete subscriptionsMap[subscription.id]; + const drop = { + type: "drop-subscription", + subscription_id: subscription.id, + reason: "Server dropping all subscriptions on stream_id: " + subscription.streamId, + }; + this.session.sendFireAndForget(drop); + }); + } + getSubscriptionList(streamingMethod, branchKey) { + if (typeof streamingMethod !== "object") { + return []; + } + let subscriptions = []; + if (!streamingMethod.protocolState.subscriptionsMap) { + return []; + } + const subscriptionsMap = streamingMethod.protocolState.subscriptionsMap; + const allSubscriptions = Object.keys(subscriptionsMap) + .map((key) => { + return subscriptionsMap[key]; + }); + if (typeof branchKey !== "string") { + subscriptions = allSubscriptions; + } + else { + subscriptions = allSubscriptions.filter((sub) => { + return sub.branchKey === branchKey; + }); + } + return subscriptions; + } + getBranchList(streamingMethod) { + if (typeof streamingMethod !== "object") { + return []; + } + if (!streamingMethod.protocolState.subscriptionsMap) { + return []; + } + const subscriptionsMap = streamingMethod.protocolState.subscriptionsMap; + const allSubscriptions = Object.keys(subscriptionsMap) + .map((key) => { + return subscriptionsMap[key]; + }); + const result = []; + allSubscriptions.forEach((sub) => { + let branch = ""; + if (typeof sub === "object" && typeof sub.branchKey === "string") { + branch = sub.branchKey; + } + if (result.indexOf(branch) === -1) { + result.push(branch); + } + }); + return result; + } + onSubAdded(callback) { + this.onSubscriptionLifetimeEvent(SUBSCRIPTION_ADDED, callback); + } + onSubRequest(callback) { + this.onSubscriptionLifetimeEvent(SUBSCRIPTION_REQUEST, callback); + } + onSubRemoved(callback) { + this.onSubscriptionLifetimeEvent(SUBSCRIPTION_REMOVED, callback); + } + handleRemoveInterest(msg) { + const streamingMethod = this.serverRepository.getById(msg.method_id); + if (typeof msg.subscription_id !== "string" || + typeof streamingMethod !== "object") { + return; + } + if (!streamingMethod.protocolState.subscriptionsMap) { + return; + } + if (typeof streamingMethod.protocolState.subscriptionsMap[msg.subscription_id] !== "object") { + return; + } + const subscription = streamingMethod.protocolState.subscriptionsMap[msg.subscription_id]; + delete streamingMethod.protocolState.subscriptionsMap[msg.subscription_id]; + this.callbacks.execute(SUBSCRIPTION_REMOVED, subscription, streamingMethod); + } + onSubscriptionLifetimeEvent(eventName, handlerFunc) { + this.callbacks.add(eventName, handlerFunc); + } + getNextStreamId() { + return this.nextStreamId++ + ""; + } + handleAddInterest(msg) { + const caller = this.repository.getServerById(msg.caller_id); + const instance = caller?.instance ?? {}; + const requestContext = { + msg, + arguments: msg.arguments_kv || {}, + instance, + }; + const streamingMethod = this.serverRepository.getById(msg.method_id); + if (streamingMethod === undefined) { + const errorMsg = "No method with id " + msg.method_id + " on this server."; + this.sendSubscriptionFailed(errorMsg, msg.subscription_id); + return; + } + if (streamingMethod.protocolState.subscriptionsMap && + streamingMethod.protocolState.subscriptionsMap[msg.subscription_id]) { + this.sendSubscriptionFailed("A subscription with id " + msg.subscription_id + " already exists.", msg.subscription_id); + return; + } + this.callbacks.execute(SUBSCRIPTION_REQUEST, requestContext, streamingMethod); + } + sendSubscriptionFailed(reason, subscriptionId) { + const errorMessage = { + type: "error", + reason_uri: this.ERR_URI_SUBSCRIPTION_FAILED, + reason, + request_id: subscriptionId, + }; + this.session.sendFireAndForget(errorMessage); + } + getStreamId(streamingMethod, branchKey) { + if (typeof branchKey !== "string") { + branchKey = ""; + } + if (!streamingMethod.protocolState.branchKeyToStreamIdMap) { + throw new Error(`streaming ${streamingMethod.definition.name} method without protocol state`); + } + const needleBranch = streamingMethod.protocolState.branchKeyToStreamIdMap.filter((branch) => { + return branch.key === branchKey; + })[0]; + let streamId = (needleBranch ? needleBranch.streamId : undefined); + if (typeof streamId !== "string" || streamId === "") { + streamId = this.getNextStreamId(); + streamingMethod.protocolState.branchKeyToStreamIdMap.push({ key: branchKey, streamId }); + } + return streamId; + } + } + + class ServerProtocol { + session; + clientRepository; + serverRepository; + logger; + callbacks = CallbackRegistryFactory$1(); + streaming; + constructor(session, clientRepository, serverRepository, logger) { + this.session = session; + this.clientRepository = clientRepository; + this.serverRepository = serverRepository; + this.logger = logger; + this.streaming = new ServerStreaming(session, clientRepository, serverRepository); + this.session.on("invoke", (msg) => this.handleInvokeMessage(msg)); + } + createStream(repoMethod) { + repoMethod.protocolState.subscriptionsMap = {}; + repoMethod.protocolState.branchKeyToStreamIdMap = []; + return this.register(repoMethod, true); + } + register(repoMethod, isStreaming) { + const methodDef = repoMethod.definition; + const flags = Object.assign({}, { metadata: methodDef.flags ?? {} }, { streaming: isStreaming || false }); + const registerMsg = { + type: "register", + methods: [{ + id: repoMethod.repoId, + name: methodDef.name, + display_name: methodDef.displayName, + description: methodDef.description, + version: methodDef.version, + flags, + object_types: methodDef.objectTypes || methodDef.object_types, + input_signature: methodDef.accepts, + result_signature: methodDef.returns, + restrictions: undefined, + }], + }; + return this.session.send(registerMsg, { methodId: repoMethod.repoId }) + .then(() => { + this.logger.debug("registered method " + repoMethod.definition.name + " with id " + repoMethod.repoId); + }) + .catch((msg) => { + this.logger.warn(`failed to register method ${repoMethod.definition.name} with id ${repoMethod.repoId} - ${JSON.stringify(msg)}`); + throw msg; + }); + } + onInvoked(callback) { + this.callbacks.add("onInvoked", callback); + } + methodInvocationResult(method, invocationId, err, result) { + let msg; + if (err || err === "") { + msg = { + type: "error", + request_id: invocationId, + reason_uri: "agm.errors.client_error", + reason: err, + context: result, + peer_id: undefined, + }; + } + else { + msg = { + type: "yield", + invocation_id: invocationId, + peer_id: this.session.peerId, + result, + request_id: undefined, + }; + } + this.session.sendFireAndForget(msg); + } + async unregister(method) { + const msg = { + type: "unregister", + methods: [method.repoId], + }; + await this.session.send(msg); + } + getBranchList(method) { + return this.streaming.getBranchList(method); + } + getSubscriptionList(method, branchKey) { + return this.streaming.getSubscriptionList(method, branchKey); + } + closeAllSubscriptions(method, branchKey) { + this.streaming.closeMultipleSubscriptions(method, branchKey); + } + pushData(method, data, branches) { + this.streaming.pushData(method, data, branches); + } + pushDataToSingle(method, subscription, data) { + this.streaming.pushDataToSingle(method, subscription, data); + } + closeSingleSubscription(method, subscription) { + this.streaming.closeSingleSubscription(method, subscription); + } + acceptRequestOnBranch(requestContext, method, branch) { + this.streaming.acceptRequestOnBranch(requestContext, method, branch); + } + rejectRequest(requestContext, method, reason) { + this.streaming.rejectRequest(requestContext, method, reason); + } + onSubRequest(callback) { + this.streaming.onSubRequest(callback); + } + onSubAdded(callback) { + this.streaming.onSubAdded(callback); + } + onSubRemoved(callback) { + this.streaming.onSubRemoved(callback); + } + handleInvokeMessage(msg) { + const invocationId = msg.invocation_id; + const callerId = msg.caller_id; + const methodId = msg.method_id; + const args = msg.arguments_kv; + const methodList = this.serverRepository.getList(); + const method = methodList.filter((m) => { + return m.repoId === methodId; + })[0]; + if (method === undefined) { + return; + } + const client = this.clientRepository.getServerById(callerId)?.instance; + const invocationArgs = { args, instance: client }; + this.callbacks.execute("onInvoked", method, invocationId, invocationArgs); + } + } + + class UserSubscription { + repository; + subscriptionData; + get requestArguments() { + return this.subscriptionData.params.arguments || {}; + } + get servers() { + return this.subscriptionData.trackedServers.reduce((servers, pair) => { + if (pair.subscriptionId) { + const server = this.repository.getServerById(pair.serverId)?.instance; + if (server) { + servers.push(server); + } + } + return servers; + }, []); + } + get serverInstance() { + return this.servers[0]; + } + get stream() { + return this.subscriptionData.method; + } + constructor(repository, subscriptionData) { + this.repository = repository; + this.subscriptionData = subscriptionData; + } + onData(dataCallback) { + if (typeof dataCallback !== "function") { + throw new TypeError("The data callback must be a function."); + } + this.subscriptionData.handlers.onData.push(dataCallback); + if (this.subscriptionData.handlers.onData.length === 1 && this.subscriptionData.queued.data.length > 0) { + this.subscriptionData.queued.data.forEach((dataItem) => { + dataCallback(dataItem); + }); + } + } + onClosed(closedCallback) { + if (typeof closedCallback !== "function") { + throw new TypeError("The callback must be a function."); + } + this.subscriptionData.handlers.onClosed.push(closedCallback); + } + onFailed(callback) { + } + onConnected(callback) { + if (typeof callback !== "function") { + throw new TypeError("The callback must be a function."); + } + this.subscriptionData.handlers.onConnected.push(callback); + } + close() { + this.subscriptionData.close(); + } + setNewSubscription(newSub) { + this.subscriptionData = newSub; + } + } + + class TimedCache { + config; + cache = []; + timeoutIds = []; + constructor(config) { + this.config = config; + } + add(element) { + const id = nanoid$1(10); + this.cache.push({ id, element }); + const timeoutId = setTimeout(() => { + const elementIdx = this.cache.findIndex((entry) => entry.id === id); + if (elementIdx < 0) { + return; + } + this.cache.splice(elementIdx, 1); + }, this.config.ELEMENT_TTL_MS); + this.timeoutIds.push(timeoutId); + } + flush() { + const elements = this.cache.map((entry) => entry.element); + this.timeoutIds.forEach((id) => clearInterval(id)); + this.cache = []; + this.timeoutIds = []; + return elements; + } + } + + const STATUS_AWAITING_ACCEPT = "awaitingAccept"; + const STATUS_SUBSCRIBED = "subscribed"; + const ERR_MSG_SUB_FAILED = "Subscription failed."; + const ERR_MSG_SUB_REJECTED = "Subscription rejected."; + const ON_CLOSE_MSG_SERVER_INIT = "ServerInitiated"; + const ON_CLOSE_MSG_CLIENT_INIT = "ClientInitiated"; + class ClientStreaming { + session; + repository; + logger; + subscriptionsList = {}; + timedCache = new TimedCache({ ELEMENT_TTL_MS: 10000 }); + subscriptionIdToLocalKeyMap = {}; + nextSubLocalKey = 0; + constructor(session, repository, logger) { + this.session = session; + this.repository = repository; + this.logger = logger; + session.on("subscribed", this.handleSubscribed); + session.on("event", this.handleEventData); + session.on("subscription-cancelled", this.handleSubscriptionCancelled); + } + subscribe(streamingMethod, params, targetServers, success, error, existingSub) { + if (targetServers.length === 0) { + error({ + method: streamingMethod, + called_with: params.arguments, + message: ERR_MSG_SUB_FAILED + " No available servers matched the target params.", + }); + return; + } + const subLocalKey = this.getNextSubscriptionLocalKey(); + const pendingSub = this.registerSubscription(subLocalKey, streamingMethod, params, success, error, params.methodResponseTimeout || 10000, existingSub); + if (typeof pendingSub !== "object") { + error({ + method: streamingMethod, + called_with: params.arguments, + message: ERR_MSG_SUB_FAILED + " Unable to register the user callbacks.", + }); + return; + } + targetServers.forEach((target) => { + const serverId = target.server.id; + const method = target.methods.find((m) => m.name === streamingMethod.name); + if (!method) { + this.logger.error(`can not find method ${streamingMethod.name} for target ${target.server.id}`); + return; + } + pendingSub.trackedServers.push({ + serverId, + subscriptionId: undefined, + }); + const msg = { + type: "subscribe", + server_id: serverId, + method_id: method.gatewayId, + arguments_kv: params.arguments, + }; + this.session.send(msg, { serverId, subLocalKey }) + .then((m) => this.handleSubscribed(m)) + .catch((err) => this.handleErrorSubscribing(err)); + }); + } + drainSubscriptions() { + const existing = Object.values(this.subscriptionsList); + this.subscriptionsList = {}; + this.subscriptionIdToLocalKeyMap = {}; + return existing; + } + drainSubscriptionsCache() { + return this.timedCache.flush(); + } + getNextSubscriptionLocalKey() { + const current = this.nextSubLocalKey; + this.nextSubLocalKey += 1; + return current; + } + registerSubscription(subLocalKey, method, params, success, error, timeout, existingSub) { + const subsInfo = { + localKey: subLocalKey, + status: STATUS_AWAITING_ACCEPT, + method, + params, + success, + error, + trackedServers: [], + handlers: { + onData: existingSub?.handlers.onData || [], + onClosed: existingSub?.handlers.onClosed || [], + onConnected: existingSub?.handlers.onConnected || [], + }, + queued: { + data: [], + closers: [], + }, + timeoutId: undefined, + close: () => this.closeSubscription(subLocalKey), + subscription: existingSub?.subscription + }; + if (!existingSub) { + if (params.onData) { + subsInfo.handlers.onData.push(params.onData); + } + if (params.onClosed) { + subsInfo.handlers.onClosed.push(params.onClosed); + } + if (params.onConnected) { + subsInfo.handlers.onConnected.push(params.onConnected); + } + } + this.subscriptionsList[subLocalKey] = subsInfo; + subsInfo.timeoutId = setTimeout(() => { + if (this.subscriptionsList[subLocalKey] === undefined) { + return; + } + const pendingSub = this.subscriptionsList[subLocalKey]; + if (pendingSub.status === STATUS_AWAITING_ACCEPT) { + error({ + method, + called_with: params.arguments, + message: ERR_MSG_SUB_FAILED + " Subscription attempt timed out after " + timeout + " ms.", + }); + delete this.subscriptionsList[subLocalKey]; + } + else if (pendingSub.status === STATUS_SUBSCRIBED && pendingSub.trackedServers.length > 0) { + pendingSub.trackedServers = pendingSub.trackedServers.filter((server) => { + return (typeof server.subscriptionId !== "undefined"); + }); + delete pendingSub.timeoutId; + if (pendingSub.trackedServers.length <= 0) { + this.callOnClosedHandlers(pendingSub); + delete this.subscriptionsList[subLocalKey]; + } + } + }, timeout); + return subsInfo; + } + handleErrorSubscribing = (errorResponse) => { + const tag = errorResponse._tag; + const subLocalKey = tag.subLocalKey; + const pendingSub = this.subscriptionsList[subLocalKey]; + if (typeof pendingSub !== "object") { + return; + } + pendingSub.trackedServers = pendingSub.trackedServers.filter((server) => { + return server.serverId !== tag.serverId; + }); + if (pendingSub.trackedServers.length <= 0) { + clearTimeout(pendingSub.timeoutId); + if (pendingSub.status === STATUS_AWAITING_ACCEPT) { + const reason = (typeof errorResponse.reason === "string" && errorResponse.reason !== "") ? + ' Publisher said "' + errorResponse.reason + '".' : + " No reason given."; + const callArgs = typeof pendingSub.params.arguments === "object" ? + JSON.stringify(pendingSub.params.arguments) : + "{}"; + pendingSub.error({ + message: ERR_MSG_SUB_REJECTED + reason + " Called with:" + callArgs, + called_with: pendingSub.params.arguments, + method: pendingSub.method, + }); + } + else if (pendingSub.status === STATUS_SUBSCRIBED) { + this.callOnClosedHandlers(pendingSub); + } + delete this.subscriptionsList[subLocalKey]; + } + }; + handleSubscribed = (msg) => { + const subLocalKey = msg._tag.subLocalKey; + const pendingSub = this.subscriptionsList[subLocalKey]; + if (typeof pendingSub !== "object") { + return; + } + const serverId = msg._tag.serverId; + const acceptingServer = pendingSub.trackedServers + .filter((server) => { + return server.serverId === serverId; + })[0]; + if (typeof acceptingServer !== "object") { + return; + } + acceptingServer.subscriptionId = msg.subscription_id; + this.subscriptionIdToLocalKeyMap[msg.subscription_id] = subLocalKey; + const isFirstResponse = (pendingSub.status === STATUS_AWAITING_ACCEPT); + pendingSub.status = STATUS_SUBSCRIBED; + if (isFirstResponse) { + let reconnect = false; + let sub = pendingSub.subscription; + if (sub) { + sub.setNewSubscription(pendingSub); + pendingSub.success(sub); + reconnect = true; + } + else { + sub = new UserSubscription(this.repository, pendingSub); + pendingSub.subscription = sub; + pendingSub.success(sub); + } + for (const handler of pendingSub.handlers.onConnected) { + try { + handler(sub.serverInstance, reconnect); + } + catch (e) { + } + } + } + }; + handleEventData = (msg) => { + const subLocalKey = this.subscriptionIdToLocalKeyMap[msg.subscription_id]; + if (typeof subLocalKey === "undefined") { + return; + } + const subscription = this.subscriptionsList[subLocalKey]; + if (typeof subscription !== "object") { + return; + } + const trackedServersFound = subscription.trackedServers.filter((s) => { + return s.subscriptionId === msg.subscription_id; + }); + if (trackedServersFound.length !== 1) { + return; + } + const isPrivateData = msg.oob; + const sendingServerId = trackedServersFound[0].serverId; + const server = this.repository.getServerById(sendingServerId); + const receivedStreamData = () => { + return { + data: msg.data, + server: server?.instance ?? {}, + requestArguments: subscription.params.arguments, + message: undefined, + private: isPrivateData, + }; + }; + const onDataHandlers = subscription.handlers.onData; + const queuedData = subscription.queued.data; + if (onDataHandlers.length > 0) { + onDataHandlers.forEach((callback) => { + if (typeof callback === "function") { + callback(receivedStreamData()); + } + }); + } + else { + queuedData.push(receivedStreamData()); + } + }; + handleSubscriptionCancelled = (msg) => { + const subLocalKey = this.subscriptionIdToLocalKeyMap[msg.subscription_id]; + if (typeof subLocalKey === "undefined") { + return; + } + const subscription = this.subscriptionsList[subLocalKey]; + if (typeof subscription !== "object") { + return; + } + const expectedNewLength = subscription.trackedServers.length - 1; + subscription.trackedServers = subscription.trackedServers.filter((server) => { + if (server.subscriptionId === msg.subscription_id) { + subscription.queued.closers.push(server.serverId); + return false; + } + else { + return true; + } + }); + if (subscription.trackedServers.length !== expectedNewLength) { + return; + } + if (subscription.trackedServers.length <= 0) { + this.timedCache.add(subscription); + clearTimeout(subscription.timeoutId); + this.callOnClosedHandlers(subscription); + delete this.subscriptionsList[subLocalKey]; + } + delete this.subscriptionIdToLocalKeyMap[msg.subscription_id]; + }; + callOnClosedHandlers(subscription, reason) { + const closersCount = subscription.queued.closers.length; + const closingServerId = (closersCount > 0) ? subscription.queued.closers[closersCount - 1] : null; + let closingServer; + if (closingServerId !== undefined && typeof closingServerId === "string") { + closingServer = this.repository.getServerById(closingServerId)?.instance ?? {}; + } + subscription.handlers.onClosed.forEach((callback) => { + if (typeof callback !== "function") { + return; + } + callback({ + message: reason || ON_CLOSE_MSG_SERVER_INIT, + requestArguments: subscription.params.arguments || {}, + server: closingServer, + stream: subscription.method, + }); + }); + } + closeSubscription(subLocalKey) { + const subscription = this.subscriptionsList[subLocalKey]; + if (typeof subscription !== "object") { + return; + } + subscription.trackedServers.forEach((server) => { + if (typeof server.subscriptionId === "undefined") { + return; + } + subscription.queued.closers.push(server.serverId); + this.session.sendFireAndForget({ + type: "unsubscribe", + subscription_id: server.subscriptionId, + reason_uri: "", + reason: ON_CLOSE_MSG_CLIENT_INIT, + }); + delete this.subscriptionIdToLocalKeyMap[server.subscriptionId]; + }); + subscription.trackedServers = []; + this.callOnClosedHandlers(subscription, ON_CLOSE_MSG_CLIENT_INIT); + delete this.subscriptionsList[subLocalKey]; + } + } + + class ClientProtocol { + session; + repository; + logger; + streaming; + constructor(session, repository, logger) { + this.session = session; + this.repository = repository; + this.logger = logger; + session.on("peer-added", (msg) => this.handlePeerAdded(msg)); + session.on("peer-removed", (msg) => this.handlePeerRemoved(msg)); + session.on("methods-added", (msg) => this.handleMethodsAddedMessage(msg)); + session.on("methods-removed", (msg) => this.handleMethodsRemovedMessage(msg)); + this.streaming = new ClientStreaming(session, repository, logger); + } + subscribe(stream, options, targetServers, success, error, existingSub) { + this.streaming.subscribe(stream, options, targetServers, success, error, existingSub); + } + invoke(id, method, args, target) { + const serverId = target.id; + const methodId = method.gatewayId; + const msg = { + type: "call", + server_id: serverId, + method_id: methodId, + arguments_kv: args, + }; + return this.session.send(msg, { invocationId: id, serverId }) + .then((m) => this.handleResultMessage(m)) + .catch((err) => this.handleInvocationError(err)); + } + drainSubscriptions() { + return this.streaming.drainSubscriptions(); + } + drainSubscriptionsCache() { + return this.streaming.drainSubscriptionsCache(); + } + handlePeerAdded(msg) { + const newPeerId = msg.new_peer_id; + const remoteId = msg.identity; + const isLocal = msg.meta ? msg.meta.local : true; + const pid = Number(remoteId.process); + const serverInfo = { + machine: remoteId.machine, + pid: isNaN(pid) ? remoteId.process : pid, + instance: remoteId.instance, + application: remoteId.application, + applicationName: remoteId.applicationName, + environment: remoteId.environment, + region: remoteId.region, + user: remoteId.user, + windowId: remoteId.windowId, + peerId: newPeerId, + api: remoteId.api, + isLocal + }; + this.repository.addServer(serverInfo, newPeerId); + } + handlePeerRemoved(msg) { + const removedPeerId = msg.removed_id; + const reason = msg.reason; + this.repository.removeServerById(removedPeerId, reason); + } + handleMethodsAddedMessage(msg) { + const serverId = msg.server_id; + const methods = msg.methods; + methods.forEach((method) => { + this.repository.addServerMethod(serverId, method); + }); + } + handleMethodsRemovedMessage(msg) { + const serverId = msg.server_id; + const methodIdList = msg.methods; + const server = this.repository.getServerById(serverId); + if (server) { + const serverMethodKeys = Object.keys(server.methods); + serverMethodKeys.forEach((methodKey) => { + const method = server.methods[methodKey]; + if (methodIdList.indexOf(method.gatewayId) > -1) { + this.repository.removeServerMethod(serverId, methodKey); + } + }); + } + } + handleResultMessage(msg) { + const invocationId = msg._tag.invocationId; + const result = msg.result; + const serverId = msg._tag.serverId; + const server = this.repository.getServerById(serverId); + return { + invocationId, + result, + instance: server?.instance, + status: InvokeStatus.Success, + message: "" + }; + } + handleInvocationError(msg) { + this.logger.debug(`handle invocation error ${JSON.stringify(msg)}`); + if ("_tag" in msg) { + const invocationId = msg._tag.invocationId; + const serverId = msg._tag.serverId; + const server = this.repository.getServerById(serverId); + const message = msg.reason; + const context = msg.context; + return { + invocationId, + result: context, + instance: server?.instance, + status: InvokeStatus.Error, + message + }; + } + else { + return { + invocationId: "", + message: msg.message, + status: InvokeStatus.Error, + error: msg + }; + } + } + } + + function gW3ProtocolFactory (instance, connection, clientRepository, serverRepository, libConfig, interop) { + const logger = libConfig.logger.subLogger("gw3-protocol"); + let resolveReadyPromise; + const readyPromise = new Promise((resolve) => { + resolveReadyPromise = resolve; + }); + const session = connection.domain("agm", ["subscribed"]); + const server = new ServerProtocol(session, clientRepository, serverRepository, logger.subLogger("server")); + const client = new ClientProtocol(session, clientRepository, logger.subLogger("client")); + async function handleReconnect() { + logger.info("reconnected - will replay registered methods and subscriptions"); + client.drainSubscriptionsCache().forEach((sub) => { + const methodInfo = sub.method; + const params = Object.assign({}, sub.params); + logger.info(`trying to soft-re-subscribe to method ${methodInfo.name}, with params: ${JSON.stringify(params)}`); + interop.client.subscribe(methodInfo, params, undefined, undefined, sub).then(() => logger.info(`soft-subscribing to method ${methodInfo.name} DONE`)).catch((error) => logger.warn(`subscribing to method ${methodInfo.name} failed: ${JSON.stringify(error)}}`)); + }); + const reconnectionPromises = []; + const existingSubscriptions = client.drainSubscriptions(); + for (const sub of existingSubscriptions) { + const methodInfo = sub.method; + const params = Object.assign({}, sub.params); + logger.info(`trying to re-subscribe to method ${methodInfo.name}, with params: ${JSON.stringify(params)}`); + reconnectionPromises.push(interop.client.subscribe(methodInfo, params, undefined, undefined, sub).then(() => logger.info(`subscribing to method ${methodInfo.name} DONE`))); + } + const registeredMethods = serverRepository.getList(); + serverRepository.reset(); + for (const method of registeredMethods) { + const def = method.definition; + if (method.stream) { + reconnectionPromises.push(interop.server.createStream(def, method.streamCallbacks, undefined, undefined, method.stream) + .then(() => logger.info(`subscribing to method ${def.name} DONE`)) + .catch(() => logger.warn(`subscribing to method ${def.name} FAILED`))); + } + else if (method?.theFunction?.userCallback) { + reconnectionPromises.push(interop.register(def, method.theFunction.userCallback) + .then(() => logger.info(`registering method ${def.name} DONE`)) + .catch(() => logger.warn(`registering method ${def.name} FAILED`))); + } + else if (method?.theFunction?.userCallbackAsync) { + reconnectionPromises.push(interop.registerAsync(def, method.theFunction.userCallbackAsync) + .then(() => logger.info(`registering method ${def.name} DONE`)) + .catch(() => logger.warn(`registering method ${def.name} FAILED`))); + } + } + await Promise.all(reconnectionPromises); + logger.info("Interop is re-announced"); + } + function handleInitialJoin() { + if (resolveReadyPromise) { + resolveReadyPromise({ + client, + server, + }); + resolveReadyPromise = undefined; + } + } + session.onJoined((reconnect) => { + clientRepository.addServer(instance, connection.peerId); + if (reconnect) { + handleReconnect().then(() => connection.setLibReAnnounced({ name: "interop" })).catch((error) => logger.warn(`Error while re-announcing interop: ${JSON.stringify(error)}`)); + } + else { + handleInitialJoin(); + } + }); + session.onLeft(() => { + clientRepository.reset(); + }); + session.join(); + return readyPromise; + } + + class Interop { + instance; + readyPromise; + client; + server; + unwrappedInstance; + protocol; + clientRepository; + serverRepository; + constructor(configuration) { + if (typeof configuration === "undefined") { + throw new Error("configuration is required"); + } + if (typeof configuration.connection === "undefined") { + throw new Error("configuration.connections is required"); + } + const connection = configuration.connection; + if (typeof configuration.methodResponseTimeout !== "number") { + configuration.methodResponseTimeout = 30 * 1000; + } + if (typeof configuration.waitTimeoutMs !== "number") { + configuration.waitTimeoutMs = 30 * 1000; + } + this.unwrappedInstance = new InstanceWrapper(this, undefined, connection); + this.instance = this.unwrappedInstance.unwrap(); + this.clientRepository = new ClientRepository(configuration.logger.subLogger("cRep"), this); + this.serverRepository = new ServerRepository(); + let protocolPromise; + if (connection.protocolVersion === 3) { + protocolPromise = gW3ProtocolFactory(this.instance, connection, this.clientRepository, this.serverRepository, configuration, this); + } + else { + throw new Error(`protocol ${connection.protocolVersion} not supported`); + } + this.readyPromise = protocolPromise.then((protocol) => { + this.protocol = protocol; + this.client = new Client(this.protocol, this.clientRepository, this.instance, configuration); + this.server = new Server(this.protocol, this.serverRepository); + return this; + }); + } + ready() { + return this.readyPromise; + } + serverRemoved(callback) { + return this.client.serverRemoved(callback); + } + serverAdded(callback) { + return this.client.serverAdded(callback); + } + serverMethodRemoved(callback) { + return this.client.serverMethodRemoved(callback); + } + serverMethodAdded(callback) { + return this.client.serverMethodAdded(callback); + } + methodRemoved(callback) { + return this.client.methodRemoved(callback); + } + methodAdded(callback) { + return this.client.methodAdded(callback); + } + methodsForInstance(instance) { + return this.client.methodsForInstance(instance); + } + methods(methodFilter) { + return this.client.methods(methodFilter); + } + servers(methodFilter) { + return this.client.servers(methodFilter); + } + subscribe(method, options, successCallback, errorCallback) { + return this.client.subscribe(method, options, successCallback, errorCallback); + } + createStream(streamDef, callbacks, successCallback, errorCallback) { + return this.server.createStream(streamDef, callbacks, successCallback, errorCallback); + } + unregister(methodFilter) { + return this.server.unregister(methodFilter); + } + registerAsync(methodDefinition, callback) { + return this.server.registerAsync(methodDefinition, callback); + } + register(methodDefinition, callback) { + return this.server.register(methodDefinition, callback); + } + invoke(methodFilter, argumentObj, target, additionalOptions, success, error) { + return this.client.invoke(methodFilter, argumentObj, target, additionalOptions, success, error); + } + waitForMethod(name) { + const pw = new PromiseWrapper$1(); + const unsubscribe = this.client.methodAdded((m) => { + if (m.name === name) { + unsubscribe(); + pw.resolve(m); + } + }); + return pw.promise; + } + } + + const successMessages = ["subscribed", "success"]; + class MessageBus { + connection; + logger; + peerId; + session; + subscriptions; + readyPromise; + constructor(connection, logger) { + this.connection = connection; + this.logger = logger; + this.peerId = connection.peerId; + this.subscriptions = []; + this.session = connection.domain("bus", successMessages); + this.readyPromise = this.session.join(); + this.readyPromise.then(() => { + this.watchOnEvent(); + }); + } + ready() { + return this.readyPromise; + } + publish = (topic, data, options) => { + const { routingKey, target } = options || {}; + const args = this.removeEmptyValues({ + type: "publish", + topic, + data, + peer_id: this.peerId, + routing_key: routingKey, + target_identity: target + }); + this.session.send(args); + }; + subscribe = (topic, callback, options) => { + return new Promise((resolve, reject) => { + const { routingKey, target } = options || {}; + const args = this.removeEmptyValues({ + type: "subscribe", + topic, + peer_id: this.peerId, + routing_key: routingKey, + source: target + }); + this.session.send(args) + .then((response) => { + const { subscription_id } = response; + this.subscriptions.push({ subscription_id, topic, callback, source: target }); + resolve({ + unsubscribe: () => { + this.session.send({ type: "unsubscribe", subscription_id, peer_id: this.peerId }); + this.subscriptions = this.subscriptions.filter((s) => s.subscription_id !== subscription_id); + return Promise.resolve(); + } + }); + }) + .catch((error) => reject(error)); + }); + }; + watchOnEvent = () => { + this.session.on("event", (args) => { + const { data, subscription_id } = args; + const source = args["publisher-identity"]; + const subscription = this.subscriptions.find((s) => s.subscription_id === subscription_id); + if (subscription) { + if (!subscription.source) { + subscription.callback(data, subscription.topic, source); + } + else { + if (this.keysMatch(subscription.source, source)) { + subscription.callback(data, subscription.topic, source); + } + } + } + }); + }; + removeEmptyValues(obj) { + const cleaned = {}; + Object.keys(obj).forEach((key) => { + if (obj[key] !== undefined && obj[key] !== null) { + cleaned[key] = obj[key]; + } + }); + return cleaned; + } + keysMatch(obj1, obj2) { + const keysObj1 = Object.keys(obj1); + let allMatch = true; + keysObj1.forEach((key) => { + if (obj1[key] !== obj2[key]) { + allMatch = false; + } + }); + return allMatch; + } + } + + const IOConnectCoreFactory = (userConfig, ext) => { + const iodesktop = typeof window === "object" ? (window.iodesktop ?? window.glue42gd) : undefined; + const preloadPromise = typeof window === "object" ? (window.gdPreloadPromise ?? Promise.resolve()) : Promise.resolve(); + const glueInitTimer = timer("glue"); + userConfig = userConfig || {}; + ext = ext || {}; + const internalConfig = prepareConfig$1(userConfig, ext, iodesktop); + let _connection; + let _interop; + let _logger; + let _metrics; + let _contexts; + let _bus; + let _allowTrace; + const libs = {}; + function registerLib(name, inner, t) { + _allowTrace = _logger.canPublish("trace"); + if (_allowTrace) { + _logger.trace(`registering ${name} module`); + } + const done = (e) => { + inner.initTime = t.stop(); + inner.initEndTime = t.endTime; + inner.marks = t.marks; + if (!_allowTrace) { + return; + } + const traceMessage = e ? + `${name} failed - ${e.message}` : + `${name} is ready - ${t.endTime - t.startTime}`; + _logger.trace(traceMessage); + }; + inner.initStartTime = t.startTime; + if (inner.ready) { + inner.ready() + .then(() => { + done(); + }) + .catch((e) => { + const error = typeof e === "string" ? new Error(e) : e; + done(error); + }); + } + else { + done(); + } + if (!Array.isArray(name)) { + name = [name]; + } + name.forEach((n) => { + libs[n] = inner; + IOConnectCoreFactory[n] = inner; + }); + } + function setupConnection() { + const initTimer = timer("connection"); + _connection = new Connection(internalConfig.connection, _logger.subLogger("connection")); + let authPromise = Promise.resolve(internalConfig.auth); + if (internalConfig.connection && !internalConfig.auth) { + if (iodesktop) { + authPromise = iodesktop.getGWToken() + .then((token) => { + return { + gatewayToken: token + }; + }); + } + else if (typeof window !== "undefined" && window?.glue42electron) { + if (typeof window.glue42electron.gwToken === "string") { + authPromise = Promise.resolve({ + gatewayToken: window.glue42electron.gwToken + }); + } + } + else { + authPromise = Promise.reject("You need to provide auth information"); + } + } + return authPromise + .then((authConfig) => { + initTimer.mark("auth-promise-resolved"); + let authRequest; + if (Object.prototype.toString.call(authConfig) === "[object Object]") { + authRequest = authConfig; + } + else { + throw new Error("Invalid auth object - " + JSON.stringify(authConfig)); + } + return _connection.login(authRequest); + }) + .then(() => { + registerLib("connection", _connection, initTimer); + return internalConfig; + }) + .catch((e) => { + if (_connection) { + _connection.logout(); + } + throw e; + }); + } + function setupLogger() { + const initTimer = timer("logger"); + _logger = new Logger$1(`${internalConfig.connection.identity?.application}`, undefined, internalConfig.customLogger); + _logger.consoleLevel(internalConfig.logger.console); + _logger.publishLevel(internalConfig.logger.publish); + if (_logger.canPublish("debug")) { + _logger.debug("initializing glue..."); + } + registerLib("logger", _logger, initTimer); + return Promise.resolve(undefined); + } + function setupMetrics() { + const initTimer = timer("metrics"); + const config = internalConfig.metrics; + const metricsPublishingEnabledFunc = iodesktop?.getMetricsPublishingEnabled; + const identity = internalConfig.connection.identity; + const canUpdateMetric = metricsPublishingEnabledFunc ? metricsPublishingEnabledFunc : () => true; + const disableAutoAppSystem = (typeof config !== "boolean" && config.disableAutoAppSystem) ?? false; + _metrics = metrics({ + connection: config ? _connection : undefined, + logger: _logger.subLogger("metrics"), + canUpdateMetric, + system: "Glue42", + service: identity?.service ?? iodesktop?.applicationName ?? internalConfig.application, + instance: identity?.instance ?? identity?.windowId ?? nanoid$1(10), + disableAutoAppSystem, + pagePerformanceMetrics: typeof config !== "boolean" ? config?.pagePerformanceMetrics : undefined + }); + registerLib("metrics", _metrics, initTimer); + return Promise.resolve(); + } + function setupInterop() { + const initTimer = timer("interop"); + const agmConfig = { + connection: _connection, + logger: _logger.subLogger("interop"), + }; + _interop = new Interop(agmConfig); + Logger$1.Interop = _interop; + registerLib(["interop", "agm"], _interop, initTimer); + return Promise.resolve(); + } + function setupContexts() { + const hasActivities = (internalConfig.activities && _connection.protocolVersion === 3); + const needsContexts = internalConfig.contexts || hasActivities; + if (needsContexts) { + const initTimer = timer("contexts"); + _contexts = new ContextsModule({ + connection: _connection, + logger: _logger.subLogger("contexts"), + trackAllContexts: typeof internalConfig.contexts === "object" ? internalConfig.contexts.trackAllContexts : false, + reAnnounceKnownContexts: typeof internalConfig.contexts === "object" ? internalConfig.contexts.reAnnounceKnownContexts : false + }); + registerLib("contexts", _contexts, initTimer); + return _contexts; + } + else { + const replayer = _connection.replayer; + if (replayer) { + replayer.drain(ContextMessageReplaySpec.name); + } + } + } + async function setupBus() { + if (!internalConfig.bus) { + return Promise.resolve(); + } + const initTimer = timer("bus"); + _bus = new MessageBus(_connection, _logger.subLogger("bus")); + registerLib("bus", _bus, initTimer); + return Promise.resolve(); + } + function setupExternalLibs(externalLibs) { + try { + externalLibs.forEach((lib) => { + setupExternalLib(lib.name, lib.create); + }); + return Promise.resolve(); + } + catch (e) { + return Promise.reject(e); + } + } + function setupExternalLib(name, createCallback) { + const initTimer = timer(name); + const lib = createCallback(libs); + if (lib) { + registerLib(name, lib, initTimer); + } + } + function waitForLibs() { + const libsReadyPromises = Object.keys(libs).map((key) => { + const lib = libs[key]; + return lib.ready ? + lib.ready() : Promise.resolve(); + }); + return Promise.all(libsReadyPromises); + } + function constructGlueObject() { + const feedbackFunc = (feedbackInfo) => { + if (!_interop) { + return; + } + _interop.invoke("T42.ACS.Feedback", feedbackInfo, "best"); + }; + const info = { + coreVersion: version$1, + version: internalConfig.version + }; + glueInitTimer.stop(); + const glue = { + feedback: feedbackFunc, + info, + logger: _logger, + interop: _interop, + agm: _interop, + connection: _connection, + metrics: _metrics, + contexts: _contexts, + bus: _bus, + version: internalConfig.version, + userConfig, + done: () => { + _logger?.info("done called by user..."); + return _connection.logout(); + } + }; + glue.performance = { + get glueVer() { + return internalConfig.version; + }, + get glueConfig() { + return JSON.stringify(userConfig); + }, + get browser() { + return window.performance.timing.toJSON(); + }, + get memory() { + return window.performance.memory; + }, + get initTimes() { + const all = getAllTimers(); + return Object.keys(all).map((key) => { + const t = all[key]; + return { + name: key, + duration: t.endTime - t.startTime, + marks: t.marks, + startTime: t.startTime, + endTime: t.endTime + }; + }); + } + }; + Object.keys(libs).forEach((key) => { + const lib = libs[key]; + glue[key] = lib; + }); + glue.config = {}; + Object.keys(internalConfig).forEach((k) => { + glue.config[k] = internalConfig[k]; + }); + if (ext && ext.extOptions) { + Object.keys(ext.extOptions).forEach((k) => { + glue.config[k] = ext?.extOptions[k]; + }); + } + if (ext?.enrichGlue) { + ext.enrichGlue(glue); + } + if (iodesktop && iodesktop.updatePerfData) { + iodesktop.updatePerfData(glue.performance); + } + if (glue.agm) { + const deprecatedDecorator = (fn, wrong, proper) => { + return function () { + glue.logger.warn(`glue.js - 'glue.agm.${wrong}' method is deprecated, use 'glue.interop.${proper}' instead.`); + return fn.apply(glue.agm, arguments); + }; + }; + const agmAny = glue.agm; + agmAny.method_added = deprecatedDecorator(glue.agm.methodAdded, "method_added", "methodAdded"); + agmAny.method_removed = deprecatedDecorator(glue.agm.methodRemoved, "method_removed", "methodRemoved"); + agmAny.server_added = deprecatedDecorator(glue.agm.serverAdded, "server_added", "serverAdded"); + agmAny.server_method_aded = deprecatedDecorator(glue.agm.serverMethodAdded, "server_method_aded", "serverMethodAdded"); + agmAny.server_method_removed = deprecatedDecorator(glue.agm.serverMethodRemoved, "server_method_removed", "serverMethodRemoved"); + } + return glue; + } + async function registerInstanceIfNeeded() { + const RegisterInstanceMethodName = "T42.ACS.RegisterInstance"; + if (Utils$1.isNode() && typeof process.env._GD_STARTING_CONTEXT_ === "undefined" && typeof userConfig?.application !== "undefined") { + const isMethodAvailable = _interop.methods({ name: RegisterInstanceMethodName }).length > 0; + if (isMethodAvailable) { + try { + await _interop.invoke(RegisterInstanceMethodName, { appName: userConfig?.application, pid: process.pid }); + } + catch (error) { + const typedError = error; + _logger.error(`Cannot register as an instance: ${JSON.stringify(typedError.message)}`); + } + } + } + } + return preloadPromise + .then(setupLogger) + .then(setupConnection) + .then(() => Promise.all([setupMetrics(), setupInterop(), setupContexts(), setupBus()])) + .then(() => _interop.readyPromise) + .then(() => registerInstanceIfNeeded()) + .then(() => { + return setupExternalLibs(internalConfig.libs || []); + }) + .then(waitForLibs) + .then(constructGlueObject) + .catch((err) => { + return Promise.reject({ + err, + libs + }); + }); + }; + if (typeof window !== "undefined") { + window.IOConnectCore = IOConnectCoreFactory; + } + IOConnectCoreFactory.version = version$1; + IOConnectCoreFactory.default = IOConnectCoreFactory; + + class ActivityEntity { + constructor(id) { + this._id = id; + } + get id() { + return this._id; + } + _update(other) { + if (other._id !== this._id) { + throw Error("Can not update from entity with different id."); + } + this._updateCore(other); + } + _updateCore(other) { + return; + } + _beforeDelete(other) { + return; + } + } + + function isNumber(arg) { + return typeof arg === "number"; + } + function isString(arg) { + return typeof arg === "string"; + } + function isObject(arg) { + return typeof arg === "object" && !Array.isArray(arg) && arg !== null; + } + function isArray(arg) { + if (Array.isArray) { + return Array.isArray(arg); + } + return toString.call(arg) === "[object Array]"; + } + function isUndefined(arg) { + return typeof arg === "undefined"; + } + function isUndefinedOrNull(arg) { + return arg === null || typeof arg === "undefined"; + } + function isNullOrWhiteSpace(str) { + return (typeof str !== "string" || !str || str.length === 0 || /^\s*$/.test(str)); + } + function isBoolean(obj) { + return obj === true || obj === false || toString.call(obj) === "[object Boolean]"; + } + function isFunction(arg) { + return !!(arg && arg.constructor && arg.call && arg.apply); + } + function some(array, predicate) { + for (let index = 0; index < array.length; index++) { + if (predicate(array[index], index)) { + return true; + } + } + return false; + } + function ifNotUndefined(what, doWithIt) { + if (typeof what !== "undefined") { + doWithIt(what); + } + } + function promisify$1(promise, successCallback, errorCallback) { + if (typeof successCallback !== "function" && typeof errorCallback !== "function") { + return promise; + } + if (typeof successCallback !== "function") { + successCallback = () => { return; }; + } + else if (typeof errorCallback !== "function") { + errorCallback = () => { return; }; + } + promise.then(successCallback, errorCallback); + } + + class ActivityType extends ActivityEntity { + constructor(name, ownerWindow, helperWindows, description) { + super(name); + this._name = name; + this._description = description; + this._ownerWindow = ownerWindow; + this._helperWindows = helperWindows || []; + } + get name() { + return this._name; + } + get description() { + return this._description; + } + get helperWindows() { + return this._helperWindows.map((hw) => this.covertToWindowDef(hw)); + } + get ownerWindow() { + return this.covertToWindowDef(this._ownerWindow); + } + initiate(context, callback, configuration) { + return this._manager.initiate(this._name, context, callback, configuration); + } + _updateCore(other) { + super._updateCore(other); + ifNotUndefined(other._description, (x) => this._description = x); + ifNotUndefined(other._ownerWindow, (x) => this._ownerWindow = x); + ifNotUndefined(other._helperWindows, (x) => this._helperWindows = x); + } + covertToWindowDef(windowType) { + var _a, _b; + return { + type: (_a = windowType === null || windowType === void 0 ? void 0 : windowType.id) === null || _a === void 0 ? void 0 : _a.type, + name: (_b = windowType === null || windowType === void 0 ? void 0 : windowType.id) === null || _b === void 0 ? void 0 : _b.name + }; + } + } + + class WindowType extends ActivityEntity { + constructor(name, appByWindowTypeGetter) { + super(name); + this._name = name; + this._appByWindowTypeGetter = appByWindowTypeGetter; + } + get name() { + return this._name; + } + get config() { + return this._appByWindowTypeGetter(this._name); + } + get windows() { + return this._manager.getWindows({ type: this._name }); + } + create(activity, configuration) { + const definition = Object.assign({ type: this.name, name: this.name, isIndependent: false }, configuration); + return this._manager.createWindow(activity, definition); + } + } + + class EntityEvent { + constructor(entitiy, context) { + this.entity = entitiy; + this.context = context; + } + } + class EntityEventContext { + constructor(eventType) { + this.type = eventType; + } + } + class ActivityStatusChangeEventContext extends EntityEventContext { + constructor(newStatus, oldStatus) { + super(EntityEventType.StatusChange); + this.newStatus = newStatus; + this.oldStatus = oldStatus; + } + } + class ActivityContextChangedEventContext extends EntityEventContext { + constructor(context, updated, removed) { + super(EntityEventType.ActivityContextChange); + this.context = typeof context === "string" ? JSON.parse(context) : context; + this.updated = updated; + this.removed = removed; + } + } + class EntityEventType { + } + EntityEventType.Added = "added"; + EntityEventType.Removed = "removed"; + EntityEventType.Updated = "updated"; + EntityEventType.Closed = "closed"; + EntityEventType.StatusChange = "statusChange"; + EntityEventType.ActivityContextChange = "activityContextUpdate"; + EntityEventType.ActivityWindowEvent = "activityWindowEvent"; + EntityEventType.ActivityWindowJoinedActivity = "joined"; + EntityEventType.ActivityWindowLeftActivity = "left"; + class ActivityState { + } + ActivityState.Created = "created"; + ActivityState.Started = "started"; + ActivityState.Destroyed = "destroyed"; + + class ActivityAGM { + constructor(activity) { + this._activity = activity; + } + register(definition, handler) { + this._ensureHasAgm(); + ActivityAGM.AGM.register(definition, handler); + } + servers() { + this._ensureHasAgm(); + if (isUndefinedOrNull(this._activity)) { + return []; + } + return this._activity.windows.map((w) => { + return w.instance; + }); + } + methods() { + this._ensureHasAgm(); + if (isUndefinedOrNull(this._activity)) { + return []; + } + const windows = this._activity.windows; + const methodNames = []; + const methods = []; + windows.forEach((window) => { + const windowMethods = this.methodsForWindow(window); + windowMethods.forEach((currentWindowMethod) => { + if (methodNames.indexOf(currentWindowMethod.name) === -1) { + methodNames.push(currentWindowMethod.name); + methods.push(currentWindowMethod); + } + }); + }); + return methods; + } + methodsForWindow(window) { + this._ensureHasAgm(); + if (!window.instance) { + return []; + } + return ActivityAGM.AGM.methodsForInstance(window.instance); + } + invoke(methodName, arg, target, options, success, error) { + this._ensureHasAgm(); + const activityServers = this.servers(); + if (isUndefinedOrNull(target)) { + target = "activity.all"; + } + if (isString(target)) { + if (target === "activity.all") ; + else if (target === "activity.best") { + const potentialTargets = activityServers.filter((server) => { + const methods = ActivityAGM.AGM.methodsForInstance(server); + return methods.filter((m) => { + return m.name === methodName; + }).length > 0; + }); + if (potentialTargets.length > 0) { + [potentialTargets[0]]; + } + } + else if (target === "all" || target === "best") { + return promisify$1(ActivityAGM.AGM.invoke(methodName, arg, target, options), success, error); + } + else { + throw new Error("Invalid invoke target " + target); + } + } + else if (isArray(target)) { + if (target.length >= 0) { + const firstElem = target[0]; + if (this._isInstance(firstElem)) { + target.map((instance) => instance); + } + else if (this._isActivityWindow(firstElem)) { + target.map((win) => win.instance); + } + else { + throw new Error("Unknown target object"); + } + } + } + else { + if (this._isInstance(target)) ; + else if (this._isActivityWindow(target)) { + [target.instance]; + } + else { + throw new Error("Unknown target object"); + } + } + throw new Error("Not implemented"); + } + unregister(definition) { + this._ensureHasAgm(); + return ActivityAGM.AGM.unregister(definition); + } + createStream(methodDefinition, subscriptionAddedHandler, subscriptionRemovedHandler) { + this._ensureHasAgm(); + ActivityAGM.AGM.createStream(methodDefinition, { + subscriptionAddedHandler, + subscriptionRemovedHandler, + subscriptionRequestHandler: undefined + }); + } + subscribe(methodDefinition, parameters, target) { + this._ensureHasAgm(); + return ActivityAGM.AGM.subscribe(methodDefinition, parameters); + } + _ensureHasAgm() { + if (isUndefinedOrNull(ActivityAGM.AGM)) { + throw new Error("Agm should be configured to be used in activity"); + } + } + _isInstance(obj) { + return obj.application !== undefined; + } + _isActivityWindow(obj) { + return obj.instance !== undefined; + } + } + + class AttachedActivityDescriptor { + constructor(manager, ownerActivityId, state) { + this._manager = manager; + this._ownerActivityId = ownerActivityId; + this._state = state; + } + get ownerId() { + return this._state.ownerId; + } + get windowIds() { + return this._state.windowIds; + } + get frameColor() { + return this._state.frameColor; + } + get context() { + return this._state.context; + } + get tag() { + return this._state.tag; + } + detach(descriptor) { + descriptor = descriptor || {}; + const merged = {}; + Object.keys(this._state).forEach((prop) => { + merged[prop] = this._state[prop]; + }); + merged.context = descriptor.context || merged.context; + merged.frameColor = descriptor.frameColor || merged.frameColor; + return this._manager.detachActivities(this._ownerActivityId, merged); + } + } + + const nextTick = (cb) => { + setTimeout(cb, 0); + }; + function nodeify(promise, callback) { + if (!isFunction(callback)) { + return promise; + } + promise.then((resp) => { + nextTick(() => { + callback(null, resp); + }); + }, (err) => { + nextTick(() => { + callback(err, null); + }); + }); + } + + class Activity extends ActivityEntity { + constructor(id, actType, status, context, ownerId) { + super(id); + this._id = id; + this._actType = actType; + this._status = status; + this._context = context; + this._ownerId = ownerId; + this._agm = new ActivityAGM(this); + } + get type() { + if (this._manager) { + return this._manager.getActivityType(this._actType); + } + return undefined; + } + get context() { + return this._context; + } + get status() { + return this._status; + } + get owner() { + if (!this._ownerId) { + return null; + } + return this._manager.getWindows({ id: this._ownerId })[0]; + } + get windows() { + return this._manager.getWindows({ activityId: this._id }); + } + get agm() { + return this._agm; + } + addWindow(window, callback) { + return this._manager.addWindowToActivity(this, window, callback); + } + createWindow(windowType, callback) { + return this._manager.createWindow(this, windowType, callback); + } + createStackedWindows(windowTypes, timeout, callback) { + return this._manager.createStackedWindows(this, windowTypes, timeout, callback); + } + leave(window, callback) { + return this._manager.leaveWindowFromActivity(this, window, callback); + } + getWindowsByType(windowType) { + const filter = { activityId: this._id, type: windowType }; + return this._manager.getWindows(filter); + } + setContext(context, callback) { + return this._manager.setActivityContext(this, context, callback); + } + updateContext(context, callback) { + return this._manager.updateActivityContext(this, context, callback); + } + onStatusChange(handler) { + return this._manager.subscribeActivityEvents((a, ns, os) => { + if (a.id === this.id) { + handler(a, ns, os); + } + }); + } + onWindowEvent(handler) { + return this._manager.subscribeWindowEvents((a, w, e) => { + if (a.id === this.id) { + handler(a, w, e); + } + }); + } + onContextChanged(handler) { + this._manager.subscribeActivityContextChanged((act, context, updated, removed) => { + if (act.id === this.id) { + handler(context, updated, removed, act); + } + }); + try { + handler(this.context, this.context, [], this); + } + catch (e) { + return; + } + } + stop() { + this._manager.stopActivity(this); + } + clone(options) { + return this._manager.clone(this, options); + } + attach(activity, tag) { + let activityId; + if (typeof activity === "string") { + activityId = activity; + } + else { + activityId = activity.id; + } + return this._manager.attachActivities(activityId, this.id, tag); + } + onActivityAttached(callback) { + this._manager.subscribeActivitiesAttached((newActId, oldActId, descriptor) => { + if (newActId !== this._id) { + return; + } + callback(descriptor); + }); + } + onDetached(callback) { + this._manager.subscribeActivitiesDetached((newAct, originalActivity, state) => { + if (originalActivity.id !== this._id) { + return; + } + callback(newAct, state); + }); + } + _updateCore(other) { + super._updateCore(other); + ifNotUndefined(other._actType, (x) => this._actType = x); + ifNotUndefined(other._context, (x) => this._context = x); + ifNotUndefined(other._ownerId, (x) => this._ownerId = x); + if (other._status && (!this._status || (this._status.state !== other._status.state))) { + this._status = other._status; + } + } + _updateDescriptors(allStates) { + this._attached = allStates.map((s) => { + return new AttachedActivityDescriptor(this._manager, this._id, s); + }); + } + get attached() { + return this._attached; + } + setFrameColor(color, callback) { + const promise = new Promise((resolve, reject) => { + let callbacksToWait = this.windows.length; + if (callbacksToWait === 0) { + resolve(this); + } + this.windows.forEach((w) => { + w.underlyingWindow.setFrameColor(color, () => { + callbacksToWait--; + if (callbacksToWait <= 0) { + resolve(this); + } + }); + }); + setTimeout(() => { + if (callbacksToWait > 0) { + reject(this.id + " - timed out waiting for setFrameColor with" + color); + } + }, 5000); + }); + return nodeify(promise, callback); + } + getFrameColor() { + if (!this.windows || this.windows.length === 0) { + return ""; + } + return this.windows[0].underlyingWindow.frameColor; + } + } + + class LogLevel { + } + LogLevel.Trace = "trace"; + LogLevel.Debug = "debug"; + LogLevel.Info = "info"; + LogLevel.Warn = "warn"; + LogLevel.Error = "error"; + class Logger { + static GetNamed(name) { + return new Logger(name); + } + static Get(owner) { + return new Logger(Logger.GetTypeName(owner)); + } + constructor(name) { + this._name = name; + if (!isUndefinedOrNull(Logger.GlueLogger)) { + this._glueLogger = Logger.GlueLogger.subLogger(name); + } + } + trace(message) { + if (!isUndefinedOrNull(this._glueLogger)) { + this._glueLogger.trace(message); + } + else { + if (Logger.Level === LogLevel.Trace) { + console.info(this._getMessage(message, LogLevel.Trace)); + } + } + } + debug(message) { + if (!isUndefinedOrNull(this._glueLogger)) { + this._glueLogger.debug(message); + } + else { + if (Logger.Level === LogLevel.Debug || + Logger.Level === LogLevel.Trace) { + console.info(this._getMessage(message, LogLevel.Debug)); + } + } + } + info(message) { + if (!isUndefinedOrNull(this._glueLogger)) { + this._glueLogger.info(message); + } + else { + if (Logger.Level === LogLevel.Debug || + Logger.Level === LogLevel.Trace || + Logger.Level === LogLevel.Info) { + console.info(this._getMessage(message, LogLevel.Info)); + } + } + } + warn(message) { + if (!isUndefinedOrNull(this._glueLogger)) { + this._glueLogger.warn(message); + } + else { + if (Logger.Level === LogLevel.Debug || + Logger.Level === LogLevel.Trace || + Logger.Level === LogLevel.Info || + Logger.Level === LogLevel.Warn) { + console.info(this._getMessage(message, LogLevel.Info)); + } + } + } + error(message) { + if (!isUndefinedOrNull(this._glueLogger)) { + this._glueLogger.error(message); + } + else { + console.error(this._getMessage(message, LogLevel.Error)); + console.trace(); + } + } + _getMessage(message, level) { + return "[" + level + "] " + this._name + " - " + message; + } + static GetTypeName(object) { + const funcNameRegex = /function (.{1,})\(/; + const results = (funcNameRegex).exec(object.constructor.toString()); + return (results && results.length > 1) ? results[1] : ""; + } + } + Logger.Level = LogLevel.Info; + + class ActivityWindow extends ActivityEntity { + constructor(id, name, type, activityId, instance, isIndependent, windowGetter, hcWindowId) { + super(id); + this._logger = Logger.Get("window"); + this._type = type; + this._activityId = activityId; + this._name = name; + this._instance = instance; + this._isIndependent = isIndependent; + this._windowGetter = windowGetter; + this._hcWindowId = hcWindowId; + } + getBounds() { + return this._manager.getWindowBounds(this.id); + } + get name() { + return this._name; + } + get isIndependent() { + return this._isIndependent; + } + get type() { + if (this._manager) { + return this._manager.getWindowType(this._type); + } + return undefined; + } + get activity() { + if (isUndefined(this._activityId)) { + return undefined; + } + return this._manager.getActivityById(this._activityId); + } + get isOwner() { + const act = this.activity; + if (isUndefined(act)) { + return false; + } + return act.owner.id === this.id; + } + setVisible(isVisible, callback) { + return this._manager.setWindowVisibility(this.id, isVisible); + } + activate(focus) { + return this._manager.activateWindow(this.id, focus); + } + setBounds(bounds, callback) { + return this._manager.setWindowBounds(this.id, bounds, callback); + } + close() { + return this._manager.closeWindow(this.id); + } + get instance() { + return this._instance; + } + get underlyingWindow() { + const window = this._windowGetter(); + if (!window) { + return { + id: this._hcWindowId + }; + } + return window; + } + onActivityJoined(callback) { + this._subscribeForActivityWindowEvent(EntityEventType.ActivityWindowJoinedActivity, callback); + } + onActivityRemoved(callback) { + this._subscribeForActivityWindowEvent(EntityEventType.ActivityWindowLeftActivity, callback); + } + _updateCore(other) { + ifNotUndefined(other._activityId, (x) => this._activityId = x); + ifNotUndefined(other._isIndependent, (x) => this._isIndependent = x); + ifNotUndefined(other._hcWindowId, (x) => this._hcWindowId = x); + ifNotUndefined(other._type, (x) => this._type = x); + ifNotUndefined(other._name, (x) => this._name = x); + if (!isUndefinedOrNull(other._instance)) { + this._instance = other._instance; + } + } + _subscribeForActivityWindowEvent(eventName, callback) { + this._manager.subscribeWindowEvents((activity, window, event) => { + if (window.id !== this.id) { + return; + } + if (event === eventName) { + callback(activity); + } + }); + } + _beforeDelete(other) { + this._hcWindowId = other._hcWindowId; + } + } + + class ActivityStatus { + constructor(state, message, time) { + this.state = state; + this.message = message; + this.time = time; + } + getState() { + return this.state; + } + getMessage() { + return this.message; + } + getTime() { + return this.time; + } + } + + const gwMmessageError = "error"; + const gwMessageAddActivityTypes = "add-types"; + const gwMmessageActivityTypesAdded = "types-added"; + const gwMessageRemoveActivityTypes = "remove-types"; + const gwMessageActivityTypesRemoved = "types-removed"; + const gwMessageActivityCreated = "created"; + const gwMessageActivityDestroyed = "destroyed"; + const gwMessageActivityInitiated = "initiated"; + const gwMmessageJoinActivity = "join-activity"; + const gwMessageJoinedActivity = "joined"; + const gwMessageActivityJoined = "activity-joined"; + const gwMessageLeaveActivity = "leave-activity"; + const gwMessageActivityLeft = "left"; + const gwNmessageMergeActivities = "merge"; + const gwMessageSplitActivities = "split"; + const gwMessageOwnerChanged = "owner-changed"; + const gwMessageAddPeerFactories = "add-peer-factories"; + const gwMessagePeerFactoriesAdded = "peer-factories-added"; + const gwMessageRemovePeerFactories = "remove-peer-factories"; + const gwMessagePeerFactoriesRemoved = "peer-factories-removed"; + const gwMessageCreateActivity = "create"; + const gwMessageCreatePeer = "create-peer"; + const gwMessagePeerRequested = "peer-requested"; + const gwMessageReady = "ready"; + const gwMessagePeerCreated = "peer-created"; + const gwMessageDestroyActivity = "destroy"; + const gwMessageDisposePeer = "dispose-peer"; + const gwMessageDestroyPeer = "destroy-peer"; + class GW3Bridge { + static activityTypeGwMessageEntityToActivityType(entity, description) { + const nameToWindowType = (windowName) => new WindowType(windowName, undefined); + return new ActivityType(entity.name, entity.owner_type && nameToWindowType(entity.owner_type), entity.helper_types && entity.helper_types.map(nameToWindowType), description); + } + static peerFactoryGwMessageEntityToWindowType(entity) { + return new WindowType(entity.peer_type, (_) => undefined); + } + static activityGwMessageToActivity(msg, status) { + const ownerId = msg.owner !== undefined ? msg.owner.peer_id : msg.owner_id; + return new Activity(msg.activity_id, msg.activity_type, status, msg.context_snapshot, ownerId); + } + static activityToActivityStatusChangeEvent(act) { + return new EntityEvent(act, new ActivityStatusChangeEventContext(act.status, undefined)); + } + constructor(config) { + this._activityChangeCallbacks = []; + this._activityTypeStatusChangeCallbacks = []; + this._activityWindowChangeCallbacks = []; + this._windowTypeStatusChangeCallbacks = []; + this._peerIdAndFactoryIdToPeerType = {}; + this._peerFactoriesRegisteredByUs = {}; + this._gw3Subscriptions = []; + this._contextSubscriptions = {}; + this._activityTypesInitiatedFromMe = {}; + this._config = config; + this._connection = config.connection; + this._logger = config.logger; + this._contexts = config.contexts; + this._windows = config.windows; + this._sessionJoinedPromise = new Promise((resolve) => { + this._sessionJoinedPromiseResolve = resolve; + }); + this._activityJoinedPromise = new Promise((resolve) => { + this._activityJoinedPromiseResolve = resolve; + }); + if (!this._config.activityId) { + this._activityJoinedPromiseResolve({}); + } + this._gw3Session = this._connection.domain("activity", ["joined", "initiated", "peer-created", "token"]); + if (typeof window !== "undefined") { + const glue42gd = (window).glue42gd; + if (glue42gd && glue42gd.activityInfo) { + if (typeof glue42gd.addRefreshHandler === "function") { + glue42gd.addRefreshHandler((success, error) => { + this._gw3Session + .send({ + type: "reload" + }) + .then((msg) => { + if (!msg.token) { + error("Expected gateway token for refreshing."); + return; + } + try { + glue42gd.setGWToken(msg.token); + } + catch (e) { + error(e.message || e); + return; + } + success(); + }, error); + }); + } + if (glue42gd && typeof glue42gd.addWillNavigateHandler === "function") { + glue42gd.addWillNavigateHandler((success, error) => { + this._gw3Session + .send({ + type: "reload" + }) + .then((msg) => { + if (!msg.token) { + error("Expected gateway token for refreshing."); + return; + } + try { + glue42gd.setGWToken(msg.token); + } + catch (e) { + error(e.message || e); + return; + } + success(); + }, error); + }); + } + } + } + } + get bridgeType() { + return "GW3"; + } + init() { + this.forwardActivityTypeMessagesToStatusEventHandlers(); + this.subscribe(gwMessageActivityCreated, this.handleActivityCreatedMessage); + this.subscribe(gwMessageActivityDestroyed, this.handleActivityDestroyedMessage); + this.forwardActivityMessagesToStatusEventHandlers(); + this.forwardActivityCreatedAndJoinedActivityToActivityWindowEventHandlers(); + this.forwardPeerFactoryMessagesToStatusEventHandlers(); + this.forwardPeerFactoryMessagesToPeerFactoryRequests(); + this.subscribe(gwMessagePeerFactoriesAdded, this.handlePeerFactoriesAdded); + this.subscribe(gwMessagePeerFactoriesRemoved, this.handlePeerFactoriesRemoved); + this.forwardActivityWindowMessagesToEventHandlers(); + this.subscribe(gwMessageDisposePeer, () => { + if (this._config.disposeRequestHandling === "dispose") { + this.dispose(); + return; + } + if (this._config.disposeRequestHandling === "exit") { + if (this._windows && typeof this._windows.my() !== "undefined") { + this._windows.my().close(); + return; + } + if (typeof window !== "undefined" && typeof (window).close === "function") { + window.close(); + return; + } + if (typeof process !== "undefined" && typeof (process).exit === "function") { + process.exit(); + return; + } + } + }); + this._gw3Session.onJoined(() => { + if (this._config.mode === "trackMyOnly" || + this._config.mode === "trackMyTypeAndInitiatedFromMe") { + this._sessionJoinedPromiseResolve(this); + } + else { + this._gw3Session + .send({ + type: "subscribe", + activity_types: (this._config.mode === "trackAll" ? [] : + this._config.mode === "trackTypes" ? this._config.typesToTrack : []) + }) + .then(() => { + this._sessionJoinedPromiseResolve(this); + }); + } + }); + this._gw3Session.join(); + } + dispose() { + this._gw3Subscriptions.forEach((sub) => sub && this._connection.off(sub)); + this._gw3Subscriptions.length = 0; + } + ready() { + return Promise.all([this._sessionJoinedPromise, this._activityJoinedPromise]); + } + initReady() { + return this._sessionJoinedPromise; + } + onActivityTypeStatusChange(callback) { + this._activityTypeStatusChangeCallbacks.push(callback); + } + registerActivityType(activityTypeName, ownerWindow, helperWindows, config, description) { + const entity = {}; + entity.name = activityTypeName; + const toActivityPeerConfig = (windowDefinition) => ({ type: windowDefinition.type, name: windowDefinition.name, configuration: windowDefinition }); + entity.owner_type = toActivityPeerConfig(ownerWindow); + entity.helper_types = helperWindows.map(toActivityPeerConfig); + return this._gw3Session + .send({ + type: gwMessageAddActivityTypes, + types: [entity] + }) + .then(() => { + const activityType = GW3Bridge.activityTypeGwMessageEntityToActivityType(entity, description); + this.invokeCallbacks(this._activityTypeStatusChangeCallbacks, new EntityEvent(activityType, new EntityEventContext(EntityEventType.Added)), gwMessageAddActivityTypes); + return activityType; + }); + } + unregisterActivityType(activityTypeName) { + return this._gw3Session + .send({ + type: gwMessageRemoveActivityTypes, + types: [activityTypeName] + }) + .then(() => { + const activityType = new ActivityType(activityTypeName, undefined, undefined, undefined); + this.invokeCallbacks(this._activityTypeStatusChangeCallbacks, new EntityEvent(activityType, new EntityEventContext(EntityEventType.Removed)), gwMessageAddActivityTypes); + }); + } + onWindowTypeStatusChange(callback) { + this._windowTypeStatusChangeCallbacks.push(callback); + } + registerWindowFactory(windowType, factory, parameters) { + if (this._peerFactoriesRegisteredByUs[windowType]) { + return Promise.reject(new Error(`Factory for windowType ${windowType} already registered.`)); + } + this._peerFactoriesRegisteredByUs[windowType] = factory; + const entity = { + id: windowType, + peer_type: windowType, + configuration: parameters + }; + return this._gw3Session.send({ + type: gwMessageAddPeerFactories, + factories: [entity] + }) + .then(() => { + this.invokeCallbacks(this._windowTypeStatusChangeCallbacks, new EntityEvent(GW3Bridge.peerFactoryGwMessageEntityToWindowType(entity), new EntityEventContext(EntityEventType.Added)), gwMessageAddPeerFactories); + }) + .catch(() => { + delete this._peerFactoriesRegisteredByUs[windowType]; + }); + } + unregisterWindowFactory(windowType) { + const factory = this._peerFactoriesRegisteredByUs[windowType]; + if (!factory) { + return Promise.reject(new Error(`Factory for windowType ${windowType} not registered.`)); + } + delete this._peerFactoriesRegisteredByUs[windowType]; + return this._gw3Session.send({ + type: gwMessageRemovePeerFactories, + factory_ids: [windowType] + }).then(() => { + this.invokeCallbacks(this._windowTypeStatusChangeCallbacks, new EntityEvent(new WindowType(windowType, undefined), new EntityEventContext(EntityEventType.Removed)), gwMessageAddPeerFactories); + }); + } + onActivityStatusChange(callback) { + this._activityChangeCallbacks.push(callback); + } + initiateActivity(activityType, context, configuration) { + const initiateMsg = { + type: gwMessageCreateActivity, + activity_type: activityType, + initial_context: context, + }; + if (this.isOverrideTypeDefinition(configuration)) { + initiateMsg.types_override = { + owner_type: { type: configuration.owner.type, name: configuration.owner.name, configuration: configuration.owner }, + helper_types: configuration.helpers && configuration.helpers.map((wd) => ({ type: wd.type, name: wd.name, configuration: wd })) + }; + } + else { + initiateMsg.configuration = configuration && configuration.map((wd) => ({ type: wd.type, name: wd.name, configuration: wd })); + } + return this.sendCreateAndMapResultingMessagesToPromise(initiateMsg, gwMessageActivityInitiated, (msg, requestId) => msg.request_id === requestId, gwMessageActivityCreated, (msg, requestId, initMsg) => msg.activity_id === initMsg.activity_id, gwMessageActivityDestroyed, (msg, requestId, initMsg) => msg.activity_id === initMsg.activity_id, (msg) => msg.activity_id, null).then((id) => { + if (this._config.mode === "trackMyTypeAndInitiatedFromMe") { + if (!this._activityTypesInitiatedFromMe[activityType]) { + this._activityTypesInitiatedFromMe[activityType] = true; + return this._gw3Session + .send({ + type: "subscribe", + activity_types: [activityType] + }) + .then(() => { + return id; + }); + } + } + return id; + }); + } + stopActivity(activity) { + return this._gw3Session.send({ + type: gwMessageDestroyActivity, + activity_id: activity.id, + reason_uri: "com.tick42.glue.activity.constants.destroyReason.general", + reason: "Destroying activity" + }).then((_) => true); + } + updateActivityContext(activity, context, fullReplace, removedKeys) { + if (fullReplace) { + return this._contexts.set(activity.id, context); + } + else { + removedKeys = removedKeys || []; + for (const x of removedKeys) { + context[x] = null; + } + return this._contexts.update(activity.id, context); + } + } + announceWindow(windowType, activityWindowId) { + throw new Error("Invalid operation 'announceWindow' for GW3 protocol"); + } + registerWindow(type, name, independent) { + let shouldSendReady = typeof this._connection.gatewayToken !== "undefined"; + const peerId = this._connection.peerId; + if (typeof window !== "undefined") { + const glue42gd = window.glue42gd; + if (glue42gd) { + shouldSendReady = typeof glue42gd.activityInfo !== "undefined"; + } + } + if (shouldSendReady) { + this._gw3Session.send({ + type: gwMessageReady, + }); + } + this.invokeCallbacks(this._activityWindowChangeCallbacks, new EntityEvent(new ActivityWindow(peerId, name, type, undefined, this.getAgmInstance(peerId), independent, this.generateWindowGetter(peerId), undefined), new EntityEventContext(EntityEventType.Added)), "register window"); + return Promise.resolve(peerId); + } + onActivityWindowChange(callback) { + this._activityWindowChangeCallbacks.push(callback); + } + createWindow(activityId, windowDefinition) { + if (!windowDefinition.layout) { + if (windowDefinition.left || windowDefinition.width || windowDefinition.height || windowDefinition.top) { + windowDefinition.layout = { + mode: "pixels", + cellSize: 1, + }; + } + } + const joinPeer = (id) => { + if (!activityId) { + return; + } + return this.joinActivity(activityId, id, windowDefinition.name) + .then(() => { + return id; + }); + }; + return this.sendCreateAndMapResultingMessagesToPromise({ + type: gwMessageCreatePeer, + peer_type: windowDefinition.type, + peer_name: windowDefinition.name || windowDefinition.type, + configuration: windowDefinition, + activity_id: activityId, + }, undefined, undefined, gwMessagePeerCreated, (msg, requestId) => msg.request_id === requestId, undefined, undefined, (msg) => msg.created_id, joinPeer) + .then(joinPeer); + } + async closeWindow(id) { + await this._gw3Session.send({ + type: gwMessageDestroyPeer, + destroy_peer_id: id + }); + } + getAnnouncementInfo() { + let activityId = this._config.activityId || (this._config.announcementInfo && this._config.announcementInfo.activityId); + let activityWindowType = (this._config.announcementInfo && this._config.announcementInfo.activityWindowType); + let activityWindowIndependent = (this._config.announcementInfo && this._config.announcementInfo.activityWindowIndependent); + let activityWindowName = (this._config.announcementInfo && this._config.announcementInfo.activityWindowName); + if (typeof window !== "undefined" && + typeof window.location !== "undefined" && + window.location.search && + typeof URLSearchParams === "function") { + const searchParams = new URLSearchParams(location.search.slice(1)); + activityWindowType = activityWindowType || searchParams.get("t42PeerType"); + activityWindowType = activityWindowType || searchParams.get("t42ActivityWindowType"); + if (typeof activityWindowIndependent === "undefined") { + activityWindowIndependent = searchParams.get("t42ActivityWindowIndependent"); + } + activityWindowName = activityWindowName || searchParams.get("t42ActivityWindowName"); + activityId = activityId || searchParams.get("t42ActivityId"); + } + activityWindowType = activityWindowType || "unknown"; + activityWindowIndependent = activityWindowIndependent || false; + activityWindowName = activityWindowName || this._connection.peerId; + return { + activityWindowId: undefined, + activityId, + activityWindowType, + activityWindowIndependent, + activityWindowName, + }; + } + joinActivity(activityId, windowId, name) { + const maybeName = (name && { name }) || {}; + return this._gw3Session.send({ + type: gwMmessageJoinActivity, + target_id: windowId, + activity_id: activityId, + ...maybeName + }).then(() => { + this.invokeCallbacks(this._activityWindowChangeCallbacks, new EntityEvent(new ActivityWindow(windowId, undefined, undefined, activityId, this.getAgmInstance(windowId), undefined, this.generateWindowGetter(windowId), undefined), new EntityEventContext(EntityEventType.ActivityWindowJoinedActivity)), "activity joined - ActivityWindow"); + this.invokeCallbacks(this._activityChangeCallbacks, new EntityEvent(new Activity(activityId, undefined, new ActivityStatus("created", undefined, undefined), undefined, undefined), new EntityEventContext(EntityEventType.Updated)), "activity joined - Activity"); + }); + } + leaveActivity(activityId, windowId) { + return this._gw3Session.send({ + type: gwMessageLeaveActivity, + target_id: windowId, + activity_id: activityId + }).then(() => { + this.invokeCallbacks(this._activityWindowChangeCallbacks, new EntityEvent(new ActivityWindow(windowId, undefined, undefined, null, this.getAgmInstance(windowId), undefined, this.generateWindowGetter(windowId), undefined), new EntityEventContext(EntityEventType.ActivityWindowLeftActivity)), "activity left - ActivityWindow"); + this.invokeCallbacks(this._activityChangeCallbacks, new EntityEvent(new Activity(activityId, undefined, new ActivityStatus("created", undefined, undefined), undefined, undefined), new EntityEventContext(EntityEventType.Updated)), "activity left - Activity"); + }); + } + getActivityTypes() { + return Promise.resolve([]); + } + getWindowTypes() { + return Promise.resolve([]); + } + getActivities() { + return Promise.resolve([]); + } + getActivityWindows() { + return Promise.resolve([]); + } + createStackedWindows(id, windowDefinitions, timeout) { + return undefined; + } + getWindowBounds(id) { + return undefined; + } + setWindowBounds(id, bounds) { + return undefined; + } + activateWindow(id, focus) { + return undefined; + } + setWindowVisibility(id, visible) { + return undefined; + } + cloneActivity(id, cloneOptions) { + return undefined; + } + attachActivities(from, to, tag) { + return this._gw3Session.send({ + type: gwNmessageMergeActivities, + into: to, + merge: from + }); + } + detachActivities(activityId, newActivityInfo) { + return this._gw3Session.send({ + type: gwMessageSplitActivities, + from: activityId, + }).then(() => ""); + } + onActivitiesAttached(callback) { + } + onActivitiesDetached(callback) { + } + onActivityAttachedDescriptorsRefreshed(callback) { + } + getAttachedDescriptors() { + return Promise.resolve([]); + } + getRandomRequestId() { + return this._connection.peerId + ":" + Math.floor(Math.random() * 1e9) + ""; + } + forwardAddedAndRemovedMessagesToEventHandler(addedMessageType, removedMessageType, mapper, handlers) { + const getGetEntityEvent = (isAdded) => (entity) => new EntityEvent(entity, new EntityEventContext(isAdded ? + EntityEventType.Added : + EntityEventType.Removed)); + const sub1 = addedMessageType && this.forwardMessageToEventHandler(addedMessageType, (msg) => mapper(msg, true), getGetEntityEvent(true), handlers); + const sub2 = removedMessageType && this.forwardMessageToEventHandler(removedMessageType, (msg) => mapper(msg, false), getGetEntityEvent(false), handlers); + return [sub1, sub2].filter((x) => x); + } + forwardMessageToEventHandler(messageType, mapper, getEntityEvent, handler) { + return this.subscribe(messageType, (msg) => { + mapper(msg) + .forEach((ent) => handler.forEach((h) => h(getEntityEvent(ent, msg)))); + }); + } + sendCreateAndMapResultingMessagesToPromise(msg, initiatedMessageType, initiatedMessageFilter, createdMessageType, createdMessageFilter, cancelledMessageType, cancelledMessageFilter, createdMessageToPromiseResolution, listenForRecreates) { + const reqId = this.getRandomRequestId(); + let resolveCreatedPromise; + let rejectCreatedPromise; + const createdPromise = new Promise((resolve, reject) => { + resolveCreatedPromise = resolve; + rejectCreatedPromise = reject; + }); + let initiatedMessageAck = null; + let initiatedSubscription; + let createdSubscription; + let cancelledSubscription; + let errorSubscription; + const dropSubscriptions = () => { + this.dropSubscription(initiatedSubscription); + if (!listenForRecreates) { + this.dropSubscription(createdSubscription); + } + this.dropSubscription(cancelledSubscription); + this.dropSubscription(errorSubscription); + }; + initiatedSubscription = initiatedMessageType && + this.subscribe(initiatedMessageType, (msg4) => { + if (!initiatedMessageFilter(msg4, reqId)) { + return; + } + initiatedMessageAck = msg4; + this.dropSubscription(initiatedSubscription); + }); + let recreated = false; + createdSubscription = + this.subscribe(createdMessageType, (msg1) => { + if (!createdMessageFilter(msg1, reqId, initiatedMessageAck)) { + return; + } + if (recreated) { + if (listenForRecreates) { + listenForRecreates(createdMessageToPromiseResolution(msg1)); + } + } + else { + recreated = true; + resolveCreatedPromise(createdMessageToPromiseResolution(msg1)); + } + }); + cancelledSubscription = cancelledMessageType && + this.subscribe(cancelledMessageType, (msg2) => { + if (!cancelledMessageFilter(msg2, reqId, initiatedMessageAck)) { + return; + } + rejectCreatedPromise(msg2); + }); + errorSubscription = cancelledMessageType && + this.subscribe(gwMmessageError, (msg3) => { + if (msg3.request_id !== reqId) { + return; + } + rejectCreatedPromise(msg3); + }); + msg.request_id = reqId; + const toReturn = this._gw3Session + .send(msg) + .then(() => { + return createdPromise; + }); + toReturn.then(dropSubscriptions, dropSubscriptions); + return toReturn; + } + peerFactoryIdAndOwnerIdToWindowType(factoryId, ownerId) { + const peerType = this._peerIdAndFactoryIdToPeerType[ownerId + ":" + factoryId]; + if (!peerType) { + return null; + } + else { + return new WindowType(peerType, undefined); + } + } + subscribe(messageType, handler) { + const sub = this._connection.on(messageType, (msg) => handler.bind(this)(msg)); + this._gw3Subscriptions.push(sub); + return sub; + } + dropSubscription(subscription) { + if (subscription) { + this._connection.off(subscription); + delete this._gw3Subscriptions[this._gw3Subscriptions.indexOf(subscription)]; + } + } + invokeCallbacks(callbacks, event, description) { + callbacks.forEach((cb) => { + try { + cb(event); + } + catch (err) { + this._logger.error(`Error in ${description || event.context.type} callback: ` + JSON.stringify(err)); + } + }); + } + handleActivityCreatedMessage(msg) { + if (!msg.context_id) { + this._logger.error("Activity created with unknown context_id: " + msg.activity_id); + } + else { + if (!this._contextSubscriptions[msg.activity_id]) { + this.subscribeToContext(msg); + } + } + } + async subscribeToContext(msg) { + const activityId = msg.activity_id; + this._contextSubscriptions[activityId] = + await this._contexts.subscribe(activityId, (data, updated, removed) => { + const event = new EntityEvent(new Activity(activityId, undefined, undefined, data, undefined), new ActivityContextChangedEventContext(data, updated, removed)); + this.invokeCallbacks(this._activityChangeCallbacks, event, "context updated"); + }); + } + handleActivityDestroyedMessage(msg) { + const unsubscribeContext = this._contextSubscriptions[msg.activity_id]; + if (typeof unsubscribeContext === "function") { + unsubscribeContext(); + } + delete this._contextSubscriptions[msg.activity_id]; + } + handlePeerFactoriesAdded(msg) { + msg.factories.forEach((entity) => { + this._peerIdAndFactoryIdToPeerType[msg.owner_id + ":" + entity.id] = entity.peer_type; + }); + } + handlePeerFactoriesRemoved(msg) { + msg.factory_ids.forEach((factoryId) => { + delete this._peerIdAndFactoryIdToPeerType[msg.owner_id + ":" + factoryId]; + }); + } + forwardActivityTypeMessagesToStatusEventHandlers() { + this.forwardAddedAndRemovedMessagesToEventHandler(gwMmessageActivityTypesAdded, gwMessageActivityTypesRemoved, (msg, isAdded) => isAdded + ? msg.types.map((t) => GW3Bridge.activityTypeGwMessageEntityToActivityType(t, undefined)) + : msg.types.map((t) => new ActivityType(t.name, undefined, undefined, undefined)), this._activityTypeStatusChangeCallbacks); + } + forwardActivityCreatedAndJoinedActivityToActivityWindowEventHandlers() { + for (const activityCreatedMessage of [gwMessageActivityCreated, gwMessageJoinedActivity, gwMessageOwnerChanged]) { + this.forwardMessageToEventHandler(activityCreatedMessage, (msg) => ([msg.owner || { ...msg, type: msg.peer_type, name: msg.peer_name, peer_id: msg.owner_id }]) + .concat(msg.participants || []) + .map((info) => new ActivityWindow(info.peer_id, info.name, info.type, msg.activity_id, this.getAgmInstance(info.peer_id), undefined, this.generateWindowGetter(info.peer_id), undefined)), (ent, msg) => new EntityEvent(ent, new EntityEventContext(EntityEventType.ActivityWindowJoinedActivity)), this._activityWindowChangeCallbacks); + } + } + forwardActivityMessagesToStatusEventHandlers() { + for (const createdMessage of [gwMessageActivityCreated, gwMessageJoinedActivity]) { + this.forwardMessageToEventHandler(createdMessage, (msg) => [GW3Bridge.activityGwMessageToActivity(msg, new ActivityStatus("started", "", new Date()))], (ent, msg) => GW3Bridge.activityToActivityStatusChangeEvent(ent), this._activityChangeCallbacks); + } + this.forwardMessageToEventHandler(gwMessageActivityDestroyed, (msg) => [GW3Bridge.activityGwMessageToActivity(msg, new ActivityStatus("destroyed", msg.reason, new Date()))], (ent, msg) => GW3Bridge.activityToActivityStatusChangeEvent(ent), this._activityChangeCallbacks); + this.forwardMessageToEventHandler(gwMessageActivityInitiated, (msg) => [GW3Bridge.activityGwMessageToActivity(msg, new ActivityStatus("created", "", new Date()))], (ent, msg) => GW3Bridge.activityToActivityStatusChangeEvent(ent), this._activityChangeCallbacks); + this.forwardMessageToEventHandler(gwMessageOwnerChanged, (msg) => [GW3Bridge.activityGwMessageToActivity(msg, new ActivityStatus("created", "", new Date()))], (ent, msg) => GW3Bridge.activityToActivityStatusChangeEvent(ent), this._activityChangeCallbacks); + } + forwardPeerFactoryMessagesToStatusEventHandlers() { + this.forwardAddedAndRemovedMessagesToEventHandler(gwMessagePeerFactoriesAdded, gwMessagePeerFactoriesRemoved, (msg, isAdded) => isAdded + ? msg.factories.map(GW3Bridge.peerFactoryGwMessageEntityToWindowType) + : msg.factory_ids.map((id) => this.peerFactoryIdAndOwnerIdToWindowType(id, msg.owner_id)).filter((x) => x != null), this._windowTypeStatusChangeCallbacks); + } + forwardPeerFactoryMessagesToPeerFactoryRequests() { + this.subscribe(gwMessagePeerRequested, (msg) => { + const factory = this._peerFactoriesRegisteredByUs[msg.peer_factory]; + if (!factory) { + this._gw3Session.send({ + type: gwMmessageError, + request_id: msg.request_id, + reason: `Unknown peer factory ${msg.peer_factory}` + }); + return; + } + try { + const configuration = msg.configuration || {}; + configuration.gateway_token = configuration.gateway_token || msg.gateway_token; + configuration.peer_factory = configuration.peer_factory || msg.peer_factory; + const promise = factory({ + activityId: msg.activity && msg.activity.id, + activityType: msg.activity && msg.activity.type, + type: msg.configuration && msg.configuration.type, + gwToken: configuration.gateway_token, + configuration + }); + if (promise && promise.then && promise.catch) { + promise.catch((err) => this._gw3Session.send({ + type: gwMmessageError, + request_id: msg.request_id, + reason: err && (err.message || JSON.stringify(err)) + })); + } + } + catch (err) { + this._gw3Session.send({ + type: gwMmessageError, + request_id: msg.request_id, + reason: err && (err.message || JSON.stringify(err)) + }); + } + }); + } + forwardActivityWindowMessagesToEventHandlers() { + for (const joinedMessage of [gwMessageActivityJoined, gwMessageJoinedActivity]) { + this.subscribe(joinedMessage, (msg) => { + const joinedId = (joinedMessage === gwMessageActivityJoined) ? msg.joined_id : msg.peer_id; + const joinedType = (joinedMessage === gwMessageActivityJoined) ? msg.joined_type : msg.peer_type; + const joinedName = (joinedMessage === gwMessageActivityJoined) ? msg.joined_name : msg.peer_name; + const entity = new ActivityWindow(joinedId, joinedName, joinedType, msg.activity_id, this.getAgmInstance(joinedId), undefined, this.generateWindowGetter(joinedId), undefined); + if (!this._contextSubscriptions[msg.activity_id]) { + this.subscribeToContext(msg).then(() => { + if (joinedMessage === gwMessageJoinedActivity) { + this._activityJoinedPromiseResolve({}); + } + }); + } + else if (joinedMessage === gwMessageJoinedActivity) { + this._activityJoinedPromiseResolve({}); + } + this.invokeCallbacks(this._activityWindowChangeCallbacks, new EntityEvent(entity, new EntityEventContext(EntityEventType.ActivityWindowJoinedActivity)), joinedMessage); + }); + } + this.subscribe(gwMessageActivityLeft, (msg) => { + const entity = new ActivityWindow(msg.left_id, undefined, undefined, null, this.getAgmInstance(msg.left_id), undefined, this.generateWindowGetter(msg.left_id), undefined); + this.invokeCallbacks(this._activityWindowChangeCallbacks, new EntityEvent(entity, new EntityEventContext(EntityEventType.ActivityWindowLeftActivity)), gwMessageActivityLeft); + }); + this.forwardAddedAndRemovedMessagesToEventHandler(gwMessagePeerCreated, undefined, (msg) => [ + new ActivityWindow(msg.created_id, undefined, undefined, undefined, undefined, undefined, this.generateWindowGetter(msg.created_id), undefined) + ], this._activityWindowChangeCallbacks); + } + getAgmInstance(id) { + return this._config.agm.servers().find((s) => s.peerId === id || s.windowId === id); + } + generateWindowGetter(peerId) { + return () => { + const server = this.getAgmInstance(peerId); + if (!server) { + return; + } + const windowId = server.windowId; + return this._config.windows.list().filter((w) => w.id === windowId)[0]; + }; + } + isOverrideTypeDefinition(value) { + if (typeof value === "undefined") { + return false; + } + if (value.owner) { + return true; + } + return false; + } + } + + class ActivityMy { + constructor(manager, windows) { + this._myAttached = []; + this._myDetached = []; + this._myAttachedTo = []; + this._myDetachedFrom = []; + this._myActivityFrameColorChanged = []; + this._myActivityJoinedCallbacks = []; + this._myActivityRemovedCallbacks = []; + this._myContextUpdateCallbacks = []; + this._logger = Logger.Get(this); + this._m = manager; + manager.ready() + .then((am) => { + am.subscribeActivityContextChanged(this._subscribeMyContextChanged.bind(this)); + am.subscribeWindowEvents(this._subscribeMyWindowEvent.bind(this)); + am.subscribeActivitiesAttached(this._subscribeActivitiesAttached.bind(this)); + am.subscribeActivitiesDetached(this._subscribeActivitiesDetached.bind(this)); + if (windows) { + windows.onWindowFrameColorChanged(this._subscribeWindowFrameColorChanged.bind(this)); + } + }); + } + get window() { + if (isUndefinedOrNull(this._w)) { + const announcedWindows = this._m.announcedWindows; + if (announcedWindows.length > 0) { + this._w = announcedWindows[0]; + } + } + return this._w; + } + get activity() { + const myWin = this.window; + if (isUndefinedOrNull(myWin)) { + return undefined; + } + return myWin.activity; + } + createWindow(windowType) { + return this._m.createWindow(this.activity, windowType); + } + createStackedWindows(windowTypes, timeout) { + return this._m.createStackedWindows(this.activity, windowTypes, timeout); + } + get context() { + const activity = this.activity; + if (isUndefined(activity)) { + return {}; + } + return activity.context; + } + updateContext(context, callback) { + const activity = this.activity; + if (isUndefined(activity)) { + return new Promise((resolve, reject) => { + reject("Not in activity"); + }); + } + return activity.updateContext(context, callback); + } + setContext(context, callback) { + const activity = this.activity; + if (isUndefined(activity)) { + return new Promise((resolve, reject) => { + reject("Not in activity"); + }); + } + return activity.setContext(context, callback); + } + onActivityJoined(callback) { + this._myActivityJoinedCallbacks.push(callback); + const myWin = this.window; + if (!isUndefinedOrNull(myWin) && !isUndefinedOrNull(myWin.activity)) { + callback(myWin.activity); + } + } + onActivityLeft(callback) { + this._myActivityRemovedCallbacks.push(callback); + } + onContextChanged(callback) { + this._myContextUpdateCallbacks.push(callback); + const myWin = this.window; + if (isUndefinedOrNull(myWin)) { + return; + } + const activity = myWin.activity; + if (isUndefinedOrNull(activity)) { + return; + } + callback(activity.context, activity.context, [], activity); + } + clone(options, callback) { + const act = this.activity; + return this._m.clone(act, options, callback); + } + attach(activity, tag) { + let activityId; + if (typeof activity === "string") { + activityId = activity; + } + else { + activityId = activity.id; + } + return this._m.attachActivities(activityId, this.activity.id, tag); + } + onActivityAttached(callback) { + this._myAttached.push(callback); + } + onActivityDetached(callback) { + this._myDetached.push(callback); + } + onAttachedToActivity(callback) { + this._myAttachedTo.push(callback); + } + onDetachedFromActivity(callback) { + this._myDetachedFrom.push(callback); + } + get attached() { + if (!this.activity) { + return []; + } + return this.activity.attached; + } + setFrameColor(color, callback) { + if (this.activity) { + return this.activity.setFrameColor(color, callback); + } + else { + return Promise.resolve(null); + } + } + getFrameColor() { + if (this.activity) { + return this.activity.getFrameColor(); + } + return ""; + } + onFrameColorChanged(callback) { + this._myActivityFrameColorChanged.push(callback); + } + _subscribeMyContextChanged(activity, context, delta, removed) { + const myWin = this.window; + if (isUndefinedOrNull(myWin)) { + return; + } + const myActivity = myWin.activity; + if (isUndefinedOrNull(myActivity)) { + return; + } + if (activity.id !== myActivity.id) { + return; + } + this._notifyMyContextChanged(activity, context, delta, removed); + } + _subscribeMyWindowEvent(activity, window, event) { + if (isUndefinedOrNull(this.window)) { + return; + } + if (this.window.id !== window.id) { + return; + } + if (event === EntityEventType.ActivityWindowJoinedActivity) { + this._notifyMyWindowEvent(activity, this._myActivityJoinedCallbacks); + this._notifyMyContextChanged(activity, activity.context, null, null); + } + else if (event === EntityEventType.ActivityWindowLeftActivity) { + this._notifyMyWindowEvent(activity, this._myActivityRemovedCallbacks); + } + } + _notifyMyWindowEvent(activity, callbackStore) { + callbackStore.forEach((element) => { + try { + element(activity, event); + } + catch (e) { + this._logger.warn("error in user callback " + e); + } + }); + } + _notifyMyContextChanged(activity, context, delta, removed) { + delta = delta || {}; + removed = removed || []; + this._myContextUpdateCallbacks.forEach((element) => { + try { + element(context, delta, removed, activity); + } + catch (e) { + this._logger.warn("error in user callback " + e); + } + }); + } + _notifyAttached(state) { + this._myAttached.forEach((cb) => { + try { + cb(state); + } + catch (e) { + this._logger.warn("error in user callback " + e); + } + }); + } + _notifyDetached(state) { + this._myDetached.forEach((cb) => { + try { + cb(state); + } + catch (e) { + this._logger.warn("error in user callback " + e); + } + }); + } + _notifyAttachedTo(state) { + this._myAttachedTo.forEach((cb) => { + try { + cb(this.activity, state); + } + catch (e) { + this._logger.warn("error in user callback " + e); + } + }); + } + _notifyDetachedFrom(detached, existing, state) { + this._myDetachedFrom.forEach((cb) => { + try { + cb(detached, existing, state); + } + catch (e) { + this._logger.warn("error in user callback " + e); + } + }); + } + _subscribeActivitiesAttached(newAct, state) { + const myWin = this.window; + if (isUndefinedOrNull(myWin)) { + return; + } + const myActivity = myWin.activity; + if (isUndefinedOrNull(myActivity)) { + return; + } + if (newAct.id !== myActivity.id) { + return; + } + if (state.windowIds.indexOf(myWin.id) >= 0) { + this._notifyAttachedTo(state); + return; + } + this._notifyAttached(state); + } + _subscribeActivitiesDetached(newAct, oldAct, state) { + const myWin = this.window; + if (isUndefinedOrNull(myWin)) { + return; + } + const myActivity = myWin.activity; + if (isUndefinedOrNull(myActivity)) { + return; + } + if (oldAct.id === myActivity.id) { + this._notifyDetached(state); + } + if (newAct.id === myActivity.id) { + this._notifyDetachedFrom(newAct, oldAct, state); + } + } + _subscribeWindowFrameColorChanged(window) { + const act = this.activity; + if (!act) { + return; + } + if (!act.owner) { + return; + } + if (act.owner.underlyingWindow.id === window.id) { + this._myActivityFrameColorChanged.forEach((callback) => { + callback(window.frameColor); + }); + } + } + } + + class ReadyMarker { + constructor(name, signalsToWait) { + this._logger = Logger.Get("ReadyMarker [" + name + "]"); + this._logger.debug("Initializing ready marker for '" + name + "' with " + signalsToWait + " signals to wait"); + if (signalsToWait <= 0) { + throw new Error("Invalid signal number. Should be > 0"); + } + this._signals = signalsToWait; + this._callbacks = []; + this._name = name; + } + setCallback(callback) { + if (this.isSet()) { + callback(undefined); + return; + } + else if (this.isError()) { + callback(this._error); + return; + } + this._callbacks.push(callback); + } + signal(message) { + this._logger.debug("Signaled - " + message + " - signals left " + (this._signals - 1)); + this._signals--; + if (this._signals < 0) { + throw new Error("Error in ready marker '" + this._name + " - signals are " + this._signals); + } + if (this.isSet()) { + this._callbacks.forEach((callback) => { + callback(undefined); + }); + } + } + error(error) { + this._error = error; + this._callbacks.forEach((errorCallback) => { + errorCallback(error); + }); + } + isSet() { + if (this.isError()) { + return false; + } + return this._signals === 0; + } + isError() { + return !isUndefined(this._error); + } + getError() { + return this._error; + } + } + + class EntityObservableCollection { + constructor(processNew) { + this._items = {}; + this._listeners = []; + this._processNew = processNew; + } + addOne(item) { + this.add([item]); + } + add(items) { + items.forEach((element) => { + this.process(new EntityEvent(element, new EntityEventContext(EntityEventType.Added))); + }); + } + process(event) { + const context = event.context; + const type = context.type; + const entity = event.entity; + if (type === EntityEventType.StatusChange && + !context.oldStatus) { + const act = this._items[entity.id]; + if (act) { + context.oldStatus = act.status; + } + } + if (type === EntityEventType.StatusChange && + context.oldStatus && + context.newStatus && + context.oldStatus.state === + context.newStatus.state) { + context.type = EntityEventType.Updated; + } + if (typeof htmlContainer === "undefined") { + if (type === EntityEventType.ActivityWindowJoinedActivity && + this._items[entity.id] && + this._items[entity.id].activity) { + context.type = EntityEventType.Updated; + } + if (type === EntityEventType.ActivityWindowLeftActivity && + this._items[entity.id] && + !this._items[entity.id].activity) { + context.type = EntityEventType.Updated; + } + } + const internalEntity = this._updateInternalCollections(entity, type, context); + this._notifyListeners(internalEntity, context); + return internalEntity; + } + get() { + const result = []; + for (const key in this._items) { + if (this._items.hasOwnProperty(key)) { + const element = this._items[key]; + result.push(element); + } + } + return result; + } + getByName(name) { + for (const key in this._items) { + if (key === name) { + return this._items[key]; + } + } + return undefined; + } + getOrWait(name) { + return new Promise((resolve) => { + const entityAddedHandler = (entity) => { + if (entity.id !== name) { + return; + } + resolve(entity); + this.unsubscribe(entityAddedHandler); + }; + this.subscribe(entityAddedHandler); + const window = this.getByName(name); + if (window) { + this.unsubscribe(entityAddedHandler); + resolve(window); + return; + } + }); + } + subscribe(handler) { + this._listeners.push(handler); + Object.keys(this._items).forEach((key) => { + const element = this._items[key]; + handler(element, new EntityEventContext(EntityEventType.Added.toString())); + }); + return () => { + this.unsubscribe(handler); + }; + } + unsubscribe(handler) { + const index = this._listeners.indexOf(handler); + if (index !== -1) { + this._listeners.splice(index, 1); + } + } + _notifyListeners(entity, context) { + this._listeners.forEach((listener) => { + try { + listener(entity, context); + } + catch (e) { + return; + } + }); + } + _updateInternalCollections(entity, type, context) { + const entityAsAny = entity; + const isActivityDestroy = (type === EntityEventType.StatusChange && + entityAsAny.status && + entityAsAny.status.state === ActivityState.Destroyed) || + (type === EntityEventType.StatusChange && + context && + context.newStatus && + context.newStatus.state === ActivityState.Destroyed); + const isWindowClose = type === EntityEventType.Closed; + const isTypeRemove = type === EntityEventType.Removed && typeof entityAsAny.isIndependent === "undefined"; + if (isTypeRemove || isWindowClose || isActivityDestroy) { + const oldEntity = this._items[entity.id]; + delete this._items[entity.id]; + this._processNew(entity); + if (oldEntity) { + entity._beforeDelete(oldEntity); + } + return entity; + } + else { + const key = entity.id; + if (!this._items.hasOwnProperty(key)) { + this._processNew(entity); + this._items[entity.id] = entity; + } + else { + this._items[entity.id]._update(entity); + } + } + return this._items[entity.id]; + } + } + + class ActivityManager { + get usingHc() { + return this._bridge.bridgeType === "HC"; + } + get announcedWindows() { + return this._announcedWindows; + } + set announcedWindows(v) { + throw new Error("not allowed"); + } + constructor(bridge, autoAnnounce, windows) { + this._logger = Logger.Get("activityManager"); + this._announcedWindows = []; + this._attachedCallbacks = []; + this._detachedCallbacks = []; + this._frameColorChangesCallbacks = []; + this._windowHandlers = []; + this._bridge = bridge; + this._activityTypes = new EntityObservableCollection((e) => this._grabEntity(e)); + this._windowTypes = new EntityObservableCollection((e) => this._grabEntity(e)); + this._activities = new EntityObservableCollection((e) => this._grabEntity(e)); + this._windows = new EntityObservableCollection((e) => this._grabEntity(e)); + this._dataReadyMarker = new ReadyMarker("Activity Manager Data", ["GetActivityTypes", "GetWindowTypes", "GetActivities", "GetWindows"].length); + this._descriptorsMarker = new ReadyMarker("Attached Activities Descriptors", ["GetDescriptors"].length); + if (autoAnnounce) { + this._readyMarker = new ReadyMarker("Activity Manager Announce", ["Announcement"].length); + this._dataReadyMarker.setCallback((dataErr) => { + if (dataErr) { + this._readyMarker.error(dataErr); + } + this._descriptorsMarker.setCallback((err) => { + if (err) { + this._readyMarker.error(err); + } + this._logger.debug("Auto announcing window"); + this.announceWindow() + .then((w) => { + this._announcedWindows.push(w); + this._readyMarker.signal("Successfully announced window with id '" + w.id + "'"); + }) + .catch((errCatch) => { + this._logger.debug("Will not announce window - " + errCatch); + this._readyMarker.signal(); + }); + }); + this.refreshDescriptors(); + }); + } + else { + this._readyMarker = this._dataReadyMarker; + } + this._bridge.onActivitiesAttached((e) => { + this._handleActivitiesAttached(e); + }); + this._bridge.onActivitiesDetached((e) => { + this._handleActivitiesDetached(e); + }); + this._bridge.onActivityAttachedDescriptorsRefreshed((e) => { + this._handleActivityDescriptorsRefreshed(e); + }); + if (windows) { + windows.onWindowFrameColorChanged(this._handleWindowFrameColorChanged.bind(this)); + } + this._bridge.init(); + this._subscribeForData(); + this._bridge + .initReady() + .then((aw) => { + this._getInitialData(); + }) + .catch((error) => { + console.log(error); + }); + } + ready(callback) { + const promise = new Promise((resolve, reject) => { + this._readyMarker.setCallback((err) => { + if (!err) { + resolve(this); + } + else { + reject(this._readyMarker.getError()); + } + }); + }); + return nodeify(Promise.all([this._bridge.ready(), promise]).then(() => this), callback); + } + getActivityTypes() { + return this._activityTypes.get(); + } + getActivityType(name) { + return this._activityTypes.getByName(name); + } + registerActivityType(activityTypeName, ownerWindowType, helperWindowTypes, config, description, callback) { + const promise = new Promise((resolve, reject) => { + if (isUndefinedOrNull(activityTypeName)) { + reject("activityTypeName argument can not be undefined"); + return; + } + if (!isString(activityTypeName)) { + reject("activityTypeName should be string"); + return; + } + const actType = this.getActivityType(activityTypeName); + if (!isUndefinedOrNull(actType)) { + reject("Activity type '" + activityTypeName + "' already exists"); + return; + } + let ownerDefinition; + if (isUndefined(ownerWindowType)) { + reject("Owner window type can not be undefined"); + return; + } + if (isString(ownerWindowType)) { + ownerDefinition = { type: (ownerWindowType), name: "", isIndependent: false, arguments: {} }; + } + else { + ownerDefinition = (ownerWindowType); + } + const helperDefinitions = []; + if (!isUndefined(helperWindowTypes) && isArray(helperWindowTypes)) { + for (const index in helperWindowTypes) { + const item = helperWindowTypes[index]; + if (isString(item)) { + const definition = { + type: (item), + name: "", + isIndependent: false, + arguments: {}, + relativeTo: "", + relativeDirection: "", + windowStyleAttributes: {} + }; + helperDefinitions.push(definition); + } + else { + helperDefinitions.push(item); + } + } + } + this._bridge + .registerActivityType(activityTypeName, ownerDefinition, helperDefinitions, config, description) + .then((activityType) => { + this._grabEntity(activityType); + resolve(activityType); + }) + .catch((error) => { + reject(error); + }); + }); + return nodeify(promise, callback); + } + unregisterActivityType(type, callback) { + const promise = new Promise((resolve, reject) => { + const actType = this.getActivityType(type); + if (isUndefined(actType)) { + reject("Activity type '" + type + "' does not exists"); + return; + } + this._bridge.unregisterActivityType(type).then(() => resolve(actType), reject); + }); + return nodeify(promise, callback); + } + initiate(activityType, context, callback, configuration) { + const promise = new Promise((resolve, reject) => { + const actType = this.getActivityType(activityType); + if (isUndefined(actType)) { + reject("Activity type '" + activityType + "' does not exists"); + return; + } + this._bridge + .initiateActivity(activityType, context, configuration) + .then((actId) => { + this._activities + .getOrWait(actId) + .then((act) => { + resolve(act); + }) + .catch((err) => reject(err)); + }) + .catch((err) => { + reject(err); + }); + }); + return nodeify(promise, callback); + } + subscribeActivityTypeEvents(handler) { + this._activityTypes.subscribe((at, context) => { + handler(at, context.type); + }); + } + getWindowTypes() { + return this._windowTypes.get(); + } + getWindowType(name) { + return this._windowTypes.getByName(name); + } + registerWindowFactory(windowType, factoryMethod, callback) { + const promise = new Promise((resolve, reject) => { + if (isUndefinedOrNull(windowType)) { + reject("no windowType specified"); + return; + } + if (isObject(windowType)) { + windowType = windowType.getName(); + } + else if (!isString(windowType)) { + reject("windowType should be string or object that has getName method"); + return; + } + this._bridge + .registerWindowFactory(windowType, factoryMethod) + .then((v) => { + resolve(v); + }) + .catch((err) => { + reject(err); + }); + }); + return nodeify(promise, callback); + } + unregisterWindowFactory(windowType, callback) { + const promise = new Promise((resolve, reject) => { + if (isUndefinedOrNull(windowType)) { + reject("no windowType specified"); + return; + } + if (!isString(windowType)) { + reject("windowType should be a string"); + return; + } + this._bridge + .unregisterWindowFactory(windowType) + .then((v) => { + resolve(v); + }) + .catch((err) => { + reject(err); + }); + }); + return nodeify(promise, callback); + } + getActivities(activityType) { + let act = this._activities.get(); + act = act.filter((a) => a._ownerId); + if (!activityType) { + return act; + } + let types = activityType; + if (isString(activityType)) { + types = [activityType]; + } + else if (activityType instanceof ActivityType) { + types = [activityType.name]; + } + else if (activityType instanceof Array) ; + else { + throw new Error("Invalid input argument 'activityType' = " + activityType); + } + return act.filter((at) => { + const type = at.type; + return some(types, (t) => { + return type.id === t.id; + }); + }); + } + getActivityById(id) { + return this._activities.getByName(id); + } + announceWindow(activityWindowId, windowType) { + const promise = new Promise((resolve, reject) => { + const announcementInfo = this._bridge.getAnnouncementInfo(); + if (isUndefined(activityWindowId)) { + activityWindowId = announcementInfo.activityWindowId; + } + if (isUndefined(windowType)) { + windowType = announcementInfo.activityWindowType; + } + if (isUndefinedOrNull(windowType)) { + throw new Error("Can not announce - unknown windowType"); + } + const activityId = announcementInfo && announcementInfo.activityId; + if (isUndefinedOrNull(activityWindowId)) { + this._logger.debug("Registering window with type:'" + windowType + "', name:'" + announcementInfo.activityWindowName + "', ind.:'" + announcementInfo.activityWindowIndependent + "'"); + this._bridge.registerWindow(windowType, announcementInfo.activityWindowName, announcementInfo.activityWindowIndependent) + .then(this._windows.getOrWait.bind(this._windows)) + .then((w) => { + if (activityId) { + return this._activities.getOrWait(activityId).then((_) => w); + } + else { + return w; + } + }) + .then((w) => { + resolve(w); + }) + .catch((err) => { + this._logger.error(err); + }); + } + else { + this._logger.debug("Announcing window with id '" + activityWindowId + "' and type '" + windowType + "'"); + const currentWindow = this._windows.getByName(activityWindowId); + if (!isUndefinedOrNull(currentWindow)) { + this._logger.debug("Window with id '" + activityWindowId + "' already announced - reusing the window"); + resolve(currentWindow); + return; + } + const windowEventHandler = (a, w, e) => { + if (activityWindowId === w.id) { + if (e === EntityEventType.ActivityWindowJoinedActivity) { + const activity = w.activity; + if (isUndefined(activity)) { + reject("UNDEFINED ACTIVITY"); + } + this._logger.trace("Got joined event for id '" + activityWindowId + "'"); + resolve(w); + this.unsubscribeWindowEvents(windowEventHandler); + } + } + }; + this.subscribeWindowEvents(windowEventHandler); + this._logger.trace("Waiting for joined event for id '" + activityWindowId + "'"); + this._bridge.announceWindow(windowType, activityWindowId); + } + }); + return promise; + } + subscribeWindowTypeEvents(handler) { + this._windowTypes.subscribe((wt, context) => { + handler(wt, context.type); + }); + } + subscribeActivityEvents(handler) { + return this._activities.subscribe((act, context) => { + if (context.type === EntityEventType.StatusChange) { + const p = context; + handler(act, p.newStatus, p.oldStatus); + } + if (context.type === EntityEventType.Removed || + (context.type === EntityEventType.StatusChange && + context.newStatus.getState() === ActivityState.Destroyed)) { + for (const window of this._windows.get()) { + if (window.activity && window.activity.id === act.id) { + this._windows.process(new EntityEvent(window, new EntityEventContext(EntityEventType.ActivityWindowLeftActivity))); + } + } + } + }); + } + subscribeWindowEvents(handler) { + const wrappingHandler = (window, context) => { + let eventType = context.type; + if (eventType === EntityEventType.Added) { + eventType = "opened"; + } + handler(window.activity, window, eventType); + }; + this._windowHandlers.push([handler, wrappingHandler]); + return this._windows.subscribe(wrappingHandler); + } + unsubscribeWindowEvents(handler) { + const found = this._windowHandlers.find((pair) => pair[0] === handler); + if (found) { + this._windowHandlers.splice(this._windowHandlers.indexOf(found), 1); + this._windows.unsubscribe(found[1]); + } + } + createWindow(activity, windowTypeOrConfiguration, callback) { + const promise = new Promise((resolve, reject) => { + if (isUndefinedOrNull(windowTypeOrConfiguration)) { + reject("windowType is undefined"); + } + let windowDefinition; + if (isString(windowTypeOrConfiguration)) { + windowDefinition = { type: (windowTypeOrConfiguration), name: "", isIndependent: false, arguments: {} }; + } + else if (windowTypeOrConfiguration instanceof WindowType) { + windowDefinition = { + type: windowTypeOrConfiguration.type || windowTypeOrConfiguration.id, + name: windowTypeOrConfiguration.name || windowTypeOrConfiguration.type || windowTypeOrConfiguration.id, + isIndependent: false + }; + } + else { + const invalidKeys = ["url"]; + const filteredWindowTypeOrConfiguration = {}; + Object.keys(windowTypeOrConfiguration).forEach((key) => { + if (invalidKeys.indexOf(key) === -1) { + filteredWindowTypeOrConfiguration[key] = windowTypeOrConfiguration[key]; + } + }); + windowDefinition = filteredWindowTypeOrConfiguration; + } + let relativeToWindow; + if (!isUndefinedOrNull(windowDefinition.relativeTo)) { + relativeToWindow = windowDefinition.relativeTo; + if (typeof relativeToWindow === "string") { + const windows = this.getWindows({ type: relativeToWindow }); + if (!isUndefinedOrNull(windows) && windows.length > 0) { + windowDefinition.relativeTo = windows[0].id; + } + } + else if (!isUndefinedOrNull(relativeToWindow.type)) { + const windows = this.getWindows({ type: relativeToWindow.type }); + if (!isUndefinedOrNull(windows) && windows.length > 0) { + windowDefinition.relativeTo = windows[0].id; + } + } + else if (!isUndefinedOrNull(relativeToWindow.windowId)) { + windowDefinition.relativeTo = relativeToWindow.windowId; + } + } + this._bridge.createWindow(activity && activity.id, windowDefinition) + .then((wid) => { + this._logger.debug("Window created, waiting for window entity with id " + wid); + const handler = (window, context) => { + if (window.id === wid && (!activity || window.activity)) { + this._logger.debug("Got entity window with id " + wid); + resolve(window); + this._windows.unsubscribe(handler); + } + }; + this._windows.subscribe(handler); + }) + .catch((err) => { + reject(err); + }); + }); + return nodeify(promise, callback); + } + createStackedWindows(activity, relativeWindowTypes, timeout, callback) { + const promise = new Promise((resolve, reject) => { + if (isUndefinedOrNull(activity)) { + reject("activity is undefined"); + } + if (isUndefinedOrNull(relativeWindowTypes)) { + reject("relativeWindowTypes is undefined"); + } + if (!Array.isArray(relativeWindowTypes)) { + reject("relativeWindowTypes has to be an array"); + } + if (isUndefinedOrNull(timeout)) { + timeout = 20000; + } + const windowDefinitions = []; + relativeWindowTypes.forEach((element) => { + let windowDefinition; + if (isString(element)) { + windowDefinition = { type: (element), name: "", isIndependent: false, arguments: {} }; + } + else { + windowDefinition = (element); + } + windowDefinition.stackedWindow = true; + windowDefinition.timeout = timeout; + let relativeToWindow; + if (!isUndefinedOrNull(windowDefinition.relativeTo)) { + relativeToWindow = windowDefinition.relativeTo; + if (!isUndefinedOrNull(relativeToWindow.type)) { + windowDefinition.relativeTo = relativeToWindow.type; + } + else if (!isUndefinedOrNull(relativeToWindow.windowId)) { + const windows = this.getWindows({ id: relativeToWindow.windowId }); + if (!isUndefinedOrNull(windows) && windows.length > 0) { + windowDefinition.relativeTo = windows[0].type.name; + } + } + } + windowDefinitions.push(windowDefinition); + }); + const tasks = []; + windowDefinitions.forEach((wd) => tasks.push(this.createWindow(activity, wd))); + Promise.all(tasks).then(resolve).catch(reject); + }); + return nodeify(promise, callback); + } + addWindowToActivity(activity, window, callback) { + const toReturn = this._bridge.joinActivity(activity.id, window.id) + .then(() => window); + nodeify(toReturn, callback); + return toReturn; + } + leaveWindowFromActivity(activity, window, callback) { + const toReturn = this._bridge.leaveActivity(activity.id, window.id) + .then(() => window); + nodeify(toReturn, callback); + return toReturn; + } + setActivityContext(activity, context, callback) { + const promise = new Promise((resolve, reject) => { + if (isUndefinedOrNull(activity)) { + reject("activity can not be null"); + } + this._bridge + .updateActivityContext(activity, context, true) + .then((_) => { + resolve(activity); + }) + .catch((err) => { + reject(err); + }); + }); + return nodeify(promise, callback); + } + updateActivityContext(activity, context, callback) { + const promise = new Promise((resolve, reject) => { + if (isUndefinedOrNull(activity)) { + reject("activity can not be null"); + } + const removedKeys = []; + for (const key in context) { + if (context.hasOwnProperty(key) && context[key] === null) { + removedKeys.push(key); + } + } + for (const removedKey of removedKeys) { + delete context[removedKey]; + } + this._bridge + .updateActivityContext(activity, context, false, removedKeys) + .then((_) => { + resolve(activity); + }) + .catch((err) => { + reject(err); + }); + }); + return nodeify(promise, callback); + } + subscribeActivityContextChanged(handler) { + this._activities.subscribe((act, context) => { + if (context.type === EntityEventType.ActivityContextChange) { + const updateContext = context; + handler(act, updateContext.context, updateContext.updated, updateContext.removed); + } + }); + } + stopActivity(activity, callback) { + const promise = this._bridge.stopActivity(activity); + return nodeify(promise, callback); + } + getWindows(filter) { + if (isUndefined(filter)) { + return this._windows.get(); + } + if (!isUndefined(filter.id)) { + return [this._windows.getByName(filter.id)]; + } + const allWindows = this._windows.get(); + return allWindows.filter((w) => { + if (!isUndefined(filter.type) && w.type.id !== filter.type) { + return false; + } + if (!isUndefined(filter.name) && w.name !== filter.name) { + return false; + } + if (!isUndefined(filter.activityId)) { + if (isUndefinedOrNull(w.activity)) { + return false; + } + if (w.activity.id !== filter.activityId) { + return false; + } + } + return true; + }); + } + getWindowBounds(id) { + return this._bridge.getWindowBounds(id); + } + setWindowBounds(id, bounds, callback) { + const promise = new Promise((resolve, reject) => { + this._bridge.setWindowBounds(id, bounds) + .then(() => resolve()) + .catch((err) => reject(err)); + }); + return nodeify(promise, callback); + } + closeWindow(id) { + return this._bridge.closeWindow(id); + } + activateWindow(id, focus) { + return this._bridge.activateWindow(id, focus); + } + setWindowVisibility(id, visible) { + return this._bridge.setWindowVisibility(id, visible); + } + clone(activity, cloneOptions, callback) { + const promise = new Promise((resolve, reject) => { + if (!activity) { + reject("activity can not be null"); + } + this._bridge.cloneActivity(activity.id, cloneOptions) + .then((activityId) => { + this._activities + .getOrWait(activityId) + .then((act) => { + resolve(act); + }) + .catch((err) => reject(err)); + }) + .catch((err) => reject(err)); + }); + return nodeify(promise, callback); + } + attachActivities(from, to, tag, callback) { + tag = tag || {}; + const promise = new Promise((resolve, reject) => { + const fromActivity = this._activities.getByName(from); + if (!fromActivity) { + reject("can not find activity with id " + from); + return; + } + const toActivity = this._activities.getByName(to); + if (!toActivity) { + reject("can not find activity with id " + to); + return; + } + return this._bridge.attachActivities(from, to, tag) + .then((data) => { + const newActId = data.to; + const state = data.descriptor; + const allStates = data.descriptors; + this._activities.getOrWait(newActId).then((act) => { + act._updateDescriptors(allStates); + const stateWrapped = act.attached.filter((u) => u.ownerId === state.ownerId)[0]; + resolve(stateWrapped); + }); + }) + .catch((err) => { + reject(err); + }); + }); + return nodeify(promise, callback); + } + detachActivities(activityId, descriptor, callback) { + const promise = new Promise((resolve, reject) => { + return this._bridge.detachActivities(activityId, descriptor) + .then(() => { + const oldActId = undefined; + const newActId = undefined; + const descriptors = undefined; + this._activities + .getOrWait(oldActId) + .then((oldAct) => { + oldAct._updateDescriptors(descriptors); + this._activities + .getOrWait(newActId) + .then((newAct) => { + resolve(newAct); + }); + }) + .catch((err) => reject(err)); + }) + .catch((err) => { + reject(err); + }); + }); + return nodeify(promise, callback); + } + subscribeActivitiesAttached(callback) { + this._attachedCallbacks.push(callback); + } + subscribeActivitiesDetached(callback) { + this._detachedCallbacks.push(callback); + } + subscribeActivityFrameColorChanged(callback) { + this._frameColorChangesCallbacks.push(callback); + } + _grabEntity(entity) { + entity._manager = this; + } + _getInitialData() { + this._logger.debug("Request initial data..."); + this._bridge.getActivityTypes() + .then((at) => { + this._activityTypes.add(at); + this._dataReadyMarker.signal("Got act types"); + }) + .catch((error) => { + this._logger.error(error); + this._dataReadyMarker.error("Can not initialize ActivityManager - error getting activity types -" + error); + }); + this._bridge.getWindowTypes() + .then((wt) => { + this._windowTypes.add(wt); + this._dataReadyMarker.signal("Got window types"); + }) + .catch((error) => { + this._logger.error(error); + this._dataReadyMarker.error("Can not initialize ActivityManager - error getting window types " + error); + }); + this._bridge.getActivities() + .then((ac) => { + this._activities.add(ac); + this._dataReadyMarker.signal("Got activities"); + }) + .catch((error) => { + this._logger.error(error); + this._dataReadyMarker.error("Can not initialize ActivityManager - error getting activity instances -" + error); + }); + this._bridge.getActivityWindows() + .then((aw) => { + this._windows.add(aw); + this._dataReadyMarker.signal("Got windows"); + }) + .catch((error) => { + this._logger.error(error); + this._dataReadyMarker.error("Can not initialize ActivityManager - error getting activity windows -" + error); + }); + } + _subscribeForData() { + this._logger.debug("Subscribe for data..."); + this._bridge.onActivityTypeStatusChange((event) => { + this._activityTypes.process(event); + }); + this._bridge.onWindowTypeStatusChange((event) => { + this._windowTypes.process(event); + }); + this._bridge.onActivityWindowChange((event) => { + this._windows.process(event); + }); + this._bridge.onActivityStatusChange((event) => { + this._activities.process(event); + }); + } + _handleActivitiesAttached(data) { + const newActId = data.to; + const descriptor = data.descriptor; + const descriptors = data.descriptors; + this._activities.getOrWait(newActId).then((act) => { + act._updateDescriptors(descriptors); + const descriptorAsObjectFromAPI = act.attached.filter((u) => u.ownerId === descriptor.ownerId)[0]; + this._attachedCallbacks.forEach((callback) => { + try { + callback(act, descriptorAsObjectFromAPI); + } + catch (err) { + return; + } + }); + }); + } + _handleActivitiesDetached(data) { + const oldActId = data.oldActivityId; + const newActId = data.newActivityId; + const descriptors = data.descriptors; + const descriptor = data.descriptor; + this._activities.getOrWait(oldActId).then((oldAct) => { + oldAct._updateDescriptors(descriptors); + this._activities.getOrWait(newActId).then((newAct) => { + this._detachedCallbacks.forEach((callback) => { + try { + callback(newAct, oldAct, descriptor); + } + catch (err) { + return; + } + }); + }); + }); + } + _handleActivityDescriptorsRefreshed(data) { + const id = data.id; + const descriptors = data.descriptors; + const act = this._activities.getByName(id); + if (act) { + act._updateDescriptors(descriptors); + } + } + refreshDescriptors() { + this._bridge.getAttachedDescriptors() + .then((map) => { + if (map) { + Object.keys(map).forEach((key) => { + const actId = key; + const descriptors = map[key]; + const act = this._activities.getByName(actId); + if (act) { + act._updateDescriptors(descriptors); + } + }); + } + this._descriptorsMarker.signal("Successfully got descriptors"); + }) + .catch((err) => { + this._descriptorsMarker.error("failed to get descriptors - " + err); + }); + } + _handleWindowFrameColorChanged(win) { + if (!win.activityId) { + return; + } + const act = this._activities.getByName(win.activityId); + if (!act) { + return; + } + if (!act.owner) { + return; + } + if (act.owner.underlyingWindow.id !== win.id) { + return; + } + this._frameColorChangesCallbacks.forEach((callback) => { + try { + callback(act, win.frameColor); + } + catch (e) { + return; + } + }); + } + } + + class ActivityManagementAPI { + constructor(manager, my) { + this._m = manager; + this._my = my; + this.activityTypes = { + get: this._getActivityTypesWrapper.bind(this), + register: this._m.registerActivityType.bind(this._m), + unregister: this._m.unregisterActivityType.bind(this._m), + subscribe: this._m.subscribeActivityTypeEvents.bind(this._m), + unsubscribe: undefined, + initiate: this._m.initiate.bind(this._m) + }; + this.windowTypes = { + get: this._getWindowTypesWrapper.bind(this), + registerFactory: this._m.registerWindowFactory.bind(this._m), + unregisterFactory: this._m.unregisterWindowFactory.bind(this._m), + subscribe: this._m.subscribeWindowTypeEvents.bind(this._m), + unsubscribe: undefined + }; + this.windows = { + get: this._m.getWindows.bind(this._m), + subscribe: this._m.subscribeWindowEvents.bind(this._m), + announce: this._m.announceWindow.bind(this._m), + unsubscribe: undefined, + create: this._m.createWindow.bind(this._m) + }; + this.instances = { + get: this._m.getActivities.bind(this._m), + subscribe: this._m.subscribeActivityEvents.bind(this._m), + unsubscribe: undefined + }; + } + onAttached(callback) { + this._m.subscribeActivitiesAttached(callback); + } + onDetached(callback) { + this._m.subscribeActivitiesDetached(callback); + } + onActivityFrameColorChanged(callback) { + this._m.subscribeActivityFrameColorChanged(callback); + } + _getActivityTypesWrapper(name) { + if (isUndefined(name)) { + return this._m.getActivityTypes(); + } + return this._m.getActivityType(name); + } + _getWindowTypesWrapper(name) { + if (isUndefined(name)) { + return this._m.getWindowTypes(); + } + return this._m.getWindowType(name); + } + } + + class ActivityAPI { + constructor(manager, my) { + this._mgr = manager; + this._my = my; + this.all = new ActivityManagementAPI(manager, my); + } + ready(callback) { + const promise = new Promise((resolve, reject) => { + this._mgr.ready() + .then(() => { + resolve(this); + }) + .catch((err) => { + reject(err); + }); + }); + return nodeify(promise, callback); + } + get my() { + return this._my; + } + get aware() { + return this._my.window !== undefined; + } + get inActivity() { + return this.aware && this._my.activity !== undefined; + } + get agm() { + if (!this.aware) { + return undefined; + } + if (!this.inActivity) { + return new ActivityAGM(null); + } + return this._my.activity.agm; + } + getAvailableFrameColors() { + return []; + } + } + + class ActivityModule { + static checkIsUsingGW3Implementation(connection) { + return connection.protocolVersion === 3; + } + get api() { + return this._api; + } + set api(value) { + this._api = value; + } + constructor(config) { + if (!config) { + throw new Error("config can not be null"); + } + if (!isUndefined(config.logLevel)) { + Logger.Level = config.logLevel; + } + if (!isUndefinedOrNull(config.logger)) { + Logger.GlueLogger = config.logger; + } + let bridge; + this._isUsingHCImplementation = config.gdMajorVersion === 2; + this._isUsingGW3Implementation = ActivityModule.checkIsUsingGW3Implementation(config.connection); + if (this._isUsingHCImplementation) { + throw new Error("GD2 not supported"); + } + else if (this._isUsingGW3Implementation) { + bridge = new GW3Bridge(config); + } + else { + throw new Error("Unable to instantiate activity bridge implementation"); + } + if (!bridge) { + throw new Error("A bridge to native activity is needed to create activity lib."); + } + ActivityAGM.AGM = config.agm; + const activityManager = new ActivityManager(bridge, !config.disableAutoAnnounce, config.windows); + const my = new ActivityMy(activityManager, config.windows); + this._api = new ActivityAPI(activityManager, my); + this._readyPromise = activityManager.ready().then((_) => this); + } + get isUsingHCImplementation() { + return this._isUsingHCImplementation; + } + get isUsingGW3Implementation() { + return this._isUsingGW3Implementation; + } + ready(callback) { + return nodeify(this._readyPromise, callback); + } + } + + const ShutdownMethodName = "T42.ACS.Shutdown"; + const OnGDShutdownMethodName = "T42.ACS.OnGDShutdown"; + const RestartMethodName = "T42.ACS.Restart"; + const GetConfigurationRegionMethodName = "T42.ACS.GetConfigurationRegion"; + const SetConfigurationRegionMethodName = "T42.ACS.SetConfigurationRegion"; + const GetUserMethodName = "T42.ACS.GetUser"; + const GetBranchesMethodName = "T42.ACS.GetBranches"; + const GetCurrentBranchMethodName = "T42.ACS.GetCurrentBranch"; + const SetCurrentBranchMethodName = "T42.ACS.SetCurrentBranch"; + const GetFunctionalEntitlementMethodName = "T42.ACS.GetFunctionalEntitlement"; + const CanIMethodName = "T42.ACS.CanI"; + const StartApplicationMethodName = "T42.ACS.StartApplication"; + const StopApplicationMethodName = "T42.ACS.StopApplication"; + const ActivateApplicationMethodName = "T42.ACS.ActivateApplication"; + const ACSExecute = "T42.ACS.Execute"; + const OnEventMethodName = "T42.ACS.OnEvent"; + const GetApplicationsMethodName = "T42.ACS.GetApplications"; + + var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; + + function getDefaultExportFromCjs (x) { + return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; + } + + function createRegistry(options) { + if (options && options.errorHandling + && typeof options.errorHandling !== "function" + && options.errorHandling !== "log" + && options.errorHandling !== "silent" + && options.errorHandling !== "throw") { + throw new Error("Invalid options passed to createRegistry. Prop errorHandling should be [\"log\" | \"silent\" | \"throw\" | (err) => void], but " + typeof options.errorHandling + " was passed"); + } + var _userErrorHandler = options && typeof options.errorHandling === "function" && options.errorHandling; + var callbacks = {}; + function add(key, callback, replayArgumentsArr) { + var callbacksForKey = callbacks[key]; + if (!callbacksForKey) { + callbacksForKey = []; + callbacks[key] = callbacksForKey; + } + callbacksForKey.push(callback); + if (replayArgumentsArr) { + setTimeout(function () { + replayArgumentsArr.forEach(function (replayArgument) { + var _a; + if ((_a = callbacks[key]) === null || _a === void 0 ? void 0 : _a.includes(callback)) { + try { + if (Array.isArray(replayArgument)) { + callback.apply(undefined, replayArgument); + } + else { + callback.apply(undefined, [replayArgument]); + } + } + catch (err) { + _handleError(err, key); + } + } + }); + }, 0); + } + return function () { + var allForKey = callbacks[key]; + if (!allForKey) { + return; + } + allForKey = allForKey.reduce(function (acc, element, index) { + if (!(element === callback && acc.length === index)) { + acc.push(element); + } + return acc; + }, []); + if (allForKey.length === 0) { + delete callbacks[key]; + } + else { + callbacks[key] = allForKey; + } + }; + } + function execute(key) { + var argumentsArr = []; + for (var _i = 1; _i < arguments.length; _i++) { + argumentsArr[_i - 1] = arguments[_i]; + } + var callbacksForKey = callbacks[key]; + if (!callbacksForKey || callbacksForKey.length === 0) { + return []; + } + var results = []; + callbacksForKey.forEach(function (callback) { + try { + var result = callback.apply(undefined, argumentsArr); + results.push(result); + } + catch (err) { + results.push(undefined); + _handleError(err, key); + } + }); + return results; + } + function _handleError(exceptionArtifact, key) { + var errParam = exceptionArtifact instanceof Error ? exceptionArtifact : new Error(exceptionArtifact); + if (_userErrorHandler) { + _userErrorHandler(errParam); + return; + } + var msg = "[ERROR] callback-registry: User callback for key \"" + key + "\" failed: " + errParam.stack; + if (options) { + switch (options.errorHandling) { + case "log": + return console.error(msg); + case "silent": + return; + case "throw": + throw new Error(msg); + } + } + console.error(msg); + } + function clear() { + callbacks = {}; + } + function clearKey(key) { + var callbacksForKey = callbacks[key]; + if (!callbacksForKey) { + return; + } + delete callbacks[key]; + } + return { + add: add, + execute: execute, + clear: clear, + clearKey: clearKey + }; + } + createRegistry.default = createRegistry; + var lib = createRegistry; + + + var CallbackRegistryFactory = /*@__PURE__*/getDefaultExportFromCjs(lib); + + function objectValues(source) { + if (!source) { + return []; + } + return Object.keys(source).map((key) => source[key]); + } + function objectClone(obj) { + let result; + try { + result = JSON.parse(JSON.stringify(obj || {})); + } + catch (error) { + result = {}; + } + return result; + } + function validate(callback, configuration) { + if (configuration.throwErrors) { + if (typeof callback !== "function") { + throw new Error("Please provide the callback as a function!"); + } + } + } + + const INTEROP_METHOD_RESPONSE_TIMEOUT_MS = 90000; + const INTEROP_METHOD_WAIT_TIMEOUT_MS = 90000; + + let urlAlphabet = + 'useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict'; + let nanoid = (size = 21) => { + let id = ''; + let i = size | 0; + while (i--) { + id += urlAlphabet[(Math.random() * 64) | 0]; + } + return id + }; + + class Utils { + static getGDMajorVersion() { + if (typeof window === "undefined") { + return -1; + } + if (!window.glueDesktop) { + return -1; + } + if (!window.glueDesktop.version) { + return -1; + } + const parsed = window.glueDesktop.version.split("."); + const major = Number(parsed[0]); + return isNaN(major) ? -1 : major; + } + static typedError(error) { + let err; + if (error instanceof Error) { + err = error; + } + else if (typeof error === "string") { + err = new Error(error); + } + else if ("message" in error && typeof error.message === "string" && error.message.length > 0) { + err = new Error(error.message); + } + else if ("returned" in error + && typeof error.returned === "object" + && "errorMsg" in error.returned + && typeof error.returned.errorMsg === "string" + && error.returned.errorMsg.length > 0) { + err = new Error(error.returned.errorMsg); + } + else { + err = new Error("Unknown error"); + } + return err; + } + static async callbackifyPromise(action, successCallback, errorCallback) { + const success = (result) => { + if (typeof successCallback === "function") { + successCallback(result); + } + return Promise.resolve(result); + }; + const fail = (error) => { + const err = Utils.typedError(error); + if (typeof errorCallback === "function") { + errorCallback(err.message); + return; + } + return Promise.reject(err); + }; + try { + const result = await action(); + return success(result); + } + catch (error) { + return fail(error); + } + } + static getMonitor(bounds, displays) { + const monitorsSortedByOverlap = displays.map((m) => { + const { left, top, workingAreaWidth: width, workingAreaHeight: height } = m; + const overlap = this.calculateTotalOverlap({ left, top, width, height }, bounds); + return { + monitor: m, + totalOverlap: overlap + }; + }).sort((a, b) => b.totalOverlap - a.totalOverlap); + return monitorsSortedByOverlap[0].monitor; + } + static getDisplayCenterOfScreen(a, currentDisplay, primaryDisplay) { + const physicalWidth = a.width / currentDisplay.scaleFactor; + const physicalHeight = a.height / currentDisplay.scaleFactor; + const physicalDisplayLeft = currentDisplay.workArea.left / primaryDisplay.scaleFactor; + const physicalDisplayTop = currentDisplay.workArea.top / primaryDisplay.scaleFactor; + const physicalDisplayWidth = currentDisplay.workArea.width / currentDisplay.scaleFactor; + const physicalDisplayHeight = currentDisplay.workArea.height / currentDisplay.scaleFactor; + const physicalHOffset = Math.max((physicalDisplayWidth - physicalWidth) / 2, 0); + const physicalVOffset = Math.max((physicalDisplayHeight - physicalHeight) / 2, 0); + const centeredPhysicalLeft = Math.floor(physicalDisplayLeft + physicalHOffset); + const centeredPhysicalTop = Math.floor(physicalDisplayTop + physicalVOffset); + const left = centeredPhysicalLeft * primaryDisplay.scaleFactor; + const top = centeredPhysicalTop * primaryDisplay.scaleFactor; + return { + left, + top, + width: a.width, + height: a.height + }; + } + static isNode() { + if (typeof Utils._isNode !== "undefined") { + return Utils._isNode; + } + if (typeof window !== "undefined") { + Utils._isNode = false; + return false; + } + try { + Utils._isNode = Object.prototype.toString.call(global.process) === "[object process]"; + } + catch (e) { + Utils._isNode = false; + } + return Utils._isNode; + } + static generateId() { + return nanoid(10); + } + static isPromise(value) { + return Boolean(value && typeof value.then === 'function'); + } + static isAsyncFunction(value) { + return value && {}.toString.call(value) === '[object AsyncFunction]'; + } + static isNullOrUndefined(value) { + return value === null || value === undefined; + } + static calculateTotalOverlap(r1, r2) { + const r1x = r1.left; + const r1y = r1.top; + const r1xMax = r1x + r1.width; + const r1yMax = r1y + r1.height; + const r2x = r2.left; + const r2y = r2.top; + const r2xMax = r2x + r2.width; + const r2yMax = r2y + r2.height; + const xOverlap = Math.max(0, Math.min(r1xMax, r2xMax) - Math.max(r1x, r2x)); + const yOverlap = Math.max(0, Math.min(r1yMax, r2yMax) - Math.max(r1y, r2y)); + return xOverlap * yOverlap; + } + } + + class ApplicationImpl { + constructor(_appManager, _name, _agm, _logger, _configuration) { + this._appManager = _appManager; + this._name = _name; + this._agm = _agm; + this._logger = _logger; + this._configuration = _configuration; + this._registry = CallbackRegistryFactory(); + _appManager.onInstanceStarted((instance) => { + if (instance.application && instance.application.name !== this._name) { + return; + } + this._registry.execute("instanceStarted", instance); + }); + _appManager.onInstanceStopped((instance) => { + if (instance.application && instance.application.name !== this._name) { + return; + } + this._registry.execute("instanceStopped", instance); + }); + _appManager.onAppRemoved((app) => { + if (app.name !== this._name) { + return; + } + this._registry.execute("appRemoved", app); + }); + _appManager.onAppChanged((app) => { + if (app.name !== this._name) { + return; + } + this._registry.execute("appChanged", app); + }); + _appManager.onAppAvailable((app) => { + if (app.name !== this._name) { + return; + } + this._props.IsReady = true; + this._registry.execute("appAvailable", app); + }); + _appManager.onAppUnavailable((app) => { + if (app.name !== this._name) { + return; + } + this._props.IsReady = false; + this._registry.execute("appUnavailable", app); + }); + } + get name() { return this._name; } + get title() { return this._props.Title; } + get version() { return this._props.Version; } + get autoStart() { return this._props.AutoStart; } + get isShell() { return this._props.IsShell; } + get caption() { return this._props.Caption; } + get hidden() { return this._props.IsHidden; } + get container() { return this._props.ApplicationName; } + get activityType() { return this._props.ActivityType; } + get activityWindowType() { return this._props.ActivityWindowType; } + get windowSettings() { + if (!this._props.Arguments) { + return {}; + } + return objectClone(this._props.Arguments); + } + get allowMultiple() { return this._props.AllowMultiple; } + get available() { return this._props.IsReady || true; } + get icon() { return this._props.Icon; } + get iconURL() { return this._props.IconUrl; } + get sortOrder() { return this._props.SortOrder; } + get userProperties() { + if (!this._props.UserProperties) { + return {}; + } + return objectClone(this._props.UserProperties); + } + get keywords() { + if (!this._props.Keywords) { + return []; + } + return this._props.Keywords; + } + get isActivity() { + return this._props.ActivityType !== undefined && this._props.ActivityType !== ""; + } + get configuration() { + return { + autoStart: this._props.AutoStart, + caption: this._props.Caption, + hidden: this._props.IsHidden, + container: this._props.ApplicationName, + activityType: this._props.ActivityType, + allowMultiple: this._props.AllowMultiple + }; + } + get instances() { + return this._appManager.instances().filter((instance) => instance.application.name === this._name); + } + get type() { + return this._props.Type; + } + get mode() { + if (!this._props) { + return "unknown"; + } + if (this._props.Mode && typeof this._props.Mode === "string") { + return this._props.Mode.toLowerCase(); + } + if (this.isActivity) { + return "unknown"; + } + if (this._props.Arguments && this._props.Arguments.mode && typeof this._props.Arguments.mode === "string") { + return this._props.Arguments.mode.toLowerCase(); + } + let styleAttributes = this._props.WindowStyleAttributes; + if (styleAttributes) { + styleAttributes = styleAttributes.split(" ").join(""); + const searchFor = "mode:\""; + const modeIndex = styleAttributes.indexOf(searchFor); + if (modeIndex !== -1) { + const startModeIndex = modeIndex + searchFor.length; + const stopModeIndex = styleAttributes.indexOf("\"", startModeIndex); + const style = styleAttributes.substr(startModeIndex, stopModeIndex - startModeIndex); + if (style && typeof style === "string") { + return style.toLowerCase(); + } + } + } + return "flat"; + } + async getConfiguration() { + const result = await this._agm.invoke(GetApplicationsMethodName, { v2: { apps: [this._name] } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + const config = result.returned.applications[0]; + return config; + } + updateFromProps(props) { + if (!this._props) { + this._props = { Name: props.Name }; + } + Object.keys(props).forEach((key) => { + this._props[key] = props[key]; + }); + } + start(context, options) { + return new Promise(async (resolve, reject) => { + var _a, _b, _c, _d; + if (isUndefinedOrNull(context)) { + context = {}; + } + else if (((_a = this._configuration()) === null || _a === void 0 ? void 0 : _a.throwErrors) && typeof context !== "object" || Array.isArray(context)) { + return reject(new Error(`Invalid "context" parameter - must be an object.`)); + } + if (isUndefinedOrNull(options)) { + options = {}; + } + else if (((_b = this._configuration()) === null || _b === void 0 ? void 0 : _b.throwErrors) && typeof options !== "object") { + return reject(new Error(`Invalid "options" parameter - must be an object.`)); + } + const name = this._name; + let waitForAGMInstance = (_d = ((_c = options.awaitInterop) !== null && _c !== void 0 ? _c : options.waitForAGMReady)) !== null && _d !== void 0 ? _d : true; + let startTimeout = 60000; + if (typeof options.timeout === "number") { + startTimeout = options.timeout * 1000; + } + if (options.relativeTo !== undefined && typeof options.relativeTo !== "string") { + options.relativeTo = options.relativeTo.id || ""; + } + const waitForApplicationInstance = (id) => { + let unsub; + const timeout = setTimeout(() => { + if (unsub) { + unsub(); + } + const errMsg = `timed out while waiting for instance id ${id} for app ${this.name}`; + this._logger.error(errMsg); + reject(new Error(errMsg)); + }, startTimeout); + const waitFunc = (i) => { + if (i.id !== id) { + return; + } + if (unsub) { + unsub(); + unsub = undefined; + } + clearTimeout(timeout); + resolve(i); + }; + if (waitForAGMInstance) { + const instance = this._appManager.instances().find((i) => i.id === id); + if (instance) { + unsub = instance.onAgmReady(waitFunc); + } + else { + unsub = this._appManager.onInstanceAgmServerReady(waitFunc); + } + } + else { + unsub = this._appManager.onInstanceStarted(waitFunc); + } + }; + try { + this._logger.trace(`starting application ${name} with options: ${JSON.stringify(options)}`); + const result = await this._agm.invoke(StartApplicationMethodName, { + Name: name, + Context: context, + Options: options + }, "best", { + methodResponseTimeoutMs: startTimeout, + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + const acsResult = result.returned; + if (typeof acsResult.timeout !== "undefined" && typeof options.timeout === "undefined") { + startTimeout = acsResult.timeout * 1000; + } + if (typeof acsResult.waitForInterop !== "undefined" && (typeof options.waitForAGMReady === "undefined" && typeof options.awaitInterop === "undefined")) { + waitForAGMInstance = acsResult.waitForInterop; + } + if (acsResult && acsResult.Id) { + if (this._appManager.mode === "startOnly") { + const instance = this._appManager.handleInstanceStarted({ + ActivityId: undefined, + IsActivityOwner: undefined, + Context: undefined, + Title: undefined, + AgmServers: undefined, + Id: acsResult.Id, + Name: acsResult.Name, + }); + resolve(instance); + } + else { + waitForApplicationInstance(acsResult.Id); + } + } + else { + resolve(undefined); + } + } + catch (error) { + const err = Utils.typedError(error); + reject(err); + } + }); + } + onInstanceStarted(callback) { + validate(callback, this._configuration()); + return this._registry.add("instanceStarted", callback); + } + onInstanceStopped(callback) { + validate(callback, this._configuration()); + return this._registry.add("instanceStopped", callback); + } + onAvailable(callback) { + validate(callback, this._configuration()); + if (this._props.IsReady) { + setTimeout(() => { + this._registry.execute("appAvailable", this); + }, 0); + } + return this._registry.add("appAvailable", callback); + } + onUnavailable(callback) { + validate(callback, this._configuration()); + if (this._props.IsReady === false) { + setTimeout(() => { + this._registry.execute("appUnavailable", this); + }, 0); + } + return this._registry.add("appUnavailable", callback); + } + onChanged(callback) { + validate(callback, this._configuration()); + this._registry.add("appChanged", callback); + } + onRemoved(callback) { + validate(callback, this._configuration()); + this._registry.add("appRemoved", callback); + } + } + + class InstanceImpl { + constructor(_id, _appName, _appManager, _agm, _activities, _windows, _logger, startFailed, _configuration) { + this._id = _id; + this._appName = _appName; + this._appManager = _appManager; + this._agm = _agm; + this._activities = _activities; + this._windows = _windows; + this._logger = _logger; + this._configuration = _configuration; + this._registry = CallbackRegistryFactory(); + if (startFailed) { + return; + } + this._unsubscribeInstanceStopped = this._appManager.onInstanceStopped((instance) => { + if (instance.id !== this._id) { + return; + } + this._registry.execute("stopped", instance); + }); + this._unsubscribeInstanceAgmServerReady = this._appManager.onInstanceAgmServerReady((instance) => { + if (instance.id !== this._id) { + return; + } + this._registry.execute("agmReady", instance); + }); + } + get id() { return this._id; } + get application() { return this._appManager.application(this._appName); } + get activity() { + if (!this._activities) { + throw new Error("This method requires glue.activities library to be enabled."); + } + return this._activities.all.instances.get() + .filter((activityInstance) => activityInstance.id === this._activityId)[0]; + } + get isActivityOwner() { return this._isActivityOwner; } + get activityInstances() { + return this._appManager.instances().filter((i) => i.application.type !== "activity" && + i.activityId && + i.activityId === this._activityId); + } + get activityOwnerInstance() { + if (!this._activityId) { + return undefined; + } + return this.activityInstances.filter((inst) => inst === null || inst === void 0 ? void 0 : inst.isActivityOwner)[0]; + } + get window() { + if (!this._windows) { + throw new Error("This method requires glue.windows library to be enabled."); + } + let win = this._windows.list().find((w) => w.id === this._id); + if (!win && this._activities && this.activity && this.activityOwnerInstance) { + win = this.activityOwnerInstance.window; + } + return win; + } + get context() { + var _a, _b, _c; + return (_c = (_a = this._startUpContext) !== null && _a !== void 0 ? _a : (_b = this.window) === null || _b === void 0 ? void 0 : _b.context) !== null && _c !== void 0 ? _c : {}; + } + get title() { return this._title; } + get isActivityInstance() { return this._isActivityInstance; } + get activityId() { return this._activityId; } + get inActivity() { return this._inActivity; } + get isSingleWindowApp() { return !this._inActivity; } + get agm() { + return this._agmInstance; + } + get interopInstance() { + return this._agmInstance; + } + onInteropReady(callback) { + validate(callback, this._configuration()); + if (this._agmInstance) { + setTimeout(() => { + this._registry.execute("agmReady", this); + }, 0); + } + return this._registry.add("agmReady", callback); + } + onAgmReady(callback) { + return this.onInteropReady(callback); + } + onStopped(callback) { + validate(callback, this._configuration()); + return this._registry.add("stopped", callback); + } + getWindow() { + return new Promise((resolve, reject) => { + const result = this.window; + if (result) { + resolve(result); + return; + } + const done = (error, window) => { + if (error) { + reject(error); + } + if (window) { + resolve(window); + } + setTimeout(() => { + clearTimeout(timeout); + unsub(); + }, 0); + }; + this._logger.trace(`waiting for window with id ${this._id} to appear`); + const timeoutInSeconds = 60; + const timeout = setTimeout(() => { + this._logger.trace(`window with id ${this._id} did not appear in ${timeoutInSeconds} sec`); + done(new Error(`can not find a window with id ${this._id}`)); + }, timeoutInSeconds * 1000); + const unsub = this._windows.onWindowAdded((w) => { + if (w.id === this._id) { + this._logger.trace(`window with id ${this._id} appeared`); + done(undefined, w); + } + }); + }); + } + updateFromProps(props) { + this._startUpContext = props.Context; + this._title = props.Title; + this._isActivityInstance = false; + if (props.ActivityId && props.ActivityId !== "") { + this._activityId = props.ActivityId; + this._isActivityInstance = true; + } + this._isActivityOwner = props.IsActivityOwner; + if (!this._activityId && this._startUpContext && this._startUpContext.activityId) { + this._activityId = this._startUpContext.activityId; + } + this._inActivity = Boolean(this._activityId); + this.updateAgmInstanceFromProps(props); + } + updateAgmInstanceFromProps(props) { + if (!props.AgmServers) { + return; + } + const agmInstances = props.AgmServers; + if (agmInstances && agmInstances.length > 0 && !isUndefinedOrNull(agmInstances[0])) { + this._agmInstance = agmInstances[0]; + } + } + stop() { + return new Promise((resolve, reject) => { + let idToResolve = this._id; + if (this.isActivityOwner) { + idToResolve = this.activityId; + } + const unsubscribe = this._appManager.onInstanceStopped((instance) => { + if (instance.id === idToResolve) { + this._logger.trace(`instance with id ${idToResolve} stopped`); + unsubscribe(); + resolve(); + } + }); + this._logger.trace(`stopping instance with id ${this._id}`); + this._agm.invoke(StopApplicationMethodName, { + Name: this._appName, + Id: this._id + }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }) + .then(() => { + if (this._appManager.mode === "startOnly") { + this._appManager.handleInstanceStopped({ + Name: this._appName, + Id: this.id + }); + resolve(); + } + }) + .catch((err) => reject(err)); + }); + } + activate() { + return this._agm.invoke(ActivateApplicationMethodName, { Name: this._appName, Id: this._id }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + done() { + this._registry.clear(); + this._unsubscribeInstanceAgmServerReady(); + this._unsubscribeInstanceStopped(); + } + getContext() { + return Promise.resolve(this.context); + } + async startedBy() { + const result = await this._agm.invoke(ACSExecute, { command: "getStartedBy", Name: this._appName, Id: this._id }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return result.returned; + } + } + + class AppManagerImpl { + constructor(mode, _agm, _activities, _windows, _logger, _gdMajorVersion, _configuration) { + this.mode = mode; + this._agm = _agm; + this._activities = _activities; + this._windows = _windows; + this._logger = _logger; + this._gdMajorVersion = _gdMajorVersion; + this._configuration = _configuration; + this._apps = {}; + this._instances = []; + this._registry = CallbackRegistryFactory(); + this.getConfigurations = async (apps) => { + const args = { + v2: { + apps: undefined + } + }; + if (Array.isArray(apps)) { + args.v2 = { + apps + }; + } + const result = await this._agm.invoke(GetApplicationsMethodName, args, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return result.returned.applications; + }; + this.application = (name) => { + var _a; + if (((_a = this._configuration()) === null || _a === void 0 ? void 0 : _a.throwErrors) && typeof name !== "string" || isNullOrWhiteSpace(name)) { + throw new Error(`"name" must be string`); + } + return this._apps[name]; + }; + this.applications = () => { + return Object.keys(this._apps).map((k) => this._apps[k]); + }; + this.instances = () => { + return this._instances.map((i) => i); + }; + this.getMyInstance = () => { + const glue42gd = typeof window !== "undefined" && window.glue42gd; + if (glue42gd) { + if (this._gdMajorVersion >= 3) { + const instanceId = glue42gd.appInstanceId; + return this._instances.find((i) => i.id === instanceId); + } + } + else { + const instanceId = this._agm.instance.instance; + return this._instances.find((i) => i.id === instanceId); + } + return undefined; + }; + this.getMyApplication = () => { + var _a; + if (this._agm.instance) { + return (_a = this.application(this._agm.instance.applicationName)) !== null && _a !== void 0 ? _a : this.application(this._agm.instance.application); + } + }; + this.handleSnapshotAppsAdded = (newApps) => { + const currentApps = this.applications(); + if (currentApps.length > 0) { + currentApps.forEach((item) => { + const name = item.name; + const alreadyExists = newApps.find((i) => i.Name === item.name); + if (!alreadyExists) { + this.handleAppRemoved({ Name: name }); + } + }); + } + newApps.forEach((item) => { + const alreadyExists = currentApps.find((i) => i.name === item.Name); + if (!alreadyExists) { + this.handleAppAdded(item); + } + }); + }; + this.handleSnapshotInstanceStarted = (newInstances) => { + const currentInstances = this.instances(); + if (currentInstances.length > 0) { + currentInstances.forEach((item) => { + const id = item.id; + const alreadyExists = newInstances.find((i) => i.Id === id); + if (!alreadyExists) { + this.handleInstanceStopped({ Name: item.application.name, Id: id }); + } + }); + } + newInstances.forEach((item) => { + const alreadyExists = currentInstances.find((i) => i.id === item.Id); + if (!alreadyExists) { + this.handleInstanceStarted(item); + } + }); + }; + this.handleAppAdded = (props) => { + const id = this._getAppId(props); + this._logger.trace(`adding app ${id}`); + this._apps[id] = new ApplicationImpl(this, id, this._agm, this._logger, this._configuration); + const app = this._updateAppFromProps(props); + this._registry.execute("appAdded", app); + this._registry.execute("appAvailable", app); + }; + this.handleAppUpdated = (props) => { + const app = this._updateAppFromProps(props); + this._registry.execute("appChanged", app); + }; + this.handleAppRemoved = (props) => { + const id = this._getAppId(props); + this._logger.trace(`removing app ${id}`); + const app = this.application(id); + this._instances = this._instances.filter((i) => i.application.name !== app.name); + delete this._apps[id]; + this._registry.execute("appRemoved", app); + }; + this.handleAppReady = (props) => { + const id = this._getAppId(props); + const app = this._getAppOrThrow(id); + app.updateFromProps(props); + if (app.available) { + this._registry.execute("appAvailable", app); + } + else { + this._registry.execute("appUnavailable", app); + } + }; + this.handleInstanceStarted = (props) => { + this._logger.trace(`started app ${props.Name} ${props.Id}`); + const id = this._getInstanceId(props); + const appName = this._getInstanceAppName(props); + const instance = new InstanceImpl(id, appName, this, this._agm, this._activities, this._windows, this._logger, false, this._configuration); + this._updateInstanceFromProps(instance, props); + this._instances.push(instance); + this._registry.execute("instanceStarted", instance); + return instance; + }; + this.handleInstanceStopped = (props) => { + this._logger.trace(`instance stopped ${props.Name} ${props.Id}`); + const id = this._getInstanceId(props); + const appName = this._getInstanceAppName(props); + const instance = this._getInstanceOrThrow(id, appName); + this._instances = this._instances.filter((i) => !this._matchInstance(i, id, appName)); + this._registry.execute("instanceStopped", instance); + instance.done(); + }; + this.handleInstanceAgmServerReady = (props) => { + this._logger.trace(`instance interop server ready ${props.Name} ${props.Id}`); + const id = this._getInstanceId(props); + const appName = this._getInstanceAppName(props); + const instance = this._getInstanceOrThrow(id, appName); + instance.updateAgmInstanceFromProps(props); + this._registry.execute("instanceAgmServerReady", instance); + }; + this.handleInstanceStartFailed = (props) => { + const id = this._getInstanceId(props); + const appName = this._getInstanceAppName(props); + const startFailed = true; + const instance = new InstanceImpl(id, appName, undefined, undefined, undefined, undefined, this._logger, startFailed, this._configuration); + this._updateInstanceFromProps(instance, props); + this._registry.execute("instanceStartFailed", instance); + }; + this.handleInstanceUpdated = (props) => { + const id = this._getInstanceId(props); + const app = this._getInstanceAppName(props); + const instance = this._getInstanceOrThrow(id, app); + this._updateInstanceFromProps(instance, props); + }; + this.onInstanceStarted = (callback) => { + validate(callback, this._configuration()); + return this._registry.add("instanceStarted", callback, this._instances); + }; + this.onInstanceStartFailed = (callback) => { + validate(callback, this._configuration()); + return this._registry.add("instanceStartFailed", callback); + }; + this.onInstanceStopped = (callback) => { + validate(callback, this._configuration()); + return this._registry.add("instanceStopped", callback); + }; + this.onInstanceUpdated = (callback) => { + validate(callback, this._configuration()); + return this._registry.add("instanceChanged", callback); + }; + this.onInstanceAgmServerReady = (callback) => { + validate(callback, this._configuration()); + return this._registry.add("instanceAgmServerReady", callback); + }; + this.onAppAdded = (callback) => { + validate(callback, this._configuration()); + return this._registry.add("appAdded", callback, Object.values(this._apps)); + }; + this.onAppRemoved = (callback) => { + validate(callback, this._configuration()); + return this._registry.add("appRemoved", callback); + }; + this.onAppAvailable = (callback) => { + validate(callback, this._configuration()); + return this._registry.add("appAvailable", callback); + }; + this.onAppUnavailable = (callback) => { + validate(callback, this._configuration()); + return this._registry.add("appUnavailable", callback); + }; + this.onAppChanged = (callback) => { + validate(callback, this._configuration()); + return this._registry.add("appChanged", callback); + }; + } + _getAppOrThrow(id) { + const result = this.application(id); + if (!result) { + throw Error(`app with id ${id} not found`); + } + return result; + } + _getAppId(props) { + return props.Name; + } + _matchInstance(instance, id, appName) { + return instance.id === id && instance.application.name === appName; + } + _getInstanceByIdAndName(id, appName) { + return this._instances.filter((i) => this._matchInstance(i, id, appName))[0]; + } + _getInstanceOrThrow(id, appName) { + const result = this._getInstanceByIdAndName(id, appName); + if (!result) { + throw Error(`instance with id ${id} not found`); + } + return result; + } + _getInstanceId(props) { + return props.Id; + } + _getInstanceAppName(props) { + return props.Name; + } + _updateAppFromProps(props) { + const id = this._getAppId(props); + this._logger.trace(`updating app with + ${id}, ${JSON.stringify(props)}`); + const app = this._getAppOrThrow(id); + app.updateFromProps(props); + return app; + } + _updateInstanceFromProps(instance, props) { + this._logger.trace("updating instance with " + this._getInstanceId(props) + " for app " + this._getInstanceAppName(props)); + instance.updateFromProps(props); + } + } + + function promisify(promise, successCallback, errorCallback) { + const isFunction = (arg) => { + return !!(arg && arg.constructor && arg.call && arg.apply); + }; + if (!isFunction(successCallback) && !isFunction(errorCallback)) { + return promise; + } + if (!isFunction(successCallback)) { + successCallback = () => { + }; + } + else if (!isFunction(errorCallback)) { + errorCallback = () => { + }; + } + return promise.then(successCallback, errorCallback); + } + class EntitlementsImpl { + constructor(_agm) { + this._agm = _agm; + this._registry = CallbackRegistryFactory(); + this._isMethodRegistered = false; + this.handleBranchModified = (branch) => { + this._registry.execute("branchChanged", branch); + }; + this.handleBranchesModified = (branches) => { + this._registry.execute("branchesChanged", branches); + }; + this.getRegion = (success, error) => { + return promisify(this._agmInvoke(GetConfigurationRegionMethodName, (e) => e.returned.Region), success, error); + }; + this.getBranches = (success, error) => { + const promise = this._agmInvoke(GetBranchesMethodName, (e) => { + const obj = e.returned.Branches; + return Object.keys(obj).map((key) => obj[key]); + }); + return promisify(promise, success, error); + }; + this.getCurrentBranch = (success, error) => { + const promise = this._agmInvoke(GetCurrentBranchMethodName, (e) => e.returned.Branch, undefined); + return promisify(promise, success, error); + }; + this.setRegion = (region, success, error) => { + const promise = this._agmInvoke(SetConfigurationRegionMethodName, (e) => e.returned.ResultMessage, { Region: region }); + return promisify(promise, success, error); + }; + this.setCurrentBranch = (branch, success, error) => { + const promise = this._agmInvoke(SetCurrentBranchMethodName, (e) => e.returned.ResultMessage, { Branch: branch }); + return promisify(promise, success, error); + }; + this.currentUser = (success, error) => { + const promise = this._agmInvoke(GetUserMethodName); + return promisify(promise, success, error); + }; + this.getFunctionalEntitlement = (funct, success, error) => { + const promise = this._agmInvoke(GetFunctionalEntitlementMethodName, (e) => e.returned.Entitlement, { Function: funct }); + return promisify(promise, success, error); + }; + this.getFunctionalEntitlementBranch = (funct, branch, success, error) => { + const promise = this._agmInvoke(GetFunctionalEntitlementMethodName, (e) => e.returned.Entitlement, { Function: funct, Branch: branch }); + return promisify(promise, success, error); + }; + this.canI = (func, success, error) => { + const promise = this._agmInvoke(CanIMethodName, (e) => e.returned.Result, { Function: func }); + return promisify(promise, success, error); + }; + this.canIBranch = (func, branch, success, error) => { + const promise = this._agmInvoke(CanIMethodName, (e) => e.returned.Result, { Function: func, Branch: branch }); + return promisify(promise, success, error); + }; + this.onBranchesChanged = (callback) => { + return this._registry.add("branchesChanged", callback); + }; + this.onBranchChanged = (callback) => { + return this._registry.add("branchChanged", callback); + }; + this.exit = (options) => { + return this._agmInvoke(ShutdownMethodName, null, options); + }; + this.onShuttingDown = (callback) => { + this.registerMethod(); + return this._registry.add("onShuttingDown", callback); + }; + this.restart = (options) => { + return this._agmInvoke(RestartMethodName, null, options); + }; + this._agmInvoke = (method, transformFunction, args) => { + args = args || {}; + return new Promise((resolve, reject) => { + const errHandler = (error) => reject(error); + this._agm.invoke(method, args, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }) + .then((result) => { + if (!transformFunction) { + transformFunction = (d) => d.returned; + } + resolve(transformFunction(result)); + }) + .catch(errHandler); + }); + }; + } + registerMethod() { + if (!this._isMethodRegistered) { + this._agm.register(OnGDShutdownMethodName, async (args) => { + try { + const results = await Promise.all(this._registry.execute("onShuttingDown", args)); + const prevent = results.some((r) => r.prevent); + return { prevent }; + } + catch (error) { + } + }); + this._isMethodRegistered = true; + } + } + } + + function snapshot(interop, appManager) { + return new Promise((resolve, reject) => { + interop.invoke(GetApplicationsMethodName, { skipIcon: true }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }) + .then((response) => { + var _a; + const data = response.returned; + const configuration = (_a = response.returned.configuration) !== null && _a !== void 0 ? _a : {}; + if (!data) { + resolve(configuration); + } + const applications = data.applications; + if (!applications) { + resolve(configuration); + } + objectValues(applications).map((item) => appManager.handleAppAdded(item)); + resolve(configuration); + }) + .catch((err) => reject(new Error(`Error getting application snapshot: ${err.message}`))); + }); + } + + const OnBranchChangedEvent = "OnBranchChanged"; + const OnBranchesModifiedEvent = "OnBranchesModified"; + const OnApplicationAddedEvent = "OnApplicationAdded"; + const OnApplicationRemovedEvent = "OnApplicationRemoved"; + const OnApplicationChangedEvent = "OnApplicationChanged"; + const OnApplicationReadyEvent = "OnApplicationReady"; + const OnApplicationStartedEvent = "OnApplicationStarted"; + const OnApplicationAgmServerReadyEvent = "OnApplicationAgmServerReady"; + const OnApplicationUpdatedEvent = "OnApplicationUpdated"; + const OnApplicationStoppedEvent = "OnApplicationStopped"; + const OnApplicationStartFailedEvent = "OnApplicationStartFailed"; + + function createDataSubscription(agm, applications, entitlements, skipIcons) { + let subscription; + let initiated = false; + const start = () => { + let resolveFunc; + let rejectFunc; + const resultPromise = new Promise((resolve, reject) => { + resolveFunc = resolve; + rejectFunc = reject; + }); + agm.subscribe(OnEventMethodName, { arguments: { skipIcon: skipIcons }, waitTimeoutMs: 10000 }) + .then((s) => { + subscription = s; + subscription.onData((streamData) => { + var _a; + const events = streamData.data; + const configuration = (_a = events.configuration) !== null && _a !== void 0 ? _a : {}; + const onApplicationAddedEventArgs = objectValues(events[OnApplicationAddedEvent]); + if (streamData.data.isSnapshot) { + applications.handleSnapshotAppsAdded(onApplicationAddedEventArgs); + } + else { + onApplicationAddedEventArgs.forEach((item) => applications.handleAppAdded(item)); + } + objectValues(events[OnApplicationChangedEvent]) + .forEach((item) => applications.handleAppUpdated(item)); + objectValues(events[OnApplicationRemovedEvent]) + .forEach((item) => applications.handleAppRemoved(item)); + objectValues(events[OnApplicationReadyEvent]) + .forEach((item) => applications.handleAppReady(item)); + const onApplicationStartedEventArgs = objectValues(events[OnApplicationStartedEvent]); + if (streamData.data.isSnapshot) { + applications.handleSnapshotInstanceStarted(onApplicationStartedEventArgs); + } + else { + onApplicationStartedEventArgs.forEach((item) => applications.handleInstanceStarted(item)); + } + objectValues(events[OnApplicationStartFailedEvent]) + .forEach((item) => applications.handleInstanceStartFailed(item)); + objectValues(events[OnApplicationStoppedEvent]) + .forEach((item) => applications.handleInstanceStopped(item)); + objectValues(events[OnApplicationUpdatedEvent]) + .forEach((item) => applications.handleInstanceUpdated(item)); + objectValues(events[OnApplicationAgmServerReadyEvent]) + .forEach((item) => applications.handleInstanceAgmServerReady(item)); + objectValues(events[OnBranchChangedEvent]) + .forEach((item) => entitlements.handleBranchModified(item)); + objectValues(events[OnBranchesModifiedEvent]) + .forEach((item) => entitlements.handleBranchesModified(item)); + if (!initiated) { + initiated = true; + const hasMyAppInSnapShot = onApplicationAddedEventArgs.some((a) => a.Name === agm.instance.application); + const hasMyInstanceInSnapShot = onApplicationStartedEventArgs.some((i) => i.Id === agm.instance.instance); + if (hasMyAppInSnapShot) { + if (hasMyInstanceInSnapShot) { + resolveFunc(configuration); + } + else { + const un = applications.onInstanceStarted((i) => { + if (i.id === agm.instance.instance) { + un(); + resolveFunc(configuration); + } + }); + } + } + else { + resolveFunc(configuration); + } + } + }); + subscription.onFailed((err) => rejectFunc(err)); + }) + .catch((err) => { var _a; return rejectFunc(`Error subscribing for ${OnEventMethodName} stream. Err: ${(_a = err.message) !== null && _a !== void 0 ? _a : JSON.stringify(err)}`); }); + return resultPromise; + }; + const stop = () => { + if (subscription) { + subscription.close(); + } + }; + return { + start, + stop + }; + } + + const InMemoryStoreCommandMethodName = "T42.ACS.InMemoryStoreCommand"; + class InMemoryStore { + constructor(interop) { + this.interop = interop; + } + import(apps, mode) { + if (!apps || !Array.isArray(apps)) { + return Promise.reject(new Error("invalid apps argument - should be an array of application definitions")); + } + if (mode && mode !== "replace" && mode !== "merge") { + return Promise.reject(new Error("invalid mode argument - should be 'replace' or 'merge'")); + } + mode = mode !== null && mode !== void 0 ? mode : "replace"; + const command = { + command: "import", + args: { + apps, + mode + } + }; + return this.interop.invoke(InMemoryStoreCommandMethodName, command, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }) + .then((r) => r.returned); + } + export() { + return this.interop.invoke(InMemoryStoreCommandMethodName, { command: "export" }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }) + .then((r) => r.returned.apps); + } + remove(app) { + if (!app || typeof app !== "string") { + return Promise.reject(new Error("invalid app name, should be a string value")); + } + const command = { + command: "remove", + args: { + apps: [app] + } + }; + return this.interop.invoke(InMemoryStoreCommandMethodName, command, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }).then((r) => r.returned); + } + clear() { + const command = { + command: "clear" + }; + return this.interop.invoke(InMemoryStoreCommandMethodName, command, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }).then((r) => r.returned); + } + createAppDef(name, url) { + if (!url) { + url = "https://google.com"; + } + return { + name, + type: "window", + title: name, + details: { + url + } + }; + } + } + + var AppManagerFactory = (config) => { + if (!config) { + throw Error("config not set"); + } + if (!config.agm) { + throw Error("config.agm is missing"); + } + const START_ONLY = "startOnly"; + const SKIP_ICONS = "skipIcons"; + const FULL = "full"; + const mode = config.mode || START_ONLY; + if (mode !== START_ONLY && mode !== SKIP_ICONS && mode !== FULL) { + throw new Error(`Invalid mode for appManager lib - ${mode} is not supported`); + } + const activities = config.activities; + const agm = config.agm; + const logger = config.logger; + const windows = config.windows; + let configuration = {}; + const appManager = new AppManagerImpl(mode, agm, activities, windows, logger.subLogger("applications"), config.gdMajorVersion, () => configuration); + const entitlements = new EntitlementsImpl(agm); + let readyPromise; + if (mode === START_ONLY) { + readyPromise = snapshot(agm, appManager); + } + else { + const subscription = createDataSubscription(agm, appManager, entitlements, mode === SKIP_ICONS); + readyPromise = subscription.start(); + } + const api = { + ready: () => readyPromise.then((c) => { configuration = c; }), + applications: appManager.applications, + application: appManager.application, + getConfigurations: appManager.getConfigurations, + onAppAdded: appManager.onAppAdded, + onAppRemoved: appManager.onAppRemoved, + onAppChanged: appManager.onAppChanged, + onAppAvailable: appManager.onAppAvailable, + onAppUnavailable: appManager.onAppUnavailable, + instances: appManager.instances, + get myInstance() { + return appManager.getMyInstance(); + }, + get myApplication() { + return appManager.getMyApplication(); + }, + onInstanceStarted: appManager.onInstanceStarted, + onInstanceStopped: appManager.onInstanceStopped, + onInstanceUpdated: appManager.onInstanceUpdated, + onInstanceStartFailed: appManager.onInstanceStartFailed, + getRegion: entitlements.getRegion, + getBranches: entitlements.getBranches, + getCurrentBranch: entitlements.getCurrentBranch, + getFunctionalEntitlement: entitlements.getFunctionalEntitlement, + getFunctionalEntitlementBranch: entitlements.getFunctionalEntitlementBranch, + setCurrentBranch: entitlements.setCurrentBranch, + setRegion: entitlements.setRegion, + currentUser: entitlements.currentUser, + canI: entitlements.canI, + canIBranch: entitlements.canIBranch, + onBranchesChanged: entitlements.onBranchesChanged, + exit: entitlements.exit, + restart: entitlements.restart, + onShuttingDown: entitlements.onShuttingDown, + inMemory: new InMemoryStore(agm) + }; + return api; + }; + + const T42JumpListAction = "T42.JumpList.Action"; + class JumpListManager { + constructor() { + this._groupActionCallbacks = new Map(); + this._registered = false; + } + init(executor, agm, logger) { + this._executor = executor; + this._agm = agm; + this._logger = logger; + this.registerCallbackMethod(); + } + setEnabled(windowId, enabled) { + const settings = { + enabled + }; + return this._executor.updateJumpList(windowId, settings); + } + createCategory(windowId, title, actions) { + this.validateActions(title, actions); + const settings = { + category: { + title, + operation: "create", + actions: this.toUpdateActions(windowId, "create", title, actions) + } + }; + return this._executor.updateJumpList(windowId, settings); + } + removeCategory(windowId, title) { + const settings = { + category: { + title, + operation: "remove", + actions: [] + } + }; + this.manageActionCallback(windowId, settings.category.operation, title); + return this._executor.updateJumpList(windowId, settings); + } + createActions(windowId, categoryTitle, actions) { + this.validateActions(categoryTitle, actions); + const settings = { + category: { + title: categoryTitle, + operation: "update", + actions: this.toUpdateActions(windowId, "create", categoryTitle, actions) + } + }; + return this._executor.updateJumpList(windowId, settings); + } + removeActions(windowId, categoryTitle, actions) { + const settings = { + category: { + title: categoryTitle, + operation: "update", + actions: this.toUpdateActions(windowId, "remove", categoryTitle, actions) + } + }; + return this._executor.updateJumpList(windowId, settings); + } + async getActions(windowId, catgoryTitle) { + const actions = []; + const configuration = await this.getJumpListSettings(windowId); + const currentCategory = configuration.categories.find((category) => category.title === catgoryTitle); + if (currentCategory) { + currentCategory.actions.forEach((action) => { + const actionCallback = this.getActionCallback(action.callbackId); + if (actionCallback) { + action.callback = actionCallback.callback; + } + actions.push({ + icon: action.icon, + callback: action.callback, + singleInstanceTitle: action.singleInstanceTitle, + multiInstanceTitle: action.multiInstanceTitle + }); + }); + } + return Promise.resolve(actions); + } + getJumpListSettings(windowId) { + return this._executor.getJumpList(windowId); + } + toUpdateActions(windowId, operation, categoryTitle, actions) { + return actions.map((action) => { + const updateAction = { + icon: action.icon, + callback: action.callback, + callbackId: Utils.generateId(), + singleInstanceTitle: action.singleInstanceTitle, + multiInstanceTitle: action.multiInstanceTitle, + operation + }; + this.manageActionCallback(windowId, operation, categoryTitle, updateAction); + return updateAction; + }); + } + manageActionCallback(windowId, operation, categoryTitle, updateAction) { + var _a; + const groupCallbacksKey = `${categoryTitle}-${windowId}`; + if (operation === "create") { + if (!this._groupActionCallbacks.has(groupCallbacksKey)) { + this._groupActionCallbacks.set(groupCallbacksKey, []); + } + const categoryActionCallbacks = this._groupActionCallbacks.get(groupCallbacksKey); + categoryActionCallbacks.push({ + callbackId: updateAction.callbackId, + callback: updateAction.callback + }); + } + else if (operation === "remove") { + if (updateAction) { + let categoryActionCallbacks = (_a = this._groupActionCallbacks.get(groupCallbacksKey)) !== null && _a !== void 0 ? _a : []; + categoryActionCallbacks = categoryActionCallbacks.filter((accCal) => accCal.callbackId !== updateAction.callbackId); + if (categoryActionCallbacks.length === 0) { + this._groupActionCallbacks.delete(groupCallbacksKey); + } + else { + this._groupActionCallbacks.set(groupCallbacksKey, categoryActionCallbacks); + } + } + else { + this._groupActionCallbacks.delete(groupCallbacksKey); + } + } + } + registerCallbackMethod() { + if (this._registered) { + return; + } + this._registered = true; + try { + this._agm.register(T42JumpListAction, (args, caller) => { + const actionCallback = this.getActionCallback(args.callbackId); + if (actionCallback) { + try { + actionCallback.callback(); + } + catch (e) { + this._logger.error("Unable to execute user callback for jump list action!", e); + } + } + }); + } + catch (e) { + this._logger.error(`Unable to register method ${T42JumpListAction} for invoking jump list action callbacks!`, e); + return Promise.reject(e); + } + } + getActionCallback(callbackId) { + let callbackAction; + [...this._groupActionCallbacks.values()].forEach((callbacks) => { + const callback = callbacks.find((cal) => cal.callbackId === callbackId); + if (callback) { + callbackAction = callback; + } + }); + return callbackAction; + } + validateActions(category, actions) { + if (!(actions && actions.length > 0)) { + throw new Error(`Category '${category}' doesn't contain any actions!`); + } + actions.forEach((action) => { + if (!action.singleInstanceTitle) { + throw new Error(`Category '${category}' contains an action with undefined singleInstanceTitle!`); + } + if (!action.multiInstanceTitle) { + throw new Error(`Category '${category}' contains an action with undefined multiInstanceTitle!`); + } + if (!action.callback) { + throw new Error(`Category '${category}' contains an action with undefined callback function!`); + } + }); + } + } + var jumpListManager = new JumpListManager(); + + class WindowStore { + constructor() { + this.waitForTimeoutInMilliseconds = 60000; + this._windows = {}; + this._pendingWindows = {}; + this._pendingWindowsStates = {}; + this._registry = CallbackRegistryFactory(); + } + init(logger) { + this._logger = logger; + } + get(id) { + return this._windows[id] || this._pendingWindows[id]; + } + getIfReady(id) { + return this._windows[id]; + } + get list() { + return this._windows; + } + add(window, state) { + const isExist = typeof this._pendingWindows[window.API.id] !== "undefined"; + if (isExist) { + this._logger.error(`trying to add window with id ${window.API.id} from windowStore, which already exists`); + return; + } + this._pendingWindows[window.API.id] = window; + this._pendingWindowsStates[window.API.id] = state; + this._registry.execute("on-added", window); + if (this.shouldMarkReadyToShow(state)) { + this.markReadyToShow(window.API.id); + } + } + remove(window) { + delete this._windows[window.API.id]; + delete this._pendingWindows[window.API.id]; + delete this._pendingWindowsStates[window.API.id]; + this._registry.execute("on-removed", window); + } + setUrlChangedState(windowId) { + const targetWindowState = this._pendingWindowsStates[windowId]; + if (typeof targetWindowState === "undefined") { + return; + } + targetWindowState.urlChanged = true; + if (this.shouldMarkReadyToShow(targetWindowState)) { + this.markReadyToShow(windowId); + } + } + setCompositionChangedState(wrapper) { + const windowId = wrapper.API.id; + const targetWindowState = this._pendingWindowsStates[windowId]; + if (typeof targetWindowState === "undefined") { + return; + } + targetWindowState.compositionChanged = true; + if (this.shouldMarkReadyToShow(targetWindowState)) { + this.markReadyToShow(windowId); + } + } + waitFor(id) { + return new Promise((resolve, reject) => { + let unReady; + let unRemoved; + const timeout = setTimeout(() => { + unReady(); + unRemoved(); + reject(new Error(`Window with id "${id}" was not ready within ${this.waitForTimeoutInMilliseconds} milliseconds.`)); + }, this.waitForTimeoutInMilliseconds); + const win = this._windows[id]; + if (win) { + clearTimeout(timeout); + resolve(win); + } + else { + const cleanup = () => { + clearTimeout(timeout); + unReady(); + unRemoved(); + }; + unReady = this.onReadyWindow((w) => { + if (w.API.id !== id) { + return; + } + cleanup(); + resolve(w); + }); + unRemoved = this.onRemoved((w) => { + if (w.API.id !== id) { + return; + } + cleanup(); + reject(new Error(`Window with id "${id}" was closed before it became ready.`)); + }); + } + }); + } + onReadyWindow(callback) { + return this._registry.add("on-ready", callback); + } + onAdded(callback) { + return this._registry.add("on-added", callback); + } + onRemoved(callback) { + return this._registry.add("on-removed", callback); + } + markReadyToShow(windowId) { + if (this._pendingWindows[windowId]) { + this._windows[windowId] = this._pendingWindows[windowId]; + delete this._pendingWindows[windowId]; + delete this._pendingWindowsStates[windowId]; + } + this._registry.execute("on-ready", this._windows[windowId]); + } + shouldMarkReadyToShow(targetWindowState) { + return targetWindowState && targetWindowState.urlChanged && targetWindowState.ready && targetWindowState.compositionChanged; + } + } + var windowStore = new WindowStore(); + + class JumpListActions { + constructor(windowId, configuration) { + this.windowId = windowId; + this._categoryTitle = configuration.title; + } + list() { + return jumpListManager.getActions(this.windowId, this._categoryTitle); + } + create(actions) { + return jumpListManager.createActions(this.windowId, this._categoryTitle, actions); + } + remove(actions) { + return jumpListManager.removeActions(this.windowId, this._categoryTitle, actions); + } + } + + class JumpListCategories { + constructor(windowId) { + this.windowId = windowId; + } + list() { + return this.getCategories(); + } + create(title, actions) { + return jumpListManager.createCategory(this.windowId, title, actions); + } + remove(title) { + return jumpListManager.removeCategory(this.windowId, title); + } + async find(title) { + const categories = await this.getCategories(); + return categories.find((cat) => cat.title === title); + } + async getCategories() { + const result = []; + const configuration = await jumpListManager.getJumpListSettings(this.windowId); + configuration.categories.forEach((category) => { + result.push({ + title: category.title, + actions: new JumpListActions(this.windowId, category) + }); + }); + return result; + } + } + + class JumpList { + constructor(windowId) { + this.windowId = windowId; + this._categories = new JumpListCategories(windowId); + } + get categories() { + return this._categories; + } + async isEnabled() { + const configuration = await jumpListManager.getJumpListSettings(this.windowId); + return configuration.enabled; + } + setEnabled(enabled) { + return jumpListManager.setEnabled(this.windowId, enabled); + } + } + + var windowFactory = (id, options, executor, logger, appManagerGetter, displayAPIGetter, channelsAPIGetter, agm) => { + var _a, _b, _c, _d; + const _registry = CallbackRegistryFactory(); + const getChannels = () => { + const channels = channelsAPIGetter(); + if (!channels) { + throw new Error(`To use this method you need to enable channels API - set the channels property to true when initializing the Glue42 library`); + } + return channels; + }; + const _id = id; + const _name = options.name; + const _mode = options.mode; + let _bounds = options.bounds; + let _url = options.url; + let _title = options.title; + let _context = (_a = options.context) !== null && _a !== void 0 ? _a : {}; + let _frameColor = options.frameColor; + let _focus = options.focus; + let _neighbours = (_b = options.neighbours) !== null && _b !== void 0 ? _b : {}; + let _groupId = options.groupId; + let _isGroupHeaderVisible = options.isGroupHeaderVisible; + let _isTabHeaderVisible = options.isTabHeaderVisible; + let _isGroupHibernated = options.isGroupHibernated; + let _isGroupVisible = options.isGroupVisible; + let _isTabSelected = (_c = options.isTabSelected) !== null && _c !== void 0 ? _c : false; + let _settings = options.settings; + const _applicationName = options.applicationName; + let _isVisible = options.isVisible; + let _isSticky = options.isSticky; + let _isCollapsed = options.isCollapsed; + let _windowState = options.state; + let _tabGroupId = options.tabGroupId; + let _tabIndex = options.tabIndex; + let _frameId = options.frameId; + let _isLocked = options.isLocked; + let _allowWorkspaceDrop = options.allowWorkspaceDrop; + let _isPinned = options.isPinned; + let _group; + let _frameButtons = (_d = options.frameButtons) !== null && _d !== void 0 ? _d : []; + let _zoomFactor = options.zoomFactor; + let _placementSettings = options.placementSettings; + const _jumpList = new JumpList(id); + function close(cbOrOptions, error) { + if (typeof cbOrOptions === "undefined" || typeof cbOrOptions === "function") { + return Utils.callbackifyPromise(() => { + if (!id) { + throw new Error("The window is already closed."); + } + return executor.close(resultWindow); + }, cbOrOptions, error); + } + else { + return executor.close(resultWindow, cbOrOptions); + } + } + function navigate(newUrl, optionsOrCallback, error) { + if (typeof optionsOrCallback === "function") { + return Utils.callbackifyPromise(() => { + if (isNullOrWhiteSpace(newUrl)) { + throw new Error("The new URL must be a non-empty string."); + } + return executor.navigate(resultWindow, newUrl); + }, optionsOrCallback, error); + } + if (isNullOrWhiteSpace(newUrl)) { + throw new Error("The new URL must be a non-empty string."); + } + if ((optionsOrCallback === null || optionsOrCallback === void 0 ? void 0 : optionsOrCallback.timeout) && typeof optionsOrCallback.timeout !== "number") { + throw new Error("Timeout argument must be a valid number"); + } + return executor.navigate(resultWindow, newUrl, optionsOrCallback); + } + function setStyle(style, success, error) { + return Utils.callbackifyPromise(() => { + if (!style || Object.keys(style).length === 0 || Object.keys(style).every((key) => !key)) { + throw new Error("Invalid style arguments: " + JSON.stringify(style)); + } + if (style && style.focus !== undefined) { + if (typeof style.focus !== "boolean") { + throw new Error("Focus must be a boolean value. Currently, only `focus: true` is supported."); + } + else if (style.focus === false) { + console.warn("`focus: false` is not supported!"); + } + } + if (style && style.hidden !== undefined && typeof style.hidden !== "boolean") { + throw new Error("The `hidden` property must hold a boolean value."); + } + for (const prop of ["minHeight", "maxHeight", "minWidth", "maxWidth"]) { + const styleAsAny = style; + const value = styleAsAny[prop]; + if (prop in style) { + if (isUndefinedOrNull(value)) { + delete styleAsAny[prop]; + continue; + } + if (!isNumber(styleAsAny[prop])) { + throw new Error(`"${prop}" must be a number`); + } + } + } + return executor.setStyle(resultWindow, style); + }, success, error); + } + function resetButtons(buttons, success, error) { + return Utils.callbackifyPromise(() => executor.resetButtons(resultWindow, buttons), success, error); + } + function getButtons() { + return executor.getButtons(resultWindow); + } + function setOnTop(onTop, success, error) { + return Utils.callbackifyPromise(() => { + if (typeof onTop === "string") { + if (onTop !== "always") { + throw new Error("`onTop` must hold a `always` value."); + } + } + else if (typeof onTop !== "boolean") { + throw new Error("`onTop` must hold a boolean or `always` value."); + } + return executor.setOnTop(resultWindow, onTop); + }, success, error); + } + function setSizeConstraints(constraints, success, error) { + return Utils.callbackifyPromise(() => { + if (!constraints || Object.keys(constraints).every((value) => value === undefined)) { + throw new Error("The properties of `constraints` cannot be null or undefined."); + } + return executor.setSizeConstraints(resultWindow, constraints); + }, success, error); + } + function getSizeConstraints() { + return executor.getSizeConstraints(resultWindow); + } + function setTitle(newTitle, success, error) { + return Utils.callbackifyPromise(() => { + if (isUndefinedOrNull(newTitle)) { + throw new Error("`newTitle` must not be null or undefined."); + } + if (newTitle === _title) { + return Promise.resolve(resultWindow); + } + return executor.setTitle(resultWindow, newTitle); + }, success, error); + } + function setSticky(isSticky, success, error) { + return Utils.callbackifyPromise(() => { + if (typeof isSticky !== "boolean") { + throw new Error("`isSticky` must hold a boolean value."); + } + return executor.setSticky(resultWindow, isSticky); + }, success, error); + } + function setAllowWorkspaceDrop(allowWorkspaceDrop) { + if (typeof allowWorkspaceDrop !== "boolean") { + throw new Error("`allowWorkspaceDrop` must hold a boolean value."); + } + return executor.setAllowWorkspaceDrop(resultWindow, allowWorkspaceDrop); + } + function pin() { + return executor.pin(resultWindow); + } + function unpin() { + return executor.unpin(resultWindow); + } + function moveResize(bounds, success, error) { + return Utils.callbackifyPromise(() => { + if (isUndefinedOrNull(bounds)) { + throw new Error("The properties of `bounds` cannot be null or undefined."); + } + return executor.moveResize(resultWindow, bounds); + }, success, error); + } + function addFrameButton(buttonInfo, success, error) { + return Utils.callbackifyPromise(() => { + if (typeof buttonInfo === "undefined" || Object.keys(buttonInfo).length === 0) { + throw new Error("Button info is not available."); + } + if (isNullOrWhiteSpace(buttonInfo.buttonId)) { + throw new Error("`buttonId` must not be null or undefined."); + } + if (isNullOrWhiteSpace(buttonInfo.imageBase64)) { + throw new Error("`imageBase64` must not be null or undefined."); + } + return executor.addFrameButton(resultWindow, buttonInfo); + }, success, error); + } + function removeFrameButton(buttonId, success, error) { + return Utils.callbackifyPromise(() => { + if (isNullOrWhiteSpace(buttonId)) { + throw new Error("`buttonId` must not be null or undefined."); + } + return executor.removeFrameButton(resultWindow, buttonId); + }, success, error); + } + function activate(success, error) { + return Utils.callbackifyPromise(() => { + if (_focus) { + return Promise.resolve(resultWindow); + } + return executor.activate(resultWindow); + }, success, error); + } + function focus(success, error) { + return Utils.callbackifyPromise(() => { + if (_focus) { + return Promise.resolve(resultWindow); + } + return executor.focus(resultWindow); + }, success, error); + } + function maximizeRestore(success, error) { + return Utils.callbackifyPromise(() => { + return executor.maximizeRestore(resultWindow); + }, success, error); + } + function maximize(success, error) { + return Utils.callbackifyPromise(() => { + if (_windowState === "maximized") { + return Promise.resolve(resultWindow); + } + return executor.maximize(resultWindow); + }, success, error); + } + function restore(success, error) { + return Utils.callbackifyPromise(() => { + if (_windowState === "normal") { + return Promise.resolve(resultWindow); + } + return executor.restore(resultWindow); + }, success, error); + } + function minimize(success, error) { + return Utils.callbackifyPromise(() => { + if (_windowState === "minimized") { + return Promise.resolve(resultWindow); + } + return executor.minimize(resultWindow); + }, success, error); + } + function collapse(success, error) { + return Utils.callbackifyPromise(() => { + if (_isCollapsed) { + return Promise.resolve(resultWindow); + } + return executor.collapse(resultWindow); + }, success, error); + } + function expand(success, error) { + return Utils.callbackifyPromise(() => { + if (!_isCollapsed) { + return Promise.resolve(resultWindow); + } + return executor.expand(resultWindow); + }, success, error); + } + function toggleCollapse(success, error) { + return Utils.callbackifyPromise(() => { + return executor.toggleCollapse(resultWindow); + }, success, error); + } + function snap(target, direction, success, error) { + return Utils.callbackifyPromise(() => { + if (isUndefinedOrNull(target)) { + throw new Error(`A target window is not specified - ${typeof target === "string" ? target : JSON.stringify(target)}`); + } + if (typeof target === "string") { + const win = windowStore.get(target); + if (!win) { + throw new Error(`Invalid "target" parameter or no such window. Invoked with: ${target}`); + } + target = win.API; + } + if (typeof direction === "string") { + direction = { + direction, + autoAlign: true + }; + } + return executor.snap(resultWindow, target, direction); + }, success, error); + } + function attachTab(tab, opt, success, error) { + return Utils.callbackifyPromise(() => { + var _a; + const errorMessage = `Invalid "tab" parameter - must be an object with an "id" property or a string. Invoked for source window with ID:`; + if (isUndefinedOrNull(tab)) { + const errMsg = `${errorMessage} ${typeof tab === "string" ? tab : JSON.stringify(tab)}`; + throw new Error(errMsg); + } + let sourceWindow; + if (typeof tab === "string") { + sourceWindow = (_a = windowStore.get(tab)) === null || _a === void 0 ? void 0 : _a.API; + if (isUndefinedOrNull(sourceWindow)) { + const errMsg = `${errorMessage} ${typeof sourceWindow === "string" ? sourceWindow : JSON.stringify(sourceWindow)}`; + throw new Error(errMsg); + } + } + else if (!isUndefinedOrNull(tab.id)) { + sourceWindow = tab; + } + else { + throw new Error(errorMessage); + } + const attachOptions = {}; + if (!isUndefinedOrNull(opt)) { + if (typeof opt === "number") { + attachOptions.index = opt; + } + else { + attachOptions.selected = opt.selected; + attachOptions.index = opt.index; + } + } + return executor.attachTab(resultWindow, sourceWindow, attachOptions); + }, success, error); + } + function detachTab(opt = {}, success, error) { + return Utils.callbackifyPromise(() => { + const argsForSend = {}; + function isDetachRelative(o) { + return o.relativeTo !== undefined; + } + if (isDetachRelative(opt)) { + if (typeof opt.relativeTo === "string") { + argsForSend.relativeTo = opt.relativeTo; + } + else if (!isUndefinedOrNull(opt.relativeTo.id)) { + argsForSend.relativeTo = opt.relativeTo.id; + } + if (!isUndefinedOrNull(opt.relativeDirection)) { + argsForSend.relativeDirection = opt.relativeDirection; + } + if (!isUndefinedOrNull(opt.width)) { + argsForSend.width = opt.width; + } + if (!isUndefinedOrNull(opt.height)) { + argsForSend.height = opt.height; + } + } + else { + if (!isUndefinedOrNull(opt.bounds)) { + argsForSend.bounds = opt.bounds; + } + } + if (!isUndefinedOrNull(opt.hideTabHeader)) { + argsForSend.hideTabHeader = opt.hideTabHeader; + } + return executor.detachTab(resultWindow, argsForSend); + }, success, error); + } + function setVisible(toBeVisible, success, error) { + return Utils.callbackifyPromise(() => { + return executor.setVisible(resultWindow, toBeVisible); + }, success, error); + } + async function center(display) { + if (display) { + validateCenterArguments(display); + } + return executor.center(resultWindow, display); + } + function validateCenterArguments(display) { + if (typeof display !== "object") { + throw Error("display argument must be a valid display object"); + } + if (!display.workArea || !display.scaleFactor) { + throw Error("display argument is not a valid display object"); + } + } + function showLoader(loader) { + return executor.showLoader(resultWindow, loader); + } + function hideLoader() { + return executor.hideLoader(resultWindow); + } + function updateContext(context, success, error) { + return Utils.callbackifyPromise(() => { + if (!isObject(context)) { + throw new Error(`"context" must not be null or undefined.`); + } + return executor.updateContext(resultWindow, context, false); + }, success, error); + } + function lock(success, error) { + return Utils.callbackifyPromise(() => { + return executor.lock(resultWindow); + }, success, error); + } + function unlock(success, error) { + return Utils.callbackifyPromise(() => { + return executor.unlock(resultWindow); + }, success, error); + } + function getIcon(success, error) { + return Utils.callbackifyPromise(() => { + return executor.getIcon(resultWindow); + }, success, error); + } + function setIcon(base64Image, success, error) { + return Utils.callbackifyPromise(() => { + if (isNullOrWhiteSpace(base64Image)) { + throw new Error(`"base64Image" must be a non-empty string.`); + } + return executor.setIcon(resultWindow, base64Image); + }, success, error); + } + function setFrameColor(frameColor, success, error) { + return Utils.callbackifyPromise(() => { + if (isNullOrWhiteSpace(frameColor)) { + throw new Error(`"frameColor" must be a non-empty string`); + } + return executor.setFrameColor(resultWindow, frameColor); + }, success, error); + } + function setTabHeaderVisible(toBeTabHeaderVisible, success, error) { + return Utils.callbackifyPromise(() => { + if (typeof toBeTabHeaderVisible !== "boolean") { + throw new Error(`"toBeTabHeaderVisible" must hold a boolean value.`); + } + return executor.setTabHeaderVisible(resultWindow, toBeTabHeaderVisible); + }, success, error); + } + async function setTabTooltip(tooltip) { + if (isNullOrWhiteSpace(tooltip)) { + throw new Error(`"${tooltip}" must not be null or undefined`); + } + return executor.setTabTooltip(resultWindow, tooltip); + } + async function getTabTooltip() { + return executor.getTabTooltip(resultWindow); + } + function showPopup(config) { + return executor.showPopup(resultWindow, config); + } + function createFlydown(config) { + return executor.createFlydown(resultWindow.id, config); + } + function setModalState(isModal) { + return executor.setModalState(resultWindow.id, isModal || false); + } + function zoomIn(success, error) { + return Utils.callbackifyPromise(() => { + return executor.zoomIn(resultWindow); + }, success, error); + } + function zoomOut(success, error) { + return Utils.callbackifyPromise(() => { + return executor.zoomOut(resultWindow); + }, success, error); + } + function setZoomFactor(zoomFactor, success, error) { + return Utils.callbackifyPromise(() => { + if (isNaN(zoomFactor)) { + throw new Error(`zoomFactor is not a number`); + } + return executor.setZoomFactor(resultWindow, zoomFactor); + }, success, error); + } + function showDevTools() { + return executor.showDevTools(resultWindow); + } + function capture(captureOptions) { + return executor.capture(resultWindow, captureOptions); + } + function flash(suppliedOptions, mode) { + const flashOptions = { + shouldFlash: true, + mode: "auto" + }; + if (typeof suppliedOptions === "boolean") { + flashOptions.shouldFlash = suppliedOptions; + } + if (typeof mode !== "undefined") { + flashOptions.mode = mode; + } + return executor.flash(resultWindow, flashOptions); + } + function flashTab(suppliedOptions) { + const flashOptions = { + shouldFlash: true, + }; + if (typeof suppliedOptions === "boolean") { + flashOptions.shouldFlash = suppliedOptions; + } + return executor.flashTab(resultWindow, flashOptions); + } + function print(printOptions) { + return executor.print(resultWindow, printOptions); + } + function printToPDF(printToPDFOptions) { + return executor.printToPDF(resultWindow, printToPDFOptions); + } + function ungroup(ungroupOptions) { + return new Promise((resolve, reject) => { + const unGroupChanged = onGroupChanged((win, newGroup, oldGroup) => { + if (id === win.id) { + unGroupChanged(); + resolve(resultWindow); + } + }); + executor.ungroup(resultWindow, ungroupOptions) + .catch((e) => { + unGroupChanged(); + reject(e); + }); + }); + } + function place(placementSettings) { + return executor.place(resultWindow, placementSettings); + } + function refresh(ignoreCache) { + return executor.refresh(resultWindow, ignoreCache); + } + function download(url, opts) { + return executor.download(resultWindow, url, opts); + } + function configure(settings) { + return executor.configureWindow(resultWindow, settings); + } + function getConfiguration() { + return executor.getWindowConfiguration(resultWindow); + } + function getDockingPlacement() { + return executor.getDockingPlacement(resultWindow); + } + function dock(opts) { + return executor.dock(resultWindow, opts); + } + async function clone(cloneOptions) { + return executor.clone(resultWindow, cloneOptions); + } + async function executeCode(code) { + if (!code) { + throw new Error("Code argument is missing"); + } + if (typeof code !== "string") { + throw new Error("Code argument must be a valid string"); + } + const response = await executor.executeCode(resultWindow, code); + return response.result; + } + function onTitleChanged(callback) { + if (!isFunction(callback)) { + throw new Error("callback should be a function"); + } + callback(resultWindow.title, resultWindow); + return onEventCore("onTitleChanged", callback); + } + function onClose(callback) { + if (!isFunction(callback)) { + throw new Error("callback should be a function"); + } + if (id === undefined) { + callback(resultWindow); + } + return _registry.add("onClose", callback); + } + function onUrlChanged(callback) { + return onEventCore("onUrlChanged", callback); + } + function onFrameButtonAdded(callback) { + return onEventCore("onFrameButtonAdded", callback); + } + function onFrameButtonRemoved(callback) { + return onEventCore("onFrameButtonRemoved", callback); + } + function onFrameButtonClicked(callback) { + return onEventCore("onFrameButtonClicked", callback); + } + function onCollapsed(callback) { + if (!isFunction(callback)) { + throw new Error("callback should be a function"); + } + if (_isCollapsed) { + callback(resultWindow); + } + return _registry.add("collapsed", callback); + } + function onExpanded(callback) { + if (!isFunction(callback)) { + throw new Error("callback should be a function"); + } + if (!_isCollapsed) { + callback(resultWindow); + } + return _registry.add("expanded", callback); + } + function onMaximized(callback) { + if (_windowState === "maximized") { + return onEventCore("maximized", callback, [resultWindow]); + } + else { + return onEventCore("maximized", callback); + } + } + function onMinimized(callback) { + if (_windowState === "minimized") { + return onEventCore("minimized", callback, [resultWindow]); + } + else { + return onEventCore("minimized", callback); + } + } + function onNormal(callback) { + if (_windowState === "normal") { + return onEventCore("normal", callback, [resultWindow]); + } + else { + return onEventCore("normal", callback); + } + } + function onAttached(callback) { + return onEventCore("attached", callback); + } + function onDetached(callback) { + return onEventCore("detached", callback); + } + function onVisibilityChanged(callback) { + return onEventCore("visibility-changed", callback); + } + function onContextUpdated(callback) { + return onEventCore("context-updated", callback); + } + function onLockingChanged(callback) { + return onEventCore("lock-changed", callback); + } + function onBoundsChanged(callback) { + return onEventCore("bounds-changed", callback); + } + function onFocusChanged(callback) { + return onEventCore("focus-changed", callback); + } + function onStickyChanged(callback) { + return onEventCore("sticky-changed", callback); + } + function onFrameColorChanged(callback) { + return onEventCore("frame-color-changed", callback); + } + function onTabHeaderVisibilityChanged(callback) { + return onEventCore("tab-header-visibility-changed", callback); + } + function onWindowAttached(callback) { + return onEventCore("window-attached", callback); + } + function onWindowDetached(callback) { + return onEventCore("window-detached", callback); + } + function onGroupChanged(callback) { + return onEventCore("group-changed", callback); + } + function onTabSelectionChanged(callback) { + return onEventCore("tab-selection-changed", callback); + } + function onChannelRestrictionsChanged(callback) { + if (!isFunction(callback)) { + throw new Error("callback must be a function"); + } + return onEventCore("channel-restrictions-changed", callback); + } + function onClosing(callback) { + if (!isFunction(callback)) { + throw new Error("callback must be a function"); + } + const callbackWrap = (success, error, prevent) => { + const promise = callback(prevent); + if (promise === null || promise === void 0 ? void 0 : promise.then) { + promise.then(success).catch(error); + } + else { + success(); + } + }; + return executor.onClosing(callbackWrap, resultWindow); + } + function onRefreshing(callback) { + if (!isFunction(callback)) { + throw new Error("callback must be a function"); + } + const callbackWrap = (success, error, prevent) => { + const promise = callback(prevent); + if (promise === null || promise === void 0 ? void 0 : promise.then) { + promise.then(success).catch(error); + } + else { + success(); + } + }; + return executor.onRefreshing(callbackWrap, resultWindow); + } + function onNavigating(callback) { + if (!isFunction(callback)) { + throw new Error("callback must be a function"); + } + const callbackWrap = (success, error, prevent, args) => { + const promise = callback(args); + if (promise === null || promise === void 0 ? void 0 : promise.then) { + promise.then(success).catch(error); + } + else { + success(); + } + }; + return executor.onNavigating(callbackWrap, resultWindow); + } + function onZoomFactorChanged(callback) { + return onEventCore("zoom-factor-changed", callback); + } + function onPlacementSettingsChanged(callback) { + return onEventCore("placementSettingsChanged", callback); + } + function onNeighboursChanged(callback) { + return onEventCore("neighbours-changed", callback); + } + function onDockingChanged(callback) { + return onEventCore("docking-changed", callback); + } + function onEventCore(key, callback, replayArguments) { + if (!isFunction(callback)) { + throw new Error("callback must be a function"); + } + return _registry.add(key, callback, replayArguments); + } + function goBack() { + return executor.goBack(resultWindow); + } + function goForward() { + return executor.goForward(resultWindow); + } + function startDrag(option) { + return executor.startDrag(resultWindow, option); + } + function showDialog(dialogOptions) { + if ((dialogOptions === null || dialogOptions === void 0 ? void 0 : dialogOptions.timerDuration) && isNaN(dialogOptions === null || dialogOptions === void 0 ? void 0 : dialogOptions.timerDuration)) { + throw new Error("timerDuration must be a number"); + } + if ((dialogOptions === null || dialogOptions === void 0 ? void 0 : dialogOptions.showTimer) && typeof (dialogOptions === null || dialogOptions === void 0 ? void 0 : dialogOptions.showTimer) !== "boolean") { + throw new Error("showTimer must be a boolean"); + } + return executor.showDialog(resultWindow, dialogOptions); + } + function handleUpdate(updated) { + _url = updated.url; + _title = updated.title; + _context = updated.context || {}; + _bounds = updated.bounds; + _frameColor = updated.frameColor; + _focus = updated.focus; + _neighbours = updated.neighbours || {}; + _groupId = updated.groupId; + _isGroupHeaderVisible = updated.isGroupHeaderVisible; + _isTabHeaderVisible = updated.isTabHeaderVisible; + _isGroupHibernated = updated.isGroupHibernated; + _isGroupVisible = updated.isGroupVisible; + _isTabSelected = updated.isTabSelected; + _settings = updated.settings; + _isVisible = updated.isVisible; + _isSticky = updated.isSticky; + _isCollapsed = updated.isCollapsed; + _windowState = updated.state; + _tabGroupId = updated.tabGroupId; + _frameId = updated.frameId; + _isLocked = updated.isLocked; + _allowWorkspaceDrop = updated.allowWorkspaceDrop; + _isPinned = updated.isPinned; + _zoomFactor = updated.zoomFactor; + _placementSettings = updated.placementSettings; + } + function handleTitleChanged(newTitle) { + _title = newTitle; + executor.finished + .finally(() => { + _registry.execute("onTitleChanged", newTitle, resultWindow); + }); + } + function handleUrlChanged(newUrl) { + _url = newUrl; + _registry.execute("onUrlChanged", newUrl, resultWindow); + } + function handleVisibilityChanged(isVisible) { + if (isVisible === _isVisible) { + return; + } + _isVisible = isVisible; + _registry.execute("visibility-changed", resultWindow); + } + function handleWindowSettingsChanged(settings) { + _settings = settings; + _registry.execute("settings-changed", resultWindow); + } + function handleContextUpdated(context) { + _context = context; + _registry.execute("context-updated", _context, resultWindow); + } + function handleWindowClose() { + if (id === undefined) { + return; + } + _registry.execute("onClose", resultWindow); + id = undefined; + } + function handleFrameButtonAdded(frameButton) { + const buttonObj = ["buttonId", "imageBase64", "order", "tooltip"].reduce((memo, k) => { + memo[k] = frameButton[k]; + return memo; + }, {}); + const frameButtonsIds = _frameButtons.map((btn) => { + return btn.buttonId; + }); + if (frameButtonsIds.indexOf(frameButton.buttonId) === -1) { + _frameButtons.push(buttonObj); + } + _registry.execute("onFrameButtonAdded", buttonObj, resultWindow); + } + function handleFrameButtonRemoved(frameButtonId) { + let button; + _frameButtons = _frameButtons.reduce((memo, btn) => { + if (btn.buttonId === frameButtonId) { + button = btn; + } + else { + memo.push(btn); + } + return memo; + }, []); + if (button !== undefined) { + _registry.execute("onFrameButtonRemoved", button, resultWindow); + } + } + function handleFrameButtonClicked(frameButton) { + const button = _frameButtons.filter((btn) => { + return btn.buttonId === frameButton.buttonId; + }); + if (button.length > 0) { + _registry.execute("onFrameButtonClicked", button[0], resultWindow); + } + } + async function handleWindowChangeState(state) { + if (state === "collapsed") { + _isCollapsed = true; + } + else if (state === "expanded") { + _isCollapsed = false; + } + else { + _windowState = state; + } + await executor.finished; + _registry.execute(state, resultWindow); + } + function handleFrameIsLockedChanged(isLocked) { + _isLocked = isLocked; + _registry.execute("lock-changed", resultWindow); + } + function handleBoundsChanged(bounds) { + if (_bounds.top === bounds.top && _bounds.left === bounds.left && _bounds.width === bounds.width && _bounds.height === bounds.height) { + return; + } + _bounds = bounds; + _registry.execute("bounds-changed", resultWindow); + } + function handleFocusChanged(isFocused) { + _focus = isFocused; + _registry.execute("focus-changed", resultWindow); + } + function handleIsStickyChanged(isSticky) { + _isSticky = isSticky; + _registry.execute("sticky-changed", isSticky, resultWindow); + } + function handleFrameColorChanged(frameColor) { + _frameColor = frameColor; + _registry.execute("frame-color-changed", resultWindow); + } + function handleFrameAttached(tabGroupId, frameId, isTabHeaderVisible) { + _tabGroupId = tabGroupId; + _frameId = frameId; + _isTabHeaderVisible = isTabHeaderVisible; + _registry.execute("frame-attached", resultWindow); + } + function handleCompositionChanged(state) { + _neighbours = state.neighbors || {}; + _tabIndex = state.index; + _registry.execute("neighbours-changed", _neighbours, resultWindow); + } + function handleAllowWorkspaceDropChanged(allowWorkspaceDrop) { + _allowWorkspaceDrop = allowWorkspaceDrop; + _registry.execute("allow-workspace-drop-changed", resultWindow); + } + function handleIsPinnedChanged(isPinned) { + _isPinned = isPinned; + _registry.execute("is-pinned-changed", resultWindow); + } + function handleGroupHeaderVisibilityChanged(isGroupHeaderVisible) { + _isGroupHeaderVisible = isGroupHeaderVisible; + } + function handleTabHeaderVisibilityChanged(isTabHeaderVisible) { + if (_isTabHeaderVisible !== isTabHeaderVisible) { + _isTabHeaderVisible = isTabHeaderVisible; + _registry.execute("tab-header-visibility-changed", resultWindow); + } + } + async function handleFrameSelectionChanged(newWindow, prevWindow) { + let selectedWindow; + if (newWindow === id) { + _isTabSelected = true; + selectedWindow = resultWindow; + } + else { + _isTabSelected = false; + selectedWindow = windowStore.get(newWindow) ? windowStore.get(newWindow).API : undefined; + } + const previousWindow = windowStore.get(prevWindow) ? windowStore.get(prevWindow).API : undefined; + await executor.finished; + _registry.execute("tab-selection-changed", selectedWindow, previousWindow, resultWindow); + } + async function handleAttached(newTabGroupId, newFrameId, tabHeaderVisible, isLocked, winsToBeNotified) { + _tabGroupId = newTabGroupId; + _isTabHeaderVisible = tabHeaderVisible; + _frameId = newFrameId; + if (typeof isLocked !== "undefined") { + _isLocked = isLocked; + } + await executor.finished; + winsToBeNotified.forEach((w) => { + w.Events.handleWindowAttached(resultWindow); + }); + _registry.execute("attached", resultWindow); + } + function handleWindowAttached(win) { + _registry.execute("window-attached", win); + } + async function handleDetached(isLocked, winsToBeNotified) { + _tabGroupId = undefined; + _isTabSelected = false; + if (typeof isLocked !== "undefined") { + _isLocked = isLocked; + } + await executor.finished; + winsToBeNotified.forEach((w) => { + w.Events.handleWindowDetached(resultWindow); + }); + _registry.execute("detached", resultWindow); + } + function handleWindowDetached(win) { + _registry.execute("window-detached", win); + } + function handleZoomFactorChanged(zoomFactor) { + _zoomFactor = zoomFactor; + _registry.execute("zoom-factor-changed", resultWindow); + } + function handlePlacementSettingsChanged(placementSettings) { + let promise; + const copy = placementSettings; + if (!copy.display) { + promise = Promise.resolve(undefined); + } + else { + const displayAPI = displayAPIGetter(); + if (!displayAPI) { + promise = Promise.resolve(undefined); + } + else { + const index = copy.display - 1; + promise = new Promise((resolve, reject) => { + displayAPI.all().then((displays) => { + const display = displays.find((d) => d.index === index); + resolve(display); + }).catch(reject); + }); + } + } + void promise.then((d) => { + copy.display = d; + _placementSettings = copy; + _registry.execute("placementSettingsChanged", resultWindow); + }); + } + function handleDockingChanged(data) { + _registry.execute("docking-changed", resultWindow, { + docked: data.docked, + position: data.position, + claimScreenArea: data.claimScreenArea + }); + } + function handleChannelRestrictionsChanged(data) { + _registry.execute("channel-restrictions-changed", data); + } + function handleGroupChanged(newGroup, oldGroup) { + _group = newGroup; + _groupId = newGroup === null || newGroup === void 0 ? void 0 : newGroup.id; + if (!isUndefinedOrNull(newGroup) && !isUndefinedOrNull(oldGroup)) { + _registry.execute("group-changed", resultWindow, newGroup, oldGroup); + } + } + function getAllTabs() { + const allWindows = windowStore.list; + if (_mode.toLowerCase() !== "tab") { + return []; + } + const tabs = Object.keys(allWindows).reduce((memo, win) => { + const window = allWindows[win]; + if (window + && window.API.tabGroupId + && typeof window.API.tabGroupId !== "undefined" + && typeof resultWindow.tabGroupId !== "undefined" + && window.API.tabGroupId === resultWindow.tabGroupId) { + memo.push(window.API); + } + return memo; + }, []); + return tabs.sort((w1, w2) => { + if (w1.tabIndex !== w2.tabIndex) { + if (w1.tabIndex === -1) { + return Number.MAX_SAFE_INTEGER; + } + if (w2.tabIndex === -1) { + return Number.MIN_SAFE_INTEGER; + } + } + return w1.tabIndex - w2.tabIndex; + }); + } + function mapWindowIdsToWindowObjects(windowIdArr) { + return windowIdArr.reduce((memo, winId) => { + const window = windowStore.get(winId); + if (window) { + memo.push(window.API); + } + return memo; + }, []); + } + function getNeighboursByDirection(direction) { + const windowIds = _neighbours[direction]; + if (typeof windowIds !== "undefined") { + return mapWindowIdsToWindowObjects(windowIds); + } + } + function getApplicationName() { + var _a; + if (_applicationName) { + return _applicationName; + } + if (_context._APPLICATION_NAME) { + return _context._APPLICATION_NAME; + } + if (_context && _context._t42 && _context._t42.application) { + return _context._t42.application; + } + const info = getWindowInfo(); + if (info && info.applicationName) { + return info.applicationName; + } + const appManager = appManagerGetter(); + if (appManager) { + const instance = appManager.instances().find((i) => id === i.id); + if (instance) { + return (_a = instance.application) === null || _a === void 0 ? void 0 : _a.name; + } + } + return undefined; + } + function getWindowInfo() { + if (typeof window !== "undefined" && window.glue42gd && window.glue42gd.getWindowInfo) { + const info = window.glue42gd.getWindowInfo(id); + if (!info) { + return undefined; + } + else { + return info; + } + } + } + const resultWindow = { + get id() { + return _id; + }, + get name() { + return _name; + }, + get application() { + const appManager = appManagerGetter(); + const appName = getApplicationName(); + if (appName && appManager) { + return appManager.application(appName); + } + }, + get hostInstance() { + return executor.hostInstance; + }, + get interopInstance() { + const instance = agm.servers().find((s) => s.windowId === this.id); + if (instance) { + return instance; + } + else { + const appName = getApplicationName(); + if (appName) { + return { application: appName }; + } + } + }, + get agmInstance() { + return resultWindow.interopInstance; + }, + get url() { + return _url; + }, + get title() { + return _title; + }, + get windowStyleAttributes() { + return _settings; + }, + get settings() { + return _settings; + }, + get tabGroupId() { + return _mode.toLowerCase() === "tab" ? _tabGroupId : undefined; + }, + get tabIndex() { + return _mode.toLowerCase() === "tab" ? _tabIndex : undefined; + }, + get frameId() { + return _frameId; + }, + get frameButtons() { + return _frameButtons.sort((b1, b2) => b1.order - b2.order); + }, + get mode() { + return _mode; + }, + get state() { + return _windowState; + }, + get isCollapsed() { + return _isCollapsed; + }, + get isVisible() { + return _isVisible; + }, + get isLocked() { + return _isLocked; + }, + get context() { + return _context; + }, + get bounds() { + return _bounds; + }, + get minHeight() { + return _settings.minHeight; + }, + get maxHeight() { + return _settings.maxHeight; + }, + get minWidth() { + return _settings.minWidth; + }, + get maxWidth() { + return _settings.maxWidth; + }, + get isFocused() { + return _focus; + }, + get frameColor() { + return _frameColor; + }, + get opened() { + return resultWindow.id !== undefined; + }, + get group() { + return _group; + }, + get groupId() { + return _groupId; + }, + get isSticky() { + return _isSticky; + }, + get topNeighbours() { + return getNeighboursByDirection("top"); + }, + get leftNeighbours() { + return getNeighboursByDirection("left"); + }, + get rightNeighbours() { + return getNeighboursByDirection("right"); + }, + get bottomNeighbours() { + return getNeighboursByDirection("bottom"); + }, + get isGroupHeaderVisible() { + return _isGroupHeaderVisible; + }, + get activityId() { + if (_context._t42) { + return _context._t42.activityId; + } + const info = getWindowInfo(); + if (!info) { + return undefined; + } + return info.activityId; + }, + get activityWindowId() { + if (_context._t42) { + return _context._t42.activityWindowId; + } + const info = getWindowInfo(); + if (!info) { + return undefined; + } + return info.activityWindowId; + }, + get windowType() { + return options.windowType || "electron"; + }, + get zoomFactor() { + return _zoomFactor; + }, + get screen() { + if (typeof window !== "undefined" && window.glue42gd) { + return Utils.getMonitor(resultWindow.bounds, window.glue42gd.monitors); + } + return undefined; + }, + get placementSettings() { + return Object.assign({}, _placementSettings); + }, + get jumpList() { + return _jumpList; + }, + get allowWorkspaceDrop() { + return _allowWorkspaceDrop; + }, + get isPinned() { + return _isPinned; + }, + maximize, + restore, + minimize, + maximizeRestore, + collapse, + expand, + toggleCollapse, + focus, + activate, + moveResize, + setTitle, + setStyle, + setOnTop, + resetButtons, + getButtons, + setSizeConstraints, + getSizeConstraints, + navigate, + addFrameButton, + removeFrameButton, + setVisible, + show: () => setVisible(true), + hide: () => setVisible(false), + center, + close, + snap, + showLoader, + hideLoader, + updateContext, + lock, + unlock, + getIcon, + setIcon, + setFrameColor, + setTabTooltip, + getTabTooltip, + attachTab, + detachTab, + setTabHeaderVisible, + showPopup, + createFlydown, + setModalState, + setZoomFactor, + zoomIn, + zoomOut, + showDevTools, + capture, + flash, + flashTab, + setSticky, + setAllowWorkspaceDrop, + pin, + unpin, + print, + printToPDF, + place, + ungroup, + refresh, + goBack, + goForward, + download, + configure, + getConfiguration, + getDockingPlacement, + dock, + clone, + executeCode, + getChannel: async () => { + var _a; + const wins = await getChannels().getWindowsWithChannels({ windowIds: [_id] }); + return (_a = wins[0]) === null || _a === void 0 ? void 0 : _a.channel; + }, + startDrag, + showDialog, + onClose, + onUrlChanged, + onTitleChanged, + onFrameButtonAdded, + onFrameButtonRemoved, + onFrameButtonClicked, + onCollapsed, + onExpanded, + onMinimized, + onMaximized, + onNormal, + onAttached, + onDetached, + onVisibilityChanged, + onContextUpdated, + onLockingChanged, + onBoundsChanged, + onFrameColorChanged, + onFocusChanged, + onStickyChanged, + onGroupChanged, + onWindowAttached, + onWindowDetached, + onTabSelectionChanged, + onTabHeaderVisibilityChanged, + onClosing, + onRefreshing, + onZoomFactorChanged, + onPlacementSettingsChanged, + onNeighboursChanged, + onDockingChanged, + onNavigating, + onChannelRestrictionsChanged, + get tabs() { + return getAllTabs(); + }, + get isTabHeaderVisible() { + return _isTabHeaderVisible; + }, + get isTabSelected() { + return _isTabSelected; + }, + getURL() { + return Promise.resolve(_url); + }, + getTitle() { + return Promise.resolve(_title); + }, + getBounds() { + return Promise.resolve(_bounds); + }, + getContext() { + return Promise.resolve(_context); + }, + setContext(context) { + if (!isObject(context)) { + throw new Error(`"context" must not be null or undefined, set to empty object if you want to clear it out.`); + } + return executor.updateContext(resultWindow, context, true); + }, + getDisplay() { + const displayAPI = displayAPIGetter(); + return displayAPI.getByWindowId(id); + }, + resizeTo(width, height) { + return moveResize({ width, height }); + }, + moveTo(top, left) { + return moveResize({ top, left }); + }, + async getParentWindow() { + var _a; + const myParentId = _settings.parentInstanceId; + if (!myParentId) { + return undefined; + } + return (_a = windowStore.list[myParentId]) === null || _a === void 0 ? void 0 : _a.API; + }, + async getChildWindows() { + return Object.keys(windowStore.list) + .map((key) => windowStore.list[key].API) + .filter((w) => { + const parentId = w.settings.parentInstanceId; + return parentId === id; + }); + }, + joinChannel: (name) => { + return getChannels().join(name, id); + }, + leaveChannel: () => { + return getChannels().leave(id); + } + }; + const events = { + handleUpdate, + handleWindowClose, + handleWindowChangeState, + handleTitleChanged, + handleVisibilityChanged, + handleUrlChanged, + handleWindowSettingsChanged, + handleContextUpdated, + handleFrameIsLockedChanged, + handleBoundsChanged, + handleFocusChanged, + handleFrameButtonAdded, + handleFrameButtonRemoved, + handleFrameButtonClicked, + handleFrameColorChanged, + handleFrameAttached, + handleFrameSelectionChanged, + handleCompositionChanged, + handleAllowWorkspaceDropChanged, + handleIsPinnedChanged, + handleGroupHeaderVisibilityChanged, + handleTabHeaderVisibilityChanged, + handleGroupChanged, + handleAttached, + handleDetached, + handleWindowAttached, + handleWindowDetached, + handleZoomFactorChanged, + handleIsStickyChanged, + handlePlacementSettingsChanged, + handleDockingChanged, + handleChannelRestrictionsChanged + }; + const groupArgs = { + get isGroupHibernated() { + return _isGroupHibernated; + }, + get isGroupVisible() { + return _isGroupVisible; + }, + }; + return { + API: resultWindow, + Events: events, + GroupCreationArgs: groupArgs + }; + }; + + function getWindowsByTabGroupId(windowId, tabGroupId) { + const windows = windowStore.list; + return Object.keys(windows).reduce((memo, id) => { + const win = windows[id]; + if (win.API.tabGroupId === tabGroupId && win.API.id !== windowId) { + memo.push(win); + } + return memo; + }, []); + } + function isEmpty(object) { + if (!object || Object.keys(object).every((value) => object[value] === undefined)) { + return true; + } + return false; + } + + class GDExecutor { + constructor() { + this.GroupMethodName = "T42.Group.Execute"; + this.WndMethodName = "T42.Wnd.Execute"; + this._registry = CallbackRegistryFactory(); + this._finished = Promise.resolve(); + this._configuration = { + windowAvailableOnURLChanged: true + }; + this.unsubCallbacks = {}; + } + get hostInstance() { + return this.agmTarget; + } + get finished() { + return this._finished; + } + get configuration() { + return this._configuration; + } + init(agm, instance) { + this.agm = agm; + this.agmTarget = instance; + this._registry.add("event", (data) => { + if (data.type === "Closed") { + const keys = Object.keys(this.unsubCallbacks); + keys.forEach((key) => { + const isSameWindow = key.startsWith(data.windowId); + if (isSameWindow) { + delete this.unsubCallbacks[key]; + } + }); + } + }); + } + setConfiguration(config) { + this._configuration = { ...this._configuration, ...config }; + } + handleEvent(data) { + this._registry.execute("event", data); + } + async open(options) { + let finishedResolve; + this._finished = new Promise((resolve) => { + finishedResolve = resolve; + }); + try { + const result = await this.agm.invoke("T42.Wnd.Create", options, this.agmTarget, { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_RESPONSE_TIMEOUT_MS + }); + if (result.returned === undefined) { + throw new Error("failed to execute T42.Wnd.Create - unknown reason"); + } + const id = result.returned.id; + const win = await windowStore.waitFor(id); + if (!this.configuration || this.configuration.windowAvailableOnURLChanged) { + setTimeout(() => { + if (win.API.windowType === "electron") { + win.Events.handleUrlChanged(win.API.url); + } + }, 0); + } + return win.API; + } + finally { + finishedResolve(); + } + } + async close(w, options) { + const result = await this.execute("close", { windowId: w.id, options }, `Closed`); + if (options) { + return result.closed; + } + return w; + } + async navigate(w, newUrl, urlLoadOptions) { + let methodResponseTimeoutMs = 120000; + if (typeof urlLoadOptions === "object" && typeof urlLoadOptions.timeout === "number") { + methodResponseTimeoutMs = urlLoadOptions.timeout * 1000; + delete urlLoadOptions.timeout; + } + await this.execute("navigate", { windowId: w.id, options: { url: newUrl, urlLoadOptions }, invocationOptions: { methodResponseTimeoutMs } }, "UrlChanged"); + return w; + } + async setStyle(w, style) { + var _a; + const stylePromises = []; + const wait = (promise) => stylePromises.push(promise); + if (!isUndefinedOrNull(style.focus) && !w.isFocused) { + wait(w.focus()); + } + if (!isUndefinedOrNull(style.hidden)) { + const toBeVisible = !style.hidden; + wait(w.setVisible(toBeVisible)); + } + if (!isUndefinedOrNull(style.onTop)) { + wait(w.setOnTop(style.onTop)); + } + if (!isNullOrWhiteSpace(style.tabTooltip) || !isNullOrWhiteSpace(style.tabToolTip)) { + const toolTip = (_a = style.tabTooltip) !== null && _a !== void 0 ? _a : style.tabToolTip; + wait(w.setTabTooltip(toolTip)); + } + if (!isNullOrWhiteSpace(style.tabTitle)) { + wait(this.execute("setTabTitle", { windowId: w.id, options: { tabTitle: style.tabTitle } })); + } + const constraints = { + minHeight: style.minHeight, + minWidth: style.minWidth, + maxHeight: style.maxHeight, + maxWidth: style.maxWidth, + }; + const hasConstraints = !isEmpty(constraints); + if (hasConstraints) { + wait(w.setSizeConstraints(constraints)); + } + const buttons = { + allowClose: style.allowClose, + allowCollapse: style.allowCollapse, + allowLockUnlock: style.allowLockUnlock, + allowMaximize: style.allowMaximize, + allowMinimize: style.allowMinimize + }; + const hasButtons = !isEmpty(buttons); + if (hasButtons) { + wait(w.resetButtons(buttons)); + } + await Promise.all(stylePromises); + return w; + } + async setSizeConstraints(w, constraints) { + await this.execute("setSizeConstraints", { windowId: w.id, options: constraints }); + return w; + } + async getSizeConstraints(w) { + const sizeConstraint = await this.execute("getSizeConstraints", { windowId: w.id }); + return sizeConstraint; + } + async setTabTooltip(w, tabTooltip) { + await this.execute("setTabTooltip", { windowId: w.id, options: { tabTooltip } }); + return w; + } + async getTabTooltip(w) { + const result = await this.execute("getTabTooltip", { windowId: w.id }); + return result.tabTooltip; + } + async resetButtons(w, buttonsConfig) { + await this.execute("resetButtons", { windowId: w.id, options: buttonsConfig }); + return w; + } + async getButtons(w) { + const buttons = await this.execute("getButtons", { windowId: w.id }); + return buttons; + } + async setOnTop(w, onTop) { + await this.execute("setOnTop", { windowId: w.id, options: { onTop } }); + return w; + } + async setTitle(w, newTitle) { + const options = { + windowId: w.id, + options: { + title: newTitle + } + }; + await this.execute("setTitle", options, "TitleChanged"); + return w; + } + async setSticky(w, isSticky) { + const options = { + windowId: w.id, + options: { + isSticky + } + }; + await this.execute("setSticky", options); + return w; + } + async setAllowWorkspaceDrop(w, allowWorkspaceDrop) { + const options = { + windowId: w.id, + options: { + allowWorkspaceDrop + } + }; + await this.execute("setAllowWorkspaceDrop", options); + return w; + } + async pin(windowToPin) { + const options = { + windowId: windowToPin.id + }; + await this.execute("pinTab", options); + return windowToPin; + } + async unpin(pinnedWindow) { + const options = { + windowId: pinnedWindow.id + }; + await this.execute("unpinTab", options); + return pinnedWindow; + } + async moveResize(w, bounds) { + if (typeof window !== "undefined" && window.glueDesktop.versionNum < 31200) { + return new Promise(async (res, rej) => { + const resolveImmediately = this.areBoundsEqual(bounds, w); + let isDone = false; + const done = () => { + if (isDone) { + return; + } + isDone = true; + if (unsubscribeBoundsChanged) { + unsubscribeBoundsChanged(); + unsubscribeBoundsChanged = undefined; + } + res(w); + if (resolveTimeout) { + clearTimeout(resolveTimeout); + resolveTimeout = undefined; + } + }; + let resolveTimeout; + let unsubscribeBoundsChanged; + if (!resolveImmediately) { + unsubscribeBoundsChanged = w.onBoundsChanged((win) => { + if (!this.areBoundsEqual(bounds, win)) { + return; + } + done(); + }); + } + try { + await this.execute("moveResize", { windowId: w.id, options: { bounds } }); + } + catch (error) { + rej(error); + return; + } + if (resolveImmediately) { + done(); + return; + } + resolveTimeout = setTimeout(() => { + done(); + }, 1000); + }); + } + else { + await this.execute("moveResize", { windowId: w.id, options: { bounds } }); + } + return w; + } + async addFrameButton(w, buttonInfo) { + await this.execute("addButton", { windowId: w.id, options: buttonInfo }, "ButtonAdded"); + return w; + } + async removeFrameButton(w, buttonId) { + await this.execute("removeButton", { windowId: w.id, options: buttonId }, "ButtonRemoved"); + return w; + } + async activate(w) { + await this.execute("activate", { windowId: w.id }); + return w; + } + async focus(w) { + await this.execute("focus", { windowId: w.id }); + return w; + } + async maximizeRestore(w) { + await this.execute("maximizeRestore", { windowId: w.id }, "StateChanged"); + return w; + } + async maximize(w) { + await this.execute("maximize", { windowId: w.id }, "StateChanged"); + return w; + } + async restore(w) { + await this.execute("restore", { windowId: w.id }, "StateChanged"); + return w; + } + async minimize(w) { + await this.execute("minimize", { windowId: w.id }, "StateChanged"); + return w; + } + async collapse(w) { + await this.execute("collapse", { windowId: w.id }, "StateChanged"); + return w; + } + async expand(w) { + await this.execute("expand", { windowId: w.id }, "StateChanged"); + return w; + } + async toggleCollapse(w) { + await this.execute("toggleCollapse", { windowId: w.id }, "StateChanged"); + return w; + } + async snap(w, targetWindow, options) { + const args = { + targetWindowId: targetWindow.id + }; + args.snappingEdge = options.direction; + args.autoAlign = options.autoAlign; + await this.execute("snap", { windowId: w.id, options: args }, "CompositionChanged", `CompositionChanged-${targetWindow.id}`); + return w; + } + async attachTab(w, sourceWindow, options) { + await this.execute("attachTab", { + windowId: w.id, + options: { + index: options, + sourceWindowId: sourceWindow.id, + targetWindowId: w.id, + } + }, `WindowFrameAdded-${sourceWindow.id}`, `WindowFrameRemoved-${sourceWindow.id}`); + return w; + } + async detachTab(w, options) { + const eventKeys = ["WindowFrameRemoved", `WindowFrameAdded`]; + if (!isUndefinedOrNull(options === null || options === void 0 ? void 0 : options.relativeTo)) { + eventKeys.push(`CompositionChanged`); + eventKeys.push(`CompositionChanged-${options.relativeTo}`); + } + else { + eventKeys.push("BoundsChanged"); + } + await this.execute("detachTab", { windowId: w.id, options }, ...eventKeys); + return w; + } + async setVisible(w, toBeVisible = true) { + let command; + if (toBeVisible) { + command = "show"; + } + else { + command = "hide"; + } + await this.execute(command, { windowId: w.id }, "VisibilityChanged"); + return w; + } + async center(w, display) { + await this.execute("center", { windowId: w.id, options: display }); + return w; + } + async showLoader(w, loader) { + await this.execute("showLoadingAnimation", { windowId: w.id, options: loader }); + return w; + } + async hideLoader(w) { + await this.execute("hideLoadingAnimation", { windowId: w.id }); + return w; + } + async updateContext(w, context, replace) { + let un; + try { + const contextWithoutUndefinedValues = this.swapUndefinedToNull(context); + const done = new Promise((resolve, reject) => { + un = w.onContextUpdated(() => { + resolve(); + }); + }); + await Promise.all([this.execute("updateContext", { + windowId: w.id, context: contextWithoutUndefinedValues, replace + }), done]); + return w; + } + finally { + if (un) { + un(); + } + } + } + async lock(w) { + await this.execute("lockUnlock", { windowId: w.id, options: { lock: true } }, "FrameIsLockedChanged"); + return w; + } + async unlock(w) { + await this.execute("lockUnlock", { windowId: w.id, options: { lock: false } }, "FrameIsLockedChanged"); + return w; + } + async getIcon(w) { + const result = await this.execute("getIcon", { + windowId: w.id, + options: {} + }); + return result.icon; + } + async setIcon(w, base64Image) { + await this.execute("setIcon", { + windowId: w.id, + options: { + dataURL: base64Image + } + }); + return w; + } + async setFrameColor(w, frameColor) { + await this.execute("setFrameColor", { windowId: w.id, options: { frameColor } }, "FrameColorChanged"); + return w; + } + async setTabHeaderVisible(w, toBeTabHeaderVisible) { + await this.execute("setTabHeaderVisible", { + windowId: w.id, + options: { + toShow: toBeTabHeaderVisible + } + }, "TabHeaderVisibilityChanged"); + return w; + } + async showGroupPopup(id, options) { + const reformatedOptions = this.showPopupCore(id, options); + await this.executeGroup("showGroupPopup", { + groupId: id, + options: reformatedOptions + }); + } + async showPopup(targetWindow, options) { + const reformatedOptions = this.showPopupCore(targetWindow.id, options); + await this.execute("showPopupWindow", { + windowId: targetWindow.id, + options: reformatedOptions + }); + return targetWindow; + } + async createFlydown(windowId, options) { + if (!options) { + throw new Error("The options object is not valid!"); + } + const optionsCopy = { ...options }; + if (!optionsCopy.horizontalOffset) { + optionsCopy.horizontalOffset = 0; + } + if (!optionsCopy.verticalOffset) { + optionsCopy.verticalOffset = 0; + } + const fullOptions = this.reformatFlydownOptions(windowId, optionsCopy); + return this.execute("setFlydownArea", { windowId, options: fullOptions }).then(() => { + const zoneIds = fullOptions.zones.map((z) => z.id); + fullOptions.zones.forEach((z) => { + let callback = typeof (z.flydownSize) === "function" ? + z.flydownSize : () => z.flydownSize; + if (options.size instanceof Function && z.flydownSize) { + callback = async (data, cancel) => { + let result; + if (options.size instanceof Function) { + result = await options.size(data, cancel); + } + if (z.flydownSize instanceof Function && z.flydownSize !== options.size) { + return await z.flydownSize(data, cancel) || result; + } + return result || z.flydownSize; + }; + } + this._registry.clearKey(`${fullOptions.targetId}_${z.id}`); + this._registry.add(`${fullOptions.targetId}_${z.id}`, callback); + }); + return { + destroy: () => this.clearFlydownArea(fullOptions.targetId, zoneIds), + options: optionsCopy + }; + }); + } + async setModalState(windowId, isModal) { + return this.execute("setModalState", { windowId, options: { isModal } }); + } + async autoArrange(displayId) { + return this.execute("autoArrange", { options: { displayId } }); + } + async handleFlydownBoundsRequested(targetId, data) { + const cancelCallback = () => data.cancel = true; + const callbackData = { + zoneId: data.flydownId, + flydownWindowBounds: data.flydownWindowBounds, + flydownWindowId: data.flydownWindowId, + }; + const responses = await Promise.all(this._registry.execute(`${targetId}_${data.flydownId}`, callbackData, cancelCallback)); + if (responses.length === 1) { + const defaultResponse = { height: 0, width: 0, top: 0, left: 0 }; + const response = typeof (responses[0]) === "object" && !Array.isArray(responses[0]) ? responses[0] : defaultResponse; + const responseOptions = { ...data, flydownWindowBounds: response }; + return responseOptions; + } + } + async handleOnEventRequested(callbackId, args) { + var _a; + const callbacks = (_a = this.unsubCallbacks[callbackId]) !== null && _a !== void 0 ? _a : []; + let prevented = false; + const preventArgs = []; + await Promise.all(callbacks.map((cb) => { + return new Promise((resolve, reject) => { + cb(() => { + resolve(); + }, () => { + reject(); + }, (pArgs) => { + prevented = true; + preventArgs.push(pArgs); + }, args); + }); + })); + return { prevented, preventArgs }; + } + async zoomIn(window) { + await this.execute("zoomIn", { + windowId: window.id, + }); + return window; + } + async zoomOut(window) { + await this.execute("zoomOut", { + windowId: window.id, + }); + return window; + } + async setZoomFactor(window, zoomFactor) { + await this.execute("setZoomFactor", { + windowId: window.id, + options: { + zoomFactor + } + }); + return window; + } + async showDevTools(window) { + await this.execute("showDevTools", { + windowId: window.id, + }); + return window; + } + async capture(window, options) { + const base64screenshot = (await this.execute("captureScreenshot", { windowId: window.id, options: { ...options } })).data; + return base64screenshot; + } + async captureGroup(windowIds, options) { + const base64screenshot = (await this.execute("captureGroupScreenshot", { windowId: windowIds[0], options: { groupWindowIds: windowIds, ...options } })).data; + return base64screenshot; + } + async flash(resultWindow, options) { + await this.execute("flash", { windowId: resultWindow.id, options: { ...options } }); + return resultWindow; + } + async flashTab(resultWindow, options) { + await this.execute("flashTab", { windowId: resultWindow.id, options: { ...options } }); + return resultWindow; + } + async configure(windowId, options) { + return this.execute("configure", { windowId, options: { ...options } }); + } + async print(resultWindow, options) { + await this.execute("print", { windowId: resultWindow.id, options: { ...options } }); + return resultWindow; + } + async printToPDF(resultWindow, options) { + const filePath = (await this.execute("printToPDF", { windowId: resultWindow.id, options: { ...options } })).filePath; + return filePath; + } + async place(window, options) { + const copy = { ...options }; + if (!options.display || options.display === "current") { + copy.display = await window.getDisplay(); + } + if (copy.display && typeof copy.display !== "string" && typeof copy.display !== "number") { + copy.display = copy.display.index + 1; + } + return this.execute("place", { windowId: window.id, options: { ...copy } }); + } + async refresh(resultWindow, ignoreCache) { + await this.execute("refresh", { windowId: resultWindow.id, options: { ignoreCache } }); + return resultWindow; + } + async download(resultWindow, url, options = {}) { + options.enableDownloadBar = !options.silent; + const result = await this.execute("downloadURL", { windowId: resultWindow.id, options: { url, options } }); + return { + url, + path: result.fullPath, + size: result.fileSize, + }; + } + async configureWindow(resultWindow, options) { + await this.execute("configureWindow", { windowId: resultWindow.id, options }); + return resultWindow; + } + async getWindowConfiguration(resultWindow) { + const config = await this.execute("getWindowConfiguration", { windowId: resultWindow.id }); + return config; + } + async startDrag(resultWindow, options) { + await this.execute("startDrag", { windowId: resultWindow.id, options }); + return resultWindow; + } + showDialog(resultWindow, options) { + return new Promise((res, rej) => { + const token = Utils.generateId(); + const un = this._registry.add("event", (args) => { + if (args.type === "DialogResult" && args.windowId === resultWindow.id && args.data.token === token) { + un(); + const data = args.data; + if ("status" in data) { + if (data.status === "failed") { + rej(new Error(data.message)); + } + else if (data.status === "successful") { + res(data.result); + } + } + } + }); + this.execute("showDialog", { windowId: resultWindow.id, options: Object.assign({}, { ...options }, { token }) }); + }); + } + async execute(command, options, ...eventKeys) { + return this.executeCore(this.WndMethodName, command, options, ...eventKeys); + } + async executeGroup(command, options, ...eventKeys) { + return this.executeCore(this.GroupMethodName, command, options, ...eventKeys); + } + async ungroup(w, options) { + const args = { + windowId: w.id, + options + }; + await this.execute("ungroup", args); + return w; + } + async updateJumpList(windowId, options) { + const args = { + windowId, + options + }; + await this.execute("updateJumplist", args); + } + async getJumpList(windowId) { + const args = { + windowId, + }; + const result = await this.execute("getJumplist", args); + return result; + } + onClosing(callback, gdWindow) { + const glue42gd = typeof window !== "undefined" && window.glue42gd; + if (glue42gd && gdWindow.windowType === "electron") { + return glue42gd.addCloseHandler(callback, gdWindow.id); + } + else { + return this.nonWindowHandlers(callback, gdWindow.id, "OnClosing"); + } + } + onGroupClosing(callback, group) { + return this.nonWindowHandlersCore(group.id, "OnClosing", true, callback); + } + onRefreshing(callback, gdWindow) { + const glue42gd = typeof window !== "undefined" && window.glue42gd; + if (glue42gd && gdWindow.windowType === "electron") { + return glue42gd.addRefreshHandler(callback, gdWindow.id); + } + else { + return this.nonWindowHandlers(callback, gdWindow.id, "OnRefreshing"); + } + } + onNavigating(callback, gdWindow) { + const glue42gd = typeof window !== "undefined" && window.glue42gd; + if (glue42gd && gdWindow.windowType === "electron") { + return glue42gd.addWillNavigateHandler(callback, gdWindow.id); + } + else { + return this.nonWindowHandlers(callback, gdWindow.id, "OnNavigating"); + } + } + async clone(window, cloneOptions) { + const args = { + windowId: window.id, + options: cloneOptions + }; + const result = await this.execute("clone", args); + const win = await windowStore.waitFor(result.id); + return win.API; + } + async executeCode(targetWindow, code) { + const args = { + windowId: targetWindow.id, + options: { + code + } + }; + return this.execute("executeCode", args); + } + async goBack(resultWindow) { + await this.execute("goBack", { windowId: resultWindow.id }); + } + async goForward(resultWindow) { + await this.execute("goForward", { windowId: resultWindow.id }); + } + async getDockingPlacement(window) { + return this.execute("getDockingPlacement", { windowId: window.id }); + } + dock(window, options) { + return this.execute("dock", { windowId: window.id, options }); + } + clearCallbacks(id) { + const keys = Object.keys(this.unsubCallbacks); + keys.forEach((key) => { + if (key.startsWith(id)) { + delete this.unsubCallbacks[key]; + } + }); + } + nonWindowHandlers(callback, targetId, type) { + return this.nonWindowHandlersCore(targetId, type, false, callback); + } + nonWindowHandlersCore(targetId, type, isGroup, callback) { + const id = `${targetId}-${type}`; + const unsub = () => { + var _a; + if (this.unsubCallbacks[id]) { + const callbacks = this.unsubCallbacks[id]; + this.unsubCallbacks[id] = callbacks.filter((cb) => cb !== callback); + if (this.unsubCallbacks[id].length === 0) { + delete this.unsubCallbacks[id]; + } + } + const cbs = (_a = this.unsubCallbacks[id]) !== null && _a !== void 0 ? _a : []; + if (cbs.length === 0) { + const options = { + unsubscribe: true + }; + if (isGroup) { + this.executeGroup(type, { + groupId: targetId, + options + }); + } + else { + this.execute(type, { + windowId: targetId, + options + }); + } + } + }; + if (this.unsubCallbacks[id]) { + this.unsubCallbacks[id].push(callback); + return unsub; + } + else { + this.unsubCallbacks[id] = [callback]; + } + if (isGroup) { + this.executeGroup(type, { groupId: targetId }); + } + else { + this.execute(type, { windowId: targetId }); + } + return unsub; + } + reformatFlydownOptions(windowId, options) { + const assignGeneralIfUnassigned = (zone, prop) => { + if (options[prop] && (zone[prop] === undefined || zone[prop] === null)) { + const valueFromOptions = options[prop]; + zone[prop] = valueFromOptions; + } + }; + const zones = options.zones.map((z) => { + assignGeneralIfUnassigned(z, "windowId"); + assignGeneralIfUnassigned(z, "targetLocation"); + if (options.size && (z.flydownSize === undefined || z.flydownSize === null)) { + z.flydownSize = options.size; + } + z.flydownBounds = z.flydownSize; + z.flydownId = z.windowId; + if (!z.targetLocation) { + z.targetLocation = "bottom"; + } + return z; + }); + return { + ...options, + zones, + targetId: windowId, + flydownBounds: options.size, + flydownActiveArea: options.activeArea + }; + } + clearFlydownArea(windowId, areaIds) { + return this.execute("clearFlydownWindowArea", { + windowId, + options: {} + }).then(() => { + areaIds.forEach((id) => { + this._registry.clearKey(`${windowId}_${id}`); + }); + }); + } + executeWithoutToken(params, ...eventKeys) { + const uns = []; + const executed = eventKeys === null || eventKeys === void 0 ? void 0 : eventKeys.filter((k) => !isUndefinedOrNull(k)).map((key) => { + return new Promise((r) => { + const [type, windowId = params.windowId] = key.split("-"); + uns.push(this._registry.add("event", (data) => { + if (data.type === type && data.windowId === windowId) { + r(); + } + })); + }); + }); + const action = new Promise((resolve, reject) => { + this.agm.invoke("T42.Wnd.Execute", params, this.agmTarget, { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_RESPONSE_TIMEOUT_MS + }) + .then((i) => { + if (i.returned && i.returned.errorMsg) { + reject(i); + } + else { + resolve(i.returned); + } + }) + .catch((e) => reject(e)); + }); + return Promise.all([action, ...executed]) + .then((r) => { + return r[0]; + }) + .finally(() => { + uns.forEach((un) => un()); + }); + } + async executeCore(methodName, command, options, ...eventKeys) { + const { invocationOptions, ...invocationArgs } = options; + const params = { + ...invocationArgs, + command, + }; + let finishedResolve; + this._finished = new Promise((resolve) => { + finishedResolve = resolve; + }); + try { + if (typeof window !== "undefined" && window.glueDesktop.versionNum < 31200) { + return await this.executeWithoutToken(params, ...eventKeys); + } + else { + return await this.executeWithToken(methodName, params, invocationOptions); + } + } + finally { + finishedResolve(); + } + } + async executeWithToken(methodName, options, invocationOptions) { + let un; + try { + const token = Utils.generateId(); + const event = new Promise((r) => { + un = this._registry.add("event", (data) => { + if (data.token === token) { + r(); + } + }); + }); + const execute = new Promise((resolve, reject) => { + options.token = token; + if (!invocationOptions) { + invocationOptions = { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_RESPONSE_TIMEOUT_MS + }; + } + else if (!invocationOptions.methodResponseTimeoutMs) { + invocationOptions.methodResponseTimeoutMs = INTEROP_METHOD_RESPONSE_TIMEOUT_MS; + } + else if (!invocationOptions.waitTimeoutMs) { + invocationOptions.waitTimeoutMs = INTEROP_METHOD_WAIT_TIMEOUT_MS; + } + this.agm.invoke(methodName, options, this.agmTarget, invocationOptions) + .then((i) => { + if (i.returned && i.returned.errorMsg) { + reject(new Error(i.returned.errorMsg)); + } + else { + resolve(i.returned); + } + }) + .catch((e) => { + const error = Utils.typedError(e); + reject(error); + }); + }); + const result = await Promise.all([execute, event]); + return result[0]; + } + finally { + if (un) { + un(); + } + } + } + areBoundsEqual(requested, w) { + const current = w.bounds; + const settings = w.settings; + let height = requested.height; + let width = requested.width; + if (requested.height < settings.minHeight) { + height = settings.minHeight; + } + if (requested.height > settings.maxHeight) { + height = settings.maxHeight; + } + if (requested.width < settings.minWidth) { + width = settings.minWidth; + } + if (requested.width > settings.maxWidth) { + width = settings.maxWidth; + } + const areHeightsEqual = height ? current.height === height : true; + const areWidthsEqual = width ? current.width === width : true; + const areLeftsEqual = requested.left ? current.left === requested.left : true; + const areTopsEqual = requested.top ? current.top === requested.top : true; + return areHeightsEqual && areWidthsEqual && areLeftsEqual && areTopsEqual; + } + swapUndefinedToNull(context) { + try { + const copy = {}; + for (const key of Object.keys(context)) { + let value = context[key]; + if (typeof value === "undefined") { + value = null; + } + copy[key] = value; + } + return copy; + } + catch { + return context; + } + } + showPopupCore(id, options) { + if (!options) { + throw new Error("The options object is not valid!"); + } + const optionsCopy = { ...options }; + if (!optionsCopy.targetLocation) { + optionsCopy.targetLocation = "bottom"; + } + const reformatedOptions = { + ...optionsCopy, + popupBounds: optionsCopy.size, + targetId: id, + popupId: optionsCopy.windowId + }; + return reformatedOptions; + } + } + var executor = new GDExecutor(); + + class GDEnvironment { + constructor(agm, logger, appManagerGetter, displayAPIGetter, channelsAPIGetter, wndId, groupId) { + this._registry = CallbackRegistryFactory(); + this._agm = agm; + this._logger = logger.subLogger("gd-env"); + this._windowId = wndId; + this._groupId = groupId; + this._appManagerGetter = appManagerGetter; + this._displayAPIGetter = displayAPIGetter; + this._channelsAPIGetter = channelsAPIGetter; + } + init() { + return new Promise((resolve, reject) => { + this._agm.register("T42.Wnd.OnEventWithResponse", (args, caller) => { + return this.respondToEvent(args); + }); + new Promise((streamResolve, streamReject) => { + this._agm.subscribe("T42.Wnd.OnEvent", { + target: "best", + arguments: { + withConfig: true + }, + onData: (streamData) => { + if (streamData.data.type === "Configuration") { + this._configuration = streamData.data; + executor.setConfiguration(this._configuration); + return; + } + this.updateWindow(streamData.data, resolve); + executor.handleEvent(streamData.data); + }, + onConnected: (instance) => { + this._agmInstance = instance; + executor.init(this._agm, this._agmInstance); + } + }).catch((error) => { + var _a; + const message = `${(_a = error === null || error === void 0 ? void 0 : error.method) === null || _a === void 0 ? void 0 : _a.name} - ${JSON.stringify(error === null || error === void 0 ? void 0 : error.called_with)} - ${error === null || error === void 0 ? void 0 : error.message}`; + reject(new Error(message)); + }); + }); + }); + } + get executor() { + return executor; + } + open(name, url, options) { + options = options || {}; + const copyOptions = { ...options }; + if (copyOptions.relativeTo !== undefined && typeof copyOptions.relativeTo !== "string") { + copyOptions.relativeTo = copyOptions.relativeTo.id || ""; + } + copyOptions.name = name; + copyOptions.url = url; + copyOptions.windowState = options.windowState || options.state; + delete copyOptions.state; + return this.executor.open(copyOptions); + } + createFlydown(windowId, options) { + return this.executor.createFlydown(windowId, options); + } + async showPopup(windowId, options) { + const window = windowStore.get(windowId); + await this.executor.showPopup(window.API, options); + } + tabAttached(callback) { + return this._registry.add("tab-attached", callback); + } + tabDetached(callback) { + return this._registry.add("tab-detached", callback); + } + onWindowFrameColorChanged(callback) { + return this._registry.add("frame-color-changed", callback); + } + onEvent(callback) { + return this._registry.add("window-event", callback); + } + my() { + return this._windowId; + } + myGroup() { + return this._groupId; + } + onCompositionChanged(callback) { + return this._registry.add("composition-changed", callback); + } + onGroupHeaderVisibilityChanged(callback) { + return this._registry.add("group-header-changed", callback); + } + onGroupVisibilityChanged(callback) { + return this._registry.add("group-visibility-changed", callback); + } + onGroupStateChanged(callback) { + return this._registry.add("group-state-changed", callback); + } + onWindowGotFocus(callback) { + return this._registry.add("got-focus", callback); + } + onWindowLostFocus(callback) { + return this._registry.add("lost-focus", callback); + } + onWindowsAutoArrangeChanged(callback) { + return this._registry.add("windows-auto-arranged-changed", callback); + } + respondToEvent(args) { + if (args.type === "ShowFlydownBoundsRequested") { + return this.executor.handleFlydownBoundsRequested(args.data.windowId, args.data); + } + else if (args.type === "OnClosing" || args.type === "OnRefreshing" || args.type === "OnNavigating") { + return this.executor.handleOnEventRequested(args.data.callbackId, args.data.args); + } + return Promise.reject(`There isn't a handler for ${args.type}`); + } + updateWindow(windowInfo, readyResolve) { + const extendedStreamEvent = this.getExtendedStreamEvent(windowInfo); + if (windowInfo.type === "Snapshot") { + const windowInfoFullInfoEvent = windowInfo; + windowInfoFullInfoEvent.windows.forEach((w) => { + const existingWindow = windowStore.get(w.id); + if (existingWindow) { + existingWindow.Events.handleUpdate(this.mapToWindowConstructorOptions(w)); + existingWindow.GroupCreationArgs = this.mapToGroupCreationArgs(w); + } + else { + this.createWindowFromSnapshot(w.id, w); + } + this._registry.execute("window-event", extendedStreamEvent); + }); + readyResolve(this); + return; + } + if (windowInfo.type === "CommandExecuted") { + this._registry.execute("window-event", extendedStreamEvent); + return; + } + if (windowInfo.type === "Created") { + const windowInfoCreatedEvent = (windowInfo); + this.createWindowFromStream(windowInfoCreatedEvent.windowId, windowInfoCreatedEvent.data || {}); + this._registry.execute("window-event", extendedStreamEvent); + return; + } + if (windowInfo.type === "OnGroupVisibilityChanged") { + const info = windowInfo; + this._registry.execute("group-visibility-changed", info.data); + this._registry.execute("window-event", windowInfo); + return; + } + if (windowInfo.type === "OnGroupStateChanged") { + const info = windowInfo; + this._registry.execute("group-state-changed", info.data); + this._registry.execute("window-event", windowInfo); + return; + } + if (windowInfo.type === "OnWindowsAutoArrangeChanged") { + const info = windowInfo; + this._registry.execute("windows-auto-arranged-changed", info.data); + this._registry.execute("window-event", windowInfo); + return; + } + const windowObjectAndEvents = windowStore.get((windowInfo).windowId); + if (!windowObjectAndEvents) { + this._logger.error(`received update for unknown window. Stream:', ${JSON.stringify(windowInfo, null, 4)}`); + return; + } + const theWindow = windowObjectAndEvents.API; + const theWindowEvents = windowObjectAndEvents.Events; + if (windowInfo.type === "BoundsChanged") { + const windowInfoBoundsChangedEvent = windowInfo; + theWindowEvents.handleBoundsChanged(windowInfoBoundsChangedEvent.data); + } + if (windowInfo.type === "UrlChanged") { + const windowInfoUrlChangedEvent = windowInfo; + windowStore.setUrlChangedState(windowInfoUrlChangedEvent.windowId); + theWindowEvents.handleUrlChanged(windowInfoUrlChangedEvent.data); + } + if (windowInfo.type === "TitleChanged") { + const windowInfoTitleChanged = windowInfo; + theWindowEvents.handleTitleChanged(windowInfoTitleChanged.data); + } + if (windowInfo.type === "IsStickyChanged") { + const windowInfoIsStickyChangedChanged = windowInfo; + theWindowEvents.handleIsStickyChanged(windowInfoIsStickyChangedChanged.data); + } + if (windowInfo.type === "VisibilityChanged") { + theWindowEvents.handleVisibilityChanged(windowInfo.data); + } + if (windowInfo.type === "ContextChanged") { + theWindowEvents.handleContextUpdated(windowInfo.data); + } + if (windowInfo.type === "StateChanged") { + theWindowEvents.handleWindowChangeState(windowInfo.data); + } + if (windowInfo.type === "FrameColorChanged") { + theWindowEvents.handleFrameColorChanged(windowInfo.data); + this._registry.execute("frame-color-changed", theWindow); + } + if (windowInfo.type === "CompositionChanged") { + const windowInfoCompositionChanged = windowInfo; + theWindowEvents.handleCompositionChanged(windowInfoCompositionChanged.data); + windowStore.setCompositionChangedState(windowObjectAndEvents); + this._registry.execute("composition-changed", windowInfoCompositionChanged.data); + } + if (windowInfo.type === "GroupHeaderVisibilityChanged") { + const info = windowInfo; + theWindowEvents.handleGroupHeaderVisibilityChanged(info.data.groupHeaderVisible); + this._registry.execute("group-header-changed", info.data); + } + if (windowInfo.type === "FocusChanged") { + const windowInfoFocusChanged = windowInfo; + this.focusChanged(theWindowEvents, theWindow, windowInfoFocusChanged.data); + } + if (windowInfo.type === "WindowFrameChanged") { + theWindowEvents.handleFrameAttached(windowInfo.data.frameId, windowInfo.data.frameId, windowInfo.data.isTabHeaderVisible); + this._registry.execute("frame-changed"); + } + if (windowInfo.type === "WindowFrameAdded") { + const winsToBeNotified = getWindowsByTabGroupId(theWindow.id, windowInfo.data.frameId); + const data = windowInfo.data; + theWindowEvents.handleAttached(data.frameId, data.frameId, data.isTabHeaderVisible, data.isLocked, winsToBeNotified) + .then(async () => { + if (winsToBeNotified.length > 0) { + await executor.finished; + this._registry.execute("tab-attached", theWindow, windowInfo.data.frameId, windowInfo.data.isTabHeaderVisible); + } + }); + } + if (windowInfo.type === "WindowFrameRemoved") { + const oldTabGroupId = theWindow.tabGroupId; + const winsToBeNotified = getWindowsByTabGroupId(theWindow.id, oldTabGroupId); + theWindowEvents.handleDetached(windowInfo.data.isLocked, winsToBeNotified) + .then(async () => { + if (winsToBeNotified.length > 0) { + await executor.finished; + this._registry.execute("tab-detached", theWindow, windowInfo.data.frameId, theWindow.tabGroupId); + } + }); + } + if (windowInfo.type === "TabHeaderVisibilityChanged") { + theWindowEvents.handleTabHeaderVisibilityChanged(windowInfo.data.isTabHeaderVisible); + } + if (windowInfo.type === "FrameSelectionChanged") { + theWindowEvents.handleFrameSelectionChanged(windowInfo.data.newWindowId, windowInfo.data.prevWindowId); + } + if (windowInfo.type === "ButtonClicked") { + theWindowEvents.handleFrameButtonClicked(windowInfo.data); + } + if (windowInfo.type === "ButtonAdded") { + theWindowEvents.handleFrameButtonAdded(windowInfo.data); + } + if (windowInfo.type === "ButtonRemoved") { + theWindowEvents.handleFrameButtonRemoved(windowInfo.data); + } + if (windowInfo.type === "WindowZoomFactorChanged") { + theWindowEvents.handleZoomFactorChanged(windowInfo.data); + } + if (windowInfo.type === "Closed") { + windowStore.remove(windowObjectAndEvents); + theWindowEvents.handleWindowClose(); + } + if (windowInfo.type === "FrameIsLockedChanged") { + theWindowEvents.handleFrameIsLockedChanged(windowInfo.data); + } + if (windowInfo.type === "PlacementSettingsChanged") { + theWindowEvents.handlePlacementSettingsChanged(windowInfo.data); + } + if (windowInfo.type === "DockingChanged") { + theWindowEvents.handleDockingChanged(windowInfo.data); + } + if (windowInfo.type === "AllowWorkspaceDropChanged") { + theWindowEvents.handleAllowWorkspaceDropChanged(windowInfo.data); + } + if (windowInfo.type === "IsPinnedChanged") { + theWindowEvents.handleIsPinnedChanged(windowInfo.data); + } + if (windowInfo.type === "WindowChannelRestrictionsChanged") { + theWindowEvents.handleChannelRestrictionsChanged(windowInfo.data); + } + this._registry.execute("window-event", extendedStreamEvent); + } + createWindowFromSnapshot(windowId, options) { + const windowObjAndEvents = this.createWindowCore(windowId, options); + windowStore.add(windowObjAndEvents, { + ready: true, + urlChanged: true, + compositionChanged: true + }); + } + createWindowFromStream(windowId, options) { + var _a; + const windowObjAndEvents = this.createWindowCore(windowId, options); + const isRemote = windowObjAndEvents.API.windowType === "remote"; + const isFrameless = windowObjAndEvents.API.windowType === "electron" && windowObjAndEvents.API.mode === "frameless"; + const isHidden = windowObjAndEvents.API.isVisible === false; + let urlChanged = false; + let compositionChanged = false; + if (isRemote) { + urlChanged = true; + } + if (isFrameless || isHidden) { + compositionChanged = true; + } + if (!isRemote) { + urlChanged = !((_a = this._configuration) === null || _a === void 0 ? void 0 : _a.windowAvailableOnURLChanged); + } + windowStore.add(windowObjAndEvents, { + ready: true, + urlChanged, + compositionChanged + }); + } + createWindowCore(windowId, options) { + const windowObjAndEvents = windowFactory(windowId, this.mapToWindowConstructorOptions(options), executor, this._logger, this._appManagerGetter, this._displayAPIGetter, this._channelsAPIGetter, this._agm); + windowObjAndEvents.GroupCreationArgs = this.mapToGroupCreationArgs(options); + return windowObjAndEvents; + } + async focusChanged(theWindowEvents, theWindow, focus) { + theWindowEvents.handleFocusChanged(focus); + try { + if (!this._configuration.windowAvailableOnURLChanged) { + await windowStore.waitFor(theWindow.id); + } + } + catch (error) { + return; + } + if (focus) { + this._registry.execute("got-focus", theWindow); + } + else { + this._registry.execute("lost-focus", theWindow); + } + } + mapToWindowConstructorOptions(args) { + return { + name: args.name, + context: args.context, + bounds: args.bounds, + url: args.url, + title: args.title, + isVisible: args.isVisible, + focus: args.isFocused, + state: args.state, + frameColor: args.frameColor, + groupId: args.groupId, + neighbours: args.neighbors, + isFocused: args.isFocused, + isGroupHeaderVisible: args.groupHeaderVisible, + isCollapsed: args.isCollapsed, + tabGroupId: args.frameId, + frameId: args.frameId, + mode: args.mode, + isTabHeaderVisible: args.isTabHeaderVisible, + isTabSelected: args.isActiveTab, + settings: args.settings, + windowType: args.windowType, + zoomFactor: args.zoomFactor, + isLocked: args.isLocked, + placementSettings: args.placementSettings, + isSticky: args.isSticky, + tabIndex: args.tabIndex, + frameButtons: args.frameButtons, + jumpListOptions: args.jumpList, + applicationName: args.applicationName, + allowWorkspaceDrop: args.allowWorkspaceDrop, + isPinned: args.isPinned + }; + } + mapToGroupCreationArgs(args) { + return { + isGroupHibernated: args.isGroupHibernated, + isGroupVisible: args.isGroupVisible + }; + } + getExtendedStreamEvent(streamEvent) { + try { + if (!streamEvent.windowId) { + return streamEvent; + } + const window = windowStore.get(streamEvent.windowId); + if (!window) { + return streamEvent; + } + const result = { + state: streamEvent.type, + windowName: window.API.name, + ...streamEvent + }; + if (result.state === "WindowFrameAdded") { + result.state = "TabAttached"; + } + if (result.state === "StateChanged") { + result.state = result.data.charAt(0).toUpperCase() + result.data.slice(1); + } + if (result.state === "ButtonAdded") { + result.state = "FrameButtonAdded"; + } + if (result.state === "ButtonRemoved") { + result.state = "FrameButtonRemoved"; + } + return result; + } + catch (error) { + return streamEvent; + } + } + } + + var envDetector = (agm, logger, appManagerGetter, displayAPIGetter, channelsAPIGetter, gdMajorVersion) => { + var _a; + const _logger = logger; + if (gdMajorVersion === 2) { + _logger.trace("running in HC"); + throw new Error("GD2 not supported"); + } + else if (gdMajorVersion >= 3) { + _logger.trace("running in GD 3"); + return new GDEnvironment(agm, _logger, appManagerGetter, displayAPIGetter, channelsAPIGetter, window.glue42gd.windowId, (_a = window.webGroupsManager) === null || _a === void 0 ? void 0 : _a.id).init(); + } + else { + _logger.trace("running in Browser or Node"); + return new GDEnvironment(agm, _logger, appManagerGetter, displayAPIGetter, channelsAPIGetter).init(); + } + }; + + var groupFactory = (id, executor) => { + const _registry = CallbackRegistryFactory(); + const _windowsId = []; + let _isHibernatedFlag; + let _isVisible; + async function addWindow(winId) { + var _a, _b, _c, _d; + if (_windowsId.indexOf(winId) === -1) { + _windowsId.push(winId); + const win = windowStore.get(winId); + win.Events.handleGroupChanged(groupObject, undefined); + _isHibernatedFlag = (_b = (_a = win.GroupCreationArgs.isGroupHibernated) !== null && _a !== void 0 ? _a : _isHibernatedFlag) !== null && _b !== void 0 ? _b : false; + _isVisible = (_d = (_c = win.GroupCreationArgs.isGroupVisible) !== null && _c !== void 0 ? _c : _isVisible) !== null && _d !== void 0 ? _d : true; + await executor.finished; + _registry.execute("window-added", groupObject, win.API); + } + } + async function removeWindow(win) { + const index = _windowsId.indexOf(win.API.id); + if (index !== -1) { + _windowsId.splice(index, 1); + win.Events.handleGroupChanged(undefined, groupObject); + await executor.finished; + _registry.execute("window-removed", groupObject, win.API); + } + } + function find(window, success, error) { + let winId; + if (typeof window === "string") { + winId = window; + } + else if (!isUndefinedOrNull(window)) { + winId = window.id; + } + const win = _mapToWindowObject(winId); + if (win) { + if (typeof success === "function") { + success(win); + } + return win; + } + else { + if (typeof error === "function") { + error(`No window with ID: ${winId}`); + } + } + } + function windows(success) { + const mappedWindows = _mapToWindowObjects(); + return mappedWindows; + } + async function execute(command, options, ...keys) { + await executor.execute(command, options, ...keys); + return groupObject; + } + function handleGroupHeaderVisibilityChanged(windowInfo) { + _registry.execute("header-visibility-changed", groupObject); + } + function handleGroupVisibilityChanged(visibile) { + _isVisible = visibile; + _registry.execute("group-visibility-changed", groupObject); + } + function handleGroupHibernateChanged(isHibernatedFlag) { + _isHibernatedFlag = isHibernatedFlag; + } + function _mapToWindowObjects() { + const winObjects = []; + _windowsId.forEach((winId) => { + const windowObject = _mapToWindowObject(winId); + if (typeof windowObject !== "undefined") { + winObjects.push(windowObject); + } + }); + return winObjects; + } + function _mapToWindowObject(windowId) { + return windowStore.get(windowId) ? windowStore.get(windowId).API : undefined; + } + function _getGroupHeaderVisibility() { + const windowWithHiddenHeader = _mapToWindowObjects().find((w) => !w.isGroupHeaderVisible); + const _isGroupHeaderVisible = windowWithHiddenHeader === undefined; + return _isGroupHeaderVisible; + } + function isHibernated() { + return _isHibernatedFlag; + } + function onHeaderVisibilityChanged(callback) { + return _registry.add("header-visibility-changed", callback); + } + function onWindowAdded(callback) { + return _registry.add("window-added", callback); + } + function onWindowRemoved(callback) { + return _registry.add("window-removed", callback); + } + function onVisibilityChanged(callback) { + if (!callback) { + throw new Error("Callback argument is required"); + } + if (callback && typeof callback !== "function") { + throw new Error("Callback argument must be a function"); + } + return _registry.add("group-visibility-changed", callback); + } + function onClosing(callback) { + if (typeof callback !== "function") { + throw new Error("callback must be a function"); + } + const callbackWrap = (success, error, prevent) => { + const promise = callback(prevent); + if (promise === null || promise === void 0 ? void 0 : promise.then) { + promise.then(success).catch(error); + } + else { + success(); + } + }; + return executor.onGroupClosing(callbackWrap, groupObject); + } + const groupObject = { + id, + get windows() { + return windows(); + }, + find, + get isHeaderVisible() { + return _getGroupHeaderVisibility(); + }, + get isHibernated() { + return isHibernated(); + }, + get isVisible() { + return _isVisible; + }, + showHeader: (success, error) => { + return Utils.callbackifyPromise(() => { + return execute("setGroupHeaderVisibility", { windowId: _windowsId[0], options: { toShow: true } }, ..._windowsId.map((w) => `GroupHeaderVisibilityChanged-${w}`)); + }, success, error); + }, + hideHeader: (success, error) => { + return Utils.callbackifyPromise(() => { + return execute("setGroupHeaderVisibility", { windowId: _windowsId[0], options: { toShow: false } }, ..._windowsId.map((w) => `GroupHeaderVisibilityChanged-${w}`)); + }, success, error); + }, + getTitle: async () => { + const r = await executor.execute("getGroupTitle", { windowId: _windowsId[0] }); + return r.title; + }, + setTitle: async (title) => { + if (isNullOrWhiteSpace(title)) { + throw new Error("`title` must not be null or undefined."); + } + return execute("setGroupTitle", { windowId: _windowsId[0], options: { title } }); + }, + capture: (captureOptions) => { + return executor.captureGroup(_windowsId, captureOptions); + }, + maximize: (success, error) => { + return Utils.callbackifyPromise(() => { + return execute("maximizeGroup", { windowId: _windowsId[0] }, ..._windowsId.map((w) => `StateChanged-${w}`)); + }, success, error); + }, + restore: (success, error) => { + return Utils.callbackifyPromise(() => { + return execute("restoreGroup", { windowId: _windowsId[0] }, ..._windowsId.map((w) => `StateChanged-${w}`)); + }, success, error); + }, + show: (activate) => { + if (!isUndefinedOrNull(activate) && !isBoolean(activate)) { + throw new Error("Activate flag must be a boolean!"); + } + activate = !isUndefinedOrNull(activate) ? activate : true; + return executor.executeGroup("showGroup", { + groupId: id, + options: { activate } + }); + }, + hide: () => { + return executor.executeGroup("hideGroup", { + groupId: id + }); + }, + close: () => { + return executor.executeGroup("closeGroup", { + groupId: id + }); + }, + showPopup: (options) => { + return executor.showGroupPopup(id, options); + }, + onHeaderVisibilityChanged, + onWindowAdded, + onWindowRemoved, + onVisibilityChanged, + onClosing, + }; + const internal = { + get windows() { + return _windowsId; + }, + addWindow, + removeWindow, + handleGroupHeaderVisibilityChanged, + handleGroupVisibilityChanged, + handleGroupHibernateChanged + }; + return { + groupAPI: groupObject, + groupInternal: internal, + }; + }; + + var groupsFactory = (environment, logger) => { + const _registry = CallbackRegistryFactory(); + const _groups = {}; + let heardForWindowsCounter = -1; + const windows = windowStore.list; + Object.keys(windows).forEach((k) => { + const win = windows[k]; + const groupId = win.API.groupId; + const winId = win.API.id; + if (!isNullOrWhiteSpace(groupId)) { + addWindow(groupId, winId); + } + }); + windowStore.onRemoved((w) => { + const group = findGroupWrapperByWindow(w.API); + removeWindow(group, w); + }); + environment.onCompositionChanged((windowInfo) => { + handleCompositionChanged(windowInfo); + }); + environment.onGroupHeaderVisibilityChanged((windowInfo) => { + const windowId = windowInfo.windowId; + const group = findGroupByWindow(windowId); + if (typeof group !== "undefined") { + const groupEvents = _groups[group.id]; + if (heardForWindowsCounter === -1) { + heardForWindowsCounter = group.windows.length; + } + heardForWindowsCounter--; + if (heardForWindowsCounter === 0) { + heardForWindowsCounter = -1; + groupEvents.groupInternal.handleGroupHeaderVisibilityChanged(windowInfo); + } + } + }); + environment.onGroupVisibilityChanged((data) => { + const groupEvents = _groups[data.groupId]; + if (groupEvents) { + groupEvents.groupInternal.handleGroupVisibilityChanged(data.visible); + } + }); + environment.onGroupStateChanged((data) => { + const groupWrapper = _groups[data.groupId]; + if (data.state === "hibernated") { + if (groupWrapper === null || groupWrapper === void 0 ? void 0 : groupWrapper.groupAPI) { + groupWrapper.groupInternal.handleGroupHibernateChanged(true); + } + _registry.execute("group-hibernated", data.groupId); + } + else if (data.state === "resumed") { + if (groupWrapper === null || groupWrapper === void 0 ? void 0 : groupWrapper.groupAPI) { + groupWrapper.groupInternal.handleGroupHibernateChanged(false); + } + _registry.execute("group-resumed", groupWrapper.groupAPI); + } + }); + function my() { + var _a; + return findGroupByWindow((_a = environment.myGroup()) !== null && _a !== void 0 ? _a : environment.my()); + } + async function create(options) { + if (isUndefinedOrNull(options)) { + throw new Error(`options must be defined`); + } + if (isUndefinedOrNull(options.groups) || !Array.isArray(options.groups) || options.groups.length === 0) { + throw new Error(`options.groups must be defined`); + } + const { groupIds } = await executor.executeGroup("createGroups", { + options + }); + const groups = groupIds.map((groupId) => { + return waitForGroup(groupId); + }); + return Promise.all(groups); + } + async function close(idOrGroup, options) { + if (isUndefinedOrNull(idOrGroup)) { + throw new Error(`group must be defined`); + } + let groupId = ""; + if (typeof idOrGroup === "string") { + groupId = idOrGroup; + } + else { + groupId = idOrGroup.id; + } + if (isUndefinedOrNull(options)) { + throw new Error(`options must be defined`); + } + await executor.executeGroup("closeGroup", { + groupId, + options + }); + } + function list(success) { + const result = Object.keys(_groups).map((groupId) => { + if (_groups[groupId]) { + return _groups[groupId].groupAPI; + } + }); + if (typeof success === "function") { + success(result); + } + return result; + } + function findGroupByWindow(winId, success, error) { + let windowId; + if (typeof winId === "string") { + windowId = winId; + } + else if (!isUndefinedOrNull(winId)) { + windowId = winId.id; + } + const result = Object.values(_groups).find((groupObj) => { + const group = groupObj.groupAPI; + const wins = group.windows.filter((w) => w.id === windowId); + return wins.length; + }); + if (result) { + if (typeof success === "function") { + success(result.groupAPI); + } + return result.groupAPI; + } + else if (typeof error === "function") { + error(`Cannot find the group of the window.`); + } + } + function waitForGroup(groupId) { + if (!groupId) { + return Promise.reject(new Error(`groupId must be defined`)); + } + return new Promise((res, rej) => { + const groupWrapper = _groups[groupId]; + if (groupWrapper) { + res(groupWrapper.groupAPI); + } + else { + const un = onGroupAdded((group) => { + if (group.id === groupId) { + un(); + res(group); + } + }); + } + }); + } + function getMyGroup() { + var _a; + return waitForGroup((_a = environment.myGroup()) !== null && _a !== void 0 ? _a : environment.my()); + } + async function resume(groupId, activate) { + validateGroupIdArg(groupId); + if (!isUndefinedOrNull(activate) && !isBoolean(activate)) { + throw new Error("Activate flag must be a boolean!"); + } + activate = !isUndefinedOrNull(activate) ? activate : true; + await executor.executeGroup("resumeGroup", { + groupId, + options: { activate } + }); + } + async function hibernate(groupId) { + validateGroupIdArg(groupId); + await executor.executeGroup("hibernateGroup", { + groupId + }); + return groupId; + } + function onGroupAdded(callback) { + return _registry.add("group-added", callback); + } + function onGroupRemoved(callback) { + return _registry.add("group-removed", callback); + } + function onWindowMoved(callback) { + return _registry.add("window-moved", callback); + } + function onHibernated(callback) { + if (!callback) { + throw new Error("Callback argument is required"); + } + if (callback && typeof callback !== "function") { + throw new Error("Callback argument must be a function"); + } + return _registry.add("group-hibernated", callback); + } + function onResumed(callback) { + if (!callback) { + throw new Error("Callback argument is required"); + } + if (callback && typeof callback !== "function") { + throw new Error("Callback argument must be a function"); + } + return _registry.add("group-resumed", callback); + } + function createOrGet(groupId) { + if (!_groups.hasOwnProperty(groupId)) { + const createdGroupWrapper = groupFactory(groupId, environment.executor); + _groups[groupId] = createdGroupWrapper; + const group = createdGroupWrapper.groupAPI; + _registry.execute("group-added", group); + return createdGroupWrapper; + } + else { + return _groups[groupId]; + } + } + function deleteIfEmpty(groupWrapper) { + const group = groupWrapper.groupAPI; + if (group.windows.length === 0) { + delete _groups[group.id]; + executor.clearCallbacks(group.id); + _registry.execute("group-removed", group); + } + } + function addWindow(groupId, winId) { + const group = createOrGet(groupId); + group.groupInternal.addWindow(winId); + return group; + } + function removeWindow(group, win) { + if (!group) { + return; + } + group.groupInternal.removeWindow(win); + deleteIfEmpty(group); + } + function handleCompositionChanged(state) { + const groupId = state.groupId; + const windowId = state.windowId; + const win = windowStore.get(windowId); + if (!win) { + return; + } + const currentGroup = findGroupWrapperByWindow(win.API); + if (isUndefinedOrNull(groupId)) { + removeWindow(currentGroup, win); + return; + } + if (isUndefinedOrNull(currentGroup) && !isUndefinedOrNull(groupId)) { + addWindow(groupId, win.API.id); + return; + } + if (currentGroup.groupAPI.id !== groupId) { + moveWindow(win, currentGroup.groupAPI.id, groupId); + } + } + function moveWindow(win, from, to) { + const winId = win.API.id; + const fromGroup = _groups[from]; + removeWindow(fromGroup, win); + const toGroup = addWindow(to, winId); + win.Events.handleGroupChanged(toGroup.groupAPI, fromGroup.groupAPI); + _registry.execute("window-moved", winId, from, to); + } + function findGroupWrapperByWindow(winId) { + let windowId; + if (typeof winId === "string") { + windowId = winId; + } + else if (!isUndefinedOrNull(winId)) { + windowId = winId.id; + } + return Object.values(_groups).find((groupObj) => { + const groupInternal = groupObj.groupInternal; + const wins = groupInternal.windows.filter((id) => id === windowId); + return wins.length; + }); + } + function validateGroupIdArg(groupId) { + if (!groupId || typeof groupId !== "string") { + throw new Error("Please provide a valid Group ID as a non-empty string!"); + } + } + const groups = { + get my() { + return my(); + }, + create, + close, + list, + findGroupByWindow, + waitForGroup, + getMyGroup, + onGroupAdded, + onGroupRemoved, + hibernate, + resume, + onHibernated, + onResumed + }; + const events = { onWindowMoved }; + return { + groupsAPI: groups, + groupsEvents: events, + }; + }; + + var WindowsFactory = (agm, logger, appManagerGetter, displayAPIGetter, channelsGetter, gdMajorVersion) => { + const _registry = CallbackRegistryFactory(); + const _logger = logger; + let groups; + let environment; + windowStore.init(_logger); + const isReady = new Promise((resolve, reject) => { + envDetector(agm, _logger, appManagerGetter, displayAPIGetter, channelsGetter, gdMajorVersion) + .then((env) => { + environment = env; + groups = groupsFactory(env); + jumpListManager.init(env.executor, agm, _logger); + resolve(); + }) + .catch((e) => { + const err = `Timed out waiting for connection to Glue42 Enterprise: Error: ${e.message}`; + _logger.error(err, e); + reject(new Error(err)); + }); + }); + function ready() { + return isReady; + } + function my() { + const myWindow = windowStore.getIfReady(environment.my()); + return myWindow ? myWindow.API : undefined; + } + function open(name, url, options, success, error) { + return Utils.callbackifyPromise(() => { + if (isNullOrWhiteSpace(name)) { + throw new Error("The window name is missing."); + } + if (isNullOrWhiteSpace(url)) { + throw new Error("The window URL is missing."); + } + if (!isUndefinedOrNull(options)) { + const optionsAsAny = options; + for (const prop of ["minHeight", "maxHeight", "minWidth", "maxWidth", "width", "height", "top", "left"]) { + if (prop in optionsAsAny) { + const value = optionsAsAny[prop]; + if (isUndefinedOrNull(value)) { + delete optionsAsAny[prop]; + continue; + } + if (!isNumber(value)) { + const errMessage = `${prop} must be a number`; + throw new Error(errMessage); + } + if (optionsAsAny[prop] === "width" || optionsAsAny[prop] === "height") { + if (value <= 0) { + const errMessage = `${prop} must be a positive number`; + throw new Error(errMessage); + } + } + } + } + } + return environment.open(name, url, options); + }, success, error); + } + function find(name, success, error) { + const windows = windowStore.list; + const windowsForListing = Object.keys(windows).reduce((memo, winId) => { + var _a; + const window = windows[winId]; + if (((_a = window === null || window === void 0 ? void 0 : window.API) === null || _a === void 0 ? void 0 : _a.name) === name) { + memo.push(window.API); + } + return memo; + }, []); + const win = windowsForListing[0]; + if (win) { + if (typeof success === "function") { + success(windowsForListing[0]); + } + return windowsForListing[0]; + } + else { + if (typeof error === "function") { + error("There is no window with name:" + name); + } + } + } + function findById(id, success, error) { + const windows = windowStore.list; + const windowsForListing = Object.keys(windows).reduce((memo, winId) => { + const window = windows[winId]; + if (typeof window !== "undefined" && window.API.id === id) { + memo.push(window.API); + } + return memo; + }, []); + const win = windowsForListing[0]; + if (win) { + if (typeof success === "function") { + success(windowsForListing[0]); + } + return windowsForListing[0]; + } + else { + if (typeof error === "function") { + error("There is no window with such id:" + id); + } + } + } + function list(success) { + const windows = windowStore.list; + const windowsForListing = Object.keys(windows) + .map((k) => { + return windows[k].API; + }); + if (typeof success !== "function") { + return windowsForListing; + } + success(windowsForListing); + } + function configure(options) { + const win = my(); + const winId = win ? win.id : ""; + return executor.configure(winId, options); + } + function autoArrange(displayId) { + return executor.autoArrange(displayId); + } + function windowAdded(callback) { + return _registry.add("window-added", callback); + } + function windowRemoved(callback) { + return _registry.add("window-removed", callback); + } + function tabAttached(callback) { + let unsubFunc; + let unsubscribed = false; + isReady.then(() => { + if (unsubscribed) { + return; + } + unsubFunc = environment.tabAttached(callback); + }); + return () => { + unsubscribed = true; + if (unsubFunc) { + unsubFunc(); + } + }; + } + function tabDetached(callback) { + let unsubFunc; + let unsubscribed = false; + isReady.then(() => { + if (unsubscribed) { + return; + } + unsubFunc = environment.tabDetached(callback); + }); + return () => { + unsubscribed = true; + if (unsubFunc) { + unsubFunc(); + } + }; + } + function onWindowFrameColorChanged(callback) { + let unsubFunc; + let unsubscribed = false; + isReady.then(() => { + if (unsubscribed) { + return; + } + unsubFunc = environment.onWindowFrameColorChanged(callback); + }); + return () => { + unsubscribed = true; + if (unsubFunc) { + unsubFunc(); + } + }; + } + function onWindowGotFocus(callback) { + let unsubFunc; + let unsubscribed = false; + isReady.then(() => { + if (unsubscribed) { + return; + } + unsubFunc = environment.onWindowGotFocus(callback); + }); + return () => { + unsubscribed = true; + if (unsubFunc) { + unsubFunc(); + } + }; + } + function onWindowLostFocus(callback) { + let unsubFunc; + let unsubscribed = false; + isReady.then(() => { + if (unsubscribed) { + return; + } + unsubFunc = environment.onWindowLostFocus(callback); + }); + return () => { + unsubscribed = true; + if (unsubFunc) { + unsubFunc(); + } + }; + } + function onArrangementChanged(callback) { + return environment.onWindowsAutoArrangeChanged(callback); + } + function onEvent(callback) { + let unsubFunc; + let unsubscribed = false; + isReady.then(() => { + if (unsubscribed) { + return; + } + unsubFunc = environment.onEvent(callback); + }); + return () => { + unsubscribed = true; + if (unsubFunc) { + unsubFunc(); + } + }; + } + function createFlydown(targetId, config) { + return environment.createFlydown(targetId, config); + } + function showPopup(targetId, config) { + return environment.showPopup(targetId, config); + } + function handleWindowAdded(w) { + _registry.execute("window-added", w.API); + } + function handleWindowRemoved(w) { + _registry.execute("window-removed", w.API); + } + windowStore.onReadyWindow(handleWindowAdded); + windowStore.onRemoved(handleWindowRemoved); + return { + my, + open, + find, + findById, + list, + ready, + onWindowAdded: windowAdded, + windowAdded, + onWindowRemoved: windowRemoved, + windowRemoved, + onTabAttached: tabAttached, + onTabDetached: tabDetached, + onWindowFrameColorChanged, + onArrangementChanged, + get groups() { + return groups.groupsAPI; + }, + onWindowGotFocus, + onWindowLostFocus, + onEvent, + createFlydown, + showPopup, + configure, + autoArrange + }; + }; + + class LayoutStore { + constructor() { + this.layouts = []; + } + removeWhere(condition) { + this.layouts = this.layouts.filter(condition); + } + removeAll() { + this.layouts = []; + } + add(item) { + this.layouts.push(item); + } + get all() { + return this.layouts; + } + where(condition) { + return this.layouts.filter(condition); + } + first(condition) { + return this.where(condition)[0]; + } + } + var store = new LayoutStore(); + + const SaveContextMethodName = "T42.HC.GetSaveContext"; + class ContextProvider { + constructor(config, activitiesGetter, callbacks, logger) { + this.config = config; + this.activitiesGetter = activitiesGetter; + this.callbacks = callbacks; + this.logger = logger; + this.interop = config.agm; + this.registerRequestMethods(); + } + onSaveRequested(callback) { + return this.callbacks.add("saveRequested", callback); + } + isActivityOwner() { + if (typeof htmlContainer !== "undefined") { + const context = htmlContainer.getContext(); + return context && context._t42 && context._t42.activityIsOwner; + } + const activities = this.activitiesGetter(); + if (!activities) { + return false; + } + if (!activities.inActivity) { + return false; + } + const myWindow = activities.my.window; + const myActivity = activities.my.activity; + if (!myActivity && !myWindow) { + return false; + } + return myActivity.owner.id === myWindow.id; + } + registerRequestMethods() { + this.interop.register(SaveContextMethodName, (args) => { + const usersCbs = this.callbacks.execute("saveRequested", args); + if ((usersCbs === null || usersCbs === void 0 ? void 0 : usersCbs.length) > 1) { + this.logger.warn(`Multiple subscriptions for "glue.layouts.onSaveRequested" - only the first one will be used`); + } + const requestResult = usersCbs[0]; + const autoSaveWindowContext = this.config.autoSaveWindowContext; + if (typeof autoSaveWindowContext === "boolean" && autoSaveWindowContext) { + return { autoSaveWindowContext }; + } + else if (Array.isArray(autoSaveWindowContext) && autoSaveWindowContext.length > 0) { + return { autoSaveWindowContext }; + } + const result = { windowContext: requestResult === null || requestResult === void 0 ? void 0 : requestResult.windowContext, activityContext: undefined }; + if (this.isActivityOwner()) { + result.activityContext = requestResult === null || requestResult === void 0 ? void 0 : requestResult.activityContext; + } + return result; + }); + } + } + + function transformACSLayout(something) { + if (!something) { + return something; + } + if (Array.isArray(something)) { + return something.map((item) => { + return transformACSLayout(item); + }); + } + if (typeof something === "string" || typeof something === "number" || typeof something === "boolean") { + return something; + } + const initial = {}; + return Object.keys(something).reduce((accumulator, current) => { + var _a; + const value = something[current]; + const convertedValue = transformACSLayout(value); + let key = current; + if (((_a = current[0]) === null || _a === void 0 ? void 0 : _a.toLowerCase()) !== current[0]) { + key = current[0].toLowerCase() + current.substr(1); + } + accumulator[key] = convertedValue; + return accumulator; + }, initial); + } + + class LayoutImpl { + constructor(data) { + this.name = data.name; + this.type = data.type; + this.components = data.components; + this.context = data.context; + this.metadata = data.metadata; + this.version = data.version; + this.displays = data.displays; + } + } + + var main = {}; + + var application = {}; + + /** + * This file was automatically generated by json-schema-to-typescript. + * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file, + * and run json-schema-to-typescript to regenerate this file. + */ + Object.defineProperty(application, "__esModule", { value: true }); + + var system = {}; + + /** + * This file was automatically generated by json-schema-to-typescript. + * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file, + * and run json-schema-to-typescript to regenerate this file. + */ + Object.defineProperty(system, "__esModule", { value: true }); + + var layout = {}; + + Object.defineProperty(layout, "__esModule", { value: true }); + layout.SwimlaneItemType = layout.LayoutType = void 0; + var LayoutType; + (function (LayoutType) { + LayoutType["Global"] = "Global"; + LayoutType["Activity"] = "Activity"; + LayoutType["ApplicationDefault"] = "ApplicationDefault"; + LayoutType["Swimlane"] = "Swimlane"; + LayoutType["Workspaces"] = "Workspace"; + })(LayoutType || (layout.LayoutType = LayoutType = {})); + var SwimlaneItemType; + (function (SwimlaneItemType) { + SwimlaneItemType["Tab"] = "tab"; + SwimlaneItemType["Window"] = "window"; + SwimlaneItemType["Canvas"] = "canvas"; + })(SwimlaneItemType || (layout.SwimlaneItemType = SwimlaneItemType = {})); + + var swTheme = {}; + + /** + * This file was automatically generated by json-schema-to-typescript. + * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file, + * and run json-schema-to-typescript to regenerate this file. + */ + Object.defineProperty(swTheme, "__esModule", { value: true }); + + var swConfiguration = {}; + + /** + * This file was automatically generated by json-schema-to-typescript. + * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file, + * and run json-schema-to-typescript to regenerate this file. + */ + Object.defineProperty(swConfiguration, "__esModule", { value: true }); + + (function (exports) { + var __createBinding = (commonjsGlobal && commonjsGlobal.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; + })); + var __exportStar = (commonjsGlobal && commonjsGlobal.__exportStar) || function(m, exports) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); + }; + Object.defineProperty(exports, "__esModule", { value: true }); + // export { SchemaValidator } from "./validator"; + // export { FileProvider } from "./fileProvider"; + // export { SchemaProvider } from "./provider"; + __exportStar(application, exports); + __exportStar(system, exports); + __exportStar(layout, exports); + __exportStar(swTheme, exports); + __exportStar(swConfiguration, exports); + + } (main)); + + const LayoutsCommandMethod = "T42.ACS.Command"; + class LayoutsAPIImpl { + constructor(config, stream, callbacks, logger) { + this.config = config; + this.stream = stream; + this.callbacks = callbacks; + this.isRegisterMethodForLayoutModified = false; + this.appManager = config.appManager; + this.provider = new ContextProvider(config, config.activityGetter, callbacks, logger); + stream.subscribe(); + } + async setDefaultGlobal(name) { + const methodName = "SelectDefaultLayout"; + await this.invokeMethodCore(methodName, { name }); + return; + } + async clearDefaultGlobal() { + const methodName = "DeselectDefaultLayout"; + await this.invokeMethodCore(methodName); + return; + } + async getDefaultGlobal() { + const methodName = "GetDefaultLayout"; + const result = await this.invokeMethodCore(methodName); + const layout = result.returned; + if (layout === null || layout === undefined || (typeof layout === 'object' && Object.keys(layout).length === 0)) { + return undefined; + } + return objectClone(this.isSlimMode() ? layout : this.list().find((l) => l.name === layout.name && l.type === layout.type)); + } + ready() { + if (this.config.mode === "fullWaitSnapshot") { + return this.stream.gotSnapshot; + } + return this.stream.ready; + } + save(layout) { + return new Promise((resolve, reject) => { + var _a, _b; + this.verifyNotSlimMode(); + if (isUndefinedOrNull(layout)) { + return reject(new Error("layout is required")); + } + if (isNullOrWhiteSpace(layout.name)) { + return reject(new Error("layout.name argument is required")); + } + if (isNullOrWhiteSpace(layout.type)) { + layout.type = "Global"; + } + if (!isNullOrWhiteSpace(layout.activityId)) { + layout.type = "Activity"; + } + const layoutObject = { + name: layout.name, + type: layout.type, + context: (_a = layout.context) !== null && _a !== void 0 ? _a : {}, + metadata: (_b = layout.metadata) !== null && _b !== void 0 ? _b : {}, + options: {}, + }; + if (layout.type === "Activity") { + let actId = layout.activityId; + if (!actId) { + if (!this.appManager.myInstance.inActivity) { + return reject(new Error("Current application is not in activity. Cannot save activity layout for it.")); + } + actId = this.appManager.myInstance.activityId; + } + layoutObject.activityId = actId; + } + else if (layout.type === "Global") { + if (Array.isArray(layout.ignoreInstances)) { + layoutObject.options.ignoreInstances = layout.ignoreInstances; + } + if (Array.isArray(layout.instances)) { + layoutObject.options.instances = layout.instances; + } + if (typeof layout.setAsCurrent === "boolean") { + layoutObject.options.setAsCurrent = layout.setAsCurrent; + } + } + else { + return reject(new Error(`layout type ${layout.type} is not supported`)); + } + this.invokeMethodAndTrack("SaveLayout", layoutObject, resolve, reject); + }); + } + restore(options) { + return new Promise((resolve, reject) => { + var _a, _b, _c; + this.verifyNotSlimMode(); + if (isUndefinedOrNull(options)) { + return reject(new Error("options argument is required")); + } + if (isNullOrWhiteSpace(options.name)) { + return reject(new Error("options.name argument is required")); + } + if (isNullOrWhiteSpace(options.type)) { + options.type = "Global"; + } + if (!isNullOrWhiteSpace(options.activityIdToJoin)) { + options.type = "Activity"; + } + if (options.type === "Activity") { + if (isUndefinedOrNull(options.setActivityContext)) { + options.setActivityContext = true; + } + if (typeof options.setActivityContext !== "boolean") { + return reject(new Error("`setActivityContext` must hold a boolean value.")); + } + options.activityIdToJoin = (_a = options.activityIdToJoin) !== null && _a !== void 0 ? _a : this.appManager.myInstance.activityId; + } + if (!isUndefinedOrNull(options.closeRunningInstance)) { + options.closeRunningInstances = options.closeRunningInstance; + } + if (isUndefinedOrNull(options.closeRunningInstances)) { + options.closeRunningInstances = true; + } + if (!isBoolean(options.closeRunningInstances)) { + return reject(new Error("`closeRunningInstances` must hold a boolean value.")); + } + if (isUndefinedOrNull(options.closeMe)) { + options.closeMe = options.closeRunningInstances; + } + if (!isBoolean(options.closeMe)) { + return reject(new Error("`closeMe` must hold a boolean value.")); + } + if (!isUndefinedOrNull(options.context) && !isObject(options.context)) { + return reject(new Error("`context` must hold an object value.")); + } + if (!isUndefinedOrNull(options.timeout) && typeof options.timeout !== "number") { + return reject(new Error("`timeout` must hold an number value.")); + } + options.context = (_b = options.context) !== null && _b !== void 0 ? _b : {}; + const restoreOptions = { + activityToJoin: options.activityIdToJoin, + setActivityContext: options.setActivityContext, + ignoreActivityWindowTypes: options.ignoreActivityWindowTypes, + reuseExistingWindows: options.reuseWindows, + closeRunningInstances: options.closeRunningInstances, + excludeFromClosing: options.closeMe ? [] : [(_c = this.appManager.myInstance) === null || _c === void 0 ? void 0 : _c.id] + }; + const arg = { + type: options.type, + name: options.name, + context: options.context, + options: restoreOptions + }; + if (options.timeout) { + arg.timeout = options.timeout; + } + this.invokeMethodAndTrack("RestoreLayout", arg, resolve, reject, true); + }); + } + reset(options) { + return new Promise((resolve, reject) => { + this.verifyNotSlimMode(); + if (typeof options !== "object") { + return reject(new Error("options argument is required")); + } + if (isNullOrWhiteSpace(options.layoutId)) { + return reject(new Error("options.layoutId argument is required")); + } + const msg = { + ...options + }; + this.invokeMethodAndTrack("ResetLayout", msg, resolve, reject, true); + }); + } + remove(type, name) { + return new Promise((resolve, reject) => { + this.verifyNotSlimMode(); + if (!name) { + return reject(new Error("name argument is required")); + } + if (!type) { + return reject(new Error("type argument is required")); + } + const msg = { + type, + name, + }; + this.invokeMethodAndTrack("RemoveLayout", msg, resolve, reject); + }); + } + list() { + this.verifyNotSlimMode(); + return objectClone(store.all); + } + import(layouts, mode) { + return new Promise((resolve, reject) => { + this.verifyNotSlimMode(); + if (!isUndefinedOrNull(mode)) { + if (mode !== "merge" && mode !== "replace") { + return reject(new Error(`${mode} is not supported - only "merge" and "replace"`)); + } + } + if (!Array.isArray(layouts)) { + return reject(new Error("layouts arguments is not an array")); + } + const msg = { + mode: mode || "replace", + layouts + }; + this.invokeMethodAndTrack("ImportLayouts", msg, resolve, reject, true); + }); + } + export(layoutType) { + return new Promise((resolve, reject) => { + var _a; + if (!isUndefinedOrNull(layoutType) && !((_a = Object.values(main.LayoutType)) === null || _a === void 0 ? void 0 : _a.includes(layoutType))) { + return reject(new Error(`${layoutType} is not a supported Layout Type`)); + } + const handleResult = (result) => { + let layouts = this.getObjectValues(result.Layouts).map((t) => new LayoutImpl(transformACSLayout(t))); + if (layoutType) { + layouts = layouts.filter((l) => l.type === layoutType); + } + resolve(layouts); + }; + this.invokeMethodAndTrack("ExportLayouts", {}, handleResult, reject, true); + }); + } + rename(layout, newName) { + return new Promise((resolve, reject) => { + this.verifyNotSlimMode(); + if (!layout) { + return reject(new Error("layout argument is required")); + } + if (!layout.name) { + return reject(new Error("name argument is required")); + } + if (!layout.type) { + return reject(new Error("type argument is required")); + } + const msg = { type: layout.type, oldName: layout.name, newName }; + this.invokeMethodAndTrack("RenameLayout", msg, resolve, reject); + }); + } + updateMetadata(layout) { + return new Promise((resolve, reject) => { + if (!layout) { + return reject(new Error("layout argument is required")); + } + if (!layout.name) { + return reject(new Error("name argument is required")); + } + if (!layout.type) { + return reject(new Error("type argument is required")); + } + if (!layout.metadata) { + return reject(new Error("metadata argument is required")); + } + const layoutObject = { + name: layout.name, + type: layout.type, + metadata: layout.metadata + }; + this.invokeMethodAndTrack("UpdateMetadata", layoutObject, resolve, reject, true); + }); + } + hibernate(name, options) { + return new Promise((resolve, reject) => { + if (!name) { + return reject(new Error("name cannot be empty")); + } + options = options || {}; + const request = { + name, + type: "Global", + context: options.context || {}, + metadata: options.metadata || {}, + }; + this.invokeMethodAndTrack("HibernateLayout", request, resolve, reject, true); + }); + } + resume(name, context, options) { + return new Promise((resolve, reject) => { + if (!name) { + return reject(new Error("name cannot be empty")); + } + const request = { + name, + type: "Global", + context, + ...options + }; + this.invokeMethodAndTrack("ResumeLayout", request, resolve, reject, true); + }); + } + async getCurrentLayout() { + const methodName = "GetCurrentLayout"; + const result = await this.invokeMethodCore(methodName); + let layout = result.returned.layout; + if (!layout) { + return undefined; + } + if (!this.isSlimMode()) { + layout = this.list().find((l) => l.name === layout.name && l.type === layout.type); + } + return objectClone(layout); + } + getRestoredLayoutsInfo() { + return new Promise((resolve, reject) => { + const methodName = "GetRestoredLayoutsInfo"; + this.invokeMethodCore(methodName) + .then((result) => { + const restoredLayouts = result.returned; + resolve(restoredLayouts); + }) + .catch(reject); + }); + } + onAdded(callback) { + const result = this.callbacks.add("added", callback); + if (store.all.length > 0) { + store.all.forEach((layout) => { + try { + callback(layout); + } + catch (err) { } + }); + } + return result; + } + onRemoved(callback) { + return this.callbacks.add("removed", callback); + } + onChanged(callback) { + return this.callbacks.add("changed", callback); + } + onRestored(callback) { + return this.callbacks.add("restored", callback); + } + onRenamed(callback) { + return this.callbacks.add("renamed", callback); + } + onEvent(callback) { + return this.stream.onEvent(callback); + } + onSaveRequested(callback) { + return this.provider.onSaveRequested(callback); + } + onLayoutModified(callback) { + if (this.isRegisterMethodForLayoutModified === false) { + this.isRegisterMethodForLayoutModified = true; + this.registerMethodForLayoutModified(); + } + return this.callbacks.add("layout-modified", callback); + } + updateAppContextInCurrent(context) { + return new Promise((resolve, reject) => { + if (context && typeof context !== "object") { + return reject(new Error("Context must be an object")); + } + context = context !== null && context !== void 0 ? context : {}; + const request = { + context + }; + this.invokeMethodAndTrack("UpdateLayoutComponentContext", request, resolve, reject, true); + }); + } + updateDefaultContext(context) { + return new Promise((resolve, reject) => { + if (context && typeof context !== "object") { + return reject(new Error("Context must be an object")); + } + context = context !== null && context !== void 0 ? context : {}; + const request = { + context + }; + this.invokeMethodAndTrack("UpdateDefaultContext", request, resolve, reject, true); + }); + } + async get(name, type) { + const matching = this.list().find((l) => l.name === name && l.type === type); + if (!matching) { + throw new Error(`cannot find layout with name=${name} and type=${type}`); + } + return objectClone(matching); + } + async getAll(type) { + var _a; + if (!isUndefinedOrNull(type) && !((_a = Object.values(main.LayoutType)) === null || _a === void 0 ? void 0 : _a.includes(type))) { + throw new Error((`${type} is not a supported Layout Type`)); + } + const matching = this.list().filter((l) => type === l.type); + return objectClone(matching); + } + async forceRefresh() { + const methodName = "RefreshLayouts"; + await this.invokeMethodCore(methodName); + } + isSlimMode() { + return this.config.mode === "slim"; + } + verifyNotSlimMode() { + if (this.isSlimMode()) { + throw Error("Operation not allowed in slim mode. Run in full mode."); + } + } + async registerMethodForLayoutModified() { + await this.config.agm.register("T42.ACS.LayoutModified", (args, caller) => { + this.callbacks.execute("layout-modified", args); + }); + } + invokeMethodAndTrack(methodName, args, resolve, reject, skipStreamEvent) { + let streamEventReceived = skipStreamEvent; + let agmResult; + const token = Utils.generateId(); + args.token = token; + const handleResult = () => { + if (streamEventReceived && agmResult) { + resolve(agmResult); + } + }; + const methodResponseTimeoutMs = 120 * 1000; + if (!skipStreamEvent) { + this.stream.waitFor(token, methodResponseTimeoutMs) + .then(() => { + streamEventReceived = true; + handleResult(); + }) + .catch((err) => { + reject(err); + }); + } + const responseHandler = (result) => { + if (!result.returned) { + return reject(new Error("No result from method " + methodName)); + } + if (result.returned.status && (result.returned.status !== "Success" && result.returned.status !== "PartialSuccess")) { + if (typeof (result.returned) === "string") { + return reject(new Error(result.returned)); + } + else if (typeof (result.returned) === "object") { + if (result.returned.status && result.returned.failed) { + return reject(new Error(`${result.returned.status}: ${JSON.stringify(result.returned.failed)}`)); + } + else { + return reject(new Error(result.returned)); + } + } + } + agmResult = result.returned; + handleResult(); + }; + this.invokeMethodCore(methodName, args, "best", { methodResponseTimeoutMs }) + .then(responseHandler) + .catch((err) => reject(err)); + } + async invokeMethodCore(methodName, args, target, options) { + options = options !== null && options !== void 0 ? options : {}; + if (typeof options.methodResponseTimeoutMs === "undefined") { + options.methodResponseTimeoutMs = INTEROP_METHOD_WAIT_TIMEOUT_MS; + } + if (typeof options.waitTimeoutMs === "undefined") { + options.waitTimeoutMs = INTEROP_METHOD_WAIT_TIMEOUT_MS; + } + if (this.isCommandMethodPresent()) { + return await this.config.agm.invoke(LayoutsCommandMethod, { command: methodName, data: args }, target, options); + } + else { + return await this.config.agm.invoke(`T42.ACS.${methodName}`, args, target, options); + } + } + getObjectValues(obj) { + if (!obj) { + return []; + } + return Object.keys(obj).map((k) => obj[k]); + } + isCommandMethodPresent() { + return this.config.agm.methods().some((method) => method.name === LayoutsCommandMethod); + } + } + + class ACSStream { + constructor(agm, callbacks) { + this.agm = agm; + this.callbacks = callbacks; + this.StreamName = "T42.ACS.OnLayoutEvent"; + this.ready = new Promise((resolve, reject) => { + this.resolveReady = resolve; + this.rejectReady = reject; + }); + this.gotSnapshot = new Promise((resolve, reject) => { + this.resolveGotSnapshot = resolve; + this.rejectGotSnapshot = reject; + }); + } + subscribe(noRetry) { + const transform = (obj) => { + return this.getObjectValues(obj).map((t) => transformACSLayout(t)); + }; + if (!this.checkForLayoutEventMethod()) { + if (noRetry) { + this.resolveReady(); + } + setTimeout(() => { + this.subscribe(true); + }, 500); + } + else { + this.agm.subscribe(this.StreamName, { waitTimeoutMs: 10000 }) + .then((subs) => { + subs.onData((args) => { + const data = args.data; + if (data.IsSnapshot) { + this.resolveGotSnapshot(); + } + this.addLayouts(transform(data.OnLayoutAdded), data.IsSnapshot); + this.removeLayouts(transform(data.OnLayoutRemoved)); + this.changeLayouts(transform(data.OnLayoutChanged)); + this.renameLayouts(transform(data.OnLayoutRenamed)); + this.restoredLayout(transform(data.OnLayoutRestored)); + this.callbacks.execute("streamEvent", data); + }); + subs.onFailed((err) => { + const msg = `Can not subscribe to "${this.StreamName}" stream - ${JSON.stringify(err)}`; + this.rejectReady(msg); + this.rejectGotSnapshot(msg); + }); + this.resolveReady(); + }) + .catch((err) => { + const msg = `Error subscribing to "${this.StreamName}" stream - ${JSON.stringify(err)}`; + this.rejectReady(msg); + this.rejectGotSnapshot(msg); + }); + } + } + onEvent(callback) { + return this.callbacks.add("streamEvent", callback); + } + waitFor(token, timeout) { + if (!timeout) { + timeout = 30000; + } + return new Promise((resolve, reject) => { + let done = false; + const unsubscribe = this.onEvent((streamEvent) => { + if (streamEvent.Token === token) { + done = true; + unsubscribe(); + resolve(); + } + }); + setTimeout(() => { + if (!done) { + reject("timed out"); + } + }, timeout); + }); + } + checkForLayoutEventMethod() { + try { + return this.agm + .methods() + .map((m) => m.name) + .indexOf(this.StreamName) !== -1; + } + catch (e) { + return false; + } + } + addLayouts(layoutsData, isSnapshot) { + if (!layoutsData) { + return; + } + const createAndNotifyLayout = (layoutData) => { + const layout = new LayoutImpl(layoutData); + store.add(layout); + this.callbacks.execute("added", layout); + }; + layoutsData.forEach((layoutData) => { + if (isSnapshot) { + const found = store.first((existingLayout) => this.compareLayouts(existingLayout, layoutData)); + if (!found) { + createAndNotifyLayout(layoutData); + } + } + else { + createAndNotifyLayout(layoutData); + } + }); + } + removeLayouts(removedLayouts) { + if (!removedLayouts) { + return; + } + removedLayouts.forEach((removedLayout) => { + store.removeWhere((existingLayout) => !this.compareLayouts(existingLayout, removedLayout)); + this.callbacks.execute("removed", removedLayout); + }); + } + changeLayouts(changedLayouts) { + if (!changedLayouts) { + return; + } + changedLayouts.forEach((changedLayout) => { + store.removeWhere((existingLayout) => !this.compareLayouts(existingLayout, changedLayout)); + store.add(new LayoutImpl(changedLayout)); + this.callbacks.execute("changed", changedLayout); + }); + } + renameLayouts(renamedLayouts) { + if (!renamedLayouts) { + return; + } + renamedLayouts.forEach((renamedLayout) => { + const existingLayout = store.first((current) => this.compareLayouts(current, { type: renamedLayout.type, name: renamedLayout.oldName })); + if (!existingLayout) { + throw Error(`received rename event for unknown layout with type ${renamedLayout.type} and name ${renamedLayout.oldName}`); + } + existingLayout.name = renamedLayout.newName; + this.callbacks.execute("renamed", existingLayout); + }); + } + compareLayouts(layout1, layout2) { + return layout1.name === layout2.name && layout1.type === layout2.type; + } + getObjectValues(obj) { + if (!obj) { + return []; + } + return Object.keys(obj).map((k) => obj[k]); + } + restoredLayout(restoredLayouts) { + if (!restoredLayouts) { + return; + } + restoredLayouts.forEach((restoredLayout) => { + const existingLayout = store.first((current) => this.compareLayouts(current, { type: restoredLayout.type, name: restoredLayout.name })); + this.callbacks.execute("restored", existingLayout); + }); + } + } + + function LayoutsFactory (config) { + if (!config.agm) { + throw Error("config.agm is required"); + } + if (!config.logger) { + throw Error("config.logger is required"); + } + config.mode = config.mode || "slim"; + const logger = config.logger; + const callbacks = CallbackRegistryFactory(); + let acsStream; + if (config.mode === "full" || "fullWaitSnapshot") { + acsStream = new ACSStream(config.agm, callbacks); + } + return new LayoutsAPIImpl(config, acsStream, callbacks, logger); + } + + const T42DisplayCommand = "T42.Displays.Command"; + const T42DisplayOnEvent = "T42.Displays.OnEvent"; + class DisplayManager { + constructor(_agm, _logger) { + this._agm = _agm; + this._logger = _logger; + this._registry = CallbackRegistryFactory(); + this._registered = false; + this.all = async () => { + const displays = await this.callGD(DisplayCommand.GetAll, {}); + return displays.map(this.decorateDisplay); + }; + this.get = async (id) => { + const display = await this.callGD(DisplayCommand.Get, { id }); + return this.decorateDisplay(display); + }; + this.getPrimary = async () => { + const primary = (await this.all()).find((d) => d.isPrimary); + return primary; + }; + this.capture = async (options) => { + const screenshot = await this.callGD(DisplayCommand.Capture, { ...options }); + return screenshot; + }; + this.captureAll = async (options) => { + const screenshots = await this.callGD(DisplayCommand.CaptureAll, { ...options }); + return screenshots; + }; + this.getMousePosition = async () => { + const point = await this.callGD(DisplayCommand.GetMousePosition); + return point; + }; + this.callGD = async (command, options) => { + const invocationResult = await this._agm.invoke(T42DisplayCommand, { options: { ...options }, command }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return invocationResult.returned.data; + }; + this.decorateDisplay = (original) => { + const decoratedDisplay = { + ...original, + capture: (size) => this.capture({ id: original.id, size }) + }; + const workAreaAsAny = decoratedDisplay.workArea; + workAreaAsAny.x = workAreaAsAny.left; + workAreaAsAny.y = decoratedDisplay.workArea.top; + return decoratedDisplay; + }; + } + getByWindowId(id) { + const current = this.callGD(DisplayCommand.GetByWindowId, { id }); + return current; + } + onDisplayChanged(cb) { + this.register(); + return this._registry.add("on-display-changed", cb); + } + register() { + if (this._registered) { + return; + } + this._registered = true; + this._agm.register(T42DisplayOnEvent, (args, caller) => { + const event = args.event; + const data = args.data; + switch (event) { + case "display-changed": + this._registry.execute("on-display-changed", data.displays.map(this.decorateDisplay)); + break; + default: + this._logger.warn(`unknown event - ${event}`); + break; + } + }); + } + } + var DisplayCommand; + (function (DisplayCommand) { + DisplayCommand["Capture"] = "capture"; + DisplayCommand["CaptureAll"] = "captureAll"; + DisplayCommand["GetAll"] = "getAll"; + DisplayCommand["Get"] = "get"; + DisplayCommand["GetByWindowId"] = "getByWindowId"; + DisplayCommand["GetMousePosition"] = "getMousePosition"; + })(DisplayCommand || (DisplayCommand = {})); + + class SingleChannelID { + constructor(channel) { + this.channel = channel; + } + get isJoinedToAnyChannel() { + return !!this.channel; + } + isOnChannel(channel) { + return this.channel === channel; + } + leaveChannel(channel) { + if (channel === undefined || this.channel === channel) { + this.channel = undefined; + } + } + joinChannel(channel) { + this.channel = channel; + } + all() { + if (this.channel) { + return [this.channel]; + } + return []; + } + toString() { + return this.channel; + } + equals(other) { + if (other instanceof SingleChannelID) { + return this.channel === other.channel; + } + return false; + } + } + class MultiChannelId { + constructor(channels) { + this.ChannelDelimiter = "+++"; + if (!channels) { + this.channels = []; + } + else if (typeof channels === "string") { + this.channels = channels === null || channels === void 0 ? void 0 : channels.split(this.ChannelDelimiter).filter(Boolean); + } + else { + this.channels = (channels !== null && channels !== void 0 ? channels : []).filter(Boolean); + } + } + get isJoinedToAnyChannel() { + return this.channels.length > 0; + } + isOnChannel(channel) { + return this.channels.includes(channel); + } + joinChannel(channel) { + const newChannels = new MultiChannelId(channel); + newChannels.all().forEach((newChannel) => { + if (!this.channels.includes(newChannel)) { + this.channels.push(newChannel); + } + }); + } + leaveChannel(channel) { + const channelsToLeave = new MultiChannelId(channel !== null && channel !== void 0 ? channel : this.channels); + channelsToLeave.all().forEach((c) => { + this.channels = this.channels.filter((ch) => ch !== c); + }); + } + all() { + return this.channels; + } + toString() { + if (this.channels.length === 0) { + return undefined; + } + return this.channels.join(this.ChannelDelimiter); + } + equals(other) { + if (other instanceof MultiChannelId) { + return this.channels.length === other.channels.length && + this.channels.every((c, i) => c === other.channels[i]); + } + return false; + } + } + + let interop; + let myInstanceId; + let logger; + const T42_ANNOUNCE_METHOD_NAME = "T42.Channels.Announce"; + const T42_COMMAND_METHOD_NAME = "T42.Channels.Command"; + async function setupInterop(interopLib, channels, loggerAPI) { + var _a, _b; + logger = loggerAPI; + interop = interopLib; + if (typeof window !== "undefined") { + if (window.glue42gd) { + myInstanceId = window.glue42gd.windowId; + } + } + if (!myInstanceId) { + myInstanceId = interopLib.instance.instance; + } + await interop.register(T42_COMMAND_METHOD_NAME, (args) => { + const command = args.command; + if (!command) { + throw new Error("missing command argument"); + } + logger.trace(`received command "${command}" with ${JSON.stringify(args)}`); + if (command === "join") { + const id = args.channel; + if (!id) { + throw new Error("missing argument id"); + } + return channels.joinNoSelectorSwitch(id); + } + if (command === "leave") { + return channels.leaveNoSelectorSwitch(); + } + if (command === "get") { + const id = channels.current(); + return { id }; + } + if (command === "restrictions-changed") { + const restrictions = args.restrictions; + const targetWindowId = args.swId; + channels.handleRestrictionsChanged(restrictions, targetWindowId); + return; + } + if (command === "isFdc3DataWrappingSupported") { + return { isSupported: true }; + } + if (command === "join-multi") { + const channelsToJoin = args.channelsToJoin; + if (!channelsToJoin) { + throw new Error("missing argument channelsToJoin"); + } + return channels.joinNoSelectorSwitch(new MultiChannelId(channelsToJoin).toString()); + } + if (command === "leave-multi") { + const channelsToLeave = args.channelsToLeave; + return channels.leaveNoSelectorSwitch(new MultiChannelId(channelsToLeave).toString()); + } + throw new Error(`unknown command ${command}`); + }); + const result = await interop.invoke(T42_ANNOUNCE_METHOD_NAME, { swId: myInstanceId, instance: interop.instance.instance }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_RESPONSE_TIMEOUT_MS + }); + if ((_a = result.returned) === null || _a === void 0 ? void 0 : _a.restrictions) { + channels.handleRestrictionsChanged((_b = result.returned) === null || _b === void 0 ? void 0 : _b.restrictions, myInstanceId); + } + return result.returned; + } + async function sendLeaveChannel(channel, winId) { + var _a; + await invoke("leaveChannel", { channel }, (_a = winId !== null && winId !== void 0 ? winId : winId) !== null && _a !== void 0 ? _a : myInstanceId); + } + async function sendSwitchChannelUI(channel, winId) { + await invoke("switchChannel", { newChannel: channel }, winId !== null && winId !== void 0 ? winId : myInstanceId); + } + async function setRestrictions(restrictions) { + var _a; + await invoke("restrict", restrictions, (_a = restrictions.windowId) !== null && _a !== void 0 ? _a : myInstanceId); + } + async function getRestrictionsByWindow(id) { + try { + const result = await invoke("getRestrictions", {}, id !== null && id !== void 0 ? id : myInstanceId); + return result.returned; + } + catch (e) { + } + } + async function setRestrictionsForAllChannels(restrictions) { + var _a; + await invoke("restrictAll", restrictions, (_a = restrictions.windowId) !== null && _a !== void 0 ? _a : myInstanceId); + } + async function getChannelsInfo(filter) { + const result = await invoke("getChannelsInfo", { filter }); + return result.returned; + } + async function addOrRemoveChannel(command, id, color, label) { + await invoke(command, { id, color, label }); + } + async function getChannelInitInfo(config, i) { + if (typeof config.operationMode !== "boolean" && typeof config.operationMode === "string") { + validateMode(config.operationMode); + return { mode: config.operationMode, initialChannel: undefined }; + } + try { + const result = await i.invoke(T42_ANNOUNCE_METHOD_NAME, { command: "getChannelsMode" }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_RESPONSE_TIMEOUT_MS, + }); + const initialChannel = result.returned.initialChannel; + if (result.returned.mode === "single") { + return { + mode: "single", + initialChannel + }; + } + else if (result.returned.mode === "multi") { + return { + mode: "multi", + initialChannel + }; + } + else { + return { + mode: "single", + initialChannel + }; + } + } + catch (e) { + return { mode: "single", initialChannel: undefined }; + } + } + function invoke(command, data, swId) { + const args = { command, data }; + if (swId) { + args.swId = swId; + } + return interop.invoke(T42_ANNOUNCE_METHOD_NAME, args, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_RESPONSE_TIMEOUT_MS, + }); + } + function validateMode(mode) { + if (mode !== "single" && mode !== "multi") { + throw new Error(`Invalid mode: ${mode}`); + } + } + + const CONTEXT_PREFIX = "___channel___"; + const LATEST_FDC3_TYPE = "latest_fdc3_type"; + class BaseSharedContextSubscriber { + constructor(contexts) { + this.contexts = contexts; + } + subscribe(callback) { + this.callback = callback; + } + subscribeFor(name, callback) { + if (!this.isChannel(name)) { + return Promise.reject(new Error(`Channel with name: ${name} doesn't exist!`)); + } + const contextName = this.createContextName(name); + return this.contexts.subscribe(contextName, (data, _, __, ___, extraData) => { + callback(data.data, data, extraData === null || extraData === void 0 ? void 0 : extraData.updaterId); + }); + } + all() { + const contextNames = this.contexts.all(); + const channelContextNames = contextNames.filter((contextName) => contextName.startsWith(CONTEXT_PREFIX)); + const channelNames = channelContextNames.map((channelContextName) => channelContextName.substr(CONTEXT_PREFIX.length)); + return channelNames; + } + async getContextData(name) { + if (!this.isChannel(name)) { + throw new Error(`A channel with name: ${name} doesn't exist!`); + } + const contextName = this.createContextName(name); + const contextData = await this.contexts.get(contextName); + if (contextData[LATEST_FDC3_TYPE]) { + return this.getContextWithFdc3Data(contextData); + } + else { + delete contextData[LATEST_FDC3_TYPE]; + } + return contextData; + } + updateChannel(name, data) { + const contextName = this.createContextName(name); + return this.contexts.update(contextName, data); + } + updateData(name, data) { + const contextName = this.createContextName(name); + const fdc3Type = this.getFDC3Type(data); + if (this.contexts.setPathSupported) { + const pathValues = Object.keys(data).map((key) => { + return { + path: `data.` + key, + value: data[key] + }; + }); + if (fdc3Type) { + pathValues.push({ path: LATEST_FDC3_TYPE, value: fdc3Type }); + } + return this.contexts.setPaths(contextName, pathValues); + } + else { + if (fdc3Type) { + data[LATEST_FDC3_TYPE] = fdc3Type; + } + return this.contexts.update(contextName, { data }); + } + } + setPaths(name, paths) { + const contextName = this.createContextName(name); + if (this.contexts.setPathSupported) { + const pathValues = paths.map((p) => { + return { + path: `data.` + p.path, + value: p.value + }; + }); + pathValues.map((p) => { + const fdc3Type = this.getFDC3Type(p.value); + if (fdc3Type) { + pathValues.push({ path: LATEST_FDC3_TYPE, value: fdc3Type }); + } + }); + return this.contexts.setPaths(contextName, pathValues); + } + else { + throw new Error("setPaths is not supported!"); + } + } + clearContextData(name) { + const contextName = this.createContextName(name); + return this.contexts.update(contextName, { data: {}, [LATEST_FDC3_TYPE]: undefined }); + } + isChannel(name) { + return this.all().some((channelName) => channelName === name); + } + async remove(name) { + if (!this.isChannel(name)) { + throw new Error(`A channel with name: ${name} doesn't exist!`); + } + const contextName = this.createContextName(name); + await this.contexts.destroy(contextName); + } + createContextName(name) { + return CONTEXT_PREFIX + name; + } + getFDC3Type(data) { + const fdc3PropsArr = Object.keys(data).filter((key) => key.indexOf("fdc3_") === 0); + if (fdc3PropsArr.length === 0) { + return; + } + if (fdc3PropsArr.length > 1) { + throw new Error("FDC3 does not support updating of multiple context keys"); + } + return fdc3PropsArr[0].split("_").slice(1).join("_"); + } + getContextWithFdc3Data(channelContext) { + const { latest_fdc3_type, ...rest } = channelContext; + const parsedType = latest_fdc3_type.split("&").join("."); + const fdc3Context = { type: parsedType, ...rest.data[`fdc3_${latest_fdc3_type}`] }; + delete rest.data[`fdc3_${latest_fdc3_type}`]; + const context = { + name: channelContext.name, + meta: channelContext.meta, + data: { + ...rest.data, + fdc3: fdc3Context + } + }; + return context; + } + } + class MultiSharedContextSubscriber extends BaseSharedContextSubscriber { + constructor() { + super(...arguments); + this.currentlySubscribedChannels = []; + this.unsubscribeMap = {}; + } + async switchChannel(id) { + const newChannels = new MultiChannelId(id).all(); + for (const newChannel of newChannels) { + if (!this.currentlySubscribedChannels.includes(newChannel)) { + await this.subscribeToChannel(newChannel); + } + } + } + async leave(id) { + const channelsToLeave = new MultiChannelId(id).all(); + for (const newChannel of channelsToLeave) { + if (this.currentlySubscribedChannels.includes(newChannel)) { + this.unsubscribeFromChannel(newChannel); + } + } + } + async updateData(id, data) { + const channels = new MultiChannelId(id).all(); + for (const channel of channels) { + await super.updateData(channel, data); + } + } + async setPaths(id, paths) { + const channels = new MultiChannelId(id).all(); + for (const channel of channels) { + await super.setPaths(channel, paths); + } + } + isChannel(name) { + const channels = new MultiChannelId(name).all(); + return channels.every((channel) => super.isChannel(channel)); + } + async subscribeToChannel(name) { + const contextName = this.createContextName(name); + const usub = await this.contexts.subscribe(contextName, (data, _, __, ___, extraData) => { + if (this.callback) { + this.callback(data.data, data, extraData === null || extraData === void 0 ? void 0 : extraData.updaterId); + } + }); + this.currentlySubscribedChannels.push(name); + this.unsubscribeMap[contextName] = usub; + } + async unsubscribeFromChannel(name) { + const contextName = this.createContextName(name); + const unsub = this.unsubscribeMap[contextName]; + if (unsub) { + unsub(); + delete this.unsubscribeMap[contextName]; + } + this.currentlySubscribedChannels = this.currentlySubscribedChannels.filter((channel) => channel !== name); + } + } + class SharedContextSubscriber extends BaseSharedContextSubscriber { + async switchChannel(name) { + this.unsubscribe(); + const contextName = this.createContextName(name); + this.unsubscribeFunc = await this.contexts.subscribe(contextName, (data, _, __, ___, extraData) => { + if (this.callback) { + this.callback(data.data, data, extraData === null || extraData === void 0 ? void 0 : extraData.updaterId); + } + }); + } + async leave() { + if (this.callback) { + this.callback({}, undefined); + } + this.unsubscribe(); + } + unsubscribe() { + if (this.unsubscribeFunc) { + this.unsubscribeFunc(); + this.unsubscribeFunc = undefined; + } + } + } + + const validateFdc3Options = (options) => { + if (typeof options !== "object" || Array.isArray(options)) { + throw new Error(`Provide options as an object`); + } + if (options.contextType && (typeof options.contextType !== "string" || !options.contextType.length)) { + throw new Error(`Provide options.contextType as a non-empty string`); + } + }; + + class ChannelsImpl { + constructor(interop, getWindowsAPI, getAppManagerAPI, logger) { + this.interop = interop; + this.getWindowsAPI = getWindowsAPI; + this.getAppManagerAPI = getAppManagerAPI; + this.logger = logger; + this.subsKey = "subs"; + this.changedKey = "changed"; + this.channelsChangedKey = "channelsChanged"; + this.isInitialJoin = true; + this.registry = CallbackRegistryFactory(); + this.pendingReplays = {}; + this.pendingRestrictionCallbacks = new Map(); + } + async getMyChannels(options) { + if (!this.currentChannelID) { + return Promise.resolve([]); + } + if (this.currentChannelID.all().length === 0) { + return Promise.resolve([]); + } + const result = []; + for (const channel of this.currentChannelID.all()) { + result.push(await this.get(channel, options)); + } + return result; + } + async init(shared, mode, initial) { + this.mode = mode; + this.shared = shared; + this.shared.subscribe(this.handler.bind(this)); + this.subscribeForChannelRestrictionsChange(); + let initialChannel = initial; + if (typeof window !== "undefined" && typeof window.glue42gd !== "undefined") { + initialChannel = window.glue42gd.initialChannel; + } + this.currentChannelID = this.getID(initialChannel); + this.logger.trace(`initialized with mode: "${mode}" and initial channel: "${initialChannel}"`); + if (this.currentChannelID.isJoinedToAnyChannel) { + this.logger.trace(`joining initial channel: "${this.currentChannelID.toString()}"`); + await this.joinNoSelectorSwitch(this.currentChannelID.toString()); + } + } + subscribe(callback, options) { + if (typeof callback !== "function") { + throw new Error("Please provide the callback as a function!"); + } + const id = Utils.generateId(); + this.pendingReplays[id] = true; + const wrappedCallback = (options === null || options === void 0 ? void 0 : options.contextType) + ? this.getWrappedSubscribeCallbackWithFdc3Type(callback, id, options.contextType) + : this.getWrappedSubscribeCallback(callback, id); + if (this.lastUpdate) { + let lastUpdate = Object.assign({}, this.lastUpdate); + setTimeout(async () => { + if (this.pendingReplays[id]) { + if (this.lastUpdate) { + lastUpdate = this.lastUpdate; + } + wrappedCallback(lastUpdate.context.data, lastUpdate.context, lastUpdate.updaterId); + } + delete this.pendingReplays[id]; + }, 0); + } + const unsub = this.registry.add(this.subsKey, wrappedCallback); + return () => { + this.pendingReplays[id] = false; + this.pendingRestrictionCallbacks.delete(id); + unsub(); + }; + } + async subscribeFor(name, callback, options) { + if (typeof name !== "string") { + throw new Error("Please provide the name as a string!"); + } + if (typeof callback !== "function") { + throw new Error("Please provide the callback as a function!"); + } + const id = Utils.generateId(); + const wrappedCallback = (options === null || options === void 0 ? void 0 : options.contextType) + ? this.getWrappedSubscribeCallbackWithFdc3Type(callback, id, options.contextType) + : this.getWrappedSubscribeCallback(callback, id); + const unsub = await this.shared.subscribeFor(name, wrappedCallback); + return () => { + this.pendingRestrictionCallbacks.delete(id); + unsub(); + }; + } + async publish(data, options) { + if (typeof data !== "object") { + throw new Error("Please provide the data as an object!"); + } + if (options) { + this.validatePublishOptions(options); + } + if (typeof options === "object") { + return this.publishWithOptions(data, options); + } + const channelName = typeof options === "string" ? options : this.currentChannelID.toString(); + if (!channelName) { + throw new Error("Not joined to any channel!"); + } + if (!this.shared.isChannel(channelName)) { + return Promise.reject(new Error(`A channel with name: ${channelName} doesn't exist!`)); + } + if (this.mode === "multi") { + const channelsToPublish = new MultiChannelId(channelName).all(); + const restrictedChannels = []; + for (const cn of channelsToPublish) { + const canPublish = (await this.getRestrictionsByChannel(cn)).write; + if (!canPublish) { + restrictedChannels.push(cn); + continue; + } + await this.shared.updateData(cn, data); + } + if (restrictedChannels.length > 0) { + const restrictedChannelsErr = `Unable to publish due to restrictions to the following channels: ${restrictedChannels.join(", ")}`; + if (restrictedChannels.length === channelsToPublish.length) { + throw new Error(restrictedChannelsErr); + } + else { + this.logger.warn(restrictedChannelsErr); + } + } + } + else { + const canPublish = (await this.getRestrictionsByChannel(channelName)).write; + if (!canPublish) { + throw new Error(`Window does not have permission to write to channel ${channelName}`); + } + return this.shared.updateData(channelName, data); + } + } + async setPaths(paths, name) { + if (name) { + if (typeof name !== "string") { + throw new Error("Please provide the name as a string!"); + } + if (!this.shared.isChannel(name)) { + return Promise.reject(new Error(`A channel with name: ${name} doesn't exist!`)); + } + if (!(await this.getRestrictionsByChannel(name)).write) { + throw new Error(`Window does not have permission to write to channel ${name}`); + } + return this.shared.setPaths(name, paths); + } + if (!this.currentChannelID) { + throw new Error("Not joined to any channel!"); + } + if (!(await this.getRestrictionsByChannel(this.currentChannelID.toString())).write) { + throw new Error(`Window does not have permission to write to channel ${this.currentChannelID.toString()}`); + } + if (!Array.isArray(paths)) { + throw new Error("Path Values argument is not a valid array"); + } + paths.forEach((path) => { + this.validatePathArgs(path); + }); + return this.shared.setPaths(this.currentChannelID.toString(), paths); + } + async setPath(path, name) { + if (name) { + if (typeof name !== "string") { + throw new Error("Please provide the name as a string!"); + } + if (!this.shared.isChannel(name)) { + return Promise.reject(new Error(`A channel with name: ${name} doesn't exist!`)); + } + if (!(await this.getRestrictionsByChannel(name)).write) { + throw new Error(`Window does not have permission to write to channel ${name}`); + } + return this.shared.setPaths(name, [path]); + } + if (!this.currentChannelID) { + throw new Error("Not joined to any channel!"); + } + if (!(await this.getRestrictionsByChannel(this.currentChannelID.toString())).write) { + throw new Error(`Window does not have permission to write to channel ${this.currentChannelID.toString()}`); + } + this.validatePathArgs(path); + return this.shared.setPaths(this.currentChannelID.toString(), [path]); + } + all() { + const channelNames = this.shared.all(); + return Promise.resolve(channelNames); + } + async list() { + const channelNames = await this.all(); + const channelContexts = await Promise.all(channelNames.map((channelName) => this.get(channelName))); + return channelContexts; + } + async get(name, options) { + if (typeof name !== "string") { + return Promise.reject(new Error("Please provide the channel name as a string!")); + } + if (!(options === null || options === void 0 ? void 0 : options.contextType)) { + return this.shared.getContextData(name); + } + validateFdc3Options(options); + const context = await this.shared.getContextData(name); + return this.getContextWithFdc3Type(context, options.contextType); + } + getMy(options) { + if (!this.currentChannelID) { + return Promise.resolve(undefined); + } + if (this.currentChannelID.all().length === 0) { + return Promise.resolve(undefined); + } + return this.get(this.currentChannelID.all()[0], options); + } + async join(name, windowId) { + if (windowId !== undefined && windowId !== null) { + this.validateWindowIdArg(windowId); + this.logger.trace(`joining channel ${name} for window: ${windowId}`); + return sendSwitchChannelUI(name, windowId); + } + return this.joinCore(name); + } + async joinNoSelectorSwitch(channelName) { + this.logger.trace(`joining channel "${channelName}" from command`); + return this.joinCore(channelName, false); + } + leave(options) { + this.logger.trace(`leaving channel with options: ${JSON.stringify(options)}`); + let windowId; + let channelName; + if (typeof options === "string") { + windowId = options; + } + else if (typeof options === "object" && !Array.isArray(options) && options !== null && options !== undefined) { + if (options.windowId) { + windowId = options.windowId; + } + if (options.channel) { + channelName = options.channel; + } + } + if (this.mode === "multi") { + return this.leaveWhenMulti(channelName, windowId); + } + else { + return this.leaveWhenSingle(channelName, windowId); + } + } + leaveNoSelectorSwitch(channelName) { + this.logger.trace(`leaving channel "${channelName}" from command`); + return this.leaveCore(false, channelName); + } + current() { + return this.currentChannelID.toString(); + } + my() { + return this.current(); + } + myChannels() { + var _a; + return (_a = this.currentChannelID.all()) !== null && _a !== void 0 ? _a : []; + } + onChannelsChanged(callback) { + if (typeof callback !== "function") { + throw new Error("Please provide the callback as a function!"); + } + let timeoutId; + const current = this.current(); + if (current) { + timeoutId = setTimeout(() => { + callback(this.myChannels()); + }, 0); + } + const un = this.registry.add(this.channelsChangedKey, callback); + return () => { + un(); + clearTimeout(timeoutId); + }; + } + changed(callback) { + if (typeof callback !== "function") { + throw new Error("Please provide the callback as a function!"); + } + const current = this.current(); + if (current) { + setTimeout(() => { + callback(this.current()); + }, 0); + } + return this.registry.add(this.changedKey, () => { + callback(this.current()); + }); + } + onChanged(callback) { + return this.changed(callback); + } + async add(info) { + var _a; + if (typeof info !== "object") { + throw new Error("Please provide the info as an object!"); + } + if (typeof info.name === "undefined") { + throw new Error("info.name is missing!"); + } + if (typeof info.name !== "string") { + throw new Error("Please provide the info.name as a string!"); + } + if (typeof info.meta === "undefined") { + throw new Error("info.meta is missing!"); + } + if (typeof info.meta !== "object") { + throw new Error("Please provide the info.meta as an object!"); + } + if (typeof info.meta.color === "undefined") { + throw new Error("info.meta.color is missing!"); + } + if (typeof info.meta.color !== "string") { + throw new Error("Please provide the info.meta.color as a string!"); + } + const context = { + name: info.name, + meta: info.meta || {}, + data: info.data || {} + }; + this.logger.trace(`adding channel: ${info.name}`); + await addOrRemoveChannel("addChannel", info.name, info.meta.color, (_a = info.meta) === null || _a === void 0 ? void 0 : _a.label); + await this.shared.updateChannel(info.name, context); + return context; + } + async remove(channel) { + if (typeof channel !== "string") { + throw new Error("Please provide the channel name as a string!"); + } + this.logger.trace(`removing channel: ${channel}`); + await this.shared.remove(channel); + await addOrRemoveChannel("removeChannel", channel); + } + async getWindowsOnChannel(channel) { + this.validateChannelArg(channel); + const windowInfos = await this.getWindowsWithChannels({ channels: [channel] }); + return windowInfos.map((w) => w.window); + } + async getWindowsWithChannels(filter) { + this.validateWindowsWithChannelsFilter(filter); + try { + const info = await getChannelsInfo(filter); + const windowsAPI = this.getWindowsAPI(); + if (info === null || info === void 0 ? void 0 : info.windows) { + return info.windows.reduce((memo, windowInfo) => { + const window = windowsAPI.findById(windowInfo.windowId); + memo.push({ + window, + channel: windowInfo.channel, + application: windowInfo.application + }); + return memo; + }, []); + } + } + catch (er) { + this.logger.error(`Error getting all channel enabled windows. This method is available since Glue42 3.12`, er); + } + return []; + } + async restrict(restriction) { + this.validateRestrictionConfig(restriction); + return setRestrictions(restriction); + } + async getRestrictions(windowId) { + if (windowId) { + this.validateWindowIdArg(windowId); + } + return getRestrictionsByWindow(windowId); + } + async restrictAll(restriction) { + this.validateRestrictionConfig(restriction); + return setRestrictionsForAllChannels(restriction); + } + handleRestrictionsChanged(restrictions, windowId) { + this.registry.execute("restrictions-changed", { + restrictions, + windowId + }); + } + async clearChannelData(channel) { + const channelName = typeof channel === "string" ? channel : this.currentChannelID.toString(); + if (!channelName) { + return; + } + if (!this.shared.isChannel(channelName)) { + return; + } + const canPublish = (await this.getRestrictionsByChannel(channelName)).write; + if (!canPublish) { + return; + } + return this.shared.clearContextData(channelName); + } + handler(data, context, updaterId) { + if (!context && !updaterId) { + this.lastUpdate = undefined; + return; + } + this.lastUpdate = { context, updaterId }; + this.pendingReplays = {}; + this.registry.execute(this.subsKey, data, context, updaterId); + } + async joinCore(name, changeSelector = true) { + this.logger.trace(`joining channel "${name}" ${changeSelector ? "" : "from command"}`); + if (typeof name !== "string") { + throw new Error("Please provide the channel name as a string!"); + } + const newId = this.getID(name); + if (!this.isInitialJoin && this.currentChannelID.isOnChannel(newId.toString())) { + this.logger.trace(`already on channel: "${name}" ${changeSelector ? "" : "from command"}`); + return; + } + this.isInitialJoin = false; + await Promise.all(newId.all().map((n) => this.verifyChannelExists(n))); + this.currentChannelID.joinChannel(name); + this.lastUpdate = undefined; + this.logger.trace(`switching channel context to: "${name}" ${changeSelector ? "" : "from command"}`); + await this.shared.switchChannel(this.currentChannelID.toString()); + if (changeSelector) { + this.logger.trace(`switching UI channel to: "${name}" ${changeSelector ? "" : "from command"}`); + await sendSwitchChannelUI(name); + this.logger.trace(`switched UI channel to: "${name}" ${changeSelector ? "" : "from command"}`); + } + this.raiseChannelsChangedEvents(); + this.logger.trace(`joined channel: ${name} ${changeSelector ? "" : "from command"} - current channel/s: ${this.currentChannelID.toString()}`); + } + async verifyChannelExists(name) { + const doesChannelExist = (channelName) => { + const channelNames = this.shared.all(); + return channelNames.includes(channelName); + }; + if (!doesChannelExist(name)) { + const channelExistsPromise = new Promise((resolve, reject) => { + const intervalId = setInterval(() => { + if (doesChannelExist(name)) { + clearTimeout(timeoutId); + clearInterval(intervalId); + resolve(); + } + }, 100); + const timeoutId = setTimeout(() => { + clearInterval(intervalId); + return reject(new Error(`A channel with name: ${name} doesn't exist!`)); + }, 3000); + }); + await channelExistsPromise; + } + } + async leaveCore(changeSelector = true, channelID) { + if (!this.currentChannelID.isJoinedToAnyChannel) { + this.logger.trace(`leave called ${changeSelector ? "" : "from command"} when not joined to any channel change selector`); + return; + } + if (channelID && !this.currentChannelID.isOnChannel(channelID)) { + this.logger.trace(`leave called ${changeSelector ? "" : "from command"} when not joined to channel: "${channelID}"`); + return; + } + this.logger.trace(`leaving context channel: "${channelID}" ${changeSelector ? "" : "from command"}`); + this.currentChannelID.leaveChannel(channelID); + await this.shared.leave(channelID); + this.lastUpdate = undefined; + this.raiseChannelsChangedEvents(); + if (changeSelector) { + this.logger.trace(`switching UI channel to: "${channelID}" ${changeSelector ? "" : "from command"}`); + await sendSwitchChannelUI(this.currentChannelID.toString()); + this.logger.trace(`switched UI channel to: "${channelID}" ${changeSelector ? "" : "from command"}`); + } + this.logger.trace(`left single channel: "${channelID}" ${changeSelector ? "" : "from command"} - current channel/s: "${this.currentChannelID.toString()}"`); + return Promise.resolve(); + } + async leaveCoreMulti(changeSelector = true, channelID) { + this.logger.trace(`leaving multi channel: "${channelID.toString()}" ${changeSelector ? "" : "from command"}`); + const currentChannels = this.currentChannelID.all(); + const isJoinedToChannel = currentChannels.some((c) => channelID.isOnChannel(c)); + if (!isJoinedToChannel || !this.currentChannelID.isJoinedToAnyChannel) { + this.logger.trace(`leave called ${changeSelector ? "" : "from command"} when not joined to any channel`); + return; + } + const channelName = channelID.toString(); + this.currentChannelID.leaveChannel(channelName); + await this.shared.leave(channelName); + this.lastUpdate = undefined; + this.raiseChannelsChangedEvents(); + if (changeSelector) { + this.logger.trace(`switching UI channel to: "${channelName}" ${changeSelector ? "" : "from command"}`); + await sendLeaveChannel(channelName); + this.logger.trace(`switched UI channel to: "${channelName}" ${changeSelector ? "" : "from command"}`); + } + this.logger.trace(`left multi channel: "${channelName}" ${changeSelector ? "" : "from command"} - current channel/s: ${this.currentChannelID.toString()}`); + return Promise.resolve(); + } + raiseChannelsChangedEvents() { + this.registry.execute(this.changedKey, this.currentChannelID.toString()); + this.registry.execute(this.channelsChangedKey, this.currentChannelID.all()); + } + async getRestrictionsByChannel(channelName) { + var _a; + const restrictions = (_a = this.channelRestrictions) !== null && _a !== void 0 ? _a : await getRestrictionsByWindow(); + if (!restrictions || !Array.isArray(restrictions.channels) || !restrictions.channels.find(c => c.name === channelName)) { + return { + read: true, + write: true + }; + } + const byChannel = restrictions.channels.find(c => c.name === channelName); + return byChannel; + } + onRestrictionsChanged(callback, callbackId, currentChannelName) { + this.pendingRestrictionCallbacks.set(callbackId, { + cb: callback, + channelName: currentChannelName + }); + if (this.onRestrictionsChangedSub) { + return; + } + this.onRestrictionsChangedSub = this.registry.add("restrictions-changed", ({ restrictions }) => { + this.logger.trace(`restrictions changed - ${JSON.stringify(restrictions)}`); + this.pendingRestrictionCallbacks.forEach(({ cb, channelName }, id) => { + const currentChannel = restrictions.channels.find((c) => c.name === channelName); + if (!currentChannel) { + this.logger.trace(`channel "${channelName}" not found in restrictions`); + return; + } + if (currentChannel.read) { + this.pendingRestrictionCallbacks.delete(id); + if (this.pendingRestrictionCallbacks.values.length === 0 && this.onRestrictionsChangedSub) { + this.onRestrictionsChangedSub(); + this.onRestrictionsChangedSub = null; + } + cb(); + } + }); + }); + } + subscribeForChannelRestrictionsChange() { + this.registry.add("restrictions-changed", (r) => { + this.logger.trace(`channel restrictions changed - ${JSON.stringify(r.restrictions)}`); + this.channelRestrictions = r.restrictions; + }); + } + validatePathArgs(path) { + if (!path) { + throw new Error("Please provide a valid path value argument"); + } + if (typeof path !== "object") { + throw new Error(`Path Value argument is not a valid object: ${JSON.stringify(path)}`); + } + if (!path.path) { + throw new Error(`path property is missing from Path Value argument: ${JSON.stringify(path)}`); + } + if (!path.value) { + throw new Error(`value property is missing from Path Value argument: ${JSON.stringify(path)}`); + } + if (typeof path.path !== "string") { + throw new Error(`path property is not a valid string from the Path Value argument: ${JSON.stringify(path)}`); + } + } + validatePublishOptions(options) { + if ((typeof options !== "string" && typeof options !== "object") || Array.isArray(options)) { + throw new Error("Provide options as a string or an object"); + } + if (typeof options === "object") { + this.validatePublishOptionsObject(options); + return; + } + if (options === "string" && !options.length) { + throw new Error("Provide options as a non-empty string"); + } + } + validatePublishOptionsObject(options) { + if (typeof options !== "object" || Array.isArray(options)) { + throw new Error("Provide options as an object"); + } + if (options.name && (typeof options.name !== "string" || !options.name.length)) { + throw new Error("Provide options.name as a non-empty string"); + } + if (Object.keys(options).includes("fdc3") && typeof options.fdc3 !== "boolean") { + throw new Error("Provide options.fdc3 as a boolean"); + } + } + async publishWithOptions(data, options) { + const channelName = options.name || this.currentChannelID.toString(); + if (!this.shared.isChannel(channelName)) { + throw new Error(`A channel with name: ${options.name} doesn't exist!`); + } + if (!channelName) { + throw new Error("Cannot publish to channel, because not joined to a channel!"); + } + const canPublish = (await this.getRestrictionsByChannel(channelName)).write; + if (!canPublish) { + throw new Error(`Window does not have permission to write to channel ${this.currentChannelID.toString()}`); + } + if (!options.fdc3) { + return this.shared.updateData(channelName, data); + } + return this.publishFdc3Data(channelName, data); + } + async publishFdc3Data(channelName, data) { + var _a; + if (typeof data.type !== "string" || !((_a = data.type) === null || _a === void 0 ? void 0 : _a.length)) { + throw new Error("Expected a valid FDC3 Context with compulsory 'type' field"); + } + const { type, ...rest } = data; + const parsedType = type.split(".").join("&"); + const fdc3DataToPublish = { [`fdc3_${parsedType}`]: rest }; + return this.shared.updateData(channelName, fdc3DataToPublish); + } + getWrappedSubscribeCallback(callback, id) { + const wrappedCallback = async (_, context, updaterId) => { + const restrictionByChannel = await this.getRestrictionsByChannel(context.name); + const channelData = this.getDataWithFdc3Encoding(context); + if (restrictionByChannel.read) { + callback(channelData, context, updaterId); + } + else { + this.onRestrictionsChanged(() => { + callback(channelData, context, updaterId); + }, id, context.name); + } + }; + return wrappedCallback; + } + getWrappedSubscribeCallbackWithFdc3Type(callback, id, fdc3Type) { + const didReplay = { replayed: false }; + const wrappedCallback = async (_, context, updaterId) => { + const restrictionByChannel = await this.getRestrictionsByChannel(context.name); + const callbackWithTypesChecks = () => { + const { data, latest_fdc3_type } = context; + const searchedType = `fdc3_${fdc3Type.split(".").join("&")}`; + if (!data[searchedType]) { + return; + } + if (didReplay.replayed) { + return this.parseDataAndInvokeSubscribeCallback({ latestFdc3TypeEncoded: latest_fdc3_type, searchedType: fdc3Type, callback, context, updaterId }); + } + const fdc3Data = { type: fdc3Type, ...data[searchedType] }; + callback({ fdc3: fdc3Data }, context, updaterId); + didReplay.replayed = true; + }; + if (restrictionByChannel.read) { + callbackWithTypesChecks(); + return; + } + this.onRestrictionsChanged(callbackWithTypesChecks, id, context.name); + }; + return wrappedCallback; + } + parseDataAndInvokeSubscribeCallback(args) { + const { latestFdc3TypeEncoded, searchedType, callback, context, updaterId } = args; + const latestPublishedType = latestFdc3TypeEncoded.split("&").join("."); + if (latestPublishedType !== searchedType) { + return; + } + const fdc3Data = { type: searchedType, ...context.data[`fdc3_${latestFdc3TypeEncoded}`] }; + callback({ fdc3: fdc3Data }, context, updaterId); + } + getContextWithFdc3Type(context, searchedType) { + var _a, _b; + if (((_b = (_a = context.data) === null || _a === void 0 ? void 0 : _a.fdc3) === null || _b === void 0 ? void 0 : _b.type) === searchedType) { + return { + name: context.name, + meta: context.meta, + data: { fdc3: context.data.fdc3 } + }; + } + const encodedType = `fdc3_${searchedType.split(".").join("&")}`; + if (!context.data[encodedType]) { + return { + name: context.name, + meta: context.meta, + data: {} + }; + } + const fdc3Context = { type: searchedType, ...context.data[encodedType] }; + return { + name: context.name, + meta: context.meta, + data: { fdc3: fdc3Context } + }; + } + getDataWithFdc3Encoding(context) { + const { data, latest_fdc3_type } = context; + if (!latest_fdc3_type) { + return data; + } + const parsedType = latest_fdc3_type.split("&").join("."); + const latestTypePropName = `fdc3_${latest_fdc3_type}`; + const fdc3Data = { type: parsedType, ...data[latestTypePropName] }; + const { [latestTypePropName]: latestFDC3Type, ...rest } = data; + return { ...rest, fdc3: fdc3Data }; + } + getID(id) { + if (this.mode === "multi") { + return new MultiChannelId(id); + } + else { + return new SingleChannelID(id); + } + } + leaveWhenSingle(channelName, windowId) { + if (windowId) { + this.logger.trace(`leaving single channel "${channelName}" for window: "${windowId}"`); + return sendSwitchChannelUI(undefined, windowId); + } + this.logger.trace(`leaving single channel "${channelName}" for our window`); + return this.leaveCore(true, channelName); + } + async leaveWhenMulti(channelName, windowId) { + if (windowId) { + this.logger.trace(`leaving multi channel "${channelName}" for window: "${windowId}"`); + return sendLeaveChannel(channelName, windowId); + } + else { + const channelId = channelName ? new MultiChannelId(channelName) : this.currentChannelID; + this.logger.trace(`leaving multi channel "${channelId.toString()}" for our window`); + return this.leaveCoreMulti(true, channelId); + } + } + validateWindowIdArg(windowId) { + if (typeof windowId !== "string") { + throw new Error("The window ID must be a non-empty string!"); + } + const windows = this.getWindowsAPI(); + if (!windows.findById(windowId)) { + throw new Error(`Window with ID "${windowId}" doesn't exist!`); + } + } + validateChannelArg(channel) { + if (!channel) { + throw new Error("Please provide a valid Channel name as a non-empty string!"); + } + if (typeof channel !== "string") { + throw new Error("The Channel name must be a non-empty string!"); + } + const channelNames = this.shared.all(); + if (channelNames.every((name) => name !== channel)) { + throw new Error(`Channel "${channel}" does not exist!"`); + } + } + validateWindowsWithChannelsFilter(filter) { + if (filter === undefined) { + return; + } + if (filter === null || Array.isArray(filter) || typeof filter !== "object") { + throw new Error("The `filter` argument must be a valid object!"); + } + } + isRestrictions(restriction) { + return 'name' in restriction; + } + validateRestrictionConfig(restriction) { + if (restriction === null || restriction === undefined || Array.isArray(restriction) || typeof restriction !== "object") { + throw new Error("The `restrictions` argument must be a valid object with Channel restrictions!"); + } + if (this.isRestrictions(restriction) && typeof restriction.name !== "string") { + throw new Error("The `name` restriction property must be a non-empty string!"); + } + if (restriction.read !== null && restriction.read !== undefined && typeof restriction.read !== "boolean") { + throw new Error("The `read` restriction property must be a boolean value!"); + } + if (restriction.write !== null && restriction.write !== undefined && typeof restriction.write !== "boolean") { + throw new Error("The `write` restriction property must be a boolean value!"); + } + if ((restriction.read === null || restriction.read === undefined) && (restriction.write === null || restriction.write === undefined)) { + throw new Error("It's required to set either the `read` or the `write` property of the Channel restriction object!"); + } + if (restriction.windowId !== null && restriction.windowId !== undefined) { + this.validateWindowIdArg(restriction.windowId); + } + } + } + + function factory$4(config, contexts, agm, getWindowsAPI, getAppManagerAPI, logger) { + const channelsReadyPromise = getChannelInitInfo(config, agm) + .then(async ({ mode, initialChannel }) => { + const sharedContexts = mode === "single" ? new SharedContextSubscriber(contexts) : new MultiSharedContextSubscriber(contexts); + if (mode === "multi") { + logger.info(`multi-channel mode enabled`); + } + await channels.init(sharedContexts, mode, initialChannel); + await setupInterop(agm, channels, logger); + return true; + }); + const channels = new ChannelsImpl(agm, getWindowsAPI, getAppManagerAPI, logger); + return { + subscribe: channels.subscribe.bind(channels), + subscribeFor: channels.subscribeFor.bind(channels), + publish: channels.publish.bind(channels), + setPath: channels.setPath.bind(channels), + setPaths: channels.setPaths.bind(channels), + all: channels.all.bind(channels), + list: channels.list.bind(channels), + get: channels.get.bind(channels), + join: channels.join.bind(channels), + leave: channels.leave.bind(channels), + restrict: channels.restrict.bind(channels), + getRestrictions: channels.getRestrictions.bind(channels), + clearChannelData: channels.clearChannelData.bind(channels), + restrictAll: channels.restrictAll.bind(channels), + current: channels.current.bind(channels), + my: channels.my.bind(channels), + changed: channels.changed.bind(channels), + onChanged: channels.onChanged.bind(channels), + add: channels.add.bind(channels), + remove: channels.remove.bind(channels), + getWindowsOnChannel: channels.getWindowsOnChannel.bind(channels), + getWindowsWithChannels: channels.getWindowsWithChannels.bind(channels), + getMy: channels.getMy.bind(channels), + ready: async () => { + await Promise.all([contexts.ready(), channelsReadyPromise]); + }, + get mode() { return channels.mode; }, + getMyChannels: channels.getMyChannels.bind(channels), + myChannels: channels.myChannels.bind(channels), + onChannelsChanged: channels.onChannelsChanged.bind(channels), + }; + } + + const CommandMethod = "T42.Hotkeys.Command"; + const InvokeMethod = "T42.Hotkeys.Invoke"; + const RegisterCommand = "register"; + const UnregisterCommand = "unregister"; + const UnregisterAllCommand = "unregisterAll"; + class HotkeysImpl { + constructor(agm) { + this.agm = agm; + this.registry = CallbackRegistryFactory(); + this.firstHotkey = true; + this.hotkeys = new Map(); + } + async register(info, callback) { + if (typeof info === "undefined") { + throw new Error("Hotkey parameter missing"); + } + if (typeof info === "string") { + info = { + hotkey: info + }; + } + else { + if (!info.hotkey) { + throw new Error("Info's hotkey parameter missing"); + } + info = { + hotkey: info.hotkey, + description: info.description + }; + } + const hkToLower = this.formatHotkey(info.hotkey); + if (this.hotkeys.has(hkToLower)) { + throw new Error(`Shortcut for ${hkToLower} already registered`); + } + if (this.firstHotkey) { + this.firstHotkey = false; + await this.registerInvokeAGMMethod(); + } + this.registry.add(hkToLower, callback); + await this.agm.invoke(CommandMethod, { command: RegisterCommand, hotkey: hkToLower, description: info.description }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + this.hotkeys.set(hkToLower, info); + } + async unregister(hotkey) { + if (typeof hotkey === "undefined") { + throw new Error("hotkey parameter missing"); + } + if (typeof hotkey !== "string") { + throw new Error("hotkey parameter must be string"); + } + const hkToLower = this.formatHotkey(hotkey); + await this.agm.invoke(CommandMethod, { command: UnregisterCommand, hotkey: hkToLower }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + this.hotkeys.delete(hkToLower); + this.registry.clearKey(hkToLower); + } + async unregisterAll() { + await this.agm.invoke(CommandMethod, { command: UnregisterAllCommand }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + this.hotkeys.clear(); + this.registry.clear(); + } + isRegistered(hotkey) { + const hkToLower = this.formatHotkey(hotkey); + return this.hotkeys.has(hkToLower); + } + registerInvokeAGMMethod() { + return this.agm.register(InvokeMethod, (args) => { + const hkToLower = args.key.toLowerCase(); + const info = this.hotkeys.get(hkToLower); + this.registry.execute(hkToLower, info); + }); + } + formatHotkey(hotkey) { + if (hotkey) { + return hotkey.replace(/\s/g, "").toLowerCase(); + } + } + } + + function factory$3(agm) { + const hotkeys = new HotkeysImpl(agm); + return { + register: hotkeys.register.bind(hotkeys), + unregister: hotkeys.unregister.bind(hotkeys), + unregisterAll: hotkeys.unregisterAll.bind(hotkeys), + isRegistered: hotkeys.isRegistered.bind(hotkeys), + ready: () => Promise.resolve() + }; + } + + var version = "6.12.0"; + + var prepareConfig = (options) => { + function getLibConfig(value, defaultMode, trueMode) { + if (typeof value === "boolean" && !value) { + return undefined; + } + const mode = getModeAsString(value, defaultMode, trueMode); + if (typeof mode === "undefined") { + return undefined; + } + if (typeof value === "object") { + value.mode = mode; + return value; + } + return { + mode, + }; + } + function getModeAsString(value, defaultMode, trueMode) { + if (typeof value === "object") { + return getModeAsString(value.mode, defaultMode, trueMode).toString(); + } + else if (typeof value === "undefined") { + if (typeof defaultMode === "boolean" && !defaultMode) { + return undefined; + } + else if (typeof defaultMode === "boolean" && defaultMode) { + return typeof trueMode === "undefined" ? defaultMode : trueMode; + } + else if (typeof defaultMode === "undefined") { + return undefined; + } + else { + return defaultMode; + } + } + else if (typeof value === "boolean") { + if (value) { + return (typeof trueMode === "undefined") ? defaultMode : trueMode; + } + else { + return undefined; + } + } + return value; + } + const appDefaultMode = true; + const appDefaultTrueMode = "startOnly"; + const activitiesDefaultMode = Utils.isNode() ? false : "trackMyTypeAndInitiatedFromMe"; + const activitiesTrueMode = "trackMyTypeAndInitiatedFromMe"; + const layoutsDefaultMode = "slim"; + const layoutsTrueMode = layoutsDefaultMode; + const channelsConfig = () => { + if (typeof options.channels === "boolean") { + return options.channels; + } + else if (typeof options.channels === "object" && typeof options.channels.enabled === "boolean" && options.channels.enabled) { + return { mode: true, ...options.channels }; + } + else { + return false; + } + }; + const exposeAPI = typeof options.exposeAPI === "boolean" || typeof options.exposeGlue === "boolean"; + return { + layouts: getLibConfig(options.layouts, layoutsDefaultMode, layoutsTrueMode), + activities: getLibConfig(options.activities, activitiesDefaultMode, activitiesTrueMode), + appManager: getLibConfig(options.appManager, appDefaultMode, appDefaultTrueMode), + windows: getLibConfig(options.windows, true, true), + channels: getLibConfig(channelsConfig(), false, true), + displays: getLibConfig(options.displays, true, true), + exposeAPI: exposeAPI ? exposeAPI : true + }; + }; + + class Glue42Notification { + constructor(options) { + this.options = options; + this.callbacks = CallbackRegistryFactory(); + this.actions = options.actions; + this.body = options.body; + this.badge = options.badge; + this.data = options.data; + this.dir = options.dir; + this.icon = options.icon; + this.image = options.image; + this.lang = options.lang; + this.renotify = options.renotify; + this.requireInteraction = options.requireInteraction; + this.silent = options.silent; + this.tag = options.tag; + this.timestamp = options.timestamp; + this.title = options.title; + } + close() { + throw new Error("Method not implemented."); + } + addEventListener(type, listener, options) { + this.callbacks.add(type, listener); + } + removeEventListener(type, listener, options) { + } + dispatchEvent(event) { + this.callbacks.execute(event.type, event); + return true; + } + } + + class PanelAPI { + constructor(interop, onStreamEvent) { + this.interop = interop; + this.onStreamEvent = onStreamEvent; + } + onVisibilityChanged(callback) { + return this.onStreamEvent("on-panel-visibility-changed", callback); + } + toggle() { + return this.interop.invoke("T42.Notifications.Show", undefined, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + show() { + return this.interop.invoke("T42.Notifications.Show", { show: true }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + hide() { + return this.interop.invoke("T42.Notifications.Hide"); + } + async isVisible() { + const interopResult = await this.interop.invoke("T42.Notifications.Execute", { command: "isPanelVisible" }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return interopResult.returned.panelVisible; + } + toAPI() { + return { + onVisibilityChanged: this.onVisibilityChanged.bind(this), + toggle: this.toggle.bind(this), + show: this.show.bind(this), + hide: this.hide.bind(this), + isVisible: this.isVisible.bind(this) + }; + } + } + + const STARTING_INDEX = 0; + class Notifications { + constructor(interop, logger) { + this.interop = interop; + this.NotificationsSubscribeStream = "T42.GNS.Subscribe.Notifications"; + this.NotificationsCounterStream = "T42.Notifications.Counter"; + this.RaiseNotificationMethodName = "T42.GNS.Publish.RaiseNotification"; + this.NotificationsExecuteMethod = "T42.Notifications.Execute"; + this.NotificationFilterMethodName = "T42.Notifications.Filter"; + this.methodsRegistered = false; + this.NOTIFICATIONS_CONFIGURE_METHOD_NAME = "T42.Notifications.Configure"; + this.methodNameRoot = "T42.Notifications.Handler-" + Utils.generateId(); + this.nextId = 0; + this.notifications = {}; + this.registry = CallbackRegistryFactory(); + this.subscribedForNotifications = false; + this.subscribedCounterStream = false; + this.subscriptionsCountForNotifications = 0; + this.subscriptionsCountForCounter = 0; + this.logger = logger.subLogger("notifications"); + this._panel = new PanelAPI(interop, this.onStreamEventCore.bind(this)); + this._panelAPI = this._panel.toAPI(); + this.subscribeInternalEvents(); + } + get maxActions() { + return 10; + } + get panel() { + return this._panelAPI; + } + async raise(options) { + var _a; + const notification = await this.createNotification(options); + const g42notification = new Glue42Notification(options); + this.notifications[notification.id] = g42notification; + try { + const invocationResult = await this.interop.invoke(this.RaiseNotificationMethodName, { notification }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + g42notification.id = (_a = invocationResult.returned) === null || _a === void 0 ? void 0 : _a.id; + } + catch (err) { + const errorMessage = err.message; + setTimeout(() => { + this.handleNotificationErrorEvent(g42notification, errorMessage); + }, 1); + } + return g42notification; + } + async setFilter(filter) { + const result = await this.interop.invoke(this.NotificationFilterMethodName, filter, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return result.returned; + } + async getFilter() { + const result = await this.interop.invoke(this.NotificationFilterMethodName, undefined, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return result.returned; + } + async configure(options) { + var _a, _b, _c, _d, _e, _f, _g, _h; + if (!options || Array.isArray(options)) { + throw new Error("Invalid options - should be an object."); + } + if (Object.values(options).length === 0) { + throw new Error("The argument must be a non-empty object."); + } + if (typeof options.enable !== "undefined" && typeof options.enable !== "boolean") { + throw new Error("Expected type of enabled - boolean."); + } + if (typeof options.enableToasts !== "undefined" && typeof options.enableToasts !== "boolean") { + throw new Error("Expected type of enableToasts - boolean."); + } + if (typeof options.toastExpiry !== "undefined" && typeof options.toastExpiry !== "number") { + throw new Error("Expected type of toastExpiry - number."); + } + if (options.sourceFilter && typeof options.sourceFilter !== "object") { + throw new Error("Expected type of sourceFilter - object."); + } + if (((_a = options.sourceFilter) === null || _a === void 0 ? void 0 : _a.allowed) && !Array.isArray((_b = options.sourceFilter) === null || _b === void 0 ? void 0 : _b.allowed)) { + throw new Error("Expected type of sourceFilter.allowed - array."); + } + if (((_c = options.sourceFilter) === null || _c === void 0 ? void 0 : _c.blocked) && !Array.isArray((_d = options.sourceFilter) === null || _d === void 0 ? void 0 : _d.blocked)) { + throw new Error("Expected type of sourceFilter.blocked - array."); + } + if (options.toasts && typeof options.toasts !== "object") { + throw new Error("Expected type of (options.toasts - object."); + } + if (((_e = options.toasts) === null || _e === void 0 ? void 0 : _e.mode) && typeof options.toasts.mode !== "string") { + throw new Error("Expected type of (options.toasts.mode - string."); + } + if (((_f = options.toasts) === null || _f === void 0 ? void 0 : _f.stackBy) && typeof options.toasts.stackBy !== "string") { + throw new Error("Expected type of (options.toasts.stackBy - string."); + } + if (options.placement && typeof options.placement !== "object") { + throw new Error("Expected type of (options.placement - object."); + } + if (((_g = options.placement) === null || _g === void 0 ? void 0 : _g.toasts) && typeof options.placement.toasts !== "string") { + throw new Error("Expected type of (options.placement.toasts - string."); + } + if (((_h = options.placement) === null || _h === void 0 ? void 0 : _h.panel) && typeof options.placement.panel !== "string") { + throw new Error("Expected type of (options.placement.panel - string."); + } + if (typeof options.closeNotificationOnClick !== "undefined" && typeof options.closeNotificationOnClick !== "boolean") { + throw new Error("Expected type of closeNotificationOnClick - boolean."); + } + const result = await this.interop.invoke(this.NOTIFICATIONS_CONFIGURE_METHOD_NAME, options, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return result.returned; + } + async getConfiguration() { + const result = await this.interop.invoke(this.NotificationsExecuteMethod, { command: "getConfiguration" }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return result.returned; + } + async list() { + const interopResult = await this.interop.invoke(this.NotificationsExecuteMethod, { + command: "list", + data: { statesVersion2: true } + }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return interopResult.returned.notifications; + } + async updateData(id, data) { + const replacer = (key, value) => typeof value === "undefined" ? null : value; + const attribute = { + key: "data", + value: { + stringValue: JSON.stringify(data, replacer) + } + }; + const interopResult = await this.interop.invoke(this.NotificationsExecuteMethod, { command: "create-or-update-attribute", data: { id, attribute } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return interopResult.returned; + } + onRaised(callback) { + return this.onStreamEventCore("on-notification-raised", callback); + } + onStateChanged(callback) { + return this.onStreamEventCore("on-state-changed", callback); + } + onClosed(callback) { + return this.onStreamEventCore("on-notification-closed", callback); + } + onConfigurationChanged(callback) { + if (typeof callback !== "function") { + throw new Error("Please provide the callback as a function!"); + } + this.subscribe(); + const un = this.registry.add("on-configuration-changed", callback); + return () => { + un(); + this.closeStreamSubscriptionIfNoNeeded(); + }; + } + onCounterChanged(callback) { + if (typeof callback !== "function") { + throw new Error("Please provide the callback as a function!"); + } + this.subscribeForCounterStream(); + const un = this.registry.add("on-counter-changed", callback); + return () => { + un(); + this.closeStreamCounterSubscriptionIfNoNeeded(); + }; + } + onDataChanged(callback) { + if (typeof callback !== "function") { + throw new Error("Please provide the callback as a function!"); + } + this.subscribe(); + const un = this.registry.add("on-notification-data-changed", callback); + return () => { + un(); + this.closeStreamSubscriptionIfNoNeeded(); + }; + } + async clearAll() { + await this.interop.invoke(this.NotificationsExecuteMethod, { command: "clearAll" }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async clearOld() { + await this.interop.invoke(this.NotificationsExecuteMethod, { command: "clearAllOld", data: { statesVersion2: true } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async clear(id) { + if (!id) { + throw new Error("The 'id' argument cannot be null or undefined"); + } + if (typeof (id) !== "string") { + throw new Error("The 'id' argument must be a string"); + } + await this.interop.invoke(this.NotificationsExecuteMethod, { command: "clear", data: { id } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async clearMany(notifications) { + this.validateNotificationsArr(notifications); + await this.interop.invoke(this.NotificationsExecuteMethod, { command: "clearMany", data: { notifications } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async click(id, action, options) { + await this.interop.invoke(this.NotificationsExecuteMethod, { command: "click", data: { id, action, options } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async snooze(id, duration) { + await this.interop.invoke(this.NotificationsExecuteMethod, { command: "snooze", data: { id, duration } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async snoozeMany(notifications, duration) { + if (!duration) { + throw new Error("The 'duration' argument cannot be null or undefined"); + } + if (typeof duration !== "number") { + throw new Error("The 'duration' argument must be a valid number"); + } + this.validateNotificationsArr(notifications); + await this.interop.invoke(this.NotificationsExecuteMethod, { command: "snoozeMany", data: { notifications, duration } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async setState(id, state) { + if (!id) { + throw new Error("The 'id' argument cannot be null or undefined"); + } + if (typeof (id) !== "string") { + throw new Error("The 'id' argument must be a string"); + } + if (!state) { + throw new Error("The 'state' argument cannot be null or undefined"); + } + this.validateState(state); + await this.interop.invoke(this.NotificationsExecuteMethod, { command: "updateState", data: { id, state } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async setStates(notifications, state) { + if (!state) { + throw new Error("The 'state' argument cannot be null or undefined"); + } + if (typeof state !== "string") { + throw new Error("The 'state' argument must be a valid string"); + } + this.validateNotificationsArr(notifications); + await this.interop.invoke(this.NotificationsExecuteMethod, { command: "updateStates", data: { notifications, state } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + toAPI() { + return { + maxActions: this.maxActions, + panel: this._panel.toAPI(), + raise: this.raise.bind(this), + setFilter: this.setFilter.bind(this), + getFilter: this.getFilter.bind(this), + configure: this.configure.bind(this), + getConfiguration: this.getConfiguration.bind(this), + list: this.list.bind(this), + onRaised: this.onRaised.bind(this), + onStateChanged: this.onStateChanged.bind(this), + onClosed: this.onClosed.bind(this), + onConfigurationChanged: this.onConfigurationChanged.bind(this), + onCounterChanged: this.onCounterChanged.bind(this), + onDataChanged: this.onDataChanged.bind(this), + clearAll: this.clearAll.bind(this), + clearOld: this.clearOld.bind(this), + clear: this.clear.bind(this), + click: this.click.bind(this), + setState: this.setState.bind(this), + updateData: this.updateData.bind(this), + snooze: this.snooze.bind(this), + snoozeMany: this.snoozeMany.bind(this), + clearMany: this.clearMany.bind(this), + setStates: this.setStates.bind(this), + import: this.importNotifications.bind(this) + }; + } + async importNotifications(notifications) { + if (!notifications || !Array.isArray(notifications) || notifications.length === 0) { + throw new Error("Notifications argument must be a valid array with notification options"); + } + const notificationsToImport = await Promise.all(notifications.map((notificationOptions) => this.createNotification(notificationOptions, true))); + const invocationResult = await this.interop.invoke(this.NotificationsExecuteMethod, { command: "importNotifications", data: { notificationSettings: notificationsToImport } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return invocationResult.returned.notifications; + } + async createNotification(options, imported) { + var _a, _b, _c, _d; + this.validate(options, imported); + if (!this.methodsRegistered) { + const bunchOfPromises = []; + for (let index = STARTING_INDEX; index < this.maxActions; index++) { + bunchOfPromises.push(this.interop.register(`${this.methodNameRoot}_${index}`, this.handleNotificationEvent.bind(this))); + } + this.methodsRegistered = true; + await Promise.all(bunchOfPromises); + } + const id = (_a = options.id) !== null && _a !== void 0 ? _a : Utils.generateId(); + const type = (_b = options.type) !== null && _b !== void 0 ? _b : "Notification"; + const notification = { + id, + state: (_c = options.state) !== null && _c !== void 0 ? _c : "Active", + title: options.title, + type, + severity: (_d = options.severity) !== null && _d !== void 0 ? _d : "None", + description: options.body, + glueRoutingDetailMethodName: `${this.methodNameRoot}_${STARTING_INDEX}`, + actions: [], + sourceId: id, + source: options.source, + publishExtraEvents: true, + clickInterop: options.clickInterop + }; + if (options.actions) { + this.handleActions(options, id, notification); + } + this.handleOptions(options, notification); + return notification; + } + onStreamEventCore(key, callback) { + if (typeof callback !== "function") { + throw new Error("Please provide the callback as a function!"); + } + this.subscribe(); + const un = this.registry.add(key, callback); + return () => { + un(); + this.closeStreamSubscriptionIfNoNeeded(); + }; + } + handleOptions(options, notification) { + if (options.icon) { + notification.attributes = notification.attributes || []; + notification.attributes.push({ key: "icon", value: { stringValue: options.icon } }); + } + if (options.data) { + notification.attributes = notification.attributes || []; + const dataAsString = JSON.stringify(options.data); + notification.attributes.push({ key: "data", value: { stringValue: dataAsString } }); + } + if (typeof options.panelExpiry === "number") { + notification.attributes = notification.attributes || []; + notification.attributes.push({ key: "panelExpiry", value: { stringValue: options.panelExpiry.toString() } }); + } + if (typeof options.toastExpiry === "number") { + notification.attributes = notification.attributes || []; + notification.attributes.push({ key: "toastExpiry", value: { stringValue: options.toastExpiry.toString() } }); + } + } + handleActions(options, id, notification) { + var _a, _b, _c; + const validActions = options.actions.slice(0, this.maxActions); + let index = STARTING_INDEX; + for (const action of validActions) { + const args = { + g42notificationId: id, + g42action: action.action, + g42interopMethod: (_a = action.interop) === null || _a === void 0 ? void 0 : _a.method, + g42interopTarget: (_b = action.interop) === null || _b === void 0 ? void 0 : _b.target, + g42interopArguments: JSON.stringify((_c = action.interop) === null || _c === void 0 ? void 0 : _c.arguments) + }; + const parameters = Object.keys(args).map((key) => { + const value = args[key]; + return { + name: key, + value: { + stringValue: value + } + }; + }); + const glueAction = { + name: `${this.methodNameRoot}_${index}`, + description: action.title, + displayName: action.title, + displayPath: action.displayPath, + displayId: action.displayId, + parameters + }; + notification.actions.push(glueAction); + index++; + } + } + validate(options, imported) { + if (!options) { + throw new Error("invalid options - should be an object"); + } + if (typeof options !== "object") { + throw new Error("invalid options - should be an object"); + } + if (!options.title) { + throw new Error("invalid options - should have a title"); + } + if (typeof options.title !== "string") { + throw new Error("invalid options - title should be a string"); + } + if (options.severity && typeof options.severity !== "string") { + throw new Error("invalid options - severity should be a string"); + } + if (options.panelExpiry && typeof options.panelExpiry !== "number") { + throw new Error("invalid options - panelExpiry should be a number"); + } + if (options.toastExpiry && typeof options.toastExpiry !== "number") { + throw new Error("invalid options - toastExpiry should be a number"); + } + if (options.state) { + this.validateState(options.state, imported); + } + } + validateState(state, imported) { + if (typeof (state) !== "string") { + throw new Error("The 'state' argument must be a string"); + } + const validStates = [ + "Active", + "Acknowledged", + "Stale" + ]; + if (imported) { + validStates.push("Seen", "Snoozed", "Processing", "Closed"); + } + if (!validStates.includes(state)) { + throw new Error(`The state argument: ${state} is not valid!`); + } + } + subscribe() { + this.subscriptionsCountForNotifications++; + if (!this.subscribedForNotifications) { + this.subscribedForNotifications = true; + this.logger.info(`Attempting to subscribe to "${this.NotificationsSubscribeStream}".`); + this.interop + .subscribe(this.NotificationsSubscribeStream, { + arguments: { + sendDeltaOnly: true, + statesVersion2: true + } + }) + .then((sub) => { + this.subscriptionForNotifications = sub; + this.logger.info(`Successfully subscribed to "${this.NotificationsSubscribeStream}".`); + sub.onData(({ data }) => { + this.handleData(data); + }); + sub.onClosed((...args) => { + this.subscribedForNotifications = false; + this.logger.info(`Stream subscription Closed - ${JSON.stringify(args)}`); + }); + sub.onFailed((...args) => { + this.subscribedForNotifications = false; + this.logger.warn(`Stream subscription Failed - ${JSON.stringify(args)}`); + }); + }) + .catch((e) => { + this.subscribedForNotifications = false; + this.logger.error(`Unable to subscribe to "${this.NotificationsSubscribeStream}"`, e); + }); + } + } + subscribeForCounterStream() { + this.subscriptionsCountForCounter++; + if (!this.subscribedCounterStream) { + this.subscribedCounterStream = true; + this.logger.info(`Attempting to subscribe to "${this.NotificationsCounterStream}".`); + this.interop + .subscribe(this.NotificationsCounterStream, { + arguments: { + sendDeltaOnly: true + } + }) + .then((sub) => { + this.subscriptionForCounter = sub; + this.logger.info(`Successfully subscribed to "${this.NotificationsCounterStream}".`); + sub.onData(({ data }) => { + this.registry.execute("on-counter-changed", { count: data.count }); + }); + sub.onClosed((...args) => { + this.subscribedCounterStream = false; + this.logger.info(`Stream subscription Closed - ${JSON.stringify(args)}`); + }); + sub.onFailed((...args) => { + this.subscribedCounterStream = false; + this.logger.warn(`Stream subscription Failed - ${JSON.stringify(args)}`); + }); + }) + .catch((e) => { + this.subscribedCounterStream = false; + this.logger.error(`Unable to subscribe to "${this.NotificationsCounterStream}"`, e); + }); + } + } + subscribeInternalEvents() { + this.registry.add("on-notification-closed", (id) => { + this.handleOnClosed(id); + }); + this.registry.add("on-notification-raised", (notification) => { + this.handleOnShow(notification.id); + }); + } + handleData(message) { + var _a; + try { + if ("items" in message && Array.isArray(message.items)) { + this.handleItemsData(message); + } + else if ("deltas" in message && Array.isArray(message.deltas)) { + this.handleDeltas(message); + } + if ("configuration" in message && typeof message.configuration === "object") { + this.logger.info(`Received configuration ${JSON.stringify(message.configuration)} from the stream`); + this.registry.execute("on-configuration-changed", message.configuration, message.configuration.allApplications); + } + if ("command" in message && typeof message.command === "string") { + this.logger.info(`Received command "${(_a = message.command) !== null && _a !== void 0 ? _a : JSON.stringify(message)}" from the stream`); + if (message.command === "showPanel" || message.command === "hidePanel") { + this.registry.execute("on-panel-visibility-changed", message.command === "showPanel"); + } + } + } + catch (e) { + this.logger.error(`Failed to parse data from the stream`, e); + } + } + handleItemsData(message) { + const items = message.items; + this.logger.info(`Received ${items.length} notifications from the stream`); + const notifications = items; + if (message.isSnapshot) { + notifications.forEach((n) => { + this.registry.execute("on-notification-raised", n); + }); + } + else { + const notification = notifications[0]; + if (notification.state === "Closed") { + this.registry.execute("on-notification-closed", { id: notification.id }); + } + else { + this.registry.execute("on-notification-raised", notification); + } + } + } + handleDeltas(message) { + const deltas = message.deltas; + deltas.forEach((info) => { + var _a; + const id = info.id; + const delta = (_a = info.delta) !== null && _a !== void 0 ? _a : {}; + if (delta.state === "Closed") { + this.registry.execute("on-notification-closed", { id, ...delta }); + } + else if (delta.state) { + this.registry.execute("on-state-changed", { id }, delta.state); + } + else if (delta.attributes) { + const attributes = delta.attributes; + const dataAttribute = attributes.find((a) => a.key === "data"); + if (dataAttribute) { + this.registry.execute("on-notification-data-changed", { id }, JSON.parse(dataAttribute.value.stringValue)); + } + } + }); + } + handleOnClosed(id) { + const { notification, key } = this.getNotification(id); + if (notification) { + this.handleEvent(notification, "close"); + delete this.notifications[key]; + } + } + handleOnShow(id) { + const { notification } = this.getNotification(id); + if (notification) { + this.handleEvent(notification, "show"); + } + } + getNotification(id) { + let notification; + let key; + for (const k in this.notifications) { + if (this.notifications[k].id === id) { + notification = this.notifications[k]; + key = k; + break; + } + } + return { notification, key }; + } + handleNotificationEvent(args) { + const gnsNotificationArgs = this.getGnsNotificationArgs(args); + if (gnsNotificationArgs.event === "unknown") { + return; + } + const notification = this.notifications[gnsNotificationArgs.notificationId]; + if (!notification) { + return; + } + this.handleNotificationEventCore(notification, gnsNotificationArgs); + } + handleNotificationEventCore(notification, args) { + switch (args.event) { + case "action": { + return this.handleNotificationActionEvent(notification, args.notificationActionPayload); + } + case "click": { + return this.handleNotificationClickEvent(notification); + } + case "close": { + return this.handleEvent(notification, "close"); + } + case "error": { + return this.handleNotificationErrorEvent(notification, args.error); + } + case "show": { + return this.handleEvent(notification, "show"); + } + } + } + handleNotificationActionEvent(notification, payload) { + const event = { + type: "onaction", + action: payload.g42action + }; + if (notification.onaction) { + notification.onaction(event); + } + notification.dispatchEvent(event); + } + handleNotificationClickEvent(notification) { + const event = { type: "onclick" }; + if (notification.onclick) { + notification.onclick(event); + } + notification.dispatchEvent(event); + } + handleEvent(notification, eventType) { + var _a; + const event = { type: eventType }; + const eventName = `on${eventType}`; + (_a = notification[eventName]) === null || _a === void 0 ? void 0 : _a.call(notification, event); + notification.dispatchEvent(event); + } + handleNotificationErrorEvent(notification, error) { + const event = { type: "onerror", error }; + if (notification.onerror) { + notification.onerror(event); + } + notification.dispatchEvent(event); + } + getGnsNotificationArgs(args) { + var _a; + let result; + const event = (_a = args.notification) === null || _a === void 0 ? void 0 : _a.event; + if (!event) { + result = this.getBackwardGnsNotificationArgs(args); + } + else { + result = { + event, + notificationId: args.notification.sourceNotificationId, + notificationActionPayload: args + }; + } + return result; + } + getBackwardGnsNotificationArgs(args) { + var _a; + let result; + if (args.g42notificationId) { + result = { + event: "action", + notificationId: args.g42notificationId, + notificationActionPayload: args + }; + } + else if ((_a = args.notification) === null || _a === void 0 ? void 0 : _a.sourceNotificationId) { + result = { + event: "click", + notificationId: args.notification.sourceNotificationId, + notificationActionPayload: args + }; + } + else { + result = { + event: "unknown", + notificationId: undefined, + notificationActionPayload: args + }; + } + return result; + } + closeStreamSubscriptionIfNoNeeded() { + this.subscriptionsCountForNotifications--; + if (this.subscriptionForNotifications && this.subscriptionsCountForNotifications === 0) { + this.subscriptionForNotifications.close(); + this.subscriptionForNotifications = undefined; + } + } + closeStreamCounterSubscriptionIfNoNeeded() { + this.subscriptionsCountForCounter--; + if (this.subscriptionForCounter && this.subscriptionsCountForCounter === 0) { + this.subscriptionForCounter.close(); + this.subscriptionForCounter = undefined; + } + } + validateNotificationsArr(notifications) { + if (!Array.isArray(notifications)) { + throw new Error("The 'notifications' argument must be an array with valid notification IDs"); + } + if (notifications.some((n) => typeof n !== "string")) { + throw new Error("The 'notifications' argument must contain only valid string notification IDs"); + } + } + } + + const ThemesConfigurationMethodName = "T42.Themes.Configuration"; + class ThemesImpl { + constructor(contexts, interop) { + this.contexts = contexts; + this.interop = interop; + this.registry = CallbackRegistryFactory(); + this.isSubscribed = false; + this.getConfiguration(); + } + async list() { + await this.getConfiguration(); + if (!this.getMethodName) { + throw new Error("not supported"); + } + return (await this.getAll()).returned.all; + } + async getCurrent() { + await this.getConfiguration(); + if (!this.getMethodName) { + throw new Error("not supported"); + } + const all = await this.getAll(); + return all.returned.all.find((t) => t.name === all.returned.selected); + } + async select(theme) { + await this.getConfiguration(); + if (!this.setMethodName) { + throw new Error("not supported"); + } + await this.interop.invoke(this.setMethodName, { theme }); + } + onChanged(callback) { + if (!callback) { + throw new Error("Callback argument is required"); + } + if (callback && typeof callback !== "function") { + throw new Error("Callback argument must be a function"); + } + this.subscribe(); + return this.registry.add("changed", callback); + } + async getConfiguration() { + try { + if (this.sharedContextName) { + return; + } + const config = await this.interop.invoke(ThemesConfigurationMethodName); + this.sharedContextName = config.returned.sharedContextName; + this.getMethodName = config.returned.getThemesMethodName; + this.setMethodName = config.returned.setThemesMethodName; + } + catch (error) { + return; + } + } + async getAll() { + await this.getConfiguration(); + return await this.interop.invoke(this.getMethodName); + } + async subscribe() { + await this.getConfiguration(); + if (this.isSubscribed) { + return; + } + this.isSubscribed = true; + this.contexts.subscribe(this.sharedContextName, (data) => { + if (data && data.all && data.selected) { + this.registry.execute("changed", data.all.find((t) => t.name === data.selected)); + } + }); + } + } + + function factory$2(contexts, interop) { + const themes = new ThemesImpl(contexts, interop); + return { + list: themes.list.bind(themes), + getCurrent: themes.getCurrent.bind(themes), + select: themes.select.bind(themes), + onChanged: themes.onChanged.bind(themes), + ready: () => Promise.resolve(), + }; + } + + const connectBrowserAppProps = ["name", "title", "version", "customProperties", "icon", "caption", "type"]; + const fdc3v2AppProps = ["appId", "name", "type", "details", "version", "title", "tooltip", "lang", "description", "categories", "icons", "screenshots", "contactEmail", "moreInfo", "publisher", "customConfig", "hostManifests", "interop", "localizedVersions"]; + + /** + * Wraps values in an `Ok` type. + * + * Example: `ok(5) // => {ok: true, result: 5}` + */ + var ok = function (result) { return ({ ok: true, result: result }); }; + /** + * Wraps errors in an `Err` type. + * + * Example: `err('on fire') // => {ok: false, error: 'on fire'}` + */ + var err = function (error) { return ({ ok: false, error: error }); }; + /** + * Create a `Promise` that either resolves with the result of `Ok` or rejects + * with the error of `Err`. + */ + var asPromise = function (r) { + return r.ok === true ? Promise.resolve(r.result) : Promise.reject(r.error); + }; + /** + * Unwraps a `Result` and returns either the result of an `Ok`, or + * `defaultValue`. + * + * Example: + * ``` + * Result.withDefault(5, number().run(json)) + * ``` + * + * It would be nice if `Decoder` had an instance method that mirrored this + * function. Such a method would look something like this: + * ``` + * class Decoder
{ + * runWithDefault = (defaultValue: A, json: any): A => + * Result.withDefault(defaultValue, this.run(json)); + * } + * + * number().runWithDefault(5, json) + * ``` + * Unfortunately, the type of `defaultValue: A` on the method causes issues + * with type inference on the `object` decoder in some situations. While these + * inference issues can be solved by providing the optional type argument for + * `object`s, the extra trouble and confusion doesn't seem worth it. + */ + var withDefault = function (defaultValue, r) { + return r.ok === true ? r.result : defaultValue; + }; + /** + * Return the successful result, or throw an error. + */ + var withException = function (r) { + if (r.ok === true) { + return r.result; + } + else { + throw r.error; + } + }; + /** + * Apply `f` to the result of an `Ok`, or pass the error through. + */ + var map = function (f, r) { + return r.ok === true ? ok(f(r.result)) : r; + }; + /** + * Apply `f` to the result of two `Ok`s, or pass an error through. If both + * `Result`s are errors then the first one is returned. + */ + var map2 = function (f, ar, br) { + return ar.ok === false ? ar : + br.ok === false ? br : + ok(f(ar.result, br.result)); + }; + /** + * Apply `f` to the error of an `Err`, or pass the success through. + */ + var mapError = function (f, r) { + return r.ok === true ? r : err(f(r.error)); + }; + /** + * Chain together a sequence of computations that may fail, similar to a + * `Promise`. If the first computation fails then the error will propagate + * through. If it succeeds, then `f` will be applied to the value, returning a + * new `Result`. + */ + var andThen = function (f, r) { + return r.ok === true ? f(r.result) : r; + }; + + /*! ***************************************************************************** + Copyright (c) Microsoft Corporation. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THIS SOFTWARE. + ***************************************************************************** */ + /* global Reflect, Promise */ + + + + var __assign = function() { + __assign = Object.assign || function __assign(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; + } + return t; + }; + return __assign.apply(this, arguments); + }; + + function __rest(s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { + if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) + t[p[i]] = s[p[i]]; + } + return t; + } + + function isEqual(a, b) { + if (a === b) { + return true; + } + if (a === null && b === null) { + return true; + } + if (typeof (a) !== typeof (b)) { + return false; + } + if (typeof (a) === 'object') { + // Array + if (Array.isArray(a)) { + if (!Array.isArray(b)) { + return false; + } + if (a.length !== b.length) { + return false; + } + for (var i = 0; i < a.length; i++) { + if (!isEqual(a[i], b[i])) { + return false; + } + } + return true; + } + // Hash table + var keys = Object.keys(a); + if (keys.length !== Object.keys(b).length) { + return false; + } + for (var i = 0; i < keys.length; i++) { + if (!b.hasOwnProperty(keys[i])) { + return false; + } + if (!isEqual(a[keys[i]], b[keys[i]])) { + return false; + } + } + return true; + } + } + /* + * Helpers + */ + var isJsonArray = function (json) { return Array.isArray(json); }; + var isJsonObject = function (json) { + return typeof json === 'object' && json !== null && !isJsonArray(json); + }; + var typeString = function (json) { + switch (typeof json) { + case 'string': + return 'a string'; + case 'number': + return 'a number'; + case 'boolean': + return 'a boolean'; + case 'undefined': + return 'undefined'; + case 'object': + if (json instanceof Array) { + return 'an array'; + } + else if (json === null) { + return 'null'; + } + else { + return 'an object'; + } + default: + return JSON.stringify(json); + } + }; + var expectedGot = function (expected, got) { + return "expected " + expected + ", got " + typeString(got); + }; + var printPath = function (paths) { + return paths.map(function (path) { return (typeof path === 'string' ? "." + path : "[" + path + "]"); }).join(''); + }; + var prependAt = function (newAt, _a) { + var at = _a.at, rest = __rest(_a, ["at"]); + return (__assign({ at: newAt + (at || '') }, rest)); + }; + /** + * Decoders transform json objects with unknown structure into known and + * verified forms. You can create objects of type `Decoder` with either the + * primitive decoder functions, such as `boolean()` and `string()`, or by + * applying higher-order decoders to the primitives, such as `array(boolean())` + * or `dict(string())`. + * + * Each of the decoder functions are available both as a static method on + * `Decoder` and as a function alias -- for example the string decoder is + * defined at `Decoder.string()`, but is also aliased to `string()`. Using the + * function aliases exported with the library is recommended. + * + * `Decoder` exposes a number of 'run' methods, which all decode json in the + * same way, but communicate success and failure in different ways. The `map` + * and `andThen` methods modify decoders without having to call a 'run' method. + * + * Alternatively, the main decoder `run()` method returns an object of type + * `Result`. This library provides a number of helper + * functions for dealing with the `Result` type, so you can do all the same + * things with a `Result` as with the decoder methods. + */ + var Decoder = /** @class */ (function () { + /** + * The Decoder class constructor is kept private to separate the internal + * `decode` function from the external `run` function. The distinction + * between the two functions is that `decode` returns a + * `Partial` on failure, which contains an unfinished error + * report. When `run` is called on a decoder, the relevant series of `decode` + * calls is made, and then on failure the resulting `Partial` + * is turned into a `DecoderError` by filling in the missing information. + * + * While hiding the constructor may seem restrictive, leveraging the + * provided decoder combinators and helper functions such as + * `andThen` and `map` should be enough to build specialized decoders as + * needed. + */ + function Decoder(decode) { + var _this = this; + this.decode = decode; + /** + * Run the decoder and return a `Result` with either the decoded value or a + * `DecoderError` containing the json input, the location of the error, and + * the error message. + * + * Examples: + * ``` + * number().run(12) + * // => {ok: true, result: 12} + * + * string().run(9001) + * // => + * // { + * // ok: false, + * // error: { + * // kind: 'DecoderError', + * // input: 9001, + * // at: 'input', + * // message: 'expected a string, got 9001' + * // } + * // } + * ``` + */ + this.run = function (json) { + return mapError(function (error) { return ({ + kind: 'DecoderError', + input: json, + at: 'input' + (error.at || ''), + message: error.message || '' + }); }, _this.decode(json)); + }; + /** + * Run the decoder as a `Promise`. + */ + this.runPromise = function (json) { return asPromise(_this.run(json)); }; + /** + * Run the decoder and return the value on success, or throw an exception + * with a formatted error string. + */ + this.runWithException = function (json) { return withException(_this.run(json)); }; + /** + * Construct a new decoder that applies a transformation to the decoded + * result. If the decoder succeeds then `f` will be applied to the value. If + * it fails the error will propagated through. + * + * Example: + * ``` + * number().map(x => x * 5).run(10) + * // => {ok: true, result: 50} + * ``` + */ + this.map = function (f) { + return new Decoder(function (json) { return map(f, _this.decode(json)); }); + }; + /** + * Chain together a sequence of decoders. The first decoder will run, and + * then the function will determine what decoder to run second. If the result + * of the first decoder succeeds then `f` will be applied to the decoded + * value. If it fails the error will propagate through. + * + * This is a very powerful method -- it can act as both the `map` and `where` + * methods, can improve error messages for edge cases, and can be used to + * make a decoder for custom types. + * + * Example of adding an error message: + * ``` + * const versionDecoder = valueAt(['version'], number()); + * const infoDecoder3 = object({a: boolean()}); + * + * const decoder = versionDecoder.andThen(version => { + * switch (version) { + * case 3: + * return infoDecoder3; + * default: + * return fail(`Unable to decode info, version ${version} is not supported.`); + * } + * }); + * + * decoder.run({version: 3, a: true}) + * // => {ok: true, result: {a: true}} + * + * decoder.run({version: 5, x: 'abc'}) + * // => + * // { + * // ok: false, + * // error: {... message: 'Unable to decode info, version 5 is not supported.'} + * // } + * ``` + * + * Example of decoding a custom type: + * ``` + * // nominal type for arrays with a length of at least one + * type NonEmptyArray = T[] & { __nonEmptyArrayBrand__: void }; + * + * const nonEmptyArrayDecoder = (values: Decoder): Decoder> => + * array(values).andThen(arr => + * arr.length > 0 + * ? succeed(createNonEmptyArray(arr)) + * : fail(`expected a non-empty array, got an empty array`) + * ); + * ``` + */ + this.andThen = function (f) { + return new Decoder(function (json) { + return andThen(function (value) { return f(value).decode(json); }, _this.decode(json)); + }); + }; + /** + * Add constraints to a decoder _without_ changing the resulting type. The + * `test` argument is a predicate function which returns true for valid + * inputs. When `test` fails on an input, the decoder fails with the given + * `errorMessage`. + * + * ``` + * const chars = (length: number): Decoder => + * string().where( + * (s: string) => s.length === length, + * `expected a string of length ${length}` + * ); + * + * chars(5).run('12345') + * // => {ok: true, result: '12345'} + * + * chars(2).run('HELLO') + * // => {ok: false, error: {... message: 'expected a string of length 2'}} + * + * chars(12).run(true) + * // => {ok: false, error: {... message: 'expected a string, got a boolean'}} + * ``` + */ + this.where = function (test, errorMessage) { + return _this.andThen(function (value) { return (test(value) ? Decoder.succeed(value) : Decoder.fail(errorMessage)); }); + }; + } + /** + * Decoder primitive that validates strings, and fails on all other input. + */ + Decoder.string = function () { + return new Decoder(function (json) { + return typeof json === 'string' + ? ok(json) + : err({ message: expectedGot('a string', json) }); + }); + }; + /** + * Decoder primitive that validates numbers, and fails on all other input. + */ + Decoder.number = function () { + return new Decoder(function (json) { + return typeof json === 'number' + ? ok(json) + : err({ message: expectedGot('a number', json) }); + }); + }; + /** + * Decoder primitive that validates booleans, and fails on all other input. + */ + Decoder.boolean = function () { + return new Decoder(function (json) { + return typeof json === 'boolean' + ? ok(json) + : err({ message: expectedGot('a boolean', json) }); + }); + }; + Decoder.constant = function (value) { + return new Decoder(function (json) { + return isEqual(json, value) + ? ok(value) + : err({ message: "expected " + JSON.stringify(value) + ", got " + JSON.stringify(json) }); + }); + }; + Decoder.object = function (decoders) { + return new Decoder(function (json) { + if (isJsonObject(json) && decoders) { + var obj = {}; + for (var key in decoders) { + if (decoders.hasOwnProperty(key)) { + var r = decoders[key].decode(json[key]); + if (r.ok === true) { + // tslint:disable-next-line:strict-type-predicates + if (r.result !== undefined) { + obj[key] = r.result; + } + } + else if (json[key] === undefined) { + return err({ message: "the key '" + key + "' is required but was not present" }); + } + else { + return err(prependAt("." + key, r.error)); + } + } + } + return ok(obj); + } + else if (isJsonObject(json)) { + return ok(json); + } + else { + return err({ message: expectedGot('an object', json) }); + } + }); + }; + Decoder.array = function (decoder) { + return new Decoder(function (json) { + if (isJsonArray(json) && decoder) { + var decodeValue_1 = function (v, i) { + return mapError(function (err$$1) { return prependAt("[" + i + "]", err$$1); }, decoder.decode(v)); + }; + return json.reduce(function (acc, v, i) { + return map2(function (arr, result) { return arr.concat([result]); }, acc, decodeValue_1(v, i)); + }, ok([])); + } + else if (isJsonArray(json)) { + return ok(json); + } + else { + return err({ message: expectedGot('an array', json) }); + } + }); + }; + Decoder.tuple = function (decoders) { + return new Decoder(function (json) { + if (isJsonArray(json)) { + if (json.length !== decoders.length) { + return err({ + message: "expected a tuple of length " + decoders.length + ", got one of length " + json.length + }); + } + var result = []; + for (var i = 0; i < decoders.length; i++) { + var nth = decoders[i].decode(json[i]); + if (nth.ok) { + result[i] = nth.result; + } + else { + return err(prependAt("[" + i + "]", nth.error)); + } + } + return ok(result); + } + else { + return err({ message: expectedGot("a tuple of length " + decoders.length, json) }); + } + }); + }; + Decoder.union = function (ad, bd) { + var decoders = []; + for (var _i = 2; _i < arguments.length; _i++) { + decoders[_i - 2] = arguments[_i]; + } + return Decoder.oneOf.apply(Decoder, [ad, bd].concat(decoders)); + }; + Decoder.intersection = function (ad, bd) { + var ds = []; + for (var _i = 2; _i < arguments.length; _i++) { + ds[_i - 2] = arguments[_i]; + } + return new Decoder(function (json) { + return [ad, bd].concat(ds).reduce(function (acc, decoder) { return map2(Object.assign, acc, decoder.decode(json)); }, ok({})); + }); + }; + /** + * Escape hatch to bypass validation. Always succeeds and types the result as + * `any`. Useful for defining decoders incrementally, particularly for + * complex objects. + * + * Example: + * ``` + * interface User { + * name: string; + * complexUserData: ComplexType; + * } + * + * const userDecoder: Decoder = object({ + * name: string(), + * complexUserData: anyJson() + * }); + * ``` + */ + Decoder.anyJson = function () { return new Decoder(function (json) { return ok(json); }); }; + /** + * Decoder identity function which always succeeds and types the result as + * `unknown`. + */ + Decoder.unknownJson = function () { + return new Decoder(function (json) { return ok(json); }); + }; + /** + * Decoder for json objects where the keys are unknown strings, but the values + * should all be of the same type. + * + * Example: + * ``` + * dict(number()).run({chocolate: 12, vanilla: 10, mint: 37}); + * // => {ok: true, result: {chocolate: 12, vanilla: 10, mint: 37}} + * ``` + */ + Decoder.dict = function (decoder) { + return new Decoder(function (json) { + if (isJsonObject(json)) { + var obj = {}; + for (var key in json) { + if (json.hasOwnProperty(key)) { + var r = decoder.decode(json[key]); + if (r.ok === true) { + obj[key] = r.result; + } + else { + return err(prependAt("." + key, r.error)); + } + } + } + return ok(obj); + } + else { + return err({ message: expectedGot('an object', json) }); + } + }); + }; + /** + * Decoder for values that may be `undefined`. This is primarily helpful for + * decoding interfaces with optional fields. + * + * Example: + * ``` + * interface User { + * id: number; + * isOwner?: boolean; + * } + * + * const decoder: Decoder = object({ + * id: number(), + * isOwner: optional(boolean()) + * }); + * ``` + */ + Decoder.optional = function (decoder) { + return new Decoder(function (json) { return (json === undefined || json === null ? ok(undefined) : decoder.decode(json)); }); + }; + /** + * Decoder that attempts to run each decoder in `decoders` and either succeeds + * with the first successful decoder, or fails after all decoders have failed. + * + * Note that `oneOf` expects the decoders to all have the same return type, + * while `union` creates a decoder for the union type of all the input + * decoders. + * + * Examples: + * ``` + * oneOf(string(), number().map(String)) + * oneOf(constant('start'), constant('stop'), succeed('unknown')) + * ``` + */ + Decoder.oneOf = function () { + var decoders = []; + for (var _i = 0; _i < arguments.length; _i++) { + decoders[_i] = arguments[_i]; + } + return new Decoder(function (json) { + var errors = []; + for (var i = 0; i < decoders.length; i++) { + var r = decoders[i].decode(json); + if (r.ok === true) { + return r; + } + else { + errors[i] = r.error; + } + } + var errorsList = errors + .map(function (error) { return "at error" + (error.at || '') + ": " + error.message; }) + .join('", "'); + return err({ + message: "expected a value matching one of the decoders, got the errors [\"" + errorsList + "\"]" + }); + }); + }; + /** + * Decoder that always succeeds with either the decoded value, or a fallback + * default value. + */ + Decoder.withDefault = function (defaultValue, decoder) { + return new Decoder(function (json) { + return ok(withDefault(defaultValue, decoder.decode(json))); + }); + }; + /** + * Decoder that pulls a specific field out of a json structure, instead of + * decoding and returning the full structure. The `paths` array describes the + * object keys and array indices to traverse, so that values can be pulled out + * of a nested structure. + * + * Example: + * ``` + * const decoder = valueAt(['a', 'b', 0], string()); + * + * decoder.run({a: {b: ['surprise!']}}) + * // => {ok: true, result: 'surprise!'} + * + * decoder.run({a: {x: 'cats'}}) + * // => {ok: false, error: {... at: 'input.a.b[0]' message: 'path does not exist'}} + * ``` + * + * Note that the `decoder` is ran on the value found at the last key in the + * path, even if the last key is not found. This allows the `optional` + * decoder to succeed when appropriate. + * ``` + * const optionalDecoder = valueAt(['a', 'b', 'c'], optional(string())); + * + * optionalDecoder.run({a: {b: {c: 'surprise!'}}}) + * // => {ok: true, result: 'surprise!'} + * + * optionalDecoder.run({a: {b: 'cats'}}) + * // => {ok: false, error: {... at: 'input.a.b.c' message: 'expected an object, got "cats"'} + * + * optionalDecoder.run({a: {b: {z: 1}}}) + * // => {ok: true, result: undefined} + * ``` + */ + Decoder.valueAt = function (paths, decoder) { + return new Decoder(function (json) { + var jsonAtPath = json; + for (var i = 0; i < paths.length; i++) { + if (jsonAtPath === undefined) { + return err({ + at: printPath(paths.slice(0, i + 1)), + message: 'path does not exist' + }); + } + else if (typeof paths[i] === 'string' && !isJsonObject(jsonAtPath)) { + return err({ + at: printPath(paths.slice(0, i + 1)), + message: expectedGot('an object', jsonAtPath) + }); + } + else if (typeof paths[i] === 'number' && !isJsonArray(jsonAtPath)) { + return err({ + at: printPath(paths.slice(0, i + 1)), + message: expectedGot('an array', jsonAtPath) + }); + } + else { + jsonAtPath = jsonAtPath[paths[i]]; + } + } + return mapError(function (error) { + return jsonAtPath === undefined + ? { at: printPath(paths), message: 'path does not exist' } + : prependAt(printPath(paths), error); + }, decoder.decode(jsonAtPath)); + }); + }; + /** + * Decoder that ignores the input json and always succeeds with `fixedValue`. + */ + Decoder.succeed = function (fixedValue) { + return new Decoder(function (json) { return ok(fixedValue); }); + }; + /** + * Decoder that ignores the input json and always fails with `errorMessage`. + */ + Decoder.fail = function (errorMessage) { + return new Decoder(function (json) { return err({ message: errorMessage }); }); + }; + /** + * Decoder that allows for validating recursive data structures. Unlike with + * functions, decoders assigned to variables can't reference themselves + * before they are fully defined. We can avoid prematurely referencing the + * decoder by wrapping it in a function that won't be called until use, at + * which point the decoder has been defined. + * + * Example: + * ``` + * interface Comment { + * msg: string; + * replies: Comment[]; + * } + * + * const decoder: Decoder = object({ + * msg: string(), + * replies: lazy(() => array(decoder)) + * }); + * ``` + */ + Decoder.lazy = function (mkDecoder) { + return new Decoder(function (json) { return mkDecoder().decode(json); }); + }; + return Decoder; + }()); + + /* tslint:disable:variable-name */ + /** See `Decoder.string` */ + var string = Decoder.string; + /** See `Decoder.number` */ + var number = Decoder.number; + /** See `Decoder.boolean` */ + var boolean = Decoder.boolean; + /** See `Decoder.anyJson` */ + var anyJson = Decoder.anyJson; + /** See `Decoder.unknownJson` */ + Decoder.unknownJson; + /** See `Decoder.constant` */ + var constant = Decoder.constant; + /** See `Decoder.object` */ + var object = Decoder.object; + /** See `Decoder.array` */ + var array = Decoder.array; + /** See `Decoder.tuple` */ + Decoder.tuple; + /** See `Decoder.dict` */ + var dict = Decoder.dict; + /** See `Decoder.optional` */ + var optional = Decoder.optional; + /** See `Decoder.oneOf` */ + var oneOf = Decoder.oneOf; + /** See `Decoder.union` */ + Decoder.union; + /** See `Decoder.intersection` */ + Decoder.intersection; + /** See `Decoder.withDefault` */ + Decoder.withDefault; + /** See `Decoder.valueAt` */ + Decoder.valueAt; + /** See `Decoder.succeed` */ + Decoder.succeed; + /** See `Decoder.fail` */ + Decoder.fail; + /** See `Decoder.lazy` */ + Decoder.lazy; + + const nonEmptyStringDecoder = string().where((s) => s.length > 0, "Expected a non-empty string"); + const nonNegativeNumberDecoder = number().where((num) => num >= 0, "Expected a non-negative number"); + + const intentDefinitionDecoder = object({ + name: nonEmptyStringDecoder, + displayName: optional(string()), + contexts: optional(array(string())), + customConfig: optional(object()) + }); + const v2TypeDecoder = oneOf(constant("web"), constant("native"), constant("citrix"), constant("onlineNative"), constant("other")); + const v2DetailsDecoder = object({ + url: nonEmptyStringDecoder + }); + const v2IconDecoder = object({ + src: nonEmptyStringDecoder, + size: optional(nonEmptyStringDecoder), + type: optional(nonEmptyStringDecoder) + }); + const v2ScreenshotDecoder = object({ + src: nonEmptyStringDecoder, + size: optional(nonEmptyStringDecoder), + type: optional(nonEmptyStringDecoder), + label: optional(nonEmptyStringDecoder) + }); + const v2ListensForIntentDecoder = object({ + contexts: array(nonEmptyStringDecoder), + displayName: optional(nonEmptyStringDecoder), + resultType: optional(nonEmptyStringDecoder), + customConfig: optional(anyJson()) + }); + const v2IntentsDecoder = object({ + listensFor: optional(dict(v2ListensForIntentDecoder)), + raises: optional(dict(array(nonEmptyStringDecoder))) + }); + const v2UserChannelDecoder = object({ + broadcasts: optional(array(nonEmptyStringDecoder)), + listensFor: optional(array(nonEmptyStringDecoder)) + }); + const v2AppChannelDecoder = object({ + name: nonEmptyStringDecoder, + description: optional(nonEmptyStringDecoder), + broadcasts: optional(array(nonEmptyStringDecoder)), + listensFor: optional(array(nonEmptyStringDecoder)) + }); + const v2InteropDecoder = object({ + intents: optional(v2IntentsDecoder), + userChannels: optional(v2UserChannelDecoder), + appChannels: optional(array(v2AppChannelDecoder)) + }); + const glue42ApplicationDetailsDecoder = object({ + url: optional(nonEmptyStringDecoder), + top: optional(number()), + left: optional(number()), + width: optional(nonNegativeNumberDecoder), + height: optional(nonNegativeNumberDecoder) + }); + const glue42HostManifestsBrowserDecoder = object({ + name: optional(nonEmptyStringDecoder), + type: optional(nonEmptyStringDecoder.where((s) => s === "window", "Expected a value of window")), + title: optional(nonEmptyStringDecoder), + version: optional(nonEmptyStringDecoder), + customProperties: optional(anyJson()), + icon: optional(string()), + caption: optional(string()), + details: optional(glue42ApplicationDetailsDecoder), + intents: optional(array(intentDefinitionDecoder)), + hidden: optional(boolean()) + }); + const v1DefinitionDecoder = object({ + name: nonEmptyStringDecoder, + appId: nonEmptyStringDecoder, + title: optional(nonEmptyStringDecoder), + version: optional(nonEmptyStringDecoder), + manifest: nonEmptyStringDecoder, + manifestType: nonEmptyStringDecoder, + tooltip: optional(nonEmptyStringDecoder), + description: optional(nonEmptyStringDecoder), + contactEmail: optional(nonEmptyStringDecoder), + supportEmail: optional(nonEmptyStringDecoder), + publisher: optional(nonEmptyStringDecoder), + images: optional(array(object({ url: optional(nonEmptyStringDecoder) }))), + icons: optional(array(object({ icon: optional(nonEmptyStringDecoder) }))), + customConfig: anyJson(), + intents: optional(array(intentDefinitionDecoder)) + }); + const v2LocalizedDefinitionDecoder = object({ + appId: optional(nonEmptyStringDecoder), + name: optional(nonEmptyStringDecoder), + details: optional(v2DetailsDecoder), + version: optional(nonEmptyStringDecoder), + title: optional(nonEmptyStringDecoder), + tooltip: optional(nonEmptyStringDecoder), + lang: optional(nonEmptyStringDecoder), + description: optional(nonEmptyStringDecoder), + categories: optional(array(nonEmptyStringDecoder)), + icons: optional(array(v2IconDecoder)), + screenshots: optional(array(v2ScreenshotDecoder)), + contactEmail: optional(nonEmptyStringDecoder), + supportEmail: optional(nonEmptyStringDecoder), + moreInfo: optional(nonEmptyStringDecoder), + publisher: optional(nonEmptyStringDecoder), + customConfig: optional(array(anyJson())), + hostManifests: optional(anyJson()), + interop: optional(v2InteropDecoder) + }); + const v2DefinitionDecoder = object({ + appId: nonEmptyStringDecoder, + name: nonEmptyStringDecoder, + type: v2TypeDecoder, + details: v2DetailsDecoder, + version: optional(nonEmptyStringDecoder), + title: optional(nonEmptyStringDecoder), + tooltip: optional(nonEmptyStringDecoder), + lang: optional(nonEmptyStringDecoder), + description: optional(nonEmptyStringDecoder), + categories: optional(array(nonEmptyStringDecoder)), + icons: optional(array(v2IconDecoder)), + screenshots: optional(array(v2ScreenshotDecoder)), + contactEmail: optional(nonEmptyStringDecoder), + supportEmail: optional(nonEmptyStringDecoder), + moreInfo: optional(nonEmptyStringDecoder), + publisher: optional(nonEmptyStringDecoder), + customConfig: optional(array(anyJson())), + hostManifests: optional(anyJson()), + interop: optional(v2InteropDecoder), + localizedVersions: optional(dict(v2LocalizedDefinitionDecoder)) + }); + const allDefinitionsDecoder = oneOf(v1DefinitionDecoder, v2DefinitionDecoder); + + const parseDecoderErrorToStringMessage = (error) => { + return `${error.kind} at ${error.at}: ${JSON.stringify(error.input)}. Reason - ${error.message}`; + }; + + class FDC3Service { + fdc3ToDesktopDefinitionType = { + web: "window", + native: "exe", + citrix: "citrix", + onlineNative: "clickonce", + other: "window" + }; + toApi() { + return { + isFdc3Definition: this.isFdc3Definition.bind(this), + parseToBrowserBaseAppData: this.parseToBrowserBaseAppData.bind(this), + parseToDesktopAppConfig: this.parseToDesktopAppConfig.bind(this) + }; + } + isFdc3Definition(definition) { + const decodeRes = allDefinitionsDecoder.run(definition); + if (!decodeRes.ok) { + return { isFdc3: false, reason: parseDecoderErrorToStringMessage(decodeRes.error) }; + } + if (definition.appId && definition.details) { + return { isFdc3: true, version: "2.0" }; + } + if (definition.manifest) { + return { isFdc3: true, version: "1.2" }; + } + return { isFdc3: false, reason: "The passed definition is not FDC3" }; + } + parseToBrowserBaseAppData(definition) { + const { isFdc3, version } = this.isFdc3Definition(definition); + if (!isFdc3) { + throw new Error("The passed definition is not FDC3"); + } + const decodeRes = allDefinitionsDecoder.run(definition); + if (!decodeRes.ok) { + throw new Error(`Invalid FDC3 ${version} definition. Error: ${parseDecoderErrorToStringMessage(decodeRes.error)}`); + } + const userProperties = this.getUserPropertiesFromDefinition(definition, version); + const createOptions = { url: this.getUrl(definition, version) }; + const baseApplicationData = { + name: definition.appId, + type: "window", + createOptions, + userProperties: { + ...userProperties, + intents: version === "1.2" + ? userProperties.intents + : this.getIntentsFromV2AppDefinition(definition), + details: createOptions + }, + title: definition.title, + version: definition.version, + icon: this.getIconFromDefinition(definition, version), + caption: definition.description, + fdc3: version === "2.0" ? { ...definition, definitionVersion: "2.0" } : undefined, + }; + const ioConnectDefinition = definition.hostManifests?.ioConnect || definition.hostManifests?.["Glue42"]; + if (!ioConnectDefinition) { + return baseApplicationData; + } + const ioDefinitionDecodeRes = glue42HostManifestsBrowserDecoder.run(ioConnectDefinition); + if (!ioDefinitionDecodeRes.ok) { + throw new Error(`Invalid FDC3 ${version} definition. Error: ${parseDecoderErrorToStringMessage(ioDefinitionDecodeRes.error)}`); + } + if (!Object.keys(ioDefinitionDecodeRes.result).length) { + return baseApplicationData; + } + return this.mergeBaseAppDataWithGlueManifest(baseApplicationData, ioDefinitionDecodeRes.result); + } + parseToDesktopAppConfig(definition) { + const { isFdc3, version } = this.isFdc3Definition(definition); + if (!isFdc3) { + throw new Error("The passed definition is not FDC3"); + } + const decodeRes = allDefinitionsDecoder.run(definition); + if (!decodeRes.ok) { + throw new Error(`Invalid FDC3 ${version} definition. Error: ${parseDecoderErrorToStringMessage(decodeRes.error)}`); + } + if (version === "1.2") { + const fdc3v1Definition = definition; + return { + name: fdc3v1Definition.appId, + type: "window", + details: { + url: this.getUrl(definition, version) + }, + version: fdc3v1Definition.version, + title: fdc3v1Definition.title, + tooltip: fdc3v1Definition.tooltip, + caption: fdc3v1Definition.description, + icon: fdc3v1Definition.icons?.[0].icon, + intents: fdc3v1Definition.intents, + customProperties: { + manifestType: fdc3v1Definition.manifestType, + images: fdc3v1Definition.images, + contactEmail: fdc3v1Definition.contactEmail, + supportEmail: fdc3v1Definition.supportEmail, + publisher: fdc3v1Definition.publisher, + icons: fdc3v1Definition.icons, + customConfig: fdc3v1Definition.customConfig + } + }; + } + const fdc3v2Definition = definition; + const desktopDefinition = { + name: fdc3v2Definition.appId, + type: this.fdc3ToDesktopDefinitionType[fdc3v2Definition.type], + details: fdc3v2Definition.details, + version: fdc3v2Definition.version, + title: fdc3v2Definition.title, + tooltip: fdc3v2Definition.tooltip, + caption: fdc3v2Definition.description, + icon: this.getIconFromDefinition(fdc3v2Definition, "2.0"), + intents: this.getIntentsFromV2AppDefinition(fdc3v2Definition), + fdc3: { ...fdc3v2Definition, definitionVersion: "2.0" } + }; + const ioConnectDefinition = definition.hostManifests?.ioConnect || definition.hostManifests?.["Glue42"]; + if (!ioConnectDefinition) { + return desktopDefinition; + } + if (typeof ioConnectDefinition !== "object" || Array.isArray(ioConnectDefinition)) { + throw new Error(`Invalid '${definition.hostManifests.ioConnect ? "hostManifests.ioConnect" : "hostManifests['Glue42']"}' key`); + } + return this.mergeDesktopConfigWithGlueManifest(desktopDefinition, ioConnectDefinition); + } + getUserPropertiesFromDefinition(definition, version) { + if (version === "1.2") { + return Object.fromEntries(Object.entries(definition).filter(([key]) => !connectBrowserAppProps.includes(key))); + } + return Object.fromEntries(Object.entries(definition).filter(([key]) => !connectBrowserAppProps.includes(key) && !fdc3v2AppProps.includes(key))); + } + getUrl(definition, version) { + let url; + if (version === "1.2") { + const parsedManifest = JSON.parse(definition.manifest); + url = parsedManifest.details?.url || parsedManifest.url; + } + else { + url = definition.details?.url; + } + if (!url || typeof url !== "string") { + throw new Error(`Invalid FDC3 ${version} definition. Provide valid 'url' under '${version === "1.2" ? "manifest" : "details"}' key`); + } + return url; + } + getIntentsFromV2AppDefinition(definition) { + const fdc3Intents = definition.interop?.intents?.listensFor; + if (!fdc3Intents) { + return; + } + const intents = Object.entries(fdc3Intents).map((fdc3Intent) => { + const [intentName, intentData] = fdc3Intent; + return { + name: intentName, + ...intentData + }; + }); + return intents; + } + getIconFromDefinition(definition, version) { + if (version === "1.2") { + return definition.icons?.find((iconDef) => iconDef.icon)?.icon || undefined; + } + return definition.icons?.find((iconDef) => iconDef.src)?.src || undefined; + } + mergeBaseAppDataWithGlueManifest(baseAppData, hostManifestDefinition) { + let baseApplicationDefinition = baseAppData; + if (hostManifestDefinition.details) { + const details = { ...baseAppData.createOptions, ...hostManifestDefinition.details }; + baseApplicationDefinition.createOptions = details; + baseApplicationDefinition.userProperties.details = details; + } + if (Array.isArray(hostManifestDefinition.intents)) { + baseApplicationDefinition.userProperties.intents = (baseApplicationDefinition.userProperties.intents || []).concat(hostManifestDefinition.intents); + } + baseApplicationDefinition = { ...baseApplicationDefinition, ...hostManifestDefinition }; + delete baseApplicationDefinition.details; + delete baseApplicationDefinition.intents; + return baseApplicationDefinition; + } + mergeDesktopConfigWithGlueManifest(config, desktopDefinition) { + const appConfig = Object.assign({}, config, desktopDefinition, { details: { ...config.details, ...desktopDefinition.details } }); + if (Array.isArray(desktopDefinition.intents)) { + appConfig.intents = (config.intents || []).concat(desktopDefinition.intents); + } + return appConfig; + } + } + + const decoders$1 = { + common: { + nonEmptyStringDecoder, + nonNegativeNumberDecoder + }, + fdc3: { + allDefinitionsDecoder, + v1DefinitionDecoder, + v2DefinitionDecoder + } + }; + + var INTENTS_ERRORS; + (function (INTENTS_ERRORS) { + INTENTS_ERRORS["USER_CANCELLED"] = "User Closed Intents Resolver UI without choosing a handler"; + INTENTS_ERRORS["CALLER_NOT_DEFINED"] = "Caller Id is not defined"; + INTENTS_ERRORS["TIMEOUT_HIT"] = "Timeout hit"; + INTENTS_ERRORS["INTENT_NOT_FOUND"] = "Cannot find Intent"; + INTENTS_ERRORS["HANDLER_NOT_FOUND"] = "Cannot find Intent Handler"; + INTENTS_ERRORS["TARGET_INSTANCE_UNAVAILABLE"] = "Cannot start Target Instance"; + INTENTS_ERRORS["INTENT_DELIVERY_FAILED"] = "Target Instance did not add a listener"; + INTENTS_ERRORS["RESOLVER_UNAVAILABLE"] = "Intents Resolver UI unavailable"; + INTENTS_ERRORS["RESOLVER_TIMEOUT"] = "User did not choose a handler"; + INTENTS_ERRORS["INVALID_RESOLVER_RESPONSE"] = "Intents Resolver UI returned invalid response"; + INTENTS_ERRORS["INTENT_HANDLER_REJECTION"] = "Intent Handler function processing the raised intent threw an error or rejected the promise it returned"; + })(INTENTS_ERRORS || (INTENTS_ERRORS = {})); + + class IoC { + _fdc3; + _decoders = decoders$1; + _errors = { + intents: INTENTS_ERRORS + }; + get fdc3() { + if (!this._fdc3) { + this._fdc3 = new FDC3Service().toApi(); + } + return this._fdc3; + } + get decoders() { + return this._decoders; + } + get errors() { + return this._errors; + } + } + + const ioc = new IoC(); + ioc.fdc3; + ioc.decoders; + const errors = ioc.errors; + + const GLUE42_FDC3_INTENTS_METHOD_PREFIX = "Tick42.FDC3.Intents."; + const INTENTS_RESOLVER_INTEROP_PREFIX = "T42.Intents.Resolver.Control"; + const INTENTS_RESOLVER_WIDTH = 400; + const INTENTS_RESOLVER_HEIGHT = 440; + const DEFAULT_RESOLVER_RESPONSE_TIMEOUT = 60 * 1000; + const INTENT_HANDLER_DEFAULT_PROPS = ["applicationName", "type"]; + const INTENTS_RESOLVER_APP_NAME = "intentsResolver"; + const MAX_SET_TIMEOUT_DELAY = 2147483647; + const DEFAULT_METHOD_RESPONSE_TIMEOUT_MS = 60 * 1000; + const DEFAULT_RAISE_TIMEOUT_MS = 90 * 1000; + const DEFAULT_PICK_HANDLER_BY_TIMEOUT_MS = 90 * 1000; + const ERRORS = errors.intents; + + const PromisePlus = (executor, timeoutMilliseconds, timeoutMessage) => { + return new Promise((resolve, reject) => { + const timeout = setTimeout(() => { + const message = timeoutMessage || `Promise timeout hit: ${timeoutMilliseconds}`; + reject(message); + }, timeoutMilliseconds); + const providedPromise = new Promise(executor); + providedPromise + .then((result) => { + clearTimeout(timeout); + resolve(result); + }) + .catch((error) => { + clearTimeout(timeout); + reject(error); + }); + }); + }; + const PromiseWrap = (promise, timeoutMilliseconds, timeoutMessage) => { + return new Promise((resolve, reject) => { + let promiseActive = true; + const timeout = setTimeout(() => { + if (!promiseActive) { + return; + } + promiseActive = false; + const message = timeoutMessage || `Promise timeout hit: ${timeoutMilliseconds}`; + reject(message); + }, timeoutMilliseconds); + promise() + .then((result) => { + if (!promiseActive) { + return; + } + promiseActive = false; + clearTimeout(timeout); + resolve(result); + }) + .catch((error) => { + if (!promiseActive) { + return; + } + promiseActive = false; + clearTimeout(timeout); + reject(error); + }); + }); + }; + + const validateIntentHandlerAsResponse = (handler) => { + if (typeof handler !== "object") { + return { isValid: false, error: `Response object has invalid 'handler' key. Expected an object, got ${typeof handler}` }; + } + const compulsoryKeysExist = INTENT_HANDLER_DEFAULT_PROPS.filter((key) => !(key in handler)); + if (compulsoryKeysExist.length) { + return { isValid: false, error: `Handler in Response object does not provide compulsory keys: ${compulsoryKeysExist.join(", ")}` }; + } + return { isValid: true, ok: handler }; + }; + const validateIntentRequestTarget = (target) => { + if (!target) { + return; + } + if (typeof target !== "string" && typeof target !== "object") { + throw new Error(`Please provide the intent target as one of the valid values: "reuse", "startNew", { app: string }, { instance: string } `); + } + }; + const validateIntentRequestContext = (context) => { + if (!context) { + return; + } + if (typeof context !== "object") { + throw new Error(`Please provide the intent context as an object`); + } + if (context.type && typeof context.type !== "string") { + throw new Error(`Please provide the intent context as an object with 'type' property as string`); + } + if (context.data && typeof context.data !== "object") { + throw new Error(`Please provide the intent context as an object with 'data' property as object`); + } + }; + const validateIntentRequestHandler = (handler) => { + if (!handler.applicationName) { + throw new Error(`Please provide applicationName for handler ${JSON.stringify(handler)}`); + } + if (!handler.type) { + throw new Error(`Please provide type for handler ${JSON.stringify(handler)}`); + } + if (handler.type === "instance" && !handler.instanceId) { + throw new Error(`Please provide instanceId for handler ${JSON.stringify(handler)}`); + } + }; + const validateIntentRequestTimeout = (timeout) => { + if (!timeout) { + return; + } + if (typeof timeout !== "number") { + throw new Error(`Please provide the timeout as a number`); + } + if (timeout <= 0) { + throw new Error(`Please provide the timeout as a positive number`); + } + }; + const validateWaitUserResponseIndefinitely = (waitUserResponseIndefinitely) => { + if (!waitUserResponseIndefinitely) { + return; + } + if (typeof waitUserResponseIndefinitely !== "boolean") { + throw new Error("Please provide waitUserResponseIndefinitely as a boolean"); + } + }; + const validateHandlerFilter = (handlerFilter) => { + if (!handlerFilter) { + throw new Error(`Provide 'handlerFilter' with at least one filter criteria of the following: 'intent' | 'contextTypes' | 'resultType' | 'applicationNames'`); + } + const { title, openResolver, timeout, intent, contextTypes, resultType, applicationNames } = handlerFilter; + if (typeof title !== "undefined" && (typeof title !== "string" || !title.length)) { + throw new Error(`Provide 'title' as a non empty string`); + } + if (typeof openResolver !== "undefined" && typeof openResolver !== "boolean") { + throw new Error(`Provide 'openResolver' prop as a boolean`); + } + if (typeof timeout !== "undefined" && (typeof timeout !== "number" || timeout <= 0)) { + throw new Error(`Provide 'timeout' prop as a positive number`); + } + if (typeof intent !== "undefined" && (typeof intent !== "string" || !intent.length)) { + throw new Error(`Provide 'intent' as a non empty string`); + } + if (typeof contextTypes !== "undefined" && (!Array.isArray(contextTypes) || contextTypes.some(ctx => typeof ctx !== "string"))) { + throw new Error(`Provide 'contextTypes' as an array of non empty strings`); + } + if (typeof resultType !== "undefined" && (typeof resultType !== "string" || !resultType.length)) { + throw new Error(`Provide 'resultType' as a non empty string`); + } + if (typeof applicationNames !== "undefined" && (!Array.isArray(applicationNames) || applicationNames.some(appName => typeof appName !== "string"))) { + throw new Error(`Provide 'applicationNames' as an array of non empty strings`); + } + const errorMsg = "Provide at least one filter criteria of the following: 'intent' | 'contextTypes' | 'resultType' | 'applicationNames'"; + if (!Object.keys(handlerFilter).length) { + throw new Error(errorMsg); + } + if (!intent && !resultType && (!contextTypes || !contextTypes.length) && (!applicationNames || !applicationNames.length)) { + throw new Error(errorMsg); + } + }; + const validateResolverResponse = (responseObj) => { + var _a, _b; + if (typeof responseObj.intent !== "string") { + return { isValid: false, error: `Response object has invalid 'intent' key. Expected a string, got ${typeof responseObj.intent}` }; + } + if (((_a = responseObj.userSettings) === null || _a === void 0 ? void 0 : _a.preserveChoice) && typeof ((_b = responseObj.userSettings) === null || _b === void 0 ? void 0 : _b.preserveChoice) !== "boolean") { + return { isValid: false, error: `Response object has invalid 'userSettings.preserveChoice' key. Expected a boolean, got ${typeof responseObj.userSettings.preserveChoice}` }; + } + const { isValid, error } = validateIntentHandlerAsResponse(responseObj.handler); + return isValid + ? { isValid: true, ok: responseObj } + : { isValid, error }; + }; + const validateIntentRequest = (request) => { + validateIntentRequestContext(request.context); + validateIntentRequestTarget(request.target); + validateIntentRequestTimeout(request.timeout); + validateWaitUserResponseIndefinitely(request.waitUserResponseIndefinitely); + if (typeof request.clearSavedHandler !== "undefined" && typeof request.clearSavedHandler !== "boolean") { + throw new Error("Please provide 'clearSavedHandler' as a boolean"); + } + if (request.handlers) { + request.handlers.forEach((handler) => validateIntentRequestHandler(handler)); + } + }; + const validateIntentHandler = (handler) => { + if (typeof handler !== "object") { + throw new Error("IntentHandler must be an object"); + } + if (typeof handler.applicationName !== "string" || !handler.applicationName.length) { + throw new Error(`Please provide 'applicationName' as a non-empty string`); + } + if (typeof handler.type !== "string" || !["app", "instance"].includes(handler.type)) { + throw new Error(`Invalid 'type' property. Expected 'app' | 'instance' got ${handler.type}`); + } + if (typeof handler.applicationTitle !== "undefined" && typeof handler.applicationTitle !== "string") { + throw new Error(`Provide 'applicationTitle' as a string`); + } + if (typeof handler.applicationDescription !== "undefined" && typeof handler.applicationDescription !== "string") { + throw new Error(`Provide 'applicationDescription' as a string`); + } + if (typeof handler.applicationIcon !== "undefined" && typeof handler.applicationIcon !== "string") { + throw new Error(`Provide 'applicationIcon' as a string`); + } + if (typeof handler.displayName !== "undefined" && typeof handler.displayName !== "string") { + throw new Error(`Provide 'displayName' as a string`); + } + if (typeof handler.contextTypes !== "undefined" && (!Array.isArray(handler.contextTypes) || handler.contextTypes.some(ctx => typeof ctx !== "string"))) { + throw new Error(`Provide 'contextTypes' as an array of non empty strings`); + } + if (typeof handler.instanceId !== "undefined" && typeof handler.instanceId !== "string") { + throw new Error(`Provide 'instanceId' as a string`); + } + if (typeof handler.instanceTitle !== "undefined" && typeof handler.instanceTitle !== "string") { + throw new Error(`Provide 'instanceTitle' as a string`); + } + if (typeof handler.resultType !== "undefined" && typeof handler.resultType !== "string") { + throw new Error(`Provide 'resultType' as a string`); + } + }; + const clearNullUndefined = (obj) => { + Object.keys(obj).forEach(key => { + if (obj[key] === null || obj[key] === undefined) { + delete obj[key]; + } + }); + }; + + class Intents { + constructor(interop, windows, logger, options, prefsController, appManager) { + this.interop = interop; + this.windows = windows; + this.logger = logger; + this.prefsController = prefsController; + this.appManager = appManager; + this.myIntents = new Set(); + this.intentsResolverResponsePromises = {}; + this.useIntentsResolverUI = true; + this.unregisterIntentPromises = []; + this.addedHandlerInfoPerApp = {}; + this.checkIfIntentsResolverIsEnabled(options, appManager); + } + async find(intentFilter) { + await Promise.all(this.unregisterIntentPromises); + let intents = await this.all(); + if (typeof intentFilter === "undefined") { + return intents; + } + if (typeof intentFilter === "string") { + return intents.filter((intent) => intent.name === intentFilter); + } + if (typeof intentFilter !== "object") { + throw new Error("Please provide the intentFilter as a string or an object!"); + } + if (intentFilter.contextType) { + const ctToLower = intentFilter.contextType.toLowerCase(); + intents = intents.filter((intent) => intent.handlers.some((handler) => { var _a; return (_a = handler.contextTypes) === null || _a === void 0 ? void 0 : _a.some((ct) => ct.toLowerCase() === ctToLower); })); + } + if (intentFilter.resultType) { + const resultTypeToLower = intentFilter.resultType.toLowerCase(); + intents = intents.filter((intent) => intent.handlers.some((handler) => { var _a; return ((_a = handler.resultType) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === resultTypeToLower; })); + } + if (intentFilter.name) { + intents = intents.filter((intent) => intent.name === intentFilter.name); + } + return intents; + } + async raise(intentRequest) { + if ((typeof intentRequest !== "string" && typeof intentRequest !== "object") || (typeof intentRequest === "object" && typeof intentRequest.intent !== "string")) { + throw new Error("Please provide the intent as a string or an object with an intent property!"); + } + if (typeof intentRequest === "string") { + intentRequest = { intent: intentRequest }; + } + validateIntentRequest(intentRequest); + await Promise.all(this.unregisterIntentPromises); + if (intentRequest.clearSavedHandler) { + this.logger.trace(`User removes saved handler for intent ${intentRequest.intent}`); + await this.removeRememberedHandler(intentRequest.intent); + } + const resolverInstance = {}; + const timeout = intentRequest.waitUserResponseIndefinitely ? MAX_SET_TIMEOUT_DELAY : intentRequest.timeout || DEFAULT_RAISE_TIMEOUT_MS; + const resultFromRememberedHandler = await this.checkHandleRaiseWithRememberedHandler(intentRequest, resolverInstance, timeout); + if (resultFromRememberedHandler) { + return resultFromRememberedHandler; + } + const coreRaiseIntentFn = this.coreRaiseIntent.bind(this, { request: intentRequest, resolverInstance, timeout }); + if (intentRequest.waitUserResponseIndefinitely) { + return coreRaiseIntentFn(); + } + const resultPromise = PromiseWrap(coreRaiseIntentFn, timeout, `${ERRORS.TIMEOUT_HIT} hit for intent request ${JSON.stringify(intentRequest)}`); + resultPromise.catch(() => this.handleRaiseOnError(resolverInstance.instanceId)); + return resultPromise; + } + async all() { + await Promise.all(this.unregisterIntentPromises); + let apps; + try { + const result = await this.interop.invoke("T42.ACS.GetApplications", { withIntentsInfo: true }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + apps = result.returned.applications; + } + catch (e) { + this.logger.error(`Failed to get the applications!`, e); + return []; + } + const intents = {}; + const appsWithIntents = apps.filter((app) => app.intents && app.intents.length > 0); + for (const app of appsWithIntents) { + for (const intentDef of app.intents) { + let intent = intents[intentDef.name]; + if (!intent) { + intent = { + name: intentDef.name, + handlers: [], + }; + intents[intentDef.name] = intent; + } + const handler = { + applicationName: app.name, + applicationTitle: app.title || "", + applicationDescription: app.caption, + displayName: intentDef.displayName, + contextTypes: intentDef.contexts, + applicationIcon: app.icon, + type: "app", + resultType: intentDef.resultType + }; + intent.handlers.push(handler); + } + } + const servers = this.interop.servers(); + const serverWindowIds = servers.map((server) => server.windowId).filter((serverWindowId) => typeof serverWindowId !== "undefined"); + const T42WndGetInfo = "T42.Wnd.GetInfo"; + const isT42WndGetInfoMethodRegistered = this.interop.methods().some((method) => method.name === T42WndGetInfo); + let windowsInfos; + if (isT42WndGetInfoMethodRegistered) { + try { + const result = await this.interop.invoke(T42WndGetInfo, { ids: serverWindowIds }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + windowsInfos = result.returned.windows; + } + catch (e) { + } + } + for (const server of servers) { + await Promise.all(server.getMethods() + .filter((method) => method.name.startsWith(GLUE42_FDC3_INTENTS_METHOD_PREFIX)) + .map(async (method) => { + const intentName = method.name.replace(GLUE42_FDC3_INTENTS_METHOD_PREFIX, ""); + let intent = intents[intentName]; + if (!intent) { + intent = { + name: intentName, + handlers: [], + }; + intents[intentName] = intent; + } + const title = await this.windowsIdToTitle(server.windowId, windowsInfos); + const handler = this.constructIntentHandler({ method, apps, server, intentName, title }); + intent.handlers.push(handler); + })); + } + return Object.values(intents); + } + addIntentListener(intent, handler) { + if ((typeof intent !== "string" && typeof intent !== "object") || (typeof intent === "object" && typeof intent.intent !== "string")) { + throw new Error("Please provide the intent as a string or an object with an intent property!"); + } + if (typeof handler !== "function") { + throw new Error("Please provide the handler as a function!"); + } + const intentName = typeof intent === "string" ? intent : intent.intent; + const methodName = `${GLUE42_FDC3_INTENTS_METHOD_PREFIX}${intentName}`; + let intentFlag = {}; + let registerPromise; + const alreadyRegistered = this.myIntents.has(intentName); + if (alreadyRegistered) { + throw new Error(`Intent listener for intent ${intentName} already registered!`); + } + this.myIntents.add(intentName); + const result = { + unsubscribe: () => { + this.myIntents.delete(intentName); + registerPromise + .then(() => this.interop.unregister(methodName)) + .catch((err) => this.logger.trace(`Unregistration of a method with name ${methodName} failed with reason: ${JSON.stringify(err)}`)); + } + }; + if (typeof intent === "object") { + const { intent: removed, ...rest } = intent; + intentFlag = rest; + } + registerPromise = this.interop.register({ name: methodName, flags: { intent: intentFlag } }, (args) => { + if (this.myIntents.has(intentName)) { + return handler(args); + } + }); + registerPromise.catch((err) => { + this.myIntents.delete(intentName); + this.logger.warn(`Registration of a method with name ${methodName} failed with reason: ${JSON.stringify(err)}`); + }); + return result; + } + async register(intent, handler) { + if ((typeof intent !== "string" && typeof intent !== "object") || (typeof intent === "object" && typeof intent.intent !== "string")) { + throw new Error("Please provide the intent as a string or an object with an intent property!"); + } + if (typeof handler !== "function") { + throw new Error("Please provide the handler as a function!"); + } + await Promise.all(this.unregisterIntentPromises); + const intentName = typeof intent === "string" ? intent : intent.intent; + const methodName = this.buildInteropMethodName(intentName); + let intentFlag = {}; + const alreadyRegistered = this.myIntents.has(intentName); + if (alreadyRegistered) { + throw new Error(`Intent listener for intent ${intentName} already registered!`); + } + this.myIntents.add(intentName); + if (typeof intent === "object") { + const { intent: removed, ...rest } = intent; + intentFlag = rest; + } + try { + await this.interop.register({ name: methodName, flags: { intent: intentFlag } }, (args, caller) => { + if (this.myIntents.has(intentName)) { + return handler(args, caller); + } + }); + } + catch (err) { + this.myIntents.delete(intentName); + throw new Error(`Registration of a method with name ${methodName} failed with reason: ${JSON.stringify(err)}`); + } + return { + unsubscribe: () => this.unsubscribeIntent(intentName) + }; + } + async filterHandlers(handlerFilter) { + var _a, _b; + validateHandlerFilter(handlerFilter); + if (handlerFilter.openResolver && !this.useIntentsResolverUI) { + throw new Error("Cannot resolve 'filterHandlers' request using Intents Resolver UI because it's globally disabled"); + } + (_a = this.logger) === null || _a === void 0 ? void 0 : _a.trace(`Received 'filterHandlers' command with request: ${JSON.stringify(handlerFilter)}`); + const filteredHandlers = this.filterHandlersBy(await this.all(), handlerFilter); + if (!filteredHandlers || !filteredHandlers.length) { + return { handlers: [] }; + } + const { open, reason } = this.checkIfResolverShouldBeOpenedForFilterHandlers(filteredHandlers, handlerFilter); + if (!open) { + (_b = this.logger) === null || _b === void 0 ? void 0 : _b.trace(`Intent Resolver UI won't be used. Reason: ${reason}`); + return { handlers: filteredHandlers }; + } + const resolverInstance = { instanceId: undefined }; + const timeout = handlerFilter.timeout || DEFAULT_PICK_HANDLER_BY_TIMEOUT_MS; + const handler = await PromiseWrap(() => this.startResolverApp({ request: handlerFilter, resolverInstance, method: 'filterHandlers' }), timeout, `Timeout of ${timeout}ms hit for 'filterHandlers' request with filter: ${JSON.stringify(handlerFilter)}`); + return { handlers: [handler] }; + } + async getIntents(handler) { + var _a; + this.logger.trace(`Received 'getIntents' command with handler ${JSON.stringify(handler)}`); + validateIntentHandler(handler); + const intents = await this.all(); + clearNullUndefined(handler); + (_a = this.logger) === null || _a === void 0 ? void 0 : _a.trace(`Extracting valid intents for the passed handler`); + const intentsWithInfo = this.extractIntentsWithInfoByHandler(intents, handler); + this.logger.trace(`Returning intents for handler ${JSON.stringify(handler)}`); + return { intents: intentsWithInfo }; + } + async clearSavedHandlers() { + this.logger.trace("Removing all saved handlers from prefs storage for current app"); + await this.prefsController.update({ intents: undefined }); + } + onHandlerAdded(callback) { + var _a; + const unAppAdded = (_a = this.appManager) === null || _a === void 0 ? void 0 : _a.onAppAdded(async (app) => { + var _a; + const appName = app.name; + const appDef = await app.getConfiguration(); + const isIntentHandler = (_a = appDef === null || appDef === void 0 ? void 0 : appDef.intents) === null || _a === void 0 ? void 0 : _a.length; + if (!isIntentHandler) { + return; + } + appDef.intents.forEach((intent) => { + const handler = this.constructIntentHandlerFromApp(appDef, intent); + if (!this.addedHandlerInfoPerApp[appName]) { + this.addedHandlerInfoPerApp[appName] = []; + } + const appHandlers = this.addedHandlerInfoPerApp[appName]; + appHandlers.push({ handler, name: intent.name }); + callback(handler, intent.name); + }); + }); + const unServerMethodAdded = this.interop.serverMethodAdded(({ method, server }) => { + if (!method.name.startsWith(GLUE42_FDC3_INTENTS_METHOD_PREFIX)) { + return; + } + const intentName = method.name.replace(GLUE42_FDC3_INTENTS_METHOD_PREFIX, ""); + const intentsInfo = this.constructIntentHandler({ method, apps: [], server, intentName, title: "" }); + callback(intentsInfo, intentName); + }); + return () => { + if (typeof unServerMethodAdded === "function") { + unServerMethodAdded(); + } + if (typeof unAppAdded === "function") { + unAppAdded(); + } + }; + } + onHandlerRemoved(callback) { + var _a; + const unAppRemoved = (_a = this.appManager) === null || _a === void 0 ? void 0 : _a.onAppRemoved(async (app) => { + const appName = app.name; + const handlers = this.addedHandlerInfoPerApp[appName]; + const isIntentHandler = handlers === null || handlers === void 0 ? void 0 : handlers.length; + if (!isIntentHandler) { + return; + } + delete this.addedHandlerInfoPerApp[appName]; + handlers.forEach((addedHandlerInfo) => { + callback(addedHandlerInfo.handler, addedHandlerInfo.name); + }); + }); + const unServerMethodAdded = this.interop.serverMethodRemoved(({ method, server }) => { + if (!method.name.startsWith(GLUE42_FDC3_INTENTS_METHOD_PREFIX)) { + return; + } + const intentName = method.name.replace(GLUE42_FDC3_INTENTS_METHOD_PREFIX, ""); + const intentsInfo = this.constructIntentHandler({ method, apps: [], server, intentName, title: "" }); + callback(intentsInfo, intentName); + }); + return () => { + if (typeof unServerMethodAdded === "function") { + unServerMethodAdded(); + } + if (typeof unAppRemoved === "function") { + unAppRemoved(); + } + }; + } + toAPI() { + return { + all: this.all.bind(this), + find: this.find.bind(this), + raise: this.raise.bind(this), + addIntentListener: this.addIntentListener.bind(this), + register: this.register.bind(this), + filterHandlers: this.filterHandlers.bind(this), + getIntents: this.getIntents.bind(this), + clearSavedHandlers: this.clearSavedHandlers.bind(this), + onHandlerAdded: this.onHandlerAdded.bind(this), + onHandlerRemoved: this.onHandlerRemoved.bind(this) + }; + } + filterHandlersBy(intents, filter) { + const filteredIntentsWithHandlers = intents.filter((intent) => { + if (filter.intent && filter.intent !== intent.name) { + return; + } + if (filter.resultType) { + const filteredHandlers = intent.handlers.filter((handler) => handler.resultType && handler.resultType === filter.resultType); + if (!filteredHandlers.length) + return; + intent.handlers = filteredHandlers; + } + if (filter.contextTypes) { + const filteredHandlers = intent.handlers.filter((handler) => { var _a; return (_a = filter.contextTypes) === null || _a === void 0 ? void 0 : _a.every((contextType) => { var _a; return (_a = handler.contextTypes) === null || _a === void 0 ? void 0 : _a.includes(contextType); }); }); + if (!filteredHandlers.length) + return; + intent.handlers = filteredHandlers; + } + if (filter.applicationNames) { + const filteredHandlers = intent.handlers.filter((handler) => { var _a; return (_a = filter.applicationNames) === null || _a === void 0 ? void 0 : _a.includes(handler.applicationName); }); + if (!filteredHandlers.length) + return; + intent.handlers = filteredHandlers; + } + return intent; + }); + return filteredIntentsWithHandlers.map((intent) => intent.handlers).flat(1); + } + async coreRaiseIntent({ request, resolverInstance, timeout }) { + var _a, _b; + const intentDef = await this.get(request.intent); + if (typeof intentDef === "undefined") { + throw new Error(`${ERRORS.INTENT_NOT_FOUND} with name ${request.intent}`); + } + const { open, reason } = await this.checkIfResolverShouldBeOpenedForRaise(intentDef, request); + if (!open) { + this.logger.trace(`Intent Resolver UI won't be used. Reason: ${reason}`); + return request.waitUserResponseIndefinitely + ? PromiseWrap(() => this.raiseIntent(request, timeout), timeout, `${ERRORS.TIMEOUT_HIT} - waited ${timeout}ms for 'raise' to resolve`) + : this.raiseIntent(request, timeout); + } + const resolverHandler = await this.startResolverApp({ request, method: "raise", resolverInstance }); + (_a = this.logger) === null || _a === void 0 ? void 0 : _a.trace(`Raising intent to target handler: ${JSON.stringify(resolverHandler)} with timeout of ${timeout}`); + if (request.waitUserResponseIndefinitely) { + return PromiseWrap(() => this.raiseIntentToTargetHandler(request, resolverHandler, timeout), timeout, `${ERRORS.TIMEOUT_HIT} - waited ${timeout}ms for 'raise' to resolve`); + } + const result = await this.raiseIntentToTargetHandler(request, resolverHandler, timeout); + (_b = this.logger) === null || _b === void 0 ? void 0 : _b.trace(`Result from raise() method for intent ${JSON.stringify(request.intent)}: ${JSON.stringify(result)}`); + return result; + } + async get(intent) { + return (await this.all()).find((registeredIntent) => registeredIntent.name === intent); + } + async raiseIntent(intentRequest, timeout) { + const intentName = intentRequest.intent; + const intentDef = await this.get(intentName); + if (typeof intentDef === "undefined") { + throw new Error(`${ERRORS.INTENT_NOT_FOUND} with name ${intentRequest.intent}`); + } + const firstFoundAppHandler = intentRequest.handlers ? this.findHandlerByFilter(intentRequest.handlers, { type: "app" }) : this.findHandlerByFilter(intentDef.handlers, { type: "app" }); + const firstFoundInstanceHandler = intentRequest.handlers ? this.findHandlerByFilter(intentRequest.handlers, { type: "instance" }) : this.findHandlerByFilter(intentDef.handlers, { type: "instance" }); + let handler; + if (!intentRequest.target || intentRequest.target === "reuse") { + handler = firstFoundInstanceHandler || firstFoundAppHandler; + } + if (intentRequest.target === "startNew") { + handler = firstFoundAppHandler; + } + if (typeof intentRequest.target === "object" && intentRequest.target.app) { + handler = this.findHandlerByFilter(intentDef.handlers, { app: intentRequest.target.app }); + } + if (typeof intentRequest.target === "object" && intentRequest.target.instance) { + handler = this.findHandlerByFilter(intentDef.handlers, { instance: intentRequest.target.instance, app: intentRequest.target.app }); + } + if (!handler) { + throw new Error(`Can not raise intent for request ${JSON.stringify(intentRequest)} - can not find intent handler!`); + } + const result = await this.raiseIntentToTargetHandler(intentRequest, handler, timeout); + return result; + } + async raiseIntentToTargetHandler(intentRequest, handler, timeout) { + var _a, _b; + (_a = this.logger) === null || _a === void 0 ? void 0 : _a.trace(`Raising intent to target handler:${JSON.stringify(handler)}`); + if (!handler.instanceId) { + const instanceIdPromise = this.invokeStartApp(handler.applicationName, intentRequest.context, intentRequest.options).catch((err) => { + const reasonMsg = typeof err === "string" ? err : JSON.stringify(err); + throw new Error(`${ERRORS.TARGET_INSTANCE_UNAVAILABLE}. Reason: ${reasonMsg}`); + }); + handler.instanceId = await instanceIdPromise; + } + const methodName = `${GLUE42_FDC3_INTENTS_METHOD_PREFIX}${intentRequest.intent}`; + const invokeOptions = { + methodResponseTimeoutMs: timeout ? timeout + 1000 : DEFAULT_METHOD_RESPONSE_TIMEOUT_MS, + waitTimeoutMs: timeout ? timeout + 1000 : DEFAULT_METHOD_RESPONSE_TIMEOUT_MS + }; + const resultPromise = this.interop.invoke(methodName, intentRequest.context, { instance: handler.instanceId }, invokeOptions) + .catch((err) => { + const reasonMsg = typeof err === "string" ? err : JSON.stringify(err); + throw new Error(`${ERRORS.INTENT_HANDLER_REJECTION}. Reason: ${reasonMsg}`); + }); + const result = await resultPromise; + (_b = this.logger) === null || _b === void 0 ? void 0 : _b.trace(`raiseIntent command completed. Returning result: ${JSON.stringify(result)}`); + return { + request: intentRequest, + handler: { ...handler, type: "instance" }, + result: result.returned + }; + } + async startResolverApp({ request, method, resolverInstance }) { + var _a, _b, _c, _d; + (_a = this.logger) === null || _a === void 0 ? void 0 : _a.trace(`Intents Resolver UI with app name ${this.intentsResolverAppName} will be used for request: ${JSON.stringify(request)}`); + const responseMethodName = await this.registerIntentResolverMethod(); + (_b = this.logger) === null || _b === void 0 ? void 0 : _b.trace(`Registered interop method ${responseMethodName}`); + const startContext = this.buildStartContext(method, request, responseMethodName); + const startOptions = await this.buildStartOptions(); + (_c = this.logger) === null || _c === void 0 ? void 0 : _c.trace(`Starting Intents Resolver UI with context: ${JSON.stringify(startContext)} and options: ${JSON.stringify(startOptions)}`); + const instance = await this.appManager.application(this.intentsResolverAppName).start(startContext, startOptions); + resolverInstance.instanceId = instance.id; + (_d = this.logger) === null || _d === void 0 ? void 0 : _d.trace(`Intents Resolver instance with id ${instance.id} opened`); + this.subscribeOnInstanceStopped(instance, method); + const timeout = request.timeout || method === "raise" ? DEFAULT_RAISE_TIMEOUT_MS : DEFAULT_PICK_HANDLER_BY_TIMEOUT_MS; + this.createResponsePromise({ + intent: method === "raise" ? request.intent : undefined, + instanceId: instance.id, + responseMethodName, + timeout, + errorMsg: `Timeout of ${timeout}ms hit waiting for the user to choose a handler ${method === "raise" + ? `for intent ${request.intent}` + : `for '${method}' method with filter ${JSON.stringify(request)}`}` + }); + const handler = await this.handleInstanceResponse({ instanceId: instance.id, caller: startContext.initialCaller, method, request }); + return handler; + } + async windowsIdToTitle(id, windowsInfos) { + var _a, _b; + if (typeof windowsInfos !== "undefined") { + return (_a = windowsInfos.find((windowsInfo) => windowsInfo.id === id)) === null || _a === void 0 ? void 0 : _a.title; + } + const window = (_b = this.windows) === null || _b === void 0 ? void 0 : _b.findById(id); + const title = await (window === null || window === void 0 ? void 0 : window.getTitle()); + return title; + } + async handleInstanceResponse({ instanceId, method, request, caller }) { + var _a, _b, _c; + try { + const response = await this.intentsResolverResponsePromises[instanceId].promise; + const subMessage = method === "raise" ? `for intent ${response.intent} ` : ""; + (_a = this.logger) === null || _a === void 0 ? void 0 : _a.trace(`Intent handler chosen ${subMessage}: ${JSON.stringify(response.handler)}. Stopping resolver instance with id ${instanceId}`); + this.stopResolverInstance(instanceId); + (_b = this.logger) === null || _b === void 0 ? void 0 : _b.trace(`Instance with id ${instanceId} successfully stopped`); + if ((_c = response.userSettings) === null || _c === void 0 ? void 0 : _c.preserveChoice) { + await this.saveUserChoice({ + intent: response.intent, + handler: response.handler, + filter: method === "filterHandlers" + ? { applicationNames: request.applicationNames, contextTypes: request.contextTypes, resultType: request.resultType } + : undefined, + caller + }); + } + return response.handler; + } + catch (error) { + this.stopResolverInstance(instanceId); + throw new Error(error); + } + } + async registerIntentResolverMethod() { + const methodName = INTENTS_RESOLVER_INTEROP_PREFIX + Utils.generateId(); + await this.interop.register(methodName, (args, callerId) => this.resolverResponseHandler(args, callerId)); + return methodName; + } + resolverResponseHandler(args, callerId) { + const { instance } = callerId; + const isValid = validateResolverResponse(args); + if (!isValid) { + this.logger.trace(`Intent Resolver instance with id ${callerId.instance} sent invalid response. Error: ${isValid.error}`); + this.intentsResolverResponsePromises[instance].reject(isValid.error); + this.stopResolverInstance(instance); + return; + } + const validResponse = isValid.ok; + this.intentsResolverResponsePromises[instance].resolve(validResponse); + this.cleanUpIntentResolverPromise(instance); + } + buildStartContext(method, request, methodName) { + var _a; + const myAppName = this.interop.instance.application || this.interop.instance.applicationName; + const myAppTitle = ((_a = this.appManager.application(myAppName)) === null || _a === void 0 ? void 0 : _a.title) || ""; + const baseStartContext = { + callerId: this.interop.instance.instance, + methodName, + initialCaller: { id: this.interop.instance.instance, applicationName: myAppName, applicationTitle: myAppTitle }, + resolverApi: "1.0" + }; + return method === "raise" + ? { ...baseStartContext, intent: request } + : { ...baseStartContext, handlerFilter: request }; + } + async buildStartOptions() { + const win = this.windows.my(); + if (!win) { + return; + } + const bounds = await win.getBounds(); + return { + top: await this.getResolverStartupTopBound(bounds), + left: (bounds.width - INTENTS_RESOLVER_WIDTH) / 2 + bounds.left, + width: INTENTS_RESOLVER_WIDTH, + height: INTENTS_RESOLVER_HEIGHT + }; + } + async getResolverStartupTopBound(bounds) { + const myDisplay = await this.windows.my().getDisplay(); + const minWorkareaHeight = myDisplay.workArea.height; + const top = (bounds.height - INTENTS_RESOLVER_HEIGHT) / 2 + bounds.top; + if (top < 0) { + return 0; + } + if (top + INTENTS_RESOLVER_HEIGHT > minWorkareaHeight) { + return minWorkareaHeight / 2; + } + return top; + } + createResponsePromise({ instanceId, intent, responseMethodName, timeout, errorMsg }) { + let resolve = () => { }; + let reject = () => { }; + const promise = PromisePlus((res, rej) => { + resolve = res; + reject = rej; + }, timeout, errorMsg); + this.intentsResolverResponsePromises[instanceId] = { intent, resolve, reject, promise, methodName: responseMethodName }; + } + async invokeStartApp(application, context, options) { + const result = await this.interop.invoke("T42.ACS.StartApplication", { Name: application, options: { ...options, startedByIntentAPI: true } }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return result.returned.Id; + } + subscribeOnInstanceStopped(instance, method) { + const { application } = instance; + const unsub = application.onInstanceStopped((inst) => { + if (inst.id !== instance.id) { + return; + } + const intentPromise = this.intentsResolverResponsePromises[inst.id]; + if (!intentPromise) { + return unsub(); + } + const errorMsg = `Cannot resolve ${method === "raise" ? `raised intent ${intentPromise.intent}` : `'${method}' method`} - User closed ${instance.application.name} app without choosing a handler`; + intentPromise.reject(errorMsg); + this.cleanUpIntentResolverPromise(inst.id); + unsub(); + }); + } + async cleanUpIntentResolverPromise(instanceId) { + const intentPromise = this.intentsResolverResponsePromises[instanceId]; + if (!intentPromise) { + return; + } + const unregisterPromise = this.interop.unregister(intentPromise.methodName); + unregisterPromise.catch((error) => this.logger.warn(error)); + delete this.intentsResolverResponsePromises[instanceId]; + } + handleRaiseOnError(instanceId) { + if (!instanceId) { + return; + } + this.stopResolverInstance(instanceId); + } + stopResolverInstance(instanceId) { + const gdWin = this.windows.findById(instanceId); + gdWin === null || gdWin === void 0 ? void 0 : gdWin.close().catch((err) => this.logger.error(err)); + } + checkIfIntentsResolverIsEnabled(options, appManager) { + var _a, _b, _c, _d, _e; + if (!appManager) { + this.useIntentsResolverUI = false; + return; + } + this.useIntentsResolverUI = typeof ((_a = options.intents) === null || _a === void 0 ? void 0 : _a.enableIntentsResolverUI) === "boolean" + ? options.intents.enableIntentsResolverUI + : true; + this.intentsResolverAppName = (_c = (_b = options.intents) === null || _b === void 0 ? void 0 : _b.intentsResolverAppName) !== null && _c !== void 0 ? _c : INTENTS_RESOLVER_APP_NAME; + this.intentsResolverResponseTimeout = (_e = (_d = options.intents) === null || _d === void 0 ? void 0 : _d.methodResponseTimeoutMs) !== null && _e !== void 0 ? _e : DEFAULT_RESOLVER_RESPONSE_TIMEOUT; + } + async checkIfResolverShouldBeOpenedForRaise(intent, request) { + const checkOpen = this.checkIfIntentsResolverShouldBeOpened(); + if (!checkOpen.open) { + return checkOpen; + } + const hasMoreThanOneHandler = await this.checkIfIntentHasMoreThanOneHandler(intent, request); + if (!hasMoreThanOneHandler) { + return { open: false, reason: `Raised intent ${intent.name} has only one handler` }; + } + return { open: true }; + } + checkIfResolverShouldBeOpenedForFilterHandlers(handlers, filter) { + if (handlers.length === 1) { + return { open: false, reason: `There's only one valid intent handler for filter ${JSON.stringify(filter)}` }; + } + if (typeof (filter === null || filter === void 0 ? void 0 : filter.openResolver) === "boolean" && !filter.openResolver) { + return { open: false, reason: "Intents resolver is disabled by IntentHandler filter" }; + } + return this.checkIfIntentsResolverShouldBeOpened(); + } + checkIfIntentsResolverShouldBeOpened() { + if (!this.useIntentsResolverUI) { + return { open: false, reason: `Intent Resolver is disabled. Resolving to first found handler` }; + } + const intentsResolverApp = this.appManager.application(this.intentsResolverAppName); + if (!intentsResolverApp) { + return { open: false, reason: `Intent Resolver Application with name ${this.intentsResolverAppName} not found.` }; + } + return { open: true }; + } + async checkIfIntentHasMoreThanOneHandler(intent, request) { + const handlers = await this.removeSingletons(request.handlers || intent.handlers); + if (!request.target) { + return handlers.length > 1; + } + if (request.target === "reuse") { + return handlers.filter(handler => handler.type === "instance" && handler.instanceId).length > 1 || intent.handlers.filter(handler => handler.type === "app").length > 1; + } + if (request.target === "startNew") { + return handlers.filter(handler => handler.type === "app").length > 1; + } + if (request.target.instance) { + return false; + } + if (request.target.app) { + const searchedAppName = request.target.app; + const instanceHandlersByAppName = handlers.filter((handler) => handler.applicationName === searchedAppName && handler.instanceId); + return instanceHandlersByAppName.length > 1; + } + return false; + } + async removeSingletons(handlers) { + const handlersWithSingletonProp = await Promise.all(handlers.map(async (handler) => { + if (handler.type === "instance") { + return handler; + } + const appConfig = await this.appManager.application(handler.applicationName).getConfiguration(); + const isSingleton = appConfig.allowMultiple === false; + return { ...handler, isSingleton }; + })); + const filteredSingletonsWithOpenedInstances = handlersWithSingletonProp.filter((handler, _, currentHandlers) => { + if (handler.instanceId || !handler.isSingleton) { + return handler; + } + const openedInstance = currentHandlers.find((h) => h.instanceId && h.applicationName === handler.applicationName); + if (openedInstance) { + return; + } + return handler; + }); + return filteredSingletonsWithOpenedInstances; + } + buildInteropMethodName(intentName) { + return `${GLUE42_FDC3_INTENTS_METHOD_PREFIX}${intentName}`; + } + clearUnregistrationPromise(promiseToRemove) { + this.unregisterIntentPromises = this.unregisterIntentPromises.filter((promise) => promise !== promiseToRemove); + } + unsubscribeIntent(intentName) { + this.myIntents.delete(intentName); + const methodName = this.buildInteropMethodName(intentName); + const unregisterPromise = this.interop.unregister(methodName); + this.unregisterIntentPromises.push(unregisterPromise); + unregisterPromise + .then(() => { + this.clearUnregistrationPromise(unregisterPromise); + }) + .catch((err) => { + this.logger.error(`Unregistration of a method with name ${methodName} failed with reason: `, err); + this.clearUnregistrationPromise(unregisterPromise); + }); + } + findHandlerByFilter(handlers, filter) { + if (filter.type) { + return handlers.find((handler) => handler.type === filter.type); + } + if (filter.instance) { + return handlers.find((handler) => filter.app + ? handler.applicationName === filter.app && handler.instanceId === filter.instance + : handler.instanceId === filter.instance); + } + if (filter.app) { + return handlers.find((handler) => handler.applicationName === filter.app); + } + } + extractIntentsWithInfoByHandler(intents, handler) { + const intentsWithInfo = intents.reduce((validIntentsWithInfo, intent) => { + intent.handlers.forEach((currentHandler) => { + const isValid = Object.keys(handler).every((key) => { + var _a; + return key === "contextTypes" + ? (_a = handler.contextTypes) === null || _a === void 0 ? void 0 : _a.every((contextType) => { var _a; return (_a = currentHandler.contextTypes) === null || _a === void 0 ? void 0 : _a.includes(contextType); }) + : currentHandler[key] === handler[key]; + }); + if (!isValid) { + return; + } + const intentWithInfo = { + intent: intent.name, + contextTypes: currentHandler.contextTypes, + description: currentHandler.applicationDescription, + displayName: currentHandler.displayName, + icon: currentHandler.applicationIcon, + resultType: currentHandler.resultType + }; + validIntentsWithInfo.push(intentWithInfo); + }); + return validIntentsWithInfo; + }, []); + return intentsWithInfo; + } + async removeRememberedHandler(intentName) { + var _a; + this.logger.trace(`Removing saved handler from prefs storage for intent ${intentName}`); + let prefs; + try { + prefs = await this.prefsController.get(); + } + catch (error) { + this.logger.warn(`prefs.get() threw the following error: ${typeof error === "string" ? error : JSON.stringify(error)}`); + return; + } + const intentPrefs = (_a = prefs.data) === null || _a === void 0 ? void 0 : _a.intents; + if (!intentPrefs) { + this.logger.trace("No app prefs found for current app"); + return; + } + delete intentPrefs[intentName]; + const updatedPrefs = { + ...prefs.data, + intents: intentPrefs + }; + try { + await this.prefsController.update(updatedPrefs); + } + catch (error) { + this.logger.warn(`prefs.update() threw the following error: ${typeof error === "string" ? error : JSON.stringify(error)}`); + return; + } + this.logger.trace(`Handler saved choice for intent ${intentName} removed successfully`); + } + async checkForRememberedHandler(intentRequest) { + var _a, _b; + let prefs; + try { + prefs = await this.prefsController.get(); + } + catch (error) { + this.logger.warn(`prefs.get() threw the following error: ${typeof error === "string" ? error : JSON.stringify(error)}`); + return; + } + const prefsForIntent = (_b = (_a = prefs.data) === null || _a === void 0 ? void 0 : _a.intents) === null || _b === void 0 ? void 0 : _b[intentRequest.intent]; + return prefsForIntent === null || prefsForIntent === void 0 ? void 0 : prefsForIntent.handler; + } + async checkHandleRaiseWithRememberedHandler(intentRequest, resolverInstance, timeout) { + if (intentRequest.target) { + return; + } + const rememberedHandler = await this.checkForRememberedHandler(intentRequest); + if (!rememberedHandler) { + return; + } + const request = { + ...intentRequest, + target: { + app: rememberedHandler.applicationName, + instance: rememberedHandler.instanceId + } + }; + try { + const response = await this.coreRaiseIntent({ request, resolverInstance, timeout }); + return response; + } + catch (error) { + this.logger.trace("Could not raise intent to remembered handler. Removing it from Prefs store"); + await this.removeRememberedHandler(intentRequest.intent); + } + } + async saveUserChoice({ intent, handler, filter, caller }) { + var _a, _b; + const prevPrefs = await this.prefsController.get(caller.applicationName); + const prevIntentsPrefs = ((_a = prevPrefs === null || prevPrefs === void 0 ? void 0 : prevPrefs.data) === null || _a === void 0 ? void 0 : _a.intents) || {}; + const prefsToUpdate = { + ...prevPrefs.data, + intents: { + ...prevIntentsPrefs, + [intent]: { handler, filter } + } + }; + await this.prefsController.update(prefsToUpdate, { app: caller.applicationName }); + (_b = this.logger) === null || _b === void 0 ? void 0 : _b.info(`Saved user's choice of handler for '${caller.applicationName}' app`); + } + constructIntentHandler({ apps, intentName, method, server, title }) { + const info = method.flags.intent; + const app = apps.find((appWithIntents) => appWithIntents.name === server.application); + let appIntent; + if (app === null || app === void 0 ? void 0 : app.intents) { + appIntent = app.intents.find((appDefIntent) => appDefIntent.name === intentName); + } + const handler = { + instanceId: server.instance, + applicationName: server.application, + applicationIcon: info.icon || (app === null || app === void 0 ? void 0 : app.icon), + applicationTitle: (app === null || app === void 0 ? void 0 : app.title) || "", + applicationDescription: info.description || (app === null || app === void 0 ? void 0 : app.caption), + displayName: info.displayName || (appIntent === null || appIntent === void 0 ? void 0 : appIntent.displayName), + contextTypes: info.contextTypes || (appIntent === null || appIntent === void 0 ? void 0 : appIntent.contexts), + instanceTitle: title, + type: "instance", + resultType: (appIntent === null || appIntent === void 0 ? void 0 : appIntent.resultType) || info.resultType + }; + return handler; + } + constructIntentHandlerFromApp(app, intent) { + return { + applicationName: app.name, + applicationTitle: app.title || "", + applicationDescription: app.caption, + displayName: intent.displayName, + contextTypes: intent.contexts, + applicationIcon: app.icon, + type: "app", + resultType: intent.resultType + }; + } + } + + class FactoryCallInfo { + constructor() { + this.initialized = false; + this.details = []; + this.reject = () => { }; + this.resolve = () => { }; + } + init(config) { + this.initialized = true; + this.addCall(config); + this.promise = new Promise((resolve, reject) => { + this.resolve = resolve; + this.reject = reject; + }); + } + addCall(config) { + this.details.push({ date: new Date(), config }); + } + done(g) { + this.resolve(g); + } + error(e) { + this.reject(e); + } + } + + class Prefs { + constructor(appName, interop) { + this.appName = appName; + this.interop = interop; + this.registry = CallbackRegistryFactory(); + this.interopMethodRegistered = false; + } + async get(app) { + const data = (await this.interop.invoke(Prefs.T42GetPrefsMethodName, { app: app !== null && app !== void 0 ? app : this.appName }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + })); + return data.returned; + } + async set(data, options) { + var _a; + this.verifyDataObject(data); + await this.interop.invoke(Prefs.T42SetPrefsMethodName, { app: (_a = options === null || options === void 0 ? void 0 : options.app) !== null && _a !== void 0 ? _a : this.appName, data, merge: false }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async setFor(app, data) { + this.verifyApp(app); + this.verifyDataObject(data); + return this.set(data, { app }); + } + async update(data, options) { + var _a; + this.verifyDataObject(data); + await this.interop.invoke(Prefs.T42SetPrefsMethodName, { app: (_a = options === null || options === void 0 ? void 0 : options.app) !== null && _a !== void 0 ? _a : this.appName, data, merge: true }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async updateFor(app, data) { + this.verifyApp(app); + this.verifyDataObject(data); + return this.update(data, { app }); + } + async clear(app) { + await this.interop.invoke(Prefs.T42SetPrefsMethodName, { app: app !== null && app !== void 0 ? app : this.appName, clear: true }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async clearFor(app) { + this.verifyApp(app); + await this.interop.invoke(Prefs.T42SetPrefsMethodName, { app, clear: true }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + async getAll() { + const data = (await this.interop.invoke(Prefs.T42GetPrefsMethodName, undefined, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + })); + return data.returned; + } + async clearAll() { + await this.interop.invoke(Prefs.T42SetPrefsMethodName, { clear: true }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + } + subscribe(callback) { + this.verifyCallback(callback); + return this.subscribeFor(this.appName, callback); + } + subscribeFor(app, callback) { + this.verifyApp(app); + this.verifyCallback(callback); + const unsubscribeFn = this.registry.add(app, callback); + this.registerInteropIfNeeded() + .then(() => { + this.interop.invoke(Prefs.T42GetPrefsMethodName, { app, subscribe: true }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + }); + return () => { + unsubscribeFn(); + }; + } + async registerInteropIfNeeded() { + if (this.interopMethodRegistered) { + return; + } + this.interopMethodRegistered = true; + await this.interop.register(Prefs.T42UpdatePrefsMethodName, (args) => { + this.registry.execute(args.app, args); + }); + } + verifyApp(app) { + if (!app) { + throw new Error(`app should be defined`); + } + if (!isString(app)) { + throw new Error(`app should be a string`); + } + } + verifyDataObject(data) { + if (!data) { + throw new Error(`data should be defined`); + } + if (!isObject(data)) { + throw new Error(`data should be an object`); + } + } + verifyCallback(callback) { + if (!isFunction(callback)) { + throw new Error(`callback should be defined`); + } + } + } + Prefs.T42UpdatePrefsMethodName = "T42.Prefs.Update"; + Prefs.T42GetPrefsMethodName = "T42.Prefs.Get"; + Prefs.T42SetPrefsMethodName = "T42.Prefs.Set"; + + class Cookies { + constructor(methodName, interop) { + this.methodName = methodName; + this.interop = interop; + } + async get(filter) { + const result = await this.invoke("get-cookies", { filter }); + return result.returned.cookies; + } + async set(cookie) { + this.verifyCookieObject(cookie); + await this.invoke("set-cookie", cookie); + } + async remove(url, name) { + if (!isString(url)) { + throw new Error(`url should be a string`); + } + if (!isString(name)) { + throw new Error(`name should be a string`); + } + await this.invoke("remove-cookie", { url, name }); + } + invoke(command, data) { + return this.interop.invoke(this.methodName, { command, args: data }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_RESPONSE_TIMEOUT_MS, + }); + } + verifyCookieObject(cookie) { + if (!cookie) { + throw new Error(`cookie should be defined`); + } + if (!isObject(cookie)) { + throw new Error(`cookie should be an object`); + } + if (Utils.isNullOrUndefined(cookie.url) || !isString(cookie.url)) { + throw new Error(`cookie.url should be a string`); + } + if (Utils.isNullOrUndefined(cookie.name) || !isString(cookie.name)) { + throw new Error(`cookie.name should be a string`); + } + if (!Utils.isNullOrUndefined(cookie.value) && !isString(cookie.value)) { + throw new Error(`cookie.value should be a string`); + } + if (!Utils.isNullOrUndefined(cookie.domain) && !isString(cookie.domain)) { + throw new Error(`cookie.domain should be a string`); + } + if (!Utils.isNullOrUndefined(cookie.path) && !isString(cookie.path)) { + throw new Error(`cookie.path should be a string`); + } + if (!Utils.isNullOrUndefined(cookie.secure) && typeof cookie.secure !== "boolean") { + throw new Error(`cookie.secure should be a boolean`); + } + if (!Utils.isNullOrUndefined(cookie.httpOnly) && typeof cookie.httpOnly !== "boolean") { + throw new Error(`cookie.httpOnly should be a boolean`); + } + if (!Utils.isNullOrUndefined(cookie.expirationDate) && typeof cookie.expirationDate !== "number") { + throw new Error(`cookie.expirationDate should be a number`); + } + } + } + + function factory$1(agm, methodName) { + const cookies = new Cookies(methodName, agm); + return { + get: cookies.get.bind(cookies), + remove: cookies.remove.bind(cookies), + set: cookies.set.bind(cookies), + ready: () => Promise.resolve() + }; + } + + class EventsDispatcher { + constructor(config) { + this.config = config; + this.glue42EventName = "Glue42"; + this.events = { + notifyStarted: { name: "notifyStarted", handle: this.handleNotifyStarted.bind(this) }, + requestGlue: { name: "requestGlue", handle: this.handleRequestGlue.bind(this) } + }; + } + start(glue) { + if (Utils.isNode()) { + return; + } + this.glue = glue; + this.wireCustomEventListener(); + this.announceStarted(); + } + wireCustomEventListener() { + window.addEventListener(this.glue42EventName, (event) => { + const data = event.detail; + if (!data || !data.glue42) { + return; + } + const glue42Event = data.glue42.event; + const foundHandler = this.events[glue42Event]; + if (!foundHandler) { + return; + } + foundHandler.handle(data.glue42.message); + }); + } + announceStarted() { + this.send("start"); + } + handleRequestGlue() { + if (!this.config.exposeAPI) { + this.send("requestGlueResponse", { error: "Will not give access to the underlying Glue API, because it was explicitly denied upon initialization." }); + return; + } + this.send("requestGlueResponse", { glue: this.glue }); + } + handleNotifyStarted() { + this.announceStarted(); + } + send(eventName, message) { + const payload = { glue42: { event: eventName, message } }; + const event = new CustomEvent(this.glue42EventName, { detail: payload }); + window.dispatchEvent(event); + } + } + + class PromiseWrapper { + static delay(time) { + return new Promise((resolve) => setTimeout(resolve, time)); + } + static async delayForever() { + const biggestPossibleDelay = 2147483647; + while (true) { + await this.delay(biggestPossibleDelay); + } + } + get ended() { + return this.rejected || this.resolved; + } + constructor() { + this.promise = new Promise((resolve, reject) => { + this.resolve = (t) => { + this.resolved = true; + resolve(t); + }; + this.reject = (err) => { + this.rejected = true; + reject(err); + }; + }); + } + } + + class Interception { + constructor() { + this.InterceptorMethodName = "T42.GD.Interception.Execute"; + this.InterceptorHandlerMethodName = "T42.GD.Interception.Handler"; + this.interceptions = []; + } + init(interop) { + this.interop = interop; + } + async register(request) { + if (!request || typeof request !== "object" || Array.isArray(request)) { + throw new Error(`Please provide a valid object.`); + } + const handler = request.handler; + if (typeof handler !== "function") { + throw new Error("Please provide a valid handler function."); + } + const interceptions = request.interceptions; + this.validateInterceptions(interceptions); + this.interceptions.push(request); + try { + await this.interop.invoke(this.InterceptorMethodName, { + command: "register", + interceptions + }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + await this.registerMethodIfNotRegistered(); + } + catch (error) { + this.interceptions = this.interceptions.filter((i) => i !== request); + const message = error.message || "Unknown error"; + const newError = new Error(`Failed to register interception: ${message}`); + throw newError; + } + } + async unregister(request) { + if (!request || typeof request !== "object" || Array.isArray(request)) { + throw new Error(`Please provide a valid object.`); + } + const interceptions = request.interceptions; + this.validateInterceptions(interceptions); + try { + await this.interop.invoke(this.InterceptorMethodName, { + command: "unregister", + interceptions + }, "best", { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + this.interceptions = this.interceptions.filter((config) => { + return !interceptions.some((interception) => { + return config.interceptions.some((i) => { + return i.domain === interception.domain && i.operation === interception.operation; + }); + }); + }); + } + catch (error) { + const message = error.message || "Unknown error"; + const newError = new Error(`Failed to unregister interception: ${message}`); + throw newError; + } + } + async handleInterception(domain, operation, operationArgs, phase) { + if (this.interop.methods(this.InterceptorMethodName).length === 0) { + return {}; + } + const result = await this.interop.invoke(this.InterceptorMethodName, { + command: "raiseInterception", + interceptions: [{ + operationArgs, + domain, + operation, + phase + }] + }, 'best', { + waitTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS, + methodResponseTimeoutMs: INTEROP_METHOD_WAIT_TIMEOUT_MS + }); + return result.returned; + } + static createProxyObject(apiToIntercept, domain, interception) { + const methods = Interception.OperationsPerDomain[domain] || []; + const handler = { + get(target, propertyKey, receiver) { + const property = Reflect.get(target, propertyKey, receiver); + try { + if (typeof property !== "function") { + return property; + } + const shouldIntercept = methods.includes(propertyKey); + const isAwaitable = Utils.isPromise(property) || Utils.isAsyncFunction(property); + if (!shouldIntercept || !isAwaitable) { + return property; + } + return Interception.interceptMethod(property, propertyKey, target, domain, interception); + } + catch (error) { + return property; + } + } + }; + const proxyAPI = new Proxy(apiToIntercept, handler); + return proxyAPI; + } + static interceptMethod(originalMethod, propertyKey, target, domain, interception) { + return async function (...args) { + const beforeInterceptionResult = await interception.handleInterception(domain, propertyKey, args, "before"); + if (!Utils.isNullOrUndefined(beforeInterceptionResult.operationResult)) { + return beforeInterceptionResult.operationResult; + } + if (!Utils.isNullOrUndefined(beforeInterceptionResult.operationArgs)) { + args = beforeInterceptionResult.operationArgs; + } + const methodResult = await originalMethod.apply(target, args); + const afterInterceptionResult = await interception.handleInterception(domain, propertyKey, [methodResult], "after"); + if (!Utils.isNullOrUndefined(afterInterceptionResult.operationResult)) { + return afterInterceptionResult.operationResult; + } + return methodResult; + }; + } + toAPI() { + return { + register: this.register.bind(this), + unregister: this.unregister.bind(this), + }; + } + async registerMethodIfNotRegistered() { + var _a; + if ((_a = this.whenRegisteredPromise) === null || _a === void 0 ? void 0 : _a.ended) { + return; + } + this.whenRegisteredPromise = new PromiseWrapper(); + this.registerMethod(); + } + async registerMethod() { + await this.interop.register(this.InterceptorHandlerMethodName, async (data) => { + const command = data.command; + if (command === "raiseInterception") { + const raisedInterception = data.interception; + const interceptor = this.interceptions.find((config) => { + return config.interceptions.some((interception) => { + return interception.domain === raisedInterception.domain && interception.operation === raisedInterception.operation; + }); + }); + const result = await interceptor.handler(raisedInterception); + return result; + } + }); + this.whenRegisteredPromise.resolve(); + } + validateInterceptions(interceptions) { + if (!Array.isArray(interceptions)) { + throw new Error("Please provide a valid array of interceptions."); + } + if (interceptions.length === 0) { + throw new Error("Please provide at least one interception."); + } + for (const interception of interceptions) { + if (typeof interception === "undefined" || interception === null || typeof interception !== "object" || Array.isArray(interception)) { + throw new Error("Please provide a valid interception object."); + } + if (typeof interception.domain !== "string" || !interception.domain) { + throw new Error("Please provide a valid domain string."); + } + if (typeof interception.operation !== "string" || !interception.operation) { + throw new Error("Please provide a valid operation string."); + } + this.validateTypeString(interception); + } + } + validateTypeString(interception) { + if (!isUndefinedOrNull(interception.phase)) { + const isValidType = ["all", "before", "after"].includes(interception.phase); + if (typeof interception.phase !== "string" || !isValidType) { + throw new Error("Please provide a valid phase string."); + } + } + } + } + Interception.OperationsPerDomain = { + "intents": ["raise"] + }; + + const callInfo = new FactoryCallInfo(); + const factory = async (options) => { + let firstRun = false; + if (!callInfo.initialized) { + firstRun = true; + callInfo.init(options); + } + const glue42gd = typeof window !== "undefined" && window.glue42gd; + if (glue42gd) { + if (!firstRun) { + callInfo.addCall(options); + return callInfo.promise; + } + } + const g = await factoryCore(options, glue42gd); + callInfo.resolve(g); + return g; + }; + const factoryCore = async (options, glue42gd) => { + const T42GDExecuteMethod = "T42.GD.Execute"; + const gdMajorVersion = Utils.getGDMajorVersion(); + options = options || {}; + const glueConfig = prepareConfig(options); + options.gateway = options.gateway || {}; + let _appManager; + let _activity; + let _windows; + let _displays; + let _channels; + let _prefs; + const _interceptors = new Interception(); + const _browserEventsDispatcher = new EventsDispatcher(glueConfig); + function createWindows(core) { + if (glueConfig.windows) { + const windowsLogger = getLibLogger("windows", core.logger, glueConfig.windows); + _windows = WindowsFactory(core.agm, windowsLogger, () => { + return _appManager; + }, () => { + return _displays; + }, () => { + return _channels; + }, gdMajorVersion); + debugLog(_windows); + return _windows; + } + } + function createActivities(core) { + var _a; + if (glueConfig.activities) { + if (ActivityModule.checkIsUsingGW3Implementation && ActivityModule.checkIsUsingGW3Implementation(core.connection)) { + const activityLogger = getLibLogger("activity", core.logger, glueConfig.activities); + _activity = new ActivityModule({ + connection: core.connection, + contexts: core.contexts, + agm: core.agm, + logger: activityLogger, + logLevel: "info", + disableAutoAnnounce: false, + disposeRequestHandling: "exit", + announcementInfo: null, + windows: _windows, + appManagerGetter: () => { + return _appManager; + }, + mode: glueConfig.activities.mode, + typesToTrack: glueConfig.activities.typesToTrack, + activityId: (_a = glue42gd === null || glue42gd === void 0 ? void 0 : glue42gd.activityInfo) === null || _a === void 0 ? void 0 : _a.activityId, + gdMajorVersion + }).api; + debugLog(_activity); + return _activity; + } + } + } + function createAppManager(core) { + if (!glueConfig.appManager) { + return; + } + const logger = getLibLogger("appManager", core.logger, glueConfig.appManager); + _appManager = AppManagerFactory({ + agm: core.agm, + windows: _windows, + logger, + activities: _activity, + mode: glueConfig.appManager.mode, + gdMajorVersion + }); + debugLog(_appManager); + return _appManager; + } + function createLayouts(core) { + var _a; + if (!glueConfig.layouts) { + return; + } + const logger = getLibLogger("layouts", core.logger, glueConfig.layouts); + const layoutsConfig = glueConfig.layouts; + const lay = LayoutsFactory({ + agm: core.agm, + appManager: _appManager, + activityGetter: () => _activity, + logger, + mode: layoutsConfig.mode, + autoSaveWindowContext: (_a = layoutsConfig.autoSaveWindowContext) !== null && _a !== void 0 ? _a : false, + gdMajorVersion + }); + debugLog(lay); + return lay; + } + function createChannels(core) { + if (!glueConfig.channels) { + return; + } + const logger = getLibLogger("channels", core.logger, glueConfig.channels); + if (!core.contexts) { + logger.error("Channels library requires Contexts library to be initialized."); + return; + } + _channels = factory$4({ operationMode: glueConfig.channels.operationMode }, core.contexts, core.agm, () => _windows, () => _appManager, logger); + debugLog(_channels); + return _channels; + } + function createHotkeys(core) { + const hotkeysAPI = factory$3(core.agm); + debugLog(hotkeysAPI); + return hotkeysAPI; + } + function createIntents(core) { + const domain = "intents"; + const intents = new Intents(core.agm, _windows, core.logger.subLogger(domain), options, _prefs, _appManager); + const intentsAPI = intents.toAPI(); + const proxyIntentsAPI = Interception.createProxyObject(intentsAPI, domain, _interceptors); + debugLog(proxyIntentsAPI); + return proxyIntentsAPI; + } + function createNotifications(core) { + const notificationsAPI = new Notifications(core.interop, core.logger).toAPI(); + debugLog(notificationsAPI); + return notificationsAPI; + } + function createDisplaysApi(core) { + if (glueConfig.displays) { + const displaysLogger = getLibLogger("displays", core.logger, glueConfig.displays); + _displays = new DisplayManager(core.agm, displaysLogger); + debugLog(_displays); + return _displays; + } + } + function createThemes(core) { + if (!core.contexts) { + return; + } + const themesAPI = factory$2(core.contexts, core.interop); + debugLog(themesAPI); + return themesAPI; + } + function createPrefs(core) { + var _a, _b; + const appName = (_b = (_a = options.application) !== null && _a !== void 0 ? _a : glue42gd === null || glue42gd === void 0 ? void 0 : glue42gd.applicationName) !== null && _b !== void 0 ? _b : core.interop.instance.application; + _prefs = new Prefs(appName, core.interop); + debugLog(_prefs); + return _prefs; + } + function createCookies(core) { + const api = factory$1(core.interop, T42GDExecuteMethod); + debugLog(api); + return api; + } + function createInterception(core) { + _interceptors.init(core.interop); + debugLog(_interceptors); + return _interceptors.toAPI(); + } + function getLibLogger(loggerName, logger, config) { + const newLogger = logger.subLogger(loggerName); + if (config && config.logger) { + const loggerConfig = config.logger; + if (loggerConfig.console) { + newLogger.consoleLevel(loggerConfig.console); + } + if (loggerConfig.publish) { + newLogger.publishLevel(loggerConfig.publish); + } + } + return newLogger; + } + const ext = { + libs: [ + { name: "windows", create: createWindows }, + { name: "activities", create: createActivities }, + { name: "appManager", create: createAppManager }, + { name: "layouts", create: createLayouts }, + { name: "channels", create: createChannels }, + { name: "hotkeys", create: createHotkeys }, + { name: "displays", create: createDisplaysApi }, + { name: "prefs", create: createPrefs }, + { name: "intents", create: createIntents }, + { name: "notifications", create: createNotifications }, + { name: "themes", create: createThemes }, + { name: "cookies", create: createCookies }, + { name: "interception", create: createInterception } + ], + version, + enrichGlue: (glue) => { + glue.config.activities = glueConfig.activities; + glue.config.windows = glueConfig.windows; + glue.config.appManager = glueConfig.appManager; + glue.config.layouts = glueConfig.layouts; + glue.config.channels = glueConfig.channels; + glue.config.displays = glueConfig.displays; + }, + }; + const currentLog = []; + if (typeof window !== "undefined") { + if (!window.glueFactoryLog) { + window.glueFactoryLog = []; + } + window.glueFactoryLog.push(currentLog); + } + function debugLog(entry) { + currentLog.push(entry); + } + const glueApi = (await IOConnectCoreFactory(options, ext)); + if (Array.isArray(options === null || options === void 0 ? void 0 : options.libraries) && options.libraries.length) { + await Promise.all(options.libraries.map((lib) => lib(glueApi, options))); + } + _browserEventsDispatcher.start(glueApi); + return glueApi; + }; + factory.coreVersion = IOConnectCoreFactory.version; + factory.version = version; + factory.calls = callInfo; + + var _a, _b; + let whatToExpose = factory; + let shouldSetToWindow = true; + if (typeof window !== "undefined") { + const windowAsAny = window; + const iodesktop = (_a = windowAsAny.iodesktop) !== null && _a !== void 0 ? _a : windowAsAny.glue42gd; + if (iodesktop && iodesktop.autoInjected) { + whatToExpose = (_b = windowAsAny.IODesktop) !== null && _b !== void 0 ? _b : windowAsAny.Glue; + shouldSetToWindow = false; + } + if (shouldSetToWindow) { + windowAsAny.Glue = whatToExpose; + windowAsAny.IODesktop = whatToExpose; + } + delete windowAsAny.IOBrowser; + delete windowAsAny.GlueCore; + } + whatToExpose.default = whatToExpose; + var whatToExpose$1 = whatToExpose; + + return whatToExpose$1; + +})); +//# sourceMappingURL=desktop.umd.js.map diff --git a/typescript/start/stocks/src/lib/io.applications.css b/typescript/start/stocks/src/lib/io.applications.css new file mode 100644 index 0000000..98e5910 --- /dev/null +++ b/typescript/start/stocks/src/lib/io.applications.css @@ -0,0 +1,12 @@ +:root{--bs-blue: #007be5;--bs-indigo: #6610f2;--bs-purple: #6f42c1;--bs-pink: #fd397a;--bs-red: #ff511f;--bs-orange: #fd7e14;--bs-yellow: #f9a825;--bs-green: #43a047;--bs-teal: #616161;--bs-cyan: #469eb9;--bs-white: #fff;--bs-gray: #6c757d;--bs-gray-dark: #343a40;--bs-gray-100: #f8f9fa;--bs-gray-200: #e9ecef;--bs-gray-300: #dee2e6;--bs-gray-400: #ced4da;--bs-gray-500: #adb5bd;--bs-gray-600: #6c757d;--bs-gray-700: #495057;--bs-gray-800: #343a40;--bs-gray-900: #212529;--bs-primary: #007be5;--bs-secondary: #616161;--bs-success: #43a047;--bs-info: #469eb9;--bs-warning: #f9a825;--bs-danger: #ff511f;--bs-light: #616161;--bs-dark: #616161;--bs-primary-rgb: 0,123,229;--bs-secondary-rgb: 97,97,97;--bs-success-rgb: 67,160,71;--bs-info-rgb: 70,158,185;--bs-warning-rgb: 249,168,37;--bs-danger-rgb: 255,81,31;--bs-light-rgb: 97,97,97;--bs-dark-rgb: 97,97,97;--bs-white-rgb: 255,255,255;--bs-black-rgb: 0,0,0;--bs-body-color-rgb: 33,37,41;--bs-body-bg-rgb: 255,255,255;--bs-font-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--bs-gradient: linear-gradient(180deg, rgba(255,255,255,0.15), rgba(255,255,255,0));--bs-body-font-family: Montserrat,Helvetica Neue,Arial,sans-serif;--bs-body-font-size: .75rem;--bs-body-font-weight: 400;--bs-body-line-height: 1.5;--bs-body-color: #212529;--bs-body-bg: #fff}:root{--t42-font-family: "Montserrat", "Helvetica Neue", Arial, sans-serif;--t42-font-size: 0.75rem;--bs-gutter-x: 0.938rem;--primary: #007be5;--secondary: #616161;--success: #43a047;--info: #616161;--warning: #f9a825;--danger: #ff511f;--light: #616161;--dark: #616161;--white: #ffffff}.dark{--t42-bg-light-base: 0, 0%;--t42-bg-light-l: 18%;--t42-bg-light: 45, 45, 45;--t42-bg-mid: 37, 37, 37;--t42-bg-dark: 30, 30, 30;--t42-content-color-base: 0, 0%;--t42-content-color: #bababa;--t42-content-color-l: 73%;--t42-content-color-muted: hsl(var(--t42-content-color-base), 63%);--t42-content-color-disabled: hsl(var(--t42-content-color-base), 43%);--t42-color-opacity-025: hsla(var(--t42-content-color-base), 100%, 0.025);--t42-color-opacity-05: hsla(var(--t42-content-color-base), 100%, 0.05);--t42-color-opacity-10: hsla(var(--t42-content-color-base), 100%, 0.1);--t42-color-opacity-20: hsla(var(--t42-content-color-base), 100%, 0.2);--t42-color-opacity-30: hsla(var(--t42-content-color-base), 100%, 0.3);--t42-link-color: hsl(var(--t42-content-color-base), 100%);--t42-shadow: 0 0 12px 0 hsla(var(--t42-content-color-base), 0%, 0.15);--t42-border: 0.0625rem solid var(--t42-color-opacity-10);--t42-logo-icon: url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 xmlns:xlink=%27http://www.w3.org/1999/xlink%27 x=%270px%27 y=%270px%27 viewBox=%270 0 100.2 121%27 style=%27enable-background:new 0 0 100.2 121;%27%3E%3Cpath fill=%27%233A77BC%27 d=%27M59.4,10.6l-8.3,8.3c-0.5,0.5-1.4,0.5-1.9,0l-8.3-8.3c-0.5-0.5-0.5-1.4,0-1.9l8.3-8.3c0.5-0.5,1.4-0.5,1.9,0 l8.3,8.3C59.9,9.2,59.9,10.1,59.4,10.6z M59.3,110.4l-8.3-8.3c-0.5-0.5-1.4-0.5-1.9,0l-8.3,8.3c-0.5,0.5-0.5,1.4,0,1.9l8.3,8.3 c0.5,0.5,1.4,0.5,1.9,0l8.3-8.3C59.9,111.8,59.9,110.9,59.3,110.4z%27/%3E%3Cpath fill=%27%23FFFFFF%27 d=%27M100.1,60.1c0.3,7.3-2.9,14.3-9.3,20.6l-24.7,24.7c-0.6,0.6-1.5,0.6-2.1,0l-8.1-8.1c-0.6-0.6-0.6-1.5,0-2.1 l24.7-24.7c0.1-0.1,0.2-0.2,0.3-0.3c3.2-3.3,4.7-6.7,4.4-10.2c0-0.4-0.1-0.8-0.2-1.3c-0.6-3.3-2.8-7-6.8-11l-9.9-9.9 c-0.3-0.3-0.7-0.5-1.1-0.5c-0.4,0-0.8,0.2-1.3,0.6L34.5,69.6c-0.6,0.6-1.5,0.6-2.1,0L27.7,65c-3.3-3.3-3.8-5.1-1.3-7.6 c11.1-11.2,22-22.1,33.2-33.2c2.7-2.7,5.1-4.2,7.5-4.3c2.5-0.1,4.7,1.2,6.9,3.5l14.3,14.3C95.9,45.3,99.8,52.8,100.1,60.1 L100.1,60.1z M0,60.9c0.3,7.3,3.7,14.3,11.2,21.9l14.8,14.8c2.3,2.3,4.5,3.6,6.9,3.5c2.4-0.1,4.8-1.6,7.5-4.3 c11.1-11.1,22.1-22,33.2-33.2c2.5-2.5,2-4.3-1.3-7.6l-4.7-4.7c-0.6-0.6-1.5-0.6-2.1,0L34,83c-0.5,0.5-0.9,0.6-1.3,0.6 c-0.4,0-0.7-0.1-1.1-0.5L21.3,72.7c-4-4-5.7-7.2-6.3-10.5c-0.1-0.4-0.1-0.8-0.2-1.3c-0.3-3.5,1.2-6.9,4.4-10.2 c0.1-0.1,0.2-0.2,0.3-0.3l24.7-24.7c0.6-0.6,0.6-1.5,0-2.1l-8.1-8.1c-0.6-0.6-1.5-0.6-2.1,0L9.3,40.3C2.9,46.6-0.3,53.5,0,60.9 L0,60.9z%27/%3E%3C/svg%3E%0A");--t42-icon-color: var(--t42-link-color);--t42-list-group-hover-bg-special: hsla(var(--t42-content-color-base), 100%, 0.065);--backdrop-filter: blur(5px) saturate(200%);--accordion-filter: invert(1) brightness(1);--filter-close: invert(1);--t42-body: rgb(var(--t42-bg-dark));--pink: rgb(0 170 200);--t42-link-hover-color: hsl(var(--t42-bg-light-base), 100%);--t42-link-hover-bg: var(--t42-color-opacity-05);--t42-link-active-bg: var(--t42-color-opacity-10);--t42-input-bg: rgb(var(--t42-bg-dark));--t42-input-disabled-bg: Hsla(var(--t42-content-color-base), 100%, 0.075);--t42-tooltip-bg: rgba(var(--t42-bg-dark), 0.85);--t42-modal-bg: rgba(var(--t42-bg-light), 0.75);--t42-table-active-bg: rgba(255, 255, 255, 0.1);--t42-select-indicator: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9IiNFRUVFRUUiIHZpZXdCb3g9IjAgMCAxNiAxNiI+PHBhdGggZD0iTTIuNSA1LjVjLjQtLjQgMS0uNSAxLjYgMGwzLjkgMy43bDMuOS0zLjdjLjUtLjUgMS4xLS40IDEuNiAwYy40LjQuNCAxLjIgMCAxLjZjLS40LjQtNC43IDQuNS00LjcgNC41Yy0uMi4yLS41LjMtLjguM3MtLjYtLjEtLjgtLjNjMCAwLTQuMy00LjEtNC43LTQuNXMtLjQtMS4yIDAtMS42eiI+PC9wYXRoPjwvc3ZnPg==)}.light{--t42-bg-light-base: 0, 0%;--t42-bg-light-l: 100%;--t42-bg-light: 255, 255, 255;--t42-bg-mid: 250, 250, 250;--t42-bg-dark: 245, 245, 245;--t42-content-color-base: 0, 0%;--t42-content-color: #757575;--t42-content-color-l: 46%;--t42-content-color-muted: hsl(var(--t42-content-color-base), 66%);--t42-color-opacity-025: hsla(var(--t42-content-color-base), 0%, 0.025);--t42-color-opacity-05: hsla(var(--t42-content-color-base), 0%, 0.05);--t42-color-opacity-10: hsla(var(--t42-content-color-base), 0%, 0.075);--t42-color-opacity-30: hsla(var(--t42-content-color-base), 0%, 0.1);--t42-color-opacity-20: hsla(var(--t42-content-color-base), 0%, 0.2);--t42-link-color: hsl(var(--t42-content-color-base), 5%);--t42-shadow: 0 0 12px 0 hsla(var(--t42-content-color-base), 0%, 0.05);--t42-border: 0.0625rem solid var(--t42-color-opacity-10);--t42-logo-icon: url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 xmlns:xlink=%27http://www.w3.org/1999/xlink%27 x=%270px%27 y=%270px%27 viewBox=%270 0 100.2 121%27 style=%27enable-background:new 0 0 100.2 121;%27%3E%3Cpath fill=%27%233A77BC%27 d=%27M59.4,10.6l-8.3,8.3c-0.5,0.5-1.4,0.5-1.9,0l-8.3-8.3c-0.5-0.5-0.5-1.4,0-1.9l8.3-8.3c0.5-0.5,1.4-0.5,1.9,0 l8.3,8.3C59.9,9.2,59.9,10.1,59.4,10.6z M59.3,110.4l-8.3-8.3c-0.5-0.5-1.4-0.5-1.9,0l-8.3,8.3c-0.5,0.5-0.5,1.4,0,1.9l8.3,8.3 c0.5,0.5,1.4,0.5,1.9,0l8.3-8.3C59.9,111.8,59.9,110.9,59.3,110.4z%27/%3E%3Cpath fill=%27%23083044%27 d=%27M100.1,60.1c0.3,7.3-2.9,14.3-9.3,20.6l-24.7,24.7c-0.6,0.6-1.5,0.6-2.1,0l-8.1-8.1c-0.6-0.6-0.6-1.5,0-2.1 l24.7-24.7c0.1-0.1,0.2-0.2,0.3-0.3c3.2-3.3,4.7-6.7,4.4-10.2c0-0.4-0.1-0.8-0.2-1.3c-0.6-3.3-2.8-7-6.8-11l-9.9-9.9 c-0.3-0.3-0.7-0.5-1.1-0.5c-0.4,0-0.8,0.2-1.3,0.6L34.5,69.6c-0.6,0.6-1.5,0.6-2.1,0L27.7,65c-3.3-3.3-3.8-5.1-1.3-7.6 c11.1-11.2,22-22.1,33.2-33.2c2.7-2.7,5.1-4.2,7.5-4.3c2.5-0.1,4.7,1.2,6.9,3.5l14.3,14.3C95.9,45.3,99.8,52.8,100.1,60.1 L100.1,60.1z M0,60.9c0.3,7.3,3.7,14.3,11.2,21.9l14.8,14.8c2.3,2.3,4.5,3.6,6.9,3.5c2.4-0.1,4.8-1.6,7.5-4.3 c11.1-11.1,22.1-22,33.2-33.2c2.5-2.5,2-4.3-1.3-7.6l-4.7-4.7c-0.6-0.6-1.5-0.6-2.1,0L34,83c-0.5,0.5-0.9,0.6-1.3,0.6 c-0.4,0-0.7-0.1-1.1-0.5L21.3,72.7c-4-4-5.7-7.2-6.3-10.5c-0.1-0.4-0.1-0.8-0.2-1.3c-0.3-3.5,1.2-6.9,4.4-10.2 c0.1-0.1,0.2-0.2,0.3-0.3l24.7-24.7c0.6-0.6,0.6-1.5,0-2.1l-8.1-8.1c-0.6-0.6-1.5-0.6-2.1,0L9.3,40.3C2.9,46.6-0.3,53.5,0,60.9 L0,60.9z%27/%3E%3C/svg%3E%0A");--t42-icon-color: Hsl(var(--t42-content-color-base), 38%);--t42-list-group-hover-bg-special: hsla(var(--t42-content-color-base), 95%, 0.065);--backdrop-filter: blur(5px) saturate(200%);--accordion-filter: brightness(0%);--filter-close: invert(0);--t42-body: rgb(var(--t42-bg-mid));--t42-link-hover-color: hsl(var(--t42-bg-light-base), 0%);--t42-link-hover-bg: hsl(var(--t42-content-color-base), 95%);--t42-link-active-bg: hsl(var(--t42-content-color-base), 90%);--t42-input-bg: rgb(var(--t42-bg-light));--t42-input-disabled-bg: var(--t42-color-opacity-10);--t42-tooltip-bg: rgba(var(--t42-bg-light), 0.95);--t42-modal-bg: rgba(var(--t42-bg-light), 0.95);--t42-table-active-bg: rgba(0, 0, 0, 0.025);--t42-select-indicator: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9IiM2MTYxNjEiIHZpZXdCb3g9IjAgMCAxNiAxNiI+PHBhdGggZD0iTTIuNSA1LjVjLjQtLjQgMS0uNSAxLjYgMGwzLjkgMy43bDMuOS0zLjdjLjUtLjUgMS4xLS40IDEuNiAwYy40LjQuNCAxLjIgMCAxLjZjLS40LjQtNC43IDQuNS00LjcgNC41Yy0uMi4yLS41LjMtLjguM3MtLjYtLjEtLjgtLjNjMCAwLTQuMy00LjEtNC43LTQuNXMtLjQtMS4yIDAtMS42eiI+PC9wYXRoPjwvc3ZnPg==)}*,*::before,*::after{box-sizing:border-box}@media (prefers-reduced-motion: no-preference){:root{scroll-behavior:smooth}}body{margin:0;font-family:var(--bs-body-font-family);font-size:var(--bs-body-font-size);font-weight:var(--bs-body-font-weight);line-height:var(--bs-body-line-height);color:var(--bs-body-color);text-align:var(--bs-body-text-align);background-color:var(--bs-body-bg);-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:rgba(0,0,0,0)}hr{margin:1rem 0;color:inherit;background-color:currentColor;border:0;opacity:.25}hr:not([size]){height:1px}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem;font-weight:500;line-height:1.2;color:var(--t42-link-color)}h1{font-size:calc(1.26563rem + .1875vw)}@media (min-width: 1200px){h1{font-size:1.40625rem}}h2{font-size:1.125rem}h3{font-size:.98475rem}h4{font-size:.84375rem}h5{font-size:.75rem}h6{font-size:.7035rem}p{margin-top:0;margin-bottom:1rem}abbr[title],abbr[data-bs-original-title]{text-decoration:underline dotted;cursor:help;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}ol,ul{padding-left:2rem}ol,ul,dl{margin-top:0;margin-bottom:1rem}ol ol,ul ul,ol ul,ul ol{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:.875em}mark{padding:0.2rem 0.2rem 0;background-color:#007be5}sub,sup{position:relative;font-size:.75em;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:var(--t42-link-color);text-decoration:underline}a:hover{color:var(--t42-link-hover-color)}a:not([href]):not([class]),a:not([href]):not([class]):hover{color:inherit;text-decoration:none}pre,code,kbd,samp{font-family:var(--bs-font-monospace);font-size:1em;direction:ltr /* rtl:ignore */;unicode-bidi:bidi-override}pre{display:block;margin-top:0;margin-bottom:1rem;overflow:auto;font-size:inherit;color:var(--t42-content-color)}pre code{font-size:inherit;color:inherit;word-break:normal}code{font-size:inherit;color:#469eb9;word-wrap:break-word}a>code{color:inherit}kbd{padding:.2rem .4rem;font-size:inherit;color:#fff;background-color:#212529;border-radius:.25rem}kbd kbd{padding:0;font-size:1em;font-weight:700}figure{margin:0 0 1rem}img,svg{vertical-align:middle}table{caption-side:bottom;border-collapse:collapse}caption{padding-top:.25rem;padding-bottom:.25rem;color:var(--t42-content-color-muted);text-align:left}th{text-align:inherit;text-align:-webkit-match-parent}thead,tbody,tfoot,tr,td,th{border-color:inherit;border-style:solid;border-width:0}label{display:inline-block}button{border-radius:0}button:focus:not(:focus-visible){outline:0}input,button,select,optgroup,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,select{text-transform:none}[role="button"]{cursor:pointer}select{word-wrap:normal}select:disabled{opacity:1}[list]::-webkit-calendar-picker-indicator{display:none}button,[type="button"],[type="reset"],[type="submit"]{-webkit-appearance:button}button:not(:disabled),[type="button"]:not(:disabled),[type="reset"]:not(:disabled),[type="submit"]:not(:disabled){cursor:pointer}::-moz-focus-inner{padding:0;border-style:none}textarea{resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{float:left;width:100%;padding:0;margin-bottom:.5rem;font-size:calc(1.275rem + .3vw);line-height:inherit}@media (min-width: 1200px){legend{font-size:1.5rem}}legend+*{clear:left}::-webkit-datetime-edit-fields-wrapper,::-webkit-datetime-edit-text,::-webkit-datetime-edit-minute,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-year-field{padding:0}::-webkit-inner-spin-button{height:auto}[type="search"]{outline-offset:-2px;-webkit-appearance:textfield}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-color-swatch-wrapper{padding:0}::file-selector-button{font:inherit}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}iframe{border:0}summary{display:list-item;cursor:pointer}progress{vertical-align:baseline}[hidden]{display:none !important}body{color:var(--t42-content-color);font-family:var(--t42-font-family);background-color:var(--t42-body)}a:focus,button:focus,div:focus,span:focus{outline:0}a{text-decoration:none}dt{font-weight:normal}::selection{color:var(--white);background-color:var(--primary)}::-webkit-scrollbar{width:4px;height:4px}::-webkit-scrollbar-track{border-radius:.25rem;background:transparent}::-webkit-scrollbar-thumb{border-radius:.25rem;background:var(--t42-color-opacity-10)}::-webkit-resizer{background:transparent}::-webkit-scrollbar-corner{background:transparent}::-webkit-scrollbar-thumb:window-inactive{background:transparent}::-webkit-scrollbar-thumb:hover,::-webkit-scrollbar-thumb:active{background:Hsla(var(--t42-content-color-base), 100%, 0.05)}.accordion-button{position:relative;display:flex;align-items:center;width:100%;padding:1rem 1.25rem;font-size:.75rem;color:var(--t42-link-color);text-align:left;background-color:Rgb(var(--t42-bg-mid));border:0;border-radius:0;overflow-anchor:none;transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out,border-radius 0.15s ease}@media (prefers-reduced-motion: reduce){.accordion-button{transition:none}}.accordion-button:not(.collapsed){color:var(--t42-link-color);background-color:Rgb(var(--t42-bg-mid));box-shadow:inset 0 -1px 0 var(--t42-color-opacity-10)}.accordion-button:not(.collapsed)::after{background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 16 16%27 fill=%27var%28--t42-link-color%29%27%3e%3cpath fill-rule=%27evenodd%27 d=%27M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z%27/%3e%3c/svg%3e");transform:rotate(-180deg)}.accordion-button::after{flex-shrink:0;width:1.25rem;height:1.25rem;margin-left:auto;content:"";background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 16 16%27 fill=%27var%28--t42-link-color%29%27%3e%3cpath fill-rule=%27evenodd%27 d=%27M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z%27/%3e%3c/svg%3e");background-repeat:no-repeat;background-size:1.25rem;transition:transform 0.2s ease-in-out}@media (prefers-reduced-motion: reduce){.accordion-button::after{transition:none}}.accordion-button:hover{z-index:2}.accordion-button:focus{z-index:3;border-color:#007be5;outline:0;box-shadow:0 0 0 0 rgba(0,123,229,0.25)}.accordion-header{margin-bottom:0}.accordion-item{background-color:Rgb(var(--t42-bg-mid));border:1px solid var(--t42-color-opacity-10)}.accordion-item:first-of-type{border-top-left-radius:0;border-top-right-radius:0}.accordion-item:first-of-type .accordion-button{border-top-left-radius:0;border-top-right-radius:0}.accordion-item:not(:first-of-type){border-top:0}.accordion-item:last-of-type{border-bottom-right-radius:0;border-bottom-left-radius:0}.accordion-item:last-of-type .accordion-button.collapsed{border-bottom-right-radius:0;border-bottom-left-radius:0}.accordion-item:last-of-type .accordion-collapse{border-bottom-right-radius:0;border-bottom-left-radius:0}.accordion-body{padding:1rem 1.25rem}.accordion-flush .accordion-collapse{border-width:0}.accordion-flush .accordion-item{border-right:0;border-left:0;border-radius:0}.accordion-flush .accordion-item:first-child{border-top:0}.accordion-flush .accordion-item:last-child{border-bottom:0}.accordion-flush .accordion-item .accordion-button{border-radius:0}.accordion-button::after,.accordion-button:not(.collapsed)::after{filter:var(--accordion-filter)}.accordion-button:disabled,.accordion-button.disabled{color:var(--t42-content-color-disabled)}.accordion-button:disabled::after,.accordion-button.disabled::after{opacity:0.25}.alert{position:relative;padding:.75rem .875rem;margin-bottom:.5rem;border:1px solid transparent;border-radius:0}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-right:2.625rem}.alert-dismissible .btn-close{position:absolute;top:0;right:0;z-index:2;padding:.9375rem .875rem}.alert-primary{color:#004a89;background-color:#cce5fa;border-color:#b3d7f7}.alert-primary .alert-link{color:#003b6e}.alert-secondary{color:#3a3a3a;background-color:#dfdfdf;border-color:#d0d0d0}.alert-secondary .alert-link{color:#2e2e2e}.alert-success{color:#28602b;background-color:#d9ecda;border-color:#c7e3c8}.alert-success .alert-link{color:#204d22}.alert-info{color:#2a5f6f;background-color:#daecf1;border-color:#c8e2ea}.alert-info .alert-link{color:#224c59}.alert-warning{color:#64430f;background-color:#feeed3;border-color:#fde5be}.alert-warning .alert-link{color:#50360c}.alert-danger{color:#993113;background-color:#ffdcd2;border-color:#ffcbbc}.alert-danger .alert-link{color:#7a270f}.alert-light{color:#3a3a3a;background-color:#dfdfdf;border-color:#d0d0d0}.alert-light .alert-link{color:#2e2e2e}.alert-dark{color:#3a3a3a;background-color:#dfdfdf;border-color:#d0d0d0}.alert-dark .alert-link{color:#2e2e2e}.alert{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border-color;position:relative;z-index:10000;display:flex;align-items:center;border:0.0625rem solid var(--t42-color-opacity-10);overflow:hidden;color:var(--t42-content-color);background-color:Rgba(var(--t42-bg-light), 0.75);background-repeat:no-repeat;background-size:100%;backdrop-filter:var(--backdrop-filter)}.alert h5{margin-bottom:0;color:var(--t42-content-color)}.alert p{margin-bottom:0}.alert-link{color:var(--t42-link-color);font-weight:normal}.alert-dismissible .close{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border-color;position:absolute;top:50%;right:0.75rem;width:1.5rem;height:1.5rem;padding:0;border:0;border-radius:50%;color:var(--t42-content-color);font-weight:700;font-size:1rem;line-height:1;background-color:var(--t42-color-opacity-05);transform:translateY(-50%);opacity:0.5}.alert-dismissible .close::before{position:relative;top:-1px}.alert-dismissible .close:hover{opacity:1}.alert::before{z-index:1;width:1.25rem;height:1.25rem;margin-right:0.875rem;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-position:center;mask-position:center;background-color:var(--t42-icon-color);content:""}.alert::after{position:absolute;top:0;left:0;z-index:-1;width:1px;height:1px;border-radius:50%;opacity:1;animation:color-pulse 3s infinite;content:""}.alert-primary:hover,.alert-secondary:hover,.alert-info:hover,.alert-light:hover,.alert-dark:hover{border-color:#616161}.alert-primary::after,.alert-secondary::after,.alert-info::after,.alert-light::after,.alert-dark::after{background:#616161;background:radial-gradient(circle, rgba(255,255,255,0.35) 0%, rgba(97,97,97,0.75) 60%, #616161 75%, #616161 100%)}.alert-primary::before,.alert-secondary::before,.alert-info::before,.alert-light::before,.alert-dark::before{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M260.6 484.4q0-4.1-4.6-4.1q-16.9 0-29.2-12.3t-11.8-29.2q0-4.6-4.6-4.6t-4.6 4.6q0 21 14.8 35.8t35.3 14.3q4.6 0 4.6-4.6zM493.6 402.4q0 14.8-10.8 25.6t-25.6 10.8h-128q0 30.2-21.5 51.7t-51.7 21.5t-51.7-21.5t-21.5-51.7h-128q-14.8 0-25.6-10.8t-10.8-25.6q14.3-12.3 26.1-25.1t24.1-34.3t21.5-45.6t13.8-58.9t5.6-74.2q0-43 33.8-80.4t87.6-45.6q-2.6-5.1-2.6-10.8q0-11.8 8.2-19.5t19.5-8.2t19.5 8.2t8.2 19.5q0 5.6-2.6 10.8q54.3 8.2 87.6 45.6t33.8 80.4q0 39.9 5.6 74.2t14.3 58.9t21 45.6t24.6 34.3t25.6 25.1z%27%3E%3C/path%3E%3C/svg%3E")}.alert-success:hover{border-color:#43a047}.alert-success::after{background:#43a047;background:radial-gradient(circle, rgba(255,255,255,0.35) 0%, rgba(67,160,71,0.75) 60%, #43a047 75%, #43a047 100%)}.alert-success::before{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M477.4 152.8q0 11.3-8.2 19.5l-245.8 245.8q-8.2 7.7-19.5 7.7t-19.5-7.7l-142.3-142.3q-7.7-8.2-7.7-19.5t7.7-19.5l38.9-38.9q8.2-8.2 19.5-8.2t19.5 8.2l84 84.5l187.4-187.9q8.2-8.2 19.5-8.2t19.5 8.2l38.9 38.9q8.2 7.7 8.2 19.5z%27%3E%3C/path%3E%3C/svg%3E")}.alert-warning:hover{border-color:#f9a825}.alert-warning::after{background:#f9a825;background:radial-gradient(circle, rgba(255,255,255,0.35) 0%, rgba(249,168,37,0.75) 60%, #f9a825 75%, #f9a825 100%)}.alert-warning::before{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M292.4 410.9v-54.3q0-4.1-2.6-6.7t-6.1-2.6h-55.3q-3.6 0-6.1 2.6t-2.6 6.7v54.3q0 4.1 2.6 6.7t6.1 3.1h55.3q3.6 0 6.1-3.1t2.6-6.7zM291.8 304.4l5.1-131.6q0-3.1-2.6-5.1q-3.6-3.1-7.2-3.1h-62.5q-3.1 0-7.2 3.1q-2.6 2-2.6 6.1l4.6 130.6q0 2.6 3.1 4.6t6.7 1.5h52.7q4.1 0 7.2-1.5t2.6-4.6zM288.3 37.1l219.1 402.4q10.2 17.9-.5 35.8q-4.6 8.7-13.3 13.3t-17.9 5.1h-439.3q-9.2 0-17.9-5.1t-13.3-13.3q-10.8-17.9-.5-35.8l219.6-402.4q4.6-8.7 13.3-13.8t18.4-5.1t18.4 5.1t13.8 13.8z%27%3E%3C/path%3E%3C/svg%3E%0A")}.alert-danger:hover{border-color:#ff511f}.alert-danger::after{background:#ff511f;background:radial-gradient(circle, rgba(255,255,255,0.35) 0%, rgba(255,81,31,0.75) 60%, #ff511f 75%, #ff511f 100%)}.alert-danger::before{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 402 512%27%3E%3Cpath d=%27M370.728 359.68q0 11.264-7.68 19.456l-38.912 38.912q-8.192 7.68-19.456 7.68t-19.456-7.68l-83.968-84.48-83.968 84.48q-8.192 7.68-19.456 7.68t-19.456-7.68l-38.912-38.912q-8.192-8.192-8.192-19.456t8.192-19.456l83.968-83.968-83.968-83.968q-8.192-8.192-8.192-19.456t8.192-19.456l38.912-38.912q8.192-8.192 19.456-8.192t19.456 8.192l83.968 83.968 83.968-83.968q8.192-8.192 19.456-8.192t19.456 8.192l38.912 38.912q7.68 7.68 7.68 19.456t-7.68 19.456l-83.968 83.968 83.968 83.968q7.68 7.68 7.68 19.456z%27%3E%3C/path%3E%3C/svg%3E")}@keyframes color-pulse{0%{transform:scale(1);opacity:1}50%{transform:scale(250);opacity:0}100%{opacity:0}}.badge{display:inline-block;padding:.2rem .5rem;font-size:.75em;font-weight:300;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:1rem}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.badge{border:var(--t42-border);color:var(--t42-link-color);backdrop-filter:var(--backdrop-filter)}.badge.bg-primary{border:0.0625rem solid #007be5;background-color:rgba(0,123,229,0.15) !important}.badge.bg-secondary{border:0.0625rem solid #616161;background-color:rgba(97,97,97,0.15) !important}.badge.bg-success{border:0.0625rem solid #43a047;background-color:rgba(67,160,71,0.15) !important}.badge.bg-info{border:0.0625rem solid #469eb9;background-color:rgba(70,158,185,0.15) !important}.badge.bg-warning{border:0.0625rem solid #f9a825;background-color:rgba(249,168,37,0.15) !important}.badge.bg-danger{border:0.0625rem solid #ff511f;background-color:rgba(255,81,31,0.15) !important}.badge.bg-light{border:0.0625rem solid #616161;background-color:rgba(97,97,97,0.15) !important}.badge.bg-dark{border:0.0625rem solid #616161;background-color:rgba(97,97,97,0.15) !important}button .badge{border:0.0625rem solid var(--t42-color-opacity-30)}button:hover .badge{color:var(--white)}.btn-close{box-sizing:content-box;width:1em;height:1em;padding:0 0;color:var(--t42-content-color);background:transparent url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 16 16%27 fill=%27var%28--t42-content-color%29%27%3e%3cpath d=%27M.293.293a1 1 0 011.414 0L8 6.586 14.293.293a1 1 0 111.414 1.414L9.414 8l6.293 6.293a1 1 0 01-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 01-1.414-1.414L6.586 8 .293 1.707a1 1 0 010-1.414z%27/%3e%3c/svg%3e") center/1em auto no-repeat;border:0;border-radius:.25rem;opacity:.5}.btn-close:hover{color:var(--t42-content-color);text-decoration:none;opacity:.75}.btn-close:focus{outline:0;box-shadow:0 0 0 0 rgba(0,123,229,0.25);opacity:1}.btn-close:disabled,.btn-close.disabled{pointer-events:none;user-select:none;opacity:.25}.btn-close-white{filter:invert(1) grayscale(100%) brightness(200%)}.btn{display:inline-block;font-weight:400;line-height:1.875rem;color:#212529;text-align:center;text-decoration:none;vertical-align:middle;cursor:pointer;user-select:none;background-color:transparent;border:1px solid transparent;padding:0 .875rem;font-size:.75rem;border-radius:0;transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.btn{transition:none}}.btn:hover{color:#212529}.btn-check:focus+.btn,.btn:focus{outline:0;box-shadow:0 0 0 0 rgba(0,123,229,0.25)}.btn:disabled,.btn.disabled,fieldset:disabled .btn{pointer-events:none;opacity:.35}.btn-primary{color:#000;background-color:#007be5;border-color:#007be5}.btn-primary:hover{color:#000;background-color:#268fe9;border-color:#1a88e8}.btn-check:focus+.btn-primary,.btn-primary:focus{color:#000;background-color:#268fe9;border-color:#1a88e8;box-shadow:0 0 0 0 rgba(0,105,195,0.5)}.btn-check:checked+.btn-primary,.btn-check:active+.btn-primary,.btn-primary:active,.btn-primary.active,.show>.btn-primary.dropdown-toggle{color:#000;background-color:#3395ea;border-color:#1a88e8}.btn-check:checked+.btn-primary:focus,.btn-check:active+.btn-primary:focus,.btn-primary:active:focus,.btn-primary.active:focus,.show>.btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(0,105,195,0.5)}.btn-primary:disabled,.btn-primary.disabled{color:#000;background-color:#007be5;border-color:#007be5}.btn-secondary{color:#fff;background-color:#616161;border-color:#616161}.btn-secondary:hover{color:#fff;background-color:#525252;border-color:#4e4e4e}.btn-check:focus+.btn-secondary,.btn-secondary:focus{color:#fff;background-color:#525252;border-color:#4e4e4e;box-shadow:0 0 0 0 rgba(121,121,121,0.5)}.btn-check:checked+.btn-secondary,.btn-check:active+.btn-secondary,.btn-secondary:active,.btn-secondary.active,.show>.btn-secondary.dropdown-toggle{color:#fff;background-color:#4e4e4e;border-color:#494949}.btn-check:checked+.btn-secondary:focus,.btn-check:active+.btn-secondary:focus,.btn-secondary:active:focus,.btn-secondary.active:focus,.show>.btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(121,121,121,0.5)}.btn-secondary:disabled,.btn-secondary.disabled{color:#fff;background-color:#616161;border-color:#616161}.btn-success{color:#000;background-color:#43a047;border-color:#43a047}.btn-success:hover{color:#000;background-color:#5fae63;border-color:#56aa59}.btn-check:focus+.btn-success,.btn-success:focus{color:#000;background-color:#5fae63;border-color:#56aa59;box-shadow:0 0 0 0 rgba(57,136,60,0.5)}.btn-check:checked+.btn-success,.btn-check:active+.btn-success,.btn-success:active,.btn-success.active,.show>.btn-success.dropdown-toggle{color:#000;background-color:#69b36c;border-color:#56aa59}.btn-check:checked+.btn-success:focus,.btn-check:active+.btn-success:focus,.btn-success:active:focus,.btn-success.active:focus,.show>.btn-success.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(57,136,60,0.5)}.btn-success:disabled,.btn-success.disabled{color:#000;background-color:#43a047;border-color:#43a047}.btn-info{color:#000;background-color:#469eb9;border-color:#469eb9}.btn-info:hover{color:#000;background-color:#62adc4;border-color:#59a8c0}.btn-check:focus+.btn-info,.btn-info:focus{color:#000;background-color:#62adc4;border-color:#59a8c0;box-shadow:0 0 0 0 rgba(60,134,157,0.5)}.btn-check:checked+.btn-info,.btn-check:active+.btn-info,.btn-info:active,.btn-info.active,.show>.btn-info.dropdown-toggle{color:#000;background-color:#6bb1c7;border-color:#59a8c0}.btn-check:checked+.btn-info:focus,.btn-check:active+.btn-info:focus,.btn-info:active:focus,.btn-info.active:focus,.show>.btn-info.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(60,134,157,0.5)}.btn-info:disabled,.btn-info.disabled{color:#000;background-color:#469eb9;border-color:#469eb9}.btn-warning{color:#000;background-color:#f9a825;border-color:#f9a825}.btn-warning:hover{color:#000;background-color:#fab546;border-color:#fab13b}.btn-check:focus+.btn-warning,.btn-warning:focus{color:#000;background-color:#fab546;border-color:#fab13b;box-shadow:0 0 0 0 rgba(212,143,31,0.5)}.btn-check:checked+.btn-warning,.btn-check:active+.btn-warning,.btn-warning:active,.btn-warning.active,.show>.btn-warning.dropdown-toggle{color:#000;background-color:#fab951;border-color:#fab13b}.btn-check:checked+.btn-warning:focus,.btn-check:active+.btn-warning:focus,.btn-warning:active:focus,.btn-warning.active:focus,.show>.btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(212,143,31,0.5)}.btn-warning:disabled,.btn-warning.disabled{color:#000;background-color:#f9a825;border-color:#f9a825}.btn-danger{color:#000;background-color:#ff511f;border-color:#ff511f}.btn-danger:hover{color:#000;background-color:#ff6b41;border-color:#ff6235}.btn-check:focus+.btn-danger,.btn-danger:focus{color:#000;background-color:#ff6b41;border-color:#ff6235;box-shadow:0 0 0 0 rgba(217,69,26,0.5)}.btn-check:checked+.btn-danger,.btn-check:active+.btn-danger,.btn-danger:active,.btn-danger.active,.show>.btn-danger.dropdown-toggle{color:#000;background-color:#ff744c;border-color:#ff6235}.btn-check:checked+.btn-danger:focus,.btn-check:active+.btn-danger:focus,.btn-danger:active:focus,.btn-danger.active:focus,.show>.btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(217,69,26,0.5)}.btn-danger:disabled,.btn-danger.disabled{color:#000;background-color:#ff511f;border-color:#ff511f}.btn-light{color:#fff;background-color:#616161;border-color:#616161}.btn-light:hover{color:#fff;background-color:#525252;border-color:#4e4e4e}.btn-check:focus+.btn-light,.btn-light:focus{color:#fff;background-color:#525252;border-color:#4e4e4e;box-shadow:0 0 0 0 rgba(121,121,121,0.5)}.btn-check:checked+.btn-light,.btn-check:active+.btn-light,.btn-light:active,.btn-light.active,.show>.btn-light.dropdown-toggle{color:#fff;background-color:#4e4e4e;border-color:#494949}.btn-check:checked+.btn-light:focus,.btn-check:active+.btn-light:focus,.btn-light:active:focus,.btn-light.active:focus,.show>.btn-light.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(121,121,121,0.5)}.btn-light:disabled,.btn-light.disabled{color:#fff;background-color:#616161;border-color:#616161}.btn-dark{color:#fff;background-color:#616161;border-color:#616161}.btn-dark:hover{color:#fff;background-color:#525252;border-color:#4e4e4e}.btn-check:focus+.btn-dark,.btn-dark:focus{color:#fff;background-color:#525252;border-color:#4e4e4e;box-shadow:0 0 0 0 rgba(121,121,121,0.5)}.btn-check:checked+.btn-dark,.btn-check:active+.btn-dark,.btn-dark:active,.btn-dark.active,.show>.btn-dark.dropdown-toggle{color:#fff;background-color:#4e4e4e;border-color:#494949}.btn-check:checked+.btn-dark:focus,.btn-check:active+.btn-dark:focus,.btn-dark:active:focus,.btn-dark.active:focus,.show>.btn-dark.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(121,121,121,0.5)}.btn-dark:disabled,.btn-dark.disabled{color:#fff;background-color:#616161;border-color:#616161}.btn-outline-primary{color:#007be5;border-color:#007be5}.btn-outline-primary:hover{color:#000;background-color:#007be5;border-color:#007be5}.btn-check:focus+.btn-outline-primary,.btn-outline-primary:focus{box-shadow:0 0 0 0 rgba(0,123,229,0.5)}.btn-check:checked+.btn-outline-primary,.btn-check:active+.btn-outline-primary,.btn-outline-primary:active,.btn-outline-primary.active,.btn-outline-primary.dropdown-toggle.show{color:#000;background-color:#007be5;border-color:#007be5}.btn-check:checked+.btn-outline-primary:focus,.btn-check:active+.btn-outline-primary:focus,.btn-outline-primary:active:focus,.btn-outline-primary.active:focus,.btn-outline-primary.dropdown-toggle.show:focus{box-shadow:0 0 0 0 rgba(0,123,229,0.5)}.btn-outline-primary:disabled,.btn-outline-primary.disabled{color:#007be5;background-color:transparent}.btn-outline-secondary{color:#616161;border-color:#616161}.btn-outline-secondary:hover{color:#fff;background-color:#616161;border-color:#616161}.btn-check:focus+.btn-outline-secondary,.btn-outline-secondary:focus{box-shadow:0 0 0 0 rgba(97,97,97,0.5)}.btn-check:checked+.btn-outline-secondary,.btn-check:active+.btn-outline-secondary,.btn-outline-secondary:active,.btn-outline-secondary.active,.btn-outline-secondary.dropdown-toggle.show{color:#fff;background-color:#616161;border-color:#616161}.btn-check:checked+.btn-outline-secondary:focus,.btn-check:active+.btn-outline-secondary:focus,.btn-outline-secondary:active:focus,.btn-outline-secondary.active:focus,.btn-outline-secondary.dropdown-toggle.show:focus{box-shadow:0 0 0 0 rgba(97,97,97,0.5)}.btn-outline-secondary:disabled,.btn-outline-secondary.disabled{color:#616161;background-color:transparent}.btn-outline-success{color:#43a047;border-color:#43a047}.btn-outline-success:hover{color:#000;background-color:#43a047;border-color:#43a047}.btn-check:focus+.btn-outline-success,.btn-outline-success:focus{box-shadow:0 0 0 0 rgba(67,160,71,0.5)}.btn-check:checked+.btn-outline-success,.btn-check:active+.btn-outline-success,.btn-outline-success:active,.btn-outline-success.active,.btn-outline-success.dropdown-toggle.show{color:#000;background-color:#43a047;border-color:#43a047}.btn-check:checked+.btn-outline-success:focus,.btn-check:active+.btn-outline-success:focus,.btn-outline-success:active:focus,.btn-outline-success.active:focus,.btn-outline-success.dropdown-toggle.show:focus{box-shadow:0 0 0 0 rgba(67,160,71,0.5)}.btn-outline-success:disabled,.btn-outline-success.disabled{color:#43a047;background-color:transparent}.btn-outline-info{color:#469eb9;border-color:#469eb9}.btn-outline-info:hover{color:#000;background-color:#469eb9;border-color:#469eb9}.btn-check:focus+.btn-outline-info,.btn-outline-info:focus{box-shadow:0 0 0 0 rgba(70,158,185,0.5)}.btn-check:checked+.btn-outline-info,.btn-check:active+.btn-outline-info,.btn-outline-info:active,.btn-outline-info.active,.btn-outline-info.dropdown-toggle.show{color:#000;background-color:#469eb9;border-color:#469eb9}.btn-check:checked+.btn-outline-info:focus,.btn-check:active+.btn-outline-info:focus,.btn-outline-info:active:focus,.btn-outline-info.active:focus,.btn-outline-info.dropdown-toggle.show:focus{box-shadow:0 0 0 0 rgba(70,158,185,0.5)}.btn-outline-info:disabled,.btn-outline-info.disabled{color:#469eb9;background-color:transparent}.btn-outline-warning{color:#f9a825;border-color:#f9a825}.btn-outline-warning:hover{color:#000;background-color:#f9a825;border-color:#f9a825}.btn-check:focus+.btn-outline-warning,.btn-outline-warning:focus{box-shadow:0 0 0 0 rgba(249,168,37,0.5)}.btn-check:checked+.btn-outline-warning,.btn-check:active+.btn-outline-warning,.btn-outline-warning:active,.btn-outline-warning.active,.btn-outline-warning.dropdown-toggle.show{color:#000;background-color:#f9a825;border-color:#f9a825}.btn-check:checked+.btn-outline-warning:focus,.btn-check:active+.btn-outline-warning:focus,.btn-outline-warning:active:focus,.btn-outline-warning.active:focus,.btn-outline-warning.dropdown-toggle.show:focus{box-shadow:0 0 0 0 rgba(249,168,37,0.5)}.btn-outline-warning:disabled,.btn-outline-warning.disabled{color:#f9a825;background-color:transparent}.btn-outline-danger{color:#ff511f;border-color:#ff511f}.btn-outline-danger:hover{color:#000;background-color:#ff511f;border-color:#ff511f}.btn-check:focus+.btn-outline-danger,.btn-outline-danger:focus{box-shadow:0 0 0 0 rgba(255,81,31,0.5)}.btn-check:checked+.btn-outline-danger,.btn-check:active+.btn-outline-danger,.btn-outline-danger:active,.btn-outline-danger.active,.btn-outline-danger.dropdown-toggle.show{color:#000;background-color:#ff511f;border-color:#ff511f}.btn-check:checked+.btn-outline-danger:focus,.btn-check:active+.btn-outline-danger:focus,.btn-outline-danger:active:focus,.btn-outline-danger.active:focus,.btn-outline-danger.dropdown-toggle.show:focus{box-shadow:0 0 0 0 rgba(255,81,31,0.5)}.btn-outline-danger:disabled,.btn-outline-danger.disabled{color:#ff511f;background-color:transparent}.btn-outline-light{color:#616161;border-color:#616161}.btn-outline-light:hover{color:#fff;background-color:#616161;border-color:#616161}.btn-check:focus+.btn-outline-light,.btn-outline-light:focus{box-shadow:0 0 0 0 rgba(97,97,97,0.5)}.btn-check:checked+.btn-outline-light,.btn-check:active+.btn-outline-light,.btn-outline-light:active,.btn-outline-light.active,.btn-outline-light.dropdown-toggle.show{color:#fff;background-color:#616161;border-color:#616161}.btn-check:checked+.btn-outline-light:focus,.btn-check:active+.btn-outline-light:focus,.btn-outline-light:active:focus,.btn-outline-light.active:focus,.btn-outline-light.dropdown-toggle.show:focus{box-shadow:0 0 0 0 rgba(97,97,97,0.5)}.btn-outline-light:disabled,.btn-outline-light.disabled{color:#616161;background-color:transparent}.btn-outline-dark{color:#616161;border-color:#616161}.btn-outline-dark:hover{color:#fff;background-color:#616161;border-color:#616161}.btn-check:focus+.btn-outline-dark,.btn-outline-dark:focus{box-shadow:0 0 0 0 rgba(97,97,97,0.5)}.btn-check:checked+.btn-outline-dark,.btn-check:active+.btn-outline-dark,.btn-outline-dark:active,.btn-outline-dark.active,.btn-outline-dark.dropdown-toggle.show{color:#fff;background-color:#616161;border-color:#616161}.btn-check:checked+.btn-outline-dark:focus,.btn-check:active+.btn-outline-dark:focus,.btn-outline-dark:active:focus,.btn-outline-dark.active:focus,.btn-outline-dark.dropdown-toggle.show:focus{box-shadow:0 0 0 0 rgba(97,97,97,0.5)}.btn-outline-dark:disabled,.btn-outline-dark.disabled{color:#616161;background-color:transparent}.btn-link{font-weight:400;color:var(--t42-link-color);text-decoration:underline}.btn-link:hover{color:var(--t42-link-hover-color)}.btn-link:disabled,.btn-link.disabled{color:#6c757d}.btn-lg,.btn-group-lg>.btn{padding:0 .875rem;font-size:.75rem;border-radius:0}.btn-sm,.btn-group-sm>.btn{padding:0 .875rem;font-size:.75rem;border-radius:0}.btn-group,.btn-group-vertical{position:relative;display:inline-flex;vertical-align:middle}.btn-group>.btn,.btn-group-vertical>.btn{position:relative;flex:1 1 auto}.btn-group>.btn-check:checked+.btn,.btn-group>.btn-check:focus+.btn,.btn-group>.btn:hover,.btn-group>.btn:focus,.btn-group>.btn:active,.btn-group>.btn.active,.btn-group-vertical>.btn-check:checked+.btn,.btn-group-vertical>.btn-check:focus+.btn,.btn-group-vertical>.btn:hover,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn.active{z-index:1}.btn-toolbar{display:flex;flex-wrap:wrap;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group>.btn:not(:first-child),.btn-group>.btn-group:not(:first-child){margin-left:-1px}.btn-group>.btn:not(:last-child):not(.dropdown-toggle),.btn-group>.btn-group:not(:last-child)>.btn{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:nth-child(n+3),.btn-group>:not(.btn-check)+.btn,.btn-group>.btn-group:not(:first-child)>.btn{border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.65625rem;padding-left:.65625rem}.dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after,.dropend .dropdown-toggle-split::after{margin-left:0}.dropstart .dropdown-toggle-split::before{margin-right:0}.btn-sm+.dropdown-toggle-split,.btn-group-sm>.btn+.dropdown-toggle-split{padding-right:.65625rem;padding-left:.65625rem}.btn-lg+.dropdown-toggle-split,.btn-group-lg>.btn+.dropdown-toggle-split{padding-right:.65625rem;padding-left:.65625rem}.btn-group-vertical{flex-direction:column;align-items:flex-start;justify-content:center}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn:not(:first-child),.btn-group-vertical>.btn-group:not(:first-child){margin-top:-1px}.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle),.btn-group-vertical>.btn-group:not(:last-child)>.btn{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn ~ .btn,.btn-group-vertical>.btn-group:not(:first-child)>.btn{border-top-left-radius:0;border-top-right-radius:0}button,button:focus{outline:none}.btn{color:var(--t42-link-color);transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, border-color;cursor:default}.btn.disabled,.btn:disabled{color:var(--t42-link-color);cursor:default}.btn:not(.disabled):not(:disabled).active,.btn:not(.disabled):not(:disabled):hover{border-color:var(--t42-color-opacity-30);color:var(--white);backdrop-filter:var(--backdrop-filter)}.btn:focus,.btn:active{color:var(--white)}.btn-primary{background-color:rgba(0,123,229,0.05)}.btn-primary.disabled,.btn-primary:disabled{background-color:rgba(0,123,229,0.05)}.btn-primary:not(.disabled):not(:disabled).active,.btn-primary:not(.disabled):not(:disabled):hover{background-color:#007be5}.btn-primary:not(.disabled):not(:disabled).btn-icon.active,.btn-primary:not(.disabled):not(:disabled).btn-icon:focus,.btn-primary:not(.disabled):not(:disabled).btn-icon:hover{color:var(--white)}.btn-primary.dropdown-toggle.active,.btn-primary.dropdown-toggle:active,.btn-primary.dropdown-toggle:focus{border-color:var(--t42-color-opacity-30);background-color:#007be5}.btn-secondary{background-color:rgba(97,97,97,0.05)}.btn-secondary.disabled,.btn-secondary:disabled{background-color:rgba(97,97,97,0.05)}.btn-secondary:not(.disabled):not(:disabled).active,.btn-secondary:not(.disabled):not(:disabled):hover{background-color:#616161}.btn-secondary:not(.disabled):not(:disabled).btn-icon.active,.btn-secondary:not(.disabled):not(:disabled).btn-icon:focus,.btn-secondary:not(.disabled):not(:disabled).btn-icon:hover{color:var(--white)}.btn-secondary.dropdown-toggle.active,.btn-secondary.dropdown-toggle:active,.btn-secondary.dropdown-toggle:focus{border-color:var(--t42-color-opacity-30);background-color:#616161}.btn-success{background-color:rgba(67,160,71,0.05)}.btn-success.disabled,.btn-success:disabled{background-color:rgba(67,160,71,0.05)}.btn-success:not(.disabled):not(:disabled).active,.btn-success:not(.disabled):not(:disabled):hover{background-color:#43a047}.btn-success:not(.disabled):not(:disabled).btn-icon.active,.btn-success:not(.disabled):not(:disabled).btn-icon:focus,.btn-success:not(.disabled):not(:disabled).btn-icon:hover{color:var(--white)}.btn-success.dropdown-toggle.active,.btn-success.dropdown-toggle:active,.btn-success.dropdown-toggle:focus{border-color:var(--t42-color-opacity-30);background-color:#43a047}.btn-info{background-color:rgba(70,158,185,0.05)}.btn-info.disabled,.btn-info:disabled{background-color:rgba(70,158,185,0.05)}.btn-info:not(.disabled):not(:disabled).active,.btn-info:not(.disabled):not(:disabled):hover{background-color:#469eb9}.btn-info:not(.disabled):not(:disabled).btn-icon.active,.btn-info:not(.disabled):not(:disabled).btn-icon:focus,.btn-info:not(.disabled):not(:disabled).btn-icon:hover{color:var(--white)}.btn-info.dropdown-toggle.active,.btn-info.dropdown-toggle:active,.btn-info.dropdown-toggle:focus{border-color:var(--t42-color-opacity-30);background-color:#469eb9}.btn-warning{background-color:rgba(249,168,37,0.05)}.btn-warning.disabled,.btn-warning:disabled{background-color:rgba(249,168,37,0.05)}.btn-warning:not(.disabled):not(:disabled).active,.btn-warning:not(.disabled):not(:disabled):hover{background-color:#f9a825}.btn-warning:not(.disabled):not(:disabled).btn-icon.active,.btn-warning:not(.disabled):not(:disabled).btn-icon:focus,.btn-warning:not(.disabled):not(:disabled).btn-icon:hover{color:var(--white)}.btn-warning.dropdown-toggle.active,.btn-warning.dropdown-toggle:active,.btn-warning.dropdown-toggle:focus{border-color:var(--t42-color-opacity-30);background-color:#f9a825}.btn-danger{background-color:rgba(255,81,31,0.05)}.btn-danger.disabled,.btn-danger:disabled{background-color:rgba(255,81,31,0.05)}.btn-danger:not(.disabled):not(:disabled).active,.btn-danger:not(.disabled):not(:disabled):hover{background-color:#ff511f}.btn-danger:not(.disabled):not(:disabled).btn-icon.active,.btn-danger:not(.disabled):not(:disabled).btn-icon:focus,.btn-danger:not(.disabled):not(:disabled).btn-icon:hover{color:var(--white)}.btn-danger.dropdown-toggle.active,.btn-danger.dropdown-toggle:active,.btn-danger.dropdown-toggle:focus{border-color:var(--t42-color-opacity-30);background-color:#ff511f}.btn-light{background-color:rgba(97,97,97,0.05)}.btn-light.disabled,.btn-light:disabled{background-color:rgba(97,97,97,0.05)}.btn-light:not(.disabled):not(:disabled).active,.btn-light:not(.disabled):not(:disabled):hover{background-color:#616161}.btn-light:not(.disabled):not(:disabled).btn-icon.active,.btn-light:not(.disabled):not(:disabled).btn-icon:focus,.btn-light:not(.disabled):not(:disabled).btn-icon:hover{color:var(--white)}.btn-light.dropdown-toggle.active,.btn-light.dropdown-toggle:active,.btn-light.dropdown-toggle:focus{border-color:var(--t42-color-opacity-30);background-color:#616161}.btn-dark{background-color:rgba(97,97,97,0.05)}.btn-dark.disabled,.btn-dark:disabled{background-color:rgba(97,97,97,0.05)}.btn-dark:not(.disabled):not(:disabled).active,.btn-dark:not(.disabled):not(:disabled):hover{background-color:#616161}.btn-dark:not(.disabled):not(:disabled).btn-icon.active,.btn-dark:not(.disabled):not(:disabled).btn-icon:focus,.btn-dark:not(.disabled):not(:disabled).btn-icon:hover{color:var(--white)}.btn-dark.dropdown-toggle.active,.btn-dark.dropdown-toggle:active,.btn-dark.dropdown-toggle:focus{border-color:var(--t42-color-opacity-30);background-color:#616161}.btn-link{text-decoration:none;backdrop-filter:none}.btn-link:not(.disabled):not(:disabled).active,.btn-link:not(.disabled):not(:disabled):focus,.btn-link:not(.disabled):not(:disabled):hover{border-color:transparent;color:var(--t42-link-color);text-decoration:underline}.btn-icon:not(.disabled):not(:disabled).active,.btn-icon:not(.disabled):not(:disabled):focus,.btn-icon:not(.disabled):not(:disabled):hover{color:var(--t42-link-color)}.btn-icon-action{display:flex;justify-content:center;width:1rem;height:1rem;padding:0;border-radius:50%;font-size:0.75rem;transition:all .2s ease-in-out}@media (prefers-reduced-motion: reduce){.btn-icon-action{transition:none}}.btn-icon-action:not(.disabled):not(:disabled).active,.btn-icon-action:not(.disabled):not(:disabled):hover,.btn-icon-action:not(.disabled):not(:disabled):focus{border-color:transparent;background-color:Rgb(var(--t42-bg-light));box-shadow:var(--t42-shadow)}.btn-icon-action-right{position:absolute;right:0.25rem}.btn-icon-action-show-hover{transition:all .2s ease-in-out}@media (prefers-reduced-motion: reduce){.btn-icon-action-show-hover{transition:none}}.btn-icon-action-show-hover .btn-icon-action{opacity:0}.btn-icon-action-show-hover:not(.disabled):not(:disabled):hover .btn-icon-action{opacity:1}.btn-close{width:1rem;height:1rem;filter:var(--filter-close)}.breadcrumb{display:flex;flex-wrap:wrap;padding:0 0;margin-bottom:.5rem;list-style:none;background-color:rgba(0,0,0,0)}.breadcrumb-item+.breadcrumb-item{padding-left:.5rem}.breadcrumb-item+.breadcrumb-item::before{float:left;padding-right:.5rem;color:#6c757d;content:var(--bs-breadcrumb-divider, "/") /* rtl: var(--bs-breadcrumb-divider, "/") */}.breadcrumb-item.active{color:var(--t42-link-color)}.breadcrumb-item{font-size:83.3%}.breadcrumb-item.active{text-decoration:underline}.breadcrumb-item+.breadcrumb-item{padding-left:0}.breadcrumb-item+.breadcrumb-item::before{position:relative;top:0.063rem;left:0.063rem;width:0.75rem;height:0.75rem;background-color:var(--t42-content-color);content:"";-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M339.2,256.3c0,2.4-0.9,4.4-2.6,6.1L203,396c-1.7,1.7-3.8,2.6-6.1,2.6c-2.4,0-4.6-0.9-6.7-2.6l-14.3-14.3 c-2-2-3.1-4.3-3.1-6.7s1-4.6,3.1-6.7L288,256.3L175.9,143.6c-2-1.7-3.1-3.8-3.1-6.1s1-4.6,3.1-6.7l14.3-14.3c1.7-2,3.9-3.1,6.7-3.1 s4.8,1,6.1,3.1l133.6,133.1C338.3,251.3,339.2,253.5,339.2,256.3L339.2,256.3z%27/%3E%3C/svg%3E")}mark,.mark{color:var(--white)}pre{background-color:var(--t42-bg-dark)}blockquote,.blockquote{padding:1rem 1rem 0.01rem;border-left:0.25rem solid var(--secondary);background-color:Rgb(var(--t42-bg-dark))}.blockquote-footer{margin-top:-2rem;margin-left:1.25rem;color:var(--t42-content-color-muted);font-size:0.875em}pre{border:0.0625rem solid var(--t42-color-opacity-10)}.card{position:relative;display:flex;flex-direction:column;min-width:0;word-wrap:break-word;background-color:Rgba(var(--t42-bg-light), 0.75);background-clip:border-box;border:1px solid var(--t42-color-opacity-10);border-radius:0}.card>hr{margin-right:0;margin-left:0}.card>.list-group{border-top:inherit;border-bottom:inherit}.card>.list-group:first-child{border-top-width:0;border-top-left-radius:0;border-top-right-radius:0}.card>.list-group:last-child{border-bottom-width:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.card>.card-header+.list-group,.card>.list-group+.card-footer{border-top:0}.card-body{flex:1 1 auto;padding:1.25rem 1.25rem}.card-title{margin-bottom:.5rem}.card-subtitle{margin-top:-.25rem;margin-bottom:0}.card-text:last-child{margin-bottom:0}.card-link+.card-link{margin-left:1.25rem}.card-header{padding:.625rem 1.25rem;margin-bottom:0;color:var(--t42-link-color);background-color:rgba(0,0,0,0);border-bottom:1px solid var(--t42-color-opacity-10)}.card-header:first-child{border-radius:0 0 0 0}.card-footer{padding:.625rem 1.25rem;color:var(--t42-link-color);background-color:rgba(0,0,0,0);border-top:1px solid var(--t42-color-opacity-10)}.card-footer:last-child{border-radius:0 0 0 0}.card-header-tabs{margin-right:-.625rem;margin-bottom:-.625rem;margin-left:-.625rem;border-bottom:0}.card-header-tabs .nav-link.active{background-color:Rgba(var(--t42-bg-light), 0.75);border-bottom-color:Rgba(var(--t42-bg-light), 0.75)}.card-header-pills{margin-right:-.625rem;margin-left:-.625rem}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1rem;border-radius:0}.card-img,.card-img-top,.card-img-bottom{width:100%}.card-img,.card-img-top{border-top-left-radius:0;border-top-right-radius:0}.card-img,.card-img-bottom{border-bottom-right-radius:0;border-bottom-left-radius:0}.card-group>.card{margin-bottom:.75rem}@media (min-width: 576px){.card-group{display:flex;flex-flow:row wrap}.card-group>.card{flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:not(:last-child) .card-img-top,.card-group>.card:not(:last-child) .card-header{border-top-right-radius:0}.card-group>.card:not(:last-child) .card-img-bottom,.card-group>.card:not(:last-child) .card-footer{border-bottom-right-radius:0}.card-group>.card:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:not(:first-child) .card-img-top,.card-group>.card:not(:first-child) .card-header{border-top-left-radius:0}.card-group>.card:not(:first-child) .card-img-bottom,.card-group>.card:not(:first-child) .card-footer{border-bottom-left-radius:0}}.card{box-shadow:var(--t42-shadow);backdrop-filter:var(--backdrop-filter)}.card .card-header{border-bottom-width:0}.card .card-subtitle{margin-bottom:0.5rem;font-size:83.3%}.card.bg-primary{background-color:transparent !important}.card.bg-primary .card-header{background-color:Rgba(var(--t42-bg-mid), 0.75)}.card.bg-primary .card-body{background-color:Rgba(var(--t42-bg-light), 0.75)}.card.bg-secondary{background-color:transparent !important}.card.bg-secondary .card-header{background-color:Rgba(var(--t42-bg-light), 0.75)}.card.bg-secondary .card-body{background-color:Rgba(var(--t42-bg-mid), 0.75)}.card:not(.bg-primary):not(.bg-secondary) .card-header+.card-body{padding-top:0}.card-header-tabs{margin-bottom:0}.accordion .card:first-of-type,.accordion .card:not(:first-of-type):not(:last-of-type){margin-bottom:0.5rem;border-bottom:var(--t42-border)}.accordion .card-header{position:relative;padding:0}.accordion .card-header .btn-link{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;width:100%;padding:0.75rem 2rem;line-height:1.4;text-align:left}.accordion .card-header .btn-link::before{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:transform;position:absolute;display:inline-block;width:0.75rem;height:0.75rem;background-color:var(--t42-content-color);transform:translateX(-1rem) translateY(0.063rem) rotate(-90deg);content:"";-webkit-mask-image:var(--t42-select-indicator)}.accordion .card-header .btn-link:hover{backdrop-filter:none}.accordion .card-header .btn-link.collapsed::before{transform:translateX(-1rem) translateY(0.063rem)}.accordion .card-header .btn-link.disabled::before,.accordion .card-header .btn-link:disabled::before{opacity:.35}.accordion .card-body{padding:0 1.25rem 1.25rem}.accordion .bg-primary .card-body,.accordion .bg-secondary .card-body{padding:1.25rem}.dropup,.dropend,.dropdown,.dropstart{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:0;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{position:absolute;z-index:1000;display:none;min-width:10rem;padding:0 0;margin:0;font-size:.75rem;color:var(--t42-content-color);text-align:left;list-style:none;background-color:Rgba(var(--t42-bg-light), 0.75);background-clip:padding-box;border:1px solid var(--t42-color-opacity-10);border-radius:0}.dropdown-menu[data-bs-popper]{top:100%;left:0;margin-top:.125rem}.dropdown-menu-start{--bs-position: start}.dropdown-menu-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-end{--bs-position: end}.dropdown-menu-end[data-bs-popper]{right:0;left:auto}@media (min-width: 576px){.dropdown-menu-sm-start{--bs-position: start}.dropdown-menu-sm-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-sm-end{--bs-position: end}.dropdown-menu-sm-end[data-bs-popper]{right:0;left:auto}}@media (min-width: 768px){.dropdown-menu-md-start{--bs-position: start}.dropdown-menu-md-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-md-end{--bs-position: end}.dropdown-menu-md-end[data-bs-popper]{right:0;left:auto}}@media (min-width: 992px){.dropdown-menu-lg-start{--bs-position: start}.dropdown-menu-lg-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-lg-end{--bs-position: end}.dropdown-menu-lg-end[data-bs-popper]{right:0;left:auto}}@media (min-width: 1200px){.dropdown-menu-xl-start{--bs-position: start}.dropdown-menu-xl-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-xl-end{--bs-position: end}.dropdown-menu-xl-end[data-bs-popper]{right:0;left:auto}}@media (min-width: 1400px){.dropdown-menu-xxl-start{--bs-position: start}.dropdown-menu-xxl-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-xxl-end{--bs-position: end}.dropdown-menu-xxl-end[data-bs-popper]{right:0;left:auto}}.dropup .dropdown-menu[data-bs-popper]{top:auto;bottom:100%;margin-top:0;margin-bottom:.125rem}.dropup .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:0;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropend .dropdown-menu[data-bs-popper]{top:0;right:auto;left:100%;margin-top:0;margin-left:.125rem}.dropend .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:0;content:"";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid}.dropend .dropdown-toggle:empty::after{margin-left:0}.dropend .dropdown-toggle::after{vertical-align:0}.dropstart .dropdown-menu[data-bs-popper]{top:0;right:100%;left:auto;margin-top:0;margin-right:.125rem}.dropstart .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:0;content:""}.dropstart .dropdown-toggle::after{display:none}.dropstart .dropdown-toggle::before{display:inline-block;margin-right:.255em;vertical-align:0;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropstart .dropdown-toggle:empty::after{margin-left:0}.dropstart .dropdown-toggle::before{vertical-align:0}.dropdown-divider{height:0;margin:0 0;overflow:hidden;border-top:1px solid var(--t42-color-opacity-10)}.dropdown-item{display:block;width:100%;padding:.375rem 1rem;clear:both;font-weight:400;color:var(--t42-content-color);text-align:inherit;text-decoration:none;white-space:nowrap;background-color:transparent;border:0}.dropdown-item:first-child{border-top-left-radius:0;border-top-right-radius:0}.dropdown-item:last-child{border-bottom-right-radius:0;border-bottom-left-radius:0}.dropdown-item:hover,.dropdown-item:focus{color:var(--t42-link-hover-color);background-color:var(--t42-link-hover-bg)}.dropdown-item.active,.dropdown-item:active{color:var(--t42-link-hover-color);text-decoration:none;background-color:var(--t42-link-active-bg)}.dropdown-item.disabled,.dropdown-item:disabled{color:#adb5bd;pointer-events:none;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:0 1rem;margin-bottom:0;font-size:.65625rem;color:shade-color(#616161, 10%);white-space:nowrap}.dropdown-item-text{display:block;padding:.375rem 1rem;color:var(--t42-content-color)}.dropdown-menu-dark{color:#dee2e6;background-color:#343a40;border-color:var(--t42-color-opacity-10)}.dropdown-menu-dark .dropdown-item{color:#dee2e6}.dropdown-menu-dark .dropdown-item:hover,.dropdown-menu-dark .dropdown-item:focus{color:#fff;background-color:rgba(255,255,255,0.15)}.dropdown-menu-dark .dropdown-item.active,.dropdown-menu-dark .dropdown-item:active{color:var(--t42-link-hover-color);background-color:var(--t42-link-active-bg)}.dropdown-menu-dark .dropdown-item.disabled,.dropdown-menu-dark .dropdown-item:disabled{color:#adb5bd}.dropdown-menu-dark .dropdown-divider{border-color:var(--t42-color-opacity-10)}.dropdown-menu-dark .dropdown-item-text{color:#dee2e6}.dropdown-menu-dark .dropdown-header{color:#adb5bd}.dropdown-menu{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:opacity, visability;display:block;visibility:hidden;opacity:0;backdrop-filter:var(--backdrop-filter)}.dropdown-menu.show{visibility:visible;opacity:1}.dropdown-toggle::after{position:relative;width:0.5rem;height:0.5rem;border:0;background-color:var(--t42-link-color);content:"";-webkit-mask-image:url("data:image/svg+xml,%3Csvg version=%271.1%27 xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M480.768 186.88l-211.968 211.456q-5.12 5.632-12.8 5.632t-12.8-5.632l-211.968-211.456q-5.632-5.632-5.632-13.312t5.632-12.8l47.616-47.104q5.12-5.632 12.8-5.632t12.8 5.632l151.552 151.552 151.552-151.552q5.632-5.632 12.8-5.632t13.312 5.632l47.104 47.104q5.632 5.632 5.632 12.8t-5.632 13.312z%27%3E%3C/path%3E%3C/svg%3E")}.dropdown-toggle.show::after{color:var(--white)}.dropup .dropdown-toggle::after{position:relative;top:0.188rem;width:0.5rem;height:0.5rem;border:0;background-color:var(--t42-link-color);content:"";-webkit-mask-image:url("data:image/svg+xml,%3Csvg version=%271.1%27 xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M480.768 351.488l-47.104 47.104q-5.632 5.12-13.312 5.12t-12.8-5.12l-151.552-152.064-151.552 152.064q-5.632 5.12-12.8 5.12t-12.8-5.12l-47.616-47.104q-5.632-5.632-5.632-13.312t5.632-12.8l211.968-211.968q5.632-5.12 12.8-5.12t12.8 5.12l211.968 211.968q5.632 5.632 5.632 12.8t-5.632 13.312z%27%3E%3C/path%3E%3C/svg%3E%0A")}.form-label{margin-bottom:.5rem}.col-form-label{padding-top:1px;padding-bottom:1px;margin-bottom:0;font-size:inherit;line-height:1.875rem}.col-form-label-lg{padding-top:1px;padding-bottom:1px;font-size:.75rem}.col-form-label-sm{padding-top:1px;padding-bottom:1px;font-size:.75rem}.form-text{margin-top:.25rem;font-size:.875em;color:var(--t42-content-color-muted)}.form-control{display:block;width:100%;padding:0 .875rem;font-size:.75rem;font-weight:400;line-height:1.875rem;color:var(--t42-link-color);background-color:var(--t42-input-bg);background-clip:padding-box;border:1px solid var(--t42-color-opacity-10);appearance:none;border-radius:0;transition:border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.form-control{transition:none}}.form-control[type="file"]{overflow:hidden}.form-control[type="file"]:not(:disabled):not([readonly]){cursor:pointer}.form-control:focus{color:var(--t42-link-color);background-color:var(--t42-input-bg);border-color:#007be5;outline:0;box-shadow:0 0 0 0 rgba(0,123,229,0.25)}.form-control::-webkit-date-and-time-value{height:1.875rem}.form-control::placeholder{color:var(--t42-content-color-muted);opacity:1}.form-control:disabled,.form-control[readonly]{background-color:var(--t42-input-disabled-bg);opacity:1}.form-control::file-selector-button{padding:0 .875rem;margin:0 -.875rem;margin-inline-end:.875rem;color:var(--t42-link-color);background-color:#e9ecef;pointer-events:none;border-color:inherit;border-style:solid;border-width:0;border-inline-end-width:1px;border-radius:0;transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.form-control::file-selector-button{transition:none}}.form-control:hover:not(:disabled):not([readonly])::file-selector-button{background-color:#dde0e3}.form-control::-webkit-file-upload-button{padding:0 .875rem;margin:0 -.875rem;margin-inline-end:.875rem;color:var(--t42-link-color);background-color:#e9ecef;pointer-events:none;border-color:inherit;border-style:solid;border-width:0;border-inline-end-width:1px;border-radius:0;transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.form-control::-webkit-file-upload-button{transition:none}}.form-control:hover:not(:disabled):not([readonly])::-webkit-file-upload-button{background-color:#dde0e3}.form-control-plaintext{display:block;width:100%;padding:0 0;margin-bottom:0;line-height:1.875rem;color:var(--t42-content-color);background-color:transparent;border:solid transparent;border-width:1px 0}.form-control-plaintext.form-control-sm,.form-control-plaintext.form-control-lg{padding-right:0;padding-left:0}.form-control-sm{min-height:2rem;padding:0 .875rem;font-size:.75rem;border-radius:0}.form-control-sm::file-selector-button{padding:0 .875rem;margin:0 -.875rem;margin-inline-end:.875rem}.form-control-sm::-webkit-file-upload-button{padding:0 .875rem;margin:0 -.875rem;margin-inline-end:.875rem}.form-control-lg{min-height:2rem;padding:0 .875rem;font-size:.75rem;border-radius:0}.form-control-lg::file-selector-button{padding:0 .875rem;margin:0 -.875rem;margin-inline-end:.875rem}.form-control-lg::-webkit-file-upload-button{padding:0 .875rem;margin:0 -.875rem;margin-inline-end:.875rem}textarea.form-control{min-height:2rem}textarea.form-control-sm{min-height:2rem}textarea.form-control-lg{min-height:2rem}.form-control-color{width:3rem;height:auto;padding:0}.form-control-color:not(:disabled):not([readonly]){cursor:pointer}.form-control-color::-moz-color-swatch{height:1.875rem;border-radius:0}.form-control-color::-webkit-color-swatch{height:1.875rem;border-radius:0}.form-select{display:block;width:100%;padding:0 2.625rem 0 .875rem;-moz-padding-start:calc(.875rem - 3px);font-size:.75rem;font-weight:400;line-height:1.875rem;color:var(--t42-link-color);background-color:var(--t42-input-bg);background-image:var(--t42-select-indicator);background-repeat:no-repeat;background-position:right 0.5rem center;background-size:1rem;border:1px solid var(--t42-color-opacity-10);border-radius:0;transition:border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out;appearance:none}@media (prefers-reduced-motion: reduce){.form-select{transition:none}}.form-select:focus{border-color:#007be5;outline:0;box-shadow:0 0 0 0 rgba(0,123,229,0.25)}.form-select[multiple],.form-select[size]:not([size="1"]){padding-right:.875rem;background-image:none}.form-select:disabled{background-color:#e9ecef}.form-select:-moz-focusring{color:transparent;text-shadow:0 0 0 var(--t42-link-color)}.form-select-sm{padding-top:0;padding-bottom:0;padding-left:.875rem;font-size:.75rem;border-radius:0}.form-select-lg{padding-top:0;padding-bottom:0;padding-left:.875rem;font-size:.75rem;border-radius:0}.form-check{display:block;min-height:1.125rem;padding-left:1.25rem;margin-bottom:0}.form-check .form-check-input{float:left;margin-left:-1.25rem}.form-check-input{width:1em;height:1em;margin-top:.25em;vertical-align:top;background-color:var(--t42-input-bg);background-repeat:no-repeat;background-position:center;background-size:contain;border:1px solid rgba(0,0,0,0.25);appearance:none;color-adjust:exact}.form-check-input[type="checkbox"]{border-radius:.25em}.form-check-input[type="radio"]{border-radius:50%}.form-check-input:active{filter:brightness(90%)}.form-check-input:focus{border-color:#007be5;outline:0;box-shadow:0 0 0 0 rgba(0,123,229,0.25)}.form-check-input:checked{background-color:#007be5;border-color:#007be5}.form-check-input:checked[type="checkbox"]{background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 20 20%27%3e%3cpath fill=%27none%27 stroke=%27%23fff%27 stroke-linecap=%27round%27 stroke-linejoin=%27round%27 stroke-width=%273%27 d=%27M6 10l3 3l6-6%27/%3e%3c/svg%3e")}.form-check-input:checked[type="radio"]{background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%27-4 -4 8 8%27%3e%3ccircle r=%272%27 fill=%27%23fff%27/%3e%3c/svg%3e")}.form-check-input[type="checkbox"]:indeterminate{background-color:#007be5;border-color:#007be5;background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 20 20%27%3e%3cpath fill=%27none%27 stroke=%27%23fff%27 stroke-linecap=%27round%27 stroke-linejoin=%27round%27 stroke-width=%273%27 d=%27M6 10h8%27/%3e%3c/svg%3e")}.form-check-input:disabled{pointer-events:none;filter:none;opacity:.5}.form-check-input[disabled] ~ .form-check-label,.form-check-input:disabled ~ .form-check-label{opacity:.5}.form-switch{padding-left:2.5em}.form-switch .form-check-input{width:2em;margin-left:-2.5em;background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%27-4 -4 8 8%27%3e%3ccircle r=%273%27 fill=%27rgba%280,0,0,0.25%29%27/%3e%3c/svg%3e");background-position:left center;border-radius:2em;transition:background-position 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.form-switch .form-check-input{transition:none}}.form-switch .form-check-input:focus{background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%27-4 -4 8 8%27%3e%3ccircle r=%273%27 fill=%27%23007be5%27/%3e%3c/svg%3e")}.form-switch .form-check-input:checked{background-position:right center;background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%27-4 -4 8 8%27%3e%3ccircle r=%273%27 fill=%27%23fff%27/%3e%3c/svg%3e")}.form-check-inline{display:inline-block;margin-right:1rem}.btn-check{position:absolute;clip:rect(0, 0, 0, 0);pointer-events:none}.btn-check[disabled]+.btn,.btn-check:disabled+.btn{pointer-events:none;filter:none;opacity:.35}.form-range{width:100%;height:1rem;padding:0;background-color:transparent;appearance:none}.form-range:focus{outline:0}.form-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 0 rgba(0,123,229,0.25)}.form-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 0 rgba(0,123,229,0.25)}.form-range::-moz-focus-outer{border:0}.form-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-.25rem;background-color:#007be5;border:0;border-radius:1rem;transition:background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out;appearance:none}@media (prefers-reduced-motion: reduce){.form-range::-webkit-slider-thumb{transition:none}}.form-range::-webkit-slider-thumb:active{background-color:#b3d7f7}.form-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.form-range::-moz-range-thumb{width:1rem;height:1rem;background-color:#007be5;border:0;border-radius:1rem;transition:background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out;appearance:none}@media (prefers-reduced-motion: reduce){.form-range::-moz-range-thumb{transition:none}}.form-range::-moz-range-thumb:active{background-color:#b3d7f7}.form-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.form-range:disabled{pointer-events:none}.form-range:disabled::-webkit-slider-thumb{background-color:#adb5bd}.form-range:disabled::-moz-range-thumb{background-color:#adb5bd}.form-floating{position:relative}.form-floating>.form-control,.form-floating>.form-select{height:calc(3.5rem + 2px);line-height:1.25}.form-floating>label{position:absolute;top:0;left:0;height:100%;padding:1rem .875rem;pointer-events:none;border:1px solid transparent;transform-origin:0 0;transition:opacity 0.1s ease-in-out,transform 0.1s ease-in-out}@media (prefers-reduced-motion: reduce){.form-floating>label{transition:none}}.form-floating>.form-control{padding:1rem .875rem}.form-floating>.form-control::placeholder{color:transparent}.form-floating>.form-control:focus,.form-floating>.form-control:not(:placeholder-shown){padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control:-webkit-autofill{padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-select{padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control:focus ~ label,.form-floating>.form-control:not(:placeholder-shown) ~ label,.form-floating>.form-select ~ label{opacity:.65;transform:scale(0.85) translateY(-0.5rem) translateX(0.15rem)}.form-floating>.form-control:-webkit-autofill ~ label{opacity:.65;transform:scale(0.85) translateY(-0.5rem) translateX(0.15rem)}.input-group{position:relative;display:flex;flex-wrap:wrap;align-items:stretch;width:100%}.input-group>.form-control,.input-group>.form-select{position:relative;flex:1 1 auto;width:1%;min-width:0}.input-group>.form-control:focus,.input-group>.form-select:focus{z-index:3}.input-group .btn{position:relative;z-index:2}.input-group .btn:focus{z-index:3}.input-group-text{display:flex;align-items:center;padding:0 .875rem;font-size:.75rem;font-weight:400;line-height:1.875rem;color:var(--t42-content-color);text-align:center;white-space:nowrap;background-color:#e9ecef;border:1px solid var(--t42-color-opacity-10);border-radius:0}.input-group-lg>.form-control,.input-group-lg>.form-select,.input-group-lg>.input-group-text,.input-group-lg>.btn{padding:0 .875rem;font-size:.75rem;border-radius:0}.input-group-sm>.form-control,.input-group-sm>.form-select,.input-group-sm>.input-group-text,.input-group-sm>.btn{padding:0 .875rem;font-size:.75rem;border-radius:0}.input-group-lg>.form-select,.input-group-sm>.form-select{padding-right:3.5rem}.input-group:not(.has-validation)>:not(:last-child):not(.dropdown-toggle):not(.dropdown-menu),.input-group:not(.has-validation)>.dropdown-toggle:nth-last-child(n+3){border-top-right-radius:0;border-bottom-right-radius:0}.input-group.has-validation>:nth-last-child(n+3):not(.dropdown-toggle):not(.dropdown-menu),.input-group.has-validation>.dropdown-toggle:nth-last-child(n+4){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>:not(:first-child):not(.dropdown-menu):not(.valid-tooltip):not(.valid-feedback):not(.invalid-tooltip):not(.invalid-feedback){margin-left:-1px;border-top-left-radius:0;border-bottom-left-radius:0}.valid-feedback{display:none;width:100%;margin-top:.5rem;font-size:.7rem;color:#43a047}.valid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem 1rem;margin-top:.1rem;font-size:.65625rem;color:#000;background-color:#43a047;border-radius:0}.was-validated :valid ~ .valid-feedback,.was-validated :valid ~ .valid-tooltip,.is-valid ~ .valid-feedback,.is-valid ~ .valid-tooltip{display:block}.was-validated .form-control:valid,.form-control.is-valid{border-color:#43a047;padding-right:2rem;background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 8 8%27%3e%3cpath fill=%27%2343a047%27 d=%27M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z%27/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right .5rem center;background-size:1rem 1rem}.was-validated .form-control:valid:focus,.form-control.is-valid:focus{border-color:#43a047;box-shadow:0 0 0 0 rgba(67,160,71,0.25)}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{padding-right:2rem;background-position:top .5rem right .5rem}.was-validated .form-select:valid,.form-select.is-valid{border-color:#43a047}.was-validated .form-select:valid:not([multiple]):not([size]),.was-validated .form-select:valid:not([multiple])[size="1"],.form-select.is-valid:not([multiple]):not([size]),.form-select.is-valid:not([multiple])[size="1"]{padding-right:3.5rem;background-image:var(--t42-select-indicator),url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 8 8%27%3e%3cpath fill=%27%2343a047%27 d=%27M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z%27/%3e%3c/svg%3e");background-position:right 0.5rem center,right 1.75rem center;background-size:1rem,1rem}.was-validated .form-select:valid:focus,.form-select.is-valid:focus{border-color:#43a047;box-shadow:0 0 0 0 rgba(67,160,71,0.25)}.was-validated .form-check-input:valid,.form-check-input.is-valid{border-color:#43a047}.was-validated .form-check-input:valid:checked,.form-check-input.is-valid:checked{background-color:#43a047}.was-validated .form-check-input:valid:focus,.form-check-input.is-valid:focus{box-shadow:0 0 0 0 rgba(67,160,71,0.25)}.was-validated .form-check-input:valid ~ .form-check-label,.form-check-input.is-valid ~ .form-check-label{color:#43a047}.form-check-inline .form-check-input ~ .valid-feedback{margin-left:.5em}.was-validated .input-group .form-control:valid,.input-group .form-control.is-valid,.was-validated .input-group .form-select:valid,.input-group .form-select.is-valid{z-index:1}.was-validated .input-group .form-control:valid:focus,.input-group .form-control.is-valid:focus,.was-validated .input-group .form-select:valid:focus,.input-group .form-select.is-valid:focus{z-index:3}.invalid-feedback{display:none;width:100%;margin-top:.5rem;font-size:.7rem;color:#ff511f}.invalid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem 1rem;margin-top:.1rem;font-size:.65625rem;color:#000;background-color:#ff511f;border-radius:0}.was-validated :invalid ~ .invalid-feedback,.was-validated :invalid ~ .invalid-tooltip,.is-invalid ~ .invalid-feedback,.is-invalid ~ .invalid-tooltip{display:block}.was-validated .form-control:invalid,.form-control.is-invalid{border-color:#ff511f;padding-right:2rem;background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 12 12%27 width=%2712%27 height=%2712%27 fill=%27none%27 stroke=%27%23ff511f%27%3e%3ccircle cx=%276%27 cy=%276%27 r=%274.5%27/%3e%3cpath stroke-linejoin=%27round%27 d=%27M5.8 3.6h.4L6 6.5z%27/%3e%3ccircle cx=%276%27 cy=%278.2%27 r=%27.6%27 fill=%27%23ff511f%27 stroke=%27none%27/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right .5rem center;background-size:1rem 1rem}.was-validated .form-control:invalid:focus,.form-control.is-invalid:focus{border-color:#ff511f;box-shadow:0 0 0 0 rgba(255,81,31,0.25)}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{padding-right:2rem;background-position:top .5rem right .5rem}.was-validated .form-select:invalid,.form-select.is-invalid{border-color:#ff511f}.was-validated .form-select:invalid:not([multiple]):not([size]),.was-validated .form-select:invalid:not([multiple])[size="1"],.form-select.is-invalid:not([multiple]):not([size]),.form-select.is-invalid:not([multiple])[size="1"]{padding-right:3.5rem;background-image:var(--t42-select-indicator),url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 12 12%27 width=%2712%27 height=%2712%27 fill=%27none%27 stroke=%27%23ff511f%27%3e%3ccircle cx=%276%27 cy=%276%27 r=%274.5%27/%3e%3cpath stroke-linejoin=%27round%27 d=%27M5.8 3.6h.4L6 6.5z%27/%3e%3ccircle cx=%276%27 cy=%278.2%27 r=%27.6%27 fill=%27%23ff511f%27 stroke=%27none%27/%3e%3c/svg%3e");background-position:right 0.5rem center,right 1.75rem center;background-size:1rem,1rem}.was-validated .form-select:invalid:focus,.form-select.is-invalid:focus{border-color:#ff511f;box-shadow:0 0 0 0 rgba(255,81,31,0.25)}.was-validated .form-check-input:invalid,.form-check-input.is-invalid{border-color:#ff511f}.was-validated .form-check-input:invalid:checked,.form-check-input.is-invalid:checked{background-color:#ff511f}.was-validated .form-check-input:invalid:focus,.form-check-input.is-invalid:focus{box-shadow:0 0 0 0 rgba(255,81,31,0.25)}.was-validated .form-check-input:invalid ~ .form-check-label,.form-check-input.is-invalid ~ .form-check-label{color:#ff511f}.form-check-inline .form-check-input ~ .invalid-feedback{margin-left:.5em}.was-validated .input-group .form-control:invalid,.input-group .form-control.is-invalid,.was-validated .input-group .form-select:invalid,.input-group .form-select.is-invalid{z-index:2}.was-validated .input-group .form-control:invalid:focus,.input-group .form-control.is-invalid:focus,.was-validated .input-group .form-select:invalid:focus,.input-group .form-select.is-invalid:focus{z-index:3}input{background-color:var(--t42-input-bg)}input[type="number"]::-webkit-calendar-picker-indicator,input[type="datetime-local"]::-webkit-calendar-picker-indicator,input[type="month"]::-webkit-calendar-picker-indicator,input[type="week"]::-webkit-calendar-picker-indicator,input[type="time"]::-webkit-calendar-picker-indicator,input[type="date"]::-webkit-calendar-picker-indicator{background:transparent}input[type="number"]::-webkit-inner-spin-button,input[type="datetime-local"]::-webkit-inner-spin-button,input[type="month"]::-webkit-inner-spin-button,input[type="week"]::-webkit-inner-spin-button,input[type="time"]::-webkit-inner-spin-button,input[type="date"]::-webkit-inner-spin-button{appearance:none}input[type="color"],input[type="range"]{padding:0;border:0}form div[class^="col"]{position:relative}.form-check-label input[type="checkbox"],.form-check-label input[type="radio"]{margin-top:0.125rem;margin-left:-1.2rem;opacity:1}.form-check .form-check-input:disabled{opacity:0}.form-check-label{margin-bottom:0}.form-check-inline .form-check-label{padding-left:0.25rem}.form-check-inline input[type="radio"]:checked+label::after{left:-1rem}.form-control{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border;background-color:transparent}.form-control:disabled,.form-control.disabled,.form-control[readonly]{cursor:default;opacity:0.65}.form-control.is-valid,.form-control.is-invalid{border-color:var(--t42-color-opacity-10)}.form-control.is-valid:focus,.form-control.is-invalid:focus{border-color:var(--primary);box-shadow:none}.form-control[type="file"]{opacity:0}.form-text{color:var(--secondary)}.form-control-plaintext:focus{outline:0}select{background-image:var(--t42-select-indicator);background-repeat:no-repeat;background-position:right 0.5rem center;background-size:1rem;cursor:pointer;appearance:none}select[multiple]{padding:0;background-image:none}select[multiple] option{padding:0 0.875rem}select[multiple] option:checked{background-color:var(--primary)}select:disabled{border-color:transparent;cursor:default;opacity:0.65}textarea,textarea.form-control{min-height:90px;max-height:180px;padding-top:5px;padding-bottom:5px}textarea:disabled,textarea.form-control:disabled{border-color:transparent}input[type="range"]{width:100%;appearance:none}input[type="range"]:focus{background-color:transparent;outline:none}input[type="range"]:focus::-ms-fill-lower,input[type="range"]:focus::-ms-fill-upper{background:var(--primary)}input[type="range"]::-webkit-slider-runnable-track{width:100%;height:0.0625rem;border:0;border-radius:0;background:var(--t42-color-opacity-10);box-shadow:none;cursor:pointer}input[type="range"]::-webkit-slider-thumb{width:12px;height:12px;margin-top:-5px;border:0;border-radius:50%;background:var(--primary);box-shadow:none;cursor:pointer;appearance:none}input[type="range"]:focus::-webkit-slider-runnable-track{background:var(--t42-color-opacity-10)}input[type="range"]::-moz-range-track{width:100%;height:2px;border:0;border-radius:0;background:var(--t42-color-opacity-10);box-shadow:none;cursor:pointer}input[type="range"]::-moz-range-thumb{width:12px;height:12px;border:0;border-radius:50px;background:var(--primary);box-shadow:none;cursor:pointer}input[type="range"]::-ms-track{width:100%;height:2px;border-color:transparent;color:transparent;background:transparent;cursor:pointer}input[type="range"]::-ms-fill-lower,input[type="range"]::-ms-fill-upper{border:0;border-radius:0;background:var(--primary);box-shadow:none}input[type="range"]::-ms-thumb{width:12px;height:12px;border:0;border-radius:50px;background:var(--primary);box-shadow:none;cursor:pointer}input[type="checkbox"]{opacity:0}input[type="checkbox"]+label{position:relative;color:var(--t42-content-color-muted);cursor:pointer;user-select:none}input[type="checkbox"]+label::before{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, border-color;position:absolute;top:0.0625rem;left:-1.25rem;display:block;width:0.875rem;height:0.875rem;border:0.0625rem solid var(--t42-content-color-muted);border-radius:0;cursor:pointer;content:"";pointer-events:all}input[type="checkbox"]+label::after{position:absolute;top:0.125rem;left:-1.188rem;display:block;width:0.875rem;height:0.875rem;background-image:none;content:"";-webkit-mask-size:0.75rem;-webkit-mask-repeat:no-repeat;content:""}input[type="checkbox"].indeterminate+label::before,input[type="checkbox"]:indeterminate+label::before{border-color:var(--t42-color-opacity-30);background-color:var(--primary)}input[type="checkbox"].indeterminate+label::after,input[type="checkbox"]:indeterminate+label::after{top:0.375rem;left:-1.063rem;width:0.5rem;height:0.188rem;background-color:var(--white)}input[type="checkbox"]:disabled+label,input[type="checkbox"]:disabled+.form-check-label{color:var(--t42-content-color-disabled)}input[type="checkbox"]:checked.disabled+label,input[type="checkbox"]:checked:disabled+label,input[type="checkbox"]:indeterminate.disabled+label,input[type="checkbox"]:indeterminate:disabled+label,input[type="checkbox"].disabled+label,input[type="checkbox"]:disabled+label{color:var(--t42-content-color-disabled)}input[type="checkbox"]:checked.disabled+label::before,input[type="checkbox"]:checked:disabled+label::before,input[type="checkbox"]:indeterminate.disabled+label::before,input[type="checkbox"]:indeterminate:disabled+label::before,input[type="checkbox"].disabled+label::before,input[type="checkbox"]:disabled+label::before{border-color:transparent;background-color:var(--t42-color-opacity-10)}input[type="checkbox"]:checked+label::before{border-color:var(--t42-color-opacity-30);background-color:var(--primary)}input[type="checkbox"]:checked+label::after{background-color:var(--t42-link-color);-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M212.48599,435.14899c-11.60532,0.00003-21.16266-4.77866-28.672-14.336l-92.16-120.832 c-5.46133-8.19202-7.50933-17.06665-6.144-26.62399s5.80267-17.408,13.312-23.552s16.21333-8.53334,26.112-7.168 c9.89867,1.36533,17.92,6.14401,24.064,14.336l60.416,78.84799L360.966,93.13298c5.46133-8.192,12.79999-13.312,22.01599-15.36 s18.26132-0.68267,27.13599,4.096c8.19199,5.46133,13.31198,12.8,15.35999,22.016s0.68265,18.26133-4.09601,27.136l-179.2,286.71997 c-6.82668,10.9227-16.384,16.384-28.672,16.384L212.48599,435.14899z%27/%3E%3C/svg%3E")}input[type="radio"]{opacity:0}input[type="radio"]+label{position:relative;color:var(--t42-content-color-muted);cursor:pointer;user-select:none}input[type="radio"]+label::before{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, border;position:absolute;top:0.0625rem;left:-1.25rem;display:block;width:0.875rem;height:0.875rem;border:0.0625rem solid var(--t42-content-color-muted);border-radius:50%;cursor:pointer;content:"";pointer-events:all}input[type="radio"]+label::after{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, border;position:absolute;top:0.313rem;left:-1rem;display:block;width:0.375rem;height:0.375rem;border-radius:50%;color:var(--white);background-image:none;transform:scale(0);opacity:0;content:""}input[type="radio"]+label:focus{border-color:var(--primary)}input[type="radio"]:disabled+label,input[type="radio"]:disabled+.form-check-label{color:var(--t42-content-color-disabled)}input[type="radio"]:checked.disabled+label,input[type="radio"]:checked:disabled+label,input[type="radio"].disabled+label,input[type="radio"]:disabled+label{color:var(--t42-content-color-disabled)}input[type="radio"]:checked.disabled+label::before,input[type="radio"]:checked:disabled+label::before,input[type="radio"].disabled+label::before,input[type="radio"]:disabled+label::before{border-color:transparent;background-color:var(--t42-color-opacity-10)}input[type="radio"]:checked+label::before{border-color:var(--t42-color-opacity-30);background-color:var(--primary)}input[type="radio"]:checked+label::after{background-color:var(--white);transform:scale(1);opacity:1}.custom-control{padding-left:1.25rem}.custom-control .custom-control-input:checked ~ .custom-control-label::before{border-color:var(--t42-color-opacity-30)}.custom-select,.form-select{max-height:2rem;background-color:transparent;background-image:var(--t42-select-indicator);background-repeat:no-repeat;background-position:right 0.5rem center;background-size:1rem}.custom-select:focus,.custom-select option,.form-select:focus,.form-select option{background-color:var(--t42-input-bg)}.custom-select:disabled option,.form-select:disabled option{background-color:transparent}.custom-radio .custom-control-label{color:var(--t42-content-color-muted);user-select:none}.custom-radio .custom-control-label::after{background:none}.custom-radio .custom-control-input:checked ~ .custom-control-label::after{background-image:none}.custom-checkbox .custom-control-label{color:var(--t42-content-color-muted);user-select:none}.custom-checkbox .custom-control-label::after{background:none}.custom-checkbox .custom-control-input:checked ~ .custom-control-label::after{background-image:none}.custom-checkbox .custom-control-input:disabled .custom-control-label::after,.custom-checkbox .custom-control-input:disabled:checked ~ .custom-control-label::after,.custom-checkbox .custom-control-input:disabled:indeterminate ~ .custom-control-label::after{opacity:0.4}.custom-checkbox .custom-control-input:disabled ~ .custom-control-label::before{border-color:transparent}.switch{position:relative;display:inline-block;align-items:center;height:0.875rem;margin-bottom:0;padding-left:2rem;cursor:pointer}.switch.disabled{color:var(--t42-content-color-disabled)}.switch .slider{position:absolute;top:0;right:0;bottom:0;left:0;width:1.75rem;border:1px solid var(--t42-content-color-muted);cursor:pointer;transition:0.4s}.switch .slider::before{position:absolute;bottom:0.125rem;left:0.125rem;width:0.5rem;height:0.5rem;background-color:var(--t42-content-color-muted);transition:0.4s;content:""}.switch input{width:0;height:0;opacity:0}.switch input:checked+.slider{border:var(--t42-border);background-color:var(--primary)}.switch input:checked+.slider::before{background-color:var(--white);transform:translateX(0.875rem)}.switch input:focus+.slider{box-shadow:0 0 1px #2196f3}.switch input:disabled+.slider{border:var(--t42-border);background-color:var(--t42-color-opacity-10)}.switch input:disabled+.slider::before{background-color:var(--t42-color-opacity-20)}.input-group-prepend .input-group-text{justify-content:center;border-right:0}.input-group-append .input-group-text{justify-content:center;border-left:0}.input-group-append .custom-control,.input-group-prepend .custom-control{margin-bottom:0;padding-left:0.875rem}.input-group-append .custom-control-label,.input-group-prepend .custom-control-label{position:absolute;left:0;min-width:0.875rem;min-height:0.875rem}.input-group-append .custom-control-label::before,.input-group-prepend .custom-control-label::before{left:0}.input-group-append .custom-control-label::after,.input-group-prepend .custom-control-label::after{left:0.25rem}.input-group-append .custom-checkbox .custom-control-label::after,.input-group-prepend .custom-checkbox .custom-control-label::after{left:0.125rem}.custom-file{margin-bottom:1rem}.custom-file-input,.form-control[type="file"]{z-index:1}.custom-file-input:focus ~ .custom-file-label,.form-control[type="file"]:focus ~ .custom-file-label{background-color:var(--t42-input-bg)}.custom-file-label,.input-group-text{background-color:transparent}.custom-file-label::after,.input-group-text::after{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color;background-color:Rgba(--secondary, 0.05);cursor:pointer}.custom-file-label:hover::after,.input-group-text:hover::after{color:var(--white);background-color:var(--secondary)}.form-control[type="file"]+.input-group-text{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color,color;position:absolute;top:0;right:0;left:0;z-index:1;height:2rem;padding:0.375rem 0.875rem;border:var(--t42-border);color:var(--t42-content-color-muted)}.form-control[type="file"]+.input-group-text::after{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color,color;position:absolute;top:0;right:0;bottom:0;z-index:3;display:block;height:100%;padding:0.375rem 0.875rem;border-left:inherit;color:var(--t42-link-color);line-height:1.5;cursor:pointer;content:"Browse"}.form-control[type="file"]+.input-group-text:hover{background-color:var(--t42-input-bg)}.form-control[type="file"]+.input-group-text:hover::after{color:var(--white);background-color:var(--secondary)}.custom-switch{padding-left:2rem}.custom-switch .custom-control-label::before{left:-2rem}.custom-switch .custom-control-label::after{top:0.25rem;left:-1.813rem;width:0.5rem;height:0.5rem}.custom-switch .custom-control-input:checked ~ .custom-control-label::after{background-color:var(--white);content:""}.custom-switch .custom-control-input:not(:disabled):active ~ .custom-control-label::before{border-color:var(--t42-color-opacity-30);background-color:var(--primary)}.valid-feedback,.valid-tooltip,.invalid-feedback,.invalid-tooltip,.warning-feedback,.warning-tooltip{position:absolute;bottom:-1rem;width:calc(100% - 1.875rem);margin-top:0;overflow:hidden;color:var(--t42-content-color);font-size:.7rem;white-space:nowrap;text-overflow:ellipsis}.valid-tooltip,.invalid-tooltip,.warning-tooltip{color:var(--t42-content-color-muted)}.custom-radio label+div,.custom-checkbox label+div,.form-check label+div{width:calc(100% + 1.25rem);transform:translateX(-1.25rem)}.form-group{margin-bottom:1rem}label{margin-bottom:0.5rem}.form-row{display:flex;flex-wrap:wrap;margin-right:-0.5rem;margin-left:-0.5rem}.form-row>.col,.form-row>[class*="col-"]{padding-right:0.5rem;padding-left:0.5rem}.form-inline{display:flex;flex-flow:row wrap;align-items:center}.form-inline .form-check{width:100%}@media (min-width: 576px){.form-inline label{display:flex;align-items:center;justify-content:center;margin-bottom:0}.form-inline .form-group{display:flex;flex:0 0 auto;flex-flow:row wrap;align-items:center;margin-bottom:0}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-plaintext{display:inline-block}.form-inline .input-group,.form-inline .custom-select,.form-inline .form-select{width:auto}.form-inline .form-check{display:flex;align-items:center;justify-content:center;width:auto;padding-left:0}.form-inline .form-check-input{position:relative;flex-shrink:0;margin-top:0;margin-left:0}.form-inline .custom-control{align-items:center;justify-content:center}.form-inline .custom-control-label{margin-bottom:0}}/*! + * Bootstrap Grid v5.1.3 (https://getbootstrap.com/) + * Copyright 2011-2021 The Bootstrap Authors + * Copyright 2011-2021 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) + */:root{--bs-blue: #007be5;--bs-indigo: #6610f2;--bs-purple: #6f42c1;--bs-pink: #fd397a;--bs-red: #ff511f;--bs-orange: #fd7e14;--bs-yellow: #f9a825;--bs-green: #43a047;--bs-teal: #616161;--bs-cyan: #469eb9;--bs-white: #fff;--bs-gray: #6c757d;--bs-gray-dark: #343a40;--bs-gray-100: #f8f9fa;--bs-gray-200: #e9ecef;--bs-gray-300: #dee2e6;--bs-gray-400: #ced4da;--bs-gray-500: #adb5bd;--bs-gray-600: #6c757d;--bs-gray-700: #495057;--bs-gray-800: #343a40;--bs-gray-900: #212529;--bs-primary: #007be5;--bs-secondary: #616161;--bs-success: #43a047;--bs-info: #469eb9;--bs-warning: #f9a825;--bs-danger: #ff511f;--bs-light: #616161;--bs-dark: #616161;--bs-primary-rgb: 0,123,229;--bs-secondary-rgb: 97,97,97;--bs-success-rgb: 67,160,71;--bs-info-rgb: 70,158,185;--bs-warning-rgb: 249,168,37;--bs-danger-rgb: 255,81,31;--bs-light-rgb: 97,97,97;--bs-dark-rgb: 97,97,97;--bs-white-rgb: 255,255,255;--bs-black-rgb: 0,0,0;--bs-body-color-rgb: 33,37,41;--bs-body-bg-rgb: 255,255,255;--bs-font-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--bs-gradient: linear-gradient(180deg, rgba(255,255,255,0.15), rgba(255,255,255,0));--bs-body-font-family: Montserrat,Helvetica Neue,Arial,sans-serif;--bs-body-font-size: .75rem;--bs-body-font-weight: 400;--bs-body-line-height: 1.5;--bs-body-color: #212529;--bs-body-bg: #fff}.container,.container-fluid,.container-sm,.container-md,.container-lg,.container-xl,.container-xxl{width:100%;padding-right:var(--bs-gutter-x, .75rem);padding-left:var(--bs-gutter-x, .75rem);margin-right:auto;margin-left:auto}@media (min-width: 576px){.container,.container-sm{max-width:540px}}@media (min-width: 768px){.container,.container-sm,.container-md{max-width:720px}}@media (min-width: 992px){.container,.container-sm,.container-md,.container-lg{max-width:960px}}@media (min-width: 1200px){.container,.container-sm,.container-md,.container-lg,.container-xl{max-width:1140px}}@media (min-width: 1400px){.container,.container-sm,.container-md,.container-lg,.container-xl,.container-xxl{max-width:1320px}}.row{--bs-gutter-x: 1.5rem;--bs-gutter-y: 0;display:flex;flex-wrap:wrap;margin-top:calc(-1 * var(--bs-gutter-y));margin-right:calc(-.5 * var(--bs-gutter-x));margin-left:calc(-.5 * var(--bs-gutter-x))}.row>*{box-sizing:border-box;flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--bs-gutter-x) * .5);padding-left:calc(var(--bs-gutter-x) * .5);margin-top:var(--bs-gutter-y)}.col{flex:1 0 0%}.row-cols-auto>*{flex:0 0 auto;width:auto}.row-cols-1>*{flex:0 0 auto;width:100%}.row-cols-2>*{flex:0 0 auto;width:50%}.row-cols-3>*{flex:0 0 auto;width:33.33333%}.row-cols-4>*{flex:0 0 auto;width:25%}.row-cols-5>*{flex:0 0 auto;width:20%}.row-cols-6>*{flex:0 0 auto;width:16.66667%}.col-auto{flex:0 0 auto;width:auto}.col-1{flex:0 0 auto;width:8.33333%}.col-2{flex:0 0 auto;width:16.66667%}.col-3{flex:0 0 auto;width:25%}.col-4{flex:0 0 auto;width:33.33333%}.col-5{flex:0 0 auto;width:41.66667%}.col-6{flex:0 0 auto;width:50%}.col-7{flex:0 0 auto;width:58.33333%}.col-8{flex:0 0 auto;width:66.66667%}.col-9{flex:0 0 auto;width:75%}.col-10{flex:0 0 auto;width:83.33333%}.col-11{flex:0 0 auto;width:91.66667%}.col-12{flex:0 0 auto;width:100%}.offset-1{margin-left:8.33333%}.offset-2{margin-left:16.66667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.33333%}.offset-5{margin-left:41.66667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.33333%}.offset-8{margin-left:66.66667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.33333%}.offset-11{margin-left:91.66667%}.g-0,.gx-0{--bs-gutter-x: 0}.g-0,.gy-0{--bs-gutter-y: 0}.g-1,.gx-1{--bs-gutter-x: .25rem}.g-1,.gy-1{--bs-gutter-y: .25rem}.g-2,.gx-2{--bs-gutter-x: .5rem}.g-2,.gy-2{--bs-gutter-y: .5rem}.g-3,.gx-3{--bs-gutter-x: 1rem}.g-3,.gy-3{--bs-gutter-y: 1rem}.g-4,.gx-4{--bs-gutter-x: 1.5rem}.g-4,.gy-4{--bs-gutter-y: 1.5rem}.g-5,.gx-5{--bs-gutter-x: 3rem}.g-5,.gy-5{--bs-gutter-y: 3rem}@media (min-width: 576px){.col-sm{flex:1 0 0%}.row-cols-sm-auto>*{flex:0 0 auto;width:auto}.row-cols-sm-1>*{flex:0 0 auto;width:100%}.row-cols-sm-2>*{flex:0 0 auto;width:50%}.row-cols-sm-3>*{flex:0 0 auto;width:33.33333%}.row-cols-sm-4>*{flex:0 0 auto;width:25%}.row-cols-sm-5>*{flex:0 0 auto;width:20%}.row-cols-sm-6>*{flex:0 0 auto;width:16.66667%}.col-sm-auto{flex:0 0 auto;width:auto}.col-sm-1{flex:0 0 auto;width:8.33333%}.col-sm-2{flex:0 0 auto;width:16.66667%}.col-sm-3{flex:0 0 auto;width:25%}.col-sm-4{flex:0 0 auto;width:33.33333%}.col-sm-5{flex:0 0 auto;width:41.66667%}.col-sm-6{flex:0 0 auto;width:50%}.col-sm-7{flex:0 0 auto;width:58.33333%}.col-sm-8{flex:0 0 auto;width:66.66667%}.col-sm-9{flex:0 0 auto;width:75%}.col-sm-10{flex:0 0 auto;width:83.33333%}.col-sm-11{flex:0 0 auto;width:91.66667%}.col-sm-12{flex:0 0 auto;width:100%}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.33333%}.offset-sm-2{margin-left:16.66667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.33333%}.offset-sm-5{margin-left:41.66667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.33333%}.offset-sm-8{margin-left:66.66667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.33333%}.offset-sm-11{margin-left:91.66667%}.g-sm-0,.gx-sm-0{--bs-gutter-x: 0}.g-sm-0,.gy-sm-0{--bs-gutter-y: 0}.g-sm-1,.gx-sm-1{--bs-gutter-x: .25rem}.g-sm-1,.gy-sm-1{--bs-gutter-y: .25rem}.g-sm-2,.gx-sm-2{--bs-gutter-x: .5rem}.g-sm-2,.gy-sm-2{--bs-gutter-y: .5rem}.g-sm-3,.gx-sm-3{--bs-gutter-x: 1rem}.g-sm-3,.gy-sm-3{--bs-gutter-y: 1rem}.g-sm-4,.gx-sm-4{--bs-gutter-x: 1.5rem}.g-sm-4,.gy-sm-4{--bs-gutter-y: 1.5rem}.g-sm-5,.gx-sm-5{--bs-gutter-x: 3rem}.g-sm-5,.gy-sm-5{--bs-gutter-y: 3rem}}@media (min-width: 768px){.col-md{flex:1 0 0%}.row-cols-md-auto>*{flex:0 0 auto;width:auto}.row-cols-md-1>*{flex:0 0 auto;width:100%}.row-cols-md-2>*{flex:0 0 auto;width:50%}.row-cols-md-3>*{flex:0 0 auto;width:33.33333%}.row-cols-md-4>*{flex:0 0 auto;width:25%}.row-cols-md-5>*{flex:0 0 auto;width:20%}.row-cols-md-6>*{flex:0 0 auto;width:16.66667%}.col-md-auto{flex:0 0 auto;width:auto}.col-md-1{flex:0 0 auto;width:8.33333%}.col-md-2{flex:0 0 auto;width:16.66667%}.col-md-3{flex:0 0 auto;width:25%}.col-md-4{flex:0 0 auto;width:33.33333%}.col-md-5{flex:0 0 auto;width:41.66667%}.col-md-6{flex:0 0 auto;width:50%}.col-md-7{flex:0 0 auto;width:58.33333%}.col-md-8{flex:0 0 auto;width:66.66667%}.col-md-9{flex:0 0 auto;width:75%}.col-md-10{flex:0 0 auto;width:83.33333%}.col-md-11{flex:0 0 auto;width:91.66667%}.col-md-12{flex:0 0 auto;width:100%}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.33333%}.offset-md-2{margin-left:16.66667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.33333%}.offset-md-5{margin-left:41.66667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.33333%}.offset-md-8{margin-left:66.66667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.33333%}.offset-md-11{margin-left:91.66667%}.g-md-0,.gx-md-0{--bs-gutter-x: 0}.g-md-0,.gy-md-0{--bs-gutter-y: 0}.g-md-1,.gx-md-1{--bs-gutter-x: .25rem}.g-md-1,.gy-md-1{--bs-gutter-y: .25rem}.g-md-2,.gx-md-2{--bs-gutter-x: .5rem}.g-md-2,.gy-md-2{--bs-gutter-y: .5rem}.g-md-3,.gx-md-3{--bs-gutter-x: 1rem}.g-md-3,.gy-md-3{--bs-gutter-y: 1rem}.g-md-4,.gx-md-4{--bs-gutter-x: 1.5rem}.g-md-4,.gy-md-4{--bs-gutter-y: 1.5rem}.g-md-5,.gx-md-5{--bs-gutter-x: 3rem}.g-md-5,.gy-md-5{--bs-gutter-y: 3rem}}@media (min-width: 992px){.col-lg{flex:1 0 0%}.row-cols-lg-auto>*{flex:0 0 auto;width:auto}.row-cols-lg-1>*{flex:0 0 auto;width:100%}.row-cols-lg-2>*{flex:0 0 auto;width:50%}.row-cols-lg-3>*{flex:0 0 auto;width:33.33333%}.row-cols-lg-4>*{flex:0 0 auto;width:25%}.row-cols-lg-5>*{flex:0 0 auto;width:20%}.row-cols-lg-6>*{flex:0 0 auto;width:16.66667%}.col-lg-auto{flex:0 0 auto;width:auto}.col-lg-1{flex:0 0 auto;width:8.33333%}.col-lg-2{flex:0 0 auto;width:16.66667%}.col-lg-3{flex:0 0 auto;width:25%}.col-lg-4{flex:0 0 auto;width:33.33333%}.col-lg-5{flex:0 0 auto;width:41.66667%}.col-lg-6{flex:0 0 auto;width:50%}.col-lg-7{flex:0 0 auto;width:58.33333%}.col-lg-8{flex:0 0 auto;width:66.66667%}.col-lg-9{flex:0 0 auto;width:75%}.col-lg-10{flex:0 0 auto;width:83.33333%}.col-lg-11{flex:0 0 auto;width:91.66667%}.col-lg-12{flex:0 0 auto;width:100%}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.33333%}.offset-lg-2{margin-left:16.66667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.33333%}.offset-lg-5{margin-left:41.66667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.33333%}.offset-lg-8{margin-left:66.66667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.33333%}.offset-lg-11{margin-left:91.66667%}.g-lg-0,.gx-lg-0{--bs-gutter-x: 0}.g-lg-0,.gy-lg-0{--bs-gutter-y: 0}.g-lg-1,.gx-lg-1{--bs-gutter-x: .25rem}.g-lg-1,.gy-lg-1{--bs-gutter-y: .25rem}.g-lg-2,.gx-lg-2{--bs-gutter-x: .5rem}.g-lg-2,.gy-lg-2{--bs-gutter-y: .5rem}.g-lg-3,.gx-lg-3{--bs-gutter-x: 1rem}.g-lg-3,.gy-lg-3{--bs-gutter-y: 1rem}.g-lg-4,.gx-lg-4{--bs-gutter-x: 1.5rem}.g-lg-4,.gy-lg-4{--bs-gutter-y: 1.5rem}.g-lg-5,.gx-lg-5{--bs-gutter-x: 3rem}.g-lg-5,.gy-lg-5{--bs-gutter-y: 3rem}}@media (min-width: 1200px){.col-xl{flex:1 0 0%}.row-cols-xl-auto>*{flex:0 0 auto;width:auto}.row-cols-xl-1>*{flex:0 0 auto;width:100%}.row-cols-xl-2>*{flex:0 0 auto;width:50%}.row-cols-xl-3>*{flex:0 0 auto;width:33.33333%}.row-cols-xl-4>*{flex:0 0 auto;width:25%}.row-cols-xl-5>*{flex:0 0 auto;width:20%}.row-cols-xl-6>*{flex:0 0 auto;width:16.66667%}.col-xl-auto{flex:0 0 auto;width:auto}.col-xl-1{flex:0 0 auto;width:8.33333%}.col-xl-2{flex:0 0 auto;width:16.66667%}.col-xl-3{flex:0 0 auto;width:25%}.col-xl-4{flex:0 0 auto;width:33.33333%}.col-xl-5{flex:0 0 auto;width:41.66667%}.col-xl-6{flex:0 0 auto;width:50%}.col-xl-7{flex:0 0 auto;width:58.33333%}.col-xl-8{flex:0 0 auto;width:66.66667%}.col-xl-9{flex:0 0 auto;width:75%}.col-xl-10{flex:0 0 auto;width:83.33333%}.col-xl-11{flex:0 0 auto;width:91.66667%}.col-xl-12{flex:0 0 auto;width:100%}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.33333%}.offset-xl-2{margin-left:16.66667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.33333%}.offset-xl-5{margin-left:41.66667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.33333%}.offset-xl-8{margin-left:66.66667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.33333%}.offset-xl-11{margin-left:91.66667%}.g-xl-0,.gx-xl-0{--bs-gutter-x: 0}.g-xl-0,.gy-xl-0{--bs-gutter-y: 0}.g-xl-1,.gx-xl-1{--bs-gutter-x: .25rem}.g-xl-1,.gy-xl-1{--bs-gutter-y: .25rem}.g-xl-2,.gx-xl-2{--bs-gutter-x: .5rem}.g-xl-2,.gy-xl-2{--bs-gutter-y: .5rem}.g-xl-3,.gx-xl-3{--bs-gutter-x: 1rem}.g-xl-3,.gy-xl-3{--bs-gutter-y: 1rem}.g-xl-4,.gx-xl-4{--bs-gutter-x: 1.5rem}.g-xl-4,.gy-xl-4{--bs-gutter-y: 1.5rem}.g-xl-5,.gx-xl-5{--bs-gutter-x: 3rem}.g-xl-5,.gy-xl-5{--bs-gutter-y: 3rem}}@media (min-width: 1400px){.col-xxl{flex:1 0 0%}.row-cols-xxl-auto>*{flex:0 0 auto;width:auto}.row-cols-xxl-1>*{flex:0 0 auto;width:100%}.row-cols-xxl-2>*{flex:0 0 auto;width:50%}.row-cols-xxl-3>*{flex:0 0 auto;width:33.33333%}.row-cols-xxl-4>*{flex:0 0 auto;width:25%}.row-cols-xxl-5>*{flex:0 0 auto;width:20%}.row-cols-xxl-6>*{flex:0 0 auto;width:16.66667%}.col-xxl-auto{flex:0 0 auto;width:auto}.col-xxl-1{flex:0 0 auto;width:8.33333%}.col-xxl-2{flex:0 0 auto;width:16.66667%}.col-xxl-3{flex:0 0 auto;width:25%}.col-xxl-4{flex:0 0 auto;width:33.33333%}.col-xxl-5{flex:0 0 auto;width:41.66667%}.col-xxl-6{flex:0 0 auto;width:50%}.col-xxl-7{flex:0 0 auto;width:58.33333%}.col-xxl-8{flex:0 0 auto;width:66.66667%}.col-xxl-9{flex:0 0 auto;width:75%}.col-xxl-10{flex:0 0 auto;width:83.33333%}.col-xxl-11{flex:0 0 auto;width:91.66667%}.col-xxl-12{flex:0 0 auto;width:100%}.offset-xxl-0{margin-left:0}.offset-xxl-1{margin-left:8.33333%}.offset-xxl-2{margin-left:16.66667%}.offset-xxl-3{margin-left:25%}.offset-xxl-4{margin-left:33.33333%}.offset-xxl-5{margin-left:41.66667%}.offset-xxl-6{margin-left:50%}.offset-xxl-7{margin-left:58.33333%}.offset-xxl-8{margin-left:66.66667%}.offset-xxl-9{margin-left:75%}.offset-xxl-10{margin-left:83.33333%}.offset-xxl-11{margin-left:91.66667%}.g-xxl-0,.gx-xxl-0{--bs-gutter-x: 0}.g-xxl-0,.gy-xxl-0{--bs-gutter-y: 0}.g-xxl-1,.gx-xxl-1{--bs-gutter-x: .25rem}.g-xxl-1,.gy-xxl-1{--bs-gutter-y: .25rem}.g-xxl-2,.gx-xxl-2{--bs-gutter-x: .5rem}.g-xxl-2,.gy-xxl-2{--bs-gutter-y: .5rem}.g-xxl-3,.gx-xxl-3{--bs-gutter-x: 1rem}.g-xxl-3,.gy-xxl-3{--bs-gutter-y: 1rem}.g-xxl-4,.gx-xxl-4{--bs-gutter-x: 1.5rem}.g-xxl-4,.gy-xxl-4{--bs-gutter-y: 1.5rem}.g-xxl-5,.gx-xxl-5{--bs-gutter-x: 3rem}.g-xxl-5,.gy-xxl-5{--bs-gutter-y: 3rem}}.d-inline{display:inline !important}.d-inline-block{display:inline-block !important}.d-block{display:block !important}.d-grid{display:grid !important}.d-table{display:table !important}.d-table-row{display:table-row !important}.d-table-cell{display:table-cell !important}.d-flex{display:flex !important}.d-inline-flex{display:inline-flex !important}.d-none{display:none !important}.flex-fill{flex:1 1 auto !important}.flex-row{flex-direction:row !important}.flex-column{flex-direction:column !important}.flex-row-reverse{flex-direction:row-reverse !important}.flex-column-reverse{flex-direction:column-reverse !important}.flex-grow-0{flex-grow:0 !important}.flex-grow-1{flex-grow:1 !important}.flex-shrink-0{flex-shrink:0 !important}.flex-shrink-1{flex-shrink:1 !important}.flex-wrap{flex-wrap:wrap !important}.flex-nowrap{flex-wrap:nowrap !important}.flex-wrap-reverse{flex-wrap:wrap-reverse !important}.justify-content-start{justify-content:flex-start !important}.justify-content-end{justify-content:flex-end !important}.justify-content-center{justify-content:center !important}.justify-content-between{justify-content:space-between !important}.justify-content-around{justify-content:space-around !important}.justify-content-evenly{justify-content:space-evenly !important}.align-items-start{align-items:flex-start !important}.align-items-end{align-items:flex-end !important}.align-items-center{align-items:center !important}.align-items-baseline{align-items:baseline !important}.align-items-stretch{align-items:stretch !important}.align-content-start{align-content:flex-start !important}.align-content-end{align-content:flex-end !important}.align-content-center{align-content:center !important}.align-content-between{align-content:space-between !important}.align-content-around{align-content:space-around !important}.align-content-stretch{align-content:stretch !important}.align-self-auto{align-self:auto !important}.align-self-start{align-self:flex-start !important}.align-self-end{align-self:flex-end !important}.align-self-center{align-self:center !important}.align-self-baseline{align-self:baseline !important}.align-self-stretch{align-self:stretch !important}.order-first{order:-1 !important}.order-0{order:0 !important}.order-1{order:1 !important}.order-2{order:2 !important}.order-3{order:3 !important}.order-4{order:4 !important}.order-5{order:5 !important}.order-last{order:6 !important}.m-0{margin:0 !important}.m-1{margin:.25rem !important}.m-2{margin:.5rem !important}.m-3{margin:1rem !important}.m-4{margin:1.5rem !important}.m-5{margin:3rem !important}.m-auto{margin:auto !important}.mx-0{margin-right:0 !important;margin-left:0 !important}.mx-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-3{margin-right:1rem !important;margin-left:1rem !important}.mx-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-5{margin-right:3rem !important;margin-left:3rem !important}.mx-auto{margin-right:auto !important;margin-left:auto !important}.my-0{margin-top:0 !important;margin-bottom:0 !important}.my-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-0{margin-top:0 !important}.mt-1{margin-top:.25rem !important}.mt-2{margin-top:.5rem !important}.mt-3{margin-top:1rem !important}.mt-4{margin-top:1.5rem !important}.mt-5{margin-top:3rem !important}.mt-auto{margin-top:auto !important}.me-0{margin-right:0 !important}.me-1{margin-right:.25rem !important}.me-2{margin-right:.5rem !important}.me-3{margin-right:1rem !important}.me-4{margin-right:1.5rem !important}.me-5{margin-right:3rem !important}.me-auto{margin-right:auto !important}.mb-0{margin-bottom:0 !important}.mb-1{margin-bottom:.25rem !important}.mb-2{margin-bottom:.5rem !important}.mb-3{margin-bottom:1rem !important}.mb-4{margin-bottom:1.5rem !important}.mb-5{margin-bottom:3rem !important}.mb-auto{margin-bottom:auto !important}.ms-0{margin-left:0 !important}.ms-1{margin-left:.25rem !important}.ms-2{margin-left:.5rem !important}.ms-3{margin-left:1rem !important}.ms-4{margin-left:1.5rem !important}.ms-5{margin-left:3rem !important}.ms-auto{margin-left:auto !important}.p-0{padding:0 !important}.p-1{padding:.25rem !important}.p-2{padding:.5rem !important}.p-3{padding:1rem !important}.p-4{padding:1.5rem !important}.p-5{padding:3rem !important}.px-0{padding-right:0 !important;padding-left:0 !important}.px-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-3{padding-right:1rem !important;padding-left:1rem !important}.px-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-5{padding-right:3rem !important;padding-left:3rem !important}.py-0{padding-top:0 !important;padding-bottom:0 !important}.py-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-0{padding-top:0 !important}.pt-1{padding-top:.25rem !important}.pt-2{padding-top:.5rem !important}.pt-3{padding-top:1rem !important}.pt-4{padding-top:1.5rem !important}.pt-5{padding-top:3rem !important}.pe-0{padding-right:0 !important}.pe-1{padding-right:.25rem !important}.pe-2{padding-right:.5rem !important}.pe-3{padding-right:1rem !important}.pe-4{padding-right:1.5rem !important}.pe-5{padding-right:3rem !important}.pb-0{padding-bottom:0 !important}.pb-1{padding-bottom:.25rem !important}.pb-2{padding-bottom:.5rem !important}.pb-3{padding-bottom:1rem !important}.pb-4{padding-bottom:1.5rem !important}.pb-5{padding-bottom:3rem !important}.ps-0{padding-left:0 !important}.ps-1{padding-left:.25rem !important}.ps-2{padding-left:.5rem !important}.ps-3{padding-left:1rem !important}.ps-4{padding-left:1.5rem !important}.ps-5{padding-left:3rem !important}@media (min-width: 576px){.d-sm-inline{display:inline !important}.d-sm-inline-block{display:inline-block !important}.d-sm-block{display:block !important}.d-sm-grid{display:grid !important}.d-sm-table{display:table !important}.d-sm-table-row{display:table-row !important}.d-sm-table-cell{display:table-cell !important}.d-sm-flex{display:flex !important}.d-sm-inline-flex{display:inline-flex !important}.d-sm-none{display:none !important}.flex-sm-fill{flex:1 1 auto !important}.flex-sm-row{flex-direction:row !important}.flex-sm-column{flex-direction:column !important}.flex-sm-row-reverse{flex-direction:row-reverse !important}.flex-sm-column-reverse{flex-direction:column-reverse !important}.flex-sm-grow-0{flex-grow:0 !important}.flex-sm-grow-1{flex-grow:1 !important}.flex-sm-shrink-0{flex-shrink:0 !important}.flex-sm-shrink-1{flex-shrink:1 !important}.flex-sm-wrap{flex-wrap:wrap !important}.flex-sm-nowrap{flex-wrap:nowrap !important}.flex-sm-wrap-reverse{flex-wrap:wrap-reverse !important}.justify-content-sm-start{justify-content:flex-start !important}.justify-content-sm-end{justify-content:flex-end !important}.justify-content-sm-center{justify-content:center !important}.justify-content-sm-between{justify-content:space-between !important}.justify-content-sm-around{justify-content:space-around !important}.justify-content-sm-evenly{justify-content:space-evenly !important}.align-items-sm-start{align-items:flex-start !important}.align-items-sm-end{align-items:flex-end !important}.align-items-sm-center{align-items:center !important}.align-items-sm-baseline{align-items:baseline !important}.align-items-sm-stretch{align-items:stretch !important}.align-content-sm-start{align-content:flex-start !important}.align-content-sm-end{align-content:flex-end !important}.align-content-sm-center{align-content:center !important}.align-content-sm-between{align-content:space-between !important}.align-content-sm-around{align-content:space-around !important}.align-content-sm-stretch{align-content:stretch !important}.align-self-sm-auto{align-self:auto !important}.align-self-sm-start{align-self:flex-start !important}.align-self-sm-end{align-self:flex-end !important}.align-self-sm-center{align-self:center !important}.align-self-sm-baseline{align-self:baseline !important}.align-self-sm-stretch{align-self:stretch !important}.order-sm-first{order:-1 !important}.order-sm-0{order:0 !important}.order-sm-1{order:1 !important}.order-sm-2{order:2 !important}.order-sm-3{order:3 !important}.order-sm-4{order:4 !important}.order-sm-5{order:5 !important}.order-sm-last{order:6 !important}.m-sm-0{margin:0 !important}.m-sm-1{margin:.25rem !important}.m-sm-2{margin:.5rem !important}.m-sm-3{margin:1rem !important}.m-sm-4{margin:1.5rem !important}.m-sm-5{margin:3rem !important}.m-sm-auto{margin:auto !important}.mx-sm-0{margin-right:0 !important;margin-left:0 !important}.mx-sm-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-sm-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-sm-3{margin-right:1rem !important;margin-left:1rem !important}.mx-sm-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-sm-5{margin-right:3rem !important;margin-left:3rem !important}.mx-sm-auto{margin-right:auto !important;margin-left:auto !important}.my-sm-0{margin-top:0 !important;margin-bottom:0 !important}.my-sm-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-sm-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-sm-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-sm-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-sm-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-sm-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-sm-0{margin-top:0 !important}.mt-sm-1{margin-top:.25rem !important}.mt-sm-2{margin-top:.5rem !important}.mt-sm-3{margin-top:1rem !important}.mt-sm-4{margin-top:1.5rem !important}.mt-sm-5{margin-top:3rem !important}.mt-sm-auto{margin-top:auto !important}.me-sm-0{margin-right:0 !important}.me-sm-1{margin-right:.25rem !important}.me-sm-2{margin-right:.5rem !important}.me-sm-3{margin-right:1rem !important}.me-sm-4{margin-right:1.5rem !important}.me-sm-5{margin-right:3rem !important}.me-sm-auto{margin-right:auto !important}.mb-sm-0{margin-bottom:0 !important}.mb-sm-1{margin-bottom:.25rem !important}.mb-sm-2{margin-bottom:.5rem !important}.mb-sm-3{margin-bottom:1rem !important}.mb-sm-4{margin-bottom:1.5rem !important}.mb-sm-5{margin-bottom:3rem !important}.mb-sm-auto{margin-bottom:auto !important}.ms-sm-0{margin-left:0 !important}.ms-sm-1{margin-left:.25rem !important}.ms-sm-2{margin-left:.5rem !important}.ms-sm-3{margin-left:1rem !important}.ms-sm-4{margin-left:1.5rem !important}.ms-sm-5{margin-left:3rem !important}.ms-sm-auto{margin-left:auto !important}.p-sm-0{padding:0 !important}.p-sm-1{padding:.25rem !important}.p-sm-2{padding:.5rem !important}.p-sm-3{padding:1rem !important}.p-sm-4{padding:1.5rem !important}.p-sm-5{padding:3rem !important}.px-sm-0{padding-right:0 !important;padding-left:0 !important}.px-sm-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-sm-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-sm-3{padding-right:1rem !important;padding-left:1rem !important}.px-sm-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-sm-5{padding-right:3rem !important;padding-left:3rem !important}.py-sm-0{padding-top:0 !important;padding-bottom:0 !important}.py-sm-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-sm-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-sm-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-sm-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-sm-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-sm-0{padding-top:0 !important}.pt-sm-1{padding-top:.25rem !important}.pt-sm-2{padding-top:.5rem !important}.pt-sm-3{padding-top:1rem !important}.pt-sm-4{padding-top:1.5rem !important}.pt-sm-5{padding-top:3rem !important}.pe-sm-0{padding-right:0 !important}.pe-sm-1{padding-right:.25rem !important}.pe-sm-2{padding-right:.5rem !important}.pe-sm-3{padding-right:1rem !important}.pe-sm-4{padding-right:1.5rem !important}.pe-sm-5{padding-right:3rem !important}.pb-sm-0{padding-bottom:0 !important}.pb-sm-1{padding-bottom:.25rem !important}.pb-sm-2{padding-bottom:.5rem !important}.pb-sm-3{padding-bottom:1rem !important}.pb-sm-4{padding-bottom:1.5rem !important}.pb-sm-5{padding-bottom:3rem !important}.ps-sm-0{padding-left:0 !important}.ps-sm-1{padding-left:.25rem !important}.ps-sm-2{padding-left:.5rem !important}.ps-sm-3{padding-left:1rem !important}.ps-sm-4{padding-left:1.5rem !important}.ps-sm-5{padding-left:3rem !important}}@media (min-width: 768px){.d-md-inline{display:inline !important}.d-md-inline-block{display:inline-block !important}.d-md-block{display:block !important}.d-md-grid{display:grid !important}.d-md-table{display:table !important}.d-md-table-row{display:table-row !important}.d-md-table-cell{display:table-cell !important}.d-md-flex{display:flex !important}.d-md-inline-flex{display:inline-flex !important}.d-md-none{display:none !important}.flex-md-fill{flex:1 1 auto !important}.flex-md-row{flex-direction:row !important}.flex-md-column{flex-direction:column !important}.flex-md-row-reverse{flex-direction:row-reverse !important}.flex-md-column-reverse{flex-direction:column-reverse !important}.flex-md-grow-0{flex-grow:0 !important}.flex-md-grow-1{flex-grow:1 !important}.flex-md-shrink-0{flex-shrink:0 !important}.flex-md-shrink-1{flex-shrink:1 !important}.flex-md-wrap{flex-wrap:wrap !important}.flex-md-nowrap{flex-wrap:nowrap !important}.flex-md-wrap-reverse{flex-wrap:wrap-reverse !important}.justify-content-md-start{justify-content:flex-start !important}.justify-content-md-end{justify-content:flex-end !important}.justify-content-md-center{justify-content:center !important}.justify-content-md-between{justify-content:space-between !important}.justify-content-md-around{justify-content:space-around !important}.justify-content-md-evenly{justify-content:space-evenly !important}.align-items-md-start{align-items:flex-start !important}.align-items-md-end{align-items:flex-end !important}.align-items-md-center{align-items:center !important}.align-items-md-baseline{align-items:baseline !important}.align-items-md-stretch{align-items:stretch !important}.align-content-md-start{align-content:flex-start !important}.align-content-md-end{align-content:flex-end !important}.align-content-md-center{align-content:center !important}.align-content-md-between{align-content:space-between !important}.align-content-md-around{align-content:space-around !important}.align-content-md-stretch{align-content:stretch !important}.align-self-md-auto{align-self:auto !important}.align-self-md-start{align-self:flex-start !important}.align-self-md-end{align-self:flex-end !important}.align-self-md-center{align-self:center !important}.align-self-md-baseline{align-self:baseline !important}.align-self-md-stretch{align-self:stretch !important}.order-md-first{order:-1 !important}.order-md-0{order:0 !important}.order-md-1{order:1 !important}.order-md-2{order:2 !important}.order-md-3{order:3 !important}.order-md-4{order:4 !important}.order-md-5{order:5 !important}.order-md-last{order:6 !important}.m-md-0{margin:0 !important}.m-md-1{margin:.25rem !important}.m-md-2{margin:.5rem !important}.m-md-3{margin:1rem !important}.m-md-4{margin:1.5rem !important}.m-md-5{margin:3rem !important}.m-md-auto{margin:auto !important}.mx-md-0{margin-right:0 !important;margin-left:0 !important}.mx-md-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-md-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-md-3{margin-right:1rem !important;margin-left:1rem !important}.mx-md-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-md-5{margin-right:3rem !important;margin-left:3rem !important}.mx-md-auto{margin-right:auto !important;margin-left:auto !important}.my-md-0{margin-top:0 !important;margin-bottom:0 !important}.my-md-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-md-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-md-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-md-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-md-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-md-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-md-0{margin-top:0 !important}.mt-md-1{margin-top:.25rem !important}.mt-md-2{margin-top:.5rem !important}.mt-md-3{margin-top:1rem !important}.mt-md-4{margin-top:1.5rem !important}.mt-md-5{margin-top:3rem !important}.mt-md-auto{margin-top:auto !important}.me-md-0{margin-right:0 !important}.me-md-1{margin-right:.25rem !important}.me-md-2{margin-right:.5rem !important}.me-md-3{margin-right:1rem !important}.me-md-4{margin-right:1.5rem !important}.me-md-5{margin-right:3rem !important}.me-md-auto{margin-right:auto !important}.mb-md-0{margin-bottom:0 !important}.mb-md-1{margin-bottom:.25rem !important}.mb-md-2{margin-bottom:.5rem !important}.mb-md-3{margin-bottom:1rem !important}.mb-md-4{margin-bottom:1.5rem !important}.mb-md-5{margin-bottom:3rem !important}.mb-md-auto{margin-bottom:auto !important}.ms-md-0{margin-left:0 !important}.ms-md-1{margin-left:.25rem !important}.ms-md-2{margin-left:.5rem !important}.ms-md-3{margin-left:1rem !important}.ms-md-4{margin-left:1.5rem !important}.ms-md-5{margin-left:3rem !important}.ms-md-auto{margin-left:auto !important}.p-md-0{padding:0 !important}.p-md-1{padding:.25rem !important}.p-md-2{padding:.5rem !important}.p-md-3{padding:1rem !important}.p-md-4{padding:1.5rem !important}.p-md-5{padding:3rem !important}.px-md-0{padding-right:0 !important;padding-left:0 !important}.px-md-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-md-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-md-3{padding-right:1rem !important;padding-left:1rem !important}.px-md-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-md-5{padding-right:3rem !important;padding-left:3rem !important}.py-md-0{padding-top:0 !important;padding-bottom:0 !important}.py-md-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-md-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-md-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-md-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-md-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-md-0{padding-top:0 !important}.pt-md-1{padding-top:.25rem !important}.pt-md-2{padding-top:.5rem !important}.pt-md-3{padding-top:1rem !important}.pt-md-4{padding-top:1.5rem !important}.pt-md-5{padding-top:3rem !important}.pe-md-0{padding-right:0 !important}.pe-md-1{padding-right:.25rem !important}.pe-md-2{padding-right:.5rem !important}.pe-md-3{padding-right:1rem !important}.pe-md-4{padding-right:1.5rem !important}.pe-md-5{padding-right:3rem !important}.pb-md-0{padding-bottom:0 !important}.pb-md-1{padding-bottom:.25rem !important}.pb-md-2{padding-bottom:.5rem !important}.pb-md-3{padding-bottom:1rem !important}.pb-md-4{padding-bottom:1.5rem !important}.pb-md-5{padding-bottom:3rem !important}.ps-md-0{padding-left:0 !important}.ps-md-1{padding-left:.25rem !important}.ps-md-2{padding-left:.5rem !important}.ps-md-3{padding-left:1rem !important}.ps-md-4{padding-left:1.5rem !important}.ps-md-5{padding-left:3rem !important}}@media (min-width: 992px){.d-lg-inline{display:inline !important}.d-lg-inline-block{display:inline-block !important}.d-lg-block{display:block !important}.d-lg-grid{display:grid !important}.d-lg-table{display:table !important}.d-lg-table-row{display:table-row !important}.d-lg-table-cell{display:table-cell !important}.d-lg-flex{display:flex !important}.d-lg-inline-flex{display:inline-flex !important}.d-lg-none{display:none !important}.flex-lg-fill{flex:1 1 auto !important}.flex-lg-row{flex-direction:row !important}.flex-lg-column{flex-direction:column !important}.flex-lg-row-reverse{flex-direction:row-reverse !important}.flex-lg-column-reverse{flex-direction:column-reverse !important}.flex-lg-grow-0{flex-grow:0 !important}.flex-lg-grow-1{flex-grow:1 !important}.flex-lg-shrink-0{flex-shrink:0 !important}.flex-lg-shrink-1{flex-shrink:1 !important}.flex-lg-wrap{flex-wrap:wrap !important}.flex-lg-nowrap{flex-wrap:nowrap !important}.flex-lg-wrap-reverse{flex-wrap:wrap-reverse !important}.justify-content-lg-start{justify-content:flex-start !important}.justify-content-lg-end{justify-content:flex-end !important}.justify-content-lg-center{justify-content:center !important}.justify-content-lg-between{justify-content:space-between !important}.justify-content-lg-around{justify-content:space-around !important}.justify-content-lg-evenly{justify-content:space-evenly !important}.align-items-lg-start{align-items:flex-start !important}.align-items-lg-end{align-items:flex-end !important}.align-items-lg-center{align-items:center !important}.align-items-lg-baseline{align-items:baseline !important}.align-items-lg-stretch{align-items:stretch !important}.align-content-lg-start{align-content:flex-start !important}.align-content-lg-end{align-content:flex-end !important}.align-content-lg-center{align-content:center !important}.align-content-lg-between{align-content:space-between !important}.align-content-lg-around{align-content:space-around !important}.align-content-lg-stretch{align-content:stretch !important}.align-self-lg-auto{align-self:auto !important}.align-self-lg-start{align-self:flex-start !important}.align-self-lg-end{align-self:flex-end !important}.align-self-lg-center{align-self:center !important}.align-self-lg-baseline{align-self:baseline !important}.align-self-lg-stretch{align-self:stretch !important}.order-lg-first{order:-1 !important}.order-lg-0{order:0 !important}.order-lg-1{order:1 !important}.order-lg-2{order:2 !important}.order-lg-3{order:3 !important}.order-lg-4{order:4 !important}.order-lg-5{order:5 !important}.order-lg-last{order:6 !important}.m-lg-0{margin:0 !important}.m-lg-1{margin:.25rem !important}.m-lg-2{margin:.5rem !important}.m-lg-3{margin:1rem !important}.m-lg-4{margin:1.5rem !important}.m-lg-5{margin:3rem !important}.m-lg-auto{margin:auto !important}.mx-lg-0{margin-right:0 !important;margin-left:0 !important}.mx-lg-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-lg-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-lg-3{margin-right:1rem !important;margin-left:1rem !important}.mx-lg-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-lg-5{margin-right:3rem !important;margin-left:3rem !important}.mx-lg-auto{margin-right:auto !important;margin-left:auto !important}.my-lg-0{margin-top:0 !important;margin-bottom:0 !important}.my-lg-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-lg-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-lg-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-lg-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-lg-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-lg-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-lg-0{margin-top:0 !important}.mt-lg-1{margin-top:.25rem !important}.mt-lg-2{margin-top:.5rem !important}.mt-lg-3{margin-top:1rem !important}.mt-lg-4{margin-top:1.5rem !important}.mt-lg-5{margin-top:3rem !important}.mt-lg-auto{margin-top:auto !important}.me-lg-0{margin-right:0 !important}.me-lg-1{margin-right:.25rem !important}.me-lg-2{margin-right:.5rem !important}.me-lg-3{margin-right:1rem !important}.me-lg-4{margin-right:1.5rem !important}.me-lg-5{margin-right:3rem !important}.me-lg-auto{margin-right:auto !important}.mb-lg-0{margin-bottom:0 !important}.mb-lg-1{margin-bottom:.25rem !important}.mb-lg-2{margin-bottom:.5rem !important}.mb-lg-3{margin-bottom:1rem !important}.mb-lg-4{margin-bottom:1.5rem !important}.mb-lg-5{margin-bottom:3rem !important}.mb-lg-auto{margin-bottom:auto !important}.ms-lg-0{margin-left:0 !important}.ms-lg-1{margin-left:.25rem !important}.ms-lg-2{margin-left:.5rem !important}.ms-lg-3{margin-left:1rem !important}.ms-lg-4{margin-left:1.5rem !important}.ms-lg-5{margin-left:3rem !important}.ms-lg-auto{margin-left:auto !important}.p-lg-0{padding:0 !important}.p-lg-1{padding:.25rem !important}.p-lg-2{padding:.5rem !important}.p-lg-3{padding:1rem !important}.p-lg-4{padding:1.5rem !important}.p-lg-5{padding:3rem !important}.px-lg-0{padding-right:0 !important;padding-left:0 !important}.px-lg-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-lg-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-lg-3{padding-right:1rem !important;padding-left:1rem !important}.px-lg-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-lg-5{padding-right:3rem !important;padding-left:3rem !important}.py-lg-0{padding-top:0 !important;padding-bottom:0 !important}.py-lg-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-lg-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-lg-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-lg-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-lg-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-lg-0{padding-top:0 !important}.pt-lg-1{padding-top:.25rem !important}.pt-lg-2{padding-top:.5rem !important}.pt-lg-3{padding-top:1rem !important}.pt-lg-4{padding-top:1.5rem !important}.pt-lg-5{padding-top:3rem !important}.pe-lg-0{padding-right:0 !important}.pe-lg-1{padding-right:.25rem !important}.pe-lg-2{padding-right:.5rem !important}.pe-lg-3{padding-right:1rem !important}.pe-lg-4{padding-right:1.5rem !important}.pe-lg-5{padding-right:3rem !important}.pb-lg-0{padding-bottom:0 !important}.pb-lg-1{padding-bottom:.25rem !important}.pb-lg-2{padding-bottom:.5rem !important}.pb-lg-3{padding-bottom:1rem !important}.pb-lg-4{padding-bottom:1.5rem !important}.pb-lg-5{padding-bottom:3rem !important}.ps-lg-0{padding-left:0 !important}.ps-lg-1{padding-left:.25rem !important}.ps-lg-2{padding-left:.5rem !important}.ps-lg-3{padding-left:1rem !important}.ps-lg-4{padding-left:1.5rem !important}.ps-lg-5{padding-left:3rem !important}}@media (min-width: 1200px){.d-xl-inline{display:inline !important}.d-xl-inline-block{display:inline-block !important}.d-xl-block{display:block !important}.d-xl-grid{display:grid !important}.d-xl-table{display:table !important}.d-xl-table-row{display:table-row !important}.d-xl-table-cell{display:table-cell !important}.d-xl-flex{display:flex !important}.d-xl-inline-flex{display:inline-flex !important}.d-xl-none{display:none !important}.flex-xl-fill{flex:1 1 auto !important}.flex-xl-row{flex-direction:row !important}.flex-xl-column{flex-direction:column !important}.flex-xl-row-reverse{flex-direction:row-reverse !important}.flex-xl-column-reverse{flex-direction:column-reverse !important}.flex-xl-grow-0{flex-grow:0 !important}.flex-xl-grow-1{flex-grow:1 !important}.flex-xl-shrink-0{flex-shrink:0 !important}.flex-xl-shrink-1{flex-shrink:1 !important}.flex-xl-wrap{flex-wrap:wrap !important}.flex-xl-nowrap{flex-wrap:nowrap !important}.flex-xl-wrap-reverse{flex-wrap:wrap-reverse !important}.justify-content-xl-start{justify-content:flex-start !important}.justify-content-xl-end{justify-content:flex-end !important}.justify-content-xl-center{justify-content:center !important}.justify-content-xl-between{justify-content:space-between !important}.justify-content-xl-around{justify-content:space-around !important}.justify-content-xl-evenly{justify-content:space-evenly !important}.align-items-xl-start{align-items:flex-start !important}.align-items-xl-end{align-items:flex-end !important}.align-items-xl-center{align-items:center !important}.align-items-xl-baseline{align-items:baseline !important}.align-items-xl-stretch{align-items:stretch !important}.align-content-xl-start{align-content:flex-start !important}.align-content-xl-end{align-content:flex-end !important}.align-content-xl-center{align-content:center !important}.align-content-xl-between{align-content:space-between !important}.align-content-xl-around{align-content:space-around !important}.align-content-xl-stretch{align-content:stretch !important}.align-self-xl-auto{align-self:auto !important}.align-self-xl-start{align-self:flex-start !important}.align-self-xl-end{align-self:flex-end !important}.align-self-xl-center{align-self:center !important}.align-self-xl-baseline{align-self:baseline !important}.align-self-xl-stretch{align-self:stretch !important}.order-xl-first{order:-1 !important}.order-xl-0{order:0 !important}.order-xl-1{order:1 !important}.order-xl-2{order:2 !important}.order-xl-3{order:3 !important}.order-xl-4{order:4 !important}.order-xl-5{order:5 !important}.order-xl-last{order:6 !important}.m-xl-0{margin:0 !important}.m-xl-1{margin:.25rem !important}.m-xl-2{margin:.5rem !important}.m-xl-3{margin:1rem !important}.m-xl-4{margin:1.5rem !important}.m-xl-5{margin:3rem !important}.m-xl-auto{margin:auto !important}.mx-xl-0{margin-right:0 !important;margin-left:0 !important}.mx-xl-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-xl-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-xl-3{margin-right:1rem !important;margin-left:1rem !important}.mx-xl-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-xl-5{margin-right:3rem !important;margin-left:3rem !important}.mx-xl-auto{margin-right:auto !important;margin-left:auto !important}.my-xl-0{margin-top:0 !important;margin-bottom:0 !important}.my-xl-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-xl-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-xl-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-xl-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-xl-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-xl-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-xl-0{margin-top:0 !important}.mt-xl-1{margin-top:.25rem !important}.mt-xl-2{margin-top:.5rem !important}.mt-xl-3{margin-top:1rem !important}.mt-xl-4{margin-top:1.5rem !important}.mt-xl-5{margin-top:3rem !important}.mt-xl-auto{margin-top:auto !important}.me-xl-0{margin-right:0 !important}.me-xl-1{margin-right:.25rem !important}.me-xl-2{margin-right:.5rem !important}.me-xl-3{margin-right:1rem !important}.me-xl-4{margin-right:1.5rem !important}.me-xl-5{margin-right:3rem !important}.me-xl-auto{margin-right:auto !important}.mb-xl-0{margin-bottom:0 !important}.mb-xl-1{margin-bottom:.25rem !important}.mb-xl-2{margin-bottom:.5rem !important}.mb-xl-3{margin-bottom:1rem !important}.mb-xl-4{margin-bottom:1.5rem !important}.mb-xl-5{margin-bottom:3rem !important}.mb-xl-auto{margin-bottom:auto !important}.ms-xl-0{margin-left:0 !important}.ms-xl-1{margin-left:.25rem !important}.ms-xl-2{margin-left:.5rem !important}.ms-xl-3{margin-left:1rem !important}.ms-xl-4{margin-left:1.5rem !important}.ms-xl-5{margin-left:3rem !important}.ms-xl-auto{margin-left:auto !important}.p-xl-0{padding:0 !important}.p-xl-1{padding:.25rem !important}.p-xl-2{padding:.5rem !important}.p-xl-3{padding:1rem !important}.p-xl-4{padding:1.5rem !important}.p-xl-5{padding:3rem !important}.px-xl-0{padding-right:0 !important;padding-left:0 !important}.px-xl-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-xl-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-xl-3{padding-right:1rem !important;padding-left:1rem !important}.px-xl-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-xl-5{padding-right:3rem !important;padding-left:3rem !important}.py-xl-0{padding-top:0 !important;padding-bottom:0 !important}.py-xl-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-xl-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-xl-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-xl-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-xl-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-xl-0{padding-top:0 !important}.pt-xl-1{padding-top:.25rem !important}.pt-xl-2{padding-top:.5rem !important}.pt-xl-3{padding-top:1rem !important}.pt-xl-4{padding-top:1.5rem !important}.pt-xl-5{padding-top:3rem !important}.pe-xl-0{padding-right:0 !important}.pe-xl-1{padding-right:.25rem !important}.pe-xl-2{padding-right:.5rem !important}.pe-xl-3{padding-right:1rem !important}.pe-xl-4{padding-right:1.5rem !important}.pe-xl-5{padding-right:3rem !important}.pb-xl-0{padding-bottom:0 !important}.pb-xl-1{padding-bottom:.25rem !important}.pb-xl-2{padding-bottom:.5rem !important}.pb-xl-3{padding-bottom:1rem !important}.pb-xl-4{padding-bottom:1.5rem !important}.pb-xl-5{padding-bottom:3rem !important}.ps-xl-0{padding-left:0 !important}.ps-xl-1{padding-left:.25rem !important}.ps-xl-2{padding-left:.5rem !important}.ps-xl-3{padding-left:1rem !important}.ps-xl-4{padding-left:1.5rem !important}.ps-xl-5{padding-left:3rem !important}}@media (min-width: 1400px){.d-xxl-inline{display:inline !important}.d-xxl-inline-block{display:inline-block !important}.d-xxl-block{display:block !important}.d-xxl-grid{display:grid !important}.d-xxl-table{display:table !important}.d-xxl-table-row{display:table-row !important}.d-xxl-table-cell{display:table-cell !important}.d-xxl-flex{display:flex !important}.d-xxl-inline-flex{display:inline-flex !important}.d-xxl-none{display:none !important}.flex-xxl-fill{flex:1 1 auto !important}.flex-xxl-row{flex-direction:row !important}.flex-xxl-column{flex-direction:column !important}.flex-xxl-row-reverse{flex-direction:row-reverse !important}.flex-xxl-column-reverse{flex-direction:column-reverse !important}.flex-xxl-grow-0{flex-grow:0 !important}.flex-xxl-grow-1{flex-grow:1 !important}.flex-xxl-shrink-0{flex-shrink:0 !important}.flex-xxl-shrink-1{flex-shrink:1 !important}.flex-xxl-wrap{flex-wrap:wrap !important}.flex-xxl-nowrap{flex-wrap:nowrap !important}.flex-xxl-wrap-reverse{flex-wrap:wrap-reverse !important}.justify-content-xxl-start{justify-content:flex-start !important}.justify-content-xxl-end{justify-content:flex-end !important}.justify-content-xxl-center{justify-content:center !important}.justify-content-xxl-between{justify-content:space-between !important}.justify-content-xxl-around{justify-content:space-around !important}.justify-content-xxl-evenly{justify-content:space-evenly !important}.align-items-xxl-start{align-items:flex-start !important}.align-items-xxl-end{align-items:flex-end !important}.align-items-xxl-center{align-items:center !important}.align-items-xxl-baseline{align-items:baseline !important}.align-items-xxl-stretch{align-items:stretch !important}.align-content-xxl-start{align-content:flex-start !important}.align-content-xxl-end{align-content:flex-end !important}.align-content-xxl-center{align-content:center !important}.align-content-xxl-between{align-content:space-between !important}.align-content-xxl-around{align-content:space-around !important}.align-content-xxl-stretch{align-content:stretch !important}.align-self-xxl-auto{align-self:auto !important}.align-self-xxl-start{align-self:flex-start !important}.align-self-xxl-end{align-self:flex-end !important}.align-self-xxl-center{align-self:center !important}.align-self-xxl-baseline{align-self:baseline !important}.align-self-xxl-stretch{align-self:stretch !important}.order-xxl-first{order:-1 !important}.order-xxl-0{order:0 !important}.order-xxl-1{order:1 !important}.order-xxl-2{order:2 !important}.order-xxl-3{order:3 !important}.order-xxl-4{order:4 !important}.order-xxl-5{order:5 !important}.order-xxl-last{order:6 !important}.m-xxl-0{margin:0 !important}.m-xxl-1{margin:.25rem !important}.m-xxl-2{margin:.5rem !important}.m-xxl-3{margin:1rem !important}.m-xxl-4{margin:1.5rem !important}.m-xxl-5{margin:3rem !important}.m-xxl-auto{margin:auto !important}.mx-xxl-0{margin-right:0 !important;margin-left:0 !important}.mx-xxl-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-xxl-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-xxl-3{margin-right:1rem !important;margin-left:1rem !important}.mx-xxl-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-xxl-5{margin-right:3rem !important;margin-left:3rem !important}.mx-xxl-auto{margin-right:auto !important;margin-left:auto !important}.my-xxl-0{margin-top:0 !important;margin-bottom:0 !important}.my-xxl-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-xxl-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-xxl-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-xxl-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-xxl-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-xxl-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-xxl-0{margin-top:0 !important}.mt-xxl-1{margin-top:.25rem !important}.mt-xxl-2{margin-top:.5rem !important}.mt-xxl-3{margin-top:1rem !important}.mt-xxl-4{margin-top:1.5rem !important}.mt-xxl-5{margin-top:3rem !important}.mt-xxl-auto{margin-top:auto !important}.me-xxl-0{margin-right:0 !important}.me-xxl-1{margin-right:.25rem !important}.me-xxl-2{margin-right:.5rem !important}.me-xxl-3{margin-right:1rem !important}.me-xxl-4{margin-right:1.5rem !important}.me-xxl-5{margin-right:3rem !important}.me-xxl-auto{margin-right:auto !important}.mb-xxl-0{margin-bottom:0 !important}.mb-xxl-1{margin-bottom:.25rem !important}.mb-xxl-2{margin-bottom:.5rem !important}.mb-xxl-3{margin-bottom:1rem !important}.mb-xxl-4{margin-bottom:1.5rem !important}.mb-xxl-5{margin-bottom:3rem !important}.mb-xxl-auto{margin-bottom:auto !important}.ms-xxl-0{margin-left:0 !important}.ms-xxl-1{margin-left:.25rem !important}.ms-xxl-2{margin-left:.5rem !important}.ms-xxl-3{margin-left:1rem !important}.ms-xxl-4{margin-left:1.5rem !important}.ms-xxl-5{margin-left:3rem !important}.ms-xxl-auto{margin-left:auto !important}.p-xxl-0{padding:0 !important}.p-xxl-1{padding:.25rem !important}.p-xxl-2{padding:.5rem !important}.p-xxl-3{padding:1rem !important}.p-xxl-4{padding:1.5rem !important}.p-xxl-5{padding:3rem !important}.px-xxl-0{padding-right:0 !important;padding-left:0 !important}.px-xxl-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-xxl-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-xxl-3{padding-right:1rem !important;padding-left:1rem !important}.px-xxl-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-xxl-5{padding-right:3rem !important;padding-left:3rem !important}.py-xxl-0{padding-top:0 !important;padding-bottom:0 !important}.py-xxl-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-xxl-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-xxl-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-xxl-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-xxl-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-xxl-0{padding-top:0 !important}.pt-xxl-1{padding-top:.25rem !important}.pt-xxl-2{padding-top:.5rem !important}.pt-xxl-3{padding-top:1rem !important}.pt-xxl-4{padding-top:1.5rem !important}.pt-xxl-5{padding-top:3rem !important}.pe-xxl-0{padding-right:0 !important}.pe-xxl-1{padding-right:.25rem !important}.pe-xxl-2{padding-right:.5rem !important}.pe-xxl-3{padding-right:1rem !important}.pe-xxl-4{padding-right:1.5rem !important}.pe-xxl-5{padding-right:3rem !important}.pb-xxl-0{padding-bottom:0 !important}.pb-xxl-1{padding-bottom:.25rem !important}.pb-xxl-2{padding-bottom:.5rem !important}.pb-xxl-3{padding-bottom:1rem !important}.pb-xxl-4{padding-bottom:1.5rem !important}.pb-xxl-5{padding-bottom:3rem !important}.ps-xxl-0{padding-left:0 !important}.ps-xxl-1{padding-left:.25rem !important}.ps-xxl-2{padding-left:.5rem !important}.ps-xxl-3{padding-left:1rem !important}.ps-xxl-4{padding-left:1.5rem !important}.ps-xxl-5{padding-left:3rem !important}}@media print{.d-print-inline{display:inline !important}.d-print-inline-block{display:inline-block !important}.d-print-block{display:block !important}.d-print-grid{display:grid !important}.d-print-table{display:table !important}.d-print-table-row{display:table-row !important}.d-print-table-cell{display:table-cell !important}.d-print-flex{display:flex !important}.d-print-inline-flex{display:inline-flex !important}.d-print-none{display:none !important}}.row{--bs-gutter-x: 1.875rem}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:#fff;border:1px solid #dee2e6;border-radius:.25rem;max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:.875em;color:#6c757d}.list-group{display:flex;flex-direction:column;padding-left:0;margin-bottom:0;border-radius:0}.list-group-numbered{list-style-type:none;counter-reset:section}.list-group-numbered>li::before{content:counters(section, ".") ". ";counter-increment:section}.list-group-item-action{width:100%;color:var(--t42-content-color);text-align:inherit}.list-group-item-action:hover,.list-group-item-action:focus{z-index:1;color:var(--t42-link-hover-color);text-decoration:none;background-color:var(--t42-link-hover-bg)}.list-group-item-action:active{color:var(--t42-link-hover-color);background-color:var(--t42-link-active-bg)}.list-group-item{position:relative;display:block;padding:.75rem 1.25rem;color:inherit;text-decoration:none;background-color:Rgb(var(--t42-bg-mid));border:1px solid rgba(0,0,0,0)}.list-group-item:first-child{border-top-left-radius:inherit;border-top-right-radius:inherit}.list-group-item:last-child{border-bottom-right-radius:inherit;border-bottom-left-radius:inherit}.list-group-item.disabled,.list-group-item:disabled{color:var(--t42-content-color-disabled);pointer-events:none;background-color:rgba(0,0,0,0)}.list-group-item.active{z-index:2;color:var(--t42-link-hover-color);background-color:var(--t42-link-active-bg);border-color:rgba(0,0,0,0)}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{margin-top:-1px;border-top-width:1px}.list-group-horizontal{flex-direction:row}.list-group-horizontal>.list-group-item:first-child{border-bottom-left-radius:0;border-top-right-radius:0}.list-group-horizontal>.list-group-item:last-child{border-top-right-radius:0;border-bottom-left-radius:0}.list-group-horizontal>.list-group-item.active{margin-top:0}.list-group-horizontal>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}@media (min-width: 576px){.list-group-horizontal-sm{flex-direction:row}.list-group-horizontal-sm>.list-group-item:first-child{border-bottom-left-radius:0;border-top-right-radius:0}.list-group-horizontal-sm>.list-group-item:last-child{border-top-right-radius:0;border-bottom-left-radius:0}.list-group-horizontal-sm>.list-group-item.active{margin-top:0}.list-group-horizontal-sm>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-sm>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width: 768px){.list-group-horizontal-md{flex-direction:row}.list-group-horizontal-md>.list-group-item:first-child{border-bottom-left-radius:0;border-top-right-radius:0}.list-group-horizontal-md>.list-group-item:last-child{border-top-right-radius:0;border-bottom-left-radius:0}.list-group-horizontal-md>.list-group-item.active{margin-top:0}.list-group-horizontal-md>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-md>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width: 992px){.list-group-horizontal-lg{flex-direction:row}.list-group-horizontal-lg>.list-group-item:first-child{border-bottom-left-radius:0;border-top-right-radius:0}.list-group-horizontal-lg>.list-group-item:last-child{border-top-right-radius:0;border-bottom-left-radius:0}.list-group-horizontal-lg>.list-group-item.active{margin-top:0}.list-group-horizontal-lg>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-lg>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width: 1200px){.list-group-horizontal-xl{flex-direction:row}.list-group-horizontal-xl>.list-group-item:first-child{border-bottom-left-radius:0;border-top-right-radius:0}.list-group-horizontal-xl>.list-group-item:last-child{border-top-right-radius:0;border-bottom-left-radius:0}.list-group-horizontal-xl>.list-group-item.active{margin-top:0}.list-group-horizontal-xl>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-xl>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width: 1400px){.list-group-horizontal-xxl{flex-direction:row}.list-group-horizontal-xxl>.list-group-item:first-child{border-bottom-left-radius:0;border-top-right-radius:0}.list-group-horizontal-xxl>.list-group-item:last-child{border-top-right-radius:0;border-bottom-left-radius:0}.list-group-horizontal-xxl>.list-group-item.active{margin-top:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}.list-group-flush{border-radius:0}.list-group-flush>.list-group-item{border-width:0 0 1px}.list-group-flush>.list-group-item:last-child{border-bottom-width:0}.list-group-item-primary{color:#004a89;background-color:#cce5fa}.list-group-item-primary.list-group-item-action:hover,.list-group-item-primary.list-group-item-action:focus{color:#004a89;background-color:#b8cee1}.list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#004a89;border-color:#004a89}.list-group-item-secondary{color:#3a3a3a;background-color:#dfdfdf}.list-group-item-secondary.list-group-item-action:hover,.list-group-item-secondary.list-group-item-action:focus{color:#3a3a3a;background-color:#c9c9c9}.list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#3a3a3a;border-color:#3a3a3a}.list-group-item-success{color:#28602b;background-color:#d9ecda}.list-group-item-success.list-group-item-action:hover,.list-group-item-success.list-group-item-action:focus{color:#28602b;background-color:#c3d4c4}.list-group-item-success.list-group-item-action.active{color:#fff;background-color:#28602b;border-color:#28602b}.list-group-item-info{color:#2a5f6f;background-color:#daecf1}.list-group-item-info.list-group-item-action:hover,.list-group-item-info.list-group-item-action:focus{color:#2a5f6f;background-color:#c4d4d9}.list-group-item-info.list-group-item-action.active{color:#fff;background-color:#2a5f6f;border-color:#2a5f6f}.list-group-item-warning{color:#64430f;background-color:#feeed3}.list-group-item-warning.list-group-item-action:hover,.list-group-item-warning.list-group-item-action:focus{color:#64430f;background-color:#e5d6be}.list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#64430f;border-color:#64430f}.list-group-item-danger{color:#993113;background-color:#ffdcd2}.list-group-item-danger.list-group-item-action:hover,.list-group-item-danger.list-group-item-action:focus{color:#993113;background-color:#e6c6bd}.list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#993113;border-color:#993113}.list-group-item-light{color:#3a3a3a;background-color:#dfdfdf}.list-group-item-light.list-group-item-action:hover,.list-group-item-light.list-group-item-action:focus{color:#3a3a3a;background-color:#c9c9c9}.list-group-item-light.list-group-item-action.active{color:#fff;background-color:#3a3a3a;border-color:#3a3a3a}.list-group-item-dark{color:#3a3a3a;background-color:#dfdfdf}.list-group-item-dark.list-group-item-action:hover,.list-group-item-dark.list-group-item-action:focus{color:#3a3a3a;background-color:#c9c9c9}.list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#3a3a3a;border-color:#3a3a3a}.list-unstyled{padding-left:0;list-style:none}.list-group{box-shadow:var(--t42-shadow)}.list-group-item{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:color;margin-bottom:0;border:0;border-bottom:var(--t42-border);backdrop-filter:var(--backdrop-filter)}.list-group-item:last-child{border-bottom:transparent}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{margin-top:0;border-top-width:0}.list-group-item-action{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background,color;transition-duration:0.25s}.list-group-item-action:hover,.list-group-item-action:focus{background-color:var(--t42-list-group-hover-bg-special)}.list-group-item-action.active:hover{background-color:var(--t42-color-opacity-05)}.modal{position:fixed;top:0;left:0;z-index:1055;display:none;width:100%;height:100%;overflow-x:hidden;overflow-y:auto;outline:0}.modal-dialog{position:relative;width:auto;margin:.5rem;pointer-events:none}.modal.fade .modal-dialog{transition:transform 0.3s ease-out;transform:translate(0, -50px)}@media (prefers-reduced-motion: reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{transform:none}.modal.modal-static .modal-dialog{transform:scale(1.02)}.modal-dialog-scrollable{height:calc(100% - 1rem)}.modal-dialog-scrollable .modal-content{max-height:100%;overflow:hidden}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{display:flex;align-items:center;min-height:calc(100% - 1rem)}.modal-content{position:relative;display:flex;flex-direction:column;width:100%;pointer-events:auto;background-color:var(--t42-modal-bg);background-clip:padding-box;border:.0625rem solid var(--t42-color-opacity-10);border-radius:0;outline:0}.modal-backdrop{position:fixed;top:0;left:0;z-index:1050;width:100vw;height:100vh;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:.5}.modal-header{display:flex;flex-shrink:0;align-items:center;justify-content:space-between;padding:1rem 1rem;border-bottom:.0625rem solid rgba(0,0,0,0);border-top-left-radius:0;border-top-right-radius:0}.modal-header .btn-close{padding:.5rem .5rem;margin:-.5rem -.5rem -.5rem auto}.modal-title{margin-bottom:0;line-height:1.5}.modal-body{position:relative;flex:1 1 auto;padding:1rem}.modal-footer{display:flex;flex-wrap:wrap;flex-shrink:0;align-items:center;justify-content:flex-end;padding:.75rem;border-top:.0625rem solid rgba(0,0,0,0);border-bottom-right-radius:0;border-bottom-left-radius:0}.modal-footer>*{margin:.25rem}@media (min-width: 576px){.modal-dialog{max-width:500px;margin:1.75rem auto}.modal-dialog-scrollable{height:calc(100% - 3.5rem)}.modal-dialog-centered{min-height:calc(100% - 3.5rem)}.modal-sm{max-width:300px}}@media (min-width: 992px){.modal-lg,.modal-xl{max-width:800px}}@media (min-width: 1200px){.modal-xl{max-width:1140px}}.modal-fullscreen{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen .modal-header{border-radius:0}.modal-fullscreen .modal-body{overflow-y:auto}.modal-fullscreen .modal-footer{border-radius:0}@media (max-width: 575.98px){.modal-fullscreen-sm-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-sm-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-sm-down .modal-header{border-radius:0}.modal-fullscreen-sm-down .modal-body{overflow-y:auto}.modal-fullscreen-sm-down .modal-footer{border-radius:0}}@media (max-width: 767.98px){.modal-fullscreen-md-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-md-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-md-down .modal-header{border-radius:0}.modal-fullscreen-md-down .modal-body{overflow-y:auto}.modal-fullscreen-md-down .modal-footer{border-radius:0}}@media (max-width: 991.98px){.modal-fullscreen-lg-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-lg-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-lg-down .modal-header{border-radius:0}.modal-fullscreen-lg-down .modal-body{overflow-y:auto}.modal-fullscreen-lg-down .modal-footer{border-radius:0}}@media (max-width: 1199.98px){.modal-fullscreen-xl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xl-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-xl-down .modal-header{border-radius:0}.modal-fullscreen-xl-down .modal-body{overflow-y:auto}.modal-fullscreen-xl-down .modal-footer{border-radius:0}}@media (max-width: 1399.98px){.modal-fullscreen-xxl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xxl-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-xxl-down .modal-header{border-radius:0}.modal-fullscreen-xxl-down .modal-body{overflow-y:auto}.modal-fullscreen-xxl-down .modal-footer{border-radius:0}}.modal{backdrop-filter:var(--backdrop-filter)}.modal .btn-close{font-size:1.25rem;background-size:0.75rem;filter:var(--filter-close)}.modal-content{border-top:0;background:linear-gradient(to bottom right, Rgba(var(--t42-bg-light), 0.75) 0%, Rgba(var(--t42-bg-dark), 0.75) 100%);box-shadow:var(--t42-shadow)}.modal-content::before{display:block;height:0.0625rem;background:linear-gradient(90deg, #007be5 0%, rgba(0,123,229,0.5) 100%);content:""}.modal-body{padding:0 1rem}.modal-body p:last-child{margin-bottom:0}.modal-sm .modal-footer{flex-direction:column}.modal-sm .modal-footer .btn{width:100%}.modal-sm .modal-footer .btn:not(:last-of-type){margin-bottom:0.5rem}.modal-fill-in{background-color:Rgba(var(--t42-bg-light), 0.75)}.modal-fill-in.modal-dialog{display:flex;flex-flow:column nowrap;align-content:center;align-items:center;justify-content:center;width:auto;max-width:100%;height:100%;margin:0 auto}.modal-fill-in .modal-content{display:flex;max-width:600px;border-color:transparent;background:transparent;background-color:transparent;box-shadow:none;backdrop-filter:none;pointer-events:auto}.modal-fill-in .modal-content::before{display:none}.modal-fill-in::before{position:fixed;top:0;right:0;left:0;display:block;height:0.0625rem;background:linear-gradient(90deg, #007be5 0%, rgba(0,123,229,0.5) 100%);content:""}.modal-fill-in.modal-lg .modal-content{max-width:800px}.modal-fill-in.modal-sm .modal-content{max-width:300px}.nav{display:flex;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:.45rem 1rem;color:var(--t42-link-color);text-decoration:none;transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.nav-link{transition:none}}.nav-link:hover,.nav-link:focus{color:var(--t42-link-hover-color)}.nav-link.disabled{color:var(--t42-content-color-disabled);pointer-events:none;cursor:default}.nav-tabs{border-bottom:.0625rem solid var(--t42-color-opacity-10)}.nav-tabs .nav-link{margin-bottom:-.0625rem;background:none;border:.0625rem solid transparent;border-top-left-radius:0;border-top-right-radius:0}.nav-tabs .nav-link:hover,.nav-tabs .nav-link:focus{border-color:transparent transparent var(--t42-color-opacity-10);isolation:isolate}.nav-tabs .nav-link.disabled{color:var(--t42-content-color-disabled);background-color:transparent;border-color:transparent}.nav-tabs .nav-link.active,.nav-tabs .nav-item.show .nav-link{color:var(--t42-link-hover-color);background-color:var(--t42-link-active-bg);border-color:transparent transparent #007be5}.nav-tabs .dropdown-menu{margin-top:-.0625rem;border-top-left-radius:0;border-top-right-radius:0}.nav-pills .nav-link{background:none;border:0;border-radius:.25rem}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:var(--t42-link-hover-color);background-color:var(--t42-link-active-bg)}.nav-fill>.nav-link,.nav-fill .nav-item{flex:1 1 auto;text-align:center}.nav-justified>.nav-link,.nav-justified .nav-item{flex-basis:0;flex-grow:1;text-align:center}.nav-fill .nav-item .nav-link,.nav-justified .nav-item .nav-link{width:100%}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-link{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, border-color, color;margin-right:3px;border:.0625rem solid transparent}.nav-link:not(.disabled):not(:disabled):focus,.nav-link:not(.disabled):not(:disabled):active,.nav-link:not(.disabled):not(:disabled).active,.nav-link:not(.disabled):not(:disabled):hover{border-color:var(--t42-color-opacity-10);color:var(--t42-link-color);background-color:var(--t42-link-hover-bg)}.nav-link.dropdown-toggle::after{right:-0.125rem}.navbar-nav .nav-item{bottom:-1px}.navbar-nav .nav-item .nav-link{border-bottom:0}.navbar-nav .nav-item:not(.disabled):not(:disabled):focus .nav-link,.navbar-nav .nav-item:not(.disabled):not(:disabled):active .nav-link,.navbar-nav .nav-item:not(.disabled):not(:disabled).active .nav-link,.navbar-nav .nav-item:not(.disabled):not(:disabled):hover .nav-link{border-color:var(--t42-color-opacity-10)}.nav.flex-column .nav-link{margin-bottom:3px}.nav-tabs .nav-link{position:relative;display:flex;align-items:center;height:2rem}.nav-tabs .nav-link::before{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:height;position:absolute;bottom:-2px;left:-1px;width:calc(100% + 2px);height:0;background-color:var(--primary);content:""}.nav-tabs .nav-link.active::before{height:3px}.nav-tabs .nav-link.active:hover::before{height:0}.nav-tabs .nav-link .btn-close{width:0.5rem;height:0.5rem}.nav-tabs .nav-item{margin-right:0}.nav-tabs .dropdown.show .dropdown-toggle{border-color:transparent}.nav-tabs.flex-column .nav-link.active:hover::before{width:0}.nav-tabs.flex-column .nav-link::before{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:width;top:-1px;width:0;height:100%;margin-left:0;background-color:var(--primary);content:""}.nav-tabs.flex-column .nav-link.active::before{width:3px;height:calc(100% + 2px)}.nav-pills .nav-link{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;width:100%;padding:0.25rem 1rem;border:1px solid transparent;border-radius:1rem}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{position:relative;border-color:transparent}.nav-pills .nav-item{margin-right:3px}.nav-pills .nav-item:last-child{margin-right:0}.nav-pills .nav-link.active:not(.dropdown-toggle),.nav-pills .show>.nav-link:not(.dropdown-toggle){padding:0.25rem 1.75rem 0.25rem 1rem}.nav-pills .nav-link.active:not(.dropdown-toggle)::before,.nav-pills .show>.nav-link:not(.dropdown-toggle)::before{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:right;position:absolute;top:50%;right:10px;width:8px;height:8px;border-radius:50%;background-color:var(--primary);transform:translateY(-50%);content:""}.nav-pills .nav-link.active:not(.dropdown-toggle):hover::before,.nav-pills .show>.nav-link:not(.dropdown-toggle):hover::before{right:-10px}.nav-justified .nav-item .nav-link::before{right:1px;left:-1px;margin-left:0}.tab-content{padding-top:0.5rem}.nav-action-buttons .nav-link{position:relative;padding:0.45rem 1.5rem 0.45rem 1rem}.nav-action-buttons .icon-cancel::before{display:block;width:1rem;height:1rem;background-color:var(--t42-content-color);content:"";-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M366.854,336.384c6.14398,6.14398,9.216,13.48267,9.216,22.01599s-3.07202,15.87198-9.216,22.01599 c-6.14398,5.46133-13.48267,8.19202-22.01599,8.19199c-8.53333,0.00003-15.87201-2.73065-22.01602-8.19199l-67.584-77.82401 l-67.584,77.82401c-6.144,5.46133-13.48267,8.19202-22.01601,8.19199c-8.53333,0.00003-15.87199-2.73065-22.01599-8.19199 c-5.46133-6.14401-8.192-13.48267-8.192-22.01599s2.73067-15.87201,8.192-22.01599l70.65599-79.87201l-70.65601-80.896 c-5.46132-6.144-8.19199-13.48268-8.19199-22.01601c0-8.53334,2.73067-15.87201,8.19199-22.01601 c6.14401-5.46133,13.48267-8.19199,22.01601-8.192c8.53334,0.00001,15.87201,2.73067,22.01601,8.192l67.584,77.82401 l67.584-77.82401c6.14401-5.46133,13.4827-8.19199,22.01602-8.192c8.53333,0.00001,15.87201,2.73067,22.01599,8.192 c6.14398,6.144,9.216,13.48267,9.216,22.01601c0,8.53333-3.07202,15.87201-9.216,22.01601l-70.65601,80.896L366.854,336.384z%27/%3E%3C/svg%3E")}.navbar{position:relative;display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;padding-top:0;padding-right:.875rem;padding-bottom:0;padding-left:.875rem}.navbar>.container,.navbar>.container-fluid,.navbar>.container-sm,.navbar>.container-md,.navbar>.container-lg,.navbar>.container-xl,.navbar>.container-xxl{display:flex;flex-wrap:inherit;align-items:center;justify-content:space-between}.navbar-brand{padding-top:.075rem;padding-bottom:.075rem;margin-right:1rem;font-size:1.25rem;text-decoration:none;white-space:nowrap}.navbar-nav{display:flex;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-nav .dropdown-menu{position:static}.navbar-text{padding-top:.45rem;padding-bottom:.45rem}.navbar-collapse{flex-basis:100%;flex-grow:1;align-items:center}.navbar-toggler{padding:0 0;font-size:.9375rem;line-height:1;background-color:transparent;border:1px solid transparent;border-radius:0;transition:box-shadow 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.navbar-toggler{transition:none}}.navbar-toggler:hover{text-decoration:none}.navbar-toggler:focus{text-decoration:none;outline:0;box-shadow:0 0 0 0}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;background-repeat:no-repeat;background-position:center;background-size:100%}.navbar-nav-scroll{max-height:var(--bs-scroll-height, 75vh);overflow-y:auto}@media (min-width: 576px){.navbar-expand-sm{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-sm .navbar-nav{flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm .navbar-nav-scroll{overflow:visible}.navbar-expand-sm .navbar-collapse{display:flex !important;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}.navbar-expand-sm .offcanvas-header{display:none}.navbar-expand-sm .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;visibility:visible !important;background-color:transparent;border-right:0;border-left:0;transition:none;transform:none}.navbar-expand-sm .offcanvas-top,.navbar-expand-sm .offcanvas-bottom{height:auto;border-top:0;border-bottom:0}.navbar-expand-sm .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width: 768px){.navbar-expand-md{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-md .navbar-nav{flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-md .navbar-nav-scroll{overflow:visible}.navbar-expand-md .navbar-collapse{display:flex !important;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}.navbar-expand-md .offcanvas-header{display:none}.navbar-expand-md .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;visibility:visible !important;background-color:transparent;border-right:0;border-left:0;transition:none;transform:none}.navbar-expand-md .offcanvas-top,.navbar-expand-md .offcanvas-bottom{height:auto;border-top:0;border-bottom:0}.navbar-expand-md .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width: 992px){.navbar-expand-lg{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-lg .navbar-nav{flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-lg .navbar-nav-scroll{overflow:visible}.navbar-expand-lg .navbar-collapse{display:flex !important;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}.navbar-expand-lg .offcanvas-header{display:none}.navbar-expand-lg .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;visibility:visible !important;background-color:transparent;border-right:0;border-left:0;transition:none;transform:none}.navbar-expand-lg .offcanvas-top,.navbar-expand-lg .offcanvas-bottom{height:auto;border-top:0;border-bottom:0}.navbar-expand-lg .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width: 1200px){.navbar-expand-xl{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-xl .navbar-nav{flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xl .navbar-nav-scroll{overflow:visible}.navbar-expand-xl .navbar-collapse{display:flex !important;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}.navbar-expand-xl .offcanvas-header{display:none}.navbar-expand-xl .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;visibility:visible !important;background-color:transparent;border-right:0;border-left:0;transition:none;transform:none}.navbar-expand-xl .offcanvas-top,.navbar-expand-xl .offcanvas-bottom{height:auto;border-top:0;border-bottom:0}.navbar-expand-xl .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width: 1400px){.navbar-expand-xxl{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-xxl .navbar-nav{flex-direction:row}.navbar-expand-xxl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xxl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xxl .navbar-nav-scroll{overflow:visible}.navbar-expand-xxl .navbar-collapse{display:flex !important;flex-basis:auto}.navbar-expand-xxl .navbar-toggler{display:none}.navbar-expand-xxl .offcanvas-header{display:none}.navbar-expand-xxl .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;visibility:visible !important;background-color:transparent;border-right:0;border-left:0;transition:none;transform:none}.navbar-expand-xxl .offcanvas-top,.navbar-expand-xxl .offcanvas-bottom{height:auto;border-top:0;border-bottom:0}.navbar-expand-xxl .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}.navbar-expand{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand .navbar-nav{flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand .navbar-nav-scroll{overflow:visible}.navbar-expand .navbar-collapse{display:flex !important;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-expand .offcanvas-header{display:none}.navbar-expand .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;visibility:visible !important;background-color:transparent;border-right:0;border-left:0;transition:none;transform:none}.navbar-expand .offcanvas-top,.navbar-expand .offcanvas-bottom{height:auto;border-top:0;border-bottom:0}.navbar-expand .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}.navbar-light .navbar-brand{color:var(--t42-link-color)}.navbar-light .navbar-brand:hover,.navbar-light .navbar-brand:focus{color:var(--t42-link-hover-color)}.navbar-light .navbar-nav .nav-link{color:var(--t42-link-color)}.navbar-light .navbar-nav .nav-link:hover,.navbar-light .navbar-nav .nav-link:focus{color:var(--t42-link-hover-color)}.navbar-light .navbar-nav .nav-link.disabled{color:var(--t42-content-color-disabled)}.navbar-light .navbar-nav .show>.nav-link,.navbar-light .navbar-nav .nav-link.active{color:var(--t42-link-hover-color)}.navbar-light .navbar-toggler{color:var(--t42-link-color);border-color:rgba(0,0,0,0.1)}.navbar-light .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 30 30%27%3e%3cpath stroke=%27var%28--t42-link-color%29%27 stroke-linecap=%27round%27 stroke-miterlimit=%2710%27 stroke-width=%272%27 d=%27M4 7h22M4 15h22M4 23h22%27/%3e%3c/svg%3e")}.navbar-light .navbar-text{color:var(--t42-link-color)}.navbar-light .navbar-text a,.navbar-light .navbar-text a:hover,.navbar-light .navbar-text a:focus{color:var(--t42-link-hover-color)}.navbar-dark .navbar-brand{color:var(--t42-link-color)}.navbar-dark .navbar-brand:hover,.navbar-dark .navbar-brand:focus{color:var(--t42-link-hover-color)}.navbar-dark .navbar-nav .nav-link{color:var(--t42-link-color)}.navbar-dark .navbar-nav .nav-link:hover,.navbar-dark .navbar-nav .nav-link:focus{color:var(--t42-link-hover-color)}.navbar-dark .navbar-nav .nav-link.disabled{color:var(--t42-content-color-disabled)}.navbar-dark .navbar-nav .show>.nav-link,.navbar-dark .navbar-nav .nav-link.active{color:var(--t42-link-hover-color)}.navbar-dark .navbar-toggler{color:var(--t42-link-color);border-color:rgba(255,255,255,0.1)}.navbar-dark .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 30 30%27%3e%3cpath stroke=%27var%28--t42-link-color%29%27 stroke-linecap=%27round%27 stroke-miterlimit=%2710%27 stroke-width=%272%27 d=%27M4 7h22M4 15h22M4 23h22%27/%3e%3c/svg%3e")}.navbar-dark .navbar-text{color:var(--t42-link-color)}.navbar-dark .navbar-text a,.navbar-dark .navbar-text a:hover,.navbar-dark .navbar-text a:focus{color:var(--t42-link-hover-color)}.navbar{border-bottom:var(--t42-border);background-color:Rgba(var(--t42-bg-mid), 0.75);backdrop-filter:var(--backdrop-filter)}.navbar-dark{background-color:Rgba(var(--t42-bg-dark), 0.75)}.navbar-light{background-color:Rgba(var(--t42-bg-light), 0.75)}.navbar .nav-item{position:relative}.navbar .nav-item.show:focus .nav-link:not(.disabled):not(:disabled),.navbar .nav-item.show:active .nav-link:not(.disabled):not(:disabled),.navbar .nav-item.show.active .nav-link:not(.disabled):not(:disabled),.navbar .nav-item:not(.disabled):not(:disabled):focus .nav-link:not(.disabled):not(:disabled),.navbar .nav-item:not(.disabled):not(:disabled):active .nav-link:not(.disabled):not(:disabled),.navbar .nav-item:not(.disabled):not(:disabled).active .nav-link:not(.disabled):not(:disabled){color:var(--t42-link-color);background-color:var(--t42-color-opacity-10)}.navbar .nav-item.show:hover .nav-link:not(.disabled):not(:disabled),.navbar .nav-item:not(.disabled):not(:disabled):hover .nav-link:not(.disabled):not(:disabled){color:var(--t42-link-color);background-color:var(--t42-color-opacity-05)}.navbar .nav-link{padding-right:.875rem;padding-left:.875rem}.navbar .btn-group{height:100%;padding-left:.875rem;border-left:var(--t42-border)}.pagination{display:flex;padding-left:0;list-style:none}.page-link{position:relative;display:block;color:var(--t42-content-color);text-decoration:none;background-color:rgba(0,0,0,0);border:0 solid rgba(0,0,0,0);transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.page-link{transition:none}}.page-link:hover{z-index:2;color:var(--t42-link-hover-color);background-color:var(--t42-link-hover-bg);border-color:#dee2e6}.page-link:focus{z-index:3;color:var(--t42-link-hover-color);background-color:rgba(0,0,0,0);outline:0;box-shadow:0 0 0 0 rgba(0,123,229,0.25)}.page-item:not(:first-child) .page-link{margin-left:0}.page-item.active .page-link{z-index:3;color:var(--white);background-color:var(--primary);border-color:var(--primary)}.page-item.disabled .page-link{color:var(--t42-content-color-disabled);pointer-events:none;background-color:rgba(0,0,0,0);border-color:#dee2e6}.page-link{padding:.125rem .5rem}.page-item:first-child .page-link{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.page-item:last-child .page-link{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.pagination-lg .page-link{padding:.75rem 1.5rem;font-size:.9375rem}.pagination-lg .page-item:first-child .page-link{border-top-left-radius:1rem;border-bottom-left-radius:1rem}.pagination-lg .page-item:last-child .page-link{border-top-right-radius:1rem;border-bottom-right-radius:1rem}.pagination-sm .page-link{padding:.25rem .5rem;font-size:.65625rem}.pagination-sm .page-item:first-child .page-link{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.pagination-sm .page-item:last-child .page-link{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.page-link{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, color;display:flex;align-items:center;justify-content:center;min-width:1.5rem;min-height:1.5rem;border-radius:0.25rem;overflow:hidden}.page-link[aria-label="Next"],.page-link[aria-label="Previous"]{padding:0}.page-link[aria-label="Next"] span{background:var(--t42-select-indicator) center center/1rem 1rem no-repeat;transform:rotate(-90deg)}.page-link[aria-label="Previous"] span{background:var(--t42-select-indicator) center center/1rem 1rem no-repeat;transform:rotate(90deg)}.page-link>span{width:100%;height:100%;min-height:1rem;font-size:0;clip:initial}.pagination-lg .page-link[aria-label="Next"],.pagination-lg .page-link[aria-label="Previous"]{padding:0.75rem 1.5rem}.page-item{margin-right:8px}.page-item:first-child .page-link>span:not(.sr-only)::before,.page-item:last-child .page-link>span:not(.sr-only)::before{top:-0.125rem}.page-item.active .page-link:hover,.page-item:active .page-link:hover{background-color:var(--t42-color-opacity-05)}.page-item.active.disabled .page-link{background-color:var(--t42-color-opacity-10)}.popover{position:absolute;top:0;left:0 /* rtl:ignore */;z-index:1070;display:block;max-width:276px;font-family:"Montserrat","Helvetica Neue",Arial,sans-serif;font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.65625rem;word-wrap:break-word;background-color:Rgba(var(--t42-bg-dark), 0.75);background-clip:padding-box;border:1px solid var(--t42-color-opacity-10);border-radius:0}.popover .popover-arrow{position:absolute;display:block;width:1rem;height:.5rem}.popover .popover-arrow::before,.popover .popover-arrow::after{position:absolute;display:block;content:"";border-color:transparent;border-style:solid}.bs-popover-top>.popover-arrow,.bs-popover-auto[data-popper-placement^="top"]>.popover-arrow{bottom:calc(-.5rem - 1px)}.bs-popover-top>.popover-arrow::before,.bs-popover-auto[data-popper-placement^="top"]>.popover-arrow::before{bottom:0;border-width:.5rem .5rem 0;border-top-color:var(--t42-color-opacity-10)}.bs-popover-top>.popover-arrow::after,.bs-popover-auto[data-popper-placement^="top"]>.popover-arrow::after{bottom:1px;border-width:.5rem .5rem 0;border-top-color:var(--t42-color-opacity-10)}.bs-popover-end>.popover-arrow,.bs-popover-auto[data-popper-placement^="right"]>.popover-arrow{left:calc(-.5rem - 1px);width:.5rem;height:1rem}.bs-popover-end>.popover-arrow::before,.bs-popover-auto[data-popper-placement^="right"]>.popover-arrow::before{left:0;border-width:.5rem .5rem .5rem 0;border-right-color:var(--t42-color-opacity-10)}.bs-popover-end>.popover-arrow::after,.bs-popover-auto[data-popper-placement^="right"]>.popover-arrow::after{left:1px;border-width:.5rem .5rem .5rem 0;border-right-color:var(--t42-color-opacity-10)}.bs-popover-bottom>.popover-arrow,.bs-popover-auto[data-popper-placement^="bottom"]>.popover-arrow{top:calc(-.5rem - 1px)}.bs-popover-bottom>.popover-arrow::before,.bs-popover-auto[data-popper-placement^="bottom"]>.popover-arrow::before{top:0;border-width:0 .5rem .5rem .5rem;border-bottom-color:var(--t42-color-opacity-10)}.bs-popover-bottom>.popover-arrow::after,.bs-popover-auto[data-popper-placement^="bottom"]>.popover-arrow::after{top:1px;border-width:0 .5rem .5rem .5rem;border-bottom-color:var(--t42-color-opacity-10)}.bs-popover-bottom .popover-header::before,.bs-popover-auto[data-popper-placement^="bottom"] .popover-header::before{position:absolute;top:0;left:50%;display:block;width:1rem;margin-left:-.5rem;content:"";border-bottom:1px solid Rgba(var(--t42-bg-mid), 0.75)}.bs-popover-start>.popover-arrow,.bs-popover-auto[data-popper-placement^="left"]>.popover-arrow{right:calc(-.5rem - 1px);width:.5rem;height:1rem}.bs-popover-start>.popover-arrow::before,.bs-popover-auto[data-popper-placement^="left"]>.popover-arrow::before{right:0;border-width:.5rem 0 .5rem .5rem;border-left-color:var(--t42-color-opacity-10)}.bs-popover-start>.popover-arrow::after,.bs-popover-auto[data-popper-placement^="left"]>.popover-arrow::after{right:1px;border-width:.5rem 0 .5rem .5rem;border-left-color:var(--t42-color-opacity-10)}.popover-header{padding:.55rem 1rem;margin-bottom:0;font-size:.75rem;color:var(--t42-link-color);background-color:Rgba(var(--t42-bg-mid), 0.75);border-bottom:1px solid var(--t42-color-opacity-10);border-top-left-radius:0;border-top-right-radius:0}.popover-header:empty{display:none}.popover-body{padding:1rem 1rem;color:var(--t42-content-color)}.popover{backdrop-filter:var(--backdrop-filter)}@keyframes progress-bar-stripes{0%{background-position-x:1.063rem}}.progress{display:flex;height:1.063rem;overflow:hidden;font-size:.6rem;background-color:Rgb(var(--t42-bg-mid));border-radius:0}.progress-bar{display:flex;flex-direction:column;justify-content:center;overflow:hidden;color:#fff;text-align:center;white-space:nowrap;background-color:#007be5;transition:width 0.6s ease}@media (prefers-reduced-motion: reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-size:1.063rem 1.063rem}.progress-bar-animated{animation:1s linear infinite progress-bar-stripes}@media (prefers-reduced-motion: reduce){.progress-bar-animated{animation:none}}.progress{border:var(--t42-border)}.table{--bs-table-bg: rgba(0,0,0,0);--bs-table-accent-bg: rgba(0,0,0,0);--bs-table-striped-color: var(--t42-content-color);--bs-table-striped-bg: rgba(0,0,0,0.05);--bs-table-active-color: var(--t42-content-color);--bs-table-active-bg: rgba(0,0,0,0.1);--bs-table-hover-color: var(--t42-link-color);--bs-table-hover-bg: rgba(0,0,0,0.075);width:100%;margin-bottom:1rem;color:var(--t42-content-color);vertical-align:top;border-color:var(--t42-color-opacity-10)}.table>:not(caption)>*>*{padding:.25rem .313rem;background-color:var(--bs-table-bg);border-bottom-width:1px;box-shadow:inset 0 0 0 9999px var(--bs-table-accent-bg)}.table>tbody{vertical-align:inherit}.table>thead{vertical-align:bottom}.table>:not(:first-child){border-top:2px solid currentColor}.caption-top{caption-side:top}.table-sm>:not(caption)>*>*{padding:.25rem .25rem}.table-bordered>:not(caption)>*{border-width:1px 0}.table-bordered>:not(caption)>*>*{border-width:0 1px}.table-borderless>:not(caption)>*>*{border-bottom-width:0}.table-borderless>:not(:first-child){border-top-width:0}.table-striped>tbody>tr:nth-of-type(odd)>*{--bs-table-accent-bg: var(--bs-table-striped-bg);color:var(--bs-table-striped-color)}.table-active{--bs-table-accent-bg: var(--bs-table-active-bg);color:var(--bs-table-active-color)}.table-hover>tbody>tr:hover>*{--bs-table-accent-bg: var(--bs-table-hover-bg);color:var(--bs-table-hover-color)}.table-primary{--bs-table-bg: #cce5fa;--bs-table-striped-bg: #c2daee;--bs-table-striped-color: #000;--bs-table-active-bg: #b8cee1;--bs-table-active-color: #000;--bs-table-hover-bg: #bdd4e7;--bs-table-hover-color: #000;color:#000;border-color:#b8cee1}.table-secondary{--bs-table-bg: #dfdfdf;--bs-table-striped-bg: #d4d4d4;--bs-table-striped-color: #000;--bs-table-active-bg: #c9c9c9;--bs-table-active-color: #000;--bs-table-hover-bg: #cecece;--bs-table-hover-color: #000;color:#000;border-color:#c9c9c9}.table-success{--bs-table-bg: #d9ecda;--bs-table-striped-bg: #cee0cf;--bs-table-striped-color: #000;--bs-table-active-bg: #c3d4c4;--bs-table-active-color: #000;--bs-table-hover-bg: #c9daca;--bs-table-hover-color: #000;color:#000;border-color:#c3d4c4}.table-info{--bs-table-bg: #daecf1;--bs-table-striped-bg: #cfe0e5;--bs-table-striped-color: #000;--bs-table-active-bg: #c4d4d9;--bs-table-active-color: #000;--bs-table-hover-bg: #cadadf;--bs-table-hover-color: #000;color:#000;border-color:#c4d4d9}.table-warning{--bs-table-bg: #feeed3;--bs-table-striped-bg: #f1e2c8;--bs-table-striped-color: #000;--bs-table-active-bg: #e5d6be;--bs-table-active-color: #000;--bs-table-hover-bg: #ebdcc3;--bs-table-hover-color: #000;color:#000;border-color:#e5d6be}.table-danger{--bs-table-bg: #ffdcd2;--bs-table-striped-bg: #f2d1c8;--bs-table-striped-color: #000;--bs-table-active-bg: #e6c6bd;--bs-table-active-color: #000;--bs-table-hover-bg: #ecccc2;--bs-table-hover-color: #000;color:#000;border-color:#e6c6bd}.table-light{--bs-table-bg: #616161;--bs-table-striped-bg: dimgray;--bs-table-striped-color: #fff;--bs-table-active-bg: #717171;--bs-table-active-color: #fff;--bs-table-hover-bg: #6d6d6d;--bs-table-hover-color: #fff;color:#fff;border-color:#717171}.table-dark{--bs-table-bg: #616161;--bs-table-striped-bg: dimgray;--bs-table-striped-color: #fff;--bs-table-active-bg: #717171;--bs-table-active-color: #fff;--bs-table-hover-bg: #6d6d6d;--bs-table-hover-color: #fff;color:#fff;border-color:#717171}.table-responsive{overflow-x:auto;-webkit-overflow-scrolling:touch}@media (max-width: 575.98px){.table-responsive-sm{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width: 767.98px){.table-responsive-md{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width: 991.98px){.table-responsive-lg{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width: 1199.98px){.table-responsive-xl{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width: 1399.98px){.table-responsive-xxl{overflow-x:auto;-webkit-overflow-scrolling:touch}}.table>:not(:first-child){border-width:0}.table td,.table th{white-space:nowrap;vertical-align:middle}.table a{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border;border-bottom:0.063rem dashed var(--dark);color:var(--t42-content-color)}.table a:hover{border-bottom-color:var(--t42-content-color);border-bottom-style:solid;color:var(--t42-link-color);text-decoration:none}.table thead th{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;border-width:1px 0;color:Hsl(var(--t42-content-color-base), calc(var(--t42-content-color-l) - 20%));font-weight:normal;font-size:83.3%;text-transform:uppercase}.table td{position:relative}.table td .btn,.table td .btn-sm,.table td .btn-group-sm>.btn,.table td .btn-lg,.table td .btn-group-lg>.btn{line-height:1.25rem}.table td .btn-icon i{position:relative;top:0.0625rem}.table tr th:first-child,.table tr td:first-child{padding-left:0.5rem}.table tr th:last-child,.table tr td:last-child{padding-right:0.5rem}.table-hover tbody tr:hover{background-color:var(--t42-table-active-bg)}.table-hover tbody tr:hover a{border-bottom-color:var(--t42-content-color);color:var(--t42-link-color)}.table-responsive{border:0}.tooltip{position:absolute;z-index:1080;display:block;margin:0;font-family:"Montserrat","Helvetica Neue",Arial,sans-serif;font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.65625rem;word-wrap:break-word;opacity:0}.tooltip.show{opacity:1}.tooltip .tooltip-arrow{position:absolute;display:block;width:.8rem;height:.4rem}.tooltip .tooltip-arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-top,.bs-tooltip-auto[data-popper-placement^="top"]{padding:.4rem 0}.bs-tooltip-top .tooltip-arrow,.bs-tooltip-auto[data-popper-placement^="top"] .tooltip-arrow{bottom:0}.bs-tooltip-top .tooltip-arrow::before,.bs-tooltip-auto[data-popper-placement^="top"] .tooltip-arrow::before{top:-1px;border-width:.4rem .4rem 0;border-top-color:var(--t42-tooltip-bg)}.bs-tooltip-end,.bs-tooltip-auto[data-popper-placement^="right"]{padding:0 .4rem}.bs-tooltip-end .tooltip-arrow,.bs-tooltip-auto[data-popper-placement^="right"] .tooltip-arrow{left:0;width:.4rem;height:.8rem}.bs-tooltip-end .tooltip-arrow::before,.bs-tooltip-auto[data-popper-placement^="right"] .tooltip-arrow::before{right:-1px;border-width:.4rem .4rem .4rem 0;border-right-color:var(--t42-tooltip-bg)}.bs-tooltip-bottom,.bs-tooltip-auto[data-popper-placement^="bottom"]{padding:.4rem 0}.bs-tooltip-bottom .tooltip-arrow,.bs-tooltip-auto[data-popper-placement^="bottom"] .tooltip-arrow{top:0}.bs-tooltip-bottom .tooltip-arrow::before,.bs-tooltip-auto[data-popper-placement^="bottom"] .tooltip-arrow::before{bottom:-1px;border-width:0 .4rem .4rem;border-bottom-color:var(--t42-tooltip-bg)}.bs-tooltip-start,.bs-tooltip-auto[data-popper-placement^="left"]{padding:0 .4rem}.bs-tooltip-start .tooltip-arrow,.bs-tooltip-auto[data-popper-placement^="left"] .tooltip-arrow{right:0;width:.4rem;height:.8rem}.bs-tooltip-start .tooltip-arrow::before,.bs-tooltip-auto[data-popper-placement^="left"] .tooltip-arrow::before{left:-1px;border-width:.4rem 0 .4rem .4rem;border-left-color:var(--t42-tooltip-bg)}.tooltip-inner{max-width:200px;padding:.25rem 1rem;color:var(--t42-content-color);text-align:center;background-color:var(--t42-tooltip-bg);border-radius:0}.tooltip .tooltip-inner{border:var(--t42-border);box-shadow:var(--t42-shadow)}.bs-tooltip-top .arrow,.bs-tooltip-auto[data-popper-placement^="top"] .arrow{bottom:1px}.bs-tooltip-top .arrow::before,.bs-tooltip-auto[data-popper-placement^="top"] .arrow::before{border-top-color:var(--t42-color-opacity-10)}.bs-tooltip-bottom .arrow,.bs-tooltip-auto[data-popper-placement^="bottom"] .arrow{top:1px}.bs-tooltip-bottom .arrow::before,.bs-tooltip-auto[data-popper-placement^="bottom"] .arrow::before{border-bottom-color:var(--t42-color-opacity-10)}.bs-tooltip-right .arrow{left:1px}.bs-tooltip-right .arrow::before{border-right-color:var(--t42-color-opacity-10)}.bs-tooltip-left .arrow{right:1px}.bs-tooltip-left .arrow::before{border-left-color:var(--t42-color-opacity-10)}.fade{transition:opacity 0.15s linear}@media (prefers-reduced-motion: reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{height:0;overflow:hidden;transition:height 0.35s ease}@media (prefers-reduced-motion: reduce){.collapsing{transition:none}}.collapsing.collapse-horizontal{width:0;height:auto;transition:width 0.35s ease}@media (prefers-reduced-motion: reduce){.collapsing.collapse-horizontal{transition:none}}mark,.mark{color:var(--white)}pre{background-color:var(--t42-bg-dark)}blockquote,.blockquote{padding:1rem 1rem 0.01rem;border-left:0.25rem solid var(--secondary);background-color:Rgb(var(--t42-bg-dark))}.blockquote-footer{margin-top:-2rem;margin-left:1.25rem;color:var(--t42-content-color-muted);font-size:0.875em}.clearfix::after{display:block;clear:both;content:""}.link-primary{color:#007be5}.link-primary:hover,.link-primary:focus{color:#3395ea}.link-secondary{color:#616161}.link-secondary:hover,.link-secondary:focus{color:#4e4e4e}.link-success{color:#43a047}.link-success:hover,.link-success:focus{color:#69b36c}.link-info{color:#469eb9}.link-info:hover,.link-info:focus{color:#6bb1c7}.link-warning{color:#f9a825}.link-warning:hover,.link-warning:focus{color:#fab951}.link-danger{color:#ff511f}.link-danger:hover,.link-danger:focus{color:#ff744c}.link-light{color:#616161}.link-light:hover,.link-light:focus{color:#4e4e4e}.link-dark{color:#616161}.link-dark:hover,.link-dark:focus{color:#4e4e4e}.ratio{position:relative;width:100%}.ratio::before{display:block;padding-top:var(--bs-aspect-ratio);content:""}.ratio>*{position:absolute;top:0;left:0;width:100%;height:100%}.ratio-1x1{--bs-aspect-ratio: 100%}.ratio-4x3{--bs-aspect-ratio: calc(3 / 4 * 100%)}.ratio-16x9{--bs-aspect-ratio: calc(9 / 16 * 100%)}.ratio-21x9{--bs-aspect-ratio: calc(9 / 21 * 100%)}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}.sticky-top{position:sticky;top:0;z-index:1020}@media (min-width: 576px){.sticky-sm-top{position:sticky;top:0;z-index:1020}}@media (min-width: 768px){.sticky-md-top{position:sticky;top:0;z-index:1020}}@media (min-width: 992px){.sticky-lg-top{position:sticky;top:0;z-index:1020}}@media (min-width: 1200px){.sticky-xl-top{position:sticky;top:0;z-index:1020}}@media (min-width: 1400px){.sticky-xxl-top{position:sticky;top:0;z-index:1020}}.hstack{display:flex;flex-direction:row;align-items:center;align-self:stretch}.vstack{display:flex;flex:1 1 auto;flex-direction:column;align-self:stretch}.visually-hidden,.visually-hidden-focusable:not(:focus):not(:focus-within){position:absolute !important;width:1px !important;height:1px !important;padding:0 !important;margin:-1px !important;overflow:hidden !important;clip:rect(0, 0, 0, 0) !important;white-space:nowrap !important;border:0 !important}.stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.vr{display:inline-block;align-self:stretch;width:1px;min-height:1em;background-color:currentColor;opacity:.25}.align-baseline{vertical-align:baseline !important}.align-top{vertical-align:top !important}.align-middle{vertical-align:middle !important}.align-bottom{vertical-align:bottom !important}.align-text-bottom{vertical-align:text-bottom !important}.align-text-top{vertical-align:text-top !important}.float-start{float:left !important}.float-end{float:right !important}.float-none{float:none !important}.opacity-0{opacity:0 !important}.opacity-25{opacity:.25 !important}.opacity-50{opacity:.5 !important}.opacity-75{opacity:.75 !important}.opacity-100{opacity:1 !important}.overflow-auto{overflow:auto !important}.overflow-hidden{overflow:hidden !important}.overflow-visible{overflow:visible !important}.overflow-scroll{overflow:scroll !important}.d-inline{display:inline !important}.d-inline-block{display:inline-block !important}.d-block{display:block !important}.d-grid{display:grid !important}.d-table{display:table !important}.d-table-row{display:table-row !important}.d-table-cell{display:table-cell !important}.d-flex{display:flex !important}.d-inline-flex{display:inline-flex !important}.d-none{display:none !important}.shadow{box-shadow:0 0.5rem 1rem rgba(0,0,0,0.15) !important}.shadow-sm{box-shadow:0 0.125rem 0.25rem rgba(0,0,0,0.075) !important}.shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,0.175) !important}.shadow-none{box-shadow:none !important}.position-static{position:static !important}.position-relative{position:relative !important}.position-absolute{position:absolute !important}.position-fixed{position:fixed !important}.position-sticky{position:sticky !important}.top-0{top:0 !important}.top-50{top:50% !important}.top-100{top:100% !important}.bottom-0{bottom:0 !important}.bottom-50{bottom:50% !important}.bottom-100{bottom:100% !important}.start-0{left:0 !important}.start-50{left:50% !important}.start-100{left:100% !important}.end-0{right:0 !important}.end-50{right:50% !important}.end-100{right:100% !important}.translate-middle{transform:translate(-50%, -50%) !important}.translate-middle-x{transform:translateX(-50%) !important}.translate-middle-y{transform:translateY(-50%) !important}.border{border:1px solid #dee2e6 !important}.border-0{border:0 !important}.border-top{border-top:1px solid #dee2e6 !important}.border-top-0{border-top:0 !important}.border-end{border-right:1px solid #dee2e6 !important}.border-end-0{border-right:0 !important}.border-bottom{border-bottom:1px solid #dee2e6 !important}.border-bottom-0{border-bottom:0 !important}.border-start{border-left:1px solid #dee2e6 !important}.border-start-0{border-left:0 !important}.border-primary{border-color:#007be5 !important}.border-secondary{border-color:#616161 !important}.border-success{border-color:#43a047 !important}.border-info{border-color:#469eb9 !important}.border-warning{border-color:#f9a825 !important}.border-danger{border-color:#ff511f !important}.border-light{border-color:#616161 !important}.border-dark{border-color:#616161 !important}.border-white{border-color:#fff !important}.border-1{border-width:1px !important}.border-2{border-width:2px !important}.border-3{border-width:3px !important}.border-4{border-width:4px !important}.border-5{border-width:5px !important}.w-25{width:25% !important}.w-50{width:50% !important}.w-75{width:75% !important}.w-100{width:100% !important}.w-auto{width:auto !important}.mw-100{max-width:100% !important}.vw-100{width:100vw !important}.min-vw-100{min-width:100vw !important}.h-25{height:25% !important}.h-50{height:50% !important}.h-75{height:75% !important}.h-100{height:100% !important}.h-auto{height:auto !important}.mh-100{max-height:100% !important}.vh-100{height:100vh !important}.min-vh-100{min-height:100vh !important}.flex-fill{flex:1 1 auto !important}.flex-row{flex-direction:row !important}.flex-column{flex-direction:column !important}.flex-row-reverse{flex-direction:row-reverse !important}.flex-column-reverse{flex-direction:column-reverse !important}.flex-grow-0{flex-grow:0 !important}.flex-grow-1{flex-grow:1 !important}.flex-shrink-0{flex-shrink:0 !important}.flex-shrink-1{flex-shrink:1 !important}.flex-wrap{flex-wrap:wrap !important}.flex-nowrap{flex-wrap:nowrap !important}.flex-wrap-reverse{flex-wrap:wrap-reverse !important}.gap-0{gap:0 !important}.gap-1{gap:.25rem !important}.gap-2{gap:.5rem !important}.gap-3{gap:1rem !important}.gap-4{gap:1.5rem !important}.gap-5{gap:3rem !important}.justify-content-start{justify-content:flex-start !important}.justify-content-end{justify-content:flex-end !important}.justify-content-center{justify-content:center !important}.justify-content-between{justify-content:space-between !important}.justify-content-around{justify-content:space-around !important}.justify-content-evenly{justify-content:space-evenly !important}.align-items-start{align-items:flex-start !important}.align-items-end{align-items:flex-end !important}.align-items-center{align-items:center !important}.align-items-baseline{align-items:baseline !important}.align-items-stretch{align-items:stretch !important}.align-content-start{align-content:flex-start !important}.align-content-end{align-content:flex-end !important}.align-content-center{align-content:center !important}.align-content-between{align-content:space-between !important}.align-content-around{align-content:space-around !important}.align-content-stretch{align-content:stretch !important}.align-self-auto{align-self:auto !important}.align-self-start{align-self:flex-start !important}.align-self-end{align-self:flex-end !important}.align-self-center{align-self:center !important}.align-self-baseline{align-self:baseline !important}.align-self-stretch{align-self:stretch !important}.order-first{order:-1 !important}.order-0{order:0 !important}.order-1{order:1 !important}.order-2{order:2 !important}.order-3{order:3 !important}.order-4{order:4 !important}.order-5{order:5 !important}.order-last{order:6 !important}.m-0{margin:0 !important}.m-1{margin:.25rem !important}.m-2{margin:.5rem !important}.m-3{margin:1rem !important}.m-4{margin:1.5rem !important}.m-5{margin:3rem !important}.m-auto{margin:auto !important}.mx-0{margin-right:0 !important;margin-left:0 !important}.mx-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-3{margin-right:1rem !important;margin-left:1rem !important}.mx-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-5{margin-right:3rem !important;margin-left:3rem !important}.mx-auto{margin-right:auto !important;margin-left:auto !important}.my-0{margin-top:0 !important;margin-bottom:0 !important}.my-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-0{margin-top:0 !important}.mt-1{margin-top:.25rem !important}.mt-2{margin-top:.5rem !important}.mt-3{margin-top:1rem !important}.mt-4{margin-top:1.5rem !important}.mt-5{margin-top:3rem !important}.mt-auto{margin-top:auto !important}.me-0{margin-right:0 !important}.me-1{margin-right:.25rem !important}.me-2{margin-right:.5rem !important}.me-3{margin-right:1rem !important}.me-4{margin-right:1.5rem !important}.me-5{margin-right:3rem !important}.me-auto{margin-right:auto !important}.mb-0{margin-bottom:0 !important}.mb-1{margin-bottom:.25rem !important}.mb-2{margin-bottom:.5rem !important}.mb-3{margin-bottom:1rem !important}.mb-4{margin-bottom:1.5rem !important}.mb-5{margin-bottom:3rem !important}.mb-auto{margin-bottom:auto !important}.ms-0{margin-left:0 !important}.ms-1{margin-left:.25rem !important}.ms-2{margin-left:.5rem !important}.ms-3{margin-left:1rem !important}.ms-4{margin-left:1.5rem !important}.ms-5{margin-left:3rem !important}.ms-auto{margin-left:auto !important}.p-0{padding:0 !important}.p-1{padding:.25rem !important}.p-2{padding:.5rem !important}.p-3{padding:1rem !important}.p-4{padding:1.5rem !important}.p-5{padding:3rem !important}.px-0{padding-right:0 !important;padding-left:0 !important}.px-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-3{padding-right:1rem !important;padding-left:1rem !important}.px-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-5{padding-right:3rem !important;padding-left:3rem !important}.py-0{padding-top:0 !important;padding-bottom:0 !important}.py-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-0{padding-top:0 !important}.pt-1{padding-top:.25rem !important}.pt-2{padding-top:.5rem !important}.pt-3{padding-top:1rem !important}.pt-4{padding-top:1.5rem !important}.pt-5{padding-top:3rem !important}.pe-0{padding-right:0 !important}.pe-1{padding-right:.25rem !important}.pe-2{padding-right:.5rem !important}.pe-3{padding-right:1rem !important}.pe-4{padding-right:1.5rem !important}.pe-5{padding-right:3rem !important}.pb-0{padding-bottom:0 !important}.pb-1{padding-bottom:.25rem !important}.pb-2{padding-bottom:.5rem !important}.pb-3{padding-bottom:1rem !important}.pb-4{padding-bottom:1.5rem !important}.pb-5{padding-bottom:3rem !important}.ps-0{padding-left:0 !important}.ps-1{padding-left:.25rem !important}.ps-2{padding-left:.5rem !important}.ps-3{padding-left:1rem !important}.ps-4{padding-left:1.5rem !important}.ps-5{padding-left:3rem !important}.font-monospace{font-family:var(--bs-font-monospace) !important}.fs-1{font-size:calc(1.26563rem + .1875vw) !important}.fs-2{font-size:1.125rem !important}.fs-3{font-size:.98475rem !important}.fs-4{font-size:.84375rem !important}.fs-5{font-size:.75rem !important}.fs-6{font-size:.7035rem !important}.fst-italic{font-style:italic !important}.fst-normal{font-style:normal !important}.fw-light{font-weight:300 !important}.fw-lighter{font-weight:lighter !important}.fw-normal{font-weight:400 !important}.fw-bold{font-weight:700 !important}.fw-bolder{font-weight:bolder !important}.lh-1{line-height:1 !important}.lh-sm{line-height:1.25 !important}.lh-base{line-height:1.5 !important}.lh-lg{line-height:2 !important}.text-start{text-align:left !important}.text-end{text-align:right !important}.text-center{text-align:center !important}.text-decoration-none{text-decoration:none !important}.text-decoration-underline{text-decoration:underline !important}.text-decoration-line-through{text-decoration:line-through !important}.text-lowercase{text-transform:lowercase !important}.text-uppercase{text-transform:uppercase !important}.text-capitalize{text-transform:capitalize !important}.text-wrap{white-space:normal !important}.text-nowrap{white-space:nowrap !important}.text-break{word-wrap:break-word !important;word-break:break-word !important}.text-primary{--bs-text-opacity: 1;color:rgba(var(--bs-primary-rgb), var(--bs-text-opacity)) !important}.text-secondary{--bs-text-opacity: 1;color:rgba(var(--bs-secondary-rgb), var(--bs-text-opacity)) !important}.text-success{--bs-text-opacity: 1;color:rgba(var(--bs-success-rgb), var(--bs-text-opacity)) !important}.text-info{--bs-text-opacity: 1;color:rgba(var(--bs-info-rgb), var(--bs-text-opacity)) !important}.text-warning{--bs-text-opacity: 1;color:rgba(var(--bs-warning-rgb), var(--bs-text-opacity)) !important}.text-danger{--bs-text-opacity: 1;color:rgba(var(--bs-danger-rgb), var(--bs-text-opacity)) !important}.text-light{--bs-text-opacity: 1;color:rgba(var(--bs-light-rgb), var(--bs-text-opacity)) !important}.text-dark{--bs-text-opacity: 1;color:rgba(var(--bs-dark-rgb), var(--bs-text-opacity)) !important}.text-black{--bs-text-opacity: 1;color:rgba(var(--bs-black-rgb), var(--bs-text-opacity)) !important}.text-white{--bs-text-opacity: 1;color:rgba(var(--bs-white-rgb), var(--bs-text-opacity)) !important}.text-body{--bs-text-opacity: 1;color:rgba(var(--bs-body-color-rgb), var(--bs-text-opacity)) !important}.text-muted{--bs-text-opacity: 1;color:var(--t42-content-color-muted) !important}.text-black-50{--bs-text-opacity: 1;color:rgba(0,0,0,0.5) !important}.text-white-50{--bs-text-opacity: 1;color:rgba(255,255,255,0.5) !important}.text-reset{--bs-text-opacity: 1;color:inherit !important}.text-opacity-25{--bs-text-opacity: .25}.text-opacity-50{--bs-text-opacity: .5}.text-opacity-75{--bs-text-opacity: .75}.text-opacity-100{--bs-text-opacity: 1}.bg-primary{--bs-bg-opacity: 1;background-color:rgba(var(--bs-primary-rgb), var(--bs-bg-opacity)) !important}.bg-secondary{--bs-bg-opacity: 1;background-color:rgba(var(--bs-secondary-rgb), var(--bs-bg-opacity)) !important}.bg-success{--bs-bg-opacity: 1;background-color:rgba(var(--bs-success-rgb), var(--bs-bg-opacity)) !important}.bg-info{--bs-bg-opacity: 1;background-color:rgba(var(--bs-info-rgb), var(--bs-bg-opacity)) !important}.bg-warning{--bs-bg-opacity: 1;background-color:rgba(var(--bs-warning-rgb), var(--bs-bg-opacity)) !important}.bg-danger{--bs-bg-opacity: 1;background-color:rgba(var(--bs-danger-rgb), var(--bs-bg-opacity)) !important}.bg-light{--bs-bg-opacity: 1;background-color:rgba(var(--bs-light-rgb), var(--bs-bg-opacity)) !important}.bg-dark{--bs-bg-opacity: 1;background-color:rgba(var(--bs-dark-rgb), var(--bs-bg-opacity)) !important}.bg-black{--bs-bg-opacity: 1;background-color:rgba(var(--bs-black-rgb), var(--bs-bg-opacity)) !important}.bg-white{--bs-bg-opacity: 1;background-color:rgba(var(--bs-white-rgb), var(--bs-bg-opacity)) !important}.bg-body{--bs-bg-opacity: 1;background-color:rgba(var(--bs-body-bg-rgb), var(--bs-bg-opacity)) !important}.bg-transparent{--bs-bg-opacity: 1;background-color:rgba(0,0,0,0) !important}.bg-opacity-10{--bs-bg-opacity: .1}.bg-opacity-25{--bs-bg-opacity: .25}.bg-opacity-50{--bs-bg-opacity: .5}.bg-opacity-75{--bs-bg-opacity: .75}.bg-opacity-100{--bs-bg-opacity: 1}.bg-gradient{background-image:var(--bs-gradient) !important}.user-select-all{user-select:all !important}.user-select-auto{user-select:auto !important}.user-select-none{user-select:none !important}.pe-none{pointer-events:none !important}.pe-auto{pointer-events:auto !important}.rounded{border-radius:.25rem !important}.rounded-0{border-radius:0 !important}.rounded-1{border-radius:.25rem !important}.rounded-2{border-radius:.25rem !important}.rounded-3{border-radius:1rem !important}.rounded-circle{border-radius:50% !important}.rounded-pill{border-radius:50rem !important}.rounded-top{border-top-left-radius:.25rem !important;border-top-right-radius:.25rem !important}.rounded-end{border-top-right-radius:.25rem !important;border-bottom-right-radius:.25rem !important}.rounded-bottom{border-bottom-right-radius:.25rem !important;border-bottom-left-radius:.25rem !important}.rounded-start{border-bottom-left-radius:.25rem !important;border-top-left-radius:.25rem !important}.visible{visibility:visible !important}.invisible{visibility:hidden !important}@media (min-width: 576px){.float-sm-start{float:left !important}.float-sm-end{float:right !important}.float-sm-none{float:none !important}.d-sm-inline{display:inline !important}.d-sm-inline-block{display:inline-block !important}.d-sm-block{display:block !important}.d-sm-grid{display:grid !important}.d-sm-table{display:table !important}.d-sm-table-row{display:table-row !important}.d-sm-table-cell{display:table-cell !important}.d-sm-flex{display:flex !important}.d-sm-inline-flex{display:inline-flex !important}.d-sm-none{display:none !important}.flex-sm-fill{flex:1 1 auto !important}.flex-sm-row{flex-direction:row !important}.flex-sm-column{flex-direction:column !important}.flex-sm-row-reverse{flex-direction:row-reverse !important}.flex-sm-column-reverse{flex-direction:column-reverse !important}.flex-sm-grow-0{flex-grow:0 !important}.flex-sm-grow-1{flex-grow:1 !important}.flex-sm-shrink-0{flex-shrink:0 !important}.flex-sm-shrink-1{flex-shrink:1 !important}.flex-sm-wrap{flex-wrap:wrap !important}.flex-sm-nowrap{flex-wrap:nowrap !important}.flex-sm-wrap-reverse{flex-wrap:wrap-reverse !important}.gap-sm-0{gap:0 !important}.gap-sm-1{gap:.25rem !important}.gap-sm-2{gap:.5rem !important}.gap-sm-3{gap:1rem !important}.gap-sm-4{gap:1.5rem !important}.gap-sm-5{gap:3rem !important}.justify-content-sm-start{justify-content:flex-start !important}.justify-content-sm-end{justify-content:flex-end !important}.justify-content-sm-center{justify-content:center !important}.justify-content-sm-between{justify-content:space-between !important}.justify-content-sm-around{justify-content:space-around !important}.justify-content-sm-evenly{justify-content:space-evenly !important}.align-items-sm-start{align-items:flex-start !important}.align-items-sm-end{align-items:flex-end !important}.align-items-sm-center{align-items:center !important}.align-items-sm-baseline{align-items:baseline !important}.align-items-sm-stretch{align-items:stretch !important}.align-content-sm-start{align-content:flex-start !important}.align-content-sm-end{align-content:flex-end !important}.align-content-sm-center{align-content:center !important}.align-content-sm-between{align-content:space-between !important}.align-content-sm-around{align-content:space-around !important}.align-content-sm-stretch{align-content:stretch !important}.align-self-sm-auto{align-self:auto !important}.align-self-sm-start{align-self:flex-start !important}.align-self-sm-end{align-self:flex-end !important}.align-self-sm-center{align-self:center !important}.align-self-sm-baseline{align-self:baseline !important}.align-self-sm-stretch{align-self:stretch !important}.order-sm-first{order:-1 !important}.order-sm-0{order:0 !important}.order-sm-1{order:1 !important}.order-sm-2{order:2 !important}.order-sm-3{order:3 !important}.order-sm-4{order:4 !important}.order-sm-5{order:5 !important}.order-sm-last{order:6 !important}.m-sm-0{margin:0 !important}.m-sm-1{margin:.25rem !important}.m-sm-2{margin:.5rem !important}.m-sm-3{margin:1rem !important}.m-sm-4{margin:1.5rem !important}.m-sm-5{margin:3rem !important}.m-sm-auto{margin:auto !important}.mx-sm-0{margin-right:0 !important;margin-left:0 !important}.mx-sm-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-sm-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-sm-3{margin-right:1rem !important;margin-left:1rem !important}.mx-sm-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-sm-5{margin-right:3rem !important;margin-left:3rem !important}.mx-sm-auto{margin-right:auto !important;margin-left:auto !important}.my-sm-0{margin-top:0 !important;margin-bottom:0 !important}.my-sm-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-sm-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-sm-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-sm-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-sm-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-sm-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-sm-0{margin-top:0 !important}.mt-sm-1{margin-top:.25rem !important}.mt-sm-2{margin-top:.5rem !important}.mt-sm-3{margin-top:1rem !important}.mt-sm-4{margin-top:1.5rem !important}.mt-sm-5{margin-top:3rem !important}.mt-sm-auto{margin-top:auto !important}.me-sm-0{margin-right:0 !important}.me-sm-1{margin-right:.25rem !important}.me-sm-2{margin-right:.5rem !important}.me-sm-3{margin-right:1rem !important}.me-sm-4{margin-right:1.5rem !important}.me-sm-5{margin-right:3rem !important}.me-sm-auto{margin-right:auto !important}.mb-sm-0{margin-bottom:0 !important}.mb-sm-1{margin-bottom:.25rem !important}.mb-sm-2{margin-bottom:.5rem !important}.mb-sm-3{margin-bottom:1rem !important}.mb-sm-4{margin-bottom:1.5rem !important}.mb-sm-5{margin-bottom:3rem !important}.mb-sm-auto{margin-bottom:auto !important}.ms-sm-0{margin-left:0 !important}.ms-sm-1{margin-left:.25rem !important}.ms-sm-2{margin-left:.5rem !important}.ms-sm-3{margin-left:1rem !important}.ms-sm-4{margin-left:1.5rem !important}.ms-sm-5{margin-left:3rem !important}.ms-sm-auto{margin-left:auto !important}.p-sm-0{padding:0 !important}.p-sm-1{padding:.25rem !important}.p-sm-2{padding:.5rem !important}.p-sm-3{padding:1rem !important}.p-sm-4{padding:1.5rem !important}.p-sm-5{padding:3rem !important}.px-sm-0{padding-right:0 !important;padding-left:0 !important}.px-sm-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-sm-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-sm-3{padding-right:1rem !important;padding-left:1rem !important}.px-sm-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-sm-5{padding-right:3rem !important;padding-left:3rem !important}.py-sm-0{padding-top:0 !important;padding-bottom:0 !important}.py-sm-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-sm-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-sm-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-sm-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-sm-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-sm-0{padding-top:0 !important}.pt-sm-1{padding-top:.25rem !important}.pt-sm-2{padding-top:.5rem !important}.pt-sm-3{padding-top:1rem !important}.pt-sm-4{padding-top:1.5rem !important}.pt-sm-5{padding-top:3rem !important}.pe-sm-0{padding-right:0 !important}.pe-sm-1{padding-right:.25rem !important}.pe-sm-2{padding-right:.5rem !important}.pe-sm-3{padding-right:1rem !important}.pe-sm-4{padding-right:1.5rem !important}.pe-sm-5{padding-right:3rem !important}.pb-sm-0{padding-bottom:0 !important}.pb-sm-1{padding-bottom:.25rem !important}.pb-sm-2{padding-bottom:.5rem !important}.pb-sm-3{padding-bottom:1rem !important}.pb-sm-4{padding-bottom:1.5rem !important}.pb-sm-5{padding-bottom:3rem !important}.ps-sm-0{padding-left:0 !important}.ps-sm-1{padding-left:.25rem !important}.ps-sm-2{padding-left:.5rem !important}.ps-sm-3{padding-left:1rem !important}.ps-sm-4{padding-left:1.5rem !important}.ps-sm-5{padding-left:3rem !important}.text-sm-start{text-align:left !important}.text-sm-end{text-align:right !important}.text-sm-center{text-align:center !important}}@media (min-width: 768px){.float-md-start{float:left !important}.float-md-end{float:right !important}.float-md-none{float:none !important}.d-md-inline{display:inline !important}.d-md-inline-block{display:inline-block !important}.d-md-block{display:block !important}.d-md-grid{display:grid !important}.d-md-table{display:table !important}.d-md-table-row{display:table-row !important}.d-md-table-cell{display:table-cell !important}.d-md-flex{display:flex !important}.d-md-inline-flex{display:inline-flex !important}.d-md-none{display:none !important}.flex-md-fill{flex:1 1 auto !important}.flex-md-row{flex-direction:row !important}.flex-md-column{flex-direction:column !important}.flex-md-row-reverse{flex-direction:row-reverse !important}.flex-md-column-reverse{flex-direction:column-reverse !important}.flex-md-grow-0{flex-grow:0 !important}.flex-md-grow-1{flex-grow:1 !important}.flex-md-shrink-0{flex-shrink:0 !important}.flex-md-shrink-1{flex-shrink:1 !important}.flex-md-wrap{flex-wrap:wrap !important}.flex-md-nowrap{flex-wrap:nowrap !important}.flex-md-wrap-reverse{flex-wrap:wrap-reverse !important}.gap-md-0{gap:0 !important}.gap-md-1{gap:.25rem !important}.gap-md-2{gap:.5rem !important}.gap-md-3{gap:1rem !important}.gap-md-4{gap:1.5rem !important}.gap-md-5{gap:3rem !important}.justify-content-md-start{justify-content:flex-start !important}.justify-content-md-end{justify-content:flex-end !important}.justify-content-md-center{justify-content:center !important}.justify-content-md-between{justify-content:space-between !important}.justify-content-md-around{justify-content:space-around !important}.justify-content-md-evenly{justify-content:space-evenly !important}.align-items-md-start{align-items:flex-start !important}.align-items-md-end{align-items:flex-end !important}.align-items-md-center{align-items:center !important}.align-items-md-baseline{align-items:baseline !important}.align-items-md-stretch{align-items:stretch !important}.align-content-md-start{align-content:flex-start !important}.align-content-md-end{align-content:flex-end !important}.align-content-md-center{align-content:center !important}.align-content-md-between{align-content:space-between !important}.align-content-md-around{align-content:space-around !important}.align-content-md-stretch{align-content:stretch !important}.align-self-md-auto{align-self:auto !important}.align-self-md-start{align-self:flex-start !important}.align-self-md-end{align-self:flex-end !important}.align-self-md-center{align-self:center !important}.align-self-md-baseline{align-self:baseline !important}.align-self-md-stretch{align-self:stretch !important}.order-md-first{order:-1 !important}.order-md-0{order:0 !important}.order-md-1{order:1 !important}.order-md-2{order:2 !important}.order-md-3{order:3 !important}.order-md-4{order:4 !important}.order-md-5{order:5 !important}.order-md-last{order:6 !important}.m-md-0{margin:0 !important}.m-md-1{margin:.25rem !important}.m-md-2{margin:.5rem !important}.m-md-3{margin:1rem !important}.m-md-4{margin:1.5rem !important}.m-md-5{margin:3rem !important}.m-md-auto{margin:auto !important}.mx-md-0{margin-right:0 !important;margin-left:0 !important}.mx-md-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-md-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-md-3{margin-right:1rem !important;margin-left:1rem !important}.mx-md-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-md-5{margin-right:3rem !important;margin-left:3rem !important}.mx-md-auto{margin-right:auto !important;margin-left:auto !important}.my-md-0{margin-top:0 !important;margin-bottom:0 !important}.my-md-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-md-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-md-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-md-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-md-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-md-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-md-0{margin-top:0 !important}.mt-md-1{margin-top:.25rem !important}.mt-md-2{margin-top:.5rem !important}.mt-md-3{margin-top:1rem !important}.mt-md-4{margin-top:1.5rem !important}.mt-md-5{margin-top:3rem !important}.mt-md-auto{margin-top:auto !important}.me-md-0{margin-right:0 !important}.me-md-1{margin-right:.25rem !important}.me-md-2{margin-right:.5rem !important}.me-md-3{margin-right:1rem !important}.me-md-4{margin-right:1.5rem !important}.me-md-5{margin-right:3rem !important}.me-md-auto{margin-right:auto !important}.mb-md-0{margin-bottom:0 !important}.mb-md-1{margin-bottom:.25rem !important}.mb-md-2{margin-bottom:.5rem !important}.mb-md-3{margin-bottom:1rem !important}.mb-md-4{margin-bottom:1.5rem !important}.mb-md-5{margin-bottom:3rem !important}.mb-md-auto{margin-bottom:auto !important}.ms-md-0{margin-left:0 !important}.ms-md-1{margin-left:.25rem !important}.ms-md-2{margin-left:.5rem !important}.ms-md-3{margin-left:1rem !important}.ms-md-4{margin-left:1.5rem !important}.ms-md-5{margin-left:3rem !important}.ms-md-auto{margin-left:auto !important}.p-md-0{padding:0 !important}.p-md-1{padding:.25rem !important}.p-md-2{padding:.5rem !important}.p-md-3{padding:1rem !important}.p-md-4{padding:1.5rem !important}.p-md-5{padding:3rem !important}.px-md-0{padding-right:0 !important;padding-left:0 !important}.px-md-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-md-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-md-3{padding-right:1rem !important;padding-left:1rem !important}.px-md-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-md-5{padding-right:3rem !important;padding-left:3rem !important}.py-md-0{padding-top:0 !important;padding-bottom:0 !important}.py-md-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-md-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-md-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-md-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-md-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-md-0{padding-top:0 !important}.pt-md-1{padding-top:.25rem !important}.pt-md-2{padding-top:.5rem !important}.pt-md-3{padding-top:1rem !important}.pt-md-4{padding-top:1.5rem !important}.pt-md-5{padding-top:3rem !important}.pe-md-0{padding-right:0 !important}.pe-md-1{padding-right:.25rem !important}.pe-md-2{padding-right:.5rem !important}.pe-md-3{padding-right:1rem !important}.pe-md-4{padding-right:1.5rem !important}.pe-md-5{padding-right:3rem !important}.pb-md-0{padding-bottom:0 !important}.pb-md-1{padding-bottom:.25rem !important}.pb-md-2{padding-bottom:.5rem !important}.pb-md-3{padding-bottom:1rem !important}.pb-md-4{padding-bottom:1.5rem !important}.pb-md-5{padding-bottom:3rem !important}.ps-md-0{padding-left:0 !important}.ps-md-1{padding-left:.25rem !important}.ps-md-2{padding-left:.5rem !important}.ps-md-3{padding-left:1rem !important}.ps-md-4{padding-left:1.5rem !important}.ps-md-5{padding-left:3rem !important}.text-md-start{text-align:left !important}.text-md-end{text-align:right !important}.text-md-center{text-align:center !important}}@media (min-width: 992px){.float-lg-start{float:left !important}.float-lg-end{float:right !important}.float-lg-none{float:none !important}.d-lg-inline{display:inline !important}.d-lg-inline-block{display:inline-block !important}.d-lg-block{display:block !important}.d-lg-grid{display:grid !important}.d-lg-table{display:table !important}.d-lg-table-row{display:table-row !important}.d-lg-table-cell{display:table-cell !important}.d-lg-flex{display:flex !important}.d-lg-inline-flex{display:inline-flex !important}.d-lg-none{display:none !important}.flex-lg-fill{flex:1 1 auto !important}.flex-lg-row{flex-direction:row !important}.flex-lg-column{flex-direction:column !important}.flex-lg-row-reverse{flex-direction:row-reverse !important}.flex-lg-column-reverse{flex-direction:column-reverse !important}.flex-lg-grow-0{flex-grow:0 !important}.flex-lg-grow-1{flex-grow:1 !important}.flex-lg-shrink-0{flex-shrink:0 !important}.flex-lg-shrink-1{flex-shrink:1 !important}.flex-lg-wrap{flex-wrap:wrap !important}.flex-lg-nowrap{flex-wrap:nowrap !important}.flex-lg-wrap-reverse{flex-wrap:wrap-reverse !important}.gap-lg-0{gap:0 !important}.gap-lg-1{gap:.25rem !important}.gap-lg-2{gap:.5rem !important}.gap-lg-3{gap:1rem !important}.gap-lg-4{gap:1.5rem !important}.gap-lg-5{gap:3rem !important}.justify-content-lg-start{justify-content:flex-start !important}.justify-content-lg-end{justify-content:flex-end !important}.justify-content-lg-center{justify-content:center !important}.justify-content-lg-between{justify-content:space-between !important}.justify-content-lg-around{justify-content:space-around !important}.justify-content-lg-evenly{justify-content:space-evenly !important}.align-items-lg-start{align-items:flex-start !important}.align-items-lg-end{align-items:flex-end !important}.align-items-lg-center{align-items:center !important}.align-items-lg-baseline{align-items:baseline !important}.align-items-lg-stretch{align-items:stretch !important}.align-content-lg-start{align-content:flex-start !important}.align-content-lg-end{align-content:flex-end !important}.align-content-lg-center{align-content:center !important}.align-content-lg-between{align-content:space-between !important}.align-content-lg-around{align-content:space-around !important}.align-content-lg-stretch{align-content:stretch !important}.align-self-lg-auto{align-self:auto !important}.align-self-lg-start{align-self:flex-start !important}.align-self-lg-end{align-self:flex-end !important}.align-self-lg-center{align-self:center !important}.align-self-lg-baseline{align-self:baseline !important}.align-self-lg-stretch{align-self:stretch !important}.order-lg-first{order:-1 !important}.order-lg-0{order:0 !important}.order-lg-1{order:1 !important}.order-lg-2{order:2 !important}.order-lg-3{order:3 !important}.order-lg-4{order:4 !important}.order-lg-5{order:5 !important}.order-lg-last{order:6 !important}.m-lg-0{margin:0 !important}.m-lg-1{margin:.25rem !important}.m-lg-2{margin:.5rem !important}.m-lg-3{margin:1rem !important}.m-lg-4{margin:1.5rem !important}.m-lg-5{margin:3rem !important}.m-lg-auto{margin:auto !important}.mx-lg-0{margin-right:0 !important;margin-left:0 !important}.mx-lg-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-lg-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-lg-3{margin-right:1rem !important;margin-left:1rem !important}.mx-lg-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-lg-5{margin-right:3rem !important;margin-left:3rem !important}.mx-lg-auto{margin-right:auto !important;margin-left:auto !important}.my-lg-0{margin-top:0 !important;margin-bottom:0 !important}.my-lg-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-lg-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-lg-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-lg-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-lg-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-lg-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-lg-0{margin-top:0 !important}.mt-lg-1{margin-top:.25rem !important}.mt-lg-2{margin-top:.5rem !important}.mt-lg-3{margin-top:1rem !important}.mt-lg-4{margin-top:1.5rem !important}.mt-lg-5{margin-top:3rem !important}.mt-lg-auto{margin-top:auto !important}.me-lg-0{margin-right:0 !important}.me-lg-1{margin-right:.25rem !important}.me-lg-2{margin-right:.5rem !important}.me-lg-3{margin-right:1rem !important}.me-lg-4{margin-right:1.5rem !important}.me-lg-5{margin-right:3rem !important}.me-lg-auto{margin-right:auto !important}.mb-lg-0{margin-bottom:0 !important}.mb-lg-1{margin-bottom:.25rem !important}.mb-lg-2{margin-bottom:.5rem !important}.mb-lg-3{margin-bottom:1rem !important}.mb-lg-4{margin-bottom:1.5rem !important}.mb-lg-5{margin-bottom:3rem !important}.mb-lg-auto{margin-bottom:auto !important}.ms-lg-0{margin-left:0 !important}.ms-lg-1{margin-left:.25rem !important}.ms-lg-2{margin-left:.5rem !important}.ms-lg-3{margin-left:1rem !important}.ms-lg-4{margin-left:1.5rem !important}.ms-lg-5{margin-left:3rem !important}.ms-lg-auto{margin-left:auto !important}.p-lg-0{padding:0 !important}.p-lg-1{padding:.25rem !important}.p-lg-2{padding:.5rem !important}.p-lg-3{padding:1rem !important}.p-lg-4{padding:1.5rem !important}.p-lg-5{padding:3rem !important}.px-lg-0{padding-right:0 !important;padding-left:0 !important}.px-lg-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-lg-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-lg-3{padding-right:1rem !important;padding-left:1rem !important}.px-lg-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-lg-5{padding-right:3rem !important;padding-left:3rem !important}.py-lg-0{padding-top:0 !important;padding-bottom:0 !important}.py-lg-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-lg-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-lg-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-lg-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-lg-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-lg-0{padding-top:0 !important}.pt-lg-1{padding-top:.25rem !important}.pt-lg-2{padding-top:.5rem !important}.pt-lg-3{padding-top:1rem !important}.pt-lg-4{padding-top:1.5rem !important}.pt-lg-5{padding-top:3rem !important}.pe-lg-0{padding-right:0 !important}.pe-lg-1{padding-right:.25rem !important}.pe-lg-2{padding-right:.5rem !important}.pe-lg-3{padding-right:1rem !important}.pe-lg-4{padding-right:1.5rem !important}.pe-lg-5{padding-right:3rem !important}.pb-lg-0{padding-bottom:0 !important}.pb-lg-1{padding-bottom:.25rem !important}.pb-lg-2{padding-bottom:.5rem !important}.pb-lg-3{padding-bottom:1rem !important}.pb-lg-4{padding-bottom:1.5rem !important}.pb-lg-5{padding-bottom:3rem !important}.ps-lg-0{padding-left:0 !important}.ps-lg-1{padding-left:.25rem !important}.ps-lg-2{padding-left:.5rem !important}.ps-lg-3{padding-left:1rem !important}.ps-lg-4{padding-left:1.5rem !important}.ps-lg-5{padding-left:3rem !important}.text-lg-start{text-align:left !important}.text-lg-end{text-align:right !important}.text-lg-center{text-align:center !important}}@media (min-width: 1200px){.float-xl-start{float:left !important}.float-xl-end{float:right !important}.float-xl-none{float:none !important}.d-xl-inline{display:inline !important}.d-xl-inline-block{display:inline-block !important}.d-xl-block{display:block !important}.d-xl-grid{display:grid !important}.d-xl-table{display:table !important}.d-xl-table-row{display:table-row !important}.d-xl-table-cell{display:table-cell !important}.d-xl-flex{display:flex !important}.d-xl-inline-flex{display:inline-flex !important}.d-xl-none{display:none !important}.flex-xl-fill{flex:1 1 auto !important}.flex-xl-row{flex-direction:row !important}.flex-xl-column{flex-direction:column !important}.flex-xl-row-reverse{flex-direction:row-reverse !important}.flex-xl-column-reverse{flex-direction:column-reverse !important}.flex-xl-grow-0{flex-grow:0 !important}.flex-xl-grow-1{flex-grow:1 !important}.flex-xl-shrink-0{flex-shrink:0 !important}.flex-xl-shrink-1{flex-shrink:1 !important}.flex-xl-wrap{flex-wrap:wrap !important}.flex-xl-nowrap{flex-wrap:nowrap !important}.flex-xl-wrap-reverse{flex-wrap:wrap-reverse !important}.gap-xl-0{gap:0 !important}.gap-xl-1{gap:.25rem !important}.gap-xl-2{gap:.5rem !important}.gap-xl-3{gap:1rem !important}.gap-xl-4{gap:1.5rem !important}.gap-xl-5{gap:3rem !important}.justify-content-xl-start{justify-content:flex-start !important}.justify-content-xl-end{justify-content:flex-end !important}.justify-content-xl-center{justify-content:center !important}.justify-content-xl-between{justify-content:space-between !important}.justify-content-xl-around{justify-content:space-around !important}.justify-content-xl-evenly{justify-content:space-evenly !important}.align-items-xl-start{align-items:flex-start !important}.align-items-xl-end{align-items:flex-end !important}.align-items-xl-center{align-items:center !important}.align-items-xl-baseline{align-items:baseline !important}.align-items-xl-stretch{align-items:stretch !important}.align-content-xl-start{align-content:flex-start !important}.align-content-xl-end{align-content:flex-end !important}.align-content-xl-center{align-content:center !important}.align-content-xl-between{align-content:space-between !important}.align-content-xl-around{align-content:space-around !important}.align-content-xl-stretch{align-content:stretch !important}.align-self-xl-auto{align-self:auto !important}.align-self-xl-start{align-self:flex-start !important}.align-self-xl-end{align-self:flex-end !important}.align-self-xl-center{align-self:center !important}.align-self-xl-baseline{align-self:baseline !important}.align-self-xl-stretch{align-self:stretch !important}.order-xl-first{order:-1 !important}.order-xl-0{order:0 !important}.order-xl-1{order:1 !important}.order-xl-2{order:2 !important}.order-xl-3{order:3 !important}.order-xl-4{order:4 !important}.order-xl-5{order:5 !important}.order-xl-last{order:6 !important}.m-xl-0{margin:0 !important}.m-xl-1{margin:.25rem !important}.m-xl-2{margin:.5rem !important}.m-xl-3{margin:1rem !important}.m-xl-4{margin:1.5rem !important}.m-xl-5{margin:3rem !important}.m-xl-auto{margin:auto !important}.mx-xl-0{margin-right:0 !important;margin-left:0 !important}.mx-xl-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-xl-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-xl-3{margin-right:1rem !important;margin-left:1rem !important}.mx-xl-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-xl-5{margin-right:3rem !important;margin-left:3rem !important}.mx-xl-auto{margin-right:auto !important;margin-left:auto !important}.my-xl-0{margin-top:0 !important;margin-bottom:0 !important}.my-xl-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-xl-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-xl-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-xl-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-xl-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-xl-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-xl-0{margin-top:0 !important}.mt-xl-1{margin-top:.25rem !important}.mt-xl-2{margin-top:.5rem !important}.mt-xl-3{margin-top:1rem !important}.mt-xl-4{margin-top:1.5rem !important}.mt-xl-5{margin-top:3rem !important}.mt-xl-auto{margin-top:auto !important}.me-xl-0{margin-right:0 !important}.me-xl-1{margin-right:.25rem !important}.me-xl-2{margin-right:.5rem !important}.me-xl-3{margin-right:1rem !important}.me-xl-4{margin-right:1.5rem !important}.me-xl-5{margin-right:3rem !important}.me-xl-auto{margin-right:auto !important}.mb-xl-0{margin-bottom:0 !important}.mb-xl-1{margin-bottom:.25rem !important}.mb-xl-2{margin-bottom:.5rem !important}.mb-xl-3{margin-bottom:1rem !important}.mb-xl-4{margin-bottom:1.5rem !important}.mb-xl-5{margin-bottom:3rem !important}.mb-xl-auto{margin-bottom:auto !important}.ms-xl-0{margin-left:0 !important}.ms-xl-1{margin-left:.25rem !important}.ms-xl-2{margin-left:.5rem !important}.ms-xl-3{margin-left:1rem !important}.ms-xl-4{margin-left:1.5rem !important}.ms-xl-5{margin-left:3rem !important}.ms-xl-auto{margin-left:auto !important}.p-xl-0{padding:0 !important}.p-xl-1{padding:.25rem !important}.p-xl-2{padding:.5rem !important}.p-xl-3{padding:1rem !important}.p-xl-4{padding:1.5rem !important}.p-xl-5{padding:3rem !important}.px-xl-0{padding-right:0 !important;padding-left:0 !important}.px-xl-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-xl-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-xl-3{padding-right:1rem !important;padding-left:1rem !important}.px-xl-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-xl-5{padding-right:3rem !important;padding-left:3rem !important}.py-xl-0{padding-top:0 !important;padding-bottom:0 !important}.py-xl-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-xl-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-xl-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-xl-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-xl-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-xl-0{padding-top:0 !important}.pt-xl-1{padding-top:.25rem !important}.pt-xl-2{padding-top:.5rem !important}.pt-xl-3{padding-top:1rem !important}.pt-xl-4{padding-top:1.5rem !important}.pt-xl-5{padding-top:3rem !important}.pe-xl-0{padding-right:0 !important}.pe-xl-1{padding-right:.25rem !important}.pe-xl-2{padding-right:.5rem !important}.pe-xl-3{padding-right:1rem !important}.pe-xl-4{padding-right:1.5rem !important}.pe-xl-5{padding-right:3rem !important}.pb-xl-0{padding-bottom:0 !important}.pb-xl-1{padding-bottom:.25rem !important}.pb-xl-2{padding-bottom:.5rem !important}.pb-xl-3{padding-bottom:1rem !important}.pb-xl-4{padding-bottom:1.5rem !important}.pb-xl-5{padding-bottom:3rem !important}.ps-xl-0{padding-left:0 !important}.ps-xl-1{padding-left:.25rem !important}.ps-xl-2{padding-left:.5rem !important}.ps-xl-3{padding-left:1rem !important}.ps-xl-4{padding-left:1.5rem !important}.ps-xl-5{padding-left:3rem !important}.text-xl-start{text-align:left !important}.text-xl-end{text-align:right !important}.text-xl-center{text-align:center !important}}@media (min-width: 1400px){.float-xxl-start{float:left !important}.float-xxl-end{float:right !important}.float-xxl-none{float:none !important}.d-xxl-inline{display:inline !important}.d-xxl-inline-block{display:inline-block !important}.d-xxl-block{display:block !important}.d-xxl-grid{display:grid !important}.d-xxl-table{display:table !important}.d-xxl-table-row{display:table-row !important}.d-xxl-table-cell{display:table-cell !important}.d-xxl-flex{display:flex !important}.d-xxl-inline-flex{display:inline-flex !important}.d-xxl-none{display:none !important}.flex-xxl-fill{flex:1 1 auto !important}.flex-xxl-row{flex-direction:row !important}.flex-xxl-column{flex-direction:column !important}.flex-xxl-row-reverse{flex-direction:row-reverse !important}.flex-xxl-column-reverse{flex-direction:column-reverse !important}.flex-xxl-grow-0{flex-grow:0 !important}.flex-xxl-grow-1{flex-grow:1 !important}.flex-xxl-shrink-0{flex-shrink:0 !important}.flex-xxl-shrink-1{flex-shrink:1 !important}.flex-xxl-wrap{flex-wrap:wrap !important}.flex-xxl-nowrap{flex-wrap:nowrap !important}.flex-xxl-wrap-reverse{flex-wrap:wrap-reverse !important}.gap-xxl-0{gap:0 !important}.gap-xxl-1{gap:.25rem !important}.gap-xxl-2{gap:.5rem !important}.gap-xxl-3{gap:1rem !important}.gap-xxl-4{gap:1.5rem !important}.gap-xxl-5{gap:3rem !important}.justify-content-xxl-start{justify-content:flex-start !important}.justify-content-xxl-end{justify-content:flex-end !important}.justify-content-xxl-center{justify-content:center !important}.justify-content-xxl-between{justify-content:space-between !important}.justify-content-xxl-around{justify-content:space-around !important}.justify-content-xxl-evenly{justify-content:space-evenly !important}.align-items-xxl-start{align-items:flex-start !important}.align-items-xxl-end{align-items:flex-end !important}.align-items-xxl-center{align-items:center !important}.align-items-xxl-baseline{align-items:baseline !important}.align-items-xxl-stretch{align-items:stretch !important}.align-content-xxl-start{align-content:flex-start !important}.align-content-xxl-end{align-content:flex-end !important}.align-content-xxl-center{align-content:center !important}.align-content-xxl-between{align-content:space-between !important}.align-content-xxl-around{align-content:space-around !important}.align-content-xxl-stretch{align-content:stretch !important}.align-self-xxl-auto{align-self:auto !important}.align-self-xxl-start{align-self:flex-start !important}.align-self-xxl-end{align-self:flex-end !important}.align-self-xxl-center{align-self:center !important}.align-self-xxl-baseline{align-self:baseline !important}.align-self-xxl-stretch{align-self:stretch !important}.order-xxl-first{order:-1 !important}.order-xxl-0{order:0 !important}.order-xxl-1{order:1 !important}.order-xxl-2{order:2 !important}.order-xxl-3{order:3 !important}.order-xxl-4{order:4 !important}.order-xxl-5{order:5 !important}.order-xxl-last{order:6 !important}.m-xxl-0{margin:0 !important}.m-xxl-1{margin:.25rem !important}.m-xxl-2{margin:.5rem !important}.m-xxl-3{margin:1rem !important}.m-xxl-4{margin:1.5rem !important}.m-xxl-5{margin:3rem !important}.m-xxl-auto{margin:auto !important}.mx-xxl-0{margin-right:0 !important;margin-left:0 !important}.mx-xxl-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-xxl-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-xxl-3{margin-right:1rem !important;margin-left:1rem !important}.mx-xxl-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-xxl-5{margin-right:3rem !important;margin-left:3rem !important}.mx-xxl-auto{margin-right:auto !important;margin-left:auto !important}.my-xxl-0{margin-top:0 !important;margin-bottom:0 !important}.my-xxl-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-xxl-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-xxl-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-xxl-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-xxl-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-xxl-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-xxl-0{margin-top:0 !important}.mt-xxl-1{margin-top:.25rem !important}.mt-xxl-2{margin-top:.5rem !important}.mt-xxl-3{margin-top:1rem !important}.mt-xxl-4{margin-top:1.5rem !important}.mt-xxl-5{margin-top:3rem !important}.mt-xxl-auto{margin-top:auto !important}.me-xxl-0{margin-right:0 !important}.me-xxl-1{margin-right:.25rem !important}.me-xxl-2{margin-right:.5rem !important}.me-xxl-3{margin-right:1rem !important}.me-xxl-4{margin-right:1.5rem !important}.me-xxl-5{margin-right:3rem !important}.me-xxl-auto{margin-right:auto !important}.mb-xxl-0{margin-bottom:0 !important}.mb-xxl-1{margin-bottom:.25rem !important}.mb-xxl-2{margin-bottom:.5rem !important}.mb-xxl-3{margin-bottom:1rem !important}.mb-xxl-4{margin-bottom:1.5rem !important}.mb-xxl-5{margin-bottom:3rem !important}.mb-xxl-auto{margin-bottom:auto !important}.ms-xxl-0{margin-left:0 !important}.ms-xxl-1{margin-left:.25rem !important}.ms-xxl-2{margin-left:.5rem !important}.ms-xxl-3{margin-left:1rem !important}.ms-xxl-4{margin-left:1.5rem !important}.ms-xxl-5{margin-left:3rem !important}.ms-xxl-auto{margin-left:auto !important}.p-xxl-0{padding:0 !important}.p-xxl-1{padding:.25rem !important}.p-xxl-2{padding:.5rem !important}.p-xxl-3{padding:1rem !important}.p-xxl-4{padding:1.5rem !important}.p-xxl-5{padding:3rem !important}.px-xxl-0{padding-right:0 !important;padding-left:0 !important}.px-xxl-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-xxl-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-xxl-3{padding-right:1rem !important;padding-left:1rem !important}.px-xxl-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-xxl-5{padding-right:3rem !important;padding-left:3rem !important}.py-xxl-0{padding-top:0 !important;padding-bottom:0 !important}.py-xxl-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-xxl-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-xxl-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-xxl-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-xxl-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-xxl-0{padding-top:0 !important}.pt-xxl-1{padding-top:.25rem !important}.pt-xxl-2{padding-top:.5rem !important}.pt-xxl-3{padding-top:1rem !important}.pt-xxl-4{padding-top:1.5rem !important}.pt-xxl-5{padding-top:3rem !important}.pe-xxl-0{padding-right:0 !important}.pe-xxl-1{padding-right:.25rem !important}.pe-xxl-2{padding-right:.5rem !important}.pe-xxl-3{padding-right:1rem !important}.pe-xxl-4{padding-right:1.5rem !important}.pe-xxl-5{padding-right:3rem !important}.pb-xxl-0{padding-bottom:0 !important}.pb-xxl-1{padding-bottom:.25rem !important}.pb-xxl-2{padding-bottom:.5rem !important}.pb-xxl-3{padding-bottom:1rem !important}.pb-xxl-4{padding-bottom:1.5rem !important}.pb-xxl-5{padding-bottom:3rem !important}.ps-xxl-0{padding-left:0 !important}.ps-xxl-1{padding-left:.25rem !important}.ps-xxl-2{padding-left:.5rem !important}.ps-xxl-3{padding-left:1rem !important}.ps-xxl-4{padding-left:1.5rem !important}.ps-xxl-5{padding-left:3rem !important}.text-xxl-start{text-align:left !important}.text-xxl-end{text-align:right !important}.text-xxl-center{text-align:center !important}}@media (min-width: 1200px){.fs-1{font-size:1.40625rem !important}}@media print{.d-print-inline{display:inline !important}.d-print-inline-block{display:inline-block !important}.d-print-block{display:block !important}.d-print-grid{display:grid !important}.d-print-table{display:table !important}.d-print-table-row{display:table-row !important}.d-print-table-cell{display:table-cell !important}.d-print-flex{display:flex !important}.d-print-inline-flex{display:inline-flex !important}.d-print-none{display:none !important}}body{background-size:cover}.bg-light{background-color:Rgb(var(--t42-bg-light)) !important}.bg-dark{background-color:Rgb(var(--t42-bg-dark)) !important}.bg-base{background-color:Rgb(var(--t42-bg-mid)) !important}.border{border:0.0625rem solid var(--t42-color-opacity-10) !important}.border-primary{border-color:#007be5 !important}.border-secondary,.border-info,.border-light,.border-dark,.border-white{border-color:var(--t42-color-opacity-10) !important}.border-success{border-color:#43a047 !important}.border-danger{border-color:#ff511f !important}.border-warning{border-color:#f9a825 !important}.pl-0{padding-left:0}.pl-1{padding-left:0.25rem}.pl-2{padding-left:0.5rem}.pl-3{padding-left:1rem}.pl-4{padding-left:1.5rem}.pl-5{padding-left:3rem}.pl-auto{padding-left:auto}.pr-0{padding-right:0}.pr-1{padding-right:0.25rem}.pr-2{padding-right:0.5rem}.pr-3{padding-right:1rem}.pr-4{padding-right:1.5rem}.pr-5{padding-right:3rem}.pr-auto{padding-right:auto}.ml-0{margin-left:0}.ml-1{margin-left:0.25rem}.ml-2{margin-left:0.5rem}.ml-3{margin-left:1rem}.ml-4{margin-left:1.5rem}.ml-5{margin-left:3rem}.ml-auto{margin-left:auto}.mr-0{margin-right:0}.mr-1{margin-right:0.25rem}.mr-2{margin-right:0.5rem}.mr-3{margin-right:1rem}.mr-4{margin-right:1.5rem}.mr-5{margin-right:3rem}.mr-auto{margin-right:auto}@keyframes spinner-border{to{transform:rotate(360deg) /* rtl:ignore */}}.spinner-border{display:inline-block;width:2rem;height:2rem;vertical-align:-.125em;border:.25em solid currentColor;border-right-color:transparent;border-radius:50%;animation:.75s linear infinite spinner-border}.spinner-border-sm{width:1rem;height:1rem;border-width:.2em}@keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1;transform:none}}.spinner-grow{display:inline-block;width:2rem;height:2rem;vertical-align:-.125em;background-color:currentColor;border-radius:50%;opacity:0;animation:.75s linear infinite spinner-grow}.spinner-grow-sm{width:1rem;height:1rem}@media (prefers-reduced-motion: reduce){.spinner-border,.spinner-grow{animation-duration:1.5s}}.loader-wrapper{display:flex;flex-direction:column;flex-grow:1;gap:1rem;align-items:center;justify-content:center}.loader-wrapper .loader{width:2rem;height:2rem;border-radius:50%;background:radial-gradient(farthest-side, #999d9e 94%, rgba(0,0,0,0)) center top/4px 4px no-repeat,conic-gradient(rgba(0,0,0,0) 15%, #999d9e);-webkit-mask:radial-gradient(farthest-side, rgba(0,0,0,0) calc(100% - 4px), #000 0)}.loader-wrapper.active .loader{animation:s3 1.5s infinite linear}@keyframes s3{to{transform:rotate(1turn)}}.loader-wrapper .loader-text{margin:0 auto;padding:0 0.833rem;overflow:hidden;color:var(--t42-content-color-muted);text-align:center;text-overflow:ellipsis}@keyframes clipMe{0%,100%{clip:rect(0, 220px, 2px, 0)}25%{clip:rect(0, 2px, 220px, 0)}50%{clip:rect(218px, 220px, 220px, 0)}75%{clip:rect(0, 220px, 220px, 218px)}}@keyframes spin{from{transform:rotate(0deg)}to{transform:rotate(360deg)}}.spinner{display:inline-block;animation-name:spin;animation-duration:3000ms;animation-timing-function:linear;animation-iteration-count:infinite}@font-face{font-weight:400;font-family:"Montserrat";font-style:normal;src:url(data:font/ttf;base64,AAEAAAARAQAABAAQR0RFRrFss1wAAmssAAACfkdQT1N2Wb7+AAJtrAABFy5HU1VCjJZZRgADhNwAAC8mT1MvMlYMpE4AAfmwAAAAYGNtYXBfILVpAAH6EAAACuRjdnQgMKUWggACEzwAAADkZnBnbU0kjnwAAgT0AAANbWdhc3AAAAAQAAJrJAAAAAhnbHlmzhsdpQAAARwAAct0aGVhZA5QtXgAAduUAAAANmhoZWEG0AwiAAH5jAAAACRobXR4v8HBsgAB28wAAB3AbG9jYfsbiDIAAcywAAAO4m1heHAIxQ5XAAHMkAAAACBuYW1lKqFFSQACFCAAAAHucG9zdFa6PIcAAhYQAABVE3ByZXDNS6zAAAISZAAAANUAAgAoAAACIwK8AAMABwApQCYAAAACAwACZQQBAwEBA1UEAQMDAV0AAQMBTQQEBAcEBxIREAUNFysTIREhJREhESgB+/4FAav+pQK8/URGAjD90AAAAv//AAAC3QK8AAcACgArQCgJAQQCAUoFAQQAAAEEAGYAAgJCSwMBAQFDAUwICAgKCAoREREQBgoYKyUhByMBMwEjJwMDAif+jE1nAT1jAT5pcJeXr68CvP1E/wFX/qn/////AAAC3QN3ACIABAAAAAMHEgKaAAD/////AAAC3QN3ACIABAAAAAMHGQKaAAD/////AAAC3QPhACIABAAAACcHMQKaAJYBBwcuApoBEQARsQIBsJawMyuxAwG4ARGwMysA//////88At0DdwAiAAQAAAAjBv8CmgAAAAMHGQKaAAD/////AAAC3QPhACIABAAAACcHMQKaAJYBBwctApoBEQARsQIBsJawMyuxAwG4ARGwMysA/////wAAAt0D7QAiAAQAAAAnBzECmgCWAQcHNAKaAP4AELECAbCWsDMrsQMBsP6wMyv/////AAAC3QPgACIABAAAACcHMQKaAJYBBwcyApoBEQARsQIBsJawMyuxAwG4ARGwMysA/////wAAAt0DdwAiAAQAAAADBxcCmgAA/////wAAAt0DdwAiAAQAAAADBxYCmgAA/////wAAAt0DvgAiAAQAAAAnBy8CmgCWAQcHLgNCAO4AELECAbCWsDMrsQMBsO6wMyv//////zwC3QN3ACIABAAAACMG/wKaAAAAAwcWApoAAP////8AAALdA74AIgAEAAAAJwcvApoAlgEHBy0DQgDuABCxAgGwlrAzK7EDAbDusDMr/////wAAAt0D0wAiAAQAAAAnBy8CmgCWAQcHNAMcAOQAELECAbCWsDMrsQMBsOSwMyv/////AAAC3QPmACIABAAAACcHLwKaAJYBBwcyApoBFwARsQIBsJawMyuxAwG4ARewMysA/////wAAAt0DdwAiAAQAAAADByMCmgAA/////wAAAt0DbQAiAAQAAAADBwoCmgAA//////88At0CvAAiAAQAAAADBv8CmgAA/////wAAAt0DdwAiAAQAAAADBxACmgAA/////wAAAt0DuwAiAAQAAAADByICmgAA/////wAAAt0DfQAiAAQAAAADByQCmgAA/////wAAAt0DVAAiAAQAAAADBx4CmgAA//////8gAvMCvAAiAAQAAAADBwMECAAA/////wAAAt0D1gAiAAQAAAEHBvACmgCqAAixAgKwqrAzK/////8AAALdBB0AIgAEAAABBwbxApoAqgAIsQICsKqwMyv/////AAAC3QN3ACIABAAAAAMHGgKaAAAAAv//AAAD3wK8AA8AEwBEQEEABQAGCQUGZQsBCQABBwkBZQgBBAQDXQADA0JLCgEHBwBdAgEAAEMATBAQAAAQExATEhEADwAPEREREREREQwKGyslFSE1IQcjASEVIRUhFSEVJxEjAwPf/gT+6mdnAaECMf51AV/+oWMU01dXr68CvFfXVeKoAWb+mv////8AAAPfA3cAIgAeAAAAAwcSA0AAAAADAGkAAALDArwADgAXAB8APEA5DgEEAgFKAAIABAUCBGUGAQMDAV0AAQFCSwcBBQUAXQAAAEMATBgYDw8YHxgeHRsPFw8WJyEkCAoXKwAWFRQGIyERITIWFRQGBwEVMzI2NTQmIxI2NTQjIxUzAn1GiYP+sgE6eIMzK/6NzU1TU01uVqvm5gFaWURbYgK8YFU3UBUBAOA5Nzc5/eY4PHXpAAABADD/+AKtAsQAGwAuQCsYFwsKBAIBAUoAAQEAXwAAAEhLAAICA18EAQMDSQNMAAAAGwAaJiQmBQoXKwQmJjU0NjYzMhYXByYjIgYGFRQWFjMyNxcGBiMBOalgYKppUogwQU92Tn5HR35OdVBBMIlSCF2jZmajXTc2P1NGe0xMe0ZUPzY4//8AMP/4Aq0DdwAiACEAAAADBxICxwAA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BwcDUQBzAAixAQGwc7AzK///AGn/LwLDArwAIgBSAAAAAwcEAsEAAP//AGkAAALDA3cAIgBSAAAAAwcXAsEAAP//AGkAAALDA3cAIgBSAAAAAwcWAsEAAP//AGn/PALDArwAIgBSAAAAAwb/AsEAAAABAGkAAADNArwAAwATQBAAAABCSwABAUMBTBEQAgoWKxMzESNpZGQCvP1EAAIAV//4Am0CvAAPABMAM0AwAwEABAIBAgACSgAEBAFdAwEBAUJLAAAAAl8FAQICSQJMAAATEhEQAA8ADhMlBgoWKwQmJzcWFjMyNjURMxEUBiMDMxEjAQN8MCcsaDdeYmSeiORkZAgmIVAeIG5vAY7+d5miAsT+eQD//wBQAAABUgN3ACIAWAAAAAMHEgHHAAD////5AAABPQN3ACIAWAAAAAMHGQHHAAD////oAAABTgN3ACIAWAAAAAMHFgHHAAD///+uAAABGwN3ACIAWAAAAAMHIwHHAAD//wALAAABKwNtACIAWAAAAAMHCgHHAAD//wAPAAABOQP0ACIAWAAAACcHKwHHAJYBBwcuAccBJAARsQECsJawMyuxAwG4ASSwMysA//8AYAAAANYDfQAiAFgAAAADBw4BxwAA//8AaP88AM4CvAAiAFgAAAADBv8BxwAA////5AAAAOYDdwAiAFgAAAADBxABxwAA//8APwAAAQADuwAiAFgAAAADByIBxwAA////+QAAAT0DfQAiAFgAAAADByQBxwAA//8AFgAAASADVAAiAFgAAAADBygBxwAA//8ATv8gAPECvAAiAFgAAAADByoB+AAA////8wAAAUMDdwAiAFgAAAADBxoBxwAAAAH/9//4AZ4CvAAQACxAKQMCAgABAUoAAQECXQACAkJLAAAAA18EAQMDSQNMAAAAEAAPERMkBQoXKxYmJzcWMzI2NREjNSERFAYjhGwhOjpYOz39AWBvbAg1MERTSEYBiVf+JXR1////9//4AaIDdwAiAGgAAAADBxYCGwAAAAEAaQAAAs4CvAALAB9AHAkGAQMAAQFKAgEBAUJLAwEAAEMATBISERIEChgrAQcVIxEzEQEzAQEjAU2AZGQBfHL+1QE+dQE3grUCvP55AYf+xf5///8AaQAAAs4DdwAiAGoAAAADBxcCowAA//8Aaf75As4CvAAiAGoAAAADBwECowAA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KAcKGSsBERQGBwYVFBYzMjY3FwYjIiY1NDcmJjURMxEUMzI2NRECs15XkCIcECEMEygyOEBFf41kxWBmArz+cnaSHjNJGBwJCDEYNy5DMQifjgGO/nbhb3IBigD//wBj//gCswPWACIAxwAAAQcG8AK4AKoACLEBArCqsDMr//8AY//4ArMDdwAiAMcAAAADBxoCuAAA//8AY//4ArMD9AAiAMcAAAAnBzICuACWAQcHLgK4ASQAEbEBAbCWsDMrsQIBuAEksDMrAAAB//8AAALJArwABgAhQB4FAQABAUoDAgIBAUJLAAAAQwBMAAAABgAGEREEChYrAQEjATMTEwLJ/s1j/sxs/P4CvP1EArz9wQI/AAEAIAAABEYCvAAMACdAJAsIAwMAAgFKBQQDAwICQksBAQAAQwBMAAAADAAMEhESEQYKGCsBAyMDAyMDMxMTMxMTBEbqab+/a+pnvcVcwcECvP1EAi/90QK8/ccCOf3EAjz//wAgAAAERgN3ACIA4AAAAAMHEgNgAAD//wAgAAAERgN3ACIA4AAAAAMHFgNgAAD//wAgAAAERgNtACIA4AAAAAMHCgNgAAD//wAgAAAERgN3ACIA4AAAAAMHEANgAAAAAQANAAAClAK8AAsAJkAjCgcEAQQAAQFKAgEBAUJLBAMCAABDAEwAAAALAAsSEhIFChcrIQMDIwEDMxMTMwMBAiHSz3MBB/dyxMJt9wEJASH+3wFnAVX+8wEN/q7+lgAAAf/8AAACiwK8AAgAHUAaBgMAAwABAUoCAQEBQksAAABDAEwSEhEDChcrJRUjNQEzExMzAXVj/upr4OFj8vL0Acj+jwFx/////AAAAosDdwAiAOYAAAADBxICcAAA/////AAAAosDdwAiAOYAAAADBxYCcAAA/////AAAAosDbQAiAOYAAAADBwoCcAAA/////AAAAosDfQAiAOYAAAADBw4CcAAA/////P88AosCvAAiAOYAAAADBv8CcAAA/////AAAAosDdwAiAOYAAAADBxACcAAA/////AAAAosDuwAiAOYAAAADByICcAAA/////AAAAosDVAAiAOYAAAADBx4CcAAA/////AAAAosDdwAiAOYAAAADBxoCcAAAAAEAKwAAAnQCvAAJAC9ALAgBAQIDAQADAkoAAQECXQACAkJLBAEDAwBdAAAAQwBM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AfIAxAAIsQEBsMSwMyv//wBb/y8CUgLmACIB2AAAAAMHBAKDAAD////YAAACUgO1ACIB2AAAAQcG7QG3ANQACLEBAbDUsDMr////2AAAAlIDoQAiAdgAAAEHBxYBtwAqAAixAQGwKrAzK///AFv/PAJSAuYAIgHYAAAAAwb/AoMAAP//AEoAAADMAvUAIgHfAAAAAwcpAbcAAAABAFsAAAC7AhIAAwATQBAAAABFSwABAUMBTBEQAgoWKxMzESNbYGACEv3u//8AQAAAAUIC4QAiAd8AAAADBucBtwAA//8AAgAAARQC4QAiAd8AAAADBzcBtwAA////8QAAASUC4QAiAd8AAAADBzYBtwAA////ngAAAQsC4QAiAd8AAAADBvsBtwAA//8AEgAAAQQC1gAiAd8AAAADBzUBtwAA/////wAAASkDXgAiAd8AAAAjBysBtwAAAQcHLgG3AI4ACLEDAbCOsDMr//8AUAAAAMYC5wAiAd8AAAADBuMBtwAA//8ASv88AMwC9QAiAd8AAAAjBykBtwAAAAMG/wG3AAD////UAAAA1gLhACIB3wAAAAMG5QG3AAD//wAvAAAA8AMlACIB3wAAAAMG+gG3AAD//wACAAABFALnACIB3wAAAAMHOgG3AAD//wBK/zgB6AL1ACIB3wAAACMHKQG3AAAAIwHwARcAAAADBykC0wAA//8ABgAAARACvgAiAd8AAAADBzkBtwAA//8APP8gAN8C9QAiAd8AAAAjBykBtwAAAAMHKgHmAAD////8AAABGgLhACIB3wAAAAMHOAG3AAD///+k/zgA0QL1ACIB8AAAAAMHKQG8AAAAAf+k/zgAwAISAA4AKUAmAwEAAQIBAgACSgABAUVLAAAAAmADAQICTQJMAAAADgANEyQEChYrBiYnNxYzMjY1ETMRFAYjDDwUHx4wJilgWFHIEBBKGS8uAiz91lJe////pP84ASoC4QAiAfAAAAADBzYBvAAAAAEAWwAAAmYC5gALACNAIAkGAQMAAgFKAAEBREsAAgJFSwMBAABDAEwSEhESBAoYKyUHFSMRMxEBMwcTIwEpbmBgASF03/V292aRAub+JAEI2/7J////2AAAAmYDtQAiAfIAAAEHBu0BtwDUAAixAQGw1LAzK///AFv++QJmAuYAIgHyAAAAAwcBAmUAAAABAFsAAAJm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yNQBDP70/////wAAAmgDBwAiAt8AAAEHBucCXwAmAAixAgGwJrAzK/////8AAAJoAwcAIgLfAAABBwbvAl8AJgAIsQIBsCawMyv/////AAACaANxACIC3wAAACcHMQJfACYBBwcuAl8AoQAQsQIBsCawMyuxAwGwobAzK///////PAJoAwcAIgLfAAAAIwb/Al8AAAEHBu8CXwAmAAixAwGwJrAzK/////8AAAJoA3EAIgLfAAAAJwcxAl8AJgEHBy0CXwChABCxAgGwJrAzK7EDAbChsDMr/////wAAAmgDfQAiAt8AAAAnBzECXwAmAQcHNAJfAI4AELECAbAmsDMrsQMBsI6wMyv/////AAACaANwACIC3wAAACcHMQJfACYBBwcyAl8AoQAQsQIBsCawMyuxAwGwobAzK/////8AAAJoAwcAIgLfAAABBwbtAl8AJgAIsQIBsCawMyv/////AAACaAMHACIC3wAAAQcG7AJfACYACLECAbAmsDMr/////wAAAnkDTgAiAt8AAAAnBy8CXwAmAQcHLgMHAH4AELECAbAmsDMrsQMBsH6wMyv//////zwCaAMHACIC3wAAACMG/wJfAAABBwbsAl8AJgAIsQMBsCawMyv/////AAACaANOACIC3wAAACcHLwJfACYBBwctAwcAfgAQsQIBsCawMyuxAwGwfrAzK/////8AAAJoA2MAIgLfAAAAJwcvAl8AJgEHBzQC4QB0ABCxAgGwJrAzK7EDAbB0sDMr/////wAAAmgDdgAiAt8AAAAnBy8CXwAmAQcHMgJfAKcAELECAbAmsDMrsQMBsKewMyv/////AAACaAMHACIC3wAAAQcG+wJfACYACLECArAmsDMr/////wAAAmgC/QAiAt8AAAEHBt8CXwAmAAixAgKwJrAzK///////PAJoAjgAIgLfAAAAAwb/Al8AAP////8AAAJoAwcAIgLfAAABBwblAl8AJgAIsQIBsCawMyv/////AAACaANLACIC3wAAAQcG+gJfACYACLECAbAmsDMr/////wAAAmgDDQAiAt8AAAEHBvwCXwAmAAixAgGwJrAzK/////8AAAJoAuQAIgLfAAABBwb2Al8AJgAIsQIBsCawMyv//////yACfgI4ACIC3wAAAAMHAwOTAAD/////AAACaANSACIC3wAAAQcG8AJf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VAD////w/zgCNgISAAICbwYA////8P84AjYC4QAiAm8GAAADB1gB8AAAAAMAK/8+AvoC5gARABgAHgA3QDQeAQAGAUoABAMEgwgBBwcDXwUBAwMiSwAGBgBfAgEAACFLAAEBJAFMFhEUEREUERERCQcdKyQGBxUjNSYmNTQ2NzUzFRYWFQQWFxEGBhUENTQmJxEC+qSVXpWjopZelaT9kG1sbWwCEW5sj44Iu7sIjXx7igjPzwiLelVgBwF0B15TrKxUXQf+iwD//wAJAAACFQISAAICbvsAAAEAKgAAAgQCEgARAC9ALBABAwIDAQEDAkoAAwABAAMBZwUEAgICIksAAAAhAEwAAAARABEjEyIRBgcYKwERIzUGIyImNTUzFRQWMzI3NQIEYFZVY2xgRT5GUQIS/e7WKFxcrKY3OCPyAAABAF3/gQKTAhIACwApQCYAAAMAUgQBAgIiSwYFAgMDAV4AAQEhAUwAAAALAAsREREREQcHGSslFSM1IREzESERMxECk1v+JWABImBU038CEv5CAb7+QgAAAQBdAAADUAISAAsAJUAiBgUDAwEBIksEAQICAF4AAAAhAEwAAAALAAsREREREQcHGSsBESERMxEzETMRMxEDUP0NYOpg6QIS/e4CEv5CAb7+QgG+AP//AF3/jwOfAhIAIgUmAAAAAwdaArIAAAABAF3/gQIoAhIACwBGS7AKUFhAGAABAAABbwUBAwMiSwAEBABeAgEAACEATBtAFwABAAGEBQEDAyJLAAQEAF4CAQAAIQBMWUAJEREREREQBgcaKyEjFSM1IxEzESERMwIot1u5YAELYH9/AhL+QgG+AAACAF3//gIhAhIACgATADBALQUBAgADBAIDZQABASJLBgEEBABeAAAAIQBMCwsAAAsTCxIRDwAKAAkRJAcHFisAFhUUBicnETMVFxI2NTQmJycVFwG3anNr5mCVKkNBQ35+AV1aUlZdAQECErMB/uk2NTQwAQLQAQACAAQAAAJhAhIADAAVADZAMwYBAwAEBQMEZQABAQJdAAICIksHAQUFAF0AAAAhAEwNDQAADRUNFBMRAAwACxERJAgHFysAFhUUBiMjESM1IRUzEjY1NCYjIxUzAfhpc2nfogECkCpAPz98fAFfW1JVXQG+VLP+6jY1MzHPAAADAF3//gLJAhIACgAOABcANkAz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hAMBAgIBXQABASEBTAAAAAUABRERBAcWKzcVIzUjNfpccVfwmVcAAQA6/2cA2wBXAAUAH0AcAAABAIQDAQICAV0AAQEhAUwAAAAFAAUREQQHFis3FSM1IzXbXURX8JlXAAEAQP+PANoAUgAFADxLsApQWEASAAABAQBvAwECAgFdAAEBIQFMG0ARAAABAIQDAQICAV0AAQEhAUxZQAsAAAAFAAUREQQHFis3FSM1IzXaV0NSw3FSAP///jICWf92A0sAIgcxAAABBgcuAHsACLEBAbB7sDMr///+MgJZ/3YDSwAiBzEAAAEGBy0AewAIsQEBsHuwMyv///4yAln/dgNXACIHMQAAAQYHNABoAAixAQGwaLAzK////i8CWf95A0oAIgcxAAABBgcyAHsACLEBAbB7sDMr///+IQJfABoDKAAiBy8AAAEHBy4AqABYAAixAQGwWLAzK////iECX//BAygAIgcvAAABBwctAKgAWAAIsQEBsFiwMyv///4hAl//pAM9ACIHLwAAAQcHNACCAE4ACLEBAbBOsDMr///+IQJf/4cDUAAiBy8AAAEHBzIAAACBAAixAQGwgbAzK////jIC7/92A+EAJwcxAAAAlgEHBy4AAAERABGxAAGwlrAzK7EBAbgBEbAzKwD///4yAu//dgPhACcHMQAAAJYBBwctAAABEQARsQABsJawMyuxAQG4ARGwMysA///+MgLv/3YD7QAnBzEAAACWAQcHNAAAAP4AELEAAbCWsDMrsQEBsP6wMyv///4vAu//eQPgACcHMQAAAJYBBwcyAAABEQARsQABsJawMyuxAQG4ARGwMysA///+IQL1ABoDvgAnBy8AAACWAQcHLgCoAO4AELEAAbCWsDMrsQEBsO6wMyv///4hAvX/wQO+ACcHLwAAAJYBBwctAKgA7gAQsQABsJawMyuxAQGw7rAzK////iEC9f+kA9MAJwcvAAAAlgEHBzQAggDkABCxAAGwlrAzK7EBAbDksDMr///+IQL1/4cD5gAnBy8AAACWAQcHMgAAARcAEbEAAbCWsDMrsQEBuAEXsDMrAAABAF//ZwC8ABcAAwAYQBUAAQAAAVUAAQEAXQAAAQBNERACBxYrFyM1M7xdXZmwAAABAF7/jwC5ABUAAwAYQBUAAQAAAVUAAQEAXQAAAQBNERACBxYrFyM1M7lb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UXdRg1GUUaVRtlHHUdhR6VICUhtSgFKLUp9SsFLJUuJS+1NDU3xTuVQOVFFUYlRzVH9UkFScVK1UuVUPVSBVOVVBVVJVa1V3VYhVlFWlVbFVxlZEVmNWdFaFVpFWnVauVrpWxlb0VwVXFlcnVzhXSVdaV2ZXd1eIV5lXslfHV+BX+VgSWCNYNFhFWF5YrFi9WM5Y51kLWTxZTVleWW9ZgFmtWdBZ4VnyWgNaFFogWjFaQlpTWmRaklqjWrRaxVrRWw1bHlsvW0hbXVt2W49bqFu5W8pb41v4XBFcKlxDXFRcZVxxXIJck1ykXLVcwVzSXONc9F1ZXWpdf13WXedd+F4JXh5eL15IXl1edl6PXqheuV7KXtte5174XwlfGl8rX0RfXV/pX/pgSGCBYOJg82EEYRVhJmE3YUhhXGGGYY5hn2HtYf5iD2IgYjFiSmJWYmdieGKJYsVi1mLiYvNjKGM5Y0VjpmOyY/dkCGQZZCVkNmRCZKJkrmS6ZMtlFmVAZVFlYmVuZXpli2WXZaNl7WX+Zg9mIGYxZkJmU2ZfZnBmgWaSZqtmwGbZZvJnC2ccZy1nPmdXZ2NndGeFZ55n5mf3aAhoGWgqaHVohmiXaKhouWjKaNto7Gj9aQ5pSWlaaWtpfGmIad9qH2onamJqr2rNatlq+ms7a0NrT2tba5tr+WwfbCtsN2yNbLtsx20hbVVtXW1lbYltkW2Zbblt8m3+blBugG62buJvDm8ab0Fvem+4b8Rv0HAxcDlwSXCYcK5wunDCcQBxc3G1ciRybXK4csxzGXNJc5hzpHOwc7xz+nQ3dGt0d3SDdNZ04nWZdaV1sXW5dc112XYNdhl2XXaTdp93B3cTdxt3J3dud6x34XggeF54anh2eH54injheO14+XkFeVF5XXlpeXV5iXmhea15uXnFedF53Xnoefh6RnqQesh7I3txe3l7qnvzfEF8f3yLfMJ85n05fWN9b317fYd9j33Ufdx96H30ffx+CH6nfrN+6380fzx/RH9Qf5p/5IA1gKOBM4GugbaCDoIagiaCMoI6gkaCUoJegmqCdoKCgo6CloLvgveDXYOng8SD1oQHhEeET4RbhGeEo4T+hSSFMIU8hZKFvYXJhhiGS4ZxhnmGnYalhq2GzYbVhuGHMIc4h22HmYfEh9CICYhFiISIyYjViTKJOolKiZaJoomuibqKAYqKisiLJouKi9uL44wxjF+MrYy5jRaNIo1djZ6Nz43bjeeN845FjtOO347rjw6PIo8uj2KPbo+vj7eP95BZkGWQbZB5kL6ROJF6ka2R6pImkjKSPpJGklKSpJKwkrySyJMRkx2TKZM1k4eTk5Ofk6uTt5PDk8+T2pPmlDWUepSylQqVXJVklZWV35ZXlpmWpZcDl1qXYpell/6YBpgSmB6YT5hymHqYgpiKmL+Yy5ktmTmZgZnPmkaabpp6moaamJrymv6bBpsSmyabLps2mz6bSptWm16bapvom/ScRJxMnFScYJyonPadXp3GnkCemJ6knrCeuJ7EnxOfH58rnzefQ59Pn1ufZ5+/n+agMqB0oLCgwaDJoQqhKaFpobKh5aItoo+izaM4o5mj36P9pD2kiKS+pQelD6VSpVqlaKV3pYallaWkpbOlwqXRpeCl76X+pkCmaKaopvCnI6drp82oC6h2qNipHqlFqYWpzqoDqkyqVKqXqp+rA6sRqx+rLas7q0mrV6tlq3OrgauPq8mr76wtrHOso6zlrTytd63Xri+uPq5krqKu6K73rzqvSa+Fr5Svo6+yr8Gv0K/fr+6v/bAMsBuwKrA5sFGwYbBxsIGwkbChsLGwwbDRsOGxFrExsVaxe7GNsbqxyrH5siiylLK2swuzZLNws4ezmbOws8yz57QMtBm0PrRVtHq0vrUFtSW1SLVrtZG1nrWrtbi1xbXStd+1+LYRtiq2MrZLtlO2W7ZotnW2graOtpq2ubbbtue287b/tya3Ubd+t5O3qLe1t8K38bgiuC64OrhZuHu4nbjxuUi5VLlguWy5eLmfucq597oNuiq6Oro6ujq6Oro6ujq6OrqWuuG7c7vfvFG8371Jvbq98r5UvsO+/79Xv6C/28BIwFjA5cErwXzBwsHswizCuML4wwDDRcNNw3XDjsOrw/XEJ8SBxJfErsTYxQTFOsW+xjLGUMayxybHacdxx3nHnMfVyATIDMhvyR7J/sodyjXKW8p0ypPKq8rUyuzLHss8y1vLfsuly8vL3sv6zBTMKsxUzGbMdsyOzJ7MxMzczQLNGs3KzjjOY87iz2TP6tAx0HnQj9Cx0QbRK9Fi0cvSU9J60pHSsdK+03fT5dQk1DXURtRX1IHUktSs1L3U1tTn1PjVHtU11VrVf9WP1cHWA9ZI1rzWzdbe1u/XDdce1y/XQNd115vXydf22CLYS9iJ2LnY+dkx2WHZftmc2brZzNnm2iHaONpP2mbajNqj2rna0Nrl2vzbE9s121bbd9uO27zcLNxD3FrccdyL3KLcudzQ3QHdI91N3Wfded2P3andzN4L3lPehN6k3sTe5t8I3zLfld+53+rgMuBU4Hzg8uEJ4S/hU+Ft4Yrhl+Gj4cDh2eH24ibiVOJu4oripuKv4rjiweLK4tPi3OLl4u7i9+MA4wnjEuMb4zTjTeNk45LjwOPs5AnkJuRS5GLkcuSC5JLko+S05MXk1uTt5QTlGuUx5UflXeVz5YrlouW6AAAAAQAAAAczM3QVnhxfDzz1AAcD6AAAAADWC/5GAAAAANYeQAX8uP75Bk0EHQAAAAcAAgAAAAAAAAJLACgAAAAAAQ0AAAENAAAC3P//Atz//wLc//8C3P//Atz//wLc//8C3P//Atz//wLc//8C3P//Atz//wLc//8C3P//Atz//wLc//8C3P//Atz//wLc//8C3P//Atz//wLc//8C3P//Atz//wLc//8C3P//Atz//wQX//8EF///AvUAaQLTADAC0wAwAtMAMALTADAC0wAwAtMAMALTADADOgBpBa4AaQNCAAsDOgBpA0IACwM6AGkDOgBpBUMAaQKeAGkCngBpAp4AaQKeAGkCngBpAp4AaQKeAGkCngBpAp4AaQKeAGkCngBpAp4AaQKeAGkCngBpAp4AaQKeAGkCngBpAp4AaQKeAGkCngBpAp4AaQKeAGkCngBpAm8AHwJvAB8CewBpAwQAMAMEADADBAAwAwQAMAMEADADBAAwAwQAMAMnADADLABpAzwACQMsAGkDLABpAywAaQMsAGkBNgBpAtAAVwE2AFABNv/5ATb/6AE2/64BNgALATYADwE2AGABNgBoATb/5AE2AD8BNv/5ATYAFgE2AE4BNv/zAgH/9wIB//cCzwBpAs8AaQLPAGkCUgBpBFMAaQJSAFACUgBpAlIAaQJSAGkCUgBpA24AaQJSAGkCWgAJA7sAaQO7AGkDLABpBS0AaQMsAGkDLABpAywAaQMsAGkDLABpAywAaQRIAGkDLABpAywAaQNIADADSAAwA0gAMANIADADSAAwA0gAMANIADADSAAwA0gAMANIADADSAAwA0gAMANIADADSAAwA0gAMANIADADSAAwA0gAMANIADADSAAwA0gAMANIADADSAAwA0gAMANIADADSAAwA0gAMANIADADSAAwA0gAMANIADADSAAwA0gAMANIADAEZgAwAtIAaQLSAGkDSAAwAtcAaQLXAGkC1wBpAtcAaQLXAGkC1wBpAtcAaQLXAGkCbQApAm0AKQJtACkBAgBQAm0AKQJtACkCbQApAm0AKQJtACkCbQApAm0AKQJtACkC+wBjAzEAMAJLAAQCSwAEAksABAJLAAQCSwAEAksABAJLAAQDFwBjAxcAYwMXAGMDFwBjAxcAYwMXAGMDFwBjAxcAYwMXAGMDFwBjAx8AYwMfAGMDHwBjAx8AYwMfAGMDHwBjAxcAYwMXAGMDFwBjAxcAYwMXAGMDFwBjAxcAYwMXAGMCyP//BGYAIARmACAEZgAgBGYAIARmACACoQANAof//AKH//wCh//8Aof//AKH//wCh//8Aof//AKH//wCh//8Aof//AKRACsCkQArApEAKwKRACsCkQArAtAAVwMgAGMDIABjAyAAYwMgAGMDIABjAyAAYwMgAGMDIABjAyAAYwMgAGMDIABjAyAAYwMgAGMDIABjAyAAYwMgAGMDIABjAyAAYwMgAGMDIABjAyAAYwMgAGMDIABjAyAAYwMgAGMDIABjBDIAWgQyAFoFrgBpBU0AaQKEADMChAAzAoQAMwKEADMChAAzAoQAMwKEADMChAAzAoQAMwKEADMChAAzAoQAMwKEADMChAAzAoQAMwKEADMChAAzAoQAMwKEADMChAAzAoQAMwKEADMChAAzAl4AYwMEADADBAAwAwQAMAMEADADBAAwAwQAMAMEADADLAAwAcgAKwLQAFcByAArAtAAVwHIACsByAArAcj/+AHIACsByAArAcgAKwHIACsByAArAcgAKwHIACsByAArAcgAKwHIACsB///3Af//9wRvAGkEywBpBMsAaQMeAGkFHQBpAx4AaQMeAGkDHgBpAx4AaQMeAGkDHgBpBDoAaQMeAGkDHgBpA0gAMAMxAEUCVv/8Alb//AJW//wCVv/8Alb//AJW//wCVv/8AxoAYwMaAGMDGgBjAxoAYwMaAGMDGgBjAxoAYwMaAGMDGgBjAxoAYwMaAGMDGgBjAxoAYwMaAGMDGgBjAxoAYwMaAGMDGgBjAxoAYwMaAGMDGgBjAxoAYwMaAGMDGgBjBKYAYwSmAGMEpgBjBKYAYwSmAGMDEwBeAxMAXgMTAF4DEwBeAxMAXgMTAF4DEwBeAxMAXgMTAF4DEwBeApsAMAKbADACmwAwApsAMAKbADACVgAyAlYAMgJWADICVgAyAlYAMgJWADICVgAyAlYAMgJWADICVgAyAlYAMgJWADICVgAyAlYAMgJWADICVgAyAlYAMgJWADICVgAyAlYAMgJWADICVgAyAlYAMgJWADICVgAyAlYAMgPdADID3QAyAqoAWwI7ACoCOwAqAjsAKgI7ACoCOwAqAjsAKgI7ACoCqgAqAoAAKgKqACoCqgAqAqoAKgKqACoEuwAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAg//7AIP/+wBYQAPArIAKgKyACoCsgAqArIAKgKyACoCsgAqArIAKgK6ACoCqQBbAqkAAAKpAFsCqf/YAqn/2AKpAFsBFwBKARcAWwEXAEABFwACARf/8QEX/54BFwASARf//wEXAFABFwBKARf/1AEXAC8BFwACAjMASgEXAAYBFwA8ARf//AEc/6QBHP+kARz/pAJoAFsCaP/YAmgAWwJeAFsBFwBbARcAQAEXAFsBFwBYAVoAWwEXAFgCMwBbARf/6AEn//kEIQBbBCEAWwKpAFsCqQBbAwIANQKpAFsCqQBbAqkAWwKpAFsCqQBbA8UAWwKpAFsCqQBbAnsAKgJ7ACoCewAqAnsAKgJ7ACoCewAqAnsAKgJ7ACoCewAqAnsAKgJ7ACoCewAqAnsAKgJ7ACoCewAqAnsAKgJ7ACoCewAqAnsAKgJ7ACoCewAqAn8AKgJ7ACoCewAqAnsAKgJ7ACoCewAqAnsAKgJ7ACoCewAqAnsAKgJ7ACoCewAqAnsAKgQrACoCqgBbAqoAWwKqACoBmgBbAZoAWwGaADcBmgBYAZr//QGaAFgBmgBIAZr/6AH1ABgB9QAYAfUAGAD/AFAB9QAYAfUAGAH1ABgB9QAYAfUAGAH1ABgB9QAYAfUAGAKkAFsBMgAZAZ4ADwGoABQBngAPAZ4ADwGeAA8BngAJAZ4ADwGeAA8CpQBWAqUAVgKlAFYCpQBWAqUAVgKlAFYCpQBWAqUAVgKlAFYCpQBWAq0AVgKtAFYCrQBWAq0AVgKtAFYCrQBWAqUAVgKlAFYCpQBWAqUAVgKlAFYCpQBWAqUAVgKlAFYCL//+A4MABgODAAYDgwAGA4MABgODAAYCKAAOAi//6gIv/+oCL//qAi//6gIv/+oCL//qAi//6gIv/+oCL//qAi//6gIJACgCCQAoAgkAKAIJACgCCQAoAjIASAKqACoCqgAqAqoAKgKqACoCqgAqAqoAKgKqACoCqgAqAqoAKgKqACoCqgAqAqoAKgKqACoCqgAqAqoAKgKqACoCqgAqAqoAKgKqACoCqgAqAqoAKgKqACoCqgAqAqoAKgKqACoCqgAqA90AMgPdADIEvQAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAAqAmQAKgJkACoCZAArAVMAWwFBAFsBQQBAAUEAWwFBAFsBbQBbAUEAWwI1AFsBQQApAUH/8QQ6ACoBiwBWAZUADAGLAFYBiwBWAYsAVgGL//YBiwBWAYsASAPZAFYD2QBWA9kAVgPZAFYD2QBWAqUAVAKlAFQCpQBUAqUAVAKlAFQCpQBUAqUAVAKlAFQCpQBUAhMALQITAC0CEwAtAhMALQITAC0EsQAEAsgADwJ4AA8CugBbAosADwJn//8CZ///Amf//wJn//8CZ///Amf//wJn//8CZ///Amf//wJn//8CZ///Amf//wJn//8CZ///Amf//wJn//8CZ///Amf//wJn//8CZ///Amf//wJn//8CZ///Amf//wJn//8CZ///A2z//wNs//8ChABhAmEALAJhACwCYQAsAmEALAJhACwCYQAsAmEALAK+AGEC0gAgAr4AYQLSACACvgBhAr4AYQTOAGECOgBhAjoAYQI6AGECOgBhAjoAYQI6AGECOgBhAjoAYQI6AGECOgBhAjoAYQI6AEMCOgBhAjoAYQI6AGECOgBhAjoAYQI6AGECOgBhAjoAYQI6AGECOgBhAjoAYQKcACwCMAAlAjAAJQIgAGECjgAsAo4ALAKOACwCjgAsAo4ALAKOACwCjgAsAq8ALAK7AGEC4wAiArsAYQK7AGECuwBhArsAYQEiAGEBIgBhASIARgJQAEEBIgAIASL/9wEi/6QBIgAYASIABQEiAFYBIgBeASL/2gEiADUBIgAIAm8ATAEiAAwBIgBDASIAAgHB//wBwf/8AmwAYQJsAGECbABhAmwAYQH7AGEB+wBHAfsAYQH7AGEB+wBhAfsAYQO8AGEB+wBhAfv/+AMyAGEDMgBhArsAYQK7AGECuwBhArsAYQK7AGECuwBhArsAYQR8AGECuwBhArsAYQLCACwCwgAsAsIALALCACwCwgAsAsIALALCACwCwgAsAsIALALCACwCwgAsAsIALALCACwCwgAsAsIALALCACwCwgAsAsIALALCACwCwgAsAsIALALCACwCwgAsAsIALALCACwCwgAsAsIALALCACwCwgAsAsIALALCACwCwgAsAsIALALCACwDqwAsAm8AYQJvAGECwgAsAnYAYQJ2AGECdgBhAnYAYQJ2AFQCdgBhAnYAYQJ2AGECEwAlAhMAJQITACUA/wBQAhMAJQITACUCEwAlAhMAJQITACUCEwAlAhMAJQITACUCigBbAe0ABAHtAAQB7QAEAe0ABAHtAAQB7QAEAe0ABAHtAAQCqABbAqgAWwKoAFsCqABbAqgAWwKoAFsCqABbAqgAWwKoAFsCqABbArAAWwKwAFsCsABbArAAWwKwAFsCsABbAqgAWwKoAFsCqABbAqgAWwKoAFsCqABbAqgAWwKoAFsCaQAIA70AIgO9ACIDvQAiA70AIgO9ACICPAAMAjkAAgI5AAICOQACAjkAAgI5AAICOQACAjkAAgI5AAICOQACAjkAAgIrACkCKwApAisAKQIrACkCKwApAq8AWwKvAFsCrwBbAq8AWwKvAFsCrwBbAq8AWwKvAFsCrwBbAq8AWwKvAFsCrwBbAq8AWwKvAFsCrwBbAq8AWwKvAFsCrwBbAq8AWwKvAFsCrwBbAq8AWwKvAFsCrwBbAq8AWwKvAFsDmQBVA5kAVQToAGECJwAqAicAKgInACoCJwAqAicAKgInACoCJwAqAicAKgInACoCJwAqAicAKgInACoCJwAqAicAKgInACoCJwAqAicAKgInACoCJwAqAicAKgInACoCJwAqAicAKgKcADkCCABbAo4ALAKOACwCjgAsAo4ALAKOACwCjgAsAo4ALAK0ACwBqgA5AaoAOQGqADkCbwBBAaoAOQGqADkBqv/pAaoAOQGqADkBqgA5AaoAHwGqADkBqgA5Am8ATAGqADkBqgA5AaoAOQHB//wBwf/8A7wAYQQAAGEEAABhAq4AYQKuAGECrgBhAq4AYQKuAGECrgBhAq4AYQRvAGECrgBhAq4AYQLCACwB9//8Aff//AH3//wB9//8Aff//AH3//wB9//8Aff//AKuAFsCrgBbAq4AWwKuAFsCrgBbAq4AWwKuAFsCrgBbAq4AWwKuAFsCtgBbArYAWwK2AFsCtgBbArYAWwK2AFsCrgBbAq4AWwKuAFsCrgBbAq4AWwKuAFsCrgBbAq4AWwP/AFsD/wBbA/8AWwP/AFsD/wBbAqMAVgKjAFYCowBWAqMAVgKjAFYCowBWAqMAVgKjAFYCowBWAqMAVgIrACkCKwApAisAKQIrACkCKwApAZQAJQGiACAC9gAMAtsAbQLrAG0CQgBtAkIAbQJFAG0DJAANApkAbQKZAG0CmQBtBAUAEwKCACADNwBtAzcAbQM3AG0DUwBtAscAbQLHAG0DFgANA8MAbQM0AG0DUAAzAzUAbQLKAG0CzgA0AlsADQKzABACswAQA54ALQKcABEC4AA2Az0AbQRHAG0EYABtAycAbQLJAG0DPAANA+EAbQSjAA0EnABtAnwAMQLEADUCwwAdAT0AbQE2AAsCHAASA0oADQRLAG0C2wA6A0EADgMrABMDhAASA1AAMwL5AA4CagAeAr8AbQQsABMCggAgAvMAbQLkAG0C3QAjAzsADQNPAG0EPwBtBKwAbQNQAG0DzgA5As4ANAJbAA0CmwAGAof//ALBABEDzgAOAvsANgLgADUC4ABtAyUAbQPdACAD3QAgAT4AbQQFABMCygBtAy8AbQNQAG0C3AAzA+gAbQL2AAwC9gAMBBYABwKZAG0DNwApAzcAKQQFABMCggAgAm8AHwM3AG0DNwBtA1AAMwNQADMDUAAzAsMAHQKzABACswAQArMAEALgADYCQgBtA+EAbQJrAB0CoAAOAqwAGgKCADkDFwAMA1YAMwQ9ABUC4wAfAt0AbQMw/7QDMQANAxkADgLlAA0DnQAxAk8AbQKCACACzgA0As4ANAMgAGMDRAAeAoQAMwKEADMChAAzAxoAYwMaAGMDGgBjAxoAYwMWACACzQBcAncADQMTAF4DEwBeA58AMgLMAF8DaAAOA+EAXwSfAAwEjABtAf//9wM7ABMCdwANAyAAYwMgAGMEMgBaAoQAMwMaAGMDGgBjAxMAXgMTAF4DEwBeA+EAXwNIADAC7wAaAk0AMAKWAD4CZgBdAegAXQHoAF0B0gBdApgACAJ0ACwCdAAsAnQALANRAA0CIAAcArYAXQK2AF0CtgBdAswAXQJWAF0CVgBdAoEABQMeAF0CqQBdAoEALAKlAF0CsABdAjsALAHtAAQCO//wAjv/8AMlACsCHQAJAmEAKgKyAF0DrQBdA60AXQKGAF0CPwBdAn8ABAMnAF0DpgAFA7gAXQIYACsCQQAsAj8AGAEbAEwBFwASARz/ogKi/9wDbABdAmQAMAKj//YCZQAAAsAADwKKACwCVAAFAgQAKwJZAF0DcgANAiAAHAJWAF0CZgBbAlUAAAKeAAQCvgBdA3YAXQKlAF0D0ABdAyYALwI7ACwB7QAEAj4ABgI+AAYCHQAJAwMABQJ6ACoCYQApAqIAXQK8AF0DAwAVAwMAFQEbAF0DUQANAlYAXQKXAAUCrwBdAr8AXQJeACcDPQBdAk0AMAJNADAD4wAwAnQALAJzADgCcwA4A1EADQIgABwCD//sArYAXQK2AF0CgQAsAooALAKKACwCPwAYAjv/8AI7//ACO//wAmEAKgHoAF0DJwBdAewADQIdAAsCOQAWAiAANQKBAAUCsAAuA6oACQJeABYCuwBeAqn/pQKWAAUCfgBMAiEALgKzACkDUQANAe7/9wKeAE0CngBNAp4ATQJVAF4CPAAFAqkAXQKiAF0EGwBdAmMALAK3AE0EGwBOBDQATgJAAFACnAAFA1cAXgH0AF0CIAAcAjsALAHoAF0CbgAnARcABgKzACcCpQBWBBsATgKqACoCswApAmQAKgJkACoCZAAqAp4ATQKeAE0CngBNAp4ATQKWAEYEGwBdAqUAVAKlAFQCSQBQAqUABQMoAFADrQAIA7IAXQJ6//wCqgAqAqoAKgPdADICZAAqAmQAKwJkACsCngBNAp4ATQKlAFQCpQBUAqUAVAMoAFACawARAtz//wOCAAkCqgBbAtT/+ALc//8CzwBpApsAMAFyAAgCPgAOAjwABQKdACYCPgARAmkAMAJWAB4ChAAsAmkAHAKsADIBcgAIAj4ABgI8AAYCnQAmAj4AEQJpADACVgAeAoQALAJpABwBrgAcAa4AUQGuABwBrgAbAa4AFgGuABsBrgAlAa4AJAGuABwBrgAgArwAPQK8AJACvAA8ArwAPgK8ADUCvABBArwASgK8AEkCvAA7ArwAQQK8ADwCvACQArwARwK8AD4CvAA1ArwAQQK8AEoCvABJArwAOwK8AEEBrgAcAa4AUQGuABwBrgAbAa4AFgGuABsBrgAlAa4AJAGuABwBrgAgAa4AHAGuAFEBrgAcAa4AGwGuABYBrgAbAa4AJQGuACQBrgAcAa4AIAGuABwBrgBRAa4AHAGuABsBrgAWAa4AGwGuACUBrgAkAa4AHAGuACABrgAcAa4AUQGuABwBrgAbAa4AFgGuABsBrgAlAa4AJAGuABwBrgAgAK7/QgQKAFEECgBRBAoAHAQKAFEECgAbBAoAUQQKABsECgAbBAoAJAGQABMBYP/aAQsAQgE6AEIA4wAuAOMAMAKzAC4BDABFAQwARQK/ABsA4wAuAj0ACQI9AEUBhwA/ANIAPwDjAC4BYP/kAfQAAAFg/9oBHwBMAU4ATAFYAH4BYP/kAIEALQFfADkBXwATAU0AaQFNABMBUQBfAVIAIAFzAEMBcwAdAWEAcwFhAB0BZQBpAWYAKgPoAAAB9AAAArwALwPoAAABfwA5AX8AOQF/ADkD6AAAAfQAAAGTAEMB+AAuAfgAIgE4AC4BOAAiAaAAMAGgAC4BoAAwAOMALgDjADAA4wAwAgwAOAIMACwBTAA4AUwALAEMAEUBDABFAdwALgHdACIBIgAuASMAIgDnADMCCgAIAgkARQGHAD8BnwAwAZ8ALgGfADAA4gAuAOIAMADjADAA0gA/AUkAJAFJACsCvAAAAGQAAADjAAABDQAAAIYAAAAAAAAC0wAwAjsAKgLTADACvAAfAm0AKQKqACoDJwAeAcH/pAKXAB4DBAAwAzgAVwKUAB4ChgAeAsgAHgOUAGkDcAAeBmoAaQNLAB4C7gAeAtAAHQKGAB4C0QBMAqoAMwSqAB4Cw//8AR8ATAIaAEwBYP/kAkYAQwJGAEMCRgBrAkYAQwJGAEMCRgBDAkYAQwJGAEMCRgBDAkYAQwJGAEMCRgA6AkYAOgJGAEMCRgAlA5sAKgGP/90DggAJAtz//wMsAGkCkQArAyMAQwKqAFsCvABIA0sAJQS6ACUCWABgAlgAeAJYAEMCWAB5AlgAagJYAG4CWABgAlgAbwLZADICWABfAlgAYAJYAEMCWABq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Bz4HPQdEB0MHTAdKB0cHQAdFB0EHRgdJB04HUwdSB1QHUAblBucG7AbyBvYG7wbjBt8G+gbwBuoG7QRuBG8ElwRqBI8EjgSRBJIEkwSMBI0ElAR3BHQEgQSIBGYEZwRoBGkEbARtBHAEcQRyBHMEdgSCBIMEhQSEBIYEhwSKBIsEiQSQBJUElgUGBQcFCAUJBQwFDQUQBREFEgUTBRYFIgUjBSUFJAUmBScFKgUrBSkFMAU1BTYFDgUPBTcFCgUvBS4FMQUyBTMFLAUtBTQFFwUUBSEFKASYBTgEmQU5BJoFOgSbBTsEdQUVBNgFeQTZBXoEawULBJwFPASdBT0EngU+BJ8FPwSgBUAEoQVBBKIFQgSjBUMEpAVEBKUFRQSmBUcEqAVIBKkFSQSqBUoEqwVLBKwFTAStBU0ErgVOBK8FTwSwBVAEsQVRBLMFUwS0BVQEtQS2BVYEtwVXBVgEuAVZBLkFWgS6BVsEuwVcBVUEvAVdBL0FXgS+BV8EvwVgBMAFYQTBBWIEwgVjBMMFZATEBWUExQVmBMYFZwTHBWgEyAVpBMkFagTKBWsEywVsBMwFbQTNBW4EzgVvBM8FcATQBXEE0QVyBNIFcwTTBXQE1AV1BNUFdgTWBXcE1wV4BKcFRgSyBVIE2gV7BNsFfAAlAasALQGyAC4BswBEAckAQwHIADQBuQBQAdYAVwHdAFQB2gBfAeUAcwH7AHUB/QB4AgAAfgIGAH8CBwCCAgoAowIrAKQCLACeAiYAnQIlAK8CNwCxAjkAuwJDALwCRAC0AjwAtwI/AL0CRQDFAk4AxgJPAN4CZwDaAmMA5AJtAOECagDjAmwA6gJzAPQCfQAVAZsAFwGdAA4BlAAQAZYAEQGXABIBmAAPAZUABwGNAAkBjwAKAZAACwGRAAgBjgA+AcMAQAHFAEYBywA2AbsAOAG9ADkBvgA6Ab8ANwG8AGMB6QBhAecAkQIZAJMCGwCIAhAAigISAIsCEwCMAhQAiQIRAJUCHQCXAh8AmAIgAJkCIQCWAh4AzgJXANACWQDSAlsA1AJdANUCXgDWAl8A0wJcAOwCdQDrAnQA7QJ2AO8CeAZzBnUGdwZ0BngGSgZJBkgGSwZXBlgGVgbVBtYGJwaBBoUGfgZ/BoQGjwaKBoIGgwZ5Bo4GjAaGBocGiwW/Bb4GtQavBrEGswa3BrgGtgaw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AREBEgETARQAYwEVAK4AkAEWACUAJgD9AP8AZAEXARgBGQAnARoA6QEbARwBHQEeAR8AKABlASABIQEiAMgBIwEkASUBJgEnASgAygEpASoAywErASwBLQEuAS8BMAExATIBMwApACoA+AE0ATUBNgE3ATgBOQArAToBOwE8AT0BPgAsAT8AzAFAAM0BQQDOAUIA+gFDAM8BRAFFAUYBRwFIAC0BSQAuAUoBSwAvAUwBTQFOAU8BUAFRAVIBUwDiADABVAAxAVUBVgFXAVgBWQFaAVsBXAFdAGYAMgDQAV4A0QFfAWABYQFiAWMBZABnAWUBZgFnANMBaAFpAWoBawFsAW0BbgFvAXABcQFyAXMBdACRAXUArwF2AXcBeACwADMA7QA0ADUBeQF6AXsBfAF9AX4BfwA2AYABgQGCAOQBgwD7AYQBhQGGAYcBiAGJAYoANwGLAYwBjQGOAY8BkAA4ANQBkQGSANUBkwBoAZQA1gGVAZYBlwGYAZkBmgGbAZwBnQGeAZ8BoAGhAaIBowA5ADoBpAGlAaYBpwA7ADwA6wGoALsBqQGqAasBrAGtAa4APQGvAOYBsAGxAbIBswG0AbUBtgG3AbgBuQG6AbsBvAG9Ab4BvwHAAcEBwgHDAcQBxQHGAccByAHJAcoBywHMAc0BzgHPAdAB0QHSAdMB1AHVAdYB1wHYAdkB2gHbAdwB3QHeAd8B4AHhAeIB4wHkAeUB5gHnAegB6QHqAesB7AHtAe4B7wHwAfEB8gHzAfQB9QH2AfcB+AH5AfoB+wH8Af0B/gH/AgACAQICAgMCBAIFAgYCBwIIAgkCCgILAgwCDQIOAg8CEAIRAhICEwIUAhUCFgIXAhgCGQIaAhsCHAIdAh4CHwIgAiECIgIjAiQCJQImAicCKAIpAioCKwIsAi0CLgIvAjACMQIyAjMCNAI1AjYCNwI4AjkCOgI7AjwCPQI+Aj8CQAJBAkICQwJEAkUCRgBEAGkCRwJIAkkCSgJLAkwCTQBrAk4CTwJQAlECUgJTAGwCVABqAlUCVgJXAlgAbgJZAG0AoAJaAEUARgD+AQAAbwJbAlwCXQBHAOoCXgEBAl8CYAJhAEgAcAJiAmMCZAByAmUCZgJnAmgCaQJqAHMCawJsAHECbQJuAm8CcAJxAnICcwJ0AnUCdgBJAEoA+QJ3AngCeQJ6AnsCfABLAn0CfgJ/AoACgQBMANcAdAKCAHYCgwB3AoQChQKGAHUChwKIAokCigKLAowATQKNAo4ATgKPApACkQBPApICkwKUApUClgKXApgA4wBQApkAUQKaApsCnAKdAp4CnwKgAqECogB4AFIAeQKjAHsCpAKlAqYCpwKoAqkAfAKqAqsCrAB6Aq0CrgKvArACsQKyArMCtAK1ArYCtwK4ArkAoQK6AH0CuwK8Ar0AsQBTAO4AVABVAr4CvwLAAsECwgLDAsQAVgLFAsYCxwDlAsgA/ALJAsoCywLMAs0AiQLOAFcCzwLQAtEC0gLTAtQC1QBYAH4C1gLXAIAC2ACBAtkAfwLaAtsC3ALdAt4C3wLgAuEC4gLjAuQC5QLmAucC6ABZAFoC6QLqAusC7ABbAFwA7ALtALoC7gLvAvAC8QLyAvMAXQL0AOcC9QL2AvcC+AL5AvoC+wL8Av0C/gL/AwADAQMCAwMDBAMFAwYDBwMIAwkDCgMLAwwDDQMOAw8DEAMRAxIDEwMUAxUDFgMXAxgDGQMaAxsDHAMdAx4DHwMgAyEDIgMjAyQDJQMmAycDKAMpAyoDKwMsAy0DLgMvAzADMQMyAzMDNAM1AzYDNwM4AzkDOgM7AzwDPQM+Az8DQANBA0IDQwNEA0UDRgNHA0gDSQNKA0sDTANNA04DTwNQA1EDUgNTAMAAwQNUA1UDVgNXA1gDWQNaA1sDXANdA14DXwNgA2EDYgNjA2QDZQNmA2cDaANpA2oDawNsA20DbgNvA3ADcQNyA3MDdAN1A3YDdwN4A3kDegN7A3wDfQN+A38DgAOBA4IDgwOEA4UDhgOHA4gDiQOKA4sDjAONA44DjwOQA5EDkgOTA5QDlQOWA5cDmAOZA5oDmwOcA50DngOfA6ADoQOiA6MDpAOlA6YDpwOoA6kDqgOrA6wDrQOuA68DsAOxA7IDswO0A7UDtgO3A7gDuQO6A7sDvAO9A74DvwPAA8EDwgPDA8QDxQPGA8cDyAPJA8oDywPMA80DzgPPA9AD0QPSA9MD1APVA9YD1wPYA9kD2gPbA9wD3QPeA98D4APhA+ID4wPkA+UD5gPnA+gD6QPqA+sD7APtA+4D7wPwA/ED8gPzA/QD9QP2A/cD+AP5A/oD+wP8A/0D/gP/BAAEAQQCBAMEBAQFBAYEBwQIBAkECgQLBAwEDQQOBA8EEAQRBBIEEwQUBBUEFgQXBBgEGQQaBBsEHAQdBB4EHwQgBCEEIgQjBCQEJQQmBCcEKAQpBCoEKwQsBC0ELgQvBDAEMQQyBDMENAQ1BDYENwQ4BDkEOgQ7BDwEPQQ+BD8EQARBBEIEQwREBEUERgRHBEgESQRKBEsETARNBE4ETwRQBFEEUgRTBFQEVQRWBFcEWARZBFoEWwRcBF0EXgRfBGAEYQRiBGMEZARlBGYEZwRoBGkEagRrBGwEbQRuBG8EcARxBHIEcwR0BHUEdgR3BHgEeQR6BHsEfAR9BH4EfwSABIEEggSDBIQEhQSGBIcEiASJBIoEiwSMBI0EjgSPBJAEkQSSBJMElASVBJYElwSYBJkEmgSbBJwEnQSeBJ8EoAShBKIEowSkBKUEpgSnBKgEqQSqBKsErAStBK4ErwSwBLEEsgSzBLQEtQS2BLcEuAS5BLoEuwS8BL0EvgS/BMAEwQTCBMMExATFBMYExwTIBMkEygTLBMwEzQTOBM8E0ATRBNIE0wTUBNUE1gTXBNgE2QTaAJ0AngTbBNwE3QTeBN8E4AThBOIE4wTkBOUE5gTnBOgE6QTqBOsE7ATtBO4E7wTwBPEE8gTzBPQE9QT2BPcE+AT5BPoE+wT8BP0E/gT/BQAFAQUCBQMFBAUFBQYFBwUIBQkFCgULBQwFDQUOBQ8FEAURBRIFEwUUBRUFFgUXBRgFGQUaBRsFHAUdBR4FHwUgBSEFIgUjBSQFJQUmBScFKAUpBSoFKwUsBS0FLgUvBTAFMQUyBTMFNAU1BTYFNwU4BTkFOgU7BTwFPQU+BT8FQAVBBUIFQwVEBUUFRgVHBUgFSQVKBUsFTAVNBU4FTwVQBVEFUgVTBVQFVQVWBVcFWAVZBVoFWwVcBV0FXgVfBWAFYQViBWMFZAVlBWYFZwVoBWkFagVrBWwFbQVuBW8FcAVxBXIFcwV0BXUFdgV3BXgFeQV6BXsFfAV9BX4FfwWABYEFggWDBYQFhQWGBYcFiAWJBYoFiwWMBY0FjgWPBZAFkQWSBZMFlAWVBZYFlwWYBZkFmgWbBZwFnQWeBZ8FoAWhBaIFowWkBaUFpgWnBagFqQWqBasFrAWtBa4FrwWwBbEFsgWzBbQFtQW2BbcFuAW5BboFuwW8Bb0FvgW/BcAFwQXCBcMFxAXFBcYFxwXIBckFygXLBcwFzQXOBc8F0AXRBdIF0wXUBdUF1gXXBdgF2QXaBdsF3AXdBd4F3wXgBeEF4gXjBeQF5QXmBecF6AXpBeoF6wXsBe0F7gXvBfAF8QXyBfMF9AX1BfYF9wX4BfkF+gX7BfwF/QX+Bf8GAAYBBgIGAwYEBgUGBgYHBggGCQYKBgsGDAYNBg4GDwYQBhEGEgYTBhQGFQYWBhcGGAYZBhoGGwYcBh0GHgYfBiAGIQYiBiMGJAYlBiYGJwYoBikGKgYrBiwGLQYuBi8GMAYxAJsGMgYzABMAFAAVABYAFwAYABkAGgAbABwGNAY1BjYGNwY4BjkGOgY7BjwGPQY+Bj8GQAZBBkIGQwZEBkUGRgZHBkgGSQZKBksGTAZNBk4GTwZQBlEGUgZTBlQGVQZWBlcGWAZZBloGWwZcBl0GXgZfBmAGYQZiBmMGZAZlBmYGZwZoBmkGagZrBmwGbQZuBm8GcAZxBnIGcwZ0BnUGdgZ3BngGeQZ6BnsGfAZ9Bn4GfwaABoEGggaDALwA9AaEBoUA9QD2BoYGhwaIBokADQA/AMMAhwAdAA8AqwAEAKMABgARACIAogAFAAoAHgASAEIGigaLBowGjQaOBo8AXgBgAD4AQAALAAwGkAaRBpIGkwaUBpUAswCyBpYGlwAQBpgGmQaaBpsGnACpAKoAvgC/AMUAtAC1ALYAtwDEBp0GngafBqAGoQaiBqMGpAalBqYGpwaoBqkGqgarBqwGrQauBq8GsAaxBrIGswa0BrUGtga3BrgGuQa6AIQGuwC9AAcGvAa9AKYA9wa+Br8GwAbBBsIGwwbEBsUGxgbHBsgAhQbJBsoGywCWBswGzQbOAA4A7wDwALgAIACPACEAHwCVAJQAkwCnAGEApAbPAJIAnAbQBtEAmgCZAKUG0gCYAAgAxgbTBtQG1QbWBtcG2AbZBtoG2wbcBt0G3gbfBuAG4QbiALkG4wbkBuUG5gbnBugG6QbqBusG7AAjAAkAiACGAIsAigCMAIMAXwDoBu0AggDCBu4G7wBBBvAG8QbyBvMG9Ab1BvYG9wb4BvkG+gb7BvwG/Qb+Bv8HAAcBBwIHAwcEBwUHBgcHBwgHCQcKBwsHDAcNBw4HDwcQBxEHEgcTBxQHFQcWBxcHGAcZBxoHGwccBx0HHgcfByAHIQciByMHJAclByYHJwcoBykHKgcrBywHLQcuBy8HMAcxBzIHMwc0BzUHNgc3BzgHOQc6BzsHPAc9Bz4HPwdAB0EHQgdDB0QHRQdGB0cHSAdJB0oHSwdMB00HTgdPB1AHUQdSB1MHVAdVB1YHVwdYB1kHWgdbB1wHXQCNANsA4QDeANgAjgDcAEMA3wDaAOAA3QDZB14HXwdgB2EHYgdjB2QHZQdmB2cHaAdpB2oHawdsB20HbgdvB3AHcQdyB3MHdAd1B3YHdwd4BE5VTEwGQWJyZXZlB3VuaTFFQUUHdW5pMUVCNgd1bmkxRUIwB3VuaTFFQjIHdW5pMUVCNAd1bmkwMUNEB3VuaTFFQTQHdW5pMUVBQwd1bmkxRUE2B3VuaTFFQTgHdW5pMUVBQQd1bmkwMjAwB3VuaTFFQTAHdW5pMUVBMgd1bmkwMjAyB0FtYWNyb24HQW9nb25lawpBcmluZ2FjdXRlB0FFYWN1dGUHdW5pMUUwOAtDY2lyY3VtZmxleApDZG90YWNjZW50B3VuaTAxQzQGRGNhcm9uBkRjcm9hdAd1bmkxRTBDB3VuaTFFMEUHdW5pMDFDNQZFYnJldmUGRWNhcm9uB3VuaTFFMUMHdW5pMUVCRQd1bmkxRUM2B3VuaTFFQzAHdW5pMUVDMgd1bmkxRUM0B3VuaTAyMDQKRWRvdGFjY2VudAd1bmkxRUI4B3VuaTFFQkEHdW5pMDIwNgdFbWFjcm9uB3VuaTFFMTYHdW5pMUUxNAdFb2dvbmVrB3VuaTFFQkMHdW5pMDFCNwd1bmkwMUVFBkdjYXJvbgtHY2lyY3VtZmxleAxHY29tbWFhY2NlbnQKR2RvdGFjY2VudAd1bmkxRTIwB3VuaTAxRTQESGJhcgd1bmkxRTJBB3VuaTAyMUULSGNpcmN1bWZsZXgHdW5pMUUyNAJJSgZJYnJldmUHdW5pMDIwOAd1bmkxRTJFB3VuaTFFQ0EHdW5pMUVDOAd1bmkwMjBBB0ltYWNyb24HSW9nb25lawZJdGlsZGULSmNpcmN1bWZsZXgHdW5pMDFFOAxLY29tbWFhY2NlbnQHdW5pMDFDNwZMYWN1dGUGTGNhcm9uDExjb21tYWFjY2VudARMZG90B3VuaTFFMzYHdW5pMDFDOAd1bmkxRTNBB3VuaTFFNDIHdW5pMDFDQQZOYWN1dGUGTmNhcm9uDE5jb21tYWFjY2VudAd1bmkxRTQ0B3VuaTFFNDYDRW5nB3VuaTAxQ0IHdW5pMUU0OAZPYnJldmUHdW5pMUVEMAd1bmkxRUQ4B3VuaTFFRDIHdW5pMUVENAd1bmkxRUQ2B3VuaTAyMEMHdW5pMDIyQQd1bmkwMjMwB3VuaTFFQ0MHdW5pMUVDRQVPaG9ybgd1bmkxRURBB3VuaTFFRTIHdW5pMUVEQwd1bmkxRURFB3VuaTFFRTANT2h1bmdhcnVtbGF1dAd1bmkwMjBFB09tYWNyb24HdW5pMUU1Mgd1bmkxRTUwB3VuaTAxRUELT3NsYXNoYWN1dGUHdW5pMUU0Qwd1bmkxRTRFB3VuaTAyMkMGUmFjdXRlBlJjYXJvbgxSY29tbWFhY2NlbnQHdW5pMDIxMAd1bmkxRTVBB3VuaTAyMTIHdW5pMUU1RQZTYWN1dGUHdW5pMUU2NAd1bmlBNzhCB3VuaTFFNjYLU2NpcmN1bWZsZXgMU2NvbW1hYWNjZW50B3VuaTFFNjAHdW5pMUU2Mgd1bmkxRTY4B3VuaTFFOUUHdW5pMDE4RgRUYmFyBlRjYXJvbgd1bmkwMTYyB3VuaTAyMUEHdW5pMUU2Qwd1bmkxRTZFBlVicmV2ZQd1bmkwMUQzB3VuaTAyMTQHdW5pMUVFNAd1bmkxRUU2BVVob3JuB3VuaTFFRTgHdW5pMUVGMAd1bmkxRUVBB3VuaTFFRUMHdW5pMUVFRQ1VaHVuZ2FydW1sYXV0B3VuaTAyMTYHVW1hY3Jvbgd1bmkxRTdBB1VvZ29uZWsFVXJpbmcGVXRpbGRlB3VuaTFFNzgGV2FjdXRlC1djaXJjdW1mbGV4CVdkaWVyZXNpcwZXZ3JhdmULWWNpcmN1bWZsZXgHdW5pMUU4RQd1bmkxRUY0BllncmF2ZQd1bmkxRUY2B3VuaTAyMzIHdW5pMUVGOAZaYWN1dGUKWmRvdGFjY2VudAd1bmkxRTkyEElhY3V0ZV9KLmxvY2xOTEQGQS5zczAxC0FhY3V0ZS5zczAxC0FicmV2ZS5zczAxDHVuaTFFQUUuc3MwMQx1bmkxRUI2LnNzMDEMdW5pMUVCMC5zczAxDHVuaTFFQjIuc3MwMQx1bmkxRUI0LnNzMDEMdW5pMDFDRC5zczAxEEFjaXJjdW1mbGV4LnNzMDEMdW5pMUVBNC5zczAxDHVuaTFFQUMuc3MwMQx1bmkxRUE2LnNzMDEMdW5pMUVBOC5zczAxDHVuaTFFQUEuc3MwMQx1bmkwMjAwLnNzMDEOQWRpZXJlc2lzLnNzMDEMdW5pMUVBMC5zczAxC0FncmF2ZS5zczAxDHVuaTFFQTIuc3MwMQx1bmkwMjAyLnNzMDEMQW1hY3Jvbi5zczAxDEFvZ29uZWsuc3MwMQpBcmluZy5zczAxD0FyaW5nYWN1dGUuc3MwMQtBdGlsZGUuc3MwMQdBRS5zczAxDEFFYWN1dGUuc3MwMQx1bmkwMUM0LnNzMDEMdW5pMDFDNS5zczAxBkUuc3MwMQtFYWN1dGUuc3MwMQtFYnJldmUuc3MwMQtFY2Fyb24uc3MwMQx1bmkxRTFDLnNzMDEQRWNpcmN1bWZsZXguc3MwMQx1bmkxRUJFLnNzMDEMdW5pMUVDNi5zczAxDHVuaTFFQzAuc3MwMQx1bmkxRUMyLnNzMDEMdW5pMUVDNC5zczAxDHVuaTAyMDQuc3MwMQ5FZGllcmVzaXMuc3MwMQ9FZG90YWNjZW50LnNzMDEMdW5pMUVCOC5zczAxC0VncmF2ZS5zczAxDHVuaTFFQkEuc3MwMQx1bmkwMjA2LnNzMDEMRW1hY3Jvbi5zczAxDHVuaTFFMTYuc3MwMQx1bmkxRTE0LnNzMDEMRW9nb25lay5zczAxDHVuaTFFQkMuc3MwMQZGLnNzMDEGRy5zczAxC0dicmV2ZS5zczAxC0djYXJvbi5zczAxEEdjaXJjdW1mbGV4LnNzMDERR2NvbW1hYWNjZW50LnNzMDEPR2RvdGFjY2VudC5zczAxDHVuaTFFMjAuc3MwMQx1bmkwMUU0LnNzMDEGSS5zczAxB0lKLnNzMDELSWFjdXRlLnNzMDEVSWFjdXRlX0oubG9jbE5MRC5zczAxC0licmV2ZS5zczAxEEljaXJjdW1mbGV4LnNzMDEMdW5pMDIwOC5zczAxDklkaWVyZXNpcy5zczAxDHVuaTFFMkUuc3MwMQ9JZG90YWNjZW50LnNzMDEMdW5pMUVDQS5zczAxC0lncmF2ZS5zczAxDHVuaTFFQzguc3MwMQx1bmkwMjBBLnNzMDEMSW1hY3Jvbi5zczAxDElvZ29uZWsuc3MwMQtJdGlsZGUuc3MwMQZKLnNzMDEQSmNpcmN1bWZsZXguc3MwMQx1bmkwMUM3LnNzMDEGTS5zczAxDHVuaTFFNDIuc3MwMQZOLnNzMDEMdW5pMDFDQS5zczAxC05hY3V0ZS5zczAxC05jYXJvbi5zczAxEU5jb21tYWFjY2VudC5zczAxDHVuaTFFNDQuc3MwMQx1bmkxRTQ2LnNzMDEIRW5nLnNzMDEMdW5pMDFDQi5zczAxDHVuaTFFNDguc3MwMQtOdGlsZGUuc3MwMQZRLnNzMDEMdW5pMDE4Ri5zczAxBlQuc3MwMQlUYmFyLnNzMDELVGNhcm9uLnNzMDEMdW5pMDE2Mi5zczAxDHVuaTAyMUEuc3MwMQx1bmkxRTZDLnNzMDEMdW5pMUU2RS5zczAxBlUuc3MwMQtVYWN1dGUuc3MwMQtVYnJldmUuc3MwMQx1bmkwMUQzLnNzMDEQVWNpcmN1bWZsZXguc3MwMQx1bmkwMjE0LnNzMDEOVWRpZXJlc2lzLnNzMDEMdW5pMUVFNC5zczAxC1VncmF2ZS5zczAxDHVuaTFFRTYuc3MwMQpVaG9ybi5zczAxDHVuaTFFRTguc3MwMQx1bmkxRUYwLnNzMDEMdW5pMUVFQS5zczAxDHVuaTFFRUMuc3MwMQx1bmkxRUVFLnNzMDESVWh1bmdhcnVtbGF1dC5zczAxDHVuaTAyMTYuc3MwMQxVbWFjcm9uLnNzMDEMdW5pMUU3QS5zczAxDFVvZ29uZWsuc3MwMQpVcmluZy5zczAxC1V0aWxkZS5zczAxDHVuaTFFNzguc3MwMQZXLnNzMDELV2FjdXRlLnNzMDEQV2NpcmN1bWZsZXguc3MwMQ5XZGllcmVzaXMuc3MwMQtXZ3JhdmUuc3MwMQZZLnNzMDELWWFjdXRlLnNzMDEQWWNpcmN1bWZsZXguc3MwMQ5ZZGllcmVzaXMuc3MwMQx1bmkxRThFLnNzMDEMdW5pMUVGNC5zczAxC1lncmF2ZS5zczAxDHVuaTFFRjYuc3MwMQx1bmkwMjMyLnNzMDEMdW5pMUVGOC5zczAxBlouc3MwMQtaYWN1dGUuc3MwMQtaY2Fyb24uc3MwMQ9aZG90YWNjZW50LnNzMDEMdW5pMUU5Mi5zczAxBmFicmV2ZQd1bmkxRUFGB3VuaTFFQjcHdW5pMUVCMQd1bmkxRUIzB3VuaTFFQjUHdW5pMDFDRQd1bmkxRUE1B3VuaTFFQUQHdW5pMUVBNwd1bmkxRUE5B3VuaTFFQUIHdW5pMDIwMQd1bmkxRUExB3VuaTFFQTMHdW5pMDIwMwdhbWFjcm9uB2FvZ29uZWsKYXJpbmdhY3V0ZQdhZWFjdXRlB3VuaTFFMDkLY2NpcmN1bWZsZXgKY2RvdGFjY2VudAZkY2Fyb24HdW5pMUUwRAd1bmkxRTBGB3VuaTAxQzYGZWJyZXZlBmVjYXJvbgd1bmkxRTFEB3VuaTFFQkYHdW5pMUVDNwd1bmkxRUMxB3VuaTFFQzMHdW5pMUVDNQd1bmkwMjA1CmVkb3RhY2NlbnQHdW5pMUVCOQd1bmkxRUJCB3VuaTAyMDcHZW1hY3Jvbgd1bmkxRTE3B3VuaTFFMTUHZW9nb25lawd1bmkxRUJEB3VuaTAyNTkHdW5pMDI5Mgd1bmkwMUVGBmdjYXJvbgtnY2lyY3VtZmxleAxnY29tbWFhY2NlbnQKZ2RvdGFjY2VudAd1bmkxRTIxB3VuaTAxRTUEaGJhcgd1bmkxRTJCB3VuaTAyMUYLaGNpcmN1bWZsZXgHdW5pMUUyNQZpYnJldmUHdW5pMDIwOQd1bmkxRTJGCWkubG9jbFRSSwd1bmkxRUNCB3VuaTFFQzkHdW5pMDIwQgJpagdpbWFjcm9uB2lvZ29uZWsGaXRpbGRlB3VuaTAyMzcLamNpcmN1bWZsZXgHdW5pMDFFOQxrY29tbWFhY2NlbnQMa2dyZWVubGFuZGljBmxhY3V0ZQZsY2Fyb24MbGNvbW1hYWNjZW50BGxkb3QHdW5pMUUzNwd1bmkwMUM5B3VuaTFFM0IHdW5pMUU0MwZuYWN1dGULbmFwb3N0cm9waGUGbmNhcm9uDG5jb21tYWFjY2VudAd1bmkxRTQ1B3VuaTFFNDcDZW5nB3VuaTAxQ0MHdW5pMUU0OQZvYnJldmUHdW5pMUVEMQd1bmkxRUQ5B3VuaTFFRDMHdW5pMUVENQd1bmkxRUQ3B3VuaTAyMEQHdW5pMDIyQgd1bmkwMjMxB3VuaTFFQ0QHdW5pMUVDRgVvaG9ybgd1bmkxRURCB3VuaTFFRTMHdW5pMUVERAd1bmkxRURGB3VuaTFFRTENb2h1bmdhcnVtbGF1dAd1bmkwMjBGB29tYWNyb24HdW5pMUU1Mwd1bmkxRTUxB3VuaTAxRUILb3NsYXNoYWN1dGUHdW5pMUU0RAd1bmkxRTRGB3VuaTAyMkQGcmFjdXRlBnJjYXJvbgxyY29tbWFhY2NlbnQHdW5pMDIxMQd1bmkxRTVCB3VuaTAyMTMHdW5pMUU1RgZzYWN1dGUHdW5pMUU2NQd1bmlBNzhDB3VuaTFFNjcLc2NpcmN1bWZsZXgMc2NvbW1hYWNjZW50B3VuaTFFNjEHdW5pMUU2Mwd1bmkxRTY5BWxvbmdzBHRiYXIGdGNhcm9uB3VuaTAxNjMHdW5pMDIxQgd1bmkxRTk3B3VuaTFFNkQHdW5pMUU2RgZ1YnJldmUHdW5pMDFENAd1bmkwMjE1B3VuaTFFRTUHdW5pMUVFNwV1aG9ybgd1bmkxRUU5B3VuaTFFRjEHdW5pMUVFQgd1bmkxRUVEB3VuaTFFRUYNdWh1bmdhcnVtbGF1dAd1bmkwMjE3B3VtYWNyb24HdW5pMUU3Qgd1b2dvbmVrBXVyaW5nBnV0aWxkZQd1bmkxRTc5BndhY3V0ZQt3Y2lyY3VtZmxleAl3ZGllcmVzaXMGd2dyYXZlC3ljaXJjdW1mbGV4B3VuaTFFOEYHdW5pMUVGNQZ5Z3JhdmUHdW5pMUVGNwd1bmkwMjMzB3VuaTFFRjkGemFjdXRlCnpkb3RhY2NlbnQHdW5pMUU5MxBpYWN1dGVfai5sb2NsTkxEBmEuc3MwMQthYWN1dGUuc3MwMQthYnJldmUuc3MwMQx1bmkxRUFGLnNzMDEMdW5pMUVCNy5zczAxDHVuaTFFQjEuc3MwMQx1bmkxRUIzLnNzMDEMdW5pMUVCNS5zczAxDHVuaTAxQ0Uuc3MwMRBhY2lyY3VtZmxleC5zczAxDHVuaTFFQTUuc3MwMQx1bmkxRUFELnNzMDEMdW5pMUVBNy5zczAxDHVuaTFFQTkuc3MwMQx1bmkxRUFCLnNzMDEMdW5pMDIwMS5zczAxDmFkaWVyZXNpcy5zczAxDHVuaTFFQTEuc3MwMQthZ3JhdmUuc3MwMQx1bmkxRUEzLnNzMDEMdW5pMDIwMy5zczAxDGFtYWNyb24uc3MwMQxhb2dvbmVrLnNzMDEKYXJpbmcuc3MwMQ9hcmluZ2FjdXRlLnNzMDELYXRpbGRlLnNzMDEHYWUuc3MwMQxhZWFjdXRlLnNzMDEMdW5pMDFDNi5zczAxBmUuc3MwMQtlYWN1dGUuc3MwMQtlYnJldmUuc3MwMQtlY2Fyb24uc3MwMQx1bmkxRTFELnNzMDEQZWNpcmN1bWZsZXguc3MwMQx1bmkxRUJGLnNzMDEMdW5pMUVDNy5zczAxDHVuaTFFQzEuc3MwMQx1bmkxRUMzLnNzMDEMdW5pMUVDNS5zczAxDHVuaTAyMDUuc3MwMQ5lZGllcmVzaXMuc3MwMQ9lZG90YWNjZW50LnNzMDEMdW5pMUVCOS5zczAxC2VncmF2ZS5zczAxDHVuaTFFQkIuc3MwMQx1bmkwMjA3LnNzMDEMZW1hY3Jvbi5zczAxDHVuaTFFMTcuc3MwMQx1bmkxRTE1LnNzMDEMZW9nb25lay5zczAxDHVuaTFFQkQuc3MwMQx1bmkwMjU5LnNzMDEGZi5zczAxBmwuc3MwMQtsYWN1dGUuc3MwMQtsY2Fyb24uc3MwMRFsY29tbWFhY2NlbnQuc3MwMQlsZG90LnNzMDEMdW5pMUUzNy5zczAxDHVuaTAxQzkuc3MwMQx1bmkxRTNCLnNzMDELbHNsYXNoLnNzMDEHb2Uuc3MwMQZ0LnNzMDEJdGJhci5zczAxC3RjYXJvbi5zczAxDHVuaTAxNjMuc3MwMQx1bmkwMjFCLnNzMDEMdW5pMUU5Ny5zczAxDHVuaTFFNkQuc3MwMQx1bmkxRTZGLnNzMDEGdy5zczAxC3dhY3V0ZS5zczAxEHdjaXJjdW1mbGV4LnNzMDEOd2RpZXJlc2lzLnNzMDELd2dyYXZlLnNzMDEGeS5zczAxC3lhY3V0ZS5zczAxEHljaXJjdW1mbGV4LnNzMDEOeWRpZXJlc2lzLnNzMDEMdW5pMUVGNS5zczAxC3lncmF2ZS5zczAxDHVuaTFFRjcuc3MwMQx1bmkwMjMzLnNzMDEMdW5pMUVGOS5zczAxBnouc3MwMQt6YWN1dGUuc3MwMQt6Y2Fyb24uc3MwMQ96ZG90YWNjZW50LnNzMDEMdW5pMUU5My5zczAxA1RfaAdmaS5zczAxB2ZsLnNzMDEEYS5zYwlhYWN1dGUuc2MJYWJyZXZlLnNjCnVuaTFFQUYuc2MKdW5pMUVCNy5zYwp1bmkxRUIxLnNjCnVuaTFFQjMuc2MKdW5pMUVCNS5zYwp1bmkwMUNFLnNjDmFjaXJjdW1mbGV4LnNjCnVuaTFFQTUuc2MKdW5pMUVBRC5zYwp1bmkxRUE3LnNjCnVuaTFFQTkuc2MKdW5pMUVBQi5zYwp1bmkwMjAxLnNjDGFkaWVyZXNpcy5zYwp1bmkxRUExLnNjCWFncmF2ZS5zYwp1bmkxRUEzLnNjCnVuaTAyMDMuc2MKYW1hY3Jvbi5zYwphb2dvbmVrLnNjCGFyaW5nLnNjDWFyaW5nYWN1dGUuc2MJYXRpbGRlLnNjBWFlLnNjCmFlYWN1dGUuc2MEYi5zYwRjLnNjCWNhY3V0ZS5zYwljY2Fyb24uc2MLY2NlZGlsbGEuc2MKdW5pMUUwOS5zYw5jY2lyY3VtZmxleC5zYw1jZG90YWNjZW50LnNjBGQuc2MGZXRoLnNjCWRjYXJvbi5zYwlkY3JvYXQuc2MKdW5pMUUwRC5zYwp1bmkxRTBGLnNjCnVuaTAxQzYuc2MEZS5zYwllYWN1dGUuc2MJZWJyZXZlLnNjCWVjYXJvbi5zYwp1bmkxRTFELnNjDmVjaXJjdW1mbGV4LnNjCnVuaTFFQkYuc2MKdW5pMUVDNy5zYwp1bmkxRUMxLnNjCnVuaTFFQzMuc2MKdW5pMUVDNS5zYwp1bmkwMjA1LnNjDGVkaWVyZXNpcy5zYw1lZG90YWNjZW50LnNjCnVuaTFFQjkuc2MJZWdyYXZlLnNjCnVuaTFFQkIuc2MKdW5pMDIwNy5zYwplbWFjcm9uLnNjCnVuaTFFMTcuc2MKdW5pMUUxNS5zYwplb2dvbmVrLnNjCnVuaTFFQkQuc2MKdW5pMDI1OS5zYwp1bmkwMjkyLnNjCnVuaTAxRUYuc2MEZi5zYwRnLnNjCWdicmV2ZS5zYwlnY2Fyb24uc2MOZ2NpcmN1bWZsZXguc2MPZ2NvbW1hYWNjZW50LnNjDWdkb3RhY2NlbnQuc2MKdW5pMUUyMS5zYwp1bmkwMUU1LnNjBGguc2MHaGJhci5zYwp1bmkxRTJCLnNjCnVuaTAyMUYuc2MOaGNpcmN1bWZsZXguc2MKdW5pMUUyNS5zYwRpLnNjC2RvdGxlc3NpLnNjCWlhY3V0ZS5zYxNpYWN1dGVfai5sb2NsTkxELnNjCWlicmV2ZS5zYw5pY2lyY3VtZmxleC5zYwp1bmkwMjA5LnNjDGlkaWVyZXNpcy5zYwp1bmkxRTJGLnNjDGkuc2MubG9jbFRSSwp1bmkxRUNCLnNjCWlncmF2ZS5zYwp1bmkxRUM5LnNjCnVuaTAyMEIuc2MFaWouc2MKaW1hY3Jvbi5zYwppb2dvbmVrLnNjCWl0aWxkZS5zYwRqLnNjDmpjaXJjdW1mbGV4LnNjBGsuc2MKdW5pMDFFOS5zYw9rY29tbWFhY2NlbnQuc2MPa2dyZWVubGFuZGljLnNjBGwuc2MJbGFjdXRlLnNjCWxjYXJvbi5zYw9sY29tbWFhY2NlbnQuc2MHbGRvdC5zYwp1bmkxRTM3LnNjCnVuaTAxQzkuc2MKdW5pMUUzQi5zYwlsc2xhc2guc2MEbS5zYwp1bmkxRTQzLnNjBG4uc2MJbmFjdXRlLnNjCW5jYXJvbi5zYw9uY29tbWFhY2NlbnQuc2MKdW5pMUU0NS5zYwp1bmkxRTQ3LnNjBmVuZy5zYwp1bmkwMUNDLnNjCnVuaTFFNDkuc2MJbnRpbGRlLnNjBG8uc2MJb2FjdXRlLnNjCW9icmV2ZS5zYw5vY2lyY3VtZmxleC5zYwp1bmkxRUQxLnNjCnVuaTFFRDkuc2MKdW5pMUVEMy5zYwp1bmkxRUQ1LnNjCnVuaTFFRDcuc2MKdW5pMDIwRC5zYwxvZGllcmVzaXMuc2MKdW5pMDIyQi5zYwp1bmkwMjMxLnNjCnVuaTFFQ0Quc2MJb2dyYXZlLnNjCnVuaTFFQ0Yuc2MIb2hvcm4uc2MKdW5pMUVEQi5zYwp1bmkxRUUzLnNjCnVuaTFFREQuc2MKdW5pMUVERi5zYwp1bmkxRUUxLnNjEG9odW5nYXJ1bWxhdXQuc2MKdW5pMDIwRi5zYwpvbWFjcm9uLnNjCnVuaTFFNTMuc2MKdW5pMUU1MS5zYwp1bmkwMUVCLnNjCW9zbGFzaC5zYw5vc2xhc2hhY3V0ZS5zYwlvdGlsZGUuc2MKdW5pMUU0RC5zYwp1bmkxRTRGLnNjCnVuaTAyMkQuc2MFb2Uuc2MEcC5zYwh0aG9ybi5zYwRxLnNjBHIuc2MJcmFjdXRlLnNjCXJjYXJvbi5zYw9yY29tbWFhY2NlbnQuc2MKdW5pMDIxMS5zYwp1bmkxRTVCLnNjCnVuaTAyMTMuc2MKdW5pMUU1Ri5zYwRzLnNjCXNhY3V0ZS5zYwp1bmkxRTY1LnNjCnVuaUE3OEMuc2MJc2Nhcm9uLnNjCnVuaTFFNjcuc2MLc2NlZGlsbGEuc2MOc2NpcmN1bWZsZXguc2MPc2NvbW1hYWNjZW50LnNjCnVuaTFFNjEuc2MKdW5pMUU2My5zYwp1bmkxRTY5LnNjDWdlcm1hbmRibHMuc2MEdC5zYwd0YmFyLnNjCXRjYXJvbi5zYwp1bmkwMTYzLnNjCnVuaTAyMUIuc2MKdW5pMUU5Ny5zYwp1bmkxRTZELnNjCnVuaTFFNkYuc2MEdS5zYwl1YWN1dGUuc2MJdWJyZXZlLnNjCnVuaTAxRDQuc2MOdWNpcmN1bWZsZXguc2MKdW5pMDIxNS5zYwx1ZGllcmVzaXMuc2MKdW5pMUVFNS5zYwl1Z3JhdmUuc2MKdW5pMUVFNy5zYwh1aG9ybi5zYwp1bmkxRUU5LnNjCnVuaTFFRjEuc2MKdW5pMUVFQi5zYwp1bmkxRUVELnNjCnVuaTFFRUYuc2MQdWh1bmdhcnVtbGF1dC5zYwp1bmkwMjE3LnNjCnVtYWNyb24uc2MKdW5pMUU3Qi5zYwp1b2dvbmVrLnNjCHVyaW5nLnNjCXV0aWxkZS5zYwp1bmkxRTc5LnNjBHYuc2MEdy5zYwl3YWN1dGUuc2MOd2NpcmN1bWZsZXguc2MMd2RpZXJlc2lzLnNjCXdncmF2ZS5zYwR4LnNjBHkuc2MJeWFjdXRlLnNjDnljaXJjdW1mbGV4LnNjDHlkaWVyZXNpcy5zYwp1bmkxRThGLnNjCnVuaTFFRjUuc2MJeWdyYXZlLnNjCnVuaTFFRjcuc2MKdW5pMDIzMy5zYwp1bmkxRUY5LnNjBHouc2MJemFjdXRlLnNjCXpjYXJvbi5zYw16ZG90YWNjZW50LnNjCnVuaTFFOTMuc2MJYS5zYy5zczAxDmFhY3V0ZS5zYy5zczAxDmFicmV2ZS5zYy5zczAxD3VuaTFFQUYuc2Muc3MwMQ91bmkxRUI3LnNjLnNzMDEPdW5pMUVCMS5zYy5zczAxD3VuaTFFQjMuc2Muc3MwMQ91bmkxRUI1LnNjLnNzMDEPdW5pMDFDRS5zYy5zczAxE2FjaXJjdW1mbGV4LnNjLnNzMDEPdW5pMUVBNS5zYy5zczAxD3VuaTFFQUQuc2Muc3MwMQ91bmkxRUE3LnNjLnNzMDEPdW5pMUVBOS5zYy5zczAxD3VuaTFFQUIuc2Muc3MwMQ91bmkwMjAxLnNjLnNzMDERYWRpZXJlc2lzLnNjLnNzMDEPdW5pMUVBMS5zYy5zczAxDmFncmF2ZS5zYy5zczAxD3VuaTFFQTMuc2Muc3MwMQ91bmkwMjAzLnNjLnNzMDEPYW1hY3Jvbi5zYy5zczAxD2FvZ29uZWsuc2Muc3MwMQ1hcmluZy5zYy5zczAxEmFyaW5nYWN1dGUuc2Muc3MwMQ5hdGlsZGUuc2Muc3MwMQphZS5zYy5zczAxD2FlYWN1dGUuc2Muc3MwMQ91bmkwMUM2LnNjLnNzMDEJZS5zYy5zczAxDmVhY3V0ZS5zYy5zczAxDmVicmV2ZS5zYy5zczAxDmVjYXJvbi5zYy5zczAxD3VuaTFFMUQuc2Muc3MwMRNlY2lyY3VtZmxleC5zYy5zczAxD3VuaTFFQkYuc2Muc3MwMQ91bmkxRUM3LnNjLnNzMDEPdW5pMUVDMS5zYy5zczAxD3VuaTFFQzMuc2Muc3MwMQ91bmkxRUM1LnNjLnNzMDEPdW5pMDIwNS5zYy5zczAxEWVkaWVyZXNpcy5zYy5zczAxEmVkb3RhY2NlbnQuc2Muc3MwMQ91bmkxRUI5LnNjLnNzMDEOZWdyYXZlLnNjLnNzMDEPdW5pMUVCQi5zYy5zczAxD3VuaTAyMDcuc2Muc3MwMQ9lbWFjcm9uLnNjLnNzMDEPdW5pMUUxNy5zYy5zczAxD3VuaTFFMTUuc2Muc3MwMQ9lb2dvbmVrLnNjLnNzMDEPdW5pMUVCRC5zYy5zczAxD3VuaTAyNTkuc2Muc3MwMQlmLnNjLnNzMDEJZy5zYy5zczAxDmdicmV2ZS5zYy5zczAxDmdjYXJvbi5zYy5zczAxE2djaXJjdW1mbGV4LnNjLnNzMDEUZ2NvbW1hYWNjZW50LnNjLnNzMDESZ2RvdGFjY2VudC5zYy5zczAxD3VuaTFFMjEuc2Muc3MwMQ91bmkwMUU1LnNjLnNzMDEJaS5zYy5zczAxEGRvdGxlc3NpLnNjLnNzMDEOaWFjdXRlLnNjLnNzMDEYaWFjdXRlX2oubG9jbE5MRC5zYy5zczAxDmlicmV2ZS5zYy5zczAxE2ljaXJjdW1mbGV4LnNjLnNzMDEPdW5pMDIwOS5zYy5zczAxEWlkaWVyZXNpcy5zYy5zczAxD3VuaTFFMkYuc2Muc3MwMQ91bmkxRUNCLnNjLnNzMDEOaWdyYXZlLnNjLnNzMDEPdW5pMUVDOS5zYy5zczAxD3VuaTAyMEIuc2Muc3MwMQppai5zYy5zczAxD2ltYWNyb24uc2Muc3MwMQ9pb2dvbmVrLnNjLnNzMDEOaXRpbGRlLnNjLnNzMDEJai5zYy5zczAxE2pjaXJjdW1mbGV4LnNjLnNzMDEPdW5pMDFDOS5zYy5zczAxCW0uc2Muc3MwMQ91bmkxRTQzLnNjLnNzMDEJbi5zYy5zczAxDm5hY3V0ZS5zYy5zczAxDm5jYXJvbi5zYy5zczAxFG5jb21tYWFjY2VudC5zYy5zczAxD3VuaTFFNDUuc2Muc3MwMQ91bmkxRTQ3LnNjLnNzMDELZW5nLnNjLnNzMDEPdW5pMDFDQy5zYy5zczAxD3VuaTFFNDkuc2Muc3MwMQ5udGlsZGUuc2Muc3MwMQlxLnNjLnNzMDEJdC5zYy5zczAxDHRiYXIuc2Muc3MwMQ50Y2Fyb24uc2Muc3MwMQ91bmkwMTYzLnNjLnNzMDEPdW5pMDIxQi5zYy5zczAxD3VuaTFFOTcuc2Muc3MwMQ91bmkxRTZELnNjLnNzMDEPdW5pMUU2Ri5zYy5zczAxCXUuc2Muc3MwMQ51YWN1dGUuc2Muc3MwMQ51YnJldmUuc2Muc3MwMQ91bmkwMUQ0LnNjLnNzMDETdWNpcmN1bWZsZXguc2Muc3MwMQ91bmkwMjE1LnNjLnNzMDERdWRpZXJlc2lzLnNjLnNzMDEPdW5pMUVFNS5zYy5zczAxDnVncmF2ZS5zYy5zczAxD3VuaTFFRTcuc2Muc3MwMQ11aG9ybi5zYy5zczAxD3VuaTFFRTkuc2Muc3MwMQ91bmkxRUYxLnNjLnNzMDEPdW5pMUVFQi5zYy5zczAxD3VuaTFFRUQuc2Muc3MwMQ91bmkxRUVGLnNjLnNzMDEVdWh1bmdhcnVtbGF1dC5zYy5zczAxD3VuaTAyMTcuc2Muc3MwMQ91bWFjcm9uLnNjLnNzMDEPdW5pMUU3Qi5zYy5zczAxD3VvZ29uZWsuc2Muc3MwMQ11cmluZy5zYy5zczAxDnV0aWxkZS5zYy5zczAxD3VuaTFFNzkuc2Muc3MwMQl3LnNjLnNzMDEOd2FjdXRlLnNjLnNzMDETd2NpcmN1bWZsZXguc2Muc3MwMRF3ZGllcmVzaXMuc2Muc3MwMQ53Z3JhdmUuc2Muc3MwMQl5LnNjLnNzMDEOeWFjdXRlLnNjLnNzMDETeWNpcmN1bWZsZXguc2Muc3MwMRF5ZGllcmVzaXMuc2Muc3MwMQ91bmkxRThGLnNjLnNzMDEPdW5pMUVGNS5zYy5zczAxDnlncmF2ZS5zYy5zczAxD3VuaTFFRjcuc2Muc3MwMQ91bmkwMjMzLnNjLnNzMDEPdW5pMUVGOS5zYy5zczAxCXouc2Muc3MwMQ56YWN1dGUuc2Muc3MwMQ56Y2Fyb24uc2Muc3MwMRJ6ZG90YWNjZW50LnNjLnNzMDEPdW5pMUU5My5zYy5zczAxB3VuaTA0MTAHdW5pMDQxMQd1bmkwNDEyB3VuaTA0MTMHdW5pMDQwMwd1bmkwNDkwB3VuaTA0MTQHdW5pMDQxNQd1bmkwNDAwB3VuaTA0MDEHdW5pMDQxNgd1bmkwNDE3B3VuaTA0MTgHdW5pMDQxOQd1bmkwNDBEB3VuaTA0OEEHdW5pMDQxQQd1bmkwNDBDB3VuaTA0MUIHdW5pMDQxQwd1bmkwNDFEB3VuaTA0MUUHdW5pMDQxRgd1bmkwNDIwB3VuaTA0MjEHdW5pMDQyMgd1bmkwNDIzB3VuaTA0MEUHdW5pMDQyNAd1bmkwNDI1B3VuaTA0MjcHdW5pMDQyNgd1bmkwNDI4B3VuaTA0MjkHdW5pMDQwRgd1bmkwNDJDB3VuaTA0MkEHdW5pMDQyQgd1bmkwNDA5B3VuaTA0MEEHdW5pMDQwNQd1bmkwNDA0B3VuaTA0MkQHdW5pMDQwNgd1bmkwNDA3B3VuaTA0MDgHdW5pMDQwQgd1bmkwNDJFB3VuaTA0MkYHdW5pMDQwMgd1bmkwNDYyB3VuaTA0NkEHdW5pMDQ3Mgd1bmkwNDc0B3VuaTA0OTIHdW5pMDQ5NAd1bmkwNDk2B3VuaTA0OTgHdW5pMDQ5QQd1bmkwNDlDB3VuaTA0OUUHdW5pMDRBMAd1bmkwNEEyB3VuaTA0QTQHdW5pMDRBNgd1bmkwNTI0B3VuaTA0QTgHdW5pMDRBQQd1bmkwNEFDB3VuaTA0QUUHdW5pMDRCMAd1bmkwNEIyB3VuaTA0QjQHdW5pMDRCNgd1bmkwNEI4B3VuaTA0QkEHdW5pMDUyNgd1bmkwNEJDB3VuaTA0QkUHdW5pMDRDMAd1bmkwNEMxB3VuaTA0QzMHdW5pMDRDNwd1bmkwNEM5B3VuaTA0Q0IHdW5pMDRDRAd1bmkwNEQwB3VuaTA0RDIHdW5pMDRENAd1bmkwNEQ2B3VuaTA0RDgHdW5pMDREQQd1bmkwNERDB3VuaTA0REUHdW5pMDRFMAd1bmkwNEUyB3VuaTA0RTQHdW5pMDRFNgd1bmkwNEU4B3VuaTA0RUEHdW5pMDRFQwd1bmkwNEVFB3VuaTA0RjAHdW5pMDRGMgd1bmkwNEY0B3VuaTA0RjYHdW5pMDRGOAd1bmkwNEZBB3VuaTA0RkMHdW5pMDRGRQd1bmkwNTEwB3VuaTA1MTIHdW5pMDUxQQd1bmkwNTFDB3VuaTA0OEMHdW5pMDQ4RQd1bmkwNTI4B3VuaTA1MkUPdW5pMDQxNC5sb2NsQkdSD3VuaTA0MUIubG9jbEJHUg91bmkwNDI0LmxvY2xCR1IPdW5pMDQ5Mi5sb2NsQlNID3VuaTA0OTgubG9jbEJTSA91bmkwNEFBLmxvY2xCU0gPdW5pMDRBQS5sb2NsQ0hVDHVuaTA0MTAuc3MwMQx1bmkwNDE0LnNzMDEMdW5pMDQxNS5zczAxDHVuaTA0MDAuc3MwMQx1bmkwNDAxLnNzMDEMdW5pMDQxOC5zczAxDHVuaTA0MTkuc3MwMQx1bmkwNDhBLnNzMDEMdW5pMDQwRC5zczAxDHVuaTA0MUIuc3MwMQx1bmkwNDIwLnNzMDEMdW5pMDQyMi5zczAxDHVuaTA0MjMuc3MwMQx1bmkwNDBFLnNzMDEMdW5pMDQyNC5zczAxDHVuaTA0MkMuc3MwMQx1bmkwNDJBLnNzMDEMdW5pMDQyQi5zczAxDHVuaTA0MDkuc3MwMQx1bmkwNDBBLnNzMDEMdW5pMDQwOC5zczAxDHVuaTA0NjIuc3MwMQx1bmkwNEFDLnNzMDEMdW5pMDREMC5zczAxDHVuaTA0RDIuc3MwMQx1bmkwNEQ0LnNzMDEMdW5pMDRENi5zczAxDHVuaTA0RTIuc3MwMQx1bmkwNEU0LnNzMDEMdW5pMDRFRS5zczAxDHVuaTA0RjAuc3MwMQx1bmkwNEYyLnNzMDEMdW5pMDRGOC5zczAxDHVuaTA1MUEuc3MwMQx1bmkwNDhDLnNzMDEHdW5pMDQzMAd1bmkwNDMxB3VuaTA0MzIHdW5pMDQzMwd1bmkwNDUzB3VuaTA0OTEHdW5pMDQzNAd1bmkwNDM1B3VuaTA0NTAHdW5pMDQ1MQd1bmkwNDM2B3VuaTA0MzcHdW5pMDQzOAd1bmkwNDM5B3VuaTA0NUQHdW5pMDQ4Qgd1bmkwNDNBB3VuaTA0NUMHdW5pMDQzQgd1bmkwNDNDB3VuaTA0M0QHdW5pMDQzRQd1bmkwNDNGB3VuaTA0NDAHdW5pMDQ0MQd1bmkwNDQyB3VuaTA0NDMHdW5pMDQ1RQd1bmkwNDQ0B3VuaTA0NDUHdW5pMDQ0Nwd1bmkwNDQ2B3VuaTA0NDgHdW5pMDQ0OQd1bmkwNDVGB3VuaTA0NEMHdW5pMDQ0QQd1bmkwNDRCB3VuaTA0NTkHdW5pMDQ1QQd1bmkwNDU1B3VuaTA0NTQHdW5pMDQ0RAd1bmkwNDU2B3VuaTA0NTcHdW5pMDQ1OAd1bmkwNDVCB3VuaTA0NEUHdW5pMDQ0Rgd1bmkwNDUyB3VuaTA0NjMHdW5pMDQ2Qgd1bmkwNDczB3VuaTA0NzUHdW5pMDQ5Mwd1bmkwNDk1B3VuaTA0OTcHdW5pMDQ5OQd1bmkwNDlCB3VuaTA0OUQHdW5pMDQ5Rgd1bmkwNEExB3VuaTA0QTMHdW5pMDRBNQd1bmkwNTI1B3VuaTA0QTcHdW5pMDRBOQd1bmkwNEFCB3VuaTA0QUQHdW5pMDRBRgd1bmkwNEIxB3VuaTA0QjMHdW5pMDRCNQd1bmkwNEI3B3VuaTA0QjkHdW5pMDRCQgd1bmkwNTI3B3VuaTA0QkQHdW5pMDRCRgd1bmkwNENGB3VuaTA0QzIHdW5pMDRDNAd1bmkwNEM2B3VuaTA0QzgHdW5pMDRDQQd1bmkwNENDB3VuaTA0Q0UHdW5pMDREMQd1bmkwNEQzB3VuaTA0RDUHdW5pMDRENwd1bmkwNEQ5B3VuaTA0REIHdW5pMDRERAd1bmkwNERGB3VuaTA0RTEHdW5pMDRFMwd1bmkwNEU1B3VuaTA0RTcHdW5pMDRFOQd1bmkwNEVCB3VuaTA0RUQHdW5pMDRFRgd1bmkwNEYxB3VuaTA0RjMHdW5pMDRGNQd1bmkwNEY3B3VuaTA0RjkHdW5pMDRGQgd1bmkwNEZEB3VuaTA0RkYHdW5pMDUxMQd1bmkwNTEzB3VuaTA1MUIHdW5pMDUxRAd1bmkwNDhEB3VuaTA0OEYHdW5pMDUyOQd1bmkwNTJGD3VuaTA0MzIubG9jbEJHUg91bmkwNDMzLmxvY2xCR1IPdW5pMDQzNC5sb2NsQkdSD3VuaTA0MzYubG9jbEJHUg91bmkwNDM3LmxvY2xCR1IPdW5pMDQzOC5sb2NsQkdSD3VuaTA0MzkubG9jbEJHUg91bmkwNDVELmxvY2xCR1IPdW5pMDQzQS5sb2NsQkdSD3VuaTA0M0IubG9jbEJHUg91bmkwNDNELmxvY2xCR1IPdW5pMDQzRi5sb2NsQkdSD3VuaTA0NDIubG9jbEJHUg91bmkwNDQ3LmxvY2xCR1IPdW5pMDQ0Ni5sb2NsQkdSD3VuaTA0NDgubG9jbEJHUg91bmkwNDQ5LmxvY2xCR1IPdW5pMDQ0Qy5sb2NsQkdSD3VuaTA0NEEubG9jbEJHUg91bmkwNDRFLmxvY2xCR1IPdW5pMDQ5My5sb2NsQlNID3VuaTA0OTkubG9jbEJTSA91bmkwNEFCLmxvY2xDSFUPdW5pMDQ1My5sb2NsTUtED3VuaTA0MzEubG9jbFNSQg91bmkwNDMzLmxvY2xTUkIPdW5pMDQzNC5sb2NsU1JCD3VuaTA0M0YubG9jbFNSQg91bmkwNDQyLmxvY2xTUkIMdW5pMDQzMC5zczAxDHVuaTA0MzQuc3MwMQx1bmkwNDM1LnNzMDEMdW5pMDQ1MC5zczAxDHVuaTA0NTEuc3MwMQx1bmkwNDM4LnNzMDEMdW5pMDQzOS5zczAxDHVuaTA0OEIuc3MwMQx1bmkwNDVELnNzMDEMdW5pMDQ0MC5zczAxDHVuaTA0NDIuc3MwMQx1bmkwNDQzLnNzMDEMdW5pMDQ1RS5zczAxDHVuaTA0NEMuc3MwMQx1bmkwNDRBLnNzMDEMdW5pMDQ0Qi5zczAxDHVuaTA0NTkuc3MwMQx1bmkwNDVBLnNzMDEMdW5pMDQ2My5zczAxDHVuaTA0RDEuc3MwMQx1bmkwNEQzLnNzMDEMdW5pMDRENS5zczAxDHVuaTA0RDcuc3MwMQx1bmkwNEQ5LnNzMDEMdW5pMDREQi5zczAxDHVuaTA0RTMuc3MwMQx1bmkwNEU1LnNzMDEMdW5pMDRFRi5zczAxDHVuaTA0RjEuc3MwMQx1bmkwNEYzLnNzMDEMdW5pMDRGOS5zczAxDHVuaTA0OEQuc3MwMQd1bmkwMzk0B3VuaTAzQTkHdW5pMDNCQwd1bmkyMTJCB3VuaTIxMkEIemVyby5vc2YHb25lLm9zZgd0d28ub3NmCXRocmVlLm9zZghmb3VyLm9zZghmaXZlLm9zZgdzaXgub3NmCXNldmVuLm9zZgllaWdodC5vc2YIbmluZS5vc2YJemVyby5zaW5mCG9uZS5zaW5mCHR3by5zaW5mCnRocmVlLnNpbmYJZm91ci5zaW5mCWZpdmUuc2luZghzaXguc2luZgpzZXZlbi5zaW5mCmVpZ2h0LnNpbmYJbmluZS5zaW5mB3plcm8udGYGb25lLnRmBnR3by50Zgh0aHJlZS50Zgdmb3VyLnRmB2ZpdmUudGYGc2l4LnRmCHNldmVuLnRmCGVpZ2h0LnRmB25pbmUudGYJemVyby50b3NmCG9uZS50b3NmCHR3by50b3NmCnRocmVlLnRvc2YJZm91ci50b3NmCWZpdmUudG9zZghzaXgudG9zZgpzZXZlbi50b3NmCmVpZ2h0LnRvc2YJbmluZS50b3NmB3VuaTIwODAHdW5pMjA4MQd1bmkyMDgyB3VuaTIwODMHdW5pMjA4NAd1bmkyMDg1B3VuaTIwODYHdW5pMjA4Nwd1bmkyMDg4B3VuaTIwODkJemVyby5kbm9tCG9uZS5kbm9tCHR3by5kbm9tCnRocmVlLmRub20JZm91ci5kbm9tCWZpdmUuZG5vbQhzaXguZG5vbQpzZXZlbi5kbm9tCmVpZ2h0LmRub20JbmluZS5kbm9tCXplcm8ubnVtcghvbmUubnVtcgh0d28ubnVtcgp0aHJlZS5udW1yCWZvdXIubnVtcglmaXZlLm51bXIIc2l4Lm51bXIKc2V2ZW4ubnVtcgplaWdodC5udW1yCW5pbmUubnVtcgd1bmkyMDcwB3VuaTAwQjkHdW5pMDBCMgd1bmkwMEIzB3VuaTIwNzQHdW5pMjA3NQd1bmkyMDc2B3VuaTIwNzcHdW5pMjA3OAd1bmkyMDc5B3VuaTIxNTMHdW5pMjE1NAlvbmVlaWdodGgMdGhyZWVlaWdodGhzC2ZpdmVlaWdodGhzDHNldmVuZWlnaHRocw5iYWNrc2xhc2guY2FzZRNwZXJpb2RjZW50ZXJlZC5jYXNlC2J1bGxldC5jYXNlG3BlcmlvZGNlbnRlcmVkLmxvY2xDQVQuY2FzZQpzbGFzaC5jYXNlFnBlcmlvZGNlbnRlcmVkLmxvY2xDQVQOYnJhY2VsZWZ0LmNhc2UPYnJhY2VyaWdodC5jYXNlEGJyYWNrZXRsZWZ0LmNhc2URYnJhY2tldHJpZ2h0LmNhc2UOcGFyZW5sZWZ0LmNhc2UPcGFyZW5yaWdodC5jYXNlCmZpZ3VyZWRhc2gHdW5pMjAxNQd1bmkyMDEwB3VuaTAwQUQLZW1kYXNoLmNhc2ULZW5kYXNoLmNhc2ULaHlwaGVuLmNhc2USZ3VpbGxlbW90bGVmdC5jYXNlE2d1aWxsZW1vdHJpZ2h0LmNhc2USZ3VpbHNpbmdsbGVmdC5jYXNlE2d1aWxzaW5nbHJpZ2h0LmNhc2UJZXhjbGFtLnNjDWV4Y2xhbWRvd24uc2MQZ3VpbGxlbW90bGVmdC5zYxFndWlsbGVtb3RyaWdodC5zYxBndWlsc2luZ2xsZWZ0LnNjEWd1aWxzaW5nbHJpZ2h0LnNjCXBlcmlvZC5zYwtxdWVzdGlvbi5zYw9xdWVzdGlvbmRvd24uc2MLcXVvdGVkYmwuc2MPcXVvdGVkYmxiYXNlLnNjD3F1b3RlZGJsbGVmdC5zYxBxdW90ZWRibHJpZ2h0LnNjDHF1b3RlbGVmdC5zYw1xdW90ZXJpZ2h0LnNjEXF1b3Rlc2luZ2xiYXNlLnNjDnF1b3Rlc2luZ2xlLnNjB3VuaTI3RTgHdW5pMjdFOQd1bmkyMDA3B3VuaTIwMEEHdW5pMjAwOAd1bmkwMEEwB3VuaTIwMDkHdW5pMjAwQgd1bmkyMEI1DWNvbG9ubW9uZXRhcnkEZG9uZwRFdXJvB3VuaTIwQjIHdW5pMjBCNAd1bmkyMEFEBGxpcmEHdW5pMjBCQQd1bmkyMEJDB3VuaTIwQTYGcGVzZXRhB3VuaTIwQjEHdW5pMjBCRAd1bmkyMEI5B3VuaTIwQjgHdW5pMjBBRQd1bmkyMEE5B3VuaTIyMTkHdW5pMjA1Mgd1bmkyMjE1CGVtcHR5c2V0B3VuaTIxMjYHdW5pMjIwNgd1bmkwMEI1B2Fycm93dXAHdW5pMjE5NwphcnJvd3JpZ2h0B3VuaTIxOTgJYXJyb3dkb3duB3VuaTIxOTkJYXJyb3dsZWZ0B3VuaTIxOTYJYXJyb3dib3RoCWFycm93dXBkbgxhcnJvd3VwLmNhc2UPYXJyb3dyaWdodC5jYXNlDmFycm93ZG93bi5jYXNlDmFycm93bGVmdC5jYXNlB3VuaTI1QzYHdW5pMjVDNwlmaWxsZWRib3gHdW5pMjVBMQd0cmlhZ3VwB3VuaTI1QjYHdHJpYWdkbgd1bmkyNUMwB3VuaTI1QjMHdW5pMjVCNwd1bmkyNUJEB3VuaTI1QzEHdW5pMjExMwllc3RpbWF0ZWQHdW5pMjExNgZtaW51dGUGc2Vjb25kB2F0LmNhc2UMdW5pMjExNi5zczAxDGFtcGVyc2FuZC5zYwd1bmkwMzA4C3VuaTAzMDgwMzAwC3VuaTAzMDgwMzAxC3VuaTAzMDgwMzA0B3VuaTAzMDcLdW5pMDMwNzAzMDQJZ3JhdmVjb21iC3VuaTAzMDAwMzA0CWFjdXRlY29tYgt1bmkwMzAxMDMwNwt1bmkwMzAxMDMwNAd1bmkwMzBCDWNhcm9uY29tYi5hbHQHdW5pMDMwMgd1bmkwMzBDC3VuaTAzMEMwMzA3B3VuaTAzMDYHdW5pMDMwQQt1bmkwMzBBMDMwMQl0aWxkZWNvbWILdW5pMDMwMzAzMDgTdGlsZGVjb21iX2FjdXRlY29tYgt1bmkwMzAzMDMwNAd1bmkwMzA0C3VuaTAzMDQwMzA4C3VuaTAzMDQwMzAwC3VuaTAzMDQwMzAxDWhvb2thYm92ZWNvbWIHdW5pMDMwRgd1bmkwMzExB3VuaTAzMTIHdW5pMDMxQgxkb3RiZWxvd2NvbWIHdW5pMDMyNAd1bmkwMzI2B3VuaTAzMjcHdW5pMDMyOAd1bmkwMzJFB3VuaTAzMzEHdW5pMDMzNQd1bmkwMzM2B3VuaTAzMzcHdW5pMDMzOAx1bmkwMzA4LmNhc2UQdW5pMDMwODAzMDAuY2FzZRB1bmkwMzA4MDMwMS5jYXNlEHVuaTAzMDgwMzA0LmNhc2UMdW5pMDMwNy5jYXNlEHVuaTAzMDcwMzA0LmNhc2UOZ3JhdmVjb21iLmNhc2UQdW5pMDMwMDAzMDQuY2FzZQ5hY3V0ZWNvbWIuY2FzZRB1bmkwMzAxMDMwNy5jYXNlEHVuaTAzMDEwMzA0LmNhc2UMdW5pMDMwQi5jYXNlDHVuaTAzMDIuY2FzZQx1bmkwMzBDLmNhc2UQdW5pMDMwQzAzMDcuY2FzZQx1bmkwMzA2LmNhc2UOdGlsZGVjb21iLmNhc2UQdW5pMDMwMzAzMDguY2FzZRh0aWxkZWNvbWJfYWN1dGVjb21iLmNhc2UQdW5pMDMwMzAzMDQuY2FzZQx1bmkwMzA0LmNhc2UQdW5pMDMwNDAzMDguY2FzZRB1bmkwMzA0MDMwMC5jYXNlEHVuaTAzMDQwMzAxLmNhc2USaG9va2Fib3ZlY29tYi5jYXNlDHVuaTAzMEYuY2FzZQx1bmkwMzExLmNhc2UMdW5pMDMzNS5jYXNlDHVuaTAzMzcuY2FzZQx1bmkwMzM4LmNhc2UTdW5pMDMwNC5uYXJyb3cuY2FzZQl1bmkwMzA3LmkJdW5pMDMyOC5pEHVuaTAzMDgubG9jbFZJRVQQdW5pMDMwNy5sb2NsVklFVBJncmF2ZWNvbWIubG9jbFZJRVQSYWN1dGVjb21iLmxvY2xWSUVUEHVuaTAzMDIubG9jbFZJRVQQdW5pMDMwQy5sb2NsVklFVBB1bmkwMzA2LmxvY2xWSUVUEnRpbGRlY29tYi5sb2NsVklFVBB1bmkwMzA0LmxvY2xWSUVUFmhvb2thYm92ZWNvbWIubG9jbFZJRVQOdW5pMDMwOC5uYXJyb3cOdW5pMDMwMi5uYXJyb3cOdW5pMDMwNi5uYXJyb3cQdGlsZGVjb21iLm5hcnJvdw51bmkwMzA0Lm5hcnJvdw51bmkwMzExLm5hcnJvdxNjYXJvbmNvbWIuYWx0LnNob3J0CXVuaTAzMzUudAd1bmkwMkJDB3VuaTAyQkIHdW5pMDJCQQd1bmkwMkM5B3VuaTAyQ0IHdW5pMDJCOQd1bmkwMkJGB3VuaTAyQkUHdW5pMDJDQQd1bmkwMkNDB3VuaTAyQzgKdW5pMDMzNS5zYwp1bmkwMzM2LnNjCnVuaTAzMzguc2MLYnJldmVjb21iY3kQYnJldmVjb21iY3kuY2FzZQtkZXNjZW5kZXJjeRBkZXNjZW5kZXJjeS5jYXNlFmRlc2NlbmRlcmN5LmNhc2Uuc2hvcnQRZGVzY2VuZGVyY3kuc2hvcnQLdW5pMDMwNjAzMDELdW5pMDMwNjAzMDALdW5pMDMwNjAzMDkLdW5pMDMwNjAzMDMLdW5pMDMwMjAzMDELdW5pMDMwMjAzMDALdW5pMDMwMjAzMDkLdW5pMDMwMjAzMDMQdW5pMDMwNjAzMDEuY2FzZRB1bmkwMzA2MDMwMC5jYXNlEHVuaTAzMDYwMzA5LmNhc2UQdW5pMDMwNjAzMDMuY2FzZRB1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AAMAAAAAAAMAAwADAAMACAADAAAAAAAAAAAAGwAAAAD/9gAAAAAACAAAAAAAAAAA/+wAAAAAAAAAAAAAAAAAAAAAAAAAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/+QAAAAAAAAAAAAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/2AAAAAAAHAAAAAP/2AAD/9AAAAAAAAAAAAAAAAAAAAAAAAAAA/8cAAAAAAAAAAAAAAAAAAAAHAAAABwAAAAAAAAAAAAD//QAAAAAAAAAAAAP/9gAIAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkAAP/2AAAAAAAKAAoAAAAA//YAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/7QAAAAAAAwAAAAoAAAAKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//bAAoAAAAAAAMAAwADAAMAAwADAAAAAAAAAAAAEwAAAAD/9gAAAAAAAAAAAAD/9gAA/+wAAAAAAAAAAAAAAAAAAAAAAAAAAP+/AAAAAAAAAAAAAAAAAAAAAAAAAAcAAP/2//YAAAAN/+7/qQAAAAD/2//5/9j/3gAA//kAAAADAAAAAwAAAAMAAAAK//YACAAA/+z/9v/s//P//QAAAAcAAAADAAD/6QAAAAf/9gAHAAAAAAAAAAAAAAAA/9YAAAAAAAAAAAAAAAAAAAAAAAcAAP/2AAAAAAAAAAD/8QAAAAAAAAAA//H/2AAA/+b/9AAAAAAAAAAAAAAAAAAAAAD//QAAAAD/5wAAAAD/4gAAAAAAAAAAAAAAAAAAAAAAAP/5AAcAAAAAAAAAAAAAAAAAJgAIAAgAAAAAAAAAAAAAAAAAAP/s/+8AAAAAAAAAAAAKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIQAAAAAAHAAAAAAAAwAAAAAAAAAAAA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAsAAAAAAAAAAAAAAADAAAAAAAA/+//9wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAmAAAAAAAAAAAAAAAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/58AAAAAAAD/wQADAAMAAwAA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BiUADAYmBicANQYoBigAMQYpBioAEAYrBisAQQYsBiwAQgYuBi4AEAYvBi8AEQYwBjAAEgYxBjIAFAYzBjMAMQY0BjQAKwY1BjUALQY2BjYADAY3BjgAUQY6BjoAKwY9Bj0ATQY/Bj8ATQZDBkMATgZFBkUATgZHBkcAUwZMBk4ANQZRBlEAUQZSBlIANQZTBlMARQZUBlQANQZVBlUARQZWBlYAEAZXBlcAEwZYBlgAOwZZBlkAEwZaBloAOwZbBlsAEAZcBlwAUQZdBl0AUAZeBl4AUQZfBl8AUAZiBmIANQZkBmQANQZmBmYAEAZqBmoAEAZvBm8AEAZ5BnkAJQZ6BnoAOAZ7BnsAJQZ8BnwAMgZ9Bn0AJgZ+Bn4AOAZ/Bn8AMgaABoAAKAaBBoEAMgaCBoIAJQaEBoQAMgaFBoUANgaGBoYAMgaIBogAMgaKBosAMgaMBowAFQaNBo0ANgaQBpAAMgaRBpEAGwaUBpQAKwaVBpYANQaYBpgANQahBqIANQanBqcAAQaqBqoANQarBqsAUgatBq4ADwbKBsoAJQbLBssAMAbMBswAOgbNBs0AFgbOBs8AJQbQBtAAPQbRBtEAHgbXBtcAJQbaBtsAFAbcBtwAJQc+Bz4AEwACAAgACgAaBJgFCjDQQfBOrlTMbU6FfI8WAAEAsgAEAAAAVAQKAV4BaAGGAYYBhgGGAYYBhgGGAbQBtAG0AbQBtAG0Af4B/gH+Af4B/gH+Af4B/gH+Af4ENAIoAigCKAIoAigCKAIoA44ClgJCA6oCjAJQAmICcAJ+AowClgKgAs4C3AOOA5wDqgPcBF4EXgReBFgEWAPuBE4D9AROA/4D/gQEBFgEWARYBFgEWARwBHAEWARYBAoENAQ0BE4EWARYBFgEWAReBF4EcAABAFQASQCUAKkAwADBAMIAwwDEAMUAxgDfAOAA4QDiAOMA5ADmAOcA6ADpAOoA6wDsAO0A7gDvASsBVwFYAVkBWgFbAVwBXQGgAbABygHPAd4B4gHjAeoB7QHvAfgB/gIxAkoCTAJkArQDhQRkBGUGJAYmBicGMAY0BjUGOgY8Bj4GQAZMBk0GTgZTBlUGVwZZBmMGZQaBBoUGjQaUBpUGlgaYBqEG2AbdBz4AAgYlAAYGNgAGAAcGNAApBjUAKAY6ACkGPQAIBj8ACAZHAAMGlAApAAsB4QAZ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//YAAAAAAAAAAAAAAAAAAAAAAAD/7wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAAAAAAoAAAAA//YAAAAAAAAAAAAAAAAAAAAA//YAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/s//cAAAAAAAAAAAAAAAD/+QAAAAAAAAAAAAD/9QAA//cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//kAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//0AAP/2AAAAAAAAAAAAAAAA//sAAAAA//0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//kAAAAAAAAAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/j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ACMCmQKaAE0CmwKzACMCtAK9AG8CvgK+ACMCvwLGAG8CxwLUADoC1QLZAEMC2gLaAAYC2wLcADMC3gLeADMC3wL6AE4C+wL7AFUC/AMCACQDAwMgAFUDIQMhACQDJAMkAFUDJQMsACQDLQNEAFUDRQNGAB8DRwNfAFUDYAOCACQDgwOEAFUDhQOFACQDhgONAFUDjgOQAFcDkgOZAFcDmwOiADQDowO6ADsDuwPAAD4DwQPBAEADwgPLAEEDzAPQAFoD0QPqAE8D7QPtAFUD7gQEABQEBQQFACQEBgQGAFIEBwQOACQEDwQRAFsEEgQSAFUEEwQbAFsEHAQcAFUEHQQfAFsEIAQhACAEIgQuAFUELwQvACQEMAQ3ADQEOARUADsEVQReAEIEXwRjAFoEZARlAA0EZgRmAEYEZwRrAGsEbARsAEcEbQRvAGsEcARwAAoEcQRxAEsEcgR3AGsEeAR4AEcEeQR6AGsEewR7AAUEfAR9AGsEfgR+AAUEfwR/AAYEgASBAAoEggSCAAUEgwSDAAoEhASEAAEEhQSJAGsEigSKAAYEiwSLAGsEjASMAEcEjQSNAGsEjgSOAEwEjwSPAAUEkASQAEsEkQSSAGsEkwSTAAMElASUAAYElQSVAGsElgSWAAoElwSYAAYEmQSZAAoEmgSaAAUEmwSbAAkEnQSdAGsEngSeAAoEnwSfAEsEoASiAGsEowSjAAYEpASnAGsEqASpAAUEqgSqAAYEqwSsAAsErQStAAoErgSuAAYErwSwAAEEsQSyAGsEswS0AAIEtQS1AGsEtgS2AAoEtwS5AGsEugS6AAEEuwS7AGsEvAS+AEYEvwS/AGsEwATBAAUEwgTCAAoEwwTEAEsExQTGAGsExwTJAAUEygTKAEsEywTNAAoEzgTOAAEEzwTRAGsE0gTTAAoE1ATUAEoE1QTVAEcE1gTWAAUE1wTXAAkE2ATaAGsE2wTcAEcE3QTdAEYE3gTeAAUE3wTfAGsE4QTiAAUE4wTjAFwE5ATkAF4E5QTnAEoE6ATrAGsE7ATsAEkE7QTtAFwE7gTuAAcE7wTwAAwE8QTxAAUE8gTyAAgE8wTzAAYE9AT0AAgE9QT1AEcE9gT2AGsE9wT3AAQE+QT5AAcE+gT7AFwE/AT8AEYE/QT9AEoE/gT/AGsFAAUCAAwFBAUEAAUFBQUFAAgFBgUGAE0FBwUHAAUFCAULAGUFDAUMAEgFDQUPACMFEAUQAD8FEQURAFEFEgUXAGUFGAUYAEgFGQUaAGUFGwUbACMFHAUdAGUFHgUeACMFHwUfADUFIAUhAD0FIgUiACMFIwUjAD8FJAUkADoFJQUpAGUFKgUqADUFKwUrAGUFLAUsAEgFLQUtAGUFLgUuAC4FLwUvACMFMAUwAFEFMQUyAGUFMwUzAGQFNAU0AG0FNQU1AGUFNgU2AD8FNwU3AG8FOAU4ADUFOQU5AD8FOgU6ACMFOwU7AD0FPAU8ABkFPQU9AGUFPgU+AD8FPwU/AFEFQAVBAGUFQgVCAG8FQwVDADUFRAVHAGUFSAVJACMFSgVKADUFSwVMAD0FTQVNAD8FTgVOADUFTwVQADoFUQVSAG8FUwVUABEFVQVVAG8FVgVWAD8FVwVXAGUFWAVYAEgFWQVaAGUFWwVbADoFXAVcAGUFXQVfAE0FYAViACMFYwVjAD8FZAVlAFEFZgVnAGUFaAVqACMFawVrAFEFbAVuAD0FbwVvADoFcAVyAGUFcwV0AD8FdQV1AFYFdgV2AEgFdwV3ACMFeAV4AD0FeQV5AC8FegV6AGUFewV7AGQFfAV8AEgFfQV9ACMFfgV+AC4FfwV/ACMFgAWAAD8FgQWBAFEFggWEADoFhQWFAG8FhgWGAEgFhwWJAGUFigWOADoFjwWPADUFkAWQAG8FkQWRAGUFkgWSAFEFkwWTACMFlAWUAGUFlQWVAA8FlgWWAGUFlwWXACMFmAWZADoFmgWeACMFnwWiADoFowWjAG4FpQWnADoFqAWoABwFqQWpADoFqgWqAEgFqwWrAGUFrQWuACMFrwWvAE0FsAWxACMFswW4ADoFuQW5AC8FugW6AEYFvgW+AEYFvwW/AGsFwAXAAEQFwQXBACUFwgXCAFkFwwXDADYFxAXEABcFxQXFAFMFxgXGAEQFxwXHADAFyAXIABUFyQXJACEFygXKAEUFywXLACYFzAXMADkFzQXNADcFzgXOABgFzwXPAFQF0AXQAEQF0QXRADEF0gXSABUF0wXTACIGJAYkAA0GJQYlAA4GJgYnAB0GKAYoABIGKQYqACgGKwYrAGAGLAYsABYGLgYuACgGLwYvACkGMAYwACoGMQYyAC0GMwYzABIGNAY0ADIGNQY1ADwGNgY2AA4GNwY4AB4GOgY6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BSMAEwUkBSQAQAUlBSkAPwUrBSsAPwUtBS0APwUuBS4AGwUvBS8AGQUxBTIAPwUzBTMAPQU1BTUAPwU2BTYAEwU3BTcAPgU5BTkAEwU6BToAGQU7BTsAEQU9BT0APwU+BT4AEwVABUEAPwVCBUIAPgVEBUcAPwVIBUkAGQVLBUwAEQVNBU0AEwVPBVAAQAVRBVIAPgVVBVUAPgVWBVYAEwVXBVcAPwVZBVoAPwVbBVsAQAVcBVwAPwVdBV8ACgVgBWIAGQVjBWMAEwVmBWcAPwVoBWoAGQVsBW4AEQVvBW8AQAVwBXIAPwVzBXQAEwV3BXcAGQV4BXgAEQV6BXoAPwV7BXsAPQV9BX0AGQV+BX4AGwV/BX8AGQWABYAAEwWCBYQAQAWFBYUAPgWHBYkAPwWKBY4AQAWQBZAAPgWRBZEAPwWTBZMAGQWUBZQAPwWWBZYAPwWXBZcAGQWYBZkAQAWaBZ4AGQWfBaIAQAWlBacAQAWpBakAQAWrBasAPwWtBa4AGQWvBa8ACgWwBbEAGQWzBbgAQAW6BboAAQW+Bb4AAQXBBcEAKwXCBcIAOQXDBcMAOAXEBcQAJwXHBccANQXKBcoAPAXLBcsALAXMBcwAOgXOBc4AKAXPBc8AJgXRBdEANgYkBiQADAYlBiUAHwYmBicAKgYoBigAIgYpBioALwYrBisAIwYuBi4ALwYvBi8AMAYwBjAAMQYxBjIANAYzBjMAIgY0BjQANwY1BjUAOwY2BjYAHwY6BjoANwY9Bj0AIAY/Bj8AIAZBBkEALQZDBkMAIQZFBkUAIQZHBkcALgZMBk4AKgZSBlIAKgZUBlQAKgZWBlYALwZYBlgAMwZaBloAMwZbBlsALwZgBmAAJAZhBmEAJQZiBmIAKgZjBmMAKQZkBmQAKgZlBmUAKQZmBmYALwZoBmgAMgZqBmoALwZvBm8ALwZ5BnkAFQZ6BnoAGQZ7BnsAFQZ9Bn0AFgZ+Bn4AGQaCBoIAFQaUBpQANwaVBpYAKgaYBpgAKgahBqIAKganBqcAAQaqBqoAKgarBqsAPwbKBsoAFQbOBs8AFQbXBtcAFQbaBtsANAbcBtwAFQACAJ4ABAAAAKwAsAABAEcAAP+j//n/9AAKAB4AKAAh//YAFAAK/6j/9v/2ABQAAwAHAB4ABwAUABH/7P/5//P/2QARAA0AEf/2//0AUAAg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AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9AAA//D/8AAAAAD/7f/3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/8f/q//f/9AAA/+0AAP/s//P/9//w//cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKACUABwAA//b/9gAA/+n/+f/bAAAAAAAAAAAAHgAAAAAAFAAAAAcAAP/9//kAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwAAAAAACP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABf/9AAAABQAFAAAAAoAAAAUAAoABwAAAAAADf/2AAAAFAAAAAAAAwAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAACP/2AAAACAAAAAAAAwAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKAAoAFAAA/+z/7AAA/+L/9v/YAAoAAABkAEQAFAAKAAAACAAAAAD/9gAA//YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAEQAAAAAACAADAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/zAAD/6QAA//T/7wAA/9//1v/WAAAAEf/0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA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ABIFhQWFAAQFhwWJAAgFkAWQAAkFkgWSABIFlAWUAAsFlQWVAAkFnAWeAAEFowWjAAkFrwWwAAEFsQWxAAkGiQaJAAwAAgFrAAQAHwBMACAAIABNACEAJwAwACgARgBNAEcASABIAEkASQBNAEoAUQAwAFIAZwBNAGoAgwBNAIQApgAwAKcAqABNAKkAqQAwAKoAsQBNALIAtABOALYAvQBOAL8AvwAwAMAAxgACAMcA3gAxAN8A5AAyAOUA5QA2AOYA7wAzAPUA9QBNAPYBDwABARABEQBMARIBEwBNASsBKwABASwBMwAwATUBNQBNAUUBRgBJAUcBSABNAUoBVABNAVUBVgAwAVcBXQBKAV4BegAxAYoBpQA3AaYBpgATAacBzAAWAc4BzgAPAdAB1wAWAdgB3QATAd4B7gBCAe8B8QBBAfIB9AATAfUB9QBCAfYB/gATAf8CCwBCAgwCLgAWAi8CLwBCAjACMAATAjECMQAWAjICOQBCAjoCPABFAj4CRQBFAkYCRgATAkgCTwAjAlACZwBGAmgCbQApAm4CbgAqAm8CeAApAnkCfQArAn8CmAAWApkCmgA3ApsCswAWArQCvQATAr4CvgAWAr8CxgATAscC1ABGAtUC2QArAtoC2gACAtsC3AAjAt4C3gAjBGQEZQAEBGYEZgBMBGcEawBNBGwEbAA1BG0EbwBNBHAEcAA2BHEEcQBIBHIEdwBNBHgEeAA1BHkEegBNBHsEewAwBHwEfQBNBH4EfgAwBH8EfwACBIAEgQA2BIIEggAwBIMEgwA2BIQEhAAuBIUEiQBNBIoEigACBIsEiwBNBIwEjAA1BI0EjQBNBI4EjgBOBI8EjwAwBJAEkABIBJEEkgBNBJQElAACBJUElQBNBJYElgA2BJcEmAACBJkEmQA2BJoEmgAwBJsEmwAyBJ0EnQBNBJ4EngA2BJ8EnwBIBKAEogBNBKMEowACBKQEpwBNBKgEqQAwBKoEqgACBKsErAAzBK0ErQA2BK4ErgACBK8EsAAuBLEEsgBNBLMEtAAvBLUEtQBNBLYEtgA2BLcEuQBNBLoEugAuBLsEuwBNBLwEvgBMBL8EvwBNBMAEwQAwBMIEwgA2BMMExABIBMUExgBNBMcEyQAwBMoEygBIBMsEzQA2BM4EzgAuBM8E0QBNBNIE0wA2BNUE1QA1BNYE1gAwBNcE1wAyBNgE2gBNBNsE3AA1BN0E3QBMBN4E3gAwBN8E3wBNBOEE4gAwBOME4wABBOQE5ABHBOgE6wBNBO0E7QABBO4E7gBKBPEE8QAwBPIE8gAxBPME8wACBPQE9AAxBPUE9QA1BPYE9gBNBPcE9wBJBPkE+QBKBPoE+wABBPwE/ABMBP4E/wBNBQQFBAAwBQUFBQAxBQYFBgA3BQcFBwAwBQgFCwBCBQwFDAAOBQ0FDwAWBRAFEAAqBREFEQAPBRIFFwBCBRgFGAAOBRkFGgBCBRsFGwAWBRwFHQBCBR4FHgAWBR8FHwAkBSAFIQApBSIFIgAWBSMFIwAqBSQFJABGBSUFKQBCBSoFKgAkBSsFKwBCBSwFLAAOBS0FLQBCBS4FLgBFBS8FLwAWBTAFMAAPBTEFMgBCBTMFMwBBBTUFNQBCBTYFNgAqBTcFNwATBTgFOAAkBTkFOQAqBToFOgAWBTsFOwApBT0FPQBCBT4FPgAqBT8FPwAPBUAFQQBCBUIFQgATBUMFQwAkBUQFRwBCBUgFSQAWBUoFSgAkBUsFTAApBU0FTQAqBU4FTgAkBU8FUABGBVEFUgATBVMFVAAJBVUFVQATBVYFVgAqBVcFVwBCBVgFWAAOBVkFWgBCBVsFWwBGBVwFXABCBV0FXwA3BWAFYgAWBWMFYwAqBWQFZQAPBWYFZwBCBWgFagAWBWsFawAPBWwFbgApBW8FbwBGBXAFcgBCBXMFdAAqBXUFdQBEBXYFdgAOBXcFdwAWBXgFeAApBXkFeQAgBXoFegBCBXsFewBBBXwFfAAOBX0FfQAWBX4FfgBFBX8FfwAWBYAFgAAqBYEFgQAPBYIFhABGBYUFhQATBYYFhgAOBYcFiQBCBYoFjgBGBY8FjwAkBZAFkAATBZEFkQBCBZIFkgAPBZMFkwAWBZQFlABCBZUFlQAGBZYFlgBCBZcFlwAWBZgFmQBGBZoFngAWBZ8FogBGBaUFpwBGBagFqABLBakFqQBGBaoFqgAOBasFqwBCBa0FrgAWBa8FrwA3BbAFsQAWBbMFuABGBbkFuQAgBboFugBMBb4FvgBMBb8FvwBNBcAFwAAsBcEFwQAXBcIFwgAoBcMFwwAlBcQFxAAQBcUFxQA/BcYFxgAsBccFxwAhBcgFyAANBckFyQAUBcoFygAtBcsFywAYBcwFzAA7Bc0FzQAm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D4oPig+KCrAPig+KD4oPig+KD4oPig+KD4oKqg+KD4oPig+KD4oPig+KD4oPig+KD4oPig+KD4oPigugD4oLjguUCg4LoA+KD4oPig+KChQPigoaD4oLuA+KD4oKIA+KD4oPig+KD4oPigomD4oPigrCCiwKzg+KD4oKMgo4Cj4Pig+KD4oPigpED4oPig+KD4oPigv0D4oLUgtYC6wLZAtqD4oPigsoD4oPig+KD4oK1A+KD4oOOg+KC74Pig+KD4oPigpKD4oPig+KD4oKUA+KD4oKVg+KClwPig+KCtoPigrgCuYPigraD4oKYgrmD4oPig+KD4oPig+KD4oPig+KD4oPigvED4oLyg+KD4oOOg+KCmgKbg+KCnQPigp6CoAPigqGD4oKjAqSD4oPig+KD4oPig+KCpgPigqeCqQPig+KD4oKqg+KD4oPig+KCrAPig+KD4oPig+KD4oPig+KD4oPig+KD4oKtg+KCrwPig+KCrYPigq8D4oPigrCCsgKzg+KD4oPig+KCtQPig+KCtoPigrgCuYPigrsD4oK8g+KD4oK/gsECvgPig+KCv4LBAsKD4oPigsQD4oLFg+KD4oLHAsiCygPig+KD4oPigsuD4oPig+KD4oLNA+KD4oPig+KCzoPig+KDjoPigtAD4oPig+KD4oLRg+KD4oPig+KC0wPig+KC1ILWAteC2QLagtSC1gLrAtkC2oLUgtYC14LZAtqD4oPigtwD4oPig+KD4oLdg+KD4oPig+KC3wPig+KD4oPiguCD4oPig+KD4oLiA+KD4oPig+KC7gPig+KC44LlAuaC6APig+KD4oLpg+KD4oPig+KC6wPig+KD4oPig+KC7IPig+KD4oPig+KD4oPig+KC7gPig+KDjoPigu+D4oPigvED4oLyg+KD4oLxA+KC8oPig+KDXoMEgwMD4oPigweDCQMKg+KD4oMHgwkC9APig+KDB4MJAvWD4oPigw2DDwMDA+KDEgMNgw8DAwPigxIDDYMPAwMD4oMSAw2DDwL3A+KDEgPig+KD4oPig+KC/oPigwADAYPigxaD4oL4g+KD4oMWg+KC+IPig+KD4oPigvoD4oPig+KD4oL7g+KD4oPig+KD4oL9A+KC/oPigwADAYPig16DBIMDA+KD4oNegwSDEIPig+KDvQPigwYD4oPigweDCQMKg+KD4oMNgw8DDAPigxIDDYMPAxCD4oMSAxaD4oMTg+KD4oMWg+KDFQPig+KDFoPigxgD4oPig+KD4oMZg+KD4oPig+KD4oMbA+KDYwNkg2GD4oPigxyD4oMeA+KD4oPig+KDigPig+KD4oPig6UD4oPig2qDbANtg+KD4oNqg2wDH4Pig+KDaoNsAyED4oPig+KD4oNdA+KD4oOfA+KDoIPig+KD4oPigyKD4oPig+KD4oMig+KD4oPig+KDJAPig+KD4oPigyWD4oPig+KD4oPNg+KD4oPig+KDJwPig+KD4oPig+KD4oPig16D4oNgA+KD4oOWA+KDl4OZA+KDdoN4A28DewN8g+KD4oPig+KD4oMog+KDKgPig+KDogPig6OD4oPig0gD4oNJg0sD4oOFg+KDK4Pig+KDhYPigyuD4oPig+KD4oPig+KD4oPig+KDTgPig+KD4oPig+KD4oPig+KD4oPig+KD4oPig+KD4oONA+KD4oPigy0DjQPig+KD4oPigy6D4oMwA+KDMYPig+KDMwPig+KD4oPig+KD4oOgg+KD4oNXAzSDNgPig+KDpoOoAzeD4oPig+KD4oM5A+KD4oM6g+KDPAM9g6CD4oPig34D4oPig+KD4oM/A+KD4oPig+KDXQPig+KDnwPig6CD4oPig+KD4oPNg+KD4oNAg+KDQgPig+KDQ4Pig0UD4oPig5YD4oOXg5kD4oOWA+KDRoOZA+KD4oPig+KD4oPig6ID4oOjg+KD4oNIA+KDSYNLA+KD4oPig+KDTIPig+KD4oPig0yD4oPig+KD4oPig+KD4oPig04D4oPig+KD4oNPg+KD4oOag+KDWINRA1KDVAPig1WD4oPig1QD4oNVg+KD4oNXA+KDWINaA1uD4oPig10D4oPig+KD4oPig+KD4oOWA+KDl4OZA+KDXoPig2AD4oPig2MDZINhg+KD4oNjA2SDZgPig+KDZ4Pig2kD4oPig2qDbANtg+KD4oN2g3CDbwPig+KDdoNwg3mD4oPig+KD4oNyA+KD4oOfA+KDgQPig+KD4oPig3OD4oPig+KD4oN1A+KD4oN2g3gDeYN7A3yD4oPig34D4oPig+KD4oN/g+KD4oPig+KDgQPig+KDhYPig4KD4oPig4WD4oOEA+KD4oOFg+KDhwPig+KD4oPig4iD4oPig+KD4oOKA+KD4oPig+KDi4ONA+KD4oPig+KD4oPig46D4oOQA+KD4oORg+KDkwPig+KD4oPig+KD4oPig+KD4oOxA+KD4oPVA9aDtYPig9mD1QPWg7WD4oPZg9UD1oO4g+KD2YPig+KDlIPig+KDlgPig5eDmQPig5qD4oOcA+KD4oO9A+KD4oPig+KD4oPig+KD4oPig9UD1oO1g+KD2YPig+KDnYPig+KD4oPig52D4oPig58D4oOgg+KD4oOiA+KDo4Pig+KD4oPig6UD4oPig6aDqAOpg+KD4oPig+KDtYPig+KDqwOsg9sD4oOuA+KD4oOvg+KD4oPDA8SDwYPig+KD4oPig7ED4oPig8kDyoPMA+KD4oPJA8qDsoPig+KDyQPKg7QD4oPig9UD1oO1g+KD2YPVA9aDtYPig9mD1QPWg7cD4oPZg9UD1oO4g+KD2YO6A+KDu4Pig+KDvQPig+KD4oPig94D4oO+g+KD4oPeA+KDvoPig+KD4oPig8AD4oPig8MDxIPBg+KD4oPDA8SDxgPig+KD4oPig8eD4oPig8kDyoPMA+KD4oPPA9CDzYPig+KDzwPQg9ID4oPig9UD1oPTg+KD2YPVA9aD2APig9mD3gPig9sD4oPig94D4oPcg+KD4oPeA+KD34Pig+KD4oPig+ED4oPigABAX0AAAABAUoDUwABAWUDUwABAWUDOQABAZoDUwABAZoCvAABAWcDUwABAfICvAABAogCSgABAUoAAAABAYMAAAABAUACvAABANAAAAABAJsAAAABAM0AAAABAJsDOQABAQoCvAABAWcCvAABAX0CvAABAfAAAAABAfACvQABA0QCvAABAS8CvAABAS8BUwABAU4AAAABAU4CvAABAUsA+QABAUQAAAABAUQCvAABAUEA+QABAS4AAAABAS4CvAABAS4BUwABAVUCvAABAVQCvAABAlUAAAABAk8CvwABAJ8AAAABANEAAAABAJ8CvAABAgQCvAABAZkAAAABAZkCvAABAZkCKQABAeEAAAABAeECvAABAXsCvAABAXsAAAABAuoAAAABAXsDOQABAhwAAAABAhwCvAABAW8AAAABAmkAAAABAWUCvAABAZ0CvAABAZ0DOQABAgQDOQABAT8DOQABAZoDNQABAZoDOQABAagAAAABAfUAAAABAagDOQABAagBXgABAoECvAABAUADOQABAVQDNQABAVQDOQABAVQDUwABAVUDOQABA0MAAAABA3QAAAABAfIDOQABAK4CSgABAWYCvAABAagCvAABAMcCSgABAUoCvAABAT8CvAABAZYAAAABAZ8CvAABAV4DUwABAV4DOQABAY8DUwABAYoCvAABAfECvAABAOwCvAABAQ4CSgABATwAAAABAT4CvAABATsBSgABAY8CvAABAr0AAAABAhQCvAABAV4AAAABAlEAAAABAV4CvAABAY8DNQABAYgAAAABArEAAAABAY8DOQABAo4CvAABAYoDNQABAYoDOQABApcAAAABAYoDUwABAfEDOQABAMMCSgABATgAAAABATgCEwABATUCvQABATUCowABAVUCEgABAVUCvQABAVUCswABATQCvQABAYIAAAABAW4CEgABARACEgABAaACEgABAgEBugABAQsAAAABAQsCEgABATkAAAABAL0AAAABAI0CxQABAIsCowABAI4CxQABAVsAAAABAJAC5gABAMMCeQABATMCEAABAUEAAAABAUECEgABAYoAAAABAYoCEgABArECEAABAPgAAAABAPgCEgABAPgA/AABAR4ABQABARQCEgABARMCEgABAMgCegABAQQCEgABAdAAAAABAcoCEAABAI0AAAABAI0C5gABAI0BZgABARYC5gABAagCEgABAY8AAAABAY8CEgABASECEgABAR8AAAABAf0AAAABASECowABAdkAAAABAc0CEgABATUAAAABAgkAAAABATUCEgABAT8CEgABAGsCEgABAagCowABAVUCnwABAVUCowABAT8AAAABAaIAAAABAT8CowABAT8BCQABAcgCEgABAUUCEgABAUUCowABAQcCowABARACnwABARACowABAaAAAAABARACvQABARQCowABASMCEAABAaACowABAJoBugABAS8AAAABAUICEgABAdQAAAABAdQCEgABATECEgABAVIAAAABAVICEgABAVIBpgABAVkAAAABAVkCEgABAgYCEAABAPsAAAABAQcCEgABAToAAAABAS4CEgABASMCuwABAIsAAAABALsAAAABAIsCnwABAVAAAAABAkkAAAABAhoCEgABAgYCnQABAUgCEgABATACvQABATACowABAUYCEgABAUYCswABAUYCvQABAWkAAAABAVYCEgABAhQAAAABAVACEgABAZUCEgABAU8CEgABAU8AAAABAk8AAAABAU8CowABAeUCEgABATAAAAABAb0AAAABATACEgABATQCEgABATQAAAABAKcCEgABATQCowABAUYCnwABAUcAAAABAkAAAAABAUYCowABAhECEgABAVACnwABAVACowABApUAAAABAVACvQABAZUCowABAAAAAAAJAAAAAQAIAAEABAAAA7wABgEAAAEACAABAAwAHAABACoASgABAAYG/wcABwEHAgcEBwUAAQAFBv8HAAcBBwQHBQAGAAAAGgAAABoAAAAaAAAAGgAAABoAAAAaAAH+1AAAAAUAEgAMABIAGAAeAAH+1P9qAAH+1P9vAAH+1P9jAAH+1P9yAAYCAAABAAgAAQF6AAwAAQGgAEAAAgAIBt8G6gAABuwG/QAMBwoHJAAeB0AHQQA5B0UHRQA7B0gHSgA8B0wHUQA/B1MHVABFAEcAkACuAK4ArgKSAJYAugCuALoAnACuALoAwADAAsAAwACiAKIAwACuAK4ArgCoAK4ArgCuALQAugDAAMYAzADqAOoA6gDSANgA9gDqAPYA3gDqAPYA/AD8At4A/AD8AOoA6gDqAOQA6gDqAOoA8AD2APwBFAEOAQ4BDgEgASABIAECAQgBDgEOARQBGgEgAAH+1AKjAAH+1AMwAAH+1AMxAAH+1AL9AAH+1AKfAAH+1AMtAAH+1AMDAAH+1AK9AAH+1AKzAAH+1ALfAAH+1AM5AAH+1ANSAAH+1APGAAH+1APHAAH+1AM1AAH+1APDAAH+1AOZAAH+1ANTAAH+1ANJAAEBLAKjAAEBLAK8AAEBLAK9AAEBLAKfAAEBLAL9AAEBLAKzAAYCAAABAAgAAQAMACgAAQAyAWoAAgAEBt8G6gAABuwG/QAMBwoHJAAeB14HbQA5AAIAAQdeB20AAABJAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABMgAAATIAAAEyAAABMgAAATIAAAEyAAABMgAAATIAAAEyAAABMgAAATIAAAEyAAABMgAAATIAAAEyAAABMgAAATIAAAEyAAABMgAAATIAAAEyAAABJgAAATIAAAEyAAABMgAAATIAAAEyAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEyAAABMgAAATIAAAEyAAABMgAAATIAAAEyAAABMgAB/tQCuwAB/tQCEgAB/tQCvAAQACgAKAAiACgALgAuADQAOgBGAEYAQABGAEwATABSAFgAAf7UAyUAAf7UAxoAAf98AvcAAf9WAwsAAf7UAyAAAf7UA7sAAf7UA7AAAf98A40AAf9WA6EAAf7UA7YAAQAMACIABQEKAq4AAgADBt8G6gAABuwHJwAMB14HbQBIAAIAJgAEAEgAAABKAH8ARQCBAKYAewCpALQAoQC2AL0ArQC/ANoAtQDcAN4A0QDgAOQA1ADmAPQA2QD2ASoA6AEsATYBHQE4AVABKAFSAVQBQQFWAaUBRAGnAa4BlAGwAc4BnAHQAdYBuwHYAgcBwgIJAjwB8gI+AkUCJgJIAm0CLgJvAn0CVAJ/ArMCYwK1AtkCmALfAyMCvQMlAzUDAgM3A1sDEwNdA4IDOAOFA5ADXgOSA5kDagObA7YDcgO4A7oDjgO8A8ADkQPCBAUDlgQHBBED2gQTBCoD5QQsBC4D/QQwBGMEAABYAAIBmAACAZgAAgGYAAIBmAACAZgAAgGYAAIBmAACAZgAAgGYAAIBmAACAZgAAgGYAAIBmAACAZgAAgGYAAIBmAACAZgAAgGYAAIBmAACAZgAAgGYAAIBmAACAZgAAgGYAAIBmAACAZgAAgGYAAIBmAACAZgAAgGYAAQBmAAAAWgAAAFoAAABaAAAAWgAAQFiAAABaAAAAWgAAwFuAAMBdAADAYwAAwF6AAIBngACAZ4AAgGeAAIBngACAZ4AAgGeAAIBngACAZ4AAgGeAAIBngACAZ4AAgGeAAIBngACAZ4AAgGeAAIBngACAZ4AAgGeAAIBngACAZ4AAgGeAAIBgAACAZ4AAgGeAAIBngACAZ4AAgGeAAMBhgADAYwAAwGSAAIBmAACAZgAAgGYAAIBmAACAZgAAgGYAAIBmAACAZgAAgGeAAIBngACAZ4AAgGeAAIBngACAZ4AAgGeAAIBngAB/tUAAAAB/tQAAAAB/tQBtgAB/kwBtgAB/soBCgAB/tQCuwAB/tQBZAAB/ycBggAB/mMBXgAB/tQCEgAB/tQCvAQ0KlIqWCpGPJQ8lCpSKlgqNDyUPJQqUipYKl48lDyUKlIqWCoQPJQ8lCouKlgqXjyUPJQqUipYKhA8lDyUKlIqWCoKPJQ8lCpSKlgqEDyUPJQqUipYKl48lDyUKlIqWCpePJQ8lCpSKlgqFjyUPJQqLipYKl48lDyUKlIqWCoWPJQ8lCpSKlgqHDyUPJQqUipYKiI8lDyUKlIqWCo0PJQ8lCpSKlgqKDyUPJQqLipYKkY8lDyUKlIqWCo0PJQ8lCpSKlgqOjyUPJQqUipYKl48lDyUKlIqWCpAPJQ8lCpSKlgqRjyUPJQqUipYKkw8lDyUKlIqWCpMPJQ8lCpSKlgqXjyUPJQuWjyULlQ8lDyULlo8lC5gPJQ8lCpkPJQqajyUPJQqgjyUKnA8lDyUKoI8lCp2PJQ8lCqCPJQqfDyUPJQqgjyUKnA8lDyUKoI8lCp2PJQ8lCqCPJQqfDyUPJQqgjyUKog8lDyUM0w8lCrQLn48lCqOPJQqlC5+PJQqmjyUKqAqpjyUM0w8lCqsLn48lCqyPJQquCq+PJQqxDyUKtAufjyUKso8lCrQLn48lCrWPJQq3C5+PJQrHiskKxg8lDyUKx4rJDjaPJQ8lCseKyQrKjyUPJQrHiskKyo8lDyUKx4rJCsqPJQ8lCseKyQrKjyUPJQrHiskKuI8lDyUKwArJCsqPJQ8lCseKyQq4jyUPJQrHiskKug8lDyUKx4rJCruPJQ8lCseKyQ42jyUPJQrHiskKvQ8lDyUKx4rJCr6PJQ8lCsAKyQrGDyUPJQrHiskONo8lDyUKx4rJCsGPJQ8lCseKyQrKjyUPJQrHiskKww8lDyUKx4rJCsSPJQ8lCseKyQrEjyUPJQrHiskKxg8lDyUKx4rJCsqPJQ8lCs2PJQrMDyUPJQrNjyUKzw8lDyULDg8lC72PJQ8lCw4PJQu2DyUPJQsODyULtg8lDyULDg8lC7YPJQ8lCwgPJQu9jyUPJQsODyULuQ8lDyULDg8lC7qPJQ8lCw4PJQu9jyUPJQsODyULDIrWjyUK0I8lCtIK048lCtUPJQsMitaPJQsODyULD4rWjyULDg8lCw+K1o8lCwgPJQsMitaPJQriiuQK948lDyUPJQ8lCtgPJQ8lCuKK5ArxjyUPJQriiuQK5Y8lDyUK4orkCuWPJQ8lCuKK5ArxjyUPJQriiuQK2Y8lDyUK4orkCtsPJQ8lCuKK5ArcjyUPJQreCuQK948lDyUK4orkCvGPJQ8lCuKK5ArfjyUPJQriiuQK5Y8lDyUK4orkCuEPJQ8lCuKK5Ar3jyUPJQriiuQK5Y8lDyUPJQ8lCucPJQ8lDyUPJQrojyUPJQrqDyUK7o8lDyUK6g8lCuuPJQ8lCu0PJQrujyUPJQvUDyUK94vXC9iL1A8lCvAL1wvYi9QPJQrxi9cL2IvUDyUK94vXC9iK8w8lCveL1wvYi9QPJQr3i9cL2IrzDyUK94vXC9iL1A8lCvSL1wvYivYPJQr3i9cL2Ir5DyUK+or8Cv2K/w8lCwIPJQ8lCwCPJQsCDyUPJQsODyULDI8lDyULDg8lCwOPJQ8lCw4PJQsFDyUPJQsODyULD48lDyULCA8lCwyPJQ8lCw4PJQsGjyUPJQsIDyULDI8lDyULDg8lCwmPJQ8lCwsPJQsMjyUPJQsODyULD48lDyULIAshiyqLJIsmCyALIYsdCySLJgsgCyGLHoskiyYLIAshix6LJIsmCyALIYsRCySLJgsYiyGLHoskiyYLIAshixELJIsmCyALIYsSiySLJgsgCyGLFAskiyYLIAshix0LJIsmCyALIYsViySLJgsgCyGLIwskiyYLIAshixcLJIsmCxiLIYsqiySLJgsgCyGLHQskiyYLIAshixoLJIsmCyAPJQsqjyUPJQsgDyULHQ8lDyULGI8lCyqPJQ8lCyAPJQsdDyUPJQsgDyULGg8lDyULIA8lCx6PJQ8lCyALIYsdCySLJgsgCyGLHoskiyYLIAshixuLJIsmCyALIYsjCySLJgsgCyGLIwskiyYPJQ8lCyqPJQ8lCyALIYsqiySLJgsgCyGLHQskiyYLIAshix6LJIsmCyALIYsjCySLJgsgCyGLIwskiyYLIAshiyMLJIsmCyePJQspDyUPJQ8lDyULKo8lDyULLw8lCzOPJQ8lCy8PJQssDyUPJQsvDyULMI8lDyULLY8lCzOPJQ8lCy8PJQssDyUPJQstjyULM48lDyULLw8lCzCPJQ8lCzIPJQszjyUPJQs7DyULPI8lDyULOw8lCzUPJQ8lCzsPJQs2jyUPJQs7DyULOY8lDyULOw8lCzgPJQ8lCzsPJQs8jyUPJQs7DyULOY8lDyULPg8lCzyPJQ8lCzsPJQs/jyUPJQs+DyULPI8lDyULPg8lCz+PJQ8lDhEPJQtBDyUPJQtEDyULSItKDyULRA8lC0iLSg8lC0QPJQtCi0oPJQtEDyULSItKDyULRY8lC0iLSg8lC0WPJQtIi0oPJQtHDyULSItKDyULWQtai06PJQtdi1kLWotRjyULXYtZC1qLV48lC12LWQtai1ePJQtdi1kLWotXjyULXYtZC1qLUY8lC12LWQtai0uPJQtdi00LWotOjyULXYtZC1qLUY8lC12LWQtai1APJQtdi1kLWotOjyULXYtZC1qLUY8lC12LTQtai06PJQtdi1kLWotRjyULXYtZC1qLUA8lC12LWQtai1ePJQtdi1kLWotRjyULXYtZC1qLV48lC12LWQtai1MPJQtdi1kLWotUjyULXYtZC1qLVg8lC12LWQtai1ePJQtdi1kLWotcDyULXYtjjyULXw8lDyULY48lC2UPJQ8lC2OPJQtgjyUPJQtjjyULYg8lDyULY48lC2UPJQ8lC3EPJQtrC3QPJQtxDyULbIt0DyULcQ8lC3KLdA8lC3EPJQtmi3QPJQtxDyULaAt0DyULaY8lC2sLdA8lC3EPJQtsi3QPJQtxDyULbgt0DyULcQ8lC2+LdA8lC3EPJQtyi3QPJQt4jyULfQ8lDyULeI8lC3WPJQ8lC3iPJQt3DyUPJQt4jyULeg8lDyULe48lC30PJQ8lC5CLkguNjyUPJQuQi5ILiQ8lDyULkIuSC5OPJQ8lC5CLkguADyUPJQuHi5ILk48lDyULkIuSC4APJQ8lC5CLkgt+jyUPJQuQi5ILgA8lDyULkIuSC5OPJQ8lC5CLkguTjyUPJQuQi5ILgY8lDyULh4uSC5OPJQ8lC5CLkguBjyUPJQuQi5ILgw8lDyULkIuSC4SPJQ8lC5CLkguJDyUPJQuQi5ILhg8lDyULh4uSC42PJQ8lC5CLkguJDyUPJQuQi5ILio8lDyULkIuSC5OPJQ8lC5CLkguMDyUPJQuQi5ILjY8lDyULkIuSC48PJQ8lC5CLkguPDyUPJQuQi5ILk48lDyULlo8lC5UPJQ8lC5aPJQuYDyUPJQuZjyULmwufjyULnI8lC54Ln48lC7GLswuwDyUPJQuxi7MLqg8lDyULsYuzC7SPJQ8lC7GLswu0jyUPJQuxi7MLtI8lDyULsYuzC7SPJQ8lC7GLswuhDyUPJQuoi7MLtI8lDyULsYuzC6EPJQ8lC7GLswuijyUPJQuxi7MLpA8lDyULsYuzC6oPJQ8lC7GLswuljyUPJQuxi7MLpw8lDyULqIuzC7APJQ8lC7GLswuqDyUPJQuxi7MLq48lDyULsYuzC7SPJQ8lC7GLswutDyUPJQuxi7MLro8lDyULsYuzC66PJQ8lC7GPJQuwDyUPJQuxi7MLtI8lDyULvA8lC72PJQ8lC7wPJQu2DyUPJQu8DyULtg8lDyULvA8lC7YPJQ8lC7ePJQu9jyUPJQu8DyULuQ8lDyULvA8lC7qPJQ8lC7wPJQu9jyUPJQvMi84Lyw8lDyUPJQ8lC78PJQ8lC8yLzgvGjyUPJQvMi84Lz48lDyULzIvOC8+PJQ8lC8yLzgvGjyUPJQvMi84LwI8lDyULzIvOC8IPJQ8lC8yLzgvDjyUPJQvFC84Lyw8lDyULzIvOC8aPJQ8lC8yLzgvIDyUPJQvMi84Lz48lDyULzIvOC8mPJQ8lC8yLzgvLDyUPJQvMi84Lz48lDyUPJQ8lC9EPJQ8lDyUPJQvSjyUPJQvUDyUL1YvXC9iL2g8lC90PJQ8lC9uPJQvdDyUPJQvpDyUL548lDyUL6Q8lC96PJQ8lC+kPJQvgDyUPJQvpDyUL6o8lDyUL4w8lC+ePJQ8lC+kPJQvhjyUPJQvjDyUL548lDyUL6Q8lC+SPJQ8lC+YPJQvnjyUPJQvpDyUL6o8lDyUL7A8lC+2PJQ8lDNYPJQvzi/UPJQzWDyUL84v1DyUM1g8lC+8L9Q8lDNYPJQvzi/UPJQvwjyUL84v1DyUL8I8lC/OL9Q8lC/IPJQvzi/UPJQwEDAWL/48lDAiMBAwFi/sPJQwIjAQMBYwCjyUMCIwEDAWMAo8lDAiMBAwFjAKPJQwIjAQMBYv7DyUMCIwEDAWL9o8lDAiL+AwFi/+PJQwIjAQMBYv7DyUMCIwEDAWL+Y8lDAiMBAwFi/+PJQwIjAQMBYv7DyUMCIv4DAWL/48lDAiMBAwFi/sPJQwIjAQMBYv5jyUMCIwEDAWMAo8lDAiMBAwFi/sPJQwIjAQMBYwCjyUMCIwEDAWL/I8lDAiMBAwFi/4PJQwIjAQMBYv/jyUMCIwEDAWMAQ8lDAiMBAwFjAKPJQwIjAQMBYwHDyUMCIwOjyUMCg8lDyUMDo8lDBAPJQ8lDA6PJQwLjyUPJQwOjyUMDQ8lDyUMDo8lDBAPJQ8lDBwPJQwWDyUPJQwcDyUMF48lDyUMHA8lDB2PJQ8lDBwPJQwRjyUPJQwcDyUMEw8lDyUMFI8lDBYPJQ8lDBwPJQwXjyUPJQwcDyUMGQ8lDyUMHA8lDBqPJQ8lDBwPJQwdjyUPJQ6SDyUMI48lDyUOkg8lDB8PJQ8lDpIPJQwgjyUPJQ6SDyUMIg8lDyUOiQ8lDCOPJQ8lDnoMNYwyjyUPJQ56DDWMLg8lDyUOegw1jDcPJQ8lDnoMNYwmjyUPJQ59DDWMNw8lDyUOegw1jCaPJQ8lDnoMNYwlDyUPJQ56DDWMJo8lDyUOegw1jDcPJQ8lDnoMNYw3DyUPJQ56DDWMKA8lDyUOfQw1jDcPJQ8lDnoMNYwoDyUPJQ56DDWMKY8lDyUOegw1jCsPJQ8lDnoMNYwuDyUPJQ56DDWMLI8lDyUOfQw1jDKPJQ8lDnoMNYwuDyUPJQ56DDWML48lDyUOegw1jDcPJQ8lDnoMNYwxDyUPJQ56DDWMMo8lDyUOegw1jDQPJQ8lDnoMNYw0DyUPJQ56DDWMNw8lDyUMOg8lDDiPJQ8lDDoPJQw7jyUPJQxBjyUMPQ8lDyUMQY8lDD6PJQ8lDEGPJQxADyUPJQxBjyUMPQ8lDyUMQY8lDD6PJQ8lDEGPJQxADyUPJQxBjyUMQw8lDyUMRI8lDyUNQ41FDESPJQ8lDUONRQxEjyUPJQ1DjUUMRg8lDyUNQ41FDEePJQ8lDUONRQxJDyUMSo1DjUUO1AxeDFOPJQ8lDtQMXgxVDyUPJQ7UDF4MX48lDyUO1AxeDF+PJQ8lDtQMXgxfjyUPJQ7UDF4MX48lDyUO1AxeDEwPJQ8lDgUMXgxfjyUPJQ7UDF4MTA8lDyUO1AxeDE2PJQ8lDtQMXgxPDyUPJQ7UDF4MVQ8lDyUO1AxeDFCPJQ8lDtQMXgxSDyUPJQ4FDF4MU48lDyUO1AxeDFUPJQ8lDtQMXgxWjyUPJQ7UDF4MX48lDyUO1AxeDFgPJQ8lDtQMXgxZjyUPJQ7UDF4MWY8lDyUMWw8lDFyPJQ8lDtQMXgxfjyUPJQxhDGKMZA8lDyUMZw8lDGWPJQ8lDGcPJQxojyUPJQ8lDyUMag8lDyUPJQ8lDGuPJQ8lDyUPJQxrjyUPJQ8lDyUMa48lDyUPJQ8lDG0PJQ8lDyUPJQxujyUPJQ8lDyUMcA8lDyUOkg8lDWkMdIx2DpIPJQ1pDHSMdgxxjyUNaQx0jHYOkg8lDIyMdIx2DpIPJQxzDHSMdg6JDyUNaQx0jHYM3AyDjIIPJQ8lDNwMg4x3jyUPJQzcDIOMfY8lDyUM3AyDjIUPJQ8lDNwMg4yFDyUPJQzcDIOMfY8lDyUM3AyDjHkPJQ8lDNwMg4x6jyUPJQzcDIOMfA8lDyUM2oyDjIIPJQ8lDNwMg4x9jyUPJQzcDIOMfw8lDyUM3AyDjIUPJQ8lDNwMg4ySjyUPJQzcDIOMgI8lDyUM3AyDjIIPJQ8lDNwMg4yFDyUPJQ8lDyUMho8lDyUPJQ8lDIgPJQ8lDyUPJQyJjyUPJQyLDyUNaQ8lDI+Miw8lDIyPJQyPjI4PJQ1pDyUMj44LDyUMkQ8lDyUM3A8lDWkNaoyUDNwPJQ1hjWqMlAzcDyUNaQ1qjJQM2o8lDWkNaoyUDNwPJQ1pDWqMlAzajyUNaQ1qjJQM3A8lDJKNaoyUDN8PJQ1pDWqMlAyVjyUMlwyYjJoMm48lDyUPJQ8lDJ0PJQ8lDyUPJQ6SDyUMp48lDyUOkg8lDJ6PJQ8lDKAPJQyhjyUPJQ6SDyUMqQ8lDyUOiQ8lDKePJQ8lDpIPJQyjDyUPJQ6JDyUMp48lDyUOkg8lDKSPJQ8lDKYPJQynjyUPJQ6SDyUMqQ8lDyUMxYzHDL4MygzLjMWMxwy7DMoMy4zFjMcMxAzKDMuMxYzHDMQMygzLjMWMxwyqjMoMy4yyDMcMxAzKDMuMxYzHDKqMygzLjMWMxwysDMoMy4zFjMcMrYzKDMuMxYzHDLsMygzLjMWMxwyvDMoMy4zFjMcMyIzKDMuMxYzHDLCMygzLjLIMxwy+DMoMy4zFjMcMuwzKDMuMxYzHDLOMygzLjLmPJQzXjyUPJQy5jyUMto8lDyUMtQ8lDNePJQ8lDLmPJQy2jyUPJQy5jyUMuA8lDyUMuY8lDMQPJQ8lDMWMxwy7DMoMy4zFjMcMxAzKDMuMxYzHDLyMygzLjMWMxwzIjMoMy4zFjMcMyIzKDMuMxY8lDL4Mygy/jMWMxwzBDMoMy4zFjMcMwozKDMuMxYzHDMQMygzLjMWMxwzIjMoMy4zFjMcMyIzKDMuMxYzHDMiMygzLjM0PJQzOjyUPJQzQDyUM0Y8lDyUM0w8lDNSPJQ8lDNYPJQzXjyUPJQzcDyUM4I8lDyUM3A8lDNkPJQ8lDNwPJQzdjyUPJQzajyUM4I8lDyUM3A8lDNkPJQ8lDNqPJQzgjyUPJQzcDyUM3Y8lDyUM3w8lDOCPJQ8lDOgPJQzpjyUPJQzoDyUM4g8lDyUM6A8lDOOPJQ8lDOgPJQzmjyUPJQzoDyUM5Q8lDyUM6A8lDOmPJQ8lDOgPJQzmjyUPJQzrDyUM6Y8lDyUM6A8lDOyPJQ8lDOsPJQzpjyUPJQzrDyUM7I8lDyUM9A8lDPoM+4z9DO4PJQzvjPEM8oz0DyUM+gz7jP0M9A8lDPoM+4z9DPcPJQz6DPuM/Qz0DyUM9Yz7jP0M9w8lDPoM+4z9DPiPJQz6DPuM/Q23DQGNig8lDQSNtw0BjYuPJQ0EjbcNAY2RjyUNBI23DQGNkY8lDQSNtw0BjZGPJQ0EjbcNAY2LjyUNBI23DQGNhw8lDQSM/o0BjYoPJQ0EjbcNAY2LjyUNBI23DQGNjQ8lDQSNtw0BjYoPJQ0EjbcNAY2LjyUNBIz+jQGNig8lDQSNtw0BjYuPJQ0EjbcNAY2NDyUNBI23DQGNkY8lDQSNtw0BjYuPJQ0EjbcNAY2RjyUNBI23DQGNjo8lDQSNtw0BjQMPJQ0EjbcNAY2KDyUNBI23DQGNAA8lDQSNtw0BjZGPJQ0EjbcNAY0DDyUNBI0GDyUNB48lDyUNDY8lDQkPJQ8lDQ2PJQ0PDyUPJQ0NjyUNCo8lDyUNDY8lDQwPJQ8lDQ2PJQ0PDyUPJQ0bDyUNFQ8lDyUNGw8lDRaPJQ8lDRsPJQ0cjyUPJQ0bDyUNEI8lDyUNGw8lDRIPJQ8lDROPJQ0VDyUPJQ0bDyUNFo8lDyUNGw8lDRgPJQ8lDRsPJQ0ZjyUPJQ0bDyUNHI8lDyUNIQ8lDSWPJQ8lDSEPJQ0eDyUPJQ0hDyUNH48lDyUNIQ8lDSKPJQ8lDSQPJQ0ljyUPJQ05DTqNNg8lDyUNOQ06jTGPJQ8lDTkNOo08DyUPJQ05DTqNKI8lDyUNMA06jTwPJQ8lDTkNOo0ojyUPJQ05DTqNJw8lDyUNOQ06jSiPJQ8lDTkNOo08DyUPJQ05DTqNPA8lDyUNOQ06jSoPJQ8lDTANOo08DyUPJQ05DTqNKg8lDyUNOQ06jSuPJQ8lDTkNOo0tDyUPJQ05DTqNMY8lDyUNOQ06jS6PJQ8lDTANOo02DyUPJQ05DTqNMY8lDyUNOQ06jTMPJQ8lDTkNOo08DyUPJQ05DTqNNI8lDyUNOQ06jTYPJQ8lDTkNOo03jyUPJQ05DTqNN48lDyUNOQ06jTwPJQ8lDyUPJQ09jyUPJQ8lDyUNPw8lDyUNQI8lDUINQ41FDViNWg1PjyUPJQ1YjVoNUQ8lDyUNWI1aDVuPJQ8lDViNWg1bjyUPJQ1YjVoNW48lDyUNWI1aDVuPJQ8lDViNWg1GjyUPJQ1ODVoNW48lDyUNWI1aDUaPJQ8lDViNWg1IDyUPJQ1YjVoNSY8lDyUNWI1aDVEPJQ8lDViNWg1LDyUPJQ1YjVoNTI8lDyUNTg1aDU+PJQ8lDViNWg1RDyUPJQ1YjVoNUo8lDyUNWI1aDVuPJQ8lDViNWg1UDyUPJQ1YjVoNVY8lDyUNWI1aDVWPJQ8lDdmPJQ1XDyUPJQ1YjVoNW48lDyUNXQ1ejWAPJQ8lDWePJQ1pDWqNc41njyUNYY1qjXONZ48lDWkNao1zjWMPJQ1pDWqNc41njyUNaQ1qjXONYw8lDWkNao1zjWePJQ1kjWqNc41mDyUNaQ1qjXONZ48lDWkNao1zjWwPJQ1tjyUPJQ11DyUNew18jX4Nbw8lDXCNcg1zjXUPJQ17DXyNfg11DyUNew18jX4NeA8lDXsNfI1+DXUPJQ12jXyNfg14DyUNew18jX4NeY8lDXsNfI1+DYQPJQ1/jyUPJQ2EDyUNhY8lDyUNhA8lDYEPJQ8lDYQPJQ2CjyUPJQ2EDyUNhY8lDyUNkA8lDYoPJQ8lDZAPJQ2LjyUPJQ2QDyUNkY8lDyUNkA8lDYcPJQ8lDYiPJQ2KDyUPJQ2QDyUNi48lDyUNkA8lDY0PJQ8lDZAPJQ2OjyUPJQ2QDyUNkY8lDyUNlg8lDZqPJQ8lDZYPJQ2TDyUPJQ2WDyUNlI8lDyUNlg8lDZePJQ8lDZkPJQ2ajyUPJQ7UDayNqY8lDyUO1A2sjaUPJQ8lDtQNrI2uDyUPJQ7UDayNnY8lDyUOBQ2sja4PJQ8lDtQNrI2djyUPJQ7UDayNnA8lDyUO1A2sjZ2PJQ8lDtQNrI2uDyUPJQ7UDayNrg8lDyUO1A2sjZ8PJQ8lDgUNrI2uDyUPJQ7UDayNnw8lDyUO1A2sjaCPJQ8lDtQNrI2iDyUPJQ7UDayNpQ8lDyUO1A2sjaOPJQ8lDgUNrI2pjyUPJQ7UDayNpQ8lDyUO1A2sjaaPJQ8lDtQNrI2uDyUPJQ7UDayNqA8lDyUO1A2sjamPJQ8lDtQNrI2rDyUPJQ7UDayNqw8lDyUO1A2sja4PJQ8lDbEPJQ2vjyUPJQ2xDyUNso8lDyUNvQ8lDbQPJQ8lDbcPJQ6/DyUPJQ23DyUNtY8lDyUNtw8lDrePJQ8lDbcPJQ6/DyUPJQ23DyUNtY8lDyUNtw8lDrePJQ8lDbcPJQ66jyUPJQ29DyUOAg6eDyUNuI8lDboNu48lDb0PJQ39jp4PJQ2+jyUNwA3BjyUNww8lDgIOng8lDcSPJQ4CDp4PJQ3GDyUNx46eDyUN2Y3bDdgPJQ8lDdmN2w3SDyUPJQ3ZjdsN3I8lDyUN2Y3bDdyPJQ8lDdmN2w3cjyUPJQ3ZjdsN3I8lDyUN2Y3bDckPJQ8lDdCN2w3cjyUPJQ3ZjdsNyQ8lDyUN2Y3bDcqPJQ8lDdmN2w3MDyUPJQ3ZjdsN0g8lDyUN2Y3bDc2PJQ8lDdmN2w3PDyUPJQ3QjdsN2A8lDyUN2Y3bDdIPJQ8lDdmN2w3TjyUPJQ3ZjdsN3I8lDyUN2Y3bDdUPJQ8lDdmN2w3WjyUPJQ3ZjdsN1o8lDyUN2Y3bDdgPJQ8lDdmN2w3cjyUPJQ60jyUOtg8lDyUN348lDd4PJQ8lDd+PJQ3hDyUPJQ8BDyUOvw8lDyUPAQ8lDrePJQ8lDwEPJQ63jyUPJQ8BDyUOt48lDyUO9o8lDr8PJQ8lDwEPJQ66jyUPJQ8BDyUOvA8lDyUPAQ8lDr8PJQ8lDh6PJQ4dDeiPJQ3ijyUN5A3ljyUN5w8lDh0N6I8lDh6PJQ4gDeiPJQ4ejyUOIA3ojyUOGI8lDh0N6I8lDfYN9430jyUPJQ32DfeN9I8lDyUN9g33jfAPJQ8lDfYN9435DyUPJQ32DfeN+Q8lDyUN9g33jfAPJQ8lDfYN943qDyUPJQ32DfeN648lDyUN9g33je0PJQ8lDe6N9430jyUPJQ32DfeN8A8lDyUN9g33jfGPJQ8lDfYN9435DyUPJQ8lDyUOyA8lDyUN9g33jfMPJQ8lDfYN9430jyUPJQ32DfeN+Q8lDyUPJQ8lDfqPJQ8lDyUPJQ38DyUPJQ4AjyUOAg8lDyUOAI8lDf2PJQ8lDf8PJQ4CDyUPJQ4AjyUOAg8lDyUO1A8lDgmO1w7YjtQPJQ4DjtcO2I7UDyUOCY7XDtiOBQ8lDgmO1w7YjtQPJQ4JjtcO2I4FDyUOCY7XDtiO1A8lDgaO1w7YjggPJQ4JjtcO2I4LDyUODI4ODg+OEQ8lDhQPJQ8lDhKPJQ4UDyUPJQ4ejyUOHQ8lDyUOHo8lDhWPJQ8lDh6PJQ4gDyUPJQ4YjyUOHQ8lDyUOHo8lDhcPJQ8lDhiPJQ4dDyUPJQ4ejyUOGg8lDyUOG48lDh0PJQ8lDh6PJQ4gDyUPJQ4zjjUOLw44DjmOM441DiwOOA45jjOONQ4yDjgOOY4zjjUOMg44DjmOM441DiGOOA45jikONQ4yDjgOOY4zjjUOIY44DjmOM441DiMOOA45jjOONQ4kjjgOOY4zjjUOLA44DjmOM441DiYOOA45jjOONQ42jjgOOY4zjjUOJ444DjmOKQ41Di8OOA45jjOONQ4sDjgOOY4zjjUOKo44DjmOM48lDi8PJQ8lDjOPJQ4sDyUPJQ4pDyUOLw8lDyUOM48lDiwPJQ8lDjOPJQ4qjyUPJQ4zjyUOMg8lDyUOM441DiwOOA45jjOONQ4yDjgOOY4zjjUOLY44DjmOM441DjaOOA45jjOONQ42jjgOOY8lDyUOLw8lDyUOMI41DuYOOA45jjCONQ7ejjgOOY4zjjUOMg44DjmOM441DjaOOA45jjOONQ42jjgOOY4zjjUONo44DjmOOw8lDjyPJQ8lDyUPJQ4+DyUPJQ5CjyUORw8lDyUOQo8lDj+PJQ8lDkKPJQ5EDyUPJQ5BDyUORw8lDyUOQo8lDj+PJQ8lDkEPJQ5HDyUPJQ5CjyUORA8lDyUORY8lDkcPJQ8lDk6PJQ5QDyUPJQ5OjyUOSI8lDyUOTo8lDkoPJQ8lDk6PJQ5NDyUPJQ5OjyUOS48lDyUOTo8lDlAPJQ8lDk6PJQ5NDyUPJQ5RjyUOUA8lDyUOTo8lDlMPJQ8lDlGPJQ5QDyUPJQ5RjyUOUw8lDyUOVg8lDlwOXY8lDlYPJQ5cDl2PJQ5WDyUOVI5djyUOVg8lDlwOXY8lDlkPJQ5cDl2PJQ5WDyUOV45djyUOWQ8lDlwOXY8lDlqPJQ5cDl2PJQ8BDl8O/I8lDmCPAQ5fDvmPJQ5gjwEOXw7/jyUOYI8BDl8O/48lDmCPAQ5fDv+PJQ5gjwEOXw75jyUOYI8BDl8O9Q8lDmCO9o5fDvyPJQ5gjwEOXw75jyUOYI8BDl8O+A8lDmCPAQ5fDvyPJQ5gjwEOXw75jyUOYI72jl8O/I8lDmCPAQ5fDvmPJQ5gjwEOXw74DyUOYI8BDl8O/48lDmCPAQ5fDvmPJQ5gjwEOXw7/jyUOYI8BDl8O+w8lDmCPAQ5fDwQPJQ5gjwEOXw7+DyUOYI8BDl8O/48lDmCPAQ5fDwQPJQ5gjmaPJQ5iDyUPJQ5mjyUOaA8lDyUOZo8lDmOPJQ8lDmaPJQ5lDyUPJQ5mjyUOaA8lDyUOdA8lDm4PJQ8lDnQPJQ5vjyUPJQ50DyUOdY8lDyUOdA8lDmmPJQ8lDnQPJQ5rDyUPJQ5sjyUObg8lDyUOdA8lDm+PJQ8lDnQPJQ5xDyUPJQ50DyUOco8lDyUOdA8lDnWPJQ8lDnoPJQ5+jyUPJQ56DyUOdw8lDyUOeg8lDniPJQ8lDnoPJQ57jyUPJQ59DyUOfo8lDyUOkg6Tjo8PJQ8lDpIOk46KjyUPJQ6SDpOOlQ8lDyUOkg6TjoGPJQ8lDokOk46VDyUPJQ6SDpOOgY8lDyUOkg6TjoAPJQ8lDpIOk46BjyUPJQ6SDpOOlQ8lDyUOkg6TjpUPJQ8lDpIOk46DDyUPJQ6JDpOOlQ8lDyUOkg6TjoMPJQ8lDpIOk46EjyUPJQ6SDpOOhg8lDyUOkg6TjoqPJQ8lDpIOk46HjyUPJQ6JDpOOjw8lDyUOkg6TjoqPJQ8lDpIOk46MDyUPJQ6SDpOOlQ8lDyUOkg6Tjo2PJQ8lDpIOk46PDyUPJQ6SDpOOkI8lDyUOkg6TjpCPJQ8lDpIOk46VDyUPJQ6YDyUOlo8lDyUOmA8lDpmPJQ8lDpsPJQ6cjp4PJQ6wDrGOro8lDyUOsA6xjqiPJQ8lDrAOsY6zDyUPJQ6wDrGOsw8lDyUOsA6xjrMPJQ8lDrAOsY6zDyUPJQ6wDrGOn48lDyUOpw6xjrMPJQ8lDrAOsY6fjyUPJQ6wDrGOoQ8lDyUOsA6xjqKPJQ8lDrAOsY6ojyUPJQ6wDrGOpA8lDyUOsA6xjqWPJQ8lDqcOsY6ujyUPJQ6wDrGOqI8lDyUOsA6xjqoPJQ8lDrAOsY6zDyUPJQ6wDrGOq48lDyUOsA6xjq0PJQ8lDrAOsY6tDyUPJQ8lDyUOro8lDyUOsA6xjrMPJQ8lDrSPJQ62DyUPJQ69jyUOvw8lDyUOvY8lDrePJQ8lDr2PJQ63jyUPJQ69jyUOt48lDyUOuQ8lDr8PJQ8lDr2PJQ66jyUPJQ69jyUOvA8lDyUOvY8lDr8PJQ8lDsyOzg7LDyUPJQ7Mjs4Oyw8lDyUOzI7ODsUPJQ8lDsyOzg7PjyUPJQ7Mjs4Oz48lDyUOzI7ODsUPJQ8lDsyOzg7AjyUPJQ7Mjs4Owg8lDyUOw47ODssPJQ8lDsyOzg7FDyUPJQ7Mjs4Oxo8lDyUOzI7ODs+PJQ8lDyUPJQ7IDyUPJQ7Mjs4OyY8lDyUOzI7ODssPJQ8lDsyOzg7PjyUPJQ8lDyUO0Q8lDyUPJQ8lDtKPJQ8lDtQPJQ7VjtcO2I7aDyUO3Q8lDyUO248lDt0PJQ8lDuePJQ7mDyUPJQ7njyUO3o8lDyUO548lDukPJQ8lDuGPJQ7mDyUPJQ7njyUO4A8lDyUO4Y8lDuYPJQ8lDuePJQ7jDyUPJQ7kjyUO5g8lDyUO548lDukPJQ8lDuwPJQ7yDvOPJQ7sDyUO8g7zjyUO7A8lDuqO848lDuwPJQ7yDvOPJQ7vDyUO8g7zjyUO7A8lDu2O848lDu8PJQ7yDvOPJQ7wjyUO8g7zjyUPAQ8CjvyPJQ8FjwEPAo75jyUPBY8BDwKO/48lDwWPAQ8Cjv+PJQ8FjwEPAo7/jyUPBY8BDwKO+Y8lDwWPAQ8CjvUPJQ8FjvaPAo78jyUPBY8BDwKO+Y8lDwWPAQ8CjvgPJQ8FjwEPAo78jyUPBY8BDwKO+Y8lDwWO9o8CjvyPJQ8FjwEPAo75jyUPBY8BDwKO+A8lDwWPAQ8Cjv+PJQ8FjwEPAo75jyUPBY8BDwKO/48lDwWPAQ8CjvsPJQ8FjwEPAo8EDyUPBY8BDwKO/I8lDwWPAQ8Cjv4PJQ8FjwEPAo7/jyUPBY8BDwKPBA8lDwWPC48lDwcPJQ8lDwuPJQ8NDyUPJQ8LjyUPCI8lDyUPC48lDwoPJQ8lDwuPJQ8NDyUPJQ8ZDyUPEw8lDyUPGQ8lDxSPJQ8lDxkPJQ8ajyUPJQ8ZDyUPDo8lDyUPGQ8lDxAPJQ8lDxGPJQ8TDyUPJQ8ZDyUPFI8lDyUPGQ8lDxYPJQ8lDxkPJQ8XjyUPJQ8ZDyUPGo8lDyUPHw8lDyOPJQ8lDx8PJQ8cDyUPJQ8fDyUPHY8lDyUPHw8lDyCPJQ8lDyIPJQ8jjyUPJQAAQFuA7sAAQFuA7AAAQIWA40AAQHwA6EAAQFuA7YAAQFu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AFYAZQB0AIMAkQCgAK8AvgDNANwA6wD6AQkBGAEnATYAAP//ABUADAAbACoAOQBIAFcAZgB1AIQAkgChALAAvwDOAN0A7AD7AQoBGQEoATcAAP//ABUADQAcACsAOgBJAFgAZwB2AIUAkwCiALEAwADPAN4A7QD8AQsBGgEpATgAAP//ABUADgAdACwAOwBKAFkAaAB3AIYAlACjALIAwQDQAN8A7gD9AQwBGwEqATkBOmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmFhbHQHXmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmMyc2MHZmNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNhc2UHbGNjbXAHgmNjbXAHgmNjbXAHgmNjbXAHgmNjbXAHgmNjbXAHcmNjbXAHgmNjbXAHgmNjbXAHgmNjbXAHgmNjbXAHgmNjbXAHgmNjbXAHgmNjbXAHgmNjbXAHgmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRsaWcHjmRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGRub20HlGZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmZyYWMHmmxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxpZ2EHpGxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxudW0HqmxvY2wHsGxvY2wHtmxvY2wHvGxvY2wHwmxvY2wHyGxvY2wHzmxvY2wH1GxvY2wH2mxvY2wH4GxvY2wH5mxvY2wH7GxvY2wH8mxvY2wH+GxvY2wH/m51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG51bXIIBG9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9udW0ICm9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEG9yZG4IEHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHBudW0IGHNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNhbHQIHnNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNpbmYIJHNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNtY3AIKnNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHNzMDEIMHN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1YnMINnN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHN1cHMIPHRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQnRudW0IQgAAAAIAAAABAAAAAQAkAAAAAQAmAAAABgACAAMABAAFAAYABwAAAAQAAgADAAQABQAAAAEAJwAAAAEAGgAAAAMAGwAcAB0AAAABACgAAAABACAAAAABABEAAAABABUAAAABABQAAAABABIAAAABABMAAAABABAAAAABAAkAAAABAA8AAAABAAwAAAABAAsAAAABAAgAAAABAAoAAAABAA0AAAABAA4AAAABABkAAAABACMAAAACAB4AHwAAAAEAIQAAAAEAKQAAAAEAFwAAAAEAJQAAAAEAKgAAAAEAFgAAAAEAGAAAAAEAIgAtAFwG3hGaEkgSrhKuFAIUAhSsFNoVHhUeFUAVQBVAFUAVQBVUFcIV1hX8FhYWPBZKFlgWiBZmFnQWiBaWFt4XJhdIF2AXeBeQF64Z+BxUHUYdZh2OHY4iniM4AAEAAAABAAgAAgRCAh4C+wL8Av0C/gL/AwADAQMCAwMDBAMFAwYDBwMIAyIDIwMtAy4DLwMwAzEDMgNHA0gDSQNLA0wDTQNOA08DUANRA1IDUwNhA2IDYwNkA2UDZgNnA2gDaQNqA2sDbANtA24DbwNwA3EDcgNzA3QDdQN2A3cDeAN5A3oDewN8A30DfgN/A4ADgQOCA4MDhAOGA4cDiAOJA4oDiwOMA40DjgOPA5ADkQOSA5MDlQOWA5cDmAOZA5oDuwPBAvsC/AL9Av4C/wMAAwEDAgMDAwQDBQMGAwcDCAMiAyMDJQMmAycDKAMpAyoDKwMsAy0DLgMvAzADMQMyAzQDNQM3AzgDOQM6AzsDPAM9Az4DPwNAA0EDQgNDA0QDRgNHA0gDSQNKA1QDVQNWA1cDWANZA1oDWwNcA10DXgNfA2EDYgNjA2QDZQNmA2cDaANpA2oDawNsA20DbgNvA3ADcQNyA3MDdAN1A3YDdwN4A3kDegN7A3wDfQN+A38DgAOBA4MDhAOFA4YDhwOIA4kDigOLA4wDjQOOA48DkAORA5IDkwOVA5YDlwOYA5kDmgOjA6QDpQOmA6cDqAOpA6oDqwOsA60DrgOvA7ADsQOyA7MDtAO1A7YDtwO4A7kDugO7A8EDxgM2At0C3gPRA9ID0wPUA9UD1gPXA9gD2QPaA9sD3APdA94D3wPgA+ED4gPjA+QD5QPmA+cD6APpA+oD6wPsA+0D7gPvA/AD8QPyA/MD9AP1A/YD9wP4A/kD+gP7A/wD/QP+A/8EAAQBBAIEAwQEBAUEBgQHBAgECQQKBAsEDAQNBA4EDwQQBBEEEgQTBBQEFQQWBBcEGAQZBBoEGwQcBB0EHgQfBCAEIQQiBCMEJAQlBCYEJwQoBCkEKgQrBCwELQQuBC8EMAQxBDIEMwQ0BDUENgQ3BDgEOQQ6BDsEPAQ9BD4EPwRABEEEQgRDBEQERQRGBEcESARJBEoESwRMBE0ETgRPBFAEUQRSBFMEVARVBFYEVwRYBFkEWgRbBFwEXQReBF8EYARhBGIEYwTjBOUE5gTnBOgE6QTrBOoE7QTuBO8E8ATyBPME9AT1BPYE9wT4BN8E4AT5BPoE+wT8BP0E/gT/BQAFAQUCBQMFBAUFBZoFlQV9BZQFnAWdBZ4FgAWBBaEFhQWGBYcFowWlBaYFigWLBYwFjQWpBaoFqwWQBawFkQWSBZMFrQWuBa8FsAWxBbIFswW0BbUFtgW3BbgFuQX8Bf0F/gX/BgAGAQYCBgMGBAYFBjYGOAZgBmEGZgZnBmgGaQZwBjkGQgZDBkQGRQZGBkcGTwZQBlEGagZrBmwGbQZuBm8GuQa6BrsGvAbcBt4G3QcKBwsHDAcNBw4HDwcQBxEHEgcTBxQHFQcWBxcHGAcZBxoHGwccBx0HHgcfByAHIQciByMHJAdWByYHZgdnB2gHaQdqB2sHbAdtAAIAXgAgACgAAAAqAC4ACQBHAEgADgBSAFcAEABqAG0AFgBvAHYAGgCFAKgAIgCqALcARgC5AL4AVADfAN8AWgDlAOUAWwGmAbMAXAHNAc4AagHQAd0AbAHfAe4AegHxAfUAigH/AgIAjwIEAgsAkwINAi0AmwIvAj8AvAJBAkYAzQJQAmgA0wJuAm4A7AJzAnMA7QJ+An4A7gLbAtwA7wLfAvoA8QMJAyEBDQMkAywBJgMzAzsBLwM9A0YBOANRA1EBQgNUA18BQwOFA4UBTwObA7oBUAO8A8ABcAPCA9ABdQRmBGYBhARtBG8BhQRyBHUBiAR9BH0BjAR/BIEBjQSJBI0BkASTBJMBlQSYBJgBlgScBJwBlwSfBJ8BmASqBKoBmQS8BL8BmgTFBMYBngTLBM0BoATQBNABowTWBNYBpATYBNgBpQUGBQgBpgUKBQoBqQUNBREBqgUVBRYBrwUYBRgBsQUaBRoBsgUdBR0BswUgBSEBtAUkBScBtgUrBS0BugU1BTUBvQU4BTgBvgU8BTwBvwU/BT8BwAVJBUkBwQVdBWIBwgVmBWcByAVsBW4BygVxBXEBzQV5BXkBzgYGBg8BzwYlBiUB2QYnBicB2gYrBiwB2wYuBjIB3QY7BkEB4gZIBkkB6QZMBkwB6wZWBlsB7AavBq8B8gaxBrEB8wazBrMB9Aa1BrUB9QbKBssB9gbYBtgB+AbfBuoB+QbsBu8CBQbyBvwCCQcHBwgCFAdeB2UCFgADAAAAAQAIAAEJtAEyAmoCcgJ4An4ChAKKApAClgKcAqICqAKuArQCugLAAsYCzALSAtgC3gLkAuoC8AL2AvwDAgMIAw4DFAMaAyADJgMsAzIDOAM+A0QDSgNQA1YDXANiA2gDbgN0A3oDgAOGA4wDkgOYA54DpAOqA7ADtgO8A8IDyAPOA9QD2gPgA+YD7APyA/gD/gQEBAoEEAQWBBwEIgQoBC4ENAQ6BEAERgRMBFIEWAReBGQEagRwBHYEfASCBIgEjgSUBJoHdgSgBKYErASyBLgEvgTEBMwE0gTYBN4E5ATqBPAE9gT8BQIFCAUOBRQFGgUgBSYFLAUyBTgFPgVEBUoFUAVWBVwFYgVoBW4FdAV6BYAFhgWMBZIFmAWeBaQFqgWwBbYFvAXCBcgFzgXUBdoF4AXmBewF9AX6BgAGBgYMBhIGGAYeBiQGKgYwBjYGPAZCBkgGTgZUBloGYAZmBmwGcgZ4Bn4GhAaKBpAGlgacBqIGqAauBrQGugbABsYGzAbSBtgG3gbkBuoG8Ab2BvwHAgcIBw4HFAcaByAHJgcsBzIHOgdAB0YHTAdSB1gHXgdkB2oHcAd2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AQIBAwEEAQUBBgEHAQgBCQEKAQsBDAENAQ4BDwEQAREBEgETARQBFQEWARcBGAEZARoBGwEcAR0BHgEfASABIQEiASMBJAElASYBJwEoASkBKgErASwBLQEuAS8BMAExATIBMwE0ATUBNgE4ATkBOgE7ATwBPQE+AT8BQAFBAUIBQwFEAUUBRgFHAUgBSQFKAUsBTAFNAU4BTwFQAVEBUgFTAVQBVQFWAVcBWAFZAVoBWwFcAV0BXgFfAWABYQFiAWMBZAFlAWYBZwFoAWkBagFrAWwBbQFuAW8BcAFxAXIBcwF0AXUBdgF3AXgBeQF6AXsBfAF9AX4BfwGAAYEBggGDAYQBhQGGAYcBiAGJATcCfwKAAoECggKDAoQChQKGAocCiAKJAooCiwKMAo0CjgKPApACkQKSApMClAKVApYClwKYApkCmgKbApwCnQKeAp8CoAKhAqICowKkAqUCpgKnAqgCqQKqAqsCrAKtAq4CrwKwArECsgKzArQCtQK2ArcCuAK5AroCuwK8Ar0CvgK/AsACwQLCAsMCxALFAsYCxwLIAskCygLLAswCzQLOAs8C0ALRAtIC0wLUAtUC1gLXAtgC2QLdAt4D0QPSA9MD1APVA9YD1wPYA9kD2gPbA9wD3QPeA98D4APhA+ID4wPkA+UD5gPnA+gD6QPqA+sD7APtA+4D7wPwA/ED8gPzA/QD9QP2A/cD+AP5A/oD+wP8A/0D/gP/BAAEAQQCBAMEBAQFBAYEBwQIBAkECgQLBAwEDQQOBA8EEAQRBBIEEwQUBBUEFgQXBBgEGQQaBBsEHAQdBB4EHwQgBCEEIgQjBCQEJQQmBCcEKAQpBCoEKwQsBC0ELgQvBDAEMQQyBDMENAQ1BDYENwQ4BDkEOgQ7BDwEPQQ+BD8EQARBBEIEQwREBEUERgRHBEgESQRKBEsETARNBE4ETwRQBFEEUgRTBFQEVQRWBFcEWARZBFoEWwRcBF0EXgRfBGAEYQRiBGME4wTkBOUE5gTnBOgE6QTrBOoE7ATtBO4E7wTwBPEE8gTzBPQE9QT2BPcE+AT5BPoE+wT8BP0E/gT/BQAFAQUCBQMFBAUFBZoFmwWcBZ0FngWfBaAFogWhBaMFpAWlBaYFpwWoBakFqgWrBawFrQWuBa8FsAWxBbIFswW0BbUFtgW3BbgFuQbdAAIAPQAEAB8AAAApACkAHAAvAEYAHQBJAFEANQBYAGkAPgBuAG4AUAB3AIMAUQCpAKkAXgC/AN4AXwDgAOQAfwDmAPUAhAGKAaUAlAG0AcwAsAHPAc8AyQH2Af4AygIuAi4A0wJIAk8A1AJpAm0A3AJvAnIA4QJ0An0A5QLbAtwA7wLfAvoA8QMJAyEBDQMkAywBJgMzAzsBLwM9A0YBOANRA1EBQgNUA18BQwOFA4UBTwObA7oBUAO8A8ABcAPCA9ABdQRmBGYBhARsBG8BhQRyBHUBiQR4BHgBjQR9BH0BjgR/BIIBjwSJBI0BkwSTBJMBmASYBJgBmQSqBKoBmgS8BL8BmwTFBMYBnwTLBM0BoQTQBNABpATWBNYBpQTYBNgBpgUGBQYBpwUMBQ8BqAUSBRUBrAUdBR0BsAUfBSEBsQUpBS0BtAU4BTgBuQVdBWIBugVmBWcBwAVsBW4BwgVxBXEBxQV5BXkBxgbYBtgBxwABAAAAAQAIAAIAWAApAd8B8AY7BwoHCwcMBw0HDgcPBxAHEQcSBxMHFAcVBxYHFwcYBxkHGgcbBxwHHQceBx8HIAchByIHIwckByUHJgcnB2YHZwdoB2kHagdrB2wHbQACAAkB3gHeAAAB7wHvAAEGJgYmAAIG3wbqAAMG7AbvAA8G8gb8ABMHBgcGAB4HCAcJAB8HXgdlACEAAQAAAAEACAACACQADwRkBGUEZARlBfwF/QX+Bf8GAAYBBgIGAwYEBgUGOQABAA8ABACEAYoCDAYGBgcGCAYJBgoGCwYMBg0GDgYPBiYAAA==) format("truetype")}@font-face{font-weight:normal;font-family:"tick42-icons";font-style:normal;src:url(data:font/ttf;base64,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YGAGCAcGqgJK/bYCgP1KJhsaARscJQK2JhsaARscJQAAAQAAAAEAAH2fuHdfDzz1AAsEAAAAAADhVnMIAAAAAOFWcwj//f+9BQADwwAAAAgAAgAAAAAAAAABAAADwP/AAAAFJP/9//0FAAABAAAAAAAAAAAAAAAAAAAA9wQAAAAAAAAAAAAAAAIAAAAEAAAABAAAAAO2//8ESQAAA24AAANuAAACkf//A24AAAO2//8CSQAABAAAAAO2//8CAAAAAmYAAALNAAACHwAAAmYAAAJmAAACqwAAAeEAAAOFAAADhQAAA24AAAQAAAAEkf//AyQAAANWAAACZgAAAOEAAAJIAAADrgAAAysAAAOaAAAEAAAAA24AAAQAAAAEAAAABAAAAAQAAAAEAP/9A24AAAQAAAADWAAAAyQAAANuAAADbgAAA24AAAQAAAADtgAAAbYAAAQAAAAEAAAAA24AAANuAAADbgAAA24AAAQAAAAEAAAABAAAAAQAAAAEAQAABAAAAAQAAAAEAAAAApH//wQA//0EAAAABAD//QQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAAA24AAAO2AAAEAAAAA7b//wMkAAADJAAAAyQAAAQAAAAEAAAAA24AAANuAAADtgAAA7YAAAMkAAADtv//BAAAAAQAAAADbgAABEkAAALbAAADtv//A7b//wQAAAACSQAAAkkAAAFuAAABbgAAAtsAAAQAAAAC2wAABAAAAAO2AAADbgAAA24AAAO2AAADtgAAA7YAAANHAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAADJAAAAtsAAAMkAAADbgAABAAAAANuAAADtv//A7b//wJJAAACSQAAAkkAAAQAAAAEAAAABAAAAAQAAAAESQAABEkAAAQAAAAEAAAAA24AAANuAAACSQAAAkkAAAKRAAACkQAAAW4AAAFuAAACkQAAApEAAARJAAADbgAAA7b//wO2//8EAAAAA24AAAQAAAADtv//BEkAAAO2AAAESQAABAAAAAMkAAACSQAAA7b//wJJAAABbgAAAW4AAAKR//8DJAAAA7b//wKR//8DJAAAANsAAANuAAADbgAAA24AAANuAAACSQAAAkkAAANuAAADtgAAA7YAAAQAAAAEAAAAA24AAANuAAABtgAAAbYAAAQAAAAEAAAABAAAAAUkAAADbgAAA24AAANuAAADbgAAA24AAANuAAADbgAAA24AAANuAAADbgAAA24AAANuAAADbgAABJEAAASRAAAEkQAAA24AAASR//8Ekf//BJH//wSR//8Ekf//BJEAAAQAAAADbgAAA24AAANuAAADbgAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAO2//8DbgAABAAAAAQAAAAEkf//BAAAAAQAAAAAAAAAAAoAFAAeAQgBbAHkAk4DIgP+BEIIOAj2CTQJjAosCkoKZAqCCqQK0Ar8CyoLZguaC9IMNAzEDPINnA4gDl4OfA6wDvoPGg84D2wP0hAGEFQQhBD0EfgSOBJ8Ep4TVhO4FBoUYBXAFioWbBaqFzAXdBfiGFAY1hmWGpYcAhx2HQIdih64IAQgZiFGIhQjcCRuJKwk3iU4JbwmBCYeJjgmuCc6J9IoKihsKJAo0ikCKbIqQiq2KxYr0Cw+LIws+i2gLeguWi6SLxgvoC/8MCAwRjBqMI4wvjDuMRwxTDGIMcQyADI8MqIzGjNgM8o0HjR6NMg1fjbONx43Xjd8OFg4zjlcOdQ6SjrEOwY7SDtyO+Q8VDywPcA+Aj5EPmg+jD8GP5A/+kBUQLRBFEFcQcxCZELCQxRDZkO4RApEOERmRJREwkUkRXJF8EZuRzJHXEe4SAxIiEjQSURJrkniSppLiEv+TFRMlE0ITZpOFk5gTrhPEE9QT5xP7FBEUPZRyFH+UnxS/FOWVDBUyFViVY5VulXoVhZWXFbcV2pYSljeWWxZ4FpIWuJbjlwGXLZdEF2SXeBejF8OX7JgXGB6YLphSmG2YlJi7GNaY/xkdmTkZXRmKGbCZ3poHmiSaWBqSGsga6Zr1Gv4bERspm0SAAEAAAD3As4ADwAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAOAK4AAQAAAAAAAQAMAAAAAQAAAAAAAgAHAI0AAQAAAAAAAwAMAEUAAQAAAAAABAAMAKIAAQAAAAAABQALACQAAQAAAAAABgAMAGkAAQAAAAAACgAaAMYAAwABBAkAAQAYAAwAAwABBAkAAgAOAJQAAwABBAkAAwAYAFEAAwABBAkABAAYAK4AAwABBAkABQAWAC8AAwABBAkABgAYAHUAAwABBAkACgA0AOB0aWNrNDItaWNvbnMAdABpAGMAawA0ADIALQBpAGMAbwBuAHNWZXJzaW9uIDEuMABWAGUAcgBzAGkAbwBuACAAMQAuADB0aWNrNDItaWNvbnMAdABpAGMAawA0ADIALQBpAGMAbwBuAHN0aWNrNDItaWNvbnMAdABpAGMAawA0ADIALQBpAGMAbwBuAHNSZWd1bGFyAFIAZQBnAHUAbABhAHJ0aWNrNDItaWNvbnMAdABpAGMAawA0ADIALQBpAGMAbwBuAHNGb250IGdlbmVyYXRlZCBieSBJY29Nb29uLgBGAG8AbgB0ACAAZwBlAG4AZQByAGEAdABlAGQAIABiAHkAIABJAGMAbwBNAG8AbwBuAC4AAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA) format("truetype")}[class^="icon-"],[class*=" icon-"]{font-weight:normal;font-family:"tick42-icons";font-style:normal;font-variant:normal;line-height:1;text-transform:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.tick42-custom-icon i{color:var(--t42-link-color)}.tick42-custom-icon img{display:block}.tick42-custom-icon.disabled i,.tick42-custom-icon:disabled i{color:var(--t42-content-color-disabled)}i.disabled,.disabled i{color:var(--t42-content-color-disabled)}.icon-size-12 i{font-size:0.75rem}.icon-size-12 i,.icon-size-12 img{width:0.75rem;height:0.75rem}.icon-size-14 i{font-size:0.875rem}.icon-size-14 i,.icon-size-14 img{width:0.875rem;height:0.875rem}.icon-size-24 i{font-size:1.5rem}.icon-size-24 i,.icon-size-24 img{width:1.5rem;height:1.5rem}.icon-size-16 i,.icon-size-16 img{width:1rem;height:1rem}.icon-size-16 i{font-size:1rem}.icon-size-32 i,.icon-size-32 img{width:2rem;height:2rem}.icon-size-32 i{font-size:2rem}.icon-size-48 i,.icon-size-48 img{width:3rem;height:3rem}.icon-size-48 i{font-size:3rem}.icon-size-64 i,.icon-size-64 img{width:4rem;height:4rem}.icon-size-64 i{font-size:4rem}.icon-size-80 i,.icon-size-80 img{width:5rem;height:5rem}.icon-size-80 i{font-size:5rem}.icon-size-96 i,.icon-size-96 img{width:6rem;height:6rem}.icon-size-96 i{font-size:6rem}.icon-size-112 i,.icon-size-112 img{width:7rem;height:7rem}.icon-size-112 i{font-size:7rem}.icon-size-128 i,.icon-size-128 img{width:8rem;height:8rem}.icon-size-128 i{font-size:8rem}.icon-primary i::before{color:#007be5}.icon-secondary i::before{color:#616161}.icon-success i::before{color:#43a047}.icon-info i::before{color:#469eb9}.icon-warning i::before{color:#f9a825}.icon-danger i::before{color:#ff511f}.icon-light i::before{color:#616161}.icon-dark i::before{color:#616161}.icon-dev-tools::before{content:"\e901"}.icon-interop::before{content:"\e900"}.icon-mail::before{content:"\e800"}.icon-attention::before{content:"\e801"}.icon-print::before{content:"\e802"}.icon-picture::before{content:"\e803"}.icon-thumbs-up::before{content:"\e804"}.icon-thumbs-down::before{content:"\e805"}.icon-lock::before{content:"\e806"}.icon-globe::before{content:"\e807"}.icon-calendar::before{content:"\e808"}.icon-location::before{content:"\e809"}.icon-briefcase::before{content:"\e80a"}.icon-export::before{content:"\e80b"}.icon-play::before{content:"\e80c"}.icon-stop::before{content:"\e80d"}.icon-record::before{content:"\e80e"}.icon-pause::before{content:"\e80f"}.icon-to-end::before{content:"\e810"}.icon-to-start::before{content:"\e811"}.icon-check::before{content:"\e812"}.icon-cancel::before{content:"\e813"}.icon-fast-forward::before{content:"\e814"}.icon-fast-backward::before{content:"\e815"}.icon-attention-circled::before{content:"\e816"}.icon-bell::before{content:"\e817"}.icon-chart-bar::before{content:"\e818"}.icon-phone::before{content:"\e819"}.icon-doc-add::before{content:"\e81a"}.icon-layout::before{content:"\e81b"}.icon-dot::before{content:"\e81c"}.icon-dot-2::before{content:"\e81d"}.icon-dot-3::before{content:"\e81e"}.icon-resize-full-1::before{content:"\e81f"}.icon-resize-small-1::before{content:"\e820"}.icon-checkbox::before{content:"\e821"}.icon-cancel-circled::before{content:"\e822"}.icon-03-context-viewer::before{content:"\e823"}.icon-volume-off-1::before{content:"\e824"}.icon-volume::before{content:"\e825"}.icon-headphones-1::before{content:"\e826"}.icon-performance-report::before{content:"\e827"}.icon-pause-1::before{content:"\e828"}.icon-volume-up-1::before{content:"\e829"}.icon-volume-down-1::before{content:"\e82a"}.icon-trash-empty::before{content:"\e839"}.icon-resize-small::before{content:"\e83b"}.icon-resize-full::before{content:"\e83c"}.icon-doc::before{content:"\e83d"}.icon-cog::before{content:"\e83e"}.icon-wrench::before{content:"\e83f"}.icon-resize-vertical::before{content:"\e840"}.icon-resize-horizontal::before{content:"\e841"}.icon-edit::before{content:"\e842"}.icon-pencil-1::before{content:"\e843"}.icon-cw-2::before{content:"\e844"}.icon-ccw-1::before{content:"\e845"}.icon-arrows-cw-1::before{content:"\e847"}.icon-th-large::before{content:"\e848"}.icon-th::before{content:"\e849"}.icon-spin5::before{content:"\e84a"}.icon-spin6::before{content:"\e84b"}.icon-spin4::before{content:"\e84c"}.icon-spin3::before{content:"\e84d"}.icon-spin2::before{content:"\e84e"}.icon-spin1::before{content:"\e84f"}.icon-pin::before{content:"\e850"}.icon-trading-controls::before{content:"\e856"}.icon-icon-coverage::before{content:"\e857"}.icon-taxes::before{content:"\e858"}.icon-credit::before{content:"\e859"}.icon-checkbox-checked::before{content:"\e85a"}.icon-checkbox-indeterminate::before{content:"\e85b"}.icon-radio::before{content:"\e85c"}.icon-radio-choose::before{content:"\e85d"}.icon-arrow-up-down::before{content:"\e85e"}.icon-arrow-double-left::before{content:"\e85f"}.icon-arrow-double-right::before{content:"\e860"}.icon-floppy::before{content:"\e861"}.icon-logout::before{content:"\e862"}.icon-mail-1::before{content:"\e864"}.icon-search-1::before{content:"\e865"}.icon-plus-1::before{content:"\e866"}.icon-minus-1::before{content:"\e867"}.icon-cancel-1::before{content:"\e868"}.icon-ok::before{content:"\e869"}.icon-th-list::before{content:"\e86a"}.icon-help-circled::before{content:"\e86b"}.icon-info-circled::before{content:"\e86c"}.icon-home::before{content:"\e86d"}.icon-link-1::before{content:"\e86e"}.icon-attach-1::before{content:"\e86f"}.icon-lock-open-1::before{content:"\e870"}.icon-eye::before{content:"\e871"}.icon-eye-off::before{content:"\e872"}.icon-tag::before{content:"\e873"}.icon-tags::before{content:"\e874"}.icon-bookmark::before{content:"\e875"}.icon-download-1::before{content:"\e876"}.icon-upload-1::before{content:"\e877"}.icon-forward-1::before{content:"\e878"}.icon-down-dir::before{content:"\e879"}.icon-up-dir::before{content:"\e87a"}.icon-left-dir::before{content:"\e87b"}.icon-right-dir::before{content:"\e87c"}.icon-left-open-1::before{content:"\e87d"}.icon-down-open-1::before{content:"\e87e"}.icon-right-open-1::before{content:"\e87f"}.icon-up-open-1::before{content:"\e880"}.icon-down-big::before{content:"\e881"}.icon-left-big::before{content:"\e882"}.icon-right-big::before{content:"\e883"}.icon-up-big::before{content:"\e884"}.icon-asterisk::before{content:"\e885"}.icon-check-1::before{content:"\e886"}.icon-tick42-icon-monochrome::before{content:"\e887"}.icon-task-manager::before{content:"\e888"}.icon-context-viewer::before{content:"\e889"}.icon-help-2::before{content:"\e88a"}.icon-star-empty-1::before{content:"\e88b"}.icon-star-full::before{content:"\e902"}.icon-move::before{content:"\f047"}.icon-link-ext::before{content:"\f08e"}.icon-check-empty::before{content:"\f096"}.icon-bookmark-empty::before{content:"\f097"}.icon-filter::before{content:"\f0b0"}.icon-resize-full-alt::before{content:"\f0b2"}.icon-docs::before{content:"\f0c5"}.icon-menu-1::before{content:"\f0c9"}.icon-table::before{content:"\f0ce"}.icon-columns::before{content:"\f0db"}.icon-sort::before{content:"\f0dc"}.icon-sort-down::before{content:"\f0dd"}.icon-sort-up::before{content:"\f0de"}.icon-mail-alt::before{content:"\f0e0"}.icon-sitemap::before{content:"\f0e8"}.icon-paste::before{content:"\f0ea"}.icon-exchange::before{content:"\f0ec"}.icon-download-cloud::before{content:"\f0ed"}.icon-upload-cloud::before{content:"\f0ee"}.icon-suitcase-1::before{content:"\f0f2"}.icon-bell-alt::before{content:"\f0f3"}.icon-doc-text-1::before{content:"\f0f6"}.icon-plus-squared::before{content:"\f0fe"}.icon-angle-double-left::before{content:"\f100"}.icon-angle-double-right::before{content:"\f101"}.icon-angle-double-up::before{content:"\f102"}.icon-angle-double-down::before{content:"\f103"}.icon-angle-left::before{content:"\f104"}.icon-angle-right::before{content:"\f105"}.icon-angle-up::before{content:"\f106"}.icon-angle-down::before{content:"\f107"}.icon-laptop::before{content:"\f109"}.icon-circle-empty::before{content:"\f10c"}.icon-quote-left::before{content:"\f10d"}.icon-quote-right::before{content:"\f10e"}.icon-spinner::before{content:"\f110"}.icon-circle::before{content:"\f111"}.icon-reply-1::before{content:"\f112"}.icon-folder-empty::before{content:"\f114"}.icon-folder-open-empty::before{content:"\f115"}.icon-terminal::before{content:"\f120"}.icon-code::before{content:"\f121"}.icon-reply-all-1::before{content:"\f122"}.icon-direction::before{content:"\f124"}.icon-fork::before{content:"\f126"}.icon-unlink::before{content:"\f127"}.icon-help::before{content:"\f128"}.icon-info::before{content:"\f129"}.icon-attention-alt::before{content:"\f12a"}.icon-mic::before{content:"\f130"}.icon-mute::before{content:"\f131"}.icon-calendar-empty::before{content:"\f133"}.icon-lock-open-alt::before{content:"\f13e"}.icon-ellipsis::before{content:"\f141"}.icon-ellipsis-vert::before{content:"\f142"}.icon-minus-squared::before{content:"\f146"}.icon-ok-squared::before{content:"\f14a"}.icon-link-ext-alt::before{content:"\f14c"}.icon-expand-right::before{content:"\f152"}.icon-euro::before{content:"\f153"}.icon-dollar::before{content:"\f155"}.icon-doc-inv::before{content:"\f15b"}.icon-sort-name-up::before{content:"\f15d"}.icon-sort-name-down::before{content:"\f15e"}.icon-sort-alt-up::before{content:"\f160"}.icon-sort-alt-down::before{content:"\f161"}.icon-sort-number-up::before{content:"\f162"}.icon-sort-number-down::before{content:"\f163"}.icon-down::before{content:"\f175"}.icon-up::before{content:"\f176"}.icon-left::before{content:"\f177"}.icon-right::before{content:"\f178"}.icon-cube::before{content:"\f1b2"}.icon-cubes::before{content:"\f1b3"}.icon-database::before{content:"\f1c0"}.icon-file-pdf::before{content:"\f1c1"}.icon-file-word::before{content:"\f1c2"}.icon-file-excel::before{content:"\f1c3"}.icon-file-powerpoint::before{content:"\f1c4"}.icon-file-image::before{content:"\f1c5"}.icon-file-archive::before{content:"\f1c6"}.icon-file-audio::before{content:"\f1c7"}.icon-file-video::before{content:"\f1c8"}.icon-file-code::before{content:"\f1c9"}.icon-circle-thin::before{content:"\f1db"}.icon-sliders::before{content:"\f1de"}.icon-share::before{content:"\f1e0"}.icon-wifi::before{content:"\f1eb"}.icon-bell-off::before{content:"\f1f6"}.icon-bell-off-empty::before{content:"\f1f7"}.icon-copyright::before{content:"\f1f9"}.icon-chart-area::before{content:"\f1fe"}.icon-chart-line::before{content:"\f201"}.icon-toggle-off::before{content:"\f204"}.icon-toggle-on::before{content:"\f205"}.icon-user-plus::before{content:"\f234"}.icon-user-times::before{content:"\f235"}.icon-clone::before{content:"\f24d"}.icon-hourglass-o::before{content:"\f250"}.icon-hourglass-1::before{content:"\f251"}.icon-hourglass-2::before{content:"\f252"}.icon-hourglass-3::before{content:"\f253"}.icon-calendar-plus-o::before{content:"\f271"}.icon-calendar-minus-o::before{content:"\f272"}.icon-calendar-times-o::before{content:"\f273"}.icon-calendar-check-o::before{content:"\f274"}.icon-hashtag::before{content:"\f292"}.icon-low-vision::before{content:"\f2a8"}.icon-envelope-open-o::before{content:"\f2b7"}.icon-address-book-o::before{content:"\f2ba"}.icon-user-o::before{content:"\f2c0"}.icon-window-maximize::before{content:"\f2d0"}.icon-window-minimize::before{content:"\f2d1"}.icon-window-restore::before{content:"\f2d2"}.icon-window-close::before{content:"\f2d3"}.icon-window-close-o::before{content:"\f2d4"}.icon-app::before{content:"\e903"}.icon-download-arrow::before{content:"\e904"}.icon-logo::before{content:"\e905"}.icon-feedback::before{content:"\e906"}.icon-action::before{content:"\e907"}.icon-swimlane::before{content:"\e908"}div.ag-dnd-ghost{border-color:transparent;border-radius:0.25rem;color:var(--white);font-size:0.75rem;font-family:inherit;line-height:inherit;background-color:var(--primary);cursor:default}div .ag-dnd-ghost-icon{display:flex;float:none;padding:0 0.25rem 0 0}div .ag-dnd-ghost-icon .ag-icon{background-color:var(--white)}.ag-tick42{padding-top:0}.ag-tick42 a{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border;border-bottom:0.063rem dashed var(--dark);color:var(--t42-content-color)}.ag-tick42 a:hover{text-decoration:none}.ag-tick42 .ag-filter-body{margin:0}.ag-tick42 input{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border;padding:0 0.5rem;border:var(--t42-border);color:var(--t42-content-color);line-height:2rem;background-color:var(--t42-input-bg)}.ag-tick42 input:focus{border-color:var(--primary);outline:0}.ag-tick42 input.ag-column-name-filter{margin-left:0.5rem}.ag-tick42 .ag-input-wrapper{padding:0.25rem}.ag-tick42 .ag-input-wrapper.ag-checkbox-input-wrapper{padding:0}.ag-tick42 .ag-cell-wrapper.ag-row-group{align-items:center}.ag-tick42 .ag-cell{padding:0 0.25rem;border-bottom:var(--t42-border);line-height:1.875rem;white-space:nowrap;text-overflow:ellipsis}.ag-tick42 .ag-cell .btn,.ag-tick42 .ag-cell .btn-sm,.ag-tick42 .ag-cell .btn-group-sm>.btn,.ag-tick42 .ag-cell .btn-lg,.ag-tick42 .ag-cell .btn-group-lg>.btn{line-height:1.25rem}.ag-tick42 .ag-cell .btn-icon i{position:relative;top:0.0625rem}.ag-tick42 .ag-cell:focus{outline:1px solid var(--primary)}.ag-tick42 .ag-cell .dropdown-toggle{width:20px;height:20px;margin-top:-3px;padding:0;border:0;line-height:22px}.ag-tick42 .ag-cell .dropdown-toggle::after{background-color:transparent;content:""}.ag-tick42 .ag-row::before{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:width;position:absolute;top:0;bottom:0;left:0;z-index:1;width:0;background-color:var(--primary);content:""}.ag-tick42 .ag-row.ag-row-selected{color:var(--t42-link-color);background-color:var(--t42-color-opacity-10)}.ag-tick42 .ag-row.ag-row-selected .ag-icon{color:var(--t42-link-color)}.ag-tick42 .ag-pinned-left-header,.ag-tick42 .ag-pinned-left-cols-container,.ag-tick42 .ag-pinned-right-header,.ag-tick42 .ag-pinned-right-cols-container{background-color:Rgb(var(--t42-bg-mid))}.ag-tick42 .ag-pinned-left-cols-container .ag-row-selected::before,.ag-tick42 .ag-pinned-left-cols-container.ag-hidden+.ag-center-cols-clipper .ag-row-selected::before{width:2px}.ag-tick42 .ag-row-hover{background-color:var(--t42-color-opacity-10)}.ag-tick42 .ag-row-hover .ag-cell{color:var(--t42-link-color)}.ag-tick42 .ag-row-hover .ag-loading .ag-icon-loading::after{background:Rgb(var(--t42-bg-light))}.ag-tick42 .ag-row-hover a{border-bottom-color:var(--t42-content-color);color:var(--t42-link-color)}.ag-tick42 .ag-row-hover a:hover{border-bottom-style:solid}.ag-tick42 .ag-header-row:last-of-type{border-bottom:var(--t42-border)}.ag-tick42 .ag-header-cell,.ag-tick42 .ag-header-group-cell{padding:0 0.25rem;border-top:var(--t42-border);border-left:var(--t42-border);color:Hsl(var(--t42-content-color-base), calc(var(--t42-content-color-l) - 20%))}.ag-tick42 .ag-header-cell:first-of-type,.ag-tick42 .ag-header-group-cell:first-of-type{border-left:0}.ag-tick42 .ag-header-cell .ag-header-cell-label,.ag-tick42 .ag-header-cell .ag-header-group-cell-label,.ag-tick42 .ag-header-group-cell .ag-header-cell-label,.ag-tick42 .ag-header-group-cell .ag-header-group-cell-label{font-weight:normal;font-size:83.3%;line-height:1.875rem;text-transform:uppercase}.ag-tick42 .ag-header-cell .ag-header-select-all,.ag-tick42 .ag-header-group-cell .ag-header-select-all{margin-right:0.5rem}.ag-tick42 .ag-header-cell-moving{background-color:Hsl(var(--t42-bg-light-base), calc(var(--t42-bg-light-l) + 5%))}.ag-tick42 .ag-cell-inline-editing{padding-top:0}.ag-tick42 .ag-cell-edit-input{border-top:0;border-bottom:0;border-radius:0}.ag-tick42 .ag-icon{font-family:inherit}.ag-tick42 .ag-icon::before{content:""}.ag-tick42 .ag-react-container .btn-icon{margin-bottom:0.125rem;padding:0 0.5rem}.ag-tick42 .ag-tabs-header{display:flex;height:1.875rem;border-bottom:var(--t42-border);border-bottom-width:0.063rem}.ag-tick42 .ag-tabs-header .ag-tab{display:flex;align-items:center;justify-content:center;width:1.875rem;height:1.875rem;color:var(--primary);cursor:pointer}.ag-tick42 .ag-tabs-header .ag-tab.ag-tab-selected{background-color:var(--primary)}.ag-tick42 .ag-tabs-header .ag-tab.ag-tab-selected .ag-icon{background-color:var(--white)}.ag-tick42 .ag-tabs-body{max-height:280px;overflow:auto}.ag-tick42 .ag-menu,.ag-tick42 .ag-tool-panel{z-index:1040;border:var(--t42-border);border-radius:0;overflow:initial;background-color:rgba(var(--t42-bg-light), 0.75);box-shadow:var(--t42-shadow);backdrop-filter:var(--backdrop-filter)}.ag-tick42 .ag-menu .ag-column-select-column,.ag-tick42 .ag-menu .ag-column-select-column-group,.ag-tick42 .ag-tool-panel .ag-column-select-column,.ag-tick42 .ag-tool-panel .ag-column-select-column-group{display:flex;align-items:center;margin-left:0;line-height:2rem;cursor:pointer}.ag-tick42 .ag-menu .ag-column-select-column .ag-column-select-checkbox:hover,.ag-tick42 .ag-menu .ag-column-select-column-group .ag-column-select-checkbox:hover,.ag-tick42 .ag-tool-panel .ag-column-select-column .ag-column-select-checkbox:hover,.ag-tick42 .ag-tool-panel .ag-column-select-column-group .ag-column-select-checkbox:hover{color:var(--t42-link-color)}.ag-tick42 .ag-menu .ag-column-select-column:hover,.ag-tick42 .ag-menu .ag-column-select-column-group:hover,.ag-tick42 .ag-tool-panel .ag-column-select-column:hover,.ag-tick42 .ag-tool-panel .ag-column-select-column-group:hover{color:Hsl(var(--t42-content--base), 100%);background-color:var(--t42-color-opacity-10)}.ag-tick42 .ag-menu .ag-column-select-header,.ag-tick42 .ag-tool-panel .ag-column-select-header{padding:0.5rem}.ag-tick42 .ag-menu .ag-column-select-column-label,.ag-tick42 .ag-tool-panel .ag-column-select-column-label{margin-left:0.25rem}.ag-tick42 .ag-tab-body{max-height:220px;overflow:auto}.ag-tick42 .ag-tab-body .ag-set-filter-list{height:9rem}.ag-tick42 .ag-tab-body input{border:var(--t42-border)}.ag-tick42 .ag-tab-body input:focus{border-color:var(--primary)}.ag-tick42 .ag-menu-option{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:color;line-height:2rem;cursor:pointer}.ag-tick42 .ag-menu-option .ag-menu-option-icon{color:var(--t42-content-color)}.ag-tick42 .ag-menu-option .ag-menu-option-icon,.ag-tick42 .ag-menu-option .ag-menu-option-popup-pointer{width:2rem;color:var(--t42-content-color);text-align:center}.ag-tick42 .ag-menu-option .ag-menu-option-icon.ag-menu-option-popup-pointer,.ag-tick42 .ag-menu-option .ag-menu-option-icon:hover,.ag-tick42 .ag-menu-option .ag-menu-option-popup-pointer.ag-menu-option-popup-pointer,.ag-tick42 .ag-menu-option .ag-menu-option-popup-pointer:hover{color:var(--t42-content-color)}.ag-tick42 .ag-menu-option .ag-menu-option-icon.ag-menu-option-popup-pointer .ag-icon,.ag-tick42 .ag-menu-option .ag-menu-option-icon:hover .ag-icon,.ag-tick42 .ag-menu-option .ag-menu-option-popup-pointer.ag-menu-option-popup-pointer .ag-icon,.ag-tick42 .ag-menu-option .ag-menu-option-popup-pointer:hover .ag-icon{color:var(--t42-content-color)}.ag-tick42 .ag-menu-option.ag-menu-option-active{color:var(--t42-link-color);background-color:var(--t42-color-opacity-10)}.ag-tick42 .ag-menu-option.ag-menu-option-active .ag-icon{color:var(--t42-content-color)}.ag-tick42 .ag-menu-separator{border-bottom:var(--t42-border);border-bottom-color:var(--t42-color-opacity-10)}.ag-tick42 .ag-menu-column-select-wrapper,.ag-tick42 .ag-primary-cols-list-panel{height:auto}.ag-tick42 .ag-tool-panel .ag-pivot-mode{padding-top:0.5rem}.ag-tick42 .ag-column-tool-panel-column{padding:0 0.25rem}.ag-tick42 .ag-column-tool-panel-column .ag-icon{margin:0 0.25rem}.ag-tick42 .ag-column-tool-panel-column-label,.ag-tick42 span.ag-column-tool-panel-column-group{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;padding-left:0.25rem}.ag-tick42 .ag-column-tool-panel-column-group .ag-icon{margin:0 0.25rem 0 0}.ag-tick42 .ag-root+.ag-tool-panel{box-shadow:none}.ag-tick42 .ag-row-group-leaf-indent{margin-left:24px}.ag-tick42 .ag-group-expanded,.ag-tick42 .ag-group-contracted{display:flex;align-items:center;min-width:0.75rem;height:100%;margin-right:0.5rem}.ag-tick42 .ag-group-value .ag-react-container{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;display:inline;font-size:87.5%}.ag-tick42 .ag-popup-editor{box-shadow:var(--t42-shadow)}.ag-tick42 .ag-rich-select{border:var(--t42-border);border-radius:0;overflow-y:auto;background-color:Rgb(var(--t42-bg-light), 1)}.ag-tick42 .ag-rich-select-row{padding-left:0.75rem}.ag-tick42 .ag-rich-select-row-selected{background:var(--t42-color-opacity-10)}.ag-tick42 .ag-rich-select-value{position:relative;height:2rem;padding-left:0.75rem;border-bottom:var(--t42-border);line-height:2rem}.ag-tick42 .ag-rich-select-value::before{position:absolute;top:0;bottom:0;left:0;width:3px;background-color:var(--primary);content:""}.ag-tick42 .icon-window-maximize::before,.ag-tick42 .icon-window-minimize::before,.ag-tick42 .icon-window-ok::before{font-size:0.813rem}.ag-tick42 .ag-column-drop{border-top:var(--t42-border)}.ag-tick42 .ag-column-drop.ag-column-drop-horizontal{display:flex;height:1.875rem}.ag-tick42 .ag-column-drop.ag-column-drop-horizontal div{display:flex;align-items:center}.ag-tick42 .ag-column-drop.ag-column-drop-horizontal div:first-of-type{margin-right:0.25rem}.ag-tick42 .ag-column-drop .ag-column-drop-empty-message{align-self:center}.ag-tick42 .ag-column-drop .ag-column-drop-cell{display:flex;height:1.125rem;margin:0.125rem 0.25rem;padding:0 0.125rem 0 0.25rem;border-radius:0.25rem;background-color:Rgb(var(--t42-bg-light))}.ag-tick42 .ag-column-drop .ag-column-drop-cell .ag-column-drop-cell-text{padding:0 0.25rem;line-height:1.125rem}.ag-tick42 .ag-column-drop.ag-column-drop-vertical div{justify-content:start}.ag-tick42 .ag-column-drop.ag-column-drop-vertical .ag-icon-group{margin:0 0.25rem}.ag-tick42 .ag-right-arrow{width:1.5rem;padding:0 0.25rem;overflow:hidden;text-indent:-999px;background-color:var(--t42-content-color);transform:rotate(-90deg);-webkit-mask-image:var(--t42-select-indicator)}.ag-tick42 .ag-right-arrow::before{position:absolute;text-indent:999px}.ag-tick42 .ag-group-checkbox{display:flex;align-items:center;width:1rem;height:100%;margin-right:0.5rem}.ag-tick42 .ag-group-checkbox .ag-icon{width:0.875rem;height:0.875rem}.ag-tick42 .ag-group-checkbox:empty{width:initial}.ag-tick42 .ag-ltr .ag-toolpanel-indent-1{padding-left:1rem}.ag-tick42 .ag-ltr .ag-toolpanel-indent-2{padding-left:2rem}.ag-tick42 .ag-ltr .ag-toolpanel-indent-3{padding-left:3rem}.ag-tick42 .ag-ltr .ag-row-group-indent-1{padding-left:calc(1 * 1.45rem)}.ag-tick42 .ag-ltr .ag-row-group-indent-2{padding-left:calc(2 * 1.45rem)}.ag-tick42 .ag-ltr .ag-row-group-indent-3{padding-left:calc(3 * 1.45rem)}.ag-menu .ag-filter-checkbox{min-width:2rem}.ag-menu .ag-icon-checkbox-checked::after{width:0.625rem;height:0.625rem}.ag-menu .ag-column-group-icons{width:1.5rem}.ag-menu .ag-labeled.ag-label-align-right>div{margin-left:0.25rem}.ag-filter-panel{width:100%}.loading-filter{background-color:rgba(var(--t42-bg-light), 0.75);backdrop-filter:var(--backdrop-filter)}#selectAllContainer,.ag-set-filter-item{display:flex;align-items:center;cursor:pointer}#selectAllContainer .ag-filter-value,#selectAllContainer .ag-set-filter-item-value,.ag-set-filter-item .ag-filter-value,.ag-set-filter-item .ag-set-filter-item-value{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}#selectAllContainer .ag-set-filter-item-value,.ag-set-filter-item .ag-set-filter-item-value{margin-left:0.25rem}.ag-filter-checkbox{justify-content:center;min-width:2rem;color:var(--primary)}.ag-set-filter-item:hover,.ag-filter-header-container:hover label{color:var(--t42-link-color);background-color:var(--t42-color-opacity-10)}.ag-set-filter-item:hover .ag-icon,.ag-filter-header-container:hover label .ag-icon{color:var(--t42-link-color)}.ag-input-text-wrapper{padding:0.25rem 0.25rem 0}.ag-primary-cols-header-panel{align-items:center;padding:0.25rem 0.25rem 0.25rem 0}.ag-primary-cols-header-panel div:nth-child(1){width:1.25rem}.ag-primary-cols-header-panel div:nth-child(2){width:1rem;margin-right:0.25rem}.ag-filter-toolpanel-header{display:flex}.ag-filter-toolpanel-header .ag-header-cell-text{padding:0 0.25rem}.ag-filter-condition{justify-content:space-evenly;padding:0.5rem 0}.ag-filter-condition .ag-labeled.ag-label-align-right div{margin-left:0}.ag-radio-button-label{position:relative;color:var(--t42-content-color-muted);cursor:pointer;user-select:none}.ag-radio-button-input-wrapper::before{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, border;position:absolute;left:-1.125rem;display:block;width:0.875rem;height:0.875rem;border:0.0625rem solid var(--t42-content-color-muted);border-radius:50%;cursor:pointer;content:"";pointer-events:all}.ag-radio-button-input-wrapper::after{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, border;position:absolute;left:-0.875rem;display:block;width:0.375rem;height:0.375rem;border-radius:50%;color:var(--white);background-image:none;transform:scale(0);opacity:0;content:""}.ag-radio-button-input-wrapper:focus{border-color:var(--primary)}.ag-radio-button-input-wrapper.ag-checked::before{border-color:var(--t42-color-opacity-30);background-color:var(--primary)}.ag-radio-button-input-wrapper.ag-checked::after{background-color:var(--white);transform:scale(1);opacity:1}.ag-list{z-index:1100;background-color:rgba(var(--t42-bg-mid), 0.7);backdrop-filter:var(--backdrop-filter)}.ag-list .ag-list-item{padding:0 0.5rem;line-height:2rem;cursor:pointer}.ag-list .ag-list-item:hover{background-color:Rgb(var(--t42-bg-light))}.ag-picker-field-wrapper{height:2rem;padding:0 0.5rem;line-height:2rem;cursor:pointer}.ag-column-select-header-icon{display:flex;align-items:center}.ag-column-select-header .ag-text-field-input{height:1.875rem;line-height:1.875rem}.ag-filter-list-panel .ag-filter-toolpanel-expand{margin:0 0.25rem}.ag-filter-list-panel .ag-filter-toolpanel-group-container,.ag-filter-list-panel .ag-filter-toolpanel-instance-filter{padding-left:0.25rem}.ag-side-bar{position:relative}.ag-side-bar .ag-side-bar-right .ag-tool-panel-horizontal-resize{left:-0.375rem}.ag-side-bar>div:first-child{border:var(--t42-border);background-color:var(--t42-color-opacity-10)}.ag-side-bar .ag-pivot-mode-select{display:flex;padding:0.25rem;border-bottom:var(--t42-border)}.ag-side-bar .ag-pivot-mode-select label{margin:0 0 0 0.5rem}.ag-side-bar .ag-pivot-mode-select .ag-checkbox-label{padding-left:0.25rem}.ag-side-bar .ag-side-buttons div.ag-side-button button{width:1rem;height:1rem;padding:0;border:0.0625rem solid transparent;color:Hsl(var(--t42-content-color-base), 100%);background-color:transparent}.ag-side-bar .ag-side-buttons div.ag-side-button button:hover{color:Hsl(var(--t42-content-color-base), 100%);background-color:Rgb(var(--t42-bg-dark))}.ag-side-bar .ag-side-buttons div.ag-side-button button>span{display:none}.ag-side-bar .ag-side-buttons div.ag-side-button.ag-selected button{border-color:var(--t42-color-opacity-30);background-color:var(--primary)}.ag-side-bar .ag-side-buttons div.ag-side-button.ag-selected button [class*="ag-icon-"]{background-color:var(--white)}.ag-side-bar .ag-icon-checkbox-checked::after{width:0.625rem;height:0.625rem}.ag-side-bar .ag-column-panel,.ag-side-bar .ag-filter-panel{padding-left:0.25rem}.ag-side-bar .ag-filter-checkbox{margin-right:0.25rem}.ag-tool-panel-wrapper{border-top:var(--t42-border);border-bottom:var(--t42-border)}.ag-tool-panel-wrapper .ag-set-filter-list{width:100%;height:auto}.ag-tool-panel-wrapper .ag-column-select-checkbox,.ag-tool-panel-wrapper .ag-column-select-header-checkbox{margin:0 0.25rem}.ag-tool-panel-horizontal-resize{top:initial;width:0.188rem;background-color:var(--t42-color-opacity-10)}.ag-column-panel,.ag-column-select-panel,.ag-column-drop-vertical,.ag-column-drop-list{display:block;min-height:initial;max-height:initial;overflow:visible}.ag-column-panel input,.ag-column-select-panel input,.ag-column-drop-vertical input,.ag-column-drop-list input{border:var(--t42-border)}.ag-column-panel input:focus,.ag-column-select-panel input:focus,.ag-column-drop-vertical input:focus,.ag-column-drop-list input:focus{border-color:var(--primary)}[class*="ag-icon-"],.icon-check-1,.icon-check-empty,.icon-resize-horizontal{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:color, transform;display:block;width:0.75rem;height:0.75rem;margin:0 auto;background-color:var(--t42-content-color);background-image:none;mask-repeat:no-repeat;mask-position:center;cursor:pointer}[class*="ag-icon-"]:hover,.icon-check-1:hover,.icon-check-empty:hover,.icon-resize-horizontal:hover{background-color:var(--t42-link-color)}.ag-menu-option-disabled{color:var(--t42-content-color-disabled)}.ag-menu-option-disabled .ag-icon{background-color:var(--t42-content-color-disabled)}.ag-icon-menu{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M475.4,384v36.4c0,5.1-1.7,9.4-5.1,12.8s-7.9,5.3-13.3,5.6H55c-5.1,0-9.4-1.9-12.8-5.6c-3.4-3.8-5.3-8-5.6-12.8V384 c0-5.1,1.9-9.4,5.6-12.8c3.8-3.4,8-5.3,12.8-5.6h401.9c5.1,0,9.6,1.9,13.3,5.6C474,375,475.7,379.2,475.4,384z M475.4,237.6v36.9 c0,4.8-1.7,9-5.1,12.8s-7.9,5.5-13.3,5.1H55c-5.1,0-9.4-1.7-12.8-5.1s-5.3-7.7-5.6-12.8v-36.9c0-4.8,1.9-9,5.6-12.8 c3.8-3.8,8-5.5,12.8-5.1h401.9c5.1,0,9.6,1.7,13.3,5.1S475.7,232.5,475.4,237.6z M475.4,91.7V128c0,4.8-1.7,9-5.1,12.8 s-7.9,5.6-13.3,5.6H55c-5.1,0-9.4-1.9-12.8-5.6s-5.3-8-5.6-12.8V91.7c0-5.1,1.9-9.6,5.6-13.3c3.8-3.8,8-5.5,12.8-5.1h401.9 c5.1,0,9.6,1.7,13.3,5.1S475.7,86.2,475.4,91.7z%27/%3E%3C/svg%3E%0A")}.ag-header-icon{margin-left:0.125rem}.ag-header-icon .ag-icon-menu{line-height:1.875rem}.ag-icon-asc{-webkit-mask-image:var(--t42-select-indicator);transform:rotate(180deg)}.ag-icon-desc{-webkit-mask-image:var(--t42-select-indicator);margin-bottom:2px}.ag-icon-filter{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 16 16%27%3E%3Cpath d=%27M14.9,1.4c0.1,0.3,0.1,0.5-0.1,0.7L9.9,7v7.4c0,0.3-0.1,0.5-0.4,0.6C9.4,15,9.4,15,9.3,15c-0.2,0-0.3-0.1-0.4-0.2l-2.5-2.5 c-0.1-0.1-0.2-0.3-0.2-0.4V7L1.2,2.1C1,1.9,0.9,1.7,1.1,1.4C1.2,1.1,1.4,1,1.7,1h12.7C14.6,1,14.8,1.1,14.9,1.4L14.9,1.4z%27/%3E%3C/svg%3E")}.ag-icon-none{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 16 16%27%3E%3Cpath d=%27M1 6L5 2Q6 1 7 2L11 6Q11 7 10 7L2 7Q1 7 1 6M2 8Q1 8 1 9L5 13Q6 14 7 13L11 9Q11 8 10 8L2 8%27/%3E%3C/svg%3E%0A")}.ag-icon-indeterminate,.ag-icon-checkbox-indeterminate,.ag-icon-checkbox-indeterminate-readonly,.ag-icon-checkbox-unchecked,.ag-icon-checkbox-unchecked-readonly,.ag-icon-checkbox-checked-readonly,.ag-icon-checkbox-checked,.icon-check-1,.icon-check-empty,.ag-checkbox-input-wrapper,.ag-toggle-button-input-wrapper{position:relative;padding:0;color:var(--t42-content-color-muted);background-color:transparent;cursor:pointer;user-select:none}.ag-icon-indeterminate::before,.ag-icon-checkbox-indeterminate::before,.ag-icon-checkbox-indeterminate-readonly::before,.ag-icon-checkbox-unchecked::before,.ag-icon-checkbox-unchecked-readonly::before,.ag-icon-checkbox-checked-readonly::before,.ag-icon-checkbox-checked::before,.icon-check-1::before,.icon-check-empty::before,.ag-checkbox-input-wrapper::before,.ag-toggle-button-input-wrapper::before{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, border-color;display:block;width:100%;height:100%;border:var(--t42-border);border-color:var(--t42-content-color);cursor:pointer;content:"";pointer-events:all}.ag-icon-indeterminate:focus,.ag-icon-checkbox-indeterminate:focus,.ag-icon-checkbox-indeterminate-readonly:focus,.ag-icon-checkbox-unchecked:focus,.ag-icon-checkbox-unchecked-readonly:focus,.ag-icon-checkbox-checked-readonly:focus,.ag-icon-checkbox-checked:focus,.icon-check-1:focus,.icon-check-empty:focus,.ag-checkbox-input-wrapper:focus,.ag-toggle-button-input-wrapper:focus{border-color:var(--primary)}.ag-icon-indeterminate:hover,.ag-icon-checkbox-indeterminate:hover,.ag-icon-checkbox-indeterminate-readonly:hover,.ag-icon-checkbox-unchecked:hover,.ag-icon-checkbox-unchecked-readonly:hover,.ag-icon-checkbox-checked-readonly:hover,.ag-icon-checkbox-checked:hover,.icon-check-1:hover,.icon-check-empty:hover,.ag-checkbox-input-wrapper:hover,.ag-toggle-button-input-wrapper:hover{background-color:transparent}.ag-icon-checkbox-indeterminate,.ag-icon-checkbox-indeterminate-readonly,.ag-icon-checkbox-checked,.ag-icon-checkbox-checked-readonly,.icon-check-empty,.ag-checkbox-input-wrapper.ag-indeterminate,.ag-checkbox-input-wrapper.ag-checked,.ag-toggle-button-input-wrapper.ag-checked{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background, color}.ag-icon-checkbox-indeterminate::before,.ag-icon-checkbox-indeterminate-readonly::before,.ag-icon-checkbox-checked::before,.ag-icon-checkbox-checked-readonly::before,.icon-check-empty::before,.ag-checkbox-input-wrapper.ag-indeterminate::before,.ag-checkbox-input-wrapper.ag-checked::before,.ag-toggle-button-input-wrapper.ag-checked::before{border:0.0625rem solid var(--t42-color-opacity-30);background:var(--primary)}.ag-icon-checkbox-indeterminate::after,.ag-icon-checkbox-indeterminate-readonly::after,.ag-icon-checkbox-checked::after,.ag-icon-checkbox-checked-readonly::after,.icon-check-empty::after,.ag-checkbox-input-wrapper.ag-indeterminate::after,.ag-checkbox-input-wrapper.ag-checked::after,.ag-toggle-button-input-wrapper.ag-checked::after{position:absolute;top:0.063rem;left:0.063rem;display:block;width:0.75rem;height:0.75rem;background:var(--white);content:""}.ag-icon-checkbox-checked::after,.ag-icon-checkbox-checked-readonly::after,.icon-check-empty::after,.ag-checkbox-input-wrapper.ag-checked::after,.ag-toggle-button-input-wrapper.ag-checked::after{-webkit-mask-image:url("data:image/svg+xml,%3Csvg version=%271.1%27 xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M477.44 152.832q0 11.264-8.192 19.456l-245.76 245.76q-8.192 7.68-19.456 7.68t-19.456-7.68l-142.336-142.336q-7.68-8.192-7.68-19.456t7.68-19.456l38.912-38.912q8.192-8.192 19.456-8.192t19.456 8.192l83.968 84.48 187.392-187.904q8.192-8.192 19.456-8.192t19.456 8.192l38.912 38.912q8.192 7.68 8.192 19.456z%27%3E%3C/path%3E%3C/svg%3E%0A")}.ag-icon-checkbox-indeterminate::after,.ag-icon-checkbox-indeterminate-readonly::after,.ag-checkbox-input-wrapper.ag-indeterminate::after{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 -1 5 6%27%3E%3Cpath d=%27M 1 1 A 1 1 0 0 0 1 2 L 4 2 A 1 1 0 0 0 4 1 L 1 1%27/%3E%3C/svg%3E%0A")}.ag-checkbox-input-wrapper.ag-indeterminate::after{top:0.125rem;left:0.125rem}.ag-checkbox-input-wrapper::before,.ag-toggle-button-input-wrapper::before{width:0.875rem;height:0.875rem}.ag-checkbox-input-wrapper .ag-checkbox-input,.ag-checkbox-input-wrapper .ag-toggle-button-input,.ag-toggle-button-input-wrapper .ag-checkbox-input,.ag-toggle-button-input-wrapper .ag-toggle-button-input{position:absolute;z-index:2;width:0.875rem;height:0.875rem}.ag-icon-columns{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M146.432 374.784v55.296q0 11.264-8.192 18.944t-19.456 8.192h-91.136q-11.776 0-19.456-8.192t-8.192-18.944v-55.296q0-11.264 8.192-19.456t19.456-7.68h91.136q11.776 0 19.456 7.68t8.192 19.456zM146.432 228.864v54.784q0 11.264-8.192 19.456t-19.456 7.68h-91.136q-11.776 0-19.456-7.68t-8.192-19.456v-54.784q0-11.776 8.192-19.456t19.456-8.192h91.136q11.776 0 19.456 8.192t8.192 19.456zM329.216 374.784v55.296q0 11.264-8.192 18.944t-19.456 8.192h-91.136q-11.776 0-19.456-8.192t-8.192-18.944v-55.296q0-11.264 8.192-19.456t19.456-7.68h91.136q11.776 0 19.456 7.68t8.192 19.456zM146.432 82.432v54.784q0 11.264-8.192 19.456t-19.456 8.192h-91.136q-11.776 0-19.456-8.192t-8.192-19.456v-54.784q0-11.264 8.192-19.456t19.456-8.192h91.136q11.776 0 19.456 8.192t8.192 19.456zM329.216 228.864v54.784q0 11.264-8.192 19.456t-19.456 7.68h-91.136q-11.776 0-19.456-7.68t-8.192-19.456v-54.784q0-11.776 8.192-19.456t19.456-8.192h91.136q11.776 0 19.456 8.192t8.192 19.456zM512 374.784v55.296q0 11.264-8.192 18.944t-19.456 8.192h-91.136q-11.264 0-19.456-8.192t-8.192-18.944v-55.296q0-11.264 8.192-19.456t19.456-7.68h91.136q11.776 0 19.456 7.68t8.192 19.456zM329.216 82.432v54.784q0 11.264-8.192 19.456t-19.456 8.192h-91.136q-11.776 0-19.456-8.192t-8.192-19.456v-54.784q0-11.264 8.192-19.456t19.456-8.192h91.136q11.776 0 19.456 8.192t8.192 19.456zM512 228.864v54.784q0 11.264-8.192 19.456t-19.456 7.68h-91.136q-11.264 0-19.456-7.68t-8.192-19.456v-54.784q0-11.776 8.192-19.456t19.456-8.192h91.136q11.776 0 19.456 8.192t8.192 19.456zM512 82.432v54.784q0 11.264-8.192 19.456t-19.456 8.192h-91.136q-11.264 0-19.456-8.192t-8.192-19.456v-54.784q0-11.264 8.192-19.456t19.456-8.192h91.136q11.776 0 19.456 8.192t8.192 19.456z%27%3E%3C/path%3E%3C/svg%3E")}.ag-icon-pin{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M228.4,228.6v-128c0-2.7-0.9-4.9-2.6-6.7s-3.9-2.6-6.7-2.6c-2.7,0-4.9,0.9-6.7,2.6c-1.7,1.7-2.6,3.9-2.6,6.7v128 c0,2.7,0.9,4.9,2.6,6.7c1.7,1.7,3.9,2.6,6.7,2.6c2.7,0,4.9-0.9,6.7-2.6S228.4,231.3,228.4,228.6z M420.4,329.5c0,4.8-1.9,9-5.6,12.8 c-3.8,3.8-8,5.5-12.8,5.1H279.6l-14.8,138.2c-0.3,2.4-1.4,4.3-3.1,5.6c-1.7,1.4-3.6,2.2-5.6,2.6h-0.5c-5.1,0-8-2.6-8.7-7.7 l-22-138.8H109.6c-5.1,0-9.4-1.7-12.8-5.1c-3.4-3.4-5.3-7.7-5.6-12.8c0-23.6,7.5-44.7,22.5-63.5s31.9-28.2,50.7-28.2V91.4 c-9.9,0-18.4-3.6-25.6-10.8c-7.2-7.2-10.9-15.7-11.3-25.6s3.4-18.4,11.3-25.6c7.9-7.2,16.4-10.9,25.6-11.3h182.8 c9.9,0,18.4,3.8,25.6,11.3s10.8,16,10.8,25.6s-3.6,18.1-10.8,25.6S357,91.7,347.1,91.4v146.4c18.8,0,35.7,9.4,50.7,28.2 C412.8,284.8,420.4,305.9,420.4,329.5L420.4,329.5z%27/%3E%3C/svg%3E")}.ag-icon-small-right,.ag-icon-small-down{width:0.65rem;height:0.65rem;-webkit-mask-image:var(--t42-select-indicator);transform:rotate(-90deg)}.ag-icon-small-down{transform:rotate(0)}.ag-icon-tick{-webkit-mask-image:url("data:image/svg+xml,%3Csvg version=%271.1%27 xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M477.44 152.832q0 11.264-8.192 19.456l-245.76 245.76q-8.192 7.68-19.456 7.68t-19.456-7.68l-142.336-142.336q-7.68-8.192-7.68-19.456t7.68-19.456l38.912-38.912q8.192-8.192 19.456-8.192t19.456 8.192l83.968 84.48 187.392-187.904q8.192-8.192 19.456-8.192t19.456 8.192l38.912 38.912q8.192 7.68 8.192 19.456z%27%3E%3C/path%3E%3C/svg%3E%0A")}.ag-icon-copy{-webkit-mask-image:url("data:image/svg+xml,")}.ag-icon-csv,.ag-icon-excel{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M0 0zq0-7.7-5.1-12.8zM475.3 356.6v91.6q0 11.3-8.2 18.9t-19.5 8.2h-420.4q-11.8 0-19.5-8.2t-8.2-18.9v-91.6q0-11.3 8.2-19.5t19.5-8.2h132.6l38.4 38.9q16.9 16.4 38.9 16.4t38.9-16.4l38.9-38.9h132.6q11.3 0 19.5 8.2t8.2 19.5zM382.1 193.8q5.1 11.8-4.1 20l-128 128q-5.1 5.6-12.8 5.6t-12.8-5.6l-128-128q-8.7-8.2-4.1-20q5.1-10.8 16.9-10.8h73.2v-128q0-7.7 5.6-12.8t12.8-5.6h73.2q7.2 0 12.8 5.6t5.1 12.8v128h73.2q12.3 0 16.9 10.8M347 439A1 1 0 00347 402A1 1 0 00347 439M420 439A1 1 0 00420 402A1 1 0 00420 439zz%27/%3E%3C/svg%3E%0A")}.ag-icon-expanded{-webkit-mask-image:var(--t42-select-indicator);transform:rotate(-90deg)}.ag-icon-contracted{-webkit-mask-image:var(--t42-select-indicator);transform:rotate(90deg)}.ag-header-expand-icon-collapsed .ag-icon-contracted{margin-bottom:1px;transform:rotate(90deg);-webkit-mask-image:var(--t42-select-indicator)}.ag-icon-paste{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M219.648 475.648h256v-183.296h-119.296q-11.264 0-18.944-7.68t-8.192-19.456v-118.784h-109.568v329.216zM292.352 64v-18.432q0-3.584-2.56-6.144t-6.144-3.072h-201.216q-3.584 0-6.656 3.072t-2.56 6.144v18.432q0 3.584 2.56 6.656t6.656 2.56h201.216q3.584 0 6.144-2.56t2.56-6.656zM365.568 256h85.504l-85.504-85.504v85.504zM512 292.352v192q0 11.776-8.192 19.456t-19.456 8.192h-273.92q-11.776 0-19.456-8.192t-8.192-19.456v-45.568h-155.136q-11.776 0-19.456-8.192t-8.192-18.944v-384q0-11.776 8.192-19.456t19.456-8.192h310.784q11.264 0 19.456 8.192t7.68 19.456v93.696q6.144 3.584 10.24 7.68l116.736 116.736q8.192 7.68 13.824 21.504t5.632 25.088z%27%3E%3C/path%3E%3C/svg%3E%0A")}.ag-icon-arrows{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M512 256q0 7.168-5.632 12.8l-72.704 73.216q-5.632 5.632-13.312 5.632t-12.8-5.632-5.12-12.8v-36.864h-110.080v110.080h36.864q7.168 0 12.8 5.12t5.632 12.8-5.632 12.8l-73.216 73.216q-5.12 5.632-12.8 5.632t-12.8-5.632l-73.216-73.216q-5.632-5.12-5.632-12.8t5.632-12.8 12.8-5.12h36.864v-110.080h-110.080v36.864q0 7.168-5.12 12.8t-12.8 5.632-12.8-5.632l-73.216-73.216q-5.632-5.632-5.632-12.8t5.632-12.8l73.216-73.216q5.12-5.632 12.8-5.632t12.8 5.632 5.12 12.8v36.864h110.080v-110.080h-36.864q-7.168 0-12.8-5.12t-5.632-12.8 5.632-13.312l73.216-72.704q5.632-5.632 12.8-5.632t12.8 5.632l73.216 72.704q5.632 5.632 5.632 13.312t-5.632 12.8-12.8 5.12h-36.864v110.080h110.080v-36.864q0-7.168 5.12-12.8t12.8-5.632 13.312 5.632l72.704 73.216q5.632 5.12 5.632 12.8z%27%3E%3C/path%3E%3C/svg%3E%0A")}.ag-icon-not-allowed{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27m 182.8 238.1 h 145.9 v -55.3 c 0 -20.1 -7.2 -37.4 -21.5 -51.7 s -31.6 -21.3 -51.7 -21 c -20.1 0.3 -37.4 7.3 -51.7 21 s -21.3 30.9 -21 51.7 l -0 55.3 l 0 0 z m 237.6 27.1 v 164.9 c 0 7.5 -2.7 13.8 -8.2 18.9 s -11.9 7.9 -19.5 8.2 h -273.9 c -7.9 0 -14.3 -2.7 -19.5 -8.2 c -5.1 -5.5 -7.9 -11.8 -8.2 -18.9 v -164.9 c 0 -7.5 2.7 -14 8.2 -19.5 s 11.9 -8 19.5 -7.7 h 8.7 v -55.3 c 0 -34.8 12.6 -64.9 37.9 -90.1 s 55.3 -37.9 90.1 -37.9 s 65 12.6 90.6 37.9 s 38.1 55.3 37.4 90.1 v 55.3 h 9.2 c 7.9 0 14.3 2.6 19.5 7.7 s 7.8 11.7 8.2 19.5 z%27/%3E%3C/svg%3E")}.ag-icon-eye-slash{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M 475.6 256.3 q -43.5 -67.6 -109.1 -100.9 q 17.4 29.7 17.4 64 q 0 52.7 -37.4 90.6 t -90.6 37.4 t -90.6 -37.4 t -37.4 -90.6 q 0 -34.3 17.4 -64 q -65.5 33.3 -109.1 100.9 q 38.4 58.4 95.7 93.2 t 123.9 34.8 t 124.4 -34.8 t 95.2 -93.2 z M 269.8 146.2 q 0 -5.6 -4.1 -9.7 t -9.7 -3.6 q -35.8 0 -61.4 25.6 t -25.6 60.9 q 0 5.6 4.1 9.7 t 9.7 4.1 t 9.7 -4.1 t 4.1 -9.7 q 0 -24.6 17.4 -42 t 42 -17.4 q 5.6 0 9.7 -4.1 t 4.1 -9.7 z M 512 256.3 q 0 9.7 -5.6 19.5 q -39.9 66 -107.5 105.5 t -142.8 39.4 t -142.8 -39.4 t -107.5 -105.5 q -5.6 -9.7 -5.6 -19.5 t 5.6 -20 q 39.9 -65.5 107.5 -105 t 142.8 -39.9 t 142.8 39.9 t 107.5 105 q 5.6 10.2 5.6 20 z%27%3E%3C/path%3E%3C/svg%3E%0A")}.ag-icon-group{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M146.4 374.8v55.3q0 11.3-8.2 18.9t-19.5 8.2h-91.1q-11.8 0-19.5-8.2t-8.2-18.9v-55.3q0-11.3 8.2-19.5t19.5-7.7h91.1q11.8 0 19.5 7.7t8.2 19.5zM146.4 228.9v54.8q0 11.3-8.2 19.5t-19.5 7.7h-91.1q-11.8 0-19.5-7.7t-8.2-19.5v-54.8q0-11.8 8.2-19.5t19.5-8.2h91.1q11.8 0 19.5 8.2t8.2 19.5zM512 374.8v55.3q0 11.3-8.2 18.9t-19.5 8.2h-273.9q-11.8 0-19.5-8.2t-8.2-18.9v-55.3q0-11.3 8.2-19.5t19.5-7.7h273.9q11.8 0 19.5 7.7t8.2 19.5zM146.4 82.4v54.8q0 11.3-8.2 19.5t-19.5 8.2h-91.1q-11.8 0-19.5-8.2t-8.2-19.5v-54.8q0-11.3 8.2-19.5t19.5-8.2h91.1q11.8 0 19.5 8.2t8.2 19.5zM512 228.9v54.8q0 11.3-8.2 19.5t-19.5 7.7h-273.9q-11.8 0-19.5-7.7t-8.2-19.5v-54.8q0-11.8 8.2-19.5t19.5-8.2h273.9q11.8 0 19.5 8.2t8.2 19.5zM512 82.4v54.8q0 11.3-8.2 19.5t-19.5 8.2h-273.9q-11.8 0-19.5-8.2t-8.2-19.5v-54.8q0-11.3 8.2-19.5t19.5-8.2h273.9q11.8 0 19.5 8.2t8.2 19.5z%27%3E%3C/path%3E%3C/svg%3E%0A")}.ag-icon-grip{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 16 16%27%3E%3Cpath d=%27M4 3L6 3L6 5L4 5L4 3M4 7L6 7L6 9L4 9L4 7M4 11L6 11L6 13L4 13L4 11M8 3L10 3L10 5L8 5L8 3M8 7L10 7L10 9L8 9L8 7M8 11L10 11L10 13L8 13L8 11%27/%3E%3C/svg%3E%0A");margin:0}.ag-icon-tree-open{-webkit-mask-image:var(--t42-select-indicator);transform:rotate(180deg)}.ag-icon-tree-closed{-webkit-mask-image:var(--t42-select-indicator);transform:rotate(270deg)}.ag-icon-tree-indeterminate{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 -1 5 6%27%3E%3Cpath d=%27M 1 1 A 1 1 0 0 0 1 2 L 4 2 A 1 1 0 0 0 4 1 L 1 1%27/%3E%3C/svg%3E%0A")}.ag-icon-save{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M 420.6 319.2 V 393 c 0 22.9 -8 42.3 -24.1 58.4 s -35.5 24.1 -58.4 24.1 H 100.6 c -22.9 0 -42.3 -8 -58.4 -24.1 S 18.2 415.8 18.2 393 V 155.4 c 0 -22.5 8 -41.8 24.1 -57.9 S 77.7 73.3 100.6 73 h 72.7 c 2.4 0 4.6 1 6.7 3.1 c 2 2 2.9 4.1 2.6 6.1 c 0 5.1 -2.6 8.2 -7.7 9.2 c -14.7 5.1 -27.3 10.9 -37.9 17.4 c -1.7 0.7 -3.2 1 -4.6 1 h -31.7 c -12.6 0 -23.4 4.4 -32.3 13.3 s -13.5 19.6 -13.8 32.3 V 393 c 0 12.6 4.6 23.4 13.8 32.3 c 9.2 8.9 20 13.5 32.3 13.8 h 237.6 c 12.6 0 23.4 -4.6 32.3 -13.8 c 8.9 -9.2 13.3 -20 13.3 -32.3 V 332 c 0 -3.8 1.7 -6.5 5.1 -8.2 c 5.5 -2.4 10.8 -6 15.9 -10.8 c 2.7 -3.1 6 -3.8 9.7 -2 C 418.6 312.7 420.6 315.5 420.6 319.2 L 420.6 319.2 z M 488.2 177.4 L 378.6 287 c -3.4 3.8 -7.7 5.6 -12.8 5.6 c -2.4 0 -4.8 -0.5 -7.2 -1.5 c -7.5 -3.1 -11.3 -8.7 -11.3 -16.9 v -54.8 h -45.6 c -61.8 0 -103.6 12.5 -125.4 37.4 c -22.5 26.3 -29.5 71.3 -21 135.2 c 0.7 4.4 -1.2 7.7 -5.6 9.7 c -1.7 0.3 -2.9 0.5 -3.6 0.5 c -3.1 0 -5.5 -1.2 -7.2 -3.6 c -2 -2.7 -4.1 -5.6 -6.1 -8.7 c -2 -3.1 -5.8 -9.7 -11.3 -20 c -5.5 -10.2 -10.2 -19.6 -14.3 -28.2 c -4.1 -8.5 -7.7 -19.5 -10.8 -32.8 c -3.1 -13.3 -4.8 -24.9 -5.1 -34.8 c 0 -9.2 0.3 -17.9 1 -26.1 c 0.7 -8.2 2 -16.7 4.1 -25.6 c 2 -8.9 4.6 -17.2 7.7 -25.1 c 3.1 -7.9 7.7 -15.5 13.8 -23 c 6.1 -7.5 12.6 -14.7 19.5 -21.5 s 15.7 -12.6 26.6 -17.4 c 10.9 -4.8 22.9 -9.4 35.8 -13.8 c 13 -4.4 28.2 -7.3 45.6 -8.7 s 36.2 -2.4 56.3 -3.1 h 45.6 V 55 c 0 -8.2 3.8 -13.8 11.3 -16.9 c 2.4 -1 4.8 -1.5 7.2 -1.5 c 4.8 0 9 1.9 12.8 5.6 l 109.6 109.6 c 3.8 3.4 5.6 7.7 5.6 12.8 S 491.9 174 488.2 177.4 L 488.2 177.4 z%27/%3E%3C/svg%3E")}.ag-tooltip{padding:0.125rem 0.5rem;border:0.0625rem solid var(--t42-color-opacity-10);border-radius:0.25rem;background:Rgb(var(--t42-bg-light));box-shadow:var(--t42-shadow)}.ag-icon-cancel{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M366.9 336.4c6.1 6.1 9.2 13.5 9.2 22s-3.1 15.9-9.2 22c-6.1 5.5-13.5 8.2-22 8.2c-8.5 0-15.9-2.7-22-8.2l-67.6-77.8l-67.6 77.8c-6.1 5.5-13.5 8.2-22 8.2c-8.5 0-15.9-2.7-22-8.2c-5.5-6.1-8.2-13.5-8.2-22s2.7-15.9 8.2-22l70.7-79.9l-70.7-80.9c-5.5-6.1-8.2-13.5-8.2-22c0-8.5 2.7-15.9 8.2-22c6.1-5.5 13.5-8.2 22-8.2c8.5 0 15.9 2.7 22 8.2l67.6 77.8l67.6-77.8c6.1-5.5 13.5-8.2 22-8.2c8.5 0 15.9 2.7 22 8.2c6.1 6.1 9.2 13.5 9.2 22c0 8.5-3.1 15.9-9.2 22l-70.7 80.9L366.9 336.4z%27/%3E%3C/svg%3E")}.icon-check-empty::after{width:0.65rem;height:0.65rem}.icon-resize-horizontal{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M512 256q0 7.2-5.6 12.8l-72.7 73.2q-5.6 5.6-13.3 5.6t-12.8-5.6t-5.1-12.8v-36.9h-292.9v36.9q0 7.2-5.1 12.8t-12.8 5.6t-12.8-5.6l-73.2-73.2q-5.6-5.6-5.6-12.8t5.6-12.8l73.2-73.2q5.1-5.6 12.8-5.6t12.8 5.6t5.1 12.8v36.9h292.9v-36.9q0-7.2 5.1-12.8t12.8-5.6t13.3 5.6l72.7 73.2q5.6 5.1 5.6 12.8z%27%3E%3C/path%3E%3C/svg%3E%0A")}.ag-icon-aggregation{margin:0 0.25rem;-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 16 16%27%3E%3Cpath d=%27M3.6,1.7c-0.2,0.7-0.9,1.1-1.5,1C1.5,2.6,1,2,1,1.3C1,0.7,1.5,0.1,2.1,0c0.4-0.1,0.7,0,1,0.2C3.4,0.4,3.6,0.7,3.7,1 c0.3,0,0.5,0.1,0.8,0.3C4.7,1.5,5,1.8,5.2,2.1c0.2,0.3,0.4,0.7,0.6,1c0.1,0.2,0.3,0.5,0.5,0.7c0.2,0.2,0.5,0.5,0.8,0.6 c0.1,0.1,0.3,0.1,0.5,0.1c0.6,0,2.3,0,2.9,0c0.4,0,0.7,0,1.1,0c0,0,0,0,0.1,0c0,0,0,0,0-0.1c0-0.1,0-0.2,0-0.3c0,0,0-0.1,0-0.1 c0-0.1,0.1-0.1,0.2-0.1c0.1,0,0.1,0,0.1,0.1c0.1,0,0.1,0.1,0.2,0.2c0.2,0.2,0.3,0.3,0.5,0.5C12.8,4.8,13,5,13.1,5.1c0,0,0,0,0,0 c0,0,0,0-0.1,0c-1.5,0-4.1,0-5.7,0C7.2,5.2,7,5.1,6.8,5C6.6,4.9,6.3,4.8,6.1,4.6C5.7,4.3,5.5,4,5.2,3.5C5,3.2,4.8,2.8,4.6,2.4 C4.4,2.2,4.3,2.1,4.1,1.9C4,1.8,3.9,1.7,3.8,1.7C3.7,1.7,3.7,1.7,3.6,1.7z%27/%3E%3Cpath d=%27M3.6,7.7c1,0,10.6,0,11,0c0.1,0,0.1,0,0.1,0.1C14.8,7.8,14.9,7.9,15,8c-0.1,0.1-0.2,0.2-0.3,0.3c0,0,0,0-0.1,0 c0,0,0,0-0.1,0c-3.3,0-7.7,0-10.9,0C3.5,8.8,3.2,9.1,2.8,9.3C2.5,9.4,2.2,9.4,2,9.3C1.4,9.1,1,8.6,1,8c0-0.7,0.5-1.2,1.1-1.3 c0.3-0.1,0.7,0,1,0.2C3.4,7.1,3.6,7.3,3.6,7.7z%27/%3E%3Cpath d=%27M13.1,10.9C13.1,10.9,13.1,10.9,13.1,10.9c-0.3,0.3-0.6,0.6-0.8,0.8c-0.1,0.1-0.2,0.2-0.3,0.3c0,0-0.1,0.1-0.1,0.1 c0,0-0.1,0-0.1,0c-0.1,0-0.1,0-0.2-0.1c0,0,0-0.1,0-0.1c0-0.1,0-0.2,0-0.3c0,0,0,0,0-0.1c-1,0-3.1,0-4.1,0c-0.1,0-0.3,0-0.4,0.1 c-0.3,0.1-0.5,0.2-0.7,0.4c-0.2,0.2-0.4,0.5-0.6,0.8c-0.2,0.4-0.4,0.7-0.7,1.1c-0.2,0.2-0.4,0.4-0.6,0.6c-0.1,0.1-0.3,0.2-0.4,0.3 c-0.1,0.1-0.3,0.2-0.4,0.2c0,0-0.1,0-0.1,0c-0.1,0.4-0.3,0.7-0.7,0.9C2.7,16,2.4,16,2.1,16C1.5,15.9,1,15.3,1,14.7 c0-0.7,0.5-1.2,1-1.3c0.3-0.1,0.7,0,1,0.2c0.3,0.2,0.5,0.5,0.6,0.8c0.1,0,0.2,0,0.2,0C4,14.2,4.1,14.1,4.2,14 c0.2-0.2,0.3-0.4,0.5-0.6c0.2-0.3,0.4-0.6,0.6-1c0.2-0.3,0.4-0.6,0.6-0.9c0.3-0.2,0.5-0.5,0.9-0.6c0.2-0.1,0.4-0.1,0.6-0.1 c0,0,0.1,0,0.1,0c0.6,0,2.4,0,3,0c0.8,0,1.7,0,2.5,0C13.1,10.9,13.1,10.9,13.1,10.9C13.1,10.9,13.1,10.9,13.1,10.9z%27/%3E%3Cpath d=%27M3.6,11.7c-0.1,0.4-0.3,0.7-0.7,0.9c-0.3,0.2-0.6,0.2-0.9,0.1C1.5,12.6,1,12.1,1,11.4c0-0.7,0.5-1.2,1.1-1.3 c0.3-0.1,0.7,0,1,0.2c0.3,0.2,0.5,0.5,0.6,0.8c0.1,0,0.1,0,0.2,0c0.2,0,0.3-0.1,0.4-0.2c0.2-0.1,0.4-0.3,0.5-0.4 C4.9,10.3,5,10.2,5,10.2C5.3,9.9,5.6,9.7,6,9.6c0.3-0.1,0.6-0.2,0.8-0.2c0.1,0,0.1,0,0.2,0c1.1,0,3.4,0,4.5,0c0.9,0,1.8,0,2.6,0 c0,0,0,0,0.1,0c0,0,0,0,0,0C14,9.6,13.8,9.8,13.6,10c-1.8,0-4.8,0-6.6,0c-0.3,0-0.6,0.1-0.9,0.2c-0.2,0.1-0.5,0.3-0.6,0.5 c-0.3,0.3-0.5,0.5-0.8,0.7c-0.2,0.1-0.4,0.2-0.6,0.3C3.9,11.7,3.8,11.7,3.6,11.7C3.7,11.7,3.7,11.7,3.6,11.7z%27/%3E%3Cpath d=%27M3.6,4.9C3.5,5.3,3.3,5.6,2.9,5.8C2.6,5.9,2.3,6,2,5.9C1.4,5.7,1,5.2,1,4.5c0-0.6,0.5-1.2,1.1-1.3c0.7-0.1,1.4,0.3,1.5,1 c0,0,0.1,0,0.1,0c0.3,0,0.5,0.1,0.7,0.3C4.7,4.7,5,4.9,5.2,5c0.1,0.1,0.2,0.2,0.4,0.4c0.3,0.3,0.6,0.5,1,0.5C6.7,6,6.9,6,7,6 c1.8,0,4.8,0,6.6,0c0.1,0.1,0.3,0.3,0.6,0.6c0,0,0,0,0,0c0,0,0,0,0,0c0,0,0,0-0.1,0c-2,0-5.1,0-7.1,0c-0.3,0-0.5,0-0.8-0.1 C6,6.5,5.7,6.4,5.5,6.2C5.3,6.1,5.1,5.9,5,5.8C4.8,5.5,4.5,5.3,4.2,5.1C4.1,5,3.9,4.9,3.6,4.9z%27/%3E%3C/svg%3E%0A")}.ag-icon-loading{position:relative;width:1rem;height:1rem;border-radius:50%;background:linear-gradient(to right, var(--t42-icon-color), Rgba(var(--t42-bg-dark) 42%));transform:translateZ(0);animation:icon-loading 1.4s infinite linear}.ag-icon-loading::before{position:absolute;top:0;left:0;width:50%;height:50%;border-radius:100% 0 0;background:var(--t42-icon-color);content:""}.ag-icon-loading::after{position:absolute;top:0;right:0;bottom:0;left:0;width:75%;height:75%;margin:auto;border-radius:50%;background:Rgb(var(--t42-bg-dark));content:""}.ag-loading{display:flex;padding-left:0.5rem}@keyframes icon-loading{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.search{position:relative}.search i{position:absolute;top:0.625rem;right:0.75rem;width:.75rem;height:.75rem;background-color:var(--t42-content-color);-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 512 512%27%3E%3Cpath d=%27M328.9 219.4q0-52.7-37.4-90.1t-90.6-37.9t-90.6 37.9t-37.4 90.1t37.4 90.6t90.6 37.4t90.6-37.4t37.4-90.6zM475.3 457.5q0 14.8-11.3 25.6t-25.6 10.8q-15.4 0-25.6-10.8l-97.8-97.8q-51.2 35.3-114.2 35.3q-41 0-78.3-15.9t-64-43t-43-64t-15.9-78.3t15.9-77.8t43-64.5t64-43t78.3-15.9t78.3 15.9t64 43t43 64.5t15.9 77.8q0 63-35.3 114.2l97.8 97.8q10.8 10.8 10.8 26.1z%27%3E%3C/path%3E%3C/svg%3E%0A")}.search-results{position:absolute;top:33px;max-height:215px;overflow-y:auto}.search-results .list-group-item{white-space:nowrap}.select{position:relative;z-index:12;display:flex;align-items:center;justify-content:center;width:100%;height:2rem;list-style:none;cursor:pointer}.select input[type="radio"]{opacity:1}.select_expand{position:absolute;top:0;right:0;width:0;height:2rem}.select_expand::after{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:transform;position:absolute;top:50%;right:0;z-index:2;width:1rem;height:1rem;background:var(--t42-select-indicator) center center/1rem 1rem no-repeat;transform:translate(-65%, -55%);content:"";pointer-events:none}.select_expand:checked+.select_close_label+.select_options .select_label:hover{color:var(--t42-link-hover-color);background-color:var(--t42-link-active-bg)}.select_expand:checked::after{transform:translate(-65%, -55%) rotate(-180deg)}.select_expand_label{position:absolute;top:0;left:0;display:block;width:100%;height:2rem;margin-bottom:0;cursor:pointer}.select_close{display:none}.select_close_label{position:fixed;top:0;left:0;display:none;margin-bottom:0}.select_items{position:absolute;top:0;left:0;width:100%;min-height:2rem;border-color:var(--t42-color-opacity-10);border-style:solid;border-width:1px}.select_items:hover{border-color:var(--primary)}.select_input{display:none}.select_label{display:block;height:0;margin-bottom:0;padding-left:0.875rem;overflow:hidden;line-height:2rem;cursor:pointer;transition:all 200ms cubic-bezier(0.4, 0.25, 0.3, 1)}.select_label-placeholder{position:absolute;top:0;left:0;height:2rem;vertical-align:middle;background-color:transparent}.select_expand:checked+.select_close_label{display:block}.select_expand:checked+.select_close_label::before,.select_expand:checked+.select_close_label::after{display:none}.select_expand:checked+.select_close_label+.select_options .select_label{height:2rem}.select_expand:checked+.select_close_label+.select_options+.select_expand_label{display:none}.select_input:checked+.select_label{height:2rem}.select_option label{color:var(--t42-content-color)}.select_options{max-height:10rem;padding-left:0;overflow:auto;list-style:none}.dark{--t42-json-icons: url("data:image/svg+xml,%3C%3Fxml version=%271.0%27 encoding=%27UTF-8%27 standalone=%27no%27%3F%3E%3Csvg xmlns:dc=%27http://purl.org/dc/elements/1.1/%27 xmlns:cc=%27http://creativecommons.org/ns%23%27 xmlns:rdf=%27http://www.w3.org/1999/02/22-rdf-syntax-ns%23%27 xmlns:svg=%27http://www.w3.org/2000/svg%27 xmlns=%27http://www.w3.org/2000/svg%27 xmlns:sodipodi=%27http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd%27 xmlns:inkscape=%27http://www.inkscape.org/namespaces/inkscape%27 width=%27240%27 height=%27144%27 id=%27svg4136%27 version=%271.1%27 inkscape:version=%270.91 r13725%27 sodipodi:docname=%27jsoneditor-icons.svg%27%3E%3Ctitle id=%27title6512%27%3EJSON Editor Icons%3C/title%3E%3Crect id=%27svg_1-7%27 height=%2716%27 width=%2716%27 y=%273.999995%27 x=%2728.000006%27 style=%27fill:%23ff511f;%27 /%3E%3Crect x=%277%27 y=%2711%27 width=%2710%27 height=%272%27 id=%27svg_1-1%27 style=%27fill:%23ffffff;%27 /%3E%3Crect x=%2711%27 y=%277%27 width=%272%27 height=%2710%27 id=%27svg_1-1-1%27 style=%27fill:%23ffffff;%27 /%3E%3Cg id=%27g4299-3%27 transform=%27matrix%280.70710678,-0.70710678,0.70710678,0.70710678,19.029435,12.000001%29%27 style=%27%27%3E%3Crect x=%277%27 y=%2711%27 width=%2710%27 height=%272%27 id=%27svg_1-1-0%27 style=%27fill:%23ffffff;%27 /%3E%3Crect x=%2711%27 y=%277%27 width=%272%27 height=%2710%27 id=%27svg_1-1-1-9%27 style=%27fill:%23ffffff;%27 /%3E%3C/g%3E%3Crect height=%277%27 width=%277%27 y=%277%27 x=%2755%27 style=%27fill:%23ffffff;stroke-width:1;stroke:%23ffffff%27 /%3E%3Crect id=%27svg_1-7-5-7%27 height=%277%27 width=%277%27 y=%2710%27 x=%2758%27 style=%27fill:%23ffffff;stroke-width:1;stroke:%231d1d1d%27 /%3E%3Cg id=%27g4378%27%3E%3Crect style=%27fill:%23ffffff;%27 x=%27198%27 y=%2711%27 width=%278%27 height=%272%27 id=%27svg_1-7-5-3%27 /%3E%3Crect id=%27rect4374%27 height=%272%27 width=%2712%27 y=%277%27 x=%27198%27 style=%27fill:%23ffffff;%27 /%3E%3Crect id=%27rect4376%27 height=%272%27 width=%274%27 y=%2715%27 x=%27198%27 style=%27fill:%23ffffff;%27 /%3E%3C/g%3E%3Cg transform=%27matrix%281,0,0,-1,-23.999995,23.999995%29%27 id=%27g4383%27%3E%3Crect id=%27rect4385%27 height=%272%27 width=%278%27 y=%2711%27 x=%27198%27 style=%27fill:%23ffffff;%27 /%3E%3Crect style=%27fill:%23ffffff;%27 x=%27198%27 y=%277%27 width=%2712%27 height=%272%27 id=%27rect4387%27 /%3E%3Crect style=%27fill:%23ffffff;%27 x=%27198%27 y=%2715%27 width=%274%27 height=%272%27 id=%27rect4389%27 /%3E%3C/g%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 85.10447,6.0157384 -0.0156,1.4063 c 3.02669,-0.2402 0.33008,3.6507996 2.48438,4.5780996 -2.18694,1.0938 0.49191,4.9069 -2.45313,4.5781 l -0.0156,1.4219 c 5.70828,0.559 1.03264,-5.1005 4.70313,-5.2656 l 0,-1.4063 c -3.61303,-0.027 1.11893,-5.7069996 -4.70313,-5.3124996 z%27 id=%27path4351%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 82.78125,5.9984384 0.0156,1.4063 c -3.02668,-0.2402 -0.33007,3.6506996 -2.48437,4.5780996 2.18694,1.0938 -0.49192,4.9069 2.45312,4.5781 l 0.0156,1.4219 c -5.70827,0.559 -1.03263,-5.1004 -4.70312,-5.2656 l 0,-1.4063 c 3.61303,-0.027 -1.11894,-5.7070996 4.70312,-5.3124996 z%27 id=%27path4351-9%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 103.719,5.6719384 0,12.7187996 3.03125,0 0,-1.5313 -1.34375,0 0,-9.6249996 1.375,0 0,-1.5625 z%27 id=%27path2987%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 112.2185,5.6721984 0,12.7187996 -3.03125,0 0,-1.5313 1.34375,0 0,-9.6249996 -1.375,0 0,-1.5625 z%27 id=%27path2987-1%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27M133,6.4h-1.9l-4.8,11.2h1.8l1.1-2.9h5.7l1.1,2.9h1.8L133,6.4z M129.7,13.5l2.3-5.5l2.3,5.5L129.7,13.5z%27 id=%27path3780%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 156.47655,5.8917384 0,2.1797 0.46093,2.3983996 1.82813,0 0.39844,-2.3983996 0,-2.1797 z%27 id=%27path5008-2%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 152.51561,5.8906384 0,2.1797 0.46094,2.3983996 1.82812,0 0.39844,-2.3983996 0,-2.1797 z%27 id=%27path5008-2-8%27 /%3E%3Crect id=%27svg_1-7-2%27 height=%272%27 width=%2712%27 y=%2764%27 x=%2754%27 style=%27fill:%236e6e6e;%27 /%3E%3Crect id=%27svg_1-7-2-2%27 height=%273%27 width=%273%27 y=%2752%27 x=%2780%27 style=%27fill:%236e6e6e;%27 /%3E%3Crect style=%27fill:%236e6e6e;%27 x=%2785%27 y=%2752%27 width=%273%27 height=%273%27 id=%27rect4561%27 /%3E%3Crect style=%27fill:%236e6e6e;%27 x=%2780%27 y=%2758%27 width=%273%27 height=%273%27 id=%27rect4563%27 /%3E%3Crect id=%27rect4565%27 height=%273%27 width=%273%27 y=%2758%27 x=%2785%27 style=%27fill:%236e6e6e;%27 /%3E%3Crect id=%27rect4567%27 height=%273%27 width=%273%27 y=%2764%27 x=%2780%27 style=%27fill:%236e6e6e;%27 /%3E%3Crect style=%27fill:%236e6e6e;%27 x=%2785%27 y=%2764%27 width=%273%27 height=%273%27 id=%27rect4569%27 /%3E%3Ccircle style=%27opacity:1;fill:none;stroke:%236e6e6e;stroke-width:2;%27 id=%27path4571%27 cx=%27110.06081%27 cy=%2757.939209%27 r=%274.7438836%27 /%3E%3Crect style=%27fill:%236e6e6e;%27 x=%27116.64566%27 y=%27-31.79752%27 width=%274.229713%27 height=%276.4053884%27 id=%27rect4563-2%27 transform=%27matrix%280.70710678,0.70710678,-0.70710678,0.70710678,0,0%29%27 /%3E%3Cpath style=%27fill:%236e6e6e;fill-rule:evenodd;%27 d=%27M 125,56 138.77027,56.095 132,64 Z%27 id=%27path4613%27 /%3E%3Cpath id=%27path4615%27 d=%27M 149,64 162.77027,63.905 156,56 Z%27 style=%27fill:%236e6e6e;fill-rule:evenodd;%27 /%3E%3Crect style=%27fill:%236e6e6e;%27 x=%2754%27 y=%2753%27 width=%2712%27 height=%272%27 id=%27rect4638%27 /%3E%3Crect id=%27svg_1-7-2-24%27 height=%272%27 width=%2713%27 y=%27-56%27 x=%2753%27 style=%27fill:%236e6e6e;%27 transform=%27matrix%280,1,-1,0,0,0%29%27 /%3E%3Crect transform=%27matrix%280,1,-1,0,0,0%29%27 style=%27fill:%236e6e6e;%27 x=%2753%27 y=%27-66%27 width=%2713%27 height=%272%27 id=%27rect4657%27 /%3E%3Crect id=%27rect4659%27 height=%271%27 width=%2712%27 y=%2757%27 x=%2754%27 style=%27fill:%236e6e6e;%27 /%3E%3Crect style=%27fill:%23ffffff;%27 x=%2754%27 y=%2788%27 width=%2712%27 height=%272%27 id=%27rect4661%27 /%3E%3Crect style=%27fill:%23ffffff;%27 x=%2780%27 y=%2776%27 width=%273%27 height=%273%27 id=%27rect4663%27 /%3E%3Crect id=%27rect4665%27 height=%273%27 width=%273%27 y=%2776%27 x=%2785%27 style=%27fill:%23ffffff;%27 /%3E%3Crect id=%27rect4667%27 height=%273%27 width=%273%27 y=%2782%27 x=%2780%27 style=%27fill:%23ffffff;%27 /%3E%3Crect style=%27fill:%23ffffff;%27 x=%2785%27 y=%2782%27 width=%273%27 height=%273%27 id=%27rect4669%27 /%3E%3Crect style=%27fill:%23ffffff;%27 x=%2780%27 y=%2788%27 width=%273%27 height=%273%27 id=%27rect4671%27 /%3E%3Crect id=%27rect4673%27 height=%273%27 width=%273%27 y=%2788%27 x=%2785%27 style=%27fill:%23ffffff;%27 /%3E%3Ccircle r=%274.7438836%27 cy=%2781.939331%27 cx=%27110.06081%27 id=%27circle4675%27 style=%27opacity:1;fill:none;stroke:%23ffffff;stroke-width:2;%27 /%3E%3Crect transform=%27matrix%280.70710678,0.70710678,-0.70710678,0.70710678,0,0%29%27 id=%27rect4677%27 height=%276.4053884%27 width=%274.229713%27 y=%27-14.826816%27 x=%27133.6163%27 style=%27fill:%23ffffff;%27 /%3E%3Cpath id=%27path4679%27 d=%27m 125,80.000005 13.77027,0.09499 L 132,87.999992 Z%27 style=%27fill:%23ffffff;%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27M 149,88.0002 162.77027,87.9052 156,80.0002 Z%27 id=%27path4681%27 /%3E%3Crect id=%27rect4683%27 height=%272%27 width=%2712%27 y=%2777%27 x=%2754%27 style=%27fill:%23ffffff;%27 /%3E%3Crect transform=%27matrix%280,1,-1,0,0,0%29%27 style=%27fill:%23ffffff;%27 x=%2777%27 y=%27-56%27 width=%2713%27 height=%272%27 id=%27rect4685%27 /%3E%3Crect id=%27rect4687%27 height=%272%27 width=%2713%27 y=%27-66%27 x=%2777%27 style=%27fill:%23ffffff;%27 transform=%27matrix%280,1,-1,0,0,0%29%27 /%3E%3Crect style=%27fill:%23ffffff;%27 x=%2754%27 y=%2781%27 width=%2712%27 height=%271%27 id=%27rect4689%27 /%3E%3Crect id=%27rect4761-1%27 height=%272%27 width=%2716%27 y=%27101%27 x=%2776%27 style=%27fill:%23ffffff;%27 /%3E%3Crect id=%27rect4761-0%27 height=%272%27 width=%2716%27 y=%27105%27 x=%2776%27 style=%27fill:%23ffffff;%27 /%3E%3Crect id=%27rect4761-7%27 height=%272%27 width=%279%27 y=%27109%27 x=%2776%27 style=%27fill:%23ffffff;%27 /%3E%3Crect id=%27rect4761-1-1%27 height=%272%27 width=%2712%27 y=%27125%27 x=%2776%27 style=%27fill:%23ffffff;%27 /%3E%3Crect id=%27rect4761-1-1-4%27 height=%272%27 width=%2710%27 y=%27137%27 x=%2776%27 style=%27fill:%23ffffff;%27 /%3E%3Crect id=%27rect4761-1-1-4-4%27 height=%272%27 width=%2710%27 y=%27129%27 x=%2782%27 style=%27fill:%23ffffff;%27 /%3E%3Crect id=%27rect4761-1-1-4-4-3%27 height=%272%27 width=%279%27 y=%27133%27 x=%2782%27 style=%27fill:%23ffffff;%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 36.398438,100.0254 c -0.423362,-0.013 -0.846847,0.01 -1.265626,0.062 -1.656562,0.2196 -3.244567,0.9739 -4.507812,2.2266 L 29,100.5991 l -2.324219,7.7129 7.826172,-1.9062 -1.804687,-1.9063 c 1.597702,-1.5308 4.048706,-1.8453 5.984375,-0.7207 1.971162,1.1452 2.881954,3.3975 2.308593,5.5508 -0.573361,2.1533 -2.533865,3.6953 -4.830078,3.6953 l 0,3.0742 c 3.550756,0 6.710442,-2.4113 7.650391,-5.9414 0.939949,-3.5301 -0.618463,-7.2736 -3.710938,-9.0703 -1.159678,-0.6738 -2.431087,-1.0231 -3.701171,-1.0625 z%27 id=%27path4138%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 59.722656,99.9629 c -1.270084,0.039 -2.541493,0.3887 -3.701172,1.0625 -3.092475,1.7967 -4.650886,5.5402 -3.710937,9.0703 0.939949,3.5301 4.09768,5.9414 7.648437,5.9414 l 0,-3.0742 c -2.296214,0 -4.256717,-1.542 -4.830078,-3.6953 -0.573361,-2.1533 0.337432,-4.4056 2.308594,-5.5508 1.935731,-1.1246 4.38863,-0.8102 5.986326,0.7207 l -1.806638,1.9063 7.828128,1.9062 -2.32422,-7.7129 -1.62696,1.7168 c -1.26338,-1.2531 -2.848917,-2.0088 -4.505855,-2.2285 -0.418778,-0.055 -0.842263,-0.076 -1.265625,-0.062 z%27 id=%27path4138-1%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 10.5,100 0,2 -2.4999996,0 L 12,107 l 4,-5 -2.5,0 0,-2 -3,0 z%27 id=%27path3055-0-77%27 /%3E%3Cpath style=%27fill:none;stroke:%23ffffff;%27 d=%27m 4.9850574,108.015 14.0298856,-0.03%27 id=%27path5244-5-0-5%27 /%3E%3Cpath style=%27fill:none;stroke:%23ffffff;%27 d=%27m 4.9849874,132.015 14.0298866,-0.03%27 id=%27path5244-5-0-5-8%27 /%3E%3Cpath style=%27color:%23000000;fill:%236e6e6e;%27 d=%27m 36.398438,123.9629 c -0.423362,-0.013 -0.846847,0.01 -1.265626,0.062 -1.656562,0.2196 -3.244567,0.9739 -4.507812,2.2266 L 29,124.5366 l -2.324219,7.7129 7.826172,-1.9062 -1.804687,-1.9063 c 1.597702,-1.5308 4.048706,-1.8453 5.984375,-0.7207 1.971162,1.1453 2.881954,3.3975 2.308593,5.5508 -0.573361,2.1533 -2.533864,3.6953 -4.830078,3.6953 l 0,3.0742 c 3.550757,0 6.710442,-2.4093 7.650391,-5.9394 0.939949,-3.5301 -0.618463,-7.2756 -3.710938,-9.0723 -1.159678,-0.6737 -2.431087,-1.0231 -3.701171,-1.0625 z%27 id=%27path4138-12%27 /%3E%3Cpath style=%27color:%23000000;fill:%236e6e6e;%27 d=%27m 59.722656,123.9629 c -1.270084,0.039 -2.541493,0.3888 -3.701172,1.0625 -3.092475,1.7967 -4.650886,5.5422 -3.710937,9.0723 0.939949,3.5301 4.09768,5.9394 7.648437,5.9394 l 0,-3.0742 c -2.296214,0 -4.256717,-1.542 -4.830078,-3.6953 -0.573361,-2.1533 0.337432,-4.4055 2.308594,-5.5508 1.935731,-1.1246 4.38863,-0.8102 5.986326,0.7207 l -1.806638,1.9063 7.828128,1.9062 -2.32422,-7.7129 -1.62696,1.7168 c -1.26338,-1.2531 -2.848917,-2.0088 -4.505855,-2.2285 -0.418778,-0.055 -0.842263,-0.076 -1.265625,-0.062 z%27 id=%27path4138-1-3%27 /%3E%3Cpath id=%27path6191%27 d=%27m 10.5,116 0,-2 -2.4999996,0 L 12,109 l 4,5 -2.5,0 0,2 -3,0 z%27 style=%27fill:%23ffffff;stroke-width:1.96599996;%27 /%3E%3Cpath style=%27fill:%23ffffff;stroke-width:1.96599996;%27 d=%27m 10.5,129 0,-2 -2.4999996,0 L 12,122 l 4,5 -2.5,0 0,2 -3,0 z%27 id=%27path6193%27 /%3E%3Cpath id=%27path6195%27 d=%27m 10.5,135 0,2 -2.4999996,0 L 12,142 l 4,-5 -2.5,0 0,-2 -3,0 z%27 style=%27fill:%23ffffff;stroke-width:1.96599996;%27 /%3E%3Cpath sodipodi:type=%27star%27 style=%27fill:%236e6e6e;%27 id=%27path4500%27 sodipodi:sides=%273%27 sodipodi:cx=%2711.55581%27 sodipodi:cy=%2760.073242%27 sodipodi:r1=%275.1116104%27 sodipodi:r2=%272.5558052%27 sodipodi:arg1=%270%27 sodipodi:arg2=%271.0471976%27 inkscape:flatsided=%27false%27 inkscape:rounded=%270%27 inkscape:randomized=%270%27 d=%27m 16.66742,60.073242 -3.833708,2.213392 -3.8337072,2.213393 0,-4.426785 0,-4.426784 3.8337082,2.213392 z%27 inkscape:transform-center-x=%27-1.2779026%27 /%3E%3Cpath inkscape:transform-center-x=%271.277902%27 d=%27m -31.500004,60.073242 -3.833708,2.213392 -3.833707,2.213393 0,-4.426785 0,-4.426784 3.833707,2.213392 z%27 inkscape:randomized=%270%27 inkscape:rounded=%270%27 inkscape:flatsided=%27false%27 sodipodi:arg2=%271.0471976%27 sodipodi:arg1=%270%27 sodipodi:r2=%272.5558052%27 sodipodi:r1=%275.1116104%27 sodipodi:cy=%2760.073242%27 sodipodi:cx=%27-36.611614%27 sodipodi:sides=%273%27 id=%27path4502%27 style=%27fill:%236e6e6e;%27 sodipodi:type=%27star%27 transform=%27scale%28-1,1%29%27 /%3E%3Cpath d=%27m 16.66742,60.073212 -3.833708,2.213392 -3.8337072,2.213392 0,-4.426784 0,-4.426785 3.8337082,2.213392 z%27 inkscape:randomized=%270%27 inkscape:rounded=%270%27 inkscape:flatsided=%27false%27 sodipodi:arg2=%271.0471976%27 sodipodi:arg1=%270%27 sodipodi:r2=%272.5558052%27 sodipodi:r1=%275.1116104%27 sodipodi:cy=%2760.073212%27 sodipodi:cx=%2711.55581%27 sodipodi:sides=%273%27 id=%27path4504%27 style=%27fill:%236e6e6e;%27 sodipodi:type=%27star%27 transform=%27matrix%280,1,-1,0,72.0074,71.7877%29%27 inkscape:transform-center-y=%271.2779029%27 /%3E%3Cpath inkscape:transform-center-y=%27-1.2779026%27 transform=%27matrix%280,-1,-1,0,96,96%29%27 sodipodi:type=%27star%27 style=%27fill:%236e6e6e;%27 id=%27path4506%27 sodipodi:sides=%273%27 sodipodi:cx=%2711.55581%27 sodipodi:cy=%2760.073212%27 sodipodi:r1=%275.1116104%27 sodipodi:r2=%272.5558052%27 sodipodi:arg1=%270%27 sodipodi:arg2=%271.0471976%27 inkscape:flatsided=%27false%27 inkscape:rounded=%270%27 inkscape:randomized=%270%27 d=%27m 16.66742,60.073212 -3.833708,2.213392 -3.8337072,2.213392 0,-4.426784 0,-4.426785 3.8337082,2.213392 z%27 /%3E%3Cpath id=%27path4615-5%27 d=%27m 171.82574,65.174193 16.34854,0 -8.17427,-13.348454 z%27 style=%27fill:%23f9a825;fill-rule:evenodd;stroke:%23f9a825;stroke-width:2;%27 /%3E%3Cpath style=%27opacity:1;fill:%23ffffff;%27 d=%27m 179,55 0,6 2,0 0,-6%27 id=%27path4300%27 /%3E%3Cpath style=%27opacity:1;fill:%23ffffff;%27 d=%27m 179,62 0,2 2,0 0,-2%27 id=%27path4300-6%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27M 99.994369,113.0221 102,114.98353 l 7,-6.9558 3,0.97227 2,-1 1,-2 0,-3 -3,3 -3,-3 3,-3 -3,0 -2,1 -1,2 0.99437,3.0221 z%27 id=%27path4268%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 234,6 0,2 -5,5 0,5 -2,0 0,-5 -5,-5 0,-2%27 id=%27path3546%27 /%3E%3Cg transform=%27matrix%281.3333328,0,0,-1.5999992,-139.9999,127.19999%29%27 id=%27g4383-6%27%3E%3Crect id=%27rect4385-2%27 height=%271%27 width=%276%27 y=%2712.625005%27 x=%27198%27 style=%27fill:%23ffffff;stroke:%23000000;stroke-width:0%27 /%3E%3Crect style=%27fill:%23ffffff;stroke:%23000000;stroke-width:0%27 x=%27198%27 y=%2715.125007%27 width=%278%27 height=%271%27 id=%27rect4387-9%27 /%3E%3Crect style=%27fill:%23ffffff;stroke:%23000000;stroke-width:0%27 x=%27198%27 y=%277.6250024%27 width=%273%27 height=%271%27 id=%27rect4389-1-0%27 /%3E%3Crect style=%27fill:%23ffffff;stroke:%23000000;stroke-width:0%27 x=%27198%27 y=%2710.125004%27 width=%274%27 height=%271%27 id=%27rect4389-1-9%27 /%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 207.00001,16.375004 0,-5.625005 -2.25,0 3,-3.1250014 3,3.1250014 -2.25,0 0,5.625005 -1.5,0%27 id=%27path4402%27 /%3E%3C/g%3E%3Cpath style=%27fill:%23ffffff;%27 d=%27m 164,100 0,3 -6,6 0,7 -4,0 0,-7 -6,-6 0,-3%27 id=%27path3546-2-2%27 /%3E%3Cpath id=%27path4402-5-7%27 d=%27m 15,41 0,-7 -4,0 0,3 -5,-4 5,-4 0,3 6,0 0,9%27 style=%27fill:%23ffffff;%27 /%3E%3C/svg%3E%0A")}.light{--t42-json-icons: url("data:image/svg+xml,%3C%3Fxml version=%271.0%27 encoding=%27UTF-8%27 standalone=%27no%27%3F%3E%3Csvg xmlns:dc=%27http://purl.org/dc/elements/1.1/%27 xmlns:cc=%27http://creativecommons.org/ns%23%27 xmlns:rdf=%27http://www.w3.org/1999/02/22-rdf-syntax-ns%23%27 xmlns:svg=%27http://www.w3.org/2000/svg%27 xmlns=%27http://www.w3.org/2000/svg%27 xmlns:sodipodi=%27http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd%27 xmlns:inkscape=%27http://www.inkscape.org/namespaces/inkscape%27 width=%27240%27 height=%27144%27 id=%27svg4136%27 version=%271.1%27 inkscape:version=%270.91 r13725%27 sodipodi:docname=%27jsoneditor-icons.svg%27%3E%3Ctitle id=%27title6512%27%3EJSON Editor Icons%3C/title%3E%3Crect id=%27svg_1-7%27 height=%2716%27 width=%2716%27 y=%273.999995%27 x=%2728.000006%27 style=%27fill:%23ff511f;%27 /%3E%3Crect x=%277%27 y=%2711%27 width=%2710%27 height=%272%27 id=%27svg_1-1%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect x=%2711%27 y=%277%27 width=%272%27 height=%2710%27 id=%27svg_1-1-1%27 style=%27fill:%230d0d0d;%27 /%3E%3Cg id=%27g4299-3%27 transform=%27matrix%280.70710678,-0.70710678,0.70710678,0.70710678,19.029435,12.000001%29%27 style=%27%27%3E%3Crect x=%277%27 y=%2711%27 width=%2710%27 height=%272%27 id=%27svg_1-1-0%27 style=%27fill:%23ffffff;%27 /%3E%3Crect x=%2711%27 y=%277%27 width=%272%27 height=%2710%27 id=%27svg_1-1-1-9%27 style=%27fill:%23ffffff;%27 /%3E%3C/g%3E%3Crect height=%277%27 width=%277%27 y=%277%27 x=%2755%27 style=%27fill:%230d0d0d;stroke-width:1;stroke:%230d0d0d%27 /%3E%3Crect id=%27svg_1-7-5-7%27 height=%277%27 width=%277%27 y=%2710%27 x=%2758%27 style=%27fill:%230d0d0d;stroke-width:1;stroke:%23ffffff%27 /%3E%3Cg id=%27g4378%27%3E%3Crect style=%27fill:%230d0d0d;%27 x=%27198%27 y=%2711%27 width=%278%27 height=%272%27 id=%27svg_1-7-5-3%27 /%3E%3Crect id=%27rect4374%27 height=%272%27 width=%2712%27 y=%277%27 x=%27198%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect id=%27rect4376%27 height=%272%27 width=%274%27 y=%2715%27 x=%27198%27 style=%27fill:%230d0d0d;%27 /%3E%3C/g%3E%3Cg transform=%27matrix%281,0,0,-1,-23.999995,23.999995%29%27 id=%27g4383%27%3E%3Crect id=%27rect4385%27 height=%272%27 width=%278%27 y=%2711%27 x=%27198%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect style=%27fill:%230d0d0d;%27 x=%27198%27 y=%277%27 width=%2712%27 height=%272%27 id=%27rect4387%27 /%3E%3Crect style=%27fill:%230d0d0d;%27 x=%27198%27 y=%2715%27 width=%274%27 height=%272%27 id=%27rect4389%27 /%3E%3C/g%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 85.10447,6.0157384 -0.0156,1.4063 c 3.02669,-0.2402 0.33008,3.6507996 2.48438,4.5780996 -2.18694,1.0938 0.49191,4.9069 -2.45313,4.5781 l -0.0156,1.4219 c 5.70828,0.559 1.03264,-5.1005 4.70313,-5.2656 l 0,-1.4063 c -3.61303,-0.027 1.11893,-5.7069996 -4.70313,-5.3124996 z%27 id=%27path4351%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 82.78125,5.9984384 0.0156,1.4063 c -3.02668,-0.2402 -0.33007,3.6506996 -2.48437,4.5780996 2.18694,1.0938 -0.49192,4.9069 2.45312,4.5781 l 0.0156,1.4219 c -5.70827,0.559 -1.03263,-5.1004 -4.70312,-5.2656 l 0,-1.4063 c 3.61303,-0.027 -1.11894,-5.7070996 4.70312,-5.3124996 z%27 id=%27path4351-9%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 103.719,5.6719384 0,12.7187996 3.03125,0 0,-1.5313 -1.34375,0 0,-9.6249996 1.375,0 0,-1.5625 z%27 id=%27path2987%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 112.2185,5.6721984 0,12.7187996 -3.03125,0 0,-1.5313 1.34375,0 0,-9.6249996 -1.375,0 0,-1.5625 z%27 id=%27path2987-1%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27M133,6.4h-1.9l-4.8,11.2h1.8l1.1-2.9h5.7l1.1,2.9h1.8L133,6.4z M129.7,13.5l2.3-5.5l2.3,5.5L129.7,13.5z%27 id=%27path3780%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 156.47655,5.8917384 0,2.1797 0.46093,2.3983996 1.82813,0 0.39844,-2.3983996 0,-2.1797 z%27 id=%27path5008-2%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 152.51561,5.8906384 0,2.1797 0.46094,2.3983996 1.82812,0 0.39844,-2.3983996 0,-2.1797 z%27 id=%27path5008-2-8%27 /%3E%3Crect id=%27svg_1-7-2%27 height=%272%27 width=%2712%27 y=%2764%27 x=%2754%27 style=%27fill:%236e6e6e;%27 /%3E%3Crect id=%27svg_1-7-2-2%27 height=%273%27 width=%273%27 y=%2752%27 x=%2780%27 style=%27fill:%236e6e6e;%27 /%3E%3Crect style=%27fill:%236e6e6e;%27 x=%2785%27 y=%2752%27 width=%273%27 height=%273%27 id=%27rect4561%27 /%3E%3Crect style=%27fill:%236e6e6e;%27 x=%2780%27 y=%2758%27 width=%273%27 height=%273%27 id=%27rect4563%27 /%3E%3Crect id=%27rect4565%27 height=%273%27 width=%273%27 y=%2758%27 x=%2785%27 style=%27fill:%236e6e6e;%27 /%3E%3Crect id=%27rect4567%27 height=%273%27 width=%273%27 y=%2764%27 x=%2780%27 style=%27fill:%236e6e6e;%27 /%3E%3Crect style=%27fill:%236e6e6e;%27 x=%2785%27 y=%2764%27 width=%273%27 height=%273%27 id=%27rect4569%27 /%3E%3Ccircle style=%27opacity:1;fill:none;stroke:%236e6e6e;stroke-width:2;%27 id=%27path4571%27 cx=%27110.06081%27 cy=%2757.939209%27 r=%274.7438836%27 /%3E%3Crect style=%27fill:%236e6e6e;%27 x=%27116.64566%27 y=%27-31.79752%27 width=%274.229713%27 height=%276.4053884%27 id=%27rect4563-2%27 transform=%27matrix%280.70710678,0.70710678,-0.70710678,0.70710678,0,0%29%27 /%3E%3Cpath style=%27fill:%236e6e6e;fill-rule:evenodd;%27 d=%27M 125,56 138.77027,56.095 132,64 Z%27 id=%27path4613%27 /%3E%3Cpath id=%27path4615%27 d=%27M 149,64 162.77027,63.905 156,56 Z%27 style=%27fill:%236e6e6e;fill-rule:evenodd;%27 /%3E%3Crect style=%27fill:%236e6e6e;%27 x=%2754%27 y=%2753%27 width=%2712%27 height=%272%27 id=%27rect4638%27 /%3E%3Crect id=%27svg_1-7-2-24%27 height=%272%27 width=%2713%27 y=%27-56%27 x=%2753%27 style=%27fill:%236e6e6e;%27 transform=%27matrix%280,1,-1,0,0,0%29%27 /%3E%3Crect transform=%27matrix%280,1,-1,0,0,0%29%27 style=%27fill:%236e6e6e;%27 x=%2753%27 y=%27-66%27 width=%2713%27 height=%272%27 id=%27rect4657%27 /%3E%3Crect id=%27rect4659%27 height=%271%27 width=%2712%27 y=%2757%27 x=%2754%27 style=%27fill:%236e6e6e;%27 /%3E%3Crect style=%27fill:%230d0d0d;%27 x=%2754%27 y=%2788%27 width=%2712%27 height=%272%27 id=%27rect4661%27 /%3E%3Crect style=%27fill:%230d0d0d;%27 x=%2780%27 y=%2776%27 width=%273%27 height=%273%27 id=%27rect4663%27 /%3E%3Crect id=%27rect4665%27 height=%273%27 width=%273%27 y=%2776%27 x=%2785%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect id=%27rect4667%27 height=%273%27 width=%273%27 y=%2782%27 x=%2780%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect style=%27fill:%230d0d0d;%27 x=%2785%27 y=%2782%27 width=%273%27 height=%273%27 id=%27rect4669%27 /%3E%3Crect style=%27fill:%230d0d0d;%27 x=%2780%27 y=%2788%27 width=%273%27 height=%273%27 id=%27rect4671%27 /%3E%3Crect id=%27rect4673%27 height=%273%27 width=%273%27 y=%2788%27 x=%2785%27 style=%27fill:%230d0d0d;%27 /%3E%3Ccircle r=%274.7438836%27 cy=%2781.939331%27 cx=%27110.06081%27 id=%27circle4675%27 style=%27opacity:1;fill:none;stroke:%230d0d0d;stroke-width:2;%27 /%3E%3Crect transform=%27matrix%280.70710678,0.70710678,-0.70710678,0.70710678,0,0%29%27 id=%27rect4677%27 height=%276.4053884%27 width=%274.229713%27 y=%27-14.826816%27 x=%27133.6163%27 style=%27fill:%230d0d0d;%27 /%3E%3Cpath id=%27path4679%27 d=%27m 125,80.000005 13.77027,0.09499 L 132,87.999992 Z%27 style=%27fill:%230d0d0d;%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27M 149,88.0002 162.77027,87.9052 156,80.0002 Z%27 id=%27path4681%27 /%3E%3Crect id=%27rect4683%27 height=%272%27 width=%2712%27 y=%2777%27 x=%2754%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect transform=%27matrix%280,1,-1,0,0,0%29%27 style=%27fill:%230d0d0d;%27 x=%2777%27 y=%27-56%27 width=%2713%27 height=%272%27 id=%27rect4685%27 /%3E%3Crect id=%27rect4687%27 height=%272%27 width=%2713%27 y=%27-66%27 x=%2777%27 style=%27fill:%230d0d0d;%27 transform=%27matrix%280,1,-1,0,0,0%29%27 /%3E%3Crect style=%27fill:%230d0d0d;%27 x=%2754%27 y=%2781%27 width=%2712%27 height=%271%27 id=%27rect4689%27 /%3E%3Crect id=%27rect4761-1%27 height=%272%27 width=%2716%27 y=%27101%27 x=%2776%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect id=%27rect4761-0%27 height=%272%27 width=%2716%27 y=%27105%27 x=%2776%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect id=%27rect4761-7%27 height=%272%27 width=%279%27 y=%27109%27 x=%2776%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect id=%27rect4761-1-1%27 height=%272%27 width=%2712%27 y=%27125%27 x=%2776%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect id=%27rect4761-1-1-4%27 height=%272%27 width=%2710%27 y=%27137%27 x=%2776%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect id=%27rect4761-1-1-4-4%27 height=%272%27 width=%2710%27 y=%27129%27 x=%2782%27 style=%27fill:%230d0d0d;%27 /%3E%3Crect id=%27rect4761-1-1-4-4-3%27 height=%272%27 width=%279%27 y=%27133%27 x=%2782%27 style=%27fill:%230d0d0d;%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 36.398438,100.0254 c -0.423362,-0.013 -0.846847,0.01 -1.265626,0.062 -1.656562,0.2196 -3.244567,0.9739 -4.507812,2.2266 L 29,100.5991 l -2.324219,7.7129 7.826172,-1.9062 -1.804687,-1.9063 c 1.597702,-1.5308 4.048706,-1.8453 5.984375,-0.7207 1.971162,1.1452 2.881954,3.3975 2.308593,5.5508 -0.573361,2.1533 -2.533865,3.6953 -4.830078,3.6953 l 0,3.0742 c 3.550756,0 6.710442,-2.4113 7.650391,-5.9414 0.939949,-3.5301 -0.618463,-7.2736 -3.710938,-9.0703 -1.159678,-0.6738 -2.431087,-1.0231 -3.701171,-1.0625 z%27 id=%27path4138%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 59.722656,99.9629 c -1.270084,0.039 -2.541493,0.3887 -3.701172,1.0625 -3.092475,1.7967 -4.650886,5.5402 -3.710937,9.0703 0.939949,3.5301 4.09768,5.9414 7.648437,5.9414 l 0,-3.0742 c -2.296214,0 -4.256717,-1.542 -4.830078,-3.6953 -0.573361,-2.1533 0.337432,-4.4056 2.308594,-5.5508 1.935731,-1.1246 4.38863,-0.8102 5.986326,0.7207 l -1.806638,1.9063 7.828128,1.9062 -2.32422,-7.7129 -1.62696,1.7168 c -1.26338,-1.2531 -2.848917,-2.0088 -4.505855,-2.2285 -0.418778,-0.055 -0.842263,-0.076 -1.265625,-0.062 z%27 id=%27path4138-1%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 10.5,100 0,2 -2.4999996,0 L 12,107 l 4,-5 -2.5,0 0,-2 -3,0 z%27 id=%27path3055-0-77%27 /%3E%3Cpath style=%27fill:none;stroke:%230d0d0d;%27 d=%27m 4.9850574,108.015 14.0298856,-0.03%27 id=%27path5244-5-0-5%27 /%3E%3Cpath style=%27fill:none;stroke:%230d0d0d;%27 d=%27m 4.9849874,132.015 14.0298866,-0.03%27 id=%27path5244-5-0-5-8%27 /%3E%3Cpath style=%27color:%23000000;fill:%236e6e6e;%27 d=%27m 36.398438,123.9629 c -0.423362,-0.013 -0.846847,0.01 -1.265626,0.062 -1.656562,0.2196 -3.244567,0.9739 -4.507812,2.2266 L 29,124.5366 l -2.324219,7.7129 7.826172,-1.9062 -1.804687,-1.9063 c 1.597702,-1.5308 4.048706,-1.8453 5.984375,-0.7207 1.971162,1.1453 2.881954,3.3975 2.308593,5.5508 -0.573361,2.1533 -2.533864,3.6953 -4.830078,3.6953 l 0,3.0742 c 3.550757,0 6.710442,-2.4093 7.650391,-5.9394 0.939949,-3.5301 -0.618463,-7.2756 -3.710938,-9.0723 -1.159678,-0.6737 -2.431087,-1.0231 -3.701171,-1.0625 z%27 id=%27path4138-12%27 /%3E%3Cpath style=%27color:%23000000;fill:%236e6e6e;%27 d=%27m 59.722656,123.9629 c -1.270084,0.039 -2.541493,0.3888 -3.701172,1.0625 -3.092475,1.7967 -4.650886,5.5422 -3.710937,9.0723 0.939949,3.5301 4.09768,5.9394 7.648437,5.9394 l 0,-3.0742 c -2.296214,0 -4.256717,-1.542 -4.830078,-3.6953 -0.573361,-2.1533 0.337432,-4.4055 2.308594,-5.5508 1.935731,-1.1246 4.38863,-0.8102 5.986326,0.7207 l -1.806638,1.9063 7.828128,1.9062 -2.32422,-7.7129 -1.62696,1.7168 c -1.26338,-1.2531 -2.848917,-2.0088 -4.505855,-2.2285 -0.418778,-0.055 -0.842263,-0.076 -1.265625,-0.062 z%27 id=%27path4138-1-3%27 /%3E%3Cpath id=%27path6191%27 d=%27m 10.5,116 0,-2 -2.4999996,0 L 12,109 l 4,5 -2.5,0 0,2 -3,0 z%27 style=%27fill:%230d0d0d;stroke-width:2;%27 /%3E%3Cpath style=%27fill:%230d0d0d;stroke-width:2;%27 d=%27m 10.5,129 0,-2 -2.4999996,0 L 12,122 l 4,5 -2.5,0 0,2 -3,0 z%27 id=%27path6193%27 /%3E%3Cpath id=%27path6195%27 d=%27m 10.5,135 0,2 -2.4999996,0 L 12,142 l 4,-5 -2.5,0 0,-2 -3,0 z%27 style=%27fill:%230d0d0d;stroke-width:2;%27 /%3E%3Cpath sodipodi:type=%27star%27 style=%27fill:%236e6e6e;%27 id=%27path4500%27 sodipodi:sides=%273%27 sodipodi:cx=%2711.55581%27 sodipodi:cy=%2760.073242%27 sodipodi:r1=%275.1116104%27 sodipodi:r2=%272.5558052%27 sodipodi:arg1=%270%27 sodipodi:arg2=%271.0471976%27 inkscape:flatsided=%27false%27 inkscape:rounded=%270%27 inkscape:randomized=%270%27 d=%27m 16.66742,60.073242 -3.833708,2.213392 -3.8337072,2.213393 0,-4.426785 0,-4.426784 3.8337082,2.213392 z%27 inkscape:transform-center-x=%27-1.2779026%27 /%3E%3Cpath inkscape:transform-center-x=%271.277902%27 d=%27m -31.500004,60.073242 -3.833708,2.213392 -3.833707,2.213393 0,-4.426785 0,-4.426784 3.833707,2.213392 z%27 inkscape:randomized=%270%27 inkscape:rounded=%270%27 inkscape:flatsided=%27false%27 sodipodi:arg2=%271.0471976%27 sodipodi:arg1=%270%27 sodipodi:r2=%272.5558052%27 sodipodi:r1=%275.1116104%27 sodipodi:cy=%2760.073242%27 sodipodi:cx=%27-36.611614%27 sodipodi:sides=%273%27 id=%27path4502%27 style=%27fill:%236e6e6e;%27 sodipodi:type=%27star%27 transform=%27scale%28-1,1%29%27 /%3E%3Cpath d=%27m 16.66742,60.073212 -3.833708,2.213392 -3.8337072,2.213392 0,-4.426784 0,-4.426785 3.8337082,2.213392 z%27 inkscape:randomized=%270%27 inkscape:rounded=%270%27 inkscape:flatsided=%27false%27 sodipodi:arg2=%271.0471976%27 sodipodi:arg1=%270%27 sodipodi:r2=%272.5558052%27 sodipodi:r1=%275.1116104%27 sodipodi:cy=%2760.073212%27 sodipodi:cx=%2711.55581%27 sodipodi:sides=%273%27 id=%27path4504%27 style=%27fill:%236e6e6e;%27 sodipodi:type=%27star%27 transform=%27matrix%280,1,-1,0,72.0074,71.7877%29%27 inkscape:transform-center-y=%271.2779029%27 /%3E%3Cpath inkscape:transform-center-y=%27-1.2779026%27 transform=%27matrix%280,-1,-1,0,96,96%29%27 sodipodi:type=%27star%27 style=%27fill:%236e6e6e;%27 id=%27path4506%27 sodipodi:sides=%273%27 sodipodi:cx=%2711.55581%27 sodipodi:cy=%2760.073212%27 sodipodi:r1=%275.1116104%27 sodipodi:r2=%272.5558052%27 sodipodi:arg1=%270%27 sodipodi:arg2=%271.0471976%27 inkscape:flatsided=%27false%27 inkscape:rounded=%270%27 inkscape:randomized=%270%27 d=%27m 16.66742,60.073212 -3.833708,2.213392 -3.8337072,2.213392 0,-4.426784 0,-4.426785 3.8337082,2.213392 z%27 /%3E%3Cpath id=%27path4615-5%27 d=%27m 171.82574,65.174193 16.34854,0 -8.17427,-13.348454 z%27 style=%27fill:%23f9a825;fill-rule:evenodd;stroke:%23f9a825;stroke-width:2;%27 /%3E%3Cpath style=%27opacity:1;fill:%23ffffff;%27 d=%27m 179,55 0,6 2,0 0,-6%27 id=%27path4300%27 /%3E%3Cpath style=%27opacity:1;fill:%23ffffff;%27 d=%27m 179,62 0,2 2,0 0,-2%27 id=%27path4300-6%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27M 99.994369,113.0221 102,114.98353 l 7,-6.9558 3,0.97227 2,-1 1,-2 0,-3 -3,3 -3,-3 3,-3 -3,0 -2,1 -1,2 0.99437,3.0221 z%27 id=%27path4268%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 234,6 0,2 -5,5 0,5 -2,0 0,-5 -5,-5 0,-2%27 id=%27path3546%27 /%3E%3Cg transform=%27matrix%281.3333328,0,0,-1.5999992,-139.9999,127.19999%29%27 id=%27g4383-6%27%3E%3Crect id=%27rect4385-2%27 height=%271%27 width=%276%27 y=%2712.625005%27 x=%27198%27 style=%27fill:%230d0d0d;stroke:%23000000;stroke-width:0%27 /%3E%3Crect style=%27fill:%230d0d0d;stroke:%23000000;stroke-width:0%27 x=%27198%27 y=%2715.125007%27 width=%278%27 height=%271%27 id=%27rect4387-9%27 /%3E%3Crect style=%27fill:%230d0d0d;stroke:%23000000;stroke-width:0%27 x=%27198%27 y=%277.6250024%27 width=%273%27 height=%271%27 id=%27rect4389-1-0%27 /%3E%3Crect style=%27fill:%230d0d0d;stroke:%23000000;stroke-width:0%27 x=%27198%27 y=%2710.125004%27 width=%274%27 height=%271%27 id=%27rect4389-1-9%27 /%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 207.00001,16.375004 0,-5.625005 -2.25,0 3,-3.1250014 3,3.1250014 -2.25,0 0,5.625005 -1.5,0%27 id=%27path4402%27 /%3E%3C/g%3E%3Cpath style=%27fill:%230d0d0d;%27 d=%27m 164,100 0,3 -6,6 0,7 -4,0 0,-7 -6,-6 0,-3%27 id=%27path3546-2-2%27 /%3E%3Cpath id=%27path4402-5-7%27 d=%27m 15,41 0,-7 -4,0 0,3 -5,-4 5,-4 0,3 6,0 0,9%27 style=%27fill:%230d0d0d;%27 /%3E%3C/svg%3E%0A")}body{/*! + * Selectr 2.4.13 + * http://mobius.ovh/docs/selectr + * + * Released under the MIT license + */}body .jsoneditor,body .jsoneditor-modal{-webkit-text-size-adjust:none;text-size-adjust:none}body .jsoneditor input,body .jsoneditor input:not([type]),body .jsoneditor input[type="text"],body .jsoneditor input[type="search"],body .jsoneditor-modal input,body .jsoneditor-modal input:not([type]),body .jsoneditor-modal input[type="text"],body .jsoneditor-modal input[type="search"]{height:auto;border:inherit;box-shadow:none;font-size:inherit;box-sizing:inherit;padding:inherit;font-family:inherit;transition:none;line-height:inherit}body .jsoneditor input:focus,body .jsoneditor input:not([type]):focus,body .jsoneditor input[type="text"]:focus,body .jsoneditor input[type="search"]:focus,body .jsoneditor-modal input:focus,body .jsoneditor-modal input:not([type]):focus,body .jsoneditor-modal input[type="text"]:focus,body .jsoneditor-modal input[type="search"]:focus{border:inherit;box-shadow:inherit}body .jsoneditor textarea,body .jsoneditor-modal textarea{height:inherit}body .jsoneditor select,body .jsoneditor-modal select{display:inherit;height:inherit}body .jsoneditor label,body .jsoneditor-modal label{font-size:inherit;font-weight:inherit;color:inherit}body .jsoneditor table,body .jsoneditor-modal table{border-collapse:collapse;width:auto}body .jsoneditor td,body .jsoneditor th,body .jsoneditor-modal td,body .jsoneditor-modal th{padding:0;display:table-cell;text-align:left;vertical-align:inherit;border-radius:inherit}body .jsoneditor .autocomplete.dropdown{position:absolute;background:var(--t42-content-color);box-shadow:var(--t42-shadow);border:1px solid var(--t42-color-opacity-10);overflow-x:hidden;overflow-y:auto;cursor:default;margin:0;padding:5px;text-align:left;outline:0;font-family:var(--bs-font-monospace);font-size:var(--t42-font-size)}body .jsoneditor .autocomplete.dropdown .item{color:var(--t42-content-color)}body .jsoneditor .autocomplete.dropdown .item.hover{background-color:Rgb(var(--t42-bg-mid))}body .jsoneditor .autocomplete.hint{color:var(--t42-content-color);top:4px;left:4px}body .jsoneditor-contextmenu-root{position:relative;width:0;height:0}body .jsoneditor-contextmenu{position:absolute;box-sizing:content-box;z-index:2}body .jsoneditor-contextmenu .jsoneditor-menu{position:relative;left:0;top:0;width:128px;height:auto;background:var(--t42-content-color);border:1px solid var(--t42-color-opacity-10);box-shadow:var(--t42-shadow);list-style:none;margin:0;padding:0}body .jsoneditor-contextmenu .jsoneditor-menu button{position:relative;padding:0 8px 0 0;margin:0;width:128px;height:auto;border:none;cursor:pointer;color:var(--t42-content-color);background:transparent;font-size:var(--t42-font-size);font-family:var(--t42-font-family);box-sizing:border-box;text-align:left}body .jsoneditor-contextmenu .jsoneditor-menu button::-moz-focus-inner{padding:0;border:0}body .jsoneditor-contextmenu .jsoneditor-menu button.jsoneditor-default{width:96px}body .jsoneditor-contextmenu .jsoneditor-menu button.jsoneditor-expand{float:right;width:32px;height:24px;border-left:1px solid var(--t42-color-opacity-10)}body .jsoneditor-contextmenu .jsoneditor-menu li{overflow:hidden}body .jsoneditor-contextmenu .jsoneditor-menu li ul{display:none;position:relative;left:-10px;top:0;border:none;box-shadow:inset var(--t42-shadow);padding:0 10px;-webkit-transition:all 0.3s ease-out;-moz-transition:all 0.3s ease-out;-o-transition:all 0.3s ease-out;transition:all 0.3s ease-out}body .jsoneditor-contextmenu .jsoneditor-menu li ul .jsoneditor-icon{margin-left:24px}body .jsoneditor-contextmenu .jsoneditor-menu li ul li button{padding-left:24px;animation:all ease-in-out 1s}body .jsoneditor-contextmenu .jsoneditor-menu li button .jsoneditor-expand{position:absolute;top:0;right:0;width:24px;height:24px;padding:0;margin:0 4px 0 0;background-image:"/";background-position:0 -72px}body .jsoneditor-contextmenu .jsoneditor-icon{position:absolute;top:0;left:0;width:24px;height:24px;border:none;padding:0;margin:0;background-image:"/"}body .jsoneditor-contextmenu .jsoneditor-text{padding:4px 0 4px 24px;word-wrap:break-word}body .jsoneditor-contextmenu .jsoneditor-text.jsoneditor-right-margin{padding-right:24px}body .jsoneditor-contextmenu .jsoneditor-separator{height:0;border-top:1px solid var(--t42-color-opacity-10);padding-top:5px;margin-top:5px}body .jsoneditor-contextmenu button.jsoneditor-remove .jsoneditor-icon{background-position:-24px 0}body .jsoneditor-contextmenu button.jsoneditor-append .jsoneditor-icon{background-position:0 0}body .jsoneditor-contextmenu button.jsoneditor-insert .jsoneditor-icon{background-position:0 0}body .jsoneditor-contextmenu button.jsoneditor-duplicate .jsoneditor-icon{background-position:-48px 0}body .jsoneditor-contextmenu button.jsoneditor-sort-asc .jsoneditor-icon{background-position:-168px 0}body .jsoneditor-contextmenu button.jsoneditor-sort-desc .jsoneditor-icon{background-position:-192px 0}body .jsoneditor-contextmenu button.jsoneditor-transform .jsoneditor-icon{background-position:-216px 0}body .jsoneditor-contextmenu button.jsoneditor-extract .jsoneditor-icon{background-position:0 -24px}body .jsoneditor-contextmenu button.jsoneditor-type-string .jsoneditor-icon{background-position:-144px 0}body .jsoneditor-contextmenu button.jsoneditor-type-auto .jsoneditor-icon{background-position:-120px 0}body .jsoneditor-contextmenu button.jsoneditor-type-object .jsoneditor-icon{background-position:-72px 0}body .jsoneditor-contextmenu button.jsoneditor-type-array .jsoneditor-icon{background-position:-96px 0}body .jsoneditor-contextmenu button.jsoneditor-type-modes .jsoneditor-icon{background-image:none;width:6px}body .jsoneditor-contextmenu ul,body .jsoneditor-contextmenu li{box-sizing:content-box;position:relative}body .jsoneditor-contextmenu .jsoneditor-menu button:hover,body .jsoneditor-contextmenu .jsoneditor-menu button:focus{color:var(--t42-content-color);background-color:var(--t42-color-opacity-10);outline:none}body .jsoneditor-contextmenu .jsoneditor-menu li button.jsoneditor-selected,body .jsoneditor-contextmenu .jsoneditor-menu li button.jsoneditor-selected:hover,body .jsoneditor-contextmenu .jsoneditor-menu li button.jsoneditor-selected:focus{color:var(--t42-content-color);background-color:var(--red)}body .jsoneditor-contextmenu .jsoneditor-menu li ul li button:hover,body .jsoneditor-contextmenu .jsoneditor-menu li ul li button:focus{background-color:var(--t42-color-opacity-10)}body .jsoneditor-modal{max-width:95%;border-radius:2px !important;padding:45px 15px 15px 15px !important;box-shadow:var(--t42-shadow);color:var(--t42-content-color);line-height:1.3em}body .jsoneditor-modal.jsoneditor-modal-transform{width:600px !important}body .jsoneditor-modal .pico-modal-header{position:absolute;box-sizing:border-box;top:0;left:0;width:100%;padding:0 10px;height:30px;line-height:30px;font-family:var(--t42-font-family);font-size:11pt;background:var(--primary);color:var(--t42-content-color)}body .jsoneditor-modal table{width:100%}body .jsoneditor-modal table td{padding:3px 0}body .jsoneditor-modal table td.jsoneditor-modal-input{text-align:right;padding-right:0;white-space:nowrap}body .jsoneditor-modal table td.jsoneditor-modal-actions{padding-top:15px}body .jsoneditor-modal table th{vertical-align:middle}body .jsoneditor-modal p:first-child{margin-top:0}body .jsoneditor-modal a{color:var(--primary)}body .jsoneditor-modal .jsoneditor-jmespath-block{margin-bottom:10px}body .jsoneditor-modal .pico-close{background:none !important;font-size:24px !important;top:7px !important;right:7px !important;color:var(--t42-content-color)}body .jsoneditor-modal input{padding:4px}body .jsoneditor-modal input[type="text"]{cursor:inherit}body .jsoneditor-modal input[disabled]{background:var(--t42-content-color-muted);color:var(--t42-content-color-muted)}body .jsoneditor-modal .jsoneditor-select-wrapper{position:relative;display:inline-block}body .jsoneditor-modal .jsoneditor-select-wrapper:after{content:"";width:0;height:0;border-left:5px solid transparent;border-right:5px solid transparent;border-top:6px solid #666;position:absolute;right:8px;top:14px;pointer-events:none}body .jsoneditor-modal select{padding:3px 24px 3px 10px;min-width:180px;max-width:350px;-webkit-appearance:none;-moz-appearance:none;appearance:none;text-indent:0;text-overflow:"";font-size:var(--t42-font-size);line-height:1.5em}body .jsoneditor-modal select::-ms-expand{display:none}body .jsoneditor-modal .jsoneditor-button-group input{padding:4px 10px;margin:0;border-radius:0;border-left-style:none}body .jsoneditor-modal .jsoneditor-button-group input.jsoneditor-button-first{border-top-left-radius:3px;border-bottom-left-radius:3px;border-left-style:solid}body .jsoneditor-modal .jsoneditor-button-group input.jsoneditor-button-last{border-top-right-radius:3px;border-bottom-right-radius:3px}body .jsoneditor-modal .jsoneditor-transform-preview{background:var(--t42-color-opacity-10);height:200px}body .jsoneditor-modal .jsoneditor-transform-preview.jsoneditor-error{color:var(--red)}body .jsoneditor-modal .jsoneditor-jmespath-wizard{line-height:1.2em;width:100%;padding:0;border-radius:3px}body .jsoneditor-modal .jsoneditor-jmespath-label{font-weight:bold;color:dodgerblue;margin-top:20px;margin-bottom:5px}body .jsoneditor-modal .jsoneditor-jmespath-wizard-table{width:100%;border-collapse:collapse}body .jsoneditor-modal .jsoneditor-jmespath-wizard-label{font-style:italic;margin:4px 0 2px 0}body .jsoneditor-modal .jsoneditor-inline{position:relative;display:inline-block;width:100%;padding-top:2px;padding-bottom:2px}body .jsoneditor-modal .jsoneditor-inline:not(:last-child){padding-right:2px}body .jsoneditor-modal .jsoneditor-jmespath-filter{display:flex;flex-wrap:wrap}body .jsoneditor-modal .jsoneditor-jmespath-filter-field{width:180px}body .jsoneditor-modal .jsoneditor-jmespath-filter-relation{width:100px}body .jsoneditor-modal .jsoneditor-jmespath-filter-value{min-width:180px;flex:1}body .jsoneditor-modal .jsoneditor-jmespath-sort-field{width:170px}body .jsoneditor-modal .jsoneditor-jmespath-sort-order{width:150px}body .jsoneditor-modal .jsoneditor-jmespath-select-fields{width:100%}body .jsoneditor-modal .selectr-selected{border-color:var(--t42-color-opacity-10);padding:4px 28px 4px 8px}body .jsoneditor-modal .selectr-selected .selectr-tag{background-color:var(--primary);border-radius:5px}body .jsoneditor-modal table th,body .jsoneditor-modal table td{text-align:left;vertical-align:middle;font-weight:normal;color:var(--t42-content-color);border-spacing:0;border-collapse:collapse}body .jsoneditor-modal select,body .jsoneditor-modal textarea,body .jsoneditor-modal input,body .jsoneditor-modal input[type="text"],body .jsoneditor-modal input[type="text"]:focus,body .jsoneditor-modal #query{background:#ffffff;border:1px solid var(--t42-color-opacity-10);color:var(--t42-content-color);border-radius:3px;padding:4px}body .jsoneditor-modal textarea,body .jsoneditor-modal #query{border-radius:unset}body .jsoneditor-modal,body .jsoneditor-modal table td,body .jsoneditor-modal table th,body .jsoneditor-modal select,body .jsoneditor-modal option,body .jsoneditor-modal textarea,body .jsoneditor-modal input,body .jsoneditor-modal input[type="text"],body .jsoneditor-modal #query{font-size:10.5pt;font-family:var(--t42-font-family)}body .jsoneditor-modal #query,body .jsoneditor-modal .jsoneditor-transform-preview{font-family:var(--bs-font-monospace);font-size:var(--t42-font-size);width:100%;box-sizing:border-box}body .jsoneditor-modal input[type="button"],body .jsoneditor-modal input[type="submit"]{background:var(--t42-color-opacity-10);padding:4px 20px}body .jsoneditor-modal select,body .jsoneditor-modal input{cursor:pointer}body .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-asc input.jsoneditor-button-asc,body .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-desc input.jsoneditor-button-desc{background:var(--primary);border-color:var(--primary);color:var(--t42-content-color)}body .jsoneditor{color:var(--t42-content-color);border:thin solid var(--primary);-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;width:100%;height:100%;position:relative;padding:0;line-height:100%}body div.jsoneditor-field,body div.jsoneditor-value,body a.jsoneditor-value,body div.jsoneditor-readonly,body div.jsoneditor-default{border:1px solid transparent;min-height:16px;min-width:32px;line-height:16px;padding:2px;margin:1px;word-wrap:break-word;word-break:break-word;overflow-wrap:break-word;float:left}body div.jsoneditor-field p,body div.jsoneditor-value p{margin:0}body div.jsoneditor-value.jsoneditor-empty::after{content:"value"}body div.jsoneditor-value.jsoneditor-string{color:var(--green)}body div.jsoneditor-value.jsoneditor-number{color:var(--red)}body div.jsoneditor-value.jsoneditor-boolean{color:var(--yellow)}body div.jsoneditor-value.jsoneditor-null{color:var(--primary)}body div.jsoneditor-value.jsoneditor-color-value{color:var(--t42-content-color)}body div.jsoneditor-value.jsoneditor-invalid{color:var(--white)}body div.jsoneditor-readonly{min-width:16px;color:var(--t42-content-color-muted)}body div.jsoneditor-empty{border-color:var(--t42-color-opacity-10);border-style:dashed;border-radius:2px}body div.jsoneditor-field.jsoneditor-empty::after{content:"field"}body div.jsoneditor td{vertical-align:top}body div.jsoneditor td.jsoneditor-separator{padding:3px 0;vertical-align:top;color:var(--t42-content-color-muted)}body div.jsoneditor td.jsoneditor-tree{vertical-align:top}body div.jsoneditor.busy pre.jsoneditor-preview{background:var(--t42-color-opacity-10);color:var(--t42-content-color-muted)}body div.jsoneditor.busy div.jsoneditor-busy{display:inherit}body div.jsoneditor code.jsoneditor-preview{background:none}body div.jsoneditor.jsoneditor-mode-preview pre.jsoneditor-preview{width:100%;height:100%;box-sizing:border-box;overflow:auto;padding:2px;margin:0;white-space:pre-wrap;word-break:break-all}body div.jsoneditor-default{color:var(--t42-content-color-muted);padding-left:10px}body div.jsoneditor-tree{width:100%;height:100%;position:relative;overflow:auto;background:var(--t42-content-color)}body div.jsoneditor-tree button.jsoneditor-button{width:24px;height:24px;padding:0;margin:0;border:none;cursor:pointer;background-color:transparent;background-image:"/"}body div.jsoneditor-tree button.jsoneditor-button:focus{background-color:var(--t42-color-opacity-10);outline:#e5e5e5 solid 1px}body div.jsoneditor-tree button.jsoneditor-collapsed{background-position:0 -48px}body div.jsoneditor-tree button.jsoneditor-expanded{background-position:0 -72px}body div.jsoneditor-tree button.jsoneditor-contextmenu-button{background-position:-48px -72px}body div.jsoneditor-tree button.jsoneditor-invisible{visibility:hidden;background:none}body div.jsoneditor-tree button.jsoneditor-dragarea{background-image:"/";background-position:-72px -72px;cursor:move}body div.jsoneditor-tree *:focus{outline:none}body div.jsoneditor-tree div.jsoneditor-show-more{display:inline-block;padding:3px 4px;margin:2px 0;background-color:var(--t42-color-opacity-10);border-radius:3px;color:var(--t42-content-color-muted);font-family:var(--t42-font-family);font-size:var(--t42-font-size)}body div.jsoneditor-tree div.jsoneditor-show-more a{display:inline-block;color:var(--t42-content-color-muted)}body div.jsoneditor-tree div.jsoneditor-color{display:inline-block;width:12px;height:12px;margin:4px;border:1px solid var(--t42-content-color-muted);cursor:pointer}body div.jsoneditor-tree div.jsoneditor-color.jsoneditor-color-readonly{cursor:inherit}body div.jsoneditor-tree div.jsoneditor-date{background:var(--t42-content-color);color:var(--t42-content-color);font-family:var(--t42-font-family);border-radius:3px;display:inline-block;padding:3px;margin:0 3px}body div.jsoneditor-tree table.jsoneditor-tree{border-collapse:collapse;border-spacing:0;width:100%}body div.jsoneditor-tree .jsoneditor-button{display:block}body div.jsoneditor-tree .jsoneditor-button.jsoneditor-schema-error{width:24px;height:24px;padding:0;margin:0 4px 0 0;background-image:"/";background-position:-168px -48px;background-color:transparent}body div.jsoneditor-outer{position:static;width:100%;height:100%;margin:0;padding:0;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}body div.jsoneditor-outer.has-nav-bar{margin-top:-26px;padding-top:26px}body div.jsoneditor-outer.has-nav-bar.has-main-menu-bar{margin-top:-61px;padding-top:61px}body div.jsoneditor-outer.has-status-bar{margin-bottom:-26px;padding-bottom:26px}body div.jsoneditor-outer.has-main-menu-bar{margin-top:-35px;padding-top:35px}body div.jsoneditor-busy{position:absolute;top:15%;left:0;box-sizing:border-box;width:100%;text-align:center;display:none}body div.jsoneditor-busy span{background-color:var(--t42-color-opacity-10);border:1px solid var(--t42-color-opacity-10);border-radius:3px;padding:5px 15px;box-shadow:var(--t42-shadow)}body div.jsoneditor-field.jsoneditor-empty::after,body div.jsoneditor-value.jsoneditor-empty::after{pointer-events:none;color:var(--t42-content-color-muted);font-size:8pt}body div.jsoneditor-value.jsoneditor-url,body a.jsoneditor-value.jsoneditor-url{color:var(--green);text-decoration:underline}body a.jsoneditor-value.jsoneditor-url{display:inline-block;padding:2px;margin:2px}body a.jsoneditor-value.jsoneditor-url:hover,body a.jsoneditor-value.jsoneditor-url:focus{color:var(--red)}body div.jsoneditor-field[contenteditable="true"]:focus,body div.jsoneditor-field[contenteditable="true"]:hover,body div.jsoneditor-value[contenteditable="true"]:focus,body div.jsoneditor-value[contenteditable="true"]:hover,body div.jsoneditor-field.jsoneditor-highlight,body div.jsoneditor-value.jsoneditor-highlight{background-color:var(--t42-color-opacity-10);border:1px solid var(--t42-color-opacity-10);border-radius:2px}body div.jsoneditor-field.jsoneditor-highlight-active,body div.jsoneditor-field.jsoneditor-highlight-active:focus,body div.jsoneditor-field.jsoneditor-highlight-active:hover,body div.jsoneditor-value.jsoneditor-highlight-active,body div.jsoneditor-value.jsoneditor-highlight-active:focus,body div.jsoneditor-value.jsoneditor-highlight-active:hover{background-color:#fe0;border:1px solid #ffc700;border-radius:2px}body div.jsoneditor-value.jsoneditor-object,body div.jsoneditor-value.jsoneditor-array{min-width:16px}body div.jsoneditor-tree button.jsoneditor-contextmenu-button:hover,body div.jsoneditor-tree button.jsoneditor-contextmenu-button:focus,body div.jsoneditor-tree button.jsoneditor-contextmenu-button.jsoneditor-selected,body tr.jsoneditor-selected.jsoneditor-first button.jsoneditor-contextmenu-button{background-position:-48px -48px}body div.jsoneditor-tree div.jsoneditor-show-more a:hover,body div.jsoneditor-tree div.jsoneditor-show-more a:focus{color:var(--red)}body textarea.jsoneditor-text,body .ace-jsoneditor{min-height:150px}body textarea.jsoneditor-text.ace_editor,body .ace-jsoneditor.ace_editor{font-family:var(--bs-font-monospace)}body textarea.jsoneditor-text{width:100%;height:100%;margin:0;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;outline-width:0;border:none;background-color:var(--t42-content-color);resize:none}body tr.jsoneditor-highlight,body tr.jsoneditor-selected{background-color:var(--t42-content-color-muted)}body tr.jsoneditor-selected button.jsoneditor-dragarea,body tr.jsoneditor-selected button.jsoneditor-contextmenu-button{visibility:hidden}body tr.jsoneditor-selected.jsoneditor-first button.jsoneditor-dragarea,body tr.jsoneditor-selected.jsoneditor-first button.jsoneditor-contextmenu-button{visibility:visible}body div.jsoneditor-tree button.jsoneditor-dragarea:hover,body div.jsoneditor-tree button.jsoneditor-dragarea:focus,body tr.jsoneditor-selected.jsoneditor-first button.jsoneditor-dragarea{background-position:-72px -48px}body div.jsoneditor tr,body div.jsoneditor th,body div.jsoneditor td{padding:0;margin:0}body div.jsoneditor-field,body div.jsoneditor-value,body div.jsoneditor td,body div.jsoneditor th,body div.jsoneditor textarea,body pre.jsoneditor-preview,body .jsoneditor-schema-error,body .jsoneditor-popover{font-family:var(--bs-font-monospace);font-size:var(--t42-font-size);color:var(--t42-content-color)}body .jsoneditor-schema-error{cursor:default;display:inline-block;height:24px;line-height:24px;position:relative;text-align:center;width:24px}body .jsoneditor-popover{background-color:Rgb(var(--t42-bg-light));border-radius:3px;box-shadow:var(--t42-shadow);color:var(--t42-content-color);padding:7px 10px;position:absolute;cursor:auto;width:200px}body .jsoneditor-popover.jsoneditor-above{bottom:32px;left:-98px}body .jsoneditor-popover.jsoneditor-above:before{border-top:7px solid Rgb(var(--t42-bg-light));bottom:-7px}body .jsoneditor-popover.jsoneditor-below{top:32px;left:-98px}body .jsoneditor-popover.jsoneditor-below:before{border-bottom:7px solid Rgb(var(--t42-bg-light));top:-7px}body .jsoneditor-popover.jsoneditor-left{top:-7px;right:32px}body .jsoneditor-popover.jsoneditor-left:before{border-left:7px solid Rgb(var(--t42-bg-light));border-top:7px solid transparent;border-bottom:7px solid transparent;content:"";top:19px;right:-14px;left:inherit;margin-left:inherit;margin-top:-7px;position:absolute}body .jsoneditor-popover.jsoneditor-right{top:-7px;left:32px}body .jsoneditor-popover.jsoneditor-right:before{border-right:7px solid Rgb(var(--t42-bg-light));border-top:7px solid transparent;border-bottom:7px solid transparent;content:"";top:19px;left:-14px;margin-left:inherit;margin-top:-7px;position:absolute}body .jsoneditor-popover:before{border-right:7px solid transparent;border-left:7px solid transparent;content:"";display:block;left:50%;margin-left:-7px;position:absolute}body .jsoneditor-text-errors tr.jump-to-line:hover{text-decoration:underline;cursor:pointer}body .jsoneditor-schema-error:hover .jsoneditor-popover,body .jsoneditor-schema-error:focus .jsoneditor-popover{display:block;animation:fade-in 0.3s linear 1, move-up 0.3s linear 1}@keyframes fade-in{from{opacity:0}to{opacity:1}}body .jsoneditor .jsoneditor-validation-errors-container{max-height:130px;overflow-y:auto}body .jsoneditor .jsoneditor-validation-errors{width:100%;overflow:hidden}body .jsoneditor .jsoneditor-additional-errors{position:absolute;margin:auto;bottom:31px;left:calc(50% - 92px);color:var(--t42-content-color-muted);background-color:Rgb(var(--t42-bg-mid));padding:7px 15px;border-radius:8px}body .jsoneditor .jsoneditor-additional-errors.visible{visibility:visible;opacity:1;transition:opacity 2s linear}body .jsoneditor .jsoneditor-additional-errors.hidden{visibility:hidden;opacity:0;transition:visibility 0s 2s, opacity 2s linear}body .jsoneditor .jsoneditor-text-errors{width:100%;border-collapse:collapse;border-top:1px solid #ffc700}body .jsoneditor .jsoneditor-text-errors td{padding:3px 6px;vertical-align:middle}body .jsoneditor .jsoneditor-text-errors td pre{margin:0;white-space:pre-wrap}body .jsoneditor .jsoneditor-text-errors tr{background-color:var(--t42-color-opacity-10)}body .jsoneditor .jsoneditor-text-errors tr.parse-error{background-color:var(--red)}body .jsoneditor-text-errors .jsoneditor-schema-error{border:none;width:24px;height:24px;padding:0;margin:0 4px 0 0;cursor:pointer}body .jsoneditor-text-errors tr .jsoneditor-schema-error{background-image:"/";background-position:-168px -48px;background-color:transparent}body .jsoneditor-text-errors tr.parse-error .jsoneditor-schema-error{background-image:"/";background-position:-25px 0px;background-color:transparent}body .jsoneditor-anchor{cursor:pointer}body .jsoneditor-anchor .picker_wrapper.popup.popup_bottom{top:28px;left:-10px}body .fadein{-webkit-animation:fadein 0.3s;animation:fadein 0.3s;-moz-animation:fadein 0.3s;-o-animation:fadein 0.3s}@keyframes fadein{0%{opacity:0}100%{opacity:1}}body .jsoneditor-modal input[type="search"].selectr-input{border:1px solid #d3d3d3;width:calc(100% - 4px);margin:2px;padding:4px;box-sizing:border-box}body .jsoneditor-modal button.selectr-input-clear{right:8px}body .jsoneditor-menu{width:100%;height:35px;padding:2px;margin:0;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;color:var(--t42-content-color);background-color:var(--primary);border-bottom:1px solid var(--primary)}body .jsoneditor-menu>button,body .jsoneditor-menu>.jsoneditor-modes>button{width:26px;height:26px;margin:2px;padding:0;border-radius:2px;border:1px solid transparent;background-color:transparent;background-image:"/";color:var(--t42-content-color);opacity:0.8;font-family:var(--t42-font-family);font-size:var(--t42-font-size);float:left}body .jsoneditor-menu>button:hover,body .jsoneditor-menu>.jsoneditor-modes>button:hover{background-color:rgba(255,255,255,0.2);border:1px solid rgba(255,255,255,0.4)}body .jsoneditor-menu>button:focus,body .jsoneditor-menu>button:active,body .jsoneditor-menu>.jsoneditor-modes>button:focus,body .jsoneditor-menu>.jsoneditor-modes>button:active{background-color:rgba(255,255,255,0.3)}body .jsoneditor-menu>button:disabled,body .jsoneditor-menu>.jsoneditor-modes>button:disabled{opacity:0.5;background-color:transparent;border:none}body .jsoneditor-menu>button.jsoneditor-collapse-all{background-position:0 -96px}body .jsoneditor-menu>button.jsoneditor-expand-all{background-position:0 -120px}body .jsoneditor-menu>button.jsoneditor-sort{background-position:-120px -96px}body .jsoneditor-menu>button.jsoneditor-transform{background-position:-144px -96px}body .jsoneditor.jsoneditor-mode-view>.jsoneditor-menu>button.jsoneditor-sort,body .jsoneditor.jsoneditor-mode-form>.jsoneditor-menu>button.jsoneditor-sort,body .jsoneditor.jsoneditor-mode-view>.jsoneditor-menu>button.jsoneditor-transform,body .jsoneditor.jsoneditor-mode-form>.jsoneditor-menu>button.jsoneditor-transform{display:none}body .jsoneditor-menu>button.jsoneditor-undo{background-position:-24px -96px}body .jsoneditor-menu>button.jsoneditor-undo:disabled{background-position:-24px -120px}body .jsoneditor-menu>button.jsoneditor-redo{background-position:-48px -96px}body .jsoneditor-menu>button.jsoneditor-redo:disabled{background-position:-48px -120px}body .jsoneditor-menu>button.jsoneditor-compact{background-position:-72px -96px}body .jsoneditor-menu>button.jsoneditor-format{background-position:-72px -120px}body .jsoneditor-menu>button.jsoneditor-repair{background-position:-96px -96px}body .jsoneditor-menu>.jsoneditor-modes{display:inline-block;float:left}body .jsoneditor-menu>.jsoneditor-modes>button{background-image:none;width:auto;padding-left:6px;padding-right:6px}body .jsoneditor-menu>button.jsoneditor-separator,body .jsoneditor-menu>.jsoneditor-modes>button.jsoneditor-separator{margin-left:10px}body .jsoneditor-menu a{font-family:var(--t42-font-family);font-size:var(--t42-font-size);color:var(--t42-content-color);opacity:0.8;vertical-align:middle}body .jsoneditor-menu a:hover{opacity:1}body .jsoneditor-menu a.jsoneditor-poweredBy{font-size:8pt;position:absolute;right:0;top:0;padding:10px}body .jsoneditor-navigation-bar{width:100%;height:26px;line-height:26px;padding:0;margin:0;border-bottom:1px solid var(--t42-color-opacity-10);-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;color:var(--t42-content-color-muted);background-color:Rgb(var(--t42-bg-mid));overflow:hidden;font-family:var(--t42-font-family);font-size:var(--t42-font-size)}body .jsoneditor-search{font-family:var(--t42-font-family);position:absolute;right:4px;top:4px;border-collapse:collapse;border-spacing:0;display:flex}body .jsoneditor-search input{color:var(--t42-content-color);width:120px;border:none;outline:none;margin:1px;line-height:20px;font-family:var(--t42-font-family)}body .jsoneditor-search button{width:16px;height:24px;padding:0;margin:0;border:none;background:"/";vertical-align:top}body .jsoneditor-search button:hover{background-color:transparent}body .jsoneditor-search button.jsoneditor-refresh{width:18px;background-position:-99px -73px}body .jsoneditor-search button.jsoneditor-next{cursor:pointer;background-position:-124px -73px}body .jsoneditor-search button.jsoneditor-next:hover{background-position:-124px -49px}body .jsoneditor-search button.jsoneditor-previous{cursor:pointer;background-position:-148px -73px;margin-right:2px}body .jsoneditor-search button.jsoneditor-previous:hover{background-position:-148px -49px}body .jsoneditor-results{font-family:var(--t42-font-family);color:var(--t42-content-color);padding-right:5px;line-height:26px}body .jsoneditor-frame{border:1px solid transparent;background-color:var(--t42-content-color);padding:0 2px;margin:0}body .jsoneditor-statusbar{line-height:26px;height:26px;color:var(--t42-content-color-muted);background-color:Rgb(var(--t42-bg-mid));border-top:1px solid var(--t42-color-opacity-10);-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;font-size:var(--t42-font-size)}body .jsoneditor-statusbar>.jsoneditor-curserinfo-val{margin-right:12px}body .jsoneditor-statusbar>.jsoneditor-curserinfo-count{margin-left:4px}body .jsoneditor-statusbar>.jsoneditor-validation-error-icon{float:right;width:24px;height:24px;padding:0;margin-top:1px;background-image:"/";background-position:-168px -48px;cursor:pointer}body .jsoneditor-statusbar>.jsoneditor-validation-error-count{float:right;margin:0 4px 0 0;cursor:pointer}body .jsoneditor-statusbar>.jsoneditor-parse-error-icon{float:right;width:24px;height:24px;padding:0;margin:1px;background-image:"/";background-position:-25px 0px}body .jsoneditor-statusbar .jsoneditor-array-info a{color:inherit}body div.jsoneditor-statusbar>.jsoneditor-curserinfo-label,body div.jsoneditor-statusbar>.jsoneditor-size-info{margin:0 4px}body .jsoneditor-treepath{padding:0 5px;overflow:hidden;white-space:nowrap;outline:none}body .jsoneditor-treepath.show-all{word-wrap:break-word;white-space:normal;position:absolute;background-color:Rgb(var(--t42-bg-mid));z-index:1;box-shadow:var(--t42-shadow)}body .jsoneditor-treepath.show-all span.jsoneditor-treepath-show-all-btn{display:none}body .jsoneditor-treepath div.jsoneditor-contextmenu-root{position:absolute;left:0}body .jsoneditor-treepath .jsoneditor-treepath-show-all-btn{position:absolute;background-color:Rgb(var(--t42-bg-mid));left:0;height:20px;padding:0 3px;cursor:pointer}body .jsoneditor-treepath .jsoneditor-treepath-element{margin:1px;font-family:var(--t42-font-family);font-size:var(--t42-font-size)}body .jsoneditor-treepath .jsoneditor-treepath-seperator{margin:2px;font-size:9pt;font-family:var(--t42-font-family)}body .jsoneditor-treepath span.jsoneditor-treepath-element:hover,body .jsoneditor-treepath span.jsoneditor-treepath-seperator:hover{cursor:pointer;text-decoration:underline}body .selectr-container{position:relative}body .selectr-container li{list-style:none}body .selectr-hidden{position:absolute;overflow:hidden;clip:rect(0px, 0px, 0px, 0px);width:1px;height:1px;margin:-1px;padding:0;border:0 none}body .selectr-visible{position:absolute;left:0;top:0;width:100%;height:100%;opacity:0;z-index:11}body .selectr-desktop.multiple .selectr-visible{display:none}body .selectr-desktop.multiple.native-open .selectr-visible{top:100%;min-height:200px !important;height:auto;opacity:1;display:block}body .selectr-container.multiple.selectr-mobile .selectr-selected{z-index:0}body .selectr-selected{position:relative;z-index:1;box-sizing:border-box;width:100%;padding:7px 28px 7px 14px;cursor:pointer;border:1px solid Rgb(var(--t42-bg-mid));border-radius:3px;background-color:var(--t42-content-color)}body .selectr-selected::before{position:absolute;top:50%;right:10px;width:0;height:0;content:'';-o-transform:rotate(0deg) translate3d(0px, -50%, 0px);-ms-transform:rotate(0deg) translate3d(0px, -50%, 0px);-moz-transform:rotate(0deg) translate3d(0px, -50%, 0px);-webkit-transform:rotate(0deg) translate3d(0px, -50%, 0px);transform:rotate(0deg) translate3d(0px, -50%, 0px);border-width:4px 4px 0 4px;border-style:solid;border-color:#6c7a86 transparent transparent}body .selectr-container.open .selectr-selected::before,body .selectr-container.native-open .selectr-selected::before{border-width:0 4px 4px 4px;border-style:solid;border-color:transparent transparent #6c7a86}body .selectr-label{display:none;overflow:hidden;width:100%;white-space:nowrap;text-overflow:ellipsis}body .selectr-placeholder{color:#6c7a86}body .selectr-tags{margin:0;padding:0;white-space:normal}body .has-selected .selectr-tags{margin:0 0 -2px}body .selectr-tag{list-style:none;position:relative;float:left;padding:2px 25px 2px 8px;margin:0 2px 2px 0;cursor:default;color:var(--t42-content-color);border:medium none;border-radius:10px;background:#acb7bf none repeat scroll 0 0}body .selectr-container.multiple.has-selected .selectr-selected{padding:5px 28px 5px 5px}body .selectr-options-container{position:absolute;z-index:10000;top:calc(100% - 1px);left:0;display:none;box-sizing:border-box;width:100%;border-width:0 1px 1px;border-style:solid;border-color:transparent Rgb(var(--t42-bg-mid)) Rgb(var(--t42-bg-mid));border-radius:0 0 3px 3px;background-color:var(--t42-content-color)}body .selectr-container.open .selectr-options-container{display:block}body .selectr-input-container{position:relative;display:none}body .selectr-clear,body .selectr-input-clear,body .selectr-tag-remove{position:absolute;top:50%;right:22px;width:20px;height:20px;padding:0;cursor:pointer;-o-transform:translate3d(0px, -50%, 0px);-ms-transform:translate3d(0px, -50%, 0px);-moz-transform:translate3d(0px, -50%, 0px);-webkit-transform:translate3d(0px, -50%, 0px);transform:translate3d(0px, -50%, 0px);border:medium none;background-color:transparent;z-index:11}body .selectr-clear,body .selectr-input-clear{display:none}body .selectr-container.has-selected .selectr-clear,body .selectr-input-container.active .selectr-input-clear{display:block}body .selectr-selected .selectr-tag-remove{right:2px}body .selectr-clear::before,body .selectr-clear::after,body .selectr-input-clear::before,body .selectr-input-clear::after,body .selectr-tag-remove::before,body .selectr-tag-remove::after{position:absolute;top:5px;left:9px;width:2px;height:10px;content:' ';background-color:#6c7a86}body .selectr-tag-remove::before,body .selectr-tag-remove::after{top:4px;width:3px;height:12px;background-color:var(--t42-content-color)}body .selectr-clear:before,body .selectr-input-clear::before,body .selectr-tag-remove::before{-o-transform:rotate(45deg);-ms-transform:rotate(45deg);-moz-transform:rotate(45deg);-webkit-transform:rotate(45deg);transform:rotate(45deg)}body .selectr-clear:after,body .selectr-input-clear::after,body .selectr-tag-remove::after{-o-transform:rotate(-45deg);-ms-transform:rotate(-45deg);-moz-transform:rotate(-45deg);-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}body .selectr-input-container.active,body .selectr-input-container.active .selectr-clear{display:block}body .selectr-input{top:5px;left:5px;box-sizing:border-box;width:calc(100% - 30px);margin:10px 15px;padding:7px 30px 7px 9px;border:1px solid Rgb(var(--t42-bg-mid));border-radius:3px}body .selectr-notice{display:none;box-sizing:border-box;width:100%;padding:8px 16px;border-top:1px solid Rgb(var(--t42-bg-mid));border-radius:0 0 3px 3px;background-color:var(--t42-content-color)}body .selectr-container.notice .selectr-notice{display:block}body .selectr-container.notice .selectr-selected{border-radius:3px 3px 0 0}body .selectr-options{position:relative;top:calc(100% + 2px);display:none;overflow-x:auto;overflow-y:scroll;max-height:200px;margin:0;padding:0}body .selectr-container.open .selectr-options,body .selectr-container.open .selectr-input-container,body .selectr-container.notice .selectr-options-container{display:block}body .selectr-option{position:relative;display:block;padding:5px 20px;list-style:outside none none;cursor:pointer;font-weight:normal}body .selectr-options.optgroups>.selectr-option{padding-left:25px}body .selectr-optgroup{font-weight:bold;padding:0}body .selectr-optgroup--label{font-weight:bold;margin-top:10px;padding:5px 15px}body .selectr-match{text-decoration:underline}body .selectr-option.selected{background-color:#ddd}body .selectr-option.active{color:var(--t42-content-color);background-color:#5897fb}body .selectr-option.disabled{opacity:0.4}body .selectr-option.excluded{display:none}body .selectr-container.open .selectr-selected{border-color:Rgb(var(--t42-bg-mid)) Rgb(var(--t42-bg-mid)) transparent Rgb(var(--t42-bg-mid));border-radius:3px 3px 0 0}body .selectr-container.open .selectr-selected::after{-o-transform:rotate(180deg) translate3d(0px, 50%, 0px);-ms-transform:rotate(180deg) translate3d(0px, 50%, 0px);-moz-transform:rotate(180deg) translate3d(0px, 50%, 0px);-webkit-transform:rotate(180deg) translate3d(0px, 50%, 0px);transform:rotate(180deg) translate3d(0px, 50%, 0px)}body .selectr-disabled{opacity:.6}body .selectr-empty,body .has-selected .selectr-placeholder{display:none}body .has-selected .selectr-label{display:block}body .taggable .selectr-selected{padding:4px 28px 4px 4px}body .taggable .selectr-selected::after{display:table;content:" ";clear:both}body .taggable .selectr-label{width:auto}body .taggable .selectr-tags{float:left;display:block}body .taggable .selectr-placeholder{display:none}body .input-tag{float:left;min-width:90px;width:auto}body .selectr-tag-input{border:medium none;padding:3px 10px;width:100%;font-family:inherit;font-weight:inherit;font-size:inherit}body .selectr-input-container.loading::after{position:absolute;top:50%;right:20px;width:20px;height:20px;content:'';-o-transform:translate3d(0px, -50%, 0px);-ms-transform:translate3d(0px, -50%, 0px);-moz-transform:translate3d(0px, -50%, 0px);-webkit-transform:translate3d(0px, -50%, 0px);transform:translate3d(0px, -50%, 0px);-o-transform-origin:50% 0 0;-ms-transform-origin:50% 0 0;-moz-transform-origin:50% 0 0;-webkit-transform-origin:50% 0 0;transform-origin:50% 0 0;-moz-animation:500ms linear 0s normal forwards infinite running selectr-spin;-webkit-animation:500ms linear 0s normal forwards infinite running selectr-spin;animation:500ms linear 0s normal forwards infinite running selectr-spin;border-width:3px;border-style:solid;border-color:#aaa #ddd #ddd;border-radius:50%}@-webkit-keyframes selectr-spin{0%{-webkit-transform:rotate(0deg) translate3d(0px, -50%, 0px);transform:rotate(0deg) translate3d(0px, -50%, 0px)}100%{-webkit-transform:rotate(360deg) translate3d(0px, -50%, 0px);transform:rotate(360deg) translate3d(0px, -50%, 0px)}}@keyframes selectr-spin{0%{-webkit-transform:rotate(0deg) translate3d(0px, -50%, 0px);transform:rotate(0deg) translate3d(0px, -50%, 0px)}100%{-webkit-transform:rotate(360deg) translate3d(0px, -50%, 0px);transform:rotate(360deg) translate3d(0px, -50%, 0px)}}body .selectr-container.open.inverted .selectr-selected{border-color:transparent Rgb(var(--t42-bg-mid)) Rgb(var(--t42-bg-mid));border-radius:0 0 3px 3px}body .selectr-container.inverted .selectr-options-container{border-width:1px 1px 0;border-color:Rgb(var(--t42-bg-mid)) Rgb(var(--t42-bg-mid)) transparent;border-radius:3px 3px 0 0;background-color:var(--t42-content-color)}body .selectr-container.inverted .selectr-options-container{top:auto;bottom:calc(100% - 1px)}body .selectr-container ::-webkit-input-placeholder{color:#6c7a86;opacity:1}body .selectr-container ::-moz-placeholder{color:#6c7a86;opacity:1}body .selectr-container :-ms-input-placeholder{color:#6c7a86;opacity:1}body .selectr-container ::placeholder{color:#6c7a86;opacity:1}body #jsoneditor{height:100%}body .jsoneditor{border-color:var(--t42-color-opacity-10)}body .jsoneditor textarea{line-height:1.5;background-color:Rgb(var(--t42-bg-dark));min-height:100%}body .jsoneditor input{outline:0}body .jsoneditor input:focus{outline:0}body .jsoneditor-button:focus{outline:none}body .jsoneditor-menu{border-bottom-color:var(--t42-color-opacity-10);background-color:Rgb(var(--t42-bg-light))}body .jsoneditor-menu button{background-image:var(--t42-json-icons);background-color:transparent}body .jsoneditor-menu button:hover,body .jsoneditor-menu button:focus{color:var(--t42-link-hover-color)}body .jsoneditor-menu>button,body .jsoneditor-menu>.jsoneditor-modes>button{border-radius:0;font-size:.75rem;backdrop-filter:var(--backdrop-filter);transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, color}body .jsoneditor-menu>button:hover:not(.disabled):not(:disabled),body .jsoneditor-menu>button:active,body .jsoneditor-menu>.jsoneditor-modes>button:hover:not(.disabled):not(:disabled),body .jsoneditor-menu>.jsoneditor-modes>button:active{border-color:transparent;color:var(--t42-link-hover-color);background-color:var(--t42-color-opacity-10)}body .jsoneditor-menu li button.jsoneditor-selected{background-color:var(--t42-color-opacity-10)}body .jsoneditor-menu .jsoneditor-poweredBy{display:none}body .jsoneditor-frame{padding:0 .875rem;border-color:var(--t42-color-opacity-10);background-color:transparent;display:flex;transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border-color}body .jsoneditor-frame:focus-within{border-color:var(--primary);background-color:var(--t42-input-bg);outline:0}body .jsoneditor-frame table td{vertical-align:middle}body .jsoneditor-search input[type="text"]{border:0}body .jsoneditor-search input[type="text"]:focus{border:0}body .jsoneditor-search input{background-color:transparent}body .jsoneditor-contextmenu{z-index:2}body .jsoneditor-contextmenu .jsoneditor-menu{border-color:var(--t42-color-opacity-10);background:linear-gradient(to bottom right, rgba(var(--t42-bg-light), 0.75) 0%, rgba(var(--t42-bg-dark), 0.75) 100%);box-shadow:var(--t42-shadow);backdrop-filter:var(--backdrop-filter)}body .jsoneditor-contextmenu .jsoneditor-menu button button .jsoneditor-expand,body .jsoneditor-contextmenu .jsoneditor-menu li button .jsoneditor-expand{background-image:var(--t42-json-icons);z-index:1}body .jsoneditor-contextmenu .jsoneditor-menu button button.jsoneditor-selected,body .jsoneditor-contextmenu .jsoneditor-menu li button.jsoneditor-selected{background-color:var(--t42-color-opacity-10);transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, color}body .jsoneditor-contextmenu .jsoneditor-menu button button.jsoneditor-selected:hover,body .jsoneditor-contextmenu .jsoneditor-menu button button.jsoneditor-selected:focus,body .jsoneditor-contextmenu .jsoneditor-menu li button.jsoneditor-selected:hover,body .jsoneditor-contextmenu .jsoneditor-menu li button.jsoneditor-selected:focus{color:var(--t42-link-hover-color);background-color:var(--t42-color-opacity-10)}body .jsoneditor-contextmenu .jsoneditor-menu button{display:flex;justify-content:start}body .jsoneditor-contextmenu .jsoneditor-menu button.jsoneditor-default{float:left;z-index:1}body .jsoneditor-contextmenu .jsoneditor-menu li ul{padding:0 !important;left:0}body .jsoneditor-contextmenu .jsoneditor-menu li ul li button{padding-left:1rem}body .jsoneditor-contextmenu .jsoneditor-menu li ul .jsoneditor-icon{position:relative;margin-left:0}body .jsoneditor-contextmenu .jsoneditor-menu .jsoneditor-text{padding:0;line-height:1.5rem}body .jsoneditor-contextmenu .jsoneditor-icon{position:relative;background-image:var(--t42-json-icons)}body .jsoneditor-contextmenu .jsoneditor-separator{margin-top:0;padding-top:0}body .jsoneditor-mode-preview pre.jsoneditor-preview{border:0;line-height:1.5}body .jsoneditor-modal{border-top:0;background:linear-gradient(to bottom right, rgba(var(--t42-bg-light), 0.75) 0%, rgba(var(--t42-bg-dark), 0.75) 100%) !important;box-shadow:var(--t42-shadow) !important;backdrop-filter:var(--backdrop-filter)}body .jsoneditor-modal::before{position:absolute;top:0;right:0;left:0;display:block;width:100%;height:0.0625rem;background:linear-gradient(90deg, #007be5 0%, rgba(0,123,229,0.5) 100%);content:""}body .jsoneditor-modal .pico-modal-header{padding:0.5rem 0.988rem;background:transparent;font-size:0.75rem}body .jsoneditor-modal .pico-close{top:1rem !important;right:1rem !important;color:var(--t42-content-color-muted);transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:color}body .jsoneditor-modal .pico-close:not(.disabled):not(:disabled).active,body .jsoneditor-modal .pico-close:not(.disabled):not(:disabled):focus,body .jsoneditor-modal .pico-close:not(.disabled):not(:disabled):hover{color:var(--t42-link-color)}body .jsoneditor-modal table td{font-size:0.75rem;padding:0 0.25rem}body .jsoneditor-modal table td.jsoneditor-modal-input{padding-top:0.25rem;padding-bottom:0.25rem;text-align:left}body .jsoneditor-modal table td.jsoneditor-modal-input.jsoneditor-modal-actions{text-align:right}body .jsoneditor-modal table th{font-size:0.75rem}body .jsoneditor-modal label,body .jsoneditor-modal p{font-size:0.75rem}body .jsoneditor-modal select{min-width:12.375rem}body .jsoneditor-modal .selectr-selected{padding:0 0.857rem}body .jsoneditor-modal select,body .jsoneditor-modal textarea,body .jsoneditor-modal input,body .jsoneditor-modal input[type="text"],body .jsoneditor-modal input[type="search"],body .jsoneditor-modal #query{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border;border-color:var(--t42-color-opacity-10);border-radius:0;font-size:0.75rem;background-color:var(--t42-input-bg)}body .jsoneditor-modal select:focus,body .jsoneditor-modal textarea:focus,body .jsoneditor-modal input:focus,body .jsoneditor-modal input[type="text"]:focus,body .jsoneditor-modal input[type="search"]:focus,body .jsoneditor-modal #query:focus{border-color:var(--primary);box-shadow:none;outline:0;padding:0 0 0 .875rem;border-radius:0}body .jsoneditor-modal select:disabled,body .jsoneditor-modal select.disabled,body .jsoneditor-modal select[readonly],body .jsoneditor-modal textarea:disabled,body .jsoneditor-modal textarea.disabled,body .jsoneditor-modal textarea[readonly],body .jsoneditor-modal input:disabled,body .jsoneditor-modal input.disabled,body .jsoneditor-modal input[readonly],body .jsoneditor-modal input[type="text"]:disabled,body .jsoneditor-modal input[type="text"].disabled,body .jsoneditor-modal input[type="text"][readonly],body .jsoneditor-modal input[type="search"]:disabled,body .jsoneditor-modal input[type="search"].disabled,body .jsoneditor-modal input[type="search"][readonly],body .jsoneditor-modal #query:disabled,body .jsoneditor-modal #query.disabled,body .jsoneditor-modal #query[readonly]{cursor:default;opacity:0.65}body .jsoneditor-modal input[type="search"].selectr-input{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border-color;border:var(--t42-border);background-color:var(--t42-input-bg);margin:0;line-height:1.5rem;width:100%;padding:0 0.5rem}body .jsoneditor-modal input[type="search"].selectr-input:hover{border-color:var(--primary)}body .jsoneditor-modal .jsoneditor-select-wrapper::after{border-top:var(--t42-color-opacity-10)}body .jsoneditor-modal input[type="button"],body .jsoneditor-modal input[type="submit"]{padding:0 .875rem;border-radius:0;color:var(--t42-link-color);line-height:1.875rem;background:transparent;transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, border-color}body .jsoneditor-modal input[type="button"]:not(.disabled):not(:disabled).active,body .jsoneditor-modal input[type="button"]:not(.disabled):not(:disabled):hover,body .jsoneditor-modal input[type="submit"]:not(.disabled):not(:disabled).active,body .jsoneditor-modal input[type="submit"]:not(.disabled):not(:disabled):hover{border-color:var(--t42-color-opacity-30);color:var(--white);background:var(--primary)}body .jsoneditor-modal .jsoneditor-button-group input.jsoneditor-button-first{border-left-style:solid;border-top-left-radius:0;border-bottom-left-radius:0}body .jsoneditor-modal .jsoneditor-button-group input.jsoneditor-button-last{border-top-right-radius:0;border-bottom-right-radius:0}body .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-asc input.jsoneditor-button-asc,body .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-desc input.jsoneditor-button-desc{color:var(--white);background:var(--primary)}body .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-asc input.jsoneditor-button-asc:hover,body .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-asc input.jsoneditor-button-asc:focus,body .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-asc input.jsoneditor-button-asc:active,body .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-desc input.jsoneditor-button-desc:hover,body .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-desc input.jsoneditor-button-desc:focus,body .jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-desc input.jsoneditor-button-desc:active{border-color:var(--t42-color-opacity-30);color:var(--white)}body .jsoneditor-modal .jsoneditor-jmespath-label{color:var(--t42-content-color);font-weight:400}body .jsoneditor-modal .jsoneditor-jmespath-filter-value input{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border-color;line-height:1.875rem;padding:0 0 0 .875rem;font-size:0.75rem;background-color:var(--t42-input-bg)}body .jsoneditor-modal .jsoneditor-jmespath-filter-value input:focus,body .jsoneditor-modal .jsoneditor-jmespath-filter-value input:hover{background-color:var(--t42-input-bg);border-color:var(--primary)}body .jsoneditor-jmespath-block .jsoneditor-modal-actions{text-align:right}body div.jsoneditor td.jsoneditor-tree{vertical-align:middle}body div.jsoneditor td.jsoneditor-separator{vertical-align:middle}body div.jsoneditor-tree{background:transparent}body div.jsoneditor-tree button.jsoneditor-button{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-color, outline-color;background-image:var(--t42-json-icons)}body div.jsoneditor-tree button.jsoneditor-button:focus{background-color:transparent;outline-color:var(--t42-color-opacity-10)}body tr.jsoneditor-selected,body tr.jsoneditor-highlight{background-color:var(--t42-color-opacity-10)}body .selectr-selected{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border-color;height:2rem;font-size:0.75rem;font-weight:400;line-height:1.875rem;background-color:var(--t42-input-bg);border-radius:0}body .selectr-selected::before{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:transform;right:0.5rem;border:0;width:0.75rem;height:0.75rem;background:var(--t42-select-indicator) center center/1rem 1rem no-repeat;transform:translateY(-50%)}body .selectr-placeholder{color:var(--t42-content-color-muted)}body .selectr-container.open .selectr-selected{border-radius:0;border-color:var(--primary)}body .selectr-container.open .selectr-selected::before{border:0;transform:rotate(180deg) translateY(50%)}body .selectr-container.open .selectr-options-container{border-left-color:var(--primary);border-right-color:var(--primary);border-bottom-color:var(--primary)}body .selectr-options{overflow-y:auto}body .selectr-options-container{min-height:2rem;border-color:var(--t42-color-opacity-10);border-style:solid;border-width:1px;background-color:Rgb(var(--t42-bg-dark))}body .selectr-options .active{color:var(--t42-link-hover-color);background-color:var(--t42-color-opacity-10)}body .selectr-options .selected{color:var(--t42-link-hover-color);background-color:var(--primary)}body .selectr-option{padding:0 0 0 0.875rem;line-height:2rem;font-size:0.75rem}body .selectr-input{transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:border-color;border:var(--t42-border);background-color:var(--t42-input-bg)}body .selectr-input:hover{border-color:var(--primary)}body .selectr-input-container{padding:0.25rem}body .selectr-clear::before,body .selectr-clear::after{background-color:var(--t42-content-color)}body .jsoneditor .ace-jsoneditor .ace_text-input{min-height:auto}body .jsoneditor .ace-jsoneditor.ace_editor,body .jsoneditor .ace-jsoneditor .ace_scroller{background-color:Rgb(var(--t42-bg-dark))}body .jsoneditor .ace-jsoneditor .ace_gutter{color:var(--t42-content-color-muted);background-color:Rgb(var(--t42-bg-mid))}body .jsoneditor .ace-jsoneditor .ace_gutter-active-line{background-color:Rgb(var(--t42-bg-light))}body .jsoneditor .ace-jsoneditor .ace_cursor{border-color:Rgb(var(--t42-content-color))}body .jsoneditor .ace-jsoneditor .ace_marker-layer .ace_active-line{background-color:rgba(var(--secondary), 0.25)}body .jsoneditor .ace-jsoneditor .ace_marker-layer .ace_selection{background-color:var(--t42-color-opacity-10)}body .jsoneditor .ace-jsoneditor .ace_marker-layer .ace_selected-word{border-color:var(--t42-color-opacity-10);background-color:var(--t42-color-opacity-10)}body .jsoneditor .ace-jsoneditor .ace_marker-layer .ace_bracket{border:var(--t42-border)}body .jsoneditor .ace-jsoneditor .ace_variable{color:var(--t42-content-color)}body .jsoneditor .ace-jsoneditor .ace_constant.ace_numeric{color:#ff511f}body .jsoneditor .ace-jsoneditor .ace_constant.ace_language{color:#f9a825}body .jsoneditor .ace-jsoneditor .ace_string{color:#43a047}body .jsoneditor .ace-jsoneditor .ace_fold{border-color:var(--t42-color-opacity-10);background-color:Rgb(var(--t42-bg-light));transition-timing-function:cubic-bezier(0.45, 0, 0.15, 1);transition-duration:250ms;transition-property:background-image}body .jsoneditor .ace-jsoneditor .ace_fold-widget:hover,body .jsoneditor .ace-jsoneditor .ace_fold-widget:active{border-color:var(--t42-color-opacity-30);background-color:var(--t42-color-opacity-10);box-shadow:none}body .pico-modal-contents{display:block} + diff --git a/typescript/start/stocks/src/lib/workspaces.umd.js b/typescript/start/stocks/src/lib/workspaces.umd.js new file mode 100644 index 0000000..53ca1d8 --- /dev/null +++ b/typescript/start/stocks/src/lib/workspaces.umd.js @@ -0,0 +1,5302 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define(factory) : + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.workspaces = factory()); +})(this, (function () { 'use strict'; + + function getDefaultExportFromCjs (x) { + return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; + } + + function createRegistry(options) { + if (options && options.errorHandling + && typeof options.errorHandling !== "function" + && options.errorHandling !== "log" + && options.errorHandling !== "silent" + && options.errorHandling !== "throw") { + throw new Error("Invalid options passed to createRegistry. Prop errorHandling should be [\"log\" | \"silent\" | \"throw\" | (err) => void], but " + typeof options.errorHandling + " was passed"); + } + var _userErrorHandler = options && typeof options.errorHandling === "function" && options.errorHandling; + var callbacks = {}; + function add(key, callback, replayArgumentsArr) { + var callbacksForKey = callbacks[key]; + if (!callbacksForKey) { + callbacksForKey = []; + callbacks[key] = callbacksForKey; + } + callbacksForKey.push(callback); + if (replayArgumentsArr) { + setTimeout(function () { + replayArgumentsArr.forEach(function (replayArgument) { + var _a; + if ((_a = callbacks[key]) === null || _a === void 0 ? void 0 : _a.includes(callback)) { + try { + if (Array.isArray(replayArgument)) { + callback.apply(undefined, replayArgument); + } + else { + callback.apply(undefined, [replayArgument]); + } + } + catch (err) { + _handleError(err, key); + } + } + }); + }, 0); + } + return function () { + var allForKey = callbacks[key]; + if (!allForKey) { + return; + } + allForKey = allForKey.reduce(function (acc, element, index) { + if (!(element === callback && acc.length === index)) { + acc.push(element); + } + return acc; + }, []); + if (allForKey.length === 0) { + delete callbacks[key]; + } + else { + callbacks[key] = allForKey; + } + }; + } + function execute(key) { + var argumentsArr = []; + for (var _i = 1; _i < arguments.length; _i++) { + argumentsArr[_i - 1] = arguments[_i]; + } + var callbacksForKey = callbacks[key]; + if (!callbacksForKey || callbacksForKey.length === 0) { + return []; + } + var results = []; + callbacksForKey.forEach(function (callback) { + try { + var result = callback.apply(undefined, argumentsArr); + results.push(result); + } + catch (err) { + results.push(undefined); + _handleError(err, key); + } + }); + return results; + } + function _handleError(exceptionArtifact, key) { + var errParam = exceptionArtifact instanceof Error ? exceptionArtifact : new Error(exceptionArtifact); + if (_userErrorHandler) { + _userErrorHandler(errParam); + return; + } + var msg = "[ERROR] callback-registry: User callback for key \"" + key + "\" failed: " + errParam.stack; + if (options) { + switch (options.errorHandling) { + case "log": + return console.error(msg); + case "silent": + return; + case "throw": + throw new Error(msg); + } + } + console.error(msg); + } + function clear() { + callbacks = {}; + } + function clearKey(key) { + var callbacksForKey = callbacks[key]; + if (!callbacksForKey) { + return; + } + delete callbacks[key]; + } + return { + add: add, + execute: execute, + clear: clear, + clearKey: clearKey + }; + } + createRegistry.default = createRegistry; + var lib = createRegistry; + + + var CallbackFactory = /*@__PURE__*/getDefaultExportFromCjs(lib); + + /** + * Wraps values in an `Ok` type. + * + * Example: `ok(5) // => {ok: true, result: 5}` + */ + var ok = function (result) { return ({ ok: true, result: result }); }; + /** + * Wraps errors in an `Err` type. + * + * Example: `err('on fire') // => {ok: false, error: 'on fire'}` + */ + var err = function (error) { return ({ ok: false, error: error }); }; + /** + * Create a `Promise` that either resolves with the result of `Ok` or rejects + * with the error of `Err`. + */ + var asPromise = function (r) { + return r.ok === true ? Promise.resolve(r.result) : Promise.reject(r.error); + }; + /** + * Unwraps a `Result` and returns either the result of an `Ok`, or + * `defaultValue`. + * + * Example: + * ``` + * Result.withDefault(5, number().run(json)) + * ``` + * + * It would be nice if `Decoder` had an instance method that mirrored this + * function. Such a method would look something like this: + * ``` + * class Decoder { + * runWithDefault = (defaultValue: A, json: any): A => + * Result.withDefault(defaultValue, this.run(json)); + * } + * + * number().runWithDefault(5, json) + * ``` + * Unfortunately, the type of `defaultValue: A` on the method causes issues + * with type inference on the `object` decoder in some situations. While these + * inference issues can be solved by providing the optional type argument for + * `object`s, the extra trouble and confusion doesn't seem worth it. + */ + var withDefault = function (defaultValue, r) { + return r.ok === true ? r.result : defaultValue; + }; + /** + * Return the successful result, or throw an error. + */ + var withException = function (r) { + if (r.ok === true) { + return r.result; + } + else { + throw r.error; + } + }; + /** + * Apply `f` to the result of an `Ok`, or pass the error through. + */ + var map = function (f, r) { + return r.ok === true ? ok(f(r.result)) : r; + }; + /** + * Apply `f` to the result of two `Ok`s, or pass an error through. If both + * `Result`s are errors then the first one is returned. + */ + var map2 = function (f, ar, br) { + return ar.ok === false ? ar : + br.ok === false ? br : + ok(f(ar.result, br.result)); + }; + /** + * Apply `f` to the error of an `Err`, or pass the success through. + */ + var mapError = function (f, r) { + return r.ok === true ? r : err(f(r.error)); + }; + /** + * Chain together a sequence of computations that may fail, similar to a + * `Promise`. If the first computation fails then the error will propagate + * through. If it succeeds, then `f` will be applied to the value, returning a + * new `Result`. + */ + var andThen = function (f, r) { + return r.ok === true ? f(r.result) : r; + }; + + /*! ***************************************************************************** + Copyright (c) Microsoft Corporation. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THIS SOFTWARE. + ***************************************************************************** */ + /* global Reflect, Promise */ + + + + var __assign = function() { + __assign = Object.assign || function __assign(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; + } + return t; + }; + return __assign.apply(this, arguments); + }; + + function __rest(s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { + if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) + t[p[i]] = s[p[i]]; + } + return t; + } + + function isEqual(a, b) { + if (a === b) { + return true; + } + if (a === null && b === null) { + return true; + } + if (typeof (a) !== typeof (b)) { + return false; + } + if (typeof (a) === 'object') { + // Array + if (Array.isArray(a)) { + if (!Array.isArray(b)) { + return false; + } + if (a.length !== b.length) { + return false; + } + for (var i = 0; i < a.length; i++) { + if (!isEqual(a[i], b[i])) { + return false; + } + } + return true; + } + // Hash table + var keys = Object.keys(a); + if (keys.length !== Object.keys(b).length) { + return false; + } + for (var i = 0; i < keys.length; i++) { + if (!b.hasOwnProperty(keys[i])) { + return false; + } + if (!isEqual(a[keys[i]], b[keys[i]])) { + return false; + } + } + return true; + } + } + /* + * Helpers + */ + var isJsonArray = function (json) { return Array.isArray(json); }; + var isJsonObject = function (json) { + return typeof json === 'object' && json !== null && !isJsonArray(json); + }; + var typeString = function (json) { + switch (typeof json) { + case 'string': + return 'a string'; + case 'number': + return 'a number'; + case 'boolean': + return 'a boolean'; + case 'undefined': + return 'undefined'; + case 'object': + if (json instanceof Array) { + return 'an array'; + } + else if (json === null) { + return 'null'; + } + else { + return 'an object'; + } + default: + return JSON.stringify(json); + } + }; + var expectedGot = function (expected, got) { + return "expected " + expected + ", got " + typeString(got); + }; + var printPath = function (paths) { + return paths.map(function (path) { return (typeof path === 'string' ? "." + path : "[" + path + "]"); }).join(''); + }; + var prependAt = function (newAt, _a) { + var at = _a.at, rest = __rest(_a, ["at"]); + return (__assign({ at: newAt + (at || '') }, rest)); + }; + /** + * Decoders transform json objects with unknown structure into known and + * verified forms. You can create objects of type `Decoder` with either the + * primitive decoder functions, such as `boolean()` and `string()`, or by + * applying higher-order decoders to the primitives, such as `array(boolean())` + * or `dict(string())`. + * + * Each of the decoder functions are available both as a static method on + * `Decoder` and as a function alias -- for example the string decoder is + * defined at `Decoder.string()`, but is also aliased to `string()`. Using the + * function aliases exported with the library is recommended. + * + * `Decoder` exposes a number of 'run' methods, which all decode json in the + * same way, but communicate success and failure in different ways. The `map` + * and `andThen` methods modify decoders without having to call a 'run' method. + * + * Alternatively, the main decoder `run()` method returns an object of type + * `Result`. This library provides a number of helper + * functions for dealing with the `Result` type, so you can do all the same + * things with a `Result` as with the decoder methods. + */ + var Decoder = /** @class */ (function () { + /** + * The Decoder class constructor is kept private to separate the internal + * `decode` function from the external `run` function. The distinction + * between the two functions is that `decode` returns a + * `Partial` on failure, which contains an unfinished error + * report. When `run` is called on a decoder, the relevant series of `decode` + * calls is made, and then on failure the resulting `Partial` + * is turned into a `DecoderError` by filling in the missing information. + * + * While hiding the constructor may seem restrictive, leveraging the + * provided decoder combinators and helper functions such as + * `andThen` and `map` should be enough to build specialized decoders as + * needed. + */ + function Decoder(decode) { + var _this = this; + this.decode = decode; + /** + * Run the decoder and return a `Result` with either the decoded value or a + * `DecoderError` containing the json input, the location of the error, and + * the error message. + * + * Examples: + * ``` + * number().run(12) + * // => {ok: true, result: 12} + * + * string().run(9001) + * // => + * // { + * // ok: false, + * // error: { + * // kind: 'DecoderError', + * // input: 9001, + * // at: 'input', + * // message: 'expected a string, got 9001' + * // } + * // } + * ``` + */ + this.run = function (json) { + return mapError(function (error) { return ({ + kind: 'DecoderError', + input: json, + at: 'input' + (error.at || ''), + message: error.message || '' + }); }, _this.decode(json)); + }; + /** + * Run the decoder as a `Promise`. + */ + this.runPromise = function (json) { return asPromise(_this.run(json)); }; + /** + * Run the decoder and return the value on success, or throw an exception + * with a formatted error string. + */ + this.runWithException = function (json) { return withException(_this.run(json)); }; + /** + * Construct a new decoder that applies a transformation to the decoded + * result. If the decoder succeeds then `f` will be applied to the value. If + * it fails the error will propagated through. + * + * Example: + * ``` + * number().map(x => x * 5).run(10) + * // => {ok: true, result: 50} + * ``` + */ + this.map = function (f) { + return new Decoder(function (json) { return map(f, _this.decode(json)); }); + }; + /** + * Chain together a sequence of decoders. The first decoder will run, and + * then the function will determine what decoder to run second. If the result + * of the first decoder succeeds then `f` will be applied to the decoded + * value. If it fails the error will propagate through. + * + * This is a very powerful method -- it can act as both the `map` and `where` + * methods, can improve error messages for edge cases, and can be used to + * make a decoder for custom types. + * + * Example of adding an error message: + * ``` + * const versionDecoder = valueAt(['version'], number()); + * const infoDecoder3 = object({a: boolean()}); + * + * const decoder = versionDecoder.andThen(version => { + * switch (version) { + * case 3: + * return infoDecoder3; + * default: + * return fail(`Unable to decode info, version ${version} is not supported.`); + * } + * }); + * + * decoder.run({version: 3, a: true}) + * // => {ok: true, result: {a: true}} + * + * decoder.run({version: 5, x: 'abc'}) + * // => + * // { + * // ok: false, + * // error: {... message: 'Unable to decode info, version 5 is not supported.'} + * // } + * ``` + * + * Example of decoding a custom type: + * ``` + * // nominal type for arrays with a length of at least one + * type NonEmptyArray = T[] & { __nonEmptyArrayBrand__: void }; + * + * const nonEmptyArrayDecoder = (values: Decoder): Decoder> => + * array(values).andThen(arr => + * arr.length > 0 + * ? succeed(createNonEmptyArray(arr)) + * : fail(`expected a non-empty array, got an empty array`) + * ); + * ``` + */ + this.andThen = function (f) { + return new Decoder(function (json) { + return andThen(function (value) { return f(value).decode(json); }, _this.decode(json)); + }); + }; + /** + * Add constraints to a decoder _without_ changing the resulting type. The + * `test` argument is a predicate function which returns true for valid + * inputs. When `test` fails on an input, the decoder fails with the given + * `errorMessage`. + * + * ``` + * const chars = (length: number): Decoder => + * string().where( + * (s: string) => s.length === length, + * `expected a string of length ${length}` + * ); + * + * chars(5).run('12345') + * // => {ok: true, result: '12345'} + * + * chars(2).run('HELLO') + * // => {ok: false, error: {... message: 'expected a string of length 2'}} + * + * chars(12).run(true) + * // => {ok: false, error: {... message: 'expected a string, got a boolean'}} + * ``` + */ + this.where = function (test, errorMessage) { + return _this.andThen(function (value) { return (test(value) ? Decoder.succeed(value) : Decoder.fail(errorMessage)); }); + }; + } + /** + * Decoder primitive that validates strings, and fails on all other input. + */ + Decoder.string = function () { + return new Decoder(function (json) { + return typeof json === 'string' + ? ok(json) + : err({ message: expectedGot('a string', json) }); + }); + }; + /** + * Decoder primitive that validates numbers, and fails on all other input. + */ + Decoder.number = function () { + return new Decoder(function (json) { + return typeof json === 'number' + ? ok(json) + : err({ message: expectedGot('a number', json) }); + }); + }; + /** + * Decoder primitive that validates booleans, and fails on all other input. + */ + Decoder.boolean = function () { + return new Decoder(function (json) { + return typeof json === 'boolean' + ? ok(json) + : err({ message: expectedGot('a boolean', json) }); + }); + }; + Decoder.constant = function (value) { + return new Decoder(function (json) { + return isEqual(json, value) + ? ok(value) + : err({ message: "expected " + JSON.stringify(value) + ", got " + JSON.stringify(json) }); + }); + }; + Decoder.object = function (decoders) { + return new Decoder(function (json) { + if (isJsonObject(json) && decoders) { + var obj = {}; + for (var key in decoders) { + if (decoders.hasOwnProperty(key)) { + var r = decoders[key].decode(json[key]); + if (r.ok === true) { + // tslint:disable-next-line:strict-type-predicates + if (r.result !== undefined) { + obj[key] = r.result; + } + } + else if (json[key] === undefined) { + return err({ message: "the key '" + key + "' is required but was not present" }); + } + else { + return err(prependAt("." + key, r.error)); + } + } + } + return ok(obj); + } + else if (isJsonObject(json)) { + return ok(json); + } + else { + return err({ message: expectedGot('an object', json) }); + } + }); + }; + Decoder.array = function (decoder) { + return new Decoder(function (json) { + if (isJsonArray(json) && decoder) { + var decodeValue_1 = function (v, i) { + return mapError(function (err$$1) { return prependAt("[" + i + "]", err$$1); }, decoder.decode(v)); + }; + return json.reduce(function (acc, v, i) { + return map2(function (arr, result) { return arr.concat([result]); }, acc, decodeValue_1(v, i)); + }, ok([])); + } + else if (isJsonArray(json)) { + return ok(json); + } + else { + return err({ message: expectedGot('an array', json) }); + } + }); + }; + Decoder.tuple = function (decoders) { + return new Decoder(function (json) { + if (isJsonArray(json)) { + if (json.length !== decoders.length) { + return err({ + message: "expected a tuple of length " + decoders.length + ", got one of length " + json.length + }); + } + var result = []; + for (var i = 0; i < decoders.length; i++) { + var nth = decoders[i].decode(json[i]); + if (nth.ok) { + result[i] = nth.result; + } + else { + return err(prependAt("[" + i + "]", nth.error)); + } + } + return ok(result); + } + else { + return err({ message: expectedGot("a tuple of length " + decoders.length, json) }); + } + }); + }; + Decoder.union = function (ad, bd) { + var decoders = []; + for (var _i = 2; _i < arguments.length; _i++) { + decoders[_i - 2] = arguments[_i]; + } + return Decoder.oneOf.apply(Decoder, [ad, bd].concat(decoders)); + }; + Decoder.intersection = function (ad, bd) { + var ds = []; + for (var _i = 2; _i < arguments.length; _i++) { + ds[_i - 2] = arguments[_i]; + } + return new Decoder(function (json) { + return [ad, bd].concat(ds).reduce(function (acc, decoder) { return map2(Object.assign, acc, decoder.decode(json)); }, ok({})); + }); + }; + /** + * Escape hatch to bypass validation. Always succeeds and types the result as + * `any`. Useful for defining decoders incrementally, particularly for + * complex objects. + * + * Example: + * ``` + * interface User { + * name: string; + * complexUserData: ComplexType; + * } + * + * const userDecoder: Decoder = object({ + * name: string(), + * complexUserData: anyJson() + * }); + * ``` + */ + Decoder.anyJson = function () { return new Decoder(function (json) { return ok(json); }); }; + /** + * Decoder identity function which always succeeds and types the result as + * `unknown`. + */ + Decoder.unknownJson = function () { + return new Decoder(function (json) { return ok(json); }); + }; + /** + * Decoder for json objects where the keys are unknown strings, but the values + * should all be of the same type. + * + * Example: + * ``` + * dict(number()).run({chocolate: 12, vanilla: 10, mint: 37}); + * // => {ok: true, result: {chocolate: 12, vanilla: 10, mint: 37}} + * ``` + */ + Decoder.dict = function (decoder) { + return new Decoder(function (json) { + if (isJsonObject(json)) { + var obj = {}; + for (var key in json) { + if (json.hasOwnProperty(key)) { + var r = decoder.decode(json[key]); + if (r.ok === true) { + obj[key] = r.result; + } + else { + return err(prependAt("." + key, r.error)); + } + } + } + return ok(obj); + } + else { + return err({ message: expectedGot('an object', json) }); + } + }); + }; + /** + * Decoder for values that may be `undefined`. This is primarily helpful for + * decoding interfaces with optional fields. + * + * Example: + * ``` + * interface User { + * id: number; + * isOwner?: boolean; + * } + * + * const decoder: Decoder = object({ + * id: number(), + * isOwner: optional(boolean()) + * }); + * ``` + */ + Decoder.optional = function (decoder) { + return new Decoder(function (json) { return (json === undefined || json === null ? ok(undefined) : decoder.decode(json)); }); + }; + /** + * Decoder that attempts to run each decoder in `decoders` and either succeeds + * with the first successful decoder, or fails after all decoders have failed. + * + * Note that `oneOf` expects the decoders to all have the same return type, + * while `union` creates a decoder for the union type of all the input + * decoders. + * + * Examples: + * ``` + * oneOf(string(), number().map(String)) + * oneOf(constant('start'), constant('stop'), succeed('unknown')) + * ``` + */ + Decoder.oneOf = function () { + var decoders = []; + for (var _i = 0; _i < arguments.length; _i++) { + decoders[_i] = arguments[_i]; + } + return new Decoder(function (json) { + var errors = []; + for (var i = 0; i < decoders.length; i++) { + var r = decoders[i].decode(json); + if (r.ok === true) { + return r; + } + else { + errors[i] = r.error; + } + } + var errorsList = errors + .map(function (error) { return "at error" + (error.at || '') + ": " + error.message; }) + .join('", "'); + return err({ + message: "expected a value matching one of the decoders, got the errors [\"" + errorsList + "\"]" + }); + }); + }; + /** + * Decoder that always succeeds with either the decoded value, or a fallback + * default value. + */ + Decoder.withDefault = function (defaultValue, decoder) { + return new Decoder(function (json) { + return ok(withDefault(defaultValue, decoder.decode(json))); + }); + }; + /** + * Decoder that pulls a specific field out of a json structure, instead of + * decoding and returning the full structure. The `paths` array describes the + * object keys and array indices to traverse, so that values can be pulled out + * of a nested structure. + * + * Example: + * ``` + * const decoder = valueAt(['a', 'b', 0], string()); + * + * decoder.run({a: {b: ['surprise!']}}) + * // => {ok: true, result: 'surprise!'} + * + * decoder.run({a: {x: 'cats'}}) + * // => {ok: false, error: {... at: 'input.a.b[0]' message: 'path does not exist'}} + * ``` + * + * Note that the `decoder` is ran on the value found at the last key in the + * path, even if the last key is not found. This allows the `optional` + * decoder to succeed when appropriate. + * ``` + * const optionalDecoder = valueAt(['a', 'b', 'c'], optional(string())); + * + * optionalDecoder.run({a: {b: {c: 'surprise!'}}}) + * // => {ok: true, result: 'surprise!'} + * + * optionalDecoder.run({a: {b: 'cats'}}) + * // => {ok: false, error: {... at: 'input.a.b.c' message: 'expected an object, got "cats"'} + * + * optionalDecoder.run({a: {b: {z: 1}}}) + * // => {ok: true, result: undefined} + * ``` + */ + Decoder.valueAt = function (paths, decoder) { + return new Decoder(function (json) { + var jsonAtPath = json; + for (var i = 0; i < paths.length; i++) { + if (jsonAtPath === undefined) { + return err({ + at: printPath(paths.slice(0, i + 1)), + message: 'path does not exist' + }); + } + else if (typeof paths[i] === 'string' && !isJsonObject(jsonAtPath)) { + return err({ + at: printPath(paths.slice(0, i + 1)), + message: expectedGot('an object', jsonAtPath) + }); + } + else if (typeof paths[i] === 'number' && !isJsonArray(jsonAtPath)) { + return err({ + at: printPath(paths.slice(0, i + 1)), + message: expectedGot('an array', jsonAtPath) + }); + } + else { + jsonAtPath = jsonAtPath[paths[i]]; + } + } + return mapError(function (error) { + return jsonAtPath === undefined + ? { at: printPath(paths), message: 'path does not exist' } + : prependAt(printPath(paths), error); + }, decoder.decode(jsonAtPath)); + }); + }; + /** + * Decoder that ignores the input json and always succeeds with `fixedValue`. + */ + Decoder.succeed = function (fixedValue) { + return new Decoder(function (json) { return ok(fixedValue); }); + }; + /** + * Decoder that ignores the input json and always fails with `errorMessage`. + */ + Decoder.fail = function (errorMessage) { + return new Decoder(function (json) { return err({ message: errorMessage }); }); + }; + /** + * Decoder that allows for validating recursive data structures. Unlike with + * functions, decoders assigned to variables can't reference themselves + * before they are fully defined. We can avoid prematurely referencing the + * decoder by wrapping it in a function that won't be called until use, at + * which point the decoder has been defined. + * + * Example: + * ``` + * interface Comment { + * msg: string; + * replies: Comment[]; + * } + * + * const decoder: Decoder = object({ + * msg: string(), + * replies: lazy(() => array(decoder)) + * }); + * ``` + */ + Decoder.lazy = function (mkDecoder) { + return new Decoder(function (json) { return mkDecoder().decode(json); }); + }; + return Decoder; + }()); + + /* tslint:disable:variable-name */ + /** See `Decoder.string` */ + var string = Decoder.string; + /** See `Decoder.number` */ + var number = Decoder.number; + /** See `Decoder.boolean` */ + var boolean = Decoder.boolean; + /** See `Decoder.anyJson` */ + var anyJson = Decoder.anyJson; + /** See `Decoder.unknownJson` */ + Decoder.unknownJson; + /** See `Decoder.constant` */ + var constant = Decoder.constant; + /** See `Decoder.object` */ + var object = Decoder.object; + /** See `Decoder.array` */ + var array = Decoder.array; + /** See `Decoder.tuple` */ + Decoder.tuple; + /** See `Decoder.dict` */ + Decoder.dict; + /** See `Decoder.optional` */ + var optional = Decoder.optional; + /** See `Decoder.oneOf` */ + var oneOf = Decoder.oneOf; + /** See `Decoder.union` */ + Decoder.union; + /** See `Decoder.intersection` */ + var intersection = Decoder.intersection; + /** See `Decoder.withDefault` */ + Decoder.withDefault; + /** See `Decoder.valueAt` */ + Decoder.valueAt; + /** See `Decoder.succeed` */ + Decoder.succeed; + /** See `Decoder.fail` */ + Decoder.fail; + /** See `Decoder.lazy` */ + var lazy = Decoder.lazy; + + const nonEmptyStringDecoder = string().where((s) => s.length > 0, "Expected a non-empty string"); + const nonNegativeNumberDecoder = number().where((num) => num >= 0, "Expected a non-negative number"); + const positiveNumberDecoder = number().where((num) => num > 0, "Expected a positive number"); + const windowDragModeDecoder = oneOf(constant("keepInside"), constant("autoEject")); + const isWindowInSwimlaneResultDecoder = object({ + inWorkspace: boolean() + }); + const allParentDecoder = oneOf(constant("workspace"), constant("row"), constant("column"), constant("group")); + const subParentDecoder = oneOf(constant("row"), constant("column"), constant("group")); + const frameStateDecoder = oneOf(constant("maximized"), constant("minimized"), constant("normal")); + const loadingAnimationTypeDecoder = oneOf(constant("workspace")); + const checkThrowCallback = (callback, allowUndefined) => { + const argumentType = typeof callback; + if (allowUndefined && argumentType !== "function" && argumentType !== "undefined") { + throw new Error(`Provided argument must be either undefined or of type function, provided: ${argumentType}`); + } + if (!allowUndefined && argumentType !== "function") { + throw new Error(`Provided argument must be of type function, provided: ${argumentType}`); + } + }; + const workspaceBuilderCreateConfigDecoder = optional(object({ + saveLayout: optional(boolean()) + })); + const deleteLayoutConfigDecoder = object({ + name: nonEmptyStringDecoder + }); + const windowDefinitionConfigDecoder = object({ + minWidth: optional(number()), + maxWidth: optional(number()), + minHeight: optional(number()), + maxHeight: optional(number()), + allowExtract: optional(boolean()), + allowReorder: optional(boolean()), + showCloseButton: optional(boolean()) + }); + const groupDefinitionConfigDecoder = object({ + minWidth: optional(number()), + maxWidth: optional(number()), + minHeight: optional(number()), + maxHeight: optional(number()), + allowExtract: optional(boolean()), + allowReorder: optional(boolean()), + allowDrop: optional(boolean()), + allowDropHeader: optional(boolean()), + allowDropLeft: optional(boolean()), + allowDropRight: optional(boolean()), + allowDropTop: optional(boolean()), + allowDropBottom: optional(boolean()), + showMaximizeButton: optional(boolean()), + showEjectButton: optional(boolean()), + showAddWindowButton: optional(boolean()) + }); + const rowDefinitionConfigDecoder = object({ + minHeight: optional(number()), + maxHeight: optional(number()), + allowDrop: optional(boolean()), + allowSplitters: optional(boolean()), + isPinned: optional(boolean()), + maximizationBoundary: optional(boolean()) + }); + const columnDefinitionConfigDecoder = object({ + minWidth: optional(number()), + maxWidth: optional(number()), + allowDrop: optional(boolean()), + allowSplitters: optional(boolean()), + isPinned: optional(boolean()), + maximizationBoundary: optional(boolean()) + }); + const swimlaneWindowDefinitionDecoder = object({ + type: optional(constant("window")), + appName: optional(nonEmptyStringDecoder), + windowId: optional(nonEmptyStringDecoder), + context: optional(anyJson()), + config: optional(windowDefinitionConfigDecoder) + }); + const strictSwimlaneWindowDefinitionDecoder = object({ + type: constant("window"), + appName: optional(nonEmptyStringDecoder), + windowId: optional(nonEmptyStringDecoder), + context: optional(anyJson()), + config: optional(windowDefinitionConfigDecoder) + }); + const parentDefinitionDecoder = optional(object({ + type: optional(subParentDecoder), + children: optional(lazy(() => array(oneOf(swimlaneWindowDefinitionDecoder, parentDefinitionDecoder)))), + config: optional(anyJson()) + })); + const strictColumnDefinitionDecoder = object({ + type: constant("column"), + children: optional(lazy(() => array(oneOf(strictSwimlaneWindowDefinitionDecoder, strictParentDefinitionDecoder)))), + config: optional(columnDefinitionConfigDecoder) + }); + const strictRowDefinitionDecoder = object({ + type: constant("row"), + children: optional(lazy(() => array(oneOf(strictSwimlaneWindowDefinitionDecoder, strictParentDefinitionDecoder)))), + config: optional(rowDefinitionConfigDecoder) + }); + const strictGroupDefinitionDecoder = object({ + type: constant("group"), + children: optional(lazy(() => array(oneOf(strictSwimlaneWindowDefinitionDecoder, strictParentDefinitionDecoder)))), + config: optional(groupDefinitionConfigDecoder) + }); + const strictParentDefinitionDecoder = oneOf(strictGroupDefinitionDecoder, strictColumnDefinitionDecoder, strictRowDefinitionDecoder); + oneOf(string().where((s) => s.toLowerCase() === "maximized", "Expected a case insensitive variation of 'maximized'"), string().where((s) => s.toLowerCase() === "normal", "Expected a case insensitive variation of 'normal'")); + const newFrameConfigDecoder = object({ + bounds: optional(object({ + left: optional(number()), + top: optional(number()), + width: optional(nonNegativeNumberDecoder), + height: optional(nonNegativeNumberDecoder) + })), + frameId: optional(nonEmptyStringDecoder) + }); + const loadingStrategyDecoder = oneOf(constant("direct"), constant("delayed"), constant("lazy")); + const restoreWorkspaceConfigDecoder = optional(object({ + app: optional(nonEmptyStringDecoder), + context: optional(anyJson()), + loadingStrategy: optional(loadingStrategyDecoder), + title: optional(nonEmptyStringDecoder), + reuseWorkspaceId: optional(nonEmptyStringDecoder), + frameId: optional(nonEmptyStringDecoder), + applicationName: optional(nonEmptyStringDecoder), + lockdown: optional(boolean()), + activateFrame: optional(boolean()), + newFrame: optional(oneOf(newFrameConfigDecoder, boolean())), + noTabHeader: optional(boolean()), + inMemoryLayout: optional(boolean()), + icon: optional(nonEmptyStringDecoder), + isPinned: optional(boolean()), + isSelected: optional(boolean()), + positionIndex: optional(nonNegativeNumberDecoder), + allowSystemHibernation: optional(boolean()) + })); + const openWorkspaceConfigDecoder = object({ + name: nonEmptyStringDecoder, + restoreOptions: optional(restoreWorkspaceConfigDecoder) + }); + const workspaceDefinitionDecoder = object({ + children: optional(array(oneOf(swimlaneWindowDefinitionDecoder, strictParentDefinitionDecoder))), + context: optional(anyJson()), + config: optional(object({ + title: optional(nonEmptyStringDecoder), + position: optional(nonNegativeNumberDecoder), + isFocused: optional(boolean()), + noTabHeader: optional(boolean()), + reuseWorkspaceId: optional(nonEmptyStringDecoder), + loadingStrategy: optional(loadingStrategyDecoder), + allowDrop: optional(boolean()), + allowDropLeft: optional(boolean()), + allowDropTop: optional(boolean()), + allowDropRight: optional(boolean()), + allowDropBottom: optional(boolean()), + allowSystemHibernation: optional(boolean()), + allowExtract: optional(boolean()), + allowWindowReorder: optional(boolean()), + showSaveButton: optional(boolean()), + allowWorkspaceTabReorder: optional(boolean()), + allowWorkspaceTabExtract: optional(boolean()), + showCloseButton: optional(boolean()), + allowSplitters: optional(boolean()), + showWindowCloseButtons: optional(boolean()), + showEjectButtons: optional(boolean()), + showAddWindowButtons: optional(boolean()), + icon: optional(nonEmptyStringDecoder), + isPinned: optional(boolean()), + isSelected: optional(boolean()), + positionIndex: optional(nonNegativeNumberDecoder), + windowDragMode: optional(windowDragModeDecoder) + })), + frame: optional(object({ + activate: optional(boolean()), + reuseFrameId: optional(nonEmptyStringDecoder), + applicationName: optional(nonEmptyStringDecoder), + newFrame: optional(oneOf(boolean(), newFrameConfigDecoder)) + })) + }); + const workspaceSelectorDecoder = object({ + workspaceId: nonEmptyStringDecoder + }); + const restoreWorkspaceDefinitionDecoder = object({ + name: nonEmptyStringDecoder, + restoreOptions: optional(restoreWorkspaceConfigDecoder) + }); + const emptyFrameDefinitionDecoder = optional(object({ + applicationName: optional(string()), + frameConfig: optional(newFrameConfigDecoder), + context: optional(object()), + layoutComponentId: optional(nonEmptyStringDecoder) + })); + const frameInitConfigDecoder = object({ + workspaces: array(oneOf(optional(workspaceDefinitionDecoder), optional(restoreWorkspaceDefinitionDecoder))) + }); + const frameInitProtocolConfigDecoder = object({ + frameId: nonEmptyStringDecoder, + workspaces: array(oneOf(workspaceDefinitionDecoder, restoreWorkspaceDefinitionDecoder)) + }); + const builderConfigDecoder = object({ + type: allParentDecoder, + definition: optional(oneOf(workspaceDefinitionDecoder, parentDefinitionDecoder)) + }); + const workspaceCreateConfigDecoder = intersection(workspaceDefinitionDecoder, object({ + saveConfig: optional(object({ + saveLayout: optional(boolean()) + })) + })); + const getFrameSummaryConfigDecoder = object({ + itemId: nonEmptyStringDecoder + }); + const frameInitializationContextDecoder = object({ + context: optional(object()) + }); + const frameSummaryDecoder = object({ + id: nonEmptyStringDecoder, + isFocused: optional(boolean()), + isInitialized: optional(boolean()), + initializationContext: optional(frameInitializationContextDecoder) + }); + object({ + type: subParentDecoder, + id: nonEmptyStringDecoder, + frameId: nonEmptyStringDecoder, + workspaceId: nonEmptyStringDecoder, + positionIndex: number() + }); + const eventTypeDecoder = oneOf(constant("frame"), constant("workspace"), constant("container"), constant("window")); + const streamRequestArgumentsDecoder = object({ + type: eventTypeDecoder, + branch: nonEmptyStringDecoder + }); + const workspaceEventActionDecoder = oneOf(constant("opened"), constant("closing"), constant("closed"), constant("focus"), constant("added"), constant("loaded"), constant("removed"), constant("childrenUpdate"), constant("containerChange"), constant("maximized"), constant("restored"), constant("minimized"), constant("normal"), constant("selected"), constant("lock-configuration-changed"), constant("hibernated"), constant("resumed")); + const workspaceConfigResultDecoder = object({ + frameId: nonEmptyStringDecoder, + title: nonEmptyStringDecoder, + positionIndex: nonNegativeNumberDecoder, + name: nonEmptyStringDecoder, + layoutName: optional(nonEmptyStringDecoder), + isHibernated: optional(boolean()), + isSelected: optional(boolean()), + allowDrop: optional(boolean()), + allowSystemHibernation: optional(boolean()), + allowExtract: optional(boolean()), + allowWindowReorder: optional(boolean()), + allowSplitters: optional(boolean()), + showCloseButton: optional(boolean()), + showSaveButton: optional(boolean()), + allowWorkspaceTabReorder: optional(boolean()), + allowWorkspaceTabExtract: optional(boolean()), + allowDropLeft: optional(boolean()), + allowDropTop: optional(boolean()), + allowDropRight: optional(boolean()), + allowDropBottom: optional(boolean()), + minWidth: optional(number()), + maxWidth: optional(number()), + minHeight: optional(number()), + maxHeight: optional(number()), + showAddWindowButtons: optional(boolean()), + showEjectButtons: optional(boolean()), + showWindowCloseButtons: optional(boolean()), + widthInPx: optional(number()), + heightInPx: optional(number()), + isPinned: optional(boolean()), + windowDragMode: optional(windowDragModeDecoder), + loadingStrategy: optional(loadingStrategyDecoder) + }); + const baseChildSnapshotConfigDecoder = object({ + frameId: nonEmptyStringDecoder, + workspaceId: nonEmptyStringDecoder, + positionIndex: number(), + minWidth: optional(number()), + maxWidth: optional(number()), + minHeight: optional(number()), + maxHeight: optional(number()) + }); + const parentSnapshotConfigDecoder = anyJson(); + const swimlaneWindowSnapshotConfigDecoder = intersection(baseChildSnapshotConfigDecoder, object({ + windowId: optional(nonEmptyStringDecoder), + isMaximized: optional(boolean()), + isFocused: boolean(), + isSelected: optional(boolean()), + title: optional(string()), + appName: optional(nonEmptyStringDecoder), + allowExtract: optional(boolean()), + allowReorder: optional(boolean()), + showCloseButton: optional(boolean()), + minWidth: optional(number()), + minHeight: optional(number()), + maxWidth: optional(number()), + maxHeight: optional(number()), + widthInPx: optional(number()), + heightInPx: optional(number()), + context: optional(anyJson()) + })); + const customWorkspaceSubParentSnapshotDecoder = object({ + id: optional(nonEmptyStringDecoder), + config: parentSnapshotConfigDecoder, + children: optional(lazy(() => array(customWorkspaceChildSnapshotDecoder))), + type: oneOf(constant("row"), constant("column"), constant("group")) + }); + const customWorkspaceWindowSnapshotDecoder = object({ + id: optional(nonEmptyStringDecoder), + config: swimlaneWindowSnapshotConfigDecoder, + type: constant("window") + }); + const customWorkspaceChildSnapshotDecoder = oneOf(customWorkspaceWindowSnapshotDecoder, customWorkspaceSubParentSnapshotDecoder); + const childSnapshotResultDecoder = customWorkspaceChildSnapshotDecoder; + const workspaceSnapshotResultDecoder = object({ + id: nonEmptyStringDecoder, + config: workspaceConfigResultDecoder, + children: array(childSnapshotResultDecoder), + frameSummary: frameSummaryDecoder, + context: optional(anyJson()) + }); + const windowLayoutItemDecoder = object({ + type: constant("window"), + config: object({ + appName: nonEmptyStringDecoder, + windowId: optional(nonEmptyStringDecoder), + context: optional(anyJson()), + url: optional(nonEmptyStringDecoder), + title: optional(string()), + allowExtract: optional(boolean()), + allowReorder: optional(boolean()), + showCloseButton: optional(boolean()), + minWidth: optional(number()), + minHeight: optional(number()), + maxWidth: optional(number()), + maxHeight: optional(number()), + isMaximized: optional(boolean()) + }) + }); + const groupLayoutItemDecoder = object({ + type: constant("group"), + config: anyJson(), + children: array(oneOf(windowLayoutItemDecoder)) + }); + const columnLayoutItemDecoder = object({ + type: constant("column"), + config: anyJson(), + children: array(oneOf(groupLayoutItemDecoder, windowLayoutItemDecoder, lazy(() => columnLayoutItemDecoder), lazy(() => rowLayoutItemDecoder))) + }); + const rowLayoutItemDecoder = object({ + type: constant("row"), + config: anyJson(), + children: array(oneOf(columnLayoutItemDecoder, groupLayoutItemDecoder, windowLayoutItemDecoder, lazy(() => rowLayoutItemDecoder))) + }); + const workspaceLayoutDecoder = object({ + name: nonEmptyStringDecoder, + type: constant("Workspace"), + metadata: optional(anyJson()), + components: array(object({ + type: constant("Workspace"), + application: optional(string()), + state: object({ + config: anyJson(), + context: anyJson(), + children: array(oneOf(rowLayoutItemDecoder, columnLayoutItemDecoder, groupLayoutItemDecoder, windowLayoutItemDecoder)) + }) + })) + }); + const workspacesImportLayoutDecoder = object({ + layout: workspaceLayoutDecoder, + mode: oneOf(constant("replace"), constant("merge")) + }); + const workspacesImportLayoutsDecoder = object({ + layouts: array(workspaceLayoutDecoder), + mode: oneOf(constant("replace"), constant("merge")) + }); + const exportedLayoutsResultDecoder = object({ + layouts: array(workspaceLayoutDecoder) + }); + const frameSummaryResultDecoder = object({ + id: nonEmptyStringDecoder, + isFocused: optional(boolean()), + isInitialized: optional(boolean()), + initializationContext: optional(frameInitializationContextDecoder) + }); + const frameSummariesResultDecoder = object({ + summaries: array(frameSummaryResultDecoder) + }); + const workspaceSummaryResultDecoder = object({ + id: nonEmptyStringDecoder, + config: workspaceConfigResultDecoder + }); + const workspaceSummariesResultDecoder = object({ + summaries: array(workspaceSummaryResultDecoder) + }); + const frameSnapshotResultDecoder = object({ + id: nonEmptyStringDecoder, + config: anyJson(), + workspaces: array(workspaceSnapshotResultDecoder) + }); + const layoutSummaryDecoder = object({ + name: nonEmptyStringDecoder, + applicationName: optional(string()) + }); + const layoutSummariesDecoder = object({ + summaries: array(layoutSummaryDecoder) + }); + const simpleWindowOperationSuccessResultDecoder = object({ + windowId: nonEmptyStringDecoder + }); + const voidResultDecoder = anyJson(); + const frameStateResultDecoder = object({ + state: frameStateDecoder + }); + const frameBoundsDecoder = object({ + top: number(), + left: number(), + width: nonNegativeNumberDecoder, + height: nonNegativeNumberDecoder + }); + const frameBoundsResultDecoder = object({ + bounds: frameBoundsDecoder + }); + const getWorkspaceIconResultDecoder = object({ + icon: optional(nonEmptyStringDecoder) + }); + const getPlatformFrameIdResultDecoder = object({ + id: optional(nonEmptyStringDecoder) + }); + const operationCheckResultDecoder = object({ + isSupported: boolean() + }); + const resizeConfigDecoder = object({ + width: optional(positiveNumberDecoder), + height: optional(positiveNumberDecoder), + relative: optional(boolean()) + }); + const moveConfigDecoder = object({ + top: optional(number()), + left: optional(number()), + relative: optional(boolean()) + }); + const simpleItemConfigDecoder = object({ + itemId: nonEmptyStringDecoder + }); + const frameSnapshotConfigDecoder = object({ + itemId: nonEmptyStringDecoder, + excludeIds: optional(boolean()) + }); + const frameStateConfigDecoder = object({ + frameId: nonEmptyStringDecoder, + requestedState: frameStateDecoder + }); + const setItemTitleConfigDecoder = object({ + itemId: nonEmptyStringDecoder, + title: nonEmptyStringDecoder + }); + const moveWindowConfigDecoder = object({ + itemId: nonEmptyStringDecoder, + containerId: nonEmptyStringDecoder + }); + const resizeItemConfigDecoder = intersection(simpleItemConfigDecoder, resizeConfigDecoder); + const setMaximizationBoundaryConfigDecoder = object({ + itemId: nonEmptyStringDecoder, + enabled: boolean() + }); + const moveFrameConfigDecoder = intersection(simpleItemConfigDecoder, moveConfigDecoder); + object({ + id: nonEmptyStringDecoder, + type: subParentDecoder + }); + const addWindowConfigDecoder = object({ + definition: swimlaneWindowDefinitionDecoder, + parentId: nonEmptyStringDecoder, + parentType: allParentDecoder + }); + const addContainerConfigDecoder = object({ + definition: strictParentDefinitionDecoder, + parentId: nonEmptyStringDecoder, + parentType: allParentDecoder + }); + const addItemResultDecoder = object({ + itemId: nonEmptyStringDecoder, + windowId: optional(nonEmptyStringDecoder) + }); + const pingResultDecoder = object({ + live: boolean() + }); + const bundleWorkspaceConfigDecoder = object({ + type: oneOf(constant("row"), constant("column")), + workspaceId: nonEmptyStringDecoder + }); + const bundleItemConfigDecoder = object({ + type: oneOf(constant("row"), constant("column")), + itemId: nonEmptyStringDecoder + }); + const containerSummaryResultDecoder = object({ + itemId: nonEmptyStringDecoder, + config: parentSnapshotConfigDecoder + }); + const frameStreamDataDecoder = object({ + frameSummary: frameSummaryDecoder, + frameBounds: optional(frameBoundsDecoder) + }); + const workspaceStreamDataDecoder = object({ + workspaceSummary: workspaceSummaryResultDecoder, + frameSummary: frameSummaryDecoder, + workspaceSnapshot: optional(workspaceSnapshotResultDecoder), + frameBounds: optional(frameBoundsDecoder) + }); + const containerStreamDataDecoder = object({ + containerSummary: containerSummaryResultDecoder + }); + const windowStreamDataDecoder = object({ + windowSummary: object({ + itemId: nonEmptyStringDecoder, + parentId: nonEmptyStringDecoder, + config: swimlaneWindowSnapshotConfigDecoder + }) + }); + const workspaceLayoutSaveConfigDecoder = object({ + name: nonEmptyStringDecoder, + workspaceId: nonEmptyStringDecoder, + saveContext: optional(boolean()), + allowMultiple: optional(boolean()), + metadata: optional(object()) + }); + const workspaceLockConfigDecoder = object({ + allowDrop: optional(boolean()), + allowDropLeft: optional(boolean()), + allowDropTop: optional(boolean()), + allowDropRight: optional(boolean()), + allowDropBottom: optional(boolean()), + allowSystemHibernation: optional(boolean()), + allowExtract: optional(boolean()), + allowWindowReorder: optional(boolean()), + allowSplitters: optional(boolean()), + showCloseButton: optional(boolean()), + showSaveButton: optional(boolean()), + allowWorkspaceTabReorder: optional(boolean()), + allowWorkspaceTabExtract: optional(boolean()), + showWindowCloseButtons: optional(boolean()), + showAddWindowButtons: optional(boolean()), + showEjectButtons: optional(boolean()), + }); + const lockWorkspaceDecoder = object({ + workspaceId: nonEmptyStringDecoder, + config: optional(workspaceLockConfigDecoder) + }); + const windowLockConfigDecoder = object({ + allowExtract: optional(boolean()), + allowReorder: optional(boolean()), + showCloseButton: optional(boolean()) + }); + const elementResizeConfigDecoder = object({ + width: optional(nonNegativeNumberDecoder), + height: optional(nonNegativeNumberDecoder) + }); + const lockWindowDecoder = object({ + windowPlacementId: nonEmptyStringDecoder, + config: optional(windowLockConfigDecoder) + }); + const rowLockConfigDecoder = object({ + allowDrop: optional(boolean()), + allowSplitters: optional(boolean()), + }); + const columnLockConfigDecoder = object({ + allowDrop: optional(boolean()), + allowSplitters: optional(boolean()), + }); + const groupLockConfigDecoder = object({ + allowExtract: optional(boolean()), + allowReorder: optional(boolean()), + allowDrop: optional(boolean()), + allowDropLeft: optional(boolean()), + allowDropRight: optional(boolean()), + allowDropTop: optional(boolean()), + allowDropBottom: optional(boolean()), + allowDropHeader: optional(boolean()), + showMaximizeButton: optional(boolean()), + showEjectButton: optional(boolean()), + showAddWindowButton: optional(boolean()), + }); + const lockRowDecoder = object({ + itemId: nonEmptyStringDecoder, + type: constant("row"), + config: optional(rowLockConfigDecoder) + }); + const lockColumnDecoder = object({ + itemId: nonEmptyStringDecoder, + type: constant("column"), + config: optional(columnLockConfigDecoder) + }); + const lockGroupDecoder = object({ + itemId: nonEmptyStringDecoder, + type: constant("group"), + config: optional(groupLockConfigDecoder) + }); + const lockContainerDecoder = oneOf(lockRowDecoder, lockColumnDecoder, lockGroupDecoder); + const pinWorkspaceDecoder = object({ + workspaceId: nonEmptyStringDecoder, + icon: optional(nonEmptyStringDecoder) + }); + const setWorkspaceIconDecoder = object({ + workspaceId: nonEmptyStringDecoder, + icon: optional(nonEmptyStringDecoder) + }); + const workspacePinOptionsDecoder = optional(object({ + icon: optional(nonEmptyStringDecoder) + })); + const shortcutConfigDecoder = object({ + shortcut: nonEmptyStringDecoder, + frameId: nonEmptyStringDecoder + }); + const shortcutClickedDataDecoder = object({ + shortcut: nonEmptyStringDecoder, + frameId: nonEmptyStringDecoder + }); + const setMaximizationBoundaryAPIConfigDecoder = object({ + enabled: boolean() + }); + const loadingAnimationConfigDecoder = object({ + itemId: nonEmptyStringDecoder, + type: loadingAnimationTypeDecoder + }); + const operationCheckConfigDecoder = object({ + operation: nonEmptyStringDecoder + }); + const setWindowDragModeDecoder = object({ + itemId: nonEmptyStringDecoder, + dragMode: windowDragModeDecoder + }); + const setLoadingStrategyDecoder = object({ + itemId: nonEmptyStringDecoder, + strategy: loadingStrategyDecoder + }); + + const webPlatformMethodName = "T42.Web.Platform.Control"; + const webPlatformWspStreamName = "T42.Web.Platform.WSP.Stream"; + const OUTGOING_METHODS = { + control: { name: "T42.Workspaces.Control", isStream: false }, + frameStream: { name: "T42.Workspaces.Stream.Frame", isStream: true }, + workspaceStream: { name: "T42.Workspaces.Stream.Workspace", isStream: true }, + containerStream: { name: "T42.Workspaces.Stream.Container", isStream: true }, + windowStream: { name: "T42.Workspaces.Stream.Window", isStream: true } + }; + const INCOMING_METHODS = { + control: { name: "T42.Workspaces.Client.Control", isStream: false }, + }; + const STREAMS = { + frame: { name: "T42.Workspaces.Stream.Frame", payloadDecoder: frameStreamDataDecoder }, + workspace: { name: "T42.Workspaces.Stream.Workspace", payloadDecoder: workspaceStreamDataDecoder }, + container: { name: "T42.Workspaces.Stream.Container", payloadDecoder: containerStreamDataDecoder }, + window: { name: "T42.Workspaces.Stream.Window", payloadDecoder: windowStreamDataDecoder } + }; + const CLIENT_OPERATIONS = { + shortcutClicked: { name: "shortcutClicked", argsDecoder: shortcutClickedDataDecoder, resultDecoder: voidResultDecoder }, + }; + const OPERATIONS = { + ping: { name: "ping", resultDecoder: pingResultDecoder }, + isWindowInWorkspace: { name: "isWindowInWorkspace", argsDecoder: simpleItemConfigDecoder, resultDecoder: isWindowInSwimlaneResultDecoder }, + createWorkspace: { name: "createWorkspace", resultDecoder: workspaceSnapshotResultDecoder, argsDecoder: workspaceCreateConfigDecoder }, + createFrame: { name: "createFrame", resultDecoder: frameSummaryResultDecoder, argsDecoder: emptyFrameDefinitionDecoder }, + initFrame: { name: "initFrame", resultDecoder: voidResultDecoder, argsDecoder: frameInitProtocolConfigDecoder }, + getAllFramesSummaries: { name: "getAllFramesSummaries", resultDecoder: frameSummariesResultDecoder }, + getFrameSummary: { name: "getFrameSummary", resultDecoder: frameSummaryDecoder, argsDecoder: getFrameSummaryConfigDecoder }, + getAllWorkspacesSummaries: { name: "getAllWorkspacesSummaries", resultDecoder: workspaceSummariesResultDecoder }, + getWorkspaceSnapshot: { name: "getWorkspaceSnapshot", resultDecoder: workspaceSnapshotResultDecoder, argsDecoder: simpleItemConfigDecoder }, + getAllLayoutsSummaries: { name: "getAllLayoutsSummaries", resultDecoder: layoutSummariesDecoder }, + openWorkspace: { name: "openWorkspace", argsDecoder: openWorkspaceConfigDecoder, resultDecoder: workspaceSnapshotResultDecoder }, + deleteLayout: { name: "deleteLayout", resultDecoder: voidResultDecoder, argsDecoder: deleteLayoutConfigDecoder }, + saveLayout: { name: "saveLayout", resultDecoder: workspaceLayoutDecoder, argsDecoder: workspaceLayoutSaveConfigDecoder }, + importLayout: { name: "importLayout", resultDecoder: voidResultDecoder, argsDecoder: workspacesImportLayoutDecoder }, + importLayouts: { name: "importLayouts", resultDecoder: voidResultDecoder, argsDecoder: workspacesImportLayoutsDecoder }, + exportAllLayouts: { name: "exportAllLayouts", resultDecoder: exportedLayoutsResultDecoder }, + restoreItem: { name: "restoreItem", argsDecoder: simpleItemConfigDecoder, resultDecoder: voidResultDecoder }, + maximizeItem: { name: "maximizeItem", argsDecoder: simpleItemConfigDecoder, resultDecoder: voidResultDecoder }, + focusItem: { name: "focusItem", argsDecoder: simpleItemConfigDecoder, resultDecoder: voidResultDecoder }, + closeItem: { name: "closeItem", argsDecoder: simpleItemConfigDecoder, resultDecoder: voidResultDecoder }, + resizeItem: { name: "resizeItem", argsDecoder: resizeItemConfigDecoder, resultDecoder: voidResultDecoder }, + setMaximizationBoundary: { name: "setMaximizationBoundary", argsDecoder: setMaximizationBoundaryConfigDecoder, resultDecoder: voidResultDecoder }, + changeFrameState: { name: "changeFrameState", argsDecoder: frameStateConfigDecoder, resultDecoder: voidResultDecoder }, + getFrameState: { name: "getFrameState", argsDecoder: simpleItemConfigDecoder, resultDecoder: frameStateResultDecoder }, + getFrameBounds: { name: "getFrameBounds", argsDecoder: simpleItemConfigDecoder, resultDecoder: frameBoundsResultDecoder }, + moveFrame: { name: "moveFrame", argsDecoder: moveFrameConfigDecoder, resultDecoder: voidResultDecoder }, + getFrameSnapshot: { name: "getFrameSnapshot", argsDecoder: frameSnapshotConfigDecoder, resultDecoder: frameSnapshotResultDecoder }, + forceLoadWindow: { name: "forceLoadWindow", argsDecoder: simpleItemConfigDecoder, resultDecoder: simpleWindowOperationSuccessResultDecoder }, + ejectWindow: { name: "ejectWindow", argsDecoder: simpleItemConfigDecoder, resultDecoder: simpleWindowOperationSuccessResultDecoder }, + setItemTitle: { name: "setItemTitle", argsDecoder: setItemTitleConfigDecoder, resultDecoder: voidResultDecoder }, + moveWindowTo: { name: "moveWindowTo", argsDecoder: moveWindowConfigDecoder, resultDecoder: voidResultDecoder }, + addWindow: { name: "addWindow", argsDecoder: addWindowConfigDecoder, resultDecoder: addItemResultDecoder }, + addContainer: { name: "addContainer", argsDecoder: addContainerConfigDecoder, resultDecoder: addItemResultDecoder }, + bundleWorkspace: { name: "bundleWorkspace", argsDecoder: bundleWorkspaceConfigDecoder, resultDecoder: voidResultDecoder }, + bundleItem: { name: "bundleItem", argsDecoder: bundleItemConfigDecoder, resultDecoder: voidResultDecoder }, + hibernateWorkspace: { name: "hibernateWorkspace", argsDecoder: workspaceSelectorDecoder, resultDecoder: voidResultDecoder }, + resumeWorkspace: { name: "resumeWorkspace", argsDecoder: workspaceSelectorDecoder, resultDecoder: voidResultDecoder }, + lockWorkspace: { name: "lockWorkspace", argsDecoder: lockWorkspaceDecoder, resultDecoder: voidResultDecoder }, + lockWindow: { name: "lockWindow", argsDecoder: lockWindowDecoder, resultDecoder: voidResultDecoder }, + lockContainer: { name: "lockContainer", argsDecoder: lockContainerDecoder, resultDecoder: voidResultDecoder }, + pinWorkspace: { name: "pinWorkspace", argsDecoder: pinWorkspaceDecoder, resultDecoder: voidResultDecoder }, + unpinWorkspace: { name: "unpinWorkspace", argsDecoder: workspaceSelectorDecoder, resultDecoder: voidResultDecoder }, + getWorkspaceIcon: { name: "getWorkspaceIcon", argsDecoder: workspaceSelectorDecoder, resultDecoder: getWorkspaceIconResultDecoder }, + setWorkspaceIcon: { name: "setWorkspaceIcon", argsDecoder: setWorkspaceIconDecoder, resultDecoder: voidResultDecoder }, + registerShortcut: { name: "registerShortcut", argsDecoder: shortcutConfigDecoder, resultDecoder: voidResultDecoder }, + unregisterShortcut: { name: "unregisterShortcut", argsDecoder: shortcutConfigDecoder, resultDecoder: voidResultDecoder }, + showLoadingAnimation: { name: "showLoadingAnimation", argsDecoder: loadingAnimationConfigDecoder, resultDecoder: voidResultDecoder }, + hideLoadingAnimation: { name: "hideLoadingAnimation", argsDecoder: loadingAnimationConfigDecoder, resultDecoder: voidResultDecoder }, + getPlatformFrameId: { name: "getPlatformFrameId", resultDecoder: getPlatformFrameIdResultDecoder }, + operationCheck: { name: "operationCheck", argsDecoder: operationCheckConfigDecoder, resultDecoder: operationCheckResultDecoder }, + setWindowDragMode: { name: "setWindowDragMode", argsDecoder: setWindowDragModeDecoder, resultDecoder: voidResultDecoder }, + setLoadingStrategy: { name: "setLoadingStrategy", argsDecoder: setLoadingStrategyDecoder, resultDecoder: voidResultDecoder } + }; + + class PromiseWrapper { + resolve; + reject; + promise; + constructor() { + this.promise = new Promise((res, rej) => { + this.resolve = res; + this.reject = rej; + }); + } + } + + class Bridge { + transport; + registry; + activeSubscriptions = []; + pendingSubScriptions = []; + constructor(transport, registry) { + this.transport = transport; + this.registry = registry; + } + async createCoreEventSubscription() { + await this.transport.coreSubscriptionReady(this.handleCoreEvent.bind(this)); + } + handleCoreSubscription(config) { + const registryKey = `${config.eventType}-${config.action}`; + const scope = config.scope; + const scopeId = config.scopeId; + return this.registry.add(registryKey, (args) => { + const scopeConfig = { + type: scope, + id: scopeId + }; + const receivedIds = { + frame: args.frameSummary?.id || args.windowSummary?.config.frameId, + workspace: args.workspaceSummary?.id || args.windowSummary?.config.workspaceId, + container: args.containerSummary?.itemId, + window: args.windowSummary?.itemId + }; + const shouldInvokeCallback = this.checkScopeMatch(scopeConfig, receivedIds); + if (!shouldInvokeCallback) { + return; + } + config.callback(args); + }); + } + async send(operationName, operationArgs) { + const operationDefinition = Object.values(OPERATIONS).find((operation) => operation.name === operationName); + if (!operationDefinition) { + throw new Error(`Cannot find definition for operation name: ${operationName}`); + } + if (operationDefinition.argsDecoder) { + try { + operationDefinition.argsDecoder.runWithException(operationArgs); + } + catch (error) { + throw new Error(`Unexpected internal outgoing validation error: ${error.message}, for input: ${JSON.stringify(error.input)}, for operation ${operationName}`); + } + } + try { + const operationResult = await this.transport.transmitControl(operationDefinition.name, operationArgs); + operationDefinition.resultDecoder.runWithException(operationResult); + return operationResult; + } + catch (error) { + if (error.kind) { + throw new Error(`Unexpected internal incoming validation error: ${error.message}, for input: ${JSON.stringify(error.input)}, for operation ${operationName}`); + } + throw new Error(error.message); + } + } + async subscribe(config) { + const pendingSub = this.getPendingSubscription(config); + if (pendingSub) { + await pendingSub.promise; + } + let activeSub = this.getActiveSubscription(config); + const registryKey = this.getRegistryKey(config); + if (!activeSub) { + const pendingPromise = new PromiseWrapper(); + const pendingSubscription = { + streamType: config.eventType, + level: config.scope, + levelId: config.scopeId, + promise: pendingPromise.promise + }; + this.pendingSubScriptions.push(pendingSubscription); + try { + const stream = STREAMS[config.eventType]; + const gdSub = await this.transport.subscribe(stream.name, this.getBranchKey(config), config.eventType); + gdSub.onData((streamData) => { + const data = streamData.data; + const requestedArgumentsResult = streamRequestArgumentsDecoder.run(streamData.requestArguments); + const actionResult = workspaceEventActionDecoder.run(data.action); + if (!requestedArgumentsResult.ok || !actionResult.ok) { + return; + } + const streamType = requestedArgumentsResult.result.type; + const branch = requestedArgumentsResult.result.branch; + const keyToExecute = `${streamType}-${branch}-${actionResult.result}`; + const validatedPayload = STREAMS[streamType].payloadDecoder.run(data.payload); + if (!validatedPayload.ok) { + return; + } + this.registry.execute(keyToExecute, validatedPayload.result); + }); + activeSub = { + streamType: config.eventType, + level: config.scope, + levelId: config.scopeId, + callbacksCount: 0, + gdSub + }; + this.activeSubscriptions.push(activeSub); + pendingPromise.resolve(); + } + catch (error) { + pendingPromise.reject(error); + throw error; + } + finally { + this.removePendingSubscription(pendingSubscription); + } + } + const unsubscribe = this.registry.add(registryKey, config.callback); + ++activeSub.callbacksCount; + return () => { + unsubscribe(); + --activeSub.callbacksCount; + if (activeSub.callbacksCount === 0) { + activeSub.gdSub.close(); + this.activeSubscriptions.splice(this.activeSubscriptions.indexOf(activeSub), 1); + } + }; + } + onOperation(callback) { + const wrappedCallback = (payload, caller) => { + const operationName = payload.operation; + const operationArgs = payload.data; + const operationDefinition = Object.values(CLIENT_OPERATIONS).find((operation) => operation.name === operationName); + if (!operationDefinition) { + throw new Error(`Cannot find definition for operation name: ${operationName}`); + } + if (operationDefinition.argsDecoder) { + try { + operationDefinition.argsDecoder.runWithException(operationArgs); + } + catch (error) { + throw new Error(`Unexpected internal outgoing validation error: ${error.message}, for input: ${JSON.stringify(error.input)}, for operation ${operationName}`); + } + } + callback(payload, caller); + }; + return this.transport.onInternalMethodInvoked("control", wrappedCallback); + } + checkScopeMatch(scope, receivedIds) { + if (scope.type === "global") { + return true; + } + if (scope.type === "frame" && scope.id === receivedIds.frame) { + return true; + } + if (scope.type === "workspace" && scope.id === receivedIds.workspace) { + return true; + } + if (scope.type === "container" && scope.id === receivedIds.container) { + return true; + } + if (scope.type === "window" && scope.id === receivedIds.window) { + return true; + } + return false; + } + handleCoreEvent(args) { + const data = args.data; + try { + const verifiedAction = workspaceEventActionDecoder.runWithException(data.action); + const verifiedType = eventTypeDecoder.runWithException(data.type); + const verifiedPayload = STREAMS[verifiedType].payloadDecoder.runWithException(data.payload); + const registryKey = `${verifiedType}-${verifiedAction}`; + this.registry.execute(registryKey, verifiedPayload); + } + catch (error) { + console.warn(`Cannot handle event with data ${JSON.stringify(data)}, because of validation error: ${error.message}`); + } + } + getBranchKey(config) { + return config.scope === "global" ? config.scope : `${config.scope}_${config.scopeId}`; + } + getRegistryKey(config) { + return `${config.eventType}-${this.getBranchKey(config)}-${config.action}`; + } + getActiveSubscription(config) { + return this.activeSubscriptions + .find((activeSub) => activeSub.streamType === config.eventType && + activeSub.level === config.scope && + activeSub.levelId === config.scopeId); + } + getPendingSubscription(config) { + return this.pendingSubScriptions + .find((activeSub) => activeSub.streamType === config.eventType && + activeSub.level === config.scope && + activeSub.levelId === config.scopeId); + } + removePendingSubscription(pendingSubscription) { + const index = this.pendingSubScriptions.indexOf(pendingSubscription); + if (index >= 0) { + this.pendingSubScriptions.splice(index, 1); + } + } + } + + const promisePlus = (promise, timeoutMilliseconds, timeoutMessage) => { + return new Promise((resolve, reject) => { + let promiseActive = true; + const timeout = setTimeout(() => { + if (!promiseActive) { + return; + } + promiseActive = false; + const message = timeoutMessage; + reject(message); + }, timeoutMilliseconds); + promise() + .then((result) => { + if (!promiseActive) { + return; + } + promiseActive = false; + clearTimeout(timeout); + resolve(result); + }) + .catch((error) => { + if (!promiseActive) { + return; + } + promiseActive = false; + clearTimeout(timeout); + reject(error); + }); + }); + }; + + const isDesktop = () => { + return typeof window === "undefined" ? + true : + window.glue42gd || window.iodesktop; + }; + const browserGlobal = () => { + return typeof window === "undefined" ? null : + window.glue42core || window.iobrowser; + }; + + class InteropTransport { + agm; + registry; + defaultTransportTimeout = 120000; + coreEventMethodInitiated = false; + corePlatformSubPromise; + constructor(agm, registry) { + this.agm = agm; + this.registry = registry; + } + async initiate(actualWindowId) { + if (isDesktop()) { + await Promise.all(Object.values(OUTGOING_METHODS).map((method) => { + return this.verifyMethodLive(method.name); + })); + await Promise.all(Object.keys(INCOMING_METHODS).map((method) => { + return this.registerMethod(method); + })); + return; + } + const systemId = browserGlobal().communicationId; + await Promise.all([ + this.verifyMethodLive(webPlatformMethodName, systemId), + this.verifyMethodLive(webPlatformWspStreamName, systemId) + ]); + await this.transmitControl("frameHello", { windowId: actualWindowId }); + } + coreSubscriptionReady(eventCallback) { + if (!this.coreEventMethodInitiated) { + this.subscribePlatform(eventCallback); + } + return this.corePlatformSubPromise; + } + subscribePlatform(eventCallback) { + this.coreEventMethodInitiated = true; + const systemId = browserGlobal().communicationId; + this.corePlatformSubPromise = this.agm.subscribe(webPlatformWspStreamName, systemId ? { target: { instance: systemId } } : undefined); + this.corePlatformSubPromise + .then((sub) => { + sub.onData((data) => eventCallback(data.data)); + }); + } + async subscribe(streamName, streamBranch, streamType) { + const subscriptionArgs = { + branch: streamBranch, + type: streamType + }; + let subscription; + try { + subscription = await this.agm.subscribe(streamName, { arguments: subscriptionArgs }); + } + catch (error) { + const message = `Internal subscription error! Error details: stream - ${streamName}, branch: ${streamBranch}. Internal message: ${error.message}`; + throw new Error(message); + } + return subscription; + } + async transmitControl(operation, operationArguments) { + const invocationArguments = isDesktop() ? { operation, operationArguments } : { operation, domain: "workspaces", data: operationArguments }; + const methodName = isDesktop() ? OUTGOING_METHODS.control.name : webPlatformMethodName; + const platformTarget = isDesktop() ? undefined : browserGlobal().communicationId; + let invocationResult; + const baseErrorMessage = `Internal Workspaces Communication Error. Attempted operation: ${JSON.stringify(invocationArguments)}. `; + try { + invocationResult = await this.agm.invoke(methodName, invocationArguments, platformTarget ? { instance: platformTarget } : "best", { methodResponseTimeoutMs: this.defaultTransportTimeout }); + if (!invocationResult) { + throw new Error("Received unsupported result from GD - empty result"); + } + if (!Array.isArray(invocationResult.all_return_values) || invocationResult.all_return_values.length === 0) { + throw new Error("Received unsupported result from GD - empty values collection"); + } + } + catch (error) { + if (error && error.all_errors && error.all_errors.length) { + const invocationErrorMessage = error.all_errors[0].message; + throw new Error(`${baseErrorMessage} -> Inner message: ${invocationErrorMessage}`); + } + throw new Error(`${baseErrorMessage} -> Inner message: ${error.message}`); + } + return invocationResult.all_return_values[0].returned; + } + onInternalMethodInvoked(key, callback) { + return this.registry.add(key, callback); + } + verifyMethodLive(name, systemId) { + return promisePlus(() => { + return new Promise((resolve) => { + const hasMethod = this.agm.methods().some((method) => { + const nameMatch = method.name === name; + const serverMatch = systemId ? + method.getServers().some((server) => server.instance === systemId) : + true; + return nameMatch && serverMatch; + }); + if (hasMethod) { + resolve(); + return; + } + const unSub = this.agm.serverMethodAdded((data) => { + const method = data.method; + const server = data.server; + const serverMatch = systemId ? + server.instance === systemId : + true; + if (method.name === name && serverMatch) { + unSub(); + resolve(); + } + }); + }); + }, 15000, "Timeout waiting for the Workspaces communication channels"); + } + registerMethod(key) { + const method = INCOMING_METHODS[key]; + return this.agm.register(method.name, (args, caller) => { + this.registry.execute(key, args, caller); + }); + } + } + + const privateData$4 = new WeakMap(); + class ParentBuilder { + constructor(definition, base) { + const children = base.wrapChildren(definition.children); + delete definition.children; + privateData$4.set(this, { base, children, definition }); + } + get type() { + return privateData$4.get(this).definition.type; + } + addColumn(definition) { + const base = privateData$4.get(this).base; + return base.add("column", privateData$4.get(this).children, definition); + } + addRow(definition) { + const base = privateData$4.get(this).base; + return base.add("row", privateData$4.get(this).children, definition); + } + addGroup(definition) { + const base = privateData$4.get(this).base; + return base.add("group", privateData$4.get(this).children, definition); + } + addWindow(definition) { + const base = privateData$4.get(this).base; + base.addWindow(privateData$4.get(this).children, definition); + return this; + } + serialize() { + const definition = privateData$4.get(this).definition; + definition.children = privateData$4.get(this).base.serializeChildren(privateData$4.get(this).children); + return definition; + } + } + + class BaseBuilder { + getBuilder; + constructor(getBuilder) { + this.getBuilder = getBuilder; + } + wrapChildren(children) { + return children.map((child) => { + if (child.type === "window") { + return child; + } + return this.getBuilder({ type: child.type, definition: child }); + }); + } + add(type, children, definition) { + const validatedDefinition = parentDefinitionDecoder.runWithException(definition); + const childBuilder = this.getBuilder({ type, definition: validatedDefinition }); + children.push(childBuilder); + return childBuilder; + } + addWindow(children, definition) { + const validatedDefinition = swimlaneWindowDefinitionDecoder.runWithException(definition); + validatedDefinition.type = "window"; + children.push(validatedDefinition); + } + serializeChildren(children) { + return children.map((child) => { + if (child instanceof ParentBuilder) { + return child.serialize(); + } + else { + return child; + } + }); + } + } + + const privateData$3 = new WeakMap(); + class WorkspaceBuilder { + constructor(definition, base, controller) { + const children = base.wrapChildren(definition.children); + delete definition.children; + privateData$3.set(this, { base, children, definition, controller }); + } + addColumn(definition) { + const children = privateData$3.get(this).children; + const areAllColumns = children.every((child) => child instanceof ParentBuilder && child.type === "column"); + if (!areAllColumns) { + throw new Error("Cannot add a column to this workspace, because there are already children of another type"); + } + const base = privateData$3.get(this).base; + return base.add("column", children, definition); + } + addRow(definition) { + const children = privateData$3.get(this).children; + const areAllRows = children.every((child) => child instanceof ParentBuilder && child.type === "row"); + if (!areAllRows) { + throw new Error("Cannot add a row to this workspace, because there are already children of another type"); + } + const base = privateData$3.get(this).base; + return base.add("row", children, definition); + } + addGroup(definition) { + const children = privateData$3.get(this).children; + if (children.length !== 0) { + throw new Error("Cannot add a group to this workspace, because there are already defined children."); + } + const base = privateData$3.get(this).base; + return base.add("group", children, definition); + } + addWindow(definition) { + const children = privateData$3.get(this).children; + if (children.length !== 0) { + throw new Error("Cannot add a window to this workspace, because there are already defined children."); + } + const base = privateData$3.get(this).base; + base.addWindow(children, definition); + return this; + } + getChildAt(index) { + nonNegativeNumberDecoder.runWithException(index); + const data = privateData$3.get(this).children; + return data[index]; + } + async create(config) { + const saveConfig = workspaceBuilderCreateConfigDecoder.runWithException(config); + const definition = privateData$3.get(this).definition; + definition.children = privateData$3.get(this).base.serializeChildren(privateData$3.get(this).children); + const controller = privateData$3.get(this).controller; + return controller.createWorkspace(definition, saveConfig); + } + } + + const privateData$2 = new WeakMap(); + const getBase$2 = (model) => { + return privateData$2.get(model).base; + }; + class Row { + constructor(base) { + privateData$2.set(this, { base }); + } + get type() { + return "row"; + } + get id() { + return getBase$2(this).getId(this); + } + get frameId() { + return getBase$2(this).getFrameId(this); + } + get workspaceId() { + return getBase$2(this).getWorkspaceId(this); + } + get positionIndex() { + return getBase$2(this).getPositionIndex(this); + } + get children() { + return getBase$2(this).getAllChildren(this); + } + get parent() { + return getBase$2(this).getMyParent(this); + } + get frame() { + return getBase$2(this).getMyFrame(this); + } + get workspace() { + return getBase$2(this).getMyWorkspace(this); + } + get allowDrop() { + return getBase$2(this).getAllowDrop(this); + } + get allowSplitters() { + return getBase$2(this).getAllowSplitters(this); + } + get minWidth() { + return getBase$2(this).getMinWidth(this); + } + get minHeight() { + return getBase$2(this).getMinHeight(this); + } + get maxWidth() { + return getBase$2(this).getMaxWidth(this); + } + get maxHeight() { + return getBase$2(this).getMaxHeight(this); + } + get width() { + return getBase$2(this).getWidthInPx(this); + } + get height() { + return getBase$2(this).getHeightInPx(this); + } + get isPinned() { + return getBase$2(this).getIsPinned(this); + } + get isMaximized() { + return getBase$2(this).getIsMaximized(this); + } + get maximizationBoundary() { + return getBase$2(this).getMaximizationBoundary(this); + } + addWindow(definition) { + return getBase$2(this).addWindow(this, definition, "row"); + } + async addGroup(definition) { + if (definition?.type && definition.type !== "group") { + throw new Error(`Expected a group definition, but received ${definition.type}`); + } + return getBase$2(this).addParent(this, "group", "row", definition); + } + async addColumn(definition) { + if (definition?.type && definition.type !== "column") { + throw new Error(`Expected a column definition, but received ${definition.type}`); + } + return getBase$2(this).addParent(this, "column", "row", definition); + } + async addRow() { + throw new Error("Adding rows as row children is not supported"); + } + removeChild(predicate) { + return getBase$2(this).removeChild(this, predicate); + } + maximize() { + return getBase$2(this).maximize(this); + } + restore() { + return getBase$2(this).restore(this); + } + close() { + return getBase$2(this).close(this); + } + lock(config) { + let lockConfigResult = undefined; + if (typeof config === "function") { + const currentLockConfig = { + allowDrop: this.allowDrop, + allowSplitters: this.allowSplitters + }; + lockConfigResult = config(currentLockConfig); + } + else { + lockConfigResult = config; + } + const verifiedConfig = lockConfigResult === undefined ? undefined : rowLockConfigDecoder.runWithException(lockConfigResult); + return getBase$2(this).lockContainer(this, verifiedConfig); + } + async setHeight(height) { + nonNegativeNumberDecoder.runWithException(height); + return getBase$2(this).setHeight(this, height); + } + async onLockConfigurationChanged(callback) { + checkThrowCallback(callback); + const wrappedCallback = async () => { + await this.workspace.refreshReference(); + callback({ + allowDrop: this.allowDrop, + allowSplitters: this.allowSplitters + }); + }; + const config = { + callback: wrappedCallback, + action: "lock-configuration-changed", + eventType: "container", + scope: "container" + }; + const unsubscribe = await getBase$2(this).processLocalSubscription(this, config); + return unsubscribe; + } + async setMaximizationBoundary(config) { + const validatedConfig = setMaximizationBoundaryAPIConfigDecoder.runWithException(config); + return getBase$2(this).setMaximizationBoundary(this, validatedConfig); + } + } + + const privateData$1 = new WeakMap(); + const getBase$1 = (model) => { + return privateData$1.get(model).base; + }; + class Column { + constructor(base) { + privateData$1.set(this, { base }); + } + get type() { + return "column"; + } + get id() { + return getBase$1(this).getId(this); + } + get frameId() { + return getBase$1(this).getFrameId(this); + } + get workspaceId() { + return getBase$1(this).getWorkspaceId(this); + } + get positionIndex() { + return getBase$1(this).getPositionIndex(this); + } + get children() { + return getBase$1(this).getAllChildren(this); + } + get parent() { + return getBase$1(this).getMyParent(this); + } + get frame() { + return getBase$1(this).getMyFrame(this); + } + get workspace() { + return getBase$1(this).getMyWorkspace(this); + } + get allowDrop() { + return getBase$1(this).getAllowDrop(this); + } + get allowSplitters() { + return getBase$1(this).getAllowSplitters(this); + } + get minWidth() { + return getBase$1(this).getMinWidth(this); + } + get minHeight() { + return getBase$1(this).getMinHeight(this); + } + get maxWidth() { + return getBase$1(this).getMaxWidth(this); + } + get maxHeight() { + return getBase$1(this).getMaxHeight(this); + } + get width() { + return getBase$1(this).getWidthInPx(this); + } + get height() { + return getBase$1(this).getHeightInPx(this); + } + get isPinned() { + return getBase$1(this).getIsPinned(this); + } + get isMaximized() { + return getBase$1(this).getIsMaximized(this); + } + get maximizationBoundary() { + return getBase$1(this).getMaximizationBoundary(this); + } + addWindow(definition) { + return getBase$1(this).addWindow(this, definition, "column"); + } + async addGroup(definition) { + if (definition?.type && definition.type !== "group") { + throw new Error(`Expected a group definition, but received ${definition.type}`); + } + return getBase$1(this).addParent(this, "group", "column", definition); + } + async addColumn() { + throw new Error("Adding columns as column children is not supported"); + } + async addRow(definition) { + if (definition?.type && definition.type !== "row") { + throw new Error(`Expected a row definition, but received ${definition.type}`); + } + return getBase$1(this).addParent(this, "row", "column", definition); + } + removeChild(predicate) { + return getBase$1(this).removeChild(this, predicate); + } + maximize() { + return getBase$1(this).maximize(this); + } + restore() { + return getBase$1(this).restore(this); + } + close() { + return getBase$1(this).close(this); + } + lock(config) { + let lockConfigResult = undefined; + if (typeof config === "function") { + const currentLockConfig = { + allowDrop: this.allowDrop, + allowSplitters: this.allowSplitters + }; + lockConfigResult = config(currentLockConfig); + } + else { + lockConfigResult = config; + } + const verifiedConfig = lockConfigResult === undefined ? undefined : columnLockConfigDecoder.runWithException(lockConfigResult); + return getBase$1(this).lockContainer(this, verifiedConfig); + } + async setWidth(width) { + nonNegativeNumberDecoder.runWithException(width); + return getBase$1(this).setWidth(this, width); + } + async onLockConfigurationChanged(callback) { + checkThrowCallback(callback); + const wrappedCallback = async () => { + await this.workspace.refreshReference(); + callback({ + allowDrop: this.allowDrop, + allowSplitters: this.allowSplitters + }); + }; + const config = { + callback: wrappedCallback, + action: "lock-configuration-changed", + eventType: "container", + scope: "container" + }; + const unsubscribe = await getBase$1(this).processLocalSubscription(this, config); + return unsubscribe; + } + async setMaximizationBoundary(config) { + const validatedConfig = setMaximizationBoundaryAPIConfigDecoder.runWithException(config); + return getBase$1(this).setMaximizationBoundary(this, validatedConfig); + } + } + + const privateData = new WeakMap(); + const getBase = (model) => { + return privateData.get(model).base; + }; + class Group { + constructor(base) { + privateData.set(this, { base }); + } + get type() { + return "group"; + } + get id() { + return getBase(this).getId(this); + } + get frameId() { + return getBase(this).getFrameId(this); + } + get workspaceId() { + return getBase(this).getWorkspaceId(this); + } + get positionIndex() { + return getBase(this).getPositionIndex(this); + } + get children() { + return getBase(this).getAllChildren(this); + } + get parent() { + return getBase(this).getMyParent(this); + } + get frame() { + return getBase(this).getMyFrame(this); + } + get workspace() { + return getBase(this).getMyWorkspace(this); + } + get allowExtract() { + return getBase(this).getAllowExtract(this); + } + get allowReorder() { + return getBase(this).getAllowReorder(this); + } + get allowDropLeft() { + return getBase(this).getAllowDropLeft(this); + } + get allowDropRight() { + return getBase(this).getAllowDropRight(this); + } + get allowDropTop() { + return getBase(this).getAllowDropTop(this); + } + get allowDropBottom() { + return getBase(this).getAllowDropBottom(this); + } + get allowDropHeader() { + return getBase(this).getAllowDropHeader(this); + } + get allowDrop() { + return getBase(this).getAllowDrop(this); + } + get showMaximizeButton() { + return getBase(this).getShowMaximizeButton(this); + } + get showEjectButton() { + return getBase(this).getShowEjectButton(this); + } + get showAddWindowButton() { + return getBase(this).getShowAddWindowButton(this); + } + get minWidth() { + return getBase(this).getMinWidth(this); + } + get minHeight() { + return getBase(this).getMinHeight(this); + } + get maxWidth() { + return getBase(this).getMaxWidth(this); + } + get maxHeight() { + return getBase(this).getMaxHeight(this); + } + get width() { + return getBase(this).getWidthInPx(this); + } + get height() { + return getBase(this).getHeightInPx(this); + } + get isMaximized() { + return getBase(this).getIsMaximized(this); + } + addWindow(definition) { + return getBase(this).addWindow(this, definition, "group"); + } + async addGroup() { + throw new Error("Adding groups as group child is not supported"); + } + async addColumn() { + throw new Error("Adding columns as group child is not supported"); + } + async addRow() { + throw new Error("Adding rows as group child is not supported"); + } + removeChild(predicate) { + return getBase(this).removeChild(this, predicate); + } + maximize() { + return getBase(this).maximize(this); + } + restore() { + return getBase(this).restore(this); + } + close() { + return getBase(this).close(this); + } + lock(config) { + let lockConfigResult = undefined; + if (typeof config === "function") { + const currentLockConfig = { + allowDrop: this.allowDrop, + allowDropHeader: this.allowDropHeader, + allowDropLeft: this.allowDropLeft, + allowDropRight: this.allowDropRight, + allowDropTop: this.allowDropTop, + allowDropBottom: this.allowDropBottom, + allowExtract: this.allowExtract, + allowReorder: this.allowReorder, + showAddWindowButton: this.showAddWindowButton, + showEjectButton: this.showEjectButton, + showMaximizeButton: this.showMaximizeButton + }; + lockConfigResult = config(currentLockConfig); + } + else { + lockConfigResult = config; + } + const verifiedConfig = lockConfigResult === undefined ? undefined : groupLockConfigDecoder.runWithException(lockConfigResult); + return getBase(this).lockContainer(this, verifiedConfig); + } + async setSize(config) { + const verifiedConfig = elementResizeConfigDecoder.runWithException(config); + if (!verifiedConfig.width && !verifiedConfig.height) { + throw new Error("Expected either width or height to be passed."); + } + return getBase(this).setSize(this, config.width, config.height); + } + async bundleToRow() { + await getBase(this).bundleTo(this, "row"); + await this.workspace.refreshReference(); + } + async bundleToColumn() { + await getBase(this).bundleTo(this, "column"); + await this.workspace.refreshReference(); + } + async onLockConfigurationChanged(callback) { + checkThrowCallback(callback); + const wrappedCallback = async () => { + await this.workspace.refreshReference(); + callback({ + allowDrop: this.allowDrop, + allowDropHeader: this.allowDropHeader, + allowDropLeft: this.allowDropLeft, + allowDropTop: this.allowDropTop, + allowDropRight: this.allowDropRight, + allowDropBottom: this.allowDropBottom, + allowExtract: this.allowExtract, + allowReorder: this.allowReorder, + showAddWindowButton: this.showAddWindowButton, + showEjectButton: this.showEjectButton, + showMaximizeButton: this.showMaximizeButton + }); + }; + const config = { + callback: wrappedCallback, + action: "lock-configuration-changed", + eventType: "container", + scope: "container" + }; + const unsubscribe = await getBase(this).processLocalSubscription(this, config); + return unsubscribe; + } + } + + const DEFAULT_WINDOW_DRAG_MODE = "keepInside"; + + const data$3 = new WeakMap(); + const getData$3 = (model) => { + return data$3.get(model).manager.getWorkspaceData(model); + }; + const getDataManager = (model) => { + return data$3.get(model).manager; + }; + class Workspace { + constructor(dataManager) { + data$3.set(this, { manager: dataManager }); + } + get id() { + return getData$3(this).id; + } + get frameId() { + return getData$3(this).config.frameId; + } + get positionIndex() { + return getData$3(this).config.positionIndex; + } + get title() { + return getData$3(this).config.title; + } + get layoutName() { + return getData$3(this).config.layoutName; + } + get isHibernated() { + return getData$3(this).config.isHibernated; + } + get isSelected() { + return getData$3(this).config.isSelected; + } + get children() { + return getData$3(this).children; + } + get frame() { + return getData$3(this).frame; + } + get allowSplitters() { + return getData$3(this).config.allowSplitters; + } + get allowSystemHibernation() { + return getData$3(this).config.allowSystemHibernation; + } + get allowDrop() { + return getData$3(this).config.allowDrop; + } + get allowDropLeft() { + return getData$3(this).config.allowDropLeft; + } + get allowDropTop() { + return getData$3(this).config.allowDropTop; + } + get allowDropRight() { + return getData$3(this).config.allowDropRight; + } + get allowDropBottom() { + return getData$3(this).config.allowDropBottom; + } + get allowExtract() { + return getData$3(this).config.allowExtract; + } + get allowWindowReorder() { + return getData$3(this).config.allowWindowReorder; + } + get showCloseButton() { + return getData$3(this).config.showCloseButton; + } + get showSaveButton() { + return getData$3(this).config.showSaveButton; + } + get allowWorkspaceTabReorder() { + return getData$3(this).config.allowWorkspaceTabReorder; + } + get allowWorkspaceTabExtract() { + return getData$3(this).config.allowWorkspaceTabExtract; + } + get minWidth() { + return getData$3(this).config.minWidth; + } + get minHeight() { + return getData$3(this).config.minHeight; + } + get maxWidth() { + return getData$3(this).config.maxWidth; + } + get maxHeight() { + return getData$3(this).config.maxHeight; + } + get width() { + return getData$3(this).config.widthInPx; + } + get height() { + return getData$3(this).config.heightInPx; + } + get showWindowCloseButtons() { + return getData$3(this).config.showWindowCloseButtons; + } + get showEjectButtons() { + return getData$3(this).config.showEjectButtons; + } + get showAddWindowButtons() { + return getData$3(this).config.showAddWindowButtons; + } + get isPinned() { + return getData$3(this).config.isPinned; + } + get windowDragMode() { + const desktopGlobal = isDesktop(); + if (!desktopGlobal) { + return DEFAULT_WINDOW_DRAG_MODE; + } + return getData$3(this).config.windowDragMode; + } + get loadingStrategy() { + if (!isDesktop()) { + console.warn("The workspace.loadingStrategy property is not supported in IO Connect Browser"); + } + return getData$3(this).config.loadingStrategy; + } + async setLoadingStrategy(strategy) { + if (!isDesktop()) { + throw new Error("Not supported in IO Connect Browser"); + } + const controller = getData$3(this).controller; + await controller.setLoadingStrategy(this.id, strategy); + await this.refreshReference(); + } + async removeChild(predicate) { + checkThrowCallback(predicate); + const child = this.children.find(predicate); + if (!child) { + return; + } + await child.close(); + await this.refreshReference(); + } + async remove(predicate) { + checkThrowCallback(predicate); + const controller = getData$3(this).controller; + const child = controller.iterateFindChild(this.children, predicate); + await child.close(); + await this.refreshReference(); + } + async focus() { + await getData$3(this).controller.focusItem(this.id); + await this.refreshReference(); + } + async close() { + const controller = getData$3(this).controller; + const workspaces = await getData$3(this).frame.workspaces(); + const platformFrameId = (await controller.getPlatformFrameId()).id; + const shouldCloseFrame = workspaces.length === 1 && + workspaces.every((wsp) => wsp.id === this.id) && + platformFrameId !== this.frame.id; + if (shouldCloseFrame) { + return this.frame.close(); + } + await controller.closeItem(this.id); + } + snapshot() { + return getData$3(this).controller.getSnapshot(this.id, "workspace"); + } + async saveLayout(name, config) { + nonEmptyStringDecoder.runWithException(name); + await getData$3(this).controller.saveLayout({ name, workspaceId: this.id, saveContext: config?.saveContext, metadata: config?.metadata, allowMultiple: config?.allowMultiple }); + } + async setTitle(title) { + nonEmptyStringDecoder.runWithException(title); + const controller = getData$3(this).controller; + await controller.setItemTitle(this.id, title); + await this.refreshReference(); + } + getContext() { + const controller = getData$3(this).controller; + return controller.getWorkspaceContext(this.id); + } + setContext(data) { + const controller = getData$3(this).controller; + return controller.setWorkspaceContext(this.id, data); + } + updateContext(data) { + const controller = getData$3(this).controller; + return controller.updateWorkspaceContext(this.id, data); + } + onContextUpdated(callback) { + const controller = getData$3(this).controller; + return controller.subscribeWorkspaceContextUpdated(this.id, callback); + } + async refreshReference() { + const newSnapshot = (await getData$3(this).controller.getSnapshot(this.id, "workspace")); + const currentChildrenFlat = getData$3(this).controller.flatChildren(getData$3(this).children); + const newChildren = getData$3(this).controller.refreshChildren({ + existingChildren: currentChildrenFlat, + workspace: this, + parent: this, + children: newSnapshot.children + }); + const currentFrame = this.frame; + let actualFrame; + if (currentFrame.id === newSnapshot.config.frameId) { + getDataManager(this).remapFrame(currentFrame, newSnapshot.frameSummary); + actualFrame = currentFrame; + } + else { + const frameCreateConfig = { + summary: newSnapshot.frameSummary + }; + const newFrame = getData$3(this).ioc.getModel("frame", frameCreateConfig); + actualFrame = newFrame; + } + getDataManager(this).remapWorkspace(this, { + config: newSnapshot.config, + children: newChildren, + frame: actualFrame + }); + } + async getIcon() { + const controller = getData$3(this).controller; + return controller.getWorkspaceIcon(this.id); + } + async setIcon(icon) { + const controller = getData$3(this).controller; + return controller.setWorkspaceIcon(this.id, icon); + } + getBox(predicate) { + checkThrowCallback(predicate); + const children = getData$3(this).children; + const controller = getData$3(this).controller; + return controller.iterateFindChild(children, (child) => child.type !== "window" && predicate(child)); + } + getAllBoxes(predicate) { + checkThrowCallback(predicate, true); + const children = getData$3(this).children; + const controller = getData$3(this).controller; + const allParents = controller.iterateFilterChildren(children, (child) => child.type !== "window"); + if (!predicate) { + return allParents; + } + return allParents.filter(predicate); + } + getRow(predicate) { + checkThrowCallback(predicate); + return this.getBox((parent) => parent.type === "row" && predicate(parent)); + } + getAllRows(predicate) { + checkThrowCallback(predicate, true); + if (predicate) { + return this.getAllBoxes((parent) => parent.type === "row" && predicate(parent)); + } + return this.getAllBoxes((parent) => parent.type === "row"); + } + getColumn(predicate) { + checkThrowCallback(predicate); + return this.getBox((parent) => parent.type === "column" && predicate(parent)); + } + getAllColumns(predicate) { + checkThrowCallback(predicate, true); + if (predicate) { + return this.getAllBoxes((parent) => parent.type === "column" && predicate(parent)); + } + return this.getAllBoxes((parent) => parent.type === "column"); + } + getGroup(predicate) { + checkThrowCallback(predicate); + return this.getBox((parent) => parent.type === "group" && predicate(parent)); + } + getAllGroups(predicate) { + checkThrowCallback(predicate, true); + if (predicate) { + return this.getAllBoxes((parent) => parent.type === "group" && predicate(parent)); + } + return this.getAllBoxes((parent) => parent.type === "group"); + } + getWindow(predicate) { + checkThrowCallback(predicate); + const children = getData$3(this).children; + const controller = getData$3(this).controller; + return controller.iterateFindChild(children, (child) => child.type === "window" && predicate(child)); + } + getAllWindows(predicate) { + checkThrowCallback(predicate, true); + const children = getData$3(this).children; + const controller = getData$3(this).controller; + const allWindows = controller.iterateFilterChildren(children, (child) => child.type === "window"); + if (!predicate) { + return allWindows; + } + return allWindows.filter(predicate); + } + addRow(definition) { + return getData$3(this).base.addParent(this, "row", "workspace", definition); + } + addColumn(definition) { + return getData$3(this).base.addParent(this, "column", "workspace", definition); + } + addGroup(definition) { + return getData$3(this).base.addParent(this, "group", "workspace", definition); + } + addWindow(definition) { + return getData$3(this).base.addWindow(this, definition, "workspace"); + } + async bundleToRow() { + await getData$3(this).controller.bundleWorkspaceTo("row", this.id); + await this.refreshReference(); + } + async bundleToColumn() { + await getData$3(this).controller.bundleWorkspaceTo("column", this.id); + await this.refreshReference(); + } + async hibernate() { + await getData$3(this).controller.hibernateWorkspace(this.id); + await this.refreshReference(); + } + async resume() { + await getData$3(this).controller.resumeWorkspace(this.id); + await this.refreshReference(); + } + async lock(config) { + let lockConfigResult = undefined; + if (typeof config === "function") { + const currentLockConfig = { + allowDrop: this.allowDrop, + allowDropLeft: this.allowDropLeft, + allowDropTop: this.allowDropTop, + allowDropRight: this.allowDropRight, + allowDropBottom: this.allowDropBottom, + allowSystemHibernation: this.allowSystemHibernation, + allowExtract: this.allowExtract, + allowWindowReorder: this.allowWindowReorder, + allowSplitters: this.allowSplitters, + showCloseButton: this.showCloseButton, + showSaveButton: this.showSaveButton, + allowWorkspaceTabReorder: this.allowWorkspaceTabReorder, + allowWorkspaceTabExtract: this.allowWorkspaceTabExtract, + showAddWindowButtons: this.showAddWindowButtons, + showEjectButtons: this.showEjectButtons, + showWindowCloseButtons: this.showWindowCloseButtons + }; + lockConfigResult = config(currentLockConfig); + } + else { + lockConfigResult = config; + } + const verifiedConfig = lockConfigResult === undefined ? undefined : workspaceLockConfigDecoder.runWithException(lockConfigResult); + await getData$3(this).controller.lockWorkspace(this.id, verifiedConfig); + await this.refreshReference(); + } + async pin(options) { + workspacePinOptionsDecoder.runWithException(options); + await getData$3(this).controller.pinWorkspace(this.id, options?.icon); + await this.refreshReference(); + } + async unpin() { + await getData$3(this).controller.unpinWorkspace(this.id); + await this.refreshReference(); + } + async showLoadingAnimation() { + if (!isDesktop()) { + throw new Error("Not supported in IO Connect Browser"); + } + await getData$3(this).controller.showWorkspaceLoadingAnimation(this.id); + } + async hideLoadingAnimation() { + if (!isDesktop()) { + throw new Error("Not supported in IO Connect Browser"); + } + await getData$3(this).controller.hideWorkspaceLoadingAnimation(this.id); + } + async setWindowDragMode(mode) { + const desktopGlobal = isDesktop(); + if (!desktopGlobal) { + throw new Error("Not supported in IO Connect Browser"); + } + windowDragModeDecoder.runWithException(mode); + await getData$3(this).controller.setWindowDragMode(this.id, mode); + await this.refreshReference(); + } + async onClosed(callback) { + checkThrowCallback(callback); + const id = getData$3(this).id; + const wrappedCallback = async (payload) => { + callback({ frameId: payload.frameSummary.id, workspaceId: payload.workspaceSummary.id, frameBounds: payload.frameBounds }); + }; + const config = { + action: "closed", + eventType: "workspace", + scope: "workspace", + scopeId: id, + callback: wrappedCallback + }; + const unsubscribe = await getData$3(this).controller.processLocalSubscription(config, id); + return unsubscribe; + } + async onHibernated(callback) { + checkThrowCallback(callback); + const id = getData$3(this).id; + const wrappedCallback = async () => { + await this.refreshReference(); + callback(); + }; + const config = { + action: "hibernated", + eventType: "workspace", + scope: "workspace", + scopeId: id, + callback: wrappedCallback + }; + const unsubscribe = await getData$3(this).controller.processLocalSubscription(config, id); + return unsubscribe; + } + async onResumed(callback) { + checkThrowCallback(callback); + const id = getData$3(this).id; + const wrappedCallback = async () => { + await this.refreshReference(); + callback(); + }; + const config = { + action: "resumed", + eventType: "workspace", + scope: "workspace", + scopeId: id, + callback: wrappedCallback + }; + const unsubscribe = await getData$3(this).controller.processLocalSubscription(config, id); + return unsubscribe; + } + async onWindowAdded(callback) { + checkThrowCallback(callback); + const id = getData$3(this).id; + const wrappedCallback = async (payload) => { + await this.refreshReference(); + const windowParent = this.getBox((parent) => parent.id === payload.windowSummary.parentId); + const foundWindow = windowParent.children.find((child) => { + return child.type === "window" && child.elementId === payload.windowSummary.itemId; + }); + callback(foundWindow); + }; + const config = { + action: "added", + eventType: "window", + scope: "workspace", + scopeId: id, + callback: wrappedCallback + }; + const unsubscribe = await getData$3(this).controller.processLocalSubscription(config, id); + return unsubscribe; + } + async onWindowRemoved(callback) { + checkThrowCallback(callback); + const id = getData$3(this).id; + const wrappedCallback = async (payload) => { + await this.refreshReference(); + const { windowId, workspaceId, frameId } = payload.windowSummary.config; + callback({ windowId, workspaceId, frameId }); + }; + const config = { + action: "removed", + eventType: "window", + scope: "workspace", + scopeId: id, + callback: wrappedCallback + }; + const unsubscribe = await getData$3(this).controller.processLocalSubscription(config, id); + return unsubscribe; + } + async onWindowLoaded(callback) { + checkThrowCallback(callback); + const id = getData$3(this).id; + const wrappedCallback = async (payload) => { + await this.refreshReference(); + const foundWindow = this.getWindow((win) => { + return win.id && win.id === payload.windowSummary.config.windowId; + }); + callback(foundWindow); + }; + const config = { + action: "loaded", + eventType: "window", + scope: "workspace", + scopeId: id, + callback: wrappedCallback + }; + const unsubscribe = await getData$3(this).controller.processLocalSubscription(config, id); + return unsubscribe; + } + async onWindowMaximized(callback) { + checkThrowCallback(callback); + const id = getData$3(this).id; + const wrappedCallback = async (payload) => { + await this.refreshReference(); + const windowParent = this.getBox((parent) => parent.id === payload.windowSummary.parentId); + const foundWindow = windowParent.children.find((child) => { + return child.type === "window" && child.elementId === payload.windowSummary.itemId; + }); + callback(foundWindow); + }; + const config = { + action: "maximized", + eventType: "window", + scope: "workspace", + scopeId: id, + callback: wrappedCallback + }; + const unsubscribe = await getData$3(this).controller.processLocalSubscription(config, id); + return unsubscribe; + } + async onWindowRestored(callback) { + checkThrowCallback(callback); + const id = getData$3(this).id; + const wrappedCallback = async (payload) => { + await this.refreshReference(); + const windowParent = this.getBox((parent) => parent.id === payload.windowSummary.parentId); + const foundWindow = windowParent.children.find((child) => { + return child.type === "window" && child.elementId === payload.windowSummary.itemId; + }); + callback(foundWindow); + }; + const config = { + action: "restored", + eventType: "window", + scope: "workspace", + scopeId: id, + callback: wrappedCallback + }; + const unsubscribe = await getData$3(this).controller.processLocalSubscription(config, id); + return unsubscribe; + } + async onWindowSelected(callback) { + checkThrowCallback(callback); + const id = getData$3(this).id; + const wrappedCallback = async (payload) => { + await this.refreshReference(); + const windowParent = this.getBox((parent) => parent.id === payload.windowSummary.parentId); + const foundWindow = windowParent.children.find((child) => { + return child.type === "window" && child.elementId === payload.windowSummary.itemId; + }); + callback(foundWindow); + }; + const config = { + action: "selected", + eventType: "window", + scope: "workspace", + scopeId: id, + callback: wrappedCallback + }; + const unsubscribe = await getData$3(this).controller.processLocalSubscription(config, id); + return unsubscribe; + } + async onLockConfigurationChanged(callback) { + checkThrowCallback(callback); + const id = getData$3(this).id; + const wrappedCallback = async () => { + await this.refreshReference(); + callback({ + allowDrop: this.allowDrop, + allowDropLeft: this.allowDropLeft, + allowDropTop: this.allowDropTop, + allowDropRight: this.allowDropRight, + allowDropBottom: this.allowDropBottom, + allowSystemHibernation: this.allowSystemHibernation, + allowExtract: this.allowExtract, + allowSplitters: this.allowSplitters, + allowWindowReorder: this.allowWindowReorder, + allowWorkspaceTabExtract: this.allowWorkspaceTabExtract, + allowWorkspaceTabReorder: this.allowWorkspaceTabReorder, + showAddWindowButtons: this.showAddWindowButtons, + showCloseButton: this.showCloseButton, + showEjectButtons: this.showEjectButtons, + showSaveButton: this.showSaveButton, + showWindowCloseButtons: this.showWindowCloseButtons + }); + }; + const config = { + action: "lock-configuration-changed", + eventType: "workspace", + scope: "workspace", + scopeId: id, + callback: wrappedCallback + }; + const unsubscribe = await getData$3(this).controller.processLocalSubscription(config, id); + return unsubscribe; + } + } + + const data$2 = new WeakMap(); + const getData$2 = (model) => { + return data$2.get(model).manager.getWindowData(model); + }; + class Window { + constructor(dataManager) { + data$2.set(this, { manager: dataManager }); + } + get id() { + return getData$2(this).config.windowId; + } + get elementId() { + return getData$2(this).id; + } + get type() { + return "window"; + } + get frameId() { + return getData$2(this).frame.id; + } + get workspaceId() { + return getData$2(this).workspace.id; + } + get positionIndex() { + return getData$2(this).config.positionIndex; + } + get isMaximized() { + return getData$2(this).config.isMaximized; + } + get isLoaded() { + return getData$2(this).controller.checkIsWindowLoaded(this.id); + } + get isSelected() { + return getData$2(this).config.isSelected; + } + get focused() { + return this.getGdWindow().isFocused; + } + get title() { + return getData$2(this).config.title; + } + get allowExtract() { + return getData$2(this).config.allowExtract; + } + get allowReorder() { + return getData$2(this).config.allowReorder; + } + get showCloseButton() { + return getData$2(this).config.showCloseButton; + } + get width() { + return getData$2(this).config.widthInPx; + } + get height() { + return getData$2(this).config.heightInPx; + } + get minWidth() { + return getData$2(this).config.minWidth; + } + get minHeight() { + return getData$2(this).config.minHeight; + } + get maxWidth() { + return getData$2(this).config.maxWidth; + } + get maxHeight() { + return getData$2(this).config.maxHeight; + } + get workspace() { + return getData$2(this).workspace; + } + get frame() { + return getData$2(this).frame; + } + get parent() { + return getData$2(this).parent; + } + get appName() { + return getData$2(this).config.appName; + } + async forceLoad() { + if (this.isLoaded) { + return; + } + const controller = getData$2(this).controller; + const itemId = getData$2(this).id; + const windowId = await controller.forceLoadWindow(itemId); + getData$2(this).config.windowId = windowId; + await this.workspace.refreshReference(); + } + async focus() { + const id = getData$2(this).id; + const controller = getData$2(this).controller; + await controller.focusItem(id); + await this.workspace.refreshReference(); + } + async close() { + const id = getData$2(this).id; + const controller = getData$2(this).controller; + await controller.closeItem(id); + await getData$2(this) + .parent + .removeChild((child) => child.id === id); + await this.workspace.refreshReference(); + } + async setTitle(title) { + nonEmptyStringDecoder.runWithException(title); + const itemId = getData$2(this).id; + const controller = getData$2(this).controller; + await controller.setItemTitle(itemId, title); + await this.workspace.refreshReference(); + } + async maximize() { + const id = getData$2(this).id; + const controller = getData$2(this).controller; + await controller.maximizeItem(id); + await this.workspace.refreshReference(); + } + async restore() { + const id = getData$2(this).id; + const controller = getData$2(this).controller; + await controller.restoreItem(id); + await this.workspace.refreshReference(); + } + async eject() { + if (!this.isLoaded) { + throw new Error("Cannot eject this window, because it is not loaded yet"); + } + const itemId = getData$2(this).id; + const newWindowId = await getData$2(this).controller.ejectWindow(itemId); + getData$2(this).config.windowId = newWindowId; + await this.workspace.refreshReference(); + return this.getGdWindow(); + } + getGdWindow() { + if (!this.isLoaded) { + throw new Error("Cannot fetch this GD window, because the window is not yet loaded"); + } + const myId = getData$2(this).config.windowId; + const controller = getData$2(this).controller; + return controller.getGDWindow(myId); + } + async moveTo(parent) { + if (!(parent instanceof Row || parent instanceof Column || parent instanceof Group)) { + throw new Error("Cannot add to the provided parent, because the provided parent is not an instance of Row, Column or Group"); + } + const myId = getData$2(this).id; + const controller = getData$2(this).controller; + const foundParent = await controller.getParent((p) => p.id === parent.id); + if (!foundParent) { + throw new Error("Cannot move the window to the selected parent, because this parent does not exist."); + } + await controller.moveWindowTo(myId, parent.id); + await this.workspace.refreshReference(); + } + async lock(config) { + let lockConfigResult = undefined; + if (typeof config === "function") { + const currentLockConfig = { + allowExtract: this.allowExtract, + allowReorder: this.allowReorder, + showCloseButton: this.showCloseButton + }; + lockConfigResult = config(currentLockConfig); + } + else { + lockConfigResult = config; + } + const verifiedConfig = lockConfigResult === undefined ? undefined : windowLockConfigDecoder.runWithException(lockConfigResult); + const windowPlacementId = getData$2(this).id; + await getData$2(this).controller.lockWindow(windowPlacementId, verifiedConfig); + await this.workspace.refreshReference(); + } + async setSize(config) { + const verifiedConfig = elementResizeConfigDecoder.runWithException(config); + if (!verifiedConfig.width && !verifiedConfig.height) { + throw new Error("Expected either width or height to be passed."); + } + const myId = getData$2(this).id; + const controller = getData$2(this).controller; + await controller.resizeItem(myId, { + height: verifiedConfig.height, + width: verifiedConfig.width, + relative: false + }); + await this.workspace.refreshReference(); + } + async onRemoved(callback) { + checkThrowCallback(callback); + const id = getData$2(this).id; + const wrappedCallback = async () => { + await this.workspace.refreshReference(); + callback(); + }; + const config = { + callback: wrappedCallback, + action: "removed", + eventType: "window", + scope: "window" + }; + const unsubscribe = await getData$2(this).controller.processLocalSubscription(config, id); + return unsubscribe; + } + async onLockConfigurationChanged(callback) { + checkThrowCallback(callback); + const id = getData$2(this).id; + const wrappedCallback = async () => { + await this.workspace.refreshReference(); + callback({ + allowExtract: this.allowExtract, + allowReorder: this.allowReorder, + showCloseButton: this.showCloseButton + }); + }; + const config = { + callback: wrappedCallback, + action: "lock-configuration-changed", + eventType: "window", + scope: "window" + }; + const unsubscribe = await getData$2(this).controller.processLocalSubscription(config, id); + return unsubscribe; + } + } + + const data$1 = new WeakMap(); + const getData$1 = (model) => { + return data$1.get(model).manager.getFrameData(model); + }; + class Frame { + constructor(dataManager) { + data$1.set(this, { manager: dataManager }); + } + async registerShortcut(shortcut, callback) { + nonEmptyStringDecoder.runWithException(shortcut); + checkThrowCallback(callback); + const myId = getData$1(this).summary.id; + const unsubscribe = await getData$1(this).controller.registerShortcut(shortcut, myId, callback); + return unsubscribe; + } + get id() { + return getData$1(this).summary.id; + } + get isInitialized() { + return getData$1(this).summary.isInitialized; + } + getBounds() { + const myId = getData$1(this).summary.id; + return getData$1(this).controller.getFrameBounds(myId); + } + async resize(config) { + const validatedConfig = resizeConfigDecoder.runWithException(config); + const myId = getData$1(this).summary.id; + return getData$1(this).controller.resizeItem(myId, validatedConfig); + } + async move(config) { + const validatedConfig = moveConfigDecoder.runWithException(config); + const myId = getData$1(this).summary.id; + return getData$1(this).controller.moveFrame(myId, validatedConfig); + } + focus() { + const myId = getData$1(this).summary.id; + return getData$1(this).controller.focusItem(myId); + } + async state() { + if (!isDesktop()) { + throw new Error("State operations are not supported in IO Connect Browser"); + } + const myId = getData$1(this).summary.id; + return getData$1(this).controller.getFrameState(myId); + } + async minimize() { + if (!isDesktop()) { + throw new Error("State operations are not supported in IO Connect Browser"); + } + const myId = getData$1(this).summary.id; + return getData$1(this).controller.changeFrameState(myId, "minimized"); + } + async maximize() { + if (!isDesktop()) { + throw new Error("State operations are not supported in IO Connect Browser"); + } + const myId = getData$1(this).summary.id; + return getData$1(this).controller.changeFrameState(myId, "maximized"); + } + async restore() { + if (!isDesktop()) { + throw new Error("State operations are not supported in IO Connect Browser"); + } + const myId = getData$1(this).summary.id; + return getData$1(this).controller.changeFrameState(myId, "normal"); + } + close() { + const myId = getData$1(this).summary.id; + return getData$1(this).controller.closeItem(myId); + } + snapshot() { + const myId = getData$1(this).summary.id; + return getData$1(this).controller.getSnapshot(myId, "frame"); + } + async workspaces() { + const controller = getData$1(this).controller; + return controller.getWorkspacesByFrameId(this.id); + } + async getConstraints() { + const controller = getData$1(this).controller; + const myId = getData$1(this).summary.id; + return controller.getFrameConstraints(myId); + } + async restoreWorkspace(name, options) { + nonEmptyStringDecoder.runWithException(name); + const validatedOptions = restoreWorkspaceConfigDecoder.runWithException(options); + return getData$1(this).controller.restoreWorkspace(name, validatedOptions); + } + createWorkspace(definition, config) { + const validatedDefinition = workspaceDefinitionDecoder.runWithException(definition); + const validatedConfig = workspaceBuilderCreateConfigDecoder.runWithException(config); + return getData$1(this).controller.createWorkspace(validatedDefinition, validatedConfig); + } + async init(config) { + frameInitConfigDecoder.runWithException(config); + if (getData$1(this).summary.isInitialized) { + throw new Error("The frame has already been initialized"); + } + return getData$1(this).controller.initFrame(this.id, config); + } + async onClosed(callback) { + checkThrowCallback(callback); + const myId = getData$1(this).summary.id; + const wrappedCallback = (payload) => { + callback({ frameId: payload.frameSummary.id, frameBounds: payload.frameBounds }); + }; + const config = { + callback: wrappedCallback, + action: "closed", + eventType: "frame", + scope: "frame" + }; + const unsubscribe = await getData$1(this).controller.processLocalSubscription(config, myId); + return unsubscribe; + } + async onMaximized(callback) { + checkThrowCallback(callback); + const myId = getData$1(this).summary.id; + const wrappedCallback = () => { + callback(); + }; + const config = { + callback: wrappedCallback, + action: "maximized", + eventType: "frame", + scope: "frame" + }; + const unsubscribe = await getData$1(this).controller.processLocalSubscription(config, myId); + return unsubscribe; + } + async onMinimized(callback) { + checkThrowCallback(callback); + const myId = getData$1(this).summary.id; + const wrappedCallback = () => { + callback(); + }; + const config = { + callback: wrappedCallback, + action: "minimized", + eventType: "frame", + scope: "frame" + }; + const unsubscribe = await getData$1(this).controller.processLocalSubscription(config, myId); + return unsubscribe; + } + async onNormal(callback) { + checkThrowCallback(callback); + const myId = getData$1(this).summary.id; + const wrappedCallback = () => { + callback(); + }; + const config = { + callback: wrappedCallback, + action: "normal", + eventType: "frame", + scope: "frame" + }; + const unsubscribe = await getData$1(this).controller.processLocalSubscription(config, myId); + return unsubscribe; + } + async onWorkspaceOpened(callback) { + checkThrowCallback(callback); + const myId = getData$1(this).summary.id; + const wrappedCallback = async (payload) => { + const workspace = await getData$1(this).controller.transformStreamPayloadToWorkspace(payload); + callback(workspace); + }; + const config = { + callback: wrappedCallback, + action: "opened", + eventType: "workspace", + scope: "frame" + }; + const unsubscribe = await getData$1(this).controller.processLocalSubscription(config, myId); + return unsubscribe; + } + async onWorkspaceSelected(callback) { + checkThrowCallback(callback); + const myId = getData$1(this).summary.id; + const wrappedCallback = async (payload) => { + const workspace = await getData$1(this).controller.getWorkspaceById(payload.workspaceSummary.id); + callback(workspace); + }; + const config = { + callback: wrappedCallback, + action: "selected", + eventType: "workspace", + scope: "frame" + }; + const unsubscribe = await getData$1(this).controller.processLocalSubscription(config, myId); + return unsubscribe; + } + async onWorkspaceClosed(callback) { + checkThrowCallback(callback); + const myId = getData$1(this).summary.id; + const wrappedCallback = (payload) => { + callback({ frameId: payload.frameSummary.id, workspaceId: payload.workspaceSummary.id, frameBounds: payload.frameBounds }); + }; + const config = { + callback: wrappedCallback, + action: "closed", + eventType: "workspace", + scope: "frame" + }; + const unsubscribe = await getData$1(this).controller.processLocalSubscription(config, myId); + return unsubscribe; + } + async onWindowAdded(callback) { + checkThrowCallback(callback); + const myId = getData$1(this).summary.id; + const wrappedCallback = async (payload) => { + const foundParent = await getData$1(this).controller.getParent((parent) => parent.id === payload.windowSummary.parentId); + const foundWindow = foundParent.children.find((child) => child.type === "window" && child.positionIndex === payload.windowSummary.config.positionIndex); + callback(foundWindow); + }; + const config = { + callback: wrappedCallback, + action: "added", + eventType: "window", + scope: "frame" + }; + const unsubscribe = await getData$1(this).controller.processLocalSubscription(config, myId); + return unsubscribe; + } + async onWindowRemoved(callback) { + checkThrowCallback(callback); + const myId = getData$1(this).summary.id; + const wrappedCallback = (payload) => { + const { windowId, workspaceId, frameId } = payload.windowSummary.config; + callback({ windowId, workspaceId, frameId }); + }; + const config = { + callback: wrappedCallback, + action: "removed", + eventType: "window", + scope: "frame" + }; + const unsubscribe = await getData$1(this).controller.processLocalSubscription(config, myId); + return unsubscribe; + } + async onWindowLoaded(callback) { + checkThrowCallback(callback); + const myId = getData$1(this).summary.id; + const wrappedCallback = async (payload) => { + const foundParent = await getData$1(this).controller.getParent((parent) => { + return parent.id === payload.windowSummary.parentId; + }); + const foundWindow = foundParent.children.find((child) => child.type === "window" && child.positionIndex === payload.windowSummary.config.positionIndex); + callback(foundWindow); + }; + const config = { + callback: wrappedCallback, + action: "loaded", + eventType: "window", + scope: "frame" + }; + const unsubscribe = await getData$1(this).controller.processLocalSubscription(config, myId); + return unsubscribe; + } + async onInitializationRequested(callback) { + checkThrowCallback(callback); + if (!this.isInitialized) { + callback(getData$1(this).summary.initializationContext); + } + return () => { }; + } + async onFocusChanged(callback) { + checkThrowCallback(callback); + const myData = getData$1(this); + const { id } = myData.summary; + const wrappedCallback = (args) => { + callback({ isFocused: args.frameSummary.isFocused }); + }; + const config = { + callback: wrappedCallback, + action: "focus", + eventType: "frame", + scope: "frame" + }; + const unsubscribe = await myData.controller.processLocalSubscription(config, id); + return unsubscribe; + } + } + + class PrivateDataManager { + parentsData = new WeakMap(); + workspacesData = new WeakMap(); + windowsData = new WeakMap(); + framesData = new WeakMap(); + deleteData(model) { + if (model instanceof Window) { + this.windowsData.delete(model); + } + if (model instanceof Workspace) { + this.workspacesData.delete(model); + } + if (model instanceof Row || model instanceof Column || model instanceof Group) { + this.parentsData.delete(model); + } + if (model instanceof Frame) { + this.framesData.delete(model); + } + } + setWindowData(model, data) { + this.windowsData.set(model, data); + } + setWorkspaceData(model, data) { + this.workspacesData.set(model, data); + } + setParentData(model, data) { + this.parentsData.set(model, data); + } + setFrameData(model, data) { + this.framesData.set(model, data); + } + getWindowData(model) { + return this.windowsData.get(model); + } + getWorkspaceData(model) { + return this.workspacesData.get(model); + } + getParentData(model) { + return this.parentsData.get(model); + } + getFrameData(model) { + return this.framesData.get(model); + } + remapChild(model, newData) { + if (model instanceof Window) { + const data = this.windowsData.get(model); + data.parent = newData.parent || data.parent; + data.config = newData.config || data.config; + } + if (model instanceof Row || model instanceof Column || model instanceof Group) { + const data = this.parentsData.get(model); + data.parent = newData.parent || data.parent; + data.config = newData.config || data.config; + data.children = newData.children || data.children; + } + } + remapFrame(model, newData) { + const data = this.framesData.get(model); + data.summary = newData; + } + remapWorkspace(model, newData) { + const data = this.workspacesData.get(model); + data.frame = newData.frame || data.frame; + data.config = newData.config || data.config; + data.children = newData.children || data.children; + } + } + + const data = new WeakMap(); + const getData = (base, model) => { + const manager = data.get(base).manager; + if (model instanceof Workspace) { + return manager.getWorkspaceData(model); + } + return data.get(base).manager.getParentData(model); + }; + class Base { + frameId; + workspaceId; + positionIndex; + constructor(dataManager) { + data.set(this, { manager: dataManager }); + } + getId(model) { + return getData(this, model).id; + } + getPositionIndex(model) { + return getData(this, model).config.positionIndex; + } + getWorkspaceId(model) { + const privateData = getData(this, model); + return privateData.config.workspaceId || privateData.workspace.id; + } + getFrameId(model) { + return getData(this, model).frame.id; + } + getAllChildren(model, predicate) { + checkThrowCallback(predicate, true); + const children = getData(this, model).children; + if (typeof predicate === "undefined") { + return children; + } + return children.filter(predicate); + } + getMyParent(model) { + if (model instanceof Workspace) { + return model; + } + return getData(this, model).parent; + } + getMyFrame(model) { + return getData(this, model).frame; + } + getMyWorkspace(model) { + if (model instanceof Workspace) { + return model; + } + return getData(this, model).workspace; + } + async addWindow(model, definition, parentType) { + if (!definition.appName && !definition.windowId) { + throw new Error("The window definition should contain either an appName or a windowId"); + } + const validatedDefinition = swimlaneWindowDefinitionDecoder.runWithException(definition); + const controller = getData(this, model).controller; + const operationResult = await controller.add("window", getData(this, model).id, parentType, validatedDefinition); + if (model instanceof Workspace) { + await model.refreshReference(); + return model.getWindow(w => w.elementId === operationResult.itemId); + } + const myWorkspace = this.getMyWorkspace(model); + await myWorkspace.refreshReference(); + return myWorkspace.getWindow(w => w.elementId === operationResult.itemId); + } + async addParent(model, typeToAdd, parentType, definition) { + const parentDefinition = this.transformDefinition(typeToAdd, definition); + const controller = getData(this, model).controller; + const newParentId = (await controller.add("container", getData(this, model).id, parentType, parentDefinition)).itemId; + if (model instanceof Workspace) { + await model.refreshReference(); + return model.getBox((parent) => parent.id === newParentId); + } + const myWorkspace = this.getMyWorkspace(model); + await myWorkspace.refreshReference(); + return myWorkspace.getBox((parent) => parent.id === newParentId); + } + async removeChild(model, predicate) { + checkThrowCallback(predicate); + const child = this.getAllChildren(model).find(predicate); + if (!child) { + return; + } + await child.close(); + if (model instanceof Workspace) { + await model.refreshReference(); + return; + } + await this.getMyWorkspace(model).refreshReference(); + } + async maximize(model) { + const { controller, id } = getData(this, model); + await controller.maximizeItem(id); + await this.getMyWorkspace(model.parent).refreshReference(); + } + async restore(model) { + const { controller, id } = getData(this, model); + await controller.restoreItem(id); + await this.getMyWorkspace(model.parent).refreshReference(); + } + async close(model) { + const modelData = getData(this, model); + const controller = getData(this, model).controller; + await controller.closeItem(modelData.id); + await this.getMyWorkspace(modelData.parent).refreshReference(); + } + async lockContainer(model, config) { + const modelData = getData(this, model); + const controller = getData(this, model).controller; + await controller.lockContainer(modelData.id, model.type, config); + await this.getMyWorkspace(modelData.parent).refreshReference(); + } + getAllowDrop(model) { + return getData(this, model).config.allowDrop; + } + getAllowDropLeft(model) { + const privateData = getData(this, model); + if (privateData.type !== "group") { + throw new Error(`Property allowDropLeft is available only for groups and not on ${model.type} ${model.id}`); + } + return privateData.config.allowDropLeft; + } + getAllowDropRight(model) { + const privateData = getData(this, model); + if (privateData.type !== "group") { + throw new Error(`Property allowDropRight is available only for groups and not on ${model.type} ${model.id}`); + } + return privateData.config.allowDropRight; + } + getAllowDropTop(model) { + const privateData = getData(this, model); + if (privateData.type !== "group") { + throw new Error(`Property allowDropTop is available only for groups and not on ${model.type} ${model.id}`); + } + return privateData.config.allowDropTop; + } + getAllowDropBottom(model) { + const privateData = getData(this, model); + if (privateData.type !== "group") { + throw new Error(`Property allowDropBottom is available only for groups and not on ${model.type} ${model.id}`); + } + return privateData.config.allowDropBottom; + } + getAllowDropHeader(model) { + const privateData = getData(this, model); + if (privateData.type !== "group") { + throw new Error(`Property allowDropHeader is available only for groups and not on ${model.type} ${model.id}`); + } + return privateData.config.allowDropHeader; + } + getAllowSplitters(model) { + const privateData = getData(this, model); + if (privateData.type === "group") { + throw new Error(`Cannot get allow splitters from private data ${privateData.type}`); + } + return privateData.config.allowSplitters; + } + getAllowExtract(model) { + const privateData = getData(this, model); + if (privateData.type !== "group") { + throw new Error(`Cannot get allow extract from private data ${privateData.type} with config ${privateData.type !== "workspace" ? privateData.config.type : ""}`); + } + return privateData.config.allowExtract; + } + getAllowReorder(model) { + const privateData = getData(this, model); + if (privateData.type !== "group") { + throw new Error(`Cannot get allow extract from private data ${privateData.type} with config ${privateData.type !== "workspace" ? privateData.config.type : ""}`); + } + return privateData.config.allowReorder; + } + getShowMaximizeButton(model) { + const privateData = getData(this, model); + if (privateData.type !== "group") { + throw new Error(`Cannot get show maximize button from private data${privateData.type} with config ${privateData.type !== "workspace" ? privateData.config.type : ""}`); + } + return privateData.config.showMaximizeButton; + } + getShowEjectButton(model) { + const privateData = getData(this, model); + if (privateData.type !== "group") { + throw new Error(`Cannot get show eject button from private data${privateData.type} with config ${privateData.type !== "workspace" ? privateData.config.type : ""}`); + } + return privateData.config.showEjectButton; + } + getShowAddWindowButton(model) { + const privateData = getData(this, model); + if (privateData.type !== "group") { + throw new Error(`Cannot get add window button from private data${privateData.type} with config ${privateData.type !== "workspace" ? privateData.config.type : ""}`); + } + return privateData.config.showAddWindowButton; + } + getMinWidth(model) { + const privateData = getData(this, model); + return privateData.config.minWidth; + } + getMaxWidth(model) { + const privateData = getData(this, model); + return privateData.config.maxWidth; + } + getMinHeight(model) { + const privateData = getData(this, model); + return privateData.config.minHeight; + } + getMaxHeight(model) { + const privateData = getData(this, model); + return privateData.config.maxHeight; + } + getWidthInPx(model) { + const privateData = getData(this, model); + return privateData.config.widthInPx; + } + getHeightInPx(model) { + const privateData = getData(this, model); + return privateData.config.heightInPx; + } + getIsPinned(model) { + const privateData = getData(this, model); + return privateData.config.isPinned; + } + getIsMaximized(model) { + const privateData = getData(this, model); + return privateData.config.isMaximized; + } + getMaximizationBoundary(model) { + const privateData = getData(this, model); + return privateData.config.maximizationBoundary; + } + async setHeight(model, height) { + const modelData = getData(this, model); + const { controller, id } = modelData; + await controller.resizeItem(id, { + height + }); + await this.getMyWorkspace(modelData.parent).refreshReference(); + } + async setWidth(model, width) { + const modelData = getData(this, model); + const { controller, id } = modelData; + await controller.resizeItem(id, { + width + }); + await this.getMyWorkspace(modelData.parent).refreshReference(); + } + async setSize(model, width, height) { + const modelData = getData(this, model); + const { controller, id } = modelData; + await controller.resizeItem(id, { + width, + height + }); + await this.getMyWorkspace(modelData.parent).refreshReference(); + } + async setMaximizationBoundary(model, config) { + const modelData = getData(this, model); + const { controller, id } = modelData; + await controller.setMaximizationBoundary(id, config); + await this.getMyWorkspace(modelData.parent).refreshReference(); + } + async bundleTo(model, type) { + const modelData = getData(this, model); + const { controller, id } = modelData; + await controller.bundleItemTo(type, id); + } + async processLocalSubscription(model, subscriptionConfig) { + return getData(this, model).controller.processLocalSubscription(subscriptionConfig, this.getId(model)); + } + transformDefinition(type, definition) { + let parentDefinition; + if (typeof definition === "undefined") { + parentDefinition = { type, children: [] }; + } + else if (definition instanceof ParentBuilder) { + parentDefinition = definition.serialize(); + } + else { + if (typeof definition.type === "undefined") { + definition.type = type; + } + parentDefinition = strictParentDefinitionDecoder.runWithException(definition); + parentDefinition.children = parentDefinition.children || []; + } + return parentDefinition; + } + } + + class BaseController { + ioc; + windows; + contexts; + layouts; + constructor(ioc, windows, contexts, layouts) { + this.ioc = ioc; + this.windows = windows; + this.contexts = contexts; + this.layouts = layouts; + } + get bridge() { + return this.ioc.bridge; + } + get privateDataManager() { + return this.ioc.privateDataManager; + } + checkIsWindowLoaded(windowId) { + return (!!windowId) && this.windows.list().some((win) => win.id === windowId); + } + async createWorkspace(createConfig) { + const snapshot = await this.bridge.send(OPERATIONS.createWorkspace.name, createConfig); + const frameConfig = { + summary: snapshot.frameSummary + }; + const frame = this.ioc.getModel("frame", frameConfig); + const workspaceConfig = { frame, snapshot }; + return this.ioc.getModel("workspace", workspaceConfig); + } + async createEmptyFrame(definition) { + const frameSummary = await this.bridge.send(OPERATIONS.createFrame.name, definition); + const frameConfig = { + summary: frameSummary + }; + return this.ioc.getModel("frame", frameConfig); + } + async initFrame(frameId, config) { + await this.bridge.send(OPERATIONS.initFrame.name, { frameId, ...config }); + } + async restoreWorkspace(name, options) { + const snapshot = await this.bridge.send(OPERATIONS.openWorkspace.name, { name, restoreOptions: options }); + const frameSummary = await this.bridge.send(OPERATIONS.getFrameSummary.name, { itemId: snapshot.config.frameId }); + const frameConfig = { + summary: frameSummary + }; + const frame = this.ioc.getModel("frame", frameConfig); + const workspaceConfig = { frame, snapshot }; + return this.ioc.getModel("workspace", workspaceConfig); + } + async add(type, parentId, parentType, definition) { + let operationName; + const operationArgs = { definition, parentId, parentType }; + if (type === "window") { + operationName = OPERATIONS.addWindow.name; + } + else if (type === "container") { + operationName = OPERATIONS.addContainer.name; + } + else { + throw new Error(`Unrecognized add type: ${type}`); + } + return await this.bridge.send(operationName, operationArgs); + } + async getFrame(windowId) { + const frameSummary = await this.bridge.send(OPERATIONS.getFrameSummary.name, { itemId: windowId }); + const frameConfig = { + summary: frameSummary + }; + return this.ioc.getModel("frame", frameConfig); + } + getFrames(allFrameSummaries, predicate) { + return allFrameSummaries.reduce((frames, frameSummary) => { + const frameConfig = { + summary: frameSummary + }; + const frameToCheck = this.ioc.getModel("frame", frameConfig); + if (!predicate || predicate(frameToCheck)) { + frames.push(frameToCheck); + } + return frames; + }, []); + } + getAllWorkspaceSummaries(...bridgeResults) { + const allSummaries = bridgeResults.reduce((summaries, summaryResult) => { + summaries.push(...summaryResult.summaries); + return summaries; + }, []); + return allSummaries.map((summary) => { + return Object.assign({}, { id: summary.id, width: summary.config.widthInPx, height: summary.config.heightInPx }, summary.config); + }); + } + handleOnSaved(callback) { + const wrappedCallback = (layout) => { + if (layout.type !== "Workspace") { + return; + } + callback(layout); + }; + const addedUnSub = this.layouts.onAdded(wrappedCallback); + const changedUnSub = this.layouts.onChanged(wrappedCallback); + return () => { + addedUnSub(); + changedUnSub(); + }; + } + handleOnRemoved(callback) { + const wrappedCallback = (layout) => { + if (layout.type !== "Workspace") { + return; + } + callback(layout); + }; + return this.layouts.onRemoved(wrappedCallback); + } + async importLayouts(layouts, mode) { + await this.layouts.import(layouts, mode); + } + async transformStreamPayloadToWorkspace(payload) { + const frameConfig = { + summary: payload.frameSummary + }; + const frame = this.ioc.getModel("frame", frameConfig); + const snapshot = payload.workspaceSnapshot || (await this.bridge.send(OPERATIONS.getWorkspaceSnapshot.name, { itemId: payload.workspaceSummary.id })); + const workspaceConfig = { frame, snapshot }; + const workspace = this.ioc.getModel("workspace", workspaceConfig); + return workspace; + } + async fetchWorkspace(itemId) { + const snapshot = await this.bridge.send(OPERATIONS.getWorkspaceSnapshot.name, { itemId }); + const frameConfig = { + summary: snapshot.frameSummary + }; + const frame = this.ioc.getModel("frame", frameConfig); + const workspaceConfig = { frame, snapshot }; + return this.ioc.getModel("workspace", workspaceConfig); + } + async bundleWorkspaceTo(type, workspaceId) { + await this.bridge.send(OPERATIONS.bundleWorkspace.name, { type, workspaceId }); + } + async bundleItemTo(type, itemId) { + const isSupported = await this.isOperationSupported(OPERATIONS.bundleItem.name); + if (!isSupported) { + throw new Error(`Operation ${OPERATIONS.bundleItem.name} is not supported. Ensure that you are running the latest version of all packages`); + } + await this.bridge.send(OPERATIONS.bundleItem.name, { type, itemId }); + } + getWorkspaceContext(workspaceId) { + const contextName = `___workspace___${workspaceId}`; + return this.contexts.get(contextName); + } + setWorkspaceContext(workspaceId, data) { + const contextName = `___workspace___${workspaceId}`; + return this.contexts.set(contextName, data); + } + updateWorkspaceContext(workspaceId, data) { + const contextName = `___workspace___${workspaceId}`; + return this.contexts.update(contextName, data); + } + subscribeWorkspaceContextUpdated(workspaceId, callback) { + const contextName = `___workspace___${workspaceId}`; + return this.contexts.subscribe(contextName, callback); + } + async restoreItem(itemId) { + await this.bridge.send(OPERATIONS.restoreItem.name, { itemId }); + } + async maximizeItem(itemId) { + await this.bridge.send(OPERATIONS.maximizeItem.name, { itemId }); + } + async focusItem(itemId) { + await this.bridge.send(OPERATIONS.focusItem.name, { itemId }); + } + async closeItem(itemId) { + await this.bridge.send(OPERATIONS.closeItem.name, { itemId }); + } + async resizeItem(itemId, config) { + await this.bridge.send(OPERATIONS.resizeItem.name, Object.assign({}, { itemId }, config)); + } + async setMaximizationBoundary(itemId, config) { + await this.bridge.send(OPERATIONS.setMaximizationBoundary.name, Object.assign({}, { itemId }, config)); + } + async showWorkspaceLoadingAnimation(workspaceId) { + await this.bridge.send(OPERATIONS.showLoadingAnimation.name, { itemId: workspaceId, type: "workspace" }); + } + async hideWorkspaceLoadingAnimation(workspaceId) { + await this.bridge.send(OPERATIONS.hideLoadingAnimation.name, { itemId: workspaceId, type: "workspace" }); + } + async setWindowDragMode(workspaceId, dragMode) { + await this.bridge.send(OPERATIONS.setWindowDragMode.name, { itemId: workspaceId, dragMode }); + } + async moveFrame(itemId, config) { + await this.bridge.send(OPERATIONS.moveFrame.name, Object.assign({}, { itemId }, config)); + } + getGDWindow(itemId) { + return this.windows.list().find((gdWindow) => gdWindow.id === itemId); + } + async forceLoadWindow(itemId) { + const controlResult = await this.bridge.send(OPERATIONS.forceLoadWindow.name, { itemId }); + return controlResult.windowId; + } + async ejectWindow(itemId) { + return await this.bridge.send(OPERATIONS.ejectWindow.name, { itemId }); + } + async moveWindowTo(itemId, newParentId) { + await this.bridge.send(OPERATIONS.moveWindowTo.name, { itemId, containerId: newParentId }); + } + async getSnapshot(itemId, type) { + let result; + if (type === "workspace") { + result = await this.bridge.send(OPERATIONS.getWorkspaceSnapshot.name, { itemId }); + } + else if (type === "frame") { + result = await this.bridge.send(OPERATIONS.getFrameSnapshot.name, { itemId }); + } + return result; + } + async setItemTitle(itemId, title) { + await this.bridge.send(OPERATIONS.setItemTitle.name, { itemId, title }); + } + refreshChildren(config) { + const { parent, children, existingChildren, workspace } = config; + if (parent instanceof Window || parent.type === "window") { + return; + } + const newChildren = children.map((newChildSnapshot) => { + let childToAdd = existingChildren.find((child) => { + return child.type === "window" ? child.elementId === newChildSnapshot.id : child.id === newChildSnapshot.id; + }); + if (childToAdd) { + this.privateDataManager.remapChild(childToAdd, { + parent: parent, + children: [], + config: newChildSnapshot.config + }); + } + else { + let createConfig; + if (newChildSnapshot.type === "window") { + createConfig = { + id: newChildSnapshot.id, + parent: parent, + frame: workspace.frame, + workspace, + config: newChildSnapshot.config, + }; + } + else { + createConfig = { + id: newChildSnapshot.id, + parent: parent, + frame: workspace.frame, + workspace, + config: newChildSnapshot.config, + children: [] + }; + } + childToAdd = this.ioc.getModel(newChildSnapshot.type, createConfig); + } + if (newChildSnapshot.type !== "window") { + this.refreshChildren({ + workspace, existingChildren, + children: newChildSnapshot.children, + parent: childToAdd + }); + } + return childToAdd; + }); + if (parent instanceof Workspace) { + return newChildren; + } + else { + this.privateDataManager.remapChild(parent, { children: newChildren }); + return newChildren; + } + } + iterateFindChild(children, predicate) { + let foundChild = children.find((child) => predicate(child)); + if (foundChild) { + return foundChild; + } + children.some((child) => { + if (child instanceof Window) { + return false; + } + foundChild = this.iterateFindChild(child.children, predicate); + if (foundChild) { + return true; + } + }); + return foundChild; + } + iterateFilterChildren(children, predicate) { + const foundChildren = children.filter((child) => predicate(child)); + const grandChildren = children.reduce((innerFound, child) => { + if (child instanceof Window) { + return innerFound; + } + innerFound.push(...this.iterateFilterChildren(child.children, predicate)); + return innerFound; + }, []); + foundChildren.push(...grandChildren); + return foundChildren; + } + notifyWindowAdded(windowId) { + return new Promise((resolve) => { + const alreadyPresent = this.windows.list().some((win) => win.id === windowId); + if (alreadyPresent) { + return resolve(); + } + const unsubscribe = this.windows.onWindowAdded((win) => { + if (win.id !== windowId) { + return; + } + if (unsubscribe) { + unsubscribe(); + } + resolve(); + }); + }); + } + async hibernateWorkspace(workspaceId) { + await this.bridge.send(OPERATIONS.hibernateWorkspace.name, { workspaceId }); + } + async resumeWorkspace(workspaceId) { + await this.bridge.send(OPERATIONS.resumeWorkspace.name, { workspaceId }); + } + async lockWorkspace(workspaceId, config) { + await this.bridge.send(OPERATIONS.lockWorkspace.name, { workspaceId, config }); + } + async lockWindow(windowPlacementId, config) { + await this.bridge.send(OPERATIONS.lockWindow.name, { windowPlacementId, config }); + } + async lockContainer(itemId, type, config) { + await this.bridge.send(OPERATIONS.lockContainer.name, { itemId, type, config }); + } + async pinWorkspace(workspaceId, icon) { + await this.bridge.send(OPERATIONS.pinWorkspace.name, { workspaceId, icon }); + } + async unpinWorkspace(workspaceId) { + await this.bridge.send(OPERATIONS.unpinWorkspace.name, { workspaceId }); + } + async getWorkspaceIcon(workspaceId) { + const result = await this.bridge.send(OPERATIONS.getWorkspaceIcon.name, { workspaceId }); + return result.icon; + } + setWorkspaceIcon(workspaceId, icon) { + return this.bridge.send(OPERATIONS.setWorkspaceIcon.name, { workspaceId, icon }); + } + async getPlatformFrameId() { + try { + const result = await this.bridge.send(OPERATIONS.getPlatformFrameId.name, {}); + return result; + } + catch (error) { + return {}; + } + } + async setLoadingStrategy(workspaceId, strategy) { + await this.isOperationSupported(OPERATIONS.setLoadingStrategy.name); + return this.bridge.send(OPERATIONS.setLoadingStrategy.name, { itemId: workspaceId, strategy }); + } + async isOperationSupported(operation) { + if (isDesktop()) { + return { isSupported: true }; + } + return await this.bridge.send(OPERATIONS.operationCheck.name, { operation }); + } + } + + class MainController { + bridge; + base; + shortcutsController; + constructor(bridge, base, shortcutsController) { + this.bridge = bridge; + this.base = base; + this.shortcutsController = shortcutsController; + } + checkIsWindowLoaded(windowId) { + return this.base.checkIsWindowLoaded(windowId); + } + async checkIsInSwimlane(windowId) { + const controlResult = await this.bridge.send(OPERATIONS.isWindowInWorkspace.name, { itemId: windowId }); + return controlResult.inWorkspace; + } + async createWorkspace(definition, saveConfig) { + const createConfig = Object.assign({}, definition, { saveConfig }); + return await this.base.createWorkspace(createConfig); + } + async createEmptyFrame(definition) { + return await this.base.createEmptyFrame(definition); + } + async initFrame(frameId, config) { + return this.base.initFrame(frameId, config); + } + async restoreWorkspace(name, options) { + const allLayouts = await this.getLayoutSummaries(); + const layoutExists = allLayouts.some((summary) => summary.name === name); + if (!layoutExists) { + throw new Error(`This layout: ${name} cannot be restored, because it doesn't exist.`); + } + if (options?.frameId) { + const allFrameSummaries = await this.bridge.send(OPERATIONS.getAllFramesSummaries.name); + const foundMatchingFrame = allFrameSummaries.summaries.some((summary) => summary.id === options.frameId); + if (!foundMatchingFrame) { + throw new Error(`Cannot reuse the frame with id: ${options.frameId}, because there is no frame with that ID found`); + } + } + return await this.base.restoreWorkspace(name, options); + } + async add(type, parentId, parentType, definition) { + return await this.base.add(type, parentId, parentType, definition); + } + processLocalSubscription(config, levelId) { + return isDesktop() ? + this.handleEnterpriseLocalSubscription(config, levelId) : + this.handleCoreLocalSubscription(config, levelId); + } + processGlobalSubscription(callback, eventType, action) { + return isDesktop() ? + this.handleEnterpriseGlobalSubscription(callback, eventType, action) : + this.handleCoreGlobalSubscription(callback, eventType, action); + } + async getFrame(selector) { + if (selector.windowId) { + return await this.base.getFrame(selector.windowId); + } + if (selector.predicate) { + return (await this.getFrames(selector.predicate))[0]; + } + throw new Error(`The provided selector is not valid: ${JSON.stringify(selector)}`); + } + async getFrames(predicate) { + const allFrameSummaries = await this.bridge.send(OPERATIONS.getAllFramesSummaries.name); + return this.base.getFrames(allFrameSummaries.summaries, predicate); + } + getWorkspaceById(workspaceId) { + return this.base.fetchWorkspace(workspaceId); + } + async getWorkspaceByWindowId(itemId) { + if (!isDesktop()) { + return (await this.getWorkspaces((wsp) => !!wsp.getWindow((w) => w.id === itemId)))[0]; + } + return this.base.fetchWorkspace(itemId); + } + transformStreamPayloadToWorkspace(payload) { + return this.base.transformStreamPayloadToWorkspace(payload); + } + async getWorkspace(predicate) { + let foundWorkspace; + await this.iterateWorkspaces((wsp, end) => { + if (predicate(wsp)) { + foundWorkspace = wsp; + end(); + } + }); + return foundWorkspace; + } + async getWorkspaces(predicate) { + const matchingWorkspaces = []; + await this.iterateWorkspaces((wsp) => { + if (!predicate || predicate(wsp)) { + matchingWorkspaces.push(wsp); + } + }); + return matchingWorkspaces; + } + async getWorkspacesByFrameId(frameId) { + const workspaceSummaries = await this.getAllWorkspaceSummaries(); + const summariesForFrame = workspaceSummaries.filter((s) => s.frameId === frameId); + const workspacesForFrame = await Promise.all(summariesForFrame.map((summary) => { + return this.base.fetchWorkspace(summary.id); + })); + return workspacesForFrame; + } + async getAllWorkspaceSummaries() { + const allSummariesResult = await this.bridge.send(OPERATIONS.getAllWorkspacesSummaries.name, {}); + return this.base.getAllWorkspaceSummaries(allSummariesResult); + } + async getWindow(predicate) { + let resultWindow; + await this.iterateWorkspaces((wsp, end) => { + const foundWindow = wsp.getWindow(predicate); + if (foundWindow) { + resultWindow = foundWindow; + end(); + } + }); + return resultWindow; + } + async getParent(predicate) { + let resultParent; + await this.iterateWorkspaces((wsp, end) => { + const foundParent = wsp.getBox(predicate); + if (foundParent) { + resultParent = foundParent; + end(); + } + }); + return resultParent; + } + async getLayoutSummaries() { + const allLayouts = await this.bridge.send(OPERATIONS.getAllLayoutsSummaries.name); + return allLayouts.summaries; + } + async deleteLayout(name) { + await this.bridge.send(OPERATIONS.deleteLayout.name, { name }); + } + async exportLayout(predicate) { + const allLayoutsResult = await this.bridge.send(OPERATIONS.exportAllLayouts.name); + return allLayoutsResult.layouts.reduce((matchingLayouts, layout) => { + if (!predicate || predicate(layout)) { + matchingLayouts.push(layout); + } + return matchingLayouts; + }, []); + } + async saveLayout(config) { + return await this.bridge.send(OPERATIONS.saveLayout.name, config); + } + async importLayouts(layouts, mode) { + if (isDesktop()) { + try { + await this.bridge.send(OPERATIONS.importLayouts.name, { layouts, mode }); + } + catch (error) { + await Promise.all(layouts.map((layout) => this.bridge.send(OPERATIONS.importLayout.name, { layout, mode }))); + } + return; + } + await this.base.importLayouts(layouts, mode); + } + handleOnSaved(callback) { + return this.base.handleOnSaved(callback); + } + handleOnRemoved(callback) { + return this.base.handleOnRemoved(callback); + } + async bundleWorkspaceTo(type, workspaceId) { + return await this.base.bundleWorkspaceTo(type, workspaceId); + } + async bundleItemTo(type, id) { + return await this.base.bundleItemTo(type, id); + } + getWorkspaceContext(workspaceId) { + return this.base.getWorkspaceContext(workspaceId); + } + setWorkspaceContext(workspaceId, data) { + return this.base.setWorkspaceContext(workspaceId, data); + } + updateWorkspaceContext(workspaceId, data) { + return this.base.updateWorkspaceContext(workspaceId, data); + } + subscribeWorkspaceContextUpdated(workspaceId, callback) { + return this.base.subscribeWorkspaceContextUpdated(workspaceId, callback); + } + async restoreItem(itemId) { + return await this.base.restoreItem(itemId); + } + async maximizeItem(itemId) { + return await this.base.maximizeItem(itemId); + } + async focusItem(itemId) { + return await this.base.focusItem(itemId); + } + async changeFrameState(frameId, state) { + await this.bridge.send(OPERATIONS.changeFrameState.name, { frameId, requestedState: state }); + } + async getFrameBounds(frameId) { + const frameResult = await this.bridge.send(OPERATIONS.getFrameBounds.name, { itemId: frameId }); + return frameResult.bounds; + } + async getFrameState(frameId) { + const frameResult = await this.bridge.send(OPERATIONS.getFrameState.name, { itemId: frameId }); + return frameResult.state; + } + async closeItem(itemId) { + return await this.base.closeItem(itemId); + } + async resizeItem(itemId, config) { + return await this.base.resizeItem(itemId, config); + } + async setMaximizationBoundary(itemId, config) { + return await this.base.setMaximizationBoundary(itemId, config); + } + async showWorkspaceLoadingAnimation(workspaceId) { + return await this.base.showWorkspaceLoadingAnimation(workspaceId); + } + async hideWorkspaceLoadingAnimation(workspaceId) { + return await this.base.hideWorkspaceLoadingAnimation(workspaceId); + } + async setWindowDragMode(workspaceId, dragMode) { + return await this.base.setWindowDragMode(workspaceId, dragMode); + } + async moveFrame(itemId, config) { + return await this.base.moveFrame(itemId, config); + } + getGDWindow(itemId) { + return this.base.getGDWindow(itemId); + } + async forceLoadWindow(itemId) { + const windowId = await this.base.forceLoadWindow(itemId); + await this.base.notifyWindowAdded(windowId); + return windowId; + } + async ejectWindow(itemId) { + const windowId = (await this.base.ejectWindow(itemId)).windowId; + await this.base.notifyWindowAdded(windowId); + return windowId; + } + async moveWindowTo(itemId, newParentId) { + return await this.base.moveWindowTo(itemId, newParentId); + } + async getSnapshot(itemId, type) { + return await this.base.getSnapshot(itemId, type); + } + async setItemTitle(itemId, title) { + return await this.base.setItemTitle(itemId, title); + } + flatChildren(children) { + return children.reduce((soFar, child) => { + soFar.push(child); + if (child.type !== "window") { + soFar.push(...this.flatChildren(child.children)); + } + return soFar; + }, []); + } + refreshChildren(config) { + return this.base.refreshChildren(config); + } + iterateFindChild(children, predicate) { + return this.base.iterateFindChild(children, predicate); + } + iterateFilterChildren(children, predicate) { + return this.base.iterateFilterChildren(children, predicate); + } + hibernateWorkspace(workspaceId) { + return this.base.hibernateWorkspace(workspaceId); + } + resumeWorkspace(workspaceId) { + return this.base.resumeWorkspace(workspaceId); + } + lockWorkspace(workspaceId, config) { + return this.base.lockWorkspace(workspaceId, config); + } + lockWindow(windowPlacementId, config) { + return this.base.lockWindow(windowPlacementId, config); + } + lockContainer(itemId, type, config) { + return this.base.lockContainer(itemId, type, config); + } + pinWorkspace(workspaceId, icon) { + return this.base.pinWorkspace(workspaceId, icon); + } + unpinWorkspace(workspaceId) { + return this.base.unpinWorkspace(workspaceId); + } + getWorkspaceIcon(workspaceId) { + return this.base.getWorkspaceIcon(workspaceId); + } + setWorkspaceIcon(workspaceId, icon) { + return this.base.setWorkspaceIcon(workspaceId, icon); + } + async getFrameConstraints(frameId) { + const frameSnapshot = await this.getSnapshot(frameId, "frame"); + return { + minWidth: frameSnapshot.config.minWidth, + maxWidth: frameSnapshot.config.maxWidth, + minHeight: frameSnapshot.config.minHeight, + maxHeight: frameSnapshot.config.maxHeight, + }; + } + registerShortcut(shortcut, frameId, callback) { + return this.shortcutsController.registerShortcut(shortcut, frameId, callback); + } + getPlatformFrameId() { + return this.base.getPlatformFrameId(); + } + setLoadingStrategy(workspaceId, strategy) { + return this.base.setLoadingStrategy(workspaceId, strategy); + } + async handleCoreLocalSubscription(config, levelId) { + await this.bridge.createCoreEventSubscription(); + config.scopeId = config.scopeId || levelId; + if (config.eventType === "window" && config.action === "loaded") { + const originalCB = config.callback; + const wrappedCB = async (callbackData) => { + await this.base.notifyWindowAdded(callbackData.windowSummary.config.windowId); + originalCB(callbackData); + }; + config.callback = wrappedCB; + } + return this.bridge.handleCoreSubscription(config); + } + handleEnterpriseLocalSubscription(config, levelId) { + config.scopeId = config.scopeId || levelId; + if (config.eventType === "window" && config.action === "loaded") { + const originalCB = config.callback; + const wrappedCB = async (callbackData) => { + await this.base.notifyWindowAdded(callbackData.windowSummary.config.windowId); + originalCB(callbackData); + }; + config.callback = wrappedCB; + } + return this.bridge.subscribe(config); + } + async handleCoreGlobalSubscription(callback, eventType, action) { + await this.bridge.createCoreEventSubscription(); + const config = { + eventType, callback, action, + scope: "global", + }; + if (eventType === "window" && action === "loaded") { + const wrappedCB = async (callbackData) => { + await this.base.notifyWindowAdded(callbackData.windowSummary.config.windowId); + callback(callbackData); + }; + config.callback = wrappedCB; + } + return this.bridge.handleCoreSubscription(config); + } + handleEnterpriseGlobalSubscription(callback, eventType, action) { + const config = { + eventType, callback, action, + scope: "global", + }; + if (eventType === "window" && action === "loaded") { + const wrappedCB = async (callbackData) => { + await this.base.notifyWindowAdded(callbackData.windowSummary.config.windowId); + callback(callbackData); + }; + config.callback = wrappedCB; + } + return this.bridge.subscribe(config); + } + async iterateWorkspaces(callback) { + let ended = false; + const end = () => { ended = true; }; + const workspaceSummaries = await this.getAllWorkspaceSummaries(); + for (const summary of workspaceSummaries) { + if (ended) { + return; + } + const wsp = await this.base.fetchWorkspace(summary.id); + callback(wsp, end); + } + } + } + + class ShortcutsController { + bridge; + _shortcuts = CallbackFactory(); + constructor(bridge) { + this.bridge = bridge; + this.bridge.onOperation((payload, caller) => { + if (payload.operation === CLIENT_OPERATIONS.shortcutClicked.name) { + const data = payload.data; + this._shortcuts.execute(`${data.frameId}-${data.shortcut}`); + } + }); + } + async registerShortcut(shortcut, frameId, callback) { + await this.bridge.send(OPERATIONS.registerShortcut.name, { shortcut, frameId }); + const un = this._shortcuts.add(`${frameId}-${shortcut}`, callback); + return () => { + un(); + this.bridge.send(OPERATIONS.unregisterShortcut.name, { shortcut, frameId }); + }; + } + } + + class IoC { + agm; + windows; + layouts; + contexts; + _controllerInstance; + _bridgeInstance; + _transportInstance; + _privateDataManagerInstance; + _parentBaseInstance; + _baseController; + _shortcutsController; + constructor(agm, windows, layouts, contexts) { + this.agm = agm; + this.windows = windows; + this.layouts = layouts; + this.contexts = contexts; + } + get baseController() { + if (!this._baseController) { + this._baseController = new BaseController(this, this.windows, this.contexts, this.layouts); + } + return this._baseController; + } + get controller() { + if (!this._controllerInstance) { + this._controllerInstance = new MainController(this.bridge, this.baseController, this.shortcutsController); + } + return this._controllerInstance; + } + get shortcutsController() { + if (!this._shortcutsController) { + this._shortcutsController = new ShortcutsController(this.bridge); + } + return this._shortcutsController; + } + get bridge() { + if (!this._bridgeInstance) { + this._bridgeInstance = new Bridge(this.transport, CallbackFactory()); + } + return this._bridgeInstance; + } + get transport() { + if (!this._transportInstance) { + this._transportInstance = new InteropTransport(this.agm, CallbackFactory()); + } + return this._transportInstance; + } + get privateDataManager() { + if (!this._privateDataManagerInstance) { + this._privateDataManagerInstance = new PrivateDataManager(); + } + return this._privateDataManagerInstance; + } + get parentBase() { + if (!this._parentBaseInstance) { + this._parentBaseInstance = new Base(this.privateDataManager); + } + return this._parentBaseInstance; + } + async initiate(actualWindowId) { + await this.transport.initiate(actualWindowId); + } + getModel(type, createConfig) { + switch (type) { + case "frame": { + const newFrame = new Frame(this.privateDataManager); + const { summary } = createConfig; + const frameData = { summary, controller: this.controller }; + this.privateDataManager.setFrameData(newFrame, frameData); + return newFrame; + } + case "window": { + const { id, parent, frame, workspace, config } = createConfig; + const windowPrivateData = { + type: "window", + controller: this.controller, + config, id, parent, frame, workspace + }; + const newWindow = new Window(this.privateDataManager); + this.privateDataManager.setWindowData(newWindow, windowPrivateData); + return newWindow; + } + case "row": + case "column": + case "group": { + const { id, children, parent, frame, workspace, config } = createConfig; + const newParent = type === "column" ? new Column(this.parentBase) : + type === "row" ? new Row(this.parentBase) : new Group(this.parentBase); + const builtChildren = this.buildChildren(children, frame, workspace, newParent); + const parentPrivateData = { + id, parent, frame, workspace, + config, + type, + controller: this.controller, + children: builtChildren, + }; + this.privateDataManager.setParentData(newParent, parentPrivateData); + return newParent; + } + case "workspace": { + const { snapshot, frame } = createConfig; + const newWorkspace = new Workspace(this.privateDataManager); + const children = this.buildChildren(snapshot.children, frame, newWorkspace, newWorkspace); + const workspacePrivateData = { + id: snapshot.id, + type: "workspace", + config: snapshot.config, + base: this.parentBase, + controller: this.controller, + children, frame, ioc: this + }; + this.privateDataManager.setWorkspaceData(newWorkspace, workspacePrivateData); + return newWorkspace; + } + default: throw new Error(`Unrecognized type: ${type}`); + } + } + getBuilder(config) { + config.definition = config.definition || {}; + if (!Array.isArray(config.definition.children)) { + config.definition.children = []; + } + const baseBuilder = new BaseBuilder(this.getBuilder.bind(this)); + switch (config.type) { + case "workspace": { + return new WorkspaceBuilder(config.definition, baseBuilder, this.controller); + } + case "row": + case "column": + case "group": { + config.definition.type = config.type; + return new ParentBuilder(config.definition, baseBuilder); + } + default: throw new Error(`Unexpected Builder creation error, provided config: ${JSON.stringify(config)}`); + } + } + buildChildren(children, frame, workspace, parent) { + return children.map((child) => { + switch (child.type) { + case "window": return this.getModel("window", { + id: child.id, + config: child.config, + frame, workspace, parent + }); + case "column": return this.getModel(child.type, { + id: child.id, + config: child.config, + children: child.children, + frame, workspace, parent + }); + case "row": return this.getModel(child.type, { + id: child.id, + config: child.config, + children: child.children, + frame, workspace, parent + }); + case "group": return this.getModel(child.type, { + id: child.id, + config: child.config, + children: child.children, + frame, workspace, parent + }); + default: throw new Error(`Unsupported child type: ${child.type}`); + } + }); + } + } + + var version = "3.5.6"; + + const composeAPI = (glue, ioc) => { + const controller = ioc.controller; + const inWorkspace = () => { + const myId = glue.windows.my().id; + if (!myId) { + throw new Error("Cannot get my frame, because my id is undefined."); + } + return controller.checkIsInSwimlane(myId); + }; + const getBuilder = (config) => { + const validatedConfig = builderConfigDecoder.runWithException(config); + return ioc.getBuilder(validatedConfig); + }; + const getMyFrame = async () => { + const windowId = glue.windows.my().id; + if (!windowId) { + throw new Error("Cannot get my frame, because my id is undefined."); + } + const isInSwimlane = await controller.checkIsInSwimlane(windowId); + if (!isInSwimlane) { + throw new Error("Cannot fetch your frame, because this window is not in a workspace"); + } + return controller.getFrame({ windowId }); + }; + const getFrame = async (predicate) => { + checkThrowCallback(predicate); + return controller.getFrame({ predicate }); + }; + const getAllFrames = async (predicate) => { + checkThrowCallback(predicate, true); + return controller.getFrames(predicate); + }; + const getAllWorkspacesSummaries = () => { + return controller.getAllWorkspaceSummaries(); + }; + const getMyWorkspace = async () => { + const myId = glue.windows.my().id; + if (!myId) { + throw new Error("Cannot get my workspace, because my id is undefined."); + } + const isInSwimlane = await controller.checkIsInSwimlane(myId); + if (!isInSwimlane) { + throw new Error("Cannot fetch your workspace, because this window is not in a workspace"); + } + return await controller.getWorkspaceByWindowId(myId); + }; + const getWorkspace = async (predicate) => { + checkThrowCallback(predicate); + return (await controller.getWorkspaces(predicate))[0]; + }; + const getWorkspaceById = async (workspaceId) => { + nonEmptyStringDecoder.runWithException(workspaceId); + return controller.getWorkspaceById(workspaceId); + }; + const getAllWorkspaces = (predicate) => { + checkThrowCallback(predicate, true); + return controller.getWorkspaces(predicate); + }; + const getWindow = async (predicate) => { + checkThrowCallback(predicate); + return controller.getWindow(predicate); + }; + const getParent = async (predicate) => { + checkThrowCallback(predicate); + return controller.getParent(predicate); + }; + const restoreWorkspace = async (name, options) => { + nonEmptyStringDecoder.runWithException(name); + const validatedOptions = restoreWorkspaceConfigDecoder.runWithException(options); + return controller.restoreWorkspace(name, validatedOptions); + }; + const createWorkspace = async (definition, saveConfig) => { + const validatedDefinition = workspaceDefinitionDecoder.runWithException(definition); + const validatedConfig = workspaceBuilderCreateConfigDecoder.runWithException(saveConfig); + return controller.createWorkspace(validatedDefinition, validatedConfig); + }; + const createEmptyFrame = async (definition) => { + const validatedDefinition = emptyFrameDefinitionDecoder.runWithException(definition); + return controller.createEmptyFrame(validatedDefinition ?? {}); + }; + const layouts = { + getSummaries: () => { + return controller.getLayoutSummaries(); + }, + delete: async (name) => { + nonEmptyStringDecoder.runWithException(name); + return controller.deleteLayout(name); + }, + export: async (predicate) => { + checkThrowCallback(predicate, true); + return controller.exportLayout(predicate); + }, + import: async (layouts, mode = "replace") => { + if (!Array.isArray(layouts)) { + throw new Error(`The provided layouts argument is not an array: ${JSON.stringify(layouts)}`); + } + layouts.forEach((layout) => workspaceLayoutDecoder.runWithException(layout)); + return controller.importLayouts(layouts, mode); + }, + save: async (config) => { + const verifiedConfig = workspaceLayoutSaveConfigDecoder.runWithException(config); + return controller.saveLayout(verifiedConfig); + }, + onSaved: async (callback) => { + checkThrowCallback(callback); + return controller.handleOnSaved(callback); + }, + onRemoved: async (callback) => { + checkThrowCallback(callback); + return controller.handleOnRemoved(callback); + } + }; + const onFrameOpened = async (callback) => { + checkThrowCallback(callback); + const wrappedCallback = (payload) => { + const frameConfig = { + summary: payload.frameSummary + }; + const frame = ioc.getModel("frame", frameConfig); + callback(frame); + }; + const unsubscribe = await controller.processGlobalSubscription(wrappedCallback, "frame", "opened"); + return unsubscribe; + }; + const onFrameClosed = async (callback) => { + checkThrowCallback(callback); + const wrappedCallback = (payload) => { + callback({ frameId: payload.frameSummary.id, frameBounds: payload.frameBounds }); + }; + const unsubscribe = await controller.processGlobalSubscription(wrappedCallback, "frame", "closed"); + return unsubscribe; + }; + const onWorkspaceOpened = async (callback) => { + checkThrowCallback(callback); + const wrappedCallback = async (payload) => { + const workspace = await controller.transformStreamPayloadToWorkspace(payload); + callback(workspace); + }; + const unsubscribe = await controller.processGlobalSubscription(wrappedCallback, "workspace", "opened"); + return unsubscribe; + }; + const onWorkspaceClosed = async (callback) => { + checkThrowCallback(callback); + const wrappedCallback = (payload) => { + callback({ frameId: payload.frameSummary.id, workspaceId: payload.workspaceSummary.id, frameBounds: payload.frameBounds }); + }; + const unsubscribe = await controller.processGlobalSubscription(wrappedCallback, "workspace", "closed"); + return unsubscribe; + }; + const onWorkspaceHibernated = async (callback) => { + checkThrowCallback(callback); + const wrappedCallback = async (payload) => { + const workspace = await controller.transformStreamPayloadToWorkspace(payload); + callback(workspace); + }; + const unsubscribe = await controller.processGlobalSubscription(wrappedCallback, "workspace", "hibernated"); + return unsubscribe; + }; + const onWorkspaceResumed = async (callback) => { + checkThrowCallback(callback); + const wrappedCallback = async (payload) => { + const workspace = await controller.transformStreamPayloadToWorkspace(payload); + callback(workspace); + }; + const unsubscribe = await controller.processGlobalSubscription(wrappedCallback, "workspace", "resumed"); + return unsubscribe; + }; + const onWindowAdded = async (callback) => { + checkThrowCallback(callback); + const wrappedCallback = async (payload) => { + const snapshot = (await controller.getSnapshot(payload.windowSummary.config.workspaceId, "workspace")); + const frameConfig = { + summary: snapshot.frameSummary + }; + const frame = ioc.getModel("frame", frameConfig); + const workspaceConfig = { frame, snapshot }; + const workspace = ioc.getModel("workspace", workspaceConfig); + const windowParent = workspace.getBox((parent) => parent.id === payload.windowSummary.parentId); + const foundWindow = windowParent.children.find((child) => child.type === "window" && child.elementId === payload.windowSummary.itemId); + callback(foundWindow); + }; + const unsubscribe = await controller.processGlobalSubscription(wrappedCallback, "window", "added"); + return unsubscribe; + }; + const onWindowLoaded = async (callback) => { + checkThrowCallback(callback); + const wrappedCallback = async (payload) => { + const snapshot = (await controller.getSnapshot(payload.windowSummary.config.workspaceId, "workspace")); + const frameConfig = { + summary: snapshot.frameSummary + }; + const frame = ioc.getModel("frame", frameConfig); + const workspaceConfig = { frame, snapshot }; + const workspace = ioc.getModel("workspace", workspaceConfig); + const foundWindow = workspace.getWindow((win) => win.id && win.id === payload.windowSummary.config.windowId); + callback(foundWindow); + }; + const unsubscribe = await controller.processGlobalSubscription(wrappedCallback, "window", "loaded"); + return unsubscribe; + }; + const onWindowRemoved = async (callback) => { + checkThrowCallback(callback); + const wrappedCallback = (payload) => { + const { windowId, workspaceId, frameId } = payload.windowSummary.config; + callback({ windowId, workspaceId, frameId }); + }; + const unsubscribe = await controller.processGlobalSubscription(wrappedCallback, "window", "removed"); + return unsubscribe; + }; + const onWindowMaximized = async (callback) => { + checkThrowCallback(callback); + const wrappedCallback = async (payload) => { + const snapshot = (await controller.getSnapshot(payload.windowSummary.config.workspaceId, "workspace")); + const frameConfig = { + summary: snapshot.frameSummary + }; + const frame = ioc.getModel("frame", frameConfig); + const workspaceConfig = { frame, snapshot }; + const workspace = ioc.getModel("workspace", workspaceConfig); + const windowParent = workspace.getBox((parent) => parent.id === payload.windowSummary.parentId); + const foundWindow = windowParent.children.find((child) => child.type === "window" && child.elementId === payload.windowSummary.itemId); + callback(foundWindow); + }; + const unsubscribe = await controller.processGlobalSubscription(wrappedCallback, "window", "maximized"); + return unsubscribe; + }; + const onWindowRestored = async (callback) => { + checkThrowCallback(callback); + const wrappedCallback = async (payload) => { + const snapshot = (await controller.getSnapshot(payload.windowSummary.config.workspaceId, "workspace")); + const frameConfig = { + summary: snapshot.frameSummary + }; + const frame = ioc.getModel("frame", frameConfig); + const workspaceConfig = { frame, snapshot }; + const workspace = ioc.getModel("workspace", workspaceConfig); + const windowParent = workspace.getBox((parent) => parent.id === payload.windowSummary.parentId); + const foundWindow = windowParent.children.find((child) => child.type === "window" && child.elementId === payload.windowSummary.itemId); + callback(foundWindow); + }; + const unsubscribe = await controller.processGlobalSubscription(wrappedCallback, "window", "restored"); + return unsubscribe; + }; + const onWindowSelected = async (callback) => { + checkThrowCallback(callback); + const wrappedCallback = async (payload) => { + const snapshot = (await controller.getSnapshot(payload.windowSummary.config.workspaceId, "workspace")); + const frameConfig = { + summary: snapshot.frameSummary + }; + const frame = ioc.getModel("frame", frameConfig); + const workspaceConfig = { frame, snapshot }; + const workspace = ioc.getModel("workspace", workspaceConfig); + const windowParent = workspace.getBox((parent) => parent.id === payload.windowSummary.parentId); + const foundWindow = windowParent.children.find((child) => child.type === "window" && child.elementId === payload.windowSummary.itemId); + callback(foundWindow); + }; + const unsubscribe = await controller.processGlobalSubscription(wrappedCallback, "window", "selected"); + return unsubscribe; + }; + const waitForFrame = async (id) => { + nonEmptyStringDecoder.runWithException(id); + return new Promise((res, rej) => { + let unsub = () => { + }; + onFrameOpened((f) => { + if (f.id === id) { + res(f); + unsub(); + } + }).then((u) => { + unsub = u; + return getAllFrames(); + }).then((frames) => { + const myFrame = frames.find((f) => f.id === id); + if (myFrame) { + res(myFrame); + unsub(); + } + }).catch(rej); + }); + }; + return { + inWorkspace, + getBuilder, + getMyFrame, + getFrame, + getAllFrames, + getAllWorkspacesSummaries, + getMyWorkspace, + getWorkspace, + getWorkspaceById, + getAllWorkspaces, + getWindow, + getBox: getParent, + restoreWorkspace, + createWorkspace, + createEmptyFrame, + waitForFrame, + layouts, + onFrameOpened, + onFrameClosed, + onWorkspaceOpened, + onWorkspaceClosed, + onWorkspaceHibernated, + onWorkspaceResumed, + onWindowAdded, + onWindowLoaded, + onWindowRemoved, + onWindowMaximized, + onWindowRestored, + onWindowSelected, + version + }; + }; + + const factoryFunction = async (io) => { + const ioc = new IoC(io.agm, io.windows, io.layouts, io.contexts); + const actualWindowId = io.interop.instance.windowId; + await ioc.initiate(actualWindowId); + io.workspaces = composeAPI(io, ioc); + }; + if (typeof window !== "undefined") { + window.IOWorkspaces = factoryFunction; + } + + return factoryFunction; + +})); +//# sourceMappingURL=workspaces.umd.js.map diff --git a/typescript/start/stocks/tsconfig.json b/typescript/start/stocks/tsconfig.json new file mode 100644 index 0000000..11ec879 --- /dev/null +++ b/typescript/start/stocks/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "./dist", + "rootDir": "./src" + }, + "include": ["./src", "../../types"] +} \ No newline at end of file diff --git a/typescript/start/stocks/webpack.config.js b/typescript/start/stocks/webpack.config.js new file mode 100644 index 0000000..0da6df6 --- /dev/null +++ b/typescript/start/stocks/webpack.config.js @@ -0,0 +1,31 @@ +const path = require('path'); +const CopyWebpackPlugin = require('copy-webpack-plugin'); + +module.exports = { + mode: 'development', + entry: './src/index.ts', + module: { + rules: [ + { + test: /\.tsx?$/, + use: 'ts-loader', + exclude: /node_modules/, + }, + ], + }, + resolve: { + extensions: ['.tsx', '.ts', '.js'], + }, + output: { + filename: 'index.js', + path: path.resolve(__dirname, 'dist'), + }, + plugins: [ + new CopyWebpackPlugin({ + patterns: [ + { from: 'src/index.html', to: 'index.html' }, + { from: '../../../javascript/start/stocks/lib', to: 'lib' } + ], + }), + ], +}; \ No newline at end of file diff --git a/typescript/tsconfig.json b/typescript/tsconfig.json new file mode 100644 index 0000000..812099e --- /dev/null +++ b/typescript/tsconfig.json @@ -0,0 +1,16 @@ +{ + "compilerOptions": { + "target": "ES2020", + "module": "ES2020", + "moduleResolution": "node", + "esModuleInterop": true, + "strict": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "outDir": "dist", + "declaration": true, + "sourceMap": true, + "lib": ["dom", "dom.iterable", "esnext"] + }, + "exclude": ["node_modules"] +} \ No newline at end of file diff --git a/typescript/types/io-connect.d.ts b/typescript/types/io-connect.d.ts new file mode 100644 index 0000000..8a3aee7 --- /dev/null +++ b/typescript/types/io-connect.d.ts @@ -0,0 +1,101 @@ +declare const iodesktop: { + theme: string; +}; + +declare const IOWorkspaces: any; + +declare function IODesktop(config?: { + libraries?: any[]; + channels?: boolean; + appManager?: string; +}): Promise; + +interface IODesktopAPI { + windows: { + open(name: string, url: string, config: any): Promise; + list(): any[]; + }; + interop: { + methods(): { name: string; }[]; + invoke(method: any, args: any): Promise; + }; + contexts: { + update(name: string, context: any): Promise; + }; + channels: { + my(): any; + publish(data: any): Promise; + subscribe(handler: (data: any) => void): void; + }; + workspaces: { + getMyWorkspace(): Promise; + restoreWorkspace(name: string, config: any): Promise; + }; + notifications: { + raise(options: NotificationOptions): Promise; + }; + themes: { + onChanged(handler: (theme: Theme) => void): void; + getCurrent(): Promise; + select(themeName: string): void; + }; + hotkeys: { + register(hotkey: Hotkey, handler: () => void): void; + }; + intents: { + register(name: string, handler: (context: any) => void): void; + }; + appManager: { + application(name: string): { + start(context?: any, options?: any): Promise; + instances: any[]; + }; + }; +} + +interface Workspace { + frame: { + focus(): Promise; + }; + focus(): Promise; + setTitle(title: string): void; + onContextUpdated(handler: (context: any) => void): void; +} + +interface Theme { + name: string; +} + +interface Hotkey { + hotkey: string; + description: string; +} + +interface NotificationOptions { + title: string; + body: string; +} + +interface Notification { + onclick: () => void; +} + +declare interface Client { + name: string; + pId?: string; + gId?: string; + id?: string; + eId?: string; + accountManager?: string; + address?: string; + contactNumbers?: string; + email?: string; + portfolio?: string; +} + +declare interface Stock { + RIC: string; + description: string; + price?: number; + updateTime?: string; +} \ No newline at end of file